r4720 - in dists/trunk: . linux-2.6-git/debian linux-2.6-git/debian/patches-debian linux-2.6-git/debian/patches-debian/series

Frederik Schüler fschueler-guest at costa.debian.org
Thu Nov 3 17:54:59 UTC 2005


Author: fschueler-guest
Date: 2005-11-03 17:51:59 +0000 (Thu, 03 Nov 2005)
New Revision: 4720

Added:
   dists/trunk/linux-2.6-git/
   dists/trunk/linux-2.6-git/debian/patches-debian/patch-2.6.14-git5
   dists/trunk/linux-2.6-git/debian/patches-debian/series/2.6.14-git-20051103
Removed:
   dists/trunk/linux-2.6-git/debian/patches-debian/series/2.6.14-1
   dists/trunk/linux-2.6-git/debian/patches-debian/series/2.6.14-2
   dists/trunk/linux-2.6/
Modified:
   dists/trunk/linux-2.6-git/debian/changelog
Log:
Rename trunk/linux-2.6 to trunk/linux-2.6-git.
Add 2.6.14-git5 patch, without the pruned-drivers bits.



Copied: dists/trunk/linux-2.6-git (from rev 4717, dists/trunk/linux-2.6)

Modified: dists/trunk/linux-2.6-git/debian/changelog
===================================================================
--- dists/trunk/linux-2.6/debian/changelog	2005-11-03 11:39:35 UTC (rev 4717)
+++ dists/trunk/linux-2.6-git/debian/changelog	2005-11-03 17:51:59 UTC (rev 4720)
@@ -1,3 +1,10 @@
+linux-2.6 (2.6.14-git-20051103) UNRELEASED; urgency=low
+
+  [ Frederik Schüler ]
+  * Upgrade to 2.6.14-git5.
+  
+ -- Frederik Schüler <fschueler at gmx.net>  Thu,  3 Nov 2005 18:25:06 +0100
+
 linux-2.6 (2.6.14-3) UNRELEASED; urgency=low
 
   [ Norbert Tretkowski ]

Added: dists/trunk/linux-2.6-git/debian/patches-debian/patch-2.6.14-git5
===================================================================
--- dists/trunk/linux-2.6/debian/patches-debian/patch-2.6.14-git5	2005-11-03 11:39:35 UTC (rev 4717)
+++ dists/trunk/linux-2.6-git/debian/patches-debian/patch-2.6.14-git5	2005-11-03 17:51:59 UTC (rev 4720)
@@ -0,0 +1,536744 @@
+diff --git a/CREDITS b/CREDITS
+--- a/CREDITS
++++ b/CREDITS
+@@ -2247,6 +2247,12 @@ S: 249 Nichols Avenue
+ S: Syracuse, New York 13206
+ S: USA
+ 
++N: Kyle McMartin
++E: kyle at parisc-linux.org
++D: Linux/PARISC hacker
++D: AD1889 sound driver
++S: Ottawa, Canada
++
+ N: Dirk Melchers
+ E: dirk at merlin.nbg.sub.org
+ D: 8 bit XT hard disk driver for OMTI5520
+diff --git a/Documentation/Changes b/Documentation/Changes
+--- a/Documentation/Changes
++++ b/Documentation/Changes
+@@ -65,7 +65,7 @@ o  isdn4k-utils           3.1pre1       
+ o  nfs-utils              1.0.5                   # showmount --version
+ o  procps                 3.2.0                   # ps --version
+ o  oprofile               0.9                     # oprofiled --version
+-o  udev                   058                     # udevinfo -V
++o  udev                   071                     # udevinfo -V
+ 
+ Kernel compilation
+ ==================
+diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
+--- a/Documentation/DocBook/kernel-api.tmpl
++++ b/Documentation/DocBook/kernel-api.tmpl
+@@ -286,7 +286,9 @@ X!Edrivers/pci/search.c
+  -->
+ !Edrivers/pci/msi.c
+ !Edrivers/pci/bus.c
+-!Edrivers/pci/hotplug.c
++<!-- FIXME: Removed for now since no structured comments in source
++X!Edrivers/pci/hotplug.c
++-->
+ !Edrivers/pci/probe.c
+ !Edrivers/pci/rom.c
+      </sect1>
+diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
+--- a/Documentation/DocBook/libata.tmpl
++++ b/Documentation/DocBook/libata.tmpl
+@@ -415,6 +415,362 @@ and other resources, etc.
+      </sect1>
+   </chapter>
+ 
++  <chapter id="libataEH">
++        <title>Error handling</title>
++
++	<para>
++	This chapter describes how errors are handled under libata.
++	Readers are advised to read SCSI EH
++	(Documentation/scsi/scsi_eh.txt) and ATA exceptions doc first.
++	</para>
++
++	<sect1><title>Origins of commands</title>
++	<para>
++	In libata, a command is represented with struct ata_queued_cmd
++	or qc.  qc's are preallocated during port initialization and
++	repetitively used for command executions.  Currently only one
++	qc is allocated per port but yet-to-be-merged NCQ branch
++	allocates one for each tag and maps each qc to NCQ tag 1-to-1.
++	</para>
++	<para>
++	libata commands can originate from two sources - libata itself
++	and SCSI midlayer.  libata internal commands are used for
++	initialization and error handling.  All normal blk requests
++	and commands for SCSI emulation are passed as SCSI commands
++	through queuecommand callback of SCSI host template.
++	</para>
++	</sect1>
++
++	<sect1><title>How commands are issued</title>
++
++	<variablelist>
++
++	<varlistentry><term>Internal commands</term>
++	<listitem>
++	<para>
++	First, qc is allocated and initialized using
++	ata_qc_new_init().  Although ata_qc_new_init() doesn't
++	implement any wait or retry mechanism when qc is not
++	available, internal commands are currently issued only during
++	initialization and error recovery, so no other command is
++	active and allocation is guaranteed to succeed.
++	</para>
++	<para>
++	Once allocated qc's taskfile is initialized for the command to
++	be executed.  qc currently has two mechanisms to notify
++	completion.  One is via qc->complete_fn() callback and the
++	other is completion qc->waiting.  qc->complete_fn() callback
++	is the asynchronous path used by normal SCSI translated
++	commands and qc->waiting is the synchronous (issuer sleeps in
++	process context) path used by internal commands.
++	</para>
++	<para>
++	Once initialization is complete, host_set lock is acquired
++	and the qc is issued.
++	</para>
++	</listitem>
++	</varlistentry>
++
++	<varlistentry><term>SCSI commands</term>
++	<listitem>
++	<para>
++	All libata drivers use ata_scsi_queuecmd() as
++	hostt->queuecommand callback.  scmds can either be simulated
++	or translated.  No qc is involved in processing a simulated
++	scmd.  The result is computed right away and the scmd is
++	completed.
++	</para>
++	<para>
++	For a translated scmd, ata_qc_new_init() is invoked to
++	allocate a qc and the scmd is translated into the qc.  SCSI
++	midlayer's completion notification function pointer is stored
++	into qc->scsidone.
++	</para>
++	<para>
++	qc->complete_fn() callback is used for completion
++	notification.  ATA commands use ata_scsi_qc_complete() while
++	ATAPI commands use atapi_qc_complete().  Both functions end up
++	calling qc->scsidone to notify upper layer when the qc is
++	finished.  After translation is completed, the qc is issued
++	with ata_qc_issue().
++	</para>
++	<para>
++	Note that SCSI midlayer invokes hostt->queuecommand while
++	holding host_set lock, so all above occur while holding
++	host_set lock.
++	</para>
++	</listitem>
++	</varlistentry>
++
++	</variablelist>
++	</sect1>
++
++	<sect1><title>How commands are processed</title>
++	<para>
++	Depending on which protocol and which controller are used,
++	commands are processed differently.  For the purpose of
++	discussion, a controller which uses taskfile interface and all
++	standard callbacks is assumed.
++	</para>
++	<para>
++	Currently 6 ATA command protocols are used.  They can be
++	sorted into the following four categories according to how
++	they are processed.
++	</para>
++
++	<variablelist>
++	   <varlistentry><term>ATA NO DATA or DMA</term>
++	   <listitem>
++	   <para>
++	   ATA_PROT_NODATA and ATA_PROT_DMA fall into this category.
++	   These types of commands don't require any software
++	   intervention once issued.  Device will raise interrupt on
++	   completion.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry><term>ATA PIO</term>
++	   <listitem>
++	   <para>
++	   ATA_PROT_PIO is in this category.  libata currently
++	   implements PIO with polling.  ATA_NIEN bit is set to turn
++	   off interrupt and pio_task on ata_wq performs polling and
++	   IO.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry><term>ATAPI NODATA or DMA</term>
++	   <listitem>
++	   <para>
++	   ATA_PROT_ATAPI_NODATA and ATA_PROT_ATAPI_DMA are in this
++	   category.  packet_task is used to poll BSY bit after
++	   issuing PACKET command.  Once BSY is turned off by the
++	   device, packet_task transfers CDB and hands off processing
++	   to interrupt handler.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry><term>ATAPI PIO</term>
++	   <listitem>
++	   <para>
++	   ATA_PROT_ATAPI is in this category.  ATA_NIEN bit is set
++	   and, as in ATAPI NODATA or DMA, packet_task submits cdb.
++	   However, after submitting cdb, further processing (data
++	   transfer) is handed off to pio_task.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++	</variablelist>
++        </sect1>
++
++	<sect1><title>How commands are completed</title>
++	<para>
++	Once issued, all qc's are either completed with
++	ata_qc_complete() or time out.  For commands which are handled
++	by interrupts, ata_host_intr() invokes ata_qc_complete(), and,
++	for PIO tasks, pio_task invokes ata_qc_complete().  In error
++	cases, packet_task may also complete commands.
++	</para>
++	<para>
++	ata_qc_complete() does the following.
++	</para>
++
++	<orderedlist>
++
++	<listitem>
++	<para>
++	DMA memory is unmapped.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	ATA_QCFLAG_ACTIVE is clared from qc->flags.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	qc->complete_fn() callback is invoked.  If the return value of
++	the callback is not zero.  Completion is short circuited and
++	ata_qc_complete() returns.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	__ata_qc_complete() is called, which does
++	   <orderedlist>
++
++	   <listitem>
++	   <para>
++	   qc->flags is cleared to zero.
++	   </para>
++	   </listitem>
++
++	   <listitem>
++	   <para>
++	   ap->active_tag and qc->tag are poisoned.
++	   </para>
++	   </listitem>
++
++	   <listitem>
++	   <para>
++	   qc->waiting is claread &amp; completed (in that order).
++	   </para>
++	   </listitem>
++
++	   <listitem>
++	   <para>
++	   qc is deallocated by clearing appropriate bit in ap->qactive.
++	   </para>
++	   </listitem>
++
++	   </orderedlist>
++	</para>
++	</listitem>
++
++	</orderedlist>
++
++	<para>
++	So, it basically notifies upper layer and deallocates qc.  One
++	exception is short-circuit path in #3 which is used by
++	atapi_qc_complete().
++	</para>
++	<para>
++	For all non-ATAPI commands, whether it fails or not, almost
++	the same code path is taken and very little error handling
++	takes place.  A qc is completed with success status if it
++	succeeded, with failed status otherwise.
++	</para>
++	<para>
++	However, failed ATAPI commands require more handling as
++	REQUEST SENSE is needed to acquire sense data.  If an ATAPI
++	command fails, ata_qc_complete() is invoked with error status,
++	which in turn invokes atapi_qc_complete() via
++	qc->complete_fn() callback.
++	</para>
++	<para>
++	This makes atapi_qc_complete() set scmd->result to
++	SAM_STAT_CHECK_CONDITION, complete the scmd and return 1.  As
++	the sense data is empty but scmd->result is CHECK CONDITION,
++	SCSI midlayer will invoke EH for the scmd, and returning 1
++	makes ata_qc_complete() to return without deallocating the qc.
++	This leads us to ata_scsi_error() with partially completed qc.
++	</para>
++
++	</sect1>
++
++	<sect1><title>ata_scsi_error()</title>
++	<para>
++	ata_scsi_error() is the current hostt->eh_strategy_handler()
++	for libata.  As discussed above, this will be entered in two
++	cases - timeout and ATAPI error completion.  This function
++	calls low level libata driver's eng_timeout() callback, the
++	standard callback for which is ata_eng_timeout().  It checks
++	if a qc is active and calls ata_qc_timeout() on the qc if so.
++	Actual error handling occurs in ata_qc_timeout().
++	</para>
++	<para>
++	If EH is invoked for timeout, ata_qc_timeout() stops BMDMA and
++	completes the qc.  Note that as we're currently in EH, we
++	cannot call scsi_done.  As described in SCSI EH doc, a
++	recovered scmd should be either retried with
++	scsi_queue_insert() or finished with scsi_finish_command().
++	Here, we override qc->scsidone with scsi_finish_command() and
++	calls ata_qc_complete().
++	</para>
++	<para>
++	If EH is invoked due to a failed ATAPI qc, the qc here is
++	completed but not deallocated.  The purpose of this
++	half-completion is to use the qc as place holder to make EH
++	code reach this place.  This is a bit hackish, but it works.
++	</para>
++	<para>
++	Once control reaches here, the qc is deallocated by invoking
++	__ata_qc_complete() explicitly.  Then, internal qc for REQUEST
++	SENSE is issued.  Once sense data is acquired, scmd is
++	finished by directly invoking scsi_finish_command() on the
++	scmd.  Note that as we already have completed and deallocated
++	the qc which was associated with the scmd, we don't need
++	to/cannot call ata_qc_complete() again.
++	</para>
++
++	</sect1>
++
++	<sect1><title>Problems with the current EH</title>
++
++	<itemizedlist>
++
++	<listitem>
++	<para>
++	Error representation is too crude.  Currently any and all
++	error conditions are represented with ATA STATUS and ERROR
++	registers.  Errors which aren't ATA device errors are treated
++	as ATA device errors by setting ATA_ERR bit.  Better error
++	descriptor which can properly represent ATA and other
++	errors/exceptions is needed.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	When handling timeouts, no action is taken to make device
++	forget about the timed out command and ready for new commands.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	EH handling via ata_scsi_error() is not properly protected
++	from usual command processing.  On EH entrance, the device is
++	not in quiescent state.  Timed out commands may succeed or
++	fail any time.  pio_task and atapi_task may still be running.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	Too weak error recovery.  Devices / controllers causing HSM
++	mismatch errors and other errors quite often require reset to
++	return to known state.  Also, advanced error handling is
++	necessary to support features like NCQ and hotplug.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	ATA errors are directly handled in the interrupt handler and
++	PIO errors in pio_task.  This is problematic for advanced
++	error handling for the following reasons.
++	</para>
++	<para>
++	First, advanced error handling often requires context and
++	internal qc execution.
++	</para>
++	<para>
++	Second, even a simple failure (say, CRC error) needs
++	information gathering and could trigger complex error handling
++	(say, resetting &amp; reconfiguring).  Having multiple code
++	paths to gather information, enter EH and trigger actions
++	makes life painful.
++	</para>
++	<para>
++	Third, scattered EH code makes implementing low level drivers
++	difficult.  Low level drivers override libata callbacks.  If
++	EH is scattered over several places, each affected callbacks
++	should perform its part of error handling.  This can be error
++	prone and painful.
++	</para>
++	</listitem>
++
++	</itemizedlist>
++	</sect1>
++  </chapter>
++
+   <chapter id="libataExt">
+      <title>libata Library</title>
+ !Edrivers/scsi/libata-core.c
+@@ -431,6 +787,722 @@ and other resources, etc.
+ !Idrivers/scsi/libata-scsi.c
+   </chapter>
+ 
++  <chapter id="ataExceptions">
++     <title>ATA errors &amp; exceptions</title>
++
++  <para>
++  This chapter tries to identify what error/exception conditions exist
++  for ATA/ATAPI devices and describe how they should be handled in
++  implementation-neutral way.
++  </para>
++
++  <para>
++  The term 'error' is used to describe conditions where either an
++  explicit error condition is reported from device or a command has
++  timed out.
++  </para>
++
++  <para>
++  The term 'exception' is either used to describe exceptional
++  conditions which are not errors (say, power or hotplug events), or
++  to describe both errors and non-error exceptional conditions.  Where
++  explicit distinction between error and exception is necessary, the
++  term 'non-error exception' is used.
++  </para>
++
++  <sect1 id="excat">
++     <title>Exception categories</title>
++     <para>
++     Exceptions are described primarily with respect to legacy
++     taskfile + bus master IDE interface.  If a controller provides
++     other better mechanism for error reporting, mapping those into
++     categories described below shouldn't be difficult.
++     </para>
++
++     <para>
++     In the following sections, two recovery actions - reset and
++     reconfiguring transport - are mentioned.  These are described
++     further in <xref linkend="exrec"/>.
++     </para>
++
++     <sect2 id="excatHSMviolation">
++        <title>HSM violation</title>
++        <para>
++        This error is indicated when STATUS value doesn't match HSM
++        requirement during issuing or excution any ATA/ATAPI command.
++        </para>
++
++	<itemizedlist>
++	<title>Examples</title>
++
++        <listitem>
++	<para>
++	ATA_STATUS doesn't contain !BSY &amp;&amp; DRDY &amp;&amp; !DRQ while trying
++	to issue a command.
++        </para>
++	</listitem>
++
++        <listitem>
++	<para>
++	!BSY &amp;&amp; !DRQ during PIO data transfer.
++        </para>
++	</listitem>
++
++        <listitem>
++	<para>
++	DRQ on command completion.
++        </para>
++	</listitem>
++
++        <listitem>
++	<para>
++	!BSY &amp;&amp; ERR after CDB tranfer starts but before the
++        last byte of CDB is transferred.  ATA/ATAPI standard states
++        that &quot;The device shall not terminate the PACKET command
++        with an error before the last byte of the command packet has
++        been written&quot; in the error outputs description of PACKET
++        command and the state diagram doesn't include such
++        transitions.
++	</para>
++	</listitem>
++
++	</itemizedlist>
++
++	<para>
++	In these cases, HSM is violated and not much information
++	regarding the error can be acquired from STATUS or ERROR
++	register.  IOW, this error can be anything - driver bug,
++	faulty device, controller and/or cable.
++	</para>
++
++	<para>
++	As HSM is violated, reset is necessary to restore known state.
++	Reconfiguring transport for lower speed might be helpful too
++	as transmission errors sometimes cause this kind of errors.
++	</para>
++     </sect2>
++     
++     <sect2 id="excatDevErr">
++        <title>ATA/ATAPI device error (non-NCQ / non-CHECK CONDITION)</title>
++
++	<para>
++	These are errors detected and reported by ATA/ATAPI devices
++	indicating device problems.  For this type of errors, STATUS
++	and ERROR register values are valid and describe error
++	condition.  Note that some of ATA bus errors are detected by
++	ATA/ATAPI devices and reported using the same mechanism as
++	device errors.  Those cases are described later in this
++	section.
++	</para>
++
++	<para>
++	For ATA commands, this type of errors are indicated by !BSY
++	&amp;&amp; ERR during command execution and on completion.
++	</para>
++
++	<para>For ATAPI commands,</para>
++
++	<itemizedlist>
++
++	<listitem>
++	<para>
++	!BSY &amp;&amp; ERR &amp;&amp; ABRT right after issuing PACKET
++	indicates that PACKET command is not supported and falls in
++	this category.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	!BSY &amp;&amp; ERR(==CHK) &amp;&amp; !ABRT after the last
++	byte of CDB is transferred indicates CHECK CONDITION and
++	doesn't fall in this category.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	!BSY &amp;&amp; ERR(==CHK) &amp;&amp; ABRT after the last byte
++        of CDB is transferred *probably* indicates CHECK CONDITION and
++        doesn't fall in this category.
++	</para>
++	</listitem>
++
++	</itemizedlist>
++
++	<para>
++	Of errors detected as above, the followings are not ATA/ATAPI
++	device errors but ATA bus errors and should be handled
++	according to <xref linkend="excatATAbusErr"/>.
++	</para>
++
++	<variablelist>
++
++	   <varlistentry>
++	   <term>CRC error during data transfer</term>
++	   <listitem>
++	   <para>
++	   This is indicated by ICRC bit in the ERROR register and
++	   means that corruption occurred during data transfer.  Upto
++	   ATA/ATAPI-7, the standard specifies that this bit is only
++	   applicable to UDMA transfers but ATA/ATAPI-8 draft revision
++	   1f says that the bit may be applicable to multiword DMA and
++	   PIO.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry>
++	   <term>ABRT error during data transfer or on completion</term>
++	   <listitem>
++	   <para>
++	   Upto ATA/ATAPI-7, the standard specifies that ABRT could be
++	   set on ICRC errors and on cases where a device is not able
++	   to complete a command.  Combined with the fact that MWDMA
++	   and PIO transfer errors aren't allowed to use ICRC bit upto
++	   ATA/ATAPI-7, it seems to imply that ABRT bit alone could
++	   indicate tranfer errors.
++	   </para>
++	   <para>
++	   However, ATA/ATAPI-8 draft revision 1f removes the part
++	   that ICRC errors can turn on ABRT.  So, this is kind of
++	   gray area.  Some heuristics are needed here.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	</variablelist>
++
++	<para>
++	ATA/ATAPI device errors can be further categorized as follows.
++	</para>
++
++	<variablelist>
++
++	   <varlistentry>
++	   <term>Media errors</term>
++	   <listitem>
++	   <para>
++	   This is indicated by UNC bit in the ERROR register.  ATA
++	   devices reports UNC error only after certain number of
++	   retries cannot recover the data, so there's nothing much
++	   else to do other than notifying upper layer.
++	   </para>
++	   <para>
++	   READ and WRITE commands report CHS or LBA of the first
++	   failed sector but ATA/ATAPI standard specifies that the
++	   amount of transferred data on error completion is
++	   indeterminate, so we cannot assume that sectors preceding
++	   the failed sector have been transferred and thus cannot
++	   complete those sectors successfully as SCSI does.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry>
++	   <term>Media changed / media change requested error</term>
++	   <listitem>
++	   <para>
++	   &lt;&lt;TODO: fill here&gt;&gt;
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry><term>Address error</term>
++	   <listitem>
++	   <para>
++	   This is indicated by IDNF bit in the ERROR register.
++	   Report to upper layer.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry><term>Other errors</term>
++	   <listitem>
++	   <para>
++	   This can be invalid command or parameter indicated by ABRT
++	   ERROR bit or some other error condition.  Note that ABRT
++	   bit can indicate a lot of things including ICRC and Address
++	   errors.  Heuristics needed.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	</variablelist>
++
++	<para>
++	Depending on commands, not all STATUS/ERROR bits are
++	applicable.  These non-applicable bits are marked with
++	&quot;na&quot; in the output descriptions but upto ATA/ATAPI-7
++	no definition of &quot;na&quot; can be found.  However,
++	ATA/ATAPI-8 draft revision 1f describes &quot;N/A&quot; as
++	follows.
++	</para>
++
++	<blockquote>
++	<variablelist>
++	   <varlistentry><term>3.2.3.3a N/A</term>
++	   <listitem>
++	   <para>
++	   A keyword the indicates a field has no defined value in
++	   this standard and should not be checked by the host or
++	   device. N/A fields should be cleared to zero.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++	</variablelist>
++	</blockquote>
++
++	<para>
++	So, it seems reasonable to assume that &quot;na&quot; bits are
++	cleared to zero by devices and thus need no explicit masking.
++	</para>
++
++     </sect2>
++
++     <sect2 id="excatATAPIcc">
++        <title>ATAPI device CHECK CONDITION</title>
++
++	<para>
++	ATAPI device CHECK CONDITION error is indicated by set CHK bit
++	(ERR bit) in the STATUS register after the last byte of CDB is
++	transferred for a PACKET command.  For this kind of errors,
++	sense data should be acquired to gather information regarding
++	the errors.  REQUEST SENSE packet command should be used to
++	acquire sense data.
++	</para>
++
++	<para>
++	Once sense data is acquired, this type of errors can be
++	handled similary to other SCSI errors.  Note that sense data
++	may indicate ATA bus error (e.g. Sense Key 04h HARDWARE ERROR
++	&amp;&amp; ASC/ASCQ 47h/00h SCSI PARITY ERROR).  In such
++	cases, the error should be considered as an ATA bus error and
++	handled according to <xref linkend="excatATAbusErr"/>.
++	</para>
++
++     </sect2>
++
++     <sect2 id="excatNCQerr">
++        <title>ATA device error (NCQ)</title>
++
++	<para>
++	NCQ command error is indicated by cleared BSY and set ERR bit
++	during NCQ command phase (one or more NCQ commands
++	outstanding).  Although STATUS and ERROR registers will
++	contain valid values describing the error, READ LOG EXT is
++	required to clear the error condition, determine which command
++	has failed and acquire more information.
++	</para>
++
++	<para>
++	READ LOG EXT Log Page 10h reports which tag has failed and
++	taskfile register values describing the error.  With this
++	information the failed command can be handled as a normal ATA
++	command error as in <xref linkend="excatDevErr"/> and all
++	other in-flight commands must be retried.  Note that this
++	retry should not be counted - it's likely that commands
++	retried this way would have completed normally if it were not
++	for the failed command.
++	</para>
++
++	<para>
++	Note that ATA bus errors can be reported as ATA device NCQ
++	errors.  This should be handled as described in <xref
++	linkend="excatATAbusErr"/>.
++	</para>
++
++	<para>
++	If READ LOG EXT Log Page 10h fails or reports NQ, we're
++	thoroughly screwed.  This condition should be treated
++	according to <xref linkend="excatHSMviolation"/>.
++	</para>
++
++     </sect2>
++
++     <sect2 id="excatATAbusErr">
++        <title>ATA bus error</title>
++
++	<para>
++	ATA bus error means that data corruption occurred during
++	transmission over ATA bus (SATA or PATA).  This type of errors
++	can be indicated by
++	</para>
++
++	<itemizedlist>
++
++	<listitem>
++	<para>
++	ICRC or ABRT error as described in <xref linkend="excatDevErr"/>.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	Controller-specific error completion with error information
++	indicating transmission error.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	On some controllers, command timeout.  In this case, there may
++	be a mechanism to determine that the timeout is due to
++	transmission error.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	Unknown/random errors, timeouts and all sorts of weirdities.
++	</para>
++	</listitem>
++
++	</itemizedlist>
++
++	<para>
++	As described above, transmission errors can cause wide variety
++	of symptoms ranging from device ICRC error to random device
++	lockup, and, for many cases, there is no way to tell if an
++	error condition is due to transmission error or not;
++	therefore, it's necessary to employ some kind of heuristic
++	when dealing with errors and timeouts.  For example,
++	encountering repetitive ABRT errors for known supported
++	command is likely to indicate ATA bus error.
++	</para>
++
++	<para>
++	Once it's determined that ATA bus errors have possibly
++	occurred, lowering ATA bus transmission speed is one of
++	actions which may alleviate the problem.  See <xref
++	linkend="exrecReconf"/> for more information.
++	</para>
++
++     </sect2>
++
++     <sect2 id="excatPCIbusErr">
++        <title>PCI bus error</title>
++
++	<para>
++	Data corruption or other failures during transmission over PCI
++	(or other system bus).  For standard BMDMA, this is indicated
++	by Error bit in the BMDMA Status register.  This type of
++	errors must be logged as it indicates something is very wrong
++	with the system.  Resetting host controller is recommended.
++	</para>
++
++     </sect2>
++
++     <sect2 id="excatLateCompletion">
++        <title>Late completion</title>
++
++	<para>
++	This occurs when timeout occurs and the timeout handler finds
++	out that the timed out command has completed successfully or
++	with error.  This is usually caused by lost interrupts.  This
++	type of errors must be logged.  Resetting host controller is
++	recommended.
++	</para>
++
++     </sect2>
++
++     <sect2 id="excatUnknown">
++        <title>Unknown error (timeout)</title>
++
++	<para>
++	This is when timeout occurs and the command is still
++	processing or the host and device are in unknown state.  When
++	this occurs, HSM could be in any valid or invalid state.  To
++	bring the device to known state and make it forget about the
++	timed out command, resetting is necessary.  The timed out
++	command may be retried.
++	</para>
++
++	<para>
++	Timeouts can also be caused by transmission errors.  Refer to
++	<xref linkend="excatATAbusErr"/> for more details.
++	</para>
++
++     </sect2>
++
++     <sect2 id="excatHoplugPM">
++        <title>Hotplug and power management exceptions</title>
++
++	<para>
++	&lt;&lt;TODO: fill here&gt;&gt;
++	</para>
++
++     </sect2>
++
++  </sect1>
++
++  <sect1 id="exrec">
++     <title>EH recovery actions</title>
++
++     <para>
++     This section discusses several important recovery actions.
++     </para>
++
++     <sect2 id="exrecClr">
++        <title>Clearing error condition</title>
++
++	<para>
++	Many controllers require its error registers to be cleared by
++	error handler.  Different controllers may have different
++	requirements.
++	</para>
++
++	<para>
++	For SATA, it's strongly recommended to clear at least SError
++	register during error handling.
++	</para>
++     </sect2>
++
++     <sect2 id="exrecRst">
++        <title>Reset</title>
++
++	<para>
++	During EH, resetting is necessary in the following cases.
++	</para>
++
++	<itemizedlist>
++
++	<listitem>
++	<para>
++	HSM is in unknown or invalid state
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	HBA is in unknown or invalid state
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	EH needs to make HBA/device forget about in-flight commands
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	HBA/device behaves weirdly
++	</para>
++	</listitem>
++
++	</itemizedlist>
++
++	<para>
++	Resetting during EH might be a good idea regardless of error
++	condition to improve EH robustness.  Whether to reset both or
++	either one of HBA and device depends on situation but the
++	following scheme is recommended.
++	</para>
++
++	<itemizedlist>
++
++	<listitem>
++	<para>
++	When it's known that HBA is in ready state but ATA/ATAPI
++	device in in unknown state, reset only device.
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	If HBA is in unknown state, reset both HBA and device.
++	</para>
++	</listitem>
++
++	</itemizedlist>
++
++	<para>
++	HBA resetting is implementation specific.  For a controller
++	complying to taskfile/BMDMA PCI IDE, stopping active DMA
++	transaction may be sufficient iff BMDMA state is the only HBA
++	context.  But even mostly taskfile/BMDMA PCI IDE complying
++	controllers may have implementation specific requirements and
++	mechanism to reset themselves.  This must be addressed by
++	specific drivers.
++	</para>
++
++	<para>
++	OTOH, ATA/ATAPI standard describes in detail ways to reset
++	ATA/ATAPI devices.
++	</para>
++
++	<variablelist>
++
++	   <varlistentry><term>PATA hardware reset</term>
++	   <listitem>
++	   <para>
++	   This is hardware initiated device reset signalled with
++	   asserted PATA RESET- signal.  There is no standard way to
++	   initiate hardware reset from software although some
++	   hardware provides registers that allow driver to directly
++	   tweak the RESET- signal.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry><term>Software reset</term>
++	   <listitem>
++	   <para>
++	   This is achieved by turning CONTROL SRST bit on for at
++	   least 5us.  Both PATA and SATA support it but, in case of
++	   SATA, this may require controller-specific support as the
++	   second Register FIS to clear SRST should be transmitted
++	   while BSY bit is still set.  Note that on PATA, this resets
++	   both master and slave devices on a channel.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry><term>EXECUTE DEVICE DIAGNOSTIC command</term>
++	   <listitem>
++	   <para>
++	   Although ATA/ATAPI standard doesn't describe exactly, EDD
++	   implies some level of resetting, possibly similar level
++	   with software reset.  Host-side EDD protocol can be handled
++	   with normal command processing and most SATA controllers
++	   should be able to handle EDD's just like other commands.
++	   As in software reset, EDD affects both devices on a PATA
++	   bus.
++	   </para>
++	   <para>
++	   Although EDD does reset devices, this doesn't suit error
++	   handling as EDD cannot be issued while BSY is set and it's
++	   unclear how it will act when device is in unknown/weird
++	   state.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry><term>ATAPI DEVICE RESET command</term>
++	   <listitem>
++	   <para>
++	   This is very similar to software reset except that reset
++	   can be restricted to the selected device without affecting
++	   the other device sharing the cable.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	   <varlistentry><term>SATA phy reset</term>
++	   <listitem>
++	   <para>
++	   This is the preferred way of resetting a SATA device.  In
++	   effect, it's identical to PATA hardware reset.  Note that
++	   this can be done with the standard SCR Control register.
++	   As such, it's usually easier to implement than software
++	   reset.
++	   </para>
++	   </listitem>
++	   </varlistentry>
++
++	</variablelist>
++
++	<para>
++	One more thing to consider when resetting devices is that
++	resetting clears certain configuration parameters and they
++	need to be set to their previous or newly adjusted values
++	after reset.
++	</para>
++
++	<para>
++	Parameters affected are.
++	</para>
++
++	<itemizedlist>
++
++	<listitem>
++	<para>
++	CHS set up with INITIALIZE DEVICE PARAMETERS (seldomly used)
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	Parameters set with SET FEATURES including transfer mode setting
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	Block count set with SET MULTIPLE MODE
++	</para>
++	</listitem>
++
++	<listitem>
++	<para>
++	Other parameters (SET MAX, MEDIA LOCK...)
++	</para>
++	</listitem>
++
++	</itemizedlist>
++
++	<para>
++	ATA/ATAPI standard specifies that some parameters must be
++	maintained across hardware or software reset, but doesn't
++	strictly specify all of them.  Always reconfiguring needed
++	parameters after reset is required for robustness.  Note that
++	this also applies when resuming from deep sleep (power-off).
++	</para>
++
++	<para>
++	Also, ATA/ATAPI standard requires that IDENTIFY DEVICE /
++	IDENTIFY PACKET DEVICE is issued after any configuration
++	parameter is updated or a hardware reset and the result used
++	for further operation.  OS driver is required to implement
++	revalidation mechanism to support this.
++	</para>
++
++     </sect2>
++
++     <sect2 id="exrecReconf">
++        <title>Reconfigure transport</title>
++
++	<para>
++	For both PATA and SATA, a lot of corners are cut for cheap
++	connectors, cables or controllers and it's quite common to see
++	high transmission error rate.  This can be mitigated by
++	lowering transmission speed.
++	</para>
++
++	<para>
++	The following is a possible scheme Jeff Garzik suggested.
++	</para>
++
++	<blockquote>
++	<para>
++	If more than $N (3?) transmission errors happen in 15 minutes,
++	</para>	
++	<itemizedlist>
++	<listitem>
++	<para>
++	if SATA, decrease SATA PHY speed.  if speed cannot be decreased,
++	</para>
++	</listitem>
++	<listitem>
++	<para>
++	decrease UDMA xfer speed.  if at UDMA0, switch to PIO4,
++	</para>
++	</listitem>
++	<listitem>
++	<para>
++	decrease PIO xfer speed.  if at PIO3, complain, but continue
++	</para>
++	</listitem>
++	</itemizedlist>
++	</blockquote>
++
++     </sect2>
++
++  </sect1>
++
++  </chapter>
++
+   <chapter id="PiixInt">
+      <title>ata_piix Internals</title>
+ !Idrivers/scsi/ata_piix.c
+diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl
+--- a/Documentation/DocBook/usb.tmpl
++++ b/Documentation/DocBook/usb.tmpl
+@@ -291,7 +291,7 @@
+ 
+ !Edrivers/usb/core/hcd.c
+ !Edrivers/usb/core/hcd-pci.c
+-!Edrivers/usb/core/buffer.c
++!Idrivers/usb/core/buffer.c
+     </chapter>
+ 
+     <chapter>
+diff --git a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl
+--- a/Documentation/DocBook/writing_usb_driver.tmpl
++++ b/Documentation/DocBook/writing_usb_driver.tmpl
+@@ -345,8 +345,7 @@ if (!retval) {
+   <programlisting>
+ static inline void skel_delete (struct usb_skel *dev)
+ {
+-    if (dev->bulk_in_buffer != NULL)
+-        kfree (dev->bulk_in_buffer);
++    kfree (dev->bulk_in_buffer);
+     if (dev->bulk_out_buffer != NULL)
+         usb_buffer_free (dev->udev, dev->bulk_out_size,
+             dev->bulk_out_buffer,
+diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt
+new file mode 100644
+--- /dev/null
++++ b/Documentation/RCU/torture.txt
+@@ -0,0 +1,122 @@
++RCU Torture Test Operation
++
++
++CONFIG_RCU_TORTURE_TEST
++
++The CONFIG_RCU_TORTURE_TEST config option is available for all RCU
++implementations.  It creates an rcutorture kernel module that can
++be loaded to run a torture test.  The test periodically outputs
++status messages via printk(), which can be examined via the dmesg
++command (perhaps grepping for "rcutorture").  The test is started
++when the module is loaded, and stops when the module is unloaded.
++
++However, actually setting this config option to "y" results in the system
++running the test immediately upon boot, and ending only when the system
++is taken down.  Normally, one will instead want to build the system
++with CONFIG_RCU_TORTURE_TEST=m and to use modprobe and rmmod to control
++the test, perhaps using a script similar to the one shown at the end of
++this document.  Note that you will need CONFIG_MODULE_UNLOAD in order
++to be able to end the test.
++
++
++MODULE PARAMETERS
++
++This module has the following parameters:
++
++nreaders	This is the number of RCU reading threads supported.
++		The default is twice the number of CPUs.  Why twice?
++		To properly exercise RCU implementations with preemptible
++		read-side critical sections.
++
++stat_interval	The number of seconds between output of torture
++		statistics (via printk()).  Regardless of the interval,
++		statistics are printed when the module is unloaded.
++		Setting the interval to zero causes the statistics to
++		be printed -only- when the module is unloaded, and this
++		is the default.
++
++verbose		Enable debug printk()s.  Default is disabled.
++
++
++OUTPUT
++
++The statistics output is as follows:
++
++	rcutorture: --- Start of test: nreaders=16 stat_interval=0 verbose=0
++	rcutorture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915
++	rcutorture: Reader Pipe:  1466408 9747 0 0 0 0 0 0 0 0 0
++	rcutorture: Reader Batch:  1464477 11678 0 0 0 0 0 0 0 0
++	rcutorture: Free-Block Circulation:  1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0
++	rcutorture: --- End of test
++
++The command "dmesg | grep rcutorture:" will extract this information on
++most systems.  On more esoteric configurations, it may be necessary to
++use other commands to access the output of the printk()s used by
++the RCU torture test.  The printk()s use KERN_ALERT, so they should
++be evident.  ;-)
++
++The entries are as follows:
++
++o	"ggp": The number of counter flips (or batches) since boot.
++
++o	"rtc": The hexadecimal address of the structure currently visible
++	to readers.
++
++o	"ver": The number of times since boot that the rcutw writer task
++	has changed the structure visible to readers.
++
++o	"tfle": If non-zero, indicates that the "torture freelist"
++	containing structure to be placed into the "rtc" area is empty.
++	This condition is important, since it can fool you into thinking
++	that RCU is working when it is not.  :-/
++
++o	"rta": Number of structures allocated from the torture freelist.
++
++o	"rtaf": Number of allocations from the torture freelist that have
++	failed due to the list being empty.
++
++o	"rtf": Number of frees into the torture freelist.
++
++o	"Reader Pipe": Histogram of "ages" of structures seen by readers.
++	If any entries past the first two are non-zero, RCU is broken.
++	And rcutorture prints the error flag string "!!!" to make sure
++	you notice.  The age of a newly allocated structure is zero,
++	it becomes one when removed from reader visibility, and is
++	incremented once per grace period subsequently -- and is freed
++	after passing through (RCU_TORTURE_PIPE_LEN-2) grace periods.
++
++	The output displayed above was taken from a correctly working
++	RCU.  If you want to see what it looks like when broken, break
++	it yourself.  ;-)
++
++o	"Reader Batch": Another histogram of "ages" of structures seen
++	by readers, but in terms of counter flips (or batches) rather
++	than in terms of grace periods.  The legal number of non-zero
++	entries is again two.  The reason for this separate view is
++	that it is easier to get the third entry to show up in the
++	"Reader Batch" list than in the "Reader Pipe" list.
++
++o	"Free-Block Circulation": Shows the number of torture structures
++	that have reached a given point in the pipeline.  The first element
++	should closely correspond to the number of structures allocated,
++	the second to the number that have been removed from reader view,
++	and all but the last remaining to the corresponding number of
++	passes through a grace period.  The last entry should be zero,
++	as it is only incremented if a torture structure's counter
++	somehow gets incremented farther than it should.
++
++
++USAGE
++
++The following script may be used to torture RCU:
++
++	#!/bin/sh
++
++	modprobe rcutorture
++	sleep 100
++	rmmod rcutorture
++	dmesg | grep rcutorture:
++
++The output can be manually inspected for the error flag of "!!!".
++One could of course create a more elaborate script that automatically
++checked for such errors.
+diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt
+--- a/Documentation/arm/Samsung-S3C24XX/Overview.txt
++++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt
+@@ -81,7 +81,8 @@ Adding New Machines
+ 
+   Any large scale modifications, or new drivers should be discussed
+   on the ARM kernel mailing list (linux-arm-kernel) before being
+-  attempted.
++  attempted. See http://www.arm.linux.org.uk/mailinglists/ for the
++  mailing list information.
+ 
+ 
+ NAND
+@@ -120,6 +121,43 @@ Clock Management
+   various clock units
+ 
+ 
++Platform Data
++-------------
++
++  Whenever a device has platform specific data that is specified
++  on a per-machine basis, care should be taken to ensure the
++  following:
++
++    1) that default data is not left in the device to confuse the
++       driver if a machine does not set it at startup
++
++    2) the data should (if possible) be marked as __initdata,
++       to ensure that the data is thrown away if the machine is
++       not the one currently in use.
++
++       The best way of doing this is to make a function that
++       kmalloc()s an area of memory, and copies the __initdata
++       and then sets the relevant device's platform data. Making
++       the function `__init` takes care of ensuring it is discarded
++       with the rest of the initialisation code
++
++       static __init void s3c24xx_xxx_set_platdata(struct xxx_data *pd)
++       {
++           struct s3c2410_xxx_mach_info *npd;
++
++	   npd = kmalloc(sizeof(struct s3c2410_xxx_mach_info), GFP_KERNEL);
++	   if (npd) {
++	      memcpy(npd, pd, sizeof(struct s3c2410_xxx_mach_info));
++	      s3c_device_xxx.dev.platform_data = npd;
++	   } else {
++              printk(KERN_ERR "no memory for xxx platform data\n");
++	   }
++	}
++
++	Note, since the code is marked as __init, it should not be
++	exported outside arch/arm/mach-s3c2410/, or exported to
++	modules via EXPORT_SYMBOL() and related functions.
++
+ Port Contributors
+ -----------------
+ 
+@@ -149,6 +187,7 @@ Document Changes
+   06 Mar 2005 - BJD - Added Christer Weinigel
+   08 Mar 2005 - BJD - Added LCVR to list of people, updated introduction
+   08 Mar 2005 - BJD - Added section on adding machines
++  09 Sep 2005 - BJD - Added section on platform data
+ 
+ Document Author
+ ---------------
+diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
+--- a/Documentation/block/biodoc.txt
++++ b/Documentation/block/biodoc.txt
+@@ -906,9 +906,20 @@ Aside:
+ 
+ 
+ 4. The I/O scheduler
+-I/O schedulers are now per queue. They should be runtime switchable and modular
+-but aren't yet. Jens has most bits to do this, but the sysfs implementation is
+-missing.
++I/O scheduler, a.k.a. elevator, is implemented in two layers.  Generic dispatch
++queue and specific I/O schedulers.  Unless stated otherwise, elevator is used
++to refer to both parts and I/O scheduler to specific I/O schedulers.
++
++Block layer implements generic dispatch queue in ll_rw_blk.c and elevator.c.
++The generic dispatch queue is responsible for properly ordering barrier
++requests, requeueing, handling non-fs requests and all other subtleties.
++
++Specific I/O schedulers are responsible for ordering normal filesystem
++requests.  They can also choose to delay certain requests to improve
++throughput or whatever purpose.  As the plural form indicates, there are
++multiple I/O schedulers.  They can be built as modules but at least one should
++be built inside the kernel.  Each queue can choose different one and can also
++change to another one dynamically.
+ 
+ A block layer call to the i/o scheduler follows the convention elv_xxx(). This
+ calls elevator_xxx_fn in the elevator switch (drivers/block/elevator.c). Oh,
+@@ -921,44 +932,36 @@ keeping work.
+ The functions an elevator may implement are: (* are mandatory)
+ elevator_merge_fn		called to query requests for merge with a bio
+ 
+-elevator_merge_req_fn		" " "  with another request
++elevator_merge_req_fn		called when two requests get merged. the one
++				which gets merged into the other one will be
++				never seen by I/O scheduler again. IOW, after
++				being merged, the request is gone.
+ 
+ elevator_merged_fn		called when a request in the scheduler has been
+ 				involved in a merge. It is used in the deadline
+ 				scheduler for example, to reposition the request
+ 				if its sorting order has changed.
+ 
+-*elevator_next_req_fn		returns the next scheduled request, or NULL
+-				if there are none (or none are ready).
++elevator_dispatch_fn		fills the dispatch queue with ready requests.
++				I/O schedulers are free to postpone requests by
++				not filling the dispatch queue unless @force
++				is non-zero.  Once dispatched, I/O schedulers
++				are not allowed to manipulate the requests -
++				they belong to generic dispatch queue.
+ 
+-*elevator_add_req_fn		called to add a new request into the scheduler
++elevator_add_req_fn		called to add a new request into the scheduler
+ 
+ elevator_queue_empty_fn		returns true if the merge queue is empty.
+ 				Drivers shouldn't use this, but rather check
+ 				if elv_next_request is NULL (without losing the
+ 				request if one exists!)
+ 
+-elevator_remove_req_fn		This is called when a driver claims ownership of
+-				the target request - it now belongs to the
+-				driver. It must not be modified or merged.
+-				Drivers must not lose the request! A subsequent
+-				call of elevator_next_req_fn must  return the
+-				_next_ request.
+-
+-elevator_requeue_req_fn		called to add a request to the scheduler. This
+-				is used when the request has alrnadebeen
+-				returned by elv_next_request, but hasn't
+-				completed. If this is not implemented then
+-				elevator_add_req_fn is called instead.
+-
+ elevator_former_req_fn
+ elevator_latter_req_fn		These return the request before or after the
+ 				one specified in disk sort order. Used by the
+ 				block layer to find merge possibilities.
+ 
+-elevator_completed_req_fn	called when a request is completed. This might
+-				come about due to being merged with another or
+-				when the device completes the request.
++elevator_completed_req_fn	called when a request is completed.
+ 
+ elevator_may_queue_fn		returns true if the scheduler wants to allow the
+ 				current context to queue a new request even if
+@@ -967,13 +970,33 @@ elevator_may_queue_fn		returns true if t
+ 
+ elevator_set_req_fn
+ elevator_put_req_fn		Must be used to allocate and free any elevator
+-				specific storate for a request.
++				specific storage for a request.
++
++elevator_activate_req_fn	Called when device driver first sees a request.
++				I/O schedulers can use this callback to
++				determine when actual execution of a request
++				starts.
++elevator_deactivate_req_fn	Called when device driver decides to delay
++				a request by requeueing it.
+ 
+ elevator_init_fn
+ elevator_exit_fn		Allocate and free any elevator specific storage
+ 				for a queue.
+ 
+-4.2 I/O scheduler implementation
++4.2 Request flows seen by I/O schedulers
++All requests seens by I/O schedulers strictly follow one of the following three
++flows.
++
++ set_req_fn ->
++
++ i.   add_req_fn -> (merged_fn ->)* -> dispatch_fn -> activate_req_fn ->
++      (deactivate_req_fn -> activate_req_fn ->)* -> completed_req_fn
++ ii.  add_req_fn -> (merged_fn ->)* -> merge_req_fn
++ iii. [none]
++
++ -> put_req_fn
++
++4.3 I/O scheduler implementation
+ The generic i/o scheduler algorithm attempts to sort/merge/batch requests for
+ optimal disk scan and request servicing performance (based on generic
+ principles and device capabilities), optimized for:
+@@ -993,18 +1016,7 @@ request in sort order to prevent binary 
+ This arrangement is not a generic block layer characteristic however, so
+ elevators may implement queues as they please.
+ 
+-ii. Last merge hint
+-The last merge hint is part of the generic queue layer. I/O schedulers must do
+-some management on it. For the most part, the most important thing is to make
+-sure q->last_merge is cleared (set to NULL) when the request on it is no longer
+-a candidate for merging (for example if it has been sent to the driver).
+-
+-The last merge performed is cached as a hint for the subsequent request. If
+-sequential data is being submitted, the hint is used to perform merges without
+-any scanning. This is not sufficient when there are multiple processes doing
+-I/O though, so a "merge hash" is used by some schedulers.
+-
+-iii. Merge hash
++ii. Merge hash
+ AS and deadline use a hash table indexed by the last sector of a request. This
+ enables merging code to quickly look up "back merge" candidates, even when
+ multiple I/O streams are being performed at once on one disk.
+@@ -1013,29 +1025,8 @@ multiple I/O streams are being performed
+ are far less common than "back merges" due to the nature of most I/O patterns.
+ Front merges are handled by the binary trees in AS and deadline schedulers.
+ 
+-iv. Handling barrier cases
+-A request with flags REQ_HARDBARRIER or REQ_SOFTBARRIER must not be ordered
+-around. That is, they must be processed after all older requests, and before
+-any newer ones. This includes merges!
+-
+-In AS and deadline schedulers, barriers have the effect of flushing the reorder
+-queue. The performance cost of this will vary from nothing to a lot depending
+-on i/o patterns and device characteristics. Obviously they won't improve
+-performance, so their use should be kept to a minimum.
+-
+-v. Handling insertion position directives
+-A request may be inserted with a position directive. The directives are one of
+-ELEVATOR_INSERT_BACK, ELEVATOR_INSERT_FRONT, ELEVATOR_INSERT_SORT.
+-
+-ELEVATOR_INSERT_SORT is a general directive for non-barrier requests.
+-ELEVATOR_INSERT_BACK is used to insert a barrier to the back of the queue.
+-ELEVATOR_INSERT_FRONT is used to insert a barrier to the front of the queue, and
+-overrides the ordering requested by any previous barriers. In practice this is
+-harmless and required, because it is used for SCSI requeueing. This does not
+-require flushing the reorder queue, so does not impose a performance penalty.
+-
+-vi. Plugging the queue to batch requests in anticipation of opportunities for
+-  merge/sort optimizations
++iii. Plugging the queue to batch requests in anticipation of opportunities for
++     merge/sort optimizations
+ 
+ This is just the same as in 2.4 so far, though per-device unplugging
+ support is anticipated for 2.5. Also with a priority-based i/o scheduler,
+@@ -1069,7 +1060,7 @@ Aside:
+   blk_kick_queue() to unplug a specific queue (right away ?)
+   or optionally, all queues, is in the plan.
+ 
+-4.3 I/O contexts
++4.4 I/O contexts
+ I/O contexts provide a dynamically allocated per process data area. They may
+ be used in I/O schedulers, and in the block layer (could be used for IO statis,
+ priorities for example). See *io_context in drivers/block/ll_rw_blk.c, and
+diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt
+--- a/Documentation/cachetlb.txt
++++ b/Documentation/cachetlb.txt
+@@ -49,9 +49,6 @@ changes occur:
+ 	page table operations such as what happens during
+ 	fork, and exec.
+ 
+-	Platform developers note that generic code will always
+-	invoke this interface without mm->page_table_lock held.
+-
+ 3) void flush_tlb_range(struct vm_area_struct *vma,
+ 			unsigned long start, unsigned long end)
+ 
+@@ -72,9 +69,6 @@ changes occur:
+ 	call flush_tlb_page (see below) for each entry which may be
+ 	modified.
+ 
+-	Platform developers note that generic code will always
+-	invoke this interface with mm->page_table_lock held.
+-
+ 4) void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+ 
+ 	This time we need to remove the PAGE_SIZE sized translation
+@@ -93,9 +87,6 @@ changes occur:
+ 
+ 	This is used primarily during fault processing.
+ 
+-	Platform developers note that generic code will always
+-	invoke this interface with mm->page_table_lock held.
+-
+ 5) void flush_tlb_pgtables(struct mm_struct *mm,
+ 			   unsigned long start, unsigned long end)
+ 
+diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
+--- a/Documentation/cpusets.txt
++++ b/Documentation/cpusets.txt
+@@ -94,7 +94,7 @@ the available CPU and Memory resources a
+ But larger systems, which benefit more from careful processor and
+ memory placement to reduce memory access times and contention,
+ and which typically represent a larger investment for the customer,
+-can benefit from explictly placing jobs on properly sized subsets of
++can benefit from explicitly placing jobs on properly sized subsets of
+ the system.
+ 
+ This can be especially valuable on:
+diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt
+--- a/Documentation/driver-model/driver.txt
++++ b/Documentation/driver-model/driver.txt
+@@ -14,8 +14,8 @@ struct device_driver {
+         int     (*probe)        (struct device * dev);
+         int     (*remove)       (struct device * dev);
+ 
+-        int     (*suspend)      (struct device * dev, pm_message_t state, u32 level);
+-        int     (*resume)       (struct device * dev, u32 level);
++        int     (*suspend)      (struct device * dev, pm_message_t state);
++        int     (*resume)       (struct device * dev);
+ };
+ 
+ 
+@@ -194,69 +194,13 @@ device; i.e. anything in the device's dr
+ If the device is still present, it should quiesce the device and place
+ it into a supported low-power state.
+ 
+-	int	(*suspend)	(struct device * dev, pm_message_t state, u32 level);
++	int	(*suspend)	(struct device * dev, pm_message_t state);
+ 
+-suspend is called to put the device in a low power state. There are
+-several stages to successfully suspending a device, which is denoted in
+-the @level parameter. Breaking the suspend transition into several
+-stages affords the platform flexibility in performing device power
+-management based on the requirements of the system and the
+-user-defined policy.
+-
+-SUSPEND_NOTIFY notifies the device that a suspend transition is about
+-to happen. This happens on system power state transitions to verify
+-that all devices can successfully suspend.
+-
+-A driver may choose to fail on this call, which should cause the
+-entire suspend transition to fail. A driver should fail only if it
+-knows that the device will not be able to be resumed properly when the
+-system wakes up again. It could also fail if it somehow determines it
+-is in the middle of an operation too important to stop.
+-
+-SUSPEND_DISABLE tells the device to stop I/O transactions. When it
+-stops transactions, or what it should do with unfinished transactions
+-is a policy of the driver. After this call, the driver should not
+-accept any other I/O requests.
+-
+-SUSPEND_SAVE_STATE tells the device to save the context of the
+-hardware. This includes any bus-specific hardware state and
+-device-specific hardware state. A pointer to this saved state can be
+-stored in the device's saved_state field.
+-
+-SUSPEND_POWER_DOWN tells the driver to place the device in the low
+-power state requested. 
+-
+-Whether suspend is called with a given level is a policy of the
+-platform. Some levels may be omitted; drivers must not assume the
+-reception of any level. However, all levels must be called in the
+-order above; i.e. notification will always come before disabling;
+-disabling the device will come before suspending the device.
+-
+-All calls are made with interrupts enabled, except for the
+-SUSPEND_POWER_DOWN level.
+-
+-	int	(*resume)	(struct device * dev, u32 level);
+-
+-Resume is used to bring a device back from a low power state. Like the
+-suspend transition, it happens in several stages. 
+-
+-RESUME_POWER_ON tells the driver to set the power state to the state
+-before the suspend call (The device could have already been in a low
+-power state before the suspend call to put in a lower power state). 
+-
+-RESUME_RESTORE_STATE tells the driver to restore the state saved by
+-the SUSPEND_SAVE_STATE suspend call. 
+-
+-RESUME_ENABLE tells the driver to start accepting I/O transactions
+-again. Depending on driver policy, the device may already have pending
+-I/O requests. 
+-
+-RESUME_POWER_ON is called with interrupts disabled. The other resume
+-levels are called with interrupts enabled. 
+-
+-As with the various suspend stages, the driver must not assume that
+-any other resume calls have been or will be made. Each call should be
+-self-contained and not dependent on any external state.
++suspend is called to put the device in a low power state.
++
++	int	(*resume)	(struct device * dev);
++
++Resume is used to bring a device back from a low power state.
+ 
+ 
+ Attributes
+diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.txt
+--- a/Documentation/driver-model/porting.txt
++++ b/Documentation/driver-model/porting.txt
+@@ -350,7 +350,7 @@ When a driver is registered, the bus's l
+ over. bus->match() is called for each device that is not already
+ claimed by a driver. 
+ 
+-When a device is successfully bound to a device, device->driver is
++When a device is successfully bound to a driver, device->driver is
+ set, the device is added to a per-driver list of devices, and a
+ symlink is created in the driver's sysfs directory that points to the
+ device's physical directory:
+diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt
+--- a/Documentation/filesystems/ntfs.txt
++++ b/Documentation/filesystems/ntfs.txt
+@@ -50,9 +50,14 @@ userspace utilities, etc.
+ Features
+ ========
+ 
+-- This is a complete rewrite of the NTFS driver that used to be in the kernel.
+-  This new driver implements NTFS read support and is functionally equivalent
+-  to the old ntfs driver.
++- This is a complete rewrite of the NTFS driver that used to be in the 2.4 and
++  earlier kernels.  This new driver implements NTFS read support and is
++  functionally equivalent to the old ntfs driver and it also implements limited
++  write support.  The biggest limitation at present is that files/directories
++  cannot be created or deleted.  See below for the list of write features that
++  are so far supported.  Another limitation is that writing to compressed files
++  is not implemented at all.  Also, neither read nor write access to encrypted
++  files is so far implemented.
+ - The new driver has full support for sparse files on NTFS 3.x volumes which
+   the old driver isn't happy with.
+ - The new driver supports execution of binaries due to mmap() now being
+@@ -78,7 +83,20 @@ Features
+ - The new driver supports fsync(2), fdatasync(2), and msync(2).
+ - The new driver supports readv(2) and writev(2).
+ - The new driver supports access time updates (including mtime and ctime).
+-
++- The new driver supports truncate(2) and open(2) with O_TRUNC.  But at present
++  only very limited support for highly fragmented files, i.e. ones which have
++  their data attribute split across multiple extents, is included.  Another
++  limitation is that at present truncate(2) will never create sparse files,
++  since to mark a file sparse we need to modify the directory entry for the
++  file and we do not implement directory modifications yet.
++- The new driver supports write(2) which can both overwrite existing data and
++  extend the file size so that you can write beyond the existing data.  Also,
++  writing into sparse regions is supported and the holes are filled in with
++  clusters.  But at present only limited support for highly fragmented files,
++  i.e. ones which have their data attribute split across multiple extents, is
++  included.  Another limitation is that write(2) will never create sparse
++  files, since to mark a file sparse we need to modify the directory entry for
++  the file and we do not implement directory modifications yet.
+ 
+ Supported mount options
+ =======================
+@@ -439,6 +457,22 @@ ChangeLog
+ 
+ Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
+ 
++2.1.25:
++	- Write support is now extended with write(2) being able to both
++	  overwrite existing file data and to extend files.  Also, if a write
++	  to a sparse region occurs, write(2) will fill in the hole.  Note,
++	  mmap(2) based writes still do not support writing into holes or
++	  writing beyond the initialized size.
++	- Write support has a new feature and that is that truncate(2) and
++	  open(2) with O_TRUNC are now implemented thus files can be both made
++	  smaller and larger.
++	- Note: Both write(2) and truncate(2)/open(2) with O_TRUNC still have
++	  limitations in that they
++	  - only provide limited support for highly fragmented files.
++	  - only work on regular, i.e. uncompressed and unencrypted files.
++	  - never create sparse files although this will change once directory
++	    operations are implemented.
++	- Lots of bug fixes and enhancements across the board.
+ 2.1.24:
+ 	- Support journals ($LogFile) which have been modified by chkdsk.  This
+ 	  means users can boot into Windows after we marked the volume dirty.
+diff --git a/Documentation/firmware_class/firmware_sample_driver.c b/Documentation/firmware_class/firmware_sample_driver.c
+--- a/Documentation/firmware_class/firmware_sample_driver.c
++++ b/Documentation/firmware_class/firmware_sample_driver.c
+@@ -13,6 +13,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
++#include <linux/string.h>
+ 
+ #include "linux/firmware.h"
+ 
+diff --git a/Documentation/firmware_class/firmware_sample_firmware_class.c b/Documentation/firmware_class/firmware_sample_firmware_class.c
+--- a/Documentation/firmware_class/firmware_sample_firmware_class.c
++++ b/Documentation/firmware_class/firmware_sample_firmware_class.c
+@@ -14,6 +14,8 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/timer.h>
++#include <linux/slab.h>
++#include <linux/string.h>
+ #include <linux/firmware.h>
+ 
+ 
+diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
+--- a/Documentation/hwmon/it87
++++ b/Documentation/hwmon/it87
+@@ -4,18 +4,18 @@ Kernel driver it87
+ Supported chips:
+   * IT8705F
+     Prefix: 'it87'
+-    Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports)
++    Addresses scanned: from Super I/O config space (8 I/O ports)
+     Datasheet: Publicly available at the ITE website
+                http://www.ite.com.tw/
+   * IT8712F
+     Prefix: 'it8712'
+     Addresses scanned: I2C 0x28 - 0x2f
+-                       from Super I/O config space, or default ISA 0x290 (8 I/O ports)
++                       from Super I/O config space (8 I/O ports)
+     Datasheet: Publicly available at the ITE website
+                http://www.ite.com.tw/
+   * SiS950   [clone of IT8705F]
+-    Prefix: 'sis950'
+-    Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports)
++    Prefix: 'it87'
++    Addresses scanned: from Super I/O config space (8 I/O ports)
+     Datasheet: No longer be available
+ 
+ Author: Christophe Gauthron <chrisg at 0-in.com>
+diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90
+--- a/Documentation/hwmon/lm90
++++ b/Documentation/hwmon/lm90
+@@ -24,14 +24,14 @@ Supported chips:
+                http://www.national.com/pf/LM/LM86.html
+   * Analog Devices ADM1032
+     Prefix: 'adm1032'
+-    Addresses scanned: I2C 0x4c
++    Addresses scanned: I2C 0x4c and 0x4d
+     Datasheet: Publicly available at the Analog Devices website
+-               http://products.analog.com/products/info.asp?product=ADM1032
++               http://www.analog.com/en/prod/0,2877,ADM1032,00.html
+   * Analog Devices ADT7461
+     Prefix: 'adt7461'
+-    Addresses scanned: I2C 0x4c
++    Addresses scanned: I2C 0x4c and 0x4d
+     Datasheet: Publicly available at the Analog Devices website
+-               http://products.analog.com/products/info.asp?product=ADT7461
++               http://www.analog.com/en/prod/0,2877,ADT7461,00.html
+     Note: Only if in ADM1032 compatibility mode
+   * Maxim MAX6657
+     Prefix: 'max6657'
+@@ -71,8 +71,8 @@ increased resolution of the remote tempe
+ 
+ The different chipsets of the family are not strictly identical, although
+ very similar. This driver doesn't handle any specific feature for now,
+-but could if there ever was a need for it. For reference, here comes a
+-non-exhaustive list of specific features:
++with the exception of SMBus PEC. For reference, here comes a non-exhaustive
++list of specific features:
+ 
+ LM90:
+   * Filter and alert configuration register at 0xBF.
+@@ -91,6 +91,7 @@ ADM1032:
+   * Conversion averaging.
+   * Up to 64 conversions/s.
+   * ALERT is triggered by open remote sensor.
++  * SMBus PEC support for Write Byte and Receive Byte transactions.
+ 
+ ADT7461
+   * Extended temperature range (breaks compatibility)
+@@ -119,3 +120,37 @@ The lm90 driver will not update its valu
+ other second; reading them more often will do no harm, but will return
+ 'old' values.
+ 
++PEC Support
++-----------
++
++The ADM1032 is the only chip of the family which supports PEC. It does
++not support PEC on all transactions though, so some care must be taken.
++
++When reading a register value, the PEC byte is computed and sent by the
++ADM1032 chip. However, in the case of a combined transaction (SMBus Read
++Byte), the ADM1032 computes the CRC value over only the second half of
++the message rather than its entirety, because it thinks the first half
++of the message belongs to a different transaction. As a result, the CRC
++value differs from what the SMBus master expects, and all reads fail.
++
++For this reason, the lm90 driver will enable PEC for the ADM1032 only if
++the bus supports the SMBus Send Byte and Receive Byte transaction types.
++These transactions will be used to read register values, instead of
++SMBus Read Byte, and PEC will work properly.
++
++Additionally, the ADM1032 doesn't support SMBus Send Byte with PEC.
++Instead, it will try to write the PEC value to the register (because the
++SMBus Send Byte transaction with PEC is similar to a Write Byte transaction
++without PEC), which is not what we want. Thus, PEC is explicitely disabled
++on SMBus Send Byte transactions in the lm90 driver.
++
++PEC on byte data transactions represents a significant increase in bandwidth
++usage (+33% for writes, +25% for reads) in normal conditions. With the need
++to use two SMBus transaction for reads, this overhead jumps to +50%. Worse,
++two transactions will typically mean twice as much delay waiting for
++transaction completion, effectively doubling the register cache refresh time.
++I guess reliability comes at a price, but it's quite expensive this time.
++
++So, as not everyone might enjoy the slowdown, PEC can be disabled through
++sysfs. Just write 0 to the "pec" file and PEC will be disabled. Write 1
++to that file to enable PEC again.
+diff --git a/Documentation/hwmon/smsc47b397 b/Documentation/hwmon/smsc47b397
+--- a/Documentation/hwmon/smsc47b397
++++ b/Documentation/hwmon/smsc47b397
+@@ -3,6 +3,7 @@ Kernel driver smsc47b397
+ 
+ Supported chips:
+   * SMSC LPC47B397-NC
++  * SMSC SCH5307-NS
+     Prefix: 'smsc47b397'
+     Addresses scanned: none, address read from Super I/O config space
+     Datasheet: In this file
+@@ -12,11 +13,14 @@ Authors: Mark M. Hoffman <mhoffman at light
+ 
+ November 23, 2004
+ 
+-The following specification describes the SMSC LPC47B397-NC sensor chip
++The following specification describes the SMSC LPC47B397-NC[1] sensor chip
+ (for which there is no public datasheet available). This document was
+ provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected
+ by Mark M. Hoffman <mhoffman at lightlink.com>.
+ 
++[1] And SMSC SCH5307-NS, which has a different device ID but is otherwise
++compatible.
++
+ * * * * *
+ 
+ Methods for detecting the HP SIO and reading the thermal data on a dc7100.
+@@ -127,7 +131,7 @@ OUT	DX,AL
+ The registers of interest for identifying the SIO on the dc7100 are Device ID
+ (0x20) and Device Rev  (0x21).
+ 
+-The Device ID will read 0X6F
++The Device ID will read 0x6F (for SCH5307-NS, 0x81)
+ The Device Rev currently reads 0x01
+ 
+ Obtaining the HWM Base Address.
+diff --git a/Documentation/hwmon/smsc47m1 b/Documentation/hwmon/smsc47m1
+--- a/Documentation/hwmon/smsc47m1
++++ b/Documentation/hwmon/smsc47m1
+@@ -12,6 +12,10 @@ Supported chips:
+         http://www.smsc.com/main/datasheets/47m14x.pdf
+         http://www.smsc.com/main/tools/discontinued/47m15x.pdf
+         http://www.smsc.com/main/datasheets/47m192.pdf
++  * SMSC LPC47M997
++    Addresses scanned: none, address read from Super I/O config space
++    Prefix: 'smsc47m1'
++    Datasheet: none
+ 
+ Authors:
+         Mark D. Studebaker <mdsxyz123 at yahoo.com>,
+@@ -30,6 +34,9 @@ The 47M15x and 47M192 chips contain a fu
+ in addition to the fan monitoring and control. The hardware monitoring
+ block is not supported by the driver.
+ 
++No documentation is available for the 47M997, but it has the same device
++ID as the 47M15x and 47M192 chips and seems to be compatible.
++
+ 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 or 8) to give
+diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
+--- a/Documentation/hwmon/sysfs-interface
++++ b/Documentation/hwmon/sysfs-interface
+@@ -272,3 +272,6 @@ beep_mask	Bitmask for beep.
+ 
+ eeprom		Raw EEPROM data in binary form.
+ 		Read only.
++
++pec		Enable or disable PEC (SMBus only)
++		Read/Write
+diff --git a/Documentation/hwmon/via686a b/Documentation/hwmon/via686a
+--- a/Documentation/hwmon/via686a
++++ b/Documentation/hwmon/via686a
+@@ -18,8 +18,9 @@ Authors:
+ Module Parameters
+ -----------------
+ 
+-force_addr=0xaddr       Set the I/O base address. Useful for Asus A7V boards
+-                        that don't set the address in the BIOS. Does not do a
++force_addr=0xaddr       Set the I/O base address. Useful for boards that
++                        don't set the address in the BIOS. Look for a BIOS
++                        upgrade before resorting to this. Does not do a
+                         PCI force; the via686a must still be present in lspci.
+                         Don't use this unless the driver complains that the
+                         base address is not set.
+@@ -63,3 +64,15 @@ miss once-only alarms.
+ 
+ The driver only updates its values each 1.5 seconds; reading it more often
+ will do no harm, but will return 'old' values.
++
++Known Issues
++------------
++
++This driver handles sensors integrated in some VIA south bridges. It is
++possible that a motherboard maker used a VT82C686A/B chip as part of a
++product design but was not interested in its hardware monitoring features,
++in which case the sensor inputs will not be wired. This is the case of
++the Asus K7V, A7V and A7V133 motherboards, to name only a few of them.
++So, if you need the force_addr parameter, and end up with values which
++don't seem to make any sense, don't look any further: your chip is simply
++not wired for hardware monitoring.
+diff --git a/Documentation/i2c/busses/i2c-i810 b/Documentation/i2c/busses/i2c-i810
+--- a/Documentation/i2c/busses/i2c-i810
++++ b/Documentation/i2c/busses/i2c-i810
+@@ -2,6 +2,7 @@ Kernel driver i2c-i810
+ 
+ Supported adapters:
+   * Intel 82810, 82810-DC100, 82810E, and 82815 (GMCH)
++  * Intel 82845G (GMCH)
+ 
+ Authors: 
+ 	Frodo Looijaard <frodol at dds.nl>, 
+diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro
+--- a/Documentation/i2c/busses/i2c-viapro
++++ b/Documentation/i2c/busses/i2c-viapro
+@@ -4,17 +4,18 @@ Supported adapters:
+   * VIA Technologies, Inc. VT82C596A/B
+     Datasheet: Sometimes available at the VIA website
+ 
+-  * VIA Technologies, Inc. VT82C686A/B 
++  * VIA Technologies, Inc. VT82C686A/B
+     Datasheet: Sometimes available at the VIA website
+ 
+   * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237
+     Datasheet: available on request from Via
+ 
+ Authors:
+-	Frodo Looijaard <frodol at dds.nl>,  
+-	Philip Edelbrock <phil at netroedge.com>, 
+-	Kyösti Mälkki <kmalkki at cc.hut.fi>, 
+-	Mark D. Studebaker <mdsxyz123 at yahoo.com> 
++	Frodo Looijaard <frodol at dds.nl>,
++	Philip Edelbrock <phil at netroedge.com>,
++	Kyösti Mälkki <kmalkki at cc.hut.fi>,
++	Mark D. Studebaker <mdsxyz123 at yahoo.com>,
++	Jean Delvare <khali at linux-fr.org>
+ 
+ Module Parameters
+ -----------------
+@@ -28,20 +29,22 @@ Description
+ -----------
+ 
+ i2c-viapro is a true SMBus host driver for motherboards with one of the
+-supported VIA southbridges.
++supported VIA south bridges.
+ 
+ Your lspci -n listing must show one of these :
+ 
+- device 1106:3050   (VT82C596 function 3)
+- device 1106:3051   (VT82C596 function 3)
++ device 1106:3050   (VT82C596A function 3)
++ device 1106:3051   (VT82C596B function 3)
+  device 1106:3057   (VT82C686 function 4)
+  device 1106:3074   (VT8233)
+  device 1106:3147   (VT8233A)
+- device 1106:8235   (VT8231)
+- devide 1106:3177   (VT8235)
+- devide 1106:3227   (VT8237)
++ device 1106:8235   (VT8231 function 4)
++ device 1106:3177   (VT8235)
++ device 1106:3227   (VT8237R)
+ 
+ If none of these show up, you should look in the BIOS for settings like
+ enable ACPI / SMBus or even USB.
+ 
+-
++Except for the oldest chips (VT82C596A/B, VT82C686A and most probably
++VT8231), this driver supports I2C block transactions. Such transactions
++are mainly useful to read from and write to EEPROMs.
+diff --git a/Documentation/i2c/chips/x1205 b/Documentation/i2c/chips/x1205
+new file mode 100644
+--- /dev/null
++++ b/Documentation/i2c/chips/x1205
+@@ -0,0 +1,38 @@
++Kernel driver x1205
++===================
++
++Supported chips:
++  * Xicor X1205 RTC
++    Prefix: 'x1205'
++    Addresses scanned: none
++    Datasheet: http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
++
++Authors:
++	Karen Spearel <kas11 at tampabay.rr.com>,
++	Alessandro Zummo <a.zummo at towertech.it>
++
++Description
++-----------
++
++This module aims to provide complete access to the Xicor X1205 RTC.
++Recently Xicor has merged with Intersil, but the chip is
++still sold under the Xicor brand.
++
++This chip is located at address 0x6f and uses a 2-byte register addressing.
++Two bytes need to be written to read a single register, while most
++other chips just require one and take the second one as the data
++to be written. To prevent corrupting unknown chips, the user must
++explicitely set the probe parameter.
++
++example:
++
++modprobe x1205 probe=0,0x6f
++
++The module supports one more option, hctosys, which is used to set the
++software clock from the x1205. On systems where the x1205 is the
++only hardware rtc, this parameter could be used to achieve a correct
++date/time earlier in the system boot sequence.
++
++example:
++
++modprobe x1205 probe=0,0x6f hctosys=1
+diff --git a/Documentation/i2c/functionality b/Documentation/i2c/functionality
+--- a/Documentation/i2c/functionality
++++ b/Documentation/i2c/functionality
+@@ -17,9 +17,10 @@ For the most up-to-date list of function
+   I2C_FUNC_I2C                    Plain i2c-level commands (Pure SMBus
+                                   adapters typically can not do these)
+   I2C_FUNC_10BIT_ADDR             Handles the 10-bit address extensions
+-  I2C_FUNC_PROTOCOL_MANGLING      Knows about the I2C_M_REV_DIR_ADDR,
+-                                  I2C_M_REV_DIR_ADDR and I2C_M_REV_DIR_NOSTART
+-                                  flags (which modify the i2c protocol!)
++  I2C_FUNC_PROTOCOL_MANGLING      Knows about the I2C_M_IGNORE_NAK,
++                                  I2C_M_REV_DIR_ADDR, I2C_M_NOSTART and
++                                  I2C_M_NO_RD_ACK flags (which modify the
++                                  I2C protocol!)
+   I2C_FUNC_SMBUS_QUICK            Handles the SMBus write_quick command
+   I2C_FUNC_SMBUS_READ_BYTE        Handles the SMBus read_byte command
+   I2C_FUNC_SMBUS_WRITE_BYTE       Handles the SMBus write_byte command
+diff --git a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients
+--- a/Documentation/i2c/porting-clients
++++ b/Documentation/i2c/porting-clients
+@@ -82,7 +82,7 @@ Technical changes:
+   exit and exit_free. For i2c+isa drivers, labels should be named
+   ERROR0, ERROR1 and ERROR2. Don't forget to properly set err before
+   jumping to error labels. By the way, labels should be left-aligned.
+-  Use memset to fill the client and data area with 0x00.
++  Use kzalloc instead of kmalloc.
+   Use i2c_set_clientdata to set the client data (as opposed to
+   a direct access to client->data).
+   Use strlcpy instead of strcpy to copy the client name.
+diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
+--- a/Documentation/i2c/writing-clients
++++ b/Documentation/i2c/writing-clients
+@@ -33,8 +33,8 @@ static struct i2c_driver foo_driver = {
+ 	.command	= &foo_command /* may be NULL */
+ }
+  
+-The name can be chosen freely, and may be upto 40 characters long. Please
+-use something descriptive here.
++The name field must match the driver name, including the case. It must not
++contain spaces, and may be up to 31 characters long.
+ 
+ Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
+ means that your driver will be notified when new adapters are found.
+@@ -43,9 +43,6 @@ This is almost always what you want.
+ All other fields are for call-back functions which will be explained 
+ below.
+ 
+-There use to be two additional fields in this structure, inc_use et dec_use,
+-for module usage count, but these fields were obsoleted and removed.
+-
+ 
+ Extra client data
+ =================
+@@ -58,6 +55,7 @@ be very useful.
+ An example structure is below.
+ 
+   struct foo_data {
++    struct i2c_client client;
+     struct semaphore lock; /* For ISA access in `sensors' drivers. */
+     int sysctl_id;         /* To keep the /proc directory entry for 
+                               `sensors' drivers. */
+@@ -275,6 +273,7 @@ For now, you can ignore the `flags' para
+     if (is_isa) {
+ 
+       /* Discard immediately if this ISA range is already used */
++      /* FIXME: never use check_region(), only request_region() */
+       if (check_region(address,FOO_EXTENT))
+         goto ERROR0;
+ 
+@@ -310,22 +309,15 @@ For now, you can ignore the `flags' para
+        client structure, even though we cannot fill it completely yet.
+        But it allows us to access several i2c functions safely */
+     
+-    /* Note that we reserve some space for foo_data too. If you don't
+-       need it, remove it. We do it here to help to lessen memory
+-       fragmentation. */
+-    if (! (new_client = kmalloc(sizeof(struct i2c_client) + 
+-                                sizeof(struct foo_data),
+-                                GFP_KERNEL))) {
++    if (!(data = kzalloc(sizeof(struct foo_data), GFP_KERNEL))) {
+       err = -ENOMEM;
+       goto ERROR0;
+     }
+ 
+-    /* This is tricky, but it will set the data to the right value. */
+-    client->data = new_client + 1;
+-    data = (struct foo_data *) (client->data);
++    new_client = &data->client;
++    i2c_set_clientdata(new_client, data);
+ 
+     new_client->addr = address;
+-    new_client->data = data;
+     new_client->adapter = adapter;
+     new_client->driver = &foo_driver;
+     new_client->flags = 0;
+@@ -451,7 +443,7 @@ much simpler than the attachment code, f
+       release_region(client->addr,LM78_EXTENT);
+     /* HYBRID SENSORS CHIP ONLY END */
+ 
+-    kfree(client); /* Frees client data too, if allocated at the same time */
++    kfree(data);
+     return 0;
+   }
+ 
+@@ -576,12 +568,12 @@ SMBus communication
+   extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
+                                         u8 command, u8 length,
+                                         u8 *values);
++  extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
++                                           u8 command, u8 *values);
+ 
+ These ones were removed in Linux 2.6.10 because they had no users, but could
+ be added back later if needed:
+ 
+-  extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
+-                                           u8 command, u8 *values);
+   extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
+                                        u8 command, u8 *values);
+   extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
+diff --git a/Documentation/input/yealink.txt b/Documentation/input/yealink.txt
+--- a/Documentation/input/yealink.txt
++++ b/Documentation/input/yealink.txt
+@@ -2,7 +2,6 @@ Driver documentation for yealink usb-p1k
+ 
+ 0. Status
+ ~~~~~~~~~
+-
+ The p1k is a relatively cheap usb 1.1 phone with:
+   - keyboard		full support, yealink.ko / input event API
+   - LCD			full support, yealink.ko / sysfs API
+@@ -17,9 +16,8 @@ For vendor documentation see http://www.
+ 
+ 1. Compilation (stand alone version)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-
+ Currently only kernel 2.6.x.y versions are supported.
+-In order to build the yealink.ko module do:
++In order to build the yealink.ko module do
+ 
+   make
+ 
+@@ -28,6 +26,21 @@ the Makefile is pointing to the location
+ are located, default /usr/src/linux.
+ 
+ 
++1.1 Troubleshooting
++~~~~~~~~~~~~~~~~~~~
++Q: Module yealink compiled and installed without any problem but phone
++   is not initialized and does not react to any actions.
++A: If you see something like:
++   hiddev0: USB HID v1.00 Device [Yealink Network Technology Ltd. VOIP USB Phone
++   in dmesg, it means that the hid driver has grabbed the device first. Try to
++   load module yealink before any other usb hid driver. Please see the
++   instructions provided by your distribution on module configuration.
++
++Q: Phone is working now (displays version and accepts keypad input) but I can't
++   find the sysfs files.
++A: The sysfs files are located on the particular usb endpoint. On most
++   distributions you can do: "find /sys/ -name get_icons" for a hint.
++
+ 
+ 2. keyboard features
+ ~~~~~~~~~~~~~~~~~~~~
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1460,8 +1460,6 @@ running once the system is up.
+ 	stifb=		[HW]
+ 			Format: bpp:<bpp1>[:<bpp2>[:<bpp3>...]]
+ 
+-	stram_swap=	[HW,M68k]
+-
+ 	swiotlb=	[IA-64] Number of I/O TLB slabs
+ 
+ 	switches=	[HW,M68k]
+@@ -1517,8 +1515,6 @@ running once the system is up.
+ 	uart6850=	[HW,OSS]
+ 			Format: <io>,<irq>
+ 
+-	usb-handoff	[HW] Enable early USB BIOS -> OS handoff
+-
+ 	usbhid.mousepoll=
+ 			[USBHID] The interval which mice are to be polled at.
+ 
+diff --git a/Documentation/keys.txt b/Documentation/keys.txt
+--- a/Documentation/keys.txt
++++ b/Documentation/keys.txt
+@@ -196,7 +196,7 @@ KEY ACCESS PERMISSIONS
+ 
+ Keys have an owner user ID, a group access ID, and a permissions mask. The mask
+ has up to eight bits each for possessor, user, group and other access. Only
+-five of each set of eight bits are defined. These permissions granted are:
++six of each set of eight bits are defined. These permissions granted are:
+ 
+  (*) View
+ 
+@@ -224,6 +224,10 @@ five of each set of eight bits are defin
+      keyring to a key, a process must have Write permission on the keyring and
+      Link permission on the key.
+ 
++ (*) Set Attribute
++
++     This permits a key's UID, GID and permissions mask to be changed.
++
+ For changing the ownership, group ID or permissions mask, being the owner of
+ the key or having the sysadmin capability is sufficient.
+ 
+@@ -242,15 +246,15 @@ about the status of the key service:
+      this way:
+ 
+ 	SERIAL   FLAGS  USAGE EXPY PERM     UID   GID   TYPE      DESCRIPTION: SUMMARY
+-	00000001 I-----    39 perm 1f1f0000     0     0 keyring   _uid_ses.0: 1/4
+-	00000002 I-----     2 perm 1f1f0000     0     0 keyring   _uid.0: empty
+-	00000007 I-----     1 perm 1f1f0000     0     0 keyring   _pid.1: empty
+-	0000018d I-----     1 perm 1f1f0000     0     0 keyring   _pid.412: empty
+-	000004d2 I--Q--     1 perm 1f1f0000    32    -1 keyring   _uid.32: 1/4
+-	000004d3 I--Q--     3 perm 1f1f0000    32    -1 keyring   _uid_ses.32: empty
++	00000001 I-----    39 perm 1f3f0000     0     0 keyring   _uid_ses.0: 1/4
++	00000002 I-----     2 perm 1f3f0000     0     0 keyring   _uid.0: empty
++	00000007 I-----     1 perm 1f3f0000     0     0 keyring   _pid.1: empty
++	0000018d I-----     1 perm 1f3f0000     0     0 keyring   _pid.412: empty
++	000004d2 I--Q--     1 perm 1f3f0000    32    -1 keyring   _uid.32: 1/4
++	000004d3 I--Q--     3 perm 1f3f0000    32    -1 keyring   _uid_ses.32: empty
+ 	00000892 I--QU-     1 perm 1f000000     0     0 user      metal:copper: 0
+-	00000893 I--Q-N     1  35s 1f1f0000     0     0 user      metal:silver: 0
+-	00000894 I--Q--     1  10h 001f0000     0     0 user      metal:gold: 0
++	00000893 I--Q-N     1  35s 1f3f0000     0     0 user      metal:silver: 0
++	00000894 I--Q--     1  10h 003f0000     0     0 user      metal:gold: 0
+ 
+      The flags are:
+ 
+diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt
+--- a/Documentation/m68k/kernel-options.txt
++++ b/Documentation/m68k/kernel-options.txt
+@@ -626,7 +626,7 @@ ignored (others aren't affected).
+     can be performed in optimal order. Not all SCSI devices support
+     tagged queuing (:-().
+ 
+-4.6 switches=
++4.5 switches=
+ -------------
+ 
+ Syntax: switches=<list of switches>
+@@ -661,28 +661,6 @@ correctly.
+ earlier initialization ("ov_"-less) takes precedence. But the
+ switching-off on reset still happens in this case.
+ 
+-4.5) stram_swap=
+-----------------
+-
+-Syntax: stram_swap=<do_swap>[,<max_swap>]
+-
+-  This option is available only if the kernel has been compiled with
+-CONFIG_STRAM_SWAP enabled. Normally, the kernel then determines
+-dynamically whether to actually use ST-RAM as swap space. (Currently,
+-the fraction of ST-RAM must be less or equal 1/3 of total memory to
+-enable this swapping.) You can override the kernel's decision by
+-specifying this option. 1 for <do_swap> means always enable the swap,
+-even if you have less alternate RAM. 0 stands for never swap to
+-ST-RAM, even if it's small enough compared to the rest of memory.
+-
+-  If ST-RAM swapping is enabled, the kernel usually uses all free
+-ST-RAM as swap "device". If the kernel resides in ST-RAM, the region
+-allocated by it is obviously never used for swapping :-) You can also
+-limit this amount by specifying the second parameter, <max_swap>, if
+-you want to use parts of ST-RAM as normal system memory. <max_swap> is
+-in kBytes and the number should be a multiple of 4 (otherwise: rounded
+-down).
+-
+ 5) Options for Amiga Only:
+ ==========================
+ 
+diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README
+new file mode 100644
+--- /dev/null
++++ b/Documentation/mips/AU1xxx_IDE.README
+@@ -0,0 +1,168 @@
++README for MIPS AU1XXX IDE driver - Released 2005-07-15
++
++ABOUT
++-----
++This file describes the 'drivers/ide/mips/au1xxx-ide.c', related files and the
++services they provide.
++
++If you are short in patience and just want to know how to add your hard disc to
++the white or black list, go to the 'ADD NEW HARD DISC TO WHITE OR BLACK LIST'
++section.
++
++
++LICENSE
++-------
++
++Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
++
++This program is free software; you can redistribute it and/or modify it under
++the terms of the 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 SOFTWARE IS PROVIDED ``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 AUTHOR
++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.
++
++You 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.
++
++Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
++      Interface and Linux Device Driver" Application Note.
++
++
++FILES, CONFIGS AND COMPATABILITY
++--------------------------------
++
++Two files are introduced:
++
++  a) 'include/asm-mips/mach-au1x00/au1xxx_ide.h'
++     containes : struct _auide_hwif
++                 struct drive_list_entry dma_white_list
++                 struct drive_list_entry dma_black_list
++                 timing parameters for PIO mode 0/1/2/3/4
++                 timing parameters for MWDMA 0/1/2
++
++  b) 'drivers/ide/mips/au1xxx-ide.c'
++     contains the functionality of the AU1XXX IDE driver
++
++Four configs variables are introduced:
++
++  CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA    - enable the PIO+DBDMA mode
++  CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA  - enable the MWDMA mode
++  CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA
++                                           controler
++  CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - maximum transfer size
++                                           per descriptor
++
++If MWDMA is enabled and the connected hard disc is not on the white list, the
++kernel switches to a "safe mwdma mode" at boot time. In this mode the IDE
++performance is substantial slower then in full speed mwdma. In this case
++please add your hard disc to the white list (follow instruction from 'ADD NEW
++HARD DISC TO WHITE OR BLACK LIST' section).
++
++
++SUPPORTED IDE MODES
++-------------------
++
++The AU1XXX IDE driver supported all PIO modes - PIO mode 0/1/2/3/4 - and all
++MWDMA modes - MWDMA 0/1/2 -. There is no support for SWDMA and UDMA mode.
++
++To change the PIO mode use the program hdparm with option -p, e.g.
++'hdparm -p0 [device]' for PIO mode 0. To enable the MWDMA mode use the option
++-X, e.g. 'hdparm -X32 [device]' for MWDMA mode 0.
++
++
++PERFORMANCE CONFIGURATIONS
++--------------------------
++
++If the used system doesn't need USB support enable the following kernel configs:
++
++CONFIG_IDE=y
++CONFIG_BLK_DEV_IDE=y
++CONFIG_IDE_GENERIC=y
++CONFIG_BLK_DEV_IDEPCI=y
++CONFIG_BLK_DEV_GENERIC=y
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++CONFIG_IDEDMA_PCI_AUTO=y
++CONFIG_BLK_DEV_IDE_AU1XXX=y
++CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
++CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON=y
++CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
++CONFIG_BLK_DEV_IDEDMA=y
++CONFIG_IDEDMA_AUTO=y
++
++If the used system need the USB support enable the following kernel configs for
++high IDE to USB throughput.
++
++CONFIG_BLK_DEV_IDEDISK=y
++CONFIG_IDE_GENERIC=y
++CONFIG_BLK_DEV_IDEPCI=y
++CONFIG_BLK_DEV_GENERIC=y
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++CONFIG_IDEDMA_PCI_AUTO=y
++CONFIG_BLK_DEV_IDE_AU1XXX=y
++CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
++CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
++CONFIG_BLK_DEV_IDEDMA=y
++CONFIG_IDEDMA_AUTO=y
++
++
++ADD NEW HARD DISC TO WHITE OR BLACK LIST
++----------------------------------------
++
++Step 1 : detect the model name of your hard disc
++
++  a) connect your hard disc to the AU1XXX
++
++  b) boot your kernel and get the hard disc model.
++
++     Example boot log:
++
++     --snipped--
++     Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
++     ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
++     Au1xxx IDE(builtin) configured for MWDMA2
++     Probing IDE interface ide0...
++     hda: Maxtor 6E040L0, ATA DISK drive
++     ide0 at 0xac800000-0xac800007,0xac8001c0 on irq 64
++     hda: max request size: 64KiB
++     hda: 80293248 sectors (41110 MB) w/2048KiB Cache, CHS=65535/16/63, (U)DMA
++     --snipped--
++
++     In this example 'Maxtor 6E040L0'.
++
++Step  2 : edit 'include/asm-mips/mach-au1x00/au1xxx_ide.h'
++
++  Add your hard disc to the dma_white_list or dma_black_list structur.
++
++Step 3 : Recompile the kernel
++
++  Enable MWDMA support in the kernel configuration. Recompile the kernel and
++  reboot.
++
++Step 4 : Tests
++
++  If you have add a hard disc to the white list, please run some stress tests
++  for verification.
++
++
++ACKNOWLEDGMENTS
++---------------
++
++These drivers wouldn't have been done without the base of kernel 2.4.x AU1XXX
++IDE driver from AMD.
++
++Additional input also from:
++Matthias Lenk <matthias.lenk at amd.com>
++
++Happy hacking!
++Enrico Walther <enrico.walther at amd.com>
+diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
+--- a/Documentation/networking/bonding.txt
++++ b/Documentation/networking/bonding.txt
+@@ -777,7 +777,7 @@ doing so is the same as described in the
+ Manually" section, below.
+ 
+ 	NOTE: It has been observed that some Red Hat supplied kernels
+-are apparently unable to rename modules at load time (the "-obonding1"
++are apparently unable to rename modules at load time (the "-o bond1"
+ part).  Attempts to pass that option to modprobe will produce an
+ "Operation not permitted" error.  This has been reported on some
+ Fedora Core kernels, and has been seen on RHEL 4 as well.  On kernels
+@@ -883,7 +883,8 @@ the above does not work, and the second 
+ its options.  In that case, the second options line can be substituted
+ as follows:
+ 
+-install bonding1 /sbin/modprobe bonding -obond1 mode=balance-alb miimon=50
++install bond1 /sbin/modprobe --ignore-install bonding -o bond1 \
++	mode=balance-alb miimon=50
+ 
+ 	This may be repeated any number of times, specifying a new and
+ unique name in place of bond1 for each subsequent instance.
+diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
+--- a/Documentation/networking/ip-sysctl.txt
++++ b/Documentation/networking/ip-sysctl.txt
+@@ -309,7 +309,7 @@ tcp_tso_win_divisor - INTEGER
+        can be consumed by a single TSO frame.
+        The setting of this parameter is a choice between burstiness and
+        building larger TSO frames.
+-       Default: 8
++       Default: 3
+ 
+ tcp_frto - BOOLEAN
+ 	Enables F-RTO, an enhanced recovery algorithm for TCP retransmission
+diff --git a/Documentation/serial/driver b/Documentation/serial/driver
+--- a/Documentation/serial/driver
++++ b/Documentation/serial/driver
+@@ -116,12 +116,15 @@ hardware.
+ 	line becoming inactive or the tty layer indicating we want
+ 	to stop transmission due to an XOFF character.
+ 
++	The driver should stop transmitting characters as soon as
++	possible.
++
+ 	Locking: port->lock taken.
+ 	Interrupts: locally disabled.
+ 	This call must not sleep
+ 
+   start_tx(port)
+-	start transmitting characters.
++	Start transmitting characters.
+ 
+ 	Locking: port->lock taken.
+ 	Interrupts: locally disabled.
+@@ -281,26 +284,31 @@ hardware.
+ Other functions
+ ---------------
+ 
+-uart_update_timeout(port,cflag,quot)
++uart_update_timeout(port,cflag,baud)
+ 	Update the FIFO drain timeout, port->timeout, according to the
+-	number of bits, parity, stop bits and quotient.
++	number of bits, parity, stop bits and baud rate.
+ 
+ 	Locking: caller is expected to take port->lock
+ 	Interrupts: n/a
+ 
+-uart_get_baud_rate(port,termios)
++uart_get_baud_rate(port,termios,old,min,max)
+ 	Return the numeric baud rate for the specified termios, taking
+ 	account of the special 38400 baud "kludge".  The B0 baud rate
+ 	is mapped to 9600 baud.
+ 
++	If the baud rate is not within min..max, then if old is non-NULL,
++	the original baud rate will be tried.  If that exceeds the
++	min..max constraint, 9600 baud will be returned.  termios will
++	be updated to the baud rate in use.
++
++	Note: min..max must always allow 9600 baud to be selected.
++
+ 	Locking: caller dependent.
+ 	Interrupts: n/a
+ 
+-uart_get_divisor(port,termios,oldtermios)
+-	Return the divsor (baud_base / baud) for the selected baud rate
+-	specified by termios.  If the baud rate is out of range, try
+-	the original baud rate specified by oldtermios (if non-NULL).
+-	If that fails, try 9600 baud.
++uart_get_divisor(port,baud)
++	Return the divsor (baud_base / baud) for the specified baud
++	rate, appropriately rounded.
+ 
+ 	If 38400 baud and custom divisor is selected, return the
+ 	custom divisor instead.
+@@ -308,6 +316,46 @@ uart_get_divisor(port,termios,oldtermios
+ 	Locking: caller dependent.
+ 	Interrupts: n/a
+ 
++uart_match_port(port1,port2)
++	This utility function can be used to determine whether two
++	uart_port structures describe the same port.
++
++	Locking: n/a
++	Interrupts: n/a
++
++uart_write_wakeup(port)
++	A driver is expected to call this function when the number of
++	characters in the transmit buffer have dropped below a threshold.
++
++	Locking: port->lock should be held.
++	Interrupts: n/a
++
++uart_register_driver(drv)
++	Register a uart driver with the core driver.  We in turn register
++	with the tty layer, and initialise the core driver per-port state.
++
++	drv->port should be NULL, and the per-port structures should be
++	registered using uart_add_one_port after this call has succeeded.
++
++	Locking: none
++	Interrupts: enabled
++
++uart_unregister_driver()
++	Remove all references to a driver from the core driver.  The low
++	level driver must have removed all its ports via the
++	uart_remove_one_port() if it registered them with uart_add_one_port().
++
++	Locking: none
++	Interrupts: enabled
++
++uart_suspend_port()
++
++uart_resume_port()
++
++uart_add_one_port()
++
++uart_remove_one_port()
++
+ Other notes
+ -----------
+ 
+diff --git a/MAINTAINERS b/MAINTAINERS
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -116,12 +116,6 @@ M:	ajk at iehk.rwth-aachen.de
+ L:	linux-hams at vger.kernel.org
+ S:	Maintained
+ 
+-YEALINK PHONE DRIVER
+-P:	Henk Vergonet
+-M:	Henk.Vergonet at gmail.com
+-L:	usbb2k-api-dev at nongnu.org
+-S:	Maintained
+-
+ 8139CP 10/100 FAST ETHERNET DRIVER
+ P:	Jeff Garzik
+ M:	jgarzik at pobox.com
+@@ -197,6 +191,15 @@ M:	Thorsten Knabe <linux at thorsten-knabe.
+ W:	http://linux.thorsten-knabe.de
+ S:	Maintained
+ 
++AD1889 SOUND DRIVER
++P:	Kyle McMartin
++M:	kyle at parisc-linux.org
++P:	Thibaut Varene
++M:	T-Bone at parisc-linux.org
++W:	http://wiki.parisc-linux.org/AD1889
++L:	parisc-linux at lists.parisc-linux.org
++S:	Maintained
++
+ ADM1025 HARDWARE MONITOR DRIVER
+ P:	Jean Delvare
+ M:	khali at linux-fr.org
+@@ -1640,7 +1643,7 @@ S:	Maintained
+ MIPS
+ P:	Ralf Baechle
+ M:	ralf at linux-mips.org
+-W:	http://oss.sgi.com/mips/mips-howto.html
++W:	http://www.linux-mips.org/
+ L:	linux-mips at linux-mips.org
+ S:	Maintained
+ 
+@@ -1942,6 +1945,14 @@ M:	george at mvista.com
+ L:	netdev at vger.kernel.org
+ S:	Supported
+ 
++POWERPC 4xx EMAC DRIVER
++P:	Eugene Surovegin
++M:	ebs at ebshome.net
++W:	http://kernel.ebshome.net/emac/
++L:	linuxppc-embedded at ozlabs.org
++L:	netdev at vger.kernel.org
++S:	Maintained
++
+ PNP SUPPORT
+ P:	Adam Belay
+ M:	ambx1 at neo.rr.com
+@@ -2275,6 +2286,11 @@ W:	http://tpmdd.sourceforge.net
+ L:	tpmdd-devel at lists.sourceforge.net
+ S:	Maintained
+ 
++Telecom Clock Driver for MCPL0010
++P: Mark Gross
++M: mark.gross at intel.com
++S: Supported
++
+ TENSILICA XTENSA PORT (xtensa):
+ P:	Chris Zankel
+ M:	chris at zankel.net
+@@ -2486,14 +2502,6 @@ L:	linux-kernel at vger.kernel.org
+ L:	linux-usb-devel at lists.sourceforge.net
+ S:	Supported
+ 
+-USB BLUETOOTH TTY CONVERTER DRIVER
+-P:	Greg Kroah-Hartman
+-M:	greg at kroah.com
+-L:	linux-usb-users at lists.sourceforge.net
+-L:	linux-usb-devel at lists.sourceforge.net
+-S:	Maintained
+-W:	http://www.kroah.com/linux-usb/
+-
+ USB CDC ETHERNET DRIVER
+ P:	Greg Kroah-Hartman
+ M:	greg at kroah.com
+@@ -2727,6 +2735,12 @@ P:	Roger Luethi
+ M:	rl at hellgate.ch
+ S:	Maintained
+ 
++VIAPRO SMBUS DRIVER
++P:	Jean Delvare
++M:	khali at linux-fr.org
++L:	lm-sensors at lm-sensors.org
++S:	Maintained
++
+ UCLINUX (AND M68KNOMMU)
+ P:	Greg Ungerer
+ M:	gerg at uclinux.org
+@@ -2848,6 +2862,12 @@ M:	jpr at f6fbb.org
+ L:	linux-hams at vger.kernel.org
+ S:	Maintained
+ 
++YEALINK PHONE DRIVER
++P:	Henk Vergonet
++M:	Henk.Vergonet at gmail.com
++L:	usbb2k-api-dev at nongnu.org
++S:	Maintained
++
+ YMFPCI YAMAHA PCI SOUND (Use ALSA instead)
+ P:	Pete Zaitcev
+ M:	zaitcev at yahoo.com
+diff --git a/Makefile b/Makefile
+--- a/Makefile
++++ b/Makefile
+@@ -334,7 +334,7 @@ KALLSYMS	= scripts/kallsyms
+ PERL		= perl
+ CHECK		= sparse
+ 
+-CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ $(CF)
++CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF)
+ MODFLAGS	= -DMODULE
+ CFLAGS_MODULE   = $(MODFLAGS)
+ AFLAGS_MODULE   = $(MODFLAGS)
+@@ -371,8 +371,8 @@ export MODVERDIR := $(if $(KBUILD_EXTMOD
+ 
+ # Files to ignore in find ... statements
+ 
+-RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg \) -prune -o
+-export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg
++RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o
++export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git
+ 
+ # ===========================================================================
+ # Rules shared between *config targets and build targets
+diff --git a/README b/README
+--- a/README
++++ b/README
+@@ -54,6 +54,10 @@ INSTALLING the kernel:
+ 
+ 		gzip -cd linux-2.6.XX.tar.gz | tar xvf -
+ 
++   or
++		bzip2 -dc linux-2.6.XX.tar.bz2 | tar xvf -
++
++
+    Replace "XX" with the version number of the latest kernel.
+ 
+    Do NOT use the /usr/src/linux area! This area has a (usually
+diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
+--- a/arch/alpha/kernel/pci-noop.c
++++ b/arch/alpha/kernel/pci-noop.c
+@@ -154,7 +154,7 @@ pci_dma_supported(struct pci_dev *hwdev,
+ 
+ void *
+ dma_alloc_coherent(struct device *dev, size_t size,
+-		   dma_addr_t *dma_handle, int gfp)
++		   dma_addr_t *dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 
+diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
+--- a/arch/alpha/kernel/pci_iommu.c
++++ b/arch/alpha/kernel/pci_iommu.c
+@@ -397,7 +397,7 @@ pci_alloc_consistent(struct pci_dev *pde
+ {
+ 	void *cpu_addr;
+ 	long order = get_order(size);
+-	int gfp = GFP_ATOMIC;
++	gfp_t gfp = GFP_ATOMIC;
+ 
+ try_again:
+ 	cpu_addr = (void *)__get_free_pages(gfp, order);
+diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
+--- a/arch/alpha/kernel/time.c
++++ b/arch/alpha/kernel/time.c
+@@ -55,10 +55,6 @@
+ #include "proto.h"
+ #include "irq_impl.h"
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ extern unsigned long wall_jiffies;	/* kernel/timer.c */
+ 
+ static int set_rtc_mmss(unsigned long);
+diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
+--- a/arch/alpha/mm/numa.c
++++ b/arch/alpha/mm/numa.c
+@@ -371,6 +371,8 @@ show_mem(void)
+ 	show_free_areas();
+ 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+ 	for_each_online_node(nid) {
++		unsigned long flags;
++		pgdat_resize_lock(NODE_DATA(nid), &flags);
+ 		i = node_spanned_pages(nid);
+ 		while (i-- > 0) {
+ 			struct page *page = nid_page_nr(nid, i);
+@@ -384,6 +386,7 @@ show_mem(void)
+ 			else
+ 				shared += page_count(page) - 1;
+ 		}
++		pgdat_resize_unlock(NODE_DATA(nid), &flags);
+ 	}
+ 	printk("%ld pages of RAM\n",total);
+ 	printk("%ld free pages\n",free);
+diff --git a/arch/alpha/mm/remap.c b/arch/alpha/mm/remap.c
+--- a/arch/alpha/mm/remap.c
++++ b/arch/alpha/mm/remap.c
+@@ -2,7 +2,6 @@
+ #include <asm/pgalloc.h>
+ #include <asm/cacheflush.h>
+ 
+-/* called with the page_table_lock held */
+ static inline void 
+ remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, 
+ 	       unsigned long phys_addr, unsigned long flags)
+@@ -31,7 +30,6 @@ remap_area_pte(pte_t * pte, unsigned lon
+ 	} while (address && (address < end));
+ }
+ 
+-/* called with the page_table_lock held */
+ static inline int 
+ remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, 
+ 	       unsigned long phys_addr, unsigned long flags)
+@@ -46,7 +44,7 @@ remap_area_pmd(pmd_t * pmd, unsigned lon
+ 	if (address >= end)
+ 		BUG();
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, 
+@@ -70,7 +68,6 @@ __alpha_remap_area_pages(unsigned long a
+ 	flush_cache_all();
+ 	if (address >= end)
+ 		BUG();
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		pmd_t *pmd;
+ 		pmd = pmd_alloc(&init_mm, dir, address);
+@@ -84,7 +81,6 @@ __alpha_remap_area_pages(unsigned long a
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
+-	spin_unlock(&init_mm.page_table_lock);
+ 	return error;
+ }
+ 
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -194,6 +194,13 @@ config ARCH_VERSATILE
+ 	help
+ 	  This enables support for ARM Ltd Versatile board.
+ 
++config ARCH_REALVIEW
++	bool "RealView"
++	select ARM_AMBA
++	select ICST307
++	help
++	  This enables support for ARM Ltd RealView boards.
++
+ config ARCH_IMX
+ 	bool "IMX"
+ 
+@@ -204,6 +211,7 @@ config ARCH_H720X
+ 
+ config ARCH_AAEC2000
+ 	bool "Agilent AAEC-2000 based"
++	select ARM_AMBA
+ 	help
+ 	  This enables support for systems based on the Agilent AAEC-2000
+ 
+@@ -243,6 +251,8 @@ source "arch/arm/mach-versatile/Kconfig"
+ 
+ source "arch/arm/mach-aaec2000/Kconfig"
+ 
++source "arch/arm/mach-realview/Kconfig"
++
+ # Definitions to make life easier
+ config ARCH_ACORN
+ 	bool
+@@ -687,7 +697,8 @@ source "drivers/acorn/block/Kconfig"
+ 
+ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
+ 	|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
+-	|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
++	|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
++	|| MACH_MP1000
+ source "drivers/ide/Kconfig"
+ endif
+ 
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -8,7 +8,7 @@
+ # Copyright (C) 1995-2001 by Russell King
+ 
+ LDFLAGS_vmlinux	:=-p --no-undefined -X
+-CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
++CPPFLAGS_vmlinux.lds = -DKERNEL_RAM_ADDR=$(TEXTADDR)
+ OBJCOPYFLAGS	:=-O binary -R .note -R .comment -S
+ GZFLAGS		:=-9
+ #CFLAGS		+=-pipe
+@@ -99,6 +99,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET)   := 0x
+  machine-$(CONFIG_ARCH_IMX)	   := imx
+  machine-$(CONFIG_ARCH_H720X)	   := h720x
+  machine-$(CONFIG_ARCH_AAEC2000)   := aaec2000
++ machine-$(CONFIG_ARCH_REALVIEW)   := realview
+ 
+ ifeq ($(CONFIG_ARCH_EBSA110),y)
+ # This is what happens if you forget the IOCS16 line.
+@@ -108,27 +109,19 @@ export CFLAGS_3c589_cs.o
+ endif
+ 
+ TEXTADDR := $(textaddr-y)
+-ifeq ($(CONFIG_XIP_KERNEL),y)
+-  DATAADDR := $(TEXTADDR)
+-  xipaddr-$(CONFIG_ARCH_CO285) := 0x5f000000
+-  xipaddr-y ?= 0xbf000000
+-  # Replace phys addr with virt addr while keeping offset from base.
+-  TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \
+-                      awk --non-decimal-data '/[:xdigit:]/ \
+-                          { printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' )
+-endif
+ 
+ ifeq ($(incdir-y),)
+ incdir-y := $(machine-y)
+ endif
+ INCDIR   := arch-$(incdir-y)
++
+ ifneq ($(machine-y),)
+ MACHINE  := arch/arm/mach-$(machine-y)/
+ else
+ MACHINE  :=
+ endif
+   
+-export	TEXTADDR DATAADDR GZFLAGS
++export	TEXTADDR GZFLAGS
+ 
+ # Do we have FASTFPE?
+ FASTFPE		:=arch/arm/fastfpe
+diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
+--- a/arch/arm/boot/compressed/head.S
++++ b/arch/arm/boot/compressed/head.S
+@@ -39,7 +39,8 @@
+     defined(CONFIG_ARCH_IXP4XX) || \
+     defined(CONFIG_ARCH_IXP2000) || \
+     defined(CONFIG_ARCH_LH7A40X) || \
+-    defined(CONFIG_ARCH_OMAP)
++    defined(CONFIG_ARCH_OMAP) || \
++    defined(CONFIG_MACH_MP1000)
+ 		.macro	loadsp,	rb
+ 		addruart \rb
+ 		.endm
+diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
+--- a/arch/arm/boot/compressed/misc.c
++++ b/arch/arm/boot/compressed/misc.c
+@@ -30,7 +30,7 @@ unsigned int __machine_arch_type;
+ #define putstr icedcc_putstr
+ #define putc icedcc_putc
+ 
+-extern void idedcc_putc(int ch);
++extern void icedcc_putc(int ch);
+ 
+ static void
+ icedcc_putstr(const char *ptr)
+diff --git a/arch/arm/common/amba.c b/arch/arm/common/amba.c
+--- a/arch/arm/common/amba.c
++++ b/arch/arm/common/amba.c
+@@ -10,6 +10,8 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
+diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
+--- a/arch/arm/common/dmabounce.c
++++ b/arch/arm/common/dmabounce.c
+@@ -33,8 +33,8 @@
+ #include <asm/cacheflush.h>
+ 
+ #undef DEBUG
+-
+ #undef STATS
++
+ #ifdef STATS
+ #define DO_STATS(X) do { X ; } while (0)
+ #else
+@@ -52,26 +52,31 @@ struct safe_buffer {
+ 	int		direction;
+ 
+ 	/* safe buffer info */
+-	struct dma_pool *pool;
++	struct dmabounce_pool *pool;
+ 	void		*safe;
+ 	dma_addr_t	safe_dma_addr;
+ };
+ 
++struct dmabounce_pool {
++	unsigned long	size;
++	struct dma_pool	*pool;
++#ifdef STATS
++	unsigned long	allocs;
++#endif
++};
++
+ struct dmabounce_device_info {
+ 	struct list_head node;
+ 
+ 	struct device *dev;
+-	struct dma_pool *small_buffer_pool;
+-	struct dma_pool *large_buffer_pool;
+ 	struct list_head safe_buffers;
+-	unsigned long small_buffer_size, large_buffer_size;
+ #ifdef STATS
+-	unsigned long sbp_allocs;
+-	unsigned long lbp_allocs;
+ 	unsigned long total_allocs;
+ 	unsigned long map_op_count;
+ 	unsigned long bounce_count;
+ #endif
++	struct dmabounce_pool	small;
++	struct dmabounce_pool	large;
+ };
+ 
+ static LIST_HEAD(dmabounce_devs);
+@@ -82,9 +87,9 @@ static void print_alloc_stats(struct dma
+ 	printk(KERN_INFO
+ 		"%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
+ 		device_info->dev->bus_id,
+-		device_info->sbp_allocs, device_info->lbp_allocs,
+-		device_info->total_allocs - device_info->sbp_allocs -
+-			device_info->lbp_allocs,
++		device_info->small.allocs, device_info->large.allocs,
++		device_info->total_allocs - device_info->small.allocs -
++			device_info->large.allocs,
+ 		device_info->total_allocs);
+ }
+ #endif
+@@ -106,18 +111,22 @@ find_dmabounce_dev(struct device *dev)
+ /* allocate a 'safe' buffer and keep track of it */
+ static inline struct safe_buffer *
+ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
+-			size_t size, enum dma_data_direction dir)
++		  size_t size, enum dma_data_direction dir)
+ {
+ 	struct safe_buffer *buf;
+-	struct dma_pool *pool;
++	struct dmabounce_pool *pool;
+ 	struct device *dev = device_info->dev;
+-	void *safe;
+-	dma_addr_t safe_dma_addr;
+ 
+ 	dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n",
+ 		__func__, ptr, size, dir);
+ 
+-	DO_STATS ( device_info->total_allocs++ );
++	if (size <= device_info->small.size) {
++		pool = &device_info->small;
++	} else if (size <= device_info->large.size) {
++		pool = &device_info->large;
++	} else {
++		pool = NULL;
++	}
+ 
+ 	buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
+ 	if (buf == NULL) {
+@@ -125,41 +134,35 @@ alloc_safe_buffer(struct dmabounce_devic
+ 		return NULL;
+ 	}
+ 
+-	if (size <= device_info->small_buffer_size) {
+-		pool = device_info->small_buffer_pool;
+-		safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
+-
+-		DO_STATS ( device_info->sbp_allocs++ );
+-	} else if (size <= device_info->large_buffer_size) {
+-		pool = device_info->large_buffer_pool;
+-		safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
++	buf->ptr = ptr;
++	buf->size = size;
++	buf->direction = dir;
++	buf->pool = pool;
+ 
+-		DO_STATS ( device_info->lbp_allocs++ );
++	if (pool) {
++		buf->safe = dma_pool_alloc(pool->pool, GFP_ATOMIC,
++					   &buf->safe_dma_addr);
+ 	} else {
+-		pool = NULL;
+-		safe = dma_alloc_coherent(dev, size, &safe_dma_addr, GFP_ATOMIC);
++		buf->safe = dma_alloc_coherent(dev, size, &buf->safe_dma_addr,
++					       GFP_ATOMIC);
+ 	}
+ 
+-	if (safe == NULL) {
+-		dev_warn(device_info->dev,
+-			"%s: could not alloc dma memory (size=%d)\n",
+-		       __func__, size);
++	if (buf->safe == NULL) {
++		dev_warn(dev,
++			 "%s: could not alloc dma memory (size=%d)\n",
++			 __func__, size);
+ 		kfree(buf);
+ 		return NULL;
+ 	}
+ 
+ #ifdef STATS
++	if (pool)
++		pool->allocs++;
++	device_info->total_allocs++;
+ 	if (device_info->total_allocs % 1000 == 0)
+ 		print_alloc_stats(device_info);
+ #endif
+ 
+-	buf->ptr = ptr;
+-	buf->size = size;
+-	buf->direction = dir;
+-	buf->pool = pool;
+-	buf->safe = safe;
+-	buf->safe_dma_addr = safe_dma_addr;
+-
+ 	list_add(&buf->node, &device_info->safe_buffers);
+ 
+ 	return buf;
+@@ -186,7 +189,7 @@ free_safe_buffer(struct dmabounce_device
+ 	list_del(&buf->node);
+ 
+ 	if (buf->pool)
+-		dma_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
++		dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr);
+ 	else
+ 		dma_free_coherent(device_info->dev, buf->size, buf->safe,
+ 				    buf->safe_dma_addr);
+@@ -197,12 +200,10 @@ free_safe_buffer(struct dmabounce_device
+ /* ************************************************** */
+ 
+ #ifdef STATS
+-
+ static void print_map_stats(struct dmabounce_device_info *device_info)
+ {
+-	printk(KERN_INFO
+-		"%s: dmabounce: map_op_count=%lu, bounce_count=%lu\n",
+-		device_info->dev->bus_id,
++	dev_info(device_info->dev,
++		"dmabounce: map_op_count=%lu, bounce_count=%lu\n",
+ 		device_info->map_op_count, device_info->bounce_count);
+ }
+ #endif
+@@ -258,13 +259,13 @@ map_single(struct device *dev, void *ptr
+ 				__func__, ptr, buf->safe, size);
+ 			memcpy(buf->safe, ptr, size);
+ 		}
+-		consistent_sync(buf->safe, size, dir);
++		ptr = buf->safe;
+ 
+ 		dma_addr = buf->safe_dma_addr;
+-	} else {
+-		consistent_sync(ptr, size, dir);
+ 	}
+ 
++	consistent_sync(ptr, size, dir);
++
+ 	return dma_addr;
+ }
+ 
+@@ -278,7 +279,7 @@ unmap_single(struct device *dev, dma_add
+ 	/*
+ 	 * Trying to unmap an invalid mapping
+ 	 */
+-	if (dma_addr == ~0) {
++	if (dma_mapping_error(dma_addr)) {
+ 		dev_err(dev, "Trying to unmap invalid mapping\n");
+ 		return;
+ 	}
+@@ -570,11 +571,25 @@ dma_sync_sg_for_device(struct device *de
+ 	local_irq_restore(flags);
+ }
+ 
++static int
++dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char *name,
++		    unsigned long size)
++{
++	pool->size = size;
++	DO_STATS(pool->allocs = 0);
++	pool->pool = dma_pool_create(name, dev, size,
++				     0 /* byte alignment */,
++				     0 /* no page-crossing issues */);
++
++	return pool->pool ? 0 : -ENOMEM;
++}
++
+ int
+ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
+ 			unsigned long large_buffer_size)
+ {
+ 	struct dmabounce_device_info *device_info;
++	int ret;
+ 
+ 	device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
+ 	if (!device_info) {
+@@ -584,45 +599,31 @@ dmabounce_register_dev(struct device *de
+ 		return -ENOMEM;
+ 	}
+ 
+-	device_info->small_buffer_pool =
+-		dma_pool_create("small_dmabounce_pool",
+-				dev,
+-				small_buffer_size,
+-				0 /* byte alignment */,
+-				0 /* no page-crossing issues */);
+-	if (!device_info->small_buffer_pool) {
+-		printk(KERN_ERR
+-			"dmabounce: could not allocate small DMA pool for %s\n",
+-			dev->bus_id);
+-		kfree(device_info);
+-		return -ENOMEM;
++	ret = dmabounce_init_pool(&device_info->small, dev,
++				  "small_dmabounce_pool", small_buffer_size);
++	if (ret) {
++		dev_err(dev,
++			"dmabounce: could not allocate DMA pool for %ld byte objects\n",
++			small_buffer_size);
++		goto err_free;
+ 	}
+ 
+ 	if (large_buffer_size) {
+-		device_info->large_buffer_pool =
+-			dma_pool_create("large_dmabounce_pool",
+-					dev,
+-					large_buffer_size,
+-					0 /* byte alignment */,
+-					0 /* no page-crossing issues */);
+-		if (!device_info->large_buffer_pool) {
+-		printk(KERN_ERR
+-			"dmabounce: could not allocate large DMA pool for %s\n",
+-			dev->bus_id);
+-			dma_pool_destroy(device_info->small_buffer_pool);
+-
+-			return -ENOMEM;
++		ret = dmabounce_init_pool(&device_info->large, dev,
++					  "large_dmabounce_pool",
++					  large_buffer_size);
++		if (ret) {
++			dev_err(dev,
++				"dmabounce: could not allocate DMA pool for %ld byte objects\n",
++				large_buffer_size);
++			goto err_destroy;
+ 		}
+ 	}
+ 
+ 	device_info->dev = dev;
+-	device_info->small_buffer_size = small_buffer_size;
+-	device_info->large_buffer_size = large_buffer_size;
+ 	INIT_LIST_HEAD(&device_info->safe_buffers);
+ 
+ #ifdef STATS
+-	device_info->sbp_allocs = 0;
+-	device_info->lbp_allocs = 0;
+ 	device_info->total_allocs = 0;
+ 	device_info->map_op_count = 0;
+ 	device_info->bounce_count = 0;
+@@ -634,6 +635,12 @@ dmabounce_register_dev(struct device *de
+ 		dev->bus_id, dev->bus->name);
+ 
+ 	return 0;
++
++ err_destroy:
++	dma_pool_destroy(device_info->small.pool);
++ err_free:
++	kfree(device_info);
++	return ret;
+ }
+ 
+ void
+@@ -655,10 +662,10 @@ dmabounce_unregister_dev(struct device *
+ 		BUG();
+ 	}
+ 
+-	if (device_info->small_buffer_pool)
+-		dma_pool_destroy(device_info->small_buffer_pool);
+-	if (device_info->large_buffer_pool)
+-		dma_pool_destroy(device_info->large_buffer_pool);
++	if (device_info->small.pool)
++		dma_pool_destroy(device_info->small.pool);
++	if (device_info->large.pool)
++		dma_pool_destroy(device_info->large.pool);
+ 
+ #ifdef STATS
+ 	print_alloc_stats(device_info);
+diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
+--- a/arch/arm/common/locomo.c
++++ b/arch/arm/common/locomo.c
+@@ -22,7 +22,7 @@
+ #include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
+ 
+@@ -550,15 +550,12 @@ struct locomo_save_data {
+ 	u16	LCM_SPIMD;
+ };
+ 
+-static int locomo_suspend(struct device *dev, pm_message_t state, u32 level)
++static int locomo_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct locomo *lchip = dev_get_drvdata(dev);
+ 	struct locomo_save_data *save;
+ 	unsigned long flags;
+ 
+-	if (level != SUSPEND_DISABLE)
+-		return 0;
+-
+ 	save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
+ 	if (!save)
+ 		return -ENOMEM;
+@@ -597,16 +594,13 @@ static int locomo_suspend(struct device 
+ 	return 0;
+ }
+ 
+-static int locomo_resume(struct device *dev, u32 level)
++static int locomo_resume(struct device *dev)
+ {
+ 	struct locomo *lchip = dev_get_drvdata(dev);
+ 	struct locomo_save_data *save;
+ 	unsigned long r;
+ 	unsigned long flags;
+ 	
+-	if (level != RESUME_ENABLE)
+-		return 0;
+-
+ 	save = (struct locomo_save_data *) dev->power.saved_state;
+ 	if (!save)
+ 		return 0;
+diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
+--- a/arch/arm/common/sa1111.c
++++ b/arch/arm/common/sa1111.c
+@@ -22,7 +22,7 @@
+ #include <linux/ptrace.h>
+ #include <linux/errno.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
+ #include <linux/dma-mapping.h>
+@@ -801,7 +801,7 @@ struct sa1111_save_data {
+ 
+ #ifdef CONFIG_PM
+ 
+-static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
++static int sa1111_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct sa1111 *sachip = dev_get_drvdata(dev);
+ 	struct sa1111_save_data *save;
+@@ -809,9 +809,6 @@ static int sa1111_suspend(struct device 
+ 	unsigned int val;
+ 	void __iomem *base;
+ 
+-	if (level != SUSPEND_DISABLE)
+-		return 0;
+-
+ 	save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
+ 	if (!save)
+ 		return -ENOMEM;
+@@ -856,23 +853,19 @@ static int sa1111_suspend(struct device 
+ /*
+  *	sa1111_resume - Restore the SA1111 device state.
+  *	@dev: device to restore
+- *	@level: resume level
+  *
+  *	Restore the general state of the SA1111; clock control and
+  *	interrupt controller.  Other parts of the SA1111 must be
+  *	restored by their respective drivers, and must be called
+  *	via LDM after this function.
+  */
+-static int sa1111_resume(struct device *dev, u32 level)
++static int sa1111_resume(struct device *dev)
+ {
+ 	struct sa1111 *sachip = dev_get_drvdata(dev);
+ 	struct sa1111_save_data *save;
+ 	unsigned long flags, id;
+ 	void __iomem *base;
+ 
+-	if (level != RESUME_ENABLE)
+-		return 0;
+-
+ 	save = (struct sa1111_save_data *)dev->power.saved_state;
+ 	if (!save)
+ 		return 0;
+diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
+--- a/arch/arm/common/scoop.c
++++ b/arch/arm/common/scoop.c
+@@ -12,6 +12,8 @@
+  */
+ 
+ #include <linux/device.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
+ #include <asm/io.h>
+ #include <asm/hardware/scoop.h>
+ 
+@@ -102,26 +104,24 @@ static void check_scoop_reg(struct scoop
+ }
+ 
+ #ifdef CONFIG_PM
+-static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level)
++static int scoop_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_POWER_DOWN) {
+-		struct scoop_dev *sdev = dev_get_drvdata(dev);
++	struct scoop_dev *sdev = dev_get_drvdata(dev);
++
++	check_scoop_reg(sdev);
++	sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
++	SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
+ 
+-		check_scoop_reg(sdev);
+-  		sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
+-		SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
+-	}
+ 	return 0;
+ }
+ 
+-static int scoop_resume(struct device *dev, uint32_t level)
++static int scoop_resume(struct device *dev)
+ {
+-	if (level == RESUME_POWER_ON) {
+-		struct scoop_dev *sdev = dev_get_drvdata(dev);
++	struct scoop_dev *sdev = dev_get_drvdata(dev);
++
++	check_scoop_reg(sdev);
++	SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
+ 
+-		check_scoop_reg(sdev);
+-		SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
+-	}
+ 	return 0;
+ }
+ #else
+diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig
+--- a/arch/arm/configs/ixdp2400_defconfig
++++ b/arch/arm/configs/ixdp2400_defconfig
+@@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ #
+ CONFIG_SERIAL_8250=y
+ CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=2
++CONFIG_SERIAL_8250_NR_UARTS=1
+ # CONFIG_SERIAL_8250_EXTENDED is not set
+ 
+ #
+diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
+--- a/arch/arm/configs/ixdp2800_defconfig
++++ b/arch/arm/configs/ixdp2800_defconfig
+@@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ #
+ CONFIG_SERIAL_8250=y
+ CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=2
++CONFIG_SERIAL_8250_NR_UARTS=1
+ # CONFIG_SERIAL_8250_EXTENDED is not set
+ 
+ #
+diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
+--- a/arch/arm/configs/ixp4xx_defconfig
++++ b/arch/arm/configs/ixp4xx_defconfig
+@@ -104,7 +104,7 @@ CONFIG_ARCH_IXCDP1100=y
+ CONFIG_ARCH_PRPMC1100=y
+ CONFIG_ARCH_IXDP4XX=y
+ CONFIG_CPU_IXP46X=y
+-CONFIG_MACH_GTWX5715=y
++# CONFIG_MACH_GTWX5715 is not set
+ 
+ #
+ # IXP4xx Options
+diff --git a/arch/arm/configs/mp1000_defconfig b/arch/arm/configs/mp1000_defconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/configs/mp1000_defconfig
+@@ -0,0 +1,897 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14-rc1
++# Fri Sep 16 15:48:13 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=y
++# CONFIG_CLEAN_COMPILE is not set
++CONFIG_BROKEN=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_HOTPLUG is not set
++CONFIG_KOBJECT_UEVENT=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_EMBEDDED=y
++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_MODULE_FORCE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_CLPS7500 is not set
++CONFIG_ARCH_CLPS711X=y
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT 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
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CEIVA is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++CONFIG_MACH_MP1000=y
++CONFIG_MP1000_90MHZ=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM720T=y
++CONFIG_CPU_32v4=y
++CONFIG_CPU_ABRT_LV4T=y
++CONFIG_CPU_CACHE_V4=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WT=y
++CONFIG_CPU_TLB_V4WT=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++
++#
++# 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=y
++# CONFIG_NO_IDLE_HZ 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_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyCL,38400 root=/dev/discs/disc0/part1 ip=any cs89x0_media=rj45"
++# 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
++
++#
++# Networking
++#
++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 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_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=y
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_IPV6_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
++# 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_NETFILTER_NETLINK 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
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=3
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=m
++CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2
++CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
++# CONFIG_MTD_REDBOOT_PARTS_READONLY 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=m
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=m
++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 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
++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=m
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=m
++# 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=m
++CONFIG_MTD_PHYSMAP_START=0x0000000
++CONFIG_MTD_PHYSMAP_LEN=0x4000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++CONFIG_MTD_EDB7312=m
++# 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_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
++
++#
++# NAND Flash Device Drivers
++#
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++CONFIG_MTD_NAND_MP1000=y
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM 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 is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=2
++CONFIG_BLK_DEV_RAM_SIZE=16384
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++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 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=y
++CONFIG_BLK_DEV_IDE_MP1000=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 is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++CONFIG_MD=y
++# CONFIG_BLK_DEV_MD is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_CRYPT is not set
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++
++#
++# Fusion MPT device support
++#
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# 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 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++CONFIG_CS89x0=y
++
++#
++# 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 is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++CONFIG_INPUT_EVBUG=y
++
++#
++# 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_LIBPS2 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=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=2
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_CLPS711X=y
++CONFIG_SERIAL_CLPS711X_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=y
++CONFIG_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_RAW_DRIVER is not set
++
++#
++# TPM devices
++#
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Hardware Monitoring support
++#
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++
++#
++# 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 is not set
++# CONFIG_USB is not set
++
++#
++# 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=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_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_QUOTA=y
++# CONFIG_QFMT_V1 is not set
++# CONFIG_QFMT_V2 is not set
++CONFIG_QUOTACTL=y
++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_HUGETLBFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_RELAYFS_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=m
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# 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_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=y
++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=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 is not set
++CONFIG_MSDOS_PARTITION=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 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
++
++#
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_MAGIC_SYSRQ is not set
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_DEBUG_PREEMPT=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_FS is not set
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_WAITQ=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++# CONFIG_DEBUG_CLPS711X_UART2 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=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
+--- a/arch/arm/kernel/Makefile
++++ b/arch/arm/kernel/Makefile
+@@ -2,7 +2,7 @@
+ # Makefile for the linux kernel.
+ #
+ 
+-AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
++AFLAGS_head.o := -DKERNEL_RAM_ADDR=$(TEXTADDR)
+ 
+ # Object file lists.
+ 
+diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c
+--- a/arch/arm/kernel/arthur.c
++++ b/arch/arm/kernel/arthur.c
+@@ -18,6 +18,7 @@
+ #include <linux/stddef.h>
+ #include <linux/signal.h>
+ #include <linux/init.h>
++#include <linux/sched.h>
+ 
+ #include <asm/ptrace.h>
+ 
+diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
+--- a/arch/arm/kernel/asm-offsets.c
++++ b/arch/arm/kernel/asm-offsets.c
+@@ -94,7 +94,6 @@ int main(void)
+   DEFINE(VM_EXEC,	       	VM_EXEC);
+   BLANK();
+   DEFINE(PAGE_SZ,	       	PAGE_SIZE);
+-  DEFINE(VIRT_OFFSET,		PAGE_OFFSET);
+   BLANK();
+   DEFINE(SYS_ERROR0,		0x9f0000);
+   BLANK();
+diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
+--- a/arch/arm/kernel/entry-armv.S
++++ b/arch/arm/kernel/entry-armv.S
+@@ -15,6 +15,7 @@
+  */
+ #include <linux/config.h>
+ 
++#include <asm/memory.h>
+ #include <asm/glue.h>
+ #include <asm/vfpmacros.h>
+ #include <asm/hardware.h>		/* should be moved into entry-macro.S */
+@@ -310,7 +311,7 @@ __pabt_svc:
+ 
+ #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+ 	@ make sure our user space atomic helper is aborted
+-	cmp	r2, #VIRT_OFFSET
++	cmp	r2, #TASK_SIZE
+ 	bichs	r3, r3, #PSR_Z_BIT
+ #endif
+ 
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -21,6 +21,7 @@
+ #include <asm/procinfo.h>
+ #include <asm/ptrace.h>
+ #include <asm/asm-offsets.h>
++#include <asm/memory.h>
+ #include <asm/thread_info.h>
+ #include <asm/system.h>
+ 
+@@ -33,52 +34,28 @@
+ #define MACHINFO_PGOFFIO	12
+ #define MACHINFO_NAME		16
+ 
+-#ifndef CONFIG_XIP_KERNEL
+ /*
+- * We place the page tables 16K below TEXTADDR.  Therefore, we must make sure
+- * that TEXTADDR is correctly set.  Currently, we expect the least significant
+- * 16 bits to be 0x8000, but we could probably relax this restriction to
+- * TEXTADDR >= PAGE_OFFSET + 0x4000
+- *
+- * Note that swapper_pg_dir is the virtual address of the page tables, and
+- * pgtbl gives us a position-independent reference to these tables.  We can
+- * do this because stext == TEXTADDR
++ * swapper_pg_dir is the virtual address of the initial page table.
++ * We place the page tables 16K below KERNEL_RAM_ADDR.  Therefore, we must
++ * make sure that KERNEL_RAM_ADDR is correctly set.  Currently, we expect
++ * the least significant 16 bits to be 0x8000, but we could probably
++ * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000.
+  */
+-#if (TEXTADDR & 0xffff) != 0x8000
+-#error TEXTADDR must start at 0xXXXX8000
++#if (KERNEL_RAM_ADDR & 0xffff) != 0x8000
++#error KERNEL_RAM_ADDR must start at 0xXXXX8000
+ #endif
+ 
+ 	.globl	swapper_pg_dir
+-	.equ	swapper_pg_dir, TEXTADDR - 0x4000
++	.equ	swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000
+ 
+-	.macro	pgtbl, rd, phys
+-	adr	\rd, stext
+-	sub	\rd, \rd, #0x4000
++	.macro	pgtbl, rd
++	ldr	\rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000))
+ 	.endm
+-#else
+-/*
+- * XIP Kernel:
+- *
+- * We place the page tables 16K below DATAADDR.  Therefore, we must make sure
+- * that DATAADDR is correctly set.  Currently, we expect the least significant
+- * 16 bits to be 0x8000, but we could probably relax this restriction to
+- * DATAADDR >= PAGE_OFFSET + 0x4000
+- *
+- * Note that pgtbl is meant to return the physical address of swapper_pg_dir.
+- * We can't make it relative to the kernel position in this case since
+- * the kernel can physically be anywhere.
+- */
+-#if (DATAADDR & 0xffff) != 0x8000
+-#error DATAADDR must start at 0xXXXX8000
+-#endif
+ 
+-	.globl	swapper_pg_dir
+-	.equ	swapper_pg_dir, DATAADDR - 0x4000
+-
+-	.macro	pgtbl, rd, phys
+-	ldr	\rd, =((DATAADDR - 0x4000) - VIRT_OFFSET)
+-	add	\rd, \rd, \phys
+-	.endm
++#ifdef CONFIG_XIP_KERNEL
++#define TEXTADDR  XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
++#else
++#define TEXTADDR  KERNEL_RAM_ADDR
+ #endif
+ 
+ /*
+@@ -279,7 +256,7 @@ __turn_mmu_on:
+ 	.type	__create_page_tables, %function
+ __create_page_tables:
+ 	ldr	r5, [r8, #MACHINFO_PHYSRAM]	@ physram
+-	pgtbl	r4, r5				@ page table address
++	pgtbl	r4				@ page table address
+ 
+ 	/*
+ 	 * Clear the 16K level 1 swapper page table
+@@ -324,7 +301,7 @@ __create_page_tables:
+ 	/*
+ 	 * Then map first 1MB of ram in case it contains our boot params.
+ 	 */
+-	add	r0, r4, #VIRT_OFFSET >> 18
++	add	r0, r4, #PAGE_OFFSET >> 18
+ 	orr	r6, r5, r7
+ 	str	r6, [r0]
+ 
+diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
+--- a/arch/arm/kernel/module.c
++++ b/arch/arm/kernel/module.c
+@@ -11,6 +11,7 @@
+  */
+ #include <linux/config.h>
+ #include <linux/module.h>
++#include <linux/moduleloader.h>
+ #include <linux/kernel.h>
+ #include <linux/elf.h>
+ #include <linux/vmalloc.h>
+diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
+--- a/arch/arm/kernel/ptrace.c
++++ b/arch/arm/kernel/ptrace.c
+@@ -782,7 +782,7 @@ static int do_ptrace(int request, struct
+ 	return ret;
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	int ret;
+diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
+--- a/arch/arm/kernel/signal.c
++++ b/arch/arm/kernel/signal.c
+@@ -139,93 +139,33 @@ struct iwmmxt_sigframe {
+ 	unsigned long	storage[0x98/4];
+ };
+ 
+-static int page_present(struct mm_struct *mm, void __user *uptr, int wr)
+-{
+-	unsigned long addr = (unsigned long)uptr;
+-	pgd_t *pgd = pgd_offset(mm, addr);
+-	if (pgd_present(*pgd)) {
+-		pmd_t *pmd = pmd_offset(pgd, addr);
+-		if (pmd_present(*pmd)) {
+-			pte_t *pte = pte_offset_map(pmd, addr);
+-			return (pte_present(*pte) && (!wr || pte_write(*pte)));
+-		}
+-	}
+-	return 0;
+-}
+-
+-static int copy_locked(void __user *uptr, void *kptr, size_t size, int write,
+-		       void (*copyfn)(void *, void __user *))
+-{
+-	unsigned char v, __user *userptr = uptr;
+-	int err = 0;
+-
+-	do {
+-		struct mm_struct *mm;
+-
+-		if (write) {
+-			__put_user_error(0, userptr, err);
+-			__put_user_error(0, userptr + size - 1, err);
+-		} else {
+-			__get_user_error(v, userptr, err);
+-			__get_user_error(v, userptr + size - 1, err);
+-		}
+-
+-		if (err)
+-			break;
+-
+-		mm = current->mm;
+-		spin_lock(&mm->page_table_lock);
+-		if (page_present(mm, userptr, write) &&
+-		    page_present(mm, userptr + size - 1, write)) {
+-		    	copyfn(kptr, uptr);
+-		} else
+-			err = 1;
+-		spin_unlock(&mm->page_table_lock);
+-	} while (err);
+-
+-	return err;
+-}
+-
+ static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
+ {
+-	int err = 0;
++	char kbuf[sizeof(*frame) + 8];
++	struct iwmmxt_sigframe *kframe;
+ 
+ 	/* the iWMMXt context must be 64 bit aligned */
+-	WARN_ON((unsigned long)frame & 7);
+-
+-	__put_user_error(IWMMXT_MAGIC0, &frame->magic0, err);
+-	__put_user_error(IWMMXT_MAGIC1, &frame->magic1, err);
+-
+-	/*
+-	 * iwmmxt_task_copy() doesn't check user permissions.
+-	 * Let's do a dummy write on the upper boundary to ensure
+-	 * access to user mem is OK all way up.
+-	 */
+-	err |= copy_locked(&frame->storage, current_thread_info(),
+-			   sizeof(frame->storage), 1, iwmmxt_task_copy);
+-	return err;
++	kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
++	kframe->magic0 = IWMMXT_MAGIC0;
++	kframe->magic1 = IWMMXT_MAGIC1;
++	iwmmxt_task_copy(current_thread_info(), &kframe->storage);
++	return __copy_to_user(frame, kframe, sizeof(*frame));
+ }
+ 
+ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
+ {
+-	unsigned long magic0, magic1;
+-	int err = 0;
++	char kbuf[sizeof(*frame) + 8];
++	struct iwmmxt_sigframe *kframe;
+ 
+-	/* the iWMMXt context is 64 bit aligned */
+-	WARN_ON((unsigned long)frame & 7);
+-
+-	/*
+-	 * Validate iWMMXt context signature.
+-	 * Also, iwmmxt_task_restore() doesn't check user permissions.
+-	 * Let's do a dummy write on the upper boundary to ensure
+-	 * access to user mem is OK all way up.
+-	 */
+-	__get_user_error(magic0, &frame->magic0, err);
+-	__get_user_error(magic1, &frame->magic1, err);
+-	if (!err && magic0 == IWMMXT_MAGIC0 && magic1 == IWMMXT_MAGIC1)
+-		err = copy_locked(&frame->storage, current_thread_info(),
+-				  sizeof(frame->storage), 0, iwmmxt_task_restore);
+-	return err;
++	/* the iWMMXt context must be 64 bit aligned */
++	kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
++	if (__copy_from_user(kframe, frame, sizeof(*frame)))
++		return -1;
++	if (kframe->magic0 != IWMMXT_MAGIC0 ||
++	    kframe->magic1 != IWMMXT_MAGIC1)
++		return -1;
++	iwmmxt_task_restore(current_thread_info(), &kframe->storage);
++	return 0;
+ }
+ 
+ #endif
+diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
+--- a/arch/arm/kernel/time.c
++++ b/arch/arm/kernel/time.c
+@@ -36,10 +36,6 @@
+ #include <asm/thread_info.h>
+ #include <asm/mach/time.h>
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ /*
+  * Our system timer.
+  */
+diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
+--- a/arch/arm/kernel/traps.c
++++ b/arch/arm/kernel/traps.c
+@@ -198,25 +198,16 @@ void show_stack(struct task_struct *tsk,
+ 	barrier();
+ }
+ 
+-DEFINE_SPINLOCK(die_lock);
+-
+-/*
+- * This function is protected against re-entrancy.
+- */
+-NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
++static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
+ {
+-	struct task_struct *tsk = current;
++	struct task_struct *tsk = thread->task;
+ 	static int die_counter;
+ 
+-	console_verbose();
+-	spin_lock_irq(&die_lock);
+-	bust_spinlocks(1);
+-
+ 	printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
+ 	print_modules();
+ 	__show_regs(regs);
+ 	printk("Process %s (pid: %d, stack limit = 0x%p)\n",
+-		tsk->comm, tsk->pid, tsk->thread_info + 1);
++		tsk->comm, tsk->pid, thread + 1);
+ 
+ 	if (!user_mode(regs) || in_interrupt()) {
+ 		dump_mem("Stack: ", regs->ARM_sp,
+@@ -224,7 +215,21 @@ NORET_TYPE void die(const char *str, str
+ 		dump_backtrace(regs, tsk);
+ 		dump_instr(regs);
+ 	}
++}
++
++DEFINE_SPINLOCK(die_lock);
++
++/*
++ * This function is protected against re-entrancy.
++ */
++NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
++{
++	struct thread_info *thread = current_thread_info();
+ 
++	console_verbose();
++	spin_lock_irq(&die_lock);
++	bust_spinlocks(1);
++	__die(str, err, thread, regs);
+ 	bust_spinlocks(0);
+ 	spin_unlock_irq(&die_lock);
+ 	do_exit(SIGSEGV);
+@@ -345,7 +350,9 @@ static int bad_syscall(int n, struct pt_
+ 	struct thread_info *thread = current_thread_info();
+ 	siginfo_t info;
+ 
+-	if (current->personality != PER_LINUX && thread->exec_domain->handler) {
++	if (current->personality != PER_LINUX &&
++	    current->personality != PER_LINUX_32BIT &&
++	    thread->exec_domain->handler) {
+ 		thread->exec_domain->handler(n, regs);
+ 		return regs->ARM_r0;
+ 	}
+@@ -481,29 +488,33 @@ asmlinkage int arm_syscall(int no, struc
+ 		unsigned long addr = regs->ARM_r2;
+ 		struct mm_struct *mm = current->mm;
+ 		pgd_t *pgd; pmd_t *pmd; pte_t *pte;
++		spinlock_t *ptl;
+ 
+ 		regs->ARM_cpsr &= ~PSR_C_BIT;
+-		spin_lock(&mm->page_table_lock);
++		down_read(&mm->mmap_sem);
+ 		pgd = pgd_offset(mm, addr);
+ 		if (!pgd_present(*pgd))
+ 			goto bad_access;
+ 		pmd = pmd_offset(pgd, addr);
+ 		if (!pmd_present(*pmd))
+ 			goto bad_access;
+-		pte = pte_offset_map(pmd, addr);
+-		if (!pte_present(*pte) || !pte_write(*pte))
++		pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
++		if (!pte_present(*pte) || !pte_write(*pte)) {
++			pte_unmap_unlock(pte, ptl);
+ 			goto bad_access;
++		}
+ 		val = *(unsigned long *)addr;
+ 		val -= regs->ARM_r0;
+ 		if (val == 0) {
+ 			*(unsigned long *)addr = regs->ARM_r1;
+ 			regs->ARM_cpsr |= PSR_C_BIT;
+ 		}
+-		spin_unlock(&mm->page_table_lock);
++		pte_unmap_unlock(pte, ptl);
++		up_read(&mm->mmap_sem);
+ 		return val;
+ 
+ 		bad_access:
+-		spin_unlock(&mm->page_table_lock);
++		up_read(&mm->mmap_sem);
+ 		/* simulate a write access fault */
+ 		do_DataAbort(addr, 15 + (1 << 11), regs);
+ 		return -1;
+diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
+--- a/arch/arm/kernel/vmlinux.lds.S
++++ b/arch/arm/kernel/vmlinux.lds.S
+@@ -6,14 +6,23 @@
+ #include <asm-generic/vmlinux.lds.h>
+ #include <linux/config.h>
+ #include <asm/thread_info.h>
++#include <asm/memory.h>
+ 	
+ OUTPUT_ARCH(arm)
+ ENTRY(stext)
++
+ #ifndef __ARMEB__
+ jiffies = jiffies_64;
+ #else
+ jiffies = jiffies_64 + 4;
+ #endif
++
++#ifdef CONFIG_XIP_KERNEL
++#define TEXTADDR  XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
++#else
++#define TEXTADDR  KERNEL_RAM_ADDR
++#endif
++
+ SECTIONS
+ {
+ 	. = TEXTADDR;
+@@ -95,7 +104,7 @@ SECTIONS
+ 
+ #ifdef CONFIG_XIP_KERNEL
+ 	__data_loc = ALIGN(4);		/* location in binary */
+-	. = DATAADDR;
++	. = KERNEL_RAM_ADDR;
+ #else
+ 	. = ALIGN(THREAD_SIZE);
+ 	__data_loc = .;
+diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
+--- a/arch/arm/lib/Makefile
++++ b/arch/arm/lib/Makefile
+@@ -7,13 +7,27 @@
+ lib-y		:= backtrace.o changebit.o csumipv6.o csumpartial.o   \
+ 		   csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
+ 		   copy_page.o delay.o findbit.o memchr.o memcpy.o    \
+-		   memset.o memzero.o setbit.o strncpy_from_user.o    \
+-		   strnlen_user.o strchr.o strrchr.o testchangebit.o  \
+-		   testclearbit.o testsetbit.o uaccess.o getuser.o    \
+-		   putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o   \
+-		   ucmpdi2.o lib1funcs.o div64.o	              \
++		   memmove.o memset.o memzero.o setbit.o              \
++		   strncpy_from_user.o strnlen_user.o                 \
++		   strchr.o strrchr.o                                 \
++		   testchangebit.o testclearbit.o testsetbit.o        \
++		   getuser.o putuser.o clear_user.o                   \
++		   ashldi3.o ashrdi3.o lshrdi3.o muldi3.o             \
++		   ucmpdi2.o lib1funcs.o div64.o sha1.o               \
+ 		   io-readsb.o io-writesb.o io-readsl.o io-writesl.o
+ 
++# the code in uaccess.S is not preemption safe and
++# probably faster on ARMv3 only
++ifeq ($CONFIG_PREEMPT,y)
++  lib-y	+= copy_from_user.o copy_to_user.o
++else
++ifneq ($(CONFIG_CPU_32v3),y)
++  lib-y	+= copy_from_user.o copy_to_user.o
++else
++  lib-y	+= uaccess.o
++endif
++endif
++
+ ifeq ($(CONFIG_CPU_32v3),y)
+   lib-y	+= io-readsw-armv3.o io-writesw-armv3.o
+ else
+diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/ashldi3.S
+@@ -0,0 +1,48 @@
++/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
++   Free Software Foundation, Inc.
++
++This file is free software; you can redistribute 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.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file into combinations with other programs,
++and to distribute those combinations without any restriction coming
++from the use of this file.  (The General Public License restrictions
++do apply in other respects; for example, they cover modification of
++the file, and distribution when not linked into a combine
++executable.)
++
++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.
++
++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, 51 Franklin Street, Fifth Floor,
++Boston, MA 02110-1301, USA.  */
++
++
++#include <linux/linkage.h>
++
++#ifdef __ARMEB__
++#define al r1
++#define ah r0
++#else
++#define al r0
++#define ah r1
++#endif
++
++ENTRY(__ashldi3)
++
++	subs	r3, r2, #32
++	rsb	ip, r2, #32
++	movmi	ah, ah, lsl r2
++	movpl	ah, al, lsl r3
++	orrmi	ah, ah, al, lsr ip
++	mov	al, al, lsl r2
++	mov	pc, lr
++
+diff --git a/arch/arm/lib/ashldi3.c b/arch/arm/lib/ashldi3.c
+deleted file mode 100644
+--- a/arch/arm/lib/ashldi3.c
++++ /dev/null
+@@ -1,56 +0,0 @@
+-/* More subroutines needed by GCC output code on some machines.  */
+-/* Compile this one with gcc.  */
+-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+-
+-This file is part of GNU CC.
+-
+-GNU CC is free software; you can redistribute 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.
+-
+-GNU CC is distributed in the hope that it will be useful,
+-but WITHOUT ANY WARRANTY; without even the implied warranty of
+-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-GNU General Public License for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with GNU CC; see the file COPYING.  If not, write to
+-the Free Software Foundation, 59 Temple Place - Suite 330,
+-Boston, MA 02111-1307, USA.  */
+-
+-/* As a special exception, if you link this library with other files,
+-   some of which are compiled with GCC, to produce an executable,
+-   this library does not by itself cause the resulting executable
+-   to be covered by the GNU General Public License.
+-   This exception does not however invalidate any other reasons why
+-   the executable file might be covered by the GNU General Public License.
+- */
+-/* support functions required by the kernel. based on code from gcc-2.95.3 */
+-/* I Molton	29/07/01 */
+-
+-#include "gcclib.h"
+-
+-s64 __ashldi3(s64 u, int b)
+-{
+-	DIunion w;
+-	int bm;
+-	DIunion uu;
+-
+-	if (b == 0)
+-		return u;
+-
+-	uu.ll = u;
+-
+-	bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+-	if (bm <= 0) {
+-		w.s.low = 0;
+-		w.s.high = (u32) uu.s.low << -bm;
+-	} else {
+-		u32 carries = (u32) uu.s.low >> bm;
+-		w.s.low = (u32) uu.s.low << b;
+-		w.s.high = ((u32) uu.s.high << b) | carries;
+-	}
+-
+-	return w.ll;
+-}
+diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/ashrdi3.S
+@@ -0,0 +1,48 @@
++/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
++   Free Software Foundation, Inc.
++
++This file is free software; you can redistribute 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.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file into combinations with other programs,
++and to distribute those combinations without any restriction coming
++from the use of this file.  (The General Public License restrictions
++do apply in other respects; for example, they cover modification of
++the file, and distribution when not linked into a combine
++executable.)
++
++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.
++
++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, 51 Franklin Street, Fifth Floor,
++Boston, MA 02110-1301, USA.  */
++
++
++#include <linux/linkage.h>
++
++#ifdef __ARMEB__
++#define al r1
++#define ah r0
++#else
++#define al r0
++#define ah r1
++#endif
++
++ENTRY(__ashrdi3)
++
++	subs	r3, r2, #32
++	rsb	ip, r2, #32
++	movmi	al, al, lsr r2
++	movpl	al, ah, asr r3
++	orrmi	al, al, ah, lsl ip
++	mov	ah, ah, asr r2
++	mov	pc, lr
++
+diff --git a/arch/arm/lib/ashrdi3.c b/arch/arm/lib/ashrdi3.c
+deleted file mode 100644
+--- a/arch/arm/lib/ashrdi3.c
++++ /dev/null
+@@ -1,57 +0,0 @@
+-/* More subroutines needed by GCC output code on some machines.  */
+-/* Compile this one with gcc.  */
+-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+-
+-This file is part of GNU CC.
+-
+-GNU CC is free software; you can redistribute 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.
+-
+-GNU CC is distributed in the hope that it will be useful,
+-but WITHOUT ANY WARRANTY; without even the implied warranty of
+-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-GNU General Public License for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with GNU CC; see the file COPYING.  If not, write to
+-the Free Software Foundation, 59 Temple Place - Suite 330,
+-Boston, MA 02111-1307, USA.  */
+-
+-/* As a special exception, if you link this library with other files,
+-   some of which are compiled with GCC, to produce an executable,
+-   this library does not by itself cause the resulting executable
+-   to be covered by the GNU General Public License.
+-   This exception does not however invalidate any other reasons why
+-   the executable file might be covered by the GNU General Public License.
+- */
+-/* support functions required by the kernel. based on code from gcc-2.95.3 */
+-/* I Molton     29/07/01 */
+-
+-#include "gcclib.h"
+-
+-s64 __ashrdi3(s64 u, int b)
+-{
+-	DIunion w;
+-	int bm;
+-	DIunion uu;
+-
+-	if (b == 0)
+-		return u;
+-
+-	uu.ll = u;
+-
+-	bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+-	if (bm <= 0) {
+-		/* w.s.high = 1..1 or 0..0 */
+-		w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
+-		w.s.low = uu.s.high >> -bm;
+-	} else {
+-		u32 carries = (u32) uu.s.high << bm;
+-		w.s.high = uu.s.high >> b;
+-		w.s.low = ((u32) uu.s.low >> b) | carries;
+-	}
+-
+-	return w.ll;
+-}
+diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/clear_user.S
+@@ -0,0 +1,52 @@
++/*
++ *  linux/arch/arm/lib/clear_user.S
++ *
++ *  Copyright (C) 1995, 1996,1997,1998 Russell King
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++
++		.text
++
++/* Prototype: int __arch_clear_user(void *addr, size_t sz)
++ * Purpose  : clear some user memory
++ * Params   : addr - user memory address to clear
++ *          : sz   - number of bytes to clear
++ * Returns  : number of bytes NOT cleared
++ */
++ENTRY(__arch_clear_user)
++		stmfd	sp!, {r1, lr}
++		mov	r2, #0
++		cmp	r1, #4
++		blt	2f
++		ands	ip, r0, #3
++		beq	1f
++		cmp	ip, #2
++USER(		strbt	r2, [r0], #1)
++USER(		strlebt	r2, [r0], #1)
++USER(		strltbt	r2, [r0], #1)
++		rsb	ip, ip, #4
++		sub	r1, r1, ip		@  7  6  5  4  3  2  1
++1:		subs	r1, r1, #8		@ -1 -2 -3 -4 -5 -6 -7
++USER(		strplt	r2, [r0], #4)
++USER(		strplt	r2, [r0], #4)
++		bpl	1b
++		adds	r1, r1, #4		@  3  2  1  0 -1 -2 -3
++USER(		strplt	r2, [r0], #4)
++2:		tst	r1, #2			@ 1x 1x 0x 0x 1x 1x 0x
++USER(		strnebt	r2, [r0], #1)
++USER(		strnebt	r2, [r0], #1)
++		tst	r1, #1			@ x1 x0 x1 x0 x1 x0 x1
++USER(		strnebt	r2, [r0], #1)
++		mov	r0, #0
++		LOADREGS(fd,sp!, {r1, pc})
++
++		.section .fixup,"ax"
++		.align	0
++9001:		LOADREGS(fd,sp!, {r0, pc})
++		.previous
++
+diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/copy_from_user.S
+@@ -0,0 +1,101 @@
++/*
++ *  linux/arch/arm/lib/copy_from_user.S
++ *
++ *  Author:	Nicolas Pitre
++ *  Created:	Sep 29, 2005
++ *  Copyright:	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/assembler.h>
++
++/*
++ * Prototype:
++ *
++ *	size_t __arch_copy_from_user(void *to, const void *from, size_t n)
++ *
++ * Purpose:
++ *
++ *	copy a block to kernel memory from user memory
++ *
++ * Params:
++ *
++ *	to = kernel memory
++ *	from = user memory
++ *	n = number of bytes to copy
++ *
++ * Return value:
++ *
++ *	Number of bytes NOT copied.
++ */
++
++	.macro ldr1w ptr reg abort
++100:	ldrt \reg, [\ptr], #4
++	.section __ex_table, "a"
++	.long 100b, \abort
++	.previous
++	.endm
++
++	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
++	ldr1w \ptr, \reg1, \abort
++	ldr1w \ptr, \reg2, \abort
++	ldr1w \ptr, \reg3, \abort
++	ldr1w \ptr, \reg4, \abort
++	.endm
++
++	.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
++	ldr4w \ptr, \reg1, \reg2, \reg3, \reg4, \abort
++	ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort
++	.endm
++
++	.macro ldr1b ptr reg cond=al abort
++100:	ldr\cond\()bt \reg, [\ptr], #1
++	.section __ex_table, "a"
++	.long 100b, \abort
++	.previous
++	.endm
++
++	.macro str1w ptr reg abort
++	str \reg, [\ptr], #4
++	.endm
++
++	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
++	stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
++	.endm
++
++	.macro str1b ptr reg cond=al abort
++	str\cond\()b \reg, [\ptr], #1
++	.endm
++
++	.macro enter reg1 reg2
++	mov	r3, #0
++	stmdb	sp!, {r0, r2, r3, \reg1, \reg2}
++	.endm
++
++	.macro exit reg1 reg2
++	add	sp, sp, #8
++	ldmfd	sp!, {r0, \reg1, \reg2}
++	.endm
++
++	.text
++
++ENTRY(__arch_copy_from_user)
++
++#include "copy_template.S"
++
++	.section .fixup,"ax"
++	.align 0
++	copy_abort_preamble
++	ldmfd	sp!, {r1, r2}
++	sub	r3, r0, r1
++	rsb	r1, r3, r2
++	str	r1, [sp]
++	bl	__memzero
++	ldr	r0, [sp], #4
++	copy_abort_end
++	.previous
++
+diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/copy_template.S
+@@ -0,0 +1,255 @@
++/*
++ *  linux/arch/arm/lib/copy_template.s
++ *
++ *  Code template for optimized memory copy functions
++ *
++ *  Author:	Nicolas Pitre
++ *  Created:	Sep 28, 2005
++ *  Copyright:	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.
++ */
++
++/*
++ * This can be used to enable code to cacheline align the source pointer.
++ * Experiments on tested architectures (StrongARM and XScale) didn't show
++ * this a worthwhile thing to do.  That might be different in the future.
++ */
++//#define CALGN(code...)	code
++#define CALGN(code...)
++
++/*
++ * Theory of operation
++ * -------------------
++ *
++ * This file provides the core code for a forward memory copy used in
++ * the implementation of memcopy(), copy_to_user() and copy_from_user().
++ *
++ * The including file must define the following accessor macros
++ * according to the need of the given function:
++ *
++ * ldr1w ptr reg abort
++ *
++ *	This loads one word from 'ptr', stores it in 'reg' and increments
++ *	'ptr' to the next word. The 'abort' argument is used for fixup tables.
++ *
++ * ldr4w ptr reg1 reg2 reg3 reg4 abort
++ * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
++ *
++ *	This loads four or eight words starting from 'ptr', stores them
++ *	in provided registers and increments 'ptr' past those words.
++ *	The'abort' argument is used for fixup tables.
++ *
++ * ldr1b ptr reg cond abort
++ *
++ *	Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
++ *	It also must apply the condition code if provided, otherwise the
++ *	"al" condition is assumed by default.
++ *
++ * str1w ptr reg abort
++ * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
++ * str1b ptr reg cond abort
++ *
++ *	Same as their ldr* counterparts, but data is stored to 'ptr' location
++ *	rather than being loaded.
++ *
++ * enter reg1 reg2
++ *
++ *	Preserve the provided registers on the stack plus any additional
++ *	data as needed by the implementation including this code. Called
++ *	upon code entry.
++ *
++ * exit reg1 reg2
++ *
++ *	Restore registers with the values previously saved with the
++ *	'preserv' macro. Called upon code termination.
++ */
++
++
++		enter	r4, lr
++
++		subs	r2, r2, #4
++		blt	8f
++		ands	ip, r0, #3
++	PLD(	pld	[r1, #0]		)
++		bne	9f
++		ands	ip, r1, #3
++		bne	10f
++
++1:		subs	r2, r2, #(28)
++		stmfd	sp!, {r5 - r8}
++		blt	5f
++
++	CALGN(	ands	ip, r1, #31		)
++	CALGN(	rsb	r3, ip, #32		)
++	CALGN(	sbcnes	r4, r3, r2		)  @ C is always set here
++	CALGN(	bcs	2f			)
++	CALGN(	adr	r4, 6f			)
++	CALGN(	subs	r2, r2, r3		)  @ C gets set
++	CALGN(	add	pc, r4, ip		)
++
++	PLD(	pld	[r1, #0]		)
++2:	PLD(	subs	r2, r2, #96		)
++	PLD(	pld	[r1, #28]		)
++	PLD(	blt	4f			)
++	PLD(	pld	[r1, #60]		)
++	PLD(	pld	[r1, #92]		)
++
++3:	PLD(	pld	[r1, #124]		)
++4:		ldr8w	r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
++		subs	r2, r2, #32
++		str8w	r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
++		bge	3b
++	PLD(	cmn	r2, #96			)
++	PLD(	bge	4b			)
++
++5:		ands	ip, r2, #28
++		rsb	ip, ip, #32
++		addne	pc, pc, ip		@ C is always clear here
++		b	7f
++6:		nop
++		ldr1w	r1, r3, abort=20f
++		ldr1w	r1, r4, abort=20f
++		ldr1w	r1, r5, abort=20f
++		ldr1w	r1, r6, abort=20f
++		ldr1w	r1, r7, abort=20f
++		ldr1w	r1, r8, abort=20f
++		ldr1w	r1, lr, abort=20f
++
++		add	pc, pc, ip
++		nop
++		nop
++		str1w	r0, r3, abort=20f
++		str1w	r0, r4, abort=20f
++		str1w	r0, r5, abort=20f
++		str1w	r0, r6, abort=20f
++		str1w	r0, r7, abort=20f
++		str1w	r0, r8, abort=20f
++		str1w	r0, lr, abort=20f
++
++	CALGN(	bcs	2b			)
++
++7:		ldmfd	sp!, {r5 - r8}
++
++8:		movs	r2, r2, lsl #31
++		ldr1b	r1, r3, ne, abort=21f
++		ldr1b	r1, r4, cs, abort=21f
++		ldr1b	r1, ip, cs, abort=21f
++		str1b	r0, r3, ne, abort=21f
++		str1b	r0, r4, cs, abort=21f
++		str1b	r0, ip, cs, abort=21f
++
++		exit	r4, pc
++
++9:		rsb	ip, ip, #4
++		cmp	ip, #2
++		ldr1b	r1, r3, gt, abort=21f
++		ldr1b	r1, r4, ge, abort=21f
++		ldr1b	r1, lr, abort=21f
++		str1b	r0, r3, gt, abort=21f
++		str1b	r0, r4, ge, abort=21f
++		subs	r2, r2, ip
++		str1b	r0, lr, abort=21f
++		blt	8b
++		ands	ip, r1, #3
++		beq	1b
++
++10:		bic	r1, r1, #3
++		cmp	ip, #2
++		ldr1w	r1, lr, abort=21f
++		beq	17f
++		bgt	18f
++
++
++		.macro	forward_copy_shift pull push
++
++		subs	r2, r2, #28
++		blt	14f
++
++	CALGN(	ands	ip, r1, #31		)
++	CALGN(	rsb	ip, ip, #32		)
++	CALGN(	sbcnes	r4, ip, r2		)  @ C is always set here
++	CALGN(	subcc	r2, r2, ip		)
++	CALGN(	bcc	15f			)
++
++11:		stmfd	sp!, {r5 - r9}
++
++	PLD(	pld	[r1, #0]		)
++	PLD(	subs	r2, r2, #96		)
++	PLD(	pld	[r1, #28]		)
++	PLD(	blt	13f			)
++	PLD(	pld	[r1, #60]		)
++	PLD(	pld	[r1, #92]		)
++
++12:	PLD(	pld	[r1, #124]		)
++13:		ldr4w	r1, r4, r5, r6, r7, abort=19f
++		mov	r3, lr, pull #\pull
++		subs	r2, r2, #32
++		ldr4w	r1, r8, r9, ip, lr, abort=19f
++		orr	r3, r3, r4, push #\push
++		mov	r4, r4, pull #\pull
++		orr	r4, r4, r5, push #\push
++		mov	r5, r5, pull #\pull
++		orr	r5, r5, r6, push #\push
++		mov	r6, r6, pull #\pull
++		orr	r6, r6, r7, push #\push
++		mov	r7, r7, pull #\pull
++		orr	r7, r7, r8, push #\push
++		mov	r8, r8, pull #\pull
++		orr	r8, r8, r9, push #\push
++		mov	r9, r9, pull #\pull
++		orr	r9, r9, ip, push #\push
++		mov	ip, ip, pull #\pull
++		orr	ip, ip, lr, push #\push
++		str8w	r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
++		bge	12b
++	PLD(	cmn	r2, #96			)
++	PLD(	bge	13b			)
++
++		ldmfd	sp!, {r5 - r9}
++
++14:		ands	ip, r2, #28
++		beq	16f
++
++15:		mov	r3, lr, pull #\pull
++		ldr1w	r1, lr, abort=21f
++		subs	ip, ip, #4
++		orr	r3, r3, lr, push #\push
++		str1w	r0, r3, abort=21f
++		bgt	15b
++	CALGN(	cmp	r2, #0			)
++	CALGN(	bge	11b			)
++
++16:		sub	r1, r1, #(\push / 8)
++		b	8b
++
++		.endm
++
++
++		forward_copy_shift	pull=8	push=24
++
++17:		forward_copy_shift	pull=16	push=16
++
++18:		forward_copy_shift	pull=24	push=8
++
++
++/*
++ * Abort preanble and completion macros.
++ * If a fixup handler is required then those macros must surround it.
++ * It is assumed that the fixup code will handle the private part of
++ * the exit macro.
++ */
++
++	.macro	copy_abort_preamble
++19:	ldmfd	sp!, {r5 - r9}
++	b	21f
++20:	ldmfd	sp!, {r5 - r8}
++21:
++	.endm
++
++	.macro	copy_abort_end
++	ldmfd	sp!, {r4, pc}
++	.endm
++
+diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/copy_to_user.S
+@@ -0,0 +1,101 @@
++/*
++ *  linux/arch/arm/lib/copy_to_user.S
++ *
++ *  Author:	Nicolas Pitre
++ *  Created:	Sep 29, 2005
++ *  Copyright:	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/assembler.h>
++
++/*
++ * Prototype:
++ *
++ *	size_t __arch_copy_to_user(void *to, const void *from, size_t n)
++ *
++ * Purpose:
++ *
++ *	copy a block to user memory from kernel memory
++ *
++ * Params:
++ *
++ *	to = user memory
++ *	from = kernel memory
++ *	n = number of bytes to copy
++ *
++ * Return value:
++ *
++ *	Number of bytes NOT copied.
++ */
++
++	.macro ldr1w ptr reg abort
++	ldr \reg, [\ptr], #4
++	.endm
++
++	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
++	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
++	.endm
++
++	.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
++	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
++	.endm
++
++	.macro ldr1b ptr reg cond=al abort
++	ldr\cond\()b \reg, [\ptr], #1
++	.endm
++
++	.macro str1w ptr reg abort
++100:	strt \reg, [\ptr], #4
++	.section __ex_table, "a"
++	.long 100b, \abort
++	.previous
++	.endm
++
++	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
++	str1w \ptr, \reg1, \abort
++	str1w \ptr, \reg2, \abort
++	str1w \ptr, \reg3, \abort
++	str1w \ptr, \reg4, \abort
++	str1w \ptr, \reg5, \abort
++	str1w \ptr, \reg6, \abort
++	str1w \ptr, \reg7, \abort
++	str1w \ptr, \reg8, \abort
++	.endm
++
++	.macro str1b ptr reg cond=al abort
++100:	str\cond\()bt \reg, [\ptr], #1
++	.section __ex_table, "a"
++	.long 100b, \abort
++	.previous
++	.endm
++
++	.macro enter reg1 reg2
++	mov	r3, #0
++	stmdb	sp!, {r0, r2, r3, \reg1, \reg2}
++	.endm
++
++	.macro exit reg1 reg2
++	add	sp, sp, #8
++	ldmfd	sp!, {r0, \reg1, \reg2}
++	.endm
++
++	.text
++
++ENTRY(__arch_copy_to_user)
++
++#include "copy_template.S"
++
++	.section .fixup,"ax"
++	.align 0
++	copy_abort_preamble
++	ldmfd	sp!, {r1, r2, r3}
++	sub	r0, r0, r1
++	rsb	r0, r0, r2
++	copy_abort_end
++	.previous
++
+diff --git a/arch/arm/lib/gcclib.h b/arch/arm/lib/gcclib.h
+deleted file mode 100644
+--- a/arch/arm/lib/gcclib.h
++++ /dev/null
+@@ -1,22 +0,0 @@
+-/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
+-/* I Molton     29/07/01 */
+-
+-#include <linux/types.h>
+-
+-#define BITS_PER_UNIT	8
+-#define SI_TYPE_SIZE	(sizeof(s32) * BITS_PER_UNIT)
+-
+-#ifdef __ARMEB__
+-struct DIstruct {
+-	s32 high, low;
+-};
+-#else
+-struct DIstruct {
+-	s32 low, high;
+-};
+-#endif
+-
+-typedef union {
+-	struct DIstruct s;
+-	s64 ll;
+-} DIunion;
+diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/lshrdi3.S
+@@ -0,0 +1,48 @@
++/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
++   Free Software Foundation, Inc.
++
++This file is free software; you can redistribute 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.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file into combinations with other programs,
++and to distribute those combinations without any restriction coming
++from the use of this file.  (The General Public License restrictions
++do apply in other respects; for example, they cover modification of
++the file, and distribution when not linked into a combine
++executable.)
++
++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.
++
++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, 51 Franklin Street, Fifth Floor,
++Boston, MA 02110-1301, USA.  */
++
++
++#include <linux/linkage.h>
++
++#ifdef __ARMEB__
++#define al r1
++#define ah r0
++#else
++#define al r0
++#define ah r1
++#endif
++
++ENTRY(__lshrdi3)
++
++	subs	r3, r2, #32
++	rsb	ip, r2, #32
++	movmi	al, al, lsr r2
++	movpl	al, ah, lsr r3
++	orrmi	al, al, ah, lsl ip
++	mov	ah, ah, lsr r2
++	mov	pc, lr
++
+diff --git a/arch/arm/lib/lshrdi3.c b/arch/arm/lib/lshrdi3.c
+deleted file mode 100644
+--- a/arch/arm/lib/lshrdi3.c
++++ /dev/null
+@@ -1,56 +0,0 @@
+-/* More subroutines needed by GCC output code on some machines.  */
+-/* Compile this one with gcc.  */
+-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+-
+-This file is part of GNU CC.
+-
+-GNU CC is free software; you can redistribute 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.
+-
+-GNU CC is distributed in the hope that it will be useful,
+-but WITHOUT ANY WARRANTY; without even the implied warranty of
+-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-GNU General Public License for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with GNU CC; see the file COPYING.  If not, write to
+-the Free Software Foundation, 59 Temple Place - Suite 330,
+-Boston, MA 02111-1307, USA.  */
+-
+-/* As a special exception, if you link this library with other files,
+-   some of which are compiled with GCC, to produce an executable,
+-   this library does not by itself cause the resulting executable
+-   to be covered by the GNU General Public License.
+-   This exception does not however invalidate any other reasons why
+-   the executable file might be covered by the GNU General Public License.
+- */
+-/* support functions required by the kernel. based on code from gcc-2.95.3 */
+-/* I Molton     29/07/01 */
+-
+-#include "gcclib.h"
+-
+-s64 __lshrdi3(s64 u, int b)
+-{
+-	DIunion w;
+-	int bm;
+-	DIunion uu;
+-
+-	if (b == 0)
+-		return u;
+-
+-	uu.ll = u;
+-
+-	bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+-	if (bm <= 0) {
+-		w.s.high = 0;
+-		w.s.low = (u32) uu.s.high >> -bm;
+-	} else {
+-		u32 carries = (u32) uu.s.high << bm;
+-		w.s.high = (u32) uu.s.high >> b;
+-		w.s.low = ((u32) uu.s.low >> b) | carries;
+-	}
+-
+-	return w.ll;
+-}
+diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
+--- a/arch/arm/lib/memcpy.S
++++ b/arch/arm/lib/memcpy.S
+@@ -1,393 +1,59 @@
+ /*
+  *  linux/arch/arm/lib/memcpy.S
+  *
+- *  Copyright (C) 1995-1999 Russell King
++ *  Author:	Nicolas Pitre
++ *  Created:	Sep 28, 2005
++ *  Copyright:	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.
+- *
+- *  ASM optimised string functions
++ *  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/assembler.h>
+ 
+-		.text
++	.macro ldr1w ptr reg abort
++	ldr \reg, [\ptr], #4
++	.endm
+ 
+-#define ENTER	\
+-		mov	ip,sp	;\
+-		stmfd	sp!,{r0,r4-r9,fp,ip,lr,pc}	;\
+-		sub	fp,ip,#4
++	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
++	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
++	.endm
+ 
+-#define EXIT	\
+-		LOADREGS(ea, fp, {r0, r4 - r9, fp, sp, pc})
++	.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
++	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
++	.endm
+ 
+-#define EXITEQ	\
+-		LOADREGS(eqea, fp, {r0, r4 - r9, fp, sp, pc})
++	.macro ldr1b ptr reg cond=al abort
++	ldr\cond\()b \reg, [\ptr], #1
++	.endm
++
++	.macro str1w ptr reg abort
++	str \reg, [\ptr], #4
++	.endm
++
++	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
++	stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
++	.endm
++
++	.macro str1b ptr reg cond=al abort
++	str\cond\()b \reg, [\ptr], #1
++	.endm
++
++	.macro enter reg1 reg2
++	stmdb sp!, {r0, \reg1, \reg2}
++	.endm
++
++	.macro exit reg1 reg2
++	ldmfd sp!, {r0, \reg1, \reg2}
++	.endm
++
++	.text
++
++/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+ 
+-/*
+- * Prototype: void memcpy(void *to,const void *from,unsigned long n);
+- */
+ ENTRY(memcpy)
+-ENTRY(memmove)
+-		ENTER
+-		cmp	r1, r0
+-		bcc	23f
+-		subs	r2, r2, #4
+-		blt	6f
+-	PLD(	pld	[r1, #0]		)
+-		ands	ip, r0, #3
+-		bne	7f
+-		ands	ip, r1, #3
+-		bne	8f
+-
+-1:		subs	r2, r2, #8
+-		blt	5f
+-		subs	r2, r2, #20
+-		blt	4f
+-	PLD(	pld	[r1, #28]		)
+-	PLD(	subs	r2, r2, #64		)
+-	PLD(	blt	3f			)
+-2:	PLD(	pld	[r1, #60]		)
+-	PLD(	pld	[r1, #92]		)
+-		ldmia	r1!, {r3 - r9, ip}
+-		subs	r2, r2, #32
+-		stmgeia	r0!, {r3 - r9, ip}
+-		ldmgeia	r1!, {r3 - r9, ip}
+-		subges	r2, r2, #32
+-		stmia	r0!, {r3 - r9, ip}
+-		bge	2b
+-3:	PLD(	ldmia	r1!, {r3 - r9, ip}	)
+-	PLD(	adds	r2, r2, #32		)
+-	PLD(	stmgeia	r0!, {r3 - r9, ip}	)
+-	PLD(	ldmgeia	r1!, {r3 - r9, ip}	)
+-	PLD(	subges	r2, r2, #32		)
+-	PLD(	stmia	r0!, {r3 - r9, ip}	)
+-4:		cmn	r2, #16
+-		ldmgeia	r1!, {r3 - r6}
+-		subge	r2, r2, #16
+-		stmgeia	r0!, {r3 - r6}
+-		adds	r2, r2, #20
+-		ldmgeia	r1!, {r3 - r5}
+-		subge	r2, r2, #12
+-		stmgeia	r0!, {r3 - r5}
+-5:		adds	r2, r2, #8
+-		blt	6f
+-		subs	r2, r2, #4
+-		ldrlt	r3, [r1], #4
+-		ldmgeia	r1!, {r4, r5}
+-		subge	r2, r2, #4
+-		strlt	r3, [r0], #4
+-		stmgeia	r0!, {r4, r5}
+-
+-6:		adds	r2, r2, #4
+-		EXITEQ
+-		cmp	r2, #2
+-		ldrb	r3, [r1], #1
+-		ldrgeb	r4, [r1], #1
+-		ldrgtb	r5, [r1], #1
+-		strb	r3, [r0], #1
+-		strgeb	r4, [r0], #1
+-		strgtb	r5, [r0], #1
+-		EXIT
+-
+-7:		rsb	ip, ip, #4
+-		cmp	ip, #2
+-		ldrb	r3, [r1], #1
+-		ldrgeb	r4, [r1], #1
+-		ldrgtb	r5, [r1], #1
+-		strb	r3, [r0], #1
+-		strgeb	r4, [r0], #1
+-		strgtb	r5, [r0], #1
+-		subs	r2, r2, ip
+-		blt	6b
+-		ands	ip, r1, #3
+-		beq	1b
+-
+-8:		bic	r1, r1, #3
+-		ldr	r7, [r1], #4
+-		cmp	ip, #2
+-		bgt	18f
+-		beq	13f
+-		cmp	r2, #12
+-		blt	11f
+-	PLD(	pld	[r1, #12]		)
+-		sub	r2, r2, #12
+-	PLD(	subs	r2, r2, #32		)
+-	PLD(	blt	10f			)
+-	PLD(	pld	[r1, #28]		)
+-9:	PLD(	pld	[r1, #44]		)
+-10:		mov	r3, r7, pull #8
+-		ldmia	r1!, {r4 - r7}
+-		subs	r2, r2, #16
+-		orr	r3, r3, r4, push #24
+-		mov	r4, r4, pull #8
+-		orr	r4, r4, r5, push #24
+-		mov	r5, r5, pull #8
+-		orr	r5, r5, r6, push #24
+-		mov	r6, r6, pull #8
+-		orr	r6, r6, r7, push #24
+-		stmia	r0!, {r3 - r6}
+-		bge	9b
+-	PLD(	cmn	r2, #32			)
+-	PLD(	bge	10b			)
+-	PLD(	add	r2, r2, #32		)
+-		adds	r2, r2, #12
+-		blt	12f
+-11:		mov	r3, r7, pull #8
+-		ldr	r7, [r1], #4
+-		subs	r2, r2, #4
+-		orr	r3, r3, r7, push #24
+-		str	r3, [r0], #4
+-		bge	11b
+-12:		sub	r1, r1, #3
+-		b	6b
+-
+-13:		cmp	r2, #12
+-		blt	16f
+-	PLD(	pld	[r1, #12]		)
+-		sub	r2, r2, #12
+-	PLD(	subs	r2, r2, #32		)
+-	PLD(	blt	15f			)
+-	PLD(	pld	[r1, #28]		)
+-14:	PLD(	pld	[r1, #44]		)
+-15:		mov	r3, r7, pull #16
+-		ldmia	r1!, {r4 - r7}
+-		subs	r2, r2, #16
+-		orr	r3, r3, r4, push #16
+-		mov	r4, r4, pull #16
+-		orr	r4, r4, r5, push #16
+-		mov	r5, r5, pull #16
+-		orr	r5, r5, r6, push #16
+-		mov	r6, r6, pull #16
+-		orr	r6, r6, r7, push #16
+-		stmia	r0!, {r3 - r6}
+-		bge	14b
+-	PLD(	cmn	r2, #32			)
+-	PLD(	bge	15b			)
+-	PLD(	add	r2, r2, #32		)
+-		adds	r2, r2, #12
+-		blt	17f
+-16:		mov	r3, r7, pull #16
+-		ldr	r7, [r1], #4
+-		subs	r2, r2, #4
+-		orr	r3, r3, r7, push #16
+-		str	r3, [r0], #4
+-		bge	16b
+-17:		sub	r1, r1, #2
+-		b	6b
+-
+-18:		cmp	r2, #12
+-		blt	21f
+-	PLD(	pld	[r1, #12]		)
+-		sub	r2, r2, #12
+-	PLD(	subs	r2, r2, #32		)
+-	PLD(	blt	20f			)
+-	PLD(	pld	[r1, #28]		)
+-19:	PLD(	pld	[r1, #44]		)
+-20:		mov	r3, r7, pull #24
+-		ldmia	r1!, {r4 - r7}
+-		subs	r2, r2, #16
+-		orr	r3, r3, r4, push #8
+-		mov	r4, r4, pull #24
+-		orr	r4, r4, r5, push #8
+-		mov	r5, r5, pull #24
+-		orr	r5, r5, r6, push #8
+-		mov	r6, r6, pull #24
+-		orr	r6, r6, r7, push #8
+-		stmia	r0!, {r3 - r6}
+-		bge	19b
+-	PLD(	cmn	r2, #32			)
+-	PLD(	bge	20b			)
+-	PLD(	add	r2, r2, #32		)
+-		adds	r2, r2, #12
+-		blt	22f
+-21:		mov	r3, r7, pull #24
+-		ldr	r7, [r1], #4
+-		subs	r2, r2, #4
+-		orr	r3, r3, r7, push #8
+-		str	r3, [r0], #4
+-		bge	21b
+-22:		sub	r1, r1, #1
+-		b	6b
+-
+-
+-23:		add	r1, r1, r2
+-		add	r0, r0, r2
+-		subs	r2, r2, #4
+-		blt	29f
+-	PLD(	pld	[r1, #-4]		)
+-		ands	ip, r0, #3
+-		bne	30f
+-		ands	ip, r1, #3
+-		bne	31f
+-
+-24:		subs	r2, r2, #8
+-		blt	28f
+-		subs	r2, r2, #20
+-		blt	27f
+-	PLD(	pld	[r1, #-32]		)
+-	PLD(	subs	r2, r2, #64		)
+-	PLD(	blt	26f			)
+-25:	PLD(	pld	[r1, #-64]		)
+-	PLD(	pld	[r1, #-96]		)
+-		ldmdb	r1!, {r3 - r9, ip}
+-		subs	r2, r2, #32
+-		stmgedb	r0!, {r3 - r9, ip}
+-		ldmgedb	r1!, {r3 - r9, ip}
+-		subges	r2, r2, #32
+-		stmdb	r0!, {r3 - r9, ip}
+-		bge	25b
+-26:	PLD(	ldmdb	r1!, {r3 - r9, ip}	)
+-	PLD(	adds	r2, r2, #32		)
+-	PLD(	stmgedb	r0!, {r3 - r9, ip}	)
+-	PLD(	ldmgedb	r1!, {r3 - r9, ip}	)
+-	PLD(	subges	r2, r2, #32		)
+-	PLD(	stmdb	r0!, {r3 - r9, ip}	)
+-27:		cmn	r2, #16
+-		ldmgedb	r1!, {r3 - r6}
+-		subge	r2, r2, #16
+-		stmgedb	r0!, {r3 - r6}
+-		adds	r2, r2, #20
+-		ldmgedb	r1!, {r3 - r5}
+-		subge	r2, r2, #12
+-		stmgedb	r0!, {r3 - r5}
+-28:		adds	r2, r2, #8
+-		blt	29f
+-		subs	r2, r2, #4
+-		ldrlt	r3, [r1, #-4]!
+-		ldmgedb	r1!, {r4, r5}
+-		subge	r2, r2, #4
+-		strlt	r3, [r0, #-4]!
+-		stmgedb	r0!, {r4, r5}
+-
+-29:		adds	r2, r2, #4
+-		EXITEQ
+-		cmp	r2, #2
+-		ldrb	r3, [r1, #-1]!
+-		ldrgeb	r4, [r1, #-1]!
+-		ldrgtb	r5, [r1, #-1]!
+-		strb	r3, [r0, #-1]!
+-		strgeb	r4, [r0, #-1]!
+-		strgtb	r5, [r0, #-1]!
+-		EXIT
+-
+-30:		cmp	ip, #2
+-		ldrb	r3, [r1, #-1]!
+-		ldrgeb	r4, [r1, #-1]!
+-		ldrgtb	r5, [r1, #-1]!
+-		strb	r3, [r0, #-1]!
+-		strgeb	r4, [r0, #-1]!
+-		strgtb	r5, [r0, #-1]!
+-		subs	r2, r2, ip
+-		blt	29b
+-		ands	ip, r1, #3
+-		beq	24b
+-
+-31:		bic	r1, r1, #3
+-		ldr	r3, [r1], #0
+-		cmp	ip, #2
+-		blt	41f
+-		beq	36f
+-		cmp	r2, #12
+-		blt	34f
+-	PLD(	pld	[r1, #-16]		)
+-		sub	r2, r2, #12
+-	PLD(	subs	r2, r2, #32		)
+-	PLD(	blt	33f			)
+-	PLD(	pld	[r1, #-32]		)
+-32:	PLD(	pld	[r1, #-48]		)
+-33:		mov	r7, r3, push #8
+-		ldmdb	r1!, {r3, r4, r5, r6}
+-		subs	r2, r2, #16
+-		orr	r7, r7, r6, pull #24
+-		mov	r6, r6, push #8
+-		orr	r6, r6, r5, pull #24
+-		mov	r5, r5, push #8
+-		orr	r5, r5, r4, pull #24
+-		mov	r4, r4, push #8
+-		orr	r4, r4, r3, pull #24
+-		stmdb	r0!, {r4, r5, r6, r7}
+-		bge	32b
+-	PLD(	cmn	r2, #32			)
+-	PLD(	bge	33b			)
+-	PLD(	add	r2, r2, #32		)
+-		adds	r2, r2, #12
+-		blt	35f
+-34:		mov	ip, r3, push #8
+-		ldr	r3, [r1, #-4]!
+-		subs	r2, r2, #4
+-		orr	ip, ip, r3, pull #24
+-		str	ip, [r0, #-4]!
+-		bge	34b
+-35:		add	r1, r1, #3
+-		b	29b
+-
+-36:		cmp	r2, #12
+-		blt	39f
+-	PLD(	pld	[r1, #-16]		)
+-		sub	r2, r2, #12
+-	PLD(	subs	r2, r2, #32		)
+-	PLD(	blt	38f			)
+-	PLD(	pld	[r1, #-32]		)
+-37:	PLD(	pld	[r1, #-48]		)
+-38:		mov	r7, r3, push #16
+-		ldmdb	r1!, {r3, r4, r5, r6}
+-		subs	r2, r2, #16
+-		orr	r7, r7, r6, pull #16
+-		mov	r6, r6, push #16
+-		orr	r6, r6, r5, pull #16
+-		mov	r5, r5, push #16
+-		orr	r5, r5, r4, pull #16
+-		mov	r4, r4, push #16
+-		orr	r4, r4, r3, pull #16
+-		stmdb	r0!, {r4, r5, r6, r7}
+-		bge	37b
+-	PLD(	cmn	r2, #32			)
+-	PLD(	bge	38b			)
+-	PLD(	add	r2, r2, #32		)
+-		adds	r2, r2, #12
+-		blt	40f
+-39:		mov	ip, r3, push #16
+-		ldr	r3, [r1, #-4]!
+-		subs	r2, r2, #4
+-		orr	ip, ip, r3, pull #16
+-		str	ip, [r0, #-4]!
+-		bge	39b
+-40:		add	r1, r1, #2
+-		b	29b
+-
+-41:		cmp	r2, #12
+-		blt	44f
+-	PLD(	pld	[r1, #-16]		)
+-		sub	r2, r2, #12
+-	PLD(	subs	r2, r2, #32		)
+-	PLD(	blt	43f			)
+-	PLD(	pld	[r1, #-32]		)
+-42:	PLD(	pld	[r1, #-48]		)
+-43:		mov	r7, r3, push #24
+-		ldmdb	r1!, {r3, r4, r5, r6}
+-		subs	r2, r2, #16
+-		orr	r7, r7, r6, pull #8
+-		mov	r6, r6, push #24
+-		orr	r6, r6, r5, pull #8
+-		mov	r5, r5, push #24
+-		orr	r5, r5, r4, pull #8
+-		mov	r4, r4, push #24
+-		orr	r4, r4, r3, pull #8
+-		stmdb	r0!, {r4, r5, r6, r7}
+-		bge	42b
+-	PLD(	cmn	r2, #32			)
+-	PLD(	bge	43b			)
+-	PLD(	add	r2, r2, #32		)
+-		adds	r2, r2, #12
+-		blt	45f
+-44:		mov	ip, r3, push #24
+-		ldr	r3, [r1, #-4]!
+-		subs	r2, r2, #4
+-		orr	ip, ip, r3, pull #8
+-		str	ip, [r0, #-4]!
+-		bge	44b
+-45:		add	r1, r1, #1
+-		b	29b
++
++#include "copy_template.S"
+ 
+diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/memmove.S
+@@ -0,0 +1,206 @@
++/*
++ *  linux/arch/arm/lib/memmove.S
++ *
++ *  Author:	Nicolas Pitre
++ *  Created:	Sep 28, 2005
++ *  Copyright:	(C) MontaVista Software Inc.
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2 as
++ *  published by the Free Software Foundation.
++ */
++
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++
++/*
++ * This can be used to enable code to cacheline align the source pointer.
++ * Experiments on tested architectures (StrongARM and XScale) didn't show
++ * this a worthwhile thing to do.  That might be different in the future.
++ */
++//#define CALGN(code...)        code
++#define CALGN(code...)
++
++		.text
++
++/*
++ * Prototype: void *memmove(void *dest, const void *src, size_t n);
++ *
++ * Note:
++ *
++ * If the memory regions don't overlap, we simply branch to memcpy which is
++ * normally a bit faster. Otherwise the copy is done going downwards.  This
++ * is a transposition of the code from copy_template.S but with the copy
++ * occurring in the opposite direction.
++ */
++
++ENTRY(memmove)
++
++		subs	ip, r0, r1
++		cmphi	r2, ip
++		bls	memcpy
++
++		stmfd	sp!, {r0, r4, lr}
++		add	r1, r1, r2
++		add	r0, r0, r2
++		subs	r2, r2, #4
++		blt	8f
++		ands	ip, r0, #3
++	PLD(	pld	[r1, #-4]		)
++		bne	9f
++		ands	ip, r1, #3
++		bne	10f
++
++1:		subs	r2, r2, #(28)
++		stmfd	sp!, {r5 - r8}
++		blt	5f
++
++	CALGN(	ands	ip, r1, #31		)
++	CALGN(	sbcnes	r4, ip, r2		)  @ C is always set here
++	CALGN(	bcs	2f			)
++	CALGN(	adr	r4, 6f			)
++	CALGN(	subs	r2, r2, ip		)  @ C is set here
++	CALGN(	add	pc, r4, ip		)
++
++	PLD(	pld	[r1, #-4]		)
++2:	PLD(	subs	r2, r2, #96		)
++	PLD(	pld	[r1, #-32]		)
++	PLD(	blt	4f			)
++	PLD(	pld	[r1, #-64]		)
++	PLD(	pld	[r1, #-96]		)
++
++3:	PLD(	pld	[r1, #-128]		)
++4:		ldmdb	r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
++		subs	r2, r2, #32
++		stmdb	r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
++		bge	3b
++	PLD(	cmn	r2, #96			)
++	PLD(	bge	4b			)
++
++5:		ands	ip, r2, #28
++		rsb	ip, ip, #32
++		addne	pc, pc, ip		@ C is always clear here
++		b	7f
++6:		nop
++		ldr	r3, [r1, #-4]!
++		ldr	r4, [r1, #-4]!
++		ldr	r5, [r1, #-4]!
++		ldr	r6, [r1, #-4]!
++		ldr	r7, [r1, #-4]!
++		ldr	r8, [r1, #-4]!
++		ldr	lr, [r1, #-4]!
++
++		add	pc, pc, ip
++		nop
++		nop
++		str	r3, [r0, #-4]!
++		str	r4, [r0, #-4]!
++		str	r5, [r0, #-4]!
++		str	r6, [r0, #-4]!
++		str	r7, [r0, #-4]!
++		str	r8, [r0, #-4]!
++		str	lr, [r0, #-4]!
++
++	CALGN(	bcs	2b			)
++
++7:		ldmfd	sp!, {r5 - r8}
++
++8:		movs	r2, r2, lsl #31
++		ldrneb	r3, [r1, #-1]!
++		ldrcsb	r4, [r1, #-1]!
++		ldrcsb	ip, [r1, #-1]
++		strneb	r3, [r0, #-1]!
++		strcsb	r4, [r0, #-1]!
++		strcsb	ip, [r0, #-1]
++		ldmfd	sp!, {r0, r4, pc}
++
++9:		cmp	ip, #2
++		ldrgtb	r3, [r1, #-1]!
++		ldrgeb	r4, [r1, #-1]!
++		ldrb	lr, [r1, #-1]!
++		strgtb	r3, [r0, #-1]!
++		strgeb	r4, [r0, #-1]!
++		subs	r2, r2, ip
++		strb	lr, [r0, #-1]!
++		blt	8b
++		ands	ip, r1, #3
++		beq	1b
++
++10:		bic	r1, r1, #3
++		cmp	ip, #2
++		ldr	r3, [r1, #0]
++		beq	17f
++		blt	18f
++
++
++		.macro	backward_copy_shift push pull
++
++		subs	r2, r2, #28
++		blt	14f
++
++	CALGN(	ands	ip, r1, #31		)
++	CALGN(	rsb	ip, ip, #32		)
++	CALGN(	sbcnes	r4, ip, r2		)  @ C is always set here
++	CALGN(	subcc	r2, r2, ip		)
++	CALGN(	bcc	15f			)
++
++11:		stmfd	sp!, {r5 - r9}
++
++	PLD(	pld	[r1, #-4]		)
++	PLD(	subs	r2, r2, #96		)
++	PLD(	pld	[r1, #-32]		)
++	PLD(	blt	13f			)
++	PLD(	pld	[r1, #-64]		)
++	PLD(	pld	[r1, #-96]		)
++
++12:	PLD(	pld	[r1, #-128]		)
++13:		ldmdb   r1!, {r7, r8, r9, ip}
++		mov     lr, r3, push #\push
++		subs    r2, r2, #32
++		ldmdb   r1!, {r3, r4, r5, r6}
++		orr     lr, lr, ip, pull #\pull
++		mov     ip, ip, push #\push
++		orr     ip, ip, r9, pull #\pull
++		mov     r9, r9, push #\push
++		orr     r9, r9, r8, pull #\pull
++		mov     r8, r8, push #\push
++		orr     r8, r8, r7, pull #\pull
++		mov     r7, r7, push #\push
++		orr     r7, r7, r6, pull #\pull
++		mov     r6, r6, push #\push
++		orr     r6, r6, r5, pull #\pull
++		mov     r5, r5, push #\push
++		orr     r5, r5, r4, pull #\pull
++		mov     r4, r4, push #\push
++		orr     r4, r4, r3, pull #\pull
++		stmdb   r0!, {r4 - r9, ip, lr}
++		bge	12b
++	PLD(	cmn	r2, #96			)
++	PLD(	bge	13b			)
++
++		ldmfd	sp!, {r5 - r9}
++
++14:		ands	ip, r2, #28
++		beq	16f
++
++15:		mov     lr, r3, push #\push
++		ldr	r3, [r1, #-4]!
++		subs	ip, ip, #4
++		orr	lr, lr, r3, pull #\pull
++		str	lr, [r0, #-4]!
++		bgt	15b
++	CALGN(	cmp	r2, #0			)
++	CALGN(	bge	11b			)
++
++16:		add	r1, r1, #(\pull / 8)
++		b	8b
++
++		.endm
++
++
++		backward_copy_shift	push=8	pull=24
++
++17:		backward_copy_shift	push=16	pull=16
++
++18:		backward_copy_shift	push=24	pull=8
++
+diff --git a/arch/arm/lib/muldi3.S b/arch/arm/lib/muldi3.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/muldi3.S
+@@ -0,0 +1,44 @@
++/*
++ *  linux/arch/arm/lib/muldi3.S
++ *
++ *  Author:     Nicolas Pitre
++ *  Created:    Oct 19, 2005
++ *  Copyright:  Monta Vista 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>
++
++#ifdef __ARMEB__
++#define xh r0
++#define xl r1
++#define yh r2
++#define yl r3
++#else
++#define xl r0
++#define xh r1
++#define yl r2
++#define yh r3
++#endif
++
++ENTRY(__muldi3)
++
++	mul	xh, yl, xh
++	mla	xh, xl, yh, xh
++	mov	ip, xl, asr #16
++	mov	yh, yl, asr #16
++	bic	xl, xl, ip, lsl #16
++	bic	yl, yl, yh, lsl #16
++	mla	xh, yh, ip, xh
++	mul	yh, xl, yh
++	mul	xl, yl, xl
++	mul	ip, yl, ip
++	adds	xl, xl, yh, lsl #16
++	adc	xh, xh, yh, lsr #16
++	adds	xl, xl, ip, lsl #16
++	adc	xh, xh, ip, lsr #16
++	mov	pc, lr
++
+diff --git a/arch/arm/lib/muldi3.c b/arch/arm/lib/muldi3.c
+deleted file mode 100644
+--- a/arch/arm/lib/muldi3.c
++++ /dev/null
+@@ -1,72 +0,0 @@
+-/* More subroutines needed by GCC output code on some machines.  */
+-/* Compile this one with gcc.  */
+-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+-
+-This file is part of GNU CC.
+-
+-GNU CC is free software; you can redistribute 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.
+-
+-GNU CC is distributed in the hope that it will be useful,
+-but WITHOUT ANY WARRANTY; without even the implied warranty of
+-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-GNU General Public License for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with GNU CC; see the file COPYING.  If not, write to
+-the Free Software Foundation, 59 Temple Place - Suite 330,
+-Boston, MA 02111-1307, USA.  */
+-
+-/* As a special exception, if you link this library with other files,
+-   some of which are compiled with GCC, to produce an executable,
+-   this library does not by itself cause the resulting executable
+-   to be covered by the GNU General Public License.
+-   This exception does not however invalidate any other reasons why
+-   the executable file might be covered by the GNU General Public License.
+- */
+-/* support functions required by the kernel. based on code from gcc-2.95.3 */
+-/* I Molton     29/07/01 */
+-
+-#include "gcclib.h"
+-
+-#define umul_ppmm(xh, xl, a, b) \
+-{register u32 __t0, __t1, __t2;                                     \
+-  __asm__ ("%@ Inlined umul_ppmm					\n\
+-        mov     %2, %5, lsr #16						\n\
+-        mov     %0, %6, lsr #16						\n\
+-        bic     %3, %5, %2, lsl #16					\n\
+-        bic     %4, %6, %0, lsl #16					\n\
+-        mul     %1, %3, %4						\n\
+-        mul     %4, %2, %4						\n\
+-        mul     %3, %0, %3						\n\
+-        mul     %0, %2, %0						\n\
+-        adds    %3, %4, %3						\n\
+-        addcs   %0, %0, #65536						\n\
+-        adds    %1, %1, %3, lsl #16					\n\
+-        adc     %0, %0, %3, lsr #16"                                    \
+-           : "=&r" ((u32) (xh)),                                    \
+-             "=r" ((u32) (xl)),                                     \
+-             "=&r" (__t0), "=&r" (__t1), "=r" (__t2)                    \
+-           : "r" ((u32) (a)),                                       \
+-             "r" ((u32) (b)));}
+-
+-#define __umulsidi3(u, v) \
+-  ({DIunion __w;                                                        \
+-    umul_ppmm (__w.s.high, __w.s.low, u, v);                            \
+-    __w.ll; })
+-
+-s64 __muldi3(s64 u, s64 v)
+-{
+-	DIunion w;
+-	DIunion uu, vv;
+-
+-	uu.ll = u, vv.ll = v;
+-
+-	w.ll = __umulsidi3(uu.s.low, vv.s.low);
+-	w.s.high += ((u32) uu.s.low * (u32) vv.s.high
+-		     + (u32) uu.s.high * (u32) vv.s.low);
+-
+-	return w.ll;
+-}
+diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/sha1.S
+@@ -0,0 +1,206 @@
++/*
++ *  linux/arch/arm/lib/sha1.S
++ *
++ *  SHA transform optimized for ARM
++ *
++ *  Copyright:	(C) 2005 by Nicolas Pitre <nico at cam.org>
++ *  Created:	September 17, 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.
++ *
++ *  The reference implementation for this code is linux/lib/sha1.c
++ */
++
++#include <linux/linkage.h>
++
++	.text
++
++
++/*
++ * void sha_transform(__u32 *digest, const char *in, __u32 *W)
++ *
++ * Note: the "in" ptr may be unaligned.
++ */
++
++ENTRY(sha_transform)
++
++	stmfd	sp!, {r4 - r8, lr}
++
++	@ for (i = 0; i < 16; i++)
++	@         W[i] = be32_to_cpu(in[i]); */
++
++#ifdef __ARMEB__
++	mov	r4, r0
++	mov	r0, r2
++	mov	r2, #64
++	bl	memcpy
++	mov	r2, r0
++	mov	r0, r4
++#else
++	mov	r3, r2
++	mov	lr, #16
++1:	ldrb	r4, [r1], #1
++	ldrb	r5, [r1], #1
++	ldrb	r6, [r1], #1
++	ldrb	r7, [r1], #1
++	subs	lr, lr, #1
++	orr	r5, r5, r4, lsl #8
++	orr	r6, r6, r5, lsl #8
++	orr	r7, r7, r6, lsl #8
++	str	r7, [r3], #4
++	bne	1b
++#endif
++
++	@ for (i = 0; i < 64; i++)
++	@         W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
++
++	sub	r3, r2, #4
++	mov	lr, #64
++2:	ldr	r4, [r3, #4]!
++	subs	lr, lr, #1
++	ldr	r5, [r3, #8]
++	ldr	r6, [r3, #32]
++	ldr	r7, [r3, #52]
++	eor	r4, r4, r5
++	eor	r4, r4, r6
++	eor	r4, r4, r7
++	mov	r4, r4, ror #31
++	str	r4, [r3, #64]
++	bne	2b
++
++	/*
++	 * The SHA functions are:
++	 *
++	 * f1(B,C,D) = (D ^ (B & (C ^ D)))
++	 * f2(B,C,D) = (B ^ C ^ D)
++	 * f3(B,C,D) = ((B & C) | (D & (B | C)))
++	 *
++	 * Then the sub-blocks are processed as follows:
++	 *
++	 * A' = ror(A, 27) + f(B,C,D) + E + K + *W++
++	 * B' = A
++	 * C' = ror(B, 2)
++	 * D' = C
++	 * E' = D
++	 *
++	 * We therefore unroll each loop 5 times to avoid register shuffling.
++	 * Also the ror for C (and also D and E which are successivelyderived
++	 * from it) is applied in place to cut on an additional mov insn for
++	 * each round.
++	 */
++
++	.macro	sha_f1, A, B, C, D, E
++	ldr	r3, [r2], #4
++	eor	ip, \C, \D
++	add	\E, r1, \E, ror #2
++	and	ip, \B, ip, ror #2
++	add	\E, \E, \A, ror #27
++	eor	ip, ip, \D, ror #2
++	add	\E, \E, r3
++	add	\E, \E, ip
++	.endm
++
++	.macro	sha_f2, A, B, C, D, E
++	ldr	r3, [r2], #4
++	add	\E, r1, \E, ror #2
++	eor	ip, \B, \C, ror #2
++	add	\E, \E, \A, ror #27
++	eor	ip, ip, \D, ror #2
++	add	\E, \E, r3
++	add	\E, \E, ip
++	.endm
++
++	.macro	sha_f3, A, B, C, D, E
++	ldr	r3, [r2], #4
++	add	\E, r1, \E, ror #2
++	orr	ip, \B, \C, ror #2
++	add	\E, \E, \A, ror #27
++	and	ip, ip, \D, ror #2
++	add	\E, \E, r3
++	and	r3, \B, \C, ror #2
++	orr	ip, ip, r3
++	add	\E, \E, ip
++	.endm
++
++	ldmia	r0, {r4 - r8}
++
++	mov	lr, #4
++	ldr	r1, .L_sha_K + 0
++
++	/* adjust initial values */
++	mov	r6, r6, ror #30
++	mov	r7, r7, ror #30
++	mov	r8, r8, ror #30
++
++3:	subs	lr, lr, #1
++	sha_f1	r4, r5, r6, r7, r8
++	sha_f1	r8, r4, r5, r6, r7
++	sha_f1	r7, r8, r4, r5, r6
++	sha_f1	r6, r7, r8, r4, r5
++	sha_f1	r5, r6, r7, r8, r4
++	bne	3b
++
++	ldr	r1, .L_sha_K + 4
++	mov	lr, #4
++
++4:	subs	lr, lr, #1
++	sha_f2	r4, r5, r6, r7, r8
++	sha_f2	r8, r4, r5, r6, r7
++	sha_f2	r7, r8, r4, r5, r6
++	sha_f2	r6, r7, r8, r4, r5
++	sha_f2	r5, r6, r7, r8, r4
++	bne	4b
++
++	ldr	r1, .L_sha_K + 8
++	mov	lr, #4
++
++5:	subs	lr, lr, #1
++	sha_f3	r4, r5, r6, r7, r8
++	sha_f3	r8, r4, r5, r6, r7
++	sha_f3	r7, r8, r4, r5, r6
++	sha_f3	r6, r7, r8, r4, r5
++	sha_f3	r5, r6, r7, r8, r4
++	bne	5b
++
++	ldr	r1, .L_sha_K + 12
++	mov	lr, #4
++
++6:	subs	lr, lr, #1
++	sha_f2	r4, r5, r6, r7, r8
++	sha_f2	r8, r4, r5, r6, r7
++	sha_f2	r7, r8, r4, r5, r6
++	sha_f2	r6, r7, r8, r4, r5
++	sha_f2	r5, r6, r7, r8, r4
++	bne	6b
++
++	ldmia	r0, {r1, r2, r3, ip, lr}
++	add	r4, r1, r4
++	add	r5, r2, r5
++	add	r6, r3, r6, ror #2
++	add	r7, ip, r7, ror #2
++	add	r8, lr, r8, ror #2
++	stmia	r0, {r4 - r8}
++
++	ldmfd	sp!, {r4 - r8, pc}
++
++.L_sha_K:
++	.word	0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
++
++
++/*
++ * void sha_init(__u32 *buf)
++ */
++
++.L_sha_initial_digest:
++	.word	0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
++
++ENTRY(sha_init)
++
++	str	lr, [sp, #-4]!
++	adr	r1, .L_sha_initial_digest
++	ldmia	r1, {r1, r2, r3, ip, lr}
++	stmia	r0, {r1, r2, r3, ip, lr}
++	ldr	pc, [sp], #4
++
+diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
+--- a/arch/arm/lib/uaccess.S
++++ b/arch/arm/lib/uaccess.S
+@@ -657,41 +657,3 @@ USER(		ldrgtbt	r3, [r1], #1)			@ May fau
+ 		LOADREGS(fd,sp!, {r4 - r7, pc})
+ 		.previous
+ 
+-/* Prototype: int __arch_clear_user(void *addr, size_t sz)
+- * Purpose  : clear some user memory
+- * Params   : addr - user memory address to clear
+- *          : sz   - number of bytes to clear
+- * Returns  : number of bytes NOT cleared
+- */
+-ENTRY(__arch_clear_user)
+-		stmfd	sp!, {r1, lr}
+-		mov	r2, #0
+-		cmp	r1, #4
+-		blt	2f
+-		ands	ip, r0, #3
+-		beq	1f
+-		cmp	ip, #2
+-USER(		strbt	r2, [r0], #1)
+-USER(		strlebt	r2, [r0], #1)
+-USER(		strltbt	r2, [r0], #1)
+-		rsb	ip, ip, #4
+-		sub	r1, r1, ip		@  7  6  5  4  3  2  1
+-1:		subs	r1, r1, #8		@ -1 -2 -3 -4 -5 -6 -7
+-USER(		strplt	r2, [r0], #4)
+-USER(		strplt	r2, [r0], #4)
+-		bpl	1b
+-		adds	r1, r1, #4		@  3  2  1  0 -1 -2 -3
+-USER(		strplt	r2, [r0], #4)
+-2:		tst	r1, #2			@ 1x 1x 0x 0x 1x 1x 0x
+-USER(		strnebt	r2, [r0], #1)
+-USER(		strnebt	r2, [r0], #1)
+-		tst	r1, #1			@ x1 x0 x1 x0 x1 x0 x1
+-USER(		strnebt	r2, [r0], #1)
+-		mov	r0, #0
+-		LOADREGS(fd,sp!, {r1, pc})
+-
+-		.section .fixup,"ax"
+-		.align	0
+-9001:		LOADREGS(fd,sp!, {r0, pc})
+-		.previous
+-
+diff --git a/arch/arm/lib/ucmpdi2.S b/arch/arm/lib/ucmpdi2.S
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/lib/ucmpdi2.S
+@@ -0,0 +1,35 @@
++/*
++ *  linux/arch/arm/lib/ucmpdi2.S
++ *
++ *  Author:	Nicolas Pitre
++ *  Created:	Oct 19, 2005
++ *  Copyright:	Monta Vista 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>
++
++#ifdef __ARMEB__
++#define xh r0
++#define xl r1
++#define yh r2
++#define yl r3
++#else
++#define xl r0
++#define xh r1
++#define yl r2
++#define yh r3
++#endif
++
++ENTRY(__ucmpdi2)
++
++	cmp	xh, yh
++	cmpeq	xl, yl
++	movlo	r0, #0
++	moveq	r0, #1
++	movhi	r0, #2
++	mov	pc, lr
++
+diff --git a/arch/arm/lib/ucmpdi2.c b/arch/arm/lib/ucmpdi2.c
+deleted file mode 100644
+--- a/arch/arm/lib/ucmpdi2.c
++++ /dev/null
+@@ -1,49 +0,0 @@
+-/* More subroutines needed by GCC output code on some machines.  */
+-/* Compile this one with gcc.  */
+-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+-
+-This file is part of GNU CC.
+-
+-GNU CC is free software; you can redistribute 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.
+-
+-GNU CC is distributed in the hope that it will be useful,
+-but WITHOUT ANY WARRANTY; without even the implied warranty of
+-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-GNU General Public License for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with GNU CC; see the file COPYING.  If not, write to
+-the Free Software Foundation, 59 Temple Place - Suite 330,
+-Boston, MA 02111-1307, USA.  */
+-
+-/* As a special exception, if you link this library with other files,
+-   some of which are compiled with GCC, to produce an executable,
+-   this library does not by itself cause the resulting executable
+-   to be covered by the GNU General Public License.
+-   This exception does not however invalidate any other reasons why
+-   the executable file might be covered by the GNU General Public License.
+- */
+-/* support functions required by the kernel. based on code from gcc-2.95.3 */
+-/* I Molton     29/07/01 */
+-
+-#include "gcclib.h"
+-
+-int __ucmpdi2(s64 a, s64 b)
+-{
+-	DIunion au, bu;
+-
+-	au.ll = a, bu.ll = b;
+-
+-	if ((u32) au.s.high < (u32) bu.s.high)
+-		return 0;
+-	else if ((u32) au.s.high > (u32) bu.s.high)
+-		return 2;
+-	if ((u32) au.s.low < (u32) bu.s.low)
+-		return 0;
+-	else if ((u32) au.s.low > (u32) bu.s.low)
+-		return 2;
+-	return 1;
+-}
+diff --git a/arch/arm/mach-aaec2000/Makefile b/arch/arm/mach-aaec2000/Makefile
+--- a/arch/arm/mach-aaec2000/Makefile
++++ b/arch/arm/mach-aaec2000/Makefile
+@@ -3,7 +3,7 @@
+ #
+ 
+ # Common support (must be linked before board specific support)
+-obj-y += core.o
++obj-y += core.o clock.o
+ 
+ # Specific board support
+ obj-$(CONFIG_MACH_AAED2000) += aaed2000.o
+diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
+--- a/arch/arm/mach-aaec2000/aaed2000.c
++++ b/arch/arm/mach-aaec2000/aaed2000.c
+@@ -27,16 +27,65 @@
+ #include <asm/mach/map.h>
+ #include <asm/mach/irq.h>
+ 
++#include <asm/arch/aaed2000.h>
++
+ #include "core.h"
+ 
++static void aaed2000_clcd_disable(struct clcd_fb *fb)
++{
++	AAED_EXT_GPIO &= ~AAED_EGPIO_LCD_PWR_EN;
++}
++
++static void aaed2000_clcd_enable(struct clcd_fb *fb)
++{
++	AAED_EXT_GPIO |= AAED_EGPIO_LCD_PWR_EN;
++}
++
++struct aaec2000_clcd_info clcd_info = {
++	.enable = aaed2000_clcd_enable,
++	.disable = aaed2000_clcd_disable,
++	.panel = {
++		.mode	= {
++			.name		= "Sharp",
++			.refresh	= 60,
++			.xres		= 640,
++			.yres		= 480,
++			.pixclock	= 39721,
++			.left_margin	= 20,
++			.right_margin	= 44,
++			.upper_margin	= 21,
++			.lower_margin	= 34,
++			.hsync_len	= 96,
++			.vsync_len	= 2,
++			.sync		= 0,
++			.vmode	= FB_VMODE_NONINTERLACED,
++		},
++		.width	= -1,
++		.height	= -1,
++		.tim2	= TIM2_IVS | TIM2_IHS,
++		.cntl	= CNTL_LCDTFT,
++		.bpp	= 16,
++	},
++};
++
+ static void __init aaed2000_init_irq(void)
+ {
+ 	aaec2000_init_irq();
+ }
+ 
++static void __init aaed2000_init(void)
++{
++	aaec2000_set_clcd_plat_data(&clcd_info);
++}
++
++static struct map_desc aaed2000_io_desc[] __initdata = {
++  { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */
++};
++
+ static void __init aaed2000_map_io(void)
+ {
+ 	aaec2000_map_io();
++	iotable_init(aaed2000_io_desc, ARRAY_SIZE(aaed2000_io_desc));
+ }
+ 
+ MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
+@@ -47,4 +96,5 @@ MACHINE_START(AAED2000, "Agilent AAED-20
+ 	.map_io		= aaed2000_map_io,
+ 	.init_irq	= aaed2000_init_irq,
+ 	.timer		= &aaec2000_timer,
++	.init_machine	= aaed2000_init,
+ MACHINE_END
+diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-aaec2000/clock.c
+@@ -0,0 +1,110 @@
++/*
++ *  linux/arch/arm/mach-aaec2000/clock.c
++ *
++ *  Copyright (C) 2005 Nicolas Bellido Y Ortega
++ *
++ *  Based on linux/arch/arm/mach-integrator/clock.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/module.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/errno.h>
++#include <linux/err.h>
++
++#include <asm/semaphore.h>
++#include <asm/hardware/clock.h>
++
++#include "clock.h"
++
++static LIST_HEAD(clocks);
++static DECLARE_MUTEX(clocks_sem);
++
++struct clk *clk_get(struct device *dev, const char *id)
++{
++	struct clk *p, *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)
++{
++	return 0;
++}
++EXPORT_SYMBOL(clk_set_rate);
++
++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)
++{
++	return 0;
++}
++arch_initcall(clk_init);
+diff --git a/arch/arm/mach-aaec2000/clock.h b/arch/arm/mach-aaec2000/clock.h
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-aaec2000/clock.h
+@@ -0,0 +1,23 @@
++/*
++ *  linux/arch/arm/mach-aaec2000/clock.h
++ *
++ *  Copyright (C) 2005 Nicolas Bellido Y Ortega
++ *
++ *  Based on linux/arch/arm/mach-integrator/clock.h
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++struct module;
++
++struct clk {
++	struct list_head	node;
++	unsigned long		rate;
++	struct module		*owner;
++	const char		*name;
++	void			*data;
++};
++
++int clk_register(struct clk *clk);
++void clk_unregister(struct clk *clk);
+diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
+--- a/arch/arm/mach-aaec2000/core.c
++++ b/arch/arm/mach-aaec2000/core.c
+@@ -13,19 +13,27 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/platform_device.h>
+ #include <linux/list.h>
+ #include <linux/errno.h>
++#include <linux/dma-mapping.h>
+ #include <linux/interrupt.h>
+ #include <linux/timex.h>
+ #include <linux/signal.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
++#include <asm/sizes.h>
++#include <asm/hardware/amba.h>
+ 
++#include <asm/mach/flash.h>
+ #include <asm/mach/irq.h>
+ #include <asm/mach/time.h>
+ #include <asm/mach/map.h>
+ 
++#include "core.h"
++#include "clock.h"
++
+ /*
+  * Common I/O mapping:
+  *
+@@ -40,9 +48,17 @@
+  * default mapping provided here.
+  */
+ static struct map_desc standard_io_desc[] __initdata = {
+- /* virtual         physical       length           type */
+-  { VIO_APB_BASE,   PIO_APB_BASE,  IO_APB_LENGTH,   MT_DEVICE },
+-  { VIO_AHB_BASE,   PIO_AHB_BASE,  IO_AHB_LENGTH,   MT_DEVICE }
++	{
++		.virtual	= VIO_APB_BASE,
++		.physical	= __phys_to_pfn(PIO_APB_BASE),
++		.length		= IO_APB_LENGTH,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= VIO_AHB_BASE,
++		.physical	= __phys_to_pfn(PIO_AHB_BASE),
++		.length		= IO_AHB_LENGTH,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init aaec2000_map_io(void)
+@@ -155,3 +171,116 @@ struct sys_timer aaec2000_timer = {
+ 	.offset		= aaec2000_gettimeoffset,
+ };
+ 
++static struct clcd_panel mach_clcd_panel;
++
++static int aaec2000_clcd_setup(struct clcd_fb *fb)
++{
++	dma_addr_t dma;
++
++	fb->panel = &mach_clcd_panel;
++
++	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, SZ_1M,
++			&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 = SZ_1M;
++
++	return 0;
++}
++
++static int aaec2000_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 aaec2000_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_plat_data = {
++	.name	= "AAEC-2000",
++	.check	= clcdfb_check,
++	.decode	= clcdfb_decode,
++	.setup	= aaec2000_clcd_setup,
++	.mmap	= aaec2000_clcd_mmap,
++	.remove	= aaec2000_clcd_remove,
++};
++
++static struct amba_device clcd_device = {
++	.dev		= {
++		.bus_id			= "mb:16",
++		.coherent_dma_mask	= ~0,
++		.platform_data		= &clcd_plat_data,
++	},
++	.res		= {
++		.start			= AAEC_CLCD_PHYS,
++		.end			= AAEC_CLCD_PHYS + SZ_4K - 1,
++		.flags			= IORESOURCE_MEM,
++	},
++	.irq		= { INT_LCD, NO_IRQ },
++	.periphid	= 0x41110,
++};
++
++static struct amba_device *amba_devs[] __initdata = {
++	&clcd_device,
++};
++
++static struct clk aaec2000_clcd_clk = {
++	.name = "CLCDCLK",
++};
++
++void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *clcd)
++{
++	clcd_plat_data.enable = clcd->enable;
++	clcd_plat_data.disable = clcd->disable;
++	memcpy(&mach_clcd_panel, &clcd->panel, sizeof(struct clcd_panel));
++}
++
++static struct flash_platform_data aaec2000_flash_data = {
++	.map_name	= "cfi_probe",
++	.width		= 4,
++};
++
++static struct resource aaec2000_flash_resource = {
++	.start		= AAEC_FLASH_BASE,
++	.end		= AAEC_FLASH_BASE + AAEC_FLASH_SIZE,
++	.flags		= IORESOURCE_MEM,
++};
++
++static struct platform_device aaec2000_flash_device = {
++	.name		= "armflash",
++	.id		= 0,
++	.dev		= {
++		.platform_data	= &aaec2000_flash_data,
++	},
++	.num_resources	= 1,
++	.resource	= &aaec2000_flash_resource,
++};
++
++static int __init aaec2000_init(void)
++{
++	int i;
++
++	clk_register(&aaec2000_clcd_clk);
++
++	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
++		struct amba_device *d = amba_devs[i];
++		amba_device_register(d, &iomem_resource);
++	}
++
++	platform_device_register(&aaec2000_flash_device);
++
++	return 0;
++};
++arch_initcall(aaec2000_init);
++
+diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h
+--- a/arch/arm/mach-aaec2000/core.h
++++ b/arch/arm/mach-aaec2000/core.h
+@@ -9,8 +9,19 @@
+  *
+  */
+ 
++#include <asm/hardware/amba_clcd.h>
++
+ struct sys_timer;
+ 
+ extern struct sys_timer aaec2000_timer;
+ extern void __init aaec2000_map_io(void);
+ extern void __init aaec2000_init_irq(void);
++
++struct aaec2000_clcd_info {
++	struct clcd_panel panel;
++	void (*disable)(struct clcd_fb *);
++	void (*enable)(struct clcd_fb *);
++};
++
++extern void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *);
++
+diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
+--- a/arch/arm/mach-clps711x/Kconfig
++++ b/arch/arm/mach-clps711x/Kconfig
+@@ -69,6 +69,17 @@ config EP72XX_ROM_BOOT
+ 
+ 	  You almost surely want to say N here.
+ 
++config MACH_MP1000
++	bool "MACH_MP1000"
++	help
++	  Say Y if you intend to run the kernel on the Comdial MP1000 platform.
++
++config MP1000_90MHZ
++	bool "MP1000_90MHZ"
++	depends on MACH_MP1000
++	help
++	  Say Y if you have the MP1000 configured to be set at 90MHZ rather than 74MHZ
++
+ endmenu
+ 
+ endif
+diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile
+--- a/arch/arm/mach-clps711x/Makefile
++++ b/arch/arm/mach-clps711x/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_CDB89712) += cdb89712.
+ obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
+ obj-$(CONFIG_ARCH_EDB7211)  += edb7211-arch.o edb7211-mm.o
+ obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
++obj-$(CONFIG_MACH_MP1000)   += mp1000-mach.o mp1000-mm.o mp1000-seprom.o
+ obj-$(CONFIG_ARCH_P720T)    += p720t.o
+ leds-$(CONFIG_ARCH_P720T)   += p720t-leds.o
+ obj-$(CONFIG_LEDS)          += $(leds-y)
+diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
+--- a/arch/arm/mach-clps711x/autcpu12.c
++++ b/arch/arm/mach-clps711x/autcpu12.c
+@@ -46,10 +46,14 @@
+ */
+ 
+ static struct map_desc autcpu12_io_desc[] __initdata = {
+- /* virtual, physical, length, type */
+- /* memory-mapped extra io and CS8900A Ethernet chip */
+- /* ethernet chip */
+- 	{ AUTCPU12_VIRT_CS8900A, AUTCPU12_PHYS_CS8900A, SZ_1M, MT_DEVICE }
++	/* memory-mapped extra io and CS8900A Ethernet chip */
++ 	/* ethernet chip */
++ 	{
++		.virtual	= AUTCPU12_VIRT_CS8900A,
++		.pfn		= __phys_to_pfn(AUTCPU12_PHYS_CS8900A),
++		.length		= SZ_1M,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init autcpu12_map_io(void)
+diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
+--- a/arch/arm/mach-clps711x/cdb89712.c
++++ b/arch/arm/mach-clps711x/cdb89712.c
+@@ -39,7 +39,12 @@
+  * ethernet driver, perhaps.
+  */
+ static struct map_desc cdb89712_io_desc[] __initdata = {
+-	{ ETHER_BASE, ETHER_START, ETHER_SIZE, MT_DEVICE }
++	{
++		.virtual	= ETHER_BASE,
++		.pfn		=__phys_to_pfn(ETHER_START),
++		.length		= ETHER_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init cdb89712_map_io(void)
+diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c
+--- a/arch/arm/mach-clps711x/ceiva.c
++++ b/arch/arm/mach-clps711x/ceiva.c
+@@ -37,11 +37,13 @@
+ #include "common.h"
+ 
+ static struct map_desc ceiva_io_desc[] __initdata = {
+- /* virtual, physical, length, type */
+-
+- /* SED1355 controlled video RAM & registers */
+- { CEIVA_VIRT_SED1355, CEIVA_PHYS_SED1355, SZ_2M, MT_DEVICE }
+-
++ 	/* SED1355 controlled video RAM & registers */
++ 	{
++		.virtual	= CEIVA_VIRT_SED1355,
++		.pfn		= __phys_to_pfn(CEIVA_PHYS_SED1355),
++		.length		= SZ_2M,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ 
+diff --git a/arch/arm/mach-clps711x/edb7211-mm.c b/arch/arm/mach-clps711x/edb7211-mm.c
+--- a/arch/arm/mach-clps711x/edb7211-mm.c
++++ b/arch/arm/mach-clps711x/edb7211-mm.c
+@@ -51,15 +51,27 @@ extern void clps711x_map_io(void);
+  *     happens).
+  */
+ static struct map_desc edb7211_io_desc[] __initdata = {
+- /* virtual, physical, length, type */
+-
+- /* memory-mapped extra keyboard row and CS8900A Ethernet chip */
+- { EP7211_VIRT_EXTKBD,  EP7211_PHYS_EXTKBD,  SZ_1M, MT_DEVICE }, 
+- { EP7211_VIRT_CS8900A, EP7211_PHYS_CS8900A, SZ_1M, MT_DEVICE },
+-
+- /* flash banks */
+- { EP7211_VIRT_FLASH1,  EP7211_PHYS_FLASH1,  SZ_8M, MT_DEVICE },
+- { EP7211_VIRT_FLASH2,  EP7211_PHYS_FLASH2,  SZ_8M, MT_DEVICE }
++ 	{	/* memory-mapped extra keyboard row */
++	 	.virtual 	= EP7211_VIRT_EXTKBD,
++		.pfn		= __phys_to_pfn(EP7211_PHYS_EXTKBD),
++		.length		= SZ_1M,
++		.type		- MT_DEVICE
++	}, {	/* and CS8900A Ethernet chip */
++		.virtual	= EP7211_VIRT_CS8900A,
++		.pfn		= __phys_to_pfn(EP7211_PHYS_CS8900A),
++		.length		= SZ_1M,
++		.type		= MT_DEVICE
++	}, { 	/* flash banks */
++		.virtual	= EP7211_VIRT_FLASH1,
++		.pfn		= __phys_to_pfn(EP7211_PHYS_FLASH1),
++		.length		= SZ_8M,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= EP7211_VIRT_FLASH2,
++		.pfn		= __phys_to_pfn(EP7211_PHYS_FLASH2),
++		.length		= SZ_8M,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init edb7211_map_io(void)
+diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
+--- a/arch/arm/mach-clps711x/mm.c
++++ b/arch/arm/mach-clps711x/mm.c
+@@ -24,6 +24,7 @@
+ #include <linux/init.h>
+ #include <linux/bootmem.h>
+ 
++#include <asm/sizes.h>
+ #include <asm/hardware.h>
+ #include <asm/pgtable.h>
+ #include <asm/page.h>
+@@ -34,7 +35,12 @@
+  * This maps the generic CLPS711x registers
+  */
+ static struct map_desc clps711x_io_desc[] __initdata = {
+- { CLPS7111_VIRT_BASE,	CLPS7111_PHYS_BASE,	1048576, MT_DEVICE }
++	{
++		.virtual	= CLPS7111_VIRT_BASE,
++		.pfn		= __phys_to_pfn(CLPS7111_PHYS_BASE),
++		.length		= SZ_1M,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init clps711x_map_io(void)
+diff --git a/arch/arm/mach-clps711x/mp1000-mach.c b/arch/arm/mach-clps711x/mp1000-mach.c
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-clps711x/mp1000-mach.c
+@@ -0,0 +1,49 @@
++/*
++ *  linux/arch/arm/mach-mp1000/mp1000.c
++ *
++ *  Copyright (C) 2005 Comdial 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
++ */
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/string.h>
++
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/arch/mp1000-seprom.h>
++
++#include "common.h"
++
++extern void mp1000_map_io(void);
++
++static void __init mp1000_init(void)
++{
++    seprom_init();
++}
++
++MACHINE_START(MP1000, "Comdial MP1000")
++	/* Maintainer: Jon Ringle */
++	.phys_ram	= 0xc0000000,
++	.phys_io	= 0x80000000,
++	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
++	.boot_params	= 0xc0015100,
++	.map_io		= mp1000_map_io,
++	.init_irq	= clps711x_init_irq,
++	.init_machine	= mp1000_init,
++	.timer		= &clps711x_timer,
++MACHINE_END
++
+diff --git a/arch/arm/mach-clps711x/mp1000-mm.c b/arch/arm/mach-clps711x/mp1000-mm.c
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-clps711x/mp1000-mm.c
+@@ -0,0 +1,47 @@
++/*
++ *  linux/arch/arm/mach-mp1000/mm.c
++ *
++ *  Extra MM routines for the MP1000
++ *
++ *  Copyright (C) 2005 Comdial 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
++ */
++#include <linux/kernel.h>
++#include <linux/init.h>
++
++#include <asm/hardware.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/sizes.h>
++
++#include <asm/mach/map.h>
++
++extern void clps711x_map_io(void);
++
++static struct map_desc mp1000_io_desc[] __initdata = {
++    { MP1000_EIO_BASE,	MP1000_EIO_START,	MP1000_EIO_SIZE, MT_DEVICE },
++    { MP1000_FIO_BASE,	MP1000_FIO_START,	MP1000_FIO_SIZE, MT_DEVICE },
++    { MP1000_LIO_BASE,	MP1000_LIO_START,	MP1000_LIO_SIZE, MT_DEVICE },
++    { MP1000_NIO_BASE,	MP1000_NIO_START,	MP1000_NIO_SIZE, MT_DEVICE },
++    { MP1000_IDE_BASE,	MP1000_IDE_START,	MP1000_IDE_SIZE, MT_DEVICE },
++    { MP1000_DSP_BASE,	MP1000_DSP_START,	MP1000_DSP_SIZE, MT_DEVICE }
++};
++
++void __init mp1000_map_io(void)
++{
++	clps711x_map_io();
++	iotable_init(mp1000_io_desc, ARRAY_SIZE(mp1000_io_desc));
++}
+diff --git a/arch/arm/mach-clps711x/mp1000-seprom.c b/arch/arm/mach-clps711x/mp1000-seprom.c
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-clps711x/mp1000-seprom.c
+@@ -0,0 +1,195 @@
++/*`
++ * mp1000-seprom.c
++ *
++ *  This file contains the Serial EEPROM code for the MP1000 board
++ *
++ *  Copyright (C) 2005 Comdial 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
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <asm/hardware.h>
++#include <asm/hardware/clps7111.h>
++#include <asm/arch/mp1000-seprom.h>
++
++/* If SepromInit() can initialize and checksum the seprom successfully, */
++/* then it will point seprom_data_ptr at the shadow copy.  */
++
++static eeprom_struct seprom_data;			/* shadow copy of seprom content */
++
++eeprom_struct *seprom_data_ptr = 0;		/* 0 => not initialized */
++
++/*
++ * Port D Bit 5 is Chip Select for EEPROM
++ * Port E Bit 0 is Input, Data out from EEPROM
++ * Port E Bit 1 is Output, Data in to EEPROM
++ * Port E Bit 2 is Output, CLK to EEPROM
++ */
++
++static char *port_d_ptr = (char *)(CLPS7111_VIRT_BASE + PDDR);
++static char *port_e_ptr = (char *)(CLPS7111_VIRT_BASE + PEDR);
++
++#define NO_OF_SHORTS	64	// Device is 64 x 16 bits
++#define ENABLE_RW	0
++#define DISABLE_RW	1
++
++static inline void toggle_seprom_clock(void)
++{
++	*port_e_ptr |= HwPortESepromCLK;
++	*port_e_ptr &= ~(HwPortESepromCLK);
++}
++
++static inline void select_eeprom(void)
++{
++	*port_d_ptr |= HwPortDEECS;
++	*port_e_ptr &= ~(HwPortESepromCLK);
++}
++
++static inline void deselect_eeprom(void)
++{
++	*port_d_ptr &= ~(HwPortDEECS);
++	*port_e_ptr &= ~(HwPortESepromDIn);
++}
++
++/*
++ * GetSepromDataPtr - returns pointer to shadow (RAM) copy of seprom
++ *                    and returns 0 if seprom is not initialized or
++ *                    has a checksum error.
++ */
++
++eeprom_struct* get_seprom_ptr(void)
++{
++	return seprom_data_ptr;
++}
++
++unsigned char* get_eeprom_mac_address(void)
++{
++	return seprom_data_ptr->variant.eprom_struct.mac_Address;
++}
++
++/*
++ * ReadSProm, Physically reads data from the Serial PROM
++ */
++static void read_sprom(short address, int length, eeprom_struct *buffer)
++{
++	short data = COMMAND_READ | (address & 0x3F);
++	short bit;
++	int i;
++
++	select_eeprom();
++
++	// Clock in 9 bits of the command
++	for (i = 0, bit = 0x100; i < 9; i++, bit >>= 1) {
++		if (data & bit)
++			*port_e_ptr |= HwPortESepromDIn;
++		else
++			*port_e_ptr &= ~(HwPortESepromDIn);
++
++		toggle_seprom_clock();
++	}
++
++	//
++	// Now read one or more shorts of data from the Seprom
++	//
++	while (length-- > 0) {
++		data = 0;
++
++		// Read 16 bits at a time
++		for (i = 0; i < 16; i++) {
++			data <<= 1;
++			toggle_seprom_clock();
++			data |= *port_e_ptr & HwPortESepromDOut;
++
++		}
++
++		buffer->variant.eprom_short_data[address++] = data;
++	}
++
++	deselect_eeprom();
++
++	return;
++}
++
++
++
++/*
++ * ReadSerialPROM
++ *
++ * Input: Pointer to array of 64 x 16 Bits
++ *
++ * Output: if no problem reading data is filled in
++ */
++static void read_serial_prom(eeprom_struct *data)
++{
++	read_sprom(0, 64, data);
++}
++
++
++//
++// Compute Serial EEPROM checksum
++//
++// Input: Pointer to struct with Eprom data
++//
++// Output: The computed Eprom checksum
++//
++static short compute_seprom_checksum(eeprom_struct *data)
++{
++	short checksum = 0;
++	int i;
++
++	for (i = 0; i < 126; i++) {
++		checksum += (short)data->variant.eprom_byte_data[i];
++	}
++
++	return((short)(0x5555 - (checksum & 0xFFFF)));
++}
++
++//
++// Make sure the data port bits for the SEPROM are correctly initialised
++//
++
++void __init seprom_init(void)
++{
++	short checksum;
++
++	// Init Port D
++	*(char *)(CLPS7111_VIRT_BASE + PDDDR) = 0x0;
++	*(char *)(CLPS7111_VIRT_BASE + PDDR) = 0x15;
++
++	// Init Port E
++	*(int *)(CLPS7111_VIRT_BASE + PEDDR) = 0x06;
++	*(int *)(CLPS7111_VIRT_BASE + PEDR) = 0x04;
++
++	//
++	// Make sure that EEPROM struct size never exceeds 128 bytes
++	//
++	if (sizeof(eeprom_struct) > 128) {
++		panic("Serial PROM struct size > 128, aborting read\n");
++	}
++
++	read_serial_prom(&seprom_data);
++
++	checksum = compute_seprom_checksum(&seprom_data);
++
++	if (checksum != seprom_data.variant.eprom_short_data[63]) {
++		panic("Serial EEPROM checksum failed\n");
++	}
++
++	seprom_data_ptr = &seprom_data;
++}
++
+diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
+--- a/arch/arm/mach-clps711x/p720t.c
++++ b/arch/arm/mach-clps711x/p720t.c
+@@ -29,6 +29,7 @@
+ #include <asm/pgtable.h>
+ #include <asm/page.h>
+ #include <asm/setup.h>
++#include <asm/sizes.h>
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+@@ -42,8 +43,17 @@
+  * We map both here.
+  */
+ static struct map_desc p720t_io_desc[] __initdata = {
+-	{ SYSPLD_VIRT_BASE,	SYSPLD_PHYS_BASE, 1048576, MT_DEVICE },
+-	{ 0xfe400000,		0x10400000,	  1048576, MT_DEVICE }
++	{
++		.virtual	= SYSPLD_VIRT_BASE,
++		.pfn		= __phys_to_pfn(SYSPLD_PHYS_BASE),
++		.length		= SZ_1M,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= 0xfe400000,
++		.pfn		= __phys_to_pfn(0x10400000),
++		.length		= SZ_1M,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init
+diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
+--- a/arch/arm/mach-clps7500/core.c
++++ b/arch/arm/mach-clps7500/core.c
+@@ -259,10 +259,27 @@ static void __init clps7500_init_irq(voi
+ }
+ 
+ static struct map_desc cl7500_io_desc[] __initdata = {
+-	{ IO_BASE,	IO_START,	IO_SIZE,    MT_DEVICE },	/* IO space	*/
+-	{ ISA_BASE,	ISA_START,	ISA_SIZE,   MT_DEVICE },	/* ISA space	*/
+-	{ FLASH_BASE,	FLASH_START,	FLASH_SIZE, MT_DEVICE },	/* Flash	*/
+-	{ LED_BASE,	LED_START,	LED_SIZE,   MT_DEVICE } 	/* LED		*/
++	{ 	/* IO space	*/
++		.virtual	= IO_BASE,
++		.pfn		= __phys_to_pfn(IO_START),
++		.length		= IO_SIZE,
++		.type		= MT_DEVICE
++	}, {	/* ISA space	*/
++		.virtual	= ISA_BASE,
++		.pfn		= __phys_to_pfn(ISA_START),
++		.length		= ISA_SIZE,
++		.type		= MT_DEVICE
++	}, {	/* Flash	*/
++		.virtual	= FLASH_BASE,
++		.pfn		= __phys_to_pfn(FLASH_START),
++		.length		= FLASH_SIZE,
++		.type		= MT_DEVICE
++	}, {	/* LED		*/
++		.virtual	= LED_BASE,
++		.pfn		= __phys_to_pfn(LED_START),
++		.length		= LED_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init clps7500_map_io(void)
+diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
+--- a/arch/arm/mach-ebsa110/core.c
++++ b/arch/arm/mach-ebsa110/core.c
+@@ -76,16 +76,42 @@ static struct map_desc ebsa110_io_desc[]
+ 	/*
+ 	 * sparse external-decode ISAIO space
+ 	 */
+-	{ IRQ_STAT,    TRICK4_PHYS, PGDIR_SIZE,  MT_DEVICE }, /* IRQ_STAT/IRQ_MCLR */
+-	{ IRQ_MASK,    TRICK3_PHYS, PGDIR_SIZE,  MT_DEVICE }, /* IRQ_MASK/IRQ_MSET */
+-	{ SOFT_BASE,   TRICK1_PHYS, PGDIR_SIZE,  MT_DEVICE }, /* SOFT_BASE */
+-	{ PIT_BASE,    TRICK0_PHYS, PGDIR_SIZE,  MT_DEVICE }, /* PIT_BASE */
++	{	/* IRQ_STAT/IRQ_MCLR */
++		.virtual	= IRQ_STAT,
++		.pfn		= __phys_to_pfn(TRICK4_PHYS),
++		.length		= PGDIR_SIZE,
++		.type		= MT_DEVICE
++	}, {	/* IRQ_MASK/IRQ_MSET */
++		.virtual	= IRQ_MASK,
++		.pfn		= __phys_to_pfn(TRICK3_PHYS),
++		.length		= PGDIR_SIZE,
++		.type		= MT_DEVICE
++	}, {	/* SOFT_BASE */
++		.virtual	= SOFT_BASE,
++		.pfn		= __phys_to_pfn(TRICK1_PHYS),
++		.length		= PGDIR_SIZE,
++		.type		= MT_DEVICE
++	}, {	/* PIT_BASE */
++		.virtual	= PIT_BASE,
++		.pfn		= __phys_to_pfn(TRICK0_PHYS),
++		.length		= PGDIR_SIZE,
++		.type		= MT_DEVICE
++	},
+ 
+ 	/*
+ 	 * self-decode ISAIO space
+ 	 */
+-	{ ISAIO_BASE,  ISAIO_PHYS,  ISAIO_SIZE,  MT_DEVICE },
+-	{ ISAMEM_BASE, ISAMEM_PHYS, ISAMEM_SIZE, MT_DEVICE }
++	{
++		.virtual	= ISAIO_BASE,
++		.pfn		= __phys_to_pfn(ISAIO_PHYS),
++		.length		= ISAIO_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= ISAMEM_BASE,
++		.pfn		= __phys_to_pfn(ISAMEM_PHYS),
++		.length		= ISAMEM_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init ebsa110_map_io(void)
+@@ -225,9 +251,33 @@ static struct platform_device serial_dev
+ 	},
+ };
+ 
++static struct resource am79c961_resources[] = {
++	{
++		.start		= 0x220,
++		.end		= 0x238,
++		.flags		= IORESOURCE_IO,
++	}, {
++		.start		= IRQ_EBSA110_ETHERNET,
++		.end		= IRQ_EBSA110_ETHERNET,
++		.flags		= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device am79c961_device = {
++	.name			= "am79c961",
++	.id			= -1,
++	.num_resources		= ARRAY_SIZE(am79c961_resources),
++	.resource		= am79c961_resources,
++};
++
++static struct platform_device *ebsa110_devices[] = {
++	&serial_device,
++	&am79c961_device,
++};
++
+ static int __init ebsa110_init(void)
+ {
+-	return platform_device_register(&serial_device);
++	return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
+ }
+ 
+ arch_initcall(ebsa110_init);
+diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
+--- a/arch/arm/mach-ebsa110/io.c
++++ b/arch/arm/mach-ebsa110/io.c
+@@ -24,6 +24,7 @@
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ 
++#include <asm/hardware.h>
+ #include <asm/io.h>
+ #include <asm/page.h>
+ 
+diff --git a/arch/arm/mach-epxa10db/mm.c b/arch/arm/mach-epxa10db/mm.c
+--- a/arch/arm/mach-epxa10db/mm.c
++++ b/arch/arm/mach-epxa10db/mm.c
+@@ -31,12 +31,37 @@
+ /* Page table mapping for I/O region */
+  
+ static struct map_desc epxa10db_io_desc[] __initdata = {
+- { IO_ADDRESS(EXC_REGISTERS_BASE),   EXC_REGISTERS_BASE,    SZ_16K, MT_DEVICE }, 
+- { IO_ADDRESS(EXC_PLD_BLOCK0_BASE),  EXC_PLD_BLOCK0_BASE,   SZ_16K, MT_DEVICE }, 
+- { IO_ADDRESS(EXC_PLD_BLOCK1_BASE),  EXC_PLD_BLOCK1_BASE,   SZ_16K, MT_DEVICE }, 
+- { IO_ADDRESS(EXC_PLD_BLOCK2_BASE),  EXC_PLD_BLOCK2_BASE,   SZ_16K, MT_DEVICE }, 
+- { IO_ADDRESS(EXC_PLD_BLOCK3_BASE),  EXC_PLD_BLOCK3_BASE,   SZ_16K, MT_DEVICE }, 
+- { FLASH_VADDR(EXC_EBI_BLOCK0_BASE), EXC_EBI_BLOCK0_BASE,   SZ_16M, MT_DEVICE }
++	{
++		.virtual	= IO_ADDRESS(EXC_REGISTERS_BASE),
++		.pfn		= __phys_to_pfn(EXC_REGISTERS_BASE),
++		.length		= SZ_16K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(EXC_PLD_BLOCK0_BASE),
++		.pfn		= __phys_to_pfn(EXC_PLD_BLOCK0_BASE),
++		.length		= SZ_16K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(EXC_PLD_BLOCK1_BASE),
++		.pfn		=__phys_to_pfn(EXC_PLD_BLOCK1_BASE),
++		.length		= SZ_16K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(EXC_PLD_BLOCK2_BASE),
++		.physical	= __phys_to_pfn(EXC_PLD_BLOCK2_BASE),
++		.length		= SZ_16K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(EXC_PLD_BLOCK3_BASE),
++		.pfn		= __phys_to_pfn(EXC_PLD_BLOCK3_BASE),
++		.length		= SZ_16K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= FLASH_VADDR(EXC_EBI_BLOCK0_BASE),
++		.pfn		= __phys_to_pfn(EXC_EBI_BLOCK0_BASE),
++		.length		= SZ_16M,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init epxa10db_map_io(void)
+diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
+--- a/arch/arm/mach-footbridge/common.c
++++ b/arch/arm/mach-footbridge/common.c
+@@ -130,8 +130,17 @@ void __init footbridge_init_irq(void)
+  * it means that we have extra bullet protection on our feet.
+  */
+ static struct map_desc fb_common_io_desc[] __initdata = {
+- { ARMCSR_BASE,	 DC21285_ARMCSR_BASE,	    ARMCSR_SIZE,  MT_DEVICE },
+- { XBUS_BASE,    0x40000000,		    XBUS_SIZE,    MT_DEVICE }
++	{
++		.virtual	= ARMCSR_BASE,
++		.pfn		= DC21285_ARMCSR_BASE,
++		.length		= ARMCSR_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= XBUS_BASE,
++		.pfn		= __phys_to_pfn(0x40000000),
++		.length		= XBUS_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ /*
+@@ -140,11 +149,32 @@ static struct map_desc fb_common_io_desc
+  */
+ static struct map_desc ebsa285_host_io_desc[] __initdata = {
+ #if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST)
+- { PCIMEM_BASE,  DC21285_PCI_MEM,	    PCIMEM_SIZE,  MT_DEVICE },
+- { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, MT_DEVICE },
+- { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, MT_DEVICE },
+- { PCIIACK_BASE, DC21285_PCI_IACK,	    PCIIACK_SIZE, MT_DEVICE },
+- { PCIO_BASE,    DC21285_PCI_IO,	    PCIO_SIZE,	  MT_DEVICE }
++	{
++		.virtual	= PCIMEM_BASE,
++		.pfn		= __phys_to_pfn(DC21285_PCI_MEM),
++		.length		= PCIMEM_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= PCICFG0_BASE,
++		.pfn		= __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
++		.length		= PCICFG0_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= PCICFG1_BASE,
++		.pfn		= __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
++		.length		= PCICFG1_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= PCIIACK_BASE,
++		.pfn		= __phys_to_pfn(DC21285_PCI_IACK),
++		.length		= PCIIACK_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= PCIO_BASE,
++		.pfn		= __phys_to_pfn(DC21285_PCI_IO),
++		.length		= PCIO_SIZE,
++		.type		= MT_DEVICE
++	}
+ #endif
+ };
+ 
+@@ -153,8 +183,17 @@ static struct map_desc ebsa285_host_io_d
+  */
+ static struct map_desc co285_io_desc[] __initdata = {
+ #ifdef CONFIG_ARCH_CO285
+- { PCIO_BASE,	 DC21285_PCI_IO,	    PCIO_SIZE,    MT_DEVICE },
+- { PCIMEM_BASE,	 DC21285_PCI_MEM,	    PCIMEM_SIZE,  MT_DEVICE }
++	{
++		.virtual	= PCIO_BASE,
++		.pfn		= __phys_to_pfn(DC21285_PCI_IO),
++		.length		= PCIO_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= PCIMEM_BASE,
++		.pfn		= __phys_to_pfn(DC21285_PCI_MEM),
++		.length		= PCIMEM_SIZE,
++		.type		= MT_DEVICE
++	}
+ #endif
+ };
+ 
+diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
+--- a/arch/arm/mach-h720x/common.c
++++ b/arch/arm/mach-h720x/common.c
+@@ -237,7 +237,12 @@ void __init h720x_init_irq (void)
+ }
+ 
+ static struct map_desc h720x_io_desc[] __initdata = {
+-	{ IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
++	{
++		.virtual	= IO_VIRT,
++		.pfn		= __phys_to_pfn(IO_PHYS),
++		.length		= IO_SIZE,
++		.type		= MT_DEVICE
++	},
+ };
+ 
+ /* Initialize io tables */
+diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c
+--- a/arch/arm/mach-h720x/h7202-eval.c
++++ b/arch/arm/mach-h720x/h7202-eval.c
+@@ -18,7 +18,7 @@
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/string.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/setup.h>
+ #include <asm/types.h>
+diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
+--- a/arch/arm/mach-imx/generic.c
++++ b/arch/arm/mach-imx/generic.c
+@@ -22,10 +22,12 @@
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  *
+  */
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/string.h>
++
+ #include <asm/arch/imxfb.h>
+ #include <asm/hardware.h>
+ #include <asm/arch/imx-regs.h>
+@@ -273,8 +275,12 @@ static struct platform_device *devices[]
+ };
+ 
+ static struct map_desc imx_io_desc[] __initdata = {
+-	/* virtual     physical    length      type */
+-	{IMX_IO_BASE, IMX_IO_PHYS, IMX_IO_SIZE, MT_DEVICE},
++	{
++		.virtual	= IMX_IO_BASE,
++		.pfn		= __phys_to_pfn(IMX_IO_PHYS),
++		.length		= IMX_IO_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init
+diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
+--- a/arch/arm/mach-imx/mx1ads.c
++++ b/arch/arm/mach-imx/mx1ads.c
+@@ -14,6 +14,7 @@
+ 
+ #include <linux/device.h>
+ #include <linux/init.h>
++#include <linux/platform_device.h>
+ #include <asm/system.h>
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+@@ -61,13 +62,37 @@ mx1ads_init(void)
+ }
+ 
+ static struct map_desc mx1ads_io_desc[] __initdata = {
+-	/* virtual     physical    length      type */
+-	{IMX_CS0_VIRT, IMX_CS0_PHYS, IMX_CS0_SIZE, MT_DEVICE},
+-	{IMX_CS1_VIRT, IMX_CS1_PHYS, IMX_CS1_SIZE, MT_DEVICE},
+-	{IMX_CS2_VIRT, IMX_CS2_PHYS, IMX_CS2_SIZE, MT_DEVICE},
+-	{IMX_CS3_VIRT, IMX_CS3_PHYS, IMX_CS3_SIZE, MT_DEVICE},
+-	{IMX_CS4_VIRT, IMX_CS4_PHYS, IMX_CS4_SIZE, MT_DEVICE},
+-	{IMX_CS5_VIRT, IMX_CS5_PHYS, IMX_CS5_SIZE, MT_DEVICE},
++	{
++		.virtual	= IMX_CS0_VIRT,
++		.pfn		= __phys_to_pfn(IMX_CS0_PHYS),
++		.length		= IMX_CS0_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IMX_CS1_VIRT,
++		.pfn		= __phys_to_pfn(IMX_CS1_PHYS),
++		.length		= IMX_CS1_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IMX_CS2_VIRT,
++		.pfn		= __phys_to_pfn(IMX_CS2_PHYS),
++		.length		= IMX_CS2_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IMX_CS3_VIRT,
++		.pfn		= __phys_to_pfn(IMX_CS3_PHYS),
++		.length		= IMX_CS3_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IMX_CS4_VIRT,
++		.pfn		= __phys_to_pfn(IMX_CS4_PHYS),
++		.length		= IMX_CS4_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IMX_CS5_VIRT,
++		.pfn		= __phys_to_pfn(IMX_CS5_PHYS),
++		.length		= IMX_CS5_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init
+diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c
+--- a/arch/arm/mach-integrator/clock.c
++++ b/arch/arm/mach-integrator/clock.c
+@@ -13,6 +13,7 @@
+ #include <linux/list.h>
+ #include <linux/errno.h>
+ #include <linux/err.h>
++#include <linux/string.h>
+ 
+ #include <asm/semaphore.h>
+ #include <asm/hardware/clock.h>
+diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
+--- a/arch/arm/mach-integrator/integrator_ap.c
++++ b/arch/arm/mach-integrator/integrator_ap.c
+@@ -21,7 +21,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/list.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/sysdev.h>
+@@ -30,6 +30,7 @@
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/setup.h>
++#include <asm/param.h>		/* HZ */
+ #include <asm/mach-types.h>
+ #include <asm/hardware/amba.h>
+ #include <asm/hardware/amba_kmi.h>
+@@ -75,19 +76,72 @@
+  */
+ 
+ static struct map_desc ap_io_desc[] __initdata = {
+- { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K,  MT_DEVICE },
+- { PCI_MEMORY_VADDR,                  PHYS_PCI_MEM_BASE,     SZ_16M, MT_DEVICE },
+- { PCI_CONFIG_VADDR,                  PHYS_PCI_CONFIG_BASE,  SZ_16M, MT_DEVICE },
+- { PCI_V3_VADDR,                      PHYS_PCI_V3_BASE,      SZ_64K, MT_DEVICE },
+- { PCI_IO_VADDR,                      PHYS_PCI_IO_BASE,      SZ_64K, MT_DEVICE }
++	{
++		.virtual	= IO_ADDRESS(INTEGRATOR_HDR_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_HDR_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_SC_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_SC_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_EBI_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_EBI_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_CT_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_CT_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_IC_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_IC_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_UART0_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_UART0_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_UART1_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_UART1_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_DBG_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_DBG_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_GPIO_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_GPIO_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= PCI_MEMORY_VADDR,
++		.pfn		= __phys_to_pfn(PHYS_PCI_MEM_BASE),
++		.length		= SZ_16M,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= PCI_CONFIG_VADDR,
++		.pfn		= __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
++		.length		= SZ_16M,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= PCI_V3_VADDR,
++		.pfn		= __phys_to_pfn(PHYS_PCI_V3_BASE),
++		.length		= SZ_64K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= PCI_IO_VADDR,
++		.pfn		= __phys_to_pfn(PHYS_PCI_IO_BASE),
++		.length		= SZ_64K,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init ap_map_io(void)
+diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
+--- a/arch/arm/mach-integrator/integrator_cp.c
++++ b/arch/arm/mach-integrator/integrator_cp.c
+@@ -11,7 +11,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/list.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
+@@ -74,17 +74,62 @@
+  */
+ 
+ static struct map_desc intcp_io_desc[] __initdata = {
+- { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K,  MT_DEVICE },
+- { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE },
+- { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE },
++	{
++		.virtual	= IO_ADDRESS(INTEGRATOR_HDR_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_HDR_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_SC_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_SC_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_EBI_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_EBI_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_CT_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_CT_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_IC_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_IC_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_UART0_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_UART0_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_UART1_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_UART1_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_DBG_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_DBG_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= IO_ADDRESS(INTEGRATOR_GPIO_BASE),
++		.pfn		= __phys_to_pfn(INTEGRATOR_GPIO_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= 0xfca00000,
++		.pfn		= __phys_to_pfn(0xca000000),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= 0xfcb00000,
++		.pfn		= __phys_to_pfn(0xcb000000),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init intcp_map_io(void)
+diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c
+--- a/arch/arm/mach-integrator/lm.c
++++ b/arch/arm/mach-integrator/lm.c
+@@ -10,6 +10,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
++#include <linux/slab.h>
+ 
+ #include <asm/arch/lm.h>
+ 
+diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
+--- a/arch/arm/mach-iop3xx/iop321-setup.c
++++ b/arch/arm/mach-iop3xx/iop321-setup.c
+@@ -16,7 +16,7 @@
+ #include <linux/init.h>
+ #include <linux/major.h>
+ #include <linux/fs.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/serial.h>
+ #include <linux/tty.h>
+ #include <linux/serial_core.h>
+@@ -38,13 +38,17 @@
+  * Standard IO mapping for all IOP321 based systems
+  */
+ static struct map_desc iop321_std_desc[] __initdata = {
+- /* virtual     physical      length      type */
+-
+- /* mem mapped registers */
+- { IOP321_VIRT_MEM_BASE,  IOP321_PHYS_MEM_BASE,   0x00002000,  MT_DEVICE },
+-
+- /* PCI IO space */
+- { IOP321_PCI_LOWER_IO_VA,  IOP321_PCI_LOWER_IO_PA,   IOP321_PCI_IO_WINDOW_SIZE,  MT_DEVICE }
++	 {	/* mem mapped registers */
++		.virtual	= IOP321_VIRT_MEM_BASE,
++		.pfn		= __phys_to_pfn(IOP321_PHYS_MEM_BASE),
++		.length		= 0x00002000,
++		.type		= MT_DEVICE
++	 }, {	/* PCI IO space */
++		.virtual	= IOP321_PCI_LOWER_IO_VA,
++		.pfn		= __phys_to_pfn(IOP321_PCI_LOWER_IO_PA),
++		.length		= IOP321_PCI_IO_WINDOW_SIZE,
++		.type		= MT_DEVICE
++	 }
+ };
+ 
+ #ifdef CONFIG_ARCH_IQ80321
+diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
+--- a/arch/arm/mach-iop3xx/iop331-setup.c
++++ b/arch/arm/mach-iop3xx/iop331-setup.c
+@@ -15,7 +15,7 @@
+ #include <linux/init.h>
+ #include <linux/major.h>
+ #include <linux/fs.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/serial.h>
+ #include <linux/tty.h>
+ #include <linux/serial_core.h>
+@@ -37,13 +37,17 @@
+  * Standard IO mapping for all IOP331 based systems
+  */
+ static struct map_desc iop331_std_desc[] __initdata = {
+- /* virtual     physical      length      type */
+-
+- /* mem mapped registers */
+- { IOP331_VIRT_MEM_BASE,  IOP331_PHYS_MEM_BASE,   0x00002000,  MT_DEVICE },
+-
+- /* PCI IO space */
+- { IOP331_PCI_LOWER_IO_VA,  IOP331_PCI_LOWER_IO_PA,   IOP331_PCI_IO_WINDOW_SIZE,  MT_DEVICE }
++	{	/* mem mapped registers */
++		.virtual	= IOP331_VIRT_MEM_BASE,
++		.pfn		= __phys_to_pfn(IOP331_PHYS_MEM_BASE),
++		.length		= 0x00002000,
++		.type		= MT_DEVICE
++	}, {	/* PCI IO space */
++		.virtual	= IOP331_PCI_LOWER_IO_VA,
++		.pfn		= __phys_to_pfn(IOP331_PCI_LOWER_IO_PA),
++		.length		= IOP331_PCI_IO_WINDOW_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static struct uart_port iop331_serial_ports[] = {
+diff --git a/arch/arm/mach-iop3xx/iq31244-mm.c b/arch/arm/mach-iop3xx/iq31244-mm.c
+--- a/arch/arm/mach-iop3xx/iq31244-mm.c
++++ b/arch/arm/mach-iop3xx/iq31244-mm.c
+@@ -29,10 +29,12 @@
+  * We use RedBoot's setup for the onboard devices.
+  */
+ static struct map_desc iq31244_io_desc[] __initdata = {
+- /* virtual     physical      length        type */
+-
+- /* on-board devices */
+- { IQ31244_UART, IQ31244_UART,   0x00100000,   MT_DEVICE }
++	{	/* on-board devices */
++		.virtual	= IQ31244_UART,
++		.pfn		= __phys_to_pfn(IQ31244_UART),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init iq31244_map_io(void)
+diff --git a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c
+--- a/arch/arm/mach-iop3xx/iq31244-pci.c
++++ b/arch/arm/mach-iop3xx/iq31244-pci.c
+@@ -14,6 +14,8 @@
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+diff --git a/arch/arm/mach-iop3xx/iq80321-mm.c b/arch/arm/mach-iop3xx/iq80321-mm.c
+--- a/arch/arm/mach-iop3xx/iq80321-mm.c
++++ b/arch/arm/mach-iop3xx/iq80321-mm.c
+@@ -29,10 +29,12 @@
+  * We use RedBoot's setup for the onboard devices.
+  */
+ static struct map_desc iq80321_io_desc[] __initdata = {
+- /* virtual     physical      length        type */
+-
+- /* on-board devices */
+- { IQ80321_UART, IQ80321_UART,   0x00100000,   MT_DEVICE }
++ 	{	/* on-board devices */
++		.virtual	= IQ80321_UART,
++		.pfn		= __phys_to_pfn(IQ80321_UART),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init iq80321_map_io(void)
+diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c
+--- a/arch/arm/mach-iop3xx/iq80321-pci.c
++++ b/arch/arm/mach-iop3xx/iq80321-pci.c
+@@ -14,6 +14,8 @@
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+diff --git a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c
+--- a/arch/arm/mach-iop3xx/iq80331-pci.c
++++ b/arch/arm/mach-iop3xx/iq80331-pci.c
+@@ -13,6 +13,8 @@
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+diff --git a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c
+--- a/arch/arm/mach-iop3xx/iq80332-pci.c
++++ b/arch/arm/mach-iop3xx/iq80332-pci.c
+@@ -13,6 +13,8 @@
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+diff --git a/arch/arm/mach-ixp2000/Makefile b/arch/arm/mach-ixp2000/Makefile
+--- a/arch/arm/mach-ixp2000/Makefile
++++ b/arch/arm/mach-ixp2000/Makefile
+@@ -1,7 +1,7 @@
+ #
+ # Makefile for the linux kernel.
+ #
+-obj-y			:= core.o pci.o
++obj-y			:= core.o pci.o uengine.o
+ obj-m			:=
+ obj-n			:=
+ obj-			:=
+diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
+--- a/arch/arm/mach-ixp2000/core.c
++++ b/arch/arm/mach-ixp2000/core.c
+@@ -1,5 +1,5 @@
+ /*
+- * arch/arm/mach-ixp2000/common.c
++ * arch/arm/mach-ixp2000/core.c
+  *
+  * Common routines used by all IXP2400/2800 based platforms.
+  *
+@@ -49,7 +49,6 @@ static unsigned long ixp2000_slowport_ir
+  *************************************************************************/
+ void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg)
+ {
+-
+ 	spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags);
+ 
+ 	old_cfg->CCR = *IXP2000_SLOWPORT_CCR;
+@@ -62,7 +61,7 @@ void ixp2000_acquire_slowport(struct slo
+ 	ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC);
+ 	ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC);
+ 	ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR);
+-	ixp2000_reg_write(IXP2000_SLOWPORT_ADC, new_cfg->ADC);
++	ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, new_cfg->ADC);
+ }
+ 
+ void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
+@@ -71,7 +70,7 @@ void ixp2000_release_slowport(struct slo
+ 	ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC);
+ 	ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC);
+ 	ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR);
+-	ixp2000_reg_write(IXP2000_SLOWPORT_ADC, old_cfg->ADC);
++	ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, old_cfg->ADC);
+ 
+ 	spin_unlock_irqrestore(&ixp2000_slowport_lock, 
+ 					ixp2000_slowport_irq_flags);
+@@ -83,42 +82,42 @@ void ixp2000_release_slowport(struct slo
+ static struct map_desc ixp2000_io_desc[] __initdata = {
+ 	{
+ 		.virtual	= IXP2000_CAP_VIRT_BASE,
+-		.physical	= IXP2000_CAP_PHYS_BASE,
++		.pfn		= __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
+ 		.length		= IXP2000_CAP_SIZE,
+ 		.type		= MT_DEVICE
+ 	}, {
+ 		.virtual	= IXP2000_INTCTL_VIRT_BASE,
+-		.physical	= IXP2000_INTCTL_PHYS_BASE,
++		.pfn		= __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
+ 		.length		= IXP2000_INTCTL_SIZE,
+ 		.type		= MT_DEVICE
+ 	}, {
+ 		.virtual	= IXP2000_PCI_CREG_VIRT_BASE,
+-		.physical	= IXP2000_PCI_CREG_PHYS_BASE,
++		.pfn		= __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
+ 		.length		= IXP2000_PCI_CREG_SIZE,
+ 		.type		= MT_DEVICE
+ 	}, {
+ 		.virtual	= IXP2000_PCI_CSR_VIRT_BASE,
+-		.physical	= IXP2000_PCI_CSR_PHYS_BASE,
++		.pfn		= __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
+ 		.length		= IXP2000_PCI_CSR_SIZE,
+ 		.type		= MT_DEVICE
+ 	}, {
+ 		.virtual	= IXP2000_MSF_VIRT_BASE,
+-		.physical	= IXP2000_MSF_PHYS_BASE,
++		.pfn		= __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
+ 		.length		= IXP2000_MSF_SIZE,
+ 		.type		= MT_DEVICE
+ 	}, {
+ 		.virtual	= IXP2000_PCI_IO_VIRT_BASE,
+-		.physical	= IXP2000_PCI_IO_PHYS_BASE,
++		.pfn		= __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
+ 		.length		= IXP2000_PCI_IO_SIZE,
+ 		.type		= MT_DEVICE
+ 	}, {
+ 		.virtual	= IXP2000_PCI_CFG0_VIRT_BASE,
+-		.physical	= IXP2000_PCI_CFG0_PHYS_BASE,
++		.pfn		= __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
+ 		.length		= IXP2000_PCI_CFG0_SIZE,
+ 		.type		= MT_DEVICE
+ 	}, {
+ 		.virtual	= IXP2000_PCI_CFG1_VIRT_BASE,
+-		.physical	= IXP2000_PCI_CFG1_PHYS_BASE,
++		.pfn		= __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
+ 		.length		= IXP2000_PCI_CFG1_SIZE,
+ 		.type		= MT_DEVICE
+ 	}
+@@ -145,7 +144,7 @@ void __init ixp2000_map_io(void)
+ 	iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
+ 
+ 	/* Set slowport to 8-bit mode.  */
+-	ixp2000_reg_write(IXP2000_SLOWPORT_FRM, 1);
++	ixp2000_reg_wrb(IXP2000_SLOWPORT_FRM, 1);
+ }
+ 
+ 
+@@ -209,7 +208,7 @@ static int ixp2000_timer_interrupt(int i
+ 	write_seqlock(&xtime_lock);
+ 
+ 	/* clear timer 1 */
+-	ixp2000_reg_write(IXP2000_T1_CLR, 1);
++	ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
+ 
+ 	while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
+ 		timer_tick(regs);
+@@ -252,12 +251,12 @@ void __init ixp2000_init_time(unsigned l
+ 
+ 		ixp2000_reg_write(IXP2000_T4_CLR, 0);
+ 		ixp2000_reg_write(IXP2000_T4_CLD, -1);
+-		ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
++		ixp2000_reg_wrb(IXP2000_T4_CTL, (1 << 7));
+ 		missing_jiffy_timer_csr = IXP2000_T4_CSR;
+ 	} else {
+ 		ixp2000_reg_write(IXP2000_T2_CLR, 0);
+ 		ixp2000_reg_write(IXP2000_T2_CLD, -1);
+-		ixp2000_reg_write(IXP2000_T2_CTL, (1 << 7));
++		ixp2000_reg_wrb(IXP2000_T2_CTL, (1 << 7));
+ 		missing_jiffy_timer_csr = IXP2000_T2_CSR;
+ 	}
+  	next_jiffy_time = 0xffffffff;
+@@ -279,7 +278,7 @@ static void update_gpio_int_csrs(void)
+ 	ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
+ 	ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
+ 	ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
+-	ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
++	ixp2000_reg_wrb(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
+ }
+ 
+ void gpio_line_config(int line, int direction)
+@@ -297,9 +296,9 @@ void gpio_line_config(int line, int dire
+ 		GPIO_IRQ_level_high &= ~(1 << line);
+ 		update_gpio_int_csrs();
+ 
+-		ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line);
++		ixp2000_reg_wrb(IXP2000_GPIO_PDSR, 1 << line);
+ 	} else if (direction == GPIO_IN) {
+-		ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
++		ixp2000_reg_wrb(IXP2000_GPIO_PDCR, 1 << line);
+ 	}
+ 	local_irq_restore(flags);
+ }
+@@ -365,12 +364,12 @@ static void ixp2000_GPIO_irq_mask_ack(un
+ 
+ 	ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+ 	ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+-	ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
++	ixp2000_reg_wrb(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
+ }
+ 
+ static void ixp2000_GPIO_irq_mask(unsigned int irq)
+ {
+-	ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
++	ixp2000_reg_wrb(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+ }
+ 
+ static void ixp2000_GPIO_irq_unmask(unsigned int irq)
+@@ -389,9 +388,9 @@ static void ixp2000_pci_irq_mask(unsigne
+ {
+ 	unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
+ 	if (irq == IRQ_IXP2000_PCIA)
+-		ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
++		ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
+ 	else if (irq == IRQ_IXP2000_PCIB)
+-		ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
++		ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
+ }
+ 
+ static void ixp2000_pci_irq_unmask(unsigned int irq)
+@@ -411,7 +410,7 @@ static struct irqchip ixp2000_pci_irq_ch
+ 
+ static void ixp2000_irq_mask(unsigned int irq)
+ {
+-	ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
++	ixp2000_reg_wrb(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
+ }
+ 
+ static void ixp2000_irq_unmask(unsigned int irq)
+@@ -443,7 +442,7 @@ void __init ixp2000_init_irq(void)
+ 	ixp2000_reg_write(IXP2000_GPIO_INCR, -1);
+ 
+ 	/* clear PCI interrupt sources */
+-	ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, 0);
++	ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, 0);
+ 
+ 	/*
+ 	 * Certain bits in the IRQ status register of the 
+diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
+--- a/arch/arm/mach-ixp2000/enp2611.c
++++ b/arch/arm/mach-ixp2000/enp2611.c
+@@ -32,7 +32,7 @@
+ #include <linux/serial.h>
+ #include <linux/tty.h>
+ #include <linux/serial_core.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -64,6 +64,35 @@ static struct sys_timer enp2611_timer = 
+ 
+ 
+ /*************************************************************************
++ * ENP-2611 I/O
++ *************************************************************************/
++static struct map_desc enp2611_io_desc[] __initdata = {
++	{
++		.virtual	= ENP2611_CALEB_VIRT_BASE,
++		.physical	= ENP2611_CALEB_PHYS_BASE,
++		.length		= ENP2611_CALEB_SIZE,
++		.type		= MT_IXP2000_DEVICE
++	}, {
++		.virtual	= ENP2611_PM3386_0_VIRT_BASE,
++		.physical	= ENP2611_PM3386_0_PHYS_BASE,
++		.length		= ENP2611_PM3386_0_SIZE,
++		.type		= MT_IXP2000_DEVICE
++	}, {
++		.virtual	= ENP2611_PM3386_1_VIRT_BASE,
++		.physical	= ENP2611_PM3386_1_PHYS_BASE,
++		.length		= ENP2611_PM3386_1_SIZE,
++		.type		= MT_IXP2000_DEVICE
++	}
++};
++
++void __init enp2611_map_io(void)
++{
++	ixp2000_map_io();
++	iotable_init(enp2611_io_desc, ARRAY_SIZE(enp2611_io_desc));
++}
++
++
++/*************************************************************************
+  * ENP-2611 PCI
+  *************************************************************************/
+ static int enp2611_pci_setup(int nr, struct pci_sys_data *sys)
+@@ -229,7 +258,7 @@ MACHINE_START(ENP2611, "Radisys ENP-2611
+ 	.phys_io	= IXP2000_UART_PHYS_BASE,
+ 	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+ 	.boot_params	= 0x00000100,
+-	.map_io		= ixp2000_map_io,
++	.map_io		= enp2611_map_io,
+ 	.init_irq	= ixp2000_init_irq,
+ 	.timer		= &enp2611_timer,
+ 	.init_machine	= enp2611_init_machine,
+diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
+--- a/arch/arm/mach-ixp2000/ixdp2x00.c
++++ b/arch/arm/mach-ixp2000/ixdp2x00.c
+@@ -20,7 +20,7 @@
+ #include <linux/mm.h>
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/bitops.h>
+ #include <linux/pci.h>
+ #include <linux/ioport.h>
+@@ -81,7 +81,7 @@ static void ixdp2x00_irq_mask(unsigned i
+ 
+ 	dummy = *board_irq_mask;
+ 	dummy |=  IXP2000_BOARD_IRQ_MASK(irq);
+-	ixp2000_reg_write(board_irq_mask, dummy);
++	ixp2000_reg_wrb(board_irq_mask, dummy);
+ 
+ #ifdef CONFIG_ARCH_IXDP2400
+ 	if (machine_is_ixdp2400())
+@@ -101,7 +101,7 @@ static void ixdp2x00_irq_unmask(unsigned
+ 
+ 	dummy = *board_irq_mask;
+ 	dummy &=  ~IXP2000_BOARD_IRQ_MASK(irq);
+-	ixp2000_reg_write(board_irq_mask, dummy);
++	ixp2000_reg_wrb(board_irq_mask, dummy);
+ 
+ 	if (machine_is_ixdp2400()) 
+ 		ixp2000_release_slowport(&old_cfg);
+@@ -176,7 +176,7 @@ void ixdp2x00_init_irq(volatile unsigned
+  *************************************************************************/
+ static struct map_desc ixdp2x00_io_desc __initdata = {
+ 	.virtual	= IXDP2X00_VIRT_CPLD_BASE, 
+-	.physical	= IXDP2X00_PHYS_CPLD_BASE,
++	.pfn		= __phys_to_pfn(IXDP2X00_PHYS_CPLD_BASE),
+ 	.length		= IXDP2X00_CPLD_SIZE,
+ 	.type		= MT_DEVICE
+ };
+diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
+--- a/arch/arm/mach-ixp2000/ixdp2x01.c
++++ b/arch/arm/mach-ixp2000/ixdp2x01.c
+@@ -29,7 +29,7 @@
+ #include <linux/serial.h>
+ #include <linux/tty.h>
+ #include <linux/serial_core.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -51,7 +51,7 @@
+  *************************************************************************/
+ static void ixdp2x01_irq_mask(unsigned int irq)
+ {
+-	ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG,
++	ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG,
+ 				IXP2000_BOARD_IRQ_MASK(irq));
+ }
+ 
+@@ -114,7 +114,7 @@ void __init ixdp2x01_init_irq(void)
+ 
+ 	/* Mask all interrupts from CPLD, disable simulation */
+ 	ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff);
+-	ixp2000_reg_write(IXDP2X01_INT_SIM_REG, 0);
++	ixp2000_reg_wrb(IXDP2X01_INT_SIM_REG, 0);
+ 
+ 	for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) {
+ 		if (irq & valid_irq_mask) {
+@@ -136,7 +136,7 @@ void __init ixdp2x01_init_irq(void)
+  *************************************************************************/
+ static struct map_desc ixdp2x01_io_desc __initdata = {
+ 	.virtual	= IXDP2X01_VIRT_CPLD_BASE, 
+-	.physical	= IXDP2X01_PHYS_CPLD_BASE,
++	.pfn		= __phys_to_pfn(IXDP2X01_PHYS_CPLD_BASE),
+ 	.length		= IXDP2X01_CPLD_REGION_SIZE,
+ 	.type		= MT_DEVICE
+ };
+@@ -299,7 +299,6 @@ struct hw_pci ixdp2x01_pci __initdata = 
+ 
+ int __init ixdp2x01_pci_init(void)
+ {
+-
+ 	pci_common_init(&ixdp2x01_pci);
+ 	return 0;
+ }
+@@ -316,7 +315,7 @@ static struct flash_platform_data ixdp2x
+ 
+ static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs)
+ {
+-	ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG,
++	ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
+ 		((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN));
+ 	return (ofs & IXDP2X01_FLASH_WINDOW_MASK);
+ }
+@@ -363,7 +362,7 @@ static struct platform_device *ixdp2x01_
+ 
+ static void __init ixdp2x01_init_machine(void)
+ {
+-	ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG,
++	ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
+ 		(IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN));
+ 	
+ 	ixdp2x01_flash_data.nr_banks =
+diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
+--- a/arch/arm/mach-ixp2000/pci.c
++++ b/arch/arm/mach-ixp2000/pci.c
+@@ -148,7 +148,7 @@ int ixp2000_pci_abort_handler(unsigned l
+ 	local_irq_save(flags);
+ 	temp = *(IXP2000_PCI_CONTROL);
+ 	if (temp & ((1 << 8) | (1 << 5))) {
+-		ixp2000_reg_write(IXP2000_PCI_CONTROL, temp);
++		ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
+ 	}
+ 
+ 	temp = *(IXP2000_PCI_CMDSTAT);
+@@ -178,8 +178,8 @@ clear_master_aborts(void)
+ 
+ 	local_irq_save(flags);
+ 	temp = *(IXP2000_PCI_CONTROL);
+-	if (temp & ((1 << 8) | (1 << 5))) {	
+-		ixp2000_reg_write(IXP2000_PCI_CONTROL, temp);
++	if (temp & ((1 << 8) | (1 << 5))) {
++		ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
+ 	}
+ 
+ 	temp = *(IXP2000_PCI_CMDSTAT);
+diff --git a/arch/arm/mach-ixp2000/uengine.c b/arch/arm/mach-ixp2000/uengine.c
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-ixp2000/uengine.c
+@@ -0,0 +1,474 @@
++/*
++ * Generic library functions for the microengines found on the Intel
++ * IXP2000 series of network processors.
++ *
++ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh at wantstofly.org>
++ * Dedicated to Marija Kulikova.
++ *
++ * This program 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.
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <asm/hardware.h>
++#include <asm/arch/ixp2000-regs.h>
++#include <asm/arch/uengine.h>
++#include <asm/io.h>
++
++#define USTORE_ADDRESS			0x000
++#define USTORE_DATA_LOWER		0x004
++#define USTORE_DATA_UPPER		0x008
++#define CTX_ENABLES			0x018
++#define CC_ENABLE			0x01c
++#define CSR_CTX_POINTER			0x020
++#define INDIRECT_CTX_STS		0x040
++#define ACTIVE_CTX_STS			0x044
++#define INDIRECT_CTX_SIG_EVENTS		0x048
++#define INDIRECT_CTX_WAKEUP_EVENTS	0x050
++#define NN_PUT				0x080
++#define NN_GET				0x084
++#define TIMESTAMP_LOW			0x0c0
++#define TIMESTAMP_HIGH			0x0c4
++#define T_INDEX_BYTE_INDEX		0x0f4
++#define LOCAL_CSR_STATUS		0x180
++
++u32 ixp2000_uengine_mask;
++
++static void *ixp2000_uengine_csr_area(int uengine)
++{
++	return ((void *)IXP2000_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
++}
++
++/*
++ * LOCAL_CSR_STATUS=1 after a read or write to a microengine's CSR
++ * space means that the microengine we tried to access was also trying
++ * to access its own CSR space on the same clock cycle as we did.  When
++ * this happens, we lose the arbitration process by default, and the
++ * read or write we tried to do was not actually performed, so we try
++ * again until it succeeds.
++ */
++u32 ixp2000_uengine_csr_read(int uengine, int offset)
++{
++	void *uebase;
++	u32 *local_csr_status;
++	u32 *reg;
++	u32 value;
++
++	uebase = ixp2000_uengine_csr_area(uengine);
++
++	local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
++	reg = (u32 *)(uebase + offset);
++	do {
++		value = ixp2000_reg_read(reg);
++	} while (ixp2000_reg_read(local_csr_status) & 1);
++
++	return value;
++}
++EXPORT_SYMBOL(ixp2000_uengine_csr_read);
++
++void ixp2000_uengine_csr_write(int uengine, int offset, u32 value)
++{
++	void *uebase;
++	u32 *local_csr_status;
++	u32 *reg;
++
++	uebase = ixp2000_uengine_csr_area(uengine);
++
++	local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
++	reg = (u32 *)(uebase + offset);
++	do {
++		ixp2000_reg_write(reg, value);
++	} while (ixp2000_reg_read(local_csr_status) & 1);
++}
++EXPORT_SYMBOL(ixp2000_uengine_csr_write);
++
++void ixp2000_uengine_reset(u32 uengine_mask)
++{
++	ixp2000_reg_write(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask);
++	ixp2000_reg_write(IXP2000_RESET1, 0);
++}
++EXPORT_SYMBOL(ixp2000_uengine_reset);
++
++void ixp2000_uengine_set_mode(int uengine, u32 mode)
++{
++	/*
++	 * CTL_STR_PAR_EN: unconditionally enable parity checking on
++	 * control store.
++	 */
++	mode |= 0x10000000;
++	ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mode);
++
++	/*
++	 * Enable updating of condition codes.
++	 */
++	ixp2000_uengine_csr_write(uengine, CC_ENABLE, 0x00002000);
++
++	/*
++	 * Initialise other per-microengine registers.
++	 */
++	ixp2000_uengine_csr_write(uengine, NN_PUT, 0x00);
++	ixp2000_uengine_csr_write(uengine, NN_GET, 0x00);
++	ixp2000_uengine_csr_write(uengine, T_INDEX_BYTE_INDEX, 0);
++}
++EXPORT_SYMBOL(ixp2000_uengine_set_mode);
++
++static int make_even_parity(u32 x)
++{
++	return hweight32(x) & 1;
++}
++
++static void ustore_write(int uengine, u64 insn)
++{
++	/*
++	 * Generate even parity for top and bottom 20 bits.
++	 */
++	insn |= (u64)make_even_parity((insn >> 20) & 0x000fffff) << 41;
++	insn |= (u64)make_even_parity(insn & 0x000fffff) << 40;
++
++	/*
++	 * Write to microstore.  The second write auto-increments
++	 * the USTORE_ADDRESS index register.
++	 */
++	ixp2000_uengine_csr_write(uengine, USTORE_DATA_LOWER, (u32)insn);
++	ixp2000_uengine_csr_write(uengine, USTORE_DATA_UPPER, (u32)(insn >> 32));
++}
++
++void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns)
++{
++	int i;
++
++	/*
++	 * Start writing to microstore at address 0.
++	 */
++	ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x80000000);
++	for (i = 0; i < insns; i++) {
++		u64 insn;
++
++		insn = (((u64)ucode[0]) << 32) |
++			(((u64)ucode[1]) << 24) |
++			(((u64)ucode[2]) << 16) |
++			(((u64)ucode[3]) << 8) |
++			((u64)ucode[4]);
++		ucode += 5;
++
++		ustore_write(uengine, insn);
++	}
++
++	/*
++ 	 * Pad with a few NOPs at the end (to avoid the microengine
++	 * aborting as it prefetches beyond the last instruction), unless
++	 * we run off the end of the instruction store first, at which
++	 * point the address register will wrap back to zero.
++	 */
++	for (i = 0; i < 4; i++) {
++		u32 addr;
++
++		addr = ixp2000_uengine_csr_read(uengine, USTORE_ADDRESS);
++		if (addr == 0x80000000)
++			break;
++		ustore_write(uengine, 0xf0000c0300ULL);
++	}
++
++	/*
++	 * End programming.
++	 */
++	ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x00000000);
++}
++EXPORT_SYMBOL(ixp2000_uengine_load_microcode);
++
++void ixp2000_uengine_init_context(int uengine, int context, int pc)
++{
++	/*
++	 * Select the right context for indirect access.
++	 */
++	ixp2000_uengine_csr_write(uengine, CSR_CTX_POINTER, context);
++
++	/*
++	 * Initialise signal masks to immediately go to Ready state.
++	 */
++	ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_SIG_EVENTS, 1);
++	ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_WAKEUP_EVENTS, 1);
++
++	/*
++	 * Set program counter.
++	 */
++	ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_STS, pc);
++}
++EXPORT_SYMBOL(ixp2000_uengine_init_context);
++
++void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask)
++{
++	u32 mask;
++
++	/*
++	 * Enable the specified context to go to Executing state.
++	 */
++	mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
++	mask |= ctx_mask << 8;
++	ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
++}
++EXPORT_SYMBOL(ixp2000_uengine_start_contexts);
++
++void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask)
++{
++	u32 mask;
++
++	/*
++	 * Disable the Ready->Executing transition.  Note that this
++	 * does not stop the context until it voluntarily yields.
++	 */
++	mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
++	mask &= ~(ctx_mask << 8);
++	ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
++}
++EXPORT_SYMBOL(ixp2000_uengine_stop_contexts);
++
++static int check_ixp_type(struct ixp2000_uengine_code *c)
++{
++	u32 product_id;
++	u32 rev;
++
++	product_id = ixp2000_reg_read(IXP2000_PRODUCT_ID);
++	if (((product_id >> 16) & 0x1f) != 0)
++		return 0;
++
++	switch ((product_id >> 8) & 0xff) {
++	case 0:		/* IXP2800 */
++		if (!(c->cpu_model_bitmask & 4))
++			return 0;
++		break;
++
++	case 1:		/* IXP2850 */
++		if (!(c->cpu_model_bitmask & 8))
++			return 0;
++		break;
++
++	case 2:		/* IXP2400 */
++		if (!(c->cpu_model_bitmask & 2))
++			return 0;
++		break;
++
++	default:
++		return 0;
++	}
++
++	rev = product_id & 0xff;
++	if (rev < c->cpu_min_revision || rev > c->cpu_max_revision)
++		return 0;
++
++	return 1;
++}
++
++static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
++{
++	int offset;
++	int i;
++
++	offset = 0;
++
++	for (i = 0; i < 128; i++) {
++		u8 b3;
++		u8 b2;
++		u8 b1;
++		u8 b0;
++
++		b3 = (gpr_a[i] >> 24) & 0xff;
++		b2 = (gpr_a[i] >> 16) & 0xff;
++		b1 = (gpr_a[i] >> 8) & 0xff;
++		b0 = gpr_a[i] & 0xff;
++
++		// immed[@ai, (b1 << 8) | b0]
++		// 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII
++		ucode[offset++] = 0xf0;
++		ucode[offset++] = (b1 >> 4);
++		ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6);
++		ucode[offset++] = (b0 << 2);
++		ucode[offset++] = 0x80 | i;
++
++		// immed_w1[@ai, (b3 << 8) | b2]
++		// 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII
++		ucode[offset++] = 0xf4;
++		ucode[offset++] = 0x40 | (b3 >> 4);
++		ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6);
++		ucode[offset++] = (b2 << 2);
++		ucode[offset++] = 0x80 | i;
++	}
++
++	for (i = 0; i < 128; i++) {
++		u8 b3;
++		u8 b2;
++		u8 b1;
++		u8 b0;
++
++		b3 = (gpr_b[i] >> 24) & 0xff;
++		b2 = (gpr_b[i] >> 16) & 0xff;
++		b1 = (gpr_b[i] >> 8) & 0xff;
++		b0 = gpr_b[i] & 0xff;
++
++		// immed[@bi, (b1 << 8) | b0]
++		// 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV
++		ucode[offset++] = 0xf0;
++		ucode[offset++] = (b1 >> 4);
++		ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6);
++		ucode[offset++] = (i << 2) | 0x03;
++		ucode[offset++] = b0;
++
++		// immed_w1[@bi, (b3 << 8) | b2]
++		// 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV
++		ucode[offset++] = 0xf4;
++		ucode[offset++] = 0x40 | (b3 >> 4);
++		ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6);
++		ucode[offset++] = (i << 2) | 0x03;
++		ucode[offset++] = b2;
++	}
++
++	// ctx_arb[kill]
++	ucode[offset++] = 0xe0;
++	ucode[offset++] = 0x00;
++	ucode[offset++] = 0x01;
++	ucode[offset++] = 0x00;
++	ucode[offset++] = 0x00;
++}
++
++static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
++{
++	int per_ctx_regs;
++	u32 *gpr_a;
++	u32 *gpr_b;
++	u8 *ucode;
++	int i;
++
++	gpr_a = kmalloc(128 * sizeof(u32), GFP_KERNEL);
++	gpr_b = kmalloc(128 * sizeof(u32), GFP_KERNEL);
++	ucode = kmalloc(513 * 5, GFP_KERNEL);
++	if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) {
++		kfree(ucode);
++		kfree(gpr_b);
++		kfree(gpr_a);
++		return 1;
++	}
++
++	per_ctx_regs = 16;
++	if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS)
++		per_ctx_regs = 32;
++
++	memset(gpr_a, 0, sizeof(gpr_a));
++	memset(gpr_b, 0, sizeof(gpr_b));
++	for (i = 0; i < 256; i++) {
++		struct ixp2000_reg_value *r = c->initial_reg_values + i;
++		u32 *bank;
++		int inc;
++		int j;
++
++		if (r->reg == -1)
++			break;
++
++		bank = (r->reg & 0x400) ? gpr_b : gpr_a;
++		inc = (r->reg & 0x80) ? 128 : per_ctx_regs;
++
++		j = r->reg & 0x7f;
++		while (j < 128) {
++			bank[j] = r->value;
++			j += inc;
++		}
++	}
++
++	generate_ucode(ucode, gpr_a, gpr_b);
++	ixp2000_uengine_load_microcode(uengine, ucode, 513);
++	ixp2000_uengine_init_context(uengine, 0, 0);
++	ixp2000_uengine_start_contexts(uengine, 0x01);
++	for (i = 0; i < 100; i++) {
++		u32 status;
++
++		status = ixp2000_uengine_csr_read(uengine, ACTIVE_CTX_STS);
++		if (!(status & 0x80000000))
++			break;
++	}
++	ixp2000_uengine_stop_contexts(uengine, 0x01);
++
++	kfree(ucode);
++	kfree(gpr_b);
++	kfree(gpr_a);
++
++	return !!(i == 100);
++}
++
++int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c)
++{
++	int ctx;
++
++	if (!check_ixp_type(c))
++		return 1;
++
++	if (!(ixp2000_uengine_mask & (1 << uengine)))
++		return 1;
++
++	ixp2000_uengine_reset(1 << uengine);
++	ixp2000_uengine_set_mode(uengine, c->uengine_parameters);
++	if (set_initial_registers(uengine, c))
++		return 1;
++	ixp2000_uengine_load_microcode(uengine, c->insns, c->num_insns);
++
++	for (ctx = 0; ctx < 8; ctx++)
++		ixp2000_uengine_init_context(uengine, ctx, 0);
++
++	return 0;
++}
++EXPORT_SYMBOL(ixp2000_uengine_load);
++
++
++static int __init ixp2000_uengine_init(void)
++{
++	int uengine;
++	u32 value;
++
++	/*
++	 * Determine number of microengines present.
++	 */
++	switch ((ixp2000_reg_read(IXP2000_PRODUCT_ID) >> 8) & 0x1fff) {
++	case 0:		/* IXP2800 */
++	case 1:		/* IXP2850 */
++		ixp2000_uengine_mask = 0x00ff00ff;
++		break;
++
++	case 2:		/* IXP2400 */
++		ixp2000_uengine_mask = 0x000f000f;
++		break;
++
++	default:
++		printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n",
++			(unsigned int)ixp2000_reg_read(IXP2000_PRODUCT_ID));
++		ixp2000_uengine_mask = 0x00000000;
++		break;
++	}
++
++	/*
++	 * Reset microengines.
++	 */
++	ixp2000_reg_write(IXP2000_RESET1, ixp2000_uengine_mask);
++	ixp2000_reg_write(IXP2000_RESET1, 0);
++
++	/*
++	 * Synchronise timestamp counters across all microengines.
++	 */
++	value = ixp2000_reg_read(IXP2000_MISC_CONTROL);
++	ixp2000_reg_write(IXP2000_MISC_CONTROL, value & ~0x80);
++	for (uengine = 0; uengine < 32; uengine++) {
++		if (ixp2000_uengine_mask & (1 << uengine)) {
++			ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
++			ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
++		}
++	}
++	ixp2000_reg_write(IXP2000_MISC_CONTROL, value | 0x80);
++
++	return 0;
++}
++
++subsys_initcall(ixp2000_uengine_init);
+diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
+--- a/arch/arm/mach-ixp4xx/common.c
++++ b/arch/arm/mach-ixp4xx/common.c
+@@ -20,6 +20,7 @@
+ #include <linux/serial.h>
+ #include <linux/sched.h>
+ #include <linux/tty.h>
++#include <linux/platform_device.h>
+ #include <linux/serial_core.h>
+ #include <linux/bootmem.h>
+ #include <linux/interrupt.h>
+@@ -44,24 +45,24 @@
+ static struct map_desc ixp4xx_io_desc[] __initdata = {
+ 	{	/* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
+ 		.virtual	= IXP4XX_PERIPHERAL_BASE_VIRT,
+-		.physical	= IXP4XX_PERIPHERAL_BASE_PHYS,
++		.pfn		= __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
+ 		.length		= IXP4XX_PERIPHERAL_REGION_SIZE,
+ 		.type		= MT_DEVICE
+ 	}, {	/* Expansion Bus Config Registers */
+ 		.virtual	= IXP4XX_EXP_CFG_BASE_VIRT,
+-		.physical	= IXP4XX_EXP_CFG_BASE_PHYS,
++		.pfn		= __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
+ 		.length		= IXP4XX_EXP_CFG_REGION_SIZE,
+ 		.type		= MT_DEVICE
+ 	}, {	/* PCI Registers */
+ 		.virtual	= IXP4XX_PCI_CFG_BASE_VIRT,
+-		.physical	= IXP4XX_PCI_CFG_BASE_PHYS,
++		.pfn		= __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
+ 		.length		= IXP4XX_PCI_CFG_REGION_SIZE,
+ 		.type		= MT_DEVICE
+ 	},
+ #ifdef CONFIG_DEBUG_LL
+ 	{	/* Debug UART mapping */
+ 		.virtual	= IXP4XX_DEBUG_UART_BASE_VIRT,
+-		.physical	= IXP4XX_DEBUG_UART_BASE_PHYS,
++		.pfn		= __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS),
+ 		.length		= IXP4XX_DEBUG_UART_REGION_SIZE,
+ 		.type		= MT_DEVICE
+ 	}
+diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
+--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
++++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
+@@ -26,8 +26,17 @@
+       /* This function calls the board specific IRQ initialization function. */
+ 
+ static struct map_desc kev7a400_io_desc[] __initdata = {
+-	{ IO_VIRT,    IO_PHYS,    IO_SIZE,    MT_DEVICE },
+-	{ CPLD_VIRT,  CPLD_PHYS,  CPLD_SIZE,  MT_DEVICE },
++	{
++		.virtual	= IO_VIRT,
++		.pfn		= __phys_to_pfn(IO_PHYS),
++		.length		= IO_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD_VIRT,
++		.pfn		= __phys_to_pfn(CPLD_PHYS),
++		.length		= CPLD_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init kev7a400_map_io(void)
+diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
++++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+@@ -10,7 +10,7 @@
+ 
+ #include <linux/tty.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ 
+ #include <asm/hardware.h>
+@@ -227,23 +227,79 @@ void __init lh7a40x_init_board_irq (void
+ }
+ 
+ static struct map_desc lpd7a400_io_desc[] __initdata = {
+-	{     IO_VIRT,	    IO_PHYS,	    IO_SIZE,	MT_DEVICE },
+-	/* Mapping added to work around chip select problems */
+-	{ IOBARRIER_VIRT, IOBARRIER_PHYS, IOBARRIER_SIZE, MT_DEVICE },
+-	{ CF_VIRT,	CF_PHYS,	CF_SIZE,	MT_DEVICE },
++	{
++		.virtual	=     IO_VIRT,
++		.pfn		= __phys_to_pfn(IO_PHYS),
++		.length		= 	    IO_SIZE,
++		.type		= MT_DEVICE
++	}, {	/* Mapping added to work around chip select problems */
++		.virtual	= IOBARRIER_VIRT,
++		.pfn		= __phys_to_pfn(IOBARRIER_PHYS),
++		.length		= IOBARRIER_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CF_VIRT,
++		.pfn		= __phys_to_pfn(CF_PHYS),
++		.length		= 	CF_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD02_VIRT,
++		.pfn		= __phys_to_pfn(CPLD02_PHYS),
++		.length		= 	CPLD02_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD06_VIRT,
++		.pfn		= __phys_to_pfn(CPLD06_PHYS),
++		.length		= 	CPLD06_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD08_VIRT,
++		.pfn		= __phys_to_pfn(CPLD08_PHYS),
++		.length		= 	CPLD08_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD0C_VIRT,
++		.pfn		= __phys_to_pfn(CPLD0C_PHYS),
++		.length		= 	CPLD0C_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD0E_VIRT,
++		.pfn		= __phys_to_pfn(CPLD0E_PHYS),
++		.length		= 	CPLD0E_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD10_VIRT,
++		.pfn		= __phys_to_pfn(CPLD10_PHYS),
++		.length		= 	CPLD10_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD12_VIRT,
++		.pfn		= __phys_to_pfn(CPLD12_PHYS),
++		.length		= 	CPLD12_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD14_VIRT,
++		.pfn		= __phys_to_pfn(CPLD14_PHYS),
++		.length		= 	CPLD14_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD16_VIRT,
++		.pfn		= __phys_to_pfn(CPLD16_PHYS),
++		.length		= 	CPLD16_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD18_VIRT,
++		.pfn		= __phys_to_pfn(CPLD18_PHYS),
++		.length		= 	CPLD18_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= CPLD1A_VIRT,
++		.pfn		= __phys_to_pfn(CPLD1A_PHYS),
++		.length		= 	CPLD1A_SIZE,
++		.type		= MT_DEVICE
++	},
+ 	/* This mapping is redundant since the smc driver performs another. */
+ /*	{ CPLD00_VIRT,  CPLD00_PHYS,	CPLD00_SIZE,	MT_DEVICE }, */
+-	{ CPLD02_VIRT,  CPLD02_PHYS,	CPLD02_SIZE,	MT_DEVICE },
+-	{ CPLD06_VIRT,  CPLD06_PHYS,	CPLD06_SIZE,	MT_DEVICE },
+-	{ CPLD08_VIRT,	CPLD08_PHYS,	CPLD08_SIZE,	MT_DEVICE },
+-	{ CPLD0C_VIRT,	CPLD0C_PHYS,	CPLD0C_SIZE,	MT_DEVICE },
+-	{ CPLD0E_VIRT,	CPLD0E_PHYS,	CPLD0E_SIZE,	MT_DEVICE },
+-	{ CPLD10_VIRT,	CPLD10_PHYS,	CPLD10_SIZE,	MT_DEVICE },
+-	{ CPLD12_VIRT,	CPLD12_PHYS,	CPLD12_SIZE,	MT_DEVICE },
+-	{ CPLD14_VIRT,	CPLD14_PHYS,	CPLD14_SIZE,	MT_DEVICE },
+-	{ CPLD16_VIRT,	CPLD16_PHYS,	CPLD16_SIZE,	MT_DEVICE },
+-	{ CPLD18_VIRT,	CPLD18_PHYS,	CPLD18_SIZE,	MT_DEVICE },
+-	{ CPLD1A_VIRT,	CPLD1A_PHYS,	CPLD1A_SIZE,	MT_DEVICE },
+ };
+ 
+ void __init
+diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
+--- a/arch/arm/mach-omap1/board-h2.c
++++ b/arch/arm/mach-omap1/board-h2.c
+@@ -21,7 +21,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/delay.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
+--- a/arch/arm/mach-omap1/board-h3.c
++++ b/arch/arm/mach-omap1/board-h3.c
+@@ -19,7 +19,7 @@
+ #include <linux/init.h>
+ #include <linux/major.h>
+ #include <linux/kernel.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/errno.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
+--- a/arch/arm/mach-omap1/board-innovator.c
++++ b/arch/arm/mach-omap1/board-innovator.c
+@@ -18,7 +18,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/delay.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+@@ -103,8 +103,12 @@ static struct platform_device innovator_
+ 
+ /* Only FPGA needs to be mapped here. All others are done with ioremap */
+ static struct map_desc innovator1510_io_desc[] __initdata = {
+-{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE,
+-	MT_DEVICE },
++	{
++		.virtual	= OMAP1510_FPGA_BASE,
++		.pfn		= __phys_to_pfn(OMAP1510_FPGA_START),
++		.length		= OMAP1510_FPGA_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static struct resource innovator1510_smc91x_resources[] = {
+diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
+--- a/arch/arm/mach-omap1/board-netstar.c
++++ b/arch/arm/mach-omap1/board-netstar.c
+@@ -11,7 +11,7 @@
+  */
+ 
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
+--- a/arch/arm/mach-omap1/board-osk.c
++++ b/arch/arm/mach-omap1/board-osk.c
+@@ -28,7 +28,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ 
+ #include <linux/mtd/mtd.h>
+diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
+--- a/arch/arm/mach-omap1/board-perseus2.c
++++ b/arch/arm/mach-omap1/board-perseus2.c
+@@ -13,7 +13,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/delay.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+@@ -134,8 +134,12 @@ void omap_perseus2_init_irq(void)
+ 
+ /* Only FPGA needs to be mapped here. All others are done with ioremap */
+ static struct map_desc omap_perseus2_io_desc[] __initdata = {
+-	{H2P2_DBG_FPGA_BASE, H2P2_DBG_FPGA_START, H2P2_DBG_FPGA_SIZE,
+-	 MT_DEVICE},
++	{
++		.virtual	= H2P2_DBG_FPGA_BASE,
++		.pfn		= __phys_to_pfn(H2P2_DBG_FPGA_START),
++		.length		= H2P2_DBG_FPGA_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init omap_perseus2_map_io(void)
+diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
+--- a/arch/arm/mach-omap1/board-voiceblue.c
++++ b/arch/arm/mach-omap1/board-voiceblue.c
+@@ -13,7 +13,7 @@
+  */
+ 
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
+--- a/arch/arm/mach-omap1/devices.c
++++ b/arch/arm/mach-omap1/devices.c
+@@ -13,7 +13,7 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/io.h>
+diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
+--- a/arch/arm/mach-omap1/io.c
++++ b/arch/arm/mach-omap1/io.c
+@@ -26,27 +26,59 @@ extern void omap_sram_init(void);
+  * default mapping provided here.
+  */
+ static struct map_desc omap_io_desc[] __initdata = {
+- { IO_VIRT,      	IO_PHYS,             IO_SIZE,        	   MT_DEVICE },
++	{
++		.virtual	= IO_VIRT,
++		.pfn		= __phys_to_pfn(IO_PHYS),
++		.length		= IO_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ #ifdef CONFIG_ARCH_OMAP730
+ static struct map_desc omap730_io_desc[] __initdata = {
+- { OMAP730_DSP_BASE,    OMAP730_DSP_START,    OMAP730_DSP_SIZE,    MT_DEVICE },
+- { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
++	{
++		.virtual	= OMAP730_DSP_BASE,
++		.pfn		= __phys_to_pfn(OMAP730_DSP_START),
++		.length		= OMAP730_DSP_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= OMAP730_DSPREG_BASE,
++		.pfn		= __phys_to_pfn(OMAP730_DSPREG_START),
++		.length		= OMAP730_DSPREG_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ #endif
+ 
+ #ifdef CONFIG_ARCH_OMAP1510
+ static struct map_desc omap1510_io_desc[] __initdata = {
+- { OMAP1510_DSP_BASE,    OMAP1510_DSP_START,    OMAP1510_DSP_SIZE,    MT_DEVICE },
+- { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
++	{
++		.virtual	= OMAP1510_DSP_BASE,
++		.pfn		= __phys_to_pfn(OMAP1510_DSP_START),
++		.length		= OMAP1510_DSP_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= OMAP1510_DSPREG_BASE,
++		.pfn		= __phys_to_pfn(OMAP1510_DSPREG_START),
++		.length		= OMAP1510_DSPREG_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ #endif
+ 
+ #if defined(CONFIG_ARCH_OMAP16XX)
+ static struct map_desc omap16xx_io_desc[] __initdata = {
+- { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
+- { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
++	{
++		.virtual	= OMAP16XX_DSP_BASE,
++		.pfn		= __phys_to_pfn(OMAP16XX_DSP_START),
++		.length		= OMAP16XX_DSP_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= OMAP16XX_DSPREG_BASE,
++		.pfn		= __phys_to_pfn(OMAP16XX_DSPREG_START),
++		.length		= OMAP16XX_DSPREG_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ #endif
+ 
+diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
+--- a/arch/arm/mach-pxa/corgi.c
++++ b/arch/arm/mach-pxa/corgi.c
+@@ -14,7 +14,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/major.h>
+ #include <linux/fs.h>
+ #include <linux/interrupt.h>
+@@ -33,6 +33,7 @@
+ 
+ #include <asm/arch/pxa-regs.h>
+ #include <asm/arch/irq.h>
++#include <asm/arch/irda.h>
+ #include <asm/arch/mmc.h>
+ #include <asm/arch/udc.h>
+ #include <asm/arch/corgi.h>
+@@ -224,6 +225,22 @@ static struct pxamci_platform_data corgi
+ };
+ 
+ 
++/*
++ * Irda
++ */
++static void corgi_irda_transceiver_mode(struct device *dev, int mode)
++{
++	if (mode & IR_OFF)
++		GPSR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
++	else
++		GPCR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
++}
++
++static struct pxaficp_platform_data corgi_ficp_platform_data = {
++	.transceiver_cap  = IR_SIRMODE | IR_OFF,
++	.transceiver_mode = corgi_irda_transceiver_mode,
++};
++
+ 
+ /*
+  * USB Device Controller
+@@ -269,10 +286,13 @@ static void __init corgi_init(void)
+ 
+ 	corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
+ 
++	pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT);
+ 	pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
+ 	pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
++
+  	pxa_set_udc_info(&udc_info);
+ 	pxa_set_mci_info(&corgi_mci_platform_data);
++	pxa_set_ficp_info(&corgi_ficp_platform_data);
+ 
+ 	scoop_num = 1;
+ 	scoop_devs = &corgi_pcmcia_scoop[0];
+diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
+--- a/arch/arm/mach-pxa/corgi_lcd.c
++++ b/arch/arm/mach-pxa/corgi_lcd.c
+@@ -17,7 +17,7 @@
+ 
+ #include <linux/delay.h>
+ #include <linux/kernel.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <asm/arch/akita.h>
+ #include <asm/arch/corgi.h>
+diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
+--- a/arch/arm/mach-pxa/corgi_ssp.c
++++ b/arch/arm/mach-pxa/corgi_ssp.c
+@@ -15,7 +15,7 @@
+ #include <linux/sched.h>
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <asm/hardware.h>
+ #include <asm/mach-types.h>
+ 
+@@ -222,24 +222,22 @@ static int corgi_ssp_remove(struct devic
+ 	return 0;
+ }
+ 
+-static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level)
++static int corgi_ssp_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_POWER_DOWN) {
+-		ssp_flush(&corgi_ssp_dev);
+-		ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
+-	}
++	ssp_flush(&corgi_ssp_dev);
++	ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
++
+ 	return 0;
+ }
+ 
+-static int corgi_ssp_resume(struct device *dev, u32 level)
++static int corgi_ssp_resume(struct device *dev)
+ {
+-	if (level == RESUME_POWER_ON) {
+-		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
+-		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
+-		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
+-		ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
+-		ssp_enable(&corgi_ssp_dev);
+-	}
++	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
++	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
++	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
++	ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
++	ssp_enable(&corgi_ssp_dev);
++
+ 	return 0;
+ }
+ 
+diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
+--- a/arch/arm/mach-pxa/generic.c
++++ b/arch/arm/mach-pxa/generic.c
+@@ -20,9 +20,10 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/ioport.h>
+ #include <linux/pm.h>
++#include <linux/string.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+@@ -34,6 +35,7 @@
+ #include <asm/arch/udc.h>
+ #include <asm/arch/pxafb.h>
+ #include <asm/arch/mmc.h>
++#include <asm/arch/irda.h>
+ #include <asm/arch/i2c.h>
+ 
+ #include "generic.h"
+@@ -92,14 +94,42 @@ EXPORT_SYMBOL(pxa_set_cken);
+  *         and cache flush area.
+  */
+ static struct map_desc standard_io_desc[] __initdata = {
+- /* virtual     physical    length      type */
+-  { 0xf2000000, 0x40000000, 0x02000000, MT_DEVICE }, /* Devs */
+-  { 0xf4000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */
+-  { 0xf6000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */
+-  { 0xf8000000, 0x4c000000, 0x00100000, MT_DEVICE }, /* USB host */
+-  { 0xfa000000, 0x50000000, 0x00100000, MT_DEVICE }, /* Camera */
+-  { 0xfe000000, 0x58000000, 0x00100000, MT_DEVICE }, /* IMem ctl */
+-  { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE }  /* UNCACHED_PHYS_0 */
++  	{	/* Devs */
++		.virtual	=  0xf2000000,
++		.pfn		= __phys_to_pfn(0x40000000),
++		.length		= 0x02000000,
++		.type		= MT_DEVICE
++	}, {	/* LCD */
++		.virtual	=  0xf4000000,
++		.pfn		= __phys_to_pfn(0x44000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* Mem Ctl */
++		.virtual	=  0xf6000000,
++		.pfn		= __phys_to_pfn(0x48000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* USB host */
++		.virtual	=  0xf8000000,
++		.pfn		= __phys_to_pfn(0x4c000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* Camera */
++		.virtual	=  0xfa000000,
++		.pfn		= __phys_to_pfn(0x50000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* IMem ctl */
++		.virtual	=  0xfe000000,
++		.pfn		= __phys_to_pfn(0x58000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* UNCACHED_PHYS_0 */
++		.virtual	= 0xff000000,
++		.pfn		= __phys_to_pfn(0x00000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init pxa_map_io(void)
+@@ -225,6 +255,10 @@ static struct platform_device stuart_dev
+ 	.name		= "pxa2xx-uart",
+ 	.id		= 2,
+ };
++static struct platform_device hwuart_device = {
++	.name		= "pxa2xx-uart",
++	.id		= 3,
++};
+ 
+ static struct resource i2c_resources[] = {
+ 	{
+@@ -265,10 +299,26 @@ static struct resource i2s_resources[] =
+ static struct platform_device i2s_device = {
+ 	.name		= "pxa2xx-i2s",
+ 	.id		= -1,
+-	.resource	= i2c_resources,
++	.resource	= i2s_resources,
+ 	.num_resources	= ARRAY_SIZE(i2s_resources),
+ };
+ 
++static u64 pxaficp_dmamask = ~(u32)0;
++
++static struct platform_device pxaficp_device = {
++	.name		= "pxa2xx-ir",
++	.id		= -1,
++	.dev		= {
++		.dma_mask = &pxaficp_dmamask,
++		.coherent_dma_mask = 0xffffffff,
++	},
++};
++
++void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
++{
++	pxaficp_device.dev.platform_data = info;
++}
++
+ static struct platform_device *devices[] __initdata = {
+ 	&pxamci_device,
+ 	&udc_device,
+@@ -276,13 +326,26 @@ static struct platform_device *devices[]
+ 	&ffuart_device,
+ 	&btuart_device,
+ 	&stuart_device,
++	&pxaficp_device,
+ 	&i2c_device,
+ 	&i2s_device,
+ };
+ 
+ static int __init pxa_init(void)
+ {
+-	return platform_add_devices(devices, ARRAY_SIZE(devices));
++	int cpuid, ret;
++
++	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
++	if (ret)
++		return ret;
++
++	/* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
++	cpuid = read_cpuid(CPUID_ID);
++	if (((cpuid >> 4) & 0xfff) == 0x2d0 ||
++	    ((cpuid >> 4) & 0xfff) == 0x290)
++		ret = platform_device_register(&hwuart_device);
++
++	return ret;
+ }
+ 
+ subsys_initcall(pxa_init);
+diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
+--- a/arch/arm/mach-pxa/idp.c
++++ b/arch/arm/mach-pxa/idp.c
+@@ -18,7 +18,7 @@
+ 
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/fb.h>
+ 
+ #include <asm/setup.h>
+@@ -152,16 +152,17 @@ static void __init idp_init_irq(void)
+ }
+ 
+ static struct map_desc idp_io_desc[] __initdata = {
+- /* virtual     physical    length      type */
+-
+-  { IDP_COREVOLT_VIRT,
+-    IDP_COREVOLT_PHYS,
+-    IDP_COREVOLT_SIZE,
+-    MT_DEVICE },
+-  { IDP_CPLD_VIRT,
+-    IDP_CPLD_PHYS,
+-    IDP_CPLD_SIZE,
+-    MT_DEVICE }
++  	{
++		.virtual	=  IDP_COREVOLT_VIRT,
++		.pfn		= __phys_to_pfn(IDP_COREVOLT_PHYS),
++		.length		= IDP_COREVOLT_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	=  IDP_CPLD_VIRT,
++		.pfn		= __phys_to_pfn(IDP_CPLD_PHYS),
++		.length		= IDP_CPLD_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init idp_map_io(void)
+diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
+--- a/arch/arm/mach-pxa/lubbock.c
++++ b/arch/arm/mach-pxa/lubbock.c
+@@ -14,7 +14,7 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/sysdev.h>
+ #include <linux/major.h>
+ #include <linux/fb.h>
+@@ -35,6 +35,7 @@
+ #include <asm/arch/pxa-regs.h>
+ #include <asm/arch/lubbock.h>
+ #include <asm/arch/udc.h>
++#include <asm/arch/irda.h>
+ #include <asm/arch/pxafb.h>
+ #include <asm/arch/mmc.h>
+ 
+@@ -174,7 +175,7 @@ static struct platform_device sa1111_dev
+ static struct resource smc91x_resources[] = {
+ 	[0] = {
+ 		.name	= "smc91x-regs",
+-		.start	= 0x0c000000,
++		.start	= 0x0c000c00,
+ 		.end	= 0x0c0fffff,
+ 		.flags	= IORESOURCE_MEM,
+ 	},
+@@ -223,18 +224,93 @@ static struct pxafb_mach_info sharp_lm8v
+ 	.lccr3		= LCCR3_PCP | LCCR3_Acb(255),
+ };
+ 
+-static int lubbock_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data)
++#define	MMC_POLL_RATE		msecs_to_jiffies(1000)
++
++static void lubbock_mmc_poll(unsigned long);
++static irqreturn_t (*mmc_detect_int)(int, void *, struct pt_regs *);
++
++static struct timer_list mmc_timer = {
++	.function	= lubbock_mmc_poll,
++};
++
++static void lubbock_mmc_poll(unsigned long data)
++{
++	unsigned long flags;
++
++	/* clear any previous irq state, then ... */
++	local_irq_save(flags);
++	LUB_IRQ_SET_CLR &= ~(1 << 0);
++	local_irq_restore(flags);
++
++	/* poll until mmc/sd card is removed */
++	if (LUB_IRQ_SET_CLR & (1 << 0))
++		mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
++	else {
++		(void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data, NULL);
++		enable_irq(LUBBOCK_SD_IRQ);
++	}
++}
++
++static irqreturn_t lubbock_detect_int(int irq, void *data, struct pt_regs *regs)
++{
++	/* IRQ is level triggered; disable, and poll for removal */
++	disable_irq(irq);
++	mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
++
++	return mmc_detect_int(irq, data, regs);
++}
++
++static int lubbock_mci_init(struct device *dev,
++		irqreturn_t (*detect_int)(int, void *, struct pt_regs *),
++		void *data)
+ {
+ 	/* setup GPIO for PXA25x MMC controller	*/
+ 	pxa_gpio_mode(GPIO6_MMCCLK_MD);
+ 	pxa_gpio_mode(GPIO8_MMCCS0_MD);
+ 
+-	return 0;
++	/* detect card insert/eject */
++	mmc_detect_int = detect_int;
++	init_timer(&mmc_timer);
++	mmc_timer.data = (unsigned long) data;
++	return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
++			SA_SAMPLE_RANDOM, "lubbock-sd-detect", data);
++}
++
++static int lubbock_mci_get_ro(struct device *dev)
++{
++	return (LUB_MISC_RD & (1 << 2)) != 0;
++}
++
++static void lubbock_mci_exit(struct device *dev, void *data)
++{
++	free_irq(LUBBOCK_SD_IRQ, data);
++	del_timer_sync(&mmc_timer);
+ }
+ 
+ static struct pxamci_platform_data lubbock_mci_platform_data = {
+ 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
++	.detect_delay	= 1,
+ 	.init 		= lubbock_mci_init,
++	.get_ro		= lubbock_mci_get_ro,
++	.exit 		= lubbock_mci_exit,
++};
++
++static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++	if (mode & IR_SIRMODE) {
++		LUB_MISC_WR &= ~(1 << 4);
++	} else if (mode & IR_FIRMODE) {
++		LUB_MISC_WR |= 1 << 4;
++	}
++	local_irq_restore(flags);
++}
++
++static struct pxaficp_platform_data lubbock_ficp_platform_data = {
++	.transceiver_cap  = IR_SIRMODE | IR_FIRMODE,
++	.transceiver_mode = lubbock_irda_transceiver_mode,
+ };
+ 
+ static void __init lubbock_init(void)
+@@ -242,11 +318,17 @@ static void __init lubbock_init(void)
+ 	pxa_set_udc_info(&udc_info);
+ 	set_pxa_fb_info(&sharp_lm8v31);
+ 	pxa_set_mci_info(&lubbock_mci_platform_data);
++	pxa_set_ficp_info(&lubbock_ficp_platform_data);
+ 	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+ 
+ static struct map_desc lubbock_io_desc[] __initdata = {
+-  { LUBBOCK_FPGA_VIRT, LUBBOCK_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */
++  	{	/* CPLD */
++		.virtual	=  LUBBOCK_FPGA_VIRT,
++		.pfn		= __phys_to_pfn(LUBBOCK_FPGA_PHYS),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init lubbock_map_io(void)
+diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
+--- a/arch/arm/mach-pxa/mainstone.c
++++ b/arch/arm/mach-pxa/mainstone.c
+@@ -14,7 +14,7 @@
+  */
+ 
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/sysdev.h>
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
+@@ -37,6 +37,7 @@
+ #include <asm/arch/audio.h>
+ #include <asm/arch/pxafb.h>
+ #include <asm/arch/mmc.h>
++#include <asm/arch/irda.h>
+ 
+ #include "generic.h"
+ 
+@@ -294,6 +295,29 @@ static struct pxamci_platform_data mains
+ 	.exit		= mainstone_mci_exit,
+ };
+ 
++static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++	if (mode & IR_SIRMODE) {
++		MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR;
++	} else if (mode & IR_FIRMODE) {
++		MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
++	}
++	if (mode & IR_OFF) {
++		MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
++	} else {
++		MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL;
++	}
++	local_irq_restore(flags);
++}
++
++static struct pxaficp_platform_data mainstone_ficp_platform_data = {
++	.transceiver_cap  = IR_SIRMODE | IR_FIRMODE | IR_OFF,
++	.transceiver_mode = mainstone_irda_transceiver_mode,
++};
++
+ static void __init mainstone_init(void)
+ {
+ 	/*
+@@ -313,11 +337,17 @@ static void __init mainstone_init(void)
+ 		set_pxa_fb_info(&toshiba_ltm035a776c);
+ 
+ 	pxa_set_mci_info(&mainstone_mci_platform_data);
++	pxa_set_ficp_info(&mainstone_ficp_platform_data);
+ }
+ 
+ 
+ static struct map_desc mainstone_io_desc[] __initdata = {
+-  { MST_FPGA_VIRT, MST_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */
++  	{	/* CPLD */
++		.virtual	=  MST_FPGA_VIRT,
++		.pfn		= __phys_to_pfn(MST_FPGA_PHYS),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init mainstone_map_io(void)
+diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
+--- a/arch/arm/mach-pxa/poodle.c
++++ b/arch/arm/mach-pxa/poodle.c
+@@ -16,7 +16,7 @@
+  */
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/fb.h>
+ 
+ #include <asm/hardware.h>
+@@ -32,6 +32,7 @@
+ #include <asm/arch/irq.h>
+ #include <asm/arch/mmc.h>
+ #include <asm/arch/udc.h>
++#include <asm/arch/irda.h>
+ #include <asm/arch/poodle.h>
+ #include <asm/arch/pxafb.h>
+ 
+@@ -152,6 +153,24 @@ static struct pxamci_platform_data poodl
+ 
+ 
+ /*
++ * Irda
++ */
++static void poodle_irda_transceiver_mode(struct device *dev, int mode)
++{
++	if (mode & IR_OFF) {
++		GPSR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
++	} else {
++		GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
++	}
++}
++
++static struct pxaficp_platform_data poodle_ficp_platform_data = {
++	.transceiver_cap  = IR_SIRMODE | IR_OFF,
++	.transceiver_mode = poodle_irda_transceiver_mode,
++};
++
++
++/*
+  * USB Device Controller
+  */
+ static void poodle_udc_command(int cmd)
+@@ -244,8 +263,10 @@ static void __init poodle_init(void)
+ 
+ 	set_pxa_fb_info(&poodle_fb_info);
+ 	pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
++	pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT);
+ 	pxa_set_udc_info(&udc_info);
+ 	pxa_set_mci_info(&poodle_mci_platform_data);
++	pxa_set_ficp_info(&poodle_ficp_platform_data);
+ 
+ 	scoop_num = 1;
+ 	scoop_devs = &poodle_pcmcia_scoop[0];
+diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
+--- a/arch/arm/mach-pxa/pxa25x.c
++++ b/arch/arm/mach-pxa/pxa25x.c
+@@ -129,7 +129,7 @@ void pxa_cpu_pm_enter(suspend_state_t st
+ 	case PM_SUSPEND_MEM:
+ 		/* set resume return address */
+ 		PSPR = virt_to_phys(pxa_cpu_resume);
+-		pxa_cpu_suspend(3);
++		pxa_cpu_suspend(PWRMODE_SLEEP);
+ 		break;
+ 	}
+ }
+diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
+--- a/arch/arm/mach-pxa/pxa27x.c
++++ b/arch/arm/mach-pxa/pxa27x.c
+@@ -16,7 +16,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/pm.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+@@ -157,7 +157,7 @@ void pxa_cpu_pm_enter(suspend_state_t st
+ 	case PM_SUSPEND_MEM:
+ 		/* set resume return address */
+ 		PSPR = virt_to_phys(pxa_cpu_resume);
+-		pxa_cpu_suspend(3);
++		pxa_cpu_suspend(PWRMODE_SLEEP);
+ 		break;
+ 	}
+ }
+diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
+--- a/arch/arm/mach-pxa/sleep.S
++++ b/arch/arm/mach-pxa/sleep.S
+@@ -28,7 +28,9 @@
+ /*
+  * pxa_cpu_suspend()
+  *
+- * Forces CPU into sleep state
++ * Forces CPU into sleep state.
++ *
++ * r0 = value for PWRMODE M field for desired sleep state
+  */
+ 
+ ENTRY(pxa_cpu_suspend)
+@@ -53,6 +55,7 @@ ENTRY(pxa_cpu_suspend)
+ 	mov	r10, sp
+ 	stmfd	sp!, {r3 - r10}
+ 
++	mov r5, r0				@ save sleep mode
+ 	@ preserve phys address of stack
+ 	mov	r0, sp
+ 	bl	sleep_phys_sp
+@@ -66,7 +69,7 @@ ENTRY(pxa_cpu_suspend)
+ 	@ (also workaround for sighting 28071)
+ 
+ 	@ prepare value for sleep mode
+-	mov	r1, #3				@ sleep mode
++	mov	r1, r5				@ sleep mode
+ 
+ 	@ prepare pointer to physical address 0 (virtual mapping in generic.c)
+ 	mov	r2, #UNCACHED_PHYS_0
+diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
+--- a/arch/arm/mach-pxa/spitz.c
++++ b/arch/arm/mach-pxa/spitz.c
+@@ -14,7 +14,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/delay.h>
+ #include <linux/major.h>
+ #include <linux/fs.h>
+@@ -34,6 +34,7 @@
+ 
+ #include <asm/arch/pxa-regs.h>
+ #include <asm/arch/irq.h>
++#include <asm/arch/irda.h>
+ #include <asm/arch/mmc.h>
+ #include <asm/arch/udc.h>
+ #include <asm/arch/pxafb.h>
+@@ -277,6 +278,23 @@ static struct pxamci_platform_data spitz
+ 
+ 
+ /*
++ * Irda
++ */
++static void spitz_irda_transceiver_mode(struct device *dev, int mode)
++{
++	if (mode & IR_OFF)
++		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
++	else
++		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
++}
++
++static struct pxaficp_platform_data spitz_ficp_platform_data = {
++	.transceiver_cap  = IR_SIRMODE | IR_OFF,
++	.transceiver_mode = spitz_irda_transceiver_mode,
++};
++
++
++/*
+  * Spitz PXA Framebuffer
+  */
+ static struct pxafb_mach_info spitz_pxafb_info __initdata = {
+@@ -326,6 +344,7 @@ static void __init common_init(void)
+ 
+ 	platform_add_devices(devices, ARRAY_SIZE(devices));
+ 	pxa_set_mci_info(&spitz_mci_platform_data);
++	pxa_set_ficp_info(&spitz_ficp_platform_data);
+ 	set_pxa_fb_parent(&spitzssp_device.dev);
+ 	set_pxa_fb_info(&spitz_pxafb_info);
+ }
+diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
+--- a/arch/arm/mach-pxa/standby.S
++++ b/arch/arm/mach-pxa/standby.S
+@@ -21,7 +21,7 @@
+ ENTRY(pxa_cpu_standby)
+ 	ldr	r0, =PSSR
+ 	mov	r1, #(PSSR_PH | PSSR_STS)
+-	mov	r2, #2
++	mov	r2, #PWRMODE_STANDBY
+ 	mov	r3, #UNCACHED_PHYS_0	@ Read mem context in.
+ 	ldr	ip, [r3]
+ 	b	1f
+diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-realview/Kconfig
+@@ -0,0 +1,11 @@
++menu "RealView platform type"
++	depends on ARCH_REALVIEW
++
++config MACH_REALVIEW_EB
++	bool "Support RealView/EB platform"
++	default n
++	select ARM_GIC
++	help
++	  Include support for the ARM(R) RealView Emulation Baseboard platform.
++
++endmenu
+diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-realview/Makefile
+@@ -0,0 +1,6 @@
++#
++# Makefile for the linux kernel.
++#
++
++obj-y					:= core.o clock.o
++obj-$(CONFIG_MACH_REALVIEW_EB)		+= realview_eb.o
+diff --git a/arch/arm/mach-realview/Makefile.boot b/arch/arm/mach-realview/Makefile.boot
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-realview/Makefile.boot
+@@ -0,0 +1,4 @@
++   zreladdr-y	:= 0x00008000
++params_phys-y	:= 0x00000100
++initrd_phys-y	:= 0x00800000
++
+diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-realview/clock.c
+@@ -0,0 +1,145 @@
++/*
++ *  linux/arch/arm/mach-realview/clock.c
++ *
++ *  Copyright (C) 2004 ARM Limited.
++ *  Written by Deep Blue Solutions Limited.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/errno.h>
++#include <linux/err.h>
++
++#include <asm/semaphore.h>
++#include <asm/hardware/clock.h>
++#include <asm/hardware/icst307.h>
++
++#include "clock.h"
++
++static LIST_HEAD(clocks);
++static DECLARE_MUTEX(clocks_sem);
++
++struct clk *clk_get(struct device *dev, const char *id)
++{
++	struct clk *p, *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;
++
++	if (clk->setvco) {
++		struct icst307_vco vco;
++
++		vco = icst307_khz_to_vco(clk->params, rate / 1000);
++		clk->rate = icst307_khz(clk->params, vco) * 1000;
++
++		printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
++			clk->name, vco.s, vco.r, vco.v);
++
++		clk->setvco(clk, vco);
++		ret = 0;
++	}
++	return ret;
++}
++EXPORT_SYMBOL(clk_set_rate);
++
++/*
++ * 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,
++};
++
++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(&kmi_clk);
++	clk_register(&uart_clk);
++	clk_register(&mmci_clk);
++	return 0;
++}
++arch_initcall(clk_init);
+diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-realview/clock.h
+@@ -0,0 +1,25 @@
++/*
++ *  linux/arch/arm/mach-realview/clock.h
++ *
++ *  Copyright (C) 2004 ARM Limited.
++ *  Written by Deep Blue Solutions Limited.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++struct module;
++struct icst307_params;
++
++struct clk {
++	struct list_head	node;
++	unsigned long		rate;
++	struct module		*owner;
++	const char		*name;
++	const struct icst307_params *params;
++	void			*data;
++	void			(*setvco)(struct clk *, struct icst307_vco vco);
++};
++
++int clk_register(struct clk *clk);
++void clk_unregister(struct clk *clk);
+diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-realview/core.c
+@@ -0,0 +1,605 @@
++/*
++ *  linux/arch/arm/mach-realview/core.c
++ *
++ *  Copyright (C) 1999 - 2003 ARM Limited
++ *  Copyright (C) 2000 Deep Blue Solutions Ltd
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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/config.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/sysdev.h>
++#include <linux/interrupt.h>
++
++#include <asm/system.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/leds.h>
++#include <asm/mach-types.h>
++#include <asm/hardware/amba.h>
++#include <asm/hardware/amba_clcd.h>
++#include <asm/hardware/arm_timer.h>
++#include <asm/hardware/icst307.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/flash.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++#include <asm/mach/map.h>
++#include <asm/mach/mmc.h>
++
++#include <asm/hardware/gic.h>
++
++#include "core.h"
++#include "clock.h"
++
++#define REALVIEW_REFCOUNTER	(__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
++
++/*
++ * This is the RealView sched_clock implementation.  This has
++ * a resolution of 41.7ns, and a maximum value of about 179s.
++ */
++unsigned long long sched_clock(void)
++{
++	unsigned long long v;
++
++	v = (unsigned long long)readl(REALVIEW_REFCOUNTER) * 125;
++	do_div(v, 3);
++
++	return v;
++}
++
++
++#define REALVIEW_FLASHCTRL    (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
++
++static int realview_flash_init(void)
++{
++	u32 val;
++
++	val = __raw_readl(REALVIEW_FLASHCTRL);
++	val &= ~REALVIEW_FLASHPROG_FLVPPEN;
++	__raw_writel(val, REALVIEW_FLASHCTRL);
++
++	return 0;
++}
++
++static void realview_flash_exit(void)
++{
++	u32 val;
++
++	val = __raw_readl(REALVIEW_FLASHCTRL);
++	val &= ~REALVIEW_FLASHPROG_FLVPPEN;
++	__raw_writel(val, REALVIEW_FLASHCTRL);
++}
++
++static void realview_flash_set_vpp(int on)
++{
++	u32 val;
++
++	val = __raw_readl(REALVIEW_FLASHCTRL);
++	if (on)
++		val |= REALVIEW_FLASHPROG_FLVPPEN;
++	else
++		val &= ~REALVIEW_FLASHPROG_FLVPPEN;
++	__raw_writel(val, REALVIEW_FLASHCTRL);
++}
++
++static struct flash_platform_data realview_flash_data = {
++	.map_name		= "cfi_probe",
++	.width			= 4,
++	.init			= realview_flash_init,
++	.exit			= realview_flash_exit,
++	.set_vpp		= realview_flash_set_vpp,
++};
++
++static struct resource realview_flash_resource = {
++	.start			= REALVIEW_FLASH_BASE,
++	.end			= REALVIEW_FLASH_BASE + REALVIEW_FLASH_SIZE,
++	.flags			= IORESOURCE_MEM,
++};
++
++struct platform_device realview_flash_device = {
++	.name			= "armflash",
++	.id			= 0,
++	.dev			= {
++		.platform_data	= &realview_flash_data,
++	},
++	.num_resources		= 1,
++	.resource		= &realview_flash_resource,
++};
++
++static struct resource realview_smc91x_resources[] = {
++	[0] = {
++		.start		= REALVIEW_ETH_BASE,
++		.end		= REALVIEW_ETH_BASE + SZ_64K - 1,
++		.flags		= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start		= IRQ_ETH,
++		.end		= IRQ_ETH,
++		.flags		= IORESOURCE_IRQ,
++	},
++};
++
++struct platform_device realview_smc91x_device = {
++	.name		= "smc91x",
++	.id		= 0,
++	.num_resources	= ARRAY_SIZE(realview_smc91x_resources),
++	.resource	= realview_smc91x_resources,
++};
++
++#define REALVIEW_SYSMCI	(__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
++
++static unsigned int realview_mmc_status(struct device *dev)
++{
++	struct amba_device *adev = container_of(dev, struct amba_device, dev);
++	u32 mask;
++
++	if (adev->res.start == REALVIEW_MMCI0_BASE)
++		mask = 1;
++	else
++		mask = 2;
++
++	return readl(REALVIEW_SYSMCI) & mask;
++}
++
++struct mmc_platform_data realview_mmc0_plat_data = {
++	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
++	.status		= realview_mmc_status,
++};
++
++struct mmc_platform_data realview_mmc1_plat_data = {
++	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
++	.status		= realview_mmc_status,
++};
++
++/*
++ * Clock handling
++ */
++static const struct icst307_params realview_oscvco_params = {
++	.ref		= 24000,
++	.vco_max	= 200000,
++	.vd_min		= 4 + 8,
++	.vd_max		= 511 + 8,
++	.rd_min		= 1 + 2,
++	.rd_max		= 127 + 2,
++};
++
++static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
++{
++	void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
++	void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC1_OFFSET;
++	u32 val;
++
++	val = readl(sys_osc) & ~0x7ffff;
++	val |= vco.v | (vco.r << 9) | (vco.s << 16);
++
++	writel(0xa05f, sys_lock);
++	writel(val, sys_osc);
++	writel(0, sys_lock);
++}
++
++struct clk realview_clcd_clk = {
++	.name	= "CLCDCLK",
++	.params	= &realview_oscvco_params,
++	.setvco = realview_oscvco_set,
++};
++
++/*
++ * CLCD support.
++ */
++#define SYS_CLCD_MODE_MASK	(3 << 0)
++#define SYS_CLCD_MODE_888	(0 << 0)
++#define SYS_CLCD_MODE_5551	(1 << 0)
++#define SYS_CLCD_MODE_565_RLSB	(2 << 0)
++#define SYS_CLCD_MODE_565_BLSB	(3 << 0)
++#define SYS_CLCD_NLCDIOON	(1 << 2)
++#define SYS_CLCD_VDDPOSSWITCH	(1 << 3)
++#define SYS_CLCD_PWR3V5SWITCH	(1 << 4)
++#define SYS_CLCD_ID_MASK	(0x1f << 8)
++#define SYS_CLCD_ID_SANYO_3_8	(0x00 << 8)
++#define SYS_CLCD_ID_UNKNOWN_8_4	(0x01 << 8)
++#define SYS_CLCD_ID_EPSON_2_2	(0x02 << 8)
++#define SYS_CLCD_ID_SANYO_2_5	(0x07 << 8)
++#define SYS_CLCD_ID_VGA		(0x1f << 8)
++
++static struct clcd_panel vga = {
++	.mode		= {
++		.name		= "VGA",
++		.refresh	= 60,
++		.xres		= 640,
++		.yres		= 480,
++		.pixclock	= 39721,
++		.left_margin	= 40,
++		.right_margin	= 24,
++		.upper_margin	= 32,
++		.lower_margin	= 11,
++		.hsync_len	= 96,
++		.vsync_len	= 2,
++		.sync		= 0,
++		.vmode		= FB_VMODE_NONINTERLACED,
++	},
++	.width		= -1,
++	.height		= -1,
++	.tim2		= TIM2_BCD | TIM2_IPC,
++	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
++	.bpp		= 16,
++};
++
++static struct clcd_panel sanyo_3_8_in = {
++	.mode		= {
++		.name		= "Sanyo QVGA",
++		.refresh	= 116,
++		.xres		= 320,
++		.yres		= 240,
++		.pixclock	= 100000,
++		.left_margin	= 6,
++		.right_margin	= 6,
++		.upper_margin	= 5,
++		.lower_margin	= 5,
++		.hsync_len	= 6,
++		.vsync_len	= 6,
++		.sync		= 0,
++		.vmode		= FB_VMODE_NONINTERLACED,
++	},
++	.width		= -1,
++	.height		= -1,
++	.tim2		= TIM2_BCD,
++	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
++	.bpp		= 16,
++};
++
++static struct clcd_panel sanyo_2_5_in = {
++	.mode		= {
++		.name		= "Sanyo QVGA Portrait",
++		.refresh	= 116,
++		.xres		= 240,
++		.yres		= 320,
++		.pixclock	= 100000,
++		.left_margin	= 20,
++		.right_margin	= 10,
++		.upper_margin	= 2,
++		.lower_margin	= 2,
++		.hsync_len	= 10,
++		.vsync_len	= 2,
++		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
++		.vmode		= FB_VMODE_NONINTERLACED,
++	},
++	.width		= -1,
++	.height		= -1,
++	.tim2		= TIM2_IVS | TIM2_IHS | TIM2_IPC,
++	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
++	.bpp		= 16,
++};
++
++static struct clcd_panel epson_2_2_in = {
++	.mode		= {
++		.name		= "Epson QCIF",
++		.refresh	= 390,
++		.xres		= 176,
++		.yres		= 220,
++		.pixclock	= 62500,
++		.left_margin	= 3,
++		.right_margin	= 2,
++		.upper_margin	= 1,
++		.lower_margin	= 0,
++		.hsync_len	= 3,
++		.vsync_len	= 2,
++		.sync		= 0,
++		.vmode		= FB_VMODE_NONINTERLACED,
++	},
++	.width		= -1,
++	.height		= -1,
++	.tim2		= TIM2_BCD | TIM2_IPC,
++	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
++	.bpp		= 16,
++};
++
++/*
++ * Detect which LCD panel is connected, and return the appropriate
++ * clcd_panel structure.  Note: we do not have any information on
++ * the required timings for the 8.4in panel, so we presently assume
++ * VGA timings.
++ */
++static struct clcd_panel *realview_clcd_panel(void)
++{
++	void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
++	struct clcd_panel *panel = &vga;
++	u32 val;
++
++	val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
++	if (val == SYS_CLCD_ID_SANYO_3_8)
++		panel = &sanyo_3_8_in;
++	else if (val == SYS_CLCD_ID_SANYO_2_5)
++		panel = &sanyo_2_5_in;
++	else if (val == SYS_CLCD_ID_EPSON_2_2)
++		panel = &epson_2_2_in;
++	else if (val == SYS_CLCD_ID_VGA)
++		panel = &vga;
++	else {
++		printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
++			val);
++		panel = &vga;
++	}
++
++	return panel;
++}
++
++/*
++ * Disable all display connectors on the interface module.
++ */
++static void realview_clcd_disable(struct clcd_fb *fb)
++{
++	void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
++	u32 val;
++
++	val = readl(sys_clcd);
++	val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
++	writel(val, sys_clcd);
++}
++
++/*
++ * Enable the relevant connector on the interface module.
++ */
++static void realview_clcd_enable(struct clcd_fb *fb)
++{
++	void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
++	u32 val;
++
++	val = readl(sys_clcd);
++	val &= ~SYS_CLCD_MODE_MASK;
++
++	switch (fb->fb.var.green.length) {
++	case 5:
++		val |= SYS_CLCD_MODE_5551;
++		break;
++	case 6:
++		val |= SYS_CLCD_MODE_565_RLSB;
++		break;
++	case 8:
++		val |= SYS_CLCD_MODE_888;
++		break;
++	}
++
++	/*
++	 * Set the MUX
++	 */
++	writel(val, sys_clcd);
++
++	/*
++	 * And now enable the PSUs
++	 */
++	val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
++	writel(val, sys_clcd);
++}
++
++static unsigned long framesize = SZ_1M;
++
++static int realview_clcd_setup(struct clcd_fb *fb)
++{
++	dma_addr_t dma;
++
++	fb->panel		= realview_clcd_panel();
++
++	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
++						    &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	= framesize;
++
++	return 0;
++}
++
++static int realview_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 realview_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);
++}
++
++struct clcd_board clcd_plat_data = {
++	.name		= "RealView",
++	.check		= clcdfb_check,
++	.decode		= clcdfb_decode,
++	.disable	= realview_clcd_disable,
++	.enable		= realview_clcd_enable,
++	.setup		= realview_clcd_setup,
++	.mmap		= realview_clcd_mmap,
++	.remove		= realview_clcd_remove,
++};
++
++#ifdef CONFIG_LEDS
++#define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
++
++void realview_leds_event(led_event_t ledevt)
++{
++	unsigned long flags;
++	u32 val;
++
++	local_irq_save(flags);
++	val = readl(VA_LEDS_BASE);
++
++	switch (ledevt) {
++	case led_idle_start:
++		val = val & ~REALVIEW_SYS_LED0;
++		break;
++
++	case led_idle_end:
++		val = val | REALVIEW_SYS_LED0;
++		break;
++
++	case led_timer:
++		val = val ^ REALVIEW_SYS_LED1;
++		break;
++
++	case led_halted:
++		val = 0;
++		break;
++
++	default:
++		break;
++	}
++
++	writel(val, VA_LEDS_BASE);
++	local_irq_restore(flags);
++}
++#endif	/* CONFIG_LEDS */
++
++/*
++ * Where is the timer (VA)?
++ */
++#define TIMER0_VA_BASE		 __io_address(REALVIEW_TIMER0_1_BASE)
++#define TIMER1_VA_BASE		(__io_address(REALVIEW_TIMER0_1_BASE) + 0x20)
++#define TIMER2_VA_BASE		 __io_address(REALVIEW_TIMER2_3_BASE)
++#define TIMER3_VA_BASE		(__io_address(REALVIEW_TIMER2_3_BASE) + 0x20)
++
++/*
++ * How long is the timer interval?
++ */
++#define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)
++#if TIMER_INTERVAL >= 0x100000
++#define TIMER_RELOAD	(TIMER_INTERVAL >> 8)
++#define TIMER_DIVISOR	(TIMER_CTRL_DIV256)
++#define TICKS2USECS(x)	(256 * (x) / TICKS_PER_uSEC)
++#elif TIMER_INTERVAL >= 0x10000
++#define TIMER_RELOAD	(TIMER_INTERVAL >> 4)		/* Divide by 16 */
++#define TIMER_DIVISOR	(TIMER_CTRL_DIV16)
++#define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)
++#else
++#define TIMER_RELOAD	(TIMER_INTERVAL)
++#define TIMER_DIVISOR	(TIMER_CTRL_DIV1)
++#define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
++#endif
++
++/*
++ * Returns number of ms since last clock interrupt.  Note that interrupts
++ * will have been disabled by do_gettimeoffset()
++ */
++static unsigned long realview_gettimeoffset(void)
++{
++	unsigned long ticks1, ticks2, status;
++
++	/*
++	 * Get the current number of ticks.  Note that there is a race
++	 * condition between us reading the timer and checking for
++	 * an interrupt.  We get around this by ensuring that the
++	 * counter has not reloaded between our two reads.
++	 */
++	ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
++	do {
++		ticks1 = ticks2;
++		status = __raw_readl(__io_address(REALVIEW_GIC_DIST_BASE + GIC_DIST_PENDING_SET)
++				     + ((IRQ_TIMERINT0_1 >> 5) << 2));
++		ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
++	} while (ticks2 > ticks1);
++
++	/*
++	 * Number of ticks since last interrupt.
++	 */
++	ticks1 = TIMER_RELOAD - ticks2;
++
++	/*
++	 * Interrupt pending?  If so, we've reloaded once already.
++	 *
++	 * FIXME: Need to check this is effectively timer 0 that expires
++	 */
++	if (status & IRQMASK_TIMERINT0_1)
++		ticks1 += TIMER_RELOAD;
++
++	/*
++	 * Convert the ticks to usecs
++	 */
++	return TICKS2USECS(ticks1);
++}
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	write_seqlock(&xtime_lock);
++
++	// ...clear the interrupt
++	writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
++
++	timer_tick(regs);
++
++	write_sequnlock(&xtime_lock);
++
++	return IRQ_HANDLED;
++}
++
++static struct irqaction realview_timer_irq = {
++	.name		= "RealView Timer Tick",
++	.flags		= SA_INTERRUPT | SA_TIMER,
++	.handler	= realview_timer_interrupt,
++};
++
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++static void __init realview_timer_init(void)
++{
++	u32 val;
++
++	/* 
++	 * set clock frequency: 
++	 *	REALVIEW_REFCLK is 32KHz
++	 *	REALVIEW_TIMCLK is 1MHz
++	 */
++	val = readl(__io_address(REALVIEW_SCTL_BASE));
++	writel((REALVIEW_TIMCLK << REALVIEW_TIMER1_EnSel) |
++	       (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) | 
++	       (REALVIEW_TIMCLK << REALVIEW_TIMER3_EnSel) |
++	       (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
++	       __io_address(REALVIEW_SCTL_BASE));
++
++	/*
++	 * Initialise to a known state (all timers off)
++	 */
++	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
++	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
++	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
++	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
++
++	writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
++	writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
++	writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
++	       TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
++
++	/* 
++	 * Make irqs happen for the system timer
++	 */
++	setup_irq(IRQ_TIMERINT0_1, &realview_timer_irq);
++}
++
++struct sys_timer realview_timer = {
++	.init		= realview_timer_init,
++	.offset		= realview_gettimeoffset,
++};
+diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-realview/core.h
+@@ -0,0 +1,118 @@
++/*
++ *  linux/arch/arm/mach-realview/core.h
++ *
++ *  Copyright (C) 2004 ARM Limited
++ *  Copyright (C) 2000 Deep Blue Solutions Ltd
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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_REALVIEW_H
++#define __ASM_ARCH_REALVIEW_H
++
++#include <asm/hardware/amba.h>
++#include <asm/io.h>
++
++#define __io_address(n)		__io(IO_ADDRESS(n))
++
++extern struct sys_timer realview_timer;
++
++#define AMBA_DEVICE(name,busid,base,plat)			\
++static struct amba_device name##_device = {			\
++	.dev		= {					\
++		.coherent_dma_mask = ~0,			\
++		.bus_id	= busid,				\
++		.platform_data = plat,				\
++	},							\
++	.res		= {					\
++		.start	= REALVIEW_##base##_BASE,		\
++		.end	= (REALVIEW_##base##_BASE) + SZ_4K - 1,\
++		.flags	= IORESOURCE_MEM,			\
++	},							\
++	.dma_mask	= ~0,					\
++	.irq		= base##_IRQ,				\
++	/* .dma		= base##_DMA,*/				\
++}
++
++/*
++ * These devices are connected via the core APB bridge
++ */
++#define GPIO2_IRQ	{ IRQ_GPIOINT2, NO_IRQ }
++#define GPIO2_DMA	{ 0, 0 }
++#define GPIO3_IRQ	{ IRQ_GPIOINT3, NO_IRQ }
++#define GPIO3_DMA	{ 0, 0 }
++
++#define AACI_IRQ	{ IRQ_AACI, NO_IRQ }
++#define AACI_DMA	{ 0x80, 0x81 }
++#define MMCI0_IRQ	{ IRQ_MMCI0A,IRQ_MMCI0B }
++#define MMCI0_DMA	{ 0x84, 0 }
++#define KMI0_IRQ	{ IRQ_KMI0, NO_IRQ }
++#define KMI0_DMA	{ 0, 0 }
++#define KMI1_IRQ	{ IRQ_KMI1, NO_IRQ }
++#define KMI1_DMA	{ 0, 0 }
++
++/*
++ * These devices are connected directly to the multi-layer AHB switch
++ */
++#define SMC_IRQ		{ NO_IRQ, NO_IRQ }
++#define SMC_DMA		{ 0, 0 }
++#define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
++#define MPMC_DMA	{ 0, 0 }
++#define CLCD_IRQ	{ IRQ_CLCDINT, NO_IRQ }
++#define CLCD_DMA	{ 0, 0 }
++#define DMAC_IRQ	{ IRQ_DMAINT, NO_IRQ }
++#define DMAC_DMA	{ 0, 0 }
++
++/*
++ * These devices are connected via the core APB bridge
++ */
++#define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
++#define SCTL_DMA	{ 0, 0 }
++#define WATCHDOG_IRQ	{ IRQ_WDOGINT, NO_IRQ }
++#define WATCHDOG_DMA	{ 0, 0 }
++#define GPIO0_IRQ	{ IRQ_GPIOINT0, NO_IRQ }
++#define GPIO0_DMA	{ 0, 0 }
++#define GPIO1_IRQ	{ IRQ_GPIOINT1, NO_IRQ }
++#define GPIO1_DMA	{ 0, 0 }
++#define RTC_IRQ		{ IRQ_RTCINT, NO_IRQ }
++#define RTC_DMA		{ 0, 0 }
++
++/*
++ * These devices are connected via the DMA APB bridge
++ */
++#define SCI_IRQ		{ IRQ_SCIINT, NO_IRQ }
++#define SCI_DMA		{ 7, 6 }
++#define UART0_IRQ	{ IRQ_UARTINT0, NO_IRQ }
++#define UART0_DMA	{ 15, 14 }
++#define UART1_IRQ	{ IRQ_UARTINT1, NO_IRQ }
++#define UART1_DMA	{ 13, 12 }
++#define UART2_IRQ	{ IRQ_UARTINT2, NO_IRQ }
++#define UART2_DMA	{ 11, 10 }
++#define UART3_IRQ	{ IRQ_UART3, NO_IRQ }
++#define UART3_DMA	{ 0x86, 0x87 }
++#define SSP_IRQ		{ IRQ_SSPINT, NO_IRQ }
++#define SSP_DMA		{ 9, 8 }
++
++
++extern struct platform_device realview_flash_device;
++extern struct platform_device realview_smc91x_device;
++extern struct mmc_platform_data realview_mmc0_plat_data;
++extern struct mmc_platform_data realview_mmc1_plat_data;
++extern struct clk realview_clcd_clk;
++extern struct clcd_board clcd_plat_data;
++
++extern void realview_leds_event(led_event_t ledevt);
++
++#endif
+diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
+new file mode 100644
+--- /dev/null
++++ b/arch/arm/mach-realview/realview_eb.c
+@@ -0,0 +1,142 @@
++/*
++ *  linux/arch/arm/mach-realview/realview_eb.c
++ *
++ *  Copyright (C) 2004 ARM Limited
++ *  Copyright (C) 2000 Deep Blue Solutions Ltd
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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/config.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/sysdev.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/leds.h>
++#include <asm/mach-types.h>
++#include <asm/hardware/gic.h>
++#include <asm/hardware/amba.h>
++#include <asm/hardware/icst307.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/mmc.h>
++
++#include <asm/arch/irqs.h>
++
++#include "core.h"
++#include "clock.h"
++
++static struct map_desc realview_eb_io_desc[] __initdata = {
++ { IO_ADDRESS(REALVIEW_SYS_BASE),	REALVIEW_SYS_BASE,	SZ_4K,	MT_DEVICE },
++ { IO_ADDRESS(REALVIEW_GIC_CPU_BASE),	REALVIEW_GIC_CPU_BASE,	SZ_4K,	MT_DEVICE },
++ { IO_ADDRESS(REALVIEW_GIC_DIST_BASE),	REALVIEW_GIC_DIST_BASE,	SZ_4K,	MT_DEVICE },
++ { IO_ADDRESS(REALVIEW_SCTL_BASE),	REALVIEW_SCTL_BASE,	SZ_4K,	MT_DEVICE },
++ { IO_ADDRESS(REALVIEW_TIMER0_1_BASE),	REALVIEW_TIMER0_1_BASE,	SZ_4K,	MT_DEVICE },
++ { IO_ADDRESS(REALVIEW_TIMER2_3_BASE),	REALVIEW_TIMER2_3_BASE,	SZ_4K,	MT_DEVICE },
++#ifdef CONFIG_DEBUG_LL
++ { IO_ADDRESS(REALVIEW_UART0_BASE),	REALVIEW_UART0_BASE,	SZ_4K,	MT_DEVICE },
++#endif
++};
++
++static void __init realview_eb_map_io(void)
++{
++	iotable_init(realview_eb_io_desc, ARRAY_SIZE(realview_eb_io_desc));
++}
++
++/* FPGA Primecells */
++AMBA_DEVICE(aaci,  "fpga:04", AACI,     NULL);
++AMBA_DEVICE(mmc0,  "fpga:05", MMCI0,    &realview_mmc0_plat_data);
++AMBA_DEVICE(kmi0,  "fpga:06", KMI0,     NULL);
++AMBA_DEVICE(kmi1,  "fpga:07", KMI1,     NULL);
++AMBA_DEVICE(uart3, "fpga:09", UART3,    NULL);
++
++/* DevChip Primecells */
++AMBA_DEVICE(smc,   "dev:00",  SMC,      NULL);
++AMBA_DEVICE(clcd,  "dev:20",  CLCD,     &clcd_plat_data);
++AMBA_DEVICE(dmac,  "dev:30",  DMAC,     NULL);
++AMBA_DEVICE(sctl,  "dev:e0",  SCTL,     NULL);
++AMBA_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL);
++AMBA_DEVICE(gpio0, "dev:e4",  GPIO0,    NULL);
++AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    NULL);
++AMBA_DEVICE(gpio2, "dev:e6",  GPIO2,    NULL);
++AMBA_DEVICE(rtc,   "dev:e8",  RTC,      NULL);
++AMBA_DEVICE(sci0,  "dev:f0",  SCI,      NULL);
++AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL);
++AMBA_DEVICE(uart1, "dev:f2",  UART1,    NULL);
++AMBA_DEVICE(uart2, "dev:f3",  UART2,    NULL);
++AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      NULL);
++
++static struct amba_device *amba_devs[] __initdata = {
++	&dmac_device,
++	&uart0_device,
++	&uart1_device,
++	&uart2_device,
++	&uart3_device,
++	&smc_device,
++	&clcd_device,
++	&sctl_device,
++	&wdog_device,
++	&gpio0_device,
++	&gpio1_device,
++	&gpio2_device,
++	&rtc_device,
++	&sci0_device,
++	&ssp0_device,
++	&aaci_device,
++	&mmc0_device,
++	&kmi0_device,
++	&kmi1_device,
++};
++
++static void __init gic_init_irq(void)
++{
++	gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE));
++	gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
++}
++
++static void __init realview_eb_init(void)
++{
++	int i;
++
++	clk_register(&realview_clcd_clk);
++
++	platform_device_register(&realview_flash_device);
++	platform_device_register(&realview_smc91x_device);
++
++	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
++		struct amba_device *d = amba_devs[i];
++		amba_device_register(d, &iomem_resource);
++	}
++
++#ifdef CONFIG_LEDS
++	leds_event = realview_leds_event;
++#endif
++}
++
++MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
++	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
++	.phys_ram	= 0x00000000,
++	.phys_io	= REALVIEW_UART0_BASE,
++	.io_pg_offst	= (IO_ADDRESS(REALVIEW_UART0_BASE) >> 18) & 0xfffc,
++	.boot_params	= 0x00000100,
++	.map_io		= realview_eb_map_io,
++	.init_irq	= gic_init_irq,
++	.timer		= &realview_timer,
++	.init_machine	= realview_eb_init,
++MACHINE_END
+diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
+--- a/arch/arm/mach-rpc/riscpc.c
++++ b/arch/arm/mach-rpc/riscpc.c
+@@ -61,9 +61,22 @@ static int __init parse_tag_acorn(const 
+ __tagtable(ATAG_ACORN, parse_tag_acorn);
+ 
+ static struct map_desc rpc_io_desc[] __initdata = {
+- { SCREEN_BASE,	SCREEN_START,	2*1048576, MT_DEVICE }, /* VRAM		*/
+- { (u32)IO_BASE, IO_START,	IO_SIZE	 , MT_DEVICE }, /* IO space	*/
+- { EASI_BASE,	EASI_START,	EASI_SIZE, MT_DEVICE }  /* EASI space	*/
++ 	{	/* VRAM		*/
++		.virtual	=  SCREEN_BASE,
++		.pfn		= __phys_to_pfn(SCREEN_START),
++		.length		= 	2*1048576,
++		.type		= MT_DEVICE
++	}, {	/* IO space	*/
++		.virtual	=  (u32)IO_BASE,
++		.pfn		= __phys_to_pfn(IO_START),
++		.length		= 	IO_SIZE	 ,
++		.type		= MT_DEVICE
++	}, {	/* EASI space	*/
++		.virtual	= EASI_BASE,
++		.pfn		= __phys_to_pfn(EASI_START),
++		.length		= EASI_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init rpc_map_io(void)
+diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
+--- a/arch/arm/mach-s3c2410/clock.c
++++ b/arch/arm/mach-s3c2410/clock.c
+@@ -32,7 +32,7 @@
+ #include <linux/list.h>
+ #include <linux/errno.h>
+ #include <linux/err.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/sysdev.h>
+ 
+ #include <linux/interrupt.h>
+diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
+--- a/arch/arm/mach-s3c2410/cpu.c
++++ b/arch/arm/mach-s3c2410/cpu.c
+@@ -26,7 +26,7 @@
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
+--- a/arch/arm/mach-s3c2410/cpu.h
++++ b/arch/arm/mach-s3c2410/cpu.h
+@@ -21,7 +21,7 @@
+ 
+ /* todo - fix when rmk changes iodescs to use `void __iomem *` */
+ 
+-#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, S3C2410_PA_##x, S3C24XX_SZ_##x, MT_DEVICE }
++#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C2410_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
+ 
+ #ifndef MHZ
+ #define MHZ (1000*1000)
+diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
+--- a/arch/arm/mach-s3c2410/devs.c
++++ b/arch/arm/mach-s3c2410/devs.c
+@@ -24,7 +24,7 @@
+ #include <linux/list.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+@@ -47,7 +47,7 @@ struct platform_device *s3c24xx_uart_dev
+ static struct resource s3c_usb_resource[] = {
+ 	[0] = {
+ 		.start = S3C2410_PA_USBHOST,
+-		.end   = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST,
++		.end   = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST - 1,
+ 		.flags = IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+@@ -77,7 +77,7 @@ EXPORT_SYMBOL(s3c_device_usb);
+ static struct resource s3c_lcd_resource[] = {
+ 	[0] = {
+ 		.start = S3C2410_PA_LCD,
+-		.end   = S3C2410_PA_LCD + S3C24XX_SZ_LCD,
++		.end   = S3C2410_PA_LCD + S3C24XX_SZ_LCD - 1,
+ 		.flags = IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+@@ -103,21 +103,25 @@ struct platform_device s3c_device_lcd = 
+ 
+ EXPORT_SYMBOL(s3c_device_lcd);
+ 
+-static struct s3c2410fb_mach_info s3c2410fb_info;
+-
+-void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info)
++void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
+ {
+-	memcpy(&s3c2410fb_info,hard_s3c2410fb_info,sizeof(struct s3c2410fb_mach_info));
+-	s3c_device_lcd.dev.platform_data = &s3c2410fb_info;
++	struct s3c2410fb_mach_info *npd;
++
++	npd = kmalloc(sizeof(*npd), GFP_KERNEL);
++	if (npd) {
++		memcpy(npd, pd, sizeof(*npd));
++		s3c_device_lcd.dev.platform_data = npd;
++	} else {
++		printk(KERN_ERR "no memory for LCD platform data\n");
++	}
+ }
+-EXPORT_SYMBOL(set_s3c2410fb_info);
+ 
+ /* NAND Controller */
+ 
+ static struct resource s3c_nand_resource[] = {
+ 	[0] = {
+ 		.start = S3C2410_PA_NAND,
+-		.end   = S3C2410_PA_NAND + S3C24XX_SZ_NAND,
++		.end   = S3C2410_PA_NAND + S3C24XX_SZ_NAND - 1,
+ 		.flags = IORESOURCE_MEM,
+ 	}
+ };
+@@ -136,7 +140,7 @@ EXPORT_SYMBOL(s3c_device_nand);
+ static struct resource s3c_usbgadget_resource[] = {
+ 	[0] = {
+ 		.start = S3C2410_PA_USBDEV,
+-		.end   = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV,
++		.end   = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
+ 		.flags = IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+@@ -161,7 +165,7 @@ EXPORT_SYMBOL(s3c_device_usbgadget);
+ static struct resource s3c_wdt_resource[] = {
+ 	[0] = {
+ 		.start = S3C2410_PA_WATCHDOG,
+-		.end   = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG,
++		.end   = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
+ 		.flags = IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+@@ -186,7 +190,7 @@ EXPORT_SYMBOL(s3c_device_wdt);
+ static struct resource s3c_i2c_resource[] = {
+ 	[0] = {
+ 		.start = S3C2410_PA_IIC,
+-		.end   = S3C2410_PA_IIC + S3C24XX_SZ_IIC,
++		.end   = S3C2410_PA_IIC + S3C24XX_SZ_IIC - 1,
+ 		.flags = IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+@@ -211,7 +215,7 @@ EXPORT_SYMBOL(s3c_device_i2c);
+ static struct resource s3c_iis_resource[] = {
+ 	[0] = {
+ 		.start = S3C2410_PA_IIS,
+-		.end   = S3C2410_PA_IIS + S3C24XX_SZ_IIS,
++		.end   = S3C2410_PA_IIS + S3C24XX_SZ_IIS -1,
+ 		.flags = IORESOURCE_MEM,
+ 	}
+ };
+@@ -265,7 +269,7 @@ EXPORT_SYMBOL(s3c_device_rtc);
+ static struct resource s3c_adc_resource[] = {
+ 	[0] = {
+ 		.start = S3C2410_PA_ADC,
+-		.end   = S3C2410_PA_ADC + S3C24XX_SZ_ADC,
++		.end   = S3C2410_PA_ADC + S3C24XX_SZ_ADC - 1,
+ 		.flags = IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+@@ -288,7 +292,7 @@ struct platform_device s3c_device_adc = 
+ static struct resource s3c_sdi_resource[] = {
+ 	[0] = {
+ 		.start = S3C2410_PA_SDI,
+-		.end   = S3C2410_PA_SDI + S3C24XX_SZ_SDI,
++		.end   = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1,
+ 		.flags = IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+@@ -465,7 +469,7 @@ EXPORT_SYMBOL(s3c_device_timer3);
+ static struct resource s3c_camif_resource[] = {
+ 	[0] = {
+ 		.start = S3C2440_PA_CAMIF,
+-		.end   = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF,
++		.end   = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1,
+ 		.flags = IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h
+--- a/arch/arm/mach-s3c2410/devs.h
++++ b/arch/arm/mach-s3c2410/devs.h
+@@ -15,6 +15,7 @@
+  *	10-Feb-2005 BJD	 Added camera from guillaume.gourat at nexvision.tv
+ */
+ #include <linux/config.h>
++#include <linux/platform_device.h>
+ 
+ extern struct platform_device *s3c24xx_uart_devs[];
+ 
+diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
+--- a/arch/arm/mach-s3c2410/gpio.c
++++ b/arch/arm/mach-s3c2410/gpio.c
+@@ -30,6 +30,7 @@
+  *	04-Oct-2004  BJD  Added irq filter controls for GPIO
+  *	05-Nov-2004  BJD  EXPORT_SYMBOL() added for all code
+  *	13-Mar-2005  BJD  Updates for __iomem
++ *	26-Oct-2005  BJD  Added generic configuration types
+  */
+ 
+ 
+@@ -58,6 +59,27 @@ void s3c2410_gpio_cfgpin(unsigned int pi
+ 		mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
+ 	}
+ 
++	switch (function) {
++	case S3C2410_GPIO_LEAVE:
++		mask = 0;
++		function = 0;
++		break;
++
++	case S3C2410_GPIO_INPUT:
++	case S3C2410_GPIO_OUTPUT:
++	case S3C2410_GPIO_SFN2:
++	case S3C2410_GPIO_SFN3:
++		if (pin < S3C2410_GPIO_BANKB) {
++			function &= 1;
++			function <<= S3C2410_GPIO_OFFSET(pin);
++		} else {
++			function &= 3;
++			function <<= S3C2410_GPIO_OFFSET(pin)*2;
++		}
++	}
++
++	/* modify the specified register wwith IRQs off */
++
+ 	local_irq_save(flags);
+ 
+ 	con  = __raw_readl(base + 0x00);
+diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
+--- a/arch/arm/mach-s3c2410/mach-anubis.c
++++ b/arch/arm/mach-s3c2410/mach-anubis.c
+@@ -21,7 +21,7 @@
+ #include <linux/list.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
+--- a/arch/arm/mach-s3c2410/mach-bast.c
++++ b/arch/arm/mach-s3c2410/mach-bast.c
+@@ -32,6 +32,7 @@
+  *     25-Jul-2005 BJD  Removed ASIX static mappings
+  *     27-Jul-2005 BJD  Ensure maximum frequency of i2c bus
+  *     20-Sep-2005 BJD  Added static to non-exported items
++ *     26-Oct-2005 BJD  Added FB platform data
+ */
+ 
+ #include <linux/kernel.h>
+@@ -40,7 +41,7 @@
+ #include <linux/list.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dm9000.h>
+ 
+ #include <asm/mach/arch.h>
+@@ -61,8 +62,10 @@
+ #include <asm/arch/regs-gpio.h>
+ #include <asm/arch/regs-mem.h>
+ #include <asm/arch/regs-lcd.h>
++
+ #include <asm/arch/nand.h>
+ #include <asm/arch/iic.h>
++#include <asm/arch/fb.h>
+ 
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/nand.h>
+@@ -399,6 +402,38 @@ static struct s3c2410_platform_i2c bast_
+ 	.max_freq	= 130*1000,
+ };
+ 
++
++static struct s3c2410fb_mach_info __initdata bast_lcd_info = {
++	.width		= 640,
++	.height		= 480,
++
++	.xres		= {
++		.min		= 320,
++		.max		= 1024,
++		.defval		= 640,
++	},
++
++	.yres		= {
++		.min		= 240,
++		.max	        = 600,
++		.defval		= 480,
++	},
++
++	.bpp		= {
++		.min		= 4,
++		.max		= 16,
++		.defval		= 8,
++	},
++
++	.regs		= {
++		.lcdcon1	= 0x00000176,
++		.lcdcon2	= 0x1d77c7c2,
++		.lcdcon3	= 0x013a7f13,
++		.lcdcon4	= 0x00000057,
++		.lcdcon5	= 0x00014b02,
++	}
++};
++
+ /* Standard BAST devices */
+ 
+ static struct platform_device *bast_devices[] __initdata = {
+@@ -454,6 +489,10 @@ static void __init bast_map_io(void)
+ 	usb_simtec_init();
+ }
+ 
++static void __init bast_init(void)
++{
++	s3c24xx_fb_set_platdata(&bast_lcd_info);
++}
+ 
+ MACHINE_START(BAST, "Simtec-BAST")
+ 	/* Maintainer: Ben Dooks <ben at simtec.co.uk> */
+@@ -463,5 +502,6 @@ MACHINE_START(BAST, "Simtec-BAST")
+ 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+ 	.map_io		= bast_map_io,
+ 	.init_irq	= s3c24xx_init_irq,
++	.init_machine	= bast_init,
+ 	.timer		= &s3c24xx_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
+--- a/arch/arm/mach-s3c2410/mach-h1940.c
++++ b/arch/arm/mach-s3c2410/mach-h1940.c
+@@ -25,6 +25,7 @@
+  *     14-Jan-2005 BJD  Added clock init
+  *     10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
+  *     20-Sep-2005 BJD  Added static to non-exported items
++ *     26-Oct-2005 BJD  Changed name of fb init call
+ */
+ 
+ #include <linux/kernel.h>
+@@ -33,6 +34,7 @@
+ #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>
+@@ -164,7 +166,7 @@ static void __init h1940_init_irq(void)
+ 
+ static void __init h1940_init(void)
+ {
+-	set_s3c2410fb_info(&h1940_lcdcfg);
++	s3c24xx_fb_set_platdata(&h1940_lcdcfg);
+ }
+ 
+ MACHINE_START(H1940, "IPAQ-H1940")
+diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
+--- a/arch/arm/mach-s3c2410/mach-n30.c
++++ b/arch/arm/mach-s3c2410/mach-n30.c
+@@ -20,7 +20,7 @@
+ #include <linux/timer.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/kthread.h>
+ 
+ #include <asm/mach/arch.h>
+diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
+--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
++++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
+@@ -19,7 +19,7 @@
+ #include <linux/timer.h>
+ #include <linux/init.h>
+ #include <linux/string.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <linux/mtd/map.h>
+ 
+diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
+--- a/arch/arm/mach-s3c2410/mach-otom.c
++++ b/arch/arm/mach-s3c2410/mach-otom.c
+@@ -15,7 +15,7 @@
+ #include <linux/list.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
+--- a/arch/arm/mach-s3c2410/mach-rx3715.c
++++ b/arch/arm/mach-s3c2410/mach-rx3715.c
+@@ -17,6 +17,7 @@
+  *	10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
+  *	14-Mar-2005 BJD  Fixed __iomem warnings
+  *	20-Sep-2005 BJD  Added static to non-exported items
++ *	31-Oct-2005 BJD  Added LCD setup for framebuffer
+ */
+ 
+ #include <linux/kernel.h>
+@@ -27,6 +28,7 @@
+ #include <linux/init.h>
+ #include <linux/tty.h>
+ #include <linux/console.h>
++#include <linux/platform_device.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial.h>
+ 
+@@ -42,6 +44,9 @@
+ 
+ #include <asm/arch/regs-serial.h>
+ #include <asm/arch/regs-gpio.h>
++#include <asm/arch/regs-lcd.h>
++
++#include <asm/arch/fb.h>
+ 
+ #include "clock.h"
+ #include "devs.h"
+@@ -96,6 +101,66 @@ static struct s3c2410_uartcfg rx3715_uar
+ 	}
+ };
+ 
++/* framebuffer lcd controller information */
++
++static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
++	.regs	= {
++		.lcdcon1 =	S3C2410_LCDCON1_TFT16BPP | \
++				S3C2410_LCDCON1_TFT | \
++				S3C2410_LCDCON1_CLKVAL(0x0C),
++
++		.lcdcon2 =	S3C2410_LCDCON2_VBPD(5) | \
++				S3C2410_LCDCON2_LINEVAL(319) | \
++				S3C2410_LCDCON2_VFPD(6) | \
++				S3C2410_LCDCON2_VSPW(2),
++
++		.lcdcon3 =	S3C2410_LCDCON3_HBPD(35) | \
++				S3C2410_LCDCON3_HOZVAL(239) | \
++				S3C2410_LCDCON3_HFPD(35),
++
++		.lcdcon4 =	S3C2410_LCDCON4_MVAL(0) | \
++				S3C2410_LCDCON4_HSPW(7),
++
++		.lcdcon5 =	S3C2410_LCDCON5_INVVLINE |
++				S3C2410_LCDCON5_FRM565 |
++				S3C2410_LCDCON5_HWSWP,
++	},
++
++	.lpcsel =	0xf82,
++
++	.gpccon =	0xaa955699,
++	.gpccon_mask =	0xffc003cc,
++	.gpcup =	0x0000ffff,
++	.gpcup_mask =	0xffffffff,
++
++	.gpdcon =	0xaa95aaa1,
++	.gpdcon_mask =	0xffc0fff0,
++	.gpdup =	0x0000faff,
++	.gpdup_mask =	0xffffffff,
++
++	.fixed_syncs =	1,
++	.width  =	240,
++	.height =	320,
++
++	.xres	= {
++		.min =		240,
++		.max =		240,
++		.defval =	240,
++	},
++
++	.yres	= {
++		.max =		320,
++		.min =		320,
++		.defval	=	320,
++	},
++
++	.bpp	= {
++		.min =		16,
++		.max =		16,
++		.defval =	16,
++	},
++};
++
+ static struct platform_device *rx3715_devices[] __initdata = {
+ 	&s3c_device_usb,
+ 	&s3c_device_lcd,
+@@ -122,14 +187,12 @@ static void __init rx3715_init_irq(void)
+ 	s3c24xx_init_irq();
+ }
+ 
+-#ifdef CONFIG_PM
+ static void __init rx3715_init_machine(void)
+ {
+ 	s3c2410_pm_init();
++	s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
+ }
+-#else
+-#define rx3715_init_machine NULL
+-#endif
++
+ 
+ MACHINE_START(RX3715, "IPAQ-RX3715")
+ 	/* Maintainer: Ben Dooks <ben at fluff.org> */
+diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
+--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
++++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
+@@ -38,6 +38,7 @@
+ #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>
+diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
+--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
++++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
+@@ -19,6 +19,7 @@
+  *	10-Mar-2005 LCVR  Replaced S3C2410_VA by S3C24XX_VA
+  *	14-Mar-2005 BJD	  void __iomem fixes
+  *	20-Sep-2005 BJD   Added static to non-exported items
++ *	26-Oct-2005 BJD   Added framebuffer data
+ */
+ 
+ #include <linux/kernel.h>
+@@ -27,6 +28,7 @@
+ #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>
+@@ -41,7 +43,10 @@
+ //#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 "s3c2440.h"
+@@ -86,6 +91,70 @@ static struct s3c2410_uartcfg smdk2440_u
+ 	}
+ };
+ 
++/* LCD driver info */
++
++static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
++	.regs	= {
++
++		.lcdcon1	= S3C2410_LCDCON1_TFT16BPP |
++				  S3C2410_LCDCON1_TFT |
++				  S3C2410_LCDCON1_CLKVAL(0x04),
++
++		.lcdcon2	= S3C2410_LCDCON2_VBPD(7) |
++				  S3C2410_LCDCON2_LINEVAL(319) |
++				  S3C2410_LCDCON2_VFPD(6) |
++				  S3C2410_LCDCON2_VSPW(3),
++
++		.lcdcon3	= S3C2410_LCDCON3_HBPD(19) |
++				  S3C2410_LCDCON3_HOZVAL(239) |
++				  S3C2410_LCDCON3_HFPD(7),
++
++		.lcdcon4	= S3C2410_LCDCON4_MVAL(0) |
++				  S3C2410_LCDCON4_HSPW(3),
++
++		.lcdcon5	= S3C2410_LCDCON5_FRM565 |
++				  S3C2410_LCDCON5_INVVLINE |
++				  S3C2410_LCDCON5_INVVFRAME |
++				  S3C2410_LCDCON5_PWREN |
++				  S3C2410_LCDCON5_HWSWP,
++	},
++
++#if 0
++	/* currently setup by downloader */
++	.gpccon		= 0xaa940659,
++	.gpccon_mask	= 0xffffffff,
++	.gpcup		= 0x0000ffff,
++	.gpcup_mask	= 0xffffffff,
++	.gpdcon		= 0xaa84aaa0,
++	.gpdcon_mask	= 0xffffffff,
++	.gpdup		= 0x0000faff,
++	.gpdup_mask	= 0xffffffff,
++#endif
++
++	.lpcsel		= ((0xCE6) & ~7) | 1<<4,
++
++	.width		= 240,
++	.height		= 320,
++
++	.xres		= {
++		.min	= 240,
++		.max	= 240,
++		.defval	= 240,
++	},
++
++	.yres		= {
++		.min	= 320,
++		.max	= 320,
++		.defval = 320,
++	},
++
++	.bpp		= {
++		.min	= 16,
++		.max	= 16,
++		.defval = 16,
++	},
++};
++
+ static struct platform_device *smdk2440_devices[] __initdata = {
+ 	&s3c_device_usb,
+ 	&s3c_device_lcd,
+@@ -121,6 +190,8 @@ static void __init smdk2440_machine_init
+ 	s3c2410_gpio_setpin(S3C2410_GPF6, 0);
+ 	s3c2410_gpio_setpin(S3C2410_GPF7, 0);
+ 
++	s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
++
+ 	s3c2410_pm_init();
+ }
+ 
+diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
+--- a/arch/arm/mach-s3c2410/s3c2410.c
++++ b/arch/arm/mach-s3c2410/s3c2410.c
+@@ -27,7 +27,7 @@
+ #include <linux/list.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
+--- a/arch/arm/mach-s3c2410/s3c2440.c
++++ b/arch/arm/mach-s3c2410/s3c2440.c
+@@ -26,7 +26,7 @@
+ #include <linux/list.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/sysdev.h>
+ 
+ #include <asm/mach/arch.h>
+diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
+--- a/arch/arm/mach-sa1100/assabet.c
++++ b/arch/arm/mach-sa1100/assabet.c
+@@ -388,9 +388,17 @@ static struct sa1100_port_fns assabet_po
+ };
+ 
+ static struct map_desc assabet_io_desc[] __initdata = {
+- /* virtual     physical    length      type */
+-  { 0xf1000000, 0x12000000, 0x00100000, MT_DEVICE }, /* Board Control Register */
+-  { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE }  /* MQ200 */
++  	{	/* Board Control Register */
++		.virtual	=  0xf1000000,
++		.pfn		= __phys_to_pfn(0x12000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* MQ200 */
++		.virtual	=  0xf2800000,
++		.pfn		= __phys_to_pfn(0x4b800000),
++		.length		= 0x00800000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init assabet_map_io(void)
+diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
+--- a/arch/arm/mach-sa1100/badge4.c
++++ b/arch/arm/mach-sa1100/badge4.c
+@@ -16,7 +16,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/delay.h>
+ #include <linux/tty.h>
+ #include <linux/mtd/mtd.h>
+@@ -254,10 +254,22 @@ EXPORT_SYMBOL(badge4_set_5V);
+ 
+ 
+ static struct map_desc badge4_io_desc[] __initdata = {
+-  /*  virtual    physical    length    type */
+-  {0xf1000000, 0x08000000, 0x00100000, MT_DEVICE },/* SRAM  bank 1 */
+-  {0xf2000000, 0x10000000, 0x00100000, MT_DEVICE },/* SRAM  bank 2 */
+-  {0xf4000000, 0x48000000, 0x00100000, MT_DEVICE } /* SA-1111      */
++  	{	/* SRAM  bank 1 */
++		.virtual	= 0xf1000000,
++		.pfn		= __phys_to_pfn(0x08000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* SRAM  bank 2 */
++		.virtual	= 0xf2000000,
++		.pfn		= __phys_to_pfn(0x10000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* SA-1111      */
++		.virtual	= 0xf4000000,
++		.pfn		= __phys_to_pfn(0x48000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void
+diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
+--- a/arch/arm/mach-sa1100/cerf.c
++++ b/arch/arm/mach-sa1100/cerf.c
+@@ -14,7 +14,7 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/tty.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+ 
+@@ -100,8 +100,12 @@ static void __init cerf_init_irq(void)
+ }
+ 
+ static struct map_desc cerf_io_desc[] __initdata = {
+-  /* virtual	 physical    length	 type */
+-  { 0xf0000000, 0x08000000, 0x00100000, MT_DEVICE }  /* Crystal Ethernet Chip */
++  	{	/* Crystal Ethernet Chip */
++		.virtual	=  0xf0000000,
++		.pfn		= __phys_to_pfn(0x08000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init cerf_map_io(void)
+diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
+--- a/arch/arm/mach-sa1100/collie.c
++++ b/arch/arm/mach-sa1100/collie.c
+@@ -21,7 +21,7 @@
+ #include <linux/kernel.h>
+ #include <linux/tty.h>
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/timer.h>
+@@ -171,9 +171,17 @@ static void __init collie_init(void)
+ }
+ 
+ static struct map_desc collie_io_desc[] __initdata = {
+-	/* virtual     physical    length      type */
+-	{0xe8000000, 0x00000000, 0x02000000, MT_DEVICE},	/* 32M main flash (cs0) */
+-	{0xea000000, 0x08000000, 0x02000000, MT_DEVICE},	/* 32M boot flash (cs1) */
++	{	/* 32M main flash (cs0) */
++		.virtual	= 0xe8000000,
++		.pfn		= __phys_to_pfn(0x00000000),
++		.length		= 0x02000000,
++		.type		= MT_DEVICE
++	}, {	/* 32M boot flash (cs1) */
++		.virtual	= 0xea000000,
++		.pfn		= __phys_to_pfn(0x08000000),
++		.length		= 0x02000000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init collie_map_io(void)
+diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
+--- a/arch/arm/mach-sa1100/generic.c
++++ b/arch/arm/mach-sa1100/generic.c
+@@ -17,12 +17,15 @@
+ #include <linux/pm.h>
+ #include <linux/cpufreq.h>
+ #include <linux/ioport.h>
++#include <linux/sched.h>	/* just for sched_clock() - funny that */
++#include <linux/platform_device.h>
+ 
+ #include <asm/div64.h>
+ #include <asm/hardware.h>
+ #include <asm/system.h>
+ #include <asm/pgtable.h>
+ #include <asm/mach/map.h>
++#include <asm/mach/flash.h>
+ #include <asm/irq.h>
+ 
+ #include "generic.h"
+@@ -283,6 +286,7 @@ static struct platform_device sa11x0mtd_
+ void sa11x0_set_flash_data(struct flash_platform_data *flash,
+ 			   struct resource *res, int nr)
+ {
++	flash->name = "sa1100";
+ 	sa11x0mtd_device.dev.platform_data = flash;
+ 	sa11x0mtd_device.resource = res;
+ 	sa11x0mtd_device.num_resources = nr;
+@@ -369,11 +373,27 @@ EXPORT_SYMBOL(sa1100fb_lcd_power);
+  */
+ 
+ static struct map_desc standard_io_desc[] __initdata = {
+- /* virtual     physical    length      type */
+-  { 0xf8000000, 0x80000000, 0x00100000, MT_DEVICE }, /* PCM */
+-  { 0xfa000000, 0x90000000, 0x00100000, MT_DEVICE }, /* SCM */
+-  { 0xfc000000, 0xa0000000, 0x00100000, MT_DEVICE }, /* MER */
+-  { 0xfe000000, 0xb0000000, 0x00200000, MT_DEVICE }  /* LCD + DMA */
++  	{	/* PCM */
++		.virtual	=  0xf8000000,
++		.pfn		= __phys_to_pfn(0x80000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* SCM */
++		.virtual	=  0xfa000000,
++		.pfn		= __phys_to_pfn(0x90000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* MER */
++		.virtual	=  0xfc000000,
++		.pfn		= __phys_to_pfn(0xa0000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* LCD + DMA */
++		.virtual	=  0xfe000000,
++		.pfn		= __phys_to_pfn(0xb0000000),
++		.length		= 0x00200000,
++		.type		= MT_DEVICE
++	},
+ };
+ 
+ void __init sa1100_map_io(void)
+diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
+--- a/arch/arm/mach-sa1100/h3600.c
++++ b/arch/arm/mach-sa1100/h3600.c
+@@ -223,10 +223,22 @@ static void h3xxx_lcd_power(int enable)
+ }
+ 
+ static struct map_desc h3600_io_desc[] __initdata = {
+- /* virtual	       physical 	  length      type */
+-  { H3600_BANK_2_VIRT, SA1100_CS2_PHYS,   0x02800000, MT_DEVICE }, /* static memory bank 2  CS#2 */
+-  { H3600_BANK_4_VIRT, SA1100_CS4_PHYS,   0x00800000, MT_DEVICE }, /* static memory bank 4  CS#4 */
+-  { H3600_EGPIO_VIRT,  H3600_EGPIO_PHYS,  0x01000000, MT_DEVICE }, /* EGPIO 0		CS#5 */
++  	{	/* static memory bank 2  CS#2 */
++		.virtual	=  H3600_BANK_2_VIRT,
++		.pfn		= __phys_to_pfn(SA1100_CS2_PHYS),
++		.length		= 0x02800000,
++		.type		= MT_DEVICE
++	}, {	/* static memory bank 4  CS#4 */
++		.virtual	=  H3600_BANK_4_VIRT,
++		.pfn		= __phys_to_pfn(SA1100_CS4_PHYS),
++		.length		= 0x00800000,
++		.type		= MT_DEVICE
++	}, {	/* EGPIO 0		CS#5 */
++		.virtual	=  H3600_EGPIO_VIRT,
++		.pfn		= __phys_to_pfn(H3600_EGPIO_PHYS),
++		.length		= 0x01000000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ /*
+diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
+--- a/arch/arm/mach-sa1100/hackkit.c
++++ b/arch/arm/mach-sa1100/hackkit.c
+@@ -57,8 +57,12 @@ static void hackkit_uart_pm(struct uart_
+  */
+ 
+ static struct map_desc hackkit_io_desc[] __initdata = {
+- /* virtual     physical    length      type */
+-  { 0xe8000000, 0x00000000, 0x01000000, MT_DEVICE } /* Flash bank 0 */
++	{	/* Flash bank 0 */
++		.virtual	=  0xe8000000,
++		.pfn		= __phys_to_pfn(0x00000000),
++		.length		= 0x01000000,
++		.type		= MT_DEVICE
++	},
+ };
+ 
+ static struct sa1100_port_fns hackkit_port_fns __initdata = {
+diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
+--- a/arch/arm/mach-sa1100/jornada720.c
++++ b/arch/arm/mach-sa1100/jornada720.c
+@@ -6,8 +6,10 @@
+ #include <linux/kernel.h>
+ #include <linux/tty.h>
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/ioport.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/hardware/sa1111.h>
+@@ -16,6 +18,7 @@
+ #include <asm/setup.h>
+ 
+ #include <asm/mach/arch.h>
++#include <asm/mach/flash.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/serial_sa1100.h>
+ 
+@@ -81,10 +84,22 @@ static int __init jornada720_init(void)
+ arch_initcall(jornada720_init);
+ 
+ static struct map_desc jornada720_io_desc[] __initdata = {
+- /* virtual     physical    length      type */
+-  { 0xf0000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Epson registers */
+-  { 0xf1000000, 0x48200000, 0x00100000, MT_DEVICE }, /* Epson frame buffer */
+-  { 0xf4000000, 0x40000000, 0x00100000, MT_DEVICE }  /* SA-1111 */
++	{	/* Epson registers */
++		.virtual	=  0xf0000000,
++		.pfn		= __phys_to_pfn(0x48000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* Epson frame buffer */
++		.virtual	=  0xf1000000,
++		.pfn		= __phys_to_pfn(0x48200000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}, {	/* SA-1111 */
++		.virtual	=  0xf4000000,
++		.pfn		= __phys_to_pfn(0x40000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init jornada720_map_io(void)
+@@ -96,6 +111,66 @@ static void __init jornada720_map_io(voi
+ 	sa1100_register_uart(1, 1);
+ }
+ 
++static struct mtd_partition jornada720_partitions[] = {
++	{
++		.name		= "JORNADA720 boot firmware",
++		.size		= 0x00040000,
++		.offset		= 0,
++		.mask_flags	= MTD_WRITEABLE,  /* force read-only */
++	}, {
++		.name		= "JORNADA720 kernel",
++		.size		= 0x000c0000,
++		.offset		= 0x00040000,
++	}, {
++		.name		= "JORNADA720 params",
++		.size		= 0x00040000,
++		.offset		= 0x00100000,
++	}, {
++		.name		= "JORNADA720 initrd",
++		.size		= 0x00100000,
++		.offset		= 0x00140000,
++	}, {
++		.name		= "JORNADA720 root cramfs",
++		.size		= 0x00300000,
++		.offset		= 0x00240000,
++	}, {
++		.name		= "JORNADA720 usr cramfs",
++		.size		= 0x00800000,
++		.offset		= 0x00540000,
++	}, {
++		.name		= "JORNADA720 usr local",
++		.size		= 0,  /* will expand to the end of the flash */
++		.offset		= 0x00d00000,
++	}
++};
++
++static void jornada720_set_vpp(int vpp)
++{
++	if (vpp)
++		PPSR |= 0x80;
++	else
++		PPSR &= ~0x80;
++	PPDR |= 0x80;
++}
++
++static struct flash_platform_data jornada720_flash_data = {
++	.map_name	= "cfi_probe",
++	.set_vpp	= jornada720_set_vpp,
++	.parts		= jornada720_partitions,
++	.nr_parts	= ARRAY_SIZE(jornada720_partitions),
++};
++
++static struct resource jornada720_flash_resource = {
++	.start		= SA1100_CS0_PHYS,
++	.end		= SA1100_CS0_PHYS + SZ_32M - 1,
++	.flags		= IORESOURCE_MEM,
++};
++
++static void __init jornada720_mach_init(void)
++{
++	sa11x0_set_flash_data(&jornada720_flash_data, &jornada720_flash_resource, 1);
++}
++
+ MACHINE_START(JORNADA720, "HP Jornada 720")
+ 	/* Maintainer: Michael Gernoth <michael at gernoth.net> */
+ 	.phys_ram	= 0xc0000000,
+@@ -105,4 +180,5 @@ MACHINE_START(JORNADA720, "HP Jornada 72
+ 	.map_io		= jornada720_map_io,
+ 	.init_irq	= sa1100_init_irq,
+ 	.timer		= &sa1100_timer,
++	.init_machine	= jornada720_mach_init,
+ MACHINE_END
+diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
+--- a/arch/arm/mach-sa1100/lart.c
++++ b/arch/arm/mach-sa1100/lart.c
+@@ -31,9 +31,17 @@ static void __init lart_init(void)
+ }
+ 
+ static struct map_desc lart_io_desc[] __initdata = {
+- /* virtual     physical    length      type */
+-  { 0xe8000000, 0x00000000, 0x00400000, MT_DEVICE }, /* main flash memory */
+-  { 0xec000000, 0x08000000, 0x00400000, MT_DEVICE }  /* main flash, alternative location */
++	{	/* main flash memory */
++		.virtual	=  0xe8000000,
++		.pfn		= __phys_to_pfn(0x00000000),
++		.length		= 0x00400000,
++		.type		= MT_DEVICE
++	}, {	/* main flash, alternative location */
++		.virtual	=  0xec000000,
++		.pfn		= __phys_to_pfn(0x08000000),
++		.length		= 0x00400000,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init lart_map_io(void)
+diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
+--- a/arch/arm/mach-sa1100/neponset.c
++++ b/arch/arm/mach-sa1100/neponset.c
+@@ -8,7 +8,7 @@
+ #include <linux/tty.h>
+ #include <linux/ioport.h>
+ #include <linux/serial_core.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/slab.h>
+ 
+ #include <asm/hardware.h>
+@@ -178,33 +178,27 @@ static int neponset_probe(struct device 
+ /*
+  * LDM power management.
+  */
+-static int neponset_suspend(struct device *dev, pm_message_t state, u32 level)
++static int neponset_suspend(struct device *dev, pm_message_t state)
+ {
+ 	/*
+ 	 * Save state.
+ 	 */
+-	if (level == SUSPEND_SAVE_STATE ||
+-	    level == SUSPEND_DISABLE ||
+-	    level == SUSPEND_POWER_DOWN) {
+-		if (!dev->power.saved_state)
+-			dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
+-		if (!dev->power.saved_state)
+-			return -ENOMEM;
++	if (!dev->power.saved_state)
++		dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
++	if (!dev->power.saved_state)
++		return -ENOMEM;
+ 
+-		*(unsigned int *)dev->power.saved_state = NCR_0;
+-	}
++	*(unsigned int *)dev->power.saved_state = NCR_0;
+ 
+ 	return 0;
+ }
+ 
+-static int neponset_resume(struct device *dev, u32 level)
++static int neponset_resume(struct device *dev)
+ {
+-	if (level == RESUME_RESTORE_STATE || level == RESUME_ENABLE) {
+-		if (dev->power.saved_state) {
+-			NCR_0 = *(unsigned int *)dev->power.saved_state;
+-			kfree(dev->power.saved_state);
+-			dev->power.saved_state = NULL;
+-		}
++	if (dev->power.saved_state) {
++		NCR_0 = *(unsigned int *)dev->power.saved_state;
++		kfree(dev->power.saved_state);
++		dev->power.saved_state = NULL;
+ 	}
+ 
+ 	return 0;
+@@ -331,9 +325,17 @@ static int __init neponset_init(void)
+ subsys_initcall(neponset_init);
+ 
+ static struct map_desc neponset_io_desc[] __initdata = {
+- /* virtual     physical    length type */
+-  { 0xf3000000, 0x10000000, SZ_1M, MT_DEVICE }, /* System Registers */
+-  { 0xf4000000, 0x40000000, SZ_1M, MT_DEVICE }  /* SA-1111 */
++	{	/* System Registers */
++		.virtual	=  0xf3000000,
++		.pfn		= __phys_to_pfn(0x10000000),
++		.length		= SZ_1M,
++		.type		= MT_DEVICE
++	}, {	/* SA-1111 */
++		.virtual	=  0xf4000000,
++		.pfn		= __phys_to_pfn(0x40000000),
++		.length		= SZ_1M,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ void __init neponset_map_io(void)
+diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
+--- a/arch/arm/mach-sa1100/pleb.c
++++ b/arch/arm/mach-sa1100/pleb.c
+@@ -6,7 +6,7 @@
+ #include <linux/kernel.h>
+ #include <linux/tty.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <linux/mtd/partitions.h>
+ 
+diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
+--- a/arch/arm/mach-sa1100/simpad.c
++++ b/arch/arm/mach-sa1100/simpad.c
+@@ -10,7 +10,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/string.h> 
+ #include <linux/pm.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+ 
+@@ -60,11 +60,17 @@ EXPORT_SYMBOL(set_cs3_bit);
+ EXPORT_SYMBOL(clear_cs3_bit);
+ 
+ static struct map_desc simpad_io_desc[] __initdata = {
+-        /* virtual	physical    length	type */
+-	/* MQ200 */
+-	{ 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE },
+-	/* Paules CS3, write only */
+-	{ 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE },
++	{	/* MQ200 */
++		.virtual	=  0xf2800000,
++		.pfn		= __phys_to_pfn(0x4b800000),
++		.length		= 0x00800000,
++		.type		= MT_DEVICE
++	}, {	/* Paules CS3, write only */
++		.virtual	=  0xf1000000,
++		.pfn		= __phys_to_pfn(0x18000000),
++		.length		= 0x00100000,
++		.type		= MT_DEVICE
++	},
+ };
+ 
+ 
+diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
+--- a/arch/arm/mach-shark/core.c
++++ b/arch/arm/mach-shark/core.c
+@@ -62,7 +62,12 @@ arch_initcall(shark_init);
+ extern void shark_init_irq(void);
+ 
+ static struct map_desc shark_io_desc[] __initdata = {
+-	{ IO_BASE	, IO_START	, IO_SIZE	, MT_DEVICE }
++	{
++		.virtual	= IO_BASE,
++		.pfn		= __phys_to_pfn(IO_START),
++		.length		= IO_SIZE,
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ static void __init shark_map_io(void)
+diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c
+--- a/arch/arm/mach-versatile/clock.c
++++ b/arch/arm/mach-versatile/clock.c
+@@ -13,6 +13,7 @@
+ #include <linux/list.h>
+ #include <linux/errno.h>
+ #include <linux/err.h>
++#include <linux/string.h>
+ 
+ #include <asm/semaphore.h>
+ #include <asm/hardware/clock.h>
+diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
+--- a/arch/arm/mach-versatile/core.c
++++ b/arch/arm/mach-versatile/core.c
+@@ -22,6 +22,7 @@
+ #include <linux/init.h>
+ #include <linux/device.h>
+ #include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
+ #include <linux/sysdev.h>
+ #include <linux/interrupt.h>
+ 
+@@ -186,25 +187,82 @@ void __init versatile_init_irq(void)
+ }
+ 
+ static struct map_desc versatile_io_desc[] __initdata = {
+- { IO_ADDRESS(VERSATILE_SYS_BASE),   VERSATILE_SYS_BASE,   SZ_4K,      MT_DEVICE },
+- { IO_ADDRESS(VERSATILE_SIC_BASE),   VERSATILE_SIC_BASE,   SZ_4K,      MT_DEVICE },
+- { IO_ADDRESS(VERSATILE_VIC_BASE),   VERSATILE_VIC_BASE,   SZ_4K,      MT_DEVICE },
+- { IO_ADDRESS(VERSATILE_SCTL_BASE),  VERSATILE_SCTL_BASE,  SZ_4K * 9,  MT_DEVICE },
++	{
++		.virtual	=  IO_ADDRESS(VERSATILE_SYS_BASE),
++		.pfn		= __phys_to_pfn(VERSATILE_SYS_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	=  IO_ADDRESS(VERSATILE_SIC_BASE),
++		.pfn		= __phys_to_pfn(VERSATILE_SIC_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	=  IO_ADDRESS(VERSATILE_VIC_BASE),
++		.pfn		= __phys_to_pfn(VERSATILE_VIC_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	=  IO_ADDRESS(VERSATILE_SCTL_BASE),
++		.pfn		= __phys_to_pfn(VERSATILE_SCTL_BASE),
++		.length		= SZ_4K * 9,
++		.type		= MT_DEVICE
++	},
+ #ifdef CONFIG_MACH_VERSATILE_AB
+- { IO_ADDRESS(VERSATILE_GPIO0_BASE), VERSATILE_GPIO0_BASE, SZ_4K,      MT_DEVICE },
+- { IO_ADDRESS(VERSATILE_IB2_BASE),   VERSATILE_IB2_BASE,   SZ_64M,     MT_DEVICE },
++ 	{
++		.virtual	=  IO_ADDRESS(VERSATILE_GPIO0_BASE),
++		.pfn		= __phys_to_pfn(VERSATILE_GPIO0_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	=  IO_ADDRESS(VERSATILE_IB2_BASE),
++		.pfn		= __phys_to_pfn(VERSATILE_IB2_BASE),
++		.length		= SZ_64M,
++		.type		= MT_DEVICE
++	},
+ #endif
+ #ifdef CONFIG_DEBUG_LL
+- { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K,      MT_DEVICE },
++ 	{
++		.virtual	=  IO_ADDRESS(VERSATILE_UART0_BASE),
++		.pfn		= __phys_to_pfn(VERSATILE_UART0_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	},
+ #endif
+ #ifdef CONFIG_PCI
+- { IO_ADDRESS(VERSATILE_PCI_CORE_BASE), VERSATILE_PCI_CORE_BASE, SZ_4K, MT_DEVICE },
+- { VERSATILE_PCI_VIRT_BASE,          VERSATILE_PCI_BASE,   VERSATILE_PCI_BASE_SIZE, MT_DEVICE },
+- { VERSATILE_PCI_CFG_VIRT_BASE,      VERSATILE_PCI_CFG_BASE, VERSATILE_PCI_CFG_BASE_SIZE, MT_DEVICE },
++ 	{
++		.virtual	=  IO_ADDRESS(VERSATILE_PCI_CORE_BASE),
++		.pfn		= __phys_to_pfn(VERSATILE_PCI_CORE_BASE),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	=  VERSATILE_PCI_VIRT_BASE,
++		.pfn		= __phys_to_pfn(VERSATILE_PCI_BASE),
++		.length		= VERSATILE_PCI_BASE_SIZE,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	=  VERSATILE_PCI_CFG_VIRT_BASE,
++		.pfn		= __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
++		.length		= VERSATILE_PCI_CFG_BASE_SIZE,
++		.type		= MT_DEVICE
++	},
+ #if 0
+- { VERSATILE_PCI_VIRT_MEM_BASE0,     VERSATILE_PCI_MEM_BASE0, SZ_16M,  MT_DEVICE },
+- { VERSATILE_PCI_VIRT_MEM_BASE1,     VERSATILE_PCI_MEM_BASE1, SZ_16M,  MT_DEVICE },
+- { VERSATILE_PCI_VIRT_MEM_BASE2,     VERSATILE_PCI_MEM_BASE2, SZ_16M,  MT_DEVICE },
++ 	{
++		.virtual	=  VERSATILE_PCI_VIRT_MEM_BASE0,
++		.pfn		= __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
++		.length		= SZ_16M,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	=  VERSATILE_PCI_VIRT_MEM_BASE1,
++		.pfn		= __phys_to_pfn(VERSATILE_PCI_MEM_BASE1),
++		.length		= SZ_16M,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	=  VERSATILE_PCI_VIRT_MEM_BASE2,
++		.pfn		= __phys_to_pfn(VERSATILE_PCI_MEM_BASE2),
++		.length		= SZ_16M,
++		.type		= MT_DEVICE
++	},
+ #endif
+ #endif
+ };
+diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
+--- a/arch/arm/mm/Kconfig
++++ b/arch/arm/mm/Kconfig
+@@ -120,8 +120,8 @@ config CPU_ARM925T
+ 
+ # ARM926T
+ config CPU_ARM926T
+-	bool "Support ARM926T processor" if ARCH_INTEGRATOR
+-	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
++	bool "Support ARM926T processor"
++	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB
+ 	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
+ 	select CPU_32v5
+ 	select CPU_ABRT_EV5TJ
+@@ -242,7 +242,7 @@ config CPU_XSCALE
+ # ARMv6
+ config CPU_V6
+ 	bool "Support ARM V6 processor"
+-	depends on ARCH_INTEGRATOR
++	depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB
+ 	select CPU_32v6
+ 	select CPU_ABRT_EV6
+ 	select CPU_CACHE_V6
+diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
+--- a/arch/arm/mm/consistent.c
++++ b/arch/arm/mm/consistent.c
+@@ -75,7 +75,7 @@ static struct vm_region consistent_head 
+ };
+ 
+ static struct vm_region *
+-vm_region_alloc(struct vm_region *head, size_t size, int gfp)
++vm_region_alloc(struct vm_region *head, size_t size, gfp_t gfp)
+ {
+ 	unsigned long addr = head->vm_start, end = head->vm_end - size;
+ 	unsigned long flags;
+@@ -133,7 +133,7 @@ static struct vm_region *vm_region_find(
+ #endif
+ 
+ static void *
+-__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp,
++__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
+ 	    pgprot_t prot)
+ {
+ 	struct page *page;
+@@ -251,7 +251,7 @@ __dma_alloc(struct device *dev, size_t s
+  * virtual and bus address for that space.
+  */
+ void *
+-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
++dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+ {
+ 	return __dma_alloc(dev, size, handle, gfp,
+ 			   pgprot_noncached(pgprot_kernel));
+@@ -263,7 +263,7 @@ EXPORT_SYMBOL(dma_alloc_coherent);
+  * dma_alloc_coherent above.
+  */
+ void *
+-dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
++dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+ {
+ 	return __dma_alloc(dev, size, handle, gfp,
+ 			   pgprot_writecombine(pgprot_kernel));
+@@ -397,8 +397,6 @@ static int __init consistent_init(void)
+ 	pte_t *pte;
+ 	int ret = 0;
+ 
+-	spin_lock(&init_mm.page_table_lock);
+-
+ 	do {
+ 		pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
+ 		pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
+@@ -409,7 +407,7 @@ static int __init consistent_init(void)
+ 		}
+ 		WARN_ON(!pmd_none(*pmd));
+ 
+-		pte = pte_alloc_kernel(&init_mm, pmd, CONSISTENT_BASE);
++		pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
+ 		if (!pte) {
+ 			printk(KERN_ERR "%s: no pte tables\n", __func__);
+ 			ret = -ENOMEM;
+@@ -419,8 +417,6 @@ static int __init consistent_init(void)
+ 		consistent_pte = pte;
+ 	} while (0);
+ 
+-	spin_unlock(&init_mm.page_table_lock);
+-
+ 	return ret;
+ }
+ 
+diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
+--- a/arch/arm/mm/copypage-v6.c
++++ b/arch/arm/mm/copypage-v6.c
+@@ -22,9 +22,7 @@
+ #endif
+ 
+ #define from_address	(0xffff8000)
+-#define from_pgprot	PAGE_KERNEL
+ #define to_address	(0xffffc000)
+-#define to_pgprot	PAGE_KERNEL
+ 
+ #define TOP_PTE(x)	pte_offset_kernel(top_pmd, x)
+ 
+@@ -34,7 +32,7 @@ static DEFINE_SPINLOCK(v6_lock);
+  * Copy the user page.  No aliasing to deal with so we can just
+  * attack the kernel's existing mapping of these pages.
+  */
+-void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
++static void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
+ {
+ 	copy_page(kto, kfrom);
+ }
+@@ -43,7 +41,7 @@ void v6_copy_user_page_nonaliasing(void 
+  * Clear the user page.  No aliasing to deal with so we can just
+  * attack the kernel's existing mapping of this page.
+  */
+-void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
++static void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
+ {
+ 	clear_page(kaddr);
+ }
+@@ -51,7 +49,7 @@ void v6_clear_user_page_nonaliasing(void
+ /*
+  * Copy the page, taking account of the cache colour.
+  */
+-void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
++static void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
+ {
+ 	unsigned int offset = CACHE_COLOUR(vaddr);
+ 	unsigned long from, to;
+@@ -72,8 +70,8 @@ void v6_copy_user_page_aliasing(void *kt
+ 	 */
+ 	spin_lock(&v6_lock);
+ 
+-	set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
+-	set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
++	set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL));
++	set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL));
+ 
+ 	from = from_address + (offset << PAGE_SHIFT);
+ 	to   = to_address + (offset << PAGE_SHIFT);
+@@ -91,7 +89,7 @@ void v6_copy_user_page_aliasing(void *kt
+  * so remap the kernel page into the same cache colour as the user
+  * page.
+  */
+-void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
++static void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
+ {
+ 	unsigned int offset = CACHE_COLOUR(vaddr);
+ 	unsigned long to = to_address + (offset << PAGE_SHIFT);
+@@ -112,7 +110,7 @@ void v6_clear_user_page_aliasing(void *k
+ 	 */
+ 	spin_lock(&v6_lock);
+ 
+-	set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
++	set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL));
+ 	flush_tlb_kernel_page(to);
+ 	clear_page((void *)to);
+ 
+diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
+--- a/arch/arm/mm/fault-armv.c
++++ b/arch/arm/mm/fault-armv.c
+@@ -26,6 +26,11 @@ static unsigned long shared_pte_mask = L
+ /*
+  * We take the easy way out of this problem - we make the
+  * PTE uncacheable.  However, we leave the write buffer on.
++ *
++ * Note that the pte lock held when calling update_mmu_cache must also
++ * guard the pte (somewhere else in the same mm) that we modify here.
++ * Therefore those configurations which might call adjust_pte (those
++ * without CONFIG_CPU_CACHE_VIPT) cannot support split page_table_lock.
+  */
+ static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
+ {
+@@ -127,7 +132,7 @@ void __flush_dcache_page(struct address_
+  *  2. If we have multiple shared mappings of the same space in
+  *     an object, we need to deal with the cache aliasing issues.
+  *
+- * Note that the page_table_lock will be held.
++ * Note that the pte lock will be held.
+  */
+ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+ {
+diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
+--- a/arch/arm/mm/init.c
++++ b/arch/arm/mm/init.c
+@@ -1,7 +1,7 @@
+ /*
+  *  linux/arch/arm/mm/init.c
+  *
+- *  Copyright (C) 1995-2002 Russell King
++ *  Copyright (C) 1995-2005 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
+@@ -86,14 +86,19 @@ void show_mem(void)
+ 	printk("%d pages swap cached\n", cached);
+ }
+ 
+-struct node_info {
+-	unsigned int start;
+-	unsigned int end;
+-	int bootmap_pages;
+-};
++static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
++{
++	return pmd_offset(pgd, virt);
++}
++
++static inline pmd_t *pmd_off_k(unsigned long virt)
++{
++	return pmd_off(pgd_offset_k(virt), virt);
++}
+ 
+-#define O_PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+-#define O_PFN_UP(x)	(PAGE_ALIGN(x) >> PAGE_SHIFT)
++#define for_each_nodebank(iter,mi,no)			\
++	for (iter = 0; iter < mi->nr_banks; iter++)	\
++		if (mi->bank[iter].node == no)
+ 
+ /*
+  * FIXME: We really want to avoid allocating the bootmap bitmap
+@@ -106,15 +111,12 @@ find_bootmap_pfn(int node, struct meminf
+ {
+ 	unsigned int start_pfn, bank, bootmap_pfn;
+ 
+-	start_pfn   = O_PFN_UP(__pa(&_end));
++	start_pfn   = PAGE_ALIGN(__pa(&_end)) >> PAGE_SHIFT;
+ 	bootmap_pfn = 0;
+ 
+-	for (bank = 0; bank < mi->nr_banks; bank ++) {
++	for_each_nodebank(bank, mi, node) {
+ 		unsigned int start, end;
+ 
+-		if (mi->bank[bank].node != node)
+-			continue;
+-
+ 		start = mi->bank[bank].start >> PAGE_SHIFT;
+ 		end   = (mi->bank[bank].size +
+ 			 mi->bank[bank].start) >> PAGE_SHIFT;
+@@ -140,92 +142,6 @@ find_bootmap_pfn(int node, struct meminf
+ 	return bootmap_pfn;
+ }
+ 
+-/*
+- * Scan the memory info structure and pull out:
+- *  - the end of memory
+- *  - the number of nodes
+- *  - the pfn range of each node
+- *  - the number of bootmem bitmap pages
+- */
+-static unsigned int __init
+-find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
+-{
+-	unsigned int i, bootmem_pages = 0, memend_pfn = 0;
+-
+-	for (i = 0; i < MAX_NUMNODES; i++) {
+-		np[i].start = -1U;
+-		np[i].end = 0;
+-		np[i].bootmap_pages = 0;
+-	}
+-
+-	for (i = 0; i < mi->nr_banks; i++) {
+-		unsigned long start, end;
+-		int node;
+-
+-		if (mi->bank[i].size == 0) {
+-			/*
+-			 * Mark this bank with an invalid node number
+-			 */
+-			mi->bank[i].node = -1;
+-			continue;
+-		}
+-
+-		node = mi->bank[i].node;
+-
+-		/*
+-		 * Make sure we haven't exceeded the maximum number of nodes
+-		 * that we have in this configuration.  If we have, we're in
+-		 * trouble.  (maybe we ought to limit, instead of bugging?)
+-		 */
+-		if (node >= MAX_NUMNODES)
+-			BUG();
+-		node_set_online(node);
+-
+-		/*
+-		 * Get the start and end pfns for this bank
+-		 */
+-		start = mi->bank[i].start >> PAGE_SHIFT;
+-		end   = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
+-
+-		if (np[node].start > start)
+-			np[node].start = start;
+-
+-		if (np[node].end < end)
+-			np[node].end = end;
+-
+-		if (memend_pfn < end)
+-			memend_pfn = end;
+-	}
+-
+-	/*
+-	 * Calculate the number of pages we require to
+-	 * store the bootmem bitmaps.
+-	 */
+-	for_each_online_node(i) {
+-		if (np[i].end == 0)
+-			continue;
+-
+-		np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end -
+-							    np[i].start);
+-		bootmem_pages += np[i].bootmap_pages;
+-	}
+-
+-	high_memory = __va(memend_pfn << PAGE_SHIFT);
+-
+-	/*
+-	 * This doesn't seem to be used by the Linux memory
+-	 * manager any more.  If we can get rid of it, we
+-	 * also get rid of some of the stuff above as well.
+-	 *
+-	 * Note: max_low_pfn and max_pfn reflect the number
+-	 * of _pages_ in the system, not the maximum PFN.
+-	 */
+-	max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
+-	max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
+-
+-	return bootmem_pages;
+-}
+-
+ static int __init check_initrd(struct meminfo *mi)
+ {
+ 	int initrd_node = -2;
+@@ -266,9 +182,8 @@ static int __init check_initrd(struct me
+ /*
+  * Reserve the various regions of node 0
+  */
+-static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages)
++static __init void reserve_node_zero(pg_data_t *pgdat)
+ {
+-	pg_data_t *pgdat = NODE_DATA(0);
+ 	unsigned long res_size = 0;
+ 
+ 	/*
+@@ -289,13 +204,6 @@ static __init void reserve_node_zero(uns
+ 			     PTRS_PER_PGD * sizeof(pgd_t));
+ 
+ 	/*
+-	 * And don't forget to reserve the allocator bitmap,
+-	 * which will be freed later.
+-	 */
+-	reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,
+-			     bootmap_pages << PAGE_SHIFT);
+-
+-	/*
+ 	 * Hmm... This should go elsewhere, but we really really need to
+ 	 * stop things allocating the low memory; ideally we need a better
+ 	 * implementation of GFP_DMA which does not assume that DMA-able
+@@ -324,183 +232,284 @@ static __init void reserve_node_zero(uns
+ 		reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size);
+ }
+ 
+-/*
+- * Register all available RAM in this node with the bootmem allocator.
+- */
+-static inline void free_bootmem_node_bank(int node, struct meminfo *mi)
++void __init build_mem_type_table(void);
++void __init create_mapping(struct map_desc *md);
++
++static unsigned long __init
++bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
+ {
+-	pg_data_t *pgdat = NODE_DATA(node);
+-	int bank;
++	unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
++	unsigned long start_pfn, end_pfn, boot_pfn;
++	unsigned int boot_pages;
++	pg_data_t *pgdat;
++	int i;
+ 
+-	for (bank = 0; bank < mi->nr_banks; bank++)
+-		if (mi->bank[bank].node == node)
+-			free_bootmem_node(pgdat, mi->bank[bank].start,
+-					  mi->bank[bank].size);
+-}
++	start_pfn = -1UL;
++	end_pfn = 0;
+ 
+-/*
+- * Initialise the bootmem allocator for all nodes.  This is called
+- * early during the architecture specific initialisation.
+- */
+-static void __init bootmem_init(struct meminfo *mi)
+-{
+-	struct node_info node_info[MAX_NUMNODES], *np = node_info;
+-	unsigned int bootmap_pages, bootmap_pfn, map_pg;
+-	int node, initrd_node;
++	/*
++	 * Calculate the pfn range, and map the memory banks for this node.
++	 */
++	for_each_nodebank(i, mi, node) {
++		unsigned long start, end;
++		struct map_desc map;
+ 
+-	bootmap_pages = find_memend_and_nodes(mi, np);
+-	bootmap_pfn   = find_bootmap_pfn(0, mi, bootmap_pages);
+-	initrd_node   = check_initrd(mi);
++		start = mi->bank[i].start >> PAGE_SHIFT;
++		end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
++
++		if (start_pfn > start)
++			start_pfn = start;
++		if (end_pfn < end)
++			end_pfn = end;
+ 
+-	map_pg = bootmap_pfn;
++		map.pfn = __phys_to_pfn(mi->bank[i].start);
++		map.virtual = __phys_to_virt(mi->bank[i].start);
++		map.length = mi->bank[i].size;
++		map.type = MT_MEMORY;
++
++		create_mapping(&map);
++	}
+ 
+ 	/*
+-	 * Initialise the bootmem nodes.
+-	 *
+-	 * What we really want to do is:
+-	 *
+-	 *   unmap_all_regions_except_kernel();
+-	 *   for_each_node_in_reverse_order(node) {
+-	 *     map_node(node);
+-	 *     allocate_bootmem_map(node);
+-	 *     init_bootmem_node(node);
+-	 *     free_bootmem_node(node);
+-	 *   }
+-	 *
+-	 * but this is a 2.5-type change.  For now, we just set
+-	 * the nodes up in reverse order.
+-	 *
+-	 * (we could also do with rolling bootmem_init and paging_init
+-	 * into one generic "memory_init" type function).
++	 * If there is no memory in this node, ignore it.
+ 	 */
+-	np += num_online_nodes() - 1;
+-	for (node = num_online_nodes() - 1; node >= 0; node--, np--) {
+-		/*
+-		 * If there are no pages in this node, ignore it.
+-		 * Note that node 0 must always have some pages.
+-		 */
+-		if (np->end == 0 || !node_online(node)) {
+-			if (node == 0)
+-				BUG();
+-			continue;
+-		}
++	if (end_pfn == 0)
++		return end_pfn;
+ 
+-		/*
+-		 * Initialise the bootmem allocator.
+-		 */
+-		init_bootmem_node(NODE_DATA(node), map_pg, np->start, np->end);
+-		free_bootmem_node_bank(node, mi);
+-		map_pg += np->bootmap_pages;
++	/*
++	 * Allocate the bootmem bitmap page.
++	 */
++	boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
++	boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
+ 
+-		/*
+-		 * If this is node 0, we need to reserve some areas ASAP -
+-		 * we may use bootmem on node 0 to setup the other nodes.
+-		 */
+-		if (node == 0)
+-			reserve_node_zero(bootmap_pfn, bootmap_pages);
+-	}
++	/*
++	 * Initialise the bootmem allocator for this node, handing the
++	 * memory banks over to bootmem.
++	 */
++	node_set_online(node);
++	pgdat = NODE_DATA(node);
++	init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
++
++	for_each_nodebank(i, mi, node)
++		free_bootmem_node(pgdat, mi->bank[i].start, mi->bank[i].size);
+ 
++	/*
++	 * Reserve the bootmem bitmap for this node.
++	 */
++	reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
++			     boot_pages << PAGE_SHIFT);
+ 
+ #ifdef CONFIG_BLK_DEV_INITRD
+-	if (phys_initrd_size && initrd_node >= 0) {
+-		reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start,
++	/*
++	 * If the initrd is in this node, reserve its memory.
++	 */
++	if (node == initrd_node) {
++		reserve_bootmem_node(pgdat, phys_initrd_start,
+ 				     phys_initrd_size);
+ 		initrd_start = __phys_to_virt(phys_initrd_start);
+ 		initrd_end = initrd_start + phys_initrd_size;
+ 	}
+ #endif
+ 
+-	BUG_ON(map_pg != bootmap_pfn + bootmap_pages);
++	/*
++	 * Finally, reserve any node zero regions.
++	 */
++	if (node == 0)
++		reserve_node_zero(pgdat);
++
++	/*
++	 * initialise the zones within this node.
++	 */
++	memset(zone_size, 0, sizeof(zone_size));
++	memset(zhole_size, 0, sizeof(zhole_size));
++
++	/*
++	 * The size of this node has already been determined.  If we need
++	 * to do anything fancy with the allocation of this memory to the
++	 * zones, now is the time to do it.
++	 */
++	zone_size[0] = end_pfn - start_pfn;
++
++	/*
++	 * For each bank in this node, calculate the size of the holes.
++	 *  holes = node_size - sum(bank_sizes_in_node)
++	 */
++	zhole_size[0] = zone_size[0];
++	for_each_nodebank(i, mi, node)
++		zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
++
++	/*
++	 * Adjust the sizes according to any special requirements for
++	 * this machine type.
++	 */
++	arch_adjust_zones(node, zone_size, zhole_size);
++
++	free_area_init_node(node, pgdat, zone_size, start_pfn, zhole_size);
++
++	return end_pfn;
+ }
+ 
+-/*
+- * paging_init() sets up the page tables, initialises the zone memory
+- * maps, and sets up the zero page, bad page and bad page tables.
+- */
+-void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
++static void __init bootmem_init(struct meminfo *mi)
+ {
+-	void *zero_page;
+-	int node;
++	unsigned long addr, memend_pfn = 0;
++	int node, initrd_node, i;
+ 
+-	bootmem_init(mi);
++	/*
++	 * Invalidate the node number for empty or invalid memory banks
++	 */
++	for (i = 0; i < mi->nr_banks; i++)
++		if (mi->bank[i].size == 0 || mi->bank[i].node >= MAX_NUMNODES)
++			mi->bank[i].node = -1;
+ 
+ 	memcpy(&meminfo, mi, sizeof(meminfo));
+ 
+ 	/*
+-	 * allocate the zero page.  Note that we count on this going ok.
++	 * Clear out all the mappings below the kernel image.
+ 	 */
+-	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
++	for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE)
++		pmd_clear(pmd_off_k(addr));
++#ifdef CONFIG_XIP_KERNEL
++	/* The XIP kernel is mapped in the module area -- skip over it */
++	addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
++#endif
++	for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
++		pmd_clear(pmd_off_k(addr));
+ 
+ 	/*
+-	 * initialise the page tables.
++	 * Clear out all the kernel space mappings, except for the first
++	 * memory bank, up to the end of the vmalloc region.
+ 	 */
+-	memtable_init(mi);
+-	if (mdesc->map_io)
+-		mdesc->map_io();
+-	local_flush_tlb_all();
++	for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size);
++	     addr < VMALLOC_END; addr += PGDIR_SIZE)
++		pmd_clear(pmd_off_k(addr));
+ 
+ 	/*
+-	 * initialise the zones within each node
++	 * Locate which node contains the ramdisk image, if any.
+ 	 */
+-	for_each_online_node(node) {
+-		unsigned long zone_size[MAX_NR_ZONES];
+-		unsigned long zhole_size[MAX_NR_ZONES];
+-		struct bootmem_data *bdata;
+-		pg_data_t *pgdat;
+-		int i;
++	initrd_node = check_initrd(mi);
+ 
+-		/*
+-		 * Initialise the zone size information.
+-		 */
+-		for (i = 0; i < MAX_NR_ZONES; i++) {
+-			zone_size[i]  = 0;
+-			zhole_size[i] = 0;
+-		}
++	/*
++	 * Run through each node initialising the bootmem allocator.
++	 */
++	for_each_node(node) {
++		unsigned long end_pfn;
+ 
+-		pgdat = NODE_DATA(node);
+-		bdata = pgdat->bdata;
++		end_pfn = bootmem_init_node(node, initrd_node, mi);
+ 
+ 		/*
+-		 * The size of this node has already been determined.
+-		 * If we need to do anything fancy with the allocation
+-		 * of this memory to the zones, now is the time to do
+-		 * it.
++		 * Remember the highest memory PFN.
+ 		 */
+-		zone_size[0] = bdata->node_low_pfn -
+-				(bdata->node_boot_start >> PAGE_SHIFT);
++		if (end_pfn > memend_pfn)
++			memend_pfn = end_pfn;
++	}
+ 
+-		/*
+-		 * If this zone has zero size, skip it.
+-		 */
+-		if (!zone_size[0])
+-			continue;
++	high_memory = __va(memend_pfn << PAGE_SHIFT);
+ 
+-		/*
+-		 * For each bank in this node, calculate the size of the
+-		 * holes.  holes = node_size - sum(bank_sizes_in_node)
+-		 */
+-		zhole_size[0] = zone_size[0];
+-		for (i = 0; i < mi->nr_banks; i++) {
+-			if (mi->bank[i].node != node)
+-				continue;
++	/*
++	 * This doesn't seem to be used by the Linux memory manager any
++	 * more, but is used by ll_rw_block.  If we can get rid of it, we
++	 * also get rid of some of the stuff above as well.
++	 *
++	 * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
++	 * the system, not the maximum PFN.
++	 */
++	max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET;
++}
+ 
+-			zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
+-		}
++/*
++ * Set up device the mappings.  Since we clear out the page tables for all
++ * mappings above VMALLOC_END, we will remove any debug device mappings.
++ * This means you have to be careful how you debug this function, or any
++ * called function.  (Do it by code inspection!)
++ */
++static void __init devicemaps_init(struct machine_desc *mdesc)
++{
++	struct map_desc map;
++	unsigned long addr;
++	void *vectors;
+ 
+-		/*
+-		 * Adjust the sizes according to any special
+-		 * requirements for this machine type.
+-		 */
+-		arch_adjust_zones(node, zone_size, zhole_size);
++	for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
++		pmd_clear(pmd_off_k(addr));
+ 
+-		free_area_init_node(node, pgdat, zone_size,
+-				bdata->node_boot_start >> PAGE_SHIFT, zhole_size);
++	/*
++	 * Map the kernel if it is XIP.
++	 * It is always first in the modulearea.
++	 */
++#ifdef CONFIG_XIP_KERNEL
++	map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK);
++	map.virtual = MODULE_START;
++	map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK;
++	map.type = MT_ROM;
++	create_mapping(&map);
++#endif
++
++	/*
++	 * Map the cache flushing regions.
++	 */
++#ifdef FLUSH_BASE
++	map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
++	map.virtual = FLUSH_BASE;
++	map.length = PGDIR_SIZE;
++	map.type = MT_CACHECLEAN;
++	create_mapping(&map);
++#endif
++#ifdef FLUSH_BASE_MINICACHE
++	map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + PGDIR_SIZE);
++	map.virtual = FLUSH_BASE_MINICACHE;
++	map.length = PGDIR_SIZE;
++	map.type = MT_MINICLEAN;
++	create_mapping(&map);
++#endif
++
++	flush_cache_all();
++	local_flush_tlb_all();
++
++	vectors = alloc_bootmem_low_pages(PAGE_SIZE);
++	BUG_ON(!vectors);
++
++	/*
++	 * Create a mapping for the machine vectors at the high-vectors
++	 * location (0xffff0000).  If we aren't using high-vectors, also
++	 * create a mapping at the low-vectors virtual address.
++	 */
++	map.pfn = __phys_to_pfn(virt_to_phys(vectors));
++	map.virtual = 0xffff0000;
++	map.length = PAGE_SIZE;
++	map.type = MT_HIGH_VECTORS;
++	create_mapping(&map);
++
++	if (!vectors_high()) {
++		map.virtual = 0;
++		map.type = MT_LOW_VECTORS;
++		create_mapping(&map);
+ 	}
+ 
+ 	/*
+-	 * finish off the bad pages once
+-	 * the mem_map is initialised
++	 * Ask the machine support to map in the statically mapped devices.
++	 * After this point, we can start to touch devices again.
++	 */
++	if (mdesc->map_io)
++		mdesc->map_io();
++}
++
++/*
++ * paging_init() sets up the page tables, initialises the zone memory
++ * maps, and sets up the zero page, bad page and bad page tables.
++ */
++void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
++{
++	void *zero_page;
++
++	build_mem_type_table();
++	bootmem_init(mi);
++	devicemaps_init(mdesc);
++
++	top_pmd = pmd_off_k(0xffff0000);
++
++	/*
++	 * allocate the zero page.  Note that we count on this going ok.
+ 	 */
++	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+ 	memzero(zero_page, PAGE_SIZE);
+ 	empty_zero_page = virt_to_page(zero_page);
+ 	flush_dcache_page(empty_zero_page);
+@@ -562,10 +571,7 @@ static void __init free_unused_memmap_no
+ 	 * may not be the case, especially if the user has provided the
+ 	 * information on the command line.
+ 	 */
+-	for (i = 0; i < mi->nr_banks; i++) {
+-		if (mi->bank[i].size == 0 || mi->bank[i].node != node)
+-			continue;
+-
++	for_each_nodebank(i, mi, node) {
+ 		bank_start = mi->bank[i].start >> PAGE_SHIFT;
+ 		if (bank_start < prev_bank_end) {
+ 			printk(KERN_ERR "MEM: unordered memory banks.  "
+diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
+--- a/arch/arm/mm/ioremap.c
++++ b/arch/arm/mm/ioremap.c
+@@ -26,6 +26,7 @@
+ #include <linux/vmalloc.h>
+ 
+ #include <asm/cacheflush.h>
++#include <asm/hardware.h>
+ #include <asm/io.h>
+ #include <asm/tlbflush.h>
+ 
+@@ -74,7 +75,7 @@ remap_area_pmd(pmd_t * pmd, unsigned lon
+ 
+ 	pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
+@@ -96,7 +97,6 @@ remap_area_pages(unsigned long start, un
+ 	phys_addr -= address;
+ 	dir = pgd_offset(&init_mm, address);
+ 	BUG_ON(address >= end);
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
+ 		if (!pmd) {
+@@ -113,7 +113,6 @@ remap_area_pages(unsigned long start, un
+ 		dir++;
+ 	} while (address && (address < end));
+ 
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_cache_vmap(start, end);
+ 	return err;
+ }
+diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
+--- a/arch/arm/mm/mm-armv.c
++++ b/arch/arm/mm/mm-armv.c
+@@ -1,7 +1,7 @@
+ /*
+  *  linux/arch/arm/mm/mm-armv.c
+  *
+- *  Copyright (C) 1998-2002 Russell King
++ *  Copyright (C) 1998-2005 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
+@@ -180,11 +180,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+ 
+ 	if (!vectors_high()) {
+ 		/*
+-		 * This lock is here just to satisfy pmd_alloc and pte_lock
+-		 */
+-		spin_lock(&mm->page_table_lock);
+-
+-		/*
+ 		 * On ARM, first page must always be allocated since it
+ 		 * contains the machine vectors.
+ 		 */
+@@ -201,23 +196,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+ 		set_pte(new_pte, *init_pte);
+ 		pte_unmap_nested(init_pte);
+ 		pte_unmap(new_pte);
+-
+-		spin_unlock(&mm->page_table_lock);
+ 	}
+ 
+ 	return new_pgd;
+ 
+ no_pte:
+-	spin_unlock(&mm->page_table_lock);
+ 	pmd_free(new_pmd);
+-	free_pages((unsigned long)new_pgd, 2);
+-	return NULL;
+-
+ no_pmd:
+-	spin_unlock(&mm->page_table_lock);
+ 	free_pages((unsigned long)new_pgd, 2);
+-	return NULL;
+-
+ no_pgd:
+ 	return NULL;
+ }
+@@ -243,6 +229,7 @@ void free_pgd_slow(pgd_t *pgd)
+ 	pte = pmd_page(*pmd);
+ 	pmd_clear(pmd);
+ 	dec_page_state(nr_page_table_pages);
++	pte_lock_deinit(pte);
+ 	pte_free(pte);
+ 	pmd_free(pmd);
+ free:
+@@ -305,16 +292,6 @@ alloc_init_page(unsigned long virt, unsi
+ 	set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
+ }
+ 
+-/*
+- * Clear any PGD mapping.  On a two-level page table system,
+- * the clearance is done by the middle-level functions (pmd)
+- * rather than the top-level (pgd) functions.
+- */
+-static inline void clear_mapping(unsigned long virt)
+-{
+-	pmd_clear(pmd_off_k(virt));
+-}
+-
+ struct mem_types {
+ 	unsigned int	prot_pte;
+ 	unsigned int	prot_l1;
+@@ -373,7 +350,7 @@ static struct mem_types mem_types[] __in
+ /*
+  * Adjust the PMD section entries according to the CPU in use.
+  */
+-static void __init build_mem_type_table(void)
++void __init build_mem_type_table(void)
+ {
+ 	struct cachepolicy *cp;
+ 	unsigned int cr = get_cr();
+@@ -483,25 +460,25 @@ static void __init build_mem_type_table(
+  * offsets, and we take full advantage of sections and
+  * supersections.
+  */
+-static void __init create_mapping(struct map_desc *md)
++void __init create_mapping(struct map_desc *md)
+ {
+ 	unsigned long virt, length;
+ 	int prot_sect, prot_l1, domain;
+ 	pgprot_t prot_pte;
+-	long off;
++	unsigned long off = (u32)__pfn_to_phys(md->pfn);
+ 
+ 	if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
+ 		printk(KERN_WARNING "BUG: not creating mapping for "
+-		       "0x%08lx at 0x%08lx in user region\n",
+-		       md->physical, md->virtual);
++		       "0x%016llx at 0x%08lx in user region\n",
++		       __pfn_to_phys((u64)md->pfn), md->virtual);
+ 		return;
+ 	}
+ 
+ 	if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
+ 	    md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
+-		printk(KERN_WARNING "BUG: mapping for 0x%08lx at 0x%08lx "
++		printk(KERN_WARNING "BUG: mapping for 0x%016llx at 0x%08lx "
+ 		       "overlaps vmalloc space\n",
+-		       md->physical, md->virtual);
++		       __pfn_to_phys((u64)md->pfn), md->virtual);
+ 	}
+ 
+ 	domain	  = mem_types[md->type].domain;
+@@ -509,15 +486,40 @@ static void __init create_mapping(struct
+ 	prot_l1   = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
+ 	prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain);
+ 
++	/*
++	 * Catch 36-bit addresses
++	 */
++	if(md->pfn >= 0x100000) {
++		if(domain) {
++			printk(KERN_ERR "MM: invalid domain in supersection "
++				"mapping for 0x%016llx at 0x%08lx\n",
++				__pfn_to_phys((u64)md->pfn), md->virtual);
++			return;
++		}
++		if((md->virtual | md->length | __pfn_to_phys(md->pfn))
++			& ~SUPERSECTION_MASK) {
++			printk(KERN_ERR "MM: cannot create mapping for "
++				"0x%016llx at 0x%08lx invalid alignment\n",
++				__pfn_to_phys((u64)md->pfn), md->virtual);
++			return;
++		}
++
++		/*
++		 * Shift bits [35:32] of address into bits [23:20] of PMD
++		 * (See ARMv6 spec).
++		 */
++		off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
++	}
++
+ 	virt   = md->virtual;
+-	off    = md->physical - virt;
++	off   -= virt;
+ 	length = md->length;
+ 
+ 	if (mem_types[md->type].prot_l1 == 0 &&
+ 	    (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) {
+ 		printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
+ 		       "be mapped using pages, ignoring.\n",
+-		       md->physical, md->virtual);
++		       __pfn_to_phys(md->pfn), md->virtual);
+ 		return;
+ 	}
+ 
+@@ -535,13 +537,22 @@ static void __init create_mapping(struct
+ 	 *	of the actual domain assignments in use.
+ 	 */
+ 	if (cpu_architecture() >= CPU_ARCH_ARMv6 && domain == 0) {
+-		/* Align to supersection boundary */
+-		while ((virt & ~SUPERSECTION_MASK || (virt + off) &
+-			~SUPERSECTION_MASK) && length >= (PGDIR_SIZE / 2)) {
+-			alloc_init_section(virt, virt + off, prot_sect);
+-
+-			virt   += (PGDIR_SIZE / 2);
+-			length -= (PGDIR_SIZE / 2);
++		/*
++		 * Align to supersection boundary if !high pages.
++		 * High pages have already been checked for proper
++		 * alignment above and they will fail the SUPSERSECTION_MASK
++		 * check because of the way the address is encoded into
++		 * offset.
++		 */
++		if (md->pfn <= 0x100000) {
++			while ((virt & ~SUPERSECTION_MASK ||
++			        (virt + off) & ~SUPERSECTION_MASK) &&
++				length >= (PGDIR_SIZE / 2)) {
++				alloc_init_section(virt, virt + off, prot_sect);
++
++				virt   += (PGDIR_SIZE / 2);
++				length -= (PGDIR_SIZE / 2);
++			}
+ 		}
+ 
+ 		while (length >= SUPERSECTION_SIZE) {
+@@ -601,100 +612,6 @@ void setup_mm_for_reboot(char mode)
+ 	}
+ }
+ 
+-extern void _stext, _etext;
+-
+-/*
+- * Setup initial mappings.  We use the page we allocated for zero page to hold
+- * the mappings, which will get overwritten by the vectors in traps_init().
+- * The mappings must be in virtual address order.
+- */
+-void __init memtable_init(struct meminfo *mi)
+-{
+-	struct map_desc *init_maps, *p, *q;
+-	unsigned long address = 0;
+-	int i;
+-
+-	build_mem_type_table();
+-
+-	init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
+-
+-#ifdef CONFIG_XIP_KERNEL
+-	p->physical   = CONFIG_XIP_PHYS_ADDR & PMD_MASK;
+-	p->virtual    = (unsigned long)&_stext & PMD_MASK;
+-	p->length     = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK;
+-	p->type       = MT_ROM;
+-	p ++;
+-#endif
+-
+-	for (i = 0; i < mi->nr_banks; i++) {
+-		if (mi->bank[i].size == 0)
+-			continue;
+-
+-		p->physical   = mi->bank[i].start;
+-		p->virtual    = __phys_to_virt(p->physical);
+-		p->length     = mi->bank[i].size;
+-		p->type       = MT_MEMORY;
+-		p ++;
+-	}
+-
+-#ifdef FLUSH_BASE
+-	p->physical   = FLUSH_BASE_PHYS;
+-	p->virtual    = FLUSH_BASE;
+-	p->length     = PGDIR_SIZE;
+-	p->type       = MT_CACHECLEAN;
+-	p ++;
+-#endif
+-
+-#ifdef FLUSH_BASE_MINICACHE
+-	p->physical   = FLUSH_BASE_PHYS + PGDIR_SIZE;
+-	p->virtual    = FLUSH_BASE_MINICACHE;
+-	p->length     = PGDIR_SIZE;
+-	p->type       = MT_MINICLEAN;
+-	p ++;
+-#endif
+-
+-	/*
+-	 * Go through the initial mappings, but clear out any
+-	 * pgdir entries that are not in the description.
+-	 */
+-	q = init_maps;
+-	do {
+-		if (address < q->virtual || q == p) {
+-			clear_mapping(address);
+-			address += PGDIR_SIZE;
+-		} else {
+-			create_mapping(q);
+-
+-			address = q->virtual + q->length;
+-			address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
+-
+-			q ++;
+-		}
+-	} while (address != 0);
+-
+-	/*
+-	 * Create a mapping for the machine vectors at the high-vectors
+-	 * location (0xffff0000).  If we aren't using high-vectors, also
+-	 * create a mapping at the low-vectors virtual address.
+-	 */
+-	init_maps->physical   = virt_to_phys(init_maps);
+-	init_maps->virtual    = 0xffff0000;
+-	init_maps->length     = PAGE_SIZE;
+-	init_maps->type       = MT_HIGH_VECTORS;
+-	create_mapping(init_maps);
+-
+-	if (!vectors_high()) {
+-		init_maps->virtual = 0;
+-		init_maps->type = MT_LOW_VECTORS;
+-		create_mapping(init_maps);
+-	}
+-
+-	flush_cache_all();
+-	local_flush_tlb_all();
+-
+-	top_pmd = pmd_off_k(0xffff0000);
+-}
+-
+ /*
+  * Create the architecture specific mappings
+  */
+diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
+--- a/arch/arm/oprofile/Makefile
++++ b/arch/arm/oprofile/Makefile
+@@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drive
+ 		oprofilefs.o oprofile_stats.o \
+ 		timer_int.o )
+ 
+-oprofile-y				:= $(DRIVER_OBJS) init.o backtrace.o
+-oprofile-$(CONFIG_CPU_XSCALE)		+= common.o op_model_xscale.o
++oprofile-y				:= $(DRIVER_OBJS) common.o backtrace.o
++oprofile-$(CONFIG_CPU_XSCALE)		+= op_model_xscale.o
+ 
+diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
+--- a/arch/arm/oprofile/backtrace.c
++++ b/arch/arm/oprofile/backtrace.c
+@@ -49,42 +49,22 @@ static struct frame_tail* kernel_backtra
+ 
+ static struct frame_tail* user_backtrace(struct frame_tail *tail)
+ {
+-	struct frame_tail buftail;
++	struct frame_tail buftail[2];
+ 
+-	/* hardware pte might not be valid due to dirty/accessed bit emulation
+-	 * so we use copy_from_user and benefit from exception fixups */
+-	if (copy_from_user(&buftail, tail, sizeof(struct frame_tail)))
++	/* Also check accessibility of one struct frame_tail beyond */
++	if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
++		return NULL;
++	if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail)))
+ 		return NULL;
+ 
+-	oprofile_add_trace(buftail.lr);
++	oprofile_add_trace(buftail[0].lr);
+ 
+ 	/* frame pointers should strictly progress back up the stack
+ 	 * (towards higher addresses) */
+-	if (tail >= buftail.fp)
++	if (tail >= buftail[0].fp)
+ 		return NULL;
+ 
+-	return buftail.fp-1;
+-}
+-
+-/* Compare two addresses and see if they're on the same page */
+-#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \
+-	== ((((unsigned long) y) + offset) >> PAGE_SHIFT))
+-
+-/* check that the page(s) containing the frame tail are present */
+-static int pages_present(struct frame_tail *tail)
+-{
+-	struct mm_struct * mm = current->mm;
+-
+-	if (!check_user_page_readable(mm, (unsigned long)tail))
+-		return 0;
+-
+-	if (CMP_ADDR_EQUAL(tail, tail, 8))
+-		return 1;
+-
+-	if (!check_user_page_readable(mm, ((unsigned long)tail) + 8))
+-		return 0;
+-
+-	return 1;
++	return buftail[0].fp-1;
+ }
+ 
+ /*
+@@ -118,7 +98,6 @@ static int valid_kernel_stack(struct fra
+ void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
+ {
+ 	struct frame_tail *tail;
+-	unsigned long last_address = 0;
+ 
+ 	tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+ 
+@@ -132,13 +111,6 @@ void arm_backtrace(struct pt_regs * cons
+ 		return;
+ 	}
+ 
+-	while (depth-- && tail && !((unsigned long) tail & 3)) {
+-		if ((!CMP_ADDR_EQUAL(last_address, tail, 0)
+-			|| !CMP_ADDR_EQUAL(last_address, tail, 8))
+-				&& !pages_present(tail))
+-			return;
+-		last_address = (unsigned long) tail;
++	while (depth-- && tail && !((unsigned long) tail & 3))
+ 		tail = user_backtrace(tail);
+-	}
+ }
+-
+diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
+--- a/arch/arm/oprofile/common.c
++++ b/arch/arm/oprofile/common.c
+@@ -10,40 +10,94 @@
+ #include <linux/init.h>
+ #include <linux/oprofile.h>
+ #include <linux/errno.h>
+-#include <asm/semaphore.h>
+ #include <linux/sysdev.h>
++#include <asm/semaphore.h>
+ 
+ #include "op_counter.h"
+ #include "op_arm_model.h"
+ 
+-static struct op_arm_model_spec *pmu_model;
+-static int pmu_enabled;
+-static struct semaphore pmu_sem;
+-
+-static int pmu_start(void);
+-static int pmu_setup(void);
+-static void pmu_stop(void);
+-static int pmu_create_files(struct super_block *, struct dentry *);
++static struct op_arm_model_spec *op_arm_model;
++static int op_arm_enabled;
++static struct semaphore op_arm_sem;
++
++struct op_counter_config counter_config[OP_MAX_COUNTER];
++
++static int op_arm_create_files(struct super_block *sb, struct dentry *root)
++{
++	unsigned int i;
++
++	for (i = 0; i < op_arm_model->num_counters; i++) {
++		struct dentry *dir;
++		char buf[2];
++
++		snprintf(buf, sizeof buf, "%d", i);
++		dir = oprofilefs_mkdir(sb, root, buf);
++		oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);
++		oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event);
++		oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count);
++		oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask);
++		oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel);
++		oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user);
++	}
++
++	return 0;
++}
++
++static int op_arm_setup(void)
++{
++	int ret;
++
++	spin_lock(&oprofilefs_lock);
++	ret = op_arm_model->setup_ctrs();
++	spin_unlock(&oprofilefs_lock);
++	return ret;
++}
++
++static int op_arm_start(void)
++{
++	int ret = -EBUSY;
++
++	down(&op_arm_sem);
++	if (!op_arm_enabled) {
++		ret = op_arm_model->start();
++		op_arm_enabled = !ret;
++	}
++	up(&op_arm_sem);
++	return ret;
++}
++
++static void op_arm_stop(void)
++{
++	down(&op_arm_sem);
++	if (op_arm_enabled)
++		op_arm_model->stop();
++	op_arm_enabled = 0;
++	up(&op_arm_sem);
++}
+ 
+ #ifdef CONFIG_PM
+-static int pmu_suspend(struct sys_device *dev, pm_message_t state)
++static int op_arm_suspend(struct sys_device *dev, pm_message_t state)
+ {
+-	if (pmu_enabled)
+-		pmu_stop();
++	down(&op_arm_sem);
++	if (op_arm_enabled)
++		op_arm_model->stop();
++	up(&op_arm_sem);
+ 	return 0;
+ }
+ 
+-static int pmu_resume(struct sys_device *dev)
++static int op_arm_resume(struct sys_device *dev)
+ {
+-	if (pmu_enabled)
+-		pmu_start();
++	down(&op_arm_sem);
++	if (op_arm_enabled && op_arm_model->start())
++		op_arm_enabled = 0;
++	up(&op_arm_sem);
+ 	return 0;
+ }
+ 
+ static struct sysdev_class oprofile_sysclass = {
+ 	set_kset_name("oprofile"),
+-	.resume		= pmu_resume,
+-	.suspend	= pmu_suspend,
++	.resume		= op_arm_resume,
++	.suspend	= op_arm_suspend,
+ };
+ 
+ static struct sys_device device_oprofile = {
+@@ -71,86 +125,41 @@ static void  exit_driverfs(void)
+ #define exit_driverfs() do { } while (0)
+ #endif /* CONFIG_PM */
+ 
+-struct op_counter_config counter_config[OP_MAX_COUNTER];
+-
+-static int pmu_create_files(struct super_block *sb, struct dentry *root)
++int __init oprofile_arch_init(struct oprofile_operations *ops)
+ {
+-	unsigned int i;
++	struct op_arm_model_spec *spec = NULL;
++	int ret = -ENODEV;
+ 
+-	for (i = 0; i < pmu_model->num_counters; i++) {
+-		struct dentry *dir;
+-		char buf[2];
+-
+-		snprintf(buf, sizeof buf, "%d", i);
+-		dir = oprofilefs_mkdir(sb, root, buf);
+-		oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);
+-		oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event);
+-		oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count);
+-		oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask);
+-		oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel);
+-		oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user);
++#ifdef CONFIG_CPU_XSCALE
++	spec = &op_xscale_spec;
++#endif
++
++	if (spec) {
++		init_MUTEX(&op_arm_sem);
++
++		if (spec->init() < 0)
++			return -ENODEV;
++
++		op_arm_model = spec;
++		init_driverfs();
++		ops->create_files = op_arm_create_files;
++		ops->setup = op_arm_setup;
++		ops->shutdown = op_arm_stop;
++		ops->start = op_arm_start;
++		ops->stop = op_arm_stop;
++		ops->cpu_type = op_arm_model->name;
++		ops->backtrace = arm_backtrace;
++		printk(KERN_INFO "oprofile: using %s\n", spec->name);
+ 	}
+ 
+-	return 0;
+-}
+-
+-static int pmu_setup(void)
+-{
+-	int ret;
+-
+-	spin_lock(&oprofilefs_lock);
+-	ret = pmu_model->setup_ctrs();
+-	spin_unlock(&oprofilefs_lock);
+-	return ret;
+-}
+-
+-static int pmu_start(void)
+-{
+-	int ret = -EBUSY;
+-
+-	down(&pmu_sem);
+-	if (!pmu_enabled) {
+-		ret = pmu_model->start();
+-		pmu_enabled = !ret;
+-	}
+-	up(&pmu_sem);
+ 	return ret;
+ }
+ 
+-static void pmu_stop(void)
+-{
+-	down(&pmu_sem);
+-	if (pmu_enabled)
+-		pmu_model->stop();
+-	pmu_enabled = 0;
+-	up(&pmu_sem);
+-}
+-
+-int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec)
+-{
+-	init_MUTEX(&pmu_sem);
+-
+-	if (spec->init() < 0)
+-		return -ENODEV;
+-
+-	pmu_model = spec;
+-	init_driverfs();
+-	ops->create_files = pmu_create_files;
+-	ops->setup = pmu_setup;
+-	ops->shutdown = pmu_stop;
+-	ops->start = pmu_start;
+-	ops->stop = pmu_stop;
+-	ops->cpu_type = pmu_model->name;
+-	printk(KERN_INFO "oprofile: using %s PMU\n", spec->name);
+-
+-	return 0;
+-}
+-
+-void pmu_exit(void)
++void oprofile_arch_exit(void)
+ {
+-	if (pmu_model) {
++	if (op_arm_model) {
+ 		exit_driverfs();
+-		pmu_model = NULL;
++		op_arm_model = NULL;
+ 	}
+ }
+ 
+diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c
+deleted file mode 100644
+--- a/arch/arm/oprofile/init.c
++++ /dev/null
+@@ -1,33 +0,0 @@
+-/**
+- * @file init.c
+- *
+- * @remark Copyright 2004 Oprofile Authors
+- * @remark Read the file COPYING
+- *
+- * @author Zwane Mwaikambo
+- */
+-
+-#include <linux/oprofile.h>
+-#include <linux/init.h>
+-#include <linux/errno.h>
+-#include "op_arm_model.h"
+-
+-int __init oprofile_arch_init(struct oprofile_operations *ops)
+-{
+-	int ret = -ENODEV;
+-
+-#ifdef CONFIG_CPU_XSCALE
+-	ret = pmu_init(ops, &op_xscale_spec);
+-#endif
+-
+-	ops->backtrace = arm_backtrace;
+-
+-	return ret;
+-}
+-
+-void oprofile_arch_exit(void)
+-{
+-#ifdef CONFIG_CPU_XSCALE
+-	pmu_exit();
+-#endif
+-}
+diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
+--- a/arch/arm/oprofile/op_arm_model.h
++++ b/arch/arm/oprofile/op_arm_model.h
+@@ -26,6 +26,6 @@ extern struct op_arm_model_spec op_xscal
+ 
+ extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
+ 
+-extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
+-extern void pmu_exit(void);
++extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
++extern void op_arm_exit(void);
+ #endif /* OP_ARM_MODEL_H */
+diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
+--- a/arch/arm/plat-omap/clock.c
++++ b/arch/arm/plat-omap/clock.c
+@@ -13,6 +13,7 @@
+ #include <linux/list.h>
+ #include <linux/errno.h>
+ #include <linux/err.h>
++#include <linux/string.h>
+ 
+ #include <asm/io.h>
+ #include <asm/semaphore.h>
+diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
+--- a/arch/arm/plat-omap/sram.c
++++ b/arch/arm/plat-omap/sram.c
+@@ -59,7 +59,11 @@ void __init omap_detect_sram(void)
+ }
+ 
+ static struct map_desc omap_sram_io_desc[] __initdata = {
+-	{ OMAP1_SRAM_BASE, OMAP1_SRAM_START, 0, MT_DEVICE }
++	{	/* .length gets filled in at runtime */
++		.virtual	= OMAP1_SRAM_BASE,
++		.pfn		= __phys_to_pfn(OMAP1_SRAM_START),
++		.type		= MT_DEVICE
++	}
+ };
+ 
+ /*
+diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
+--- a/arch/arm/plat-omap/usb.c
++++ b/arch/arm/plat-omap/usb.c
+@@ -26,7 +26,7 @@
+ #include <linux/types.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/usb_otg.h>
+ 
+ #include <asm/io.h>
+diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
+--- a/arch/arm26/kernel/ptrace.c
++++ b/arch/arm26/kernel/ptrace.c
+@@ -665,7 +665,7 @@ static int do_ptrace(int request, struct
+ 	return ret;
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	int ret;
+diff --git a/arch/arm26/kernel/time.c b/arch/arm26/kernel/time.c
+--- a/arch/arm26/kernel/time.c
++++ b/arch/arm26/kernel/time.c
+@@ -34,10 +34,6 @@
+ #include <asm/irq.h>
+ #include <asm/ioc.h>
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ extern unsigned long wall_jiffies;
+ 
+ /* this needs a better home */
+diff --git a/arch/arm26/mm/memc.c b/arch/arm26/mm/memc.c
+--- a/arch/arm26/mm/memc.c
++++ b/arch/arm26/mm/memc.c
+@@ -79,12 +79,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+ 		goto no_pgd;
+ 
+ 	/*
+-	 * This lock is here just to satisfy pmd_alloc and pte_lock
+-         * FIXME: I bet we could avoid taking it pretty much altogether
+-	 */
+-	spin_lock(&mm->page_table_lock);
+-
+-	/*
+ 	 * On ARM, first page must always be allocated since it contains
+ 	 * the machine vectors.
+ 	 */
+@@ -92,7 +86,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+ 	if (!new_pmd)
+ 		goto no_pmd;
+ 
+-	new_pte = pte_alloc_kernel(mm, new_pmd, 0);
++	new_pte = pte_alloc_map(mm, new_pmd, 0);
+ 	if (!new_pte)
+ 		goto no_pte;
+ 
+@@ -101,6 +95,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+ 	init_pte = pte_offset(init_pmd, 0);
+ 
+ 	set_pte(new_pte, *init_pte);
++	pte_unmap(new_pte);
+ 
+ 	/*
+ 	 * the page table entries are zeroed
+@@ -112,23 +107,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
+ 	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
+ 		(PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
+ 
+-	spin_unlock(&mm->page_table_lock);
+-
+ 	/* update MEMC tables */
+ 	cpu_memc_update_all(new_pgd);
+ 	return new_pgd;
+ 
+ no_pte:
+-	spin_unlock(&mm->page_table_lock);
+ 	pmd_free(new_pmd);
+-	free_pgd_slow(new_pgd);
+-	return NULL;
+-
+ no_pmd:
+-	spin_unlock(&mm->page_table_lock);
+ 	free_pgd_slow(new_pgd);
+-	return NULL;
+-
+ no_pgd:
+ 	return NULL;
+ }
+diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c
+--- a/arch/cris/arch-v10/drivers/axisflashmap.c
++++ b/arch/cris/arch-v10/drivers/axisflashmap.c
+@@ -140,6 +140,7 @@
+ #include <linux/kernel.h>
+ #include <linux/config.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ 
+ #include <linux/mtd/concat.h>
+ #include <linux/mtd/map.h>
+diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
+--- a/arch/cris/arch-v32/drivers/axisflashmap.c
++++ b/arch/cris/arch-v32/drivers/axisflashmap.c
+@@ -20,6 +20,7 @@
+ #include <linux/kernel.h>
+ #include <linux/config.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ 
+ #include <linux/mtd/concat.h>
+ #include <linux/mtd/map.h>
+diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
+--- a/arch/cris/arch-v32/mm/tlb.c
++++ b/arch/cris/arch-v32/mm/tlb.c
+@@ -175,6 +175,8 @@ init_new_context(struct task_struct *tsk
+ 	return 0;
+ }
+ 
++static DEFINE_SPINLOCK(mmu_context_lock);
++
+ /* Called in schedule() just before actually doing the switch_to. */
+ void
+ switch_mm(struct mm_struct *prev, struct mm_struct *next,
+@@ -183,10 +185,10 @@ switch_mm(struct mm_struct *prev, struct
+ 	int cpu = smp_processor_id();
+ 
+ 	/* Make sure there is a MMU context. */
+-	spin_lock(&next->page_table_lock);
++	spin_lock(&mmu_context_lock);
+ 	get_mmu_context(next);
+ 	cpu_set(cpu, next->cpu_vm_mask);
+-	spin_unlock(&next->page_table_lock);
++	spin_unlock(&mmu_context_lock);
+ 
+ 	/*
+ 	 * Remember the pgd for the fault handlers. Keep a seperate copy of it
+diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
+--- a/arch/cris/kernel/time.c
++++ b/arch/cris/kernel/time.c
+@@ -31,10 +31,7 @@
+ #include <linux/timex.h>
+ #include <linux/init.h>
+ #include <linux/profile.h>
+-
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
++#include <linux/sched.h>	/* just for sched_clock() - funny that */
+ 
+ int have_rtc;  /* used to remember if we have an RTC or not */;
+ 
+diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
+--- a/arch/cris/mm/ioremap.c
++++ b/arch/cris/mm/ioremap.c
+@@ -52,7 +52,7 @@ static inline int remap_area_pmd(pmd_t *
+ 	if (address >= end)
+ 		BUG();
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, address + phys_addr, prot);
+@@ -74,7 +74,6 @@ static int remap_area_pages(unsigned lon
+ 	flush_cache_all();
+ 	if (address >= end)
+ 		BUG();
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		pud_t *pud;
+ 		pmd_t *pmd;
+@@ -94,7 +93,6 @@ static int remap_area_pages(unsigned lon
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_tlb_all();
+ 	return error;
+ }
+diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
+--- a/arch/frv/kernel/ptrace.c
++++ b/arch/frv/kernel/ptrace.c
+@@ -106,7 +106,7 @@ void ptrace_enable(struct task_struct *c
+ 	child->thread.frame0->__status |= REG__STATUS_STEP;
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	unsigned long tmp;
+diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
+--- a/arch/frv/kernel/time.c
++++ b/arch/frv/kernel/time.c
+@@ -34,9 +34,6 @@
+ 
+ extern unsigned long wall_jiffies;
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-EXPORT_SYMBOL(jiffies_64);
+-
+ unsigned long __nongprelbss __clkin_clock_speed_HZ;
+ unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
+ unsigned long __nongprelbss __res_bus_clock_speed_HZ;
+@@ -221,6 +218,7 @@ int do_settimeofday(struct timespec *tv)
+ 	clock_was_set();
+ 	return 0;
+ }
++EXPORT_SYMBOL(do_settimeofday);
+ 
+ /*
+  * Scheduler clock - returns current time in nanosec units.
+diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
+--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
++++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
+@@ -33,7 +33,7 @@ struct dma_alloc_record {
+ static DEFINE_SPINLOCK(dma_alloc_lock);
+ static LIST_HEAD(dma_alloc_list);
+ 
+-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, int gfp)
++void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
+ {
+ 	struct dma_alloc_record *new;
+ 	struct list_head *this = &dma_alloc_list;
+diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
+--- a/arch/frv/mb93090-mb00/pci-dma.c
++++ b/arch/frv/mb93090-mb00/pci-dma.c
+@@ -17,7 +17,7 @@
+ #include <linux/highmem.h>
+ #include <asm/io.h>
+ 
+-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, int gfp)
++void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 
+diff --git a/arch/frv/mm/dma-alloc.c b/arch/frv/mm/dma-alloc.c
+--- a/arch/frv/mm/dma-alloc.c
++++ b/arch/frv/mm/dma-alloc.c
+@@ -55,21 +55,18 @@ static int map_page(unsigned long va, un
+ 	pte_t *pte;
+ 	int err = -ENOMEM;
+ 
+-	spin_lock(&init_mm.page_table_lock);
+-
+ 	/* Use upper 10 bits of VA to index the first level map */
+ 	pge = pgd_offset_k(va);
+ 	pue = pud_offset(pge, va);
+ 	pme = pmd_offset(pue, va);
+ 
+ 	/* Use middle 10 bits of VA to index the second-level map */
+-	pte = pte_alloc_kernel(&init_mm, pme, va);
++	pte = pte_alloc_kernel(pme, va);
+ 	if (pte != 0) {
+ 		err = 0;
+ 		set_pte(pte, mk_pte_phys(pa & PAGE_MASK, prot));
+ 	}
+ 
+-	spin_unlock(&init_mm.page_table_lock);
+ 	return err;
+ }
+ 
+@@ -81,7 +78,7 @@ static int map_page(unsigned long va, un
+  * portions of the kernel with single large page TLB entries, and
+  * still get unique uncached pages for consistent DMA.
+  */
+-void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
++void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
+ {
+ 	struct vm_struct *area;
+ 	unsigned long page, va, pa;
+diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
+--- a/arch/frv/mm/pgalloc.c
++++ b/arch/frv/mm/pgalloc.c
+@@ -87,14 +87,14 @@ static inline void pgd_list_add(pgd_t *p
+ 	if (pgd_list)
+ 		pgd_list->private = (unsigned long) &page->index;
+ 	pgd_list = page;
+-	page->private = (unsigned long) &pgd_list;
++	set_page_private(page, (unsigned long)&pgd_list);
+ }
+ 
+ static inline void pgd_list_del(pgd_t *pgd)
+ {
+ 	struct page *next, **pprev, *page = virt_to_page(pgd);
+ 	next = (struct page *) page->index;
+-	pprev = (struct page **) page->private;
++	pprev = (struct page **)page_private(page);
+ 	*pprev = next;
+ 	if (next)
+ 		next->private = (unsigned long) pprev;
+diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
+--- a/arch/h8300/kernel/ptrace.c
++++ b/arch/h8300/kernel/ptrace.c
+@@ -57,7 +57,7 @@ void ptrace_disable(struct task_struct *
+ 	h8300_disable_trace(child);
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	int ret;
+diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
+--- a/arch/h8300/kernel/time.c
++++ b/arch/h8300/kernel/time.c
+@@ -32,10 +32,6 @@
+ 
+ #define	TICK_SIZE (tick_nsec / 1000)
+ 
+-u64 jiffies_64;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ /*
+  * timer_interrupt() needs to keep up the real-time clock,
+  * as well as call the "do_timer()" routine every clocktick
+diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
+--- a/arch/i386/Kconfig
++++ b/arch/i386/Kconfig
+@@ -5,7 +5,7 @@
+ 
+ mainmenu "Linux Kernel Configuration"
+ 
+-config X86
++config X86_32
+ 	bool
+ 	default y
+ 	help
+@@ -18,6 +18,10 @@ config SEMAPHORE_SLEEPERS
+ 	bool
+ 	default y
+ 
++config X86
++	bool
++	default y
++
+ config MMU
+ 	bool
+ 	default y
+@@ -151,304 +155,7 @@ config ES7000_CLUSTERED_APIC
+ 	default y
+ 	depends on SMP && X86_ES7000 && MPENTIUMIII
+ 
+-if !X86_ELAN
+-
+-choice
+-	prompt "Processor family"
+-	default M686
+-
+-config M386
+-	bool "386"
+-	---help---
+-	  This is the processor type of your CPU. This information is used for
+-	  optimizing purposes. In order to compile a kernel that can run on
+-	  all x86 CPU types (albeit not optimally fast), you can specify
+-	  "386" here.
+-
+-	  The kernel will not necessarily run on earlier architectures than
+-	  the one you have chosen, e.g. a Pentium optimized kernel will run on
+-	  a PPro, but not necessarily on a i486.
+-
+-	  Here are the settings recommended for greatest speed:
+-	  - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
+-	  486DLC/DLC2, UMC 486SX-S and NexGen Nx586.  Only "386" kernels
+-	  will run on a 386 class machine.
+-	  - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
+-	  SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
+-	  - "586" for generic Pentium CPUs lacking the TSC
+-	  (time stamp counter) register.
+-	  - "Pentium-Classic" for the Intel Pentium.
+-	  - "Pentium-MMX" for the Intel Pentium MMX.
+-	  - "Pentium-Pro" for the Intel Pentium Pro.
+-	  - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
+-	  - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
+-	  - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
+-	  - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
+-	  - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
+-	  - "Crusoe" for the Transmeta Crusoe series.
+-	  - "Efficeon" for the Transmeta Efficeon series.
+-	  - "Winchip-C6" for original IDT Winchip.
+-	  - "Winchip-2" for IDT Winchip 2.
+-	  - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
+-	  - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
+-	  - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
+-	  - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
+-
+-	  If you don't know what to do, choose "386".
+-
+-config M486
+-	bool "486"
+-	help
+-	  Select this for a 486 series processor, either Intel or one of the
+-	  compatible processors from AMD, Cyrix, IBM, or Intel.  Includes DX,
+-	  DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
+-	  U5S.
+-
+-config M586
+-	bool "586/K5/5x86/6x86/6x86MX"
+-	help
+-	  Select this for an 586 or 686 series processor such as the AMD K5,
+-	  the Cyrix 5x86, 6x86 and 6x86MX.  This choice does not
+-	  assume the RDTSC (Read Time Stamp Counter) instruction.
+-
+-config M586TSC
+-	bool "Pentium-Classic"
+-	help
+-	  Select this for a Pentium Classic processor with the RDTSC (Read
+-	  Time Stamp Counter) instruction for benchmarking.
+-
+-config M586MMX
+-	bool "Pentium-MMX"
+-	help
+-	  Select this for a Pentium with the MMX graphics/multimedia
+-	  extended instructions.
+-
+-config M686
+-	bool "Pentium-Pro"
+-	help
+-	  Select this for Intel Pentium Pro chips.  This enables the use of
+-	  Pentium Pro extended instructions, and disables the init-time guard
+-	  against the f00f bug found in earlier Pentiums.
+-
+-config MPENTIUMII
+-	bool "Pentium-II/Celeron(pre-Coppermine)"
+-	help
+-	  Select this for Intel chips based on the Pentium-II and
+-	  pre-Coppermine Celeron core.  This option enables an unaligned
+-	  copy optimization, compiles the kernel with optimization flags
+-	  tailored for the chip, and applies any applicable Pentium Pro
+-	  optimizations.
+-
+-config MPENTIUMIII
+-	bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
+-	help
+-	  Select this for Intel chips based on the Pentium-III and
+-	  Celeron-Coppermine core.  This option enables use of some
+-	  extended prefetch instructions in addition to the Pentium II
+-	  extensions.
+-
+-config MPENTIUMM
+-	bool "Pentium M"
+-	help
+-	  Select this for Intel Pentium M (not Pentium-4 M)
+-	  notebook chips.
+-
+-config MPENTIUM4
+-	bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
+-	help
+-	  Select this for Intel Pentium 4 chips.  This includes the
+-	  Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
+-	  (not Pentium M) chips.  This option enables compile flags
+-	  optimized for the chip, uses the correct cache shift, and
+-	  applies any applicable Pentium III optimizations.
+-
+-config MK6
+-	bool "K6/K6-II/K6-III"
+-	help
+-	  Select this for an AMD K6-family processor.  Enables use of
+-	  some extended instructions, and passes appropriate optimization
+-	  flags to GCC.
+-
+-config MK7
+-	bool "Athlon/Duron/K7"
+-	help
+-	  Select this for an AMD Athlon K7-family processor.  Enables use of
+-	  some extended instructions, and passes appropriate optimization
+-	  flags to GCC.
+-
+-config MK8
+-	bool "Opteron/Athlon64/Hammer/K8"
+-	help
+-	  Select this for an AMD Opteron or Athlon64 Hammer-family processor.  Enables
+-	  use of some extended instructions, and passes appropriate optimization
+-	  flags to GCC.
+-
+-config MCRUSOE
+-	bool "Crusoe"
+-	help
+-	  Select this for a Transmeta Crusoe processor.  Treats the processor
+-	  like a 586 with TSC, and sets some GCC optimization flags (like a
+-	  Pentium Pro with no alignment requirements).
+-
+-config MEFFICEON
+-	bool "Efficeon"
+-	help
+-	  Select this for a Transmeta Efficeon processor.
+-
+-config MWINCHIPC6
+-	bool "Winchip-C6"
+-	help
+-	  Select this for an IDT Winchip C6 chip.  Linux and GCC
+-	  treat this chip as a 586TSC with some extended instructions
+-	  and alignment requirements.
+-
+-config MWINCHIP2
+-	bool "Winchip-2"
+-	help
+-	  Select this for an IDT Winchip-2.  Linux and GCC
+-	  treat this chip as a 586TSC with some extended instructions
+-	  and alignment requirements.
+-
+-config MWINCHIP3D
+-	bool "Winchip-2A/Winchip-3"
+-	help
+-	  Select this for an IDT Winchip-2A or 3.  Linux and GCC
+-	  treat this chip as a 586TSC with some extended instructions
+-	  and alignment reqirements.  Also enable out of order memory
+-	  stores for this CPU, which can increase performance of some
+-	  operations.
+-
+-config MGEODEGX1
+-	bool "GeodeGX1"
+-	help
+-	  Select this for a Geode GX1 (Cyrix MediaGX) chip.
+-
+-config MCYRIXIII
+-	bool "CyrixIII/VIA-C3"
+-	help
+-	  Select this for a Cyrix III or C3 chip.  Presently Linux and GCC
+-	  treat this chip as a generic 586. Whilst the CPU is 686 class,
+-	  it lacks the cmov extension which gcc assumes is present when
+-	  generating 686 code.
+-	  Note that Nehemiah (Model 9) and above will not boot with this
+-	  kernel due to them lacking the 3DNow! instructions used in earlier
+-	  incarnations of the CPU.
+-
+-config MVIAC3_2
+-	bool "VIA C3-2 (Nehemiah)"
+-	help
+-	  Select this for a VIA C3 "Nehemiah". Selecting this enables usage
+-	  of SSE and tells gcc to treat the CPU as a 686.
+-	  Note, this kernel will not boot on older (pre model 9) C3s.
+-
+-endchoice
+-
+-config X86_GENERIC
+-       bool "Generic x86 support"
+-       help
+-	  Instead of just including optimizations for the selected
+-	  x86 variant (e.g. PII, Crusoe or Athlon), include some more
+-	  generic optimizations as well. This will make the kernel
+-	  perform better on x86 CPUs other than that selected.
+-
+-	  This is really intended for distributors who need more
+-	  generic optimizations.
+-
+-endif
+-
+-#
+-# Define implied options from the CPU selection here
+-#
+-config X86_CMPXCHG
+-	bool
+-	depends on !M386
+-	default y
+-
+-config X86_XADD
+-	bool
+-	depends on !M386
+-	default y
+-
+-config X86_L1_CACHE_SHIFT
+-	int
+-	default "7" if MPENTIUM4 || X86_GENERIC
+-	default "4" if X86_ELAN || M486 || M386
+-	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
+-	default "6" if MK7 || MK8 || MPENTIUMM
+-
+-config RWSEM_GENERIC_SPINLOCK
+-	bool
+-	depends on M386
+-	default y
+-
+-config RWSEM_XCHGADD_ALGORITHM
+-	bool
+-	depends on !M386
+-	default y
+-
+-config GENERIC_CALIBRATE_DELAY
+-	bool
+-	default y
+-
+-config X86_PPRO_FENCE
+-	bool
+-	depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
+-	default y
+-
+-config X86_F00F_BUG
+-	bool
+-	depends on M586MMX || M586TSC || M586 || M486 || M386
+-	default y
+-
+-config X86_WP_WORKS_OK
+-	bool
+-	depends on !M386
+-	default y
+-
+-config X86_INVLPG
+-	bool
+-	depends on !M386
+-	default y
+-
+-config X86_BSWAP
+-	bool
+-	depends on !M386
+-	default y
+-
+-config X86_POPAD_OK
+-	bool
+-	depends on !M386
+-	default y
+-
+-config X86_ALIGNMENT_16
+-	bool
+-	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
+-	default y
+-
+-config X86_GOOD_APIC
+-	bool
+-	depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
+-	default y
+-
+-config X86_INTEL_USERCOPY
+-	bool
+-	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
+-	default y
+-
+-config X86_USE_PPRO_CHECKSUM
+-	bool
+-	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
+-	default y
+-
+-config X86_USE_3DNOW
+-	bool
+-	depends on MCYRIXIII || MK7
+-	default y
+-
+-config X86_OOSTORE
+-	bool
+-	depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
+-	default y
++source "arch/i386/Kconfig.cpu"
+ 
+ config HPET_TIMER
+ 	bool "HPET Timer Support"
+@@ -561,11 +268,6 @@ config X86_VISWS_APIC
+ 	depends on X86_VISWS
+ 	default y
+ 
+-config X86_TSC
+-	bool
+-	depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
+-	default y
+-
+ config X86_MCE
+ 	bool "Machine Check Exception"
+ 	depends on !X86_VOYAGER
+@@ -1340,8 +1042,3 @@ config X86_TRAMPOLINE
+ 	bool
+ 	depends on X86_SMP || (X86_VOYAGER && SMP)
+ 	default y
+-
+-config PC
+-	bool
+-	depends on X86 && !EMBEDDED
+-	default y
+diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
+new file mode 100644
+--- /dev/null
++++ b/arch/i386/Kconfig.cpu
+@@ -0,0 +1,309 @@
++# Put here option for CPU selection and depending optimization
++if !X86_ELAN
++
++choice
++	prompt "Processor family"
++	default M686
++
++config M386
++	bool "386"
++	---help---
++	  This is the processor type of your CPU. This information is used for
++	  optimizing purposes. In order to compile a kernel that can run on
++	  all x86 CPU types (albeit not optimally fast), you can specify
++	  "386" here.
++
++	  The kernel will not necessarily run on earlier architectures than
++	  the one you have chosen, e.g. a Pentium optimized kernel will run on
++	  a PPro, but not necessarily on a i486.
++
++	  Here are the settings recommended for greatest speed:
++	  - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
++	  486DLC/DLC2, UMC 486SX-S and NexGen Nx586.  Only "386" kernels
++	  will run on a 386 class machine.
++	  - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
++	  SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
++	  - "586" for generic Pentium CPUs lacking the TSC
++	  (time stamp counter) register.
++	  - "Pentium-Classic" for the Intel Pentium.
++	  - "Pentium-MMX" for the Intel Pentium MMX.
++	  - "Pentium-Pro" for the Intel Pentium Pro.
++	  - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
++	  - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
++	  - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
++	  - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
++	  - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
++	  - "Crusoe" for the Transmeta Crusoe series.
++	  - "Efficeon" for the Transmeta Efficeon series.
++	  - "Winchip-C6" for original IDT Winchip.
++	  - "Winchip-2" for IDT Winchip 2.
++	  - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
++	  - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
++	  - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
++	  - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
++
++	  If you don't know what to do, choose "386".
++
++config M486
++	bool "486"
++	help
++	  Select this for a 486 series processor, either Intel or one of the
++	  compatible processors from AMD, Cyrix, IBM, or Intel.  Includes DX,
++	  DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
++	  U5S.
++
++config M586
++	bool "586/K5/5x86/6x86/6x86MX"
++	help
++	  Select this for an 586 or 686 series processor such as the AMD K5,
++	  the Cyrix 5x86, 6x86 and 6x86MX.  This choice does not
++	  assume the RDTSC (Read Time Stamp Counter) instruction.
++
++config M586TSC
++	bool "Pentium-Classic"
++	help
++	  Select this for a Pentium Classic processor with the RDTSC (Read
++	  Time Stamp Counter) instruction for benchmarking.
++
++config M586MMX
++	bool "Pentium-MMX"
++	help
++	  Select this for a Pentium with the MMX graphics/multimedia
++	  extended instructions.
++
++config M686
++	bool "Pentium-Pro"
++	help
++	  Select this for Intel Pentium Pro chips.  This enables the use of
++	  Pentium Pro extended instructions, and disables the init-time guard
++	  against the f00f bug found in earlier Pentiums.
++
++config MPENTIUMII
++	bool "Pentium-II/Celeron(pre-Coppermine)"
++	help
++	  Select this for Intel chips based on the Pentium-II and
++	  pre-Coppermine Celeron core.  This option enables an unaligned
++	  copy optimization, compiles the kernel with optimization flags
++	  tailored for the chip, and applies any applicable Pentium Pro
++	  optimizations.
++
++config MPENTIUMIII
++	bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
++	help
++	  Select this for Intel chips based on the Pentium-III and
++	  Celeron-Coppermine core.  This option enables use of some
++	  extended prefetch instructions in addition to the Pentium II
++	  extensions.
++
++config MPENTIUMM
++	bool "Pentium M"
++	help
++	  Select this for Intel Pentium M (not Pentium-4 M)
++	  notebook chips.
++
++config MPENTIUM4
++	bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
++	help
++	  Select this for Intel Pentium 4 chips.  This includes the
++	  Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
++	  (not Pentium M) chips.  This option enables compile flags
++	  optimized for the chip, uses the correct cache shift, and
++	  applies any applicable Pentium III optimizations.
++
++config MK6
++	bool "K6/K6-II/K6-III"
++	help
++	  Select this for an AMD K6-family processor.  Enables use of
++	  some extended instructions, and passes appropriate optimization
++	  flags to GCC.
++
++config MK7
++	bool "Athlon/Duron/K7"
++	help
++	  Select this for an AMD Athlon K7-family processor.  Enables use of
++	  some extended instructions, and passes appropriate optimization
++	  flags to GCC.
++
++config MK8
++	bool "Opteron/Athlon64/Hammer/K8"
++	help
++	  Select this for an AMD Opteron or Athlon64 Hammer-family processor.  Enables
++	  use of some extended instructions, and passes appropriate optimization
++	  flags to GCC.
++
++config MCRUSOE
++	bool "Crusoe"
++	help
++	  Select this for a Transmeta Crusoe processor.  Treats the processor
++	  like a 586 with TSC, and sets some GCC optimization flags (like a
++	  Pentium Pro with no alignment requirements).
++
++config MEFFICEON
++	bool "Efficeon"
++	help
++	  Select this for a Transmeta Efficeon processor.
++
++config MWINCHIPC6
++	bool "Winchip-C6"
++	help
++	  Select this for an IDT Winchip C6 chip.  Linux and GCC
++	  treat this chip as a 586TSC with some extended instructions
++	  and alignment requirements.
++
++config MWINCHIP2
++	bool "Winchip-2"
++	help
++	  Select this for an IDT Winchip-2.  Linux and GCC
++	  treat this chip as a 586TSC with some extended instructions
++	  and alignment requirements.
++
++config MWINCHIP3D
++	bool "Winchip-2A/Winchip-3"
++	help
++	  Select this for an IDT Winchip-2A or 3.  Linux and GCC
++	  treat this chip as a 586TSC with some extended instructions
++	  and alignment reqirements.  Also enable out of order memory
++	  stores for this CPU, which can increase performance of some
++	  operations.
++
++config MGEODEGX1
++	bool "GeodeGX1"
++	help
++	  Select this for a Geode GX1 (Cyrix MediaGX) chip.
++
++config MCYRIXIII
++	bool "CyrixIII/VIA-C3"
++	help
++	  Select this for a Cyrix III or C3 chip.  Presently Linux and GCC
++	  treat this chip as a generic 586. Whilst the CPU is 686 class,
++	  it lacks the cmov extension which gcc assumes is present when
++	  generating 686 code.
++	  Note that Nehemiah (Model 9) and above will not boot with this
++	  kernel due to them lacking the 3DNow! instructions used in earlier
++	  incarnations of the CPU.
++
++config MVIAC3_2
++	bool "VIA C3-2 (Nehemiah)"
++	help
++	  Select this for a VIA C3 "Nehemiah". Selecting this enables usage
++	  of SSE and tells gcc to treat the CPU as a 686.
++	  Note, this kernel will not boot on older (pre model 9) C3s.
++
++endchoice
++
++config X86_GENERIC
++       bool "Generic x86 support"
++       help
++	  Instead of just including optimizations for the selected
++	  x86 variant (e.g. PII, Crusoe or Athlon), include some more
++	  generic optimizations as well. This will make the kernel
++	  perform better on x86 CPUs other than that selected.
++
++	  This is really intended for distributors who need more
++	  generic optimizations.
++
++endif
++
++#
++# Define implied options from the CPU selection here
++#
++config X86_CMPXCHG
++	bool
++	depends on !M386
++	default y
++
++config X86_XADD
++	bool
++	depends on !M386
++	default y
++
++config X86_L1_CACHE_SHIFT
++	int
++	default "7" if MPENTIUM4 || X86_GENERIC
++	default "4" if X86_ELAN || M486 || M386
++	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
++	default "6" if MK7 || MK8 || MPENTIUMM
++
++config RWSEM_GENERIC_SPINLOCK
++	bool
++	depends on M386
++	default y
++
++config RWSEM_XCHGADD_ALGORITHM
++	bool
++	depends on !M386
++	default y
++
++config GENERIC_CALIBRATE_DELAY
++	bool
++	default y
++
++config X86_PPRO_FENCE
++	bool
++	depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
++	default y
++
++config X86_F00F_BUG
++	bool
++	depends on M586MMX || M586TSC || M586 || M486 || M386
++	default y
++
++config X86_WP_WORKS_OK
++	bool
++	depends on !M386
++	default y
++
++config X86_INVLPG
++	bool
++	depends on !M386
++	default y
++
++config X86_BSWAP
++	bool
++	depends on !M386
++	default y
++
++config X86_POPAD_OK
++	bool
++	depends on !M386
++	default y
++
++config X86_CMPXCHG64
++	bool
++	depends on !M386 && !M486
++	default y
++
++config X86_ALIGNMENT_16
++	bool
++	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
++	default y
++
++config X86_GOOD_APIC
++	bool
++	depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
++	default y
++
++config X86_INTEL_USERCOPY
++	bool
++	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
++	default y
++
++config X86_USE_PPRO_CHECKSUM
++	bool
++	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
++	default y
++
++config X86_USE_3DNOW
++	bool
++	depends on MCYRIXIII || MK7
++	default y
++
++config X86_OOSTORE
++	bool
++	depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
++	default y
++
++config X86_TSC
++	bool
++	depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
++	default y
+diff --git a/arch/i386/Makefile b/arch/i386/Makefile
+--- a/arch/i386/Makefile
++++ b/arch/i386/Makefile
+@@ -34,35 +34,8 @@ CFLAGS += -pipe -msoft-float
+ # prevent gcc from keeping the stack 16 byte aligned
+ CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
+ 
+-align := $(cc-option-align)
+-cflags-$(CONFIG_M386)		+= -march=i386
+-cflags-$(CONFIG_M486)		+= -march=i486
+-cflags-$(CONFIG_M586)		+= -march=i586
+-cflags-$(CONFIG_M586TSC)	+= -march=i586
+-cflags-$(CONFIG_M586MMX)	+= $(call cc-option,-march=pentium-mmx,-march=i586)
+-cflags-$(CONFIG_M686)		+= -march=i686
+-cflags-$(CONFIG_MPENTIUMII)	+= -march=i686 $(call cc-option,-mtune=pentium2)
+-cflags-$(CONFIG_MPENTIUMIII)	+= -march=i686 $(call cc-option,-mtune=pentium3)
+-cflags-$(CONFIG_MPENTIUMM)	+= -march=i686 $(call cc-option,-mtune=pentium3)
+-cflags-$(CONFIG_MPENTIUM4)	+= -march=i686 $(call cc-option,-mtune=pentium4)
+-cflags-$(CONFIG_MK6)		+= -march=k6
+-# Please note, that patches that add -march=athlon-xp and friends are pointless.
+-# They make zero difference whatsosever to performance at this time.
+-cflags-$(CONFIG_MK7)		+= $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
+-cflags-$(CONFIG_MK8)		+= $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
+-cflags-$(CONFIG_MCRUSOE)	+= -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+-cflags-$(CONFIG_MEFFICEON)	+= -march=i686 $(call cc-option,-mtune=pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+-cflags-$(CONFIG_MWINCHIPC6)	+= $(call cc-option,-march=winchip-c6,-march=i586)
+-cflags-$(CONFIG_MWINCHIP2)	+= $(call cc-option,-march=winchip2,-march=i586)
+-cflags-$(CONFIG_MWINCHIP3D)	+= $(call cc-option,-march=winchip2,-march=i586)
+-cflags-$(CONFIG_MCYRIXIII)	+= $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+-cflags-$(CONFIG_MVIAC3_2)	+= $(call cc-option,-march=c3-2,-march=i686)
+-
+-# AMD Elan support
+-cflags-$(CONFIG_X86_ELAN)	+= -march=i486
+-
+-# Geode GX1 support
+-cflags-$(CONFIG_MGEODEGX1)		+= $(call cc-option,-march=pentium-mmx,-march=i486)
++# CPU-specific tuning. Anything which can be shared with UML should go here.
++include $(srctree)/arch/i386/Makefile.cpu
+ 
+ # -mregparm=3 works ok on gcc-3.0 and later
+ #
+diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu
+new file mode 100644
+--- /dev/null
++++ b/arch/i386/Makefile.cpu
+@@ -0,0 +1,41 @@
++# CPU tuning section - shared with UML.
++# Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML.
++
++#-mtune exists since gcc 3.4, and some -mcpu flavors didn't exist in gcc 2.95.
++HAS_MTUNE	:= $(call cc-option-yn, -mtune=i386)
++ifeq ($(HAS_MTUNE),y)
++tune		= $(call cc-option,-mtune=$(1),)
++else
++tune		= $(call cc-option,-mcpu=$(1),)
++endif
++
++align := $(cc-option-align)
++cflags-$(CONFIG_M386)		+= -march=i386
++cflags-$(CONFIG_M486)		+= -march=i486
++cflags-$(CONFIG_M586)		+= -march=i586
++cflags-$(CONFIG_M586TSC)	+= -march=i586
++cflags-$(CONFIG_M586MMX)	+= $(call cc-option,-march=pentium-mmx,-march=i586)
++cflags-$(CONFIG_M686)		+= -march=i686
++cflags-$(CONFIG_MPENTIUMII)	+= -march=i686 $(call tune,pentium2)
++cflags-$(CONFIG_MPENTIUMIII)	+= -march=i686 $(call tune,pentium3)
++cflags-$(CONFIG_MPENTIUMM)	+= -march=i686 $(call tune,pentium3)
++cflags-$(CONFIG_MPENTIUM4)	+= -march=i686 $(call tune,pentium4)
++cflags-$(CONFIG_MK6)		+= -march=k6
++# Please note, that patches that add -march=athlon-xp and friends are pointless.
++# They make zero difference whatsosever to performance at this time.
++cflags-$(CONFIG_MK7)		+= $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
++cflags-$(CONFIG_MK8)		+= $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
++cflags-$(CONFIG_MCRUSOE)	+= -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
++cflags-$(CONFIG_MEFFICEON)	+= -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
++cflags-$(CONFIG_MWINCHIPC6)	+= $(call cc-option,-march=winchip-c6,-march=i586)
++cflags-$(CONFIG_MWINCHIP2)	+= $(call cc-option,-march=winchip2,-march=i586)
++cflags-$(CONFIG_MWINCHIP3D)	+= $(call cc-option,-march=winchip2,-march=i586)
++cflags-$(CONFIG_MCYRIXIII)	+= $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
++cflags-$(CONFIG_MVIAC3_2)	+= $(call cc-option,-march=c3-2,-march=i686)
++
++# AMD Elan support
++cflags-$(CONFIG_X86_ELAN)	+= -march=i486
++
++# Geode GX1 support
++cflags-$(CONFIG_MGEODEGX1)		+= $(call cc-option,-march=pentium-mmx,-march=i486)
++
+diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
+--- a/arch/i386/kernel/apic.c
++++ b/arch/i386/kernel/apic.c
+@@ -1046,10 +1046,11 @@ static unsigned int calibration_result;
+ 
+ void __init setup_boot_APIC_clock(void)
+ {
++	unsigned long flags;
+ 	apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
+ 	using_apic_timer = 1;
+ 
+-	local_irq_disable();
++	local_irq_save(flags);
+ 
+ 	calibration_result = calibrate_APIC_clock();
+ 	/*
+@@ -1057,7 +1058,7 @@ void __init setup_boot_APIC_clock(void)
+ 	 */
+ 	setup_APIC_timer(calibration_result);
+ 
+-	local_irq_enable();
++	local_irq_restore(flags);
+ }
+ 
+ void __devinit setup_secondary_APIC_clock(void)
+diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
+--- a/arch/i386/kernel/apm.c
++++ b/arch/i386/kernel/apm.c
+@@ -597,12 +597,14 @@ static u8 apm_bios_call(u32 func, u32 eb
+ 	cpumask_t		cpus;
+ 	int			cpu;
+ 	struct desc_struct	save_desc_40;
++	struct desc_struct	*gdt;
+ 
+ 	cpus = apm_save_cpus();
+ 	
+ 	cpu = get_cpu();
+-	save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
+-	per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
++	gdt = get_cpu_gdt_table(cpu);
++	save_desc_40 = gdt[0x40 / 8];
++	gdt[0x40 / 8] = bad_bios_desc;
+ 
+ 	local_save_flags(flags);
+ 	APM_DO_CLI;
+@@ -610,7 +612,7 @@ static u8 apm_bios_call(u32 func, u32 eb
+ 	apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
+ 	APM_DO_RESTORE_SEGS;
+ 	local_irq_restore(flags);
+-	per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = save_desc_40;
++	gdt[0x40 / 8] = save_desc_40;
+ 	put_cpu();
+ 	apm_restore_cpus(cpus);
+ 	
+@@ -639,13 +641,14 @@ static u8 apm_bios_call_simple(u32 func,
+ 	cpumask_t		cpus;
+ 	int			cpu;
+ 	struct desc_struct	save_desc_40;
+-
++	struct desc_struct	*gdt;
+ 
+ 	cpus = apm_save_cpus();
+ 	
+ 	cpu = get_cpu();
+-	save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
+-	per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
++	gdt = get_cpu_gdt_table(cpu);
++	save_desc_40 = gdt[0x40 / 8];
++	gdt[0x40 / 8] = bad_bios_desc;
+ 
+ 	local_save_flags(flags);
+ 	APM_DO_CLI;
+@@ -653,7 +656,7 @@ static u8 apm_bios_call_simple(u32 func,
+ 	error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
+ 	APM_DO_RESTORE_SEGS;
+ 	local_irq_restore(flags);
+-	__get_cpu_var(cpu_gdt_table)[0x40 / 8] = save_desc_40;
++	gdt[0x40 / 8] = save_desc_40;
+ 	put_cpu();
+ 	apm_restore_cpus(cpus);
+ 	return error;
+@@ -2295,35 +2298,36 @@ static int __init apm_init(void)
+ 	apm_bios_entry.segment = APM_CS;
+ 
+ 	for (i = 0; i < NR_CPUS; i++) {
+-		set_base(per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
++		struct desc_struct *gdt = get_cpu_gdt_table(i);
++		set_base(gdt[APM_CS >> 3],
+ 			 __va((unsigned long)apm_info.bios.cseg << 4));
+-		set_base(per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
++		set_base(gdt[APM_CS_16 >> 3],
+ 			 __va((unsigned long)apm_info.bios.cseg_16 << 4));
+-		set_base(per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
++		set_base(gdt[APM_DS >> 3],
+ 			 __va((unsigned long)apm_info.bios.dseg << 4));
+ #ifndef APM_RELAX_SEGMENTS
+ 		if (apm_info.bios.version == 0x100) {
+ #endif
+ 			/* For ASUS motherboard, Award BIOS rev 110 (and others?) */
+-			_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 - 1);
++			_set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1);
+ 			/* For some unknown machine. */
+-			_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3], 64 * 1024 - 1);
++			_set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
+ 			/* For the DEC Hinote Ultra CT475 (and others?) */
+-			_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3], 64 * 1024 - 1);
++			_set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
+ #ifndef APM_RELAX_SEGMENTS
+ 		} else {
+-			_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
++			_set_limit((char *)&gdt[APM_CS >> 3],
+ 				(apm_info.bios.cseg_len - 1) & 0xffff);
+-			_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
++			_set_limit((char *)&gdt[APM_CS_16 >> 3],
+ 				(apm_info.bios.cseg_16_len - 1) & 0xffff);
+-			_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
++			_set_limit((char *)&gdt[APM_DS >> 3],
+ 				(apm_info.bios.dseg_len - 1) & 0xffff);
+ 		      /* workaround for broken BIOSes */
+ 	                if (apm_info.bios.cseg_len <= apm_info.bios.offset)
+-        	                _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 -1);
++        	                _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 -1);
+                        if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
+                         	/* for the BIOS that assumes granularity = 1 */
+-                        	per_cpu(cpu_gdt_table, i)[APM_DS >> 3].b |= 0x800000;
++                        	gdt[APM_DS >> 3].b |= 0x800000;
+                         	printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
+         	        }
+ 		}
+diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
+--- a/arch/i386/kernel/cpu/common.c
++++ b/arch/i386/kernel/cpu/common.c
+@@ -573,6 +573,7 @@ void __devinit cpu_init(void)
+ 	int cpu = smp_processor_id();
+ 	struct tss_struct * t = &per_cpu(init_tss, cpu);
+ 	struct thread_struct *thread = &current->thread;
++	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+ 	__u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
+ 
+ 	if (cpu_test_and_set(cpu, cpu_initialized)) {
+@@ -594,24 +595,16 @@ void __devinit cpu_init(void)
+ 	 * Initialize the per-CPU GDT with the boot GDT,
+ 	 * and set up the GDT descriptor:
+ 	 */
+-	memcpy(&per_cpu(cpu_gdt_table, cpu), cpu_gdt_table,
+-	       GDT_SIZE);
++ 	memcpy(gdt, cpu_gdt_table, GDT_SIZE);
+ 
+ 	/* Set up GDT entry for 16bit stack */
+-	*(__u64 *)&(per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_ESPFIX_SS]) |=
++ 	*(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
+ 		((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) |
+ 		((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
+ 		(CPU_16BIT_STACK_SIZE - 1);
+ 
+ 	cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
+-	cpu_gdt_descr[cpu].address =
+-	    (unsigned long)&per_cpu(cpu_gdt_table, cpu);
+-
+-	/*
+-	 * Set up the per-thread TLS descriptor cache:
+-	 */
+-	memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu),
+-		GDT_ENTRY_TLS_ENTRIES * 8);
++ 	cpu_gdt_descr[cpu].address = (unsigned long)gdt;
+ 
+ 	load_gdt(&cpu_gdt_descr[cpu]);
+ 	load_idt(&idt_descr);
+diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
++++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+@@ -32,6 +32,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+ #include <linux/compiler.h>
++#include <linux/sched.h>	/* current */
+ #include <asm/io.h>
+ #include <asm/delay.h>
+ #include <asm/uaccess.h>
+diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
++++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+@@ -28,6 +28,7 @@
+ #include <linux/cpufreq.h>
+ #include <linux/slab.h>
+ #include <linux/cpumask.h>
++#include <linux/sched.h>	/* current / set_cpus_allowed() */
+ 
+ #include <asm/processor.h> 
+ #include <asm/msr.h>
+diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
++++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+@@ -32,6 +32,7 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/cpumask.h>
++#include <linux/sched.h>	/* for current / set_cpus_allowed() */
+ 
+ #include <asm/msr.h>
+ #include <asm/io.h>
+diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
++++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+@@ -22,6 +22,7 @@
+ #include <linux/init.h>
+ #include <linux/cpufreq.h>
+ #include <linux/config.h>
++#include <linux/sched.h>	/* current */
+ #include <linux/delay.h>
+ #include <linux/compiler.h>
+ 
+diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
+--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
++++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
+@@ -3,6 +3,7 @@
+  *
+  *      Changes:
+  *      Venkatesh Pallipadi	: Adding cache identification through cpuid(4)
++ *		Ashok Raj <ashok.raj at intel.com>: Work with CPU hotplug infrastructure.
+  */
+ 
+ #include <linux/init.h>
+@@ -10,6 +11,7 @@
+ #include <linux/device.h>
+ #include <linux/compiler.h>
+ #include <linux/cpu.h>
++#include <linux/sched.h>
+ 
+ #include <asm/processor.h>
+ #include <asm/smp.h>
+@@ -28,7 +30,7 @@ struct _cache_table
+ };
+ 
+ /* all the cache descriptor types we care about (no TLB or trace cache entries) */
+-static struct _cache_table cache_table[] __devinitdata =
++static struct _cache_table cache_table[] __cpuinitdata =
+ {
+ 	{ 0x06, LVL_1_INST, 8 },	/* 4-way set assoc, 32 byte line size */
+ 	{ 0x08, LVL_1_INST, 16 },	/* 4-way set assoc, 32 byte line size */
+@@ -117,10 +119,9 @@ struct _cpuid4_info {
+ 	cpumask_t shared_cpu_map;
+ };
+ 
+-#define MAX_CACHE_LEAVES		4
+ static unsigned short			num_cache_leaves;
+ 
+-static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
++static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+ {
+ 	unsigned int		eax, ebx, ecx, edx;
+ 	union _cpuid4_leaf_eax	cache_eax;
+@@ -144,23 +145,18 @@ static int __init find_num_cache_leaves(
+ {
+ 	unsigned int		eax, ebx, ecx, edx;
+ 	union _cpuid4_leaf_eax	cache_eax;
+-	int 			i;
+-	int 			retval;
++	int 			i = -1;
+ 
+-	retval = MAX_CACHE_LEAVES;
+-	/* Do cpuid(4) loop to find out num_cache_leaves */
+-	for (i = 0; i < MAX_CACHE_LEAVES; i++) {
++	do {
++		++i;
++		/* Do cpuid(4) loop to find out num_cache_leaves */
+ 		cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
+ 		cache_eax.full = eax;
+-		if (cache_eax.split.type == CACHE_TYPE_NULL) {
+-			retval = i;
+-			break;
+-		}
+-	}
+-	return retval;
++	} while (cache_eax.split.type != CACHE_TYPE_NULL);
++	return i;
+ }
+ 
+-unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
++unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
+ {
+ 	unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
+ 	unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
+@@ -284,13 +280,7 @@ unsigned int __devinit init_intel_cachei
+ 		if ( l3 )
+ 			printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
+ 
+-		/*
+-		 * This assumes the L3 cache is shared; it typically lives in
+-		 * the northbridge.  The L1 caches are included by the L2
+-		 * cache, and so should not be included for the purpose of
+-		 * SMP switching weights.
+-		 */
+-		c->x86_cache_size = l2 ? l2 : (l1i+l1d);
++		c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
+ 	}
+ 
+ 	return l2;
+@@ -301,7 +291,7 @@ static struct _cpuid4_info *cpuid4_info[
+ #define CPUID4_INFO_IDX(x,y)    (&((cpuid4_info[x])[y]))
+ 
+ #ifdef CONFIG_SMP
+-static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
++static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+ {
+ 	struct _cpuid4_info	*this_leaf;
+ 	unsigned long num_threads_sharing;
+@@ -334,7 +324,7 @@ static void free_cache_attributes(unsign
+ 	cpuid4_info[cpu] = NULL;
+ }
+ 
+-static int __devinit detect_cache_attributes(unsigned int cpu)
++static int __cpuinit detect_cache_attributes(unsigned int cpu)
+ {
+ 	struct _cpuid4_info	*this_leaf;
+ 	unsigned long 		j;
+@@ -511,7 +501,7 @@ static void cpuid4_cache_sysfs_exit(unsi
+ 	free_cache_attributes(cpu);
+ }
+ 
+-static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu)
++static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
+ {
+ 
+ 	if (num_cache_leaves == 0)
+@@ -542,7 +532,7 @@ err_out:
+ }
+ 
+ /* Add/Remove cache interface for CPU device */
+-static int __devinit cache_add_dev(struct sys_device * sys_dev)
++static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
+ {
+ 	unsigned int cpu = sys_dev->id;
+ 	unsigned long i, j;
+@@ -579,7 +569,7 @@ static int __devinit cache_add_dev(struc
+ 	return retval;
+ }
+ 
+-static int __devexit cache_remove_dev(struct sys_device * sys_dev)
++static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
+ {
+ 	unsigned int cpu = sys_dev->id;
+ 	unsigned long i;
+@@ -588,24 +578,49 @@ static int __devexit cache_remove_dev(st
+ 		kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
+ 	kobject_unregister(cache_kobject[cpu]);
+ 	cpuid4_cache_sysfs_exit(cpu);
+-	return 0;
++	return;
++}
++
++static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
++					unsigned long action, void *hcpu)
++{
++	unsigned int cpu = (unsigned long)hcpu;
++	struct sys_device *sys_dev;
++
++	sys_dev = get_cpu_sysdev(cpu);
++	switch (action) {
++	case CPU_ONLINE:
++		cache_add_dev(sys_dev);
++		break;
++	case CPU_DEAD:
++		cache_remove_dev(sys_dev);
++		break;
++	}
++	return NOTIFY_OK;
+ }
+ 
+-static struct sysdev_driver cache_sysdev_driver = {
+-	.add = cache_add_dev,
+-	.remove = __devexit_p(cache_remove_dev),
++static struct notifier_block cacheinfo_cpu_notifier =
++{
++    .notifier_call = cacheinfo_cpu_callback,
+ };
+ 
+-/* Register/Unregister the cpu_cache driver */
+-static int __devinit cache_register_driver(void)
++static int __cpuinit cache_sysfs_init(void)
+ {
++	int i;
++
+ 	if (num_cache_leaves == 0)
+ 		return 0;
+ 
+-	return sysdev_driver_register(&cpu_sysdev_class,&cache_sysdev_driver);
++	register_cpu_notifier(&cacheinfo_cpu_notifier);
++
++	for_each_online_cpu(i) {
++		cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE,
++			(void *)(long)i);
++	}
++
++	return 0;
+ }
+ 
+-device_initcall(cache_register_driver);
++device_initcall(cache_sysfs_init);
+ 
+ #endif
+-
+diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c
+--- a/arch/i386/kernel/cpu/mcheck/p6.c
++++ b/arch/i386/kernel/cpu/mcheck/p6.c
+@@ -102,11 +102,16 @@ void __devinit intel_p6_mcheck_init(stru
+ 		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
+ 	nr_mce_banks = l & 0xff;
+ 
+-	/* Don't enable bank 0 on intel P6 cores, it goes bang quickly. */
+-	for (i=1; i<nr_mce_banks; i++) {
++	/*
++	 * Following the example in IA-32 SDM Vol 3:
++	 * - MC0_CTL should not be written
++	 * - Status registers on all banks should be cleared on reset
++	 */
++	for (i=1; i<nr_mce_banks; i++)
+ 		wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
++
++	for (i=0; i<nr_mce_banks; i++)
+ 		wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
+-	}
+ 
+ 	set_in_cr4 (X86_CR4_MCE);
+ 	printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
+diff --git a/arch/i386/kernel/cpu/mtrr/if.c b/arch/i386/kernel/cpu/mtrr/if.c
+--- a/arch/i386/kernel/cpu/mtrr/if.c
++++ b/arch/i386/kernel/cpu/mtrr/if.c
+@@ -149,60 +149,89 @@ mtrr_write(struct file *file, const char
+ 	return -EINVAL;
+ }
+ 
+-static int
+-mtrr_ioctl(struct inode *inode, struct file *file,
+-	   unsigned int cmd, unsigned long __arg)
++static long
++mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
+ {
+-	int err;
++	int err = 0;
+ 	mtrr_type type;
+ 	struct mtrr_sentry sentry;
+ 	struct mtrr_gentry gentry;
+ 	void __user *arg = (void __user *) __arg;
+ 
+ 	switch (cmd) {
++	case MTRRIOC_ADD_ENTRY:
++	case MTRRIOC_SET_ENTRY:
++	case MTRRIOC_DEL_ENTRY:
++	case MTRRIOC_KILL_ENTRY:
++	case MTRRIOC_ADD_PAGE_ENTRY:
++	case MTRRIOC_SET_PAGE_ENTRY:
++	case MTRRIOC_DEL_PAGE_ENTRY:
++	case MTRRIOC_KILL_PAGE_ENTRY:
++		if (copy_from_user(&sentry, arg, sizeof sentry))
++			return -EFAULT;
++		break;
++	case MTRRIOC_GET_ENTRY:
++	case MTRRIOC_GET_PAGE_ENTRY:
++		if (copy_from_user(&gentry, arg, sizeof gentry))
++			return -EFAULT;
++		break;
++#ifdef CONFIG_COMPAT
++	case MTRRIOC32_ADD_ENTRY:
++	case MTRRIOC32_SET_ENTRY:
++	case MTRRIOC32_DEL_ENTRY:
++	case MTRRIOC32_KILL_ENTRY:
++	case MTRRIOC32_ADD_PAGE_ENTRY:
++	case MTRRIOC32_SET_PAGE_ENTRY:
++	case MTRRIOC32_DEL_PAGE_ENTRY:
++	case MTRRIOC32_KILL_PAGE_ENTRY: {
++		struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg;
++		err = get_user(sentry.base, &s32->base);
++		err |= get_user(sentry.size, &s32->size);
++		err |= get_user(sentry.type, &s32->type);
++		if (err)
++			return err;
++		break;
++	}
++	case MTRRIOC32_GET_ENTRY:
++	case MTRRIOC32_GET_PAGE_ENTRY: {
++		struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
++		err = get_user(gentry.regnum, &g32->regnum);
++		err |= get_user(gentry.base, &g32->base);
++		err |= get_user(gentry.size, &g32->size);
++		err |= get_user(gentry.type, &g32->type);
++		if (err)
++			return err;
++		break;
++	}
++#endif
++	}
++
++	switch (cmd) {
+ 	default:
+ 		return -ENOTTY;
+ 	case MTRRIOC_ADD_ENTRY:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		if (copy_from_user(&sentry, arg, sizeof sentry))
+-			return -EFAULT;
+ 		err =
+ 		    mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
+ 				  file, 0);
+-		if (err < 0)
+-			return err;
+ 		break;
+ 	case MTRRIOC_SET_ENTRY:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		if (copy_from_user(&sentry, arg, sizeof sentry))
+-			return -EFAULT;
+ 		err = mtrr_add(sentry.base, sentry.size, sentry.type, 0);
+-		if (err < 0)
+-			return err;
+ 		break;
+ 	case MTRRIOC_DEL_ENTRY:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		if (copy_from_user(&sentry, arg, sizeof sentry))
+-			return -EFAULT;
+ 		err = mtrr_file_del(sentry.base, sentry.size, file, 0);
+-		if (err < 0)
+-			return err;
+ 		break;
+ 	case MTRRIOC_KILL_ENTRY:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		if (copy_from_user(&sentry, arg, sizeof sentry))
+-			return -EFAULT;
+ 		err = mtrr_del(-1, sentry.base, sentry.size);
+-		if (err < 0)
+-			return err;
+ 		break;
+ 	case MTRRIOC_GET_ENTRY:
+-		if (copy_from_user(&gentry, arg, sizeof gentry))
+-			return -EFAULT;
+ 		if (gentry.regnum >= num_var_ranges)
+ 			return -EINVAL;
+ 		mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
+@@ -217,60 +246,59 @@ mtrr_ioctl(struct inode *inode, struct f
+ 			gentry.type = type;
+ 		}
+ 
+-		if (copy_to_user(arg, &gentry, sizeof gentry))
+-			return -EFAULT;
+ 		break;
+ 	case MTRRIOC_ADD_PAGE_ENTRY:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		if (copy_from_user(&sentry, arg, sizeof sentry))
+-			return -EFAULT;
+ 		err =
+ 		    mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
+ 				  file, 1);
+-		if (err < 0)
+-			return err;
+ 		break;
+ 	case MTRRIOC_SET_PAGE_ENTRY:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		if (copy_from_user(&sentry, arg, sizeof sentry))
+-			return -EFAULT;
+ 		err = mtrr_add_page(sentry.base, sentry.size, sentry.type, 0);
+-		if (err < 0)
+-			return err;
+ 		break;
+ 	case MTRRIOC_DEL_PAGE_ENTRY:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		if (copy_from_user(&sentry, arg, sizeof sentry))
+-			return -EFAULT;
+ 		err = mtrr_file_del(sentry.base, sentry.size, file, 1);
+-		if (err < 0)
+-			return err;
+ 		break;
+ 	case MTRRIOC_KILL_PAGE_ENTRY:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		if (copy_from_user(&sentry, arg, sizeof sentry))
+-			return -EFAULT;
+ 		err = mtrr_del_page(-1, sentry.base, sentry.size);
+-		if (err < 0)
+-			return err;
+ 		break;
+ 	case MTRRIOC_GET_PAGE_ENTRY:
+-		if (copy_from_user(&gentry, arg, sizeof gentry))
+-			return -EFAULT;
+ 		if (gentry.regnum >= num_var_ranges)
+ 			return -EINVAL;
+ 		mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
+ 		gentry.type = type;
++		break;
++	}
++
++	if (err)
++		return err;
+ 
++	switch(cmd) {
++	case MTRRIOC_GET_ENTRY:
++	case MTRRIOC_GET_PAGE_ENTRY:
+ 		if (copy_to_user(arg, &gentry, sizeof gentry))
+-			return -EFAULT;
++			err = -EFAULT;
++		break;
++#ifdef CONFIG_COMPAT
++	case MTRRIOC32_GET_ENTRY:
++	case MTRRIOC32_GET_PAGE_ENTRY: {
++		struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
++		err = put_user(gentry.base, &g32->base);
++		err |= put_user(gentry.size, &g32->size);
++		err |= put_user(gentry.regnum, &g32->regnum);
++		err |= put_user(gentry.type, &g32->type);
+ 		break;
+ 	}
+-	return 0;
++#endif
++	}
++	return err;
+ }
+ 
+ static int
+@@ -310,7 +338,8 @@ static struct file_operations mtrr_fops 
+ 	.read    = seq_read,
+ 	.llseek  = seq_lseek,
+ 	.write   = mtrr_write,
+-	.ioctl   = mtrr_ioctl,
++	.unlocked_ioctl = mtrr_ioctl,
++	.compat_ioctl = mtrr_ioctl,
+ 	.release = mtrr_close,
+ };
+ 
+diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
+--- a/arch/i386/kernel/cpu/proc.c
++++ b/arch/i386/kernel/cpu/proc.c
+@@ -44,7 +44,7 @@ static int show_cpuinfo(struct seq_file 
+ 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ 
+ 		/* Intel-defined (#2) */
+-		"pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
++		"pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
+ 		"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
+ 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
+--- a/arch/i386/kernel/cpuid.c
++++ b/arch/i386/kernel/cpuid.c
+@@ -163,7 +163,7 @@ static int cpuid_class_device_create(int
+ 	int err = 0;
+ 	struct class_device *class_err;
+ 
+-	class_err = class_device_create(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
++	class_err = class_device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
+ 	if (IS_ERR(class_err))
+ 		err = PTR_ERR(class_err);
+ 	return err;
+diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
+--- a/arch/i386/kernel/crash.c
++++ b/arch/i386/kernel/crash.c
+@@ -21,7 +21,6 @@
+ #include <asm/hardirq.h>
+ #include <asm/nmi.h>
+ #include <asm/hw_irq.h>
+-#include <asm/apic.h>
+ #include <mach_ipi.h>
+ 
+ 
+@@ -148,7 +147,6 @@ static int crash_nmi_callback(struct pt_
+ 		regs = &fixed_regs;
+ 	}
+ 	crash_save_this_cpu(regs, cpu);
+-	disable_local_APIC();
+ 	atomic_dec(&waiting_for_crash_ipi);
+ 	/* Assume hlt works */
+ 	halt();
+@@ -188,7 +186,6 @@ static void nmi_shootdown_cpus(void)
+ 	}
+ 
+ 	/* Leave the nmi callback set */
+-	disable_local_APIC();
+ }
+ #else
+ static void nmi_shootdown_cpus(void)
+@@ -213,9 +210,5 @@ void machine_crash_shutdown(struct pt_re
+ 	/* Make a note of crashing cpu. Will be used in NMI callback.*/
+ 	crashing_cpu = smp_processor_id();
+ 	nmi_shootdown_cpus();
+-	lapic_shutdown();
+-#if defined(CONFIG_X86_IO_APIC)
+-	disable_IO_APIC();
+-#endif
+ 	crash_save_self(regs);
+ }
+diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
+--- a/arch/i386/kernel/io_apic.c
++++ b/arch/i386/kernel/io_apic.c
+@@ -46,6 +46,9 @@
+ int (*ioapic_renumber_irq)(int ioapic, int irq);
+ atomic_t irq_mis_count;
+ 
++/* Where if anywhere is the i8259 connect in external int mode */
++static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
++
+ static DEFINE_SPINLOCK(ioapic_lock);
+ 
+ /*
+@@ -738,7 +741,7 @@ static int find_irq_entry(int apic, int 
+ /*
+  * Find the pin to which IRQ[irq] (ISA) is connected
+  */
+-static int find_isa_irq_pin(int irq, int type)
++static int __init find_isa_irq_pin(int irq, int type)
+ {
+ 	int i;
+ 
+@@ -758,6 +761,33 @@ static int find_isa_irq_pin(int irq, int
+ 	return -1;
+ }
+ 
++static int __init find_isa_irq_apic(int irq, int type)
++{
++	int i;
++
++	for (i = 0; i < mp_irq_entries; i++) {
++		int lbus = mp_irqs[i].mpc_srcbus;
++
++		if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
++		     mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
++		     mp_bus_id_to_type[lbus] == MP_BUS_MCA ||
++		     mp_bus_id_to_type[lbus] == MP_BUS_NEC98
++		    ) &&
++		    (mp_irqs[i].mpc_irqtype == type) &&
++		    (mp_irqs[i].mpc_srcbusirq == irq))
++			break;
++	}
++	if (i < mp_irq_entries) {
++		int apic;
++		for(apic = 0; apic < nr_ioapics; apic++) {
++			if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
++				return apic;
++		}
++	}
++
++	return -1;
++}
++
+ /*
+  * Find a specific PCI IRQ entry.
+  * Not an __init, possibly needed by modules
+@@ -1253,7 +1283,7 @@ static void __init setup_IO_APIC_irqs(vo
+ /*
+  * Set up the 8259A-master output pin:
+  */
+-static void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
++static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
+ {
+ 	struct IO_APIC_route_entry entry;
+ 	unsigned long flags;
+@@ -1287,8 +1317,8 @@ static void __init setup_ExtINT_IRQ0_pin
+ 	 * Add it to the IO-APIC irq-routing table:
+ 	 */
+ 	spin_lock_irqsave(&ioapic_lock, flags);
+-	io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
+-	io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
++	io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
++	io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
+ 	spin_unlock_irqrestore(&ioapic_lock, flags);
+ 
+ 	enable_8259A_irq(0);
+@@ -1595,7 +1625,8 @@ void /*__init*/ print_PIC(void)
+ static void __init enable_IO_APIC(void)
+ {
+ 	union IO_APIC_reg_01 reg_01;
+-	int i;
++	int i8259_apic, i8259_pin;
++	int i, apic;
+ 	unsigned long flags;
+ 
+ 	for (i = 0; i < PIN_MAP_SIZE; i++) {
+@@ -1609,11 +1640,52 @@ static void __init enable_IO_APIC(void)
+ 	/*
+ 	 * The number of IO-APIC IRQ registers (== #pins):
+ 	 */
+-	for (i = 0; i < nr_ioapics; i++) {
++	for (apic = 0; apic < nr_ioapics; apic++) {
+ 		spin_lock_irqsave(&ioapic_lock, flags);
+-		reg_01.raw = io_apic_read(i, 1);
++		reg_01.raw = io_apic_read(apic, 1);
+ 		spin_unlock_irqrestore(&ioapic_lock, flags);
+-		nr_ioapic_registers[i] = reg_01.bits.entries+1;
++		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
++	}
++	for(apic = 0; apic < nr_ioapics; apic++) {
++		int pin;
++		/* See if any of the pins is in ExtINT mode */
++		for(pin = 0; pin < nr_ioapic_registers[i]; pin++) {
++			struct IO_APIC_route_entry entry;
++			spin_lock_irqsave(&ioapic_lock, flags);
++			*(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
++			*(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
++			spin_unlock_irqrestore(&ioapic_lock, flags);
++
++
++			/* If the interrupt line is enabled and in ExtInt mode
++			 * I have found the pin where the i8259 is connected.
++			 */
++			if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
++				ioapic_i8259.apic = apic;
++				ioapic_i8259.pin  = pin;
++				goto found_i8259;
++			}
++		}
++	}
++ found_i8259:
++	/* Look to see what if the MP table has reported the ExtINT */
++	/* If we could not find the appropriate pin by looking at the ioapic
++	 * the i8259 probably is not connected the ioapic but give the
++	 * mptable a chance anyway.
++	 */
++	i8259_pin  = find_isa_irq_pin(0, mp_ExtINT);
++	i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
++	/* Trust the MP table if nothing is setup in the hardware */
++	if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
++		printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
++		ioapic_i8259.pin  = i8259_pin;
++		ioapic_i8259.apic = i8259_apic;
++	}
++	/* Complain if the MP table and the hardware disagree */
++	if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
++		(i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
++	{
++		printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
+ 	}
+ 
+ 	/*
+@@ -1627,7 +1699,6 @@ static void __init enable_IO_APIC(void)
+  */
+ void disable_IO_APIC(void)
+ {
+-	int pin;
+ 	/*
+ 	 * Clear the IO-APIC before rebooting:
+ 	 */
+@@ -1638,8 +1709,7 @@ void disable_IO_APIC(void)
+ 	 * Put that IOAPIC in virtual wire mode
+ 	 * so legacy interrupts can be delivered.
+ 	 */
+-	pin = find_isa_irq_pin(0, mp_ExtINT);
+-	if (pin != -1) {
++	if (ioapic_i8259.pin != -1) {
+ 		struct IO_APIC_route_entry entry;
+ 		unsigned long flags;
+ 
+@@ -1650,7 +1720,7 @@ void disable_IO_APIC(void)
+ 		entry.polarity        = 0; /* High */
+ 		entry.delivery_status = 0;
+ 		entry.dest_mode       = 0; /* Physical */
+-		entry.delivery_mode   = 7; /* ExtInt */
++		entry.delivery_mode   = dest_ExtINT; /* ExtInt */
+ 		entry.vector          = 0;
+ 		entry.dest.physical.physical_dest = 0;
+ 
+@@ -1659,11 +1729,13 @@ void disable_IO_APIC(void)
+ 		 * Add it to the IO-APIC irq-routing table:
+ 		 */
+ 		spin_lock_irqsave(&ioapic_lock, flags);
+-		io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
+-		io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
++		io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
++			*(((int *)&entry)+1));
++		io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
++			*(((int *)&entry)+0));
+ 		spin_unlock_irqrestore(&ioapic_lock, flags);
+ 	}
+-	disconnect_bsp_APIC(pin != -1);
++	disconnect_bsp_APIC(ioapic_i8259.pin != -1);
+ }
+ 
+ /*
+@@ -2113,20 +2185,21 @@ static void setup_nmi (void)
+  */
+ static inline void unlock_ExtINT_logic(void)
+ {
+-	int pin, i;
++	int apic, pin, i;
+ 	struct IO_APIC_route_entry entry0, entry1;
+ 	unsigned char save_control, save_freq_select;
+ 	unsigned long flags;
+ 
+-	pin = find_isa_irq_pin(8, mp_INT);
++	pin  = find_isa_irq_pin(8, mp_INT);
++	apic = find_isa_irq_apic(8, mp_INT);
+ 	if (pin == -1)
+ 		return;
+ 
+ 	spin_lock_irqsave(&ioapic_lock, flags);
+-	*(((int *)&entry0) + 1) = io_apic_read(0, 0x11 + 2 * pin);
+-	*(((int *)&entry0) + 0) = io_apic_read(0, 0x10 + 2 * pin);
++	*(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
++	*(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
+ 	spin_unlock_irqrestore(&ioapic_lock, flags);
+-	clear_IO_APIC_pin(0, pin);
++	clear_IO_APIC_pin(apic, pin);
+ 
+ 	memset(&entry1, 0, sizeof(entry1));
+ 
+@@ -2139,8 +2212,8 @@ static inline void unlock_ExtINT_logic(v
+ 	entry1.vector = 0;
+ 
+ 	spin_lock_irqsave(&ioapic_lock, flags);
+-	io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
+-	io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
++	io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
++	io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
+ 	spin_unlock_irqrestore(&ioapic_lock, flags);
+ 
+ 	save_control = CMOS_READ(RTC_CONTROL);
+@@ -2158,11 +2231,11 @@ static inline void unlock_ExtINT_logic(v
+ 
+ 	CMOS_WRITE(save_control, RTC_CONTROL);
+ 	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+-	clear_IO_APIC_pin(0, pin);
++	clear_IO_APIC_pin(apic, pin);
+ 
+ 	spin_lock_irqsave(&ioapic_lock, flags);
+-	io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
+-	io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
++	io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
++	io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
+ 	spin_unlock_irqrestore(&ioapic_lock, flags);
+ }
+ 
+@@ -2174,7 +2247,7 @@ static inline void unlock_ExtINT_logic(v
+  */
+ static inline void check_timer(void)
+ {
+-	int pin1, pin2;
++	int apic1, pin1, apic2, pin2;
+ 	int vector;
+ 
+ 	/*
+@@ -2196,10 +2269,13 @@ static inline void check_timer(void)
+ 	timer_ack = 1;
+ 	enable_8259A_irq(0);
+ 
+-	pin1 = find_isa_irq_pin(0, mp_INT);
+-	pin2 = find_isa_irq_pin(0, mp_ExtINT);
++	pin1  = find_isa_irq_pin(0, mp_INT);
++	apic1 = find_isa_irq_apic(0, mp_INT);
++	pin2  = ioapic_i8259.pin;
++	apic2 = ioapic_i8259.apic;
+ 
+-	printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
++	printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
++		vector, apic1, pin1, apic2, pin2);
+ 
+ 	if (pin1 != -1) {
+ 		/*
+@@ -2216,8 +2292,9 @@ static inline void check_timer(void)
+ 				clear_IO_APIC_pin(0, pin1);
+ 			return;
+ 		}
+-		clear_IO_APIC_pin(0, pin1);
+-		printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
++		clear_IO_APIC_pin(apic1, pin1);
++		printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to "
++				"IO-APIC\n");
+ 	}
+ 
+ 	printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
+@@ -2226,13 +2303,13 @@ static inline void check_timer(void)
+ 		/*
+ 		 * legacy devices should be connected to IO APIC #0
+ 		 */
+-		setup_ExtINT_IRQ0_pin(pin2, vector);
++		setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
+ 		if (timer_irq_works()) {
+ 			printk("works.\n");
+ 			if (pin1 != -1)
+-				replace_pin_at_irq(0, 0, pin1, 0, pin2);
++				replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
+ 			else
+-				add_pin_to_irq(0, 0, pin2);
++				add_pin_to_irq(0, apic2, pin2);
+ 			if (nmi_watchdog == NMI_IO_APIC) {
+ 				setup_nmi();
+ 			}
+@@ -2241,7 +2318,7 @@ static inline void check_timer(void)
+ 		/*
+ 		 * Cleanup, just in case ...
+ 		 */
+-		clear_IO_APIC_pin(0, pin2);
++		clear_IO_APIC_pin(apic2, pin2);
+ 	}
+ 	printk(" failed.\n");
+ 
+diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
+--- a/arch/i386/kernel/irq.c
++++ b/arch/i386/kernel/irq.c
+@@ -218,7 +218,7 @@ int show_interrupts(struct seq_file *p, 
+ 
+ 	if (i == 0) {
+ 		seq_printf(p, "           ");
+-		for_each_cpu(j)
++		for_each_online_cpu(j)
+ 			seq_printf(p, "CPU%d       ",j);
+ 		seq_putc(p, '\n');
+ 	}
+@@ -232,7 +232,7 @@ int show_interrupts(struct seq_file *p, 
+ #ifndef CONFIG_SMP
+ 		seq_printf(p, "%10u ", kstat_irqs(i));
+ #else
+-		for_each_cpu(j)
++		for_each_online_cpu(j)
+ 			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ #endif
+ 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+@@ -246,12 +246,12 @@ skip:
+ 		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ 	} else if (i == NR_IRQS) {
+ 		seq_printf(p, "NMI: ");
+-		for_each_cpu(j)
++		for_each_online_cpu(j)
+ 			seq_printf(p, "%10u ", nmi_count(j));
+ 		seq_putc(p, '\n');
+ #ifdef CONFIG_X86_LOCAL_APIC
+ 		seq_printf(p, "LOC: ");
+-		for_each_cpu(j)
++		for_each_online_cpu(j)
+ 			seq_printf(p, "%10u ",
+ 				per_cpu(irq_stat,j).apic_timer_irqs);
+ 		seq_putc(p, '\n');
+diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
+--- a/arch/i386/kernel/mpparse.c
++++ b/arch/i386/kernel/mpparse.c
+@@ -69,7 +69,7 @@ unsigned int def_to_bigsmp = 0;
+ /* Processor that is doing the boot up */
+ unsigned int boot_cpu_physical_apicid = -1U;
+ /* Internal processor count */
+-static unsigned int __initdata num_processors;
++static unsigned int __devinitdata num_processors;
+ 
+ /* Bitmask of physically existing CPUs */
+ physid_mask_t phys_cpu_present_map;
+@@ -119,7 +119,7 @@ static int MP_valid_apicid(int apicid, i
+ }
+ #endif
+ 
+-static void __init MP_processor_info (struct mpc_config_processor *m)
++static void __devinit MP_processor_info (struct mpc_config_processor *m)
+ {
+  	int ver, apicid;
+ 	physid_mask_t phys_cpu;
+@@ -182,17 +182,6 @@ static void __init MP_processor_info (st
+ 		boot_cpu_physical_apicid = m->mpc_apicid;
+ 	}
+ 
+-	if (num_processors >= NR_CPUS) {
+-		printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
+-			"  Processor ignored.\n", NR_CPUS); 
+-		return;
+-	}
+-
+-	if (num_processors >= maxcpus) {
+-		printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
+-			" Processor ignored.\n", maxcpus); 
+-		return;
+-	}
+ 	ver = m->mpc_apicver;
+ 
+ 	if (!MP_valid_apicid(apicid, ver)) {
+@@ -201,11 +190,6 @@ static void __init MP_processor_info (st
+ 		return;
+ 	}
+ 
+-	cpu_set(num_processors, cpu_possible_map);
+-	num_processors++;
+-	phys_cpu = apicid_to_cpu_present(apicid);
+-	physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
+-
+ 	/*
+ 	 * Validate version
+ 	 */
+@@ -216,6 +200,25 @@ static void __init MP_processor_info (st
+ 		ver = 0x10;
+ 	}
+ 	apic_version[m->mpc_apicid] = ver;
++
++	phys_cpu = apicid_to_cpu_present(apicid);
++	physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
++
++	if (num_processors >= NR_CPUS) {
++		printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
++			"  Processor ignored.\n", NR_CPUS);
++		return;
++	}
++
++	if (num_processors >= maxcpus) {
++		printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
++			" Processor ignored.\n", maxcpus);
++		return;
++	}
++
++	cpu_set(num_processors, cpu_possible_map);
++	num_processors++;
++
+ 	if ((num_processors > 8) &&
+ 	    APIC_XAPIC(ver) &&
+ 	    (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
+@@ -834,7 +837,7 @@ void __init mp_register_lapic_address (
+ }
+ 
+ 
+-void __init mp_register_lapic (
++void __devinit mp_register_lapic (
+ 	u8			id, 
+ 	u8			enabled)
+ {
+diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
+--- a/arch/i386/kernel/msr.c
++++ b/arch/i386/kernel/msr.c
+@@ -246,7 +246,7 @@ static int msr_class_device_create(int i
+ 	int err = 0;
+ 	struct class_device *class_err;
+ 
+-	class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
++	class_err = class_device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
+ 	if (IS_ERR(class_err)) 
+ 		err = PTR_ERR(class_err);
+ 	return err;
+diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
+--- a/arch/i386/kernel/nmi.c
++++ b/arch/i386/kernel/nmi.c
+@@ -100,16 +100,44 @@ int nmi_active;
+ 	(P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT|	\
+ 	 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
+ 
++#ifdef CONFIG_SMP
++/* The performance counters used by NMI_LOCAL_APIC don't trigger when
++ * the CPU is idle. To make sure the NMI watchdog really ticks on all
++ * CPUs during the test make them busy.
++ */
++static __init void nmi_cpu_busy(void *data)
++{
++	volatile int *endflag = data;
++	local_irq_enable();
++	/* Intentionally don't use cpu_relax here. This is
++	   to make sure that the performance counter really ticks,
++	   even if there is a simulator or similar that catches the
++	   pause instruction. On a real HT machine this is fine because
++	   all other CPUs are busy with "useless" delay loops and don't
++	   care if they get somewhat less cycles. */
++	while (*endflag == 0)
++		barrier();
++}
++#endif
++
+ static int __init check_nmi_watchdog(void)
+ {
+-	unsigned int prev_nmi_count[NR_CPUS];
++	volatile int endflag = 0;
++	unsigned int *prev_nmi_count;
+ 	int cpu;
+ 
+ 	if (nmi_watchdog == NMI_NONE)
+ 		return 0;
+ 
++	prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
++	if (!prev_nmi_count)
++		return -1;
++
+ 	printk(KERN_INFO "Testing NMI watchdog ... ");
+ 
++	if (nmi_watchdog == NMI_LOCAL_APIC)
++		smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
++
+ 	for (cpu = 0; cpu < NR_CPUS; cpu++)
+ 		prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
+ 	local_irq_enable();
+@@ -123,12 +151,18 @@ static int __init check_nmi_watchdog(voi
+ 			continue;
+ #endif
+ 		if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
+-			printk("CPU#%d: NMI appears to be stuck!\n", cpu);
++			endflag = 1;
++			printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
++				cpu,
++				prev_nmi_count[cpu],
++				nmi_count(cpu));
+ 			nmi_active = 0;
+ 			lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
++			kfree(prev_nmi_count);
+ 			return -1;
+ 		}
+ 	}
++	endflag = 1;
+ 	printk("OK.\n");
+ 
+ 	/* now that we know it works we can reduce NMI frequency to
+@@ -136,6 +170,7 @@ static int __init check_nmi_watchdog(voi
+ 	if (nmi_watchdog == NMI_LOCAL_APIC)
+ 		nmi_hz = 1;
+ 
++	kfree(prev_nmi_count);
+ 	return 0;
+ }
+ /* This needs to happen later in boot so counters are working */
+diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
+--- a/arch/i386/kernel/ptrace.c
++++ b/arch/i386/kernel/ptrace.c
+@@ -354,7 +354,7 @@ ptrace_set_thread_area(struct task_struc
+ 	return 0;
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	struct user * dummy = NULL;
+diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c
+--- a/arch/i386/kernel/reboot_fixups.c
++++ b/arch/i386/kernel/reboot_fixups.c
+@@ -44,7 +44,7 @@ void mach_reboot_fixups(void)
+ 
+ 	for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
+ 		cur = &(fixups_table[i]);
+-		dev = pci_get_device(cur->vendor, cur->device, 0);
++		dev = pci_get_device(cur->vendor, cur->device, NULL);
+ 		if (!dev)
+ 			continue;
+ 
+diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
+--- a/arch/i386/kernel/setup.c
++++ b/arch/i386/kernel/setup.c
+@@ -389,14 +389,24 @@ static void __init limit_regions(unsigne
+ 		}
+ 	}
+ 	for (i = 0; i < e820.nr_map; i++) {
+-		if (e820.map[i].type == E820_RAM) {
+-			current_addr = e820.map[i].addr + e820.map[i].size;
+-			if (current_addr >= size) {
+-				e820.map[i].size -= current_addr-size;
+-				e820.nr_map = i + 1;
+-				return;
+-			}
++		current_addr = e820.map[i].addr + e820.map[i].size;
++		if (current_addr < size)
++			continue;
++
++		if (e820.map[i].type != E820_RAM)
++			continue;
++
++		if (e820.map[i].addr >= size) {
++			/*
++			 * This region starts past the end of the
++			 * requested size, skip it completely.
++			 */
++			e820.nr_map = i;
++		} else {
++			e820.nr_map = i + 1;
++			e820.map[i].size -= current_addr - size;
+ 		}
++		return;
+ 	}
+ }
+ 
+diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
+--- a/arch/i386/kernel/smpboot.c
++++ b/arch/i386/kernel/smpboot.c
+@@ -87,7 +87,11 @@ EXPORT_SYMBOL(cpu_online_map);
+ cpumask_t cpu_callin_map;
+ cpumask_t cpu_callout_map;
+ EXPORT_SYMBOL(cpu_callout_map);
++#ifdef CONFIG_HOTPLUG_CPU
++cpumask_t cpu_possible_map = CPU_MASK_ALL;
++#else
+ cpumask_t cpu_possible_map;
++#endif
+ EXPORT_SYMBOL(cpu_possible_map);
+ static cpumask_t smp_commenced_mask;
+ 
+diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
+--- a/arch/i386/kernel/srat.c
++++ b/arch/i386/kernel/srat.c
+@@ -327,7 +327,12 @@ int __init get_memcfg_from_srat(void)
+ 	int tables = 0;
+ 	int i = 0;
+ 
+-	acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, rsdp_address);
++	if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING,
++						rsdp_address))) {
++		printk("%s: System description tables not found\n",
++		       __FUNCTION__);
++		goto out_err;
++	}
+ 
+ 	if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) {
+ 		printk("%s: assigning address to rsdp\n", __FUNCTION__);
+diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
+--- a/arch/i386/kernel/time.c
++++ b/arch/i386/kernel/time.c
+@@ -74,10 +74,6 @@ int pit_latch_buggy;              /* ext
+ 
+ #include "do_timer.h"
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ unsigned int cpu_khz;	/* Detected as we calibrate the TSC */
+ EXPORT_SYMBOL(cpu_khz);
+ 
+diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
+--- a/arch/i386/kernel/time_hpet.c
++++ b/arch/i386/kernel/time_hpet.c
+@@ -275,6 +275,7 @@ static unsigned long PIE_freq = DEFAULT_
+ static unsigned long PIE_count;
+ 
+ static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
++static unsigned int hpet_t1_cmp; /* cached comparator register */
+ 
+ /*
+  * Timer 1 for RTC, we do not use periodic interrupt feature,
+@@ -306,10 +307,12 @@ int hpet_rtc_timer_init(void)
+ 	cnt = hpet_readl(HPET_COUNTER);
+ 	cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
+ 	hpet_writel(cnt, HPET_T1_CMP);
++	hpet_t1_cmp = cnt;
+ 	local_irq_restore(flags);
+ 
+ 	cfg = hpet_readl(HPET_T1_CFG);
+-	cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
++	cfg &= ~HPET_TN_PERIODIC;
++	cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
+ 	hpet_writel(cfg, HPET_T1_CFG);
+ 
+ 	return 1;
+@@ -319,8 +322,12 @@ static void hpet_rtc_timer_reinit(void)
+ {
+ 	unsigned int cfg, cnt;
+ 
+-	if (!(PIE_on | AIE_on | UIE_on))
++	if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
++		cfg = hpet_readl(HPET_T1_CFG);
++		cfg &= ~HPET_TN_ENABLE;
++		hpet_writel(cfg, HPET_T1_CFG);
+ 		return;
++	}
+ 
+ 	if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
+ 		hpet_rtc_int_freq = PIE_freq;
+@@ -328,15 +335,10 @@ static void hpet_rtc_timer_reinit(void)
+ 		hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
+ 
+ 	/* It is more accurate to use the comparator value than current count.*/
+-	cnt = hpet_readl(HPET_T1_CMP);
++	cnt = hpet_t1_cmp;
+ 	cnt += hpet_tick*HZ/hpet_rtc_int_freq;
+ 	hpet_writel(cnt, HPET_T1_CMP);
+-
+-	cfg = hpet_readl(HPET_T1_CFG);
+-	cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+-	hpet_writel(cfg, HPET_T1_CFG);
+-
+-	return;
++	hpet_t1_cmp = cnt;
+ }
+ 
+ /*
+diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c
+--- a/arch/i386/kernel/timers/timer_hpet.c
++++ b/arch/i386/kernel/timers/timer_hpet.c
+@@ -30,23 +30,28 @@ static seqlock_t monotonic_lock = SEQLOC
+  *  basic equation:
+  *		ns = cycles / (freq / ns_per_sec)
+  *		ns = cycles * (ns_per_sec / freq)
+- *		ns = cycles * (10^9 / (cpu_mhz * 10^6))
+- *		ns = cycles * (10^3 / cpu_mhz)
++ *		ns = cycles * (10^9 / (cpu_khz * 10^3))
++ *		ns = cycles * (10^6 / cpu_khz)
+  *
+  *	Then we use scaling math (suggested by george at mvista.com) to get:
+- *		ns = cycles * (10^3 * SC / cpu_mhz) / SC
++ *		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 at polymtl.ca)
++ *
+  *			-johnstul at us.ibm.com "math is hard, lets go shopping!"
+  */
+ static unsigned long cyc2ns_scale;
+ #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
+ 
+-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
++static inline void set_cyc2ns_scale(unsigned long cpu_khz)
+ {
+-	cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
++	cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
+ }
+ 
+ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
+@@ -163,7 +168,7 @@ static int __init init_hpet(char* overri
+ 				printk("Detected %u.%03u MHz processor.\n",
+ 					cpu_khz / 1000, cpu_khz % 1000);
+ 			}
+-			set_cyc2ns_scale(cpu_khz/1000);
++			set_cyc2ns_scale(cpu_khz);
+ 		}
+ 		/* set this only when cpu_has_tsc */
+ 		timer_hpet.read_timer = read_timer_tsc;
+diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
+--- a/arch/i386/kernel/timers/timer_tsc.c
++++ b/arch/i386/kernel/timers/timer_tsc.c
+@@ -49,23 +49,28 @@ static seqlock_t monotonic_lock = SEQLOC
+  *  basic equation:
+  *		ns = cycles / (freq / ns_per_sec)
+  *		ns = cycles * (ns_per_sec / freq)
+- *		ns = cycles * (10^9 / (cpu_mhz * 10^6))
+- *		ns = cycles * (10^3 / cpu_mhz)
++ *		ns = cycles * (10^9 / (cpu_khz * 10^3))
++ *		ns = cycles * (10^6 / cpu_khz)
+  *
+  *	Then we use scaling math (suggested by george at mvista.com) to get:
+- *		ns = cycles * (10^3 * SC / cpu_mhz) / SC
++ *		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.   
++ *  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 at polymtl.ca)
++ *
+  *			-johnstul at us.ibm.com "math is hard, lets go shopping!"
+  */
+ static unsigned long cyc2ns_scale; 
+ #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
+ 
+-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
++static inline void set_cyc2ns_scale(unsigned long cpu_khz)
+ {
+-	cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
++	cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
+ }
+ 
+ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
+@@ -286,7 +291,7 @@ time_cpufreq_notifier(struct notifier_bl
+ 		if (use_tsc) {
+ 			if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
+ 				fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
+-				set_cyc2ns_scale(cpu_khz/1000);
++				set_cyc2ns_scale(cpu_khz);
+ 			}
+ 		}
+ #endif
+@@ -536,7 +541,7 @@ static int __init init_tsc(char* overrid
+ 				printk("Detected %u.%03u MHz processor.\n",
+ 					cpu_khz / 1000, cpu_khz % 1000);
+ 			}
+-			set_cyc2ns_scale(cpu_khz/1000);
++			set_cyc2ns_scale(cpu_khz);
+ 			return 0;
+ 		}
+ 	}
+diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
+--- a/arch/i386/kernel/traps.c
++++ b/arch/i386/kernel/traps.c
+@@ -488,6 +488,7 @@ fastcall void __kprobes do_general_prote
+ 				tss->io_bitmap_max - thread->io_bitmap_max);
+ 		tss->io_bitmap_max = thread->io_bitmap_max;
+ 		tss->io_bitmap_base = IO_BITMAP_OFFSET;
++		tss->io_bitmap_owner = thread;
+ 		put_cpu();
+ 		return;
+ 	}
+diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
+--- a/arch/i386/kernel/vm86.c
++++ b/arch/i386/kernel/vm86.c
+@@ -134,17 +134,16 @@ struct pt_regs * fastcall save_v86_state
+ 	return ret;
+ }
+ 
+-static void mark_screen_rdonly(struct task_struct * tsk)
++static void mark_screen_rdonly(struct mm_struct *mm)
+ {
+ 	pgd_t *pgd;
+ 	pud_t *pud;
+ 	pmd_t *pmd;
+-	pte_t *pte, *mapped;
++	pte_t *pte;
++	spinlock_t *ptl;
+ 	int i;
+ 
+-	preempt_disable();
+-	spin_lock(&tsk->mm->page_table_lock);
+-	pgd = pgd_offset(tsk->mm, 0xA0000);
++	pgd = pgd_offset(mm, 0xA0000);
+ 	if (pgd_none_or_clear_bad(pgd))
+ 		goto out;
+ 	pud = pud_offset(pgd, 0xA0000);
+@@ -153,16 +152,14 @@ static void mark_screen_rdonly(struct ta
+ 	pmd = pmd_offset(pud, 0xA0000);
+ 	if (pmd_none_or_clear_bad(pmd))
+ 		goto out;
+-	pte = mapped = pte_offset_map(pmd, 0xA0000);
++	pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);
+ 	for (i = 0; i < 32; i++) {
+ 		if (pte_present(*pte))
+ 			set_pte(pte, pte_wrprotect(*pte));
+ 		pte++;
+ 	}
+-	pte_unmap(mapped);
++	pte_unmap_unlock(pte, ptl);
+ out:
+-	spin_unlock(&tsk->mm->page_table_lock);
+-	preempt_enable();
+ 	flush_tlb();
+ }
+ 
+@@ -306,7 +303,7 @@ static void do_sys_vm86(struct kernel_vm
+ 
+ 	tsk->thread.screen_bitmap = info->screen_bitmap;
+ 	if (info->flags & VM86_SCREEN_BITMAP)
+-		mark_screen_rdonly(tsk);
++		mark_screen_rdonly(tsk->mm);
+ 	__asm__ __volatile__(
+ 		"xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t"
+ 		"movl %0,%%esp\n\t"
+diff --git a/arch/i386/mach-es7000/es7000.h b/arch/i386/mach-es7000/es7000.h
+--- a/arch/i386/mach-es7000/es7000.h
++++ b/arch/i386/mach-es7000/es7000.h
+@@ -24,6 +24,15 @@
+  * http://www.unisys.com
+  */
+ 
++/*
++ * ES7000 chipsets
++ */
++
++#define NON_UNISYS		0
++#define ES7000_CLASSIC		1
++#define ES7000_ZORRO		2
++
++
+ #define	MIP_REG			1
+ #define	MIP_PSAI_REG		4
+ 
+@@ -106,6 +115,6 @@ struct mip_reg {
+ 
+ extern int parse_unisys_oem (char *oemptr);
+ extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
+-extern void setup_unisys ();
++extern void setup_unisys(void);
+ extern int es7000_start_cpu(int cpu, unsigned long eip);
+ extern void es7000_sw_apic(void);
+diff --git a/arch/i386/mach-es7000/es7000plat.c b/arch/i386/mach-es7000/es7000plat.c
+--- a/arch/i386/mach-es7000/es7000plat.c
++++ b/arch/i386/mach-es7000/es7000plat.c
+@@ -62,6 +62,9 @@ static unsigned int base;
+ static int
+ es7000_rename_gsi(int ioapic, int gsi)
+ {
++	if (es7000_plat == ES7000_ZORRO)
++		return gsi;
++
+ 	if (!base) {
+ 		int i;
+ 		for (i = 0; i < nr_ioapics; i++)
+@@ -76,7 +79,7 @@ es7000_rename_gsi(int ioapic, int gsi)
+ #endif	/* (CONFIG_X86_IO_APIC) && (CONFIG_ACPI) */
+ 
+ void __init
+-setup_unisys ()
++setup_unisys(void)
+ {
+ 	/*
+ 	 * Determine the generation of the ES7000 currently running.
+@@ -86,9 +89,9 @@ setup_unisys ()
+ 	 *
+ 	 */
+ 	if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
+-		es7000_plat = 2;
++		es7000_plat = ES7000_ZORRO;
+ 	else
+-		es7000_plat = 1;
++		es7000_plat = ES7000_CLASSIC;
+ 	ioapic_renumber_irq = es7000_rename_gsi;
+ }
+ 
+@@ -151,7 +154,7 @@ parse_unisys_oem (char *oemptr)
+ 	}
+ 
+ 	if (success < 2) {
+-		es7000_plat = 0;
++		es7000_plat = NON_UNISYS;
+ 	} else
+ 		setup_unisys();
+ 	return es7000_plat;
+diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
+--- a/arch/i386/mm/discontig.c
++++ b/arch/i386/mm/discontig.c
+@@ -98,7 +98,7 @@ unsigned long node_memmap_size_bytes(int
+ 
+ extern unsigned long find_max_low_pfn(void);
+ extern void find_max_pfn(void);
+-extern void one_highpage_init(struct page *, int, int);
++extern void add_one_highpage_init(struct page *, int, int);
+ 
+ extern struct e820map e820;
+ extern unsigned long init_pg_tables_end;
+@@ -427,7 +427,7 @@ void __init set_highmem_pages_init(int b
+ 			if (!pfn_valid(node_pfn))
+ 				continue;
+ 			page = pfn_to_page(node_pfn);
+-			one_highpage_init(page, node_pfn, bad_ppro);
++			add_one_highpage_init(page, node_pfn, bad_ppro);
+ 		}
+ 	}
+ 	totalram_pages += totalhigh_pages;
+diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
+--- a/arch/i386/mm/fault.c
++++ b/arch/i386/mm/fault.c
+@@ -108,7 +108,7 @@ static inline unsigned long get_segment_
+ 		desc = (void *)desc + (seg & ~7);
+ 	} else {
+ 		/* Must disable preemption while reading the GDT. */
+-		desc = (u32 *)&per_cpu(cpu_gdt_table, get_cpu());
++ 		desc = (u32 *)get_cpu_gdt_table(get_cpu());
+ 		desc = (void *)desc + (seg & ~7);
+ 	}
+ 
+diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
+--- a/arch/i386/mm/init.c
++++ b/arch/i386/mm/init.c
+@@ -27,6 +27,7 @@
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
+ #include <linux/efi.h>
++#include <linux/memory_hotplug.h>
+ 
+ #include <asm/processor.h>
+ #include <asm/system.h>
+@@ -266,17 +267,46 @@ static void __init permanent_kmaps_init(
+ 	pkmap_page_table = pte;	
+ }
+ 
+-void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
++void __devinit free_new_highpage(struct page *page)
++{
++	set_page_count(page, 1);
++	__free_page(page);
++	totalhigh_pages++;
++}
++
++void __init add_one_highpage_init(struct page *page, int pfn, int bad_ppro)
+ {
+ 	if (page_is_ram(pfn) && !(bad_ppro && page_kills_ppro(pfn))) {
+ 		ClearPageReserved(page);
+-		set_page_count(page, 1);
+-		__free_page(page);
+-		totalhigh_pages++;
++		free_new_highpage(page);
+ 	} else
+ 		SetPageReserved(page);
+ }
+ 
++static int add_one_highpage_hotplug(struct page *page, unsigned long pfn)
++{
++	free_new_highpage(page);
++	totalram_pages++;
++#ifdef CONFIG_FLATMEM
++	max_mapnr = max(pfn, max_mapnr);
++#endif
++	num_physpages++;
++	return 0;
++}
++
++/*
++ * Not currently handling the NUMA case.
++ * Assuming single node and all memory that
++ * has been added dynamically that would be
++ * onlined here is in HIGHMEM
++ */
++void online_page(struct page *page)
++{
++	ClearPageReserved(page);
++	add_one_highpage_hotplug(page, page_to_pfn(page));
++}
++
++
+ #ifdef CONFIG_NUMA
+ extern void set_highmem_pages_init(int);
+ #else
+@@ -284,7 +314,7 @@ static void __init set_highmem_pages_ini
+ {
+ 	int pfn;
+ 	for (pfn = highstart_pfn; pfn < highend_pfn; pfn++)
+-		one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
++		add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
+ 	totalram_pages += totalhigh_pages;
+ }
+ #endif /* CONFIG_FLATMEM */
+@@ -615,6 +645,28 @@ void __init mem_init(void)
+ #endif
+ }
+ 
++/*
++ * this is for the non-NUMA, single node SMP system case.
++ * Specifically, in the case of x86, we will always add
++ * memory to the highmem for now.
++ */
++#ifndef CONFIG_NEED_MULTIPLE_NODES
++int add_memory(u64 start, u64 size)
++{
++	struct pglist_data *pgdata = &contig_page_data;
++	struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;
++	unsigned long start_pfn = start >> PAGE_SHIFT;
++	unsigned long nr_pages = size >> PAGE_SHIFT;
++
++	return __add_pages(zone, start_pfn, nr_pages);
++}
++
++int remove_memory(u64 start, u64 size)
++{
++	return -EINVAL;
++}
++#endif
++
+ kmem_cache_t *pgd_cache;
+ kmem_cache_t *pmd_cache;
+ 
+diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
+--- a/arch/i386/mm/ioremap.c
++++ b/arch/i386/mm/ioremap.c
+@@ -28,7 +28,7 @@ static int ioremap_pte_range(pmd_t *pmd,
+ 	unsigned long pfn;
+ 
+ 	pfn = phys_addr >> PAGE_SHIFT;
+-	pte = pte_alloc_kernel(&init_mm, pmd, addr);
++	pte = pte_alloc_kernel(pmd, addr);
+ 	if (!pte)
+ 		return -ENOMEM;
+ 	do {
+@@ -87,14 +87,12 @@ static int ioremap_page_range(unsigned l
+ 	flush_cache_all();
+ 	phys_addr -= addr;
+ 	pgd = pgd_offset_k(addr);
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		next = pgd_addr_end(addr, end);
+ 		err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, flags);
+ 		if (err)
+ 			break;
+ 	} while (pgd++, addr = next, addr != end);
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_tlb_all();
+ 	return err;
+ }
+diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
+--- a/arch/i386/mm/pgtable.c
++++ b/arch/i386/mm/pgtable.c
+@@ -31,11 +31,13 @@ void show_mem(void)
+ 	pg_data_t *pgdat;
+ 	unsigned long i;
+ 	struct page_state ps;
++	unsigned long flags;
+ 
+ 	printk(KERN_INFO "Mem-info:\n");
+ 	show_free_areas();
+ 	printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+ 	for_each_pgdat(pgdat) {
++		pgdat_resize_lock(pgdat, &flags);
+ 		for (i = 0; i < pgdat->node_spanned_pages; ++i) {
+ 			page = pgdat_page_nr(pgdat, i);
+ 			total++;
+@@ -48,6 +50,7 @@ void show_mem(void)
+ 			else if (page_count(page))
+ 				shared += page_count(page) - 1;
+ 		}
++		pgdat_resize_unlock(pgdat, &flags);
+ 	}
+ 	printk(KERN_INFO "%d pages of RAM\n", total);
+ 	printk(KERN_INFO "%d pages of HIGHMEM\n", highmem);
+@@ -188,19 +191,19 @@ static inline void pgd_list_add(pgd_t *p
+ 	struct page *page = virt_to_page(pgd);
+ 	page->index = (unsigned long)pgd_list;
+ 	if (pgd_list)
+-		pgd_list->private = (unsigned long)&page->index;
++		set_page_private(pgd_list, (unsigned long)&page->index);
+ 	pgd_list = page;
+-	page->private = (unsigned long)&pgd_list;
++	set_page_private(page, (unsigned long)&pgd_list);
+ }
+ 
+ static inline void pgd_list_del(pgd_t *pgd)
+ {
+ 	struct page *next, **pprev, *page = virt_to_page(pgd);
+ 	next = (struct page *)page->index;
+-	pprev = (struct page **)page->private;
++	pprev = (struct page **)page_private(page);
+ 	*pprev = next;
+ 	if (next)
+-		next->private = (unsigned long)pprev;
++		set_page_private(next, (unsigned long)pprev);
+ }
+ 
+ void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+diff --git a/arch/i386/oprofile/backtrace.c b/arch/i386/oprofile/backtrace.c
+--- a/arch/i386/oprofile/backtrace.c
++++ b/arch/i386/oprofile/backtrace.c
+@@ -12,6 +12,7 @@
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+ #include <asm/ptrace.h>
++#include <asm/uaccess.h>
+ 
+ struct frame_head {
+ 	struct frame_head * ebp;
+@@ -21,26 +22,22 @@ struct frame_head {
+ static struct frame_head *
+ dump_backtrace(struct frame_head * head)
+ {
+-	oprofile_add_trace(head->ret);
++	struct frame_head bufhead[2];
+ 
+-	/* frame pointers should strictly progress back up the stack
+-	 * (towards higher addresses) */
+-	if (head >= head->ebp)
++	/* Also check accessibility of one struct frame_head beyond */
++	if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
++		return NULL;
++	if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
+ 		return NULL;
+ 
+-	return head->ebp;
+-}
+-
+-/* check that the page(s) containing the frame head are present */
+-static int pages_present(struct frame_head * head)
+-{
+-	struct mm_struct * mm = current->mm;
++	oprofile_add_trace(bufhead[0].ret);
+ 
+-	/* FIXME: only necessary once per page */
+-	if (!check_user_page_readable(mm, (unsigned long)head))
+-		return 0;
++	/* frame pointers should strictly progress back up the stack
++	 * (towards higher addresses) */
++	if (head >= bufhead[0].ebp)
++		return NULL;
+ 
+-	return check_user_page_readable(mm, (unsigned long)(head + 1));
++	return bufhead[0].ebp;
+ }
+ 
+ /*
+@@ -97,15 +94,6 @@ x86_backtrace(struct pt_regs * const reg
+ 		return;
+ 	}
+ 
+-#ifdef CONFIG_SMP
+-	if (!spin_trylock(&current->mm->page_table_lock))
+-		return;
+-#endif
+-
+-	while (depth-- && head && pages_present(head))
++	while (depth-- && head)
+ 		head = dump_backtrace(head);
+-
+-#ifdef CONFIG_SMP
+-	spin_unlock(&current->mm->page_table_lock);
+-#endif
+ }
+diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
+--- a/arch/i386/pci/fixup.c
++++ b/arch/i386/pci/fixup.c
+@@ -2,6 +2,8 @@
+  * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
+  */
+ 
++#include <linux/delay.h>
++#include <linux/dmi.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include "pci.h"
+@@ -384,3 +386,60 @@ static void __devinit pci_fixup_video(st
+ 	}
+ }
+ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
++
++/*
++ * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
++ *
++ * We pretend to bring them out of full D3 state, and restore the proper
++ * IRQ, PCI cache line size, and BARs, otherwise the device won't function
++ * properly.  In some cases, the device will generate an interrupt on
++ * the wrong IRQ line, causing any devices sharing the the line it's
++ * *supposed* to use to be disabled by the kernel's IRQ debug code.
++ */
++static u16 toshiba_line_size;
++
++static struct dmi_system_id __devinitdata toshiba_ohci1394_dmi_table[] = {
++	{
++		.ident = "Toshiba PS5 based laptop",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
++			DMI_MATCH(DMI_PRODUCT_VERSION, "PS5"),
++		},
++	},
++	{
++		.ident = "Toshiba PSM4 based laptop",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
++			DMI_MATCH(DMI_PRODUCT_VERSION, "PSM4"),
++		},
++	},
++	{ }
++};
++
++static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
++{
++	if (!dmi_check_system(toshiba_ohci1394_dmi_table))
++		return; /* only applies to certain Toshibas (so far) */
++
++	dev->current_state = PCI_D3cold;
++	pci_read_config_word(dev, PCI_CACHE_LINE_SIZE, &toshiba_line_size);
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0x8032,
++			 pci_pre_fixup_toshiba_ohci1394);
++
++static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev)
++{
++	if (!dmi_check_system(toshiba_ohci1394_dmi_table))
++		return; /* only applies to certain Toshibas (so far) */
++
++	/* Restore config space on Toshiba laptops */
++	mdelay(10);
++	pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size);
++	pci_write_config_word(dev, PCI_INTERRUPT_LINE, dev->irq);
++	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
++			       pci_resource_start(dev, 0));
++	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
++			       pci_resource_start(dev, 1));
++}
++DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032,
++			 pci_post_fixup_toshiba_ohci1394);
+diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
+--- a/arch/i386/pci/irq.c
++++ b/arch/i386/pci/irq.c
+@@ -547,31 +547,48 @@ static __init int intel_router_probe(str
+ 	return 0;
+ }
+ 
+-static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
++static __init int via_router_probe(struct irq_router *r,
++				struct pci_dev *router, u16 device)
+ {
+ 	/* FIXME: We should move some of the quirk fixup stuff here */
+ 
+-	if (router->device == PCI_DEVICE_ID_VIA_82C686 &&
+-			device == PCI_DEVICE_ID_VIA_82C586_0) {
+-		/* Asus k7m bios wrongly reports 82C686A as 586-compatible */
+-		device = PCI_DEVICE_ID_VIA_82C686;
++	/*
++	 * work arounds for some buggy BIOSes
++	 */
++	if (device == PCI_DEVICE_ID_VIA_82C586_0) {
++		switch(router->device) {
++		case PCI_DEVICE_ID_VIA_82C686:
++			/*
++			 * Asus k7m bios wrongly reports 82C686A
++			 * as 586-compatible
++			 */
++			device = PCI_DEVICE_ID_VIA_82C686;
++			break;
++		case PCI_DEVICE_ID_VIA_8235:
++			/**
++			 * Asus a7v-x bios wrongly reports 8235
++			 * as 586-compatible
++			 */
++			device = PCI_DEVICE_ID_VIA_8235;
++			break;
++		}
+ 	}
+ 
+-	switch(device)
+-	{
+-		case PCI_DEVICE_ID_VIA_82C586_0:
+-			r->name = "VIA";
+-			r->get = pirq_via586_get;
+-			r->set = pirq_via586_set;
+-			return 1;
+-		case PCI_DEVICE_ID_VIA_82C596:
+-		case PCI_DEVICE_ID_VIA_82C686:
+-		case PCI_DEVICE_ID_VIA_8231:
++	switch(device) {
++	case PCI_DEVICE_ID_VIA_82C586_0:
++		r->name = "VIA";
++		r->get = pirq_via586_get;
++		r->set = pirq_via586_set;
++		return 1;
++	case PCI_DEVICE_ID_VIA_82C596:
++	case PCI_DEVICE_ID_VIA_82C686:
++	case PCI_DEVICE_ID_VIA_8231:
++	case PCI_DEVICE_ID_VIA_8235:
+ 		/* FIXME: add new ones for 8233/5 */
+-			r->name = "VIA";
+-			r->get = pirq_via_get;
+-			r->set = pirq_via_set;
+-			return 1;
++		r->name = "VIA";
++		r->get = pirq_via_get;
++		r->set = pirq_via_set;
++		return 1;
+ 	}
+ 	return 0;
+ }
+diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
+--- a/arch/i386/power/cpu.c
++++ b/arch/i386/power/cpu.c
+@@ -51,16 +51,14 @@ void save_processor_state(void)
+ 	__save_processor_state(&saved_context);
+ }
+ 
+-static void
+-do_fpu_end(void)
++static void do_fpu_end(void)
+ {
+-        /* restore FPU regs if necessary */
+-	/* Do it out of line so that gcc does not move cr0 load to some stupid place */
+-        kernel_fpu_end();
+-	mxcsr_feature_mask_init();
++	/*
++	 * Restore FPU regs if necessary.
++	 */
++	kernel_fpu_end();
+ }
+ 
+-
+ static void fix_processor_context(void)
+ {
+ 	int cpu = smp_processor_id();
+diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
+--- a/arch/ia64/Kconfig
++++ b/arch/ia64/Kconfig
+@@ -63,8 +63,6 @@ config IA64_GENERIC
+ 	select ACPI
+ 	select NUMA
+ 	select ACPI_NUMA
+-	select VIRTUAL_MEM_MAP
+-	select DISCONTIGMEM
+ 	help
+ 	  This selects the system type of your hardware.  A "generic" kernel
+ 	  will run on any supported IA-64 system.  However, if you configure
+@@ -176,40 +174,6 @@ config IA64_L1_CACHE_SHIFT
+ 	default "6" if ITANIUM
+ 
+ # align cache-sensitive data to 64 bytes
+-config NUMA
+-	bool "NUMA support"
+-	depends on !IA64_HP_SIM
+-	default y if IA64_SGI_SN2
+-	select ACPI_NUMA
+-	help
+-	  Say Y to compile the kernel to support NUMA (Non-Uniform Memory
+-	  Access).  This option is for configuring high-end multiprocessor
+-	  server systems.  If in doubt, say N.
+-
+-config VIRTUAL_MEM_MAP
+-	bool "Virtual mem map"
+-	default y if !IA64_HP_SIM
+-	help
+-	  Say Y to compile the kernel with support for a virtual mem map.
+-	  This code also only takes effect if a memory hole of greater than
+-	  1 Gb is found during boot.  You must turn this option on if you
+-	  require the DISCONTIGMEM option for your machine. If you are
+-	  unsure, say Y.
+-
+-config HOLES_IN_ZONE
+-	bool
+-	default y if VIRTUAL_MEM_MAP
+-
+-config ARCH_DISCONTIGMEM_ENABLE
+-	bool "Discontiguous memory support"
+-	depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP
+-	default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
+-	help
+-	  Say Y to support efficient handling of discontiguous physical memory,
+-	  for architectures which are either NUMA (Non-Uniform Memory Access)
+-	  or have huge holes in the physical address space for other reasons.
+-	  See <file:Documentation/vm/numa> for more.
+-
+ config IA64_CYCLONE
+ 	bool "Cyclone (EXA) Time Source support"
+ 	help
+@@ -232,8 +196,10 @@ config IA64_SGI_SN_XP
+ 	  based on a network adapter and DMA messaging.
+ 
+ config FORCE_MAX_ZONEORDER
+-	int
+-	default "18"
++	int "MAX_ORDER (11 - 17)"  if !HUGETLB_PAGE
++	range 11 17  if !HUGETLB_PAGE
++	default "17" if HUGETLB_PAGE
++	default "11"
+ 
+ config SMP
+ 	bool "Symmetric multi-processing support"
+@@ -254,8 +220,8 @@ config SMP
+ 	  If you don't know what to do here, say N.
+ 
+ config NR_CPUS
+-	int "Maximum number of CPUs (2-512)"
+-	range 2 512
++	int "Maximum number of CPUs (2-1024)"
++	range 2 1024
+ 	depends on SMP
+ 	default "64"
+ 	help
+@@ -298,6 +264,58 @@ config PREEMPT
+ 
+ source "mm/Kconfig"
+ 
++config ARCH_SELECT_MEMORY_MODEL
++	def_bool y
++
++config ARCH_DISCONTIGMEM_ENABLE
++	def_bool y
++	help
++	  Say Y to support efficient handling of discontiguous physical memory,
++	  for architectures which are either NUMA (Non-Uniform Memory Access)
++	  or have huge holes in the physical address space for other reasons.
++ 	  See <file:Documentation/vm/numa> for more.
++
++config ARCH_FLATMEM_ENABLE
++	def_bool y
++
++config ARCH_SPARSEMEM_ENABLE
++	def_bool y
++	depends on ARCH_DISCONTIGMEM_ENABLE
++
++config ARCH_DISCONTIGMEM_DEFAULT
++	def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB)
++	depends on ARCH_DISCONTIGMEM_ENABLE
++
++config NUMA
++	bool "NUMA support"
++	depends on !IA64_HP_SIM && !FLATMEM
++	default y if IA64_SGI_SN2
++	help
++	  Say Y to compile the kernel to support NUMA (Non-Uniform Memory
++	  Access).  This option is for configuring high-end multiprocessor
++	  server systems.  If in doubt, say N.
++
++# VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent.
++# VIRTUAL_MEM_MAP has been retained for historical reasons.
++config VIRTUAL_MEM_MAP
++	bool "Virtual mem map"
++	depends on !SPARSEMEM
++	default y if !IA64_HP_SIM
++	help
++	  Say Y to compile the kernel with support for a virtual mem map.
++	  This code also only takes effect if a memory hole of greater than
++	  1 Gb is found during boot.  You must turn this option on if you
++	  require the DISCONTIGMEM option for your machine. If you are
++	  unsure, say Y.
++
++config HOLES_IN_ZONE
++	bool
++	default y if VIRTUAL_MEM_MAP
++
++config HAVE_ARCH_EARLY_PFN_TO_NID
++	def_bool y
++	depends on NEED_MULTIPLE_NODES
++
+ config IA32_SUPPORT
+ 	bool "Support for Linux/x86 binaries"
+ 	help
+diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig
+--- a/arch/ia64/configs/bigsur_defconfig
++++ b/arch/ia64/configs/bigsur_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Mon Nov 29 13:27:48 2004
++# Linux kernel version: 2.6.14-rc1
++# Wed Sep 14 15:18:49 2005
+ #
+ 
+ #
+@@ -10,34 +10,40 @@
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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 is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=16
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++# CONFIG_CPUSETS is not set
++CONFIG_INITRAMFS_SOURCE=""
+ # 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 is not set
+ CONFIG_SHMEM=y
+ CONFIG_CC_ALIGN_FUNCTIONS=0
+ CONFIG_CC_ALIGN_LABELS=0
+ CONFIG_CC_ALIGN_LOOPS=0
+ CONFIG_CC_ALIGN_JUMPS=0
+ # CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
+ 
+ #
+ # Loadable module support
+@@ -58,12 +64,15 @@ CONFIG_IA64=y
+ CONFIG_64BIT=y
+ CONFIG_MMU=y
+ CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
+ CONFIG_TIME_INTERPOLATION=y
+ CONFIG_EFI=y
+ CONFIG_GENERIC_IOMAP=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=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=y
+@@ -72,17 +81,30 @@ CONFIG_ITANIUM=y
+ # CONFIG_IA64_PAGE_SIZE_8KB is not set
+ CONFIG_IA64_PAGE_SIZE_16KB=y
+ # CONFIG_IA64_PAGE_SIZE_64KB is not set
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
+ CONFIG_IA64_BRL_EMU=y
+ CONFIG_IA64_L1_CACHE_SHIFT=6
+ # CONFIG_NUMA is not set
+ # CONFIG_VIRTUAL_MEM_MAP is not set
+ # CONFIG_IA64_CYCLONE is not set
+ CONFIG_IOSAPIC=y
++# CONFIG_IA64_SGI_SN_XP is not set
+ CONFIG_FORCE_MAX_ZONEORDER=18
+ CONFIG_SMP=y
+ CONFIG_NR_CPUS=2
+ # CONFIG_HOTPLUG_CPU is not set
++# CONFIG_SCHED_SMT is not set
+ CONFIG_PREEMPT=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_HAVE_DEC_LOCK=y
+ CONFIG_IA32_SUPPORT=y
+ CONFIG_COMPAT=y
+@@ -95,6 +117,7 @@ CONFIG_IA64_PALINFO=y
+ #
+ CONFIG_EFI_VARS=y
+ CONFIG_EFI_PCDP=y
++# CONFIG_DELL_RBU is not set
+ CONFIG_BINFMT_ELF=y
+ CONFIG_BINFMT_MISC=m
+ 
+@@ -102,18 +125,26 @@ CONFIG_BINFMT_MISC=m
+ # Power management and ACPI
+ #
+ CONFIG_PM=y
+-CONFIG_ACPI=y
++# CONFIG_PM_DEBUG is not set
+ 
+ #
+ # ACPI (Advanced Configuration and Power Interface) Support
+ #
++CONFIG_ACPI=y
+ CONFIG_ACPI_BUTTON=m
+ CONFIG_ACPI_FAN=m
+ CONFIG_ACPI_PROCESSOR=m
+ CONFIG_ACPI_THERMAL=m
++CONFIG_ACPI_BLACKLIST_YEAR=0
+ # CONFIG_ACPI_DEBUG is not set
+ CONFIG_ACPI_POWER=y
+ CONFIG_ACPI_SYSTEM=y
++# CONFIG_ACPI_CONTAINER is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
+ 
+ #
+ # Bus options (PCI, PCMCIA)
+@@ -122,7 +153,7 @@ CONFIG_PCI=y
+ CONFIG_PCI_DOMAINS=y
+ # CONFIG_PCI_MSI is not set
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
++# CONFIG_PCI_DEBUG is not set
+ 
+ #
+ # PCI Hotplug Support
+@@ -135,8 +166,70 @@ CONFIG_PCI_NAMES=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE is not set
++
++#
++# Network testing
+ #
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_NETFILTER_NETLINK 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
+@@ -151,6 +244,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_DEBUG_DRIVER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -163,7 +261,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Plug and Play support
+ #
+-# CONFIG_PNP is not set
++CONFIG_PNP=y
++# CONFIG_PNP_DEBUG is not set
++
++#
++# Protocols
++#
++CONFIG_PNPACPI=y
+ 
+ #
+ # Block devices
+@@ -172,14 +276,15 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # 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=m
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_UB is not set
+ CONFIG_BLK_DEV_RAM=m
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+@@ -189,6 +294,7 @@ CONFIG_IOSCHED_NOOP=y
+ CONFIG_IOSCHED_AS=y
+ CONFIG_IOSCHED_DEADLINE=y
+ CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
+ 
+ #
+ # ATA/ATAPI/MFM/RLL support
+@@ -211,7 +317,8 @@ CONFIG_BLK_DEV_IDEFLOPPY=m
+ #
+ # IDE chipset support/bugfixes
+ #
+-CONFIG_IDE_GENERIC=m
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_IDEPNP is not set
+ CONFIG_BLK_DEV_IDEPCI=y
+ CONFIG_IDEPCI_SHARE_IRQ=y
+ # CONFIG_BLK_DEV_OFFBOARD is not set
+@@ -233,6 +340,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
+ # CONFIG_BLK_DEV_HPT366 is not set
+ # CONFIG_BLK_DEV_SC1200 is not set
+ CONFIG_BLK_DEV_PIIX=m
++# 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
+@@ -250,6 +358,7 @@ CONFIG_IDEDMA_AUTO=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -261,6 +370,7 @@ CONFIG_BLK_DEV_SD=y
+ # 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
+@@ -274,6 +384,8 @@ CONFIG_SCSI_LOGGING=y
+ #
+ CONFIG_SCSI_SPI_ATTRS=m
+ # 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
+@@ -288,18 +400,13 @@ CONFIG_SCSI_SPI_ATTRS=m
+ # CONFIG_MEGARAID_NEWGEN is not set
+ # CONFIG_MEGARAID_LEGACY is not set
+ # CONFIG_SCSI_SATA is not set
+-# CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_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_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ CONFIG_SCSI_QLOGIC_1280=y
+ # CONFIG_SCSI_QLOGIC_1280_1040 is not set
+@@ -309,7 +416,8 @@ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA2300 is not set
+ # CONFIG_SCSI_QLA2322 is not set
+ # CONFIG_SCSI_QLA6312 is not set
+-# CONFIG_SCSI_QLA6322 is not set
++# CONFIG_SCSI_QLA24XX is not set
++# CONFIG_SCSI_LPFC is not set
+ # CONFIG_SCSI_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+ # CONFIG_SCSI_DEBUG is not set
+@@ -332,11 +440,14 @@ CONFIG_DM_CRYPT=m
+ CONFIG_DM_SNAPSHOT=m
+ CONFIG_DM_MIRROR=m
+ CONFIG_DM_ZERO=m
++# CONFIG_DM_MULTIPATH is not set
+ 
+ #
+ # Fusion MPT device support
+ #
+ # CONFIG_FUSION is not set
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -349,72 +460,14 @@ CONFIG_DM_ZERO=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
++# Network device support
+ #
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-# CONFIG_NETLINK_DEV 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_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_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=y
+ # CONFIG_BONDING is not set
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
++# CONFIG_NET_SB1000 is not set
+ 
+ #
+ # ARCnet devices
+@@ -422,6 +475,11 @@ CONFIG_DUMMY=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -443,7 +501,6 @@ CONFIG_NET_PCI=y
+ # CONFIG_FORCEDETH is not set
+ # CONFIG_DGRS is not set
+ CONFIG_EEPRO100=y
+-# CONFIG_EEPRO100_PIO is not set
+ # CONFIG_E100 is not set
+ # CONFIG_FEALNX is not set
+ # CONFIG_NATSEMI is not set
+@@ -465,13 +522,17 @@ CONFIG_EEPRO100=y
+ # 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_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
+ 
+@@ -496,6 +557,8 @@ CONFIG_EEPRO100=y
+ # 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
+@@ -525,18 +588,6 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_I8042=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_RAW is not set
+-
+-#
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
+@@ -554,6 +605,17 @@ CONFIG_MOUSE_PS2=y
+ # 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
+@@ -571,7 +633,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ CONFIG_SERIAL_8250_EXTENDED=y
+ CONFIG_SERIAL_8250_SHARE_IRQ=y
+ # CONFIG_SERIAL_8250_DETECT_IRQ is not set
+-# CONFIG_SERIAL_8250_MULTIPORT is not set
+ # CONFIG_SERIAL_8250_RSA is not set
+ 
+ #
+@@ -579,6 +640,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
+ #
+ 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
+@@ -603,14 +665,22 @@ CONFIG_EFI_RTC=y
+ #
+ CONFIG_AGP=m
+ CONFIG_AGP_I460=m
+-CONFIG_DRM=y
++CONFIG_DRM=m
+ # CONFIG_DRM_TDFX is not set
+ CONFIG_DRM_R128=m
+ # CONFIG_DRM_RADEON is not set
+ # CONFIG_DRM_MGA is not set
+ # CONFIG_DRM_SIS is not set
++# CONFIG_DRM_VIA is not set
++# CONFIG_DRM_SAVAGE is not set
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_HPET is not set
++# CONFIG_HANGCHECK_TIMER is not set
++
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
+ 
+ #
+ # I2C support
+@@ -635,7 +705,7 @@ CONFIG_I2C_ALGOBIT=y
+ # CONFIG_I2C_AMD8111 is not set
+ # CONFIG_I2C_I801 is not set
+ # CONFIG_I2C_I810 is not set
+-# CONFIG_I2C_ISA is not set
++# CONFIG_I2C_PIIX4 is not set
+ # CONFIG_I2C_NFORCE2 is not set
+ # CONFIG_I2C_PARPORT_LIGHT is not set
+ # CONFIG_I2C_PROSAVAGE is not set
+@@ -651,16 +721,43 @@ CONFIG_I2C_ALGOBIT=y
+ # CONFIG_I2C_PCA_ISA is not set
+ 
+ #
+-# Hardware Sensors Chip support
++# Miscellaneous I2C Chip support
+ #
+-# CONFIG_I2C_SENSOR is not set
++# 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_RTC8564 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
++
++#
++# 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_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
+@@ -671,33 +768,26 @@ CONFIG_I2C_ALGOBIT=y
+ # 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_SMSC47B397 is not set
+ # CONFIG_SENSORS_VIA686A 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
+ 
+ #
+-# Other I2C Chip support
+-#
+-# CONFIG_SENSORS_EEPROM is not set
+-# CONFIG_SENSORS_PCF8574 is not set
+-# CONFIG_SENSORS_PCF8591 is not set
+-# CONFIG_SENSORS_RTC8564 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
+-
+-#
+-# Dallas's 1-wire bus
++# Misc devices
+ #
+-# CONFIG_W1 is not set
+ 
+ #
+-# Misc devices
++# Multimedia Capabilities Port drivers
+ #
+ 
+ #
+@@ -752,11 +842,12 @@ CONFIG_SND_OPL3_LIB=m
+ # CONFIG_SND_MTPAV is not set
+ # CONFIG_SND_SERIAL_U16550 is not set
+ # CONFIG_SND_MPU401 is not set
++CONFIG_SND_AC97_CODEC=m
++CONFIG_SND_AC97_BUS=m
+ 
+ #
+ # PCI devices
+ #
+-CONFIG_SND_AC97_CODEC=m
+ # CONFIG_SND_ALI5451 is not set
+ # CONFIG_SND_ATIIXP is not set
+ # CONFIG_SND_ATIIXP_MODEM is not set
+@@ -768,6 +859,8 @@ CONFIG_SND_AC97_CODEC=m
+ # CONFIG_SND_CS46XX is not set
+ CONFIG_SND_CS4281=m
+ # CONFIG_SND_EMU10K1 is not set
++# CONFIG_SND_EMU10K1X is not set
++# CONFIG_SND_CA0106 is not set
+ # CONFIG_SND_KORG1212 is not set
+ # CONFIG_SND_MIXART is not set
+ # CONFIG_SND_NM256 is not set
+@@ -775,9 +868,10 @@ CONFIG_SND_CS4281=m
+ # CONFIG_SND_RME96 is not set
+ # CONFIG_SND_RME9652 is not set
+ # CONFIG_SND_HDSP is not set
++# CONFIG_SND_HDSPM is not set
+ # CONFIG_SND_TRIDENT is not set
+ # CONFIG_SND_YMFPCI is not set
+-# CONFIG_SND_ALS4000 is not set
++# CONFIG_SND_AD1889 is not set
+ # CONFIG_SND_CMIPCI is not set
+ # CONFIG_SND_ENS1370 is not set
+ # CONFIG_SND_ENS1371 is not set
+@@ -791,13 +885,14 @@ CONFIG_SND_CS4281=m
+ # CONFIG_SND_INTEL8X0M is not set
+ # CONFIG_SND_SONICVIBES is not set
+ # CONFIG_SND_VIA82XX is not set
++# CONFIG_SND_VIA82XX_MODEM is not set
+ # CONFIG_SND_VX222 is not set
++# CONFIG_SND_HDA_INTEL is not set
+ 
+ #
+ # USB devices
+ #
+ # CONFIG_SND_USB_AUDIO is not set
+-# CONFIG_SND_USB_USX2Y is not set
+ 
+ #
+ # Open Sound System
+@@ -807,6 +902,8 @@ CONFIG_SND_CS4281=m
+ #
+ # USB support
+ #
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
+ CONFIG_USB=m
+ # CONFIG_USB_DEBUG is not set
+ 
+@@ -818,35 +915,38 @@ CONFIG_USB_DEVICEFS=y
+ # CONFIG_USB_DYNAMIC_MINORS is not set
+ # CONFIG_USB_SUSPEND is not set
+ # CONFIG_USB_OTG is not set
+-CONFIG_USB_ARCH_HAS_HCD=y
+-CONFIG_USB_ARCH_HAS_OHCI=y
+ 
+ #
+ # USB Host Controller Drivers
+ #
+ # CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
+ # CONFIG_USB_OHCI_HCD is not set
+ CONFIG_USB_UHCI_HCD=m
++# CONFIG_USB_SL811_HCD is not set
+ 
+ #
+ # USB Device Class drivers
+ #
+-CONFIG_USB_AUDIO=m
++# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+ CONFIG_USB_BLUETOOTH_TTY=m
+-CONFIG_USB_MIDI=m
+ 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_RW_DETECT is not set
+ # CONFIG_USB_STORAGE_DATAFAB is not set
+ # CONFIG_USB_STORAGE_FREECOM is not set
+ # CONFIG_USB_STORAGE_ISD200 is not set
+ # CONFIG_USB_STORAGE_DPCM is not set
+-# CONFIG_USB_STORAGE_HP8200e 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_ONETOUCH is not set
+ 
+ #
+ # USB Input Devices
+@@ -863,19 +963,23 @@ CONFIG_USB_HIDDEV=y
+ # 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_YEALINK is not set
+ # CONFIG_USB_XPAD is not set
+ # CONFIG_USB_ATI_REMOTE 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
+-# CONFIG_USB_HPUSBSCSI is not set
+ 
+ #
+ # USB Multimedia devices
+@@ -894,6 +998,7 @@ CONFIG_USB_HIDDEV=y
+ # 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
+@@ -909,7 +1014,6 @@ CONFIG_USB_HIDDEV=y
+ #
+ # CONFIG_USB_EMI62 is not set
+ # CONFIG_USB_EMI26 is not set
+-# CONFIG_USB_TIGL is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+@@ -918,10 +1022,12 @@ CONFIG_USB_HIDDEV=y
+ # 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 ATM/DSL drivers
++# USB DSL modem support
+ #
+ 
+ #
+@@ -930,10 +1036,25 @@ CONFIG_USB_HIDDEV=y
+ # CONFIG_USB_GADGET is not set
+ 
+ #
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN 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
+@@ -945,17 +1066,20 @@ CONFIG_FS_MBCACHE=y
+ # CONFIG_JFS_FS is not set
+ CONFIG_FS_POSIX_ACL=y
+ CONFIG_XFS_FS=y
+-# CONFIG_XFS_RT is not set
++CONFIG_XFS_EXPORT=y
+ CONFIG_XFS_QUOTA=y
+ CONFIG_XFS_SECURITY=y
+ CONFIG_XFS_POSIX_ACL=y
++# CONFIG_XFS_RT is not set
+ # CONFIG_MINIX_FS is not set
+ # CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
+ # CONFIG_QUOTA is not set
+ CONFIG_QUOTACTL=y
+ CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=m
+ CONFIG_AUTOFS4_FS=m
++# CONFIG_FUSE_FS is not set
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -982,14 +1106,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ CONFIG_HUGETLBFS=y
+ CONFIG_HUGETLB_PAGE=y
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -1013,15 +1134,18 @@ CONFIG_RAMFS=y
+ #
+ CONFIG_NFS_FS=m
+ CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
+ CONFIG_NFS_V4=y
+ # CONFIG_NFS_DIRECTIO is not set
+ 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_EXPORTFS=y
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=m
+ CONFIG_SUNRPC_GSS=m
+ CONFIG_RPCSEC_GSS_KRB5=m
+@@ -1031,9 +1155,11 @@ CONFIG_CIFS=m
+ CONFIG_CIFS_STATS=y
+ CONFIG_CIFS_XATTR=y
+ CONFIG_CIFS_POSIX=y
++# 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
+@@ -1103,8 +1229,12 @@ CONFIG_NLS_UTF8=m
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
+ CONFIG_CRC32=y
+ # CONFIG_LIBCRC32C is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_PENDING_IRQ=y
+ 
+ #
+ # Profiling support
+@@ -1115,14 +1245,20 @@ CONFIG_OPROFILE=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ CONFIG_DEBUG_KERNEL=y
+ CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_DETECT_SOFTLOCKUP=y
+ # CONFIG_SCHEDSTATS is not set
+ # CONFIG_DEBUG_SLAB is not set
++CONFIG_DEBUG_PREEMPT=y
+ # CONFIG_DEBUG_SPINLOCK is not set
+ # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+ # CONFIG_DEBUG_KOBJECT is not set
+ # CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_KPROBES is not set
+ # CONFIG_IA64_GRANULE_16MB is not set
+ CONFIG_IA64_GRANULE_64MB=y
+ # CONFIG_IA64_PRINT_HAZARDS is not set
+@@ -1149,6 +1285,7 @@ CONFIG_CRYPTO_MD5=y
+ # 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
+@@ -1164,3 +1301,7 @@ CONFIG_CRYPTO_DES=y
+ # 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/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/ia64/configs/gensparse_defconfig
+@@ -0,0 +1,1319 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14-rc2
++# Wed Sep 28 08:27:29 2005
++#
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_CLEAN_COMPILE=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 is not set
++CONFIG_SYSCTL=y
++# CONFIG_AUDIT is not set
++CONFIG_HOTPLUG=y
++CONFIG_KOBJECT_UEVENT=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++# CONFIG_CPUSETS is not set
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_EMBEDDED is not set
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_ALL=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_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 is not set
++CONFIG_OBSOLETE_MODPARM=y
++CONFIG_MODVERSIONS=y
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_STOP_MACHINE=y
++
++#
++# Processor type and features
++#
++CONFIG_IA64=y
++CONFIG_64BIT=y
++CONFIG_MMU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_TIME_INTERPOLATION=y
++CONFIG_EFI=y
++CONFIG_GENERIC_IOMAP=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=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_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 is not set
++CONFIG_FORCE_MAX_ZONEORDER=17
++CONFIG_SMP=y
++CONFIG_NR_CPUS=512
++CONFIG_HOTPLUG_CPU=y
++# CONFIG_SCHED_SMT 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_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_HAVE_ARCH_EARLY_PFN_TO_NID=y
++CONFIG_IA32_SUPPORT=y
++CONFIG_COMPAT=y
++CONFIG_IA64_MCA_RECOVERY=y
++CONFIG_PERFMON=y
++CONFIG_IA64_PALINFO=y
++
++#
++# Firmware Drivers
++#
++CONFIG_EFI_VARS=y
++CONFIG_EFI_PCDP=y
++# CONFIG_DELL_RBU is not set
++CONFIG_BINFMT_ELF=y
++CONFIG_BINFMT_MISC=m
++
++#
++# Power management and ACPI
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++
++#
++# ACPI (Advanced Configuration and Power Interface) Support
++#
++CONFIG_ACPI=y
++CONFIG_ACPI_BUTTON=m
++CONFIG_ACPI_FAN=m
++CONFIG_ACPI_PROCESSOR=m
++CONFIG_ACPI_HOTPLUG_CPU=y
++CONFIG_ACPI_THERMAL=m
++CONFIG_ACPI_NUMA=y
++CONFIG_ACPI_BLACKLIST_YEAR=0
++# CONFIG_ACPI_DEBUG is not set
++CONFIG_ACPI_POWER=y
++CONFIG_ACPI_SYSTEM=y
++CONFIG_ACPI_CONTAINER=m
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Bus options (PCI, PCMCIA)
++#
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++# CONFIG_PCI_MSI is not set
++CONFIG_PCI_LEGACY_PROC=y
++# CONFIG_PCI_DEBUG is not set
++
++#
++# PCI Hotplug Support
++#
++CONFIG_HOTPLUG_PCI=m
++# CONFIG_HOTPLUG_PCI_FAKE is not set
++CONFIG_HOTPLUG_PCI_ACPI=m
++# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
++# CONFIG_HOTPLUG_PCI_CPCI is not set
++# CONFIG_HOTPLUG_PCI_SHPC is not set
++# CONFIG_HOTPLUG_PCI_SGI is not set
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# CONFIG_PCCARD is not set
++
++#
++# Networking
++#
++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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++CONFIG_ARPD=y
++CONFIG_SYN_COOKIES=y
++# 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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=m
++# CONFIG_DEBUG_DRIVER 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_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=m
++# 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_INITRD=y
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++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=y
++# CONFIG_BLK_DEV_IDETAPE is not set
++CONFIG_BLK_DEV_IDEFLOPPY=y
++CONFIG_BLK_DEV_IDESCSI=m
++# CONFIG_IDE_TASK_IOCTL is not set
++
++#
++# IDE chipset support/bugfixes
++#
++CONFIG_IDE_GENERIC=y
++CONFIG_BLK_DEV_IDEPCI=y
++# CONFIG_IDEPCI_SHARE_IRQ is not set
++# 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 is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++# CONFIG_BLK_DEV_AMD74XX is not set
++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 is not set
++# CONFIG_BLK_DEV_HPT366 is not set
++# CONFIG_BLK_DEV_SC1200 is not set
++CONFIG_BLK_DEV_PIIX=y
++# 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_SGIIOC4=y
++# 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 is not set
++# 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 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=m
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=m
++# CONFIG_BLK_DEV_SR_VENDOR 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=y
++CONFIG_SCSI_FC_ATTRS=y
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++
++#
++# SCSI low-level drivers
++#
++# 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_MEGARAID_NEWGEN is not set
++# CONFIG_MEGARAID_LEGACY 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_SATA_PROMISE is not set
++# CONFIG_SCSI_SATA_QSTOR is not set
++# CONFIG_SCSI_SATA_SX4 is not set
++# CONFIG_SCSI_SATA_SIL 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=y
++# 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=y
++CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
++CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
++CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
++# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
++# CONFIG_SCSI_IPR is not set
++# CONFIG_SCSI_QLOGIC_FC is not set
++CONFIG_SCSI_QLOGIC_1280=y
++# CONFIG_SCSI_QLOGIC_1280_1040 is not set
++CONFIG_SCSI_QLA2XXX=y
++CONFIG_SCSI_QLA21XX=m
++CONFIG_SCSI_QLA22XX=m
++CONFIG_SCSI_QLA2300=m
++CONFIG_SCSI_QLA2322=m
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX is not set
++# CONFIG_SCSI_LPFC is not set
++# CONFIG_SCSI_DC395x is not set
++# CONFIG_SCSI_DC390T is not set
++# CONFIG_SCSI_DEBUG is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=m
++CONFIG_MD_LINEAR=m
++CONFIG_MD_RAID0=m
++CONFIG_MD_RAID1=m
++# CONFIG_MD_RAID10 is not set
++CONFIG_MD_RAID5=m
++CONFIG_MD_RAID6=m
++CONFIG_MD_MULTIPATH=m
++# CONFIG_MD_FAULTY is not set
++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 is not set
++
++#
++# Fusion MPT device support
++#
++CONFIG_FUSION=y
++CONFIG_FUSION_SPI=y
++CONFIG_FUSION_FC=m
++CONFIG_FUSION_MAX_SGE=128
++# CONFIG_FUSION_CTL 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=m
++# 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=m
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++
++#
++# Tulip family network device support
++#
++CONFIG_NET_TULIP=y
++# CONFIG_DE2104X is not set
++CONFIG_TULIP=m
++# CONFIG_TULIP_MWI is not set
++# CONFIG_TULIP_MMIO is not set
++# CONFIG_TULIP_NAPI is not set
++# CONFIG_DE4X5 is not set
++# CONFIG_WINBOND_840 is not set
++# CONFIG_DM9102 is not set
++# CONFIG_ULI526X 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=m
++CONFIG_E100=m
++# 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_VIA_RHINE is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++CONFIG_E1000=y
++# CONFIG_E1000_NAPI 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_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
++CONFIG_TIGON3=y
++# CONFIG_BNX2 is not set
++
++#
++# Ethernet (10000 Mbit)
++#
++# CONFIG_CHELSIO_T1 is not set
++# CONFIG_IXGB is not set
++# CONFIG_S2IO 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=y
++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
++
++#
++# 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 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_I8042=y
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_PCIPS2 is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++CONFIG_GAMEPORT=m
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_GAMEPORT_EMU10K1 is not set
++# CONFIG_GAMEPORT_FM801 is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_ROCKETPORT is not set
++# CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
++# CONFIG_MOXA_SMARTIO is not set
++# CONFIG_ISI is not set
++# CONFIG_SYNCLINKMP is not set
++# CONFIG_N_HDLC is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_SX 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_ACPI=y
++CONFIG_SERIAL_8250_NR_UARTS=6
++CONFIG_SERIAL_8250_EXTENDED=y
++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_SGI_L1_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_SERIAL_SGI_IOC4=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_EFI_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++CONFIG_AGP=m
++CONFIG_AGP_I460=m
++CONFIG_AGP_HP_ZX1=m
++CONFIG_AGP_SGI_TIOCA=m
++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 is not set
++# CONFIG_DRM_SAVAGE is not set
++CONFIG_RAW_DRIVER=m
++CONFIG_HPET=y
++# CONFIG_HPET_RTC_IRQ is not set
++CONFIG_HPET_MMAP=y
++CONFIG_MAX_RAW_DEVS=256
++# CONFIG_HANGCHECK_TIMER is not set
++CONFIG_MMTIMER=y
++
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C 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_HWMON_DEBUG_CHIP is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++
++#
++# 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=y
++CONFIG_DUMMY_CONSOLE=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_SEQUENCER_OSS=y
++CONFIG_SND_VERBOSE_PRINTK=y
++# CONFIG_SND_DEBUG is not set
++CONFIG_SND_GENERIC_DRIVER=y
++
++#
++# Generic devices
++#
++CONFIG_SND_MPU401_UART=m
++CONFIG_SND_OPL3_LIB=m
++CONFIG_SND_DUMMY=m
++CONFIG_SND_VIRMIDI=m
++CONFIG_SND_MTPAV=m
++CONFIG_SND_SERIAL_U16550=m
++CONFIG_SND_MPU401=m
++CONFIG_SND_AC97_CODEC=m
++CONFIG_SND_AC97_BUS=m
++
++#
++# PCI devices
++#
++# CONFIG_SND_ALI5451 is not set
++# CONFIG_SND_ATIIXP is not set
++# CONFIG_SND_ATIIXP_MODEM is not set
++# CONFIG_SND_AU8810 is not set
++# CONFIG_SND_AU8820 is not set
++# CONFIG_SND_AU8830 is not set
++# CONFIG_SND_AZT3328 is not set
++# CONFIG_SND_BT87X is not set
++CONFIG_SND_CS46XX=m
++CONFIG_SND_CS46XX_NEW_DSP=y
++CONFIG_SND_CS4281=m
++CONFIG_SND_EMU10K1=m
++# CONFIG_SND_EMU10K1X is not set
++# CONFIG_SND_CA0106 is not set
++# CONFIG_SND_KORG1212 is not set
++# CONFIG_SND_MIXART is not set
++# CONFIG_SND_NM256 is not set
++# CONFIG_SND_RME32 is not set
++# CONFIG_SND_RME96 is not set
++# CONFIG_SND_RME9652 is not set
++# CONFIG_SND_HDSP is not set
++# CONFIG_SND_HDSPM is not set
++# CONFIG_SND_TRIDENT is not set
++# CONFIG_SND_YMFPCI is not set
++# CONFIG_SND_AD1889 is not set
++# CONFIG_SND_CMIPCI is not set
++# CONFIG_SND_ENS1370 is not set
++# CONFIG_SND_ENS1371 is not set
++# CONFIG_SND_ES1938 is not set
++# CONFIG_SND_ES1968 is not set
++# CONFIG_SND_MAESTRO3 is not set
++CONFIG_SND_FM801=m
++# CONFIG_SND_FM801_TEA575X is not set
++# CONFIG_SND_ICE1712 is not set
++# CONFIG_SND_ICE1724 is not set
++# CONFIG_SND_INTEL8X0 is not set
++# CONFIG_SND_INTEL8X0M is not set
++# CONFIG_SND_SONICVIBES is not set
++# CONFIG_SND_VIA82XX is not set
++# CONFIG_SND_VIA82XX_MODEM is not set
++# CONFIG_SND_VX222 is not set
++# CONFIG_SND_HDA_INTEL is not set
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO 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=m
++# 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 is not set
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++# CONFIG_USB_OHCI_BIG_ENDIAN is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++CONFIG_USB_UHCI_HCD=m
++# CONFIG_USB_SL811_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
++# 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=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
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=m
++CONFIG_USB_HIDINPUT=y
++# 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_MTOUCH is not set
++# CONFIG_USB_ITMTOUCH is not set
++# CONFIG_USB_EGALAX is not set
++# CONFIG_USB_YEALINK is not set
++# CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE 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 Multimedia devices
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# 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_CYTHERM is not set
++# CONFIG_USB_PHIDGETKIT is not set
++# CONFIG_USB_PHIDGETSERVO is not set
++# CONFIG_USB_IDMOUSE 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
++
++#
++# InfiniBand support
++#
++CONFIG_INFINIBAND=m
++# CONFIG_INFINIBAND_USER_MAD is not set
++# CONFIG_INFINIBAND_USER_ACCESS is not set
++CONFIG_INFINIBAND_MTHCA=m
++# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
++CONFIG_INFINIBAND_IPOIB=m
++# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
++
++#
++# SN Devices
++#
++CONFIG_SGI_IOC4=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 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=y
++# 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 is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=y
++CONFIG_XFS_EXPORT=y
++# 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_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=y
++CONFIG_AUTOFS4_FS=y
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=m
++CONFIG_JOLIET=y
++# CONFIG_ZISOFS is not set
++CONFIG_UDF_FS=m
++CONFIG_UDF_NLS=y
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=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_HUGETLBFS=y
++CONFIG_HUGETLB_PAGE=y
++CONFIG_RAMFS=y
++# CONFIG_RELAYFS_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=m
++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_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=y
++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=m
++CONFIG_SMB_NLS_DEFAULT=y
++CONFIG_SMB_NLS_REMOTE="cp437"
++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 is not set
++CONFIG_SGI_PARTITION=y
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++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 is not set
++CONFIG_NLS_ISO8859_1=y
++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 is not set
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++# CONFIG_LIBCRC32C is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_PENDING_IRQ=y
++
++#
++# HP Simulator drivers
++#
++# CONFIG_HP_SIMETH is not set
++# CONFIG_HP_SIMSERIAL is not set
++# CONFIG_HP_SIMSCSI is not set
++
++#
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=20
++CONFIG_DETECT_SOFTLOCKUP=y
++# 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_INFO is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_KPROBES 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
++CONFIG_SYSVIPC_COMPAT=y
++
++#
++# 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 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/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
+--- a/arch/ia64/configs/tiger_defconfig
++++ b/arch/ia64/configs/tiger_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.13-rc6-tiger-smp
+-# Wed Aug 17 10:19:51 2005
++# Linux kernel version: 2.6.14-rc1
++# Wed Sep 14 15:17:57 2005
+ #
+ 
+ #
+@@ -16,6 +16,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
+ # General setup
+ #
+ CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
+ CONFIG_SWAP=y
+ CONFIG_SYSVIPC=y
+ CONFIG_POSIX_MQUEUE=y
+@@ -27,6 +28,7 @@ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
+ # CONFIG_CPUSETS is not set
++CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_EMBEDDED is not set
+ CONFIG_KALLSYMS=y
+ CONFIG_KALLSYMS_ALL=y
+@@ -103,6 +105,7 @@ CONFIG_FLATMEM_MANUAL=y
+ # CONFIG_SPARSEMEM_MANUAL is not set
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_IA32_SUPPORT=y
+ CONFIG_COMPAT=y
+@@ -115,6 +118,7 @@ CONFIG_IA64_PALINFO=y
+ #
+ CONFIG_EFI_VARS=y
+ CONFIG_EFI_PCDP=y
++# CONFIG_DELL_RBU is not set
+ CONFIG_BINFMT_ELF=y
+ CONFIG_BINFMT_MISC=m
+ 
+@@ -122,20 +126,27 @@ CONFIG_BINFMT_MISC=m
+ # Power management and ACPI
+ #
+ CONFIG_PM=y
+-CONFIG_ACPI=y
++# CONFIG_PM_DEBUG is not set
+ 
+ #
+ # ACPI (Advanced Configuration and Power Interface) Support
+ #
++CONFIG_ACPI=y
+ CONFIG_ACPI_BUTTON=m
+ CONFIG_ACPI_FAN=m
+ CONFIG_ACPI_PROCESSOR=m
+-# CONFIG_ACPI_HOTPLUG_CPU is not set
++CONFIG_ACPI_HOTPLUG_CPU=y
+ CONFIG_ACPI_THERMAL=m
++CONFIG_ACPI_BLACKLIST_YEAR=0
+ # CONFIG_ACPI_DEBUG is not set
+ CONFIG_ACPI_POWER=y
+ CONFIG_ACPI_SYSTEM=y
+-# CONFIG_ACPI_CONTAINER is not set
++CONFIG_ACPI_CONTAINER=m
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
+ 
+ #
+ # Bus options (PCI, PCMCIA)
+@@ -144,7 +155,6 @@ CONFIG_PCI=y
+ CONFIG_PCI_DOMAINS=y
+ # CONFIG_PCI_MSI is not set
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ # CONFIG_PCI_DEBUG is not set
+ 
+ #
+@@ -188,14 +198,19 @@ CONFIG_SYN_COOKIES=y
+ # 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_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_NETFILTER is not set
+ 
+ #
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
++
++#
+ # SCTP Configuration (EXPERIMENTAL)
+ #
+ # CONFIG_IP_SCTP is not set
+@@ -218,9 +233,11 @@ CONFIG_TCP_CONG_BIC=y
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
++# CONFIG_NETFILTER_NETLINK 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
+@@ -235,6 +252,11 @@ CONFIG_FW_LOADER=m
+ # CONFIG_DEBUG_DRIVER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -247,7 +269,13 @@ CONFIG_FW_LOADER=m
+ #
+ # Plug and Play support
+ #
+-# CONFIG_PNP is not set
++CONFIG_PNP=y
++# CONFIG_PNP_DEBUG is not set
++
++#
++# Protocols
++#
++CONFIG_PNPACPI=y
+ 
+ #
+ # Block devices
+@@ -266,7 +294,6 @@ 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
+ 
+ #
+@@ -299,7 +326,8 @@ CONFIG_BLK_DEV_IDESCSI=m
+ #
+ # IDE chipset support/bugfixes
+ #
+-CONFIG_IDE_GENERIC=y
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_IDEPNP is not set
+ CONFIG_BLK_DEV_IDEPCI=y
+ # CONFIG_IDEPCI_SHARE_IRQ is not set
+ # CONFIG_BLK_DEV_OFFBOARD is not set
+@@ -339,6 +367,7 @@ CONFIG_IDEDMA_AUTO=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -366,6 +395,7 @@ CONFIG_CHR_DEV_SG=m
+ CONFIG_SCSI_SPI_ATTRS=y
+ CONFIG_SCSI_FC_ATTRS=y
+ # CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
+ 
+ #
+ # SCSI low-level drivers
+@@ -454,6 +484,7 @@ CONFIG_DUMMY=m
+ # CONFIG_BONDING is not set
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
++# CONFIG_NET_SB1000 is not set
+ 
+ #
+ # ARCnet devices
+@@ -461,6 +492,11 @@ CONFIG_DUMMY=m
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -481,6 +517,7 @@ CONFIG_TULIP=m
+ # CONFIG_DE4X5 is not set
+ # CONFIG_WINBOND_840 is not set
+ # CONFIG_DM9102 is not set
++# CONFIG_ULI526X is not set
+ # CONFIG_HP100 is not set
+ CONFIG_NET_PCI=y
+ # CONFIG_PCNET32 is not set
+@@ -512,6 +549,7 @@ CONFIG_E1000=y
+ # 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_SK98LIN is not set
+ # CONFIG_VIA_VELOCITY is not set
+@@ -521,6 +559,7 @@ CONFIG_TIGON3=y
+ #
+ # Ethernet (10000 Mbit)
+ #
++# CONFIG_CHELSIO_T1 is not set
+ # CONFIG_IXGB is not set
+ # CONFIG_S2IO is not set
+ 
+@@ -618,6 +657,7 @@ CONFIG_HW_CONSOLE=y
+ CONFIG_SERIAL_NONSTANDARD=y
+ # CONFIG_ROCKETPORT is not set
+ # CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
+ # CONFIG_MOXA_SMARTIO is not set
+ # CONFIG_ISI is not set
+ # CONFIG_SYNCLINKMP is not set
+@@ -675,6 +715,7 @@ CONFIG_DRM_RADEON=m
+ CONFIG_DRM_MGA=m
+ CONFIG_DRM_SIS=m
+ # CONFIG_DRM_VIA is not set
++# CONFIG_DRM_SAVAGE is not set
+ CONFIG_RAW_DRIVER=m
+ CONFIG_HPET=y
+ # CONFIG_HPET_RTC_IRQ is not set
+@@ -691,7 +732,6 @@ CONFIG_MAX_RAW_DEVS=256
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+-# CONFIG_I2C_SENSOR is not set
+ 
+ #
+ # Dallas's 1-wire bus
+@@ -702,6 +742,7 @@ CONFIG_MAX_RAW_DEVS=256
+ # Hardware Monitoring support
+ #
+ CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
+ # CONFIG_HWMON_DEBUG_CHIP is not set
+ 
+ #
+@@ -709,6 +750,10 @@ CONFIG_HWMON=y
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -800,9 +845,11 @@ CONFIG_USB_HIDINPUT=y
+ # CONFIG_USB_MTOUCH is not set
+ # CONFIG_USB_ITMTOUCH is not set
+ # CONFIG_USB_EGALAX is not set
++# CONFIG_USB_YEALINK is not set
+ # CONFIG_USB_XPAD is not set
+ # CONFIG_USB_ATI_REMOTE is not set
+ # CONFIG_USB_KEYSPAN_REMOTE is not set
++# CONFIG_USB_APPLETOUCH is not set
+ 
+ #
+ # USB Imaging devices
+@@ -902,16 +949,12 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
+ CONFIG_REISERFS_FS_SECURITY=y
+ # CONFIG_JFS_FS is not set
+ CONFIG_FS_POSIX_ACL=y
+-
+-#
+-# XFS support
+-#
+ CONFIG_XFS_FS=y
+ CONFIG_XFS_EXPORT=y
+-# CONFIG_XFS_RT is not set
+ # 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_MINIX_FS is not set
+ # CONFIG_ROMFS_FS is not set
+ CONFIG_INOTIFY=y
+@@ -919,6 +962,7 @@ CONFIG_INOTIFY=y
+ CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=y
+ CONFIG_AUTOFS4_FS=y
++# CONFIG_FUSE_FS is not set
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -947,13 +991,11 @@ CONFIG_NTFS_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ CONFIG_TMPFS=y
+-CONFIG_TMPFS_XATTR=y
+-CONFIG_TMPFS_SECURITY=y
+ CONFIG_HUGETLBFS=y
+ CONFIG_HUGETLB_PAGE=y
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -1003,6 +1045,7 @@ CONFIG_CIFS=m
+ # 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
+@@ -1072,10 +1115,12 @@ CONFIG_NLS_UTF8=m
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
+ CONFIG_CRC32=y
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_PENDING_IRQ=y
+ 
+ #
+ # Profiling support
+@@ -1089,6 +1134,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
+ CONFIG_DEBUG_KERNEL=y
+ CONFIG_MAGIC_SYSRQ=y
+ CONFIG_LOG_BUF_SHIFT=20
++CONFIG_DETECT_SOFTLOCKUP=y
+ # CONFIG_SCHEDSTATS is not set
+ # CONFIG_DEBUG_SLAB is not set
+ # CONFIG_DEBUG_SPINLOCK is not set
+diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
+--- a/arch/ia64/configs/zx1_defconfig
++++ b/arch/ia64/configs/zx1_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.13-rc6
+-# Wed Aug 17 10:02:43 2005
++# Linux kernel version: 2.6.14-rc1
++# Wed Sep 14 15:15:01 2005
+ #
+ 
+ #
+@@ -18,6 +18,7 @@ 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
+@@ -29,6 +30,7 @@ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
+ # CONFIG_CPUSETS is not set
++CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_EMBEDDED is not set
+ CONFIG_KALLSYMS=y
+ # CONFIG_KALLSYMS_ALL is not set
+@@ -103,6 +105,7 @@ CONFIG_FLATMEM_MANUAL=y
+ # CONFIG_SPARSEMEM_MANUAL is not set
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_IA32_SUPPORT=y
+ CONFIG_COMPAT=y
+@@ -115,6 +118,7 @@ CONFIG_IA64_PALINFO=y
+ #
+ CONFIG_EFI_VARS=y
+ CONFIG_EFI_PCDP=y
++# CONFIG_DELL_RBU is not set
+ CONFIG_BINFMT_ELF=y
+ CONFIG_BINFMT_MISC=y
+ 
+@@ -122,28 +126,34 @@ CONFIG_BINFMT_MISC=y
+ # Power management and ACPI
+ #
+ CONFIG_PM=y
+-CONFIG_ACPI=y
++# CONFIG_PM_DEBUG is not set
+ 
+ #
+ # ACPI (Advanced Configuration and Power Interface) Support
+ #
++CONFIG_ACPI=y
+ CONFIG_ACPI_BUTTON=y
+ CONFIG_ACPI_FAN=y
+ CONFIG_ACPI_PROCESSOR=y
+ CONFIG_ACPI_THERMAL=y
++CONFIG_ACPI_BLACKLIST_YEAR=0
+ # CONFIG_ACPI_DEBUG is not set
+ CONFIG_ACPI_POWER=y
+ CONFIG_ACPI_SYSTEM=y
+ # CONFIG_ACPI_CONTAINER is not set
+ 
+ #
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
+ # Bus options (PCI, PCMCIA)
+ #
+ CONFIG_PCI=y
+ CONFIG_PCI_DOMAINS=y
+ # CONFIG_PCI_MSI is not set
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ # CONFIG_PCI_DEBUG is not set
+ 
+ #
+@@ -187,8 +197,8 @@ CONFIG_IP_FIB_HASH=y
+ # 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_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
+ # CONFIG_TCP_CONG_ADVANCED is not set
+ CONFIG_TCP_CONG_BIC=y
+ 
+@@ -204,7 +214,6 @@ CONFIG_NETFILTER=y
+ # IP: Netfilter Configuration
+ #
+ # CONFIG_IP_NF_CONNTRACK is not set
+-# CONFIG_IP_NF_CONNTRACK_MARK is not set
+ # CONFIG_IP_NF_QUEUE is not set
+ # CONFIG_IP_NF_IPTABLES is not set
+ CONFIG_IP_NF_ARPTABLES=y
+@@ -212,6 +221,11 @@ CONFIG_IP_NF_ARPTABLES=y
+ # CONFIG_IP_NF_ARP_MANGLE is not set
+ 
+ #
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
++
++#
+ # SCTP Configuration (EXPERIMENTAL)
+ #
+ # CONFIG_IP_SCTP is not set
+@@ -234,9 +248,11 @@ CONFIG_IP_NF_ARPTABLES=y
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
++# CONFIG_NETFILTER_NETLINK 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
+@@ -251,6 +267,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_DEBUG_DRIVER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -263,7 +284,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Plug and Play support
+ #
+-# CONFIG_PNP is not set
++CONFIG_PNP=y
++# CONFIG_PNP_DEBUG is not set
++
++#
++# Protocols
++#
++CONFIG_PNPACPI=y
+ 
+ #
+ # Block devices
+@@ -282,7 +309,6 @@ 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
+ 
+ #
+@@ -315,7 +341,8 @@ CONFIG_BLK_DEV_IDECD=y
+ #
+ # IDE chipset support/bugfixes
+ #
+-CONFIG_IDE_GENERIC=y
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_IDEPNP is not set
+ CONFIG_BLK_DEV_IDEPCI=y
+ CONFIG_IDEPCI_SHARE_IRQ=y
+ # CONFIG_BLK_DEV_OFFBOARD is not set
+@@ -354,6 +381,7 @@ CONFIG_BLK_DEV_IDEDMA=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -381,6 +409,7 @@ CONFIG_SCSI_LOGGING=y
+ 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
+@@ -457,6 +486,7 @@ CONFIG_DUMMY=y
+ # CONFIG_BONDING is not set
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
++# CONFIG_NET_SB1000 is not set
+ 
+ #
+ # ARCnet devices
+@@ -464,6 +494,11 @@ CONFIG_DUMMY=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -485,6 +520,7 @@ CONFIG_TULIP_NAPI_HW_MITIGATION=y
+ # CONFIG_DE4X5 is not set
+ # CONFIG_WINBOND_840 is not set
+ # CONFIG_DM9102 is not set
++# CONFIG_ULI526X is not set
+ # CONFIG_HP100 is not set
+ CONFIG_NET_PCI=y
+ # CONFIG_PCNET32 is not set
+@@ -516,6 +552,7 @@ CONFIG_E1000=y
+ # 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_SK98LIN is not set
+ # CONFIG_VIA_VELOCITY is not set
+@@ -525,6 +562,7 @@ CONFIG_TIGON3=y
+ #
+ # Ethernet (10000 Mbit)
+ #
++# CONFIG_CHELSIO_T1 is not set
+ # CONFIG_IXGB is not set
+ # CONFIG_S2IO is not set
+ 
+@@ -650,12 +688,12 @@ CONFIG_AGP=y
+ CONFIG_AGP_HP_ZX1=y
+ CONFIG_DRM=y
+ # CONFIG_DRM_TDFX is not set
+-# CONFIG_DRM_GAMMA is not set
+ # CONFIG_DRM_R128 is not set
+ CONFIG_DRM_RADEON=y
+ # CONFIG_DRM_MGA is not set
+ # CONFIG_DRM_SIS is not set
+ # CONFIG_DRM_VIA is not set
++# CONFIG_DRM_SAVAGE is not set
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_HPET is not set
+ # CONFIG_HANGCHECK_TIMER is not set
+@@ -689,7 +727,6 @@ CONFIG_I2C_ALGOPCF=y
+ # CONFIG_I2C_I801 is not set
+ # CONFIG_I2C_I810 is not set
+ # CONFIG_I2C_PIIX4 is not set
+-# CONFIG_I2C_ISA is not set
+ # CONFIG_I2C_NFORCE2 is not set
+ # CONFIG_I2C_PARPORT_LIGHT is not set
+ # CONFIG_I2C_PROSAVAGE is not set
+@@ -703,7 +740,6 @@ CONFIG_I2C_ALGOPCF=y
+ # CONFIG_I2C_VIAPRO is not set
+ # CONFIG_I2C_VOODOO3 is not set
+ # CONFIG_I2C_PCA_ISA is not set
+-# CONFIG_I2C_SENSOR is not set
+ 
+ #
+ # Miscellaneous I2C Chip support
+@@ -730,12 +766,17 @@ CONFIG_I2C_ALGOPCF=y
+ # Hardware Monitoring support
+ #
+ # CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
+ 
+ #
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ CONFIG_VIDEO_DEV=y
+@@ -806,6 +847,7 @@ CONFIG_FB_RADEON_DEBUG=y
+ # CONFIG_FB_KYRO is not set
+ # CONFIG_FB_3DFX is not set
+ # CONFIG_FB_VOODOO1 is not set
++# CONFIG_FB_CYBLA is not set
+ # CONFIG_FB_TRIDENT is not set
+ # CONFIG_FB_PM3 is not set
+ # CONFIG_FB_S1D13XXX is not set
+@@ -862,11 +904,12 @@ CONFIG_SND_OPL3_LIB=y
+ # CONFIG_SND_MTPAV is not set
+ # CONFIG_SND_SERIAL_U16550 is not set
+ # CONFIG_SND_MPU401 is not set
++CONFIG_SND_AC97_CODEC=y
++CONFIG_SND_AC97_BUS=y
+ 
+ #
+ # PCI devices
+ #
+-CONFIG_SND_AC97_CODEC=y
+ # CONFIG_SND_ALI5451 is not set
+ # CONFIG_SND_ATIIXP is not set
+ # CONFIG_SND_ATIIXP_MODEM is not set
+@@ -890,7 +933,7 @@ CONFIG_SND_AC97_CODEC=y
+ # CONFIG_SND_HDSPM is not set
+ # CONFIG_SND_TRIDENT is not set
+ # CONFIG_SND_YMFPCI is not set
+-# CONFIG_SND_ALS4000 is not set
++# CONFIG_SND_AD1889 is not set
+ # CONFIG_SND_CMIPCI is not set
+ # CONFIG_SND_ENS1370 is not set
+ # CONFIG_SND_ENS1371 is not set
+@@ -952,9 +995,8 @@ CONFIG_USB_UHCI_HCD=y
+ #
+ # USB Device Class drivers
+ #
+-# CONFIG_USB_AUDIO is not set
++# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+ # CONFIG_USB_BLUETOOTH_TTY is not set
+-# CONFIG_USB_MIDI is not set
+ # CONFIG_USB_ACM is not set
+ # CONFIG_USB_PRINTER is not set
+ 
+@@ -971,6 +1013,7 @@ CONFIG_USB_STORAGE=y
+ # CONFIG_USB_STORAGE_SDDR09 is not set
+ # CONFIG_USB_STORAGE_SDDR55 is not set
+ # CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
+ 
+ #
+ # USB Input Devices
+@@ -987,9 +1030,11 @@ CONFIG_USB_HIDDEV=y
+ # CONFIG_USB_MTOUCH is not set
+ # CONFIG_USB_ITMTOUCH is not set
+ # CONFIG_USB_EGALAX is not set
++# CONFIG_USB_YEALINK is not set
+ # CONFIG_USB_XPAD is not set
+ # CONFIG_USB_ATI_REMOTE is not set
+ # CONFIG_USB_KEYSPAN_REMOTE is not set
++# CONFIG_USB_APPLETOUCH is not set
+ 
+ #
+ # USB Imaging devices
+@@ -1088,10 +1133,6 @@ CONFIG_FS_MBCACHE=y
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_JFS_FS is not set
+ # CONFIG_FS_POSIX_ACL is not set
+-
+-#
+-# XFS support
+-#
+ # CONFIG_XFS_FS is not set
+ # CONFIG_MINIX_FS is not set
+ # CONFIG_ROMFS_FS is not set
+@@ -1100,6 +1141,7 @@ CONFIG_FS_MBCACHE=y
+ CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=y
+ # CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -1126,13 +1168,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ CONFIG_TMPFS=y
+-CONFIG_TMPFS_XATTR=y
+-CONFIG_TMPFS_SECURITY=y
+ CONFIG_HUGETLBFS=y
+ CONFIG_HUGETLB_PAGE=y
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -1177,6 +1217,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
+ # 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
+@@ -1246,10 +1287,12 @@ CONFIG_NLS_UTF8=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
+ CONFIG_CRC32=y
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_PENDING_IRQ=y
+ 
+ #
+ # Profiling support
+@@ -1263,6 +1306,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
+ CONFIG_DEBUG_KERNEL=y
+ CONFIG_MAGIC_SYSRQ=y
+ CONFIG_LOG_BUF_SHIFT=17
++CONFIG_DETECT_SOFTLOCKUP=y
+ # CONFIG_SCHEDSTATS is not set
+ # CONFIG_DEBUG_SLAB is not set
+ # CONFIG_DEBUG_SPINLOCK is not set
+diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
+--- a/arch/ia64/defconfig
++++ b/arch/ia64/defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.12
+-# Tue Jun 21 11:30:42 2005
++# Linux kernel version: 2.6.14-rc1
++# Wed Sep 14 15:13:03 2005
+ #
+ 
+ #
+@@ -16,6 +16,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
+ # General setup
+ #
+ CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
+ CONFIG_SWAP=y
+ CONFIG_SYSVIPC=y
+ CONFIG_POSIX_MQUEUE=y
+@@ -27,6 +28,7 @@ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
+ # CONFIG_CPUSETS is not set
++CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_EMBEDDED is not set
+ CONFIG_KALLSYMS=y
+ CONFIG_KALLSYMS_ALL=y
+@@ -80,6 +82,10 @@ CONFIG_MCKINLEY=y
+ # CONFIG_IA64_PAGE_SIZE_8KB is not set
+ CONFIG_IA64_PAGE_SIZE_16KB=y
+ # CONFIG_IA64_PAGE_SIZE_64KB 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_NUMA=y
+ CONFIG_VIRTUAL_MEM_MAP=y
+@@ -87,12 +93,21 @@ CONFIG_HOLES_IN_ZONE=y
+ CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+ CONFIG_IA64_CYCLONE=y
+ CONFIG_IOSAPIC=y
++# CONFIG_IA64_SGI_SN_XP is not set
+ CONFIG_FORCE_MAX_ZONEORDER=18
+ CONFIG_SMP=y
+ CONFIG_NR_CPUS=512
+ CONFIG_HOTPLUG_CPU=y
+ # CONFIG_SCHED_SMT is not set
+ # CONFIG_PREEMPT is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++# CONFIG_FLATMEM_MANUAL is not set
++CONFIG_DISCONTIGMEM_MANUAL=y
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_DISCONTIGMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_NEED_MULTIPLE_NODES=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_IA32_SUPPORT=y
+ CONFIG_COMPAT=y
+@@ -105,6 +120,7 @@ CONFIG_IA64_PALINFO=y
+ #
+ CONFIG_EFI_VARS=y
+ CONFIG_EFI_PCDP=y
++# CONFIG_DELL_RBU is not set
+ CONFIG_BINFMT_ELF=y
+ CONFIG_BINFMT_MISC=m
+ 
+@@ -112,30 +128,36 @@ CONFIG_BINFMT_MISC=m
+ # Power management and ACPI
+ #
+ CONFIG_PM=y
+-CONFIG_ACPI=y
++# CONFIG_PM_DEBUG is not set
+ 
+ #
+ # ACPI (Advanced Configuration and Power Interface) Support
+ #
++CONFIG_ACPI=y
+ CONFIG_ACPI_BUTTON=m
+ CONFIG_ACPI_FAN=m
+ CONFIG_ACPI_PROCESSOR=m
+ CONFIG_ACPI_HOTPLUG_CPU=y
+ CONFIG_ACPI_THERMAL=m
+ CONFIG_ACPI_NUMA=y
++CONFIG_ACPI_BLACKLIST_YEAR=0
+ # CONFIG_ACPI_DEBUG is not set
+ CONFIG_ACPI_POWER=y
+ CONFIG_ACPI_SYSTEM=y
+ CONFIG_ACPI_CONTAINER=m
+ 
+ #
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
+ # Bus options (PCI, PCMCIA)
+ #
+ CONFIG_PCI=y
+ CONFIG_PCI_DOMAINS=y
+ # CONFIG_PCI_MSI is not set
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ # CONFIG_PCI_DEBUG is not set
+ 
+ #
+@@ -147,6 +169,7 @@ CONFIG_HOTPLUG_PCI_ACPI=m
+ # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
+ # CONFIG_HOTPLUG_PCI_CPCI is not set
+ # CONFIG_HOTPLUG_PCI_SHPC is not set
++# CONFIG_HOTPLUG_PCI_SGI is not set
+ 
+ #
+ # PCCARD (PCMCIA/CardBus) support
+@@ -154,6 +177,73 @@ CONFIG_HOTPLUG_PCI_ACPI=m
+ # CONFIG_PCCARD is not set
+ 
+ #
++# Networking
++#
++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 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++CONFIG_ARPD=y
++CONFIG_SYN_COOKIES=y
++# 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_NETFILTER_NETLINK 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
+ #
+ 
+@@ -162,10 +252,15 @@ CONFIG_HOTPLUG_PCI_ACPI=m
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
+ # CONFIG_DEBUG_DRIVER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -178,7 +273,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Plug and Play support
+ #
+-# CONFIG_PNP is not set
++CONFIG_PNP=y
++# CONFIG_PNP_DEBUG is not set
++
++#
++# Protocols
++#
++CONFIG_PNPACPI=y
+ 
+ #
+ # Block devices
+@@ -197,7 +298,6 @@ 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
+ 
+ #
+@@ -230,7 +330,8 @@ CONFIG_BLK_DEV_IDESCSI=m
+ #
+ # IDE chipset support/bugfixes
+ #
+-CONFIG_IDE_GENERIC=y
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_IDEPNP is not set
+ CONFIG_BLK_DEV_IDEPCI=y
+ # CONFIG_IDEPCI_SHARE_IRQ is not set
+ # CONFIG_BLK_DEV_OFFBOARD is not set
+@@ -252,6 +353,7 @@ CONFIG_BLK_DEV_CMD64X=y
+ # CONFIG_BLK_DEV_HPT366 is not set
+ # CONFIG_BLK_DEV_SC1200 is not set
+ CONFIG_BLK_DEV_PIIX=y
++# 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
+@@ -270,6 +372,7 @@ CONFIG_IDEDMA_AUTO=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -297,6 +400,7 @@ CONFIG_CHR_DEV_SG=m
+ CONFIG_SCSI_SPI_ATTRS=y
+ CONFIG_SCSI_FC_ATTRS=y
+ # CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
+ 
+ #
+ # SCSI low-level drivers
+@@ -314,6 +418,7 @@ 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_SATA_PROMISE is not set
+ # CONFIG_SCSI_SATA_QSTOR is not set
+@@ -335,7 +440,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+ # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+ # CONFIG_SCSI_IPR is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+ CONFIG_SCSI_QLOGIC_1280=y
+ # CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ CONFIG_SCSI_QLA2XXX=y
+@@ -344,6 +448,7 @@ CONFIG_SCSI_QLA22XX=m
+ CONFIG_SCSI_QLA2300=m
+ CONFIG_SCSI_QLA2322=m
+ # CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX is not set
+ # CONFIG_SCSI_LPFC is not set
+ # CONFIG_SCSI_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+@@ -390,74 +495,14 @@ CONFIG_FUSION_MAX_SGE=128
+ # CONFIG_I2O is not set
+ 
+ #
+-# 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_PNP is not set
+-# CONFIG_NET_IPIP is not set
+-# CONFIG_NET_IPGRE is not set
+-# CONFIG_IP_MROUTE is not set
+-CONFIG_ARPD=y
+-CONFIG_SYN_COOKIES=y
+-# 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
+-
++# Network device support
+ #
+-# 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=y
+-# CONFIG_NETPOLL_RX is not set
+-# CONFIG_NETPOLL_TRAP is not set
+-CONFIG_NET_POLL_CONTROLLER=y
+-# CONFIG_HAMRADIO is not set
+-# CONFIG_IRDA is not set
+-# CONFIG_BT is not set
+ CONFIG_NETDEVICES=y
+ CONFIG_DUMMY=m
+ # CONFIG_BONDING is not set
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
++# CONFIG_NET_SB1000 is not set
+ 
+ #
+ # ARCnet devices
+@@ -465,6 +510,11 @@ CONFIG_DUMMY=m
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -485,6 +535,7 @@ CONFIG_TULIP=m
+ # CONFIG_DE4X5 is not set
+ # CONFIG_WINBOND_840 is not set
+ # CONFIG_DM9102 is not set
++# CONFIG_ULI526X is not set
+ # CONFIG_HP100 is not set
+ CONFIG_NET_PCI=y
+ # CONFIG_PCNET32 is not set
+@@ -516,6 +567,7 @@ CONFIG_E1000=y
+ # 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_SK98LIN is not set
+ # CONFIG_VIA_VELOCITY is not set
+@@ -525,6 +577,7 @@ CONFIG_TIGON3=y
+ #
+ # Ethernet (10000 Mbit)
+ #
++# CONFIG_CHELSIO_T1 is not set
+ # CONFIG_IXGB is not set
+ # CONFIG_S2IO is not set
+ 
+@@ -549,6 +602,10 @@ CONFIG_TIGON3=y
+ # CONFIG_NET_FC is not set
+ # CONFIG_SHAPER is not set
+ CONFIG_NETCONSOLE=y
++CONFIG_NETPOLL=y
++# CONFIG_NETPOLL_RX is not set
++# CONFIG_NETPOLL_TRAP is not set
++CONFIG_NET_POLL_CONTROLLER=y
+ 
+ #
+ # ISDN subsystem
+@@ -607,9 +664,7 @@ CONFIG_GAMEPORT=m
+ # CONFIG_GAMEPORT_NS558 is not set
+ # CONFIG_GAMEPORT_L4 is not set
+ # CONFIG_GAMEPORT_EMU10K1 is not set
+-# CONFIG_GAMEPORT_VORTEX is not set
+ # CONFIG_GAMEPORT_FM801 is not set
+-# CONFIG_GAMEPORT_CS461X is not set
+ 
+ #
+ # Character devices
+@@ -620,6 +675,7 @@ CONFIG_HW_CONSOLE=y
+ CONFIG_SERIAL_NONSTANDARD=y
+ # CONFIG_ROCKETPORT is not set
+ # CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
+ # CONFIG_MOXA_SMARTIO is not set
+ # CONFIG_ISI is not set
+ # CONFIG_SYNCLINKMP is not set
+@@ -641,7 +697,6 @@ CONFIG_SERIAL_8250_NR_UARTS=6
+ CONFIG_SERIAL_8250_EXTENDED=y
+ CONFIG_SERIAL_8250_SHARE_IRQ=y
+ # CONFIG_SERIAL_8250_DETECT_IRQ is not set
+-# CONFIG_SERIAL_8250_MULTIPORT is not set
+ # CONFIG_SERIAL_8250_RSA is not set
+ 
+ #
+@@ -650,8 +705,8 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ CONFIG_SERIAL_SGI_L1_CONSOLE=y
+-CONFIG_SERIAL_SGI_IOC4=y
+ # CONFIG_SERIAL_JSM is not set
++CONFIG_SERIAL_SGI_IOC4=y
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -684,6 +739,8 @@ CONFIG_DRM_R128=m
+ CONFIG_DRM_RADEON=m
+ CONFIG_DRM_MGA=m
+ CONFIG_DRM_SIS=m
++# CONFIG_DRM_VIA is not set
++# CONFIG_DRM_SAVAGE is not set
+ CONFIG_RAW_DRIVER=m
+ CONFIG_HPET=y
+ # CONFIG_HPET_RTC_IRQ is not set
+@@ -708,10 +765,21 @@ CONFIG_MMTIMER=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -753,6 +821,7 @@ CONFIG_SND_PCM_OSS=m
+ CONFIG_SND_SEQUENCER_OSS=y
+ CONFIG_SND_VERBOSE_PRINTK=y
+ # CONFIG_SND_DEBUG is not set
++CONFIG_SND_GENERIC_DRIVER=y
+ 
+ #
+ # Generic devices
+@@ -764,11 +833,12 @@ CONFIG_SND_VIRMIDI=m
+ CONFIG_SND_MTPAV=m
+ CONFIG_SND_SERIAL_U16550=m
+ CONFIG_SND_MPU401=m
++CONFIG_SND_AC97_CODEC=m
++CONFIG_SND_AC97_BUS=m
+ 
+ #
+ # PCI devices
+ #
+-CONFIG_SND_AC97_CODEC=m
+ # CONFIG_SND_ALI5451 is not set
+ # CONFIG_SND_ATIIXP is not set
+ # CONFIG_SND_ATIIXP_MODEM is not set
+@@ -790,9 +860,10 @@ CONFIG_SND_EMU10K1=m
+ # CONFIG_SND_RME96 is not set
+ # CONFIG_SND_RME9652 is not set
+ # CONFIG_SND_HDSP is not set
++# CONFIG_SND_HDSPM is not set
+ # CONFIG_SND_TRIDENT is not set
+ # CONFIG_SND_YMFPCI is not set
+-# CONFIG_SND_ALS4000 is not set
++# CONFIG_SND_AD1889 is not set
+ # CONFIG_SND_CMIPCI is not set
+ # CONFIG_SND_ENS1370 is not set
+ # CONFIG_SND_ENS1371 is not set
+@@ -844,6 +915,7 @@ CONFIG_USB_DEVICEFS=y
+ CONFIG_USB_EHCI_HCD=m
+ # CONFIG_USB_EHCI_SPLIT_ISO is not set
+ # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++# CONFIG_USB_ISP116X_HCD is not set
+ CONFIG_USB_OHCI_HCD=m
+ # CONFIG_USB_OHCI_BIG_ENDIAN is not set
+ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+@@ -853,9 +925,8 @@ CONFIG_USB_UHCI_HCD=m
+ #
+ # USB Device Class drivers
+ #
+-# CONFIG_USB_AUDIO is not set
++# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+ # CONFIG_USB_BLUETOOTH_TTY is not set
+-# CONFIG_USB_MIDI is not set
+ # CONFIG_USB_ACM is not set
+ # CONFIG_USB_PRINTER is not set
+ 
+@@ -888,12 +959,17 @@ CONFIG_USB_HIDINPUT=y
+ # 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_YEALINK is not set
+ # CONFIG_USB_XPAD is not set
+ # CONFIG_USB_ATI_REMOTE is not set
++# CONFIG_USB_KEYSPAN_REMOTE is not set
++# CONFIG_USB_APPLETOUCH is not set
+ 
+ #
+ # USB Imaging devices
+@@ -918,7 +994,7 @@ CONFIG_USB_HIDINPUT=y
+ # CONFIG_USB_PEGASUS is not set
+ # CONFIG_USB_RTL8150 is not set
+ # CONFIG_USB_USBNET is not set
+-CONFIG_USB_MON=m
++CONFIG_USB_MON=y
+ 
+ #
+ # USB port drivers
+@@ -944,10 +1020,11 @@ CONFIG_USB_MON=m
+ # CONFIG_USB_PHIDGETSERVO is not set
+ # CONFIG_USB_IDMOUSE is not set
+ # CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
+ # CONFIG_USB_TEST is not set
+ 
+ #
+-# USB ATM/DSL drivers
++# USB DSL modem support
+ #
+ 
+ #
+@@ -964,6 +1041,8 @@ CONFIG_USB_MON=m
+ # InfiniBand support
+ #
+ CONFIG_INFINIBAND=m
++# CONFIG_INFINIBAND_USER_MAD is not set
++# CONFIG_INFINIBAND_USER_ACCESS is not set
+ CONFIG_INFINIBAND_MTHCA=m
+ # CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+ CONFIG_INFINIBAND_IPOIB=m
+@@ -981,6 +1060,7 @@ 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
+@@ -996,22 +1076,20 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
+ CONFIG_REISERFS_FS_SECURITY=y
+ # CONFIG_JFS_FS is not set
+ CONFIG_FS_POSIX_ACL=y
+-
+-#
+-# XFS support
+-#
+ CONFIG_XFS_FS=y
+ CONFIG_XFS_EXPORT=y
+-# CONFIG_XFS_RT is not set
+ # 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_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=y
+ CONFIG_AUTOFS4_FS=y
++# CONFIG_FUSE_FS is not set
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -1040,14 +1118,11 @@ CONFIG_NTFS_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ CONFIG_TMPFS=y
+-CONFIG_TMPFS_XATTR=y
+-CONFIG_TMPFS_SECURITY=y
+ CONFIG_HUGETLBFS=y
+ CONFIG_HUGETLB_PAGE=y
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -1071,15 +1146,18 @@ CONFIG_RAMFS=y
+ #
+ CONFIG_NFS_FS=m
+ 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_LOCKD=m
+ CONFIG_LOCKD_V4=y
+ CONFIG_EXPORTFS=y
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=m
+ CONFIG_SUNRPC_GSS=m
+ CONFIG_RPCSEC_GSS_KRB5=m
+@@ -1094,6 +1172,7 @@ CONFIG_CIFS=m
+ # 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
+@@ -1163,10 +1242,12 @@ CONFIG_NLS_UTF8=m
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
+ CONFIG_CRC32=y
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_PENDING_IRQ=y
+ 
+ #
+ # HP Simulator drivers
+@@ -1187,6 +1268,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
+ CONFIG_DEBUG_KERNEL=y
+ CONFIG_MAGIC_SYSRQ=y
+ CONFIG_LOG_BUF_SHIFT=20
++CONFIG_DETECT_SOFTLOCKUP=y
+ # CONFIG_SCHEDSTATS is not set
+ # CONFIG_DEBUG_SLAB is not set
+ # CONFIG_DEBUG_SPINLOCK is not set
+@@ -1194,6 +1276,7 @@ CONFIG_LOG_BUF_SHIFT=20
+ # CONFIG_DEBUG_KOBJECT is not set
+ # CONFIG_DEBUG_INFO is not set
+ # CONFIG_DEBUG_FS is not set
++# CONFIG_KPROBES is not set
+ CONFIG_IA64_GRANULE_16MB=y
+ # CONFIG_IA64_GRANULE_64MB is not set
+ # CONFIG_IA64_PRINT_HAZARDS is not set
+@@ -1215,7 +1298,7 @@ CONFIG_CRYPTO=y
+ # CONFIG_CRYPTO_HMAC is not set
+ # CONFIG_CRYPTO_NULL is not set
+ # CONFIG_CRYPTO_MD4 is not set
+-CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_MD5=y
+ # CONFIG_CRYPTO_SHA1 is not set
+ # CONFIG_CRYPTO_SHA256 is not set
+ # CONFIG_CRYPTO_SHA512 is not set
+diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
+--- a/arch/ia64/hp/common/hwsw_iommu.c
++++ b/arch/ia64/hp/common/hwsw_iommu.c
+@@ -17,7 +17,7 @@
+ #include <asm/machvec.h>
+ 
+ /* swiotlb declarations & definitions: */
+-extern void swiotlb_init_with_default_size (size_t size);
++extern int swiotlb_late_init_with_default_size (size_t size);
+ extern ia64_mv_dma_alloc_coherent	swiotlb_alloc_coherent;
+ extern ia64_mv_dma_free_coherent	swiotlb_free_coherent;
+ extern ia64_mv_dma_map_single		swiotlb_map_single;
+@@ -67,11 +67,20 @@ void
+ hwsw_init (void)
+ {
+ 	/* default to a smallish 2MB sw I/O TLB */
+-	swiotlb_init_with_default_size (2 * (1<<20));
++	if (swiotlb_late_init_with_default_size (2 * (1<<20)) != 0) {
++#ifdef CONFIG_IA64_GENERIC
++		/* Better to have normal DMA than panic */
++		printk(KERN_WARNING "%s: Failed to initialize software I/O TLB,"
++		       " reverting to hpzx1 platform vector\n", __FUNCTION__);
++		machvec_init("hpzx1");
++#else
++		panic("Unable to initialize software I/O TLB services");
++#endif
++	}
+ }
+ 
+ void *
+-hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
++hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
+ {
+ 	if (use_swiotlb(dev))
+ 		return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
+diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
+--- a/arch/ia64/hp/common/sba_iommu.c
++++ b/arch/ia64/hp/common/sba_iommu.c
+@@ -1076,7 +1076,7 @@ void sba_unmap_single(struct device *dev
+  * See Documentation/DMA-mapping.txt
+  */
+ void *
+-sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
++sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
+ {
+ 	struct ioc *ioc;
+ 	void *addr;
+@@ -2028,9 +2028,40 @@ static struct acpi_driver acpi_sba_ioc_d
+ static int __init
+ sba_init(void)
+ {
++	if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb"))
++		return 0;
++
+ 	acpi_bus_register_driver(&acpi_sba_ioc_driver);
+-	if (!ioc_list)
++	if (!ioc_list) {
++#ifdef CONFIG_IA64_GENERIC
++		extern int swiotlb_late_init_with_default_size (size_t size);
++
++		/*
++		 * If we didn't find something sba_iommu can claim, we
++		 * need to setup the swiotlb and switch to the dig machvec.
++		 */
++		if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
++			panic("Unable to find SBA IOMMU or initialize "
++			      "software I/O TLB: Try machvec=dig boot option");
++		machvec_init("dig");
++#else
++		panic("Unable to find SBA IOMMU: Try a generic or DIG kernel");
++#endif
+ 		return 0;
++	}
++
++#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB)
++	/*
++	 * hpzx1_swiotlb needs to have a fairly small swiotlb bounce
++	 * buffer setup to support devices with smaller DMA masks than
++	 * sba_iommu can handle.
++	 */
++	if (ia64_platform_is("hpzx1_swiotlb")) {
++		extern void hwsw_init(void);
++
++		hwsw_init();
++	}
++#endif
+ 
+ #ifdef CONFIG_PCI
+ 	{
+@@ -2048,18 +2079,6 @@ sba_init(void)
+ 
+ subsys_initcall(sba_init); /* must be initialized after ACPI etc., but before any drivers... */
+ 
+-extern void dig_setup(char**);
+-/*
+- * MAX_DMA_ADDRESS needs to be setup prior to paging_init to do any good,
+- * so we use the platform_setup hook to fix it up.
+- */
+-void __init
+-sba_setup(char **cmdline_p)
+-{
+-	MAX_DMA_ADDRESS = ~0UL;
+-	dig_setup(cmdline_p);
+-}
+-
+ static int __init
+ nosbagart(char *str)
+ {
+diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
+--- a/arch/ia64/hp/sim/simscsi.c
++++ b/arch/ia64/hp/sim/simscsi.c
+@@ -205,10 +205,11 @@ simscsi_get_disk_size (int fd)
+ 	char buf[512];
+ 
+ 	/*
+-	 * This is a bit kludgey: the simulator doesn't provide a direct way of determining
+-	 * the disk size, so we do a binary search, assuming a maximum disk size of 4GB.
++	 * This is a bit kludgey: the simulator doesn't provide a
++	 * direct way of determining the disk size, so we do a binary
++	 * search, assuming a maximum disk size of 128GB.
+ 	 */
+-	for (bit = (4UL << 30)/512; bit != 0; bit >>= 1) {
++	for (bit = (128UL << 30)/512; bit != 0; bit >>= 1) {
+ 		req.addr = __pa(&buf);
+ 		req.len = sizeof(buf);
+ 		ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ);
+@@ -225,8 +226,10 @@ simscsi_readwrite10 (struct scsi_cmnd *s
+ {
+ 	unsigned long offset;
+ 
+-	offset = (  (sc->cmnd[2] << 24) | (sc->cmnd[3] << 16)
+-		  | (sc->cmnd[4] <<  8) | (sc->cmnd[5] <<  0))*512;
++	offset = (((unsigned long)sc->cmnd[2] << 24) 
++		| ((unsigned long)sc->cmnd[3] << 16)
++		| ((unsigned long)sc->cmnd[4] <<  8) 
++		| ((unsigned long)sc->cmnd[5] <<  0))*512UL;
+ 	if (sc->use_sg > 0)
+ 		simscsi_sg_readwrite(sc, mode, offset);
+ 	else
+diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
+--- a/arch/ia64/ia32/sys_ia32.c
++++ b/arch/ia64/ia32/sys_ia32.c
+@@ -36,6 +36,7 @@
+ #include <linux/uio.h>
+ #include <linux/nfs_fs.h>
+ #include <linux/quota.h>
++#include <linux/syscalls.h>
+ #include <linux/sunrpc/svc.h>
+ #include <linux/nfsd/nfsd.h>
+ #include <linux/nfsd/cache.h>
+diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
+--- a/arch/ia64/kernel/acpi.c
++++ b/arch/ia64/kernel/acpi.c
+@@ -838,7 +838,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
+ #endif				/* CONFIG_ACPI_HOTPLUG_CPU */
+ 
+ #ifdef CONFIG_ACPI_NUMA
+-acpi_status __devinit
++static acpi_status __devinit
+ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret)
+ {
+ 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+@@ -890,7 +890,16 @@ acpi_map_iosapic(acpi_handle handle, u32
+ 	map_iosapic_to_node(gsi_base, node);
+ 	return AE_OK;
+ }
+-#endif				/* CONFIG_NUMA */
++
++static int __init
++acpi_map_iosapics (void)
++{
++	acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
++	return 0;
++}
++
++fs_initcall(acpi_map_iosapics);
++#endif				/* CONFIG_ACPI_NUMA */
+ 
+ int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
+ {
+diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c
+--- a/arch/ia64/kernel/cyclone.c
++++ b/arch/ia64/kernel/cyclone.c
+@@ -2,6 +2,7 @@
+ #include <linux/smp.h>
+ #include <linux/time.h>
+ #include <linux/errno.h>
++#include <linux/timex.h>
+ #include <asm/io.h>
+ 
+ /* IBM Summit (EXA) Cyclone counter code*/
+diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
+--- a/arch/ia64/kernel/efi.c
++++ b/arch/ia64/kernel/efi.c
+@@ -239,57 +239,30 @@ is_available_memory (efi_memory_desc_t *
+ 	return 0;
+ }
+ 
+-/*
+- * Trim descriptor MD so its starts at address START_ADDR.  If the descriptor covers
+- * memory that is normally available to the kernel, issue a warning that some memory
+- * is being ignored.
+- */
+-static void
+-trim_bottom (efi_memory_desc_t *md, u64 start_addr)
+-{
+-	u64 num_skipped_pages;
+-
+-	if (md->phys_addr >= start_addr || !md->num_pages)
+-		return;
++typedef struct kern_memdesc {
++	u64 attribute;
++	u64 start;
++	u64 num_pages;
++} kern_memdesc_t;
+ 
+-	num_skipped_pages = (start_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
+-	if (num_skipped_pages > md->num_pages)
+-		num_skipped_pages = md->num_pages;
+-
+-	if (is_available_memory(md))
+-		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
+-		       "at 0x%lx\n", __FUNCTION__,
+-		       (num_skipped_pages << EFI_PAGE_SHIFT) >> 10,
+-		       md->phys_addr, start_addr - IA64_GRANULE_SIZE);
+-	/*
+-	 * NOTE: Don't set md->phys_addr to START_ADDR because that could cause the memory
+-	 * descriptor list to become unsorted.  In such a case, md->num_pages will be
+-	 * zero, so the Right Thing will happen.
+-	 */
+-	md->phys_addr += num_skipped_pages << EFI_PAGE_SHIFT;
+-	md->num_pages -= num_skipped_pages;
+-}
++static kern_memdesc_t *kern_memmap;
+ 
+ static void
+-trim_top (efi_memory_desc_t *md, u64 end_addr)
++walk (efi_freemem_callback_t callback, void *arg, u64 attr)
+ {
+-	u64 num_dropped_pages, md_end_addr;
+-
+-	md_end_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+-
+-	if (md_end_addr <= end_addr || !md->num_pages)
+-		return;
++	kern_memdesc_t *k;
++	u64 start, end, voff;
+ 
+-	num_dropped_pages = (md_end_addr - end_addr) >> EFI_PAGE_SHIFT;
+-	if (num_dropped_pages > md->num_pages)
+-		num_dropped_pages = md->num_pages;
+-
+-	if (is_available_memory(md))
+-		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
+-		       "at 0x%lx\n", __FUNCTION__,
+-		       (num_dropped_pages << EFI_PAGE_SHIFT) >> 10,
+-		       md->phys_addr, end_addr);
+-	md->num_pages -= num_dropped_pages;
++	voff = (attr == EFI_MEMORY_WB) ? PAGE_OFFSET : __IA64_UNCACHED_OFFSET;
++	for (k = kern_memmap; k->start != ~0UL; k++) {
++		if (k->attribute != attr)
++			continue;
++		start = PAGE_ALIGN(k->start);
++		end = (k->start + (k->num_pages << EFI_PAGE_SHIFT)) & PAGE_MASK;
++		if (start < end)
++			if ((*callback)(start + voff, end + voff, arg) < 0)
++				return;
++	}
+ }
+ 
+ /*
+@@ -299,148 +272,19 @@ trim_top (efi_memory_desc_t *md, u64 end
+ void
+ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
+ {
+-	int prev_valid = 0;
+-	struct range {
+-		u64 start;
+-		u64 end;
+-	} prev, curr;
+-	void *efi_map_start, *efi_map_end, *p, *q;
+-	efi_memory_desc_t *md, *check_md;
+-	u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0;
+-	unsigned long total_mem = 0;
+-
+-	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;
+-
+-	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+-		md = p;
+-
+-		/* skip over non-WB memory descriptors; that's all we're interested in... */
+-		if (!(md->attribute & EFI_MEMORY_WB))
+-			continue;
+-
+-		/*
+-		 * granule_addr is the base of md's first granule.
+-		 * [granule_addr - first_non_wb_addr) is guaranteed to
+-		 * be contiguous WB memory.
+-		 */
+-		granule_addr = GRANULEROUNDDOWN(md->phys_addr);
+-		first_non_wb_addr = max(first_non_wb_addr, granule_addr);
+-
+-		if (first_non_wb_addr < md->phys_addr) {
+-			trim_bottom(md, granule_addr + IA64_GRANULE_SIZE);
+-			granule_addr = GRANULEROUNDDOWN(md->phys_addr);
+-			first_non_wb_addr = max(first_non_wb_addr, granule_addr);
+-		}
+-
+-		for (q = p; q < efi_map_end; q += efi_desc_size) {
+-			check_md = q;
+-
+-			if ((check_md->attribute & EFI_MEMORY_WB) &&
+-			    (check_md->phys_addr == first_non_wb_addr))
+-				first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT;
+-			else
+-				break;		/* non-WB or hole */
+-		}
+-
+-		last_granule_addr = GRANULEROUNDDOWN(first_non_wb_addr);
+-		if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT))
+-			trim_top(md, last_granule_addr);
+-
+-		if (is_available_memory(md)) {
+-			if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) >= max_addr) {
+-				if (md->phys_addr >= max_addr)
+-					continue;
+-				md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
+-				first_non_wb_addr = max_addr;
+-			}
+-
+-			if (total_mem >= mem_limit)
+-				continue;
+-
+-			if (total_mem + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
+-				unsigned long limit_addr = md->phys_addr;
+-
+-				limit_addr += mem_limit - total_mem;
+-				limit_addr = GRANULEROUNDDOWN(limit_addr);
+-
+-				if (md->phys_addr > limit_addr)
+-					continue;
+-
+-				md->num_pages = (limit_addr - md->phys_addr) >>
+-				                EFI_PAGE_SHIFT;
+-				first_non_wb_addr = max_addr = md->phys_addr +
+-				              (md->num_pages << EFI_PAGE_SHIFT);
+-			}
+-			total_mem += (md->num_pages << EFI_PAGE_SHIFT);
+-
+-			if (md->num_pages == 0)
+-				continue;
+-
+-			curr.start = PAGE_OFFSET + md->phys_addr;
+-			curr.end   = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
+-
+-			if (!prev_valid) {
+-				prev = curr;
+-				prev_valid = 1;
+-			} else {
+-				if (curr.start < prev.start)
+-					printk(KERN_ERR "Oops: EFI memory table not ordered!\n");
+-
+-				if (prev.end == curr.start) {
+-					/* merge two consecutive memory ranges */
+-					prev.end = curr.end;
+-				} else {
+-					start = PAGE_ALIGN(prev.start);
+-					end = prev.end & PAGE_MASK;
+-					if ((end > start) && (*callback)(start, end, arg) < 0)
+-						return;
+-					prev = curr;
+-				}
+-			}
+-		}
+-	}
+-	if (prev_valid) {
+-		start = PAGE_ALIGN(prev.start);
+-		end = prev.end & PAGE_MASK;
+-		if (end > start)
+-			(*callback)(start, end, arg);
+-	}
++	walk(callback, arg, EFI_MEMORY_WB);
+ }
+ 
+ /*
+- * Walk the EFI memory map to pull out leftover pages in the lower
+- * memory regions which do not end up in the regular memory map and
+- * stick them into the uncached allocator
+- *
+- * The regular walk function is significantly more complex than the
+- * uncached walk which means it really doesn't make sense to try and
+- * marge the two.
++ * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that
++ * has memory that is available for uncached allocator.
+  */
+-void __init
+-efi_memmap_walk_uc (efi_freemem_callback_t callback)
++void
++efi_memmap_walk_uc (efi_freemem_callback_t callback, void *arg)
+ {
+-	void *efi_map_start, *efi_map_end, *p;
+-	efi_memory_desc_t *md;
+-	u64 efi_desc_size, start, end;
+-
+-	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;
+-
+-	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+-		md = p;
+-		if (md->attribute == EFI_MEMORY_UC) {
+-			start = PAGE_ALIGN(md->phys_addr);
+-			end = PAGE_ALIGN((md->phys_addr+(md->num_pages << EFI_PAGE_SHIFT)) & PAGE_MASK);
+-			if ((*callback)(start, end, NULL) < 0)
+-				return;
+-		}
+-	}
++	walk(callback, arg, EFI_MEMORY_UC);
+ }
+ 
+-
+ /*
+  * Look for the PAL_CODE region reported by EFI and maps it using an
+  * ITR to enable safe PAL calls in virtual mode.  See IA-64 Processor
+@@ -862,3 +706,307 @@ efi_uart_console_only(void)
+ 	printk(KERN_ERR "Malformed %s value\n", name);
+ 	return 0;
+ }
++
++#define efi_md_size(md)	(md->num_pages << EFI_PAGE_SHIFT)
++
++static inline u64
++kmd_end(kern_memdesc_t *kmd)
++{
++	return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT));
++}
++
++static inline u64
++efi_md_end(efi_memory_desc_t *md)
++{
++	return (md->phys_addr + efi_md_size(md));
++}
++
++static inline int
++efi_wb(efi_memory_desc_t *md)
++{
++	return (md->attribute & EFI_MEMORY_WB);
++}
++
++static inline int
++efi_uc(efi_memory_desc_t *md)
++{
++	return (md->attribute & EFI_MEMORY_UC);
++}
++
++/*
++ * Look for the first granule aligned memory descriptor memory
++ * that is big enough to hold EFI memory map. Make sure this
++ * descriptor is atleast granule sized so it does not get trimmed
++ */
++struct kern_memdesc *
++find_memmap_space (void)
++{
++	u64	contig_low=0, contig_high=0;
++	u64	as = 0, ae;
++	void *efi_map_start, *efi_map_end, *p, *q;
++	efi_memory_desc_t *md, *pmd = NULL, *check_md;
++	u64	space_needed, efi_desc_size;
++	unsigned long total_mem = 0;
++
++	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;
++
++	/*
++	 * Worst case: we need 3 kernel descriptors for each efi descriptor
++	 * (if every entry has a WB part in the middle, and UC head and tail),
++	 * plus one for the end marker.
++	 */
++	space_needed = sizeof(kern_memdesc_t) *
++		(3 * (ia64_boot_param->efi_memmap_size/efi_desc_size) + 1);
++
++	for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) {
++		md = p;
++		if (!efi_wb(md)) {
++			continue;
++		}
++		if (pmd == NULL || !efi_wb(pmd) || efi_md_end(pmd) != md->phys_addr) {
++			contig_low = GRANULEROUNDUP(md->phys_addr);
++			contig_high = efi_md_end(md);
++			for (q = p + efi_desc_size; q < efi_map_end; q += efi_desc_size) {
++				check_md = q;
++				if (!efi_wb(check_md))
++					break;
++				if (contig_high != check_md->phys_addr)
++					break;
++				contig_high = efi_md_end(check_md);
++			}
++			contig_high = GRANULEROUNDDOWN(contig_high);
++		}
++		if (!is_available_memory(md) || md->type == EFI_LOADER_DATA)
++			continue;
++
++		/* Round ends inward to granule boundaries */
++		as = max(contig_low, md->phys_addr);
++		ae = min(contig_high, efi_md_end(md));
++
++		/* keep within max_addr= command line arg */
++		ae = min(ae, max_addr);
++		if (ae <= as)
++			continue;
++
++		/* avoid going over mem= command line arg */
++		if (total_mem + (ae - as) > mem_limit)
++			ae -= total_mem + (ae - as) - mem_limit;
++
++		if (ae <= as)
++			continue;
++
++		if (ae - as > space_needed)
++			break;
++	}
++	if (p >= efi_map_end)
++		panic("Can't allocate space for kernel memory descriptors");
++
++	return __va(as);
++}
++
++/*
++ * Walk the EFI memory map and gather all memory available for kernel
++ * to use.  We can allocate partial granules only if the unavailable
++ * parts exist, and are WB.
++ */
++void
++efi_memmap_init(unsigned long *s, unsigned long *e)
++{
++	struct kern_memdesc *k, *prev = 0;
++	u64	contig_low=0, contig_high=0;
++	u64	as, ae, lim;
++	void *efi_map_start, *efi_map_end, *p, *q;
++	efi_memory_desc_t *md, *pmd = NULL, *check_md;
++	u64	efi_desc_size;
++	unsigned long total_mem = 0;
++
++	k = kern_memmap = find_memmap_space();
++
++	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;
++
++	for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) {
++		md = p;
++		if (!efi_wb(md)) {
++			if (efi_uc(md) && (md->type == EFI_CONVENTIONAL_MEMORY ||
++				    	   md->type == EFI_BOOT_SERVICES_DATA)) {
++				k->attribute = EFI_MEMORY_UC;
++				k->start = md->phys_addr;
++				k->num_pages = md->num_pages;
++				k++;
++			}
++			continue;
++		}
++		if (pmd == NULL || !efi_wb(pmd) || efi_md_end(pmd) != md->phys_addr) {
++			contig_low = GRANULEROUNDUP(md->phys_addr);
++			contig_high = efi_md_end(md);
++			for (q = p + efi_desc_size; q < efi_map_end; q += efi_desc_size) {
++				check_md = q;
++				if (!efi_wb(check_md))
++					break;
++				if (contig_high != check_md->phys_addr)
++					break;
++				contig_high = efi_md_end(check_md);
++			}
++			contig_high = GRANULEROUNDDOWN(contig_high);
++		}
++		if (!is_available_memory(md))
++			continue;
++
++		/*
++		 * Round ends inward to granule boundaries
++		 * Give trimmings to uncached allocator
++		 */
++		if (md->phys_addr < contig_low) {
++			lim = min(efi_md_end(md), contig_low);
++			if (efi_uc(md)) {
++				if (k > kern_memmap && (k-1)->attribute == EFI_MEMORY_UC &&
++				    kmd_end(k-1) == md->phys_addr) {
++					(k-1)->num_pages += (lim - md->phys_addr) >> EFI_PAGE_SHIFT;
++				} else {
++					k->attribute = EFI_MEMORY_UC;
++					k->start = md->phys_addr;
++					k->num_pages = (lim - md->phys_addr) >> EFI_PAGE_SHIFT;
++					k++;
++				}
++			}
++			as = contig_low;
++		} else
++			as = md->phys_addr;
++
++		if (efi_md_end(md) > contig_high) {
++			lim = max(md->phys_addr, contig_high);
++			if (efi_uc(md)) {
++				if (lim == md->phys_addr && k > kern_memmap &&
++				    (k-1)->attribute == EFI_MEMORY_UC &&
++				    kmd_end(k-1) == md->phys_addr) {
++					(k-1)->num_pages += md->num_pages;
++				} else {
++					k->attribute = EFI_MEMORY_UC;
++					k->start = lim;
++					k->num_pages = (efi_md_end(md) - lim) >> EFI_PAGE_SHIFT;
++					k++;
++				}
++			}
++			ae = contig_high;
++		} else
++			ae = efi_md_end(md);
++
++		/* keep within max_addr= command line arg */
++		ae = min(ae, max_addr);
++		if (ae <= as)
++			continue;
++
++		/* avoid going over mem= command line arg */
++		if (total_mem + (ae - as) > mem_limit)
++			ae -= total_mem + (ae - as) - mem_limit;
++
++		if (ae <= as)
++			continue;
++		if (prev && kmd_end(prev) == md->phys_addr) {
++			prev->num_pages += (ae - as) >> EFI_PAGE_SHIFT;
++			total_mem += ae - as;
++			continue;
++		}
++		k->attribute = EFI_MEMORY_WB;
++		k->start = as;
++		k->num_pages = (ae - as) >> EFI_PAGE_SHIFT;
++		total_mem += ae - as;
++		prev = k++;
++	}
++	k->start = ~0L; /* end-marker */
++
++	/* reserve the memory we are using for kern_memmap */
++	*s = (u64)kern_memmap;
++	*e = (u64)++k;
++}
++
++void
++efi_initialize_iomem_resources(struct resource *code_resource,
++			       struct resource *data_resource)
++{
++	struct resource *res;
++	void *efi_map_start, *efi_map_end, *p;
++	efi_memory_desc_t *md;
++	u64 efi_desc_size;
++	char *name;
++	unsigned long flags;
++
++	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;
++
++	res = NULL;
++
++	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
++		md = p;
++
++		if (md->num_pages == 0) /* should not happen */
++			continue;
++
++		flags = IORESOURCE_MEM;
++		switch (md->type) {
++
++			case EFI_MEMORY_MAPPED_IO:
++			case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
++				continue;
++
++			case EFI_LOADER_CODE:
++			case EFI_LOADER_DATA:
++			case EFI_BOOT_SERVICES_DATA:
++			case EFI_BOOT_SERVICES_CODE:
++			case EFI_CONVENTIONAL_MEMORY:
++				if (md->attribute & EFI_MEMORY_WP) {
++					name = "System ROM";
++					flags |= IORESOURCE_READONLY;
++				} else {
++					name = "System RAM";
++				}
++				break;
++
++			case EFI_ACPI_MEMORY_NVS:
++				name = "ACPI Non-volatile Storage";
++				flags |= IORESOURCE_BUSY;
++				break;
++
++			case EFI_UNUSABLE_MEMORY:
++				name = "reserved";
++				flags |= IORESOURCE_BUSY | IORESOURCE_DISABLED;
++				break;
++
++			case EFI_RESERVED_TYPE:
++			case EFI_RUNTIME_SERVICES_CODE:
++			case EFI_RUNTIME_SERVICES_DATA:
++			case EFI_ACPI_RECLAIM_MEMORY:
++			default:
++				name = "reserved";
++				flags |= IORESOURCE_BUSY;
++				break;
++		}
++
++		if ((res = kcalloc(1, sizeof(struct resource), GFP_KERNEL)) == NULL) {
++			printk(KERN_ERR "failed to alocate resource for iomem\n");
++			return;
++		}
++
++		res->name = name;
++		res->start = md->phys_addr;
++		res->end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
++		res->flags = flags;
++
++		if (insert_resource(&iomem_resource, res) < 0)
++			kfree(res);
++		else {
++			/*
++			 * We don't know which region contains
++			 * kernel data so we try it repeatedly and
++			 * let the resource manager test it.
++			 */
++			insert_resource(res, code_resource);
++			insert_resource(res, data_resource);
++		}
++	}
++}
+diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
+--- a/arch/ia64/kernel/irq.c
++++ b/arch/ia64/kernel/irq.c
+@@ -57,9 +57,9 @@ int show_interrupts(struct seq_file *p, 
+ 
+ 	if (i == 0) {
+ 		seq_printf(p, "           ");
+-		for (j=0; j<NR_CPUS; j++)
+-			if (cpu_online(j))
+-				seq_printf(p, "CPU%d       ",j);
++		for_each_online_cpu(j) {
++			seq_printf(p, "CPU%d       ",j);
++		}
+ 		seq_putc(p, '\n');
+ 	}
+ 
+@@ -72,9 +72,9 @@ int show_interrupts(struct seq_file *p, 
+ #ifndef CONFIG_SMP
+ 		seq_printf(p, "%10u ", kstat_irqs(i));
+ #else
+-		for (j = 0; j < NR_CPUS; j++)
+-			if (cpu_online(j))
+-				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
++		for_each_online_cpu(j) {
++			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
++		}
+ #endif
+ 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+ 		seq_printf(p, "  %s", action->name);
+diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
+--- a/arch/ia64/kernel/mca.c
++++ b/arch/ia64/kernel/mca.c
+@@ -508,9 +508,7 @@ ia64_mca_wakeup_all(void)
+ 	int cpu;
+ 
+ 	/* Clear the Rendez checkin flag for all cpus */
+-	for(cpu = 0; cpu < NR_CPUS; cpu++) {
+-		if (!cpu_online(cpu))
+-			continue;
++	for_each_online_cpu(cpu) {
+ 		if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE)
+ 			ia64_mca_wakeup(cpu);
+ 	}
+diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
+--- a/arch/ia64/kernel/module.c
++++ b/arch/ia64/kernel/module.c
+@@ -947,8 +947,8 @@ void
+ percpu_modcopy (void *pcpudst, const void *src, unsigned long size)
+ {
+ 	unsigned int i;
+-	for (i = 0; i < NR_CPUS; i++)
+-		if (cpu_possible(i))
+-			memcpy(pcpudst + __per_cpu_offset[i], src, size);
++	for_each_cpu(i) {
++		memcpy(pcpudst + __per_cpu_offset[i], src, size);
++	}
+ }
+ #endif /* CONFIG_SMP */
+diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c
+--- a/arch/ia64/kernel/patch.c
++++ b/arch/ia64/kernel/patch.c
+@@ -64,22 +64,30 @@ ia64_patch (u64 insn_addr, u64 mask, u64
+ void
+ ia64_patch_imm64 (u64 insn_addr, u64 val)
+ {
+-	ia64_patch(insn_addr,
++	/* The assembler may generate offset pointing to either slot 1
++	   or slot 2 for a long (2-slot) instruction, occupying slots 1
++	   and 2.  */
++  	insn_addr &= -16UL;
++	ia64_patch(insn_addr + 2,
+ 		   0x01fffefe000UL, (  ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
+ 				     | ((val & 0x0000000000200000UL) <<  0) /* bit 21 -> 21 */
+ 				     | ((val & 0x00000000001f0000UL) <<  6) /* bit 16 -> 22 */
+ 				     | ((val & 0x000000000000ff80UL) << 20) /* bit  7 -> 27 */
+ 				     | ((val & 0x000000000000007fUL) << 13) /* bit  0 -> 13 */));
+-	ia64_patch(insn_addr - 1, 0x1ffffffffffUL, val >> 22);
++	ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22);
+ }
+ 
+ void
+ ia64_patch_imm60 (u64 insn_addr, u64 val)
+ {
+-	ia64_patch(insn_addr,
++	/* The assembler may generate offset pointing to either slot 1
++	   or slot 2 for a long (2-slot) instruction, occupying slots 1
++	   and 2.  */
++  	insn_addr &= -16UL;
++	ia64_patch(insn_addr + 2,
+ 		   0x011ffffe000UL, (  ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
+ 				     | ((val & 0x00000000000fffffUL) << 13) /* bit  0 -> 13 */));
+-	ia64_patch(insn_addr - 1, 0x1fffffffffcUL, val >> 18);
++	ia64_patch(insn_addr + 1, 0x1fffffffffcUL, val >> 18);
+ }
+ 
+ /*
+diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
+--- a/arch/ia64/kernel/perfmon.c
++++ b/arch/ia64/kernel/perfmon.c
+@@ -2352,7 +2352,8 @@ pfm_smpl_buffer_alloc(struct task_struct
+ 	insert_vm_struct(mm, vma);
+ 
+ 	mm->total_vm  += size >> PAGE_SHIFT;
+-	vm_stat_account(vma);
++	vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
++							vma_pages(vma));
+ 	up_write(&task->mm->mmap_sem);
+ 
+ 	/*
+diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
+--- a/arch/ia64/kernel/ptrace.c
++++ b/arch/ia64/kernel/ptrace.c
+@@ -587,8 +587,9 @@ thread_matches (struct task_struct *thre
+ static struct task_struct *
+ find_thread_for_addr (struct task_struct *child, unsigned long addr)
+ {
+-	struct task_struct *g, *p;
++	struct task_struct *p;
+ 	struct mm_struct *mm;
++	struct list_head *this, *next;
+ 	int mm_users;
+ 
+ 	if (!(mm = get_task_mm(child)))
+@@ -600,28 +601,21 @@ find_thread_for_addr (struct task_struct
+ 		goto out;		/* not multi-threaded */
+ 
+ 	/*
+-	 * First, traverse the child's thread-list.  Good for scalability with
+-	 * NPTL-threads.
++	 * Traverse the current process' children list.  Every task that
++	 * one attaches to becomes a child.  And it is only attached children
++	 * of the debugger that are of interest (ptrace_check_attach checks
++	 * for this).
+ 	 */
+-	p = child;
+-	do {
+-		if (thread_matches(p, addr)) {
+-			child = p;
+-			goto out;
+-		}
+-		if (mm_users-- <= 1)
+-			goto out;
+-	} while ((p = next_thread(p)) != child);
+-
+-	do_each_thread(g, p) {
+-		if (child->mm != mm)
++ 	list_for_each_safe(this, next, &current->children) {
++		p = list_entry(this, struct task_struct, sibling);
++		if (p->mm != mm)
+ 			continue;
+-
+ 		if (thread_matches(p, addr)) {
+ 			child = p;
+ 			goto out;
+ 		}
+-	} while_each_thread(g, p);
++	}
++
+   out:
+ 	mmput(mm);
+ 	return child;
+diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
+--- a/arch/ia64/kernel/setup.c
++++ b/arch/ia64/kernel/setup.c
+@@ -78,6 +78,19 @@ struct screen_info screen_info;
+ unsigned long vga_console_iobase;
+ unsigned long vga_console_membase;
+ 
++static struct resource data_resource = {
++	.name	= "Kernel data",
++	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
++};
++
++static struct resource code_resource = {
++	.name	= "Kernel code",
++	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
++};
++extern void efi_initialize_iomem_resources(struct resource *,
++		struct resource *);
++extern char _text[], _end[], _etext[];
++
+ unsigned long ia64_max_cacheline_size;
+ unsigned long ia64_iobase;	/* virtual address for I/O accesses */
+ EXPORT_SYMBOL(ia64_iobase);
+@@ -171,6 +184,22 @@ sort_regions (struct rsvd_region *rsvd_r
+ 	}
+ }
+ 
++/*
++ * Request address space for all standard resources
++ */
++static int __init register_memory(void)
++{
++	code_resource.start = ia64_tpa(_text);
++	code_resource.end   = ia64_tpa(_etext) - 1;
++	data_resource.start = ia64_tpa(_etext);
++	data_resource.end   = ia64_tpa(_end) - 1;
++	efi_initialize_iomem_resources(&code_resource, &data_resource);
++
++	return 0;
++}
++
++__initcall(register_memory);
++
+ /**
+  * reserve_memory - setup reserved memory areas
+  *
+@@ -211,6 +240,9 @@ reserve_memory (void)
+ 	}
+ #endif
+ 
++	efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
++	n++;
++
+ 	/* end of memory marker */
+ 	rsvd_region[n].start = ~0UL;
+ 	rsvd_region[n].end   = ~0UL;
+@@ -244,28 +276,31 @@ find_initrd (void)
+ static void __init
+ io_port_init (void)
+ {
+-	extern unsigned long ia64_iobase;
+ 	unsigned long phys_iobase;
+ 
+ 	/*
+-	 *  Set `iobase' to the appropriate address in region 6 (uncached access range).
++	 * Set `iobase' based on the EFI memory map or, failing that, the
++	 * value firmware left in ar.k0.
+ 	 *
+-	 *  The EFI memory map is the "preferred" location to get the I/O port space base,
+-	 *  rather the relying on AR.KR0. This should become more clear in future SAL
+-	 *  specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is
+-	 *  found in the memory map.
++	 * Note that in ia32 mode, IN/OUT instructions use ar.k0 to compute
++	 * the port's virtual address, so ia32_load_state() loads it with a
++	 * user virtual address.  But in ia64 mode, glibc uses the
++	 * *physical* address in ar.k0 to mmap the appropriate area from
++	 * /dev/mem, and the inX()/outX() interfaces use MMIO.  In both
++	 * cases, user-mode can only use the legacy 0-64K I/O port space.
++	 *
++	 * ar.k0 is not involved in kernel I/O port accesses, which can use
++	 * any of the I/O port spaces and are done via MMIO using the
++	 * virtual mmio_base from the appropriate io_space[].
+ 	 */
+ 	phys_iobase = efi_get_iobase();
+-	if (phys_iobase)
+-		/* set AR.KR0 since this is all we use it for anyway */
+-		ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
+-	else {
++	if (!phys_iobase) {
+ 		phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
+-		printk(KERN_INFO "No I/O port range found in EFI memory map, falling back "
+-		       "to AR.KR0\n");
+-		printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase);
++		printk(KERN_INFO "No I/O port range found in EFI memory map, "
++			"falling back to AR.KR0 (0x%lx)\n", phys_iobase);
+ 	}
+ 	ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
++	ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
+ 
+ 	/* setup legacy IO port space */
+ 	io_space[0].mmio_base = ia64_iobase;
+@@ -526,7 +561,7 @@ show_cpuinfo (struct seq_file *m, void *
+ 		   c->itc_freq / 1000000, c->itc_freq % 1000000,
+ 		   lpj*HZ/500000, (lpj*HZ/5000) % 100);
+ #ifdef CONFIG_SMP
+-	seq_printf(m, "siblings   : %u\n", c->num_log);
++	seq_printf(m, "siblings   : %u\n", cpus_weight(cpu_core_map[cpunum]));
+ 	if (c->threads_per_core > 1 || c->cores_per_socket > 1)
+ 		seq_printf(m,
+ 		   	   "physical id: %u\n"
+diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
+--- a/arch/ia64/kernel/smp.c
++++ b/arch/ia64/kernel/smp.c
+@@ -185,8 +185,8 @@ send_IPI_allbutself (int op)
+ {
+ 	unsigned int i;
+ 
+-	for (i = 0; i < NR_CPUS; i++) {
+-		if (cpu_online(i) && i != smp_processor_id())
++	for_each_online_cpu(i) {
++		if (i != smp_processor_id())
+ 			send_IPI_single(i, op);
+ 	}
+ }
+@@ -199,9 +199,9 @@ send_IPI_all (int op)
+ {
+ 	int i;
+ 
+-	for (i = 0; i < NR_CPUS; i++)
+-		if (cpu_online(i))
+-			send_IPI_single(i, op);
++	for_each_online_cpu(i) {
++		send_IPI_single(i, op);
++	}
+ }
+ 
+ /*
+diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
+--- a/arch/ia64/kernel/smpboot.c
++++ b/arch/ia64/kernel/smpboot.c
+@@ -694,9 +694,9 @@ smp_cpus_done (unsigned int dummy)
+ 	 * Allow the user to impress friends.
+ 	 */
+ 
+-	for (cpu = 0; cpu < NR_CPUS; cpu++)
+-		if (cpu_online(cpu))
+-			bogosum += cpu_data(cpu)->loops_per_jiffy;
++	for_each_online_cpu(cpu) {
++		bogosum += cpu_data(cpu)->loops_per_jiffy;
++	}
+ 
+ 	printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
+ 	       (int)num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
+diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
+--- a/arch/ia64/kernel/time.c
++++ b/arch/ia64/kernel/time.c
+@@ -32,10 +32,6 @@
+ 
+ extern unsigned long wall_jiffies;
+ 
+-u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ #define TIME_KEEPER_ID	0	/* smp_processor_id() of time-keeper */
+ 
+ #ifdef CONFIG_IA64_DEBUG_IRQ
+diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
+--- a/arch/ia64/kernel/uncached.c
++++ b/arch/ia64/kernel/uncached.c
+@@ -205,23 +205,18 @@ EXPORT_SYMBOL(uncached_free_page);
+ static int __init
+ uncached_build_memmap(unsigned long start, unsigned long end, void *arg)
+ {
+-	long length;
+-	unsigned long vstart, vend;
++	long length = end - start;
+ 	int node;
+ 
+-	length = end - start;
+-	vstart = start + __IA64_UNCACHED_OFFSET;
+-	vend = end + __IA64_UNCACHED_OFFSET;
+-
+ 	dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end);
+ 
+-	memset((char *)vstart, 0, length);
++	memset((char *)start, 0, length);
+ 
+-	node = paddr_to_nid(start);
++	node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET);
+ 
+-	for (; vstart < vend ; vstart += PAGE_SIZE) {
+-		dprintk(KERN_INFO "sticking %lx into the pool!\n", vstart);
+-		gen_pool_free(uncached_pool[node], vstart, PAGE_SIZE);
++	for (; start < end ; start += PAGE_SIZE) {
++		dprintk(KERN_INFO "sticking %lx into the pool!\n", start);
++		gen_pool_free(uncached_pool[node], start, PAGE_SIZE);
+ 	}
+ 
+ 	return 0;
+diff --git a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c
+--- a/arch/ia64/lib/swiotlb.c
++++ b/arch/ia64/lib/swiotlb.c
+@@ -49,6 +49,15 @@
+  */
+ #define IO_TLB_SHIFT 11
+ 
++#define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT))
++
++/*
++ * Minimum IO TLB size to bother booting with.  Systems with mainly
++ * 64bit capable cards will only lightly use the swiotlb.  If we can't
++ * allocate a contiguous 1MB, we're probably in trouble anyway.
++ */
++#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
++
+ int swiotlb_force;
+ 
+ /*
+@@ -154,6 +163,99 @@ swiotlb_init (void)
+ 	swiotlb_init_with_default_size(64 * (1<<20));	/* default to 64MB */
+ }
+ 
++/*
++ * Systems with larger DMA zones (those that don't support ISA) can
++ * initialize the swiotlb later using the slab allocator if needed.
++ * This should be just like above, but with some error catching.
++ */
++int
++swiotlb_late_init_with_default_size (size_t default_size)
++{
++	unsigned long i, req_nslabs = io_tlb_nslabs;
++	unsigned int order;
++
++	if (!io_tlb_nslabs) {
++		io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
++		io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
++	}
++
++	/*
++	 * Get IO TLB memory from the low pages
++	 */
++	order = get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT));
++	io_tlb_nslabs = SLABS_PER_PAGE << order;
++
++	while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) {
++		io_tlb_start = (char *)__get_free_pages(GFP_DMA | __GFP_NOWARN,
++		                                        order);
++		if (io_tlb_start)
++			break;
++		order--;
++	}
++
++	if (!io_tlb_start)
++		goto cleanup1;
++
++	if (order != get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT))) {
++		printk(KERN_WARNING "Warning: only able to allocate %ld MB "
++		       "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
++		io_tlb_nslabs = SLABS_PER_PAGE << order;
++	}
++	io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
++	memset(io_tlb_start, 0, io_tlb_nslabs * (1 << IO_TLB_SHIFT));
++
++	/*
++	 * Allocate and initialize the free list array.  This array is used
++	 * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
++	 * between io_tlb_start and io_tlb_end.
++	 */
++	io_tlb_list = (unsigned int *)__get_free_pages(GFP_KERNEL,
++	                              get_order(io_tlb_nslabs * sizeof(int)));
++	if (!io_tlb_list)
++		goto cleanup2;
++
++	for (i = 0; i < io_tlb_nslabs; i++)
++ 		io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
++	io_tlb_index = 0;
++
++	io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL,
++	                           get_order(io_tlb_nslabs * sizeof(char *)));
++	if (!io_tlb_orig_addr)
++		goto cleanup3;
++
++	memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *));
++
++	/*
++	 * Get the overflow emergency buffer
++	 */
++	io_tlb_overflow_buffer = (void *)__get_free_pages(GFP_DMA,
++	                                          get_order(io_tlb_overflow));
++	if (!io_tlb_overflow_buffer)
++		goto cleanup4;
++
++	printk(KERN_INFO "Placing %ldMB software IO TLB between 0x%lx - "
++	       "0x%lx\n", (io_tlb_nslabs * (1 << IO_TLB_SHIFT)) >> 20,
++	       virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
++
++	return 0;
++
++cleanup4:
++	free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs *
++	                                                      sizeof(char *)));
++	io_tlb_orig_addr = NULL;
++cleanup3:
++	free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs *
++	                                                 sizeof(int)));
++	io_tlb_list = NULL;
++	io_tlb_end = NULL;
++cleanup2:
++	free_pages((unsigned long)io_tlb_start, order);
++	io_tlb_start = NULL;
++cleanup1:
++	io_tlb_nslabs = req_nslabs;
++	return -ENOMEM;
++}
++
+ static inline int
+ address_needs_mapping(struct device *hwdev, dma_addr_t addr)
+ {
+@@ -314,7 +416,7 @@ sync_single(struct device *hwdev, char *
+ 
+ void *
+ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
+-		       dma_addr_t *dma_handle, int flags)
++		       dma_addr_t *dma_handle, gfp_t flags)
+ {
+ 	unsigned long dev_addr;
+ 	void *ret;
+diff --git a/arch/ia64/mm/Makefile b/arch/ia64/mm/Makefile
+--- a/arch/ia64/mm/Makefile
++++ b/arch/ia64/mm/Makefile
+@@ -7,6 +7,5 @@ obj-y := init.o fault.o tlb.o extable.o
+ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+ obj-$(CONFIG_NUMA)	   += numa.o
+ obj-$(CONFIG_DISCONTIGMEM) += discontig.o
+-ifndef CONFIG_DISCONTIGMEM
+-obj-y += contig.o
+-endif
++obj-$(CONFIG_SPARSEMEM)	   += discontig.o
++obj-$(CONFIG_FLATMEM)	   += contig.o
+diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
+--- a/arch/ia64/mm/contig.c
++++ b/arch/ia64/mm/contig.c
+@@ -269,7 +269,7 @@ paging_init (void)
+ 	efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
+ 	if (max_gap < LARGE_GAP) {
+ 		vmem_map = (struct page *) 0;
+-		free_area_init_node(0, &contig_page_data, zones_size, 0,
++		free_area_init_node(0, NODE_DATA(0), zones_size, 0,
+ 				    zholes_size);
+ 	} else {
+ 		unsigned long map_size;
+@@ -282,7 +282,7 @@ paging_init (void)
+ 		efi_memmap_walk(create_mem_map_page_table, NULL);
+ 
+ 		NODE_DATA(0)->node_mem_map = vmem_map;
+-		free_area_init_node(0, &contig_page_data, zones_size,
++		free_area_init_node(0, NODE_DATA(0), zones_size,
+ 				    0, zholes_size);
+ 
+ 		printk("Virtual mem_map starts at 0x%p\n", mem_map);
+diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
+--- a/arch/ia64/mm/discontig.c
++++ b/arch/ia64/mm/discontig.c
+@@ -421,6 +421,37 @@ static void __init memory_less_nodes(voi
+ 	return;
+ }
+ 
++#ifdef CONFIG_SPARSEMEM
++/**
++ * register_sparse_mem - notify SPARSEMEM that this memory range exists.
++ * @start: physical start of range
++ * @end: physical end of range
++ * @arg: unused
++ *
++ * Simply calls SPARSEMEM to register memory section(s).
++ */
++static int __init register_sparse_mem(unsigned long start, unsigned long end,
++	void *arg)
++{
++	int nid;
++
++	start = __pa(start) >> PAGE_SHIFT;
++	end = __pa(end) >> PAGE_SHIFT;
++	nid = early_pfn_to_nid(start);
++	memory_present(nid, start, end);
++
++	return 0;
++}
++
++static void __init arch_sparse_init(void)
++{
++	efi_memmap_walk(register_sparse_mem, NULL);
++	sparse_init();
++}
++#else
++#define arch_sparse_init() do {} while (0)
++#endif
++
+ /**
+  * find_memory - walk the EFI memory map and setup the bootmem allocator
+  *
+@@ -524,12 +555,18 @@ void show_mem(void)
+ 	show_free_areas();
+ 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+ 	for_each_pgdat(pgdat) {
+-		unsigned long present = pgdat->node_present_pages;
++		unsigned long present;
++		unsigned long flags;
+ 		int shared = 0, cached = 0, reserved = 0;
++
+ 		printk("Node ID: %d\n", pgdat->node_id);
++		pgdat_resize_lock(pgdat, &flags);
++		present = pgdat->node_present_pages;
+ 		for(i = 0; i < pgdat->node_spanned_pages; i++) {
+-			struct page *page = pgdat_page_nr(pgdat, i);
+-			if (!ia64_pfn_valid(pgdat->node_start_pfn+i))
++			struct page *page;
++			if (pfn_valid(pgdat->node_start_pfn + i))
++				page = pfn_to_page(pgdat->node_start_pfn + i);
++			else
+ 				continue;
+ 			if (PageReserved(page))
+ 				reserved++;
+@@ -538,6 +575,7 @@ void show_mem(void)
+ 			else if (page_count(page))
+ 				shared += page_count(page)-1;
+ 		}
++		pgdat_resize_unlock(pgdat, &flags);
+ 		total_present += present;
+ 		total_reserved += reserved;
+ 		total_cached += cached;
+@@ -648,12 +686,16 @@ void __init paging_init(void)
+ 
+ 	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ 
++	arch_sparse_init();
++
+ 	efi_memmap_walk(filter_rsvd_memory, count_node_pages);
+ 
++#ifdef CONFIG_VIRTUAL_MEM_MAP
+ 	vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page));
+ 	vmem_map = (struct page *) vmalloc_end;
+ 	efi_memmap_walk(create_mem_map_page_table, NULL);
+ 	printk("Virtual mem_map starts at 0x%p\n", vmem_map);
++#endif
+ 
+ 	for_each_online_node(node) {
+ 		memset(zones_size, 0, sizeof(zones_size));
+@@ -690,7 +732,9 @@ void __init paging_init(void)
+ 
+ 		pfn_offset = mem_data[node].min_pfn;
+ 
++#ifdef CONFIG_VIRTUAL_MEM_MAP
+ 		NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset;
++#endif
+ 		free_area_init_node(node, NODE_DATA(node), zones_size,
+ 				    pfn_offset, zholes_size);
+ 	}
+diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
+--- a/arch/ia64/mm/fault.c
++++ b/arch/ia64/mm/fault.c
+@@ -20,32 +20,6 @@
+ extern void die (char *, struct pt_regs *, long);
+ 
+ /*
+- * This routine is analogous to expand_stack() but instead grows the
+- * register backing store (which grows towards higher addresses).
+- * Since the register backing store is access sequentially, we
+- * disallow growing the RBS by more than a page at a time.  Note that
+- * the VM_GROWSUP flag can be set on any VM area but that's fine
+- * because the total process size is still limited by RLIMIT_STACK and
+- * RLIMIT_AS.
+- */
+-static inline long
+-expand_backing_store (struct vm_area_struct *vma, unsigned long address)
+-{
+-	unsigned long grow;
+-
+-	grow = PAGE_SIZE >> PAGE_SHIFT;
+-	if (address - vma->vm_start > current->signal->rlim[RLIMIT_STACK].rlim_cur
+-	    || (((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->signal->rlim[RLIMIT_AS].rlim_cur))
+-		return -ENOMEM;
+-	vma->vm_end += PAGE_SIZE;
+-	vma->vm_mm->total_vm += grow;
+-	if (vma->vm_flags & VM_LOCKED)
+-		vma->vm_mm->locked_vm += grow;
+-	__vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, grow);
+-	return 0;
+-}
+-
+-/*
+  * Return TRUE if ADDRESS points at a page in the kernel's mapped segment
+  * (inside region 5, on ia64) and that page is present.
+  */
+@@ -185,7 +159,13 @@ ia64_do_page_fault (unsigned long addres
+ 		if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
+ 		    || REGION_OFFSET(address) >= RGN_MAP_LIMIT)
+ 			goto bad_area;
+-		if (expand_backing_store(vma, address))
++		/*
++		 * Since the register backing store is accessed sequentially,
++		 * we disallow growing it by more than a page at a time.
++		 */
++		if (address > vma->vm_end + PAGE_SIZE - sizeof(long))
++			goto bad_area;
++		if (expand_upwards(vma, address))
+ 			goto bad_area;
+ 	}
+ 	goto good_area;
+diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
+--- a/arch/ia64/mm/init.c
++++ b/arch/ia64/mm/init.c
+@@ -158,7 +158,7 @@ ia64_init_addr_space (void)
+ 		vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
+ 		vma->vm_end = vma->vm_start + PAGE_SIZE;
+ 		vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
+-		vma->vm_flags = VM_DATA_DEFAULT_FLAGS | VM_GROWSUP;
++		vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
+ 		down_write(&current->mm->mmap_sem);
+ 		if (insert_vm_struct(current->mm, vma)) {
+ 			up_write(&current->mm->mmap_sem);
+@@ -275,26 +275,21 @@ put_kernel_page (struct page *page, unsi
+ 
+ 	pgd = pgd_offset_k(address);		/* note: this is NOT pgd_offset()! */
+ 
+-	spin_lock(&init_mm.page_table_lock);
+ 	{
+ 		pud = pud_alloc(&init_mm, pgd, address);
+ 		if (!pud)
+ 			goto out;
+-
+ 		pmd = pmd_alloc(&init_mm, pud, address);
+ 		if (!pmd)
+ 			goto out;
+-		pte = pte_alloc_map(&init_mm, pmd, address);
++		pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			goto out;
+-		if (!pte_none(*pte)) {
+-			pte_unmap(pte);
++		if (!pte_none(*pte))
+ 			goto out;
+-		}
+ 		set_pte(pte, mk_pte(page, pgprot));
+-		pte_unmap(pte);
+ 	}
+-  out:	spin_unlock(&init_mm.page_table_lock);
++  out:
+ 	/* no need for flush_tlb */
+ 	return page;
+ }
+@@ -593,7 +588,7 @@ mem_init (void)
+ 	platform_dma_init();
+ #endif
+ 
+-#ifndef CONFIG_DISCONTIGMEM
++#ifdef CONFIG_FLATMEM
+ 	if (!mem_map)
+ 		BUG();
+ 	max_mapnr = max_low_pfn;
+diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c
+--- a/arch/ia64/mm/numa.c
++++ b/arch/ia64/mm/numa.c
+@@ -47,3 +47,27 @@ paddr_to_nid(unsigned long paddr)
+ 
+ 	return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0);
+ }
++
++#if defined(CONFIG_SPARSEMEM) && defined(CONFIG_NUMA)
++/*
++ * Because of holes evaluate on section limits.
++ * If the section of memory exists, then return the node where the section
++ * resides.  Otherwise return node 0 as the default.  This is used by
++ * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where
++ * the section resides.
++ */
++int early_pfn_to_nid(unsigned long pfn)
++{
++	int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec;
++
++	for (i = 0; i < num_node_memblks; i++) {
++		ssec = node_memblk[i].start_paddr >> PA_SECTION_SHIFT;
++		esec = (node_memblk[i].start_paddr + node_memblk[i].size +
++			((1L << PA_SECTION_SHIFT) - 1)) >> PA_SECTION_SHIFT;
++		if (section >= ssec && section < esec)
++			return node_memblk[i].nid;
++	}
++
++	return 0;
++}
++#endif
+diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
+--- a/arch/ia64/mm/tlb.c
++++ b/arch/ia64/mm/tlb.c
+@@ -77,19 +77,25 @@ wrap_mmu_context (struct mm_struct *mm)
+ 	/* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */
+ 	{
+ 		int cpu = get_cpu(); /* prevent preemption/migration */
+-		for (i = 0; i < NR_CPUS; ++i)
+-			if (cpu_online(i) && (i != cpu))
++		for_each_online_cpu(i) {
++			if (i != cpu)
+ 				per_cpu(ia64_need_tlb_flush, i) = 1;
++		}
+ 		put_cpu();
+ 	}
+ 	local_flush_tlb_all();
+ }
+ 
+ void
+-ia64_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
++ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits)
+ {
+ 	static DEFINE_SPINLOCK(ptcg_lock);
+ 
++	if (mm != current->active_mm) {
++		flush_tlb_all();
++		return;
++	}
++
+ 	/* HW requires global serialization of ptc.ga.  */
+ 	spin_lock(&ptcg_lock);
+ 	{
+@@ -135,15 +141,12 @@ flush_tlb_range (struct vm_area_struct *
+ 	unsigned long size = end - start;
+ 	unsigned long nbits;
+ 
++#ifndef CONFIG_SMP
+ 	if (mm != current->active_mm) {
+-		/* this does happen, but perhaps it's not worth optimizing for? */
+-#ifdef CONFIG_SMP
+-		flush_tlb_all();
+-#else
+ 		mm->context = 0;
+-#endif
+ 		return;
+ 	}
++#endif
+ 
+ 	nbits = ia64_fls(size + 0xfff);
+ 	while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits))
+@@ -153,12 +156,14 @@ flush_tlb_range (struct vm_area_struct *
+ 	start &= ~((1UL << nbits) - 1);
+ 
+ # ifdef CONFIG_SMP
+-	platform_global_tlb_purge(start, end, nbits);
++	platform_global_tlb_purge(mm, start, end, nbits);
+ # else
++	preempt_disable();
+ 	do {
+ 		ia64_ptcl(start, (nbits<<2));
+ 		start += (1UL << nbits);
+ 	} while (start < end);
++	preempt_enable();
+ # endif
+ 
+ 	ia64_srlz_i();			/* srlz.i implies srlz.d */
+diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
+--- a/arch/ia64/pci/pci.c
++++ b/arch/ia64/pci/pci.c
+@@ -120,29 +120,6 @@ struct pci_ops pci_root_ops = {
+ 	.write = pci_write,
+ };
+ 
+-#ifdef CONFIG_NUMA
+-extern acpi_status acpi_map_iosapic(acpi_handle, u32, void *, void **);
+-static void acpi_map_iosapics(void)
+-{
+-	acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
+-}
+-#else
+-static void acpi_map_iosapics(void)
+-{
+-	return;
+-}
+-#endif /* CONFIG_NUMA */
+-
+-static int __init
+-pci_acpi_init (void)
+-{
+-	acpi_map_iosapics();
+-
+-	return 0;
+-}
+-
+-subsys_initcall(pci_acpi_init);
+-
+ /* Called by ACPI when it finds a new root bus.  */
+ 
+ static struct pci_controller * __devinit
+@@ -191,6 +168,29 @@ add_io_space (struct acpi_resource_addre
+ 	return IO_SPACE_BASE(i);
+ }
+ 
++static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
++	struct acpi_resource_address64 *addr)
++{
++	acpi_status status;
++
++	/*
++	 * We're only interested in _CRS descriptors that are
++	 *	- address space descriptors for memory or I/O space
++	 *	- non-zero size
++	 *	- producers, i.e., the address space is routed downstream,
++	 *	  not consumed by the bridge itself
++	 */
++	status = acpi_resource_to_address64(resource, addr);
++	if (ACPI_SUCCESS(status) &&
++	    (addr->resource_type == ACPI_MEMORY_RANGE ||
++	     addr->resource_type == ACPI_IO_RANGE) &&
++	    addr->address_length &&
++	    addr->producer_consumer == ACPI_PRODUCER)
++		return AE_OK;
++
++	return AE_ERROR;
++}
++
+ static acpi_status __devinit
+ count_window (struct acpi_resource *resource, void *data)
+ {
+@@ -198,11 +198,9 @@ count_window (struct acpi_resource *reso
+ 	struct acpi_resource_address64 addr;
+ 	acpi_status status;
+ 
+-	status = acpi_resource_to_address64(resource, &addr);
++	status = resource_to_window(resource, &addr);
+ 	if (ACPI_SUCCESS(status))
+-		if (addr.resource_type == ACPI_MEMORY_RANGE ||
+-		    addr.resource_type == ACPI_IO_RANGE)
+-			(*windows)++;
++		(*windows)++;
+ 
+ 	return AE_OK;
+ }
+@@ -221,13 +219,11 @@ static __devinit acpi_status add_window(
+ 	unsigned long flags, offset = 0;
+ 	struct resource *root;
+ 
+-	status = acpi_resource_to_address64(res, &addr);
++	/* Return AE_OK for non-window resources to keep scanning for more */
++	status = resource_to_window(res, &addr);
+ 	if (!ACPI_SUCCESS(status))
+ 		return AE_OK;
+ 
+-	if (!addr.address_length)
+-		return AE_OK;
+-
+ 	if (addr.resource_type == ACPI_MEMORY_RANGE) {
+ 		flags = IORESOURCE_MEM;
+ 		root = &iomem_resource;
+diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
+--- a/arch/ia64/sn/kernel/bte.c
++++ b/arch/ia64/sn/kernel/bte.c
+@@ -87,7 +87,7 @@ bte_result_t bte_copy(u64 src, u64 dest,
+ 	unsigned long irq_flags;
+ 	unsigned long itc_end = 0;
+ 	int nasid_to_try[MAX_NODES_TO_TRY];
+-	int my_nasid = get_nasid();
++	int my_nasid = cpuid_to_nasid(raw_smp_processor_id());
+ 	int bte_if_index, nasid_index;
+ 	int bte_first, btes_per_node = BTES_PER_NODE;
+ 
+diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
+--- a/arch/ia64/sn/kernel/io_init.c
++++ b/arch/ia64/sn/kernel/io_init.c
+@@ -22,8 +22,6 @@
+ #include "xtalk/hubdev.h"
+ #include "xtalk/xwidgetdev.h"
+ 
+-nasid_t master_nasid = INVALID_NASID;	/* Partition Master */
+-
+ static struct list_head sn_sysdata_list;
+ 
+ /* sysdata list struct */
+@@ -165,7 +163,7 @@ static void sn_fixup_ionodes(void)
+ 	 * Get SGI Specific HUB chipset information.
+ 	 * Inform Prom that this kernel can support domain bus numbering.
+ 	 */
+-	for (i = 0; i < numionodes; i++) {
++	for (i = 0; i < num_cnodes; i++) {
+ 		hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo);
+ 		nasid = cnodeid_to_nasid(i);
+ 		hubdev->max_segment_number = 0xffffffff;
+diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
+--- a/arch/ia64/sn/kernel/setup.c
++++ b/arch/ia64/sn/kernel/setup.c
+@@ -59,8 +59,6 @@ DEFINE_PER_CPU(struct pda_s, pda_percpu)
+ 
+ #define MAX_PHYS_MEMORY		(1UL << IA64_MAX_PHYS_BITS)	/* Max physical address supported */
+ 
+-lboard_t *root_lboard[MAX_COMPACT_NODES];
+-
+ extern void bte_init_node(nodepda_t *, cnodeid_t);
+ 
+ extern void sn_timer_init(void);
+@@ -97,15 +95,15 @@ u8 sn_region_size;
+ EXPORT_SYMBOL(sn_region_size);
+ int sn_prom_type;	/* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
+ 
+-short physical_node_map[MAX_PHYSNODE_ID];
++short physical_node_map[MAX_NUMALINK_NODES];
+ static unsigned long sn_prom_features[MAX_PROM_FEATURE_SETS];
+ 
+ EXPORT_SYMBOL(physical_node_map);
+ 
+-int numionodes;
++int num_cnodes;
+ 
+ static void sn_init_pdas(char **);
+-static void scan_for_ionodes(void);
++static void build_cnode_tables(void);
+ 
+ static nodepda_t *nodepdaindr[MAX_COMPACT_NODES];
+ 
+@@ -140,19 +138,6 @@ char drive_info[4 * 16];
+ #endif
+ 
+ /*
+- * Get nasid of current cpu early in boot before nodepda is initialized
+- */
+-static int
+-boot_get_nasid(void)
+-{
+-	int nasid;
+-
+-	if (ia64_sn_get_sapic_info(get_sapicid(), &nasid, NULL, NULL))
+-		BUG();
+-	return nasid;
+-}
+-
+-/*
+  * This routine can only be used during init, since
+  * smp_boot_data is an init data structure.
+  * We have to use smp_boot_data.cpu_phys_id to find
+@@ -223,7 +208,6 @@ void __init early_sn_setup(void)
+ }
+ 
+ extern int platform_intr_list[];
+-extern nasid_t master_nasid;
+ static int __initdata shub_1_1_found = 0;
+ 
+ /*
+@@ -269,7 +253,6 @@ static void __init sn_check_for_wars(voi
+ void __init sn_setup(char **cmdline_p)
+ {
+ 	long status, ticks_per_sec, drift;
+-	int pxm;
+ 	u32 version = sn_sal_rev();
+ 	extern void sn_cpu_init(void);
+ 
+@@ -300,11 +283,10 @@ void __init sn_setup(char **cmdline_p)
+ 
+ 	MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY;
+ 
+-	memset(physical_node_map, -1, sizeof(physical_node_map));
+-	for (pxm = 0; pxm < MAX_PXM_DOMAINS; pxm++)
+-		if (pxm_to_nid_map[pxm] != -1)
+-			physical_node_map[pxm_to_nasid(pxm)] =
+-			    pxm_to_nid_map[pxm];
++	/*
++	 * Build the tables for managing cnodes.
++	 */
++	build_cnode_tables();
+ 
+ 	/*
+ 	 * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
+@@ -319,8 +301,6 @@ void __init sn_setup(char **cmdline_p)
+ 
+ 	printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
+ 
+-	master_nasid = boot_get_nasid();
+-
+ 	status =
+ 	    ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
+ 			       &drift);
+@@ -378,15 +358,6 @@ static void __init sn_init_pdas(char **c
+ {
+ 	cnodeid_t cnode;
+ 
+-	memset(sn_cnodeid_to_nasid, -1,
+-			sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
+-	for_each_online_node(cnode)
+-		sn_cnodeid_to_nasid[cnode] =
+-				pxm_to_nasid(nid_to_pxm_map[cnode]);
+-
+-	numionodes = num_online_nodes();
+-	scan_for_ionodes();
+-
+ 	/*
+ 	 * Allocate & initalize the nodepda for each node.
+ 	 */
+@@ -402,7 +373,7 @@ static void __init sn_init_pdas(char **c
+ 	/*
+ 	 * Allocate & initialize nodepda for TIOs.  For now, put them on node 0.
+ 	 */
+-	for (cnode = num_online_nodes(); cnode < numionodes; cnode++) {
++	for (cnode = num_online_nodes(); cnode < num_cnodes; cnode++) {
+ 		nodepdaindr[cnode] =
+ 		    alloc_bootmem_node(NODE_DATA(0), sizeof(nodepda_t));
+ 		memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
+@@ -411,7 +382,7 @@ static void __init sn_init_pdas(char **c
+ 	/*
+ 	 * Now copy the array of nodepda pointers to each nodepda.
+ 	 */
+-	for (cnode = 0; cnode < numionodes; cnode++)
++	for (cnode = 0; cnode < num_cnodes; cnode++)
+ 		memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr,
+ 		       sizeof(nodepdaindr));
+ 
+@@ -428,7 +399,7 @@ static void __init sn_init_pdas(char **c
+ 	 * Initialize the per node hubdev.  This includes IO Nodes and
+ 	 * headless/memless nodes.
+ 	 */
+-	for (cnode = 0; cnode < numionodes; cnode++) {
++	for (cnode = 0; cnode < num_cnodes; cnode++) {
+ 		hubdev_init_node(nodepdaindr[cnode], cnode);
+ 	}
+ }
+@@ -553,87 +524,58 @@ void __init sn_cpu_init(void)
+ }
+ 
+ /*
+- * Scan klconfig for ionodes.  Add the nasids to the
+- * physical_node_map and the pda and increment numionodes.
++ * Build tables for converting between NASIDs and cnodes.
+  */
++static inline int __init board_needs_cnode(int type)
++{
++	return (type == KLTYPE_SNIA || type == KLTYPE_TIO);
++}
+ 
+-static void __init scan_for_ionodes(void)
++void __init build_cnode_tables(void)
+ {
+-	int nasid = 0;
++	int nasid;
++	int node;
+ 	lboard_t *brd;
+ 
+-	/* fakeprom does not support klgraph */
+-	if (IS_RUNNING_ON_FAKE_PROM())
+-		return;
+-
+-	/* Setup ionodes with memory */
+-	for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
+-		char *klgraph_header;
+-		cnodeid_t cnodeid;
+-
+-		if (physical_node_map[nasid] == -1)
+-			continue;
+-
+-		cnodeid = -1;
+-		klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid));
+-		if (!klgraph_header) {
+-			BUG();	/* All nodes must have klconfig tables! */
+-		}
+-		cnodeid = nasid_to_cnodeid(nasid);
+-		root_lboard[cnodeid] = (lboard_t *)
+-		    NODE_OFFSET_TO_LBOARD((nasid),
+-					  ((kl_config_hdr_t
+-					    *) (klgraph_header))->
+-					  ch_board_info);
+-	}
+-
+-	/* Scan headless/memless IO Nodes. */
+-	for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
+-		/* if there's no nasid, don't try to read the klconfig on the node */
+-		if (physical_node_map[nasid] == -1)
+-			continue;
+-		brd = find_lboard_any((lboard_t *)
+-				      root_lboard[nasid_to_cnodeid(nasid)],
+-				      KLTYPE_SNIA);
+-		if (brd) {
+-			brd = KLCF_NEXT_ANY(brd);	/* Skip this node's lboard */
+-			if (!brd)
+-				continue;
+-		}
++	memset(physical_node_map, -1, sizeof(physical_node_map));
++	memset(sn_cnodeid_to_nasid, -1,
++			sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
+ 
+-		brd = find_lboard_any(brd, KLTYPE_SNIA);
++	/*
++	 * First populate the tables with C/M bricks. This ensures that
++	 * cnode == node for all C & M bricks.
++	 */
++	for_each_online_node(node) {
++		nasid = pxm_to_nasid(nid_to_pxm_map[node]);
++		sn_cnodeid_to_nasid[node] = nasid;
++		physical_node_map[nasid] = node;
++	}
+ 
+-		while (brd) {
+-			sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
+-			physical_node_map[brd->brd_nasid] = numionodes;
+-			root_lboard[numionodes] = brd;
+-			numionodes++;
+-			brd = KLCF_NEXT_ANY(brd);
+-			if (!brd)
+-				break;
++	/*
++	 * num_cnodes is total number of C/M/TIO bricks. Because of the 256 node
++	 * limit on the number of nodes, we can't use the generic node numbers 
++	 * for this. Note that num_cnodes is incremented below as TIOs or
++	 * headless/memoryless nodes are discovered.
++	 */
++	num_cnodes = num_online_nodes();
+ 
+-			brd = find_lboard_any(brd, KLTYPE_SNIA);
+-		}
+-	}
++	/* fakeprom does not support klgraph */
++	if (IS_RUNNING_ON_FAKE_PROM())
++		return;
+ 
+-	/* Scan for TIO nodes. */
+-	for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
+-		/* if there's no nasid, don't try to read the klconfig on the node */
+-		if (physical_node_map[nasid] == -1)
+-			continue;
+-		brd = find_lboard_any((lboard_t *)
+-				      root_lboard[nasid_to_cnodeid(nasid)],
+-				      KLTYPE_TIO);
++	/* Find TIOs & headless/memoryless nodes and add them to the tables */
++	for_each_online_node(node) {
++		kl_config_hdr_t *klgraph_header;
++		nasid = cnodeid_to_nasid(node);
++		if ((klgraph_header = ia64_sn_get_klconfig_addr(nasid)) == NULL)
++			BUG();
++		brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
+ 		while (brd) {
+-			sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
+-			physical_node_map[brd->brd_nasid] = numionodes;
+-			root_lboard[numionodes] = brd;
+-			numionodes++;
+-			brd = KLCF_NEXT_ANY(brd);
+-			if (!brd)
+-				break;
+-
+-			brd = find_lboard_any(brd, KLTYPE_TIO);
++			if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) {
++				sn_cnodeid_to_nasid[num_cnodes] = brd->brd_nasid;
++				physical_node_map[brd->brd_nasid] = num_cnodes++;
++			}
++			brd = find_lboard_next(brd);
+ 		}
+ 	}
+ }
+diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
+--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
++++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
+@@ -177,6 +177,7 @@ void sn_tlb_migrate_finish(struct mm_str
+ 
+ /**
+  * sn2_global_tlb_purge - globally purge translation cache of virtual address range
++ * @mm: mm_struct containing virtual address range
+  * @start: start of virtual address range
+  * @end: end of virtual address range
+  * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
+@@ -188,21 +189,22 @@ void sn_tlb_migrate_finish(struct mm_str
+  * 	- cpu_vm_mask is a bit mask that indicates which cpus have loaded the context.
+  * 	- cpu_vm_mask is converted into a nodemask of the nodes containing the
+  * 	  cpus in cpu_vm_mask.
+- *	- if only one bit is set in cpu_vm_mask & it is the current cpu,
+- *	  then only the local TLB needs to be flushed. This flushing can be done
+- *	  using ptc.l. This is the common case & avoids the global spinlock.
++ *	- if only one bit is set in cpu_vm_mask & it is the current cpu & the
++ *	  process is purging its own virtual address range, then only the
++ *	  local TLB needs to be flushed. This flushing can be done using
++ *	  ptc.l. This is the common case & avoids the global spinlock.
+  *	- if multiple cpus have loaded the context, then flushing has to be
+  *	  done with ptc.g/MMRs under protection of the global ptc_lock.
+  */
+ 
+ void
+-sn2_global_tlb_purge(unsigned long start, unsigned long end,
+-		     unsigned long nbits)
++sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
++		     unsigned long end, unsigned long nbits)
+ {
+ 	int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
++	int mymm = (mm == current->active_mm);
+ 	volatile unsigned long *ptc0, *ptc1;
+-	unsigned long itc, itc2, flags, data0 = 0, data1 = 0;
+-	struct mm_struct *mm = current->active_mm;
++	unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value;
+ 	short nasids[MAX_NUMNODES], nix;
+ 	nodemask_t nodes_flushed;
+ 
+@@ -216,9 +218,12 @@ sn2_global_tlb_purge(unsigned long start
+ 		i++;
+ 	}
+ 
++	if (i == 0)
++		return;
++
+ 	preempt_disable();
+ 
+-	if (likely(i == 1 && lcpu == smp_processor_id())) {
++	if (likely(i == 1 && lcpu == smp_processor_id() && mymm)) {
+ 		do {
+ 			ia64_ptcl(start, nbits << 2);
+ 			start += (1UL << nbits);
+@@ -229,7 +234,7 @@ sn2_global_tlb_purge(unsigned long start
+ 		return;
+ 	}
+ 
+-	if (atomic_read(&mm->mm_users) == 1) {
++	if (atomic_read(&mm->mm_users) == 1 && mymm) {
+ 		flush_tlb_mm(mm);
+ 		__get_cpu_var(ptcstats).change_rid++;
+ 		preempt_enable();
+@@ -241,11 +246,13 @@ sn2_global_tlb_purge(unsigned long start
+ 	for_each_node_mask(cnode, nodes_flushed)
+ 		nasids[nix++] = cnodeid_to_nasid(cnode);
+ 
++	rr_value = (mm->context << 3) | REGION_NUMBER(start);
++
+ 	shub1 = is_shub1();
+ 	if (shub1) {
+ 		data0 = (1UL << SH1_PTC_0_A_SHFT) |
+ 		    	(nbits << SH1_PTC_0_PS_SHFT) |
+-		    	((ia64_get_rr(start) >> 8) << SH1_PTC_0_RID_SHFT) |
++			(rr_value << SH1_PTC_0_RID_SHFT) |
+ 		    	(1UL << SH1_PTC_0_START_SHFT);
+ 		ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0);
+ 		ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1);
+@@ -254,7 +261,7 @@ sn2_global_tlb_purge(unsigned long start
+ 			(nbits << SH2_PTC_PS_SHFT) |
+ 		    	(1UL << SH2_PTC_START_SHFT);
+ 		ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH2_PTC + 
+-			((ia64_get_rr(start) >> 8) << SH2_PTC_RID_SHFT) );
++			(rr_value << SH2_PTC_RID_SHFT));
+ 		ptc1 = NULL;
+ 	}
+ 	
+@@ -275,7 +282,7 @@ sn2_global_tlb_purge(unsigned long start
+ 			data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK);
+ 		for (i = 0; i < nix; i++) {
+ 			nasid = nasids[i];
+-			if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid)) {
++			if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid && mymm)) {
+ 				ia64_ptcga(start, nbits << 2);
+ 				ia64_srlz_i();
+ 			} else {
+diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
++++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+@@ -476,8 +476,8 @@ static int sn_topology_show(struct seq_f
+ 				for_each_online_cpu(j) {
+ 					seq_printf(s, j ? ":%d" : ", dist %d",
+ 						node_distance(
+-						    cpuid_to_cnodeid(i),
+-						    cpuid_to_cnodeid(j)));
++						    cpu_to_node(i),
++						    cpu_to_node(j)));
+ 				}
+ 				seq_putc(s, '\n');
+ 			}
+diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
+--- a/arch/ia64/sn/kernel/tiocx.c
++++ b/arch/ia64/sn/kernel/tiocx.c
+@@ -183,11 +183,12 @@ int cx_driver_unregister(struct cx_drv *
+  * @part_num: device's part number
+  * @mfg_num: device's manufacturer number
+  * @hubdev: hub info associated with this device
++ * @bt: board type of the device
+  *
+  */
+ int
+ cx_device_register(nasid_t nasid, int part_num, int mfg_num,
+-		   struct hubdev_info *hubdev)
++		   struct hubdev_info *hubdev, int bt)
+ {
+ 	struct cx_dev *cx_dev;
+ 
+@@ -200,6 +201,7 @@ cx_device_register(nasid_t nasid, int pa
+ 	cx_dev->cx_id.mfg_num = mfg_num;
+ 	cx_dev->cx_id.nasid = nasid;
+ 	cx_dev->hubdev = hubdev;
++	cx_dev->bt = bt;
+ 
+ 	cx_dev->dev.parent = NULL;
+ 	cx_dev->dev.bus = &tiocx_bus_type;
+@@ -238,7 +240,8 @@ static int cx_device_reload(struct cx_de
+ {
+ 	cx_device_unregister(cx_dev);
+ 	return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num,
+-				  cx_dev->cx_id.mfg_num, cx_dev->hubdev);
++				  cx_dev->cx_id.mfg_num, cx_dev->hubdev,
++				  cx_dev->bt);
+ }
+ 
+ static inline uint64_t tiocx_intr_alloc(nasid_t nasid, int widget,
+@@ -365,26 +368,20 @@ static void tio_corelet_reset(nasid_t na
+ 	udelay(2000);
+ }
+ 
+-static int tiocx_btchar_get(int nasid)
++static int is_fpga_tio(int nasid, int *bt)
+ {
+-	moduleid_t module_id;
+-	geoid_t geoid;
+-	int cnodeid;
++	int ioboard_type;
+ 
+-	cnodeid = nasid_to_cnodeid(nasid);
+-	geoid = cnodeid_get_geoid(cnodeid);
+-	module_id = geo_module(geoid);
+-	return MODULE_GET_BTCHAR(module_id);
+-}
++	ioboard_type = ia64_sn_sysctl_ioboard_get(nasid);
+ 
+-static int is_fpga_brick(int nasid)
+-{
+-	switch (tiocx_btchar_get(nasid)) {
++	switch (ioboard_type) {
+ 	case L1_BRICKTYPE_SA:
+ 	case L1_BRICKTYPE_ATHENA:
+-	case L1_BRICKTYPE_DAYTONA:
++	case L1_BOARDTYPE_DAYTONA:
++		*bt = ioboard_type;
+ 		return 1;
+ 	}
++
+ 	return 0;
+ }
+ 
+@@ -407,16 +404,22 @@ static int tiocx_reload(struct cx_dev *c
+ 
+ 	if (bitstream_loaded(nasid)) {
+ 		uint64_t cx_id;
++		int rv;
+ 
+-		cx_id =
+-		    *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
++		rv = ia64_sn_sysctl_tio_clock_reset(nasid);
++		if (rv) {
++			printk(KERN_ALERT "CX port JTAG reset failed.\n");
++		} else {
++			cx_id = *(volatile uint64_t *)
++				(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
+ 					  WIDGET_ID);
+-		part_num = XWIDGET_PART_NUM(cx_id);
+-		mfg_num = XWIDGET_MFG_NUM(cx_id);
+-		DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num);
+-		/* just ignore it if it's a CE */
+-		if (part_num == TIO_CE_ASIC_PARTNUM)
+-			return 0;
++			part_num = XWIDGET_PART_NUM(cx_id);
++			mfg_num = XWIDGET_MFG_NUM(cx_id);
++			DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num);
++			/* just ignore it if it's a CE */
++			if (part_num == TIO_CE_ASIC_PARTNUM)
++				return 0;
++		}
+ 	}
+ 
+ 	cx_dev->cx_id.part_num = part_num;
+@@ -436,10 +439,10 @@ static ssize_t show_cxdev_control(struct
+ {
+ 	struct cx_dev *cx_dev = to_cx_dev(dev);
+ 
+-	return sprintf(buf, "0x%x 0x%x 0x%x %d\n",
++	return sprintf(buf, "0x%x 0x%x 0x%x 0x%x\n",
+ 		       cx_dev->cx_id.nasid,
+ 		       cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num,
+-		       tiocx_btchar_get(cx_dev->cx_id.nasid));
++		       cx_dev->bt);
+ }
+ 
+ static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf,
+@@ -486,13 +489,13 @@ static int __init tiocx_init(void)
+ 
+ 	bus_register(&tiocx_bus_type);
+ 
+-	for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) {
++	for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) {
+ 		nasid_t nasid;
++		int bt;
+ 
+-		if ((nasid = cnodeid_to_nasid(cnodeid)) < 0)
+-			break;	/* No more nasids .. bail out of loop */
++		nasid = cnodeid_to_nasid(cnodeid);
+ 
+-		if ((nasid & 0x1) && is_fpga_brick(nasid)) {
++		if ((nasid & 0x1) && is_fpga_tio(nasid, &bt)) {
+ 			struct hubdev_info *hubdev;
+ 			struct xwidget_info *widgetp;
+ 
+@@ -512,7 +515,7 @@ static int __init tiocx_init(void)
+ 
+ 			if (cx_device_register
+ 			    (nasid, widgetp->xwi_hwid.part_num,
+-			     widgetp->xwi_hwid.mfg_num, hubdev) < 0)
++			     widgetp->xwi_hwid.mfg_num, hubdev, bt) < 0)
+ 				return -ENXIO;
+ 			else
+ 				found_tiocx_device++;
+diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
+--- a/arch/ia64/sn/kernel/xpc.h
++++ b/arch/ia64/sn/kernel/xpc.h
+@@ -57,7 +57,7 @@
+ #define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2)
+ 
+ #define XPC_HB_DEFAULT_INTERVAL		5	/* incr HB every x secs */
+-#define XPC_HB_CHECK_DEFAULT_TIMEOUT	20	/* check HB every x secs */
++#define XPC_HB_CHECK_DEFAULT_INTERVAL	20	/* check HB every x secs */
+ 
+ /* define the process name of HB checker and the CPU it is pinned to */
+ #define XPC_HB_CHECK_THREAD_NAME	"xpc_hb"
+@@ -67,34 +67,82 @@
+ #define XPC_DISCOVERY_THREAD_NAME	"xpc_discovery"
+ 
+ 
+-#define XPC_HB_ALLOWED(_p, _v)	((_v)->heartbeating_to_mask & (1UL << (_p)))
+-#define XPC_ALLOW_HB(_p, _v)	(_v)->heartbeating_to_mask |= (1UL << (_p))
+-#define XPC_DISALLOW_HB(_p, _v)	(_v)->heartbeating_to_mask &= (~(1UL << (_p)))
+-
+-
+ /*
+- * Reserved Page provided by SAL.
++ * the reserved page
+  *
+- * SAL provides one page per partition of reserved memory.  When SAL
+- * initialization is complete, SAL_signature, SAL_version, partid,
+- * part_nasids, and mach_nasids are set.
++ *   SAL reserves one page of memory per partition for XPC. Though a full page
++ *   in length (16384 bytes), its starting address is not page aligned, but it
++ *   is cacheline aligned. The reserved page consists of the following:
++ *
++ *   reserved page header
++ *
++ *     The first cacheline of the reserved page contains the header
++ *     (struct xpc_rsvd_page). Before SAL initialization has completed,
++ *     SAL has set up the following fields of the reserved page header:
++ *     SAL_signature, SAL_version, partid, and nasids_size. The other
++ *     fields are set up by XPC. (xpc_rsvd_page points to the local
++ *     partition's reserved page.)
++ *
++ *   part_nasids mask
++ *   mach_nasids mask
++ *
++ *     SAL also sets up two bitmaps (or masks), one that reflects the actual
++ *     nasids in this partition (part_nasids), and the other that reflects
++ *     the actual nasids in the entire machine (mach_nasids). We're only
++ *     interested in the even numbered nasids (which contain the processors
++ *     and/or memory), so we only need half as many bits to represent the
++ *     nasids. The part_nasids mask is located starting at the first cacheline
++ *     following the reserved page header. The mach_nasids mask follows right
++ *     after the part_nasids mask. The size in bytes of each mask is reflected
++ *     by the reserved page header field 'nasids_size'. (Local partition's
++ *     mask pointers are xpc_part_nasids and xpc_mach_nasids.)
++ *
++ *   vars
++ *   vars part
++ *
++ *     Immediately following the mach_nasids mask are the XPC variables
++ *     required by other partitions. First are those that are generic to all
++ *     partitions (vars), followed on the next available cacheline by those
++ *     which are partition specific (vars part). These are setup by XPC.
++ *     (Local partition's vars pointers are xpc_vars and xpc_vars_part.)
+  *
+  * Note: Until vars_pa is set, the partition XPC code has not been initialized.
+  */
+ struct xpc_rsvd_page {
+-	u64 SAL_signature;	/* SAL unique signature */
+-	u64 SAL_version;	/* SAL specified version */
+-	u8 partid;		/* partition ID from SAL */
++	u64 SAL_signature;	/* SAL: unique signature */
++	u64 SAL_version;	/* SAL: version */
++	u8 partid;		/* SAL: partition ID */
+ 	u8 version;
+-	u8 pad[6];		/* pad to u64 align */
++	u8 pad1[6];		/* align to next u64 in cacheline */
+ 	volatile u64 vars_pa;
+-	u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
+-	u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
++	struct timespec stamp;	/* time when reserved page was setup by XPC */
++	u64 pad2[9];		/* align to last u64 in cacheline */
++	u64 nasids_size;	/* SAL: size of each nasid mask in bytes */
+ };
+-#define XPC_RP_VERSION _XPC_VERSION(1,0) /* version 1.0 of the reserved page */
+ 
+-#define XPC_RSVD_PAGE_ALIGNED_SIZE \
+-			(L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page)))
++#define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */
++
++#define XPC_SUPPORTS_RP_STAMP(_version) \
++			(_version >= _XPC_VERSION(1,1))
++
++/*
++ * compare stamps - the return value is:
++ *
++ *	< 0,	if stamp1 < stamp2
++ *	= 0,	if stamp1 == stamp2
++ *	> 0,	if stamp1 > stamp2
++ */
++static inline int
++xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2)
++{
++	int ret;
++
++
++	if ((ret = stamp1->tv_sec - stamp2->tv_sec) == 0) {
++		ret = stamp1->tv_nsec - stamp2->tv_nsec;
++	}
++	return ret;
++}
+ 
+ 
+ /*
+@@ -121,11 +169,58 @@ struct xpc_vars {
+ 	u64 vars_part_pa;
+ 	u64 amos_page_pa;	/* paddr of page of AMOs from MSPEC driver */
+ 	AMO_t *amos_page;	/* vaddr of page of AMOs from MSPEC driver */
+-	AMO_t *act_amos;	/* pointer to the first activation AMO */
+ };
+-#define XPC_V_VERSION _XPC_VERSION(3,0) /* version 3.0 of the cross vars */
+ 
+-#define XPC_VARS_ALIGNED_SIZE  (L1_CACHE_ALIGN(sizeof(struct xpc_vars)))
++#define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */
++
++#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \
++			(_version >= _XPC_VERSION(3,1))
++
++
++static inline int
++xpc_hb_allowed(partid_t partid, struct xpc_vars *vars)
++{
++	return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
++}
++
++static inline void
++xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
++{
++	u64 old_mask, new_mask;
++
++	do {
++		old_mask = vars->heartbeating_to_mask;
++		new_mask = (old_mask | (1UL << partid));
++	} while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
++							old_mask);
++}
++
++static inline void
++xpc_disallow_hb(partid_t partid, struct xpc_vars *vars)
++{
++	u64 old_mask, new_mask;
++
++	do {
++		old_mask = vars->heartbeating_to_mask;
++		new_mask = (old_mask & ~(1UL << partid));
++	} while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
++							old_mask);
++}
++
++
++/*
++ * The AMOs page consists of a number of AMO variables which are divided into
++ * four groups, The first two groups are used to identify an IRQ's sender.
++ * These two groups consist of 64 and 128 AMO variables respectively. The last
++ * two groups, consisting of just one AMO variable each, are used to identify
++ * the remote partitions that are currently engaged (from the viewpoint of
++ * the XPC running on the remote partition).
++ */
++#define XPC_NOTIFY_IRQ_AMOS	   0
++#define XPC_ACTIVATE_IRQ_AMOS	   (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS)
++#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)
++#define XPC_DISENGAGE_REQUEST_AMO  (XPC_ENGAGED_PARTITIONS_AMO + 1)
++
+ 
+ /*
+  * The following structure describes the per partition specific variables.
+@@ -165,6 +260,16 @@ struct xpc_vars_part {
+ #define XPC_VP_MAGIC2	0x0073726176435058L  /* 'XPCvars\0'L (little endian) */
+ 
+ 
++/* the reserved page sizes and offsets */
++
++#define XPC_RP_HEADER_SIZE	L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
++#define XPC_RP_VARS_SIZE 	L1_CACHE_ALIGN(sizeof(struct xpc_vars))
++
++#define XPC_RP_PART_NASIDS(_rp) (u64 *) ((u8 *) _rp + XPC_RP_HEADER_SIZE)
++#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words)
++#define XPC_RP_VARS(_rp)	((struct xpc_vars *) XPC_RP_MACH_NASIDS(_rp) + xp_nasid_mask_words)
++#define XPC_RP_VARS_PART(_rp)	(struct xpc_vars_part *) ((u8 *) XPC_RP_VARS(rp) + XPC_RP_VARS_SIZE)
++
+ 
+ /*
+  * Functions registered by add_timer() or called by kernel_thread() only
+@@ -349,6 +454,9 @@ struct xpc_channel {
+ 	atomic_t n_on_msg_allocate_wq;   /* #on msg allocation wait queue */
+ 	wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */
+ 
++	u8 delayed_IPI_flags;		/* IPI flags received, but delayed */
++					/* action until channel disconnected */
++
+ 	/* queue of msg senders who want to be notified when msg received */
+ 
+ 	atomic_t n_to_notify;		/* #of msg senders to notify */
+@@ -358,7 +466,7 @@ struct xpc_channel {
+ 	void *key;			/* pointer to user's key */
+ 
+ 	struct semaphore msg_to_pull_sema; /* next msg to pull serialization */
+-	struct semaphore teardown_sema;    /* wait for teardown completion */
++	struct semaphore wdisconnect_sema; /* wait for channel disconnect */
+ 
+ 	struct xpc_openclose_args *local_openclose_args; /* args passed on */
+ 					/* opening or closing of channel */
+@@ -410,6 +518,8 @@ struct xpc_channel {
+ 
+ #define	XPC_C_DISCONNECTED	0x00002000 /* channel is disconnected */
+ #define	XPC_C_DISCONNECTING	0x00004000 /* channel is being disconnected */
++#define	XPC_C_DISCONNECTCALLOUT	0x00008000 /* chan disconnected callout made */
++#define	XPC_C_WDISCONNECT	0x00010000 /* waiting for channel disconnect */
+ 
+ 
+ 
+@@ -422,6 +532,8 @@ struct xpc_partition {
+ 
+ 	/* XPC HB infrastructure */
+ 
++	u8 remote_rp_version;		/* version# of partition's rsvd pg */
++	struct timespec remote_rp_stamp;/* time when rsvd pg was initialized */
+ 	u64 remote_rp_pa;		/* phys addr of partition's rsvd pg */
+ 	u64 remote_vars_pa;		/* phys addr of partition's vars */
+ 	u64 remote_vars_part_pa;	/* phys addr of partition's vars part */
+@@ -432,14 +544,18 @@ struct xpc_partition {
+ 	u32 act_IRQ_rcvd;		/* IRQs since activation */
+ 	spinlock_t act_lock;		/* protect updating of act_state */
+ 	u8 act_state;			/* from XPC HB viewpoint */
++	u8 remote_vars_version;		/* version# of partition's vars */
+ 	enum xpc_retval reason;		/* reason partition is deactivating */
+ 	int reason_line;		/* line# deactivation initiated from */
+ 	int reactivate_nasid;		/* nasid in partition to reactivate */
+ 
++	unsigned long disengage_request_timeout; /* timeout in jiffies */
++	struct timer_list disengage_request_timer;
++
+ 
+ 	/* XPC infrastructure referencing and teardown control */
+ 
+-	volatile u8 setup_state;			/* infrastructure setup state */
++	volatile u8 setup_state;	/* infrastructure setup state */
+ 	wait_queue_head_t teardown_wq;	/* kthread waiting to teardown infra */
+ 	atomic_t references;		/* #of references to infrastructure */
+ 
+@@ -454,6 +570,7 @@ struct xpc_partition {
+ 
+ 	u8 nchannels;		   /* #of defined channels supported */
+ 	atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */
++	atomic_t nchannels_engaged;/* #of channels engaged with remote part */
+ 	struct xpc_channel *channels;/* array of channel structures */
+ 
+ 	void *local_GPs_base;	  /* base address of kmalloc'd space */
+@@ -518,6 +635,7 @@ struct xpc_partition {
+ #define XPC_P_TORNDOWN		0x03	/* infrastructure is torndown */
+ 
+ 
++
+ /*
+  * struct xpc_partition IPI_timer #of seconds to wait before checking for
+  * dropped IPIs. These occur whenever an IPI amo write doesn't complete until
+@@ -526,6 +644,13 @@ struct xpc_partition {
+ #define XPC_P_DROPPED_IPI_WAIT	(0.25 * HZ)
+ 
+ 
++/* number of seconds to wait for other partitions to disengage */
++#define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT	90
++
++/* interval in seconds to print 'waiting disengagement' messages */
++#define XPC_DISENGAGE_PRINTMSG_INTERVAL		10
++
++
+ #define XPC_PARTID(_p)	((partid_t) ((_p) - &xpc_partitions[0]))
+ 
+ 
+@@ -534,24 +659,20 @@ struct xpc_partition {
+ extern struct xpc_registration xpc_registrations[];
+ 
+ 
+-/* >>> found in xpc_main.c only */
++/* found in xpc_main.c */
+ extern struct device *xpc_part;
+ extern struct device *xpc_chan;
++extern int xpc_disengage_request_timelimit;
+ extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *);
+ extern void xpc_dropped_IPI_check(struct xpc_partition *);
++extern void xpc_activate_partition(struct xpc_partition *);
+ extern void xpc_activate_kthreads(struct xpc_channel *, int);
+ extern void xpc_create_kthreads(struct xpc_channel *, int);
+ extern void xpc_disconnect_wait(int);
+ 
+ 
+-/* found in xpc_main.c and efi-xpc.c */
+-extern void xpc_activate_partition(struct xpc_partition *);
+-
+-
+ /* found in xpc_partition.c */
+ extern int xpc_exiting;
+-extern int xpc_hb_interval;
+-extern int xpc_hb_check_interval;
+ extern struct xpc_vars *xpc_vars;
+ extern struct xpc_rsvd_page *xpc_rsvd_page;
+ extern struct xpc_vars_part *xpc_vars_part;
+@@ -561,6 +682,7 @@ extern struct xpc_rsvd_page *xpc_rsvd_pa
+ extern void xpc_allow_IPI_ops(void);
+ extern void xpc_restrict_IPI_ops(void);
+ extern int xpc_identify_act_IRQ_sender(void);
++extern int xpc_partition_disengaged(struct xpc_partition *);
+ extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *);
+ extern void xpc_mark_partition_inactive(struct xpc_partition *);
+ extern void xpc_discovery(void);
+@@ -585,8 +707,8 @@ extern void xpc_connected_callout(struct
+ extern void xpc_deliver_msg(struct xpc_channel *);
+ extern void xpc_disconnect_channel(const int, struct xpc_channel *,
+ 					enum xpc_retval, unsigned long *);
+-extern void xpc_disconnected_callout(struct xpc_channel *);
+-extern void xpc_partition_down(struct xpc_partition *, enum xpc_retval);
++extern void xpc_disconnecting_callout(struct xpc_channel *);
++extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
+ extern void xpc_teardown_infrastructure(struct xpc_partition *);
+ 
+ 
+@@ -674,6 +796,157 @@ xpc_part_ref(struct xpc_partition *part)
+ 
+ 
+ /*
++ * This next set of inlines are used to keep track of when a partition is
++ * potentially engaged in accessing memory belonging to another partition.
++ */
++
++static inline void
++xpc_mark_partition_engaged(struct xpc_partition *part)
++{
++	unsigned long irq_flags;
++	AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
++				(XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t)));
++
++
++	local_irq_save(irq_flags);
++
++	/* set bit corresponding to our partid in remote partition's AMO */
++	FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR,
++						(1UL << sn_partition_id));
++	/*
++	 * We must always use the nofault function regardless of whether we
++	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
++	 * didn't, we'd never know that the other partition is down and would
++	 * keep sending IPIs and AMOs to it until the heartbeat times out.
++	 */
++	(void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
++				variable), xp_nofault_PIOR_target));
++
++	local_irq_restore(irq_flags);
++}
++
++static inline void
++xpc_mark_partition_disengaged(struct xpc_partition *part)
++{
++	unsigned long irq_flags;
++	AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
++				(XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t)));
++
++
++	local_irq_save(irq_flags);
++
++	/* clear bit corresponding to our partid in remote partition's AMO */
++	FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
++						~(1UL << sn_partition_id));
++	/*
++	 * We must always use the nofault function regardless of whether we
++	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
++	 * didn't, we'd never know that the other partition is down and would
++	 * keep sending IPIs and AMOs to it until the heartbeat times out.
++	 */
++	(void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
++				variable), xp_nofault_PIOR_target));
++
++	local_irq_restore(irq_flags);
++}
++
++static inline void
++xpc_request_partition_disengage(struct xpc_partition *part)
++{
++	unsigned long irq_flags;
++	AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
++				(XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
++
++
++	local_irq_save(irq_flags);
++
++	/* set bit corresponding to our partid in remote partition's AMO */
++	FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR,
++						(1UL << sn_partition_id));
++	/*
++	 * We must always use the nofault function regardless of whether we
++	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
++	 * didn't, we'd never know that the other partition is down and would
++	 * keep sending IPIs and AMOs to it until the heartbeat times out.
++	 */
++	(void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
++				variable), xp_nofault_PIOR_target));
++
++	local_irq_restore(irq_flags);
++}
++
++static inline void
++xpc_cancel_partition_disengage_request(struct xpc_partition *part)
++{
++	unsigned long irq_flags;
++	AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
++				(XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
++
++
++	local_irq_save(irq_flags);
++
++	/* clear bit corresponding to our partid in remote partition's AMO */
++	FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
++						~(1UL << sn_partition_id));
++	/*
++	 * We must always use the nofault function regardless of whether we
++	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
++	 * didn't, we'd never know that the other partition is down and would
++	 * keep sending IPIs and AMOs to it until the heartbeat times out.
++	 */
++	(void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
++				variable), xp_nofault_PIOR_target));
++
++	local_irq_restore(irq_flags);
++}
++
++static inline u64
++xpc_partition_engaged(u64 partid_mask)
++{
++	AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
++
++
++	/* return our partition's AMO variable ANDed with partid_mask */
++	return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) &
++								partid_mask);
++}
++
++static inline u64
++xpc_partition_disengage_requested(u64 partid_mask)
++{
++	AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
++
++
++	/* return our partition's AMO variable ANDed with partid_mask */
++	return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) &
++								partid_mask);
++}
++
++static inline void
++xpc_clear_partition_engaged(u64 partid_mask)
++{
++	AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
++
++
++	/* clear bit(s) based on partid_mask in our partition's AMO */
++	FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
++								~partid_mask);
++}
++
++static inline void
++xpc_clear_partition_disengage_request(u64 partid_mask)
++{
++	AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
++
++
++	/* clear bit(s) based on partid_mask in our partition's AMO */
++	FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
++								~partid_mask);
++}
++
++
++
++/*
+  * The following set of macros and inlines are used for the sending and
+  * receiving of IPIs (also known as IRQs). There are two flavors of IPIs,
+  * one that is associated with partition activity (SGI_XPC_ACTIVATE) and
+@@ -722,13 +995,13 @@ xpc_IPI_send(AMO_t *amo, u64 flag, int n
+  * Flag the appropriate AMO variable and send an IPI to the specified node.
+  */
+ static inline void
+-xpc_activate_IRQ_send(u64 amos_page, int from_nasid, int to_nasid,
++xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid,
+ 			int to_phys_cpuid)
+ {
+ 	int w_index = XPC_NASID_W_INDEX(from_nasid);
+ 	int b_index = XPC_NASID_B_INDEX(from_nasid);
+-	AMO_t *amos = (AMO_t *) __va(amos_page +
+-					(XP_MAX_PARTITIONS * sizeof(AMO_t)));
++	AMO_t *amos = (AMO_t *) __va(amos_page_pa +
++				(XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t)));
+ 
+ 
+ 	(void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid,
+@@ -756,6 +1029,13 @@ xpc_IPI_send_reactivate(struct xpc_parti
+ 				xpc_vars->act_nasid, xpc_vars->act_phys_cpuid);
+ }
+ 
++static inline void
++xpc_IPI_send_disengage(struct xpc_partition *part)
++{
++	xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
++			part->remote_act_nasid, part->remote_act_phys_cpuid);
++}
++
+ 
+ /*
+  * IPIs associated with SGI_XPC_NOTIFY IRQ.
+@@ -836,6 +1116,7 @@ xpc_notify_IRQ_send_local(struct xpc_cha
+ 
+ /* given an AMO variable and a channel#, get its associated IPI flags */
+ #define XPC_GET_IPI_FLAGS(_amo, _c)	((u8) (((_amo) >> ((_c) * 8)) & 0xff))
++#define XPC_SET_IPI_FLAGS(_amo, _c, _f)	(_amo) |= ((u64) (_f) << ((_c) * 8))
+ 
+ #define	XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f)
+ #define XPC_ANY_MSG_IPI_FLAGS_SET(_amo)       ((_amo) & 0x1010101010101010)
+@@ -903,17 +1184,18 @@ xpc_IPI_send_local_msgrequest(struct xpc
+  * cacheable mapping for the entire region. This will prevent speculative
+  * reading of cached copies of our lines from being issued which will cause
+  * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
+- * (XP_MAX_PARTITIONS) AMO variables for message notification (xpc_main.c)
+- * and an additional 16 AMO variables for partition activation (xpc_hb.c).
++ * AMO variables (based on XP_MAX_PARTITIONS) for message notification and an
++ * additional 128 AMO variables (based on XP_NASID_MASK_WORDS) for partition
++ * activation and 2 AMO variables for partition deactivation.
+  */
+ static inline AMO_t *
+-xpc_IPI_init(partid_t partid)
++xpc_IPI_init(int index)
+ {
+-	AMO_t *part_amo = xpc_vars->amos_page + partid;
++	AMO_t *amo = xpc_vars->amos_page + index;
+ 
+ 
+-	xpc_IPI_receive(part_amo);
+-	return part_amo;
++	(void) xpc_IPI_receive(amo);	/* clear AMO variable */
++	return amo;
+ }
+ 
+ 
+@@ -939,7 +1221,7 @@ xpc_map_bte_errors(bte_result_t error)
+ 
+ 
+ static inline void *
+-xpc_kmalloc_cacheline_aligned(size_t size, int flags, void **base)
++xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
+ {
+ 	/* see if kmalloc will give us cachline aligned memory by default */
+ 	*base = kmalloc(size, flags);
+diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
+--- a/arch/ia64/sn/kernel/xpc_channel.c
++++ b/arch/ia64/sn/kernel/xpc_channel.c
+@@ -57,6 +57,7 @@ xpc_initialize_channels(struct xpc_parti
+ 
+ 		spin_lock_init(&ch->lock);
+ 		sema_init(&ch->msg_to_pull_sema, 1);	/* mutex */
++		sema_init(&ch->wdisconnect_sema, 0);	/* event wait */
+ 
+ 		atomic_set(&ch->n_on_msg_allocate_wq, 0);
+ 		init_waitqueue_head(&ch->msg_allocate_wq);
+@@ -166,6 +167,7 @@ xpc_setup_infrastructure(struct xpc_part
+ 	xpc_initialize_channels(part, partid);
+ 
+ 	atomic_set(&part->nchannels_active, 0);
++	atomic_set(&part->nchannels_engaged, 0);
+ 
+ 
+ 	/* local_IPI_amo were set to 0 by an earlier memset() */
+@@ -555,8 +557,6 @@ xpc_allocate_msgqueues(struct xpc_channe
+ 		sema_init(&ch->notify_queue[i].sema, 0);
+ 	}
+ 
+-	sema_init(&ch->teardown_sema, 0);	/* event wait */
+-
+ 	spin_lock_irqsave(&ch->lock, irq_flags);
+ 	ch->flags |= XPC_C_SETUP;
+ 	spin_unlock_irqrestore(&ch->lock, irq_flags);
+@@ -626,6 +626,55 @@ xpc_process_connect(struct xpc_channel *
+ 
+ 
+ /*
++ * Notify those who wanted to be notified upon delivery of their message.
++ */
++static void
++xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put)
++{
++	struct xpc_notify *notify;
++	u8 notify_type;
++	s64 get = ch->w_remote_GP.get - 1;
++
++
++	while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
++
++		notify = &ch->notify_queue[get % ch->local_nentries];
++
++		/*
++		 * See if the notify entry indicates it was associated with
++		 * a message who's sender wants to be notified. It is possible
++		 * that it is, but someone else is doing or has done the
++		 * notification.
++		 */
++		notify_type = notify->type;
++		if (notify_type == 0 ||
++				cmpxchg(&notify->type, notify_type, 0) !=
++								notify_type) {
++			continue;
++		}
++
++		DBUG_ON(notify_type != XPC_N_CALL);
++
++		atomic_dec(&ch->n_to_notify);
++
++		if (notify->func != NULL) {
++			dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, "
++				"msg_number=%ld, partid=%d, channel=%d\n",
++				(void *) notify, get, ch->partid, ch->number);
++
++			notify->func(reason, ch->partid, ch->number,
++								notify->key);
++
++			dev_dbg(xpc_chan, "notify->func() returned, "
++				"notify=0x%p, msg_number=%ld, partid=%d, "
++				"channel=%d\n", (void *) notify, get,
++				ch->partid, ch->number);
++		}
++	}
++}
++
++
++/*
+  * Free up message queues and other stuff that were allocated for the specified
+  * channel.
+  *
+@@ -669,9 +718,6 @@ xpc_free_msgqueues(struct xpc_channel *c
+ 		ch->remote_msgqueue = NULL;
+ 		kfree(ch->notify_queue);
+ 		ch->notify_queue = NULL;
+-
+-		/* in case someone is waiting for the teardown to complete */
+-		up(&ch->teardown_sema);
+ 	}
+ }
+ 
+@@ -683,7 +729,7 @@ static void
+ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
+ {
+ 	struct xpc_partition *part = &xpc_partitions[ch->partid];
+-	u32 ch_flags = ch->flags;
++	u32 channel_was_connected = (ch->flags & XPC_C_WASCONNECTED);
+ 
+ 
+ 	DBUG_ON(!spin_is_locked(&ch->lock));
+@@ -701,12 +747,13 @@ xpc_process_disconnect(struct xpc_channe
+ 	}
+ 	DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
+ 
+-	/* it's now safe to free the channel's message queues */
+-
+-	xpc_free_msgqueues(ch);
+-	DBUG_ON(ch->flags & XPC_C_SETUP);
++	if (part->act_state == XPC_P_DEACTIVATING) {
++		/* can't proceed until the other side disengages from us */
++		if (xpc_partition_engaged(1UL << ch->partid)) {
++			return;
++		}
+ 
+-	if (part->act_state != XPC_P_DEACTIVATING) {
++	} else {
+ 
+ 		/* as long as the other side is up do the full protocol */
+ 
+@@ -724,16 +771,42 @@ xpc_process_disconnect(struct xpc_channe
+ 		}
+ 	}
+ 
++	/* wake those waiting for notify completion */
++	if (atomic_read(&ch->n_to_notify) > 0) {
++		/* >>> we do callout while holding ch->lock */
++		xpc_notify_senders(ch, ch->reason, ch->w_local_GP.put);
++	}
++
+ 	/* both sides are disconnected now */
+ 
+-	ch->flags = XPC_C_DISCONNECTED;	/* clear all flags, but this one */
++	/* it's now safe to free the channel's message queues */
++	xpc_free_msgqueues(ch);
++
++	/* mark disconnected, clear all other flags except XPC_C_WDISCONNECT */
++	ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT));
+ 
+ 	atomic_dec(&part->nchannels_active);
+ 
+-	if (ch_flags & XPC_C_WASCONNECTED) {
++	if (channel_was_connected) {
+ 		dev_info(xpc_chan, "channel %d to partition %d disconnected, "
+ 			"reason=%d\n", ch->number, ch->partid, ch->reason);
+ 	}
++
++	if (ch->flags & XPC_C_WDISCONNECT) {
++		spin_unlock_irqrestore(&ch->lock, *irq_flags);
++		up(&ch->wdisconnect_sema);
++		spin_lock_irqsave(&ch->lock, *irq_flags);
++
++	} else if (ch->delayed_IPI_flags) {
++		if (part->act_state != XPC_P_DEACTIVATING) {
++			/* time to take action on any delayed IPI flags */
++			spin_lock(&part->IPI_lock);
++			XPC_SET_IPI_FLAGS(part->local_IPI_amo, ch->number,
++							ch->delayed_IPI_flags);
++			spin_unlock(&part->IPI_lock);
++		}
++		ch->delayed_IPI_flags = 0;
++	}
+ }
+ 
+ 
+@@ -754,6 +827,19 @@ xpc_process_openclose_IPI(struct xpc_par
+ 
+ 	spin_lock_irqsave(&ch->lock, irq_flags);
+ 
++again:
++
++	if ((ch->flags & XPC_C_DISCONNECTED) &&
++					(ch->flags & XPC_C_WDISCONNECT)) {
++		/*
++		 * Delay processing IPI flags until thread waiting disconnect
++		 * has had a chance to see that the channel is disconnected.
++		 */
++		ch->delayed_IPI_flags |= IPI_flags;
++		spin_unlock_irqrestore(&ch->lock, irq_flags);
++		return;
++	}
++
+ 
+ 	if (IPI_flags & XPC_IPI_CLOSEREQUEST) {
+ 
+@@ -764,7 +850,7 @@ xpc_process_openclose_IPI(struct xpc_par
+ 		/*
+ 		 * If RCLOSEREQUEST is set, we're probably waiting for
+ 		 * RCLOSEREPLY. We should find it and a ROPENREQUEST packed
+-		 * with this RCLOSEQREUQEST in the IPI_flags.
++		 * with this RCLOSEREQUEST in the IPI_flags.
+ 		 */
+ 
+ 		if (ch->flags & XPC_C_RCLOSEREQUEST) {
+@@ -779,14 +865,22 @@ xpc_process_openclose_IPI(struct xpc_par
+ 
+ 			/* both sides have finished disconnecting */
+ 			xpc_process_disconnect(ch, &irq_flags);
++			DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
++			goto again;
+ 		}
+ 
+ 		if (ch->flags & XPC_C_DISCONNECTED) {
+-			// >>> explain this section
+-
+ 			if (!(IPI_flags & XPC_IPI_OPENREQUEST)) {
+-				DBUG_ON(part->act_state !=
+-							XPC_P_DEACTIVATING);
++				if ((XPC_GET_IPI_FLAGS(part->local_IPI_amo,
++					 ch_number) & XPC_IPI_OPENREQUEST)) {
++
++					DBUG_ON(ch->delayed_IPI_flags != 0);
++					spin_lock(&part->IPI_lock);
++					XPC_SET_IPI_FLAGS(part->local_IPI_amo,
++							ch_number,
++							XPC_IPI_CLOSEREQUEST);
++					spin_unlock(&part->IPI_lock);
++				}
+ 				spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 				return;
+ 			}
+@@ -816,9 +910,13 @@ xpc_process_openclose_IPI(struct xpc_par
+ 			}
+ 
+ 			XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
+-		} else {
+-			xpc_process_disconnect(ch, &irq_flags);
++
++			DBUG_ON(IPI_flags & XPC_IPI_CLOSEREPLY);
++			spin_unlock_irqrestore(&ch->lock, irq_flags);
++			return;
+ 		}
++
++		xpc_process_disconnect(ch, &irq_flags);
+ 	}
+ 
+ 
+@@ -834,7 +932,20 @@ xpc_process_openclose_IPI(struct xpc_par
+ 		}
+ 
+ 		DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
+-		DBUG_ON(!(ch->flags & XPC_C_RCLOSEREQUEST));
++
++		if (!(ch->flags & XPC_C_RCLOSEREQUEST)) {
++			if ((XPC_GET_IPI_FLAGS(part->local_IPI_amo, ch_number)
++						& XPC_IPI_CLOSEREQUEST)) {
++
++				DBUG_ON(ch->delayed_IPI_flags != 0);
++				spin_lock(&part->IPI_lock);
++				XPC_SET_IPI_FLAGS(part->local_IPI_amo,
++						ch_number, XPC_IPI_CLOSEREPLY);
++				spin_unlock(&part->IPI_lock);
++			}
++			spin_unlock_irqrestore(&ch->lock, irq_flags);
++			return;
++		}
+ 
+ 		ch->flags |= XPC_C_RCLOSEREPLY;
+ 
+@@ -852,8 +963,14 @@ xpc_process_openclose_IPI(struct xpc_par
+ 			"channel=%d\n", args->msg_size, args->local_nentries,
+ 			ch->partid, ch->number);
+ 
+-		if ((ch->flags & XPC_C_DISCONNECTING) ||
+-					part->act_state == XPC_P_DEACTIVATING) {
++		if (part->act_state == XPC_P_DEACTIVATING ||
++					(ch->flags & XPC_C_ROPENREQUEST)) {
++			spin_unlock_irqrestore(&ch->lock, irq_flags);
++			return;
++		}
++
++		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) {
++			ch->delayed_IPI_flags |= XPC_IPI_OPENREQUEST;
+ 			spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 			return;
+ 		}
+@@ -867,8 +984,11 @@ xpc_process_openclose_IPI(struct xpc_par
+ 		 *      msg_size = size of channel's messages in bytes
+ 		 *      local_nentries = remote partition's local_nentries
+ 		 */
+-		DBUG_ON(args->msg_size == 0);
+-		DBUG_ON(args->local_nentries == 0);
++		if (args->msg_size == 0 || args->local_nentries == 0) {
++			/* assume OPENREQUEST was delayed by mistake */
++			spin_unlock_irqrestore(&ch->lock, irq_flags);
++			return;
++		}
+ 
+ 		ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING);
+ 		ch->remote_nentries = args->local_nentries;
+@@ -906,7 +1026,13 @@ xpc_process_openclose_IPI(struct xpc_par
+ 			spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 			return;
+ 		}
+-		DBUG_ON(!(ch->flags & XPC_C_OPENREQUEST));
++		if (!(ch->flags & XPC_C_OPENREQUEST)) {
++			XPC_DISCONNECT_CHANNEL(ch, xpcOpenCloseError,
++								&irq_flags);
++			spin_unlock_irqrestore(&ch->lock, irq_flags);
++			return;
++		}
++
+ 		DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
+ 		DBUG_ON(ch->flags & XPC_C_CONNECTED);
+ 
+@@ -960,8 +1086,8 @@ xpc_connect_channel(struct xpc_channel *
+ 	struct xpc_registration *registration = &xpc_registrations[ch->number];
+ 
+ 
+-	if (down_interruptible(&registration->sema) != 0) {
+-		return xpcInterrupted;
++	if (down_trylock(&registration->sema) != 0) {
++		return xpcRetry;
+ 	}
+ 
+ 	if (!XPC_CHANNEL_REGISTERED(ch->number)) {
+@@ -1040,55 +1166,6 @@ xpc_connect_channel(struct xpc_channel *
+ 
+ 
+ /*
+- * Notify those who wanted to be notified upon delivery of their message.
+- */
+-static void
+-xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put)
+-{
+-	struct xpc_notify *notify;
+-	u8 notify_type;
+-	s64 get = ch->w_remote_GP.get - 1;
+-
+-
+-	while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
+-
+-		notify = &ch->notify_queue[get % ch->local_nentries];
+-
+-		/*
+-		 * See if the notify entry indicates it was associated with
+-		 * a message who's sender wants to be notified. It is possible
+-		 * that it is, but someone else is doing or has done the
+-		 * notification.
+-		 */
+-		notify_type = notify->type;
+-		if (notify_type == 0 ||
+-				cmpxchg(&notify->type, notify_type, 0) !=
+-								notify_type) {
+-			continue;
+-		}
+-
+-		DBUG_ON(notify_type != XPC_N_CALL);
+-
+-		atomic_dec(&ch->n_to_notify);
+-
+-		if (notify->func != NULL) {
+-			dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, "
+-				"msg_number=%ld, partid=%d, channel=%d\n",
+-				(void *) notify, get, ch->partid, ch->number);
+-
+-			notify->func(reason, ch->partid, ch->number,
+-								notify->key);
+-
+-			dev_dbg(xpc_chan, "notify->func() returned, "
+-				"notify=0x%p, msg_number=%ld, partid=%d, "
+-				"channel=%d\n", (void *) notify, get,
+-				ch->partid, ch->number);
+-		}
+-	}
+-}
+-
+-
+-/*
+  * Clear some of the msg flags in the local message queue.
+  */
+ static inline void
+@@ -1240,6 +1317,7 @@ xpc_process_channel_activity(struct xpc_
+ 	u64 IPI_amo, IPI_flags;
+ 	struct xpc_channel *ch;
+ 	int ch_number;
++	u32 ch_flags;
+ 
+ 
+ 	IPI_amo = xpc_get_IPI_flags(part);
+@@ -1266,8 +1344,9 @@ xpc_process_channel_activity(struct xpc_
+ 			xpc_process_openclose_IPI(part, ch_number, IPI_flags);
+ 		}
+ 
++		ch_flags = ch->flags;	/* need an atomic snapshot of flags */
+ 
+-		if (ch->flags & XPC_C_DISCONNECTING) {
++		if (ch_flags & XPC_C_DISCONNECTING) {
+ 			spin_lock_irqsave(&ch->lock, irq_flags);
+ 			xpc_process_disconnect(ch, &irq_flags);
+ 			spin_unlock_irqrestore(&ch->lock, irq_flags);
+@@ -1278,9 +1357,9 @@ xpc_process_channel_activity(struct xpc_
+ 			continue;
+ 		}
+ 
+-		if (!(ch->flags & XPC_C_CONNECTED)) {
+-			if (!(ch->flags & XPC_C_OPENREQUEST)) {
+-				DBUG_ON(ch->flags & XPC_C_SETUP);
++		if (!(ch_flags & XPC_C_CONNECTED)) {
++			if (!(ch_flags & XPC_C_OPENREQUEST)) {
++				DBUG_ON(ch_flags & XPC_C_SETUP);
+ 				(void) xpc_connect_channel(ch);
+ 			} else {
+ 				spin_lock_irqsave(&ch->lock, irq_flags);
+@@ -1305,8 +1384,8 @@ xpc_process_channel_activity(struct xpc_
+ 
+ 
+ /*
+- * XPC's heartbeat code calls this function to inform XPC that a partition has
+- * gone down.  XPC responds by tearing down the XPartition Communication
++ * XPC's heartbeat code calls this function to inform XPC that a partition is
++ * going down.  XPC responds by tearing down the XPartition Communication
+  * infrastructure used for the just downed partition.
+  *
+  * XPC's heartbeat code will never call this function and xpc_partition_up()
+@@ -1314,7 +1393,7 @@ xpc_process_channel_activity(struct xpc_
+  * at the same time.
+  */
+ void
+-xpc_partition_down(struct xpc_partition *part, enum xpc_retval reason)
++xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason)
+ {
+ 	unsigned long irq_flags;
+ 	int ch_number;
+@@ -1330,12 +1409,11 @@ xpc_partition_down(struct xpc_partition 
+ 	}
+ 
+ 
+-	/* disconnect all channels associated with the downed partition */
++	/* disconnect channels associated with the partition going down */
+ 
+ 	for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
+ 		ch = &part->channels[ch_number];
+ 
+-
+ 		xpc_msgqueue_ref(ch);
+ 		spin_lock_irqsave(&ch->lock, irq_flags);
+ 
+@@ -1370,6 +1448,7 @@ xpc_teardown_infrastructure(struct xpc_p
+ 	 * this partition.
+ 	 */
+ 
++	DBUG_ON(atomic_read(&part->nchannels_engaged) != 0);
+ 	DBUG_ON(atomic_read(&part->nchannels_active) != 0);
+ 	DBUG_ON(part->setup_state != XPC_P_SETUP);
+ 	part->setup_state = XPC_P_WTEARDOWN;
+@@ -1428,19 +1507,11 @@ xpc_initiate_connect(int ch_number)
+ 		if (xpc_part_ref(part)) {
+ 			ch = &part->channels[ch_number];
+ 
+-			if (!(ch->flags & XPC_C_DISCONNECTING)) {
+-				DBUG_ON(ch->flags & XPC_C_OPENREQUEST);
+-				DBUG_ON(ch->flags & XPC_C_CONNECTED);
+-				DBUG_ON(ch->flags & XPC_C_SETUP);
+-
+-				/*
+-				 * Initiate the establishment of a connection
+-				 * on the newly registered channel to the
+-				 * remote partition.
+-				 */
+-				xpc_wakeup_channel_mgr(part);
+-			}
+-
++			/*
++			 * Initiate the establishment of a connection on the
++			 * newly registered channel to the remote partition.
++			 */
++			xpc_wakeup_channel_mgr(part);
+ 			xpc_part_deref(part);
+ 		}
+ 	}
+@@ -1450,9 +1521,6 @@ xpc_initiate_connect(int ch_number)
+ void
+ xpc_connected_callout(struct xpc_channel *ch)
+ {
+-	unsigned long irq_flags;
+-
+-
+ 	/* let the registerer know that a connection has been established */
+ 
+ 	if (ch->func != NULL) {
+@@ -1465,10 +1533,6 @@ xpc_connected_callout(struct xpc_channel
+ 		dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, "
+ 			"partid=%d, channel=%d\n", ch->partid, ch->number);
+ 	}
+-
+-	spin_lock_irqsave(&ch->lock, irq_flags);
+-	ch->flags |= XPC_C_CONNECTCALLOUT;
+-	spin_unlock_irqrestore(&ch->lock, irq_flags);
+ }
+ 
+ 
+@@ -1506,8 +1570,12 @@ xpc_initiate_disconnect(int ch_number)
+ 
+ 			spin_lock_irqsave(&ch->lock, irq_flags);
+ 
+-			XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering,
++			if (!(ch->flags & XPC_C_DISCONNECTED)) {
++				ch->flags |= XPC_C_WDISCONNECT;
++
++				XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering,
+ 								&irq_flags);
++			}
+ 
+ 			spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 
+@@ -1523,8 +1591,9 @@ xpc_initiate_disconnect(int ch_number)
+ /*
+  * To disconnect a channel, and reflect it back to all who may be waiting.
+  *
+- * >>> An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by
+- * >>> xpc_free_msgqueues().
++ * An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by
++ * xpc_process_disconnect(), and if set, XPC_C_WDISCONNECT is cleared by
++ * xpc_disconnect_wait().
+  *
+  * THE CHANNEL IS TO BE LOCKED BY THE CALLER AND WILL REMAIN LOCKED UPON RETURN.
+  */
+@@ -1532,7 +1601,7 @@ void
+ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
+ 			enum xpc_retval reason, unsigned long *irq_flags)
+ {
+-	u32 flags;
++	u32 channel_was_connected = (ch->flags & XPC_C_CONNECTED);
+ 
+ 
+ 	DBUG_ON(!spin_is_locked(&ch->lock));
+@@ -1547,61 +1616,53 @@ xpc_disconnect_channel(const int line, s
+ 
+ 	XPC_SET_REASON(ch, reason, line);
+ 
+-	flags = ch->flags;
++	ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING);
+ 	/* some of these may not have been set */
+ 	ch->flags &= ~(XPC_C_OPENREQUEST | XPC_C_OPENREPLY |
+ 			XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
+ 			XPC_C_CONNECTING | XPC_C_CONNECTED);
+ 
+-	ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING);
+ 	xpc_IPI_send_closerequest(ch, irq_flags);
+ 
+-	if (flags & XPC_C_CONNECTED) {
++	if (channel_was_connected) {
+ 		ch->flags |= XPC_C_WASCONNECTED;
+ 	}
+ 
++	spin_unlock_irqrestore(&ch->lock, *irq_flags);
++
++	/* wake all idle kthreads so they can exit */
+ 	if (atomic_read(&ch->kthreads_idle) > 0) {
+-		/* wake all idle kthreads so they can exit */
+ 		wake_up_all(&ch->idle_wq);
+ 	}
+ 
+-	spin_unlock_irqrestore(&ch->lock, *irq_flags);
+-
+-
+ 	/* wake those waiting to allocate an entry from the local msg queue */
+-
+ 	if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) {
+ 		wake_up(&ch->msg_allocate_wq);
+ 	}
+ 
+-	/* wake those waiting for notify completion */
+-
+-	if (atomic_read(&ch->n_to_notify) > 0) {
+-		xpc_notify_senders(ch, reason, ch->w_local_GP.put);
+-	}
+-
+ 	spin_lock_irqsave(&ch->lock, *irq_flags);
+ }
+ 
+ 
+ void
+-xpc_disconnected_callout(struct xpc_channel *ch)
++xpc_disconnecting_callout(struct xpc_channel *ch)
+ {
+ 	/*
+-	 * Let the channel's registerer know that the channel is now
++	 * Let the channel's registerer know that the channel is being
+ 	 * disconnected. We don't want to do this if the registerer was never
+-	 * informed of a connection being made, unless the disconnect was for
+-	 * abnormal reasons.
++	 * informed of a connection being made.
+ 	 */
+ 
+ 	if (ch->func != NULL) {
+-		dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, "
+-			"channel=%d\n", ch->reason, ch->partid, ch->number);
++		dev_dbg(xpc_chan, "ch->func() called, reason=xpcDisconnecting,"
++			" partid=%d, channel=%d\n", ch->partid, ch->number);
+ 
+-		ch->func(ch->reason, ch->partid, ch->number, NULL, ch->key);
++		ch->func(xpcDisconnecting, ch->partid, ch->number, NULL,
++								ch->key);
+ 
+-		dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, "
+-			"channel=%d\n", ch->reason, ch->partid, ch->number);
++		dev_dbg(xpc_chan, "ch->func() returned, reason="
++			"xpcDisconnecting, partid=%d, channel=%d\n",
++			ch->partid, ch->number);
+ 	}
+ }
+ 
+@@ -1848,7 +1909,7 @@ xpc_send_msg(struct xpc_channel *ch, str
+ 			xpc_notify_func func, void *key)
+ {
+ 	enum xpc_retval ret = xpcSuccess;
+-	struct xpc_notify *notify = NULL;   // >>> to keep the compiler happy!!
++	struct xpc_notify *notify = notify;
+ 	s64 put, msg_number = msg->number;
+ 
+ 
+diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
+--- a/arch/ia64/sn/kernel/xpc_main.c
++++ b/arch/ia64/sn/kernel/xpc_main.c
+@@ -54,6 +54,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/slab.h>
+ #include <linux/delay.h>
++#include <linux/reboot.h>
+ #include <asm/sn/intr.h>
+ #include <asm/sn/sn_sal.h>
+ #include <asm/uaccess.h>
+@@ -82,11 +83,17 @@ struct device *xpc_chan = &xpc_chan_dbg_
+ 
+ /* systune related variables for /proc/sys directories */
+ 
+-static int xpc_hb_min = 1;
+-static int xpc_hb_max = 10;
+-
+-static int xpc_hb_check_min = 10;
+-static int xpc_hb_check_max = 120;
++static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
++static int xpc_hb_min_interval = 1;
++static int xpc_hb_max_interval = 10;
++
++static int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_INTERVAL;
++static int xpc_hb_check_min_interval = 10;
++static int xpc_hb_check_max_interval = 120;
++
++int xpc_disengage_request_timelimit = XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT;
++static int xpc_disengage_request_min_timelimit = 0;
++static int xpc_disengage_request_max_timelimit = 120;
+ 
+ static ctl_table xpc_sys_xpc_hb_dir[] = {
+ 	{
+@@ -99,7 +106,8 @@ static ctl_table xpc_sys_xpc_hb_dir[] = 
+ 		&proc_dointvec_minmax,
+ 		&sysctl_intvec,
+ 		NULL,
+-		&xpc_hb_min, &xpc_hb_max
++		&xpc_hb_min_interval,
++		&xpc_hb_max_interval
+ 	},
+ 	{
+ 		2,
+@@ -111,7 +119,8 @@ static ctl_table xpc_sys_xpc_hb_dir[] = 
+ 		&proc_dointvec_minmax,
+ 		&sysctl_intvec,
+ 		NULL,
+-		&xpc_hb_check_min, &xpc_hb_check_max
++		&xpc_hb_check_min_interval,
++		&xpc_hb_check_max_interval
+ 	},
+ 	{0}
+ };
+@@ -124,6 +133,19 @@ static ctl_table xpc_sys_xpc_dir[] = {
+ 		0555,
+ 		xpc_sys_xpc_hb_dir
+ 	},
++	{
++		2,
++		"disengage_request_timelimit",
++		&xpc_disengage_request_timelimit,
++		sizeof(int),
++		0644,
++		NULL,
++		&proc_dointvec_minmax,
++		&sysctl_intvec,
++		NULL,
++		&xpc_disengage_request_min_timelimit,
++		&xpc_disengage_request_max_timelimit
++	},
+ 	{0}
+ };
+ static ctl_table xpc_sys_dir[] = {
+@@ -148,10 +170,10 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_I
+ 
+ static unsigned long xpc_hb_check_timeout;
+ 
+-/* xpc_hb_checker thread exited notification */
++/* notification that the xpc_hb_checker thread has exited */
+ static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited);
+ 
+-/* xpc_discovery thread exited notification */
++/* notification that the xpc_discovery thread has exited */
+ static DECLARE_MUTEX_LOCKED(xpc_discovery_exited);
+ 
+ 
+@@ -161,6 +183,30 @@ static struct timer_list xpc_hb_timer;
+ static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *);
+ 
+ 
++static int xpc_system_reboot(struct notifier_block *, unsigned long, void *);
++static struct notifier_block xpc_reboot_notifier = {
++	.notifier_call = xpc_system_reboot,
++};
++
++
++/*
++ * Timer function to enforce the timelimit on the partition disengage request.
++ */
++static void
++xpc_timeout_partition_disengage_request(unsigned long data)
++{
++	struct xpc_partition *part = (struct xpc_partition *) data;
++
++
++	DBUG_ON(jiffies < part->disengage_request_timeout);
++
++	(void) xpc_partition_disengaged(part);
++
++	DBUG_ON(part->disengage_request_timeout != 0);
++	DBUG_ON(xpc_partition_engaged(1UL << XPC_PARTID(part)) != 0);
++}
++
++
+ /*
+  * Notify the heartbeat check thread that an IRQ has been received.
+  */
+@@ -214,12 +260,6 @@ xpc_hb_checker(void *ignore)
+ 
+ 	while (!(volatile int) xpc_exiting) {
+ 
+-		/* wait for IRQ or timeout */
+-		(void) wait_event_interruptible(xpc_act_IRQ_wq,
+-			    (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) ||
+-					jiffies >= xpc_hb_check_timeout ||
+-						(volatile int) xpc_exiting));
+-
+ 		dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have "
+ 			"been received\n",
+ 			(int) (xpc_hb_check_timeout - jiffies),
+@@ -240,6 +280,7 @@ xpc_hb_checker(void *ignore)
+ 		}
+ 
+ 
++		/* check for outstanding IRQs */
+ 		new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd);
+ 		if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) {
+ 			force_IRQ = 0;
+@@ -257,12 +298,18 @@ xpc_hb_checker(void *ignore)
+ 			xpc_hb_check_timeout = jiffies +
+ 					   (xpc_hb_check_interval * HZ);
+ 		}
++
++		/* wait for IRQ or timeout */
++		(void) wait_event_interruptible(xpc_act_IRQ_wq,
++			    (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) ||
++					jiffies >= xpc_hb_check_timeout ||
++						(volatile int) xpc_exiting));
+ 	}
+ 
+ 	dev_dbg(xpc_part, "heartbeat checker is exiting\n");
+ 
+ 
+-	/* mark this thread as inactive */
++	/* mark this thread as having exited */
+ 	up(&xpc_hb_checker_exited);
+ 	return 0;
+ }
+@@ -282,7 +329,7 @@ xpc_initiate_discovery(void *ignore)
+ 
+ 	dev_dbg(xpc_part, "discovery thread is exiting\n");
+ 
+-	/* mark this thread as inactive */
++	/* mark this thread as having exited */
+ 	up(&xpc_discovery_exited);
+ 	return 0;
+ }
+@@ -309,7 +356,7 @@ xpc_make_first_contact(struct xpc_partit
+ 			"partition %d\n", XPC_PARTID(part));
+ 
+ 		/* wait a 1/4 of a second or so */
+-		msleep_interruptible(250);
++		(void) msleep_interruptible(250);
+ 
+ 		if (part->act_state == XPC_P_DEACTIVATING) {
+ 			return part->reason;
+@@ -336,7 +383,8 @@ static void
+ xpc_channel_mgr(struct xpc_partition *part)
+ {
+ 	while (part->act_state != XPC_P_DEACTIVATING ||
+-				atomic_read(&part->nchannels_active) > 0) {
++			atomic_read(&part->nchannels_active) > 0 ||
++					!xpc_partition_disengaged(part)) {
+ 
+ 		xpc_process_channel_activity(part);
+ 
+@@ -360,7 +408,8 @@ xpc_channel_mgr(struct xpc_partition *pa
+ 				(volatile u64) part->local_IPI_amo != 0 ||
+ 				((volatile u8) part->act_state ==
+ 							XPC_P_DEACTIVATING &&
+-				atomic_read(&part->nchannels_active) == 0)));
++				atomic_read(&part->nchannels_active) == 0 &&
++				xpc_partition_disengaged(part))));
+ 		atomic_set(&part->channel_mgr_requests, 1);
+ 
+ 		// >>> Does it need to wakeup periodically as well? In case we
+@@ -482,7 +531,7 @@ xpc_activating(void *__partid)
+ 		return 0;
+ 	}
+ 
+-	XPC_ALLOW_HB(partid, xpc_vars);
++	xpc_allow_hb(partid, xpc_vars);
+ 	xpc_IPI_send_activated(part);
+ 
+ 
+@@ -492,6 +541,7 @@ xpc_activating(void *__partid)
+ 	 */
+ 	(void) xpc_partition_up(part);
+ 
++	xpc_disallow_hb(partid, xpc_vars);
+ 	xpc_mark_partition_inactive(part);
+ 
+ 	if (part->reason == xpcReactivating) {
+@@ -670,6 +720,7 @@ xpc_daemonize_kthread(void *args)
+ 	struct xpc_partition *part = &xpc_partitions[partid];
+ 	struct xpc_channel *ch;
+ 	int n_needed;
++	unsigned long irq_flags;
+ 
+ 
+ 	daemonize("xpc%02dc%d", partid, ch_number);
+@@ -680,11 +731,14 @@ xpc_daemonize_kthread(void *args)
+ 	ch = &part->channels[ch_number];
+ 
+ 	if (!(ch->flags & XPC_C_DISCONNECTING)) {
+-		DBUG_ON(!(ch->flags & XPC_C_CONNECTED));
+ 
+ 		/* let registerer know that connection has been established */
+ 
+-		if (atomic_read(&ch->kthreads_assigned) == 1) {
++		spin_lock_irqsave(&ch->lock, irq_flags);
++		if (!(ch->flags & XPC_C_CONNECTCALLOUT)) {
++			ch->flags |= XPC_C_CONNECTCALLOUT;
++			spin_unlock_irqrestore(&ch->lock, irq_flags);
++
+ 			xpc_connected_callout(ch);
+ 
+ 			/*
+@@ -699,16 +753,28 @@ xpc_daemonize_kthread(void *args)
+ 					!(ch->flags & XPC_C_DISCONNECTING)) {
+ 				xpc_activate_kthreads(ch, n_needed);
+ 			}
++		} else {
++			spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 		}
+ 
+ 		xpc_kthread_waitmsgs(part, ch);
+ 	}
+ 
+-	if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
+-			((ch->flags & XPC_C_CONNECTCALLOUT) ||
+-				(ch->reason != xpcUnregistering &&
+-					ch->reason != xpcOtherUnregistering))) {
+-		xpc_disconnected_callout(ch);
++	if (atomic_dec_return(&ch->kthreads_assigned) == 0) {
++		spin_lock_irqsave(&ch->lock, irq_flags);
++		if ((ch->flags & XPC_C_CONNECTCALLOUT) &&
++				!(ch->flags & XPC_C_DISCONNECTCALLOUT)) {
++			ch->flags |= XPC_C_DISCONNECTCALLOUT;
++			spin_unlock_irqrestore(&ch->lock, irq_flags);
++
++			xpc_disconnecting_callout(ch);
++		} else {
++			spin_unlock_irqrestore(&ch->lock, irq_flags);
++		}
++		if (atomic_dec_return(&part->nchannels_engaged) == 0) {
++			xpc_mark_partition_disengaged(part);
++			xpc_IPI_send_disengage(part);
++		}
+ 	}
+ 
+ 
+@@ -740,12 +806,33 @@ xpc_create_kthreads(struct xpc_channel *
+ 	unsigned long irq_flags;
+ 	pid_t pid;
+ 	u64 args = XPC_PACK_ARGS(ch->partid, ch->number);
++	struct xpc_partition *part = &xpc_partitions[ch->partid];
+ 
+ 
+ 	while (needed-- > 0) {
++
++		/*
++		 * The following is done on behalf of the newly created
++		 * kthread. That kthread is responsible for doing the
++		 * counterpart to the following before it exits.
++		 */
++		(void) xpc_part_ref(part);
++		xpc_msgqueue_ref(ch);
++		if (atomic_inc_return(&ch->kthreads_assigned) == 1 &&
++		    atomic_inc_return(&part->nchannels_engaged) == 1) {
++			xpc_mark_partition_engaged(part);
++		}
++
+ 		pid = kernel_thread(xpc_daemonize_kthread, (void *) args, 0);
+ 		if (pid < 0) {
+ 			/* the fork failed */
++			if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
++			    atomic_dec_return(&part->nchannels_engaged) == 0) {
++				xpc_mark_partition_disengaged(part);
++				xpc_IPI_send_disengage(part);
++			}
++			xpc_msgqueue_deref(ch);
++			xpc_part_deref(part);
+ 
+ 			if (atomic_read(&ch->kthreads_assigned) <
+ 						ch->kthreads_idle_limit) {
+@@ -765,14 +852,6 @@ xpc_create_kthreads(struct xpc_channel *
+ 			break;
+ 		}
+ 
+-		/*
+-		 * The following is done on behalf of the newly created
+-		 * kthread. That kthread is responsible for doing the
+-		 * counterpart to the following before it exits.
+-		 */
+-		(void) xpc_part_ref(&xpc_partitions[ch->partid]);
+-		xpc_msgqueue_ref(ch);
+-		atomic_inc(&ch->kthreads_assigned);
+ 		ch->kthreads_created++;	// >>> temporary debug only!!!
+ 	}
+ }
+@@ -781,87 +860,142 @@ xpc_create_kthreads(struct xpc_channel *
+ void
+ xpc_disconnect_wait(int ch_number)
+ {
++	unsigned long irq_flags;
+ 	partid_t partid;
+ 	struct xpc_partition *part;
+ 	struct xpc_channel *ch;
++	int wakeup_channel_mgr;
+ 
+ 
+ 	/* now wait for all callouts to the caller's function to cease */
+ 	for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+ 		part = &xpc_partitions[partid];
+ 
+-		if (xpc_part_ref(part)) {
+-			ch = &part->channels[ch_number];
++		if (!xpc_part_ref(part)) {
++			continue;
++		}
+ 
+-// >>> how do we keep from falling into the window between our check and going
+-// >>> down and coming back up where sema is re-inited?
+-			if (ch->flags & XPC_C_SETUP) {
+-				(void) down(&ch->teardown_sema);
+-			}
++		ch = &part->channels[ch_number];
+ 
++		if (!(ch->flags & XPC_C_WDISCONNECT)) {
+ 			xpc_part_deref(part);
++			continue;
+ 		}
++
++		(void) down(&ch->wdisconnect_sema);
++
++		spin_lock_irqsave(&ch->lock, irq_flags);
++		DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
++		wakeup_channel_mgr = 0;
++
++		if (ch->delayed_IPI_flags) {
++			if (part->act_state != XPC_P_DEACTIVATING) {
++				spin_lock(&part->IPI_lock);
++				XPC_SET_IPI_FLAGS(part->local_IPI_amo,
++					ch->number, ch->delayed_IPI_flags);
++				spin_unlock(&part->IPI_lock);
++				wakeup_channel_mgr = 1;
++			}
++			ch->delayed_IPI_flags = 0;
++		}
++
++		ch->flags &= ~XPC_C_WDISCONNECT;
++		spin_unlock_irqrestore(&ch->lock, irq_flags);
++
++		if (wakeup_channel_mgr) {
++			xpc_wakeup_channel_mgr(part);
++		}
++
++		xpc_part_deref(part);
+ 	}
+ }
+ 
+ 
+ static void
+-xpc_do_exit(void)
++xpc_do_exit(enum xpc_retval reason)
+ {
+ 	partid_t partid;
+ 	int active_part_count;
+ 	struct xpc_partition *part;
++	unsigned long printmsg_time;
+ 
+ 
+-	/* now it's time to eliminate our heartbeat */
+-	del_timer_sync(&xpc_hb_timer);
+-	xpc_vars->heartbeating_to_mask = 0;
+-
+-	/* indicate to others that our reserved page is uninitialized */
+-	xpc_rsvd_page->vars_pa = 0;
+-
+-	/*
+-	 * Ignore all incoming interrupts. Without interupts the heartbeat
+-	 * checker won't activate any new partitions that may come up.
+-	 */
+-	free_irq(SGI_XPC_ACTIVATE, NULL);
++	/* a 'rmmod XPC' and a 'reboot' cannot both end up here together */
++	DBUG_ON(xpc_exiting == 1);
+ 
+ 	/*
+-	 * Cause the heartbeat checker and the discovery threads to exit.
+-	 * We don't want them attempting to activate new partitions as we
+-	 * try to deactivate the existing ones.
++	 * Let the heartbeat checker thread and the discovery thread
++	 * (if one is running) know that they should exit. Also wake up
++	 * the heartbeat checker thread in case it's sleeping.
+ 	 */
+ 	xpc_exiting = 1;
+ 	wake_up_interruptible(&xpc_act_IRQ_wq);
+ 
+-	/* wait for the heartbeat checker thread to mark itself inactive */
+-	down(&xpc_hb_checker_exited);
++	/* ignore all incoming interrupts */
++	free_irq(SGI_XPC_ACTIVATE, NULL);
+ 
+-	/* wait for the discovery thread to mark itself inactive */
++	/* wait for the discovery thread to exit */
+ 	down(&xpc_discovery_exited);
+ 
++	/* wait for the heartbeat checker thread to exit */
++	down(&xpc_hb_checker_exited);
++
+ 
+-	msleep_interruptible(300);
++	/* sleep for a 1/3 of a second or so */
++	(void) msleep_interruptible(300);
+ 
+ 
+ 	/* wait for all partitions to become inactive */
+ 
++	printmsg_time = jiffies;
++
+ 	do {
+ 		active_part_count = 0;
+ 
+ 		for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+ 			part = &xpc_partitions[partid];
+-			if (part->act_state != XPC_P_INACTIVE) {
+-				active_part_count++;
+ 
+-				XPC_DEACTIVATE_PARTITION(part, xpcUnloading);
++			if (xpc_partition_disengaged(part) &&
++					part->act_state == XPC_P_INACTIVE) {
++				continue;
+ 			}
++
++			active_part_count++;
++
++			XPC_DEACTIVATE_PARTITION(part, reason);
+ 		}
+ 
+-		if (active_part_count)
+-			msleep_interruptible(300);
+-	} while (active_part_count > 0);
++		if (active_part_count == 0) {
++			break;
++		}
++
++		if (jiffies >= printmsg_time) {
++			dev_info(xpc_part, "waiting for partitions to "
++				"deactivate/disengage, active count=%d, remote "
++				"engaged=0x%lx\n", active_part_count,
++				xpc_partition_engaged(1UL << partid));
++
++			printmsg_time = jiffies +
++					(XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ);
++		}
+ 
++		/* sleep for a 1/3 of a second or so */
++		(void) msleep_interruptible(300);
++
++	} while (1);
++
++	DBUG_ON(xpc_partition_engaged(-1UL));
++
++
++	/* indicate to others that our reserved page is uninitialized */
++	xpc_rsvd_page->vars_pa = 0;
++
++	/* now it's time to eliminate our heartbeat */
++	del_timer_sync(&xpc_hb_timer);
++	DBUG_ON(xpc_vars->heartbeating_to_mask != 0);
++
++	/* take ourselves off of the reboot_notifier_list */
++	(void) unregister_reboot_notifier(&xpc_reboot_notifier);
+ 
+ 	/* close down protections for IPI operations */
+ 	xpc_restrict_IPI_ops();
+@@ -876,6 +1010,34 @@ xpc_do_exit(void)
+ }
+ 
+ 
++/*
++ * This function is called when the system is being rebooted.
++ */
++static int
++xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
++{
++	enum xpc_retval reason;
++
++
++	switch (event) {
++	case SYS_RESTART:
++		reason = xpcSystemReboot;
++		break;
++	case SYS_HALT:
++		reason = xpcSystemHalt;
++		break;
++	case SYS_POWER_OFF:
++		reason = xpcSystemPoweroff;
++		break;
++	default:
++		reason = xpcSystemGoingDown;
++	}
++
++	xpc_do_exit(reason);
++	return NOTIFY_DONE;
++}
++
++
+ int __init
+ xpc_init(void)
+ {
+@@ -891,11 +1053,11 @@ xpc_init(void)
+ 
+ 	/*
+ 	 * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
+-	 * both a partition's reserved page and its XPC variables. Its size was
+-	 * based on the size of a reserved page. So we need to ensure that the
+-	 * XPC variables will fit as well.
++	 * various portions of a partition's reserved page. Its size is based
++	 * on the size of the reserved page header and part_nasids mask. So we
++	 * need to ensure that the other items will fit as well.
+ 	 */
+-	if (XPC_VARS_ALIGNED_SIZE > XPC_RSVD_PAGE_ALIGNED_SIZE) {
++	if (XPC_RP_VARS_SIZE > XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES) {
+ 		dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n");
+ 		return -EPERM;
+ 	}
+@@ -924,6 +1086,12 @@ xpc_init(void)
+ 		spin_lock_init(&part->act_lock);
+ 		part->act_state = XPC_P_INACTIVE;
+ 		XPC_SET_REASON(part, 0, 0);
++
++		init_timer(&part->disengage_request_timer);
++		part->disengage_request_timer.function =
++				xpc_timeout_partition_disengage_request;
++		part->disengage_request_timer.data = (unsigned long) part;
++
+ 		part->setup_state = XPC_P_UNSET;
+ 		init_waitqueue_head(&part->teardown_wq);
+ 		atomic_set(&part->references, 0);
+@@ -980,6 +1148,13 @@ xpc_init(void)
+ 	}
+ 
+ 
++	/* add ourselves to the reboot_notifier_list */
++	ret = register_reboot_notifier(&xpc_reboot_notifier);
++	if (ret != 0) {
++		dev_warn(xpc_part, "can't register reboot notifier\n");
++	}
++
++
+ 	/*
+ 	 * Set the beating to other partitions into motion.  This is
+ 	 * the last requirement for other partitions' discovery to
+@@ -1001,6 +1176,9 @@ xpc_init(void)
+ 		/* indicate to others that our reserved page is uninitialized */
+ 		xpc_rsvd_page->vars_pa = 0;
+ 
++		/* take ourselves off of the reboot_notifier_list */
++		(void) unregister_reboot_notifier(&xpc_reboot_notifier);
++
+ 		del_timer_sync(&xpc_hb_timer);
+ 		free_irq(SGI_XPC_ACTIVATE, NULL);
+ 		xpc_restrict_IPI_ops();
+@@ -1024,7 +1202,7 @@ xpc_init(void)
+ 		/* mark this new thread as a non-starter */
+ 		up(&xpc_discovery_exited);
+ 
+-		xpc_do_exit();
++		xpc_do_exit(xpcUnloading);
+ 		return -EBUSY;
+ 	}
+ 
+@@ -1043,7 +1221,7 @@ module_init(xpc_init);
+ void __exit
+ xpc_exit(void)
+ {
+-	xpc_do_exit();
++	xpc_do_exit(xpcUnloading);
+ }
+ module_exit(xpc_exit);
+ 
+@@ -1060,3 +1238,7 @@ module_param(xpc_hb_check_interval, int,
+ MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between "
+ 		"heartbeat checks.");
+ 
++module_param(xpc_disengage_request_timelimit, int, 0);
++MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait "
++		"for disengage request to complete.");
++
+diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
+--- a/arch/ia64/sn/kernel/xpc_partition.c
++++ b/arch/ia64/sn/kernel/xpc_partition.c
+@@ -44,16 +44,19 @@ static u64 xpc_sh2_IPI_access3;
+ 
+ 
+ /* original protection values for each node */
+-u64 xpc_prot_vec[MAX_COMPACT_NODES];
++u64 xpc_prot_vec[MAX_NUMNODES];
+ 
+ 
+-/* this partition's reserved page */
++/* this partition's reserved page pointers */
+ struct xpc_rsvd_page *xpc_rsvd_page;
+-
+-/* this partition's XPC variables (within the reserved page) */
++static u64 *xpc_part_nasids;
++static u64 *xpc_mach_nasids;
+ struct xpc_vars *xpc_vars;
+ struct xpc_vars_part *xpc_vars_part;
+ 
++static int xp_nasid_mask_bytes;	/* actual size in bytes of nasid mask */
++static int xp_nasid_mask_words;	/* actual size in words of nasid mask */
++
+ 
+ /*
+  * For performance reasons, each entry of xpc_partitions[] is cacheline
+@@ -65,20 +68,16 @@ struct xpc_partition xpc_partitions[XP_M
+ 
+ 
+ /*
+- * Generic buffer used to store a local copy of the remote partitions
+- * reserved page or XPC variables.
++ * Generic buffer used to store a local copy of portions of a remote
++ * partition's reserved page (either its header and part_nasids mask,
++ * or its vars).
+  *
+  * xpc_discovery runs only once and is a seperate thread that is
+  * very likely going to be processing in parallel with receiving
+  * interrupts.
+  */
+-char ____cacheline_aligned
+-		xpc_remote_copy_buffer[XPC_RSVD_PAGE_ALIGNED_SIZE];
+-
+-
+-/* systune related variables */
+-int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
+-int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_TIMEOUT;
++char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE +
++							XP_NASID_MASK_BYTES];
+ 
+ 
+ /*
+@@ -86,13 +85,16 @@ int xpc_hb_check_interval = XPC_HB_CHECK
+  * for that nasid. This function returns 0 on any error.
+  */
+ static u64
+-xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size)
++xpc_get_rsvd_page_pa(int nasid)
+ {
+ 	bte_result_t bte_res;
+ 	s64 status;
+ 	u64 cookie = 0;
+ 	u64 rp_pa = nasid;	/* seed with nasid */
+ 	u64 len = 0;
++	u64 buf = buf;
++	u64 buf_len = 0;
++	void *buf_base = NULL;
+ 
+ 
+ 	while (1) {
+@@ -108,13 +110,22 @@ xpc_get_rsvd_page_pa(int nasid, u64 buf,
+ 			break;
+ 		}
+ 
+-		if (len > buf_size) {
+-			dev_err(xpc_part, "len (=0x%016lx) > buf_size\n", len);
+-			status = SALRET_ERROR;
+-			break;
++		if (L1_CACHE_ALIGN(len) > buf_len) {
++			if (buf_base != NULL) {
++				kfree(buf_base);
++			}
++			buf_len = L1_CACHE_ALIGN(len);
++			buf = (u64) xpc_kmalloc_cacheline_aligned(buf_len,
++							GFP_KERNEL, &buf_base);
++			if (buf_base == NULL) {
++				dev_err(xpc_part, "unable to kmalloc "
++					"len=0x%016lx\n", buf_len);
++				status = SALRET_ERROR;
++				break;
++			}
+ 		}
+ 
+-		bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_size,
++		bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_len,
+ 					(BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 		if (bte_res != BTE_SUCCESS) {
+ 			dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res);
+@@ -123,6 +134,10 @@ xpc_get_rsvd_page_pa(int nasid, u64 buf,
+ 		}
+ 	}
+ 
++	if (buf_base != NULL) {
++		kfree(buf_base);
++	}
++
+ 	if (status != SALRET_OK) {
+ 		rp_pa = 0;
+ 	}
+@@ -141,15 +156,15 @@ xpc_rsvd_page_init(void)
+ {
+ 	struct xpc_rsvd_page *rp;
+ 	AMO_t *amos_page;
+-	u64 rp_pa, next_cl, nasid_array = 0;
++	u64 rp_pa, nasid_array = 0;
+ 	int i, ret;
+ 
+ 
+ 	/* get the local reserved page's address */
+ 
+-	rp_pa = xpc_get_rsvd_page_pa(cnodeid_to_nasid(0),
+-					(u64) xpc_remote_copy_buffer,
+-						XPC_RSVD_PAGE_ALIGNED_SIZE);
++	preempt_disable();
++	rp_pa = xpc_get_rsvd_page_pa(cpuid_to_nasid(smp_processor_id()));
++	preempt_enable();
+ 	if (rp_pa == 0) {
+ 		dev_err(xpc_part, "SAL failed to locate the reserved page\n");
+ 		return NULL;
+@@ -164,12 +179,19 @@ xpc_rsvd_page_init(void)
+ 
+ 	rp->version = XPC_RP_VERSION;
+ 
+-	/*
+-	 * Place the XPC variables on the cache line following the
+-	 * reserved page structure.
+-	 */
+-	next_cl = (u64) rp + XPC_RSVD_PAGE_ALIGNED_SIZE;
+-	xpc_vars = (struct xpc_vars *) next_cl;
++	/* establish the actual sizes of the nasid masks */
++	if (rp->SAL_version == 1) {
++		/* SAL_version 1 didn't set the nasids_size field */
++		rp->nasids_size = 128;
++	}
++	xp_nasid_mask_bytes = rp->nasids_size;
++	xp_nasid_mask_words = xp_nasid_mask_bytes / 8;
++
++	/* setup the pointers to the various items in the reserved page */
++	xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
++	xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp);
++	xpc_vars = XPC_RP_VARS(rp);
++	xpc_vars_part = XPC_RP_VARS_PART(rp);
+ 
+ 	/*
+ 	 * Before clearing xpc_vars, see if a page of AMOs had been previously
+@@ -221,33 +243,32 @@ xpc_rsvd_page_init(void)
+ 		amos_page = (AMO_t *) TO_AMO((u64) amos_page);
+ 	}
+ 
++	/* clear xpc_vars */
+ 	memset(xpc_vars, 0, sizeof(struct xpc_vars));
+ 
+-	/*
+-	 * Place the XPC per partition specific variables on the cache line
+-	 * following the XPC variables structure.
+-	 */
+-	next_cl += XPC_VARS_ALIGNED_SIZE;
+-	memset((u64 *) next_cl, 0, sizeof(struct xpc_vars_part) *
+-							XP_MAX_PARTITIONS);
+-	xpc_vars_part = (struct xpc_vars_part *) next_cl;
+-	xpc_vars->vars_part_pa = __pa(next_cl);
+-
+ 	xpc_vars->version = XPC_V_VERSION;
+ 	xpc_vars->act_nasid = cpuid_to_nasid(0);
+ 	xpc_vars->act_phys_cpuid = cpu_physical_id(0);
++	xpc_vars->vars_part_pa = __pa(xpc_vars_part);
++	xpc_vars->amos_page_pa = ia64_tpa((u64) amos_page);
+ 	xpc_vars->amos_page = amos_page;  /* save for next load of XPC */
+ 
+ 
+-	/*
+-	 * Initialize the activation related AMO variables.
+-	 */
+-	xpc_vars->act_amos = xpc_IPI_init(XP_MAX_PARTITIONS);
+-	for (i = 1; i < XP_NASID_MASK_WORDS; i++) {
+-		xpc_IPI_init(i + XP_MAX_PARTITIONS);
++	/* clear xpc_vars_part */
++	memset((u64 *) xpc_vars_part, 0, sizeof(struct xpc_vars_part) *
++							XP_MAX_PARTITIONS);
++
++	/* initialize the activate IRQ related AMO variables */
++	for (i = 0; i < xp_nasid_mask_words; i++) {
++		(void) xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i);
+ 	}
+-	/* export AMO page's physical address to other partitions */
+-	xpc_vars->amos_page_pa = ia64_tpa((u64) xpc_vars->amos_page);
++
++	/* initialize the engaged remote partitions related AMO variables */
++	(void) xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO);
++	(void) xpc_IPI_init(XPC_DISENGAGE_REQUEST_AMO);
++
++	/* timestamp of when reserved page was setup by XPC */
++	rp->stamp = CURRENT_TIME;
+ 
+ 	/*
+ 	 * This signifies to the remote partition that our reserved
+@@ -387,6 +408,11 @@ xpc_check_remote_hb(void)
+ 	remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer;
+ 
+ 	for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
++
++		if (xpc_exiting) {
++			break;
++		}
++
+ 		if (partid == sn_partition_id) {
+ 			continue;
+ 		}
+@@ -401,7 +427,7 @@ xpc_check_remote_hb(void)
+ 		/* pull the remote_hb cache line */
+ 		bres = xp_bte_copy(part->remote_vars_pa,
+ 					ia64_tpa((u64) remote_vars),
+-					XPC_VARS_ALIGNED_SIZE,
++					XPC_RP_VARS_SIZE,
+ 					(BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 		if (bres != BTE_SUCCESS) {
+ 			XPC_DEACTIVATE_PARTITION(part,
+@@ -417,7 +443,7 @@ xpc_check_remote_hb(void)
+ 
+ 		if (((remote_vars->heartbeat == part->last_heartbeat) &&
+ 			(remote_vars->kdb_status == 0)) ||
+-			     !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) {
++			     !xpc_hb_allowed(sn_partition_id, remote_vars)) {
+ 
+ 			XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
+ 			continue;
+@@ -429,31 +455,31 @@ xpc_check_remote_hb(void)
+ 
+ 
+ /*
+- * Get a copy of the remote partition's rsvd page.
++ * Get a copy of a portion of the remote partition's rsvd page.
+  *
+  * remote_rp points to a buffer that is cacheline aligned for BTE copies and
+- * assumed to be of size XPC_RSVD_PAGE_ALIGNED_SIZE.
++ * is large enough to contain a copy of their reserved page header and
++ * part_nasids mask.
+  */
+ static enum xpc_retval
+ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
+-		struct xpc_rsvd_page *remote_rp, u64 *remote_rsvd_page_pa)
++		struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
+ {
+ 	int bres, i;
+ 
+ 
+ 	/* get the reserved page's physical address */
+ 
+-	*remote_rsvd_page_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp,
+-						XPC_RSVD_PAGE_ALIGNED_SIZE);
+-	if (*remote_rsvd_page_pa == 0) {
++	*remote_rp_pa = xpc_get_rsvd_page_pa(nasid);
++	if (*remote_rp_pa == 0) {
+ 		return xpcNoRsvdPageAddr;
+ 	}
+ 
+ 
+-	/* pull over the reserved page structure */
++	/* pull over the reserved page header and part_nasids mask */
+ 
+-	bres = xp_bte_copy(*remote_rsvd_page_pa, ia64_tpa((u64) remote_rp),
+-				XPC_RSVD_PAGE_ALIGNED_SIZE,
++	bres = xp_bte_copy(*remote_rp_pa, ia64_tpa((u64) remote_rp),
++				XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes,
+ 				(BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 	if (bres != BTE_SUCCESS) {
+ 		return xpc_map_bte_errors(bres);
+@@ -461,8 +487,11 @@ xpc_get_remote_rp(int nasid, u64 *discov
+ 
+ 
+ 	if (discovered_nasids != NULL) {
+-		for (i = 0; i < XP_NASID_MASK_WORDS; i++) {
+-			discovered_nasids[i] |= remote_rp->part_nasids[i];
++		u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp);
++
++
++		for (i = 0; i < xp_nasid_mask_words; i++) {
++			discovered_nasids[i] |= remote_part_nasids[i];
+ 		}
+ 	}
+ 
+@@ -489,10 +518,10 @@ xpc_get_remote_rp(int nasid, u64 *discov
+ 
+ 
+ /*
+- * Get a copy of the remote partition's XPC variables.
++ * Get a copy of the remote partition's XPC variables from the reserved page.
+  *
+  * remote_vars points to a buffer that is cacheline aligned for BTE copies and
+- * assumed to be of size XPC_VARS_ALIGNED_SIZE.
++ * assumed to be of size XPC_RP_VARS_SIZE.
+  */
+ static enum xpc_retval
+ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
+@@ -508,7 +537,7 @@ xpc_get_remote_vars(u64 remote_vars_pa, 
+ 	/* pull over the cross partition variables */
+ 
+ 	bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars),
+-				XPC_VARS_ALIGNED_SIZE,
++				XPC_RP_VARS_SIZE,
+ 				(BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 	if (bres != BTE_SUCCESS) {
+ 		return xpc_map_bte_errors(bres);
+@@ -524,7 +553,56 @@ xpc_get_remote_vars(u64 remote_vars_pa, 
+ 
+ 
+ /*
+- * Prior code has determine the nasid which generated an IPI.  Inspect
++ * Update the remote partition's info.
++ */
++static void
++xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version,
++		struct timespec *remote_rp_stamp, u64 remote_rp_pa,
++		u64 remote_vars_pa, struct xpc_vars *remote_vars)
++{
++	part->remote_rp_version = remote_rp_version;
++	dev_dbg(xpc_part, "  remote_rp_version = 0x%016lx\n",
++		part->remote_rp_version);
++
++	part->remote_rp_stamp = *remote_rp_stamp;
++	dev_dbg(xpc_part, "  remote_rp_stamp (tv_sec = 0x%lx tv_nsec = 0x%lx\n",
++		part->remote_rp_stamp.tv_sec, part->remote_rp_stamp.tv_nsec);
++
++	part->remote_rp_pa = remote_rp_pa;
++	dev_dbg(xpc_part, "  remote_rp_pa = 0x%016lx\n", part->remote_rp_pa);
++
++	part->remote_vars_pa = remote_vars_pa;
++	dev_dbg(xpc_part, "  remote_vars_pa = 0x%016lx\n",
++		part->remote_vars_pa);
++
++	part->last_heartbeat = remote_vars->heartbeat;
++	dev_dbg(xpc_part, "  last_heartbeat = 0x%016lx\n",
++		part->last_heartbeat);
++
++	part->remote_vars_part_pa = remote_vars->vars_part_pa;
++	dev_dbg(xpc_part, "  remote_vars_part_pa = 0x%016lx\n",
++		part->remote_vars_part_pa);
++
++	part->remote_act_nasid = remote_vars->act_nasid;
++	dev_dbg(xpc_part, "  remote_act_nasid = 0x%x\n",
++		part->remote_act_nasid);
++
++	part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid;
++	dev_dbg(xpc_part, "  remote_act_phys_cpuid = 0x%x\n",
++		part->remote_act_phys_cpuid);
++
++	part->remote_amos_page_pa = remote_vars->amos_page_pa;
++	dev_dbg(xpc_part, "  remote_amos_page_pa = 0x%lx\n",
++		part->remote_amos_page_pa);
++
++	part->remote_vars_version = remote_vars->version;
++	dev_dbg(xpc_part, "  remote_vars_version = 0x%x\n",
++		part->remote_vars_version);
++}
++
++
++/*
++ * Prior code has determined the nasid which generated an IPI.  Inspect
+  * that nasid to determine if its partition needs to be activated or
+  * deactivated.
+  *
+@@ -542,8 +620,12 @@ xpc_identify_act_IRQ_req(int nasid)
+ {
+ 	struct xpc_rsvd_page *remote_rp;
+ 	struct xpc_vars *remote_vars;
+-	u64 remote_rsvd_page_pa;
++	u64 remote_rp_pa;
+ 	u64 remote_vars_pa;
++	int remote_rp_version;
++	int reactivate = 0;
++	int stamp_diff;
++	struct timespec remote_rp_stamp = { 0, 0 };
+ 	partid_t partid;
+ 	struct xpc_partition *part;
+ 	enum xpc_retval ret;
+@@ -553,7 +635,7 @@ xpc_identify_act_IRQ_req(int nasid)
+ 
+ 	remote_rp = (struct xpc_rsvd_page *) xpc_remote_copy_buffer;
+ 
+-	ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rsvd_page_pa);
++	ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
+ 	if (ret != xpcSuccess) {
+ 		dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
+ 			"which sent interrupt, reason=%d\n", nasid, ret);
+@@ -561,6 +643,10 @@ xpc_identify_act_IRQ_req(int nasid)
+ 	}
+ 
+ 	remote_vars_pa = remote_rp->vars_pa;
++	remote_rp_version = remote_rp->version;
++	if (XPC_SUPPORTS_RP_STAMP(remote_rp_version)) {
++		remote_rp_stamp = remote_rp->stamp;
++	}
+ 	partid = remote_rp->partid;
+ 	part = &xpc_partitions[partid];
+ 
+@@ -586,44 +672,117 @@ xpc_identify_act_IRQ_req(int nasid)
+ 		"%ld:0x%lx\n", (int) nasid, (int) partid, part->act_IRQ_rcvd,
+ 		remote_vars->heartbeat, remote_vars->heartbeating_to_mask);
+ 
++	if (xpc_partition_disengaged(part) &&
++					part->act_state == XPC_P_INACTIVE) {
+ 
+-	if (part->act_state == XPC_P_INACTIVE) {
++		xpc_update_partition_info(part, remote_rp_version,
++					&remote_rp_stamp, remote_rp_pa,
++					remote_vars_pa, remote_vars);
++
++		if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
++			if (xpc_partition_disengage_requested(1UL << partid)) {
++				/*
++				 * Other side is waiting on us to disengage,
++				 * even though we already have.
++				 */
++				return;
++			}
++		} else {
++			/* other side doesn't support disengage requests */
++			xpc_clear_partition_disengage_request(1UL << partid);
++		}
+ 
+-		part->remote_rp_pa = remote_rsvd_page_pa;
+-		dev_dbg(xpc_part, "  remote_rp_pa = 0x%016lx\n",
+-			part->remote_rp_pa);
+-
+-		part->remote_vars_pa = remote_vars_pa;
+-		dev_dbg(xpc_part, "  remote_vars_pa = 0x%016lx\n",
+-			part->remote_vars_pa);
++		xpc_activate_partition(part);
++		return;
++	}
+ 
+-		part->last_heartbeat = remote_vars->heartbeat;
+-		dev_dbg(xpc_part, "  last_heartbeat = 0x%016lx\n",
+-			part->last_heartbeat);
++	DBUG_ON(part->remote_rp_version == 0);
++	DBUG_ON(part->remote_vars_version == 0);
+ 
+-		part->remote_vars_part_pa = remote_vars->vars_part_pa;
+-		dev_dbg(xpc_part, "  remote_vars_part_pa = 0x%016lx\n",
+-			part->remote_vars_part_pa);
+-
+-		part->remote_act_nasid = remote_vars->act_nasid;
+-		dev_dbg(xpc_part, "  remote_act_nasid = 0x%x\n",
+-			part->remote_act_nasid);
+-
+-		part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid;
+-		dev_dbg(xpc_part, "  remote_act_phys_cpuid = 0x%x\n",
+-			part->remote_act_phys_cpuid);
+-
+-		part->remote_amos_page_pa = remote_vars->amos_page_pa;
+-		dev_dbg(xpc_part, "  remote_amos_page_pa = 0x%lx\n",
+-			part->remote_amos_page_pa);
++	if (!XPC_SUPPORTS_RP_STAMP(part->remote_rp_version)) {
++		DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(part->
++							remote_vars_version));
++
++		if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) {
++			DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->
++								version));
++			/* see if the other side rebooted */
++			if (part->remote_amos_page_pa ==
++				remote_vars->amos_page_pa &&
++					xpc_hb_allowed(sn_partition_id,
++								remote_vars)) {
++				/* doesn't look that way, so ignore the IPI */
++				return;
++			}
++		}
+ 
+-		xpc_activate_partition(part);
++		/*
++		 * Other side rebooted and previous XPC didn't support the
++		 * disengage request, so we don't need to do anything special.
++		 */
++
++		xpc_update_partition_info(part, remote_rp_version,
++						&remote_rp_stamp, remote_rp_pa,
++						remote_vars_pa, remote_vars);
++		part->reactivate_nasid = nasid;
++		XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
++		return;
++	}
+ 
+-	} else if (part->remote_amos_page_pa != remote_vars->amos_page_pa ||
+-			!XPC_HB_ALLOWED(sn_partition_id, remote_vars)) {
++	DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version));
+ 
++	if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) {
++		DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version));
++
++		/*
++		 * Other side rebooted and previous XPC did support the
++		 * disengage request, but the new one doesn't.
++		 */
++
++		xpc_clear_partition_engaged(1UL << partid);
++		xpc_clear_partition_disengage_request(1UL << partid);
++
++		xpc_update_partition_info(part, remote_rp_version,
++						&remote_rp_stamp, remote_rp_pa,
++						remote_vars_pa, remote_vars);
++		reactivate = 1;
++
++	} else {
++		DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version));
++
++		stamp_diff = xpc_compare_stamps(&part->remote_rp_stamp,
++							&remote_rp_stamp);
++		if (stamp_diff != 0) {
++			DBUG_ON(stamp_diff >= 0);
++
++			/*
++			 * Other side rebooted and the previous XPC did support
++			 * the disengage request, as does the new one.
++			 */
++
++			DBUG_ON(xpc_partition_engaged(1UL << partid));
++			DBUG_ON(xpc_partition_disengage_requested(1UL <<
++								partid));
++
++			xpc_update_partition_info(part, remote_rp_version,
++						&remote_rp_stamp, remote_rp_pa,
++						remote_vars_pa, remote_vars);
++			reactivate = 1;
++		}
++	}
++
++	if (!xpc_partition_disengaged(part)) {
++		/* still waiting on other side to disengage from us */
++		return;
++	}
++
++	if (reactivate) {
+ 		part->reactivate_nasid = nasid;
+ 		XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
++
++	} else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) &&
++			xpc_partition_disengage_requested(1UL << partid)) {
++		XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown);
+ 	}
+ }
+ 
+@@ -643,14 +802,17 @@ xpc_identify_act_IRQ_sender(void)
+ 	u64 nasid;			/* remote nasid */
+ 	int n_IRQs_detected = 0;
+ 	AMO_t *act_amos;
+-	struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
+ 
+ 
+-	act_amos = xpc_vars->act_amos;
++	act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS;
+ 
+ 
+ 	/* scan through act AMO variable looking for non-zero entries */
+-	for (word = 0; word < XP_NASID_MASK_WORDS; word++) {
++	for (word = 0; word < xp_nasid_mask_words; word++) {
++
++		if (xpc_exiting) {
++			break;
++		}
+ 
+ 		nasid_mask = xpc_IPI_receive(&act_amos[word]);
+ 		if (nasid_mask == 0) {
+@@ -668,7 +830,7 @@ xpc_identify_act_IRQ_sender(void)
+ 		 * remote nasid in our reserved pages machine mask.
+ 		 * This is used in the event of module reload.
+ 		 */
+-		rp->mach_nasids[word] |= nasid_mask;
++		xpc_mach_nasids[word] |= nasid_mask;
+ 
+ 
+ 		/* locate the nasid(s) which sent interrupts */
+@@ -688,6 +850,55 @@ xpc_identify_act_IRQ_sender(void)
+ 
+ 
+ /*
++ * See if the other side has responded to a partition disengage request
++ * from us.
++ */
++int
++xpc_partition_disengaged(struct xpc_partition *part)
++{
++	partid_t partid = XPC_PARTID(part);
++	int disengaged;
++
++
++	disengaged = (xpc_partition_engaged(1UL << partid) == 0);
++	if (part->disengage_request_timeout) {
++		if (!disengaged) {
++			if (jiffies < part->disengage_request_timeout) {
++				/* timelimit hasn't been reached yet */
++				return 0;
++			}
++
++			/*
++			 * Other side hasn't responded to our disengage
++			 * request in a timely fashion, so assume it's dead.
++			 */
++
++			xpc_clear_partition_engaged(1UL << partid);
++			disengaged = 1;
++		}
++		part->disengage_request_timeout = 0;
++
++		/* cancel the timer function, provided it's not us */
++		if (!in_interrupt()) {
++			del_singleshot_timer_sync(&part->
++						      disengage_request_timer);
++		}
++
++		DBUG_ON(part->act_state != XPC_P_DEACTIVATING &&
++					part->act_state != XPC_P_INACTIVE);
++		if (part->act_state != XPC_P_INACTIVE) {
++			xpc_wakeup_channel_mgr(part);
++		}
++
++		if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
++			xpc_cancel_partition_disengage_request(part);
++		}
++	}
++	return disengaged;
++}
++
++
++/*
+  * Mark specified partition as active.
+  */
+ enum xpc_retval
+@@ -721,7 +932,6 @@ xpc_deactivate_partition(const int line,
+ 				enum xpc_retval reason)
+ {
+ 	unsigned long irq_flags;
+-	partid_t partid = XPC_PARTID(part);
+ 
+ 
+ 	spin_lock_irqsave(&part->act_lock, irq_flags);
+@@ -749,17 +959,27 @@ xpc_deactivate_partition(const int line,
+ 
+ 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
+ 
+-	XPC_DISALLOW_HB(partid, xpc_vars);
++	if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
++		xpc_request_partition_disengage(part);
++		xpc_IPI_send_disengage(part);
++
++		/* set a timelimit on the disengage request */
++		part->disengage_request_timeout = jiffies +
++					(xpc_disengage_request_timelimit * HZ);
++		part->disengage_request_timer.expires =
++					part->disengage_request_timeout;
++		add_timer(&part->disengage_request_timer);
++	}
+ 
+-	dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", partid,
+-		reason);
++	dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n",
++		XPC_PARTID(part), reason);
+ 
+-	xpc_partition_down(part, reason);
++	xpc_partition_going_down(part, reason);
+ }
+ 
+ 
+ /*
+- * Mark specified partition as active.
++ * Mark specified partition as inactive.
+  */
+ void
+ xpc_mark_partition_inactive(struct xpc_partition *part)
+@@ -792,9 +1012,10 @@ xpc_discovery(void)
+ 	void *remote_rp_base;
+ 	struct xpc_rsvd_page *remote_rp;
+ 	struct xpc_vars *remote_vars;
+-	u64 remote_rsvd_page_pa;
++	u64 remote_rp_pa;
+ 	u64 remote_vars_pa;
+ 	int region;
++	int region_size;
+ 	int max_regions;
+ 	int nasid;
+ 	struct xpc_rsvd_page *rp;
+@@ -804,7 +1025,8 @@ xpc_discovery(void)
+ 	enum xpc_retval ret;
+ 
+ 
+-	remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RSVD_PAGE_ALIGNED_SIZE,
++	remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
++						xp_nasid_mask_bytes,
+ 						GFP_KERNEL, &remote_rp_base);
+ 	if (remote_rp == NULL) {
+ 		return;
+@@ -812,13 +1034,13 @@ xpc_discovery(void)
+ 	remote_vars = (struct xpc_vars *) remote_rp;
+ 
+ 
+-	discovered_nasids = kmalloc(sizeof(u64) * XP_NASID_MASK_WORDS,
++	discovered_nasids = kmalloc(sizeof(u64) * xp_nasid_mask_words,
+ 							GFP_KERNEL);
+ 	if (discovered_nasids == NULL) {
+ 		kfree(remote_rp_base);
+ 		return;
+ 	}
+-	memset(discovered_nasids, 0, sizeof(u64) * XP_NASID_MASK_WORDS);
++	memset(discovered_nasids, 0, sizeof(u64) * xp_nasid_mask_words);
+ 
+ 	rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
+ 
+@@ -827,11 +1049,19 @@ xpc_discovery(void)
+ 	 * nodes that can comprise an access protection grouping. The access
+ 	 * protection is in regards to memory, IOI and IPI.
+ 	 */
+-//>>> move the next two #defines into either include/asm-ia64/sn/arch.h or
+-//>>> include/asm-ia64/sn/addrs.h
+-#define SH1_MAX_REGIONS		64
+-#define SH2_MAX_REGIONS		256
+-	max_regions = is_shub2() ? SH2_MAX_REGIONS : SH1_MAX_REGIONS;
++	max_regions = 64;
++	region_size = sn_region_size;
++
++	switch (region_size) {
++	case 128:
++		max_regions *= 2;
++	case 64:
++		max_regions *= 2;
++	case 32:
++		max_regions *= 2;
++		region_size = 16;
++		DBUG_ON(!is_shub2());
++	}
+ 
+ 	for (region = 0; region < max_regions; region++) {
+ 
+@@ -841,8 +1071,8 @@ xpc_discovery(void)
+ 
+ 		dev_dbg(xpc_part, "searching region %d\n", region);
+ 
+-		for (nasid = (region * sn_region_size * 2);
+-		     nasid < ((region + 1) * sn_region_size * 2);
++		for (nasid = (region * region_size * 2);
++		     nasid < ((region + 1) * region_size * 2);
+ 		     nasid += 2) {
+ 
+ 			if ((volatile int) xpc_exiting) {
+@@ -852,14 +1082,14 @@ xpc_discovery(void)
+ 			dev_dbg(xpc_part, "checking nasid %d\n", nasid);
+ 
+ 
+-			if (XPC_NASID_IN_ARRAY(nasid, rp->part_nasids)) {
++			if (XPC_NASID_IN_ARRAY(nasid, xpc_part_nasids)) {
+ 				dev_dbg(xpc_part, "PROM indicates Nasid %d is "
+ 					"part of the local partition; skipping "
+ 					"region\n", nasid);
+ 				break;
+ 			}
+ 
+-			if (!(XPC_NASID_IN_ARRAY(nasid, rp->mach_nasids))) {
++			if (!(XPC_NASID_IN_ARRAY(nasid, xpc_mach_nasids))) {
+ 				dev_dbg(xpc_part, "PROM indicates Nasid %d was "
+ 					"not on Numa-Link network at reset\n",
+ 					nasid);
+@@ -877,7 +1107,7 @@ xpc_discovery(void)
+ 			/* pull over the reserved page structure */
+ 
+ 			ret = xpc_get_remote_rp(nasid, discovered_nasids,
+-					      remote_rp, &remote_rsvd_page_pa);
++					      remote_rp, &remote_rp_pa);
+ 			if (ret != xpcSuccess) {
+ 				dev_dbg(xpc_part, "unable to get reserved page "
+ 					"from nasid %d, reason=%d\n", nasid,
+@@ -948,6 +1178,13 @@ xpc_discovery(void)
+ 				remote_vars->act_nasid,
+ 				remote_vars->act_phys_cpuid);
+ 
++			if (XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->
++								version)) {
++				part->remote_amos_page_pa =
++						remote_vars->amos_page_pa;
++				xpc_mark_partition_disengaged(part);
++				xpc_cancel_partition_disengage_request(part);
++			}
+ 			xpc_IPI_send_activate(remote_vars);
+ 		}
+ 	}
+@@ -974,12 +1211,12 @@ xpc_initiate_partid_to_nasids(partid_t p
+ 		return xpcPartitionDown;
+ 	}
+ 
+-	part_nasid_pa = part->remote_rp_pa +
+-		(u64) &((struct xpc_rsvd_page *) 0)->part_nasids;
++	memset(nasid_mask, 0, XP_NASID_MASK_BYTES);
++
++	part_nasid_pa = (u64) XPC_RP_PART_NASIDS(part->remote_rp_pa);
+ 
+ 	bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask),
+-				L1_CACHE_ALIGN(XP_NASID_MASK_BYTES),
+-				(BTE_NOTIFY | BTE_WACQUIRE), NULL);
++			xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 
+ 	return xpc_map_bte_errors(bte_res);
+ }
+diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
+--- a/arch/ia64/sn/pci/pci_dma.c
++++ b/arch/ia64/sn/pci/pci_dma.c
+@@ -75,7 +75,7 @@ EXPORT_SYMBOL(sn_dma_set_mask);
+  * more information.
+  */
+ void *sn_dma_alloc_coherent(struct device *dev, size_t size,
+-			    dma_addr_t * dma_handle, int flags)
++			    dma_addr_t * dma_handle, gfp_t flags)
+ {
+ 	void *cpuaddr;
+ 	unsigned long phys_addr;
+@@ -326,6 +326,29 @@ int sn_pci_legacy_read(struct pci_bus *b
+ {
+ 	unsigned long addr;
+ 	int ret;
++	struct ia64_sal_retval isrv;
++
++	/*
++	 * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
++	 * around hw issues at the pci bus level.  SGI proms older than
++	 * 4.10 don't implment this.
++	 */
++
++	SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
++		pci_domain_nr(bus), bus->number,
++		0, /* io */
++		0, /* read */
++		port, size, __pa(val));
++
++	if (isrv.status == 0)
++		return size;
++
++	/*
++	 * If the above failed, retry using the SAL_PROBE call which should
++	 * be present in all proms (but which cannot work round PCI chipset
++	 * bugs).  This code is retained for compatability with old
++	 * pre-4.10 proms, and should be removed at some point in the future.
++	 */
+ 
+ 	if (!SN_PCIBUS_BUSSOFT(bus))
+ 		return -ENODEV;
+@@ -349,6 +372,29 @@ int sn_pci_legacy_write(struct pci_bus *
+ 	int ret = size;
+ 	unsigned long paddr;
+ 	unsigned long *addr;
++	struct ia64_sal_retval isrv;
++
++	/*
++	 * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
++	 * around hw issues at the pci bus level.  SGI proms older than
++	 * 4.10 don't implment this.
++	 */
++
++	SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
++		pci_domain_nr(bus), bus->number,
++		0, /* io */
++		1, /* write */
++		port, size, __pa(&val));
++
++	if (isrv.status == 0)
++		return size;
++
++	/*
++	 * If the above failed, retry using the SAL_PROBE call which should
++	 * be present in all proms (but which cannot work round PCI chipset
++	 * bugs).  This code is retained for compatability with old
++	 * pre-4.10 proms, and should be removed at some point in the future.
++	 */
+ 
+ 	if (!SN_PCIBUS_BUSSOFT(bus)) {
+ 		ret = -ENODEV;
+diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
+--- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c
++++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
+@@ -8,6 +8,7 @@
+ 
+ #include <linux/interrupt.h>
+ #include <linux/types.h>
++#include <asm/sn/io.h>
+ #include <asm/sn/pcibr_provider.h>
+ #include <asm/sn/pcibus_provider_defs.h>
+ #include <asm/sn/pcidev.h>
+@@ -29,10 +30,10 @@ void pcireg_control_bit_clr(struct pcibu
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ptr->tio.cp_control &= ~bits;
++			__sn_clrq_relaxed(&ptr->tio.cp_control, bits);
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ptr->pic.p_wid_control &= ~bits;
++			__sn_clrq_relaxed(&ptr->pic.p_wid_control, bits);
+ 			break;
+ 		default:
+ 			panic
+@@ -49,10 +50,10 @@ void pcireg_control_bit_set(struct pcibu
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ptr->tio.cp_control |= bits;
++			__sn_setq_relaxed(&ptr->tio.cp_control, bits);
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ptr->pic.p_wid_control |= bits;
++			__sn_setq_relaxed(&ptr->pic.p_wid_control, bits);
+ 			break;
+ 		default:
+ 			panic
+@@ -73,10 +74,10 @@ uint64_t pcireg_tflush_get(struct pcibus
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ret = ptr->tio.cp_tflush;
++			ret = __sn_readq_relaxed(&ptr->tio.cp_tflush);
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ret = ptr->pic.p_wid_tflush;
++			ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush);
+ 			break;
+ 		default:
+ 			panic
+@@ -103,10 +104,10 @@ uint64_t pcireg_intr_status_get(struct p
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ret = ptr->tio.cp_int_status;
++			ret = __sn_readq_relaxed(&ptr->tio.cp_int_status);
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ret = ptr->pic.p_int_status;
++			ret = __sn_readq_relaxed(&ptr->pic.p_int_status);
+ 			break;
+ 		default:
+ 			panic
+@@ -127,10 +128,10 @@ void pcireg_intr_enable_bit_clr(struct p
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ptr->tio.cp_int_enable &= ~bits;
++			__sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ptr->pic.p_int_enable &= ~bits;
++			__sn_clrq_relaxed(&ptr->pic.p_int_enable, ~bits);
+ 			break;
+ 		default:
+ 			panic
+@@ -147,10 +148,10 @@ void pcireg_intr_enable_bit_set(struct p
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ptr->tio.cp_int_enable |= bits;
++			__sn_setq_relaxed(&ptr->tio.cp_int_enable, bits);
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ptr->pic.p_int_enable |= bits;
++			__sn_setq_relaxed(&ptr->pic.p_int_enable, bits);
+ 			break;
+ 		default:
+ 			panic
+@@ -171,14 +172,16 @@ void pcireg_intr_addr_addr_set(struct pc
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ptr->tio.cp_int_addr[int_n] &= ~TIOCP_HOST_INTR_ADDR;
+-			ptr->tio.cp_int_addr[int_n] |=
+-			    (addr & TIOCP_HOST_INTR_ADDR);
++			__sn_clrq_relaxed(&ptr->tio.cp_int_addr[int_n],
++			    TIOCP_HOST_INTR_ADDR);
++			__sn_setq_relaxed(&ptr->tio.cp_int_addr[int_n],
++			    (addr & TIOCP_HOST_INTR_ADDR));
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ptr->pic.p_int_addr[int_n] &= ~PIC_HOST_INTR_ADDR;
+-			ptr->pic.p_int_addr[int_n] |=
+-			    (addr & PIC_HOST_INTR_ADDR);
++			__sn_clrq_relaxed(&ptr->pic.p_int_addr[int_n],
++			    PIC_HOST_INTR_ADDR);
++			__sn_setq_relaxed(&ptr->pic.p_int_addr[int_n],
++			    (addr & PIC_HOST_INTR_ADDR));
+ 			break;
+ 		default:
+ 			panic
+@@ -198,10 +201,10 @@ void pcireg_force_intr_set(struct pcibus
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ptr->tio.cp_force_pin[int_n] = 1;
++			writeq(1, &ptr->tio.cp_force_pin[int_n]);
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ptr->pic.p_force_pin[int_n] = 1;
++			writeq(1, &ptr->pic.p_force_pin[int_n]);
+ 			break;
+ 		default:
+ 			panic
+@@ -222,10 +225,12 @@ uint64_t pcireg_wrb_flush_get(struct pci
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ret = ptr->tio.cp_wr_req_buf[device];
++			ret =
++			    __sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]);
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ret = ptr->pic.p_wr_req_buf[device];
++			ret =
++			    __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]);
+ 			break;
+ 		default:
+ 		      panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", (void *)ptr);
+@@ -244,10 +249,10 @@ void pcireg_int_ate_set(struct pcibus_in
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ptr->tio.cp_int_ate_ram[ate_index] = (uint64_t) val;
++			writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]);
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ptr->pic.p_int_ate_ram[ate_index] = (uint64_t) val;
++			writeq(val, &ptr->pic.p_int_ate_ram[ate_index]);
+ 			break;
+ 		default:
+ 			panic
+@@ -265,12 +270,10 @@ uint64_t *pcireg_int_ate_addr(struct pci
+ 	if (pcibus_info) {
+ 		switch (pcibus_info->pbi_bridge_type) {
+ 		case PCIBR_BRIDGETYPE_TIOCP:
+-			ret =
+-			    (uint64_t *) & (ptr->tio.cp_int_ate_ram[ate_index]);
++			ret = &ptr->tio.cp_int_ate_ram[ate_index];
+ 			break;
+ 		case PCIBR_BRIDGETYPE_PIC:
+-			ret =
+-			    (uint64_t *) & (ptr->pic.p_int_ate_ram[ate_index]);
++			ret = &ptr->pic.p_int_ate_ram[ate_index];
+ 			break;
+ 		default:
+ 			panic
+diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
+--- a/arch/ia64/sn/pci/tioca_provider.c
++++ b/arch/ia64/sn/pci/tioca_provider.c
+@@ -11,6 +11,7 @@
+ #include <linux/pci.h>
+ #include <asm/sn/sn_sal.h>
+ #include <asm/sn/addrs.h>
++#include <asm/sn/io.h>
+ #include <asm/sn/pcidev.h>
+ #include <asm/sn/pcibus_provider_defs.h>
+ #include <asm/sn/tioca_provider.h>
+@@ -37,7 +38,7 @@ tioca_gart_init(struct tioca_kernel *tio
+ 	uint64_t offset;
+ 	struct page *tmp;
+ 	struct tioca_common *tioca_common;
+-	volatile struct tioca *ca_base;
++	struct tioca *ca_base;
+ 
+ 	tioca_common = tioca_kern->ca_common;
+ 	ca_base = (struct tioca *)tioca_common->ca_common.bs_base;
+@@ -174,27 +175,29 @@ tioca_gart_init(struct tioca_kernel *tio
+ 	 * 	DISABLE GART PREFETCHING due to hw bug tracked in SGI PV930029
+ 	 */
+ 
+-	ca_base->ca_control1 |= CA_AGPDMA_OP_ENB_COMBDELAY;	/* PV895469 ? */
+-	ca_base->ca_control2 &= ~(CA_GART_MEM_PARAM);
+-	ca_base->ca_control2 |= (0x2ull << CA_GART_MEM_PARAM_SHFT);
++	__sn_setq_relaxed(&ca_base->ca_control1,
++			CA_AGPDMA_OP_ENB_COMBDELAY);	/* PV895469 ? */
++	__sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
++	__sn_setq_relaxed(&ca_base->ca_control2,
++			(0x2ull << CA_GART_MEM_PARAM_SHFT));
+ 	tioca_kern->ca_gart_iscoherent = 1;
+-	ca_base->ca_control2 &=
+-	    ~(CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB);
++	__sn_clrq_relaxed(&ca_base->ca_control2,
++	    		(CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB));
+ 
+ 	/*
+ 	 * Unmask GART fetch error interrupts.  Clear residual errors first.
+ 	 */
+ 
+-	ca_base->ca_int_status_alias = CA_GART_FETCH_ERR;
+-	ca_base->ca_mult_error_alias = CA_GART_FETCH_ERR;
+-	ca_base->ca_int_mask &= ~CA_GART_FETCH_ERR;
++	writeq(CA_GART_FETCH_ERR, &ca_base->ca_int_status_alias);
++	writeq(CA_GART_FETCH_ERR, &ca_base->ca_mult_error_alias);
++	__sn_clrq_relaxed(&ca_base->ca_int_mask, CA_GART_FETCH_ERR);
+ 
+ 	/*
+ 	 * Program the aperature and gart registers in TIOCA
+ 	 */
+ 
+-	ca_base->ca_gart_aperature = ap_reg;
+-	ca_base->ca_gart_ptr_table = tioca_kern->ca_gart_coretalk_addr | 1;
++	writeq(ap_reg, &ca_base->ca_gart_aperature);
++	writeq(tioca_kern->ca_gart_coretalk_addr|1, &ca_base->ca_gart_ptr_table);
+ 
+ 	return 0;
+ }
+@@ -211,7 +214,6 @@ void
+ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
+ {
+ 	int cap_ptr;
+-	uint64_t ca_control1;
+ 	uint32_t reg;
+ 	struct tioca *tioca_base;
+ 	struct pci_dev *pdev;
+@@ -256,9 +258,7 @@ tioca_fastwrite_enable(struct tioca_kern
+ 	 */
+ 
+ 	tioca_base = (struct tioca *)common->ca_common.bs_base;
+-	ca_control1 = tioca_base->ca_control1;
+-	ca_control1 |= CA_AGP_FW_ENABLE;
+-	tioca_base->ca_control1 = ca_control1;
++	__sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE);
+ }
+ 
+ EXPORT_SYMBOL(tioca_fastwrite_enable);	/* used by agp-sgi */
+@@ -345,7 +345,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint
+ 		return 0;
+ 	}
+ 
+-	agp_dma_extn = ca_base->ca_agp_dma_addr_extn;
++	agp_dma_extn = __sn_readq_relaxed(&ca_base->ca_agp_dma_addr_extn);
+ 	if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) {
+ 		printk(KERN_ERR "%s:  coretalk upper node (%u) "
+ 		       "mismatch with ca_agp_dma_addr_extn (%lu)\n",
+diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c
+--- a/arch/ia64/sn/pci/tioce_provider.c
++++ b/arch/ia64/sn/pci/tioce_provider.c
+@@ -11,6 +11,7 @@
+ #include <linux/pci.h>
+ #include <asm/sn/sn_sal.h>
+ #include <asm/sn/addrs.h>
++#include <asm/sn/io.h>
+ #include <asm/sn/pcidev.h>
+ #include <asm/sn/pcibus_provider_defs.h>
+ #include <asm/sn/tioce_provider.h>
+@@ -227,7 +228,7 @@ tioce_alloc_map(struct tioce_kernel *ce_
+ 
+ 		ate = ATE_MAKE(addr, pagesize);
+ 		ate_shadow[i + j] = ate;
+-		ate_reg[i + j] = ate;
++		writeq(ate, &ate_reg[i + j]);
+ 		addr += pagesize;
+ 	}
+ 
+@@ -268,10 +269,10 @@ tioce_dma_d32(struct pci_dev *pdev, uint
+ 	pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port);
+ 
+ 	if (ce_kern->ce_port[port].dirmap_refcnt == 0) {
+-		volatile uint64_t tmp;
++		uint64_t tmp;
+ 
+ 		ce_kern->ce_port[port].dirmap_shadow = ct_upper;
+-		ce_mmr->ce_ure_dir_map[port] = ct_upper;
++		writeq(ct_upper, &ce_mmr->ce_ure_dir_map[port]);
+ 		tmp = ce_mmr->ce_ure_dir_map[port];
+ 		dma_ok = 1;
+ 	} else
+@@ -343,7 +344,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dm
+ 	if (TIOCE_D32_ADDR(bus_addr)) {
+ 		if (--ce_kern->ce_port[port].dirmap_refcnt == 0) {
+ 			ce_kern->ce_port[port].dirmap_shadow = 0;
+-			ce_mmr->ce_ure_dir_map[port] = 0;
++			writeq(0, &ce_mmr->ce_ure_dir_map[port]);
+ 		}
+ 	} else {
+ 		struct tioce_dmamap *map;
+@@ -582,18 +583,18 @@ tioce_kern_init(struct tioce_common *tio
+ 	 */
+ 
+ 	tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base;
+-	tioce_mmr->ce_ure_page_map &= ~CE_URE_PAGESIZE_MASK;
+-	tioce_mmr->ce_ure_page_map |= CE_URE_256K_PAGESIZE;
++	__sn_clrq_relaxed(&tioce_mmr->ce_ure_page_map, CE_URE_PAGESIZE_MASK);
++	__sn_setq_relaxed(&tioce_mmr->ce_ure_page_map, CE_URE_256K_PAGESIZE);
+ 	tioce_kern->ce_ate3240_pagesize = KB(256);
+ 
+ 	for (i = 0; i < TIOCE_NUM_M40_ATES; i++) {
+ 		tioce_kern->ce_ate40_shadow[i] = 0;
+-		tioce_mmr->ce_ure_ate40[i] = 0;
++		writeq(0, &tioce_mmr->ce_ure_ate40[i]);
+ 	}
+ 
+ 	for (i = 0; i < TIOCE_NUM_M3240_ATES; i++) {
+ 		tioce_kern->ce_ate3240_shadow[i] = 0;
+-		tioce_mmr->ce_ure_ate3240[i] = 0;
++		writeq(0, &tioce_mmr->ce_ure_ate3240[i]);
+ 	}
+ 
+ 	return tioce_kern;
+@@ -665,7 +666,7 @@ tioce_force_interrupt(struct sn_irq_info
+ 	default:
+ 		return;
+ 	}
+-	ce_mmr->ce_adm_force_int = force_int_val;
++	writeq(force_int_val, &ce_mmr->ce_adm_force_int);
+ }
+ 
+ /**
+@@ -686,6 +687,7 @@ tioce_target_interrupt(struct sn_irq_inf
+ 	struct tioce_common *ce_common;
+ 	struct tioce *ce_mmr;
+ 	int bit;
++	uint64_t vector;
+ 
+ 	pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
+ 	if (!pcidev_info)
+@@ -696,11 +698,11 @@ tioce_target_interrupt(struct sn_irq_inf
+ 
+ 	bit = sn_irq_info->irq_int_bit;
+ 
+-	ce_mmr->ce_adm_int_mask |= (1UL << bit);
+-	ce_mmr->ce_adm_int_dest[bit] =
+-		((uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT) |
+-			   sn_irq_info->irq_xtalkaddr;
+-	ce_mmr->ce_adm_int_mask &= ~(1UL << bit);
++	__sn_setq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit));
++	vector = (uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT;
++	vector |= sn_irq_info->irq_xtalkaddr;
++	writeq(vector, &ce_mmr->ce_adm_int_dest[bit]);
++	__sn_clrq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit));
+ 
+ 	tioce_force_interrupt(sn_irq_info);
+ }
+diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
+--- a/arch/m32r/kernel/entry.S
++++ b/arch/m32r/kernel/entry.S
+@@ -653,8 +653,6 @@ ENTRY(rie_handler)
+ 	SAVE_ALL
+ 	mvfc	r0, bpc
+ 	ld	r1, @r0
+-	seth	r0, #0xa0f0
+-	st	r1, @r0
+ 	ldi	r1, #0x20			; error_code
+ 	mv	r0, sp				; pt_regs
+ 	bl	do_rie_handler
+diff --git a/arch/m32r/kernel/io_m32700ut.c b/arch/m32r/kernel/io_m32700ut.c
+--- a/arch/m32r/kernel/io_m32700ut.c
++++ b/arch/m32r/kernel/io_m32700ut.c
+@@ -64,11 +64,11 @@ static inline void *__port2addr_ata(unsi
+  * from 0x10000000 to 0x13ffffff on physical address.
+  * The base address of LAN controller(LAN91C111) is 0x300.
+  */
+-#define LAN_IOSTART	0x300
+-#define LAN_IOEND	0x320
++#define LAN_IOSTART	0xa0000300
++#define LAN_IOEND	0xa0000320
+ static inline void *_port2addr_ne(unsigned long port)
+ {
+-	return (void *)(port + NONCACHE_OFFSET + 0x10000000);
++	return (void *)(port + 0x10000000);
+ }
+ static inline void *_port2addr_usb(unsigned long port)
+ {
+diff --git a/arch/m32r/kernel/io_mappi.c b/arch/m32r/kernel/io_mappi.c
+--- a/arch/m32r/kernel/io_mappi.c
++++ b/arch/m32r/kernel/io_mappi.c
+@@ -31,7 +31,7 @@ extern void pcc_iowrite(int, unsigned lo
+ 
+ static inline void *_port2addr(unsigned long port)
+ {
+-	return (void *)(port + NONCACHE_OFFSET);
++	return (void *)(port | (NONCACHE_OFFSET));
+ }
+ 
+ static inline void *_port2addr_ne(unsigned long port)
+diff --git a/arch/m32r/kernel/io_mappi2.c b/arch/m32r/kernel/io_mappi2.c
+--- a/arch/m32r/kernel/io_mappi2.c
++++ b/arch/m32r/kernel/io_mappi2.c
+@@ -33,12 +33,9 @@ extern void pcc_iowrite_word(int, unsign
+ 
+ static inline void *_port2addr(unsigned long port)
+ {
+-	return (void *)(port + NONCACHE_OFFSET);
++	return (void *)(port | (NONCACHE_OFFSET));
+ }
+ 
+-#define LAN_IOSTART	0x300
+-#define LAN_IOEND	0x320
+-
+ #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+ static inline void *__port2addr_ata(unsigned long port)
+ {
+@@ -59,15 +56,17 @@ static inline void *__port2addr_ata(unsi
+ }
+ #endif
+ 
++#define LAN_IOSTART	0xa0000300
++#define LAN_IOEND	0xa0000320
+ #ifdef CONFIG_CHIP_OPSP
+ static inline void *_port2addr_ne(unsigned long port)
+ {
+-	return (void *)(port + NONCACHE_OFFSET + 0x10000000);
++	return (void *)(port + 0x10000000);
+ }
+ #else
+ static inline void *_port2addr_ne(unsigned long port)
+ {
+-	return (void *)(port + NONCACHE_OFFSET + 0x04000000);
++	return (void *)(port + 0x04000000);
+ }
+ #endif
+ static inline void *_port2addr_usb(unsigned long port)
+diff --git a/arch/m32r/kernel/io_mappi3.c b/arch/m32r/kernel/io_mappi3.c
+--- a/arch/m32r/kernel/io_mappi3.c
++++ b/arch/m32r/kernel/io_mappi3.c
+@@ -36,9 +36,6 @@ static inline void *_port2addr(unsigned 
+ 	return (void *)(port + NONCACHE_OFFSET);
+ }
+ 
+-#define LAN_IOSTART	0x300
+-#define LAN_IOEND	0x320
+-
+ #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+ static inline void *__port2addr_ata(unsigned long port)
+ {
+@@ -59,9 +56,11 @@ static inline void *__port2addr_ata(unsi
+ }
+ #endif
+ 
++#define LAN_IOSTART	0xa0000300
++#define LAN_IOEND	0xa0000320
+ static inline void *_port2addr_ne(unsigned long port)
+ {
+-	return (void *)(port + NONCACHE_OFFSET + 0x10000000);
++	return (void *)(port + 0x10000000);
+ }
+ 
+ static inline void *_port2addr_usb(unsigned long port)
+diff --git a/arch/m32r/kernel/io_oaks32r.c b/arch/m32r/kernel/io_oaks32r.c
+--- a/arch/m32r/kernel/io_oaks32r.c
++++ b/arch/m32r/kernel/io_oaks32r.c
+@@ -16,7 +16,7 @@
+ 
+ static inline void *_port2addr(unsigned long port)
+ {
+-	return (void *)(port + NONCACHE_OFFSET);
++	return (void *)(port | (NONCACHE_OFFSET));
+ }
+ 
+ static inline  void *_port2addr_ne(unsigned long port)
+diff --git a/arch/m32r/kernel/io_opsput.c b/arch/m32r/kernel/io_opsput.c
+--- a/arch/m32r/kernel/io_opsput.c
++++ b/arch/m32r/kernel/io_opsput.c
+@@ -36,7 +36,7 @@ extern void pcc_iowrite_word(int, unsign
+ 
+ static inline void *_port2addr(unsigned long port)
+ {
+-	return (void *)(port + NONCACHE_OFFSET);
++	return (void *)(port | (NONCACHE_OFFSET));
+ }
+ 
+ /*
+@@ -44,11 +44,11 @@ static inline void *_port2addr(unsigned 
+  * from 0x10000000 to 0x13ffffff on physical address.
+  * The base address of LAN controller(LAN91C111) is 0x300.
+  */
+-#define LAN_IOSTART	0x300
+-#define LAN_IOEND	0x320
++#define LAN_IOSTART	0xa0000300
++#define LAN_IOEND	0xa0000320
+ static inline void *_port2addr_ne(unsigned long port)
+ {
+-	return (void *)(port + NONCACHE_OFFSET + 0x10000000);
++	return (void *)(port + 0x10000000);
+ }
+ static inline void *_port2addr_usb(unsigned long port)
+ {
+diff --git a/arch/m32r/kernel/io_usrv.c b/arch/m32r/kernel/io_usrv.c
+--- a/arch/m32r/kernel/io_usrv.c
++++ b/arch/m32r/kernel/io_usrv.c
+@@ -47,7 +47,7 @@ static inline void *_port2addr(unsigned 
+ 	else if (port >= UART1_IOSTART && port <= UART1_IOEND)
+ 		port = ((port - UART1_IOSTART) << 1) + UART1_REGSTART;
+ #endif	/* CONFIG_SERIAL_8250 || CONFIG_SERIAL_8250_MODULE */
+-	return (void *)(port + NONCACHE_OFFSET);
++	return (void *)(port | (NONCACHE_OFFSET));
+ }
+ 
+ static inline void delay(void)
+diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
+--- a/arch/m32r/kernel/ptrace.c
++++ b/arch/m32r/kernel/ptrace.c
+@@ -756,7 +756,7 @@ do_ptrace(long request, struct task_stru
+ 	return ret;
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	int ret;
+diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
+--- a/arch/m32r/kernel/setup.c
++++ b/arch/m32r/kernel/setup.c
+@@ -305,19 +305,19 @@ static int show_cpuinfo(struct seq_file 
+ 
+ 	seq_printf(m, "processor\t: %ld\n", cpu);
+ 
+-#ifdef CONFIG_CHIP_VDEC2
++#if defined(CONFIG_CHIP_VDEC2)
+ 	seq_printf(m, "cpu family\t: VDEC2\n"
+ 		"cache size\t: Unknown\n");
+-#elif  CONFIG_CHIP_M32700
++#elif defined(CONFIG_CHIP_M32700)
+ 	seq_printf(m,"cpu family\t: M32700\n"
+ 		"cache size\t: I-8KB/D-8KB\n");
+-#elif  CONFIG_CHIP_M32102
++#elif defined(CONFIG_CHIP_M32102)
+ 	seq_printf(m,"cpu family\t: M32102\n"
+ 		"cache size\t: I-8KB\n");
+-#elif  CONFIG_CHIP_OPSP
++#elif defined(CONFIG_CHIP_OPSP)
+ 	seq_printf(m,"cpu family\t: OPSP\n"
+ 		"cache size\t: I-8KB/D-8KB\n");
+-#elif  CONFIG_CHIP_MP
++#elif defined(CONFIG_CHIP_MP)
+ 	seq_printf(m, "cpu family\t: M32R-MP\n"
+ 		"cache size\t: I-xxKB/D-xxKB\n");
+ #else
+@@ -326,19 +326,19 @@ static int show_cpuinfo(struct seq_file 
+ 	seq_printf(m, "bogomips\t: %lu.%02lu\n",
+ 		c->loops_per_jiffy/(500000/HZ),
+ 		(c->loops_per_jiffy/(5000/HZ)) % 100);
+-#ifdef CONFIG_PLAT_MAPPI
++#if defined(CONFIG_PLAT_MAPPI)
+ 	seq_printf(m, "Machine\t\t: Mappi Evaluation board\n");
+-#elif CONFIG_PLAT_MAPPI2
++#elif defined(CONFIG_PLAT_MAPPI2)
+ 	seq_printf(m, "Machine\t\t: Mappi-II Evaluation board\n");
+-#elif CONFIG_PLAT_MAPPI3
++#elif defined(CONFIG_PLAT_MAPPI3)
+ 	seq_printf(m, "Machine\t\t: Mappi-III Evaluation board\n");
+-#elif  CONFIG_PLAT_M32700UT
++#elif defined(CONFIG_PLAT_M32700UT)
+ 	seq_printf(m, "Machine\t\t: M32700UT Evaluation board\n");
+-#elif  CONFIG_PLAT_OPSPUT
++#elif defined(CONFIG_PLAT_OPSPUT)
+ 	seq_printf(m, "Machine\t\t: OPSPUT Evaluation board\n");
+-#elif  CONFIG_PLAT_USRV
++#elif defined(CONFIG_PLAT_USRV)
+ 	seq_printf(m, "Machine\t\t: uServer\n");
+-#elif  CONFIG_PLAT_OAKS32R
++#elif defined(CONFIG_PLAT_OAKS32R)
+ 	seq_printf(m, "Machine\t\t: OAKS32R\n");
+ #else
+ 	seq_printf(m, "Machine\t\t: Unknown\n");
+diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c
+--- a/arch/m32r/kernel/setup_m32700ut.c
++++ b/arch/m32r/kernel/setup_m32700ut.c
+@@ -15,7 +15,7 @@
+ #include <linux/irq.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/system.h>
+ #include <asm/m32r.h>
+diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c
+--- a/arch/m32r/kernel/setup_mappi.c
++++ b/arch/m32r/kernel/setup_mappi.c
+@@ -11,7 +11,7 @@
+ #include <linux/irq.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/system.h>
+ #include <asm/m32r.h>
+diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c
+--- a/arch/m32r/kernel/setup_mappi2.c
++++ b/arch/m32r/kernel/setup_mappi2.c
+@@ -11,7 +11,7 @@
+ #include <linux/irq.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/system.h>
+ #include <asm/m32r.h>
+diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c
+--- a/arch/m32r/kernel/setup_mappi3.c
++++ b/arch/m32r/kernel/setup_mappi3.c
+@@ -11,7 +11,7 @@
+ #include <linux/irq.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/system.h>
+ #include <asm/m32r.h>
+diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c
+--- a/arch/m32r/kernel/setup_opsput.c
++++ b/arch/m32r/kernel/setup_opsput.c
+@@ -16,7 +16,7 @@
+ #include <linux/irq.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/system.h>
+ #include <asm/m32r.h>
+diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
+--- a/arch/m32r/kernel/time.c
++++ b/arch/m32r/kernel/time.c
+@@ -39,10 +39,6 @@ extern void send_IPI_allbutself(int, int
+ extern void smp_local_timer_interrupt(struct pt_regs *);
+ #endif
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ extern unsigned long wall_jiffies;
+ #define TICK_SIZE	(tick_nsec / 1000)
+ 
+diff --git a/arch/m32r/lib/csum_partial_copy.c b/arch/m32r/lib/csum_partial_copy.c
+--- a/arch/m32r/lib/csum_partial_copy.c
++++ b/arch/m32r/lib/csum_partial_copy.c
+@@ -18,10 +18,10 @@
+ 
+ #include <linux/module.h>
+ #include <linux/types.h>
++#include <linux/string.h>
+ 
+ #include <net/checksum.h>
+ #include <asm/byteorder.h>
+-#include <asm/string.h>
+ #include <asm/uaccess.h>
+ 
+ /*
+diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
+--- a/arch/m32r/mm/init.c
++++ b/arch/m32r/mm/init.c
+@@ -48,6 +48,8 @@ void show_mem(void)
+ 	show_free_areas();
+ 	printk("Free swap:       %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+ 	for_each_pgdat(pgdat) {
++		unsigned long flags;
++		pgdat_resize_lock(pgdat, &flags);
+ 		for (i = 0; i < pgdat->node_spanned_pages; ++i) {
+ 			page = pgdat_page_nr(pgdat, i);
+ 			total++;
+@@ -60,6 +62,7 @@ void show_mem(void)
+ 			else if (page_count(page))
+ 				shared += page_count(page) - 1;
+ 		}
++		pgdat_resize_unlock(pgdat, &flags);
+ 	}
+ 	printk("%d pages of RAM\n", total);
+ 	printk("%d pages of HIGHMEM\n",highmem);
+@@ -150,10 +153,14 @@ int __init reservedpages_count(void)
+ 	int reservedpages, nid, i;
+ 
+ 	reservedpages = 0;
+-	for_each_online_node(nid)
++	for_each_online_node(nid) {
++		unsigned long flags;
++		pgdat_resize_lock(NODE_DATA(nid), &flags);
+ 		for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++)
+ 			if (PageReserved(nid_page_nr(nid, i)))
+ 				reservedpages++;
++		pgdat_resize_unlock(NODE_DATA(nid), &flags);
++	}
+ 
+ 	return reservedpages;
+ }
+diff --git a/arch/m32r/mm/ioremap.c b/arch/m32r/mm/ioremap.c
+--- a/arch/m32r/mm/ioremap.c
++++ b/arch/m32r/mm/ioremap.c
+@@ -67,7 +67,7 @@ remap_area_pmd(pmd_t * pmd, unsigned lon
+ 	if (address >= end)
+ 		BUG();
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+@@ -90,7 +90,6 @@ remap_area_pages(unsigned long address, 
+ 	flush_cache_all();
+ 	if (address >= end)
+ 		BUG();
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		pmd_t *pmd;
+ 		pmd = pmd_alloc(&init_mm, dir, address);
+@@ -104,7 +103,6 @@ remap_area_pages(unsigned long address, 
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_tlb_all();
+ 	return error;
+ }
+diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
+--- a/arch/m68k/Kconfig
++++ b/arch/m68k/Kconfig
+@@ -388,33 +388,11 @@ config AMIGA_PCMCIA
+ 	  Include support in the kernel for pcmcia on Amiga 1200 and Amiga
+ 	  600. If you intend to use pcmcia cards say Y; otherwise say N.
+ 
+-config STRAM_SWAP
+-	bool "Support for ST-RAM as swap space"
+-	depends on ATARI && BROKEN
+-	---help---
+-	  Some Atari 68k machines (including the 520STF and 1020STE) divide
+-	  their addressable memory into ST and TT sections.  The TT section
+-	  (up to 512MB) is the main memory; the ST section (up to 4MB) is
+-	  accessible to the built-in graphics board, runs slower, and is
+-	  present mainly for backward compatibility with older machines.
+-
+-	  This enables support for using (parts of) ST-RAM as swap space,
+-	  instead of as normal system memory. This can first enhance system
+-	  performance if you have lots of alternate RAM (compared to the size
+-	  of ST-RAM), because executable code always will reside in faster
+-	  memory. ST-RAM will remain as ultra-fast swap space. On the other
+-	  hand, it allows much improved dynamic allocations of ST-RAM buffers
+-	  for device driver modules (e.g. floppy, ACSI, SLM printer, DMA
+-	  sound). The probability that such allocations at module load time
+-	  fail is drastically reduced.
+-
+ config STRAM_PROC
+ 	bool "ST-RAM statistics in /proc"
+ 	depends on ATARI
+ 	help
+-	  Say Y here to report ST-RAM usage statistics in /proc/stram.  See
+-	  the help for CONFIG_STRAM_SWAP for discussion of ST-RAM and its
+-	  uses.
++	  Say Y here to report ST-RAM usage statistics in /proc/stram.
+ 
+ config HEARTBEAT
+ 	bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
+diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
+--- a/arch/m68k/atari/stram.c
++++ b/arch/m68k/atari/stram.c
+@@ -15,11 +15,9 @@
+ #include <linux/kdev_t.h>
+ #include <linux/major.h>
+ #include <linux/init.h>
+-#include <linux/swap.h>
+ #include <linux/slab.h>
+ #include <linux/vmalloc.h>
+ #include <linux/pagemap.h>
+-#include <linux/shm.h>
+ #include <linux/bootmem.h>
+ #include <linux/mount.h>
+ #include <linux/blkdev.h>
+@@ -33,8 +31,6 @@
+ #include <asm/io.h>
+ #include <asm/semaphore.h>
+ 
+-#include <linux/swapops.h>
+-
+ #undef DEBUG
+ 
+ #ifdef DEBUG
+@@ -49,8 +45,7 @@
+ #include <linux/proc_fs.h>
+ #endif
+ 
+-/* Pre-swapping comments:
+- *
++/*
+  * ++roman:
+  *
+  * New version of ST-Ram buffer allocation. Instead of using the
+@@ -75,76 +70,6 @@
+  *
+  */
+ 
+-/*
+- * New Nov 1997: Use ST-RAM as swap space!
+- *
+- * In the past, there were often problems with modules that require ST-RAM
+- * buffers. Such drivers have to use __get_dma_pages(), which unfortunately
+- * often isn't very successful in allocating more than 1 page :-( [1] The net
+- * result was that most of the time you couldn't insmod such modules (ataflop,
+- * ACSI, SCSI on Falcon, Atari internal framebuffer, not to speak of acsi_slm,
+- * which needs a 1 MB buffer... :-).
+- *
+- * To overcome this limitation, ST-RAM can now be turned into a very
+- * high-speed swap space. If a request for an ST-RAM buffer comes, the kernel
+- * now tries to unswap some pages on that swap device to make some free (and
+- * contiguous) space. This works much better in comparison to
+- * __get_dma_pages(), since used swap pages can be selectively freed by either
+- * moving them to somewhere else in swap space, or by reading them back into
+- * system memory. Ok, there operation of unswapping isn't really cheap (for
+- * each page, one has to go through the page tables of all processes), but it
+- * doesn't happen that often (only when allocation ST-RAM, i.e. when loading a
+- * module that needs ST-RAM). But it at least makes it possible to load such
+- * modules!
+- *
+- * It could also be that overall system performance increases a bit due to
+- * ST-RAM swapping, since slow ST-RAM isn't used anymore for holding data or
+- * executing code in. It's then just a (very fast, compared to disk) back
+- * storage for not-so-often needed data. (But this effect must be compared
+- * with the loss of total memory...) Don't know if the effect is already
+- * visible on a TT, where the speed difference between ST- and TT-RAM isn't
+- * that dramatic, but it should on machines where TT-RAM is really much faster
+- * (e.g. Afterburner).
+- *
+- *   [1]: __get_free_pages() does a fine job if you only want one page, but if
+- * you want more (contiguous) pages, it can give you such a block only if
+- * there's already a free one. The algorithm can't try to free buffers or swap
+- * out something in order to make more free space, since all that page-freeing
+- * mechanisms work "target-less", i.e. they just free something, but not in a
+- * specific place. I.e., __get_free_pages() can't do anything to free
+- * *adjacent* pages :-( This situation becomes even worse for DMA memory,
+- * since the freeing algorithms are also blind to DMA capability of pages.
+- */
+-
+-/* 1998-10-20: ++andreas
+-   unswap_by_move disabled because it does not handle swapped shm pages.
+-*/
+-
+-/* 2000-05-01: ++andreas
+-   Integrated with bootmem.  Remove all traces of unswap_by_move.
+-*/
+-
+-#ifdef CONFIG_STRAM_SWAP
+-#define ALIGN_IF_SWAP(x)	PAGE_ALIGN(x)
+-#else
+-#define ALIGN_IF_SWAP(x)	(x)
+-#endif
+-
+-/* get index of swap page at address 'addr' */
+-#define SWAP_NR(addr)		(((addr) - swap_start) >> PAGE_SHIFT)
+-
+-/* get address of swap page #'nr' */
+-#define SWAP_ADDR(nr)		(swap_start + ((nr) << PAGE_SHIFT))
+-
+-/* get number of pages for 'n' bytes (already page-aligned) */
+-#define N_PAGES(n)			((n) >> PAGE_SHIFT)
+-
+-/* The following two numbers define the maximum fraction of ST-RAM in total
+- * memory, below that the kernel would automatically use ST-RAM as swap
+- * space. This decision can be overridden with stram_swap= */
+-#define MAX_STRAM_FRACTION_NOM		1
+-#define MAX_STRAM_FRACTION_DENOM	3
+-
+ /* Start and end (virtual) of ST-RAM */
+ static void *stram_start, *stram_end;
+ 
+@@ -164,10 +89,9 @@ typedef struct stram_block {
+ } BLOCK;
+ 
+ /* values for flags field */
+-#define BLOCK_FREE		0x01	/* free structure in the BLOCKs pool */
++#define BLOCK_FREE	0x01	/* free structure in the BLOCKs pool */
+ #define BLOCK_KMALLOCED	0x02	/* structure allocated by kmalloc() */
+-#define BLOCK_GFP		0x08	/* block allocated with __get_dma_pages() */
+-#define BLOCK_INSWAP	0x10	/* block allocated in swap space */
++#define BLOCK_GFP	0x08	/* block allocated with __get_dma_pages() */
+ 
+ /* list of allocated blocks */
+ static BLOCK *alloc_list;
+@@ -179,60 +103,8 @@ static BLOCK *alloc_list;
+ #define N_STATIC_BLOCKS	20
+ static BLOCK static_blocks[N_STATIC_BLOCKS];
+ 
+-#ifdef CONFIG_STRAM_SWAP
+-/* max. number of bytes to use for swapping
+- *  0 = no ST-RAM swapping
+- * -1 = do swapping (to whole ST-RAM) if it's less than MAX_STRAM_FRACTION of
+- *      total memory
+- */
+-static int max_swap_size = -1;
+-
+-/* start and end of swapping area */
+-static void *swap_start, *swap_end;
+-
+-/* The ST-RAM's swap info structure */
+-static struct swap_info_struct *stram_swap_info;
+-
+-/* The ST-RAM's swap type */
+-static int stram_swap_type;
+-
+-/* Semaphore for get_stram_region.  */
+-static DECLARE_MUTEX(stram_swap_sem);
+-
+-/* major and minor device number of the ST-RAM device; for the major, we use
+- * the same as Amiga z2ram, which is really similar and impossible on Atari,
+- * and for the minor a relatively odd number to avoid the user creating and
+- * using that device. */
+-#define	STRAM_MAJOR		Z2RAM_MAJOR
+-#define	STRAM_MINOR		13
+-
+-/* Some impossible pointer value */
+-#define MAGIC_FILE_P	(struct file *)0xffffdead
+-
+-#ifdef DO_PROC
+-static unsigned stat_swap_read;
+-static unsigned stat_swap_write;
+-static unsigned stat_swap_force;
+-#endif /* DO_PROC */
+-
+-#endif /* CONFIG_STRAM_SWAP */
+-
+ /***************************** Prototypes *****************************/
+ 
+-#ifdef CONFIG_STRAM_SWAP
+-static int swap_init(void *start_mem, void *swap_data);
+-static void *get_stram_region( unsigned long n_pages );
+-static void free_stram_region( unsigned long offset, unsigned long n_pages
+-			       );
+-static int in_some_region(void *addr);
+-static unsigned long find_free_region( unsigned long n_pages, unsigned long
+-				       *total_free, unsigned long
+-				       *region_free );
+-static void do_stram_request(request_queue_t *);
+-static int stram_open( struct inode *inode, struct file *filp );
+-static int stram_release( struct inode *inode, struct file *filp );
+-static void reserve_region(void *start, void *end);
+-#endif
+ static BLOCK *add_region( void *addr, unsigned long size );
+ static BLOCK *find_region( void *addr );
+ static int remove_region( BLOCK *block );
+@@ -279,84 +151,11 @@ void __init atari_stram_init(void)
+  */
+ void __init atari_stram_reserve_pages(void *start_mem)
+ {
+-#ifdef CONFIG_STRAM_SWAP
+-	/* if max_swap_size is negative (i.e. no stram_swap= option given),
+-	 * determine at run time whether to use ST-RAM swapping */
+-	if (max_swap_size < 0)
+-		/* Use swapping if ST-RAM doesn't make up more than MAX_STRAM_FRACTION
+-		 * of total memory. In that case, the max. size is set to 16 MB,
+-		 * because ST-RAM can never be bigger than that.
+-		 * Also, never use swapping on a Hades, there's no separate ST-RAM in
+-		 * that machine. */
+-		max_swap_size =
+-			(!MACH_IS_HADES &&
+-			 (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
+-			  ((unsigned long)high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
+-	DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
+-#endif
+-
+ 	/* always reserve first page of ST-RAM, the first 2 kB are
+ 	 * supervisor-only! */
+ 	if (!kernel_in_stram)
+ 		reserve_bootmem (0, PAGE_SIZE);
+ 
+-#ifdef CONFIG_STRAM_SWAP
+-	{
+-		void *swap_data;
+-
+-		start_mem = (void *) PAGE_ALIGN ((unsigned long) start_mem);
+-		/* determine first page to use as swap: if the kernel is
+-		   in TT-RAM, this is the first page of (usable) ST-RAM;
+-		   otherwise just use the end of kernel data (= start_mem) */
+-		swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE : start_mem;
+-		/* decrement by one page, rest of kernel assumes that first swap page
+-		 * is always reserved and maybe doesn't handle swp_entry == 0
+-		 * correctly */
+-		swap_start -= PAGE_SIZE;
+-		swap_end = stram_end;
+-		if (swap_end-swap_start > max_swap_size)
+-			swap_end =  swap_start + max_swap_size;
+-		DPRINTK( "atari_stram_reserve_pages: swapping enabled; "
+-				 "swap=%p-%p\n", swap_start, swap_end);
+-
+-		/* reserve some amount of memory for maintainance of
+-		 * swapping itself: one page for each 2048 (PAGE_SIZE/2)
+-		 * swap pages. (2 bytes for each page) */
+-		swap_data = start_mem;
+-		start_mem += ((SWAP_NR(swap_end) + PAGE_SIZE/2 - 1)
+-			      >> (PAGE_SHIFT-1)) << PAGE_SHIFT;
+-		/* correct swap_start if necessary */
+-		if (swap_start + PAGE_SIZE == swap_data)
+-			swap_start = start_mem - PAGE_SIZE;
+-
+-		if (!swap_init( start_mem, swap_data )) {
+-			printk( KERN_ERR "ST-RAM swap space initialization failed\n" );
+-			max_swap_size = 0;
+-			return;
+-		}
+-		/* reserve region for swapping meta-data */
+-		reserve_region(swap_data, start_mem);
+-		/* reserve swapping area itself */
+-		reserve_region(swap_start + PAGE_SIZE, swap_end);
+-
+-		/*
+-		 * If the whole ST-RAM is used for swapping, there are no allocatable
+-		 * dma pages left. But unfortunately, some shared parts of the kernel
+-		 * (particularly the SCSI mid-level) call __get_dma_pages()
+-		 * unconditionally :-( These calls then fail, and scsi.c even doesn't
+-		 * check for NULL return values and just crashes. The quick fix for
+-		 * this (instead of doing much clean up work in the SCSI code) is to
+-		 * pretend all pages are DMA-able by setting mach_max_dma_address to
+-		 * ULONG_MAX. This doesn't change any functionality so far, since
+-		 * get_dma_pages() shouldn't be used on Atari anyway anymore (better
+-		 * use atari_stram_alloc()), and the Atari SCSI drivers don't need DMA
+-		 * memory. But unfortunately there's now no kind of warning (even not
+-		 * a NULL return value) if you use get_dma_pages() nevertheless :-(
+-		 * You just will get non-DMA-able memory...
+-		 */
+-		mach_max_dma_address = 0xffffffff;
+-	}
+-#endif
+ }
+ 
+ void atari_stram_mem_init_hook (void)
+@@ -367,7 +166,6 @@ void atari_stram_mem_init_hook (void)
+ 
+ /*
+  * This is main public interface: somehow allocate a ST-RAM block
+- * There are three strategies:
+  *
+  *  - If we're before mem_init(), we have to make a static allocation. The
+  *    region is taken in the kernel data area (if the kernel is in ST-RAM) or
+@@ -375,14 +173,9 @@ void atari_stram_mem_init_hook (void)
+  *    rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel
+  *    address space in the latter case.
+  *
+- *  - If mem_init() already has been called and ST-RAM swapping is enabled,
+- *    try to get the memory from the (pseudo) swap-space, either free already
+- *    or by moving some other pages out of the swap.
+- *
+- *  - If mem_init() already has been called, and ST-RAM swapping is not
+- *    enabled, the only possibility is to try with __get_dma_pages(). This has
+- *    the disadvantage that it's very hard to get more than 1 page, and it is
+- *    likely to fail :-(
++ *  - If mem_init() already has been called, try with __get_dma_pages().
++ *    This has the disadvantage that it's very hard to get more than 1 page,
++ *    and it is likely to fail :-(
+  *
+  */
+ void *atari_stram_alloc(long size, const char *owner)
+@@ -393,27 +186,13 @@ void *atari_stram_alloc(long size, const
+ 
+ 	DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
+ 
+-	size = ALIGN_IF_SWAP(size);
+-	DPRINTK( "atari_stram_alloc: rounded size = %08lx\n", size );
+-#ifdef CONFIG_STRAM_SWAP
+-	if (max_swap_size) {
+-		/* If swapping is active: make some free space in the swap
+-		   "device". */
+-		DPRINTK( "atari_stram_alloc: after mem_init, swapping ok, "
+-				 "calling get_region\n" );
+-		addr = get_stram_region( N_PAGES(size) );
+-		flags = BLOCK_INSWAP;
+-	}
+-	else
+-#endif
+ 	if (!mem_init_done)
+ 		return alloc_bootmem_low(size);
+ 	else {
+-		/* After mem_init() and no swapping: can only resort to
+-		 * __get_dma_pages() */
++		/* After mem_init(): can only resort to __get_dma_pages() */
+ 		addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
+ 		flags = BLOCK_GFP;
+-		DPRINTK( "atari_stram_alloc: after mem_init, swapping off, "
++		DPRINTK( "atari_stram_alloc: after mem_init, "
+ 				 "get_pages=%p\n", addr );
+ 	}
+ 
+@@ -422,12 +201,7 @@ void *atari_stram_alloc(long size, const
+ 			/* out of memory for BLOCK structure :-( */
+ 			DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
+ 					 "freeing again\n" );
+-#ifdef CONFIG_STRAM_SWAP
+-			if (flags == BLOCK_INSWAP)
+-				free_stram_region( SWAP_NR(addr), N_PAGES(size) );
+-			else
+-#endif
+-				free_pages((unsigned long)addr, get_order(size));
++			free_pages((unsigned long)addr, get_order(size));
+ 			return( NULL );
+ 		}
+ 		block->owner = owner;
+@@ -451,25 +225,12 @@ void atari_stram_free( void *addr )
+ 	DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
+ 			 "flags=%02x\n", block, block->size, block->owner, block->flags );
+ 
+-#ifdef CONFIG_STRAM_SWAP
+-	if (!max_swap_size) {
+-#endif
+-		if (block->flags & BLOCK_GFP) {
+-			DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
+-				get_order(block->size));
+-			free_pages((unsigned long)addr, get_order(block->size));
+-		}
+-		else
+-			goto fail;
+-#ifdef CONFIG_STRAM_SWAP
+-	}
+-	else if (block->flags & BLOCK_INSWAP) {
+-		DPRINTK( "atari_stram_free: is swap-alloced\n" );
+-		free_stram_region( SWAP_NR(block->start), N_PAGES(block->size) );
+-	}
+-	else
++	if (!(block->flags & BLOCK_GFP))
+ 		goto fail;
+-#endif
++
++	DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
++		get_order(block->size));
++	free_pages((unsigned long)addr, get_order(block->size));
+ 	remove_region( block );
+ 	return;
+ 
+@@ -478,612 +239,6 @@ void atari_stram_free( void *addr )
+ 			"(called from %p)\n", addr, __builtin_return_address(0) );
+ }
+ 
+-
+-#ifdef CONFIG_STRAM_SWAP
+-
+-
+-/* ------------------------------------------------------------------------ */
+-/*						   Main Swapping Functions							*/
+-/* ------------------------------------------------------------------------ */
+-
+-
+-/*
+- * Initialize ST-RAM swap device
+- * (lots copied and modified from sys_swapon() in mm/swapfile.c)
+- */
+-static int __init swap_init(void *start_mem, void *swap_data)
+-{
+-	static struct dentry fake_dentry;
+-	static struct vfsmount fake_vfsmnt;
+-	struct swap_info_struct *p;
+-	struct inode swap_inode;
+-	unsigned int type;
+-	void *addr;
+-	int i, j, k, prev;
+-
+-	DPRINTK("swap_init(start_mem=%p, swap_data=%p)\n",
+-		start_mem, swap_data);
+-
+-	/* need at least one page for swapping to (and this also isn't very
+-	 * much... :-) */
+-	if (swap_end - swap_start < 2*PAGE_SIZE) {
+-		printk( KERN_WARNING "stram_swap_init: swap space too small\n" );
+-		return( 0 );
+-	}
+-
+-	/* find free slot in swap_info */
+-	for( p = swap_info, type = 0; type < nr_swapfiles; type++, p++ )
+-		if (!(p->flags & SWP_USED))
+-			break;
+-	if (type >= MAX_SWAPFILES) {
+-		printk( KERN_WARNING "stram_swap_init: max. number of "
+-				"swap devices exhausted\n" );
+-		return( 0 );
+-	}
+-	if (type >= nr_swapfiles)
+-		nr_swapfiles = type+1;
+-
+-	stram_swap_info = p;
+-	stram_swap_type = type;
+-
+-	/* fake some dir cache entries to give us some name in /dev/swaps */
+-	fake_dentry.d_parent = &fake_dentry;
+-	fake_dentry.d_name.name = "stram (internal)";
+-	fake_dentry.d_name.len = 16;
+-	fake_vfsmnt.mnt_parent = &fake_vfsmnt;
+-
+-	p->flags        = SWP_USED;
+-	p->swap_file    = &fake_dentry;
+-	p->swap_vfsmnt  = &fake_vfsmnt;
+-	p->swap_map	= swap_data;
+-	p->cluster_nr   = 0;
+-	p->next         = -1;
+-	p->prio         = 0x7ff0;	/* a rather high priority, but not the higest
+-								 * to give the user a chance to override */
+-
+-	/* call stram_open() directly, avoids at least the overhead in
+-	 * constructing a dummy file structure... */
+-	swap_inode.i_rdev = MKDEV( STRAM_MAJOR, STRAM_MINOR );
+-	stram_open( &swap_inode, MAGIC_FILE_P );
+-	p->max = SWAP_NR(swap_end);
+-
+-	/* initialize swap_map: set regions that are already allocated or belong
+-	 * to kernel data space to SWAP_MAP_BAD, otherwise to free */
+-	j = 0; /* # of free pages */
+-	k = 0; /* # of already allocated pages (from pre-mem_init stram_alloc()) */
+-	p->lowest_bit = 0;
+-	p->highest_bit = 0;
+-	for( i = 1, addr = SWAP_ADDR(1); i < p->max;
+-		 i++, addr += PAGE_SIZE ) {
+-		if (in_some_region( addr )) {
+-			p->swap_map[i] = SWAP_MAP_BAD;
+-			++k;
+-		}
+-		else if (kernel_in_stram && addr < start_mem ) {
+-			p->swap_map[i] = SWAP_MAP_BAD;
+-		}
+-		else {
+-			p->swap_map[i] = 0;
+-			++j;
+-			if (!p->lowest_bit) p->lowest_bit = i;
+-			p->highest_bit = i;
+-		}
+-	}
+-	/* first page always reserved (and doesn't really belong to swap space) */
+-	p->swap_map[0] = SWAP_MAP_BAD;
+-
+-	/* now swapping to this device ok */
+-	p->pages = j + k;
+-	swap_list_lock();
+-	nr_swap_pages += j;
+-	p->flags = SWP_WRITEOK;
+-
+-	/* insert swap space into swap_list */
+-	prev = -1;
+-	for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
+-		if (p->prio >= swap_info[i].prio) {
+-			break;
+-		}
+-		prev = i;
+-	}
+-	p->next = i;
+-	if (prev < 0) {
+-		swap_list.head = swap_list.next = p - swap_info;
+-	} else {
+-		swap_info[prev].next = p - swap_info;
+-	}
+-	swap_list_unlock();
+-
+-	printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
+-			p->pages << 2, p->pages );
+-	return( 1 );
+-}
+-
+-
+-/*
+- * The swap entry has been read in advance, and we return 1 to indicate
+- * that the page has been used or is no longer needed.
+- *
+- * Always set the resulting pte to be nowrite (the same as COW pages
+- * after one process has exited).  We don't know just how many PTEs will
+- * share this swap entry, so be cautious and let do_wp_page work out
+- * what to do if a write is requested later.
+- */
+-static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
+-			      address, pte_t *dir, swp_entry_t entry,
+-			      struct page *page)
+-{
+-	pte_t pte = *dir;
+-
+-	if (pte_none(pte))
+-		return;
+-	if (pte_present(pte)) {
+-		/* If this entry is swap-cached, then page must already
+-                   hold the right address for any copies in physical
+-                   memory */
+-		if (pte_page(pte) != page)
+-			return;
+-		/* We will be removing the swap cache in a moment, so... */
+-		set_pte(dir, pte_mkdirty(pte));
+-		return;
+-	}
+-	if (pte_val(pte) != entry.val)
+-		return;
+-
+-	DPRINTK("unswap_pte: replacing entry %08lx by new page %p",
+-		entry.val, page);
+-	set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
+-	swap_free(entry);
+-	get_page(page);
+-	inc_mm_counter(vma->vm_mm, rss);
+-}
+-
+-static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
+-			      unsigned long address, unsigned long size,
+-			      unsigned long offset, swp_entry_t entry,
+-			      struct page *page)
+-{
+-	pte_t * pte;
+-	unsigned long end;
+-
+-	if (pmd_none(*dir))
+-		return;
+-	if (pmd_bad(*dir)) {
+-		pmd_ERROR(*dir);
+-		pmd_clear(dir);
+-		return;
+-	}
+-	pte = pte_offset_kernel(dir, address);
+-	offset += address & PMD_MASK;
+-	address &= ~PMD_MASK;
+-	end = address + size;
+-	if (end > PMD_SIZE)
+-		end = PMD_SIZE;
+-	do {
+-		unswap_pte(vma, offset+address-vma->vm_start, pte, entry, page);
+-		address += PAGE_SIZE;
+-		pte++;
+-	} while (address < end);
+-}
+-
+-static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
+-			      unsigned long address, unsigned long size,
+-			      swp_entry_t entry, struct page *page)
+-{
+-	pmd_t * pmd;
+-	unsigned long offset, end;
+-
+-	if (pgd_none(*dir))
+-		return;
+-	if (pgd_bad(*dir)) {
+-		pgd_ERROR(*dir);
+-		pgd_clear(dir);
+-		return;
+-	}
+-	pmd = pmd_offset(dir, address);
+-	offset = address & PGDIR_MASK;
+-	address &= ~PGDIR_MASK;
+-	end = address + size;
+-	if (end > PGDIR_SIZE)
+-		end = PGDIR_SIZE;
+-	do {
+-		unswap_pmd(vma, pmd, address, end - address, offset, entry,
+-			   page);
+-		address = (address + PMD_SIZE) & PMD_MASK;
+-		pmd++;
+-	} while (address < end);
+-}
+-
+-static void unswap_vma(struct vm_area_struct * vma, pgd_t *pgdir,
+-		       swp_entry_t entry, struct page *page)
+-{
+-	unsigned long start = vma->vm_start, end = vma->vm_end;
+-
+-	do {
+-		unswap_pgd(vma, pgdir, start, end - start, entry, page);
+-		start = (start + PGDIR_SIZE) & PGDIR_MASK;
+-		pgdir++;
+-	} while (start < end);
+-}
+-
+-static void unswap_process(struct mm_struct * mm, swp_entry_t entry,
+-			   struct page *page)
+-{
+-	struct vm_area_struct* vma;
+-
+-	/*
+-	 * Go through process' page directory.
+-	 */
+-	if (!mm)
+-		return;
+-	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+-		pgd_t * pgd = pgd_offset(mm, vma->vm_start);
+-		unswap_vma(vma, pgd, entry, page);
+-	}
+-}
+-
+-
+-static int unswap_by_read(unsigned short *map, unsigned long max,
+-			  unsigned long start, unsigned long n_pages)
+-{
+-	struct task_struct *p;
+-	struct page *page;
+-	swp_entry_t entry;
+-	unsigned long i;
+-
+-	DPRINTK( "unswapping %lu..%lu by reading in\n",
+-			 start, start+n_pages-1 );
+-
+-	for( i = start; i < start+n_pages; ++i ) {
+-		if (map[i] == SWAP_MAP_BAD) {
+-			printk( KERN_ERR "get_stram_region: page %lu already "
+-					"reserved??\n", i );
+-			continue;
+-		}
+-
+-		if (map[i]) {
+-			entry = swp_entry(stram_swap_type, i);
+-			DPRINTK("unswap: map[i=%lu]=%u nr_swap=%ld\n",
+-				i, map[i], nr_swap_pages);
+-
+-			swap_device_lock(stram_swap_info);
+-			map[i]++;
+-			swap_device_unlock(stram_swap_info);
+-			/* Get a page for the entry, using the existing
+-			   swap cache page if there is one.  Otherwise,
+-			   get a clean page and read the swap into it. */
+-			page = read_swap_cache_async(entry, NULL, 0);
+-			if (!page) {
+-				swap_free(entry);
+-				return -ENOMEM;
+-			}
+-			read_lock(&tasklist_lock);
+-			for_each_process(p)
+-				unswap_process(p->mm, entry, page);
+-			read_unlock(&tasklist_lock);
+-			shmem_unuse(entry, page);
+-			/* Now get rid of the extra reference to the
+-			   temporary page we've been using. */
+-			if (PageSwapCache(page))
+-				delete_from_swap_cache(page);
+-			__free_page(page);
+-	#ifdef DO_PROC
+-			stat_swap_force++;
+-	#endif
+-		}
+-
+-		DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%ld\n",
+-				 i, map[i], nr_swap_pages );
+-		swap_list_lock();
+-		swap_device_lock(stram_swap_info);
+-		map[i] = SWAP_MAP_BAD;
+-		if (stram_swap_info->lowest_bit == i)
+-			stram_swap_info->lowest_bit++;
+-		if (stram_swap_info->highest_bit == i)
+-			stram_swap_info->highest_bit--;
+-		--nr_swap_pages;
+-		swap_device_unlock(stram_swap_info);
+-		swap_list_unlock();
+-	}
+-
+-	return 0;
+-}
+-
+-/*
+- * reserve a region in ST-RAM swap space for an allocation
+- */
+-static void *get_stram_region( unsigned long n_pages )
+-{
+-	unsigned short *map = stram_swap_info->swap_map;
+-	unsigned long max = stram_swap_info->max;
+-	unsigned long start, total_free, region_free;
+-	int err;
+-	void *ret = NULL;
+-
+-	DPRINTK( "get_stram_region(n_pages=%lu)\n", n_pages );
+-
+-	down(&stram_swap_sem);
+-
+-	/* disallow writing to the swap device now */
+-	stram_swap_info->flags = SWP_USED;
+-
+-	/* find a region of n_pages pages in the swap space including as much free
+-	 * pages as possible (and excluding any already-reserved pages). */
+-	if (!(start = find_free_region( n_pages, &total_free, &region_free )))
+-		goto end;
+-	DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n",
+-			 start, region_free );
+-
+-	err = unswap_by_read(map, max, start, n_pages);
+-	if (err)
+-		goto end;
+-
+-	ret = SWAP_ADDR(start);
+-  end:
+-	/* allow using swap device again */
+-	stram_swap_info->flags = SWP_WRITEOK;
+-	up(&stram_swap_sem);
+-	DPRINTK( "get_stram_region: returning %p\n", ret );
+-	return( ret );
+-}
+-
+-
+-/*
+- * free a reserved region in ST-RAM swap space
+- */
+-static void free_stram_region( unsigned long offset, unsigned long n_pages )
+-{
+-	unsigned short *map = stram_swap_info->swap_map;
+-
+-	DPRINTK( "free_stram_region(offset=%lu,n_pages=%lu)\n", offset, n_pages );
+-
+-	if (offset < 1 || offset + n_pages > stram_swap_info->max) {
+-		printk( KERN_ERR "free_stram_region: Trying to free non-ST-RAM\n" );
+-		return;
+-	}
+-
+-	swap_list_lock();
+-	swap_device_lock(stram_swap_info);
+-	/* un-reserve the freed pages */
+-	for( ; n_pages > 0; ++offset, --n_pages ) {
+-		if (map[offset] != SWAP_MAP_BAD)
+-			printk( KERN_ERR "free_stram_region: Swap page %lu was not "
+-					"reserved\n", offset );
+-		map[offset] = 0;
+-	}
+-
+-	/* update swapping meta-data */
+-	if (offset < stram_swap_info->lowest_bit)
+-		stram_swap_info->lowest_bit = offset;
+-	if (offset+n_pages-1 > stram_swap_info->highest_bit)
+-		stram_swap_info->highest_bit = offset+n_pages-1;
+-	if (stram_swap_info->prio > swap_info[swap_list.next].prio)
+-		swap_list.next = swap_list.head;
+-	nr_swap_pages += n_pages;
+-	swap_device_unlock(stram_swap_info);
+-	swap_list_unlock();
+-}
+-
+-
+-/* ------------------------------------------------------------------------ */
+-/*						Utility Functions for Swapping						*/
+-/* ------------------------------------------------------------------------ */
+-
+-
+-/* is addr in some of the allocated regions? */
+-static int in_some_region(void *addr)
+-{
+-	BLOCK *p;
+-
+-	for( p = alloc_list; p; p = p->next ) {
+-		if (p->start <= addr && addr < p->start + p->size)
+-			return( 1 );
+-	}
+-	return( 0 );
+-}
+-
+-
+-static unsigned long find_free_region(unsigned long n_pages,
+-				      unsigned long *total_free,
+-				      unsigned long *region_free)
+-{
+-	unsigned short *map = stram_swap_info->swap_map;
+-	unsigned long max = stram_swap_info->max;
+-	unsigned long head, tail, max_start;
+-	long nfree, max_free;
+-
+-	/* first scan the swap space for a suitable place for the allocation */
+-	head = 1;
+-	max_start = 0;
+-	max_free = -1;
+-	*total_free = 0;
+-
+-  start_over:
+-	/* increment tail until final window size reached, and count free pages */
+-	nfree = 0;
+-	for( tail = head; tail-head < n_pages && tail < max; ++tail ) {
+-		if (map[tail] == SWAP_MAP_BAD) {
+-			head = tail+1;
+-			goto start_over;
+-		}
+-		if (!map[tail]) {
+-			++nfree;
+-			++*total_free;
+-		}
+-	}
+-	if (tail-head < n_pages)
+-		goto out;
+-	if (nfree > max_free) {
+-		max_start = head;
+-		max_free  = nfree;
+-		if (max_free >= n_pages)
+-			/* don't need more free pages... :-) */
+-			goto out;
+-	}
+-
+-	/* now shift the window and look for the area where as much pages as
+-	 * possible are free */
+-	while( tail < max ) {
+-		nfree -= (map[head++] == 0);
+-		if (map[tail] == SWAP_MAP_BAD) {
+-			head = tail+1;
+-			goto start_over;
+-		}
+-		if (!map[tail]) {
+-			++nfree;
+-			++*total_free;
+-		}
+-		++tail;
+-		if (nfree > max_free) {
+-			max_start = head;
+-			max_free  = nfree;
+-			if (max_free >= n_pages)
+-				/* don't need more free pages... :-) */
+-				goto out;
+-		}
+-	}
+-
+-  out:
+-	if (max_free < 0) {
+-		printk( KERN_NOTICE "get_stram_region: ST-RAM too full or fragmented "
+-				"-- can't allocate %lu pages\n", n_pages );
+-		return( 0 );
+-	}
+-
+-	*region_free = max_free;
+-	return( max_start );
+-}
+-
+-
+-/* setup parameters from command line */
+-void __init stram_swap_setup(char *str, int *ints)
+-{
+-	if (ints[0] >= 1)
+-		max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK;
+-}
+-
+-
+-/* ------------------------------------------------------------------------ */
+-/*								ST-RAM device								*/
+-/* ------------------------------------------------------------------------ */
+-
+-static int refcnt;
+-
+-static void do_stram_request(request_queue_t *q)
+-{
+-	struct request *req;
+-
+-	while ((req = elv_next_request(q)) != NULL) {
+-		void *start = swap_start + (req->sector << 9);
+-		unsigned long len = req->current_nr_sectors << 9;
+-		if ((start + len) > swap_end) {
+-			printk( KERN_ERR "stram: bad access beyond end of device: "
+-					"block=%ld, count=%d\n",
+-					req->sector,
+-					req->current_nr_sectors );
+-			end_request(req, 0);
+-			continue;
+-		}
+-
+-		if (req->cmd == READ) {
+-			memcpy(req->buffer, start, len);
+-#ifdef DO_PROC
+-			stat_swap_read += N_PAGES(len);
+-#endif
+-		}
+-		else {
+-			memcpy(start, req->buffer, len);
+-#ifdef DO_PROC
+-			stat_swap_write += N_PAGES(len);
+-#endif
+-		}
+-		end_request(req, 1);
+-	}
+-}
+-
+-
+-static int stram_open( struct inode *inode, struct file *filp )
+-{
+-	if (filp != MAGIC_FILE_P) {
+-		printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );
+-		return( -EPERM );
+-	}
+-	if (refcnt)
+-		return( -EBUSY );
+-	++refcnt;
+-	return( 0 );
+-}
+-
+-static int stram_release( struct inode *inode, struct file *filp )
+-{
+-	if (filp != MAGIC_FILE_P) {
+-		printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );
+-		return( -EPERM );
+-	}
+-	if (refcnt > 0)
+-		--refcnt;
+-	return( 0 );
+-}
+-
+-
+-static struct block_device_operations stram_fops = {
+-	.open =		stram_open,
+-	.release =	stram_release,
+-};
+-
+-static struct gendisk *stram_disk;
+-static struct request_queue *stram_queue;
+-static DEFINE_SPINLOCK(stram_lock);
+-
+-int __init stram_device_init(void)
+-{
+-	if (!MACH_IS_ATARI)
+-		/* no point in initializing this, I hope */
+-		return -ENXIO;
+-
+-	if (!max_swap_size)
+-		/* swapping not enabled */
+-		return -ENXIO;
+-	stram_disk = alloc_disk(1);
+-	if (!stram_disk)
+-		return -ENOMEM;
+-
+-	if (register_blkdev(STRAM_MAJOR, "stram")) {
+-		put_disk(stram_disk);
+-		return -ENXIO;
+-	}
+-
+-	stram_queue = blk_init_queue(do_stram_request, &stram_lock);
+-	if (!stram_queue) {
+-		unregister_blkdev(STRAM_MAJOR, "stram");
+-		put_disk(stram_disk);
+-		return -ENOMEM;
+-	}
+-
+-	stram_disk->major = STRAM_MAJOR;
+-	stram_disk->first_minor = STRAM_MINOR;
+-	stram_disk->fops = &stram_fops;
+-	stram_disk->queue = stram_queue;
+-	sprintf(stram_disk->disk_name, "stram");
+-	set_capacity(stram_disk, (swap_end - swap_start)/512);
+-	add_disk(stram_disk);
+-	return 0;
+-}
+-
+-
+-
+-/* ------------------------------------------------------------------------ */
+-/*							Misc Utility Functions							*/
+-/* ------------------------------------------------------------------------ */
+-
+-/* reserve a range of pages */
+-static void reserve_region(void *start, void *end)
+-{
+-	reserve_bootmem (virt_to_phys(start), end - start);
+-}
+-
+-#endif /* CONFIG_STRAM_SWAP */
+-
+ 
+ /* ------------------------------------------------------------------------ */
+ /*							  Region Management								*/
+@@ -1173,50 +328,9 @@ int get_stram_list( char *buf )
+ {
+ 	int len = 0;
+ 	BLOCK *p;
+-#ifdef CONFIG_STRAM_SWAP
+-	int i;
+-	unsigned short *map = stram_swap_info->swap_map;
+-	unsigned long max = stram_swap_info->max;
+-	unsigned free = 0, used = 0, rsvd = 0;
+-#endif
+ 
+-#ifdef CONFIG_STRAM_SWAP
+-	if (max_swap_size) {
+-		for( i = 1; i < max; ++i ) {
+-			if (!map[i])
+-				++free;
+-			else if (map[i] == SWAP_MAP_BAD)
+-				++rsvd;
+-			else
+-				++used;
+-		}
+-		PRINT_PROC(
+-			"Total ST-RAM:      %8u kB\n"
+-			"Total ST-RAM swap: %8lu kB\n"
+-			"Free swap:         %8u kB\n"
+-			"Used swap:         %8u kB\n"
+-			"Allocated swap:    %8u kB\n"
+-			"Swap Reads:        %8u\n"
+-			"Swap Writes:       %8u\n"
+-			"Swap Forced Reads: %8u\n",
+-			(stram_end - stram_start) >> 10,
+-			(max-1) << (PAGE_SHIFT-10),
+-			free << (PAGE_SHIFT-10),
+-			used << (PAGE_SHIFT-10),
+-			rsvd << (PAGE_SHIFT-10),
+-			stat_swap_read,
+-			stat_swap_write,
+-			stat_swap_force );
+-	}
+-	else {
+-#endif
+-		PRINT_PROC( "ST-RAM swapping disabled\n" );
+-		PRINT_PROC("Total ST-RAM:      %8u kB\n",
++	PRINT_PROC("Total ST-RAM:      %8u kB\n",
+ 			   (stram_end - stram_start) >> 10);
+-#ifdef CONFIG_STRAM_SWAP
+-	}
+-#endif
+-
+ 	PRINT_PROC( "Allocated regions:\n" );
+ 	for( p = alloc_list; p; p = p->next ) {
+ 		if (len + 50 >= PAGE_SIZE)
+@@ -1227,8 +341,6 @@ int get_stram_list( char *buf )
+ 			   p->owner);
+ 		if (p->flags & BLOCK_GFP)
+ 			PRINT_PROC( "page-alloced)\n" );
+-		else if (p->flags & BLOCK_INSWAP)
+-			PRINT_PROC( "in swap)\n" );
+ 		else
+ 			PRINT_PROC( "??)\n" );
+ 	}
+diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
+--- a/arch/m68k/kernel/ptrace.c
++++ b/arch/m68k/kernel/ptrace.c
+@@ -121,7 +121,7 @@ void ptrace_disable(struct task_struct *
+ 	child->thread.work.syscall_trace = 0;
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	unsigned long tmp;
+diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
+--- a/arch/m68k/kernel/time.c
++++ b/arch/m68k/kernel/time.c
+@@ -27,10 +27,6 @@
+ #include <linux/timex.h>
+ #include <linux/profile.h>
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ static inline int set_rtc_mmss(unsigned long nowtime)
+ {
+   if (mach_set_clock_mmss)
+diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
+--- a/arch/m68k/mm/kmap.c
++++ b/arch/m68k/mm/kmap.c
+@@ -201,7 +201,7 @@ void *__ioremap(unsigned long physaddr, 
+ 			virtaddr += PTRTREESIZE;
+ 			size -= PTRTREESIZE;
+ 		} else {
+-			pte_dir = pte_alloc_kernel(&init_mm, pmd_dir, virtaddr);
++			pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
+ 			if (!pte_dir) {
+ 				printk("ioremap: no mem for pte_dir\n");
+ 				return NULL;
+diff --git a/arch/m68k/sun3x/dvma.c b/arch/m68k/sun3x/dvma.c
+--- a/arch/m68k/sun3x/dvma.c
++++ b/arch/m68k/sun3x/dvma.c
+@@ -116,7 +116,7 @@ inline int dvma_map_cpu(unsigned long ka
+ 			pte_t *pte;
+ 			unsigned long end3;
+ 
+-			if((pte = pte_alloc_kernel(&init_mm, pmd, vaddr)) == NULL) {
++			if((pte = pte_alloc_kernel(pmd, vaddr)) == NULL) {
+ 				ret = -ENOMEM;
+ 				goto out;
+ 			}
+diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig
+--- a/arch/m68knommu/defconfig
++++ b/arch/m68knommu/defconfig
+@@ -99,7 +99,7 @@ CONFIG_M5272C3=y
+ # CONFIG_NETtel is not set
+ # CONFIG_CPU16B is not set
+ # CONFIG_MOD5272 is not set
+-CONFIG_MOTOROLA=y
++CONFIG_FREESCALE=y
+ # CONFIG_LARGE_ALLOCS is not set
+ CONFIG_4KSTACKS=y
+ CONFIG_RAMAUTO=y
+@@ -554,7 +554,6 @@ CONFIG_EXT2_FS=y
+ # CONFIG_XFS_FS is not set
+ # CONFIG_MINIX_FS is not set
+ CONFIG_ROMFS_FS=y
+-CONFIG_MAGIC_ROM_PTR=y
+ # CONFIG_INOTIFY is not set
+ # CONFIG_QUOTA is not set
+ # CONFIG_DNOTIFY is not set
+diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
+--- a/arch/m68knommu/kernel/ptrace.c
++++ b/arch/m68knommu/kernel/ptrace.c
+@@ -101,7 +101,7 @@ void ptrace_disable(struct task_struct *
+ 	put_reg(child, PT_SR, tmp);
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	int ret;
+diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
+--- a/arch/m68knommu/kernel/time.c
++++ b/arch/m68knommu/kernel/time.c
+@@ -27,10 +27,6 @@
+ 
+ #define	TICK_SIZE (tick_nsec / 1000)
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ extern unsigned long wall_jiffies;
+ 
+ 
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -4,216 +4,147 @@ config MIPS
+ 	# Horrible source of confusion.  Die, die, die ...
+ 	select EMBEDDED
+ 
+-# shouldn't it be per-subarchitecture?
+-config ARCH_MAY_HAVE_PC_FDC
+-	bool
+-	default y
+-
+ mainmenu "Linux/MIPS Kernel Configuration"
+ 
+ source "init/Kconfig"
+ 
+-config SYS_SUPPORTS_32BIT_KERNEL
+-	bool
+-config SYS_SUPPORTS_64BIT_KERNEL
+-	bool
+-config CPU_SUPPORTS_32BIT_KERNEL
+-	bool
+-config CPU_SUPPORTS_64BIT_KERNEL
+-	bool
+-
+-menu "Kernel type"
+-
+-choice
+-
+-	prompt "Kernel code model"
+-	help
+-	  You should only select this option if you have a workload that
+-	  actually benefits from 64-bit processing or if your machine has
+-	  large memory.  You will only be presented a single option in this
+-	  menu if your system does not support both 32-bit and 64-bit kernels.
+-
+-config 32BIT
+-	bool "32-bit kernel"
+-	depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL
+-	select TRAD_SIGNALS
+-	help
+-	  Select this option if you want to build a 32-bit kernel.
+-
+-config 64BIT
+-	bool "64-bit kernel"
+-	depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
+-	help
+-	  Select this option if you want to build a 64-bit kernel.
+-
+-endchoice
+-
+-endmenu
+-
+ menu "Machine selection"
+ 
+-config MACH_JAZZ
+-	bool "Support for the Jazz family of machines"
+-	select ARC
+-	select ARC32
+-	select GENERIC_ISA_DMA
+-	select I8259
+-	select ISA
+-	select SYS_SUPPORTS_32BIT_KERNEL
+-	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+-	help
+-	 This a family of machines based on the MIPS R4030 chipset which was
+-	 used by several vendors to build RISC/os and Windows NT workstations.
+-	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
+-	 Olivetti M700-10 workstations.
++choice
++	prompt "System type"
++	default SGI_IP22
+ 
+-config ACER_PICA_61
+-	bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
+-	depends on MACH_JAZZ && EXPERIMENTAL
++config MIPS_MTX1
++	bool "Support for 4G Systems MTX-1 board"
+ 	select DMA_NONCOHERENT
+-	help
+-	  This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
+-	  kernel that runs on these, say Y here. For details about Linux on
+-	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+-	  <http://www.linux-mips.org/>.
++	select HW_HAS_PCI
++	select SOC_AU1500
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config MIPS_MAGNUM_4000
+-	bool "Support for MIPS Magnum 4000"
+-	depends on MACH_JAZZ
++config MIPS_BOSPORUS
++	bool "AMD Alchemy Bosporus board"
++	select SOC_AU1500
+ 	select DMA_NONCOHERENT
+-	help
+-	  This is a machine with a R4000 100 MHz CPU. To compile a Linux
+-	  kernel that runs on these, say Y here. For details about Linux on
+-	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+-	  <http://www.linux-mips.org/>.
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config OLIVETTI_M700
+-	bool "Support for Olivetti M700-10"
+-	depends on MACH_JAZZ
++config MIPS_PB1000
++	bool "AMD Alchemy PB1000 board"
++	select SOC_AU1000
+ 	select DMA_NONCOHERENT
+-	help
+-	  This is a machine with a R4000 100 MHz CPU. To compile a Linux
+-	  kernel that runs on these, say Y here. For details about Linux on
+-	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+-	  <http://www.linux-mips.org/>.
+-
+-config MACH_VR41XX
+-	bool "Support for NEC VR4100 series based machines"
+-	select SYS_SUPPORTS_32BIT_KERNEL
+-	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select HW_HAS_PCI
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config NEC_CMBVR4133
+-	bool "Support for NEC CMB-VR4133"
+-	depends on MACH_VR41XX
+-	select CPU_VR41XX
++config MIPS_PB1100
++	bool "AMD Alchemy PB1100 board"
++	select SOC_AU1100
+ 	select DMA_NONCOHERENT
+-	select IRQ_CPU
+ 	select HW_HAS_PCI
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config ROCKHOPPER
+-	bool "Support for Rockhopper baseboard"
+-	depends on NEC_CMBVR4133
+-	select I8259
+-	select HAVE_STD_PC_SERIAL_PORT
++config MIPS_PB1500
++	bool "AMD Alchemy PB1500 board"
++	select SOC_AU1500
++	select DMA_NONCOHERENT
++	select HW_HAS_PCI
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config CASIO_E55
+-	bool "Support for CASIO CASSIOPEIA E-10/15/55/65"
+-	depends on MACH_VR41XX
+-	select CPU_LITTLE_ENDIAN
++config MIPS_PB1550
++	bool "AMD Alchemy PB1550 board"
++	select SOC_AU1550
+ 	select DMA_NONCOHERENT
+-	select IRQ_CPU
+-	select ISA
++	select HW_HAS_PCI
++	select MIPS_DISABLE_OBSOLETE_IDE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config IBM_WORKPAD
+-	bool "Support for IBM WorkPad z50"
+-	depends on MACH_VR41XX
+-	select CPU_LITTLE_ENDIAN
++config MIPS_PB1200
++	bool "AMD Alchemy PB1200 board"
++	select SOC_AU1200
+ 	select DMA_NONCOHERENT
+-	select IRQ_CPU
+-	select ISA
++	select MIPS_DISABLE_OBSOLETE_IDE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config TANBAC_TB022X
+-	bool "Support for TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
+-	depends on MACH_VR41XX
+-	select CPU_LITTLE_ENDIAN
++config MIPS_DB1000
++	bool "AMD Alchemy DB1000 board"
++	select SOC_AU1000
+ 	select DMA_NONCOHERENT
+-	select IRQ_CPU
+ 	select HW_HAS_PCI
+-	help
+-	  The TANBAC VR4131 multichip module(TB0225) and
+-	  the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms
+-	  manufactured by TANBAC.
+-	  Please refer to <http://www.tanbac.co.jp/>
+-	  about VR4131 multichip module and VR4131DIMM.
+-
+-config TANBAC_TB0226
+-	bool "Support for TANBAC Mbase(TB0226)"
+-	depends on TANBAC_TB022X
+-	select GPIO_VR41XX
+-	help
+-	  The TANBAC Mbase(TB0226) is a MIPS-based platform manufactured by TANBAC.
+-	  Please refer to <http://www.tanbac.co.jp/> about Mbase.
+-
+-config TANBAC_TB0287
+-	bool "Support for TANBAC Mini-ITX DIMM base(TB0287)"
+-	depends on TANBAC_TB022X
+-	help
+-	  The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform manufactured by TANBAC.
+-	  Please refer to <http://www.tanbac.co.jp/> about Mini-ITX DIMM base.
+-
+-config VICTOR_MPC30X
+-	bool "Support for Victor MP-C303/304"
+-	depends on MACH_VR41XX
+-	select CPU_LITTLE_ENDIAN
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++
++config MIPS_DB1100
++	bool "AMD Alchemy DB1100 board"
++	select SOC_AU1100
+ 	select DMA_NONCOHERENT
+-	select IRQ_CPU
+-	select HW_HAS_PCI
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config ZAO_CAPCELLA
+-	bool "Support for ZAO Networks Capcella"
+-	depends on MACH_VR41XX
+-	select CPU_LITTLE_ENDIAN
++config MIPS_DB1500
++	bool "AMD Alchemy DB1500 board"
++	select SOC_AU1500
+ 	select DMA_NONCOHERENT
+-	select IRQ_CPU
+ 	select HW_HAS_PCI
++	select MIPS_DISABLE_OBSOLETE_IDE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config PCI_VR41XX
+-	bool "Add PCI control unit support of NEC VR4100 series"
+-	depends on MACH_VR41XX && HW_HAS_PCI
+-	default y
+-	select PCI
++config MIPS_DB1550
++	bool "AMD Alchemy DB1550 board"
++	select SOC_AU1550
++	select HW_HAS_PCI
++	select DMA_NONCOHERENT
++	select MIPS_DISABLE_OBSOLETE_IDE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config VRC4173
+-	tristate "Add NEC VRC4173 companion chip support"
+-	depends on MACH_VR41XX && PCI_VR41XX
+-	---help---
+-	  The NEC VRC4173 is a companion chip for NEC VR4122/VR4131.
++config MIPS_DB1200
++	bool "AMD Alchemy DB1200 board"
++	select SOC_AU1200
++	select DMA_COHERENT
++	select MIPS_DISABLE_OBSOLETE_IDE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+-config TOSHIBA_JMR3927
+-	bool "Support for Toshiba JMR-TX3927 board"
++config MIPS_MIRAGE
++	bool "AMD Alchemy Mirage board"
+ 	select DMA_NONCOHERENT
+-	select HW_HAS_PCI
+-	select SWAP_IO_SPACE
+-	select SYS_SUPPORTS_32BIT_KERNEL
++	select SOC_AU1500
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config MIPS_COBALT
+ 	bool "Support for Cobalt Server"
+-	depends on EXPERIMENTAL
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select I8259
+ 	select IRQ_CPU
++	select MIPS_GT64111
++	select SYS_HAS_CPU_NEVADA
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config MACH_DECSTATION
+ 	bool "Support for DECstations"
+ 	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
++	select EARLY_PRINTK
+ 	select IRQ_CPU
++	select SYS_HAS_CPU_R3000
++	select SYS_HAS_CPU_R4X00
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+-	---help---
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++	help
+ 	  This enables support for DEC's MIPS based workstations.  For details
+ 	  see the Linux/MIPS FAQ on <http://www.linux-mips.org/> and the
+ 	  DECstation porting pages on <http://decstation.unix-ag.org/>.
+@@ -234,8 +165,10 @@ config MIPS_EV64120
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select MIPS_GT64120
++	select SYS_HAS_CPU_R5000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+ 	  This is an evaluation board based on the Galileo GT-64120
+ 	  single-chip system controller that contains a MIPS R5000 compatible
+@@ -243,10 +176,6 @@ config MIPS_EV64120
+ 	  <http://www.marvell.com/>.  Say Y here if you wish to build a
+ 	  kernel for this platform.
+ 
+-config EVB_PCI1
+-	bool "Enable Second PCI (PCI1)"
+-	depends on MIPS_EV64120
+-
+ config MIPS_EV96100
+ 	bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)"
+ 	depends on EXPERIMENTAL
+@@ -256,8 +185,11 @@ config MIPS_EV96100
+ 	select MIPS_GT96100
+ 	select RM7000_CPU_SCACHE
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_R5000
++	select SYS_HAS_CPU_RM7000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+-	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+ 	  This is an evaluation board based on the Galileo GT-96100 LAN/WAN
+ 	  communications controllers containing a MIPS R5000 compatible core
+@@ -268,8 +200,11 @@ config MIPS_IVR
+ 	bool "Support for Globespan IVR board"
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
++	select ITE_BOARD_GEN
++	select SYS_HAS_CPU_NEVADA
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	help
+ 	  This is an evaluation board built by Globespan to showcase thir
+ 	  iVR (Internet Video Recorder) design. It utilizes a QED RM5231
+@@ -277,37 +212,16 @@ config MIPS_IVR
+ 	  located at <http://www.globespan.net/>. Say Y here if you wish to
+ 	  build a kernel for this platform.
+ 
+-config LASAT
+-	bool "Support for LASAT Networks platforms"
+-	select DMA_NONCOHERENT
+-	select HW_HAS_PCI
+-	select MIPS_GT64120
+-	select R5000_CPU_SCACHE
+-	select SYS_SUPPORTS_32BIT_KERNEL
+-	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+-
+-config PICVUE
+-	tristate "PICVUE LCD display driver"
+-	depends on LASAT
+-
+-config PICVUE_PROC
+-	tristate "PICVUE LCD display driver /proc interface"
+-	depends on PICVUE
+-
+-config DS1603
+-	bool "DS1603 RTC driver"
+-	depends on LASAT
+-
+-config LASAT_SYSCTL
+-	bool "LASAT sysctl interface"
+-	depends on LASAT
+-
+ config MIPS_ITE8172
+ 	bool "Support for ITE 8172G board"
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
++	select ITE_BOARD_GEN
++	select SYS_HAS_CPU_R5432
++	select SYS_HAS_CPU_NEVADA
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	help
+ 	  Ths is an evaluation board made by ITE <http://www.ite.com.tw/>
+ 	  with ATX form factor that utilizes a MIPS R5000 to work with its
+@@ -315,42 +229,86 @@ config MIPS_ITE8172
+ 	  either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build
+ 	  a kernel for this platform.
+ 
+-config IT8172_REVC
+-	bool "Support for older IT8172 (Rev C)"
+-	depends on MIPS_ITE8172
++config MACH_JAZZ
++	bool "Support for the Jazz family of machines"
++	select ARC
++	select ARC32
++	select ARCH_MAY_HAVE_PC_FDC
++	select GENERIC_ISA_DMA
++	select I8259
++	select ISA
++	select SYS_HAS_CPU_R4X00
++	select SYS_SUPPORTS_32BIT_KERNEL
++	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ 	help
+-	  Say Y here to support the older, Revision C version of the Integrated
+-	  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+-	  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+-	  board at <http://www.mvista.com/partners/semiconductor/ite.html>.
++	 This a family of machines based on the MIPS R4030 chipset which was
++	 used by several vendors to build RISC/os and Windows NT workstations.
++	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
++	 Olivetti M700-10 workstations.
++
++config LASAT
++	bool "Support for LASAT Networks platforms"
++	select DMA_NONCOHERENT
++	select HW_HAS_PCI
++	select MIPS_GT64120
++	select MIPS_NILE4
++	select R5000_CPU_SCACHE
++	select SYS_HAS_CPU_R5000
++	select SYS_SUPPORTS_32BIT_KERNEL
++	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config MIPS_ATLAS
+ 	bool "Support for MIPS Atlas board"
+ 	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
++	select IRQ_CPU
+ 	select HW_HAS_PCI
++	select MIPS_BOARDS_GEN
++	select MIPS_BONITO64
+ 	select MIPS_GT64120
++	select MIPS_MSC
++	select RM7000_CPU_SCACHE
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_HAS_CPU_MIPS32_R2
++	select SYS_HAS_CPU_MIPS64_R1
++	select SYS_HAS_CPU_NEVADA
++	select SYS_HAS_CPU_RM7000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	help
+-	  This enables support for the QED R5231-based MIPS Atlas evaluation
++	  This enables support for the MIPS Technologies Atlas evaluation
+ 	  board.
+ 
+ config MIPS_MALTA
+ 	bool "Support for MIPS Malta board"
++	select ARCH_MAY_HAVE_PC_FDC
+ 	select BOOT_ELF32
+ 	select HAVE_STD_PC_SERIAL_PORT
+ 	select DMA_NONCOHERENT
++	select IRQ_CPU
+ 	select GENERIC_ISA_DMA
+ 	select HW_HAS_PCI
+ 	select I8259
++	select MIPS_BOARDS_GEN
++	select MIPS_BONITO64
+ 	select MIPS_GT64120
++	select MIPS_MSC
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_HAS_CPU_MIPS32_R2
++	select SYS_HAS_CPU_MIPS64_R1
++	select SYS_HAS_CPU_NEVADA
++	select SYS_HAS_CPU_RM7000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	help
+-	  This enables support for the VR5000-based MIPS Malta evaluation
++	  This enables support for the MIPS Technologies Malta evaluation
+ 	  board.
+ 
+ config MIPS_SEAD
+@@ -358,50 +316,64 @@ config MIPS_SEAD
+ 	depends on EXPERIMENTAL
+ 	select IRQ_CPU
+ 	select DMA_NONCOHERENT
++	select MIPS_BOARDS_GEN
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_HAS_CPU_MIPS32_R2
++	select SYS_HAS_CPU_MIPS64_R1
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+-	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++	help
++	  This enables support for the MIPS Technologies SEAD evaluation
++	  board.
+ 
+-config MOMENCO_OCELOT
+-	bool "Support for Momentum Ocelot board"
++config MIPS_SIM
++	bool 'Support for MIPS simulator (MIPSsim)'
+ 	select DMA_NONCOHERENT
+-	select HW_HAS_PCI
+ 	select IRQ_CPU
+-	select IRQ_CPU_RM7K
+-	select MIPS_GT64120
+-	select RM7000_CPU_SCACHE
+-	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_HAS_CPU_MIPS32_R2
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+-	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	help
+-	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+-	  Momentum Computer <http://www.momenco.com/>.
++	  This option enables support for MIPS Technologies MIPSsim software
++	  emulator.
+ 
+-config MOMENCO_OCELOT_G
+-	bool "Support for Momentum Ocelot-G board"
++config MOMENCO_JAGUAR_ATX
++	bool "Support for Momentum Jaguar board"
++	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+ 	select IRQ_CPU_RM7K
++	select IRQ_MV64340
++	select LIMITED_DMA
+ 	select PCI_MARVELL
+ 	select RM7000_CPU_SCACHE
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_RM9000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+-	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
++	  The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
+ 	  Momentum Computer <http://www.momenco.com/>.
+ 
+-config MOMENCO_OCELOT_C
+-	bool "Support for Momentum Ocelot-C board"
++config MOMENCO_OCELOT
++	bool "Support for Momentum Ocelot board"
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+-	select IRQ_MV64340
+-	select PCI_MARVELL
++	select IRQ_CPU_RM7K
++	select MIPS_GT64120
+ 	select RM7000_CPU_SCACHE
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_RM7000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+ 	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+ 	  Momentum Computer <http://www.momenco.com/>.
+@@ -417,80 +389,95 @@ config MOMENCO_OCELOT_3
+ 	select PCI_MARVELL
+ 	select RM7000_CPU_SCACHE
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_RM9000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+ 	  The Ocelot-3 is based off Discovery III System Controller and
+ 	  PMC-Sierra Rm79000 core.
+ 
+-config MOMENCO_JAGUAR_ATX
+-	bool "Support for Momentum Jaguar board"
+-	select BOOT_ELF32
++config MOMENCO_OCELOT_C
++	bool "Support for Momentum Ocelot-C board"
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+-	select IRQ_CPU_RM7K
+ 	select IRQ_MV64340
+-	select LIMITED_DMA
+ 	select PCI_MARVELL
+ 	select RM7000_CPU_SCACHE
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_RM7000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+-	  The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
++	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+ 	  Momentum Computer <http://www.momenco.com/>.
+ 
+-config JAGUAR_DMALOW
+-	bool "Low DMA Mode"
+-	depends on MOMENCO_JAGUAR_ATX
+-	help
+-	  Select to Y if jump JP5 is set on your board, N otherwise.  Normally
+-	  the jumper is set, so if you feel unsafe, just say Y.
+-
+-config PMC_YOSEMITE
+-	bool "Support for PMC-Sierra Yosemite eval board"
+-	select DMA_COHERENT
++config MOMENCO_OCELOT_G
++	bool "Support for Momentum Ocelot-G board"
++	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+ 	select IRQ_CPU_RM7K
+-	select IRQ_CPU_RM9K
++	select PCI_MARVELL
++	select RM7000_CPU_SCACHE
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_RM7000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+-	  Yosemite is an evaluation board for the RM9000x2 processor
+-	  manufactured by PMC-Sierra
++	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
++	  Momentum Computer <http://www.momenco.com/>.
+ 
+-config HYPERTRANSPORT
+-	bool "Hypertransport Support for PMC-Sierra Yosemite"
+-	depends on PMC_YOSEMITE
++config MIPS_XXS1500
++	bool "Support for MyCable XXS1500 board"
++	select DMA_NONCOHERENT
++	select SOC_AU1500
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++
++config PNX8550_V2PCI
++	bool "Support for Philips PNX8550 based Viper2-PCI board"
++	select PNX8550
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++
++config PNX8550_JBS
++	bool "Support for Philips PNX8550 based JBS board"
++	select PNX8550
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config DDB5074
+ 	bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)"
+ 	depends on EXPERIMENTAL
++	select DDB5XXX_COMMON
+ 	select DMA_NONCOHERENT
+ 	select HAVE_STD_PC_SERIAL_PORT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+ 	select I8259
+ 	select ISA
++	select SYS_HAS_CPU_R5000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+-	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	help
+ 	  This enables support for the VR5000-based NEC DDB Vrc-5074
+ 	  evaluation board.
+ 
+ config DDB5476
+ 	bool "Support for NEC DDB Vrc-5476"
++	select DDB5XXX_COMMON
+ 	select DMA_NONCOHERENT
+ 	select HAVE_STD_PC_SERIAL_PORT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+ 	select I8259
+ 	select ISA
++	select SYS_HAS_CPU_R5432
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	help
+ 	  This enables support for the R5432-based NEC DDB Vrc-5476
+ 	  evaluation board.
+@@ -501,12 +488,15 @@ config DDB5476
+ 
+ config DDB5477
+ 	bool "Support for NEC DDB Vrc-5477"
++	select DDB5XXX_COMMON
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select I8259
+ 	select IRQ_CPU
++	select SYS_HAS_CPU_R5432
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	help
+ 	  This enables support for the R5432-based NEC DDB Vrc-5477,
+ 	  or Rockhopper/SolutionGear boards with R5432/R5500 CPUs.
+@@ -514,10 +504,28 @@ config DDB5477
+ 	  Features : kernel debugging, serial terminal, NFS root fs, on-board
+ 	  ether port USB, AC97, PCI, etc.
+ 
+-config DDB5477_BUS_FREQUENCY
+-	int "bus frequency (in kHZ, 0 for auto-detect)"
+-	depends on DDB5477
+-	default 0
++config MACH_VR41XX
++	bool "Support for NEC VR4100 series based machines"
++	select SYS_HAS_CPU_VR41XX
++	select SYS_SUPPORTS_32BIT_KERNEL
++	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++
++config PMC_YOSEMITE
++	bool "Support for PMC-Sierra Yosemite eval board"
++	select DMA_COHERENT
++	select HW_HAS_PCI
++	select IRQ_CPU
++	select IRQ_CPU_RM7K
++	select IRQ_CPU_RM9K
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_RM9000
++	select SYS_SUPPORTS_32BIT_KERNEL
++	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_HIGHMEM
++	help
++	  Yosemite is an evaluation board for the RM9000x2 processor
++	  manufactured by PMC-Sierra.
+ 
+ config QEMU
+ 	bool "Support for Qemu"
+@@ -527,15 +535,16 @@ config QEMU
+ 	select I8259
+ 	select ISA
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_MIPS32_R1
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+-	 Qemu is a software emulator which among other architectures also
+-	 can simulate a MIPS32 4Kc system.  This patch adds support for the
+-	 system architecture that currently is being simulated by Qemu.  It
+-	 will eventually be removed again when Qemu has the capability to
+-	 simulate actual MIPS hardware platforms.  More information on Qemu
+-	 can be found at http://www.linux-mips.org/wiki/Qemu.
++	  Qemu is a software emulator which among other architectures also
++	  can simulate a MIPS32 4Kc system.  This patch adds support for the
++	  system architecture that currently is being simulated by Qemu.  It
++	  will eventually be removed again when Qemu has the capability to
++	  simulate actual MIPS hardware platforms.  More information on Qemu
++	  can be found at http://www.linux-mips.org/wiki/Qemu.
+ 
+ config SGI_IP22
+ 	bool "Support for SGI IP22 (Indy/Indigo2)"
+@@ -543,11 +552,15 @@ config SGI_IP22
+ 	select ARC32
+ 	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
++	select HW_HAS_EISA
+ 	select IP22_CPU_SCACHE
+ 	select IRQ_CPU
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_R4X00
++	select SYS_HAS_CPU_R5000
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+ 	  This are the SGI Indy, Challenge S and Indigo2, as well as certain
+ 	  OEM variants like the Tandem CMN B006S. To compile a Linux kernel
+@@ -557,70 +570,18 @@ config SGI_IP27
+ 	bool "Support for SGI IP27 (Origin200/2000)"
+ 	select ARC
+ 	select ARC64
++	select BOOT_ELF64
+ 	select DMA_IP27
+ 	select HW_HAS_PCI
+ 	select PCI_DOMAINS
++	select SYS_HAS_CPU_R10000
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+ 	  This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
+ 	  workstations.  To compile a Linux kernel that runs on these, say Y
+ 	  here.
+ 
+-#config SGI_SN0_XXL
+-#	bool "IP27 XXL"
+-#	depends on SGI_IP27
+-#	  This options adds support for userspace processes upto 16TB size.
+-#	  Normally the limit is just .5TB.
+-
+-config SGI_SN0_N_MODE
+-	bool "IP27 N-Mode"
+-	depends on SGI_IP27
+-	help
+-	  The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be
+-	  configured in either N-Modes which allows for more nodes or M-Mode
+-	  which allows for more memory.  Your system is most probably
+-	  running in M-Mode, so you should say N here.
+-
+-config ARCH_DISCONTIGMEM_ENABLE
+-	bool
+-	default y if SGI_IP27
+-	help
+-	  Say Y to upport efficient handling of discontiguous physical memory,
+-	  for architectures which are either NUMA (Non-Uniform Memory Access)
+-	  or have huge holes in the physical address space for other reasons.
+-	  See <file:Documentation/vm/numa> for more.
+-
+-config NUMA
+-	bool "NUMA Support"
+-	depends on SGI_IP27
+-	help
+-	  Say Y to compile the kernel to support NUMA (Non-Uniform Memory
+-	  Access).  This option is for configuring high-end multiprocessor
+-	  server machines.  If in doubt, say N.
+-
+-config MAPPED_KERNEL
+-	bool "Mapped kernel support"
+-	depends on SGI_IP27
+-	help
+-	  Change the way a Linux kernel is loaded into memory on a MIPS64
+-	  machine.  This is required in order to support text replication and
+-	  NUMA.  If you need to understand it, read the source code.
+-
+-config REPLICATE_KTEXT
+-	bool "Kernel text replication support"
+-	depends on SGI_IP27
+-	help
+-	  Say Y here to enable replicating the kernel text across multiple
+-	  nodes in a NUMA cluster.  This trades memory for speed.
+-
+-config REPLICATE_EXHANDLERS
+-	bool "Exception handler replication support"
+-	depends on SGI_IP27
+-	help
+-	  Say Y here to enable replicating the kernel exception handlers
+-	  across multiple nodes in a NUMA cluster. This trades memory for
+-	  speed.
+-
+ config SGI_IP32
+ 	bool "Support for SGI IP32 (O2) (EXPERIMENTAL)"
+ 	depends on EXPERIMENTAL
+@@ -633,353 +594,152 @@ config SGI_IP32
+ 	select HW_HAS_PCI
+ 	select R5000_CPU_SCACHE
+ 	select RM7000_CPU_SCACHE
++	select SYS_HAS_CPU_R5000
++	select SYS_HAS_CPU_R10000 if BROKEN
++	select SYS_HAS_CPU_RM7000
+ 	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
+ 	help
+ 	  If you want this kernel to run on SGI O2 workstation, say Y here.
+ 
+-config SOC_AU1X00
+-	bool "Support for AMD/Alchemy Au1X00 SOCs"
+-	select SYS_SUPPORTS_32BIT_KERNEL
+-
+-choice
+-	prompt "Au1X00 SOC Type"
+-	depends on SOC_AU1X00
+-	help
+-	  Say Y here to enable support for one of three AMD/Alchemy
+-	  SOCs. For additional documentation see www.amd.com.
+-
+-config SOC_AU1000
+-	bool "SOC_AU1000"
+-config SOC_AU1100
+-	bool "SOC_AU1100"
+-config SOC_AU1500
+-	bool "SOC_AU1500"
+-config SOC_AU1550
+-	bool "SOC_AU1550"
+-
+-endchoice
+-
+-choice
+-	prompt "AMD/Alchemy Au1x00 board support"
+-	depends on SOC_AU1X00
+-	help
+-	  These are evaluation boards built by AMD/Alchemy to
+-	  showcase their Au1X00 Internet Edge Processors. The SOC design
+-	  is based on the MIPS32 architecture running at 266/400/500MHz
+-	  with many integrated peripherals. Further information can be
+-	  found at their website, <http://www.amd.com/>. Say Y here if you
+-	  wish to build a kernel for this platform.
+-
+-config MIPS_PB1000
+-	bool "PB1000 board"
+-	depends on SOC_AU1000
+-	select DMA_NONCOHERENT
+-	select HW_HAS_PCI
+-	select SWAP_IO_SPACE
+-
+-config MIPS_PB1100
+-	bool "PB1100 board"
+-	depends on SOC_AU1100
+-	select DMA_NONCOHERENT
+-	select HW_HAS_PCI
+-	select SWAP_IO_SPACE
+-
+-config MIPS_PB1500
+-	bool "PB1500 board"
+-	depends on SOC_AU1500
+-	select DMA_COHERENT
+-	select HW_HAS_PCI
+-
+-config MIPS_PB1550
+-	bool "PB1550 board"
+-	depends on SOC_AU1550
+-	select DMA_COHERENT
+-	select HW_HAS_PCI
+-	select MIPS_DISABLE_OBSOLETE_IDE
+-
+-config MIPS_DB1000
+-	bool "DB1000 board"
+-	depends on SOC_AU1000
+-	select DMA_NONCOHERENT
+-	select HW_HAS_PCI
+-
+-config MIPS_DB1100
+-	bool "DB1100 board"
+-	depends on SOC_AU1100
+-	select DMA_NONCOHERENT
+-
+-config MIPS_DB1500
+-	bool "DB1500 board"
+-	depends on SOC_AU1500
+-	select DMA_COHERENT
+-	select HW_HAS_PCI
+-	select MIPS_DISABLE_OBSOLETE_IDE
+-
+-config MIPS_DB1550
+-	bool "DB1550 board"
+-	depends on SOC_AU1550
+-	select HW_HAS_PCI
+-	select DMA_COHERENT
+-	select MIPS_DISABLE_OBSOLETE_IDE
+-
+-config MIPS_BOSPORUS
+-	bool "Bosporus board"
+-	depends on SOC_AU1500
+-	select DMA_NONCOHERENT
+-
+-config MIPS_MIRAGE
+-	bool "Mirage board"
+-	depends on SOC_AU1500
+-	select DMA_NONCOHERENT
+-
+-config MIPS_XXS1500
+-	bool "MyCable XXS1500 board"
+-	depends on SOC_AU1500
+-	select DMA_NONCOHERENT
+-
+-config MIPS_MTX1
+-	bool "4G Systems MTX-1 board"
+-	depends on SOC_AU1500
+-	select HW_HAS_PCI
+-	select DMA_NONCOHERENT
+-
+-endchoice
+-
+-config SIBYTE_SB1xxx_SOC
+-	bool "Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)"
+-	depends on EXPERIMENTAL
++config SIBYTE_BIGSUR
++	bool "Support for Sibyte BigSur"
+ 	select BOOT_ELF32
+ 	select DMA_COHERENT
++	select PCI_DOMAINS
++	select SIBYTE_BCM1x80
+ 	select SWAP_IO_SPACE
+-	select SYS_SUPPORTS_32BIT_KERNEL
+-	select SYS_SUPPORTS_64BIT_KERNEL
+-
+-choice
+-	prompt "BCM1xxx SOC-based board"
+-	depends on SIBYTE_SB1xxx_SOC
+-	default SIBYTE_SWARM
+-	help
+-	  Enable support for boards based on the SiByte line of SOCs
+-	  from Broadcom.  There are configurations for the known
+-	  evaluation boards, or you can choose "Other" and add your
+-	  own board support code.
++	select SYS_HAS_CPU_SB1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config SIBYTE_SWARM
+-	bool "BCM91250A-SWARM"
++	bool "Support for Sibyte BCM91250A-SWARM"
++	select BOOT_ELF32
++	select DMA_COHERENT
+ 	select SIBYTE_SB1250
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_SB1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_HIGHMEM
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config SIBYTE_SENTOSA
+-	bool "BCM91250E-Sentosa"
++	bool "Support for Sibyte BCM91250E-Sentosa"
++	depends on EXPERIMENTAL
++	select BOOT_ELF32
++	select DMA_COHERENT
+ 	select SIBYTE_SB1250
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_SB1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config SIBYTE_RHONE
+-	bool "BCM91125E-Rhone"
++	bool "Support for Sibyte BCM91125E-Rhone"
++	depends on EXPERIMENTAL
++	select BOOT_ELF32
++	select DMA_COHERENT
+ 	select SIBYTE_BCM1125H
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_SB1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config SIBYTE_CARMEL
+-	bool "BCM91120x-Carmel"
++	bool "Support for Sibyte BCM91120x-Carmel"
++	depends on EXPERIMENTAL
++	select BOOT_ELF32
++	select DMA_COHERENT
+ 	select SIBYTE_BCM1120
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_SB1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config SIBYTE_PTSWARM
+-	bool "BCM91250PT-PTSWARM"
++	bool "Support for Sibyte BCM91250PT-PTSWARM"
++	depends on EXPERIMENTAL
++	select BOOT_ELF32
++	select DMA_COHERENT
+ 	select SIBYTE_SB1250
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_SB1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_HIGHMEM
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config SIBYTE_LITTLESUR
+-	bool "BCM91250C2-LittleSur"
++	bool "Support for Sibyte BCM91250C2-LittleSur"
++	depends on EXPERIMENTAL
++	select BOOT_ELF32
++	select DMA_COHERENT
+ 	select SIBYTE_SB1250
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_SB1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_HIGHMEM
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config SIBYTE_CRHINE
+-	bool "BCM91120C-CRhine"
++	bool "Support for Sibyte BCM91120C-CRhine"
++	depends on EXPERIMENTAL
++	select BOOT_ELF32
++	select DMA_COHERENT
+ 	select SIBYTE_BCM1120
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_SB1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config SIBYTE_CRHONE
+-	bool "BCM91125C-CRhone"
+-	select SIBYTE_BCM1125
+-
+-config SIBYTE_UNKNOWN
+-	bool "Other"
+-
+-endchoice
+-
+-config SIBYTE_BOARD
+-	bool
+-	depends on SIBYTE_SB1xxx_SOC && !SIBYTE_UNKNOWN
+-	default y
+-
+-choice
+-	prompt "BCM1xxx SOC Type"
+-	depends on SIBYTE_UNKNOWN
+-	default SIBYTE_UNK_BCM1250
+-	help
+-	  Since you haven't chosen a known evaluation board from
+-	  Broadcom, you must explicitly pick the SOC this kernel is
+-	  targetted for.
+-
+-config SIBYTE_UNK_BCM1250
+-	bool "BCM1250"
+-	select SIBYTE_SB1250
+-
+-config SIBYTE_UNK_BCM1120
+-	bool "BCM1120"
+-	select SIBYTE_BCM1120
+-
+-config SIBYTE_UNK_BCM1125
+-	bool "BCM1125"
++	bool "Support for Sibyte BCM91125C-CRhone"
++	depends on EXPERIMENTAL
++	select BOOT_ELF32
++	select DMA_COHERENT
+ 	select SIBYTE_BCM1125
+-
+-config SIBYTE_UNK_BCM1125H
+-	bool "BCM1125H"
+-	select SIBYTE_BCM1125H
+-
+-endchoice
+-
+-config SIBYTE_SB1250
+-	bool
+-	select HW_HAS_PCI
+-
+-config SIBYTE_BCM1120
+-	bool
+-	select SIBYTE_BCM112X
+-
+-config SIBYTE_BCM1125
+-	bool
+-	select HW_HAS_PCI
+-	select SIBYTE_BCM112X
+-
+-config SIBYTE_BCM1125H
+-	bool
+-	select HW_HAS_PCI
+-	select SIBYTE_BCM112X
+-
+-config SIBYTE_BCM112X
+-	bool
+-
+-choice
+-	prompt "SiByte SOC Stepping"
+-	depends on SIBYTE_SB1xxx_SOC
+-
+-config CPU_SB1_PASS_1
+-	bool "1250 Pass1"
+-	depends on SIBYTE_SB1250
+-	select CPU_HAS_PREFETCH
+-
+-config CPU_SB1_PASS_2_1250
+-	bool "1250 An"
+-	depends on SIBYTE_SB1250
+-	select CPU_SB1_PASS_2
+-	help
+-	  Also called BCM1250 Pass 2
+-
+-config CPU_SB1_PASS_2_2
+-	bool "1250 Bn"
+-	depends on SIBYTE_SB1250
+-	select CPU_HAS_PREFETCH
+-	help
+-	  Also called BCM1250 Pass 2.2
+-
+-config CPU_SB1_PASS_4
+-	bool "1250 Cn"
+-	depends on SIBYTE_SB1250
+-	select CPU_HAS_PREFETCH
+-	help
+-	  Also called BCM1250 Pass 3
+-
+-config CPU_SB1_PASS_2_112x
+-	bool "112x Hybrid"
+-	depends on SIBYTE_BCM112X
+-	select CPU_SB1_PASS_2
+-
+-config CPU_SB1_PASS_3
+-	bool "112x An"
+-	depends on SIBYTE_BCM112X
+-	select CPU_HAS_PREFETCH
+-
+-endchoice
+-
+-config CPU_SB1_PASS_2
+-	bool
+-
+-config SIBYTE_HAS_LDT
+-	bool
+-	depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H)
+-	default y
+-
+-config SIMULATION
+-	bool "Running under simulation"
+-	depends on SIBYTE_SB1xxx_SOC
+-	help
+-	  Build a kernel suitable for running under the GDB simulator.
+-	  Primarily adjusts the kernel's notion of time.
+-
+-config SIBYTE_CFE
+-	bool "Booting from CFE"
+-	depends on SIBYTE_SB1xxx_SOC
+-	help
+-	  Make use of the CFE API for enumerating available memory,
+-	  controlling secondary CPUs, and possibly console output.
+-
+-config SIBYTE_CFE_CONSOLE
+-	bool "Use firmware console"
+-	depends on SIBYTE_CFE
+-	help
+-	  Use the CFE API's console write routines during boot.  Other console
+-	  options (VT console, sb1250 duart console, etc.) should not be
+-	  configured.
+-
+-config SIBYTE_STANDALONE
+-	bool
+-	depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE
+-	default y
+-
+-config SIBYTE_STANDALONE_RAM_SIZE
+-	int "Memory size (in megabytes)"
+-	depends on SIBYTE_STANDALONE
+-	default "32"
+-
+-config SIBYTE_BUS_WATCHER
+-	bool "Support for Bus Watcher statistics"
+-	depends on SIBYTE_SB1xxx_SOC
+-	help
+-	  Handle and keep statistics on the bus error interrupts (COR_ECC,
+-	  BAD_ECC, IO_BUS).
+-
+-config SIBYTE_BW_TRACE
+-	bool "Capture bus trace before bus error"
+-	depends on SIBYTE_BUS_WATCHER
+-	help
+-	  Run a continuous bus trace, dumping the raw data as soon as
+-	  a ZBbus error is detected.  Cannot work if ZBbus profiling
+-	  is turned on, and also will interfere with JTAG-based trace
+-	  buffer activity.  Raw buffer data is dumped to console, and
+-	  must be processed off-line.
+-
+-config SIBYTE_SB1250_PROF
+-	bool "Support for SB1/SOC profiling - SB1/SCD perf counters"
+-	depends on SIBYTE_SB1xxx_SOC
+-
+-config SIBYTE_TBPROF
+-	bool "Support for ZBbus profiling"
+-	depends on SIBYTE_SB1xxx_SOC
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_SB1
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_HIGHMEM
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 
+ config SNI_RM200_PCI
+ 	bool "Support for SNI RM200 PCI"
+ 	select ARC
+ 	select ARC32
++	select ARCH_MAY_HAVE_PC_FDC
+ 	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
+ 	select GENERIC_ISA_DMA
+ 	select HAVE_STD_PC_SERIAL_PORT
++	select HW_HAS_EISA
+ 	select HW_HAS_PCI
+ 	select I8259
+ 	select ISA
++	select SYS_HAS_CPU_R4X00
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
++	select SYS_SUPPORTS_BIG_ENDIAN if EXPERIMENTAL
++	select SYS_SUPPORTS_HIGHMEM
++	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	help
+ 	  The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens
+ 	  Nixdorf Informationssysteme (SNI), parent company of Pyramid
+ 	  Technology and now in turn merged with Fujitsu.  Say Y here to
+ 	  support this machine type.
+ 
++config TOSHIBA_JMR3927
++	bool "Support for Toshiba JMR-TX3927 board"
++	select DMA_NONCOHERENT
++	select HW_HAS_PCI
++	select MIPS_TX3927
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_TX39XX
++	select SYS_SUPPORTS_32BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select TOSHIBA_BOARDS
++
+ config TOSHIBA_RBTX4927
+ 	bool "Support for Toshiba TBTX49[23]7 board"
+ 	select DMA_NONCOHERENT
+@@ -988,15 +748,51 @@ config TOSHIBA_RBTX4927
+ 	select I8259
+ 	select ISA
+ 	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_TX49XX
++	select SYS_SUPPORTS_32BIT_KERNEL
++	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select TOSHIBA_BOARDS
++	help
++	  This Toshiba board is based on the TX4927 processor. Say Y here to
++	  support this machine type
++
++config TOSHIBA_RBTX4938
++	bool "Support for Toshiba RBTX4938 board"
++	select HAVE_STD_PC_SERIAL_PORT
++	select DMA_NONCOHERENT
++	select GENERIC_ISA_DMA
++	select HAS_TXX9_SERIAL
++	select HW_HAS_PCI
++	select I8259
++	select ISA
++	select SWAP_IO_SPACE
++	select SYS_HAS_CPU_TX49XX
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+-	select SYS_SUPPORTS_64BIT_KERNEL
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select TOSHIBA_BOARDS
+ 	help
+-	  This Toshiba board is based on the TX4927 processor. Say Y here to
++	  This Toshiba board is based on the TX4938 processor. Say Y here to
+ 	  support this machine type
+ 
+-config TOSHIBA_FPCIB0
+-	bool "FPCIB0 Backplane Support"
+-	depends on TOSHIBA_RBTX4927
++endchoice
++
++source "arch/mips/ddb5xxx/Kconfig"
++source "arch/mips/gt64120/ev64120/Kconfig"
++source "arch/mips/jazz/Kconfig"
++source "arch/mips/ite-boards/Kconfig"
++source "arch/mips/lasat/Kconfig"
++source "arch/mips/momentum/Kconfig"
++source "arch/mips/pmc-sierra/Kconfig"
++source "arch/mips/sgi-ip27/Kconfig"
++source "arch/mips/sibyte/Kconfig"
++source "arch/mips/tx4927/Kconfig"
++source "arch/mips/tx4938/Kconfig"
++source "arch/mips/vr41xx/Kconfig"
++source "arch/mips/philips/pnx8550/common/Kconfig"
++
++endmenu
+ 
+ config RWSEM_GENERIC_SPINLOCK
+ 	bool
+@@ -1014,8 +810,9 @@ config GENERIC_CALIBRATE_DELAY
+ #
+ config ARC
+ 	bool
+-	depends on SNI_RM200_PCI || SGI_IP32 || SGI_IP27 || SGI_IP22 || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61
+-	default y
++
++config ARCH_MAY_HAVE_PC_FDC
++	bool
+ 
+ config DMA_COHERENT
+ 	bool
+@@ -1034,51 +831,65 @@ config DMA_NONCOHERENT
+ config DMA_NEED_PCI_MAP_STATE
+ 	bool
+ 
++config OWN_DMA
++	bool
++
+ config EARLY_PRINTK
+ 	bool
+-	depends on MACH_DECSTATION
+-	default y
+ 
+ config GENERIC_ISA_DMA
+ 	bool
+-	depends on SNI_RM200_PCI || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61 || MIPS_MALTA
+-	default y
+ 
+ config I8259
+ 	bool
+-	depends on SNI_RM200_PCI || DDB5477 || DDB5476 || DDB5074 || MACH_JAZZ || MIPS_MALTA || MIPS_COBALT
+-	default y
+ 
+ config LIMITED_DMA
+ 	bool
+ 	select HIGHMEM
++	select SYS_SUPPORTS_HIGHMEM
+ 
+ config MIPS_BONITO64
+ 	bool
+-	depends on MIPS_ATLAS || MIPS_MALTA
+-	default y
+ 
+ config MIPS_MSC
+ 	bool
+-	depends on MIPS_ATLAS || MIPS_MALTA
+-	default y
+ 
+ config MIPS_NILE4
+ 	bool
+-	depends on LASAT
+-	default y
+ 
+ config MIPS_DISABLE_OBSOLETE_IDE
+ 	bool
+ 
+-config CPU_LITTLE_ENDIAN
+-	bool "Generate little endian code"
+-	default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA
+-	default n if MIPS_EV64120 || MIPS_EV96100 || MOMENCO_OCELOT || MOMENCO_OCELOT_G || SGI_IP22 || SGI_IP27 || SGI_IP32 || TOSHIBA_JMR3927
++#
++# Endianess selection.  Suffiently obscure so many users don't know what to
++# answer,so we try hard to limit the available choices.  Also the use of a
++# choice statement should be more obvious to the user.
++#
++choice
++	prompt "Endianess selection"
+ 	help
+ 	  Some MIPS machines can be configured for either little or big endian
+-	  byte order. These modes require different kernels. Say Y if your
+-	  machine is little endian, N if it's a big endian machine.
++	  byte order. These modes require different kernels and a different
++	  Linux distribution.  In general there is one prefered byteorder for a
++	  particular system but some systems are just as commonly used in the
++	  one or the other endianess.
++
++config CPU_BIG_ENDIAN
++	bool "Big endian"
++	depends on SYS_SUPPORTS_BIG_ENDIAN
++
++config CPU_LITTLE_ENDIAN
++	bool "Little endian"
++	depends on SYS_SUPPORTS_LITTLE_ENDIAN
++	help
++
++endchoice
++
++config SYS_SUPPORTS_BIG_ENDIAN
++	bool
++
++config SYS_SUPPORTS_LITTLE_ENDIAN
++	bool
+ 
+ config IRQ_CPU
+ 	bool
+@@ -1086,42 +897,69 @@ config IRQ_CPU
+ config IRQ_CPU_RM7K
+ 	bool
+ 
++config IRQ_CPU_RM9K
++	bool
++
+ config IRQ_MV64340
+ 	bool
+ 
+ config DDB5XXX_COMMON
+ 	bool
+-	depends on DDB5074 || DDB5476 || DDB5477
+-	default y
+ 
+ config MIPS_BOARDS_GEN
+ 	bool
+-	depends on MIPS_ATLAS || MIPS_MALTA || MIPS_SEAD
+-	default y
+ 
+ config MIPS_GT64111
+ 	bool
+-	depends on MIPS_COBALT
+-	default y
+ 
+ config MIPS_GT64120
+ 	bool
+-	depends on MIPS_EV64120 || MIPS_EV96100 || LASAT || MIPS_ATLAS || MIPS_MALTA || MOMENCO_OCELOT
+-	default y
+ 
+ config MIPS_TX3927
+ 	bool
+-	depends on TOSHIBA_JMR3927
+ 	select HAS_TXX9_SERIAL
+-	default y
+ 
+ config PCI_MARVELL
+ 	bool
+ 
+ config ITE_BOARD_GEN
+ 	bool
+-	depends on MIPS_IVR || MIPS_ITE8172
+-	default y
++
++config SOC_AU1000
++	bool
++	select SOC_AU1X00
++
++config SOC_AU1100
++	bool
++	select SOC_AU1X00
++
++config SOC_AU1500
++	bool
++	select SOC_AU1X00
++
++config SOC_AU1550
++	bool
++	select SOC_AU1X00
++
++config SOC_AU1200
++	bool
++	select SOC_AU1X00
++
++config SOC_AU1X00
++	bool
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_SUPPORTS_32BIT_KERNEL
++
++config PNX8550
++	bool
++	select SOC_PNX8550
++
++config SOC_PNX8550
++	bool
++	select DMA_NONCOHERENT
++	select HW_HAS_PCI
++	select SYS_HAS_CPU_R4X00
++	select SYS_SUPPORTS_32BIT_KERNEL
+ 
+ config SWAP_IO_SPACE
+ 	bool
+@@ -1148,6 +986,9 @@ config SYSCLK_100
+ 
+ endchoice
+ 
++config ARC32
++	bool
++
+ config AU1X00_USB_DEVICE
+ 	bool
+ 	depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
+@@ -1155,11 +996,7 @@ config AU1X00_USB_DEVICE
+ 
+ config MIPS_GT96100
+ 	bool
+-	depends on MIPS_EV96100
+-	default y
+-	help
+-	  Say Y here to support the Galileo Technology GT96100 communications
+-	  controller card.  There is a web page at <http://www.galileot.com/>.
++	select MIPS_GT64120
+ 
+ config IT8172_CIR
+ 	bool
+@@ -1173,8 +1010,6 @@ config IT8712
+ 
+ config BOOT_ELF32
+ 	bool
+-	depends on MACH_DECSTATION || MIPS_ATLAS || MIPS_MALTA || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3 || SIBYTE_SB1xxx_SOC || SGI_IP32 || SGI_IP22 || SNI_RM200_PCI
+-	default y
+ 
+ config MIPS_L1_CACHE_SHIFT
+ 	int
+@@ -1182,11 +1017,6 @@ config MIPS_L1_CACHE_SHIFT
+ 	default "7" if SGI_IP27
+ 	default "5"
+ 
+-config ARC32
+-	bool
+-	depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32
+-	default y
+-
+ config HAVE_STD_PC_SERIAL_PORT
+ 	bool
+ 
+@@ -1206,30 +1036,12 @@ config ARC_PROMLIB
+ 
+ config ARC64
+ 	bool
+-	depends on SGI_IP27
+-	default y
+ 
+ config BOOT_ELF64
+ 	bool
+-	depends on SGI_IP27
+-	default y
+-
+-#config MAPPED_PCI_IO y
+-#	bool
+-#	depends on SGI_IP27
+-#	default y
+-
+-config QL_ISP_A64
+-	bool
+-	depends on SGI_IP27
+-	default y
+ 
+ config TOSHIBA_BOARDS
+ 	bool
+-	depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927
+-	default y
+-
+-endmenu
+ 
+ menu "CPU selection"
+ 
+@@ -1237,18 +1049,69 @@ choice
+ 	prompt "CPU type"
+ 	default CPU_R4X00
+ 
+-config CPU_MIPS32
+-	bool "MIPS32"
++config CPU_MIPS32_R1
++	bool "MIPS32 Release 1"
++	depends on SYS_HAS_CPU_MIPS32_R1
++	select CPU_HAS_PREFETCH
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+-
+-config CPU_MIPS64
+-	bool "MIPS64"
++	help
++	  Choose this option to build a kernel for release 1 or later of the
++	  MIPS32 architecture.  Most modern embedded systems with a 32-bit
++	  MIPS processor are based on a MIPS32 processor.  If you know the
++	  specific type of processor in your system, choose those that one
++	  otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
++	  Release 2 of the MIPS32 architecture is available since several
++	  years so chances are you even have a MIPS32 Release 2 processor
++	  in which case you should choose CPU_MIPS32_R2 instead for better
++	  performance.
++
++config CPU_MIPS32_R2
++	bool "MIPS32 Release 2"
++	depends on SYS_HAS_CPU_MIPS32_R2
++	select CPU_HAS_PREFETCH
++	select CPU_SUPPORTS_32BIT_KERNEL
++	help
++	  Choose this option to build a kernel for release 2 or later of the
++	  MIPS32 architecture.  Most modern embedded systems with a 32-bit
++	  MIPS processor are based on a MIPS32 processor.  If you know the
++	  specific type of processor in your system, choose those that one
++	  otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
++
++config CPU_MIPS64_R1
++	bool "MIPS64 Release 1"
++	depends on SYS_HAS_CPU_MIPS64_R1
++	select CPU_HAS_PREFETCH
++	select CPU_SUPPORTS_32BIT_KERNEL
++	select CPU_SUPPORTS_64BIT_KERNEL
++	help
++	  Choose this option to build a kernel for release 1 or later of the
++	  MIPS64 architecture.  Many modern embedded systems with a 64-bit
++	  MIPS processor are based on a MIPS64 processor.  If you know the
++	  specific type of processor in your system, choose those that one
++	  otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
++	  Release 2 of the MIPS64 architecture is available since several
++	  years so chances are you even have a MIPS64 Release 2 processor
++	  in which case you should choose CPU_MIPS64_R2 instead for better
++	  performance.
++
++config CPU_MIPS64_R2
++	bool "MIPS64 Release 2"
++	depends on SYS_HAS_CPU_MIPS64_R2
++	select CPU_HAS_PREFETCH
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
++	help
++	  Choose this option to build a kernel for release 2 or later of the
++	  MIPS64 architecture.  Many modern embedded systems with a 64-bit
++	  MIPS processor are based on a MIPS64 processor.  If you know the
++	  specific type of processor in your system, choose those that one
++	  otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
+ 
+ config CPU_R3000
+ 	bool "R3000"
++	depends on SYS_HAS_CPU_R3000
+ 	select CPU_SUPPORTS_32BIT_KERNEL
++	select CPU_SUPPORTS_HIGHMEM
+ 	help
+ 	  Please make sure to pick the right CPU type. Linux/MIPS is not
+ 	  designed to be generic, i.e. Kernels compiled for R3000 CPUs will
+@@ -1259,20 +1122,23 @@ config CPU_R3000
+ 
+ config CPU_TX39XX
+ 	bool "R39XX"
++	depends on SYS_HAS_CPU_TX39XX
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 
+ config CPU_VR41XX
+ 	bool "R41xx"
++	depends on SYS_HAS_CPU_VR41XX
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
+ 	help
+-	  The options selects support for the NEC VR41xx series of processors.
++	  The options selects support for the NEC VR4100 series of processors.
+ 	  Only choose this option if you have one of these processors as a
+ 	  kernel built with this option will not run on any other type of
+ 	  processor or vice versa.
+ 
+ config CPU_R4300
+ 	bool "R4300"
++	depends on SYS_HAS_CPU_R4300
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
+ 	help
+@@ -1280,6 +1146,7 @@ config CPU_R4300
+ 
+ config CPU_R4X00
+ 	bool "R4x00"
++	depends on SYS_HAS_CPU_R4X00
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
+ 	help
+@@ -1288,11 +1155,13 @@ config CPU_R4X00
+ 
+ config CPU_TX49XX
+ 	bool "R49XX"
++	depends on SYS_HAS_CPU_TX49XX
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
+ 
+ config CPU_R5000
+ 	bool "R5000"
++	depends on SYS_HAS_CPU_R5000
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
+ 	help
+@@ -1300,10 +1169,14 @@ config CPU_R5000
+ 
+ config CPU_R5432
+ 	bool "R5432"
++	depends on SYS_HAS_CPU_R5432
++	select CPU_SUPPORTS_32BIT_KERNEL
++	select CPU_SUPPORTS_64BIT_KERNEL
+ 
+ config CPU_R6000
+ 	bool "R6000"
+ 	depends on EXPERIMENTAL
++	depends on SYS_HAS_CPU_R6000
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	help
+ 	  MIPS Technologies R6000 and R6000A series processors.  Note these
+@@ -1311,6 +1184,7 @@ config CPU_R6000
+ 
+ config CPU_NEVADA
+ 	bool "RM52xx"
++	depends on SYS_HAS_CPU_NEVADA
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
+ 	help
+@@ -1319,6 +1193,8 @@ config CPU_NEVADA
+ config CPU_R8000
+ 	bool "R8000"
+ 	depends on EXPERIMENTAL
++	depends on SYS_HAS_CPU_R8000
++	select CPU_HAS_PREFETCH
+ 	select CPU_SUPPORTS_64BIT_KERNEL
+ 	help
+ 	  MIPS Technologies R8000 processors.  Note these processors are
+@@ -1326,25 +1202,151 @@ config CPU_R8000
+ 
+ config CPU_R10000
+ 	bool "R10000"
++	depends on SYS_HAS_CPU_R10000
++	select CPU_HAS_PREFETCH
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
++	select CPU_SUPPORTS_HIGHMEM
+ 	help
+ 	  MIPS Technologies R10000-series processors.
+ 
+ config CPU_RM7000
+ 	bool "RM7000"
++	depends on SYS_HAS_CPU_RM7000
++	select CPU_HAS_PREFETCH
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
++	select CPU_SUPPORTS_HIGHMEM
+ 
+ config CPU_RM9000
+ 	bool "RM9000"
++	depends on SYS_HAS_CPU_RM9000
++	select CPU_HAS_PREFETCH
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
++	select CPU_SUPPORTS_HIGHMEM
+ 
+ config CPU_SB1
+ 	bool "SB1"
++	depends on SYS_HAS_CPU_SB1
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_64BIT_KERNEL
++	select CPU_SUPPORTS_HIGHMEM
++
++endchoice
++
++config SYS_HAS_CPU_MIPS32_R1
++	bool
++
++config SYS_HAS_CPU_MIPS32_R2
++	bool
++
++config SYS_HAS_CPU_MIPS64_R1
++	bool
++
++config SYS_HAS_CPU_MIPS64_R2
++	bool
++
++config SYS_HAS_CPU_R3000
++	bool
++
++config SYS_HAS_CPU_TX39XX
++	bool
++
++config SYS_HAS_CPU_VR41XX
++	bool
++
++config SYS_HAS_CPU_R4300
++	bool
++
++config SYS_HAS_CPU_R4X00
++	bool
++
++config SYS_HAS_CPU_TX49XX
++	bool
++
++config SYS_HAS_CPU_R5000
++	bool
++
++config SYS_HAS_CPU_R5432
++	bool
++
++config SYS_HAS_CPU_R6000
++	bool
++
++config SYS_HAS_CPU_NEVADA
++	bool
++
++config SYS_HAS_CPU_R8000
++	bool
++
++config SYS_HAS_CPU_R10000
++	bool
++
++config SYS_HAS_CPU_RM7000
++	bool
++
++config SYS_HAS_CPU_RM9000
++	bool
++
++config SYS_HAS_CPU_SB1
++	bool
++
++endmenu
++
++#
++# These two indicate any levelof the MIPS32 and MIPS64 architecture
++#
++config CPU_MIPS32
++	bool
++	default y if CPU_MIPS32_R1 || CPU_MIPS32_R2
++
++config CPU_MIPS64
++	bool
++	default y if CPU_MIPS64_R1 || CPU_MIPS64_R2
++
++#
++# These two indicate the revision of the architecture, either 32 bot 64 bit.
++#
++config CPU_MIPSR1
++	bool
++	default y if CPU_MIPS32_R1 || CPU_MIPS64_R1
++
++config CPU_MIPSR2
++	bool
++	default y if CPU_MIPS32_R2 || CPU_MIPS64_R2
++
++config SYS_SUPPORTS_32BIT_KERNEL
++	bool
++config SYS_SUPPORTS_64BIT_KERNEL
++	bool
++config CPU_SUPPORTS_32BIT_KERNEL
++	bool
++config CPU_SUPPORTS_64BIT_KERNEL
++	bool
++
++menu "Kernel type"
++
++choice
++
++	prompt "Kernel code model"
++	help
++	  You should only select this option if you have a workload that
++	  actually benefits from 64-bit processing or if your machine has
++	  large memory.  You will only be presented a single option in this
++	  menu if your system does not support both 32-bit and 64-bit kernels.
++
++config 32BIT
++	bool "32-bit kernel"
++	depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL
++	select TRAD_SIGNALS
++	help
++	  Select this option if you want to build a 32-bit kernel.
++config 64BIT
++	bool "64-bit kernel"
++	depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
++	help
++	  Select this option if you want to build a 64-bit kernel.
+ 
+ endchoice
+ 
+@@ -1416,12 +1418,43 @@ config SIBYTE_DMA_PAGEOPS
+ 	  SiByte Linux port.  Seems to give a small performance benefit.
+ 
+ config CPU_HAS_PREFETCH
+-	bool "Enable prefetches" if CPU_SB1 && !CPU_SB1_PASS_2
+-	default y if CPU_MIPS32 || CPU_MIPS64 || CPU_RM7000 || CPU_RM9000 || CPU_R10000
++	bool
++
++config MIPS_MT
++	bool "Enable MIPS MT"
+ 
+-config VTAG_ICACHE
+-	bool "Support for Virtual Tagged I-cache" if CPU_MIPS64 || CPU_MIPS32
+-	default y if CPU_SB1
++choice
++	prompt "MIPS MT options"
++	depends on MIPS_MT
++
++config MIPS_MT_SMP
++	bool "Use 1 TC on each available VPE for SMP"
++	select SMP
++
++config MIPS_VPE_LOADER
++	bool "VPE loader support."
++	depends on MIPS_MT
++	help
++	  Includes a loader for loading an elf relocatable object
++	  onto another VPE and running it.
++
++endchoice
++
++config MIPS_VPE_LOADER_TOM
++	bool "Load VPE program into memory hidden from linux"
++	depends on MIPS_VPE_LOADER
++	default y
++	help
++	  The loader can use memory that is present but has been hidden from
++	  Linux using the kernel command line option "mem=xxMB". It's up to
++	  you to ensure the amount you put in the option and the space your
++	  program requires is less or equal to the amount physically present.
++
++# this should possibly be in drivers/char, but it is rather cpu related. Hmmm
++config MIPS_VPE_APSP_API
++	bool "Enable support for AP/SP API (RTLX)"
++	depends on MIPS_VPE_LOADER
++	help
+ 
+ config SB1_PASS_1_WORKAROUNDS
+ 	bool
+@@ -1440,7 +1473,7 @@ config SB1_PASS_2_1_WORKAROUNDS
+ 
+ config 64BIT_PHYS_ADDR
+ 	bool "Support for 64-bit physical address space"
+-	depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_RM9000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32 || CPU_MIPS64) && 32BIT
++	depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_RM9000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32_R1 || CPU_MIPS64_R1) && 32BIT
+ 
+ config CPU_ADVANCED
+ 	bool "Override CPU Options"
+@@ -1463,7 +1496,7 @@ config CPU_HAS_LLSC
+ 
+ config CPU_HAS_LLDSCD
+ 	bool "lld/scd Instructions available" if CPU_ADVANCED
+-	default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX && !CPU_MIPS32
++	default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX && !CPU_MIPS32_R1
+ 	help
+ 	  Say Y here if your CPU has the lld and scd instructions, the 64-bit
+ 	  equivalents of ll and sc.  Say Y here for better performance, N if
+@@ -1477,12 +1510,52 @@ config CPU_HAS_WB
+ 	  machines which require flushing of write buffers in software.  Saying
+ 	  Y is the safe option; N may result in kernel malfunction and crashes.
+ 
++menu "MIPSR2 Interrupt handling"
++	depends on CPU_MIPSR2 && CPU_ADVANCED
++
++config CPU_MIPSR2_IRQ_VI
++	bool "Vectored interrupt mode"
++	help
++	   Vectored interrupt mode allowing faster dispatching of interrupts.
++	   The board support code needs to be written to take advantage of this
++	   mode.  Compatibility code is included to allow the kernel to run on
++	   a CPU that does not support vectored interrupts.  It's safe to
++	   say Y here.
++
++config CPU_MIPSR2_IRQ_EI
++	bool "External interrupt controller mode"
++	help
++	   Extended interrupt mode takes advantage of an external interrupt
++	   controller to allow fast dispatching from many possible interrupt
++	   sources. Say N unless you know that external interrupt support is
++	   required.
++
++config CPU_MIPSR2_SRS
++	bool "Make shadow set registers available for interrupt handlers"
++	depends on CPU_MIPSR2_IRQ_VI || CPU_MIPSR2_IRQ_EI
++	help
++	   Allow the kernel to use shadow register sets for fast interrupts.
++	   Interrupt handlers must be specially written to use shadow sets.
++	   Say N unless you know that shadow register set upport is needed.
++endmenu
++
+ config CPU_HAS_SYNC
+ 	bool
+ 	depends on !CPU_R3000
+ 	default y
+ 
+ #
++# Use the generic interrupt handling code in kernel/irq/:
++#
++config GENERIC_HARDIRQS
++	bool
++	default y
++
++config GENERIC_IRQ_PROBE
++	bool
++	default y
++
++#
+ # - Highmem only makes sense for the 32-bit kernel.
+ # - The current highmem code will only work properly on physically indexed
+ #   caches such as R3000, SB1, R7000 or those that look like they're virtually
+@@ -1491,14 +1564,19 @@ config CPU_HAS_SYNC
+ #   where it's known to be safe.  This will not offer highmem on a few systems
+ #   such as MIPS32 and MIPS64 CPUs which may have virtual and physically
+ #   indexed CPUs but we're playing safe.
+-# - We should not offer highmem for system of which we already know that they
+-#   don't have memory configurations that could gain from highmem support in
+-#   the kernel because they don't support configurations with RAM at physical
+-#   addresses > 0x20000000.
++# - We use SYS_SUPPORTS_HIGHMEM to offer highmem only for systems where we
++#   know they might have memory configurations that could make use of highmem
++#   support.
+ #
+ config HIGHMEM
+ 	bool "High Memory Support"
+-	depends on 32BIT && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX)
++	depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM
++
++config CPU_SUPPORTS_HIGHMEM
++	bool
++
++config SYS_SUPPORTS_HIGHMEM
++	bool
+ 
+ config ARCH_FLATMEM_ENABLE
+ 	def_bool y
+@@ -1508,7 +1586,7 @@ source "mm/Kconfig"
+ 
+ config SMP
+ 	bool "Multi-Processing support"
+-	depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27
++	depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP
+ 	---help---
+ 	  This enables support for systems with more than one CPU. If you have
+ 	  a system with only one CPU, like most personal computers, say N. If
+@@ -1543,14 +1621,7 @@ config NR_CPUS
+ 	  This is purely to save memory - each supported CPU adds
+ 	  approximately eight kilobytes to the kernel image.
+ 
+-config PREEMPT
+-	bool "Preemptible Kernel"
+-	help
+-	  This option reduces the latency of the kernel when reacting to
+-	  real-time or interactive events by allowing a low priority process to
+-	  be preempted even if it is in kernel mode executing a system call.
+-	  This allows applications to run more reliably even when the system is
+-	  under load.
++source "kernel/Kconfig.preempt"
+ 
+ config RTC_DS1742
+ 	bool "DS1742 BRAM/RTC support"
+@@ -1566,14 +1637,16 @@ config MIPS_INSANE_LARGE
+ 	  This will result in additional memory usage, so it is not
+ 	  recommended for normal users.
+ 
++endmenu
++
+ config RWSEM_GENERIC_SPINLOCK
+ 	bool
+ 	default y
+ 
+-endmenu
+-
+ menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
+ 
++config HW_HAS_EISA
++	bool
+ config HW_HAS_PCI
+ 	bool
+ 
+@@ -1607,7 +1680,7 @@ config ISA
+ 
+ config EISA
+ 	bool "EISA support"
+-	depends on SGI_IP22 || SNI_RM200_PCI
++	depends on HW_HAS_EISA
+ 	select ISA
+ 	---help---
+ 	  The Extended Industry Standard Architecture (EISA) bus was
+@@ -1641,12 +1714,6 @@ config MMU
+ 	bool
+ 	default y
+ 
+-config MCA
+-	bool
+-
+-config SBUS
+-	bool
+-
+ source "drivers/pcmcia/Kconfig"
+ 
+ source "drivers/pci/hotplug/Kconfig"
+@@ -1659,7 +1726,6 @@ source "fs/Kconfig.binfmt"
+ 
+ config TRAD_SIGNALS
+ 	bool
+-	default y if 32BIT
+ 
+ config BUILD_ELF64
+ 	bool "Use 64-bit ELF format for building"
+@@ -1678,7 +1744,7 @@ config BUILD_ELF64
+ 
+ config BINFMT_IRIX
+ 	bool "Include IRIX binary compatibility"
+-	depends on !CPU_LITTLE_ENDIAN && 32BIT && BROKEN
++	depends on CPU_BIG_ENDIAN && 32BIT && BROKEN
+ 
+ config MIPS32_COMPAT
+ 	bool "Kernel support for Linux/MIPS 32-bit binary compatibility"
+@@ -1718,9 +1784,26 @@ config BINFMT_ELF32
+ 	bool
+ 	default y if MIPS32_O32 || MIPS32_N32
+ 
++config SECCOMP
++	bool "Enable seccomp to safely compute untrusted bytecode"
++	depends on PROC_FS && BROKEN
++	default y
++	help
++	  This kernel feature is useful for number crunching applications
++	  that may need to compute untrusted bytecode during their
++	  execution. By using pipes or other transports made available to
++	  the process as file descriptors supporting the read/write
++	  syscalls, it's possible to isolate those applications in
++	  their own address space using seccomp. Once seccomp is
++	  enabled via /proc/<pid>/seccomp, it cannot be disabled
++	  and the task is only allowed to execute a few safe syscalls
++	  defined by each seccomp mode.
++
++	  If unsure, say Y. Only embedded should say N here.
++
+ config PM
+ 	bool "Power Management support (EXPERIMENTAL)"
+-	depends on EXPERIMENTAL && MACH_AU1X00
++	depends on EXPERIMENTAL && SOC_AU1X00
+ 
+ endmenu
+ 
+@@ -1730,6 +1813,8 @@ source "drivers/Kconfig"
+ 
+ source "fs/Kconfig"
+ 
++source "arch/mips/oprofile/Kconfig"
++
+ source "arch/mips/Kconfig.debug"
+ 
+ source "security/Kconfig"
+@@ -1737,18 +1822,3 @@ source "security/Kconfig"
+ source "crypto/Kconfig"
+ 
+ source "lib/Kconfig"
+-
+-#
+-# Use the generic interrupt handling code in kernel/irq/:
+-#
+-config GENERIC_HARDIRQS
+-	bool
+-	default y
+-
+-config GENERIC_IRQ_PROBE
+-	bool
+-	default y
+-
+-config ISA_DMA_API
+-	bool
+-	default y
+diff --git a/arch/mips/Makefile b/arch/mips/Makefile
+--- a/arch/mips/Makefile
++++ b/arch/mips/Makefile
+@@ -52,6 +52,21 @@ ifdef CONFIG_CROSSCOMPILE
+ CROSS_COMPILE		:= $(tool-prefix)
+ endif
+ 
++CHECKFLAGS-y				+= -D__linux__ -D__mips__ \
++					   -D_ABIO32=1 \
++					   -D_ABIN32=2 \
++					   -D_ABI64=3
++CHECKFLAGS-$(CONFIG_32BIT)		+= -D_MIPS_SIM=_ABIO32 \
++					   -D_MIPS_SZLONG=32 \
++					   -D__PTRDIFF_TYPE__=int
++CHECKFLAGS-$(CONFIG_64BIT)		+= -m64 -D_MIPS_SIM=_ABI64 \
++					   -D_MIPS_SZLONG=64 \
++					   -D__PTRDIFF_TYPE__="long int"
++CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN)	+= -D__MIPSEB__
++CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN)	+= -D__MIPSEL__
++
++CHECKFLAGS				= $(CHECKFLAGS-y)
++
+ ifdef CONFIG_BUILD_ELF64
+ gas-abi			= 64
+ ld-emul			= $(64bit-emul)
+@@ -79,9 +94,18 @@ endif
+ cflags-y			+= -I $(TOPDIR)/include/asm/gcc
+ cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe
+ cflags-y			+= $(call cc-option, -finline-limit=100000)
+-LDFLAGS_vmlinux			+= -G 0 -static -n
++LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
+ MODFLAGS			+= -mlong-calls
+ 
++#
++# We explicitly add the endianness specifier if needed, this allows
++# to compile kernels with a toolchain for the other endianness. We
++# carefully avoid to add it redundantly because gcc 3.3/3.4 complains
++# when fed the toolchain default!
++#
++cflags-$(CONFIG_CPU_BIG_ENDIAN)		+= $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB)
++cflags-$(CONFIG_CPU_LITTLE_ENDIAN)	+= $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL)
++
+ cflags-$(CONFIG_SB1XXX_CORELIS)	+= -mno-sched-prolog -fno-omit-frame-pointer
+ 
+ #
+@@ -167,14 +191,22 @@ cflags-$(CONFIG_CPU_TX49XX)	+= \
+ 			$(call set_gccflags,r4600,mips3,r4600,mips3,mips2)  \
+ 			-Wa,--trap
+ 
+-cflags-$(CONFIG_CPU_MIPS32)	+= \
++cflags-$(CONFIG_CPU_MIPS32_R1)	+= \
+ 			$(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
+ 			-Wa,--trap
+ 
+-cflags-$(CONFIG_CPU_MIPS64)	+= \
++cflags-$(CONFIG_CPU_MIPS32_R2)	+= \
++			$(call set_gccflags,mips32r2,mips32r2,r4600,mips3,mips2) \
++			-Wa,--trap
++
++cflags-$(CONFIG_CPU_MIPS64_R1)	+= \
+ 			$(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
+ 			-Wa,--trap
+ 
++cflags-$(CONFIG_CPU_MIPS64_R2)	+= \
++			$(call set_gccflags,mips64r2,mips64r2,r4600,mips3,mips2) \
++			-Wa,--trap
++
+ cflags-$(CONFIG_CPU_R5000)	+= \
+ 			$(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \
+ 			-Wa,--trap
+@@ -196,6 +228,7 @@ cflags-$(CONFIG_CPU_RM9000)	+= \
+ 			$(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
+ 			-Wa,--trap
+ 
++
+ cflags-$(CONFIG_CPU_SB1)	+= \
+ 			$(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
+ 			-Wa,--trap
+@@ -266,6 +299,13 @@ cflags-$(CONFIG_MIPS_PB1550)	+= -Iinclud
+ load-$(CONFIG_MIPS_PB1550)	+= 0xffffffff80100000
+ 
+ #
++# AMD Alchemy Pb1200 eval board
++#
++libs-$(CONFIG_MIPS_PB1200)	+= arch/mips/au1000/pb1200/
++cflags-$(CONFIG_MIPS_PB1200)	+= -Iinclude/asm-mips/mach-pb1x00
++load-$(CONFIG_MIPS_PB1200)	+= 0xffffffff80100000
++
++#
+ # AMD Alchemy Db1000 eval board
+ #
+ libs-$(CONFIG_MIPS_DB1000)	+= arch/mips/au1000/db1x00/
+@@ -294,6 +334,13 @@ cflags-$(CONFIG_MIPS_DB1550)	+= -Iinclud
+ load-$(CONFIG_MIPS_DB1550)	+= 0xffffffff80100000
+ 
+ #
++# AMD Alchemy Db1200 eval board
++#
++libs-$(CONFIG_MIPS_DB1200)	+= arch/mips/au1000/pb1200/
++cflags-$(CONFIG_MIPS_DB1200)	+= -Iinclude/asm-mips/mach-db1x00
++load-$(CONFIG_MIPS_DB1200)	+= 0xffffffff80100000
++
++#
+ # AMD Alchemy Bosporus eval board
+ #
+ libs-$(CONFIG_MIPS_BOSPORUS)	+= arch/mips/au1000/db1x00/
+@@ -323,6 +370,7 @@ load-$(CONFIG_MIPS_XXS1500)	+= 0xfffffff
+ # Cobalt Server
+ #
+ core-$(CONFIG_MIPS_COBALT)	+= arch/mips/cobalt/
++cflags-$(CONFIG_MIPS_COBALT)	+= -Iinclude/asm-mips/cobalt
+ load-$(CONFIG_MIPS_COBALT)	+= 0xffffffff80080000
+ 
+ #
+@@ -389,6 +437,13 @@ core-$(CONFIG_MIPS_SEAD)	+= arch/mips/mi
+ load-$(CONFIG_MIPS_SEAD)	+= 0xffffffff80100000
+ 
+ #
++# MIPS SIM
++#
++core-$(CONFIG_MIPS_SIM)		+= arch/mips/mips-boards/sim/
++cflags-$(CONFIG_MIPS_SIM)	+= -Iinclude/asm-mips/mach-sim
++load-$(CONFIG_MIPS_SIM)		+= 0x80100000
++
++#
+ # Momentum Ocelot board
+ #
+ # The Ocelot setup.o must be linked early - it does the ioremap() for the
+@@ -514,6 +569,19 @@ load-$(CONFIG_CASIO_E55)	+= 0xffffffff80
+ load-$(CONFIG_TANBAC_TB022X)	+= 0xffffffff80000000
+ 
+ #
++# Common Philips PNX8550
++#
++core-$(CONFIG_SOC_PNX8550)	+= arch/mips/philips/pnx8550/common/
++cflags-$(CONFIG_SOC_PNX8550)	+= -Iinclude/asm-mips/mach-pnx8550
++
++#
++# Philips PNX8550 JBS board
++#
++libs-$(CONFIG_PNX8550_JBS)	+= arch/mips/philips/pnx8550/jbs/
++#cflags-$(CONFIG_PNX8550_JBS)	+= -Iinclude/asm-mips/mach-pnx8550
++load-$(CONFIG_PNX8550_JBS)	+= 0xffffffff80060000
++
++#
+ # SGI IP22 (Indy/Indigo2)
+ #
+ # Set the load address to >= 0xffffffff88069000 if you want to leave space for
+@@ -582,10 +650,20 @@ load-$(CONFIG_SGI_IP32)		+= 0xffffffff80
+ # removed (as happens, even if they have __initcall/module_init)
+ #
+ core-$(CONFIG_SIBYTE_BCM112X)	+= arch/mips/sibyte/sb1250/
+-cflags-$(CONFIG_SIBYTE_BCM112X)	+= -Iinclude/asm-mips/mach-sibyte
++cflags-$(CONFIG_SIBYTE_BCM112X)	+= -Iinclude/asm-mips/mach-sibyte \
++			-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
+ 
+ core-$(CONFIG_SIBYTE_SB1250)	+= arch/mips/sibyte/sb1250/
+-cflags-$(CONFIG_SIBYTE_SB1250)	+= -Iinclude/asm-mips/mach-sibyte
++cflags-$(CONFIG_SIBYTE_SB1250)	+= -Iinclude/asm-mips/mach-sibyte \
++			-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
++
++core-$(CONFIG_SIBYTE_BCM1x55)	+= arch/mips/sibyte/bcm1480/
++cflags-$(CONFIG_SIBYTE_BCM1x55)	+= -Iinclude/asm-mips/mach-sibyte \
++			-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
++
++core-$(CONFIG_SIBYTE_BCM1x80)	+= arch/mips/sibyte/bcm1480/
++cflags-$(CONFIG_SIBYTE_BCM1x80)	+= -Iinclude/asm-mips/mach-sibyte \
++			-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
+ 
+ #
+ # Sibyte BCM91120x (Carmel) board
+@@ -593,6 +671,7 @@ cflags-$(CONFIG_SIBYTE_SB1250)	+= -Iincl
+ # Sibyte BCM91125C (CRhone) board
+ # Sibyte BCM91125E (Rhone) board
+ # Sibyte SWARM board
++# Sibyte BCM91x80 (BigSur) board
+ #
+ libs-$(CONFIG_SIBYTE_CARMEL)	+= arch/mips/sibyte/swarm/
+ load-$(CONFIG_SIBYTE_CARMEL)	:= 0xffffffff80100000
+@@ -606,6 +685,8 @@ libs-$(CONFIG_SIBYTE_SENTOSA)	+= arch/mi
+ load-$(CONFIG_SIBYTE_SENTOSA)	:= 0xffffffff80100000
+ libs-$(CONFIG_SIBYTE_SWARM)	+= arch/mips/sibyte/swarm/
+ load-$(CONFIG_SIBYTE_SWARM)	:= 0xffffffff80100000
++libs-$(CONFIG_SIBYTE_BIGSUR)	+= arch/mips/sibyte/swarm/
++load-$(CONFIG_SIBYTE_BIGSUR)	:= 0xffffffff80100000
+ 
+ #
+ # SNI RM200 PCI
+@@ -629,6 +710,13 @@ core-$(CONFIG_TOSHIBA_RBTX4927)	+= arch/
+ core-$(CONFIG_TOSHIBA_RBTX4927)	+= arch/mips/tx4927/common/
+ load-$(CONFIG_TOSHIBA_RBTX4927)	+= 0xffffffff80020000
+ 
++#
++# Toshiba RBTX4938 board
++#
++core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/
++core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/
++load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000
++
+ cflags-y			+= -Iinclude/asm-mips/mach-generic
+ drivers-$(CONFIG_PCI)		+= arch/mips/pci/
+ 
+@@ -701,10 +789,29 @@ ifdef CONFIG_BOOT_ELF64
+ all:	$(vmlinux-64)
+ endif
+ 
++ifdef CONFIG_MIPS_ATLAS
++all:	vmlinux.srec
++endif
++
++ifdef CONFIG_MIPS_MALTA
++all:	vmlinux.srec
++endif
++
++ifdef CONFIG_MIPS_SEAD
++all:	vmlinux.srec
++endif
++
++ifdef CONFIG_QEMU
++all:	vmlinux.bin
++endif
++
+ ifdef CONFIG_SNI_RM200_PCI
+ all:	vmlinux.ecoff
+ endif
+ 
++vmlinux.bin: $(vmlinux-32)
++	+@$(call makeboot,$@)
++
+ vmlinux.ecoff vmlinux.rm200: $(vmlinux-32)
+ 	+@$(call makeboot,$@)
+ 
+@@ -720,7 +827,6 @@ archclean:
+ 	@$(MAKE) $(clean)=arch/mips/boot
+ 	@$(MAKE) $(clean)=arch/mips/lasat
+ 
+-
+ CLEAN_FILES += vmlinux.32 \
+ 	       vmlinux.64 \
+ 	       vmlinux.ecoff
+diff --git a/arch/mips/arc/Makefile b/arch/mips/arc/Makefile
+--- a/arch/mips/arc/Makefile
++++ b/arch/mips/arc/Makefile
+@@ -3,7 +3,7 @@
+ #
+ 
+ lib-y				+= cmdline.o env.o file.o identify.o init.o \
+-				   misc.o time.o tree.o
++				   misc.o salone.o time.o tree.o
+ 
+ lib-$(CONFIG_ARC_MEMORY)	+= memory.o
+ lib-$(CONFIG_ARC_CONSOLE)	+= arc_con.o
+diff --git a/arch/mips/arc/identify.c b/arch/mips/arc/identify.c
+--- a/arch/mips/arc/identify.c
++++ b/arch/mips/arc/identify.c
+@@ -44,6 +44,11 @@ static struct smatch mach_table[] = {
+ 		MACH_GROUP_SGI,
+ 		MACH_SGI_IP28,
+ 		PROM_FLAG_ARCS
++	}, {	"SGI-IP30",
++		"SGI Octane",
++		MACH_GROUP_SGI,
++		MACH_SGI_IP30,
++		PROM_FLAG_ARCS
+ 	}, {	"SGI-IP32",
+ 		"SGI O2",
+ 		MACH_GROUP_SGI,
+diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile
+--- a/arch/mips/au1000/common/Makefile
++++ b/arch/mips/au1000/common/Makefile
+@@ -8,7 +8,7 @@
+ 
+ obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \
+ 	au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
+-	sleeper.o cputable.o dma.o dbdma.o
++	sleeper.o cputable.o dma.o dbdma.o gpio.o
+ 
+ obj-$(CONFIG_AU1X00_USB_DEVICE)	+= usbdev.o
+ obj-$(CONFIG_KGDB)		+= dbg_io.o
+diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
+--- a/arch/mips/au1000/common/au1xxx_irqmap.c
++++ b/arch/mips/au1000/common/au1xxx_irqmap.c
+@@ -173,14 +173,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = {
+ 	{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
+ 	{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
+ 	{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1550_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1550_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1550_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+-	{ AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1550_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1550_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1550_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
++	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
+ 	{ AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+@@ -201,14 +201,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = {
+ 	{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
+ 	{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
+ 	{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1200_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1200_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1200_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1200_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+-	{ AU1200_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1200_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1200_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1200_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
++	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
++	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
+ 	{ AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
+diff --git a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c
+--- a/arch/mips/au1000/common/cputable.c
++++ b/arch/mips/au1000/common/cputable.c
+@@ -37,7 +37,8 @@ struct cpu_spec	cpu_specs[] = {
+     { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 },
+     { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 },
+     { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 },
+-    { 0xffffffff, 0x04030200, "Au1200 AA", 0, 1 },
++    { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0 },
++    { 0xffffffff, 0x04030201, "Au1200 AC", 0, 1 },
+     { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 },
+ };
+ 
+diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
+--- a/arch/mips/au1000/common/dbdma.c
++++ b/arch/mips/au1000/common/dbdma.c
+@@ -29,6 +29,7 @@
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  */
++
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+@@ -38,10 +39,12 @@
+ #include <linux/string.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/module.h>
+ #include <asm/mach-au1x00/au1000.h>
+ #include <asm/mach-au1x00/au1xxx_dbdma.h>
+ #include <asm/system.h>
+ 
++
+ #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+ 
+ /*
+@@ -61,37 +64,10 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin
+ */
+ #define ALIGN_ADDR(x, a)	((((u32)(x)) + (a-1)) & ~(a-1))
+ 
+-static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
+-static int dbdma_initialized;
++static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
++static int dbdma_initialized=0;
+ static void au1xxx_dbdma_init(void);
+ 
+-typedef struct dbdma_device_table {
+-	u32		dev_id;
+-	u32		dev_flags;
+-	u32		dev_tsize;
+-	u32		dev_devwidth;
+-	u32		dev_physaddr;		/* If FIFO */
+-	u32		dev_intlevel;
+-	u32		dev_intpolarity;
+-} dbdev_tab_t;
+-
+-typedef struct dbdma_chan_config {
+-	u32			chan_flags;
+-	u32			chan_index;
+-	dbdev_tab_t		*chan_src;
+-	dbdev_tab_t		*chan_dest;
+-	au1x_dma_chan_t		*chan_ptr;
+-	au1x_ddma_desc_t	*chan_desc_base;
+-	au1x_ddma_desc_t	*get_ptr, *put_ptr, *cur_ptr;
+-	void			*chan_callparam;
+-	void (*chan_callback)(int, void *, struct pt_regs *);
+-} chan_tab_t;
+-
+-#define	DEV_FLAGS_INUSE		(1 << 0)
+-#define	DEV_FLAGS_ANYUSE	(1 << 1)
+-#define DEV_FLAGS_OUT		(1 << 2)
+-#define DEV_FLAGS_IN		(1 << 3)
+-
+ static dbdev_tab_t dbdev_tab[] = {
+ #ifdef CONFIG_SOC_AU1550
+ 	/* UARTS */
+@@ -157,25 +133,25 @@ static dbdev_tab_t dbdev_tab[] = {
+ 	{ DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ 	{ DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ 
+-	{ DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+-	{ DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+-	{ DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+-	{ DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
++	{ DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
++	{ DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
++	{ DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 },
++	{ DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 },
+ 
+-	{ DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+-	{ DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
++	{ DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
++	{ DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
+ 
+-	{ DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
+-	{ DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
++	{ DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 },
++	{ DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 },
+ 	{ DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ 
+-	{ DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
+-	{ DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
++	{ DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 },
++	{ DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 },
+ 	{ DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ 
+-	{ DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+-	{ DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+-	{ DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
++	{ DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 },
++	{ DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 },
++	{ DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 },
+ 	{ DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ 
+ 	{ DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+@@ -184,6 +160,24 @@ static dbdev_tab_t dbdev_tab[] = {
+ 
+ 	{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ 	{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
++
++	/* Provide 16 user definable device types */
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
++	{ 0, 0, 0, 0, 0, 0, 0 },
+ };
+ 
+ #define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t))
+@@ -203,6 +197,36 @@ find_dbdev_id (u32 id)
+ 	return NULL;
+ }
+ 
++void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
++{
++        return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
++}
++EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt);
++
++u32
++au1xxx_ddma_add_device(dbdev_tab_t *dev)
++{
++	u32 ret = 0;
++	dbdev_tab_t *p=NULL;
++	static u16 new_id=0x1000;
++
++	p = find_dbdev_id(0);
++	if ( NULL != p )
++	{
++		memcpy(p, dev, sizeof(dbdev_tab_t));
++ 		p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id);
++		ret = p->dev_id;
++		new_id++;
++#if 0
++		printk("add_device: id:%x flags:%x padd:%x\n",
++				p->dev_id, p->dev_flags, p->dev_physaddr );
++#endif
++	}
++
++	return ret;
++}
++EXPORT_SYMBOL(au1xxx_ddma_add_device);
++
+ /* Allocate a channel and return a non-zero descriptor if successful.
+ */
+ u32
+@@ -215,7 +239,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
+ 	int		i;
+ 	dbdev_tab_t	*stp, *dtp;
+ 	chan_tab_t	*ctp;
+-	volatile au1x_dma_chan_t *cp;
++	au1x_dma_chan_t *cp;
+ 
+ 	/* We do the intialization on the first channel allocation.
+ 	 * We have to wait because of the interrupt handler initialization
+@@ -225,9 +249,6 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
+ 		au1xxx_dbdma_init();
+ 	dbdma_initialized = 1;
+ 
+-	if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS))
+-		return 0;
+-
+ 	if ((stp = find_dbdev_id(srcid)) == NULL) return 0;
+ 	if ((dtp = find_dbdev_id(destid)) == NULL) return 0;
+ 
+@@ -271,7 +292,6 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
+ 				 */
+ 				ctp = kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
+ 				chan_tab_ptr[i] = ctp;
+-				ctp->chan_index = chan = i;
+ 				break;
+ 			}
+ 		}
+@@ -279,10 +299,11 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
+ 
+ 		if (ctp != NULL) {
+ 			memset(ctp, 0, sizeof(chan_tab_t));
++			ctp->chan_index = chan = i;
+ 			dcp = DDMA_CHANNEL_BASE;
+ 			dcp += (0x0100 * chan);
+ 			ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
+-			cp = (volatile au1x_dma_chan_t *)dcp;
++			cp = (au1x_dma_chan_t *)dcp;
+ 			ctp->chan_src = stp;
+ 			ctp->chan_dest = dtp;
+ 			ctp->chan_callback = callback;
+@@ -299,6 +320,9 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
+ 				i |= DDMA_CFG_DED;
+ 			if (dtp->dev_intpolarity)
+ 				i |= DDMA_CFG_DP;
++			if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
++				(dtp->dev_flags & DEV_FLAGS_SYNC))
++					i |= DDMA_CFG_SYNC;
+ 			cp->ddma_cfg = i;
+ 			au_sync();
+ 
+@@ -309,14 +333,14 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
+ 			rv = (u32)(&chan_tab_ptr[chan]);
+ 		}
+ 		else {
+-			/* Release devices.
+-			*/
++			/* Release devices */
+ 			stp->dev_flags &= ~DEV_FLAGS_INUSE;
+ 			dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+ 		}
+ 	}
+ 	return rv;
+ }
++EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
+ 
+ /* Set the device width if source or destination is a FIFO.
+  * Should be 8, 16, or 32 bits.
+@@ -344,6 +368,7 @@ au1xxx_dbdma_set_devwidth(u32 chanid, in
+ 
+ 	return rv;
+ }
++EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
+ 
+ /* Allocate a descriptor ring, initializing as much as possible.
+ */
+@@ -370,7 +395,8 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int 
+ 	 * and if we try that first we are likely to not waste larger
+ 	 * slabs of memory.
+ 	 */
+-	desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
++	desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
++			GFP_KERNEL|GFP_DMA);
+ 	if (desc_base == 0)
+ 		return 0;
+ 
+@@ -381,7 +407,7 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int 
+ 		kfree((const void *)desc_base);
+ 		i = entries * sizeof(au1x_ddma_desc_t);
+ 		i += (sizeof(au1x_ddma_desc_t) - 1);
+-		if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0)
++		if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0)
+ 			return 0;
+ 
+ 		desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
+@@ -403,7 +429,13 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int 
+ 	cmd0 |= DSCR_CMD0_SID(srcid);
+ 	cmd0 |= DSCR_CMD0_DID(destid);
+ 	cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
+-	cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_CURRENT);
++	cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE);
++
++        /* is it mem to mem transfer? */
++        if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
++           ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) {
++               cmd0 |= DSCR_CMD0_MEM;
++        }
+ 
+ 	switch (stp->dev_devwidth) {
+ 	case 8:
+@@ -461,9 +493,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int 
+ 	/* If source input is fifo, set static address.
+ 	*/
+ 	if (stp->dev_flags & DEV_FLAGS_IN) {
+-		src0 = stp->dev_physaddr;
++		if ( stp->dev_flags & DEV_FLAGS_BURSTABLE )
++			src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
++		else
+ 		src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
++
+ 	}
++	if (stp->dev_physaddr)
++		src0 = stp->dev_physaddr;
+ 
+ 	/* Set up dest1.  For now, assume no stride and increment.
+ 	 * A channel attribute update can change this later.
+@@ -487,10 +524,18 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int 
+ 	/* If destination output is fifo, set static address.
+ 	*/
+ 	if (dtp->dev_flags & DEV_FLAGS_OUT) {
+-		dest0 = dtp->dev_physaddr;
++		if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE )
++	                dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
++				else
+ 		dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
+ 	}
++	if (dtp->dev_physaddr)
++		dest0 = dtp->dev_physaddr;
+ 
++#if 0
++		printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
++			dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 );
++#endif
+ 	for (i=0; i<entries; i++) {
+ 		dp->dscr_cmd0 = cmd0;
+ 		dp->dscr_cmd1 = cmd1;
+@@ -499,6 +544,8 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int 
+ 		dp->dscr_dest0 = dest0;
+ 		dp->dscr_dest1 = dest1;
+ 		dp->dscr_stat = 0;
++		dp->sw_context = 0;
++		dp->sw_status = 0;
+ 		dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1));
+ 		dp++;
+ 	}
+@@ -511,13 +558,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int 
+ 
+ 	return (u32)(ctp->chan_desc_base);
+ }
++EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
+ 
+ /* Put a source buffer into the DMA ring.
+  * This updates the source pointer and byte count.  Normally used
+  * for memory to fifo transfers.
+  */
+ u32
+-au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
++_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
+ {
+ 	chan_tab_t		*ctp;
+ 	au1x_ddma_desc_t	*dp;
+@@ -544,8 +592,24 @@ au1xxx_dbdma_put_source(u32 chanid, void
+ 	*/
+ 	dp->dscr_source0 = virt_to_phys(buf);
+ 	dp->dscr_cmd1 = nbytes;
+-	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
+-	ctp->chan_ptr->ddma_dbell = 0xffffffff;	/* Make it go */
++	/* Check flags  */
++	if (flags & DDMA_FLAGS_IE)
++		dp->dscr_cmd0 |= DSCR_CMD0_IE;
++	if (flags & DDMA_FLAGS_NOIE)
++		dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
++
++	/*
++	 * There is an errata on the Au1200/Au1550 parts that could result
++	 * in "stale" data being DMA'd. It has to do with the snoop logic on
++	 * the dache eviction buffer.  NONCOHERENT_IO is on by default for
++	 * these parts. If it is fixedin the future, these dma_cache_inv will
++	 * just be nothing more than empty macros. See io.h.
++	 * */
++	dma_cache_wback_inv((unsigned long)buf, nbytes);
++        dp->dscr_cmd0 |= DSCR_CMD0_V;        /* Let it rip */
++	au_sync();
++	dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
++        ctp->chan_ptr->ddma_dbell = 0;
+ 
+ 	/* Get next descriptor pointer.
+ 	*/
+@@ -555,13 +619,14 @@ au1xxx_dbdma_put_source(u32 chanid, void
+ 	*/
+ 	return nbytes;
+ }
++EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
+ 
+ /* Put a destination buffer into the DMA ring.
+  * This updates the destination pointer and byte count.  Normally used
+  * to place an empty buffer into the ring for fifo to memory transfers.
+  */
+ u32
+-au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
++_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
+ {
+ 	chan_tab_t		*ctp;
+ 	au1x_ddma_desc_t	*dp;
+@@ -583,11 +648,33 @@ au1xxx_dbdma_put_dest(u32 chanid, void *
+ 	if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ 		return 0;
+ 
+-	/* Load up buffer address and byte count.
+-	*/
++	/* Load up buffer address and byte count */
++
++	/* Check flags  */
++	if (flags & DDMA_FLAGS_IE)
++		dp->dscr_cmd0 |= DSCR_CMD0_IE;
++	if (flags & DDMA_FLAGS_NOIE)
++		dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
++
+ 	dp->dscr_dest0 = virt_to_phys(buf);
+ 	dp->dscr_cmd1 = nbytes;
++#if 0
++	printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
++			dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
++			dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 );
++#endif
++	/*
++	 * There is an errata on the Au1200/Au1550 parts that could result in
++	 * "stale" data being DMA'd. It has to do with the snoop logic on the
++	 * dache eviction buffer. NONCOHERENT_IO is on by default for these
++	 * parts. If it is fixedin the future, these dma_cache_inv will just
++	 * be nothing more than empty macros. See io.h.
++	 * */
++	dma_cache_inv((unsigned long)buf,nbytes);
+ 	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
++	au_sync();
++	dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
++        ctp->chan_ptr->ddma_dbell = 0;
+ 
+ 	/* Get next descriptor pointer.
+ 	*/
+@@ -597,6 +684,7 @@ au1xxx_dbdma_put_dest(u32 chanid, void *
+ 	*/
+ 	return nbytes;
+ }
++EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
+ 
+ /* Get a destination buffer into the DMA ring.
+  * Normally used to get a full buffer from the ring during fifo
+@@ -646,7 +734,7 @@ void
+ au1xxx_dbdma_stop(u32 chanid)
+ {
+ 	chan_tab_t	*ctp;
+-	volatile au1x_dma_chan_t *cp;
++	au1x_dma_chan_t *cp;
+ 	int halt_timeout = 0;
+ 
+ 	ctp = *((chan_tab_t **)chanid);
+@@ -666,6 +754,7 @@ au1xxx_dbdma_stop(u32 chanid)
+ 	cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V);
+ 	au_sync();
+ }
++EXPORT_SYMBOL(au1xxx_dbdma_stop);
+ 
+ /* Start using the current descriptor pointer.  If the dbdma encounters
+  * a not valid descriptor, it will stop.  In this case, we can just
+@@ -675,17 +764,17 @@ void
+ au1xxx_dbdma_start(u32 chanid)
+ {
+ 	chan_tab_t	*ctp;
+-	volatile au1x_dma_chan_t *cp;
++	au1x_dma_chan_t *cp;
+ 
+ 	ctp = *((chan_tab_t **)chanid);
+-
+ 	cp = ctp->chan_ptr;
+ 	cp->ddma_desptr = virt_to_phys(ctp->cur_ptr);
+ 	cp->ddma_cfg |= DDMA_CFG_EN;	/* Enable channel */
+ 	au_sync();
+-	cp->ddma_dbell = 0xffffffff;	/* Make it go */
++	cp->ddma_dbell = 0;
+ 	au_sync();
+ }
++EXPORT_SYMBOL(au1xxx_dbdma_start);
+ 
+ void
+ au1xxx_dbdma_reset(u32 chanid)
+@@ -704,15 +793,21 @@ au1xxx_dbdma_reset(u32 chanid)
+ 
+ 	do {
+ 		dp->dscr_cmd0 &= ~DSCR_CMD0_V;
++		/* reset our SW status -- this is used to determine
++		 * if a descriptor is in use by upper level SW. Since
++		 * posting can reset 'V' bit.
++		 */
++		dp->sw_status = 0;
+ 		dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ 	} while (dp != ctp->chan_desc_base);
+ }
++EXPORT_SYMBOL(au1xxx_dbdma_reset);
+ 
+ u32
+ au1xxx_get_dma_residue(u32 chanid)
+ {
+ 	chan_tab_t	*ctp;
+-	volatile au1x_dma_chan_t *cp;
++	au1x_dma_chan_t *cp;
+ 	u32		rv;
+ 
+ 	ctp = *((chan_tab_t **)chanid);
+@@ -738,8 +833,7 @@ au1xxx_dbdma_chan_free(u32 chanid)
+ 
+ 	au1xxx_dbdma_stop(chanid);
+ 
+-	if (ctp->chan_desc_base != NULL)
+-		kfree(ctp->chan_desc_base);
++	kfree((void *)ctp->chan_desc_base);
+ 
+ 	stp->dev_flags &= ~DEV_FLAGS_INUSE;
+ 	dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+@@ -747,15 +841,16 @@ au1xxx_dbdma_chan_free(u32 chanid)
+ 
+ 	kfree(ctp);
+ }
++EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
+ 
+ static irqreturn_t
+ dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+-	u32	intstat;
+-	u32	chan_index;
++	u32 intstat;
++	u32 chan_index;
+ 	chan_tab_t		*ctp;
+ 	au1x_ddma_desc_t	*dp;
+-	volatile au1x_dma_chan_t *cp;
++	au1x_dma_chan_t *cp;
+ 
+ 	intstat = dbdma_gptr->ddma_intstat;
+ 	au_sync();
+@@ -774,19 +869,27 @@ dbdma_interrupt(int irq, void *dev_id, s
+ 		(ctp->chan_callback)(irq, ctp->chan_callparam, regs);
+ 
+ 	ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+-
+-	return IRQ_HANDLED;
++	return IRQ_RETVAL(1);
+ }
+ 
+-static void
+-au1xxx_dbdma_init(void)
++static void au1xxx_dbdma_init(void)
+ {
++	int irq_nr;
++
+ 	dbdma_gptr->ddma_config = 0;
+ 	dbdma_gptr->ddma_throttle = 0;
+ 	dbdma_gptr->ddma_inten = 0xffff;
+ 	au_sync();
+ 
+-	if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT,
++#if defined(CONFIG_SOC_AU1550)
++	irq_nr = AU1550_DDMA_INT;
++#elif defined(CONFIG_SOC_AU1200)
++	irq_nr = AU1200_DDMA_INT;
++#else
++	#error Unknown Au1x00 SOC
++#endif
++
++	if (request_irq(irq_nr, dbdma_interrupt, SA_INTERRUPT,
+ 			"Au1xxx dbdma", (void *)dbdma_gptr))
+ 		printk("Can't get 1550 dbdma irq");
+ }
+@@ -797,7 +900,8 @@ au1xxx_dbdma_dump(u32 chanid)
+ 	chan_tab_t		*ctp;
+ 	au1x_ddma_desc_t	*dp;
+ 	dbdev_tab_t		*stp, *dtp;
+-	volatile au1x_dma_chan_t *cp;
++	au1x_dma_chan_t *cp;
++		u32			i = 0;
+ 
+ 	ctp = *((chan_tab_t **)chanid);
+ 	stp = ctp->chan_src;
+@@ -822,15 +926,64 @@ au1xxx_dbdma_dump(u32 chanid)
+ 	dp = ctp->chan_desc_base;
+ 
+ 	do {
+-		printk("dp %08x, cmd0 %08x, cmd1 %08x\n",
+-			(u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
+-		printk("src0 %08x, src1 %08x, dest0 %08x\n",
+-			dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0);
+-		printk("dest1 %08x, stat %08x, nxtptr %08x\n",
+-			dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr);
++                printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
++                        i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
++                printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
++                        dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
++                printk("stat %08x, nxtptr %08x\n",
++                        dp->dscr_stat, dp->dscr_nxtptr);
+ 		dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ 	} while (dp != ctp->chan_desc_base);
+ }
+ 
++/* Put a descriptor into the DMA ring.
++ * This updates the source/destination pointers and byte count.
++ */
++u32
++au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
++{
++	chan_tab_t *ctp;
++	au1x_ddma_desc_t *dp;
++	u32 nbytes=0;
++
++	/* I guess we could check this to be within the
++	* range of the table......
++	*/
++	ctp = *((chan_tab_t **)chanid);
++
++	/* We should have multiple callers for a particular channel,
++	* an interrupt doesn't affect this pointer nor the descriptor,
++	* so no locking should be needed.
++	*/
++	dp = ctp->put_ptr;
++
++	/* If the descriptor is valid, we are way ahead of the DMA
++	* engine, so just return an error condition.
++	*/
++	if (dp->dscr_cmd0 & DSCR_CMD0_V)
++		return 0;
++
++	/* Load up buffer addresses and byte count.
++	*/
++	dp->dscr_dest0 = dscr->dscr_dest0;
++	dp->dscr_source0 = dscr->dscr_source0;
++	dp->dscr_dest1 = dscr->dscr_dest1;
++	dp->dscr_source1 = dscr->dscr_source1;
++	dp->dscr_cmd1 = dscr->dscr_cmd1;
++	nbytes = dscr->dscr_cmd1;
++	/* Allow the caller to specifiy if an interrupt is generated */
++	dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
++	dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
++	ctp->chan_ptr->ddma_dbell = 0;
++
++	/* Get next descriptor pointer.
++	*/
++	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
++
++	/* return something not zero.
++	*/
++	return nbytes;
++}
++
+ #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
+ 
+diff --git a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c
+--- a/arch/mips/au1000/common/dma.c
++++ b/arch/mips/au1000/common/dma.c
+@@ -39,7 +39,6 @@
+ #include <linux/string.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+-#include <linux/module.h>
+ #include <asm/system.h>
+ #include <asm/mach-au1x00/au1000.h>
+ #include <asm/mach-au1x00/au1000_dma.h>
+diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/au1000/common/gpio.c
+@@ -0,0 +1,119 @@
++/*
++ *  This program is free software; you can redistribute	 it and/or modify it
++ *  under  the terms of	 the 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  SOFTWARE  IS PROVIDED	  ``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 AUTHOR  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.
++ *
++ *  You 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/config.h>
++#include <linux/module.h>
++#include <au1000.h>
++#include <au1xxx_gpio.h>
++
++#define gpio1 sys
++#if !defined(CONFIG_SOC_AU1000)
++static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE;
++
++#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000
++
++int au1xxx_gpio2_read(int signal)
++{
++	signal -= 200;
++/*	gpio2->dir &= ~(0x01 << signal);						//Set GPIO to input */
++	return ((gpio2->pinstate >> signal) & 0x01);
++}
++
++void au1xxx_gpio2_write(int signal, int value)
++{
++	signal -= 200;
++
++	gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) |
++		(value << signal);
++}
++
++void au1xxx_gpio2_tristate(int signal)
++{
++	signal -= 200;
++	gpio2->dir &= ~(0x01 << signal); 	/* Set GPIO to input */
++}
++#endif
++
++int au1xxx_gpio1_read(int signal)
++{
++/*	gpio1->trioutclr |= (0x01 << signal); */
++	return ((gpio1->pinstaterd >> signal) & 0x01);
++}
++
++void au1xxx_gpio1_write(int signal, int value)
++{
++	if(value)
++		gpio1->outputset = (0x01 << signal);
++	else
++		gpio1->outputclr = (0x01 << signal);	/* Output a Zero */
++}
++
++void au1xxx_gpio1_tristate(int signal)
++{
++	gpio1->trioutclr = (0x01 << signal);		/* Tristate signal */
++}
++
++
++int au1xxx_gpio_read(int signal)
++{
++	if(signal >= 200)
++#if defined(CONFIG_SOC_AU1000)
++		return 0;
++#else
++		return au1xxx_gpio2_read(signal);
++#endif
++	else
++		return au1xxx_gpio1_read(signal);
++}
++
++void au1xxx_gpio_write(int signal, int value)
++{
++	if(signal >= 200)
++#if defined(CONFIG_SOC_AU1000)
++		;
++#else
++		au1xxx_gpio2_write(signal, value);
++#endif
++	else
++		au1xxx_gpio1_write(signal, value);
++}
++
++void au1xxx_gpio_tristate(int signal)
++{
++	if(signal >= 200)
++#if defined(CONFIG_SOC_AU1000)
++		;
++#else
++		au1xxx_gpio2_tristate(signal);
++#endif
++	else
++		au1xxx_gpio1_tristate(signal);
++}
++
++void au1xxx_gpio1_set_inputs(void)
++{
++	gpio1->pininputen = 0;
++}
++
++EXPORT_SYMBOL(au1xxx_gpio1_set_inputs);
++EXPORT_SYMBOL(au1xxx_gpio_tristate);
++EXPORT_SYMBOL(au1xxx_gpio_write);
++EXPORT_SYMBOL(au1xxx_gpio_read);
+diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
+--- a/arch/mips/au1000/common/irq.c
++++ b/arch/mips/au1000/common/irq.c
+@@ -83,7 +83,7 @@ inline void local_disable_irq(unsigned i
+ void	(*board_init_irq)(void);
+ 
+ #ifdef CONFIG_PM
+-extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
++extern irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
+ #endif
+ 
+ static DEFINE_SPINLOCK(irq_lock);
+@@ -253,52 +253,72 @@ void restore_local_and_enable(int contro
+ 
+ 
+ static struct hw_interrupt_type rise_edge_irq_type = {
+-	"Au1000 Rise Edge",
+-	startup_irq,
+-	shutdown_irq,
+-	local_enable_irq,
+-	local_disable_irq,
+-	mask_and_ack_rise_edge_irq,
+-	end_irq,
+-	NULL
++	.typename = "Au1000 Rise Edge",
++	.startup = startup_irq,
++	.shutdown = shutdown_irq,
++	.enable = local_enable_irq,
++	.disable = local_disable_irq,
++	.ack = mask_and_ack_rise_edge_irq,
++	.end = end_irq,
+ };
+ 
+ static struct hw_interrupt_type fall_edge_irq_type = {
+-	"Au1000 Fall Edge",
+-	startup_irq,
+-	shutdown_irq,
+-	local_enable_irq,
+-	local_disable_irq,
+-	mask_and_ack_fall_edge_irq,
+-	end_irq,
+-	NULL
++	.typename = "Au1000 Fall Edge",
++	.startup = startup_irq,
++	.shutdown = shutdown_irq,
++	.enable = local_enable_irq,
++	.disable = local_disable_irq,
++	.ack = mask_and_ack_fall_edge_irq,
++	.end = end_irq,
+ };
+ 
+ static struct hw_interrupt_type either_edge_irq_type = {
+-	"Au1000 Rise or Fall Edge",
+-	startup_irq,
+-	shutdown_irq,
+-	local_enable_irq,
+-	local_disable_irq,
+-	mask_and_ack_either_edge_irq,
+-	end_irq,
+-	NULL
++	.typename = "Au1000 Rise or Fall Edge",
++	.startup = startup_irq,
++	.shutdown = shutdown_irq,
++	.enable = local_enable_irq,
++	.disable = local_disable_irq,
++	.ack = mask_and_ack_either_edge_irq,
++	.end = end_irq,
+ };
+ 
+ static struct hw_interrupt_type level_irq_type = {
+-	"Au1000 Level",
+-	startup_irq,
+-	shutdown_irq,
+-	local_enable_irq,
+-	local_disable_irq,
+-	mask_and_ack_level_irq,
+-	end_irq,
+-	NULL
++	.typename = "Au1000 Level",
++	.startup = startup_irq,
++	.shutdown = shutdown_irq,
++	.enable = local_enable_irq,
++	.disable = local_disable_irq,
++	.ack = mask_and_ack_level_irq,
++	.end = end_irq,
+ };
+ 
+ #ifdef CONFIG_PM
+-void startup_match20_interrupt(void)
++void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *))
+ {
++	struct irq_desc *desc = &irq_desc[AU1000_TOY_MATCH2_INT];
++
++	static struct irqaction action;
++	memset(&action, 0, sizeof(struct irqaction));
++
++	/* This is a big problem.... since we didn't use request_irq
++	 * when kernel/irq.c calls probe_irq_xxx this interrupt will
++	 * be probed for usage. This will end up disabling the device :(
++	 * Give it a bogus "action" pointer -- this will keep it from
++	 * getting auto-probed!
++	 *
++	 * By setting the status to match that of request_irq() we
++	 * can avoid it.  --cgray
++	*/
++	action.dev_id = handler;
++	action.flags = SA_INTERRUPT;
++	cpus_clear(action.mask);
++	action.name = "Au1xxx TOY";
++	action.handler = handler;
++	action.next = NULL;
++
++	desc->action = &action;
++	desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
++
+ 	local_enable_irq(AU1000_TOY_MATCH2_INT);
+ }
+ #endif
+@@ -426,7 +446,6 @@ void __init arch_init_irq(void)
+ 	extern int au1xxx_ic0_nr_irqs;
+ 
+ 	cp0_status = read_c0_status();
+-	memset(irq_desc, 0, sizeof(irq_desc));
+ 	set_except_vector(0, au1000_IRQ);
+ 
+ 	/* Initialize interrupt controllers to a safe state.
+@@ -492,7 +511,7 @@ void intc0_req0_irqdispatch(struct pt_re
+ 	intc0_req0 |= au_readl(IC0_REQ0INT);
+ 
+ 	if (!intc0_req0) return;
+-
++#ifdef AU1000_USB_DEV_REQ_INT
+ 	/*
+ 	 * Because of the tight timing of SETUP token to reply
+ 	 * transactions, the USB devices-side packet complete
+@@ -503,7 +522,7 @@ void intc0_req0_irqdispatch(struct pt_re
+ 		do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
+ 		return;
+ 	}
+-
++#endif
+ 	irq = au_ffs(intc0_req0) - 1;
+ 	intc0_req0 &= ~(1<<irq);
+ 	do_IRQ(irq, regs);
+@@ -521,17 +540,7 @@ void intc0_req1_irqdispatch(struct pt_re
+ 
+ 	irq = au_ffs(intc0_req1) - 1;
+ 	intc0_req1 &= ~(1<<irq);
+-#ifdef CONFIG_PM
+-	if (irq == AU1000_TOY_MATCH2_INT) {
+-		mask_and_ack_rise_edge_irq(irq);
+-		counter0_irq(irq, NULL, regs);
+-		local_enable_irq(irq);
+-	}
+-	else
+-#endif
+-	{
+-		do_IRQ(irq, regs);
+-	}
++	do_IRQ(irq, regs);
+ }
+ 
+ 
+diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
+--- a/arch/mips/au1000/common/platform.c
++++ b/arch/mips/au1000/common/platform.c
+@@ -7,13 +7,16 @@
+  * 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/device.h>
++#include <linux/platform_device.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/resource.h>
+ 
+-#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-au1x00/au1xxx.h>
+ 
++/* OHCI (USB full speed host controller) */
+ static struct resource au1xxx_usb_ohci_resources[] = {
+ 	[0] = {
+ 		.start		= USB_OHCI_BASE,
+@@ -41,8 +44,252 @@ static struct platform_device au1xxx_usb
+ 	.resource	= au1xxx_usb_ohci_resources,
+ };
+ 
++/*** AU1100 LCD controller ***/
++
++#ifdef CONFIG_FB_AU1100
++static struct resource au1100_lcd_resources[] = {
++	[0] = {
++		.start          = LCD_PHYS_ADDR,
++		.end            = LCD_PHYS_ADDR + 0x800 - 1,
++		.flags          = IORESOURCE_MEM,
++	},
++	[1] = {
++		.start          = AU1100_LCD_INT,
++		.end            = AU1100_LCD_INT,
++		.flags          = IORESOURCE_IRQ,
++	}
++};
++
++static u64 au1100_lcd_dmamask = ~(u32)0;
++
++static struct platform_device au1100_lcd_device = {
++	.name           = "au1100-lcd",
++	.id             = 0,
++	.dev = {
++		.dma_mask               = &au1100_lcd_dmamask,
++		.coherent_dma_mask      = 0xffffffff,
++	},
++	.num_resources  = ARRAY_SIZE(au1100_lcd_resources),
++	.resource       = au1100_lcd_resources,
++};
++#endif
++
++#ifdef CONFIG_SOC_AU1200
++/* EHCI (USB high speed host controller) */
++static struct resource au1xxx_usb_ehci_resources[] = {
++	[0] = {
++		.start		= USB_EHCI_BASE,
++		.end		= USB_EHCI_BASE + USB_EHCI_LEN - 1,
++		.flags		= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start		= AU1000_USB_HOST_INT,
++		.end		= AU1000_USB_HOST_INT,
++		.flags		= IORESOURCE_IRQ,
++	},
++};
++
++static u64 ehci_dmamask = ~(u32)0;
++
++static struct platform_device au1xxx_usb_ehci_device = {
++	.name		= "au1xxx-ehci",
++	.id		= 0,
++	.dev = {
++		.dma_mask		= &ehci_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.num_resources	= ARRAY_SIZE(au1xxx_usb_ehci_resources),
++	.resource	= au1xxx_usb_ehci_resources,
++};
++
++/* Au1200 UDC (USB gadget controller) */
++static struct resource au1xxx_usb_gdt_resources[] = {
++	[0] = {
++		.start		= USB_UDC_BASE,
++		.end		= USB_UDC_BASE + USB_UDC_LEN - 1,
++		.flags		= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start		= AU1200_USB_INT,
++		.end		= AU1200_USB_INT,
++		.flags		= IORESOURCE_IRQ,
++	},
++};
++
++static struct resource au1xxx_mmc_resources[] = {
++	[0] = {
++		.start          = SD0_PHYS_ADDR,
++		.end            = SD0_PHYS_ADDR + 0x40,
++		.flags          = IORESOURCE_MEM,
++	},
++	[1] = {
++		.start		= SD1_PHYS_ADDR,
++		.end 		= SD1_PHYS_ADDR + 0x40,
++		.flags		= IORESOURCE_MEM,
++	},
++	[2] = {
++		.start          = AU1200_SD_INT,
++		.end            = AU1200_SD_INT,
++		.flags          = IORESOURCE_IRQ,
++	}
++};
++
++static u64 udc_dmamask = ~(u32)0;
++
++static struct platform_device au1xxx_usb_gdt_device = {
++	.name		= "au1xxx-udc",
++	.id		= 0,
++	.dev = {
++		.dma_mask		= &udc_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.num_resources	= ARRAY_SIZE(au1xxx_usb_gdt_resources),
++	.resource	= au1xxx_usb_gdt_resources,
++};
++
++/* Au1200 UOC (USB OTG controller) */
++static struct resource au1xxx_usb_otg_resources[] = {
++	[0] = {
++		.start		= USB_UOC_BASE,
++		.end		= USB_UOC_BASE + USB_UOC_LEN - 1,
++		.flags		= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start		= AU1200_USB_INT,
++		.end		= AU1200_USB_INT,
++		.flags		= IORESOURCE_IRQ,
++	},
++};
++
++static u64 uoc_dmamask = ~(u32)0;
++
++static struct platform_device au1xxx_usb_otg_device = {
++	.name		= "au1xxx-uoc",
++	.id		= 0,
++	.dev = {
++		.dma_mask		= &uoc_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.num_resources	= ARRAY_SIZE(au1xxx_usb_otg_resources),
++	.resource	= au1xxx_usb_otg_resources,
++};
++
++static struct resource au1200_lcd_resources[] = {
++	[0] = {
++		.start          = LCD_PHYS_ADDR,
++		.end            = LCD_PHYS_ADDR + 0x800 - 1,
++		.flags          = IORESOURCE_MEM,
++	},
++	[1] = {
++		.start          = AU1200_LCD_INT,
++		.end            = AU1200_LCD_INT,
++		.flags          = IORESOURCE_IRQ,
++	}
++};
++
++static struct resource au1200_ide0_resources[] = {
++	[0] = {
++		.start		= AU1XXX_ATA_PHYS_ADDR,
++		.end 		= AU1XXX_ATA_PHYS_ADDR + AU1XXX_ATA_PHYS_LEN,
++		.flags		= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start		= AU1XXX_ATA_INT,
++		.end		= AU1XXX_ATA_INT,
++		.flags		= IORESOURCE_IRQ,
++	}
++};
++
++static u64 au1200_lcd_dmamask = ~(u32)0;
++
++static struct platform_device au1200_lcd_device = {
++	.name           = "au1200-lcd",
++	.id             = 0,
++	.dev = {
++		.dma_mask               = &au1200_lcd_dmamask,
++		.coherent_dma_mask      = 0xffffffff,
++	},
++	.num_resources  = ARRAY_SIZE(au1200_lcd_resources),
++	.resource       = au1200_lcd_resources,
++};
++
++
++static u64 ide0_dmamask = ~(u32)0;
++
++static struct platform_device au1200_ide0_device = {
++	.name		= "au1200-ide",
++	.id		= 0,
++	.dev = {
++		.dma_mask 		= &ide0_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.num_resources = ARRAY_SIZE(au1200_ide0_resources),
++	.resource	= au1200_ide0_resources,
++};
++
++static u64 au1xxx_mmc_dmamask =  ~(u32)0;
++
++static struct platform_device au1xxx_mmc_device = {
++	.name = "au1xxx-mmc",
++	.id = 0,
++	.dev = {
++		.dma_mask               = &au1xxx_mmc_dmamask,
++		.coherent_dma_mask      = 0xffffffff,
++	},
++	.num_resources  = ARRAY_SIZE(au1xxx_mmc_resources),
++	.resource       = au1xxx_mmc_resources,
++};
++#endif /* #ifdef CONFIG_SOC_AU1200 */
++
++static struct platform_device au1x00_pcmcia_device = {
++	.name 		= "au1x00-pcmcia",
++	.id 		= 0,
++};
++
++#ifdef CONFIG_MIPS_DB1200
++
++static struct resource smc91x_resources[] = {
++	[0] = {
++		.name	= "smc91x-regs",
++		.start	= AU1XXX_SMC91111_PHYS_ADDR,
++		.end	= AU1XXX_SMC91111_PHYS_ADDR + 0xfffff,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= AU1XXX_SMC91111_IRQ,
++		.end	= AU1XXX_SMC91111_IRQ,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device smc91x_device = {
++	.name		= "smc91x",
++ 	.id		= -1,
++	.num_resources	= ARRAY_SIZE(smc91x_resources),
++	.resource	= smc91x_resources,
++};
++
++#endif
++
+ static struct platform_device *au1xxx_platform_devices[] __initdata = {
+ 	&au1xxx_usb_ohci_device,
++	&au1x00_pcmcia_device,
++#ifdef CONFIG_FB_AU1100
++	&au1100_lcd_device,
++#endif
++#ifdef CONFIG_SOC_AU1200
++#if 0	/* fixme */
++	&au1xxx_usb_ehci_device,
++#endif
++	&au1xxx_usb_gdt_device,
++	&au1xxx_usb_otg_device,
++	&au1200_lcd_device,
++	&au1200_ide0_device,
++	&au1xxx_mmc_device,
++#endif
++#ifdef CONFIG_MIPS_DB1200
++ 	&smc91x_device,
++#endif
+ };
+ 
+ int au1xxx_platform_init(void)
+diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
+--- a/arch/mips/au1000/common/power.c
++++ b/arch/mips/au1000/common/power.c
+@@ -34,11 +34,13 @@
+ #include <linux/pm.h>
+ #include <linux/slab.h>
+ #include <linux/sysctl.h>
++#include <linux/jiffies.h>
+ 
+ #include <asm/string.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+ #include <asm/system.h>
++#include <asm/cacheflush.h>
+ #include <asm/mach-au1x00/au1000.h>
+ 
+ #ifdef CONFIG_PM
+@@ -50,7 +52,7 @@
+ #  define DPRINTK(fmt, args...)
+ #endif
+ 
+-static void calibrate_delay(void);
++static void au1000_calibrate_delay(void);
+ 
+ extern void set_au1x00_speed(unsigned int new_freq);
+ extern unsigned int get_au1x00_speed(void);
+@@ -260,7 +262,7 @@ int au_sleep(void)
+ }
+ 
+ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
+-		       void *buffer, size_t * len)
++		       void __user *buffer, size_t * len, loff_t *ppos)
+ {
+ 	int retval = 0;
+ #ifdef SLEEP_TEST_TIMEOUT
+@@ -294,10 +296,9 @@ static int pm_do_sleep(ctl_table * ctl, 
+ }
+ 
+ static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
+-			 void *buffer, size_t * len)
++			 void __user *buffer, size_t * len, loff_t *ppos)
+ {
+ 	int retval = 0;
+-	void	au1k_wait(void);
+ 
+ 	if (!write) {
+ 		*len = 0;
+@@ -306,7 +307,7 @@ static int pm_do_suspend(ctl_table * ctl
+ 		if (retval)
+ 			return retval;
+ 		suspend_mode = 1;
+-		au1k_wait();
++
+ 		retval = pm_send_all(PM_RESUME, (void *) 0);
+ 	}
+ 	return retval;
+@@ -314,7 +315,7 @@ static int pm_do_suspend(ctl_table * ctl
+ 
+ 
+ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
+-		      void *buffer, size_t * len)
++		      void __user *buffer, size_t * len, loff_t *ppos)
+ {
+ 	int retval = 0, i;
+ 	unsigned long val, pll;
+@@ -409,14 +410,14 @@ static int pm_do_freq(ctl_table * ctl, i
+ 
+ 
+ 	/* We don't want _any_ interrupts other than
+-	 * match20. Otherwise our calibrate_delay()
++	 * match20. Otherwise our au1000_calibrate_delay()
+ 	 * calculation will be off, potentially a lot.
+ 	 */
+ 	intc0_mask = save_local_and_disable(0);
+ 	intc1_mask = save_local_and_disable(1);
+ 	local_enable_irq(AU1000_TOY_MATCH2_INT);
+ 	spin_unlock_irqrestore(&pm_lock, flags);
+-	calibrate_delay();
++	au1000_calibrate_delay();
+ 	restore_local_and_enable(0, intc0_mask);
+ 	restore_local_and_enable(1, intc1_mask);
+ 	return retval;
+@@ -456,7 +457,7 @@ __initcall(pm_init);
+    better than 1% */
+ #define LPS_PREC 8
+ 
+-static void calibrate_delay(void)
++static void au1000_calibrate_delay(void)
+ {
+ 	unsigned long ticks, loopbit;
+ 	int lps_precision = LPS_PREC;
+diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
+--- a/arch/mips/au1000/common/prom.c
++++ b/arch/mips/au1000/common/prom.c
+@@ -75,7 +75,8 @@ void  prom_init_cmdline(void)
+ 	}
+ 	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+ 		--cp;
+-	*cp = '\0';
++	if (prom_argc > 1)
++		*cp = '\0';
+ 
+ }
+ 
+diff --git a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c
+--- a/arch/mips/au1000/common/puts.c
++++ b/arch/mips/au1000/common/puts.c
+@@ -39,7 +39,6 @@
+ #define TIMEOUT       0xffffff
+ #define SLOW_DOWN
+ 
+-static const char digits[16] = "0123456789abcdef";
+ static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
+ 
+ 
+@@ -54,7 +53,7 @@ static inline void slow_down(void)
+ #endif
+ 
+ void
+-putch(const unsigned char c)
++prom_putchar(const unsigned char c)
+ {
+     unsigned char ch;
+     int i = 0;
+@@ -69,77 +68,3 @@ putch(const unsigned char c)
+     } while (0 == (ch & TX_BUSY));
+     com1[SER_DATA] = c;
+ }
+-
+-void
+-puts(unsigned char *cp)
+-{
+-    unsigned char ch;
+-    int i = 0;
+-
+-    while (*cp) {
+-        do {
+-             ch = com1[SER_CMD];
+-            slow_down();
+-            i++;
+-            if (i>TIMEOUT) {
+-                break;
+-            }
+-        } while (0 == (ch & TX_BUSY));
+-        com1[SER_DATA] = *cp++;
+-    }
+-    putch('\r');
+-    putch('\n');
+-}
+-
+-void
+-fputs(const char *cp)
+-{
+-    unsigned char ch;
+-    int i = 0;
+-
+-    while (*cp) {
+-
+-        do {
+-             ch = com1[SER_CMD];
+-             slow_down();
+-            i++;
+-            if (i>TIMEOUT) {
+-                break;
+-            }
+-        } while (0 == (ch & TX_BUSY));
+-        com1[SER_DATA] = *cp++;
+-    }
+-}
+-
+-
+-void
+-put64(uint64_t ul)
+-{
+-    int cnt;
+-    unsigned ch;
+-
+-    cnt = 16;            /* 16 nibbles in a 64 bit long */
+-    putch('0');
+-    putch('x');
+-    do {
+-        cnt--;
+-        ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
+-                putch(digits[ch]);
+-    } while (cnt > 0);
+-}
+-
+-void
+-put32(unsigned u)
+-{
+-    int cnt;
+-    unsigned ch;
+-
+-    cnt = 8;            /* 8 nibbles in a 32 bit long */
+-    putch('0');
+-    putch('x');
+-    do {
+-        cnt--;
+-        ch = (unsigned char)(u >> cnt * 4) & 0x0F;
+-                putch(digits[ch]);
+-    } while (cnt > 0);
+-}
+diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
+--- a/arch/mips/au1000/common/setup.c
++++ b/arch/mips/au1000/common/setup.c
+@@ -32,6 +32,7 @@
+ #include <linux/mm.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/module.h>
+ 
+ #include <asm/cpu.h>
+ #include <asm/bootinfo.h>
+@@ -57,7 +58,7 @@ extern void au1xxx_time_init(void);
+ extern void au1xxx_timer_setup(struct irqaction *irq);
+ extern void set_cpuspec(void);
+ 
+-static int __init au1x00_setup(void)
++void __init plat_setup(void)
+ {
+ 	struct	cpu_spec *sp;
+ 	char *argptr;
+@@ -106,8 +107,6 @@ static int __init au1x00_setup(void)
+         /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
+ #ifdef CONFIG_MIPS_HYDROGEN3
+          strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor");
+-#else
+-        strcat(argptr, " video=au1100fb:panel:s10,nohwcursor");
+ #endif
+     }
+ #endif
+@@ -153,15 +152,11 @@ static int __init au1x00_setup(void)
+ 	au_sync();
+ 	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+ 	au_writel(0, SYS_TOYTRIM);
+-
+-	return 0;
+ }
+ 
+-early_initcall(au1x00_setup);
+-
+ #if defined(CONFIG_64BIT_PHYS_ADDR)
+ /* This routine should be valid for all Au1x based boards */
+-phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
++phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+ {
+ 	u32 start, end;
+ 
+@@ -192,4 +187,5 @@ phys_t fixup_bigphys_addr(phys_t phys_ad
+ 	/* default nop */
+ 	return phys_addr;
+ }
++EXPORT_SYMBOL(__fixup_bigphys_addr);
+ #endif
+diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
+--- a/arch/mips/au1000/common/time.c
++++ b/arch/mips/au1000/common/time.c
+@@ -50,7 +50,6 @@
+ #include <linux/mc146818rtc.h>
+ #include <linux/timex.h>
+ 
+-extern void startup_match20_interrupt(void);
+ extern void do_softirq(void);
+ extern volatile unsigned long wall_jiffies;
+ unsigned long missed_heart_beats = 0;
+@@ -58,14 +57,17 @@ unsigned long missed_heart_beats = 0;
+ static unsigned long r4k_offset; /* Amount to increment compare reg each time */
+ static unsigned long r4k_cur;    /* What counter should be at next timer irq */
+ int	no_au1xxx_32khz;
+-void	(*au1k_wait_ptr)(void);
++extern int allow_au1k_wait; /* default off for CP0 Counter */
+ 
+ /* Cycle counter value at the previous timer interrupt.. */
+ static unsigned int timerhi = 0, timerlo = 0;
+ 
+ #ifdef CONFIG_PM
+-#define MATCH20_INC 328
+-extern void startup_match20_interrupt(void);
++#if HZ < 100 || HZ > 1000
++#error "unsupported HZ value! Must be in [100,1000]"
++#endif
++#define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */
++extern void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+ static unsigned long last_pc0, last_match20;
+ #endif
+ 
+@@ -117,17 +119,16 @@ null:
+ }
+ 
+ #ifdef CONFIG_PM
+-void counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	unsigned long pc0;
+ 	int time_elapsed;
+ 	static int jiffie_drift = 0;
+ 
+-	kstat.irqs[0][irq]++;
+ 	if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
+ 		/* should never happen! */
+-		printk(KERN_WARNING "counter 0 w status eror\n");
+-		return;
++		printk(KERN_WARNING "counter 0 w status error\n");
++		return IRQ_NONE;
+ 	}
+ 
+ 	pc0 = au_readl(SYS_TOYREAD);
+@@ -164,6 +165,8 @@ void counter0_irq(int irq, void *dev_id,
+ 		update_process_times(user_mode(regs));
+ #endif
+ 	}
++
++	return IRQ_HANDLED;
+ }
+ 
+ /* When we wakeup from sleep, we have to "catch up" on all of the
+@@ -388,7 +391,6 @@ void au1xxx_timer_setup(struct irqaction
+ {
+         unsigned int est_freq;
+ 	extern unsigned long (*do_gettimeoffset)(void);
+-	extern void au1k_wait(void);
+ 
+ 	printk("calculating r4koff... ");
+ 	r4k_offset = cal_r4koff();
+@@ -441,18 +443,18 @@ void au1xxx_timer_setup(struct irqaction
+ 		au_sync();
+ 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+ 
+-		/* setup match20 to interrupt once every 10ms */
++		/* setup match20 to interrupt once every HZ */
+ 		last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
+ 		au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+ 		au_sync();
+ 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+-		startup_match20_interrupt();
++		startup_match20_interrupt(counter0_irq);
+ 
+ 		do_gettimeoffset = do_fast_pm_gettimeoffset;
+ 
+ 		/* We can use the real 'wait' instruction.
+ 		*/
+-		au1k_wait_ptr = au1k_wait;
++		allow_au1k_wait = 1;
+ 	}
+ 
+ #else
+diff --git a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
+--- a/arch/mips/au1000/common/usbdev.c
++++ b/arch/mips/au1000/common/usbdev.c
+@@ -1005,11 +1005,11 @@ process_ep0_receive (struct usb_dev* dev
+ #endif
+ 		dev->ep0_stage = SETUP_STAGE;
+ 		break;
+-		}
++	}
+ 
+ 	spin_unlock(&ep0->lock);
+-		// we're done processing the packet, free it
+-		kfree(pkt);
++	// we're done processing the packet, free it
++	kfree(pkt);
+ }
+ 
+ 
+@@ -1072,8 +1072,7 @@ dma_done_ep0_intr(int irq, void *dev_id,
+ 			clear_dma_done1(ep0->indma);
+ 
+ 		pkt = send_packet_complete(ep0);
+-		if (pkt)
+-			kfree(pkt);
++		kfree(pkt);
+ 	}
+ 
+ 	/*
+@@ -1302,8 +1301,7 @@ usbdev_exit(void)
+ 		endpoint_flush(ep);
+ 	}
+ 
+-	if (usbdev.full_conf_desc)
+-		kfree(usbdev.full_conf_desc);
++	kfree(usbdev.full_conf_desc);
+ }
+ 
+ int
+diff --git a/arch/mips/au1000/csb250/init.c b/arch/mips/au1000/csb250/init.c
+--- a/arch/mips/au1000/csb250/init.c
++++ b/arch/mips/au1000/csb250/init.c
+@@ -35,7 +35,6 @@
+ #include <asm/bootinfo.h>
+ #include <linux/string.h>
+ #include <linux/kernel.h>
+-#include <linux/sched.h>
+ 
+ int prom_argc;
+ char **prom_argv, **prom_envp;
+diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c
+--- a/arch/mips/au1000/db1x00/irqmap.c
++++ b/arch/mips/au1000/db1x00/irqmap.c
+@@ -48,6 +48,38 @@
+ #include <asm/system.h>
+ #include <asm/mach-au1x00/au1000.h>
+ 
++#ifdef CONFIG_MIPS_DB1500
++char irq_tab_alchemy[][5] __initdata = {
++ [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT371   */
++ [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
++};
++#endif
++
++#ifdef CONFIG_MIPS_BOSPORUS
++char irq_tab_alchemy[][5] __initdata = {
++ [11] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 11 - miniPCI  */
++ [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - SN1741   */
++ [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
++};
++#endif
++
++#ifdef CONFIG_MIPS_MIRAGE
++char irq_tab_alchemy[][5] __initdata = {
++ [11] =	{ -1, INTD, INTX, INTX, INTX},   /* IDSEL 11 - SMI VGX */
++ [12] =	{ -1, INTX, INTX, INTC, INTX},   /* IDSEL 12 - PNX1300 */
++ [13] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 13 - miniPCI */
++};
++#endif
++
++#ifdef CONFIG_MIPS_DB1550
++char irq_tab_alchemy[][5] __initdata = {
++ [11] =	{ -1, INTC, INTX, INTX, INTX},   /* IDSEL 11 - on-board HPT371    */
++ [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
++ [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
++};
++#endif
++
++
+ au1xxx_irq_map_t au1xxx_irq_map[] = {
+ 
+ #ifndef CONFIG_MIPS_MIRAGE
+diff --git a/arch/mips/au1000/db1x00/mirage_ts.c b/arch/mips/au1000/db1x00/mirage_ts.c
+--- a/arch/mips/au1000/db1x00/mirage_ts.c
++++ b/arch/mips/au1000/db1x00/mirage_ts.c
+@@ -102,15 +102,15 @@ static struct {
+ } mirage_ts_cal =
+ {
+ #if 0
+-	xscale:   84,
+-	xtrans: -157,
+-	yscale:   66,
+-	ytrans: -150,
++	.xscale   = 84,
++	.xtrans = -157,
++	.yscale   = 66,
++	.ytrans = -150,
+ #else
+-	xscale:   84,
+-	xtrans: -150,
+-	yscale:   66,
+-	ytrans: -146,
++	.xscale   = 84,
++	.xtrans = -150,
++	.yscale   = 66,
++	.ytrans = -146,
+ #endif
+ };
+ 
+diff --git a/arch/mips/au1000/hydrogen3/init.c b/arch/mips/au1000/hydrogen3/init.c
+--- a/arch/mips/au1000/hydrogen3/init.c
++++ b/arch/mips/au1000/hydrogen3/init.c
+@@ -37,7 +37,6 @@
+ #include <linux/config.h>
+ #include <linux/string.h>
+ #include <linux/kernel.h>
+-#include <linux/sched.h>
+ 
+ int prom_argc;
+ char **prom_argv, **prom_envp;
+diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
+--- a/arch/mips/au1000/mtx-1/init.c
++++ b/arch/mips/au1000/mtx-1/init.c
+@@ -33,7 +33,6 @@
+ #include <linux/sched.h>
+ #include <linux/init.h>
+ #include <linux/mm.h>
+-#include <linux/sched.h>
+ #include <linux/bootmem.h>
+ #include <asm/addrspace.h>
+ #include <asm/bootinfo.h>
+diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c
+--- a/arch/mips/au1000/mtx-1/irqmap.c
++++ b/arch/mips/au1000/mtx-1/irqmap.c
+@@ -47,6 +47,17 @@
+ #include <asm/system.h>
+ #include <asm/mach-au1x00/au1000.h>
+ 
++char irq_tab_alchemy[][5] __initdata = {
++ [0] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 00 - AdapterA-Slot0 (top)    */
++ [1] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 01 - AdapterA-Slot1 (bottom) */
++ [2] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 02 - AdapterB-Slot0 (top)    */
++ [3] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 03 - AdapterB-Slot1 (bottom) */
++ [4] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 04 - AdapterC-Slot0 (top)    */
++ [5] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 05 - AdapterC-Slot1 (bottom) */
++ [6] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 06 - AdapterD-Slot0 (top)    */
++ [7] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 07 - AdapterD-Slot1 (bottom) */
++};
++
+ au1xxx_irq_map_t au1xxx_irq_map[] = {
+        { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+        { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
+--- a/arch/mips/au1000/pb1000/init.c
++++ b/arch/mips/au1000/pb1000/init.c
+@@ -65,5 +65,4 @@ void __init prom_init(void)
+ 		memsize = simple_strtol(memsize_str, NULL, 0);
+ 	}
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+-	return 0;
+ }
+diff --git a/arch/mips/au1000/pb1200/Makefile b/arch/mips/au1000/pb1200/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/au1000/pb1200/Makefile
+@@ -0,0 +1,5 @@
++#
++# Makefile for the Alchemy Semiconductor PB1200 board.
++#
++
++lib-y := init.o board_setup.o irqmap.o
+diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/au1000/pb1200/board_setup.c
+@@ -0,0 +1,193 @@
++/*
++ *
++ * BRIEF MODULE DESCRIPTION
++ *	Alchemy Pb1200/Db1200 board setup.
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the 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  SOFTWARE  IS PROVIDED   ``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 AUTHOR  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.
++ *
++ *  You 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/config.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/ioport.h>
++#include <linux/mm.h>
++#include <linux/console.h>
++#include <linux/mc146818rtc.h>
++#include <linux/delay.h>
++
++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
++#include <linux/ide.h>
++#endif
++
++#include <asm/cpu.h>
++#include <asm/bootinfo.h>
++#include <asm/irq.h>
++#include <asm/mipsregs.h>
++#include <asm/reboot.h>
++#include <asm/pgtable.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-au1x00/au1xxx_dbdma.h>
++
++#ifdef CONFIG_MIPS_PB1200
++#include <asm/mach-pb1x00/pb1200.h>
++#endif
++
++#ifdef CONFIG_MIPS_DB1200
++#include <asm/mach-db1x00/db1200.h>
++#define PB1200_ETH_INT DB1200_ETH_INT
++#define PB1200_IDE_INT DB1200_IDE_INT
++#endif
++
++extern void _board_init_irq(void);
++extern void	(*board_init_irq)(void);
++
++void board_reset (void)
++{
++	bcsr->resets = 0;
++	bcsr->system = 0;
++}
++
++void __init board_setup(void)
++{
++	char *argptr = NULL;
++	u32 pin_func;
++
++#if 0
++	/* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
++	 * but it is board specific code, so put it here.
++	 */
++	pin_func = au_readl(SYS_PINFUNC);
++	au_sync();
++	pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
++	au_writel(pin_func, SYS_PINFUNC);
++
++	au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
++	au_sync();
++#endif
++
++#if defined(CONFIG_I2C_AU1550)
++	{
++	u32 freq0, clksrc;
++
++	/* Select SMBUS in CPLD */
++	bcsr->resets &= ~(BCSR_RESETS_PCS0MUX);
++
++	pin_func = au_readl(SYS_PINFUNC);
++	au_sync();
++	pin_func &= ~(3<<17 | 1<<4);
++	/* Set GPIOs correctly */
++	pin_func |= 2<<17;
++	au_writel(pin_func, SYS_PINFUNC);
++	au_sync();
++
++	/* The i2c driver depends on 50Mhz clock */
++	freq0 = au_readl(SYS_FREQCTRL0);
++	au_sync();
++	freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
++	freq0 |= (3<<SYS_FC_FRDIV1_BIT);
++	/* 396Mhz / (3+1)*2 == 49.5Mhz */
++	au_writel(freq0, SYS_FREQCTRL0);
++	au_sync();
++	freq0 |= SYS_FC_FE1;
++	au_writel(freq0, SYS_FREQCTRL0);
++	au_sync();
++
++	clksrc = au_readl(SYS_CLKSRC);
++	au_sync();
++	clksrc &= ~0x01f00000;
++	/* bit 22 is EXTCLK0 for PSC0 */
++	clksrc |= (0x3 << 22);
++	au_writel(clksrc, SYS_CLKSRC);
++	au_sync();
++	}
++#endif
++
++#ifdef CONFIG_FB_AU1200
++	argptr = prom_getcmdline();
++#ifdef CONFIG_MIPS_PB1200
++	strcat(argptr, " video=au1200fb:panel:bs");
++#endif
++#ifdef CONFIG_MIPS_DB1200
++	strcat(argptr, " video=au1200fb:panel:bs");
++#endif
++#endif
++
++	/* The Pb1200 development board uses external MUX for PSC0 to
++	support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
++	*/
++#if defined(CONFIG_AU1XXX_PSC_SPI) && defined(CONFIG_I2C_AU1550)
++	#error I2C and SPI are mutually exclusive. Both are physically connected to PSC0.\
++			Refer to Pb1200/Db1200 documentation.
++#elif defined( CONFIG_AU1XXX_PSC_SPI )
++	bcsr->resets |= BCSR_RESETS_PCS0MUX;
++	/*Hard Coding Value to enable Temp Sensors [bit 14] Value for SOC Au1200. Pls refer documentation*/
++	  bcsr->resets =0x900f;
++#elif defined( CONFIG_I2C_AU1550 )
++	bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
++#endif
++	au_sync();
++
++#ifdef CONFIG_MIPS_PB1200
++	printk("AMD Alchemy Pb1200 Board\n");
++#endif
++#ifdef CONFIG_MIPS_DB1200
++	printk("AMD Alchemy Db1200 Board\n");
++#endif
++
++	/* Setup Pb1200 External Interrupt Controller */
++	{
++		extern void (*board_init_irq)(void);
++		extern void _board_init_irq(void);
++		board_init_irq = _board_init_irq;
++	}
++}
++
++int
++board_au1200fb_panel (void)
++{
++	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++	int p;
++
++	p = bcsr->switches;
++	p >>= 8;
++	p &= 0x0F;
++	return p;
++}
++
++int
++board_au1200fb_panel_init (void)
++{
++	/* Apply power */
++    BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++	bcsr->board |= (BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
++	/*printk("board_au1200fb_panel_init()\n"); */
++	return 0;
++}
++
++int
++board_au1200fb_panel_shutdown (void)
++{
++	/* Remove power */
++    BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++	bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
++	/*printk("board_au1200fb_panel_shutdown()\n"); */
++	return 0;
++}
++
+diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/au1000/pb1200/init.c
+@@ -0,0 +1,69 @@
++/*
++ *
++ * BRIEF MODULE DESCRIPTION
++ *	PB1200 board setup
++ *
++ * Copyright 2001 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *         	ppopov at mvista.com or source at 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  SOFTWARE  IS PROVIDED   ``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 AUTHOR  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.
++ *
++ *  You 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/mm.h>
++#include <linux/sched.h>
++#include <linux/bootmem.h>
++#include <asm/addrspace.h>
++#include <asm/bootinfo.h>
++#include <linux/string.h>
++#include <linux/kernel.h>
++
++int prom_argc;
++char **prom_argv, **prom_envp;
++extern void  __init prom_init_cmdline(void);
++extern char *prom_getenv(char *envname);
++
++const char *get_system_type(void)
++{
++	return "Alchemy Pb1200";
++}
++
++void __init prom_init(void)
++{
++	unsigned char *memsize_str;
++	unsigned long memsize;
++
++	prom_argc = (int) fw_arg0;
++	prom_argv = (char **) fw_arg1;
++	prom_envp = (char **) fw_arg2;
++
++	mips_machgroup = MACH_GROUP_ALCHEMY;
++	mips_machtype = MACH_PB1200;
++
++	prom_init_cmdline();
++	memsize_str = prom_getenv("memsize");
++	if (!memsize_str) {
++		memsize = 0x08000000;
++	} else {
++		memsize = simple_strtol(memsize_str, NULL, 0);
++	}
++	add_memory_region(0, memsize, BOOT_MEM_RAM);
++}
+diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/au1000/pb1200/irqmap.c
+@@ -0,0 +1,182 @@
++/*
++ * BRIEF MODULE DESCRIPTION
++ *	Au1xxx irq map table
++ *
++ *  This program is free software; you can redistribute	 it and/or modify it
++ *  under  the terms of	 the 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  SOFTWARE  IS PROVIDED	  ``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 AUTHOR  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.
++ *
++ *  You 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/config.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/irq.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/delay.h>
++
++#include <asm/bitops.h>
++#include <asm/bootinfo.h>
++#include <asm/io.h>
++#include <asm/mipsregs.h>
++#include <asm/system.h>
++#include <asm/mach-au1x00/au1000.h>
++
++#ifdef CONFIG_MIPS_PB1200
++#include <asm/mach-pb1x00/pb1200.h>
++#endif
++
++#ifdef CONFIG_MIPS_DB1200
++#include <asm/mach-db1x00/db1200.h>
++#define PB1200_INT_BEGIN DB1200_INT_BEGIN
++#define PB1200_INT_END DB1200_INT_END
++#endif
++
++au1xxx_irq_map_t au1xxx_irq_map[] = {
++	{ AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade
++};
++
++int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
++
++/*
++ *	Support for External interrupts on the PbAu1200 Development platform.
++ */
++static volatile int pb1200_cascade_en=0;
++
++irqreturn_t pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs)
++{
++	unsigned short bisr = bcsr->int_status;
++	int extirq_nr = 0;
++
++	/* Clear all the edge interrupts. This has no effect on level */
++	bcsr->int_status = bisr;
++	for( ; bisr; bisr &= (bisr-1) )
++	{
++		extirq_nr = (PB1200_INT_BEGIN-1) + au_ffs(bisr);
++		/* Ack and dispatch IRQ */
++		do_IRQ(extirq_nr,regs);
++	}
++	return IRQ_RETVAL(1);
++}
++
++inline void pb1200_enable_irq(unsigned int irq_nr)
++{
++	bcsr->intset_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
++	bcsr->intset = 1<<(irq_nr - PB1200_INT_BEGIN);
++}
++
++inline void pb1200_disable_irq(unsigned int irq_nr)
++{
++	bcsr->intclr_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
++	bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN);
++}
++
++static unsigned int pb1200_startup_irq( unsigned int irq_nr )
++{
++	if (++pb1200_cascade_en == 1)
++	{
++		request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
++			0, "Pb1200 Cascade", (void *)&pb1200_cascade_handler );
++#ifdef CONFIG_MIPS_PB1200
++    /* We have a problem with CPLD rev3. Enable a workaround */
++	if( ((bcsr->whoami & BCSR_WHOAMI_CPLD)>>4) <= 3)
++	{
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n");
++		printk("updated to latest revision. This software will not\n");
++		printk("work on anything less than CPLD rev4\n");
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		printk("\nWARNING!!!\n");
++		while(1);
++	}
++#endif
++	}
++	pb1200_enable_irq(irq_nr);
++	return 0;
++}
++
++static void pb1200_shutdown_irq( unsigned int irq_nr )
++{
++	pb1200_disable_irq(irq_nr);
++	if (--pb1200_cascade_en == 0)
++	{
++		free_irq(AU1000_GPIO_7,&pb1200_cascade_handler );
++	}
++	return;
++}
++
++static inline void pb1200_mask_and_ack_irq(unsigned int irq_nr)
++{
++	pb1200_disable_irq( irq_nr );
++}
++
++static void pb1200_end_irq(unsigned int irq_nr)
++{
++	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
++		pb1200_enable_irq(irq_nr);
++	}
++}
++
++static struct hw_interrupt_type external_irq_type =
++{
++#ifdef CONFIG_MIPS_PB1200
++	"Pb1200 Ext",
++#endif
++#ifdef CONFIG_MIPS_DB1200
++	"Db1200 Ext",
++#endif
++	pb1200_startup_irq,
++	pb1200_shutdown_irq,
++	pb1200_enable_irq,
++	pb1200_disable_irq,
++	pb1200_mask_and_ack_irq,
++	pb1200_end_irq,
++	NULL
++};
++
++void _board_init_irq(void)
++{
++	int irq_nr;
++
++	for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++)
++	{
++		irq_desc[irq_nr].handler = &external_irq_type;
++		pb1200_disable_irq(irq_nr);
++	}
++
++	/* GPIO_7 can not be hooked here, so it is hooked upon first
++	request of any source attached to the cascade */
++}
++
+diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c
+--- a/arch/mips/au1000/pb1500/irqmap.c
++++ b/arch/mips/au1000/pb1500/irqmap.c
+@@ -47,6 +47,11 @@
+ #include <asm/system.h>
+ #include <asm/mach-au1x00/au1000.h>
+ 
++char irq_tab_alchemy[][5] __initdata = {
++ [12] = { -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT370   */
++ [13] = { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
++};
++
+ au1xxx_irq_map_t au1xxx_irq_map[] = {
+ 	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+ 	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c
+--- a/arch/mips/au1000/pb1550/irqmap.c
++++ b/arch/mips/au1000/pb1550/irqmap.c
+@@ -47,6 +47,11 @@
+ #include <asm/system.h>
+ #include <asm/mach-au1x00/au1000.h>
+ 
++char irq_tab_alchemy[][5] __initdata = {
++ [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
++ [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
++};
++
+ au1xxx_irq_map_t au1xxx_irq_map[] = {
+ 	{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
+diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
+--- a/arch/mips/boot/Makefile
++++ b/arch/mips/boot/Makefile
+@@ -33,6 +33,9 @@ vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINU
+ $(obj)/elf2ecoff: $(obj)/elf2ecoff.c
+ 	$(HOSTCC) -o $@ $^
+ 
++vmlinux.bin: $(VMLINUX)
++	$(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $(obj)/vmlinux.bin
++
+ vmlinux.srec: $(VMLINUX)
+ 	$(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec
+ 
+@@ -45,5 +48,6 @@ archhelp:
+ 
+ clean-files += addinitrd \
+ 	       elf2ecoff \
++	       vmlinux.bin \
+ 	       vmlinux.ecoff \
+ 	       vmlinux.srec
+diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
+--- a/arch/mips/cobalt/Makefile
++++ b/arch/mips/cobalt/Makefile
+@@ -2,6 +2,6 @@
+ # Makefile for the Cobalt micro systems family specific parts of the kernel
+ #
+ 
+-obj-y	 := irq.o int-handler.o reset.o setup.o promcon.o
++obj-y	 := irq.o int-handler.o reset.o setup.o
+ 
+ EXTRA_AFLAGS := $(CFLAGS)
+diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S
+--- a/arch/mips/cobalt/int-handler.S
++++ b/arch/mips/cobalt/int-handler.S
+@@ -18,8 +18,8 @@
+ 		SAVE_ALL
+ 		CLI
+ 
+-		la	ra, ret_from_irq
+-		move	a1, sp
++		PTR_LA	ra, ret_from_irq
++		move	a0, sp
+ 		j	cobalt_irq
+ 
+ 		END(cobalt_handle_int)
+diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
+--- a/arch/mips/cobalt/irq.c
++++ b/arch/mips/cobalt/irq.c
+@@ -10,6 +10,8 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
+ 
+ #include <asm/i8259.h>
+ #include <asm/irq_cpu.h>
+@@ -25,8 +27,8 @@ extern void cobalt_handle_int(void);
+  * the CPU interrupt lines, and ones that come in on the via chip. The CPU
+  * mappings are:
+  *
+- *    16,  - Software interrupt 0 (unused)	IE_SW0
+- *    17   - Software interrupt 1 (unused)	IE_SW0
++ *    16   - Software interrupt 0 (unused)	IE_SW0
++ *    17   - Software interrupt 1 (unused)	IE_SW1
+  *    18   - Galileo chip (timer)		IE_IRQ0
+  *    19   - Tulip 0 + NCR SCSI			IE_IRQ1
+  *    20   - Tulip 1				IE_IRQ2
+@@ -42,61 +44,94 @@ extern void cobalt_handle_int(void);
+  *    15  - IDE1
+  */
+ 
+-asmlinkage void cobalt_irq(struct pt_regs *regs)
++static inline void galileo_irq(struct pt_regs *regs)
+ {
+-	unsigned int pending = read_c0_status() & read_c0_cause();
++	unsigned int mask, pending, devfn;
+ 
+-	if (pending & CAUSEF_IP2) {			/* int 18 */
+-		unsigned long irq_src = GALILEO_INL(GT_INTRCAUSE_OFS);
++	mask = GALILEO_INL(GT_INTRMASK_OFS);
++	pending = GALILEO_INL(GT_INTRCAUSE_OFS) & mask;
+ 
+-		/* Check for timer irq ... */
+-		if (irq_src & GALILEO_T0EXP) {
+-			/* Clear the int line */
+-			GALILEO_OUTL(0, GT_INTRCAUSE_OFS);
+-			do_IRQ(COBALT_TIMER_IRQ, regs);
+-		}
+-		return;
+-	}
++	if (pending & GALILEO_INTR_T0EXP) {
+ 
+-	if (pending & CAUSEF_IP6) {			/* int 22 */
+-		int irq = i8259_irq();
++		GALILEO_OUTL(~GALILEO_INTR_T0EXP, GT_INTRCAUSE_OFS);
++		do_IRQ(COBALT_GALILEO_IRQ, regs);
+ 
+-		if (irq >= 0)
+-			do_IRQ(irq, regs);
+-		return;
+-	}
++	} else if (pending & GALILEO_INTR_RETRY_CTR) {
+ 
+-	if (pending & CAUSEF_IP3) {			/* int 19 */
+-		do_IRQ(COBALT_ETH0_IRQ, regs);
+-		return;
+-	}
++		devfn = GALILEO_INL(GT_PCI0_CFGADDR_OFS) >> 8;
++		GALILEO_OUTL(~GALILEO_INTR_RETRY_CTR, GT_INTRCAUSE_OFS);
++		printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n",
++			PCI_SLOT(devfn), PCI_FUNC(devfn));
+ 
+-	if (pending & CAUSEF_IP4) {			/* int 20 */
+-		do_IRQ(COBALT_ETH1_IRQ, regs);
+-		return;
+-	}
++	} else {
+ 
+-	if (pending & CAUSEF_IP5) {			/* int 21 */
+-		do_IRQ(COBALT_SERIAL_IRQ, regs);
+-		return;
++		GALILEO_OUTL(mask & ~pending, GT_INTRMASK_OFS);
++		printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending);
+ 	}
++}
+ 
+-	if (pending & CAUSEF_IP7) {			/* int 23 */
+-		do_IRQ(COBALT_QUBE_SLOT_IRQ, regs);
+-		return;
+-	}
++static inline void via_pic_irq(struct pt_regs *regs)
++{
++	int irq;
++
++	irq = i8259_irq();
++	if (irq >= 0)
++		do_IRQ(irq, regs);
+ }
+ 
++asmlinkage void cobalt_irq(struct pt_regs *regs)
++{
++	unsigned pending;
++
++	pending = read_c0_status() & read_c0_cause();
++
++	if (pending & CAUSEF_IP2)			/* COBALT_GALILEO_IRQ (18) */
++
++		galileo_irq(regs);
++
++	else if (pending & CAUSEF_IP6)			/* COBALT_VIA_IRQ (22) */
++
++		via_pic_irq(regs);
++
++	else if (pending & CAUSEF_IP3)			/* COBALT_ETH0_IRQ (19) */
++
++		do_IRQ(COBALT_CPU_IRQ + 3, regs);
++
++	else if (pending & CAUSEF_IP4)			/* COBALT_ETH1_IRQ (20) */
++
++		do_IRQ(COBALT_CPU_IRQ + 4, regs);
++
++	else if (pending & CAUSEF_IP5)			/* COBALT_SERIAL_IRQ (21) */
++
++		do_IRQ(COBALT_CPU_IRQ + 5, regs);
++
++	else if (pending & CAUSEF_IP7)			/* IRQ 23 */
++
++		do_IRQ(COBALT_CPU_IRQ + 7, regs);
++}
++
++static struct irqaction irq_via = {
++	no_action, 0, { { 0, } }, "cascade", NULL, NULL
++};
++
+ void __init arch_init_irq(void)
+ {
++	/*
++	 * Mask all Galileo interrupts. The Galileo
++	 * handler is set in cobalt_timer_setup()
++	 */
++	GALILEO_OUTL(0, GT_INTRMASK_OFS);
++
+ 	set_except_vector(0, cobalt_handle_int);
+ 
+ 	init_i8259_irqs();				/*  0 ... 15 */
+-	mips_cpu_irq_init(16);				/* 16 ... 23 */
++	mips_cpu_irq_init(COBALT_CPU_IRQ);		/* 16 ... 23 */
+ 
+ 	/*
+ 	 * Mask all cpu interrupts
+ 	 *  (except IE4, we already masked those at VIA level)
+ 	 */
+ 	change_c0_status(ST0_IM, IE_IRQ4);
++
++	setup_irq(COBALT_VIA_IRQ, &irq_via);
+ }
+diff --git a/arch/mips/cobalt/promcon.c b/arch/mips/cobalt/promcon.c
+deleted file mode 100644
+--- a/arch/mips/cobalt/promcon.c
++++ /dev/null
+@@ -1,87 +0,0 @@
+-/*
+- * PROM console for Cobalt Raq2
+- *
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License.  See the file "COPYING" in the main directory of this archive
+- * for more details.
+- *
+- * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+- * Copyright (C) 2001 by Liam Davies (ldavies at agile.tv)
+- *
+- */
+-
+-#include <linux/init.h>
+-#include <linux/console.h>
+-#include <linux/kdev_t.h>
+-#include <linux/serial_reg.h>
+-
+-#include <asm/delay.h>
+-#include <asm/serial.h>
+-#include <asm/io.h>
+-
+-static unsigned long port = 0xc800000;
+-
+-static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr)
+-{
+-	char lsr;
+-
+-	do {
+-		lsr = inb(ioaddr + UART_LSR);
+-	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+-	outb(ch, ioaddr + UART_TX);
+-}
+-
+-static __inline__ char ns16550_cons_get_char(unsigned long ioaddr)
+-{
+-	while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0)
+-		udelay(1);
+-	return inb(ioaddr + UART_RX);
+-}
+-
+-void ns16550_console_write(struct console *co, const char *s, unsigned count)
+-{
+-	char lsr, ier;
+-	unsigned i;
+-
+-	ier = inb(port + UART_IER);
+-	outb(0x00, port + UART_IER);
+-	for (i=0; i < count; i++, s++) {
+-
+-		if(*s == '\n')
+-			ns16550_cons_put_char('\r', port);
+-		ns16550_cons_put_char(*s, port);
+-	}
+-
+-	do {
+-		lsr = inb(port + UART_LSR);
+-   	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+-
+-	outb(ier, port + UART_IER);
+-}
+-
+-char getDebugChar(void)
+-{
+-	return ns16550_cons_get_char(port);
+-}
+-
+-void putDebugChar(char kgdb_char)
+-{
+-	ns16550_cons_put_char(kgdb_char, port);
+-}
+-
+-static struct console ns16550_console = {
+-    .name	= "prom",
+-    .setup	= NULL,
+-    .write	= ns16550_console_write,
+-    .flags	= CON_PRINTBUFFER,
+-    .index	= -1,
+-};
+-
+-static int __init ns16550_setup_console(void)
+-{
+-	register_console(&ns16550_console);
+-
+-	return 0;
+-}
+-
+-console_initcall(ns16550_setup_console);
+diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
+--- a/arch/mips/cobalt/reset.c
++++ b/arch/mips/cobalt/reset.c
+@@ -16,48 +16,45 @@
+ #include <asm/reboot.h>
+ #include <asm/system.h>
+ #include <asm/mipsregs.h>
++#include <asm/cobalt/cobalt.h>
+ 
+-void cobalt_machine_restart(char *command)
++void cobalt_machine_halt(void)
+ {
+-	*(volatile char *)0xbc000000 = 0x0f;
++	int state, last, diff;
++	unsigned long mark;
+ 
+ 	/*
+-	 * 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.
++	 * turn off bar on Qube, flash power off LED on RaQ (0.5Hz)
++	 *
++	 * restart if ENTER and SELECT are pressed
+ 	 */
+-	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));
+-}
+ 
+-extern int led_state;
+-#define kLED            0xBC000000
+-#define LEDSet(x)       (*(volatile unsigned char *) kLED) = (( unsigned char)x)
++	last = COBALT_KEY_PORT;
+ 
+-void cobalt_machine_halt(void)
+-{
+-	int mark;
++	for (state = 0;;) {
++
++		state ^= COBALT_LED_POWER_OFF;
++		COBALT_LED_PORT = state;
++
++		diff = COBALT_KEY_PORT ^ last;
++		last ^= diff;
+ 
+-	/* Blink our cute? little LED (number 3)... */
+-	while (1) {
+-		led_state = led_state | ( 1 << 3 );
+-		LEDSet(led_state);
+-		mark = jiffies;
+-		while (jiffies<(mark+HZ));
+-		led_state = led_state & ~( 1 << 3 );
+-		LEDSet(led_state);
+-		mark = jiffies;
+-		while (jiffies<(mark+HZ));
++		if((diff & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)) && !(~last & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)))
++			COBALT_LED_PORT = COBALT_LED_RESET;
++
++		for (mark = jiffies; jiffies - mark < HZ;)
++			;
+ 	}
+ }
+ 
++void cobalt_machine_restart(char *command)
++{
++	COBALT_LED_PORT = COBALT_LED_RESET;
++
++	/* we should never get here */
++	cobalt_machine_halt();
++}
++
+ /*
+  * This triggers the luser mode device driver for the power switch ;-)
+  */
+diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
+--- a/arch/mips/cobalt/setup.c
++++ b/arch/mips/cobalt/setup.c
+@@ -13,6 +13,8 @@
+ #include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
+ 
+ #include <asm/bootinfo.h>
+ #include <asm/time.h>
+@@ -21,6 +23,7 @@
+ #include <asm/processor.h>
+ #include <asm/reboot.h>
+ #include <asm/gt64120.h>
++#include <asm/serial.h>
+ 
+ #include <asm/cobalt/cobalt.h>
+ 
+@@ -30,45 +33,44 @@ extern void cobalt_machine_power_off(voi
+ 
+ int cobalt_board_id;
+ 
+-static char my_cmdline[CL_SIZE] = {
+- "console=ttyS0,115200 "
+-#ifdef CONFIG_IP_PNP
+- "ip=on "
+-#endif
+-#ifdef CONFIG_ROOT_NFS
+- "root=/dev/nfs "
+-#else
+- "root=/dev/hda1 "
+-#endif
+- };
+-
+ const char *get_system_type(void)
+ {
++	switch (cobalt_board_id) {
++		case COBALT_BRD_ID_QUBE1:
++			return "Cobalt Qube";
++		case COBALT_BRD_ID_RAQ1:
++			return "Cobalt RaQ";
++		case COBALT_BRD_ID_QUBE2:
++			return "Cobalt Qube2";
++		case COBALT_BRD_ID_RAQ2:
++			return "Cobalt RaQ2";
++	}
+ 	return "MIPS Cobalt";
+ }
+ 
+ static void __init cobalt_timer_setup(struct irqaction *irq)
+ {
+-	/* Load timer value for 150 Hz */
+-	GALILEO_OUTL(500000, GT_TC0_OFS);
++	/* Load timer value for 1KHz (TCLK is 50MHz) */
++	GALILEO_OUTL(50*1000*1000 / 1000, GT_TC0_OFS);
++
++	/* Enable timer */
++	GALILEO_OUTL(GALILEO_ENTC0 | GALILEO_SELTC0, GT_TC_CONTROL_OFS);
+ 
+-	/* Register our timer interrupt */
+-	setup_irq(COBALT_TIMER_IRQ, irq);
++	/* Register interrupt */
++	setup_irq(COBALT_GALILEO_IRQ, irq);
+ 
+-	/* Enable timer ints */
+-	GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS);
+-	/* Unmask timer int */
+-	GALILEO_OUTL(0x100, GT_INTRMASK_OFS);
++	/* Enable interrupt */
++	GALILEO_OUTL(GALILEO_INTR_T0EXP | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS);
+ }
+ 
+ extern struct pci_ops gt64111_pci_ops;
+ 
+ static struct resource cobalt_mem_resource = {
+-	"GT64111 PCI MEM", GT64111_IO_BASE, 0xffffffffUL, IORESOURCE_MEM
++	"PCI memory", GT64111_MEM_BASE, GT64111_MEM_END, IORESOURCE_MEM
+ };
+ 
+ static struct resource cobalt_io_resource = {
+-	"GT64111 IO MEM", 0x00001000UL, 0x0fffffffUL, IORESOURCE_IO
++	"PCI I/O", 0x1000, 0xffff, IORESOURCE_IO
+ };
+ 
+ static struct resource cobalt_io_resources[] = {
+@@ -86,11 +88,12 @@ static struct pci_controller cobalt_pci_
+ 	.mem_resource	= &cobalt_mem_resource,
+ 	.mem_offset	= 0,
+ 	.io_resource	= &cobalt_io_resource,
+-	.io_offset	= 0x00001000UL - GT64111_IO_BASE
++	.io_offset	= 0 - GT64111_IO_BASE
+ };
+ 
+-static void __init cobalt_setup(void)
++void __init plat_setup(void)
+ {
++	static struct uart_port uart;
+ 	unsigned int devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0);
+ 	int i;
+ 
+@@ -100,7 +103,10 @@ static void __init cobalt_setup(void)
+ 
+ 	board_timer_setup = cobalt_timer_setup;
+ 
+-        set_io_port_base(KSEG1ADDR(GT64111_IO_BASE));
++        set_io_port_base(CKSEG1ADDR(GT64111_IO_BASE));
++
++	/* I/O port resource must include UART and LCD/buttons */
++	ioport_resource.end = 0x0fffffff;
+ 
+ 	/*
+ 	 * This is a prom style console. We just poke at the
+@@ -120,27 +126,61 @@ static void __init cobalt_setup(void)
+         cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8);
+         cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id);
+ 
++	printk("Cobalt board ID: %d\n", cobalt_board_id);
++
+ #ifdef CONFIG_PCI
+ 	register_pci_controller(&cobalt_pci_controller);
+ #endif
+-}
+ 
+-early_initcall(cobalt_setup);
++#ifdef CONFIG_SERIAL_8250
++	if (cobalt_board_id > COBALT_BRD_ID_RAQ1) {
++
++		uart.line	= 0;
++		uart.type	= PORT_UNKNOWN;
++		uart.uartclk	= 18432000;
++		uart.irq	= COBALT_SERIAL_IRQ;
++		uart.flags	= STD_COM_FLAGS;
++		uart.iobase	= 0xc800000;
++		uart.iotype	= UPIO_PORT;
++
++		early_serial_setup(&uart);
++	}
++#endif
++}
+ 
+ /*
+  * Prom init. We read our one and only communication with the firmware.
+- * Grab the amount of installed memory
++ * Grab the amount of installed memory.
++ * Better boot loaders (CoLo) pass a command line too :-)
+  */
+ 
+ void __init prom_init(void)
+ {
+-	int argc = fw_arg0;
+-
+-	strcpy(arcs_cmdline, my_cmdline);
++	int narg, indx, posn, nchr;
++	unsigned long memsz;
++	char **argv;
+ 
+ 	mips_machgroup = MACH_GROUP_COBALT;
+ 
+-	add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
++	memsz = fw_arg0 & 0x7fff0000;
++	narg = fw_arg0 & 0x0000ffff;
++
++	if (narg) {
++		arcs_cmdline[0] = '\0';
++		argv = (char **) fw_arg1;
++		posn = 0;
++		for (indx = 1; indx < narg; ++indx) {
++			nchr = strlen(argv[indx]);
++			if (posn + 1 + nchr + 1 > sizeof(arcs_cmdline))
++				break;
++			if (posn)
++				arcs_cmdline[posn++] = ' ';
++			strcpy(arcs_cmdline + posn, argv[indx]);
++			posn += nchr;
++		}
++	}
++
++	add_memory_region(0x0, memsz, BOOT_MEM_RAM);
+ }
+ 
+ unsigned long __init prom_free_prom_memory(void)
+diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
+--- a/arch/mips/configs/atlas_defconfig
++++ b/arch/mips/configs/atlas_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:00 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:13 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,42 +59,72 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT is not set
+ # CONFIG_MIPS_ITE8172 is not set
++# CONFIG_MACH_JAZZ is not set
++# CONFIG_LASAT is not set
+ CONFIG_MIPS_ATLAS=y
+ # CONFIG_MIPS_MALTA is not set
+ # CONFIG_MIPS_SEAD 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_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_MIPS_BONITO64=y
+ CONFIG_MIPS_MSC=y
+-# CONFIG_CPU_LITTLE_ENDIAN is not set
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_BOARDS_GEN=y
+ CONFIG_MIPS_GT64120=y
+ CONFIG_SWAP_IO_SPACE=y
+@@ -101,8 +134,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -118,15 +153,46 @@ CONFIG_CPU_MIPS32=y
+ # 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_BOARD_SCACHE=y
++CONFIG_RM7000_CPU_SCACHE=y
+ CONFIG_CPU_HAS_PREFETCH=y
++# CONFIG_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -135,7 +201,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -144,10 +209,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -160,199 +221,7 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
+-# Device Drivers
+-#
+-
+-#
+-# Generic Driver Options
+-#
+-CONFIG_STANDALONE=y
+-CONFIG_PREVENT_FIRMWARE_BUILD=y
+-CONFIG_FW_LOADER=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 is not set
+-# CONFIG_BLK_DEV_DAC960 is not set
+-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=4096
+-# CONFIG_BLK_DEV_INITRD is not set
+-CONFIG_INITRAMFS_SOURCE=""
+-# CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE 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=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 is not set
+-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 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_SCSI=y
+-CONFIG_SCSI_PROC_FS=y
+-
+-#
+-# SCSI support type (disk, tape, CD-ROM)
+-#
+-CONFIG_BLK_DEV_SD=y
+-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
+-
+-#
+-# 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=y
+-CONFIG_SCSI_FC_ATTRS=m
+-CONFIG_SCSI_ISCSI_ATTRS=m
+-
+-#
+-# SCSI low-level drivers
+-#
+-# 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_SCSI_SATA is not set
+-# CONFIG_SCSI_BUSLOGIC is not set
+-# CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_EATA_PIO is not set
+-# CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+-# CONFIG_SCSI_IPS is not set
+-# CONFIG_SCSI_INITIO is not set
+-# CONFIG_SCSI_INIA100 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_IOMAPPED is not set
+-# CONFIG_SCSI_IPR is not set
+-# CONFIG_SCSI_QLOGIC_ISP is not set
+-# CONFIG_SCSI_QLOGIC_FC is not set
+-# CONFIG_SCSI_QLOGIC_1280 is not set
+-CONFIG_SCSI_QLA2XXX=y
+-# CONFIG_SCSI_QLA21XX is not set
+-# CONFIG_SCSI_QLA22XX is not set
+-# CONFIG_SCSI_QLA2300 is not set
+-# CONFIG_SCSI_QLA2322 is not set
+-# CONFIG_SCSI_QLA6312 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=m
+-CONFIG_MD_LINEAR=m
+-CONFIG_MD_RAID0=m
+-CONFIG_MD_RAID1=m
+-CONFIG_MD_RAID10=m
+-CONFIG_MD_RAID5=m
+-CONFIG_MD_RAID6=m
+-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
+-
+-#
+-# 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
+-
+-#
+-# Networking support
++# Networking
+ #
+ CONFIG_NET=y
+ 
+@@ -361,15 +230,20 @@ CONFIG_NET=y
+ #
+ CONFIG_PACKET=y
+ CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=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=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
+@@ -387,8 +261,10 @@ CONFIG_INET_AH=m
+ CONFIG_INET_ESP=m
+ CONFIG_INET_IPCOMP=m
+ CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-CONFIG_IP_TCPDIAG_IPV6=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
+@@ -433,6 +309,9 @@ CONFIG_IPV6_TUNNEL=m
+ CONFIG_NETFILTER=y
+ # CONFIG_NETFILTER_DEBUG is not set
+ CONFIG_BRIDGE_NETFILTER=y
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
+ 
+ #
+ # IP: Netfilter Configuration
+@@ -440,11 +319,15 @@ CONFIG_BRIDGE_NETFILTER=y
+ CONFIG_IP_NF_CONNTRACK=m
+ CONFIG_IP_NF_CT_ACCT=y
+ CONFIG_IP_NF_CONNTRACK_MARK=y
++CONFIG_IP_NF_CONNTRACK_EVENTS=y
++CONFIG_IP_NF_CONNTRACK_NETLINK=m
+ CONFIG_IP_NF_CT_PROTO_SCTP=m
+ CONFIG_IP_NF_FTP=m
+ CONFIG_IP_NF_IRC=m
++# CONFIG_IP_NF_NETBIOS_NS is not set
+ CONFIG_IP_NF_TFTP=m
+ CONFIG_IP_NF_AMANDA=m
++CONFIG_IP_NF_PPTP=m
+ CONFIG_IP_NF_QUEUE=m
+ CONFIG_IP_NF_IPTABLES=m
+ CONFIG_IP_NF_MATCH_LIMIT=m
+@@ -469,9 +352,12 @@ CONFIG_IP_NF_MATCH_PHYSDEV=m
+ CONFIG_IP_NF_MATCH_ADDRTYPE=m
+ CONFIG_IP_NF_MATCH_REALM=m
+ CONFIG_IP_NF_MATCH_SCTP=m
++CONFIG_IP_NF_MATCH_DCCP=m
+ CONFIG_IP_NF_MATCH_COMMENT=m
+ CONFIG_IP_NF_MATCH_CONNMARK=m
++CONFIG_IP_NF_MATCH_CONNBYTES=m
+ CONFIG_IP_NF_MATCH_HASHLIMIT=m
++CONFIG_IP_NF_MATCH_STRING=m
+ CONFIG_IP_NF_FILTER=m
+ CONFIG_IP_NF_TARGET_REJECT=m
+ CONFIG_IP_NF_TARGET_LOG=m
+@@ -488,12 +374,14 @@ 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_MANGLE=m
+ CONFIG_IP_NF_TARGET_TOS=m
+ CONFIG_IP_NF_TARGET_ECN=m
+ CONFIG_IP_NF_TARGET_DSCP=m
+ CONFIG_IP_NF_TARGET_MARK=m
+ CONFIG_IP_NF_TARGET_CLASSIFY=m
++CONFIG_IP_NF_TARGET_TTL=m
+ CONFIG_IP_NF_TARGET_CONNMARK=m
+ CONFIG_IP_NF_TARGET_CLUSTERIP=m
+ CONFIG_IP_NF_RAW=m
+@@ -503,7 +391,7 @@ CONFIG_IP_NF_ARPFILTER=m
+ CONFIG_IP_NF_ARP_MANGLE=m
+ 
+ #
+-# IPv6: Netfilter Configuration
++# IPv6: Netfilter Configuration (EXPERIMENTAL)
+ #
+ CONFIG_IP6_NF_QUEUE=m
+ CONFIG_IP6_NF_IPTABLES=m
+@@ -523,8 +411,10 @@ CONFIG_IP6_NF_MATCH_EUI64=m
+ CONFIG_IP6_NF_MATCH_PHYSDEV=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_MARK=m
++CONFIG_IP6_NF_TARGET_HL=m
+ CONFIG_IP6_NF_RAW=m
+ 
+ #
+@@ -550,8 +440,11 @@ CONFIG_BRIDGE_EBT_REDIRECT=m
+ CONFIG_BRIDGE_EBT_SNAT=m
+ CONFIG_BRIDGE_EBT_LOG=m
+ CONFIG_BRIDGE_EBT_ULOG=m
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
+ 
+ #
+ # SCTP Configuration (EXPERIMENTAL)
+@@ -579,10 +472,6 @@ CONFIG_IPDDP_DECAP=y
+ CONFIG_NET_DIVERT=y
+ # 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=y
+ # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+@@ -602,6 +491,7 @@ CONFIG_NET_SCH_INGRESS=m
+ CONFIG_NET_QOS=y
+ CONFIG_NET_ESTIMATOR=y
+ CONFIG_NET_CLS=y
++CONFIG_NET_CLS_BASIC=m
+ CONFIG_NET_CLS_TCINDEX=m
+ CONFIG_NET_CLS_ROUTE4=m
+ CONFIG_NET_CLS_ROUTE=y
+@@ -612,6 +502,7 @@ CONFIG_NET_CLS_IND=y
+ # 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
+ 
+@@ -619,17 +510,222 @@ CONFIG_NET_CLS_POLICE=y
+ # 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_IEEE80211=m
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=m
++CONFIG_IEEE80211_CRYPT_CCMP=m
++CONFIG_IEEE80211_CRYPT_TKIP=m
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
++
++#
++# 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=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=4096
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_LBD is not set
++CONFIG_CDROM_PKTCDVD=m
++CONFIG_CDROM_PKTCDVD_BUFFERS=8
++# CONFIG_CDROM_PKTCDVD_WCACHE 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=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 is not set
++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 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=y
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++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=y
++CONFIG_SCSI_FC_ATTRS=m
++CONFIG_SCSI_ISCSI_ATTRS=m
++CONFIG_SCSI_SAS_ATTRS=m
++
++#
++# SCSI low-level drivers
++#
++# 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_SCSI_SATA 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=y
++CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
++CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
++CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
++# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
++# CONFIG_SCSI_IPR is not set
++# CONFIG_SCSI_QLOGIC_FC is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++CONFIG_SCSI_QLA2XXX=y
++# CONFIG_SCSI_QLA21XX is not set
++# CONFIG_SCSI_QLA22XX is not set
++# CONFIG_SCSI_QLA2300 is not set
++# CONFIG_SCSI_QLA2322 is not set
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX 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=m
++CONFIG_MD_LINEAR=m
++CONFIG_MD_RAID0=m
++CONFIG_MD_RAID1=m
++CONFIG_MD_RAID10=m
++CONFIG_MD_RAID5=m
++CONFIG_MD_RAID6=m
++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
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC 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=m
+ CONFIG_BONDING=m
+ CONFIG_EQUALIZER=m
+ CONFIG_TUN=m
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -637,6 +733,21 @@ CONFIG_TUN=m
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -681,13 +792,17 @@ CONFIG_LAN_SAA9730=y
+ # 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_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
+ 
+@@ -700,6 +815,8 @@ CONFIG_LAN_SAA9730=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -712,6 +829,8 @@ CONFIG_LAN_SAA9730=y
+ # 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
+@@ -741,19 +860,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-CONFIG_SERIO_LIBPS2=y
+-CONFIG_SERIO_RAW=y
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -766,6 +872,17 @@ CONFIG_MOUSE_SERIAL=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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=y
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -786,6 +903,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -812,6 +930,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -822,10 +945,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -845,7 +978,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -855,13 +987,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -879,10 +1007,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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
+@@ -903,12 +1036,14 @@ CONFIG_JFS_SECURITY=y
+ # CONFIG_JFS_STATISTICS is not set
+ CONFIG_FS_POSIX_ACL=y
+ CONFIG_XFS_FS=m
+-# CONFIG_XFS_RT is not set
+-CONFIG_XFS_QUOTA=y
++CONFIG_XFS_EXPORT=y
++CONFIG_XFS_QUOTA=m
+ CONFIG_XFS_SECURITY=y
+ CONFIG_XFS_POSIX_ACL=y
++# CONFIG_XFS_RT is not set
+ CONFIG_MINIX_FS=m
+ CONFIG_ROMFS_FS=m
++CONFIG_INOTIFY=y
+ CONFIG_QUOTA=y
+ # CONFIG_QFMT_V1 is not set
+ CONFIG_QFMT_V2=y
+@@ -916,6 +1051,7 @@ CONFIG_QUOTACTL=y
+ CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=y
+ # CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -943,12 +1079,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -974,16 +1108,19 @@ CONFIG_UFS_FS=m
+ #
+ 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=y
++# CONFIG_NFSD_V3_ACL is not set
+ # CONFIG_NFSD_V4 is not set
+ # CONFIG_NFSD_TCP is not set
+ 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
+@@ -992,6 +1129,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -1051,7 +1189,9 @@ CONFIG_NLS_UTF8=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -1073,6 +1213,7 @@ CONFIG_CRYPTO_SHA1=m
+ 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
+@@ -1097,9 +1238,12 @@ CONFIG_CRYPTO_CRC32C=m
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=m
+ CONFIG_ZLIB_DEFLATE=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_TEXTSEARCH=y
++CONFIG_TEXTSEARCH_KMP=m
++CONFIG_TEXTSEARCH_BM=m
++CONFIG_TEXTSEARCH_FSM=m
+diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/configs/bigsur_defconfig
+@@ -0,0 +1,881 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:17 2005
++#
++CONFIG_MIPS=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_CLEAN_COMPILE=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_HOTPLUG is not set
++CONFIG_KOBJECT_UEVENT=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++# CONFIG_CPUSETS is not set
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_EMBEDDED=y
++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 is not set
++CONFIG_SHMEM=y
++CONFIG_CC_ALIGN_FUNCTIONS=0
++CONFIG_CC_ALIGN_LABELS=0
++CONFIG_CC_ALIGN_LOOPS=0
++CONFIG_CC_ALIGN_JUMPS=0
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++CONFIG_MODVERSIONS=y
++CONFIG_MODULE_SRCVERSION_ALL=y
++CONFIG_KMOD=y
++CONFIG_STOP_MACHINE=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_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_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_DDB5074 is not set
++# CONFIG_DDB5476 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_SGI_IP22 is not set
++# CONFIG_SGI_IP27 is not set
++# CONFIG_SGI_IP32 is not set
++CONFIG_SIBYTE_BIGSUR=y
++# 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_SIBYTE_BCM1x80=y
++CONFIG_SIBYTE_SB1xxx_SOC=y
++# CONFIG_CPU_SB1_PASS_1 is not set
++# CONFIG_CPU_SB1_PASS_2_1250 is not set
++# CONFIG_CPU_SB1_PASS_2_2 is not set
++# CONFIG_CPU_SB1_PASS_4 is not set
++# CONFIG_CPU_SB1_PASS_2_112x is not set
++# CONFIG_CPU_SB1_PASS_3 is not set
++# CONFIG_SIMULATION is not set
++# CONFIG_CONFIG_SB1_CEX_ALWAYS_FATAL is not set
++# CONFIG_CONFIG_SB1_CERR_STALL is not set
++CONFIG_SIBYTE_CFE=y
++# CONFIG_SIBYTE_CFE_CONSOLE is not set
++# CONFIG_SIBYTE_BUS_WATCHER is not set
++# CONFIG_SIBYTE_SB1250_PROF is not set
++# CONFIG_SIBYTE_TBPROF is not set
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_DMA_COHERENT=y
++CONFIG_CPU_BIG_ENDIAN=y
++# CONFIG_CPU_LITTLE_ENDIAN is not set
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SWAP_IO_SPACE=y
++CONFIG_BOOT_ELF32=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 is not set
++CONFIG_CPU_SB1=y
++CONFIG_SYS_HAS_CPU_SB1=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
++CONFIG_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_SIBYTE_DMA_PAGEOPS is not set
++# CONFIG_MIPS_MT is not set
++CONFIG_CPU_HAS_LLSC=y
++CONFIG_CPU_HAS_LLDSCD=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_SMP=y
++CONFIG_NR_CPUS=4
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_PREEMPT_BKL is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_LEGACY_PROC=y
++CONFIG_PCI_DEBUG=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_BUILD_ELF64=y
++CONFIG_MIPS32_COMPAT=y
++CONFIG_COMPAT=y
++CONFIG_MIPS32_O32=y
++# CONFIG_MIPS32_N32 is not set
++CONFIG_BINFMT_ELF32=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
++# 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=m
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++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=y
++CONFIG_BLK_DEV_IDETAPE=y
++CONFIG_BLK_DEV_IDEFLOPPY=y
++# CONFIG_IDE_TASK_IOCTL is not set
++
++#
++# IDE chipset support/bugfixes
++#
++CONFIG_IDE_GENERIC=y
++# CONFIG_BLK_DEV_IDEPCI is not set
++# CONFIG_BLK_DEV_IDE_SWARM 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
++#
++# 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 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_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_NET_SB1250_MAC=y
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE 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
++
++#
++# 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=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_PCIPS2 is not set
++# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_ROCKETPORT is not set
++# CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
++# CONFIG_MOXA_SMARTIO is not set
++# CONFIG_ISI is not set
++# CONFIG_SYNCLINKMP is not set
++# CONFIG_N_HDLC is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_SX is not set
++# CONFIG_STALDRV is not set
++CONFIG_SIBYTE_SB1250_DUART=y
++CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# 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_RTC 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_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++CONFIG_I2C_ALGO_SIBYTE=y
++
++#
++# 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_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++CONFIG_I2C_SIBYTE=y
++# CONFIG_SCx200_ACB 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=y
++CONFIG_SENSORS_DS1374=y
++CONFIG_SENSORS_EEPROM=y
++CONFIG_SENSORS_PCF8574=y
++CONFIG_SENSORS_PCA9539=y
++CONFIG_SENSORS_PCF8591=y
++CONFIG_SENSORS_RTC8564=y
++CONFIG_SENSORS_MAX6875=y
++CONFIG_I2C_DEBUG_CORE=y
++CONFIG_I2C_DEBUG_ALGO=y
++CONFIG_I2C_DEBUG_BUS=y
++CONFIG_I2C_DEBUG_CHIP=y
++
++#
++# 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 Capabilities Port drivers
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++
++#
++# Graphics support
++#
++# 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 is not set
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN 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 is not set
++# CONFIG_JBD 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_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_PROC_KCORE=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_RELAYFS_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_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=y
++CONFIG_DEBUG_KERNEL=y
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_DETECT_SOFTLOCKUP=y
++# 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_INFO is not set
++# CONFIG_DEBUG_FS is not set
++CONFIG_CROSSCOMPILE=y
++CONFIG_CMDLINE=""
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_KGDB is not set
++# CONFIG_SB1XXX_CORELIS is not set
++# CONFIG_RUNTIME_DEBUG is not set
++
++#
++# Security options
++#
++CONFIG_KEYS=y
++CONFIG_KEYS_DEBUG_PROC_KEYS=y
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=m
++CONFIG_CRYPTO_TGR192=m
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=m
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_TEA=m
++# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_KHAZAD=m
++CONFIG_CRYPTO_ANUBIS=m
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# 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
+diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
+--- a/arch/mips/configs/capcella_defconfig
++++ b/arch/mips/configs/capcella_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:00 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:20 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,57 +59,86 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-CONFIG_MACH_VR41XX=y
+-# CONFIG_NEC_CMBVR4133 is not set
+-# CONFIG_CASIO_E55 is not set
+-# CONFIG_IBM_WORKPAD is not set
+-# CONFIG_TANBAC_TB0226 is not set
+-# CONFIG_TANBAC_TB0229 is not set
+-# CONFIG_VICTOR_MPC30X is not set
+-CONFIG_ZAO_CAPCELLA=y
+-CONFIG_PCI_VR41XX=y
+-CONFIG_VRC4173=y
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++CONFIG_MACH_VR41XX=y
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_NEC_CMBVR4133 is not set
++# CONFIG_CASIO_E55 is not set
++# CONFIG_IBM_WORKPAD is not set
++# CONFIG_TANBAC_TB022X is not set
++# CONFIG_VICTOR_MPC30X is not set
++CONFIG_ZAO_CAPCELLA=y
++CONFIG_PCI_VR41XX=y
++# CONFIG_VRC4173 is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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=y
+@@ -122,12 +154,36 @@ CONFIG_CPU_VR41XX=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_VR41XX=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# 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 is not set
+ # CONFIG_CPU_ADVANCED is not set
+ 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -136,7 +192,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -145,10 +200,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -161,6 +212,81 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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 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 is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -169,7 +295,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -188,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -199,11 +329,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
++# CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+ # IO Schedulers
+@@ -244,6 +371,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -254,6 +382,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -266,79 +395,13 @@ CONFIG_IDE_GENERIC=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -346,10 +409,25 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+-# CONFIG_MII is not set
++CONFIG_MII=y
+ # CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNGEM is not set
+ # CONFIG_NET_VENDOR_3COM is not set
+@@ -359,7 +437,30 @@ CONFIG_NET_ETHERNET=y
+ #
+ # CONFIG_NET_TULIP is not set
+ # CONFIG_HP100 is not set
+-# CONFIG_NET_PCI 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 is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_8139CP is not set
++CONFIG_8139TOO=y
++CONFIG_8139TOO_PIO=y
++# 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
++# CONFIG_LAN_SAA9730 is not set
+ 
+ #
+ # Ethernet (1000 Mbit)
+@@ -371,12 +472,17 @@ CONFIG_NET_ETHERNET=y
+ # 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_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
+ 
+@@ -389,6 +495,8 @@ CONFIG_NET_ETHERNET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -400,6 +508,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -419,29 +529,13 @@ 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_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 I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_I8042=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-CONFIG_SERIO_LIBPS2=m
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -451,6 +545,12 @@ CONFIG_SERIO_RAW=m
+ # 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
+@@ -461,16 +561,16 @@ CONFIG_HW_CONSOLE=y
+ #
+ # Serial drivers
+ #
+-CONFIG_SERIAL_8250=y
+-CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=4
+-# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250 is not set
+ 
+ #
+ # Non-8250 serial port support
+ #
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_VR41XX=y
++CONFIG_SERIAL_VR41XX_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -483,19 +583,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # 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
++# CONFIG_WATCHDOG is not set
+ # CONFIG_RTC is not set
+ # CONFIG_GEN_RTC is not set
+ # CONFIG_DTLK is not set
+@@ -506,9 +594,15 @@ CONFIG_WATCHDOG=y
+ # Ftape, the floppy tape device driver
+ #
+ # CONFIG_DRM is not set
++CONFIG_GPIO_VR41XX=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -519,10 +613,20 @@ CONFIG_WATCHDOG=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -542,7 +646,6 @@ CONFIG_WATCHDOG=y
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -552,13 +655,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -576,21 +675,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_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=y
+ CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -611,12 +718,10 @@ CONFIG_AUTOFS4_FS=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -648,6 +753,7 @@ CONFIG_NFSD=y
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=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
+@@ -656,6 +762,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -676,9 +783,11 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+-CONFIG_CMDLINE=""
++CONFIG_CMDLINE="mem=32M console=ttyVR0,38400"
+ 
+ #
+ # Security options
+@@ -690,7 +799,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -700,7 +833,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
++CONFIG_CRC16=m
++CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
+--- a/arch/mips/configs/cobalt_defconfig
++++ b/arch/mips/configs/cobalt_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:00 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:23 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -50,41 +53,69 @@ CONFIG_CC_ALIGN_JUMPS=0
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_MIPS_COBALT=y
+ # 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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_I8259=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_GT64111=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -92,8 +123,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -109,14 +142,38 @@ CONFIG_CPU_NEVADA=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_NEVADA=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_MIPS_MT is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -125,7 +182,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -134,10 +190,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -150,6 +202,77 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=y
++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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++CONFIG_IEEE80211_CRYPT_CCMP=y
++CONFIG_IEEE80211_CRYPT_TKIP=y
++
++#
+ # Device Drivers
+ #
+ 
+@@ -161,6 +284,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ CONFIG_FW_LOADER=y
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=y
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -177,7 +305,6 @@ CONFIG_FW_LOADER=y
+ #
+ # 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
+@@ -189,7 +316,6 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -234,6 +360,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -244,6 +371,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -256,75 +384,13 @@ CONFIG_IDE_GENERIC=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-# 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_TUNNEL=y
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=y
+-
+-#
+-# 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
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -332,6 +398,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=y
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=y
++CONFIG_DAVICOM_PHY=y
++CONFIG_QSEMI_PHY=y
++CONFIG_LXT_PHY=y
++CONFIG_CICADA_PHY=y
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -357,12 +438,16 @@ CONFIG_NET_ETHERNET=y
+ # 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_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
+ 
+@@ -375,6 +460,8 @@ CONFIG_NET_ETHERNET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=y
+ 
+ #
+ # Wan interfaces
+@@ -386,6 +473,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -415,19 +504,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=y
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -437,6 +513,17 @@ CONFIG_SERIO_RAW=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=y
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -457,6 +544,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -483,6 +571,11 @@ CONFIG_COBALT_LCD=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -493,10 +586,20 @@ CONFIG_COBALT_LCD=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -516,7 +619,6 @@ CONFIG_COBALT_LCD=y
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -526,13 +628,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -550,12 +648,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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 is not set
+ # CONFIG_JBD is not set
+ CONFIG_FS_MBCACHE=y
+@@ -565,10 +668,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -589,12 +694,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -622,7 +725,7 @@ CONFIG_NFS_FS=y
+ # CONFIG_NFS_DIRECTIO is not set
+ # CONFIG_NFSD is not set
+ CONFIG_LOCKD=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -631,6 +734,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -651,7 +755,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -665,7 +771,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=y
++CONFIG_CRYPTO_TGR192=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=y
++CONFIG_CRYPTO_CAST5=y
++CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_TEA=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_KHAZAD=y
++CONFIG_CRYPTO_ANUBIS=y
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -675,7 +805,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=y
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
+--- a/arch/mips/configs/db1000_defconfig
++++ b/arch/mips/configs/db1000_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:01 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:26 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,63 +59,79 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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=y
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-CONFIG_SOC_AU1X00=y
+-CONFIG_SOC_AU1000=y
+-# CONFIG_SOC_AU1100 is not set
+-# CONFIG_SOC_AU1500 is not set
+-# CONFIG_SOC_AU1550 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_DB1000=y
+-# CONFIG_MIPS_DB1100 is not set
+-# CONFIG_MIPS_DB1500 is not set
+-# CONFIG_MIPS_DB1550 is not set
+-# CONFIG_MIPS_BOSPORUS is not set
+-# CONFIG_MIPS_MIRAGE is not set
+-# CONFIG_MIPS_XXS1500 is not set
+-# CONFIG_MIPS_MTX1 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SOC_AU1000=y
++CONFIG_SOC_AU1X00=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -128,15 +147,39 @@ CONFIG_CPU_MIPS32=y
+ # 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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_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 is not set
+ CONFIG_64BIT_PHYS_ADDR=y
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -152,6 +195,8 @@ CONFIG_MMU=y
+ CONFIG_PCCARD=m
+ # CONFIG_PCMCIA_DEBUG is not set
+ CONFIG_PCMCIA=m
++CONFIG_PCMCIA_LOAD_CIS=y
++CONFIG_PCMCIA_IOCTL=y
+ 
+ #
+ # PC-card bridges
+@@ -169,6 +214,100 @@ CONFIG_PCMCIA=m
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ CONFIG_TRAD_SIGNALS=y
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++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 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 is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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 is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ 
+ #
+ # Device Drivers
+@@ -179,12 +318,86 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+ #
+-# CONFIG_MTD is not set
++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
++
++#
++# 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_AMDSTD_RETRY=0
++# 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_ALCHEMY=y
++# 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_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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
+ 
+ #
+ # Parallel port support
+@@ -198,14 +411,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -228,6 +439,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -238,6 +450,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -248,94 +461,28 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# IP: Netfilter Configuration
++# Network device support
+ #
+-# CONFIG_IP_NF_CONNTRACK is not set
+-CONFIG_IP_NF_CONNTRACK_MARK=y
+-# CONFIG_IP_NF_QUEUE is not set
+-# CONFIG_IP_NF_IPTABLES is not set
+-# CONFIG_IP_NF_ARPTABLES is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
+ 
+ #
+-# QoS and/or fair queueing
++# PHY device support
+ #
+-# CONFIG_NET_SCHED is not set
+-# CONFIG_NET_CLS_ROUTE is not set
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
+ 
+ #
+-# Network testing
++# MII PHY device drivers
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -389,6 +536,8 @@ 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
+@@ -418,18 +567,6 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -439,6 +576,16 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -473,14 +620,14 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Watchdog Cards
+ #
+ # CONFIG_WATCHDOG is not set
+-CONFIG_RTC=y
++# CONFIG_RTC is not set
++# CONFIG_GEN_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
+ 
+ #
+ # PCMCIA character devices
+@@ -489,6 +636,10 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -499,10 +650,20 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -522,7 +683,6 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -532,12 +692,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB_ARCH_HAS_HCD is not set
+-# CONFIG_USB_ARCH_HAS_OHCI 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_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -552,7 +709,10 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN Devices
++#
+ 
+ #
+ # File systems
+@@ -561,6 +721,7 @@ CONFIG_EXT2_FS=y
+ CONFIG_EXT2_FS_XATTR=y
+ CONFIG_EXT2_FS_POSIX_ACL=y
+ # 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=y
+@@ -579,10 +740,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -603,13 +766,10 @@ CONFIG_AUTOFS4_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -621,6 +781,8 @@ CONFIG_RAMFS=y
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
+ CONFIG_CRAMFS=m
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+@@ -641,6 +803,7 @@ CONFIG_NFSD=m
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -650,6 +813,7 @@ CONFIG_SMB_FS=m
+ # 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
+@@ -709,7 +873,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -725,26 +891,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-# 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=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
+-# CONFIG_CRYPTO_DES is not set
+-# CONFIG_CRYPTO_BLOWFISH is not set
+-CONFIG_CRYPTO_TWOFISH=y
+-# CONFIG_CRYPTO_SERPENT is not set
++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 is not set
+-# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+ # CONFIG_CRYPTO_TEST is not set
+ 
+@@ -756,9 +923,8 @@ CONFIG_CRYPTO_CRC32C=m
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
+--- a/arch/mips/configs/db1100_defconfig
++++ b/arch/mips/configs/db1100_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:01 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:29 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,63 +59,79 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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=y
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-CONFIG_SOC_AU1X00=y
+-# CONFIG_SOC_AU1000 is not set
+-CONFIG_SOC_AU1100=y
+-# CONFIG_SOC_AU1500 is not set
+-# CONFIG_SOC_AU1550 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_DB1000 is not set
+-CONFIG_MIPS_DB1100=y
+-# CONFIG_MIPS_DB1500 is not set
+-# CONFIG_MIPS_DB1550 is not set
+-# CONFIG_MIPS_BOSPORUS is not set
+-# CONFIG_MIPS_MIRAGE is not set
+-# CONFIG_MIPS_XXS1500 is not set
+-# CONFIG_MIPS_MTX1 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SOC_AU1100=y
++CONFIG_SOC_AU1X00=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -128,15 +147,39 @@ CONFIG_CPU_MIPS32=y
+ # 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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_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_64BIT_PHYS_ADDR is not set
++# CONFIG_MIPS_MT is not set
++CONFIG_64BIT_PHYS_ADDR=y
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -147,15 +190,7 @@ CONFIG_MMU=y
+ #
+ # PCCARD (PCMCIA/CardBus) support
+ #
+-CONFIG_PCCARD=m
+-# CONFIG_PCMCIA_DEBUG is not set
+-CONFIG_PCMCIA=m
+-
+-#
+-# PC-card bridges
+-#
+-# CONFIG_TCIC is not set
+-# CONFIG_PCMCIA_AU1X00 is not set
++# CONFIG_PCCARD is not set
+ 
+ #
+ # PCI Hotplug Support
+@@ -167,6 +202,100 @@ CONFIG_PCMCIA=m
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ CONFIG_TRAD_SIGNALS=y
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++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 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 is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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 is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ 
+ #
+ # Device Drivers
+@@ -180,9 +309,83 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_FW_LOADER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
++
++#
+ # Memory Technology Devices (MTD)
+ #
+-# CONFIG_MTD is not set
++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
++
++#
++# 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_AMDSTD_RETRY=0
++# 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_ALCHEMY=y
++# 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_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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
+ 
+ #
+ # Parallel port support
+@@ -196,14 +399,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -226,6 +427,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -236,6 +438,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -246,101 +449,35 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# IP: Netfilter Configuration
++# Network device support
+ #
+-# CONFIG_IP_NF_CONNTRACK is not set
+-CONFIG_IP_NF_CONNTRACK_MARK=y
+-# CONFIG_IP_NF_QUEUE is not set
+-# CONFIG_IP_NF_IPTABLES is not set
+-# CONFIG_IP_NF_ARPTABLES is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
+ 
+ #
+-# QoS and/or fair queueing
++# PHY device support
+ #
+-# CONFIG_NET_SCHED is not set
+-# CONFIG_NET_CLS_ROUTE is not set
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
+ 
+ #
+-# Network testing
++# MII PHY device drivers
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=m
+-# CONFIG_MIPS_AU1X00_ENET is not set
++CONFIG_MIPS_AU1X00_ENET=y
+ 
+ #
+ # Ethernet (1000 Mbit)
+@@ -360,19 +497,6 @@ CONFIG_MII=m
+ # CONFIG_NET_RADIO is not set
+ 
+ #
+-# 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
+@@ -387,6 +511,8 @@ 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
+@@ -416,18 +542,6 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-CONFIG_SERIO_LIBPS2=m
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -437,6 +551,16 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++CONFIG_SERIO_LIBPS2=m
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -454,7 +578,10 @@ CONFIG_HW_CONSOLE=y
+ #
+ # Non-8250 serial port support
+ #
+-# CONFIG_SERIAL_AU1X00 is not set
++CONFIG_SERIAL_AU1X00=y
++CONFIG_SERIAL_AU1X00_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -468,20 +595,19 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Watchdog Cards
+ #
+ # CONFIG_WATCHDOG is not set
+-CONFIG_RTC=y
++# CONFIG_RTC is not set
++# CONFIG_GEN_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
+ 
+ #
+-# PCMCIA character devices
++# TPM devices
+ #
+-CONFIG_SYNCLINK_CS=m
+-# CONFIG_RAW_DRIVER is not set
+ 
+ #
+ # I2C support
+@@ -494,10 +620,20 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -510,13 +646,43 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # Graphics support
+ #
+-# CONFIG_FB is not set
++CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++CONFIG_FB_SOFT_CURSOR=y
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++CONFIG_FB_AU1100=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_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 is not set
+ 
+ #
+@@ -527,12 +693,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB_ARCH_HAS_HCD is not set
+-# CONFIG_USB_ARCH_HAS_OHCI 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_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -547,7 +710,10 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN Devices
++#
+ 
+ #
+ # File systems
+@@ -556,6 +722,7 @@ CONFIG_EXT2_FS=y
+ CONFIG_EXT2_FS_XATTR=y
+ CONFIG_EXT2_FS_POSIX_ACL=y
+ # 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=y
+@@ -574,10 +741,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -598,13 +767,10 @@ CONFIG_AUTOFS4_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -616,6 +782,8 @@ CONFIG_RAMFS=y
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
+ CONFIG_CRAMFS=m
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+@@ -636,6 +804,7 @@ CONFIG_NFSD=m
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -645,6 +814,7 @@ CONFIG_SMB_FS=m
+ # 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
+@@ -704,7 +874,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -720,26 +892,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-# 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=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
+-# CONFIG_CRYPTO_DES is not set
+-# CONFIG_CRYPTO_BLOWFISH is not set
+-CONFIG_CRYPTO_TWOFISH=y
+-# CONFIG_CRYPTO_SERPENT is not set
++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 is not set
+-# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+ # CONFIG_CRYPTO_TEST is not set
+ 
+@@ -751,9 +924,8 @@ CONFIG_CRYPTO_CRC32C=m
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/configs/db1200_defconfig
+@@ -0,0 +1,987 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:32 2005
++#
++CONFIG_MIPS=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_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_HOTPLUG=y
++CONFIG_KOBJECT_UEVENT=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
++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 is not set
++CONFIG_SHMEM=y
++CONFIG_CC_ALIGN_FUNCTIONS=0
++CONFIG_CC_ALIGN_LABELS=0
++CONFIG_CC_ALIGN_LOOPS=0
++CONFIG_CC_ALIGN_JUMPS=0
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++CONFIG_MODVERSIONS=y
++CONFIG_MODULE_SRCVERSION_ALL=y
++CONFIG_KMOD=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=y
++# CONFIG_MIPS_MIRAGE 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_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_DDB5074 is not set
++# CONFIG_DDB5476 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_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_CALIBRATE_DELAY=y
++CONFIG_DMA_COHERENT=y
++CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SOC_AU1200=y
++CONFIG_SOC_AU1X00=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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_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 is not set
++CONFIG_64BIT_PHYS_ADDR=y
++# CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_MMU=y
++
++#
++# 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_TCIC is not set
++CONFIG_PCMCIA_AU1X00=m
++
++#
++# PCI Hotplug Support
++#
++
++#
++# Executable file formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_TRAD_SIGNALS=y
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++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 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=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 is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_NETFILTER_NETLINK is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
++# 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
++
++#
++# 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_AMDSTD_RETRY=0
++# 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_ALCHEMY=y
++# 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_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
++
++#
++# NAND Flash Device Drivers
++#
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_AU1550 is not set
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Plug and Play support
++#
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_LBD is not set
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++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_BLK_DEV_IDE_AU1XXX=y
++CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA=y
++# CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA is not set
++# CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON is not set
++CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
++# 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=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=y
++# CONFIG_BLK_DEV_SR_VENDOR 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=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_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 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=m
++# CONFIG_MIPS_AU1X00_ENET 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
++
++#
++# 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 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 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_RAW=y
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_AU1X00_GPIO is not set
++# CONFIG_TS_AU1X00_ADS7846 is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_AU1X00=y
++CONFIG_SERIAL_AU1X00_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_RTC is not set
++# CONFIG_GEN_RTC 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_RAW_DRIVER is not set
++
++#
++# TPM devices
++#
++
++#
++# I2C support
++#
++# CONFIG_I2C 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 Capabilities Port drivers
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# 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_SOFT_CURSOR=y
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++CONFIG_FB_AU1200=y
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++
++#
++# Console display driver support
++#
++CONFIG_VGA_CONSOLE=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE 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 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 is not set
++
++#
++# USB Gadget Support
++#
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# 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_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++
++#
++# MMC/SD Card support
++#
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_AU1X=y
++
++#
++# InfiniBand support
++#
++
++#
++# SN Devices
++#
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++# 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=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=y
++# CONFIG_JFS_POSIX_ACL is not set
++# CONFIG_JFS_SECURITY is not set
++# CONFIG_JFS_DEBUG is not set
++# CONFIG_JFS_STATISTICS is not set
++CONFIG_FS_POSIX_ACL=y
++# CONFIG_XFS_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 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_RELAYFS_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_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=m
++# 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_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=y
++# CONFIG_SMB_NLS_DEFAULT is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=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_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_CROSSCOMPILE=y
++CONFIG_CMDLINE="mem=48M"
++
++#
++# Security options
++#
++CONFIG_KEYS=y
++CONFIG_KEYS_DEBUG_PROC_KEYS=y
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Hardware crypto devices
++#
++
++#
++# Library routines
++#
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
+--- a/arch/mips/configs/db1500_defconfig
++++ b/arch/mips/configs/db1500_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:01 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:36 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,63 +59,81 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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=y
++# CONFIG_MIPS_DB1550 is not set
++# CONFIG_MIPS_DB1200 is not set
++# CONFIG_MIPS_MIRAGE 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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-CONFIG_SOC_AU1X00=y
+-# CONFIG_SOC_AU1000 is not set
+-# CONFIG_SOC_AU1100 is not set
+-CONFIG_SOC_AU1500=y
+-# CONFIG_SOC_AU1550 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_DB1000 is not set
+-# CONFIG_MIPS_DB1100 is not set
+-CONFIG_MIPS_DB1500=y
+-# CONFIG_MIPS_DB1550 is not set
+-# CONFIG_MIPS_BOSPORUS is not set
+-# CONFIG_MIPS_MIRAGE is not set
+-# CONFIG_MIPS_XXS1500 is not set
+-# CONFIG_MIPS_MTX1 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+-CONFIG_DMA_COHERENT=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SOC_AU1500=y
++CONFIG_SOC_AU1X00=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -128,15 +149,39 @@ CONFIG_CPU_MIPS32=y
+ # 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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_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 is not set
+ CONFIG_64BIT_PHYS_ADDR=y
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -145,7 +190,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -154,6 +198,8 @@ CONFIG_MMU=y
+ CONFIG_PCCARD=m
+ # CONFIG_PCMCIA_DEBUG is not set
+ CONFIG_PCMCIA=m
++CONFIG_PCMCIA_LOAD_CIS=y
++CONFIG_PCMCIA_IOCTL=y
+ CONFIG_CARDBUS=y
+ 
+ #
+@@ -176,6 +222,100 @@ CONFIG_PCMCIA_AU1X00=m
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ CONFIG_TRAD_SIGNALS=y
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++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 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 is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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 is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ 
+ #
+ # Device Drivers
+@@ -186,15 +326,20 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+ #
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+-CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+ # CONFIG_MTD_CMDLINE_PARTS is not set
+ 
+@@ -232,16 +377,14 @@ 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_XIP is not set
+ 
+ #
+ # Mapping drivers for chip access
+ #
+ # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+ # CONFIG_MTD_PHYSMAP is not set
+-CONFIG_MTD_DB1X00=y
+-CONFIG_MTD_DB1X00_BOOT=y
+-CONFIG_MTD_DB1X00_USER=y
++CONFIG_MTD_ALCHEMY=y
++# CONFIG_MTD_PLATRAM is not set
+ 
+ #
+ # Self-contained MTD device drivers
+@@ -277,7 +420,6 @@ CONFIG_MTD_DB1X00_USER=y
+ #
+ # 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
+@@ -290,7 +432,6 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_UB is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -336,6 +477,7 @@ CONFIG_BLK_DEV_IDECS=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -346,6 +488,7 @@ CONFIG_BLK_DEV_IDECS=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -358,94 +501,13 @@ CONFIG_BLK_DEV_IDECS=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
++# Network device support
+ #
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# IP: Netfilter Configuration
+-#
+-# CONFIG_IP_NF_CONNTRACK is not set
+-CONFIG_IP_NF_CONNTRACK_MARK=y
+-# CONFIG_IP_NF_QUEUE is not set
+-# CONFIG_IP_NF_IPTABLES is not set
+-# CONFIG_IP_NF_ARPTABLES is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -453,6 +515,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -479,12 +556,16 @@ CONFIG_MIPS_AU1X00_ENET=y
+ # 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_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
+ 
+@@ -497,6 +578,8 @@ CONFIG_MIPS_AU1X00_ENET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # PCMCIA network device support
+@@ -520,6 +603,8 @@ 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
+@@ -549,19 +634,6 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -571,6 +643,17 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ # CONFIG_VT is not set
+@@ -590,6 +673,7 @@ CONFIG_SERIAL_AU1X00=y
+ CONFIG_SERIAL_AU1X00_CONSOLE=y
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -603,7 +687,8 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Watchdog Cards
+ #
+ # CONFIG_WATCHDOG is not set
+-CONFIG_RTC=y
++# 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
+@@ -620,6 +705,11 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -630,10 +720,20 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -647,7 +747,6 @@ CONFIG_SYNCLINK_CS=m
+ # Graphics support
+ #
+ # CONFIG_FB is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -680,7 +779,6 @@ CONFIG_SOUND_AU1000=y
+ # CONFIG_SOUND_MSNDCLAS is not set
+ # CONFIG_SOUND_MSNDPIN is not set
+ # CONFIG_SOUND_VIA82CXXX is not set
+-# CONFIG_SOUND_OSS is not set
+ # CONFIG_SOUND_ALI5455 is not set
+ # CONFIG_SOUND_FORTE is not set
+ # CONFIG_SOUND_RME96XX is not set
+@@ -689,6 +787,8 @@ CONFIG_SOUND_AU1000=y
+ #
+ # USB support
+ #
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
+ CONFIG_USB=y
+ # CONFIG_USB_DEBUG is not set
+ 
+@@ -699,23 +799,23 @@ CONFIG_USB=y
+ # CONFIG_USB_BANDWIDTH is not set
+ # CONFIG_USB_DYNAMIC_MINORS is not set
+ # CONFIG_USB_OTG is not set
+-CONFIG_USB_ARCH_HAS_HCD=y
+-CONFIG_USB_ARCH_HAS_OHCI=y
+ 
+ #
+ # USB Host Controller Drivers
+ #
+ # CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
+ CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+ # CONFIG_USB_UHCI_HCD is not set
+ # CONFIG_USB_SL811_HCD is not set
+ 
+ #
+ # USB Device Class drivers
+ #
+-# CONFIG_USB_AUDIO is not set
++# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+ # CONFIG_USB_BLUETOOTH_TTY is not set
+-# CONFIG_USB_MIDI is not set
+ # CONFIG_USB_ACM is not set
+ # CONFIG_USB_PRINTER is not set
+ 
+@@ -733,12 +833,17 @@ CONFIG_USB_HIDINPUT=y
+ # 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_MTOUCH is not set
++# CONFIG_USB_ITMTOUCH is not set
+ # CONFIG_USB_EGALAX is not set
++CONFIG_USB_YEALINK=m
+ # CONFIG_USB_XPAD is not set
+ # CONFIG_USB_ATI_REMOTE is not set
++# CONFIG_USB_KEYSPAN_REMOTE is not set
++# CONFIG_USB_APPLETOUCH is not set
+ 
+ #
+ # USB Imaging devices
+@@ -762,6 +867,7 @@ CONFIG_USB_HIDINPUT=y
+ # 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
+@@ -786,9 +892,10 @@ CONFIG_USB_HIDINPUT=y
+ # CONFIG_USB_PHIDGETKIT is not set
+ # CONFIG_USB_PHIDGETSERVO is not set
+ # CONFIG_USB_IDMOUSE is not set
++CONFIG_USB_LD=m
+ 
+ #
+-# USB ATM/DSL drivers
++# USB DSL modem support
+ #
+ 
+ #
+@@ -807,12 +914,17 @@ CONFIG_USB_HIDINPUT=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+ CONFIG_EXT2_FS_XATTR=y
+ CONFIG_EXT2_FS_POSIX_ACL=y
+ # 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=y
+@@ -831,10 +943,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -855,13 +969,10 @@ CONFIG_AUTOFS4_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -895,6 +1006,7 @@ CONFIG_NFSD=m
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -904,6 +1016,7 @@ CONFIG_SMB_FS=m
+ # 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
+@@ -963,7 +1076,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -979,26 +1094,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-# 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=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
+-# CONFIG_CRYPTO_DES is not set
+-# CONFIG_CRYPTO_BLOWFISH is not set
+-CONFIG_CRYPTO_TWOFISH=y
+-# CONFIG_CRYPTO_SERPENT is not set
++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 is not set
+-# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+ # CONFIG_CRYPTO_TEST is not set
+ 
+@@ -1010,9 +1126,8 @@ CONFIG_CRYPTO_CRC32C=m
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
+--- a/arch/mips/configs/db1550_defconfig
++++ b/arch/mips/configs/db1550_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:02 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:39 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,63 +59,80 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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=y
++# CONFIG_MIPS_DB1200 is not set
++# CONFIG_MIPS_MIRAGE 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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-CONFIG_SOC_AU1X00=y
+-# CONFIG_SOC_AU1000 is not set
+-# CONFIG_SOC_AU1100 is not set
+-# CONFIG_SOC_AU1500 is not set
+-CONFIG_SOC_AU1550=y
+-# 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_DB1000 is not set
+-# CONFIG_MIPS_DB1100 is not set
+-# CONFIG_MIPS_DB1500 is not set
+-CONFIG_MIPS_DB1550=y
+-# CONFIG_MIPS_BOSPORUS is not set
+-# CONFIG_MIPS_MIRAGE is not set
+-# CONFIG_MIPS_XXS1500 is not set
+-# CONFIG_MIPS_MTX1 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+-CONFIG_DMA_COHERENT=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SOC_AU1550=y
++CONFIG_SOC_AU1X00=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -128,15 +148,39 @@ CONFIG_CPU_MIPS32=y
+ # 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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_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 is not set
+ CONFIG_64BIT_PHYS_ADDR=y
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -145,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -154,6 +197,8 @@ CONFIG_MMU=y
+ CONFIG_PCCARD=m
+ # CONFIG_PCMCIA_DEBUG is not set
+ CONFIG_PCMCIA=m
++CONFIG_PCMCIA_LOAD_CIS=y
++CONFIG_PCMCIA_IOCTL=y
+ CONFIG_CARDBUS=y
+ 
+ #
+@@ -176,6 +221,100 @@ CONFIG_PCMCIA_AU1X00=m
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ CONFIG_TRAD_SIGNALS=y
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++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 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 is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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 is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ 
+ #
+ # Device Drivers
+@@ -186,15 +325,20 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+ #
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+-CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+ # CONFIG_MTD_CMDLINE_PARTS is not set
+ 
+@@ -238,9 +382,8 @@ CONFIG_MTD_CFI_UTIL=y
+ #
+ # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+ # CONFIG_MTD_PHYSMAP is not set
+-CONFIG_MTD_DB1550=y
+-CONFIG_MTD_DB1550_BOOT=y
+-CONFIG_MTD_DB1550_USER=y
++CONFIG_MTD_ALCHEMY=y
++# CONFIG_MTD_PLATRAM is not set
+ 
+ #
+ # Self-contained MTD device drivers
+@@ -281,7 +424,6 @@ CONFIG_MTD_NAND_AU1550=m
+ #
+ # 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
+@@ -293,7 +435,6 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -350,6 +491,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
+ # 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
+@@ -367,6 +509,7 @@ CONFIG_BLK_DEV_IDEDMA=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -377,6 +520,7 @@ CONFIG_BLK_DEV_IDEDMA=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -389,94 +533,13 @@ CONFIG_BLK_DEV_IDEDMA=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
++# Network device support
+ #
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# IP: Netfilter Configuration
+-#
+-# CONFIG_IP_NF_CONNTRACK is not set
+-CONFIG_IP_NF_CONNTRACK_MARK=y
+-# CONFIG_IP_NF_QUEUE is not set
+-# CONFIG_IP_NF_IPTABLES is not set
+-# CONFIG_IP_NF_ARPTABLES is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -484,6 +547,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -510,12 +588,16 @@ CONFIG_MIPS_AU1X00_ENET=y
+ # 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_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
+ 
+@@ -528,6 +610,8 @@ CONFIG_MIPS_AU1X00_ENET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # PCMCIA network device support
+@@ -559,6 +643,8 @@ 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
+@@ -588,19 +674,6 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -610,6 +683,17 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ # CONFIG_VT is not set
+@@ -629,6 +713,7 @@ CONFIG_SERIAL_AU1X00=y
+ CONFIG_SERIAL_AU1X00_CONSOLE=y
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -660,6 +745,11 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -670,10 +760,20 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -687,7 +787,6 @@ CONFIG_SYNCLINK_CS=m
+ # Graphics support
+ #
+ # CONFIG_FB is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -697,13 +796,9 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -721,12 +816,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+ CONFIG_EXT2_FS_XATTR=y
+ CONFIG_EXT2_FS_POSIX_ACL=y
+ # 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=y
+@@ -745,10 +845,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -769,13 +871,10 @@ CONFIG_AUTOFS4_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -809,6 +908,7 @@ CONFIG_NFSD=m
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -818,6 +918,7 @@ CONFIG_SMB_FS=m
+ # 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
+@@ -877,7 +978,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -893,26 +996,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-# 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=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
+-# CONFIG_CRYPTO_DES is not set
+-# CONFIG_CRYPTO_BLOWFISH is not set
+-CONFIG_CRYPTO_TWOFISH=y
+-# CONFIG_CRYPTO_SERPENT is not set
++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 is not set
+-# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+ # CONFIG_CRYPTO_TEST is not set
+ 
+@@ -924,9 +1028,8 @@ CONFIG_CRYPTO_CRC32C=m
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig
+--- a/arch/mips/configs/ddb5476_defconfig
++++ b/arch/mips/configs/ddb5476_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:02 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:42 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -50,41 +53,69 @@ CONFIG_CC_ALIGN_JUMPS=0
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ CONFIG_DDB5476=y
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_I8259=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_DDB5XXX_COMMON=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -93,8 +124,10 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -110,14 +143,38 @@ CONFIG_CPU_R5432=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R5432=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_MIPS_MT is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -126,7 +183,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_ISA=y
+ CONFIG_MMU=y
+ 
+@@ -136,11 +192,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-CONFIG_PCMCIA_PROBE=y
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -153,6 +204,80 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=y
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++CONFIG_IEEE80211_CRYPT_CCMP=y
++CONFIG_IEEE80211_CRYPT_TKIP=y
++
++#
+ # Device Drivers
+ #
+ 
+@@ -161,7 +286,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=y
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -181,8 +311,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD is not set
+-# 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
+@@ -193,7 +321,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -239,6 +366,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -254,6 +382,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -266,78 +395,13 @@ CONFIG_IDE_GENERIC=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=y
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=y
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -345,6 +409,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=y
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=y
++CONFIG_DAVICOM_PHY=y
++CONFIG_QSEMI_PHY=y
++CONFIG_LXT_PHY=y
++CONFIG_CICADA_PHY=y
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -352,7 +431,6 @@ CONFIG_NET_ETHERNET=y
+ # CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNGEM is not set
+ # CONFIG_NET_VENDOR_3COM is not set
+-# CONFIG_LANCE is not set
+ # CONFIG_NET_VENDOR_SMC is not set
+ # CONFIG_NET_VENDOR_RACAL is not set
+ 
+@@ -377,12 +455,16 @@ CONFIG_NET_ETHERNET=y
+ # 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_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
+ 
+@@ -395,6 +477,8 @@ CONFIG_NET_ETHERNET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=y
+ 
+ #
+ # Wan interfaces
+@@ -406,6 +490,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -435,19 +521,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=y
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -457,6 +530,17 @@ CONFIG_SERIO_RAW=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=y
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -477,6 +561,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -503,6 +588,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -513,10 +603,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -530,6 +630,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Graphics support
+ #
+ 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_SOFT_CURSOR is not set
++# CONFIG_FB_MACMODES is not set
+ # CONFIG_FB_MODE_HELPERS is not set
+ # CONFIG_FB_TILEBLITTING is not set
+ # CONFIG_FB_CIRRUS is not set
+@@ -537,6 +642,7 @@ CONFIG_FB=y
+ # CONFIG_FB_CYBER2000 is not set
+ # CONFIG_FB_ASILIANT is not set
+ # CONFIG_FB_IMSTT is not set
++# CONFIG_FB_NVIDIA is not set
+ # CONFIG_FB_RIVA is not set
+ # CONFIG_FB_MATROX is not set
+ # CONFIG_FB_RADEON_OLD is not set
+@@ -549,8 +655,11 @@ CONFIG_FB=y
+ # 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_CYBLA is not set
+ # CONFIG_FB_TRIDENT is not set
+ # CONFIG_FB_E1356 is not set
++# CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+ 
+ #
+@@ -575,13 +684,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -599,21 +704,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_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=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -634,12 +747,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -668,7 +779,7 @@ CONFIG_NFS_FS=y
+ # CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -677,6 +788,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -697,7 +809,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE="ip=any"
+ 
+@@ -711,7 +825,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=y
++CONFIG_CRYPTO_TGR192=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=y
++CONFIG_CRYPTO_CAST5=y
++CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_TEA=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_KHAZAD=y
++CONFIG_CRYPTO_ANUBIS=y
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -721,7 +859,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=y
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
+--- a/arch/mips/configs/ddb5477_defconfig
++++ b/arch/mips/configs/ddb5477_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:02 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:45 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -50,42 +53,70 @@ CONFIG_CC_ALIGN_JUMPS=0
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ CONFIG_DDB5477=y
+-CONFIG_DDB5477_BUS_FREQUENCY=0
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_DDB5477_BUS_FREQUENCY=0
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_I8259=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_DDB5XXX_COMMON=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -93,8 +124,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -110,14 +143,38 @@ CONFIG_CPU_R5432=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R5432=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_MIPS_MT is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -126,7 +183,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -135,10 +191,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -151,6 +203,80 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=y
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++CONFIG_IEEE80211_CRYPT_CCMP=y
++CONFIG_IEEE80211_CRYPT_TKIP=y
++
++#
+ # Device Drivers
+ #
+ 
+@@ -159,7 +285,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=y
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -178,7 +309,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -189,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -212,6 +341,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -222,6 +352,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -234,78 +365,13 @@ CONFIG_ATA_OVER_ETH=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=y
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=y
+-
+-#
+-# 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
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -313,6 +379,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=y
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=y
++CONFIG_DAVICOM_PHY=y
++CONFIG_QSEMI_PHY=y
++CONFIG_LXT_PHY=y
++CONFIG_CICADA_PHY=y
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -357,13 +438,17 @@ CONFIG_PCNET32=y
+ # 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_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
+ 
+@@ -376,6 +461,8 @@ CONFIG_PCNET32=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=y
+ 
+ #
+ # Wan interfaces
+@@ -387,6 +474,8 @@ CONFIG_PCNET32=y
+ # 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
+@@ -416,19 +505,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=y
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -438,6 +514,17 @@ CONFIG_SERIO_RAW=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=y
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -458,6 +545,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -484,6 +572,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -494,10 +587,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -517,7 +620,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -527,13 +629,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -551,21 +649,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_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=y
+ CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -586,12 +692,10 @@ CONFIG_AUTOFS4_FS=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -623,6 +727,7 @@ CONFIG_NFSD=y
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=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
+@@ -631,6 +736,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -651,7 +757,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE="ip=any"
+ 
+@@ -665,7 +773,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=y
++CONFIG_CRYPTO_TGR192=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=y
++CONFIG_CRYPTO_CAST5=y
++CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_TEA=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_KHAZAD=y
++CONFIG_CRYPTO_ANUBIS=y
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -675,7 +807,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
+ CONFIG_CRC32=y
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
+--- a/arch/mips/configs/decstation_defconfig
++++ b/arch/mips/configs/decstation_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:03 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:48 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,30 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_EMBEDDED=y
+ 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 is not set
+@@ -41,6 +44,7 @@ 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
+@@ -49,48 +53,76 @@ CONFIG_MODULES=y
+ CONFIG_MODULE_UNLOAD=y
+ # CONFIG_MODULE_FORCE_UNLOAD is not set
+ CONFIG_OBSOLETE_MODPARM=y
+-CONFIG_MODVERSIONS=y
++# CONFIG_MODVERSIONS is not set
+ CONFIG_MODULE_SRCVERSION_ALL=y
+ CONFIG_KMOD=y
+ 
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_MIPS_COBALT is not set
+ CONFIG_MACH_DECSTATION=y
+ # CONFIG_MIPS_EV64120 is not set
+ # CONFIG_MIPS_EV96100 is not set
+ # CONFIG_MIPS_IVR is not set
+-# CONFIG_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_EARLY_PRINTK=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=4
+@@ -98,8 +130,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=4
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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=y
+ # CONFIG_CPU_TX39XX is not set
+ # CONFIG_CPU_VR41XX is not set
+@@ -115,12 +149,37 @@ CONFIG_CPU_R3000=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R3000=y
++CONFIG_SYS_HAS_CPU_R4X00=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_MIPS_MT is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_WB=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -135,10 +194,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -150,6 +205,80 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
++# 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -159,6 +288,12 @@ CONFIG_TRAD_SIGNALS=y
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -177,17 +312,14 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD is not set
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+-# CONFIG_BLK_DEV_LOOP 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
++# CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+ # IO Schedulers
+@@ -196,7 +328,7 @@ CONFIG_IOSCHED_NOOP=y
+ CONFIG_IOSCHED_AS=y
+ CONFIG_IOSCHED_DEADLINE=y
+ CONFIG_IOSCHED_CFQ=y
+-CONFIG_ATA_OVER_ETH=m
++# CONFIG_ATA_OVER_ETH is not set
+ 
+ #
+ # ATA/ATAPI/MFM/RLL support
+@@ -206,6 +338,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -213,10 +346,12 @@ 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_ST=m
+ # CONFIG_CHR_DEV_OSST is not set
+-# CONFIG_BLK_DEV_SR is not set
+-# CONFIG_CHR_DEV_SG is not set
++CONFIG_BLK_DEV_SR=m
++# CONFIG_BLK_DEV_SR_VENDOR 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
+@@ -228,9 +363,10 @@ CONFIG_SCSI_CONSTANTS=y
+ #
+ # SCSI Transport Attributes
+ #
+-# CONFIG_SCSI_SPI_ATTRS is not set
++CONFIG_SCSI_SPI_ATTRS=m
+ # CONFIG_SCSI_FC_ATTRS is not set
+ # CONFIG_SCSI_ISCSI_ATTRS is not set
++CONFIG_SCSI_SAS_ATTRS=m
+ 
+ #
+ # SCSI low-level drivers
+@@ -248,6 +384,7 @@ CONFIG_SCSI_DECNCR=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -258,78 +395,28 @@ CONFIG_SCSI_DECNCR=y
+ #
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
++# Network device support
+ #
+-# 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
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
+ 
+ #
+-# QoS and/or fair queueing
++# PHY device support
+ #
+-# CONFIG_NET_SCHED is not set
+-# CONFIG_NET_CLS_ROUTE is not set
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
+ 
+ #
+-# Network testing
++# MII PHY device drivers
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -363,6 +450,8 @@ CONFIG_DECLANCE=y
+ # 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
+@@ -377,48 +466,22 @@ CONFIG_DECLANCE=y
+ #
+ # Input device support
+ #
+-CONFIG_INPUT=y
++# CONFIG_INPUT is not set
+ 
+ #
+-# 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 I/O drivers
++# Hardware I/O ports
+ #
++# CONFIG_SERIO is not set
+ # CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+-# 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
+ 
+ #
+ # Character devices
+ #
+-CONFIG_VT=y
+-CONFIG_VT_CONSOLE=y
+-CONFIG_HW_CONSOLE=y
++# CONFIG_VT is not set
+ # CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_DEC=y
++CONFIG_SERIAL_DEC_CONSOLE=y
++CONFIG_ZS=y
+ 
+ #
+ # Serial drivers
+@@ -445,18 +508,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Watchdog Cards
+ #
+ # CONFIG_WATCHDOG is not set
+-# CONFIG_RTC is not set
+-# CONFIG_GEN_RTC is not set
++CONFIG_RTC=y
+ # 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
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -467,10 +532,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -483,13 +558,29 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
+-# CONFIG_FB is not set
+-
+-#
+-# Console display driver support
+-#
+-# CONFIG_VGA_CONSOLE is not set
+-CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++CONFIG_FB_SOFT_CURSOR=y
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++# CONFIG_FB_PMAG_AA is not set
++CONFIG_FB_PMAG_BA=y
++CONFIG_FB_PMAGB_B=y
++# CONFIG_FB_MAXINE is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++
++#
++# Logo configuration
++#
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++# CONFIG_LOGO_LINUX_CLUT224 is not set
++CONFIG_LOGO_DEC_CLUT224=y
+ # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+@@ -504,10 +595,6 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -520,7 +607,10 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN Devices
++#
+ 
+ #
+ # File systems
+@@ -529,6 +619,7 @@ 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 is not set
+ # CONFIG_JBD is not set
+ CONFIG_FS_MBCACHE=y
+@@ -538,10 +629,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -562,12 +655,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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_TMPFS=y
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -584,19 +675,31 @@ CONFIG_RAMFS=y
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
+ # CONFIG_SYSV_FS is not set
+-# CONFIG_UFS_FS is not set
++CONFIG_UFS_FS=y
++CONFIG_UFS_FS_WRITE=y
+ 
+ #
+ # Network File Systems
+ #
+-# CONFIG_NFS_FS is not set
++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_EXPORTFS 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_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
+@@ -631,9 +734,24 @@ CONFIG_ULTRIX_PARTITION=y
+ #
+ # Kernel hacking
+ #
+-# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_PRINTK_TIME is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_DETECT_SOFTLOCKUP=y
++# 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_INFO is not set
++# CONFIG_DEBUG_FS is not set
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_KGDB is not set
++# CONFIG_RUNTIME_DEBUG is not set
++# CONFIG_MIPS_UNCACHED is not set
+ 
+ #
+ # Security options
+@@ -645,7 +763,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -655,7 +797,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
+--- a/arch/mips/configs/e55_defconfig
++++ b/arch/mips/configs/e55_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:03 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:51 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,56 +59,84 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-CONFIG_MACH_VR41XX=y
+-# CONFIG_NEC_CMBVR4133 is not set
+-CONFIG_CASIO_E55=y
+-# CONFIG_IBM_WORKPAD is not set
+-# CONFIG_TANBAC_TB0226 is not set
+-# CONFIG_TANBAC_TB0229 is not set
+-# CONFIG_VICTOR_MPC30X is not set
+-# CONFIG_ZAO_CAPCELLA is not set
+-# CONFIG_VRC4171 is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++CONFIG_MACH_VR41XX=y
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_NEC_CMBVR4133 is not set
++CONFIG_CASIO_E55=y
++# CONFIG_IBM_WORKPAD is not set
++# CONFIG_TANBAC_TB022X is not set
++# CONFIG_VICTOR_MPC30X is not set
++# CONFIG_ZAO_CAPCELLA is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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=y
+@@ -121,12 +152,36 @@ CONFIG_CPU_VR41XX=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_VR41XX=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# 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 is not set
+ # CONFIG_CPU_ADVANCED is not set
+ 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -141,11 +196,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-CONFIG_PCMCIA_PROBE=y
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -157,6 +207,78 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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 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=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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -168,6 +290,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_FW_LOADER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -185,18 +312,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD is not set
+-# CONFIG_BLK_DEV_XD 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
++# CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+ # IO Schedulers
+@@ -205,7 +327,7 @@ CONFIG_IOSCHED_NOOP=y
+ CONFIG_IOSCHED_AS=y
+ CONFIG_IOSCHED_DEADLINE=y
+ CONFIG_IOSCHED_CFQ=y
+-CONFIG_ATA_OVER_ETH=m
++# CONFIG_ATA_OVER_ETH is not set
+ 
+ #
+ # ATA/ATAPI/MFM/RLL support
+@@ -237,6 +359,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -252,6 +375,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -262,76 +386,13 @@ CONFIG_IDE_GENERIC=y
+ #
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-CONFIG_IP_MULTICAST=y
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-# 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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -339,12 +400,26 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+ # CONFIG_MII 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
+ # CONFIG_AT1700 is not set
+@@ -380,6 +455,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -401,26 +478,14 @@ CONFIG_INPUT=y
+ #
+ CONFIG_INPUT_MOUSEDEV=y
+ CONFIG_INPUT_MOUSEDEV_PSAUX=y
+-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+ # 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 I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_I8042=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -430,6 +495,16 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -440,16 +515,15 @@ CONFIG_HW_CONSOLE=y
+ #
+ # Serial drivers
+ #
+-CONFIG_SERIAL_8250=y
+-CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=4
+-# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250 is not set
+ 
+ #
+ # Non-8250 serial port support
+ #
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_VR41XX=y
++CONFIG_SERIAL_VR41XX_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -484,10 +558,14 @@ CONFIG_WATCHDOG=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_DRM is not set
++CONFIG_GPIO_VR41XX=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -498,10 +576,20 @@ CONFIG_WATCHDOG=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -522,7 +610,6 @@ CONFIG_WATCHDOG=y
+ # CONFIG_VGA_CONSOLE is not set
+ # CONFIG_MDA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -536,10 +623,6 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -552,24 +635,31 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN 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_JBD 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_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=y
+ CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -590,12 +680,10 @@ CONFIG_AUTOFS4_FS=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -617,16 +705,17 @@ CONFIG_RAMFS=y
+ #
+ # Network File Systems
+ #
+-CONFIG_NFS_FS=y
++CONFIG_NFS_FS=m
+ # CONFIG_NFS_V3 is not set
+ # CONFIG_NFS_V4 is not set
+ # CONFIG_NFS_DIRECTIO is not set
+-CONFIG_NFSD=y
++CONFIG_NFSD=m
+ # CONFIG_NFSD_V3 is not set
+ # CONFIG_NFSD_TCP is not set
+-CONFIG_LOCKD=y
+-CONFIG_EXPORTFS=y
+-CONFIG_SUNRPC=y
++CONFIG_LOCKD=m
++CONFIG_EXPORTFS=m
++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
+@@ -634,6 +723,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -654,9 +744,11 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+-CONFIG_CMDLINE=""
++CONFIG_CMDLINE="console=ttyVR0,19200 mem=8M"
+ 
+ #
+ # Security options
+@@ -668,7 +760,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -678,7 +794,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
++CONFIG_CRC16=m
++CONFIG_CRC32=m
+ CONFIG_LIBCRC32C=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
+--- a/arch/mips/configs/ev64120_defconfig
++++ b/arch/mips/configs/ev64120_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:03 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:54 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,41 +59,69 @@ CONFIG_MODULE_SRCVERSION_ALL=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_MIPS_COBALT is not set
+ # CONFIG_MACH_DECSTATION is not set
+ CONFIG_MIPS_EV64120=y
+-# CONFIG_EVB_PCI1 is not set
+ # CONFIG_MIPS_EV96100 is not set
+ # CONFIG_MIPS_IVR is not set
+-# CONFIG_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_EVB_PCI1 is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=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_MIPS_GT64120=y
+ # CONFIG_SYSCLK_75 is not set
+ # CONFIG_SYSCLK_83 is not set
+@@ -100,8 +131,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -117,15 +150,39 @@ CONFIG_CPU_R5000=y
+ # 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_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_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -134,7 +191,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -143,10 +199,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -159,6 +211,79 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++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 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_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=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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -167,7 +292,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -186,7 +316,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -197,7 +326,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -220,6 +348,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -230,6 +359,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -242,77 +372,13 @@ CONFIG_ATA_OVER_ETH=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-# CONFIG_PACKET is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# 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_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=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -320,6 +386,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -345,12 +426,16 @@ CONFIG_NET_ETHERNET=y
+ # 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_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
+ 
+@@ -363,6 +448,8 @@ CONFIG_NET_ETHERNET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -381,6 +468,8 @@ CONFIG_PPP_ASYNC=y
+ # 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
+@@ -410,19 +499,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -432,6 +508,17 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -452,6 +539,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -478,6 +566,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -488,10 +581,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -511,7 +614,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -521,13 +623,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -545,21 +643,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_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=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -580,12 +686,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -614,7 +718,7 @@ CONFIG_NFS_FS=y
+ # CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -623,6 +727,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -643,7 +748,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
+ 
+@@ -657,7 +764,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -667,7 +798,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=y
+-# CONFIG_CRC32 is not set
++CONFIG_CRC16=m
++CONFIG_CRC32=m
+ CONFIG_LIBCRC32C=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/ev96100_defconfig b/arch/mips/configs/ev96100_defconfig
+--- a/arch/mips/configs/ev96100_defconfig
++++ b/arch/mips/configs/ev96100_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:03 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:57 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,40 +59,68 @@ CONFIG_MODULE_SRCVERSION_ALL=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_MIPS_COBALT is not set
+ # CONFIG_MACH_DECSTATION is not set
+ # CONFIG_MIPS_EV64120 is not set
+ CONFIG_MIPS_EV96100=y
+ # CONFIG_MIPS_IVR is not set
+-# CONFIG_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=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_IRQ_CPU=y
+ CONFIG_MIPS_GT64120=y
+ CONFIG_SWAP_IO_SPACE=y
+@@ -99,8 +130,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -116,6 +149,18 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ CONFIG_CPU_RM7000=y
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R5000=y
++CONFIG_SYS_HAS_CPU_RM7000=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# Kernel type
++#
++CONFIG_32BIT=y
++# CONFIG_64BIT is not set
+ CONFIG_PAGE_SIZE_4KB=y
+ # CONFIG_PAGE_SIZE_8KB is not set
+ # CONFIG_PAGE_SIZE_16KB is not set
+@@ -123,11 +168,25 @@ CONFIG_PAGE_SIZE_4KB=y
+ CONFIG_BOARD_SCACHE=y
+ CONFIG_RM7000_CPU_SCACHE=y
+ CONFIG_CPU_HAS_PREFETCH=y
++# CONFIG_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -143,10 +202,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -158,6 +213,79 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -169,6 +297,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_FW_LOADER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -185,13 +318,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -214,6 +345,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -224,6 +356,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -234,77 +367,28 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
++# Network device support
+ #
+-# CONFIG_PACKET is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
+ 
+ #
+-# QoS and/or fair queueing
++# PHY device support
+ #
+-# CONFIG_NET_SCHED is not set
+-# CONFIG_NET_CLS_ROUTE is not set
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
+ 
+ #
+-# Network testing
++# MII PHY device drivers
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -338,6 +422,8 @@ CONFIG_MIPS_GT96100ETH=y
+ # 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
+@@ -367,18 +453,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -388,6 +462,16 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -429,10 +513,13 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -443,10 +530,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -466,7 +563,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -480,10 +576,6 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -496,24 +588,31 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN 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_JBD 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_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=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -534,12 +633,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -568,7 +665,7 @@ CONFIG_NFS_FS=y
+ # CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -577,6 +674,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -597,7 +695,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -611,7 +711,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -621,7 +745,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
++CONFIG_CRC16=m
++CONFIG_CRC32=m
+ CONFIG_LIBCRC32C=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
+--- a/arch/mips/configs/ip22_defconfig
++++ b/arch/mips/configs/ip22_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:04 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:01 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,25 +11,30 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -42,6 +44,7 @@ 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
+@@ -57,41 +60,69 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ CONFIG_SGI_IP22=y
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_ARC=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_IRQ_CPU=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_ARC32=y
+@@ -103,8 +134,10 @@ CONFIG_ARC_PROMLIB=y
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -120,22 +153,48 @@ CONFIG_CPU_R5000=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R4X00=y
++CONFIG_SYS_HAS_CPU_R5000=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_BOARD_SCACHE=y
+ CONFIG_IP22_CPU_SCACHE=y
++# CONFIG_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE is not set
++CONFIG_PREEMPT_VOLUNTARY=y
+ # CONFIG_PREEMPT is not set
+ 
+ #
+ # Bus options (PCI, PCMCIA, EISA, ISA, TC)
+ #
++CONFIG_HW_HAS_EISA=y
+ # CONFIG_EISA is not set
+ CONFIG_MMU=y
+ 
+@@ -145,10 +204,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -160,115 +215,7 @@ CONFIG_BINFMT_MISC=m
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
+-# 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 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_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_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+-# CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE 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=m
+-
+-#
+-# ATA/ATAPI/MFM/RLL support
+-#
+-# CONFIG_IDE 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=y
+-# CONFIG_CHR_DEV_OSST is not set
+-CONFIG_BLK_DEV_SR=y
+-# CONFIG_BLK_DEV_SR_VENDOR is not set
+-# CONFIG_CHR_DEV_SG 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=m
+-# CONFIG_SCSI_FC_ATTRS is not set
+-# CONFIG_SCSI_ISCSI_ATTRS is not set
+-
+-#
+-# SCSI low-level drivers
+-#
+-CONFIG_SGIWD93_SCSI=y
+-# 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
+-#
+-
+-#
+-# IEEE 1394 (FireWire) support
+-#
+-
+-#
+-# I2O device support
+-#
+-
+-#
+-# Networking support
++# Networking
+ #
+ CONFIG_NET=y
+ 
+@@ -277,12 +224,14 @@ CONFIG_NET=y
+ #
+ CONFIG_PACKET=y
+ CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=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 is not set
+ CONFIG_IP_PNP_BOOTP=y
+@@ -296,8 +245,10 @@ CONFIG_INET_AH=m
+ CONFIG_INET_ESP=m
+ CONFIG_INET_IPCOMP=m
+ CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-CONFIG_IP_TCPDIAG_IPV6=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
+@@ -341,6 +292,9 @@ CONFIG_INET6_TUNNEL=m
+ CONFIG_IPV6_TUNNEL=m
+ CONFIG_NETFILTER=y
+ # CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
+ 
+ #
+ # IP: Netfilter Configuration
+@@ -348,11 +302,15 @@ CONFIG_NETFILTER=y
+ CONFIG_IP_NF_CONNTRACK=m
+ CONFIG_IP_NF_CT_ACCT=y
+ CONFIG_IP_NF_CONNTRACK_MARK=y
++CONFIG_IP_NF_CONNTRACK_EVENTS=y
++CONFIG_IP_NF_CONNTRACK_NETLINK=m
+ # CONFIG_IP_NF_CT_PROTO_SCTP is not set
+ CONFIG_IP_NF_FTP=m
+ CONFIG_IP_NF_IRC=m
++# CONFIG_IP_NF_NETBIOS_NS is not set
+ CONFIG_IP_NF_TFTP=m
+ CONFIG_IP_NF_AMANDA=m
++CONFIG_IP_NF_PPTP=m
+ CONFIG_IP_NF_QUEUE=m
+ CONFIG_IP_NF_IPTABLES=m
+ CONFIG_IP_NF_MATCH_LIMIT=m
+@@ -376,9 +334,12 @@ CONFIG_IP_NF_MATCH_OWNER=m
+ CONFIG_IP_NF_MATCH_ADDRTYPE=m
+ CONFIG_IP_NF_MATCH_REALM=m
+ CONFIG_IP_NF_MATCH_SCTP=m
++CONFIG_IP_NF_MATCH_DCCP=m
+ CONFIG_IP_NF_MATCH_COMMENT=m
+ CONFIG_IP_NF_MATCH_CONNMARK=m
++CONFIG_IP_NF_MATCH_CONNBYTES=m
+ CONFIG_IP_NF_MATCH_HASHLIMIT=m
++CONFIG_IP_NF_MATCH_STRING=m
+ CONFIG_IP_NF_FILTER=m
+ CONFIG_IP_NF_TARGET_REJECT=m
+ CONFIG_IP_NF_TARGET_LOG=m
+@@ -395,12 +356,14 @@ 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_MANGLE=m
+ CONFIG_IP_NF_TARGET_TOS=m
+ CONFIG_IP_NF_TARGET_ECN=m
+ CONFIG_IP_NF_TARGET_DSCP=m
+ CONFIG_IP_NF_TARGET_MARK=m
+ CONFIG_IP_NF_TARGET_CLASSIFY=m
++CONFIG_IP_NF_TARGET_TTL=m
+ CONFIG_IP_NF_TARGET_CONNMARK=m
+ CONFIG_IP_NF_TARGET_CLUSTERIP=m
+ CONFIG_IP_NF_RAW=m
+@@ -410,7 +373,7 @@ CONFIG_IP_NF_ARPFILTER=m
+ CONFIG_IP_NF_ARP_MANGLE=m
+ 
+ #
+-# IPv6: Netfilter Configuration
++# IPv6: Netfilter Configuration (EXPERIMENTAL)
+ #
+ CONFIG_IP6_NF_QUEUE=m
+ CONFIG_IP6_NF_IPTABLES=m
+@@ -429,11 +392,16 @@ CONFIG_IP6_NF_MATCH_LENGTH=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_MARK=m
++CONFIG_IP6_NF_TARGET_HL=m
+ CONFIG_IP6_NF_RAW=m
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
+ 
+ #
+ # SCTP Configuration (EXPERIMENTAL)
+@@ -456,10 +424,6 @@ CONFIG_SCTP_HMAC_MD5=y
+ CONFIG_NET_DIVERT=y
+ # 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
+@@ -479,6 +443,7 @@ CONFIG_NET_SCH_INGRESS=m
+ CONFIG_NET_QOS=y
+ CONFIG_NET_ESTIMATOR=y
+ CONFIG_NET_CLS=y
++CONFIG_NET_CLS_BASIC=m
+ CONFIG_NET_CLS_TCINDEX=m
+ CONFIG_NET_CLS_ROUTE4=m
+ CONFIG_NET_CLS_ROUTE=y
+@@ -489,6 +454,7 @@ CONFIG_NET_CLS_U32=m
+ # 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
+ 
+@@ -496,17 +462,153 @@ CONFIG_NET_CLS_POLICE=y
+ # 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_IEEE80211=m
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=m
++CONFIG_IEEE80211_CRYPT_CCMP=m
++CONFIG_IEEE80211_CRYPT_TKIP=m
++
++#
++# 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=m
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Plug and Play support
++#
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
++# CONFIG_LBD is not set
++CONFIG_CDROM_PKTCDVD=m
++CONFIG_CDROM_PKTCDVD_BUFFERS=8
++# CONFIG_CDROM_PKTCDVD_WCACHE 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=m
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++CONFIG_RAID_ATTRS=m
++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 is not set
++# CONFIG_CHR_DEV_SG is not set
++CONFIG_CHR_DEV_SCH=m
++
++#
++# 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=m
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++CONFIG_SCSI_SAS_ATTRS=m
++
++#
++# SCSI low-level drivers
++#
++CONFIG_SGIWD93_SCSI=y
++# 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
++#
++
++#
++# Network device support
++#
+ CONFIG_NETDEVICES=y
+ CONFIG_DUMMY=m
+ CONFIG_BONDING=m
+ CONFIG_EQUALIZER=m
+ CONFIG_TUN=m
+-CONFIG_ETHERTAP=m
++
++#
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -540,6 +642,8 @@ CONFIG_SGISEEQ=y
+ # 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
+@@ -569,18 +673,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-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
+-
+-#
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
+@@ -598,6 +690,16 @@ CONFIG_MOUSE_SERIAL=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_I8042=y
++CONFIG_SERIO_SERPORT=y
++CONFIG_SERIO_LIBPS2=y
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -644,11 +746,14 @@ CONFIG_SGI_DS1286=m
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_DRM is not set
+ CONFIG_RAW_DRIVER=m
+ CONFIG_MAX_RAW_DEVS=256
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -659,10 +764,20 @@ CONFIG_MAX_RAW_DEVS=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -693,7 +808,6 @@ CONFIG_LOGO=y
+ # CONFIG_LOGO_LINUX_VGA16 is not set
+ # CONFIG_LOGO_LINUX_CLUT224 is not set
+ CONFIG_LOGO_SGI_CLUT224=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -707,10 +821,6 @@ CONFIG_LOGO_SGI_CLUT224=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -723,13 +833,17 @@ CONFIG_LOGO_SGI_CLUT224=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN Devices
++#
+ 
+ #
+ # File systems
+ #
+ CONFIG_EXT2_FS=m
+ # 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=y
+@@ -741,12 +855,14 @@ CONFIG_FS_MBCACHE=y
+ # CONFIG_JFS_FS is not set
+ CONFIG_FS_POSIX_ACL=y
+ CONFIG_XFS_FS=m
+-# CONFIG_XFS_RT is not set
+-CONFIG_XFS_QUOTA=y
++CONFIG_XFS_EXPORT=y
++CONFIG_XFS_QUOTA=m
+ CONFIG_XFS_SECURITY=y
+ # CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
+ CONFIG_MINIX_FS=m
+ # CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
+ CONFIG_QUOTA=y
+ # CONFIG_QFMT_V1 is not set
+ CONFIG_QFMT_V2=m
+@@ -754,6 +870,7 @@ CONFIG_QUOTACTL=y
+ CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -781,12 +898,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -811,15 +926,20 @@ CONFIG_UFS_FS=m
+ #
+ CONFIG_NFS_FS=m
+ CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
+ # CONFIG_NFS_V4 is not set
+ # CONFIG_NFS_DIRECTIO is not set
+ CONFIG_NFSD=m
++CONFIG_NFSD_V2_ACL=y
+ CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
+ # CONFIG_NFSD_V4 is not set
+ 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
+@@ -835,6 +955,7 @@ CONFIG_CIFS=m
+ CONFIG_CODA_FS=m
+ # CONFIG_CODA_FS_OLD_API is not set
+ # CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
+ 
+ #
+ # Partition Types
+@@ -908,7 +1029,9 @@ CONFIG_NLS_UTF8=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -931,6 +1054,7 @@ CONFIG_CRYPTO_SHA1=m
+ 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
+@@ -942,10 +1066,10 @@ CONFIG_CRYPTO_TEA=m
+ CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_DEFLATE=m
+ CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+-CONFIG_CRYPTO_TEST=m
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -955,9 +1079,12 @@ CONFIG_CRYPTO_TEST=m
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=m
+ CONFIG_CRC32=m
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_TEXTSEARCH=y
++CONFIG_TEXTSEARCH_KMP=m
++CONFIG_TEXTSEARCH_BM=m
++CONFIG_TEXTSEARCH_FSM=m
+diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
+--- a/arch/mips/configs/ip27_defconfig
++++ b/arch/mips/configs/ip27_defconfig
+@@ -1,11 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:04 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:04 2005
+ #
+ CONFIG_MIPS=y
+-CONFIG_64BIT=y
+-CONFIG_64BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -13,25 +11,31 @@ CONFIG_64BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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 is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=15
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++CONFIG_CPUSETS=y
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +45,7 @@ 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
+@@ -57,55 +62,85 @@ CONFIG_STOP_MACHINE=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+ CONFIG_SGI_IP27=y
++# 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_SGI_SN0_N_MODE is not set
+ CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+ CONFIG_NUMA=y
+ # CONFIG_MAPPED_KERNEL is not set
+ # CONFIG_REPLICATE_KTEXT is not set
+ # CONFIG_REPLICATE_EXHANDLERS is not set
+-# CONFIG_SGI_IP32 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+-# CONFIG_SNI_RM200_PCI is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_ARC=y
+ CONFIG_DMA_IP27=y
++CONFIG_CPU_BIG_ENDIAN=y
+ # CONFIG_CPU_LITTLE_ENDIAN is not set
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=7
+ CONFIG_ARC64=y
+ CONFIG_BOOT_ELF64=y
+-CONFIG_QL_ISP_A64=y
+ 
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -121,17 +156,42 @@ CONFIG_CPU_R10000=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R10000=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
+ CONFIG_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 is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=y
+ CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_SELECT_MEMORY_MODEL=y
++# CONFIG_FLATMEM_MANUAL is not set
++CONFIG_DISCONTIGMEM_MANUAL=y
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_DISCONTIGMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_NEED_MULTIPLE_NODES=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ CONFIG_SMP=y
+ CONFIG_NR_CPUS=64
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
++CONFIG_PREEMPT_BKL=y
+ # CONFIG_MIPS_INSANE_LARGE is not set
+ 
+ #
+@@ -141,7 +201,6 @@ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_DOMAINS=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -150,10 +209,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -163,7 +218,7 @@ CONFIG_MMU=y
+ #
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+-# CONFIG_BUILD_ELF64 is not set
++CONFIG_BUILD_ELF64=y
+ CONFIG_MIPS32_COMPAT=y
+ CONFIG_COMPAT=y
+ CONFIG_MIPS32_O32=y
+@@ -171,6 +226,111 @@ CONFIG_MIPS32_O32=y
+ CONFIG_BINFMT_ELF32=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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 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=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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++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
++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
++CONFIG_NET_QOS=y
++CONFIG_NET_ESTIMATOR=y
++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 is not set
++# CONFIG_NET_CLS_IND 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
++
++#
++# 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -179,7 +339,12 @@ CONFIG_BINFMT_ELF32=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -198,7 +363,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -210,7 +374,6 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+ # CONFIG_CDROM_PKTCDVD_WCACHE is not set
+@@ -232,6 +395,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -241,8 +405,10 @@ CONFIG_SCSI_PROC_FS=y
+ CONFIG_BLK_DEV_SD=y
+ CONFIG_CHR_DEV_ST=y
+ # CONFIG_CHR_DEV_OSST is not set
+-# CONFIG_BLK_DEV_SR is not set
+-# CONFIG_CHR_DEV_SG is not set
++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
+@@ -256,7 +422,8 @@ CONFIG_SCSI_LOGGING=y
+ #
+ CONFIG_SCSI_SPI_ATTRS=y
+ # CONFIG_SCSI_FC_ATTRS is not set
+-# CONFIG_SCSI_ISCSI_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++CONFIG_SCSI_SAS_ATTRS=m
+ 
+ #
+ # SCSI low-level drivers
+@@ -271,26 +438,24 @@ CONFIG_SCSI_SPI_ATTRS=y
+ # CONFIG_MEGARAID_NEWGEN is not set
+ # CONFIG_MEGARAID_LEGACY is not set
+ # CONFIG_SCSI_SATA is not set
+-# CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_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_ISP=y
+ # CONFIG_SCSI_QLOGIC_FC is not set
+-# CONFIG_SCSI_QLOGIC_1280 is not set
++CONFIG_SCSI_QLOGIC_1280=y
++CONFIG_SCSI_QLOGIC_1280_1040=y
+ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA21XX is not set
+ # CONFIG_SCSI_QLA22XX is not set
+ # CONFIG_SCSI_QLA2300 is not set
+ # CONFIG_SCSI_QLA2322 is not set
+ # CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX is not set
++# CONFIG_SCSI_LPFC is not set
+ # CONFIG_SCSI_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+ # CONFIG_SCSI_DEBUG is not set
+@@ -313,11 +478,15 @@ 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
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -330,107 +499,13 @@ CONFIG_DM_ZERO=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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=y
+-# CONFIG_NET_SCH_CLK_JIFFIES is not set
+-CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+-# CONFIG_NET_SCH_CLK_CPU is not set
+-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
+-CONFIG_NET_QOS=y
+-CONFIG_NET_ESTIMATOR=y
+-CONFIG_NET_CLS=y
+-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_NET_CLS_IND is not set
+-CONFIG_NET_CLS_RSVP=m
+-CONFIG_NET_CLS_RSVP6=m
+-# CONFIG_NET_CLS_ACT is not set
+-CONFIG_NET_CLS_POLICE=y
+-
+-#
+-# Network testing
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -438,13 +513,25 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=y
+-CONFIG_SGI_IOC3_ETH=y
+-CONFIG_SGI_IOC3_ETH_HW_RX_CSUM=y
+-CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
+ # CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNGEM is not set
+ # CONFIG_NET_VENDOR_3COM is not set
+@@ -466,12 +553,16 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
+ # 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_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
+ 
+@@ -484,6 +575,8 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -496,6 +589,8 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
+ # 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
+@@ -513,25 +608,15 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
+ # CONFIG_INPUT is not set
+ 
+ #
+-# Userland interfaces
+-#
+-
+-#
+-# Input I/O drivers
++# Hardware I/O ports
+ #
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+ CONFIG_SERIO=y
+ # CONFIG_SERIO_I8042 is not set
+ CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+ # CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_LIBPS2=m
+ CONFIG_SERIO_RAW=m
+-
+-#
+-# Input Device Drivers
+-#
++# CONFIG_GAMEPORT is not set
+ 
+ #
+ # Character devices
+@@ -549,7 +634,6 @@ 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_MULTIPORT is not set
+ # CONFIG_SERIAL_8250_RSA is not set
+ 
+ #
+@@ -557,6 +641,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
+ #
+ 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
+@@ -584,6 +669,11 @@ CONFIG_SGI_IP27_RTC=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -594,10 +684,20 @@ CONFIG_SGI_IP27_RTC=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -611,7 +711,6 @@ CONFIG_SGI_IP27_RTC=y
+ # Graphics support
+ #
+ # CONFIG_FB is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -621,13 +720,9 @@ CONFIG_SGI_IP27_RTC=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -645,12 +740,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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=y
+ CONFIG_EXT3_FS_XATTR=y
+ CONFIG_EXT3_FS_POSIX_ACL=y
+@@ -662,17 +762,19 @@ CONFIG_FS_MBCACHE=y
+ # CONFIG_JFS_FS is not set
+ CONFIG_FS_POSIX_ACL=y
+ CONFIG_XFS_FS=m
+-# CONFIG_XFS_RT is not set
+-CONFIG_XFS_QUOTA=y
++CONFIG_XFS_QUOTA=m
+ CONFIG_XFS_SECURITY=y
+ CONFIG_XFS_POSIX_ACL=y
++# CONFIG_XFS_RT is not set
+ # CONFIG_MINIX_FS is not set
+ # CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
+ # CONFIG_QUOTA is not set
+ CONFIG_QUOTACTL=y
+ CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=m
+ # CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -693,12 +795,10 @@ CONFIG_AUTOFS_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -722,13 +822,14 @@ CONFIG_RAMFS=y
+ #
+ 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 is not set
+ CONFIG_LOCKD=y
+ CONFIG_LOCKD_V4=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ CONFIG_SUNRPC_GSS=y
+ CONFIG_RPCSEC_GSS_KRB5=y
+@@ -738,6 +839,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
+ # 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
+@@ -772,7 +874,9 @@ CONFIG_SGI_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=15
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -788,28 +892,29 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
+ CONFIG_CRYPTO_MD5=y
+-CONFIG_CRYPTO_SHA1=y
+-CONFIG_CRYPTO_SHA256=y
+-CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
++CONFIG_CRYPTO_TGR192=m
+ CONFIG_CRYPTO_DES=y
+-CONFIG_CRYPTO_BLOWFISH=y
+-CONFIG_CRYPTO_TWOFISH=y
+-CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_BLOWFISH=m
++CONFIG_CRYPTO_TWOFISH=m
++CONFIG_CRYPTO_SERPENT=m
+ CONFIG_CRYPTO_AES=m
+-CONFIG_CRYPTO_CAST5=y
+-CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+-CONFIG_CRYPTO_TEST=m
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -819,9 +924,8 @@ CONFIG_CRYPTO_TEST=m
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
+--- a/arch/mips/configs/ip32_defconfig
++++ b/arch/mips/configs/ip32_defconfig
+@@ -1,11 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:04 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:07 2005
+ #
+ CONFIG_MIPS=y
+-CONFIG_64BIT=y
+-CONFIG_64BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -13,11 +11,13 @@ CONFIG_64BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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
+@@ -25,13 +25,16 @@ CONFIG_BSD_PROCESS_ACCT=y
+ # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +44,7 @@ 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
+@@ -50,42 +54,71 @@ CONFIG_CC_ALIGN_JUMPS=0
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+ # CONFIG_SGI_IP27 is not set
+ CONFIG_SGI_IP32=y
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_ARC=y
+ CONFIG_DMA_IP32=y
+-CONFIG_OWN_DMA=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++CONFIG_OWN_DMA=y
++CONFIG_CPU_BIG_ENDIAN=y
+ # CONFIG_CPU_LITTLE_ENDIAN is not set
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+ CONFIG_ARC32=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -95,8 +128,10 @@ CONFIG_ARC_PROMLIB=y
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -112,6 +147,17 @@ CONFIG_CPU_R5000=y
+ # 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_HAS_CPU_RM7000=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
+ CONFIG_PAGE_SIZE_4KB=y
+ # CONFIG_PAGE_SIZE_8KB is not set
+ # CONFIG_PAGE_SIZE_16KB is not set
+@@ -119,9 +165,22 @@ CONFIG_PAGE_SIZE_4KB=y
+ CONFIG_BOARD_SCACHE=y
+ CONFIG_R5000_CPU_SCACHE=y
+ CONFIG_RM7000_CPU_SCACHE=y
++# CONFIG_MIPS_MT is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE is not set
++CONFIG_PREEMPT_VOLUNTARY=y
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -130,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -139,10 +197,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -160,6 +214,80 @@ CONFIG_MIPS32_O32=y
+ CONFIG_BINFMT_ELF32=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=y
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++CONFIG_IEEE80211_CRYPT_CCMP=y
++CONFIG_IEEE80211_CRYPT_TKIP=y
++
++#
+ # Device Drivers
+ #
+ 
+@@ -168,7 +296,12 @@ CONFIG_BINFMT_ELF32=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=y
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -187,7 +320,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -199,7 +331,6 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+ # CONFIG_CDROM_PKTCDVD_WCACHE is not set
+@@ -221,6 +352,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -233,6 +365,7 @@ CONFIG_CHR_DEV_OSST=y
+ 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
+@@ -244,9 +377,10 @@ CONFIG_SCSI_LOGGING=y
+ #
+ # SCSI Transport Attributes
+ #
+-# CONFIG_SCSI_SPI_ATTRS is not set
++CONFIG_SCSI_SPI_ATTRS=y
+ # CONFIG_SCSI_FC_ATTRS is not set
+ # CONFIG_SCSI_ISCSI_ATTRS is not set
++CONFIG_SCSI_SAS_ATTRS=y
+ 
+ #
+ # SCSI low-level drivers
+@@ -266,18 +400,13 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+ # CONFIG_MEGARAID_NEWGEN is not set
+ # CONFIG_MEGARAID_LEGACY is not set
+ # CONFIG_SCSI_SATA is not set
+-# CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_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_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+ CONFIG_SCSI_QLA2XXX=y
+@@ -286,6 +415,8 @@ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA2300 is not set
+ # CONFIG_SCSI_QLA2322 is not set
+ # CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX is not set
++# CONFIG_SCSI_LPFC is not set
+ # CONFIG_SCSI_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+ # CONFIG_SCSI_DEBUG is not set
+@@ -299,6 +430,8 @@ CONFIG_SCSI_QLA2XXX=y
+ # Fusion MPT device support
+ #
+ # CONFIG_FUSION is not set
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -311,78 +444,13 @@ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=y
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=y
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -390,6 +458,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=y
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=y
++CONFIG_DAVICOM_PHY=y
++CONFIG_QSEMI_PHY=y
++CONFIG_LXT_PHY=y
++CONFIG_CICADA_PHY=y
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -416,12 +499,16 @@ CONFIG_SGI_O2MACE_ETH=y
+ # 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_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
+ 
+@@ -434,6 +521,8 @@ CONFIG_SGI_O2MACE_ETH=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=y
+ 
+ #
+ # Wan interfaces
+@@ -446,6 +535,8 @@ CONFIG_SGI_O2MACE_ETH=y
+ # 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
+@@ -475,27 +566,25 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
++# 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_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+ CONFIG_SERIO=y
+ # CONFIG_SERIO_I8042 is not set
+ CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+ # CONFIG_SERIO_PCIPS2 is not set
+ # CONFIG_SERIO_MACEPS2 is not set
+ # CONFIG_SERIO_LIBPS2 is not set
+ CONFIG_SERIO_RAW=y
+-
+-#
+-# 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
++# CONFIG_GAMEPORT is not set
+ 
+ #
+ # Character devices
+@@ -518,6 +607,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -544,6 +634,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -554,10 +649,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -577,7 +682,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -587,13 +691,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -611,21 +711,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_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=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -646,13 +754,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -676,13 +781,14 @@ CONFIG_RAMFS=y
+ #
+ 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_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -691,6 +797,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -721,7 +828,9 @@ CONFIG_SGI_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -735,7 +844,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=y
++CONFIG_CRYPTO_TGR192=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=y
++CONFIG_CRYPTO_CAST5=y
++CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_TEA=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_KHAZAD=y
++CONFIG_CRYPTO_ANUBIS=y
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -745,7 +878,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=y
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig
+--- a/arch/mips/configs/it8172_defconfig
++++ b/arch/mips/configs/it8172_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:05 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:09 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,11 +11,13 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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
+@@ -26,13 +25,16 @@ CONFIG_BSD_PROCESS_ACCT=y
+ # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=14
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -42,6 +44,7 @@ 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
+@@ -57,41 +60,69 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT is not set
+ CONFIG_MIPS_ITE8172=y
+-# CONFIG_IT8172_REVC 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_IT8172_REVC is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_ITE_BOARD_GEN=y
+ CONFIG_IT8172_CIR=y
+ CONFIG_IT8712=y
+@@ -100,8 +131,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -117,14 +150,39 @@ CONFIG_CPU_NEVADA=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R5432=y
++CONFIG_SYS_HAS_CPU_NEVADA=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_MIPS_MT is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -140,10 +198,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -155,6 +209,80 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -166,12 +294,17 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_FW_LOADER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+-# CONFIG_MTD_PARTITIONS is not set
+ # CONFIG_MTD_CONCAT is not set
++# CONFIG_MTD_PARTITIONS is not set
+ 
+ #
+ # User Modules And Translation Layers
+@@ -207,7 +340,6 @@ 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_XIP is not set
+ 
+ #
+ # Mapping drivers for chip access
+@@ -217,6 +349,7 @@ CONFIG_MTD_PHYSMAP=y
+ CONFIG_MTD_PHYSMAP_START=0x8000000
+ CONFIG_MTD_PHYSMAP_LEN=0x2000000
+ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PLATRAM is not set
+ 
+ #
+ # Self-contained MTD device drivers
+@@ -251,14 +384,12 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -302,6 +433,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -312,6 +444,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -322,78 +455,28 @@ CONFIG_IDE_GENERIC=y
+ #
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
++# Network device support
+ #
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
+ 
+ #
+-# SCTP Configuration (EXPERIMENTAL)
++# PHY device support
+ #
+-# 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
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
+ 
+ #
+-# QoS and/or fair queueing
++# MII PHY device drivers
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -426,6 +509,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -455,18 +540,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -476,6 +549,16 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -521,10 +604,13 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -535,10 +621,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -558,7 +654,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -574,15 +669,9 @@ CONFIG_SOUND=y
+ # Open Sound System
+ #
+ CONFIG_SOUND_PRIME=y
+-# CONFIG_SOUND_BT878 is not set
+-# CONFIG_SOUND_FUSION is not set
+-# CONFIG_SOUND_CS4281 is not set
+-# CONFIG_SOUND_SONICVIBES is not set
+ CONFIG_SOUND_IT8172=y
+-# CONFIG_SOUND_TRIDENT is not set
+ # CONFIG_SOUND_MSNDCLAS is not set
+ # CONFIG_SOUND_MSNDPIN is not set
+-# CONFIG_SOUND_OSS is not set
+ # CONFIG_SOUND_AD1980 is not set
+ 
+ #
+@@ -592,10 +681,6 @@ CONFIG_SOUND_IT8172=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -608,24 +693,31 @@ CONFIG_SOUND_IT8172=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN 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_JBD 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_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=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -646,12 +738,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -682,7 +772,7 @@ CONFIG_NFS_FS=y
+ # CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -691,6 +781,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -711,7 +802,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -725,7 +818,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -735,7 +852,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
++CONFIG_CRC16=m
++CONFIG_CRC32=m
+ CONFIG_LIBCRC32C=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig
+--- a/arch/mips/configs/ivr_defconfig
++++ b/arch/mips/configs/ivr_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:05 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:12 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,11 +11,13 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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
+@@ -26,13 +25,16 @@ CONFIG_BSD_PROCESS_ACCT=y
+ # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -42,6 +44,7 @@ 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
+@@ -57,40 +60,68 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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=y
+-# CONFIG_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_ITE_BOARD_GEN=y
+ CONFIG_IT8172_CIR=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -98,8 +129,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -115,14 +148,38 @@ CONFIG_CPU_NEVADA=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_NEVADA=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_MIPS_MT is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -131,7 +188,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -140,10 +196,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -156,6 +208,80 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -164,7 +290,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -183,7 +314,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -194,7 +324,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -239,6 +368,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -249,6 +379,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -261,78 +392,13 @@ CONFIG_IDE_GENERIC=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -340,6 +406,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -365,12 +446,16 @@ CONFIG_NET_ETHERNET=y
+ # 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_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
+ 
+@@ -383,6 +468,8 @@ CONFIG_NET_ETHERNET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -394,6 +481,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -423,19 +512,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -445,6 +521,17 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -467,6 +554,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -492,6 +580,11 @@ CONFIG_RTC=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -502,10 +595,20 @@ CONFIG_RTC=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -525,7 +628,6 @@ CONFIG_RTC=y
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -535,13 +637,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -559,21 +657,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_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=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -594,12 +700,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -628,7 +732,7 @@ CONFIG_NFS_FS=y
+ # CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -637,6 +741,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -657,7 +762,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -671,7 +778,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -681,7 +812,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
++CONFIG_CRC16=m
++CONFIG_CRC32=m
+ CONFIG_LIBCRC32C=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
+--- a/arch/mips/configs/jaguar-atx_defconfig
++++ b/arch/mips/configs/jaguar-atx_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:05 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:14 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ # 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_LOCALVERSION_AUTO=y
+ CONFIG_SWAP=y
+ CONFIG_SYSVIPC=y
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -54,36 +57,70 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++CONFIG_MOMENCO_JAGUAR_ATX=y
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-CONFIG_MOMENCO_JAGUAR_ATX=y
+-CONFIG_JAGUAR_DMALOW=y
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 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_JAGUAR_DMALOW=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_LIMITED_DMA=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_MV64340=y
+@@ -95,8 +132,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -112,6 +151,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ # 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
+@@ -119,13 +169,24 @@ CONFIG_PAGE_SIZE_4KB=y
+ CONFIG_BOARD_SCACHE=y
+ CONFIG_RM7000_CPU_SCACHE=y
+ CONFIG_CPU_HAS_PREFETCH=y
++# CONFIG_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=y
+ CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
+ CONFIG_HIGHMEM=y
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_SYS_SUPPORTS_HIGHMEM=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ # CONFIG_SMP is not set
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -134,7 +195,6 @@ CONFIG_HIGHMEM=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -143,10 +203,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -158,6 +214,68 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET 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 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_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=m
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_BIC=y
++CONFIG_IPV6=m
++CONFIG_IPV6_PRIVACY=y
++CONFIG_INET6_AH=m
++CONFIG_INET6_ESP=m
++CONFIG_INET6_IPCOMP=m
++CONFIG_INET6_TUNNEL=m
++CONFIG_IPV6_TUNNEL=m
++# 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -166,7 +284,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -185,7 +308,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -195,7 +317,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -218,6 +339,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -228,6 +350,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -240,58 +363,8 @@ CONFIG_ATA_OVER_ETH=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
++# Network device support
+ #
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-# CONFIG_PACKET is not set
+-# CONFIG_NETLINK_DEV 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_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_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=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-# 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
+@@ -304,6 +377,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -343,9 +431,11 @@ CONFIG_EEPRO100=y
+ # CONFIG_NS83820 is not set
+ # CONFIG_HAMACHI is not set
+ # CONFIG_R8169 is not set
++# CONFIG_SIS190 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=y
+ CONFIG_MV643XX_ETH_1=y
+@@ -354,6 +444,7 @@ CONFIG_MV643XX_ETH_2=y
+ #
+ # Ethernet (10000 Mbit)
+ #
++# CONFIG_CHELSIO_T1 is not set
+ # CONFIG_IXGB is not set
+ # CONFIG_S2IO is not set
+ 
+@@ -366,6 +457,8 @@ CONFIG_MV643XX_ETH_2=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -374,6 +467,8 @@ CONFIG_MV643XX_ETH_2=y
+ # CONFIG_FDDI is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
+ 
+ #
+ # ISDN subsystem
+@@ -391,20 +486,10 @@ CONFIG_MV643XX_ETH_2=y
+ # CONFIG_INPUT is not set
+ 
+ #
+-# Userland interfaces
+-#
+-
+-#
+-# Input I/O drivers
++# Hardware I/O ports
+ #
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+ # CONFIG_SERIO is not set
+-# CONFIG_SERIO_I8042 is not set
+-
+-#
+-# Input Device Drivers
+-#
++# CONFIG_GAMEPORT is not set
+ 
+ #
+ # Character devices
+@@ -425,6 +510,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -451,6 +537,10 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -461,10 +551,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -478,7 +578,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Graphics support
+ #
+ # CONFIG_FB is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -488,13 +587,9 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -512,6 +607,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ # CONFIG_EXT2_FS is not set
+@@ -519,13 +618,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_JBD 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_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=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -546,10 +648,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ # CONFIG_TMPFS is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -570,7 +672,7 @@ CONFIG_NFS_FS=y
+ # CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_SMB_FS is not set
+ # CONFIG_CIFS is not set
+@@ -591,7 +693,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -605,7 +709,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -615,7 +743,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=m
++CONFIG_CRC32=m
++CONFIG_LIBCRC32C=m
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
+--- a/arch/mips/configs/jmr3927_defconfig
++++ b/arch/mips/configs/jmr3927_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:06 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:17 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -50,40 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-CONFIG_TOSHIBA_JMR3927=y
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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=y
+ # CONFIG_TOSHIBA_RBTX4927 is not set
++# CONFIG_TOSHIBA_RBTX4938 is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=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_MIPS_TX3927=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -92,8 +123,10 @@ CONFIG_TOSHIBA_BOARDS=y
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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=y
+ # CONFIG_CPU_VR41XX is not set
+@@ -109,12 +142,34 @@ CONFIG_CPU_TX39XX=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_TX39XX=y
++CONFIG_SYS_SUPPORTS_32BIT_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_MIPS_MT is not set
+ # CONFIG_CPU_ADVANCED is not set
+ 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ CONFIG_RTC_DS1742=y
+ 
+@@ -124,7 +179,6 @@ CONFIG_RTC_DS1742=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -133,10 +187,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -149,6 +199,80 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=y
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++CONFIG_IEEE80211_CRYPT_CCMP=y
++CONFIG_IEEE80211_CRYPT_TKIP=y
++
++#
+ # Device Drivers
+ #
+ 
+@@ -157,7 +281,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=y
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -176,7 +305,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -187,7 +315,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -210,6 +337,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -220,6 +348,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -232,78 +361,13 @@ CONFIG_ATA_OVER_ETH=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=y
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=y
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -311,6 +375,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=y
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=y
++CONFIG_DAVICOM_PHY=y
++CONFIG_QSEMI_PHY=y
++CONFIG_LXT_PHY=y
++CONFIG_CICADA_PHY=y
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -336,12 +415,16 @@ CONFIG_NET_ETHERNET=y
+ # 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_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
+ 
+@@ -354,6 +437,8 @@ CONFIG_NET_ETHERNET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=y
+ 
+ #
+ # Wan interfaces
+@@ -365,6 +450,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -394,19 +481,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=y
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -416,6 +490,17 @@ CONFIG_SERIO_RAW=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=y
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -426,11 +511,9 @@ CONFIG_SERIAL_NONSTANDARD=y
+ # CONFIG_ROCKETPORT is not set
+ # CONFIG_CYCLADES is not set
+ # CONFIG_DIGIEPCA is not set
+-# CONFIG_DIGI is not set
+ # CONFIG_MOXA_INTELLIO is not set
+ # CONFIG_MOXA_SMARTIO is not set
+ # CONFIG_ISI is not set
+-# CONFIG_SYNCLINK is not set
+ # CONFIG_SYNCLINKMP is not set
+ # CONFIG_N_HDLC is not set
+ # CONFIG_RISCOM8 is not set
+@@ -438,10 +521,6 @@ CONFIG_SERIAL_NONSTANDARD=y
+ # CONFIG_SX is not set
+ # CONFIG_RIO is not set
+ # CONFIG_STALDRV is not set
+-# CONFIG_SERIAL_TX3912 is not set
+-CONFIG_TXX927_SERIAL=y
+-CONFIG_TXX927_SERIAL_CONSOLE=y
+-# CONFIG_SERIAL_TXX9 is not set
+ 
+ #
+ # Serial drivers
+@@ -451,6 +530,8 @@ CONFIG_TXX927_SERIAL_CONSOLE=y
+ #
+ # Non-8250 serial port support
+ #
++CONFIG_HAS_TXX9_SERIAL=y
++# CONFIG_SERIAL_JSM is not set
+ # CONFIG_UNIX98_PTYS is not set
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -477,6 +558,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -487,10 +573,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -504,6 +600,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Graphics support
+ #
+ 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_SOFT_CURSOR is not set
++# CONFIG_FB_MACMODES is not set
+ # CONFIG_FB_MODE_HELPERS is not set
+ # CONFIG_FB_TILEBLITTING is not set
+ # CONFIG_FB_CIRRUS is not set
+@@ -511,6 +612,7 @@ CONFIG_FB=y
+ # CONFIG_FB_CYBER2000 is not set
+ # CONFIG_FB_ASILIANT is not set
+ # CONFIG_FB_IMSTT is not set
++# CONFIG_FB_NVIDIA is not set
+ # CONFIG_FB_RIVA is not set
+ # CONFIG_FB_MATROX is not set
+ # CONFIG_FB_RADEON_OLD is not set
+@@ -523,8 +625,11 @@ CONFIG_FB=y
+ # 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_CYBLA is not set
+ # CONFIG_FB_TRIDENT is not set
+ # CONFIG_FB_E1356 is not set
++# CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+ 
+ #
+@@ -548,13 +653,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -572,6 +673,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ # CONFIG_EXT2_FS is not set
+@@ -579,13 +684,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_JBD 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_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=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -606,10 +714,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+ # CONFIG_TMPFS is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -638,7 +746,7 @@ CONFIG_NFS_FS=y
+ # CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -647,6 +755,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -667,7 +776,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -681,7 +792,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=y
++CONFIG_CRYPTO_TGR192=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=y
++CONFIG_CRYPTO_CAST5=y
++CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_TEA=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_KHAZAD=y
++CONFIG_CRYPTO_ANUBIS=y
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -691,7 +826,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=y
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
+--- a/arch/mips/configs/lasat200_defconfig
++++ b/arch/mips/configs/lasat200_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:06 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:19 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,53 +59,83 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT=y
+-CONFIG_PICVUE=y
+-CONFIG_PICVUE_PROC=y
+-CONFIG_DS1603=y
+-CONFIG_LASAT_SYSCTL=y
+ # CONFIG_MIPS_ITE8172 is not set
++# CONFIG_MACH_JAZZ is not set
++CONFIG_LASAT=y
+ # CONFIG_MIPS_ATLAS is not set
+ # CONFIG_MIPS_MALTA is not set
+ # CONFIG_MIPS_SEAD 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_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_PICVUE=y
++CONFIG_PICVUE_PROC=y
++CONFIG_DS1603=y
++CONFIG_LASAT_SYSCTL=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_MIPS_NILE4=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_MIPS_GT64120=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -118,17 +151,41 @@ CONFIG_CPU_R5000=y
+ # 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_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_BOARD_SCACHE=y
+ CONFIG_R5000_CPU_SCACHE=y
++# CONFIG_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -137,7 +194,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-# CONFIG_PCI_NAMES is not set
+ CONFIG_MMU=y
+ 
+ #
+@@ -146,10 +202,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -162,6 +214,76 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -170,15 +292,20 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+ #
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+-CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+ # CONFIG_MTD_CMDLINE_PARTS is not set
+ 
+@@ -223,6 +350,7 @@ CONFIG_MTD_CFI_UTIL=y
+ # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+ # CONFIG_MTD_PHYSMAP is not set
+ CONFIG_MTD_LASAT=y
++# CONFIG_MTD_PLATRAM is not set
+ 
+ #
+ # Self-contained MTD device drivers
+@@ -258,7 +386,6 @@ CONFIG_MTD_LASAT=y
+ #
+ # 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
+@@ -269,7 +396,6 @@ CONFIG_MTD_LASAT=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -326,6 +452,7 @@ CONFIG_BLK_DEV_CMD64X=y
+ # 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
+@@ -343,6 +470,7 @@ CONFIG_IDEDMA_AUTO=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -353,6 +481,7 @@ CONFIG_IDEDMA_AUTO=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -365,68 +494,8 @@ CONFIG_IDEDMA_AUTO=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-# CONFIG_PACKET is not set
+-# CONFIG_NETLINK_DEV is not set
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-# 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_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
++# Network device support
+ #
+-# 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
+@@ -439,6 +508,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -464,12 +548,16 @@ CONFIG_NET_ETHERNET=y
+ # 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_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
+ 
+@@ -482,6 +570,8 @@ CONFIG_NET_ETHERNET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -493,6 +583,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -522,19 +614,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_I8042=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -544,6 +623,17 @@ CONFIG_SERIO_RAW=m
+ # 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 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -564,6 +654,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -590,6 +681,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -600,10 +696,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -623,7 +729,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -633,13 +738,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -657,10 +758,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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
+@@ -670,13 +776,16 @@ CONFIG_JBD=y
+ 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_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=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -697,12 +806,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -728,12 +835,13 @@ CONFIG_RAMFS=y
+ #
+ 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_LOCKD=y
+ CONFIG_LOCKD_V4=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -742,6 +850,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -762,7 +871,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -776,7 +887,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -786,7 +921,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
+--- a/arch/mips/configs/malta_defconfig
++++ b/arch/mips/configs/malta_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:53:14 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:22 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,44 +59,75 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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=y
+ # CONFIG_MIPS_SEAD 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_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_GENERIC_ISA_DMA=y
+ CONFIG_I8259=y
+ CONFIG_MIPS_BONITO64=y
+ CONFIG_MIPS_MSC=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_BOARDS_GEN=y
+ CONFIG_MIPS_GT64120=y
+ CONFIG_SWAP_IO_SPACE=y
+@@ -104,8 +138,10 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -121,14 +157,48 @@ CONFIG_CPU_MIPS32=y
+ # 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=y
++# CONFIG_MIPS_MT_SMP is not set
++CONFIG_MIPS_VPE_LOADER=y
++CONFIG_MIPS_VPE_LOADER_TOM=y
++CONFIG_MIPS_VPE_APSP_API=y
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -137,7 +207,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -146,10 +215,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -162,229 +227,7 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
+-# Device Drivers
+-#
+-
+-#
+-# Generic Driver Options
+-#
+-CONFIG_STANDALONE=y
+-CONFIG_PREVENT_FIRMWARE_BUILD=y
+-CONFIG_FW_LOADER=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_CPQ_DA is not set
+-# CONFIG_BLK_CPQ_CISS_DA is not set
+-# CONFIG_BLK_DEV_DAC960 is not set
+-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=4096
+-# CONFIG_BLK_DEV_INITRD is not set
+-CONFIG_INITRAMFS_SOURCE=""
+-# CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE 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=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 is not set
+-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 is not set
+-# 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 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=y
+-# 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 is not set
+-# 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_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
+-
+-#
+-# 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
+-
+-#
+-# SCSI low-level drivers
+-#
+-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=32
+-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+-# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+-CONFIG_AIC7XXX_DEBUG_MASK=0
+-CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+-# 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_SCSI_SATA is not set
+-# CONFIG_SCSI_BUSLOGIC is not set
+-# CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_EATA_PIO is not set
+-# CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+-# CONFIG_SCSI_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_ISP is not set
+-# CONFIG_SCSI_QLOGIC_FC is not set
+-# CONFIG_SCSI_QLOGIC_1280 is not set
+-CONFIG_SCSI_QLA2XXX=m
+-# CONFIG_SCSI_QLA21XX is not set
+-# CONFIG_SCSI_QLA22XX is not set
+-# CONFIG_SCSI_QLA2300 is not set
+-# CONFIG_SCSI_QLA2322 is not set
+-# CONFIG_SCSI_QLA6312 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=m
+-CONFIG_MD_LINEAR=m
+-CONFIG_MD_RAID0=m
+-CONFIG_MD_RAID1=m
+-CONFIG_MD_RAID10=m
+-CONFIG_MD_RAID5=m
+-CONFIG_MD_RAID6=m
+-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
+-
+-#
+-# 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
+-
+-#
+-# Networking support
++# Networking
+ #
+ CONFIG_NET=y
+ 
+@@ -393,15 +236,20 @@ CONFIG_NET=y
+ #
+ CONFIG_PACKET=y
+ CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=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=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
+@@ -419,8 +267,10 @@ CONFIG_INET_AH=m
+ CONFIG_INET_ESP=m
+ CONFIG_INET_IPCOMP=m
+ CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-CONFIG_IP_TCPDIAG_IPV6=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
+@@ -465,6 +315,9 @@ CONFIG_IPV6_TUNNEL=m
+ CONFIG_NETFILTER=y
+ # CONFIG_NETFILTER_DEBUG is not set
+ CONFIG_BRIDGE_NETFILTER=y
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
+ 
+ #
+ # IP: Netfilter Configuration
+@@ -472,11 +325,15 @@ CONFIG_BRIDGE_NETFILTER=y
+ CONFIG_IP_NF_CONNTRACK=m
+ CONFIG_IP_NF_CT_ACCT=y
+ CONFIG_IP_NF_CONNTRACK_MARK=y
++CONFIG_IP_NF_CONNTRACK_EVENTS=y
++CONFIG_IP_NF_CONNTRACK_NETLINK=m
+ CONFIG_IP_NF_CT_PROTO_SCTP=m
+ CONFIG_IP_NF_FTP=m
+ CONFIG_IP_NF_IRC=m
++# CONFIG_IP_NF_NETBIOS_NS is not set
+ CONFIG_IP_NF_TFTP=m
+ CONFIG_IP_NF_AMANDA=m
++CONFIG_IP_NF_PPTP=m
+ CONFIG_IP_NF_QUEUE=m
+ CONFIG_IP_NF_IPTABLES=m
+ CONFIG_IP_NF_MATCH_LIMIT=m
+@@ -501,9 +358,12 @@ CONFIG_IP_NF_MATCH_PHYSDEV=m
+ CONFIG_IP_NF_MATCH_ADDRTYPE=m
+ CONFIG_IP_NF_MATCH_REALM=m
+ CONFIG_IP_NF_MATCH_SCTP=m
++CONFIG_IP_NF_MATCH_DCCP=m
+ CONFIG_IP_NF_MATCH_COMMENT=m
+ CONFIG_IP_NF_MATCH_CONNMARK=m
++CONFIG_IP_NF_MATCH_CONNBYTES=m
+ CONFIG_IP_NF_MATCH_HASHLIMIT=m
++CONFIG_IP_NF_MATCH_STRING=m
+ CONFIG_IP_NF_FILTER=m
+ CONFIG_IP_NF_TARGET_REJECT=m
+ CONFIG_IP_NF_TARGET_LOG=m
+@@ -520,12 +380,14 @@ 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_MANGLE=m
+ CONFIG_IP_NF_TARGET_TOS=m
+ CONFIG_IP_NF_TARGET_ECN=m
+ CONFIG_IP_NF_TARGET_DSCP=m
+ CONFIG_IP_NF_TARGET_MARK=m
+ CONFIG_IP_NF_TARGET_CLASSIFY=m
++CONFIG_IP_NF_TARGET_TTL=m
+ CONFIG_IP_NF_TARGET_CONNMARK=m
+ CONFIG_IP_NF_TARGET_CLUSTERIP=m
+ CONFIG_IP_NF_RAW=m
+@@ -535,133 +397,373 @@ CONFIG_IP_NF_ARPFILTER=m
+ CONFIG_IP_NF_ARP_MANGLE=m
+ 
+ #
+-# IPv6: Netfilter Configuration
++# IPv6: Netfilter Configuration (EXPERIMENTAL)
++#
++CONFIG_IP6_NF_QUEUE=m
++CONFIG_IP6_NF_IPTABLES=m
++CONFIG_IP6_NF_MATCH_LIMIT=m
++CONFIG_IP6_NF_MATCH_MAC=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_MULTIPORT=m
++CONFIG_IP6_NF_MATCH_OWNER=m
++CONFIG_IP6_NF_MATCH_MARK=m
++CONFIG_IP6_NF_MATCH_IPV6HEADER=m
++CONFIG_IP6_NF_MATCH_AHESP=m
++CONFIG_IP6_NF_MATCH_LENGTH=m
++CONFIG_IP6_NF_MATCH_EUI64=m
++CONFIG_IP6_NF_MATCH_PHYSDEV=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_MARK=m
++CONFIG_IP6_NF_TARGET_HL=m
++CONFIG_IP6_NF_RAW=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=m
++
++#
++# 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
++# 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=m
++CONFIG_DEV_APPLETALK=y
++CONFIG_IPDDP=m
++CONFIG_IPDDP_ENCAP=y
++CONFIG_IPDDP_DECAP=y
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++CONFIG_NET_DIVERT=y
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++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
++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
++CONFIG_NET_QOS=y
++CONFIG_NET_ESTIMATOR=y
++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 is not set
++CONFIG_NET_CLS_IND=y
++# 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
++
++#
++# 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
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
++
++#
++# 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_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++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=4096
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_LBD is not set
++CONFIG_CDROM_PKTCDVD=m
++CONFIG_CDROM_PKTCDVD_BUFFERS=8
++# CONFIG_CDROM_PKTCDVD_WCACHE 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=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 is not set
++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 is not set
++# 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 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=y
++# 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 is not set
++# 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_IP6_NF_QUEUE=m
+-CONFIG_IP6_NF_IPTABLES=m
+-CONFIG_IP6_NF_MATCH_LIMIT=m
+-CONFIG_IP6_NF_MATCH_MAC=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_MULTIPORT=m
+-CONFIG_IP6_NF_MATCH_OWNER=m
+-CONFIG_IP6_NF_MATCH_MARK=m
+-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+-CONFIG_IP6_NF_MATCH_AHESP=m
+-CONFIG_IP6_NF_MATCH_LENGTH=m
+-CONFIG_IP6_NF_MATCH_EUI64=m
+-CONFIG_IP6_NF_MATCH_PHYSDEV=m
+-CONFIG_IP6_NF_FILTER=m
+-CONFIG_IP6_NF_TARGET_LOG=m
+-CONFIG_IP6_NF_MANGLE=m
+-CONFIG_IP6_NF_TARGET_MARK=m
+-CONFIG_IP6_NF_RAW=m
++CONFIG_RAID_ATTRS=m
++CONFIG_SCSI=m
++CONFIG_SCSI_PROC_FS=y
+ 
+ #
+-# Bridge: Netfilter Configuration
++# SCSI support type (disk, tape, CD-ROM)
+ #
+-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
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
++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 is not set
+ 
+ #
+-# SCTP Configuration (EXPERIMENTAL)
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+ #
+-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
+-# 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=m
+-CONFIG_DEV_APPLETALK=y
+-CONFIG_IPDDP=m
+-CONFIG_IPDDP_ENCAP=y
+-CONFIG_IPDDP_DECAP=y
+-# CONFIG_X25 is not set
+-# CONFIG_LAPB is not set
+-CONFIG_NET_DIVERT=y
+-# CONFIG_ECONET is not set
+-# CONFIG_WAN_ROUTER is not set
++CONFIG_SCSI_MULTI_LUN=y
++CONFIG_SCSI_CONSTANTS=y
++CONFIG_SCSI_LOGGING=y
+ 
+ #
+-# QoS and/or fair queueing
++# SCSI Transport Attributes
+ #
+-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
+-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
+-CONFIG_NET_QOS=y
+-CONFIG_NET_ESTIMATOR=y
+-CONFIG_NET_CLS=y
+-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_NET_CLS_IND=y
+-# CONFIG_CLS_U32_MARK is not set
+-CONFIG_NET_CLS_RSVP=m
+-CONFIG_NET_CLS_RSVP6=m
+-# CONFIG_NET_CLS_ACT is not set
+-CONFIG_NET_CLS_POLICE=y
++CONFIG_SCSI_SPI_ATTRS=m
++CONFIG_SCSI_FC_ATTRS=m
++CONFIG_SCSI_ISCSI_ATTRS=m
++CONFIG_SCSI_SAS_ATTRS=m
+ 
+ #
+-# Network testing
++# SCSI low-level drivers
++#
++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=32
++CONFIG_AIC7XXX_RESET_DELAY_MS=15000
++# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
++CONFIG_AIC7XXX_DEBUG_MASK=0
++CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
++# 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_SCSI_SATA 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_FC is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++CONFIG_SCSI_QLA2XXX=m
++# CONFIG_SCSI_QLA21XX is not set
++# CONFIG_SCSI_QLA22XX is not set
++# CONFIG_SCSI_QLA2300 is not set
++# CONFIG_SCSI_QLA2322 is not set
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX 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=m
++CONFIG_MD_LINEAR=m
++CONFIG_MD_RAID0=m
++CONFIG_MD_RAID1=m
++CONFIG_MD_RAID10=m
++CONFIG_MD_RAID5=m
++CONFIG_MD_RAID6=m
++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
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# Network device support
+ #
+-# 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=m
+ CONFIG_BONDING=m
+ CONFIG_EQUALIZER=m
+ CONFIG_TUN=m
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -669,6 +771,21 @@ CONFIG_TUN=m
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -713,13 +830,17 @@ CONFIG_PCNET32=y
+ # 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_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
+ 
+@@ -732,6 +853,8 @@ CONFIG_PCNET32=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -744,6 +867,8 @@ CONFIG_PCNET32=y
+ # 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
+@@ -773,19 +898,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-# CONFIG_SERIO_RAW is not set
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -795,6 +907,17 @@ CONFIG_SERIO_SERPORT=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -815,6 +938,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -840,6 +964,11 @@ CONFIG_RTC=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -850,10 +979,20 @@ CONFIG_RTC=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -873,7 +1012,6 @@ CONFIG_RTC=y
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -883,13 +1021,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -907,10 +1041,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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
+@@ -931,12 +1070,14 @@ CONFIG_JFS_SECURITY=y
+ # CONFIG_JFS_STATISTICS is not set
+ CONFIG_FS_POSIX_ACL=y
+ CONFIG_XFS_FS=m
+-# CONFIG_XFS_RT is not set
+-CONFIG_XFS_QUOTA=y
++CONFIG_XFS_EXPORT=y
++CONFIG_XFS_QUOTA=m
+ CONFIG_XFS_SECURITY=y
+ CONFIG_XFS_POSIX_ACL=y
++# CONFIG_XFS_RT is not set
+ CONFIG_MINIX_FS=m
+ CONFIG_ROMFS_FS=m
++CONFIG_INOTIFY=y
+ CONFIG_QUOTA=y
+ # CONFIG_QFMT_V1 is not set
+ CONFIG_QFMT_V2=y
+@@ -944,6 +1085,7 @@ CONFIG_QUOTACTL=y
+ CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=y
+ # CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -971,12 +1113,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -1002,16 +1142,19 @@ CONFIG_UFS_FS=m
+ #
+ 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=y
++# CONFIG_NFSD_V3_ACL is not set
+ # CONFIG_NFSD_V4 is not set
+ # CONFIG_NFSD_TCP is not set
+ 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
+@@ -1020,6 +1163,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -1079,7 +1223,9 @@ CONFIG_NLS_UTF8=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -1101,6 +1247,7 @@ CONFIG_CRYPTO_SHA1=m
+ 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
+@@ -1125,9 +1272,12 @@ CONFIG_CRYPTO_CRC32C=m
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=m
+ CONFIG_ZLIB_DEFLATE=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_TEXTSEARCH=y
++CONFIG_TEXTSEARCH_KMP=m
++CONFIG_TEXTSEARCH_BM=m
++CONFIG_TEXTSEARCH_FSM=m
+diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/configs/mipssim_defconfig
+@@ -0,0 +1,775 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:25 2005
++#
++CONFIG_MIPS=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_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_HOTPLUG=y
++CONFIG_KOBJECT_UEVENT=y
++# CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_EMBEDDED=y
++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 is not set
++CONFIG_SHMEM=y
++CONFIG_CC_ALIGN_FUNCTIONS=0
++CONFIG_CC_ALIGN_LABELS=0
++CONFIG_CC_ALIGN_LOOPS=0
++CONFIG_CC_ALIGN_JUMPS=0
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++CONFIG_MODVERSIONS=y
++CONFIG_MODULE_SRCVERSION_ALL=y
++CONFIG_KMOD=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_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_MIPS_SIM=y
++# 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_DDB5074 is not set
++# CONFIG_DDB5476 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_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_CALIBRATE_DELAY=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_IRQ_CPU=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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_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=y
++# CONFIG_MIPS_MT_SMP is not set
++CONFIG_MIPS_VPE_LOADER=y
++CONFIG_MIPS_VPE_LOADER_TOM=y
++CONFIG_MIPS_VPE_APSP_API=y
++# CONFIG_64BIT_PHYS_ADDR is not set
++# CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_MMU=y
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# CONFIG_PCCARD is not set
++
++#
++# PCI Hotplug Support
++#
++
++#
++# Executable file formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_TRAD_SIGNALS=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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_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 is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP 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_NETFILTER 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
++# 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=y
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++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
++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
++CONFIG_NET_QOS=y
++CONFIG_NET_ESTIMATOR=y
++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 is not set
++# CONFIG_NET_CLS_U32 is not set
++# CONFIG_NET_CLS_RSVP is not set
++# CONFIG_NET_CLS_RSVP6 is not set
++# CONFIG_NET_EMATCH is not set
++# CONFIG_NET_CLS_ACT is not set
++# CONFIG_NET_CLS_POLICE 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 is not set
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER 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_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_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
++# CONFIG_LBD is not set
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# 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
++#
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++# CONFIG_MIPS_SIM_NET 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
++
++#
++# 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 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_LIBPS2 is not set
++# CONFIG_SERIO_RAW 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_NR_UARTS=1
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# 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 is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_RAW_DRIVER is not set
++
++#
++# TPM devices
++#
++
++#
++# I2C support
++#
++# CONFIG_I2C 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 Capabilities Port drivers
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++
++#
++# Graphics support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB_ARCH_HAS_HCD is not set
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# InfiniBand support
++#
++
++#
++# SN 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_JBD 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_MINIX_FS is not set
++CONFIG_ROMFS_FS=y
++# 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 is not set
++# CONFIG_SYSFS is not set
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_RELAYFS_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_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_DEBUG_KERNEL=y
++# CONFIG_MAGIC_SYSRQ is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_DETECT_SOFTLOCKUP is not set
++# 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_INFO=y
++CONFIG_CROSSCOMPILE=y
++CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_KGDB is not set
++# CONFIG_RUNTIME_DEBUG is not set
++# CONFIG_MIPS_UNCACHED is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS 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 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=y
++CONFIG_CRC32=y
++# CONFIG_LIBCRC32C is not set
+diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
+--- a/arch/mips/configs/mpc30x_defconfig
++++ b/arch/mips/configs/mpc30x_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:07 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:28 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,57 +59,86 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-CONFIG_MACH_VR41XX=y
+-# CONFIG_NEC_CMBVR4133 is not set
+-# CONFIG_CASIO_E55 is not set
+-# CONFIG_IBM_WORKPAD is not set
+-# CONFIG_TANBAC_TB0226 is not set
+-# CONFIG_TANBAC_TB0229 is not set
+-CONFIG_VICTOR_MPC30X=y
+-# CONFIG_ZAO_CAPCELLA is not set
+-CONFIG_PCI_VR41XX=y
+-CONFIG_VRC4173=y
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++CONFIG_MACH_VR41XX=y
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_NEC_CMBVR4133 is not set
++# CONFIG_CASIO_E55 is not set
++# CONFIG_IBM_WORKPAD is not set
++# CONFIG_TANBAC_TB022X is not set
++CONFIG_VICTOR_MPC30X=y
++# CONFIG_ZAO_CAPCELLA is not set
++CONFIG_PCI_VR41XX=y
++CONFIG_VRC4173=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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=y
+@@ -122,12 +154,36 @@ CONFIG_CPU_VR41XX=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_VR41XX=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# 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 is not set
+ # CONFIG_CPU_ADVANCED is not set
+ 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -136,17 +192,26 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+ # PCCARD (PCMCIA/CardBus) support
+ #
+-# CONFIG_PCCARD is not set
++CONFIG_PCCARD=y
++# CONFIG_PCMCIA_DEBUG is not set
++CONFIG_PCMCIA=y
++CONFIG_PCMCIA_LOAD_CIS=y
++CONFIG_PCMCIA_IOCTL=y
++# CONFIG_CARDBUS is not set
+ 
+ #
+ # PC-card bridges
+ #
++# CONFIG_YENTA is not set
++# CONFIG_PD6729 is not set
++# CONFIG_I82092 is not set
++# CONFIG_TCIC is not set
++CONFIG_PCMCIA_VRC4173=y
+ 
+ #
+ # PCI Hotplug Support
+@@ -161,6 +226,78 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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 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=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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -169,7 +306,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -188,7 +330,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -197,13 +338,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_LOOP 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_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
++# CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+ # IO Schedulers
+@@ -217,11 +356,35 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # ATA/ATAPI/MFM/RLL support
+ #
+-# CONFIG_IDE is not set
++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_IDECS=m
++# 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 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
+ 
+ #
+@@ -232,6 +395,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -244,79 +408,13 @@ CONFIG_ATA_OVER_ETH=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -324,20 +422,14 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
+-# Ethernet (10 or 100Mbit)
++# PHY device support
+ #
+-CONFIG_NET_ETHERNET=y
+-# CONFIG_MII is not set
+-# CONFIG_HAPPYMEAL is not set
+-# CONFIG_SUNGEM 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 (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++CONFIG_MII=m
+ 
+ #
+ # Ethernet (1000 Mbit)
+@@ -349,12 +441,16 @@ CONFIG_NET_ETHERNET=y
+ # 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_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
+ 
+@@ -366,7 +462,59 @@ CONFIG_NET_ETHERNET=y
+ #
+ # Wireless LAN (non-hamradio)
+ #
+-# CONFIG_NET_RADIO is not set
++CONFIG_NET_RADIO=y
++
++#
++# 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_IPW2100 is not set
++# CONFIG_IPW2200 is not set
++CONFIG_HERMES=m
++# CONFIG_PLX_HERMES is not set
++# CONFIG_TMD_HERMES is not set
++# CONFIG_NORTEL_HERMES is not set
++# CONFIG_PCI_HERMES is not set
++# 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 is not set
++# CONFIG_PCMCIA_WL3501 is not set
++
++#
++# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
++#
++# CONFIG_PRISM54 is not set
++# CONFIG_HOSTAP 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
+@@ -378,6 +526,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -407,19 +557,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_I8042=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -429,6 +566,17 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -439,16 +587,16 @@ CONFIG_HW_CONSOLE=y
+ #
+ # Serial drivers
+ #
+-CONFIG_SERIAL_8250=y
+-CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=4
+-# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250 is not set
+ 
+ #
+ # Non-8250 serial port support
+ #
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_VR41XX=y
++CONFIG_SERIAL_VR41XX_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -472,9 +620,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Ftape, the floppy tape device driver
+ #
+ # CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_SYNCLINK_CS is not set
++CONFIG_GPIO_VR41XX=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -485,10 +644,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -508,7 +677,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -518,13 +686,120 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB=m
++# 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 is not set
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++# CONFIG_USB_OHCI_BIG_ENDIAN is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_UHCI_HCD is not set
++# 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 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_YEALINK is not set
++# CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE 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 Multimedia devices
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++CONFIG_USB_PEGASUS=m
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_ZD1201 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_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
+@@ -542,21 +817,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_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=y
+ CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -577,12 +860,10 @@ CONFIG_AUTOFS4_FS=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -609,9 +890,8 @@ CONFIG_NFS_FS=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_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -620,6 +900,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -640,9 +921,11 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+-CONFIG_CMDLINE=""
++CONFIG_CMDLINE="mem=32M console=ttyVR0,19200"
+ 
+ #
+ # Security options
+@@ -656,26 +939,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-# 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=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
+-# CONFIG_CRYPTO_DES is not set
+-# CONFIG_CRYPTO_BLOWFISH is not set
+-CONFIG_CRYPTO_TWOFISH=y
+-# CONFIG_CRYPTO_SERPENT is not set
++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 is not set
+-# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+ # CONFIG_CRYPTO_TEST is not set
+ 
+@@ -687,9 +971,8 @@ CONFIG_CRYPTO_CRC32C=m
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
++CONFIG_CRC16=m
++CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
+--- a/arch/mips/configs/ocelot_3_defconfig
++++ b/arch/mips/configs/ocelot_3_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:07 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:30 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,25 +11,30 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -42,6 +44,7 @@ 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
+@@ -57,40 +60,68 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ CONFIG_MOMENCO_OCELOT_3=y
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=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_IRQ_CPU=y
+ CONFIG_IRQ_CPU_RM7K=y
+ CONFIG_IRQ_MV64340=y
+@@ -102,8 +133,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -119,6 +152,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ # 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
+@@ -126,13 +170,26 @@ CONFIG_PAGE_SIZE_4KB=y
+ CONFIG_BOARD_SCACHE=y
+ CONFIG_RM7000_CPU_SCACHE=y
+ CONFIG_CPU_HAS_PREFETCH=y
++# CONFIG_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=y
+ CONFIG_CPU_HAS_SYNC=y
+-# CONFIG_HIGHMEM is not set
++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_SMP is not set
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -141,7 +198,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -150,10 +206,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -166,6 +218,110 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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=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_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_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_IPV6_TUNNEL is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# IPv6: Netfilter Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP6_NF_QUEUE is not set
++# CONFIG_IP6_NF_IPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -174,7 +330,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -193,7 +354,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -205,7 +365,6 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+ 
+@@ -226,6 +385,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ CONFIG_SCSI=m
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -237,6 +397,7 @@ CONFIG_SCSI_PROC_FS=y
+ # 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
+@@ -251,6 +412,7 @@ CONFIG_SCSI_PROC_FS=y
+ # 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=m
+ 
+ #
+ # SCSI low-level drivers
+@@ -266,18 +428,13 @@ CONFIG_SCSI_PROC_FS=y
+ # CONFIG_MEGARAID_NEWGEN is not set
+ # CONFIG_MEGARAID_LEGACY is not set
+ # CONFIG_SCSI_SATA is not set
+-# CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_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_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+ CONFIG_SCSI_QLA2XXX=m
+@@ -286,6 +443,8 @@ CONFIG_SCSI_QLA2XXX=m
+ # CONFIG_SCSI_QLA2300 is not set
+ # CONFIG_SCSI_QLA2322 is not set
+ # CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX 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
+@@ -300,6 +459,8 @@ CONFIG_SCSI_QLA2XXX=m
+ # Fusion MPT device support
+ #
+ # CONFIG_FUSION is not set
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -312,105 +473,13 @@ CONFIG_SCSI_QLA2XXX=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL is not set
+-CONFIG_IP_TCPDIAG=m
+-CONFIG_IP_TCPDIAG_IPV6=y
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-CONFIG_IPV6=m
+-# CONFIG_IPV6_PRIVACY is not set
+-# CONFIG_INET6_AH is not set
+-# CONFIG_INET6_ESP is not set
+-# CONFIG_INET6_IPCOMP is not set
+-# CONFIG_INET6_TUNNEL is not set
+-# CONFIG_IPV6_TUNNEL is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# IP: Netfilter Configuration
+-#
+-# CONFIG_IP_NF_CONNTRACK is not set
+-# CONFIG_IP_NF_CONNTRACK_MARK is not set
+-# CONFIG_IP_NF_QUEUE is not set
+-# CONFIG_IP_NF_IPTABLES is not set
+-# CONFIG_IP_NF_ARPTABLES is not set
+-
+-#
+-# IPv6: Netfilter Configuration
+-#
+-# CONFIG_IP6_NF_QUEUE is not set
+-# CONFIG_IP6_NF_IPTABLES is not set
+-CONFIG_XFRM=y
+-# CONFIG_XFRM_USER 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
++# Network device support
+ #
+-# 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=m
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -418,6 +487,21 @@ CONFIG_TUN=m
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -440,7 +524,6 @@ CONFIG_NET_PCI=y
+ # CONFIG_DGRS is not set
+ # CONFIG_EEPRO100 is not set
+ CONFIG_E100=y
+-# CONFIG_E100_NAPI is not set
+ # CONFIG_FEALNX is not set
+ # CONFIG_NATSEMI is not set
+ # CONFIG_NE2K_PCI is not set
+@@ -463,9 +546,12 @@ CONFIG_E100=y
+ # 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_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=y
+ CONFIG_MV643XX_ETH_1=y
+@@ -474,6 +560,7 @@ CONFIG_MV643XX_ETH_2=y
+ #
+ # Ethernet (10000 Mbit)
+ #
++# CONFIG_CHELSIO_T1 is not set
+ # CONFIG_IXGB is not set
+ # CONFIG_S2IO is not set
+ 
+@@ -486,6 +573,8 @@ CONFIG_MV643XX_ETH_2=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -505,6 +594,8 @@ CONFIG_PPPOE=m
+ # 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
+@@ -531,19 +622,6 @@ CONFIG_INPUT=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-# CONFIG_SERIO_SERPORT is not set
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-# CONFIG_SERIO_RAW is not set
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -553,6 +631,17 @@ CONFIG_SERIO=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_PCIPS2 is not set
++# CONFIG_SERIO_LIBPS2 is not set
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -573,6 +662,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -598,6 +688,11 @@ CONFIG_RTC=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -608,10 +703,20 @@ CONFIG_RTC=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -625,6 +730,11 @@ CONFIG_RTC=y
+ # Graphics support
+ #
+ 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_SOFT_CURSOR is not set
++# CONFIG_FB_MACMODES is not set
+ CONFIG_FB_MODE_HELPERS=y
+ # CONFIG_FB_TILEBLITTING is not set
+ # CONFIG_FB_CIRRUS is not set
+@@ -632,6 +742,7 @@ CONFIG_FB_MODE_HELPERS=y
+ # CONFIG_FB_CYBER2000 is not set
+ # CONFIG_FB_ASILIANT is not set
+ # CONFIG_FB_IMSTT is not set
++# CONFIG_FB_NVIDIA is not set
+ # CONFIG_FB_RIVA is not set
+ # CONFIG_FB_MATROX is not set
+ # CONFIG_FB_RADEON_OLD is not set
+@@ -644,8 +755,11 @@ CONFIG_FB_MODE_HELPERS=y
+ # 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_CYBLA is not set
+ # CONFIG_FB_TRIDENT is not set
+ # CONFIG_FB_E1356 is not set
++# CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+ 
+ #
+@@ -675,13 +789,9 @@ CONFIG_LOGO_LINUX_CLUT224=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -699,10 +809,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+ # 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
+@@ -715,17 +830,21 @@ CONFIG_REISERFS_FS=m
+ # CONFIG_REISERFS_PROC_INFO is not set
+ # CONFIG_REISERFS_FS_XATTR is not set
+ # CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
+ CONFIG_XFS_FS=m
+-# CONFIG_XFS_RT is not set
++CONFIG_XFS_EXPORT=y
+ # 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_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=y
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -746,15 +865,10 @@ CONFIG_AUTOFS4_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-CONFIG_DEVFS_FS=y
+-CONFIG_DEVFS_MOUNT=y
+-# CONFIG_DEVFS_DEBUG is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -778,16 +892,19 @@ CONFIG_CRAMFS=y
+ #
+ 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=y
++# CONFIG_NFSD_V3_ACL is not set
+ # CONFIG_NFSD_V4 is not set
+ # CONFIG_NFSD_TCP is not set
+ 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
+@@ -797,6 +914,7 @@ CONFIG_SMB_FS=m
+ # 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
+@@ -856,7 +974,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE="ip=any root=nfs"
+ 
+@@ -869,7 +989,31 @@ CONFIG_CMDLINE="ip=any root=nfs"
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -879,9 +1023,8 @@ CONFIG_CMDLINE="ip=any root=nfs"
+ # 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_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
+diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
+--- a/arch/mips/configs/ocelot_c_defconfig
++++ b/arch/mips/configs/ocelot_c_defconfig
+@@ -1,11 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:07 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:33 2005
+ #
+ CONFIG_MIPS=y
+-CONFIG_64BIT=y
+-CONFIG_64BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -13,24 +11,29 @@ CONFIG_64BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -40,6 +43,7 @@ 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
+@@ -49,39 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-CONFIG_MOMENCO_OCELOT_C=y
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE is not set
++CONFIG_MOMENCO_OCELOT_C=y
++# 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+ # CONFIG_SGI_IP27 is not set
+ # CONFIG_SGI_IP32 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=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_IRQ_CPU=y
+ CONFIG_IRQ_MV64340=y
+ CONFIG_PCI_MARVELL=y
+@@ -91,8 +124,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -108,6 +143,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ CONFIG_CPU_RM7000=y
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_RM7000=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
+ CONFIG_PAGE_SIZE_4KB=y
+ # CONFIG_PAGE_SIZE_8KB is not set
+ # CONFIG_PAGE_SIZE_16KB is not set
+@@ -115,9 +161,23 @@ CONFIG_PAGE_SIZE_4KB=y
+ CONFIG_BOARD_SCACHE=y
+ CONFIG_RM7000_CPU_SCACHE=y
+ CONFIG_CPU_HAS_PREFETCH=y
++# CONFIG_MIPS_MT is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -126,7 +186,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -135,10 +194,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -156,6 +211,79 @@ CONFIG_MIPS32_N32=y
+ CONFIG_BINFMT_ELF32=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=y
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++CONFIG_IEEE80211_CRYPT_CCMP=y
++CONFIG_IEEE80211_CRYPT_TKIP=y
++
++#
+ # Device Drivers
+ #
+ 
+@@ -164,7 +292,12 @@ CONFIG_BINFMT_ELF32=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=y
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -183,7 +316,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -194,7 +326,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+ # CONFIG_CDROM_PKTCDVD_WCACHE is not set
+@@ -216,6 +347,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -226,6 +358,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -238,77 +371,13 @@ CONFIG_ATA_OVER_ETH=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-# CONFIG_PACKET is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=y
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=y
+-
+-#
+-# 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
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -316,6 +385,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=y
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=y
++CONFIG_DAVICOM_PHY=y
++CONFIG_QSEMI_PHY=y
++CONFIG_LXT_PHY=y
++CONFIG_CICADA_PHY=y
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -341,13 +425,17 @@ CONFIG_NET_ETHERNET=y
+ # 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_SK98LIN is not set
+ # CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
+ # CONFIG_MV643XX_ETH is not set
+ 
+ #
+ # Ethernet (10000 Mbit)
+ #
++# CONFIG_CHELSIO_T1 is not set
+ # CONFIG_IXGB is not set
+ # CONFIG_S2IO is not set
+ 
+@@ -360,6 +448,8 @@ CONFIG_NET_ETHERNET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=y
+ 
+ #
+ # Wan interfaces
+@@ -371,6 +461,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -400,19 +492,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=y
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -422,6 +501,17 @@ CONFIG_SERIO_RAW=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=y
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -442,6 +532,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -468,6 +559,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -478,10 +574,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -501,7 +607,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -511,13 +616,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -535,21 +636,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_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=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -570,12 +679,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -607,6 +714,7 @@ CONFIG_NFSD=y
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=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
+@@ -615,6 +723,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -635,7 +744,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -649,7 +760,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=y
++CONFIG_CRYPTO_TGR192=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=y
++CONFIG_CRYPTO_CAST5=y
++CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_TEA=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_KHAZAD=y
++CONFIG_CRYPTO_ANUBIS=y
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -659,7 +794,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=y
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
+--- a/arch/mips/configs/ocelot_defconfig
++++ b/arch/mips/configs/ocelot_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:08 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:35 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -50,40 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ CONFIG_MOMENCO_OCELOT=y
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=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_IRQ_CPU=y
+ CONFIG_IRQ_CPU_RM7K=y
+ CONFIG_MIPS_GT64120=y
+@@ -96,8 +127,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -113,6 +146,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ CONFIG_CPU_RM7000=y
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_RM7000=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# Kernel type
++#
++CONFIG_32BIT=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
+@@ -120,11 +164,25 @@ CONFIG_PAGE_SIZE_4KB=y
+ CONFIG_BOARD_SCACHE=y
+ CONFIG_RM7000_CPU_SCACHE=y
+ CONFIG_CPU_HAS_PREFETCH=y
++# CONFIG_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -140,10 +198,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -155,6 +209,79 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=y
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++CONFIG_IEEE80211_CRYPT_CCMP=y
++CONFIG_IEEE80211_CRYPT_TKIP=y
++
++#
+ # Device Drivers
+ #
+ 
+@@ -166,6 +293,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_FW_LOADER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=y
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -182,13 +314,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -211,6 +341,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -221,6 +352,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -231,77 +363,28 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
++# Network device support
+ #
+-# CONFIG_PACKET is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=y
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=y
+-
+-#
+-# 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
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
+ 
+ #
+-# QoS and/or fair queueing
++# PHY device support
+ #
+-# CONFIG_NET_SCHED is not set
+-# CONFIG_NET_CLS_ROUTE is not set
++CONFIG_PHYLIB=y
++CONFIG_PHYCONTROL=y
+ 
+ #
+-# Network testing
++# MII PHY device drivers
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
++CONFIG_MARVELL_PHY=y
++CONFIG_DAVICOM_PHY=y
++CONFIG_QSEMI_PHY=y
++CONFIG_LXT_PHY=y
++CONFIG_CICADA_PHY=y
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -334,6 +417,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -363,18 +448,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=y
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -384,6 +457,16 @@ CONFIG_SERIO_RAW=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_RAW=y
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -425,10 +508,13 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -439,10 +525,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -462,7 +558,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -476,10 +571,6 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -492,24 +583,31 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN 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_JBD 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_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=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -530,12 +628,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -567,6 +663,7 @@ CONFIG_NFSD=y
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=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
+@@ -575,6 +672,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -595,7 +693,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -609,7 +709,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=y
++CONFIG_CRYPTO_TGR192=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=y
++CONFIG_CRYPTO_CAST5=y
++CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_TEA=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_KHAZAD=y
++CONFIG_CRYPTO_ANUBIS=y
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -619,7 +743,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=y
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
+--- a/arch/mips/configs/ocelot_g_defconfig
++++ b/arch/mips/configs/ocelot_g_defconfig
+@@ -1,11 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:08 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:38 2005
+ #
+ CONFIG_MIPS=y
+-CONFIG_64BIT=y
+-CONFIG_64BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -13,24 +11,29 @@ CONFIG_64BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -40,6 +43,7 @@ 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
+@@ -49,39 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-CONFIG_MOMENCO_OCELOT_G=y
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_MOMENCO_OCELOT_C is not set
++CONFIG_MOMENCO_OCELOT_G=y
++# CONFIG_MIPS_XXS1500 is not set
++# CONFIG_PNX8550_V2PCI is not set
++# CONFIG_PNX8550_JBS is not set
+ # CONFIG_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+ # CONFIG_SGI_IP27 is not set
+ # CONFIG_SGI_IP32 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=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_IRQ_CPU=y
+ CONFIG_IRQ_CPU_RM7K=y
+ CONFIG_PCI_MARVELL=y
+@@ -94,8 +127,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -111,6 +146,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ CONFIG_CPU_RM7000=y
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_RM7000=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
+ CONFIG_PAGE_SIZE_4KB=y
+ # CONFIG_PAGE_SIZE_8KB is not set
+ # CONFIG_PAGE_SIZE_16KB is not set
+@@ -118,9 +164,23 @@ CONFIG_PAGE_SIZE_4KB=y
+ CONFIG_BOARD_SCACHE=y
+ CONFIG_RM7000_CPU_SCACHE=y
+ CONFIG_CPU_HAS_PREFETCH=y
++# CONFIG_MIPS_MT is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -129,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -138,10 +197,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -159,6 +214,79 @@ CONFIG_MIPS32_N32=y
+ CONFIG_BINFMT_ELF32=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=y
++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 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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++CONFIG_IEEE80211_CRYPT_CCMP=y
++CONFIG_IEEE80211_CRYPT_TKIP=y
++
++#
+ # Device Drivers
+ #
+ 
+@@ -167,7 +295,12 @@ CONFIG_BINFMT_ELF32=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=y
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -186,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -197,7 +329,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+ # CONFIG_CDROM_PKTCDVD_WCACHE is not set
+@@ -219,6 +350,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -229,6 +361,7 @@ CONFIG_ATA_OVER_ETH=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -241,77 +374,13 @@ CONFIG_ATA_OVER_ETH=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-# CONFIG_PACKET is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=y
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=y
+-
+-#
+-# 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
++# Network device support
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -319,6 +388,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=y
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=y
++CONFIG_DAVICOM_PHY=y
++CONFIG_QSEMI_PHY=y
++CONFIG_LXT_PHY=y
++CONFIG_CICADA_PHY=y
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -345,12 +429,16 @@ CONFIG_GALILEO_64240_ETH=y
+ # 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_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
+ 
+@@ -363,6 +451,8 @@ CONFIG_GALILEO_64240_ETH=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=y
+ 
+ #
+ # Wan interfaces
+@@ -374,6 +464,8 @@ CONFIG_GALILEO_64240_ETH=y
+ # 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
+@@ -403,19 +495,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=y
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -425,6 +504,17 @@ CONFIG_SERIO_RAW=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=y
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -445,6 +535,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -471,6 +562,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -481,10 +577,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -504,7 +610,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -514,13 +619,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -538,21 +639,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_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=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -573,12 +682,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -610,6 +717,7 @@ CONFIG_NFSD=y
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=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
+@@ -618,6 +726,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -638,7 +747,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -652,7 +763,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=y
++CONFIG_CRYPTO_TGR192=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=y
++CONFIG_CRYPTO_CAST5=y
++CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_TEA=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_KHAZAD=y
++CONFIG_CRYPTO_ANUBIS=y
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -662,7 +797,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=y
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
+--- a/arch/mips/configs/pb1100_defconfig
++++ b/arch/mips/configs/pb1100_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:08 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:41 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,56 +59,70 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# CONFIG_MIPS_MTX1 is not set
++# CONFIG_MIPS_BOSPORUS is not set
++# CONFIG_MIPS_PB1000 is not set
++CONFIG_MIPS_PB1100=y
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-CONFIG_SOC_AU1X00=y
+-# CONFIG_SOC_AU1000 is not set
+-CONFIG_SOC_AU1100=y
+-# CONFIG_SOC_AU1500 is not set
+-# CONFIG_SOC_AU1550 is not set
+-# CONFIG_MIPS_PB1000 is not set
+-CONFIG_MIPS_PB1100=y
+-# CONFIG_MIPS_PB1500 is not set
+-# CONFIG_MIPS_PB1550 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_BOSPORUS is not set
+-# CONFIG_MIPS_MIRAGE is not set
+-# CONFIG_MIPS_XXS1500 is not set
+-# CONFIG_MIPS_MTX1 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SOC_AU1100=y
++CONFIG_SOC_AU1X00=y
+ CONFIG_SWAP_IO_SPACE=y
+ # CONFIG_AU1X00_USB_DEVICE is not set
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -113,8 +130,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -130,15 +149,39 @@ CONFIG_CPU_MIPS32=y
+ # 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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_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_64BIT_PHYS_ADDR is not set
++# CONFIG_MIPS_MT is not set
++CONFIG_64BIT_PHYS_ADDR=y
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -154,6 +197,8 @@ CONFIG_MMU=y
+ CONFIG_PCCARD=m
+ # CONFIG_PCMCIA_DEBUG is not set
+ CONFIG_PCMCIA=m
++CONFIG_PCMCIA_LOAD_CIS=y
++CONFIG_PCMCIA_IOCTL=y
+ 
+ #
+ # PC-card bridges
+@@ -171,6 +216,100 @@ CONFIG_PCMCIA=m
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ CONFIG_TRAD_SIGNALS=y
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++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 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 is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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 is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ 
+ #
+ # Device Drivers
+@@ -181,15 +320,20 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+ #
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+-CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+ # CONFIG_MTD_CMDLINE_PARTS is not set
+ 
+@@ -233,9 +377,8 @@ CONFIG_MTD_CFI_UTIL=y
+ #
+ # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+ # CONFIG_MTD_PHYSMAP is not set
+-CONFIG_MTD_PB1100=y
+-CONFIG_MTD_PB1500_BOOT=y
+-CONFIG_MTD_PB1500_USER=y
++CONFIG_MTD_ALCHEMY=y
++# CONFIG_MTD_PLATRAM is not set
+ 
+ #
+ # Self-contained MTD device drivers
+@@ -270,14 +413,12 @@ CONFIG_MTD_PB1500_USER=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -300,6 +441,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -310,6 +452,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -320,94 +463,28 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# IP: Netfilter Configuration
+-#
+-# CONFIG_IP_NF_CONNTRACK is not set
+-CONFIG_IP_NF_CONNTRACK_MARK=y
+-# CONFIG_IP_NF_QUEUE is not set
+-# CONFIG_IP_NF_IPTABLES is not set
+-# CONFIG_IP_NF_ARPTABLES is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
++# Network device support
+ #
+-# 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
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
+ 
+ #
+-# QoS and/or fair queueing
++# PHY device support
+ #
+-# CONFIG_NET_SCHED is not set
+-# CONFIG_NET_CLS_ROUTE is not set
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
+ 
+ #
+-# Network testing
++# MII PHY device drivers
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -453,6 +530,8 @@ 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
+@@ -482,18 +561,6 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -503,6 +570,16 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -534,14 +611,14 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Watchdog Cards
+ #
+ # CONFIG_WATCHDOG is not set
+-CONFIG_RTC=y
++# CONFIG_RTC is not set
++# CONFIG_GEN_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
+ 
+ #
+ # PCMCIA character devices
+@@ -550,6 +627,10 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -560,10 +641,20 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -583,7 +674,6 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -593,12 +683,9 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB_ARCH_HAS_HCD is not set
+-# CONFIG_USB_ARCH_HAS_OHCI 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_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -613,7 +700,10 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN Devices
++#
+ 
+ #
+ # File systems
+@@ -622,6 +712,7 @@ CONFIG_EXT2_FS=y
+ CONFIG_EXT2_FS_XATTR=y
+ CONFIG_EXT2_FS_POSIX_ACL=y
+ # 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=y
+@@ -640,10 +731,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -664,13 +757,10 @@ CONFIG_AUTOFS4_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -704,6 +794,7 @@ CONFIG_NFSD=m
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -713,6 +804,7 @@ CONFIG_SMB_FS=m
+ # 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
+@@ -772,7 +864,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -788,26 +882,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-# 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=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
+-# CONFIG_CRYPTO_DES is not set
+-# CONFIG_CRYPTO_BLOWFISH is not set
+-CONFIG_CRYPTO_TWOFISH=y
+-# CONFIG_CRYPTO_SERPENT is not set
++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 is not set
+-# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+ # CONFIG_CRYPTO_TEST is not set
+ 
+@@ -819,9 +914,8 @@ CONFIG_CRYPTO_CRC32C=m
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
+--- a/arch/mips/configs/pb1500_defconfig
++++ b/arch/mips/configs/pb1500_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:09 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:44 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,63 +59,80 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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=y
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-CONFIG_SOC_AU1X00=y
+-# CONFIG_SOC_AU1000 is not set
+-# CONFIG_SOC_AU1100 is not set
+-CONFIG_SOC_AU1500=y
+-# CONFIG_SOC_AU1550 is not set
+-# CONFIG_MIPS_PB1000 is not set
+-# CONFIG_MIPS_PB1100 is not set
+-CONFIG_MIPS_PB1500=y
+-# CONFIG_MIPS_PB1550 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_BOSPORUS is not set
+-# CONFIG_MIPS_MIRAGE is not set
+-# CONFIG_MIPS_XXS1500 is not set
+-# CONFIG_MIPS_MTX1 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+-CONFIG_DMA_COHERENT=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SOC_AU1500=y
++CONFIG_SOC_AU1X00=y
+ # CONFIG_AU1X00_USB_DEVICE is not set
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -128,15 +148,39 @@ CONFIG_CPU_MIPS32=y
+ # 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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_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 is not set
+ CONFIG_64BIT_PHYS_ADDR=y
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -145,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -154,6 +197,8 @@ CONFIG_MMU=y
+ CONFIG_PCCARD=m
+ # CONFIG_PCMCIA_DEBUG is not set
+ CONFIG_PCMCIA=m
++CONFIG_PCMCIA_LOAD_CIS=y
++CONFIG_PCMCIA_IOCTL=y
+ CONFIG_CARDBUS=y
+ 
+ #
+@@ -177,6 +222,100 @@ CONFIG_PCCARD_NONSTATIC=m
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ CONFIG_TRAD_SIGNALS=y
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++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 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 is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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 is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ 
+ #
+ # Device Drivers
+@@ -187,12 +326,87 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+ #
+-# CONFIG_MTD is not set
++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
++
++#
++# 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_AMDSTD_RETRY=0
++# 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_ALCHEMY=y
++# 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_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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
+ 
+ #
+ # Parallel port support
+@@ -206,7 +420,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -218,7 +431,6 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -275,6 +487,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
+ CONFIG_BLK_DEV_HPT366=y
+ # 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
+@@ -292,6 +505,7 @@ CONFIG_BLK_DEV_IDEDMA=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -302,6 +516,7 @@ CONFIG_BLK_DEV_IDEDMA=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -314,94 +529,13 @@ CONFIG_BLK_DEV_IDEDMA=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# IP: Netfilter Configuration
++# Network device support
+ #
+-# CONFIG_IP_NF_CONNTRACK is not set
+-CONFIG_IP_NF_CONNTRACK_MARK=y
+-# CONFIG_IP_NF_QUEUE is not set
+-# CONFIG_IP_NF_IPTABLES is not set
+-# CONFIG_IP_NF_ARPTABLES is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -409,6 +543,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -435,12 +584,16 @@ CONFIG_MIPS_AU1X00_ENET=y
+ # 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_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
+ 
+@@ -453,6 +606,8 @@ CONFIG_MIPS_AU1X00_ENET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # PCMCIA network device support
+@@ -484,6 +639,8 @@ 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
+@@ -513,19 +670,6 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -535,6 +679,17 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ # CONFIG_VT is not set
+@@ -554,6 +709,7 @@ CONFIG_SERIAL_AU1X00=y
+ CONFIG_SERIAL_AU1X00_CONSOLE=y
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -585,6 +741,11 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -595,10 +756,20 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -612,7 +783,6 @@ CONFIG_SYNCLINK_CS=m
+ # Graphics support
+ #
+ # CONFIG_FB is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -622,13 +792,9 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -646,12 +812,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+ CONFIG_EXT2_FS_XATTR=y
+ CONFIG_EXT2_FS_POSIX_ACL=y
+ # 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=y
+@@ -670,10 +841,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -694,13 +867,10 @@ CONFIG_AUTOFS4_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -712,6 +882,8 @@ CONFIG_RAMFS=y
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
+ CONFIG_CRAMFS=m
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+@@ -732,6 +904,7 @@ CONFIG_NFSD=m
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -741,6 +914,7 @@ CONFIG_SMB_FS=m
+ # 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
+@@ -800,7 +974,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -816,27 +992,28 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-# 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=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
+-# CONFIG_CRYPTO_DES is not set
+-# CONFIG_CRYPTO_BLOWFISH is not set
+-CONFIG_CRYPTO_TWOFISH=y
+-# CONFIG_CRYPTO_SERPENT is not set
++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 is not set
+-# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
+-# CONFIG_CRYPTO_CRC32C is not set
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
++CONFIG_CRYPTO_CRC32C=m
+ # CONFIG_CRYPTO_TEST is not set
+ 
+ #
+@@ -847,9 +1024,8 @@ CONFIG_CRYPTO_MICHAEL_MIC=y
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_LIBCRC32C=m
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
+--- a/arch/mips/configs/pb1550_defconfig
++++ b/arch/mips/configs/pb1550_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:09 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:47 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,63 +59,80 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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=y
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-CONFIG_SOC_AU1X00=y
+-# CONFIG_SOC_AU1000 is not set
+-# CONFIG_SOC_AU1100 is not set
+-# CONFIG_SOC_AU1500 is not set
+-CONFIG_SOC_AU1550=y
+-# CONFIG_MIPS_PB1000 is not set
+-# CONFIG_MIPS_PB1100 is not set
+-# CONFIG_MIPS_PB1500 is not set
+-CONFIG_MIPS_PB1550=y
+-# 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_BOSPORUS is not set
+-# CONFIG_MIPS_MIRAGE is not set
+-# CONFIG_MIPS_XXS1500 is not set
+-# CONFIG_MIPS_MTX1 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+-CONFIG_DMA_COHERENT=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SOC_AU1550=y
++CONFIG_SOC_AU1X00=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -128,15 +148,39 @@ CONFIG_CPU_MIPS32=y
+ # 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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_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 is not set
+ CONFIG_64BIT_PHYS_ADDR=y
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -145,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -154,6 +197,8 @@ CONFIG_MMU=y
+ CONFIG_PCCARD=m
+ # CONFIG_PCMCIA_DEBUG is not set
+ CONFIG_PCMCIA=m
++CONFIG_PCMCIA_LOAD_CIS=y
++CONFIG_PCMCIA_IOCTL=y
+ CONFIG_CARDBUS=y
+ 
+ #
+@@ -177,6 +222,100 @@ CONFIG_PCCARD_NONSTATIC=m
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ CONFIG_TRAD_SIGNALS=y
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++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 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 is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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 is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ 
+ #
+ # Device Drivers
+@@ -187,12 +326,87 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+ #
+-# CONFIG_MTD is not set
++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
++
++#
++# 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_AMDSTD_RETRY=0
++# 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_ALCHEMY=y
++# 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_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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
+ 
+ #
+ # Parallel port support
+@@ -206,7 +420,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -218,7 +431,6 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -275,6 +487,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
+ CONFIG_BLK_DEV_HPT366=y
+ # 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
+@@ -292,6 +505,7 @@ CONFIG_BLK_DEV_IDEDMA=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -302,6 +516,7 @@ CONFIG_BLK_DEV_IDEDMA=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -314,94 +529,13 @@ CONFIG_BLK_DEV_IDEDMA=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-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=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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# IP: Netfilter Configuration
++# Network device support
+ #
+-# CONFIG_IP_NF_CONNTRACK is not set
+-CONFIG_IP_NF_CONNTRACK_MARK=y
+-# CONFIG_IP_NF_QUEUE is not set
+-# CONFIG_IP_NF_IPTABLES is not set
+-# CONFIG_IP_NF_ARPTABLES is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -409,6 +543,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -435,12 +584,16 @@ CONFIG_MIPS_AU1X00_ENET=y
+ # 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_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
+ 
+@@ -453,6 +606,8 @@ CONFIG_MIPS_AU1X00_ENET=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # PCMCIA network device support
+@@ -476,6 +631,8 @@ 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
+@@ -505,19 +662,6 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -527,6 +671,17 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# 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 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ # CONFIG_VT is not set
+@@ -546,6 +701,7 @@ CONFIG_SERIAL_AU1X00=y
+ CONFIG_SERIAL_AU1X00_CONSOLE=y
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -577,6 +733,11 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -587,10 +748,20 @@ CONFIG_SYNCLINK_CS=m
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -604,7 +775,6 @@ CONFIG_SYNCLINK_CS=m
+ # Graphics support
+ #
+ # CONFIG_FB is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -614,13 +784,9 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -638,12 +804,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+ CONFIG_EXT2_FS_XATTR=y
+ CONFIG_EXT2_FS_POSIX_ACL=y
+ # 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=y
+@@ -662,10 +833,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -686,13 +859,10 @@ CONFIG_AUTOFS4_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -704,6 +874,8 @@ CONFIG_RAMFS=y
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
+ CONFIG_CRAMFS=m
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+@@ -724,6 +896,7 @@ CONFIG_NFSD=m
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -733,6 +906,7 @@ CONFIG_SMB_FS=m
+ # 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
+@@ -792,7 +966,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -808,26 +984,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-# 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=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
+-# CONFIG_CRYPTO_DES is not set
+-# CONFIG_CRYPTO_BLOWFISH is not set
+-CONFIG_CRYPTO_TWOFISH=y
+-# CONFIG_CRYPTO_SERPENT is not set
++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 is not set
+-# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+ # CONFIG_CRYPTO_TEST is not set
+ 
+@@ -839,9 +1016,8 @@ CONFIG_CRYPTO_CRC32C=m
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/configs/pnx8550-jbs_defconfig
+@@ -0,0 +1,1069 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:50 2005
++#
++CONFIG_MIPS=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_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_HOTPLUG is not set
++CONFIG_KOBJECT_UEVENT=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_EMBEDDED=y
++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 is not set
++CONFIG_SHMEM=y
++CONFIG_CC_ALIGN_FUNCTIONS=0
++CONFIG_CC_ALIGN_LABELS=0
++CONFIG_CC_ALIGN_LOOPS=0
++CONFIG_CC_ALIGN_JUMPS=0
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++
++#
++# 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_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_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=y
++# CONFIG_DDB5074 is not set
++# CONFIG_DDB5476 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_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_CALIBRATE_DELAY=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_PNX8550=y
++CONFIG_SOC_PNX8550=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=y
++# 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_R4X00=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 is not set
++# CONFIG_64BIT_PHYS_ADDR is not set
++# CONFIG_CPU_ADVANCED is not set
++CONFIG_CPU_HAS_LLSC=y
++CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_PCI=y
++CONFIG_PCI=y
++# CONFIG_PCI_LEGACY_PROC is not set
++# CONFIG_PCI_DEBUG is not set
++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_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
++# 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=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=8192
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_LBD is not set
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++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=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++CONFIG_BLK_DEV_IDESCSI=y
++# 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=y
++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 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=y
++# 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 is not set
++# 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=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=y
++# 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_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_SCSI_SATA 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_FC is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++CONFIG_SCSI_QLA2XXX=y
++# CONFIG_SCSI_QLA21XX is not set
++# CONFIG_SCSI_QLA22XX is not set
++# CONFIG_SCSI_QLA2300 is not set
++# CONFIG_SCSI_QLA2322 is not set
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX 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
++
++#
++# 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 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_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 is not set
++# 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=y
++CONFIG_8139TOO_8129=y
++# 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
++# 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_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
++
++#
++# 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=y
++# CONFIG_SERIO_I8042 is not set
++# CONFIG_SERIO_SERPORT is not set
++# 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_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_IP3106 is not set
++# 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_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
++
++#
++# I2C support
++#
++# CONFIG_I2C 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_HWMON_DEBUG_CHIP is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++
++#
++# 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 is not set
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_UHCI_HCD is not set
++# 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 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
++
++#
++# 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_YEALINK is not set
++# CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE 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 Multimedia devices
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# 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_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
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN 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_JBD 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_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=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=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_PROC_KCORE is not set
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_RELAYFS_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=m
++# CONFIG_NFSD_V3 is not set
++# CONFIG_NFSD_TCP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 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
++
++#
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_SCHEDSTATS is not set
++CONFIG_DEBUG_SLAB=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_FS is not set
++CONFIG_CROSSCOMPILE=y
++CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_KGDB is not set
++# CONFIG_RUNTIME_DEBUG is not set
++# CONFIG_MIPS_UNCACHED 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=m
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++# CONFIG_LIBCRC32C is not set
+diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/configs/pnx8550-v2pci_defconfig
+@@ -0,0 +1,1251 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:53 2005
++#
++CONFIG_MIPS=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_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_HOTPLUG is not set
++CONFIG_KOBJECT_UEVENT=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
++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 is not set
++CONFIG_SHMEM=y
++CONFIG_CC_ALIGN_FUNCTIONS=0
++CONFIG_CC_ALIGN_LABELS=0
++CONFIG_CC_ALIGN_LOOPS=0
++CONFIG_CC_ALIGN_JUMPS=0
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++
++#
++# 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_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_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=y
++# CONFIG_PNX8550_JBS is not set
++# CONFIG_DDB5074 is not set
++# CONFIG_DDB5476 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_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_CALIBRATE_DELAY=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_PNX8550=y
++CONFIG_SOC_PNX8550=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=y
++# 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_R4X00=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 is not set
++# CONFIG_64BIT_PHYS_ADDR is not set
++CONFIG_CPU_ADVANCED=y
++CONFIG_CPU_HAS_LLSC=y
++# CONFIG_CPU_HAS_LLDSCD is not set
++# CONFIG_CPU_HAS_WB is not set
++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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_PCI=y
++CONFIG_PCI=y
++# CONFIG_PCI_LEGACY_PROC is not set
++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_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++# CONFIG_IP_PNP_BOOTP 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_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_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_IPV6_TUNNEL is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_NETFILTER_NETLINK is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# IPv6: Netfilter Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP6_NF_QUEUE is not set
++# CONFIG_IP6_NF_IPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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 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=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=8192
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_LBD is not set
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++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 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_BLK_DEV_IDEPCI=y
++CONFIG_IDEPCI_SHARE_IRQ=y
++# CONFIG_BLK_DEV_OFFBOARD is not set
++# CONFIG_BLK_DEV_GENERIC is not set
++# 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 is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++# CONFIG_BLK_DEV_AMD74XX is not set
++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 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 is not set
++# 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 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=m
++# 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_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=m
++CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
++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 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_SCSI_SATA 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_FC is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++CONFIG_SCSI_QLA2XXX=y
++# CONFIG_SCSI_QLA21XX is not set
++# CONFIG_SCSI_QLA22XX is not set
++# CONFIG_SCSI_QLA2300 is not set
++# CONFIG_SCSI_QLA2322 is not set
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX 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
++
++#
++# 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_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 is not set
++# CONFIG_FEALNX is not set
++CONFIG_NATSEMI=y
++# 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
++# 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_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
++
++#
++# 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_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=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=m
++# 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_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 is not set
++CONFIG_HW_CONSOLE=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_COMPUTONE is not set
++# CONFIG_ROCKETPORT is not set
++# CONFIG_CYCLADES 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 is not set
++# CONFIG_N_HDLC is not set
++# 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 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_IP3106 is not set
++# 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_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
++
++#
++# I2C support
++#
++CONFIG_I2C=m
++CONFIG_I2C_CHARDEV=m
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=m
++# 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_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++# CONFIG_SCx200_ACB 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_RTC8564 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
++
++#
++# 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_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_SMSC47B397 is not set
++# CONFIG_SENSORS_VIA686A 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
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++
++#
++# Graphics support
++#
++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_SOFT_CURSOR is not set
++# CONFIG_FB_MACMODES 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_NVIDIA is not set
++# CONFIG_FB_RIVA is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_RADEON_OLD 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_CYBLA is not set
++# CONFIG_FB_TRIDENT is not set
++# CONFIG_FB_E1356 is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE is not set
++
++#
++# Logo configuration
++#
++# CONFIG_LOGO is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=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 is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_UHCI_HCD is not set
++# 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 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_ONETOUCH is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++CONFIG_USB_HIDINPUT=y
++# CONFIG_HID_FF is not set
++CONFIG_USB_HIDDEV=y
++# 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_YEALINK is not set
++# CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE 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 Multimedia devices
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# 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_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 is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN 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=m
++CONFIG_XFS_EXPORT=y
++# 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_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=y
++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=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_PROC_KCORE is not set
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_RELAYFS_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=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 is not set
++# CONFIG_NFS_DIRECTIO is not set
++CONFIG_NFSD=m
++# CONFIG_NFSD_V3 is not set
++# CONFIG_NFSD_TCP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++CONFIG_SMB_FS=m
++# CONFIG_SMB_NLS_DEFAULT is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 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
++
++#
++# 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_CROSSCOMPILE=y
++CONFIG_CMDLINE=""
++
++#
++# 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=m
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
+--- a/arch/mips/configs/qemu_defconfig
++++ b/arch/mips/configs/qemu_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.13-rc6
+-# Mon Aug  8 11:49:54 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:56 2005
+ #
+ CONFIG_MIPS=y
+ 
+@@ -17,6 +17,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
+ # General setup
+ #
+ CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
+ # CONFIG_SWAP is not set
+ # CONFIG_SYSVIPC is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+@@ -25,6 +26,7 @@ CONFIG_LOCALVERSION=""
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_EMBEDDED=y
+ CONFIG_KALLSYMS=y
+ # CONFIG_KALLSYMS_EXTRA_PASS is not set
+@@ -74,6 +76,7 @@ CONFIG_BASE_SMALL=1
+ # CONFIG_MIPS_ATLAS is not set
+ # CONFIG_MIPS_MALTA is not set
+ # CONFIG_MIPS_SEAD 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
+@@ -91,6 +94,7 @@ CONFIG_QEMU=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
+@@ -105,7 +109,6 @@ CONFIG_QEMU=y
+ # CONFIG_TOSHIBA_RBTX4938 is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_COHERENT=y
+ CONFIG_GENERIC_ISA_DMA=y
+ CONFIG_I8259=y
+@@ -119,7 +122,7 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32_R1 is not set
++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
+@@ -127,7 +130,7 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+ # CONFIG_CPU_TX39XX is not set
+ # CONFIG_CPU_VR41XX is not set
+ # CONFIG_CPU_R4300 is not set
+-CONFIG_CPU_R4X00=y
++# CONFIG_CPU_R4X00 is not set
+ # CONFIG_CPU_TX49XX is not set
+ # CONFIG_CPU_R5000 is not set
+ # CONFIG_CPU_R5432 is not set
+@@ -138,9 +141,11 @@ CONFIG_CPU_R4X00=y
+ # 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_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
+ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+ CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+ 
+ #
+ # Kernel type
+@@ -151,15 +156,18 @@ 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 is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+-CONFIG_CPU_HAS_LLDSCD=y
+ CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
+ CONFIG_ARCH_FLATMEM_ENABLE=y
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ CONFIG_PREEMPT_NONE=y
+ # CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+@@ -214,8 +222,8 @@ CONFIG_IP_PNP_BOOTP=y
+ # 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_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
+@@ -232,9 +240,15 @@ CONFIG_TCP_CONG_BIC=y
+ #
+ # 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=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++CONFIG_IEEE80211_CRYPT_CCMP=y
++CONFIG_IEEE80211_CRYPT_TKIP=y
+ 
+ #
+ # Device Drivers
+@@ -248,6 +262,11 @@ CONFIG_STANDALONE=y
+ # CONFIG_FW_LOADER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=y
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -265,13 +284,12 @@ CONFIG_STANDALONE=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_LBD is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+@@ -291,6 +309,7 @@ CONFIG_IOSCHED_NOOP=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -331,6 +350,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=y
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=y
++CONFIG_DAVICOM_PHY=y
++CONFIG_QSEMI_PHY=y
++CONFIG_LXT_PHY=y
++CONFIG_CICADA_PHY=y
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -470,7 +504,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+-# CONFIG_I2C_SENSOR is not set
+ 
+ #
+ # Dallas's 1-wire bus
+@@ -481,12 +514,17 @@ CONFIG_SERIAL_CORE_CONSOLE=y
+ # Hardware Monitoring support
+ #
+ # CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
+ 
+ #
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -532,7 +570,6 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
+ 
+ #
+ # SN Devices
+@@ -547,10 +584,6 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_JFS_FS is not set
+ # CONFIG_FS_POSIX_ACL is not set
+-
+-#
+-# XFS support
+-#
+ # CONFIG_XFS_FS is not set
+ # CONFIG_MINIX_FS is not set
+ # CONFIG_ROMFS_FS is not set
+@@ -559,6 +592,7 @@ CONFIG_INOTIFY=y
+ # CONFIG_DNOTIFY is not set
+ # CONFIG_AUTOFS_FS is not set
+ # CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -576,11 +610,13 @@ CONFIG_INOTIFY=y
+ #
+ # Pseudo filesystems
+ #
+-# CONFIG_PROC_FS is not set
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
+ # CONFIG_SYSFS is not set
+ # CONFIG_TMPFS is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -634,12 +670,35 @@ CONFIG_CMDLINE="console=ttyS0 debug ip=1
+ # Security options
+ #
+ # CONFIG_KEYS is not set
+-# CONFIG_SECURITY is not set
+ 
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=y
++CONFIG_CRYPTO_MD4=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++CONFIG_CRYPTO_SHA256=y
++CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_WP512=y
++CONFIG_CRYPTO_TGR192=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_BLOWFISH=y
++CONFIG_CRYPTO_TWOFISH=y
++CONFIG_CRYPTO_SERPENT=y
++CONFIG_CRYPTO_AES=y
++CONFIG_CRYPTO_CAST5=y
++CONFIG_CRYPTO_CAST6=y
++CONFIG_CRYPTO_TEA=y
++CONFIG_CRYPTO_ARC4=y
++CONFIG_CRYPTO_KHAZAD=y
++CONFIG_CRYPTO_ANUBIS=y
++CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_MICHAEL_MIC=y
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -649,7 +708,8 @@ CONFIG_CMDLINE="console=ttyS0 debug ip=1
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
+ CONFIG_CRC32=y
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_LIBCRC32C=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/configs/rbhma4500_defconfig
+@@ -0,0 +1,1259 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:26:59 2005
++#
++CONFIG_MIPS=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_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_HOTPLUG=y
++# CONFIG_KOBJECT_UEVENT is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
++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 is not set
++# CONFIG_EPOLL is not set
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SHMEM=y
++CONFIG_CC_ALIGN_FUNCTIONS=0
++CONFIG_CC_ALIGN_LABELS=0
++CONFIG_CC_ALIGN_LOOPS=0
++CONFIG_CC_ALIGN_JUMPS=0
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++
++#
++# 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_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_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_DDB5074 is not set
++# CONFIG_DDB5476 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_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=y
++
++#
++# Multiplex Pin Select
++#
++CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61=y
++# CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND is not set
++# CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA is not set
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++CONFIG_GENERIC_ISA_DMA=y
++CONFIG_I8259=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_SWAP_IO_SPACE=y
++CONFIG_MIPS_L1_CACHE_SHIFT=5
++CONFIG_HAVE_STD_PC_SERIAL_PORT=y
++CONFIG_TOSHIBA_BOARDS=y
++
++#
++# 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=y
++# 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_TX49XX=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 is not set
++CONFIG_CPU_ADVANCED=y
++CONFIG_CPU_HAS_LLSC=y
++CONFIG_CPU_HAS_LLDSCD=y
++CONFIG_CPU_HAS_WB=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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_PCI=y
++CONFIG_PCI=y
++# CONFIG_PCI_LEGACY_PROC is not set
++CONFIG_ISA=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_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 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 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_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_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_IPV6_TUNNEL is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++CONFIG_IP_NF_PPTP=m
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# IPv6: Netfilter Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP6_NF_QUEUE is not set
++# CONFIG_IP6_NF_IPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
++
++#
++# 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
++
++#
++# 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=y
++CONFIG_MTD_CFI_AMDSTD_RETRY=0
++# 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
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP 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_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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# 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=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=m
++# 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=8192
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_LBD is not set
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++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=y
++# 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 is not set
++# 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 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 is not set
++# CONFIG_IDE_ARM is not set
++# CONFIG_IDE_CHIPSETS is not set
++CONFIG_BLK_DEV_IDEDMA=y
++# CONFIG_IDEDMA_IVB is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++CONFIG_RAID_ATTRS=m
++# CONFIG_SCSI 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
++
++#
++# 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=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++
++#
++# Tulip family network device support
++#
++# CONFIG_NET_TULIP is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++CONFIG_NET_ISA=y
++# CONFIG_E2100 is not set
++# CONFIG_EWRK3 is not set
++# 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=y
++# CONFIG_SEEQ8005 is not set
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++# CONFIG_AMD8111_ETH is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_AC3200 is not set
++# CONFIG_APRICOT is not set
++# CONFIG_B44 is not set
++# CONFIG_FORCEDETH is not set
++# CONFIG_CS89x0 is not set
++# CONFIG_DGRS is not set
++# CONFIG_EEPRO100 is not set
++# CONFIG_E100 is not set
++# 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
++# CONFIG_NET_POCKET 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_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
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++
++#
++# Obsolete Wireless cards support (pre-802.11)
++#
++# CONFIG_STRIP is not set
++# CONFIG_ARLAN is not set
++# CONFIG_WAVELAN is not set
++
++#
++# Wireless 802.11b ISA/PCI cards support
++#
++# CONFIG_IPW2100 is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
++# CONFIG_AIRO is not set
++# CONFIG_HERMES is not set
++# CONFIG_ATMEL is not set
++
++#
++# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
++#
++# CONFIG_PRISM54 is not set
++# CONFIG_HOSTAP is not set
++CONFIG_NET_WIRELESS=y
++
++#
++# 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 is not set
++CONFIG_PPP_ASYNC=m
++CONFIG_PPP_SYNC_TTY=m
++CONFIG_PPP_DEFLATE=m
++# CONFIG_PPP_BSDCOMP 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
++
++#
++# 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 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_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_HAS_TXX9_SERIAL=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_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
++
++#
++# I2C support
++#
++# CONFIG_I2C 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_HWMON_DEBUG_CHIP is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# 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_SOFT_CURSOR=y
++# CONFIG_FB_MACMODES 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_NVIDIA is not set
++# CONFIG_FB_RIVA is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_RADEON_OLD is not set
++# CONFIG_FB_RADEON 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_XL_INIT is not set
++# CONFIG_FB_ATY_GX 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_CYBLA is not set
++# CONFIG_FB_TRIDENT is not set
++# CONFIG_FB_E1356 is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++
++#
++# Console display driver support
++#
++CONFIG_VGA_CONSOLE=y
++# CONFIG_MDA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE is not set
++
++#
++# Logo configuration
++#
++# CONFIG_LOGO is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_UHCI_HCD is not set
++# 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 is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++CONFIG_USB_HIDINPUT=y
++# CONFIG_HID_FF is not set
++CONFIG_USB_HIDDEV=y
++# 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_YEALINK=m
++# CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE 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 Multimedia devices
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# 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
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN Devices
++#
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# 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=y
++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 is not set
++CONFIG_XFS_FS=m
++CONFIG_XFS_EXPORT=y
++# 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_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++# CONFIG_QUOTA is not set
++# CONFIG_DNOTIFY is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
++
++#
++# 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=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++# CONFIG_PROC_KCORE is not set
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
++
++#
++# 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_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++CONFIG_NFSD=m
++# CONFIG_NFSD_V3 is not set
++# CONFIG_NFSD_TCP is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++CONFIG_SMB_FS=m
++# CONFIG_SMB_NLS_DEFAULT is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 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
++
++#
++# 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_CROSSCOMPILE=y
++CONFIG_CMDLINE=""
++
++#
++# 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=m
++CONFIG_CRYPTO_SHA1=m
++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
++
++#
++# 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=y
+diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
+--- a/arch/mips/configs/rm200_defconfig
++++ b/arch/mips/configs/rm200_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:09 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:27:03 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,11 +11,13 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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=y
+@@ -26,14 +25,17 @@ CONFIG_BSD_PROCESS_ACCT=y
+ # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -43,6 +45,7 @@ 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
+@@ -58,43 +61,73 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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=y
++# 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_ARC=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
+ CONFIG_GENERIC_ISA_DMA=y
+ CONFIG_I8259=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_ARC32=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -106,8 +139,10 @@ CONFIG_ARC_PROMLIB=y
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -123,24 +158,49 @@ CONFIG_CPU_R4X00=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R4X00=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_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=y
+ CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_SYS_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_PREEMPT_NONE is not set
++CONFIG_PREEMPT_VOLUNTARY=y
+ # CONFIG_PREEMPT is not set
+ 
+ #
+ # Bus options (PCI, PCMCIA, EISA, ISA, TC)
+ #
++CONFIG_HW_HAS_EISA=y
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-# CONFIG_PCI_NAMES is not set
+ CONFIG_ISA=y
+ # CONFIG_EISA is not set
+ CONFIG_MMU=y
+@@ -151,11 +211,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-CONFIG_PCMCIA_PROBE=y
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -168,6 +223,281 @@ CONFIG_BINFMT_MISC=m
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=m
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++CONFIG_NET_KEY=m
++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=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 is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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=y
++CONFIG_INET6_AH=m
++CONFIG_INET6_ESP=m
++CONFIG_INET6_IPCOMP=m
++CONFIG_INET6_TUNNEL=m
++CONFIG_IPV6_TUNNEL=m
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_BRIDGE_NETFILTER=y
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++
++#
++# IP: Netfilter Configuration
++#
++CONFIG_IP_NF_CONNTRACK=m
++# CONFIG_IP_NF_CT_ACCT is not set
++CONFIG_IP_NF_CONNTRACK_MARK=y
++CONFIG_IP_NF_CONNTRACK_EVENTS=y
++CONFIG_IP_NF_CONNTRACK_NETLINK=m
++CONFIG_IP_NF_CT_PROTO_SCTP=m
++CONFIG_IP_NF_FTP=m
++CONFIG_IP_NF_IRC=m
++# CONFIG_IP_NF_NETBIOS_NS is not set
++CONFIG_IP_NF_TFTP=m
++CONFIG_IP_NF_AMANDA=m
++CONFIG_IP_NF_PPTP=m
++CONFIG_IP_NF_QUEUE=m
++CONFIG_IP_NF_IPTABLES=m
++CONFIG_IP_NF_MATCH_LIMIT=m
++CONFIG_IP_NF_MATCH_IPRANGE=m
++CONFIG_IP_NF_MATCH_MAC=m
++CONFIG_IP_NF_MATCH_PKTTYPE=m
++CONFIG_IP_NF_MATCH_MARK=m
++CONFIG_IP_NF_MATCH_MULTIPORT=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_ESP=m
++CONFIG_IP_NF_MATCH_LENGTH=m
++CONFIG_IP_NF_MATCH_TTL=m
++CONFIG_IP_NF_MATCH_TCPMSS=m
++CONFIG_IP_NF_MATCH_HELPER=m
++CONFIG_IP_NF_MATCH_STATE=m
++CONFIG_IP_NF_MATCH_CONNTRACK=m
++CONFIG_IP_NF_MATCH_OWNER=m
++CONFIG_IP_NF_MATCH_PHYSDEV=m
++CONFIG_IP_NF_MATCH_ADDRTYPE=m
++CONFIG_IP_NF_MATCH_REALM=m
++CONFIG_IP_NF_MATCH_SCTP=m
++CONFIG_IP_NF_MATCH_DCCP=m
++CONFIG_IP_NF_MATCH_COMMENT=m
++CONFIG_IP_NF_MATCH_CONNMARK=m
++CONFIG_IP_NF_MATCH_HASHLIMIT=m
++CONFIG_IP_NF_MATCH_STRING=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_MANGLE=m
++CONFIG_IP_NF_TARGET_TOS=m
++CONFIG_IP_NF_TARGET_ECN=m
++CONFIG_IP_NF_TARGET_DSCP=m
++CONFIG_IP_NF_TARGET_MARK=m
++CONFIG_IP_NF_TARGET_CLASSIFY=m
++CONFIG_IP_NF_TARGET_TTL=m
++CONFIG_IP_NF_TARGET_CONNMARK=m
++CONFIG_IP_NF_TARGET_CLUSTERIP=m
++CONFIG_IP_NF_RAW=m
++CONFIG_IP_NF_TARGET_NOTRACK=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_LIMIT=m
++CONFIG_IP6_NF_MATCH_MAC=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_MULTIPORT=m
++CONFIG_IP6_NF_MATCH_OWNER=m
++CONFIG_IP6_NF_MATCH_MARK=m
++CONFIG_IP6_NF_MATCH_IPV6HEADER=m
++CONFIG_IP6_NF_MATCH_AHESP=m
++CONFIG_IP6_NF_MATCH_LENGTH=m
++CONFIG_IP6_NF_MATCH_EUI64=m
++CONFIG_IP6_NF_MATCH_PHYSDEV=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_MARK=m
++CONFIG_IP6_NF_TARGET_HL=m
++CONFIG_IP6_NF_RAW=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=m
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++CONFIG_BRIDGE=m
++# CONFIG_VLAN_8021Q is not set
++CONFIG_DECNET=m
++# CONFIG_DECNET_ROUTER 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
++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
++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
++CONFIG_NET_QOS=y
++CONFIG_NET_ESTIMATOR=y
++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 is not set
++# CONFIG_NET_CLS_IND 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
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++CONFIG_HAMRADIO=y
++
++#
++# Packet Radio protocols
++#
++CONFIG_AX25=m
++CONFIG_AX25_DAMA_SLAVE=y
++CONFIG_NETROM=m
++CONFIG_ROSE=m
++
++#
++# AX.25 network device drivers
++#
++CONFIG_MKISS=m
++CONFIG_6PACK=m
++CONFIG_BPQETHER=m
++# CONFIG_BAYCOM_SER_FDX is not set
++# CONFIG_BAYCOM_SER_HDX is not set
++# CONFIG_BAYCOM_PAR is not set
++# CONFIG_BAYCOM_EPP is not set
++# CONFIG_YAM 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -176,7 +506,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -188,11 +523,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ CONFIG_PARPORT=m
+ CONFIG_PARPORT_PC=m
+-CONFIG_PARPORT_PC_CML1=m
+ CONFIG_PARPORT_SERIAL=m
+ # CONFIG_PARPORT_PC_FIFO is not set
+ # CONFIG_PARPORT_PC_SUPERIO is not set
+-# CONFIG_PARPORT_OTHER is not set
++CONFIG_PARPORT_NOT_PC=y
++# CONFIG_PARPORT_GSC is not set
+ CONFIG_PARPORT_1284=y
+ 
+ #
+@@ -204,7 +539,6 @@ CONFIG_PARPORT_1284=y
+ # Block devices
+ #
+ CONFIG_BLK_DEV_FD=m
+-# CONFIG_BLK_DEV_XD is not set
+ CONFIG_PARIDE=m
+ CONFIG_PARIDE_PARPORT=m
+ 
+@@ -249,7 +583,6 @@ CONFIG_BLK_DEV_UB=m
+ CONFIG_BLK_DEV_RAM=m
+ CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -272,6 +605,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -283,384 +617,131 @@ CONFIG_CHR_DEV_ST=m
+ # CONFIG_CHR_DEV_OSST is not set
+ CONFIG_BLK_DEV_SR=m
+ CONFIG_BLK_DEV_SR_VENDOR=y
+-# CONFIG_CHR_DEV_SG 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
+-
+-#
+-# SCSI low-level drivers
+-#
+-# 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=y
+-CONFIG_MEGARAID_MM=m
+-CONFIG_MEGARAID_MAILBOX=m
+-# CONFIG_SCSI_SATA 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_EATA_PIO is not set
+-# CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+-# CONFIG_SCSI_GENERIC_NCR5380 is not set
+-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+-# CONFIG_SCSI_IPS is not set
+-# CONFIG_SCSI_INITIO is not set
+-# CONFIG_SCSI_INIA100 is not set
+-CONFIG_SCSI_PPA=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=y
+-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+-# 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_ISP is not set
+-# CONFIG_SCSI_QLOGIC_FC is not set
+-# CONFIG_SCSI_QLOGIC_1280 is not set
+-CONFIG_SCSI_QLA2XXX=y
+-# CONFIG_SCSI_QLA21XX is not set
+-# CONFIG_SCSI_QLA22XX is not set
+-# CONFIG_SCSI_QLA2300 is not set
+-# CONFIG_SCSI_QLA2322 is not set
+-# CONFIG_SCSI_QLA6312 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=y
+-CONFIG_BLK_DEV_MD=m
+-CONFIG_MD_LINEAR=m
+-CONFIG_MD_RAID0=m
+-CONFIG_MD_RAID1=m
+-CONFIG_MD_RAID10=m
+-CONFIG_MD_RAID5=m
+-# CONFIG_MD_RAID6 is not set
+-CONFIG_MD_MULTIPATH=m
+-CONFIG_MD_FAULTY=m
+-CONFIG_BLK_DEV_DM=m
+-# CONFIG_DM_CRYPT is not set
+-CONFIG_DM_SNAPSHOT=m
+-CONFIG_DM_MIRROR=m
+-CONFIG_DM_ZERO=m
+-
+-#
+-# 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
+-
+-#
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=m
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=m
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=m
+-CONFIG_INET=y
+-CONFIG_IP_MULTICAST=y
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-# 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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-CONFIG_IP_TCPDIAG_IPV6=y
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-CONFIG_IPV6=m
+-CONFIG_IPV6_PRIVACY=y
+-CONFIG_INET6_AH=m
+-CONFIG_INET6_ESP=m
+-CONFIG_INET6_IPCOMP=m
+-CONFIG_INET6_TUNNEL=m
+-CONFIG_IPV6_TUNNEL=m
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-CONFIG_BRIDGE_NETFILTER=y
+-
+-#
+-# IP: Netfilter Configuration
+-#
+-CONFIG_IP_NF_CONNTRACK=m
+-# CONFIG_IP_NF_CT_ACCT is not set
+-CONFIG_IP_NF_CONNTRACK_MARK=y
+-CONFIG_IP_NF_CT_PROTO_SCTP=m
+-CONFIG_IP_NF_FTP=m
+-CONFIG_IP_NF_IRC=m
+-CONFIG_IP_NF_TFTP=m
+-CONFIG_IP_NF_AMANDA=m
+-CONFIG_IP_NF_QUEUE=m
+-CONFIG_IP_NF_IPTABLES=m
+-CONFIG_IP_NF_MATCH_LIMIT=m
+-CONFIG_IP_NF_MATCH_IPRANGE=m
+-CONFIG_IP_NF_MATCH_MAC=m
+-CONFIG_IP_NF_MATCH_PKTTYPE=m
+-CONFIG_IP_NF_MATCH_MARK=m
+-CONFIG_IP_NF_MATCH_MULTIPORT=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_ESP=m
+-CONFIG_IP_NF_MATCH_LENGTH=m
+-CONFIG_IP_NF_MATCH_TTL=m
+-CONFIG_IP_NF_MATCH_TCPMSS=m
+-CONFIG_IP_NF_MATCH_HELPER=m
+-CONFIG_IP_NF_MATCH_STATE=m
+-CONFIG_IP_NF_MATCH_CONNTRACK=m
+-CONFIG_IP_NF_MATCH_OWNER=m
+-CONFIG_IP_NF_MATCH_PHYSDEV=m
+-CONFIG_IP_NF_MATCH_ADDRTYPE=m
+-CONFIG_IP_NF_MATCH_REALM=m
+-CONFIG_IP_NF_MATCH_SCTP=m
+-CONFIG_IP_NF_MATCH_COMMENT=m
+-CONFIG_IP_NF_MATCH_CONNMARK=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_MANGLE=m
+-CONFIG_IP_NF_TARGET_TOS=m
+-CONFIG_IP_NF_TARGET_ECN=m
+-CONFIG_IP_NF_TARGET_DSCP=m
+-CONFIG_IP_NF_TARGET_MARK=m
+-CONFIG_IP_NF_TARGET_CLASSIFY=m
+-CONFIG_IP_NF_TARGET_CONNMARK=m
+-CONFIG_IP_NF_TARGET_CLUSTERIP=m
+-CONFIG_IP_NF_RAW=m
+-CONFIG_IP_NF_TARGET_NOTRACK=m
+-CONFIG_IP_NF_ARPTABLES=m
+-CONFIG_IP_NF_ARPFILTER=m
+-CONFIG_IP_NF_ARP_MANGLE=m
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
+ 
+ #
+-# IPv6: Netfilter Configuration
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+ #
+-CONFIG_IP6_NF_QUEUE=m
+-CONFIG_IP6_NF_IPTABLES=m
+-CONFIG_IP6_NF_MATCH_LIMIT=m
+-CONFIG_IP6_NF_MATCH_MAC=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_MULTIPORT=m
+-CONFIG_IP6_NF_MATCH_OWNER=m
+-CONFIG_IP6_NF_MATCH_MARK=m
+-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+-CONFIG_IP6_NF_MATCH_AHESP=m
+-CONFIG_IP6_NF_MATCH_LENGTH=m
+-CONFIG_IP6_NF_MATCH_EUI64=m
+-CONFIG_IP6_NF_MATCH_PHYSDEV=m
+-CONFIG_IP6_NF_FILTER=m
+-CONFIG_IP6_NF_TARGET_LOG=m
+-CONFIG_IP6_NF_MANGLE=m
+-CONFIG_IP6_NF_TARGET_MARK=m
+-CONFIG_IP6_NF_RAW=m
++# CONFIG_SCSI_MULTI_LUN is not set
++CONFIG_SCSI_CONSTANTS=y
++# CONFIG_SCSI_LOGGING is not set
+ 
+ #
+-# DECnet: Netfilter Configuration
++# SCSI Transport Attributes
+ #
+-CONFIG_DECNET_NF_GRABULATOR=m
++CONFIG_SCSI_SPI_ATTRS=y
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++CONFIG_SCSI_SAS_ATTRS=m
+ 
+ #
+-# Bridge: Netfilter Configuration
++# SCSI low-level drivers
+ #
+-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
+-CONFIG_XFRM=y
+-# CONFIG_XFRM_USER 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_AHA152X 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=y
++CONFIG_MEGARAID_MM=m
++CONFIG_MEGARAID_MAILBOX=m
++# CONFIG_SCSI_SATA is not set
++# CONFIG_SCSI_DMX3191D is not set
++# CONFIG_SCSI_DTC3280 is not set
++# CONFIG_SCSI_FUTURE_DOMAIN is not set
++# CONFIG_SCSI_GENERIC_NCR5380 is not set
++# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
++# CONFIG_SCSI_IPS is not set
++# CONFIG_SCSI_INITIO is not set
++# CONFIG_SCSI_INIA100 is not set
++CONFIG_SCSI_PPA=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=y
++CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
++CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
++CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
++# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
++# 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_FC is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++CONFIG_SCSI_QLA2XXX=y
++# CONFIG_SCSI_QLA21XX is not set
++# CONFIG_SCSI_QLA22XX is not set
++# CONFIG_SCSI_QLA2300 is not set
++# CONFIG_SCSI_QLA2322 is not set
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX 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_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
+ 
+ #
+-# SCTP Configuration (EXPERIMENTAL)
++# Old CD-ROM drivers (not SCSI, not IDE)
+ #
+-# CONFIG_IP_SCTP is not set
+-# CONFIG_ATM is not set
+-CONFIG_BRIDGE=m
+-# CONFIG_VLAN_8021Q is not set
+-CONFIG_DECNET=m
+-# CONFIG_DECNET_ROUTER 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
++# CONFIG_CD_NO_IDESCSI is not set
+ 
+ #
+-# QoS and/or fair queueing
++# Multi-device support (RAID and LVM)
+ #
+-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
+-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
+-CONFIG_NET_QOS=y
+-CONFIG_NET_ESTIMATOR=y
+-CONFIG_NET_CLS=y
+-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_NET_CLS_IND is not set
+-# CONFIG_CLS_U32_MARK is not set
+-CONFIG_NET_CLS_RSVP=m
+-CONFIG_NET_CLS_RSVP6=m
+-# CONFIG_NET_CLS_ACT is not set
+-CONFIG_NET_CLS_POLICE=y
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=m
++CONFIG_MD_LINEAR=m
++CONFIG_MD_RAID0=m
++CONFIG_MD_RAID1=m
++CONFIG_MD_RAID10=m
++CONFIG_MD_RAID5=m
++# CONFIG_MD_RAID6 is not set
++CONFIG_MD_MULTIPATH=m
++CONFIG_MD_FAULTY=m
++CONFIG_BLK_DEV_DM=m
++# CONFIG_DM_CRYPT is not set
++CONFIG_DM_SNAPSHOT=m
++CONFIG_DM_MIRROR=m
++CONFIG_DM_ZERO=m
++CONFIG_DM_MULTIPATH=m
++CONFIG_DM_MULTIPATH_EMC=m
+ 
+ #
+-# Network testing
++# Fusion MPT device support
+ #
+-# CONFIG_NET_PKTGEN is not set
+-# CONFIG_NETPOLL is not set
+-# CONFIG_NET_POLL_CONTROLLER is not set
+-CONFIG_HAMRADIO=y
++# CONFIG_FUSION is not set
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC is not set
+ 
+ #
+-# Packet Radio protocols
++# IEEE 1394 (FireWire) support
+ #
+-CONFIG_AX25=m
+-CONFIG_AX25_DAMA_SLAVE=y
+-CONFIG_NETROM=m
+-CONFIG_ROSE=m
++# CONFIG_IEEE1394 is not set
+ 
+ #
+-# AX.25 network device drivers
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# Network device support
+ #
+-CONFIG_MKISS=m
+-CONFIG_6PACK=m
+-CONFIG_BPQETHER=m
+-# CONFIG_DMASCC is not set
+-# CONFIG_SCC is not set
+-# CONFIG_BAYCOM_SER_FDX is not set
+-# CONFIG_BAYCOM_SER_HDX is not set
+-# CONFIG_BAYCOM_PAR is not set
+-# CONFIG_BAYCOM_EPP is not set
+-# CONFIG_YAM is not set
+-# CONFIG_IRDA is not set
+-# CONFIG_BT is not set
+ CONFIG_NETDEVICES=y
+ CONFIG_DUMMY=m
+ CONFIG_BONDING=m
+ CONFIG_EQUALIZER=m
+ CONFIG_TUN=m
+-CONFIG_ETHERTAP=m
+ 
+ #
+ # ARCnet devices
+@@ -668,6 +749,21 @@ CONFIG_ETHERTAP=m
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -675,7 +771,6 @@ CONFIG_MII=y
+ # CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNGEM is not set
+ # CONFIG_NET_VENDOR_3COM is not set
+-# CONFIG_LANCE is not set
+ # CONFIG_NET_VENDOR_SMC is not set
+ # CONFIG_NET_VENDOR_RACAL is not set
+ 
+@@ -696,7 +791,6 @@ CONFIG_NET_ISA=y
+ # 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=y
+@@ -733,13 +827,17 @@ CONFIG_EEPRO100=m
+ # 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_SK98LIN is not set
+ CONFIG_VIA_VELOCITY=m
+ # 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
+ 
+@@ -752,6 +850,8 @@ CONFIG_VIA_VELOCITY=m
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -765,6 +865,8 @@ CONFIG_PLIP=m
+ # 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
+@@ -794,20 +896,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_I8042=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-CONFIG_SERIO_PARKBD=m
+-# CONFIG_SERIO_PCIPS2 is not set
+-CONFIG_SERIO_LIBPS2=y
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
+@@ -828,6 +916,18 @@ CONFIG_MOUSE_PS2=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_I8042=y
++CONFIG_SERIO_SERPORT=y
++CONFIG_SERIO_PARKBD=m
++# CONFIG_SERIO_PCIPS2 is not set
++CONFIG_SERIO_LIBPS2=y
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -844,13 +944,13 @@ CONFIG_SERIAL_8250_EXTENDED=y
+ # CONFIG_SERIAL_8250_MANY_PORTS is not set
+ CONFIG_SERIAL_8250_SHARE_IRQ=y
+ CONFIG_SERIAL_8250_DETECT_IRQ=y
+-CONFIG_SERIAL_8250_MULTIPORT=y
+ CONFIG_SERIAL_8250_RSA=y
+ 
+ #
+ # Non-8250 serial port support
+ #
+ CONFIG_SERIAL_CORE=m
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -881,6 +981,11 @@ CONFIG_RTC=m
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -891,15 +996,26 @@ CONFIG_RTC=m
+ CONFIG_W1=m
+ CONFIG_W1_MATROX=m
+ CONFIG_W1_DS9490=m
+-CONFIG_W1_DS9490_BRIDGE=m
++# CONFIG_W1_DS9490_BRIDGE is not set
+ CONFIG_W1_THERM=m
+ CONFIG_W1_SMEM=m
++# CONFIG_W1_DS2433 is not set
++
++#
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
+ 
+ #
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -920,7 +1036,6 @@ CONFIG_W1_SMEM=m
+ CONFIG_VGA_CONSOLE=y
+ # CONFIG_MDA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -930,6 +1045,8 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
+ CONFIG_USB=m
+ # CONFIG_USB_DEBUG is not set
+ 
+@@ -940,8 +1057,6 @@ CONFIG_USB_DEVICEFS=y
+ # CONFIG_USB_BANDWIDTH is not set
+ # CONFIG_USB_DYNAMIC_MINORS is not set
+ # CONFIG_USB_OTG is not set
+-CONFIG_USB_ARCH_HAS_HCD=y
+-CONFIG_USB_ARCH_HAS_OHCI=y
+ 
+ #
+ # USB Host Controller Drivers
+@@ -949,7 +1064,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ CONFIG_USB_EHCI_HCD=m
+ # CONFIG_USB_EHCI_SPLIT_ISO is not set
+ # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++# CONFIG_USB_ISP116X_HCD is not set
+ CONFIG_USB_OHCI_HCD=m
++# CONFIG_USB_OHCI_BIG_ENDIAN is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+ CONFIG_USB_UHCI_HCD=m
+ # CONFIG_USB_SL811_HCD is not set
+ 
+@@ -965,11 +1083,10 @@ CONFIG_USB_PRINTER=m
+ #
+ CONFIG_USB_STORAGE=m
+ # CONFIG_USB_STORAGE_DEBUG is not set
+-# CONFIG_USB_STORAGE_RW_DETECT is not set
+ CONFIG_USB_STORAGE_DATAFAB=y
+ CONFIG_USB_STORAGE_FREECOM=y
+ CONFIG_USB_STORAGE_DPCM=y
+-CONFIG_USB_STORAGE_HP8200e=y
++# CONFIG_USB_STORAGE_USBAT is not set
+ CONFIG_USB_STORAGE_SDDR09=y
+ CONFIG_USB_STORAGE_SDDR55=y
+ CONFIG_USB_STORAGE_JUMPSHOT=y
+@@ -992,12 +1109,17 @@ 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_MTOUCH is not set
++# CONFIG_USB_ITMTOUCH is not set
+ CONFIG_USB_EGALAX=m
++CONFIG_USB_YEALINK=m
+ CONFIG_USB_XPAD=m
+ # CONFIG_USB_ATI_REMOTE is not set
++# CONFIG_USB_KEYSPAN_REMOTE is not set
++# CONFIG_USB_APPLETOUCH is not set
+ 
+ #
+ # USB Imaging devices
+@@ -1022,30 +1144,15 @@ CONFIG_USB_KAWETH=m
+ CONFIG_USB_PEGASUS=m
+ CONFIG_USB_RTL8150=m
+ CONFIG_USB_USBNET=m
+-
+-#
+-# USB Host-to-Host Cables
+-#
+-CONFIG_USB_ALI_M5632=y
+-CONFIG_USB_AN2720=y
+-CONFIG_USB_BELKIN=y
+-CONFIG_USB_GENESYS=y
+-CONFIG_USB_NET1080=y
+-CONFIG_USB_PL2301=y
+-CONFIG_USB_KC2190=y
+-
+-#
+-# Intelligent USB Devices/Gadgets
+-#
+-CONFIG_USB_ARMLINUX=y
+-CONFIG_USB_EPSON2888=y
+-CONFIG_USB_ZAURUS=y
+-CONFIG_USB_CDCETHER=y
+-
+-#
+-# USB Network Adapters
+-#
+-CONFIG_USB_AX8817X=y
++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
+@@ -1057,9 +1164,11 @@ CONFIG_USB_USS720=m
+ #
+ CONFIG_USB_SERIAL=m
+ CONFIG_USB_SERIAL_GENERIC=y
++CONFIG_USB_SERIAL_AIRPRIME=m
+ 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
+@@ -1088,6 +1197,7 @@ CONFIG_USB_SERIAL_KLSI=m
+ CONFIG_USB_SERIAL_KOBIL_SCT=m
+ CONFIG_USB_SERIAL_MCT_U232=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_TI is not set
+@@ -1110,10 +1220,13 @@ CONFIG_USB_CYTHERM=m
+ CONFIG_USB_PHIDGETKIT=m
+ CONFIG_USB_PHIDGETSERVO=m
+ # CONFIG_USB_IDMOUSE is not set
++CONFIG_USB_SISUSBVGA=m
++# CONFIG_USB_SISUSBVGA_CON is not set
++CONFIG_USB_LD=m
+ CONFIG_USB_TEST=m
+ 
+ #
+-# USB ATM/DSL drivers
++# USB DSL modem support
+ #
+ 
+ #
+@@ -1132,10 +1245,15 @@ CONFIG_USB_TEST=m
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=m
+ # 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
+@@ -1152,17 +1270,20 @@ CONFIG_REISERFS_FS_SECURITY=y
+ # CONFIG_JFS_FS is not set
+ CONFIG_FS_POSIX_ACL=y
+ CONFIG_XFS_FS=m
+-# CONFIG_XFS_RT is not set
+-CONFIG_XFS_QUOTA=y
++CONFIG_XFS_EXPORT=y
++CONFIG_XFS_QUOTA=m
+ CONFIG_XFS_SECURITY=y
+ # CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
+ CONFIG_MINIX_FS=m
+ CONFIG_ROMFS_FS=m
++CONFIG_INOTIFY=y
+ # CONFIG_QUOTA is not set
+ CONFIG_QUOTACTL=y
+ CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -1192,12 +1313,10 @@ CONFIG_NTFS_FS=m
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -1224,15 +1343,18 @@ CONFIG_UFS_FS=m
+ #
+ 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=m
+ CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
+ # CONFIG_NFSD_V4 is not set
+ CONFIG_NFSD_TCP=y
+ CONFIG_LOCKD=m
+ CONFIG_LOCKD_V4=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=m
+ CONFIG_SUNRPC_GSS=m
+ CONFIG_RPCSEC_GSS_KRB5=m
+@@ -1256,6 +1378,7 @@ CONFIG_CODA_FS=m
+ CONFIG_CODA_FS_OLD_API=y
+ CONFIG_AFS_FS=m
+ CONFIG_RXRPC=m
++# CONFIG_9P_FS is not set
+ 
+ #
+ # Partition Types
+@@ -1329,7 +1452,9 @@ CONFIG_NLS_UTF8=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -1352,6 +1477,7 @@ CONFIG_CRYPTO_SHA1=m
+ 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
+@@ -1360,13 +1486,13 @@ CONFIG_CRYPTO_AES=m
+ CONFIG_CRYPTO_CAST5=m
+ CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+ CONFIG_CRYPTO_DEFLATE=m
+ CONFIG_CRYPTO_MICHAEL_MIC=m
+-# CONFIG_CRYPTO_CRC32C is not set
+-CONFIG_CRYPTO_TEST=m
++CONFIG_CRYPTO_CRC32C=m
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -1376,9 +1502,12 @@ CONFIG_CRYPTO_TEST=m
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+-# CONFIG_LIBCRC32C is not set
++CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=m
+ CONFIG_ZLIB_DEFLATE=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_TEXTSEARCH=y
++CONFIG_TEXTSEARCH_KMP=m
++CONFIG_TEXTSEARCH_BM=m
++CONFIG_TEXTSEARCH_FSM=m
+diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
+--- a/arch/mips/configs/sb1250-swarm_defconfig
++++ b/arch/mips/configs/sb1250-swarm_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:10 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:27:05 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,30 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=15
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_CPUSETS=y
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +44,7 @@ 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
+@@ -57,32 +61,49 @@ CONFIG_STOP_MACHINE=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-CONFIG_SIBYTE_SB1xxx_SOC=y
++# CONFIG_SGI_IP27 is not set
++# CONFIG_SGI_IP32 is not set
++# CONFIG_SIBYTE_BIGSUR is not set
+ CONFIG_SIBYTE_SWARM=y
+ # CONFIG_SIBYTE_SENTOSA is not set
+ # CONFIG_SIBYTE_RHONE is not set
+@@ -91,9 +112,12 @@ CONFIG_SIBYTE_SWARM=y
+ # CONFIG_SIBYTE_LITTLESUR is not set
+ # CONFIG_SIBYTE_CRHINE is not set
+ # CONFIG_SIBYTE_CRHONE is not set
+-# CONFIG_SIBYTE_UNKNOWN is not set
+-CONFIG_SIBYTE_BOARD=y
++# 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_SIBYTE_SB1250=y
++CONFIG_SIBYTE_SB1xxx_SOC=y
+ CONFIG_CPU_SB1_PASS_1=y
+ # CONFIG_CPU_SB1_PASS_2_1250 is not set
+ # CONFIG_CPU_SB1_PASS_2_2 is not set
+@@ -102,18 +126,20 @@ CONFIG_CPU_SB1_PASS_1=y
+ # CONFIG_CPU_SB1_PASS_3 is not set
+ CONFIG_SIBYTE_HAS_LDT=y
+ # CONFIG_SIMULATION is not set
++# CONFIG_CONFIG_SB1_CEX_ALWAYS_FATAL is not set
++# CONFIG_CONFIG_SB1_CERR_STALL is not set
+ CONFIG_SIBYTE_CFE=y
+ # CONFIG_SIBYTE_CFE_CONSOLE is not set
+ # CONFIG_SIBYTE_BUS_WATCHER is not set
+ # CONFIG_SIBYTE_SB1250_PROF is not set
+ # CONFIG_SIBYTE_TBPROF is not set
+-# CONFIG_SNI_RM200_PCI is not set
+-# CONFIG_TOSHIBA_RBTX4927 is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_COHERENT=y
++CONFIG_CPU_BIG_ENDIAN=y
+ # CONFIG_CPU_LITTLE_ENDIAN is not set
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -121,8 +147,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -138,22 +166,46 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ CONFIG_CPU_SB1=y
++CONFIG_SYS_HAS_CPU_SB1=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
+ CONFIG_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_SIBYTE_DMA_PAGEOPS is not set
+ CONFIG_CPU_HAS_PREFETCH=y
++# CONFIG_MIPS_MT is not set
+ CONFIG_SB1_PASS_1_WORKAROUNDS=y
+-# CONFIG_64BIT_PHYS_ADDR is not set
+-# CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=y
+ CONFIG_CPU_HAS_SYNC=y
+-# CONFIG_HIGHMEM is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_SYS_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_SMP=y
+ CONFIG_NR_CPUS=2
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
++CONFIG_PREEMPT_BKL=y
+ 
+ #
+ # Bus options (PCI, PCMCIA, EISA, ISA, TC)
+@@ -161,7 +213,6 @@ CONFIG_NR_CPUS=2
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+ CONFIG_MMU=y
+ 
+ #
+@@ -170,10 +221,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -183,7 +230,86 @@ CONFIG_MMU=y
+ #
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+-CONFIG_TRAD_SIGNALS=y
++# CONFIG_BUILD_ELF64 is not set
++CONFIG_MIPS32_COMPAT=y
++CONFIG_COMPAT=y
++CONFIG_MIPS32_O32=y
++# CONFIG_MIPS32_N32 is not set
++CONFIG_BINFMT_ELF32=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ 
+ #
+ # Device Drivers
+@@ -194,7 +320,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -213,7 +344,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -226,8 +356,6 @@ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=9220
+ CONFIG_BLK_DEV_INITRD=y
+-CONFIG_INITRAMFS_SOURCE=""
+-# CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+ # CONFIG_CDROM_PKTCDVD_WCACHE is not set
+@@ -263,7 +391,7 @@ CONFIG_BLK_DEV_IDEFLOPPY=y
+ #
+ CONFIG_IDE_GENERIC=y
+ # CONFIG_BLK_DEV_IDEPCI is not set
+-CONFIG_BLK_DEV_IDE_SWARM=y
++# CONFIG_BLK_DEV_IDE_SWARM is not set
+ # CONFIG_IDE_ARM is not set
+ # CONFIG_BLK_DEV_IDEDMA is not set
+ # CONFIG_IDEDMA_AUTO is not set
+@@ -272,6 +400,7 @@ CONFIG_BLK_DEV_IDE_SWARM=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -282,6 +411,7 @@ CONFIG_BLK_DEV_IDE_SWARM=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -294,78 +424,13 @@ CONFIG_BLK_DEV_IDE_SWARM=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
++# Network device support
+ #
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -373,6 +438,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -399,12 +479,16 @@ CONFIG_MII=y
+ # CONFIG_YELLOWFIN is not set
+ # CONFIG_R8169 is not set
+ CONFIG_NET_SB1250_MAC=y
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE 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
+ 
+@@ -417,6 +501,8 @@ CONFIG_NET_SB1250_MAC=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -428,6 +514,8 @@ CONFIG_NET_SB1250_MAC=y
+ # 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
+@@ -445,25 +533,15 @@ CONFIG_NET_SB1250_MAC=y
+ # CONFIG_INPUT is not set
+ 
+ #
+-# Userland interfaces
+-#
+-
+-#
+-# Input I/O drivers
++# Hardware I/O ports
+ #
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+ CONFIG_SERIO=y
+ # CONFIG_SERIO_I8042 is not set
+ CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+ # CONFIG_SERIO_PCIPS2 is not set
+ # CONFIG_SERIO_LIBPS2 is not set
+ CONFIG_SERIO_RAW=m
+-
+-#
+-# Input Device Drivers
+-#
++# CONFIG_GAMEPORT is not set
+ 
+ #
+ # Character devices
+@@ -472,11 +550,13 @@ CONFIG_SERIO_RAW=m
+ CONFIG_SERIAL_NONSTANDARD=y
+ # CONFIG_ROCKETPORT is not set
+ # CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
+ # CONFIG_MOXA_SMARTIO is not set
+ # CONFIG_ISI is not set
+-# CONFIG_SYNCLINK is not set
+ # CONFIG_SYNCLINKMP is not set
+ # CONFIG_N_HDLC is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_SX is not set
+ # CONFIG_STALDRV is not set
+ CONFIG_SIBYTE_SB1250_DUART=y
+ CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
+@@ -489,6 +569,7 @@ CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
+ #
+ # Non-8250 serial port support
+ #
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -515,6 +596,11 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -525,10 +611,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -542,7 +638,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # Graphics support
+ #
+ # CONFIG_FB is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -552,13 +647,9 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -576,12 +667,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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 is not set
+ # CONFIG_JBD is not set
+ CONFIG_FS_MBCACHE=y
+@@ -591,10 +687,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -615,11 +713,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ # CONFIG_TMPFS is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -643,13 +740,14 @@ CONFIG_RAMFS=y
+ #
+ 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_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -658,6 +756,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -678,7 +777,9 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=15
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ # CONFIG_SB1XXX_CORELIS is not set
+@@ -695,27 +796,28 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=y
+-CONFIG_CRYPTO_MD4=y
+-CONFIG_CRYPTO_MD5=y
+-CONFIG_CRYPTO_SHA1=y
+-CONFIG_CRYPTO_SHA256=y
+-CONFIG_CRYPTO_SHA512=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
+-CONFIG_CRYPTO_DES=y
+-CONFIG_CRYPTO_BLOWFISH=y
+-CONFIG_CRYPTO_TWOFISH=y
+-CONFIG_CRYPTO_SERPENT=y
++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 is not set
+-# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
+ CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
++CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
+-CONFIG_CRYPTO_MICHAEL_MIC=y
+-# CONFIG_CRYPTO_CRC32C is not set
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
++CONFIG_CRYPTO_CRC32C=m
+ # CONFIG_CRYPTO_TEST is not set
+ 
+ #
+@@ -726,9 +828,8 @@ CONFIG_CRYPTO_MICHAEL_MIC=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_LIBCRC32C=m
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
+--- a/arch/mips/configs/sead_defconfig
++++ b/arch/mips/configs/sead_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:10 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:27:07 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,22 +11,26 @@ CONFIG_32BIT=y
+ 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_LOCALVERSION_AUTO=y
++# CONFIG_SWAP is not set
++CONFIG_SYSVIPC=y
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+-# CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=14
+ # CONFIG_HOTPLUG is not set
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -39,6 +40,7 @@ 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
+@@ -48,40 +50,69 @@ CONFIG_CC_ALIGN_JUMPS=0
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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=y
++# CONFIG_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_BOARDS_GEN=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+@@ -89,8 +120,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-CONFIG_CPU_MIPS32=y
+-# CONFIG_CPU_MIPS64 is not set
++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
+@@ -106,15 +139,42 @@ CONFIG_CPU_MIPS32=y
+ # 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_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 is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -128,10 +188,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -143,6 +199,11 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++# CONFIG_NET is not set
++
++#
+ # Device Drivers
+ #
+ 
+@@ -154,6 +215,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_FW_LOADER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -170,7 +235,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD is not set
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+@@ -178,11 +242,8 @@ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=18432
+ CONFIG_BLK_DEV_INITRD=y
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=y
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
++# CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+ # IO Schedulers
+@@ -200,6 +261,7 @@ CONFIG_IOSCHED_CFQ=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=y
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -210,6 +272,7 @@ CONFIG_IOSCHED_CFQ=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -220,9 +283,8 @@ CONFIG_IOSCHED_CFQ=y
+ #
+ 
+ #
+-# Networking support
++# Network device support
+ #
+-# CONFIG_NET is not set
+ # CONFIG_NETPOLL is not set
+ # CONFIG_NET_POLL_CONTROLLER is not set
+ 
+@@ -238,47 +300,18 @@ CONFIG_IOSCHED_CFQ=y
+ #
+ # Input device support
+ #
+-CONFIG_INPUT=y
++# CONFIG_INPUT is not set
+ 
+ #
+-# 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 I/O drivers
++# Hardware I/O ports
+ #
++# CONFIG_SERIO is not set
+ # CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=y
+-
+-#
+-# 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
+ 
+ #
+ # Character devices
+ #
+-CONFIG_VT=y
+-CONFIG_VT_CONSOLE=y
+-CONFIG_HW_CONSOLE=y
++# CONFIG_VT is not set
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ 
+ #
+@@ -294,7 +327,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+-# CONFIG_UNIX98_PTYS is not set
++CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+ 
+@@ -315,10 +348,13 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -329,10 +365,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -347,13 +393,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_FB is not set
+ 
+ #
+-# Console display driver support
+-#
+-# CONFIG_VGA_CONSOLE is not set
+-CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+-
+-#
+ # Sound
+ #
+ # CONFIG_SOUND is not set
+@@ -365,10 +404,6 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -381,28 +416,31 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN 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_XATTR is not set
++# CONFIG_EXT2_FS_XIP 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
+-CONFIG_FS_POSIX_ACL=y
++# CONFIG_FS_POSIX_ACL is not set
+ # CONFIG_XFS_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=y
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -423,10 +461,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+ # CONFIG_TMPFS is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=y
+ 
+ #
+ # Miscellaneous filesystems
+@@ -448,8 +486,18 @@ CONFIG_RAMFS=y
+ #
+ # Partition Types
+ #
+-# CONFIG_PARTITION_ADVANCED is not set
+-CONFIG_MSDOS_PARTITION=y
++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_EFI_PARTITION is not set
+ 
+ #
+ # Native Language Support
+@@ -464,15 +512,16 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+ #
+ # Security options
+ #
+-CONFIG_KEYS=y
+-CONFIG_KEYS_DEBUG_PROC_KEYS=y
++# CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
+ 
+ #
+@@ -488,7 +537,6 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=y
+ # CONFIG_CRC32 is not set
+ # CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
+diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
+--- a/arch/mips/configs/tb0226_defconfig
++++ b/arch/mips/configs/tb0226_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:12 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:27:10 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,55 +59,87 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-CONFIG_MACH_VR41XX=y
+-# CONFIG_NEC_CMBVR4133 is not set
+-# CONFIG_CASIO_E55 is not set
+-# CONFIG_IBM_WORKPAD is not set
+-CONFIG_TANBAC_TB0226=y
+-# CONFIG_TANBAC_TB0229 is not set
+-# CONFIG_VICTOR_MPC30X is not set
+-# CONFIG_ZAO_CAPCELLA is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++CONFIG_MACH_VR41XX=y
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_NEC_CMBVR4133 is not set
++# CONFIG_CASIO_E55 is not set
++# CONFIG_IBM_WORKPAD is not set
++CONFIG_TANBAC_TB022X=y
++CONFIG_TANBAC_TB0226=y
++# CONFIG_VICTOR_MPC30X is not set
++# CONFIG_ZAO_CAPCELLA is not set
++CONFIG_PCI_VR41XX=y
++# CONFIG_VRC4173 is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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=y
+@@ -120,19 +155,44 @@ CONFIG_CPU_VR41XX=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_VR41XX=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# 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 is not set
+ # CONFIG_CPU_ADVANCED is not set
+ 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+ # Bus options (PCI, PCMCIA, EISA, ISA, TC)
+ #
+ CONFIG_HW_HAS_PCI=y
+-# CONFIG_PCI is not set
++CONFIG_PCI=y
++# CONFIG_PCI_LEGACY_PROC is not set
+ CONFIG_MMU=y
+ 
+ #
+@@ -141,12 +201,9 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
++# CONFIG_HOTPLUG_PCI is not set
+ 
+ #
+ # Executable file formats
+@@ -156,6 +213,87 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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=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_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_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -167,6 +305,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_FW_LOADER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -183,19 +326,21 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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=m
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
+ CONFIG_BLK_DEV_RAM=m
+ CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
++# CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+ # IO Schedulers
+@@ -209,33 +354,12 @@ 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_IDECD is not set
+-# CONFIG_BLK_DEV_IDETAPE is not set
+-# CONFIG_BLK_DEV_IDEFLOPPY is not set
+-CONFIG_BLK_DEV_IDESCSI=y
+-# CONFIG_IDE_TASK_IOCTL is not set
+-
+-#
+-# IDE chipset support/bugfixes
+-#
+-CONFIG_IDE_GENERIC=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
++# CONFIG_IDE is not set
+ 
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -245,15 +369,15 @@ CONFIG_SCSI_PROC_FS=y
+ CONFIG_BLK_DEV_SD=y
+ # CONFIG_CHR_DEV_ST is not set
+ # CONFIG_CHR_DEV_OSST is not set
+-CONFIG_BLK_DEV_SR=y
+-# CONFIG_BLK_DEV_SR_VENDOR is not set
+-CONFIG_CHR_DEV_SG=y
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
+ 
+ #
+ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+ #
+ CONFIG_SCSI_MULTI_LUN=y
+-CONFIG_SCSI_CONSTANTS=y
++# CONFIG_SCSI_CONSTANTS is not set
+ # CONFIG_SCSI_LOGGING is not set
+ 
+ #
+@@ -262,11 +386,42 @@ CONFIG_SCSI_CONSTANTS=y
+ # 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_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_SCSI_SATA 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_FC is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++CONFIG_SCSI_QLA2XXX=y
++# CONFIG_SCSI_QLA21XX is not set
++# CONFIG_SCSI_QLA22XX is not set
++# CONFIG_SCSI_QLA2300 is not set
++# CONFIG_SCSI_QLA2322 is not set
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX 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
+ 
+ #
+@@ -277,131 +432,132 @@ CONFIG_SCSI_CONSTANTS=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+ #
++# CONFIG_IEEE1394 is not set
+ 
+ #
+ # I2O device support
+ #
++# CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
++# Network device support
+ #
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=m
+-CONFIG_UNIX=y
+-# CONFIG_NET_KEY is not set
+-CONFIG_INET=y
+-CONFIG_IP_MULTICAST=y
+-CONFIG_IP_ADVANCED_ROUTER=y
+-CONFIG_IP_MULTIPLE_TABLES=y
+-CONFIG_IP_ROUTE_MULTIPATH=y
+-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_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
+ 
+ #
+-# SCTP Configuration (EXPERIMENTAL)
++# ARCnet devices
+ #
+-# 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
++# CONFIG_ARCNET is not set
+ 
+ #
+-# QoS and/or fair queueing
++# PHY device support
+ #
+-# CONFIG_NET_SCHED is not set
+-# CONFIG_NET_CLS_ROUTE is not set
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
+ 
+ #
+-# Network testing
++# MII PHY device drivers
+ #
+-# 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
+-# CONFIG_ETHERTAP is not set
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+-# CONFIG_MII is not set
++CONFIG_MII=y
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM 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=y
++# CONFIG_E100 is not set
++# 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_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
+ 
+ #
+ # Token Ring devices
+ #
++# CONFIG_TR is not set
+ 
+ #
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW2200 is not set
+ 
+ #
+ # Wan interfaces
+ #
+ # CONFIG_WAN is not set
+-CONFIG_PPP=m
+-CONFIG_PPP_MULTILINK=y
+-# CONFIG_PPP_FILTER is not set
+-CONFIG_PPP_ASYNC=m
+-CONFIG_PPP_SYNC_TTY=m
+-CONFIG_PPP_DEFLATE=m
+-CONFIG_PPP_BSDCOMP=m
+-CONFIG_PPPOE=m
++# 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
+@@ -421,28 +577,13 @@ 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_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 I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_I8042=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -452,6 +593,12 @@ CONFIG_SERIO_RAW=m
+ # 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
+@@ -462,16 +609,16 @@ CONFIG_HW_CONSOLE=y
+ #
+ # Serial drivers
+ #
+-CONFIG_SERIAL_8250=y
+-CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=4
+-# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250 is not set
+ 
+ #
+ # Non-8250 serial port support
+ #
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_VR41XX=y
++CONFIG_SERIAL_VR41XX_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -489,14 +636,22 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_GEN_RTC is not set
+ # CONFIG_DTLK is not set
+ # CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_TANBAC_TB0219 is not set
+ 
+ #
+ # Ftape, the floppy tape device driver
+ #
+ # CONFIG_DRM is not set
++CONFIG_GPIO_VR41XX=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -507,10 +662,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -523,48 +688,147 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
+-CONFIG_FB=y
+-# CONFIG_FB_MODE_HELPERS is not set
+-# CONFIG_FB_TILEBLITTING is not set
+-# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_FRAMEBUFFER_CONSOLE is not set
+ 
+ #
+-# Logo configuration
++# Sound
+ #
+-# CONFIG_LOGO is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++# CONFIG_SOUND is not set
+ 
+ #
+-# Sound
++# USB support
+ #
+-CONFIG_SOUND=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
+ 
+ #
+-# Advanced Linux Sound Architecture
++# Miscellaneous USB options
+ #
+-# CONFIG_SND is not set
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
+ 
+ #
+-# Open Sound System
++# USB Host Controller Drivers
+ #
+-# CONFIG_SOUND_PRIME is not set
++CONFIG_USB_EHCI_HCD=y
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++# CONFIG_USB_EHCI_ROOT_HUB_TT 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 support
++# USB Device Class drivers
+ #
+-# CONFIG_USB_ARCH_HAS_HCD is not set
+-# CONFIG_USB_ARCH_HAS_OHCI is not set
++# 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=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_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
++
++#
++# 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_YEALINK is not set
++# CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE 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 Multimedia devices
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# 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_CYTHERM is not set
++# CONFIG_USB_PHIDGETKIT is not set
++# CONFIG_USB_PHIDGETSERVO is not set
++# CONFIG_USB_IDMOUSE 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
+@@ -582,39 +846,41 @@ CONFIG_SOUND=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN 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_JBD 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_MINIX_FS is not set
+ CONFIG_ROMFS_FS=m
++CONFIG_INOTIFY=y
+ # CONFIG_QUOTA is not set
+ CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+ #
+-CONFIG_ISO9660_FS=y
+-CONFIG_JOLIET=y
+-CONFIG_ZISOFS=y
+-CONFIG_ZISOFS_FS=y
++# 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_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
+ # CONFIG_NTFS_FS is not set
+ 
+ #
+@@ -623,13 +889,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -653,16 +916,19 @@ CONFIG_CRAMFS=m
+ #
+ 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=m
+ CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
+ # CONFIG_NFSD_V4 is not set
+ # CONFIG_NFSD_TCP is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+ CONFIG_LOCKD_V4=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -673,6 +939,7 @@ CONFIG_SMB_NLS_REMOTE="cp932"
+ # 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
+@@ -732,9 +999,11 @@ CONFIG_NLS_ISO8859_1=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+-CONFIG_CMDLINE=""
++CONFIG_CMDLINE="mem=32M console=ttyVR0,115200"
+ 
+ #
+ # Security options
+@@ -746,7 +1015,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -756,9 +1049,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_ZLIB_INFLATE=y
++CONFIG_CRC16=m
++CONFIG_CRC32=m
++CONFIG_LIBCRC32C=m
++CONFIG_ZLIB_INFLATE=m
+ CONFIG_ZLIB_DEFLATE=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
+diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
+--- a/arch/mips/configs/tb0229_defconfig
++++ b/arch/mips/configs/tb0229_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:12 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:27:13 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,58 +59,87 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-CONFIG_MACH_VR41XX=y
+-# CONFIG_NEC_CMBVR4133 is not set
+-# CONFIG_CASIO_E55 is not set
+-# CONFIG_IBM_WORKPAD is not set
+-# CONFIG_TANBAC_TB0226 is not set
+-CONFIG_TANBAC_TB0229=y
+-CONFIG_TANBAC_TB0219=y
+-# CONFIG_VICTOR_MPC30X is not set
+-# CONFIG_ZAO_CAPCELLA is not set
+-CONFIG_PCI_VR41XX=y
+-# CONFIG_VRC4173 is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++CONFIG_MACH_VR41XX=y
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_NEC_CMBVR4133 is not set
++# CONFIG_CASIO_E55 is not set
++# CONFIG_IBM_WORKPAD is not set
++CONFIG_TANBAC_TB022X=y
++# CONFIG_TANBAC_TB0226 is not set
++# CONFIG_VICTOR_MPC30X is not set
++# CONFIG_ZAO_CAPCELLA is not set
++CONFIG_PCI_VR41XX=y
++# CONFIG_VRC4173 is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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=y
+@@ -123,12 +155,36 @@ CONFIG_CPU_VR41XX=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_VR41XX=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# 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 is not set
+ # CONFIG_CPU_ADVANCED is not set
+ 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -136,8 +192,7 @@ CONFIG_CPU_HAS_SYNC=y
+ #
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+-CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
++# CONFIG_PCI_LEGACY_PROC is not set
+ CONFIG_MMU=y
+ 
+ #
+@@ -146,10 +201,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+@@ -162,6 +213,88 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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=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_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=m
++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 is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -170,7 +303,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -189,7 +327,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -199,11 +336,11 @@ CONFIG_BLK_DEV_LOOP=m
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ CONFIG_BLK_DEV_NBD=m
+ # 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_INITRD is not set
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -226,6 +363,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -236,6 +374,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -248,83 +387,13 @@ CONFIG_ATA_OVER_ETH=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_NETLINK_DEV=m
+-CONFIG_UNIX=y
+-# CONFIG_NET_KEY is not set
+-CONFIG_INET=y
+-CONFIG_IP_MULTICAST=y
+-CONFIG_IP_ADVANCED_ROUTER=y
+-CONFIG_IP_MULTIPLE_TABLES=y
+-CONFIG_IP_ROUTE_MULTIPATH=y
+-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=m
+-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 is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
++# Network device support
+ #
+-# 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=m
+ # CONFIG_BONDING is not set
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -332,6 +401,21 @@ CONFIG_DUMMY=m
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -346,7 +430,7 @@ CONFIG_MII=y
+ # CONFIG_NET_TULIP is not set
+ # CONFIG_HP100 is not set
+ CONFIG_NET_PCI=y
+-CONFIG_PCNET32=y
++# CONFIG_PCNET32 is not set
+ # CONFIG_AMD8111_ETH is not set
+ # CONFIG_ADAPTEC_STARFIRE is not set
+ # CONFIG_B44 is not set
+@@ -358,7 +442,11 @@ CONFIG_EEPRO100=y
+ # CONFIG_NATSEMI is not set
+ # CONFIG_NE2K_PCI is not set
+ # CONFIG_8139CP is not set
+-# CONFIG_8139TOO is not set
++CONFIG_8139TOO=y
++CONFIG_8139TOO_PIO=y
++# 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
+@@ -375,14 +463,19 @@ CONFIG_EEPRO100=y
+ # CONFIG_NS83820 is not set
+ # CONFIG_HAMACHI is not set
+ # CONFIG_YELLOWFIN is not set
+-# CONFIG_R8169 is not set
++CONFIG_R8169=y
++# CONFIG_R8169_NAPI is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE 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
+ 
+@@ -395,6 +488,8 @@ CONFIG_EEPRO100=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -416,6 +511,8 @@ CONFIG_SLIP_SMART=y
+ CONFIG_SLIP_MODE_SLIP6=y
+ # CONFIG_SHAPER is not set
+ # CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
+ 
+ #
+ # ISDN subsystem
+@@ -435,29 +532,13 @@ 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_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 I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_I8042=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -467,6 +548,12 @@ CONFIG_SERIO_RAW=m
+ # 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
+@@ -477,16 +564,16 @@ CONFIG_HW_CONSOLE=y
+ #
+ # Serial drivers
+ #
+-CONFIG_SERIAL_8250=y
+-CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=4
+-# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250 is not set
+ 
+ #
+ # Non-8250 serial port support
+ #
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_VR41XX=y
++CONFIG_SERIAL_VR41XX_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -505,14 +592,21 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_DTLK is not set
+ # CONFIG_R3964 is not set
+ # CONFIG_APPLICOM is not set
++CONFIG_TANBAC_TB0219=y
+ 
+ #
+ # Ftape, the floppy tape device driver
+ #
+ # CONFIG_DRM is not set
++CONFIG_GPIO_VR41XX=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -523,10 +617,20 @@ CONFIG_LEGACY_PTY_COUNT=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -546,7 +650,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_VGA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -556,13 +659,122 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB=m
++# 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_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++# 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_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 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_YEALINK is not set
++# CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE 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 Multimedia devices
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# 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_CYTHERM is not set
++# CONFIG_USB_PHIDGETKIT is not set
++# CONFIG_USB_PHIDGETSERVO is not set
++# CONFIG_USB_IDMOUSE 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
+@@ -580,10 +792,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+ # 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
+@@ -597,18 +814,22 @@ CONFIG_JFS_FS=m
+ # CONFIG_JFS_SECURITY is not set
+ # CONFIG_JFS_DEBUG is not set
+ # CONFIG_JFS_STATISTICS is not set
++# CONFIG_FS_POSIX_ACL is not set
+ CONFIG_XFS_FS=y
+-# CONFIG_XFS_RT is not set
++CONFIG_XFS_EXPORT=y
+ CONFIG_XFS_QUOTA=y
+ # CONFIG_XFS_SECURITY is not set
+ CONFIG_XFS_POSIX_ACL=y
++# CONFIG_XFS_RT is not set
+ # CONFIG_MINIX_FS is not set
+ CONFIG_ROMFS_FS=m
++CONFIG_INOTIFY=y
+ # CONFIG_QUOTA is not set
+ CONFIG_QUOTACTL=y
+ CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -635,13 +856,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS_XATTR=y
+-CONFIG_DEVPTS_FS_SECURITY=y
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -665,16 +883,19 @@ CONFIG_CRAMFS=m
+ #
+ 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=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=y
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+@@ -685,6 +906,7 @@ CONFIG_SMB_NLS_REMOTE="cp932"
+ # 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
+@@ -744,9 +966,11 @@ CONFIG_NLS_ISO8859_1=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+-CONFIG_CMDLINE="mem=64M console=ttyS0,38400 ip=bootp root=/dev/nfs"
++CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
+ 
+ #
+ # Security options
+@@ -758,7 +982,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -768,9 +1016,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
+ CONFIG_CRC32=y
+-# CONFIG_LIBCRC32C is not set
++CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=y
+ CONFIG_ZLIB_DEFLATE=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
+diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
+--- a/arch/mips/configs/tb0287_defconfig
++++ b/arch/mips/configs/tb0287_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.13-mm1
+-# Thu Sep  1 22:58:34 2005
++# Linux kernel version: 2.6.14-rc5-mm1
++# Tue Oct 25 00:20:22 2005
+ #
+ CONFIG_MIPS=y
+ 
+@@ -19,6 +19,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
+ CONFIG_LOCALVERSION=""
+ CONFIG_LOCALVERSION_AUTO=y
+ CONFIG_SWAP=y
++CONFIG_SWAP_PREFETCH=y
+ CONFIG_SYSVIPC=y
+ # CONFIG_POSIX_MQUEUE is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+@@ -55,74 +56,91 @@ CONFIG_OBSOLETE_MODPARM=y
+ CONFIG_MODVERSIONS=y
+ CONFIG_MODULE_SRCVERSION_ALL=y
+ CONFIG_KMOD=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
+ 
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-CONFIG_MACH_VR41XX=y
+-# CONFIG_NEC_CMBVR4133 is not set
+-# CONFIG_CASIO_E55 is not set
+-# CONFIG_IBM_WORKPAD is not set
+-CONFIG_TANBAC_TB022X=y
+-# CONFIG_TANBAC_TB0226 is not set
+-CONFIG_TANBAC_TB0287=y
+-# CONFIG_VICTOR_MPC30X is not set
+-# CONFIG_ZAO_CAPCELLA is not set
+-CONFIG_PCI_VR41XX=y
+-# CONFIG_VRC4173 is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
++CONFIG_MACH_VR41XX=y
++# CONFIG_PMC_YOSEMITE is not set
+ # CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+ # CONFIG_SGI_IP27 is not set
+ # CONFIG_SGI_IP32 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CASIO_E55 is not set
++# CONFIG_IBM_WORKPAD is not set
++# CONFIG_NEC_CMBVR4133 is not set
++CONFIG_TANBAC_TB022X=y
++# CONFIG_TANBAC_TB0226 is not set
++CONFIG_TANBAC_TB0287=y
++# CONFIG_VICTOR_MPC30X is not set
++# CONFIG_ZAO_CAPCELLA is not set
++CONFIG_PCI_VR41XX=y
++# CONFIG_VRC4173 is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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=y
+@@ -138,12 +156,25 @@ CONFIG_CPU_VR41XX=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++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_MIPS_MT is not set
+ # CONFIG_CPU_ADVANCED is not set
+ 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
+@@ -152,6 +183,9 @@ CONFIG_FLATMEM_MANUAL=y
+ CONFIG_FLATMEM=y
+ CONFIG_FLAT_NODE_MEM_MAP=y
+ # CONFIG_SPARSEMEM_STATIC is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -262,7 +296,6 @@ CONFIG_TCP_CONG_HTCP=m
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+-# CONFIG_NETFILTER_NETLINK is not set
+ # CONFIG_HAMRADIO is not set
+ # CONFIG_IRDA is not set
+ # CONFIG_BT is not set
+@@ -280,6 +313,11 @@ 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 is not set
+@@ -296,7 +334,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -312,6 +349,7 @@ CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+ # CONFIG_BLK_DEV_INITRD is not set
+ # CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+@@ -321,6 +359,11 @@ 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_ATA_OVER_ETH is not set
+ 
+ #
+@@ -410,13 +453,20 @@ CONFIG_BLK_DEV_SD=y
+ # 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 Transport Layers
++#
++# CONFIG_SAS_CLASS is not set
+ 
+ #
+ # SCSI low-level drivers
+ #
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_ARCMSR is not set
+ # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+ # CONFIG_SCSI_3W_9XXX is not set
+-# CONFIG_SCSI_ARCMSR is not set
+ # CONFIG_SCSI_ACARD is not set
+ # CONFIG_SCSI_AACRAID is not set
+ # CONFIG_SCSI_AIC7XXX is not set
+@@ -425,12 +475,10 @@ CONFIG_BLK_DEV_SD=y
+ # 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_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
+@@ -462,6 +510,7 @@ CONFIG_SCSI_QLA2XXX=y
+ # 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
+@@ -529,6 +578,7 @@ 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
+ 
+ #
+@@ -572,6 +622,7 @@ CONFIG_R8169=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_HOSTAP is not set
+ 
+ #
+ # Wan interfaces
+@@ -682,6 +733,7 @@ CONFIG_GPIO_VR41XX=y
+ # TPM devices
+ #
+ # CONFIG_TCG_TPM is not set
++# CONFIG_TELCLOCK is not set
+ 
+ #
+ # I2C support
+@@ -770,12 +822,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+ #
+ # 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
++# 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
+@@ -891,6 +946,11 @@ CONFIG_USB_MON=y
+ #
+ 
+ #
++# EDAC - error detection and reporting (RAS)
++#
++# CONFIG_EDAC is not set
++
++#
+ # Distributed Lock Manager
+ #
+ # CONFIG_DLM is not set
+@@ -901,20 +961,22 @@ CONFIG_USB_MON=y
+ 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_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_REISER4_FS is not set
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_JFS_FS is not set
+ # CONFIG_FS_POSIX_ACL is not set
+-
+-#
+-# XFS support
+-#
+ CONFIG_XFS_FS=y
+-# CONFIG_XFS_RT is not set
+ CONFIG_XFS_QUOTA=y
+ # CONFIG_XFS_SECURITY is not set
+ CONFIG_XFS_POSIX_ACL=y
++# CONFIG_XFS_RT is not set
+ # CONFIG_OCFS2_FS is not set
+ # CONFIG_MINIX_FS is not set
+ CONFIG_ROMFS_FS=m
+@@ -948,8 +1010,8 @@ CONFIG_SYSFS=y
+ CONFIG_TMPFS=y
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
+-# CONFIG_CONFIGFS_FS is not set
+ # CONFIG_RELAYFS_FS is not set
++# CONFIG_CONFIGFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -1004,6 +1066,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_PRINTK_TIME is not set
+@@ -1036,6 +1103,3 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ CONFIG_CRC32=y
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_ZLIB_INFLATE=m
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
+-CONFIG_ISA_DMA_API=y
+diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
+--- a/arch/mips/configs/workpad_defconfig
++++ b/arch/mips/configs/workpad_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:12 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:27:16 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,24 +11,29 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ # CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -41,6 +43,7 @@ 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
+@@ -56,56 +59,84 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-CONFIG_MACH_VR41XX=y
+-# CONFIG_NEC_CMBVR4133 is not set
+-# CONFIG_CASIO_E55 is not set
+-CONFIG_IBM_WORKPAD=y
+-# CONFIG_TANBAC_TB0226 is not set
+-# CONFIG_TANBAC_TB0229 is not set
+-# CONFIG_VICTOR_MPC30X is not set
+-# CONFIG_ZAO_CAPCELLA is not set
+-CONFIG_VRC4171=y
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++CONFIG_MACH_VR41XX=y
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_NEC_CMBVR4133 is not set
++# CONFIG_CASIO_E55 is not set
++CONFIG_IBM_WORKPAD=y
++# CONFIG_TANBAC_TB022X is not set
++# CONFIG_VICTOR_MPC30X is not set
++# CONFIG_ZAO_CAPCELLA is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_DMA_NEED_PCI_MAP_STATE=y
++# CONFIG_CPU_BIG_ENDIAN is not set
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ 
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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=y
+@@ -121,12 +152,36 @@ CONFIG_CPU_VR41XX=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_VR41XX=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# 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 is not set
+ # CONFIG_CPU_ADVANCED is not set
+ 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_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
+ 
+ #
+@@ -138,11 +193,17 @@ CONFIG_MMU=y
+ #
+ # PCCARD (PCMCIA/CardBus) support
+ #
+-# CONFIG_PCCARD is not set
++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_I82365 is not set
++# CONFIG_TCIC is not set
+ CONFIG_PCMCIA_PROBE=y
+ 
+ #
+@@ -157,6 +218,78 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++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 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=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_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -165,7 +298,12 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=y
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
+ 
+ #
+ # Memory Technology Devices (MTD)
+@@ -185,18 +323,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD is not set
+-# CONFIG_BLK_DEV_XD 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_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
++# CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+ # IO Schedulers
+@@ -219,6 +352,7 @@ CONFIG_BLK_DEV_IDE=y
+ # CONFIG_BLK_DEV_IDE_SATA is not set
+ CONFIG_BLK_DEV_IDEDISK=y
+ # CONFIG_IDEDISK_MULTI_MODE is not set
++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
+@@ -237,6 +371,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -252,6 +387,7 @@ CONFIG_IDE_GENERIC=y
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -262,76 +398,13 @@ CONFIG_IDE_GENERIC=y
+ #
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
++# Network device support
+ #
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=y
+-CONFIG_INET=y
+-CONFIG_IP_MULTICAST=y
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-# 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 is not set
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -339,12 +412,26 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+-# CONFIG_MII is not set
++CONFIG_MII=m
+ # 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
+ # CONFIG_AT1700 is not set
+@@ -373,6 +460,19 @@ CONFIG_NET_ETHERNET=y
+ # CONFIG_NET_RADIO is not set
+ 
+ #
++# 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
+@@ -380,6 +480,8 @@ CONFIG_NET_ETHERNET=y
+ # 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
+@@ -409,18 +511,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_I8042=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_LIBPS2 is not set
+-CONFIG_SERIO_RAW=m
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -430,6 +520,16 @@ CONFIG_SERIO_RAW=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_LIBPS2 is not set
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -440,16 +540,15 @@ CONFIG_HW_CONSOLE=y
+ #
+ # Serial drivers
+ #
+-CONFIG_SERIAL_8250=y
+-CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=4
+-# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250 is not set
+ 
+ #
+ # Non-8250 serial port support
+ #
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_VR41XX=y
++CONFIG_SERIAL_VR41XX_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -484,10 +583,19 @@ CONFIG_WATCHDOG=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_SYNCLINK_CS is not set
++# CONFIG_GPIO_VR41XX is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -498,10 +606,20 @@ CONFIG_WATCHDOG=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -522,7 +640,6 @@ CONFIG_WATCHDOG=y
+ # CONFIG_VGA_CONSOLE is not set
+ # CONFIG_MDA_CONSOLE is not set
+ CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -536,10 +653,6 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -552,7 +665,10 @@ CONFIG_DUMMY_CONSOLE=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN Devices
++#
+ 
+ #
+ # File systems
+@@ -561,6 +677,7 @@ 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 is not set
+ # CONFIG_JBD is not set
+ CONFIG_FS_MBCACHE=y
+@@ -570,10 +687,12 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_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=y
+ CONFIG_AUTOFS4_FS=y
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -594,12 +713,10 @@ CONFIG_AUTOFS4_FS=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -630,6 +747,7 @@ CONFIG_NFSD=y
+ # CONFIG_NFSD_TCP is not set
+ CONFIG_LOCKD=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
+@@ -638,6 +756,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -658,9 +777,11 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+-CONFIG_CMDLINE=""
++CONFIG_CMDLINE="console=ttyVR0,19200 mem=16M"
+ 
+ #
+ # Security options
+@@ -672,7 +793,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -682,7 +827,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=m
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=m
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
+--- a/arch/mips/configs/yosemite_defconfig
++++ b/arch/mips/configs/yosemite_defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:49:13 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:27:18 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,25 +11,31 @@ CONFIG_32BIT=y
+ # CONFIG_EXPERIMENTAL is not set
+ CONFIG_CLEAN_COMPILE=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_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=14
+-# CONFIG_HOTPLUG is not set
++CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++# CONFIG_CPUSETS is not set
++CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_EMBEDDED=y
+ 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 is not set
+@@ -42,6 +45,7 @@ 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
+@@ -56,34 +60,68 @@ CONFIG_STOP_MACHINE=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-CONFIG_PMC_YOSEMITE=y
+-# CONFIG_HYPERTRANSPORT 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++CONFIG_PMC_YOSEMITE=y
++# CONFIG_QEMU is not set
+ # CONFIG_SGI_IP22 is not set
+-# CONFIG_SOC_AU1X00 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_HYPERTRANSPORT is not set
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=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
+@@ -93,8 +131,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -110,20 +150,43 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
+ # 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 is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=y
+ CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
+ CONFIG_HIGHMEM=y
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_SYS_SUPPORTS_HIGHMEM=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ CONFIG_SMP=y
+ CONFIG_NR_CPUS=2
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
+ # CONFIG_PREEMPT is not set
++CONFIG_PREEMPT_BKL=y
+ 
+ #
+ # Bus options (PCI, PCMCIA, EISA, ISA, TC)
+@@ -131,7 +194,7 @@ CONFIG_NR_CPUS=2
+ CONFIG_HW_HAS_PCI=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
++# CONFIG_PCI_DEBUG is not set
+ CONFIG_MMU=y
+ 
+ #
+@@ -140,10 +203,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -155,6 +214,69 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=m
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
++# 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_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=m
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_BIC=y
++CONFIG_IPV6=m
++CONFIG_IPV6_PRIVACY=y
++CONFIG_INET6_AH=m
++CONFIG_INET6_ESP=m
++CONFIG_INET6_IPCOMP=m
++CONFIG_INET6_TUNNEL=m
++CONFIG_IPV6_TUNNEL=m
++# 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
++
++#
+ # Device Drivers
+ #
+ 
+@@ -163,10 +285,15 @@ CONFIG_TRAD_SIGNALS=y
+ #
+ CONFIG_STANDALONE=y
+ CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
++CONFIG_FW_LOADER=m
+ # CONFIG_DEBUG_DRIVER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++CONFIG_CONNECTOR=m
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -183,7 +310,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ #
+ # 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
+@@ -193,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -216,6 +341,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ # CONFIG_SCSI is not set
+ 
+ #
+@@ -226,6 +352,7 @@ CONFIG_ATA_OVER_ETH=m
+ #
+ # Fusion MPT device support
+ #
++# CONFIG_FUSION is not set
+ 
+ #
+ # IEEE 1394 (FireWire) support
+@@ -238,59 +365,8 @@ CONFIG_ATA_OVER_ETH=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
++# Network device support
+ #
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=m
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=m
+-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_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_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=m
+-CONFIG_IP_TCPDIAG=m
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-# CONFIG_NETFILTER is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-# 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
+@@ -303,6 +379,21 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -327,13 +418,16 @@ CONFIG_MII=y
+ # CONFIG_NS83820 is not set
+ # CONFIG_HAMACHI is not set
+ # CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
+ # CONFIG_SK98LIN is not set
+ # CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
+ CONFIG_TITAN_GE=y
+ 
+ #
+ # Ethernet (10000 Mbit)
+ #
++# CONFIG_CHELSIO_T1 is not set
+ # CONFIG_IXGB is not set
+ # CONFIG_S2IO is not set
+ 
+@@ -346,6 +440,8 @@ CONFIG_TITAN_GE=y
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
++# CONFIG_IPW_DEBUG is not set
++CONFIG_IPW2200=m
+ 
+ #
+ # Wan interfaces
+@@ -354,6 +450,8 @@ CONFIG_TITAN_GE=y
+ # CONFIG_FDDI is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
+ 
+ #
+ # ISDN subsystem
+@@ -371,20 +469,10 @@ CONFIG_TITAN_GE=y
+ # CONFIG_INPUT is not set
+ 
+ #
+-# Userland interfaces
+-#
+-
+-#
+-# Input I/O drivers
++# Hardware I/O ports
+ #
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+ # CONFIG_SERIO is not set
+-# CONFIG_SERIO_I8042 is not set
+-
+-#
+-# Input Device Drivers
+-#
++# CONFIG_GAMEPORT is not set
+ 
+ #
+ # Character devices
+@@ -405,6 +493,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
+ #
+ 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
+@@ -432,6 +521,10 @@ CONFIG_GEN_RTC_X=y
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -442,10 +535,20 @@ CONFIG_GEN_RTC_X=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -459,7 +562,6 @@ CONFIG_GEN_RTC_X=y
+ # Graphics support
+ #
+ # CONFIG_FB is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -469,13 +571,9 @@ CONFIG_GEN_RTC_X=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -493,6 +591,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_INFINIBAND is not set
+ 
+ #
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ # CONFIG_EXT2_FS is not set
+@@ -500,13 +602,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_JBD 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_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=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -527,11 +632,10 @@ CONFIG_DNOTIFY=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -552,7 +656,7 @@ CONFIG_NFS_FS=y
+ # CONFIG_NFSD is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_LOCKD=y
+-# CONFIG_EXPORTFS is not set
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+ # CONFIG_SMB_FS is not set
+ # CONFIG_CIFS is not set
+@@ -573,8 +677,11 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ CONFIG_DEBUG_KERNEL=y
+ # CONFIG_MAGIC_SYSRQ is not set
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_DETECT_SOFTLOCKUP=y
+ # CONFIG_SCHEDSTATS is not set
+ # CONFIG_DEBUG_SLAB is not set
+ # CONFIG_DEBUG_SPINLOCK is not set
+@@ -599,7 +706,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++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
+ 
+ #
+ # Hardware crypto devices
+@@ -609,7 +740,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CRC16=m
++CONFIG_CRC32=m
++CONFIG_LIBCRC32C=m
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+diff --git a/arch/mips/ddb5xxx/Kconfig b/arch/mips/ddb5xxx/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/ddb5xxx/Kconfig
+@@ -0,0 +1,4 @@
++config DDB5477_BUS_FREQUENCY
++	int "bus frequency (in kHZ, 0 for auto-detect)"
++	depends on DDB5477
++	default 0
+diff --git a/arch/mips/ddb5xxx/ddb5074/nile4_pic.c b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
+--- a/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
++++ b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
+@@ -209,14 +209,13 @@ static void nile4_irq_end(unsigned int i
+ #define nile4_irq_shutdown nile4_disable_irq
+ 
+ static hw_irq_controller nile4_irq_controller = {
+-    "nile4",
+-    nile4_irq_startup,
+-    nile4_irq_shutdown,
+-    nile4_enable_irq,
+-    nile4_disable_irq,
+-    nile4_ack_irq,
+-    nile4_irq_end,
+-    NULL
++	.typename = "nile4",
++	.startup = nile4_irq_startup,
++	.shutdown = nile4_irq_shutdown,
++	.enable = nile4_enable_irq,
++	.disable = nile4_disable_irq,
++	.ack = nile4_ack_irq,
++	.end = nile4_irq_end,
+ };
+ 
+ void nile4_irq_setup(u32 base) {
+diff --git a/arch/mips/ddb5xxx/ddb5074/setup.c b/arch/mips/ddb5xxx/ddb5074/setup.c
+--- a/arch/mips/ddb5xxx/ddb5074/setup.c
++++ b/arch/mips/ddb5xxx/ddb5074/setup.c
+@@ -85,7 +85,7 @@ static void __init ddb_time_init(void)
+ 
+ 
+ 
+-static void __init ddb5074_setup(void)
++void __init plat_setup(void)
+ {
+ 	set_io_port_base(NILE4_PCI_IO_BASE);
+ 	isa_slot_offset = NILE4_PCI_MEM_BASE;
+@@ -106,8 +106,6 @@ static void __init ddb5074_setup(void)
+ 	panic_timeout = 180;
+ }
+ 
+-early_initcall(ddb5074_setup);
+-
+ #define USE_NILE4_SERIAL	0
+ 
+ #if USE_NILE4_SERIAL
+diff --git a/arch/mips/ddb5xxx/ddb5476/setup.c b/arch/mips/ddb5xxx/ddb5476/setup.c
+--- a/arch/mips/ddb5xxx/ddb5476/setup.c
++++ b/arch/mips/ddb5xxx/ddb5476/setup.c
+@@ -124,7 +124,7 @@ static struct {
+ 
+ static void ddb5476_board_init(void);
+ 
+-static void __init ddb5476_setup(void)
++void __init plat_setup(void)
+ {
+ 	set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
+ 
+@@ -158,8 +158,6 @@ static void __init ddb5476_setup(void)
+ 	ddb5476_board_init();
+ }
+ 
+-early_initcall(ddb5476_setup);
+-
+ /*
+  * We don't trust bios.  We essentially does hardware re-initialization
+  * as complete as possible, as far as we know we can safely do.
+diff --git a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
+--- a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
++++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
+@@ -53,14 +53,13 @@ static void vrc5476_irq_end(uint irq)
+ }
+ 
+ static hw_irq_controller vrc5476_irq_controller = {
+-	"vrc5476",
+-	vrc5476_irq_startup,
+-	vrc5476_irq_shutdown,
+-	vrc5476_irq_enable,
+-	vrc5476_irq_disable,
+-	vrc5476_irq_ack,
+-	vrc5476_irq_end,
+-	NULL				/* no affinity stuff for UP */
++	.typename = "vrc5476",
++	.startup = vrc5476_irq_startup,
++	.shutdown = vrc5476_irq_shutdown,
++	.enable = vrc5476_irq_enable,
++	.disable = vrc5476_irq_disable,
++	.ack = vrc5476_irq_ack,
++	.end = vrc5476_irq_end
+ };
+ 
+ void __init
+diff --git a/arch/mips/ddb5xxx/ddb5477/irq_5477.c b/arch/mips/ddb5xxx/ddb5477/irq_5477.c
+--- a/arch/mips/ddb5xxx/ddb5477/irq_5477.c
++++ b/arch/mips/ddb5xxx/ddb5477/irq_5477.c
+@@ -90,14 +90,13 @@ vrc5477_irq_end(unsigned int irq)
+ }
+ 
+ hw_irq_controller vrc5477_irq_controller = {
+-	"vrc5477_irq",
+-	vrc5477_irq_startup,
+-	vrc5477_irq_shutdown,
+-	vrc5477_irq_enable,
+-	vrc5477_irq_disable,
+-	vrc5477_irq_ack,
+-	vrc5477_irq_end,
+-	NULL			/* no affinity stuff for UP */
++	.typename = "vrc5477_irq",
++	.startup = vrc5477_irq_startup,
++	.shutdown = vrc5477_irq_shutdown,
++	.enable = vrc5477_irq_enable,
++	.disable = vrc5477_irq_disable,
++	.ack = vrc5477_irq_ack,
++	.end = vrc5477_irq_end
+ };
+ 
+ void __init vrc5477_irq_init(u32 irq_base)
+diff --git a/arch/mips/ddb5xxx/ddb5477/setup.c b/arch/mips/ddb5xxx/ddb5477/setup.c
+--- a/arch/mips/ddb5xxx/ddb5477/setup.c
++++ b/arch/mips/ddb5xxx/ddb5477/setup.c
+@@ -170,7 +170,7 @@ static void ddb5477_board_init(void);
+ extern struct pci_controller ddb5477_ext_controller;
+ extern struct pci_controller ddb5477_io_controller;
+ 
+-static int  ddb5477_setup(void)
++void __init plat_setup(void)
+ {
+ 	/* initialize board - we don't trust the loader */
+         ddb5477_board_init();
+@@ -193,12 +193,8 @@ static int  ddb5477_setup(void)
+ 
+ 	register_pci_controller (&ddb5477_ext_controller);
+ 	register_pci_controller (&ddb5477_io_controller);
+-
+-	return 0;
+ }
+ 
+-early_initcall(ddb5477_setup);
+-
+ static void __init ddb5477_board_init(void)
+ {
+ 	/* ----------- setup PDARs ------------ */
+diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
+--- a/arch/mips/dec/Makefile
++++ b/arch/mips/dec/Makefile
+@@ -2,8 +2,8 @@
+ # Makefile for the DECstation family specific parts of the kernel
+ #
+ 
+-obj-y		:= ecc-berr.o int-handler.o ioasic-irq.o kn02-irq.o reset.o \
+-		   setup.o time.o
++obj-y		:= ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
++		   kn02-irq.o kn02xa-berr.o reset.o setup.o time.o
+ 
+ obj-$(CONFIG_PROM_CONSOLE)	+= promcon.o
+ obj-$(CONFIG_CPU_HAS_WB)	+= wbflush.o
+diff --git a/arch/mips/dec/ecc-berr.c b/arch/mips/dec/ecc-berr.c
+--- a/arch/mips/dec/ecc-berr.c
++++ b/arch/mips/dec/ecc-berr.c
+@@ -6,7 +6,7 @@
+  *	5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03),
+  *	5900/260 (KN05) systems.
+  *
+- *	Copyright (c) 2003  Maciej W. Rozycki
++ *	Copyright (c) 2003, 2005  Maciej W. Rozycki
+  *
+  *	This program is free software; you can redistribute it and/or
+  *	modify it under the terms of the GNU General Public License
+@@ -15,6 +15,7 @@
+  */
+ 
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/spinlock.h>
+@@ -57,7 +58,7 @@ static int dec_ecc_be_backend(struct pt_
+ 
+ 	const char *kind, *agent, *cycle, *event;
+ 	const char *status = "", *xbit = "", *fmt = "";
+-	dma_addr_t address;
++	unsigned long address;
+ 	u16 syn = 0, sngl;
+ 
+ 	int i = 0;
+@@ -66,7 +67,7 @@ static int dec_ecc_be_backend(struct pt_
+ 	u32 chksyn = *kn0x_chksyn;
+ 	int action = MIPS_BE_FATAL;
+ 
+-	/* For non-ECC ack ASAP, so any subsequent errors get caught. */
++	/* For non-ECC ack ASAP, so that any subsequent errors get caught. */
+ 	if ((erraddr & (KN0X_EAR_VALID | KN0X_EAR_ECCERR)) == KN0X_EAR_VALID)
+ 		dec_ecc_be_ack();
+ 
+@@ -74,7 +75,7 @@ static int dec_ecc_be_backend(struct pt_
+ 
+ 	if (!(erraddr & KN0X_EAR_VALID)) {
+ 		/* No idea what happened. */
+-		printk(KERN_ALERT "Unidentified bus error %s.\n", kind);
++		printk(KERN_ALERT "Unidentified bus error %s\n", kind);
+ 		return action;
+ 	}
+ 
+@@ -126,7 +127,7 @@ static int dec_ecc_be_backend(struct pt_
+ 			/* Ack now, no rewrite will happen. */
+ 			dec_ecc_be_ack();
+ 
+-			fmt = KERN_ALERT "%s" "invalid.\n";
++			fmt = KERN_ALERT "%s" "invalid\n";
+ 		} else {
+ 			sngl = syn & KN0X_ESR_SNGLO;
+ 			syn &= KN0X_ESR_SYNLO;
+@@ -144,7 +145,8 @@ static int dec_ecc_be_backend(struct pt_
+ 			} else if (!sngl) {
+ 				status = dbestr;
+ 			} else {
+-				volatile u32 *ptr = (void *)KSEG1ADDR(address);
++				volatile u32 *ptr =
++					(void *)CKSEG1ADDR(address);
+ 
+ 				*ptr = *ptr;		/* Rewrite. */
+ 				iob();
+@@ -160,12 +162,12 @@ static int dec_ecc_be_backend(struct pt_
+ 				if (syn == 0x01) {
+ 					fmt = KERN_ALERT "%s"
+ 					      "%#04x -- %s bit error "
+-					      "at check bit C%s.\n";
++					      "at check bit C%s\n";
+ 					xbit = "X";
+ 				} else {
+ 					fmt = KERN_ALERT "%s"
+ 					      "%#04x -- %s bit error "
+-					      "at check bit C%s%u.\n";
++					      "at check bit C%s%u\n";
+ 				}
+ 				i = syn >> 2;
+ 			} else {
+@@ -175,16 +177,16 @@ static int dec_ecc_be_backend(struct pt_
+ 				if (i < 32)
+ 					fmt = KERN_ALERT "%s"
+ 					      "%#04x -- %s bit error "
+-					      "at data bit D%s%u.\n";
++					      "at data bit D%s%u\n";
+ 				else
+ 					fmt = KERN_ALERT "%s"
+-					      "%#04x -- %s bit error.\n";
++					      "%#04x -- %s bit error\n";
+ 			}
+ 		}
+ 	}
+ 
+ 	if (action != MIPS_BE_FIXUP)
+-		printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx.\n",
++		printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
+ 			kind, agent, cycle, event, address);
+ 
+ 	if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR)
+@@ -203,11 +205,11 @@ irqreturn_t dec_ecc_be_interrupt(int irq
+ 	int action = dec_ecc_be_backend(regs, 0, 1);
+ 
+ 	if (action == MIPS_BE_DISCARD)
+-		return IRQ_NONE;
++		return IRQ_HANDLED;
+ 
+ 	/*
+-	 * FIXME: Find affected processes and kill them, otherwise we
+-	 * must die.
++	 * FIXME: Find the affected processes and kill them, otherwise
++	 * we must die.
+ 	 *
+ 	 * The interrupt is asynchronously delivered thus EPC and RA
+ 	 * may be irrelevant, but are printed for a reference.
+@@ -225,16 +227,16 @@ irqreturn_t dec_ecc_be_interrupt(int irq
+  */
+ static inline void dec_kn02_be_init(void)
+ {
+-	volatile u32 *csr = (void *)KN02_CSR_BASE;
++	volatile u32 *csr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR);
+ 	unsigned long flags;
+ 
+-	kn0x_erraddr = (void *)(KN02_SLOT_BASE + KN02_ERRADDR);
+-	kn0x_chksyn = (void *)(KN02_SLOT_BASE + KN02_CHKSYN);
++	kn0x_erraddr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_ERRADDR);
++	kn0x_chksyn = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CHKSYN);
+ 
+ 	spin_lock_irqsave(&kn02_lock, flags);
+ 
+ 	/* Preset write-only bits of the Control Register cache. */
+-	cached_kn02_csr = *csr | KN03_CSR_LEDS;
++	cached_kn02_csr = *csr | KN02_CSR_LEDS;
+ 
+ 	/* Set normal ECC detection and generation. */
+ 	cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN);
+@@ -248,11 +250,11 @@ static inline void dec_kn02_be_init(void
+ 
+ static inline void dec_kn03_be_init(void)
+ {
+-	volatile u32 *mcr = (void *)(KN03_SLOT_BASE + IOASIC_MCR);
+-	volatile u32 *mbcs = (void *)(KN03_SLOT_BASE + KN05_MB_CSR);
++	volatile u32 *mcr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_MCR);
++	volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
+ 
+-	kn0x_erraddr = (void *)(KN03_SLOT_BASE + IOASIC_ERRADDR);
+-	kn0x_chksyn = (void *)(KN03_SLOT_BASE + IOASIC_CHKSYN);
++	kn0x_erraddr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_ERRADDR);
++	kn0x_chksyn = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_CHKSYN);
+ 
+ 	/*
+ 	 * Set normal ECC detection and generation, enable ECC correction.
+@@ -264,7 +266,7 @@ static inline void dec_kn03_be_init(void
+ 	*mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) |
+ 	       KN03_MCR_CORRECT;
+ 	if (current_cpu_data.cputype == CPU_R4400SC)
+-		*mbcs |= KN05_MB_CSR_EE;
++		*mbcs |= KN4K_MB_CSR_EE;
+ 	fast_iob();
+ }
+ 
+diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
+--- a/arch/mips/dec/int-handler.S
++++ b/arch/mips/dec/int-handler.S
+@@ -2,9 +2,9 @@
+  * arch/mips/dec/int-handler.S
+  *
+  * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
+- * Copyright (C) 2000, 2001, 2002, 2003  Maciej W. Rozycki
++ * Copyright (C) 2000, 2001, 2002, 2003, 2005  Maciej W. Rozycki
+  *
+- * Written by Ralf Baechle and Andreas Busse, modified for DECStation
++ * Written by Ralf Baechle and Andreas Busse, modified for DECstation
+  * support by Paul Antoine and Harald Koerfgen.
+  *
+  * completly rewritten:
+@@ -14,11 +14,12 @@
+  * by Maciej W. Rozycki.
+  */
+ #include <linux/config.h>
++
++#include <asm/addrspace.h>
+ #include <asm/asm.h>
+-#include <asm/regdef.h>
+ #include <asm/mipsregs.h>
++#include <asm/regdef.h>
+ #include <asm/stackframe.h>
+-#include <asm/addrspace.h>
+ 
+ #include <asm/dec/interrupts.h>
+ #include <asm/dec/ioasic_addrs.h>
+@@ -28,11 +29,14 @@
+ #include <asm/dec/kn02xa.h>
+ #include <asm/dec/kn03.h>
+ 
++#define KN02_CSR_BASE		CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR)
++#define KN02XA_IOASIC_BASE	CKSEG1ADDR(KN02XA_SLOT_BASE + IOASIC_IOCTL)
++#define KN03_IOASIC_BASE	CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_IOCTL)
+ 
+ 		.text
+ 		.set	noreorder
+ /*
+- * decstation_handle_int: Interrupt handler for DECStations
++ * decstation_handle_int: Interrupt handler for DECstations
+  *
+  * We follow the model in the Indy interrupt code by David Miller, where he
+  * says: a lot of complication here is taken away because:
+@@ -48,7 +52,7 @@
+  * 3) Linux only thinks in terms of all IRQs on or all IRQs
+  *    off, nothing in between like BSD spl() brain-damage.
+  *
+- * Furthermore, the IRQs on the DECStations look basically (barring
++ * Furthermore, the IRQs on the DECstations look basically (barring
+  * software IRQs which we don't use at all) like...
+  *
+  * DS2100/3100's, aka kn01, aka Pmax:
+@@ -61,7 +65,7 @@
+  *             3        Lance Ethernet
+  *             4        DZ11 serial
+  *             5        RTC
+- *             6        Memory Controller
++ *             6        Memory Controller & Video
+  *             7        FPU
+  *
+  * DS5000/200, aka kn02, aka 3max:
+diff --git a/arch/mips/dec/kn01-berr.c b/arch/mips/dec/kn01-berr.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/dec/kn01-berr.c
+@@ -0,0 +1,201 @@
++/*
++ *	linux/arch/mips/dec/kn01-berr.c
++ *
++ *	Bus error event handling code for DECstation/DECsystem 3100
++ *	and 2100 (KN01) systems equipped with parity error detection
++ *	logic.
++ *
++ *	Copyright (c) 2005  Maciej W. Rozycki
++ *
++ *	This program is free software; you can redistribute it and/or
++ *	modify it under the terms of the 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/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++
++#include <asm/inst.h>
++#include <asm/mipsregs.h>
++#include <asm/page.h>
++#include <asm/system.h>
++#include <asm/traps.h>
++#include <asm/uaccess.h>
++
++#include <asm/dec/kn01.h>
++
++
++/* CP0 hazard avoidance. */
++#define BARRIER				\
++	__asm__ __volatile__(		\
++		".set	push\n\t"	\
++		".set	noreorder\n\t"	\
++		"nop\n\t"		\
++		".set	pop\n\t")
++
++/*
++ * Bits 7:0 of the Control Register are write-only -- the
++ * corresponding bits of the Status Register have a different
++ * meaning.  Hence we use a cache.  It speeds up things a bit
++ * as well.
++ *
++ * There is no default value -- it has to be initialized.
++ */
++u16 cached_kn01_csr;
++DEFINE_SPINLOCK(kn01_lock);
++
++
++static inline void dec_kn01_be_ack(void)
++{
++	volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
++	unsigned long flags;
++
++	spin_lock_irqsave(&kn01_lock, flags);
++
++	*csr = cached_kn01_csr | KN01_CSR_MEMERR;	/* Clear bus IRQ. */
++	iob();
++
++	spin_unlock_irqrestore(&kn01_lock, flags);
++}
++
++static int dec_kn01_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
++{
++	volatile u32 *kn01_erraddr = (void *)CKSEG1ADDR(KN01_SLOT_BASE +
++							KN01_ERRADDR);
++
++	static const char excstr[] = "exception";
++	static const char intstr[] = "interrupt";
++	static const char cpustr[] = "CPU";
++	static const char mreadstr[] = "memory read";
++	static const char readstr[] = "read";
++	static const char writestr[] = "write";
++	static const char timestr[] = "timeout";
++	static const char paritystr[] = "parity error";
++
++	int data = regs->cp0_cause & 4;
++	unsigned int __user *pc = (unsigned int __user *)regs->cp0_epc +
++				  ((regs->cp0_cause & CAUSEF_BD) != 0);
++	union mips_instruction insn;
++	unsigned long entrylo, offset;
++	long asid, entryhi, vaddr;
++
++	const char *kind, *agent, *cycle, *event;
++	unsigned long address;
++
++	u32 erraddr = *kn01_erraddr;
++	int action = MIPS_BE_FATAL;
++
++	/* Ack ASAP, so that any subsequent errors get caught. */
++	dec_kn01_be_ack();
++
++	kind = invoker ? intstr : excstr;
++
++	agent = cpustr;
++
++	if (invoker)
++		address = erraddr;
++	else {
++		/* Bloody hardware doesn't record the address for reads... */
++		if (data) {
++			/* This never faults. */
++			__get_user(insn.word, pc);
++			vaddr = regs->regs[insn.i_format.rs] +
++				insn.i_format.simmediate;
++		} else
++			vaddr = (long)pc;
++		if (KSEGX(vaddr) == CKSEG0 || KSEGX(vaddr) == CKSEG1)
++			address = CPHYSADDR(vaddr);
++		else {
++			/* Peek at what physical address the CPU used. */
++			asid = read_c0_entryhi();
++			entryhi = asid & (PAGE_SIZE - 1);
++			entryhi |= vaddr & ~(PAGE_SIZE - 1);
++			write_c0_entryhi(entryhi);
++			BARRIER;
++			tlb_probe();
++			/* No need to check for presence. */
++			tlb_read();
++			entrylo = read_c0_entrylo0();
++			write_c0_entryhi(asid);
++			offset = vaddr & (PAGE_SIZE - 1);
++			address = (entrylo & ~(PAGE_SIZE - 1)) | offset;
++		}
++	}
++
++	/* Treat low 256MB as memory, high -- as I/O. */
++	if (address < 0x10000000) {
++		cycle = mreadstr;
++		event = paritystr;
++	} else {
++		cycle = invoker ? writestr : readstr;
++		event = timestr;
++	}
++
++	if (is_fixup)
++		action = MIPS_BE_FIXUP;
++
++	if (action != MIPS_BE_FIXUP)
++		printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
++			kind, agent, cycle, event, address);
++
++	return action;
++}
++
++int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup)
++{
++	return dec_kn01_be_backend(regs, is_fixup, 0);
++}
++
++irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id,
++				    struct pt_regs *regs)
++{
++	volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
++	int action;
++
++	if (!(*csr & KN01_CSR_MEMERR))
++		return IRQ_NONE;		/* Must have been video. */
++
++	action = dec_kn01_be_backend(regs, 0, 1);
++
++	if (action == MIPS_BE_DISCARD)
++		return IRQ_HANDLED;
++
++	/*
++	 * FIXME: Find the affected processes and kill them, otherwise
++	 * we must die.
++	 *
++	 * The interrupt is asynchronously delivered thus EPC and RA
++	 * may be irrelevant, but are printed for a reference.
++	 */
++	printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
++	       regs->cp0_epc, regs->regs[31]);
++	die("Unrecoverable bus error", regs);
++}
++
++
++void __init dec_kn01_be_init(void)
++{
++	volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
++	unsigned long flags;
++
++	spin_lock_irqsave(&kn01_lock, flags);
++
++	/* Preset write-only bits of the Control Register cache. */
++	cached_kn01_csr = *csr;
++	cached_kn01_csr &= KN01_CSR_STATUS | KN01_CSR_PARDIS | KN01_CSR_TXDIS;
++	cached_kn01_csr |= KN01_CSR_LEDS;
++
++	/* Enable parity error detection. */
++	cached_kn01_csr &= ~KN01_CSR_PARDIS;
++	*csr = cached_kn01_csr;
++	iob();
++
++	spin_unlock_irqrestore(&kn01_lock, flags);
++
++	/* Clear any leftover errors from the firmware. */
++	dec_kn01_be_ack();
++}
+diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
+--- a/arch/mips/dec/kn02-irq.c
++++ b/arch/mips/dec/kn02-irq.c
+@@ -4,7 +4,7 @@
+  *	DECstation 5000/200 (KN02) Control and Status Register
+  *	interrupts.
+  *
+- *	Copyright (c) 2002, 2003  Maciej W. Rozycki
++ *	Copyright (c) 2002, 2003, 2005  Maciej W. Rozycki
+  *
+  *	This program is free software; you can redistribute it and/or
+  *	modify it under the terms of the GNU General Public License
+@@ -37,7 +37,8 @@ static int kn02_irq_base;
+ 
+ static inline void unmask_kn02_irq(unsigned int irq)
+ {
+-	volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
++	volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
++						       KN02_CSR);
+ 
+ 	cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16));
+ 	*csr = cached_kn02_csr;
+@@ -45,7 +46,8 @@ static inline void unmask_kn02_irq(unsig
+ 
+ static inline void mask_kn02_irq(unsigned int irq)
+ {
+-	volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
++	volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
++						       KN02_CSR);
+ 
+ 	cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16));
+ 	*csr = cached_kn02_csr;
+@@ -105,13 +107,14 @@ static struct hw_interrupt_type kn02_irq
+ 
+ void __init init_kn02_irqs(int base)
+ {
+-	volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
++	volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
++						       KN02_CSR);
+ 	unsigned long flags;
+ 	int i;
+ 
+ 	/* Mask interrupts. */
+ 	spin_lock_irqsave(&kn02_lock, flags);
+-	cached_kn02_csr &= ~KN03_CSR_IOINTEN;
++	cached_kn02_csr &= ~KN02_CSR_IOINTEN;
+ 	*csr = cached_kn02_csr;
+ 	iob();
+ 	spin_unlock_irqrestore(&kn02_lock, flags);
+diff --git a/arch/mips/dec/kn02xa-berr.c b/arch/mips/dec/kn02xa-berr.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/dec/kn02xa-berr.c
+@@ -0,0 +1,139 @@
++/*
++ *	linux/arch/mips/dec/kn02xa-berr.c
++ *
++ *	Bus error event handling code for 5000-series systems equipped
++ *	with parity error detection logic, i.e. DECstation/DECsystem
++ *	5000/120, /125, /133 (KN02-BA), 5000/150 (KN04-BA) and Personal
++ *	DECstation/DECsystem 5000/20, /25, /33 (KN02-CA), 5000/50
++ *	(KN04-CA) systems.
++ *
++ *	Copyright (c) 2005  Maciej W. Rozycki
++ *
++ *	This program is free software; you can redistribute it and/or
++ *	modify it under the terms of the 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/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++
++#include <asm/addrspace.h>
++#include <asm/system.h>
++#include <asm/traps.h>
++
++#include <asm/dec/kn02ca.h>
++#include <asm/dec/kn02xa.h>
++#include <asm/dec/kn05.h>
++
++static inline void dec_kn02xa_be_ack(void)
++{
++	volatile u32 *mer = (void *)CKSEG1ADDR(KN02XA_MER);
++	volatile u32 *mem_intr = (void *)CKSEG1ADDR(KN02XA_MEM_INTR);
++
++	*mer = KN02CA_MER_INTR;		/* Clear errors; keep the ARC IRQ. */
++	*mem_intr = 0;			/* Any write clears the bus IRQ. */
++	iob();
++}
++
++static int dec_kn02xa_be_backend(struct pt_regs *regs, int is_fixup,
++				 int invoker)
++{
++	volatile u32 *kn02xa_mer = (void *)CKSEG1ADDR(KN02XA_MER);
++	volatile u32 *kn02xa_ear = (void *)CKSEG1ADDR(KN02XA_EAR);
++
++	static const char excstr[] = "exception";
++	static const char intstr[] = "interrupt";
++	static const char cpustr[] = "CPU";
++	static const char mreadstr[] = "memory read";
++	static const char readstr[] = "read";
++	static const char writestr[] = "write";
++	static const char timestr[] = "timeout";
++	static const char paritystr[] = "parity error";
++	static const char lanestat[][4] = { " OK", "BAD" };
++
++	const char *kind, *agent, *cycle, *event;
++	unsigned long address;
++
++	u32 mer = *kn02xa_mer;
++	u32 ear = *kn02xa_ear;
++	int action = MIPS_BE_FATAL;
++
++	/* Ack ASAP, so that any subsequent errors get caught. */
++	dec_kn02xa_be_ack();
++
++	kind = invoker ? intstr : excstr;
++
++	/* No DMA errors? */
++	agent = cpustr;
++
++	address = ear & KN02XA_EAR_ADDRESS;
++
++	/* Low 256MB is decoded as memory, high -- as TC. */
++	if (address < 0x10000000) {
++		cycle = mreadstr;
++		event = paritystr;
++	} else {
++		cycle = invoker ? writestr : readstr;
++		event = timestr;
++	}
++
++	if (is_fixup)
++		action = MIPS_BE_FIXUP;
++
++	if (action != MIPS_BE_FIXUP)
++		printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
++			kind, agent, cycle, event, address);
++
++	if (action != MIPS_BE_FIXUP && address < 0x10000000)
++		printk(KERN_ALERT "  Byte lane status %#3x -- "
++		       "#3: %s, #2: %s, #1: %s, #0: %s\n",
++		       (mer & KN02XA_MER_BYTERR) >> 8,
++		       lanestat[(mer & KN02XA_MER_BYTERR_3) != 0],
++		       lanestat[(mer & KN02XA_MER_BYTERR_2) != 0],
++		       lanestat[(mer & KN02XA_MER_BYTERR_1) != 0],
++		       lanestat[(mer & KN02XA_MER_BYTERR_0) != 0]);
++
++	return action;
++}
++
++int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup)
++{
++	return dec_kn02xa_be_backend(regs, is_fixup, 0);
++}
++
++irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id,
++				    struct pt_regs *regs)
++{
++	int action = dec_kn02xa_be_backend(regs, 0, 1);
++
++	if (action == MIPS_BE_DISCARD)
++		return IRQ_HANDLED;
++
++	/*
++	 * FIXME: Find the affected processes and kill them, otherwise
++	 * we must die.
++	 *
++	 * The interrupt is asynchronously delivered thus EPC and RA
++	 * may be irrelevant, but are printed for a reference.
++	 */
++	printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
++	       regs->cp0_epc, regs->regs[31]);
++	die("Unrecoverable bus error", regs);
++}
++
++
++void __init dec_kn02xa_be_init(void)
++{
++	volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
++
++        /* For KN04 we need to make sure EE (?) is enabled in the MB.  */
++        if (current_cpu_data.cputype == CPU_R4000SC)
++		*mbcs |= KN4K_MB_CSR_EE;
++	fast_iob();
++
++	/* Clear any leftover errors from the firmware. */
++	dec_kn02xa_be_ack();
++}
+diff --git a/arch/mips/dec/prom/identify.c b/arch/mips/dec/prom/identify.c
+--- a/arch/mips/dec/prom/identify.c
++++ b/arch/mips/dec/prom/identify.c
+@@ -2,7 +2,7 @@
+  * identify.c: machine identification code.
+  *
+  * Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
+- * Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
++ * Copyright (C) 2002, 2003, 2004, 2005  Maciej W. Rozycki
+  */
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -12,6 +12,7 @@
+ #include <linux/types.h>
+ 
+ #include <asm/bootinfo.h>
++
+ #include <asm/dec/ioasic.h>
+ #include <asm/dec/ioasic_addrs.h>
+ #include <asm/dec/kn01.h>
+@@ -21,6 +22,7 @@
+ #include <asm/dec/kn03.h>
+ #include <asm/dec/kn230.h>
+ #include <asm/dec/prom.h>
++#include <asm/dec/system.h>
+ 
+ #include "dectypes.h"
+ 
+@@ -68,34 +70,44 @@ EXPORT_SYMBOL(dec_rtc_base);
+ 
+ static inline void prom_init_kn01(void)
+ {
+-	dec_rtc_base = (void *)KN01_RTC_BASE;
++	dec_kn_slot_base = KN01_SLOT_BASE;
+ 	dec_kn_slot_size = KN01_SLOT_SIZE;
++
++	dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
+ }
+ 
+ static inline void prom_init_kn230(void)
+ {
+-	dec_rtc_base = (void *)KN01_RTC_BASE;
++	dec_kn_slot_base = KN01_SLOT_BASE;
+ 	dec_kn_slot_size = KN01_SLOT_SIZE;
++
++	dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
+ }
+ 
+ static inline void prom_init_kn02(void)
+ {
+-	dec_rtc_base = (void *)KN02_RTC_BASE;
++	dec_kn_slot_base = KN02_SLOT_BASE;
+ 	dec_kn_slot_size = KN02_SLOT_SIZE;
++
++	dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN02_RTC);
+ }
+ 
+ static inline void prom_init_kn02xa(void)
+ {
+-	ioasic_base = (void *)KN02XA_IOASIC_BASE;
+-	dec_rtc_base = (void *)KN02XA_RTC_BASE;
++	dec_kn_slot_base = KN02XA_SLOT_BASE;
+ 	dec_kn_slot_size = IOASIC_SLOT_SIZE;
++
++	ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
++	dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
+ }
+ 
+ static inline void prom_init_kn03(void)
+ {
+-	ioasic_base = (void *)KN03_IOASIC_BASE;
+-	dec_rtc_base = (void *)KN03_RTC_BASE;
++	dec_kn_slot_base = KN03_SLOT_BASE;
+ 	dec_kn_slot_size = IOASIC_SLOT_SIZE;
++
++	ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
++	dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
+ }
+ 
+ 
+diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c
+--- a/arch/mips/dec/prom/init.c
++++ b/arch/mips/dec/prom/init.c
+@@ -6,6 +6,8 @@
+  */
+ #include <linux/config.h>
+ #include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/linkage.h>
+ #include <linux/smp.h>
+ #include <linux/string.h>
+ #include <linux/types.h>
+@@ -85,17 +87,13 @@ void __init which_prom(s32 magic, s32 *p
+ 
+ void __init prom_init(void)
+ {
+-	extern void dec_machine_halt(void);
++	extern void ATTRIB_NORET dec_machine_halt(void);
+ 	static char cpu_msg[] __initdata =
+ 		"Sorry, this kernel is compiled for a wrong CPU type!\n";
+-	static char r3k_msg[] __initdata =
+-		"Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
+-	static char r4k_msg[] __initdata =
+-		"Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
+ 	s32 argc = fw_arg0;
+-	s32 argv = fw_arg1;
++	s32 *argv = (void *)fw_arg1;
+ 	u32 magic = fw_arg2;
+-	s32 prom_vec = fw_arg3;
++	s32 *prom_vec = (void *)fw_arg3;
+ 
+ 	/*
+ 	 * Determine which PROM we have
+@@ -113,6 +111,8 @@ void __init prom_init(void)
+ #if defined(CONFIG_CPU_R3000)
+ 	if ((current_cpu_data.cputype == CPU_R4000SC) ||
+ 	    (current_cpu_data.cputype == CPU_R4400SC)) {
++		static char r4k_msg[] __initdata =
++			"Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
+ 		printk(cpu_msg);
+ 		printk(r4k_msg);
+ 		dec_machine_halt();
+@@ -122,6 +122,8 @@ void __init prom_init(void)
+ #if defined(CONFIG_CPU_R4X00)
+ 	if ((current_cpu_data.cputype == CPU_R3000) ||
+ 	    (current_cpu_data.cputype == CPU_R3000A)) {
++		static char r3k_msg[] __initdata =
++			"Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
+ 		printk(cpu_msg);
+ 		printk(r3k_msg);
+ 		dec_machine_halt();
+diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c
+--- a/arch/mips/dec/prom/memory.c
++++ b/arch/mips/dec/prom/memory.c
+@@ -35,22 +35,22 @@ static inline void pmax_setup_memory_reg
+ 	extern char genexcept_early;
+ 
+ 	/* Install exception handler */
+-	memcpy(&old_handler, (void *)(KSEG0 + 0x80), 0x80);
+-	memcpy((void *)(KSEG0 + 0x80), &genexcept_early, 0x80);
++	memcpy(&old_handler, (void *)(CKSEG0 + 0x80), 0x80);
++	memcpy((void *)(CKSEG0 + 0x80), &genexcept_early, 0x80);
+ 
+ 	/* read unmapped and uncached (KSEG1)
+ 	 * DECstations have at least 4MB RAM
+ 	 * Assume less than 480MB of RAM, as this is max for 5000/2xx
+ 	 * FIXME this should be replaced by the first free page!
+ 	 */
+-	for (memory_page = (unsigned char *) KSEG1 + CHUNK_SIZE;
+-	     (mem_err== 0) && (memory_page < ((unsigned char *) KSEG1+0x1E000000));
++	for (memory_page = (unsigned char *)CKSEG1 + CHUNK_SIZE;
++	     mem_err == 0 && memory_page < (unsigned char *)CKSEG1 + 0x1e00000;
+   	     memory_page += CHUNK_SIZE) {
+ 		dummy = *memory_page;
+ 	}
+-	memcpy((void *)(KSEG0 + 0x80), &old_handler, 0x80);
++	memcpy((void *)(CKSEG0 + 0x80), &old_handler, 0x80);
+ 
+-	add_memory_region(0, (unsigned long)memory_page - KSEG1 - CHUNK_SIZE,
++	add_memory_region(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE,
+ 			  BOOT_MEM_RAM);
+ }
+ 
+@@ -65,7 +65,7 @@ static inline void rex_setup_memory_regi
+ 	memmap *bm;
+ 
+ 	/* some free 64k */
+-	bm = (memmap *)KSEG0ADDR(0x28000);
++	bm = (memmap *)CKSEG0ADDR(0x28000);
+ 
+ 	bitmap_size = rex_getbitmap(bm);
+ 
+diff --git a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c
+--- a/arch/mips/dec/reset.c
++++ b/arch/mips/dec/reset.c
+@@ -14,7 +14,7 @@ typedef void ATTRIB_NORET (* noret_func_
+ 
+ static inline void ATTRIB_NORET back_to_prom(void)
+ {
+-	noret_func_t func = (void *) KSEG1ADDR(0x1fc00000);
++	noret_func_t func = (void *)CKSEG1ADDR(0x1fc00000);
+ 
+ 	func();
+ }
+diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
+--- a/arch/mips/dec/setup.c
++++ b/arch/mips/dec/setup.c
+@@ -1,19 +1,20 @@
+ /*
+- * Setup the interrupt stuff.
++ * System-specific setup, especially interrupts.
+  *
+  * 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) 1998 Harald Koerfgen
+- * Copyright (C) 2000, 2001, 2002, 2003  Maciej W. Rozycki
++ * Copyright (C) 2000, 2001, 2002, 2003, 2005  Maciej W. Rozycki
+  */
+-#include <linux/sched.h>
+-#include <linux/interrupt.h>
+-#include <linux/param.h>
+ #include <linux/console.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/ioport.h>
+ #include <linux/module.h>
++#include <linux/param.h>
++#include <linux/sched.h>
+ #include <linux/spinlock.h>
+ #include <linux/types.h>
+ 
+@@ -38,6 +39,7 @@
+ #include <asm/dec/kn02ca.h>
+ #include <asm/dec/kn03.h>
+ #include <asm/dec/kn230.h>
++#include <asm/dec/system.h>
+ 
+ 
+ extern void dec_machine_restart(char *command);
+@@ -47,10 +49,16 @@ extern irqreturn_t dec_intr_halt(int irq
+ 
+ extern asmlinkage void decstation_handle_int(void);
+ 
++unsigned long dec_kn_slot_base, dec_kn_slot_size;
++
++EXPORT_SYMBOL(dec_kn_slot_base);
++EXPORT_SYMBOL(dec_kn_slot_size);
++
+ spinlock_t ioasic_ssr_lock;
+ 
+ volatile u32 *ioasic_base;
+-unsigned long dec_kn_slot_size;
++
++EXPORT_SYMBOL(ioasic_base);
+ 
+ /*
+  * IRQ routing and priority tables.  Priorites are set as follows:
+@@ -77,6 +85,9 @@ unsigned long dec_kn_slot_size;
+ int dec_interrupt[DEC_NR_INTS] = {
+ 	[0 ... DEC_NR_INTS - 1] = -1
+ };
++
++EXPORT_SYMBOL(dec_interrupt);
++
+ int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2] = {
+ 	{ { .i = ~0 }, { .p = dec_intr_unimplemented } },
+ };
+@@ -108,11 +119,20 @@ static struct irqaction haltirq = {
+ /*
+  * Bus error (DBE/IBE exceptions and bus interrupts) handling setup.
+  */
+-void __init dec_be_init(void)
++static void __init dec_be_init(void)
+ {
+ 	switch (mips_machtype) {
+ 	case MACH_DS23100:	/* DS2100/DS3100 Pmin/Pmax */
++		board_be_handler = dec_kn01_be_handler;
++		busirq.handler = dec_kn01_be_interrupt;
+ 		busirq.flags |= SA_SHIRQ;
++		dec_kn01_be_init();
++		break;
++	case MACH_DS5000_1XX:	/* DS5000/1xx 3min */
++	case MACH_DS5000_XX:	/* DS5000/xx Maxine */
++		board_be_handler = dec_kn02xa_be_handler;
++		busirq.handler = dec_kn02xa_be_interrupt;
++		dec_kn02xa_be_init();
+ 		break;
+ 	case MACH_DS5000_200:	/* DS5000/200 3max */
+ 	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+@@ -128,7 +148,7 @@ void __init dec_be_init(void)
+ extern void dec_time_init(void);
+ extern void dec_timer_setup(struct irqaction *);
+ 
+-static void __init decstation_setup(void)
++void __init plat_setup(void)
+ {
+ 	board_be_init = dec_be_init;
+ 	board_time_init = dec_time_init;
+@@ -139,9 +159,10 @@ static void __init decstation_setup(void
+ 	_machine_restart = dec_machine_restart;
+ 	_machine_halt = dec_machine_halt;
+ 	_machine_power_off = dec_machine_power_off;
+-}
+ 
+-early_initcall(decstation_setup);
++	ioport_resource.start = ~0UL;
++	ioport_resource.end = 0UL;
++}
+ 
+ /*
+  * Machine-specific initialisation for KN01, aka DS2100 (aka Pmin)
+@@ -206,7 +227,7 @@ static int_ptr kn01_cpu_mask_nr_tbl[][2]
+ 		{ .p = cpu_all_int } },
+ };
+ 
+-void __init dec_init_kn01(void)
++static void __init dec_init_kn01(void)
+ {
+ 	/* IRQ routing. */
+ 	memcpy(&dec_interrupt, &kn01_interrupt,
+@@ -281,7 +302,7 @@ static int_ptr kn230_cpu_mask_nr_tbl[][2
+ 		{ .p = cpu_all_int } },
+ };
+ 
+-void __init dec_init_kn230(void)
++static void __init dec_init_kn230(void)
+ {
+ 	/* IRQ routing. */
+ 	memcpy(&dec_interrupt, &kn230_interrupt,
+@@ -371,7 +392,7 @@ static int_ptr kn02_asic_mask_nr_tbl[][2
+ 		{ .p = kn02_all_int } },
+ };
+ 
+-void __init dec_init_kn02(void)
++static void __init dec_init_kn02(void)
+ {
+ 	/* IRQ routing. */
+ 	memcpy(&dec_interrupt, &kn02_interrupt,
+@@ -472,7 +493,7 @@ static int_ptr kn02ba_asic_mask_nr_tbl[]
+ 		{ .p = asic_all_int } },
+ };
+ 
+-void __init dec_init_kn02ba(void)
++static void __init dec_init_kn02ba(void)
+ {
+ 	/* IRQ routing. */
+ 	memcpy(&dec_interrupt, &kn02ba_interrupt,
+@@ -569,7 +590,7 @@ static int_ptr kn02ca_asic_mask_nr_tbl[]
+ 		{ .p = asic_all_int } },
+ };
+ 
+-void __init dec_init_kn02ca(void)
++static void __init dec_init_kn02ca(void)
+ {
+ 	/* IRQ routing. */
+ 	memcpy(&dec_interrupt, &kn02ca_interrupt,
+@@ -670,7 +691,7 @@ static int_ptr kn03_asic_mask_nr_tbl[][2
+ 		{ .p = asic_all_int } },
+ };
+ 
+-void __init dec_init_kn03(void)
++static void __init dec_init_kn03(void)
+ {
+ 	/* IRQ routing. */
+ 	memcpy(&dec_interrupt, &kn03_interrupt,
+@@ -744,7 +765,3 @@ void __init arch_init_irq(void)
+ 	if (dec_interrupt[DEC_IRQ_HALT] >= 0)
+ 		setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq);
+ }
+-
+-EXPORT_SYMBOL(ioasic_base);
+-EXPORT_SYMBOL(dec_kn_slot_size);
+-EXPORT_SYMBOL(dec_interrupt);
+diff --git a/arch/mips/defconfig b/arch/mips/defconfig
+--- a/arch/mips/defconfig
++++ b/arch/mips/defconfig
+@@ -1,12 +1,9 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc2
+-# Wed Jan 26 02:48:59 2005
++# Linux kernel version: 2.6.14-rc2
++# Thu Oct 20 22:25:09 2005
+ #
+ CONFIG_MIPS=y
+-# CONFIG_64BIT is not set
+-# CONFIG_64BIT is not set
+-CONFIG_32BIT=y
+ 
+ #
+ # Code maturity level options
+@@ -14,25 +11,30 @@ CONFIG_32BIT=y
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=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_LOG_BUF_SHIFT=14
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
+ 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 is not set
+@@ -42,6 +44,7 @@ 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
+@@ -57,41 +60,69 @@ CONFIG_KMOD=y
+ #
+ # Machine selection
+ #
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
++# 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_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_LASAT 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_MIPS_SIM is not set
++# CONFIG_MOMENCO_JAGUAR_ATX is not set
+ # CONFIG_MOMENCO_OCELOT is not set
+-# CONFIG_MOMENCO_OCELOT_G is not set
+-# CONFIG_MOMENCO_OCELOT_C is not set
+ # CONFIG_MOMENCO_OCELOT_3 is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_PMC_YOSEMITE 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_DDB5074 is not set
+ # CONFIG_DDB5476 is not set
+ # CONFIG_DDB5477 is not set
+-# CONFIG_NEC_OSPREY is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_QEMU is not set
+ CONFIG_SGI_IP22=y
+-# CONFIG_SOC_AU1X00 is not set
+-# CONFIG_SIBYTE_SB1xxx_SOC 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_CALIBRATE_DELAY=y
+-CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_ARC=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_IRQ_CPU=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_ARC32=y
+@@ -103,8 +134,10 @@ CONFIG_ARC_PROMLIB=y
+ #
+ # CPU selection
+ #
+-# CONFIG_CPU_MIPS32 is not set
+-# CONFIG_CPU_MIPS64 is not set
++# 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
+@@ -120,22 +153,48 @@ CONFIG_CPU_R5000=y
+ # CONFIG_CPU_RM7000 is not set
+ # CONFIG_CPU_RM9000 is not set
+ # CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R4X00=y
++CONFIG_SYS_HAS_CPU_R5000=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_BOARD_SCACHE=y
+ CONFIG_IP22_CPU_SCACHE=y
++# CONFIG_MIPS_MT is not set
+ # CONFIG_64BIT_PHYS_ADDR is not set
+ # CONFIG_CPU_ADVANCED is not set
+ CONFIG_CPU_HAS_LLSC=y
+ CONFIG_CPU_HAS_LLDSCD=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_PREEMPT_NONE is not set
++CONFIG_PREEMPT_VOLUNTARY=y
+ # CONFIG_PREEMPT is not set
+ 
+ #
+ # Bus options (PCI, PCMCIA, EISA, ISA, TC)
+ #
++CONFIG_HW_HAS_EISA=y
+ # CONFIG_EISA is not set
+ CONFIG_MMU=y
+ 
+@@ -145,10 +204,6 @@ CONFIG_MMU=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
+-#
+-
+-#
+ # PCI Hotplug Support
+ #
+ 
+@@ -160,115 +215,7 @@ CONFIG_BINFMT_MISC=m
+ CONFIG_TRAD_SIGNALS=y
+ 
+ #
+-# 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 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_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_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+-# CONFIG_LBD is not set
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE 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=m
+-
+-#
+-# ATA/ATAPI/MFM/RLL support
+-#
+-# CONFIG_IDE 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=y
+-# CONFIG_CHR_DEV_OSST is not set
+-CONFIG_BLK_DEV_SR=y
+-# CONFIG_BLK_DEV_SR_VENDOR is not set
+-# CONFIG_CHR_DEV_SG 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=m
+-# CONFIG_SCSI_FC_ATTRS is not set
+-CONFIG_SCSI_ISCSI_ATTRS=m
+-
+-#
+-# SCSI low-level drivers
+-#
+-CONFIG_SGIWD93_SCSI=y
+-# 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
+-#
+-
+-#
+-# IEEE 1394 (FireWire) support
+-#
+-
+-#
+-# I2O device support
+-#
+-
+-#
+-# Networking support
++# Networking
+ #
+ CONFIG_NET=y
+ 
+@@ -277,12 +224,14 @@ CONFIG_NET=y
+ #
+ CONFIG_PACKET=y
+ CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=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 is not set
+ CONFIG_IP_PNP_BOOTP=y
+@@ -296,8 +245,10 @@ CONFIG_INET_AH=m
+ CONFIG_INET_ESP=m
+ CONFIG_INET_IPCOMP=m
+ CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=m
+-CONFIG_IP_TCPDIAG_IPV6=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
+@@ -341,6 +292,9 @@ CONFIG_INET6_TUNNEL=m
+ CONFIG_IPV6_TUNNEL=m
+ CONFIG_NETFILTER=y
+ # CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
+ 
+ #
+ # IP: Netfilter Configuration
+@@ -348,11 +302,15 @@ CONFIG_NETFILTER=y
+ CONFIG_IP_NF_CONNTRACK=m
+ CONFIG_IP_NF_CT_ACCT=y
+ CONFIG_IP_NF_CONNTRACK_MARK=y
++CONFIG_IP_NF_CONNTRACK_EVENTS=y
++CONFIG_IP_NF_CONNTRACK_NETLINK=m
+ # CONFIG_IP_NF_CT_PROTO_SCTP is not set
+ CONFIG_IP_NF_FTP=m
+ CONFIG_IP_NF_IRC=m
++# CONFIG_IP_NF_NETBIOS_NS is not set
+ CONFIG_IP_NF_TFTP=m
+ CONFIG_IP_NF_AMANDA=m
++CONFIG_IP_NF_PPTP=m
+ CONFIG_IP_NF_QUEUE=m
+ CONFIG_IP_NF_IPTABLES=m
+ CONFIG_IP_NF_MATCH_LIMIT=m
+@@ -376,9 +334,12 @@ CONFIG_IP_NF_MATCH_OWNER=m
+ CONFIG_IP_NF_MATCH_ADDRTYPE=m
+ CONFIG_IP_NF_MATCH_REALM=m
+ CONFIG_IP_NF_MATCH_SCTP=m
++CONFIG_IP_NF_MATCH_DCCP=m
+ CONFIG_IP_NF_MATCH_COMMENT=m
+ CONFIG_IP_NF_MATCH_CONNMARK=m
++CONFIG_IP_NF_MATCH_CONNBYTES=m
+ CONFIG_IP_NF_MATCH_HASHLIMIT=m
++CONFIG_IP_NF_MATCH_STRING=m
+ CONFIG_IP_NF_FILTER=m
+ CONFIG_IP_NF_TARGET_REJECT=m
+ CONFIG_IP_NF_TARGET_LOG=m
+@@ -395,12 +356,14 @@ 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_MANGLE=m
+ CONFIG_IP_NF_TARGET_TOS=m
+ CONFIG_IP_NF_TARGET_ECN=m
+ CONFIG_IP_NF_TARGET_DSCP=m
+ CONFIG_IP_NF_TARGET_MARK=m
+ CONFIG_IP_NF_TARGET_CLASSIFY=m
++CONFIG_IP_NF_TARGET_TTL=m
+ CONFIG_IP_NF_TARGET_CONNMARK=m
+ CONFIG_IP_NF_TARGET_CLUSTERIP=m
+ CONFIG_IP_NF_RAW=m
+@@ -410,7 +373,7 @@ CONFIG_IP_NF_ARPFILTER=m
+ CONFIG_IP_NF_ARP_MANGLE=m
+ 
+ #
+-# IPv6: Netfilter Configuration
++# IPv6: Netfilter Configuration (EXPERIMENTAL)
+ #
+ CONFIG_IP6_NF_QUEUE=m
+ CONFIG_IP6_NF_IPTABLES=m
+@@ -429,11 +392,16 @@ CONFIG_IP6_NF_MATCH_LENGTH=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_MARK=m
++CONFIG_IP6_NF_TARGET_HL=m
+ CONFIG_IP6_NF_RAW=m
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
+ 
+ #
+ # SCTP Configuration (EXPERIMENTAL)
+@@ -456,10 +424,6 @@ CONFIG_SCTP_HMAC_MD5=y
+ CONFIG_NET_DIVERT=y
+ # 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
+@@ -479,6 +443,7 @@ CONFIG_NET_SCH_INGRESS=m
+ CONFIG_NET_QOS=y
+ CONFIG_NET_ESTIMATOR=y
+ CONFIG_NET_CLS=y
++CONFIG_NET_CLS_BASIC=m
+ CONFIG_NET_CLS_TCINDEX=m
+ CONFIG_NET_CLS_ROUTE4=m
+ CONFIG_NET_CLS_ROUTE=y
+@@ -489,6 +454,7 @@ CONFIG_NET_CLS_U32=m
+ # 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
+ 
+@@ -496,17 +462,153 @@ CONFIG_NET_CLS_POLICE=y
+ # 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_IEEE80211=m
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=m
++CONFIG_IEEE80211_CRYPT_CCMP=m
++CONFIG_IEEE80211_CRYPT_TKIP=m
++
++#
++# 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=m
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Plug and Play support
++#
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
++# CONFIG_LBD is not set
++CONFIG_CDROM_PKTCDVD=m
++CONFIG_CDROM_PKTCDVD_BUFFERS=8
++# CONFIG_CDROM_PKTCDVD_WCACHE 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=m
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++CONFIG_RAID_ATTRS=m
++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 is not set
++# CONFIG_CHR_DEV_SG is not set
++CONFIG_CHR_DEV_SCH=m
++
++#
++# 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=m
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++CONFIG_SCSI_SAS_ATTRS=m
++
++#
++# SCSI low-level drivers
++#
++CONFIG_SGIWD93_SCSI=y
++# 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
++#
++
++#
++# Network device support
++#
+ CONFIG_NETDEVICES=y
+ CONFIG_DUMMY=m
+ CONFIG_BONDING=m
+ CONFIG_EQUALIZER=m
+ CONFIG_TUN=m
+-CONFIG_ETHERTAP=m
++
++#
++# PHY device support
++#
++CONFIG_PHYLIB=m
++CONFIG_PHYCONTROL=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -540,6 +642,8 @@ CONFIG_SGISEEQ=y
+ # 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
+@@ -569,18 +673,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-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
+-
+-#
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
+@@ -598,6 +690,16 @@ CONFIG_MOUSE_SERIAL=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_I8042=y
++CONFIG_SERIO_SERPORT=y
++CONFIG_SERIO_LIBPS2=y
++CONFIG_SERIO_RAW=m
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -644,11 +746,14 @@ CONFIG_SGI_DS1286=m
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_DRM is not set
+ CONFIG_RAW_DRIVER=m
+ CONFIG_MAX_RAW_DEVS=256
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -659,10 +764,20 @@ CONFIG_MAX_RAW_DEVS=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -693,7 +808,6 @@ CONFIG_LOGO=y
+ # CONFIG_LOGO_LINUX_VGA16 is not set
+ # CONFIG_LOGO_LINUX_CLUT224 is not set
+ CONFIG_LOGO_SGI_CLUT224=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -707,10 +821,6 @@ CONFIG_LOGO_SGI_CLUT224=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -723,13 +833,17 @@ CONFIG_LOGO_SGI_CLUT224=y
+ #
+ # InfiniBand support
+ #
+-# CONFIG_INFINIBAND is not set
++
++#
++# SN Devices
++#
+ 
+ #
+ # File systems
+ #
+ CONFIG_EXT2_FS=m
+ # 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=y
+@@ -741,12 +855,14 @@ CONFIG_FS_MBCACHE=y
+ # CONFIG_JFS_FS is not set
+ CONFIG_FS_POSIX_ACL=y
+ CONFIG_XFS_FS=m
+-# CONFIG_XFS_RT is not set
+-CONFIG_XFS_QUOTA=y
++CONFIG_XFS_EXPORT=y
++CONFIG_XFS_QUOTA=m
+ CONFIG_XFS_SECURITY=y
+ # CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
+ CONFIG_MINIX_FS=m
+ # CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
+ CONFIG_QUOTA=y
+ # CONFIG_QFMT_V1 is not set
+ CONFIG_QFMT_V2=m
+@@ -754,6 +870,7 @@ CONFIG_QUOTACTL=y
+ CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=m
+ CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -781,12 +898,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=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
++CONFIG_RELAYFS_FS=m
+ 
+ #
+ # Miscellaneous filesystems
+@@ -811,15 +926,20 @@ CONFIG_UFS_FS=m
+ #
+ CONFIG_NFS_FS=m
+ CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
+ # CONFIG_NFS_V4 is not set
+ # CONFIG_NFS_DIRECTIO is not set
+ CONFIG_NFSD=m
++CONFIG_NFSD_V2_ACL=y
+ CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
+ # CONFIG_NFSD_V4 is not set
+ 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
+@@ -835,6 +955,7 @@ CONFIG_CIFS=m
+ CONFIG_CODA_FS=m
+ # CONFIG_CODA_FS_OLD_API is not set
+ # CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
+ 
+ #
+ # Partition Types
+@@ -908,7 +1029,9 @@ CONFIG_NLS_UTF8=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ # CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_CROSSCOMPILE=y
+ CONFIG_CMDLINE=""
+ 
+@@ -931,6 +1054,7 @@ CONFIG_CRYPTO_SHA1=m
+ 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
+@@ -942,10 +1066,10 @@ CONFIG_CRYPTO_TEA=m
+ CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_KHAZAD=m
+ CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=y
++CONFIG_CRYPTO_DEFLATE=m
+ CONFIG_CRYPTO_MICHAEL_MIC=m
+ CONFIG_CRYPTO_CRC32C=m
+-CONFIG_CRYPTO_TEST=m
++# CONFIG_CRYPTO_TEST is not set
+ 
+ #
+ # Hardware crypto devices
+@@ -955,9 +1079,12 @@ CONFIG_CRYPTO_TEST=m
+ # Library routines
+ #
+ # CONFIG_CRC_CCITT is not set
++CONFIG_CRC16=m
+ CONFIG_CRC32=m
+ CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=y
+-CONFIG_ZLIB_DEFLATE=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_TEXTSEARCH=y
++CONFIG_TEXTSEARCH_KMP=m
++CONFIG_TEXTSEARCH_BM=m
++CONFIG_TEXTSEARCH_FSM=m
+diff --git a/arch/mips/galileo-boards/ev96100/setup.c b/arch/mips/galileo-boards/ev96100/setup.c
+--- a/arch/mips/galileo-boards/ev96100/setup.c
++++ b/arch/mips/galileo-boards/ev96100/setup.c
+@@ -55,7 +55,7 @@ extern void mips_reboot_setup(void);
+ 
+ unsigned char mac_0_1[12];
+ 
+-static void __init ev96100_setup(void)
++void __init plat_setup(void)
+ {
+ 	unsigned int config = read_c0_config();
+ 	unsigned int status = read_c0_status();
+@@ -142,8 +142,6 @@ static void __init ev96100_setup(void)
+ 	tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
+ }
+ 
+-early_initcall(ev96100_setup);
+-
+ unsigned short get_gt_devid(void)
+ {
+ 	u32 gt_devid;
+diff --git a/arch/mips/gt64120/ev64120/Kconfig b/arch/mips/gt64120/ev64120/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/gt64120/ev64120/Kconfig
+@@ -0,0 +1,3 @@
++config EVB_PCI1
++	bool "Enable Second PCI (PCI1)"
++	depends on MIPS_EV64120
+diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c
+--- a/arch/mips/gt64120/ev64120/setup.c
++++ b/arch/mips/gt64120/ev64120/setup.c
+@@ -69,7 +69,7 @@ unsigned long __init prom_free_prom_memo
+  */
+ extern void gt64120_time_init(void);
+ 
+-static void __init ev64120_setup(void)
++void __init plat_setup(void)
+ {
+ 	_machine_restart = galileo_machine_restart;
+ 	_machine_halt = galileo_machine_halt;
+@@ -79,8 +79,6 @@ static void __init ev64120_setup(void)
+ 	set_io_port_base(KSEG1);
+ }
+ 
+-early_initcall(ev64120_setup);
+-
+ const char *get_system_type(void)
+ {
+ 	return "Galileo EV64120A";
+diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c
+--- a/arch/mips/gt64120/momenco_ocelot/setup.c
++++ b/arch/mips/gt64120/momenco_ocelot/setup.c
+@@ -150,7 +150,7 @@ void PMON_v2_setup()
+ 	gt64120_base = 0xe0000000;
+ }
+ 
+-static void __init momenco_ocelot_setup(void)
++void __init plat_setup(void)
+ {
+ 	void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
+ 	unsigned int tmpword;
+@@ -307,8 +307,6 @@ static void __init momenco_ocelot_setup(
+ 	GT_WRITE(GT_DEV_B3_OFS, 0xfef73);
+ }
+ 
+-early_initcall(momenco_ocelot_setup);
+-
+ extern int rm7k_tcache_enabled;
+ /*
+  * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
+diff --git a/arch/mips/ite-boards/Kconfig b/arch/mips/ite-boards/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/ite-boards/Kconfig
+@@ -0,0 +1,8 @@
++config IT8172_REVC
++	bool "Support for older IT8172 (Rev C)"
++	depends on MIPS_ITE8172
++	help
++	  Say Y here to support the older, Revision C version of the Integrated
++	  Technology Express, Inc. ITE8172 SBC.  Vendor page at
++	  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
++	  board at <http://www.mvista.com/partners/semiconductor/ite.html>.
+diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
+--- a/arch/mips/ite-boards/generic/irq.c
++++ b/arch/mips/ite-boards/generic/irq.c
+@@ -138,14 +138,13 @@ static void end_ite_irq(unsigned int irq
+ }
+ 
+ static struct hw_interrupt_type it8172_irq_type = {
+-	"ITE8172",
+-	startup_ite_irq,
+-	shutdown_ite_irq,
+-	enable_it8172_irq,
+-	disable_it8172_irq,
+-	mask_and_ack_ite_irq,
+-	end_ite_irq,
+-	NULL
++	.typename = "ITE8172",
++	.startup = startup_ite_irq,
++	.shutdown = shutdown_ite_irq,
++	.enable = enable_it8172_irq,
++	.disable = disable_it8172_irq,
++	.ack = mask_and_ack_ite_irq,
++	.end = end_ite_irq,
+ };
+ 
+ 
+@@ -159,13 +158,13 @@ static void ack_none(unsigned int irq) {
+ #define end_none	enable_none
+ 
+ static struct hw_interrupt_type cp0_irq_type = {
+-	"CP0 Count",
+-	startup_none,
+-	shutdown_none,
+-	enable_none,
+-	disable_none,
+-	ack_none,
+-	end_none
++	.typename = "CP0 Count",
++	.startup = startup_none,
++	.shutdown = shutdown_none,
++	.enable = enable_none,
++	.disable = disable_none,
++	.ack = ack_none,
++	.end = end_none
+ };
+ 
+ void enable_cpu_timer(void)
+@@ -182,7 +181,6 @@ void __init arch_init_irq(void)
+ 	int i;
+         unsigned long flags;
+ 
+-        memset(irq_desc, 0, sizeof(irq_desc));
+         set_except_vector(0, it8172_IRQ);
+ 
+ 	/* mask all interrupts */
+diff --git a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c
+--- a/arch/mips/ite-boards/generic/it8172_setup.c
++++ b/arch/mips/ite-boards/generic/it8172_setup.c
+@@ -105,7 +105,7 @@ void __init it8172_init_ram_resource(uns
+ 	it8172_resources.ram.end = memsize;
+ }
+ 
+-static void __init it8172_setup(void)
++void __init plat_setup(void)
+ {
+ 	unsigned short dsr;
+ 	char *argptr;
+@@ -251,8 +251,6 @@ static void __init it8172_setup(void)
+ #endif /* CONFIG_IT8172_SCR1 */
+ }
+ 
+-early_initcall(it8172_setup);
+-
+ #ifdef CONFIG_SERIO_I8042
+ /*
+  * According to the ITE Special BIOS Note for waking up the
+diff --git a/arch/mips/jazz/Kconfig b/arch/mips/jazz/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/jazz/Kconfig
+@@ -0,0 +1,33 @@
++config ACER_PICA_61
++	bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
++	depends on MACH_JAZZ && EXPERIMENTAL
++	select DMA_NONCOHERENT
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++	help
++	  This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
++	  kernel that runs on these, say Y here. For details about Linux on
++	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
++	  <http://www.linux-mips.org/>.
++
++config MIPS_MAGNUM_4000
++	bool "Support for MIPS Magnum 4000"
++	depends on MACH_JAZZ
++	select DMA_NONCOHERENT
++	select SYS_SUPPORTS_BIG_ENDIAN if EXPERIMENTAL
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++	help
++	  This is a machine with a R4000 100 MHz CPU. To compile a Linux
++	  kernel that runs on these, say Y here. For details about Linux on
++	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
++	  <http://www.linux-mips.org/>.
++
++config OLIVETTI_M700
++	bool "Support for Olivetti M700-10"
++	depends on MACH_JAZZ
++	select DMA_NONCOHERENT
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++	help
++	  This is a machine with a R4000 100 MHz CPU. To compile a Linux
++	  kernel that runs on these, say Y here. For details about Linux on
++	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
++	  <http://www.linux-mips.org/>.
+diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
+--- a/arch/mips/jazz/irq.c
++++ b/arch/mips/jazz/irq.c
+@@ -58,14 +58,13 @@ static void end_r4030_irq(unsigned int i
+ }
+ 
+ static struct hw_interrupt_type r4030_irq_type = {
+-	"R4030",
+-	startup_r4030_irq,
+-	shutdown_r4030_irq,
+-	enable_r4030_irq,
+-	disable_r4030_irq,
+-	mask_and_ack_r4030_irq,
+-	end_r4030_irq,
+-	NULL
++	.typename = "R4030",
++	.startup = startup_r4030_irq,
++	.shutdown = shutdown_r4030_irq,
++	.enable = enable_r4030_irq,
++	.disable = disable_r4030_irq,
++	.ack = mask_and_ack_r4030_irq,
++	.end = end_r4030_irq,
+ };
+ 
+ void __init init_r4030_ints(void)
+diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
+--- a/arch/mips/jazz/setup.c
++++ b/arch/mips/jazz/setup.c
+@@ -50,7 +50,7 @@ static struct resource jazz_io_resources
+ 	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
+ };
+ 
+-static void __init jazz_setup(void)
++void __init plat_setup(void)
+ {
+ 	int i;
+ 
+@@ -97,5 +97,3 @@ static void __init jazz_setup(void)
+ 
+ 	vdma_init();
+ }
+-
+-early_initcall(jazz_setup);
+diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c
+--- a/arch/mips/jmr3927/rbhma3100/irq.c
++++ b/arch/mips/jmr3927/rbhma3100/irq.c
+@@ -412,13 +412,13 @@ void __init arch_init_irq(void)
+ }
+ 
+ static hw_irq_controller jmr3927_irq_controller = {
+-	"jmr3927_irq",
+-	jmr3927_irq_startup,
+-	jmr3927_irq_shutdown,
+-	jmr3927_irq_enable,
+-	jmr3927_irq_disable,
+-	jmr3927_irq_ack,
+-	jmr3927_irq_end,
++	.typename = "jmr3927_irq",
++	.startup = jmr3927_irq_startup,
++	.shutdown = jmr3927_irq_shutdown,
++	.enable = jmr3927_irq_enable,
++	.disable = jmr3927_irq_disable,
++	.ack = jmr3927_irq_ack,
++	.end = jmr3927_irq_end,
+ };
+ 
+ void jmr3927_irq_init(u32 irq_base)
+diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
+--- a/arch/mips/jmr3927/rbhma3100/setup.c
++++ b/arch/mips/jmr3927/rbhma3100/setup.c
+@@ -44,6 +44,11 @@
+ #include <linux/ioport.h>
+ #include <linux/param.h>	/* for HZ */
+ #include <linux/delay.h>
++#ifdef CONFIG_SERIAL_TXX9
++#include <linux/tty.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++#endif
+ 
+ #include <asm/addrspace.h>
+ #include <asm/time.h>
+@@ -193,7 +198,7 @@ static void jmr3927_board_init(void);
+ extern struct resource pci_io_resource;
+ extern struct resource pci_mem_resource;
+ 
+-static void __init jmr3927_setup(void)
++void __init plat_setup(void)
+ {
+ 	char *argptr;
+ 
+@@ -211,8 +216,8 @@ static void __init jmr3927_setup(void)
+ 	 */
+ 	ioport_resource.start = pci_io_resource.start;
+ 	ioport_resource.end = pci_io_resource.end;
+-	iomem_resource.start = pci_mem_resource.start;
+-	iomem_resource.end = pci_mem_resource.end;
++	iomem_resource.start = 0;
++	iomem_resource.end = 0xffffffff;
+ 
+ 	/* Reboot on panic */
+ 	panic_timeout = 180;
+@@ -265,18 +270,35 @@ static void __init jmr3927_setup(void)
+ 		strcat(argptr, " ip=bootp");
+ 	}
+ 
+-#ifdef CONFIG_TXX927_SERIAL_CONSOLE
++#ifdef CONFIG_SERIAL_TXX9
++	{
++		extern int early_serial_txx9_setup(struct uart_port *port);
++		int i;
++		struct uart_port req;
++		for(i = 0; i < 2; i++) {
++			memset(&req, 0, sizeof(req));
++			req.line = i;
++			req.iotype = UPIO_MEM;
++			req.membase = (char *)TX3927_SIO_REG(i);
++			req.mapbase = TX3927_SIO_REG(i);
++			req.irq = i == 0 ?
++				JMR3927_IRQ_IRC_SIO0 : JMR3927_IRQ_IRC_SIO1;
++			if (i == 0)
++				req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
++			req.uartclk = JMR3927_IMCLK;
++			early_serial_txx9_setup(&req);
++		}
++	}
++#ifdef CONFIG_SERIAL_TXX9_CONSOLE
+ 	argptr = prom_getcmdline();
+ 	if ((argptr = strstr(argptr, "console=")) == NULL) {
+ 		argptr = prom_getcmdline();
+ 		strcat(argptr, " console=ttyS1,115200");
+ 	}
+ #endif
++#endif
+ }
+ 
+-early_initcall(jmr3927_setup);
+-
+-
+ static void tx3927_setup(void);
+ 
+ #ifdef CONFIG_PCI
+@@ -335,7 +357,7 @@ static void __init jmr3927_board_init(vo
+ 		       jmr3927_io_dipsw());
+ }
+ 
+-static void __init tx3927_setup(void)
++void __init plat_setup(void)
+ {
+ 	int i;
+ 
+diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
+--- a/arch/mips/kernel/Makefile
++++ b/arch/mips/kernel/Makefile
+@@ -11,11 +11,7 @@ obj-y		+= cpu-probe.o branch.o entry.o g
+ binfmt_irix-objs	:= irixelf.o irixinv.o irixioctl.o irixsig.o	\
+ 			   irix5sys.o sysirix.o
+ 
+-ifdef CONFIG_MODULES
+-obj-y				+= mips_ksyms.o module.o
+-obj-$(CONFIG_32BIT)		+= module-elf32.o
+-obj-$(CONFIG_64BIT)		+= module-elf64.o
+-endif
++obj-$(CONFIG_MODULES)		+= mips_ksyms.o module.o
+ 
+ obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
+ obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o r2300_switch.o
+@@ -38,12 +34,18 @@ obj-$(CONFIG_CPU_R6000)		+= r6000_fpu.o 
+ 
+ obj-$(CONFIG_SMP)		+= smp.o
+ 
++obj-$(CONFIG_MIPS_MT_SMP)	+= smp_mt.o
++
++obj-$(CONFIG_MIPS_VPE_LOADER)	+= vpe.o
++obj-$(CONFIG_MIPS_VPE_APSP_API)	+= rtlx.o
++
+ obj-$(CONFIG_NO_ISA)		+= dma-no-isa.o
+ obj-$(CONFIG_I8259)		+= i8259.o
+ obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
+ obj-$(CONFIG_IRQ_CPU_RM7K)	+= irq-rm7000.o
+ obj-$(CONFIG_IRQ_CPU_RM9K)	+= irq-rm9000.o
+ obj-$(CONFIG_IRQ_MV64340)	+= irq-mv6434x.o
++obj-$(CONFIG_MIPS_BOARDS_GEN)	+= irq-msc01.o
+ 
+ obj-$(CONFIG_32BIT)		+= scall32-o32.o
+ obj-$(CONFIG_64BIT)		+= scall64-64.o
+@@ -57,8 +59,6 @@ obj-$(CONFIG_PROC_FS)		+= proc.o
+ 
+ obj-$(CONFIG_64BIT)		+= cpu-bugs64.o
+ 
+-obj-$(CONFIG_GEN_RTC)		+= genrtc.o
+-
+ CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
+ CFLAGS_ioctl32.o	+= -Ifs/
+ 
+diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
+--- a/arch/mips/kernel/asm-offsets.c
++++ b/arch/mips/kernel/asm-offsets.c
+@@ -95,6 +95,7 @@ void output_thread_info_defines(void)
+ 	offset("#define TI_PRE_COUNT       ", struct thread_info, preempt_count);
+ 	offset("#define TI_ADDR_LIMIT      ", struct thread_info, addr_limit);
+ 	offset("#define TI_RESTART_BLOCK   ", struct thread_info, restart_block);
++	offset("#define TI_TP_VALUE	   ", struct thread_info, tp_value);
+ 	constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER);
+ 	constant("#define _THREAD_SIZE       ", THREAD_SIZE);
+ 	constant("#define _THREAD_MASK       ", THREAD_MASK);
+@@ -240,6 +241,7 @@ void output_mm_defines(void)
+ 	linefeed;
+ }
+ 
++#ifdef CONFIG_32BIT
+ void output_sc_defines(void)
+ {
+ 	text("/* Linux sigcontext offsets. */");
+@@ -251,10 +253,29 @@ void output_sc_defines(void)
+ 	offset("#define SC_STATUS     ", struct sigcontext, sc_status);
+ 	offset("#define SC_FPC_CSR    ", struct sigcontext, sc_fpc_csr);
+ 	offset("#define SC_FPC_EIR    ", struct sigcontext, sc_fpc_eir);
+-	offset("#define SC_CAUSE      ", struct sigcontext, sc_cause);
+-	offset("#define SC_BADVADDR   ", struct sigcontext, sc_badvaddr);
++	offset("#define SC_HI1        ", struct sigcontext, sc_hi1);
++	offset("#define SC_LO1        ", struct sigcontext, sc_lo1);
++	offset("#define SC_HI2        ", struct sigcontext, sc_hi2);
++	offset("#define SC_LO2        ", struct sigcontext, sc_lo2);
++	offset("#define SC_HI3        ", struct sigcontext, sc_hi3);
++	offset("#define SC_LO3        ", struct sigcontext, sc_lo3);
+ 	linefeed;
+ }
++#endif
++
++#ifdef CONFIG_64BIT
++void output_sc_defines(void)
++{
++	text("/* Linux sigcontext offsets. */");
++	offset("#define SC_REGS       ", struct sigcontext, sc_regs);
++	offset("#define SC_FPREGS     ", struct sigcontext, sc_fpregs);
++	offset("#define SC_MDHI       ", struct sigcontext, sc_hi);
++	offset("#define SC_MDLO       ", struct sigcontext, sc_lo);
++	offset("#define SC_PC         ", struct sigcontext, sc_pc);
++	offset("#define SC_FPC_CSR    ", struct sigcontext, sc_fpc_csr);
++	linefeed;
++}
++#endif
+ 
+ #ifdef CONFIG_MIPS32_COMPAT
+ void output_sc32_defines(void)
+diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
+--- a/arch/mips/kernel/binfmt_elfn32.c
++++ b/arch/mips/kernel/binfmt_elfn32.c
+@@ -52,7 +52,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
+ 
+ #include <asm/processor.h>
+ #include <linux/module.h>
+-#include <linux/config.h>
+ #include <linux/elfcore.h>
+ #include <linux/compat.h>
+ 
+@@ -116,4 +115,7 @@ MODULE_AUTHOR("Ralf Baechle (ralf at linux-
+ #undef MODULE_DESCRIPTION
+ #undef MODULE_AUTHOR
+ 
++#undef TASK_SIZE
++#define TASK_SIZE TASK_SIZE32
++
+ #include "../../../fs/binfmt_elf.c"
+diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
+--- a/arch/mips/kernel/binfmt_elfo32.c
++++ b/arch/mips/kernel/binfmt_elfo32.c
+@@ -54,7 +54,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
+ 
+ #include <asm/processor.h>
+ #include <linux/module.h>
+-#include <linux/config.h>
+ #include <linux/elfcore.h>
+ #include <linux/compat.h>
+ 
+@@ -98,7 +97,7 @@ struct elf_prpsinfo32
+ #define init_elf_binfmt init_elf32_binfmt
+ 
+ #define jiffies_to_timeval jiffies_to_compat_timeval
+-static __inline__ void
++static inline void
+ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+ {
+ 	/*
+@@ -113,21 +112,26 @@ jiffies_to_compat_timeval(unsigned long 
+ #undef ELF_CORE_COPY_REGS
+ #define ELF_CORE_COPY_REGS(_dest,_regs) elf32_core_copy_regs(_dest,_regs);
+ 
+-void elf32_core_copy_regs(elf_gregset_t _dest, struct pt_regs *_regs)
++void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs)
+ {
+ 	int i;
+ 
+-	memset(_dest, 0, sizeof(elf_gregset_t));
+-
+-	/* XXXKW the 6 is from EF_REG0 in gdb/gdb/mips-linux-tdep.c, include/asm-mips/reg.h */
+-	for (i=6; i<38; i++)
+-		_dest[i] = (elf_greg_t) _regs->regs[i-6];
+-	_dest[i++] = (elf_greg_t) _regs->lo;
+-	_dest[i++] = (elf_greg_t) _regs->hi;
+-	_dest[i++] = (elf_greg_t) _regs->cp0_epc;
+-	_dest[i++] = (elf_greg_t) _regs->cp0_badvaddr;
+-	_dest[i++] = (elf_greg_t) _regs->cp0_status;
+-	_dest[i++] = (elf_greg_t) _regs->cp0_cause;
++	for (i = 0; i < EF_R0; i++)
++		grp[i] = 0;
++	grp[EF_R0] = 0;
++	for (i = 1; i <= 31; i++)
++		grp[EF_R0 + i] = (elf_greg_t) regs->regs[i];
++	grp[EF_R26] = 0;
++	grp[EF_R27] = 0;
++	grp[EF_LO] = (elf_greg_t) regs->lo;
++	grp[EF_HI] = (elf_greg_t) regs->hi;
++	grp[EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc;
++	grp[EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr;
++	grp[EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status;
++	grp[EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause;
++#ifdef EF_UNUSED0
++	grp[EF_UNUSED0] = 0;
++#endif
+ }
+ 
+ MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries");
+@@ -136,4 +140,7 @@ MODULE_AUTHOR("Ralf Baechle (ralf at linux-
+ #undef MODULE_DESCRIPTION
+ #undef MODULE_AUTHOR
+ 
++#undef TASK_SIZE
++#define TASK_SIZE TASK_SIZE32
++
+ #include "../../../fs/binfmt_elf.c"
+diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
+--- a/arch/mips/kernel/branch.c
++++ b/arch/mips/kernel/branch.c
+@@ -12,6 +12,7 @@
+ #include <asm/branch.h>
+ #include <asm/cpu.h>
+ #include <asm/cpu-features.h>
++#include <asm/fpu.h>
+ #include <asm/inst.h>
+ #include <asm/ptrace.h>
+ #include <asm/uaccess.h>
+@@ -21,7 +22,7 @@
+  */
+ int __compute_return_epc(struct pt_regs *regs)
+ {
+-	unsigned int *addr, bit, fcr31;
++	unsigned int *addr, bit, fcr31, dspcontrol;
+ 	long epc;
+ 	union mips_instruction insn;
+ 
+@@ -98,6 +99,18 @@ int __compute_return_epc(struct pt_regs 
+ 				epc += 8;
+ 			regs->cp0_epc = epc;
+ 			break;
++		case bposge32_op:
++			if (!cpu_has_dsp)
++				goto sigill;
++
++			dspcontrol = rddsp(0x01);
++
++			if (dspcontrol >= 32) {
++				epc = epc + 4 + (insn.i_format.simmediate << 2);
++			} else
++				epc += 8;
++			regs->cp0_epc = epc;
++			break;
+ 		}
+ 		break;
+ 
+@@ -161,10 +174,13 @@ int __compute_return_epc(struct pt_regs 
+ 	 * And now the FPA/cp1 branch instructions.
+ 	 */
+ 	case cop1_op:
+-		if (!cpu_has_fpu)
+-			fcr31 = current->thread.fpu.soft.fcr31;
+-		else
++		preempt_disable();
++		if (is_fpu_owner())
+ 			asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
++		else
++			fcr31 = current->thread.fpu.hard.fcr31;
++		preempt_enable();
++
+ 		bit = (insn.i_format.rt >> 2);
+ 		bit += (bit != 0);
+ 		bit += 23;
+@@ -196,4 +212,9 @@ unaligned:
+ 	printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
+ 	force_sig(SIGBUS, current);
+ 	return -EFAULT;
++
++sigill:
++	printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
++	force_sig(SIGBUS, current);
++	return -EFAULT;
+ }
+diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
+--- a/arch/mips/kernel/cpu-probe.c
++++ b/arch/mips/kernel/cpu-probe.c
+@@ -2,9 +2,9 @@
+  * Processor capabilities determination functions.
+  *
+  * Copyright (C) xxxx  the Anonymous
+- * Copyright (C) 2003  Maciej W. Rozycki
++ * Copyright (C) 2003, 2004  Maciej W. Rozycki
+  * Copyright (C) 1994 - 2003 Ralf Baechle
+- * Copyright (C) 2001 MIPS Inc.
++ * Copyright (C) 2001, 2004  MIPS Inc.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -17,7 +17,6 @@
+ #include <linux/ptrace.h>
+ #include <linux/stddef.h>
+ 
+-#include <asm/bugs.h>
+ #include <asm/cpu.h>
+ #include <asm/fpu.h>
+ #include <asm/mipsregs.h>
+@@ -51,36 +50,48 @@ static void r4k_wait(void)
+ 		".set\tmips0");
+ }
+ 
+-/*
+- * The Au1xxx wait is available only if we run CONFIG_PM and
+- * the timer setup found we had a 32KHz counter available.
+- * There are still problems with functions that may call au1k_wait
+- * directly, but that will be discovered pretty quickly.
+- */
+-extern void (*au1k_wait_ptr)(void);
++/* The Au1xxx wait is available only if using 32khz counter or
++ * external timer source, but specifically not CP0 Counter. */
++int allow_au1k_wait;
+ 
+-void au1k_wait(void)
++static void au1k_wait(void)
+ {
+-#ifdef CONFIG_PM
+ 	/* using the wait instruction makes CP0 counter unusable */
+-	__asm__(".set\tmips3\n\t"
++	__asm__(".set mips3\n\t"
++		"cache 0x14, 0(%0)\n\t"
++		"cache 0x14, 32(%0)\n\t"
++		"sync\n\t"
++		"nop\n\t"
+ 		"wait\n\t"
+ 		"nop\n\t"
+ 		"nop\n\t"
+ 		"nop\n\t"
+ 		"nop\n\t"
+-		".set\tmips0");
+-#else
+-	__asm__("nop\n\t"
+-		"nop");
+-#endif
++		".set mips0\n\t"
++		: : "r" (au1k_wait));
++}
++
++static int __initdata nowait = 0;
++
++int __init wait_disable(char *s)
++{
++	nowait = 1;
++
++	return 1;
+ }
+ 
++__setup("nowait", wait_disable);
++
+ static inline void check_wait(void)
+ {
+ 	struct cpuinfo_mips *c = &current_cpu_data;
+ 
+ 	printk("Checking for 'wait' instruction... ");
++	if (nowait) {
++		printk (" disabled.\n");
++		return;
++	}
++
+ 	switch (c->cputype) {
+ 	case CPU_R3081:
+ 	case CPU_R3081E:
+@@ -109,22 +120,22 @@ static inline void check_wait(void)
+ /*	case CPU_20KC:*/
+ 	case CPU_24K:
+ 	case CPU_25KF:
++	case CPU_34K:
++ 	case CPU_PR4450:
+ 		cpu_wait = r4k_wait;
+ 		printk(" available.\n");
+ 		break;
+-#ifdef CONFIG_PM
+ 	case CPU_AU1000:
+ 	case CPU_AU1100:
+ 	case CPU_AU1500:
+-		if (au1k_wait_ptr != NULL) {
+-			cpu_wait = au1k_wait_ptr;
++	case CPU_AU1550:
++	case CPU_AU1200:
++		if (allow_au1k_wait) {
++			cpu_wait = au1k_wait;
+ 			printk(" available.\n");
+-		}
+-		else {
++		} else
+ 			printk(" unavailable.\n");
+-		}
+ 		break;
+-#endif
+ 	default:
+ 		printk(" unavailable.\n");
+ 		break;
+@@ -180,7 +191,7 @@ static inline int __cpu_has_fpu(void)
+ 	return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
+ }
+ 
+-#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
++#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
+ 		| MIPS_CPU_COUNTER)
+ 
+ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
+@@ -189,7 +200,8 @@ static inline void cpu_probe_legacy(stru
+ 	case PRID_IMP_R2000:
+ 		c->cputype = CPU_R2000;
+ 		c->isa_level = MIPS_CPU_ISA_I;
+-		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
++		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
++		             MIPS_CPU_NOFPUEX;
+ 		if (__cpu_has_fpu())
+ 			c->options |= MIPS_CPU_FPU;
+ 		c->tlbsize = 64;
+@@ -203,7 +215,8 @@ static inline void cpu_probe_legacy(stru
+ 		else
+ 			c->cputype = CPU_R3000;
+ 		c->isa_level = MIPS_CPU_ISA_I;
+-		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
++		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
++		             MIPS_CPU_NOFPUEX;
+ 		if (__cpu_has_fpu())
+ 			c->options |= MIPS_CPU_FPU;
+ 		c->tlbsize = 64;
+@@ -266,7 +279,8 @@ static inline void cpu_probe_legacy(stru
+ 	case PRID_IMP_R4600:
+ 		c->cputype = CPU_R4600;
+ 		c->isa_level = MIPS_CPU_ISA_III;
+-		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
++		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
++			     MIPS_CPU_LLSC;
+ 		c->tlbsize = 48;
+ 		break;
+ 	#if 0
+@@ -285,7 +299,7 @@ static inline void cpu_probe_legacy(stru
+ 	#endif
+ 	case PRID_IMP_TX39:
+ 		c->isa_level = MIPS_CPU_ISA_I;
+-		c->options = MIPS_CPU_TLB;
++		c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
+ 
+ 		if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
+ 			c->cputype = CPU_TX3927;
+@@ -421,74 +435,147 @@ static inline void cpu_probe_legacy(stru
+ 	}
+ }
+ 
+-static inline void decode_config1(struct cpuinfo_mips *c)
++static inline unsigned int decode_config0(struct cpuinfo_mips *c)
+ {
+-	unsigned long config0 = read_c0_config();
+-	unsigned long config1;
++	unsigned int config0;
++	int isa;
+ 
+-	if ((config0 & (1 << 31)) == 0)
+-		return;			/* actually wort a panic() */
++	config0 = read_c0_config();
++
++	if (((config0 & MIPS_CONF_MT) >> 7) == 1)
++		c->options |= MIPS_CPU_TLB;
++	isa = (config0 & MIPS_CONF_AT) >> 13;
++	switch (isa) {
++	case 0:
++		c->isa_level = MIPS_CPU_ISA_M32;
++		break;
++	case 2:
++		c->isa_level = MIPS_CPU_ISA_M64;
++		break;
++	default:
++		panic("Unsupported ISA type, cp0.config0.at: %d.", isa);
++	}
++
++	return config0 & MIPS_CONF_M;
++}
++
++static inline unsigned int decode_config1(struct cpuinfo_mips *c)
++{
++	unsigned int config1;
+ 
+-	/* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
+-	c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+-		MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
+-		MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
+ 	config1 = read_c0_config1();
+-	if (config1 & (1 << 3))
++
++	if (config1 & MIPS_CONF1_MD)
++		c->ases |= MIPS_ASE_MDMX;
++	if (config1 & MIPS_CONF1_WR)
+ 		c->options |= MIPS_CPU_WATCH;
+-	if (config1 & (1 << 2))
+-		c->options |= MIPS_CPU_MIPS16;
+-	if (config1 & (1 << 1))
++	if (config1 & MIPS_CONF1_CA)
++		c->ases |= MIPS_ASE_MIPS16;
++	if (config1 & MIPS_CONF1_EP)
+ 		c->options |= MIPS_CPU_EJTAG;
+-	if (config1 & 1) {
++	if (config1 & MIPS_CONF1_FP) {
+ 		c->options |= MIPS_CPU_FPU;
+ 		c->options |= MIPS_CPU_32FPR;
+ 	}
++	if (cpu_has_tlb)
++		c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
++
++	return config1 & MIPS_CONF_M;
++}
++
++static inline unsigned int decode_config2(struct cpuinfo_mips *c)
++{
++	unsigned int config2;
++
++	config2 = read_c0_config2();
++
++	if (config2 & MIPS_CONF2_SL)
++		c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
++
++	return config2 & MIPS_CONF_M;
++}
++
++static inline unsigned int decode_config3(struct cpuinfo_mips *c)
++{
++	unsigned int config3;
++
++	config3 = read_c0_config3();
++
++	if (config3 & MIPS_CONF3_SM)
++		c->ases |= MIPS_ASE_SMARTMIPS;
++	if (config3 & MIPS_CONF3_DSP)
++		c->ases |= MIPS_ASE_DSP;
++	if (config3 & MIPS_CONF3_VINT)
++		c->options |= MIPS_CPU_VINT;
++	if (config3 & MIPS_CONF3_VEIC)
++		c->options |= MIPS_CPU_VEIC;
++	if (config3 & MIPS_CONF3_MT)
++                c->ases |= MIPS_ASE_MIPSMT;
++
++	return config3 & MIPS_CONF_M;
++}
++
++static inline void decode_configs(struct cpuinfo_mips *c)
++{
++	/* MIPS32 or MIPS64 compliant CPU.  */
++	c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
++	             MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
++
+ 	c->scache.flags = MIPS_CACHE_NOT_PRESENT;
+ 
+-	c->tlbsize = ((config1 >> 25) & 0x3f) + 1;
++	/* Read Config registers.  */
++	if (!decode_config0(c))
++		return;			/* actually worth a panic() */
++	if (!decode_config1(c))
++		return;
++	if (!decode_config2(c))
++		return;
++	if (!decode_config3(c))
++		return;
+ }
+ 
+ static inline void cpu_probe_mips(struct cpuinfo_mips *c)
+ {
+-	decode_config1(c);
++	decode_configs(c);
+ 	switch (c->processor_id & 0xff00) {
+ 	case PRID_IMP_4KC:
+ 		c->cputype = CPU_4KC;
+-		c->isa_level = MIPS_CPU_ISA_M32;
+ 		break;
+ 	case PRID_IMP_4KEC:
+ 		c->cputype = CPU_4KEC;
+-		c->isa_level = MIPS_CPU_ISA_M32;
++		break;
++	case PRID_IMP_4KECR2:
++		c->cputype = CPU_4KEC;
+ 		break;
+ 	case PRID_IMP_4KSC:
++	case PRID_IMP_4KSD:
+ 		c->cputype = CPU_4KSC;
+-		c->isa_level = MIPS_CPU_ISA_M32;
+ 		break;
+ 	case PRID_IMP_5KC:
+ 		c->cputype = CPU_5KC;
+-		c->isa_level = MIPS_CPU_ISA_M64;
+ 		break;
+ 	case PRID_IMP_20KC:
+ 		c->cputype = CPU_20KC;
+-		c->isa_level = MIPS_CPU_ISA_M64;
+ 		break;
+ 	case PRID_IMP_24K:
++	case PRID_IMP_24KE:
+ 		c->cputype = CPU_24K;
+-		c->isa_level = MIPS_CPU_ISA_M32;
+ 		break;
+ 	case PRID_IMP_25KF:
+ 		c->cputype = CPU_25KF;
+-		c->isa_level = MIPS_CPU_ISA_M64;
+ 		/* Probe for L2 cache */
+ 		c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+ 		break;
++	case PRID_IMP_34K:
++		c->cputype = CPU_34K;
++		c->isa_level = MIPS_CPU_ISA_M32;
++		break;
+ 	}
+ }
+ 
+ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
+ {
+-	decode_config1(c);
++	decode_configs(c);
+ 	switch (c->processor_id & 0xff00) {
+ 	case PRID_IMP_AU1_REV1:
+ 	case PRID_IMP_AU1_REV2:
+@@ -505,50 +592,70 @@ static inline void cpu_probe_alchemy(str
+ 		case 3:
+ 			c->cputype = CPU_AU1550;
+ 			break;
++		case 4:
++			c->cputype = CPU_AU1200;
++			break;
+ 		default:
+ 			panic("Unknown Au Core!");
+ 			break;
+ 		}
+-		c->isa_level = MIPS_CPU_ISA_M32;
+ 		break;
+ 	}
+ }
+ 
+ static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
+ {
+-	decode_config1(c);
++	decode_configs(c);
++
++	/*
++	 * For historical reasons the SB1 comes with it's own variant of
++	 * cache code which eventually will be folded into c-r4k.c.  Until
++	 * then we pretend it's got it's own cache architecture.
++	 */
++	c->options &= ~MIPS_CPU_4K_CACHE;
++	c->options |= MIPS_CPU_SB1_CACHE;
++
+ 	switch (c->processor_id & 0xff00) {
+ 	case PRID_IMP_SB1:
+ 		c->cputype = CPU_SB1;
+-		c->isa_level = MIPS_CPU_ISA_M64;
+-		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+-		             MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
+-		             MIPS_CPU_MCHECK | MIPS_CPU_EJTAG |
+-		             MIPS_CPU_WATCH | MIPS_CPU_LLSC;
+-#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
++#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+ 		/* FPU in pass1 is known to have issues. */
+-		c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
++		c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
+ #endif
+ 		break;
++	case PRID_IMP_SB1A:
++		c->cputype = CPU_SB1A;
++		break;
+ 	}
+ }
+ 
+ static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
+ {
+-	decode_config1(c);
++	decode_configs(c);
+ 	switch (c->processor_id & 0xff00) {
+ 	case PRID_IMP_SR71000:
+ 		c->cputype = CPU_SR71000;
+-		c->isa_level = MIPS_CPU_ISA_M64;
+-		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+-		             MIPS_CPU_4KTLB | MIPS_CPU_FPU |
+-		             MIPS_CPU_COUNTER | MIPS_CPU_MCHECK;
+ 		c->scache.ways = 8;
+ 		c->tlbsize = 64;
+ 		break;
+ 	}
+ }
+ 
++static inline void cpu_probe_philips(struct cpuinfo_mips *c)
++{
++	decode_configs(c);
++	switch (c->processor_id & 0xff00) {
++	case PRID_IMP_PR4450:
++		c->cputype = CPU_PR4450;
++		c->isa_level = MIPS_CPU_ISA_M32;
++		break;
++	default:
++		panic("Unknown Philips Core!"); /* REVISIT: die? */
++		break;
++	}
++}
++
++
+ __init void cpu_probe(void)
+ {
+ 	struct cpuinfo_mips *c = &current_cpu_data;
+@@ -571,15 +678,24 @@ __init void cpu_probe(void)
+ 	case PRID_COMP_SIBYTE:
+ 		cpu_probe_sibyte(c);
+ 		break;
+-
+ 	case PRID_COMP_SANDCRAFT:
+ 		cpu_probe_sandcraft(c);
+ 		break;
++ 	case PRID_COMP_PHILIPS:
++		cpu_probe_philips(c);
++ 		break;
+ 	default:
+ 		c->cputype = CPU_UNKNOWN;
+ 	}
+-	if (c->options & MIPS_CPU_FPU)
++	if (c->options & MIPS_CPU_FPU) {
+ 		c->fpu_id = cpu_get_fpu_id();
++
++		if (c->isa_level == MIPS_CPU_ISA_M32 ||
++		    c->isa_level == MIPS_CPU_ISA_M64) {
++			if (c->fpu_id & MIPS_FPIR_3D)
++				c->ases |= MIPS_ASE_MIPS3D;
++		}
++	}
+ }
+ 
+ __init void cpu_report(void)
+diff --git a/arch/mips/kernel/dma-no-isa.c b/arch/mips/kernel/dma-no-isa.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/kernel/dma-no-isa.c
+@@ -0,0 +1,28 @@
++/*
++ * 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 by Ralf Baechle
++ *
++ * Dummy ISA DMA functions for systems that don't have ISA but share drivers
++ * with ISA such as legacy free PCI.
++ */
++#include <linux/errno.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++
++DEFINE_SPINLOCK(dma_spin_lock);
++
++int request_dma(unsigned int dmanr, const char * device_id)
++{
++	return -EINVAL;
++}
++
++void free_dma(unsigned int dmanr)
++{
++}
++
++EXPORT_SYMBOL(dma_spin_lock);
++EXPORT_SYMBOL(request_dma);
++EXPORT_SYMBOL(free_dma);
+diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
+--- a/arch/mips/kernel/entry.S
++++ b/arch/mips/kernel/entry.S
+@@ -19,11 +19,11 @@
+ #include <asm/war.h>
+ 
+ #ifdef CONFIG_PREEMPT
+-	.macro	preempt_stop reg=t0
++	.macro	preempt_stop
+ 	.endm
+ #else
+-	.macro	preempt_stop reg=t0
+-	local_irq_disable \reg
++	.macro	preempt_stop
++	local_irq_disable
+ 	.endm
+ #define resume_kernel	restore_all
+ #endif
+@@ -37,17 +37,18 @@ FEXPORT(ret_from_irq)
+ 	andi	t0, t0, KU_USER
+ 	beqz	t0, resume_kernel
+ 
+-FEXPORT(resume_userspace)
+-	local_irq_disable	t0	# make sure we dont miss an
++resume_userspace:
++	local_irq_disable		# make sure we dont miss an
+ 					# interrupt setting need_resched
+ 					# between sampling and return
+ 	LONG_L	a2, TI_FLAGS($28)	# current->work
+-	andi	a2, _TIF_WORK_MASK	# (ignoring syscall_trace)
+-	bnez	a2, work_pending
++	andi	t0, a2, _TIF_WORK_MASK	# (ignoring syscall_trace)
++	bnez	t0, work_pending
+ 	j	restore_all
+ 
+ #ifdef CONFIG_PREEMPT
+-ENTRY(resume_kernel)
++resume_kernel:
++	local_irq_disable
+ 	lw	t0, TI_PRE_COUNT($28)
+ 	bnez	t0, restore_all
+ need_resched:
+@@ -57,12 +58,7 @@ need_resched:
+ 	LONG_L	t0, PT_STATUS(sp)		# Interrupts off?
+ 	andi	t0, 1
+ 	beqz	t0, restore_all
+-	li	t0, PREEMPT_ACTIVE
+-	sw	t0, TI_PRE_COUNT($28)
+-	local_irq_enable t0
+-	jal	schedule
+-	sw	zero, TI_PRE_COUNT($28)
+-	local_irq_disable t0
++	jal	preempt_schedule_irq
+ 	b	need_resched
+ #endif
+ 
+@@ -88,13 +84,13 @@ FEXPORT(restore_partial)		# restore part
+ 	RESTORE_SP_AND_RET
+ 	.set	at
+ 
+-FEXPORT(work_pending)
+-	andi	t0, a2, _TIF_NEED_RESCHED
++work_pending:
++	andi	t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
+ 	beqz	t0, work_notifysig
+ work_resched:
+ 	jal	schedule
+ 
+-	local_irq_disable t0		# make sure need_resched and
++	local_irq_disable		# make sure need_resched and
+ 					# signals dont change between
+ 					# sampling and return
+ 	LONG_L	a2, TI_FLAGS($28)
+@@ -109,15 +105,14 @@ work_notifysig:				# deal with pending s
+ 	move	a0, sp
+ 	li	a1, 0
+ 	jal	do_notify_resume	# a2 already loaded
+-	j	restore_all
++	j	resume_userspace
+ 
+ FEXPORT(syscall_exit_work_partial)
+ 	SAVE_STATIC
+-FEXPORT(syscall_exit_work)
+-	LONG_L	t0, TI_FLAGS($28)
+-	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+-	and	t0, t1
+-	beqz	t0, work_pending	# trace bit is set
++syscall_exit_work:
++	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
++	and	t0, a2			# a2 is preloaded with TI_FLAGS
++	beqz	t0, work_pending	# trace bit set?
+ 	local_irq_enable		# could let do_syscall_trace()
+ 					# call schedule() instead
+ 	move	a0, sp
+@@ -128,28 +123,25 @@ FEXPORT(syscall_exit_work)
+ /*
+  * Common spurious interrupt handler.
+  */
+-	.text
+-	.align  5
+ LEAF(spurious_interrupt)
+ 	/*
+ 	 * Someone tried to fool us by sending an interrupt but we
+ 	 * couldn't find a cause for it.
+ 	 */
++	PTR_LA	t1, irq_err_count
+ #ifdef CONFIG_SMP
+-	lui     t1, %hi(irq_err_count)
+-1:	ll      t0, %lo(irq_err_count)(t1)
++1:	ll      t0, (t1)
+ 	addiu   t0, 1
+-	sc      t0, %lo(irq_err_count)(t1)
++	sc      t0, (t1)
+ #if R10000_LLSC_WAR
+ 	beqzl	t0, 1b
+ #else
+ 	beqz	t0, 1b
+ #endif
+ #else
+-	lui     t1, %hi(irq_err_count)
+-	lw      t0, %lo(irq_err_count)(t1)
++	lw      t0, (t1)
+ 	addiu   t0, 1
+-	sw      t0, %lo(irq_err_count)(t1)
++	sw      t0, (t1)
+ #endif
+ 	j	ret_from_irq
+ 	END(spurious_interrupt)
+diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S
+--- a/arch/mips/kernel/gdb-low.S
++++ b/arch/mips/kernel/gdb-low.S
+@@ -52,16 +52,15 @@
+ 		/*
+ 		 * Called from user mode, go somewhere else.
+ 		 */
+-		lui	k1, %hi(saved_vectors)
+ 		mfc0	k0, CP0_CAUSE
+ 		andi	k0, k0, 0x7c
+ 		add	k1, k1, k0
+-		lw	k0, %lo(saved_vectors)(k1)
++		PTR_L	k0, saved_vectors(k1)
+ 		jr	k0
+ 		nop
+ 1:
+ 		move	k0, sp
+-		subu	sp, k1, GDB_FR_SIZE*2	# see comment above
++		PTR_SUBU sp, k1, GDB_FR_SIZE*2	# see comment above
+ 		LONG_S	k0, GDB_FR_REG29(sp)
+ 		LONG_S	$2, GDB_FR_REG2(sp)
+ 
+diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
+--- a/arch/mips/kernel/gdb-stub.c
++++ b/arch/mips/kernel/gdb-stub.c
+@@ -176,8 +176,10 @@ int kgdb_enabled;
+ /*
+  * spin locks for smp case
+  */
+-static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED;
+-static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED};
++static DEFINE_SPINLOCK(kgdb_lock);
++static raw_spinlock_t kgdb_cpulock[NR_CPUS] = {
++	[0 ... NR_CPUS-1] = __RAW_SPIN_LOCK_UNLOCKED;
++};
+ 
+ /*
+  * BUFMAX defines the maximum number of characters in inbound/outbound buffers
+@@ -637,29 +639,32 @@ static struct gdb_bp_save async_bp;
+  * and only one can be active at a time.
+  */
+ extern spinlock_t smp_call_lock;
++
+ void set_async_breakpoint(unsigned long *epc)
+ {
+ 	/* skip breaking into userland */
+ 	if ((*epc & 0x80000000) == 0)
+ 		return;
+ 
++#ifdef CONFIG_SMP
+ 	/* avoid deadlock if someone is make IPC */
+ 	if (spin_is_locked(&smp_call_lock))
+ 		return;
++#endif
+ 
+ 	async_bp.addr = *epc;
+ 	*epc = (unsigned long)async_breakpoint;
+ }
+ 
+-void kgdb_wait(void *arg)
++static void kgdb_wait(void *arg)
+ {
+ 	unsigned flags;
+ 	int cpu = smp_processor_id();
+ 
+ 	local_irq_save(flags);
+ 
+-	spin_lock(&kgdb_cpulock[cpu]);
+-	spin_unlock(&kgdb_cpulock[cpu]);
++	__raw_spin_lock(&kgdb_cpulock[cpu]);
++	__raw_spin_unlock(&kgdb_cpulock[cpu]);
+ 
+ 	local_irq_restore(flags);
+ }
+@@ -707,7 +712,7 @@ void handle_exception (struct gdb_regs *
+ 	 * acquire the CPU spinlocks
+ 	 */
+ 	for (i = num_online_cpus()-1; i >= 0; i--)
+-		if (spin_trylock(&kgdb_cpulock[i]) == 0)
++		if (__raw_spin_trylock(&kgdb_cpulock[i]) == 0)
+ 			panic("kgdb: couldn't get cpulock %d\n", i);
+ 
+ 	/*
+@@ -982,7 +987,7 @@ finish_kgdb:
+ exit_kgdb_exception:
+ 	/* release locks so other CPUs can go */
+ 	for (i = num_online_cpus()-1; i >= 0; i--)
+-		spin_unlock(&kgdb_cpulock[i]);
++		__raw_spin_unlock(&kgdb_cpulock[i]);
+ 	spin_unlock(&kgdb_lock);
+ 
+ 	__flush_cache_all();
+@@ -1036,12 +1041,12 @@ void adel(void)
+  * malloc is needed by gdb client in "call func()", even a private one
+  * will make gdb happy
+  */
+-static void *malloc(size_t size)
++static void * __attribute_used__ malloc(size_t size)
+ {
+ 	return kmalloc(size, GFP_ATOMIC);
+ }
+ 
+-static void free(void *where)
++static void __attribute_used__ free (void *where)
+ {
+ 	kfree(where);
+ }
+diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
+--- a/arch/mips/kernel/genex.S
++++ b/arch/mips/kernel/genex.S
+@@ -82,7 +82,7 @@ NESTED(except_vec3_r4000, 0, sp)
+ 	 li	k0, 14<<2
+ 	beq	k1, k0, handle_vcei
+ #ifdef CONFIG_64BIT
+-	dsll	k1, k1, 1
++	 dsll	k1, k1, 1
+ #endif
+ 	.set	pop
+ 	PTR_L	k0, exception_handlers(k1)
+@@ -90,17 +90,17 @@ NESTED(except_vec3_r4000, 0, sp)
+ 
+ 	/*
+ 	 * Big shit, we now may have two dirty primary cache lines for the same
+-	 * physical address.  We can savely invalidate the line pointed to by
++	 * physical address.  We can safely invalidate the line pointed to by
+ 	 * c0_badvaddr because after return from this exception handler the
+ 	 * load / store will be re-executed.
+ 	 */
+ handle_vced:
+-	DMFC0	k0, CP0_BADVADDR
++	MFC0	k0, CP0_BADVADDR
+ 	li	k1, -4					# Is this ...
+ 	and	k0, k1					# ... really needed?
+ 	mtc0	zero, CP0_TAGLO
+-	cache	Index_Store_Tag_D,(k0)
+-	cache	Hit_Writeback_Inv_SD,(k0)
++	cache	Index_Store_Tag_D, (k0)
++	cache	Hit_Writeback_Inv_SD, (k0)
+ #ifdef CONFIG_PROC_FS
+ 	PTR_LA	k0, vced_count
+ 	lw	k1, (k0)
+@@ -148,6 +148,38 @@ NESTED(except_vec_ejtag_debug, 0, sp)
+ 	__FINIT
+ 
+ /*
++ * Vectored interrupt handler.
++ * This prototype is copied to ebase + n*IntCtl.VS and patched
++ * to invoke the handler
++ */
++NESTED(except_vec_vi, 0, sp)
++	SAVE_SOME
++	SAVE_AT
++	.set	push
++	.set	noreorder
++EXPORT(except_vec_vi_lui)
++	lui	v0, 0		/* Patched */
++	j	except_vec_vi_handler
++EXPORT(except_vec_vi_ori)
++	 ori	v0, 0		/* Patched */
++	.set	pop
++	END(except_vec_vi)
++EXPORT(except_vec_vi_end)
++
++/*
++ * Common Vectored Interrupt code
++ * Complete the register saves and invoke the handler which is passed in $v0
++ */
++NESTED(except_vec_vi_handler, 0, sp)
++	SAVE_TEMP
++	SAVE_STATIC
++	CLI
++	move	a0, sp
++	jalr	v0
++	j	ret_from_irq
++	END(except_vec_vi_handler)
++
++/*
+  * EJTAG debug exception handler.
+  */
+ NESTED(ejtag_debug_handler, PT_SIZE, sp)
+@@ -291,6 +323,8 @@ NESTED(nmi_handler, PT_SIZE, sp)
+ 	BUILD_HANDLER mdmx mdmx sti silent		/* #22 */
+ 	BUILD_HANDLER watch watch sti verbose		/* #23 */
+ 	BUILD_HANDLER mcheck mcheck cli verbose		/* #24 */
++	BUILD_HANDLER mt mt sti verbose			/* #25 */
++	BUILD_HANDLER dsp dsp sti silent		/* #26 */
+ 	BUILD_HANDLER reserved reserved sti verbose	/* others */
+ 
+ #ifdef CONFIG_64BIT
+diff --git a/arch/mips/kernel/genrtc.c b/arch/mips/kernel/genrtc.c
+deleted file mode 100644
+--- a/arch/mips/kernel/genrtc.c
++++ /dev/null
+@@ -1,64 +0,0 @@
+-/*
+- * A glue layer that provides RTC read/write to drivers/char/genrtc.c driver
+- * based on MIPS internal RTC routines.  It does take care locking
+- * issues so that we are SMP/Preemption safe.
+- *
+- * Copyright (C) 2004 MontaVista Software Inc.
+- * Author: Jun Sun, jsun at mvista.com or jsun at junsun.net
+- *
+- * Please read the COPYING file for all license details.
+- */
+-
+-#include <linux/spinlock.h>
+-
+-#include <asm/rtc.h>
+-#include <asm/time.h>
+-
+-static DEFINE_SPINLOCK(mips_rtc_lock);
+-
+-unsigned int get_rtc_time(struct rtc_time *time)
+-{
+-	unsigned long nowtime;
+-
+-	spin_lock(&mips_rtc_lock);
+-	nowtime = rtc_get_time();
+-	to_tm(nowtime, time);
+-	time->tm_year -= 1900;
+-	spin_unlock(&mips_rtc_lock);
+-
+-	return RTC_24H;
+-}
+-
+-int set_rtc_time(struct rtc_time *time)
+-{
+-	unsigned long nowtime;
+-	int ret;
+-
+-	spin_lock(&mips_rtc_lock);
+-	nowtime = mktime(time->tm_year+1900, time->tm_mon+1,
+-			time->tm_mday, time->tm_hour, time->tm_min,
+-			time->tm_sec);
+-	ret = rtc_set_time(nowtime);
+-	spin_unlock(&mips_rtc_lock);
+-
+-	return ret;
+-}
+-
+-unsigned int get_rtc_ss(void)
+-{
+-	struct rtc_time h;
+-
+-	get_rtc_time(&h);
+-	return h.tm_sec;
+-}
+-
+-int get_rtc_pll(struct rtc_pll_info *pll)
+-{
+-	return -EINVAL;
+-}
+-
+-int set_rtc_pll(struct rtc_pll_info *pll)
+-{
+-	return -EINVAL;
+-}
+-
+diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
+--- a/arch/mips/kernel/head.S
++++ b/arch/mips/kernel/head.S
+@@ -22,11 +22,8 @@
+ #include <asm/page.h>
+ #include <asm/mipsregs.h>
+ #include <asm/stackframe.h>
+-#ifdef CONFIG_SGI_IP27
+-#include <asm/sn/addrs.h>
+-#include <asm/sn/sn0/hubni.h>
+-#include <asm/sn/klkernvars.h>
+-#endif
++
++#include <kernel-entry-init.h>
+ 
+ 	.macro	ARC64_TWIDDLE_PC
+ #if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
+@@ -38,18 +35,6 @@
+ #endif
+ 	.endm
+ 
+-#ifdef CONFIG_SGI_IP27
+-	/*
+-	 * outputs the local nasid into res.  IP27 stuff.
+-	 */
+-	.macro GET_NASID_ASM res
+-	dli	\res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
+-	ld	\res, (\res)
+-	and	\res, NSRI_NODEID_MASK
+-	dsrl	\res, NSRI_NODEID_SHFT
+-	.endm
+-#endif /* CONFIG_SGI_IP27 */
+-
+ 	/*
+ 	 * inputs are the text nasid in t1, data nasid in t2.
+ 	 */
+@@ -131,16 +116,21 @@
+ EXPORT(stext)					# used for profiling
+ EXPORT(_stext)
+ 
++#if defined(CONFIG_QEMU) || defined(CONFIG_MIPS_SIM)
++	/*
++	 * Give us a fighting chance of running if execution beings at the
++	 * kernel load address.  This is needed because this platform does
++	 * not have a ELF loader yet.
++	 */
++	j	kernel_entry
++#endif
+ 	__INIT
+ 
+ NESTED(kernel_entry, 16, sp)			# kernel entry point
+-	setup_c0_status_pri
+ 
+-#ifdef CONFIG_SGI_IP27
+-	GET_NASID_ASM	t1
+-	move	t2, t1				# text and data are here
+-	MAPPED_KERNEL_SETUP_TLB
+-#endif /* IP27 */
++	kernel_entry_setup			# cpu specific setup
++
++	setup_c0_status_pri
+ 
+ 	ARC64_TWIDDLE_PC
+ 
+@@ -157,6 +147,7 @@ NESTED(kernel_entry, 16, sp)			# kernel 
+ 	LONG_S		a2, fw_arg2
+ 	LONG_S		a3, fw_arg3
+ 
++	MTC0		zero, CP0_CONTEXT	# clear context register
+ 	PTR_LA		$28, init_thread_union
+ 	PTR_ADDIU	sp, $28, _THREAD_SIZE - 32
+ 	set_saved_sp	sp, t0, t1
+@@ -165,6 +156,10 @@ NESTED(kernel_entry, 16, sp)			# kernel 
+ 	j		start_kernel
+ 	END(kernel_entry)
+ 
++#ifdef CONFIG_QEMU
++	__INIT
++#endif
++
+ #ifdef CONFIG_SMP
+ /*
+  * SMP slave cpus entry point.  Board specific code for bootstrap calls this
+@@ -172,20 +167,7 @@ NESTED(kernel_entry, 16, sp)			# kernel 
+  */
+ NESTED(smp_bootstrap, 16, sp)
+ 	setup_c0_status_sec
+-
+-#ifdef CONFIG_SGI_IP27
+-	GET_NASID_ASM	t1
+-	dli	t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
+-		    KLDIR_OFF_POINTER + CAC_BASE
+-	dsll	t1, NASID_SHFT
+-	or	t0, t0, t1
+-	ld	t0, 0(t0)			# t0 points to kern_vars struct
+-	lh	t1, KV_RO_NASID_OFFSET(t0)
+-	lh	t2, KV_RW_NASID_OFFSET(t0)
+-	MAPPED_KERNEL_SETUP_TLB
+-	ARC64_TWIDDLE_PC
+-#endif /* CONFIG_SGI_IP27 */
+-
++	smp_slave_setup
+ 	j	start_secondary
+ 	END(smp_bootstrap)
+ #endif /* CONFIG_SMP */
+@@ -200,19 +182,13 @@ NESTED(smp_bootstrap, 16, sp)
+ 	.comm	fw_arg2, SZREG, SZREG
+ 	.comm	fw_arg3, SZREG, SZREG
+ 
+-	.macro	page name, order=0
+-	.globl	\name
+-\name:	.size	\name, (_PAGE_SIZE << \order)
+-	.org	. + (_PAGE_SIZE << \order)
+-	.type	\name, @object
++	.macro page name, order
++	.comm	\name, (_PAGE_SIZE << \order), (_PAGE_SIZE << \order)
+ 	.endm
+ 
+-	.data
+-	.align	PAGE_SHIFT
+-
+ 	/*
+-	 * ... but on 64-bit we've got three-level pagetables with a
+-	 * slightly different layout ...
++	 * On 64-bit we've got three-level pagetables with a slightly
++	 * different layout ...
+ 	 */
+ 	page	swapper_pg_dir, _PGD_ORDER
+ #ifdef CONFIG_64BIT
+diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
+--- a/arch/mips/kernel/i8259.c
++++ b/arch/mips/kernel/i8259.c
+@@ -31,7 +31,7 @@ void disable_8259A_irq(unsigned int irq)
+  * moves to arch independent land
+  */
+ 
+-spinlock_t DEFINE_SPINLOCK(i8259A_lock);
++DEFINE_SPINLOCK(i8259A_lock);
+ 
+ static void end_8259A_irq (unsigned int irq)
+ {
+@@ -52,14 +52,13 @@ static unsigned int startup_8259A_irq(un
+ }
+ 
+ static struct hw_interrupt_type i8259A_irq_type = {
+-	"XT-PIC",
+-	startup_8259A_irq,
+-	shutdown_8259A_irq,
+-	enable_8259A_irq,
+-	disable_8259A_irq,
+-	mask_and_ack_8259A,
+-	end_8259A_irq,
+-	NULL
++	.typename = "XT-PIC",
++	.startup = startup_8259A_irq,
++	.shutdown = shutdown_8259A_irq,
++	.enable = enable_8259A_irq,
++	.disable = disable_8259A_irq,
++	.ack = mask_and_ack_8259A,
++	.end = end_8259A_irq,
+ };
+ 
+ /*
+@@ -308,7 +307,7 @@ static struct resource pic2_io_resource 
+ 
+ /*
+  * On systems with i8259-style interrupt controllers we assume for
+- * driver compatibility reasons interrupts 0 - 15 to be the i8295
++ * driver compatibility reasons interrupts 0 - 15 to be the i8259
+  * interrupts even if the hardware uses a different interrupt numbering.
+  */
+ void __init init_i8259_irqs (void)
+@@ -322,7 +321,7 @@ void __init init_i8259_irqs (void)
+ 
+ 	for (i = 0; i < 16; i++) {
+ 		irq_desc[i].status = IRQ_DISABLED;
+-		irq_desc[i].action = 0;
++		irq_desc[i].action = NULL;
+ 		irq_desc[i].depth = 1;
+ 		irq_desc[i].handler = &i8259A_irq_type;
+ 	}
+diff --git a/arch/mips/kernel/ioctl32.c b/arch/mips/kernel/ioctl32.c
+--- a/arch/mips/kernel/ioctl32.c
++++ b/arch/mips/kernel/ioctl32.c
+@@ -41,12 +41,6 @@ IOCTL_TABLE_START
+ #define DECLARES
+ #include "compat_ioctl.c"
+ 
+-#ifdef CONFIG_SIBYTE_TBPROF
+-COMPATIBLE_IOCTL(SBPROF_ZBSTART)
+-COMPATIBLE_IOCTL(SBPROF_ZBSTOP)
+-COMPATIBLE_IOCTL(SBPROF_ZBWAITFULL)
+-#endif /* CONFIG_SIBYTE_TBPROF */
+-
+ /*HANDLE_IOCTL(RTC_IRQP_READ, w_long)
+ COMPATIBLE_IOCTL(RTC_IRQP_SET)
+ HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
+diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
+--- a/arch/mips/kernel/irixelf.c
++++ b/arch/mips/kernel/irixelf.c
+@@ -8,7 +8,7 @@
+  *
+  * Copyright (C) 1993 - 1994 Eric Youngdale <ericy at cais.com>
+  * Copyright (C) 1996 - 2004 David S. Miller <dm at engr.sgi.com>
+- * Copyright (C) 2004 Steven J. Hill <sjhill at realitydiluted.com>
++ * Copyright (C) 2004 - 2005 Steven J. Hill <sjhill at realitydiluted.com>
+  */
+ #include <linux/module.h>
+ #include <linux/fs.h>
+@@ -31,15 +31,16 @@
+ #include <linux/elfcore.h>
+ #include <linux/smp_lock.h>
+ 
+-#include <asm/uaccess.h>
+ #include <asm/mipsregs.h>
++#include <asm/namei.h>
+ #include <asm/prctl.h>
++#include <asm/uaccess.h>
+ 
+ #define DLINFO_ITEMS 12
+ 
+ #include <linux/elf.h>
+ 
+-#undef DEBUG_ELF
++#undef DEBUG
+ 
+ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
+ static int load_irix_library(struct file *);
+@@ -55,7 +56,7 @@ static struct linux_binfmt irix_format =
+ #define elf_addr_t unsigned long
+ #endif
+ 
+-#ifdef DEBUG_ELF
++#ifdef DEBUG
+ /* Debugging routines. */
+ static char *get_elf_p_type(Elf32_Word p_type)
+ {
+@@ -120,7 +121,7 @@ static void dump_phdrs(struct elf_phdr *
+ 			print_phdr(i, ep);
+ 	}
+ }
+-#endif /* (DEBUG_ELF) */
++#endif /* DEBUG */
+ 
+ static void set_brk(unsigned long start, unsigned long end)
+ {
+@@ -146,20 +147,20 @@ static void padzero(unsigned long elf_bs
+ 	nbyte = elf_bss & (PAGE_SIZE-1);
+ 	if (nbyte) {
+ 		nbyte = PAGE_SIZE - nbyte;
+-		clear_user((void *) elf_bss, nbyte);
++		clear_user((void __user *) elf_bss, nbyte);
+ 	}
+ }
+ 
+-unsigned long * create_irix_tables(char * p, int argc, int envc,
+-				   struct elfhdr * exec, unsigned int load_addr,
+-				   unsigned int interp_load_addr,
+-				   struct pt_regs *regs, struct elf_phdr *ephdr)
++static unsigned long * create_irix_tables(char * p, int argc, int envc,
++	struct elfhdr * exec, unsigned int load_addr,
++	unsigned int interp_load_addr, struct pt_regs *regs,
++	struct elf_phdr *ephdr)
+ {
+ 	elf_addr_t *argv;
+ 	elf_addr_t *envp;
+ 	elf_addr_t *sp, *csp;
+ 
+-#ifdef DEBUG_ELF
++#ifdef DEBUG
+ 	printk("create_irix_tables: p[%p] argc[%d] envc[%d] "
+ 	       "load_addr[%08x] interp_load_addr[%08x]\n",
+ 	       p, argc, envc, load_addr, interp_load_addr);
+@@ -248,14 +249,13 @@ static unsigned int load_irix_interp(str
+ 	last_bss = 0;
+ 	error = load_addr = 0;
+ 
+-#ifdef DEBUG_ELF
++#ifdef DEBUG
+ 	print_elfhdr(interp_elf_ex);
+ #endif
+ 
+ 	/* First of all, some simple consistency checks */
+ 	if ((interp_elf_ex->e_type != ET_EXEC &&
+ 	     interp_elf_ex->e_type != ET_DYN) ||
+-	     !irix_elf_check_arch(interp_elf_ex) ||
+ 	     !interpreter->f_op->mmap) {
+ 		printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type);
+ 		return 0xffffffff;
+@@ -290,7 +290,7 @@ static unsigned int load_irix_interp(str
+ 			   (char *) elf_phdata,
+ 			   sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
+ 
+-#ifdef DEBUG_ELF
++#ifdef DEBUG
+ 	dump_phdrs(elf_phdata, interp_elf_ex->e_phnum);
+ #endif
+ 
+@@ -306,13 +306,11 @@ static unsigned int load_irix_interp(str
+ 	    elf_type |= MAP_FIXED;
+ 	    vaddr = eppnt->p_vaddr;
+ 
+-#ifdef DEBUG_ELF
+-	    printk("INTERP do_mmap(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",
++	    pr_debug("INTERP do_mmap(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",
+ 		   interpreter, vaddr,
+ 		   (unsigned long) (eppnt->p_filesz + (eppnt->p_vaddr & 0xfff)),
+ 		   (unsigned long) elf_prot, (unsigned long) elf_type,
+ 		   (unsigned long) (eppnt->p_offset & 0xfffff000));
+-#endif
+ 	    down_write(&current->mm->mmap_sem);
+ 	    error = do_mmap(interpreter, vaddr,
+ 			    eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
+@@ -324,14 +322,10 @@ static unsigned int load_irix_interp(str
+ 		    printk("Aieee IRIX interp mmap error=%d\n", error);
+ 		    break;  /* Real error */
+ 	    }
+-#ifdef DEBUG_ELF
+-	    printk("error=%08lx ", (unsigned long) error);
+-#endif
++	    pr_debug("error=%08lx ", (unsigned long) error);
+ 	    if(!load_addr && interp_elf_ex->e_type == ET_DYN) {
+ 	      load_addr = error;
+-#ifdef DEBUG_ELF
+-              printk("load_addr = error ");
+-#endif
++              pr_debug("load_addr = error ");
+ 	    }
+ 
+ 	    /* Find the end of the file  mapping for this phdr, and keep
+@@ -345,17 +339,13 @@ static unsigned int load_irix_interp(str
+ 	     */
+ 	    k = eppnt->p_memsz + eppnt->p_vaddr;
+ 	    if(k > last_bss) last_bss = k;
+-#ifdef DEBUG_ELF
+-	    printk("\n");
+-#endif
++	    pr_debug("\n");
+ 	  }
+ 	}
+ 
+ 	/* Now use mmap to map the library into memory. */
+ 	if(error < 0 && error > -1024) {
+-#ifdef DEBUG_ELF
+-		printk("got error %d\n", error);
+-#endif
++		pr_debug("got error %d\n", error);
+ 		kfree(elf_phdata);
+ 		return 0xffffffff;
+ 	}
+@@ -365,16 +355,12 @@ static unsigned int load_irix_interp(str
+ 	 * that there are zero-mapped pages up to and including the
+ 	 * last bss page.
+ 	 */
+-#ifdef DEBUG_ELF
+-	printk("padzero(%08lx) ", (unsigned long) (elf_bss));
+-#endif
++	pr_debug("padzero(%08lx) ", (unsigned long) (elf_bss));
+ 	padzero(elf_bss);
+ 	len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */
+ 
+-#ifdef DEBUG_ELF
+-	printk("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss,
+-	       (unsigned long) len);
+-#endif
++	pr_debug("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss,
++	         (unsigned long) len);
+ 
+ 	/* Map the last of the bss segment */
+ 	if (last_bss > len) {
+@@ -396,12 +382,7 @@ static int verify_binary(struct elfhdr *
+ 
+ 	/* First of all, some simple consistency checks */
+ 	if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
+-	    !irix_elf_check_arch(ehp) || !bprm->file->f_op->mmap) {
+-		return -ENOEXEC;
+-	}
+-
+-	/* Only support MIPS ARCH2 or greater IRIX binaries for now. */
+-	if(!(ehp->e_flags & EF_MIPS_ARCH) && !(ehp->e_flags & 0x04)) {
++	    !bprm->file->f_op->mmap) {
+ 		return -ENOEXEC;
+ 	}
+ 
+@@ -411,16 +392,17 @@ static int verify_binary(struct elfhdr *
+ 	 * XXX all registers as 64bits on cpu's capable of this at
+ 	 * XXX exception time plus frob the XTLB exception vector.
+ 	 */
+-	if((ehp->e_flags & 0x20)) {
++	if((ehp->e_flags & EF_MIPS_ABI2))
+ 		return -ENOEXEC;
+-	}
+ 
+-	return 0; /* It's ok. */
++	return 0;
+ }
+ 
+-#define IRIX_INTERP_PREFIX "/usr/gnemul/irix"
+-
+-/* Look for an IRIX ELF interpreter. */
++/*
++ * This is where the detailed check is performed. Irix binaries
++ * use interpreters with 'libc.so' in the name, so this function
++ * can differentiate between Linux and Irix binaries.
++ */
+ static inline int look_for_irix_interpreter(char **name,
+ 					    struct file **interpreter,
+ 					    struct elfhdr *interp_elf_ex,
+@@ -440,12 +422,11 @@ static inline int look_for_irix_interpre
+ 		if (*name != NULL)
+ 			goto out;
+ 
+-		*name = kmalloc((epp->p_filesz + strlen(IRIX_INTERP_PREFIX)),
+-				GFP_KERNEL);
++		*name = kmalloc(epp->p_filesz + strlen(IRIX_EMUL), GFP_KERNEL);
+ 		if (!*name)
+ 			return -ENOMEM;
+ 
+-		strcpy(*name, IRIX_INTERP_PREFIX);
++		strcpy(*name, IRIX_EMUL);
+ 		retval = kernel_read(bprm->file, epp->p_offset, (*name + 16),
+ 		                     epp->p_filesz);
+ 		if (retval < 0)
+@@ -562,7 +543,7 @@ static inline int map_interpreter(struct
+  * process and the system, here we map the page and fill the
+  * structure
+  */
+-void irix_map_prda_page (void)
++static void irix_map_prda_page(void)
+ {
+ 	unsigned long v;
+ 	struct prda *pp;
+@@ -601,14 +582,33 @@ static int load_irix_binary(struct linux
+ 
+ 	load_addr = 0;
+ 	has_interp = has_ephdr = 0;
+-	elf_ihdr = elf_ephdr = 0;
++	elf_ihdr = elf_ephdr = NULL;
+ 	elf_ex = *((struct elfhdr *) bprm->buf);
+ 	retval = -ENOEXEC;
+ 
+ 	if (verify_binary(&elf_ex, bprm))
+ 		goto out;
+ 
+-#ifdef DEBUG_ELF
++	/*
++	 * Telling -o32 static binaries from Linux and Irix apart from each
++	 * other is difficult. There are 2 differences to be noted for static
++	 * binaries from the 2 operating systems:
++	 *
++	 *    1) Irix binaries have their .text section before their .init
++	 *       section. Linux binaries are just the opposite.
++	 *
++	 *    2) Irix binaries usually have <= 12 sections and Linux
++	 *       binaries have > 20.
++	 *
++	 * We will use Method #2 since Method #1 would require us to read in
++	 * the section headers which is way too much overhead. This appears
++	 * to work for everything we have ran into so far. If anyone has a
++	 * better method to tell the binaries apart, I'm listening.
++	 */
++	if (elf_ex.e_shnum > 20)
++		goto out;
++
++#ifdef DEBUG
+ 	print_elfhdr(&elf_ex);
+ #endif
+ 
+@@ -623,11 +623,10 @@ static int load_irix_binary(struct linux
+ 	}
+ 
+ 	retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
+-
+ 	if (retval < 0)
+ 		goto out_free_ph;
+ 
+-#ifdef DEBUG_ELF
++#ifdef DEBUG
+ 	dump_phdrs(elf_phdata, elf_ex.e_phnum);
+ #endif
+ 
+@@ -644,9 +643,8 @@ static int load_irix_binary(struct linux
+ 			break;
+ 		};
+ 	}
+-#ifdef DEBUG_ELF
+-	printk("\n");
+-#endif
++
++	pr_debug("\n");
+ 
+ 	elf_bss = 0;
+ 	elf_brk = 0;
+@@ -657,12 +655,19 @@ static int load_irix_binary(struct linux
+ 	end_code = 0;
+ 	end_data = 0;
+ 
+-	retval = look_for_irix_interpreter(&elf_interpreter,
+-	                                   &interpreter,
++	/*
++	 * If we get a return value, we change the value to be ENOEXEC
++	 * so that we can exit gracefully and the main binary format
++	 * search loop in 'fs/exec.c' will move onto the next handler
++	 * which should be the normal ELF binary handler.
++	 */
++	retval = look_for_irix_interpreter(&elf_interpreter, &interpreter,
+ 					   &interp_elf_ex, elf_phdata, bprm,
+ 					   elf_ex.e_phnum);
+-	if (retval)
++	if (retval) {
++		retval = -ENOEXEC;
+ 		goto out_free_file;
++	}
+ 
+ 	if (elf_interpreter) {
+ 		retval = verify_irix_interpreter(&interp_elf_ex);
+@@ -692,7 +697,6 @@ static int load_irix_binary(struct linux
+ 	/* Do this so that we can load the interpreter, if need be.  We will
+ 	 * change some of these later.
+ 	 */
+-	set_mm_counter(current->mm, rss, 0);
+ 	setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
+ 	current->mm->start_stack = bprm->p;
+ 
+@@ -746,18 +750,16 @@ static int load_irix_binary(struct linux
+ 	 * IRIX maps a page at 0x200000 which holds some system
+ 	 * information.  Programs depend on this.
+ 	 */
+-	irix_map_prda_page ();
++	irix_map_prda_page();
+ 
+ 	padzero(elf_bss);
+ 
+-#ifdef DEBUG_ELF
+-	printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
+-	printk("(end_code) %lx\n" , (long) current->mm->end_code);
+-	printk("(start_code) %lx\n" , (long) current->mm->start_code);
+-	printk("(end_data) %lx\n" , (long) current->mm->end_data);
+-	printk("(start_stack) %lx\n" , (long) current->mm->start_stack);
+-	printk("(brk) %lx\n" , (long) current->mm->brk);
+-#endif
++	pr_debug("(start_brk) %lx\n" , (long) current->mm->start_brk);
++	pr_debug("(end_code) %lx\n" , (long) current->mm->end_code);
++	pr_debug("(start_code) %lx\n" , (long) current->mm->start_code);
++	pr_debug("(end_data) %lx\n" , (long) current->mm->end_data);
++	pr_debug("(start_stack) %lx\n" , (long) current->mm->start_stack);
++	pr_debug("(brk) %lx\n" , (long) current->mm->brk);
+ 
+ #if 0 /* XXX No fucking way dude... */
+ 	/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
+@@ -782,8 +784,7 @@ out_free_dentry:
+ 	allow_write_access(interpreter);
+ 	fput(interpreter);
+ out_free_interp:
+-	if (elf_interpreter)
+-		kfree(elf_interpreter);
++	kfree(elf_interpreter);
+ out_free_file:
+ out_free_ph:
+ 	kfree (elf_phdata);
+@@ -813,7 +814,7 @@ static int load_irix_library(struct file
+ 
+ 	/* First of all, some simple consistency checks. */
+ 	if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
+-	   !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap)
++	   !file->f_op->mmap)
+ 		return -ENOEXEC;
+ 
+ 	/* Now read in all of the header information. */
+@@ -874,35 +875,36 @@ static int load_irix_library(struct file
+  * phdrs there are in the USER_PHDRP array.  We return the vaddr the
+  * first phdr was successfully mapped to.
+  */
+-unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
++unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt)
+ {
+-	struct elf_phdr *hp;
++	unsigned long type, vaddr, filesz, offset, flags;
++	struct elf_phdr __user *hp;
+ 	struct file *filp;
+ 	int i, retval;
+ 
+-#ifdef DEBUG_ELF
+-	printk("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",
+-	       fd, user_phdrp, cnt);
+-#endif
++	pr_debug("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",
++	         fd, user_phdrp, cnt);
+ 
+ 	/* First get the verification out of the way. */
+ 	hp = user_phdrp;
+ 	if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) {
+-#ifdef DEBUG_ELF
+-		printk("irix_mapelf: access_ok fails!\n");
+-#endif
++		pr_debug("irix_mapelf: bad pointer to ELF PHDR!\n");
++
+ 		return -EFAULT;
+ 	}
+ 
+-#ifdef DEBUG_ELF
++#ifdef DEBUG
+ 	dump_phdrs(user_phdrp, cnt);
+ #endif
+ 
+-	for(i = 0; i < cnt; i++, hp++)
+-		if(hp->p_type != PT_LOAD) {
++	for (i = 0; i < cnt; i++, hp++) {
++		if (__get_user(type, &hp->p_type))
++			return -EFAULT;
++		if (type != PT_LOAD) {
+ 			printk("irix_mapelf: One section is not PT_LOAD!\n");
+ 			return -ENOEXEC;
+ 		}
++	}
+ 
+ 	filp = fget(fd);
+ 	if (!filp)
+@@ -917,29 +919,40 @@ unsigned long irix_mapelf(int fd, struct
+ 	for(i = 0; i < cnt; i++, hp++) {
+ 		int prot;
+ 
+-		prot  = (hp->p_flags & PF_R) ? PROT_READ : 0;
+-		prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0;
+-		prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0;
++		retval = __get_user(vaddr, &hp->p_vaddr);
++		retval |= __get_user(filesz, &hp->p_filesz);
++		retval |= __get_user(offset, &hp->p_offset);
++		retval |= __get_user(flags, &hp->p_flags);
++		if (retval)
++			return retval;
++
++		prot  = (flags & PF_R) ? PROT_READ : 0;
++		prot |= (flags & PF_W) ? PROT_WRITE : 0;
++		prot |= (flags & PF_X) ? PROT_EXEC : 0;
++
+ 		down_write(&current->mm->mmap_sem);
+-		retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000),
+-				 (hp->p_filesz + (hp->p_vaddr & 0xfff)),
++		retval = do_mmap(filp, (vaddr & 0xfffff000),
++				 (filesz + (vaddr & 0xfff)),
+ 				 prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
+-				 (hp->p_offset & 0xfffff000));
++				 (offset & 0xfffff000));
+ 		up_write(&current->mm->mmap_sem);
+ 
+-		if(retval != (hp->p_vaddr & 0xfffff000)) {
++		if (retval != (vaddr & 0xfffff000)) {
+ 			printk("irix_mapelf: do_mmap fails with %d!\n", retval);
+ 			fput(filp);
+ 			return retval;
+ 		}
+ 	}
+ 
+-#ifdef DEBUG_ELF
+-	printk("irix_mapelf: Success, returning %08lx\n",
+-		(unsigned long) user_phdrp->p_vaddr);
+-#endif
++	pr_debug("irix_mapelf: Success, returning %08lx\n",
++		 (unsigned long) user_phdrp->p_vaddr);
++
+ 	fput(filp);
+-	return user_phdrp->p_vaddr;
++
++	if (__get_user(vaddr, &user_phdrp->p_vaddr))
++		return -EFAULT;
++
++	return vaddr;
+ }
+ 
+ /*
+@@ -952,9 +965,9 @@ unsigned long irix_mapelf(int fd, struct
+ /* These are the only things you should do on a core-file: use only these
+  * functions to write out all the necessary info.
+  */
+-static int dump_write(struct file *file, const void *addr, int nr)
++static int dump_write(struct file *file, const void __user *addr, int nr)
+ {
+-	return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
++	return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr;
+ }
+ 
+ static int dump_seek(struct file *file, off_t off)
+@@ -1064,8 +1077,8 @@ static int irix_core_dump(long signr, st
+ 	struct elfhdr elf;
+ 	off_t offset = 0, dataoff;
+ 	int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
+-	int numnote = 4;
+-	struct memelfnote notes[4];
++	int numnote = 3;
++	struct memelfnote notes[3];
+ 	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
+ 	elf_fpregset_t fpu;		/* NT_PRFPREG */
+ 	struct elf_prpsinfo psinfo;	/* NT_PRPSINFO */
+@@ -1073,7 +1086,7 @@ static int irix_core_dump(long signr, st
+ 	/* Count what's needed to dump, up to the limit of coredump size. */
+ 	segs = 0;
+ 	size = 0;
+-	for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
++	for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
+ 		if (maydump(vma))
+ 		{
+ 			int sz = vma->vm_end-vma->vm_start;
+@@ -1187,9 +1200,9 @@ static int irix_core_dump(long signr, st
+ 
+ 		len = current->mm->arg_end - current->mm->arg_start;
+ 		len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
+-		copy_from_user(&psinfo.pr_psargs,
+-			       (const char *)current->mm->arg_start, len);
+-		for(i = 0; i < len; i++)
++		(void *) copy_from_user(&psinfo.pr_psargs,
++			       (const char __user *)current->mm->arg_start, len);
++		for (i = 0; i < len; i++)
+ 			if (psinfo.pr_psargs[i] == 0)
+ 				psinfo.pr_psargs[i] = ' ';
+ 		psinfo.pr_psargs[len] = 0;
+@@ -1198,20 +1211,15 @@ static int irix_core_dump(long signr, st
+ 	}
+ 	strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
+ 
+-	notes[2].name = "CORE";
+-	notes[2].type = NT_TASKSTRUCT;
+-	notes[2].datasz = sizeof(*current);
+-	notes[2].data = current;
+-
+ 	/* Try to dump the FPU. */
+ 	prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
+ 	if (!prstatus.pr_fpvalid) {
+ 		numnote--;
+ 	} else {
+-		notes[3].name = "CORE";
+-		notes[3].type = NT_PRFPREG;
+-		notes[3].datasz = sizeof(fpu);
+-		notes[3].data = &fpu;
++		notes[2].name = "CORE";
++		notes[2].type = NT_PRFPREG;
++		notes[2].datasz = sizeof(fpu);
++		notes[2].data = &fpu;
+ 	}
+ 
+ 	/* Write notes phdr entry. */
+@@ -1256,8 +1264,10 @@ static int irix_core_dump(long signr, st
+ 		phdr.p_memsz = sz;
+ 		offset += phdr.p_filesz;
+ 		phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
+-		if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
+-		if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
++		if (vma->vm_flags & VM_WRITE)
++			phdr.p_flags |= PF_W;
++		if (vma->vm_flags & VM_EXEC)
++			phdr.p_flags |= PF_X;
+ 		phdr.p_align = PAGE_SIZE;
+ 
+ 		DUMP_WRITE(&phdr, sizeof(phdr));
+@@ -1283,7 +1293,7 @@ static int irix_core_dump(long signr, st
+ #ifdef DEBUG
+ 		printk("elf_core_dump: writing %08lx %lx\n", addr, len);
+ #endif
+-		DUMP_WRITE((void *)addr, len);
++		DUMP_WRITE((void __user *)addr, len);
+ 	}
+ 
+ 	if ((off_t) file->f_pos != offset) {
+@@ -1299,7 +1309,7 @@ end_coredump:
+ 
+ static int __init init_irix_binfmt(void)
+ {
+-	int init_inventory(void);
++	extern int init_inventory(void);
+ 	extern asmlinkage unsigned long sys_call_table;
+ 	extern asmlinkage unsigned long sys_call_table_irix5;
+ 
+@@ -1318,7 +1328,9 @@ static int __init init_irix_binfmt(void)
+ 
+ static void __exit exit_irix_binfmt(void)
+ {
+-	/* Remove the IRIX ELF loaders. */
++	/*
++	 * Remove the Irix ELF loader.
++	 */
+ 	unregister_binfmt(&irix_format);
+ }
+ 
+diff --git a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c
+--- a/arch/mips/kernel/irixinv.c
++++ b/arch/mips/kernel/irixinv.c
+@@ -30,10 +30,10 @@ void add_to_inventory (int class, int ty
+ 	inventory_items++;
+ }
+ 
+-int dump_inventory_to_user (void *userbuf, int size)
++int dump_inventory_to_user (void __user *userbuf, int size)
+ {
+ 	inventory_t *inv  = &inventory [0];
+-	inventory_t *user = userbuf;
++	inventory_t __user *user = userbuf;
+ 	int v;
+ 
+ 	if (!access_ok(VERIFY_WRITE, userbuf, size))
+@@ -41,7 +41,8 @@ int dump_inventory_to_user (void *userbu
+ 
+ 	for (v = 0; v < inventory_items; v++){
+ 		inv = &inventory [v];
+-		copy_to_user (user, inv, sizeof (inventory_t));
++		if (copy_to_user (user, inv, sizeof (inventory_t)))
++			return -EFAULT;
+ 		user++;
+ 	}
+ 	return inventory_items * sizeof (inventory_t);
+diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
+--- a/arch/mips/kernel/irixioctl.c
++++ b/arch/mips/kernel/irixioctl.c
+@@ -59,7 +59,7 @@ asmlinkage int irix_ioctl(int fd, unsign
+ {
+ 	struct tty_struct *tp, *rtp;
+ 	mm_segment_t old_fs;
+-	int error = 0;
++	int i, error = 0;
+ 
+ #ifdef DEBUG_IOCTLS
+ 	printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd);
+@@ -74,12 +74,13 @@ asmlinkage int irix_ioctl(int fd, unsign
+ 
+ 	case 0x0000540d: {
+ 		struct termios kt;
+-		struct irix_termios *it = (struct irix_termios *) arg;
++		struct irix_termios __user *it =
++			(struct irix_termios __user *) arg;
+ 
+ #ifdef DEBUG_IOCTLS
+ 		printk("TCGETS, %08lx) ", arg);
+ #endif
+-		if(!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
++		if (!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
+ 			error = -EFAULT;
+ 			break;
+ 		}
+@@ -88,13 +89,14 @@ asmlinkage int irix_ioctl(int fd, unsign
+ 		set_fs(old_fs);
+ 		if (error)
+ 			break;
+-		__put_user(kt.c_iflag, &it->c_iflag);
+-		__put_user(kt.c_oflag, &it->c_oflag);
+-		__put_user(kt.c_cflag, &it->c_cflag);
+-		__put_user(kt.c_lflag, &it->c_lflag);
+-		for(error = 0; error < NCCS; error++)
+-			__put_user(kt.c_cc[error], &it->c_cc[error]);
+-		error = 0;
++
++		error = __put_user(kt.c_iflag, &it->c_iflag);
++		error |= __put_user(kt.c_oflag, &it->c_oflag);
++		error |= __put_user(kt.c_cflag, &it->c_cflag);
++		error |= __put_user(kt.c_lflag, &it->c_lflag);
++
++		for (i = 0; i < NCCS; i++)
++			error |= __put_user(kt.c_cc[i], &it->c_cc[i]);
+ 		break;
+ 	}
+ 
+@@ -112,14 +114,19 @@ asmlinkage int irix_ioctl(int fd, unsign
+ 		old_fs = get_fs(); set_fs(get_ds());
+ 		error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
+ 		set_fs(old_fs);
+-		if(error)
++		if (error)
++			break;
++
++		error = __get_user(kt.c_iflag, &it->c_iflag);
++		error |= __get_user(kt.c_oflag, &it->c_oflag);
++		error |= __get_user(kt.c_cflag, &it->c_cflag);
++		error |= __get_user(kt.c_lflag, &it->c_lflag);
++
++		for (i = 0; i < NCCS; i++)
++			error |= __get_user(kt.c_cc[i], &it->c_cc[i]);
++
++		if (error)
+ 			break;
+-		__get_user(kt.c_iflag, &it->c_iflag);
+-		__get_user(kt.c_oflag, &it->c_oflag);
+-		__get_user(kt.c_cflag, &it->c_cflag);
+-		__get_user(kt.c_lflag, &it->c_lflag);
+-		for(error = 0; error < NCCS; error++)
+-			__get_user(kt.c_cc[error], &it->c_cc[error]);
+ 		old_fs = get_fs(); set_fs(get_ds());
+ 		error = sys_ioctl(fd, TCSETS, (unsigned long) &kt);
+ 		set_fs(old_fs);
+@@ -153,7 +160,7 @@ asmlinkage int irix_ioctl(int fd, unsign
+ #ifdef DEBUG_IOCTLS
+ 		printk("rtp->session=%d ", rtp->session);
+ #endif
+-		error = put_user(rtp->session, (unsigned long *) arg);
++		error = put_user(rtp->session, (unsigned long __user *) arg);
+ 		break;
+ 
+ 	case 0x746e:
+@@ -195,50 +202,32 @@ asmlinkage int irix_ioctl(int fd, unsign
+ 		break;
+ 
+ 	case 0x8004667e:
+-#ifdef DEBUG_IOCTLS
+-		printk("FIONBIO, %08lx) arg=%d ", arg, *(int *)arg);
+-#endif
+ 		error = sys_ioctl(fd, FIONBIO, arg);
+ 		break;
+ 
+ 	case 0x80047476:
+-#ifdef DEBUG_IOCTLS
+-		printk("TIOCSPGRP, %08lx) arg=%d ", arg, *(int *)arg);
+-#endif
+ 		error = sys_ioctl(fd, TIOCSPGRP, arg);
+ 		break;
+ 
+ 	case 0x8020690c:
+-#ifdef DEBUG_IOCTLS
+-		printk("SIOCSIFADDR, %08lx) arg=%d ", arg, *(int *)arg);
+-#endif
+ 		error = sys_ioctl(fd, SIOCSIFADDR, arg);
+ 		break;
+ 
+ 	case 0x80206910:
+-#ifdef DEBUG_IOCTLS
+-		printk("SIOCSIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
+-#endif
+ 		error = sys_ioctl(fd, SIOCSIFFLAGS, arg);
+ 		break;
+ 
+ 	case 0xc0206911:
+-#ifdef DEBUG_IOCTLS
+-		printk("SIOCGIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
+-#endif
+ 		error = sys_ioctl(fd, SIOCGIFFLAGS, arg);
+ 		break;
+ 
+ 	case 0xc020691b:
+-#ifdef DEBUG_IOCTLS
+-		printk("SIOCGIFMETRIC, %08lx) arg=%d ", arg, *(int *)arg);
+-#endif
+ 		error = sys_ioctl(fd, SIOCGIFMETRIC, arg);
+ 		break;
+ 
+ 	default: {
+ #ifdef DEBUG_MISSING_IOCTL
+-		char *msg = "Unimplemented IOCTL cmd tell linux at engr.sgi.com\n";
++		char *msg = "Unimplemented IOCTL cmd tell linux-mips at linux-mips.org\n";
+ 
+ #ifdef DEBUG_IOCTLS
+ 		printk("UNIMP_IOCTL, %08lx)\n", arg);
+diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
+--- a/arch/mips/kernel/irixsig.c
++++ b/arch/mips/kernel/irixsig.c
+@@ -76,36 +76,39 @@ static inline void dump_irix5_sigctx(str
+ }
+ #endif
+ 
+-static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
+-			     int signr, sigset_t *oldmask)
++static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
++			    int signr, sigset_t *oldmask)
+ {
++	struct sigctx_irix5 __user *ctx;
+ 	unsigned long sp;
+-	struct sigctx_irix5 *ctx;
+-	int i;
++	int error, i;
+ 
+ 	sp = regs->regs[29];
+ 	sp -= sizeof(struct sigctx_irix5);
+ 	sp &= ~(0xf);
+-	ctx = (struct sigctx_irix5 *) sp;
++	ctx = (struct sigctx_irix5 __user *) sp;
+ 	if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
+ 		goto segv_and_exit;
+ 
+-	__put_user(0, &ctx->weird_fpu_thing);
+-	__put_user(~(0x00000001), &ctx->rmask);
+-	__put_user(0, &ctx->regs[0]);
++	error = __put_user(0, &ctx->weird_fpu_thing);
++	error |= __put_user(~(0x00000001), &ctx->rmask);
++	error |= __put_user(0, &ctx->regs[0]);
+ 	for(i = 1; i < 32; i++)
+-		__put_user((u64) regs->regs[i], &ctx->regs[i]);
++		error |= __put_user((u64) regs->regs[i], &ctx->regs[i]);
+ 
+-	__put_user((u64) regs->hi, &ctx->hi);
+-	__put_user((u64) regs->lo, &ctx->lo);
+-	__put_user((u64) regs->cp0_epc, &ctx->pc);
+-	__put_user(!!used_math(), &ctx->usedfp);
+-	__put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
+-	__put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
++	error |= __put_user((u64) regs->hi, &ctx->hi);
++	error |= __put_user((u64) regs->lo, &ctx->lo);
++	error |= __put_user((u64) regs->cp0_epc, &ctx->pc);
++	error |= __put_user(!!used_math(), &ctx->usedfp);
++	error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
++	error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
+ 
+-	__put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
++	error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
+ 
+-	__copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t));
++	error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0;
++
++	if (error)
++		goto segv_and_exit;
+ 
+ #ifdef DEBUG_SIG
+ 	dump_irix5_sigctx(ctx);
+@@ -117,13 +120,14 @@ static void setup_irix_frame(struct k_si
+ 	regs->regs[7] = (unsigned long) ka->sa.sa_handler;
+ 	regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer;
+ 
+-	return;
++	return 1;
+ 
+ segv_and_exit:
+ 	force_sigsegv(signr, current);
++	return 0;
+ }
+ 
+-static void inline
++static int inline
+ setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+                int signr, sigset_t *oldmask, siginfo_t *info)
+ {
+@@ -131,9 +135,11 @@ setup_irix_rt_frame(struct k_sigaction *
+ 	do_exit(SIGSEGV);
+ }
+ 
+-static inline void handle_signal(unsigned long sig, siginfo_t *info,
++static inline int handle_signal(unsigned long sig, siginfo_t *info,
+ 	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
+ {
++	int ret;
++
+ 	switch(regs->regs[0]) {
+ 	case ERESTARTNOHAND:
+ 		regs->regs[2] = EINTR;
+@@ -151,9 +157,9 @@ static inline void handle_signal(unsigne
+ 	regs->regs[0] = 0;		/* Don't deal with this again.  */
+ 
+ 	if (ka->sa.sa_flags & SA_SIGINFO)
+-		setup_irix_rt_frame(ka, regs, sig, oldset, info);
++		ret = setup_irix_rt_frame(ka, regs, sig, oldset, info);
+ 	else
+-		setup_irix_frame(ka, regs, sig, oldset);
++		ret = setup_irix_frame(ka, regs, sig, oldset);
+ 
+ 	spin_lock_irq(&current->sighand->siglock);
+ 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+@@ -161,6 +167,8 @@ static inline void handle_signal(unsigne
+ 		sigaddset(&current->blocked,sig);
+ 	recalc_sigpending();
+ 	spin_unlock_irq(&current->sighand->siglock);
++
++	return ret;
+ }
+ 
+ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
+@@ -184,10 +192,8 @@ asmlinkage int do_irix_signal(sigset_t *
+ 		oldset = &current->blocked;
+ 
+ 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+-	if (signr > 0) {
+-		handle_signal(signr, &info, &ka, oldset, regs);
+-		return 1;
+-	}
++	if (signr > 0)
++		return handle_signal(signr, &info, &ka, oldset, regs);
+ 
+ no_signal:
+ 	/*
+@@ -208,10 +214,11 @@ no_signal:
+ asmlinkage void
+ irix_sigreturn(struct pt_regs *regs)
+ {
+-	struct sigctx_irix5 *context, *magic;
++	struct sigctx_irix5 __user *context, *magic;
+ 	unsigned long umask, mask;
+ 	u64 *fregs;
+-	int sig, i, base = 0;
++	u32 usedfp;
++	int error, sig, i, base = 0;
+ 	sigset_t blocked;
+ 
+ 	/* Always make any pending restarted system calls return -EINTR */
+@@ -220,8 +227,8 @@ irix_sigreturn(struct pt_regs *regs)
+ 	if (regs->regs[2] == 1000)
+ 		base = 1;
+ 
+-	context = (struct sigctx_irix5 *) regs->regs[base + 4];
+-	magic = (struct sigctx_irix5 *) regs->regs[base + 5];
++	context = (struct sigctx_irix5 __user *) regs->regs[base + 4];
++	magic = (struct sigctx_irix5 __user *) regs->regs[base + 5];
+ 	sig = (int) regs->regs[base + 6];
+ #ifdef DEBUG_SIG
+ 	printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n",
+@@ -236,25 +243,31 @@ irix_sigreturn(struct pt_regs *regs)
+ 	dump_irix5_sigctx(context);
+ #endif
+ 
+-	__get_user(regs->cp0_epc, &context->pc);
+-	umask = context->rmask; mask = 2;
++	error = __get_user(regs->cp0_epc, &context->pc);
++	error |= __get_user(umask, &context->rmask);
++
++	mask = 2;
+ 	for (i = 1; i < 32; i++, mask <<= 1) {
+-		if(umask & mask)
+-			__get_user(regs->regs[i], &context->regs[i]);
++		if (umask & mask)
++			error |= __get_user(regs->regs[i], &context->regs[i]);
+ 	}
+-	__get_user(regs->hi, &context->hi);
+-	__get_user(regs->lo, &context->lo);
++	error |= __get_user(regs->hi, &context->hi);
++	error |= __get_user(regs->lo, &context->lo);
+ 
+-	if ((umask & 1) && context->usedfp) {
++	error |= __get_user(usedfp, &context->usedfp);
++	if ((umask & 1) && usedfp) {
+ 		fregs = (u64 *) &current->thread.fpu;
++
+ 		for(i = 0; i < 32; i++)
+-			fregs[i] = (u64) context->fpregs[i];
+-		__get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
++			error |= __get_user(fregs[i], &context->fpregs[i]);
++		error |= __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
+ 	}
+ 
+ 	/* XXX do sigstack crapola here... XXX */
+ 
+-	if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked)))
++	error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0;
++
++	if (error)
+ 		goto badframe;
+ 
+ 	sigdelsetmask(&blocked, ~_BLOCKABLE);
+@@ -296,8 +309,8 @@ static inline void dump_sigact_irix5(str
+ #endif
+ 
+ asmlinkage int
+-irix_sigaction(int sig, const struct sigaction *act,
+-	      struct sigaction *oact, void *trampoline)
++irix_sigaction(int sig, const struct sigaction __user *act,
++	      struct sigaction __user *oact, void __user *trampoline)
+ {
+ 	struct k_sigaction new_ka, old_ka;
+ 	int ret;
+@@ -311,12 +324,16 @@ irix_sigaction(int sig, const struct sig
+ #endif
+ 	if (act) {
+ 		sigset_t mask;
+-		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+-		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+-		    __get_user(new_ka.sa.sa_flags, &act->sa_flags))
++		int err;
++
++		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+ 			return -EFAULT;
++		err = __get_user(new_ka.sa.sa_handler, &act->sa_handler);
++		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ 
+-		__copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
++		err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0;
++		if (err)
++			return err;
+ 
+ 		/*
+ 		 * Hmmm... methinks IRIX libc always passes a valid trampoline
+@@ -330,30 +347,37 @@ irix_sigaction(int sig, const struct sig
+ 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+ 
+ 	if (!ret && oact) {
+-		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+-		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+-		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
++		int err;
++
++		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
++			return -EFAULT;
++
++		err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
++		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
++		err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask,
++		               sizeof(sigset_t)) ? -EFAULT : 0;
++		if (err)
+ 			return -EFAULT;
+-		__copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
+-		               sizeof(sigset_t));
+ 	}
+ 
+ 	return ret;
+ }
+ 
+-asmlinkage int irix_sigpending(irix_sigset_t *set)
++asmlinkage int irix_sigpending(irix_sigset_t __user *set)
+ {
+ 	return do_sigpending(set, sizeof(*set));
+ }
+ 
+-asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
++asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,
++	irix_sigset_t __user *old)
+ {
+ 	sigset_t oldbits, newbits;
+ 
+ 	if (new) {
+ 		if (!access_ok(VERIFY_READ, new, sizeof(*new)))
+ 			return -EFAULT;
+-		__copy_from_user(&newbits, new, sizeof(unsigned long)*4);
++		if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4))
++			return -EFAULT;
+ 		sigdelsetmask(&newbits, ~_BLOCKABLE);
+ 
+ 		spin_lock_irq(&current->sighand->siglock);
+@@ -381,20 +405,19 @@ asmlinkage int irix_sigprocmask(int how,
+ 		recalc_sigpending();
+ 		spin_unlock_irq(&current->sighand->siglock);
+ 	}
+-	if(old) {
+-		if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
+-			return -EFAULT;
+-		__copy_to_user(old, &current->blocked, sizeof(unsigned long)*4);
+-	}
++	if (old)
++		return copy_to_user(old, &current->blocked,
++		                  sizeof(unsigned long)*4) ? -EFAULT : 0;
+ 
+ 	return 0;
+ }
+ 
+ asmlinkage int irix_sigsuspend(struct pt_regs *regs)
+ {
+-	sigset_t *uset, saveset, newset;
++	sigset_t saveset, newset;
++	sigset_t __user *uset;
+ 
+-	uset = (sigset_t *) regs->regs[4];
++	uset = (sigset_t __user *) regs->regs[4];
+ 	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
+ 		return -EFAULT;
+ 	sigdelsetmask(&newset, ~_BLOCKABLE);
+@@ -440,12 +463,13 @@ struct irix5_siginfo {
+ 	} stuff;
+ };
+ 
+-asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
+-				struct timespec *tp)
++asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
++	struct irix5_siginfo __user *info, struct timespec __user *tp)
+ {
+ 	long expire = MAX_SCHEDULE_TIMEOUT;
+ 	sigset_t kset;
+ 	int i, sig, error, timeo = 0;
++	struct timespec ktp;
+ 
+ #ifdef DEBUG_SIG
+ 	printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n",
+@@ -456,14 +480,8 @@ asmlinkage int irix_sigpoll_sys(unsigned
+ 	if (!set)
+ 		return -EINVAL;
+ 
+-	if (!access_ok(VERIFY_READ, set, sizeof(kset))) {
+-		error = -EFAULT;
+-		goto out;
+-	}
+-
+-	__copy_from_user(&kset, set, sizeof(set));
+-	if (error)
+-		goto out;
++	if (copy_from_user(&kset, set, sizeof(set)))
++		return -EFAULT;
+ 
+ 	if (info && clear_user(info, sizeof(*info))) {
+ 		error = -EFAULT;
+@@ -471,19 +489,21 @@ asmlinkage int irix_sigpoll_sys(unsigned
+ 	}
+ 
+ 	if (tp) {
+-		if (!access_ok(VERIFY_READ, tp, sizeof(*tp)))
++		if (copy_from_user(&ktp, tp, sizeof(*tp)))
+ 			return -EFAULT;
+-		if (!tp->tv_sec && !tp->tv_nsec) {
+-			error = -EINVAL;
+-			goto out;
+-		}
+-		expire = timespec_to_jiffies(tp) + (tp->tv_sec||tp->tv_nsec);
++
++		if (!ktp.tv_sec && !ktp.tv_nsec)
++			return -EINVAL;
++
++		expire = timespec_to_jiffies(&ktp) +
++		         (ktp.tv_sec || ktp.tv_nsec);
+ 	}
+ 
+ 	while(1) {
+ 		long tmp = 0;
+ 
+-		expire = schedule_timeout_interruptible(expire);
++		current->state = TASK_INTERRUPTIBLE;
++		expire = schedule_timeout(expire);
+ 
+ 		for (i=0; i<=4; i++)
+ 			tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
+@@ -500,15 +520,14 @@ asmlinkage int irix_sigpoll_sys(unsigned
+ 	if (timeo)
+ 		return -EAGAIN;
+ 
+-	for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
++	for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
+ 		if (sigismember (&kset, sig))
+ 			continue;
+ 		if (sigismember (&current->pending.signal, sig)) {
+ 			/* XXX need more than this... */
+ 			if (info)
+-				info->sig = sig;
+-			error = 0;
+-			goto out;
++				return copy_to_user(&info->sig, &sig, sizeof(sig));
++			return 0;
+ 		}
+ 	}
+ 
+@@ -534,8 +553,9 @@ extern int getrusage(struct task_struct 
+ 
+ #define W_MASK      (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)
+ 
+-asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
+-			    int options, struct rusage *ru)
++asmlinkage int irix_waitsys(int type, int pid,
++	struct irix5_siginfo __user *info, int options,
++	struct rusage __user *ru)
+ {
+ 	int flag, retval;
+ 	DECLARE_WAITQUEUE(wait, current);
+@@ -543,28 +563,22 @@ asmlinkage int irix_waitsys(int type, in
+ 	struct task_struct *p;
+ 	struct list_head *_p;
+ 
+-	if (!info) {
+-		retval = -EINVAL;
+-		goto out;
+-	}
+-	if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) {
+-		retval = -EFAULT;
+-		goto out;
+-	}
+-	if (ru) {
+-		if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) {
+-			retval = -EFAULT;
+-			goto out;
+-		}
+-	}
+-	if (options & ~(W_MASK)) {
+-		retval = -EINVAL;
+-		goto out;
+-	}
+-	if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) {
+-		retval = -EINVAL;
+-		goto out;
+-	}
++	if (!info)
++		return -EINVAL;
++
++	if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
++		return -EFAULT;
++
++	if (ru)
++		if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)))
++			return -EFAULT;
++
++	if (options & ~W_MASK)
++		return -EINVAL;
++
++	if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL)
++		return -EINVAL;
++
+ 	add_wait_queue(&current->signal->wait_chldexit, &wait);
+ repeat:
+ 	flag = 0;
+@@ -595,18 +609,20 @@ repeat:
+ 			add_parent(p, p->parent);
+ 			write_unlock_irq(&tasklist_lock);
+ 			retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
+-			if (!retval && ru) {
+-				retval |= __put_user(SIGCHLD, &info->sig);
+-				retval |= __put_user(0, &info->code);
+-				retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
+-				retval |= __put_user((p->exit_code >> 8) & 0xff,
+-				           &info->stuff.procinfo.procdata.child.status);
+-				retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
+-				retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
+-			}
+-			if (!retval) {
+-				p->exit_code = 0;
+-			}
++			if (retval)
++				goto end_waitsys;
++
++			retval = __put_user(SIGCHLD, &info->sig);
++			retval |= __put_user(0, &info->code);
++			retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
++			retval |= __put_user((p->exit_code >> 8) & 0xff,
++			           &info->stuff.procinfo.procdata.child.status);
++			retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
++			retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
++			if (retval)
++				goto end_waitsys;
++
++			p->exit_code = 0;
+ 			goto end_waitsys;
+ 
+ 		case EXIT_ZOMBIE:
+@@ -614,16 +630,18 @@ repeat:
+ 			current->signal->cstime += p->stime + p->signal->cstime;
+ 			if (ru != NULL)
+ 				getrusage(p, RUSAGE_BOTH, ru);
+-			__put_user(SIGCHLD, &info->sig);
+-			__put_user(1, &info->code);      /* CLD_EXITED */
+-			__put_user(p->pid, &info->stuff.procinfo.pid);
+-			__put_user((p->exit_code >> 8) & 0xff,
++			retval = __put_user(SIGCHLD, &info->sig);
++			retval |= __put_user(1, &info->code);      /* CLD_EXITED */
++			retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
++			retval |= __put_user((p->exit_code >> 8) & 0xff,
+ 			           &info->stuff.procinfo.procdata.child.status);
+-			__put_user(p->utime,
++			retval |= __put_user(p->utime,
+ 			           &info->stuff.procinfo.procdata.child.utime);
+-			__put_user(p->stime,
++			retval |= __put_user(p->stime,
+ 			           &info->stuff.procinfo.procdata.child.stime);
+-			retval = 0;
++			if (retval)
++				return retval;
++
+ 			if (p->real_parent != p->parent) {
+ 				write_lock_irq(&tasklist_lock);
+ 				remove_parent(p);
+@@ -656,7 +674,6 @@ end_waitsys:
+ 	current->state = TASK_RUNNING;
+ 	remove_wait_queue(&current->signal->wait_chldexit, &wait);
+ 
+-out:
+ 	return retval;
+ }
+ 
+@@ -675,39 +692,39 @@ struct irix5_context {
+ 
+ asmlinkage int irix_getcontext(struct pt_regs *regs)
+ {
+-	int i, base = 0;
+-	struct irix5_context *ctx;
++	int error, i, base = 0;
++	struct irix5_context __user *ctx;
+ 	unsigned long flags;
+ 
+ 	if (regs->regs[2] == 1000)
+ 		base = 1;
+-	ctx = (struct irix5_context *) regs->regs[base + 4];
++	ctx = (struct irix5_context __user *) regs->regs[base + 4];
+ 
+ #ifdef DEBUG_SIG
+ 	printk("[%s:%d] irix_getcontext(%p)\n",
+ 	       current->comm, current->pid, ctx);
+ #endif
+ 
+-	if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
++	if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)));
+ 		return -EFAULT;
+ 
+-	__put_user(current->thread.irix_oldctx, &ctx->link);
++	error = __put_user(current->thread.irix_oldctx, &ctx->link);
+ 
+-	__copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t));
++	error |= __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0;
+ 
+ 	/* XXX Do sigstack stuff someday... */
+-	__put_user(0, &ctx->stack.sp);
+-	__put_user(0, &ctx->stack.size);
+-	__put_user(0, &ctx->stack.flags);
++	error |= __put_user(0, &ctx->stack.sp);
++	error |= __put_user(0, &ctx->stack.size);
++	error |= __put_user(0, &ctx->stack.flags);
+ 
+-	__put_user(0, &ctx->weird_graphics_thing);
+-	__put_user(0, &ctx->regs[0]);
++	error |= __put_user(0, &ctx->weird_graphics_thing);
++	error |= __put_user(0, &ctx->regs[0]);
+ 	for (i = 1; i < 32; i++)
+-		__put_user(regs->regs[i], &ctx->regs[i]);
+-	__put_user(regs->lo, &ctx->regs[32]);
+-	__put_user(regs->hi, &ctx->regs[33]);
+-	__put_user(regs->cp0_cause, &ctx->regs[34]);
+-	__put_user(regs->cp0_epc, &ctx->regs[35]);
++		error |= __put_user(regs->regs[i], &ctx->regs[i]);
++	error |= __put_user(regs->lo, &ctx->regs[32]);
++	error |= __put_user(regs->hi, &ctx->regs[33]);
++	error |= __put_user(regs->cp0_cause, &ctx->regs[34]);
++	error |= __put_user(regs->cp0_epc, &ctx->regs[35]);
+ 
+ 	flags = 0x0f;
+ 	if (!used_math()) {
+@@ -716,119 +733,124 @@ asmlinkage int irix_getcontext(struct pt
+ 		/* XXX wheee... */
+ 		printk("Wheee, no code for saving IRIX FPU context yet.\n");
+ 	}
+-	__put_user(flags, &ctx->flags);
++	error |= __put_user(flags, &ctx->flags);
+ 
+-	return 0;
++	return error;
+ }
+ 
+-asmlinkage unsigned long irix_setcontext(struct pt_regs *regs)
++asmlinkage void irix_setcontext(struct pt_regs *regs)
+ {
+-	int error, base = 0;
+-	struct irix5_context *ctx;
++	struct irix5_context __user *ctx;
++	int err, base = 0;
++	u32 flags;
+ 
+-	if(regs->regs[2] == 1000)
++	if (regs->regs[2] == 1000)
+ 		base = 1;
+-	ctx = (struct irix5_context *) regs->regs[base + 4];
++	ctx = (struct irix5_context __user *) regs->regs[base + 4];
+ 
+ #ifdef DEBUG_SIG
+ 	printk("[%s:%d] irix_setcontext(%p)\n",
+ 	       current->comm, current->pid, ctx);
+ #endif
+ 
+-	if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) {
+-		error = -EFAULT;
+-		goto out;
+-	}
++	if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)))
++		goto segv_and_exit;
+ 
+-	if (ctx->flags & 0x02) {
++	err = __get_user(flags, &ctx->flags);
++	if (flags & 0x02) {
+ 		/* XXX sigstack garbage, todo... */
+ 		printk("Wheee, cannot do sigstack stuff in setcontext\n");
+ 	}
+ 
+-	if (ctx->flags & 0x04) {
++	if (flags & 0x04) {
+ 		int i;
+ 
+ 		/* XXX extra control block stuff... todo... */
+-		for(i = 1; i < 32; i++)
+-			regs->regs[i] = ctx->regs[i];
+-		regs->lo = ctx->regs[32];
+-		regs->hi = ctx->regs[33];
+-		regs->cp0_epc = ctx->regs[35];
++		for (i = 1; i < 32; i++)
++			err |= __get_user(regs->regs[i], &ctx->regs[i]);
++		err |= __get_user(regs->lo, &ctx->regs[32]);
++		err |= __get_user(regs->hi, &ctx->regs[33]);
++		err |= __get_user(regs->cp0_epc, &ctx->regs[35]);
+ 	}
+ 
+-	if (ctx->flags & 0x08) {
++	if (flags & 0x08)
+ 		/* XXX fpu context, blah... */
+-		printk("Wheee, cannot restore FPU context yet...\n");
+-	}
+-	current->thread.irix_oldctx = ctx->link;
+-	error = regs->regs[2];
++		printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n");
+ 
+-out:
+-	return error;
++	err |= __get_user(current->thread.irix_oldctx, &ctx->link);
++	if (err)
++		goto segv_and_exit;
++
++	/*
++	 * Don't let your children do this ...
++	 */
++	if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
++		do_syscall_trace(regs, 1);
++	__asm__ __volatile__(
++		"move\t$29,%0\n\t"
++		"j\tsyscall_exit"
++		:/* no outputs */
++		:"r" (&regs));
++		/* Unreached */
++
++segv_and_exit:
++	force_sigsegv(SIGSEGV, current);
+ }
+ 
+-struct irix_sigstack { unsigned long sp; int status; };
++struct irix_sigstack {
++	unsigned long sp;
++	int status;
++};
+ 
+-asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old)
++asmlinkage int irix_sigstack(struct irix_sigstack __user *new,
++	struct irix_sigstack __user *old)
+ {
+-	int error = -EFAULT;
+-
+ #ifdef DEBUG_SIG
+ 	printk("[%s:%d] irix_sigstack(%p,%p)\n",
+ 	       current->comm, current->pid, new, old);
+ #endif
+-	if(new) {
++	if (new) {
+ 		if (!access_ok(VERIFY_READ, new, sizeof(*new)))
+-			goto out;
++			return -EFAULT;
+ 	}
+ 
+-	if(old) {
++	if (old) {
+ 		if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
+-			goto out;
++			return -EFAULT;
+ 	}
+-	error = 0;
+ 
+-out:
+-	return error;
++	return 0;
+ }
+ 
+ struct irix_sigaltstack { unsigned long sp; int size; int status; };
+ 
+-asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new,
+-				struct irix_sigaltstack *old)
++asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new,
++				struct irix_sigaltstack __user *old)
+ {
+-	int error = -EFAULT;
+-
+ #ifdef DEBUG_SIG
+ 	printk("[%s:%d] irix_sigaltstack(%p,%p)\n",
+ 	       current->comm, current->pid, new, old);
+ #endif
+-	if (new) {
++	if (new)
+ 		if (!access_ok(VERIFY_READ, new, sizeof(*new)))
+-			goto out;
+-	}
++			return -EFAULT;
+ 
+ 	if (old) {
+ 		if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
+-			goto out;
++			return -EFAULT;
+ 	}
+-	error = 0;
+-
+-out:
+-	error = 0;
+ 
+-	return error;
++	return 0;
+ }
+ 
+ struct irix_procset {
+ 	int cmd, ltype, lid, rtype, rid;
+ };
+ 
+-asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig)
++asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig)
+ {
+ 	if (!access_ok(VERIFY_READ, pset, sizeof(*pset)))
+ 		return -EFAULT;
+-
+ #ifdef DEBUG_SIG
+ 	printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n",
+ 	       current->comm, current->pid,
+diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
+--- a/arch/mips/kernel/irq-msc01.c
++++ b/arch/mips/kernel/irq-msc01.c
+@@ -74,7 +74,7 @@ static void disable_msc_irq(unsigned int
+ static void level_mask_and_ack_msc_irq(unsigned int irq)
+ {
+ 	mask_msc_irq(irq);
+-	if (!cpu_has_ei)
++	if (!cpu_has_veic)
+ 		MSCIC_WRITE(MSC01_IC_EOI, 0);
+ }
+ 
+@@ -84,7 +84,7 @@ static void level_mask_and_ack_msc_irq(u
+ static void edge_mask_and_ack_msc_irq(unsigned int irq)
+ {
+ 	mask_msc_irq(irq);
+-	if (!cpu_has_ei)
++	if (!cpu_has_veic)
+ 		MSCIC_WRITE(MSC01_IC_EOI, 0);
+ 	else {
+ 		u32 r;
+@@ -129,25 +129,23 @@ msc_bind_eic_interrupt (unsigned int irq
+ #define shutdown_msc_irq	disable_msc_irq
+ 
+ struct hw_interrupt_type msc_levelirq_type = {
+-	"SOC-it-Level",
+-	startup_msc_irq,
+-	shutdown_msc_irq,
+-	enable_msc_irq,
+-	disable_msc_irq,
+-	level_mask_and_ack_msc_irq,
+-	end_msc_irq,
+-	NULL
++	.typename = "SOC-it-Level",
++	.startup = startup_msc_irq,
++	.shutdown = shutdown_msc_irq,
++	.enable = enable_msc_irq,
++	.disable = disable_msc_irq,
++	.ack = level_mask_and_ack_msc_irq,
++	.end = end_msc_irq,
+ };
+ 
+ struct hw_interrupt_type msc_edgeirq_type = {
+-	"SOC-it-Edge",
+-	startup_msc_irq,
+-	shutdown_msc_irq,
+-	enable_msc_irq,
+-	disable_msc_irq,
+-	edge_mask_and_ack_msc_irq,
+-	end_msc_irq,
+-	NULL
++	.typename = "SOC-it-Edge",
++	.startup =startup_msc_irq,
++	.shutdown = shutdown_msc_irq,
++	.enable = enable_msc_irq,
++	.disable = disable_msc_irq,
++	.ack = edge_mask_and_ack_msc_irq,
++	.end = end_msc_irq,
+ };
+ 
+ 
+@@ -168,14 +166,14 @@ void __init init_msc_irqs(unsigned int b
+ 		switch (imp->im_type) {
+ 		case MSC01_IRQ_EDGE:
+ 			irq_desc[base+n].handler = &msc_edgeirq_type;
+-			if (cpu_has_ei)
++			if (cpu_has_veic)
+ 				MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT);
+ 			else
+ 				MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl);
+ 			break;
+ 		case MSC01_IRQ_LEVEL:
+ 			irq_desc[base+n].handler = &msc_levelirq_type;
+-			if (cpu_has_ei)
++			if (cpu_has_veic)
+ 				MSCIC_WRITE(MSC01_IC_SUP+n*8, 0);
+ 			else
+ 				MSCIC_WRITE(MSC01_IC_SUP+n*8, imp->im_lvl);
+diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c
+--- a/arch/mips/kernel/irq-mv6434x.c
++++ b/arch/mips/kernel/irq-mv6434x.c
+@@ -135,14 +135,13 @@ void ll_mv64340_irq(struct pt_regs *regs
+ #define shutdown_mv64340_irq	disable_mv64340_irq
+ 
+ struct hw_interrupt_type mv64340_irq_type = {
+-	"MV-64340",
+-	startup_mv64340_irq,
+-	shutdown_mv64340_irq,
+-	enable_mv64340_irq,
+-	disable_mv64340_irq,
+-	mask_and_ack_mv64340_irq,
+-	end_mv64340_irq,
+-	NULL
++	.typename = "MV-64340",
++	.startup = startup_mv64340_irq,
++	.shutdown = shutdown_mv64340_irq,
++	.enable = enable_mv64340_irq,
++	.disable = disable_mv64340_irq,
++	.ack = mask_and_ack_mv64340_irq,
++	.end = end_mv64340_irq,
+ };
+ 
+ void __init mv64340_irq_init(unsigned int base)
+diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
+--- a/arch/mips/kernel/irq-rm7000.c
++++ b/arch/mips/kernel/irq-rm7000.c
+@@ -72,13 +72,13 @@ static void rm7k_cpu_irq_end(unsigned in
+ }
+ 
+ static hw_irq_controller rm7k_irq_controller = {
+-	"RM7000",
+-	rm7k_cpu_irq_startup,
+-	rm7k_cpu_irq_shutdown,
+-	rm7k_cpu_irq_enable,
+-	rm7k_cpu_irq_disable,
+-	rm7k_cpu_irq_ack,
+-	rm7k_cpu_irq_end,
++	.typename = "RM7000",
++	.startup = rm7k_cpu_irq_startup,
++	.shutdown = rm7k_cpu_irq_shutdown,
++	.enable = rm7k_cpu_irq_enable,
++	.disable = rm7k_cpu_irq_disable,
++	.ack = rm7k_cpu_irq_ack,
++	.end = rm7k_cpu_irq_end,
+ };
+ 
+ void __init rm7k_cpu_irq_init(int base)
+diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
+--- a/arch/mips/kernel/irq-rm9000.c
++++ b/arch/mips/kernel/irq-rm9000.c
+@@ -106,23 +106,23 @@ static void rm9k_cpu_irq_end(unsigned in
+ }
+ 
+ static hw_irq_controller rm9k_irq_controller = {
+-	"RM9000",
+-	rm9k_cpu_irq_startup,
+-	rm9k_cpu_irq_shutdown,
+-	rm9k_cpu_irq_enable,
+-	rm9k_cpu_irq_disable,
+-	rm9k_cpu_irq_ack,
+-	rm9k_cpu_irq_end,
++	.typename = "RM9000",
++	.startup = rm9k_cpu_irq_startup,
++	.shutdown = rm9k_cpu_irq_shutdown,
++	.enable = rm9k_cpu_irq_enable,
++	.disable = rm9k_cpu_irq_disable,
++	.ack = rm9k_cpu_irq_ack,
++	.end = rm9k_cpu_irq_end,
+ };
+ 
+ static hw_irq_controller rm9k_perfcounter_irq = {
+-	"RM9000",
+-	rm9k_perfcounter_irq_startup,
+-	rm9k_perfcounter_irq_shutdown,
+-	rm9k_cpu_irq_enable,
+-	rm9k_cpu_irq_disable,
+-	rm9k_cpu_irq_ack,
+-	rm9k_cpu_irq_end,
++	.typename = "RM9000",
++	.startup = rm9k_perfcounter_irq_startup,
++	.shutdown = rm9k_perfcounter_irq_shutdown,
++	.enable = rm9k_cpu_irq_enable,
++	.disable = rm9k_cpu_irq_disable,
++	.ack = rm9k_cpu_irq_ack,
++	.end = rm9k_cpu_irq_end,
+ };
+ 
+ unsigned int rm9000_perfcount_irq;
+diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
+--- a/arch/mips/kernel/irq_cpu.c
++++ b/arch/mips/kernel/irq_cpu.c
+@@ -3,6 +3,8 @@
+  * Author: Jun Sun, jsun at mvista.com or jsun at junsun.net
+  *
+  * Copyright (C) 2001 Ralf Baechle
++ * Copyright (C) 2005  MIPS Technologies, Inc.  All rights reserved.
++ *      Author: Maciej W. Rozycki <macro at mips.com>
+  *
+  * This file define the irq handler for MIPS CPU interrupts.
+  *
+@@ -31,19 +33,21 @@
+ 
+ #include <asm/irq_cpu.h>
+ #include <asm/mipsregs.h>
++#include <asm/mipsmtregs.h>
+ #include <asm/system.h>
+ 
+ static int mips_cpu_irq_base;
+ 
+ static inline void unmask_mips_irq(unsigned int irq)
+ {
+-	clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
+ 	set_c0_status(0x100 << (irq - mips_cpu_irq_base));
++	irq_enable_hazard();
+ }
+ 
+ static inline void mask_mips_irq(unsigned int irq)
+ {
+ 	clear_c0_status(0x100 << (irq - mips_cpu_irq_base));
++	irq_disable_hazard();
+ }
+ 
+ static inline void mips_cpu_irq_enable(unsigned int irq)
+@@ -52,6 +56,7 @@ static inline void mips_cpu_irq_enable(u
+ 
+ 	local_irq_save(flags);
+ 	unmask_mips_irq(irq);
++	back_to_back_c0_hazard();
+ 	local_irq_restore(flags);
+ }
+ 
+@@ -61,6 +66,7 @@ static void mips_cpu_irq_disable(unsigne
+ 
+ 	local_irq_save(flags);
+ 	mask_mips_irq(irq);
++	back_to_back_c0_hazard();
+ 	local_irq_restore(flags);
+ }
+ 
+@@ -71,7 +77,7 @@ static unsigned int mips_cpu_irq_startup
+ 	return 0;
+ }
+ 
+-#define	mips_cpu_irq_shutdown	mips_cpu_irq_disable
++#define	mips_cpu_irq_shutdown		mips_cpu_irq_disable
+ 
+ /*
+  * While we ack the interrupt interrupts are disabled and thus we don't need
+@@ -79,9 +85,6 @@ static unsigned int mips_cpu_irq_startup
+  */
+ static void mips_cpu_irq_ack(unsigned int irq)
+ {
+-	/* Only necessary for soft interrupts */
+-	clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
+-
+ 	mask_mips_irq(irq);
+ }
+ 
+@@ -92,22 +95,82 @@ static void mips_cpu_irq_end(unsigned in
+ }
+ 
+ static hw_irq_controller mips_cpu_irq_controller = {
+-	"MIPS",
+-	mips_cpu_irq_startup,
+-	mips_cpu_irq_shutdown,
+-	mips_cpu_irq_enable,
+-	mips_cpu_irq_disable,
+-	mips_cpu_irq_ack,
+-	mips_cpu_irq_end,
+-	NULL			/* no affinity stuff for UP */
++	.typename	= "MIPS",
++	.startup	= mips_cpu_irq_startup,
++	.shutdown	= mips_cpu_irq_shutdown,
++	.enable		= mips_cpu_irq_enable,
++	.disable	= mips_cpu_irq_disable,
++	.ack		= mips_cpu_irq_ack,
++	.end		= mips_cpu_irq_end,
+ };
+ 
++/*
++ * Basically the same as above but taking care of all the MT stuff
++ */
++
++#define unmask_mips_mt_irq	unmask_mips_irq
++#define mask_mips_mt_irq	mask_mips_irq
++#define mips_mt_cpu_irq_enable	mips_cpu_irq_enable
++#define mips_mt_cpu_irq_disable	mips_cpu_irq_disable
++
++static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
++{
++	unsigned int vpflags = dvpe();
++
++	clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
++	evpe(vpflags);
++	mips_mt_cpu_irq_enable(irq);
++
++	return 0;
++}
++
++#define	mips_mt_cpu_irq_shutdown	mips_mt_cpu_irq_disable
++
++/*
++ * While we ack the interrupt interrupts are disabled and thus we don't need
++ * to deal with concurrency issues.  Same for mips_cpu_irq_end.
++ */
++static void mips_mt_cpu_irq_ack(unsigned int irq)
++{
++	unsigned int vpflags = dvpe();
++	clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
++	evpe(vpflags);
++	mask_mips_mt_irq(irq);
++}
++
++#define mips_mt_cpu_irq_end mips_cpu_irq_end
++
++static hw_irq_controller mips_mt_cpu_irq_controller = {
++	.typename	= "MIPS",
++	.startup	= mips_mt_cpu_irq_startup,
++	.shutdown	= mips_mt_cpu_irq_shutdown,
++	.enable		= mips_mt_cpu_irq_enable,
++	.disable	= mips_mt_cpu_irq_disable,
++	.ack		= mips_mt_cpu_irq_ack,
++	.end		= mips_mt_cpu_irq_end,
++};
+ 
+ void __init mips_cpu_irq_init(int irq_base)
+ {
+ 	int i;
+ 
+-	for (i = irq_base; i < irq_base + 8; i++) {
++	/* Mask interrupts. */
++	clear_c0_status(ST0_IM);
++	clear_c0_cause(CAUSEF_IP);
++
++	/*
++	 * Only MT is using the software interrupts currently, so we just
++	 * leave them uninitialized for other processors.
++	 */
++	if (cpu_has_mipsmt)
++		for (i = irq_base; i < irq_base + 2; i++) {
++			irq_desc[i].status = IRQ_DISABLED;
++			irq_desc[i].action = NULL;
++			irq_desc[i].depth = 1;
++			irq_desc[i].handler = &mips_mt_cpu_irq_controller;
++		}
++
++	for (i = irq_base + 2; i < irq_base + 8; i++) {
+ 		irq_desc[i].status = IRQ_DISABLED;
+ 		irq_desc[i].action = NULL;
+ 		irq_desc[i].depth = 1;
+diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
+--- a/arch/mips/kernel/linux32.c
++++ b/arch/mips/kernel/linux32.c
+@@ -215,81 +215,32 @@ sys32_readdir(unsigned int fd, void * di
+ 	return(n);
+ }
+ 
+-struct rusage32 {
+-        struct compat_timeval ru_utime;
+-        struct compat_timeval ru_stime;
+-        int    ru_maxrss;
+-        int    ru_ixrss;
+-        int    ru_idrss;
+-        int    ru_isrss;
+-        int    ru_minflt;
+-        int    ru_majflt;
+-        int    ru_nswap;
+-        int    ru_inblock;
+-        int    ru_oublock;
+-        int    ru_msgsnd;
+-        int    ru_msgrcv;
+-        int    ru_nsignals;
+-        int    ru_nvcsw;
+-        int    ru_nivcsw;
+-};
+-
+-static int
+-put_rusage (struct rusage32 *ru, struct rusage *r)
++asmlinkage int
++sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
+ {
+-	int err;
+-
+-	if (!access_ok(VERIFY_WRITE, ru, sizeof *ru))
+-		return -EFAULT;
+-
+-	err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
+-	err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
+-	err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
+-	err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
+-	err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
+-	err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
+-	err |= __put_user (r->ru_idrss, &ru->ru_idrss);
+-	err |= __put_user (r->ru_isrss, &ru->ru_isrss);
+-	err |= __put_user (r->ru_minflt, &ru->ru_minflt);
+-	err |= __put_user (r->ru_majflt, &ru->ru_majflt);
+-	err |= __put_user (r->ru_nswap, &ru->ru_nswap);
+-	err |= __put_user (r->ru_inblock, &ru->ru_inblock);
+-	err |= __put_user (r->ru_oublock, &ru->ru_oublock);
+-	err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
+-	err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
+-	err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
+-	err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
+-	err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
+-
+-	return err;
++	return compat_sys_wait4(pid, stat_addr, options, NULL);
+ }
+ 
+-asmlinkage int
+-sys32_wait4(compat_pid_t pid, unsigned int * stat_addr, int options,
+-	    struct rusage32 * ru)
++asmlinkage long
++sysn32_waitid(int which, compat_pid_t pid,
++	      siginfo_t __user *uinfo, int options,
++	      struct compat_rusage __user *uru)
+ {
+-	if (!ru)
+-		return sys_wait4(pid, stat_addr, options, NULL);
+-	else {
+-		struct rusage r;
+-		int ret;
+-		unsigned int status;
+-		mm_segment_t old_fs = get_fs();
++	struct rusage ru;
++	long ret;
++	mm_segment_t old_fs = get_fs();
+ 
+-		set_fs(KERNEL_DS);
+-		ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
+-		set_fs(old_fs);
+-		if (put_rusage (ru, &r)) return -EFAULT;
+-		if (stat_addr && put_user (status, stat_addr))
+-			return -EFAULT;
++	set_fs (KERNEL_DS);
++	ret = sys_waitid(which, pid, uinfo, options,
++			 uru ? (struct rusage __user *) &ru : NULL);
++	set_fs (old_fs);
++
++	if (ret < 0 || uinfo->si_signo == 0)
+ 		return ret;
+-	}
+-}
+ 
+-asmlinkage int
+-sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
+-{
+-	return sys32_wait4(pid, stat_addr, options, NULL);
++	if (uru)
++		ret = put_compat_rusage(&ru, uru);
++	return ret;
+ }
+ 
+ struct sysinfo32 {
+@@ -1467,3 +1418,80 @@ asmlinkage long sys32_socketcall(int cal
+ 	}
+ 	return err;
+ }
++
++struct sigevent32 {
++	u32 sigev_value;
++	u32 sigev_signo;
++	u32 sigev_notify;
++	u32 payload[(64 / 4) - 3];
++};
++
++extern asmlinkage long
++sys_timer_create(clockid_t which_clock,
++		 struct sigevent __user *timer_event_spec,
++		 timer_t __user * created_timer_id);
++
++long
++sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
++{
++	struct sigevent __user *p = NULL;
++	if (se32) {
++		struct sigevent se;
++		p = compat_alloc_user_space(sizeof(struct sigevent));
++		memset(&se, 0, sizeof(struct sigevent));
++		if (get_user(se.sigev_value.sival_int,  &se32->sigev_value) ||
++		    __get_user(se.sigev_signo, &se32->sigev_signo) ||
++		    __get_user(se.sigev_notify, &se32->sigev_notify) ||
++		    __copy_from_user(&se._sigev_un._pad, &se32->payload,
++				     sizeof(se32->payload)) ||
++		    copy_to_user(p, &se, sizeof(se)))
++			return -EFAULT;
++	}
++	return sys_timer_create(clock, p, timer_id);
++}
++
++asmlinkage long
++sysn32_rt_sigtimedwait(const sigset_t __user *uthese,
++		       siginfo_t __user *uinfo,
++		       const struct compat_timespec __user *uts32,
++		       size_t sigsetsize)
++{
++	struct timespec __user *uts = NULL;
++
++	if (uts32) {
++		struct timespec ts;
++		uts = compat_alloc_user_space(sizeof(struct timespec));
++		if (get_user(ts.tv_sec, &uts32->tv_sec) ||
++		    get_user(ts.tv_nsec, &uts32->tv_nsec) ||
++		    copy_to_user (uts, &ts, sizeof (ts)))
++			return -EFAULT;
++	}
++	return sys_rt_sigtimedwait(uthese, uinfo, uts, sigsetsize);
++}
++
++save_static_function(sys32_clone);
++__attribute_used__ noinline static int
++_sys32_clone(nabi_no_regargs struct pt_regs regs)
++{
++	unsigned long clone_flags;
++	unsigned long newsp;
++	int __user *parent_tidptr, *child_tidptr;
++
++	clone_flags = regs.regs[4];
++	newsp = regs.regs[5];
++	if (!newsp)
++		newsp = regs.regs[29];
++	parent_tidptr = (int *) regs.regs[6];
++
++	/* Use __dummy4 instead of getting it off the stack, so that
++	   syscall() works.  */
++	child_tidptr = (int __user *) __dummy4;
++	return do_fork(clone_flags, newsp, &regs, 0,
++	               parent_tidptr, child_tidptr);
++}
++
++extern asmlinkage void sys_set_thread_area(u32 addr);
++asmlinkage void sys32_set_thread_area(u32 addr)
++{
++	sys_set_thread_area(AA(addr));
++}
+diff --git a/arch/mips/kernel/module-elf32.c b/arch/mips/kernel/module-elf32.c
+deleted file mode 100644
+--- a/arch/mips/kernel/module-elf32.c
++++ /dev/null
+@@ -1,250 +0,0 @@
+-/*
+- *  This program is free software; you can redistribute it and/or modify
+- *  it under the terms of the 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
+- *
+- *  Copyright (C) 2001 Rusty Russell.
+- *  Copyright (C) 2003, 2004 Ralf Baechle (ralf at linux-mips.org)
+- */
+-
+-#undef DEBUG
+-
+-#include <linux/moduleloader.h>
+-#include <linux/elf.h>
+-#include <linux/vmalloc.h>
+-#include <linux/slab.h>
+-#include <linux/fs.h>
+-#include <linux/string.h>
+-#include <linux/kernel.h>
+-
+-struct mips_hi16 {
+-	struct mips_hi16 *next;
+-	Elf32_Addr *addr;
+-	Elf32_Addr value;
+-};
+-
+-static struct mips_hi16 *mips_hi16_list;
+-
+-void *module_alloc(unsigned long size)
+-{
+-	if (size == 0)
+-		return NULL;
+-	return vmalloc(size);
+-}
+-
+-
+-/* Free memory returned from module_alloc */
+-void module_free(struct module *mod, void *module_region)
+-{
+-	vfree(module_region);
+-	/* FIXME: If module_region == mod->init_region, trim exception
+-           table entries. */
+-}
+-
+-int module_frob_arch_sections(Elf_Ehdr *hdr,
+-			      Elf_Shdr *sechdrs,
+-			      char *secstrings,
+-			      struct module *mod)
+-{
+-	return 0;
+-}
+-
+-static int apply_r_mips_none(struct module *me, uint32_t *location,
+-	Elf32_Addr v)
+-{
+-	return 0;
+-}
+-
+-static int apply_r_mips_32(struct module *me, uint32_t *location,
+-	Elf32_Addr v)
+-{
+-	*location += v;
+-
+-	return 0;
+-}
+-
+-static int apply_r_mips_26(struct module *me, uint32_t *location,
+-	Elf32_Addr v)
+-{
+-	if (v % 4) {
+-		printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
+-		return -ENOEXEC;
+-	}
+-
+-	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+-		printk(KERN_ERR
+-		       "module %s: relocation overflow\n",
+-		       me->name);
+-		return -ENOEXEC;
+-	}
+-
+-	*location = (*location & ~0x03ffffff) |
+-	            ((*location + (v >> 2)) & 0x03ffffff);
+-
+-	return 0;
+-}
+-
+-static int apply_r_mips_hi16(struct module *me, uint32_t *location,
+-	Elf32_Addr v)
+-{
+-	struct mips_hi16 *n;
+-
+-	/*
+-	 * We cannot relocate this one now because we don't know the value of
+-	 * the carry we need to add.  Save the information, and let LO16 do the
+-	 * actual relocation.
+-	 */
+-	n = kmalloc(sizeof *n, GFP_KERNEL);
+-	if (!n)
+-		return -ENOMEM;
+-
+-	n->addr = location;
+-	n->value = v;
+-	n->next = mips_hi16_list;
+-	mips_hi16_list = n;
+-
+-	return 0;
+-}
+-
+-static int apply_r_mips_lo16(struct module *me, uint32_t *location,
+-	Elf32_Addr v)
+-{
+-	unsigned long insnlo = *location;
+-	Elf32_Addr val, vallo;
+-
+-	/* Sign extend the addend we extract from the lo insn.  */
+-	vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+-
+-	if (mips_hi16_list != NULL) {
+-		struct mips_hi16 *l;
+-
+-		l = mips_hi16_list;
+-		while (l != NULL) {
+-			struct mips_hi16 *next;
+-			unsigned long insn;
+-
+-			/*
+-			 * The value for the HI16 had best be the same.
+-			 */
+-			if (v != l->value)
+-				goto out_danger;
+-
+-			/*
+-			 * Do the HI16 relocation.  Note that we actually don't
+-			 * need to know anything about the LO16 itself, except
+-			 * where to find the low 16 bits of the addend needed
+-			 * by the LO16.
+-			 */
+-			insn = *l->addr;
+-			val = ((insn & 0xffff) << 16) + vallo;
+-			val += v;
+-
+-			/*
+-			 * Account for the sign extension that will happen in
+-			 * the low bits.
+-			 */
+-			val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+-
+-			insn = (insn & ~0xffff) | val;
+-			*l->addr = insn;
+-
+-			next = l->next;
+-			kfree(l);
+-			l = next;
+-		}
+-
+-		mips_hi16_list = NULL;
+-	}
+-
+-	/*
+-	 * Ok, we're done with the HI16 relocs.  Now deal with the LO16.
+-	 */
+-	val = v + vallo;
+-	insnlo = (insnlo & ~0xffff) | (val & 0xffff);
+-	*location = insnlo;
+-
+-	return 0;
+-
+-out_danger:
+-	printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
+-
+-	return -ENOEXEC;
+-}
+-
+-static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
+-	Elf32_Addr v) = {
+-	[R_MIPS_NONE]	= apply_r_mips_none,
+-	[R_MIPS_32]	= apply_r_mips_32,
+-	[R_MIPS_26]	= apply_r_mips_26,
+-	[R_MIPS_HI16]	= apply_r_mips_hi16,
+-	[R_MIPS_LO16]	= apply_r_mips_lo16
+-};
+-
+-int apply_relocate(Elf32_Shdr *sechdrs,
+-		   const char *strtab,
+-		   unsigned int symindex,
+-		   unsigned int relsec,
+-		   struct module *me)
+-{
+-	Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+-	Elf32_Sym *sym;
+-	uint32_t *location;
+-	unsigned int i;
+-	Elf32_Addr v;
+-	int res;
+-
+-	pr_debug("Applying relocate section %u to %u\n", relsec,
+-	       sechdrs[relsec].sh_info);
+-
+-	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+-		Elf32_Word r_info = rel[i].r_info;
+-
+-		/* This is where to make the change */
+-		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+-			+ rel[i].r_offset;
+-		/* This is the symbol it is referring to */
+-		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+-			+ ELF32_R_SYM(r_info);
+-		if (!sym->st_value) {
+-			printk(KERN_WARNING "%s: Unknown symbol %s\n",
+-			       me->name, strtab + sym->st_name);
+-			return -ENOENT;
+-		}
+-
+-		v = sym->st_value;
+-
+-		res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
+-		if (res)
+-			return res;
+-	}
+-
+-	return 0;
+-}
+-
+-int apply_relocate_add(Elf32_Shdr *sechdrs,
+-		       const char *strtab,
+-		       unsigned int symindex,
+-		       unsigned int relsec,
+-		       struct module *me)
+-{
+-	/*
+-	 * Current binutils always generate .rela relocations.  Keep smiling
+-	 * if it's empty, abort otherwise.
+-	 */
+-	if (!sechdrs[relsec].sh_size)
+-		return 0;
+-
+-	printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
+-	       me->name);
+-	return -ENOEXEC;
+-}
+diff --git a/arch/mips/kernel/module-elf64.c b/arch/mips/kernel/module-elf64.c
+deleted file mode 100644
+--- a/arch/mips/kernel/module-elf64.c
++++ /dev/null
+@@ -1,274 +0,0 @@
+-/*
+- *  This program is free software; you can redistribute it and/or modify
+- *  it under the terms of the 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
+- *
+- *  Copyright (C) 2001 Rusty Russell.
+- *  Copyright (C) 2003, 2004 Ralf Baechle (ralf at linux-mips.org)
+- */
+-
+-#undef DEBUG
+-
+-#include <linux/moduleloader.h>
+-#include <linux/elf.h>
+-#include <linux/vmalloc.h>
+-#include <linux/slab.h>
+-#include <linux/fs.h>
+-#include <linux/string.h>
+-#include <linux/kernel.h>
+-
+-struct mips_hi16 {
+-	struct mips_hi16 *next;
+-	Elf32_Addr *addr;
+-	Elf64_Addr value;
+-};
+-
+-static struct mips_hi16 *mips_hi16_list;
+-
+-void *module_alloc(unsigned long size)
+-{
+-	if (size == 0)
+-		return NULL;
+-	return vmalloc(size);
+-}
+-
+-
+-/* Free memory returned from module_alloc */
+-void module_free(struct module *mod, void *module_region)
+-{
+-	vfree(module_region);
+-	/* FIXME: If module_region == mod->init_region, trim exception
+-           table entries. */
+-}
+-
+-int module_frob_arch_sections(Elf_Ehdr *hdr,
+-			      Elf_Shdr *sechdrs,
+-			      char *secstrings,
+-			      struct module *mod)
+-{
+-	return 0;
+-}
+-
+-int apply_relocate(Elf64_Shdr *sechdrs,
+-		   const char *strtab,
+-		   unsigned int symindex,
+-		   unsigned int relsec,
+-		   struct module *me)
+-{
+-	/*
+-	 * We don't want to deal with REL relocations - RELA is so much saner.
+-	 */
+-	if (!sechdrs[relsec].sh_size)
+-		return 0;
+-
+-	printk(KERN_ERR "module %s: REL relocation unsupported\n",
+-	       me->name);
+-	return -ENOEXEC;
+-}
+-
+-static int apply_r_mips_none(struct module *me, uint32_t *location,
+-	Elf64_Addr v)
+-{
+-	return 0;
+-}
+-
+-static int apply_r_mips_32(struct module *me, uint32_t *location,
+-	Elf64_Addr v)
+-{
+-	*location = v;
+-
+-	return 0;
+-}
+-
+-static int apply_r_mips_26(struct module *me, uint32_t *location,
+-	Elf64_Addr v)
+-{
+-	if (v % 4) {
+-		printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
+-		return -ENOEXEC;
+-	}
+-
+-	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+-		printk(KERN_ERR
+-		       "module %s: relocation overflow\n",
+-		       me->name);
+-		return -ENOEXEC;
+-	}
+-
+-	*location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
+-
+-	return 0;
+-}
+-
+-static int apply_r_mips_hi16(struct module *me, uint32_t *location,
+-	Elf64_Addr v)
+-{
+-	struct mips_hi16 *n;
+-
+-	/*
+-	 * We cannot relocate this one now because we don't know the value of
+-	 * the carry we need to add.  Save the information, and let LO16 do the
+-	 * actual relocation.
+-	 */
+-	n = kmalloc(sizeof *n, GFP_KERNEL);
+-	if (!n)
+-		return -ENOMEM;
+-
+-	n->addr = location;
+-	n->value = v;
+-	n->next = mips_hi16_list;
+-	mips_hi16_list = n;
+-
+-	return 0;
+-}
+-
+-static int apply_r_mips_lo16(struct module *me, uint32_t *location,
+-	Elf64_Addr v)
+-{
+-	unsigned long insnlo = *location;
+-	Elf32_Addr val, vallo;
+-
+-	/* Sign extend the addend we extract from the lo insn.  */
+-	vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+-
+-	if (mips_hi16_list != NULL) {
+-		struct mips_hi16 *l;
+-
+-		l = mips_hi16_list;
+-		while (l != NULL) {
+-			struct mips_hi16 *next;
+-			unsigned long insn;
+-
+-			/*
+-			 * The value for the HI16 had best be the same.
+-			 */
+-			if (v != l->value)
+-				goto out_danger;
+-
+-			/*
+-			 * Do the HI16 relocation.  Note that we actually don't
+-			 * need to know anything about the LO16 itself, except
+-			 * where to find the low 16 bits of the addend needed
+-			 * by the LO16.
+-			 */
+-			insn = *l->addr;
+-			val = ((insn & 0xffff) << 16) + vallo;
+-			val += v;
+-
+-			/*
+-			 * Account for the sign extension that will happen in
+-			 * the low bits.
+-			 */
+-			val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+-
+-			insn = (insn & ~0xffff) | val;
+-			*l->addr = insn;
+-
+-			next = l->next;
+-			kfree(l);
+-			l = next;
+-		}
+-
+-		mips_hi16_list = NULL;
+-	}
+-
+-	/*
+-	 * Ok, we're done with the HI16 relocs.  Now deal with the LO16.
+-	 */
+-	insnlo = (insnlo & ~0xffff) | (v & 0xffff);
+-	*location = insnlo;
+-
+-	return 0;
+-
+-out_danger:
+-	printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
+-
+-	return -ENOEXEC;
+-}
+-
+-static int apply_r_mips_64(struct module *me, uint32_t *location,
+-	Elf64_Addr v)
+-{
+-	*(uint64_t *) location = v;
+-
+-	return 0;
+-}
+-
+-
+-static int apply_r_mips_higher(struct module *me, uint32_t *location,
+-	Elf64_Addr v)
+-{
+-	*location = (*location & 0xffff0000) |
+-	            ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
+-
+-	return 0;
+-}
+-
+-static int apply_r_mips_highest(struct module *me, uint32_t *location,
+-	Elf64_Addr v)
+-{
+-	*location = (*location & 0xffff0000) |
+-	            ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
+-
+-	return 0;
+-}
+-
+-static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
+-	Elf64_Addr v) = {
+-	[R_MIPS_NONE]		= apply_r_mips_none,
+-	[R_MIPS_32]		= apply_r_mips_32,
+-	[R_MIPS_26]		= apply_r_mips_26,
+-	[R_MIPS_HI16]		= apply_r_mips_hi16,
+-	[R_MIPS_LO16]		= apply_r_mips_lo16,
+-	[R_MIPS_64]		= apply_r_mips_64,
+-	[R_MIPS_HIGHER]		= apply_r_mips_higher,
+-	[R_MIPS_HIGHEST]	= apply_r_mips_highest
+-};
+-
+-int apply_relocate_add(Elf64_Shdr *sechdrs,
+-		       const char *strtab,
+-		       unsigned int symindex,
+-		       unsigned int relsec,
+-		       struct module *me)
+-{
+-	Elf64_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
+-	Elf64_Sym *sym;
+-	uint32_t *location;
+-	unsigned int i;
+-	Elf64_Addr v;
+-	int res;
+-
+-	pr_debug("Applying relocate section %u to %u\n", relsec,
+-	       sechdrs[relsec].sh_info);
+-
+-	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+-		/* This is where to make the change */
+-		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+-			+ rel[i].r_offset;
+-		/* This is the symbol it is referring to */
+-		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr + rel[i].r_sym;
+-		if (!sym->st_value) {
+-			printk(KERN_WARNING "%s: Unknown symbol %s\n",
+-			       me->name, strtab + sym->st_name);
+-			return -ENOENT;
+-		}
+-
+-		v = sym->st_value;
+-
+-		res = reloc_handlers[rel[i].r_type](me, location, v);
+-		if (res)
+-			return res;
+-	}
+-
+-	return 0;
+-}
+diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
+--- a/arch/mips/kernel/module.c
++++ b/arch/mips/kernel/module.c
+@@ -1,9 +1,345 @@
++/*
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the 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
++ *
++ *  Copyright (C) 2001 Rusty Russell.
++ *  Copyright (C) 2003, 2004 Ralf Baechle (ralf at linux-mips.org)
++ *  Copyright (C) 2005 Thiemo Seufer
++ */
++
++#undef DEBUG
++
++#include <linux/moduleloader.h>
++#include <linux/elf.h>
++#include <linux/vmalloc.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/string.h>
++#include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/spinlock.h>
+ 
++struct mips_hi16 {
++	struct mips_hi16 *next;
++	Elf_Addr *addr;
++	Elf_Addr value;
++};
++
++static struct mips_hi16 *mips_hi16_list;
++
+ static LIST_HEAD(dbe_list);
+ static DEFINE_SPINLOCK(dbe_lock);
+ 
++void *module_alloc(unsigned long size)
++{
++	if (size == 0)
++		return NULL;
++	return vmalloc(size);
++}
++
++/* Free memory returned from module_alloc */
++void module_free(struct module *mod, void *module_region)
++{
++	vfree(module_region);
++	/* FIXME: If module_region == mod->init_region, trim exception
++           table entries. */
++}
++
++int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
++			      char *secstrings, struct module *mod)
++{
++	return 0;
++}
++
++static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v)
++{
++	return 0;
++}
++
++static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v)
++{
++	*location += v;
++
++	return 0;
++}
++
++static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v)
++{
++	*location = v;
++
++	return 0;
++}
++
++static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
++{
++	if (v % 4) {
++		printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
++		return -ENOEXEC;
++	}
++
++	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
++		printk(KERN_ERR
++		       "module %s: relocation overflow\n",
++		       me->name);
++		return -ENOEXEC;
++	}
++
++	*location = (*location & ~0x03ffffff) |
++	            ((*location + (v >> 2)) & 0x03ffffff);
++
++	return 0;
++}
++
++static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
++{
++	if (v % 4) {
++		printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
++		return -ENOEXEC;
++	}
++
++	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
++		printk(KERN_ERR
++		       "module %s: relocation overflow\n",
++		       me->name);
++		return -ENOEXEC;
++	}
++
++	*location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
++
++	return 0;
++}
++
++static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
++{
++	struct mips_hi16 *n;
++
++	/*
++	 * We cannot relocate this one now because we don't know the value of
++	 * the carry we need to add.  Save the information, and let LO16 do the
++	 * actual relocation.
++	 */
++	n = kmalloc(sizeof *n, GFP_KERNEL);
++	if (!n)
++		return -ENOMEM;
++
++	n->addr = (Elf_Addr *)location;
++	n->value = v;
++	n->next = mips_hi16_list;
++	mips_hi16_list = n;
++
++	return 0;
++}
++
++static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)
++{
++	*location = (*location & 0xffff0000) |
++	            ((((long long) v + 0x8000LL) >> 16) & 0xffff);
++
++	return 0;
++}
++
++static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
++{
++	unsigned long insnlo = *location;
++	Elf_Addr val, vallo;
++
++	/* Sign extend the addend we extract from the lo insn.  */
++	vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
++
++	if (mips_hi16_list != NULL) {
++		struct mips_hi16 *l;
++
++		l = mips_hi16_list;
++		while (l != NULL) {
++			struct mips_hi16 *next;
++			unsigned long insn;
++
++			/*
++			 * The value for the HI16 had best be the same.
++			 */
++			if (v != l->value)
++				goto out_danger;
++
++			/*
++			 * Do the HI16 relocation.  Note that we actually don't
++			 * need to know anything about the LO16 itself, except
++			 * where to find the low 16 bits of the addend needed
++			 * by the LO16.
++			 */
++			insn = *l->addr;
++			val = ((insn & 0xffff) << 16) + vallo;
++			val += v;
++
++			/*
++			 * Account for the sign extension that will happen in
++			 * the low bits.
++			 */
++			val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
++
++			insn = (insn & ~0xffff) | val;
++			*l->addr = insn;
++
++			next = l->next;
++			kfree(l);
++			l = next;
++		}
++
++		mips_hi16_list = NULL;
++	}
++
++	/*
++	 * Ok, we're done with the HI16 relocs.  Now deal with the LO16.
++	 */
++	val = v + vallo;
++	insnlo = (insnlo & ~0xffff) | (val & 0xffff);
++	*location = insnlo;
++
++	return 0;
++
++out_danger:
++	printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
++
++	return -ENOEXEC;
++}
++
++static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v)
++{
++	*location = (*location & 0xffff0000) | (v & 0xffff);
++
++	return 0;
++}
++
++static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v)
++{
++	*(Elf_Addr *)location = v;
++
++	return 0;
++}
++
++static int apply_r_mips_higher_rela(struct module *me, u32 *location,
++				    Elf_Addr v)
++{
++	*location = (*location & 0xffff0000) |
++	            ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
++
++	return 0;
++}
++
++static int apply_r_mips_highest_rela(struct module *me, u32 *location,
++				     Elf_Addr v)
++{
++	*location = (*location & 0xffff0000) |
++	            ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
++
++	return 0;
++}
++
++static int (*reloc_handlers_rel[]) (struct module *me, u32 *location,
++				Elf_Addr v) = {
++	[R_MIPS_NONE]		= apply_r_mips_none,
++	[R_MIPS_32]		= apply_r_mips_32_rel,
++	[R_MIPS_26]		= apply_r_mips_26_rel,
++	[R_MIPS_HI16]		= apply_r_mips_hi16_rel,
++	[R_MIPS_LO16]		= apply_r_mips_lo16_rel
++};
++
++static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
++				Elf_Addr v) = {
++	[R_MIPS_NONE]		= apply_r_mips_none,
++	[R_MIPS_32]		= apply_r_mips_32_rela,
++	[R_MIPS_26]		= apply_r_mips_26_rela,
++	[R_MIPS_HI16]		= apply_r_mips_hi16_rela,
++	[R_MIPS_LO16]		= apply_r_mips_lo16_rela,
++	[R_MIPS_64]		= apply_r_mips_64_rela,
++	[R_MIPS_HIGHER]		= apply_r_mips_higher_rela,
++	[R_MIPS_HIGHEST]	= apply_r_mips_highest_rela
++};
++
++int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
++		   unsigned int symindex, unsigned int relsec,
++		   struct module *me)
++{
++	Elf_Mips_Rel *rel = (void *) sechdrs[relsec].sh_addr;
++	Elf_Sym *sym;
++	u32 *location;
++	unsigned int i;
++	Elf_Addr v;
++	int res;
++
++	pr_debug("Applying relocate section %u to %u\n", relsec,
++	       sechdrs[relsec].sh_info);
++
++	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
++		/* This is where to make the change */
++		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
++			+ rel[i].r_offset;
++		/* This is the symbol it is referring to */
++		sym = (Elf_Sym *)sechdrs[symindex].sh_addr
++			+ ELF_MIPS_R_SYM(rel[i]);
++		if (!sym->st_value) {
++			printk(KERN_WARNING "%s: Unknown symbol %s\n",
++			       me->name, strtab + sym->st_name);
++			return -ENOENT;
++		}
++
++		v = sym->st_value;
++
++		res = reloc_handlers_rel[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
++		if (res)
++			return res;
++	}
++
++	return 0;
++}
++
++int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
++		       unsigned int symindex, unsigned int relsec,
++		       struct module *me)
++{
++	Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
++	Elf_Sym *sym;
++	u32 *location;
++	unsigned int i;
++	Elf_Addr v;
++	int res;
++
++	pr_debug("Applying relocate section %u to %u\n", relsec,
++	       sechdrs[relsec].sh_info);
++
++	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
++		/* This is where to make the change */
++		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
++			+ rel[i].r_offset;
++		/* This is the symbol it is referring to */
++		sym = (Elf_Sym *)sechdrs[symindex].sh_addr
++			+ ELF_MIPS_R_SYM(rel[i]);
++		if (!sym->st_value) {
++			printk(KERN_WARNING "%s: Unknown symbol %s\n",
++			       me->name, strtab + sym->st_name);
++			return -ENOENT;
++		}
++
++		v = sym->st_value + rel[i].r_addend;
++
++		res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
++		if (res)
++			return res;
++	}
++
++	return 0;
++}
++
+ /* Given an address, look for it in the module exception tables. */
+ const struct exception_table_entry *search_module_dbetables(unsigned long addr)
+ {
+diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
+--- a/arch/mips/kernel/proc.c
++++ b/arch/mips/kernel/proc.c
+@@ -2,7 +2,8 @@
+  *  linux/arch/mips/kernel/proc.c
+  *
+  *  Copyright (C) 1995, 1996, 2001  Ralf Baechle
+- *  Copyright (C) 2001  MIPS Technologies, Inc.
++ *  Copyright (C) 2001, 2004  MIPS Technologies, Inc.
++ *  Copyright (C) 2004  Maciej W. Rozycki
+  */
+ #include <linux/config.h>
+ #include <linux/delay.h>
+@@ -19,63 +20,69 @@
+ unsigned int vced_count, vcei_count;
+ 
+ static const char *cpu_name[] = {
+-	[CPU_UNKNOWN]	"unknown",
+-	[CPU_R2000]	"R2000",
+-	[CPU_R3000]	"R3000",
+-	[CPU_R3000A]	"R3000A",
+-	[CPU_R3041]	"R3041",
+-	[CPU_R3051]	"R3051",
+-	[CPU_R3052]	"R3052",
+-	[CPU_R3081]	"R3081",
+-	[CPU_R3081E]	"R3081E",
+-	[CPU_R4000PC]	"R4000PC",
+-	[CPU_R4000SC]	"R4000SC",
+-	[CPU_R4000MC]	"R4000MC",
+-        [CPU_R4200]	"R4200",
+-	[CPU_R4400PC]	"R4400PC",
+-	[CPU_R4400SC]	"R4400SC",
+-	[CPU_R4400MC]	"R4400MC",
+-	[CPU_R4600]	"R4600",
+-	[CPU_R6000]	"R6000",
+-        [CPU_R6000A]	"R6000A",
+-	[CPU_R8000]	"R8000",
+-	[CPU_R10000]	"R10000",
+-	[CPU_R12000]	"R12000",
+-	[CPU_R4300]	"R4300",
+-	[CPU_R4650]	"R4650",
+-	[CPU_R4700]	"R4700",
+-	[CPU_R5000]	"R5000",
+-        [CPU_R5000A]	"R5000A",
+-	[CPU_R4640]	"R4640",
+-	[CPU_NEVADA]	"Nevada",
+-	[CPU_RM7000]	"RM7000",
+-	[CPU_RM9000]	"RM9000",
+-	[CPU_R5432]	"R5432",
+-	[CPU_4KC]	"MIPS 4Kc",
+-        [CPU_5KC]	"MIPS 5Kc",
+-	[CPU_R4310]	"R4310",
+-	[CPU_SB1]	"SiByte SB1",
+-	[CPU_TX3912]	"TX3912",
+-	[CPU_TX3922]	"TX3922",
+-	[CPU_TX3927]	"TX3927",
+-	[CPU_AU1000]	"Au1000",
+-	[CPU_AU1500]	"Au1500",
+-	[CPU_4KEC]	"MIPS 4KEc",
+-	[CPU_4KSC]	"MIPS 4KSc",
+-	[CPU_VR41XX]	"NEC Vr41xx",
+-	[CPU_R5500]	"R5500",
+-	[CPU_TX49XX]	"TX49xx",
+-	[CPU_20KC]	"MIPS 20Kc",
+-	[CPU_24K]	"MIPS 24K",
+-	[CPU_25KF]	"MIPS 25Kf",
+-	[CPU_VR4111]	"NEC VR4111",
+-	[CPU_VR4121]	"NEC VR4121",
+-	[CPU_VR4122]	"NEC VR4122",
+-	[CPU_VR4131]	"NEC VR4131",
+-	[CPU_VR4133]	"NEC VR4133",
+-	[CPU_VR4181]	"NEC VR4181",
+-	[CPU_VR4181A]	"NEC VR4181A",
+-	[CPU_SR71000]	"Sandcraft SR71000"
++	[CPU_UNKNOWN]	= "unknown",
++	[CPU_R2000]	= "R2000",
++	[CPU_R3000]	= "R3000",
++	[CPU_R3000A]	= "R3000A",
++	[CPU_R3041]	= "R3041",
++	[CPU_R3051]	= "R3051",
++	[CPU_R3052]	= "R3052",
++	[CPU_R3081]	= "R3081",
++	[CPU_R3081E]	= "R3081E",
++	[CPU_R4000PC]	= "R4000PC",
++	[CPU_R4000SC]	= "R4000SC",
++	[CPU_R4000MC]	= "R4000MC",
++        [CPU_R4200]	= "R4200",
++	[CPU_R4400PC]	= "R4400PC",
++	[CPU_R4400SC]	= "R4400SC",
++	[CPU_R4400MC]	= "R4400MC",
++	[CPU_R4600]	= "R4600",
++	[CPU_R6000]	= "R6000",
++        [CPU_R6000A]	= "R6000A",
++	[CPU_R8000]	= "R8000",
++	[CPU_R10000]	= "R10000",
++	[CPU_R12000]	= "R12000",
++	[CPU_R4300]	= "R4300",
++	[CPU_R4650]	= "R4650",
++	[CPU_R4700]	= "R4700",
++	[CPU_R5000]	= "R5000",
++        [CPU_R5000A]	= "R5000A",
++	[CPU_R4640]	= "R4640",
++	[CPU_NEVADA]	= "Nevada",
++	[CPU_RM7000]	= "RM7000",
++	[CPU_RM9000]	= "RM9000",
++	[CPU_R5432]	= "R5432",
++	[CPU_4KC]	= "MIPS 4Kc",
++        [CPU_5KC]	= "MIPS 5Kc",
++	[CPU_R4310]	= "R4310",
++	[CPU_SB1]	= "SiByte SB1",
++	[CPU_SB1A]	= "SiByte SB1A",
++	[CPU_TX3912]	= "TX3912",
++	[CPU_TX3922]	= "TX3922",
++	[CPU_TX3927]	= "TX3927",
++	[CPU_AU1000]	= "Au1000",
++	[CPU_AU1500]	= "Au1500",
++	[CPU_AU1100]	= "Au1100",
++	[CPU_AU1550]	= "Au1550",
++	[CPU_AU1200]	= "Au1200",
++	[CPU_4KEC]	= "MIPS 4KEc",
++	[CPU_4KSC]	= "MIPS 4KSc",
++	[CPU_VR41XX]	= "NEC Vr41xx",
++	[CPU_R5500]	= "R5500",
++	[CPU_TX49XX]	= "TX49xx",
++	[CPU_20KC]	= "MIPS 20Kc",
++	[CPU_24K]	= "MIPS 24K",
++	[CPU_25KF]	= "MIPS 25Kf",
++	[CPU_34K]	= "MIPS 34K",
++	[CPU_VR4111]	= "NEC VR4111",
++	[CPU_VR4121]	= "NEC VR4121",
++	[CPU_VR4122]	= "NEC VR4122",
++	[CPU_VR4131]	= "NEC VR4131",
++	[CPU_VR4133]	= "NEC VR4133",
++	[CPU_VR4181]	= "NEC VR4181",
++	[CPU_VR4181A]	= "NEC VR4181A",
++	[CPU_SR71000]	= "Sandcraft SR71000",
++	[CPU_PR4450]	= "Philips PR4450",
+ };
+ 
+ 
+@@ -105,8 +112,8 @@ static int show_cpuinfo(struct seq_file 
+ 	                           (version >> 4) & 0x0f, version & 0x0f,
+ 	                           (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
+ 	seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
+-	              loops_per_jiffy / (500000/HZ),
+-	              (loops_per_jiffy / (5000/HZ)) % 100);
++	              cpu_data[n].udelay_val / (500000/HZ),
++	              (cpu_data[n].udelay_val / (5000/HZ)) % 100);
+ 	seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
+ 	seq_printf(m, "microsecond timers\t: %s\n",
+ 	              cpu_has_counter ? "yes" : "no");
+@@ -115,6 +122,14 @@ static int show_cpuinfo(struct seq_file 
+ 	              cpu_has_divec ? "yes" : "no");
+ 	seq_printf(m, "hardware watchpoint\t: %s\n",
+ 	              cpu_has_watch ? "yes" : "no");
++	seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n",
++		      cpu_has_mips16 ? " mips16" : "",
++		      cpu_has_mdmx ? " mdmx" : "",
++		      cpu_has_mips3d ? " mips3d" : "",
++		      cpu_has_smartmips ? " smartmips" : "",
++		      cpu_has_dsp ? " dsp" : "",
++		      cpu_has_mipsmt ? " mt" : ""
++		);
+ 
+ 	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
+ 	        cpu_has_vce ? "%u" : "not available");
+diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -25,8 +25,10 @@
+ #include <linux/init.h>
+ #include <linux/completion.h>
+ 
++#include <asm/abi.h>
+ #include <asm/bootinfo.h>
+ #include <asm/cpu.h>
++#include <asm/dsp.h>
+ #include <asm/fpu.h>
+ #include <asm/pgtable.h>
+ #include <asm/system.h>
+@@ -39,14 +41,6 @@
+ #include <asm/inst.h>
+ 
+ /*
+- * We use this if we don't have any better idle routine..
+- * (This to kill: kernel/platform.c.
+- */
+-void default_idle (void)
+-{
+-}
+-
+-/*
+  * The idle thread. There's no useful work to be done, so just try to conserve
+  * power and have a low exit latency (ie sit in a loop waiting for somebody to
+  * say that they'd like to reschedule)
+@@ -62,6 +56,54 @@ ATTRIB_NORET void cpu_idle(void)
+ 	}
+ }
+ 
++extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
++extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
++
++/*
++ * Native o32 and N64 ABI without DSP ASE
++ */
++extern int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
++        int signr, sigset_t *set);
++extern int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
++        int signr, sigset_t *set, siginfo_t *info);
++
++struct mips_abi mips_abi = {
++	.do_signal	= do_signal,
++#ifdef CONFIG_TRAD_SIGNALS
++	.setup_frame	= setup_frame,
++#endif
++	.setup_rt_frame	= setup_rt_frame
++};
++
++#ifdef CONFIG_MIPS32_O32
++/*
++ * o32 compatibility on 64-bit kernels, without DSP ASE
++ */
++extern int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
++        int signr, sigset_t *set);
++extern int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
++        int signr, sigset_t *set, siginfo_t *info);
++
++struct mips_abi mips_abi_32 = {
++	.do_signal	= do_signal32,
++	.setup_frame	= setup_frame_32,
++	.setup_rt_frame	= setup_rt_frame_32
++};
++#endif /* CONFIG_MIPS32_O32 */
++
++#ifdef CONFIG_MIPS32_N32
++/*
++ * N32 on 64-bit kernels, without DSP ASE
++ */
++extern int setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs,
++        int signr, sigset_t *set, siginfo_t *info);
++
++struct mips_abi mips_abi_n32 = {
++	.do_signal	= do_signal,
++	.setup_rt_frame	= setup_rt_frame_n32
++};
++#endif /* CONFIG_MIPS32_N32 */
++
+ asmlinkage void ret_from_fork(void);
+ 
+ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+@@ -78,6 +120,8 @@ void start_thread(struct pt_regs * regs,
+ 	regs->cp0_status = status;
+ 	clear_used_math();
+ 	lose_fpu();
++	if (cpu_has_dsp)
++		__init_dsp();
+ 	regs->cp0_epc = pc;
+ 	regs->regs[29] = sp;
+ 	current_thread_info()->addr_limit = USER_DS;
+@@ -97,14 +141,17 @@ int copy_thread(int nr, unsigned long cl
+ 	struct thread_info *ti = p->thread_info;
+ 	struct pt_regs *childregs;
+ 	long childksp;
++	p->set_child_tid = p->clear_child_tid = NULL;
+ 
+ 	childksp = (unsigned long)ti + THREAD_SIZE - 32;
+ 
+ 	preempt_disable();
+ 
+-	if (is_fpu_owner()) {
++	if (is_fpu_owner())
+ 		save_fp(p);
+-	}
++
++	if (cpu_has_dsp)
++		save_dsp(p);
+ 
+ 	preempt_enable();
+ 
+@@ -142,6 +189,9 @@ int copy_thread(int nr, unsigned long cl
+ 	childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
+ 	clear_tsk_thread_flag(p, TIF_USEDFPU);
+ 
++	if (clone_flags & CLONE_SETTLS)
++		ti->tp_value = regs->regs[7];
++
+ 	return 0;
+ }
+ 
+@@ -175,6 +225,14 @@ void dump_regs(elf_greg_t *gp, struct pt
+ #endif
+ }
+ 
++int dump_task_regs (struct task_struct *tsk, elf_gregset_t *regs)
++{
++	struct thread_info *ti = tsk->thread_info;
++	long ksp = (unsigned long)ti + THREAD_SIZE - 32;
++	dump_regs(&(*regs)[0], (struct pt_regs *) ksp - 1);
++	return 1;
++}
++
+ int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
+ {
+ 	memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu));
+@@ -211,22 +269,48 @@ long kernel_thread(int (*fn)(void *), vo
+ 	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+ }
+ 
+-struct mips_frame_info {
++static struct mips_frame_info {
++	void *func;
++	int omit_fp;	/* compiled without fno-omit-frame-pointer */
+ 	int frame_offset;
+ 	int pc_offset;
++} schedule_frame, mfinfo[] = {
++	{ schedule, 0 },	/* must be first */
++	/* arch/mips/kernel/semaphore.c */
++	{ __down, 1 },
++	{ __down_interruptible, 1 },
++	/* kernel/sched.c */
++#ifdef CONFIG_PREEMPT
++	{ preempt_schedule, 0 },
++#endif
++	{ wait_for_completion, 0 },
++	{ interruptible_sleep_on, 0 },
++	{ interruptible_sleep_on_timeout, 0 },
++	{ sleep_on, 0 },
++	{ sleep_on_timeout, 0 },
++	{ yield, 0 },
++	{ io_schedule, 0 },
++	{ io_schedule_timeout, 0 },
++#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
++	{ __preempt_spin_lock, 0 },
++	{ __preempt_write_lock, 0 },
++#endif
++	/* kernel/timer.c */
++	{ schedule_timeout, 1 },
++/*	{ nanosleep_restart, 1 }, */
++	/* lib/rwsem-spinlock.c */
++	{ __down_read, 1 },
++	{ __down_write, 1 },
+ };
+-static struct mips_frame_info schedule_frame;
+-static struct mips_frame_info schedule_timeout_frame;
+-static struct mips_frame_info sleep_on_frame;
+-static struct mips_frame_info sleep_on_timeout_frame;
+-static struct mips_frame_info wait_for_completion_frame;
++
+ static int mips_frame_info_initialized;
+-static int __init get_frame_info(struct mips_frame_info *info, void *func)
++static int __init get_frame_info(struct mips_frame_info *info)
+ {
+ 	int i;
++	void *func = info->func;
+ 	union mips_instruction *ip = (union mips_instruction *)func;
+ 	info->pc_offset = -1;
+-	info->frame_offset = -1;
++	info->frame_offset = info->omit_fp ? 0 : -1;
+ 	for (i = 0; i < 128; i++, ip++) {
+ 		/* if jal, jalr, jr, stop. */
+ 		if (ip->j_format.opcode == jal_op ||
+@@ -247,14 +331,16 @@ static int __init get_frame_info(struct 
+ 			/* sw / sd $ra, offset($sp) */
+ 			if (ip->i_format.rt == 31) {
+ 				if (info->pc_offset != -1)
+-					break;
++					continue;
+ 				info->pc_offset =
+ 					ip->i_format.simmediate / sizeof(long);
+ 			}
+ 			/* sw / sd $s8, offset($sp) */
+ 			if (ip->i_format.rt == 30) {
++//#if 0	/* gcc 3.4 does aggressive optimization... */
+ 				if (info->frame_offset != -1)
+-					break;
++					continue;
++//#endif
+ 				info->frame_offset =
+ 					ip->i_format.simmediate / sizeof(long);
+ 			}
+@@ -272,13 +358,25 @@ static int __init get_frame_info(struct 
+ 
+ static int __init frame_info_init(void)
+ {
+-	mips_frame_info_initialized =
+-		!get_frame_info(&schedule_frame, schedule) &&
+-		!get_frame_info(&schedule_timeout_frame, schedule_timeout) &&
+-		!get_frame_info(&sleep_on_frame, sleep_on) &&
+-		!get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) &&
+-		!get_frame_info(&wait_for_completion_frame, wait_for_completion);
+-
++	int i, found;
++	for (i = 0; i < ARRAY_SIZE(mfinfo); i++)
++		if (get_frame_info(&mfinfo[i]))
++			return -1;
++	schedule_frame = mfinfo[0];
++	/* bubble sort */
++	do {
++		struct mips_frame_info tmp;
++		found = 0;
++		for (i = 1; i < ARRAY_SIZE(mfinfo); i++) {
++			if (mfinfo[i-1].func > mfinfo[i].func) {
++				tmp = mfinfo[i];
++				mfinfo[i] = mfinfo[i-1];
++				mfinfo[i-1] = tmp;
++				found = 1;
++			}
++		}
++	} while (found);
++	mips_frame_info_initialized = 1;
+ 	return 0;
+ }
+ 
+@@ -303,60 +401,39 @@ unsigned long thread_saved_pc(struct tas
+ /* get_wchan - a maintenance nightmare^W^Wpain in the ass ...  */
+ unsigned long get_wchan(struct task_struct *p)
+ {
++	unsigned long stack_page;
+ 	unsigned long frame, pc;
+ 
+ 	if (!p || p == current || p->state == TASK_RUNNING)
+ 		return 0;
+ 
+-	if (!mips_frame_info_initialized)
++	stack_page = (unsigned long)p->thread_info;
++	if (!stack_page || !mips_frame_info_initialized)
+ 		return 0;
++
+ 	pc = thread_saved_pc(p);
+ 	if (!in_sched_functions(pc))
+-		goto out;
+-
+-	if (pc >= (unsigned long) sleep_on_timeout)
+-		goto schedule_timeout_caller;
+-	if (pc >= (unsigned long) sleep_on)
+-		goto schedule_caller;
+-	if (pc >= (unsigned long) interruptible_sleep_on_timeout)
+-		goto schedule_timeout_caller;
+-	if (pc >= (unsigned long)interruptible_sleep_on)
+-		goto schedule_caller;
+-	if (pc >= (unsigned long)wait_for_completion)
+-		goto schedule_caller;
+-	goto schedule_timeout_caller;
+-
+-schedule_caller:
+-	frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
+-	if (pc >= (unsigned long) sleep_on)
+-		pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset];
+-	else
+-		pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset];
+-	goto out;
++		return pc;
+ 
+-schedule_timeout_caller:
+-	/*
+-	 * The schedule_timeout frame
+-	 */
+ 	frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
++	do {
++		int i;
+ 
+-	/*
+-	 * frame now points to sleep_on_timeout's frame
+-	 */
+-	pc    = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset];
+-
+-	if (in_sched_functions(pc)) {
+-		/* schedule_timeout called by [interruptible_]sleep_on_timeout */
+-		frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset];
+-		pc    = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset];
+-	}
++		if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32)
++			return 0;
+ 
+-out:
++		for (i = ARRAY_SIZE(mfinfo) - 1; i >= 0; i--) {
++			if (pc >= (unsigned long) mfinfo[i].func)
++				break;
++		}
++		if (i < 0)
++			break;
+ 
+-#ifdef CONFIG_64BIT
+-	if (current->thread.mflags & MF_32BIT_REGS) /* Kludge for 32-bit ps  */
+-		pc &= 0xffffffffUL;
+-#endif
++		if (mfinfo[i].omit_fp)
++			break;
++		pc = ((unsigned long *)frame)[mfinfo[i].pc_offset];
++		frame = ((unsigned long *)frame)[mfinfo[i].frame_offset];
++	} while (in_sched_functions(pc));
+ 
+ 	return pc;
+ }
+diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -28,14 +28,18 @@
+ #include <linux/security.h>
+ #include <linux/signal.h>
+ 
++#include <asm/byteorder.h>
+ #include <asm/cpu.h>
++#include <asm/dsp.h>
+ #include <asm/fpu.h>
+ #include <asm/mipsregs.h>
++#include <asm/mipsmtregs.h>
+ #include <asm/pgtable.h>
+ #include <asm/page.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ #include <asm/bootinfo.h>
++#include <asm/reg.h>
+ 
+ /*
+  * Called by kernel/ptrace.c when detaching..
+@@ -47,7 +51,130 @@ void ptrace_disable(struct task_struct *
+ 	/* Nothing to do.. */
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++/*
++ * Read a general register set.  We always use the 64-bit format, even
++ * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
++ * Registers are sign extended to fill the available space.
++ */
++int ptrace_getregs (struct task_struct *child, __s64 __user *data)
++{
++	struct pt_regs *regs;
++	int i;
++
++	if (!access_ok(VERIFY_WRITE, data, 38 * 8))
++		return -EIO;
++
++	regs = (struct pt_regs *) ((unsigned long) child->thread_info +
++	       THREAD_SIZE - 32 - sizeof(struct pt_regs));
++
++	for (i = 0; i < 32; i++)
++		__put_user (regs->regs[i], data + i);
++	__put_user (regs->lo, data + EF_LO - EF_R0);
++	__put_user (regs->hi, data + EF_HI - EF_R0);
++	__put_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
++	__put_user (regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
++	__put_user (regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
++	__put_user (regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
++
++	return 0;
++}
++
++/*
++ * Write a general register set.  As for PTRACE_GETREGS, we always use
++ * the 64-bit format.  On a 32-bit kernel only the lower order half
++ * (according to endianness) will be used.
++ */
++int ptrace_setregs (struct task_struct *child, __s64 __user *data)
++{
++	struct pt_regs *regs;
++	int i;
++
++	if (!access_ok(VERIFY_READ, data, 38 * 8))
++		return -EIO;
++
++	regs = (struct pt_regs *) ((unsigned long) child->thread_info +
++	       THREAD_SIZE - 32 - sizeof(struct pt_regs));
++
++	for (i = 0; i < 32; i++)
++		__get_user (regs->regs[i], data + i);
++	__get_user (regs->lo, data + EF_LO - EF_R0);
++	__get_user (regs->hi, data + EF_HI - EF_R0);
++	__get_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
++
++	/* badvaddr, status, and cause may not be written.  */
++
++	return 0;
++}
++
++int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
++{
++	int i;
++
++	if (!access_ok(VERIFY_WRITE, data, 33 * 8))
++		return -EIO;
++
++	if (tsk_used_math(child)) {
++		fpureg_t *fregs = get_fpu_regs(child);
++		for (i = 0; i < 32; i++)
++			__put_user (fregs[i], i + (__u64 __user *) data);
++	} else {
++		for (i = 0; i < 32; i++)
++			__put_user ((__u64) -1, i + (__u64 __user *) data);
++	}
++
++	if (cpu_has_fpu) {
++		unsigned int flags, tmp;
++
++		__put_user (child->thread.fpu.hard.fcr31, data + 64);
++
++		preempt_disable();
++		if (cpu_has_mipsmt) {
++			unsigned int vpflags = dvpe();
++			flags = read_c0_status();
++			__enable_fpu();
++			__asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
++			write_c0_status(flags);
++			evpe(vpflags);
++		} else {
++			flags = read_c0_status();
++			__enable_fpu();
++			__asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
++			write_c0_status(flags);
++		}
++		preempt_enable();
++		__put_user (tmp, data + 65);
++	} else {
++		__put_user (child->thread.fpu.soft.fcr31, data + 64);
++		__put_user ((__u32) 0, data + 65);
++	}
++
++	return 0;
++}
++
++int ptrace_setfpregs (struct task_struct *child, __u32 __user *data)
++{
++	fpureg_t *fregs;
++	int i;
++
++	if (!access_ok(VERIFY_READ, data, 33 * 8))
++		return -EIO;
++
++	fregs = get_fpu_regs(child);
++
++	for (i = 0; i < 32; i++)
++		__get_user (fregs[i], i + (__u64 __user *) data);
++
++	if (cpu_has_fpu)
++		__get_user (child->thread.fpu.hard.fcr31, data + 64);
++	else
++		__get_user (child->thread.fpu.soft.fcr31, data + 64);
++
++	/* FIR may not be written.  */
++
++	return 0;
++}
++
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	int ret;
+@@ -103,7 +230,7 @@ asmlinkage int sys_ptrace(long request, 
+ 		ret = -EIO;
+ 		if (copied != sizeof(tmp))
+ 			break;
+-		ret = put_user(tmp,(unsigned long *) data);
++		ret = put_user(tmp,(unsigned long __user *) data);
+ 		break;
+ 	}
+ 
+@@ -169,18 +296,53 @@ asmlinkage int sys_ptrace(long request, 
+ 			if (!cpu_has_fpu)
+ 				break;
+ 
+-			flags = read_c0_status();
+-			__enable_fpu();
+-			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+-			write_c0_status(flags);
++			preempt_disable();
++			if (cpu_has_mipsmt) {
++				unsigned int vpflags = dvpe();
++				flags = read_c0_status();
++				__enable_fpu();
++				__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
++				write_c0_status(flags);
++				evpe(vpflags);
++			} else {
++				flags = read_c0_status();
++				__enable_fpu();
++				__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
++				write_c0_status(flags);
++			}
++			preempt_enable();
++			break;
++		}
++		case DSP_BASE ... DSP_BASE + 5: {
++			dspreg_t *dregs;
++
++			if (!cpu_has_dsp) {
++				tmp = 0;
++				ret = -EIO;
++				goto out_tsk;
++			}
++			if (child->thread.dsp.used_dsp) {
++				dregs = __get_dsp_regs(child);
++				tmp = (unsigned long) (dregs[addr - DSP_BASE]);
++			} else {
++				tmp = -1;	/* DSP registers yet used  */
++			}
+ 			break;
+ 		}
++		case DSP_CONTROL:
++			if (!cpu_has_dsp) {
++				tmp = 0;
++				ret = -EIO;
++				goto out_tsk;
++			}
++			tmp = child->thread.dsp.dspcontrol;
++			break;
+ 		default:
+ 			tmp = 0;
+ 			ret = -EIO;
+ 			goto out_tsk;
+ 		}
+-		ret = put_user(tmp, (unsigned long *) data);
++		ret = put_user(tmp, (unsigned long __user *) data);
+ 		break;
+ 	}
+ 
+@@ -247,6 +409,25 @@ asmlinkage int sys_ptrace(long request, 
+ 			else
+ 				child->thread.fpu.soft.fcr31 = data;
+ 			break;
++		case DSP_BASE ... DSP_BASE + 5: {
++			dspreg_t *dregs;
++
++			if (!cpu_has_dsp) {
++				ret = -EIO;
++				break;
++			}
++
++			dregs = __get_dsp_regs(child);
++			dregs[addr - DSP_BASE] = data;
++			break;
++		}
++		case DSP_CONTROL:
++			if (!cpu_has_dsp) {
++				ret = -EIO;
++				break;
++			}
++			child->thread.dsp.dspcontrol = data;
++			break;
+ 		default:
+ 			/* The rest are not allowed. */
+ 			ret = -EIO;
+@@ -255,6 +436,22 @@ asmlinkage int sys_ptrace(long request, 
+ 		break;
+ 		}
+ 
++	case PTRACE_GETREGS:
++		ret = ptrace_getregs (child, (__u64 __user *) data);
++		break;
++
++	case PTRACE_SETREGS:
++		ret = ptrace_setregs (child, (__u64 __user *) data);
++		break;
++
++	case PTRACE_GETFPREGS:
++		ret = ptrace_getfpregs (child, (__u32 __user *) data);
++		break;
++
++	case PTRACE_SETFPREGS:
++		ret = ptrace_setfpregs (child, (__u32 __user *) data);
++		break;
++
+ 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+ 	case PTRACE_CONT: { /* restart after signal. */
+ 		ret = -EIO;
+@@ -289,6 +486,11 @@ asmlinkage int sys_ptrace(long request, 
+ 		ret = ptrace_detach(child, data);
+ 		break;
+ 
++	case PTRACE_GET_THREAD_AREA:
++		ret = put_user(child->thread_info->tp_value,
++				(unsigned long __user *) data);
++		break;
++
+ 	default:
+ 		ret = ptrace_request(child, request, addr, data);
+ 		break;
+@@ -303,21 +505,14 @@ out:
+ 
+ static inline int audit_arch(void)
+ {
+-#ifdef CONFIG_CPU_LITTLE_ENDIAN
+-#ifdef CONFIG_64BIT
+-	if (!(current->thread.mflags & MF_32BIT_REGS))
+-		return AUDIT_ARCH_MIPSEL64;
+-#endif /* MIPS64 */
+-	return AUDIT_ARCH_MIPSEL;
+-
+-#else /* big endian... */
++	int arch = EM_MIPS;
+ #ifdef CONFIG_64BIT
+-	if (!(current->thread.mflags & MF_32BIT_REGS))
+-		return AUDIT_ARCH_MIPS64;
+-#endif /* MIPS64 */
+-	return AUDIT_ARCH_MIPS;
+-
+-#endif /* endian */
++	arch |=  __AUDIT_ARCH_64BIT;
++#endif
++#if defined(__LITTLE_ENDIAN)
++	arch |=  __AUDIT_ARCH_LE;
++#endif
++	return arch;
+ }
+ 
+ /*
+@@ -327,12 +522,13 @@ static inline int audit_arch(void)
+ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
+ {
+ 	if (unlikely(current->audit_context) && entryexit)
+-		audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
++		audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]),
++		                   regs->regs[2]);
+ 
+-	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+-		goto out;
+ 	if (!(current->ptrace & PT_PTRACED))
+ 		goto out;
++	if (!test_thread_flag(TIF_SYSCALL_TRACE))
++		goto out;
+ 
+ 	/* The 0x80 provides a way for the tracing parent to distinguish
+ 	   between a syscall stop and SIGTRAP delivery */
+diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
+--- a/arch/mips/kernel/ptrace32.c
++++ b/arch/mips/kernel/ptrace32.c
+@@ -24,17 +24,24 @@
+ #include <linux/smp_lock.h>
+ #include <linux/user.h>
+ #include <linux/security.h>
+-#include <linux/signal.h>
+ 
+ #include <asm/cpu.h>
++#include <asm/dsp.h>
+ #include <asm/fpu.h>
+ #include <asm/mipsregs.h>
++#include <asm/mipsmtregs.h>
+ #include <asm/pgtable.h>
+ #include <asm/page.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ #include <asm/bootinfo.h>
+ 
++int ptrace_getregs (struct task_struct *child, __s64 __user *data);
++int ptrace_setregs (struct task_struct *child, __s64 __user *data);
++
++int ptrace_getfpregs (struct task_struct *child, __u32 __user *data);
++int ptrace_setfpregs (struct task_struct *child, __u32 __user *data);
++
+ /*
+  * Tracing a 32-bit process with a 64-bit strace and vice versa will not
+  * work.  I don't know how to fix this.
+@@ -99,6 +106,35 @@ asmlinkage int sys32_ptrace(int request,
+ 		break;
+ 	}
+ 
++	/*
++	 * Read 4 bytes of the other process' storage
++	 *  data is a pointer specifying where the user wants the
++	 *	4 bytes copied into
++	 *  addr is a pointer in the user's storage that contains an 8 byte
++	 *	address in the other process of the 4 bytes that is to be read
++	 * (this is run in a 32-bit process looking at a 64-bit process)
++	 * when I and D space are separate, these will need to be fixed.
++	 */
++	case PTRACE_PEEKTEXT_3264:
++	case PTRACE_PEEKDATA_3264: {
++		u32 tmp;
++		int copied;
++		u32 __user * addrOthers;
++
++		ret = -EIO;
++
++		/* Get the addr in the other process that we want to read */
++		if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
++			break;
++
++		copied = access_process_vm(child, (u64)addrOthers, &tmp,
++				sizeof(tmp), 0);
++		if (copied != sizeof(tmp))
++			break;
++		ret = put_user(tmp, (u32 __user *) (unsigned long) data);
++		break;
++	}
++
+ 	/* Read the word at location addr in the USER area. */
+ 	case PTRACE_PEEKUSR: {
+ 		struct pt_regs *regs;
+@@ -156,12 +192,44 @@ asmlinkage int sys32_ptrace(int request,
+ 			if (!cpu_has_fpu)
+ 				break;
+ 
+-			flags = read_c0_status();
+-			__enable_fpu();
+-			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+-			write_c0_status(flags);
++			preempt_disable();
++			if (cpu_has_mipsmt) {
++				unsigned int vpflags = dvpe();
++				flags = read_c0_status();
++				__enable_fpu();
++				__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
++				write_c0_status(flags);
++				evpe(vpflags);
++			} else {
++				flags = read_c0_status();
++				__enable_fpu();
++				__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
++				write_c0_status(flags);
++			}
++			preempt_enable();
+ 			break;
+ 		}
++		case DSP_BASE ... DSP_BASE + 5:
++			if (!cpu_has_dsp) {
++				tmp = 0;
++				ret = -EIO;
++				goto out_tsk;
++			}
++			if (child->thread.dsp.used_dsp) {
++				dspreg_t *dregs = __get_dsp_regs(child);
++				tmp = (unsigned long) (dregs[addr - DSP_BASE]);
++			} else {
++				tmp = -1;	/* DSP registers yet used  */
++			}
++			break;
++		case DSP_CONTROL:
++			if (!cpu_has_dsp) {
++				tmp = 0;
++				ret = -EIO;
++				goto out_tsk;
++			}
++			tmp = child->thread.dsp.dspcontrol;
++			break;
+ 		default:
+ 			tmp = 0;
+ 			ret = -EIO;
+@@ -181,6 +249,31 @@ asmlinkage int sys32_ptrace(int request,
+ 		ret = -EIO;
+ 		break;
+ 
++	/*
++	 * Write 4 bytes into the other process' storage
++	 *  data is the 4 bytes that the user wants written
++	 *  addr is a pointer in the user's storage that contains an
++	 *	8 byte address in the other process where the 4 bytes
++	 *	that is to be written
++	 * (this is run in a 32-bit process looking at a 64-bit process)
++	 * when I and D space are separate, these will need to be fixed.
++	 */
++	case PTRACE_POKETEXT_3264:
++	case PTRACE_POKEDATA_3264: {
++		u32 __user * addrOthers;
++
++		/* Get the addr in the other process that we want to write into */
++		ret = -EIO;
++		if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
++			break;
++		ret = 0;
++		if (access_process_vm(child, (u64)addrOthers, &data,
++					sizeof(data), 1) == sizeof(data))
++			break;
++		ret = -EIO;
++		break;
++	}
++
+ 	case PTRACE_POKEUSR: {
+ 		struct pt_regs *regs;
+ 		ret = 0;
+@@ -231,6 +324,22 @@ asmlinkage int sys32_ptrace(int request,
+ 			else
+ 				child->thread.fpu.soft.fcr31 = data;
+ 			break;
++		case DSP_BASE ... DSP_BASE + 5:
++			if (!cpu_has_dsp) {
++				ret = -EIO;
++				break;
++			}
++
++			dspreg_t *dregs = __get_dsp_regs(child);
++			dregs[addr - DSP_BASE] = data;
++			break;
++		case DSP_CONTROL:
++			if (!cpu_has_dsp) {
++				ret = -EIO;
++				break;
++			}
++			child->thread.dsp.dspcontrol = data;
++			break;
+ 		default:
+ 			/* The rest are not allowed. */
+ 			ret = -EIO;
+@@ -239,6 +348,22 @@ asmlinkage int sys32_ptrace(int request,
+ 		break;
+ 		}
+ 
++	case PTRACE_GETREGS:
++		ret = ptrace_getregs (child, (__u64 __user *) (__u64) data);
++		break;
++
++	case PTRACE_SETREGS:
++		ret = ptrace_setregs (child, (__u64 __user *) (__u64) data);
++		break;
++
++	case PTRACE_GETFPREGS:
++		ret = ptrace_getfpregs (child, (__u32 __user *) (__u64) data);
++		break;
++
++	case PTRACE_SETFPREGS:
++		ret = ptrace_setfpregs (child, (__u32 __user *) (__u64) data);
++		break;
++
+ 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+ 	case PTRACE_CONT: { /* restart after signal. */
+ 		ret = -EIO;
+@@ -269,10 +394,25 @@ asmlinkage int sys32_ptrace(int request,
+ 		wake_up_process(child);
+ 		break;
+ 
++	case PTRACE_GET_THREAD_AREA:
++		ret = put_user(child->thread_info->tp_value,
++				(unsigned int __user *) (unsigned long) data);
++		break;
++
+ 	case PTRACE_DETACH: /* detach a process that was attached. */
+ 		ret = ptrace_detach(child, data);
+ 		break;
+ 
++	case PTRACE_GETEVENTMSG:
++		ret = put_user(child->ptrace_message,
++			       (unsigned int __user *) (unsigned long) data);
++		break;
++
++	case PTRACE_GET_THREAD_AREA_3264:
++		ret = put_user(child->thread_info->tp_value,
++				(unsigned long __user *) (unsigned long) data);
++		break;
++
+ 	default:
+ 		ret = ptrace_request(child, request, addr, data);
+ 		break;
+diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
+--- a/arch/mips/kernel/r4k_fpu.S
++++ b/arch/mips/kernel/r4k_fpu.S
+@@ -32,7 +32,7 @@
+ 
+ 	.set	noreorder
+ 	.set	mips3
+-	/* Save floating point context */
++
+ LEAF(_save_fp_context)
+ 	cfc1	t1, fcr31
+ 
+@@ -74,9 +74,6 @@ LEAF(_save_fp_context)
+ 	EX	sdc1 $f28, SC_FPREGS+224(a0)
+ 	EX	sdc1 $f30, SC_FPREGS+240(a0)
+ 	EX	sw t1, SC_FPC_CSR(a0)
+-	cfc1	t0, $0				# implementation/version
+-	EX	sw t0, SC_FPC_EIR(a0)
+-
+ 	jr	ra
+ 	 li	v0, 0					# success
+ 	END(_save_fp_context)
+diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/kernel/rtlx.c
+@@ -0,0 +1,341 @@
++/*
++ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/fs.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <linux/slab.h>
++#include <linux/list.h>
++#include <linux/vmalloc.h>
++#include <linux/elf.h>
++#include <linux/seq_file.h>
++#include <linux/syscalls.h>
++#include <linux/moduleloader.h>
++#include <linux/interrupt.h>
++#include <linux/poll.h>
++#include <linux/sched.h>
++#include <linux/wait.h>
++#include <asm/mipsmtregs.h>
++#include <asm/cacheflush.h>
++#include <asm/atomic.h>
++#include <asm/cpu.h>
++#include <asm/processor.h>
++#include <asm/system.h>
++#include <asm/rtlx.h>
++
++#define RTLX_MAJOR 64
++#define RTLX_TARG_VPE 1
++
++struct rtlx_info *rtlx;
++static int major;
++static char module_name[] = "rtlx";
++static inline int spacefree(int read, int write, int size);
++
++static struct chan_waitqueues {
++	wait_queue_head_t rt_queue;
++	wait_queue_head_t lx_queue;
++} channel_wqs[RTLX_CHANNELS];
++
++static struct irqaction irq;
++static int irq_num;
++
++extern void *vpe_get_shared(int index);
++
++static void rtlx_dispatch(struct pt_regs *regs)
++{
++	do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs);
++}
++
++irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	irqreturn_t r = IRQ_HANDLED;
++	int i;
++
++	for (i = 0; i < RTLX_CHANNELS; i++) {
++		struct rtlx_channel *chan = &rtlx->channel[i];
++
++		if (chan->lx_read != chan->lx_write)
++			wake_up_interruptible(&channel_wqs[i].lx_queue);
++	}
++
++	return r;
++}
++
++void dump_rtlx(void)
++{
++	int i;
++
++	printk("id 0x%lx state %d\n", rtlx->id, rtlx->state);
++
++	for (i = 0; i < RTLX_CHANNELS; i++) {
++		struct rtlx_channel *chan = &rtlx->channel[i];
++
++		printk(" rt_state %d lx_state %d buffer_size %d\n",
++		       chan->rt_state, chan->lx_state, chan->buffer_size);
++
++		printk(" rt_read %d rt_write %d\n",
++		       chan->rt_read, chan->rt_write);
++
++		printk(" lx_read %d lx_write %d\n",
++		       chan->lx_read, chan->lx_write);
++
++		printk(" rt_buffer <%s>\n", chan->rt_buffer);
++		printk(" lx_buffer <%s>\n", chan->lx_buffer);
++	}
++}
++
++/* call when we have the address of the shared structure from the SP side. */
++static int rtlx_init(struct rtlx_info *rtlxi)
++{
++	int i;
++
++	if (rtlxi->id != RTLX_ID) {
++		printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi);
++		return (-ENOEXEC);
++	}
++
++	/* initialise the wait queues */
++	for (i = 0; i < RTLX_CHANNELS; i++) {
++		init_waitqueue_head(&channel_wqs[i].rt_queue);
++		init_waitqueue_head(&channel_wqs[i].lx_queue);
++	}
++
++	/* set up for interrupt handling */
++	memset(&irq, 0, sizeof(struct irqaction));
++
++	if (cpu_has_vint) {
++		set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
++	}
++
++	irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ;
++	irq.handler = rtlx_interrupt;
++	irq.flags = SA_INTERRUPT;
++	irq.name = "RTLX";
++	irq.dev_id = rtlx;
++	setup_irq(irq_num, &irq);
++
++	rtlx = rtlxi;
++	return (0);
++}
++
++/* only allow one open process at a time to open each channel */
++static int rtlx_open(struct inode *inode, struct file *filp)
++{
++	int minor, ret;
++	struct rtlx_channel *chan;
++
++	/* assume only 1 device at the mo. */
++	minor = MINOR(inode->i_rdev);
++
++	if (rtlx == NULL) {
++		struct rtlx_info **p;
++		if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
++			printk(" vpe_get_shared is NULL. Has an SP program been loaded?\n");
++			return (-EFAULT);
++		}
++
++		if (*p == NULL) {
++			printk(" vpe_shared %p %p\n", p, *p);
++			return (-EFAULT);
++		}
++
++		if ((ret = rtlx_init(*p)) < 0)
++			return (ret);
++	}
++
++	chan = &rtlx->channel[minor];
++
++	/* already open? */
++	if (chan->lx_state == RTLX_STATE_OPENED)
++		return (-EBUSY);
++
++	chan->lx_state = RTLX_STATE_OPENED;
++	return (0);
++}
++
++static int rtlx_release(struct inode *inode, struct file *filp)
++{
++	int minor;
++
++	minor = MINOR(inode->i_rdev);
++	rtlx->channel[minor].lx_state = RTLX_STATE_UNUSED;
++	return (0);
++}
++
++static unsigned int rtlx_poll(struct file *file, poll_table * wait)
++{
++	int minor;
++	unsigned int mask = 0;
++	struct rtlx_channel *chan;
++
++	minor = MINOR(file->f_dentry->d_inode->i_rdev);
++	chan = &rtlx->channel[minor];
++
++	poll_wait(file, &channel_wqs[minor].rt_queue, wait);
++	poll_wait(file, &channel_wqs[minor].lx_queue, wait);
++
++	/* data available to read? */
++	if (chan->lx_read != chan->lx_write)
++		mask |= POLLIN | POLLRDNORM;
++
++	/* space to write */
++	if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size))
++		mask |= POLLOUT | POLLWRNORM;
++
++	return (mask);
++}
++
++static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count,
++			 loff_t * ppos)
++{
++	size_t fl = 0L;
++	int minor;
++	struct rtlx_channel *lx;
++	DECLARE_WAITQUEUE(wait, current);
++
++	minor = MINOR(file->f_dentry->d_inode->i_rdev);
++	lx = &rtlx->channel[minor];
++
++	/* data available? */
++	if (lx->lx_write == lx->lx_read) {
++		if (file->f_flags & O_NONBLOCK)
++			return (0);	// -EAGAIN makes cat whinge
++
++		/* go to sleep */
++		add_wait_queue(&channel_wqs[minor].lx_queue, &wait);
++		set_current_state(TASK_INTERRUPTIBLE);
++
++		while (lx->lx_write == lx->lx_read)
++			schedule();
++
++		set_current_state(TASK_RUNNING);
++		remove_wait_queue(&channel_wqs[minor].lx_queue, &wait);
++
++		/* back running */
++	}
++
++	/* find out how much in total */
++	count = min( count,
++		     (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size);
++
++	/* then how much from the read pointer onwards */
++	fl = min( count, (size_t)lx->buffer_size - lx->lx_read);
++
++	copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl);
++
++	/* and if there is anything left at the beginning of the buffer */
++	if ( count - fl )
++		copy_to_user (buffer + fl, lx->lx_buffer, count - fl);
++
++	/* update the index */
++	lx->lx_read += count;
++	lx->lx_read %= lx->buffer_size;
++
++	return (count);
++}
++
++static inline int spacefree(int read, int write, int size)
++{
++	if (read == write) {
++		/* never fill the buffer completely, so indexes are always equal if empty
++		   and only empty, or !equal if data available */
++		return (size - 1);
++	}
++
++	return ((read + size - write) % size) - 1;
++}
++
++static ssize_t rtlx_write(struct file *file, const char __user * buffer,
++			  size_t count, loff_t * ppos)
++{
++	int minor;
++	struct rtlx_channel *rt;
++	size_t fl;
++	DECLARE_WAITQUEUE(wait, current);
++
++	minor = MINOR(file->f_dentry->d_inode->i_rdev);
++	rt = &rtlx->channel[minor];
++
++	/* any space left... */
++	if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) {
++
++		if (file->f_flags & O_NONBLOCK)
++			return (-EAGAIN);
++
++		add_wait_queue(&channel_wqs[minor].rt_queue, &wait);
++		set_current_state(TASK_INTERRUPTIBLE);
++
++		while (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size))
++			schedule();
++
++		set_current_state(TASK_RUNNING);
++		remove_wait_queue(&channel_wqs[minor].rt_queue, &wait);
++	}
++
++	/* total number of bytes to copy */
++	count = min( count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) );
++
++	/* first bit from write pointer to the end of the buffer, or count */
++	fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
++
++	copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl);
++
++	/* if there's any left copy to the beginning of the buffer */
++	if( count - fl )
++		copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
++
++	rt->rt_write += count;
++	rt->rt_write %= rt->buffer_size;
++
++	return(count);
++}
++
++static struct file_operations rtlx_fops = {
++	.owner = THIS_MODULE,
++	.open = rtlx_open,
++	.release = rtlx_release,
++	.write = rtlx_write,
++	.read = rtlx_read,
++	.poll = rtlx_poll
++};
++
++static int rtlx_module_init(void)
++{
++	if ((major = register_chrdev(RTLX_MAJOR, module_name, &rtlx_fops)) < 0) {
++		printk("rtlx_module_init: unable to register device\n");
++		return (-EBUSY);
++	}
++
++	if (major == 0)
++		major = RTLX_MAJOR;
++
++	return (0);
++}
++
++static void rtlx_module_exit(void)
++{
++	unregister_chrdev(major, module_name);
++}
++
++module_init(rtlx_module_init);
++module_exit(rtlx_module_exit);
++MODULE_DESCRIPTION("MIPS RTLX");
++MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc");
++MODULE_LICENSE("GPL");
+diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
+--- a/arch/mips/kernel/scall32-o32.S
++++ b/arch/mips/kernel/scall32-o32.S
+@@ -578,7 +578,7 @@ einval:	li	v0, -EINVAL
+ 	sys	sys_fremovexattr	2	/* 4235 */
+ 	sys	sys_tkill		2
+ 	sys	sys_sendfile64		5
+-	sys	sys_futex		2
++	sys	sys_futex		6
+ 	sys	sys_sched_setaffinity	3
+ 	sys	sys_sched_getaffinity	3	/* 4240 */
+ 	sys	sys_io_setup		2
+@@ -587,7 +587,7 @@ einval:	li	v0, -EINVAL
+ 	sys	sys_io_submit		3
+ 	sys	sys_io_cancel		3	/* 4245 */
+ 	sys	sys_exit_group		1
+-	sys	sys_lookup_dcookie	3
++	sys	sys_lookup_dcookie	4
+ 	sys	sys_epoll_create	1
+ 	sys	sys_epoll_ctl		4
+ 	sys	sys_epoll_wait		3	/* 4250 */
+@@ -618,12 +618,15 @@ einval:	li	v0, -EINVAL
+ 	sys	sys_mq_notify		2	/* 4275 */
+ 	sys	sys_mq_getsetattr	3
+ 	sys	sys_ni_syscall		0	/* sys_vserver */
+-	sys	sys_waitid		4
++	sys	sys_waitid		5
+ 	sys	sys_ni_syscall		0	/* available, was setaltroot */
+-	sys	sys_add_key		5
++	sys	sys_add_key		5	/* 4280 */
+ 	sys	sys_request_key		4
+ 	sys	sys_keyctl		5
+-
++	sys	sys_set_thread_area	1
++	sys	sys_inotify_init	0
++	sys	sys_inotify_add_watch	3	/* 4285 */
++	sys	sys_inotify_rm_watch	2
+ 	.endm
+ 
+ 	/* We pre-compute the number of _instruction_ bytes needed to
+diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
+--- a/arch/mips/kernel/scall64-64.S
++++ b/arch/mips/kernel/scall64-64.S
+@@ -449,3 +449,7 @@ sys_call_table:
+ 	PTR	sys_add_key
+ 	PTR	sys_request_key			/* 5240 */
+ 	PTR	sys_keyctl
++	PTR	sys_set_thread_area
++	PTR	sys_inotify_init
++	PTR	sys_inotify_add_watch
++	PTR	sys_inotify_rm_watch		/* 5245 */
+diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
+--- a/arch/mips/kernel/scall64-n32.S
++++ b/arch/mips/kernel/scall64-n32.S
+@@ -176,7 +176,7 @@ EXPORT(sysn32_call_table)
+ 	PTR	sys_fork
+ 	PTR	sys32_execve
+ 	PTR	sys_exit
+-	PTR	sys32_wait4
++	PTR	compat_sys_wait4
+ 	PTR	sys_kill			/* 6060 */
+ 	PTR	sys32_newuname
+ 	PTR	sys_semget
+@@ -216,7 +216,7 @@ EXPORT(sysn32_call_table)
+ 	PTR	compat_sys_getrusage
+ 	PTR	sys32_sysinfo
+ 	PTR	compat_sys_times
+-	PTR	sys_ptrace
++	PTR	sys32_ptrace
+ 	PTR	sys_getuid			/* 6100 */
+ 	PTR	sys_syslog
+ 	PTR	sys_getgid
+@@ -243,14 +243,14 @@ EXPORT(sysn32_call_table)
+ 	PTR	sys_capget
+ 	PTR	sys_capset
+ 	PTR	sys32_rt_sigpending		/* 6125 */
+-	PTR	compat_sys_rt_sigtimedwait
+-	PTR	sys32_rt_sigqueueinfo
++	PTR	sysn32_rt_sigtimedwait
++	PTR	sys_rt_sigqueueinfo
+ 	PTR	sys32_rt_sigsuspend
+ 	PTR	sys32_sigaltstack
+ 	PTR	compat_sys_utime		/* 6130 */
+ 	PTR	sys_mknod
+ 	PTR	sys32_personality
+-	PTR	sys_ustat
++	PTR	sys32_ustat
+ 	PTR	compat_sys_statfs
+ 	PTR	compat_sys_fstatfs		/* 6135 */
+ 	PTR	sys_sysfs
+@@ -329,7 +329,7 @@ EXPORT(sysn32_call_table)
+ 	PTR	sys_epoll_wait
+ 	PTR	sys_remap_file_pages		/* 6210 */
+ 	PTR	sysn32_rt_sigreturn
+-	PTR	sys_fcntl
++	PTR	compat_sys_fcntl64
+ 	PTR	sys_set_tid_address
+ 	PTR	sys_restart_syscall
+ 	PTR	sys_semtimedop			/* 6215 */
+@@ -337,15 +337,15 @@ EXPORT(sysn32_call_table)
+ 	PTR	compat_sys_statfs64
+ 	PTR	compat_sys_fstatfs64
+ 	PTR	sys_sendfile64
+-	PTR	sys_timer_create		/* 6220 */
+-	PTR	sys_timer_settime
+-	PTR	sys_timer_gettime
++	PTR	sys32_timer_create		/* 6220 */
++	PTR	compat_sys_timer_settime
++	PTR	compat_sys_timer_gettime
+ 	PTR	sys_timer_getoverrun
+ 	PTR	sys_timer_delete
+-	PTR	sys_clock_settime		/* 6225 */
+-	PTR	sys_clock_gettime
+-	PTR	sys_clock_getres
+-	PTR	sys_clock_nanosleep
++	PTR	compat_sys_clock_settime		/* 6225 */
++	PTR	compat_sys_clock_gettime
++	PTR	compat_sys_clock_getres
++	PTR	compat_sys_clock_nanosleep
+ 	PTR	sys_tgkill
+ 	PTR	compat_sys_utimes		/* 6230 */
+ 	PTR	sys_ni_syscall			/* sys_mbind */
+@@ -358,8 +358,12 @@ EXPORT(sysn32_call_table)
+ 	PTR	compat_sys_mq_notify
+ 	PTR	compat_sys_mq_getsetattr
+ 	PTR	sys_ni_syscall			/* 6240, sys_vserver */
+-	PTR	sys_waitid
++	PTR	sysn32_waitid
+ 	PTR	sys_ni_syscall			/* available, was setaltroot */
+ 	PTR	sys_add_key
+ 	PTR	sys_request_key
+ 	PTR	sys_keyctl			/* 6245 */
++	PTR	sys_set_thread_area
++	PTR	sys_inotify_init
++	PTR	sys_inotify_add_watch
++	PTR	sys_inotify_rm_watch
+diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
+--- a/arch/mips/kernel/scall64-o32.S
++++ b/arch/mips/kernel/scall64-o32.S
+@@ -316,13 +316,13 @@ sys_call_table:
+ 	PTR	sys_vhangup
+ 	PTR	sys_ni_syscall			/* was sys_idle	 */
+ 	PTR	sys_ni_syscall			/* sys_vm86 */
+-	PTR	sys32_wait4
++	PTR	compat_sys_wait4
+ 	PTR	sys_swapoff			/* 4115 */
+ 	PTR	sys32_sysinfo
+ 	PTR	sys32_ipc
+ 	PTR	sys_fsync
+ 	PTR	sys32_sigreturn
+-	PTR	sys_clone			/* 4120 */
++	PTR	sys32_clone			/* 4120 */
+ 	PTR	sys_setdomainname
+ 	PTR	sys32_newuname
+ 	PTR	sys_ni_syscall			/* sys_modify_ldt */
+@@ -391,7 +391,7 @@ sys_call_table:
+ 	PTR	sys_getresuid
+ 	PTR	sys_ni_syscall			/* was query_module */
+ 	PTR	sys_poll
+-	PTR	sys_nfsservctl
++	PTR	compat_sys_nfsservctl
+ 	PTR	sys_setresgid			/* 4190 */
+ 	PTR	sys_getresgid
+ 	PTR	sys_prctl
+@@ -459,7 +459,7 @@ sys_call_table:
+ 	PTR	sys_fadvise64_64
+ 	PTR	compat_sys_statfs64		/* 4255 */
+ 	PTR	compat_sys_fstatfs64
+-	PTR	sys_timer_create
++	PTR	sys32_timer_create
+ 	PTR	compat_sys_timer_settime
+ 	PTR	compat_sys_timer_gettime
+ 	PTR	sys_timer_getoverrun		/* 4260 */
+@@ -480,9 +480,13 @@ sys_call_table:
+ 	PTR	compat_sys_mq_notify		/* 4275 */
+ 	PTR	compat_sys_mq_getsetattr
+ 	PTR	sys_ni_syscall			/* sys_vserver */
+-	PTR	sys_waitid
++	PTR	sys32_waitid
+ 	PTR	sys_ni_syscall			/* available, was setaltroot */
+ 	PTR	sys_add_key			/* 4280 */
+ 	PTR	sys_request_key
+ 	PTR	sys_keyctl
++	PTR	sys_set_thread_area
++	PTR	sys_inotify_init
++	PTR	sys_inotify_add_watch		/* 4285 */
++	PTR	sys_inotify_rm_watch
+ 	.size	sys_call_table,.-sys_call_table
+diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c
+--- a/arch/mips/kernel/semaphore.c
++++ b/arch/mips/kernel/semaphore.c
+@@ -42,24 +42,28 @@ static inline int __sem_update_count(str
+ 
+ 	if (cpu_has_llsc && R10000_LLSC_WAR) {
+ 		__asm__ __volatile__(
+-		"1:	ll	%0, %2					\n"
++		"	.set	mips3					\n"
++		"1:	ll	%0, %2		# __sem_update_count	\n"
+ 		"	sra	%1, %0, 31				\n"
+ 		"	not	%1					\n"
+ 		"	and	%1, %0, %1				\n"
+-		"	add	%1, %1, %3				\n"
++		"	addu	%1, %1, %3				\n"
+ 		"	sc	%1, %2					\n"
+ 		"	beqzl	%1, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
+ 		: "r" (incr), "m" (sem->count));
+ 	} else if (cpu_has_llsc) {
+ 		__asm__ __volatile__(
+-		"1:	ll	%0, %2					\n"
++		"	.set	mips3					\n"
++		"1:	ll	%0, %2		# __sem_update_count	\n"
+ 		"	sra	%1, %0, 31				\n"
+ 		"	not	%1					\n"
+ 		"	and	%1, %0, %1				\n"
+-		"	add	%1, %1, %3				\n"
++		"	addu	%1, %1, %3				\n"
+ 		"	sc	%1, %2					\n"
+ 		"	beqz	%1, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
+ 		: "r" (incr), "m" (sem->count));
+ 	} else {
+diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -37,12 +37,13 @@
+ 
+ #include <asm/addrspace.h>
+ #include <asm/bootinfo.h>
++#include <asm/cache.h>
+ #include <asm/cpu.h>
+ #include <asm/sections.h>
+ #include <asm/setup.h>
+ #include <asm/system.h>
+ 
+-struct cpuinfo_mips cpu_data[NR_CPUS];
++struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
+ 
+ EXPORT_SYMBOL(cpu_data);
+ 
+@@ -62,8 +63,8 @@ EXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS);
+  *
+  * These are initialized so they are in the .data section
+  */
+-unsigned long mips_machtype = MACH_UNKNOWN;
+-unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
++unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
++unsigned long mips_machgroup __read_mostly = MACH_GROUP_UNKNOWN;
+ 
+ EXPORT_SYMBOL(mips_machtype);
+ EXPORT_SYMBOL(mips_machgroup);
+@@ -77,7 +78,7 @@ static char command_line[CL_SIZE];
+  * mips_io_port_base is the begin of the address space to which x86 style
+  * I/O ports are mapped.
+  */
+-const unsigned long mips_io_port_base = -1;
++const unsigned long mips_io_port_base __read_mostly = -1;
+ EXPORT_SYMBOL(mips_io_port_base);
+ 
+ /*
+@@ -510,31 +511,7 @@ static inline void resource_init(void)
+ #undef MAXMEM
+ #undef MAXMEM_PFN
+ 
+-static int __initdata earlyinit_debug;
+-
+-static int __init earlyinit_debug_setup(char *str)
+-{
+-	earlyinit_debug = 1;
+-	return 1;
+-}
+-__setup("earlyinit_debug", earlyinit_debug_setup);
+-
+-extern initcall_t __earlyinitcall_start, __earlyinitcall_end;
+-
+-static void __init do_earlyinitcalls(void)
+-{
+-	initcall_t *call, *start, *end;
+-
+-	start = &__earlyinitcall_start;
+-	end = &__earlyinitcall_end;
+-
+-	for (call = start; call < end; call++) {
+-		if (earlyinit_debug)
+-			printk("calling earlyinitcall 0x%p\n", *call);
+-
+-		(*call)();
+-	}
+-}
++extern void plat_setup(void);
+ 
+ void __init setup_arch(char **cmdline_p)
+ {
+@@ -551,7 +528,7 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+ 
+ 	/* call board setup routine */
+-	do_earlyinitcalls();
++	plat_setup();
+ 
+ 	strlcpy(command_line, arcs_cmdline, sizeof(command_line));
+ 	strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+@@ -573,3 +550,12 @@ int __init fpu_disable(char *s)
+ }
+ 
+ __setup("nofpu", fpu_disable);
++
++int __init dsp_disable(char *s)
++{
++	cpu_data[0].ases &= ~MIPS_ASE_DSP;
++
++	return 1;
++}
++
++__setup("nodsp", dsp_disable);
+diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
+--- a/arch/mips/kernel/signal-common.h
++++ b/arch/mips/kernel/signal-common.h
+@@ -8,13 +8,14 @@
+  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+  */
+ 
++#include <linux/config.h>
++
+ static inline int
+ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+ {
+ 	int err = 0;
+ 
+ 	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+-	err |= __put_user(regs->cp0_status, &sc->sc_status);
+ 
+ #define save_gp_reg(i) do {						\
+ 	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
+@@ -30,10 +31,32 @@ setup_sigcontext(struct pt_regs *regs, s
+ 	save_gp_reg(31);
+ #undef save_gp_reg
+ 
++#ifdef CONFIG_32BIT
+ 	err |= __put_user(regs->hi, &sc->sc_mdhi);
+ 	err |= __put_user(regs->lo, &sc->sc_mdlo);
+-	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+-	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
++	if (cpu_has_dsp) {
++		err |= __put_user(mfhi1(), &sc->sc_hi1);
++		err |= __put_user(mflo1(), &sc->sc_lo1);
++		err |= __put_user(mfhi2(), &sc->sc_hi2);
++		err |= __put_user(mflo2(), &sc->sc_lo2);
++		err |= __put_user(mfhi3(), &sc->sc_hi3);
++		err |= __put_user(mflo3(), &sc->sc_lo3);
++		err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
++	}
++#endif
++#ifdef CONFIG_64BIT
++	err |= __put_user(regs->hi, &sc->sc_hi[0]);
++	err |= __put_user(regs->lo, &sc->sc_lo[0]);
++	if (cpu_has_dsp) {
++		err |= __put_user(mfhi1(), &sc->sc_hi[1]);
++		err |= __put_user(mflo1(), &sc->sc_lo[1]);
++		err |= __put_user(mfhi2(), &sc->sc_hi[2]);
++		err |= __put_user(mflo2(), &sc->sc_lo[2]);
++		err |= __put_user(mfhi3(), &sc->sc_hi[3]);
++		err |= __put_user(mflo3(), &sc->sc_lo[3]);
++		err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
++	}
++#endif
+ 
+ 	err |= __put_user(!!used_math(), &sc->sc_used_math);
+ 
+@@ -61,15 +84,40 @@ out:
+ static inline int
+ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+ {
+-	int err = 0;
+ 	unsigned int used_math;
++	unsigned long treg;
++	int err = 0;
+ 
+ 	/* Always make any pending restarted system calls return -EINTR */
+ 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+ 
+ 	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
++#ifdef CONFIG_32BIT
+ 	err |= __get_user(regs->hi, &sc->sc_mdhi);
+ 	err |= __get_user(regs->lo, &sc->sc_mdlo);
++	if (cpu_has_dsp) {
++		err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
++		err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
++		err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
++		err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
++		err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
++		err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
++		err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
++	}
++#endif
++#ifdef CONFIG_64BIT
++	err |= __get_user(regs->hi, &sc->sc_hi[0]);
++	err |= __get_user(regs->lo, &sc->sc_lo[0]);
++	if (cpu_has_dsp) {
++		err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
++		err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
++		err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
++		err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
++		err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
++		err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
++		err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
++	}
++#endif
+ 
+ #define restore_gp_reg(i) do {						\
+ 	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
+@@ -112,7 +160,7 @@ restore_sigcontext(struct pt_regs *regs,
+ static inline void *
+ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+ {
+-	unsigned long sp, almask;
++	unsigned long sp;
+ 
+ 	/* Default to using normal stack */
+ 	sp = regs->regs[29];
+@@ -128,10 +176,32 @@ get_sigframe(struct k_sigaction *ka, str
+ 	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
+ 		sp = current->sas_ss_sp + current->sas_ss_size;
+ 
+-	if (PLAT_TRAMPOLINE_STUFF_LINE)
+-		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
+-	else
+-		almask = ALMASK;
++	return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
++}
++
++static inline int install_sigtramp(unsigned int __user *tramp,
++	unsigned int syscall)
++{
++	int err;
++
++	/*
++	 * Set up the return code ...
++	 *
++	 *         li      v0, __NR__foo_sigreturn
++	 *         syscall
++	 */
++
++	err = __put_user(0x24020000 + syscall, tramp + 0);
++	err |= __put_user(0x0000000c          , tramp + 1);
++	if (ICACHE_REFILLS_WORKAROUND_WAR) {
++		err |= __put_user(0, tramp + 2);
++		err |= __put_user(0, tramp + 3);
++		err |= __put_user(0, tramp + 4);
++		err |= __put_user(0, tramp + 5);
++		err |= __put_user(0, tramp + 6);
++		err |= __put_user(0, tramp + 7);
++	}
++	flush_cache_sigtramp((unsigned long) tramp);
+ 
+-	return (void *)((sp - frame_size) & almask);
++	return err;
+ }
+diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
+--- a/arch/mips/kernel/signal.c
++++ b/arch/mips/kernel/signal.c
+@@ -8,6 +8,7 @@
+  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+  */
+ #include <linux/config.h>
++#include <linux/cache.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+ #include <linux/personality.h>
+@@ -21,6 +22,7 @@
+ #include <linux/unistd.h>
+ #include <linux/compiler.h>
+ 
++#include <asm/abi.h>
+ #include <asm/asm.h>
+ #include <linux/bitops.h>
+ #include <asm/cacheflush.h>
+@@ -29,6 +31,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/ucontext.h>
+ #include <asm/cpu-features.h>
++#include <asm/war.h>
+ 
+ #include "signal-common.h"
+ 
+@@ -36,7 +39,7 @@
+ 
+ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+ 
+-static int do_signal(sigset_t *oldset, struct pt_regs *regs);
++int do_signal(sigset_t *oldset, struct pt_regs *regs);
+ 
+ /*
+  * Atomically swap in the new signal mask, and wait for a signal.
+@@ -47,9 +50,10 @@ save_static_function(sys_sigsuspend);
+ __attribute_used__ noinline static int
+ _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
+ {
+-	sigset_t *uset, saveset, newset;
++	sigset_t saveset, newset;
++	sigset_t __user *uset;
+ 
+-	uset = (sigset_t *) regs.regs[4];
++	uset = (sigset_t __user *) regs.regs[4];
+ 	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
+ 		return -EFAULT;
+ 	sigdelsetmask(&newset, ~_BLOCKABLE);
+@@ -75,7 +79,8 @@ save_static_function(sys_rt_sigsuspend);
+ __attribute_used__ noinline static int
+ _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
+ {
+-	sigset_t *unewset, saveset, newset;
++	sigset_t saveset, newset;
++	sigset_t __user *unewset;
+ 	size_t sigsetsize;
+ 
+ 	/* XXX Don't preclude handling different sized sigset_t's.  */
+@@ -83,7 +88,7 @@ _sys_rt_sigsuspend(nabi_no_regargs struc
+ 	if (sigsetsize != sizeof(sigset_t))
+ 		return -EINVAL;
+ 
+-	unewset = (sigset_t *) regs.regs[4];
++	unewset = (sigset_t __user *) regs.regs[4];
+ 	if (copy_from_user(&newset, unewset, sizeof(newset)))
+ 		return -EFAULT;
+ 	sigdelsetmask(&newset, ~_BLOCKABLE);
+@@ -147,33 +152,46 @@ asmlinkage int sys_sigaction(int sig, co
+ 
+ asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
+ {
+-	const stack_t *uss = (const stack_t *) regs.regs[4];
+-	stack_t *uoss = (stack_t *) regs.regs[5];
++	const stack_t __user *uss = (const stack_t __user *) regs.regs[4];
++	stack_t __user *uoss = (stack_t __user *) regs.regs[5];
+ 	unsigned long usp = regs.regs[29];
+ 
+ 	return do_sigaltstack(uss, uoss, usp);
+ }
+ 
+-#if PLAT_TRAMPOLINE_STUFF_LINE
+-#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
+-#else
+-#define __tramp
+-#endif
+-
++/*
++ * Horribly complicated - with the bloody RM9000 workarounds enabled
++ * the signal trampolines is moving to the end of the structure so we can
++ * increase the alignment without breaking software compatibility.
++ */
+ #ifdef CONFIG_TRAD_SIGNALS
+ struct sigframe {
+ 	u32 sf_ass[4];			/* argument save space for o32 */
+-	u32 sf_code[2] __tramp;		/* signal trampoline */
+-	struct sigcontext sf_sc __tramp;
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 sf_pad[2];
++#else
++	u32 sf_code[2];			/* signal trampoline */
++#endif
++	struct sigcontext sf_sc;
+ 	sigset_t sf_mask;
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
++#endif
+ };
+ #endif
+ 
+ struct rt_sigframe {
+ 	u32 rs_ass[4];			/* argument save space for o32 */
+-	u32 rs_code[2] __tramp;		/* signal trampoline */
+-	struct siginfo rs_info __tramp;
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 rs_pad[2];
++#else
++	u32 rs_code[2];			/* signal trampoline */
++#endif
++	struct siginfo rs_info;
+ 	struct ucontext rs_uc;
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 rs_code[8] ____cacheline_aligned;	/* signal trampoline */
++#endif
+ };
+ 
+ #ifdef CONFIG_TRAD_SIGNALS
+@@ -214,7 +232,7 @@ _sys_sigreturn(nabi_no_regargs struct pt
+ badframe:
+ 	force_sig(SIGSEGV, current);
+ }
+-#endif
++#endif /* CONFIG_TRAD_SIGNALS */
+ 
+ save_static_function(sys_rt_sigreturn);
+ __attribute_used__ noinline static void
+@@ -260,7 +278,7 @@ badframe:
+ }
+ 
+ #ifdef CONFIG_TRAD_SIGNALS
+-static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
++int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ 	int signr, sigset_t *set)
+ {
+ 	struct sigframe *frame;
+@@ -270,17 +288,7 @@ static void inline setup_frame(struct k_
+ 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ 		goto give_sigsegv;
+ 
+-	/*
+-	 * Set up the return code ...
+-	 *
+-	 *         li      v0, __NR_sigreturn
+-	 *         syscall
+-	 */
+-	if (PLAT_TRAMPOLINE_STUFF_LINE)
+-		__clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);
+-	err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);
+-	err |= __put_user(0x0000000c                 , frame->sf_code + 1);
+-	flush_cache_sigtramp((unsigned long) frame->sf_code);
++	install_sigtramp(frame->sf_code, __NR_sigreturn);
+ 
+ 	err |= setup_sigcontext(regs, &frame->sf_sc);
+ 	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+@@ -309,14 +317,15 @@ static void inline setup_frame(struct k_
+ 	       current->comm, current->pid,
+ 	       frame, regs->cp0_epc, frame->regs[31]);
+ #endif
+-        return;
++        return 1;
+ 
+ give_sigsegv:
+ 	force_sigsegv(signr, current);
++	return 0;
+ }
+ #endif
+ 
+-static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
++int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ 	int signr, sigset_t *set, siginfo_t *info)
+ {
+ 	struct rt_sigframe *frame;
+@@ -326,17 +335,7 @@ static void inline setup_rt_frame(struct
+ 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ 		goto give_sigsegv;
+ 
+-	/*
+-	 * Set up the return code ...
+-	 *
+-	 *         li      v0, __NR_rt_sigreturn
+-	 *         syscall
+-	 */
+-	if (PLAT_TRAMPOLINE_STUFF_LINE)
+-		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
+-	err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
+-	err |= __put_user(0x0000000c                    , frame->rs_code + 1);
+-	flush_cache_sigtramp((unsigned long) frame->rs_code);
++	install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
+ 
+ 	/* Create siginfo.  */
+ 	err |= copy_siginfo_to_user(&frame->rs_info, info);
+@@ -378,18 +377,21 @@ static void inline setup_rt_frame(struct
+ 	       current->comm, current->pid,
+ 	       frame, regs->cp0_epc, regs->regs[31]);
+ #endif
+-	return;
++	return 1;
+ 
+ give_sigsegv:
+ 	force_sigsegv(signr, current);
++	return 0;
+ }
+ 
+ extern void setup_rt_frame_n32(struct k_sigaction * ka,
+ 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info);
+ 
+-static inline void handle_signal(unsigned long sig, siginfo_t *info,
++static inline int handle_signal(unsigned long sig, siginfo_t *info,
+ 	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
+ {
++	int ret;
++
+ 	switch(regs->regs[0]) {
+ 	case ERESTART_RESTARTBLOCK:
+ 	case ERESTARTNOHAND:
+@@ -408,22 +410,10 @@ static inline void handle_signal(unsigne
+ 
+ 	regs->regs[0] = 0;		/* Don't deal with this again.  */
+ 
+-#ifdef CONFIG_TRAD_SIGNALS
+-	if (ka->sa.sa_flags & SA_SIGINFO) {
+-#else
+-	if (1) {
+-#endif
+-#ifdef CONFIG_MIPS32_N32
+-		if ((current->thread.mflags & MF_ABI_MASK) == MF_N32)
+-			setup_rt_frame_n32 (ka, regs, sig, oldset, info);
+-		else
+-#endif
+-			setup_rt_frame(ka, regs, sig, oldset, info);
+-	}
+-#ifdef CONFIG_TRAD_SIGNALS
++	if (sig_uses_siginfo(ka))
++		ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
+ 	else
+-		setup_frame(ka, regs, sig, oldset);
+-#endif
++		ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
+ 
+ 	spin_lock_irq(&current->sighand->siglock);
+ 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+@@ -431,23 +421,16 @@ static inline void handle_signal(unsigne
+ 		sigaddset(&current->blocked,sig);
+ 	recalc_sigpending();
+ 	spin_unlock_irq(&current->sighand->siglock);
+-}
+ 
+-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+-extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
++	return ret;
++}
+ 
+-static int do_signal(sigset_t *oldset, struct pt_regs *regs)
++int do_signal(sigset_t *oldset, struct pt_regs *regs)
+ {
+ 	struct k_sigaction ka;
+ 	siginfo_t info;
+ 	int signr;
+ 
+-#ifdef CONFIG_BINFMT_ELF32
+-	if ((current->thread.mflags & MF_ABI_MASK) == MF_O32) {
+-		return do_signal32(oldset, regs);
+-	}
+-#endif
+-
+ 	/*
+ 	 * We want the common case to go fast, which is why we may in certain
+ 	 * cases get here from kernel mode. Just return without doing anything
+@@ -463,10 +446,8 @@ static int do_signal(sigset_t *oldset, s
+ 		oldset = &current->blocked;
+ 
+ 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+-	if (signr > 0) {
+-		handle_signal(signr, &info, &ka, oldset, regs);
+-		return 1;
+-	}
++	if (signr > 0)
++		return handle_signal(signr, &info, &ka, oldset, regs);
+ 
+ no_signal:
+ 	/*
+@@ -499,18 +480,6 @@ asmlinkage void do_notify_resume(struct 
+ {
+ 	/* deal with pending signal delivery */
+ 	if (thread_info_flags & _TIF_SIGPENDING) {
+-#ifdef CONFIG_BINFMT_ELF32
+-		if (likely((current->thread.mflags & MF_ABI_MASK) == MF_O32)) {
+-			do_signal32(oldset, regs);
+-			return;
+-		}
+-#endif
+-#ifdef CONFIG_BINFMT_IRIX
+-		if (unlikely(current->personality != PER_LINUX)) {
+-			do_irix_signal(oldset, regs);
+-			return;
+-		}
+-#endif
+-		do_signal(oldset, regs);
++		current->thread.abi->do_signal(oldset, regs);
+ 	}
+ }
+diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
+--- a/arch/mips/kernel/signal32.c
++++ b/arch/mips/kernel/signal32.c
+@@ -7,6 +7,7 @@
+  * Copyright (C) 1994 - 2000  Ralf Baechle
+  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+  */
++#include <linux/cache.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+ #include <linux/smp.h>
+@@ -21,6 +22,7 @@
+ #include <linux/suspend.h>
+ #include <linux/compiler.h>
+ 
++#include <asm/abi.h>
+ #include <asm/asm.h>
+ #include <linux/bitops.h>
+ #include <asm/cacheflush.h>
+@@ -29,6 +31,7 @@
+ #include <asm/ucontext.h>
+ #include <asm/system.h>
+ #include <asm/fpu.h>
++#include <asm/war.h>
+ 
+ #define SI_PAD_SIZE32   ((SI_MAX_SIZE/sizeof(int)) - 3)
+ 
+@@ -76,8 +79,10 @@ typedef struct compat_siginfo {
+ 
+ 		/* POSIX.1b timers */
+ 		struct {
+-			unsigned int _timer1;
+-			unsigned int _timer2;
++			timer_t _tid;		/* timer id */
++			int _overrun;		/* overrun count */
++			compat_sigval_t _sigval;/* same as below */
++			int _sys_private;       /* not to be passed to user */
+ 		} _timer;
+ 
+ 		/* POSIX.1b signals */
+@@ -259,11 +264,12 @@ asmlinkage int sys32_sigaction(int sig, 
+ 
+ 	if (act) {
+ 		old_sigset_t mask;
++		s32 handler;
+ 
+ 		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+ 			return -EFAULT;
+-		err |= __get_user((u32)(u64)new_ka.sa.sa_handler,
+-		                  &act->sa_handler);
++		err |= __get_user(handler, &act->sa_handler);
++		new_ka.sa.sa_handler = (void*)(s64)handler;
+ 		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ 		err |= __get_user(mask, &act->sa_mask.sig[0]);
+ 		if (err)
+@@ -331,8 +337,9 @@ asmlinkage int sys32_sigaltstack(nabi_no
+ 
+ static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
+ {
++	u32 used_math;
+ 	int err = 0;
+-	__u32 used_math;
++	s32 treg;
+ 
+ 	/* Always make any pending restarted system calls return -EINTR */
+ 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+@@ -340,6 +347,15 @@ static int restore_sigcontext32(struct p
+ 	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+ 	err |= __get_user(regs->hi, &sc->sc_mdhi);
+ 	err |= __get_user(regs->lo, &sc->sc_mdlo);
++	if (cpu_has_dsp) {
++		err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
++		err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
++		err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
++		err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
++		err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
++		err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
++		err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
++	}
+ 
+ #define restore_gp_reg(i) do {						\
+ 	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
+@@ -378,16 +394,30 @@ static int restore_sigcontext32(struct p
+ 
+ struct sigframe {
+ 	u32 sf_ass[4];			/* argument save space for o32 */
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 sf_pad[2];
++#else
+ 	u32 sf_code[2];			/* signal trampoline */
++#endif
+ 	struct sigcontext32 sf_sc;
+ 	sigset_t sf_mask;
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
++#endif
+ };
+ 
+ struct rt_sigframe32 {
+ 	u32 rs_ass[4];			/* argument save space for o32 */
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 rs_pad[2];
++#else
+ 	u32 rs_code[2];			/* signal trampoline */
++#endif
+ 	compat_siginfo_t rs_info;
+ 	struct ucontext32 rs_uc;
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 rs_code[8] __attribute__((aligned(32)));	/* signal trampoline */
++#endif
+ };
+ 
+ int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
+@@ -411,6 +441,11 @@ int copy_siginfo_to_user32(compat_siginf
+ 		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
+ 	else {
+ 		switch (from->si_code >> 16) {
++		case __SI_TIMER >> 16:
++			err |= __put_user(from->si_tid, &to->si_tid);
++			err |= __put_user(from->si_overrun, &to->si_overrun);
++			err |= __put_user(from->si_int, &to->si_int);
++			break;
+ 		case __SI_CHLD >> 16:
+ 			err |= __put_user(from->si_utime, &to->si_utime);
+ 			err |= __put_user(from->si_stime, &to->si_stime);
+@@ -480,6 +515,7 @@ __attribute_used__ noinline static void
+ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+ {
+ 	struct rt_sigframe32 *frame;
++	mm_segment_t old_fs;
+ 	sigset_t set;
+ 	stack_t st;
+ 	s32 sp;
+@@ -510,7 +546,10 @@ _sys32_rt_sigreturn(nabi_no_regargs stru
+ 
+ 	/* It is more difficult to avoid calling this function than to
+ 	   call it and ignore errors.  */
++	old_fs = get_fs();
++	set_fs (KERNEL_DS);
+ 	do_sigaltstack(&st, NULL, regs.regs[29]);
++	set_fs (old_fs);
+ 
+ 	/*
+ 	 * Don't let your children do this ...
+@@ -550,8 +589,15 @@ static inline int setup_sigcontext32(str
+ 
+ 	err |= __put_user(regs->hi, &sc->sc_mdhi);
+ 	err |= __put_user(regs->lo, &sc->sc_mdlo);
+-	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+-	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
++	if (cpu_has_dsp) {
++		err |= __put_user(rddsp(DSP_MASK), &sc->sc_hi1);
++		err |= __put_user(mfhi1(), &sc->sc_hi1);
++		err |= __put_user(mflo1(), &sc->sc_lo1);
++		err |= __put_user(mfhi2(), &sc->sc_hi2);
++		err |= __put_user(mflo2(), &sc->sc_lo2);
++		err |= __put_user(mfhi3(), &sc->sc_hi3);
++		err |= __put_user(mflo3(), &sc->sc_lo3);
++	}
+ 
+ 	err |= __put_user(!!used_math(), &sc->sc_used_math);
+ 
+@@ -601,7 +647,7 @@ static inline void *get_sigframe(struct 
+ 	return (void *)((sp - frame_size) & ALMASK);
+ }
+ 
+-static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
++void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+ 			       int signr, sigset_t *set)
+ {
+ 	struct sigframe *frame;
+@@ -654,9 +700,7 @@ give_sigsegv:
+ 	force_sigsegv(signr, current);
+ }
+ 
+-static inline void setup_rt_frame(struct k_sigaction * ka,
+-				  struct pt_regs *regs, int signr,
+-				  sigset_t *set, siginfo_t *info)
++void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr,	sigset_t *set, siginfo_t *info)
+ {
+ 	struct rt_sigframe32 *frame;
+ 	int err = 0;
+@@ -725,9 +769,11 @@ give_sigsegv:
+ 	force_sigsegv(signr, current);
+ }
+ 
+-static inline void handle_signal(unsigned long sig, siginfo_t *info,
++static inline int handle_signal(unsigned long sig, siginfo_t *info,
+ 	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
+ {
++	int ret;
++
+ 	switch (regs->regs[0]) {
+ 	case ERESTART_RESTARTBLOCK:
+ 	case ERESTARTNOHAND:
+@@ -747,9 +793,9 @@ static inline void handle_signal(unsigne
+ 	regs->regs[0] = 0;		/* Don't deal with this again.  */
+ 
+ 	if (ka->sa.sa_flags & SA_SIGINFO)
+-		setup_rt_frame(ka, regs, sig, oldset, info);
++		ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
+ 	else
+-		setup_frame(ka, regs, sig, oldset);
++		ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
+ 
+ 	spin_lock_irq(&current->sighand->siglock);
+ 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+@@ -757,6 +803,8 @@ static inline void handle_signal(unsigne
+ 		sigaddset(&current->blocked,sig);
+ 	recalc_sigpending();
+ 	spin_unlock_irq(&current->sighand->siglock);
++
++	return ret;
+ }
+ 
+ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+@@ -780,10 +828,8 @@ int do_signal32(sigset_t *oldset, struct
+ 		oldset = &current->blocked;
+ 
+ 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+-	if (signr > 0) {
+-		handle_signal(signr, &info, &ka, oldset, regs);
+-		return 1;
+-	}
++	if (signr > 0)
++		return handle_signal(signr, &info, &ka, oldset, regs);
+ 
+ no_signal:
+ 	/*
+@@ -819,12 +865,13 @@ asmlinkage int sys32_rt_sigaction(int si
+ 		goto out;
+ 
+ 	if (act) {
++		s32 handler;
+ 		int err = 0;
+ 
+ 		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+ 			return -EFAULT;
+-		err |= __get_user((u32)(u64)new_sa.sa.sa_handler,
+-		                  &act->sa_handler);
++		err |= __get_user(handler, &act->sa_handler);
++		new_sa.sa.sa_handler = (void*)(s64)handler;
+ 		err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
+ 		err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
+ 		if (err)
+@@ -902,3 +949,30 @@ asmlinkage int sys32_rt_sigqueueinfo(int
+ 	set_fs (old_fs);
+ 	return ret;
+ }
++
++asmlinkage long
++sys32_waitid(int which, compat_pid_t pid,
++	     compat_siginfo_t __user *uinfo, int options,
++	     struct compat_rusage __user *uru)
++{
++	siginfo_t info;
++	struct rusage ru;
++	long ret;
++	mm_segment_t old_fs = get_fs();
++
++	info.si_signo = 0;
++	set_fs (KERNEL_DS);
++	ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
++			 uru ? (struct rusage __user *) &ru : NULL);
++	set_fs (old_fs);
++
++	if (ret < 0 || info.si_signo == 0)
++		return ret;
++
++	if (uru && (ret = put_compat_rusage(&ru, uru)))
++		return ret;
++
++	BUG_ON(info.si_code & __SI_MASK);
++	info.si_code |= __SI_CHLD;
++	return copy_siginfo_to_user32(uinfo, &info);
++}
+diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
+--- a/arch/mips/kernel/signal_n32.c
++++ b/arch/mips/kernel/signal_n32.c
+@@ -15,6 +15,8 @@
+  * 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/cache.h>
++#include <linux/sched.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+ #include <linux/smp.h>
+@@ -36,6 +38,7 @@
+ #include <asm/system.h>
+ #include <asm/fpu.h>
+ #include <asm/cpu-features.h>
++#include <asm/war.h>
+ 
+ #include "signal-common.h"
+ 
+@@ -62,17 +65,18 @@ struct ucontextn32 {
+ 	sigset_t            uc_sigmask;   /* mask last for extensibility */
+ };
+ 
+-#if PLAT_TRAMPOLINE_STUFF_LINE
+-#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
+-#else
+-#define __tramp
+-#endif
+-
+ struct rt_sigframe_n32 {
+ 	u32 rs_ass[4];			/* argument save space for o32 */
+-	u32 rs_code[2] __tramp;		/* signal trampoline */
+-	struct siginfo rs_info __tramp;
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 rs_pad[2];
++#else
++	u32 rs_code[2];			/* signal trampoline */
++#endif
++	struct siginfo rs_info;
+ 	struct ucontextn32 rs_uc;
++#if ICACHE_REFILLS_WORKAROUND_WAR
++	u32 rs_code[8] ____cacheline_aligned;		/* signal trampoline */
++#endif
+ };
+ 
+ save_static_function(sysn32_rt_sigreturn);
+@@ -126,7 +130,7 @@ badframe:
+ 	force_sig(SIGSEGV, current);
+ }
+ 
+-void setup_rt_frame_n32(struct k_sigaction * ka,
++int setup_rt_frame_n32(struct k_sigaction * ka,
+ 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
+ {
+ 	struct rt_sigframe_n32 *frame;
+@@ -137,17 +141,7 @@ void setup_rt_frame_n32(struct k_sigacti
+ 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ 		goto give_sigsegv;
+ 
+-	/*
+-	 * Set up the return code ...
+-	 *
+-	 *         li      v0, __NR_rt_sigreturn
+-	 *         syscall
+-	 */
+-	if (PLAT_TRAMPOLINE_STUFF_LINE)
+-		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
+-	err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0);
+-	err |= __put_user(0x0000000c                        , frame->rs_code + 1);
+-	flush_cache_sigtramp((unsigned long) frame->rs_code);
++	install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
+ 
+ 	/* Create siginfo.  */
+ 	err |= copy_siginfo_to_user(&frame->rs_info, info);
+@@ -190,8 +184,9 @@ void setup_rt_frame_n32(struct k_sigacti
+ 	       current->comm, current->pid,
+ 	       frame, regs->cp0_epc, regs->regs[31]);
+ #endif
+-	return;
++	return 1;
+ 
+ give_sigsegv:
+ 	force_sigsegv(signr, current);
++	return 0;
+ }
+diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
+--- a/arch/mips/kernel/smp.c
++++ b/arch/mips/kernel/smp.c
+@@ -50,7 +50,6 @@ static void smp_tune_scheduling (void)
+ {
+ 	struct cache_desc *cd = &current_cpu_data.scache;
+ 	unsigned long cachesize;       /* kB   */
+-	unsigned long bandwidth = 350; /* MB/s */
+ 	unsigned long cpu_khz;
+ 
+ 	/*
+@@ -121,7 +120,19 @@ struct call_data_struct *call_data;
+  * or are or have executed.
+  *
+  * You must not call this function with disabled interrupts or from a
+- * hardware interrupt handler or from a bottom half handler.
++ * hardware interrupt handler or from a bottom half handler:
++ *
++ * CPU A                               CPU B
++ * Disable interrupts
++ *                                     smp_call_function()
++ *                                     Take call_lock
++ *                                     Send IPIs
++ *                                     Wait for all cpus to acknowledge IPI
++ *                                     CPU A has not responded, spin waiting
++ *                                     for cpu A to respond, holding call_lock
++ * smp_call_function()
++ * Spin waiting for call_lock
++ * Deadlock                            Deadlock
+  */
+ int smp_call_function (void (*func) (void *info), void *info, int retry,
+ 								int wait)
+@@ -130,6 +141,11 @@ int smp_call_function (void (*func) (voi
+ 	int i, cpus = num_online_cpus() - 1;
+ 	int cpu = smp_processor_id();
+ 
++	/*
++	 * Can die spectacularly if this CPU isn't yet marked online
++	 */
++	BUG_ON(!cpu_online(cpu));
++
+ 	if (!cpus)
+ 		return 0;
+ 
+@@ -214,7 +230,6 @@ void __init smp_cpus_done(unsigned int m
+ /* called from main before smp_init() */
+ void __init smp_prepare_cpus(unsigned int max_cpus)
+ {
+-	cpu_data[0].udelay_val = loops_per_jiffy;
+ 	init_new_context(current, &init_mm);
+ 	current_thread_info()->cpu = 0;
+ 	smp_tune_scheduling();
+@@ -236,23 +251,28 @@ void __devinit smp_prepare_boot_cpu(void
+ }
+ 
+ /*
+- * Startup the CPU with this logical number
++ * Called once for each "cpu_possible(cpu)".  Needs to spin up the cpu
++ * and keep control until "cpu_online(cpu)" is set.  Note: cpu is
++ * physical, not logical.
+  */
+-static int __init do_boot_cpu(int cpu)
++int __devinit __cpu_up(unsigned int cpu)
+ {
+ 	struct task_struct *idle;
+ 
+ 	/*
++	 * Processor goes to start_secondary(), sets online flag
+ 	 * The following code is purely to make sure
+ 	 * Linux can schedule processes on this slave.
+ 	 */
+ 	idle = fork_idle(cpu);
+ 	if (IS_ERR(idle))
+-		panic("failed fork for CPU %d\n", cpu);
++		panic(KERN_ERR "Fork failed for CPU %d", cpu);
+ 
+ 	prom_boot_secondary(cpu, idle);
+ 
+-	/* XXXKW timeout */
++	/*
++	 * Trust is futile.  We should really have timeouts ...
++	 */
+ 	while (!cpu_isset(cpu, cpu_callin_map))
+ 		udelay(100);
+ 
+@@ -261,23 +281,6 @@ static int __init do_boot_cpu(int cpu)
+ 	return 0;
+ }
+ 
+-/*
+- * Called once for each "cpu_possible(cpu)".  Needs to spin up the cpu
+- * and keep control until "cpu_online(cpu)" is set.  Note: cpu is
+- * physical, not logical.
+- */
+-int __devinit __cpu_up(unsigned int cpu)
+-{
+-	int ret;
+-
+-	/* Processor goes to start_secondary(), sets online flag */
+-	ret = do_boot_cpu(cpu);
+-	if (ret < 0)
+-		return ret;
+-
+-	return 0;
+-}
+-
+ /* Not really SMP stuff ... */
+ int setup_profiling_timer(unsigned int multiplier)
+ {
+diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/kernel/smp_mt.c
+@@ -0,0 +1,366 @@
++/*
++ * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  Elizabeth Clarke (beth at mips.com)
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/sched.h>
++#include <linux/cpumask.h>
++#include <linux/interrupt.h>
++#include <linux/compiler.h>
++
++#include <asm/atomic.h>
++#include <asm/cpu.h>
++#include <asm/processor.h>
++#include <asm/system.h>
++#include <asm/hardirq.h>
++#include <asm/mmu_context.h>
++#include <asm/smp.h>
++#include <asm/time.h>
++#include <asm/mipsregs.h>
++#include <asm/mipsmtregs.h>
++#include <asm/cacheflush.h>
++#include <asm/mips-boards/maltaint.h>
++
++#define MIPS_CPU_IPI_RESCHED_IRQ 0
++#define MIPS_CPU_IPI_CALL_IRQ 1
++
++static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
++
++#if 0
++static void dump_mtregisters(int vpe, int tc)
++{
++	printk("vpe %d tc %d\n", vpe, tc);
++
++	settc(tc);
++
++	printk("  c0 status  0x%lx\n", read_vpe_c0_status());
++	printk("  vpecontrol 0x%lx\n", read_vpe_c0_vpecontrol());
++	printk("  vpeconf0    0x%lx\n", read_vpe_c0_vpeconf0());
++	printk("  tcstatus 0x%lx\n", read_tc_c0_tcstatus());
++	printk("  tcrestart 0x%lx\n", read_tc_c0_tcrestart());
++	printk("  tcbind 0x%lx\n", read_tc_c0_tcbind());
++	printk("  tchalt 0x%lx\n", read_tc_c0_tchalt());
++}
++#endif
++
++void __init sanitize_tlb_entries(void)
++{
++	int i, tlbsiz;
++	unsigned long mvpconf0, ncpu;
++
++	if (!cpu_has_mipsmt)
++		return;
++
++	set_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	/* Disable TLB sharing */
++	clear_c0_mvpcontrol(MVPCONTROL_STLB);
++
++	mvpconf0 = read_c0_mvpconf0();
++
++	printk(KERN_INFO "MVPConf0 0x%lx TLBS %lx PTLBE %ld\n", mvpconf0,
++		   (mvpconf0 & MVPCONF0_TLBS) >> MVPCONF0_TLBS_SHIFT,
++			   (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT);
++
++	tlbsiz = (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT;
++	ncpu = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
++
++	printk(" tlbsiz %d ncpu %ld\n", tlbsiz, ncpu);
++
++	if (tlbsiz > 0) {
++		/* share them out across the vpe's */
++		tlbsiz /= ncpu;
++
++		printk(KERN_INFO "setting Config1.MMU_size to %d\n", tlbsiz);
++
++		for (i = 0; i < ncpu; i++) {
++			settc(i);
++
++			if (i == 0)
++				write_c0_config1((read_c0_config1() & ~(0x3f << 25)) | (tlbsiz << 25));
++			else
++				write_vpe_c0_config1((read_vpe_c0_config1() & ~(0x3f << 25)) |
++						   (tlbsiz << 25));
++		}
++	}
++
++	clear_c0_mvpcontrol(MVPCONTROL_VPC);
++}
++
++#if 0
++/*
++ * Use c0_MVPConf0 to find out how many CPUs are available, setting up
++ * phys_cpu_present_map and the logical/physical mappings.
++ */
++void __init prom_build_cpu_map(void)
++{
++	int i, num, ncpus;
++
++	cpus_clear(phys_cpu_present_map);
++
++	/* assume we boot on cpu 0.... */
++	cpu_set(0, phys_cpu_present_map);
++	__cpu_number_map[0] = 0;
++	__cpu_logical_map[0] = 0;
++
++	if (cpu_has_mipsmt) {
++		ncpus = ((read_c0_mvpconf0() & (MVPCONF0_PVPE)) >> MVPCONF0_PVPE_SHIFT) + 1;
++		for (i=1, num=0; i< NR_CPUS && i<ncpus; i++) {
++			cpu_set(i, phys_cpu_present_map);
++			__cpu_number_map[i] = ++num;
++			__cpu_logical_map[num] = i;
++		}
++
++		printk(KERN_INFO "%i available secondary CPU(s)\n", num);
++	}
++}
++#endif
++
++static void ipi_resched_dispatch (struct pt_regs *regs)
++{
++	do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs);
++}
++
++static void ipi_call_dispatch (struct pt_regs *regs)
++{
++	do_IRQ(MIPS_CPU_IPI_CALL_IRQ, regs);
++}
++
++irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	return IRQ_HANDLED;
++}
++
++irqreturn_t ipi_call_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	smp_call_function_interrupt();
++
++	return IRQ_HANDLED;
++}
++
++static struct irqaction irq_resched = {
++	.handler	= ipi_resched_interrupt,
++	.flags		= SA_INTERRUPT,
++	.name		= "IPI_resched"
++};
++
++static struct irqaction irq_call = {
++	.handler	= ipi_call_interrupt,
++	.flags		= SA_INTERRUPT,
++	.name		= "IPI_call"
++};
++
++/*
++ * Common setup before any secondaries are started
++ * Make sure all CPU's are in a sensible state before we boot any of the
++ * secondarys
++ */
++void prom_prepare_cpus(unsigned int max_cpus)
++{
++	unsigned long val;
++	int i, num;
++
++	if (!cpu_has_mipsmt)
++		return;
++
++	/* disable MT so we can configure */
++	dvpe();
++	dmt();
++
++	/* Put MVPE's into 'configuration state' */
++	set_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	val = read_c0_mvpconf0();
++
++	/* we'll always have more TC's than VPE's, so loop setting everything
++	   to a sensible state */
++	for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) {
++		settc(i);
++
++		/* VPE's */
++		if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) {
++
++			/* deactivate all but vpe0 */
++			if (i != 0) {
++				unsigned long tmp = read_vpe_c0_vpeconf0();
++
++				tmp &= ~VPECONF0_VPA;
++
++				/* master VPE */
++				tmp |= VPECONF0_MVP;
++				write_vpe_c0_vpeconf0(tmp);
++
++				/* Record this as available CPU */
++				if (i < max_cpus) {
++					cpu_set(i, phys_cpu_present_map);
++					__cpu_number_map[i]	= ++num;
++					__cpu_logical_map[num]	= i;
++				}
++			}
++
++			/* disable multi-threading with TC's */
++			write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
++
++			if (i != 0) {
++				write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
++				write_vpe_c0_cause(read_vpe_c0_cause() & ~CAUSEF_IP);
++
++				/* set config to be the same as vpe0, particularly kseg0 coherency alg */
++				write_vpe_c0_config( read_c0_config());
++			}
++
++		}
++
++		/* TC's */
++
++		if (i != 0) {
++			unsigned long tmp;
++
++			/* bind a TC to each VPE, May as well put all excess TC's
++			   on the last VPE */
++			if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) )
++				write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) );
++			else {
++				write_tc_c0_tcbind( read_tc_c0_tcbind() | i);
++
++				/* and set XTC */
++				write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT));
++			}
++
++			tmp = read_tc_c0_tcstatus();
++
++			/* mark not allocated and not dynamically allocatable */
++			tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
++			tmp |= TCSTATUS_IXMT;		/* interrupt exempt */
++			write_tc_c0_tcstatus(tmp);
++
++			write_tc_c0_tchalt(TCHALT_H);
++		}
++	}
++
++	/* Release config state */
++	clear_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	/* We'll wait until starting the secondaries before starting MVPE */
++
++	printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
++
++	/* set up ipi interrupts */
++	if (cpu_has_vint) {
++		set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
++		set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
++	}
++
++	cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
++	cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ;
++
++	setup_irq(cpu_ipi_resched_irq, &irq_resched);
++	setup_irq(cpu_ipi_call_irq, &irq_call);
++
++	/* need to mark IPI's as IRQ_PER_CPU */
++	irq_desc[cpu_ipi_resched_irq].status |= IRQ_PER_CPU;
++	irq_desc[cpu_ipi_call_irq].status |= IRQ_PER_CPU;
++}
++
++/*
++ * Setup the PC, SP, and GP of a secondary processor and start it
++ * running!
++ * smp_bootstrap is the place to resume from
++ * __KSTK_TOS(idle) is apparently the stack pointer
++ * (unsigned long)idle->thread_info the gp
++ * assumes a 1:1 mapping of TC => VPE
++ */
++void prom_boot_secondary(int cpu, struct task_struct *idle)
++{
++	dvpe();
++	set_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	settc(cpu);
++
++	/* restart */
++	write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
++
++	/* enable the tc this vpe/cpu will be running */
++	write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~TCSTATUS_IXMT) | TCSTATUS_A);
++
++	write_tc_c0_tchalt(0);
++
++	/* enable the VPE */
++	write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
++
++	/* stack pointer */
++	write_tc_gpr_sp( __KSTK_TOS(idle));
++
++	/* global pointer */
++	write_tc_gpr_gp((unsigned long)idle->thread_info);
++
++	flush_icache_range((unsigned long)idle->thread_info,
++					   (unsigned long)idle->thread_info +
++					   sizeof(struct thread_info));
++
++	/* finally out of configuration and into chaos */
++	clear_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	evpe(EVPE_ENABLE);
++}
++
++void prom_init_secondary(void)
++{
++	write_c0_status((read_c0_status() & ~ST0_IM ) |
++	                (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7));
++}
++
++void prom_smp_finish(void)
++{
++	write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
++
++	local_irq_enable();
++}
++
++void prom_cpus_done(void)
++{
++}
++
++void core_send_ipi(int cpu, unsigned int action)
++{
++	int i;
++	unsigned long flags;
++	int vpflags;
++
++	local_irq_save (flags);
++
++	vpflags = dvpe();	/* cant access the other CPU's registers whilst MVPE enabled */
++
++	switch (action) {
++	case SMP_CALL_FUNCTION:
++		i = C_SW1;
++		break;
++
++	case SMP_RESCHEDULE_YOURSELF:
++	default:
++		i = C_SW0;
++		break;
++	}
++
++	/* 1:1 mapping of vpe and tc... */
++	settc(cpu);
++	write_vpe_c0_cause(read_vpe_c0_cause() | i);
++	evpe(vpflags);
++
++	local_irq_restore(flags);
++}
+diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
+--- a/arch/mips/kernel/syscall.c
++++ b/arch/mips/kernel/syscall.c
+@@ -7,6 +7,7 @@
+  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+  * Copyright (C) 2001 MIPS Technologies, Inc.
+  */
++#include <linux/config.h>
+ #include <linux/a.out.h>
+ #include <linux/errno.h>
+ #include <linux/linkage.h>
+@@ -26,6 +27,7 @@
+ #include <linux/msg.h>
+ #include <linux/shm.h>
+ #include <linux/compiler.h>
++#include <linux/module.h>
+ 
+ #include <asm/branch.h>
+ #include <asm/cachectl.h>
+@@ -56,6 +58,8 @@ out:
+ 
+ unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
+ 
++EXPORT_SYMBOL(shm_align_mask);
++
+ #define COLOUR_ALIGN(addr,pgoff)				\
+ 	((((addr) + shm_align_mask) & ~shm_align_mask) +	\
+ 	 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
+@@ -173,14 +177,28 @@ _sys_clone(nabi_no_regargs struct pt_reg
+ {
+ 	unsigned long clone_flags;
+ 	unsigned long newsp;
+-	int *parent_tidptr, *child_tidptr;
++	int __user *parent_tidptr, *child_tidptr;
+ 
+ 	clone_flags = regs.regs[4];
+ 	newsp = regs.regs[5];
+ 	if (!newsp)
+ 		newsp = regs.regs[29];
+-	parent_tidptr = (int *) regs.regs[6];
+-	child_tidptr = (int *) regs.regs[7];
++	parent_tidptr = (int __user *) regs.regs[6];
++#ifdef CONFIG_32BIT
++	/* We need to fetch the fifth argument off the stack.  */
++	child_tidptr = NULL;
++	if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) {
++		int __user *__user *usp = (int __user *__user *) regs.regs[29];
++		if (regs.regs[2] == __NR_syscall) {
++			if (get_user (child_tidptr, &usp[5]))
++				return -EFAULT;
++		}
++		else if (get_user (child_tidptr, &usp[4]))
++			return -EFAULT;
++	}
++#else
++	child_tidptr = (int __user *) regs.regs[8];
++#endif
+ 	return do_fork(clone_flags, newsp, &regs, 0,
+ 	               parent_tidptr, child_tidptr);
+ }
+@@ -242,6 +260,16 @@ asmlinkage int sys_olduname(struct oldol
+ 	return error;
+ }
+ 
++void sys_set_thread_area(unsigned long addr)
++{
++	struct thread_info *ti = current->thread_info;
++
++	ti->tp_value = addr;
++
++	/* If some future MIPS implementation has this register in hardware,
++	 * we will need to update it here (and in context switches).  */
++}
++
+ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
+ {
+ 	int	tmp, len;
+diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
+--- a/arch/mips/kernel/sysirix.c
++++ b/arch/mips/kernel/sysirix.c
+@@ -73,32 +73,30 @@ asmlinkage int irix_sysmp(struct pt_regs
+ }
+ 
+ /* The prctl commands. */
+-#define PR_MAXPROCS          1 /* Tasks/user. */
+-#define PR_ISBLOCKED         2 /* If blocked, return 1. */
+-#define PR_SETSTACKSIZE      3 /* Set largest task stack size. */
+-#define PR_GETSTACKSIZE      4 /* Get largest task stack size. */
+-#define PR_MAXPPROCS         5 /* Num parallel tasks. */
+-#define PR_UNBLKONEXEC       6 /* When task exec/exit's, unblock. */
+-#define PR_SETEXITSIG        8 /* When task exit's, set signal. */
+-#define PR_RESIDENT          9 /* Make task unswappable. */
+-#define PR_ATTACHADDR       10 /* (Re-)Connect a vma to a task. */
+-#define PR_DETACHADDR       11 /* Disconnect a vma from a task. */
+-#define PR_TERMCHILD        12 /* When parent sleeps with fishes, kill child. */
+-#define PR_GETSHMASK        13 /* Get the sproc() share mask. */
+-#define PR_GETNSHARE        14 /* Number of share group members. */
+-#define PR_COREPID          15 /* Add task pid to name when it core. */
+-#define	PR_ATTACHADDRPERM   16 /* (Re-)Connect vma, with specified prot. */
+-#define PR_PTHREADEXIT      17 /* Kill a pthread without prejudice. */
++#define PR_MAXPROCS		 1 /* Tasks/user. */
++#define PR_ISBLOCKED		 2 /* If blocked, return 1. */
++#define PR_SETSTACKSIZE		 3 /* Set largest task stack size. */
++#define PR_GETSTACKSIZE		 4 /* Get largest task stack size. */
++#define PR_MAXPPROCS		 5 /* Num parallel tasks. */
++#define PR_UNBLKONEXEC		 6 /* When task exec/exit's, unblock. */
++#define PR_SETEXITSIG		 8 /* When task exit's, set signal. */
++#define PR_RESIDENT		 9 /* Make task unswappable. */
++#define PR_ATTACHADDR		10 /* (Re-)Connect a vma to a task. */
++#define PR_DETACHADDR		11 /* Disconnect a vma from a task. */
++#define PR_TERMCHILD		12 /* Kill child if the parent dies. */
++#define PR_GETSHMASK		13 /* Get the sproc() share mask. */
++#define PR_GETNSHARE		14 /* Number of share group members. */
++#define PR_COREPID		15 /* Add task pid to name when it core. */
++#define PR_ATTACHADDRPERM	16 /* (Re-)Connect vma, with specified prot. */
++#define PR_PTHREADEXIT		17 /* Kill a pthread, only for IRIX 6.[234] */
+ 
+-asmlinkage int irix_prctl(struct pt_regs *regs)
++asmlinkage int irix_prctl(unsigned option, ...)
+ {
+-	unsigned long cmd;
+-	int error = 0, base = 0;
++	va_list args;
++	int error = 0;
+ 
+-	if (regs->regs[2] == 1000)
+-		base = 1;
+-	cmd = regs->regs[base + 4];
+-	switch (cmd) {
++	va_start(args, option);
++	switch (option) {
+ 	case PR_MAXPROCS:
+ 		printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
+ 		       current->comm, current->pid);
+@@ -111,7 +109,7 @@ asmlinkage int irix_prctl(struct pt_regs
+ 		printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
+ 		       current->comm, current->pid);
+ 		read_lock(&tasklist_lock);
+-		task = find_task_by_pid(regs->regs[base + 5]);
++		task = find_task_by_pid(va_arg(args, pid_t));
+ 		error = -ESRCH;
+ 		if (error)
+ 			error = (task->run_list.next != NULL);
+@@ -121,7 +119,7 @@ asmlinkage int irix_prctl(struct pt_regs
+ 	}
+ 
+ 	case PR_SETSTACKSIZE: {
+-		long value = regs->regs[base + 5];
++		long value = va_arg(args, long);
+ 
+ 		printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n",
+ 		       current->comm, current->pid, (unsigned long) value);
+@@ -222,24 +220,20 @@ asmlinkage int irix_prctl(struct pt_regs
+ 		error = -EINVAL;
+ 		break;
+ 
+-	case PR_PTHREADEXIT:
+-		printk("irix_prctl[%s:%d]: Wants PR_PTHREADEXIT\n",
+-		       current->comm, current->pid);
+-		do_exit(regs->regs[base + 5]);
+-
+ 	default:
+ 		printk("irix_prctl[%s:%d]: Non-existant opcode %d\n",
+-		       current->comm, current->pid, (int)cmd);
++		       current->comm, current->pid, option);
+ 		error = -EINVAL;
+ 		break;
+ 	}
++	va_end(args);
+ 
+ 	return error;
+ }
+ 
+ #undef DEBUG_PROCGRPS
+ 
+-extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
++extern unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt);
+ extern int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
+ extern char *prom_getenv(char *name);
+ extern long prom_setenv(char *name, char *value);
+@@ -276,23 +270,19 @@ asmlinkage int irix_syssgi(struct pt_reg
+ 	cmd = regs->regs[base + 4];
+ 	switch(cmd) {
+ 	case SGI_SYSID: {
+-		char *buf = (char *) regs->regs[base + 5];
++		char __user *buf = (char __user *) regs->regs[base + 5];
+ 
+ 		/* XXX Use ethernet addr.... */
+-		retval = clear_user(buf, 64);
++		retval = clear_user(buf, 64) ? -EFAULT : 0;
+ 		break;
+ 	}
+ #if 0
+ 	case SGI_RDNAME: {
+ 		int pid = (int) regs->regs[base + 5];
+-		char *buf = (char *) regs->regs[base + 6];
++		char __user *buf = (char __user *) regs->regs[base + 6];
+ 		struct task_struct *p;
+ 		char tcomm[sizeof(current->comm)];
+ 
+-		if (!access_ok(VERIFY_WRITE, buf, sizeof(tcomm))) {
+-			retval = -EFAULT;
+-			break;
+-		}
+ 		read_lock(&tasklist_lock);
+ 		p = find_task_by_pid(pid);
+ 		if (!p) {
+@@ -304,34 +294,28 @@ asmlinkage int irix_syssgi(struct pt_reg
+ 		read_unlock(&tasklist_lock);
+ 
+ 		/* XXX Need to check sizes. */
+-		copy_to_user(buf, tcomm, sizeof(tcomm));
+-		retval = 0;
++		retval = copy_to_user(buf, tcomm, sizeof(tcomm)) ? -EFAULT : 0;
+ 		break;
+ 	}
+ 
+ 	case SGI_GETNVRAM: {
+-		char *name = (char *) regs->regs[base+5];
+-		char *buf = (char *) regs->regs[base+6];
++		char __user *name = (char __user *) regs->regs[base+5];
++		char __user *buf = (char __user *) regs->regs[base+6];
+ 		char *value;
+ 		return -EINVAL;	/* til I fix it */
+-		if (!access_ok(VERIFY_WRITE, buf, 128)) {
+-			retval = -EFAULT;
+-			break;
+-		}
+ 		value = prom_getenv(name);	/* PROM lock?  */
+ 		if (!value) {
+ 			retval = -EINVAL;
+ 			break;
+ 		}
+ 		/* Do I strlen() for the length? */
+-		copy_to_user(buf, value, 128);
+-		retval = 0;
++		retval = copy_to_user(buf, value, 128) ? -EFAULT : 0;
+ 		break;
+ 	}
+ 
+ 	case SGI_SETNVRAM: {
+-		char *name = (char *) regs->regs[base+5];
+-		char *value = (char *) regs->regs[base+6];
++		char __user *name = (char __user *) regs->regs[base+5];
++		char __user *value = (char __user *) regs->regs[base+6];
+ 		return -EINVAL;	/* til I fix it */
+ 		retval = prom_setenv(name, value);
+ 		/* XXX make sure retval conforms to syssgi(2) */
+@@ -407,16 +391,16 @@ asmlinkage int irix_syssgi(struct pt_reg
+ 
+ 	case SGI_SETGROUPS:
+ 		retval = sys_setgroups((int) regs->regs[base + 5],
+-		                       (gid_t *) regs->regs[base + 6]);
++		                       (gid_t __user *) regs->regs[base + 6]);
+ 		break;
+ 
+ 	case SGI_GETGROUPS:
+ 		retval = sys_getgroups((int) regs->regs[base + 5],
+-		                       (gid_t *) regs->regs[base + 6]);
++		                       (gid_t __user *) regs->regs[base + 6]);
+ 		break;
+ 
+ 	case SGI_RUSAGE: {
+-		struct rusage *ru = (struct rusage *) regs->regs[base + 6];
++		struct rusage __user *ru = (struct rusage __user *) regs->regs[base + 6];
+ 
+ 		switch((int) regs->regs[base + 5]) {
+ 		case 0:
+@@ -453,7 +437,7 @@ asmlinkage int irix_syssgi(struct pt_reg
+ 
+ 	case SGI_ELFMAP:
+ 		retval = irix_mapelf((int) regs->regs[base + 5],
+-				     (struct elf_phdr *) regs->regs[base + 6],
++				     (struct elf_phdr __user *) regs->regs[base + 6],
+ 				     (int) regs->regs[base + 7]);
+ 		break;
+ 
+@@ -468,24 +452,24 @@ asmlinkage int irix_syssgi(struct pt_reg
+ 
+ 	case SGI_PHYSP: {
+ 		unsigned long addr = regs->regs[base + 5];
+-		int *pageno = (int *) (regs->regs[base + 6]);
++		int __user *pageno = (int __user *) (regs->regs[base + 6]);
+ 		struct mm_struct *mm = current->mm;
+ 		pgd_t *pgdp;
++		pud_t *pudp;
+ 		pmd_t *pmdp;
+ 		pte_t *ptep;
+ 
+-		if (!access_ok(VERIFY_WRITE, pageno, sizeof(int)))
+-			return -EFAULT;
+-
+ 		down_read(&mm->mmap_sem);
+ 		pgdp = pgd_offset(mm, addr);
+-		pmdp = pmd_offset(pgdp, addr);
++		pudp = pud_offset(pgdp, addr);
++		pmdp = pmd_offset(pudp, addr);
+ 		ptep = pte_offset(pmdp, addr);
+ 		retval = -EINVAL;
+ 		if (ptep) {
+ 			pte_t pte = *ptep;
+ 
+ 			if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) {
++				/* b0rked on 64-bit */
+ 				retval =  put_user((pte_val(pte) & PAGE_MASK) >>
+ 				                   PAGE_SHIFT, pageno);
+ 			}
+@@ -496,7 +480,7 @@ asmlinkage int irix_syssgi(struct pt_reg
+ 
+ 	case SGI_INVENT: {
+ 		int  arg1    = (int)    regs->regs [base + 5];
+-		void *buffer = (void *) regs->regs [base + 6];
++		void __user *buffer = (void __user *) regs->regs [base + 6];
+ 		int  count   = (int)    regs->regs [base + 7];
+ 
+ 		switch (arg1) {
+@@ -692,8 +676,8 @@ asmlinkage int irix_pause(void)
+ }
+ 
+ /* XXX need more than this... */
+-asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
+-			  char *type, void *data, int datalen)
++asmlinkage int irix_mount(char __user *dev_name, char __user *dir_name,
++	unsigned long flags, char __user *type, void __user *data, int datalen)
+ {
+ 	printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
+ 	       current->comm, current->pid,
+@@ -708,8 +692,8 @@ struct irix_statfs {
+ 	char  f_fname[6], f_fpack[6];
+ };
+ 
+-asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
+-			   int len, int fs_type)
++asmlinkage int irix_statfs(const char __user *path,
++	struct irix_statfs __user *buf, int len, int fs_type)
+ {
+ 	struct nameidata nd;
+ 	struct kstatfs kbuf;
+@@ -724,6 +708,7 @@ asmlinkage int irix_statfs(const char *p
+ 		error = -EFAULT;
+ 		goto out;
+ 	}
++
+ 	error = user_path_walk(path, &nd);
+ 	if (error)
+ 		goto out;
+@@ -732,18 +717,17 @@ asmlinkage int irix_statfs(const char *p
+ 	if (error)
+ 		goto dput_and_out;
+ 
+-	__put_user(kbuf.f_type, &buf->f_type);
+-	__put_user(kbuf.f_bsize, &buf->f_bsize);
+-	__put_user(kbuf.f_frsize, &buf->f_frsize);
+-	__put_user(kbuf.f_blocks, &buf->f_blocks);
+-	__put_user(kbuf.f_bfree, &buf->f_bfree);
+-	__put_user(kbuf.f_files, &buf->f_files);
+-	__put_user(kbuf.f_ffree, &buf->f_ffree);
++	error = __put_user(kbuf.f_type, &buf->f_type);
++	error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
++	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
++	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
++	error |= __put_user(kbuf.f_files, &buf->f_files);
++	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+ 	for (i = 0; i < 6; i++) {
+-		__put_user(0, &buf->f_fname[i]);
+-		__put_user(0, &buf->f_fpack[i]);
++		error |= __put_user(0, &buf->f_fname[i]);
++		error |= __put_user(0, &buf->f_fpack[i]);
+ 	}
+-	error = 0;
+ 
+ dput_and_out:
+ 	path_release(&nd);
+@@ -751,7 +735,7 @@ out:
+ 	return error;
+ }
+ 
+-asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
++asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf)
+ {
+ 	struct kstatfs kbuf;
+ 	struct file *file;
+@@ -761,6 +745,7 @@ asmlinkage int irix_fstatfs(unsigned int
+ 		error = -EFAULT;
+ 		goto out;
+ 	}
++
+ 	if (!(file = fget(fd))) {
+ 		error = -EBADF;
+ 		goto out;
+@@ -770,16 +755,17 @@ asmlinkage int irix_fstatfs(unsigned int
+ 	if (error)
+ 		goto out_f;
+ 
+-	__put_user(kbuf.f_type, &buf->f_type);
+-	__put_user(kbuf.f_bsize, &buf->f_bsize);
+-	__put_user(kbuf.f_frsize, &buf->f_frsize);
+-	__put_user(kbuf.f_blocks, &buf->f_blocks);
+-	__put_user(kbuf.f_bfree, &buf->f_bfree);
+-	__put_user(kbuf.f_files, &buf->f_files);
+-	__put_user(kbuf.f_ffree, &buf->f_ffree);
+-	for(i = 0; i < 6; i++) {
+-		__put_user(0, &buf->f_fname[i]);
+-		__put_user(0, &buf->f_fpack[i]);
++	error = __put_user(kbuf.f_type, &buf->f_type);
++	error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
++	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
++	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
++	error |= __put_user(kbuf.f_files, &buf->f_files);
++	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
++
++	for (i = 0; i < 6; i++) {
++		error |= __put_user(0, &buf->f_fname[i]);
++		error |= __put_user(0, &buf->f_fpack[i]);
+ 	}
+ 
+ out_f:
+@@ -806,14 +792,15 @@ asmlinkage int irix_setpgrp(int flags)
+ 	return error;
+ }
+ 
+-asmlinkage int irix_times(struct tms * tbuf)
++asmlinkage int irix_times(struct tms __user *tbuf)
+ {
+ 	int err = 0;
+ 
+ 	if (tbuf) {
+ 		if (!access_ok(VERIFY_WRITE,tbuf,sizeof *tbuf))
+ 			return -EFAULT;
+-		err |= __put_user(current->utime, &tbuf->tms_utime);
++
++		err = __put_user(current->utime, &tbuf->tms_utime);
+ 		err |= __put_user(current->stime, &tbuf->tms_stime);
+ 		err |= __put_user(current->signal->cutime, &tbuf->tms_cutime);
+ 		err |= __put_user(current->signal->cstime, &tbuf->tms_cstime);
+@@ -829,13 +816,13 @@ asmlinkage int irix_exec(struct pt_regs 
+ 
+ 	if(regs->regs[2] == 1000)
+ 		base = 1;
+-	filename = getname((char *) (long)regs->regs[base + 4]);
++	filename = getname((char __user *) (long)regs->regs[base + 4]);
+ 	error = PTR_ERR(filename);
+ 	if (IS_ERR(filename))
+ 		return error;
+ 
+-	error = do_execve(filename, (char **) (long)regs->regs[base + 5],
+-	                  (char **) 0, regs);
++	error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
++	                  NULL, regs);
+ 	putname(filename);
+ 
+ 	return error;
+@@ -848,12 +835,12 @@ asmlinkage int irix_exece(struct pt_regs
+ 
+ 	if (regs->regs[2] == 1000)
+ 		base = 1;
+-	filename = getname((char *) (long)regs->regs[base + 4]);
++	filename = getname((char __user *) (long)regs->regs[base + 4]);
+ 	error = PTR_ERR(filename);
+ 	if (IS_ERR(filename))
+ 		return error;
+-	error = do_execve(filename, (char **) (long)regs->regs[base + 5],
+-	                  (char **) (long)regs->regs[base + 6], regs);
++	error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
++	                  (char __user * __user *) (long)regs->regs[base + 6], regs);
+ 	putname(filename);
+ 
+ 	return error;
+@@ -909,22 +896,17 @@ asmlinkage int irix_socket(int family, i
+ 	return sys_socket(family, type, protocol);
+ }
+ 
+-asmlinkage int irix_getdomainname(char *name, int len)
++asmlinkage int irix_getdomainname(char __user *name, int len)
+ {
+-	int error;
+-
+-	if (!access_ok(VERIFY_WRITE, name, len))
+-		return -EFAULT;
++	int err;
+ 
+ 	down_read(&uts_sem);
+ 	if (len > __NEW_UTS_LEN)
+ 		len = __NEW_UTS_LEN;
+-	error = 0;
+-	if (copy_to_user(name, system_utsname.domainname, len))
+-		error = -EFAULT;
++	err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0;
+ 	up_read(&uts_sem);
+ 
+-	return error;
++	return err;
+ }
+ 
+ asmlinkage unsigned long irix_getpagesize(void)
+@@ -940,12 +922,13 @@ asmlinkage int irix_msgsys(int opcode, u
+ 	case 0:
+ 		return sys_msgget((key_t) arg0, (int) arg1);
+ 	case 1:
+-		return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds *)arg2);
++		return sys_msgctl((int) arg0, (int) arg1,
++		                  (struct msqid_ds __user *)arg2);
+ 	case 2:
+-		return sys_msgrcv((int) arg0, (struct msgbuf *) arg1,
++		return sys_msgrcv((int) arg0, (struct msgbuf __user *) arg1,
+ 				  (size_t) arg2, (long) arg3, (int) arg4);
+ 	case 3:
+-		return sys_msgsnd((int) arg0, (struct msgbuf *) arg1,
++		return sys_msgsnd((int) arg0, (struct msgbuf __user *) arg1,
+ 				  (size_t) arg2, (int) arg3);
+ 	default:
+ 		return -EINVAL;
+@@ -957,12 +940,13 @@ asmlinkage int irix_shmsys(int opcode, u
+ {
+ 	switch (opcode) {
+ 	case 0:
+-		return do_shmat((int) arg0, (char *)arg1, (int) arg2,
++		return do_shmat((int) arg0, (char __user *) arg1, (int) arg2,
+ 				 (unsigned long *) arg3);
+ 	case 1:
+-		return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds *)arg2);
++		return sys_shmctl((int)arg0, (int)arg1,
++		                  (struct shmid_ds __user *)arg2);
+ 	case 2:
+-		return sys_shmdt((char *)arg0);
++		return sys_shmdt((char __user *)arg0);
+ 	case 3:
+ 		return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
+ 	default:
+@@ -980,7 +964,7 @@ asmlinkage int irix_semsys(int opcode, u
+ 	case 1:
+ 		return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
+ 	case 2:
+-		return sys_semop((int) arg0, (struct sembuf *)arg1,
++		return sys_semop((int) arg0, (struct sembuf __user *)arg1,
+ 				 (unsigned int) arg2);
+ 	default:
+ 		return -EINVAL;
+@@ -998,15 +982,16 @@ static inline loff_t llseek(struct file 
+ 	lock_kernel();
+ 	retval = fn(file, offset, origin);
+ 	unlock_kernel();
++
+ 	return retval;
+ }
+ 
+ asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,
+                             int origin)
+ {
+-	int retval;
+ 	struct file * file;
+ 	loff_t offset;
++	int retval;
+ 
+ 	retval = -EBADF;
+ 	file = fget(fd);
+@@ -1031,12 +1016,12 @@ asmlinkage int irix_sginap(int ticks)
+ 	return 0;
+ }
+ 
+-asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)
++asmlinkage int irix_sgikopt(char __user *istring, char __user *ostring, int len)
+ {
+ 	return -EINVAL;
+ }
+ 
+-asmlinkage int irix_gettimeofday(struct timeval *tv)
++asmlinkage int irix_gettimeofday(struct timeval __user *tv)
+ {
+ 	time_t sec;
+ 	long nsec, seq;
+@@ -1077,7 +1062,7 @@ asmlinkage unsigned long irix_mmap32(uns
+ 
+ 			if (max_size > file->f_dentry->d_inode->i_size) {
+ 				old_pos = sys_lseek (fd, max_size - 1, 0);
+-				sys_write (fd, "", 1);
++				sys_write (fd, (void __user *) "", 1);
+ 				sys_lseek (fd, old_pos, 0);
+ 			}
+ 		}
+@@ -1102,7 +1087,7 @@ asmlinkage int irix_madvise(unsigned lon
+ 	return -EINVAL;
+ }
+ 
+-asmlinkage int irix_pagelock(char *addr, int len, int op)
++asmlinkage int irix_pagelock(char __user *addr, int len, int op)
+ {
+ 	printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
+ 	       current->comm, current->pid, addr, len, op);
+@@ -1142,7 +1127,7 @@ asmlinkage int irix_BSDsetpgrp(int pid, 
+ 	return error;
+ }
+ 
+-asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
++asmlinkage int irix_systeminfo(int cmd, char __user *buf, int cnt)
+ {
+ 	printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
+ 	       current->comm, current->pid, cmd, buf, cnt);
+@@ -1158,14 +1143,14 @@ struct iuname {
+ 	char _unused3[257], _unused4[257], _unused5[257];
+ };
+ 
+-asmlinkage int irix_uname(struct iuname *buf)
++asmlinkage int irix_uname(struct iuname __user *buf)
+ {
+ 	down_read(&uts_sem);
+-	if (copy_to_user(system_utsname.sysname, buf->sysname, 65)
+-	    || copy_to_user(system_utsname.nodename, buf->nodename, 65)
+-	    || copy_to_user(system_utsname.release, buf->release, 65)
+-	    || copy_to_user(system_utsname.version, buf->version, 65)
+-	    || copy_to_user(system_utsname.machine, buf->machine, 65)) {
++	if (copy_from_user(system_utsname.sysname, buf->sysname, 65)
++	    || copy_from_user(system_utsname.nodename, buf->nodename, 65)
++	    || copy_from_user(system_utsname.release, buf->release, 65)
++	    || copy_from_user(system_utsname.version, buf->version, 65)
++	    || copy_from_user(system_utsname.machine, buf->machine, 65)) {
+ 		return -EFAULT;
+ 	}
+ 	up_read(&uts_sem);
+@@ -1175,7 +1160,7 @@ asmlinkage int irix_uname(struct iuname 
+ 
+ #undef DEBUG_XSTAT
+ 
+-static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
++static int irix_xstat32_xlate(struct kstat *stat, void __user *ubuf)
+ {
+ 	struct xstat32 {
+ 		u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
+@@ -1215,7 +1200,7 @@ static int irix_xstat32_xlate(struct kst
+ 	return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
+ }
+ 
+-static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
++static int irix_xstat64_xlate(struct kstat *stat, void __user *ubuf)
+ {
+ 	struct xstat64 {
+ 		u32 st_dev; s32 st_pad1[3];
+@@ -1265,7 +1250,7 @@ static int irix_xstat64_xlate(struct kst
+ 	return copy_to_user(ubuf, &ks, sizeof(ks)) ? -EFAULT : 0;
+ }
+ 
+-asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
++asmlinkage int irix_xstat(int version, char __user *filename, struct stat __user *statbuf)
+ {
+ 	int retval;
+ 	struct kstat stat;
+@@ -1291,7 +1276,7 @@ asmlinkage int irix_xstat(int version, c
+ 	return retval;
+ }
+ 
+-asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
++asmlinkage int irix_lxstat(int version, char __user *filename, struct stat __user *statbuf)
+ {
+ 	int error;
+ 	struct kstat stat;
+@@ -1318,7 +1303,7 @@ asmlinkage int irix_lxstat(int version, 
+ 	return error;
+ }
+ 
+-asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
++asmlinkage int irix_fxstat(int version, int fd, struct stat __user *statbuf)
+ {
+ 	int error;
+ 	struct kstat stat;
+@@ -1344,7 +1329,7 @@ asmlinkage int irix_fxstat(int version, 
+ 	return error;
+ }
+ 
+-asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
++asmlinkage int irix_xmknod(int ver, char __user *filename, int mode, unsigned dev)
+ {
+ 	int retval;
+ 	printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
+@@ -1364,7 +1349,7 @@ asmlinkage int irix_xmknod(int ver, char
+ 	return retval;
+ }
+ 
+-asmlinkage int irix_swapctl(int cmd, char *arg)
++asmlinkage int irix_swapctl(int cmd, char __user *arg)
+ {
+ 	printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
+ 	       current->comm, current->pid, cmd, arg);
+@@ -1380,7 +1365,7 @@ struct irix_statvfs {
+ 	char	f_fstr[32]; u32 f_filler[16];
+ };
+ 
+-asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
++asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf)
+ {
+ 	struct nameidata nd;
+ 	struct kstatfs kbuf;
+@@ -1388,10 +1373,9 @@ asmlinkage int irix_statvfs(char *fname,
+ 
+ 	printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
+ 	       current->comm, current->pid, fname, buf);
+-	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
+-		error = -EFAULT;
+-		goto out;
+-	}
++	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
++		return -EFAULT;
++
+ 	error = user_path_walk(fname, &nd);
+ 	if (error)
+ 		goto out;
+@@ -1399,27 +1383,25 @@ asmlinkage int irix_statvfs(char *fname,
+ 	if (error)
+ 		goto dput_and_out;
+ 
+-	__put_user(kbuf.f_bsize, &buf->f_bsize);
+-	__put_user(kbuf.f_frsize, &buf->f_frsize);
+-	__put_user(kbuf.f_blocks, &buf->f_blocks);
+-	__put_user(kbuf.f_bfree, &buf->f_bfree);
+-	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
+-	__put_user(kbuf.f_files, &buf->f_files);
+-	__put_user(kbuf.f_ffree, &buf->f_ffree);
+-	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
++	error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
++	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
++	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
++	error |= __put_user(kbuf.f_files, &buf->f_files);
++	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
++	error |= __put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
+ #ifdef __MIPSEB__
+-	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
++	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ #else
+-	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
++	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ #endif
+ 	for (i = 0; i < 16; i++)
+-		__put_user(0, &buf->f_basetype[i]);
+-	__put_user(0, &buf->f_flag);
+-	__put_user(kbuf.f_namelen, &buf->f_namemax);
++		error |= __put_user(0, &buf->f_basetype[i]);
++	error |= __put_user(0, &buf->f_flag);
++	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
+ 	for (i = 0; i < 32; i++)
+-		__put_user(0, &buf->f_fstr[i]);
+-
+-	error = 0;
++		error |= __put_user(0, &buf->f_fstr[i]);
+ 
+ dput_and_out:
+ 	path_release(&nd);
+@@ -1427,7 +1409,7 @@ out:
+ 	return error;
+ }
+ 
+-asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
++asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf)
+ {
+ 	struct kstatfs kbuf;
+ 	struct file *file;
+@@ -1436,10 +1418,9 @@ asmlinkage int irix_fstatvfs(int fd, str
+ 	printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
+ 	       current->comm, current->pid, fd, buf);
+ 
+-	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
+-		error = -EFAULT;
+-		goto out;
+-	}
++	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
++		return -EFAULT;
++
+ 	if (!(file = fget(fd))) {
+ 		error = -EBADF;
+ 		goto out;
+@@ -1448,24 +1429,24 @@ asmlinkage int irix_fstatvfs(int fd, str
+ 	if (error)
+ 		goto out_f;
+ 
+-	__put_user(kbuf.f_bsize, &buf->f_bsize);
+-	__put_user(kbuf.f_frsize, &buf->f_frsize);
+-	__put_user(kbuf.f_blocks, &buf->f_blocks);
+-	__put_user(kbuf.f_bfree, &buf->f_bfree);
+-	__put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+-	__put_user(kbuf.f_files, &buf->f_files);
+-	__put_user(kbuf.f_ffree, &buf->f_ffree);
+-	__put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
++	error = __put_user(kbuf.f_bsize, &buf->f_bsize);
++	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
++	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
++	error |= __put_user(kbuf.f_files, &buf->f_files);
++	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
++	error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+ #ifdef __MIPSEB__
+-	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
++	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ #else
+-	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
++	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ #endif
+ 	for(i = 0; i < 16; i++)
+-		__put_user(0, &buf->f_basetype[i]);
+-	__put_user(0, &buf->f_flag);
+-	__put_user(kbuf.f_namelen, &buf->f_namemax);
+-	__clear_user(&buf->f_fstr, sizeof(buf->f_fstr));
++		error |= __put_user(0, &buf->f_basetype[i]);
++	error |= __put_user(0, &buf->f_flag);
++	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
++	error |= __clear_user(&buf->f_fstr, sizeof(buf->f_fstr)) ? -EFAULT : 0;
+ 
+ out_f:
+ 	fput(file);
+@@ -1489,7 +1470,7 @@ asmlinkage int irix_sigqueue(int pid, in
+ 	return -EINVAL;
+ }
+ 
+-asmlinkage int irix_truncate64(char *name, int pad, int size1, int size2)
++asmlinkage int irix_truncate64(char __user *name, int pad, int size1, int size2)
+ {
+ 	int retval;
+ 
+@@ -1522,6 +1503,7 @@ asmlinkage int irix_mmap64(struct pt_reg
+ 	int len, prot, flags, fd, off1, off2, error, base = 0;
+ 	unsigned long addr, pgoff, *sp;
+ 	struct file *file = NULL;
++	int err;
+ 
+ 	if (regs->regs[2] == 1000)
+ 		base = 1;
+@@ -1531,36 +1513,31 @@ asmlinkage int irix_mmap64(struct pt_reg
+ 	prot = regs->regs[base + 6];
+ 	if (!base) {
+ 		flags = regs->regs[base + 7];
+-		if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long)))) {
+-			error = -EFAULT;
+-			goto out;
+-		}
++		if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long))))
++			return -EFAULT;
+ 		fd = sp[0];
+-		__get_user(off1, &sp[1]);
+-		__get_user(off2, &sp[2]);
++		err = __get_user(off1, &sp[1]);
++		err |= __get_user(off2, &sp[2]);
+ 	} else {
+-		if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long)))) {
+-			error = -EFAULT;
+-			goto out;
+-		}
+-		__get_user(flags, &sp[0]);
+-		__get_user(fd, &sp[1]);
+-		__get_user(off1, &sp[2]);
+-		__get_user(off2, &sp[3]);
++		if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long))))
++			return -EFAULT;
++		err = __get_user(flags, &sp[0]);
++		err |= __get_user(fd, &sp[1]);
++		err |= __get_user(off1, &sp[2]);
++		err |= __get_user(off2, &sp[3]);
+ 	}
+ 
+-	if (off1 & PAGE_MASK) {
+-		error = -EOVERFLOW;
+-		goto out;
+-	}
++	if (err)
++		return err;
++
++	if (off1 & PAGE_MASK)
++		return -EOVERFLOW;
+ 
+ 	pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
+ 
+ 	if (!(flags & MAP_ANONYMOUS)) {
+-		if (!(file = fget(fd))) {
+-			error = -EBADF;
+-			goto out;
+-		}
++		if (!(file = fget(fd)))
++			return -EBADF;
+ 
+ 		/* Ok, bad taste hack follows, try to think in something else
+ 		   when reading this */
+@@ -1570,7 +1547,7 @@ asmlinkage int irix_mmap64(struct pt_reg
+ 
+ 			if (max_size > file->f_dentry->d_inode->i_size) {
+ 				old_pos = sys_lseek (fd, max_size - 1, 0);
+-				sys_write (fd, "", 1);
++				sys_write (fd, (void __user *) "", 1);
+ 				sys_lseek (fd, old_pos, 0);
+ 			}
+ 		}
+@@ -1585,7 +1562,6 @@ asmlinkage int irix_mmap64(struct pt_reg
+ 	if (file)
+ 		fput(file);
+ 
+-out:
+ 	return error;
+ }
+ 
+@@ -1597,7 +1573,7 @@ asmlinkage int irix_dmi(struct pt_regs *
+ 	return -EINVAL;
+ }
+ 
+-asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
++asmlinkage int irix_pread(int fd, char __user *buf, int cnt, int off64,
+ 			  int off1, int off2)
+ {
+ 	printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
+@@ -1606,7 +1582,7 @@ asmlinkage int irix_pread(int fd, char *
+ 	return -EINVAL;
+ }
+ 
+-asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
++asmlinkage int irix_pwrite(int fd, char __user *buf, int cnt, int off64,
+ 			   int off1, int off2)
+ {
+ 	printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
+@@ -1638,7 +1614,7 @@ struct irix_statvfs64 {
+ 	u32  f_filler[16];
+ };
+ 
+-asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
++asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *buf)
+ {
+ 	struct nameidata nd;
+ 	struct kstatfs kbuf;
+@@ -1650,6 +1626,7 @@ asmlinkage int irix_statvfs64(char *fnam
+ 		error = -EFAULT;
+ 		goto out;
+ 	}
++
+ 	error = user_path_walk(fname, &nd);
+ 	if (error)
+ 		goto out;
+@@ -1657,27 +1634,25 @@ asmlinkage int irix_statvfs64(char *fnam
+ 	if (error)
+ 		goto dput_and_out;
+ 
+-	__put_user(kbuf.f_bsize, &buf->f_bsize);
+-	__put_user(kbuf.f_frsize, &buf->f_frsize);
+-	__put_user(kbuf.f_blocks, &buf->f_blocks);
+-	__put_user(kbuf.f_bfree, &buf->f_bfree);
+-	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
+-	__put_user(kbuf.f_files, &buf->f_files);
+-	__put_user(kbuf.f_ffree, &buf->f_ffree);
+-	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
++	error = __put_user(kbuf.f_bsize, &buf->f_bsize);
++	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
++	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
++	error |= __put_user(kbuf.f_files, &buf->f_files);
++	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
++	error |= __put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
+ #ifdef __MIPSEB__
+-	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
++	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ #else
+-	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
++	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ #endif
+ 	for(i = 0; i < 16; i++)
+-		__put_user(0, &buf->f_basetype[i]);
+-	__put_user(0, &buf->f_flag);
+-	__put_user(kbuf.f_namelen, &buf->f_namemax);
++		error |= __put_user(0, &buf->f_basetype[i]);
++	error |= __put_user(0, &buf->f_flag);
++	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
+ 	for(i = 0; i < 32; i++)
+-		__put_user(0, &buf->f_fstr[i]);
+-
+-	error = 0;
++		error |= __put_user(0, &buf->f_fstr[i]);
+ 
+ dput_and_out:
+ 	path_release(&nd);
+@@ -1685,7 +1660,7 @@ out:
+ 	return error;
+ }
+ 
+-asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
++asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf)
+ {
+ 	struct kstatfs kbuf;
+ 	struct file *file;
+@@ -1706,24 +1681,24 @@ asmlinkage int irix_fstatvfs64(int fd, s
+ 	if (error)
+ 		goto out_f;
+ 
+-	__put_user(kbuf.f_bsize, &buf->f_bsize);
+-	__put_user(kbuf.f_frsize, &buf->f_frsize);
+-	__put_user(kbuf.f_blocks, &buf->f_blocks);
+-	__put_user(kbuf.f_bfree, &buf->f_bfree);
+-	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
+-	__put_user(kbuf.f_files, &buf->f_files);
+-	__put_user(kbuf.f_ffree, &buf->f_ffree);
+-	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
++	error = __put_user(kbuf.f_bsize, &buf->f_bsize);
++	error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
++	error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
++	error |= __put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
++	error |= __put_user(kbuf.f_files, &buf->f_files);
++	error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
++	error |= __put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
+ #ifdef __MIPSEB__
+-	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
++	error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ #else
+-	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
++	error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ #endif
+ 	for(i = 0; i < 16; i++)
+-		__put_user(0, &buf->f_basetype[i]);
+-	__put_user(0, &buf->f_flag);
+-	__put_user(kbuf.f_namelen, &buf->f_namemax);
+-	__clear_user(buf->f_fstr, sizeof(buf->f_fstr[i]));
++		error |= __put_user(0, &buf->f_basetype[i]);
++	error |= __put_user(0, &buf->f_flag);
++	error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
++	error |= __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i])) ? -EFAULT : 0;
+ 
+ out_f:
+ 	fput(file);
+@@ -1731,9 +1706,9 @@ out:
+ 	return error;
+ }
+ 
+-asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
++asmlinkage int irix_getmountid(char __user *fname, unsigned long __user *midbuf)
+ {
+-	int err = 0;
++	int err;
+ 
+ 	printk("[%s:%d] irix_getmountid(%s, %p)\n",
+ 	       current->comm, current->pid, fname, midbuf);
+@@ -1746,7 +1721,7 @@ asmlinkage int irix_getmountid(char *fna
+ 	 * fsid of the filesystem to try and make the right decision, but
+ 	 * we don't have this so for now. XXX
+ 	 */
+-	err |= __put_user(0, &midbuf[0]);
++	err = __put_user(0, &midbuf[0]);
+ 	err |= __put_user(0, &midbuf[1]);
+ 	err |= __put_user(0, &midbuf[2]);
+ 	err |= __put_user(0, &midbuf[3]);
+@@ -1773,8 +1748,8 @@ struct irix_dirent32 {
+ };
+ 
+ struct irix_dirent32_callback {
+-	struct irix_dirent32 *current_dir;
+-	struct irix_dirent32 *previous;
++	struct irix_dirent32 __user *current_dir;
++	struct irix_dirent32 __user *previous;
+ 	int count;
+ 	int error;
+ };
+@@ -1782,13 +1757,13 @@ struct irix_dirent32_callback {
+ #define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))
+ #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
+ 
+-static int irix_filldir32(void *__buf, const char *name, int namlen,
+-                          loff_t offset, ino_t ino, unsigned int d_type)
++static int irix_filldir32(void *__buf, const char *name,
++	int namlen, loff_t offset, ino_t ino, unsigned int d_type)
+ {
+-	struct irix_dirent32 *dirent;
+-	struct irix_dirent32_callback *buf =
+-		 (struct irix_dirent32_callback *)__buf;
++	struct irix_dirent32 __user *dirent;
++	struct irix_dirent32_callback *buf = __buf;
+ 	unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
++	int err = 0;
+ 
+ #ifdef DEBUG_GETDENTS
+ 	printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
+@@ -1799,25 +1774,26 @@ static int irix_filldir32(void *__buf, c
+ 		return -EINVAL;
+ 	dirent = buf->previous;
+ 	if (dirent)
+-		__put_user(offset, &dirent->d_off);
++		err = __put_user(offset, &dirent->d_off);
+ 	dirent = buf->current_dir;
+-	buf->previous = dirent;
+-	__put_user(ino, &dirent->d_ino);
+-	__put_user(reclen, &dirent->d_reclen);
+-	copy_to_user(dirent->d_name, name, namlen);
+-	__put_user(0, &dirent->d_name[namlen]);
+-	((char *) dirent) += reclen;
++	err |= __put_user(dirent, &buf->previous);
++	err |= __put_user(ino, &dirent->d_ino);
++	err |= __put_user(reclen, &dirent->d_reclen);
++	err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;
++	err |= __put_user(0, &dirent->d_name[namlen]);
++	dirent = (struct irix_dirent32 __user *) ((char __user *) dirent + reclen);
++
+ 	buf->current_dir = dirent;
+ 	buf->count -= reclen;
+ 
+-	return 0;
++	return err;
+ }
+ 
+-asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
+-	unsigned int count, int *eob)
++asmlinkage int irix_ngetdents(unsigned int fd, void __user * dirent,
++	unsigned int count, int __user *eob)
+ {
+ 	struct file *file;
+-	struct irix_dirent32 *lastdirent;
++	struct irix_dirent32 __user *lastdirent;
+ 	struct irix_dirent32_callback buf;
+ 	int error;
+ 
+@@ -1830,7 +1806,7 @@ asmlinkage int irix_ngetdents(unsigned i
+ 	if (!file)
+ 		goto out;
+ 
+-	buf.current_dir = (struct irix_dirent32 *) dirent;
++	buf.current_dir = (struct irix_dirent32 __user *) dirent;
+ 	buf.previous = NULL;
+ 	buf.count = count;
+ 	buf.error = 0;
+@@ -1870,8 +1846,8 @@ struct irix_dirent64 {
+ };
+ 
+ struct irix_dirent64_callback {
+-	struct irix_dirent64 *curr;
+-	struct irix_dirent64 *previous;
++	struct irix_dirent64 __user *curr;
++	struct irix_dirent64 __user *previous;
+ 	int count;
+ 	int error;
+ };
+@@ -1879,37 +1855,44 @@ struct irix_dirent64_callback {
+ #define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))
+ #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
+ 
+-static int irix_filldir64(void * __buf, const char * name, int namlen,
+-			  loff_t offset, ino_t ino, unsigned int d_type)
++static int irix_filldir64(void *__buf, const char *name,
++	int namlen, loff_t offset, ino_t ino, unsigned int d_type)
+ {
+-	struct irix_dirent64 *dirent;
+-	struct irix_dirent64_callback * buf =
+-		(struct irix_dirent64_callback *) __buf;
++	struct irix_dirent64 __user *dirent;
++	struct irix_dirent64_callback * buf = __buf;
+ 	unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
++	int err = 0;
+ 
+-	buf->error = -EINVAL;	/* only used if we fail.. */
++	if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
++		return -EFAULT;
++
++	if (__put_user(-EINVAL, &buf->error))	/* only used if we fail.. */
++		return -EFAULT;
+ 	if (reclen > buf->count)
+ 		return -EINVAL;
+ 	dirent = buf->previous;
+ 	if (dirent)
+-		__put_user(offset, &dirent->d_off);
++		err = __put_user(offset, &dirent->d_off);
+ 	dirent = buf->curr;
+ 	buf->previous = dirent;
+-	__put_user(ino, &dirent->d_ino);
+-	__put_user(reclen, &dirent->d_reclen);
+-	__copy_to_user(dirent->d_name, name, namlen);
+-	__put_user(0, &dirent->d_name[namlen]);
+-	((char *) dirent) += reclen;
++	err |= __put_user(ino, &dirent->d_ino);
++	err |= __put_user(reclen, &dirent->d_reclen);
++	err |= __copy_to_user((char __user *)dirent->d_name, name, namlen)
++	       ? -EFAULT : 0;
++	err |= __put_user(0, &dirent->d_name[namlen]);
++
++	dirent = (struct irix_dirent64 __user *) ((char __user *) dirent + reclen);
++
+ 	buf->curr = dirent;
+ 	buf->count -= reclen;
+ 
+-	return 0;
++	return err;
+ }
+ 
+-asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
++asmlinkage int irix_getdents64(int fd, void __user *dirent, int cnt)
+ {
+ 	struct file *file;
+-	struct irix_dirent64 *lastdirent;
++	struct irix_dirent64 __user *lastdirent;
+ 	struct irix_dirent64_callback buf;
+ 	int error;
+ 
+@@ -1929,7 +1912,7 @@ asmlinkage int irix_getdents64(int fd, v
+ 	if (cnt < (sizeof(struct irix_dirent64) + 255))
+ 		goto out_f;
+ 
+-	buf.curr = (struct irix_dirent64 *) dirent;
++	buf.curr = (struct irix_dirent64 __user *) dirent;
+ 	buf.previous = NULL;
+ 	buf.count = cnt;
+ 	buf.error = 0;
+@@ -1941,7 +1924,8 @@ asmlinkage int irix_getdents64(int fd, v
+ 		error = buf.error;
+ 		goto out_f;
+ 	}
+-	lastdirent->d_off = (u64) file->f_pos;
++	if (put_user(file->f_pos, &lastdirent->d_off))
++		return -EFAULT;
+ #ifdef DEBUG_GETDENTS
+ 	printk("returning %d\n", cnt - buf.count);
+ #endif
+@@ -1953,10 +1937,10 @@ out:
+ 	return error;
+ }
+ 
+-asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
++asmlinkage int irix_ngetdents64(int fd, void __user *dirent, int cnt, int *eob)
+ {
+ 	struct file *file;
+-	struct irix_dirent64 *lastdirent;
++	struct irix_dirent64 __user *lastdirent;
+ 	struct irix_dirent64_callback buf;
+ 	int error;
+ 
+@@ -1978,7 +1962,7 @@ asmlinkage int irix_ngetdents64(int fd, 
+ 		goto out_f;
+ 
+ 	*eob = 0;
+-	buf.curr = (struct irix_dirent64 *) dirent;
++	buf.curr = (struct irix_dirent64 __user *) dirent;
+ 	buf.previous = NULL;
+ 	buf.count = cnt;
+ 	buf.error = 0;
+@@ -1990,7 +1974,8 @@ asmlinkage int irix_ngetdents64(int fd, 
+ 		error = buf.error;
+ 		goto out_f;
+ 	}
+-	lastdirent->d_off = (u64) file->f_pos;
++	if (put_user(file->f_pos, &lastdirent->d_off))
++		return -EFAULT;
+ #ifdef DEBUG_GETDENTS
+ 	printk("eob=%d returning %d\n", *eob, cnt - buf.count);
+ #endif
+@@ -2053,14 +2038,14 @@ out:
+ 	return retval;
+ }
+ 
+-asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf)
++asmlinkage int irix_utssys(char __user *inbuf, int arg, int type, char __user *outbuf)
+ {
+ 	int retval;
+ 
+ 	switch(type) {
+ 	case 0:
+ 		/* uname() */
+-		retval = irix_uname((struct iuname *)inbuf);
++		retval = irix_uname((struct iuname __user *)inbuf);
+ 		goto out;
+ 
+ 	case 2:
+diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
+--- a/arch/mips/kernel/time.c
++++ b/arch/mips/kernel/time.c
+@@ -11,6 +11,7 @@
+  * Free Software Foundation;  either version 2 of the  License, or (at your
+  * option) any later version.
+  */
++#include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -25,6 +26,7 @@
+ #include <linux/module.h>
+ 
+ #include <asm/bootinfo.h>
++#include <asm/cache.h>
+ #include <asm/compiler.h>
+ #include <asm/cpu.h>
+ #include <asm/cpu-features.h>
+@@ -43,10 +45,6 @@
+ 
+ #define TICK_SIZE	(tick_nsec / 1000)
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ /*
+  * forward reference
+  */
+@@ -76,7 +74,7 @@ int (*rtc_set_mmss)(unsigned long);
+ static unsigned int sll32_usecs_per_cycle;
+ 
+ /* how many counter cycles in a jiffy */
+-static unsigned long cycles_per_jiffy;
++static unsigned long cycles_per_jiffy __read_mostly;
+ 
+ /* Cycle counter value at the previous timer interrupt.. */
+ static unsigned int timerhi, timerlo;
+@@ -98,7 +96,10 @@ static unsigned int null_hpt_read(void)
+ 	return 0;
+ }
+ 
+-static void null_hpt_init(unsigned int count) { /* nothing */ }
++static void null_hpt_init(unsigned int count)
++{
++	/* nothing */
++}
+ 
+ 
+ /*
+@@ -108,8 +109,10 @@ static void c0_timer_ack(void)
+ {
+ 	unsigned int count;
+ 
++#ifndef CONFIG_SOC_PNX8550	/* pnx8550 resets to zero */
+ 	/* Ack this timer interrupt and set the next one.  */
+ 	expirelo += cycles_per_jiffy;
++#endif
+ 	write_c0_compare(expirelo);
+ 
+ 	/* Check to see if we have missed any timer interrupts.  */
+@@ -224,7 +227,6 @@ int do_settimeofday(struct timespec *tv)
+ 	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+ 
+ 	ntp_clear();
+-
+ 	write_sequnlock_irq(&xtime_lock);
+ 	clock_was_set();
+ 	return 0;
+diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -9,7 +9,7 @@
+  * Copyright (C) 1999 Silicon Graphics, Inc.
+  * Kevin D. Kissell, kevink at mips.com and Carsten Langgaard, carstenl at mips.com
+  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
+- * Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
++ * Copyright (C) 2002, 2003, 2004, 2005  Maciej W. Rozycki
+  */
+ #include <linux/config.h>
+ #include <linux/init.h>
+@@ -20,12 +20,16 @@
+ #include <linux/smp_lock.h>
+ #include <linux/spinlock.h>
+ #include <linux/kallsyms.h>
++#include <linux/bootmem.h>
+ 
+ #include <asm/bootinfo.h>
+ #include <asm/branch.h>
+ #include <asm/break.h>
+ #include <asm/cpu.h>
++#include <asm/dsp.h>
+ #include <asm/fpu.h>
++#include <asm/mipsregs.h>
++#include <asm/mipsmtregs.h>
+ #include <asm/module.h>
+ #include <asm/pgtable.h>
+ #include <asm/ptrace.h>
+@@ -54,14 +58,19 @@ extern asmlinkage void handle_tr(void);
+ extern asmlinkage void handle_fpe(void);
+ extern asmlinkage void handle_mdmx(void);
+ extern asmlinkage void handle_watch(void);
++extern asmlinkage void handle_mt(void);
++extern asmlinkage void handle_dsp(void);
+ extern asmlinkage void handle_mcheck(void);
+ extern asmlinkage void handle_reserved(void);
+ 
+-extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
++extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
+ 	struct mips_fpu_soft_struct *ctx);
+ 
+ void (*board_be_init)(void);
+ int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
++void (*board_nmi_handler_setup)(void);
++void (*board_ejtag_handler_setup)(void);
++void (*board_bind_eic_interrupt)(int irq, int regset);
+ 
+ /*
+  * These constant is for searching for possible module text segments.
+@@ -201,32 +210,47 @@ void show_regs(struct pt_regs *regs)
+ 
+ 	printk("Status: %08x    ", (uint32_t) regs->cp0_status);
+ 
+-	if (regs->cp0_status & ST0_KX)
+-		printk("KX ");
+-	if (regs->cp0_status & ST0_SX)
+-		printk("SX ");
+-	if (regs->cp0_status & ST0_UX)
+-		printk("UX ");
+-	switch (regs->cp0_status & ST0_KSU) {
+-	case KSU_USER:
+-		printk("USER ");
+-		break;
+-	case KSU_SUPERVISOR:
+-		printk("SUPERVISOR ");
+-		break;
+-	case KSU_KERNEL:
+-		printk("KERNEL ");
+-		break;
+-	default:
+-		printk("BAD_MODE ");
+-		break;
++	if (current_cpu_data.isa_level == MIPS_CPU_ISA_I) {
++		if (regs->cp0_status & ST0_KUO)
++			printk("KUo ");
++		if (regs->cp0_status & ST0_IEO)
++			printk("IEo ");
++		if (regs->cp0_status & ST0_KUP)
++			printk("KUp ");
++		if (regs->cp0_status & ST0_IEP)
++			printk("IEp ");
++		if (regs->cp0_status & ST0_KUC)
++			printk("KUc ");
++		if (regs->cp0_status & ST0_IEC)
++			printk("IEc ");
++	} else {
++		if (regs->cp0_status & ST0_KX)
++			printk("KX ");
++		if (regs->cp0_status & ST0_SX)
++			printk("SX ");
++		if (regs->cp0_status & ST0_UX)
++			printk("UX ");
++		switch (regs->cp0_status & ST0_KSU) {
++		case KSU_USER:
++			printk("USER ");
++			break;
++		case KSU_SUPERVISOR:
++			printk("SUPERVISOR ");
++			break;
++		case KSU_KERNEL:
++			printk("KERNEL ");
++			break;
++		default:
++			printk("BAD_MODE ");
++			break;
++		}
++		if (regs->cp0_status & ST0_ERL)
++			printk("ERL ");
++		if (regs->cp0_status & ST0_EXL)
++			printk("EXL ");
++		if (regs->cp0_status & ST0_IE)
++			printk("IE ");
+ 	}
+-	if (regs->cp0_status & ST0_ERL)
+-		printk("ERL ");
+-	if (regs->cp0_status & ST0_EXL)
+-		printk("EXL ");
+-	if (regs->cp0_status & ST0_IE)
+-		printk("IE ");
+ 	printk("\n");
+ 
+ 	printk("Cause : %08x\n", cause);
+@@ -252,29 +276,18 @@ void show_registers(struct pt_regs *regs
+ 
+ static DEFINE_SPINLOCK(die_lock);
+ 
+-NORET_TYPE void __die(const char * str, struct pt_regs * regs,
+-	const char * file, const char * func, unsigned long line)
++NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs)
+ {
+ 	static int die_counter;
+ 
+ 	console_verbose();
+ 	spin_lock_irq(&die_lock);
+-	printk("%s", str);
+-	if (file && func)
+-		printk(" in %s:%s, line %ld", file, func, line);
+-	printk("[#%d]:\n", ++die_counter);
++	printk("%s[#%d]:\n", str, ++die_counter);
+ 	show_registers(regs);
+ 	spin_unlock_irq(&die_lock);
+ 	do_exit(SIGSEGV);
+ }
+ 
+-void __die_if_kernel(const char * str, struct pt_regs * regs,
+-		     const char * file, const char * func, unsigned long line)
+-{
+-	if (!user_mode(regs))
+-		__die(str, regs, file, func, line);
+-}
+-
+ extern const struct exception_table_entry __start___dbe_table[];
+ extern const struct exception_table_entry __stop___dbe_table[];
+ 
+@@ -339,9 +352,9 @@ asmlinkage void do_be(struct pt_regs *re
+ 
+ static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
+ {
+-	unsigned int *epc;
++	unsigned int __user *epc;
+ 
+-	epc = (unsigned int *) regs->cp0_epc +
++	epc = (unsigned int __user *) regs->cp0_epc +
+ 	      ((regs->cp0_cause & CAUSEF_BD) != 0);
+ 	if (!get_user(*opcode, epc))
+ 		return 0;
+@@ -360,6 +373,10 @@ static inline int get_insn_opcode(struct
+ #define OFFSET 0x0000ffff
+ #define LL     0xc0000000
+ #define SC     0xe0000000
++#define SPEC3  0x7c000000
++#define RD     0x0000f800
++#define FUNC   0x0000003f
++#define RDHWR  0x0000003b
+ 
+ /*
+  * The ll_bit is cleared by r*_switch.S
+@@ -371,7 +388,7 @@ static struct task_struct *ll_task = NUL
+ 
+ static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
+ {
+-	unsigned long value, *vaddr;
++	unsigned long value, __user *vaddr;
+ 	long offset;
+ 	int signal = 0;
+ 
+@@ -385,7 +402,8 @@ static inline void simulate_ll(struct pt
+ 	offset <<= 16;
+ 	offset >>= 16;
+ 
+-	vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
++	vaddr = (unsigned long __user *)
++	        ((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+ 
+ 	if ((unsigned long)vaddr & 3) {
+ 		signal = SIGBUS;
+@@ -407,9 +425,10 @@ static inline void simulate_ll(struct pt
+ 
+ 	preempt_enable();
+ 
++	compute_return_epc(regs);
++
+ 	regs->regs[(opcode & RT) >> 16] = value;
+ 
+-	compute_return_epc(regs);
+ 	return;
+ 
+ sig:
+@@ -418,7 +437,8 @@ sig:
+ 
+ static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
+ {
+-	unsigned long *vaddr, reg;
++	unsigned long __user *vaddr;
++	unsigned long reg;
+ 	long offset;
+ 	int signal = 0;
+ 
+@@ -432,7 +452,8 @@ static inline void simulate_sc(struct pt
+ 	offset <<= 16;
+ 	offset >>= 16;
+ 
+-	vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
++	vaddr = (unsigned long __user *)
++	        ((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+ 	reg = (opcode & RT) >> 16;
+ 
+ 	if ((unsigned long)vaddr & 3) {
+@@ -443,9 +464,9 @@ static inline void simulate_sc(struct pt
+ 	preempt_disable();
+ 
+ 	if (ll_bit == 0 || ll_task != current) {
++		compute_return_epc(regs);
+ 		regs->regs[reg] = 0;
+ 		preempt_enable();
+-		compute_return_epc(regs);
+ 		return;
+ 	}
+ 
+@@ -456,9 +477,9 @@ static inline void simulate_sc(struct pt
+ 		goto sig;
+ 	}
+ 
++	compute_return_epc(regs);
+ 	regs->regs[reg] = 1;
+ 
+-	compute_return_epc(regs);
+ 	return;
+ 
+ sig:
+@@ -491,6 +512,37 @@ static inline int simulate_llsc(struct p
+ 	return -EFAULT;			/* Strange things going on ... */
+ }
+ 
++/*
++ * Simulate trapping 'rdhwr' instructions to provide user accessible
++ * registers not implemented in hardware.  The only current use of this
++ * is the thread area pointer.
++ */
++static inline int simulate_rdhwr(struct pt_regs *regs)
++{
++	struct thread_info *ti = current->thread_info;
++	unsigned int opcode;
++
++	if (unlikely(get_insn_opcode(regs, &opcode)))
++		return -EFAULT;
++
++	if (unlikely(compute_return_epc(regs)))
++		return -EFAULT;
++
++	if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) {
++		int rd = (opcode & RD) >> 11;
++		int rt = (opcode & RT) >> 16;
++		switch (rd) {
++			case 29:
++				regs->regs[rt] = ti->tp_value;
++				break;
++			default:
++				return -EFAULT;
++		}
++	}
++
++	return 0;
++}
++
+ asmlinkage void do_ov(struct pt_regs *regs)
+ {
+ 	siginfo_t info;
+@@ -498,7 +550,7 @@ asmlinkage void do_ov(struct pt_regs *re
+ 	info.si_code = FPE_INTOVF;
+ 	info.si_signo = SIGFPE;
+ 	info.si_errno = 0;
+-	info.si_addr = (void *)regs->cp0_epc;
++	info.si_addr = (void __user *) regs->cp0_epc;
+ 	force_sig_info(SIGFPE, &info, current);
+ }
+ 
+@@ -512,6 +564,14 @@ asmlinkage void do_fpe(struct pt_regs *r
+ 
+ 		preempt_disable();
+ 
++#ifdef CONFIG_PREEMPT
++		if (!is_fpu_owner()) {
++			/* We might lose fpu before disabling preempt... */
++			own_fpu();
++			BUG_ON(!used_math());
++			restore_fp(current);
++		}
++#endif
+ 		/*
+ 	 	 * Unimplemented operation exception.  If we've got the full
+ 		 * software emulator on-board, let's use it...
+@@ -523,11 +583,18 @@ asmlinkage void do_fpe(struct pt_regs *r
+ 		 * a bit extreme for what should be an infrequent event.
+ 		 */
+ 		save_fp(current);
++		/* Ensure 'resume' not overwrite saved fp context again. */
++		lose_fpu();
++
++		preempt_enable();
+ 
+ 		/* Run the emulator */
+-		sig = fpu_emulator_cop1Handler (0, regs,
++		sig = fpu_emulator_cop1Handler (regs,
+ 			&current->thread.fpu.soft);
+ 
++		preempt_disable();
++
++		own_fpu();	/* Using the FPU again.  */
+ 		/*
+ 		 * We can't allow the emulated instruction to leave any of
+ 		 * the cause bit set in $fcr31.
+@@ -584,7 +651,7 @@ asmlinkage void do_bp(struct pt_regs *re
+ 			info.si_code = FPE_INTOVF;
+ 		info.si_signo = SIGFPE;
+ 		info.si_errno = 0;
+-		info.si_addr = (void *)regs->cp0_epc;
++		info.si_addr = (void __user *) regs->cp0_epc;
+ 		force_sig_info(SIGFPE, &info, current);
+ 		break;
+ 	default:
+@@ -621,7 +688,7 @@ asmlinkage void do_tr(struct pt_regs *re
+ 			info.si_code = FPE_INTOVF;
+ 		info.si_signo = SIGFPE;
+ 		info.si_errno = 0;
+-		info.si_addr = (void *)regs->cp0_epc;
++		info.si_addr = (void __user *) regs->cp0_epc;
+ 		force_sig_info(SIGFPE, &info, current);
+ 		break;
+ 	default:
+@@ -637,6 +704,9 @@ asmlinkage void do_ri(struct pt_regs *re
+ 		if (!simulate_llsc(regs))
+ 			return;
+ 
++	if (!simulate_rdhwr(regs))
++		return;
++
+ 	force_sig(SIGILL, current);
+ }
+ 
+@@ -650,11 +720,13 @@ asmlinkage void do_cpu(struct pt_regs *r
+ 
+ 	switch (cpid) {
+ 	case 0:
+-		if (cpu_has_llsc)
+-			break;
++		if (!cpu_has_llsc)
++			if (!simulate_llsc(regs))
++				return;
+ 
+-		if (!simulate_llsc(regs))
++		if (!simulate_rdhwr(regs))
+ 			return;
++
+ 		break;
+ 
+ 	case 1:
+@@ -668,15 +740,15 @@ asmlinkage void do_cpu(struct pt_regs *r
+ 			set_used_math();
+ 		}
+ 
++		preempt_enable();
++
+ 		if (!cpu_has_fpu) {
+-			int sig = fpu_emulator_cop1Handler(0, regs,
++			int sig = fpu_emulator_cop1Handler(regs,
+ 						&current->thread.fpu.soft);
+ 			if (sig)
+ 				force_sig(sig, current);
+ 		}
+ 
+-		preempt_enable();
+-
+ 		return;
+ 
+ 	case 2:
+@@ -716,6 +788,22 @@ asmlinkage void do_mcheck(struct pt_regs
+ 	      (regs->cp0_status & ST0_TS) ? "" : "not ");
+ }
+ 
++asmlinkage void do_mt(struct pt_regs *regs)
++{
++	die_if_kernel("MIPS MT Thread exception in kernel", regs);
++
++	force_sig(SIGILL, current);
++}
++
++
++asmlinkage void do_dsp(struct pt_regs *regs)
++{
++	if (cpu_has_dsp)
++		panic("Unexpected DSP exception\n");
++
++	force_sig(SIGILL, current);
++}
++
+ asmlinkage void do_reserved(struct pt_regs *regs)
+ {
+ 	/*
+@@ -728,6 +816,12 @@ asmlinkage void do_reserved(struct pt_re
+ 	      (regs->cp0_cause & 0x7f) >> 2);
+ }
+ 
++asmlinkage void do_default_vi(struct pt_regs *regs)
++{
++	show_regs(regs);
++	panic("Caught unexpected vectored interrupt.");
++}
++
+ /*
+  * Some MIPS CPUs can enable/disable for cache parity detection, but do
+  * it different ways.
+@@ -736,16 +830,12 @@ static inline void parity_protection_ini
+ {
+ 	switch (current_cpu_data.cputype) {
+ 	case CPU_24K:
+-		/* 24K cache parity not currently implemented in FPGA */
+-		printk(KERN_INFO "Disable cache parity protection for "
+-		       "MIPS 24K CPU.\n");
+-		write_c0_ecc(read_c0_ecc() & ~0x80000000);
+-		break;
+ 	case CPU_5KC:
+-		/* Set the PE bit (bit 31) in the c0_ecc register. */
+-		printk(KERN_INFO "Enable cache parity protection for "
+-		       "MIPS 5KC/24K CPUs.\n");
+-		write_c0_ecc(read_c0_ecc() | 0x80000000);
++		write_c0_ecc(0x80000000);
++		back_to_back_c0_hazard();
++		/* Set the PE bit (bit 31) in the c0_errctl register. */
++		printk(KERN_INFO "Cache parity protection %sabled\n",
++		       (read_c0_ecc() & 0x80000000) ? "en" : "dis");
+ 		break;
+ 	case CPU_20KC:
+ 	case CPU_25KF:
+@@ -783,7 +873,7 @@ asmlinkage void cache_parity_error(void)
+ 	       reg_val & (1<<22) ? "E0 " : "");
+ 	printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
+ 
+-#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64)
++#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ 	if (reg_val & (1<<22))
+ 		printk("DErrAddr0: 0x%0*lx\n", field, read_c0_derraddr0());
+ 
+@@ -840,7 +930,11 @@ void nmi_exception_handler(struct pt_reg
+ 	while(1) ;
+ }
+ 
++#define VECTORSPACING 0x100	/* for EI/VI mode */
++
++unsigned long ebase;
+ unsigned long exception_handlers[32];
++unsigned long vi_handlers[64];
+ 
+ /*
+  * As a side effect of the way this is implemented we're limited
+@@ -854,13 +948,156 @@ void *set_except_vector(int n, void *add
+ 
+ 	exception_handlers[n] = handler;
+ 	if (n == 0 && cpu_has_divec) {
+-		*(volatile u32 *)(CAC_BASE + 0x200) = 0x08000000 |
++		*(volatile u32 *)(ebase + 0x200) = 0x08000000 |
+ 		                                 (0x03ffffff & (handler >> 2));
+-		flush_icache_range(CAC_BASE + 0x200, CAC_BASE + 0x204);
++		flush_icache_range(ebase + 0x200, ebase + 0x204);
++	}
++	return (void *)old_handler;
++}
++
++#ifdef CONFIG_CPU_MIPSR2
++/*
++ * Shadow register allocation
++ * FIXME: SMP...
++ */
++
++/* MIPSR2 shadow register sets */
++struct shadow_registers {
++	spinlock_t sr_lock;	/*  */
++	int sr_supported;	/* Number of shadow register sets supported */
++	int sr_allocated;	/* Bitmap of allocated shadow registers */
++} shadow_registers;
++
++void mips_srs_init(void)
++{
++#ifdef CONFIG_CPU_MIPSR2_SRS
++	shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
++	printk ("%d MIPSR2 register sets available\n", shadow_registers.sr_supported);
++#else
++	shadow_registers.sr_supported = 1;
++#endif
++	shadow_registers.sr_allocated = 1;	/* Set 0 used by kernel */
++	spin_lock_init(&shadow_registers.sr_lock);
++}
++
++int mips_srs_max(void)
++{
++	return shadow_registers.sr_supported;
++}
++
++int mips_srs_alloc (void)
++{
++	struct shadow_registers *sr = &shadow_registers;
++	unsigned long flags;
++	int set;
++
++	spin_lock_irqsave(&sr->sr_lock, flags);
++
++	for (set = 0; set < sr->sr_supported; set++) {
++		if ((sr->sr_allocated & (1 << set)) == 0) {
++			sr->sr_allocated |= 1 << set;
++			spin_unlock_irqrestore(&sr->sr_lock, flags);
++			return set;
++		}
+ 	}
++
++	/* None available */
++	spin_unlock_irqrestore(&sr->sr_lock, flags);
++	return -1;
++}
++
++void mips_srs_free (int set)
++{
++	struct shadow_registers *sr = &shadow_registers;
++	unsigned long flags;
++
++	spin_lock_irqsave(&sr->sr_lock, flags);
++	sr->sr_allocated &= ~(1 << set);
++	spin_unlock_irqrestore(&sr->sr_lock, flags);
++}
++
++void *set_vi_srs_handler (int n, void *addr, int srs)
++{
++	unsigned long handler;
++	unsigned long old_handler = vi_handlers[n];
++	u32 *w;
++	unsigned char *b;
++
++	if (!cpu_has_veic && !cpu_has_vint)
++		BUG();
++
++	if (addr == NULL) {
++		handler = (unsigned long) do_default_vi;
++		srs = 0;
++	}
++	else
++		handler = (unsigned long) addr;
++	vi_handlers[n] = (unsigned long) addr;
++
++	b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);
++
++	if (srs >= mips_srs_max())
++		panic("Shadow register set %d not supported", srs);
++
++	if (cpu_has_veic) {
++		if (board_bind_eic_interrupt)
++			board_bind_eic_interrupt (n, srs);
++	}
++	else if (cpu_has_vint) {
++		/* SRSMap is only defined if shadow sets are implemented */
++		if (mips_srs_max() > 1)
++			change_c0_srsmap (0xf << n*4, srs << n*4);
++	}
++
++	if (srs == 0) {
++		/*
++		 * If no shadow set is selected then use the default handler
++		 * that does normal register saving and a standard interrupt exit
++		 */
++
++		extern char except_vec_vi, except_vec_vi_lui;
++		extern char except_vec_vi_ori, except_vec_vi_end;
++		const int handler_len = &except_vec_vi_end - &except_vec_vi;
++		const int lui_offset = &except_vec_vi_lui - &except_vec_vi;
++		const int ori_offset = &except_vec_vi_ori - &except_vec_vi;
++
++		if (handler_len > VECTORSPACING) {
++			/*
++			 * Sigh... panicing won't help as the console
++			 * is probably not configured :(
++			 */
++			panic ("VECTORSPACING too small");
++		}
++
++		memcpy (b, &except_vec_vi, handler_len);
++		w = (u32 *)(b + lui_offset);
++		*w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff);
++		w = (u32 *)(b + ori_offset);
++		*w = (*w & 0xffff0000) | ((u32)handler & 0xffff);
++		flush_icache_range((unsigned long)b, (unsigned long)(b+handler_len));
++	}
++	else {
++		/*
++		 * In other cases jump directly to the interrupt handler
++		 *
++		 * It is the handlers responsibility to save registers if required
++		 * (eg hi/lo) and return from the exception using "eret"
++		 */
++		w = (u32 *)b;
++		*w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */
++		*w = 0;
++		flush_icache_range((unsigned long)b, (unsigned long)(b+8));
++	}
++
+ 	return (void *)old_handler;
+ }
+ 
++void *set_vi_handler (int n, void *addr)
++{
++	return set_vi_srs_handler (n, addr, 0);
++}
++#endif
++
+ /*
+  * This is used by native signal handling
+  */
+@@ -912,6 +1149,7 @@ static inline void signal32_init(void)
+ 
+ extern void cpu_cache_init(void);
+ extern void tlb_init(void);
++extern void flush_tlb_handlers(void);
+ 
+ void __init per_cpu_trap_init(void)
+ {
+@@ -929,15 +1167,32 @@ void __init per_cpu_trap_init(void)
+ #endif
+ 	if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV)
+ 		status_set |= ST0_XX;
+-	change_c0_status(ST0_CU|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
++	change_c0_status(ST0_CU|ST0_MX|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
+ 			 status_set);
+ 
++	if (cpu_has_dsp)
++		set_c0_status(ST0_MX);
++
++#ifdef CONFIG_CPU_MIPSR2
++	write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */
++#endif
++
+ 	/*
+-	 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+-	 * interrupt processing overhead.  Use it where available.
++	 * Interrupt handling.
+ 	 */
+-	if (cpu_has_divec)
+-		set_c0_cause(CAUSEF_IV);
++	if (cpu_has_veic || cpu_has_vint) {
++		write_c0_ebase (ebase);
++		/* Setting vector spacing enables EI/VI mode  */
++		change_c0_intctl (0x3e0, VECTORSPACING);
++	}
++	if (cpu_has_divec) {
++		if (cpu_has_mipsmt) {
++			unsigned int vpflags = dvpe();
++			set_c0_cause(CAUSEF_IV);
++			evpe(vpflags);
++		} else
++			set_c0_cause(CAUSEF_IV);
++	}
+ 
+ 	cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
+ 	TLBMISS_HANDLER_SETUP();
+@@ -951,13 +1206,41 @@ void __init per_cpu_trap_init(void)
+ 	tlb_init();
+ }
+ 
++/* Install CPU exception handler */
++void __init set_handler (unsigned long offset, void *addr, unsigned long size)
++{
++	memcpy((void *)(ebase + offset), addr, size);
++	flush_icache_range(ebase + offset, ebase + offset + size);
++}
++
++/* Install uncached CPU exception handler */
++void __init set_uncached_handler (unsigned long offset, void *addr, unsigned long size)
++{
++#ifdef CONFIG_32BIT
++	unsigned long uncached_ebase = KSEG1ADDR(ebase);
++#endif
++#ifdef CONFIG_64BIT
++	unsigned long uncached_ebase = TO_UNCAC(ebase);
++#endif
++
++	memcpy((void *)(uncached_ebase + offset), addr, size);
++}
++
+ void __init trap_init(void)
+ {
+ 	extern char except_vec3_generic, except_vec3_r4000;
+-	extern char except_vec_ejtag_debug;
+ 	extern char except_vec4;
+ 	unsigned long i;
+ 
++	if (cpu_has_veic || cpu_has_vint)
++		ebase = (unsigned long) alloc_bootmem_low_pages (0x200 + VECTORSPACING*64);
++	else
++		ebase = CAC_BASE;
++
++#ifdef CONFIG_CPU_MIPSR2
++	mips_srs_init();
++#endif
++
+ 	per_cpu_trap_init();
+ 
+ 	/*
+@@ -965,7 +1248,7 @@ void __init trap_init(void)
+ 	 * This will be overriden later as suitable for a particular
+ 	 * configuration.
+ 	 */
+-	memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
++	set_handler(0x180, &except_vec3_generic, 0x80);
+ 
+ 	/*
+ 	 * Setup default vectors
+@@ -977,8 +1260,8 @@ void __init trap_init(void)
+ 	 * Copy the EJTAG debug exception vector handler code to it's final
+ 	 * destination.
+ 	 */
+-	if (cpu_has_ejtag)
+-		memcpy((void *)(CAC_BASE + 0x300), &except_vec_ejtag_debug, 0x80);
++	if (cpu_has_ejtag && board_ejtag_handler_setup)
++		board_ejtag_handler_setup ();
+ 
+ 	/*
+ 	 * Only some CPUs have the watch exceptions.
+@@ -987,11 +1270,15 @@ void __init trap_init(void)
+ 		set_except_vector(23, handle_watch);
+ 
+ 	/*
+-	 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+-	 * interrupt processing overhead.  Use it where available.
++	 * Initialise interrupt handlers
+ 	 */
+-	if (cpu_has_divec)
+-		memcpy((void *)(CAC_BASE + 0x200), &except_vec4, 0x8);
++	if (cpu_has_veic || cpu_has_vint) {
++		int nvec = cpu_has_veic ? 64 : 8;
++		for (i = 0; i < nvec; i++)
++			set_vi_handler (i, NULL);
++	}
++	else if (cpu_has_divec)
++		set_handler(0x200, &except_vec4, 0x8);
+ 
+ 	/*
+ 	 * Some CPUs can enable/disable for cache parity detection, but does
+@@ -1023,21 +1310,6 @@ void __init trap_init(void)
+ 	set_except_vector(11, handle_cpu);
+ 	set_except_vector(12, handle_ov);
+ 	set_except_vector(13, handle_tr);
+-	set_except_vector(22, handle_mdmx);
+-
+-	if (cpu_has_fpu && !cpu_has_nofpuex)
+-		set_except_vector(15, handle_fpe);
+-
+-	if (cpu_has_mcheck)
+-		set_except_vector(24, handle_mcheck);
+-
+-	if (cpu_has_vce)
+-		/* Special exception: R4[04]00 uses also the divec space. */
+-		memcpy((void *)(CAC_BASE + 0x180), &except_vec3_r4000, 0x100);
+-	else if (cpu_has_4kex)
+-		memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
+-	else
+-		memcpy((void *)(CAC_BASE + 0x080), &except_vec3_generic, 0x80);
+ 
+ 	if (current_cpu_data.cputype == CPU_R6000 ||
+ 	    current_cpu_data.cputype == CPU_R6000A) {
+@@ -1053,10 +1325,37 @@ void __init trap_init(void)
+ 		//set_except_vector(15, handle_ndc);
+ 	}
+ 
++
++	if (board_nmi_handler_setup)
++		board_nmi_handler_setup();
++
++	if (cpu_has_fpu && !cpu_has_nofpuex)
++		set_except_vector(15, handle_fpe);
++
++	set_except_vector(22, handle_mdmx);
++
++	if (cpu_has_mcheck)
++		set_except_vector(24, handle_mcheck);
++
++	if (cpu_has_mipsmt)
++		set_except_vector(25, handle_mt);
++
++	if (cpu_has_dsp)
++		set_except_vector(26, handle_dsp);
++
++	if (cpu_has_vce)
++		/* Special exception: R4[04]00 uses also the divec space. */
++		memcpy((void *)(CAC_BASE + 0x180), &except_vec3_r4000, 0x100);
++	else if (cpu_has_4kex)
++		memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
++	else
++		memcpy((void *)(CAC_BASE + 0x080), &except_vec3_generic, 0x80);
++
+ 	signal_init();
+ #ifdef CONFIG_MIPS32_COMPAT
+ 	signal32_init();
+ #endif
+ 
+-	flush_icache_range(CAC_BASE, CAC_BASE + 0x400);
++	flush_icache_range(ebase, ebase + 0x400);
++	flush_tlb_handlers();
+ }
+diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
+--- a/arch/mips/kernel/unaligned.c
++++ b/arch/mips/kernel/unaligned.c
+@@ -94,7 +94,7 @@ unsigned long unaligned_instructions;
+ #endif
+ 
+ static inline int emulate_load_store_insn(struct pt_regs *regs,
+-	void *addr, unsigned long pc,
++	void __user *addr, unsigned int __user *pc,
+ 	unsigned long **regptr, unsigned long *newvalue)
+ {
+ 	union mips_instruction insn;
+@@ -107,7 +107,7 @@ static inline int emulate_load_store_ins
+ 	/*
+ 	 * This load never faults.
+ 	 */
+-	__get_user(insn.word, (unsigned int *)pc);
++	__get_user(insn.word, pc);
+ 
+ 	switch (insn.i_format.opcode) {
+ 	/*
+@@ -494,8 +494,8 @@ asmlinkage void do_ade(struct pt_regs *r
+ {
+ 	unsigned long *regptr, newval;
+ 	extern int do_dsemulret(struct pt_regs *);
++	unsigned int __user *pc;
+ 	mm_segment_t seg;
+-	unsigned long pc;
+ 
+ 	/*
+ 	 * Address errors may be deliberately induced by the FPU emulator to
+@@ -515,7 +515,7 @@ asmlinkage void do_ade(struct pt_regs *r
+ 	if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1))
+ 		goto sigbus;
+ 
+-	pc = exception_epc(regs);
++	pc = (unsigned int __user *) exception_epc(regs);
+ 	if ((current->thread.mflags & MF_FIXADE) == 0)
+ 		goto sigbus;
+ 
+@@ -526,7 +526,7 @@ asmlinkage void do_ade(struct pt_regs *r
+ 	seg = get_fs();
+ 	if (!user_mode(regs))
+ 		set_fs(KERNEL_DS);
+-	if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc,
++	if (!emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc,
+ 	                             &regptr, &newval)) {
+ 		compute_return_epc(regs);
+ 		/*
+diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
+--- a/arch/mips/kernel/vmlinux.lds.S
++++ b/arch/mips/kernel/vmlinux.lds.S
+@@ -54,13 +54,6 @@ SECTIONS
+ 
+     *(.data)
+ 
+-   /* Align the initial ramdisk image (INITRD) on page boundaries. */
+-   . = ALIGN(4096);
+-   __rd_start = .;
+-   *(.initrd)
+-   . = ALIGN(4096);
+-   __rd_end = .;
+-
+     CONSTRUCTORS
+   }
+   _gp = . + 0x8000;
+@@ -96,12 +89,6 @@ SECTIONS
+   .init.setup : { *(.init.setup) }
+   __setup_end = .;
+ 
+-  .early_initcall.init : {
+-  __earlyinitcall_start = .;
+-	*(.initcall.early1.init)
+-  }
+-  __earlyinitcall_end = .;
+-
+   __initcall_start = .;
+   .initcall.init : {
+ 	*(.initcall1.init)
+diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/kernel/vpe.c
+@@ -0,0 +1,1296 @@
++/*
++ * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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.
++ *
++ */
++
++/*
++ * VPE support module
++ *
++ * Provides support for loading a MIPS SP program on VPE1.
++ * The SP enviroment is rather simple, no tlb's.  It needs to be relocatable
++ * (or partially linked). You should initialise your stack in the startup
++ * code. This loader looks for the symbol __start and sets up
++ * execution to resume from there. The MIPS SDE kit contains suitable examples.
++ *
++ * To load and run, simply cat a SP 'program file' to /dev/vpe1.
++ * i.e cat spapp >/dev/vpe1.
++ *
++ * You'll need to have the following device files.
++ * mknod /dev/vpe0 c 63 0
++ * mknod /dev/vpe1 c 63 1
++ */
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <linux/slab.h>
++#include <linux/list.h>
++#include <linux/vmalloc.h>
++#include <linux/elf.h>
++#include <linux/seq_file.h>
++#include <linux/syscalls.h>
++#include <linux/moduleloader.h>
++#include <linux/interrupt.h>
++#include <linux/poll.h>
++#include <linux/bootmem.h>
++#include <asm/mipsregs.h>
++#include <asm/mipsmtregs.h>
++#include <asm/cacheflush.h>
++#include <asm/atomic.h>
++#include <asm/cpu.h>
++#include <asm/processor.h>
++#include <asm/system.h>
++
++typedef void *vpe_handle;
++
++// defined here because the kernel module loader doesn't have
++// anything to do with it.
++#define SHN_MIPS_SCOMMON 0xff03
++
++#ifndef ARCH_SHF_SMALL
++#define ARCH_SHF_SMALL 0
++#endif
++
++/* If this is set, the section belongs in the init part of the module */
++#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
++
++// temp number,
++#define VPE_MAJOR 63
++
++static char module_name[] = "vpe";
++static int major = 0;
++
++/* grab the likely amount of memory we will need. */
++#ifdef CONFIG_MIPS_VPE_LOADER_TOM
++#define P_SIZE (2 * 1024 * 1024)
++#else
++/* add an overhead to the max kmalloc size for non-striped symbols/etc */
++#define P_SIZE (256 * 1024)
++#endif
++
++#define MAX_VPES 16
++
++enum vpe_state {
++	VPE_STATE_UNUSED = 0,
++	VPE_STATE_INUSE,
++	VPE_STATE_RUNNING
++};
++
++enum tc_state {
++	TC_STATE_UNUSED = 0,
++	TC_STATE_INUSE,
++	TC_STATE_RUNNING,
++	TC_STATE_DYNAMIC
++};
++
++struct vpe;
++typedef struct tc {
++	enum tc_state state;
++	int index;
++
++	/* parent VPE */
++	struct vpe *pvpe;
++
++	/* The list of TC's with this VPE */
++	struct list_head tc;
++
++	/* The global list of tc's */
++	struct list_head list;
++} tc_t;
++
++typedef struct vpe {
++	enum vpe_state state;
++
++	/* (device) minor associated with this vpe */
++	int minor;
++
++	/* elfloader stuff */
++	void *load_addr;
++	u32 len;
++	char *pbuffer;
++	u32 plen;
++
++	unsigned long __start;
++
++	/* tc's associated with this vpe */
++	struct list_head tc;
++
++	/* The list of vpe's */
++	struct list_head list;
++
++	/* shared symbol address */
++	void *shared_ptr;
++} vpe_t;
++
++struct vpecontrol_ {
++	/* Virtual processing elements */
++	struct list_head vpe_list;
++
++	/* Thread contexts */
++	struct list_head tc_list;
++} vpecontrol;
++
++static void release_progmem(void *ptr);
++static void dump_vpe(vpe_t * v);
++extern void save_gp_address(unsigned int secbase, unsigned int rel);
++
++/* get the vpe associated with this minor */
++struct vpe *get_vpe(int minor)
++{
++	struct vpe *v;
++
++	list_for_each_entry(v, &vpecontrol.vpe_list, list) {
++		if (v->minor == minor)
++			return v;
++	}
++
++	printk(KERN_DEBUG "VPE: get_vpe minor %d not found\n", minor);
++	return NULL;
++}
++
++/* get the vpe associated with this minor */
++struct tc *get_tc(int index)
++{
++	struct tc *t;
++
++	list_for_each_entry(t, &vpecontrol.tc_list, list) {
++		if (t->index == index)
++			return t;
++	}
++
++	printk(KERN_DEBUG "VPE: get_tc index %d not found\n", index);
++
++	return NULL;
++}
++
++struct tc *get_tc_unused(void)
++{
++	struct tc *t;
++
++	list_for_each_entry(t, &vpecontrol.tc_list, list) {
++		if (t->state == TC_STATE_UNUSED)
++			return t;
++	}
++
++	printk(KERN_DEBUG "VPE: All TC's are in use\n");
++
++	return NULL;
++}
++
++/* allocate a vpe and associate it with this minor (or index) */
++struct vpe *alloc_vpe(int minor)
++{
++	struct vpe *v;
++
++	if ((v = kmalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) {
++		printk(KERN_WARNING "VPE: alloc_vpe no mem\n");
++		return NULL;
++	}
++
++	memset(v, 0, sizeof(struct vpe));
++
++	INIT_LIST_HEAD(&v->tc);
++	list_add_tail(&v->list, &vpecontrol.vpe_list);
++
++	v->minor = minor;
++	return v;
++}
++
++/* allocate a tc. At startup only tc0 is running, all other can be halted. */
++struct tc *alloc_tc(int index)
++{
++	struct tc *t;
++
++	if ((t = kmalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) {
++		printk(KERN_WARNING "VPE: alloc_tc no mem\n");
++		return NULL;
++	}
++
++	memset(t, 0, sizeof(struct tc));
++
++	INIT_LIST_HEAD(&t->tc);
++	list_add_tail(&t->list, &vpecontrol.tc_list);
++
++	t->index = index;
++
++	return t;
++}
++
++/* clean up and free everything */
++void release_vpe(struct vpe *v)
++{
++	list_del(&v->list);
++	if (v->load_addr)
++		release_progmem(v);
++	kfree(v);
++}
++
++void dump_mtregs(void)
++{
++	unsigned long val;
++
++	val = read_c0_config3();
++	printk("config3 0x%lx MT %ld\n", val,
++	       (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT);
++
++	val = read_c0_mvpconf0();
++	printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val,
++	       (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT,
++	       val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT);
++
++	val = read_c0_mvpcontrol();
++	printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val,
++	       (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT,
++	       (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT,
++	       (val & MVPCONTROL_EVP));
++
++	val = read_c0_vpeconf0();
++	printk("VPEConf0 0x%lx MVP %ld\n", val,
++	       (val & VPECONF0_MVP) >> VPECONF0_MVP_SHIFT);
++}
++
++/* Find some VPE program space  */
++static void *alloc_progmem(u32 len)
++{
++#ifdef CONFIG_MIPS_VPE_LOADER_TOM
++	/* this means you must tell linux to use less memory than you physically have */
++	return (void *)((max_pfn * PAGE_SIZE) + KSEG0);
++#else
++	// simple grab some mem for now
++	return kmalloc(len, GFP_KERNEL);
++#endif
++}
++
++static void release_progmem(void *ptr)
++{
++#ifndef CONFIG_MIPS_VPE_LOADER_TOM
++	kfree(ptr);
++#endif
++}
++
++/* Update size with this section: return offset. */
++static long get_offset(unsigned long *size, Elf_Shdr * sechdr)
++{
++	long ret;
++
++	ret = ALIGN(*size, sechdr->sh_addralign ? : 1);
++	*size = ret + sechdr->sh_size;
++	return ret;
++}
++
++/* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
++   might -- code, read-only data, read-write data, small data.  Tally
++   sizes, and place the offsets into sh_entsize fields: high bit means it
++   belongs in init. */
++static void layout_sections(struct module *mod, const Elf_Ehdr * hdr,
++			    Elf_Shdr * sechdrs, const char *secstrings)
++{
++	static unsigned long const masks[][2] = {
++		/* NOTE: all executable code must be the first section
++		 * in this array; otherwise modify the text_size
++		 * finder in the two loops below */
++		{SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL},
++		{SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL},
++		{SHF_WRITE | SHF_ALLOC, ARCH_SHF_SMALL},
++		{ARCH_SHF_SMALL | SHF_ALLOC, 0}
++	};
++	unsigned int m, i;
++
++	for (i = 0; i < hdr->e_shnum; i++)
++		sechdrs[i].sh_entsize = ~0UL;
++
++	for (m = 0; m < ARRAY_SIZE(masks); ++m) {
++		for (i = 0; i < hdr->e_shnum; ++i) {
++			Elf_Shdr *s = &sechdrs[i];
++
++			//  || strncmp(secstrings + s->sh_name, ".init", 5) == 0)
++			if ((s->sh_flags & masks[m][0]) != masks[m][0]
++			    || (s->sh_flags & masks[m][1])
++			    || s->sh_entsize != ~0UL)
++				continue;
++			s->sh_entsize = get_offset(&mod->core_size, s);
++		}
++
++		if (m == 0)
++			mod->core_text_size = mod->core_size;
++
++	}
++}
++
++
++/* from module-elf32.c, but subverted a little */
++
++struct mips_hi16 {
++	struct mips_hi16 *next;
++	Elf32_Addr *addr;
++	Elf32_Addr value;
++};
++
++static struct mips_hi16 *mips_hi16_list;
++static unsigned int gp_offs, gp_addr;
++
++static int apply_r_mips_none(struct module *me, uint32_t *location,
++			     Elf32_Addr v)
++{
++	return 0;
++}
++
++static int apply_r_mips_gprel16(struct module *me, uint32_t *location,
++				Elf32_Addr v)
++{
++	int rel;
++
++	if( !(*location & 0xffff) ) {
++		rel = (int)v - gp_addr;
++	}
++	else {
++		/* .sbss + gp(relative) + offset */
++		/* kludge! */
++		rel =  (int)(short)((int)v + gp_offs +
++				    (int)(short)(*location & 0xffff) - gp_addr);
++	}
++
++	if( (rel > 32768) || (rel < -32768) ) {
++		printk(KERN_ERR
++		       "apply_r_mips_gprel16: relative address out of range 0x%x %d\n",
++		       rel, rel);
++		return -ENOEXEC;
++	}
++
++	*location = (*location & 0xffff0000) | (rel & 0xffff);
++
++	return 0;
++}
++
++static int apply_r_mips_pc16(struct module *me, uint32_t *location,
++			     Elf32_Addr v)
++{
++	int rel;
++	rel = (((unsigned int)v - (unsigned int)location));
++	rel >>= 2;		// because the offset is in _instructions_ not bytes.
++	rel -= 1;		// and one instruction less due to the branch delay slot.
++
++	if( (rel > 32768) || (rel < -32768) ) {
++		printk(KERN_ERR
++		       "apply_r_mips_pc16: relative address out of range 0x%x\n", rel);
++		return -ENOEXEC;
++	}
++
++	*location = (*location & 0xffff0000) | (rel & 0xffff);
++
++	return 0;
++}
++
++static int apply_r_mips_32(struct module *me, uint32_t *location,
++			   Elf32_Addr v)
++{
++	*location += v;
++
++	return 0;
++}
++
++static int apply_r_mips_26(struct module *me, uint32_t *location,
++			   Elf32_Addr v)
++{
++	if (v % 4) {
++		printk(KERN_ERR "module %s: dangerous relocation mod4\n", me->name);
++		return -ENOEXEC;
++	}
++
++/* Not desperately convinced this is a good check of an overflow condition
++   anyway. But it gets in the way of handling undefined weak symbols which
++   we want to set to zero.
++   if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
++   printk(KERN_ERR
++   "module %s: relocation overflow\n",
++   me->name);
++   return -ENOEXEC;
++   }
++*/
++
++	*location = (*location & ~0x03ffffff) |
++		((*location + (v >> 2)) & 0x03ffffff);
++	return 0;
++}
++
++static int apply_r_mips_hi16(struct module *me, uint32_t *location,
++			     Elf32_Addr v)
++{
++	struct mips_hi16 *n;
++
++	/*
++	 * We cannot relocate this one now because we don't know the value of
++	 * the carry we need to add.  Save the information, and let LO16 do the
++	 * actual relocation.
++	 */
++	n = kmalloc(sizeof *n, GFP_KERNEL);
++	if (!n)
++		return -ENOMEM;
++
++	n->addr = location;
++	n->value = v;
++	n->next = mips_hi16_list;
++	mips_hi16_list = n;
++
++	return 0;
++}
++
++static int apply_r_mips_lo16(struct module *me, uint32_t *location,
++			     Elf32_Addr v)
++{
++	unsigned long insnlo = *location;
++	Elf32_Addr val, vallo;
++
++	/* Sign extend the addend we extract from the lo insn.  */
++	vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
++
++	if (mips_hi16_list != NULL) {
++		struct mips_hi16 *l;
++
++		l = mips_hi16_list;
++		while (l != NULL) {
++			struct mips_hi16 *next;
++			unsigned long insn;
++
++			/*
++			 * The value for the HI16 had best be the same.
++			 */
++			if (v != l->value) {
++				printk("%d != %d\n", v, l->value);
++				goto out_danger;
++			}
++
++
++			/*
++			 * Do the HI16 relocation.  Note that we actually don't
++			 * need to know anything about the LO16 itself, except
++			 * where to find the low 16 bits of the addend needed
++			 * by the LO16.
++			 */
++			insn = *l->addr;
++			val = ((insn & 0xffff) << 16) + vallo;
++			val += v;
++
++			/*
++			 * Account for the sign extension that will happen in
++			 * the low bits.
++			 */
++			val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
++
++			insn = (insn & ~0xffff) | val;
++			*l->addr = insn;
++
++			next = l->next;
++			kfree(l);
++			l = next;
++		}
++
++		mips_hi16_list = NULL;
++	}
++
++	/*
++	 * Ok, we're done with the HI16 relocs.  Now deal with the LO16.
++	 */
++	val = v + vallo;
++	insnlo = (insnlo & ~0xffff) | (val & 0xffff);
++	*location = insnlo;
++
++	return 0;
++
++out_danger:
++	printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
++
++	return -ENOEXEC;
++}
++
++static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
++				Elf32_Addr v) = {
++	[R_MIPS_NONE]	= apply_r_mips_none,
++	[R_MIPS_32]	= apply_r_mips_32,
++	[R_MIPS_26]	= apply_r_mips_26,
++	[R_MIPS_HI16]	= apply_r_mips_hi16,
++	[R_MIPS_LO16]	= apply_r_mips_lo16,
++	[R_MIPS_GPREL16] = apply_r_mips_gprel16,
++	[R_MIPS_PC16] = apply_r_mips_pc16
++};
++
++
++int apply_relocations(Elf32_Shdr *sechdrs,
++		      const char *strtab,
++		      unsigned int symindex,
++		      unsigned int relsec,
++		      struct module *me)
++{
++	Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
++	Elf32_Sym *sym;
++	uint32_t *location;
++	unsigned int i;
++	Elf32_Addr v;
++	int res;
++
++	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
++		Elf32_Word r_info = rel[i].r_info;
++
++		/* This is where to make the change */
++		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
++			+ rel[i].r_offset;
++		/* This is the symbol it is referring to */
++		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
++			+ ELF32_R_SYM(r_info);
++
++		if (!sym->st_value) {
++			printk(KERN_DEBUG "%s: undefined weak symbol %s\n",
++			       me->name, strtab + sym->st_name);
++			/* just print the warning, dont barf */
++		}
++
++		v = sym->st_value;
++
++		res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
++		if( res ) {
++			printk(KERN_DEBUG
++			       "relocation error 0x%x sym refer <%s> value 0x%x "
++			       "type 0x%x r_info 0x%x\n",
++			       (unsigned int)location, strtab + sym->st_name, v,
++			       r_info, ELF32_R_TYPE(r_info));
++		}
++
++		if (res)
++			return res;
++	}
++
++	return 0;
++}
++
++void save_gp_address(unsigned int secbase, unsigned int rel)
++{
++	gp_addr = secbase + rel;
++	gp_offs = gp_addr - (secbase & 0xffff0000);
++}
++/* end module-elf32.c */
++
++
++
++/* Change all symbols so that sh_value encodes the pointer directly. */
++static int simplify_symbols(Elf_Shdr * sechdrs,
++			    unsigned int symindex,
++			    const char *strtab,
++			    const char *secstrings,
++			    unsigned int nsecs, struct module *mod)
++{
++	Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
++	unsigned long secbase, bssbase = 0;
++	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
++	int ret = 0, size;
++
++	/* find the .bss section for COMMON symbols */
++	for (i = 0; i < nsecs; i++) {
++		if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0)
++			bssbase = sechdrs[i].sh_addr;
++	}
++
++	for (i = 1; i < n; i++) {
++		switch (sym[i].st_shndx) {
++		case SHN_COMMON:
++			/* Allocate space for the symbol in the .bss section. st_value is currently size.
++			   We want it to have the address of the symbol. */
++
++			size = sym[i].st_value;
++			sym[i].st_value = bssbase;
++
++			bssbase += size;
++			break;
++
++		case SHN_ABS:
++			/* Don't need to do anything */
++			break;
++
++		case SHN_UNDEF:
++			/* ret = -ENOENT; */
++			break;
++
++		case SHN_MIPS_SCOMMON:
++
++			printk(KERN_DEBUG
++			       "simplify_symbols: ignoring SHN_MIPS_SCOMMON symbol <%s> st_shndx %d\n",
++			       strtab + sym[i].st_name, sym[i].st_shndx);
++
++			// .sbss section
++			break;
++
++		default:
++			secbase = sechdrs[sym[i].st_shndx].sh_addr;
++
++			if (strncmp(strtab + sym[i].st_name, "_gp", 3) == 0) {
++				save_gp_address(secbase, sym[i].st_value);
++			}
++
++			sym[i].st_value += secbase;
++			break;
++		}
++
++	}
++
++	return ret;
++}
++
++#ifdef DEBUG_ELFLOADER
++static void dump_elfsymbols(Elf_Shdr * sechdrs, unsigned int symindex,
++			    const char *strtab, struct module *mod)
++{
++	Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
++	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
++
++	printk(KERN_DEBUG "dump_elfsymbols: n %d\n", n);
++	for (i = 1; i < n; i++) {
++		printk(KERN_DEBUG " i %d name <%s> 0x%x\n", i,
++		       strtab + sym[i].st_name, sym[i].st_value);
++	}
++}
++#endif
++
++static void dump_tc(struct tc *t)
++{
++	printk(KERN_WARNING "VPE: TC index %d TCStatus 0x%lx halt 0x%lx\n",
++	       t->index, read_tc_c0_tcstatus(), read_tc_c0_tchalt());
++	printk(KERN_WARNING "VPE: tcrestart 0x%lx\n", read_tc_c0_tcrestart());
++}
++
++static void dump_tclist(void)
++{
++	struct tc *t;
++
++	list_for_each_entry(t, &vpecontrol.tc_list, list) {
++		dump_tc(t);
++	}
++}
++
++/* We are prepared so configure and start the VPE... */
++int vpe_run(vpe_t * v)
++{
++	unsigned long val;
++	struct tc *t;
++
++	/* check we are the Master VPE */
++	val = read_c0_vpeconf0();
++	if (!(val & VPECONF0_MVP)) {
++		printk(KERN_WARNING
++		       "VPE: only Master VPE's are allowed to configure MT\n");
++		return -1;
++	}
++
++	/* disable MT (using dvpe) */
++	dvpe();
++
++	/* Put MVPE's into 'configuration state' */
++	set_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	if (!list_empty(&v->tc)) {
++		if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
++			printk(KERN_WARNING "VPE: TC %d is already in use.\n",
++			       t->index);
++			return -ENOEXEC;
++		}
++	} else {
++		printk(KERN_WARNING "VPE: No TC's associated with VPE %d\n",
++		       v->minor);
++		return -ENOEXEC;
++	}
++
++	settc(t->index);
++
++	val = read_vpe_c0_vpeconf0();
++
++	/* should check it is halted, and not activated */
++	if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) {
++		printk(KERN_WARNING "VPE: TC %d is already doing something!\n",
++		       t->index);
++
++		dump_tclist();
++		return -ENOEXEC;
++	}
++
++	/* Write the address we want it to start running from in the TCPC register. */
++	write_tc_c0_tcrestart((unsigned long)v->__start);
++
++	/* write the sivc_info address to tccontext */
++	write_tc_c0_tccontext((unsigned long)0);
++
++	/* Set up the XTC bit in vpeconf0 to point at our tc */
++	write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (t->index << VPECONF0_XTC_SHIFT));
++
++	/* mark the TC as activated, not interrupt exempt and not dynamically allocatable */
++	val = read_tc_c0_tcstatus();
++	val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A;
++	write_tc_c0_tcstatus(val);
++
++	write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
++
++	/* set up VPE1 */
++	write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);	// no multiple TC's
++	write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);	// enable this VPE
++
++	/*
++	 * The sde-kit passes 'memsize' to __start in $a3, so set something
++	 * here...
++	 * Or set $a3 (register 7) to zero and define DFLT_STACK_SIZE and
++	 * DFLT_HEAP_SIZE when you compile your program
++	 */
++
++	mttgpr(7, 0);
++
++	/* set config to be the same as vpe0, particularly kseg0 coherency alg */
++	write_vpe_c0_config(read_c0_config());
++
++	/* clear out any left overs from a previous program */
++	write_vpe_c0_cause(0);
++
++	/* take system out of configuration state */
++	clear_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	/* clear interrupts enabled IE, ERL, EXL, and KSU from c0 status */
++	write_vpe_c0_status(read_vpe_c0_status() & ~(ST0_ERL | ST0_KSU | ST0_IE | ST0_EXL));
++
++	/* set it running */
++	evpe(EVPE_ENABLE);
++
++	return 0;
++}
++
++static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs,
++				      unsigned int symindex, const char *strtab,
++				      struct module *mod)
++{
++	Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
++	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
++
++	for (i = 1; i < n; i++) {
++		if (strcmp(strtab + sym[i].st_name, "__start") == 0) {
++			v->__start = sym[i].st_value;
++		}
++
++		if (strcmp(strtab + sym[i].st_name, "vpe_shared") == 0) {
++			v->shared_ptr = (void *)sym[i].st_value;
++		}
++	}
++
++	return 0;
++}
++
++/* Allocates a VPE with some program code space(the load address), copies the contents
++   of the program (p)buffer performing relocatations/etc, free's it when finished.
++*/
++int vpe_elfload(vpe_t * v)
++{
++	Elf_Ehdr *hdr;
++	Elf_Shdr *sechdrs;
++	long err = 0;
++	char *secstrings, *strtab = NULL;
++	unsigned int len, i, symindex = 0, strindex = 0;
++
++	struct module mod;	// so we can re-use the relocations code
++
++	memset(&mod, 0, sizeof(struct module));
++	strcpy(mod.name, "VPE dummy prog module");
++
++	hdr = (Elf_Ehdr *) v->pbuffer;
++	len = v->plen;
++
++	/* Sanity checks against insmoding binaries or wrong arch,
++	   weird elf version */
++	if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
++	    || hdr->e_type != ET_REL || !elf_check_arch(hdr)
++	    || hdr->e_shentsize != sizeof(*sechdrs)) {
++		printk(KERN_WARNING
++		       "VPE program, wrong arch or weird elf version\n");
++
++		return -ENOEXEC;
++	}
++
++	if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
++		printk(KERN_ERR "VPE program length %u truncated\n", len);
++		return -ENOEXEC;
++	}
++
++	/* Convenience variables */
++	sechdrs = (void *)hdr + hdr->e_shoff;
++	secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
++	sechdrs[0].sh_addr = 0;
++
++	/* And these should exist, but gcc whinges if we don't init them */
++	symindex = strindex = 0;
++
++	for (i = 1; i < hdr->e_shnum; i++) {
++
++		if (sechdrs[i].sh_type != SHT_NOBITS
++		    && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) {
++			printk(KERN_ERR "VPE program length %u truncated\n",
++			       len);
++			return -ENOEXEC;
++		}
++
++		/* Mark all sections sh_addr with their address in the
++		   temporary image. */
++		sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
++
++		/* Internal symbols and strings. */
++		if (sechdrs[i].sh_type == SHT_SYMTAB) {
++			symindex = i;
++			strindex = sechdrs[i].sh_link;
++			strtab = (char *)hdr + sechdrs[strindex].sh_offset;
++		}
++	}
++
++	layout_sections(&mod, hdr, sechdrs, secstrings);
++
++	v->load_addr = alloc_progmem(mod.core_size);
++	memset(v->load_addr, 0, mod.core_size);
++
++	printk("VPE elf_loader: loading to %p\n", v->load_addr);
++
++	for (i = 0; i < hdr->e_shnum; i++) {
++		void *dest;
++
++		if (!(sechdrs[i].sh_flags & SHF_ALLOC))
++			continue;
++
++		dest = v->load_addr + sechdrs[i].sh_entsize;
++
++		if (sechdrs[i].sh_type != SHT_NOBITS)
++			memcpy(dest, (void *)sechdrs[i].sh_addr,
++			       sechdrs[i].sh_size);
++		/* Update sh_addr to point to copy in image. */
++		sechdrs[i].sh_addr = (unsigned long)dest;
++	}
++
++	/* Fix up syms, so that st_value is a pointer to location. */
++	err =
++		simplify_symbols(sechdrs, symindex, strtab, secstrings,
++				 hdr->e_shnum, &mod);
++	if (err < 0) {
++		printk(KERN_WARNING "VPE: unable to simplify symbols\n");
++		goto cleanup;
++	}
++
++	/* Now do relocations. */
++	for (i = 1; i < hdr->e_shnum; i++) {
++		const char *strtab = (char *)sechdrs[strindex].sh_addr;
++		unsigned int info = sechdrs[i].sh_info;
++
++		/* Not a valid relocation section? */
++		if (info >= hdr->e_shnum)
++			continue;
++
++		/* Don't bother with non-allocated sections */
++		if (!(sechdrs[info].sh_flags & SHF_ALLOC))
++			continue;
++
++		if (sechdrs[i].sh_type == SHT_REL)
++			err =
++				apply_relocations(sechdrs, strtab, symindex, i, &mod);
++		else if (sechdrs[i].sh_type == SHT_RELA)
++			err = apply_relocate_add(sechdrs, strtab, symindex, i,
++						 &mod);
++		if (err < 0) {
++			printk(KERN_WARNING
++			       "vpe_elfload: error in relocations err %ld\n",
++			       err);
++			goto cleanup;
++		}
++	}
++
++	/* make sure it's physically written out */
++	flush_icache_range((unsigned long)v->load_addr,
++			   (unsigned long)v->load_addr + v->len);
++
++	if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
++
++		printk(KERN_WARNING
++		       "VPE: program doesn't contain __start or vpe_shared symbols\n");
++		err = -ENOEXEC;
++	}
++
++	printk(" elf loaded\n");
++
++cleanup:
++	return err;
++}
++
++static void dump_vpe(vpe_t * v)
++{
++	struct tc *t;
++
++	printk(KERN_DEBUG "VPEControl 0x%lx\n", read_vpe_c0_vpecontrol());
++	printk(KERN_DEBUG "VPEConf0 0x%lx\n", read_vpe_c0_vpeconf0());
++
++	list_for_each_entry(t, &vpecontrol.tc_list, list) {
++		dump_tc(t);
++	}
++}
++
++/* checks for VPE is unused and gets ready to load program	 */
++static int vpe_open(struct inode *inode, struct file *filp)
++{
++	int minor;
++	vpe_t *v;
++
++	/* assume only 1 device at the mo. */
++	if ((minor = MINOR(inode->i_rdev)) != 1) {
++		printk(KERN_WARNING "VPE: only vpe1 is supported\n");
++		return -ENODEV;
++	}
++
++	if ((v = get_vpe(minor)) == NULL) {
++		printk(KERN_WARNING "VPE: unable to get vpe\n");
++		return -ENODEV;
++	}
++
++	if (v->state != VPE_STATE_UNUSED) {
++		unsigned long tmp;
++		struct tc *t;
++
++		printk(KERN_WARNING "VPE: device %d already in use\n", minor);
++
++		dvpe();
++		dump_vpe(v);
++
++		printk(KERN_WARNING "VPE: re-initialising %d\n", minor);
++
++		release_progmem(v->load_addr);
++
++		t = get_tc(minor);
++		settc(minor);
++		tmp = read_tc_c0_tcstatus();
++
++		/* mark not allocated and not dynamically allocatable */
++		tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
++		tmp |= TCSTATUS_IXMT;	/* interrupt exempt */
++		write_tc_c0_tcstatus(tmp);
++
++		write_tc_c0_tchalt(TCHALT_H);
++
++	}
++
++	// allocate it so when we get write ops we know it's expected.
++	v->state = VPE_STATE_INUSE;
++
++	/* this of-course trashes what was there before... */
++	v->pbuffer = vmalloc(P_SIZE);
++	v->plen = P_SIZE;
++	v->load_addr = NULL;
++	v->len = 0;
++
++	return 0;
++}
++
++static int vpe_release(struct inode *inode, struct file *filp)
++{
++	int minor, ret = 0;
++	vpe_t *v;
++	Elf_Ehdr *hdr;
++
++	minor = MINOR(inode->i_rdev);
++	if ((v = get_vpe(minor)) == NULL)
++		return -ENODEV;
++
++	// simple case of fire and forget, so tell the VPE to run...
++
++	hdr = (Elf_Ehdr *) v->pbuffer;
++	if (memcmp(hdr->e_ident, ELFMAG, 4) == 0) {
++		if (vpe_elfload(v) >= 0)
++			vpe_run(v);
++		else {
++			printk(KERN_WARNING "VPE: ELF load failed.\n");
++			ret = -ENOEXEC;
++		}
++	} else {
++		printk(KERN_WARNING "VPE: only elf files are supported\n");
++		ret = -ENOEXEC;
++	}
++
++	// cleanup any temp buffers
++	if (v->pbuffer)
++		vfree(v->pbuffer);
++	v->plen = 0;
++	return ret;
++}
++
++static ssize_t vpe_write(struct file *file, const char __user * buffer,
++			 size_t count, loff_t * ppos)
++{
++	int minor;
++	size_t ret = count;
++	vpe_t *v;
++
++	minor = MINOR(file->f_dentry->d_inode->i_rdev);
++	if ((v = get_vpe(minor)) == NULL)
++		return -ENODEV;
++
++	if (v->pbuffer == NULL) {
++		printk(KERN_ERR "vpe_write: no pbuffer\n");
++		return -ENOMEM;
++	}
++
++	if ((count + v->len) > v->plen) {
++		printk(KERN_WARNING
++		       "VPE Loader: elf size too big. Perhaps strip uneeded symbols\n");
++		return -ENOMEM;
++	}
++
++	count -= copy_from_user(v->pbuffer + v->len, buffer, count);
++	if (!count) {
++		printk("vpe_write: copy_to_user failed\n");
++		return -EFAULT;
++	}
++
++	v->len += count;
++	return ret;
++}
++
++static struct file_operations vpe_fops = {
++	.owner = THIS_MODULE,
++	.open = vpe_open,
++	.release = vpe_release,
++	.write = vpe_write
++};
++
++/* module wrapper entry points */
++/* give me a vpe */
++vpe_handle vpe_alloc(void)
++{
++	int i;
++	struct vpe *v;
++
++	/* find a vpe */
++	for (i = 1; i < MAX_VPES; i++) {
++		if ((v = get_vpe(i)) != NULL) {
++			v->state = VPE_STATE_INUSE;
++			return v;
++		}
++	}
++	return NULL;
++}
++
++EXPORT_SYMBOL(vpe_alloc);
++
++/* start running from here */
++int vpe_start(vpe_handle vpe, unsigned long start)
++{
++	struct vpe *v = vpe;
++
++	v->__start = start;
++	return vpe_run(v);
++}
++
++EXPORT_SYMBOL(vpe_start);
++
++/* halt it for now */
++int vpe_stop(vpe_handle vpe)
++{
++	struct vpe *v = vpe;
++	struct tc *t;
++	unsigned int evpe_flags;
++
++	evpe_flags = dvpe();
++
++	if ((t = list_entry(v->tc.next, struct tc, tc)) != NULL) {
++
++		settc(t->index);
++		write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
++	}
++
++	evpe(evpe_flags);
++
++	return 0;
++}
++
++EXPORT_SYMBOL(vpe_stop);
++
++/* I've done with it thank you */
++int vpe_free(vpe_handle vpe)
++{
++	struct vpe *v = vpe;
++	struct tc *t;
++	unsigned int evpe_flags;
++
++	if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
++		return -ENOEXEC;
++	}
++
++	evpe_flags = dvpe();
++
++	/* Put MVPE's into 'configuration state' */
++	set_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	settc(t->index);
++	write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
++
++	/* mark the TC unallocated and halt'ed */
++	write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
++	write_tc_c0_tchalt(TCHALT_H);
++
++	v->state = VPE_STATE_UNUSED;
++
++	clear_c0_mvpcontrol(MVPCONTROL_VPC);
++	evpe(evpe_flags);
++
++	return 0;
++}
++
++EXPORT_SYMBOL(vpe_free);
++
++void *vpe_get_shared(int index)
++{
++	struct vpe *v;
++
++	if ((v = get_vpe(index)) == NULL) {
++		printk(KERN_WARNING "vpe: invalid vpe index %d\n", index);
++		return NULL;
++	}
++
++	return v->shared_ptr;
++}
++
++EXPORT_SYMBOL(vpe_get_shared);
++
++static int __init vpe_module_init(void)
++{
++	struct vpe *v = NULL;
++	struct tc *t;
++	unsigned long val;
++	int i;
++
++	if (!cpu_has_mipsmt) {
++		printk("VPE loader: not a MIPS MT capable processor\n");
++		return -ENODEV;
++	}
++
++	if ((major = register_chrdev(VPE_MAJOR, module_name, &vpe_fops) < 0)) {
++		printk("VPE loader: unable to register character device\n");
++		return -EBUSY;
++	}
++
++	if (major == 0)
++		major = VPE_MAJOR;
++
++	dmt();
++	dvpe();
++
++	/* Put MVPE's into 'configuration state' */
++	set_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	/* dump_mtregs(); */
++
++	INIT_LIST_HEAD(&vpecontrol.vpe_list);
++	INIT_LIST_HEAD(&vpecontrol.tc_list);
++
++	val = read_c0_mvpconf0();
++	for (i = 0; i < ((val & MVPCONF0_PTC) + 1); i++) {
++		t = alloc_tc(i);
++
++		/* VPE's */
++		if (i < ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1) {
++			settc(i);
++
++			if ((v = alloc_vpe(i)) == NULL) {
++				printk(KERN_WARNING "VPE: unable to allocate VPE\n");
++				return -ENODEV;
++			}
++
++			list_add(&t->tc, &v->tc);	/* add the tc to the list of this vpe's tc's. */
++
++			/* deactivate all but vpe0 */
++			if (i != 0) {
++				unsigned long tmp = read_vpe_c0_vpeconf0();
++
++				tmp &= ~VPECONF0_VPA;
++
++				/* master VPE */
++				tmp |= VPECONF0_MVP;
++				write_vpe_c0_vpeconf0(tmp);
++			}
++
++			/* disable multi-threading with TC's */
++			write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
++
++			if (i != 0) {
++				write_vpe_c0_status((read_c0_status() &
++						     ~(ST0_IM | ST0_IE | ST0_KSU))
++						    | ST0_CU0);
++
++				/* set config to be the same as vpe0, particularly kseg0 coherency alg */
++				write_vpe_c0_config(read_c0_config());
++			}
++
++		}
++
++		/* TC's */
++		t->pvpe = v;	/* set the parent vpe */
++
++		if (i != 0) {
++			unsigned long tmp;
++
++			/* tc 0 will of course be running.... */
++			if (i == 0)
++				t->state = TC_STATE_RUNNING;
++
++			settc(i);
++
++			/* bind a TC to each VPE, May as well put all excess TC's
++			   on the last VPE */
++			if (i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1))
++				write_tc_c0_tcbind(read_tc_c0_tcbind() |
++						   ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT));
++			else
++				write_tc_c0_tcbind(read_tc_c0_tcbind() | i);
++
++			tmp = read_tc_c0_tcstatus();
++
++			/* mark not allocated and not dynamically allocatable */
++			tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
++			tmp |= TCSTATUS_IXMT;	/* interrupt exempt */
++			write_tc_c0_tcstatus(tmp);
++
++			write_tc_c0_tchalt(TCHALT_H);
++		}
++	}
++
++	/* release config state */
++	clear_c0_mvpcontrol(MVPCONTROL_VPC);
++
++	return 0;
++}
++
++static void __exit vpe_module_exit(void)
++{
++	struct vpe *v, *n;
++
++	list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
++		if (v->state != VPE_STATE_UNUSED) {
++			release_vpe(v);
++		}
++	}
++
++	unregister_chrdev(major, module_name);
++}
++
++module_init(vpe_module_init);
++module_exit(vpe_module_exit);
++MODULE_DESCRIPTION("MIPS VPE Loader");
++MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc");
++MODULE_LICENSE("GPL");
+diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/lasat/Kconfig
+@@ -0,0 +1,15 @@
++config PICVUE
++	tristate "PICVUE LCD display driver"
++	depends on LASAT
++
++config PICVUE_PROC
++	tristate "PICVUE LCD display driver /proc interface"
++	depends on PICVUE
++
++config DS1603
++	bool "DS1603 RTC driver"
++	depends on LASAT
++
++config LASAT_SYSCTL
++	bool "LASAT sysctl interface"
++	depends on LASAT
+diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
+--- a/arch/mips/lasat/interrupt.c
++++ b/arch/mips/lasat/interrupt.c
+@@ -71,14 +71,13 @@ static void end_lasat_irq(unsigned int i
+ }
+ 
+ static struct hw_interrupt_type lasat_irq_type = {
+-	"Lasat",
+-	startup_lasat_irq,
+-	shutdown_lasat_irq,
+-	enable_lasat_irq,
+-	disable_lasat_irq,
+-	mask_and_ack_lasat_irq,
+-	end_lasat_irq,
+-	NULL
++	.typename = "Lasat",
++	.startup = startup_lasat_irq,
++	.shutdown = shutdown_lasat_irq,
++	.enable = enable_lasat_irq,
++	.disable = disable_lasat_irq,
++	.ack = mask_and_ack_lasat_irq,
++	.end = end_lasat_irq,
+ };
+ 
+ static inline int ls1bit32(unsigned int x)
+diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
+--- a/arch/mips/lasat/setup.c
++++ b/arch/mips/lasat/setup.c
+@@ -155,7 +155,7 @@ void __init serial_init(void)
+ }
+ #endif
+ 
+-static int __init lasat_setup(void)
++void __init plat_setup(void)
+ {
+ 	int i;
+ 	lasat_misc  = &lasat_misc_info[mips_machtype];
+@@ -185,8 +185,4 @@ static int __init lasat_setup(void)
+ 	change_c0_status(ST0_BEV,0);
+ 
+ 	prom_printf("Lasat specific initialization complete\n");
+-
+-        return 0;
+ }
+-
+-early_initcall(lasat_setup);
+diff --git a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c
+--- a/arch/mips/lib-32/dump_tlb.c
++++ b/arch/mips/lib-32/dump_tlb.c
+@@ -20,16 +20,25 @@
+ static inline const char *msk2str(unsigned int mask)
+ {
+ 	switch (mask) {
+-	case PM_4K:	return "4kb";
+-	case PM_16K:	return "16kb";
+-	case PM_64K:	return "64kb";
+-	case PM_256K:	return "256kb";
++	case PM_4K:
++		return "4kb";
++	case PM_16K:
++		return "16kb";
++	case PM_64K:
++		return "64kb";
++	case PM_256K:
++		return "256kb";
+ #ifndef CONFIG_CPU_VR41XX
+-	case PM_1M:	return "1Mb";
+-	case PM_4M:	return "4Mb";
+-	case PM_16M:	return "16Mb";
+-	case PM_64M:	return "64Mb";
+-	case PM_256M:	return "256Mb";
++	case PM_1M:
++		return "1Mb";
++	case PM_4M:
++		return "4Mb";
++	case PM_16M:
++		return "16Mb";
++	case PM_64M:
++		return "64Mb";
++	case PM_256M:
++		return "256Mb";
+ #endif
+ 	}
+ 
+@@ -47,7 +56,7 @@ void dump_tlb(int first, int last)
+ 	unsigned int pagemask, c0, c1, asid;
+ 	unsigned long long entrylo0, entrylo1;
+ 	unsigned long entryhi;
+-	int	i;
++	int i;
+ 
+ 	asid = read_c0_entryhi() & 0xff;
+ 
+@@ -58,7 +67,7 @@ void dump_tlb(int first, int last)
+ 		tlb_read();
+ 		BARRIER();
+ 		pagemask = read_c0_pagemask();
+-		entryhi  = read_c0_entryhi();
++		entryhi = read_c0_entryhi();
+ 		entrylo0 = read_c0_entrylo0();
+ 		entrylo1 = read_c0_entrylo1();
+ 
+@@ -78,13 +87,11 @@ void dump_tlb(int first, int last)
+ 			printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
+ 			       (entrylo0 << 6) & PAGE_MASK, c0,
+ 			       (entrylo0 & 4) ? 1 : 0,
+-			       (entrylo0 & 2) ? 1 : 0,
+-			       (entrylo0 & 1));
++			       (entrylo0 & 2) ? 1 : 0, (entrylo0 & 1));
+ 			printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
+ 			       (entrylo1 << 6) & PAGE_MASK, c1,
+ 			       (entrylo1 & 4) ? 1 : 0,
+-			       (entrylo1 & 2) ? 1 : 0,
+-			       (entrylo1 & 1));
++			       (entrylo1 & 2) ? 1 : 0, (entrylo1 & 1));
+ 			printk("\n");
+ 		}
+ 	}
+@@ -99,7 +106,7 @@ void dump_tlb_all(void)
+ 
+ void dump_tlb_wired(void)
+ {
+-	int	wired;
++	int wired;
+ 
+ 	wired = read_c0_wired();
+ 	printk("Wired: %d", wired);
+@@ -138,9 +145,10 @@ void dump_tlb_nonwired(void)
+ 
+ void dump_list_process(struct task_struct *t, void *address)
+ {
+-	pgd_t	*page_dir, *pgd;
+-	pmd_t	*pmd;
+-	pte_t	*pte, page;
++	pgd_t *page_dir, *pgd;
++	pud_t *pud;
++	pmd_t *pmd;
++	pte_t *pte, page;
+ 	unsigned long addr, val;
+ 
+ 	addr = (unsigned long) address;
+@@ -152,21 +160,27 @@ void dump_list_process(struct task_struc
+ 
+ 	if (addr > KSEG0)
+ 		page_dir = pgd_offset_k(0);
+-	else
++	else if (t->mm) {
+ 		page_dir = pgd_offset(t->mm, 0);
+-	printk("page_dir == %08x\n", (unsigned int) page_dir);
++		printk("page_dir == %08x\n", (unsigned int) page_dir);
++	} else
++		printk("Current thread has no mm\n");
+ 
+ 	if (addr > KSEG0)
+ 		pgd = pgd_offset_k(addr);
+-	else
++	else if (t->mm) {
+ 		pgd = pgd_offset(t->mm, addr);
+-	printk("pgd == %08x, ", (unsigned int) pgd);
+-
+-	pmd = pmd_offset(pgd, addr);
+-	printk("pmd == %08x, ", (unsigned int) pmd);
+-
+-	pte = pte_offset(pmd, addr);
+-	printk("pte == %08x, ", (unsigned int) pte);
++		printk("pgd == %08x, ", (unsigned int) pgd);
++		pud = pud_offset(pgd, addr);
++		printk("pud == %08x, ", (unsigned int) pud);
++
++		pmd = pmd_offset(pud, addr);
++		printk("pmd == %08x, ", (unsigned int) pmd);
++
++		pte = pte_offset(pmd, addr);
++		printk("pte == %08x, ", (unsigned int) pte);
++	} else
++		printk("Current thread has no mm\n");
+ 
+ 	page = *pte;
+ #ifdef CONFIG_64BIT_PHYS_ADDR
+@@ -176,14 +190,22 @@ void dump_list_process(struct task_struc
+ #endif
+ 
+ 	val = pte_val(page);
+-	if (val & _PAGE_PRESENT) printk("present ");
+-	if (val & _PAGE_READ) printk("read ");
+-	if (val & _PAGE_WRITE) printk("write ");
+-	if (val & _PAGE_ACCESSED) printk("accessed ");
+-	if (val & _PAGE_MODIFIED) printk("modified ");
+-	if (val & _PAGE_R4KBUG) printk("r4kbug ");
+-	if (val & _PAGE_GLOBAL) printk("global ");
+-	if (val & _PAGE_VALID) printk("valid ");
++	if (val & _PAGE_PRESENT)
++		printk("present ");
++	if (val & _PAGE_READ)
++		printk("read ");
++	if (val & _PAGE_WRITE)
++		printk("write ");
++	if (val & _PAGE_ACCESSED)
++		printk("accessed ");
++	if (val & _PAGE_MODIFIED)
++		printk("modified ");
++	if (val & _PAGE_R4KBUG)
++		printk("r4kbug ");
++	if (val & _PAGE_GLOBAL)
++		printk("global ");
++	if (val & _PAGE_VALID)
++		printk("valid ");
+ 	printk("\n");
+ }
+ 
+@@ -194,14 +216,16 @@ void dump_list_current(void *address)
+ 
+ unsigned int vtop(void *address)
+ {
+-	pgd_t	*pgd;
+-	pmd_t	*pmd;
+-	pte_t	*pte;
++	pgd_t *pgd;
++	pud_t *pud;
++	pmd_t *pmd;
++	pte_t *pte;
+ 	unsigned int addr, paddr;
+ 
+ 	addr = (unsigned long) address;
+ 	pgd = pgd_offset(current->mm, addr);
+-	pmd = pmd_offset(pgd, addr);
++	pud = pud_offset(pgd, addr);
++	pmd = pmd_offset(pud, addr);
+ 	pte = pte_offset(pmd, addr);
+ 	paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
+ 	paddr |= (addr & ~PAGE_MASK);
+@@ -214,9 +238,9 @@ void dump16(unsigned long *p)
+ 	int i;
+ 
+ 	for (i = 0; i < 8; i++) {
+-		printk("*%08lx == %08lx, ", (unsigned long)p, *p);
++		printk("*%08lx == %08lx, ", (unsigned long) p, *p);
+ 		p++;
+-		printk("*%08lx == %08lx\n", (unsigned long)p, *p);
++		printk("*%08lx == %08lx\n", (unsigned long) p, *p);
+ 		p++;
+ 	}
+ }
+diff --git a/arch/mips/lib-32/r3k_dump_tlb.c b/arch/mips/lib-32/r3k_dump_tlb.c
+--- a/arch/mips/lib-32/r3k_dump_tlb.c
++++ b/arch/mips/lib-32/r3k_dump_tlb.c
+@@ -105,6 +105,7 @@ void dump_tlb_nonwired(void)
+ void dump_list_process(struct task_struct *t, void *address)
+ {
+ 	pgd_t	*page_dir, *pgd;
++	pud_t	*pud;
+ 	pmd_t	*pmd;
+ 	pte_t	*pte, page;
+ 	unsigned int addr;
+@@ -121,7 +122,10 @@ void dump_list_process(struct task_struc
+ 	pgd = pgd_offset(t->mm, addr);
+ 	printk("pgd == %08x, ", (unsigned int) pgd);
+ 
+-	pmd = pmd_offset(pgd, addr);
++	pud = pud_offset(pgd, addr);
++	printk("pud == %08x, ", (unsigned int) pud);
++
++	pmd = pmd_offset(pud, addr);
+ 	printk("pmd == %08x, ", (unsigned int) pmd);
+ 
+ 	pte = pte_offset(pmd, addr);
+@@ -149,13 +153,15 @@ void dump_list_current(void *address)
+ unsigned int vtop(void *address)
+ {
+ 	pgd_t	*pgd;
++	pud_t	*pud;
+ 	pmd_t	*pmd;
+ 	pte_t	*pte;
+ 	unsigned int addr, paddr;
+ 
+ 	addr = (unsigned long) address;
+ 	pgd = pgd_offset(current->mm, addr);
+-	pmd = pmd_offset(pgd, addr);
++	pud = pud_offset(pgd, addr);
++	pmd = pmd_offset(pud, addr);
+ 	pte = pte_offset(pmd, addr);
+ 	paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
+ 	paddr |= (addr & ~PAGE_MASK);
+diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c
+--- a/arch/mips/lib-64/dump_tlb.c
++++ b/arch/mips/lib-64/dump_tlb.c
+@@ -140,6 +140,7 @@ void dump_tlb_nonwired(void)
+ void dump_list_process(struct task_struct *t, void *address)
+ {
+ 	pgd_t	*page_dir, *pgd;
++	pud_t	*pud;
+ 	pmd_t	*pmd;
+ 	pte_t	*pte, page;
+ 	unsigned long addr, val;
+@@ -155,7 +156,10 @@ void dump_list_process(struct task_struc
+ 	pgd = pgd_offset(t->mm, addr);
+ 	printk("pgd == %016lx\n", (unsigned long) pgd);
+ 
+-	pmd = pmd_offset(pgd, addr);
++	pud = pud_offset(pgd, addr);
++	printk("pud == %016lx\n", (unsigned long) pud);
++
++	pmd = pmd_offset(pud, addr);
+ 	printk("pmd == %016lx\n", (unsigned long) pmd);
+ 
+ 	pte = pte_offset(pmd, addr);
+@@ -184,13 +188,15 @@ void dump_list_current(void *address)
+ unsigned int vtop(void *address)
+ {
+ 	pgd_t	*pgd;
++	pud_t	*pud;
+ 	pmd_t	*pmd;
+ 	pte_t	*pte;
+ 	unsigned int addr, paddr;
+ 
+ 	addr = (unsigned long) address;
+ 	pgd = pgd_offset(current->mm, addr);
+-	pmd = pmd_offset(pgd, addr);
++	pud = pud_offset(pgd, addr);
++	pmd = pmd_offset(pud, addr);
+ 	pte = pte_offset(pmd, addr);
+ 	paddr = (CKSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
+ 	paddr |= (addr & ~PAGE_MASK);
+diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
+--- a/arch/mips/lib/Makefile
++++ b/arch/mips/lib/Makefile
+@@ -2,8 +2,8 @@
+ # Makefile for MIPS-specific library files..
+ #
+ 
+-lib-y	+= csum_partial_copy.o memcpy.o promlib.o \
+-	   strlen_user.o strncpy_user.o strnlen_user.o
++lib-y	+= csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \
++	   strnlen_user.o uncached.o
+ 
+ obj-y	+= iomap.o
+ 
+diff --git a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c
+--- a/arch/mips/lib/csum_partial_copy.c
++++ b/arch/mips/lib/csum_partial_copy.c
+@@ -16,8 +16,8 @@
+ /*
+  * copy while checksumming, otherwise like csum_partial
+  */
+-unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
+-	int len, unsigned int sum)
++unsigned int csum_partial_copy_nocheck(const unsigned char *src,
++	unsigned char *dst, int len, unsigned int sum)
+ {
+ 	/*
+ 	 * It's 2:30 am and I don't feel like doing it real ...
+@@ -33,8 +33,8 @@ unsigned int csum_partial_copy_nocheck(c
+  * Copy from userspace and compute checksum.  If we catch an exception
+  * then zero the rest of the buffer.
+  */
+-unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
+-	int len, unsigned int sum, int *err_ptr)
++unsigned int csum_partial_copy_from_user (const unsigned char __user *src,
++	unsigned char *dst, int len, unsigned int sum, int *err_ptr)
+ {
+ 	int missing;
+ 
+diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
+--- a/arch/mips/lib/memcpy.S
++++ b/arch/mips/lib/memcpy.S
+@@ -13,6 +13,21 @@
+  * Mnemonic names for arguments to memcpy/__copy_user
+  */
+ #include <linux/config.h>
++
++/*
++ * Hack to resolve longstanding prefetch issue
++ *
++ * Prefetching may be fatal on some systems if we're prefetching beyond the
++ * end of memory on some systems.  It's also a seriously bad idea on non
++ * dma-coherent systems.
++ */
++#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27)
++#undef CONFIG_CPU_HAS_PREFETCH
++#endif
++#ifdef CONFIG_MIPS_MALTA
++#undef CONFIG_CPU_HAS_PREFETCH
++#endif
++
+ #include <asm/asm.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/regdef.h>
+diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/lib/uncached.c
+@@ -0,0 +1,76 @@
++/*
++ * 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 Thiemo Seufer
++ * Copyright (C) 2005  MIPS Technologies, Inc.  All rights reserved.
++ *	Author: Maciej W. Rozycki <macro at mips.com>
++ */
++
++#include <linux/init.h>
++
++#include <asm/addrspace.h>
++#include <asm/bug.h>
++
++#ifndef CKSEG2
++#define CKSEG2 CKSSEG
++#endif
++#ifndef TO_PHYS_MASK
++#define TO_PHYS_MASK -1
++#endif
++
++/*
++ * FUNC is executed in one of the uncached segments, depending on its
++ * original address as follows:
++ *
++ * 1. If the original address is in CKSEG0 or CKSEG1, then the uncached
++ *    segment used is CKSEG1.
++ * 2. If the original address is in XKPHYS, then the uncached segment
++ *    used is XKPHYS(2).
++ * 3. Otherwise it's a bug.
++ *
++ * The same remapping is done with the stack pointer.  Stack handling
++ * works because we don't handle stack arguments or more complex return
++ * values, so we can avoid sharing the same stack area between a cached
++ * and the uncached mode.
++ */
++unsigned long __init run_uncached(void *func)
++{
++	register long sp __asm__("$sp");
++	register long ret __asm__("$2");
++	long lfunc = (long)func, ufunc;
++	long usp;
++
++	if (sp >= (long)CKSEG0 && sp < (long)CKSEG2)
++		usp = CKSEG1ADDR(sp);
++	else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0LL, 0) &&
++		 (long long)sp < (long long)PHYS_TO_XKPHYS(8LL, 0))
++		usp = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED,
++				     XKPHYS_TO_PHYS((long long)sp));
++	else {
++		BUG();
++		usp = sp;
++	}
++	if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2)
++		ufunc = CKSEG1ADDR(lfunc);
++	else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0LL, 0) &&
++		 (long long)lfunc < (long long)PHYS_TO_XKPHYS(8LL, 0))
++		ufunc = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED,
++				       XKPHYS_TO_PHYS((long long)lfunc));
++	else {
++		BUG();
++		ufunc = lfunc;
++	}
++
++	__asm__ __volatile__ (
++		"	move	$16, $sp\n"
++		"	move	$sp, %1\n"
++		"	jalr	%2\n"
++		"	move	$sp, $16"
++		: "=r" (ret)
++		: "r" (usp), "r" (ufunc)
++		: "$16", "$31");
++
++	return ret;
++}
+diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
+--- a/arch/mips/math-emu/cp1emu.c
++++ b/arch/mips/math-emu/cp1emu.c
+@@ -70,7 +70,7 @@ static int fpux_emu(struct pt_regs *,
+ 
+ /* Further private data for which no space exists in mips_fpu_soft_struct */
+ 
+-struct mips_fpu_emulator_private fpuemuprivate;
++struct mips_fpu_emulator_stats fpuemustats;
+ 
+ /* Control registers */
+ 
+@@ -79,7 +79,17 @@ struct mips_fpu_emulator_private fpuemup
+ 
+ /* Convert Mips rounding mode (0..3) to IEEE library modes. */
+ static const unsigned char ieee_rm[4] = {
+-	IEEE754_RN, IEEE754_RZ, IEEE754_RU, IEEE754_RD
++	[FPU_CSR_RN] = IEEE754_RN,
++	[FPU_CSR_RZ] = IEEE754_RZ,
++	[FPU_CSR_RU] = IEEE754_RU,
++	[FPU_CSR_RD] = IEEE754_RD,
++};
++/* Convert IEEE library modes to Mips rounding mode (0..3). */
++static const unsigned char mips_rm[4] = {
++	[IEEE754_RN] = FPU_CSR_RN,
++	[IEEE754_RZ] = FPU_CSR_RZ,
++	[IEEE754_RD] = FPU_CSR_RD,
++	[IEEE754_RU] = FPU_CSR_RU,
+ };
+ 
+ #if __mips >= 4
+@@ -196,11 +206,11 @@ static int isBranchInstr(mips_instructio
+ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
+ {
+ 	mips_instruction ir;
+-	vaddr_t emulpc, contpc;
++	void * emulpc, *contpc;
+ 	unsigned int cond;
+ 
+-	if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) {
+-		fpuemuprivate.stats.errors++;
++	if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
++		fpuemustats.errors++;
+ 		return SIGBUS;
+ 	}
+ 
+@@ -221,41 +231,39 @@ static int cop1Emulate(struct pt_regs *x
+ 		 * Linux MIPS branch emulator operates on context, updating the
+ 		 * cp0_epc.
+ 		 */
+-		emulpc = REG_TO_VA(xcp->cp0_epc + 4);	/* Snapshot emulation target */
++		emulpc = (void *) (xcp->cp0_epc + 4);	/* Snapshot emulation target */
+ 
+ 		if (__compute_return_epc(xcp)) {
+ #ifdef CP1DBG
+ 			printk("failed to emulate branch at %p\n",
+-				REG_TO_VA(xcp->cp0_epc));
++				(void *) (xcp->cp0_epc));
+ #endif
+ 			return SIGILL;
+ 		}
+-		if (get_user(ir, (mips_instruction *) emulpc)) {
+-			fpuemuprivate.stats.errors++;
++		if (get_user(ir, (mips_instruction __user *) emulpc)) {
++			fpuemustats.errors++;
+ 			return SIGBUS;
+ 		}
+ 		/* __compute_return_epc() will have updated cp0_epc */
+-		contpc = REG_TO_VA xcp->cp0_epc;
++		contpc = (void *)  xcp->cp0_epc;
+ 		/* In order not to confuse ptrace() et al, tweak context */
+-		xcp->cp0_epc = VA_TO_REG emulpc - 4;
+-	}
+-	else {
+-		emulpc = REG_TO_VA xcp->cp0_epc;
+-		contpc = REG_TO_VA(xcp->cp0_epc + 4);
++		xcp->cp0_epc = (unsigned long) emulpc - 4;
++	} else {
++		emulpc = (void *)  xcp->cp0_epc;
++		contpc = (void *) (xcp->cp0_epc + 4);
+ 	}
+ 
+       emul:
+-	fpuemuprivate.stats.emulated++;
++	fpuemustats.emulated++;
+ 	switch (MIPSInst_OPCODE(ir)) {
+-#ifndef SINGLE_ONLY_FPU
+ 	case ldc1_op:{
+-		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
++		u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
+ 			MIPSInst_SIMM(ir));
+ 		u64 val;
+ 
+-		fpuemuprivate.stats.loads++;
++		fpuemustats.loads++;
+ 		if (get_user(val, va)) {
+-			fpuemuprivate.stats.errors++;
++			fpuemustats.errors++;
+ 			return SIGBUS;
+ 		}
+ 		DITOREG(val, MIPSInst_RT(ir));
+@@ -263,55 +271,42 @@ static int cop1Emulate(struct pt_regs *x
+ 	}
+ 
+ 	case sdc1_op:{
+-		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
++		u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
+ 			MIPSInst_SIMM(ir));
+ 		u64 val;
+ 
+-		fpuemuprivate.stats.stores++;
++		fpuemustats.stores++;
+ 		DIFROMREG(val, MIPSInst_RT(ir));
+ 		if (put_user(val, va)) {
+-			fpuemuprivate.stats.errors++;
++			fpuemustats.errors++;
+ 			return SIGBUS;
+ 		}
+ 		break;
+ 	}
+-#endif
+ 
+ 	case lwc1_op:{
+-		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
++		u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
+ 			MIPSInst_SIMM(ir));
+ 		u32 val;
+ 
+-		fpuemuprivate.stats.loads++;
++		fpuemustats.loads++;
+ 		if (get_user(val, va)) {
+-			fpuemuprivate.stats.errors++;
++			fpuemustats.errors++;
+ 			return SIGBUS;
+ 		}
+-#ifdef SINGLE_ONLY_FPU
+-		if (MIPSInst_RT(ir) & 1) {
+-			/* illegal register in single-float mode */
+-			return SIGILL;
+-		}
+-#endif
+ 		SITOREG(val, MIPSInst_RT(ir));
+ 		break;
+ 	}
+ 
+ 	case swc1_op:{
+-		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
++		u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
+ 			MIPSInst_SIMM(ir));
+ 		u32 val;
+ 
+-		fpuemuprivate.stats.stores++;
+-#ifdef SINGLE_ONLY_FPU
+-		if (MIPSInst_RT(ir) & 1) {
+-			/* illegal register in single-float mode */
+-			return SIGILL;
+-		}
+-#endif
++		fpuemustats.stores++;
+ 		SIFROMREG(val, MIPSInst_RT(ir));
+ 		if (put_user(val, va)) {
+-			fpuemuprivate.stats.errors++;
++			fpuemustats.errors++;
+ 			return SIGBUS;
+ 		}
+ 		break;
+@@ -320,7 +315,7 @@ static int cop1Emulate(struct pt_regs *x
+ 	case cop1_op:
+ 		switch (MIPSInst_RS(ir)) {
+ 
+-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
++#if defined(__mips64)
+ 		case dmfc_op:
+ 			/* copregister fs -> gpr[rt] */
+ 			if (MIPSInst_RT(ir) != 0) {
+@@ -337,12 +332,6 @@ static int cop1Emulate(struct pt_regs *x
+ 
+ 		case mfc_op:
+ 			/* copregister rd -> gpr[rt] */
+-#ifdef SINGLE_ONLY_FPU
+-			if (MIPSInst_RD(ir) & 1) {
+-				/* illegal register in single-float mode */
+-				return SIGILL;
+-			}
+-#endif
+ 			if (MIPSInst_RT(ir) != 0) {
+ 				SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
+ 					MIPSInst_RD(ir));
+@@ -351,12 +340,6 @@ static int cop1Emulate(struct pt_regs *x
+ 
+ 		case mtc_op:
+ 			/* copregister rd <- rt */
+-#ifdef SINGLE_ONLY_FPU
+-			if (MIPSInst_RD(ir) & 1) {
+-				/* illegal register in single-float mode */
+-				return SIGILL;
+-			}
+-#endif
+ 			SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
+ 			break;
+ 
+@@ -369,9 +352,10 @@ static int cop1Emulate(struct pt_regs *x
+ 			}
+ 			if (MIPSInst_RD(ir) == FPCREG_CSR) {
+ 				value = ctx->fcr31;
++				value = (value & ~0x3) | mips_rm[value & 0x3];
+ #ifdef CSRTRACE
+ 				printk("%p gpr[%d]<-csr=%08x\n",
+-					REG_TO_VA(xcp->cp0_epc),
++					(void *) (xcp->cp0_epc),
+ 					MIPSInst_RT(ir), value);
+ #endif
+ 			}
+@@ -398,14 +382,13 @@ static int cop1Emulate(struct pt_regs *x
+ 			if (MIPSInst_RD(ir) == FPCREG_CSR) {
+ #ifdef CSRTRACE
+ 				printk("%p gpr[%d]->csr=%08x\n",
+-					REG_TO_VA(xcp->cp0_epc),
++					(void *) (xcp->cp0_epc),
+ 					MIPSInst_RT(ir), value);
+ #endif
+-				ctx->fcr31 = value;
+-				/* copy new rounding mode and
+-				   flush bit to ieee library state! */
+-				ieee754_csr.nod = (ctx->fcr31 & 0x1000000) != 0;
+-				ieee754_csr.rm = ieee_rm[value & 0x3];
++				value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
++				ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
++				/* convert to ieee library modes */
++				ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3];
+ 			}
+ 			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
+ 				return SIGFPE;
+@@ -445,20 +428,20 @@ static int cop1Emulate(struct pt_regs *x
+ 				 * instruction
+ 				 */
+ 				xcp->cp0_epc += 4;
+-				contpc = REG_TO_VA
++				contpc = (void *)
+ 					(xcp->cp0_epc +
+ 					(MIPSInst_SIMM(ir) << 2));
+ 
+-				if (get_user(ir, (mips_instruction *)
+-						REG_TO_VA xcp->cp0_epc)) {
+-					fpuemuprivate.stats.errors++;
++				if (get_user(ir,
++				    (mips_instruction __user *) xcp->cp0_epc)) {
++					fpuemustats.errors++;
+ 					return SIGBUS;
+ 				}
+ 
+ 				switch (MIPSInst_OPCODE(ir)) {
+ 				case lwc1_op:
+ 				case swc1_op:
+-#if (__mips >= 2 || __mips64) && !defined(SINGLE_ONLY_FPU)
++#if (__mips >= 2 || defined(__mips64))
+ 				case ldc1_op:
+ 				case sdc1_op:
+ #endif
+@@ -480,7 +463,7 @@ static int cop1Emulate(struct pt_regs *x
+ 				 * Single step the non-cp1
+ 				 * instruction in the dslot
+ 				 */
+-				return mips_dsemul(xcp, ir, VA_TO_REG contpc);
++				return mips_dsemul(xcp, ir, (unsigned long) contpc);
+ 			}
+ 			else {
+ 				/* branch not taken */
+@@ -539,8 +522,9 @@ static int cop1Emulate(struct pt_regs *x
+ 	}
+ 
+ 	/* we did it !! */
+-	xcp->cp0_epc = VA_TO_REG(contpc);
++	xcp->cp0_epc = (unsigned long) contpc;
+ 	xcp->cp0_cause &= ~CAUSEF_BD;
++
+ 	return 0;
+ }
+ 
+@@ -570,7 +554,7 @@ static const unsigned char cmptab[8] = {
+ static ieee754##p fpemu_##p##_##name (ieee754##p r, ieee754##p s, \
+     ieee754##p t) \
+ { \
+-	struct ieee754_csr ieee754_csr_save; \
++	struct _ieee754_csr ieee754_csr_save; \
+ 	s = f1 (s, t); \
+ 	ieee754_csr_save = ieee754_csr; \
+ 	s = f2 (s, r); \
+@@ -616,54 +600,38 @@ static int fpux_emu(struct pt_regs *xcp,
+ {
+ 	unsigned rcsr = 0;	/* resulting csr */
+ 
+-	fpuemuprivate.stats.cp1xops++;
++	fpuemustats.cp1xops++;
+ 
+ 	switch (MIPSInst_FMA_FFMT(ir)) {
+ 	case s_fmt:{		/* 0 */
+ 
+ 		ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
+ 		ieee754sp fd, fr, fs, ft;
+-		u32 *va;
++		u32 __user *va;
+ 		u32 val;
+ 
+ 		switch (MIPSInst_FUNC(ir)) {
+ 		case lwxc1_op:
+-			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
++			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ 				xcp->regs[MIPSInst_FT(ir)]);
+ 
+-			fpuemuprivate.stats.loads++;
++			fpuemustats.loads++;
+ 			if (get_user(val, va)) {
+-				fpuemuprivate.stats.errors++;
++				fpuemustats.errors++;
+ 				return SIGBUS;
+ 			}
+-#ifdef SINGLE_ONLY_FPU
+-			if (MIPSInst_FD(ir) & 1) {
+-				/* illegal register in single-float
+-				 * mode
+-				 */
+-				return SIGILL;
+-			}
+-#endif
+ 			SITOREG(val, MIPSInst_FD(ir));
+ 			break;
+ 
+ 		case swxc1_op:
+-			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
++			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ 				xcp->regs[MIPSInst_FT(ir)]);
+ 
+-			fpuemuprivate.stats.stores++;
+-#ifdef SINGLE_ONLY_FPU
+-			if (MIPSInst_FS(ir) & 1) {
+-				/* illegal register in single-float
+-				 * mode
+-				 */
+-				return SIGILL;
+-			}
+-#endif
++			fpuemustats.stores++;
+ 
+ 			SIFROMREG(val, MIPSInst_FS(ir));
+ 			if (put_user(val, va)) {
+-				fpuemuprivate.stats.errors++;
++				fpuemustats.errors++;
+ 				return SIGBUS;
+ 			}
+ 			break;
+@@ -699,8 +667,6 @@ static int fpux_emu(struct pt_regs *xcp,
+ 				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+ 
+ 			ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
+-			if (ieee754_csr.nod)
+-				ctx->fcr31 |= 0x1000000;
+ 			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
+ 				/*printk ("SIGFPE: fpu csr = %08x\n",
+ 				   ctx->fcr31); */
+@@ -715,34 +681,33 @@ static int fpux_emu(struct pt_regs *xcp,
+ 		break;
+ 	}
+ 
+-#ifndef SINGLE_ONLY_FPU
+ 	case d_fmt:{		/* 1 */
+ 		ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
+ 		ieee754dp fd, fr, fs, ft;
+-		u64 *va;
++		u64 __user *va;
+ 		u64 val;
+ 
+ 		switch (MIPSInst_FUNC(ir)) {
+ 		case ldxc1_op:
+-			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
++			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ 				xcp->regs[MIPSInst_FT(ir)]);
+ 
+-			fpuemuprivate.stats.loads++;
++			fpuemustats.loads++;
+ 			if (get_user(val, va)) {
+-				fpuemuprivate.stats.errors++;
++				fpuemustats.errors++;
+ 				return SIGBUS;
+ 			}
+ 			DITOREG(val, MIPSInst_FD(ir));
+ 			break;
+ 
+ 		case sdxc1_op:
+-			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
++			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ 				xcp->regs[MIPSInst_FT(ir)]);
+ 
+-			fpuemuprivate.stats.stores++;
++			fpuemustats.stores++;
+ 			DIFROMREG(val, MIPSInst_FS(ir));
+ 			if (put_user(val, va)) {
+-				fpuemuprivate.stats.errors++;
++				fpuemustats.errors++;
+ 				return SIGBUS;
+ 			}
+ 			break;
+@@ -773,7 +738,6 @@ static int fpux_emu(struct pt_regs *xcp,
+ 		}
+ 		break;
+ 	}
+-#endif
+ 
+ 	case 0x7:		/* 7 */
+ 		if (MIPSInst_FUNC(ir) != pfetch_op) {
+@@ -810,7 +774,7 @@ static int fpu_emu(struct pt_regs *xcp, 
+ #endif
+ 	} rv;			/* resulting value */
+ 
+-	fpuemuprivate.stats.cp1ops++;
++	fpuemustats.cp1ops++;
+ 	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
+ 	case s_fmt:{		/* 0 */
+ 		union {
+@@ -834,7 +798,7 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 			goto scopbop;
+ 
+ 			/* unary  ops */
+-#if __mips >= 2 || __mips64
++#if __mips >= 2 || defined(__mips64)
+ 		case fsqrt_op:
+ 			handler.u = ieee754sp_sqrt;
+ 			goto scopuop;
+@@ -913,9 +877,6 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 		case fcvts_op:
+ 			return SIGILL;	/* not defined */
+ 		case fcvtd_op:{
+-#ifdef SINGLE_ONLY_FPU
+-			return SIGILL;	/* not defined */
+-#else
+ 			ieee754sp fs;
+ 
+ 			SPFROMREG(fs, MIPSInst_FS(ir));
+@@ -923,7 +884,6 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 			rfmt = d_fmt;
+ 			goto copcsr;
+ 		}
+-#endif
+ 		case fcvtw_op:{
+ 			ieee754sp fs;
+ 
+@@ -933,7 +893,7 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 			goto copcsr;
+ 		}
+ 
+-#if __mips >= 2 || __mips64
++#if __mips >= 2 || defined(__mips64)
+ 		case fround_op:
+ 		case ftrunc_op:
+ 		case fceil_op:
+@@ -950,7 +910,7 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 		}
+ #endif /* __mips >= 2 */
+ 
+-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
++#if defined(__mips64)
+ 		case fcvtl_op:{
+ 			ieee754sp fs;
+ 
+@@ -974,7 +934,7 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 			rfmt = l_fmt;
+ 			goto copcsr;
+ 		}
+-#endif /* __mips64 && !fpu(single) */
++#endif /* defined(__mips64) */
+ 
+ 		default:
+ 			if (MIPSInst_FUNC(ir) >= fcmp_op) {
+@@ -1001,7 +961,6 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 		break;
+ 	}
+ 
+-#ifndef SINGLE_ONLY_FPU
+ 	case d_fmt:{
+ 		union {
+ 			ieee754dp(*b) (ieee754dp, ieee754dp);
+@@ -1024,7 +983,7 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 			goto dcopbop;
+ 
+ 			/* unary  ops */
+-#if __mips >= 2 || __mips64
++#if __mips >= 2 || defined(__mips64)
+ 		case fsqrt_op:
+ 			handler.u = ieee754dp_sqrt;
+ 			goto dcopuop;
+@@ -1108,7 +1067,7 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 			goto copcsr;
+ 		}
+ 
+-#if __mips >= 2 || __mips64
++#if __mips >= 2 || defined(__mips64)
+ 		case fround_op:
+ 		case ftrunc_op:
+ 		case fceil_op:
+@@ -1125,7 +1084,7 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 		}
+ #endif
+ 
+-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
++#if defined(__mips64)
+ 		case fcvtl_op:{
+ 			ieee754dp fs;
+ 
+@@ -1149,7 +1108,7 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 			rfmt = l_fmt;
+ 			goto copcsr;
+ 		}
+-#endif /* __mips >= 3 && !fpu(single) */
++#endif /* __mips >= 3 */
+ 
+ 		default:
+ 			if (MIPSInst_FUNC(ir) >= fcmp_op) {
+@@ -1177,7 +1136,6 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 		}
+ 		break;
+ 	}
+-#endif /* ifndef SINGLE_ONLY_FPU */
+ 
+ 	case w_fmt:{
+ 		ieee754sp fs;
+@@ -1189,21 +1147,19 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 			rv.s = ieee754sp_fint(fs.bits);
+ 			rfmt = s_fmt;
+ 			goto copcsr;
+-#ifndef SINGLE_ONLY_FPU
+ 		case fcvtd_op:
+ 			/* convert word to double precision real */
+ 			SPFROMREG(fs, MIPSInst_FS(ir));
+ 			rv.d = ieee754dp_fint(fs.bits);
+ 			rfmt = d_fmt;
+ 			goto copcsr;
+-#endif
+ 		default:
+ 			return SIGILL;
+ 		}
+ 		break;
+ 	}
+ 
+-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
++#if defined(__mips64)
+ 	case l_fmt:{
+ 		switch (MIPSInst_FUNC(ir)) {
+ 		case fcvts_op:
+@@ -1256,18 +1212,16 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 			ctx->fcr31 &= ~cond;
+ 		break;
+ 	}
+-#ifndef SINGLE_ONLY_FPU
+ 	case d_fmt:
+ 		DPTOREG(rv.d, MIPSInst_FD(ir));
+ 		break;
+-#endif
+ 	case s_fmt:
+ 		SPTOREG(rv.s, MIPSInst_FD(ir));
+ 		break;
+ 	case w_fmt:
+ 		SITOREG(rv.w, MIPSInst_FD(ir));
+ 		break;
+-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
++#if defined(__mips64)
+ 	case l_fmt:
+ 		DITOREG(rv.l, MIPSInst_FD(ir));
+ 		break;
+@@ -1279,10 +1233,10 @@ static int fpu_emu(struct pt_regs *xcp, 
+ 	return 0;
+ }
+ 
+-int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
++int fpu_emulator_cop1Handler(struct pt_regs *xcp,
+ 	struct mips_fpu_soft_struct *ctx)
+ {
+-	gpreg_t oldepc, prevepc;
++	unsigned long oldepc, prevepc;
+ 	mips_instruction insn;
+ 	int sig = 0;
+ 
+@@ -1290,19 +1244,24 @@ int fpu_emulator_cop1Handler(int xcptno,
+ 	do {
+ 		prevepc = xcp->cp0_epc;
+ 
+-		if (get_user(insn, (mips_instruction *) xcp->cp0_epc)) {
+-			fpuemuprivate.stats.errors++;
++		if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
++			fpuemustats.errors++;
+ 			return SIGBUS;
+ 		}
+ 		if (insn == 0)
+ 			xcp->cp0_epc += 4;	/* skip nops */
+ 		else {
+-			/* Update ieee754_csr. Only relevant if we have a
+-			   h/w FPU */
+-			ieee754_csr.nod = (ctx->fcr31 & 0x1000000) != 0;
+-			ieee754_csr.rm = ieee_rm[ctx->fcr31 & 0x3];
+-			ieee754_csr.cx = (ctx->fcr31 >> 12) & 0x1f;
++			/*
++			 * The 'ieee754_csr' is an alias of
++			 * ctx->fcr31.  No need to copy ctx->fcr31 to
++			 * ieee754_csr.  But ieee754_csr.rm is ieee
++			 * library modes. (not mips rounding mode)
++			 */
++			/* convert to ieee library modes */
++			ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
+ 			sig = cop1Emulate(xcp, ctx);
++			/* revert to mips rounding mode */
++			ieee754_csr.rm = mips_rm[ieee754_csr.rm];
+ 		}
+ 
+ 		if (cpu_has_fpu)
+diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c
+--- a/arch/mips/math-emu/dp_sqrt.c
++++ b/arch/mips/math-emu/dp_sqrt.c
+@@ -37,7 +37,7 @@ static const unsigned table[] = {
+ 
+ ieee754dp ieee754dp_sqrt(ieee754dp x)
+ {
+-	struct ieee754_csr oldcsr;
++	struct _ieee754_csr oldcsr;
+ 	ieee754dp y, z, t;
+ 	unsigned scalx, yh;
+ 	COMPXDP;
+diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
+--- a/arch/mips/math-emu/dsemul.c
++++ b/arch/mips/math-emu/dsemul.c
+@@ -28,9 +28,6 @@
+ #endif
+ #define __mips 4
+ 
+-extern struct mips_fpu_emulator_private fpuemuprivate;
+-
+-
+ /*
+  * Emulate the arbritrary instruction ir at xcp->cp0_epc.  Required when
+  * we have to emulate the instruction in a COP1 branch delay slot.  Do
+@@ -52,10 +49,10 @@ struct emuframe {
+ 	mips_instruction	emul;
+ 	mips_instruction	badinst;
+ 	mips_instruction	cookie;
+-	gpreg_t			epc;
++	unsigned long		epc;
+ };
+ 
+-int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
++int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
+ {
+ 	extern asmlinkage void handle_dsemulret(void);
+ 	mips_instruction *dsemul_insns;
+@@ -91,7 +88,7 @@ int mips_dsemul(struct pt_regs *regs, mi
+ 	 */
+ 
+ 	/* Ensure that the two instructions are in the same cache line */
+-	dsemul_insns = (mips_instruction *) REG_TO_VA ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
++	dsemul_insns = (mips_instruction *) ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
+ 	fr = (struct emuframe *) dsemul_insns;
+ 
+ 	/* Verify that the stack pointer is not competely insane */
+@@ -104,11 +101,11 @@ int mips_dsemul(struct pt_regs *regs, mi
+ 	err |= __put_user(cpc, &fr->epc);
+ 
+ 	if (unlikely(err)) {
+-		fpuemuprivate.stats.errors++;
++		fpuemustats.errors++;
+ 		return SIGBUS;
+ 	}
+ 
+-	regs->cp0_epc = VA_TO_REG & fr->emul;
++	regs->cp0_epc = (unsigned long) &fr->emul;
+ 
+ 	flush_cache_sigtramp((unsigned long)&fr->badinst);
+ 
+@@ -118,7 +115,7 @@ int mips_dsemul(struct pt_regs *regs, mi
+ int do_dsemulret(struct pt_regs *xcp)
+ {
+ 	struct emuframe *fr;
+-	gpreg_t epc;
++	unsigned long epc;
+ 	u32 insn, cookie;
+ 	int err = 0;
+ 
+@@ -141,7 +138,7 @@ int do_dsemulret(struct pt_regs *xcp)
+ 	err |= __get_user(cookie, &fr->cookie);
+ 
+ 	if (unlikely(err || (insn != BADINST) || (cookie != BD_COOKIE))) {
+-		fpuemuprivate.stats.errors++;
++		fpuemustats.errors++;
+ 		return 0;
+ 	}
+ 
+diff --git a/arch/mips/math-emu/dsemul.h b/arch/mips/math-emu/dsemul.h
+--- a/arch/mips/math-emu/dsemul.h
++++ b/arch/mips/math-emu/dsemul.h
+@@ -1,11 +1,5 @@
+-typedef long gpreg_t;
+-typedef void *vaddr_t;
+-
+-#define REG_TO_VA (vaddr_t)
+-#define VA_TO_REG (gpreg_t)
+-
+-int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc);
+-int do_dsemulret(struct pt_regs *xcp);
++extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc);
++extern int do_dsemulret(struct pt_regs *xcp);
+ 
+ /* Instruction which will always cause an address error */
+ #define AdELOAD 0x8c000001	/* lw $0,1($0) */
+diff --git a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
+--- a/arch/mips/math-emu/ieee754.c
++++ b/arch/mips/math-emu/ieee754.c
+@@ -31,6 +31,8 @@
+ 
+ 
+ #include "ieee754int.h"
++#include "ieee754sp.h"
++#include "ieee754dp.h"
+ 
+ #define DP_EBIAS	1023
+ #define DP_EMIN		(-1022)
+@@ -40,20 +42,6 @@
+ #define SP_EMIN		(-126)
+ #define SP_EMAX		127
+ 
+-/* indexed by class */
+-const char *const ieee754_cname[] = {
+-	"Normal",
+-	"Zero",
+-	"Denormal",
+-	"Infinity",
+-	"QNaN",
+-	"SNaN",
+-};
+-
+-/* the control status register
+-*/
+-struct ieee754_csr ieee754_csr;
+-
+ /* special constants
+ */
+ 
+diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
+--- a/arch/mips/math-emu/ieee754.h
++++ b/arch/mips/math-emu/ieee754.h
+@@ -1,13 +1,8 @@
+-/* single and double precision fp ops
+- * missing extended precision.
+-*/
+ /*
+  * MIPS floating point support
+  * Copyright (C) 1994-2000 Algorithmics Ltd.
+  * http://www.algor.co.uk
+  *
+- * ########################################################################
+- *
+  *  This program is free software; you can distribute it and/or modify it
+  *  under the terms of the GNU General Public License (Version 2) as
+  *  published by the Free Software Foundation.
+@@ -21,20 +16,18 @@
+  *  with this program; if not, write to the Free Software Foundation, Inc.,
+  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+  *
+- * ########################################################################
+- */
+-
+-/**************************************************************************
+  *  Nov 7, 2000
+  *  Modification to allow integration with Linux kernel
+  *
+  *  Kevin D. Kissell, kevink at mips.com and Carsten Langgard, carstenl at mips.com
+  *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+- *************************************************************************/
++ */
++#ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H
++#define __ARCH_MIPS_MATH_EMU_IEEE754_H
+ 
+-#ifdef __KERNEL__
+-/* Going from Algorithmics to Linux native environment, add this */
++#include <asm/byteorder.h>
+ #include <linux/types.h>
++#include <linux/sched.h>
+ 
+ /*
+  * Not very pretty, but the Linux kernel's normal va_list definition
+@@ -44,18 +37,7 @@
+ #include <stdarg.h>
+ #endif
+ 
+-#else
+-
+-/* Note that __KERNEL__ is taken to mean Linux kernel */
+-
+-#if #system(OpenBSD)
+-#include <machine/types.h>
+-#endif
+-#include <machine/endian.h>
+-
+-#endif				/* __KERNEL__ */
+-
+-#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
++#ifdef __LITTLE_ENDIAN
+ struct ieee754dp_konst {
+ 	unsigned mantlo:32;
+ 	unsigned manthi:20;
+@@ -86,13 +68,14 @@ typedef union _ieee754sp {
+ } ieee754sp;
+ #endif
+ 
+-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
++#ifdef __BIG_ENDIAN
+ struct ieee754dp_konst {
+ 	unsigned sign:1;
+ 	unsigned bexp:11;
+ 	unsigned manthi:20;
+ 	unsigned mantlo:32;
+ };
++
+ typedef union _ieee754dp {
+ 	struct ieee754dp_konst oparts;
+ 	struct {
+@@ -222,7 +205,6 @@ ieee754dp ieee754dp_sqrt(ieee754dp x);
+ #define IEEE754_CLASS_INF	0x03
+ #define IEEE754_CLASS_SNAN	0x04
+ #define IEEE754_CLASS_QNAN	0x05
+-extern const char *const ieee754_cname[];
+ 
+ /* exception numbers */
+ #define IEEE754_INEXACT			0x01
+@@ -251,93 +233,109 @@ extern const char *const ieee754_cname[]
+ 
+ /* "normal" comparisons
+ */
+-static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
++static inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
+ {
+ 	return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
+ }
+ 
+-static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
++static inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
+ {
+ 	return ieee754sp_cmp(x, y,
+ 			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
+ }
+ 
+-static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
++static inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
+ {
+ 	return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
+ }
+ 
+-static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
++static inline int ieee754sp_le(ieee754sp x, ieee754sp y)
+ {
+ 	return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
+ }
+ 
+-static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
++static inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
+ {
+ 	return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
+ }
+ 
+ 
+-static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
++static inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
+ {
+ 	return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
+ }
+ 
+-static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
++static inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
+ {
+ 	return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
+ }
+ 
+-static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
++static inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
+ {
+ 	return ieee754dp_cmp(x, y,
+ 			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
+ }
+ 
+-static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
++static inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
+ {
+ 	return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
+ }
+ 
+-static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
++static inline int ieee754dp_le(ieee754dp x, ieee754dp y)
+ {
+ 	return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
+ }
+ 
+-static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
++static inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
+ {
+ 	return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
+ }
+ 
+-static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
++static inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
+ {
+ 	return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
+ }
+ 
+ 
+-/* like strtod
+-*/
++/*
++ * Like strtod
++ */
+ ieee754dp ieee754dp_fstr(const char *s, char **endp);
+ char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
+ 
+ 
+-/* the control status register
+-*/
+-struct ieee754_csr {
+-	unsigned pad:13;
++/*
++ * The control status register
++ */
++struct _ieee754_csr {
++#ifdef __BIG_ENDIAN
++	unsigned pad0:7;
+ 	unsigned nod:1;		/* set 1 for no denormalised numbers */
+-	unsigned cx:5;		/* exceptions this operation */
++	unsigned c:1;		/* condition */
++	unsigned pad1:5;
++	unsigned cx:6;		/* exceptions this operation */
+ 	unsigned mx:5;		/* exception enable  mask */
+ 	unsigned sx:5;		/* exceptions total */
+ 	unsigned rm:2;		/* current rounding mode */
++#endif
++#ifdef __LITTLE_ENDIAN
++	unsigned rm:2;		/* current rounding mode */
++	unsigned sx:5;		/* exceptions total */
++	unsigned mx:5;		/* exception enable  mask */
++	unsigned cx:6;		/* exceptions this operation */
++	unsigned pad1:5;
++	unsigned c:1;		/* condition */
++	unsigned nod:1;		/* set 1 for no denormalised numbers */
++	unsigned pad0:7;
++#endif
+ };
+-extern struct ieee754_csr ieee754_csr;
++#define ieee754_csr (*(struct _ieee754_csr *)(&current->thread.fpu.soft.fcr31))
+ 
+-static __inline unsigned ieee754_getrm(void)
++static inline unsigned ieee754_getrm(void)
+ {
+ 	return (ieee754_csr.rm);
+ }
+-static __inline unsigned ieee754_setrm(unsigned rm)
++static inline unsigned ieee754_setrm(unsigned rm)
+ {
+ 	return (ieee754_csr.rm = rm);
+ }
+@@ -345,14 +343,14 @@ static __inline unsigned ieee754_setrm(u
+ /*
+  * get current exceptions
+  */
+-static __inline unsigned ieee754_getcx(void)
++static inline unsigned ieee754_getcx(void)
+ {
+ 	return (ieee754_csr.cx);
+ }
+ 
+ /* test for current exception condition
+  */
+-static __inline int ieee754_cxtest(unsigned n)
++static inline int ieee754_cxtest(unsigned n)
+ {
+ 	return (ieee754_csr.cx & n);
+ }
+@@ -360,21 +358,21 @@ static __inline int ieee754_cxtest(unsig
+ /*
+  * get sticky exceptions
+  */
+-static __inline unsigned ieee754_getsx(void)
++static inline unsigned ieee754_getsx(void)
+ {
+ 	return (ieee754_csr.sx);
+ }
+ 
+ /* clear sticky conditions
+ */
+-static __inline unsigned ieee754_clrsx(void)
++static inline unsigned ieee754_clrsx(void)
+ {
+ 	return (ieee754_csr.sx = 0);
+ }
+ 
+ /* test for sticky exception condition
+  */
+-static __inline int ieee754_sxtest(unsigned n)
++static inline int ieee754_sxtest(unsigned n)
+ {
+ 	return (ieee754_csr.sx & n);
+ }
+@@ -406,52 +404,34 @@ extern const struct ieee754sp_konst __ie
+ #define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
+ #define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
+ 
+-/* return infinity with given sign
+-*/
+-#define ieee754dp_inf(sn)	\
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+-#define ieee754dp_zero(sn) \
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+-#define ieee754dp_one(sn) \
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+-#define ieee754dp_ten(sn) \
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+-#define ieee754dp_indef() \
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
+-#define ieee754dp_max(sn) \
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+-#define ieee754dp_min(sn) \
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+-#define ieee754dp_mind(sn) \
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+-#define ieee754dp_1e31() \
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
+-#define ieee754dp_1e63() \
+-  (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
+-
+-#define ieee754sp_inf(sn) \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+-#define ieee754sp_zero(sn) \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+-#define ieee754sp_one(sn) \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+-#define ieee754sp_ten(sn) \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+-#define ieee754sp_indef() \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
+-#define ieee754sp_max(sn) \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+-#define ieee754sp_min(sn) \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+-#define ieee754sp_mind(sn) \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+-#define ieee754sp_1e31() \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
+-#define ieee754sp_1e63() \
+-  (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
++/*
++ * Return infinity with given sign
++ */
++#define ieee754dp_inf(sn)     (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
++#define ieee754dp_zero(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
++#define ieee754dp_one(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
++#define ieee754dp_ten(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
++#define ieee754dp_indef()	(ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
++#define ieee754dp_max(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
++#define ieee754dp_min(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
++#define ieee754dp_mind(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
++#define ieee754dp_1e31()	(ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
++#define ieee754dp_1e63()	(ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
++
++#define ieee754sp_inf(sn)     (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
++#define ieee754sp_zero(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
++#define ieee754sp_one(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
++#define ieee754sp_ten(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
++#define ieee754sp_indef()	(ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
++#define ieee754sp_max(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
++#define ieee754sp_min(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
++#define ieee754sp_mind(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
++#define ieee754sp_1e31()	(ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
++#define ieee754sp_1e63()	(ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
+ 
+-/* indefinite integer value
+-*/
++/*
++ * Indefinite integer value
++ */
+ #define ieee754si_indef()	INT_MAX
+ #ifdef LONG_LONG_MAX
+ #define ieee754di_indef()	LONG_LONG_MAX
+@@ -487,3 +467,5 @@ extern void ieee754_xcpt(struct ieee754x
+ /* compat */
+ #define ieee754dp_fix(x)	ieee754dp_tint(x)
+ #define ieee754sp_fix(x)	ieee754sp_tint(x)
++
++#endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */
+diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c
+--- a/arch/mips/math-emu/kernel_linkage.c
++++ b/arch/mips/math-emu/kernel_linkage.c
+@@ -27,8 +27,6 @@
+ 
+ #include <asm/fpu_emulator.h>
+ 
+-extern struct mips_fpu_emulator_private fpuemuprivate;
+-
+ #define SIGNALLING_NAN 0x7ff800007ff80000LL
+ 
+ void fpu_emulator_init_fpu(void)
+@@ -65,7 +63,6 @@ int fpu_emulator_save_context(struct sig
+ 			       &sc->sc_fpregs[i]);
+ 	}
+ 	err |= __put_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
+-	err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
+ 
+ 	return err;
+ }
+@@ -81,7 +78,6 @@ int fpu_emulator_restore_context(struct 
+ 			       &sc->sc_fpregs[i]);
+ 	}
+ 	err |= __get_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
+-	err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
+ 
+ 	return err;
+ }
+@@ -102,7 +98,6 @@ int fpu_emulator_save_context32(struct s
+ 			       &sc->sc_fpregs[i]);
+ 	}
+ 	err |= __put_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
+-	err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
+ 
+ 	return err;
+ }
+@@ -118,7 +113,6 @@ int fpu_emulator_restore_context32(struc
+ 			       &sc->sc_fpregs[i]);
+ 	}
+ 	err |= __get_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
+-	err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
+ 
+ 	return err;
+ }
+diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
+--- a/arch/mips/mips-boards/atlas/atlas_int.c
++++ b/arch/mips/mips-boards/atlas/atlas_int.c
+@@ -76,14 +76,13 @@ static void end_atlas_irq(unsigned int i
+ }
+ 
+ static struct hw_interrupt_type atlas_irq_type = {
+-	"Atlas",
+-	startup_atlas_irq,
+-	shutdown_atlas_irq,
+-	enable_atlas_irq,
+-	disable_atlas_irq,
+-	mask_and_ack_atlas_irq,
+-	end_atlas_irq,
+-	NULL
++	.typename = "Atlas",
++	.startup = startup_atlas_irq,
++	.shutdown = shutdown_atlas_irq,
++	.enable = enable_atlas_irq,
++	.disable = disable_atlas_irq,
++	.ack = mask_and_ack_atlas_irq,
++	.end = end_atlas_irq,
+ };
+ 
+ static inline int ls1bit32(unsigned int x)
+diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
+--- a/arch/mips/mips-boards/atlas/atlas_setup.c
++++ b/arch/mips/mips-boards/atlas/atlas_setup.c
+@@ -50,8 +50,10 @@ const char *get_system_type(void)
+ 	return "MIPS Atlas";
+ }
+ 
+-static int __init atlas_setup(void)
++void __init plat_setup(void)
+ {
++	mips_pcibios_init();
++
+ 	ioport_resource.end = 0x7fffffff;
+ 
+ 	serial_init ();
+@@ -64,12 +66,8 @@ static int __init atlas_setup(void)
+ 	board_time_init = mips_time_init;
+ 	board_timer_setup = mips_timer_setup;
+ 	rtc_get_time = mips_rtc_get_time;
+-
+-	return 0;
+ }
+ 
+-early_initcall(atlas_setup);
+-
+ static void __init serial_init(void)
+ {
+ #ifdef CONFIG_SERIAL_8250
+diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
+--- a/arch/mips/mips-boards/generic/init.c
++++ b/arch/mips/mips-boards/generic/init.c
+@@ -1,6 +1,8 @@
+ /*
+- * Carsten Langgaard, carstenl at mips.com
+- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
++ * Copyright (C) 1999, 2000, 2004, 2005  MIPS Technologies, Inc.
++ *	All rights reserved.
++ *	Authors: Carsten Langgaard <carstenl at mips.com>
++ *		 Maciej W. Rozycki <macro at mips.com>
+  *
+  *  This program is free software; you can distribute it and/or modify it
+  *  under the terms of the GNU General Public License (Version 2) as
+@@ -22,18 +24,19 @@
+ #include <linux/string.h>
+ #include <linux/kernel.h>
+ 
+-#include <asm/io.h>
+ #include <asm/bootinfo.h>
++#include <asm/gt64120.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/cacheflush.h>
++#include <asm/traps.h>
++
+ #include <asm/mips-boards/prom.h>
+ #include <asm/mips-boards/generic.h>
+-#ifdef CONFIG_MIPS_GT64120
+-#include <asm/gt64120.h>
+-#endif
+-#include <asm/mips-boards/msc01_pci.h>
+ #include <asm/mips-boards/bonito64.h>
+-#ifdef CONFIG_MIPS_MALTA
++#include <asm/mips-boards/msc01_pci.h>
++
+ #include <asm/mips-boards/malta.h>
+-#endif
+ 
+ #ifdef CONFIG_KGDB
+ extern int rs_kgdb_hook(int, int);
+@@ -223,8 +226,34 @@ void __init kgdb_config (void)
+ }
+ #endif
+ 
++void __init mips_nmi_setup (void)
++{
++	void *base;
++	extern char except_vec_nmi;
++
++	base = cpu_has_veic ?
++		(void *)(CAC_BASE + 0xa80) :
++		(void *)(CAC_BASE + 0x380);
++	memcpy(base, &except_vec_nmi, 0x80);
++	flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
++}
++
++void __init mips_ejtag_setup (void)
++{
++	void *base;
++	extern char except_vec_ejtag_debug;
++
++	base = cpu_has_veic ?
++		(void *)(CAC_BASE + 0xa00) :
++		(void *)(CAC_BASE + 0x300);
++	memcpy(base, &except_vec_ejtag_debug, 0x80);
++	flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
++}
++
+ void __init prom_init(void)
+ {
++	u32 start, map, mask, data;
++
+ 	prom_argc = fw_arg0;
+ 	_prom_argv = (int *) fw_arg1;
+ 	_prom_envp = (int *) fw_arg2;
+@@ -266,12 +295,15 @@ void __init prom_init(void)
+ #else
+ 		GT_WRITE(GT_PCI0_CMD_OFS, 0);
+ #endif
++		/* Fix up PCI I/O mapping if necessary (for Atlas).  */
++		start = GT_READ(GT_PCI0IOLD_OFS);
++		map = GT_READ(GT_PCI0IOREMAP_OFS);
++		if ((start & map) != 0) {
++			map &= ~start;
++			GT_WRITE(GT_PCI0IOREMAP_OFS, map);
++		}
+ 
+-#ifdef CONFIG_MIPS_MALTA
+ 		set_io_port_base(MALTA_GT_PORT_BASE);
+-#else
+-		set_io_port_base((unsigned long)ioremap(0, 0x20000000));
+-#endif
+ 		break;
+ 
+ 	case MIPS_REVISION_CORID_CORE_EMUL_BON:
+@@ -300,18 +332,21 @@ void __init prom_init(void)
+ 			BONITO_BONGENCFG_BYTESWAP;
+ #endif
+ 
+-#ifdef CONFIG_MIPS_MALTA
+ 		set_io_port_base(MALTA_BONITO_PORT_BASE);
+-#else
+-		set_io_port_base((unsigned long)ioremap(0, 0x20000000));
+-#endif
+ 		break;
+ 
+ 	case MIPS_REVISION_CORID_CORE_MSC:
+ 	case MIPS_REVISION_CORID_CORE_FPGA2:
++	case MIPS_REVISION_CORID_CORE_FPGA3:
+ 	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ 		_pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000);
+ 
++		mb();
++		MSC_READ(MSC01_PCI_CFG, data);
++		MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT);
++		wmb();
++
++		/* Fix up lane swapping.  */
+ #ifdef CONFIG_CPU_LITTLE_ENDIAN
+ 		MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
+ #else
+@@ -320,12 +355,23 @@ void __init prom_init(void)
+ 			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
+ 			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
+ #endif
++		/* Fix up target memory mapping.  */
++		MSC_READ(MSC01_PCI_BAR0, mask);
++		MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK);
++
++		/* Don't handle target retries indefinitely.  */
++		if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
++		    MSC01_PCI_CFG_MAXRTRY_MSK)
++			data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK <<
++					 MSC01_PCI_CFG_MAXRTRY_SHF)) |
++			       ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) <<
++				MSC01_PCI_CFG_MAXRTRY_SHF);
++
++		wmb();
++		MSC_WRITE(MSC01_PCI_CFG, data);
++		mb();
+ 
+-#ifdef CONFIG_MIPS_MALTA
+ 		set_io_port_base(MALTA_MSC_PORT_BASE);
+-#else
+-		set_io_port_base((unsigned long)ioremap(0, 0x20000000));
+-#endif
+ 		break;
+ 
+ 	default:
+@@ -334,6 +380,9 @@ void __init prom_init(void)
+ 		while(1);   /* We die here... */
+ 	}
+ #endif
++	board_nmi_handler_setup = mips_nmi_setup;
++	board_ejtag_handler_setup = mips_ejtag_setup;
++
+ 	prom_printf("\nLINUX started...\n");
+ 	prom_init_cmdline();
+ 	prom_meminit();
+diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
+--- a/arch/mips/mips-boards/generic/memory.c
++++ b/arch/mips/mips-boards/generic/memory.c
+@@ -22,6 +22,7 @@
+ #include <linux/init.h>
+ #include <linux/mm.h>
+ #include <linux/bootmem.h>
++#include <linux/string.h>
+ 
+ #include <asm/bootinfo.h>
+ #include <asm/page.h>
+@@ -55,18 +56,30 @@ struct prom_pmemblock * __init prom_getm
+ {
+ 	char *memsize_str;
+ 	unsigned int memsize;
++	char cmdline[CL_SIZE], *ptr;
+ 
+-	memsize_str = prom_getenv("memsize");
+-	if (!memsize_str) {
+-		prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
+-		memsize = 0x02000000;
+-	} else {
++	/* Check the command line first for a memsize directive */
++	strcpy(cmdline, arcs_cmdline);
++	ptr = strstr(cmdline, "memsize=");
++	if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
++		ptr = strstr(ptr, " memsize=");
++
++	if (ptr) {
++		memsize = memparse(ptr + 8, &ptr);
++	}
++	else {
++		/* otherwise look in the environment */
++		memsize_str = prom_getenv("memsize");
++		if (!memsize_str) {
++			prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
++			memsize = 0x02000000;
++		} else {
+ #ifdef DEBUG
+-		prom_printf("prom_memsize = %s\n", memsize_str);
++			prom_printf("prom_memsize = %s\n", memsize_str);
+ #endif
+-		memsize = simple_strtol(memsize_str, NULL, 0);
++			memsize = simple_strtol(memsize_str, NULL, 0);
++		}
+ 	}
+-
+ 	memset(mdesc, 0, sizeof(mdesc));
+ 
+ 	mdesc[0].type = yamon_dontuse;
+diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S
+--- a/arch/mips/mips-boards/generic/mipsIRQ.S
++++ b/arch/mips/mips-boards/generic/mipsIRQ.S
+@@ -29,6 +29,20 @@
+ #include <asm/regdef.h>
+ #include <asm/stackframe.h>
+ 
++#ifdef CONFIG_MIPS_ATLAS
++#include <asm/mips-boards/atlasint.h>
++#define CASCADE_IRQ		MIPSCPU_INT_ATLAS
++#define CASCADE_DISPATCH	atlas_hw0_irqdispatch
++#endif
++#ifdef CONFIG_MIPS_MALTA
++#include <asm/mips-boards/maltaint.h>
++#define CASCADE_IRQ		MIPSCPU_INT_I8259A
++#define CASCADE_DISPATCH	malta_hw0_irqdispatch
++#endif
++#ifdef CONFIG_MIPS_SEAD
++#include <asm/mips-boards/seadint.h>
++#endif
++
+ /* A lot of complication here is taken away because:
+  *
+  * 1) We handle one interrupt and return, sitting in a loop and moving across
+@@ -80,74 +94,62 @@
+ 
+ 	mfc0	s0, CP0_CAUSE		# get irq bits
+ 	mfc0	s1, CP0_STATUS		# get irq mask
++	andi	s0, ST0_IM		# CAUSE.CE may be non-zero!
+ 	and	s0, s1
+ 
+-	/* First we check for r4k counter/timer IRQ. */
+-	andi	a0, s0, CAUSEF_IP7
+-	beq	a0, zero, 1f
+-	 andi	a0, s0, CAUSEF_IP2	# delay slot, check hw0 interrupt
+-
+-	/* Wheee, a timer interrupt. */
+-	move	a0, sp
+-	jal	mips_timer_interrupt
+-	 nop
+-
+-	j	ret_from_irq
+-	 nop
+-
+-1:
+-#if defined(CONFIG_MIPS_SEAD)
+-	beq	a0, zero, 1f
+-	 andi	a0, s0, CAUSEF_IP3	# delay slot, check hw1 interrupt
++#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
++ 	.set	mips32
++	clz	a0, s0
++	.set	mips0
++	negu	a0
++	addu	a0, 31-CAUSEB_IP
++	bltz	a0, spurious
+ #else
+-	beq	a0, zero, 1f		# delay slot, check hw3 interrupt
+- 	 andi	a0, s0, CAUSEF_IP5
+-#endif
++	beqz	s0, spurious
++	 li	a0, 7
+ 
+-	/* Wheee, combined hardware level zero interrupt. */
+-#if defined(CONFIG_MIPS_ATLAS)
+-	jal	atlas_hw0_irqdispatch
+-#elif defined(CONFIG_MIPS_MALTA)
+-	jal	malta_hw0_irqdispatch
+-#elif defined(CONFIG_MIPS_SEAD)
+-	jal	sead_hw0_irqdispatch
+-#else
+-#error "MIPS board not supported\n"
++	and	t0, s0, 0xf000
++	sltiu	t0, t0, 1
++	sll	t0, 2
++	subu	a0, t0
++	sll	s0, t0
++
++	and	t0, s0, 0xc000
++	sltiu	t0, t0, 1
++	sll	t0, 1
++	subu	a0, t0
++	sll	s0, t0
++
++	and	t0, s0, 0x8000
++	sltiu	t0, t0, 1
++	# sll	t0, 0
++	subu	a0, t0
++	# sll	s0, t0
+ #endif
+-	 move	a0, sp			# delay slot
+ 
+-	j	ret_from_irq
+-	 nop				# delay slot
++#ifdef CASCADE_IRQ
++	 li	a1, CASCADE_IRQ
++	bne	a0, a1, 1f
++	 addu	a0, MIPSCPU_INT_BASE
++
++	jal	CASCADE_DISPATCH
++	 move	 a0, sp
+ 
+-1:
+-#if defined(CONFIG_MIPS_SEAD)
+-	beq	a0, zero, 1f
+-	 andi	a0, s0, CAUSEF_IP5	# delay slot, check hw3 interrupt
+-	jal	sead_hw1_irqdispatch
+-	 move	a0, sp			# delay slot
+-	j	ret_from_irq
+-	 nop				# delay slot
+-1:
+-#endif
+-#if defined(CONFIG_MIPS_MALTA)
+-	beq	a0, zero, 1f            # check hw3 (coreHI) interrupt
+-	 nop
+-	jal	corehi_irqdispatch
+-	 move	a0, sp
+ 	j	ret_from_irq
+ 	 nop
+ 1:
++#else
++	 addu	a0, MIPSCPU_INT_BASE
+ #endif
+-	/*
+-	 * Here by mistake?  This is possible, what can happen is that by the
+-	 * time we take the exception the IRQ pin goes low, so just leave if
+-	 * this is the case.
+-	 */
+-	move	a1,s0
+-	PRINT("Got interrupt: c0_cause = %08x\n")
+-	mfc0	a1, CP0_EPC
+-	PRINT("c0_epc = %08x\n")
++
++	jal	do_IRQ
++	 move	a1, sp
+ 
+ 	j	ret_from_irq
+ 	 nop
++
++
++spurious:
++	j	spurious_interrupt
++	 nop
+ 	END(mipsIRQ)
+diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c
+--- a/arch/mips/mips-boards/generic/pci.c
++++ b/arch/mips/mips-boards/generic/pci.c
+@@ -1,6 +1,8 @@
+ /*
+- * Carsten Langgaard, carstenl at mips.com
+- * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
++ * Copyright (C) 1999, 2000, 2004, 2005  MIPS Technologies, Inc.
++ *	All rights reserved.
++ *	Authors: Carsten Langgaard <carstenl at mips.com>
++ *		 Maciej W. Rozycki <macro at mips.com>
+  *
+  * Copyright (C) 2004 by Ralf Baechle (ralf at linux-mips.org)
+  *
+@@ -19,65 +21,46 @@
+  *
+  * MIPS boards specific PCI support.
+  */
+-#include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ 
+-#include <asm/mips-boards/generic.h>
+ #include <asm/gt64120.h>
++
++#include <asm/mips-boards/generic.h>
+ #include <asm/mips-boards/bonito64.h>
+ #include <asm/mips-boards/msc01_pci.h>
+-#ifdef CONFIG_MIPS_MALTA
+-#include <asm/mips-boards/malta.h>
+-#endif
+ 
+ static struct resource bonito64_mem_resource = {
+ 	.name	= "Bonito PCI MEM",
+-	.start	= 0x10000000UL,
+-	.end	= 0x1bffffffUL,
+ 	.flags	= IORESOURCE_MEM,
+ };
+ 
+ static struct resource bonito64_io_resource = {
+-	.name	= "Bonito IO MEM",
+-	.start	= 0x00002000UL,	/* avoid conflicts with YAMON allocated I/O addresses */
++	.name	= "Bonito PCI I/O",
++	.start	= 0x00000000UL,
+ 	.end	= 0x000fffffUL,
+ 	.flags	= IORESOURCE_IO,
+ };
+ 
+ static struct resource gt64120_mem_resource = {
+-	.name	= "GT64120 PCI MEM",
+-	.start	= 0x10000000UL,
+-	.end	= 0x1bdfffffUL,
++	.name	= "GT-64120 PCI MEM",
+ 	.flags	= IORESOURCE_MEM,
+ };
+ 
+ static struct resource gt64120_io_resource = {
+-	.name	= "GT64120 IO MEM",
+-#ifdef CONFIG_MIPS_ATLAS
+-	.start	= 0x18000000UL,
+-	.end	= 0x181fffffUL,
+-#endif
+-#ifdef CONFIG_MIPS_MALTA
+-	.start	= 0x00002000UL,
+-	.end	= 0x001fffffUL,
+-#endif
++	.name	= "GT-64120 PCI I/O",
+ 	.flags	= IORESOURCE_IO,
+ };
+ 
+ static struct resource msc_mem_resource = {
+ 	.name	= "MSC PCI MEM",
+-	.start	= 0x10000000UL,
+-	.end	= 0x1fffffffUL,
+ 	.flags	= IORESOURCE_MEM,
+ };
+ 
+ static struct resource msc_io_resource = {
+-	.name	= "MSC IO MEM",
+-	.start	= 0x00002000UL,
+-	.end	= 0x007fffffUL,
++	.name	= "MSC PCI I/O",
+ 	.flags	= IORESOURCE_IO,
+ };
+ 
+@@ -89,7 +72,6 @@ static struct pci_controller bonito64_co
+ 	.pci_ops	= &bonito64_pci_ops,
+ 	.io_resource	= &bonito64_io_resource,
+ 	.mem_resource	= &bonito64_mem_resource,
+-	.mem_offset	= 0x10000000UL,
+ 	.io_offset	= 0x00000000UL,
+ };
+ 
+@@ -97,21 +79,18 @@ static struct pci_controller gt64120_con
+ 	.pci_ops	= &gt64120_pci_ops,
+ 	.io_resource	= &gt64120_io_resource,
+ 	.mem_resource	= &gt64120_mem_resource,
+-	.mem_offset	= 0x00000000UL,
+-	.io_offset	= 0x00000000UL,
+ };
+ 
+-static struct pci_controller  msc_controller = {
++static struct pci_controller msc_controller = {
+ 	.pci_ops	= &msc_pci_ops,
+ 	.io_resource	= &msc_io_resource,
+ 	.mem_resource	= &msc_mem_resource,
+-	.mem_offset	= 0x10000000UL,
+-	.io_offset	= 0x00000000UL,
+ };
+ 
+-static int __init pcibios_init(void)
++void __init mips_pcibios_init(void)
+ {
+ 	struct pci_controller *controller;
++	unsigned long start, end, map, start1, end1, map1, map2, map3, mask;
+ 
+ 	switch (mips_revision_corid) {
+ 	case MIPS_REVISION_CORID_QED_RM5261:
+@@ -130,34 +109,140 @@ static int __init pcibios_init(void)
+ 			 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
+ 			 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
+ 			 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
+-			 GT_PCI0_CFGADDR_CONFIGEN_BIT );
++			 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+ 
+ 		/* Perform the write */
+ 		GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
+ 
++		/* Set up resource ranges from the controller's registers.  */
++		start = GT_READ(GT_PCI0M0LD_OFS);
++		end = GT_READ(GT_PCI0M0HD_OFS);
++		map = GT_READ(GT_PCI0M0REMAP_OFS);
++		end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
++		start1 = GT_READ(GT_PCI0M1LD_OFS);
++		end1 = GT_READ(GT_PCI0M1HD_OFS);
++		map1 = GT_READ(GT_PCI0M1REMAP_OFS);
++		end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
++		/* Cannot support multiple windows, use the wider.  */
++		if (end1 - start1 > end - start) {
++			start = start1;
++			end = end1;
++			map = map1;
++		}
++		mask = ~(start ^ end);
++                /* We don't support remapping with a discontiguous mask.  */
++		BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
++		       mask != ~((mask & -mask) - 1));
++		gt64120_mem_resource.start = start;
++		gt64120_mem_resource.end = end;
++		gt64120_controller.mem_offset = (start & mask) - (map & mask);
++		/* Addresses are 36-bit, so do shifts in the destinations.  */
++		gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
++		gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
++		gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
++		gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
++
++		start = GT_READ(GT_PCI0IOLD_OFS);
++		end = GT_READ(GT_PCI0IOHD_OFS);
++		map = GT_READ(GT_PCI0IOREMAP_OFS);
++		end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
++		mask = ~(start ^ end);
++                /* We don't support remapping with a discontiguous mask.  */
++		BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
++		       mask != ~((mask & -mask) - 1));
++		gt64120_io_resource.start = map & mask;
++		gt64120_io_resource.end = (map & mask) | ~mask;
++		gt64120_controller.io_offset = 0;
++		/* Addresses are 36-bit, so do shifts in the destinations.  */
++		gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
++		gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
++		gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
++
+ 		controller = &gt64120_controller;
+ 		break;
+ 
+ 	case MIPS_REVISION_CORID_BONITO64:
+ 	case MIPS_REVISION_CORID_CORE_20K:
+ 	case MIPS_REVISION_CORID_CORE_EMUL_BON:
++		/* Set up resource ranges from the controller's registers.  */
++		map = BONITO_PCIMAP;
++		map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >>
++		       BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
++		map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >>
++		       BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
++		map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >>
++		       BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
++		/* Combine as many adjacent windows as possible.  */
++		map = map1;
++		start = BONITO_PCILO0_BASE;
++		end = 1;
++		if (map3 == map2 + 1) {
++			map = map2;
++			start = BONITO_PCILO1_BASE;
++			end++;
++		}
++		if (map2 == map1 + 1) {
++			map = map1;
++			start = BONITO_PCILO0_BASE;
++			end++;
++		}
++		bonito64_mem_resource.start = start;
++		bonito64_mem_resource.end = start +
++					    BONITO_PCIMAP_WINBASE(end) - 1;
++		bonito64_controller.mem_offset = start -
++						 BONITO_PCIMAP_WINBASE(map);
++
+ 		controller = &bonito64_controller;
+ 		break;
+ 
+ 	case MIPS_REVISION_CORID_CORE_MSC:
+ 	case MIPS_REVISION_CORID_CORE_FPGA2:
++	case MIPS_REVISION_CORID_CORE_FPGA3:
+ 	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
++		/* Set up resource ranges from the controller's registers.  */
++		MSC_READ(MSC01_PCI_SC2PMBASL, start);
++		MSC_READ(MSC01_PCI_SC2PMMSKL, mask);
++		MSC_READ(MSC01_PCI_SC2PMMAPL, map);
++		msc_mem_resource.start = start & mask;
++		msc_mem_resource.end = (start & mask) | ~mask;
++		msc_controller.mem_offset = (start & mask) - (map & mask);
++
++		MSC_READ(MSC01_PCI_SC2PIOBASL, start);
++		MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
++		MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
++		msc_io_resource.start = map & mask;
++		msc_io_resource.end = (map & mask) | ~mask;
++		msc_controller.io_offset = 0;
++		ioport_resource.end = ~mask;
++
++		/* If ranges overlap I/O takes precedence.  */
++		start = start & mask;
++		end = start | ~mask;
++		if ((start >= msc_mem_resource.start &&
++		     start <= msc_mem_resource.end) ||
++		    (end >= msc_mem_resource.start &&
++		     end <= msc_mem_resource.end)) {
++			/* Use the larger space.  */
++			start = max(start, msc_mem_resource.start);
++			end = min(end, msc_mem_resource.end);
++			if (start - msc_mem_resource.start >=
++			    msc_mem_resource.end - end)
++				msc_mem_resource.end = start - 1;
++			else
++				msc_mem_resource.start = end + 1;
++		}
++
+ 		controller = &msc_controller;
+ 		break;
+ 	default:
+-		return 1;
++		return;
+ 	}
+ 
++	if (controller->io_resource->start < 0x00001000UL)	/* FIXME */
++		controller->io_resource->start = 0x00001000UL;
++
++	iomem_resource.end &= 0xfffffffffULL;			/* 64 GB */
+ 	ioport_resource.end = controller->io_resource->end;
+ 
+ 	register_pci_controller (controller);
+-
+-	return 0;
+ }
+-
+-early_initcall(pcibios_init);
+diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
+--- a/arch/mips/mips-boards/generic/time.c
++++ b/arch/mips/mips-boards/generic/time.c
+@@ -31,22 +31,21 @@
+ 
+ #include <asm/mipsregs.h>
+ #include <asm/ptrace.h>
++#include <asm/hardirq.h>
++#include <asm/irq.h>
+ #include <asm/div64.h>
+ #include <asm/cpu.h>
+ #include <asm/time.h>
+ #include <asm/mc146818-time.h>
++#include <asm/msc01_ic.h>
+ 
+ #include <asm/mips-boards/generic.h>
+ #include <asm/mips-boards/prom.h>
++#include <asm/mips-boards/maltaint.h>
++#include <asm/mc146818-time.h>
+ 
+ unsigned long cpu_khz;
+ 
+-#if defined(CONFIG_MIPS_SEAD)
+-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5)
+-#else
+-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+-#endif
+-
+ #if defined(CONFIG_MIPS_ATLAS)
+ static char display_string[] = "        LINUX ON ATLAS       ";
+ #endif
+@@ -59,20 +58,61 @@ static char display_string[] = "        
+ static unsigned int display_count = 0;
+ #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
+ 
+-#define MIPS_CPU_TIMER_IRQ (NR_IRQS-1)
+-
+ static unsigned int timer_tick_count=0;
++static int mips_cpu_timer_irq;
+ 
+-void mips_timer_interrupt(struct pt_regs *regs)
++static inline void scroll_display_message(void)
+ {
+ 	if ((timer_tick_count++ % HZ) == 0) {
+ 		mips_display_message(&display_string[display_count++]);
+ 		if (display_count == MAX_DISPLAY_COUNT)
+-		        display_count = 0;
++			display_count = 0;
++	}
++}
++
++static void mips_timer_dispatch (struct pt_regs *regs)
++{
++	do_IRQ (mips_cpu_timer_irq, regs);
++}
+ 
++irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++#ifdef CONFIG_SMP
++	int cpu = smp_processor_id();
++
++	if (cpu == 0) {
++		/*
++		 * CPU 0 handles the global timer interrupt job and process accounting
++		 * resets count/compare registers to trigger next timer int.
++		 */
++		(void) timer_interrupt(irq, dev_id, regs);
++		scroll_display_message();
++	}
++	else {
++		/* Everyone else needs to reset the timer int here as
++		   ll_local_timer_interrupt doesn't */
++		/*
++		 * FIXME: need to cope with counter underflow.
++		 * More support needs to be added to kernel/time for
++		 * counter/timer interrupts on multiple CPU's
++		 */
++		write_c0_compare (read_c0_count() + (mips_hpt_frequency/HZ));
++		/*
++		 * other CPUs should do profiling and process accounting
++		 */
++		local_timer_interrupt (irq, dev_id, regs);
+ 	}
+ 
+-	ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs);
++	return IRQ_HANDLED;
++#else
++	irqreturn_t r;
++
++	r = timer_interrupt(irq, dev_id, regs);
++
++	scroll_display_message();
++
++	return r;
++#endif
+ }
+ 
+ /*
+@@ -140,10 +180,8 @@ void __init mips_time_init(void)
+ 
+ 	local_irq_save(flags);
+ 
+-#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA)
+         /* Set Data mode - binary. */
+         CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+-#endif
+ 
+ 	est_freq = estimate_cpu_frequency ();
+ 
+@@ -157,11 +195,29 @@ void __init mips_time_init(void)
+ 
+ void __init mips_timer_setup(struct irqaction *irq)
+ {
++	if (cpu_has_veic) {
++		set_vi_handler (MSC01E_INT_CPUCTR, mips_timer_dispatch);
++		mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
++	}
++	else {
++		if (cpu_has_vint)
++			set_vi_handler (MIPSCPU_INT_CPUCTR, mips_timer_dispatch);
++		mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR;
++	}
++
++
+ 	/* we are using the cpu counter for timer interrupts */
+-	irq->handler = no_action;     /* we use our own handler */
+-	setup_irq(MIPS_CPU_TIMER_IRQ, irq);
++	irq->handler = mips_timer_interrupt;	/* we use our own handler */
++	setup_irq(mips_cpu_timer_irq, irq);
++
++#ifdef CONFIG_SMP
++	/* irq_desc(riptor) is a global resource, when the interrupt overlaps
++	   on seperate cpu's the first one tries to handle the second interrupt.
++	   The effect is that the int remains disabled on the second cpu.
++	   Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
++	irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU;
++#endif
+ 
+         /* to generate the first timer interrupt */
+ 	write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ);
+-	set_c0_status(ALLINTS);
+ }
+diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
+--- a/arch/mips/mips-boards/malta/malta_int.c
++++ b/arch/mips/mips-boards/malta/malta_int.c
+@@ -30,6 +30,7 @@
+ #include <linux/random.h>
+ 
+ #include <asm/i8259.h>
++#include <asm/irq_cpu.h>
+ #include <asm/io.h>
+ #include <asm/mips-boards/malta.h>
+ #include <asm/mips-boards/maltaint.h>
+@@ -37,8 +38,10 @@
+ #include <asm/gt64120.h>
+ #include <asm/mips-boards/generic.h>
+ #include <asm/mips-boards/msc01_pci.h>
++#include <asm/msc01_ic.h>
+ 
+ extern asmlinkage void mipsIRQ(void);
++extern void mips_timer_interrupt(void);
+ 
+ static DEFINE_SPINLOCK(mips_irq_lock);
+ 
+@@ -54,6 +57,7 @@ static inline int mips_pcibios_iack(void
+ 	switch(mips_revision_corid) {
+ 	case MIPS_REVISION_CORID_CORE_MSC:
+ 	case MIPS_REVISION_CORID_CORE_FPGA2:
++	case MIPS_REVISION_CORID_CORE_FPGA3:
+ 	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ 	        MSC_READ(MSC01_PCI_IACK, irq);
+ 		irq &= 0xff;
+@@ -91,88 +95,86 @@ static inline int mips_pcibios_iack(void
+ 	return irq;
+ }
+ 
+-static inline int get_int(int *irq)
++static inline int get_int(void)
+ {
+ 	unsigned long flags;
+-
++	int irq;
+ 	spin_lock_irqsave(&mips_irq_lock, flags);
+ 
+-	*irq = mips_pcibios_iack();
++	irq = mips_pcibios_iack();
+ 
+ 	/*
+-	 * IRQ7 is used to detect spurious interrupts.
+-	 * The interrupt acknowledge cycle returns IRQ7, if no
+-	 * interrupts is requested.
+-	 * We can differentiate between this situation and a
+-	 * "Normal" IRQ7 by reading the ISR.
++	 * The only way we can decide if an interrupt is spurious
++	 * is by checking the 8259 registers.  This needs a spinlock
++	 * on an SMP system,  so leave it up to the generic code...
+ 	 */
+-	if (*irq == 7)
+-	{
+-		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR,
+-		     PIIX4_ICTLR1_OCW3);
+-		if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) {
+-			spin_unlock_irqrestore(&mips_irq_lock, flags);
+-			printk("We got a spurious interrupt from PIIX4.\n");
+-			atomic_inc(&irq_err_count);
+-			return -1;    /* Spurious interrupt. */
+-		}
+-	}
+ 
+ 	spin_unlock_irqrestore(&mips_irq_lock, flags);
+ 
+-	return 0;
++	return irq;
+ }
+ 
+ void malta_hw0_irqdispatch(struct pt_regs *regs)
+ {
+ 	int irq;
+ 
+-	if (get_int(&irq))
+-	        return;  /* interrupt has already been cleared */
++	irq = get_int();
++	if (irq < 0)
++		return;  /* interrupt has already been cleared */
+ 
+-	do_IRQ(irq, regs);
++	do_IRQ(MALTA_INT_BASE+irq, regs);
+ }
+ 
+ void corehi_irqdispatch(struct pt_regs *regs)
+ {
+-        unsigned int data,datahi;
+-
+-	/* Mask out corehi interrupt. */
+-	clear_c0_status(IE_IRQ3);
++	unsigned int intrcause,datalo,datahi;
++        unsigned int pcimstat, intisr, inten, intpol, intedge, intsteer, pcicmd, pcibadaddr;
+ 
+         printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n");
+         printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n"
+ , regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr);
++
++	/* Read all the registers and then print them as there is a
++	   problem with interspersed printk's upsetting the Bonito controller.
++	   Do it for the others too.
++	*/
++
+         switch(mips_revision_corid) {
+         case MIPS_REVISION_CORID_CORE_MSC:
+         case MIPS_REVISION_CORID_CORE_FPGA2:
+-	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
++        case MIPS_REVISION_CORID_CORE_FPGA3:
++        case MIPS_REVISION_CORID_CORE_EMUL_MSC:
++                ll_msc_irq(regs);
+                 break;
+         case MIPS_REVISION_CORID_QED_RM5261:
+         case MIPS_REVISION_CORID_CORE_LV:
+         case MIPS_REVISION_CORID_CORE_FPGA:
+         case MIPS_REVISION_CORID_CORE_FPGAR2:
+-                data = GT_READ(GT_INTRCAUSE_OFS);
+-                printk("GT_INTRCAUSE = %08x\n", data);
+-                data = GT_READ(GT_CPUERR_ADDRLO_OFS);
++                intrcause = GT_READ(GT_INTRCAUSE_OFS);
++                datalo = GT_READ(GT_CPUERR_ADDRLO_OFS);
+                 datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
+-                printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data);
++                printk("GT_INTRCAUSE = %08x\n", intrcause);
++                printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo);
+                 break;
+         case MIPS_REVISION_CORID_BONITO64:
+         case MIPS_REVISION_CORID_CORE_20K:
+         case MIPS_REVISION_CORID_CORE_EMUL_BON:
+-                data = BONITO_INTISR;
+-                printk("BONITO_INTISR = %08x\n", data);
+-                data = BONITO_INTEN;
+-                printk("BONITO_INTEN = %08x\n", data);
+-                data = BONITO_INTPOL;
+-                printk("BONITO_INTPOL = %08x\n", data);
+-                data = BONITO_INTEDGE;
+-                printk("BONITO_INTEDGE = %08x\n", data);
+-                data = BONITO_INTSTEER;
+-                printk("BONITO_INTSTEER = %08x\n", data);
+-                data = BONITO_PCICMD;
+-                printk("BONITO_PCICMD = %08x\n", data);
++                pcibadaddr = BONITO_PCIBADADDR;
++                pcimstat = BONITO_PCIMSTAT;
++                intisr = BONITO_INTISR;
++                inten = BONITO_INTEN;
++                intpol = BONITO_INTPOL;
++                intedge = BONITO_INTEDGE;
++                intsteer = BONITO_INTSTEER;
++                pcicmd = BONITO_PCICMD;
++                printk("BONITO_INTISR = %08x\n", intisr);
++                printk("BONITO_INTEN = %08x\n", inten);
++                printk("BONITO_INTPOL = %08x\n", intpol);
++                printk("BONITO_INTEDGE = %08x\n", intedge);
++                printk("BONITO_INTSTEER = %08x\n", intsteer);
++                printk("BONITO_PCICMD = %08x\n", pcicmd);
++                printk("BONITO_PCIBADADDR = %08x\n", pcibadaddr);
++                printk("BONITO_PCIMSTAT = %08x\n", pcimstat);
+                 break;
+         }
+ 
+@@ -180,8 +182,71 @@ void corehi_irqdispatch(struct pt_regs *
+         die("CoreHi interrupt", regs);
+ }
+ 
++static struct irqaction i8259irq = {
++	.handler = no_action,
++	.name = "XT-PIC cascade"
++};
++
++static struct irqaction corehi_irqaction = {
++	.handler = no_action,
++	.name = "CoreHi"
++};
++
++msc_irqmap_t __initdata msc_irqmap[] = {
++	{MSC01C_INT_TMR,		MSC01_IRQ_EDGE, 0},
++	{MSC01C_INT_PCI,		MSC01_IRQ_LEVEL, 0},
++};
++int __initdata msc_nr_irqs = sizeof(msc_irqmap)/sizeof(msc_irqmap_t);
++
++msc_irqmap_t __initdata msc_eicirqmap[] = {
++	{MSC01E_INT_SW0,		MSC01_IRQ_LEVEL, 0},
++	{MSC01E_INT_SW1,		MSC01_IRQ_LEVEL, 0},
++	{MSC01E_INT_I8259A,		MSC01_IRQ_LEVEL, 0},
++	{MSC01E_INT_SMI,		MSC01_IRQ_LEVEL, 0},
++	{MSC01E_INT_COREHI,		MSC01_IRQ_LEVEL, 0},
++	{MSC01E_INT_CORELO,		MSC01_IRQ_LEVEL, 0},
++	{MSC01E_INT_TMR,		MSC01_IRQ_EDGE, 0},
++	{MSC01E_INT_PCI,		MSC01_IRQ_LEVEL, 0},
++	{MSC01E_INT_PERFCTR,		MSC01_IRQ_LEVEL, 0},
++	{MSC01E_INT_CPUCTR,		MSC01_IRQ_LEVEL, 0}
++};
++int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t);
++
+ void __init arch_init_irq(void)
+ {
+ 	set_except_vector(0, mipsIRQ);
+ 	init_i8259_irqs();
++
++	if (!cpu_has_veic)
++		mips_cpu_irq_init (MIPSCPU_INT_BASE);
++
++        switch(mips_revision_corid) {
++        case MIPS_REVISION_CORID_CORE_MSC:
++        case MIPS_REVISION_CORID_CORE_FPGA2:
++        case MIPS_REVISION_CORID_CORE_FPGA3:
++        case MIPS_REVISION_CORID_CORE_EMUL_MSC:
++		if (cpu_has_veic)
++			init_msc_irqs (MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs);
++		else
++			init_msc_irqs (MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs);
++	}
++
++	if (cpu_has_veic) {
++		set_vi_handler (MSC01E_INT_I8259A, malta_hw0_irqdispatch);
++		set_vi_handler (MSC01E_INT_COREHI, corehi_irqdispatch);
++		setup_irq (MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq);
++		setup_irq (MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction);
++	}
++	else if (cpu_has_vint) {
++		set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
++		set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch);
++
++		setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
++		setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
++	}
++	else {
++		set_except_vector(0, mipsIRQ);
++		setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
++		setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
++	}
+ }
+diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
+--- a/arch/mips/mips-boards/malta/malta_setup.c
++++ b/arch/mips/mips-boards/malta/malta_setup.c
+@@ -111,10 +111,12 @@ void __init fd_activate(void)
+ }
+ #endif
+ 
+-static int __init malta_setup(void)
++void __init plat_setup(void)
+ {
+ 	unsigned int i;
+ 
++	mips_pcibios_init();
++
+ 	/* Request I/O space for devices used on the Malta board. */
+ 	for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
+ 		request_resource(&ioport_resource, standard_io_resources+i);
+@@ -224,8 +226,4 @@ static int __init malta_setup(void)
+ 	board_time_init = mips_time_init;
+ 	board_timer_setup = mips_timer_setup;
+ 	rtc_get_time = mips_rtc_get_time;
+-
+-	return 0;
+ }
+-
+-early_initcall(malta_setup);
+diff --git a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c
+--- a/arch/mips/mips-boards/sead/sead_int.c
++++ b/arch/mips/mips-boards/sead/sead_int.c
+@@ -2,6 +2,7 @@
+  * Carsten Langgaard, carstenl at mips.com
+  * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+  * Copyright (C) 2003 Ralf Baechle (ralf at linux-mips.org)
++ * Copyright (C) 2004  Maciej W. Rozycki
+  *
+  *  This program is free software; you can distribute it and/or modify it
+  *  under the terms of the GNU General Public License (Version 2) as
+@@ -21,7 +22,9 @@
+  */
+ #include <linux/init.h>
+ #include <linux/irq.h>
+-#include <linux/interrupt.h>
++
++#include <asm/irq_cpu.h>
++#include <asm/system.h>
+ 
+ #include <asm/mips-boards/seadint.h>
+ 
+@@ -39,13 +42,8 @@ asmlinkage void sead_hw1_irqdispatch(str
+ 
+ void __init arch_init_irq(void)
+ {
+-        /*
+-         * Mask out all interrupt
+-	 */
+-	clear_c0_status(0x0000ff00);
++	mips_cpu_irq_init(0);
+ 
+ 	/* Now safe to set the exception vector. */
+ 	set_except_vector(0, mipsIRQ);
+-
+-	mips_cpu_irq_init(0);
+ }
+diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c
+--- a/arch/mips/mips-boards/sead/sead_setup.c
++++ b/arch/mips/mips-boards/sead/sead_setup.c
+@@ -57,8 +57,6 @@ static void __init sead_setup(void)
+ 	mips_reboot_setup();
+ }
+ 
+-early_initcall(sead_setup);
+-
+ static void __init serial_init(void)
+ {
+ #ifdef CONFIG_SERIAL_8250
+diff --git a/arch/mips/mips-boards/sim/Makefile b/arch/mips/mips-boards/sim/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/Makefile
+@@ -0,0 +1,20 @@
++#
++# Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
++#
++# This program is free software; you can distribute 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 it will be useful, but WITHOUT
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++# for more details.
++#
++# You 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.
++#
++
++obj-y := sim_setup.o sim_mem.o sim_time.o sim_printf.o sim_int.o sim_irq.o \
++	sim_cmdline.o
++obj-$(CONFIG_SMP) += sim_smp.o
+diff --git a/arch/mips/mips-boards/sim/cmdline.c b/arch/mips/mips-boards/sim/cmdline.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/cmdline.c
+@@ -0,0 +1,59 @@
++/*
++ * Carsten Langgaard, carstenl at mips.com
++ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
++ *
++ * This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ * for more details.
++ *
++ * You 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.
++ *
++ * Kernel command line creation using the prom monitor (YAMON) argc/argv.
++ */
++#include <linux/init.h>
++#include <linux/string.h>
++
++#include <asm/bootinfo.h>
++
++extern int prom_argc;
++extern int *_prom_argv;
++
++/*
++ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
++ * This macro take care of sign extension.
++ */
++#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)]))
++
++char arcs_cmdline[CL_SIZE];
++
++char * __init prom_getcmdline(void)
++{
++	return &(arcs_cmdline[0]);
++}
++
++
++void  __init prom_init_cmdline(void)
++{
++	char *cp;
++	int actr;
++
++	actr = 1; /* Always ignore argv[0] */
++
++	cp = &(arcs_cmdline[0]);
++	while(actr < prom_argc) {
++	        strcpy(cp, prom_argv(actr));
++		cp += strlen(prom_argv(actr));
++		*cp++ = ' ';
++		actr++;
++	}
++	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
++		--cp;
++	*cp = '\0';
++}
+diff --git a/arch/mips/mips-boards/sim/sim_IRQ.c b/arch/mips/mips-boards/sim/sim_IRQ.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/sim_IRQ.c
+@@ -0,0 +1,148 @@
++/*
++ * Carsten Langgaard, carstenl at mips.com
++ * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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.
++ *
++ * Interrupt exception dispatch code.
++ */
++#include <linux/config.h>
++
++#include <asm/asm.h>
++#include <asm/mipsregs.h>
++#include <asm/regdef.h>
++#include <asm/stackframe.h>
++
++/* A lot of complication here is taken away because:
++ *
++ * 1) We handle one interrupt and return, sitting in a loop and moving across
++ *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
++ *    common case is one pending IRQ so optimize in that direction.
++ *
++ * 2) We need not check against bits in the status register IRQ mask, that
++ *    would make this routine slow as hell.
++ *
++ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
++ *    between like BSD spl() brain-damage.
++ *
++ * Furthermore, the IRQs on the MIPS board look basically (barring software
++ * IRQs which we don't use at all and all external interrupt sources are
++ * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
++ *
++ *	MIPS IRQ	Source
++ *      --------        ------
++ *             0	Software (ignored)
++ *             1        Software (ignored)
++ *             2        Combined hardware interrupt (hw0)
++ *             3        Hardware (ignored)
++ *             4        Hardware (ignored)
++ *             5        Hardware (ignored)
++ *             6        Hardware (ignored)
++ *             7        R4k timer (what we use)
++ *
++ * Note: On the SEAD board thing are a little bit different.
++ *       Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
++ *       wired to UART1.
++ *
++ * We handle the IRQ according to _our_ priority which is:
++ *
++ * Highest ----     R4k Timer
++ * Lowest  ----     Combined hardware interrupt
++ *
++ * then we just return, if multiple IRQs are pending then we will just take
++ * another exception, big deal.
++ */
++
++	.text
++	.set	noreorder
++	.set	noat
++	.align	5
++	NESTED(mipsIRQ, PT_SIZE, sp)
++	SAVE_ALL
++	CLI
++	.set	at
++
++	mfc0	s0, CP0_CAUSE		# get irq bits
++	mfc0	s1, CP0_STATUS		# get irq mask
++	and	s0, s1
++
++	/* First we check for r4k counter/timer IRQ. */
++	andi	a0, s0, CAUSEF_IP7
++	beq	a0, zero, 1f
++	 andi	a0, s0, CAUSEF_IP2	# delay slot, check hw0 interrupt
++
++	/* Wheee, a timer interrupt. */
++	move	a0, sp
++	jal	mips_timer_interrupt
++	 nop
++
++	j	ret_from_irq
++	 nop
++
++1:
++#if defined(CONFIG_MIPS_SEAD)
++	beq	a0, zero, 1f
++	 andi	a0, s0, CAUSEF_IP3	# delay slot, check hw1 interrupt
++#else
++	beq	a0, zero, 1f		# delay slot, check hw3 interrupt
++ 	 andi	a0, s0, CAUSEF_IP5
++#endif
++
++	/* Wheee, combined hardware level zero interrupt. */
++#if defined(CONFIG_MIPS_ATLAS)
++	jal	atlas_hw0_irqdispatch
++#elif defined(CONFIG_MIPS_MALTA)
++	jal	malta_hw0_irqdispatch
++#elif defined(CONFIG_MIPS_SEAD)
++	jal	sead_hw0_irqdispatch
++#else
++#error "MIPS board not supported\n"
++#endif
++	 move	a0, sp			# delay slot
++
++	j	ret_from_irq
++	 nop				# delay slot
++
++1:
++#if defined(CONFIG_MIPS_SEAD)
++	beq	a0, zero, 1f
++	 andi	a0, s0, CAUSEF_IP5	# delay slot, check hw3 interrupt
++	jal	sead_hw1_irqdispatch
++	 move	a0, sp			# delay slot
++	j	ret_from_irq
++	 nop				# delay slot
++1:
++#endif
++#if defined(CONFIG_MIPS_MALTA)
++	beq	a0, zero, 1f            # check hw3 (coreHI) interrupt
++	 nop
++	jal	corehi_irqdispatch
++	 move	a0, sp
++	j	ret_from_irq
++	 nop
++1:
++#endif
++	/*
++	 * Here by mistake?  This is possible, what can happen is that by the
++	 * time we take the exception the IRQ pin goes low, so just leave if
++	 * this is the case.
++	 */
++	move	a1,s0
++	PRINT("Got interrupt: c0_cause = %08x\n")
++	mfc0	a1, CP0_EPC
++	PRINT("c0_epc = %08x\n")
++
++	j	ret_from_irq
++	 nop
++	END(mipsIRQ)
+diff --git a/arch/mips/mips-boards/sim/sim_cmdline.c b/arch/mips/mips-boards/sim/sim_cmdline.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/sim_cmdline.c
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/string.h>
++#include <asm/bootinfo.h>
++
++extern char arcs_cmdline[];
++
++char * __init prom_getcmdline(void)
++{
++	return arcs_cmdline;
++}
++
++
++void  __init prom_init_cmdline(void)
++{
++    /* nothing to do */
++}
+diff --git a/arch/mips/mips-boards/sim/sim_int.c b/arch/mips/mips-boards/sim/sim_int.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/sim_int.c
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (C) 1999, 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/slab.h>
++#include <linux/interrupt.h>
++#include <linux/kernel_stat.h>
++#include <asm/mips-boards/simint.h>
++
++
++extern void mips_cpu_irq_init(int);
++
++extern asmlinkage void simIRQ(void);
++
++asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs)
++{
++	do_IRQ(2, regs);
++}
++
++void __init arch_init_irq(void)
++{
++	/* Now safe to set the exception vector. */
++	set_except_vector(0, simIRQ);
++
++	mips_cpu_irq_init(MIPSCPU_INT_BASE);
++}
+diff --git a/arch/mips/mips-boards/sim/sim_irq.S b/arch/mips/mips-boards/sim/sim_irq.S
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/sim_irq.S
+@@ -0,0 +1,99 @@
++/*
++ * Copyright (C) 1999, 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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.
++ *
++ * Interrupt exception dispatch code.
++ *
++ */
++#include <linux/config.h>
++
++#include <asm/asm.h>
++#include <asm/mipsregs.h>
++#include <asm/regdef.h>
++#include <asm/stackframe.h>
++
++#include <asm/mips-boards/simint.h>
++
++
++	.text
++	.set	noreorder
++	.set	noat
++	.align	5
++	NESTED(simIRQ, PT_SIZE, sp)
++	SAVE_ALL
++	CLI
++	.set	at
++
++	mfc0	s0, CP0_CAUSE		# get irq bits
++	mfc0	s1, CP0_STATUS		# get irq mask
++	andi	s0, ST0_IM		# CAUSE.CE may be non-zero!
++	and	s0, s1
++
++#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
++ 	.set	mips32
++	clz	a0, s0
++	.set	mips0
++	negu	a0
++	addu	a0, 31-CAUSEB_IP
++	bltz	a0, spurious
++#else
++	beqz	s0, spurious
++	 li	a0, 7
++
++	and	t0, s0, 0xf000
++	sltiu	t0, t0, 1
++	sll	t0, 2
++	subu	a0, t0
++	sll	s0, t0
++
++	and	t0, s0, 0xc000
++	sltiu	t0, t0, 1
++	sll	t0, 1
++	subu	a0, t0
++	sll	s0, t0
++
++	and	t0, s0, 0x8000
++	sltiu	t0, t0, 1
++	# sll	t0, 0
++	subu	a0, t0
++	# sll	s0, t0
++#endif
++
++#ifdef CASCADE_IRQ
++	 li	a1, CASCADE_IRQ
++	bne	a0, a1, 1f
++	 addu	a0, MIPSCPU_INT_BASE
++
++	jal	CASCADE_DISPATCH
++	 move	 a0, sp
++
++	j	ret_from_irq
++	 nop
++1:
++#else
++	 addu	a0, MIPSCPU_INT_BASE
++#endif
++
++	jal	do_IRQ
++	 move	a1, sp
++
++	j	ret_from_irq
++	 nop
++
++
++spurious:
++	j	spurious_interrupt
++	 nop
++	END(simIRQ)
+diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/sim_mem.c
+@@ -0,0 +1,129 @@
++/*
++ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/bootmem.h>
++
++#include <asm/bootinfo.h>
++#include <asm/page.h>
++
++#include <asm/mips-boards/prom.h>
++
++/*#define DEBUG*/
++
++enum simmem_memtypes {
++	simmem_reserved = 0,
++	simmem_free,
++};
++struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
++
++#ifdef DEBUG
++static char *mtypes[3] = {
++	"SIM reserved memory",
++	"SIM free memory",
++};
++#endif
++
++/* References to section boundaries */
++extern char _end;
++
++#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
++
++
++struct prom_pmemblock * __init prom_getmdesc(void)
++{
++	unsigned int memsize;
++
++	memsize = 0x02000000;
++	prom_printf("Setting default memory size 0x%08x\n", memsize);
++
++	memset(mdesc, 0, sizeof(mdesc));
++
++	mdesc[0].type = simmem_reserved;
++	mdesc[0].base = 0x00000000;
++	mdesc[0].size = 0x00001000;
++
++	mdesc[1].type = simmem_free;
++	mdesc[1].base = 0x00001000;
++	mdesc[1].size = 0x000ff000;
++
++	mdesc[2].type = simmem_reserved;
++	mdesc[2].base = 0x00100000;
++	mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
++
++	mdesc[3].type = simmem_free;
++	mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
++	mdesc[3].size = memsize - mdesc[3].base;
++
++	return &mdesc[0];
++}
++
++static int __init prom_memtype_classify (unsigned int type)
++{
++	switch (type) {
++	case simmem_free:
++		return BOOT_MEM_RAM;
++	case simmem_reserved:
++	default:
++		return BOOT_MEM_RESERVED;
++	}
++}
++
++void __init prom_meminit(void)
++{
++	struct prom_pmemblock *p;
++
++	p = prom_getmdesc();
++
++	while (p->size) {
++		long type;
++		unsigned long base, size;
++
++		type = prom_memtype_classify (p->type);
++		base = p->base;
++		size = p->size;
++
++		add_memory_region(base, size, type);
++                p++;
++	}
++}
++
++unsigned long __init prom_free_prom_memory(void)
++{
++	int i;
++	unsigned long freed = 0;
++	unsigned long addr;
++
++	for (i = 0; i < boot_mem_map.nr_map; i++) {
++		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
++			continue;
++
++		addr = boot_mem_map.map[i].addr;
++		while (addr < boot_mem_map.map[i].addr
++			      + boot_mem_map.map[i].size) {
++			ClearPageReserved(virt_to_page(__va(addr)));
++			set_page_count(virt_to_page(__va(addr)), 1);
++			free_page((unsigned long)__va(addr));
++			addr += PAGE_SIZE;
++			freed += PAGE_SIZE;
++		}
++	}
++	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
++
++	return freed;
++}
+diff --git a/arch/mips/mips-boards/sim/sim_printf.c b/arch/mips/mips-boards/sim/sim_printf.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/sim_printf.c
+@@ -0,0 +1,74 @@
++/*
++ * Carsten Langgaard, carstenl at mips.com
++ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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.
++ *
++ * Putting things on the screen/serial line using YAMONs facilities.
++ */
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/serial_reg.h>
++#include <linux/spinlock.h>
++#include <asm/io.h>
++#include <asm/system.h>
++
++static inline unsigned int serial_in(int offset)
++{
++	return inb(0x3f8 + offset);
++}
++
++static inline void serial_out(int offset, int value)
++{
++	outb(value, 0x3f8 + offset);
++}
++
++int putPromChar(char c)
++{
++	while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
++		;
++
++	serial_out(UART_TX, c);
++
++	return 1;
++}
++
++char getPromChar(void)
++{
++	while (!(serial_in(UART_LSR) & 1))
++		;
++
++	return serial_in(UART_RX);
++}
++
++void prom_printf(char *fmt, ...)
++{
++	va_list args;
++	int l;
++	char *p, *buf_end;
++	char buf[1024];
++
++	va_start(args, fmt);
++	l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
++	va_end(args);
++
++	buf_end = buf + l;
++
++	for (p = buf; p < buf_end; p++) {
++		/* Crude cr/nl handling is better than none */
++		if (*p == '\n')
++			putPromChar('\r');
++		putPromChar(*p);
++	}
++}
+diff --git a/arch/mips/mips-boards/sim/sim_setup.c b/arch/mips/mips-boards/sim/sim_setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/sim_setup.c
+@@ -0,0 +1,101 @@
++/*
++ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/config.h>
++#include <linux/init.h>
++#include <linux/string.h>
++#include <linux/kernel.h>
++#include <linux/ioport.h>
++#include <linux/tty.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++
++#include <asm/cpu.h>
++#include <asm/bootinfo.h>
++#include <asm/irq.h>
++#include <asm/mips-boards/generic.h>
++#include <asm/mips-boards/prom.h>
++#include <asm/serial.h>
++#include <asm/io.h>
++#include <asm/time.h>
++#include <asm/mips-boards/sim.h>
++#include <asm/mips-boards/simint.h>
++
++
++extern void sim_time_init(void);
++extern void sim_timer_setup(struct irqaction *irq);
++static void __init serial_init(void);
++unsigned int _isbonito = 0;
++
++extern void __init sanitize_tlb_entries(void);
++
++
++const char *get_system_type(void)
++{
++	return "MIPSsim";
++}
++
++void __init plat_setup(void)
++{
++	set_io_port_base(0xbfd00000);
++
++	serial_init();
++
++	board_time_init = sim_time_init;
++	board_timer_setup = sim_timer_setup;
++	prom_printf("Linux started...\n");
++
++#ifdef CONFIG_MT_SMP
++	sanitize_tlb_entries();
++#endif
++}
++
++void prom_init(void)
++{
++	set_io_port_base(0xbfd00000);
++
++	prom_printf("\nLINUX started...\n");
++	prom_init_cmdline();
++	prom_meminit();
++}
++
++
++static void __init serial_init(void)
++{
++#ifdef CONFIG_SERIAL_8250
++	struct uart_port s;
++
++	memset(&s, 0, sizeof(s));
++
++	s.iobase = 0x3f8;
++
++	/* hardware int 4 - the serial int, is CPU int 6
++	 but poll for now */
++	s.irq =  0;
++	s.uartclk = BASE_BAUD * 16;
++	s.flags = ASYNC_BOOT_AUTOCONF | UPF_SKIP_TEST;
++	s.iotype = SERIAL_IO_PORT | ASYNC_SKIP_TEST;
++	s.regshift = 0;
++	s.timeout = 4;
++
++	if (early_serial_setup(&s) != 0) {
++		prom_printf(KERN_ERR "Serial setup failed!\n");
++	}
++
++#endif
++}
+diff --git a/arch/mips/mips-boards/sim/sim_smp.c b/arch/mips/mips-boards/sim/sim_smp.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/sim_smp.c
+@@ -0,0 +1,151 @@
++/*
++ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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.
++ *
++ */
++/*
++ * Simulator Platform-specific hooks for SMP operation
++ */
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/cpumask.h>
++#include <linux/interrupt.h>
++#include <asm/atomic.h>
++#include <asm/cpu.h>
++#include <asm/processor.h>
++#include <asm/system.h>
++#include <asm/hardirq.h>
++#include <asm/mmu_context.h>
++#include <asm/smp.h>
++#ifdef CONFIG_MIPS_MT_SMTC
++#include <asm/smtc_ipi.h>
++#endif /* CONFIG_MIPS_MT_SMTC */
++
++/* VPE/SMP Prototype implements platform interfaces directly */
++#if !defined(CONFIG_MIPS_MT_SMP)
++
++/*
++ * Cause the specified action to be performed on a targeted "CPU"
++ */
++
++void core_send_ipi(int cpu, unsigned int action)
++{
++#ifdef CONFIG_MIPS_MT_SMTC
++	void smtc_send_ipi(int, int, unsigned int);
++
++	smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
++#endif /* CONFIG_MIPS_MT_SMTC */
++/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
++
++}
++
++/*
++ * Detect available CPUs/VPEs/TCs and populate phys_cpu_present_map
++ */
++
++void __init prom_build_cpu_map(void)
++{
++#ifdef CONFIG_MIPS_MT_SMTC
++	extern int mipsmt_build_cpu_map(int startslot);
++	int nextslot;
++
++	cpus_clear(phys_cpu_present_map);
++
++	/* Register the boot CPU */
++
++	smp_prepare_boot_cpu();
++
++	/*
++	 * As of November, 2004, MIPSsim only simulates one core
++	 * at a time.  However, that core may be a MIPS MT core
++	 * with multiple virtual processors and thread contexts.
++	 */
++
++	if (read_c0_config3() & (1<<2)) {
++		nextslot = mipsmt_build_cpu_map(1);
++	}
++#endif /* CONFIG_MIPS_MT_SMTC */
++}
++
++/*
++ * Platform "CPU" startup hook
++ */
++
++void prom_boot_secondary(int cpu, struct task_struct *idle)
++{
++#ifdef CONFIG_MIPS_MT_SMTC
++	extern void smtc_boot_secondary(int cpu, struct task_struct *t);
++
++	smtc_boot_secondary(cpu, idle);
++#endif /* CONFIG_MIPS_MT_SMTC */
++}
++
++/*
++ * Post-config but pre-boot cleanup entry point
++ */
++
++void prom_init_secondary(void)
++{
++#ifdef CONFIG_MIPS_MT_SMTC
++	void smtc_init_secondary(void);
++
++	smtc_init_secondary();
++#endif /* CONFIG_MIPS_MT_SMTC */
++}
++
++/*
++ * Platform SMP pre-initialization
++ */
++
++void prom_prepare_cpus(unsigned int max_cpus)
++{
++#ifdef CONFIG_MIPS_MT_SMTC
++	void mipsmt_prepare_cpus(int c);
++	/*
++ 	 * As noted above, we can assume a single CPU for now
++	 * but it may be multithreaded.
++	 */
++
++	if (read_c0_config3() & (1<<2)) {
++		mipsmt_prepare_cpus(max_cpus);
++	}
++#endif /* CONFIG_MIPS_MT_SMTC */
++}
++
++/*
++ * SMP initialization finalization entry point
++ */
++
++void prom_smp_finish(void)
++{
++#ifdef CONFIG_MIPS_MT_SMTC
++	void smtc_smp_finish(void);
++
++	smtc_smp_finish();
++#endif /* CONFIG_MIPS_MT_SMTC */
++}
++
++/*
++ * Hook for after all CPUs are online
++ */
++
++void prom_cpus_done(void)
++{
++#ifdef CONFIG_MIPS_MT_SMTC
++
++#endif /* CONFIG_MIPS_MT_SMTC */
++}
++#endif /* CONFIG_MIPS32R2_MT_SMP */
+diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/mips-boards/sim/sim_time.c
+@@ -0,0 +1,215 @@
++#include <linux/types.h>
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/kernel_stat.h>
++#include <linux/sched.h>
++#include <linux/spinlock.h>
++
++#include <asm/mipsregs.h>
++#include <asm/ptrace.h>
++#include <asm/hardirq.h>
++#include <asm/div64.h>
++#include <asm/cpu.h>
++#include <asm/time.h>
++
++#include <linux/interrupt.h>
++#include <linux/mc146818rtc.h>
++#include <linux/timex.h>
++#include <asm/mipsregs.h>
++#include <asm/ptrace.h>
++#include <asm/hardirq.h>
++#include <asm/irq.h>
++#include <asm/div64.h>
++#include <asm/cpu.h>
++#include <asm/time.h>
++#include <asm/mc146818-time.h>
++#include <asm/msc01_ic.h>
++
++#include <asm/mips-boards/generic.h>
++#include <asm/mips-boards/prom.h>
++#include <asm/mips-boards/simint.h>
++#include <asm/mc146818-time.h>
++#include <asm/smp.h>
++
++
++unsigned long cpu_khz;
++
++extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
++
++irqreturn_t sim_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++#ifdef CONFIG_SMP
++	int cpu = smp_processor_id();
++
++	/*
++	 * CPU 0 handles the global timer interrupt job
++	 * resets count/compare registers to trigger next timer int.
++	 */
++#ifndef CONFIG_MIPS_MT_SMTC
++	if (cpu == 0) {
++		timer_interrupt(irq, dev_id, regs);
++	}
++	else {
++		/* Everyone else needs to reset the timer int here as
++		   ll_local_timer_interrupt doesn't */
++		/*
++		 * FIXME: need to cope with counter underflow.
++		 * More support needs to be added to kernel/time for
++		 * counter/timer interrupts on multiple CPU's
++		 */
++		write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
++	}
++#else /* SMTC */
++	/*
++	 *  In SMTC system, one Count/Compare set exists per VPE.
++	 *  Which TC within a VPE gets the interrupt is essentially
++	 *  random - we only know that it shouldn't be one with
++	 *  IXMT set. Whichever TC gets the interrupt needs to
++	 *  send special interprocessor interrupts to the other
++	 *  TCs to make sure that they schedule, etc.
++	 *
++	 *  That code is specific to the SMTC kernel, not to
++	 *  the simulation platform, so it's invoked from
++	 *  the general MIPS timer_interrupt routine.
++	 *
++	 * We have a problem in that the interrupt vector code
++	 * had to turn off the timer IM bit to avoid redundant
++	 * entries, but we may never get to mips_cpu_irq_end
++	 * to turn it back on again if the scheduler gets
++	 * involved.  So we clear the pending timer here,
++	 * and re-enable the mask...
++	 */
++
++	int vpflags = dvpe();
++	write_c0_compare (read_c0_count() - 1);
++	clear_c0_cause(0x100 << MIPSCPU_INT_CPUCTR);
++	set_c0_status(0x100 << MIPSCPU_INT_CPUCTR);
++	irq_enable_hazard();
++	evpe(vpflags);
++
++	if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id, regs);
++	else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
++	smtc_timer_broadcast(cpu_data[cpu].vpe_id);
++
++#endif /* CONFIG_MIPS_MT_SMTC */
++
++	/*
++	 * every CPU should do profiling and process accounting
++	 */
++ 	local_timer_interrupt (irq, dev_id, regs);
++	return IRQ_HANDLED;
++#else
++	return timer_interrupt (irq, dev_id, regs);
++#endif
++}
++
++
++
++/*
++ * Estimate CPU frequency.  Sets mips_counter_frequency as a side-effect
++ */
++static unsigned int __init estimate_cpu_frequency(void)
++{
++	unsigned int prid = read_c0_prid() & 0xffff00;
++	unsigned int count;
++
++#if 1
++	/*
++	 * hardwire the board frequency to 12MHz.
++	 */
++
++	if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
++	    (prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
++		count = 12000000;
++	else
++		count =  6000000;
++#else
++	unsigned int flags;
++
++	local_irq_save(flags);
++
++	/* Start counter exactly on falling edge of update flag */
++	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
++	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
++
++	/* Start r4k counter. */
++	write_c0_count(0);
++
++	/* Read counter exactly on falling edge of update flag */
++	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
++	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
++
++	count = read_c0_count();
++
++	/* restore interrupts */
++	local_irq_restore(flags);
++#endif
++
++	mips_hpt_frequency = count;
++
++	if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
++	    (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
++		count *= 2;
++
++	count += 5000;    /* round */
++	count -= count%10000;
++
++	return count;
++}
++
++void __init sim_time_init(void)
++{
++	unsigned int est_freq, flags;
++
++	local_irq_save(flags);
++
++
++        /* Set Data mode - binary. */
++	CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
++
++
++	est_freq = estimate_cpu_frequency ();
++
++	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
++	       (est_freq%1000000)*100/1000000);
++
++        cpu_khz = est_freq / 1000;
++
++	local_irq_restore(flags);
++}
++
++static int mips_cpu_timer_irq;
++
++static void mips_timer_dispatch (struct pt_regs *regs)
++{
++	do_IRQ (mips_cpu_timer_irq, regs);
++}
++
++
++void __init sim_timer_setup(struct irqaction *irq)
++{
++	if (cpu_has_veic) {
++		set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
++		mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
++	}
++	else {
++		if (cpu_has_vint)
++			set_vi_handler(MIPSCPU_INT_CPUCTR, mips_timer_dispatch);
++		mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR;
++	}
++
++	/* we are using the cpu counter for timer interrupts */
++	irq->handler = sim_timer_interrupt;
++	setup_irq(mips_cpu_timer_irq, irq);
++
++#ifdef CONFIG_SMP
++	/* irq_desc(riptor) is a global resource, when the interrupt overlaps
++	   on seperate cpu's the first one tries to handle the second interrupt.
++	   The effect is that the int remains disabled on the second cpu.
++	   Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
++	irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU;
++#endif
++
++	/* to generate the first timer interrupt */
++	write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ));
++}
+diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
+--- a/arch/mips/mm/Makefile
++++ b/arch/mips/mm/Makefile
+@@ -22,7 +22,7 @@ obj-$(CONFIG_CPU_R8000)		+= c-r4k.o cex-
+ obj-$(CONFIG_CPU_RM7000)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+ obj-$(CONFIG_CPU_RM9000)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+ obj-$(CONFIG_CPU_SB1)		+= c-sb1.o cerr-sb1.o cex-sb1.o pg-sb1.o \
+-				   tlb-sb1.o
++				   tlb-r4k.o
+ obj-$(CONFIG_CPU_TX39XX)	+= c-tx39.o pg-r4k.o tlb-r3k.o
+ obj-$(CONFIG_CPU_TX49XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+ obj-$(CONFIG_CPU_VR41XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
+--- a/arch/mips/mm/c-r3k.c
++++ b/arch/mips/mm/c-r3k.c
+@@ -221,12 +221,14 @@ static inline unsigned long get_phys_pag
+ 					   struct mm_struct *mm)
+ {
+ 	pgd_t *pgd;
++	pud_t *pud;
+ 	pmd_t *pmd;
+ 	pte_t *pte;
+ 	unsigned long physpage;
+ 
+ 	pgd = pgd_offset(mm, addr);
+-	pmd = pmd_offset(pgd, addr);
++	pud = pud_offset(pgd, addr);
++	pmd = pmd_offset(pud, addr);
+ 	pte = pte_offset(pmd, addr);
+ 
+ 	if ((physpage = pte_val(*pte)) & _PAGE_VALID)
+@@ -317,7 +319,7 @@ static void r3k_dma_cache_wback_inv(unsi
+ 	r3k_flush_dcache_range(start, start + size);
+ }
+ 
+-void __init ld_mmu_r23000(void)
++void __init r3k_cache_init(void)
+ {
+ 	extern void build_clear_page(void);
+ 	extern void build_copy_page(void);
+diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
+--- a/arch/mips/mm/c-r4k.c
++++ b/arch/mips/mm/c-r4k.c
+@@ -16,6 +16,7 @@
+ 
+ #include <asm/bcache.h>
+ #include <asm/bootinfo.h>
++#include <asm/cache.h>
+ #include <asm/cacheops.h>
+ #include <asm/cpu.h>
+ #include <asm/cpu-features.h>
+@@ -26,8 +27,14 @@
+ #include <asm/system.h>
+ #include <asm/mmu_context.h>
+ #include <asm/war.h>
++#include <asm/cacheflush.h> /* for run_uncached() */
+ 
+-static unsigned long icache_size, dcache_size, scache_size;
++/*
++ * Must die.
++ */
++static unsigned long icache_size __read_mostly;
++static unsigned long dcache_size __read_mostly;
++static unsigned long scache_size __read_mostly;
+ 
+ /*
+  * Dummy cache handling routines for machines without boardcaches
+@@ -43,8 +50,8 @@ static struct bcache_ops no_sc_ops = {
+ 
+ struct bcache_ops *bcops = &no_sc_ops;
+ 
+-#define cpu_is_r4600_v1_x()	((read_c0_prid() & 0xfffffff0) == 0x2010)
+-#define cpu_is_r4600_v2_x()	((read_c0_prid() & 0xfffffff0) == 0x2020)
++#define cpu_is_r4600_v1_x()	((read_c0_prid() & 0xfffffff0) == 0x00002010)
++#define cpu_is_r4600_v2_x()	((read_c0_prid() & 0xfffffff0) == 0x00002020)
+ 
+ #define R4600_HIT_CACHEOP_WAR_IMPL					\
+ do {									\
+@@ -190,12 +197,12 @@ static inline void r4k_blast_icache_page
+ 	if (ic_lsize == 16)
+ 		r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
+ 	else if (ic_lsize == 32) {
+-		if (TX49XX_ICACHE_INDEX_INV_WAR)
+-			r4k_blast_icache_page_indexed =
+-				tx49_blast_icache32_page_indexed;
+-		else if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
++		if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+ 			r4k_blast_icache_page_indexed =
+ 				blast_icache32_r4600_v1_page_indexed;
++		else if (TX49XX_ICACHE_INDEX_INV_WAR)
++			r4k_blast_icache_page_indexed =
++				tx49_blast_icache32_page_indexed;
+ 		else
+ 			r4k_blast_icache_page_indexed =
+ 				blast_icache32_page_indexed;
+@@ -361,24 +368,33 @@ static void r4k_flush_cache_mm(struct mm
+ 
+ struct flush_cache_page_args {
+ 	struct vm_area_struct *vma;
+-	unsigned long page;
++	unsigned long addr;
+ };
+ 
+ static inline void local_r4k_flush_cache_page(void *args)
+ {
+ 	struct flush_cache_page_args *fcp_args = args;
+ 	struct vm_area_struct *vma = fcp_args->vma;
+-	unsigned long page = fcp_args->page;
++	unsigned long addr = fcp_args->addr;
+ 	int exec = vma->vm_flags & VM_EXEC;
+ 	struct mm_struct *mm = vma->vm_mm;
+ 	pgd_t *pgdp;
++	pud_t *pudp;
+ 	pmd_t *pmdp;
+ 	pte_t *ptep;
+ 
+-	page &= PAGE_MASK;
+-	pgdp = pgd_offset(mm, page);
+-	pmdp = pmd_offset(pgdp, page);
+-	ptep = pte_offset(pmdp, page);
++	/*
++	 * If ownes no valid ASID yet, cannot possibly have gotten
++	 * this page into the cache.
++	 */
++	if (cpu_context(smp_processor_id(), mm) == 0)
++		return;
++
++	addr &= PAGE_MASK;
++	pgdp = pgd_offset(mm, addr);
++	pudp = pud_offset(pgdp, addr);
++	pmdp = pmd_offset(pudp, addr);
++	ptep = pte_offset(pmdp, addr);
+ 
+ 	/*
+ 	 * If the page isn't marked valid, the page cannot possibly be
+@@ -395,12 +411,12 @@ static inline void local_r4k_flush_cache
+ 	 */
+ 	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+ 		if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
+-			r4k_blast_dcache_page(page);
++			r4k_blast_dcache_page(addr);
+ 			if (exec && !cpu_icache_snoops_remote_store)
+-				r4k_blast_scache_page(page);
++				r4k_blast_scache_page(addr);
+ 		}
+ 		if (exec)
+-			r4k_blast_icache_page(page);
++			r4k_blast_icache_page(addr);
+ 
+ 		return;
+ 	}
+@@ -409,36 +425,30 @@ static inline void local_r4k_flush_cache
+ 	 * Do indexed flush, too much work to get the (possible) TLB refills
+ 	 * to work correctly.
+ 	 */
+-	page = INDEX_BASE + (page & (dcache_size - 1));
++	addr = INDEX_BASE + (addr & (dcache_size - 1));
+ 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
+-		r4k_blast_dcache_page_indexed(page);
++		r4k_blast_dcache_page_indexed(addr);
+ 		if (exec && !cpu_icache_snoops_remote_store)
+-			r4k_blast_scache_page_indexed(page);
++			r4k_blast_scache_page_indexed(addr);
+ 	}
+ 	if (exec) {
+ 		if (cpu_has_vtag_icache) {
+ 			int cpu = smp_processor_id();
+ 
+-			if (cpu_context(cpu, vma->vm_mm) != 0)
+-				drop_mmu_context(vma->vm_mm, cpu);
++			if (cpu_context(cpu, mm) != 0)
++				drop_mmu_context(mm, cpu);
+ 		} else
+-			r4k_blast_icache_page_indexed(page);
++			r4k_blast_icache_page_indexed(addr);
+ 	}
+ }
+ 
+-static void r4k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
++static void r4k_flush_cache_page(struct vm_area_struct *vma,
++	unsigned long addr, unsigned long pfn)
+ {
+ 	struct flush_cache_page_args args;
+ 
+-	/*
+-	 * If ownes no valid ASID yet, cannot possibly have gotten
+-	 * this page into the cache.
+-	 */
+-	if (cpu_context(smp_processor_id(), vma->vm_mm) == 0)
+-		return;
+-
+ 	args.vma = vma;
+-	args.page = page;
++	args.addr = addr;
+ 
+ 	on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
+ }
+@@ -454,16 +464,16 @@ static void r4k_flush_data_cache_page(un
+ }
+ 
+ struct flush_icache_range_args {
+-	unsigned long start;
+-	unsigned long end;
++	unsigned long __user start;
++	unsigned long __user end;
+ };
+ 
+ static inline void local_r4k_flush_icache_range(void *args)
+ {
+ 	struct flush_icache_range_args *fir_args = args;
+-	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+-	unsigned long ic_lsize = current_cpu_data.icache.linesz;
+-	unsigned long sc_lsize = current_cpu_data.scache.linesz;
++	unsigned long dc_lsize = cpu_dcache_line_size();
++	unsigned long ic_lsize = cpu_icache_line_size();
++	unsigned long sc_lsize = cpu_scache_line_size();
+ 	unsigned long start = fir_args->start;
+ 	unsigned long end = fir_args->end;
+ 	unsigned long addr, aend;
+@@ -472,6 +482,7 @@ static inline void local_r4k_flush_icach
+ 		if (end - start > dcache_size) {
+ 			r4k_blast_dcache();
+ 		} else {
++			R4600_HIT_CACHEOP_WAR_IMPL;
+ 			addr = start & ~(dc_lsize - 1);
+ 			aend = (end - 1) & ~(dc_lsize - 1);
+ 
+@@ -492,7 +503,7 @@ static inline void local_r4k_flush_icach
+ 				aend = (end - 1) & ~(sc_lsize - 1);
+ 
+ 				while (1) {
+-					/* Hit_Writeback_Inv_D */
++					/* Hit_Writeback_Inv_SD */
+ 					protected_writeback_scache_line(addr);
+ 					if (addr == aend)
+ 						break;
+@@ -517,7 +528,8 @@ static inline void local_r4k_flush_icach
+ 	}
+ }
+ 
+-static void r4k_flush_icache_range(unsigned long start, unsigned long end)
++static void r4k_flush_icache_range(unsigned long __user start,
++	unsigned long __user end)
+ {
+ 	struct flush_icache_range_args args;
+ 
+@@ -525,6 +537,7 @@ static void r4k_flush_icache_range(unsig
+ 	args.end = end;
+ 
+ 	on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1);
++	instruction_hazard();
+ }
+ 
+ /*
+@@ -613,7 +626,7 @@ static void r4k_dma_cache_wback_inv(unsi
+ 	BUG_ON(size == 0);
+ 
+ 	if (cpu_has_subset_pcaches) {
+-		unsigned long sc_lsize = current_cpu_data.scache.linesz;
++		unsigned long sc_lsize = cpu_scache_line_size();
+ 
+ 		if (size >= scache_size) {
+ 			r4k_blast_scache();
+@@ -639,7 +652,7 @@ static void r4k_dma_cache_wback_inv(unsi
+ 	if (size >= dcache_size) {
+ 		r4k_blast_dcache();
+ 	} else {
+-		unsigned long dc_lsize = current_cpu_data.dcache.linesz;
++		unsigned long dc_lsize = cpu_dcache_line_size();
+ 
+ 		R4600_HIT_CACHEOP_WAR_IMPL;
+ 		a = addr & ~(dc_lsize - 1);
+@@ -663,7 +676,7 @@ static void r4k_dma_cache_inv(unsigned l
+ 	BUG_ON(size == 0);
+ 
+ 	if (cpu_has_subset_pcaches) {
+-		unsigned long sc_lsize = current_cpu_data.scache.linesz;
++		unsigned long sc_lsize = cpu_scache_line_size();
+ 
+ 		if (size >= scache_size) {
+ 			r4k_blast_scache();
+@@ -684,7 +697,7 @@ static void r4k_dma_cache_inv(unsigned l
+ 	if (size >= dcache_size) {
+ 		r4k_blast_dcache();
+ 	} else {
+-		unsigned long dc_lsize = current_cpu_data.dcache.linesz;
++		unsigned long dc_lsize = cpu_dcache_line_size();
+ 
+ 		R4600_HIT_CACHEOP_WAR_IMPL;
+ 		a = addr & ~(dc_lsize - 1);
+@@ -708,9 +721,9 @@ static void r4k_dma_cache_inv(unsigned l
+  */
+ static void local_r4k_flush_cache_sigtramp(void * arg)
+ {
+-	unsigned long ic_lsize = current_cpu_data.icache.linesz;
+-	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+-	unsigned long sc_lsize = current_cpu_data.scache.linesz;
++	unsigned long ic_lsize = cpu_icache_line_size();
++	unsigned long dc_lsize = cpu_dcache_line_size();
++	unsigned long sc_lsize = cpu_scache_line_size();
+ 	unsigned long addr = (unsigned long) arg;
+ 
+ 	R4600_HIT_CACHEOP_WAR_IMPL;
+@@ -762,6 +775,7 @@ static inline void rm7k_erratum31(void)
+ 
+ 	for (addr = INDEX_BASE; addr <= INDEX_BASE + 4096; addr += ic_lsize) {
+ 		__asm__ __volatile__ (
++			".set push\n\t"
+ 			".set noreorder\n\t"
+ 			".set mips3\n\t"
+ 			"cache\t%1, 0(%0)\n\t"
+@@ -776,8 +790,7 @@ static inline void rm7k_erratum31(void)
+ 			"cache\t%1, 0x1000(%0)\n\t"
+ 			"cache\t%1, 0x2000(%0)\n\t"
+ 			"cache\t%1, 0x3000(%0)\n\t"
+-			".set\tmips0\n\t"
+-			".set\treorder\n\t"
++			".set pop\n"
+ 			:
+ 			: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
+ 	}
+@@ -1011,9 +1024,19 @@ static void __init probe_pcache(void)
+ 	 * normally they'd suffer from aliases but magic in the hardware deals
+ 	 * with that for us so we don't need to take care ourselves.
+ 	 */
+-	if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000)
+-		if (c->dcache.waysize > PAGE_SIZE)
+-		        c->dcache.flags |= MIPS_CACHE_ALIASES;
++	switch (c->cputype) {
++	case CPU_20KC:
++	case CPU_25KF:
++	case CPU_R10000:
++	case CPU_R12000:
++	case CPU_SB1:
++		break;
++	case CPU_24K:
++		if (!(read_c0_config7() & (1 << 16)))
++	default:
++			if (c->dcache.waysize > PAGE_SIZE)
++				c->dcache.flags |= MIPS_CACHE_ALIASES;
++	}
+ 
+ 	switch (c->cputype) {
+ 	case CPU_20KC:
+@@ -1024,7 +1047,11 @@ static void __init probe_pcache(void)
+ 		c->icache.flags |= MIPS_CACHE_VTAG;
+ 		break;
+ 
++	case CPU_AU1000:
+ 	case CPU_AU1500:
++	case CPU_AU1100:
++	case CPU_AU1550:
++	case CPU_AU1200:
+ 		c->icache.flags |= MIPS_CACHE_IC_F_DC;
+ 		break;
+ 	}
+@@ -1102,7 +1129,6 @@ static int __init probe_scache(void)
+ 	return 1;
+ }
+ 
+-typedef int (*probe_func_t)(unsigned long);
+ extern int r5k_sc_init(void);
+ extern int rm7k_sc_init(void);
+ 
+@@ -1110,7 +1136,6 @@ static void __init setup_scache(void)
+ {
+ 	struct cpuinfo_mips *c = &current_cpu_data;
+ 	unsigned int config = read_c0_config();
+-	probe_func_t probe_scache_kseg1;
+ 	int sc_present = 0;
+ 
+ 	/*
+@@ -1123,8 +1148,7 @@ static void __init setup_scache(void)
+ 	case CPU_R4000MC:
+ 	case CPU_R4400SC:
+ 	case CPU_R4400MC:
+-		probe_scache_kseg1 = (probe_func_t) (CKSEG1ADDR(&probe_scache));
+-		sc_present = probe_scache_kseg1(config);
++		sc_present = run_uncached(probe_scache);
+ 		if (sc_present)
+ 			c->options |= MIPS_CPU_CACHE_CDEX_S;
+ 		break;
+@@ -1198,7 +1222,7 @@ static inline void coherency_setup(void)
+ 	}
+ }
+ 
+-void __init ld_mmu_r4xx0(void)
++void __init r4k_cache_init(void)
+ {
+ 	extern void build_clear_page(void);
+ 	extern void build_copy_page(void);
+@@ -1206,15 +1230,11 @@ void __init ld_mmu_r4xx0(void)
+ 	struct cpuinfo_mips *c = &current_cpu_data;
+ 
+ 	/* Default cache error handler for R4000 and R5000 family */
+-	memcpy((void *)(CAC_BASE   + 0x100), &except_vec2_generic, 0x80);
+-	memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_generic, 0x80);
++	set_uncached_handler (0x100, &except_vec2_generic, 0x80);
+ 
+ 	probe_pcache();
+ 	setup_scache();
+ 
+-	if (c->dcache.sets * c->dcache.ways > PAGE_SIZE)
+-		c->dcache.flags |= MIPS_CACHE_ALIASES;
+-
+ 	r4k_blast_dcache_page_setup();
+ 	r4k_blast_dcache_page_indexed_setup();
+ 	r4k_blast_dcache_setup();
+@@ -1252,9 +1272,8 @@ void __init ld_mmu_r4xx0(void)
+ 	_dma_cache_inv		= r4k_dma_cache_inv;
+ #endif
+ 
+-	__flush_cache_all();
+-	coherency_setup();
+-
+ 	build_clear_page();
+ 	build_copy_page();
++	local_r4k___flush_cache_all(NULL);
++	coherency_setup();
+ }
+diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
+--- a/arch/mips/mm/c-sb1.c
++++ b/arch/mips/mm/c-sb1.c
+@@ -235,7 +235,7 @@ static inline void __sb1_flush_icache_ra
+ /*
+  * Invalidate all caches on this CPU
+  */
+-static void local_sb1___flush_cache_all(void)
++static void __attribute_used__ local_sb1___flush_cache_all(void)
+ {
+ 	__sb1_writeback_inv_dcache_all();
+ 	__sb1_flush_icache_all();
+@@ -492,19 +492,17 @@ static __init void probe_cache_sizes(voi
+ }
+ 
+ /*
+- * This is called from loadmmu.c.  We have to set up all the
++ * This is called from cache.c.  We have to set up all the
+  * memory management function pointers, as well as initialize
+  * the caches and tlbs
+  */
+-void ld_mmu_sb1(void)
++void sb1_cache_init(void)
+ {
+ 	extern char except_vec2_sb1;
+ 	extern char handle_vec2_sb1;
+ 
+ 	/* Special cache error handler for SB1 */
+-	memcpy((void *)(CAC_BASE   + 0x100), &except_vec2_sb1, 0x80);
+-	memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_sb1, 0x80);
+-	memcpy((void *)CKSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
++	set_uncached_handler (0x100, &except_vec2_sb1, 0x80);
+ 
+ 	probe_cache_sizes();
+ 
+diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
+--- a/arch/mips/mm/c-tx39.c
++++ b/arch/mips/mm/c-tx39.c
+@@ -167,15 +167,16 @@ static void tx39_flush_cache_mm(struct m
+ static void tx39_flush_cache_range(struct vm_area_struct *vma,
+ 	unsigned long start, unsigned long end)
+ {
+-	struct mm_struct *mm = vma->vm_mm;
++	int exec;
+ 
+-	if (!cpu_has_dc_aliases)
++	if (!(cpu_context(smp_processor_id(), vma->vm_mm)))
+ 		return;
+ 
+-	if (cpu_context(smp_processor_id(), mm) != 0) {
++	exec = vma->vm_flags & VM_EXEC;
++	if (cpu_has_dc_aliases || exec)
+ 		tx39_blast_dcache();
++	if (exec)
+ 		tx39_blast_icache();
+-	}
+ }
+ 
+ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
+@@ -183,6 +184,7 @@ static void tx39_flush_cache_page(struct
+ 	int exec = vma->vm_flags & VM_EXEC;
+ 	struct mm_struct *mm = vma->vm_mm;
+ 	pgd_t *pgdp;
++	pud_t *pudp;
+ 	pmd_t *pmdp;
+ 	pte_t *ptep;
+ 
+@@ -195,7 +197,8 @@ static void tx39_flush_cache_page(struct
+ 
+ 	page &= PAGE_MASK;
+ 	pgdp = pgd_offset(mm, page);
+-	pmdp = pmd_offset(pgdp, page);
++	pudp = pud_offset(pgdp, page);
++	pmdp = pmd_offset(pudp, page);
+ 	ptep = pte_offset(pmdp, page);
+ 
+ 	/*
+@@ -407,7 +410,7 @@ static __init void tx39_probe_cache(void
+ 	}
+ }
+ 
+-void __init ld_mmu_tx39(void)
++void __init tx39_cache_init(void)
+ {
+ 	extern void build_clear_page(void);
+ 	extern void build_copy_page(void);
+@@ -490,4 +493,5 @@ void __init ld_mmu_tx39(void)
+ 
+ 	build_clear_page();
+ 	build_copy_page();
++	tx39h_flush_icache_all();
+ }
+diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
+--- a/arch/mips/mm/cache.c
++++ b/arch/mips/mm/cache.c
+@@ -23,8 +23,10 @@ void (*__flush_cache_all)(void);
+ void (*flush_cache_mm)(struct mm_struct *mm);
+ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
+ 	unsigned long end);
+-void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
+-void (*flush_icache_range)(unsigned long start, unsigned long end);
++void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
++	unsigned long pfn);
++void (*flush_icache_range)(unsigned long __user start,
++	unsigned long __user end);
+ void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page);
+ 
+ /* MIPS specific cache operations */
+@@ -32,6 +34,8 @@ void (*flush_cache_sigtramp)(unsigned lo
+ void (*flush_data_cache_page)(unsigned long addr);
+ void (*flush_icache_all)(void);
+ 
++EXPORT_SYMBOL(flush_data_cache_page);
++
+ #ifdef CONFIG_DMA_NONCOHERENT
+ 
+ /* DMA cache operations. */
+@@ -49,10 +53,12 @@ EXPORT_SYMBOL(_dma_cache_inv);
+  * We could optimize the case where the cache argument is not BCACHE but
+  * that seems very atypical use ...
+  */
+-asmlinkage int sys_cacheflush(unsigned long addr, unsigned long int bytes,
+-	unsigned int cache)
++asmlinkage int sys_cacheflush(unsigned long __user addr,
++	unsigned long bytes, unsigned int cache)
+ {
+-	if (!access_ok(VERIFY_WRITE, (void *) addr, bytes))
++	if (bytes == 0)
++		return 0;
++	if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes))
+ 		return -EFAULT;
+ 
+ 	flush_icache_range(addr, addr + bytes);
+@@ -100,58 +106,48 @@ void __update_cache(struct vm_area_struc
+ 	}
+ }
+ 
+-extern void ld_mmu_r23000(void);
+-extern void ld_mmu_r4xx0(void);
+-extern void ld_mmu_tx39(void);
+-extern void ld_mmu_r6000(void);
+-extern void ld_mmu_tfp(void);
+-extern void ld_mmu_andes(void);
+-extern void ld_mmu_sb1(void);
++#define __weak __attribute__((weak))
++
++static char cache_panic[] __initdata = "Yeee, unsupported cache architecture.";
+ 
+ void __init cpu_cache_init(void)
+ {
+-	if (cpu_has_4ktlb) {
+-#if defined(CONFIG_CPU_R4X00)  || defined(CONFIG_CPU_VR41XX) || \
+-    defined(CONFIG_CPU_R4300)  || defined(CONFIG_CPU_R5000)  || \
+-    defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432)  || \
+-    defined(CONFIG_CPU_R5500)  || defined(CONFIG_CPU_MIPS32) || \
+-    defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \
+-    defined(CONFIG_CPU_RM7000) || defined(CONFIG_CPU_RM9000)
+-		ld_mmu_r4xx0();
+-#endif
+-	} else switch (current_cpu_data.cputype) {
+-#ifdef CONFIG_CPU_R3000
+-	case CPU_R2000:
+-	case CPU_R3000:
+-	case CPU_R3000A:
+-	case CPU_R3081E:
+-		ld_mmu_r23000();
+-		break;
+-#endif
+-#ifdef CONFIG_CPU_TX39XX
+-	case CPU_TX3912:
+-	case CPU_TX3922:
+-	case CPU_TX3927:
+-		ld_mmu_tx39();
+-		break;
+-#endif
+-#ifdef CONFIG_CPU_R10000
+-	case CPU_R10000:
+-	case CPU_R12000:
+-		ld_mmu_r4xx0();
+-		break;
+-#endif
+-#ifdef CONFIG_CPU_SB1
+-	case CPU_SB1:
+-		ld_mmu_sb1();
+-		break;
+-#endif
+-
+-	case CPU_R8000:
+-		panic("R8000 is unsupported");
+-		break;
++	if (cpu_has_3k_cache) {
++		extern void __weak r3k_cache_init(void);
++
++		r3k_cache_init();
++		return;
++	}
++	if (cpu_has_6k_cache) {
++		extern void __weak r6k_cache_init(void);
+ 
+-	default:
+-		panic("Yeee, unsupported cache architecture.");
++		r6k_cache_init();
++		return;
+ 	}
++	if (cpu_has_4k_cache) {
++		extern void __weak r4k_cache_init(void);
++
++		r4k_cache_init();
++		return;
++	}
++	if (cpu_has_8k_cache) {
++		extern void __weak r8k_cache_init(void);
++
++		r8k_cache_init();
++		return;
++	}
++	if (cpu_has_tx39_cache) {
++		extern void __weak tx39_cache_init(void);
++
++		tx39_cache_init();
++		return;
++	}
++	if (cpu_has_sb1_cache) {
++		extern void __weak sb1_cache_init(void);
++
++		sb1_cache_init();
++		return;
++	}
++
++	panic(cache_panic);
+ }
+diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
+--- a/arch/mips/mm/cerr-sb1.c
++++ b/arch/mips/mm/cerr-sb1.c
+@@ -19,13 +19,19 @@
+ #include <linux/sched.h>
+ #include <asm/mipsregs.h>
+ #include <asm/sibyte/sb1250.h>
++#include <asm/sibyte/sb1250_regs.h>
+ 
+-#ifndef CONFIG_SIBYTE_BUS_WATCHER
++#if !defined(CONFIG_SIBYTE_BUS_WATCHER) || defined(CONFIG_SIBYTE_BW_TRACE)
+ #include <asm/io.h>
+-#include <asm/sibyte/sb1250_regs.h>
+ #include <asm/sibyte/sb1250_scd.h>
+ #endif
+ 
++/*
++ * We'd like to dump the L2_ECC_TAG register on errors, but errata make
++ * that unsafe... So for now we don't.  (BCM1250/BCM112x erratum SOC-48.)
++ */
++#undef DUMP_L2_ECC_TAG_ON_ERROR
++
+ /* SB1 definitions */
+ 
+ /* XXX should come from config1 XXX */
+@@ -139,12 +145,18 @@ static inline void breakout_cerrd(unsign
+ static void check_bus_watcher(void)
+ {
+ 	uint32_t status, l2_err, memio_err;
++#ifdef DUMP_L2_ECC_TAG_ON_ERROR
++	uint64_t l2_tag;
++#endif
+ 
+ 	/* Destructive read, clears register and interrupt */
+ 	status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
+ 	/* Bit 31 is always on, but there's no #define for that */
+ 	if (status & ~(1UL << 31)) {
+ 		l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
++#ifdef DUMP_L2_ECC_TAG_ON_ERROR
++		l2_tag = in64(IO_SPACE_BASE | A_L2_ECC_TAG);
++#endif
+ 		memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
+ 		prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
+ 		prom_printf("\nLast recorded signature:\n");
+@@ -153,6 +165,9 @@ static void check_bus_watcher(void)
+ 		       (int)(G_SCD_BERR_TID(status) >> 6),
+ 		       (int)G_SCD_BERR_RID(status),
+ 		       (int)G_SCD_BERR_DCODE(status));
++#ifdef DUMP_L2_ECC_TAG_ON_ERROR
++		prom_printf("Last L2 tag w/ bad ECC: %016llx\n", l2_tag);
++#endif
+ 	} else {
+ 		prom_printf("Bus watcher indicates no error\n");
+ 	}
+@@ -166,6 +181,16 @@ asmlinkage void sb1_cache_error(void)
+ 	uint64_t cerr_dpa;
+ 	uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
+ 
++#ifdef CONFIG_SIBYTE_BW_TRACE
++	/* Freeze the trace buffer now */
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++	csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
++#else
++	csr_out32(M_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
++#endif
++	prom_printf("Trace buffer frozen\n");
++#endif
++
+ 	prom_printf("Cache error exception on CPU %x:\n",
+ 		    (read_c0_prid() >> 25) & 0x7);
+ 
+@@ -229,11 +254,19 @@ asmlinkage void sb1_cache_error(void)
+ 
+ 	check_bus_watcher();
+ 
+-	while (1);
+ 	/*
+-	 * This tends to make things get really ugly; let's just stall instead.
+-	 *    panic("Can't handle the cache error!");
++	 * Calling panic() when a fatal cache error occurs scrambles the
++	 * state of the system (and the cache), making it difficult to
++	 * investigate after the fact.  However, if you just stall the CPU,
++	 * the other CPU may keep on running, which is typically very
++	 * undesirable.
+ 	 */
++#ifdef CONFIG_SB1_CERR_STALL
++	while (1)
++		;
++#else
++	panic("unhandled cache error");
++#endif
+ }
+ 
+ 
+@@ -434,7 +467,8 @@ static struct dc_state dc_states[] = {
+ };
+ 
+ #define DC_TAG_VALID(state) \
+-    (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c))
++    (((state) == 0x0) || ((state) == 0xf) || ((state) == 0x13) || \
++     ((state) == 0x19) || ((state) == 0x16) || ((state) == 0x1c))
+ 
+ static char *dc_state_str(unsigned char state)
+ {
+@@ -505,6 +539,7 @@ static uint32_t extract_dc(unsigned shor
+ 			uint64_t datalo;
+ 			uint32_t datalohi, datalolo, datahi;
+ 			int offset;
++			char bad_ecc = 0;
+ 
+ 			for (offset = 0; offset < 4; offset++) {
+ 				/* Index-load-data-D */
+@@ -525,8 +560,7 @@ static uint32_t extract_dc(unsigned shor
+ 				ecc = dc_ecc(datalo);
+ 				if (ecc != datahi) {
+ 					int bits = 0;
+-					prom_printf("  ** bad ECC (%02x %02x) ->",
+-						    datahi, ecc);
++					bad_ecc |= 1 << (3-offset);
+ 					ecc ^= datahi;
+ 					while (ecc) {
+ 						if (ecc & 1) bits++;
+@@ -537,6 +571,10 @@ static uint32_t extract_dc(unsigned shor
+ 				prom_printf("  %02X-%016llX", datahi, datalo);
+ 			}
+ 			prom_printf("\n");
++			if (bad_ecc)
++				prom_printf("  dwords w/ bad ECC: %d %d %d %d\n",
++					    !!(bad_ecc & 8), !!(bad_ecc & 4),
++					    !!(bad_ecc & 2), !!(bad_ecc & 1));
+ 		}
+ 	}
+ 	return res;
+diff --git a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S
+--- a/arch/mips/mm/cex-sb1.S
++++ b/arch/mips/mm/cex-sb1.S
+@@ -64,6 +64,10 @@ LEAF(except_vec2_sb1)
+ 	sd	k0,0x170($0)
+ 	sd	k1,0x178($0)
+ 
++#if CONFIG_SB1_CEX_ALWAYS_FATAL
++	j	handle_vec2_sb1
++	 nop
++#else
+ 	/*
+ 	 * M_ERRCTL_RECOVERABLE is bit 31, which makes it easy to tell
+ 	 * if we can fast-path out of here for a h/w-recovered error.
+@@ -134,6 +138,7 @@ unrecoverable:
+ 	/* Unrecoverable Icache or Dcache error; log it and/or fail */
+ 	j	handle_vec2_sb1
+ 	 nop
++#endif
+ 
+ END(except_vec2_sb1)
+ 
+diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
+--- a/arch/mips/mm/dma-coherent.c
++++ b/arch/mips/mm/dma-coherent.c
+@@ -9,16 +9,16 @@
+  */
+ #include <linux/config.h>
+ #include <linux/types.h>
++#include <linux/dma-mapping.h>
+ #include <linux/mm.h>
+ #include <linux/module.h>
+ #include <linux/string.h>
+-#include <linux/pci.h>
+ 
+ #include <asm/cache.h>
+ #include <asm/io.h>
+ 
+ void *dma_alloc_noncoherent(struct device *dev, size_t size,
+-	dma_addr_t * dma_handle, int gfp)
++	dma_addr_t * dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 	/* ignore region specifiers */
+@@ -39,7 +39,7 @@ void *dma_alloc_noncoherent(struct devic
+ EXPORT_SYMBOL(dma_alloc_noncoherent);
+ 
+ void *dma_alloc_coherent(struct device *dev, size_t size,
+-	dma_addr_t * dma_handle, int gfp)
++	dma_addr_t * dma_handle, gfp_t gfp)
+ 	__attribute__((alias("dma_alloc_noncoherent")));
+ 
+ EXPORT_SYMBOL(dma_alloc_coherent);
+diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c
+--- a/arch/mips/mm/dma-ip27.c
++++ b/arch/mips/mm/dma-ip27.c
+@@ -22,7 +22,7 @@
+ 	pdev_to_baddr(to_pci_dev(dev), (addr))
+ 
+ void *dma_alloc_noncoherent(struct device *dev, size_t size,
+-	dma_addr_t * dma_handle, int gfp)
++	dma_addr_t * dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 
+@@ -44,7 +44,7 @@ void *dma_alloc_noncoherent(struct devic
+ EXPORT_SYMBOL(dma_alloc_noncoherent);
+ 
+ void *dma_alloc_coherent(struct device *dev, size_t size,
+-	dma_addr_t * dma_handle, int gfp)
++	dma_addr_t * dma_handle, gfp_t gfp)
+ 	__attribute__((alias("dma_alloc_noncoherent")));
+ 
+ EXPORT_SYMBOL(dma_alloc_coherent);
+diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
+--- a/arch/mips/mm/dma-ip32.c
++++ b/arch/mips/mm/dma-ip32.c
+@@ -37,7 +37,7 @@
+ #define RAM_OFFSET_MASK	0x3fffffff
+ 
+ void *dma_alloc_noncoherent(struct device *dev, size_t size,
+-	dma_addr_t * dma_handle, int gfp)
++	dma_addr_t * dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 	/* ignore region specifiers */
+@@ -61,7 +61,7 @@ void *dma_alloc_noncoherent(struct devic
+ EXPORT_SYMBOL(dma_alloc_noncoherent);
+ 
+ void *dma_alloc_coherent(struct device *dev, size_t size,
+-	dma_addr_t * dma_handle, int gfp)
++	dma_addr_t * dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 
+diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
+--- a/arch/mips/mm/dma-noncoherent.c
++++ b/arch/mips/mm/dma-noncoherent.c
+@@ -24,7 +24,7 @@
+  */
+ 
+ void *dma_alloc_noncoherent(struct device *dev, size_t size,
+-	dma_addr_t * dma_handle, int gfp)
++	dma_addr_t * dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 	/* ignore region specifiers */
+@@ -45,7 +45,7 @@ void *dma_alloc_noncoherent(struct devic
+ EXPORT_SYMBOL(dma_alloc_noncoherent);
+ 
+ void *dma_alloc_coherent(struct device *dev, size_t size,
+-	dma_addr_t * dma_handle, int gfp)
++	dma_addr_t * dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 
+@@ -105,22 +105,7 @@ dma_addr_t dma_map_single(struct device 
+ {
+ 	unsigned long addr = (unsigned long) ptr;
+ 
+-	switch (direction) {
+-	case DMA_TO_DEVICE:
+-		dma_cache_wback(addr, size);
+-		break;
+-
+-	case DMA_FROM_DEVICE:
+-		dma_cache_inv(addr, size);
+-		break;
+-
+-	case DMA_BIDIRECTIONAL:
+-		dma_cache_wback_inv(addr, size);
+-		break;
+-
+-	default:
+-		BUG();
+-	}
++	__dma_sync(addr, size, direction);
+ 
+ 	return virt_to_phys(ptr);
+ }
+@@ -133,22 +118,7 @@ void dma_unmap_single(struct device *dev
+ 	unsigned long addr;
+ 	addr = dma_addr + PAGE_OFFSET;
+ 
+-	switch (direction) {
+-	case DMA_TO_DEVICE:
+-		//dma_cache_wback(addr, size);
+-		break;
+-
+-	case DMA_FROM_DEVICE:
+-		//dma_cache_inv(addr, size);
+-		break;
+-
+-	case DMA_BIDIRECTIONAL:
+-		//dma_cache_wback_inv(addr, size);
+-		break;
+-
+-	default:
+-		BUG();
+-	}
++	//__dma_sync(addr, size, direction);
+ }
+ 
+ EXPORT_SYMBOL(dma_unmap_single);
+@@ -164,10 +134,11 @@ int dma_map_sg(struct device *dev, struc
+ 		unsigned long addr;
+ 
+ 		addr = (unsigned long) page_address(sg->page);
+-		if (addr)
++		if (addr) {
+ 			__dma_sync(addr + sg->offset, sg->length, direction);
+-		sg->dma_address = (dma_addr_t)
+-			(page_to_phys(sg->page) + sg->offset);
++			sg->dma_address = (dma_addr_t)page_to_phys(sg->page)
++					  + sg->offset;
++		}
+ 	}
+ 
+ 	return nents;
+@@ -218,9 +189,8 @@ void dma_unmap_sg(struct device *dev, st
+ 
+ 	for (i = 0; i < nhwentries; i++, sg++) {
+ 		addr = (unsigned long) page_address(sg->page);
+-		if (!addr)
+-			continue;
+-		dma_cache_wback_inv(addr + sg->offset, sg->length);
++		if (addr)
++			__dma_sync(addr + sg->offset, sg->length, direction);
+ 	}
+ }
+ 
+diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
+--- a/arch/mips/mm/fault.c
++++ b/arch/mips/mm/fault.c
+@@ -25,6 +25,7 @@
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ #include <asm/ptrace.h>
++#include <asm/highmem.h>		/* For VMALLOC_END */
+ 
+ /*
+  * This routine handles page faults.  It determines the address,
+@@ -57,7 +58,7 @@ asmlinkage void do_page_fault(struct pt_
+ 	 * only copy the information from the master page table,
+ 	 * nothing more.
+ 	 */
+-	if (unlikely(address >= VMALLOC_START))
++	if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
+ 		goto vmalloc_fault;
+ 
+ 	/*
+@@ -140,7 +141,7 @@ bad_area_nosemaphore:
+ 		info.si_signo = SIGSEGV;
+ 		info.si_errno = 0;
+ 		/* info.si_code has been set above */
+-		info.si_addr = (void *) address;
++		info.si_addr = (void __user *) address;
+ 		force_sig_info(SIGSEGV, &info, tsk);
+ 		return;
+ 	}
+@@ -196,7 +197,7 @@ do_sigbus:
+ 	info.si_signo = SIGBUS;
+ 	info.si_errno = 0;
+ 	info.si_code = BUS_ADRERR;
+-	info.si_addr = (void *) address;
++	info.si_addr = (void __user *) address;
+ 	force_sig_info(SIGBUS, &info, tsk);
+ 
+ 	return;
+@@ -212,6 +213,7 @@ vmalloc_fault:
+ 		 */
+ 		int offset = __pgd_offset(address);
+ 		pgd_t *pgd, *pgd_k;
++		pud_t *pud, *pud_k;
+ 		pmd_t *pmd, *pmd_k;
+ 		pte_t *pte_k;
+ 
+@@ -222,8 +224,13 @@ vmalloc_fault:
+ 			goto no_context;
+ 		set_pgd(pgd, *pgd_k);
+ 
+-		pmd = pmd_offset(pgd, address);
+-		pmd_k = pmd_offset(pgd_k, address);
++		pud = pud_offset(pgd, address);
++		pud_k = pud_offset(pgd_k, address);
++		if (!pud_present(*pud_k))
++			goto no_context;
++
++		pmd = pmd_offset(pud, address);
++		pmd_k = pmd_offset(pud_k, address);
+ 		if (!pmd_present(*pmd_k))
+ 			goto no_context;
+ 		set_pmd(pmd, *pmd_k);
+diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
+--- a/arch/mips/mm/highmem.c
++++ b/arch/mips/mm/highmem.c
+@@ -83,6 +83,25 @@ void __kunmap_atomic(void *kvaddr, enum 
+ 	preempt_check_resched();
+ }
+ 
++/*
++ * This is the same as kmap_atomic() but can map memory that doesn't
++ * have a struct page associated with it.
++ */
++void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
++{
++	enum fixed_addresses idx;
++	unsigned long vaddr;
++
++	inc_preempt_count();
++
++	idx = type + KM_TYPE_NR*smp_processor_id();
++	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
++	set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
++	flush_tlb_one(vaddr);
++
++	return (void*) vaddr;
++}
++
+ struct page *__kmap_atomic_to_page(void *ptr)
+ {
+ 	unsigned long idx, vaddr = (unsigned long)ptr;
+diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
+--- a/arch/mips/mm/init.c
++++ b/arch/mips/mm/init.c
+@@ -83,7 +83,7 @@ pte_t *kmap_pte;
+ pgprot_t kmap_prot;
+ 
+ #define kmap_get_fixmap_pte(vaddr)					\
+-	pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
++	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
+ 
+ static void __init kmap_init(void)
+ {
+@@ -96,36 +96,42 @@ static void __init kmap_init(void)
+ 	kmap_prot = PAGE_KERNEL;
+ }
+ 
+-#ifdef CONFIG_64BIT
+-static void __init fixrange_init(unsigned long start, unsigned long end,
++#ifdef CONFIG_32BIT
++void __init fixrange_init(unsigned long start, unsigned long end,
+ 	pgd_t *pgd_base)
+ {
+ 	pgd_t *pgd;
++	pud_t *pud;
+ 	pmd_t *pmd;
+ 	pte_t *pte;
+-	int i, j;
++	int i, j, k;
+ 	unsigned long vaddr;
+ 
+ 	vaddr = start;
+ 	i = __pgd_offset(vaddr);
+-	j = __pmd_offset(vaddr);
++	j = __pud_offset(vaddr);
++	k = __pmd_offset(vaddr);
+ 	pgd = pgd_base + i;
+ 
+ 	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+-		pmd = (pmd_t *)pgd;
+-		for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
+-			if (pmd_none(*pmd)) {
+-				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+-				set_pmd(pmd, __pmd(pte));
+-				if (pte != pte_offset_kernel(pmd, 0))
+-					BUG();
++		pud = (pud_t *)pgd;
++		for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
++			pmd = (pmd_t *)pud;
++			for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
++				if (pmd_none(*pmd)) {
++					pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++					set_pmd(pmd, __pmd(pte));
++					if (pte != pte_offset_kernel(pmd, 0))
++						BUG();
++				}
++				vaddr += PMD_SIZE;
+ 			}
+-			vaddr += PMD_SIZE;
++			k = 0;
+ 		}
+ 		j = 0;
+ 	}
+ }
+-#endif /* CONFIG_64BIT */
++#endif /* CONFIG_32BIT */
+ #endif /* CONFIG_HIGHMEM */
+ 
+ #ifndef CONFIG_NEED_MULTIPLE_NODES
+diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
+--- a/arch/mips/mm/ioremap.c
++++ b/arch/mips/mm/ioremap.c
+@@ -55,7 +55,7 @@ static inline int remap_area_pmd(pmd_t *
+ 	if (address >= end)
+ 		BUG();
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+@@ -77,11 +77,15 @@ static int remap_area_pages(unsigned lon
+ 	flush_cache_all();
+ 	if (address >= end)
+ 		BUG();
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
++		pud_t *pud;
+ 		pmd_t *pmd;
+-		pmd = pmd_alloc(&init_mm, dir, address);
++
+ 		error = -ENOMEM;
++		pud = pud_alloc(&init_mm, dir, address);
++		if (!pud)
++			break;
++		pmd = pmd_alloc(&init_mm, pud, address);
+ 		if (!pmd)
+ 			break;
+ 		if (remap_area_pmd(pmd, address, end - address,
+@@ -91,21 +95,11 @@ static int remap_area_pages(unsigned lon
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_tlb_all();
+ 	return error;
+ }
+ 
+ /*
+- * Allow physical addresses to be fixed up to help 36 bit peripherals.
+- */
+-phys_t __attribute__ ((weak))
+-fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+-{
+-	return phys_addr;
+-}
+-
+-/*
+  * Generic mapping function (not visible outside):
+  */
+ 
+@@ -121,7 +115,7 @@ fixup_bigphys_addr(phys_t phys_addr, phy
+ 
+ #define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
+ 
+-void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
++void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
+ {
+ 	struct vm_struct * area;
+ 	unsigned long offset;
+@@ -141,7 +135,7 @@ void * __ioremap(phys_t phys_addr, phys_
+ 	 */
+ 	if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) &&
+ 	    flags == _CACHE_UNCACHED)
+-		return (void *) KSEG1ADDR(phys_addr);
++		return (void __iomem *) CKSEG1ADDR(phys_addr);
+ 
+ 	/*
+ 	 * Don't allow anybody to remap normal RAM that we're using..
+@@ -177,10 +171,10 @@ void * __ioremap(phys_t phys_addr, phys_
+ 		return NULL;
+ 	}
+ 
+-	return (void *) (offset + (char *)addr);
++	return (void __iomem *) (offset + (char *)addr);
+ }
+ 
+-#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == KSEG1)
++#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
+ 
+ void __iounmap(volatile void __iomem *addr)
+ {
+@@ -190,10 +184,8 @@ void __iounmap(volatile void __iomem *ad
+ 		return;
+ 
+ 	p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
+-	if (!p) {
++	if (!p)
+ 		printk(KERN_ERR "iounmap: bad address %p\n", addr);
+-		return;
+-	}
+ 
+         kfree(p);
+ }
+diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
+--- a/arch/mips/mm/pg-r4k.c
++++ b/arch/mips/mm/pg-r4k.c
+@@ -25,7 +25,10 @@
+ #include <asm/cpu.h>
+ #include <asm/war.h>
+ 
+-#define half_scache_line_size()		(cpu_scache_line_size() >> 1)
++#define half_scache_line_size()	(cpu_scache_line_size() >> 1)
++#define cpu_is_r4600_v1_x()	((read_c0_prid() & 0xfffffff0) == 0x00002010)
++#define cpu_is_r4600_v2_x()	((read_c0_prid() & 0xfffffff0) == 0x00002020)
++
+ 
+ /*
+  * Maximum sizes:
+@@ -198,15 +201,15 @@ static inline void build_cdex_p(void)
+ 	if (store_offset & (cpu_dcache_line_size() - 1))
+ 		return;
+ 
+-	if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) {
++	if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) {
+ 		build_nop();
+ 		build_nop();
+ 		build_nop();
+ 		build_nop();
+ 	}
+ 
+-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+-		build_insn_word(0x8c200000);	/* lw      $zero, ($at) */
++	if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
++		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
+ 
+ 	mi.c_format.opcode     = cache_op;
+ 	mi.c_format.rs         = 4;		/* $a0 */
+@@ -361,7 +364,7 @@ void __init build_clear_page(void)
+ 
+ 	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+ 
+-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
++	if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
+ 		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
+ 
+ dest = label();
+@@ -404,9 +407,6 @@ dest = label();
+ 
+ 	build_jr_ra();
+ 
+-	flush_icache_range((unsigned long)&clear_page_array,
+-	                   (unsigned long) epc);
+-
+ 	BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array));
+ }
+ 
+@@ -420,7 +420,7 @@ void __init build_copy_page(void)
+ 
+ 	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+ 
+-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
++	if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
+ 		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
+ 
+ dest = label();
+@@ -482,8 +482,5 @@ dest = label();
+ 
+ 	build_jr_ra();
+ 
+-	flush_icache_range((unsigned long)&copy_page_array,
+-	                   (unsigned long) epc);
+-
+ 	BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
+ }
+diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
+--- a/arch/mips/mm/pg-sb1.c
++++ b/arch/mips/mm/pg-sb1.c
+@@ -60,7 +60,8 @@ static inline void clear_page_cpu(void *
+ 	"	.set	noreorder	\n"
+ #ifdef CONFIG_CPU_HAS_PREFETCH
+ 	"	daddiu	%0, %0, 128	\n"
+-	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%0)  \n"  /* Prefetch the first 4 lines */
++	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%0)  \n"
++					     /* Prefetch the first 4 lines */
+ 	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%0)  \n"
+ 	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -64(%0)  \n"
+ 	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%0)  \n"
+@@ -106,7 +107,8 @@ static inline void copy_page_cpu(void *t
+ #ifdef CONFIG_CPU_HAS_PREFETCH
+ 	"	daddiu	%0, %0, 128	\n"
+ 	"	daddiu	%1, %1, 128	\n"
+-	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ", -128(%0)\n"  /* Prefetch the first 4 lines */
++	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ", -128(%0)\n"
++					     /* Prefetch the first 4 lines */
+ 	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n"
+ 	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -96(%0)\n"
+ 	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%1)\n"
+@@ -207,66 +209,73 @@ typedef struct dmadscr_s {
+ 	u64 pad_b;
+ } dmadscr_t;
+ 
+-static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES)));
++static dmadscr_t page_descr[DM_NUM_CHANNELS]
++	__attribute__((aligned(SMP_CACHE_BYTES)));
+ 
+ void sb1_dma_init(void)
+ {
+-	int cpu = smp_processor_id();
+-	u64 base_val = CPHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
++	int i;
+ 
+-	bus_writeq(base_val,
+-		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+-	bus_writeq(base_val | M_DM_DSCR_BASE_RESET,
+-		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+-	bus_writeq(base_val | M_DM_DSCR_BASE_ENABL,
+-		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
++	for (i = 0; i < DM_NUM_CHANNELS; i++) {
++		const u64 base_val = CPHYSADDR(&page_descr[i]) |
++				     V_DM_DSCR_BASE_RINGSZ(1);
++		volatile void *base_reg =
++			IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
++
++		__raw_writeq(base_val, base_reg);
++		__raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg);
++		__raw_writeq(base_val | M_DM_DSCR_BASE_ENABL, base_reg);
++	}
+ }
+ 
+ void clear_page(void *page)
+ {
+-	int cpu = smp_processor_id();
++	u64 to_phys = CPHYSADDR(page);
++	unsigned int cpu = smp_processor_id();
+ 
+-	/* if the page is above Kseg0, use old way */
++	/* if the page is not in KSEG0, use old way */
+ 	if ((long)KSEGX(page) != (long)CKSEG0)
+ 		return clear_page_cpu(page);
+ 
+-	page_descr[cpu].dscr_a = CPHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
++	page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM |
++				 M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+ 	page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+-	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
++	__raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+ 
+ 	/*
+ 	 * Don't really want to do it this way, but there's no
+ 	 * reliable way to delay completion detection.
+ 	 */
+-	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
+-			   M_DM_DSCR_BASE_INTERRUPT))))
++	while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
++		 & M_DM_DSCR_BASE_INTERRUPT))
+ 		;
+-	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
++	__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ }
+ 
+ void copy_page(void *to, void *from)
+ {
+-	unsigned long from_phys = CPHYSADDR(from);
+-	unsigned long to_phys = CPHYSADDR(to);
+-	int cpu = smp_processor_id();
++	u64 from_phys = CPHYSADDR(from);
++	u64 to_phys = CPHYSADDR(to);
++	unsigned int cpu = smp_processor_id();
+ 
+-	/* if either page is above Kseg0, use old way */
++	/* if any page is not in KSEG0, use old way */
+ 	if ((long)KSEGX(to) != (long)CKSEG0
+ 	    || (long)KSEGX(from) != (long)CKSEG0)
+ 		return copy_page_cpu(to, from);
+ 
+-	page_descr[cpu].dscr_a = CPHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+-	page_descr[cpu].dscr_b = CPHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+-	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
++	page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST |
++				 M_DM_DSCRA_INTERRUPT;
++	page_descr[cpu].dscr_b = from_phys | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
++	__raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+ 
+ 	/*
+ 	 * Don't really want to do it this way, but there's no
+ 	 * reliable way to delay completion detection.
+ 	 */
+-	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
+-				    M_DM_DSCR_BASE_INTERRUPT))))
++	while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
++		 & M_DM_DSCR_BASE_INTERRUPT))
+ 		;
+-	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
++	__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ }
+ 
+ #else /* !CONFIG_SIBYTE_DMA_PAGEOPS */
+diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
+--- a/arch/mips/mm/pgtable-32.c
++++ b/arch/mips/mm/pgtable-32.c
+@@ -10,6 +10,7 @@
+ #include <linux/mm.h>
+ #include <linux/bootmem.h>
+ #include <linux/highmem.h>
++#include <asm/fixmap.h>
+ #include <asm/pgtable.h>
+ 
+ void pgd_init(unsigned long page)
+@@ -29,42 +30,12 @@ void pgd_init(unsigned long page)
+ 	}
+ }
+ 
+-#ifdef CONFIG_HIGHMEM
+-static void __init fixrange_init (unsigned long start, unsigned long end,
+-	pgd_t *pgd_base)
+-{
+-	pgd_t *pgd;
+-	pmd_t *pmd;
+-	pte_t *pte;
+-	int i, j;
+-	unsigned long vaddr;
+-
+-	vaddr = start;
+-	i = __pgd_offset(vaddr);
+-	j = __pmd_offset(vaddr);
+-	pgd = pgd_base + i;
+-
+-	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+-		pmd = (pmd_t *)pgd;
+-		for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
+-			if (pmd_none(*pmd)) {
+-				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+-				set_pmd(pmd, __pmd((unsigned long)pte));
+-				if (pte != pte_offset_kernel(pmd, 0))
+-					BUG();
+-			}
+-			vaddr += PMD_SIZE;
+-		}
+-		j = 0;
+-	}
+-}
+-#endif
+-
+ void __init pagetable_init(void)
+ {
+ #ifdef CONFIG_HIGHMEM
+ 	unsigned long vaddr;
+ 	pgd_t *pgd, *pgd_base;
++	pud_t *pud;
+ 	pmd_t *pmd;
+ 	pte_t *pte;
+ #endif
+@@ -90,7 +61,8 @@ void __init pagetable_init(void)
+ 	fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+ 
+ 	pgd = swapper_pg_dir + __pgd_offset(vaddr);
+-	pmd = pmd_offset(pgd, vaddr);
++	pud = pud_offset(pgd, vaddr);
++	pmd = pmd_offset(pud, vaddr);
+ 	pte = pte_offset_kernel(pmd, vaddr);
+ 	pkmap_page_table = pte;
+ #endif
+diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c
+--- a/arch/mips/mm/sc-rm7k.c
++++ b/arch/mips/mm/sc-rm7k.c
+@@ -15,6 +15,7 @@
+ #include <asm/cacheops.h>
+ #include <asm/mipsregs.h>
+ #include <asm/processor.h>
++#include <asm/cacheflush.h> /* for run_uncached() */
+ 
+ /* Primary cache parameters. */
+ #define sc_lsize	32
+@@ -96,25 +97,13 @@ static void rm7k_sc_inv(unsigned long ad
+ }
+ 
+ /*
+- * This function is executed in the uncached segment CKSEG1.
+- * It must not touch the stack, because the stack pointer still points
+- * into CKSEG0.
+- *
+- * Three options:
+- *	- Write it in assembly and guarantee that we don't use the stack.
+- *	- Disable caching for CKSEG0 before calling it.
+- *	- Pray that GCC doesn't randomly start using the stack.
+- *
+- * This being Linux, we obviously take the least sane of those options -
+- * following DaveM's lead in c-r4k.c
+- *
+- * It seems we get our kicks from relying on unguaranteed behaviour in GCC
++ * This function is executed in uncached address space.
+  */
+ static __init void __rm7k_sc_enable(void)
+ {
+ 	int i;
+ 
+-	set_c0_config(1 << 3);				/* CONF_SE */
++	set_c0_config(RM7K_CONF_SE);
+ 
+ 	write_c0_taglo(0);
+ 	write_c0_taghi(0);
+@@ -127,24 +116,22 @@ static __init void __rm7k_sc_enable(void
+ 		      ".set mips0\n\t"
+ 		      ".set reorder"
+ 		      :
+-		      : "r" (KSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
++		      : "r" (CKSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
+ 	}
+ }
+ 
+ static __init void rm7k_sc_enable(void)
+ {
+-	void (*func)(void) = (void *) KSEG1ADDR(&__rm7k_sc_enable);
+-
+-	if (read_c0_config() & 0x08)			/* CONF_SE */
++	if (read_c0_config() & RM7K_CONF_SE)
+ 		return;
+ 
+-	printk(KERN_INFO "Enabling secondary cache...");
+-	func();
++	printk(KERN_INFO "Enabling secondary cache...\n");
++	run_uncached(__rm7k_sc_enable);
+ }
+ 
+ static void rm7k_sc_disable(void)
+ {
+-	clear_c0_config(1<<3);				/* CONF_SE */
++	clear_c0_config(RM7K_CONF_SE);
+ }
+ 
+ struct bcache_ops rm7k_sc_ops = {
+@@ -158,19 +145,19 @@ void __init rm7k_sc_init(void)
+ {
+ 	unsigned int config = read_c0_config();
+ 
+-	if ((config >> 31) & 1)		/* Bit 31 set -> no S-Cache */
++	if ((config & RM7K_CONF_SC))
+ 		return;
+ 
+ 	printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
+ 	       (scache_size >> 10), sc_lsize);
+ 
+-	if (!((config >> 3) & 1))	/* CONF_SE */
++	if (!(config & RM7K_CONF_SE))
+ 		rm7k_sc_enable();
+ 
+ 	/*
+ 	 * While we're at it let's deal with the tertiary cache.
+ 	 */
+-	if (!((config >> 17) & 1)) {
++	if (!(config & RM7K_CONF_TC)) {
+ 
+ 		/*
+ 		 * We can't enable the L3 cache yet. There may be board-specific
+@@ -183,9 +170,9 @@ void __init rm7k_sc_init(void)
+ 		 * to probe it.
+ 		 */
+ 		printk(KERN_INFO "Tertiary cache present, %s enabled\n",
+-		       config&(1<<12) ? "already" : "not (yet)");
++		       (config & RM7K_CONF_TE) ? "already" : "not (yet)");
+ 
+-		if ((config >> 12) & 1)
++		if ((config & RM7K_CONF_TE))
+ 			rm7k_tcache_enabled = 1;
+ 	}
+ 
+diff --git a/arch/mips/mm/tlb-andes.c b/arch/mips/mm/tlb-andes.c
+--- a/arch/mips/mm/tlb-andes.c
++++ b/arch/mips/mm/tlb-andes.c
+@@ -195,6 +195,7 @@ void __update_tlb(struct vm_area_struct 
+ {
+ 	unsigned long flags;
+ 	pgd_t *pgdp;
++	pud_t *pudp;
+ 	pmd_t *pmdp;
+ 	pte_t *ptep;
+ 	int idx, pid;
+@@ -220,7 +221,8 @@ void __update_tlb(struct vm_area_struct 
+ 	write_c0_entryhi(address | (pid));
+ 	pgdp = pgd_offset(vma->vm_mm, address);
+ 	tlb_probe();
+-	pmdp = pmd_offset(pgdp, address);
++	pudp = pud_offset(pgdp, address);
++	pmdp = pmd_offset(pudp, address);
+ 	idx = read_c0_index();
+ 	ptep = pte_offset_map(pmdp, address);
+ 	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
+--- a/arch/mips/mm/tlb-r4k.c
++++ b/arch/mips/mm/tlb-r4k.c
+@@ -21,6 +21,12 @@
+ 
+ extern void build_tlb_refill_handler(void);
+ 
++/*
++ * Make sure all entries differ.  If they're not different
++ * MIPS32 will take revenge ...
++ */
++#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
++
+ /* CP0 hazard avoidance. */
+ #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+ 				     "nop; nop; nop; nop; nop; nop;\n\t" \
+@@ -42,11 +48,8 @@ void local_flush_tlb_all(void)
+ 
+ 	/* Blast 'em all away. */
+ 	while (entry < current_cpu_data.tlbsize) {
+-		/*
+-		 * Make sure all entries differ.  If they're not different
+-		 * MIPS32 will take revenge ...
+-		 */
+-		write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
++		/* Make sure all entries differ. */
++		write_c0_entryhi(UNIQUE_ENTRYHI(entry));
+ 		write_c0_index(entry);
+ 		mtc0_tlbw_hazard();
+ 		tlb_write_indexed();
+@@ -57,12 +60,21 @@ void local_flush_tlb_all(void)
+ 	local_irq_restore(flags);
+ }
+ 
++/* All entries common to a mm share an asid.  To effectively flush
++   these entries, we just bump the asid. */
+ void local_flush_tlb_mm(struct mm_struct *mm)
+ {
+-	int cpu = smp_processor_id();
++	int cpu;
++
++	preempt_disable();
+ 
+-	if (cpu_context(cpu, mm) != 0)
+-		drop_mmu_context(mm,cpu);
++	cpu = smp_processor_id();
++
++	if (cpu_context(cpu, mm) != 0) {
++		drop_mmu_context(mm, cpu);
++	}
++
++	preempt_enable();
+ }
+ 
+ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+@@ -75,9 +87,9 @@ void local_flush_tlb_range(struct vm_are
+ 		unsigned long flags;
+ 		int size;
+ 
+-		local_irq_save(flags);
+ 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ 		size = (size + 1) >> 1;
++		local_irq_save(flags);
+ 		if (size <= current_cpu_data.tlbsize/2) {
+ 			int oldpid = read_c0_entryhi();
+ 			int newpid = cpu_asid(cpu, mm);
+@@ -99,8 +111,7 @@ void local_flush_tlb_range(struct vm_are
+ 				if (idx < 0)
+ 					continue;
+ 				/* Make sure all entries differ. */
+-				write_c0_entryhi(CKSEG0 +
+-				                 (idx << (PAGE_SHIFT + 1)));
++				write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+ 				mtc0_tlbw_hazard();
+ 				tlb_write_indexed();
+ 			}
+@@ -118,9 +129,9 @@ void local_flush_tlb_kernel_range(unsign
+ 	unsigned long flags;
+ 	int size;
+ 
+-	local_irq_save(flags);
+ 	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ 	size = (size + 1) >> 1;
++	local_irq_save(flags);
+ 	if (size <= current_cpu_data.tlbsize / 2) {
+ 		int pid = read_c0_entryhi();
+ 
+@@ -142,7 +153,7 @@ void local_flush_tlb_kernel_range(unsign
+ 			if (idx < 0)
+ 				continue;
+ 			/* Make sure all entries differ. */
+-			write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
++			write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+ 			mtc0_tlbw_hazard();
+ 			tlb_write_indexed();
+ 		}
+@@ -176,7 +187,7 @@ void local_flush_tlb_page(struct vm_area
+ 		if (idx < 0)
+ 			goto finish;
+ 		/* Make sure all entries differ. */
+-		write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
++		write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+ 		mtc0_tlbw_hazard();
+ 		tlb_write_indexed();
+ 		tlbw_use_hazard();
+@@ -197,8 +208,8 @@ void local_flush_tlb_one(unsigned long p
+ 	int oldpid, idx;
+ 
+ 	local_irq_save(flags);
+-	page &= (PAGE_MASK << 1);
+ 	oldpid = read_c0_entryhi();
++	page &= (PAGE_MASK << 1);
+ 	write_c0_entryhi(page);
+ 	mtc0_tlbw_hazard();
+ 	tlb_probe();
+@@ -208,7 +219,7 @@ void local_flush_tlb_one(unsigned long p
+ 	write_c0_entrylo1(0);
+ 	if (idx >= 0) {
+ 		/* Make sure all entries differ. */
+-		write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
++		write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+ 		mtc0_tlbw_hazard();
+ 		tlb_write_indexed();
+ 		tlbw_use_hazard();
+@@ -227,6 +238,7 @@ void __update_tlb(struct vm_area_struct 
+ {
+ 	unsigned long flags;
+ 	pgd_t *pgdp;
++	pud_t *pudp;
+ 	pmd_t *pmdp;
+ 	pte_t *ptep;
+ 	int idx, pid;
+@@ -237,35 +249,34 @@ void __update_tlb(struct vm_area_struct 
+ 	if (current->active_mm != vma->vm_mm)
+ 		return;
+ 
+-	pid = read_c0_entryhi() & ASID_MASK;
+-
+ 	local_irq_save(flags);
++
++	pid = read_c0_entryhi() & ASID_MASK;
+ 	address &= (PAGE_MASK << 1);
+ 	write_c0_entryhi(address | pid);
+ 	pgdp = pgd_offset(vma->vm_mm, address);
+ 	mtc0_tlbw_hazard();
+ 	tlb_probe();
+ 	BARRIER;
+-	pmdp = pmd_offset(pgdp, address);
++	pudp = pud_offset(pgdp, address);
++	pmdp = pmd_offset(pudp, address);
+ 	idx = read_c0_index();
+ 	ptep = pte_offset_map(pmdp, address);
+ 
+- #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+- 	write_c0_entrylo0(ptep->pte_high);
+- 	ptep++;
+- 	write_c0_entrylo1(ptep->pte_high);
++#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
++	write_c0_entrylo0(ptep->pte_high);
++	ptep++;
++	write_c0_entrylo1(ptep->pte_high);
+ #else
+-  	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+-  	write_c0_entrylo1(pte_val(*ptep) >> 6);
++	write_c0_entrylo0(pte_val(*ptep++) >> 6);
++	write_c0_entrylo1(pte_val(*ptep) >> 6);
+ #endif
+-	write_c0_entryhi(address | pid);
+ 	mtc0_tlbw_hazard();
+ 	if (idx < 0)
+ 		tlb_write_random();
+ 	else
+ 		tlb_write_indexed();
+ 	tlbw_use_hazard();
+-	write_c0_entryhi(pid);
+ 	local_irq_restore(flags);
+ }
+ 
+@@ -357,7 +368,8 @@ __init int add_temporary_entry(unsigned 
+ 	old_pagemask = read_c0_pagemask();
+ 	wired = read_c0_wired();
+ 	if (--temp_tlb_entry < wired) {
+-		printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");
++		printk(KERN_WARNING
++		       "No TLB space left for add_temporary_entry\n");
+ 		ret = -ENOSPC;
+ 		goto out;
+ 	}
+@@ -388,7 +400,7 @@ static void __init probe_tlb(unsigned lo
+ 	 * is not supported, we assume R4k style.  Cpu probing already figured
+ 	 * out the number of tlb entries.
+ 	 */
+-	if ((c->processor_id  & 0xff0000) == PRID_COMP_LEGACY)
++	if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY)
+ 		return;
+ 
+ 	reg = read_c0_config1();
+diff --git a/arch/mips/mm/tlb-sb1.c b/arch/mips/mm/tlb-sb1.c
+deleted file mode 100644
+--- a/arch/mips/mm/tlb-sb1.c
++++ /dev/null
+@@ -1,376 +0,0 @@
+-/*
+- * Copyright (C) 1996 David S. Miller (dm at engr.sgi.com)
+- * Copyright (C) 1997, 2001 Ralf Baechle (ralf at gnu.org)
+- * Copyright (C) 2000, 2001, 2002, 2003 Broadcom 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.
+- */
+-#include <linux/init.h>
+-#include <asm/mmu_context.h>
+-#include <asm/bootinfo.h>
+-#include <asm/cpu.h>
+-
+-extern void build_tlb_refill_handler(void);
+-
+-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+-
+-/* Dump the current entry* and pagemask registers */
+-static inline void dump_cur_tlb_regs(void)
+-{
+-	unsigned int entryhihi, entryhilo, entrylo0hi, entrylo0lo, entrylo1hi;
+-	unsigned int entrylo1lo, pagemask;
+-
+-	__asm__ __volatile__ (
+-		".set push             \n"
+-		".set noreorder        \n"
+-		".set mips64           \n"
+-		".set noat             \n"
+-		"     tlbr             \n"
+-		"     dmfc0  $1, $10   \n"
+-		"     dsrl32 %0, $1, 0 \n"
+-		"     sll    %1, $1, 0 \n"
+-		"     dmfc0  $1, $2    \n"
+-		"     dsrl32 %2, $1, 0 \n"
+-		"     sll    %3, $1, 0 \n"
+-		"     dmfc0  $1, $3    \n"
+-		"     dsrl32 %4, $1, 0 \n"
+-		"     sll    %5, $1, 0 \n"
+-		"     mfc0   %6, $5    \n"
+-		".set pop              \n"
+-		: "=r" (entryhihi), "=r" (entryhilo),
+-		  "=r" (entrylo0hi), "=r" (entrylo0lo),
+-		  "=r" (entrylo1hi), "=r" (entrylo1lo),
+-		  "=r" (pagemask));
+-
+-	printk("%08X%08X %08X%08X %08X%08X %08X",
+-	       entryhihi, entryhilo,
+-	       entrylo0hi, entrylo0lo,
+-	       entrylo1hi, entrylo1lo,
+-	       pagemask);
+-}
+-
+-void sb1_dump_tlb(void)
+-{
+-	unsigned long old_ctx;
+-	unsigned long flags;
+-	int entry;
+-	local_irq_save(flags);
+-	old_ctx = read_c0_entryhi();
+-	printk("Current TLB registers state:\n"
+-	       "      EntryHi       EntryLo0          EntryLo1     PageMask  Index\n"
+-	       "--------------------------------------------------------------------\n");
+-	dump_cur_tlb_regs();
+-	printk(" %08X\n", read_c0_index());
+-	printk("\n\nFull TLB Dump:\n"
+-	       "Idx      EntryHi       EntryLo0          EntryLo1     PageMask\n"
+-	       "--------------------------------------------------------------\n");
+-	for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
+-		write_c0_index(entry);
+-		printk("\n%02i ", entry);
+-		dump_cur_tlb_regs();
+-	}
+-	printk("\n");
+-	write_c0_entryhi(old_ctx);
+-	local_irq_restore(flags);
+-}
+-
+-void local_flush_tlb_all(void)
+-{
+-	unsigned long flags;
+-	unsigned long old_ctx;
+-	int entry;
+-
+-	local_irq_save(flags);
+-	/* Save old context and create impossible VPN2 value */
+-	old_ctx = read_c0_entryhi() & ASID_MASK;
+-	write_c0_entrylo0(0);
+-	write_c0_entrylo1(0);
+-
+-	entry = read_c0_wired();
+-	while (entry < current_cpu_data.tlbsize) {
+-		write_c0_entryhi(UNIQUE_ENTRYHI(entry));
+-		write_c0_index(entry);
+-		tlb_write_indexed();
+-		entry++;
+-	}
+-	write_c0_entryhi(old_ctx);
+-	local_irq_restore(flags);
+-}
+-
+-
+-/*
+- * Use a bogus region of memory (starting at 0) to sanitize the TLB's.
+- * Use increments of the maximum page size (16MB), and check for duplicate
+- * entries before doing a given write.  Then, when we're safe from collisions
+- * with the firmware, go back and give all the entries invalid addresses with
+- * the normal flush routine.  Wired entries will be killed as well!
+- */
+-static void __init sb1_sanitize_tlb(void)
+-{
+-	int entry;
+-	long addr = 0;
+-
+-	long inc = 1<<24;  /* 16MB */
+-	/* Save old context and create impossible VPN2 value */
+-	write_c0_entrylo0(0);
+-	write_c0_entrylo1(0);
+-	for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
+-		do {
+-			addr += inc;
+-			write_c0_entryhi(addr);
+-			tlb_probe();
+-		} while ((int)(read_c0_index()) >= 0);
+-		write_c0_index(entry);
+-		tlb_write_indexed();
+-	}
+-	/* Now that we know we're safe from collisions, we can safely flush
+-	   the TLB with the "normal" routine. */
+-	local_flush_tlb_all();
+-}
+-
+-void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+-	unsigned long end)
+-{
+-	struct mm_struct *mm = vma->vm_mm;
+-	unsigned long flags;
+-	int cpu;
+-
+-	local_irq_save(flags);
+-	cpu = smp_processor_id();
+-	if (cpu_context(cpu, mm) != 0) {
+-		int size;
+-		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+-		size = (size + 1) >> 1;
+-		if (size <= (current_cpu_data.tlbsize/2)) {
+-			int oldpid = read_c0_entryhi() & ASID_MASK;
+-			int newpid = cpu_asid(cpu, mm);
+-
+-			start &= (PAGE_MASK << 1);
+-			end += ((PAGE_SIZE << 1) - 1);
+-			end &= (PAGE_MASK << 1);
+-			while (start < end) {
+-				int idx;
+-
+-				write_c0_entryhi(start | newpid);
+-				start += (PAGE_SIZE << 1);
+-				tlb_probe();
+-				idx = read_c0_index();
+-				write_c0_entrylo0(0);
+-				write_c0_entrylo1(0);
+-				write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+-				if (idx < 0)
+-					continue;
+-				tlb_write_indexed();
+-			}
+-			write_c0_entryhi(oldpid);
+-		} else {
+-			drop_mmu_context(mm, cpu);
+-		}
+-	}
+-	local_irq_restore(flags);
+-}
+-
+-void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+-{
+-	unsigned long flags;
+-	int size;
+-
+-	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+-	size = (size + 1) >> 1;
+-
+-	local_irq_save(flags);
+-	if (size <= (current_cpu_data.tlbsize/2)) {
+-		int pid = read_c0_entryhi();
+-
+-		start &= (PAGE_MASK << 1);
+-		end += ((PAGE_SIZE << 1) - 1);
+-		end &= (PAGE_MASK << 1);
+-
+-		while (start < end) {
+-			int idx;
+-
+-			write_c0_entryhi(start);
+-			start += (PAGE_SIZE << 1);
+-			tlb_probe();
+-			idx = read_c0_index();
+-			write_c0_entrylo0(0);
+-			write_c0_entrylo1(0);
+-			write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+-			if (idx < 0)
+-				continue;
+-			tlb_write_indexed();
+-		}
+-		write_c0_entryhi(pid);
+-	} else {
+-		local_flush_tlb_all();
+-	}
+-	local_irq_restore(flags);
+-}
+-
+-void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+-{
+-	unsigned long flags;
+-	int cpu = smp_processor_id();
+-
+-	local_irq_save(flags);
+-	if (cpu_context(cpu, vma->vm_mm) != 0) {
+-		int oldpid, newpid, idx;
+-		newpid = cpu_asid(cpu, vma->vm_mm);
+-		page &= (PAGE_MASK << 1);
+-		oldpid = read_c0_entryhi() & ASID_MASK;
+-		write_c0_entryhi(page | newpid);
+-		tlb_probe();
+-		idx = read_c0_index();
+-		write_c0_entrylo0(0);
+-		write_c0_entrylo1(0);
+-		if (idx < 0)
+-			goto finish;
+-		/* Make sure all entries differ. */
+-		write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+-		tlb_write_indexed();
+-	finish:
+-		write_c0_entryhi(oldpid);
+-	}
+-	local_irq_restore(flags);
+-}
+-
+-/*
+- * Remove one kernel space TLB entry.  This entry is assumed to be marked
+- * global so we don't do the ASID thing.
+- */
+-void local_flush_tlb_one(unsigned long page)
+-{
+-	unsigned long flags;
+-	int oldpid, idx;
+-
+-	page &= (PAGE_MASK << 1);
+-	oldpid = read_c0_entryhi() & ASID_MASK;
+-
+-	local_irq_save(flags);
+-	write_c0_entryhi(page);
+-	tlb_probe();
+-	idx = read_c0_index();
+-	if (idx >= 0) {
+-		/* Make sure all entries differ. */
+-		write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+-		write_c0_entrylo0(0);
+-		write_c0_entrylo1(0);
+-		tlb_write_indexed();
+-	}
+-
+-	write_c0_entryhi(oldpid);
+-	local_irq_restore(flags);
+-}
+-
+-/* All entries common to a mm share an asid.  To effectively flush
+-   these entries, we just bump the asid. */
+-void local_flush_tlb_mm(struct mm_struct *mm)
+-{
+-	int cpu;
+-
+-	preempt_disable();
+-
+-	cpu = smp_processor_id();
+-
+-	if (cpu_context(cpu, mm) != 0) {
+-		drop_mmu_context(mm, cpu);
+-	}
+-
+-	preempt_enable();
+-}
+-
+-/* Stolen from mips32 routines */
+-
+-void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+-{
+-	unsigned long flags;
+-	pgd_t *pgdp;
+-	pmd_t *pmdp;
+-	pte_t *ptep;
+-	int idx, pid;
+-
+-	/*
+-	 * Handle debugger faulting in for debugee.
+-	 */
+-	if (current->active_mm != vma->vm_mm)
+-		return;
+-
+-	local_irq_save(flags);
+-
+-	pid = read_c0_entryhi() & ASID_MASK;
+-	address &= (PAGE_MASK << 1);
+-	write_c0_entryhi(address | (pid));
+-	pgdp = pgd_offset(vma->vm_mm, address);
+-	tlb_probe();
+-	pmdp = pmd_offset(pgdp, address);
+-	idx = read_c0_index();
+-	ptep = pte_offset_map(pmdp, address);
+-	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+-	write_c0_entrylo1(pte_val(*ptep) >> 6);
+-	if (idx < 0) {
+-		tlb_write_random();
+-	} else {
+-		tlb_write_indexed();
+-	}
+-	local_irq_restore(flags);
+-}
+-
+-void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+-	unsigned long entryhi, unsigned long pagemask)
+-{
+-	unsigned long flags;
+-	unsigned long wired;
+-	unsigned long old_pagemask;
+-	unsigned long old_ctx;
+-
+-	local_irq_save(flags);
+-	old_ctx = read_c0_entryhi() & 0xff;
+-	old_pagemask = read_c0_pagemask();
+-	wired = read_c0_wired();
+-	write_c0_wired(wired + 1);
+-	write_c0_index(wired);
+-
+-	write_c0_pagemask(pagemask);
+-	write_c0_entryhi(entryhi);
+-	write_c0_entrylo0(entrylo0);
+-	write_c0_entrylo1(entrylo1);
+-	tlb_write_indexed();
+-
+-	write_c0_entryhi(old_ctx);
+-	write_c0_pagemask(old_pagemask);
+-
+-	local_flush_tlb_all();
+-	local_irq_restore(flags);
+-}
+-
+-/*
+- * This is called from loadmmu.c.  We have to set up all the
+- * memory management function pointers, as well as initialize
+- * the caches and tlbs
+- */
+-void tlb_init(void)
+-{
+-	write_c0_pagemask(PM_DEFAULT_MASK);
+-	write_c0_wired(0);
+-
+-	/*
+-	 * We don't know what state the firmware left the TLB's in, so this is
+-	 * the ultra-conservative way to flush the TLB's and avoid machine
+-	 * check exceptions due to duplicate TLB entries
+-	 */
+-	sb1_sanitize_tlb();
+-
+-	build_tlb_refill_handler();
+-}
+diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
+--- a/arch/mips/mm/tlbex.c
++++ b/arch/mips/mm/tlbex.c
+@@ -6,6 +6,7 @@
+  * Synthesize TLB refill handlers at runtime.
+  *
+  * Copyright (C) 2004,2005 by Thiemo Seufer
++ * Copyright (C) 2005  Maciej W. Rozycki
+  */
+ 
+ #include <stdarg.h>
+@@ -91,7 +92,7 @@ enum opcode {
+ 	insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
+ 	insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
+ 	insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
+-	insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
++	insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
+ 	insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
+ 	insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
+ 	insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
+@@ -134,7 +135,6 @@ static __initdata struct insn insn_table
+ 	{ insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
+ 	{ insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
+ 	{ insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE },
+-	{ insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE },
+ 	{ insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD },
+ 	{ insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 },
+ 	{ insn_j, M(j_op,0,0,0,0,0), JIMM },
+@@ -366,7 +366,6 @@ I_u2u1u3(_dsll);
+ I_u2u1u3(_dsll32);
+ I_u2u1u3(_dsra);
+ I_u2u1u3(_dsrl);
+-I_u2u1u3(_dsrl32);
+ I_u3u1u2(_dsubu);
+ I_0(_eret);
+ I_u1(_j);
+@@ -412,7 +411,6 @@ enum label_id {
+ 	label_nopage_tlbm,
+ 	label_smp_pgtable_change,
+ 	label_r3000_write_probe_fail,
+-	label_r3000_write_probe_ok
+ };
+ 
+ struct label {
+@@ -445,7 +443,6 @@ L_LA(_nopage_tlbs)
+ L_LA(_nopage_tlbm)
+ L_LA(_smp_pgtable_change)
+ L_LA(_r3000_write_probe_fail)
+-L_LA(_r3000_write_probe_ok)
+ 
+ /* convenience macros for instructions */
+ #ifdef CONFIG_64BIT
+@@ -490,7 +487,7 @@ L_LA(_r3000_write_probe_ok)
+ static __init int __attribute__((unused)) in_compat_space_p(long addr)
+ {
+ 	/* Is this address in 32bit compat space? */
+-	return (((addr) & 0xffffffff00000000) == 0xffffffff00000000);
++	return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
+ }
+ 
+ static __init int __attribute__((unused)) rel_highest(long val)
+@@ -734,7 +731,7 @@ static void __init build_r3000_tlb_refil
+ 	if (p > tlb_handler + 32)
+ 		panic("TLB refill handler space exceeded");
+ 
+-	printk("Synthesized TLB handler (%u instructions).\n",
++	printk("Synthesized TLB refill handler (%u instructions).\n",
+ 	       (unsigned int)(p - tlb_handler));
+ #ifdef DEBUG_TLB
+ 	{
+@@ -746,7 +743,6 @@ static void __init build_r3000_tlb_refil
+ #endif
+ 
+ 	memcpy((void *)CAC_BASE, tlb_handler, 0x80);
+-	flush_icache_range(CAC_BASE, CAC_BASE + 0x80);
+ }
+ 
+ /*
+@@ -783,6 +779,8 @@ static __initdata u32 final_handler[64];
+ static __init void __attribute__((unused)) build_tlb_probe_entry(u32 **p)
+ {
+ 	switch (current_cpu_data.cputype) {
++	/* Found by experiment: R4600 v2.0 needs this, too.  */
++	case CPU_R4600:
+ 	case CPU_R5000:
+ 	case CPU_R5000A:
+ 	case CPU_NEVADA:
+@@ -834,12 +832,20 @@ static __init void build_tlb_write_entry
+ 	case CPU_R4700:
+ 	case CPU_R5000:
+ 	case CPU_R5000A:
++		i_nop(p);
++		tlbw(p);
++		i_nop(p);
++		break;
++
++	case CPU_R4300:
+ 	case CPU_5KC:
+ 	case CPU_TX49XX:
+ 	case CPU_AU1000:
+ 	case CPU_AU1100:
+ 	case CPU_AU1500:
+ 	case CPU_AU1550:
++	case CPU_AU1200:
++	case CPU_PR4450:
+ 		i_nop(p);
+ 		tlbw(p);
+ 		break;
+@@ -848,6 +854,7 @@ static __init void build_tlb_write_entry
+ 	case CPU_R12000:
+ 	case CPU_4KC:
+ 	case CPU_SB1:
++	case CPU_SB1A:
+ 	case CPU_4KSC:
+ 	case CPU_20KC:
+ 	case CPU_25KF:
+@@ -875,6 +882,7 @@ static __init void build_tlb_write_entry
+ 
+ 	case CPU_4KEC:
+ 	case CPU_24K:
++	case CPU_34K:
+ 		i_ehb(p);
+ 		tlbw(p);
+ 		break;
+@@ -911,6 +919,7 @@ static __init void build_tlb_write_entry
+ 
+ 	case CPU_VR4131:
+ 	case CPU_VR4133:
++	case CPU_R5432:
+ 		i_nop(p);
+ 		i_nop(p);
+ 		tlbw(p);
+@@ -942,34 +951,29 @@ build_get_pmde64(u32 **p, struct label *
+ 	/* No i_nop needed here, since the next insn doesn't touch TMP. */
+ 
+ #ifdef CONFIG_SMP
++# ifdef CONFIG_BUILD_ELF64
+ 	/*
+-	 * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()]
++	 * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
+ 	 * stored in CONTEXT.
+ 	 */
+-	if (in_compat_space_p(pgdc)) {
+-		i_dmfc0(p, ptr, C0_CONTEXT);
+-		i_dsra(p, ptr, ptr, 23);
+-		i_ld(p, ptr, 0, ptr);
+-	} else {
+-#ifdef CONFIG_BUILD_ELF64
+-		i_dmfc0(p, ptr, C0_CONTEXT);
+-		i_dsrl(p, ptr, ptr, 23);
+-		i_dsll(p, ptr, ptr, 3);
+-		i_LA_mostly(p, tmp, pgdc);
+-		i_daddu(p, ptr, ptr, tmp);
+-		i_dmfc0(p, tmp, C0_BADVADDR);
+-		i_ld(p, ptr, rel_lo(pgdc), ptr);
+-#else
+-		i_dmfc0(p, ptr, C0_CONTEXT);
+-		i_lui(p, tmp, rel_highest(pgdc));
+-		i_dsll(p, ptr, ptr, 9);
+-		i_daddiu(p, tmp, tmp, rel_higher(pgdc));
+-		i_dsrl32(p, ptr, ptr, 0);
+-		i_and(p, ptr, ptr, tmp);
+-		i_dmfc0(p, tmp, C0_BADVADDR);
+-		i_ld(p, ptr, 0, ptr);
+-#endif
+-	}
++	i_dmfc0(p, ptr, C0_CONTEXT);
++	i_dsrl(p, ptr, ptr, 23);
++	i_LA_mostly(p, tmp, pgdc);
++	i_daddu(p, ptr, ptr, tmp);
++	i_dmfc0(p, tmp, C0_BADVADDR);
++	i_ld(p, ptr, rel_lo(pgdc), ptr);
++# else
++	/*
++	 * 64 bit SMP running in compat space has the lower part of
++	 * &pgd_current[smp_processor_id()] stored in CONTEXT.
++	 */
++	if (!in_compat_space_p(pgdc))
++		panic("Invalid page directory address!");
++
++	i_dmfc0(p, ptr, C0_CONTEXT);
++	i_dsra(p, ptr, ptr, 23);
++	i_ld(p, ptr, 0, ptr);
++# endif
+ #else
+ 	i_LA_mostly(p, ptr, pgdc);
+ 	i_ld(p, ptr, rel_lo(pgdc), ptr);
+@@ -1026,7 +1030,6 @@ build_get_pgde32(u32 **p, unsigned int t
+ 	i_mfc0(p, ptr, C0_CONTEXT);
+ 	i_LA_mostly(p, tmp, pgdc);
+ 	i_srl(p, ptr, ptr, 23);
+-	i_sll(p, ptr, ptr, 2);
+ 	i_addu(p, ptr, tmp, ptr);
+ #else
+ 	i_LA_mostly(p, ptr, pgdc);
+@@ -1245,13 +1248,19 @@ static void __init build_r4000_tlb_refil
+ 	{
+ 		int i;
+ 
+-		for (i = 0; i < 64; i++)
+-			printk("%08x\n", final_handler[i]);
++		f = final_handler;
++#ifdef CONFIG_64BIT
++		if (final_len > 32)
++			final_len = 64;
++		else
++			f = final_handler + 32;
++#endif /* CONFIG_64BIT */
++		for (i = 0; i < final_len; i++)
++			printk("%08x\n", f[i]);
+ 	}
+ #endif
+ 
+ 	memcpy((void *)CAC_BASE, final_handler, 0x100);
+-	flush_icache_range(CAC_BASE, CAC_BASE + 0x100);
+ }
+ 
+ /*
+@@ -1277,37 +1286,41 @@ u32 __tlb_handler_align handle_tlbs[FAST
+ u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE];
+ 
+ static void __init
+-iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset,
+-	unsigned int ptr)
++iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr)
+ {
+ #ifdef CONFIG_SMP
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+ 	if (cpu_has_64bits)
+-		i_lld(p, pte, offset, ptr);
++		i_lld(p, pte, 0, ptr);
+ 	else
+ # endif
+-		i_LL(p, pte, offset, ptr);
++		i_LL(p, pte, 0, ptr);
+ #else
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+ 	if (cpu_has_64bits)
+-		i_ld(p, pte, offset, ptr);
++		i_ld(p, pte, 0, ptr);
+ 	else
+ # endif
+-		i_LW(p, pte, offset, ptr);
++		i_LW(p, pte, 0, ptr);
+ #endif
+ }
+ 
+ static void __init
+-iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
+-	unsigned int ptr)
++iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, unsigned int ptr,
++	unsigned int mode)
+ {
++#ifdef CONFIG_64BIT_PHYS_ADDR
++	unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
++#endif
++
++	i_ori(p, pte, pte, mode);
+ #ifdef CONFIG_SMP
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+ 	if (cpu_has_64bits)
+-		i_scd(p, pte, offset, ptr);
++		i_scd(p, pte, 0, ptr);
+ 	else
+ # endif
+-		i_SC(p, pte, offset, ptr);
++		i_SC(p, pte, 0, ptr);
+ 
+ 	if (r10000_llsc_war())
+ 		il_beqzl(p, r, pte, label_smp_pgtable_change);
+@@ -1318,7 +1331,7 @@ iPTE_SW(u32 **p, struct reloc **r, unsig
+ 	if (!cpu_has_64bits) {
+ 		/* no i_nop needed */
+ 		i_ll(p, pte, sizeof(pte_t) / 2, ptr);
+-		i_ori(p, pte, pte, _PAGE_VALID);
++		i_ori(p, pte, pte, hwmode);
+ 		i_sc(p, pte, sizeof(pte_t) / 2, ptr);
+ 		il_beqz(p, r, pte, label_smp_pgtable_change);
+ 		/* no i_nop needed */
+@@ -1331,15 +1344,15 @@ iPTE_SW(u32 **p, struct reloc **r, unsig
+ #else
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+ 	if (cpu_has_64bits)
+-		i_sd(p, pte, offset, ptr);
++		i_sd(p, pte, 0, ptr);
+ 	else
+ # endif
+-		i_SW(p, pte, offset, ptr);
++		i_SW(p, pte, 0, ptr);
+ 
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+ 	if (!cpu_has_64bits) {
+ 		i_lw(p, pte, sizeof(pte_t) / 2, ptr);
+-		i_ori(p, pte, pte, _PAGE_VALID);
++		i_ori(p, pte, pte, hwmode);
+ 		i_sw(p, pte, sizeof(pte_t) / 2, ptr);
+ 		i_lw(p, pte, 0, ptr);
+ 	}
+@@ -1359,7 +1372,7 @@ build_pte_present(u32 **p, struct label 
+ 	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+ 	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+ 	il_bnez(p, r, pte, lid);
+-	iPTE_LW(p, l, pte, 0, ptr);
++	iPTE_LW(p, l, pte, ptr);
+ }
+ 
+ /* Make PTE valid, store result in PTR. */
+@@ -1367,8 +1380,9 @@ static void __init
+ build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
+ 		 unsigned int ptr)
+ {
+-	i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED);
+-	iPTE_SW(p, r, pte, 0, ptr);
++	unsigned int mode = _PAGE_VALID | _PAGE_ACCESSED;
++
++	iPTE_SW(p, r, pte, ptr, mode);
+ }
+ 
+ /*
+@@ -1382,7 +1396,7 @@ build_pte_writable(u32 **p, struct label
+ 	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ 	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ 	il_bnez(p, r, pte, lid);
+-	iPTE_LW(p, l, pte, 0, ptr);
++	iPTE_LW(p, l, pte, ptr);
+ }
+ 
+ /* Make PTE writable, update software status bits as well, then store
+@@ -1392,9 +1406,10 @@ static void __init
+ build_make_write(u32 **p, struct reloc **r, unsigned int pte,
+ 		 unsigned int ptr)
+ {
+-	i_ori(p, pte, pte,
+-	      _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
+-	iPTE_SW(p, r, pte, 0, ptr);
++	unsigned int mode = (_PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID
++			     | _PAGE_DIRTY);
++
++	iPTE_SW(p, r, pte, ptr, mode);
+ }
+ 
+ /*
+@@ -1407,41 +1422,48 @@ build_pte_modifiable(u32 **p, struct lab
+ {
+ 	i_andi(p, pte, pte, _PAGE_WRITE);
+ 	il_beqz(p, r, pte, lid);
+-	iPTE_LW(p, l, pte, 0, ptr);
++	iPTE_LW(p, l, pte, ptr);
+ }
+ 
+ /*
+  * R3000 style TLB load/store/modify handlers.
+  */
+ 
+-/* This places the pte in the page table at PTR into ENTRYLO0. */
++/*
++ * This places the pte into ENTRYLO0 and writes it with tlbwi.
++ * Then it returns.
++ */
+ static void __init
+-build_r3000_pte_reload(u32 **p, unsigned int ptr)
++build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp)
+ {
+-	i_lw(p, ptr, 0, ptr);
+-	i_nop(p); /* load delay */
+-	i_mtc0(p, ptr, C0_ENTRYLO0);
+-	i_nop(p); /* cp0 delay */
++	i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
++	i_mfc0(p, tmp, C0_EPC); /* cp0 delay */
++	i_tlbwi(p);
++	i_jr(p, tmp);
++	i_rfe(p); /* branch delay */
+ }
+ 
+ /*
+- * The index register may have the probe fail bit set,
+- * because we would trap on access kseg2, i.e. without refill.
++ * This places the pte into ENTRYLO0 and writes it with tlbwi
++ * or tlbwr as appropriate.  This is because the index register
++ * may have the probe fail bit set as a result of a trap on a
++ * kseg2 access, i.e. without refill.  Then it returns.
+  */
+ static void __init
+-build_r3000_tlb_write(u32 **p, struct label **l, struct reloc **r,
+-		      unsigned int tmp)
++build_r3000_tlb_reload_write(u32 **p, struct label **l, struct reloc **r,
++			     unsigned int pte, unsigned int tmp)
+ {
+ 	i_mfc0(p, tmp, C0_INDEX);
+-	i_nop(p); /* cp0 delay */
+-	il_bltz(p, r, tmp, label_r3000_write_probe_fail);
+-	i_nop(p); /* branch delay */
+-	i_tlbwi(p);
+-	il_b(p, r, label_r3000_write_probe_ok);
+-	i_nop(p); /* branch delay */
++	i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
++	il_bltz(p, r, tmp, label_r3000_write_probe_fail); /* cp0 delay */
++	i_mfc0(p, tmp, C0_EPC); /* branch delay */
++	i_tlbwi(p); /* cp0 delay */
++	i_jr(p, tmp);
++	i_rfe(p); /* branch delay */
+ 	l_r3000_write_probe_fail(l, *p);
+-	i_tlbwr(p);
+-	l_r3000_write_probe_ok(l, *p);
++	i_tlbwr(p); /* cp0 delay */
++	i_jr(p, tmp);
++	i_rfe(p); /* branch delay */
+ }
+ 
+ static void __init
+@@ -1461,17 +1483,7 @@ build_r3000_tlbchange_handler_head(u32 *
+ 	i_andi(p, pte, pte, 0xffc); /* load delay */
+ 	i_addu(p, ptr, ptr, pte);
+ 	i_lw(p, pte, 0, ptr);
+-	i_nop(p); /* load delay */
+-	i_tlbp(p);
+-}
+-
+-static void __init
+-build_r3000_tlbchange_handler_tail(u32 **p, unsigned int tmp)
+-{
+-	i_mfc0(p, tmp, C0_EPC);
+-	i_nop(p); /* cp0 delay */
+-	i_jr(p, tmp);
+-	i_rfe(p); /* branch delay */
++	i_tlbp(p); /* load delay */
+ }
+ 
+ static void __init build_r3000_tlb_load_handler(void)
+@@ -1486,10 +1498,9 @@ static void __init build_r3000_tlb_load_
+ 
+ 	build_r3000_tlbchange_handler_head(&p, K0, K1);
+ 	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
++	i_nop(&p); /* load delay */
+ 	build_make_valid(&p, &r, K0, K1);
+-	build_r3000_pte_reload(&p, K1);
+-	build_r3000_tlb_write(&p, &l, &r, K0);
+-	build_r3000_tlbchange_handler_tail(&p, K0);
++	build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
+ 
+ 	l_nopage_tlbl(&l, p);
+ 	i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+@@ -1506,13 +1517,10 @@ static void __init build_r3000_tlb_load_
+ 	{
+ 		int i;
+ 
+-		for (i = 0; i < FASTPATH_SIZE; i++)
++		for (i = 0; i < (p - handle_tlbl); i++)
+ 			printk("%08x\n", handle_tlbl[i]);
+ 	}
+ #endif
+-
+-	flush_icache_range((unsigned long)handle_tlbl,
+-			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
+ }
+ 
+ static void __init build_r3000_tlb_store_handler(void)
+@@ -1527,10 +1535,9 @@ static void __init build_r3000_tlb_store
+ 
+ 	build_r3000_tlbchange_handler_head(&p, K0, K1);
+ 	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
++	i_nop(&p); /* load delay */
+ 	build_make_write(&p, &r, K0, K1);
+-	build_r3000_pte_reload(&p, K1);
+-	build_r3000_tlb_write(&p, &l, &r, K0);
+-	build_r3000_tlbchange_handler_tail(&p, K0);
++	build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
+ 
+ 	l_nopage_tlbs(&l, p);
+ 	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+@@ -1547,13 +1554,10 @@ static void __init build_r3000_tlb_store
+ 	{
+ 		int i;
+ 
+-		for (i = 0; i < FASTPATH_SIZE; i++)
++		for (i = 0; i < (p - handle_tlbs); i++)
+ 			printk("%08x\n", handle_tlbs[i]);
+ 	}
+ #endif
+-
+-	flush_icache_range((unsigned long)handle_tlbs,
+-			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
+ }
+ 
+ static void __init build_r3000_tlb_modify_handler(void)
+@@ -1568,10 +1572,9 @@ static void __init build_r3000_tlb_modif
+ 
+ 	build_r3000_tlbchange_handler_head(&p, K0, K1);
+ 	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
++	i_nop(&p); /* load delay */
+ 	build_make_write(&p, &r, K0, K1);
+-	build_r3000_pte_reload(&p, K1);
+-	i_tlbwi(&p);
+-	build_r3000_tlbchange_handler_tail(&p, K0);
++	build_r3000_pte_reload_tlbwi(&p, K0, K1);
+ 
+ 	l_nopage_tlbm(&l, p);
+ 	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+@@ -1588,13 +1591,10 @@ static void __init build_r3000_tlb_modif
+ 	{
+ 		int i;
+ 
+-		for (i = 0; i < FASTPATH_SIZE; i++)
++		for (i = 0; i < (p - handle_tlbm); i++)
+ 			printk("%08x\n", handle_tlbm[i]);
+ 	}
+ #endif
+-
+-	flush_icache_range((unsigned long)handle_tlbm,
+-			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
+ }
+ 
+ /*
+@@ -1620,7 +1620,7 @@ build_r4000_tlbchange_handler_head(u32 *
+ #ifdef CONFIG_SMP
+ 	l_smp_pgtable_change(l, *p);
+ # endif
+-	iPTE_LW(p, l, pte, 0, ptr); /* get even pte */
++	iPTE_LW(p, l, pte, ptr); /* get even pte */
+ 	build_tlb_probe_entry(p);
+ }
+ 
+@@ -1680,13 +1680,10 @@ static void __init build_r4000_tlb_load_
+ 	{
+ 		int i;
+ 
+-		for (i = 0; i < FASTPATH_SIZE; i++)
++		for (i = 0; i < (p - handle_tlbl); i++)
+ 			printk("%08x\n", handle_tlbl[i]);
+ 	}
+ #endif
+-
+-	flush_icache_range((unsigned long)handle_tlbl,
+-			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
+ }
+ 
+ static void __init build_r4000_tlb_store_handler(void)
+@@ -1719,13 +1716,10 @@ static void __init build_r4000_tlb_store
+ 	{
+ 		int i;
+ 
+-		for (i = 0; i < FASTPATH_SIZE; i++)
++		for (i = 0; i < (p - handle_tlbs); i++)
+ 			printk("%08x\n", handle_tlbs[i]);
+ 	}
+ #endif
+-
+-	flush_icache_range((unsigned long)handle_tlbs,
+-			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
+ }
+ 
+ static void __init build_r4000_tlb_modify_handler(void)
+@@ -1759,13 +1753,10 @@ static void __init build_r4000_tlb_modif
+ 	{
+ 		int i;
+ 
+-		for (i = 0; i < FASTPATH_SIZE; i++)
++		for (i = 0; i < (p - handle_tlbm); i++)
+ 			printk("%08x\n", handle_tlbm[i]);
+ 	}
+ #endif
+-
+-	flush_icache_range((unsigned long)handle_tlbm,
+-			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
+ }
+ 
+ void __init build_tlb_refill_handler(void)
+@@ -1813,3 +1804,13 @@ void __init build_tlb_refill_handler(voi
+ 		}
+ 	}
+ }
++
++void __init flush_tlb_handlers(void)
++{
++	flush_icache_range((unsigned long)handle_tlbl,
++			   (unsigned long)handle_tlbl + sizeof(handle_tlbl));
++	flush_icache_range((unsigned long)handle_tlbs,
++			   (unsigned long)handle_tlbs + sizeof(handle_tlbs));
++	flush_icache_range((unsigned long)handle_tlbm,
++			   (unsigned long)handle_tlbm + sizeof(handle_tlbm));
++}
+diff --git a/arch/mips/momentum/Kconfig b/arch/mips/momentum/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/momentum/Kconfig
+@@ -0,0 +1,6 @@
++config JAGUAR_DMALOW
++	bool "Low DMA Mode"
++	depends on MOMENCO_JAGUAR_ATX
++	help
++	  Select to Y if jump JP5 is set on your board, N otherwise.  Normally
++	  the jumper is set, so if you feel unsafe, just say Y.
+diff --git a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c
+--- a/arch/mips/momentum/jaguar_atx/prom.c
++++ b/arch/mips/momentum/jaguar_atx/prom.c
+@@ -236,8 +236,9 @@ void __init prom_init(void)
+ #endif
+ }
+ 
+-void __init prom_free_prom_memory(void)
++unsigned long __init prom_free_prom_memory(void)
+ {
++	return 0;
+ }
+ 
+ void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
+--- a/arch/mips/momentum/jaguar_atx/setup.c
++++ b/arch/mips/momentum/jaguar_atx/setup.c
+@@ -351,7 +351,7 @@ static __init int __init ja_pci_init(voi
+ 
+ arch_initcall(ja_pci_init);
+ 
+-static int  __init momenco_jaguar_atx_setup(void)
++void __init plat_setup(void)
+ {
+ 	unsigned int tmpword;
+ 
+@@ -467,8 +467,4 @@ static int  __init momenco_jaguar_atx_se
+ 
+ 	}
+ #endif
+-
+-	return 0;
+ }
+-
+-early_initcall(momenco_jaguar_atx_setup);
+diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c
+--- a/arch/mips/momentum/ocelot_3/prom.c
++++ b/arch/mips/momentum/ocelot_3/prom.c
+@@ -239,8 +239,9 @@ void __init prom_init(void)
+ #endif
+ }
+ 
+-void __init prom_free_prom_memory(void)
++unsigned long __init prom_free_prom_memory(void)
+ {
++	return 0;
+ }
+ 
+ void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
+--- a/arch/mips/momentum/ocelot_3/setup.c
++++ b/arch/mips/momentum/ocelot_3/setup.c
+@@ -307,7 +307,7 @@ static __init int __init ja_pci_init(voi
+ 
+ arch_initcall(ja_pci_init);
+ 
+-static int __init momenco_ocelot_3_setup(void)
++void __init plat_setup(void)
+ {
+ 	unsigned int tmpword;
+ 
+@@ -391,8 +391,4 @@ static int __init momenco_ocelot_3_setup
+ 
+ 	/* Support for 128 MB memory */
+ 	add_memory_region(0x0, 0x08000000, BOOT_MEM_RAM);
+-
+-	return 0;
+ }
+-
+-early_initcall(momenco_ocelot_3_setup);
+diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c
+--- a/arch/mips/momentum/ocelot_c/cpci-irq.c
++++ b/arch/mips/momentum/ocelot_c/cpci-irq.c
+@@ -129,14 +129,13 @@ void ll_cpci_irq(struct pt_regs *regs)
+ #define shutdown_cpci_irq	disable_cpci_irq
+ 
+ struct hw_interrupt_type cpci_irq_type = {
+-	"CPCI/FPGA",
+-	startup_cpci_irq,
+-	shutdown_cpci_irq,
+-	enable_cpci_irq,
+-	disable_cpci_irq,
+-	mask_and_ack_cpci_irq,
+-	end_cpci_irq,
+-	NULL
++	.typename = "CPCI/FPGA",
++	.startup = startup_cpci_irq,
++	.shutdown = shutdown_cpci_irq,
++	.enable = enable_cpci_irq,
++	.disable = disable_cpci_irq,
++	.ack = mask_and_ack_cpci_irq,
++	.end = end_cpci_irq,
+ };
+ 
+ void cpci_irq_init(void)
+diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
+--- a/arch/mips/momentum/ocelot_c/setup.c
++++ b/arch/mips/momentum/ocelot_c/setup.c
+@@ -222,7 +222,7 @@ void momenco_time_init(void)
+ 	rtc_set_time = m48t37y_set_time;
+ }
+ 
+-static void __init momenco_ocelot_c_setup(void)
++void __init plat_setup(void)
+ {
+ 	unsigned int tmpword;
+ 
+@@ -340,8 +340,6 @@ static void __init momenco_ocelot_c_setu
+ 	}
+ }
+ 
+-early_initcall(momenco_ocelot_c_setup);
+-
+ #ifndef CONFIG_64BIT
+ /* This needs to be one of the first initcalls, because no I/O port access
+    can work before this */
+diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c
+--- a/arch/mips/momentum/ocelot_c/uart-irq.c
++++ b/arch/mips/momentum/ocelot_c/uart-irq.c
+@@ -122,14 +122,13 @@ void ll_uart_irq(struct pt_regs *regs)
+ #define shutdown_uart_irq	disable_uart_irq
+ 
+ struct hw_interrupt_type uart_irq_type = {
+-	"UART/FPGA",
+-	startup_uart_irq,
+-	shutdown_uart_irq,
+-	enable_uart_irq,
+-	disable_uart_irq,
+-	mask_and_ack_uart_irq,
+-	end_uart_irq,
+-	NULL
++	.typename = "UART/FPGA",
++	.startup = startup_uart_irq,
++	.shutdown = shutdown_uart_irq,
++	.enable = enable_uart_irq,
++	.disable = disable_uart_irq,
++	.ack = mask_and_ack_uart_irq,
++	.end = end_uart_irq,
+ };
+ 
+ void uart_irq_init(void)
+diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c
+--- a/arch/mips/momentum/ocelot_g/setup.c
++++ b/arch/mips/momentum/ocelot_g/setup.c
+@@ -160,7 +160,7 @@ static void __init setup_l3cache(unsigne
+ 	printk("Done\n");
+ }
+ 
+-static int  __init momenco_ocelot_g_setup(void)
++void __init plat_setup(void)
+ {
+ 	void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache);
+ 	unsigned int tmpword;
+@@ -240,12 +240,8 @@ static int  __init momenco_ocelot_g_setu
+ 
+ 	/* FIXME: Fix up the DiskOnChip mapping */
+ 	MV_WRITE(0x468, 0xfef73);
+-
+-	return 0;
+ }
+ 
+-early_initcall(momenco_ocelot_g_setup);
+-
+ /* This needs to be one of the first initcalls, because no I/O port access
+    can work before this */
+ 
+diff --git a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
+--- a/arch/mips/oprofile/Kconfig
++++ b/arch/mips/oprofile/Kconfig
+@@ -11,7 +11,7 @@ config PROFILING
+ 
+ config OPROFILE
+ 	tristate "OProfile system profiling (EXPERIMENTAL)"
+-	depends on PROFILING
++	depends on PROFILING && EXPERIMENTAL
+ 	help
+ 	  OProfile is a profiling system capable of profiling the
+ 	  whole system, include the kernel, kernel modules, libraries,
+diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
+--- a/arch/mips/oprofile/common.c
++++ b/arch/mips/oprofile/common.c
+@@ -3,7 +3,8 @@
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
+- * Copyright (C) 2004 by Ralf Baechle
++ * Copyright (C) 2004, 2005 Ralf Baechle
++ * Copyright (C) 2005 MIPS Technologies, Inc.
+  */
+ #include <linux/errno.h>
+ #include <linux/init.h>
+@@ -45,10 +46,10 @@ static int op_mips_create_files(struct s
+ 		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+ 		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+ 		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+-		/* Dummies.  */
+ 		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+ 		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+ 		oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
++		/* Dummy.  */
+ 		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+ 	}
+ 
+@@ -68,9 +69,10 @@ static void op_mips_stop(void)
+ 	on_each_cpu(model->cpu_stop, NULL, 0, 1);
+ }
+ 
+-void __init oprofile_arch_init(struct oprofile_operations *ops)
++int __init oprofile_arch_init(struct oprofile_operations *ops)
+ {
+ 	struct op_mips_model *lmodel = NULL;
++	int res;
+ 
+ 	switch (current_cpu_data.cputype) {
+ 	case CPU_24K:
+@@ -83,21 +85,25 @@ void __init oprofile_arch_init(struct op
+ 	};
+ 
+ 	if (!lmodel)
+-		return;
++		return -ENODEV;
+ 
+-	if (lmodel->init())
+-		return;
++	res = lmodel->init();
++	if (res)
++		return res;
+ 
+ 	model = lmodel;
+ 
+-	ops->create_files = op_mips_create_files;
+-	ops->setup = op_mips_setup;
+-	ops->start = op_mips_start;
+-	ops->stop = op_mips_stop;
+-	ops->cpu_type = lmodel->cpu_type;
++	ops->create_files	= op_mips_create_files;
++	ops->setup		= op_mips_setup;
++	//ops->shutdown         = op_mips_shutdown;
++	ops->start		= op_mips_start;
++	ops->stop		= op_mips_stop;
++	ops->cpu_type		= lmodel->cpu_type;
+ 
+ 	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+ 	       lmodel->cpu_type);
++
++	return 0;
+ }
+ 
+ void oprofile_arch_exit(void)
+diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h
+--- a/arch/mips/oprofile/op_impl.h
++++ b/arch/mips/oprofile/op_impl.h
+@@ -10,6 +10,11 @@
+ #ifndef OP_IMPL_H
+ #define OP_IMPL_H 1
+ 
++struct pt_regs;
++
++extern void null_perf_irq(struct pt_regs *regs);
++extern void (*perf_irq)(struct pt_regs *regs);
++
+ /* Per-counter configuration as set via oprofilefs.  */
+ struct op_counter_config {
+ 	unsigned long enabled;
+diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/oprofile/op_model_mipsxx.c
+@@ -0,0 +1,215 @@
++/*
++ * 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, 2005 by Ralf Baechle
++ * Copyright (C) 2005 by MIPS Technologies, Inc.
++ */
++#include <linux/oprofile.h>
++#include <linux/interrupt.h>
++#include <linux/smp.h>
++
++#include "op_impl.h"
++
++#define M_PERFCTL_EXL			(1UL    <<  0)
++#define M_PERFCTL_KERNEL		(1UL    <<  1)
++#define M_PERFCTL_SUPERVISOR		(1UL    <<  2)
++#define M_PERFCTL_USER			(1UL    <<  3)
++#define M_PERFCTL_INTERRUPT_ENABLE	(1UL    <<  4)
++#define M_PERFCTL_EVENT(event)		((event) << 5)
++#define M_PERFCTL_WIDE			(1UL    << 30)
++#define M_PERFCTL_MORE			(1UL    << 31)
++
++#define M_COUNTER_OVERFLOW		(1UL    << 31)
++
++struct op_mips_model op_model_mipsxx;
++
++static struct mipsxx_register_config {
++	unsigned int control[4];
++	unsigned int counter[4];
++} reg;
++
++/* Compute all of the registers in preparation for enabling profiling.  */
++
++static void mipsxx_reg_setup(struct op_counter_config *ctr)
++{
++	unsigned int counters = op_model_mipsxx.num_counters;
++	int i;
++
++	/* Compute the performance counter control word.  */
++	/* For now count kernel and user mode */
++	for (i = 0; i < counters; i++) {
++		reg.control[i] = 0;
++		reg.counter[i] = 0;
++
++		if (!ctr[i].enabled)
++			continue;
++
++		reg.control[i] = M_PERFCTL_EVENT(ctr[i].event) |
++		                 M_PERFCTL_INTERRUPT_ENABLE;
++		if (ctr[i].kernel)
++			reg.control[i] |= M_PERFCTL_KERNEL;
++		if (ctr[i].user)
++			reg.control[i] |= M_PERFCTL_USER;
++		if (ctr[i].exl)
++			reg.control[i] |= M_PERFCTL_EXL;
++		reg.counter[i] = 0x80000000 - ctr[i].count;
++	}
++}
++
++/* Program all of the registers in preparation for enabling profiling.  */
++
++static void mipsxx_cpu_setup (void *args)
++{
++	unsigned int counters = op_model_mipsxx.num_counters;
++
++	switch (counters) {
++	case 4:
++		write_c0_perfctrl3(0);
++		write_c0_perfcntr3(reg.counter[3]);
++	case 3:
++		write_c0_perfctrl2(0);
++		write_c0_perfcntr2(reg.counter[2]);
++	case 2:
++		write_c0_perfctrl1(0);
++		write_c0_perfcntr1(reg.counter[1]);
++	case 1:
++		write_c0_perfctrl0(0);
++		write_c0_perfcntr0(reg.counter[0]);
++	}
++}
++
++/* Start all counters on current CPU */
++static void mipsxx_cpu_start(void *args)
++{
++	unsigned int counters = op_model_mipsxx.num_counters;
++
++	switch (counters) {
++	case 4:
++		write_c0_perfctrl3(reg.control[3]);
++	case 3:
++		write_c0_perfctrl2(reg.control[2]);
++	case 2:
++		write_c0_perfctrl1(reg.control[1]);
++	case 1:
++		write_c0_perfctrl0(reg.control[0]);
++	}
++}
++
++/* Stop all counters on current CPU */
++static void mipsxx_cpu_stop(void *args)
++{
++	unsigned int counters = op_model_mipsxx.num_counters;
++
++	switch (counters) {
++	case 4:
++		write_c0_perfctrl3(0);
++	case 3:
++		write_c0_perfctrl2(0);
++	case 2:
++		write_c0_perfctrl1(0);
++	case 1:
++		write_c0_perfctrl0(0);
++	}
++}
++
++static void mipsxx_perfcount_handler(struct pt_regs *regs)
++{
++	unsigned int counters = op_model_mipsxx.num_counters;
++	unsigned int control;
++	unsigned int counter;
++
++	switch (counters) {
++#define HANDLE_COUNTER(n)						\
++	case n + 1:							\
++		control = read_c0_perfctrl ## n();			\
++		counter = read_c0_perfcntr ## n();			\
++		if ((control & M_PERFCTL_INTERRUPT_ENABLE) &&		\
++		    (counter & M_COUNTER_OVERFLOW)) {			\
++			oprofile_add_sample(regs, n);			\
++			write_c0_perfcntr ## n(reg.counter[n]);		\
++		}
++	HANDLE_COUNTER(3)
++	HANDLE_COUNTER(2)
++	HANDLE_COUNTER(1)
++	HANDLE_COUNTER(0)
++	}
++}
++
++#define M_CONFIG1_PC	(1 << 4)
++
++static inline int n_counters(void)
++{
++	if (!(read_c0_config1() & M_CONFIG1_PC))
++		return 0;
++	if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
++		return 1;
++	if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
++		return 2;
++	if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
++		return 3;
++
++	return 4;
++}
++
++static inline void reset_counters(int counters)
++{
++	switch (counters) {
++	case 4:
++		write_c0_perfctrl3(0);
++		write_c0_perfcntr3(0);
++	case 3:
++		write_c0_perfctrl2(0);
++		write_c0_perfcntr2(0);
++	case 2:
++		write_c0_perfctrl1(0);
++		write_c0_perfcntr1(0);
++	case 1:
++		write_c0_perfctrl0(0);
++		write_c0_perfcntr0(0);
++	}
++}
++
++static int __init mipsxx_init(void)
++{
++	int counters;
++
++	counters = n_counters();
++	if (counters == 0)
++		return -ENODEV;
++
++	reset_counters(counters);
++
++	op_model_mipsxx.num_counters = counters;
++	switch (current_cpu_data.cputype) {
++	case CPU_24K:
++		op_model_mipsxx.cpu_type = "mips/24K";
++		break;
++
++	default:
++		printk(KERN_ERR "Profiling unsupported for this CPU\n");
++
++		return -ENODEV;
++	}
++
++	perf_irq = mipsxx_perfcount_handler;
++
++	return 0;
++}
++
++static void mipsxx_exit(void)
++{
++	reset_counters(op_model_mipsxx.num_counters);
++
++	perf_irq = null_perf_irq;
++}
++
++struct op_mips_model op_model_mipsxx = {
++	.reg_setup	= mipsxx_reg_setup,
++	.cpu_setup	= mipsxx_cpu_setup,
++	.init		= mipsxx_init,
++	.exit		= mipsxx_exit,
++	.cpu_start	= mipsxx_cpu_start,
++	.cpu_stop	= mipsxx_cpu_stop,
++};
+diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c
+--- a/arch/mips/oprofile/op_model_rm9000.c
++++ b/arch/mips/oprofile/op_model_rm9000.c
+@@ -5,6 +5,7 @@
+  *
+  * Copyright (C) 2004 by Ralf Baechle
+  */
++#include <linux/init.h>
+ #include <linux/oprofile.h>
+ #include <linux/interrupt.h>
+ #include <linux/smp.h>
+@@ -114,7 +115,7 @@ static irqreturn_t rm9000_perfcount_hand
+ 	return IRQ_HANDLED;
+ }
+ 
+-static int rm9000_init(void)
++static int __init rm9000_init(void)
+ {
+ 	return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
+ 	                   0, "Perfcounter", NULL);
+diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
+--- a/arch/mips/pci/Makefile
++++ b/arch/mips/pci/Makefile
+@@ -34,6 +34,7 @@ obj-$(CONFIG_MIPS_ITE8172)	+= fixup-ite8
+ obj-$(CONFIG_MIPS_IVR)		+= fixup-ivr.o
+ obj-$(CONFIG_SOC_AU1500)	+= fixup-au1000.o ops-au1000.o
+ obj-$(CONFIG_SOC_AU1550)	+= fixup-au1000.o ops-au1000.o
++obj-$(CONFIG_SOC_PNX8550)	+= fixup-pnx8550.o ops-pnx8550.o
+ obj-$(CONFIG_MIPS_MALTA)	+= fixup-malta.o
+ obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o
+ obj-$(CONFIG_MOMENCO_OCELOT)	+= fixup-ocelot.o pci-ocelot.o
+@@ -45,11 +46,13 @@ obj-$(CONFIG_PMC_YOSEMITE)	+= fixup-yose
+ obj-$(CONFIG_SGI_IP27)		+= pci-ip27.o
+ obj-$(CONFIG_SGI_IP32)		+= fixup-ip32.o ops-mace.o pci-ip32.o
+ obj-$(CONFIG_SIBYTE_SB1250)	+= fixup-sb1250.o pci-sb1250.o
++obj-$(CONFIG_SIBYTE_BCM1x80)	+= pci-bcm1480.o pci-bcm1480ht.o
+ obj-$(CONFIG_SNI_RM200_PCI)	+= fixup-sni.o ops-sni.o
+ obj-$(CONFIG_TANBAC_TB0219)	+= fixup-tb0219.o
+ obj-$(CONFIG_TANBAC_TB0226)	+= fixup-tb0226.o
+ obj-$(CONFIG_TANBAC_TB0287)	+= fixup-tb0287.o
+ obj-$(CONFIG_TOSHIBA_JMR3927)	+= fixup-jmr3927.o pci-jmr3927.o
+ obj-$(CONFIG_TOSHIBA_RBTX4927)	+= fixup-rbtx4927.o ops-tx4927.o
++obj-$(CONFIG_TOSHIBA_RBTX4938)	+= fixup-tx4938.o ops-tx4938.o
+ obj-$(CONFIG_VICTOR_MPC30X)	+= fixup-mpc30x.o
+ obj-$(CONFIG_ZAO_CAPCELLA)	+= fixup-capcella.o
+diff --git a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c
+--- a/arch/mips/pci/fixup-atlas.c
++++ b/arch/mips/pci/fixup-atlas.c
+@@ -1,14 +1,37 @@
++/*
++ * Copyright (C) 2003, 2004  Ralf Baechle (ralf at linux-mips.org)
++ * Copyright (C) 2005  MIPS Technologies, Inc.  All rights reserved.
++ *	Author:	 Maciej W. Rozycki <macro at mips.com>
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/config.h>
+ #include <linux/init.h>
+ #include <linux/pci.h>
++
+ #include <asm/mips-boards/atlasint.h>
+ 
+-#define INTD		ATLASINT_INTD
+-#define INTC		ATLASINT_INTC
+-#define INTB		ATLASINT_INTB
++#define PCIA		ATLASINT_PCIA
++#define PCIB		ATLASINT_PCIB
++#define PCIC		ATLASINT_PCIC
++#define PCID		ATLASINT_PCID
+ #define INTA		ATLASINT_INTA
+-#define SCSI		ATLASINT_SCSI
++#define INTB		ATLASINT_INTB
+ #define ETH		ATLASINT_ETH
++#define INTC		ATLASINT_INTC
++#define SCSI		ATLASINT_SCSI
++#define INTD		ATLASINT_INTD
+ 
+ static char irq_tab[][5] __initdata = {
+ 	/*      INTA    INTB    INTC    INTD */
+@@ -27,13 +50,13 @@ static char irq_tab[][5] __initdata = {
+ 	{0,	0,	0,	0,	0 },	/* 12: Unused */
+ 	{0,	0,	0,	0,	0 },	/* 13: Unused */
+ 	{0,	0,	0,	0,	0 },	/* 14: Unused */
+-	{0,	0,	0,	0,	0 },	/* 15: Unused */
++	{0,	PCIA,	PCIB,	PCIC,	PCID },	/* 15: cPCI (behind 21150) */
+ 	{0,	SCSI,	0,	0,	0 },	/* 16: SYM53C810A SCSI */
+ 	{0,	0,	0,	0,	0 },	/* 17: Core */
+-	{0,	INTA,	INTB,	INTC,	INTD },	/* 18: PCI Slot 1 */
+-	{0,	ETH,	0,	0,	0 },	/* 19: SAA9730 Ethernet */
+-	{0,	0,	0,	0,	0 },	/* 20: PCI Slot 3 */
+-	{0,	0,	0,	0,	0 }	/* 21: PCI Slot 4 */
++	{0,	INTA,	INTB,	INTC,	INTD },	/* 18: PCI Slot */
++	{0,	ETH,	0,	0,	0 },	/* 19: SAA9730 Eth. et al. */
++	{0,	0,	0,	0,	0 },	/* 20: Unused */
++	{0,	0,	0,	0,	0 }	/* 21: Unused */
+ };
+ 
+ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
+--- a/arch/mips/pci/fixup-au1000.c
++++ b/arch/mips/pci/fixup-au1000.c
+@@ -26,7 +26,6 @@
+  *  with this program; if not, write  to the Free Software Foundation, Inc.,
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+-#include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+@@ -34,82 +33,7 @@
+ 
+ #include <asm/mach-au1x00/au1000.h>
+ 
+-/*
+- * Shortcut
+- */
+-#ifdef CONFIG_SOC_AU1500
+-#define INTA AU1000_PCI_INTA
+-#define INTB AU1000_PCI_INTB
+-#define INTC AU1000_PCI_INTC
+-#define INTD AU1000_PCI_INTD
+-#endif
+-
+-#ifdef CONFIG_SOC_AU1550
+-#define INTA AU1550_PCI_INTA
+-#define INTB AU1550_PCI_INTB
+-#define INTC AU1550_PCI_INTC
+-#define INTD AU1550_PCI_INTD
+-#endif
+-
+-#define INTX    0xFF /* not valid */
+-
+-#ifdef CONFIG_MIPS_DB1500
+-static char irq_tab_alchemy[][5] __initdata = {
+- [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT371   */
+- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+-};
+-#endif
+-
+-#ifdef CONFIG_MIPS_BOSPORUS
+-static char irq_tab_alchemy[][5] __initdata = {
+- [11] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 11 - miniPCI  */
+- [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - SN1741   */
+- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+-};
+-#endif
+-
+-#ifdef CONFIG_MIPS_MIRAGE
+-static char irq_tab_alchemy[][5] __initdata = {
+- [11] =	{ -1, INTD, INTX, INTX, INTX},   /* IDSEL 11 - SMI VGX */
+- [12] =	{ -1, INTX, INTX, INTC, INTX},   /* IDSEL 12 - PNX1300 */
+- [13] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 13 - miniPCI */
+-};
+-#endif
+-
+-#ifdef CONFIG_MIPS_DB1550
+-static char irq_tab_alchemy[][5] __initdata = {
+- [11] =	{ -1, INTC, INTX, INTX, INTX},   /* IDSEL 11 - on-board HPT371    */
+- [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
+- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
+-};
+-#endif
+-
+-#ifdef CONFIG_MIPS_PB1500
+-static char irq_tab_alchemy[][5] __initdata = {
+- [12] = { -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT370   */
+- [13] = { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+-};
+-#endif
+-
+-#ifdef CONFIG_MIPS_PB1550
+-static char irq_tab_alchemy[][5] __initdata = {
+- [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
+- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
+-};
+-#endif
+-
+-#ifdef CONFIG_MIPS_MTX1
+-static char irq_tab_alchemy[][5] __initdata = {
+- [0] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 00 - AdapterA-Slot0 (top)    */
+- [1] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+- [2] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 02 - AdapterB-Slot0 (top)    */
+- [3] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+- [4] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 04 - AdapterC-Slot0 (top)    */
+- [5] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+- [6] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 06 - AdapterD-Slot0 (top)    */
+- [7] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+-};
+-#endif
++extern char irq_tab_alchemy[][5];
+ 
+ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+ {
+diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
+--- a/arch/mips/pci/fixup-cobalt.c
++++ b/arch/mips/pci/fixup-cobalt.c
+@@ -21,6 +21,20 @@
+ 
+ extern int cobalt_board_id;
+ 
++static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
++{
++	if (dev->devfn == PCI_DEVFN(0, 0) &&
++		(dev->class >> 8) == PCI_CLASS_MEMORY_OTHER) {
++
++		dev->class = (PCI_CLASS_BRIDGE_HOST << 8) | (dev->class & 0xff);
++
++		printk(KERN_INFO "Galileo: fixed bridge class\n");
++	}
++}
++
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
++	 qube_raq_galileo_early_fixup);
++
+ static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
+ {
+ 	unsigned short cfgword;
+@@ -48,6 +62,9 @@ static void qube_raq_galileo_fixup(struc
+ {
+ 	unsigned short galileo_id;
+ 
++	if (dev->devfn != PCI_DEVFN(0, 0))
++		return;
++
+ 	/* Fix PCI latency-timer and cache-line-size values in Galileo
+ 	 * host bridge.
+ 	 */
+@@ -55,6 +72,13 @@ static void qube_raq_galileo_fixup(struc
+ 	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+ 
+ 	/*
++	 * The code described by the comment below has been removed
++	 * as it causes bus mastering by the Ethernet controllers
++	 * to break under any kind of network load. We always set
++	 * the retry timeouts to their maximum.
++	 *
++	 * --x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--
++	 *
+ 	 * On all machines prior to Q2, we had the STOP line disconnected
+ 	 * from Galileo to VIA on PCI.  The new Galileo does not function
+ 	 * correctly unless we have it connected.
+@@ -64,21 +88,43 @@ static void qube_raq_galileo_fixup(struc
+ 	 */
+ 	pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id);
+ 	galileo_id &= 0xff;	/* mask off class info */
++
++ 	printk(KERN_INFO "Galileo: revision %u\n", galileo_id);
++
++#if 0
+ 	if (galileo_id >= 0x10) {
+ 		/* New Galileo, assumes PCI stop line to VIA is connected. */
+ 		GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS);
+-	} else if (galileo_id == 0x1 || galileo_id == 0x2) {
++	} else if (galileo_id == 0x1 || galileo_id == 0x2)
++#endif
++	{
+ 		signed int timeo;
+ 		/* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
+ 		timeo = GALILEO_INL(GT_PCI0_TOR_OFS);
+ 		/* Old Galileo, assumes PCI STOP line to VIA is disconnected. */
+-		GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS);
++		GALILEO_OUTL(
++			(0xff << 16) |		/* retry count */
++			(0xff << 8) |		/* timeout 1   */
++			0xff,			/* timeout 0   */
++			GT_PCI0_TOR_OFS);
++
++		/* enable PCI retry exceeded interrupt */
++		GALILEO_OUTL(GALILEO_INTR_RETRY_CTR | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS);
+ 	}
+ }
+ 
+-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_GALILEO, PCI_ANY_ID,
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
+ 	 qube_raq_galileo_fixup);
+ 
++static char irq_tab_qube1[] __initdata = {
++  [COBALT_PCICONF_CPU]     = 0,
++  [COBALT_PCICONF_ETH0]    = COBALT_QUBE1_ETH0_IRQ,
++  [COBALT_PCICONF_RAQSCSI] = COBALT_SCSI_IRQ,
++  [COBALT_PCICONF_VIA]     = 0,
++  [COBALT_PCICONF_PCISLOT] = COBALT_QUBE_SLOT_IRQ,
++  [COBALT_PCICONF_ETH1]    = 0
++};
++
+ static char irq_tab_cobalt[] __initdata = {
+   [COBALT_PCICONF_CPU]     = 0,
+   [COBALT_PCICONF_ETH0]    = COBALT_ETH0_IRQ,
+@@ -99,6 +145,9 @@ static char irq_tab_raq2[] __initdata = 
+ 
+ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+ {
++	if (cobalt_board_id < COBALT_BRD_ID_QUBE2)
++		return irq_tab_qube1[slot];
++
+ 	if (cobalt_board_id == COBALT_BRD_ID_RAQ2)
+ 		return irq_tab_raq2[slot];
+ 
+diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/pci/fixup-pnx8550.c
+@@ -0,0 +1,57 @@
++/*
++ *  Philips PNX8550 pci fixups.
++ *
++ *  Copyright 2005 Embedded Alley Solutions, Inc
++ *  source at embeddealley.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++
++#include <asm/mach-pnx8550/pci.h>
++#include <asm/mach-pnx8550/int.h>
++
++
++#undef	DEBUG
++#ifdef 	DEBUG
++#define	DBG(x...)	printk(x)
++#else
++#define	DBG(x...)
++#endif
++
++extern char irq_tab_jbs[][5];
++
++void __init pcibios_fixup_resources(struct pci_dev *dev)
++{
++	/* no need to fixup IO resources */
++}
++
++void __init pcibios_fixup(void)
++{
++	/* nothing to do here */
++}
++
++int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++	return irq_tab_jbs[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-tx4938.c b/arch/mips/pci/fixup-tx4938.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/pci/fixup-tx4938.c
+@@ -0,0 +1,92 @@
++/*
++ * Toshiba rbtx4938 pci routines
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++
++#include <asm/tx4938/rbtx4938.h>
++
++extern struct pci_controller tx4938_pci_controller[];
++
++int pci_get_irq(struct pci_dev *dev, int pin)
++{
++	int irq = pin;
++	u8 slot = PCI_SLOT(dev->devfn);
++	struct pci_controller *controller = (struct pci_controller *)dev->sysdata;
++
++	if (controller == &tx4938_pci_controller[1]) {
++		/* TX4938 PCIC1 */
++		switch (slot) {
++		case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
++			if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH0_SEL)
++				return RBTX4938_IRQ_IRC + TX4938_IR_ETH0;
++			break;
++		case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
++			if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH1_SEL)
++				return RBTX4938_IRQ_IRC + TX4938_IR_ETH1;
++			break;
++		}
++		return 0;
++	}
++
++	/* IRQ rotation */
++	irq--;	/* 0-3 */
++	if (dev->bus->parent == NULL &&
++	    (slot == TX4938_PCIC_IDSEL_AD_TO_SLOT(23))) {
++		/* PCI CardSlot (IDSEL=A23) */
++		/* PCIA => PCIA (IDSEL=A23) */
++		irq = (irq + 0 + slot) % 4;
++	} else {
++		/* PCI Backplane */
++		irq = (irq + 33 - slot) % 4;
++	}
++	irq++;	/* 1-4 */
++
++	switch (irq) {
++	case 1:
++		irq = RBTX4938_IRQ_IOC_PCIA;
++		break;
++	case 2:
++		irq = RBTX4938_IRQ_IOC_PCIB;
++		break;
++	case 3:
++		irq = RBTX4938_IRQ_IOC_PCIC;
++		break;
++	case 4:
++		irq = RBTX4938_IRQ_IOC_PCID;
++		break;
++	}
++	return irq;
++}
++
++int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++	unsigned char irq = 0;
++
++	irq = pci_get_irq(dev, pin);
++
++	printk(KERN_INFO "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n",
++	       dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn),
++	       PCI_FUNC(dev->devfn), irq);
++
++	return irq;
++}
++
++/*
++ * 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-au1000.c b/arch/mips/pci/ops-au1000.c
+--- a/arch/mips/pci/ops-au1000.c
++++ b/arch/mips/pci/ops-au1000.c
+@@ -50,11 +50,6 @@
+ 
+ int (*board_pci_idsel)(unsigned int devsel, int assert);
+ 
+-/* CP0 hazard avoidance. */
+-#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+-				     "nop; nop; nop; nop;\t" \
+-				     ".set reorder\n\t")
+-
+ void mod_wired_entry(int entry, unsigned long entrylo0,
+ 		unsigned long entrylo1, unsigned long entryhi,
+ 		unsigned long pagemask)
+@@ -66,16 +61,12 @@ void mod_wired_entry(int entry, unsigned
+ 	old_ctx = read_c0_entryhi() & 0xff;
+ 	old_pagemask = read_c0_pagemask();
+ 	write_c0_index(entry);
+-	BARRIER;
+ 	write_c0_pagemask(pagemask);
+ 	write_c0_entryhi(entryhi);
+ 	write_c0_entrylo0(entrylo0);
+ 	write_c0_entrylo1(entrylo1);
+-	BARRIER;
+ 	tlb_write_indexed();
+-	BARRIER;
+ 	write_c0_entryhi(old_ctx);
+-	BARRIER;
+ 	write_c0_pagemask(old_pagemask);
+ }
+ 
+@@ -128,9 +119,8 @@ static int config_access(unsigned char a
+ 		last_entryLo0  = last_entryLo1 = 0xffffffff;
+ 	}
+ 
+-	/* Since the Au1xxx doesn't do the idsel timing exactly to spec,
+-	 * many board vendors implement their own off-chip idsel, so call
+-	 * it now.  If it doesn't succeed, may as well bail out at this point.
++	/* Allow board vendors to implement their own off-chip idsel.
++	 * If it doesn't succeed, may as well bail out at this point.
+ 	 */
+ 	if (board_pci_idsel) {
+ 		if (board_pci_idsel(device, 1) == 0) {
+diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c
+--- a/arch/mips/pci/ops-bonito64.c
++++ b/arch/mips/pci/ops-bonito64.c
+@@ -1,6 +1,8 @@
+ /*
+- * Carsten Langgaard, carstenl at mips.com
+- * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
++ * Copyright (C) 1999, 2000, 2004  MIPS Technologies, Inc.
++ *	All rights reserved.
++ *	Authors: Carsten Langgaard <carstenl at mips.com>
++ *		 Maciej W. Rozycki <macro at mips.com>
+  *
+  *  This program is free software; you can distribute it and/or modify it
+  *  under the terms of the GNU General Public License (Version 2) as
+@@ -17,7 +19,6 @@
+  *
+  * MIPS boards specific PCI support.
+  */
+-#include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+@@ -57,13 +58,6 @@ static int bonito64_pcibios_config_acces
+ 		return -1;
+ 	}
+ 
+-#ifdef CONFIG_MIPS_BOARDS_GEN
+-	if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
+-		/* MIPS Core boards have Bonito connected as device 17 */
+-		return -1;
+-	}
+-#endif
+-
+ 	/* Clear cause register bits */
+ 	BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
+ 			  BONITO_PCICMD_MTABORT_CLR);
+diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c
+--- a/arch/mips/pci/ops-gt64111.c
++++ b/arch/mips/pci/ops-gt64111.c
+@@ -18,15 +18,15 @@
+ #include <asm/cobalt/cobalt.h>
+ 
+ /*
+- * Accessing device 31 hangs the GT64120.  Not sure if this will also hang
+- * the GT64111, let's be paranoid for now.
++ * Device 31 on the GT64111 is used to generate PCI special
++ * cycles, so we shouldn't expected to find a device there ...
+  */
+ static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn)
+ {
+-	if (bus->number == 0 && devfn == PCI_DEVFN(31, 0))
+-		return -1;
++	if (bus->number == 0 && PCI_SLOT(devfn) < 31)
++		return 0;
+ 
+-	return 0;
++	return -1;
+ }
+ 
+ static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+diff --git a/arch/mips/pci/ops-gt64120.c b/arch/mips/pci/ops-gt64120.c
+--- a/arch/mips/pci/ops-gt64120.c
++++ b/arch/mips/pci/ops-gt64120.c
+@@ -1,6 +1,8 @@
+ /*
+- * Carsten Langgaard, carstenl at mips.com
+- * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
++ * Copyright (C) 1999, 2000, 2004  MIPS Technologies, Inc.
++ *	All rights reserved.
++ *	Authors: Carsten Langgaard <carstenl at mips.com>
++ *		 Maciej W. Rozycki <macro at mips.com>
+  *
+  *  This program is free software; you can distribute it and/or modify it
+  *  under the terms of the GNU General Public License (Version 2) as
+@@ -43,10 +45,6 @@ static int gt64120_pcibios_config_access
+ 	unsigned char busnum = bus->number;
+ 	u32 intr;
+ 
+-	if ((busnum == 0) && (PCI_SLOT(devfn) == 0))
+-		/* Galileo itself is devfn 0, don't move it around */
+-		return -1;
+-
+ 	if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
+ 		return -1;	/* Because of a bug in the galileo (for slot 31). */
+ 
+diff --git a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c
+--- a/arch/mips/pci/ops-msc.c
++++ b/arch/mips/pci/ops-msc.c
+@@ -21,7 +21,6 @@
+  * MIPS boards specific PCI support.
+  *
+  */
+-#include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+@@ -49,34 +48,17 @@ static int msc_pcibios_config_access(uns
+ 	struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
+ {
+ 	unsigned char busnum = bus->number;
+-	unsigned char type;
+ 	u32 intr;
+ 
+-#ifdef CONFIG_MIPS_BOARDS_GEN
+-	if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
+-		/* MIPS Core boards have SOCit connected as device 17 */
+-		return -1;
+-	}
+-#endif
+-
+ 	/* Clear status register bits. */
+ 	MSC_WRITE(MSC01_PCI_INTSTAT,
+ 		  (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
+ 
+-	/* Setup address */
+-	if (busnum == 0)
+-		type = 0;	/* Type 0 */
+-	else
+-		type = 1;	/* Type 1 */
+-
+ 	MSC_WRITE(MSC01_PCI_CFGADDR,
+ 		  ((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) |
+-		   (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF)
+-		   | (PCI_FUNC(devfn) <<
+-		      MSC01_PCI_CFGADDR_FNUM_SHF) | ((where /
+-						      4) <<
+-						     MSC01_PCI_CFGADDR_RNUM_SHF)
+-		   | (type)));
++		   (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF) |
++		   (PCI_FUNC(devfn) << MSC01_PCI_CFGADDR_FNUM_SHF) |
++		   ((where / 4) << MSC01_PCI_CFGADDR_RNUM_SHF)));
+ 
+ 	/* Perform access */
+ 	if (access_type == PCI_ACCESS_WRITE)
+@@ -86,15 +68,12 @@ static int msc_pcibios_config_access(uns
+ 
+ 	/* Detect Master/Target abort */
+ 	MSC_READ(MSC01_PCI_INTSTAT, intr);
+-	if (intr & (MSC01_PCI_INTCFG_MA_BIT |
+-		    MSC01_PCI_INTCFG_TA_BIT)) {
++	if (intr & (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)) {
+ 		/* Error occurred */
+ 
+ 		/* Clear bits */
+-		MSC_READ(MSC01_PCI_INTSTAT, intr);
+ 		MSC_WRITE(MSC01_PCI_INTSTAT,
+-			  (MSC01_PCI_INTCFG_MA_BIT |
+-			   MSC01_PCI_INTCFG_TA_BIT));
++			  (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
+ 
+ 		return -1;
+ 	}
+diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
+--- a/arch/mips/pci/ops-nile4.c
++++ b/arch/mips/pci/ops-nile4.c
+@@ -15,7 +15,7 @@
+ 
+ volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
+ 
+-static spinlock_t nile4_pci_lock;
++static DEFINE_SPINLOCK(nile4_pci_lock);
+ 
+ static int nile4_pcibios_config_access(unsigned char access_type,
+ 	struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
+diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/pci/ops-pnx8550.c
+@@ -0,0 +1,284 @@
++/*
++ *
++ *  BRIEF MODULE DESCRIPTION
++ *
++ *  2.6 port, Embedded Alley Solutions, Inc
++ *
++ *  Based on:
++ *  Author: source at mvista.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/vmalloc.h>
++#include <linux/delay.h>
++
++#include <asm/mach-pnx8550/pci.h>
++#include <asm/mach-pnx8550/glb.h>
++#include <asm/debug.h>
++
++
++static inline void clear_status(void)
++{
++	unsigned long pci_stat;
++
++	pci_stat = inl(PCI_BASE | PCI_GPPM_STATUS);
++	outl(pci_stat, PCI_BASE | PCI_GPPM_ICLR);
++}
++
++static inline unsigned int
++calc_cfg_addr(struct pci_bus *bus, unsigned int devfn, int where)
++{
++	unsigned int addr;
++
++	addr = ((bus->number > 0) ? (((bus->number & 0xff) << PCI_CFG_BUS_SHIFT) | 1) : 0);
++	addr |= ((devfn & 0xff) << PCI_CFG_FUNC_SHIFT) | (where & 0xfc);
++
++	return addr;
++}
++
++static int
++config_access(unsigned int pci_cmd, struct pci_bus *bus, unsigned int devfn, int where, unsigned int pci_mode, unsigned int *val)
++{
++	unsigned int flags;
++	unsigned long loops = 0;
++	unsigned long ioaddr = calc_cfg_addr(bus, devfn, where);
++
++	local_irq_save(flags);
++	/*Clear pending interrupt status */
++	if (inl(PCI_BASE | PCI_GPPM_STATUS)) {
++		clear_status();
++		while (!(inl(PCI_BASE | PCI_GPPM_STATUS) == 0)) ;
++	}
++
++	outl(ioaddr, PCI_BASE | PCI_GPPM_ADDR);
++
++	if ((pci_cmd == PCI_CMD_IOW) || (pci_cmd == PCI_CMD_CONFIG_WRITE))
++		outl(*val, PCI_BASE | PCI_GPPM_WDAT);
++
++	outl(INIT_PCI_CYCLE | pci_cmd | (pci_mode & PCI_BYTE_ENABLE_MASK),
++	     PCI_BASE | PCI_GPPM_CTRL);
++
++	loops =
++	    ((loops_per_jiffy *
++	      PCI_IO_JIFFIES_TIMEOUT) >> (PCI_IO_JIFFIES_SHIFT));
++	while (1) {
++		if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_DONE) {
++			if ((pci_cmd == PCI_CMD_IOR) ||
++			    (pci_cmd == PCI_CMD_CONFIG_READ))
++				*val = inl(PCI_BASE | PCI_GPPM_RDAT);
++			clear_status();
++			local_irq_restore(flags);
++			return PCIBIOS_SUCCESSFUL;
++		} else if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_R_MABORT) {
++			break;
++		}
++
++		loops--;
++		if (loops == 0) {
++			printk("%s : Arbiter Locked.\n", __FUNCTION__);
++		}
++	}
++
++	clear_status();
++	if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) {
++		printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n",
++		       __FUNCTION__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr,
++		       pci_cmd);
++	}
++
++	if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_CONFIG_READ))
++		*val = 0xffffffff;
++	local_irq_restore(flags);
++	return PCIBIOS_DEVICE_NOT_FOUND;
++}
++
++/*
++ * We can't address 8 and 16 bit words directly.  Instead we have to
++ * read/write a 32bit word and mask/modify the data we actually want.
++ */
++static int
++read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val)
++{
++	unsigned int data = 0;
++	int err;
++
++	if (bus == 0)
++		return -1;
++
++	err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
++	switch (where & 0x03) {
++	case 0:
++		*val = (unsigned char)(data & 0x000000ff);
++		break;
++	case 1:
++		*val = (unsigned char)((data & 0x0000ff00) >> 8);
++		break;
++	case 2:
++		*val = (unsigned char)((data & 0x00ff0000) >> 16);
++		break;
++	case 3:
++		*val = (unsigned char)((data & 0xff000000) >> 24);
++		break;
++	}
++
++	return err;
++}
++
++static int
++read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val)
++{
++	unsigned int data = 0;
++	int err;
++
++	if (bus == 0)
++		return -1;
++
++	if (where & 0x01)
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(3 << (where & 3)), &data);
++	switch (where & 0x02) {
++	case 0:
++		*val = (unsigned short)(data & 0x0000ffff);
++		break;
++	case 2:
++		*val = (unsigned short)((data & 0xffff0000) >> 16);
++		break;
++	}
++
++	return err;
++}
++
++static int
++read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
++{
++	int err;
++	if (bus == 0)
++		return -1;
++
++	if (where & 0x03)
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, 0, val);
++
++	return err;
++}
++
++static int
++write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
++{
++	unsigned int data = (unsigned int)val;
++	int err;
++
++	if (bus == 0)
++		return -1;
++
++	switch (where & 0x03) {
++	case 1:
++		data = (data << 8);
++		break;
++	case 2:
++		data = (data << 16);
++		break;
++	case 3:
++		data = (data << 24);
++		break;
++	default:
++		break;
++	}
++
++	err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
++
++	return err;
++}
++
++static int
++write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
++{
++	unsigned int data = (unsigned int)val;
++	int err;
++
++	if (bus == 0)
++		return -1;
++
++	if (where & 0x01)
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	switch (where & 0x02) {
++	case 2:
++		data = (data << 16);
++		break;
++	default:
++		break;
++	}
++	err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(3 << (where & 3)), &data);
++
++	return err;
++}
++
++static int
++write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
++{
++	int err;
++	if (bus == 0)
++		return -1;
++
++	if (where & 0x03)
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, 0, &val);
++
++	return err;
++}
++
++static int config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
++{
++	switch (size) {
++	case 1: {
++			u8 _val;
++			int rc = read_config_byte(bus, devfn, where, &_val);
++			*val = _val;
++			return rc;
++		}
++       case 2: {
++			u16 _val;
++			int rc = read_config_word(bus, devfn, where, &_val);
++			*val = _val;
++			return rc;
++		}
++	default:
++		return read_config_dword(bus, devfn, where, val);
++	}
++}
++
++static int config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
++{
++	switch (size) {
++	case 1:
++		return write_config_byte(bus, devfn, where, (u8) val);
++	case 2:
++		return write_config_word(bus, devfn, where, (u16) val);
++	default:
++		return write_config_dword(bus, devfn, where, val);
++	}
++}
++
++struct pci_ops pnx8550_pci_ops = {
++	config_read,
++	config_write
++};
+diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/pci/ops-tx4938.c
+@@ -0,0 +1,198 @@
++/*
++ * Define the pci_ops for the Toshiba rbtx4938
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++
++#include <asm/addrspace.h>
++#include <asm/tx4938/rbtx4938.h>
++
++/* initialize in setup */
++struct resource pci_io_resource = {
++	.name	= "pci IO space",
++	.start	= 0,
++	.end	= 0,
++	.flags	= IORESOURCE_IO
++};
++
++/* initialize in setup */
++struct resource pci_mem_resource = {
++	.name	= "pci memory space",
++	.start	= 0,
++	.end	= 0,
++	.flags	= IORESOURCE_MEM
++};
++
++struct resource tx4938_pcic1_pci_io_resource = {
++       	.name	= "PCI1 IO",
++       	.start	= 0,
++       	.end	= 0,
++       	.flags	= IORESOURCE_IO
++};
++struct resource tx4938_pcic1_pci_mem_resource = {
++       	.name	= "PCI1 mem",
++       	.start	= 0,
++       	.end	= 0,
++       	.flags	= IORESOURCE_MEM
++};
++
++static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
++{
++	if (bus > 0) {
++		/* Type 1 configuration */
++		tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
++		    ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
++	} else {
++		if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
++			return -1;
++
++		/* Type 0 configuration */
++		tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
++		    ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
++	}
++	/* clear M_ABORT and Disable M_ABORT Int. */
++	tx4938_pcicptr->pcistatus =
++	    (tx4938_pcicptr->pcistatus & 0x0000ffff) |
++	    (PCI_STATUS_REC_MASTER_ABORT << 16);
++	tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
++
++	return 0;
++}
++
++static int check_abort(int flags)
++{
++	int code = PCIBIOS_SUCCESSFUL;
++	/* wait write cycle completion before checking error status */
++	while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
++				;
++	if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
++		tx4938_pcicptr->pcistatus =
++		    (tx4938_pcicptr->
++		     pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
++						<< 16);
++		tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
++		code = PCIBIOS_DEVICE_NOT_FOUND;
++	}
++	return code;
++}
++
++static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
++					int where, int size, u32 * val)
++{
++	int flags, retval, dev, busno, func;
++
++	dev = PCI_SLOT(devfn);
++	func = PCI_FUNC(devfn);
++
++	/* check if the bus is top-level */
++	if (bus->parent != NULL)
++		busno = bus->number;
++	else {
++		busno = 0;
++	}
++
++	if (mkaddr(busno, devfn, where, &flags))
++		return -1;
++
++	switch (size) {
++	case 1:
++		*val = *(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
++#ifdef __BIG_ENDIAN
++			      ((where & 3) ^ 3));
++#else
++			      (where & 3));
++#endif
++		break;
++	case 2:
++		*val = *(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
++#ifdef __BIG_ENDIAN
++				((where & 3) ^ 2));
++#else
++				(where & 3));
++#endif
++		break;
++	case 4:
++		*val = tx4938_pcicptr->g2pcfgdata;
++		break;
++	}
++
++	retval = check_abort(flags);
++	if (retval == PCIBIOS_DEVICE_NOT_FOUND)
++		*val = 0xffffffff;
++
++	return retval;
++}
++
++static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
++						int size, u32 val)
++{
++	int flags, dev, busno, func;
++
++	busno = bus->number;
++	dev = PCI_SLOT(devfn);
++	func = PCI_FUNC(devfn);
++
++	/* check if the bus is top-level */
++	if (bus->parent != NULL) {
++		busno = bus->number;
++	} else {
++		busno = 0;
++	}
++
++	if (mkaddr(busno, devfn, where, &flags))
++		return -1;
++
++	switch (size) {
++	case 1:
++		*(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
++#ifdef __BIG_ENDIAN
++			  ((where & 3) ^ 3)) = val;
++#else
++			  (where & 3)) = val;
++#endif
++		break;
++	case 2:
++		*(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
++#ifdef __BIG_ENDIAN
++			((where & 0x3) ^ 0x2)) = val;
++#else
++			(where & 3)) = val;
++#endif
++		break;
++	case 4:
++		tx4938_pcicptr->g2pcfgdata = val;
++		break;
++	}
++
++	return check_abort(flags);
++}
++
++struct pci_ops tx4938_pci_ops = {
++	tx4938_pcibios_read_config,
++	tx4938_pcibios_write_config
++};
++
++struct pci_controller tx4938_pci_controller[] = {
++	/* h/w only supports devices 0x00 to 0x14 */
++	{
++		.pci_ops        = &tx4938_pci_ops,
++		.io_resource    = &pci_io_resource,
++		.mem_resource   = &pci_mem_resource,
++	},
++	/* h/w only supports devices 0x00 to 0x14 */
++	{
++		.pci_ops        = &tx4938_pci_ops,
++		.io_resource    = &tx4938_pcic1_pci_io_resource,
++		.mem_resource   = &tx4938_pcic1_pci_mem_resource,
++        }
++};
+diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/pci/pci-bcm1480.c
+@@ -0,0 +1,265 @@
++/*
++ * Copyright (C) 2001,2002,2005 Broadcom Corporation
++ * Copyright (C) 2004 by Ralf Baechle (ralf at linux-mips.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ */
++
++/*
++ * BCM1x80/1x55-specific PCI support
++ *
++ * This module provides the glue between Linux's PCI subsystem
++ * and the hardware.  We basically provide glue for accessing
++ * configuration space, and set up the translation for I/O
++ * space accesses.
++ *
++ * To access configuration space, we use ioremap.  In the 32-bit
++ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
++ * kernel mapped memory.  Hopefully neither of these should be a huge
++ * problem.
++ *
++ * XXX: AT THIS TIME, ONLY the NATIVE PCI-X INTERFACE IS SUPPORTED.
++ */
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/console.h>
++#include <linux/tty.h>
++
++#include <asm/sibyte/bcm1480_regs.h>
++#include <asm/sibyte/bcm1480_scd.h>
++#include <asm/sibyte/board.h>
++#include <asm/io.h>
++
++/*
++ * Macros for calculating offsets into config space given a device
++ * structure or dev/fun/reg
++ */
++#define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
++#define CFGADDR(bus,devfn,where)   CFGOFFSET((bus)->number,(devfn),where)
++
++static void *cfg_space;
++
++#define PCI_BUS_ENABLED	1
++#define PCI_DEVICE_MODE	2
++
++static int bcm1480_bus_status = 0;
++
++#define PCI_BRIDGE_DEVICE  0
++
++/*
++ * Read/write 32-bit values in config space.
++ */
++static inline u32 READCFG32(u32 addr)
++{
++	return *(u32 *)(cfg_space + (addr&~3));
++}
++
++static inline void WRITECFG32(u32 addr, u32 data)
++{
++	*(u32 *)(cfg_space + (addr & ~3)) = data;
++}
++
++int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++	return dev->irq;
++}
++
++/* Do platform specific device initialization at pci_enable_device() time */
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++	return 0;
++}
++
++/*
++ * Some checks before doing config cycles:
++ * In PCI Device Mode, hide everything on bus 0 except the LDT host
++ * bridge.  Otherwise, access is controlled by bridge MasterEn bits.
++ */
++static int bcm1480_pci_can_access(struct pci_bus *bus, int devfn)
++{
++	u32 devno;
++
++	if (!(bcm1480_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
++		return 0;
++
++	if (bus->number == 0) {
++		devno = PCI_SLOT(devfn);
++ 		if (bcm1480_bus_status & PCI_DEVICE_MODE)
++			return 0;
++		else
++			return 1;
++	} else
++		return 1;
++}
++
++/*
++ * Read/write access functions for various sizes of values
++ * in config space.  Return all 1's for disallowed accesses
++ * for a kludgy but adequate simulation of master aborts.
++ */
++
++static int bcm1480_pcibios_read(struct pci_bus *bus, unsigned int devfn,
++				int where, int size, u32 * val)
++{
++	u32 data = 0;
++
++	if ((size == 2) && (where & 1))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++	else if ((size == 4) && (where & 3))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	if (bcm1480_pci_can_access(bus, devfn))
++		data = READCFG32(CFGADDR(bus, devfn, where));
++	else
++		data = 0xFFFFFFFF;
++
++	if (size == 1)
++		*val = (data >> ((where & 3) << 3)) & 0xff;
++	else if (size == 2)
++		*val = (data >> ((where & 3) << 3)) & 0xffff;
++	else
++		*val = data;
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int bcm1480_pcibios_write(struct pci_bus *bus, unsigned int devfn,
++				int where, int size, u32 val)
++{
++	u32 cfgaddr = CFGADDR(bus, devfn, where);
++	u32 data = 0;
++
++	if ((size == 2) && (where & 1))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++	else if ((size == 4) && (where & 3))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	if (!bcm1480_pci_can_access(bus, devfn))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	data = READCFG32(cfgaddr);
++
++	if (size == 1)
++		data = (data & ~(0xff << ((where & 3) << 3))) |
++		    (val << ((where & 3) << 3));
++	else if (size == 2)
++		data = (data & ~(0xffff << ((where & 3) << 3))) |
++		    (val << ((where & 3) << 3));
++	else
++		data = val;
++
++	WRITECFG32(cfgaddr, data);
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++struct pci_ops bcm1480_pci_ops = {
++	bcm1480_pcibios_read,
++	bcm1480_pcibios_write,
++};
++
++static struct resource bcm1480_mem_resource = {
++	.name	= "BCM1480 PCI MEM",
++	.start	= 0x30000000UL,
++	.end	= 0x3fffffffUL,
++	.flags	= IORESOURCE_MEM,
++};
++
++static struct resource bcm1480_io_resource = {
++	.name	= "BCM1480 PCI I/O",
++	.start	= 0x2c000000UL,
++	.end	= 0x2dffffffUL,
++	.flags	= IORESOURCE_IO,
++};
++
++struct pci_controller bcm1480_controller = {
++	.pci_ops	= &bcm1480_pci_ops,
++	.mem_resource	= &bcm1480_mem_resource,
++	.io_resource	= &bcm1480_io_resource,
++};
++
++
++static int __init bcm1480_pcibios_init(void)
++{
++	uint32_t cmdreg;
++	uint64_t reg;
++	extern int pci_probe_only;
++
++	/* CFE will assign PCI resources */
++	pci_probe_only = 1;
++
++	/* Avoid ISA compat ranges.  */
++	PCIBIOS_MIN_IO = 0x00008000UL;
++	PCIBIOS_MIN_MEM = 0x01000000UL;
++
++	/* Set I/O resource limits. - unlimited for now to accomodate HT */
++	ioport_resource.end = 0xffffffffUL;
++	iomem_resource.end = 0xffffffffUL;
++
++	cfg_space = ioremap(A_BCM1480_PHYS_PCI_CFG_MATCH_BITS, 16*1024*1024);
++
++	/*
++	 * See if the PCI bus has been configured by the firmware.
++	 */
++	reg = *((volatile uint64_t *) IOADDR(A_SCD_SYSTEM_CFG));
++	if (!(reg & M_BCM1480_SYS_PCI_HOST)) {
++		bcm1480_bus_status |= PCI_DEVICE_MODE;
++	} else {
++		cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
++					     PCI_COMMAND));
++		if (!(cmdreg & PCI_COMMAND_MASTER)) {
++			printk
++			    ("PCI: Skipping PCI probe.  Bus is not initialized.\n");
++			iounmap(cfg_space);
++			return 1; /* XXX */
++		}
++		bcm1480_bus_status |= PCI_BUS_ENABLED;
++	}
++
++	/* turn on ExpMemEn */
++	cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
++	printk("PCIFeatureCtrl = %x\n", cmdreg);
++	WRITECFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40),
++			cmdreg | 0x10);
++	cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
++	printk("PCIFeatureCtrl = %x\n", cmdreg);
++
++	/*
++	 * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
++	 * space.  Use "match bytes" policy to make everything look
++	 * little-endian.  So, you need to also set
++	 * CONFIG_SWAP_IO_SPACE, but this is the combination that
++	 * works correctly with most of Linux's drivers.
++	 * XXX ehs: Should this happen in PCI Device mode?
++	 */
++
++	set_io_port_base((unsigned long)
++		ioremap(A_BCM1480_PHYS_PCI_IO_MATCH_BYTES, 65536));
++	isa_slot_offset = (unsigned long)
++		ioremap(A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES, 1024*1024);
++
++	register_pci_controller(&bcm1480_controller);
++
++#ifdef CONFIG_VGA_CONSOLE
++	take_over_console(&vga_con,0,MAX_NR_CONSOLES-1,1);
++#endif
++	return 0;
++}
++
++arch_initcall(bcm1480_pcibios_init);
+diff --git a/arch/mips/pci/pci-bcm1480ht.c b/arch/mips/pci/pci-bcm1480ht.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/pci/pci-bcm1480ht.c
+@@ -0,0 +1,224 @@
++/*
++ * Copyright (C) 2001,2002,2005 Broadcom Corporation
++ * Copyright (C) 2004 by Ralf Baechle (ralf at linux-mips.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ */
++
++/*
++ * BCM1480/1455-specific HT support (looking like PCI)
++ *
++ * This module provides the glue between Linux's PCI subsystem
++ * and the hardware.  We basically provide glue for accessing
++ * configuration space, and set up the translation for I/O
++ * space accesses.
++ *
++ * To access configuration space, we use ioremap.  In the 32-bit
++ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
++ * kernel mapped memory.  Hopefully neither of these should be a huge
++ * problem.
++ *
++ */
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/console.h>
++#include <linux/tty.h>
++
++#include <asm/sibyte/bcm1480_regs.h>
++#include <asm/sibyte/bcm1480_scd.h>
++#include <asm/sibyte/board.h>
++#include <asm/io.h>
++
++/*
++ * Macros for calculating offsets into config space given a device
++ * structure or dev/fun/reg
++ */
++#define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
++#define CFGADDR(bus,devfn,where)   CFGOFFSET((bus)->number,(devfn),where)
++
++static void *ht_cfg_space;
++
++#define PCI_BUS_ENABLED	1
++#define PCI_DEVICE_MODE	2
++
++static int bcm1480ht_bus_status = 0;
++
++#define PCI_BRIDGE_DEVICE  0
++#define HT_BRIDGE_DEVICE   1
++
++/*
++ * HT's level-sensitive interrupts require EOI, which is generated
++ * through a 4MB memory-mapped region
++ */
++unsigned long ht_eoi_space;
++
++/*
++ * Read/write 32-bit values in config space.
++ */
++static inline u32 READCFG32(u32 addr)
++{
++	return *(u32 *)(ht_cfg_space + (addr&~3));
++}
++
++static inline void WRITECFG32(u32 addr, u32 data)
++{
++	*(u32 *)(ht_cfg_space + (addr & ~3)) = data;
++}
++
++/*
++ * Some checks before doing config cycles:
++ * In PCI Device Mode, hide everything on bus 0 except the LDT host
++ * bridge.  Otherwise, access is controlled by bridge MasterEn bits.
++ */
++static int bcm1480ht_can_access(struct pci_bus *bus, int devfn)
++{
++	u32 devno;
++
++	if (!(bcm1480ht_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
++		return 0;
++
++	if (bus->number == 0) {
++		devno = PCI_SLOT(devfn);
++ 		if (bcm1480ht_bus_status & PCI_DEVICE_MODE)
++			return 0;
++	}
++	return 1;
++}
++
++/*
++ * Read/write access functions for various sizes of values
++ * in config space.  Return all 1's for disallowed accesses
++ * for a kludgy but adequate simulation of master aborts.
++ */
++
++static int bcm1480ht_pcibios_read(struct pci_bus *bus, unsigned int devfn,
++				  int where, int size, u32 * val)
++{
++	u32 data = 0;
++
++	if ((size == 2) && (where & 1))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++	else if ((size == 4) && (where & 3))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	if (bcm1480ht_can_access(bus, devfn))
++		data = READCFG32(CFGADDR(bus, devfn, where));
++	else
++		data = 0xFFFFFFFF;
++
++	if (size == 1)
++		*val = (data >> ((where & 3) << 3)) & 0xff;
++	else if (size == 2)
++		*val = (data >> ((where & 3) << 3)) & 0xffff;
++	else
++		*val = data;
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int bcm1480ht_pcibios_write(struct pci_bus *bus, unsigned int devfn,
++				   int where, int size, u32 val)
++{
++	u32 cfgaddr = CFGADDR(bus, devfn, where);
++	u32 data = 0;
++
++	if ((size == 2) && (where & 1))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++	else if ((size == 4) && (where & 3))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	if (!bcm1480ht_can_access(bus, devfn))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	data = READCFG32(cfgaddr);
++
++	if (size == 1)
++		data = (data & ~(0xff << ((where & 3) << 3))) |
++		    (val << ((where & 3) << 3));
++	else if (size == 2)
++		data = (data & ~(0xffff << ((where & 3) << 3))) |
++		    (val << ((where & 3) << 3));
++	else
++		data = val;
++
++	WRITECFG32(cfgaddr, data);
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int bcm1480ht_pcibios_get_busno(void)
++{
++	return 0;
++}
++
++struct pci_ops bcm1480ht_pci_ops = {
++	.read	= bcm1480ht_pcibios_read,
++	.write	= bcm1480ht_pcibios_write,
++};
++
++static struct resource bcm1480ht_mem_resource = {
++	.name	= "BCM1480 HT MEM",
++	.start	= 0x40000000UL,
++	.end	= 0x5fffffffUL,
++	.flags	= IORESOURCE_MEM,
++};
++
++static struct resource bcm1480ht_io_resource = {
++	.name	= "BCM1480 HT I/O",
++	.start	= 0x00000000UL,
++	.end	= 0x01ffffffUL,
++	.flags	= IORESOURCE_IO,
++};
++
++struct pci_controller bcm1480ht_controller = {
++	.pci_ops	= &bcm1480ht_pci_ops,
++	.mem_resource	= &bcm1480ht_mem_resource,
++	.io_resource	= &bcm1480ht_io_resource,
++	.index		= 1,
++	.get_busno	= bcm1480ht_pcibios_get_busno,
++};
++
++static int __init bcm1480ht_pcibios_init(void)
++{
++	uint32_t cmdreg;
++
++	ht_cfg_space = ioremap(A_BCM1480_PHYS_HT_CFG_MATCH_BITS, 16*1024*1024);
++
++	/*
++	 * See if the PCI bus has been configured by the firmware.
++	 */
++	cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
++				     PCI_COMMAND));
++	if (!(cmdreg & PCI_COMMAND_MASTER)) {
++		printk("HT: Skipping HT probe. Bus is not initialized.\n");
++		iounmap(ht_cfg_space);
++		return 1; /* XXX */
++	}
++	bcm1480ht_bus_status |= PCI_BUS_ENABLED;
++
++	ht_eoi_space = (unsigned long)
++		ioremap(A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES,
++			4 * 1024 * 1024);
++
++	register_pci_controller(&bcm1480ht_controller);
++
++	return 0;
++}
++
++arch_initcall(bcm1480ht_pcibios_init);
+diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
+--- a/arch/mips/pci/pci-ip27.c
++++ b/arch/mips/pci/pci-ip27.c
+@@ -485,5 +485,12 @@ static void __init pci_fixup_ioc3(struct
+ 	pci_disable_swapping(d);
+ }
+ 
++int pcibus_to_node(struct pci_bus *bus)
++{
++	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
++
++	return bc->nasid;
++}
++
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+ 	pci_fixup_ioc3);
+diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
+--- a/arch/mips/pci/pci-ip32.c
++++ b/arch/mips/pci/pci-ip32.c
+@@ -136,7 +136,9 @@ static int __init mace_init(void)
+ 	BUG_ON(request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
+ 			   "MACE PCI error", NULL));
+ 
+-	ioport_resource.end = mace_pci_io_resource.end;
++	iomem_resource = mace_pci_mem_resource;
++	ioport_resource = mace_pci_io_resource;
++
+ 	register_pci_controller(&mace_pci_controller);
+ 
+ 	return 0;
+diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c
+--- a/arch/mips/pci/pci-lasat.c
++++ b/arch/mips/pci/pci-lasat.c
+@@ -7,12 +7,8 @@
+  */
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/types.h>
+-#include <linux/interrupt.h>
+-#include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <asm/bootinfo.h>
+ 
+ extern struct pci_ops nile4_pci_ops;
+@@ -20,14 +16,14 @@ extern struct pci_ops gt64120_pci_ops;
+ static struct resource lasat_pci_mem_resource = {
+ 	.name	= "LASAT PCI MEM",
+ 	.start	= 0x18000000,
+-	.end	= 0x19FFFFFF,
++	.end	= 0x19ffffff,
+ 	.flags	= IORESOURCE_MEM,
+ };
+ 
+ static struct resource lasat_pci_io_resource = {
+ 	.name	= "LASAT PCI IO",
+ 	.start	= 0x1a000000,
+-	.end	= 0x1bFFFFFF,
++	.end	= 0x1bffffff,
+ 	.flags	= IORESOURCE_IO,
+ };
+ 
+@@ -38,23 +34,25 @@ static struct pci_controller lasat_pci_c
+ 
+ static int __init lasat_pci_setup(void)
+ {
+- 	printk("PCI: starting\n");
++	printk("PCI: starting\n");
+ 
+-        switch (mips_machtype) {
+-            case MACH_LASAT_100:
++	switch (mips_machtype) {
++	case MACH_LASAT_100:
+                 lasat_pci_controller.pci_ops = &gt64120_pci_ops;
+                 break;
+-            case MACH_LASAT_200:
++	case MACH_LASAT_200:
+                 lasat_pci_controller.pci_ops = &nile4_pci_ops;
+                 break;
+-            default:
++	default:
+                 panic("pcibios_init: mips_machtype incorrect");
+         }
+ 
+ 	register_pci_controller(&lasat_pci_controller);
+-        return 0;
++
++	return 0;
+ }
+-early_initcall(lasat_pci_setup);
++
++arch_initcall(lasat_pci_setup);
+ 
+ #define LASATINT_ETH1   0
+ #define LASATINT_ETH0   1
+@@ -68,24 +66,22 @@ early_initcall(lasat_pci_setup);
+ 
+ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+ {
+-    switch (slot) {
+-        case 1:
+-            return LASATINT_PCIA;   /* Expansion Module 0 */
+-        case 2:
+-            return LASATINT_PCIB;   /* Expansion Module 1 */
+-        case 3:
+-            return LASATINT_PCIC;   /* Expansion Module 2 */
+-        case 4:
+-            return LASATINT_ETH1;   /* Ethernet 1 (LAN 2) */
+-        case 5:
+-            return LASATINT_ETH0;   /* Ethernet 0 (LAN 1) */
+-        case 6:
+-            return LASATINT_HDC;    /* IDE controller */
+-        default:
+-            return 0xff;            /* Illegal */
+-    }
++	switch (slot) {
++	case 1:
++	case 2:
++	case 3:
++		return LASATINT_PCIA + (((slot-1) + (pin-1)) % 4);
++	case 4:
++		return LASATINT_ETH1;   /* Ethernet 1 (LAN 2) */
++	case 5:
++		return LASATINT_ETH0;   /* Ethernet 0 (LAN 1) */
++	case 6:
++		return LASATINT_HDC;    /* IDE controller */
++	default:
++		return 0xff;            /* Illegal */
++	}
+ 
+-    return -1;
++	return -1;
+ }
+ 
+ /* Do platform specific device initialization at pci_enable_device() time */
+diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
+--- a/arch/mips/pci/pci.c
++++ b/arch/mips/pci/pci.c
+@@ -127,15 +127,20 @@ static int __init pcibios_init(void)
+ 		if (!hose->iommu)
+ 			PCI_DMA_BUS_IS_PHYS = 1;
+ 
++		if (hose->get_busno && pci_probe_only)
++			next_busno = (*hose->get_busno)();
++
+ 		bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
+ 		hose->bus = bus;
+ 		hose->need_domain_info = need_domain_info;
+-		next_busno = bus->subordinate + 1;
+-		/* Don't allow 8-bit bus number overflow inside the hose -
+-		   reserve some space for bridges. */
+-		if (next_busno > 224) {
+-			next_busno = 0;
+-			need_domain_info = 1;
++		if (bus) {
++			next_busno = bus->subordinate + 1;
++			/* Don't allow 8-bit bus number overflow inside the hose -
++			   reserve some space for bridges. */
++			if (next_busno > 224) {
++				next_busno = 0;
++				need_domain_info = 1;
++			}
+ 		}
+ 		continue;
+ 
+@@ -164,7 +169,7 @@ static int pcibios_enable_resources(stru
+ 
+ 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ 	old_cmd = cmd;
+-	for(idx=0; idx<6; idx++) {
++	for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
+ 		/* Only set up the requested stuff */
+ 		if (!(mask & (1<<idx)))
+ 			continue;
+diff --git a/arch/mips/philips/pnx8550/common/Kconfig b/arch/mips/philips/pnx8550/common/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/Kconfig
+@@ -0,0 +1 @@
++# Place holder
+diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/philips/pnx8550/common/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/Makefile
+@@ -0,0 +1,27 @@
++#
++# Per Hallsmark, per.hallsmark at mvista.com
++#
++# ########################################################################
++#
++# This program is free software; you can distribute 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 it will be useful, but WITHOUT
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++# for more details.
++#
++# You 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.
++#
++# #######################################################################
++#
++# Makefile for the PNX8550 specific kernel interface routines
++# under Linux.
++#
++
++obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o
++obj-$(CONFIG_PCI) += pci.o
++obj-$(CONFIG_KGDB) += gdb_hook.o
+diff --git a/arch/mips/philips/pnx8550/common/gdb_hook.c b/arch/mips/philips/pnx8550/common/gdb_hook.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/gdb_hook.c
+@@ -0,0 +1,109 @@
++/*
++ * Carsten Langgaard, carstenl at mips.com
++ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
++ *
++ * ########################################################################
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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 the interface to the remote debugger stub.
++ *
++ */
++#include <linux/types.h>
++#include <linux/serial.h>
++#include <linux/serialP.h>
++#include <linux/serial_reg.h>
++#include <linux/serial_ip3106.h>
++
++#include <asm/serial.h>
++#include <asm/io.h>
++
++#include <uart.h>
++
++static struct serial_state rs_table[IP3106_NR_PORTS] = {
++};
++static struct async_struct kdb_port_info = {0};
++
++void rs_kgdb_hook(int tty_no)
++{
++	struct serial_state *ser = &rs_table[tty_no];
++
++	kdb_port_info.state = ser;
++	kdb_port_info.magic = SERIAL_MAGIC;
++	kdb_port_info.port  = tty_no;
++	kdb_port_info.flags = ser->flags;
++
++	/*
++	 * Clear all interrupts
++	 */
++	/* Clear all the transmitter FIFO counters (pointer and status) */
++	ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_TX_RST;
++	/* Clear all the receiver FIFO counters (pointer and status) */
++	ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_RX_RST;
++	/* Clear all interrupts */
++	ip3106_iclr(UART_BASE, tty_no) = IP3106_UART_INT_ALLRX |
++		IP3106_UART_INT_ALLTX;
++
++	/*
++	 * Now, initialize the UART
++	 */
++	ip3106_lcr(UART_BASE, tty_no) = IP3106_UART_LCR_8BIT;
++	ip3106_baud(UART_BASE, tty_no) = 5; // 38400 Baud
++}
++
++int putDebugChar(char c)
++{
++	/* Wait until FIFO not full */
++	while (((ip3106_fifo(UART_BASE, kdb_port_info.port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16)
++		;
++	/* Send one char */
++	ip3106_fifo(UART_BASE, kdb_port_info.port) = c;
++
++	return 1;
++}
++
++char getDebugChar(void)
++{
++	char ch;
++
++	/* Wait until there is a char in the FIFO */
++	while (!((ip3106_fifo(UART_BASE, kdb_port_info.port) &
++					IP3106_UART_FIFO_RXFIFO) >> 8))
++		;
++	/* Read one char */
++	ch = ip3106_fifo(UART_BASE, kdb_port_info.port) &
++		IP3106_UART_FIFO_RBRTHR;
++	/* Advance the RX FIFO read pointer */
++	ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_NEXT;
++	return (ch);
++}
++
++void rs_disable_debug_interrupts(void)
++{
++	ip3106_ien(UART_BASE, kdb_port_info.port) = 0; /* Disable all interrupts */
++}
++
++void rs_enable_debug_interrupts(void)
++{
++	/* Clear all the transmitter FIFO counters (pointer and status) */
++	ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_TX_RST;
++	/* Clear all the receiver FIFO counters (pointer and status) */
++	ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_RST;
++	/* Clear all interrupts */
++	ip3106_iclr(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX |
++		IP3106_UART_INT_ALLTX;
++	ip3106_ien(UART_BASE, kdb_port_info.port)  = IP3106_UART_INT_ALLRX; /* Enable RX interrupts */
++}
+diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/int.c
+@@ -0,0 +1,293 @@
++/*
++ *
++ * Copyright (C) 2005 Embedded Alley Solutions, Inc
++ * Ported to 2.6.
++ *
++ * Per Hallsmark, per.hallsmark at mvista.com
++ * Copyright (C) 2000, 2001 MIPS Technologies, Inc.
++ * Copyright (C) 2001 Ralf Baechle
++ *
++ * Cleaned up and bug fixing: Pete Popov, ppopov at embeddedalley.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/config.h>
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/kernel_stat.h>
++#include <linux/random.h>
++#include <linux/module.h>
++
++#include <asm/io.h>
++#include <asm/gdb-stub.h>
++#include <int.h>
++#include <uart.h>
++
++extern asmlinkage void cp0_irqdispatch(void);
++
++static DEFINE_SPINLOCK(irq_lock);
++
++/* default prio for interrupts */
++/* first one is a no-no so therefore always prio 0 (disabled) */
++static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
++	0, 1, 1, 1, 1, 15, 1, 1, 1, 1,	//   0 -  9
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	//  10 - 19
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	//  20 - 29
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	//  30 - 39
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	//  40 - 49
++	1, 1, 1, 1, 1, 1, 1, 1, 2, 1,	//  50 - 59
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	//  60 - 69
++	1			//  70
++};
++
++void hw0_irqdispatch(int irq, struct pt_regs *regs)
++{
++	/* find out which interrupt */
++	irq = PNX8550_GIC_VECTOR_0 >> 3;
++
++	if (irq == 0) {
++		printk("hw0_irqdispatch: irq 0, spurious interrupt?\n");
++		return;
++	}
++	do_IRQ(PNX8550_INT_GIC_MIN + irq, regs);
++}
++
++
++void timer_irqdispatch(int irq, struct pt_regs *regs)
++{
++	irq = (0x01c0 & read_c0_config7()) >> 6;
++
++	if (irq == 0) {
++		printk("timer_irqdispatch: irq 0, spurious interrupt?\n");
++		return;
++	}
++
++	if (irq & 0x1) {
++		do_IRQ(PNX8550_INT_TIMER1, regs);
++	}
++	if (irq & 0x2) {
++		do_IRQ(PNX8550_INT_TIMER2, regs);
++	}
++	if (irq & 0x4) {
++		do_IRQ(PNX8550_INT_TIMER3, regs);
++	}
++}
++
++static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
++{
++	unsigned long status = read_c0_status();
++
++	status &= ~((clr_mask & 0xFF) << 8);
++	status |= (set_mask & 0xFF) << 8;
++
++	write_c0_status(status);
++}
++
++static inline void mask_gic_int(unsigned int irq_nr)
++{
++	/* interrupt disabled, bit 26(WE_ENABLE)=1 and bit 16(enable)=0 */
++	PNX8550_GIC_REQ(irq_nr) = 1<<28; /* set priority to 0 */
++}
++
++static inline void unmask_gic_int(unsigned int irq_nr)
++{
++	/* set prio mask to lower four bits and enable interrupt */
++	PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr];
++}
++
++static inline void mask_irq(unsigned int irq_nr)
++{
++	if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
++		modify_cp0_intmask(1 << irq_nr, 0);
++	} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
++		(irq_nr <= PNX8550_INT_GIC_MAX)) {
++		mask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
++	} else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
++		(irq_nr <= PNX8550_INT_TIMER_MAX)) {
++		modify_cp0_intmask(1 << 7, 0);
++	} else {
++		printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
++	}
++}
++
++static inline void unmask_irq(unsigned int irq_nr)
++{
++	if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
++		modify_cp0_intmask(0, 1 << irq_nr);
++	} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
++		(irq_nr <= PNX8550_INT_GIC_MAX)) {
++		unmask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
++	} else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
++		(irq_nr <= PNX8550_INT_TIMER_MAX)) {
++		modify_cp0_intmask(0, 1 << 7);
++	} else {
++		printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
++	}
++}
++
++#define pnx8550_disable pnx8550_ack
++static void pnx8550_ack(unsigned int irq)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&irq_lock, flags);
++	mask_irq(irq);
++	spin_unlock_irqrestore(&irq_lock, flags);
++}
++
++#define pnx8550_enable pnx8550_unmask
++static void pnx8550_unmask(unsigned int irq)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&irq_lock, flags);
++	unmask_irq(irq);
++	spin_unlock_irqrestore(&irq_lock, flags);
++}
++
++static unsigned int startup_irq(unsigned int irq_nr)
++{
++	pnx8550_unmask(irq_nr);
++	return 0;
++}
++
++static void shutdown_irq(unsigned int irq_nr)
++{
++	pnx8550_ack(irq_nr);
++	return;
++}
++
++int pnx8550_set_gic_priority(int irq, int priority)
++{
++	int gic_irq = irq-PNX8550_INT_GIC_MIN;
++	int prev_priority = PNX8550_GIC_REQ(gic_irq) & 0xf;
++
++        gic_prio[gic_irq] = priority;
++	PNX8550_GIC_REQ(gic_irq) |= (0x10000000 | gic_prio[gic_irq]);
++
++	return prev_priority;
++}
++
++static inline void mask_and_ack_level_irq(unsigned int irq)
++{
++	pnx8550_disable(irq);
++	return;
++}
++
++static void end_irq(unsigned int irq)
++{
++	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
++		pnx8550_enable(irq);
++	}
++}
++
++static struct hw_interrupt_type level_irq_type = {
++	.typename =	"PNX Level IRQ",
++	.startup =	startup_irq,
++	.shutdown =	shutdown_irq,
++	.enable =	pnx8550_enable,
++	.disable =	pnx8550_disable,
++	.ack =		mask_and_ack_level_irq,
++	.end =		end_irq,
++};
++
++static struct irqaction gic_action = {
++	.handler =	no_action,
++	.flags =	SA_INTERRUPT,
++	.name =		"GIC",
++};
++
++static struct irqaction timer_action = {
++	.handler =	no_action,
++	.flags =	SA_INTERRUPT,
++	.name =		"Timer",
++};
++
++void __init arch_init_irq(void)
++{
++	int i;
++	int configPR;
++
++	/* init of cp0 interrupts */
++	set_except_vector(0, cp0_irqdispatch);
++
++	for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
++		irq_desc[i].handler = &level_irq_type;
++		pnx8550_ack(i);	/* mask the irq just in case  */
++	}
++
++	/* init of GIC/IPC interrupts */
++	/* should be done before cp0 since cp0 init enables the GIC int */
++	for (i = PNX8550_INT_GIC_MIN; i <= PNX8550_INT_GIC_MAX; i++) {
++		int gic_int_line = i - PNX8550_INT_GIC_MIN;
++		if (gic_int_line == 0 )
++			continue;	// don't fiddle with int 0
++		/*
++		 * enable change of TARGET, ENABLE and ACTIVE_LOW bits
++		 * set TARGET        0 to route through hw0 interrupt
++		 * set ACTIVE_LOW    0 active high  (correct?)
++		 *
++		 * We really should setup an interrupt description table
++		 * to do this nicely.
++		 * Note, PCI INTA is active low on the bus, but inverted
++		 * in the GIC, so to us it's active high.
++		 */
++#ifdef CONFIG_PNX8550_V2PCI
++		if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) {
++			/* PCI INT through gpio 8, which is setup in
++			 * pnx8550_setup.c and routed to GPIO
++ 			 * Interrupt Level 0 (GPIO Connection 58).
++			 * Set it active low. */
++
++			PNX8550_GIC_REQ(gic_int_line) = 0x1E020000;
++		} else
++#endif
++		{
++			PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000;
++		}
++
++		/* mask/priority is still 0 so we will not get any
++		 * interrupts until it is unmasked */
++
++		irq_desc[i].handler = &level_irq_type;
++	}
++
++	/* Priority level 0 */
++	PNX8550_GIC_PRIMASK_0 = PNX8550_GIC_PRIMASK_1 = 0;
++
++	/* Set int vector table address */
++	PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0;
++
++	irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type;
++	setup_irq(MIPS_CPU_GIC_IRQ, &gic_action);
++
++	/* init of Timer interrupts */
++	for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) {
++		irq_desc[i].handler = &level_irq_type;
++	}
++
++	/* Stop Timer 1-3 */
++	configPR = read_c0_config7();
++	configPR |= 0x00000038;
++	write_c0_config7(configPR);
++
++	irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type;
++	setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action);
++}
++
++EXPORT_SYMBOL(pnx8550_set_gic_priority);
+diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/mipsIRQ.S
+@@ -0,0 +1,76 @@
++/*
++ * Copyright (c) 2002 Philips, Inc. All rights.
++ * Copyright (c) 2002 Red Hat, Inc. All rights.
++ *
++ * This software may be freely redistributed under the terms of the
++ * GNU General Public License.
++ *
++ * You 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.
++ *
++ * Based upon arch/mips/galileo-boards/ev64240/int-handler.S
++ *
++ */
++#include <asm/asm.h>
++#include <asm/mipsregs.h>
++#include <asm/addrspace.h>
++#include <asm/regdef.h>
++#include <asm/stackframe.h>
++
++/*
++ * cp0_irqdispatch
++ *
++ *    Code to handle in-core interrupt exception.
++ */
++
++		.align	5
++		.set	reorder
++		.set	noat
++		NESTED(cp0_irqdispatch, PT_SIZE, sp)
++		SAVE_ALL
++		CLI
++		.set	at
++		mfc0	t0,CP0_CAUSE
++		mfc0	t2,CP0_STATUS
++
++		and	t0,t2
++
++		andi	t1,t0,STATUSF_IP2 /* int0 hardware line */
++		bnez	t1,ll_hw0_irq
++		nop
++
++		andi	t1,t0,STATUSF_IP7 /* int5 hardware line */
++		bnez	t1,ll_timer_irq
++		nop
++
++		/* wrong alarm or masked ... */
++
++		j	spurious_interrupt
++		nop
++		END(cp0_irqdispatch)
++
++		.align	5
++		.set	reorder
++ll_hw0_irq:
++		li	a0,2
++		move	a1,sp
++		jal	hw0_irqdispatch
++		nop
++		j	ret_from_irq
++		nop
++
++		.align	5
++		.set	reorder
++ll_timer_irq:
++		mfc0	t3,CP0_CONFIG,7
++		andi	t4,t3,0x01c0
++		beqz	t4,ll_timer_out
++		nop
++		li	a0,7
++		move	a1,sp
++		jal	timer_irqdispatch
++		nop
++
++ll_timer_out:	j	ret_from_irq
++		nop
+diff --git a/arch/mips/philips/pnx8550/common/pci.c b/arch/mips/philips/pnx8550/common/pci.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/pci.c
+@@ -0,0 +1,133 @@
++/*
++ *
++ * BRIEF MODULE DESCRIPTION
++ *
++ * Author: source at mvista.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++
++#include <pci.h>
++#include <glb.h>
++#include <nand.h>
++
++static struct resource pci_io_resource = {
++	"pci IO space",
++	(u32)(PNX8550_PCIIO + 0x1000),	/* reserve regacy I/O space */
++	(u32)(PNX8550_PCIIO + PNX8550_PCIIO_SIZE),
++	IORESOURCE_IO
++};
++
++static struct resource pci_mem_resource = {
++	"pci memory space",
++	(u32)(PNX8550_PCIMEM),
++	(u32)(PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1),
++	IORESOURCE_MEM
++};
++
++extern struct pci_ops pnx8550_pci_ops;
++
++static struct pci_controller pnx8550_controller = {
++	.pci_ops	= &pnx8550_pci_ops,
++	.io_resource	= &pci_io_resource,
++	.mem_resource	= &pci_mem_resource,
++};
++
++/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
++static inline unsigned long get_system_mem_size(void)
++{
++	/* Read IP2031_RANK0_ADDR_LO */
++	unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
++	/* Read IP2031_RANK1_ADDR_HI */
++	unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
++
++	return dram_r1_hi - dram_r0_lo + 1;
++}
++
++static int __init pnx8550_pci_setup(void)
++{
++	int pci_mem_code;
++	int mem_size = get_system_mem_size() >> 20;
++
++	/* Clear the Global 2 Register, PCI Inta Output Enable Registers
++	   Bit 1:Enable DAC Powerdown
++	  -> 0:DACs are enabled and are working normally
++	     1:DACs are powerdown
++	   Bit 0:Enable of PCI inta output
++	  -> 0 = Disable PCI inta output
++	     1 = Enable PCI inta output
++	*/
++	PNX8550_GLB2_ENAB_INTA_O = 0;
++
++	/* Calc the PCI mem size code */
++	if (mem_size >= 128)
++		pci_mem_code = SIZE_128M;
++	else if (mem_size >= 64)
++		pci_mem_code = SIZE_64M;
++	else if (mem_size >= 32)
++		pci_mem_code = SIZE_32M;
++	else
++		pci_mem_code = SIZE_16M;
++
++	/* Set PCI_XIO registers */
++	outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
++	outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
++	outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
++	outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
++
++	/* Send memory transaction via PCI_BASE2 */
++	outl(0x00000001, PCI_BASE | PCI_IO);
++
++	/* Unlock the setup register */
++	outl(0xca, PCI_BASE | PCI_UNLOCKREG);
++
++	/*
++	 * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
++	 * to work, and in order for bus_to_baddr to work without any
++	 * hacks.
++	 */
++	outl(0x00000000, PCI_BASE | PCI_BASE10);
++
++	/*
++	 *These two bars are set by default or the boot code.
++	 * However, it's safer to set them here so we're not boot
++	 * code dependent.
++	 */
++	outl(0x1be00000, PCI_BASE | PCI_BASE14);  /* PNX MMIO */
++	outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18);  /* XIO      */
++
++	outl(PCI_EN_TA |
++	     PCI_EN_PCI2MMI |
++	     PCI_EN_XIO |
++	     PCI_SETUP_BASE18_SIZE(SIZE_32M) |
++	     PCI_SETUP_BASE18_EN |
++	     PCI_SETUP_BASE14_EN |
++	     PCI_SETUP_BASE10_PREF |
++	     PCI_SETUP_BASE10_SIZE(pci_mem_code) |
++	     PCI_SETUP_CFGMANAGE_EN |
++	     PCI_SETUP_PCIARB_EN,
++	     PCI_BASE |
++	     PCI_SETUP);	/* PCI_SETUP */
++	outl(0x00000000, PCI_BASE | PCI_CTRL);	/* PCI_CONTROL */
++
++	register_pci_controller(&pnx8550_controller);
++
++	return 0;
++}
++
++arch_initcall(pnx8550_pci_setup);
+diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/platform.c
+@@ -0,0 +1,135 @@
++/*
++ * Platform device support for Philips PNX8550 SoCs
++ *
++ * Copyright 2005, Embedded Alley Solutions, Inc
++ *
++ * Based on arch/mips/au1000/common/platform.c
++ * Platform device support for Au1x00 SoCs.
++ *
++ * Copyright 2004, Matt Porter <mporter at kernel.crashing.org>
++ *
++ * 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/device.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/resource.h>
++#include <linux/serial.h>
++#include <linux/serial_ip3106.h>
++
++#include <int.h>
++#include <usb.h>
++#include <uart.h>
++
++extern struct uart_ops ip3106_pops;
++
++static struct resource pnx8550_usb_ohci_resources[] = {
++	[0] = {
++		.start		= PNX8550_USB_OHCI_OP_BASE,
++		.end		= PNX8550_USB_OHCI_OP_BASE +
++				  PNX8550_USB_OHCI_OP_LEN,
++		.flags		= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start		= PNX8550_INT_USB,
++		.end		= PNX8550_INT_USB,
++		.flags		= IORESOURCE_IRQ,
++	},
++};
++
++static struct resource pnx8550_uart_resources[] = {
++	[0] = {
++		.start		= PNX8550_UART_PORT0,
++		.end		= PNX8550_UART_PORT0 + 0xfff,
++		.flags		= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start		= PNX8550_UART_INT(0),
++		.end		= PNX8550_UART_INT(0),
++		.flags		= IORESOURCE_IRQ,
++	},
++	[2] = {
++		.start		= PNX8550_UART_PORT1,
++		.end		= PNX8550_UART_PORT1 + 0xfff,
++		.flags		= IORESOURCE_MEM,
++	},
++	[3] = {
++		.start		= PNX8550_UART_INT(1),
++		.end		= PNX8550_UART_INT(1),
++		.flags		= IORESOURCE_IRQ,
++	},
++};
++
++struct ip3106_port ip3106_ports[] = {
++	[0] = {
++		.port   = {
++			.type		= PORT_IP3106,
++			.iotype		= SERIAL_IO_MEM,
++			.membase	= (void __iomem *)PNX8550_UART_PORT0,
++			.mapbase	= PNX8550_UART_PORT0,
++			.irq		= PNX8550_UART_INT(0),
++			.uartclk	= 3692300,
++			.fifosize	= 16,
++			.ops		= &ip3106_pops,
++			.flags		= ASYNC_BOOT_AUTOCONF,
++			.line		= 0,
++		},
++	},
++	[1] = {
++		.port   = {
++			.type		= PORT_IP3106,
++			.iotype		= SERIAL_IO_MEM,
++			.membase	= (void __iomem *)PNX8550_UART_PORT1,
++			.mapbase	= PNX8550_UART_PORT1,
++			.irq		= PNX8550_UART_INT(1),
++			.uartclk	= 3692300,
++			.fifosize	= 16,
++			.ops		= &ip3106_pops,
++			.flags		= ASYNC_BOOT_AUTOCONF,
++			.line		= 1,
++		},
++	},
++};
++
++/* The dmamask must be set for OHCI to work */
++static u64 ohci_dmamask = ~(u32)0;
++
++static u64 uart_dmamask = ~(u32)0;
++
++static struct platform_device pnx8550_usb_ohci_device = {
++	.name		= "pnx8550-ohci",
++	.id		= -1,
++	.dev = {
++		.dma_mask		= &ohci_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.num_resources	= ARRAY_SIZE(pnx8550_usb_ohci_resources),
++	.resource	= pnx8550_usb_ohci_resources,
++};
++
++static struct platform_device pnx8550_uart_device = {
++	.name		= "ip3106-uart",
++	.id		= -1,
++	.dev = {
++		.dma_mask		= &uart_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++		.platform_data = ip3106_ports,
++	},
++	.num_resources	= ARRAY_SIZE(pnx8550_uart_resources),
++	.resource	= pnx8550_uart_resources,
++};
++
++static struct platform_device *pnx8550_platform_devices[] __initdata = {
++	&pnx8550_usb_ohci_device,
++	&pnx8550_uart_device,
++};
++
++int pnx8550_platform_init(void)
++{
++	return platform_add_devices(pnx8550_platform_devices,
++			            ARRAY_SIZE(pnx8550_platform_devices));
++}
++
++arch_initcall(pnx8550_platform_init);
+diff --git a/arch/mips/philips/pnx8550/common/proc.c b/arch/mips/philips/pnx8550/common/proc.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/proc.c
+@@ -0,0 +1,113 @@
++/*
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/proc_fs.h>
++#include <linux/irq.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/kernel_stat.h>
++#include <linux/random.h>
++
++#include <asm/io.h>
++#include <asm/gdb-stub.h>
++#include <int.h>
++#include <uart.h>
++
++
++static int pnx8550_timers_read (char* page, char** start, off_t offset, int count, int* eof, void* data)
++{
++        int len = 0;
++	int configPR = read_c0_config7();
++
++        if (offset==0) {
++		len += sprintf(&page[len],"Timer:       count,  compare, tc, status\n");
++                len += sprintf(&page[len],"    1: %11i, %8i,  %1i, %s\n",
++			       read_c0_count(), read_c0_compare(),
++			      (configPR>>6)&0x1, ((configPR>>3)&0x1)? "off":"on");
++                len += sprintf(&page[len],"    2: %11i, %8i,  %1i, %s\n",
++			       read_c0_count2(), read_c0_compare2(),
++			      (configPR>>7)&0x1, ((configPR>>4)&0x1)? "off":"on");
++                len += sprintf(&page[len],"    3: %11i, %8i,  %1i, %s\n",
++			       read_c0_count3(), read_c0_compare3(),
++			      (configPR>>8)&0x1, ((configPR>>5)&0x1)? "off":"on");
++        }
++
++        return len;
++}
++
++static int pnx8550_registers_read (char* page, char** start, off_t offset, int count, int* eof, void* data)
++{
++        int len = 0;
++
++        if (offset==0) {
++                len += sprintf(&page[len],"config1:   %#10.8x\n",read_c0_config1());
++                len += sprintf(&page[len],"config2:   %#10.8x\n",read_c0_config2());
++                len += sprintf(&page[len],"config3:   %#10.8x\n",read_c0_config3());
++                len += sprintf(&page[len],"configPR:  %#10.8x\n",read_c0_config7());
++                len += sprintf(&page[len],"status:    %#10.8x\n",read_c0_status());
++                len += sprintf(&page[len],"cause:     %#10.8x\n",read_c0_cause());
++                len += sprintf(&page[len],"count:     %#10.8x\n",read_c0_count());
++                len += sprintf(&page[len],"count_2:   %#10.8x\n",read_c0_count2());
++                len += sprintf(&page[len],"count_3:   %#10.8x\n",read_c0_count3());
++                len += sprintf(&page[len],"compare:   %#10.8x\n",read_c0_compare());
++                len += sprintf(&page[len],"compare_2: %#10.8x\n",read_c0_compare2());
++                len += sprintf(&page[len],"compare_3: %#10.8x\n",read_c0_compare3());
++        }
++
++        return len;
++}
++
++static struct proc_dir_entry* pnx8550_dir        = NULL;
++static struct proc_dir_entry* pnx8550_timers     = NULL;
++static struct proc_dir_entry* pnx8550_registers  = NULL;
++
++static int pnx8550_proc_init( void )
++{
++
++	// Create /proc/pnx8550
++        pnx8550_dir = create_proc_entry("pnx8550", S_IFDIR|S_IRUGO, NULL);
++        if (pnx8550_dir){
++                pnx8550_dir->nlink = 1;
++        }
++        else {
++                printk(KERN_ERR "Can't create pnx8550 proc dir\n");
++                return -1;
++        }
++
++	// Create /proc/pnx8550/timers
++        pnx8550_timers = create_proc_entry("timers", S_IFREG|S_IRUGO, pnx8550_dir );
++        if (pnx8550_timers){
++                pnx8550_timers->nlink = 1;
++                pnx8550_timers->read_proc = pnx8550_timers_read;
++        }
++        else {
++                printk(KERN_ERR "Can't create pnx8550 timers proc file\n");
++        }
++
++	// Create /proc/pnx8550/registers
++        pnx8550_registers = create_proc_entry("registers", S_IFREG|S_IRUGO, pnx8550_dir );
++        if (pnx8550_registers){
++                pnx8550_registers->nlink = 1;
++                pnx8550_registers->read_proc = pnx8550_registers_read;
++        }
++        else {
++                printk(KERN_ERR "Can't create pnx8550 registers proc file\n");
++        }
++
++	return 0;
++}
++
++__initcall(pnx8550_proc_init);
+diff --git a/arch/mips/philips/pnx8550/common/prom.c b/arch/mips/philips/pnx8550/common/prom.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/prom.c
+@@ -0,0 +1,138 @@
++/*
++ *
++ * Per Hallsmark, per.hallsmark at mvista.com
++ *
++ * Based on jmr3927/common/prom.c
++ *
++ * 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/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/string.h>
++#include <linux/serial_ip3106.h>
++
++#include <asm/bootinfo.h>
++#include <uart.h>
++
++/* #define DEBUG_CMDLINE */
++
++extern int prom_argc;
++extern char **prom_argv, **prom_envp;
++
++typedef struct
++{
++    char *name;
++/*    char *val; */
++}t_env_var;
++
++
++char * prom_getcmdline(void)
++{
++	return &(arcs_cmdline[0]);
++}
++
++void  prom_init_cmdline(void)
++{
++	char *cp;
++	int actr;
++
++	actr = 1; /* Always ignore argv[0] */
++
++	cp = &(arcs_cmdline[0]);
++	while(actr < prom_argc) {
++	        strcpy(cp, prom_argv[actr]);
++		cp += strlen(prom_argv[actr]);
++		*cp++ = ' ';
++		actr++;
++	}
++	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
++		--cp;
++	*cp = '\0';
++}
++
++char *prom_getenv(char *envname)
++{
++	/*
++	 * Return a pointer to the given environment variable.
++	 * Environment variables are stored in the form of "memsize=64".
++	 */
++
++	t_env_var *env = (t_env_var *)prom_envp;
++	int i;
++
++	i = strlen(envname);
++
++	while(env->name) {
++		if(strncmp(envname, env->name, i) == 0) {
++			return(env->name + strlen(envname) + 1);
++		}
++		env++;
++	}
++	return(NULL);
++}
++
++inline unsigned char str2hexnum(unsigned char c)
++{
++	if(c >= '0' && c <= '9')
++		return c - '0';
++	if(c >= 'a' && c <= 'f')
++		return c - 'a' + 10;
++	if(c >= 'A' && c <= 'F')
++		return c - 'A' + 10;
++	return 0; /* foo */
++}
++
++inline void str2eaddr(unsigned char *ea, unsigned char *str)
++{
++	int i;
++
++	for(i = 0; i < 6; i++) {
++		unsigned char num;
++
++		if((*str == '.') || (*str == ':'))
++			str++;
++		num = str2hexnum(*str++) << 4;
++		num |= (str2hexnum(*str++));
++		ea[i] = num;
++	}
++}
++
++int get_ethernet_addr(char *ethernet_addr)
++{
++        char *ethaddr_str;
++
++        ethaddr_str = prom_getenv("ethaddr");
++	if (!ethaddr_str) {
++	        printk("ethaddr not set in boot prom\n");
++		return -1;
++	}
++	str2eaddr(ethernet_addr, ethaddr_str);
++	return 0;
++}
++
++unsigned long __init prom_free_prom_memory(void)
++{
++	return 0;
++}
++
++extern int pnx8550_console_port;
++
++/* used by prom_printf */
++void prom_putchar(char c)
++{
++	if (pnx8550_console_port != -1) {
++		/* Wait until FIFO not full */
++		while( ((ip3106_fifo(UART_BASE, pnx8550_console_port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16)
++			;
++		/* Send one char */
++		ip3106_fifo(UART_BASE, pnx8550_console_port) = c;
++	}
++}
++
++EXPORT_SYMBOL(prom_getcmdline);
++EXPORT_SYMBOL(get_ethernet_addr);
++EXPORT_SYMBOL(str2eaddr);
+diff --git a/arch/mips/philips/pnx8550/common/reset.c b/arch/mips/philips/pnx8550/common/reset.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/reset.c
+@@ -0,0 +1,49 @@
++/*.
++ *
++ * ########################################################################
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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.
++ *
++ * ########################################################################
++ *
++ * Reset the PNX8550 board.
++ *
++ */
++#include <linux/slab.h>
++#include <asm/reboot.h>
++#include <glb.h>
++
++void pnx8550_machine_restart(char *command)
++{
++	char head[] = "************* Machine restart *************";
++	char foot[] = "*******************************************";
++
++	printk("\n\n");
++	printk("%s\n", head);
++	if (command != NULL)
++		printk("* %s\n", command);
++	printk("%s\n", foot);
++
++	PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST;
++}
++
++void pnx8550_machine_halt(void)
++{
++	printk("*** Machine halt. (Not implemented) ***\n");
++}
++
++void pnx8550_machine_power_off(void)
++{
++	printk("*** Machine power off.  (Not implemented) ***\n");
++}
+diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/setup.c
+@@ -0,0 +1,149 @@
++/*
++ *
++ * 2.6 port, Embedded Alley Solutions, Inc
++ *
++ *  Based on Per Hallsmark, per.hallsmark at mvista.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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/config.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/ioport.h>
++#include <linux/mm.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/serial_ip3106.h>
++
++#include <asm/cpu.h>
++#include <asm/bootinfo.h>
++#include <asm/irq.h>
++#include <asm/mipsregs.h>
++#include <asm/reboot.h>
++#include <asm/pgtable.h>
++#include <asm/time.h>
++
++#include <glb.h>
++#include <int.h>
++#include <pci.h>
++#include <uart.h>
++#include <nand.h>
++
++extern void prom_printf(char *fmt, ...);
++
++extern void __init board_setup(void);
++extern void pnx8550_machine_restart(char *);
++extern void pnx8550_machine_halt(void);
++extern void pnx8550_machine_power_off(void);
++extern struct resource ioport_resource;
++extern struct resource iomem_resource;
++extern void (*board_time_init)(void);
++extern void pnx8550_time_init(void);
++extern void (*board_timer_setup)(struct irqaction *irq);
++extern void pnx8550_timer_setup(struct irqaction *irq);
++extern void rs_kgdb_hook(int tty_no);
++extern void prom_printf(char *fmt, ...);
++extern char *prom_getcmdline(void);
++
++struct resource standard_io_resources[] = {
++	{"dma1", 0x00, 0x1f, IORESOURCE_BUSY},
++	{"timer", 0x40, 0x5f, IORESOURCE_BUSY},
++	{"dma page reg", 0x80, 0x8f, IORESOURCE_BUSY},
++	{"dma2", 0xc0, 0xdf, IORESOURCE_BUSY},
++};
++
++#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
++
++extern struct resource pci_io_resource;
++extern struct resource pci_mem_resource;
++
++/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
++unsigned long get_system_mem_size(void)
++{
++	/* Read IP2031_RANK0_ADDR_LO */
++	unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
++	/* Read IP2031_RANK1_ADDR_HI */
++	unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
++
++	return dram_r1_hi - dram_r0_lo + 1;
++}
++
++int pnx8550_console_port = -1;
++
++void __init plat_setup(void)
++{
++	int i;
++	char* argptr;
++
++	board_setup();  /* board specific setup */
++
++        _machine_restart = pnx8550_machine_restart;
++        _machine_halt = pnx8550_machine_halt;
++        _machine_power_off = pnx8550_machine_power_off;
++
++	board_time_init = pnx8550_time_init;
++	board_timer_setup = pnx8550_timer_setup;
++
++	/* Clear the Global 2 Register, PCI Inta Output Enable Registers
++	   Bit 1:Enable DAC Powerdown
++	  -> 0:DACs are enabled and are working normally
++	     1:DACs are powerdown
++	   Bit 0:Enable of PCI inta output
++	  -> 0 = Disable PCI inta output
++	     1 = Enable PCI inta output
++	*/
++	PNX8550_GLB2_ENAB_INTA_O = 0;
++
++	/* IO/MEM resources. */
++	set_io_port_base(KSEG1);
++	ioport_resource.start = 0;
++	ioport_resource.end = ~0;
++	iomem_resource.start = 0;
++	iomem_resource.end = ~0;
++
++	/* Request I/O space for devices on this board */
++	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
++		request_resource(&ioport_resource, standard_io_resources + i);
++
++	/* Place the Mode Control bit for GPIO pin 16 in primary function */
++	/* Pin 16 is used by UART1, UA1_TX                                */
++	outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
++			(PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
++			PNX8550_GPIO_MC1);
++
++	argptr = prom_getcmdline();
++	if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
++		argptr += strlen("console=ttyS");
++		pnx8550_console_port = *argptr == '0' ? 0 : 1;
++
++		/* We must initialize the UART (console) before prom_printf */
++		/* Set LCR to 8-bit and BAUD to 38400 (no 5)                */
++		ip3106_lcr(UART_BASE, pnx8550_console_port) =
++			IP3106_UART_LCR_8BIT;
++		ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
++	}
++
++#ifdef CONFIG_KGDB
++	argptr = prom_getcmdline();
++	if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
++		int line;
++		argptr += strlen("kgdb=ttyS");
++		line = *argptr == '0' ? 0 : 1;
++		rs_kgdb_hook(line);
++		prom_printf("KGDB: Using ttyS%i for session, "
++				"please connect your debugger\n", line ? 1 : 0);
++	}
++#endif
++	return;
++}
+diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/common/time.c
+@@ -0,0 +1,105 @@
++/*
++ * Copyright 2001, 2002, 2003 MontaVista Software Inc.
++ * Author: Jun Sun, jsun at mvista.com or jsun at junsun.net
++ *
++ * Common time service routines for MIPS machines. See
++ * Documents/MIPS/README.txt.
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the 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/kernel.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/param.h>
++#include <linux/time.h>
++#include <linux/timer.h>
++#include <linux/smp.h>
++#include <linux/kernel_stat.h>
++#include <linux/spinlock.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++
++#include <asm/bootinfo.h>
++#include <asm/cpu.h>
++#include <asm/time.h>
++#include <asm/hardirq.h>
++#include <asm/div64.h>
++#include <asm/debug.h>
++
++#include <int.h>
++#include <cm.h>
++
++extern unsigned int mips_hpt_frequency;
++
++/*
++ * pnx8550_time_init() - it does the following things:
++ *
++ * 1) board_time_init() -
++ * 	a) (optional) set up RTC routines,
++ *      b) (optional) calibrate and set the mips_hpt_frequency
++ *	    (only needed if you intended to use fixed_rate_gettimeoffset
++ *	     or use cpu counter as timer interrupt source)
++ */
++
++void pnx8550_time_init(void)
++{
++	unsigned int             n;
++	unsigned int             m;
++	unsigned int             p;
++	unsigned int             pow2p;
++
++        /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */
++        /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1:  FIXME) */
++
++        n = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_N_MASK) >> 16;
++        m = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_M_MASK) >> 8;
++        p = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_P_MASK) >> 2;
++	pow2p = (1 << p);
++
++	db_assert(m != 0 && pow2p != 0);
++
++        /*
++	 * Compute the frequency as in the PNX8550 User Manual 1.0, p.186
++	 * (a.k.a. 8-10).  Divide by HZ for a timer offset that results in
++	 * HZ timer interrupts per second.
++	 */
++	mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p));
++}
++
++/*
++ * pnx8550_timer_setup() - it does the following things:
++ *
++ * 5) board_timer_setup() -
++ *	a) (optional) over-write any choices made above by time_init().
++ *	b) machine specific code should setup the timer irqaction.
++ *	c) enable the timer interrupt
++ */
++
++void __init pnx8550_timer_setup(struct irqaction *irq)
++{
++	int configPR;
++
++	setup_irq(PNX8550_INT_TIMER1, irq);
++
++	/* Start timer1 */
++	configPR = read_c0_config7();
++	configPR &= ~0x00000008;
++	write_c0_config7(configPR);
++
++	/* Timer 2 stop */
++	configPR = read_c0_config7();
++	configPR |= 0x00000010;
++	write_c0_config7(configPR);
++
++	write_c0_count2(0);
++	write_c0_compare2(0xffffffff);
++
++	/* Timer 3 stop */
++	configPR = read_c0_config7();
++	configPR |= 0x00000020;
++	write_c0_config7(configPR);
++}
+diff --git a/arch/mips/philips/pnx8550/jbs/Makefile b/arch/mips/philips/pnx8550/jbs/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/jbs/Makefile
+@@ -0,0 +1,4 @@
++
++# Makefile for the Philips JBS Board.
++
++lib-y := init.o board_setup.o irqmap.o
+diff --git a/arch/mips/philips/pnx8550/jbs/board_setup.c b/arch/mips/philips/pnx8550/jbs/board_setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/jbs/board_setup.c
+@@ -0,0 +1,65 @@
++/*
++ *  JBS Specific board startup routines.
++ *
++ *  Copyright 2005, Embedded Alley Solutions, 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  SOFTWARE  IS PROVIDED   ``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 AUTHOR  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.
++ *
++ *  You 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/sched.h>
++#include <linux/ioport.h>
++#include <linux/mm.h>
++#include <linux/console.h>
++#include <linux/mc146818rtc.h>
++#include <linux/delay.h>
++
++#include <asm/cpu.h>
++#include <asm/bootinfo.h>
++#include <asm/irq.h>
++#include <asm/mipsregs.h>
++#include <asm/reboot.h>
++#include <asm/pgtable.h>
++
++#include <glb.h>
++
++/* CP0 hazard avoidance. */
++#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
++				     "nop; nop; nop; nop; nop; nop;\n\t" \
++				     ".set reorder\n\t")
++
++void __init board_setup(void)
++{
++	unsigned long config0, configpr;
++
++	config0 = read_c0_config();
++
++	/* clear all three cache coherency fields */
++	config0 &= ~(0x7 | (7<<25) | (7<<28));
++	config0 |= (CONF_CM_DEFAULT | (CONF_CM_DEFAULT<<25) |
++			(CONF_CM_DEFAULT<<28));
++	write_c0_config(config0);
++	BARRIER;
++
++	configpr = read_c0_config7();
++	configpr |= (1<<19); /* enable tlb */
++	write_c0_config7(configpr);
++	BARRIER;
++}
+diff --git a/arch/mips/philips/pnx8550/jbs/init.c b/arch/mips/philips/pnx8550/jbs/init.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/jbs/init.c
+@@ -0,0 +1,57 @@
++/*
++ *
++ *  Copyright 2005 Embedded Alley Solutions, Inc
++ *  source at embeddedalley.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  SOFTWARE  IS PROVIDED   ``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 AUTHOR  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.
++ *
++ *  You 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/mm.h>
++#include <linux/sched.h>
++#include <linux/bootmem.h>
++#include <asm/addrspace.h>
++#include <asm/bootinfo.h>
++#include <linux/string.h>
++#include <linux/kernel.h>
++
++int prom_argc;
++char **prom_argv, **prom_envp;
++extern void  __init prom_init_cmdline(void);
++extern char *prom_getenv(char *envname);
++
++const char *get_system_type(void)
++{
++	return "Philips PNX8550/JBS";
++}
++
++void __init prom_init(void)
++{
++
++	unsigned long memsize;
++
++	mips_machgroup = MACH_GROUP_PHILIPS;
++	mips_machtype = MACH_PHILIPS_JBS;
++
++	//memsize = 0x02800000; /* Trimedia uses memory above */
++	memsize = 0x08000000; /* Trimedia uses memory above */
++	add_memory_region(0, memsize, BOOT_MEM_RAM);
++}
+diff --git a/arch/mips/philips/pnx8550/jbs/irqmap.c b/arch/mips/philips/pnx8550/jbs/irqmap.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/philips/pnx8550/jbs/irqmap.c
+@@ -0,0 +1,36 @@
++/*
++ *  Philips JBS board irqmap.
++ *
++ *  Copyright 2005 Embedded Alley Solutions, Inc
++ *  source at embeddealley.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  SOFTWARE  IS PROVIDED	  ``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 AUTHOR  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.
++ *
++ *  You 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 <int.h>
++
++char irq_tab_jbs[][5] __initdata = {
++ [8] =	{ -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
++ [9] =	{ -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
++ [17] =	{ -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
++};
++
+diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/pmc-sierra/Kconfig
+@@ -0,0 +1,3 @@
++config HYPERTRANSPORT
++	bool "Hypertransport Support for PMC-Sierra Yosemite"
++	depends on PMC_YOSEMITE
+diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
+--- a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
++++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
+@@ -34,7 +34,6 @@
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+-#include <linux/version.h>
+ #include <asm/pci.h>
+ #include <asm/io.h>
+ #include <linux/init.h>
+diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
+--- a/arch/mips/pmc-sierra/yosemite/ht-irq.c
++++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c
+@@ -26,7 +26,6 @@
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+-#include <linux/version.h>
+ #include <linux/init.h>
+ #include <asm/pci.h>
+ 
+diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c
+--- a/arch/mips/pmc-sierra/yosemite/ht.c
++++ b/arch/mips/pmc-sierra/yosemite/ht.c
+@@ -28,7 +28,6 @@
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+-#include <linux/version.h>
+ #include <asm/pci.h>
+ #include <asm/io.h>
+ 
+diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
+--- a/arch/mips/pmc-sierra/yosemite/prom.c
++++ b/arch/mips/pmc-sierra/yosemite/prom.c
+@@ -132,8 +132,9 @@ void __init prom_init(void)
+ 	prom_grab_secondary();
+ }
+ 
+-void __init prom_free_prom_memory(void)
++unsigned long __init prom_free_prom_memory(void)
+ {
++	return 0;
+ }
+ 
+ void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
+--- a/arch/mips/pmc-sierra/yosemite/setup.c
++++ b/arch/mips/pmc-sierra/yosemite/setup.c
+@@ -212,7 +212,7 @@ static void __init py_late_time_init(voi
+ 	py_rtc_setup();
+ }
+ 
+-static int __init pmc_yosemite_setup(void)
++void __init plat_setup(void)
+ {
+ 	board_time_init = yosemite_time_init;
+ 	late_time_init = py_late_time_init;
+@@ -228,8 +228,4 @@ static int __init pmc_yosemite_setup(voi
+ 	OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR);
+ 	OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0);
+ #endif
+-
+-	return 0;
+ }
+-
+-early_initcall(pmc_yosemite_setup);
+diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
+--- a/arch/mips/pmc-sierra/yosemite/smp.c
++++ b/arch/mips/pmc-sierra/yosemite/smp.c
+@@ -9,7 +9,7 @@ extern void (*mips_hpt_init)(unsigned in
+ 
+ #define LAUNCHSTACK_SIZE 256
+ 
+-static spinlock_t launch_lock __initdata;
++static __initdata DEFINE_SPINLOCK(launch_lock);
+ 
+ static unsigned long secondary_sp __initdata;
+ static unsigned long secondary_gp __initdata;
+diff --git a/arch/mips/qemu/q-setup.c b/arch/mips/qemu/q-setup.c
+--- a/arch/mips/qemu/q-setup.c
++++ b/arch/mips/qemu/q-setup.c
+@@ -4,6 +4,11 @@
+ 
+ #define QEMU_PORT_BASE 0xb4000000
+ 
++const char *get_system_type(void)
++{
++	return "Qemu";
++}
++
+ static void __init qemu_timer_setup(struct irqaction *irq)
+ {
+ 	/* set the clock to 100 Hz */
+diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c
+--- a/arch/mips/sgi-ip22/ip22-eisa.c
++++ b/arch/mips/sgi-ip22/ip22-eisa.c
+@@ -29,6 +29,7 @@
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
++#include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/mipsregs.h>
+ #include <asm/addrspace.h>
+@@ -37,42 +38,29 @@
+ #include <asm/sgi/mc.h>
+ #include <asm/sgi/ip22.h>
+ 
+-#define EISA_MAX_SLOTS		  4
++/* I2 has four EISA slots. */
++#define IP22_EISA_MAX_SLOTS	  4
+ #define EISA_MAX_IRQ             16
+ 
+-#define EISA_TO_PHYS(x)  (0x00080000 | (x))
+-#define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x))))
++#define EIU_MODE_REG     0x0001ffc0
++#define EIU_STAT_REG     0x0001ffc4
++#define EIU_PREMPT_REG   0x0001ffc8
++#define EIU_QUIET_REG    0x0001ffcc
++#define EIU_INTRPT_ACK   0x00010004
++
++static char __init *decode_eisa_sig(unsigned long addr)
++{
++        static char sig_str[EISA_SIG_LEN];
++	u8 sig[4];
++        u16 rev;
++	int i;
+ 
+-#define EIU_MODE_REG     0x0009ffc0
+-#define EIU_STAT_REG     0x0009ffc4
+-#define EIU_PREMPT_REG   0x0009ffc8
+-#define EIU_QUIET_REG    0x0009ffcc
+-#define EIU_INTRPT_ACK   0x00090004
+-
+-#define EISA_DMA1_STATUS            8
+-#define EISA_INT1_CTRL           0x20
+-#define EISA_INT1_MASK           0x21
+-#define EISA_INT2_CTRL           0xA0
+-#define EISA_INT2_MASK           0xA1
+-#define EISA_DMA2_STATUS         0xD0
+-#define EISA_DMA2_WRITE_SINGLE   0xD4
+-#define EISA_EXT_NMI_RESET_CTRL 0x461
+-#define EISA_INT1_EDGE_LEVEL    0x4D0
+-#define EISA_INT2_EDGE_LEVEL    0x4D1
+-#define EISA_VENDOR_ID_OFFSET   0xC80
+-
+-#define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); }
+-#define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x))
+-#define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); }
+-#define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x))
++	for (i = 0; i < 4; i++) {
++		sig[i] = inb (addr + i);
+ 
+-static char *decode_eisa_sig(u8 * sig)
+-{
+-	static char sig_str[8];
+-	u16 rev;
+-
+-	if (sig[0] & 0x80)
+-		return NULL;
++		if (!i && (sig[0] & 0x80))
++			return NULL;
++	}
+ 
+ 	sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
+ 	sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
+@@ -83,23 +71,26 @@ static char *decode_eisa_sig(u8 * sig)
+ 	return sig_str;
+ }
+ 
+-static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	u8 eisa_irq;
+ 	u8 dma1, dma2;
+ 
+-	eisa_irq = EIU_READ_8(EIU_INTRPT_ACK);
+-	dma1 = EISA_READ_8(EISA_DMA1_STATUS);
+-	dma2 = EISA_READ_8(EISA_DMA2_STATUS);
+-
+-	if (eisa_irq >= EISA_MAX_IRQ) {
+-		/* Oops, Bad Stuff Happened... */
+-		printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
+-
+-		EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+-		EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+-	} else
++	eisa_irq = inb(EIU_INTRPT_ACK);
++	dma1 = inb(EISA_DMA1_STATUS);
++	dma2 = inb(EISA_DMA2_STATUS);
++
++	if (eisa_irq < EISA_MAX_IRQ) {
+ 		do_IRQ(eisa_irq, regs);
++		return IRQ_HANDLED;
++	}
++
++	/* Oops, Bad Stuff Happened... */
++	printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
++
++	outb(0x20, EISA_INT2_CTRL);
++	outb(0x20, EISA_INT1_CTRL);
++	return IRQ_NONE;
+ }
+ 
+ static void enable_eisa1_irq(unsigned int irq)
+@@ -109,9 +100,9 @@ static void enable_eisa1_irq(unsigned in
+ 
+ 	local_irq_save(flags);
+ 
+-	mask = EISA_READ_8(EISA_INT1_MASK);
++	mask = inb(EISA_INT1_MASK);
+ 	mask &= ~((u8) (1 << irq));
+-	EISA_WRITE_8(EISA_INT1_MASK, mask);
++	outb(mask, EISA_INT1_MASK);
+ 
+ 	local_irq_restore(flags);
+ }
+@@ -122,9 +113,9 @@ static unsigned int startup_eisa1_irq(un
+ 
+ 	/* Only use edge interrupts for EISA */
+ 
+-	edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL);
++	edge = inb(EISA_INT1_EDGE_LEVEL);
+ 	edge &= ~((u8) (1 << irq));
+-	EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge);
++	outb(edge, EISA_INT1_EDGE_LEVEL);
+ 
+ 	enable_eisa1_irq(irq);
+ 	return 0;
+@@ -134,9 +125,9 @@ static void disable_eisa1_irq(unsigned i
+ {
+ 	u8 mask;
+ 
+-	mask = EISA_READ_8(EISA_INT1_MASK);
++	mask = inb(EISA_INT1_MASK);
+ 	mask |= ((u8) (1 << irq));
+-	EISA_WRITE_8(EISA_INT1_MASK, mask);
++	outb(mask, EISA_INT1_MASK);
+ }
+ 
+ #define shutdown_eisa1_irq	disable_eisa1_irq
+@@ -145,7 +136,7 @@ static void mask_and_ack_eisa1_irq(unsig
+ {
+ 	disable_eisa1_irq(irq);
+ 
+-	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
++	outb(0x20, EISA_INT1_CTRL);
+ }
+ 
+ static void end_eisa1_irq(unsigned int irq)
+@@ -171,9 +162,9 @@ static void enable_eisa2_irq(unsigned in
+ 
+ 	local_irq_save(flags);
+ 
+-	mask = EISA_READ_8(EISA_INT2_MASK);
++	mask = inb(EISA_INT2_MASK);
+ 	mask &= ~((u8) (1 << (irq - 8)));
+-	EISA_WRITE_8(EISA_INT2_MASK, mask);
++	outb(mask, EISA_INT2_MASK);
+ 
+ 	local_irq_restore(flags);
+ }
+@@ -184,9 +175,9 @@ static unsigned int startup_eisa2_irq(un
+ 
+ 	/* Only use edge interrupts for EISA */
+ 
+-	edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL);
++	edge = inb(EISA_INT2_EDGE_LEVEL);
+ 	edge &= ~((u8) (1 << (irq - 8)));
+-	EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge);
++	outb(edge, EISA_INT2_EDGE_LEVEL);
+ 
+ 	enable_eisa2_irq(irq);
+ 	return 0;
+@@ -196,9 +187,9 @@ static void disable_eisa2_irq(unsigned i
+ {
+ 	u8 mask;
+ 
+-	mask = EISA_READ_8(EISA_INT2_MASK);
++	mask = inb(EISA_INT2_MASK);
+ 	mask |= ((u8) (1 << (irq - 8)));
+-	EISA_WRITE_8(EISA_INT2_MASK, mask);
++	outb(mask, EISA_INT2_MASK);
+ }
+ 
+ #define shutdown_eisa2_irq	disable_eisa2_irq
+@@ -207,8 +198,7 @@ static void mask_and_ack_eisa2_irq(unsig
+ {
+ 	disable_eisa2_irq(irq);
+ 
+-	EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+-	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
++	outb(0x20, EISA_INT2_CTRL);
+ }
+ 
+ static void end_eisa2_irq(unsigned int irq)
+@@ -241,7 +231,6 @@ int __init ip22_eisa_init(void)
+ {
+ 	int i, c;
+ 	char *str;
+-	u8 *slot_addr;
+ 
+ 	if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
+ 		printk(KERN_INFO "EISA: bus not present.\n");
+@@ -249,11 +238,8 @@ int __init ip22_eisa_init(void)
+ 	}
+ 
+ 	printk(KERN_INFO "EISA: Probing bus...\n");
+-	for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) {
+-		slot_addr =
+-		    (u8 *) EISA_TO_KSEG1((0x1000 * i) +
+-					 EISA_VENDOR_ID_OFFSET);
+-		if ((str = decode_eisa_sig(slot_addr))) {
++	for (c = 0, i = 1; i <= IP22_EISA_MAX_SLOTS; i++) {
++		if ((str = decode_eisa_sig(0x1000 * i + EISA_VENDOR_ID_OFFSET))) {
+ 			printk(KERN_INFO "EISA: slot %d : %s detected.\n",
+ 			       i, str);
+ 			c++;
+@@ -268,25 +254,25 @@ int __init ip22_eisa_init(void)
+ 	   Please wave your favorite dead chicken over the busses */
+ 
+ 	/* First say hello to the EIU */
+-	EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF);
+-	EIU_WRITE_32(EIU_QUIET_REG, 1);
+-	EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F);
++	outl(0x0000FFFF, EIU_PREMPT_REG);
++	outl(1, EIU_QUIET_REG);
++	outl(0x40f3c07F, EIU_MODE_REG);
+ 
+ 	/* Now be nice to the EISA chipset */
+-	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1);
+-	for (i = 0; i < 10000; i++);	/* Wait long enough for the dust to settle */
+-	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0);
+-	EISA_WRITE_8(EISA_INT1_CTRL, 0x11);
+-	EISA_WRITE_8(EISA_INT2_CTRL, 0x11);
+-	EISA_WRITE_8(EISA_INT1_MASK, 0);
+-	EISA_WRITE_8(EISA_INT2_MASK, 8);
+-	EISA_WRITE_8(EISA_INT1_MASK, 4);
+-	EISA_WRITE_8(EISA_INT2_MASK, 2);
+-	EISA_WRITE_8(EISA_INT1_MASK, 1);
+-	EISA_WRITE_8(EISA_INT2_MASK, 1);
+-	EISA_WRITE_8(EISA_INT1_MASK, 0xfb);
+-	EISA_WRITE_8(EISA_INT2_MASK, 0xff);
+-	EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0);
++	outb(1, EISA_EXT_NMI_RESET_CTRL);
++	udelay(50);	/* Wait long enough for the dust to settle */
++	outb(0, EISA_EXT_NMI_RESET_CTRL);
++	outb(0x11, EISA_INT1_CTRL);
++	outb(0x11, EISA_INT2_CTRL);
++	outb(0, EISA_INT1_MASK);
++	outb(8, EISA_INT2_MASK);
++	outb(4, EISA_INT1_MASK);
++	outb(2, EISA_INT2_MASK);
++	outb(1, EISA_INT1_MASK);
++	outb(1, EISA_INT2_MASK);
++	outb(0xfb, EISA_INT1_MASK);
++	outb(0xff, EISA_INT2_MASK);
++	outb(0, EISA_DMA2_WRITE_SINGLE);
+ 
+ 	for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) {
+ 		irq_desc[i].status = IRQ_DISABLED;
+diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
+--- a/arch/mips/sgi-ip22/ip22-setup.c
++++ b/arch/mips/sgi-ip22/ip22-setup.c
+@@ -53,7 +53,7 @@ EXPORT_SYMBOL(ip22_do_break);
+ extern void ip22_be_init(void) __init;
+ extern void ip22_time_init(void) __init;
+ 
+-static int __init ip22_setup(void)
++void __init plat_setup(void)
+ {
+ 	char *ctype;
+ 
+@@ -137,8 +137,4 @@ static int __init ip22_setup(void)
+ 		}
+ 	}
+ #endif
+-
+-	return 0;
+ }
+-
+-early_initcall(ip22_setup);
+diff --git a/arch/mips/sgi-ip27/Kconfig b/arch/mips/sgi-ip27/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/sgi-ip27/Kconfig
+@@ -0,0 +1,54 @@
++#config SGI_SN0_XXL
++#	bool "IP27 XXL"
++#	depends on SGI_IP27
++#	  This options adds support for userspace processes upto 16TB size.
++#	  Normally the limit is just .5TB.
++
++config SGI_SN0_N_MODE
++	bool "IP27 N-Mode"
++	depends on SGI_IP27
++	help
++	  The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be
++	  configured in either N-Modes which allows for more nodes or M-Mode
++	  which allows for more memory.  Your system is most probably
++	  running in M-Mode, so you should say N here.
++
++config ARCH_DISCONTIGMEM_ENABLE
++	bool
++	default y if SGI_IP27
++	help
++	  Say Y to upport efficient handling of discontiguous physical memory,
++	  for architectures which are either NUMA (Non-Uniform Memory Access)
++	  or have huge holes in the physical address space for other reasons.
++	  See <file:Documentation/vm/numa> for more.
++
++config NUMA
++	bool "NUMA Support"
++	depends on SGI_IP27
++	help
++	  Say Y to compile the kernel to support NUMA (Non-Uniform Memory
++	  Access).  This option is for configuring high-end multiprocessor
++	  server machines.  If in doubt, say N.
++
++config MAPPED_KERNEL
++	bool "Mapped kernel support"
++	depends on SGI_IP27
++	help
++	  Change the way a Linux kernel is loaded into memory on a MIPS64
++	  machine.  This is required in order to support text replication and
++	  NUMA.  If you need to understand it, read the source code.
++
++config REPLICATE_KTEXT
++	bool "Kernel text replication support"
++	depends on SGI_IP27
++	help
++	  Say Y here to enable replicating the kernel text across multiple
++	  nodes in a NUMA cluster.  This trades memory for speed.
++
++config REPLICATE_EXHANDLERS
++	bool "Exception handler replication support"
++	depends on SGI_IP27
++	help
++	  Say Y here to enable replicating the kernel exception handlers
++	  across multiple nodes in a NUMA cluster. This trades memory for
++	  speed.
+diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c
+--- a/arch/mips/sgi-ip27/ip27-berr.c
++++ b/arch/mips/sgi-ip27/ip27-berr.c
+@@ -10,6 +10,7 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/signal.h>	/* for SIGBUS */
+ 
+ #include <asm/module.h>
+ #include <asm/sn/addrs.h>
+diff --git a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c
+--- a/arch/mips/sgi-ip27/ip27-console.c
++++ b/arch/mips/sgi-ip27/ip27-console.c
+@@ -30,8 +30,10 @@
+ static inline struct ioc3_uartregs *console_uart(void)
+ {
+ 	struct ioc3 *ioc3;
++	nasid_t nasid;
+ 
+-	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
++	nasid = (master_nasid == INVALID_NASID) ? get_nasid() : master_nasid;
++	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(nasid)->memory_base;
+ 
+ 	return &ioc3->sregs.uarta;
+ }
+diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
+--- a/arch/mips/sgi-ip27/ip27-init.c
++++ b/arch/mips/sgi-ip27/ip27-init.c
+@@ -56,12 +56,12 @@ static void __init per_hub_init(cnodeid_
+ {
+ 	struct hub_data *hub = hub_data(cnode);
+ 	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
++	int i;
+ 
+ 	cpu_set(smp_processor_id(), hub->h_cpus);
+ 
+ 	if (test_and_set_bit(cnode, hub_init_mask))
+ 		return;
+-
+ 	/*
+ 	 * Set CRB timeout at 5ms, (< PI timeout of 10ms)
+ 	 */
+@@ -88,6 +88,24 @@ static void __init per_hub_init(cnodeid_
+ 		__flush_cache_all();
+ 	}
+ #endif
++
++	/*
++	 * Some interrupts are reserved by hardware or by software convention.
++	 * Mark these as reserved right away so they won't be used accidently
++	 * later.
++	 */
++	for (i = 0; i <= BASE_PCI_IRQ; i++) {
++		__set_bit(i, hub->irq_alloc_mask);
++		LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
++	}
++
++	__set_bit(IP_PEND0_6_63, hub->irq_alloc_mask);
++	LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
++
++	for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
++		__set_bit(i, hub->irq_alloc_mask);
++		LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
++	}
+ }
+ 
+ void __init per_cpu_init(void)
+@@ -104,30 +122,12 @@ void __init per_cpu_init(void)
+ 
+ 	clear_c0_status(ST0_IM);
+ 
++	per_hub_init(cnode);
++
+ 	for (i = 0; i < LEVELS_PER_SLICE; i++)
+ 		si->level_to_irq[i] = -1;
+ 
+ 	/*
+-	 * Some interrupts are reserved by hardware or by software convention.
+-	 * Mark these as reserved right away so they won't be used accidently
+-	 * later.
+-	 */
+-	for (i = 0; i <= BASE_PCI_IRQ; i++) {
+-		__set_bit(i, si->irq_alloc_mask);
+-		LOCAL_HUB_S(PI_INT_PEND_MOD, i);
+-	}
+-
+-	__set_bit(IP_PEND0_6_63, si->irq_alloc_mask);
+-	LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
+-
+-	for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
+-		__set_bit(i, si->irq_alloc_mask + 1);
+-		LOCAL_HUB_S(PI_INT_PEND_MOD, i);
+-	}
+-
+-	LOCAL_HUB_L(PI_INT_PEND0);
+-
+-	/*
+ 	 * We use this so we can find the local hub's data as fast as only
+ 	 * possible.
+ 	 */
+@@ -140,8 +140,6 @@ void __init per_cpu_init(void)
+ 	install_cpu_nmi_handler(cputoslice(cpu));
+ 
+ 	set_c0_status(SRB_DEV0 | SRB_DEV1);
+-
+-	per_hub_init(cnode);
+ }
+ 
+ /*
+@@ -198,7 +196,7 @@ extern void ip27_setup_console(void);
+ extern void ip27_time_init(void);
+ extern void ip27_reboot_setup(void);
+ 
+-static int __init ip27_setup(void)
++void __init plat_setup(void)
+ {
+ 	hubreg_t p, e, n_mode;
+ 	nasid_t nid;
+@@ -245,8 +243,4 @@ static int __init ip27_setup(void)
+ 	set_io_port_base(IO_BASE);
+ 
+ 	board_time_init = ip27_time_init;
+-
+-	return 0;
+ }
+-
+-early_initcall(ip27_setup);
+diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
+--- a/arch/mips/sgi-ip27/ip27-irq.c
++++ b/arch/mips/sgi-ip27/ip27-irq.c
+@@ -5,6 +5,9 @@
+  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+  * Copyright (C) 1999 - 2001 Kanoj Sarcar
+  */
++
++#undef DEBUG
++
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/irq.h>
+@@ -14,11 +17,11 @@
+ #include <linux/types.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+-#include <linux/irq.h>
+ #include <linux/timex.h>
+ #include <linux/slab.h>
+ #include <linux/random.h>
+ #include <linux/smp_lock.h>
++#include <linux/kernel.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/delay.h>
+ #include <linux/bitops.h>
+@@ -37,13 +40,6 @@
+ #include <asm/sn/hub.h>
+ #include <asm/sn/intr.h>
+ 
+-#undef DEBUG_IRQ
+-#ifdef DEBUG_IRQ
+-#define DBG(x...) printk(x)
+-#else
+-#define DBG(x...)
+-#endif
+-
+ /*
+  * Linux has a controller-independent x86 interrupt architecture.
+  * every controller has a 'controller-template', that is used
+@@ -74,14 +70,15 @@ extern int irq_to_slot[];
+ 
+ static inline int alloc_level(int cpu, int irq)
+ {
++	struct hub_data *hub = hub_data(cpu_to_node(cpu));
+ 	struct slice_data *si = cpu_data[cpu].data;
+-	int level;				/* pre-allocated entries */
++	int level;
+ 
+-	level = find_first_zero_bit(si->irq_alloc_mask, LEVELS_PER_SLICE);
++	level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
+ 	if (level >= LEVELS_PER_SLICE)
+ 		panic("Cpu %d flooded with devices\n", cpu);
+ 
+-	__set_bit(level, si->irq_alloc_mask);
++	__set_bit(level, hub->irq_alloc_mask);
+ 	si->level_to_irq[level] = irq;
+ 
+ 	return level;
+@@ -216,9 +213,11 @@ static int intr_connect_level(int cpu, i
+ {
+ 	nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+ 	struct slice_data *si = cpu_data[cpu].data;
++	unsigned long flags;
+ 
+-	__set_bit(bit, si->irq_enable_mask);
++	set_bit(bit, si->irq_enable_mask);
+ 
++	local_irq_save(flags);
+ 	if (!cputoslice(cpu)) {
+ 		REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
+ 		REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
+@@ -226,6 +225,7 @@ static int intr_connect_level(int cpu, i
+ 		REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
+ 		REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
+ 	}
++	local_irq_restore(flags);
+ 
+ 	return 0;
+ }
+@@ -235,7 +235,7 @@ static int intr_disconnect_level(int cpu
+ 	nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+ 	struct slice_data *si = cpu_data[cpu].data;
+ 
+-	__clear_bit(bit, si->irq_enable_mask);
++	clear_bit(bit, si->irq_enable_mask);
+ 
+ 	if (!cputoslice(cpu)) {
+ 		REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
+@@ -261,7 +261,7 @@ static unsigned int startup_bridge_irq(u
+ 	bc = IRQ_TO_BRIDGE(irq);
+ 	bridge = bc->base;
+ 
+-	DBG("bridge_startup(): irq= 0x%x  pin=%d\n", irq, pin);
++	pr_debug("bridge_startup(): irq= 0x%x  pin=%d\n", irq, pin);
+ 	/*
+ 	 * "map" irq to a swlevel greater than 6 since the first 6 bits
+ 	 * of INT_PEND0 are taken
+@@ -298,12 +298,13 @@ static unsigned int startup_bridge_irq(u
+ static void shutdown_bridge_irq(unsigned int irq)
+ {
+ 	struct bridge_controller *bc = IRQ_TO_BRIDGE(irq);
++	struct hub_data *hub = hub_data(cpu_to_node(bc->irq_cpu));
+ 	bridge_t *bridge = bc->base;
+ 	struct slice_data *si = cpu_data[bc->irq_cpu].data;
+ 	int pin, swlevel;
+ 	cpuid_t cpu;
+ 
+-	DBG("bridge_shutdown: irq 0x%x\n", irq);
++	pr_debug("bridge_shutdown: irq 0x%x\n", irq);
+ 	pin = SLOT_FROM_PCI_IRQ(irq);
+ 
+ 	/*
+@@ -313,7 +314,7 @@ static void shutdown_bridge_irq(unsigned
+ 	swlevel = find_level(&cpu, irq);
+ 	intr_disconnect_level(cpu, swlevel);
+ 
+-	__clear_bit(swlevel, si->irq_alloc_mask);
++	__clear_bit(swlevel, hub->irq_alloc_mask);
+ 	si->level_to_irq[swlevel] = -1;
+ 
+ 	bridge->b_int_enable &= ~(1 << pin);
+@@ -433,25 +434,24 @@ void install_ipi(void)
+ 	int slice = LOCAL_HUB_L(PI_CPU_NUM);
+ 	int cpu = smp_processor_id();
+ 	struct slice_data *si = cpu_data[cpu].data;
+-	hubreg_t mask, set;
++	struct hub_data *hub = hub_data(cpu_to_node(cpu));
++	int resched, call;
++
++	resched = CPU_RESCHED_A_IRQ + slice;
++	__set_bit(resched, hub->irq_alloc_mask);
++	__set_bit(resched, si->irq_enable_mask);
++	LOCAL_HUB_CLR_INTR(resched);
++
++	call = CPU_CALL_A_IRQ + slice;
++	__set_bit(call, hub->irq_alloc_mask);
++	__set_bit(call, si->irq_enable_mask);
++	LOCAL_HUB_CLR_INTR(call);
+ 
+ 	if (slice == 0) {
+-		LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
+-		LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
+-		mask = LOCAL_HUB_L(PI_INT_MASK0_A);	/* Slice A */
+-		set = (1UL << CPU_RESCHED_A_IRQ) | (1UL << CPU_CALL_A_IRQ);
+-		mask |= set;
+-		si->irq_enable_mask[0] |= set;
+-		si->irq_alloc_mask[0] |= set;
+-		LOCAL_HUB_S(PI_INT_MASK0_A, mask);
++		LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]);
++		LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]);
+ 	} else {
+-		LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ);
+-		LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ);
+-		mask = LOCAL_HUB_L(PI_INT_MASK0_B);	/* Slice B */
+-		set = (1UL << CPU_RESCHED_B_IRQ) | (1UL << CPU_CALL_B_IRQ);
+-		mask |= set;
+-		si->irq_enable_mask[1] |= set;
+-		si->irq_alloc_mask[1] |= set;
+-		LOCAL_HUB_S(PI_INT_MASK0_B, mask);
++		LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]);
++		LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]);
+ 	}
+ }
+diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
+--- a/arch/mips/sgi-ip27/ip27-smp.c
++++ b/arch/mips/sgi-ip27/ip27-smp.c
+@@ -127,37 +127,28 @@ void cpu_node_probe(void)
+ 	printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
+ }
+ 
+-static void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend,
+-	int base_level)
++static __init void intr_clear_all(nasid_t nasid)
+ {
+-	volatile hubreg_t bits;
+ 	int i;
+ 
+-	/* Check pending interrupts */
+-	if ((bits = HUB_L(pend)) != 0)
+-		for (i = 0; i < N_INTPEND_BITS; i++)
+-			if (bits & (1 << i))
+-				LOCAL_HUB_CLR_INTR(base_level + i);
+-}
+-
+-static void intr_clear_all(nasid_t nasid)
+-{
+ 	REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
+ 	REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
+ 	REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
+ 	REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
+-	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0),
+-	                INT_PEND0_BASELVL);
+-	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1),
+-	                INT_PEND1_BASELVL);
++
++	for (i = 0; i < 128; i++)
++		REMOTE_HUB_CLR_INTR(nasid, i);
+ }
+ 
+ void __init prom_prepare_cpus(unsigned int max_cpus)
+ {
+ 	cnodeid_t	cnode;
+ 
+-	for_each_online_node(cnode)
++	for_each_online_node(cnode) {
++		if (cnode == 0)
++			continue;
+ 		intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
++	}
+ 
+ 	replicate_kernel_text();
+ 
+diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
+--- a/arch/mips/sgi-ip32/ip32-irq.c
++++ b/arch/mips/sgi-ip32/ip32-irq.c
+@@ -163,14 +163,13 @@ static void end_cpu_irq(unsigned int irq
+ #define mask_and_ack_cpu_irq disable_cpu_irq
+ 
+ static struct hw_interrupt_type ip32_cpu_interrupt = {
+-	"IP32 CPU",
+-	startup_cpu_irq,
+-	shutdown_cpu_irq,
+-	enable_cpu_irq,
+-	disable_cpu_irq,
+-	mask_and_ack_cpu_irq,
+-	end_cpu_irq,
+-	NULL
++	.typename = "IP32 CPU",
++	.startup = startup_cpu_irq,
++	.shutdown = shutdown_cpu_irq,
++	.enable = enable_cpu_irq,
++	.disable = disable_cpu_irq,
++	.ack = mask_and_ack_cpu_irq,
++	.end = end_cpu_irq,
+ };
+ 
+ /*
+@@ -234,14 +233,13 @@ static void end_crime_irq(unsigned int i
+ #define shutdown_crime_irq disable_crime_irq
+ 
+ static struct hw_interrupt_type ip32_crime_interrupt = {
+-	"IP32 CRIME",
+-	startup_crime_irq,
+-	shutdown_crime_irq,
+-	enable_crime_irq,
+-	disable_crime_irq,
+-	mask_and_ack_crime_irq,
+-	end_crime_irq,
+-	NULL
++	.typename = "IP32 CRIME",
++	.startup = startup_crime_irq,
++	.shutdown = shutdown_crime_irq,
++	.enable = enable_crime_irq,
++	.disable = disable_crime_irq,
++	.ack = mask_and_ack_crime_irq,
++	.end = end_crime_irq,
+ };
+ 
+ /*
+@@ -294,14 +292,13 @@ static void end_macepci_irq(unsigned int
+ #define mask_and_ack_macepci_irq disable_macepci_irq
+ 
+ static struct hw_interrupt_type ip32_macepci_interrupt = {
+-	"IP32 MACE PCI",
+-	startup_macepci_irq,
+-	shutdown_macepci_irq,
+-	enable_macepci_irq,
+-	disable_macepci_irq,
+-	mask_and_ack_macepci_irq,
+-	end_macepci_irq,
+-	NULL
++	.typename = "IP32 MACE PCI",
++	.startup = startup_macepci_irq,
++	.shutdown = shutdown_macepci_irq,
++	.enable = enable_macepci_irq,
++	.disable = disable_macepci_irq,
++	.ack = mask_and_ack_macepci_irq,
++	.end = end_macepci_irq,
+ };
+ 
+ /* This is used for MACE ISA interrupts.  That means bits 4-6 in the
+@@ -425,14 +422,13 @@ static void end_maceisa_irq(unsigned irq
+ #define shutdown_maceisa_irq disable_maceisa_irq
+ 
+ static struct hw_interrupt_type ip32_maceisa_interrupt = {
+-	"IP32 MACE ISA",
+-	startup_maceisa_irq,
+-	shutdown_maceisa_irq,
+-	enable_maceisa_irq,
+-	disable_maceisa_irq,
+-	mask_and_ack_maceisa_irq,
+-	end_maceisa_irq,
+-	NULL
++	.typename = "IP32 MACE ISA",
++	.startup = startup_maceisa_irq,
++	.shutdown = shutdown_maceisa_irq,
++	.enable = enable_maceisa_irq,
++	.disable = disable_maceisa_irq,
++	.ack = mask_and_ack_maceisa_irq,
++	.end = end_maceisa_irq,
+ };
+ 
+ /* This is used for regular non-ISA, non-PCI MACE interrupts.  That means
+@@ -476,14 +472,13 @@ static void end_mace_irq(unsigned int ir
+ #define mask_and_ack_mace_irq disable_mace_irq
+ 
+ static struct hw_interrupt_type ip32_mace_interrupt = {
+-	"IP32 MACE",
+-	startup_mace_irq,
+-	shutdown_mace_irq,
+-	enable_mace_irq,
+-	disable_mace_irq,
+-	mask_and_ack_mace_irq,
+-	end_mace_irq,
+-	NULL
++	.typename = "IP32 MACE",
++	.startup = startup_mace_irq,
++	.shutdown = shutdown_mace_irq,
++	.enable = enable_mace_irq,
++	.disable = disable_mace_irq,
++	.ack = mask_and_ack_mace_irq,
++	.end = end_mace_irq,
+ };
+ 
+ static void ip32_unknown_interrupt(struct pt_regs *regs)
+diff --git a/arch/mips/sgi-ip32/ip32-memory.c b/arch/mips/sgi-ip32/ip32-memory.c
+--- a/arch/mips/sgi-ip32/ip32-memory.c
++++ b/arch/mips/sgi-ip32/ip32-memory.c
+@@ -36,8 +36,8 @@ void __init prom_meminit (void)
+ 		if (base + size > (256 << 20))
+ 			base += CRIME_HI_MEM_BASE;
+ 
+-		printk("CRIME MC: bank %u base 0x%016lx size %luMB\n",
+-			bank, base, size);
++		printk("CRIME MC: bank %u base 0x%016lx size %luMiB\n",
++			bank, base, size >> 20);
+ 		add_memory_region (base, size, BOOT_MEM_RAM);
+ 	}
+ }
+diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
+--- a/arch/mips/sgi-ip32/ip32-setup.c
++++ b/arch/mips/sgi-ip32/ip32-setup.c
+@@ -92,7 +92,7 @@ void __init ip32_timer_setup(struct irqa
+ 	setup_irq(IP32_R4K_TIMER_IRQ, irq);
+ }
+ 
+-static int __init ip32_setup(void)
++void __init plat_setup(void)
+ {
+ 	board_be_init = ip32_be_init;
+ 
+@@ -152,8 +152,4 @@ static int __init ip32_setup(void)
+ 		}
+ 	}
+ #endif
+-
+-	return 0;
+ }
+-
+-early_initcall(ip32_setup);
+diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/sibyte/Kconfig
+@@ -0,0 +1,161 @@
++config SIBYTE_SB1250
++	bool
++	select HW_HAS_PCI
++	select SIBYTE_HAS_LDT
++	select SIBYTE_SB1xxx_SOC
++
++config SIBYTE_BCM1120
++	bool
++	select SIBYTE_BCM112X
++	select SIBYTE_SB1xxx_SOC
++
++config SIBYTE_BCM1125
++	bool
++	select HW_HAS_PCI
++	select SIBYTE_BCM112X
++	select SIBYTE_SB1xxx_SOC
++
++config SIBYTE_BCM1125H
++	bool
++	select HW_HAS_PCI
++	select SIBYTE_BCM112X
++	select SIBYTE_HAS_LDT
++	select SIBYTE_SB1xxx_SOC
++
++config SIBYTE_BCM112X
++	bool
++	select SIBYTE_SB1xxx_SOC
++
++config SIBYTE_BCM1x80
++	bool
++	select HW_HAS_PCI
++	select SIBYTE_SB1xxx_SOC
++
++config SIBYTE_BCM1x55
++	bool
++	select HW_HAS_PCI
++	select SIBYTE_SB1xxx_SOC
++
++config SIBYTE_SB1xxx_SOC
++	bool
++	depends on EXPERIMENTAL
++	select DMA_COHERENT
++	select SIBYTE_CFE
++	select SWAP_IO_SPACE
++	select SYS_SUPPORTS_32BIT_KERNEL
++	select SYS_SUPPORTS_64BIT_KERNEL
++
++choice
++	prompt "SiByte SOC Stepping"
++	depends on SIBYTE_SB1xxx_SOC
++
++config CPU_SB1_PASS_1
++	bool "1250 Pass1"
++	depends on SIBYTE_SB1250
++	select CPU_HAS_PREFETCH
++
++config CPU_SB1_PASS_2_1250
++	bool "1250 An"
++	depends on SIBYTE_SB1250
++	select CPU_SB1_PASS_2
++	help
++	  Also called BCM1250 Pass 2
++
++config CPU_SB1_PASS_2_2
++	bool "1250 Bn"
++	depends on SIBYTE_SB1250
++	select CPU_HAS_PREFETCH
++	help
++	  Also called BCM1250 Pass 2.2
++
++config CPU_SB1_PASS_4
++	bool "1250 Cn"
++	depends on SIBYTE_SB1250
++	select CPU_HAS_PREFETCH
++	help
++	  Also called BCM1250 Pass 3
++
++config CPU_SB1_PASS_2_112x
++	bool "112x Hybrid"
++	depends on SIBYTE_BCM112X
++	select CPU_SB1_PASS_2
++
++config CPU_SB1_PASS_3
++	bool "112x An"
++	depends on SIBYTE_BCM112X
++	select CPU_HAS_PREFETCH
++
++endchoice
++
++config CPU_SB1_PASS_2
++	bool
++
++config SIBYTE_HAS_LDT
++	bool
++	depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H)
++	default y
++
++config SIMULATION
++	bool "Running under simulation"
++	depends on SIBYTE_SB1xxx_SOC
++	help
++	  Build a kernel suitable for running under the GDB simulator.
++	  Primarily adjusts the kernel's notion of time.
++
++config CONFIG_SB1_CEX_ALWAYS_FATAL
++	bool "All cache exceptions considered fatal (no recovery attempted)"
++	depends on SIBYTE_SB1xxx_SOC
++
++config CONFIG_SB1_CERR_STALL
++	bool "Stall (rather than panic) on fatal cache error"
++	depends on SIBYTE_SB1xxx_SOC
++
++config SIBYTE_CFE
++	bool "Booting from CFE"
++	depends on SIBYTE_SB1xxx_SOC
++	help
++	  Make use of the CFE API for enumerating available memory,
++	  controlling secondary CPUs, and possibly console output.
++
++config SIBYTE_CFE_CONSOLE
++	bool "Use firmware console"
++	depends on SIBYTE_CFE
++	help
++	  Use the CFE API's console write routines during boot.  Other console
++	  options (VT console, sb1250 duart console, etc.) should not be
++	  configured.
++
++config SIBYTE_STANDALONE
++	bool
++	depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE
++	default y
++
++config SIBYTE_STANDALONE_RAM_SIZE
++	int "Memory size (in megabytes)"
++	depends on SIBYTE_STANDALONE
++	default "32"
++
++config SIBYTE_BUS_WATCHER
++	bool "Support for Bus Watcher statistics"
++	depends on SIBYTE_SB1xxx_SOC
++	help
++	  Handle and keep statistics on the bus error interrupts (COR_ECC,
++	  BAD_ECC, IO_BUS).
++
++config SIBYTE_BW_TRACE
++	bool "Capture bus trace before bus error"
++	depends on SIBYTE_BUS_WATCHER
++	help
++	  Run a continuous bus trace, dumping the raw data as soon as
++	  a ZBbus error is detected.  Cannot work if ZBbus profiling
++	  is turned on, and also will interfere with JTAG-based trace
++	  buffer activity.  Raw buffer data is dumped to console, and
++	  must be processed off-line.
++
++config SIBYTE_SB1250_PROF
++	bool "Support for SB1/SOC profiling - SB1/SCD perf counters"
++	depends on SIBYTE_SB1xxx_SOC
++
++config SIBYTE_TBPROF
++	bool "Support for ZBbus profiling"
++	depends on SIBYTE_SB1xxx_SOC
+diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/sibyte/bcm1480/Makefile
+@@ -0,0 +1,5 @@
++obj-y := setup.o irq.o irq_handler.o time.o
++
++obj-$(CONFIG_SMP)			+= smp.o
++
++EXTRA_AFLAGS := $(CFLAGS)
+diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/sibyte/bcm1480/irq.c
+@@ -0,0 +1,476 @@
++/*
++ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom 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.
++ */
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/linkage.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/kernel_stat.h>
++
++#include <asm/errno.h>
++#include <asm/signal.h>
++#include <asm/system.h>
++#include <asm/ptrace.h>
++#include <asm/io.h>
++
++#include <asm/sibyte/bcm1480_regs.h>
++#include <asm/sibyte/bcm1480_int.h>
++#include <asm/sibyte/bcm1480_scd.h>
++
++#include <asm/sibyte/sb1250_uart.h>
++#include <asm/sibyte/sb1250.h>
++
++/*
++ * These are the routines that handle all the low level interrupt stuff.
++ * Actions handled here are: initialization of the interrupt map, requesting of
++ * interrupt lines by handlers, dispatching if interrupts to handlers, probing
++ * for interrupt lines
++ */
++
++
++#define shutdown_bcm1480_irq	disable_bcm1480_irq
++static void end_bcm1480_irq(unsigned int irq);
++static void enable_bcm1480_irq(unsigned int irq);
++static void disable_bcm1480_irq(unsigned int irq);
++static unsigned int startup_bcm1480_irq(unsigned int irq);
++static void ack_bcm1480_irq(unsigned int irq);
++#ifdef CONFIG_SMP
++static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask);
++#endif
++
++#ifdef CONFIG_PCI
++extern unsigned long ht_eoi_space;
++#endif
++
++#ifdef CONFIG_KGDB
++#include <asm/gdb-stub.h>
++extern void breakpoint(void);
++static int kgdb_irq;
++#ifdef CONFIG_GDB_CONSOLE
++extern void register_gdb_console(void);
++#endif
++
++/* kgdb is on when configured.  Pass "nokgdb" kernel arg to turn it off */
++static int kgdb_flag = 1;
++static int __init nokgdb(char *str)
++{
++	kgdb_flag = 0;
++	return 1;
++}
++__setup("nokgdb", nokgdb);
++
++/* Default to UART1 */
++int kgdb_port = 1;
++#ifdef CONFIG_SIBYTE_SB1250_DUART
++extern char sb1250_duart_present[];
++#endif
++#endif
++
++static struct hw_interrupt_type bcm1480_irq_type = {
++	.typename = "BCM1480-IMR",
++	.startup = startup_bcm1480_irq,
++	.shutdown = shutdown_bcm1480_irq,
++	.enable = enable_bcm1480_irq,
++	.disable = disable_bcm1480_irq,
++	.ack = ack_bcm1480_irq,
++	.end = end_bcm1480_irq,
++#ifdef CONFIG_SMP
++	.set_affinity = bcm1480_set_affinity
++#endif
++};
++
++/* Store the CPU id (not the logical number) */
++int bcm1480_irq_owner[BCM1480_NR_IRQS];
++
++DEFINE_SPINLOCK(bcm1480_imr_lock);
++
++void bcm1480_mask_irq(int cpu, int irq)
++{
++	unsigned long flags;
++	u64 cur_ints,hl_spacing;
++
++	spin_lock_irqsave(&bcm1480_imr_lock, flags);
++	hl_spacing = 0;
++	if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
++		hl_spacing = BCM1480_IMR_HL_SPACING;
++		irq -= BCM1480_NR_IRQS_HALF;
++	}
++	cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
++	cur_ints |= (((u64) 1) << irq);
++	____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
++	spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
++}
++
++void bcm1480_unmask_irq(int cpu, int irq)
++{
++	unsigned long flags;
++	u64 cur_ints,hl_spacing;
++
++	spin_lock_irqsave(&bcm1480_imr_lock, flags);
++	hl_spacing = 0;
++	if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
++		hl_spacing = BCM1480_IMR_HL_SPACING;
++		irq -= BCM1480_NR_IRQS_HALF;
++	}
++	cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
++	cur_ints &= ~(((u64) 1) << irq);
++	____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
++	spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
++}
++
++#ifdef CONFIG_SMP
++static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
++{
++	int i = 0, old_cpu, cpu, int_on;
++	u64 cur_ints;
++	irq_desc_t *desc = irq_desc + irq;
++	unsigned long flags;
++	unsigned int irq_dirty;
++
++	i = first_cpu(mask);
++	if (next_cpu(i, mask) <= NR_CPUS) {
++		printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
++		return;
++	}
++
++	/* Convert logical CPU to physical CPU */
++	cpu = cpu_logical_map(i);
++
++	/* Protect against other affinity changers and IMR manipulation */
++	spin_lock_irqsave(&desc->lock, flags);
++	spin_lock(&bcm1480_imr_lock);
++
++	/* Swizzle each CPU's IMR (but leave the IP selection alone) */
++	old_cpu = bcm1480_irq_owner[irq];
++	irq_dirty = irq;
++	if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) {
++		irq_dirty -= BCM1480_NR_IRQS_HALF;
++	}
++
++	int k;
++	for (k=0; k<2; k++) { /* Loop through high and low interrupt mask register */
++		cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
++		int_on = !(cur_ints & (((u64) 1) << irq_dirty));
++		if (int_on) {
++			/* If it was on, mask it */
++			cur_ints |= (((u64) 1) << irq_dirty);
++			____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
++		}
++		bcm1480_irq_owner[irq] = cpu;
++		if (int_on) {
++			/* unmask for the new CPU */
++			cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
++			cur_ints &= ~(((u64) 1) << irq_dirty);
++			____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
++		}
++	}
++	spin_unlock(&bcm1480_imr_lock);
++	spin_unlock_irqrestore(&desc->lock, flags);
++}
++#endif
++
++
++/* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */
++extern void bcm1480_irq_handler(void);
++
++/*****************************************************************************/
++
++static unsigned int startup_bcm1480_irq(unsigned int irq)
++{
++	bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
++
++	return 0;		/* never anything pending */
++}
++
++
++static void disable_bcm1480_irq(unsigned int irq)
++{
++	bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
++}
++
++static void enable_bcm1480_irq(unsigned int irq)
++{
++	bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
++}
++
++
++static void ack_bcm1480_irq(unsigned int irq)
++{
++	u64 pending;
++	unsigned int irq_dirty;
++
++	/*
++	 * If the interrupt was an HT interrupt, now is the time to
++	 * clear it.  NOTE: we assume the HT bridge was set up to
++	 * deliver the interrupts to all CPUs (which makes affinity
++	 * changing easier for us)
++	 */
++	irq_dirty = irq;
++	if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) {
++		irq_dirty -= BCM1480_NR_IRQS_HALF;
++	}
++	int k;
++	for (k=0; k<2; k++) { /* Loop through high and low LDT interrupts */
++		pending = __raw_readq(IOADDR(A_BCM1480_IMR_REGISTER(bcm1480_irq_owner[irq],
++						R_BCM1480_IMR_LDT_INTERRUPT_H + (k*BCM1480_IMR_HL_SPACING))));
++		pending &= ((u64)1 << (irq_dirty));
++		if (pending) {
++#ifdef CONFIG_SMP
++			int i;
++			for (i=0; i<NR_CPUS; i++) {
++				/*
++				 * Clear for all CPUs so an affinity switch
++				 * doesn't find an old status
++				 */
++				__raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(cpu_logical_map(i),
++								R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING))));
++			}
++#else
++			__raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING))));
++#endif
++
++			/*
++			 * Generate EOI.  For Pass 1 parts, EOI is a nop.  For
++			 * Pass 2, the LDT world may be edge-triggered, but
++			 * this EOI shouldn't hurt.  If they are
++			 * level-sensitive, the EOI is required.
++			 */
++#ifdef CONFIG_PCI
++			if (ht_eoi_space)
++				*(uint32_t *)(ht_eoi_space+(irq<<16)+(7<<2)) = 0;
++#endif
++		}
++	}
++	bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
++}
++
++
++static void end_bcm1480_irq(unsigned int irq)
++{
++	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
++		bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
++	}
++}
++
++
++void __init init_bcm1480_irqs(void)
++{
++	int i;
++
++	for (i = 0; i < NR_IRQS; i++) {
++		irq_desc[i].status = IRQ_DISABLED;
++		irq_desc[i].action = 0;
++		irq_desc[i].depth = 1;
++		if (i < BCM1480_NR_IRQS) {
++			irq_desc[i].handler = &bcm1480_irq_type;
++			bcm1480_irq_owner[i] = 0;
++		} else {
++			irq_desc[i].handler = &no_irq_type;
++		}
++	}
++}
++
++
++static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id,
++	struct pt_regs *regs)
++{
++	return IRQ_NONE;
++}
++
++static struct irqaction bcm1480_dummy_action = {
++	.handler = bcm1480_dummy_handler,
++	.flags   = 0,
++	.mask    = CPU_MASK_NONE,
++	.name    = "bcm1480-private",
++	.next    = NULL,
++	.dev_id  = 0
++};
++
++int bcm1480_steal_irq(int irq)
++{
++	irq_desc_t *desc = irq_desc + irq;
++	unsigned long flags;
++	int retval = 0;
++
++	if (irq >= BCM1480_NR_IRQS)
++		return -EINVAL;
++
++	spin_lock_irqsave(&desc->lock,flags);
++	/* Don't allow sharing at all for these */
++	if (desc->action != NULL)
++		retval = -EBUSY;
++	else {
++		desc->action = &bcm1480_dummy_action;
++		desc->depth = 0;
++	}
++	spin_unlock_irqrestore(&desc->lock,flags);
++	return 0;
++}
++
++/*
++ *  init_IRQ is called early in the boot sequence from init/main.c.  It
++ *  is responsible for setting up the interrupt mapper and installing the
++ *  handler that will be responsible for dispatching interrupts to the
++ *  "right" place.
++ */
++/*
++ * For now, map all interrupts to IP[2].  We could save
++ * some cycles by parceling out system interrupts to different
++ * IP lines, but keep it simple for bringup.  We'll also direct
++ * all interrupts to a single CPU; we should probably route
++ * PCI and LDT to one cpu and everything else to the other
++ * to balance the load a bit.
++ *
++ * On the second cpu, everything is set to IP5, which is
++ * ignored, EXCEPT the mailbox interrupt.  That one is
++ * set to IP[2] so it is handled.  This is needed so we
++ * can do cross-cpu function calls, as requred by SMP
++ */
++
++#define IMR_IP2_VAL	K_BCM1480_INT_MAP_I0
++#define IMR_IP3_VAL	K_BCM1480_INT_MAP_I1
++#define IMR_IP4_VAL	K_BCM1480_INT_MAP_I2
++#define IMR_IP5_VAL	K_BCM1480_INT_MAP_I3
++#define IMR_IP6_VAL	K_BCM1480_INT_MAP_I4
++
++void __init arch_init_irq(void)
++{
++
++	unsigned int i, cpu;
++	u64 tmp;
++	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
++		STATUSF_IP1 | STATUSF_IP0;
++
++	/* Default everything to IP2 */
++	/* Start with _high registers which has no bit 0 interrupt source */
++	for (i = 1; i < BCM1480_NR_IRQS_HALF; i++) {	/* was I0 */
++		for (cpu = 0; cpu < 4; cpu++) {
++			__raw_writeq(IMR_IP2_VAL,
++				     IOADDR(A_BCM1480_IMR_REGISTER(cpu,
++								   R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (i << 3)));
++		}
++	}
++
++	/* Now do _low registers */
++	for (i = 0; i < BCM1480_NR_IRQS_HALF; i++) {
++		for (cpu = 0; cpu < 4; cpu++) {
++			__raw_writeq(IMR_IP2_VAL,
++				     IOADDR(A_BCM1480_IMR_REGISTER(cpu,
++								   R_BCM1480_IMR_INTERRUPT_MAP_BASE_L) + (i << 3)));
++		}
++	}
++
++	init_bcm1480_irqs();
++
++	/*
++	 * Map the high 16 bits of mailbox_0 registers to IP[3], for
++	 * inter-cpu messages
++	 */
++	/* Was I1 */
++	for (cpu = 0; cpu < 4; cpu++) {
++		__raw_writeq(IMR_IP3_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
++						 (K_BCM1480_INT_MBOX_0_0 << 3)));
++        }
++
++
++	/* Clear the mailboxes.  The firmware may leave them dirty */
++	for (cpu = 0; cpu < 4; cpu++) {
++		__raw_writeq(0xffffffffffffffffULL,
++			     IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_0_CLR_CPU)));
++		__raw_writeq(0xffffffffffffffffULL,
++			     IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_1_CLR_CPU)));
++	}
++
++
++	/* Mask everything except the high 16 bit of mailbox_0 registers for all cpus */
++	tmp = ~((u64) 0) ^ ( (((u64) 1) << K_BCM1480_INT_MBOX_0_0));
++	for (cpu = 0; cpu < 4; cpu++) {
++		__raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_H)));
++	}
++	tmp = ~((u64) 0);
++	for (cpu = 0; cpu < 4; cpu++) {
++		__raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L)));
++	}
++
++	bcm1480_steal_irq(K_BCM1480_INT_MBOX_0_0);
++
++	/*
++	 * Note that the timer interrupts are also mapped, but this is
++	 * done in bcm1480_time_init().  Also, the profiling driver
++	 * does its own management of IP7.
++	 */
++
++#ifdef CONFIG_KGDB
++	imask |= STATUSF_IP6;
++#endif
++	/* Enable necessary IPs, disable the rest */
++	change_c0_status(ST0_IM, imask);
++	set_except_vector(0, bcm1480_irq_handler);
++
++#ifdef CONFIG_KGDB
++	if (kgdb_flag) {
++		kgdb_irq = K_BCM1480_INT_UART_0 + kgdb_port;
++
++#ifdef CONFIG_SIBYTE_SB1250_DUART
++		sb1250_duart_present[kgdb_port] = 0;
++#endif
++		/* Setup uart 1 settings, mapper */
++		/* QQQ FIXME */
++		__raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port));
++
++		bcm1480_steal_irq(kgdb_irq);
++		__raw_writeq(IMR_IP6_VAL,
++			     IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
++			     (kgdb_irq<<3));
++		bcm1480_unmask_irq(0, kgdb_irq);
++
++#ifdef CONFIG_GDB_CONSOLE
++		register_gdb_console();
++#endif
++		prom_printf("Waiting for GDB on UART port %d\n", kgdb_port);
++		set_debug_traps();
++		breakpoint();
++	}
++#endif
++}
++
++#ifdef CONFIG_KGDB
++
++#include <linux/delay.h>
++
++#define duart_out(reg, val)     csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
++#define duart_in(reg)           csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
++
++void bcm1480_kgdb_interrupt(struct pt_regs *regs)
++{
++	/*
++	 * Clear break-change status (allow some time for the remote
++	 * host to stop the break, since we would see another
++	 * interrupt on the end-of-break too)
++	 */
++	kstat.irqs[smp_processor_id()][kgdb_irq]++;
++	mdelay(500);
++	duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
++				M_DUART_RX_EN | M_DUART_TX_EN);
++	set_async_breakpoint(&regs->cp0_epc);
++}
++
++#endif 	/* CONFIG_KGDB */
+diff --git a/arch/mips/sibyte/bcm1480/irq_handler.S b/arch/mips/sibyte/bcm1480/irq_handler.S
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/sibyte/bcm1480/irq_handler.S
+@@ -0,0 +1,165 @@
++/*
++ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom 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.
++ */
++
++/*
++ * bcm1480_irq_handler() is the routine that is actually called when an
++ * interrupt occurs.  It is installed as the exception vector handler in
++ * init_IRQ() in arch/mips/sibyte/bcm1480/irq.c
++ *
++ * In the handle we figure out which interrupts need handling, and use that
++ * to call the dispatcher, which will take care of actually calling
++ * registered handlers
++ *
++ * Note that we take care of all raised interrupts in one go at the handler.
++ * This is more BSDish than the Indy code, and also, IMHO, more sane.
++ */
++#include <linux/config.h>
++
++#include <asm/addrspace.h>
++#include <asm/asm.h>
++#include <asm/mipsregs.h>
++#include <asm/regdef.h>
++#include <asm/stackframe.h>
++#include <asm/sibyte/sb1250_defs.h>
++#include <asm/sibyte/bcm1480_regs.h>
++#include <asm/sibyte/bcm1480_int.h>
++
++/*
++ * What a pain. We have to be really careful saving the upper 32 bits of any
++ * register across function calls if we don't want them trashed--since were
++ * running in -o32, the calling routing never saves the full 64 bits of a
++ * register across a function call.  Being the interrupt handler, we're
++ * guaranteed that interrupts are disabled during this code so we don't have
++ * to worry about random interrupts blasting the high 32 bits.
++ */
++
++	.text
++	.set	push
++	.set	noreorder
++	.set	noat
++	.set	mips64
++	#.set	mips4
++	.align	5
++	NESTED(bcm1480_irq_handler, PT_SIZE, sp)
++	SAVE_ALL
++	CLI
++
++#ifdef CONFIG_SIBYTE_BCM1480_PROF
++	/* Set compare to count to silence count/compare timer interrupts */
++	mfc0	t1, CP0_COUNT
++	mtc0	t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
++#endif
++	/* Read cause */
++	mfc0	s0, CP0_CAUSE
++
++#ifdef CONFIG_SIBYTE_BCM1480_PROF
++	/* Cpu performance counter interrupt is routed to IP[7] */
++	andi	t1, s0, CAUSEF_IP7
++	beqz	t1, 0f
++	 srl	t1, s0, (CAUSEB_BD-2)	/* Shift BD bit to bit 2 */
++	and	t1, t1, 0x4		/* mask to get just BD bit */
++#ifdef CONFIG_MIPS64
++	dmfc0	a0, CP0_EPC
++	daddu	a0, a0, t1		/* a0 = EPC + (BD ? 4 :	0) */
++#else
++	mfc0	a0, CP0_EPC
++	addu	a0, a0, t1		/* a0 = EPC + (BD ? 4 :	0) */
++#endif
++	jal	sbprof_cpu_intr
++	 nop
++	j	ret_from_irq
++	 nop
++0:
++#endif
++
++	/* Timer interrupt is routed to IP[4] */
++	andi	t1, s0, CAUSEF_IP4
++	beqz	t1, 1f
++	 nop
++	jal	bcm1480_timer_interrupt
++	 move	a0, sp			/* Pass the registers along */
++	j	ret_from_irq
++	 nop				/* delay slot  */
++1:
++
++#ifdef CONFIG_SMP
++	/* Mailbox interrupt is routed to IP[3] */
++	andi	 t1, s0, CAUSEF_IP3
++	beqz	 t1, 2f
++	 nop
++	jal	 bcm1480_mailbox_interrupt
++	 move	 a0, sp
++	j	 ret_from_irq
++	 nop				/* delay slot  */
++2:
++#endif
++
++#ifdef CONFIG_KGDB
++	/* KGDB (uart 1) interrupt is routed to IP[6] */
++	andi	 t1, s0, CAUSEF_IP6
++	beqz	 t1, 3f
++	 nop				/* delay slot  */
++	jal	 bcm1480_kgdb_interrupt
++	 move	 a0, sp
++	j	 ret_from_irq
++	 nop				/* delay slot  */
++3:
++#endif
++
++	and	 t1, s0, CAUSEF_IP2
++	beqz	 t1, 9f
++	 nop
++
++	/*
++	 * Default...we've hit an IP[2] interrupt, which means we've got
++	 * to check the 1480 interrupt registers to figure out what to do
++	 * Need to detect which CPU we're on, now that smp_affinity is
++	 * supported.
++	 */
++	PTR_LA	 v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE
++#ifdef CONFIG_SMP
++	lw	 t1, TI_CPU($28)
++	sll	 t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT
++	addu	 v0, v0, t1
++#endif
++
++	/* Read IP[2] status (get both high and low halves of status) */
++	ld	 s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0)
++	ld	 s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0)
++
++	move	 s2, zero	/* intr number  */
++	li	 s3, 64
++
++	beqz	 s0, 9f		/* No interrupts.  Return.  */
++	 move	 a1, sp
++
++	xori	 s4, s0, 1	/* if s0 (_H) == 1, it's a low intr, so...  */
++	movz	 s2, s3, s4	/* start the intr number at 64, and  */
++	movz	 s0, s1, s4	/* look at the low status value.  */
++
++	dclz	 s1, s0		/* Find the next interrupt.  */
++	dsubu	 a0, zero, s1
++	daddiu	 a0, a0, 63
++	jal	 do_IRQ
++	 daddu	 a0, a0, s2
++
++9:	j	 ret_from_irq
++	 nop
++
++	.set pop
++	END(bcm1480_irq_handler)
+diff --git a/arch/mips/sibyte/bcm1480/setup.c b/arch/mips/sibyte/bcm1480/setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/sibyte/bcm1480/setup.c
+@@ -0,0 +1,136 @@
++/*
++ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom 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.
++ */
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/reboot.h>
++#include <linux/string.h>
++
++#include <asm/bootinfo.h>
++#include <asm/mipsregs.h>
++#include <asm/io.h>
++#include <asm/sibyte/sb1250.h>
++
++#include <asm/sibyte/bcm1480_regs.h>
++#include <asm/sibyte/bcm1480_scd.h>
++#include <asm/sibyte/sb1250_scd.h>
++
++unsigned int sb1_pass;
++unsigned int soc_pass;
++unsigned int soc_type;
++unsigned int periph_rev;
++unsigned int zbbus_mhz;
++
++static unsigned int part_type;
++
++static char *soc_str;
++static char *pass_str;
++
++static inline int setup_bcm1x80_bcm1x55(void);
++
++/* Setup code likely to be common to all SiByte platforms */
++
++static inline int sys_rev_decode(void)
++{
++	int ret = 0;
++
++	switch (soc_type) {
++	    case K_SYS_SOC_TYPE_BCM1x80:
++		if (part_type == K_SYS_PART_BCM1480)
++		    soc_str = "BCM1480";
++		else if (part_type == K_SYS_PART_BCM1280)
++		    soc_str = "BCM1280";
++		else
++		    soc_str = "BCM1x80";
++		ret = setup_bcm1x80_bcm1x55();
++		break;
++
++	    case K_SYS_SOC_TYPE_BCM1x55:
++		if (part_type == K_SYS_PART_BCM1455)
++		    soc_str = "BCM1455";
++		else if (part_type == K_SYS_PART_BCM1255)
++		    soc_str = "BCM1255";
++		else
++		    soc_str = "BCM1x55";
++		ret = setup_bcm1x80_bcm1x55();
++		break;
++
++	    default:
++		prom_printf("Unknown part type %x\n", part_type);
++		ret = 1;
++		break;
++	}
++	return ret;
++}
++
++static inline int setup_bcm1x80_bcm1x55(void)
++{
++	int ret = 0;
++
++	switch (soc_pass) {
++	    case K_SYS_REVISION_BCM1480_S0:
++		periph_rev = 1;
++		pass_str = "S0 (pass1)";
++		break;
++	    case K_SYS_REVISION_BCM1480_A1:
++		periph_rev = 1;
++		pass_str = "A1 (pass1)";
++		break;
++	    case K_SYS_REVISION_BCM1480_A2:
++		periph_rev = 1;
++		pass_str = "A2 (pass1)";
++		break;
++	    case K_SYS_REVISION_BCM1480_A3:
++		periph_rev = 1;
++		pass_str = "A3 (pass1)";
++		break;
++	    case K_SYS_REVISION_BCM1480_B0:
++		periph_rev = 1;
++		pass_str = "B0 (pass2)";
++		break;
++	    default:
++		prom_printf("Unknown %s rev %x\n", soc_str, soc_pass);
++		periph_rev = 1;
++		pass_str = "Unknown Revision";
++		break;
++	}
++	return ret;
++}
++
++void bcm1480_setup(void)
++{
++	uint64_t sys_rev;
++	int plldiv;
++
++	sb1_pass = read_c0_prid() & 0xff;
++	sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
++	soc_type = SYS_SOC_TYPE(sys_rev);
++	part_type = G_SYS_PART(sys_rev);
++	soc_pass = G_SYS_REVISION(sys_rev);
++
++	if (sys_rev_decode()) {
++		prom_printf("Restart after failure to identify SiByte chip\n");
++		machine_restart(NULL);
++	}
++
++	plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
++	zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
++
++	prom_printf("Broadcom SiByte %s %s @ %d MHz (SB-1A rev %d)\n",
++		    soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
++	prom_printf("Board type: %s\n", get_system_type());
++}
+diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/sibyte/bcm1480/smp.c
+@@ -0,0 +1,110 @@
++/*
++ * Copyright (C) 2001,2002,2004 Broadcom 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.
++ */
++
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/smp.h>
++#include <linux/kernel_stat.h>
++
++#include <asm/mmu_context.h>
++#include <asm/io.h>
++#include <asm/sibyte/sb1250.h>
++#include <asm/sibyte/bcm1480_regs.h>
++#include <asm/sibyte/bcm1480_int.h>
++
++extern void smp_call_function_interrupt(void);
++
++/*
++ * These are routines for dealing with the bcm1480 smp capabilities
++ * independent of board/firmware
++ */
++
++static void *mailbox_0_set_regs[] = {
++	IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
++	IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
++	IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
++	IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
++};
++
++static void *mailbox_0_clear_regs[] = {
++	IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
++	IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
++	IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
++	IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
++};
++
++static void *mailbox_0_regs[] = {
++	IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
++	IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
++	IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
++	IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
++};
++
++/*
++ * SMP init and finish on secondary CPUs
++ */
++void bcm1480_smp_init(void)
++{
++	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
++		STATUSF_IP1 | STATUSF_IP0;
++
++	/* Set interrupt mask, but don't enable */
++	change_c0_status(ST0_IM, imask);
++}
++
++void bcm1480_smp_finish(void)
++{
++	extern void bcm1480_time_init(void);
++	bcm1480_time_init();
++	local_irq_enable();
++}
++
++/*
++ * These are routines for dealing with the sb1250 smp capabilities
++ * independent of board/firmware
++ */
++
++/*
++ * Simple enough; everything is set up, so just poke the appropriate mailbox
++ * register, and we should be set
++ */
++void core_send_ipi(int cpu, unsigned int action)
++{
++	__raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]);
++}
++
++void bcm1480_mailbox_interrupt(struct pt_regs *regs)
++{
++	int cpu = smp_processor_id();
++	unsigned int action;
++
++	kstat_this_cpu.irqs[K_BCM1480_INT_MBOX_0_0]++;
++	/* Load the mailbox register to figure out what we're supposed to do */
++	action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff;
++
++	/* Clear the mailbox to clear the interrupt */
++	__raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
++
++	/*
++	 * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
++	 * interrupt will do the reschedule for us
++	 */
++
++	if (action & SMP_CALL_FUNCTION)
++		smp_call_function_interrupt();
++}
+diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/sibyte/bcm1480/time.c
+@@ -0,0 +1,138 @@
++/*
++ * Copyright (C) 2000,2001,2004 Broadcom 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.
++ */
++
++/*
++ * These are routines to set up and handle interrupts from the
++ * bcm1480 general purpose timer 0.  We're using the timer as a
++ * system clock, so we set it up to run at 100 Hz.  On every
++ * interrupt, we update our idea of what the time of day is,
++ * then call do_timer() in the architecture-independent kernel
++ * code to do general bookkeeping (e.g. update jiffies, run
++ * bottom halves, etc.)
++ */
++#include <linux/config.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/spinlock.h>
++#include <linux/kernel_stat.h>
++
++#include <asm/irq.h>
++#include <asm/ptrace.h>
++#include <asm/addrspace.h>
++#include <asm/time.h>
++#include <asm/io.h>
++
++#include <asm/sibyte/bcm1480_regs.h>
++#include <asm/sibyte/sb1250_regs.h>
++#include <asm/sibyte/bcm1480_int.h>
++#include <asm/sibyte/bcm1480_scd.h>
++
++#include <asm/sibyte/sb1250.h>
++
++
++#define IMR_IP2_VAL	K_BCM1480_INT_MAP_I0
++#define IMR_IP3_VAL	K_BCM1480_INT_MAP_I1
++#define IMR_IP4_VAL	K_BCM1480_INT_MAP_I2
++
++extern int bcm1480_steal_irq(int irq);
++
++void bcm1480_time_init(void)
++{
++	int cpu = smp_processor_id();
++	int irq = K_BCM1480_INT_TIMER_0+cpu;
++
++	/* Only have 4 general purpose timers */
++	if (cpu > 3) {
++		BUG();
++	}
++
++	if (!cpu) {
++		/* Use our own gettimeoffset() routine */
++		do_gettimeoffset = bcm1480_gettimeoffset;
++	}
++
++	bcm1480_mask_irq(cpu, irq);
++
++	/* Map the timer interrupt to ip[4] of this cpu */
++	__raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H)
++	      + (irq<<3)));
++
++	/* the general purpose timer ticks at 1 Mhz independent of the rest of the system */
++	/* Disable the timer and set up the count */
++	__raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
++	__raw_writeq(
++#ifndef CONFIG_SIMULATION
++		1000000/HZ
++#else
++		50000/HZ
++#endif
++		, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
++
++	/* Set the timer running */
++	__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
++	      IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
++
++	bcm1480_unmask_irq(cpu, irq);
++	bcm1480_steal_irq(irq);
++	/*
++	 * This interrupt is "special" in that it doesn't use the request_irq
++	 * way to hook the irq line.  The timer interrupt is initialized early
++	 * enough to make this a major pain, and it's also firing enough to
++	 * warrant a bit of special case code.  bcm1480_timer_interrupt is
++	 * called directly from irq_handler.S when IP[4] is set during an
++	 * interrupt
++	 */
++}
++
++#include <asm/sibyte/sb1250.h>
++
++void bcm1480_timer_interrupt(struct pt_regs *regs)
++{
++	int cpu = smp_processor_id();
++	int irq = K_BCM1480_INT_TIMER_0+cpu;
++
++	/* Reset the timer */
++	__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
++	      IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
++
++	/*
++	 * CPU 0 handles the global timer interrupt job
++	 */
++	if (cpu == 0) {
++		ll_timer_interrupt(irq, regs);
++	}
++
++	/*
++	 * every CPU should do profiling and process accouting
++	 */
++	ll_local_timer_interrupt(irq, regs);
++}
++
++/*
++ * We use our own do_gettimeoffset() instead of the generic one,
++ * because the generic one does not work for SMP case.
++ * In addition, since we use general timer 0 for system time,
++ * we can get accurate intra-jiffy offset without calibration.
++ */
++unsigned long bcm1480_gettimeoffset(void)
++{
++	unsigned long count =
++		__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
++
++	return 1000000/HZ - count;
++}
+diff --git a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c
+--- a/arch/mips/sibyte/cfe/smp.c
++++ b/arch/mips/sibyte/cfe/smp.c
+@@ -70,8 +70,15 @@ void prom_boot_secondary(int cpu, struct
+  */
+ void prom_init_secondary(void)
+ {
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++	extern void bcm1480_smp_init(void);
++	bcm1480_smp_init();
++#elif defined(CONFIG_SIBYTE_SB1250)
+ 	extern void sb1250_smp_init(void);
+ 	sb1250_smp_init();
++#else
++#error invalid SMP configuration
++#endif
+ }
+ 
+ /*
+@@ -80,8 +87,15 @@ void prom_init_secondary(void)
+  */
+ void prom_smp_finish(void)
+ {
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++	extern void bcm1480_smp_finish(void);
++	bcm1480_smp_finish();
++#elif defined(CONFIG_SIBYTE_SB1250)
+ 	extern void sb1250_smp_finish(void);
+ 	sb1250_smp_finish();
++#else
++#error invalid SMP configuration
++#endif
+ }
+ 
+ /*
+diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
+--- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
++++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
+@@ -28,6 +28,8 @@
+ #include <linux/fs.h>
+ #include <linux/errno.h>
+ #include <linux/reboot.h>
++#include <linux/smp_lock.h>
++#include <linux/wait.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+ #include <asm/sibyte/sb1250.h>
+@@ -64,24 +66,25 @@ static void arm_tb(void)
+ 	u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
+ 	/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
+ 	   trigger start of trace.  XXX vary sampling period */
+-	bus_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
+-	scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
++	__raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
++	scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+ 	/* Unfortunately, in Pass 2 we must clear all counters to knock down
+ 	   a previous interrupt request.  This means that bus profiling
+ 	   requires ALL of the SCD perf counters. */
+-	bus_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
+-		   M_SPC_CFG_ENABLE |		 // enable counting
+-		   M_SPC_CFG_CLEAR |		 // clear all counters
+-		   V_SPC_CFG_SRC1(1),		 // counter 1 counts cycles
+-		   IOADDR(A_SCD_PERF_CNT_CFG));
+-	bus_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
++	__raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) |
++						// keep counters 0,2,3 as is
++		     M_SPC_CFG_ENABLE |		// enable counting
++		     M_SPC_CFG_CLEAR |		// clear all counters
++		     V_SPC_CFG_SRC1(1),		// counter 1 counts cycles
++		     IOADDR(A_SCD_PERF_CNT_CFG));
++	__raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
+ 	/* Reset the trace buffer */
+-	bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
++	__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ #if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
+ 	/* XXXKW may want to expose control to the data-collector */
+ 	tb_options |= M_SCD_TRACE_CFG_FORCECNT;
+ #endif
+-	bus_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
++	__raw_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
+ 	sbp.tb_armed = 1;
+ }
+ 
+@@ -93,23 +96,30 @@ static irqreturn_t sbprof_tb_intr(int ir
+ 		/* XXX should use XKPHYS to make writes bypass L2 */
+ 		u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
+ 		/* Read out trace */
+-		bus_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
++		__raw_writeq(M_SCD_TRACE_CFG_START_READ,
++			     IOADDR(A_SCD_TRACE_CFG));
+ 		__asm__ __volatile__ ("sync" : : : "memory");
+ 		/* Loop runs backwards because bundles are read out in reverse order */
+ 		for (i = 256 * 6; i > 0; i -= 6) {
+ 			// Subscripts decrease to put bundle in the order
+ 			//   t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi
+-			p[i-1] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 hi
+-			p[i-2] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 lo
+-			p[i-3] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 hi
+-			p[i-4] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 lo
+-			p[i-5] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 hi
+-			p[i-6] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 lo
++			p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
++								// read t2 hi
++			p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
++								// read t2 lo
++			p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
++								// read t1 hi
++			p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
++								// read t1 lo
++			p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
++								// read t0 hi
++			p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
++								// read t0 lo
+ 		}
+ 		if (!sbp.tb_enable) {
+ 			DBG(printk(DEVNAME ": tb_intr shutdown\n"));
+-			bus_writeq(M_SCD_TRACE_CFG_RESET,
+-				   IOADDR(A_SCD_TRACE_CFG));
++			__raw_writeq(M_SCD_TRACE_CFG_RESET,
++				     IOADDR(A_SCD_TRACE_CFG));
+ 			sbp.tb_armed = 0;
+ 			wake_up(&sbp.tb_sync);
+ 		} else {
+@@ -118,7 +128,7 @@ static irqreturn_t sbprof_tb_intr(int ir
+ 	} else {
+ 		/* No more trace buffer samples */
+ 		DBG(printk(DEVNAME ": tb_intr full\n"));
+-		bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
++		__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ 		sbp.tb_armed = 0;
+ 		if (!sbp.tb_enable) {
+ 			wake_up(&sbp.tb_sync);
+@@ -152,13 +162,11 @@ int sbprof_zbprof_start(struct file *fil
+ 		return -EBUSY;
+ 	}
+ 	/* Make sure there isn't a perf-cnt interrupt waiting */
+-	scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
++	scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+ 	/* Disable and clear counters, override SRC_1 */
+-	bus_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
+-		   M_SPC_CFG_ENABLE |
+-		   M_SPC_CFG_CLEAR |
+-		   V_SPC_CFG_SRC1(1),
+-		   IOADDR(A_SCD_PERF_CNT_CFG));
++	__raw_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
++		     M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1),
++		     IOADDR(A_SCD_PERF_CNT_CFG));
+ 
+ 	/* We grab this interrupt to prevent others from trying to use
+            it, even though we don't want to service the interrupts
+@@ -172,55 +180,55 @@ int sbprof_zbprof_start(struct file *fil
+ 	/* I need the core to mask these, but the interrupt mapper to
+ 	   pass them through.  I am exploiting my knowledge that
+ 	   cp0_status masks out IP[5]. krw */
+-	bus_writeq(K_INT_MAP_I3,
+-		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+-			  (K_INT_PERF_CNT << 3)));
++	__raw_writeq(K_INT_MAP_I3,
++		     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
++			    (K_INT_PERF_CNT << 3)));
+ 
+ 	/* Initialize address traps */
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
+-
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
+-
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
+-	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
++
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
++
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
++	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
+ 
+ 	/* Initialize Trace Event 0-7 */
+ 	//				when interrupt
+-	bus_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
++	__raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
+ 
+ 	/* Initialize Trace Sequence 0-7 */
+ 	//				     Start on event 0 (interrupt)
+-	bus_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
+-		   IOADDR(A_SCD_TRACE_SEQUENCE_0));
++	__raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
++		     IOADDR(A_SCD_TRACE_SEQUENCE_0));
+ 	//			  dsamp when d used | asamp when a used
+-	bus_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
+-		   K_SCD_TRSEQ_TRIGGER_ALL,
+-		   IOADDR(A_SCD_TRACE_SEQUENCE_1));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
+-	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
++	__raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
++		     K_SCD_TRSEQ_TRIGGER_ALL,
++		     IOADDR(A_SCD_TRACE_SEQUENCE_1));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
++	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
+ 
+ 	/* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */
+-	bus_writeq((1ULL << K_INT_PERF_CNT),
+-		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
++	__raw_writeq(1ULL << K_INT_PERF_CNT,
++		     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
+ 
+ 	arm_tb();
+ 
+@@ -231,6 +239,7 @@ int sbprof_zbprof_start(struct file *fil
+ 
+ int sbprof_zbprof_stop(void)
+ {
++	DEFINE_WAIT(wait);
+ 	DBG(printk(DEVNAME ": stopping\n"));
+ 
+ 	if (sbp.tb_enable) {
+@@ -240,7 +249,9 @@ int sbprof_zbprof_stop(void)
+ 		   this sleep happens. */
+ 		if (sbp.tb_armed) {
+ 			DBG(printk(DEVNAME ": wait for disarm\n"));
+-			interruptible_sleep_on(&sbp.tb_sync);
++			prepare_to_wait(&sbp.tb_sync, &wait, TASK_INTERRUPTIBLE);
++			schedule();
++			finish_wait(&sbp.tb_sync, &wait);
+ 			DBG(printk(DEVNAME ": disarm complete\n"));
+ 		}
+ 		free_irq(K_INT_TRACE_FREEZE, &sbp);
+@@ -333,13 +344,13 @@ static ssize_t sbprof_tb_read(struct fil
+ 	return count;
+ }
+ 
+-static int sbprof_tb_ioctl(struct inode *inode,
+-			   struct file *filp,
+-			   unsigned int command,
+-			   unsigned long arg)
++static long sbprof_tb_ioctl(struct file *filp,
++			    unsigned int command,
++			    unsigned long arg)
+ {
+ 	int error = 0;
+ 
++	lock_kernel();
+ 	switch (command) {
+ 	case SBPROF_ZBSTART:
+ 		error = sbprof_zbprof_start(filp);
+@@ -348,13 +359,17 @@ static int sbprof_tb_ioctl(struct inode 
+ 		error = sbprof_zbprof_stop();
+ 		break;
+ 	case SBPROF_ZBWAITFULL:
+-		interruptible_sleep_on(&sbp.tb_read);
++		DEFINE_WAIT(wait);
++		prepare_to_wait(&sbp.tb_read, &wait, TASK_INTERRUPTIBLE);
++		schedule();
++		finish_wait(&sbp.tb_read, &wait);
+ 		/* XXXKW check if interrupted? */
+ 		return put_user(TB_FULL, (int *) arg);
+ 	default:
+ 		error = -EINVAL;
+ 		break;
+ 	}
++	unlock_kernel();
+ 
+ 	return error;
+ }
+@@ -364,7 +379,8 @@ static struct file_operations sbprof_tb_
+ 	.open		= sbprof_tb_open,
+ 	.release	= sbprof_tb_release,
+ 	.read		= sbprof_tb_read,
+-	.ioctl		= sbprof_tb_ioctl,
++	.unlocked_ioctl	= sbprof_tb_ioctl,
++	.compat_ioctl	= sbprof_tb_ioctl,
+ 	.mmap		= NULL,
+ };
+ 
+diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c
+--- a/arch/mips/sibyte/sb1250/bus_watcher.c
++++ b/arch/mips/sibyte/sb1250/bus_watcher.c
+@@ -189,7 +189,7 @@ static irqreturn_t sibyte_bw_int(int irq
+ 
+ 	for (i=0; i<256*6; i++)
+ 		printk("%016llx\n",
+-		       (unsigned long long)bus_readq(IOADDR(A_SCD_TRACE_READ)));
++		       (long long)__raw_readq(IOADDR(A_SCD_TRACE_READ)));
+ 
+ 	csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ 	csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
+diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
+--- a/arch/mips/sibyte/sb1250/irq.c
++++ b/arch/mips/sibyte/sb1250/irq.c
+@@ -53,7 +53,7 @@ static void disable_sb1250_irq(unsigned 
+ static unsigned int startup_sb1250_irq(unsigned int irq);
+ static void ack_sb1250_irq(unsigned int irq);
+ #ifdef CONFIG_SMP
+-static void sb1250_set_affinity(unsigned int irq, unsigned long mask);
++static void sb1250_set_affinity(unsigned int irq, cpumask_t mask);
+ #endif
+ 
+ #ifdef CONFIG_SIBYTE_HAS_LDT
+@@ -71,17 +71,15 @@ extern char sb1250_duart_present[];
+ #endif
+ 
+ static struct hw_interrupt_type sb1250_irq_type = {
+-	"SB1250-IMR",
+-	startup_sb1250_irq,
+-	shutdown_sb1250_irq,
+-	enable_sb1250_irq,
+-	disable_sb1250_irq,
+-	ack_sb1250_irq,
+-	end_sb1250_irq,
++	.typename = "SB1250-IMR",
++	.startup = startup_sb1250_irq,
++	.shutdown = shutdown_sb1250_irq,
++	.enable = enable_sb1250_irq,
++	.disable = disable_sb1250_irq,
++	.ack = ack_sb1250_irq,
++	.end = end_sb1250_irq,
+ #ifdef CONFIG_SMP
+-	sb1250_set_affinity
+-#else
+-	NULL
++	.set_affinity = sb1250_set_affinity
+ #endif
+ };
+ 
+@@ -96,11 +94,11 @@ void sb1250_mask_irq(int cpu, int irq)
+ 	u64 cur_ints;
+ 
+ 	spin_lock_irqsave(&sb1250_imr_lock, flags);
+-	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
+-				      R_IMR_INTERRUPT_MASK));
++	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
++					R_IMR_INTERRUPT_MASK));
+ 	cur_ints |= (((u64) 1) << irq);
+-	__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+-				      R_IMR_INTERRUPT_MASK));
++	____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
++					R_IMR_INTERRUPT_MASK));
+ 	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+ }
+ 
+@@ -110,32 +108,25 @@ void sb1250_unmask_irq(int cpu, int irq)
+ 	u64 cur_ints;
+ 
+ 	spin_lock_irqsave(&sb1250_imr_lock, flags);
+-	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
+-				      R_IMR_INTERRUPT_MASK));
++	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
++					R_IMR_INTERRUPT_MASK));
+ 	cur_ints &= ~(((u64) 1) << irq);
+-	__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+-				      R_IMR_INTERRUPT_MASK));
++	____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
++					R_IMR_INTERRUPT_MASK));
+ 	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+ }
+ 
+ #ifdef CONFIG_SMP
+-static void sb1250_set_affinity(unsigned int irq, unsigned long mask)
++static void sb1250_set_affinity(unsigned int irq, cpumask_t mask)
+ {
+ 	int i = 0, old_cpu, cpu, int_on;
+ 	u64 cur_ints;
+ 	irq_desc_t *desc = irq_desc + irq;
+ 	unsigned long flags;
+ 
+-	while (mask) {
+-		if (mask & 1) {
+-			mask >>= 1;
+-			break;
+-		}
+-		mask >>= 1;
+-		i++;
+-	}
++	i = first_cpu(mask);
+ 
+-	if (mask) {
++	if (cpus_weight(mask) > 1) {
+ 		printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
+ 		return;
+ 	}
+@@ -149,23 +140,23 @@ static void sb1250_set_affinity(unsigned
+ 
+ 	/* Swizzle each CPU's IMR (but leave the IP selection alone) */
+ 	old_cpu = sb1250_irq_owner[irq];
+-	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
+-			       R_IMR_INTERRUPT_MASK));
++	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
++					R_IMR_INTERRUPT_MASK));
+ 	int_on = !(cur_ints & (((u64) 1) << irq));
+ 	if (int_on) {
+ 		/* If it was on, mask it */
+ 		cur_ints |= (((u64) 1) << irq);
+-		__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
+-					      R_IMR_INTERRUPT_MASK));
++		____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
++					R_IMR_INTERRUPT_MASK));
+ 	}
+ 	sb1250_irq_owner[irq] = cpu;
+ 	if (int_on) {
+ 		/* unmask for the new CPU */
+-		cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
+-				       R_IMR_INTERRUPT_MASK));
++		cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
++					R_IMR_INTERRUPT_MASK));
+ 		cur_ints &= ~(((u64) 1) << irq);
+-		__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+-					      R_IMR_INTERRUPT_MASK));
++		____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
++					R_IMR_INTERRUPT_MASK));
+ 	}
+ 	spin_unlock(&sb1250_imr_lock);
+ 	spin_unlock_irqrestore(&desc->lock, flags);
+@@ -208,8 +199,8 @@ static void ack_sb1250_irq(unsigned int 
+ 	 * deliver the interrupts to all CPUs (which makes affinity
+ 	 * changing easier for us)
+ 	 */
+-	pending = bus_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
+-						  R_IMR_LDT_INTERRUPT)));
++	pending = __raw_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
++						    R_IMR_LDT_INTERRUPT)));
+ 	pending &= ((u64)1 << (irq));
+ 	if (pending) {
+ 		int i;
+@@ -224,8 +215,8 @@ static void ack_sb1250_irq(unsigned int 
+ 			 * Clear for all CPUs so an affinity switch
+ 			 * doesn't find an old status
+ 			 */
+-			bus_writeq(pending,
+-				   IOADDR(A_IMR_REGISTER(cpu,
++			__raw_writeq(pending,
++				     IOADDR(A_IMR_REGISTER(cpu,
+ 						R_IMR_LDT_INTERRUPT_CLR)));
+ 		}
+ 
+@@ -340,12 +331,14 @@ void __init arch_init_irq(void)
+ 
+ 	/* Default everything to IP2 */
+ 	for (i = 0; i < SB1250_NR_IRQS; i++) {	/* was I0 */
+-		bus_writeq(IMR_IP2_VAL,
+-			   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+-				  (i << 3)));
+-		bus_writeq(IMR_IP2_VAL,
+-			   IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+-				  (i << 3)));
++		__raw_writeq(IMR_IP2_VAL,
++			     IOADDR(A_IMR_REGISTER(0,
++						   R_IMR_INTERRUPT_MAP_BASE) +
++				    (i << 3)));
++		__raw_writeq(IMR_IP2_VAL,
++			     IOADDR(A_IMR_REGISTER(1,
++						   R_IMR_INTERRUPT_MAP_BASE) +
++				    (i << 3)));
+ 	}
+ 
+ 	init_sb1250_irqs();
+@@ -355,23 +348,23 @@ void __init arch_init_irq(void)
+ 	 * inter-cpu messages
+ 	 */
+ 	/* Was I1 */
+-	bus_writeq(IMR_IP3_VAL,
+-		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+-			  (K_INT_MBOX_0 << 3)));
+-	bus_writeq(IMR_IP3_VAL,
+-		   IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+-			  (K_INT_MBOX_0 << 3)));
++	__raw_writeq(IMR_IP3_VAL,
++		     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
++			    (K_INT_MBOX_0 << 3)));
++	__raw_writeq(IMR_IP3_VAL,
++		     IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
++			    (K_INT_MBOX_0 << 3)));
+ 
+ 	/* Clear the mailboxes.  The firmware may leave them dirty */
+-	bus_writeq(0xffffffffffffffffULL,
+-		   IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
+-	bus_writeq(0xffffffffffffffffULL,
+-		   IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
++	__raw_writeq(0xffffffffffffffffULL,
++		     IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
++	__raw_writeq(0xffffffffffffffffULL,
++		     IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
+ 
+ 	/* Mask everything except the mailbox registers for both cpus */
+ 	tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0);
+-	bus_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
+-	bus_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
++	__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
++	__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
+ 
+ 	sb1250_steal_irq(K_INT_MBOX_0);
+ 
+@@ -396,12 +389,14 @@ void __init arch_init_irq(void)
+ 		sb1250_duart_present[kgdb_port] = 0;
+ #endif
+ 		/* Setup uart 1 settings, mapper */
+-		bus_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
++		__raw_writeq(M_DUART_IMR_BRK,
++			     IOADDR(A_DUART_IMRREG(kgdb_port)));
+ 
+ 		sb1250_steal_irq(kgdb_irq);
+-		bus_writeq(IMR_IP6_VAL,
+-			   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+-				  (kgdb_irq<<3)));
++		__raw_writeq(IMR_IP6_VAL,
++			     IOADDR(A_IMR_REGISTER(0,
++						   R_IMR_INTERRUPT_MAP_BASE) +
++				    (kgdb_irq << 3)));
+ 		sb1250_unmask_irq(0, kgdb_irq);
+ 	}
+ #endif
+diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
+--- a/arch/mips/sibyte/sb1250/setup.c
++++ b/arch/mips/sibyte/sb1250/setup.c
+@@ -153,7 +153,7 @@ void sb1250_setup(void)
+ 	int bad_config = 0;
+ 
+ 	sb1_pass = read_c0_prid() & 0xff;
+-	sys_rev = bus_readq(IOADDR(A_SCD_SYSTEM_REVISION));
++	sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+ 	soc_type = SYS_SOC_TYPE(sys_rev);
+ 	soc_pass = G_SYS_REVISION(sys_rev);
+ 
+@@ -162,7 +162,7 @@ void sb1250_setup(void)
+ 		machine_restart(NULL);
+ 	}
+ 
+-	plldiv = G_SYS_PLL_DIV(bus_readq(IOADDR(A_SCD_SYSTEM_CFG)));
++	plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ 	zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
+ 
+ 	prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
+diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
+--- a/arch/mips/sibyte/sb1250/smp.c
++++ b/arch/mips/sibyte/sb1250/smp.c
+@@ -29,18 +29,18 @@
+ #include <asm/sibyte/sb1250_int.h>
+ 
+ static void *mailbox_set_regs[] = {
+-	(void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
+-	(void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
++	IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
++	IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
+ };
+ 
+ static void *mailbox_clear_regs[] = {
+-	(void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
+-	(void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
++	IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
++	IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
+ };
+ 
+ static void *mailbox_regs[] = {
+-	(void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
+-	(void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
++	IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
++	IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
+ };
+ 
+ /*
+@@ -73,7 +73,7 @@ void sb1250_smp_finish(void)
+  */
+ void core_send_ipi(int cpu, unsigned int action)
+ {
+-	bus_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
++	__raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
+ }
+ 
+ void sb1250_mailbox_interrupt(struct pt_regs *regs)
+@@ -83,10 +83,10 @@ void sb1250_mailbox_interrupt(struct pt_
+ 
+ 	kstat_this_cpu.irqs[K_INT_MBOX_0]++;
+ 	/* Load the mailbox register to figure out what we're supposed to do */
+-	action = (__bus_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
++	action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
+ 
+ 	/* Clear the mailbox to clear the interrupt */
+-	__bus_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
++	____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
+ 
+ 	/*
+ 	 * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
+diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
+--- a/arch/mips/sibyte/sb1250/time.c
++++ b/arch/mips/sibyte/sb1250/time.c
+@@ -67,24 +67,24 @@ void sb1250_time_init(void)
+ 	sb1250_mask_irq(cpu, irq);
+ 
+ 	/* Map the timer interrupt to ip[4] of this cpu */
+-	bus_writeq(IMR_IP4_VAL,
+-		   IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
+-			  (irq << 3)));
++	__raw_writeq(IMR_IP4_VAL,
++		     IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
++			    (irq << 3)));
+ 
+ 	/* the general purpose timer ticks at 1 Mhz independent if the rest of the system */
+ 	/* Disable the timer and set up the count */
+-	bus_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
++	__raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ #ifdef CONFIG_SIMULATION
+-	bus_writeq(50000 / HZ,
+-		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
++	__raw_writeq(50000 / HZ,
++		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+ #else
+-	bus_writeq(1000000/HZ,
+-		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
++	__raw_writeq(1000000 / HZ,
++		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+ #endif
+ 
+ 	/* Set the timer running */
+-	bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+-		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
++	__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
++		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ 
+ 	sb1250_unmask_irq(cpu, irq);
+ 	sb1250_steal_irq(irq);
+@@ -100,25 +100,25 @@ void sb1250_time_init(void)
+ 
+ void sb1250_timer_interrupt(struct pt_regs *regs)
+ {
+-	extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
+ 	int cpu = smp_processor_id();
+ 	int irq = K_INT_TIMER_0 + cpu;
+ 
+ 	/* Reset the timer */
+-	__bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+-		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
++	____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
++		       IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ 
+-	/*
+-	 * CPU 0 handles the global timer interrupt job
+-	 */
+ 	if (cpu == 0) {
++		/*
++		 * CPU 0 handles the global timer interrupt job
++		 */
+ 		ll_timer_interrupt(irq, regs);
+ 	}
+-
+-	/*
+-	 * every CPU should do profiling and process accouting
+-	 */
+-	ll_local_timer_interrupt(irq, regs);
++	else {
++		/*
++		 * other CPUs should just do profiling and process accounting
++		 */
++		ll_local_timer_interrupt(irq, regs);
++	}
+ }
+ 
+ /*
+@@ -130,7 +130,7 @@ void sb1250_timer_interrupt(struct pt_re
+ unsigned long sb1250_gettimeoffset(void)
+ {
+ 	unsigned long count =
+-		bus_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
++		__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+ 
+ 	return 1000000/HZ - count;
+  }
+diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
+--- a/arch/mips/sibyte/swarm/rtc_m41t81.c
++++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
+@@ -82,59 +82,60 @@
+ #define M41T81REG_SQW	0x13		/* square wave register */
+ 
+ #define M41T81_CCR_ADDRESS	0x68
+-#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
++
++#define SMB_CSR(reg)	IOADDR(A_SMB_REGISTER(1, reg))
+ 
+ static int m41t81_read(uint8_t addr)
+ {
+-	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	bus_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+-	bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE),
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
++	__raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++	if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ 		/* Clear error bit by writing a 1 */
+-		bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++		__raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ 		return -1;
+ 	}
+ 
+-	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
++	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ }
+ 
+ static int m41t81_write(uint8_t addr, int b)
+ {
+-	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	bus_writeq((addr & 0xFF), SMB_CSR(R_SMB_CMD));
+-	bus_writeq((b & 0xff), SMB_CSR(R_SMB_DATA));
+-	bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
++	__raw_writeq(b & 0xff, SMB_CSR(R_SMB_DATA));
++	__raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++	if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ 		/* Clear error bit by writing a 1 */
+-		bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++		__raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ 		return -1;
+ 	}
+ 
+ 	/* read the same byte again to make sure it is written */
+-	bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+ 	return 0;
+diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
+--- a/arch/mips/sibyte/swarm/rtc_xicor1241.c
++++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
+@@ -57,52 +57,52 @@
+ 
+ #define X1241_CCR_ADDRESS	0x6F
+ 
+-#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
++#define SMB_CSR(reg)	IOADDR(A_SMB_REGISTER(1, reg))
+ 
+ static int xicor_read(uint8_t addr)
+ {
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+-	bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
+-	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
++	__raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
++	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                 /* Clear error bit by writing a 1 */
+-                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                 return -1;
+         }
+ 
+-	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
++	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ }
+ 
+ static int xicor_write(uint8_t addr, int b)
+ {
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	bus_writeq(addr, SMB_CSR(R_SMB_CMD));
+-	bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+-	bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq(addr, SMB_CSR(R_SMB_CMD));
++	__raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
++	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                 /* Clear error bit by writing a 1 */
+-                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                 return -1;
+         } else {
+ 		return 0;
+diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
+--- a/arch/mips/sibyte/swarm/setup.c
++++ b/arch/mips/sibyte/swarm/setup.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
++ * Copyright (C) 2000, 2001, 2002, 2003, 2004 Broadcom Corporation
+  * Copyright (C) 2004 by Ralf Baechle (ralf at linux-mips.org)
+  *
+  * This program is free software; you can redistribute it and/or
+@@ -39,11 +39,23 @@
+ #include <asm/time.h>
+ #include <asm/traps.h>
+ #include <asm/sibyte/sb1250.h>
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++#include <asm/sibyte/bcm1480_regs.h>
++#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ #include <asm/sibyte/sb1250_regs.h>
++#else
++#error invalid SiByte board configuation
++#endif
+ #include <asm/sibyte/sb1250_genbus.h>
+ #include <asm/sibyte/board.h>
+ 
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++extern void bcm1480_setup(void);
++#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ extern void sb1250_setup(void);
++#else
++#error invalid SiByte board configuation
++#endif
+ 
+ extern int xicor_probe(void);
+ extern int xicor_set_time(unsigned long);
+@@ -66,27 +78,34 @@ void __init swarm_timer_setup(struct irq
+          */
+ 
+         /* We only need to setup the generic timer */
+-        sb1250_time_init();
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++	bcm1480_time_init();
++#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
++	sb1250_time_init();
++#else
++#error invalid SiByte board configuation
++#endif
+ }
+ 
+ int swarm_be_handler(struct pt_regs *regs, int is_fixup)
+ {
+ 	if (!is_fixup && (regs->cp0_cause & 4)) {
+ 		/* Data bus error - print PA */
+-#ifdef CONFIG_64BIT
+-		printk("DBE physical address: %010lx\n",
++		printk("DBE physical address: %010Lx\n",
+ 		       __read_64bit_c0_register($26, 1));
+-#else
+-		printk("DBE physical address: %010llx\n",
+-		       __read_64bit_c0_split($26, 1));
+-#endif
+ 	}
+ 	return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL);
+ }
+ 
+-static int __init swarm_setup(void)
++void __init plat_setup(void)
+ {
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++	bcm1480_setup();
++#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ 	sb1250_setup();
++#else
++#error invalid SiByte board configuation
++#endif
+ 
+ 	panic_timeout = 5;  /* For debug.  */
+ 
+@@ -133,12 +152,8 @@ static int __init swarm_setup(void)
+        };
+        /* XXXKW for CFE, get lines/cols from environment */
+ #endif
+-
+-	return 0;
+ }
+ 
+-early_initcall(swarm_setup);
+-
+ #ifdef LEDS_PHYS
+ 
+ #ifdef CONFIG_SIBYTE_CARMEL
+diff --git a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c
+--- a/arch/mips/sibyte/swarm/time.c
++++ b/arch/mips/sibyte/swarm/time.c
+@@ -79,48 +79,48 @@ static unsigned int usec_bias = 0;
+ 
+ static int xicor_read(uint8_t addr)
+ {
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+-	bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
+-	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
++	__raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
++	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                 /* Clear error bit by writing a 1 */
+-                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                 return -1;
+         }
+ 
+-	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
++	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ }
+ 
+ static int xicor_write(uint8_t addr, int b)
+ {
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	bus_writeq(addr, SMB_CSR(R_SMB_CMD));
+-	bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+-	bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+-		   SMB_CSR(R_SMB_START));
++	__raw_writeq(addr, SMB_CSR(R_SMB_CMD));
++	__raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
++	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
++		     SMB_CSR(R_SMB_START));
+ 
+-        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                 /* Clear error bit by writing a 1 */
+-                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                 return -1;
+         } else {
+ 		return 0;
+@@ -228,8 +228,8 @@ void __init swarm_time_init(void)
+ 	/* Establish communication with the Xicor 1241 RTC */
+ 	/* XXXKW how do I share the SMBus with the I2C subsystem? */
+ 
+-	bus_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
+-	bus_writeq(0, SMB_CSR(R_SMB_CONTROL));
++	__raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
++	__raw_writeq(0, SMB_CSR(R_SMB_CONTROL));
+ 
+ 	if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
+ 		printk("x1241: couldn't detect on SWARM SMBus 1\n");
+diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
+--- a/arch/mips/sni/irq.c
++++ b/arch/mips/sni/irq.c
+@@ -58,14 +58,13 @@ static void end_pciasic_irq(unsigned int
+ }
+ 
+ static struct hw_interrupt_type pciasic_irq_type = {
+-	"ASIC-PCI",
+-	startup_pciasic_irq,
+-	shutdown_pciasic_irq,
+-	enable_pciasic_irq,
+-	disable_pciasic_irq,
+-	mask_and_ack_pciasic_irq,
+-	end_pciasic_irq,
+-	NULL
++	.typename = "ASIC-PCI",
++	.startup = startup_pciasic_irq,
++	.shutdown = shutdown_pciasic_irq,
++	.enable = enable_pciasic_irq,
++	.disable = disable_pciasic_irq,
++	.ack = mask_and_ack_pciasic_irq,
++	.end = end_pciasic_irq,
+ };
+ 
+ /*
+diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
+--- a/arch/mips/sni/setup.c
++++ b/arch/mips/sni/setup.c
+@@ -167,7 +167,7 @@ static inline void sni_pcimt_time_init(v
+ 	rtc_set_time = mc146818_set_rtc_mmss;
+ }
+ 
+-static int __init sni_rm200_pci_setup(void)
++void __init plat_setup(void)
+ {
+ 	sni_pcimt_detect();
+ 	sni_pcimt_sc_init();
+@@ -196,8 +196,4 @@ static int __init sni_rm200_pci_setup(vo
+ #ifdef CONFIG_PCI
+ 	register_pci_controller(&sni_controller);
+ #endif
+-
+-	return 0;
+ }
+-
+-early_initcall(sni_rm200_pci_setup);
+diff --git a/arch/mips/tx4927/Kconfig b/arch/mips/tx4927/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4927/Kconfig
+@@ -0,0 +1,3 @@
++config TOSHIBA_FPCIB0
++	bool "FPCIB0 Backplane Support"
++	depends on TOSHIBA_RBTX4927
+diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
+--- a/arch/mips/tx4927/common/tx4927_setup.c
++++ b/arch/mips/tx4927/common/tx4927_setup.c
+@@ -64,7 +64,7 @@ static void tx4927_write_buffer_flush(vo
+ }
+ 
+ 
+-static void __init tx4927_setup(void)
++void __init plat_setup(void)
+ {
+ 	board_time_init = tx4927_time_init;
+ 	board_timer_setup = tx4927_timer_setup;
+@@ -76,12 +76,8 @@ static void __init tx4927_setup(void)
+ 		toshiba_rbtx4927_setup();
+ 	}
+ #endif
+-
+-	return;
+ }
+ 
+-early_initcall(tx4927_setup);
+-
+ void __init tx4927_time_init(void)
+ {
+ 
+diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
++++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+@@ -77,6 +77,11 @@
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #endif
++#ifdef CONFIG_SERIAL_TXX9
++#include <linux/tty.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++#endif
+ 
+ #undef TOSHIBA_RBTX4927_SETUP_DEBUG
+ 
+@@ -920,12 +925,30 @@ void __init toshiba_rbtx4927_setup(void)
+ 
+ #endif /* CONFIG_PCI */
+ 
++#ifdef CONFIG_SERIAL_TXX9
++	{
++		extern int early_serial_txx9_setup(struct uart_port *port);
++		int i;
++		struct uart_port req;
++		for(i = 0; i < 2; i++) {
++			memset(&req, 0, sizeof(req));
++			req.line = i;
++			req.iotype = UPIO_MEM;
++			req.membase = (char *)(0xff1ff300 + i * 0x100);
++			req.mapbase = 0xff1ff300 + i * 0x100;
++			req.irq = 32 + i;
++			req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
++			req.uartclk = 50000000;
++			early_serial_txx9_setup(&req);
++		}
++	}
+ #ifdef CONFIG_SERIAL_TXX9_CONSOLE
+         argptr = prom_getcmdline();
+         if (strstr(argptr, "console=") == NULL) {
+                 strcat(argptr, " console=ttyS0,38400");
+         }
+ #endif
++#endif
+ 
+ #ifdef CONFIG_ROOT_NFS
+         argptr = prom_getcmdline();
+diff --git a/arch/mips/tx4938/Kconfig b/arch/mips/tx4938/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/Kconfig
+@@ -0,0 +1,24 @@
++if TOSHIBA_RBTX4938
++
++comment "Multiplex Pin Select"
++choice
++	prompt "PIO[58:61]"
++	default TOSHIBA_RBTX4938_MPLEX_PIO58_61
++
++config TOSHIBA_RBTX4938_MPLEX_PIO58_61
++	bool "PIO"
++config TOSHIBA_RBTX4938_MPLEX_NAND
++	bool "NAND"
++config TOSHIBA_RBTX4938_MPLEX_ATA
++	bool "ATA"
++
++endchoice
++
++config TX4938_NAND_BOOT
++	depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND
++	bool "NAND Boot Support (EXPERIMENTAL)"
++	help
++	  This is only for Toshiba RBTX4938 reference board, which has NAND IPL.
++	  Select this option if you need to use NAND boot.
++
++endif
+diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/common/Makefile
+@@ -0,0 +1,11 @@
++#
++# Makefile for common code for Toshiba TX4927 based systems
++#
++# 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).
++#
++
++obj-y	+= prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o
++obj-$(CONFIG_KGDB) += dbgio.o
++
+diff --git a/arch/mips/tx4938/common/dbgio.c b/arch/mips/tx4938/common/dbgio.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/common/dbgio.c
+@@ -0,0 +1,50 @@
++/*
++ * linux/arch/mips/tx4938/common/dbgio.c
++ *
++ * kgdb interface for gdb
++ *
++ * Author: MontaVista Software, Inc.
++ *         source at mvista.com
++ *
++ * Copyright 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 SOFTWARE IS PROVIDED ``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 AUTHOR 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.
++ *
++ *  You 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.
++ *
++ * Support for TX4938 in 2.6 - Hiroshi DOYU <Hiroshi_DOYU at montavista.co.jp>
++ */
++
++#include <asm/mipsregs.h>
++#include <asm/system.h>
++#include <asm/tx4938/tx4938_mips.h>
++
++extern u8 txx9_sio_kdbg_rd(void);
++extern int txx9_sio_kdbg_wr( u8 ch );
++
++u8 getDebugChar(void)
++{
++	return (txx9_sio_kdbg_rd());
++}
++
++int putDebugChar(u8 byte)
++{
++	return (txx9_sio_kdbg_wr(byte));
++}
++
+diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/common/irq.c
+@@ -0,0 +1,424 @@
++/*
++ * linux/arch/mps/tx4938/common/irq.c
++ *
++ * Common tx4938 irq handler
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#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/irq.h>
++#include <asm/bitops.h>
++#include <asm/bootinfo.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/mipsregs.h>
++#include <asm/system.h>
++#include <asm/tx4938/rbtx4938.h>
++
++/**********************************************************************************/
++/* Forwad definitions for all pic's                                               */
++/**********************************************************************************/
++
++static unsigned int tx4938_irq_cp0_startup(unsigned int irq);
++static void tx4938_irq_cp0_shutdown(unsigned int irq);
++static void tx4938_irq_cp0_enable(unsigned int irq);
++static void tx4938_irq_cp0_disable(unsigned int irq);
++static void tx4938_irq_cp0_mask_and_ack(unsigned int irq);
++static void tx4938_irq_cp0_end(unsigned int irq);
++
++static unsigned int tx4938_irq_pic_startup(unsigned int irq);
++static void tx4938_irq_pic_shutdown(unsigned int irq);
++static void tx4938_irq_pic_enable(unsigned int irq);
++static void tx4938_irq_pic_disable(unsigned int irq);
++static void tx4938_irq_pic_mask_and_ack(unsigned int irq);
++static void tx4938_irq_pic_end(unsigned int irq);
++
++/**********************************************************************************/
++/* Kernel structs for all pic's                                                   */
++/**********************************************************************************/
++DEFINE_SPINLOCK(tx4938_cp0_lock);
++DEFINE_SPINLOCK(tx4938_pic_lock);
++
++#define TX4938_CP0_NAME "TX4938-CP0"
++static struct hw_interrupt_type tx4938_irq_cp0_type = {
++	.typename = TX4938_CP0_NAME,
++	.startup = tx4938_irq_cp0_startup,
++	.shutdown = tx4938_irq_cp0_shutdown,
++	.enable = tx4938_irq_cp0_enable,
++	.disable = tx4938_irq_cp0_disable,
++	.ack = tx4938_irq_cp0_mask_and_ack,
++	.end = tx4938_irq_cp0_end,
++	.set_affinity = NULL
++};
++
++#define TX4938_PIC_NAME "TX4938-PIC"
++static struct hw_interrupt_type tx4938_irq_pic_type = {
++	.typename = TX4938_PIC_NAME,
++	.startup = tx4938_irq_pic_startup,
++	.shutdown = tx4938_irq_pic_shutdown,
++	.enable = tx4938_irq_pic_enable,
++	.disable = tx4938_irq_pic_disable,
++	.ack = tx4938_irq_pic_mask_and_ack,
++	.end = tx4938_irq_pic_end,
++	.set_affinity = NULL
++};
++
++static struct irqaction tx4938_irq_pic_action = {
++	.handler = no_action,
++	.flags = 0,
++	.mask = CPU_MASK_NONE,
++	.name = TX4938_PIC_NAME
++};
++
++/**********************************************************************************/
++/* Functions for cp0                                                              */
++/**********************************************************************************/
++
++#define tx4938_irq_cp0_mask(irq) ( 1 << ( irq-TX4938_IRQ_CP0_BEG+8 ) )
++
++static void __init
++tx4938_irq_cp0_init(void)
++{
++	int i;
++
++	for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) {
++		irq_desc[i].status = IRQ_DISABLED;
++		irq_desc[i].action = 0;
++		irq_desc[i].depth = 1;
++		irq_desc[i].handler = &tx4938_irq_cp0_type;
++	}
++
++	return;
++}
++
++static unsigned int
++tx4938_irq_cp0_startup(unsigned int irq)
++{
++	tx4938_irq_cp0_enable(irq);
++
++	return (0);
++}
++
++static void
++tx4938_irq_cp0_shutdown(unsigned int irq)
++{
++	tx4938_irq_cp0_disable(irq);
++}
++
++static void
++tx4938_irq_cp0_enable(unsigned int irq)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&tx4938_cp0_lock, flags);
++
++	set_c0_status(tx4938_irq_cp0_mask(irq));
++
++	spin_unlock_irqrestore(&tx4938_cp0_lock, flags);
++}
++
++static void
++tx4938_irq_cp0_disable(unsigned int irq)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&tx4938_cp0_lock, flags);
++
++	clear_c0_status(tx4938_irq_cp0_mask(irq));
++
++	spin_unlock_irqrestore(&tx4938_cp0_lock, flags);
++
++	return;
++}
++
++static void
++tx4938_irq_cp0_mask_and_ack(unsigned int irq)
++{
++	tx4938_irq_cp0_disable(irq);
++
++	return;
++}
++
++static void
++tx4938_irq_cp0_end(unsigned int irq)
++{
++	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
++		tx4938_irq_cp0_enable(irq);
++	}
++
++	return;
++}
++
++/**********************************************************************************/
++/* Functions for pic                                                              */
++/**********************************************************************************/
++
++u32
++tx4938_irq_pic_addr(int irq)
++{
++	/* MVMCP -- need to formulize this */
++	irq -= TX4938_IRQ_PIC_BEG;
++
++	switch (irq) {
++	case 17:
++	case 16:
++	case 1:
++	case 0:{
++			return (TX4938_MKA(TX4938_IRC_IRLVL0));
++		}
++	case 19:
++	case 18:
++	case 3:
++	case 2:{
++			return (TX4938_MKA(TX4938_IRC_IRLVL1));
++		}
++	case 21:
++	case 20:
++	case 5:
++	case 4:{
++			return (TX4938_MKA(TX4938_IRC_IRLVL2));
++		}
++	case 23:
++	case 22:
++	case 7:
++	case 6:{
++			return (TX4938_MKA(TX4938_IRC_IRLVL3));
++		}
++	case 25:
++	case 24:
++	case 9:
++	case 8:{
++			return (TX4938_MKA(TX4938_IRC_IRLVL4));
++		}
++	case 27:
++	case 26:
++	case 11:
++	case 10:{
++			return (TX4938_MKA(TX4938_IRC_IRLVL5));
++		}
++	case 29:
++	case 28:
++	case 13:
++	case 12:{
++			return (TX4938_MKA(TX4938_IRC_IRLVL6));
++		}
++	case 31:
++	case 30:
++	case 15:
++	case 14:{
++			return (TX4938_MKA(TX4938_IRC_IRLVL7));
++		}
++	}
++
++	return (0);
++}
++
++u32
++tx4938_irq_pic_mask(int irq)
++{
++	/* MVMCP -- need to formulize this */
++	irq -= TX4938_IRQ_PIC_BEG;
++
++	switch (irq) {
++	case 31:
++	case 29:
++	case 27:
++	case 25:
++	case 23:
++	case 21:
++	case 19:
++	case 17:{
++			return (0x07000000);
++		}
++	case 30:
++	case 28:
++	case 26:
++	case 24:
++	case 22:
++	case 20:
++	case 18:
++	case 16:{
++			return (0x00070000);
++		}
++	case 15:
++	case 13:
++	case 11:
++	case 9:
++	case 7:
++	case 5:
++	case 3:
++	case 1:{
++			return (0x00000700);
++		}
++	case 14:
++	case 12:
++	case 10:
++	case 8:
++	case 6:
++	case 4:
++	case 2:
++	case 0:{
++			return (0x00000007);
++		}
++	}
++	return (0x00000000);
++}
++
++static void
++tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits)
++{
++	unsigned long val = 0;
++
++	val = TX4938_RD(pic_reg);
++	val &= (~clr_bits);
++	val |= (set_bits);
++	TX4938_WR(pic_reg, val);
++	mmiowb();
++	TX4938_RD(pic_reg);
++
++	return;
++}
++
++static void __init
++tx4938_irq_pic_init(void)
++{
++	unsigned long flags;
++	int i;
++
++	for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) {
++		irq_desc[i].status = IRQ_DISABLED;
++		irq_desc[i].action = 0;
++		irq_desc[i].depth = 2;
++		irq_desc[i].handler = &tx4938_irq_pic_type;
++	}
++
++	setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action);
++
++	spin_lock_irqsave(&tx4938_pic_lock, flags);
++
++	TX4938_WR(0xff1ff640, 0x6);	/* irq level mask -- only accept hightest */
++	TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1);	/* irq enable */
++
++	spin_unlock_irqrestore(&tx4938_pic_lock, flags);
++
++	return;
++}
++
++static unsigned int
++tx4938_irq_pic_startup(unsigned int irq)
++{
++	tx4938_irq_pic_enable(irq);
++
++	return (0);
++}
++
++static void
++tx4938_irq_pic_shutdown(unsigned int irq)
++{
++	tx4938_irq_pic_disable(irq);
++
++	return;
++}
++
++static void
++tx4938_irq_pic_enable(unsigned int irq)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&tx4938_pic_lock, flags);
++
++	tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), 0,
++			      tx4938_irq_pic_mask(irq));
++
++	spin_unlock_irqrestore(&tx4938_pic_lock, flags);
++
++	return;
++}
++
++static void
++tx4938_irq_pic_disable(unsigned int irq)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&tx4938_pic_lock, flags);
++
++	tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq),
++			      tx4938_irq_pic_mask(irq), 0);
++
++	spin_unlock_irqrestore(&tx4938_pic_lock, flags);
++
++	return;
++}
++
++static void
++tx4938_irq_pic_mask_and_ack(unsigned int irq)
++{
++	tx4938_irq_pic_disable(irq);
++
++	return;
++}
++
++static void
++tx4938_irq_pic_end(unsigned int irq)
++{
++	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
++		tx4938_irq_pic_enable(irq);
++	}
++
++	return;
++}
++
++/**********************************************************************************/
++/* Main init functions                                                            */
++/**********************************************************************************/
++
++void __init
++tx4938_irq_init(void)
++{
++	extern asmlinkage void tx4938_irq_handler(void);
++
++	tx4938_irq_cp0_init();
++	tx4938_irq_pic_init();
++	set_except_vector(0, tx4938_irq_handler);
++
++	return;
++}
++
++int
++tx4938_irq_nested(void)
++{
++	int sw_irq = 0;
++	u32 level2;
++
++	level2 = TX4938_RD(0xff1ff6a0);
++	if ((level2 & 0x10000) == 0) {
++		level2 &= 0x1f;
++		sw_irq = TX4938_IRQ_PIC_BEG + level2;
++		if (sw_irq == 26) {
++			{
++				extern int toshiba_rbtx4938_irq_nested(int sw_irq);
++				sw_irq = toshiba_rbtx4938_irq_nested(sw_irq);
++			}
++		}
++	}
++
++	wbflush();
++	return (sw_irq);
++}
+diff --git a/arch/mips/tx4938/common/irq_handler.S b/arch/mips/tx4938/common/irq_handler.S
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/common/irq_handler.S
+@@ -0,0 +1,84 @@
++/*
++ * linux/arch/mips/tx4938/common/handler.S
++ *
++ * Primary interrupt handler for tx4938 based systems
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <asm/asm.h>
++#include <asm/mipsregs.h>
++#include <asm/addrspace.h>
++#include <asm/regdef.h>
++#include <asm/stackframe.h>
++#include <asm/tx4938/rbtx4938.h>
++
++
++		.align	5
++		NESTED(tx4938_irq_handler, PT_SIZE, sp)
++		SAVE_ALL
++		CLI
++		.set	at
++
++		mfc0	t0, CP0_CAUSE
++		mfc0	t1, CP0_STATUS
++		and	t0, t1
++
++		andi	t1, t0, STATUSF_IP7	/* cpu timer */
++		bnez	t1, ll_ip7
++
++		/* IP6..IP3 multiplexed -- do not use */
++
++		andi	t1, t0, STATUSF_IP2	/* tx4938 pic */
++		bnez	t1, ll_ip2
++
++		andi	t1, t0, STATUSF_IP1	/* user line 1 */
++		bnez	t1, ll_ip1
++
++		andi	t1, t0, STATUSF_IP0	/* user line 0 */
++		bnez	t1, ll_ip0
++
++		.set	reorder
++
++		nop
++		END(tx4938_irq_handler)
++
++		.align	5
++
++
++ll_ip7:
++		li	a0, TX4938_IRQ_CPU_TIMER
++		move	a1, sp
++		jal	do_IRQ
++		j	ret_from_irq
++
++
++ll_ip2:
++		jal	tx4938_irq_nested
++		nop
++		beqz	v0, goto_spurious_interrupt
++		nop
++		move	a0, v0
++		move	a1, sp
++		jal	do_IRQ
++		j	ret_from_irq
++
++goto_spurious_interrupt:
++		j	ret_from_irq
++
++ll_ip1:
++		li	a0, TX4938_IRQ_USER1
++		move	a1, sp
++		jal	do_IRQ
++		j	ret_from_irq
++
++ll_ip0:
++		li	a0, TX4938_IRQ_USER0
++		move	a1, sp
++		jal	do_IRQ
++		j	ret_from_irq
+diff --git a/arch/mips/tx4938/common/prom.c b/arch/mips/tx4938/common/prom.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/common/prom.c
+@@ -0,0 +1,129 @@
++/*
++ * linux/arch/mips/tx4938/common/prom.c
++ *
++ * common tx4938 memory interface
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++
++#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/tx4938/tx4938.h>
++
++static unsigned int __init
++tx4938_process_sdccr(u64 * addr)
++{
++	u64 val;
++	unsigned int sdccr_ce;
++	unsigned int sdccr_rs;
++	unsigned int sdccr_cs;
++	unsigned int sdccr_mw;
++	unsigned int rs = 0;
++	unsigned int cs = 0;
++	unsigned int mw = 0;
++	unsigned int bc = 4;
++	unsigned int msize = 0;
++
++	val = (*((vu64 *) (addr)));
++
++	/* MVMCP -- need #defs for these bits masks */
++	sdccr_ce = ((val & (1 << 10)) >> 10);
++	sdccr_rs = ((val & (3 << 5)) >> 5);
++	sdccr_cs = ((val & (7 << 2)) >> 2);
++	sdccr_mw = ((val & (1 << 0)) >> 0);
++
++	if (sdccr_ce) {
++		switch (sdccr_rs) {
++		case 0:{
++				rs = 2048;
++				break;
++			}
++		case 1:{
++				rs = 4096;
++				break;
++			}
++		case 2:{
++				rs = 8192;
++				break;
++			}
++		default:{
++				rs = 0;
++				break;
++			}
++		}
++		switch (sdccr_cs) {
++		case 0:{
++				cs = 256;
++				break;
++			}
++		case 1:{
++				cs = 512;
++				break;
++			}
++		case 2:{
++				cs = 1024;
++				break;
++			}
++		case 3:{
++				cs = 2048;
++				break;
++			}
++		case 4:{
++				cs = 4096;
++				break;
++			}
++		default:{
++				cs = 0;
++				break;
++			}
++		}
++		switch (sdccr_mw) {
++		case 0:{
++				mw = 8;
++				break;
++			}	/* 8 bytes = 64 bits */
++		case 1:{
++				mw = 4;
++				break;
++			}	/* 4 bytes = 32 bits */
++		}
++	}
++
++	/*           bytes per chip    MB per chip          bank count */
++	msize = (((rs * cs * mw) / (1024 * 1024)) * (bc));
++
++	/* MVMCP -- bc hard coded to 4 from table 9.3.1     */
++	/*          boad supports bc=2 but no way to detect */
++
++	return (msize);
++}
++
++unsigned int __init
++tx4938_get_mem_size(void)
++{
++	unsigned int c0;
++	unsigned int c1;
++	unsigned int c2;
++	unsigned int c3;
++	unsigned int total;
++
++	/* MVMCP -- need #defs for these registers */
++	c0 = tx4938_process_sdccr((u64 *) 0xff1f8000);
++	c1 = tx4938_process_sdccr((u64 *) 0xff1f8008);
++	c2 = tx4938_process_sdccr((u64 *) 0xff1f8010);
++	c3 = tx4938_process_sdccr((u64 *) 0xff1f8018);
++	total = c0 + c1 + c2 + c3;
++
++	return (total);
++}
+diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/common/rtc_rx5c348.c
+@@ -0,0 +1,202 @@
++/*
++ * RTC routines for RICOH Rx5C348 SPI chip.
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/rtc.h>
++#include <linux/time.h>
++#include <asm/time.h>
++#include <asm/tx4938/spi.h>
++
++#define	EPOCH		2000
++
++/* registers */
++#define Rx5C348_REG_SECOND	0
++#define Rx5C348_REG_MINUTE	1
++#define Rx5C348_REG_HOUR	2
++#define Rx5C348_REG_WEEK	3
++#define Rx5C348_REG_DAY	4
++#define Rx5C348_REG_MONTH	5
++#define Rx5C348_REG_YEAR	6
++#define Rx5C348_REG_ADJUST	7
++#define Rx5C348_REG_ALARM_W_MIN	8
++#define Rx5C348_REG_ALARM_W_HOUR	9
++#define Rx5C348_REG_ALARM_W_WEEK	10
++#define Rx5C348_REG_ALARM_D_MIN	11
++#define Rx5C348_REG_ALARM_D_HOUR	12
++#define Rx5C348_REG_CTL1	14
++#define Rx5C348_REG_CTL2	15
++
++/* register bits */
++#define Rx5C348_BIT_PM	0x20	/* REG_HOUR */
++#define Rx5C348_BIT_Y2K	0x80	/* REG_MONTH */
++#define Rx5C348_BIT_24H	0x20	/* REG_CTL1 */
++#define Rx5C348_BIT_XSTP	0x10	/* REG_CTL2 */
++
++/* commands */
++#define Rx5C348_CMD_W(addr)	(((addr) << 4) | 0x08)	/* single write */
++#define Rx5C348_CMD_R(addr)	(((addr) << 4) | 0x0c)	/* single read */
++#define Rx5C348_CMD_MW(addr)	(((addr) << 4) | 0x00)	/* burst write */
++#define Rx5C348_CMD_MR(addr)	(((addr) << 4) | 0x04)	/* burst read */
++
++static struct spi_dev_desc srtc_dev_desc = {
++	.baud 		= 1000000,	/* 1.0Mbps @ Vdd 2.0V */
++	.tcss		= 31,
++	.tcsh		= 1,
++	.tcsr		= 62,
++	/* 31us for Tcss (62us for Tcsr) is required for carry operation) */
++	.byteorder	= 1,		/* MSB-First */
++	.polarity	= 0,		/* High-Active */
++	.phase		= 1,		/* Shift-Then-Sample */
++
++};
++static int srtc_chipid;
++static int srtc_24h;
++
++static inline int
++spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count)
++{
++	unsigned char *inbufs[1], *outbufs[1];
++	unsigned int incounts[2], outcounts[2];
++	inbufs[0] = inbuf;
++	incounts[0] = count;
++	incounts[1] = 0;
++	outbufs[0] = outbuf;
++	outcounts[0] = count;
++	outcounts[1] = 0;
++	return txx9_spi_io(srtc_chipid, &srtc_dev_desc,
++			   inbufs, incounts, outbufs, outcounts, 0);
++}
++
++/*
++ * Conversion between binary and BCD.
++ */
++#ifndef BCD_TO_BIN
++#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
++#endif
++
++#ifndef BIN_TO_BCD
++#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
++#endif
++
++/* RTC-dependent code for time.c */
++
++static int
++rtc_rx5c348_set_time(unsigned long t)
++{
++	unsigned char inbuf[8];
++	struct rtc_time tm;
++	u8 year, month, day, hour, minute, second, century;
++
++	/* convert */
++	to_tm(t, &tm);
++
++	year = tm.tm_year % 100;
++	month = tm.tm_mon+1;	/* tm_mon starts from 0 to 11 */
++	day = tm.tm_mday;
++	hour = tm.tm_hour;
++	minute = tm.tm_min;
++	second = tm.tm_sec;
++	century = tm.tm_year / 100;
++
++	inbuf[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND);
++	BIN_TO_BCD(second);
++	inbuf[1] = second;
++	BIN_TO_BCD(minute);
++	inbuf[2] = minute;
++
++	if (srtc_24h) {
++		BIN_TO_BCD(hour);
++		inbuf[3] = hour;
++	} else {
++		/* hour 0 is AM12, noon is PM12 */
++		inbuf[3] = 0;
++		if (hour >= 12)
++			inbuf[3] = Rx5C348_BIT_PM;
++		hour = (hour + 11) % 12 + 1;
++		BIN_TO_BCD(hour);
++		inbuf[3] |= hour;
++	}
++	inbuf[4] = 0;	/* ignore week */
++	BIN_TO_BCD(day);
++	inbuf[5] = day;
++	BIN_TO_BCD(month);
++	inbuf[6] = month;
++	if (century >= 20)
++		inbuf[6] |= Rx5C348_BIT_Y2K;
++	BIN_TO_BCD(year);
++	inbuf[7] = year;
++	/* write in one transfer to avoid data inconsistency */
++	return spi_rtc_io(inbuf, NULL, 8);
++}
++
++static unsigned long
++rtc_rx5c348_get_time(void)
++{
++	unsigned char inbuf[8], outbuf[8];
++	unsigned int year, month, day, hour, minute, second;
++
++	inbuf[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND);
++	memset(inbuf + 1, 0, 7);
++	/* read in one transfer to avoid data inconsistency */
++	if (spi_rtc_io(inbuf, outbuf, 8))
++		return 0;
++	second = outbuf[1];
++	BCD_TO_BIN(second);
++	minute = outbuf[2];
++	BCD_TO_BIN(minute);
++	if (srtc_24h) {
++		hour = outbuf[3];
++		BCD_TO_BIN(hour);
++	} else {
++		hour = outbuf[3] & ~Rx5C348_BIT_PM;
++		BCD_TO_BIN(hour);
++		hour %= 12;
++		if (outbuf[3] & Rx5C348_BIT_PM)
++			hour += 12;
++	}
++	day = outbuf[5];
++	BCD_TO_BIN(day);
++	month = outbuf[6] & ~Rx5C348_BIT_Y2K;
++	BCD_TO_BIN(month);
++	year = outbuf[7];
++	BCD_TO_BIN(year);
++	year += EPOCH;
++
++	return mktime(year, month, day, hour, minute, second);
++}
++
++void __init
++rtc_rx5c348_init(int chipid)
++{
++	unsigned char inbuf[2], outbuf[2];
++	srtc_chipid = chipid;
++	/* turn on RTC if it is not on */
++	inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2);
++	inbuf[1] = 0;
++	spi_rtc_io(inbuf, outbuf, 2);
++	if (outbuf[1] & Rx5C348_BIT_XSTP) {
++		inbuf[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2);
++		inbuf[1] = 0;
++		spi_rtc_io(inbuf, NULL, 2);
++	}
++
++	inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1);
++	inbuf[1] = 0;
++	spi_rtc_io(inbuf, outbuf, 2);
++	if (outbuf[1] & Rx5C348_BIT_24H)
++		srtc_24h = 1;
++
++	/* set the function pointers */
++	rtc_get_time = rtc_rx5c348_get_time;
++	rtc_set_time = rtc_rx5c348_set_time;
++}
+diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/common/setup.c
+@@ -0,0 +1,91 @@
++/*
++ * linux/arch/mips/tx4938/common/setup.c
++ *
++ * common tx4938 setup routines
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++
++#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/irq.h>
++#include <asm/bitops.h>
++#include <asm/bootinfo.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/mipsregs.h>
++#include <asm/system.h>
++#include <asm/time.h>
++#include <asm/time.h>
++#include <asm/tx4938/rbtx4938.h>
++
++extern void toshiba_rbtx4938_setup(void);
++extern void rbtx4938_time_init(void);
++
++void __init tx4938_setup(void);
++void __init tx4938_time_init(void);
++void __init tx4938_timer_setup(struct irqaction *irq);
++void dump_cp0(char *key);
++
++void (*__wbflush) (void);
++
++static void
++tx4938_write_buffer_flush(void)
++{
++	mmiowb();
++
++	__asm__ __volatile__(
++		".set	push\n\t"
++		".set	noreorder\n\t"
++		"lw	$0,%0\n\t"
++		"nop\n\t"
++		".set	pop"
++		: /* no output */
++		: "m" (*(int *)KSEG1)
++		: "memory");
++}
++
++void __init
++plat_setup(void)
++{
++	board_time_init = tx4938_time_init;
++	board_timer_setup = tx4938_timer_setup;
++	__wbflush = tx4938_write_buffer_flush;
++	toshiba_rbtx4938_setup();
++}
++
++void __init
++tx4938_time_init(void)
++{
++	rbtx4938_time_init();
++}
++
++void __init
++tx4938_timer_setup(struct irqaction *irq)
++{
++	u32 count;
++	u32 c1;
++	u32 c2;
++
++	setup_irq(TX4938_IRQ_CPU_TIMER, irq);
++
++	c1 = read_c0_count();
++	count = c1 + (mips_hpt_frequency / HZ);
++	write_c0_compare(count);
++	c2 = read_c0_count();
++}
+diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
+@@ -0,0 +1,9 @@
++#
++# Makefile for common code for Toshiba TX4927 based systems
++#
++# 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).
++#
++
++obj-y	+= prom.o setup.o irq.o spi_eeprom.o spi_txx9.o
+diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+@@ -0,0 +1,244 @@
++/*
++ * linux/arch/mips/tx4938/toshiba_rbtx4938/irq.c
++ *
++ * Toshiba RBTX4938 specific interrupt handlers
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++
++/*
++IRQ  Device
++
++16   TX4938-CP0/00 Software 0
++17   TX4938-CP0/01 Software 1
++18   TX4938-CP0/02 Cascade TX4938-CP0
++19   TX4938-CP0/03 Multiplexed -- do not use
++20   TX4938-CP0/04 Multiplexed -- do not use
++21   TX4938-CP0/05 Multiplexed -- do not use
++22   TX4938-CP0/06 Multiplexed -- do not use
++23   TX4938-CP0/07 CPU TIMER
++
++24   TX4938-PIC/00
++25   TX4938-PIC/01
++26   TX4938-PIC/02 Cascade RBTX4938-IOC
++27   TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet
++28   TX4938-PIC/04
++29   TX4938-PIC/05 TX4938 ETH1
++30   TX4938-PIC/06 TX4938 ETH0
++31   TX4938-PIC/07
++32   TX4938-PIC/08 TX4938 SIO 0
++33   TX4938-PIC/09 TX4938 SIO 1
++34   TX4938-PIC/10 TX4938 DMA0
++35   TX4938-PIC/11 TX4938 DMA1
++36   TX4938-PIC/12 TX4938 DMA2
++37   TX4938-PIC/13 TX4938 DMA3
++38   TX4938-PIC/14
++39   TX4938-PIC/15
++40   TX4938-PIC/16 TX4938 PCIC
++41   TX4938-PIC/17 TX4938 TMR0
++42   TX4938-PIC/18 TX4938 TMR1
++43   TX4938-PIC/19 TX4938 TMR2
++44   TX4938-PIC/20
++45   TX4938-PIC/21
++46   TX4938-PIC/22 TX4938 PCIERR
++47   TX4938-PIC/23
++48   TX4938-PIC/24
++49   TX4938-PIC/25
++50   TX4938-PIC/26
++51   TX4938-PIC/27
++52   TX4938-PIC/28
++53   TX4938-PIC/29
++54   TX4938-PIC/30
++55   TX4938-PIC/31 TX4938 SPI
++
++56 RBTX4938-IOC/00 PCI-D
++57 RBTX4938-IOC/01 PCI-C
++58 RBTX4938-IOC/02 PCI-B
++59 RBTX4938-IOC/03 PCI-A
++60 RBTX4938-IOC/04 RTC
++61 RBTX4938-IOC/05 ATA
++62 RBTX4938-IOC/06 MODEM
++63 RBTX4938-IOC/07 SWINT
++*/
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++#include <linux/timex.h>
++#include <asm/bootinfo.h>
++#include <asm/page.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/processor.h>
++#include <asm/ptrace.h>
++#include <asm/reboot.h>
++#include <asm/time.h>
++#include <linux/version.h>
++#include <linux/bootmem.h>
++#include <asm/tx4938/rbtx4938.h>
++
++static unsigned int toshiba_rbtx4938_irq_ioc_startup(unsigned int irq);
++static void toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq);
++static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
++static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
++static void toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq);
++static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq);
++
++DEFINE_SPINLOCK(toshiba_rbtx4938_ioc_lock);
++
++#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
++static struct hw_interrupt_type toshiba_rbtx4938_irq_ioc_type = {
++	.typename = TOSHIBA_RBTX4938_IOC_NAME,
++	.startup = toshiba_rbtx4938_irq_ioc_startup,
++	.shutdown = toshiba_rbtx4938_irq_ioc_shutdown,
++	.enable = toshiba_rbtx4938_irq_ioc_enable,
++	.disable = toshiba_rbtx4938_irq_ioc_disable,
++	.ack = toshiba_rbtx4938_irq_ioc_mask_and_ack,
++	.end = toshiba_rbtx4938_irq_ioc_end,
++	.set_affinity = NULL
++};
++
++#define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000
++#define TOSHIBA_RBTX4938_IOC_INTR_STAT 0xb7f0200a
++
++int
++toshiba_rbtx4938_irq_nested(int sw_irq)
++{
++	u8 level3;
++
++	level3 = reg_rd08(TOSHIBA_RBTX4938_IOC_INTR_STAT) & 0xff;
++	if (level3) {
++		/* must use fls so onboard ATA has priority */
++		sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1;
++	}
++
++	wbflush();
++	return sw_irq;
++}
++
++static struct irqaction toshiba_rbtx4938_irq_ioc_action = {
++	.handler = no_action,
++	.flags = 0,
++	.mask = CPU_MASK_NONE,
++	.name = TOSHIBA_RBTX4938_IOC_NAME,
++};
++
++/**********************************************************************************/
++/* Functions for ioc                                                              */
++/**********************************************************************************/
++static void __init
++toshiba_rbtx4938_irq_ioc_init(void)
++{
++	int i;
++
++	for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG;
++	     i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) {
++		irq_desc[i].status = IRQ_DISABLED;
++		irq_desc[i].action = 0;
++		irq_desc[i].depth = 3;
++		irq_desc[i].handler = &toshiba_rbtx4938_irq_ioc_type;
++	}
++
++	setup_irq(RBTX4938_IRQ_IOCINT,
++		  &toshiba_rbtx4938_irq_ioc_action);
++}
++
++static unsigned int
++toshiba_rbtx4938_irq_ioc_startup(unsigned int irq)
++{
++	toshiba_rbtx4938_irq_ioc_enable(irq);
++
++	return 0;
++}
++
++static void
++toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq)
++{
++	toshiba_rbtx4938_irq_ioc_disable(irq);
++}
++
++static void
++toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
++{
++	unsigned long flags;
++	volatile unsigned char v;
++
++	spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
++
++	v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
++	v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
++	TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
++	mmiowb();
++	TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
++
++	spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
++}
++
++static void
++toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
++{
++	unsigned long flags;
++	volatile unsigned char v;
++
++	spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
++
++	v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
++	v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
++	TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
++	mmiowb();
++	TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
++
++	spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
++}
++
++static void
++toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq)
++{
++	toshiba_rbtx4938_irq_ioc_disable(irq);
++}
++
++static void
++toshiba_rbtx4938_irq_ioc_end(unsigned int irq)
++{
++	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
++		toshiba_rbtx4938_irq_ioc_enable(irq);
++	}
++}
++
++extern void __init txx9_spi_irqinit(int irc_irq);
++
++void __init arch_init_irq(void)
++{
++	extern void tx4938_irq_init(void);
++
++	/* Now, interrupt control disabled, */
++	/* all IRC interrupts are masked, */
++	/* all IRC interrupt mode are Low Active. */
++
++	/* mask all IOC interrupts */
++	*rbtx4938_imask_ptr = 0;
++
++	/* clear SoftInt interrupts */
++	*rbtx4938_softint_ptr = 0;
++	tx4938_irq_init();
++	toshiba_rbtx4938_irq_ioc_init();
++	/* Onboard 10M Ether: High Active */
++	TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040);
++
++	if (tx4938_ccfgptr->pcfg & TX4938_PCFG_SPI_SEL) {
++		txx9_spi_irqinit(RBTX4938_IRQ_IRC_SPI);
++        }
++
++	wbflush();
++}
+diff --git a/arch/mips/tx4938/toshiba_rbtx4938/prom.c b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
+@@ -0,0 +1,78 @@
++/*
++ * linux/arch/mips/tx4938/toshiba_rbtx4938/prom.c
++ *
++ * rbtx4938 specific prom routines
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++
++#include <linux/config.h>
++#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/tx4938/tx4938.h>
++
++void __init prom_init_cmdline(void)
++{
++	int argc = (int) fw_arg0;
++	char **argv = (char **) fw_arg1;
++	int i;
++
++	/* ignore all built-in args if any f/w args given */
++	if (argc > 1) {
++		*arcs_cmdline = '\0';
++	}
++
++	for (i = 1; i < argc; i++) {
++		if (i != 1) {
++			strcat(arcs_cmdline, " ");
++		}
++		strcat(arcs_cmdline, argv[i]);
++	}
++}
++
++void __init prom_init(void)
++{
++	extern int tx4938_get_mem_size(void);
++	int msize;
++#ifndef CONFIG_TX4938_NAND_BOOT
++	prom_init_cmdline();
++#endif
++	mips_machgroup = MACH_GROUP_TOSHIBA;
++	mips_machtype = MACH_TOSHIBA_RBTX4938;
++
++	msize = tx4938_get_mem_size();
++	add_memory_region(0, msize << 20, BOOT_MEM_RAM);
++
++	return;
++}
++
++unsigned long  __init prom_free_prom_memory(void)
++{
++	return 0;
++}
++
++void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
++{
++	return;
++}
++
++const char *get_system_type(void)
++{
++	return "Toshiba RBTX4938";
++}
++
++char * __init prom_getcmdline(void)
++{
++	return &(arcs_cmdline[0]);
++}
+diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+@@ -0,0 +1,1035 @@
++/*
++ * linux/arch/mips/tx4938/toshiba_rbtx4938/setup.c
++ *
++ * Setup pointers to hardware-dependent routines.
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/ioport.h>
++#include <linux/proc_fs.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/console.h>
++#include <linux/pci.h>
++#include <asm/wbflush.h>
++#include <asm/reboot.h>
++#include <asm/irq.h>
++#include <asm/time.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <asm/bootinfo.h>
++#include <asm/tx4938/rbtx4938.h>
++#ifdef CONFIG_SERIAL_TXX9
++#include <linux/tty.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++#endif
++
++extern void rbtx4938_time_init(void) __init;
++extern char * __init prom_getcmdline(void);
++static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr);
++
++/* These functions are used for rebooting or halting the machine*/
++extern void rbtx4938_machine_restart(char *command);
++extern void rbtx4938_machine_halt(void);
++extern void rbtx4938_machine_power_off(void);
++
++/* clocks */
++unsigned int txx9_master_clock;
++unsigned int txx9_cpu_clock;
++unsigned int txx9_gbus_clock;
++
++unsigned long rbtx4938_ce_base[8];
++unsigned long rbtx4938_ce_size[8];
++int txboard_pci66_mode;
++static int tx4938_pcic_trdyto;	/* default: disabled */
++static int tx4938_pcic_retryto;	/* default: disabled */
++static int tx4938_ccfg_toeon = 1;
++
++struct tx4938_pcic_reg *pcicptrs[4] = {
++       tx4938_pcicptr  /* default setting for TX4938 */
++};
++
++static struct {
++	unsigned long base;
++	unsigned long size;
++} phys_regions[16] __initdata;
++static int num_phys_regions  __initdata;
++
++#define PHYS_REGION_MINSIZE	0x10000
++
++void rbtx4938_machine_halt(void)
++{
++        printk(KERN_NOTICE "System Halted\n");
++	local_irq_disable();
++
++	while (1)
++		__asm__(".set\tmips3\n\t"
++			"wait\n\t"
++			".set\tmips0");
++}
++
++void rbtx4938_machine_power_off(void)
++{
++        rbtx4938_machine_halt();
++        /* no return */
++}
++
++void rbtx4938_machine_restart(char *command)
++{
++	local_irq_disable();
++
++	printk("Rebooting...");
++	*rbtx4938_softresetlock_ptr = 1;
++	*rbtx4938_sfvol_ptr = 1;
++	*rbtx4938_softreset_ptr = 1;
++	wbflush();
++
++	while(1);
++}
++
++void __init
++txboard_add_phys_region(unsigned long base, unsigned long size)
++{
++	if (num_phys_regions >= ARRAY_SIZE(phys_regions)) {
++		printk("phys_region overflow\n");
++		return;
++	}
++	phys_regions[num_phys_regions].base = base;
++	phys_regions[num_phys_regions].size = size;
++	num_phys_regions++;
++}
++unsigned long __init
++txboard_find_free_phys_region(unsigned long begin, unsigned long end,
++			      unsigned long size)
++{
++	unsigned long base;
++	int i;
++
++	for (base = begin / size * size; base < end; base += size) {
++		for (i = 0; i < num_phys_regions; i++) {
++			if (phys_regions[i].size &&
++			    base <= phys_regions[i].base + (phys_regions[i].size - 1) &&
++			    base + (size - 1) >= phys_regions[i].base)
++				break;
++		}
++		if (i == num_phys_regions)
++			return base;
++	}
++	return 0;
++}
++unsigned long __init
++txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end,
++				     unsigned long *size)
++{
++	unsigned long sz, base;
++	for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) {
++		base = txboard_find_free_phys_region(begin, end, sz);
++		if (base) {
++			*size = sz;
++			return base;
++		}
++	}
++	return 0;
++}
++unsigned long __init
++txboard_request_phys_region_range(unsigned long begin, unsigned long end,
++				  unsigned long size)
++{
++	unsigned long base;
++	base = txboard_find_free_phys_region(begin, end, size);
++	if (base)
++		txboard_add_phys_region(base, size);
++	return base;
++}
++unsigned long __init
++txboard_request_phys_region(unsigned long size)
++{
++	unsigned long base;
++	unsigned long begin = 0, end = 0x20000000;	/* search low 512MB */
++	base = txboard_find_free_phys_region(begin, end, size);
++	if (base)
++		txboard_add_phys_region(base, size);
++	return base;
++}
++unsigned long __init
++txboard_request_phys_region_shrink(unsigned long *size)
++{
++	unsigned long base;
++	unsigned long begin = 0, end = 0x20000000;	/* search low 512MB */
++	base = txboard_find_free_phys_region_shrink(begin, end, size);
++	if (base)
++		txboard_add_phys_region(base, *size);
++	return base;
++}
++
++#ifdef CONFIG_PCI
++void __init
++tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr,
++		  struct pci_controller *channel,
++		  unsigned long pci_io_base,
++		  int extarb)
++{
++	int i;
++
++	/* Disable All Initiator Space */
++	pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)|
++			      TX4938_PCIC_PCICCFG_G2PMEN(1)|
++			      TX4938_PCIC_PCICCFG_G2PMEN(2)|
++			      TX4938_PCIC_PCICCFG_G2PIOEN);
++
++	/* GB->PCI mappings */
++	pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4;
++	pcicptr->g2piogbase = pci_io_base |
++#ifdef __BIG_ENDIAN
++		TX4938_PCIC_G2PIOGBASE_ECHG
++#else
++		TX4938_PCIC_G2PIOGBASE_BSDIS
++#endif
++		;
++	pcicptr->g2piopbase = 0;
++	for (i = 0; i < 3; i++) {
++		pcicptr->g2pmmask[i] = 0;
++		pcicptr->g2pmgbase[i] = 0;
++		pcicptr->g2pmpbase[i] = 0;
++	}
++	if (channel->mem_resource->end) {
++		pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4;
++		pcicptr->g2pmgbase[0] = channel->mem_resource->start |
++#ifdef __BIG_ENDIAN
++			TX4938_PCIC_G2PMnGBASE_ECHG
++#else
++			TX4938_PCIC_G2PMnGBASE_BSDIS
++#endif
++			;
++		pcicptr->g2pmpbase[0] = channel->mem_resource->start;
++	}
++	/* PCI->GB mappings (I/O 256B) */
++	pcicptr->p2giopbase = 0; /* 256B */
++	pcicptr->p2giogbase = 0;
++	/* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */
++	pcicptr->p2gm0plbase = 0;
++	pcicptr->p2gm0pubase = 0;
++	pcicptr->p2gmgbase[0] = 0 |
++		TX4938_PCIC_P2GMnGBASE_TMEMEN |
++#ifdef __BIG_ENDIAN
++		TX4938_PCIC_P2GMnGBASE_TECHG
++#else
++		TX4938_PCIC_P2GMnGBASE_TBSDIS
++#endif
++		;
++	/* PCI->GB mappings (MEM 16MB) */
++	pcicptr->p2gm1plbase = 0xffffffff;
++	pcicptr->p2gm1pubase = 0xffffffff;
++	pcicptr->p2gmgbase[1] = 0;
++	/* PCI->GB mappings (MEM 1MB) */
++	pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */
++	pcicptr->p2gmgbase[2] = 0;
++
++	pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK;
++	/* Enable Initiator Memory Space */
++	if (channel->mem_resource->end)
++		pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0);
++	/* Enable Initiator I/O Space */
++	if (channel->io_resource->end)
++		pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN;
++	/* Enable Initiator Config */
++	pcicptr->pciccfg |=
++		TX4938_PCIC_PCICCFG_ICAEN |
++		TX4938_PCIC_PCICCFG_TCAR;
++
++	/* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */
++	pcicptr->pcicfg1 = 0;
++
++	pcicptr->g2ptocnt &= ~0xffff;
++
++	if (tx4938_pcic_trdyto >= 0) {
++		pcicptr->g2ptocnt &= ~0xff;
++		pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff);
++	}
++
++	if (tx4938_pcic_retryto >= 0) {
++		pcicptr->g2ptocnt &= ~0xff00;
++		pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00);
++	}
++
++	/* Clear All Local Bus Status */
++	pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL;
++	/* Enable All Local Bus Interrupts */
++	pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL;
++	/* Clear All Initiator Status */
++	pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL;
++	/* Enable All Initiator Interrupts */
++	pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL;
++	/* Clear All PCI Status Error */
++	pcicptr->pcistatus =
++		(pcicptr->pcistatus & 0x0000ffff) |
++		(TX4938_PCIC_PCISTATUS_ALL << 16);
++	/* Enable All PCI Status Error Interrupts */
++	pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL;
++
++	if (!extarb) {
++		/* Reset Bus Arbiter */
++		pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA;
++		pcicptr->pbabm = 0;
++		/* Enable Bus Arbiter */
++		pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN;
++	}
++
++      /* PCIC Int => IRC IRQ16 */
++	pcicptr->pcicfg2 =
++		    (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC;
++
++	pcicptr->pcistatus = PCI_COMMAND_MASTER |
++		PCI_COMMAND_MEMORY |
++		PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
++}
++
++int __init
++tx4938_report_pciclk(void)
++{
++	unsigned long pcode = TX4938_REV_PCODE();
++	int pciclk = 0;
++	printk("TX%lx PCIC --%s PCICLK:",
++	       pcode,
++	       (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : "");
++	if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
++
++		switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) {
++		case TX4938_CCFG_PCIDIVMODE_4:
++			pciclk = txx9_cpu_clock / 4; break;
++		case TX4938_CCFG_PCIDIVMODE_4_5:
++			pciclk = txx9_cpu_clock * 2 / 9; break;
++		case TX4938_CCFG_PCIDIVMODE_5:
++			pciclk = txx9_cpu_clock / 5; break;
++		case TX4938_CCFG_PCIDIVMODE_5_5:
++			pciclk = txx9_cpu_clock * 2 / 11; break;
++		case TX4938_CCFG_PCIDIVMODE_8:
++			pciclk = txx9_cpu_clock / 8; break;
++		case TX4938_CCFG_PCIDIVMODE_9:
++			pciclk = txx9_cpu_clock / 9; break;
++		case TX4938_CCFG_PCIDIVMODE_10:
++			pciclk = txx9_cpu_clock / 10; break;
++		case TX4938_CCFG_PCIDIVMODE_11:
++			pciclk = txx9_cpu_clock / 11; break;
++		}
++		printk("Internal(%dMHz)", pciclk / 1000000);
++	} else {
++		printk("External");
++		pciclk = -1;
++	}
++	printk("\n");
++	return pciclk;
++}
++
++void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr)
++{
++	pcicptrs[ch] = pcicptr;
++}
++
++struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch)
++{
++       return pcicptrs[ch];
++}
++
++static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
++                                    int top_bus, int busnr, int devfn)
++{
++	static struct pci_dev dev;
++	static struct pci_bus bus;
++
++	dev.sysdata = (void *)hose;
++	dev.devfn = devfn;
++	bus.number = busnr;
++	bus.ops = hose->pci_ops;
++	bus.parent = NULL;
++	dev.bus = &bus;
++
++	return &dev;
++}
++
++#define EARLY_PCI_OP(rw, size, type)                                    \
++static int early_##rw##_config_##size(struct pci_controller *hose,      \
++        int top_bus, int bus, int devfn, int offset, type value)        \
++{                                                                       \
++        return pci_##rw##_config_##size(                                \
++                fake_pci_dev(hose, top_bus, bus, devfn),                \
++                offset, value);                                         \
++}
++
++EARLY_PCI_OP(read, word, u16 *)
++
++int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus)
++{
++	u32 pci_devfn;
++	unsigned short vid;
++	int devfn_start = 0;
++	int devfn_stop = 0xff;
++	int cap66 = -1;
++	u16 stat;
++
++	printk("PCI: Checking 66MHz capabilities...\n");
++
++	for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
++		early_read_config_word(hose, top_bus, current_bus, pci_devfn,
++				       PCI_VENDOR_ID, &vid);
++
++		if (vid == 0xffff) continue;
++
++		/* check 66MHz capability */
++		if (cap66 < 0)
++			cap66 = 1;
++		if (cap66) {
++			early_read_config_word(hose, top_bus, current_bus, pci_devfn,
++					       PCI_STATUS, &stat);
++			if (!(stat & PCI_STATUS_66MHZ)) {
++				printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n",
++				       current_bus, pci_devfn);
++				cap66 = 0;
++				break;
++			}
++		}
++	}
++	return cap66 > 0;
++}
++
++int __init
++tx4938_pciclk66_setup(void)
++{
++	int pciclk;
++
++	/* Assert M66EN */
++	tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66;
++	/* Double PCICLK (if possible) */
++	if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
++		unsigned int pcidivmode =
++			tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK;
++		switch (pcidivmode) {
++		case TX4938_CCFG_PCIDIVMODE_8:
++		case TX4938_CCFG_PCIDIVMODE_4:
++			pcidivmode = TX4938_CCFG_PCIDIVMODE_4;
++			pciclk = txx9_cpu_clock / 4;
++			break;
++		case TX4938_CCFG_PCIDIVMODE_9:
++		case TX4938_CCFG_PCIDIVMODE_4_5:
++			pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5;
++			pciclk = txx9_cpu_clock * 2 / 9;
++			break;
++		case TX4938_CCFG_PCIDIVMODE_10:
++		case TX4938_CCFG_PCIDIVMODE_5:
++			pcidivmode = TX4938_CCFG_PCIDIVMODE_5;
++			pciclk = txx9_cpu_clock / 5;
++			break;
++		case TX4938_CCFG_PCIDIVMODE_11:
++		case TX4938_CCFG_PCIDIVMODE_5_5:
++		default:
++			pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5;
++			pciclk = txx9_cpu_clock * 2 / 11;
++			break;
++		}
++		tx4938_ccfgptr->ccfg =
++			(tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK)
++			| pcidivmode;
++		printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n",
++		       (unsigned long)tx4938_ccfgptr->ccfg);
++	} else {
++		pciclk = -1;
++	}
++	return pciclk;
++}
++
++extern struct pci_controller tx4938_pci_controller[];
++static int __init tx4938_pcibios_init(void)
++{
++	unsigned long mem_base[2];
++	unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0,TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */
++	unsigned long io_base[2];
++	unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0,TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */
++	/* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */
++	int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
++
++	PCIBIOS_MIN_IO = 0x00001000UL;
++	PCIBIOS_MIN_MEM = 0x01000000UL;
++
++	mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
++	io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
++
++	printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
++	       (unsigned short)(tx4938_pcicptr->pciid >> 16),
++	       (unsigned short)(tx4938_pcicptr->pciid & 0xffff),
++	       (unsigned short)(tx4938_pcicptr->pciccrev & 0xff),
++	       extarb ? "External" : "Internal");
++
++	/* setup PCI area */
++	tx4938_pci_controller[0].io_resource->start = io_base[0];
++	tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1;
++	tx4938_pci_controller[0].mem_resource->start = mem_base[0];
++	tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1;
++
++	set_tx4938_pcicptr(0, tx4938_pcicptr);
++
++	register_pci_controller(&tx4938_pci_controller[0]);
++
++	if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) {
++		printk("TX4938_CCFG_PCI66 already configured\n");
++		txboard_pci66_mode = -1; /* already configured */
++	}
++
++	/* Reset PCI Bus */
++	*rbtx4938_pcireset_ptr = 0;
++	/* Reset PCIC */
++	tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
++	if (txboard_pci66_mode > 0)
++		tx4938_pciclk66_setup();
++	mdelay(10);
++	/* clear PCIC reset */
++	tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
++	*rbtx4938_pcireset_ptr = 1;
++	wbflush();
++	tx4938_report_pcic_status1(tx4938_pcicptr);
++
++	tx4938_report_pciclk();
++	tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
++	if (txboard_pci66_mode == 0 &&
++	    txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) {
++		/* Reset PCI Bus */
++		*rbtx4938_pcireset_ptr = 0;
++		/* Reset PCIC */
++		tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
++		tx4938_pciclk66_setup();
++		mdelay(10);
++		/* clear PCIC reset */
++		tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
++		*rbtx4938_pcireset_ptr = 1;
++		wbflush();
++		/* Reinitialize PCIC */
++		tx4938_report_pciclk();
++		tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
++	}
++
++	mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]);
++	io_base[1] = txboard_request_phys_region_shrink(&io_size[1]);
++	/* Reset PCIC1 */
++	tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST;
++	/* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */
++	if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD))
++		tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66;
++	else
++		tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66;
++	mdelay(10);
++	/* clear PCIC1 reset */
++	tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
++	tx4938_report_pcic_status1(tx4938_pcic1ptr);
++
++	printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x",
++	       (unsigned short)(tx4938_pcic1ptr->pciid >> 16),
++	       (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff),
++	       (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff));
++	printk("%s PCICLK:%dMHz\n",
++	       (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "",
++	       txx9_gbus_clock /
++	       ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) /
++	       1000000);
++
++	/* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */
++	tx4938_pci_controller[1].io_resource->start =
++		io_base[1] - io_base[0];
++	tx4938_pci_controller[1].io_resource->end =
++		io_base[1] - io_base[0] + io_size[1] - 1;
++	tx4938_pci_controller[1].mem_resource->start = mem_base[1];
++	tx4938_pci_controller[1].mem_resource->end =
++		mem_base[1] + mem_size[1] - 1;
++	set_tx4938_pcicptr(1, tx4938_pcic1ptr);
++
++	register_pci_controller(&tx4938_pci_controller[1]);
++
++	tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb);
++
++	/* map ioport 0 to PCI I/O space address 0 */
++	set_io_port_base(KSEG1 + io_base[0]);
++
++	return 0;
++}
++
++arch_initcall(tx4938_pcibios_init);
++
++#endif /* CONFIG_PCI */
++
++/* SPI support */
++
++/* chip select for SPI devices */
++#define	SEEPROM1_CS	7	/* PIO7 */
++#define	SEEPROM2_CS	0	/* IOC */
++#define	SEEPROM3_CS	1	/* IOC */
++#define	SRTC_CS	2	/* IOC */
++
++static int rbtx4938_spi_cs_func(int chipid, int on)
++{
++	unsigned char bit;
++	switch (chipid) {
++	case RBTX4938_SEEPROM1_CHIPID:
++		if (on)
++			tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS);
++		else
++			tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
++		return 0;
++		break;
++	case RBTX4938_SEEPROM2_CHIPID:
++		bit = (1 << SEEPROM2_CS);
++		break;
++	case RBTX4938_SEEPROM3_CHIPID:
++		bit = (1 << SEEPROM3_CS);
++		break;
++	case RBTX4938_SRTC_CHIPID:
++		bit = (1 << SRTC_CS);
++		break;
++	default:
++		return -ENODEV;
++	}
++	/* bit1,2,4 are low active, bit3 is high active */
++	*rbtx4938_spics_ptr =
++		(*rbtx4938_spics_ptr & ~bit) |
++		((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit);
++	return 0;
++}
++
++#ifdef CONFIG_PCI
++extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
++
++int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
++{
++	struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
++	static unsigned char dat[17];
++	static int read_dat = 0;
++	int ch = 0;
++
++	if (channel != &tx4938_pci_controller[1])
++		return -ENODEV;
++	/* TX4938 PCIC1 */
++	switch (PCI_SLOT(dev->devfn)) {
++	case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
++		ch = 0;
++		break;
++	case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
++		ch = 1;
++		break;
++	default:
++		return -ENODEV;
++	}
++	if (!read_dat) {
++		unsigned char sum;
++		int i;
++		read_dat = 1;
++		/* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
++		if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID,
++				    0, dat, sizeof(dat))) {
++			printk(KERN_ERR "seeprom: read error.\n");
++		} else {
++			if (strcmp(dat, "MAC") != 0)
++				printk(KERN_WARNING "seeprom: bad signature.\n");
++			for (i = 0, sum = 0; i < sizeof(dat); i++)
++				sum += dat[i];
++			if (sum)
++				printk(KERN_WARNING "seeprom: bad checksum.\n");
++		}
++	}
++	memcpy(addr, &dat[4 + 6 * ch], 6);
++	return 0;
++}
++#endif /* CONFIG_PCI */
++
++extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on));
++static void __init rbtx4938_spi_setup(void)
++{
++	/* set SPI_SEL */
++	tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL;
++	/* chip selects for SPI devices */
++	tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
++	tx4938_pioptr->dir |= (1 << SEEPROM1_CS);
++	txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func);
++}
++
++static struct resource rbtx4938_fpga_resource;
++
++static char pcode_str[8];
++static struct resource tx4938_reg_resource = {
++	pcode_str, TX4938_REG_BASE, TX4938_REG_BASE+TX4938_REG_SIZE, IORESOURCE_MEM
++};
++
++void __init tx4938_board_setup(void)
++{
++	int i;
++	unsigned long divmode;
++	int cpuclk = 0;
++	unsigned long pcode = TX4938_REV_PCODE();
++
++	ioport_resource.start = 0x1000;
++	ioport_resource.end = 0xffffffff;
++	iomem_resource.start = 0x1000;
++	iomem_resource.end = 0xffffffff;	/* expand to 4GB */
++
++	sprintf(pcode_str, "TX%lx", pcode);
++	/* SDRAMC,EBUSC are configured by PROM */
++	for (i = 0; i < 8; i++) {
++		if (!(tx4938_ebuscptr->cr[i] & 0x8))
++			continue;	/* disabled */
++ 		rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i);
++		txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i));
++	}
++
++	/* clocks */
++	if (txx9_master_clock) {
++		/* calculate gbus_clock and cpu_clock from master_clock */
++		divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
++		switch (divmode) {
++		case TX4938_CCFG_DIVMODE_8:
++		case TX4938_CCFG_DIVMODE_10:
++		case TX4938_CCFG_DIVMODE_12:
++		case TX4938_CCFG_DIVMODE_16:
++		case TX4938_CCFG_DIVMODE_18:
++			txx9_gbus_clock = txx9_master_clock * 4; break;
++		default:
++			txx9_gbus_clock = txx9_master_clock;
++		}
++		switch (divmode) {
++		case TX4938_CCFG_DIVMODE_2:
++		case TX4938_CCFG_DIVMODE_8:
++			cpuclk = txx9_gbus_clock * 2; break;
++		case TX4938_CCFG_DIVMODE_2_5:
++		case TX4938_CCFG_DIVMODE_10:
++			cpuclk = txx9_gbus_clock * 5 / 2; break;
++		case TX4938_CCFG_DIVMODE_3:
++		case TX4938_CCFG_DIVMODE_12:
++			cpuclk = txx9_gbus_clock * 3; break;
++		case TX4938_CCFG_DIVMODE_4:
++		case TX4938_CCFG_DIVMODE_16:
++			cpuclk = txx9_gbus_clock * 4; break;
++		case TX4938_CCFG_DIVMODE_4_5:
++		case TX4938_CCFG_DIVMODE_18:
++			cpuclk = txx9_gbus_clock * 9 / 2; break;
++		}
++		txx9_cpu_clock = cpuclk;
++	} else {
++		if (txx9_cpu_clock == 0) {
++			txx9_cpu_clock = 300000000;	/* 300MHz */
++		}
++		/* calculate gbus_clock and master_clock from cpu_clock */
++		cpuclk = txx9_cpu_clock;
++		divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
++		switch (divmode) {
++		case TX4938_CCFG_DIVMODE_2:
++		case TX4938_CCFG_DIVMODE_8:
++			txx9_gbus_clock = cpuclk / 2; break;
++		case TX4938_CCFG_DIVMODE_2_5:
++		case TX4938_CCFG_DIVMODE_10:
++			txx9_gbus_clock = cpuclk * 2 / 5; break;
++		case TX4938_CCFG_DIVMODE_3:
++		case TX4938_CCFG_DIVMODE_12:
++			txx9_gbus_clock = cpuclk / 3; break;
++		case TX4938_CCFG_DIVMODE_4:
++		case TX4938_CCFG_DIVMODE_16:
++			txx9_gbus_clock = cpuclk / 4; break;
++		case TX4938_CCFG_DIVMODE_4_5:
++		case TX4938_CCFG_DIVMODE_18:
++			txx9_gbus_clock = cpuclk * 2 / 9; break;
++		}
++		switch (divmode) {
++		case TX4938_CCFG_DIVMODE_8:
++		case TX4938_CCFG_DIVMODE_10:
++		case TX4938_CCFG_DIVMODE_12:
++		case TX4938_CCFG_DIVMODE_16:
++		case TX4938_CCFG_DIVMODE_18:
++			txx9_master_clock = txx9_gbus_clock / 4; break;
++		default:
++			txx9_master_clock = txx9_gbus_clock;
++		}
++	}
++	/* change default value to udelay/mdelay take reasonable time */
++	loops_per_jiffy = txx9_cpu_clock / HZ / 2;
++
++	/* CCFG */
++	/* clear WatchDogReset,BusErrorOnWrite flag (W1C) */
++	tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW;
++	/* clear PCIC1 reset */
++	if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST)
++		tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
++
++	/* enable Timeout BusError */
++	if (tx4938_ccfg_toeon)
++		tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE;
++
++	/* DMA selection */
++	tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL;
++
++	/* Use external clock for external arbiter */
++	if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB))
++		tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL;
++
++	printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n",
++	       pcode_str,
++	       cpuclk / 1000000, txx9_master_clock / 1000000,
++	       (unsigned long)tx4938_ccfgptr->crir,
++	       tx4938_ccfgptr->ccfg,
++	       tx4938_ccfgptr->pcfg);
++
++	printk("%s SDRAMC --", pcode_str);
++	for (i = 0; i < 4; i++) {
++		unsigned long long cr = tx4938_sdramcptr->cr[i];
++		unsigned long ram_base, ram_size;
++		if (!((unsigned long)cr & 0x00000400))
++			continue;	/* disabled */
++		ram_base = (unsigned long)(cr >> 49) << 21;
++		ram_size = ((unsigned long)(cr >> 33) + 1) << 21;
++		if (ram_base >= 0x20000000)
++			continue;	/* high memory (ignore) */
++		printk(" CR%d:%016Lx", i, cr);
++		txboard_add_phys_region(ram_base, ram_size);
++	}
++	printk(" TR:%09Lx\n", tx4938_sdramcptr->tr);
++
++	/* SRAM */
++	if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) {
++		unsigned int size = 0x800;
++		unsigned long base =
++			(tx4938_sramcptr->cr >> (39-11)) & ~(size - 1);
++		 txboard_add_phys_region(base, size);
++	}
++
++	/* IRC */
++	/* disable interrupt control */
++	tx4938_ircptr->cer = 0;
++
++	/* TMR */
++	/* disable all timers */
++	for (i = 0; i < TX4938_NR_TMR; i++) {
++		tx4938_tmrptr(i)->tcr  = 0x00000020;
++		tx4938_tmrptr(i)->tisr = 0;
++		tx4938_tmrptr(i)->cpra = 0xffffffff;
++		tx4938_tmrptr(i)->itmr = 0;
++		tx4938_tmrptr(i)->ccdr = 0;
++		tx4938_tmrptr(i)->pgmr = 0;
++	}
++
++	/* enable DMA */
++	TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN);
++	TX4938_WR64(0xff1fb950, TX4938_DMA_MCR_MSTEN);
++
++	/* PIO */
++	tx4938_pioptr->maskcpu = 0;
++	tx4938_pioptr->maskext = 0;
++
++	/* TX4938 internal registers */
++	if (request_resource(&iomem_resource, &tx4938_reg_resource))
++		printk("request resource for internal registers failed\n");
++}
++
++#ifdef CONFIG_PCI
++static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr)
++{
++	unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16);
++	unsigned long g2pstatus = pcicptr->g2pstatus;
++	unsigned long pcicstatus = pcicptr->pcicstatus;
++	static struct {
++		unsigned long flag;
++		const char *str;
++	} pcistat_tbl[] = {
++		{ PCI_STATUS_DETECTED_PARITY,	"DetectedParityError" },
++		{ PCI_STATUS_SIG_SYSTEM_ERROR,	"SignaledSystemError" },
++		{ PCI_STATUS_REC_MASTER_ABORT,	"ReceivedMasterAbort" },
++		{ PCI_STATUS_REC_TARGET_ABORT,	"ReceivedTargetAbort" },
++		{ PCI_STATUS_SIG_TARGET_ABORT,	"SignaledTargetAbort" },
++		{ PCI_STATUS_PARITY,	"MasterParityError" },
++	}, g2pstat_tbl[] = {
++		{ TX4938_PCIC_G2PSTATUS_TTOE,	"TIOE" },
++		{ TX4938_PCIC_G2PSTATUS_RTOE,	"RTOE" },
++	}, pcicstat_tbl[] = {
++		{ TX4938_PCIC_PCICSTATUS_PME,	"PME" },
++		{ TX4938_PCIC_PCICSTATUS_TLB,	"TLB" },
++		{ TX4938_PCIC_PCICSTATUS_NIB,	"NIB" },
++		{ TX4938_PCIC_PCICSTATUS_ZIB,	"ZIB" },
++		{ TX4938_PCIC_PCICSTATUS_PERR,	"PERR" },
++		{ TX4938_PCIC_PCICSTATUS_SERR,	"SERR" },
++		{ TX4938_PCIC_PCICSTATUS_GBE,	"GBE" },
++		{ TX4938_PCIC_PCICSTATUS_IWB,	"IWB" },
++	};
++	int i;
++
++	printk("pcistat:%04x(", pcistatus);
++	for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++)
++		if (pcistatus & pcistat_tbl[i].flag)
++			printk("%s ", pcistat_tbl[i].str);
++	printk("), g2pstatus:%08lx(", g2pstatus);
++	for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++)
++		if (g2pstatus & g2pstat_tbl[i].flag)
++			printk("%s ", g2pstat_tbl[i].str);
++	printk("), pcicstatus:%08lx(", pcicstatus);
++	for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++)
++		if (pcicstatus & pcicstat_tbl[i].flag)
++			printk("%s ", pcicstat_tbl[i].str);
++	printk(")\n");
++}
++
++void tx4938_report_pcic_status(void)
++{
++	int i;
++	struct tx4938_pcic_reg *pcicptr;
++	for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++)
++		tx4938_report_pcic_status1(pcicptr);
++}
++
++#endif /* CONFIG_PCI */
++
++/* We use onchip r4k counter or TMR timer as our system wide timer
++ * interrupt running at 100HZ. */
++
++extern void __init rtc_rx5c348_init(int chipid);
++void __init rbtx4938_time_init(void)
++{
++	rtc_rx5c348_init(RBTX4938_SRTC_CHIPID);
++	mips_hpt_frequency = txx9_cpu_clock / 2;
++}
++
++void __init toshiba_rbtx4938_setup(void)
++{
++	unsigned long long pcfg;
++	char *argptr;
++
++	iomem_resource.end = 0xffffffff;	/* 4GB */
++
++	if (txx9_master_clock == 0)
++		txx9_master_clock = 25000000; /* 25MHz */
++	tx4938_board_setup();
++	/* setup irq stuff */
++	TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000000);	/* irq trigger */
++	TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM1), 0x00000000);	/* irq trigger */
++	/* setup serial stuff */
++	TX4938_WR(0xff1ff314, 0x00000000);	/* h/w flow control off */
++	TX4938_WR(0xff1ff414, 0x00000000);	/* h/w flow control off */
++
++#ifndef CONFIG_PCI
++	set_io_port_base(RBTX4938_ETHER_BASE);
++#endif
++
++#ifdef CONFIG_SERIAL_TXX9
++	{
++		extern int early_serial_txx9_setup(struct uart_port *port);
++		int i;
++		struct uart_port req;
++		for(i = 0; i < 2; i++) {
++			memset(&req, 0, sizeof(req));
++			req.line = i;
++			req.iotype = UPIO_MEM;
++			req.membase = (char *)(0xff1ff300 + i * 0x100);
++			req.mapbase = 0xff1ff300 + i * 0x100;
++			req.irq = 32 + i;
++			req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
++			req.uartclk = 50000000;
++			early_serial_txx9_setup(&req);
++		}
++	}
++#ifdef CONFIG_SERIAL_TXX9_CONSOLE
++        argptr = prom_getcmdline();
++        if (strstr(argptr, "console=") == NULL) {
++                strcat(argptr, " console=ttyS0,38400");
++        }
++#endif
++#endif
++
++#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
++	printk("PIOSEL: disabling both ata and nand selection\n");
++	local_irq_disable();
++	tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
++#endif
++
++#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
++	printk("PIOSEL: enabling nand selection\n");
++	tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL;
++	tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL;
++#endif
++
++#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
++	printk("PIOSEL: enabling ata selection\n");
++	tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL;
++	tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL;
++#endif
++
++#ifdef CONFIG_IP_PNP
++	argptr = prom_getcmdline();
++	if (strstr(argptr, "ip=") == NULL) {
++		strcat(argptr, " ip=any");
++	}
++#endif
++
++
++#ifdef CONFIG_FB
++	{
++		conswitchp = &dummy_con;
++	}
++#endif
++
++	rbtx4938_spi_setup();
++	pcfg = tx4938_ccfgptr->pcfg;	/* updated */
++	/* fixup piosel */
++	if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
++	    TX4938_PCFG_ATA_SEL) {
++		*rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x04;
++	}
++	else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
++	    TX4938_PCFG_NDF_SEL) {
++		*rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x08;
++	}
++	else {
++		*rbtx4938_piosel_ptr &= ~(0x08 | 0x04);
++	}
++
++	rbtx4938_fpga_resource.name = "FPGA Registers";
++	rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
++	rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff;
++	rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++	if (request_resource(&iomem_resource, &rbtx4938_fpga_resource))
++		printk("request resource for fpga failed\n");
++
++	/* disable all OnBoard I/O interrupts */
++	*rbtx4938_imask_ptr = 0;
++
++	_machine_restart = rbtx4938_machine_restart;
++	_machine_halt = rbtx4938_machine_halt;
++	_machine_power_off = rbtx4938_machine_power_off;
++
++	*rbtx4938_led_ptr = 0xff;
++	printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr);
++	printk(" DIPSW:%02x,%02x\n",
++	       *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr);
++}
++
++#ifdef CONFIG_PROC_FS
++extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid);
++static int __init tx4938_spi_proc_setup(void)
++{
++	struct proc_dir_entry *tx4938_spi_eeprom_dir;
++
++	tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0);
++
++	if (!tx4938_spi_eeprom_dir)
++		return -ENOMEM;
++
++	/* don't allow user access to RBTX4938_SEEPROM1_CHIPID
++	 * as it contains eth0 and eth1 MAC addresses
++	 */
++	spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID);
++	spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID);
++
++	return 0;
++}
++
++__initcall(tx4938_spi_proc_setup);
++#endif
+diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
+@@ -0,0 +1,219 @@
++/*
++ * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/proc_fs.h>
++#include <linux/spinlock.h>
++#include <asm/tx4938/spi.h>
++#include <asm/tx4938/tx4938.h>
++
++/* ATMEL 250x0 instructions */
++#define	ATMEL_WREN	0x06
++#define	ATMEL_WRDI	0x04
++#define ATMEL_RDSR	0x05
++#define ATMEL_WRSR	0x01
++#define	ATMEL_READ	0x03
++#define	ATMEL_WRITE	0x02
++
++#define ATMEL_SR_BSY	0x01
++#define ATMEL_SR_WEN	0x02
++#define ATMEL_SR_BP0	0x04
++#define ATMEL_SR_BP1	0x08
++
++DEFINE_SPINLOCK(spi_eeprom_lock);
++
++static struct spi_dev_desc seeprom_dev_desc = {
++	.baud 		= 1500000,	/* 1.5Mbps */
++	.tcss		= 1,
++	.tcsh		= 1,
++	.tcsr		= 1,
++	.byteorder	= 1,		/* MSB-First */
++	.polarity	= 0,		/* High-Active */
++	.phase		= 0,		/* Sample-Then-Shift */
++
++};
++static inline int
++spi_eeprom_io(int chipid,
++	      unsigned char **inbufs, unsigned int *incounts,
++	      unsigned char **outbufs, unsigned int *outcounts)
++{
++	return txx9_spi_io(chipid, &seeprom_dev_desc,
++			   inbufs, incounts, outbufs, outcounts, 0);
++}
++
++int spi_eeprom_write_enable(int chipid, int enable)
++{
++	unsigned char inbuf[1];
++	unsigned char *inbufs[1];
++	unsigned int incounts[2];
++	unsigned long flags;
++	int stat;
++	inbuf[0] = enable ? ATMEL_WREN : ATMEL_WRDI;
++	inbufs[0] = inbuf;
++	incounts[0] = sizeof(inbuf);
++	incounts[1] = 0;
++	spin_lock_irqsave(&spi_eeprom_lock, flags);
++	stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
++	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
++	return stat;
++}
++
++static int spi_eeprom_read_status_nolock(int chipid)
++{
++	unsigned char inbuf[2], outbuf[2];
++	unsigned char *inbufs[1], *outbufs[1];
++	unsigned int incounts[2], outcounts[2];
++	int stat;
++	inbuf[0] = ATMEL_RDSR;
++	inbuf[1] = 0;
++	inbufs[0] = inbuf;
++	incounts[0] = sizeof(inbuf);
++	incounts[1] = 0;
++	outbufs[0] = outbuf;
++	outcounts[0] = sizeof(outbuf);
++	outcounts[1] = 0;
++	stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
++	if (stat < 0)
++		return stat;
++	return outbuf[1];
++}
++
++int spi_eeprom_read_status(int chipid)
++{
++	unsigned long flags;
++	int stat;
++	spin_lock_irqsave(&spi_eeprom_lock, flags);
++	stat = spi_eeprom_read_status_nolock(chipid);
++	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
++	return stat;
++}
++
++int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len)
++{
++	unsigned char inbuf[2];
++	unsigned char *inbufs[2], *outbufs[2];
++	unsigned int incounts[2], outcounts[3];
++	unsigned long flags;
++	int stat;
++	inbuf[0] = ATMEL_READ;
++	inbuf[1] = address;
++	inbufs[0] = inbuf;
++	inbufs[1] = NULL;
++	incounts[0] = sizeof(inbuf);
++	incounts[1] = 0;
++	outbufs[0] = NULL;
++	outbufs[1] = buf;
++	outcounts[0] = 2;
++	outcounts[1] = len;
++	outcounts[2] = 0;
++	spin_lock_irqsave(&spi_eeprom_lock, flags);
++	stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
++	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
++	return stat;
++}
++
++int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len)
++{
++	unsigned char inbuf[2];
++	unsigned char *inbufs[2];
++	unsigned int incounts[3];
++	unsigned long flags;
++	int i, stat;
++
++	if (address / 8 != (address + len - 1) / 8)
++		return -EINVAL;
++	stat = spi_eeprom_write_enable(chipid, 1);
++	if (stat < 0)
++		return stat;
++	stat = spi_eeprom_read_status(chipid);
++	if (stat < 0)
++		return stat;
++	if (!(stat & ATMEL_SR_WEN))
++		return -EPERM;
++
++	inbuf[0] = ATMEL_WRITE;
++	inbuf[1] = address;
++	inbufs[0] = inbuf;
++	inbufs[1] = buf;
++	incounts[0] = sizeof(inbuf);
++	incounts[1] = len;
++	incounts[2] = 0;
++	spin_lock_irqsave(&spi_eeprom_lock, flags);
++	stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
++	if (stat < 0)
++		goto unlock_return;
++
++	/* write start.  max 10ms */
++	for (i = 10; i > 0; i--) {
++		int stat = spi_eeprom_read_status_nolock(chipid);
++		if (stat < 0)
++			goto unlock_return;
++		if (!(stat & ATMEL_SR_BSY))
++			break;
++		mdelay(1);
++	}
++	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
++	if (i == 0)
++		return -EIO;
++	return len;
++ unlock_return:
++	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
++	return stat;
++}
++
++#ifdef CONFIG_PROC_FS
++#define MAX_SIZE	0x80	/* for ATMEL 25010 */
++static int spi_eeprom_read_proc(char *page, char **start, off_t off,
++				int count, int *eof, void *data)
++{
++	unsigned int size = MAX_SIZE;
++	if (spi_eeprom_read((int)data, 0, (unsigned char *)page, size) < 0)
++		size = 0;
++	return size;
++}
++
++static int spi_eeprom_write_proc(struct file *file, const char *buffer,
++				 unsigned long count, void *data)
++{
++	unsigned int size = MAX_SIZE;
++	int i;
++	if (file->f_pos >= size)
++		return -EIO;
++	if (file->f_pos + count > size)
++		count = size - file->f_pos;
++	for (i = 0; i < count; i += 8) {
++		int len = count - i < 8 ? count - i : 8;
++		if (spi_eeprom_write((int)data, file->f_pos,
++				     (unsigned char *)buffer, len) < 0) {
++			count = -EIO;
++			break;
++		}
++		buffer += len;
++		file->f_pos += len;
++	}
++	return count;
++}
++
++__init void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid)
++{
++	struct proc_dir_entry *entry;
++	char name[128];
++	sprintf(name, "seeprom-%d", chipid);
++	entry = create_proc_entry(name, 0600, dir);
++	if (entry) {
++		entry->read_proc = spi_eeprom_read_proc;
++		entry->write_proc = spi_eeprom_write_proc;
++		entry->data = (void *)chipid;
++	}
++}
++#endif /* CONFIG_PROC_FS */
+diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
+@@ -0,0 +1,159 @@
++/*
++ * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/spinlock.h>
++#include <linux/wait.h>
++#include <asm/tx4938/spi.h>
++#include <asm/tx4938/tx4938.h>
++
++static int (*txx9_spi_cs_func)(int chipid, int on);
++static DEFINE_SPINLOCK(txx9_spi_lock);
++
++extern unsigned int txx9_gbus_clock;
++
++#define SPI_FIFO_SIZE	4
++
++void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on))
++{
++	txx9_spi_cs_func = cs_func;
++	/* enter config mode */
++	tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
++}
++
++static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
++static void txx9_spi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	/* disable rx intr */
++	tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
++	wake_up(&txx9_spi_wait);
++}
++static struct irqaction txx9_spi_action = {
++	txx9_spi_interrupt, 0, 0, "spi", NULL, NULL,
++};
++
++void __init txx9_spi_irqinit(int irc_irq)
++{
++	setup_irq(irc_irq, &txx9_spi_action);
++}
++
++int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
++		unsigned char **inbufs, unsigned int *incounts,
++		unsigned char **outbufs, unsigned int *outcounts,
++		int cansleep)
++{
++	unsigned int incount, outcount;
++	unsigned char *inp, *outp;
++	int ret;
++	unsigned long flags;
++
++	spin_lock_irqsave(&txx9_spi_lock, flags);
++	if ((tx4938_spiptr->mcr & TXx9_SPMCR_OPMODE) == TXx9_SPMCR_ACTIVE) {
++		spin_unlock_irqrestore(&txx9_spi_lock, flags);
++		return -EBUSY;
++	}
++	/* enter config mode */
++	tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
++	tx4938_spiptr->cr0 =
++		(desc->byteorder ? TXx9_SPCR0_SBOS : 0) |
++		(desc->polarity ? TXx9_SPCR0_SPOL : 0) |
++		(desc->phase ? TXx9_SPCR0_SPHA : 0) |
++		0x08;
++	tx4938_spiptr->cr1 =
++		(((TXX9_IMCLK + desc->baud) / (2 * desc->baud) - 1) << 8) |
++		0x08 /* 8 bit only */;
++	/* enter active mode */
++	tx4938_spiptr->mcr = TXx9_SPMCR_ACTIVE;
++	spin_unlock_irqrestore(&txx9_spi_lock, flags);
++
++	/* CS ON */
++	if ((ret = txx9_spi_cs_func(chipid, 1)) < 0) {
++		spin_unlock_irqrestore(&txx9_spi_lock, flags);
++		return ret;
++	}
++	udelay(desc->tcss);
++
++	/* do scatter IO */
++	inp = inbufs ? *inbufs : NULL;
++	outp = outbufs ? *outbufs : NULL;
++	incount = 0;
++	outcount = 0;
++	while (1) {
++		unsigned char data;
++		unsigned int count;
++		int i;
++		if (!incount) {
++			incount = incounts ? *incounts++ : 0;
++			inp = (incount && inbufs) ? *inbufs++ : NULL;
++		}
++		if (!outcount) {
++			outcount = outcounts ? *outcounts++ : 0;
++			outp = (outcount && outbufs) ? *outbufs++ : NULL;
++		}
++		if (!inp && !outp)
++			break;
++		count = SPI_FIFO_SIZE;
++		if (incount)
++			count = min(count, incount);
++		if (outcount)
++			count = min(count, outcount);
++
++		/* now tx must be idle... */
++		while (!(tx4938_spiptr->sr & TXx9_SPSR_SIDLE))
++			;
++
++		tx4938_spiptr->cr0 =
++			(tx4938_spiptr->cr0 & ~TXx9_SPCR0_RXIFL_MASK) |
++			((count - 1) << 12);
++		if (cansleep) {
++			/* enable rx intr */
++			tx4938_spiptr->cr0 |= TXx9_SPCR0_RBSIE;
++		}
++		/* send */
++		for (i = 0; i < count; i++)
++			tx4938_spiptr->dr = inp ? *inp++ : 0;
++		/* wait all rx data */
++		if (cansleep) {
++			wait_event(txx9_spi_wait,
++				   tx4938_spiptr->sr & TXx9_SPSR_SRRDY);
++		} else {
++			while (!(tx4938_spiptr->sr & TXx9_SPSR_RBSI))
++				;
++		}
++		/* receive */
++		for (i = 0; i < count; i++) {
++			data = tx4938_spiptr->dr;
++			if (outp)
++				*outp++ = data;
++		}
++		if (incount)
++			incount -= count;
++		if (outcount)
++			outcount -= count;
++	}
++
++	/* CS OFF */
++	udelay(desc->tcsh);
++	txx9_spi_cs_func(chipid, 0);
++	udelay(desc->tcsr);
++
++	spin_lock_irqsave(&txx9_spi_lock, flags);
++	/* enter config mode */
++	tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
++	spin_unlock_irqrestore(&txx9_spi_lock, flags);
++
++	return 0;
++}
+diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/mips/vr41xx/Kconfig
+@@ -0,0 +1,88 @@
++config CASIO_E55
++	bool "Support for CASIO CASSIOPEIA E-10/15/55/65"
++	depends on MACH_VR41XX
++	select DMA_NONCOHERENT
++	select IRQ_CPU
++	select ISA
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++
++config IBM_WORKPAD
++	bool "Support for IBM WorkPad z50"
++	depends on MACH_VR41XX
++	select DMA_NONCOHERENT
++	select IRQ_CPU
++	select ISA
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++
++config NEC_CMBVR4133
++	bool "Support for NEC CMB-VR4133"
++	depends on MACH_VR41XX
++	select CPU_VR41XX
++	select DMA_NONCOHERENT
++	select IRQ_CPU
++	select HW_HAS_PCI
++
++config ROCKHOPPER
++	bool "Support for Rockhopper baseboard"
++	depends on NEC_CMBVR4133
++	select I8259
++	select HAVE_STD_PC_SERIAL_PORT
++
++config TANBAC_TB022X
++	bool "Support for TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
++	depends on MACH_VR41XX
++	select DMA_NONCOHERENT
++	select HW_HAS_PCI
++	select IRQ_CPU
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++	help
++	  The TANBAC VR4131 multichip module(TB0225) and
++	  the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms
++	  manufactured by TANBAC.
++	  Please refer to <http://www.tanbac.co.jp/>
++	  about VR4131 multichip module and VR4131DIMM.
++
++config TANBAC_TB0226
++	bool "Support for TANBAC Mbase(TB0226)"
++	depends on TANBAC_TB022X
++	select GPIO_VR41XX
++	help
++	  The TANBAC Mbase(TB0226) is a MIPS-based platform
++	  manufactured by TANBAC.
++	  Please refer to <http://www.tanbac.co.jp/> about Mbase.
++
++config TANBAC_TB0287
++	bool "Support for TANBAC Mini-ITX DIMM base(TB0287)"
++	depends on TANBAC_TB022X
++	help
++	  The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform
++	  manufactured by TANBAC.
++	  Please refer to <http://www.tanbac.co.jp/> about Mini-ITX DIMM base.
++
++config VICTOR_MPC30X
++	bool "Support for Victor MP-C303/304"
++	depends on MACH_VR41XX
++	select DMA_NONCOHERENT
++	select HW_HAS_PCI
++	select IRQ_CPU
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++
++config ZAO_CAPCELLA
++	bool "Support for ZAO Networks Capcella"
++	depends on MACH_VR41XX
++	select DMA_NONCOHERENT
++	select HW_HAS_PCI
++	select IRQ_CPU
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++
++config PCI_VR41XX
++	bool "Add PCI control unit support of NEC VR4100 series"
++	depends on MACH_VR41XX && HW_HAS_PCI
++	default y
++	select PCI
++
++config VRC4173
++	tristate "Add NEC VRC4173 companion chip support"
++	depends on MACH_VR41XX && PCI_VR41XX
++	help
++	  The NEC VRC4173 is a companion chip for NEC VR4122/VR4131.
+diff --git a/arch/mips/vr41xx/common/cmu.c b/arch/mips/vr41xx/common/cmu.c
+--- a/arch/mips/vr41xx/common/cmu.c
++++ b/arch/mips/vr41xx/common/cmu.c
+@@ -69,7 +69,7 @@
+ 
+ static void __iomem *cmu_base;
+ static uint16_t cmuclkmsk, cmuclkmsk2;
+-static spinlock_t cmu_lock;
++static DEFINE_SPINLOCK(cmu_lock);
+ 
+ #define cmu_read(offset)		readw(cmu_base + (offset))
+ #define cmu_write(offset, value)	writew((value), cmu_base + (offset))
+diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c
+--- a/arch/mips/vr41xx/common/init.c
++++ b/arch/mips/vr41xx/common/init.c
+@@ -58,6 +58,14 @@ static void __init timer_init(void)
+ 	board_timer_setup = setup_timer_irq;
+ }
+ 
++void __init plat_setup(void)
++{
++	vr41xx_calculate_clock_frequency();
++
++	timer_init();
++	iomem_resource_init();
++}
++
+ void __init prom_init(void)
+ {
+ 	int argc, i;
+@@ -71,12 +79,6 @@ void __init prom_init(void)
+ 		if (i < (argc - 1))
+ 			strcat(arcs_cmdline, " ");
+ 	}
+-
+-	vr41xx_calculate_clock_frequency();
+-
+-	timer_init();
+-
+-	iomem_resource_init();
+ }
+ 
+ unsigned long __init prom_free_prom_memory (void)
+diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c
+--- a/arch/mips/vr41xx/common/vrc4173.c
++++ b/arch/mips/vr41xx/common/vrc4173.c
+@@ -81,8 +81,8 @@ EXPORT_SYMBOL(vrc4173_io_offset);
+ static int vrc4173_initialized;
+ static uint16_t vrc4173_cmuclkmsk;
+ static uint16_t vrc4173_selectreg;
+-static spinlock_t vrc4173_cmu_lock;
+-static spinlock_t vrc4173_giu_lock;
++static DEFINE_SPINLOCK(vrc4173_cmu_lock);
++static DEFINE_SPINLOCK(vrc4173_giu_lock);
+ 
+ static inline void set_cmusrst(uint16_t val)
+ {
+diff --git a/arch/mips/vr41xx/nec-cmbvr4133/setup.c b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
+--- a/arch/mips/vr41xx/nec-cmbvr4133/setup.c
++++ b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
+@@ -56,7 +56,7 @@ static struct mtd_partition cmbvr4133_mt
+ 
+ extern void i8259_init(void);
+ 
+-static int __init nec_cmbvr4133_setup(void)
++static void __init nec_cmbvr4133_setup(void)
+ {
+ #ifdef CONFIG_ROCKHOPPER
+ 	extern void disable_pcnet(void);
+@@ -90,7 +90,4 @@ static int __init nec_cmbvr4133_setup(vo
+ #ifdef CONFIG_ROCKHOPPER
+ 	i8259_init();
+ #endif
+-	return 0;
+ }
+-
+-early_initcall(nec_cmbvr4133_setup);
+diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
+--- a/arch/parisc/Kconfig
++++ b/arch/parisc/Kconfig
+@@ -47,10 +47,10 @@ config PM
+ 
+ config ISA_DMA_API
+ 	bool
+-	default y
+ 
+ config ARCH_MAY_HAVE_PC_FDC
+ 	bool
++	depends on BROKEN
+ 	default y
+ 
+ source "init/Kconfig"
+@@ -154,13 +154,14 @@ config HOTPLUG_CPU
+ 
+ config ARCH_DISCONTIGMEM_ENABLE
+ 	bool "Discontiguous memory support (EXPERIMENTAL)"
+-	depends on EXPERIMENTAL
++	depends on 64BIT && EXPERIMENTAL
+ 	help
+ 	  Say Y to support efficient handling of discontiguous physical memory,
+ 	  for architectures which are either NUMA (Non-Uniform Memory Access)
+ 	  or have huge holes in the physical address space for other reasons.
+ 	  See <file:Documentation/vm/numa> for more.
+ 
++source "kernel/Kconfig.hz"
+ source "mm/Kconfig"
+ 
+ config PREEMPT
+diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
+--- a/arch/parisc/Makefile
++++ b/arch/parisc/Makefile
+@@ -20,7 +20,8 @@ NM		= sh $(srctree)/arch/parisc/nm
+ CHECKFLAGS	+= -D__hppa__=1
+ 
+ ifdef CONFIG_64BIT
+-CROSS_COMPILE	:= hppa64-linux-
++CROSS_COMPILE	:= $(shell if [ -x /usr/bin/hppa64-linux-gnu-gcc ]; then \
++			echo hppa64-linux-gnu-; else echo hppa64-linux-; fi)
+ UTS_MACHINE	:= parisc64
+ CHECKFLAGS	+= -D__LP64__=1 -m64
+ else
+@@ -34,6 +35,14 @@ FINAL_LD=$(CROSS_COMPILE)ld --warn-commo
+ 
+ OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
+ 
++GCC_VERSION     := $(call cc-version)
++ifneq ($(shell if [ -z $(GCC_VERSION) ] ; then echo "bad"; fi ;),)
++$(error Sorry, couldn't find ($(cc-version)).)
++endif
++ifneq ($(shell if [ $(GCC_VERSION) -lt 0303 ] ; then echo "bad"; fi ;),)
++$(error Sorry, your compiler is too old ($(GCC_VERSION)).  GCC v3.3 or above is required.)
++endif
++
+ cflags-y	:= -pipe
+ 
+ # These flags should be implied by an hppa-linux configuration, but they
+@@ -43,7 +52,7 @@ cflags-y	+= -mno-space-regs -mfast-indir
+ # Currently we save and restore fpregs on all kernel entry/interruption paths.
+ # If that gets optimized, we might need to disable the use of fpregs in the
+ # kernel.
+-#cflags-y	+= -mdisable-fpregs
++cflags-y	+= -mdisable-fpregs
+ 
+ # Without this, "ld -r" results in .text sections that are too big
+ # (> 0x40000) for branches to reach stubs.
+diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
+--- a/arch/parisc/configs/712_defconfig
++++ b/arch/parisc/configs/712_defconfig
+@@ -1,12 +1,16 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-pa5
+-# Wed Jan  5 13:20:32 2005
++# Linux kernel version: 2.6.14-rc5-pa1
++# Fri Oct 21 23:04:34 2005
+ #
+ CONFIG_PARISC=y
+ CONFIG_MMU=y
+ CONFIG_STACK_GROWSUP=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+ 
+ #
+ # Code maturity level options
+@@ -15,35 +19,40 @@ CONFIG_EXPERIMENTAL=y
+ # CONFIG_CLEAN_COMPILE is not set
+ CONFIG_BROKEN=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 is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=16
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_EMBEDDED is not set
+ CONFIG_KALLSYMS=y
+ CONFIG_KALLSYMS_ALL=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 is not set
+ CONFIG_SHMEM=y
+ CONFIG_CC_ALIGN_FUNCTIONS=0
+ CONFIG_CC_ALIGN_LABELS=0
+ CONFIG_CC_ALIGN_LOOPS=0
+ CONFIG_CC_ALIGN_JUMPS=0
+ # CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
+ 
+ #
+ # Loadable module support
+@@ -65,9 +74,18 @@ CONFIG_PA7100LC=y
+ # CONFIG_PA7300LC is not set
+ # CONFIG_PA8X00 is not set
+ CONFIG_PA11=y
+-# CONFIG_64BIT is not set
+ # CONFIG_SMP is not set
+-# CONFIG_DISCONTIGMEM is not set
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++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_PREEMPT is not set
+ # CONFIG_HPUX is not set
+ 
+@@ -81,8 +99,6 @@ CONFIG_GSC_LASI=y
+ # CONFIG_GSC_WAX is not set
+ # CONFIG_EISA is not set
+ # CONFIG_PCI is not set
+-CONFIG_CHASSIS_LCD_LED=y
+-# CONFIG_PDC_CHASSIS is not set
+ 
+ #
+ # PCCARD (PCMCIA/CardBus) support
+@@ -90,12 +106,15 @@ CONFIG_CHASSIS_LCD_LED=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
++# PCI Hotplug Support
+ #
+ 
+ #
+-# PCI Hotplug Support
++# PA-RISC specific drivers
+ #
++CONFIG_CHASSIS_LCD_LED=y
++# CONFIG_PDC_CHASSIS is not set
++CONFIG_PDC_STABLE=y
+ 
+ #
+ # Executable file formats
+@@ -104,137 +123,7 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_BINFMT_MISC=m
+ 
+ #
+-# Device Drivers
+-#
+-
+-#
+-# Generic Driver Options
+-#
+-# CONFIG_STANDALONE is not set
+-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+-CONFIG_FW_LOADER=y
+-# CONFIG_DEBUG_DRIVER is not set
+-
+-#
+-# Memory Technology Devices (MTD)
+-#
+-# CONFIG_MTD is not set
+-
+-#
+-# Parallel port support
+-#
+-CONFIG_PARPORT=y
+-CONFIG_PARPORT_PC=m
+-CONFIG_PARPORT_PC_CML1=m
+-# CONFIG_PARPORT_PC_FIFO is not set
+-# CONFIG_PARPORT_PC_SUPERIO is not set
+-CONFIG_PARPORT_GSC=y
+-# CONFIG_PARPORT_OTHER is not set
+-# CONFIG_PARPORT_1284 is not set
+-
+-#
+-# Plug and Play support
+-#
+-
+-#
+-# Block devices
+-#
+-# CONFIG_BLK_DEV_FD is not set
+-# CONFIG_PARIDE is not set
+-CONFIG_BLK_DEV_LOOP=y
+-CONFIG_BLK_DEV_CRYPTOLOOP=y
+-# CONFIG_BLK_DEV_NBD is not set
+-CONFIG_BLK_DEV_RAM=y
+-CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_BLK_DEV_RAM_SIZE=6144
+-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
+-
+-#
+-# ATA/ATAPI/MFM/RLL support
+-#
+-# CONFIG_IDE 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=y
+-# CONFIG_CHR_DEV_OSST is not set
+-CONFIG_BLK_DEV_SR=y
+-# CONFIG_BLK_DEV_SR_VENDOR is not set
+-CONFIG_CHR_DEV_SG=y
+-
+-#
+-# 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
+-
+-#
+-# SCSI low-level drivers
+-#
+-# CONFIG_SCSI_SATA is not set
+-# CONFIG_SCSI_PPA is not set
+-# CONFIG_SCSI_IMM is not set
+-CONFIG_SCSI_LASI700=y
+-CONFIG_53C700_MEM_MAPPED=y
+-CONFIG_53C700_LE_ON_BE=y
+-# CONFIG_SCSI_ZALON is not set
+-CONFIG_SCSI_DEBUG=m
+-
+-#
+-# Multi-device support (RAID and LVM)
+-#
+-CONFIG_MD=y
+-CONFIG_BLK_DEV_MD=m
+-CONFIG_MD_LINEAR=m
+-CONFIG_MD_RAID0=m
+-CONFIG_MD_RAID1=m
+-# CONFIG_MD_RAID10 is not set
+-# CONFIG_MD_RAID5 is not set
+-# CONFIG_MD_RAID6 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
+-#
+-
+-#
+-# IEEE 1394 (FireWire) support
+-#
+-# CONFIG_IEEE1394 is not set
+-
+-#
+-# I2O device support
+-#
+-
+-#
+-# Networking support
++# Networking
+ #
+ CONFIG_NET=y
+ 
+@@ -243,12 +132,14 @@ CONFIG_NET=y
+ #
+ CONFIG_PACKET=y
+ CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+ CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
+ CONFIG_NET_KEY=m
+ 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
+@@ -262,8 +153,10 @@ CONFIG_INET_AH=m
+ CONFIG_INET_ESP=m
+ # CONFIG_INET_IPCOMP is not set
+ CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
++CONFIG_INET_DIAG=m
++CONFIG_INET_TCP_DIAG=m
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_BIC=y
+ 
+ #
+ # IP: Virtual Server Configuration
+@@ -272,6 +165,7 @@ CONFIG_IP_TCPDIAG=y
+ # CONFIG_IPV6 is not set
+ CONFIG_NETFILTER=y
+ # CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_NETFILTER_NETLINK is not set
+ 
+ #
+ # IP: Netfilter Configuration
+@@ -279,11 +173,14 @@ CONFIG_NETFILTER=y
+ CONFIG_IP_NF_CONNTRACK=m
+ # CONFIG_IP_NF_CT_ACCT is not set
+ 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_QUEUE=m
+ CONFIG_IP_NF_IPTABLES=m
+ CONFIG_IP_NF_MATCH_LIMIT=m
+@@ -307,21 +204,23 @@ CONFIG_IP_NF_MATCH_OWNER=m
+ # CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+ # CONFIG_IP_NF_MATCH_REALM is not set
+ CONFIG_IP_NF_MATCH_SCTP=m
++# CONFIG_IP_NF_MATCH_DCCP is not set
+ CONFIG_IP_NF_MATCH_COMMENT=m
+ CONFIG_IP_NF_MATCH_CONNMARK=m
+ CONFIG_IP_NF_MATCH_HASHLIMIT=m
++# CONFIG_IP_NF_MATCH_STRING is not set
+ 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_TARGET_NFQUEUE is not set
+ CONFIG_IP_NF_NAT=m
+ CONFIG_IP_NF_NAT_NEEDED=y
+ CONFIG_IP_NF_TARGET_MASQUERADE=m
+ CONFIG_IP_NF_TARGET_REDIRECT=m
+ CONFIG_IP_NF_TARGET_NETMAP=m
+ CONFIG_IP_NF_TARGET_SAME=m
+-# CONFIG_IP_NF_NAT_LOCAL is not set
+ CONFIG_IP_NF_NAT_SNMP_BASIC=m
+ CONFIG_IP_NF_NAT_IRC=m
+ CONFIG_IP_NF_NAT_FTP=m
+@@ -333,6 +232,7 @@ CONFIG_IP_NF_TARGET_ECN=m
+ CONFIG_IP_NF_TARGET_DSCP=m
+ CONFIG_IP_NF_TARGET_MARK=m
+ CONFIG_IP_NF_TARGET_CLASSIFY=m
++# CONFIG_IP_NF_TARGET_TTL is not set
+ CONFIG_IP_NF_TARGET_CONNMARK=m
+ CONFIG_IP_NF_TARGET_CLUSTERIP=m
+ CONFIG_IP_NF_RAW=m
+@@ -340,10 +240,11 @@ CONFIG_IP_NF_TARGET_NOTRACK=m
+ CONFIG_IP_NF_ARPTABLES=m
+ CONFIG_IP_NF_ARPFILTER=m
+ CONFIG_IP_NF_ARP_MANGLE=m
+-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
+ 
+ #
+ # SCTP Configuration (EXPERIMENTAL)
+@@ -362,10 +263,6 @@ CONFIG_LLC2=m
+ # 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
+ 
+@@ -373,17 +270,162 @@ CONFIG_LLC2=m
+ # Network testing
+ #
+ CONFIG_NET_PKTGEN=m
+-# 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_IEEE80211 is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++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 is not set
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=y
++CONFIG_PARPORT_PC=m
++# CONFIG_PARPORT_PC_FIFO is not set
++# CONFIG_PARPORT_PC_SUPERIO is not set
++CONFIG_PARPORT_GSC=y
++# CONFIG_PARPORT_1284 is not set
++
++#
++# Plug and Play support
++#
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_PARIDE is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_CRYPTOLOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=6144
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_ATA_OVER_ETH=m
++
++#
++# 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=y
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=y
++# CONFIG_BLK_DEV_SR_VENDOR 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=m
++# CONFIG_SCSI_SAS_ATTRS is not set
++
++#
++# SCSI low-level drivers
++#
++# CONFIG_SCSI_SATA is not set
++# CONFIG_SCSI_PPA is not set
++# CONFIG_SCSI_IMM is not set
++CONFIG_SCSI_LASI700=y
++CONFIG_53C700_LE_ON_BE=y
++# CONFIG_SCSI_ZALON is not set
++CONFIG_SCSI_DEBUG=m
++
++#
++# Multi-device support (RAID and LVM)
++#
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=m
++CONFIG_MD_LINEAR=m
++CONFIG_MD_RAID0=m
++CONFIG_MD_RAID1=m
++# CONFIG_MD_RAID10 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_RAID6 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
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++
++#
++# Network device support
++#
+ CONFIG_NETDEVICES=y
+ CONFIG_DUMMY=m
+ CONFIG_BONDING=m
+ # CONFIG_EQUALIZER is not set
+ CONFIG_TUN=m
+-# CONFIG_ETHERTAP is not set
++
++#
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -391,6 +433,7 @@ CONFIG_TUN=m
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=m
+ CONFIG_LASI_82596=y
++# CONFIG_NET_POCKET is not set
+ 
+ #
+ # Ethernet (1000 Mbit)
+@@ -414,6 +457,7 @@ CONFIG_NET_RADIO=y
+ #
+ # CONFIG_STRIP is not set
+ # CONFIG_ATMEL is not set
++# CONFIG_HOSTAP is not set
+ 
+ #
+ # Wan interfaces
+@@ -431,6 +475,8 @@ 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
+@@ -460,19 +506,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_PARKBD is not set
+-CONFIG_SERIO_GSCPS2=y
+-CONFIG_HP_SDC=y
+-CONFIG_HIL_MLC=y
+-# CONFIG_SERIO_RAW is not set
+-
+-#
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
+@@ -483,6 +516,7 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
+ # CONFIG_KEYBOARD_LKKBD is not set
+ # CONFIG_KEYBOARD_XTKBD is not set
+ # CONFIG_KEYBOARD_NEWTON is not set
++CONFIG_KEYBOARD_HIL_OLD=y
+ # CONFIG_KEYBOARD_HIL is not set
+ CONFIG_INPUT_MOUSE=y
+ CONFIG_MOUSE_PS2=y
+@@ -494,6 +528,19 @@ CONFIG_MOUSE_HIL=m
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_PARKBD is not set
++CONFIG_SERIO_GSCPS2=y
++CONFIG_HP_SDC=y
++CONFIG_HIL_MLC=y
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -511,7 +558,6 @@ 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_MULTIPORT is not set
+ # CONFIG_SERIAL_8250_RSA is not set
+ 
+ #
+@@ -546,12 +592,14 @@ CONFIG_GEN_RTC_X=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+-# CONFIG_DRM is not set
+ CONFIG_RAW_DRIVER=y
+ CONFIG_MAX_RAW_DEVS=256
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -562,10 +610,20 @@ CONFIG_MAX_RAW_DEVS=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -579,28 +637,36 @@ CONFIG_MAX_RAW_DEVS=256
+ # Graphics support
+ #
+ CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++CONFIG_FB_SOFT_CURSOR=y
++# CONFIG_FB_MACMODES is not set
+ CONFIG_FB_MODE_HELPERS=y
+ CONFIG_FB_TILEBLITTING=y
+ CONFIG_FB_STI=y
++# CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+ 
+ #
+ # Console display driver support
+ #
+-CONFIG_STI_CONSOLE=y
++CONFIG_DUMMY_CONSOLE=y
+ CONFIG_DUMMY_CONSOLE_COLUMNS=128
+ CONFIG_DUMMY_CONSOLE_ROWS=48
+-CONFIG_DUMMY_CONSOLE=y
+ CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_STI_CONSOLE=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
+@@ -610,6 +676,7 @@ CONFIG_LOGO=y
+ # CONFIG_LOGO_LINUX_VGA16 is not set
+ # CONFIG_LOGO_LINUX_CLUT224 is not set
+ CONFIG_LOGO_PARISC_CLUT224=y
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -657,10 +724,6 @@ CONFIG_SND_HARMONY=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+ # USB Gadget Support
+ #
+ # CONFIG_USB_GADGET is not set
+@@ -671,10 +734,20 @@ CONFIG_SND_HARMONY=y
+ # CONFIG_MMC is not set
+ 
+ #
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN 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 is not set
+ CONFIG_JBD=y
+@@ -682,20 +755,24 @@ CONFIG_JBD=y
+ # CONFIG_REISERFS_FS is not set
+ CONFIG_JFS_FS=m
+ # CONFIG_JFS_POSIX_ACL is not set
++# CONFIG_JFS_SECURITY is not set
+ # CONFIG_JFS_DEBUG is not set
+ # CONFIG_JFS_STATISTICS is not set
+ CONFIG_FS_POSIX_ACL=y
+ CONFIG_XFS_FS=m
+-# CONFIG_XFS_RT is not set
++CONFIG_XFS_EXPORT=y
+ # 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_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
+@@ -722,14 +799,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ CONFIG_TMPFS=y
+-CONFIG_TMPFS_XATTR=y
+-# CONFIG_TMPFS_SECURITY is not set
+ # CONFIG_HUGETLBFS is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -754,16 +828,19 @@ CONFIG_UFS_FS=m
+ #
+ 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
+@@ -778,6 +855,7 @@ CONFIG_CIFS=m
+ # 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
+@@ -838,13 +916,19 @@ CONFIG_OPROFILE=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ CONFIG_DEBUG_KERNEL=y
+ CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_DETECT_SOFTLOCKUP=y
+ # 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_INFO is not set
++# CONFIG_DEBUG_IOREMAP is not set
++# CONFIG_DEBUG_FS is not set
+ 
+ #
+ # Security options
+@@ -865,6 +949,7 @@ CONFIG_CRYPTO_SHA1=m
+ CONFIG_CRYPTO_SHA256=m
+ CONFIG_CRYPTO_SHA512=m
+ CONFIG_CRYPTO_WP512=m
++CONFIG_CRYPTO_TGR192=m
+ CONFIG_CRYPTO_DES=y
+ CONFIG_CRYPTO_BLOWFISH=m
+ CONFIG_CRYPTO_TWOFISH=m
+@@ -882,9 +967,14 @@ CONFIG_CRYPTO_CRC32C=m
+ CONFIG_CRYPTO_TEST=m
+ 
+ #
++# Hardware crypto devices
++#
++
++#
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++# CONFIG_CRC16 is not set
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=m
+diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
+--- a/arch/parisc/configs/a500_defconfig
++++ b/arch/parisc/configs/a500_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.11-rc4-pa1
+-# Wed Feb 16 11:32:49 2005
++# Linux kernel version: 2.6.14-rc5-pa1
++# Fri Oct 21 23:04:54 2005
+ #
+ CONFIG_PARISC=y
+ CONFIG_MMU=y
+@@ -10,6 +10,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+ 
+ #
+ # Code maturity level options
+@@ -19,26 +20,32 @@ CONFIG_EXPERIMENTAL=y
+ CONFIG_BROKEN=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_LOG_BUF_SHIFT=16
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++# CONFIG_CPUSETS is not set
++CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_EMBEDDED=y
+ CONFIG_KALLSYMS=y
+ CONFIG_KALLSYMS_ALL=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 is not set
+@@ -48,6 +55,7 @@ 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
+@@ -74,7 +82,19 @@ CONFIG_PREFETCH=y
+ CONFIG_64BIT=y
+ CONFIG_SMP=y
+ CONFIG_HOTPLUG_CPU=y
++CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_SELECT_MEMORY_MODEL=y
++# CONFIG_FLATMEM_MANUAL is not set
++CONFIG_DISCONTIGMEM_MANUAL=y
++# CONFIG_SPARSEMEM_MANUAL is not set
+ CONFIG_DISCONTIGMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_NEED_MULTIPLE_NODES=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ # CONFIG_PREEMPT is not set
+ CONFIG_COMPAT=y
+ CONFIG_NR_CPUS=8
+@@ -85,7 +105,7 @@ CONFIG_NR_CPUS=8
+ # CONFIG_GSC is not set
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
++# CONFIG_PCI_DEBUG is not set
+ CONFIG_PCI_LBA=y
+ CONFIG_IOSAPIC=y
+ CONFIG_IOMMU_SBA=y
+@@ -96,6 +116,8 @@ CONFIG_IOMMU_SBA=y
+ CONFIG_PCCARD=m
+ # CONFIG_PCMCIA_DEBUG is not set
+ CONFIG_PCMCIA=m
++# CONFIG_PCMCIA_LOAD_CIS is not set
++CONFIG_PCMCIA_IOCTL=y
+ CONFIG_CARDBUS=y
+ 
+ #
+@@ -104,7 +126,6 @@ CONFIG_CARDBUS=y
+ CONFIG_YENTA=m
+ CONFIG_PD6729=m
+ CONFIG_I82092=m
+-CONFIG_TCIC=m
+ CONFIG_PCCARD_NONSTATIC=m
+ 
+ #
+@@ -127,6 +148,203 @@ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
++CONFIG_NET_KEY=m
++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 is not set
++CONFIG_INET_AH=m
++CONFIG_INET_ESP=m
++# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_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_INET6_AH=m
++CONFIG_INET6_ESP=m
++CONFIG_INET6_IPCOMP=m
++CONFIG_INET6_TUNNEL=m
++CONFIG_IPV6_TUNNEL=m
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_NETFILTER_NETLINK is not set
++
++#
++# IP: Netfilter Configuration
++#
++CONFIG_IP_NF_CONNTRACK=m
++# CONFIG_IP_NF_CT_ACCT is not set
++CONFIG_IP_NF_CONNTRACK_MARK=y
++# CONFIG_IP_NF_CONNTRACK_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_QUEUE=m
++CONFIG_IP_NF_IPTABLES=m
++CONFIG_IP_NF_MATCH_LIMIT=m
++CONFIG_IP_NF_MATCH_IPRANGE=m
++CONFIG_IP_NF_MATCH_MAC=m
++CONFIG_IP_NF_MATCH_PKTTYPE=m
++CONFIG_IP_NF_MATCH_MARK=m
++CONFIG_IP_NF_MATCH_MULTIPORT=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_ESP=m
++CONFIG_IP_NF_MATCH_LENGTH=m
++CONFIG_IP_NF_MATCH_TTL=m
++CONFIG_IP_NF_MATCH_TCPMSS=m
++CONFIG_IP_NF_MATCH_HELPER=m
++CONFIG_IP_NF_MATCH_STATE=m
++CONFIG_IP_NF_MATCH_CONNTRACK=m
++CONFIG_IP_NF_MATCH_OWNER=m
++# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
++# CONFIG_IP_NF_MATCH_REALM is not set
++CONFIG_IP_NF_MATCH_SCTP=m
++# CONFIG_IP_NF_MATCH_DCCP is not set
++CONFIG_IP_NF_MATCH_COMMENT=m
++CONFIG_IP_NF_MATCH_CONNMARK=m
++CONFIG_IP_NF_MATCH_HASHLIMIT=m
++# CONFIG_IP_NF_MATCH_STRING is not set
++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_TARGET_NFQUEUE is not set
++CONFIG_IP_NF_NAT=m
++CONFIG_IP_NF_NAT_NEEDED=y
++CONFIG_IP_NF_TARGET_MASQUERADE=m
++CONFIG_IP_NF_TARGET_REDIRECT=m
++CONFIG_IP_NF_TARGET_NETMAP=m
++CONFIG_IP_NF_TARGET_SAME=m
++CONFIG_IP_NF_NAT_SNMP_BASIC=m
++CONFIG_IP_NF_NAT_IRC=m
++CONFIG_IP_NF_NAT_FTP=m
++CONFIG_IP_NF_NAT_TFTP=m
++CONFIG_IP_NF_NAT_AMANDA=m
++CONFIG_IP_NF_MANGLE=m
++CONFIG_IP_NF_TARGET_TOS=m
++CONFIG_IP_NF_TARGET_ECN=m
++CONFIG_IP_NF_TARGET_DSCP=m
++CONFIG_IP_NF_TARGET_MARK=m
++CONFIG_IP_NF_TARGET_CLASSIFY=m
++# CONFIG_IP_NF_TARGET_TTL is not set
++CONFIG_IP_NF_TARGET_CONNMARK=m
++CONFIG_IP_NF_TARGET_CLUSTERIP=m
++CONFIG_IP_NF_RAW=m
++CONFIG_IP_NF_TARGET_NOTRACK=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 is not set
++CONFIG_IP6_NF_IPTABLES=m
++# CONFIG_IP6_NF_MATCH_LIMIT is not set
++CONFIG_IP6_NF_MATCH_MAC=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_MULTIPORT is not set
++# CONFIG_IP6_NF_MATCH_OWNER is not set
++# CONFIG_IP6_NF_MATCH_MARK is not set
++CONFIG_IP6_NF_MATCH_IPV6HEADER=m
++# CONFIG_IP6_NF_MATCH_AHESP is not set
++# CONFIG_IP6_NF_MATCH_LENGTH is not set
++# CONFIG_IP6_NF_MATCH_EUI64 is not set
++CONFIG_IP6_NF_FILTER=m
++CONFIG_IP6_NF_TARGET_LOG=m
++CONFIG_IP6_NF_TARGET_REJECT=m
++# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
++CONFIG_IP6_NF_MANGLE=m
++# CONFIG_IP6_NF_TARGET_MARK is not set
++# CONFIG_IP6_NF_TARGET_HL is not set
++CONFIG_IP6_NF_RAW=m
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++CONFIG_IP_DCCP=m
++CONFIG_INET_DCCP_DIAG=m
++
++#
++# DCCP CCIDs Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP_CCID3 is not set
++
++#
++# DCCP Kernel Hacking
++#
++# CONFIG_IP_DCCP_DEBUG 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_LLC=m
++CONFIG_LLC2=m
++# 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ #
+ 
+@@ -139,6 +357,11 @@ 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 is not set
+@@ -169,7 +392,6 @@ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=6144
+ CONFIG_BLK_DEV_INITRD=y
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+@@ -189,6 +411,7 @@ CONFIG_IOSCHED_CFQ=y
+ #
+ # SCSI device support
+ #
++CONFIG_RAID_ATTRS=m
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -201,6 +424,7 @@ CONFIG_CHR_DEV_ST=y
+ CONFIG_BLK_DEV_SR=y
+ # CONFIG_BLK_DEV_SR_VENDOR 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
+@@ -215,6 +439,7 @@ CONFIG_SCSI_MULTI_LUN=y
+ CONFIG_SCSI_SPI_ATTRS=y
+ CONFIG_SCSI_FC_ATTRS=m
+ CONFIG_SCSI_ISCSI_ATTRS=m
++CONFIG_SCSI_SAS_ATTRS=m
+ 
+ #
+ # SCSI low-level drivers
+@@ -229,14 +454,12 @@ CONFIG_SCSI_ISCSI_ATTRS=m
+ # CONFIG_SCSI_ADVANSYS 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_BUSLOGIC is not set
+ # CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+ # CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_IPS is not set
+ # CONFIG_SCSI_INITIO is not set
+ # CONFIG_SCSI_INIA100 is not set
+@@ -246,8 +469,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+ # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+ # CONFIG_SCSI_IPR is not set
+-# CONFIG_SCSI_PCI2000 is not set
+-# CONFIG_SCSI_PCI2220I is not set
+ # CONFIG_SCSI_QLOGIC_ISP is not set
+ CONFIG_SCSI_QLOGIC_FC=m
+ # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+@@ -258,7 +479,9 @@ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA22XX is not set
+ CONFIG_SCSI_QLA2300=m
+ CONFIG_SCSI_QLA2322=m
+-CONFIG_SCSI_QLA6312=m
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX is not set
++# CONFIG_SCSI_LPFC is not set
+ # CONFIG_SCSI_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+ CONFIG_SCSI_DEBUG=m
+@@ -288,8 +511,11 @@ CONFIG_MD_RAID1=y
+ #
+ # Fusion MPT device support
+ #
+-CONFIG_FUSION=m
+-CONFIG_FUSION_MAX_SGE=40
++CONFIG_FUSION=y
++CONFIG_FUSION_SPI=m
++CONFIG_FUSION_FC=m
++# CONFIG_FUSION_SAS is not set
++CONFIG_FUSION_MAX_SGE=128
+ CONFIG_FUSION_CTL=m
+ 
+ #
+@@ -303,153 +529,13 @@ CONFIG_FUSION_CTL=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
++# Network device support
+ #
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=m
+-CONFIG_INET=y
+-CONFIG_IP_MULTICAST=y
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-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 is not set
+-CONFIG_INET_AH=m
+-CONFIG_INET_ESP=m
+-# CONFIG_INET_IPCOMP is not set
+-CONFIG_INET_TUNNEL=m
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-
+-#
+-# IP: Netfilter Configuration
+-#
+-CONFIG_IP_NF_CONNTRACK=m
+-# CONFIG_IP_NF_CT_ACCT is not set
+-CONFIG_IP_NF_CONNTRACK_MARK=y
+-CONFIG_IP_NF_CT_PROTO_SCTP=m
+-CONFIG_IP_NF_FTP=m
+-CONFIG_IP_NF_IRC=m
+-CONFIG_IP_NF_TFTP=m
+-CONFIG_IP_NF_AMANDA=m
+-CONFIG_IP_NF_QUEUE=m
+-CONFIG_IP_NF_IPTABLES=m
+-CONFIG_IP_NF_MATCH_LIMIT=m
+-CONFIG_IP_NF_MATCH_IPRANGE=m
+-CONFIG_IP_NF_MATCH_MAC=m
+-CONFIG_IP_NF_MATCH_PKTTYPE=m
+-CONFIG_IP_NF_MATCH_MARK=m
+-CONFIG_IP_NF_MATCH_MULTIPORT=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_ESP=m
+-CONFIG_IP_NF_MATCH_LENGTH=m
+-CONFIG_IP_NF_MATCH_TTL=m
+-CONFIG_IP_NF_MATCH_TCPMSS=m
+-CONFIG_IP_NF_MATCH_HELPER=m
+-CONFIG_IP_NF_MATCH_STATE=m
+-CONFIG_IP_NF_MATCH_CONNTRACK=m
+-CONFIG_IP_NF_MATCH_OWNER=m
+-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+-# CONFIG_IP_NF_MATCH_REALM is not set
+-CONFIG_IP_NF_MATCH_SCTP=m
+-CONFIG_IP_NF_MATCH_COMMENT=m
+-CONFIG_IP_NF_MATCH_CONNMARK=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_MANGLE=m
+-CONFIG_IP_NF_TARGET_TOS=m
+-CONFIG_IP_NF_TARGET_ECN=m
+-CONFIG_IP_NF_TARGET_DSCP=m
+-CONFIG_IP_NF_TARGET_MARK=m
+-CONFIG_IP_NF_TARGET_CLASSIFY=m
+-CONFIG_IP_NF_TARGET_CONNMARK=m
+-CONFIG_IP_NF_TARGET_CLUSTERIP=m
+-CONFIG_IP_NF_RAW=m
+-CONFIG_IP_NF_TARGET_NOTRACK=m
+-CONFIG_IP_NF_ARPTABLES=m
+-CONFIG_IP_NF_ARPFILTER=m
+-CONFIG_IP_NF_ARP_MANGLE=m
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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_LLC=m
+-CONFIG_LLC2=m
+-# 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=m
+-# 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=m
+ CONFIG_BONDING=m
+ # CONFIG_EQUALIZER is not set
+ CONFIG_TUN=m
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -457,12 +543,18 @@ CONFIG_TUN=m
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=m
+ # CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
+ CONFIG_NET_VENDOR_3COM=y
+ CONFIG_VORTEX=m
+ CONFIG_TYPHOON=m
+@@ -479,6 +571,7 @@ CONFIG_TULIP_MMIO=y
+ # CONFIG_DE4X5 is not set
+ # CONFIG_WINBOND_840 is not set
+ # CONFIG_DM9102 is not set
++# CONFIG_ULI526X is not set
+ CONFIG_PCMCIA_XIRCOM=m
+ # CONFIG_PCMCIA_XIRTULIP is not set
+ CONFIG_HP100=m
+@@ -489,48 +582,43 @@ CONFIG_PCNET32=m
+ # CONFIG_B44 is not set
+ # CONFIG_FORCEDETH is not set
+ # CONFIG_DGRS is not set
+-CONFIG_EEPRO100=m
++# CONFIG_EEPRO100 is not set
+ CONFIG_E100=m
+-CONFIG_E100_NAPI=y
+ # CONFIG_FEALNX is not set
+-CONFIG_NATSEMI=m
++# CONFIG_NATSEMI is not set
+ # CONFIG_NE2K_PCI is not set
+ # CONFIG_8139CP is not set
+-CONFIG_8139TOO=m
+-# 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_8139TOO is not set
+ # CONFIG_SIS900 is not set
+-CONFIG_EPIC100=m
++# CONFIG_EPIC100 is not set
+ # CONFIG_SUNDANCE is not set
+-CONFIG_VIA_RHINE=m
+-CONFIG_VIA_RHINE_MMIO=y
++# CONFIG_VIA_RHINE is not set
+ 
+ #
+ # Ethernet (1000 Mbit)
+ #
+ CONFIG_ACENIC=m
+ CONFIG_ACENIC_OMIT_TIGON_I=y
+-CONFIG_DL2K=m
++# CONFIG_DL2K is not set
+ CONFIG_E1000=m
+ CONFIG_E1000_NAPI=y
+ # 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_SK98LIN is not set
+ # CONFIG_VIA_VELOCITY is not set
+ CONFIG_TIGON3=m
++# CONFIG_BNX2 is not set
+ 
+ #
+ # Ethernet (10000 Mbit)
+ #
+-CONFIG_IXGB=m
+-CONFIG_IXGB_NAPI=y
+-CONFIG_S2IO=m
+-CONFIG_S2IO_NAPI=y
+-# CONFIG_2BUFF_MODE is not set
++# CONFIG_CHELSIO_T1 is not set
++# CONFIG_IXGB is not set
++# CONFIG_S2IO is not set
+ 
+ #
+ # Token Ring devices
+@@ -560,6 +648,7 @@ CONFIG_PCMCIA_RAYCS=m
+ CONFIG_HERMES=m
+ CONFIG_PLX_HERMES=m
+ CONFIG_TMD_HERMES=m
++# CONFIG_NORTEL_HERMES is not set
+ CONFIG_PCI_HERMES=m
+ # CONFIG_ATMEL is not set
+ 
+@@ -567,6 +656,7 @@ CONFIG_PCI_HERMES=m
+ # Wireless 802.11b Pcmcia/Cardbus cards support
+ #
+ CONFIG_PCMCIA_HERMES=m
++# CONFIG_PCMCIA_SPECTRUM is not set
+ CONFIG_AIRO_CS=m
+ CONFIG_PCMCIA_WL3501=m
+ 
+@@ -574,6 +664,7 @@ CONFIG_PCMCIA_WL3501=m
+ # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+ #
+ # CONFIG_PRISM54 is not set
++# CONFIG_HOSTAP is not set
+ CONFIG_NET_WIRELESS=y
+ 
+ #
+@@ -607,6 +698,8 @@ CONFIG_PPP_BSDCOMP=m
+ # 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
+@@ -633,13 +726,6 @@ CONFIG_INPUT=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-# CONFIG_SERIO is not set
+-
+-#
+ # Input Device Drivers
+ #
+ # CONFIG_INPUT_KEYBOARD is not set
+@@ -649,6 +735,12 @@ CONFIG_SOUND_GAMEPORT=y
+ # 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
+@@ -667,7 +759,6 @@ 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_MULTIPORT is not set
+ # CONFIG_SERIAL_8250_RSA is not set
+ 
+ #
+@@ -677,6 +768,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
+ CONFIG_PDC_CONSOLE=y
+ 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
+ 
+@@ -708,6 +800,11 @@ CONFIG_RAW_DRIVER=y
+ CONFIG_MAX_RAW_DEVS=256
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -718,10 +815,20 @@ CONFIG_MAX_RAW_DEVS=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -742,6 +849,7 @@ CONFIG_MAX_RAW_DEVS=256
+ CONFIG_DUMMY_CONSOLE=y
+ CONFIG_DUMMY_CONSOLE_COLUMNS=160
+ CONFIG_DUMMY_CONSOLE_ROWS=64
++# CONFIG_STI_CONSOLE is not set
+ 
+ #
+ # Sound
+@@ -751,13 +859,9 @@ CONFIG_DUMMY_CONSOLE_ROWS=64
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -772,17 +876,18 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ #
+ # InfiniBand support
+ #
+-CONFIG_INFINIBAND=m
+-CONFIG_INFINIBAND_MTHCA=m
+-# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+-CONFIG_INFINIBAND_IPOIB=m
+-# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
++# CONFIG_INFINIBAND is not set
++
++#
++# SN 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 is not set
+ CONFIG_JBD=y
+@@ -794,22 +899,20 @@ CONFIG_JFS_FS=m
+ # CONFIG_JFS_DEBUG is not set
+ # CONFIG_JFS_STATISTICS is not set
+ CONFIG_FS_POSIX_ACL=y
+-
+-#
+-# XFS support
+-#
+ CONFIG_XFS_FS=m
+ CONFIG_XFS_EXPORT=y
+-# CONFIG_XFS_RT is not set
+ # 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_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
+@@ -836,13 +939,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLBFS is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -867,15 +968,18 @@ CONFIG_UFS_FS=m
+ #
+ CONFIG_NFS_FS=m
+ 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_LOCKD=m
+ CONFIG_LOCKD_V4=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=m
+ CONFIG_SUNRPC_GSS=m
+ CONFIG_RPCSEC_GSS_KRB5=m
+@@ -890,6 +994,7 @@ CONFIG_CIFS=m
+ # 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
+@@ -906,15 +1011,15 @@ 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=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=m
++# CONFIG_NLS_CODEPAGE_863 is not set
+ # CONFIG_NLS_CODEPAGE_864 is not set
+-CONFIG_NLS_CODEPAGE_865=m
++# 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
+@@ -926,10 +1031,10 @@ CONFIG_NLS_CODEPAGE_865=m
+ # 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=m
+-CONFIG_NLS_ISO8859_3=m
+-CONFIG_NLS_ISO8859_4=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
+@@ -950,11 +1055,15 @@ CONFIG_OPROFILE=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ CONFIG_DEBUG_KERNEL=y
+ CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_DETECT_SOFTLOCKUP=y
+ # 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_INFO is not set
+ # CONFIG_DEBUG_IOREMAP is not set
+@@ -974,25 +1083,26 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+ CONFIG_CRYPTO_NULL=m
+-CONFIG_CRYPTO_MD4=m
+-CONFIG_CRYPTO_MD5=m
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
+ CONFIG_CRYPTO_SHA1=m
+-CONFIG_CRYPTO_SHA256=m
+-CONFIG_CRYPTO_SHA512=m
+-CONFIG_CRYPTO_WP512=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=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_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=m
+-CONFIG_CRYPTO_MICHAEL_MIC=m
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
+ CONFIG_CRYPTO_CRC32C=m
+ CONFIG_CRYPTO_TEST=m
+ 
+@@ -1004,6 +1114,7 @@ CONFIG_CRYPTO_TEST=m
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++# CONFIG_CRC16 is not set
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=m
+diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
+--- a/arch/parisc/configs/b180_defconfig
++++ b/arch/parisc/configs/b180_defconfig
+@@ -1,12 +1,15 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-pa5
+-# Wed Jan  5 13:35:54 2005
++# Linux kernel version: 2.6.14-rc5-pa1
++# Fri Oct 21 23:06:10 2005
+ #
+ CONFIG_PARISC=y
+ CONFIG_MMU=y
+ CONFIG_STACK_GROWSUP=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
+ 
+ #
+ # Code maturity level options
+@@ -14,33 +17,39 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ # 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_LOCALVERSION_AUTO is not set
+ CONFIG_SWAP=y
+ CONFIG_SYSVIPC=y
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=16
+ # CONFIG_HOTPLUG is not set
+ CONFIG_KOBJECT_UEVENT=y
+-# CONFIG_IKCONFIG is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
+ # 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 is not set
+ CONFIG_SHMEM=y
+ CONFIG_CC_ALIGN_FUNCTIONS=0
+ CONFIG_CC_ALIGN_LABELS=0
+ CONFIG_CC_ALIGN_LOOPS=0
+ CONFIG_CC_ALIGN_JUMPS=0
+ # CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
+ 
+ #
+ # Loadable module support
+@@ -60,8 +69,14 @@ CONFIG_PA7100LC=y
+ # CONFIG_PA7300LC is not set
+ # CONFIG_PA8X00 is not set
+ CONFIG_PA11=y
+-# CONFIG_64BIT is not set
+ # CONFIG_SMP is not set
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ # CONFIG_PREEMPT is not set
+ # CONFIG_HPUX is not set
+ 
+@@ -78,11 +93,25 @@ CONFIG_EISA_NAMES=y
+ CONFIG_ISA=y
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
++# CONFIG_PCI_DEBUG is not set
+ CONFIG_GSC_DINO=y
+ # CONFIG_PCI_LBA is not set
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# CONFIG_PCCARD is not set
++
++#
++# PCI Hotplug Support
++#
++
++#
++# PA-RISC specific drivers
++#
+ CONFIG_CHASSIS_LCD_LED=y
+ # CONFIG_PDC_CHASSIS is not set
++CONFIG_PDC_STABLE=y
+ 
+ #
+ # Executable file formats
+@@ -91,6 +120,64 @@ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++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 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_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_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_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_IPV6_TUNNEL 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ #
+ 
+@@ -99,9 +186,15 @@ CONFIG_BINFMT_ELF=y
+ #
+ CONFIG_STANDALONE=y
+ # CONFIG_PREVENT_FIRMWARE_BUILD is not set
++# CONFIG_FW_LOADER is not set
+ # CONFIG_DEBUG_DRIVER is not set
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -111,10 +204,8 @@ CONFIG_STANDALONE=y
+ #
+ CONFIG_PARPORT=y
+ CONFIG_PARPORT_PC=y
+-CONFIG_PARPORT_PC_CML1=y
+ # CONFIG_PARPORT_SERIAL is not set
+ CONFIG_PARPORT_GSC=y
+-# CONFIG_PARPORT_OTHER is not set
+ # CONFIG_PARPORT_1284 is not set
+ 
+ #
+@@ -125,19 +216,17 @@ CONFIG_PARPORT_GSC=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD is not set
+-# CONFIG_BLK_DEV_XD is not set
+ # CONFIG_PARIDE is not set
+ # CONFIG_BLK_CPQ_DA is not set
+ # CONFIG_BLK_CPQ_CISS_DA is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
+ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_BLK_DEV_CRYPTOLOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+ # CONFIG_CDROM_PKTCDVD_WCACHE is not set
+@@ -149,6 +238,7 @@ CONFIG_IOSCHED_NOOP=y
+ CONFIG_IOSCHED_AS=y
+ CONFIG_IOSCHED_DEADLINE=y
+ CONFIG_IOSCHED_CFQ=y
++CONFIG_ATA_OVER_ETH=y
+ 
+ #
+ # ATA/ATAPI/MFM/RLL support
+@@ -158,6 +248,7 @@ CONFIG_IOSCHED_CFQ=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -170,6 +261,7 @@ CONFIG_CHR_DEV_ST=y
+ CONFIG_BLK_DEV_SR=y
+ # CONFIG_BLK_DEV_SR_VENDOR 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
+@@ -183,16 +275,16 @@ CONFIG_CHR_DEV_SG=y
+ #
+ 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_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_AHA1740 is not set
+ # CONFIG_SCSI_AACRAID is not set
+ # CONFIG_SCSI_AIC7XXX is not set
+@@ -202,14 +294,11 @@ CONFIG_SCSI_SPI_ATTRS=y
+ # 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_BUSLOGIC is not set
+ # CONFIG_SCSI_DMX3191D is not set
+ # CONFIG_SCSI_DTC3280 is not set
+-# CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_GENERIC_NCR5380 is not set
+ # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+ # CONFIG_SCSI_IPS is not set
+@@ -219,7 +308,6 @@ CONFIG_SCSI_SPI_ATTRS=y
+ # CONFIG_SCSI_IMM is not set
+ # CONFIG_SCSI_NCR53C406A is not set
+ CONFIG_SCSI_LASI700=y
+-CONFIG_53C700_MEM_MAPPED=y
+ CONFIG_53C700_LE_ON_BE=y
+ CONFIG_SCSI_SYM53C8XX_2=y
+ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+@@ -231,7 +319,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+ # CONFIG_SCSI_PAS16 is not set
+ # CONFIG_SCSI_PSI240I is not set
+ # CONFIG_SCSI_QLOGIC_FAS is not set
+-# CONFIG_SCSI_QLOGIC_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+ CONFIG_SCSI_QLA2XXX=y
+@@ -240,12 +327,12 @@ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA2300 is not set
+ # CONFIG_SCSI_QLA2322 is not set
+ # CONFIG_SCSI_QLA6312 is not set
+-# CONFIG_SCSI_QLA6322 is not set
++# CONFIG_SCSI_QLA24XX is not set
++# CONFIG_SCSI_LPFC is not set
+ # CONFIG_SCSI_SIM710 is not set
+ # CONFIG_SCSI_SYM53C416 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
+ 
+@@ -263,6 +350,7 @@ CONFIG_MD_LINEAR=y
+ CONFIG_MD_RAID0=y
+ CONFIG_MD_RAID1=y
+ CONFIG_MD_RAID5=y
++CONFIG_MD_RAID6=y
+ # CONFIG_MD_MULTIPATH is not set
+ # CONFIG_MD_FAULTY is not set
+ # CONFIG_BLK_DEV_DM is not set
+@@ -271,6 +359,9 @@ CONFIG_MD_RAID5=y
+ # 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
+@@ -283,58 +374,8 @@ CONFIG_MD_RAID5=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-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=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_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_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
++# Network device support
+ #
+-# 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
+@@ -347,6 +388,11 @@ CONFIG_NETDEVICES=y
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+@@ -354,8 +400,8 @@ CONFIG_NET_ETHERNET=y
+ # CONFIG_LASI_82596 is not set
+ # 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
+ 
+@@ -369,6 +415,7 @@ CONFIG_TULIP=y
+ # CONFIG_DE4X5 is not set
+ # CONFIG_WINBOND_840 is not set
+ # CONFIG_DM9102 is not set
++# CONFIG_ULI526X is not set
+ # CONFIG_DEPCA is not set
+ # CONFIG_HP100 is not set
+ # CONFIG_NET_ISA is not set
+@@ -384,12 +431,15 @@ CONFIG_TULIP=y
+ # CONFIG_NS83820 is not set
+ # CONFIG_HAMACHI is not set
+ # CONFIG_R8169 is not set
++# CONFIG_SIS190 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
+ 
+@@ -413,12 +463,12 @@ CONFIG_NET_RADIO=y
+ #
+ # Wireless 802.11b ISA/PCI cards support
+ #
+-# CONFIG_AIRO is not set
+ # CONFIG_HERMES is not set
+ 
+ #
+ # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+ #
++# CONFIG_HOSTAP is not set
+ CONFIG_NET_WIRELESS=y
+ 
+ #
+@@ -435,6 +485,8 @@ CONFIG_PPP=y
+ # CONFIG_PPP_BSDCOMP is not set
+ # CONFIG_SLIP is not set
+ # CONFIG_NET_FC is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
+ 
+ #
+ # ISDN subsystem
+@@ -464,23 +516,12 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_SERPORT is not set
+-# CONFIG_SERIO_PARKBD is not set
+-CONFIG_SERIO_GSCPS2=y
+-# CONFIG_HP_SDC is not set
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_RAW is not set
+-
+-#
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
+-# CONFIG_KEYBOARD_ATKBD is not set
++CONFIG_KEYBOARD_ATKBD=y
++CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
++# CONFIG_KEYBOARD_ATKBD_RDI_KEYCODES is not set
+ # CONFIG_KEYBOARD_SUNKBD is not set
+ # CONFIG_KEYBOARD_LKKBD is not set
+ # CONFIG_KEYBOARD_XTKBD is not set
+@@ -488,7 +529,7 @@ CONFIG_INPUT_KEYBOARD=y
+ # CONFIG_KEYBOARD_HIL_OLD is not set
+ # CONFIG_KEYBOARD_HIL is not set
+ CONFIG_INPUT_MOUSE=y
+-# CONFIG_MOUSE_PS2 is not set
++CONFIG_MOUSE_PS2=y
+ # CONFIG_MOUSE_SERIAL is not set
+ # CONFIG_MOUSE_INPORT is not set
+ # CONFIG_MOUSE_LOGIBM is not set
+@@ -502,6 +543,19 @@ CONFIG_INPUT_MISC=y
+ # CONFIG_HP_SDC_RTC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_PARKBD is not set
++CONFIG_SERIO_GSCPS2=y
++# CONFIG_HP_SDC is not set
++# 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
+@@ -519,8 +573,11 @@ 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_MULTIPORT is not set
+ # CONFIG_SERIAL_8250_RSA is not set
++# CONFIG_SERIAL_8250_FOURPORT is not set
++# CONFIG_SERIAL_8250_ACCENT is not set
++# CONFIG_SERIAL_8250_BOCA is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
+ 
+ #
+ # Non-8250 serial port support
+@@ -529,6 +586,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
+ # CONFIG_PDC_CONSOLE is not set
+ 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
+@@ -555,11 +613,14 @@ CONFIG_GEN_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -570,10 +631,20 @@ CONFIG_GEN_RTC=y
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -587,6 +658,11 @@ CONFIG_GEN_RTC=y
+ # Graphics support
+ #
+ CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++CONFIG_FB_SOFT_CURSOR=y
++# CONFIG_FB_MACMODES is not set
+ # CONFIG_FB_MODE_HELPERS is not set
+ # CONFIG_FB_TILEBLITTING is not set
+ # CONFIG_FB_CIRRUS is not set
+@@ -595,6 +671,7 @@ CONFIG_FB=y
+ # CONFIG_FB_ASILIANT is not set
+ # CONFIG_FB_IMSTT is not set
+ CONFIG_FB_STI=y
++# CONFIG_FB_NVIDIA is not set
+ # CONFIG_FB_RIVA is not set
+ # CONFIG_FB_MATROX is not set
+ # CONFIG_FB_RADEON_OLD is not set
+@@ -606,18 +683,19 @@ CONFIG_FB_STI=y
+ # CONFIG_FB_KYRO is not set
+ # CONFIG_FB_3DFX is not set
+ # CONFIG_FB_VOODOO1 is not set
++# CONFIG_FB_CYBLA is not set
+ # CONFIG_FB_TRIDENT is not set
++# CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+ 
+ #
+ # Console display driver support
+ #
+-# CONFIG_MDA_CONSOLE is not set
+-CONFIG_STI_CONSOLE=y
++CONFIG_DUMMY_CONSOLE=y
+ CONFIG_DUMMY_CONSOLE_COLUMNS=160
+ CONFIG_DUMMY_CONSOLE_ROWS=64
+-CONFIG_DUMMY_CONSOLE=y
+ CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_STI_CONSOLE=y
+ # CONFIG_FONTS is not set
+ CONFIG_FONT_8x8=y
+ CONFIG_FONT_8x16=y
+@@ -630,6 +708,7 @@ CONFIG_LOGO_LINUX_MONO=y
+ CONFIG_LOGO_LINUX_VGA16=y
+ CONFIG_LOGO_LINUX_CLUT224=y
+ CONFIG_LOGO_PARISC_CLUT224=y
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -639,13 +718,9 @@ CONFIG_LOGO_PARISC_CLUT224=y
+ #
+ # USB support
+ #
+-# CONFIG_USB is not set
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
++# CONFIG_USB is not set
+ 
+ #
+ # USB Gadget Support
+@@ -658,23 +733,36 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_MMC is not set
+ 
+ #
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN 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 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_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
+@@ -697,11 +785,10 @@ CONFIG_JOLIET=y
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -719,15 +806,19 @@ CONFIG_RAMFS=y
+ #
+ CONFIG_NFS_FS=y
+ CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
+ CONFIG_NFSD=y
+ CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL 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_SMB_FS is not set
++CONFIG_SMB_FS=y
++# CONFIG_SMB_NLS_DEFAULT is not set
+ # CONFIG_CIFS is not set
+ # CONFIG_NCP_FS is not set
+ # CONFIG_CODA_FS is not set
+@@ -785,13 +876,19 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ CONFIG_DEBUG_KERNEL=y
+ CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_DETECT_SOFTLOCKUP=y
+ # 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_INFO is not set
++# CONFIG_DEBUG_IOREMAP is not set
++# CONFIG_DEBUG_FS is not set
+ 
+ #
+ # Security options
+@@ -815,6 +912,7 @@ CONFIG_CRYPTO=y
+ # 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
+@@ -832,8 +930,13 @@ CONFIG_CRYPTO=y
+ # 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
+diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
+--- a/arch/parisc/configs/c3000_defconfig
++++ b/arch/parisc/configs/c3000_defconfig
+@@ -1,12 +1,16 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-pa5
+-# Wed Jan  5 13:26:49 2005
++# Linux kernel version: 2.6.14-rc5-pa1
++# Fri Oct 21 23:06:31 2005
+ #
+ CONFIG_PARISC=y
+ CONFIG_MMU=y
+ CONFIG_STACK_GROWSUP=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+ 
+ #
+ # Code maturity level options
+@@ -15,26 +19,31 @@ CONFIG_EXPERIMENTAL=y
+ # CONFIG_CLEAN_COMPILE is not set
+ CONFIG_BROKEN=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 is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+ # CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=16
+ CONFIG_HOTPLUG=y
+ CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_EMBEDDED=y
+ CONFIG_KALLSYMS=y
+ CONFIG_KALLSYMS_ALL=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 is not set
+@@ -44,6 +53,7 @@ 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
+@@ -66,10 +76,19 @@ CONFIG_KMOD=y
+ CONFIG_PA8X00=y
+ CONFIG_PA20=y
+ CONFIG_PREFETCH=y
+-# CONFIG_PARISC64 is not set
+ # CONFIG_64BIT is not set
+ # CONFIG_SMP is not set
+-# CONFIG_DISCONTIGMEM is not set
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++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_PREEMPT is not set
+ # CONFIG_HPUX is not set
+ 
+@@ -79,13 +98,10 @@ CONFIG_PREFETCH=y
+ # CONFIG_GSC is not set
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
++# CONFIG_PCI_DEBUG is not set
+ CONFIG_PCI_LBA=y
+ CONFIG_IOSAPIC=y
+ CONFIG_IOMMU_SBA=y
+-CONFIG_SUPERIO=y
+-CONFIG_CHASSIS_LCD_LED=y
+-# CONFIG_PDC_CHASSIS is not set
+ 
+ #
+ # PCCARD (PCMCIA/CardBus) support
+@@ -93,13 +109,17 @@ CONFIG_CHASSIS_LCD_LED=y
+ # CONFIG_PCCARD is not set
+ 
+ #
+-# PC-card bridges
++# PCI Hotplug Support
+ #
++# CONFIG_HOTPLUG_PCI is not set
+ 
+ #
+-# PCI Hotplug Support
++# PA-RISC specific drivers
+ #
+-# CONFIG_HOTPLUG_PCI is not set
++CONFIG_SUPERIO=y
++CONFIG_CHASSIS_LCD_LED=y
++# CONFIG_PDC_CHASSIS is not set
++CONFIG_PDC_STABLE=y
+ 
+ #
+ # Executable file formats
+@@ -108,6 +128,186 @@ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
++CONFIG_NET_KEY=m
++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 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 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_INET_DIAG is not set
++# 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_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++CONFIG_INET6_IPCOMP=m
++CONFIG_INET6_TUNNEL=m
++CONFIG_IPV6_TUNNEL=m
++CONFIG_NETFILTER=y
++CONFIG_NETFILTER_DEBUG=y
++# CONFIG_NETFILTER_NETLINK 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_QUEUE=m
++CONFIG_IP_NF_IPTABLES=m
++CONFIG_IP_NF_MATCH_LIMIT=m
++CONFIG_IP_NF_MATCH_IPRANGE=m
++CONFIG_IP_NF_MATCH_MAC=m
++CONFIG_IP_NF_MATCH_PKTTYPE=m
++CONFIG_IP_NF_MATCH_MARK=m
++CONFIG_IP_NF_MATCH_MULTIPORT=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_ESP=m
++CONFIG_IP_NF_MATCH_LENGTH=m
++CONFIG_IP_NF_MATCH_TTL=m
++CONFIG_IP_NF_MATCH_TCPMSS=m
++CONFIG_IP_NF_MATCH_HELPER=m
++CONFIG_IP_NF_MATCH_STATE=m
++CONFIG_IP_NF_MATCH_CONNTRACK=m
++CONFIG_IP_NF_MATCH_OWNER=m
++# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
++# CONFIG_IP_NF_MATCH_REALM is not set
++# CONFIG_IP_NF_MATCH_SCTP is not set
++# CONFIG_IP_NF_MATCH_DCCP is not set
++# CONFIG_IP_NF_MATCH_COMMENT is not set
++# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
++# CONFIG_IP_NF_MATCH_STRING is not set
++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_TARGET_NFQUEUE is not set
++CONFIG_IP_NF_NAT=m
++CONFIG_IP_NF_NAT_NEEDED=y
++CONFIG_IP_NF_TARGET_MASQUERADE=m
++CONFIG_IP_NF_TARGET_REDIRECT=m
++CONFIG_IP_NF_TARGET_NETMAP=m
++CONFIG_IP_NF_TARGET_SAME=m
++CONFIG_IP_NF_NAT_SNMP_BASIC=m
++CONFIG_IP_NF_NAT_IRC=m
++CONFIG_IP_NF_NAT_FTP=m
++CONFIG_IP_NF_NAT_TFTP=m
++CONFIG_IP_NF_NAT_AMANDA=m
++CONFIG_IP_NF_MANGLE=m
++CONFIG_IP_NF_TARGET_TOS=m
++CONFIG_IP_NF_TARGET_ECN=m
++CONFIG_IP_NF_TARGET_DSCP=m
++CONFIG_IP_NF_TARGET_MARK=m
++CONFIG_IP_NF_TARGET_CLASSIFY=m
++# CONFIG_IP_NF_TARGET_TTL is not set
++# CONFIG_IP_NF_RAW is not set
++CONFIG_IP_NF_ARPTABLES=m
++CONFIG_IP_NF_ARPFILTER=m
++CONFIG_IP_NF_ARP_MANGLE=m
++
++#
++# IPv6: Netfilter Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP6_NF_QUEUE is not set
++CONFIG_IP6_NF_IPTABLES=m
++# CONFIG_IP6_NF_MATCH_LIMIT is not set
++CONFIG_IP6_NF_MATCH_MAC=m
++CONFIG_IP6_NF_MATCH_RT=m
++# CONFIG_IP6_NF_MATCH_OPTS is not set
++# CONFIG_IP6_NF_MATCH_FRAG is not set
++# CONFIG_IP6_NF_MATCH_HL is not set
++# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
++CONFIG_IP6_NF_MATCH_OWNER=m
++# CONFIG_IP6_NF_MATCH_MARK is not set
++CONFIG_IP6_NF_MATCH_IPV6HEADER=m
++# CONFIG_IP6_NF_MATCH_AHESP is not set
++CONFIG_IP6_NF_MATCH_LENGTH=m
++# CONFIG_IP6_NF_MATCH_EUI64 is not set
++CONFIG_IP6_NF_FILTER=m
++CONFIG_IP6_NF_TARGET_LOG=m
++CONFIG_IP6_NF_TARGET_REJECT=m
++# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
++CONFIG_IP6_NF_MANGLE=m
++# CONFIG_IP6_NF_TARGET_MARK is not set
++# CONFIG_IP6_NF_TARGET_HL is not set
++# CONFIG_IP6_NF_RAW is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ #
+ 
+@@ -120,6 +320,11 @@ 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 is not set
+@@ -141,14 +346,14 @@ CONFIG_FW_LOADER=y
+ # CONFIG_BLK_CPQ_CISS_DA is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ CONFIG_BLK_DEV_UMEM=m
++# CONFIG_BLK_DEV_COW_COMMON is not set
+ CONFIG_BLK_DEV_LOOP=y
+-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_CRYPTOLOOP=m
+ # 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_RAM_COUNT=16
+-CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+@@ -158,6 +363,7 @@ CONFIG_IOSCHED_NOOP=y
+ CONFIG_IOSCHED_AS=y
+ CONFIG_IOSCHED_DEADLINE=y
+ CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
+ 
+ #
+ # ATA/ATAPI/MFM/RLL support
+@@ -201,6 +407,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
+ # 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=y
+ # CONFIG_BLK_DEV_PDC202XX_OLD is not set
+ # CONFIG_BLK_DEV_PDC202XX_NEW is not set
+@@ -218,6 +425,7 @@ CONFIG_BLK_DEV_IDEDMA=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -230,6 +438,7 @@ CONFIG_CHR_DEV_ST=y
+ CONFIG_BLK_DEV_SR=y
+ # CONFIG_BLK_DEV_SR_VENDOR 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
+@@ -242,7 +451,9 @@ CONFIG_SCSI_MULTI_LUN=y
+ # SCSI Transport Attributes
+ #
+ CONFIG_SCSI_SPI_ATTRS=y
+-CONFIG_SCSI_FC_ATTRS=m
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_ATTRS is not set
+ 
+ #
+ # SCSI low-level drivers
+@@ -258,25 +469,26 @@ CONFIG_SCSI_FC_ATTRS=m
+ # CONFIG_SCSI_ADVANSYS 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=m
++# CONFIG_SCSI_SATA_MV is not set
+ # CONFIG_SCSI_SATA_NV is not set
+ CONFIG_SCSI_SATA_PROMISE=m
++# CONFIG_SCSI_SATA_QSTOR is not set
+ # CONFIG_SCSI_SATA_SX4 is not set
+ CONFIG_SCSI_SATA_SIL=m
+ # CONFIG_SCSI_SATA_SIS is not set
+ # CONFIG_SCSI_SATA_ULI is not set
+ CONFIG_SCSI_SATA_VIA=m
+ # CONFIG_SCSI_SATA_VITESSE is not set
+-# CONFIG_SCSI_BUSLOGIC is not set
++CONFIG_SCSI_SATA_INTEL_COMBINED=y
+ # CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+ # CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_IPS is not set
+ # CONFIG_SCSI_INITIO is not set
+ # CONFIG_SCSI_INIA100 is not set
+@@ -286,20 +498,17 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+ # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+ # CONFIG_SCSI_IPR is not set
+-# CONFIG_SCSI_PCI2000 is not set
+-# CONFIG_SCSI_PCI2220I is not set
+ # CONFIG_SCSI_QLOGIC_ISP is not set
+-CONFIG_SCSI_QLOGIC_FC=m
+-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+-CONFIG_SCSI_QLOGIC_1280=m
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
++# CONFIG_SCSI_QLOGIC_FC is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
+ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA21XX is not set
+ # CONFIG_SCSI_QLA22XX is not set
+-CONFIG_SCSI_QLA2300=m
+-CONFIG_SCSI_QLA2322=m
+-CONFIG_SCSI_QLA6312=m
+-CONFIG_SCSI_QLA6322=m
++# CONFIG_SCSI_QLA2300 is not set
++# CONFIG_SCSI_QLA2322 is not set
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX 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
+@@ -316,19 +525,24 @@ CONFIG_MD_RAID1=y
+ # CONFIG_MD_RAID10 is not set
+ # CONFIG_MD_RAID5 is not set
+ # CONFIG_MD_RAID6 is not set
+-CONFIG_MD_MULTIPATH=y
++# CONFIG_MD_MULTIPATH is not set
+ # CONFIG_MD_FAULTY is not set
+-CONFIG_BLK_DEV_DM=y
+-# CONFIG_DM_CRYPT is not set
+-# CONFIG_DM_SNAPSHOT is not set
+-# CONFIG_DM_MIRROR is not set
+-# CONFIG_DM_ZERO is not set
++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 is not set
+ 
+ #
+ # Fusion MPT device support
+ #
+-CONFIG_FUSION=m
+-CONFIG_FUSION_MAX_SGE=40
++CONFIG_FUSION=y
++CONFIG_FUSION_SPI=m
++# CONFIG_FUSION_FC is not set
++# CONFIG_FUSION_SAS is not set
++CONFIG_FUSION_MAX_SGE=128
+ CONFIG_FUSION_CTL=m
+ 
+ #
+@@ -342,151 +556,13 @@ CONFIG_FUSION_CTL=m
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
++# Network device support
+ #
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=m
+-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=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 is not set
+-CONFIG_INET_AH=m
+-CONFIG_INET_ESP=m
+-# CONFIG_INET_IPCOMP is not set
+-# CONFIG_INET_TUNNEL is not set
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-CONFIG_NETFILTER_DEBUG=y
+-
+-#
+-# 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_CT_PROTO_SCTP is not set
+-CONFIG_IP_NF_FTP=m
+-CONFIG_IP_NF_IRC=m
+-CONFIG_IP_NF_TFTP=m
+-CONFIG_IP_NF_AMANDA=m
+-CONFIG_IP_NF_QUEUE=m
+-CONFIG_IP_NF_IPTABLES=m
+-CONFIG_IP_NF_MATCH_LIMIT=m
+-CONFIG_IP_NF_MATCH_IPRANGE=m
+-CONFIG_IP_NF_MATCH_MAC=m
+-CONFIG_IP_NF_MATCH_PKTTYPE=m
+-CONFIG_IP_NF_MATCH_MARK=m
+-CONFIG_IP_NF_MATCH_MULTIPORT=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_ESP=m
+-CONFIG_IP_NF_MATCH_LENGTH=m
+-CONFIG_IP_NF_MATCH_TTL=m
+-CONFIG_IP_NF_MATCH_TCPMSS=m
+-CONFIG_IP_NF_MATCH_HELPER=m
+-CONFIG_IP_NF_MATCH_STATE=m
+-CONFIG_IP_NF_MATCH_CONNTRACK=m
+-CONFIG_IP_NF_MATCH_OWNER=m
+-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+-# CONFIG_IP_NF_MATCH_REALM is not set
+-# CONFIG_IP_NF_MATCH_SCTP is not set
+-# CONFIG_IP_NF_MATCH_COMMENT is not set
+-# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
+-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_MANGLE=m
+-CONFIG_IP_NF_TARGET_TOS=m
+-CONFIG_IP_NF_TARGET_ECN=m
+-CONFIG_IP_NF_TARGET_DSCP=m
+-CONFIG_IP_NF_TARGET_MARK=m
+-CONFIG_IP_NF_TARGET_CLASSIFY=m
+-# CONFIG_IP_NF_RAW is not set
+-CONFIG_IP_NF_ARPTABLES=m
+-CONFIG_IP_NF_ARPFILTER=m
+-CONFIG_IP_NF_ARP_MANGLE=m
+-CONFIG_IP_NF_COMPAT_IPCHAINS=m
+-CONFIG_IP_NF_COMPAT_IPFWADM=m
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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_LLC=m
+-CONFIG_LLC2=m
+-# 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=m
+ CONFIG_BONDING=m
+ # CONFIG_EQUALIZER is not set
+ CONFIG_TUN=m
+-# CONFIG_ETHERTAP is not set
+ 
+ #
+ # ARCnet devices
+@@ -494,12 +570,18 @@ CONFIG_TUN=m
+ # CONFIG_ARCNET is not set
+ 
+ #
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=m
+-CONFIG_HAPPYMEAL=m
++# CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
+ # CONFIG_NET_VENDOR_3COM is not set
+ 
+ #
+@@ -514,28 +596,22 @@ CONFIG_TULIP_MMIO=y
+ # CONFIG_DE4X5 is not set
+ # CONFIG_WINBOND_840 is not set
+ # CONFIG_DM9102 is not set
++# CONFIG_ULI526X is not set
+ # CONFIG_HP100 is not set
+ CONFIG_NET_PCI=y
+-CONFIG_PCNET32=m
++# CONFIG_PCNET32 is not set
+ # CONFIG_AMD8111_ETH is not set
+-CONFIG_ADAPTEC_STARFIRE=m
+-# CONFIG_ADAPTEC_STARFIRE_NAPI is not set
+-CONFIG_B44=m
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_B44 is not set
+ # CONFIG_FORCEDETH is not set
+ # CONFIG_DGRS is not set
+-CONFIG_EEPRO100=m
+-# CONFIG_EEPRO100_PIO is not set
++# CONFIG_EEPRO100 is not set
+ CONFIG_E100=m
+-# CONFIG_E100_NAPI is not set
+ # CONFIG_FEALNX is not set
+-CONFIG_NATSEMI=m
++# CONFIG_NATSEMI is not set
+ # CONFIG_NE2K_PCI is not set
+ # CONFIG_8139CP is not set
+-CONFIG_8139TOO=m
+-# 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_8139TOO is not set
+ # CONFIG_SIS900 is not set
+ # CONFIG_EPIC100 is not set
+ # CONFIG_SUNDANCE is not set
+@@ -554,15 +630,18 @@ CONFIG_E1000=m
+ # 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_SK98LIN is not set
+ # CONFIG_VIA_VELOCITY is not set
+ CONFIG_TIGON3=m
++# CONFIG_BNX2 is not set
+ 
+ #
+ # Ethernet (10000 Mbit)
+ #
+-CONFIG_IXGB=y
+-CONFIG_IXGB_NAPI=y
++# CONFIG_CHELSIO_T1 is not set
++# CONFIG_IXGB is not set
+ # CONFIG_S2IO is not set
+ 
+ #
+@@ -593,6 +672,8 @@ CONFIG_PPPOE=m
+ # 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
+@@ -622,16 +703,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=m
+-CONFIG_SERIO_SERPORT=m
+-# CONFIG_SERIO_PCIPS2 is not set
+-# CONFIG_SERIO_RAW is not set
+-
+-#
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
+@@ -649,6 +720,16 @@ CONFIG_INPUT_MOUSE=y
+ # CONFIG_INPUT_MISC is not set
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=m
++CONFIG_SERIO_SERPORT=m
++# CONFIG_SERIO_PCIPS2 is not set
++CONFIG_SERIO_LIBPS2=m
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -666,7 +747,6 @@ 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_MULTIPORT is not set
+ # CONFIG_SERIAL_8250_RSA is not set
+ 
+ #
+@@ -676,6 +756,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
+ # CONFIG_PDC_CONSOLE is not set
+ 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
+@@ -698,12 +779,16 @@ CONFIG_GEN_RTC_X=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ CONFIG_RAW_DRIVER=y
+ CONFIG_MAX_RAW_DEVS=256
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+@@ -714,10 +799,20 @@ CONFIG_MAX_RAW_DEVS=256
+ # CONFIG_W1 is not set
+ 
+ #
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -731,6 +826,11 @@ CONFIG_MAX_RAW_DEVS=256
+ # Graphics support
+ #
+ CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++CONFIG_FB_SOFT_CURSOR=y
++# CONFIG_FB_MACMODES is not set
+ # CONFIG_FB_MODE_HELPERS is not set
+ # CONFIG_FB_TILEBLITTING is not set
+ # CONFIG_FB_CIRRUS is not set
+@@ -739,6 +839,7 @@ CONFIG_FB=y
+ # CONFIG_FB_ASILIANT is not set
+ # CONFIG_FB_IMSTT is not set
+ CONFIG_FB_STI=y
++# CONFIG_FB_NVIDIA is not set
+ # CONFIG_FB_RIVA is not set
+ # CONFIG_FB_MATROX is not set
+ # CONFIG_FB_RADEON_OLD is not set
+@@ -751,18 +852,20 @@ CONFIG_FB_STI=y
+ # CONFIG_FB_KYRO is not set
+ # CONFIG_FB_3DFX is not set
+ # CONFIG_FB_VOODOO1 is not set
++# CONFIG_FB_CYBLA is not set
+ # CONFIG_FB_TRIDENT is not set
+ # CONFIG_FB_PM3 is not set
++# CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+ 
+ #
+ # Console display driver support
+ #
+-CONFIG_STI_CONSOLE=y
++CONFIG_DUMMY_CONSOLE=y
+ CONFIG_DUMMY_CONSOLE_COLUMNS=160
+ CONFIG_DUMMY_CONSOLE_ROWS=64
+-CONFIG_DUMMY_CONSOLE=y
+ CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_STI_CONSOLE=y
+ # CONFIG_FONTS is not set
+ CONFIG_FONT_8x8=y
+ CONFIG_FONT_8x16=y
+@@ -775,6 +878,7 @@ CONFIG_LOGO=y
+ # CONFIG_LOGO_LINUX_VGA16 is not set
+ # CONFIG_LOGO_LINUX_CLUT224 is not set
+ CONFIG_LOGO_PARISC_CLUT224=y
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -784,7 +888,78 @@ CONFIG_SOUND=y
+ #
+ # Advanced Linux Sound Architecture
+ #
+-# CONFIG_SND is not set
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_SEQUENCER_OSS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++# 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
++CONFIG_SND_AC97_CODEC=y
++CONFIG_SND_AC97_BUS=y
++
++#
++# PCI devices
++#
++# CONFIG_SND_ALI5451 is not set
++# CONFIG_SND_ATIIXP is not set
++# CONFIG_SND_ATIIXP_MODEM is not set
++# CONFIG_SND_AU8810 is not set
++# CONFIG_SND_AU8820 is not set
++# CONFIG_SND_AU8830 is not set
++# CONFIG_SND_AZT3328 is not set
++# CONFIG_SND_BT87X is not set
++# CONFIG_SND_CS46XX is not set
++# CONFIG_SND_CS4281 is not set
++# CONFIG_SND_EMU10K1 is not set
++# CONFIG_SND_EMU10K1X is not set
++# CONFIG_SND_CA0106 is not set
++# CONFIG_SND_KORG1212 is not set
++# CONFIG_SND_MIXART is not set
++# CONFIG_SND_NM256 is not set
++# CONFIG_SND_RME32 is not set
++# CONFIG_SND_RME96 is not set
++# CONFIG_SND_RME9652 is not set
++# CONFIG_SND_HDSP is not set
++# CONFIG_SND_HDSPM is not set
++# CONFIG_SND_TRIDENT is not set
++# CONFIG_SND_YMFPCI is not set
++CONFIG_SND_AD1889=y
++# CONFIG_SND_AD1889_OPL3 is not set
++# CONFIG_SND_CMIPCI is not set
++# CONFIG_SND_ENS1370 is not set
++# CONFIG_SND_ENS1371 is not set
++# CONFIG_SND_ES1938 is not set
++# CONFIG_SND_ES1968 is not set
++# CONFIG_SND_MAESTRO3 is not set
++# CONFIG_SND_FM801 is not set
++# CONFIG_SND_ICE1712 is not set
++# CONFIG_SND_ICE1724 is not set
++# CONFIG_SND_INTEL8X0 is not set
++# CONFIG_SND_INTEL8X0M is not set
++# CONFIG_SND_SONICVIBES is not set
++# CONFIG_SND_VIA82XX is not set
++# CONFIG_SND_VIA82XX_MODEM is not set
++# CONFIG_SND_VX222 is not set
++# CONFIG_SND_HDA_INTEL is not set
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
+ 
+ #
+ # Open Sound System
+@@ -794,6 +969,8 @@ CONFIG_SOUND=y
+ #
+ # USB support
+ #
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
+ CONFIG_USB=y
+ CONFIG_USB_DEBUG=y
+ 
+@@ -804,23 +981,23 @@ CONFIG_USB_DEVICEFS=y
+ # CONFIG_USB_BANDWIDTH is not set
+ # CONFIG_USB_DYNAMIC_MINORS is not set
+ # CONFIG_USB_OTG is not set
+-CONFIG_USB_ARCH_HAS_HCD=y
+-CONFIG_USB_ARCH_HAS_OHCI=y
+ 
+ #
+ # USB Host Controller Drivers
+ #
+ # CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
+ CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+ # CONFIG_USB_UHCI_HCD is not set
+ # CONFIG_USB_SL811_HCD is not set
+ 
+ #
+ # USB Device Class drivers
+ #
+-# CONFIG_USB_AUDIO is not set
++# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+ # CONFIG_USB_BLUETOOTH_TTY is not set
+-# CONFIG_USB_MIDI is not set
+ # CONFIG_USB_ACM is not set
+ CONFIG_USB_PRINTER=m
+ 
+@@ -829,12 +1006,11 @@ CONFIG_USB_PRINTER=m
+ #
+ CONFIG_USB_STORAGE=m
+ # CONFIG_USB_STORAGE_DEBUG is not set
+-# CONFIG_USB_STORAGE_RW_DETECT is not set
+-CONFIG_USB_STORAGE_DATAFAB=y
+-CONFIG_USB_STORAGE_FREECOM=y
++# 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=y
+-CONFIG_USB_STORAGE_HP8200e=y
++CONFIG_USB_STORAGE_USBAT=y
+ CONFIG_USB_STORAGE_SDDR09=y
+ CONFIG_USB_STORAGE_SDDR55=y
+ CONFIG_USB_STORAGE_JUMPSHOT=y
+@@ -846,21 +1022,25 @@ CONFIG_USB_HID=y
+ CONFIG_USB_HIDINPUT=y
+ # CONFIG_HID_FF is not set
+ CONFIG_USB_HIDDEV=y
+-CONFIG_USB_AIPTEK=m
+-CONFIG_USB_WACOM=m
+-CONFIG_USB_KBTAB=m
++# 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_YEALINK is not set
+ # CONFIG_USB_XPAD is not set
+ # CONFIG_USB_ATI_REMOTE 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
+-CONFIG_USB_HPUSBSCSI=m
+ 
+ #
+ # USB Multimedia devices
+@@ -879,6 +1059,7 @@ CONFIG_USB_HPUSBSCSI=m
+ # 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
+@@ -894,7 +1075,6 @@ CONFIG_USB_HPUSBSCSI=m
+ #
+ # CONFIG_USB_EMI62 is not set
+ # CONFIG_USB_EMI26 is not set
+-# CONFIG_USB_TIGL is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ CONFIG_USB_LEGOTOWER=m
+@@ -903,10 +1083,12 @@ CONFIG_USB_LEGOTOWER=m
+ # CONFIG_USB_CYTHERM is not set
+ # CONFIG_USB_PHIDGETKIT is not set
+ # CONFIG_USB_PHIDGETSERVO is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_LD is not set
+ # CONFIG_USB_TEST is not set
+ 
+ #
+-# USB ATM/DSL drivers
++# USB DSL modem support
+ #
+ 
+ #
+@@ -920,27 +1102,41 @@ CONFIG_USB_LEGOTOWER=m
+ # CONFIG_MMC is not set
+ 
+ #
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN 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 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=m
+-# CONFIG_XFS_RT is not set
++CONFIG_XFS_EXPORT=y
+ # 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_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
+@@ -966,13 +1162,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+ CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-# CONFIG_DEVPTS_FS_XATTR is not set
+ CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLBFS is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -996,16 +1190,19 @@ CONFIG_RAMFS=y
+ #
+ 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=y
++# CONFIG_NFSD_V3_ACL is not set
+ # CONFIG_NFSD_V4 is not set
+ # CONFIG_NFSD_TCP is not set
+ 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
+@@ -1014,6 +1211,7 @@ CONFIG_SUNRPC=y
+ # 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
+@@ -1074,13 +1272,19 @@ CONFIG_OPROFILE=m
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ CONFIG_DEBUG_KERNEL=y
+ CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_DETECT_SOFTLOCKUP=y
+ # 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_INFO is not set
++# CONFIG_DEBUG_IOREMAP is not set
++# CONFIG_DEBUG_FS is not set
+ 
+ #
+ # Security options
+@@ -1092,21 +1296,22 @@ CONFIG_MAGIC_SYSRQ=y
+ # Cryptographic options
+ #
+ CONFIG_CRYPTO=y
+-CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_HMAC is not set
+ CONFIG_CRYPTO_NULL=m
+-CONFIG_CRYPTO_MD4=m
++# CONFIG_CRYPTO_MD4 is not set
+ CONFIG_CRYPTO_MD5=m
+-CONFIG_CRYPTO_SHA1=m
+-CONFIG_CRYPTO_SHA256=m
++# 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=m
+-CONFIG_CRYPTO_TWOFISH=m
+-CONFIG_CRYPTO_SERPENT=m
+-CONFIG_CRYPTO_AES=m
+-CONFIG_CRYPTO_CAST5=m
+-CONFIG_CRYPTO_CAST6=m
++# 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
+@@ -1117,9 +1322,14 @@ CONFIG_CRYPTO_CRC32C=m
+ CONFIG_CRYPTO_TEST=m
+ 
+ #
++# Hardware crypto devices
++#
++
++#
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
++# CONFIG_CRC16 is not set
+ CONFIG_CRC32=y
+ CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=m
+diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig
+--- a/arch/parisc/defconfig
++++ b/arch/parisc/defconfig
+@@ -1,38 +1,56 @@
+ #
+ # Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14-rc5-pa1
++# Fri Oct 21 23:01:33 2005
+ #
+ CONFIG_PARISC=y
+ CONFIG_MMU=y
+ CONFIG_STACK_GROWSUP=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
+ 
+ #
+ # Code maturity level options
+ #
+ CONFIG_EXPERIMENTAL=y
+ CONFIG_CLEAN_COMPILE=y
+-CONFIG_STANDALONE=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 is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+-CONFIG_LOG_BUF_SHIFT=15
++# CONFIG_AUDIT is not set
+ # CONFIG_HOTPLUG is not set
++CONFIG_KOBJECT_UEVENT=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
++CONFIG_INITRAMFS_SOURCE=""
+ # 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_IOSCHED_NOOP=y
+-CONFIG_IOSCHED_AS=y
+-CONFIG_IOSCHED_DEADLINE=y
+-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SHMEM=y
++CONFIG_CC_ALIGN_FUNCTIONS=0
++CONFIG_CC_ALIGN_LABELS=0
++CONFIG_CC_ALIGN_LOOPS=0
++CONFIG_CC_ALIGN_JUMPS=0
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
+ 
+ #
+ # Loadable module support
+@@ -45,10 +63,21 @@ CONFIG_IOSCHED_DEADLINE=y
+ CONFIG_PA7000=y
+ # CONFIG_PA7100LC is not set
+ # CONFIG_PA7200 is not set
++# CONFIG_PA7300LC is not set
+ # CONFIG_PA8X00 is not set
+ CONFIG_PA11=y
+-# CONFIG_64BIT is not set
+ # CONFIG_SMP is not set
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++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_PREEMPT is not set
+ # CONFIG_HPUX is not set
+ 
+@@ -65,14 +94,29 @@ CONFIG_EISA_NAMES=y
+ # CONFIG_ISA is not set
+ CONFIG_PCI=y
+ CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
++# CONFIG_PCI_DEBUG is not set
+ CONFIG_GSC_DINO=y
+ CONFIG_PCI_LBA=y
+ CONFIG_IOSAPIC=y
+ CONFIG_IOMMU_SBA=y
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# CONFIG_PCCARD is not set
++
++#
++# PCI Hotplug Support
++#
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# PA-RISC specific drivers
++#
+ CONFIG_SUPERIO=y
+ CONFIG_CHASSIS_LCD_LED=y
+ CONFIG_PDC_CHASSIS=y
++CONFIG_PDC_STABLE=y
+ 
+ #
+ # Executable file formats
+@@ -81,15 +125,97 @@ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++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 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 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_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_BIC=y
++CONFIG_IPV6=y
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_IPV6_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
++# 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
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE 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
+ 
+ #
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+@@ -99,12 +225,10 @@ CONFIG_BINFMT_ELF=y
+ #
+ CONFIG_PARPORT=y
+ CONFIG_PARPORT_PC=y
+-CONFIG_PARPORT_PC_CML1=y
+ # CONFIG_PARPORT_SERIAL is not set
+ # CONFIG_PARPORT_PC_FIFO is not set
+ # CONFIG_PARPORT_PC_SUPERIO is not set
+ CONFIG_PARPORT_GSC=y
+-# CONFIG_PARPORT_OTHER is not set
+ # CONFIG_PARPORT_1284 is not set
+ 
+ #
+@@ -114,18 +238,31 @@ CONFIG_PARPORT_GSC=y
+ #
+ # Block devices
+ #
+-# CONFIG_BLK_DEV_FD is not set
+ # CONFIG_PARIDE is not set
+ # CONFIG_BLK_CPQ_DA is not set
+ # CONFIG_BLK_CPQ_CISS_DA is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ # CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
+ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_BLK_DEV_CRYPTOLOOP=y
+ # 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_INITRD=y
++# CONFIG_CDROM_PKTCDVD is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
+ 
+ #
+ # ATA/ATAPI/MFM/RLL support
+@@ -135,6 +272,7 @@ CONFIG_BLK_DEV_INITRD=y
+ #
+ # SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ CONFIG_SCSI=y
+ CONFIG_SCSI_PROC_FS=y
+ 
+@@ -147,53 +285,59 @@ CONFIG_CHR_DEV_ST=y
+ CONFIG_BLK_DEV_SR=y
+ # CONFIG_BLK_DEV_SR_VENDOR 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_REPORT_LUNS 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_BLK_DEV_3W_XXXX_RAID is not set
++# CONFIG_SCSI_3W_9XXX is not set
+ # CONFIG_SCSI_ACARD is not set
+ # CONFIG_SCSI_AHA1740 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_ADVANSYS is not set
+-# CONFIG_SCSI_MEGARAID 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_BUSLOGIC is not set
+-# CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_IPS is not set
++# CONFIG_SCSI_INITIO is not set
+ # CONFIG_SCSI_INIA100 is not set
+ # CONFIG_SCSI_PPA is not set
+ # CONFIG_SCSI_IMM is not set
+ CONFIG_SCSI_LASI700=y
+-CONFIG_53C700_MEM_MAPPED=y
+ CONFIG_53C700_LE_ON_BE=y
+ CONFIG_SCSI_SYM53C8XX_2=y
+ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+ # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
++# CONFIG_SCSI_IPR is not set
+ CONFIG_SCSI_ZALON=y
+ CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+ CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+ CONFIG_SCSI_NCR53C8XX_SYNC=20
+ # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+-# CONFIG_SCSI_QLOGIC_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+ CONFIG_SCSI_QLA2XXX=y
+@@ -202,7 +346,8 @@ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA2300 is not set
+ # CONFIG_SCSI_QLA2322 is not set
+ # CONFIG_SCSI_QLA6312 is not set
+-# CONFIG_SCSI_QLA6322 is not set
++# CONFIG_SCSI_QLA24XX is not set
++# CONFIG_SCSI_LPFC is not set
+ # CONFIG_SCSI_SIM710 is not set
+ # CONFIG_SCSI_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+@@ -217,15 +362,20 @@ 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_RAID5=y
+ # CONFIG_MD_RAID6 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
+@@ -238,80 +388,23 @@ CONFIG_MD_RAID5=y
+ # CONFIG_I2O is not set
+ 
+ #
+-# Macintosh device drivers
+-#
+-
+-#
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-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=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_INET_ECN 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_IPV6 is not set
+-# CONFIG_DECNET is not set
+-# CONFIG_BRIDGE is not set
+-# CONFIG_NETFILTER is not set
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
+-#
+-CONFIG_IPV6_SCTP__=y
+-# CONFIG_IP_SCTP is not set
+-# CONFIG_ATM is not set
+-# CONFIG_VLAN_8021Q 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
+-# CONFIG_NET_HW_FLOWCONTROL is not set
+-
+-#
+-# QoS and/or fair queueing
+-#
+-# CONFIG_NET_SCHED is not set
+-
+-#
+-# Network testing
++# Network device support
+ #
+-# CONFIG_NET_PKTGEN 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
+ 
+ #
+ # ARCnet devices
+ #
+ # CONFIG_ARCNET is not set
+-# CONFIG_DUMMY is not set
+-# CONFIG_BONDING is not set
+-# CONFIG_EQUALIZER is not set
+-# CONFIG_TUN is not set
+-# CONFIG_ETHERTAP is not set
++
++#
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -321,6 +414,7 @@ CONFIG_NET_ETHERNET=y
+ CONFIG_LASI_82596=y
+ # CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
+ # CONFIG_NET_VENDOR_3COM is not set
+ # CONFIG_NET_VENDOR_SMC is not set
+ 
+@@ -336,6 +430,7 @@ CONFIG_TULIP=y
+ # CONFIG_DE4X5 is not set
+ # CONFIG_WINBOND_840 is not set
+ # CONFIG_DM9102 is not set
++# CONFIG_ULI526X is not set
+ # CONFIG_DEPCA is not set
+ # CONFIG_HP100 is not set
+ CONFIG_NET_PCI=y
+@@ -361,30 +456,37 @@ CONFIG_NET_PCI=y
+ # CONFIG_SUNDANCE is not set
+ # CONFIG_TLAN is not set
+ # CONFIG_VIA_RHINE is not set
++# CONFIG_NET_POCKET is not set
+ 
+ #
+ # Ethernet (1000 Mbit)
+ #
+-# CONFIG_ACENIC is not set
+-CONFIG_DL2K=y
++CONFIG_ACENIC=y
++# CONFIG_ACENIC_OMIT_TIGON_I 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_SK98LIN is not set
+-# CONFIG_TIGON3 is not set
++# CONFIG_VIA_VELOCITY is not set
++CONFIG_TIGON3=y
++# CONFIG_BNX2 is not set
+ 
+ #
+ # Ethernet (10000 Mbit)
+ #
++# CONFIG_CHELSIO_T1 is not set
+ # CONFIG_IXGB is not set
+-# CONFIG_FDDI is not set
+-# CONFIG_HIPPI is not set
+-# CONFIG_PLIP is not set
+-# CONFIG_PPP is not set
+-# CONFIG_SLIP is not set
++# CONFIG_S2IO is not set
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
+ 
+ #
+ # Wireless LAN (non-hamradio)
+@@ -399,38 +501,30 @@ CONFIG_NET_RADIO=y
+ #
+ # Wireless 802.11b ISA/PCI cards support
+ #
+-CONFIG_AIRO=y
+ # CONFIG_HERMES is not set
+ # CONFIG_ATMEL is not set
+-CONFIG_NET_WIRELESS=y
+ 
+ #
+-# Token Ring devices
++# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+ #
+-# CONFIG_TR is not set
+-# CONFIG_NET_FC is not set
+-# CONFIG_RCPCI is not set
+-# CONFIG_SHAPER is not set
++# CONFIG_PRISM54 is not set
++# CONFIG_HOSTAP is not set
++CONFIG_NET_WIRELESS=y
+ 
+ #
+ # Wan interfaces
+ #
+ # CONFIG_WAN is not set
+-
+-#
+-# Amateur Radio support
+-#
+-# CONFIG_HAMRADIO is not set
+-
+-#
+-# IrDA (infrared) support
+-#
+-# CONFIG_IRDA is not set
+-
+-#
+-# Bluetooth support
+-#
+-# CONFIG_BT is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP 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
+@@ -460,51 +554,67 @@ CONFIG_INPUT_EVDEV=y
+ # CONFIG_INPUT_EVBUG is not set
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_SERPORT is not set
+-# CONFIG_SERIO_PARKBD is not set
+-CONFIG_SERIO_GSCPS2=y
+-CONFIG_HP_SDC=y
+-CONFIG_HIL_MLC=y
+-# CONFIG_SERIO_PCIPS2 is not set
+-
+-#
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
+ # CONFIG_KEYBOARD_ATKBD is not set
+ # 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_KEYBOARD_HIL_OLD=y
+ CONFIG_KEYBOARD_HIL=y
+ CONFIG_INPUT_MOUSE=y
+ # CONFIG_MOUSE_PS2 is not set
+ # CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_VSXXXAA is not set
+ # CONFIG_MOUSE_HIL is not set
+ CONFIG_INPUT_JOYSTICK=y
++# CONFIG_JOYSTICK_ANALOG is not set
++# CONFIG_JOYSTICK_A3D is not set
++# CONFIG_JOYSTICK_ADI is not set
++# CONFIG_JOYSTICK_COBRA is not set
++# CONFIG_JOYSTICK_GF2K is not set
++# CONFIG_JOYSTICK_GRIP is not set
++# CONFIG_JOYSTICK_GRIP_MP is not set
++# CONFIG_JOYSTICK_GUILLEMOT is not set
++# CONFIG_JOYSTICK_INTERACT is not set
++# CONFIG_JOYSTICK_SIDEWINDER is not set
++# CONFIG_JOYSTICK_TMDC is not set
+ # CONFIG_JOYSTICK_IFORCE is not set
+ # CONFIG_JOYSTICK_WARRIOR is not set
+ # CONFIG_JOYSTICK_MAGELLAN is not set
+ # CONFIG_JOYSTICK_SPACEORB is not set
+ # CONFIG_JOYSTICK_SPACEBALL is not set
+ # CONFIG_JOYSTICK_STINGER is not set
+-# CONFIG_JOYSTICK_TWIDDLER is not set
++# CONFIG_JOYSTICK_TWIDJOY is not set
+ # CONFIG_JOYSTICK_DB9 is not set
+ # CONFIG_JOYSTICK_GAMECON is not set
+ # CONFIG_JOYSTICK_TURBOGRAFX is not set
+-# CONFIG_INPUT_JOYDUMP is not set
++# CONFIG_JOYSTICK_JOYDUMP is not set
+ CONFIG_INPUT_TOUCHSCREEN=y
+ # CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
+ CONFIG_INPUT_MISC=y
+-# CONFIG_INPUT_PCSPKR is not set
+ # CONFIG_INPUT_UINPUT is not set
+ CONFIG_HP_SDC_RTC=y
+ 
+ #
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_PARKBD is not set
++CONFIG_SERIO_GSCPS2=y
++CONFIG_HP_SDC=y
++CONFIG_HIL_MLC=y
++# CONFIG_SERIO_PCIPS2 is not set
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
+ # Character devices
+ #
+ CONFIG_VT=y
+@@ -522,16 +632,16 @@ 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_MULTIPORT is not set
+ # CONFIG_SERIAL_8250_RSA is not set
+ 
+ #
+ # Non-8250 serial port support
+ #
+-# CONFIG_SERIAL_MUX is not set
+-# CONFIG_PDC_CONSOLE is not set
++CONFIG_SERIAL_MUX=y
++CONFIG_SERIAL_MUX_CONSOLE=y
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -541,12 +651,6 @@ CONFIG_PRINTER=y
+ # CONFIG_TIPAR is not set
+ 
+ #
+-# Mice
+-#
+-# CONFIG_BUSMOUSE is not set
+-# CONFIG_QIC02_TAPE is not set
+-
+-#
+ # IPMI
+ #
+ # CONFIG_IPMI_HANDLER is not set
+@@ -555,7 +659,6 @@ CONFIG_PRINTER=y
+ # Watchdog Cards
+ #
+ # CONFIG_WATCHDOG is not set
+-# CONFIG_NVRAM is not set
+ CONFIG_GEN_RTC=y
+ # CONFIG_GEN_RTC_X is not set
+ # CONFIG_DTLK is not set
+@@ -565,21 +668,40 @@ CONFIG_GEN_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_FTAPE is not set
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+ #
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
+ # I2C support
+ #
+ # CONFIG_I2C 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_HWMON_DEBUG_CHIP is not set
++
++#
+ # Misc devices
+ #
+ 
+ #
++# Multimedia Capabilities Port drivers
++#
++
++#
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+@@ -593,34 +715,45 @@ CONFIG_GEN_RTC=y
+ # Graphics support
+ #
+ CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++CONFIG_FB_SOFT_CURSOR=y
++# CONFIG_FB_MACMODES 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_STI=y
++# CONFIG_FB_NVIDIA is not set
+ # CONFIG_FB_RIVA is not set
+ # CONFIG_FB_MATROX is not set
+ # CONFIG_FB_RADEON_OLD 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_CYBLA is not set
+ # CONFIG_FB_TRIDENT is not set
++# CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+ 
+ #
+ # Console display driver support
+ #
+-# CONFIG_MDA_CONSOLE is not set
+-CONFIG_STI_CONSOLE=y
++CONFIG_DUMMY_CONSOLE=y
+ CONFIG_DUMMY_CONSOLE_COLUMNS=160
+ CONFIG_DUMMY_CONSOLE_ROWS=64
+-CONFIG_DUMMY_CONSOLE=y
+ CONFIG_FRAMEBUFFER_CONSOLE=y
+-CONFIG_PCI_CONSOLE=y
++CONFIG_STI_CONSOLE=y
+ # CONFIG_FONTS is not set
+ CONFIG_FONT_8x8=y
+ CONFIG_FONT_8x16=y
+@@ -629,6 +762,7 @@ CONFIG_FONT_8x16=y
+ # Logo configuration
+ #
+ # CONFIG_LOGO is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+ 
+ #
+ # Sound
+@@ -638,17 +772,94 @@ CONFIG_SOUND=y
+ #
+ # Advanced Linux Sound Architecture
+ #
+-# CONFIG_SND is not set
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_SEQUENCER_OSS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++# 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
++CONFIG_SND_AC97_CODEC=y
++CONFIG_SND_AC97_BUS=y
++
++#
++# PCI devices
++#
++# CONFIG_SND_ALI5451 is not set
++# CONFIG_SND_ATIIXP is not set
++# CONFIG_SND_ATIIXP_MODEM is not set
++# CONFIG_SND_AU8810 is not set
++# CONFIG_SND_AU8820 is not set
++# CONFIG_SND_AU8830 is not set
++# CONFIG_SND_AZT3328 is not set
++# CONFIG_SND_BT87X is not set
++# CONFIG_SND_CS46XX is not set
++# CONFIG_SND_CS4281 is not set
++# CONFIG_SND_EMU10K1 is not set
++# CONFIG_SND_EMU10K1X is not set
++# CONFIG_SND_CA0106 is not set
++# CONFIG_SND_KORG1212 is not set
++# CONFIG_SND_MIXART is not set
++# CONFIG_SND_NM256 is not set
++# CONFIG_SND_RME32 is not set
++# CONFIG_SND_RME96 is not set
++# CONFIG_SND_RME9652 is not set
++# CONFIG_SND_HDSP is not set
++# CONFIG_SND_HDSPM is not set
++# CONFIG_SND_TRIDENT is not set
++# CONFIG_SND_YMFPCI is not set
++CONFIG_SND_AD1889=y
++# CONFIG_SND_AD1889_OPL3 is not set
++# CONFIG_SND_CMIPCI is not set
++# CONFIG_SND_ENS1370 is not set
++# CONFIG_SND_ENS1371 is not set
++# CONFIG_SND_ES1938 is not set
++# CONFIG_SND_ES1968 is not set
++# CONFIG_SND_MAESTRO3 is not set
++# CONFIG_SND_FM801 is not set
++# CONFIG_SND_ICE1712 is not set
++# CONFIG_SND_ICE1724 is not set
++# CONFIG_SND_INTEL8X0 is not set
++# CONFIG_SND_INTEL8X0M is not set
++# CONFIG_SND_SONICVIBES is not set
++# CONFIG_SND_VIA82XX is not set
++# CONFIG_SND_VIA82XX_MODEM is not set
++# CONFIG_SND_VX222 is not set
++# CONFIG_SND_HDA_INTEL is not set
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++
++#
++# GSC devices
++#
++CONFIG_SND_HARMONY=y
+ 
+ #
+ # Open Sound System
+ #
+ # CONFIG_SOUND_PRIME is not set
+-# CONFIG_SOUND_HARMONY is not set
+ 
+ #
+ # USB support
+ #
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
+ CONFIG_USB=y
+ CONFIG_USB_DEBUG=y
+ 
+@@ -658,26 +869,36 @@ CONFIG_USB_DEBUG=y
+ # CONFIG_USB_DEVICEFS is not set
+ # CONFIG_USB_BANDWIDTH is not set
+ # CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
+ 
+ #
+ # 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_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_AUDIO is not set
++# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+ # CONFIG_USB_BLUETOOTH_TTY is not set
+-# CONFIG_USB_MIDI 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 is not set
+ 
+ #
+-# USB Human Interface Devices (HID)
++# USB Input Devices
+ #
+ # CONFIG_USB_HID is not set
+ 
+@@ -688,16 +909,23 @@ CONFIG_USB_OHCI_HCD=y
+ # 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_YEALINK is not set
+ # CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE 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
+-# CONFIG_USB_HPUSBSCSI is not set
+ 
+ #
+ # USB Multimedia devices
+@@ -709,13 +937,15 @@ CONFIG_USB_OHCI_HCD=y
+ #
+ 
+ #
+-# USB Network adaptors
++# 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
+@@ -732,12 +962,21 @@ CONFIG_USB_OHCI_HCD=y
+ #
+ # CONFIG_USB_EMI62 is not set
+ # CONFIG_USB_EMI26 is not set
+-# CONFIG_USB_TIGL is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+ # CONFIG_USB_LCD is not set
+ # CONFIG_USB_LED is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGETKIT is not set
++# CONFIG_USB_PHIDGETSERVO is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++
++#
++# USB DSL modem support
++#
+ 
+ #
+ # USB Gadget Support
+@@ -745,22 +984,41 @@ CONFIG_USB_OHCI_HCD=y
+ # CONFIG_USB_GADGET is not set
+ 
+ #
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN 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 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_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
+@@ -773,7 +1031,8 @@ CONFIG_JOLIET=y
+ #
+ # DOS/FAT/NT Filesystems
+ #
+-# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
+ # CONFIG_NTFS_FS is not set
+ 
+ #
+@@ -781,11 +1040,11 @@ CONFIG_JOLIET=y
+ #
+ CONFIG_PROC_FS=y
+ CONFIG_PROC_KCORE=y
+-# CONFIG_DEVFS_FS is not set
+-# CONFIG_DEVPTS_FS_XATTR is not set
++CONFIG_SYSFS=y
+ CONFIG_TMPFS=y
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -809,23 +1068,28 @@ CONFIG_RAMFS=y
+ #
+ 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=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=y
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+-# CONFIG_SUNRPC_GSS is not set
++# 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
+@@ -861,6 +1125,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ # 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
+@@ -885,17 +1150,24 @@ CONFIG_OPROFILE=y
+ #
+ # Kernel hacking
+ #
++# CONFIG_PRINTK_TIME is not set
+ CONFIG_DEBUG_KERNEL=y
+-# CONFIG_DEBUG_SLAB is not set
+ CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=15
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_DEBUG_SLAB is not set
+ # CONFIG_DEBUG_SPINLOCK is not set
+-# CONFIG_DEBUG_RWLOCK is not set
+-CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_KOBJECT is not set
+ # CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_IOREMAP is not set
++# CONFIG_DEBUG_FS is not set
+ 
+ #
+ # Security options
+ #
++# CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
+ 
+ #
+@@ -909,6 +1181,8 @@ CONFIG_CRYPTO=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 is not set
+ # CONFIG_CRYPTO_BLOWFISH is not set
+ # CONFIG_CRYPTO_TWOFISH is not set
+@@ -916,11 +1190,23 @@ CONFIG_CRYPTO=y
+ # 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
+diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
+--- a/arch/parisc/kernel/cache.c
++++ b/arch/parisc/kernel/cache.c
+@@ -27,6 +27,7 @@
+ #include <asm/page.h>
+ #include <asm/pgalloc.h>
+ #include <asm/processor.h>
++#include <asm/sections.h>
+ 
+ int split_tlb;
+ int dcache_stride;
+@@ -207,6 +208,9 @@ parisc_cache_init(void)
+ 
+ 	/* "New and Improved" version from Jim Hull 
+ 	 *	(1 << (cc_block-1)) * (cc_line << (4 + cnf.cc_shift))
++	 * The following CAFL_STRIDE is an optimized version, see
++	 * http://lists.parisc-linux.org/pipermail/parisc-linux/2004-June/023625.html
++	 * http://lists.parisc-linux.org/pipermail/parisc-linux/2004-June/023671.html
+ 	 */
+ #define CAFL_STRIDE(cnf) (cnf.cc_line << (3 + cnf.cc_block + cnf.cc_shift))
+ 	dcache_stride = CAFL_STRIDE(cache_info.dc_conf);
+@@ -266,7 +270,6 @@ void flush_dcache_page(struct page *page
+ 	unsigned long offset;
+ 	unsigned long addr;
+ 	pgoff_t pgoff;
+-	pte_t *pte;
+ 	unsigned long pfn = page_to_pfn(page);
+ 
+ 
+@@ -297,21 +300,16 @@ void flush_dcache_page(struct page *page
+ 		 * taking a page fault if the pte doesn't exist.
+ 		 * This is just for speed.  If the page translation
+ 		 * isn't there, there's no point exciting the
+-		 * nadtlb handler into a nullification frenzy */
+-
+-
+-  		if(!(pte = translation_exists(mpnt, addr)))
+-			continue;
+-
+-		/* make sure we really have this page: the private
++		 * nadtlb handler into a nullification frenzy.
++		 *
++		 * Make sure we really have this page: the private
+ 		 * mappings may cover this area but have COW'd this
+-		 * particular page */
+-		if(pte_pfn(*pte) != pfn)
+-  			continue;
+-
+-		__flush_cache_page(mpnt, addr);
+-
+-		break;
++		 * particular page.
++		 */
++  		if (translation_exists(mpnt, addr, pfn)) {
++			__flush_cache_page(mpnt, addr);
++			break;
++		}
+ 	}
+ 	flush_dcache_mmap_unlock(mapping);
+ }
+@@ -339,17 +337,15 @@ int parisc_cache_flush_threshold = FLUSH
+ void parisc_setup_cache_timing(void)
+ {
+ 	unsigned long rangetime, alltime;
+-	extern char _text;	/* start of kernel code, defined by linker */
+-	extern char _end;	/* end of BSS, defined by linker */
+ 	unsigned long size;
+ 
+ 	alltime = mfctl(16);
+ 	flush_data_cache();
+ 	alltime = mfctl(16) - alltime;
+ 
+-	size = (unsigned long)(&_end - _text);
++	size = (unsigned long)(_end - _text);
+ 	rangetime = mfctl(16);
+-	flush_kernel_dcache_range((unsigned long)&_text, size);
++	flush_kernel_dcache_range((unsigned long)_text, size);
+ 	rangetime = mfctl(16) - rangetime;
+ 
+ 	printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n",
+diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
+--- a/arch/parisc/kernel/drivers.c
++++ b/arch/parisc/kernel/drivers.c
+@@ -46,36 +46,51 @@ static struct device root = {
+ 	.bus_id = "parisc",
+ };
+ 
+-#define for_each_padev(padev) \
+-	for (padev = next_dev(&root); padev != NULL; \
+-			padev = next_dev(&padev->dev))
++static inline int check_dev(struct device *dev)
++{
++	if (dev->bus == &parisc_bus_type) {
++		struct parisc_device *pdev;
++		pdev = to_parisc_device(dev);
++		return pdev->id.hw_type != HPHW_FAULTY;
++	}
++	return 1;
++}
++
++static struct device *
++parse_tree_node(struct device *parent, int index, struct hardware_path *modpath);
+ 
+-#define check_dev(padev) \
+-	(padev->id.hw_type != HPHW_FAULTY) ? padev : next_dev(&padev->dev)
++struct recurse_struct {
++	void * obj;
++	int (*fn)(struct device *, void *);
++};
++
++static int descend_children(struct device * dev, void * data)
++{
++	struct recurse_struct * recurse_data = (struct recurse_struct *)data;
++
++	if (recurse_data->fn(dev, recurse_data->obj))
++		return 1;
++	else
++		return device_for_each_child(dev, recurse_data, descend_children);
++}
+ 
+ /**
+- * next_dev - enumerates registered devices
+- * @dev: the previous device returned from next_dev
++ *	for_each_padev - Iterate over all devices in the tree
++ *	@fn:	Function to call for each device.
++ *	@data:	Data to pass to the called function.
+  *
+- * next_dev does a depth-first search of the tree, returning parents
+- * before children.  Returns NULL when there are no more devices.
++ *	This performs a depth-first traversal of the tree, calling the
++ *	function passed for each node.  It calls the function for parents
++ *	before children.
+  */
+-static struct parisc_device *next_dev(struct device *dev)
+-{
+-	if (!list_empty(&dev->children)) {
+-		dev = list_to_dev(dev->children.next);
+-		return check_dev(to_parisc_device(dev));
+-	}
+ 
+-	while (dev != &root) {
+-		if (dev->node.next != &dev->parent->children) {
+-			dev = list_to_dev(dev->node.next);
+-			return to_parisc_device(dev);
+-		}
+-		dev = dev->parent;
+-	}
+-
+-	return NULL;
++static int for_each_padev(int (*fn)(struct device *, void *), void * data)
++{
++	struct recurse_struct recurse_data = {
++		.obj	= data,
++		.fn	= fn,
++	};
++	return device_for_each_child(&root, &recurse_data, descend_children);
+ }
+ 
+ /**
+@@ -105,12 +120,6 @@ static int match_device(struct parisc_dr
+ 	return 0;
+ }
+ 
+-static void claim_device(struct parisc_driver *driver, struct parisc_device *dev)
+-{
+-	dev->driver = driver;
+-	request_mem_region(dev->hpa, 0x1000, driver->name);
+-}
+-
+ static int parisc_driver_probe(struct device *dev)
+ {
+ 	int rc;
+@@ -119,8 +128,8 @@ static int parisc_driver_probe(struct de
+ 
+ 	rc = pa_drv->probe(pa_dev);
+ 
+-	if(!rc)
+-		claim_device(pa_drv, pa_dev);
++	if (!rc)
++		pa_dev->driver = pa_drv;
+ 
+ 	return rc;
+ }
+@@ -131,7 +140,6 @@ static int parisc_driver_remove(struct d
+ 	struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
+ 	if (pa_drv->remove)
+ 		pa_drv->remove(pa_dev);
+-	release_mem_region(pa_dev->hpa, 0x1000);
+ 
+ 	return 0;
+ }
+@@ -173,6 +181,24 @@ int register_parisc_driver(struct parisc
+ }
+ EXPORT_SYMBOL(register_parisc_driver);
+ 
++
++struct match_count {
++	struct parisc_driver * driver;
++	int count;
++};
++
++static int match_and_count(struct device * dev, void * data)
++{
++	struct match_count * m = data;
++	struct parisc_device * pdev = to_parisc_device(dev);
++
++	if (check_dev(dev)) {
++		if (match_device(m->driver, pdev))
++			m->count++;
++	}
++	return 0;
++}
++
+ /**
+  * count_parisc_driver - count # of devices this driver would match
+  * @driver: the PA-RISC driver to try
+@@ -182,15 +208,14 @@ EXPORT_SYMBOL(register_parisc_driver);
+  */
+ int count_parisc_driver(struct parisc_driver *driver)
+ {
+-	struct parisc_device *device;
+-	int cnt = 0;
++	struct match_count m = {
++		.driver	= driver,
++		.count	= 0,
++	};
+ 
+-	for_each_padev(device) {
+-		if (match_device(driver, device))
+-			cnt++;
+-	}
++	for_each_padev(match_and_count, &m);
+ 
+-	return cnt;
++	return m.count;
+ }
+ 
+ 
+@@ -206,14 +231,34 @@ int unregister_parisc_driver(struct pari
+ }
+ EXPORT_SYMBOL(unregister_parisc_driver);
+ 
+-static struct parisc_device *find_device_by_addr(unsigned long hpa)
++struct find_data {
++	unsigned long hpa;
++	struct parisc_device * dev;
++};
++
++static int find_device(struct device * dev, void * data)
+ {
+-	struct parisc_device *dev;
+-	for_each_padev(dev) {
+-		if (dev->hpa == hpa)
+-			return dev;
++	struct parisc_device * pdev = to_parisc_device(dev);
++	struct find_data * d = (struct find_data*)data;
++
++	if (check_dev(dev)) {
++		if (pdev->hpa.start == d->hpa) {
++			d->dev = pdev;
++			return 1;
++		}
+ 	}
+-	return NULL;
++	return 0;
++}
++
++static struct parisc_device *find_device_by_addr(unsigned long hpa)
++{
++	struct find_data d = {
++		.hpa	= hpa,
++	};
++	int ret;
++
++	ret = for_each_padev(find_device, &d);
++	return ret ? d.dev : NULL;
+ }
+ 
+ /**
+@@ -387,6 +432,23 @@ struct parisc_device * create_tree_node(
+ 	return dev;
+ }
+ 
++struct match_id_data {
++	char id;
++	struct parisc_device * dev;
++};
++
++static int match_by_id(struct device * dev, void * data)
++{
++	struct parisc_device * pdev = to_parisc_device(dev);
++	struct match_id_data * d = data;
++
++	if (pdev->hw_path == d->id) {
++		d->dev = pdev;
++		return 1;
++	}
++	return 0;
++}
++
+ /**
+  * alloc_tree_node - returns a device entry in the iotree
+  * @parent: the parent node in the tree
+@@ -397,15 +459,13 @@ struct parisc_device * create_tree_node(
+  */
+ static struct parisc_device * alloc_tree_node(struct device *parent, char id)
+ {
+-	struct device *dev;
+-
+-	list_for_each_entry(dev, &parent->children, node) {
+-		struct parisc_device *padev = to_parisc_device(dev);
+-		if (padev->hw_path == id)
+-			return padev;
+-	}
+-
+-	return create_tree_node(id, parent);
++	struct match_id_data d = {
++		.id = id,
++	};
++	if (device_for_each_child(parent, &d, match_by_id))
++		return d.dev;
++	else
++		return create_tree_node(id, parent);
+ }
+ 
+ static struct parisc_device *create_parisc_device(struct hardware_path *modpath)
+@@ -439,10 +499,8 @@ alloc_pa_dev(unsigned long hpa, struct h
+ 
+ 	dev = create_parisc_device(mod_path);
+ 	if (dev->id.hw_type != HPHW_FAULTY) {
+-		char p[64];
+-		print_pa_hwpath(dev, p);
+ 		printk("Two devices have hardware path %s.  Please file a bug with HP.\n"
+-			"In the meantime, you could try rearranging your cards.\n", p);
++			"In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev));
+ 		return NULL;
+ 	}
+ 
+@@ -451,12 +509,27 @@ alloc_pa_dev(unsigned long hpa, struct h
+ 	dev->id.hversion_rev = iodc_data[1] & 0x0f;
+ 	dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) |
+ 			(iodc_data[5] << 8) | iodc_data[6];
+-	dev->hpa = hpa;
++	dev->hpa.name = parisc_pathname(dev);
++	dev->hpa.start = hpa;
++	if (hpa == 0xf4000000 || hpa == 0xf6000000 ||
++	    hpa == 0xf8000000 || hpa == 0xfa000000) {
++		dev->hpa.end = hpa + 0x01ffffff;
++	} else {
++		dev->hpa.end = hpa + 0xfff;
++	}
++	dev->hpa.flags = IORESOURCE_MEM;
+ 	name = parisc_hardware_description(&dev->id);
+ 	if (name) {
+ 		strlcpy(dev->name, name, sizeof(dev->name));
+ 	}
+ 
++	/* Silently fail things like mouse ports which are subsumed within
++	 * the keyboard controller
++	 */
++	if ((hpa & 0xfff) == 0 && insert_resource(&iomem_resource, &dev->hpa))
++		printk("Unable to claim HPA %lx for device %s\n",
++				hpa, name);
++
+ 	return dev;
+ }
+ 
+@@ -555,6 +628,33 @@ static int match_parisc_device(struct de
+ 	return (curr->hw_path == id);
+ }
+ 
++struct parse_tree_data {
++	int index;
++	struct hardware_path * modpath;
++	struct device * dev;
++};
++
++static int check_parent(struct device * dev, void * data)
++{
++	struct parse_tree_data * d = data;
++
++	if (check_dev(dev)) {
++		if (dev->bus == &parisc_bus_type) {
++			if (match_parisc_device(dev, d->index, d->modpath))
++				d->dev = dev;
++		} else if (is_pci_dev(dev)) {
++			if (match_pci_device(dev, d->index, d->modpath))
++				d->dev = dev;
++		} else if (dev->bus == NULL) {
++			/* we are on a bus bridge */
++			struct device *new = parse_tree_node(dev, d->index, d->modpath);
++			if (new)
++				d->dev = new;
++		}
++	}
++	return d->dev != NULL;
++}
++
+ /**
+  * parse_tree_node - returns a device entry in the iotree
+  * @parent: the parent node in the tree
+@@ -568,24 +668,18 @@ static int match_parisc_device(struct de
+ static struct device *
+ parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
+ {
+-	struct device *device;
+-	 
+-	list_for_each_entry(device, &parent->children, node) {
+-		if (device->bus == &parisc_bus_type) {
+-			if (match_parisc_device(device, index, modpath))
+-				return device;
+-		} else if (is_pci_dev(device)) {
+-			if (match_pci_device(device, index, modpath))
+-				return device;
+-		} else if (device->bus == NULL) {
+-			/* we are on a bus bridge */
+-			struct device *new = parse_tree_node(device, index, modpath);
+-			if (new)
+-				return new;
+-		}
+-	}
++	struct parse_tree_data d = {
++		.index          = index,
++		.modpath        = modpath,
++	};
++
++	struct recurse_struct recurse_data = {
++		.obj	= &d,
++		.fn	= check_parent,
++	};
+ 
+-	return NULL;
++	device_for_each_child(parent, &recurse_data, descend_children);
++	return d.dev;
+ }
+ 
+ /**
+@@ -636,7 +730,7 @@ EXPORT_SYMBOL(device_to_hwpath);
+         ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
+ 
+ #define IS_LOWER_PORT(dev) \
+-        ((gsc_readl(dev->hpa + offsetof(struct bc_module, io_status)) \
++        ((gsc_readl(dev->hpa.start + offsetof(struct bc_module, io_status)) \
+                 & BC_PORT_MASK) == BC_LOWER_PORT)
+ 
+ #define MAX_NATIVE_DEVICES 64
+@@ -645,8 +739,8 @@ EXPORT_SYMBOL(device_to_hwpath);
+ #define FLEX_MASK 	F_EXTEND(0xfffc0000)
+ #define IO_IO_LOW	offsetof(struct bc_module, io_io_low)
+ #define IO_IO_HIGH	offsetof(struct bc_module, io_io_high)
+-#define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_LOW)
+-#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_HIGH)
++#define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_LOW)
++#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_HIGH)
+ 
+ static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
+                             struct device *parent);
+@@ -655,10 +749,10 @@ void walk_lower_bus(struct parisc_device
+ {
+ 	unsigned long io_io_low, io_io_high;
+ 
+-	if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
++	if (!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
+ 		return;
+ 
+-	if(dev->id.hw_type == HPHW_IOA) {
++	if (dev->id.hw_type == HPHW_IOA) {
+ 		io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16);
+ 		io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET;
+ 	} else {
+@@ -731,7 +825,7 @@ static void print_parisc_device(struct p
+ 
+ 	print_pa_hwpath(dev, hw_path);
+ 	printk(KERN_INFO "%d. %s at 0x%lx [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
+-		++count, dev->name, dev->hpa, hw_path, dev->id.hw_type,
++		++count, dev->name, dev->hpa.start, hw_path, dev->id.hw_type,
+ 		dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
+ 
+ 	if (dev->num_addrs) {
+@@ -753,13 +847,20 @@ void init_parisc_bus(void)
+ 	get_device(&root);
+ }
+ 
++
++static int print_one_device(struct device * dev, void * data)
++{
++	struct parisc_device * pdev = to_parisc_device(dev);
++
++	if (check_dev(dev))
++		print_parisc_device(pdev);
++	return 0;
++}
++
+ /**
+  * print_parisc_devices - Print out a list of devices found in this system
+  */
+ void print_parisc_devices(void)
+ {
+-	struct parisc_device *dev;
+-	for_each_padev(dev) {
+-		print_parisc_device(dev);
+-	}
++	for_each_padev(print_one_device, NULL);
+ }
+diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
+--- a/arch/parisc/kernel/entry.S
++++ b/arch/parisc/kernel/entry.S
+@@ -30,14 +30,14 @@
+  *  - save registers to kernel stack and handle in assembly or C */
+ 
+ 
++#include <asm/psw.h>
+ #include <asm/assembly.h>	/* for LDREG/STREG defines */
+ #include <asm/pgtable.h>
+-#include <asm/psw.h>
+ #include <asm/signal.h>
+ #include <asm/unistd.h>
+ #include <asm/thread_info.h>
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ #define CMPIB           cmpib,*
+ #define CMPB            cmpb,*
+ #define COND(x)		*x
+@@ -67,19 +67,22 @@
+ 
+ 	/* Switch to virtual mapping, trashing only %r1 */
+ 	.macro  virt_map
+-	rsm     PSW_SM_Q,%r0
+-	tovirt_r1 %r29
+-	mfsp	%sr7, %r1
+-	or,=    %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
+-	mtsp	%r1, %sr3
++	/* pcxt_ssm_bug */
++	rsm	PSW_SM_I, %r0	/* barrier for "Relied upon Translation */
+ 	mtsp	%r0, %sr4
+ 	mtsp	%r0, %sr5
++	mfsp	%sr7, %r1
++	or,=    %r0,%r1,%r0	/* Only save sr7 in sr3 if sr7 != 0 */
++	mtsp	%r1, %sr3
++	tovirt_r1 %r29
++	load32	KERNEL_PSW, %r1
++
++	rsm     PSW_SM_QUIET,%r0	/* second "heavy weight" ctl op */
+ 	mtsp	%r0, %sr6
+ 	mtsp	%r0, %sr7
+-	load32	KERNEL_PSW, %r1
+-	mtctl	%r1, %cr22
+ 	mtctl	%r0, %cr17	/* Clear IIASQ tail */
+ 	mtctl	%r0, %cr17	/* Clear IIASQ head */
++	mtctl	%r1, %ipsw
+ 	load32	4f, %r1
+ 	mtctl	%r1, %cr18	/* Set IIAOQ tail */
+ 	ldo	4(%r1), %r1
+@@ -214,7 +217,7 @@
+ 	va  = r8	/* virtual address for which the trap occured */
+ 	spc = r24	/* space for which the trap occured */
+ 
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ 
+ 	/*
+ 	 * itlb miss interruption handler (parisc 1.1 - 32 bit)
+@@ -236,7 +239,7 @@
+ 
+ 	.macro	itlb_20 code
+ 	mfctl	%pcsq, spc
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	b       itlb_miss_20w
+ #else
+ 	b	itlb_miss_20
+@@ -246,7 +249,7 @@
+ 	.align		32
+ 	.endm
+ 	
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ 	/*
+ 	 * naitlb miss interruption handler (parisc 1.1 - 32 bit)
+ 	 *
+@@ -283,7 +286,7 @@
+ 	.macro	naitlb_20 code
+ 
+ 	mfctl	%isr,spc
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	b       itlb_miss_20w
+ #else
+ 	b	itlb_miss_20
+@@ -296,7 +299,7 @@
+ 	.align		32
+ 	.endm
+ 	
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ 	/*
+ 	 * dtlb miss interruption handler (parisc 1.1 - 32 bit)
+ 	 */
+@@ -318,7 +321,7 @@
+ 	.macro	dtlb_20 code
+ 
+ 	mfctl	%isr, spc
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	b       dtlb_miss_20w
+ #else
+ 	b	dtlb_miss_20
+@@ -328,7 +331,7 @@
+ 	.align		32
+ 	.endm
+ 	
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ 	/* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
+ 
+ 	.macro	nadtlb_11 code
+@@ -346,7 +349,7 @@
+ 	.macro	nadtlb_20 code
+ 
+ 	mfctl	%isr,spc
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	b       nadtlb_miss_20w
+ #else
+ 	b       nadtlb_miss_20
+@@ -356,7 +359,7 @@
+ 	.align		32
+ 	.endm
+ 	
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ 	/*
+ 	 * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
+ 	 */
+@@ -378,7 +381,7 @@
+ 	.macro	dbit_20 code
+ 
+ 	mfctl	%isr,spc
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	b       dbit_trap_20w
+ #else
+ 	b	dbit_trap_20
+@@ -391,7 +394,7 @@
+ 	/* The following are simple 32 vs 64 bit instruction
+ 	 * abstractions for the macros */
+ 	.macro		EXTR	reg1,start,length,reg2
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	extrd,u		\reg1,32+\start,\length,\reg2
+ #else
+ 	extrw,u		\reg1,\start,\length,\reg2
+@@ -399,7 +402,7 @@
+ 	.endm
+ 
+ 	.macro		DEP	reg1,start,length,reg2
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	depd		\reg1,32+\start,\length,\reg2
+ #else
+ 	depw		\reg1,\start,\length,\reg2
+@@ -407,7 +410,7 @@
+ 	.endm
+ 
+ 	.macro		DEPI	val,start,length,reg
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	depdi		\val,32+\start,\length,\reg
+ #else
+ 	depwi		\val,\start,\length,\reg
+@@ -418,7 +421,7 @@
+ 	 * fault.  We have to extract this and place it in the va,
+ 	 * zeroing the corresponding bits in the space register */
+ 	.macro		space_adjust	spc,va,tmp
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	extrd,u		\spc,63,SPACEID_SHIFT,\tmp
+ 	depd		%r0,63,SPACEID_SHIFT,\spc
+ 	depd		\tmp,31,SPACEID_SHIFT,\va
+@@ -476,7 +479,7 @@
+ 	bb,>=,n		\pmd,_PxD_PRESENT_BIT,\fault
+ 	DEP		%r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
+ 	copy		\pmd,%r9
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	shld		%r9,PxD_VALUE_SHIFT,\pmd
+ #else
+ 	shlw		%r9,PxD_VALUE_SHIFT,\pmd
+@@ -607,7 +610,7 @@
+ 	.macro		do_alias	spc,tmp,tmp1,va,pte,prot,fault
+ 	cmpib,COND(<>),n 0,\spc,\fault
+ 	ldil		L%(TMPALIAS_MAP_START),\tmp
+-#if defined(__LP64__) && (TMPALIAS_MAP_START >= 0x80000000)
++#if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000)
+ 	/* on LP64, ldi will sign extend into the upper 32 bits,
+ 	 * which is behaviour we don't want */
+ 	depdi		0,31,32,\tmp
+@@ -621,7 +624,7 @@
+ 	 * OK, it is in the temp alias region, check whether "from" or "to".
+ 	 * Check "subtle" note in pacache.S re: r23/r26.
+ 	 */
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	extrd,u,*=	\va,41,1,%r0
+ #else
+ 	extrw,u,=	\va,9,1,%r0
+@@ -688,7 +691,7 @@ fault_vector_20:
+ 	def		30
+ 	def		31
+ 
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ 
+ 	.export fault_vector_11
+ 	
+@@ -761,7 +764,7 @@ __kernel_thread:
+ 
+ 	copy	%r30, %r1
+ 	ldo	PT_SZ_ALGN(%r30),%r30
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* Yo, function pointers in wide mode are little structs... -PB */
+ 	ldd	24(%r26), %r2
+ 	STREG	%r2, PT_GR27(%r1)	/* Store childs %dp */
+@@ -777,7 +780,7 @@ __kernel_thread:
+ 	or	%r26, %r24, %r26      /* will have kernel mappings.	 */
+ 	ldi	1, %r25			/* stack_start, signals kernel thread */
+ 	stw	%r0, -52(%r30)	     	/* user_tid */
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+ #endif
+ 	BL	do_fork, %r2
+@@ -806,7 +809,7 @@ ret_from_kernel_thread:
+ 
+ 	LDREG	TI_TASK-THREAD_SZ_ALGN(%r30), %r1
+ 	LDREG	TASK_PT_GR25(%r1), %r26
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	LDREG	TASK_PT_GR27(%r1), %r27
+ 	LDREG	TASK_PT_GR22(%r1), %r22
+ #endif
+@@ -814,11 +817,16 @@ ret_from_kernel_thread:
+ 	ble	0(%sr7, %r1)
+ 	copy	%r31, %r2
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+ 	loadgp				/* Thread could have been in a module */
+ #endif
++#ifndef CONFIG_64BIT
+ 	b	sys_exit
++#else
++	load32	sys_exit, %r1
++	bv	%r0(%r1)
++#endif
+ 	ldi	0, %r26
+ 
+ 	.import	sys_execve, code
+@@ -830,7 +838,7 @@ __execve:
+ 	STREG	%r26, PT_GR26(%r16)
+ 	STREG	%r25, PT_GR25(%r16)
+ 	STREG	%r24, PT_GR24(%r16)
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+ #endif
+ 	BL	sys_execve, %r2
+@@ -855,6 +863,7 @@ __execve:
+ _switch_to:
+ 	STREG	 %r2, -RP_OFFSET(%r30)
+ 
++	callee_save_float
+ 	callee_save
+ 
+ 	load32	_switch_to_ret, %r2
+@@ -871,6 +880,7 @@ _switch_to:
+ _switch_to_ret:
+ 	mtctl	%r0, %cr0		/* Needed for single stepping */
+ 	callee_rest
++	callee_rest_float
+ 
+ 	LDREG	-RP_OFFSET(%r30), %r2
+ 	bv	%r0(%r2)
+@@ -888,9 +898,6 @@ _switch_to_ret:
+ 	 * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
+ 	 * adjust IASQ[0..1].
+ 	 *
+-	 * Note that the following code uses a "relied upon translation".
+-	 * See the parisc ACD for details. The ssm is necessary due to a
+-	 * PCXT bug.
+ 	 */
+ 
+ 	.align 4096
+@@ -911,7 +918,7 @@ syscall_exit_rfi:
+ 	STREG	%r19,PT_IAOQ1(%r16)
+ 	LDREG   PT_PSW(%r16),%r19
+ 	load32	USER_PSW_MASK,%r1
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	load32	USER_PSW_HI_MASK,%r20
+ 	depd    %r20,31,32,%r1
+ #endif
+@@ -955,7 +962,7 @@ intr_return:
+ 	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
+ 	** irq_stat[] is defined using ____cacheline_aligned.
+ 	*/
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	shld	%r1, 6, %r20
+ #else
+ 	shlw	%r1, 5, %r20
+@@ -963,9 +970,6 @@ intr_return:
+ 	add     %r19,%r20,%r19	/* now have &irq_stat[smp_processor_id()] */
+ #endif /* CONFIG_SMP */
+ 
+-	LDREG   IRQSTAT_SIRQ_PEND(%r19),%r20    /* hardirq.h: unsigned long */
+-	cmpib,<>,n 0,%r20,intr_do_softirq /* forward */
+-
+ intr_check_resched:
+ 
+ 	/* check for reschedule */
+@@ -985,24 +989,19 @@ intr_restore:
+ 	rest_fp         %r1
+ 	rest_general    %r29
+ 
+-	/* Create a "relied upon translation" PA 2.0 Arch. F-5 */
+-	ssm		0,%r0
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
++	/* inverse of virt_map */
++	pcxt_ssm_bug
++	rsm             PSW_SM_QUIET,%r0	/* prepare for rfi */
+ 	tophys_r1       %r29
+-	rsm             (PSW_SM_Q|PSW_SM_P|PSW_SM_D|PSW_SM_I),%r0
+ 
+ 	/* Restore space id's and special cr's from PT_REGS
+-	 * structure pointed to by r29 */
++	 * structure pointed to by r29
++	 */
+ 	rest_specials	%r29
+ 
+-	/* Important: Note that rest_stack restores r29
+-	 * last (we are using it)! It also restores r1 and r30. */
++	/* IMPORTANT: rest_stack restores r29 last (we are using it)!
++	 * It also restores r1 and r30.
++	 */
+ 	rest_stack
+ 
+ 	rfi
+@@ -1015,17 +1014,6 @@ intr_restore:
+ 	nop
+ 	nop
+ 
+-	.import do_softirq,code
+-intr_do_softirq:
+-	bl      do_softirq,%r2
+-#ifdef __LP64__
+-	ldo	-16(%r30),%r29		/* Reference param save area */
+-#else
+-	nop
+-#endif
+-	b       intr_check_resched
+-	nop
+-
+ 	.import schedule,code
+ intr_do_resched:
+ 	/* Only do reschedule if we are returning to user space */
+@@ -1036,12 +1024,17 @@ intr_do_resched:
+ 	CMPIB= 0,%r20,intr_restore /* backward */
+ 	nop
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+ #endif
+ 
+ 	ldil	L%intr_check_sig, %r2
++#ifndef CONFIG_64BIT
+ 	b	schedule
++#else
++	load32	schedule, %r20
++	bv	%r0(%r20)
++#endif
+ 	ldo	R%intr_check_sig(%r2), %r2
+ 
+ 
+@@ -1064,7 +1057,7 @@ intr_do_signal:
+ 
+ 	copy	%r0, %r24			/* unsigned long in_syscall */
+ 	copy	%r16, %r25			/* struct pt_regs *regs */
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29			/* Reference param save area */
+ #endif
+ 
+@@ -1088,7 +1081,7 @@ intr_extint:
+ 	mfctl	%cr31,%r1
+ 	copy	%r30,%r17
+ 	/* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	depdi	0,63,15,%r17
+ #else
+ 	depi	0,31,15,%r17
+@@ -1115,7 +1108,7 @@ intr_extint:
+ 
+ 	ldil	L%intr_return, %r2
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29	/* Reference param save area */
+ #endif
+ 
+@@ -1153,15 +1146,17 @@ intr_save:
+ 
+ 	CMPIB=,n        6,%r26,skip_save_ior
+ 
+-	/* save_specials left ipsw value in r8 for us to test */
+ 
+ 	mfctl           %cr20, %r16 /* isr */
++	nop		/* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
+ 	mfctl           %cr21, %r17 /* ior */
+ 
+-#ifdef __LP64__
++
++#ifdef CONFIG_64BIT
+ 	/*
+ 	 * If the interrupted code was running with W bit off (32 bit),
+ 	 * clear the b bits (bits 0 & 1) in the ior.
++	 * save_specials left ipsw value in r8 for us to test.
+ 	 */
+ 	extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
+ 	depdi           0,1,2,%r17
+@@ -1192,7 +1187,7 @@ skip_save_ior:
+ 	loadgp
+ 
+ 	copy		%r29, %r25	/* arg1 is pt_regs */
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo		-16(%r30),%r29	/* Reference param save area */
+ #endif
+ 
+@@ -1230,7 +1225,7 @@ skip_save_ior:
+ 	spc  = r24	/* space for which the trap occured */
+ 	ptp = r25	/* page directory/page table pointer */
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 
+ dtlb_miss_20w:
+ 	space_adjust	spc,va,t0
+@@ -1487,10 +1482,10 @@ nadtlb_emulate:
+ 	add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
+ 
+ nadtlb_nullify:
+-	mfctl           %cr22,%r8              /* Get ipsw */
++	mfctl           %ipsw,%r8
+ 	ldil            L%PSW_N,%r9
+ 	or              %r8,%r9,%r8            /* Set PSW_N */
+-	mtctl           %r8,%cr22
++	mtctl           %r8,%ipsw
+ 
+ 	rfir
+ 	nop
+@@ -1521,7 +1516,7 @@ nadtlb_probe_check:
+ 	nop
+ 
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ itlb_miss_20w:
+ 
+ 	/*
+@@ -1588,7 +1583,7 @@ itlb_miss_20:
+ 
+ #endif
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 
+ dbit_trap_20w:
+ 	space_adjust	spc,va,t0
+@@ -1797,7 +1792,7 @@ sys_fork_wrapper:
+ 
+ 	STREG	%r2,-RP_OFFSET(%r30)
+ 	ldo	FRAME_SIZE(%r30),%r30
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+ #endif
+ 
+@@ -1847,7 +1842,7 @@ sys_clone_wrapper:
+ 
+ 	STREG	%r2,-RP_OFFSET(%r30)
+ 	ldo	FRAME_SIZE(%r30),%r30
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+ #endif
+ 
+@@ -1869,7 +1864,7 @@ sys_vfork_wrapper:
+ 
+ 	STREG	%r2,-RP_OFFSET(%r30)
+ 	ldo	FRAME_SIZE(%r30),%r30
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+ #endif
+ 
+@@ -1897,10 +1892,10 @@ sys_vfork_wrapper:
+ 
+ 	STREG %r2,-RP_OFFSET(%r30)
+ 	ldo FRAME_SIZE(%r30),%r30
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+ #endif
+-	bl \execve,%r2
++	BL \execve,%r2
+ 	copy %r1,%arg0
+ 
+ 	ldo -FRAME_SIZE(%r30),%r30
+@@ -1923,7 +1918,7 @@ error_\execve:
+ sys_execve_wrapper:
+ 	execve_wrapper sys_execve
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	.export sys32_execve_wrapper
+ 	.import sys32_execve
+ 
+@@ -1937,7 +1932,7 @@ sys_rt_sigreturn_wrapper:
+ 	ldo	TASK_REGS(%r26),%r26	/* get pt regs */
+ 	/* Don't save regs, we are going to restore them from sigcontext. */
+ 	STREG	%r2, -RP_OFFSET(%r30)
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	FRAME_SIZE(%r30), %r30
+ 	BL	sys_rt_sigreturn,%r2
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+@@ -1968,7 +1963,7 @@ sys_sigaltstack_wrapper:
+ 	ldo	TASK_REGS(%r1),%r24	/* get pt regs */
+ 	LDREG	TASK_PT_GR30(%r24),%r24
+ 	STREG	%r2, -RP_OFFSET(%r30)
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	FRAME_SIZE(%r30), %r30
+ 	b,l	do_sigaltstack,%r2
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+@@ -1982,7 +1977,7 @@ sys_sigaltstack_wrapper:
+ 	bv	%r0(%r2)
+ 	nop
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	.export sys32_sigaltstack_wrapper
+ sys32_sigaltstack_wrapper:
+ 	/* Get the user stack pointer */
+@@ -2006,7 +2001,7 @@ sys_rt_sigsuspend_wrapper:
+ 	reg_save %r24
+ 
+ 	STREG	%r2, -RP_OFFSET(%r30)
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	FRAME_SIZE(%r30), %r30
+ 	b,l	sys_rt_sigsuspend,%r2
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+@@ -2079,7 +2074,7 @@ syscall_check_bh:
+ 	ldw     TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
+ 
+ 	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	shld	%r26, 6, %r20
+ #else
+ 	shlw	%r26, 5, %r20
+@@ -2087,9 +2082,6 @@ syscall_check_bh:
+ 	add     %r19,%r20,%r19	/* now have &irq_stat[smp_processor_id()] */
+ #endif /* CONFIG_SMP */
+ 
+-	LDREG   IRQSTAT_SIRQ_PEND(%r19),%r20    /* hardirq.h: unsigned long */
+-	cmpib,<>,n 0,%r20,syscall_do_softirq /* forward */
+-
+ syscall_check_resched:
+ 
+ 	/* check for reschedule */
+@@ -2144,7 +2136,7 @@ syscall_restore:
+ 
+ 	depi	3,31,2,%r31			   /* ensure return to user mode. */
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* decide whether to reset the wide mode bit
+ 	 *
+ 	 * For a syscall, the W bit is stored in the lowest bit
+@@ -2227,20 +2219,10 @@ pt_regs_ok:
+ 	b	intr_restore
+ 	nop
+ 
+-	.import do_softirq,code
+-syscall_do_softirq:
+-	bl      do_softirq,%r2
+-	nop
+-	/* NOTE: We enable I-bit incase we schedule later,
+-	 * and we might be going back to userspace if we were
+-	 * traced. */
+-	b       syscall_check_resched
+-	ssm     PSW_SM_I, %r0  /* do_softirq returns with I bit off */
+-
+ 	.import schedule,code
+ syscall_do_resched:
+ 	BL	schedule,%r2
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29		/* Reference param save area */
+ #else
+ 	nop
+@@ -2260,7 +2242,7 @@ syscall_do_signal:
+ 
+ 	ldi	1, %r24				/* unsigned long in_syscall */
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29			/* Reference param save area */
+ #endif
+ 	BL	do_signal,%r2
+diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
+--- a/arch/parisc/kernel/firmware.c
++++ b/arch/parisc/kernel/firmware.c
+@@ -83,15 +83,15 @@ static unsigned long pdc_result2[32] __a
+ int parisc_narrow_firmware = 1;
+ #endif
+ 
+-/* on all currently-supported platforms, IODC I/O calls are always
+- * 32-bit calls, and MEM_PDC calls are always the same width as the OS.
+- * This means Cxxx boxes can't run wide kernels right now. -PB
+- *
+- * CONFIG_PDC_NARROW has been added to allow 64-bit kernels to run on
+- * systems with 32-bit MEM_PDC calls. This will allow wide kernels to
+- * run on Cxxx boxes now. -RB
+- *
+- * Note that some PAT boxes may have 64-bit IODC I/O...
++/* On most currently-supported platforms, IODC I/O calls are 32-bit calls
++ * and MEM_PDC calls are always the same width as the OS.
++ * Some PAT boxes may have 64-bit IODC I/O.
++ *
++ * Ryan Bradetich added the now obsolete CONFIG_PDC_NARROW to allow
++ * 64-bit kernels to run on systems with 32-bit MEM_PDC calls.
++ * This allowed wide kernels to run on Cxxx boxes.
++ * We now detect 32-bit-only PDC and dynamically switch to 32-bit mode
++ * when running a 64-bit kernel on such boxes (e.g. C200 or C360).
+  */
+ 
+ #ifdef __LP64__
+diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
+--- a/arch/parisc/kernel/head.S
++++ b/arch/parisc/kernel/head.S
+@@ -12,7 +12,7 @@
+  * Initial Version 04-23-1999 by Helge Deller <deller at gmx.de>
+  */
+ 
+-#include <linux/autoconf.h>	/* for CONFIG_SMP */
++#include <linux/config.h>	/* for CONFIG_SMP */
+ 
+ #include <asm/asm-offsets.h>
+ #include <asm/psw.h>
+@@ -36,10 +36,10 @@ boot_args:
+ 	.align	4
+ 	.import init_thread_union,data
+ 	.import fault_vector_20,code    /* IVA parisc 2.0 32 bit */
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+         .import fault_vector_11,code    /* IVA parisc 1.1 32 bit */
+ 	.import	$global$		/* forward declaration */
+-#endif /*!LP64*/
++#endif /*!CONFIG_64BIT*/
+ 	.export stext
+ 	.export _stext,data		/* Kernel want it this way! */
+ _stext:
+@@ -76,7 +76,7 @@ $bss_loop:
+ 	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+ 	mtctl		%r4,%cr25	/* Initialize user root pointer */
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* Set pmd in pgd */
+ 	load32		PA(pmd0),%r5
+ 	shrd            %r5,PxD_VALUE_SHIFT,%r3	
+@@ -99,7 +99,7 @@ $bss_loop:
+ 	stw		%r3,0(%r4)
+ 	ldo		(ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
+ 	addib,>		-1,%r1,1b
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo             ASM_PMD_ENTRY_SIZE(%r4),%r4
+ #else
+ 	ldo             ASM_PGD_ENTRY_SIZE(%r4),%r4
+@@ -170,7 +170,7 @@ common_stext:
+ 	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
+ #endif /*CONFIG_SMP*/
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	tophys_r1	%sp
+ 
+ 	/* Save the rfi target address */
+@@ -224,8 +224,6 @@ stext_pdc_ret:
+ 	mtctl	%r0,%cr12
+ 	mtctl	%r0,%cr13
+ 
+-	/* Prepare to RFI! Man all the cannons! */
+-
+ 	/* Initialize the global data pointer */
+ 	loadgp
+ 
+@@ -235,7 +233,7 @@ stext_pdc_ret:
+ 	 * following short sequence of instructions can determine this
+ 	 * (without being illegal on a PA1.1 machine).
+ 	 */
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ 	ldi		32,%r10
+ 	mtctl		%r10,%cr11
+ 	.level 2.0
+@@ -248,52 +246,22 @@ stext_pdc_ret:
+ 
+ $is_pa20:
+ 	.level		LEVEL /* restore 1.1 || 2.0w */
+-#endif /*!LP64*/
++#endif /*!CONFIG_64BIT*/
+ 	load32		PA(fault_vector_20),%r10
+ 
+ $install_iva:
+ 	mtctl		%r10,%cr14
+ 
+-#ifdef __LP64__
+-	b		aligned_rfi
++	b		aligned_rfi  /* Prepare to RFI! Man all the cannons! */
+ 	nop
+ 
+-	.align          256
++	.align 128
+ aligned_rfi:
+-	ssm             0,0
+-	nop             /* 1 */
+-	nop             /* 2 */
+-	nop             /* 3 */
+-	nop             /* 4 */
+-	nop             /* 5 */
+-	nop             /* 6 */
+-	nop             /* 7 */
+-	nop             /* 8 */
+-#endif
+-
+-#ifdef __LP64__ /* move to psw.h? */
+-#define		PSW_BITS	PSW_Q+PSW_I+PSW_D+PSW_P+PSW_R
+-#else
+-#define		PSW_BITS	PSW_SM_Q
+-#endif
++	pcxt_ssm_bug
+ 
+-$rfi:	
+-	/* turn off troublesome PSW bits */
+-	rsm		PSW_BITS,%r0
+-
+-	/* kernel PSW:
+-	 *  - no interruptions except HPMC and TOC (which are handled by PDC)
+-	 *  - Q bit set (IODC / PDC interruptions)
+-	 *  - big-endian
+-	 *  - virtually mapped
+-	 */
+-	load32		KERNEL_PSW,%r10
+-	mtctl		%r10,%ipsw
++	rsm		PSW_SM_QUIET,%r0	/* off troublesome PSW bits */
++	/* Don't need NOPs, have 8 compliant insn before rfi */
+ 
+-	/* Set the space pointers for the post-RFI world
+-	** Clear the two-level IIA Space Queue, effectively setting
+-	** Kernel space.
+-	*/
+ 	mtctl		%r0,%cr17	/* Clear IIASQ tail */
+ 	mtctl		%r0,%cr17	/* Clear IIASQ head */
+ 
+@@ -301,8 +269,11 @@ $rfi:	
+ 	mtctl		%r11,%cr18	/* IIAOQ head */
+ 	ldo		4(%r11),%r11
+ 	mtctl		%r11,%cr18	/* IIAOQ tail */
++
++	load32		KERNEL_PSW,%r10
++	mtctl		%r10,%ipsw
+ 	
+-	/* Jump to hyperspace */
++	/* Jump through hyperspace to Virt Mode */
+ 	rfi
+ 	nop
+ 
+@@ -313,7 +284,7 @@ $rfi:	
+ 	.import smp_init_current_idle_task,data
+ 	.import	smp_callin,code
+ 
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ smp_callin_rtn:
+         .proc
+ 	.callinfo
+@@ -321,7 +292,7 @@ smp_callin_rtn:
+ 	nop
+ 	nop
+         .procend
+-#endif /*!LP64*/
++#endif /*!CONFIG_64BIT*/
+ 
+ /***************************************************************************
+ * smp_slave_stext is executed by all non-monarch Processors when the Monarch
+@@ -356,7 +327,7 @@ smp_slave_stext:
+ 	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+ 	mtctl		%r4,%cr25	/* Initialize user root pointer */
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* Setup PDCE_PROC entry */
+ 	copy            %arg0,%r3
+ #else
+@@ -373,7 +344,7 @@ smp_slave_stext:
+ 
+ 	.procend
+ #endif /* CONFIG_SMP */
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ 	.data
+ 
+ 	.align	4
+@@ -383,4 +354,4 @@ smp_slave_stext:
+ 	.size	$global$,4
+ $global$:	
+ 	.word 0
+-#endif /*!LP64*/
++#endif /*!CONFIG_64BIT*/
+diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
+--- a/arch/parisc/kernel/ioctl32.c
++++ b/arch/parisc/kernel/ioctl32.c
+@@ -104,12 +104,9 @@ static int drm32_version(unsigned int fd
+ 	}
+ 
+ out:
+-	if (kversion.name)
+-		kfree(kversion.name);
+-	if (kversion.date)
+-		kfree(kversion.date);
+-	if (kversion.desc)
+-		kfree(kversion.desc);
++	kfree(kversion.name);
++	kfree(kversion.date);
++	kfree(kversion.desc);
+ 	return ret;
+ }
+ 
+@@ -166,9 +163,7 @@ static int drm32_getsetunique(unsigned i
+ 			ret = -EFAULT;
+ 	}
+ 
+-	if (karg.unique != NULL)
+-		kfree(karg.unique);
+-
++	kfree(karg.unique);
+ 	return ret;
+ }
+ 
+@@ -265,7 +260,6 @@ static int drm32_info_bufs(unsigned int 
+ 	}
+ 
+ 	kfree(karg.list);
+-
+ 	return ret;
+ }
+ 
+@@ -305,7 +299,6 @@ static int drm32_free_bufs(unsigned int 
+ 
+ out:
+ 	kfree(karg.list);
+-
+ 	return ret;
+ }
+ 
+@@ -494,15 +487,10 @@ static int drm32_dma(unsigned int fd, un
+ 	}
+ 
+ out:
+-	if (karg.send_indices)
+-		kfree(karg.send_indices);
+-	if (karg.send_sizes)
+-		kfree(karg.send_sizes);
+-	if (karg.request_indices)
+-		kfree(karg.request_indices);
+-	if (karg.request_sizes)
+-		kfree(karg.request_sizes);
+-
++	kfree(karg.send_indices);
++	kfree(karg.send_sizes);
++	kfree(karg.request_indices);
++	kfree(karg.request_sizes);
+ 	return ret;
+ }
+ 
+@@ -555,9 +543,7 @@ static int drm32_res_ctx(unsigned int fd
+ 			ret = -EFAULT;
+ 	}
+ 
+-	if (karg.contexts)
+-		kfree(karg.contexts);
+-
++	kfree(karg.contexts);
+ 	return ret;
+ }
+ 
+@@ -575,11 +561,6 @@ IOCTL_TABLE_START
+ #define DECLARES
+ #include "compat_ioctl.c"
+ 
+-/* Might be moved to compat_ioctl.h with some ifdefs... */
+-COMPATIBLE_IOCTL(TIOCSTART)
+-COMPATIBLE_IOCTL(TIOCSTOP)
+-COMPATIBLE_IOCTL(TIOCSLTC)
+-
+ /* PA-specific ioctls */
+ COMPATIBLE_IOCTL(PA_PERF_ON)
+ COMPATIBLE_IOCTL(PA_PERF_OFF)
+diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
+--- a/arch/parisc/kernel/pacache.S
++++ b/arch/parisc/kernel/pacache.S
+@@ -26,7 +26,7 @@
+  *       can be used.
+  */
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ #define ADDIB	addib,*
+ #define CMPB	cmpb,*
+ #define ANDCM	andcm,*
+@@ -40,8 +40,10 @@
+ 	.level	2.0
+ #endif
+ 
+-#include <asm/assembly.h>
++#include <linux/config.h>
++
+ #include <asm/psw.h>
++#include <asm/assembly.h>
+ #include <asm/pgtable.h>
+ #include <asm/cache.h>
+ 
+@@ -62,32 +64,23 @@ flush_tlb_all_local:
+ 	 * to happen in real mode with all interruptions disabled.
+ 	 */
+ 
+-	/*
+-	 * Once again, we do the rfi dance ... some day we need examine
+-	 * all of our uses of this type of code and see what can be
+-	 * consolidated.
+-	 */
+-
+-	rsm		PSW_SM_I, %r19		/* relied upon translation! PA 2.0 Arch. F-5 */
++	/* pcxt_ssm_bug	- relied upon translation! PA 2.0 Arch. F-4 and F-5 */
++	rsm	PSW_SM_I, %r19		/* save I-bit state */
++	load32		PA(1f), %r1
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+-	nop
+-	nop
+-	
+-	rsm		PSW_SM_Q, %r0		/* Turn off Q bit to load iia queue */
+-	ldil		L%REAL_MODE_PSW, %r1
+-	ldo		R%REAL_MODE_PSW(%r1), %r1
+-	mtctl		%r1, %cr22
++
++	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
+ 	mtctl		%r0, %cr17		/* Clear IIASQ tail */
+ 	mtctl		%r0, %cr17		/* Clear IIASQ head */
+-	ldil		L%PA(1f), %r1
+-	ldo		R%PA(1f)(%r1), %r1
+ 	mtctl		%r1, %cr18		/* IIAOQ head */
+ 	ldo		4(%r1), %r1
+ 	mtctl		%r1, %cr18		/* IIAOQ tail */
++	load32		REAL_MODE_PSW, %r1
++	mtctl           %r1, %ipsw
+ 	rfi
+ 	nop
+ 
+@@ -178,29 +171,36 @@ fdtonemiddle:					/* Loop if LOOP = 1 */
+ 	ADDIB>		-1, %r22, fdtoneloop	/* Outer loop count decr */
+ 	add		%r21, %r20, %r20	/* increment space */
+ 
+-fdtdone:
+ 
+-	/* Switch back to virtual mode */
++fdtdone:
++	/*
++	 * Switch back to virtual mode
++	 */
++	/* pcxt_ssm_bug */
++	rsm		PSW_SM_I, %r0
++	load32		2f, %r1
++	nop
++	nop
++	nop
++	nop
++	nop
+ 
+-	rsm		PSW_SM_Q, %r0		/* clear Q bit to load iia queue */
+-	ldil		L%KERNEL_PSW, %r1
+-	ldo		R%KERNEL_PSW(%r1), %r1
+-	or		%r1, %r19, %r1		/* Set I bit if set on entry */
+-	mtctl		%r1, %cr22
++	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
+ 	mtctl		%r0, %cr17		/* Clear IIASQ tail */
+ 	mtctl		%r0, %cr17		/* Clear IIASQ head */
+-	ldil		L%(2f), %r1
+-	ldo		R%(2f)(%r1), %r1
+ 	mtctl		%r1, %cr18		/* IIAOQ head */
+ 	ldo		4(%r1), %r1
+ 	mtctl		%r1, %cr18		/* IIAOQ tail */
++	load32		KERNEL_PSW, %r1
++	or		%r1, %r19, %r1	/* I-bit to state on entry */
++	mtctl		%r1, %ipsw	/* restore I-bit (entire PSW) */
+ 	rfi
+ 	nop
+ 
+ 2:      bv		%r0(%r2)
+ 	nop
+-	.exit
+ 
++	.exit
+ 	.procend
+ 
+ 	.export flush_instruction_cache_local,code
+@@ -227,7 +227,7 @@ flush_instruction_cache_local:
+ 
+ fimanyloop:					/* Loop if LOOP >= 2 */
+ 	ADDIB>		-1, %r31, fimanyloop	/* Adjusted inner loop decr */
+-	fice            0(%sr1, %arg0)
++	fice            %r0(%sr1, %arg0)
+ 	fice,m		%arg1(%sr1, %arg0)	/* Last fice and addr adjust */
+ 	movb,tr		%arg3, %r31, fimanyloop	/* Re-init inner loop count */
+ 	ADDIB<=,n	-1, %arg2, fisync	/* Outer loop decr */
+@@ -238,7 +238,7 @@ fioneloop:					/* Loop if LOOP = 1 */
+ 
+ fisync:
+ 	sync
+-	mtsm		%r22
++	mtsm		%r22			/* restore I-bit */
+ 	bv		%r0(%r2)
+ 	nop
+ 	.exit
+@@ -269,7 +269,7 @@ flush_data_cache_local:
+ 
+ fdmanyloop:					/* Loop if LOOP >= 2 */
+ 	ADDIB>		-1, %r31, fdmanyloop	/* Adjusted inner loop decr */
+-	fdce		0(%sr1, %arg0)
++	fdce		%r0(%sr1, %arg0)
+ 	fdce,m		%arg1(%sr1, %arg0)	/* Last fdce and addr adjust */
+ 	movb,tr		%arg3, %r31, fdmanyloop	/* Re-init inner loop count */
+ 	ADDIB<=,n	-1, %arg2, fdsync	/* Outer loop decr */
+@@ -281,7 +281,7 @@ fdoneloop:					/* Loop if LOOP = 1 */
+ fdsync:
+ 	syncdma
+ 	sync
+-	mtsm		%r22
++	mtsm		%r22			/* restore I-bit */
+ 	bv		%r0(%r2)
+ 	nop
+ 	.exit
+@@ -296,7 +296,7 @@ copy_user_page_asm:
+ 	.callinfo NO_CALLS
+ 	.entry
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
+ 	 * Unroll the loop by hand and arrange insn appropriately.
+ 	 * GCC probably can do this just as well.
+@@ -351,7 +351,11 @@ copy_user_page_asm:
+ 	std		%r22, 120(%r26)
+ 	ldo		128(%r26), %r26
+ 
+-	ADDIB>		-1, %r1, 1b		/* bundle 10 */
++	/* conditional branches nullify on forward taken branch, and on
++	 * non-taken backward branch. Note that .+4 is a backwards branch.
++	 * The ldd should only get executed if the branch is taken.
++	 */
++	ADDIB>,n	-1, %r1, 1b		/* bundle 10 */
+ 	ldd		0(%r25), %r19		/* start next loads */
+ 
+ #else
+@@ -363,10 +367,10 @@ copy_user_page_asm:
+ 	 * the full 64 bit register values on interrupt, we can't
+ 	 * use ldd/std on a 32 bit kernel.
+ 	 */
++	ldw		0(%r25), %r19
+ 	ldi		64, %r1		/* PAGE_SIZE/64 == 64 */
+ 
+ 1:
+-	ldw		0(%r25), %r19
+ 	ldw		4(%r25), %r20
+ 	ldw		8(%r25), %r21
+ 	ldw		12(%r25), %r22
+@@ -396,11 +400,12 @@ copy_user_page_asm:
+ 	ldw		60(%r25), %r22
+ 	stw		%r19, 48(%r26)
+ 	stw		%r20, 52(%r26)
++	ldo		64(%r25), %r25
+ 	stw		%r21, 56(%r26)
+ 	stw		%r22, 60(%r26)
+ 	ldo		64(%r26), %r26
+-	ADDIB>		-1, %r1, 1b
+-	ldo		64(%r25), %r25
++	ADDIB>,n	-1, %r1, 1b
++	ldw		0(%r25), %r19
+ #endif
+ 	bv		%r0(%r2)
+ 	nop
+@@ -456,7 +461,7 @@ copy_user_page_asm:
+ 	sub		%r25, %r1, %r23		/* move physical addr into non shadowed reg */
+ 
+ 	ldil		L%(TMPALIAS_MAP_START), %r28
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	extrd,u		%r26,56,32, %r26		/* convert phys addr to tlb insert format */
+ 	extrd,u		%r23,56,32, %r23		/* convert phys addr to tlb insert format */
+ 	depd		%r24,63,22, %r28		/* Form aliased virtual address 'to' */
+@@ -543,7 +548,7 @@ __clear_user_page_asm:
+ 	tophys_r1	%r26
+ 
+ 	ldil		L%(TMPALIAS_MAP_START), %r28
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ #if (TMPALIAS_MAP_START >= 0x80000000)
+ 	depdi		0, 31,32, %r28		/* clear any sign extension */
+ #endif
+@@ -560,7 +565,7 @@ __clear_user_page_asm:
+ 
+ 	pdtlb		0(%r28)
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldi		32, %r1			/* PAGE_SIZE/128 == 32 */
+ 
+ 	/* PREFETCH (Write) has not (yet) been proven to help here */
+@@ -585,7 +590,7 @@ __clear_user_page_asm:
+ 	ADDIB>		-1, %r1, 1b
+ 	ldo		128(%r28), %r28
+ 
+-#else	/* ! __LP64 */
++#else	/* ! CONFIG_64BIT */
+ 
+ 	ldi		64, %r1			/* PAGE_SIZE/64 == 64 */
+ 
+@@ -608,7 +613,7 @@ __clear_user_page_asm:
+ 	stw		%r0, 60(%r28)
+ 	ADDIB>		-1, %r1, 1b
+ 	ldo		64(%r28), %r28
+-#endif	/* __LP64 */
++#endif	/* CONFIG_64BIT */
+ 
+ 	bv		%r0(%r2)
+ 	nop
+@@ -626,7 +631,7 @@ flush_kernel_dcache_page:
+ 	ldil		L%dcache_stride, %r1
+ 	ldw		R%dcache_stride(%r1), %r23
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	depdi,z		1, 63-PAGE_SHIFT,1, %r25
+ #else
+ 	depwi,z		1, 31-PAGE_SHIFT,1, %r25
+@@ -670,7 +675,7 @@ flush_user_dcache_page:
+ 	ldil		L%dcache_stride, %r1
+ 	ldw		R%dcache_stride(%r1), %r23
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	depdi,z		1,63-PAGE_SHIFT,1, %r25
+ #else
+ 	depwi,z		1,31-PAGE_SHIFT,1, %r25
+@@ -714,7 +719,7 @@ flush_user_icache_page:
+ 	ldil		L%dcache_stride, %r1
+ 	ldw		R%dcache_stride(%r1), %r23
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	depdi,z		1, 63-PAGE_SHIFT,1, %r25
+ #else
+ 	depwi,z		1, 31-PAGE_SHIFT,1, %r25
+@@ -759,7 +764,7 @@ purge_kernel_dcache_page:
+ 	ldil		L%dcache_stride, %r1
+ 	ldw		R%dcache_stride(%r1), %r23
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	depdi,z		1, 63-PAGE_SHIFT,1, %r25
+ #else
+ 	depwi,z		1, 31-PAGE_SHIFT,1, %r25
+@@ -807,7 +812,7 @@ flush_alias_page:
+ 	tophys_r1		%r26
+ 
+ 	ldil		L%(TMPALIAS_MAP_START), %r28
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	extrd,u		%r26, 56,32, %r26	/* convert phys addr to tlb insert format */
+ 	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
+ 	depdi		0, 63,12, %r28		/* Clear any offset bits */
+@@ -824,7 +829,7 @@ flush_alias_page:
+ 	ldil		L%dcache_stride, %r1
+ 	ldw		R%dcache_stride(%r1), %r23
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	depdi,z		1, 63-PAGE_SHIFT,1, %r29
+ #else
+ 	depwi,z		1, 31-PAGE_SHIFT,1, %r29
+@@ -935,7 +940,7 @@ flush_kernel_icache_page:
+ 	ldil		L%icache_stride, %r1
+ 	ldw		R%icache_stride(%r1), %r23
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	depdi,z		1, 63-PAGE_SHIFT,1, %r25
+ #else
+ 	depwi,z		1, 31-PAGE_SHIFT,1, %r25
+@@ -944,23 +949,23 @@ flush_kernel_icache_page:
+ 	sub		%r25, %r23, %r25
+ 
+ 
+-1:      fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
+-	fic,m		%r23(%r26)
++1:      fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
++	fic,m		%r23(%sr4, %r26)
+ 	CMPB<<		%r26, %r25, 1b
+-	fic,m		%r23(%r26)
++	fic,m		%r23(%sr4, %r26)
+ 
+ 	sync
+ 	bv		%r0(%r2)
+@@ -982,17 +987,18 @@ flush_kernel_icache_range_asm:
+ 	ANDCM		%r26, %r21, %r26
+ 
+ 1:      CMPB<<,n	%r26, %r25, 1b
+-	fic,m		%r23(%r26)
++	fic,m		%r23(%sr4, %r26)
+ 
+ 	sync
+ 	bv		%r0(%r2)
+ 	nop
+ 	.exit
+-
+ 	.procend
+ 
+-	.align	128
+-
++	/* align should cover use of rfi in disable_sr_hashing_asm and
++	 * srdis_done.
++	 */
++	.align	256
+ 	.export disable_sr_hashing_asm,code
+ 
+ disable_sr_hashing_asm:
+@@ -1000,28 +1006,26 @@ disable_sr_hashing_asm:
+ 	.callinfo NO_CALLS
+ 	.entry
+ 
+-	/* Switch to real mode */
+-
+-	ssm		0, %r0			/* relied upon translation! */
+-	nop
+-	nop
++	/*
++	 * Switch to real mode
++	 */
++	/* pcxt_ssm_bug */
++	rsm		PSW_SM_I, %r0
++	load32		PA(1f), %r1
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+-	
+-	rsm		(PSW_SM_Q|PSW_SM_I), %r0 /* disable Q&I to load the iia queue */
+-	ldil		L%REAL_MODE_PSW, %r1
+-	ldo		R%REAL_MODE_PSW(%r1), %r1
+-	mtctl		%r1, %cr22
++
++	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
+ 	mtctl		%r0, %cr17		/* Clear IIASQ tail */
+ 	mtctl		%r0, %cr17		/* Clear IIASQ head */
+-	ldil		L%PA(1f), %r1
+-	ldo		R%PA(1f)(%r1), %r1
+ 	mtctl		%r1, %cr18		/* IIAOQ head */
+ 	ldo		4(%r1), %r1
+ 	mtctl		%r1, %cr18		/* IIAOQ tail */
++	load32		REAL_MODE_PSW, %r1
++	mtctl		%r1, %ipsw
+ 	rfi
+ 	nop
+ 
+@@ -1053,27 +1057,31 @@ srdis_pcxl:
+ 
+ srdis_pa20:
+ 
+-	/* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+ */
++	/* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */
+ 
+ 	.word		0x144008bc		/* mfdiag %dr2, %r28 */
+ 	depdi		0, 54,1, %r28		/* clear DIAG_SPHASH_ENAB (bit 54) */
+ 	.word		0x145c1840		/* mtdiag %r28, %dr2 */
+ 
+-srdis_done:
+ 
++srdis_done:
+ 	/* Switch back to virtual mode */
++	rsm		PSW_SM_I, %r0		/* prep to load iia queue */
++	load32 	   	2f, %r1
++	nop
++	nop
++	nop
++	nop
++	nop
+ 
+-	rsm		PSW_SM_Q, %r0		/* clear Q bit to load iia queue */
+-	ldil		L%KERNEL_PSW, %r1
+-	ldo		R%KERNEL_PSW(%r1), %r1
+-	mtctl		%r1, %cr22
++	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
+ 	mtctl		%r0, %cr17		/* Clear IIASQ tail */
+ 	mtctl		%r0, %cr17		/* Clear IIASQ head */
+-	ldil 	   	L%(2f), %r1
+-	ldo     	R%(2f)(%r1), %r1
+ 	mtctl		%r1, %cr18		/* IIAOQ head */
+ 	ldo		4(%r1), %r1
+ 	mtctl		%r1, %cr18		/* IIAOQ tail */
++	load32		KERNEL_PSW, %r1
++	mtctl		%r1, %ipsw
+ 	rfi
+ 	nop
+ 
+diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
+--- a/arch/parisc/kernel/pci-dma.c
++++ b/arch/parisc/kernel/pci-dma.c
+@@ -31,7 +31,7 @@
+ #include <asm/page.h>	/* get_order */
+ #include <asm/pgalloc.h>
+ #include <asm/uaccess.h>
+-
++#include <asm/tlbflush.h>	/* for purge_tlb_*() macros */
+ 
+ static struct proc_dir_entry * proc_gsc_root = NULL;
+ static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length);
+@@ -114,7 +114,7 @@ static inline int map_pmd_uncached(pmd_t
+ 	if (end > PGDIR_SIZE)
+ 		end = PGDIR_SIZE;
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, vaddr);
++		pte_t * pte = pte_alloc_kernel(pmd, vaddr);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		if (map_pte_uncached(pte, orig_vaddr, end - vaddr, paddr_ptr))
+@@ -333,23 +333,33 @@ pcxl_free_range(unsigned long vaddr, siz
+ static int __init
+ pcxl_dma_init(void)
+ {
+-    if (pcxl_dma_start == 0)
+-	return 0;
++	if (pcxl_dma_start == 0)
++		return 0;
+ 
+-    spin_lock_init(&pcxl_res_lock);
+-    pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3);
+-    pcxl_res_hint = 0;
+-    pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
++	spin_lock_init(&pcxl_res_lock);
++	pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3);
++	pcxl_res_hint = 0;
++	pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
+ 					    get_order(pcxl_res_size));
+-    memset(pcxl_res_map, 0, pcxl_res_size);
+-    proc_gsc_root = proc_mkdir("gsc", 0);
+-    create_proc_info_entry("dino", 0, proc_gsc_root, pcxl_proc_info);
+-    return 0;
++	memset(pcxl_res_map, 0, pcxl_res_size);
++	proc_gsc_root = proc_mkdir("gsc", 0);
++	if (!proc_gsc_root)
++    		printk(KERN_WARNING
++			"pcxl_dma_init: Unable to create gsc /proc dir entry\n");
++	else {
++		struct proc_dir_entry* ent;
++		ent = create_proc_info_entry("pcxl_dma", 0,
++				proc_gsc_root, pcxl_proc_info);
++		if (!ent)
++			printk(KERN_WARNING
++				"pci-dma.c: Unable to create pcxl_dma /proc entry.\n");
++	}
++	return 0;
+ }
+ 
+ __initcall(pcxl_dma_init);
+ 
+-static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
++static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
+ {
+ 	unsigned long vaddr;
+ 	unsigned long paddr;
+@@ -502,13 +512,13 @@ struct hppa_dma_ops pcxl_dma_ops = {
+ };
+ 
+ static void *fail_alloc_consistent(struct device *dev, size_t size,
+-				   dma_addr_t *dma_handle, int flag)
++				   dma_addr_t *dma_handle, gfp_t flag)
+ {
+ 	return NULL;
+ }
+ 
+ static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
+-					  dma_addr_t *dma_handle, int flag)
++					  dma_addr_t *dma_handle, gfp_t flag)
+ {
+ 	void *addr = NULL;
+ 
+@@ -545,16 +555,16 @@ struct hppa_dma_ops pcx_dma_ops = {
+ 
+ static int pcxl_proc_info(char *buf, char **start, off_t offset, int len)
+ {
++#if 0
+ 	u_long i = 0;
+ 	unsigned long *res_ptr = (u_long *)pcxl_res_map;
+-	unsigned long total_pages = pcxl_res_size << 3;        /* 8 bits per byte */
++#endif
++	unsigned long total_pages = pcxl_res_size << 3;   /* 8 bits per byte */
+ 
+-	sprintf(buf, "\nDMA Mapping Area size    : %d bytes (%d pages)\n",
+-		PCXL_DMA_MAP_SIZE,
+-		(pcxl_res_size << 3) ); /* 1 bit per page */
++	sprintf(buf, "\nDMA Mapping Area size    : %d bytes (%ld pages)\n",
++		PCXL_DMA_MAP_SIZE, total_pages);
+ 	
+-	sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
+-		buf, pcxl_res_size, pcxl_res_size << 3);   /* 8 bits per byte */
++	sprintf(buf, "%sResource bitmap : %d bytes\n", buf, pcxl_res_size);
+ 
+ 	strcat(buf,  "     	  total:    free:    used:   % used:\n");
+ 	sprintf(buf, "%sblocks  %8d %8ld %8ld %8ld%%\n", buf, pcxl_res_size,
+@@ -564,7 +574,8 @@ static int pcxl_proc_info(char *buf, cha
+ 	sprintf(buf, "%spages   %8ld %8ld %8ld %8ld%%\n", buf, total_pages,
+ 		total_pages - pcxl_used_pages, pcxl_used_pages,
+ 		(pcxl_used_pages * 100 / total_pages));
+-	
++
++#if 0
+ 	strcat(buf, "\nResource bitmap:");
+ 
+ 	for(; i < (pcxl_res_size / sizeof(u_long)); ++i, ++res_ptr) {
+@@ -572,6 +583,7 @@ static int pcxl_proc_info(char *buf, cha
+ 		    strcat(buf,"\n   ");
+ 		sprintf(buf, "%s %08lx", buf, *res_ptr);
+ 	}
++#endif
+ 	strcat(buf, "\n");
+ 	return strlen(buf);
+ }
+diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
+--- a/arch/parisc/kernel/pci.c
++++ b/arch/parisc/kernel/pci.c
+@@ -202,7 +202,8 @@ static void
+ pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
+ {
+ 	if (!r->parent) {
+-		printk(KERN_EMERG "PCI: Tell willy he's wrong\n");
++		printk(KERN_EMERG "PCI: resource not parented! [%lx-%lx]\n",
++				r->start, r->end);
+ 		r->parent = hba_res;
+ 
+ 		/* reverse link is harder *sigh*  */
+diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
+--- a/arch/parisc/kernel/pdc_cons.c
++++ b/arch/parisc/kernel/pdc_cons.c
+@@ -41,7 +41,7 @@
+ 
+ /* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems. 
+  * On production kernels EARLY_BOOTUP_DEBUG should be undefined. */
+-#undef EARLY_BOOTUP_DEBUG
++#define EARLY_BOOTUP_DEBUG
+ 
+ 
+ #include <linux/config.h>
+@@ -49,14 +49,8 @@
+ #include <linux/console.h>
+ #include <linux/string.h>
+ #include <linux/init.h>
+-#include <linux/delay.h>
+-#include <linux/sched.h>
+-#include <linux/interrupt.h>
+ #include <linux/major.h>
+ #include <linux/tty.h>
+-#include <asm/page.h>
+-#include <asm/types.h>
+-#include <asm/system.h>
+ #include <asm/pdc.h>		/* for iodc_call() proto and friends */
+ 
+ 
+@@ -96,7 +90,6 @@ static int pdc_console_setup(struct cons
+ }
+ 
+ #if defined(CONFIG_PDC_CONSOLE)
+-#define PDC_CONSOLE_DEVICE pdc_console_device
+ static struct tty_driver * pdc_console_device (struct console *c, int *index)
+ {
+ 	extern struct tty_driver console_driver;
+@@ -104,22 +97,19 @@ static struct tty_driver * pdc_console_d
+ 	return &console_driver;
+ }
+ #else
+-#define PDC_CONSOLE_DEVICE NULL
++#define pdc_console_device NULL
+ #endif
+ 
+ static struct console pdc_cons = {
+ 	.name =		"ttyB",
+ 	.write =	pdc_console_write,
+-	.device =	PDC_CONSOLE_DEVICE,
++	.device =	pdc_console_device,
+ 	.setup =	pdc_console_setup,
+-	.flags =	CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
++	.flags =	CON_BOOT | CON_PRINTBUFFER | CON_ENABLED,
+ 	.index =	-1,
+ };
+ 
+ static int pdc_console_initialized;
+-extern unsigned long con_start;	/* kernel/printk.c */
+-extern unsigned long log_end;	/* kernel/printk.c */
+-
+ 
+ static void pdc_console_init_force(void)
+ {
+@@ -146,27 +136,11 @@ void __init pdc_console_init(void)
+ }
+ 
+ 
+-/* Unregister the pdc console with the printk console layer */
+-void pdc_console_die(void)
+-{
+-	if (!pdc_console_initialized)
+-		return;
+-	--pdc_console_initialized;
+-
+-	printk(KERN_INFO "Switching from PDC console\n");
+-
+-	/* Don't repeat what we've already printed */
+-	con_start = log_end;
+-
+-	unregister_console(&pdc_cons);
+-}
+-
+-
+ /*
+  * Used for emergencies. Currently only used if an HPMC occurs. If an
+  * HPMC occurs, it is possible that the current console may not be
+- * properly initialed after the PDC IO reset. This routine unregisters all
+- * of the current consoles, reinitializes the pdc console and
++ * properly initialised after the PDC IO reset. This routine unregisters
++ * all of the current consoles, reinitializes the pdc console and
+  * registers it.
+  */
+ 
+@@ -177,13 +151,13 @@ void pdc_console_restart(void)
+ 	if (pdc_console_initialized)
+ 		return;
+ 
++	/* If we've already seen the output, don't bother to print it again */
++	if (console_drivers != NULL)
++		pdc_cons.flags &= ~CON_PRINTBUFFER;
++
+ 	while ((console = console_drivers) != NULL)
+ 		unregister_console(console_drivers);
+ 
+-	/* Don't repeat what we've already printed */
+-	con_start = log_end;
+-	
+ 	/* force registering the pdc console */
+ 	pdc_console_init_force();
+ }
+-
+diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
+--- a/arch/parisc/kernel/perf.c
++++ b/arch/parisc/kernel/perf.c
+@@ -746,7 +746,8 @@ static int perf_write_image(uint64_t *me
+ 	uint64_t *bptr;
+ 	uint32_t dwords;
+ 	uint32_t *intrigue_rdr;
+-	uint64_t *intrigue_bitmask, tmp64, proc_hpa;
++	uint64_t *intrigue_bitmask, tmp64;
++	void __iomem *runway;
+ 	struct rdr_tbl_ent *tentry;
+ 	int i;
+ 
+@@ -798,15 +799,16 @@ static int perf_write_image(uint64_t *me
+ 		return -1;
+ 	}
+ 
+-	proc_hpa = cpu_device->hpa;
++	runway = ioremap(cpu_device->hpa.start, 4096);
+ 
+ 	/* Merge intrigue bits into Runway STATUS 0 */
+-	tmp64 = __raw_readq(proc_hpa + RUNWAY_STATUS) & 0xffecfffffffffffful;
+-	__raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), proc_hpa + RUNWAY_STATUS);
++	tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful;
++	__raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), 
++		     runway + RUNWAY_STATUS);
+ 	
+ 	/* Write RUNWAY DEBUG registers */
+ 	for (i = 0; i < 8; i++) {
+-		__raw_writeq(*memaddr++, proc_hpa + RUNWAY_DEBUG + i);
++		__raw_writeq(*memaddr++, runway + RUNWAY_DEBUG);
+ 	}
+ 
+ 	return 0; 
+diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
+--- a/arch/parisc/kernel/process.c
++++ b/arch/parisc/kernel/process.c
+@@ -9,7 +9,7 @@
+  *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+  *    Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
+  *    Copyright (C) 2000 David Kennedy <dkennedy with linuxcare.com>
+- *    Copyright (C) 2000 Richard Hirst <rhirst with parisc-lixux.org>
++ *    Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org>
+  *    Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
+  *    Copyright (C) 2001 Alan Modra <amodra at parisc-linux.org>
+  *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
+@@ -245,7 +245,17 @@ int
+ sys_clone(unsigned long clone_flags, unsigned long usp,
+ 	  struct pt_regs *regs)
+ {
+-	int __user *user_tid = (int __user *)regs->gr[26];
++  	/* Arugments from userspace are:
++	   r26 = Clone flags.
++	   r25 = Child stack.
++	   r24 = parent_tidptr.
++	   r23 = Is the TLS storage descriptor 
++	   r22 = child_tidptr 
++	   
++	   However, these last 3 args are only examined
++	   if the proper flags are set. */
++	int __user *child_tidptr;
++	int __user *parent_tidptr;
+ 
+ 	/* usp must be word aligned.  This also prevents users from
+ 	 * passing in the value 1 (which is the signal for a special
+@@ -253,10 +263,20 @@ sys_clone(unsigned long clone_flags, uns
+ 	usp = ALIGN(usp, 4);
+ 
+ 	/* A zero value for usp means use the current stack */
+-	if(usp == 0)
+-		usp = regs->gr[30];
++	if (usp == 0)
++	  usp = regs->gr[30];
+ 
+-	return do_fork(clone_flags, usp, regs, 0, user_tid, NULL);
++	if (clone_flags & CLONE_PARENT_SETTID)
++	  parent_tidptr = (int __user *)regs->gr[24];
++	else
++	  parent_tidptr = NULL;
++	
++	if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID))
++	  child_tidptr = (int __user *)regs->gr[22];
++	else
++	  child_tidptr = NULL;
++
++	return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr);
+ }
+ 
+ int
+@@ -332,6 +352,10 @@ copy_thread(int nr, unsigned long clone_
+ 		} else {
+ 			cregs->kpc = (unsigned long) &child_return;
+ 		}
++		/* Setup thread TLS area from the 4th parameter in clone */
++		if (clone_flags & CLONE_SETTLS)
++		  cregs->cr27 = pregs->gr[23];
++	
+ 	}
+ 
+ 	return 0;
+diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
+--- a/arch/parisc/kernel/processor.c
++++ b/arch/parisc/kernel/processor.c
+@@ -92,7 +92,7 @@ static int __init processor_probe(struct
+ 	 * May get overwritten by PAT code.
+ 	 */
+ 	cpuid = boot_cpu_data.cpu_count;
+-	txn_addr = dev->hpa;	/* for legacy PDC */
++	txn_addr = dev->hpa.start;	/* for legacy PDC */
+ 
+ #ifdef __LP64__
+ 	if (is_pdc_pat()) {
+@@ -122,7 +122,7 @@ static int __init processor_probe(struct
+  * boot time (ie shutdown a CPU from an OS perspective).
+  */
+ 		/* get the cpu number */
+-		status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa);
++		status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa.start);
+ 
+ 		BUG_ON(PDC_OK != status);
+ 
+@@ -130,7 +130,7 @@ static int __init processor_probe(struct
+ 			printk(KERN_WARNING "IGNORING CPU at 0x%x,"
+ 				" cpu_slot_id > NR_CPUS"
+ 				" (%ld > %d)\n",
+-				dev->hpa, cpu_info.cpu_num, NR_CPUS);
++				dev->hpa.start, cpu_info.cpu_num, NR_CPUS);
+ 			/* Ignore CPU since it will only crash */
+ 			boot_cpu_data.cpu_count--;
+ 			return 1;
+@@ -149,7 +149,7 @@ static int __init processor_probe(struct
+ 
+ 	p->loops_per_jiffy = loops_per_jiffy;
+ 	p->dev = dev;		/* Save IODC data in case we need it */
+-	p->hpa = dev->hpa;	/* save CPU hpa */
++	p->hpa = dev->hpa.start;	/* save CPU hpa */
+ 	p->cpuid = cpuid;	/* save CPU id */
+ 	p->txn_addr = txn_addr;	/* save CPU IRQ address */
+ #ifdef CONFIG_SMP
+diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
+--- a/arch/parisc/kernel/ptrace.c
++++ b/arch/parisc/kernel/ptrace.c
+@@ -78,7 +78,7 @@ void ptrace_disable(struct task_struct *
+ 	pa_psw(child)->l = 0;
+ }
+ 
+-long sys_ptrace(long request, pid_t pid, long addr, long data)
++long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	long ret;
+diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S
+--- a/arch/parisc/kernel/real2.S
++++ b/arch/parisc/kernel/real2.S
+@@ -7,8 +7,10 @@
+  * Copyright (C) 2000 Hewlett Packard (Paul Bame bame at puffin.external.hp.com)
+  *
+  */
+-#include <asm/assembly.h>
++#include <linux/config.h>
++
+ #include <asm/psw.h>
++#include <asm/assembly.h>
+ 
+ 	.section	.bss
+ 	.export real_stack
+@@ -20,7 +22,7 @@ real32_stack:
+ real64_stack:
+ 	.block	8192
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ #  define REG_SZ 8
+ #else
+ #  define REG_SZ 4
+@@ -50,7 +52,7 @@ save_cr_end:
+ 
+ real32_call_asm:
+ 	STREG	%rp, -RP_OFFSET(%sp)	/* save RP */
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	callee_save
+ 	ldo	2*REG_SZ(%sp), %sp	/* room for a couple more saves */
+ 	STREG	%r27, -1*REG_SZ(%sp)
+@@ -77,7 +79,7 @@ real32_call_asm:
+ 	b,l	save_control_regs,%r2		/* modifies r1, r2, r28 */
+ 	nop
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	rsm	PSW_SM_W, %r0		/* go narrow */
+ #endif
+ 
+@@ -85,7 +87,7 @@ real32_call_asm:
+ 	bv	0(%r31)
+ 	nop
+ ric_ret:
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ssm	PSW_SM_W, %r0		/* go wide */
+ #endif
+ 	/* restore CRs before going virtual in case we page fault */
+@@ -97,7 +99,7 @@ ric_ret:
+ 
+ 	tovirt_r1 %sp
+ 	LDREG	-REG_SZ(%sp), %sp	/* restore SP */
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	LDREG	-1*REG_SZ(%sp), %r27
+ 	LDREG	-2*REG_SZ(%sp), %r29
+ 	ldo	-2*REG_SZ(%sp), %sp
+@@ -143,24 +145,21 @@ restore_control_regs:
+ /* rfi_virt2real() and rfi_real2virt() could perhaps be adapted for
+  * more general-purpose use by the several places which need RFIs
+  */
+-	.align 128
+ 	.text
++	.align 128
+ rfi_virt2real:
+ 	/* switch to real mode... */
+-	ssm		0,0		/* See "relied upon translation" */
+-	nop				/* PA 2.0 Arch. F-5 */
+-	nop
+-	nop
++	rsm		PSW_SM_I,%r0
++	load32		PA(rfi_v2r_1), %r1
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	
+-	rsm             (PSW_SM_Q|PSW_SM_I),%r0  /* disable Q & I bits to load iia queue */
++	rsm             PSW_SM_Q,%r0  /* disable Q & I bits to load iia queue */
+ 	mtctl		%r0, %cr17	/* Clear IIASQ tail */
+ 	mtctl		%r0, %cr17	/* Clear IIASQ head */
+-	load32		PA(rfi_v2r_1), %r1
+ 	mtctl		%r1, %cr18	/* IIAOQ head */
+ 	ldo		4(%r1), %r1
+ 	mtctl		%r1, %cr18	/* IIAOQ tail */
+@@ -184,10 +183,8 @@ rfi_v2r_1:
+ 	.text
+ 	.align 128
+ rfi_real2virt:
+-	ssm		0,0		/* See "relied upon translation" */
+-	nop				/* PA 2.0 Arch. F-5 */
+-	nop
+-	nop
++	rsm		PSW_SM_I,%r0
++	load32		(rfi_r2v_1), %r1
+ 	nop
+ 	nop
+ 	nop
+@@ -197,7 +194,6 @@ rfi_real2virt:
+ 	rsm             PSW_SM_Q,%r0    /* disable Q bit to load iia queue */
+ 	mtctl		%r0, %cr17	/* Clear IIASQ tail */
+ 	mtctl		%r0, %cr17	/* Clear IIASQ head */
+-	load32		(rfi_r2v_1), %r1
+ 	mtctl		%r1, %cr18	/* IIAOQ head */
+ 	ldo		4(%r1), %r1
+ 	mtctl		%r1, %cr18	/* IIAOQ tail */
+@@ -218,7 +214,7 @@ rfi_r2v_1:
+ 	bv	0(%r2)
+ 	nop
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 
+ /************************ 64-bit real-mode calls ***********************/
+ /* This is only usable in wide kernels right now and will probably stay so */
+@@ -296,7 +292,7 @@ pc_in_user_space:
+ 	**	comparing function pointers.
+ 	*/
+ __canonicalize_funcptr_for_compare:
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	bve (%r2)
+ #else
+ 	bv %r0(%r2)
+diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
+--- a/arch/parisc/kernel/signal.c
++++ b/arch/parisc/kernel/signal.c
+@@ -490,15 +490,7 @@ setup_rt_frame(int sig, struct k_sigacti
+ 
+ give_sigsegv:
+ 	DBG(1,"setup_rt_frame: sending SIGSEGV\n");
+-	if (sig == SIGSEGV)
+-		ka->sa.sa_handler = SIG_DFL;
+-	si.si_signo = SIGSEGV;
+-	si.si_errno = 0;
+-	si.si_code = SI_KERNEL;
+-	si.si_pid = current->pid;
+-	si.si_uid = current->uid;
+-	si.si_addr = frame;
+-	force_sig_info(SIGSEGV, &si, current);
++	force_sigsegv(sig, current);
+ 	return 0;
+ }
+ 
+@@ -633,10 +625,14 @@ do_signal(sigset_t *oldset, struct pt_re
+ 			put_user(0xe0008200, &usp[3]);
+ 			put_user(0x34140000, &usp[4]);
+ 
+-			/* Stack is 64-byte aligned, and we only 
+-			 * need to flush 1 cache line */
+-			asm("fdc 0(%%sr3, %0)\n"
+-			    "fic 0(%%sr3, %0)\n"
++			/* Stack is 64-byte aligned, and we only need
++			 * to flush 1 cache line.
++			 * Flushing one cacheline is cheap.
++			 * "sync" on bigger (> 4 way) boxes is not.
++			 */
++			asm("fdc %%r0(%%sr3, %0)\n"
++			    "sync\n"
++			    "fic %%r0(%%sr3, %0)\n"
+ 			    "sync\n"
+ 			    : : "r"(regs->gr[30]));
+ 
+diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
+--- a/arch/parisc/kernel/smp.c
++++ b/arch/parisc/kernel/smp.c
+@@ -18,7 +18,7 @@
+ */
+ #undef ENTRY_SYS_CPUS	/* syscall support for iCOD-like functionality */
+ 
+-#include <linux/autoconf.h>
++#include <linux/config.h>
+ 
+ #include <linux/types.h>
+ #include <linux/spinlock.h>
+diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
+--- a/arch/parisc/kernel/syscall.S
++++ b/arch/parisc/kernel/syscall.S
+@@ -6,6 +6,7 @@
+  * thanks to Philipp Rumpf, Mike Shaver and various others
+  * sorry about the wall, puffin..
+  */
++#include <linux/config.h> /* for CONFIG_SMP */
+ 
+ #include <asm/asm-offsets.h>
+ #include <asm/unistd.h>
+@@ -22,15 +23,13 @@
+ 	 */
+ #define KILL_INSN	break	0,0
+ 
+-#include <linux/config.h> /* for CONFIG_SMP */
+-
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	.level          2.0w
+ #else
+ 	.level		1.1
+ #endif
+ 
+-#ifndef __LP64__
++#ifndef CONFIG_64BIT
+ 	.macro fixup_branch,lbl
+ 	b	    \lbl
+ 	.endm
+@@ -103,7 +102,7 @@ linux_gateway_entry:
+ 	mfsp    %sr7,%r1                        /* save user sr7 */
+ 	mtsp    %r1,%sr3                        /* and store it in sr3 */
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* for now we can *always* set the W bit on entry to the syscall
+ 	 * since we don't support wide userland processes.  We could
+ 	 * also save the current SM other than in r0 and restore it on
+@@ -155,7 +154,7 @@ linux_gateway_entry:
+ 	STREG	%r19, TASK_PT_GR19(%r1)
+ 
+ 	LDREGM	-FRAME_SIZE(%r30), %r2		/* get users sp back */
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	extrd,u	%r2,63,1,%r19			/* W hidden in bottom bit */
+ #if 0
+ 	xor	%r19,%r2,%r2			/* clear bottom bit */
+@@ -186,7 +185,7 @@ linux_gateway_entry:
+ 
+ 	loadgp
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29			/* Reference param save area */
+ 	copy	%r19,%r2			/* W bit back to r2 */
+ #else
+@@ -205,7 +204,7 @@ linux_gateway_entry:
+ 	/* Note!  We cannot use the syscall table that is mapped
+ 	nearby since the gateway page is mapped execute-only. */
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldil	L%sys_call_table, %r1
+ 	or,=	%r2,%r2,%r2
+ 	addil	L%(sys_call_table64-sys_call_table), %r1
+@@ -321,7 +320,7 @@ tracesys_next:	
+ 	LDREG   TASK_PT_GR25(%r1), %r25
+ 	LDREG   TASK_PT_GR24(%r1), %r24
+ 	LDREG   TASK_PT_GR23(%r1), %r23
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	LDREG   TASK_PT_GR22(%r1), %r22
+ 	LDREG   TASK_PT_GR21(%r1), %r21
+ 	ldo	-16(%r30),%r29			/* Reference param save area */
+@@ -350,7 +349,7 @@ tracesys_next:	
+ tracesys_exit:
+ 	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
+ 	LDREG	TI_TASK(%r1), %r1
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29			/* Reference param save area */
+ #endif
+ 	bl	syscall_trace, %r2
+@@ -371,7 +370,7 @@ tracesys_exit:
+ tracesys_sigexit:
+ 	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
+ 	LDREG	0(%r1), %r1
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	ldo	-16(%r30),%r29			/* Reference param save area */
+ #endif
+ 	bl	syscall_trace, %r2
+@@ -404,7 +403,7 @@ lws_start:
+ 	gate	.+8, %r0
+ 	depi	3, 31, 2, %r31	/* Ensure we return to userspace */
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* FIXME: If we are a 64-bit kernel just
+ 	 *        turn this on unconditionally.
+ 	 */
+@@ -440,7 +439,7 @@ lws_exit_nosys:
+ 	/* Fall through: Return to userspace */
+ 
+ lws_exit:
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* decide whether to reset the wide mode bit
+ 	 *
+ 	 * For a syscall, the W bit is stored in the lowest bit
+@@ -486,7 +485,7 @@ lws_exit:
+ 
+ 	/* ELF64 Process entry path */
+ lws_compare_and_swap64:
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	b,n	lws_compare_and_swap
+ #else
+ 	/* If we are not a 64-bit kernel, then we don't
+@@ -497,7 +496,7 @@ lws_compare_and_swap64:
+ 
+ 	/* ELF32 Process entry path */
+ lws_compare_and_swap32:
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* Clip all the input registers */
+ 	depdi	0, 31, 32, %r26
+ 	depdi	0, 31, 32, %r25
+@@ -608,7 +607,7 @@ cas_action:
+ 	   the other for the store. Either return -EFAULT.
+ 	   Each of the entries must be relocated. */
+ 	.section __ex_table,"aw"
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* Pad the address calculation */
+ 	.word	0,(2b - linux_gateway_page)
+ 	.word	0,(3b - linux_gateway_page)
+@@ -619,7 +618,7 @@ cas_action:
+ 	.previous
+ 
+ 	.section __ex_table,"aw"
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* Pad the address calculation */
+ 	.word	0,(1b - linux_gateway_page)
+ 	.word	0,(3b - linux_gateway_page)
+@@ -638,7 +637,7 @@ end_linux_gateway_page:
+ 
+ 	/* Relocate symbols assuming linux_gateway_page is mapped
+ 	   to virtual address 0x0 */
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/* FIXME: The code will always be on the gateay page
+ 		  and thus it will be on the first 4k, the
+ 		  assembler seems to think that the final
+@@ -666,7 +665,7 @@ lws_table:
+ sys_call_table:
+ #include "syscall_table.S"
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	.align 4096
+ 	.export sys_call_table64
+ .Lsys_call_table64:
+diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
+--- a/arch/parisc/kernel/syscall_table.S
++++ b/arch/parisc/kernel/syscall_table.S
+@@ -35,7 +35,7 @@
+ #undef ENTRY_UHOH
+ #undef ENTRY_COMP
+ #undef ENTRY_OURS
+-#if defined(__LP64__) && !defined(SYSCALL_TABLE_64BIT)
++#if defined(CONFIG_64BIT) && !defined(SYSCALL_TABLE_64BIT)
+ /* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and
+  * narrow palinux.  Use ENTRY_DIFF for those where a 32-bit specific
+  * implementation is required on wide palinux.  Use ENTRY_COMP where
+@@ -46,7 +46,7 @@
+ #define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
+ #define ENTRY_OURS(_name_) .dword parisc_##_name_
+ #define ENTRY_COMP(_name_) .dword compat_sys_##_name_
+-#elif defined(__LP64__) && defined(SYSCALL_TABLE_64BIT)
++#elif defined(CONFIG_64BIT) && defined(SYSCALL_TABLE_64BIT)
+ #define ENTRY_SAME(_name_) .dword sys_##_name_
+ #define ENTRY_DIFF(_name_) .dword sys_##_name_
+ #define ENTRY_UHOH(_name_) .dword sys_##_name_
+@@ -368,5 +368,11 @@
+ 	ENTRY_COMP(mbind)		/* 260 */
+ 	ENTRY_COMP(get_mempolicy)
+ 	ENTRY_COMP(set_mempolicy)
++	ENTRY_SAME(ni_syscall)	/* 263: reserved for vserver */
++	ENTRY_SAME(add_key)
++	ENTRY_SAME(request_key)		/* 265 */
++	ENTRY_SAME(keyctl)
++	ENTRY_SAME(ioprio_set)
++	ENTRY_SAME(ioprio_get)
+ 	/* Nothing yet */
+ 
+diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
+--- a/arch/parisc/kernel/time.c
++++ b/arch/parisc/kernel/time.c
+@@ -33,10 +33,6 @@
+ 
+ #include <linux/timex.h>
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ /* xtime and wall_jiffies keep wall-clock time */
+ extern unsigned long wall_jiffies;
+ 
+@@ -89,14 +85,6 @@ irqreturn_t timer_interrupt(int irq, voi
+ 		}
+ 	}
+     
+-#ifdef CONFIG_CHASSIS_LCD_LED
+-	/* Only schedule the led tasklet on cpu 0, and only if it
+-	 * is enabled.
+-	 */
+-	if (cpu == 0 && !atomic_read(&led_tasklet.count))
+-		tasklet_schedule(&led_tasklet);
+-#endif
+-
+ 	/* check soft power switch status */
+ 	if (cpu == 0 && !atomic_read(&power_tasklet.count))
+ 		tasklet_schedule(&power_tasklet);
+@@ -104,6 +92,24 @@ irqreturn_t timer_interrupt(int irq, voi
+ 	return IRQ_HANDLED;
+ }
+ 
++
++unsigned long profile_pc(struct pt_regs *regs)
++{
++	unsigned long pc = instruction_pointer(regs);
++
++	if (regs->gr[0] & PSW_N)
++		pc -= 4;
++
++#ifdef CONFIG_SMP
++	if (in_lock_functions(pc))
++		pc = regs->gr[2];
++#endif
++
++	return pc;
++}
++EXPORT_SYMBOL(profile_pc);
++
++
+ /*** converted from ia64 ***/
+ /*
+  * Return the number of micro-seconds that elapsed since the last
+diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
+--- a/arch/parisc/kernel/traps.c
++++ b/arch/parisc/kernel/traps.c
+@@ -74,7 +74,10 @@ void show_regs(struct pt_regs *regs)
+ 	char *level;
+ 	unsigned long cr30;
+ 	unsigned long cr31;
+-
++	/* carlos says that gcc understands better memory in a struct,
++	 * and it makes our life easier with fpregs -- T-Bone */
++	struct { u32 sw[2]; } s;
++	
+ 	level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;
+ 
+ 	printk("%s\n", level); /* don't want to have that pretty register dump messed up */
+@@ -103,11 +106,33 @@ void show_regs(struct pt_regs *regs)
+ 		printk("%s\n", buf);
+ 	}
+ 
+-#if RIDICULOUSLY_VERBOSE
+-	for (i = 0; i < 32; i += 2)
+-		printk("%sFR%02d : %016lx  FR%2d : %016lx", level, i,
+-				regs->fr[i], i+1, regs->fr[i+1]);
+-#endif
++	/* FR are 64bit everywhere. Need to use asm to get the content
++	 * of fpsr/fper1, and we assume that we won't have a FP Identify
++	 * in our way, otherwise we're screwed.
++	 * The fldd is used to restore the T-bit if there was one, as the
++	 * store clears it anyway.
++	 * BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */ 
++	__asm__ (
++		"fstd %%fr0,0(%1)	\n\t"
++		"fldd 0(%1),%%fr0	\n\t"
++		: "=m" (s) : "r" (&s) : "%r0"
++		);
++
++	printk("%s\n", level);
++	printk("%s      VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level);
++	printbinary(buf, s.sw[0], 32);
++	printk("%sFPSR: %s\n", level, buf);
++	printk("%sFPER1: %08x\n", level, s.sw[1]);
++
++	/* here we'll print fr0 again, tho it'll be meaningless */
++	for (i = 0; i < 32; i += 4) {
++		int j;
++		p = buf;
++		p += sprintf(p, "%sfr%02d-%02d ", level, i, i + 3);
++		for (j = 0; j < 4; j++)
++			p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]);
++		printk("%s\n", buf);
++	}
+ 
+ 	cr30 = mfctl(30);
+ 	cr31 = mfctl(31);
+diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
+--- a/arch/parisc/kernel/unaligned.c
++++ b/arch/parisc/kernel/unaligned.c
+@@ -513,15 +513,18 @@ void handle_unaligned(struct pt_regs *re
+ 	register int flop=0;	/* true if this is a flop */
+ 
+ 	/* log a message with pacing */
+-	if (user_mode(regs))
+-	{
+-		if (unaligned_count > 5 && jiffies - last_time > 5*HZ)
+-		{
++	if (user_mode(regs)) {
++		if (current->thread.flags & PARISC_UAC_SIGBUS) {
++			goto force_sigbus;
++		}
++
++		if (unaligned_count > 5 && jiffies - last_time > 5*HZ) {
+ 			unaligned_count = 0;
+ 			last_time = jiffies;
+ 		}
+-		if (++unaligned_count < 5)
+-		{
++
++		if (!(current->thread.flags & PARISC_UAC_NOPRINT) 
++		    && ++unaligned_count < 5) {
+ 			char buf[256];
+ 			sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
+ 				current->comm, current->pid, regs->ior, regs->iaoq[0]);
+@@ -530,6 +533,7 @@ void handle_unaligned(struct pt_regs *re
+ 			show_regs(regs);
+ #endif		
+ 		}
++
+ 		if (!unaligned_enabled)
+ 			goto force_sigbus;
+ 	}
+diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S
+--- a/arch/parisc/lib/fixup.S
++++ b/arch/parisc/lib/fixup.S
+@@ -35,7 +35,7 @@
+ 	extrd,u \t2,63,32,\t2
+ #endif
+ 	/* t2 = &__per_cpu_offset[smp_processor_id()]; */
+-	LDREG,s \t2(\t1),\t2 
++	LDREGX \t2(\t1),\t2 
+ 	addil LT%per_cpu__exception_data,%r27
+ 	LDREG RT%per_cpu__exception_data(%r1),\t1
+ 	/* t1 = &__get_cpu_var(exception_data) */
+@@ -53,6 +53,8 @@
+ 	.endm
+ #endif
+ 
++	.level LEVEL
++
+ 	.text
+ 	.section .fixup, "ax"
+ 
+diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
+--- a/arch/parisc/lib/memcpy.c
++++ b/arch/parisc/lib/memcpy.c
+@@ -339,6 +339,7 @@ unsigned long pa_memcpy(void *dstp, cons
+ 	pds = (double *)pcs;
+ 	pdd = (double *)pcd;
+ 
++#if 0
+ 	/* Copy 8 doubles at a time */
+ 	while (len >= 8*sizeof(double)) {
+ 		register double r1, r2, r3, r4, r5, r6, r7, r8;
+@@ -366,6 +367,7 @@ unsigned long pa_memcpy(void *dstp, cons
+ 		fstdma(d_space, r8, pdd, pmc_store_exc);
+ 		len -= 8*sizeof(double);
+ 	}
++#endif
+ 
+ 	pws = (unsigned int *)pds;
+ 	pwd = (unsigned int *)pdd;
+diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
+--- a/arch/parisc/mm/init.c
++++ b/arch/parisc/mm/init.c
+@@ -505,7 +505,9 @@ void show_mem(void)
+ 
+ 		for (j = node_start_pfn(i); j < node_end_pfn(i); j++) {
+ 			struct page *p;
++			unsigned long flags;
+ 
++			pgdat_resize_lock(NODE_DATA(i), &flags);
+ 			p = nid_page_nr(i, j) - node_start_pfn(i);
+ 
+ 			total++;
+@@ -517,6 +519,7 @@ void show_mem(void)
+ 				free++;
+ 			else
+ 				shared += page_count(p) - 1;
++			pgdat_resize_unlock(NODE_DATA(i), &flags);
+         	}
+ 	}
+ #endif
+diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
+--- a/arch/parisc/mm/ioremap.c
++++ b/arch/parisc/mm/ioremap.c
+@@ -52,7 +52,7 @@ static inline int remap_area_pmd(pmd_t *
+ 	if (address >= end)
+ 		BUG();
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(NULL, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+@@ -75,10 +75,9 @@ static int remap_area_pages(unsigned lon
+ 	flush_cache_all();
+ 	if (address >= end)
+ 		BUG();
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		pmd_t *pmd;
+-		pmd = pmd_alloc(dir, address);
++		pmd = pmd_alloc(&init_mm, dir, address);
+ 		error = -ENOMEM;
+ 		if (!pmd)
+ 			break;
+@@ -89,7 +88,6 @@ static int remap_area_pages(unsigned lon
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_tlb_all();
+ 	return error;
+ }
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/Kconfig
+@@ -0,0 +1,900 @@
++# For a description of the syntax of this configuration file,
++# see Documentation/kbuild/kconfig-language.txt.
++#
++
++mainmenu "Linux/PowerPC Kernel Configuration"
++
++config PPC64
++	bool "64-bit kernel"
++	default n
++	help
++	  This option selects whether a 32-bit or a 64-bit kernel
++	  will be built.
++
++config PPC32
++	bool
++	default y if !PPC64
++
++config 64BIT
++	bool
++	default y if PPC64
++
++config PPC_MERGE
++	def_bool y
++
++config MMU
++	bool
++	default y
++
++config UID16
++	bool
++
++config GENERIC_HARDIRQS
++	bool
++	default y
++
++config RWSEM_GENERIC_SPINLOCK
++	bool
++
++config RWSEM_XCHGADD_ALGORITHM
++	bool
++	default y
++
++config GENERIC_CALIBRATE_DELAY
++	bool
++	default y
++
++config PPC
++	bool
++	default y
++
++config EARLY_PRINTK
++	bool
++	default y if PPC64
++
++config COMPAT
++	bool
++	default y if PPC64
++
++config SYSVIPC_COMPAT
++	bool
++	depends on COMPAT && SYSVIPC
++	default y
++
++# All PPC32s use generic nvram driver through ppc_md
++config GENERIC_NVRAM
++	bool
++	default y if PPC32
++
++config SCHED_NO_NO_OMIT_FRAME_POINTER
++	bool
++	default y
++
++config ARCH_MAY_HAVE_PC_FDC
++	bool
++	default y
++
++menu "Processor support"
++choice
++	prompt "Processor Type"
++	depends on PPC32
++	default 6xx
++
++config 6xx
++	bool "6xx/7xx/74xx"
++	select PPC_FPU
++	help
++	  There are four families of PowerPC chips supported.  The more common
++	  types (601, 603, 604, 740, 750, 7400), the Motorola embedded
++	  versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC
++	  embedded versions (403 and 405) and the high end 64 bit Power
++	  processors (POWER 3, POWER4, and IBM PPC970 also known as G5).
++	  
++	  Unless you are building a kernel for one of the embedded processor
++	  systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
++	  Note that the kernel runs in 32-bit mode even on 64-bit chips.
++
++config PPC_52xx
++	bool "Freescale 52xx"
++	
++config PPC_82xx
++	bool "Freescale 82xx"
++
++config PPC_83xx
++	bool "Freescale 83xx"
++
++config 40x
++	bool "AMCC 40x"
++
++config 44x
++	bool "AMCC 44x"
++
++config 8xx
++	bool "Freescale 8xx"
++
++config E200
++	bool "Freescale e200"
++
++config E500
++	bool "Freescale e500"
++endchoice
++
++config POWER4_ONLY
++	bool "Optimize for POWER4"
++	depends on PPC64
++	default n
++	---help---
++	  Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
++	  The resulting binary will not work on POWER3 or RS64 processors
++	  when compiled with binutils 2.15 or later.
++
++config POWER3
++	bool
++	depends on PPC64
++	default y if !POWER4_ONLY
++
++config POWER4
++	depends on PPC64
++	def_bool y
++
++config PPC_FPU
++	bool
++	default y if PPC64
++
++config BOOKE
++	bool
++	depends on E200 || E500
++	default y
++
++config FSL_BOOKE
++	bool
++	depends on E200 || E500
++	default y
++
++config PTE_64BIT
++	bool
++	depends on 44x || E500
++	default y if 44x
++	default y if E500 && PHYS_64BIT
++
++config PHYS_64BIT
++	bool 'Large physical address support' if E500
++	depends on 44x || E500
++	default y if 44x
++	---help---
++	  This option enables kernel support for larger than 32-bit physical
++	  addresses.  This features is not be available on all e500 cores.
++
++	  If in doubt, say N here.
++
++config ALTIVEC
++	bool "AltiVec Support"
++	depends on 6xx || POWER4
++	---help---
++	  This option enables kernel support for the Altivec extensions to the
++	  PowerPC processor. The kernel currently supports saving and restoring
++	  altivec registers, and turning on the 'altivec enable' bit so user
++	  processes can execute altivec instructions.
++
++	  This option is only usefully if you have a processor that supports
++	  altivec (G4, otherwise known as 74xx series), but does not have
++	  any affect on a non-altivec cpu (it does, however add code to the
++	  kernel).
++
++	  If in doubt, say Y here.
++
++config SPE
++	bool "SPE Support"
++	depends on E200 || E500
++	---help---
++	  This option enables kernel support for the Signal Processing
++	  Extensions (SPE) to the PowerPC processor. The kernel currently
++	  supports saving and restoring SPE registers, and turning on the
++	  'spe enable' bit so user processes can execute SPE instructions.
++
++	  This option is only useful if you have a processor that supports
++	  SPE (e500, otherwise known as 85xx series), but does not have any
++	  effect on a non-spe cpu (it does, however add code to the kernel).
++
++	  If in doubt, say Y here.
++
++config PPC_STD_MMU
++	bool
++	depends on 6xx || POWER3 || POWER4 || PPC64
++	default y
++
++config PPC_STD_MMU_32
++	def_bool y
++	depends on PPC_STD_MMU && PPC32
++
++config SMP
++	depends on PPC_STD_MMU
++	bool "Symmetric multi-processing support"
++	---help---
++	  This enables support for systems with more than one CPU. If you have
++	  a system with only one CPU, say N. If you have a system with more
++	  than one CPU, say Y.  Note that the kernel does not currently
++	  support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
++	  since they have inadequate hardware support for multiprocessor
++	  operation.
++
++	  If you say N here, the kernel will run on single and multiprocessor
++	  machines, but will use only one CPU of a multiprocessor machine. If
++	  you say Y here, the kernel will run on single-processor machines.
++	  On a single-processor machine, the kernel will run faster if you say
++	  N here.
++
++	  If you don't know what to do here, say N.
++
++config NR_CPUS
++	int "Maximum number of CPUs (2-32)"
++	range 2 128
++	depends on SMP
++	default "32" if PPC64
++	default "4"
++
++config NOT_COHERENT_CACHE
++	bool
++	depends on 4xx || 8xx || E200
++	default y
++endmenu
++
++source "init/Kconfig"
++
++menu "Platform support"
++	depends on PPC64 || 6xx
++
++choice
++	prompt "Machine type"
++	default PPC_MULTIPLATFORM
++
++config PPC_MULTIPLATFORM
++	bool "Generic desktop/server/laptop"
++	help
++	  Select this option if configuring for an IBM pSeries or
++	  RS/6000 machine, an Apple machine, or a PReP, CHRP,
++	  Maple or Cell-based machine.
++
++config PPC_ISERIES
++	bool "IBM Legacy iSeries"
++	depends on PPC64
++
++config EMBEDDED6xx
++	bool "Embedded 6xx/7xx/7xxx-based board"
++	depends on PPC32
++
++config APUS
++	bool "Amiga-APUS"
++	depends on PPC32 && BROKEN
++	help
++	  Select APUS if configuring for a PowerUP Amiga.
++	  More information is available at:
++	  <http://linux-apus.sourceforge.net/>.
++endchoice
++
++config PPC_PSERIES
++	depends on PPC_MULTIPLATFORM && PPC64
++	bool "  IBM pSeries & new (POWER5-based) iSeries"
++	select PPC_I8259
++	select PPC_RTAS
++	select RTAS_ERROR_LOGGING
++	default y
++
++config PPC_CHRP
++	bool "  Common Hardware Reference Platform (CHRP) based machines"
++	depends on PPC_MULTIPLATFORM && PPC32
++	select PPC_I8259
++	select PPC_INDIRECT_PCI
++	select PPC_RTAS
++	select PPC_MPC106
++	default y
++
++config PPC_PMAC
++	bool "  Apple PowerMac based machines"
++	depends on PPC_MULTIPLATFORM
++	select PPC_INDIRECT_PCI if PPC32
++	select PPC_MPC106 if PPC32
++	default y
++
++config PPC_PMAC64
++	bool
++	depends on PPC_PMAC && POWER4
++	select U3_DART
++	default y
++
++config PPC_PREP
++	bool "  PowerPC Reference Platform (PReP) based machines"
++	depends on PPC_MULTIPLATFORM && PPC32
++	select PPC_I8259
++	select PPC_INDIRECT_PCI
++	default y
++
++config PPC_MAPLE
++	depends on PPC_MULTIPLATFORM && PPC64
++	bool "  Maple 970FX Evaluation Board"
++	select U3_DART
++	select MPIC_BROKEN_U3
++	default n
++	help
++          This option enables support for the Maple 970FX Evaluation Board.
++	  For more informations, refer to <http://www.970eval.com>
++
++config PPC_BPA
++	bool "  Broadband Processor Architecture"
++	depends on PPC_MULTIPLATFORM && PPC64
++	select PPC_RTAS
++
++config PPC_OF
++	bool
++	depends on PPC_MULTIPLATFORM	# for now
++	default y
++
++config XICS
++	depends on PPC_PSERIES
++	bool
++	default y
++
++config U3_DART
++	bool 
++	depends on PPC_MULTIPLATFORM && PPC64
++	default n
++
++config MPIC
++	depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
++	bool
++	default y
++
++config PPC_RTAS
++	bool
++	default n
++
++config RTAS_ERROR_LOGGING
++	bool
++	depends on PPC_RTAS
++	default n
++
++config MPIC_BROKEN_U3
++	bool
++	depends on PPC_MAPLE
++	default y
++
++config BPA_IIC
++	depends on PPC_BPA
++	bool
++	default y
++
++config IBMVIO
++	depends on PPC_PSERIES || PPC_ISERIES
++	bool
++	default y
++
++config PPC_MPC106
++	bool
++	default n
++
++source "drivers/cpufreq/Kconfig"
++
++config CPU_FREQ_PMAC
++	bool "Support for Apple PowerBooks"
++	depends on CPU_FREQ && ADB_PMU && PPC32
++	select CPU_FREQ_TABLE
++	help
++	  This adds support for frequency switching on Apple PowerBooks,
++	  this currently includes some models of iBook & Titanium
++	  PowerBook.
++
++config PPC601_SYNC_FIX
++	bool "Workarounds for PPC601 bugs"
++	depends on 6xx && (PPC_PREP || PPC_PMAC)
++	help
++	  Some versions of the PPC601 (the first PowerPC chip) have bugs which
++	  mean that extra synchronization instructions are required near
++	  certain instructions, typically those that make major changes to the
++	  CPU state.  These extra instructions reduce performance slightly.
++	  If you say N here, these extra instructions will not be included,
++	  resulting in a kernel which will run faster but may not run at all
++	  on some systems with the PPC601 chip.
++
++	  If in doubt, say Y here.
++
++config TAU
++	bool "Thermal Management Support"
++	depends on 6xx
++	help
++	  G3 and G4 processors have an on-chip temperature sensor called the
++	  'Thermal Assist Unit (TAU)', which, in theory, can measure the on-die
++	  temperature within 2-4 degrees Celsius. This option shows the current
++	  on-die temperature in /proc/cpuinfo if the cpu supports it.
++
++	  Unfortunately, on some chip revisions, this sensor is very inaccurate
++	  and in some cases, does not work at all, so don't assume the cpu
++	  temp is actually what /proc/cpuinfo says it is.
++
++config TAU_INT
++	bool "Interrupt driven TAU driver (DANGEROUS)"
++	depends on TAU
++	---help---
++	  The TAU supports an interrupt driven mode which causes an interrupt
++	  whenever the temperature goes out of range. This is the fastest way
++	  to get notified the temp has exceeded a range. With this option off,
++	  a timer is used to re-check the temperature periodically.
++
++	  However, on some cpus it appears that the TAU interrupt hardware
++	  is buggy and can cause a situation which would lead unexplained hard
++	  lockups.
++
++	  Unless you are extending the TAU driver, or enjoy kernel/hardware
++	  debugging, leave this option off.
++
++config TAU_AVERAGE
++	bool "Average high and low temp"
++	depends on TAU
++	---help---
++	  The TAU hardware can compare the temperature to an upper and lower
++	  bound.  The default behavior is to show both the upper and lower
++	  bound in /proc/cpuinfo. If the range is large, the temperature is
++	  either changing a lot, or the TAU hardware is broken (likely on some
++	  G4's). If the range is small (around 4 degrees), the temperature is
++	  relatively stable.  If you say Y here, a single temperature value,
++	  halfway between the upper and lower bounds, will be reported in
++	  /proc/cpuinfo.
++
++	  If in doubt, say N here.
++endmenu
++
++source arch/powerpc/platforms/embedded6xx/Kconfig
++source arch/powerpc/platforms/4xx/Kconfig
++source arch/powerpc/platforms/85xx/Kconfig
++source arch/powerpc/platforms/8xx/Kconfig
++
++menu "Kernel options"
++
++config HIGHMEM
++	bool "High memory support"
++	depends on PPC32
++
++source kernel/Kconfig.hz
++source kernel/Kconfig.preempt
++source "fs/Kconfig.binfmt"
++
++# We optimistically allocate largepages from the VM, so make the limit
++# large enough (16MB). This badly named config option is actually
++# max order + 1
++config FORCE_MAX_ZONEORDER
++	int
++	depends on PPC64
++	default "13"
++
++config MATH_EMULATION
++	bool "Math emulation"
++	depends on 4xx || 8xx || E200 || E500
++	---help---
++	  Some PowerPC chips designed for embedded applications do not have
++	  a floating-point unit and therefore do not implement the
++	  floating-point instructions in the PowerPC instruction set.  If you
++	  say Y here, the kernel will include code to emulate a floating-point
++	  unit, which will allow programs that use floating-point
++	  instructions to run.
++
++config IOMMU_VMERGE
++	bool "Enable IOMMU virtual merging (EXPERIMENTAL)"
++	depends on EXPERIMENTAL && PPC64
++	default n
++	help
++	  Cause IO segments sent to a device for DMA to be merged virtually
++	  by the IOMMU when they happen to have been allocated contiguously.
++	  This doesn't add pressure to the IOMMU allocator. However, some
++	  drivers don't support getting large merged segments coming back
++	  from *_map_sg(). Say Y if you know the drivers you are using are
++	  properly handling this case.
++
++config HOTPLUG_CPU
++	bool "Support for enabling/disabling CPUs"
++	depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
++	---help---
++	  Say Y here to be able to disable and re-enable individual
++	  CPUs at runtime on SMP machines.
++
++	  Say N if you are unsure.
++
++config KEXEC
++	bool "kexec system call (EXPERIMENTAL)"
++	depends on PPC_MULTIPLATFORM && EXPERIMENTAL
++	help
++	  kexec is a system call that implements the ability to shutdown your
++	  current kernel, and to start another kernel.  It is like a reboot
++	  but it is indepedent of the system firmware.   And like a reboot
++	  you can start any kernel with it, not just Linux.
++
++	  The name comes from the similiarity to the exec system call.
++
++	  It is an ongoing process to be certain the hardware in a machine
++	  is properly shutdown, so do not be surprised if this code does not
++	  initially work for you.  It may help to enable device hotplugging
++	  support.  As of this writing the exact hardware interface is
++	  strongly in flux, so no good recommendation can be made.
++
++config EMBEDDEDBOOT
++	bool
++	depends on 8xx || 8260
++	default y
++
++config PC_KEYBOARD
++	bool "PC PS/2 style Keyboard"
++	depends on 4xx || CPM2
++
++config PPCBUG_NVRAM
++	bool "Enable reading PPCBUG NVRAM during boot" if PPLUS || LOPEC
++	default y if PPC_PREP
++
++config IRQ_ALL_CPUS
++	bool "Distribute interrupts on all CPUs by default"
++	depends on SMP && !MV64360
++	help
++	  This option gives the kernel permission to distribute IRQs across
++	  multiple CPUs.  Saying N here will route all IRQs to the first
++	  CPU.  Generally saying Y is safe, although some problems have been
++	  reported with SMP Power Macintoshes with this option enabled.
++
++source "arch/powerpc/platforms/pseries/Kconfig"
++
++config NUMA
++	bool "NUMA support"
++	depends on PPC64
++	default y if SMP && PPC_PSERIES
++
++config ARCH_SELECT_MEMORY_MODEL
++	def_bool y
++	depends on PPC64
++
++config ARCH_FLATMEM_ENABLE
++       def_bool y
++       depends on PPC64 && !NUMA
++
++config ARCH_DISCONTIGMEM_ENABLE
++	def_bool y
++	depends on SMP && PPC_PSERIES
++
++config ARCH_DISCONTIGMEM_DEFAULT
++	def_bool y
++	depends on ARCH_DISCONTIGMEM_ENABLE
++
++config ARCH_SPARSEMEM_ENABLE
++	def_bool y
++	depends on ARCH_DISCONTIGMEM_ENABLE
++
++source "mm/Kconfig"
++
++config HAVE_ARCH_EARLY_PFN_TO_NID
++	def_bool y
++	depends on NEED_MULTIPLE_NODES
++
++# Some NUMA nodes have memory ranges that span
++# other nodes.  Even though a pfn is valid and
++# between a node's start and end pfns, it may not
++# reside on that node.
++#
++# This is a relatively temporary hack that should
++# be able to go away when sparsemem is fully in
++# place
++
++config NODES_SPAN_OTHER_NODES
++	def_bool y
++	depends on NEED_MULTIPLE_NODES
++
++config SCHED_SMT
++	bool "SMT (Hyperthreading) scheduler support"
++	depends on PPC64 && SMP
++	default off
++	help
++	  SMT scheduler support improves the CPU scheduler's decision making
++	  when dealing with POWER5 cpus at a cost of slightly increased
++	  overhead in some places. If unsure say N here.
++
++config PROC_DEVICETREE
++	bool "Support for device tree in /proc"
++	depends on PROC_FS
++	help
++	  This option adds a device-tree directory under /proc which contains
++	  an image of the device tree that the kernel copies from Open
++	  Firmware or other boot firmware. If unsure, say Y here.
++
++source "arch/powerpc/platforms/prep/Kconfig"
++
++config CMDLINE_BOOL
++	bool "Default bootloader kernel arguments"
++	depends on !PPC_ISERIES
++
++config CMDLINE
++	string "Initial kernel command string"
++	depends on CMDLINE_BOOL
++	default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
++	help
++	  On some platforms, there is currently no way for the boot loader to
++	  pass arguments to the kernel. For these platforms, you can supply
++	  some command-line options at build time by entering them here.  In
++	  most cases you will need to specify the root device here.
++
++if !44x || BROKEN
++source kernel/power/Kconfig
++endif
++
++config SECCOMP
++	bool "Enable seccomp to safely compute untrusted bytecode"
++	depends on PROC_FS
++	default y
++	help
++	  This kernel feature is useful for number crunching applications
++	  that may need to compute untrusted bytecode during their
++	  execution. By using pipes or other transports made available to
++	  the process as file descriptors supporting the read/write
++	  syscalls, it's possible to isolate those applications in
++	  their own address space using seccomp. Once seccomp is
++	  enabled via /proc/<pid>/seccomp, it cannot be disabled
++	  and the task is only allowed to execute a few safe syscalls
++	  defined by each seccomp mode.
++
++	  If unsure, say Y. Only embedded should say N here.
++
++endmenu
++
++config ISA_DMA_API
++	bool
++	default y
++
++menu "Bus options"
++
++config ISA
++	bool "Support for ISA-bus hardware"
++	depends on PPC_PREP || PPC_CHRP
++	select PPC_I8259
++	help
++	  Find out whether you have ISA slots on your motherboard.  ISA is the
++	  name of a bus system, i.e. the way the CPU talks to the other stuff
++	  inside your box.  If you have an Apple machine, say N here; if you
++	  have an IBM RS/6000 or pSeries machine or a PReP machine, say Y.  If
++	  you have an embedded board, consult your board documentation.
++
++config GENERIC_ISA_DMA
++	bool
++	depends on PPC64 || POWER4 || 6xx && !CPM2
++	default y
++
++config PPC_I8259
++	bool
++	default y if 85xx
++	default n
++
++config PPC_INDIRECT_PCI
++	bool
++	depends on PCI
++	default y if 40x || 44x || 85xx || 83xx
++	default n
++
++config EISA
++	bool
++
++config SBUS
++	bool
++
++# Yes MCA RS/6000s exist but Linux-PPC does not currently support any
++config MCA
++	bool
++
++config PCI
++	bool "PCI support" if 40x || CPM2 || 83xx || 85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
++	default y if !40x && !CPM2 && !8xx && !APUS && !83xx && !85xx
++	default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
++	default PCI_QSPAN if !4xx && !CPM2 && 8xx
++	help
++	  Find out whether your system includes a PCI bus. PCI is the name of
++	  a bus system, i.e. the way the CPU talks to the other stuff inside
++	  your box.  If you say Y here, the kernel will include drivers and
++	  infrastructure code to support PCI bus devices.
++
++config PCI_DOMAINS
++	bool
++	default PCI
++
++config MPC83xx_PCI2
++	bool "  Supprt for 2nd PCI host controller"
++	depends on PCI && MPC834x
++	default y if MPC834x_SYS
++
++config PCI_QSPAN
++	bool "QSpan PCI"
++	depends on !4xx && !CPM2 && 8xx
++	select PPC_I8259
++	help
++	  Say Y here if you have a system based on a Motorola 8xx-series
++	  embedded processor with a QSPAN PCI interface, otherwise say N.
++
++config PCI_8260
++	bool
++	depends on PCI && 8260
++	select PPC_INDIRECT_PCI
++	default y
++
++config 8260_PCI9
++	bool "  Enable workaround for MPC826x erratum PCI 9"
++	depends on PCI_8260 && !ADS8272
++	default y
++
++choice
++	prompt "  IDMA channel for PCI 9 workaround"
++	depends on 8260_PCI9
++
++config 8260_PCI9_IDMA1
++	bool "IDMA1"
++
++config 8260_PCI9_IDMA2
++	bool "IDMA2"
++
++config 8260_PCI9_IDMA3
++	bool "IDMA3"
++
++config 8260_PCI9_IDMA4
++	bool "IDMA4"
++
++endchoice
++
++source "drivers/pci/Kconfig"
++
++source "drivers/pcmcia/Kconfig"
++
++source "drivers/pci/hotplug/Kconfig"
++
++endmenu
++
++menu "Advanced setup"
++	depends on PPC32
++
++config ADVANCED_OPTIONS
++	bool "Prompt for advanced kernel configuration options"
++	help
++	  This option will enable prompting for a variety of advanced kernel
++	  configuration options.  These options can cause the kernel to not
++	  work if they are set incorrectly, but can be used to optimize certain
++	  aspects of kernel memory management.
++
++	  Unless you know what you are doing, say N here.
++
++comment "Default settings for advanced configuration options are used"
++	depends on !ADVANCED_OPTIONS
++
++config HIGHMEM_START_BOOL
++	bool "Set high memory pool address"
++	depends on ADVANCED_OPTIONS && HIGHMEM
++	help
++	  This option allows you to set the base address of the kernel virtual
++	  area used to map high memory pages.  This can be useful in
++	  optimizing the layout of kernel virtual memory.
++
++	  Say N here unless you know what you are doing.
++
++config HIGHMEM_START
++	hex "Virtual start address of high memory pool" if HIGHMEM_START_BOOL
++	default "0xfe000000"
++
++config LOWMEM_SIZE_BOOL
++	bool "Set maximum low memory"
++	depends on ADVANCED_OPTIONS
++	help
++	  This option allows you to set the maximum amount of memory which
++	  will be used as "low memory", that is, memory which the kernel can
++	  access directly, without having to set up a kernel virtual mapping.
++	  This can be useful in optimizing the layout of kernel virtual
++	  memory.
++
++	  Say N here unless you know what you are doing.
++
++config LOWMEM_SIZE
++	hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
++	default "0x30000000"
++
++config KERNEL_START_BOOL
++	bool "Set custom kernel base address"
++	depends on ADVANCED_OPTIONS
++	help
++	  This option allows you to set the kernel virtual address at which
++	  the kernel will map low memory (the kernel image will be linked at
++	  this address).  This can be useful in optimizing the virtual memory
++	  layout of the system.
++
++	  Say N here unless you know what you are doing.
++
++config KERNEL_START
++	hex "Virtual address of kernel base" if KERNEL_START_BOOL
++	default "0xc0000000"
++
++config TASK_SIZE_BOOL
++	bool "Set custom user task size"
++	depends on ADVANCED_OPTIONS
++	help
++	  This option allows you to set the amount of virtual address space
++	  allocated to user tasks.  This can be useful in optimizing the
++	  virtual memory layout of the system.
++
++	  Say N here unless you know what you are doing.
++
++config TASK_SIZE
++	hex "Size of user task space" if TASK_SIZE_BOOL
++	default "0x80000000"
++
++config CONSISTENT_START_BOOL
++	bool "Set custom consistent memory pool address"
++	depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
++	help
++	  This option allows you to set the base virtual address
++	  of the the consistent memory pool.  This pool of virtual
++	  memory is used to make consistent memory allocations.
++
++config CONSISTENT_START
++	hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL
++	default "0xff100000" if NOT_COHERENT_CACHE
++
++config CONSISTENT_SIZE_BOOL
++	bool "Set custom consistent memory pool size"
++	depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
++	help
++	  This option allows you to set the size of the the
++	  consistent memory pool.  This pool of virtual memory
++	  is used to make consistent memory allocations.
++
++config CONSISTENT_SIZE
++	hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
++	default "0x00200000" if NOT_COHERENT_CACHE
++
++config BOOT_LOAD_BOOL
++	bool "Set the boot link/load address"
++	depends on ADVANCED_OPTIONS && !PPC_MULTIPLATFORM
++	help
++	  This option allows you to set the initial load address of the zImage
++	  or zImage.initrd file.  This can be useful if you are on a board
++	  which has a small amount of memory.
++
++	  Say N here unless you know what you are doing.
++
++config BOOT_LOAD
++	hex "Link/load address for booting" if BOOT_LOAD_BOOL
++	default "0x00400000" if 40x || 8xx || 8260
++	default "0x01000000" if 44x
++	default "0x00800000"
++
++config PIN_TLB
++	bool "Pinned Kernel TLBs (860 ONLY)"
++	depends on ADVANCED_OPTIONS && 8xx
++endmenu
++
++if PPC64
++config KERNEL_START
++	hex
++	default "0xc000000000000000"
++endif
++
++source "net/Kconfig"
++
++source "drivers/Kconfig"
++
++source "fs/Kconfig"
++
++# XXX source "arch/ppc/8xx_io/Kconfig"
++
++# XXX source "arch/ppc/8260_io/Kconfig"
++
++source "arch/powerpc/platforms/iseries/Kconfig"
++
++source "lib/Kconfig"
++
++source "arch/powerpc/oprofile/Kconfig"
++
++source "arch/powerpc/Kconfig.debug"
++
++source "security/Kconfig"
++
++config KEYS_COMPAT
++	bool
++	depends on COMPAT && KEYS
++	default y
++
++source "crypto/Kconfig"
+diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/Kconfig.debug
+@@ -0,0 +1,128 @@
++menu "Kernel hacking"
++
++source "lib/Kconfig.debug"
++
++config DEBUG_STACKOVERFLOW
++	bool "Check for stack overflows"
++	depends on DEBUG_KERNEL && PPC64
++	help
++	  This option will cause messages to be printed if free stack space
++	  drops below a certain limit.
++
++config KPROBES
++	bool "Kprobes"
++	depends on DEBUG_KERNEL && PPC64
++	help
++	  Kprobes allows you to trap at almost any kernel address and
++	  execute a callback function.  register_kprobe() establishes
++	  a probepoint and specifies the callback.  Kprobes is useful
++	  for kernel debugging, non-intrusive instrumentation and testing.
++	  If in doubt, say "N".
++
++config DEBUG_STACK_USAGE
++	bool "Stack utilization instrumentation"
++	depends on DEBUG_KERNEL && PPC64
++	help
++	  Enables the display of the minimum amount of free stack which each
++	  task has ever had available in the sysrq-T and sysrq-P debug output.
++
++	  This option will slow down process creation somewhat.
++
++config DEBUGGER
++	bool "Enable debugger hooks"
++	depends on DEBUG_KERNEL
++	help
++	  Include in-kernel hooks for kernel debuggers. Unless you are
++	  intending to debug the kernel, say N here.
++
++config KGDB
++	bool "Include kgdb kernel debugger"
++	depends on DEBUGGER && (BROKEN || PPC_GEN550 || 4xx)
++	select DEBUG_INFO
++	help
++	  Include in-kernel hooks for kgdb, the Linux kernel source level
++	  debugger.  See <http://kgdb.sourceforge.net/> for more information.
++	  Unless you are intending to debug the kernel, say N here.
++
++choice
++	prompt "Serial Port"
++	depends on KGDB
++	default KGDB_TTYS1
++
++config KGDB_TTYS0
++	bool "ttyS0"
++
++config KGDB_TTYS1
++	bool "ttyS1"
++
++config KGDB_TTYS2
++	bool "ttyS2"
++
++config KGDB_TTYS3
++	bool "ttyS3"
++
++endchoice
++
++config KGDB_CONSOLE
++	bool "Enable serial console thru kgdb port"
++	depends on KGDB && 8xx || CPM2
++	help
++	  If you enable this, all serial console messages will be sent
++	  over the gdb stub.
++	  If unsure, say N.
++
++config XMON
++	bool "Include xmon kernel debugger"
++	depends on DEBUGGER && !PPC_ISERIES
++	help
++	  Include in-kernel hooks for the xmon kernel monitor/debugger.
++	  Unless you are intending to debug the kernel, say N here.
++	  Make sure to enable also CONFIG_BOOTX_TEXT on Macs. Otherwise
++	  nothing will appear on the screen (xmon writes directly to the
++	  framebuffer memory).
++	  The cmdline option 'xmon' or 'xmon=early' will drop into xmon
++	  very early during boot. 'xmon=on' will just enable the xmon
++	  debugger hooks.  'xmon=off' will disable the debugger hooks
++	  if CONFIG_XMON_DEFAULT is set.
++
++config XMON_DEFAULT
++	bool "Enable xmon by default"
++	depends on XMON
++	help
++	  xmon is normally disabled unless booted with 'xmon=on'.
++	  Use 'xmon=off' to disable xmon init during runtime.
++
++config IRQSTACKS
++	bool "Use separate kernel stacks when processing interrupts"
++	depends on PPC64
++	help
++	  If you say Y here the kernel will use separate kernel stacks
++	  for handling hard and soft interrupts.  This can help avoid
++	  overflowing the process kernel stacks.
++
++config BDI_SWITCH
++	bool "Include BDI-2000 user context switcher"
++	depends on DEBUG_KERNEL && PPC32
++	help
++	  Include in-kernel support for the Abatron BDI2000 debugger.
++	  Unless you are intending to debug the kernel with one of these
++	  machines, say N here.
++
++config BOOTX_TEXT
++	bool "Support for early boot text console (BootX or OpenFirmware only)"
++	depends PPC_OF && !PPC_ISERIES
++	help
++	  Say Y here to see progress messages from the boot firmware in text
++	  mode. Requires either BootX or Open Firmware.
++
++config SERIAL_TEXT_DEBUG
++	bool "Support for early boot texts over serial port"
++	depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \
++		PPC_GEN550 || PPC_MPC52xx
++
++config PPC_OCP
++	bool
++	depends on IBM_OCP || XILINX_OCP
++	default y
++
++endmenu
+diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/Makefile
+@@ -0,0 +1,222 @@
++# This file is included by the global makefile so that you can add your own
++# architecture-specific flags and dependencies. Remember to do have actions
++# for "archclean" and "archdep" for cleaning up and making dependencies for
++# this architecture.
++#
++# 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 by Linus Torvalds
++# Changes for PPC by Gary Thomas
++# Rewritten by Cort Dougan and Paul Mackerras
++#
++
++# This must match PAGE_OFFSET in include/asm-powerpc/page.h.
++KERNELLOAD	:= $(CONFIG_KERNEL_START)
++
++HAS_BIARCH	:= $(call cc-option-yn, -m32)
++
++ifeq ($(CONFIG_PPC64),y)
++OLDARCH	:= ppc64
++SZ	:= 64
++
++# Set default 32 bits cross compilers for vdso and boot wrapper
++CROSS32_COMPILE ?=
++
++CROSS32CC		:= $(CROSS32_COMPILE)gcc
++CROSS32AS		:= $(CROSS32_COMPILE)as
++CROSS32LD		:= $(CROSS32_COMPILE)ld
++CROSS32OBJCOPY		:= $(CROSS32_COMPILE)objcopy
++
++ifeq ($(HAS_BIARCH),y)
++ifeq ($(CROSS32_COMPILE),)
++CROSS32CC	:= $(CC) -m32
++CROSS32AS	:= $(AS) -a32
++CROSS32LD	:= $(LD) -m elf32ppc
++CROSS32OBJCOPY	:= $(OBJCOPY)
++endif
++endif
++
++export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY
++
++new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi)
++
++ifeq ($(new_nm),y)
++NM		:= $(NM) --synthetic
++endif
++
++else
++OLDARCH	:= ppc
++SZ	:= 32
++endif
++
++UTS_MACHINE := $(OLDARCH)
++
++ifeq ($(HAS_BIARCH),y)
++override AS	+= -a$(SZ)
++override LD	+= -m elf$(SZ)ppc
++override CC	+= -m$(SZ)
++endif
++
++LDFLAGS_vmlinux	:= -Ttext $(KERNELLOAD) -Bstatic -e $(KERNELLOAD)
++
++# The -Iarch/$(ARCH)/include is temporary while we are merging
++CPPFLAGS	+= -Iarch/$(ARCH) -Iarch/$(ARCH)/include
++AFLAGS		+= -Iarch/$(ARCH)
++CFLAGS		+= -Iarch/$(ARCH) -msoft-float -pipe
++CFLAGS-$(CONFIG_PPC64)	:= -mminimal-toc -mtraceback=none  -mcall-aixdesc
++CFLAGS-$(CONFIG_PPC32)	:= -ffixed-r2 -mmultiple
++CFLAGS		+= $(CFLAGS-y)
++CPP		= $(CC) -E $(CFLAGS)
++# Temporary hack until we have migrated to asm-powerpc
++LINUXINCLUDE    += -Iarch/$(ARCH)/include
++
++CHECKFLAGS	+= -m$(SZ) -D__powerpc__ -D__powerpc$(SZ)__
++
++ifeq ($(CONFIG_PPC64),y)
++GCC_VERSION     := $(call cc-version)
++GCC_BROKEN_VEC	:= $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi)
++
++ifeq ($(CONFIG_POWER4_ONLY),y)
++ifeq ($(CONFIG_ALTIVEC),y)
++ifeq ($(GCC_BROKEN_VEC),y)
++	CFLAGS += $(call cc-option,-mcpu=970)
++else
++	CFLAGS += $(call cc-option,-mcpu=power4)
++endif
++else
++	CFLAGS += $(call cc-option,-mcpu=power4)
++endif
++else
++	CFLAGS += $(call cc-option,-mtune=power4)
++endif
++endif
++
++# No AltiVec instruction when building kernel
++CFLAGS += $(call cc-option,-mno-altivec)
++
++# Enable unit-at-a-time mode when possible. It shrinks the
++# kernel considerably.
++CFLAGS += $(call cc-option,-funit-at-a-time)
++
++ifndef CONFIG_FSL_BOOKE
++CFLAGS		+= -mstring
++endif
++
++cpu-as-$(CONFIG_PPC64BRIDGE)	+= -Wa,-mppc64bridge
++cpu-as-$(CONFIG_4xx)		+= -Wa,-m405
++cpu-as-$(CONFIG_6xx)		+= -Wa,-maltivec
++cpu-as-$(CONFIG_POWER4)		+= -Wa,-maltivec
++cpu-as-$(CONFIG_E500)		+= -Wa,-me500
++cpu-as-$(CONFIG_E200)		+= -Wa,-me200
++
++AFLAGS += $(cpu-as-y)
++CFLAGS += $(cpu-as-y)
++
++# Default to the common case.
++KBUILD_DEFCONFIG := common_defconfig
++
++head-y				:= arch/powerpc/kernel/head_32.o
++head-$(CONFIG_PPC64)		:= arch/powerpc/kernel/head_64.o
++head-$(CONFIG_8xx)		:= arch/powerpc/kernel/head_8xx.o
++head-$(CONFIG_4xx)		:= arch/powerpc/kernel/head_4xx.o
++head-$(CONFIG_44x)		:= arch/powerpc/kernel/head_44x.o
++head-$(CONFIG_FSL_BOOKE)	:= arch/powerpc/kernel/head_fsl_booke.o
++
++head-$(CONFIG_PPC64)		+= arch/powerpc/kernel/entry_64.o
++head-$(CONFIG_PPC_FPU)		+= arch/powerpc/kernel/fpu.o
++
++core-y				+= arch/powerpc/kernel/ \
++				   arch/$(OLDARCH)/kernel/ \
++				   arch/powerpc/mm/ \
++				   arch/powerpc/lib/ \
++				   arch/powerpc/sysdev/ \
++				   arch/powerpc/platforms/
++core-$(CONFIG_MATH_EMULATION)	+= arch/ppc/math-emu/
++core-$(CONFIG_XMON)		+= arch/powerpc/xmon/
++core-$(CONFIG_APUS)		+= arch/ppc/amiga/
++drivers-$(CONFIG_8xx)		+= arch/ppc/8xx_io/
++drivers-$(CONFIG_4xx)		+= arch/ppc/4xx_io/
++drivers-$(CONFIG_CPM2)		+= arch/ppc/8260_io/
++
++drivers-$(CONFIG_OPROFILE)	+= arch/powerpc/oprofile/
++
++defaultimage-$(CONFIG_PPC32)	:= uImage zImage
++defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
++defaultimage-$(CONFIG_PPC_PSERIES) := zImage
++KBUILD_IMAGE := $(defaultimage-y)
++all: $(KBUILD_IMAGE)
++
++CPPFLAGS_vmlinux.lds	:= -Upowerpc
++
++# All the instructions talk about "make bzImage".
++bzImage: zImage
++
++BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
++
++.PHONY: $(BOOT_TARGETS)
++
++boot := arch/$(OLDARCH)/boot
++
++# urk
++ifeq ($(CONFIG_PPC64),y)
++$(BOOT_TARGETS): vmlinux
++	$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
++else
++$(BOOT_TARGETS): vmlinux
++	$(Q)$(MAKE) ARCH=ppc $(build)=$(boot) $@
++endif
++
++uImage: vmlinux
++	$(Q)$(MAKE) ARCH=$(OLDARCH) $(build)=$(boot)/images $(boot)/images/$@
++
++define archhelp
++  @echo '* zImage          - Compressed kernel image (arch/$(ARCH)/boot/images/zImage.*)'
++  @echo '  uImage          - Create a bootable image for U-Boot / PPCBoot'
++  @echo '  install         - Install kernel using'
++  @echo '                    (your) ~/bin/installkernel or'
++  @echo '                    (distribution) /sbin/installkernel or'
++  @echo '                    install to $$(INSTALL_PATH) and run lilo'
++  @echo '  *_defconfig     - Select default config from arch/$(ARCH)/ppc/configs'
++endef
++
++archclean:
++	$(Q)$(MAKE) $(clean)=$(boot)
++	# Temporary hack until we have migrated to asm-powerpc
++	$(Q)rm -rf arch/$(ARCH)/include
++
++archprepare: checkbin
++
++# Temporary hack until we have migrated to asm-powerpc
++include/asm: arch/$(ARCH)/include/asm
++arch/$(ARCH)/include/asm:
++	$(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
++	$(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm
++
++# Use the file '.tmp_gas_check' for binutils tests, as gas won't output
++# to stdout and these checks are run even on install targets.
++TOUT	:= .tmp_gas_check
++# Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec
++# instructions.
++# gcc-3.4 and binutils-2.14 are a fatal combination.
++GCC_VERSION	:= $(call cc-version)
++
++checkbin:
++	@if test "$(GCC_VERSION)" = "0304" ; then \
++		if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \
++			echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \
++			echo 'correctly with gcc-3.4 and your version of binutils.'; \
++			echo '*** Please upgrade your binutils or downgrade your gcc'; \
++			false; \
++		fi ; \
++	fi
++	@if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \
++		echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \
++		echo 'correctly with old versions of binutils.' ; \
++		echo '*** Please upgrade your binutils to 2.12.1 or newer' ; \
++		false ; \
++	fi
++
++CLEAN_FILES += $(TOUT)
++
+diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/Makefile
+@@ -0,0 +1,56 @@
++#
++# Makefile for the linux kernel.
++#
++
++ifeq ($(CONFIG_PPC64),y)
++EXTRA_CFLAGS	+= -mno-minimal-toc
++endif
++ifeq ($(CONFIG_PPC32),y)
++CFLAGS_prom_init.o      += -fPIC
++CFLAGS_btext.o		+= -fPIC
++endif
++
++obj-y				:= semaphore.o cputable.o ptrace.o syscalls.o \
++				   signal_32.o pmc.o
++obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
++				   ptrace32.o systbl.o
++obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
++obj-$(CONFIG_POWER4)		+= idle_power4.o
++obj-$(CONFIG_PPC_OF)		+= of_device.o
++obj-$(CONFIG_PPC_RTAS)		+= rtas.o
++obj-$(CONFIG_IBMVIO)		+= vio.o
++
++ifeq ($(CONFIG_PPC_MERGE),y)
++
++extra-$(CONFIG_PPC_STD_MMU)	:= head_32.o
++extra-$(CONFIG_PPC64)		:= head_64.o
++extra-$(CONFIG_40x)		:= head_4xx.o
++extra-$(CONFIG_44x)		:= head_44x.o
++extra-$(CONFIG_FSL_BOOKE)	:= head_fsl_booke.o
++extra-$(CONFIG_8xx)		:= head_8xx.o
++extra-y				+= vmlinux.lds
++
++obj-y				+= process.o init_task.o time.o \
++				   prom.o traps.o setup-common.o
++obj-$(CONFIG_PPC32)		+= entry_32.o setup_32.o misc_32.o systbl.o
++obj-$(CONFIG_PPC64)		+= misc_64.o
++obj-$(CONFIG_PPC_OF)		+= prom_init.o
++obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
++obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
++obj-$(CONFIG_6xx)		+= idle_6xx.o
++
++ifeq ($(CONFIG_PPC_ISERIES),y)
++$(obj)/head_64.o: $(obj)/lparmap.s
++AFLAGS_head_64.o += -I$(obj)
++endif
++
++else
++# stuff used from here for ARCH=ppc or ARCH=ppc64
++obj-$(CONFIG_PPC64)		+= traps.o process.o init_task.o time.o \
++				   setup-common.o
++
++
++endif
++
++extra-$(CONFIG_PPC_FPU)		+= fpu.o
++extra-$(CONFIG_PPC64)		+= entry_64.o
+diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/asm-offsets.c
+@@ -0,0 +1,273 @@
++/*
++ * This program is used to generate definitions needed by
++ * assembly language modules.
++ *
++ * We use the technique used in the OSF Mach kernel code:
++ * generate asm statements containing #defines,
++ * compile this file to assembler, and then extract the
++ * #defines from the assembly-language output.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/signal.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/mman.h>
++#include <linux/mm.h>
++#ifdef CONFIG_PPC64
++#include <linux/time.h>
++#include <linux/hardirq.h>
++#else
++#include <linux/ptrace.h>
++#include <linux/suspend.h>
++#endif
++
++#include <asm/io.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/processor.h>
++#include <asm/cputable.h>
++#include <asm/thread_info.h>
++#include <asm/rtas.h>
++#ifdef CONFIG_PPC64
++#include <asm/paca.h>
++#include <asm/lppaca.h>
++#include <asm/iSeries/HvLpEvent.h>
++#include <asm/cache.h>
++#include <asm/systemcfg.h>
++#include <asm/compat.h>
++#endif
++
++#define DEFINE(sym, val) \
++	asm volatile("\n->" #sym " %0 " #val : : "i" (val))
++
++#define BLANK() asm volatile("\n->" : : )
++
++int main(void)
++{
++	DEFINE(THREAD, offsetof(struct task_struct, thread));
++	DEFINE(MM, offsetof(struct task_struct, mm));
++#ifdef CONFIG_PPC64
++	DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
++#else
++	DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info));
++	DEFINE(PTRACE, offsetof(struct task_struct, ptrace));
++#endif /* CONFIG_PPC64 */
++
++	DEFINE(KSP, offsetof(struct thread_struct, ksp));
++	DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
++	DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
++	DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
++	DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
++#ifdef CONFIG_ALTIVEC
++	DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
++	DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
++	DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
++	DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_PPC64
++	DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid));
++#else /* CONFIG_PPC64 */
++	DEFINE(PGDIR, offsetof(struct thread_struct, pgdir));
++	DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall));
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++	DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
++	DEFINE(PT_PTRACED, PT_PTRACED);
++#endif
++#ifdef CONFIG_SPE
++	DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0]));
++	DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc));
++	DEFINE(THREAD_SPEFSCR, offsetof(struct thread_struct, spefscr));
++	DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe));
++#endif /* CONFIG_SPE */
++#endif /* CONFIG_PPC64 */
++
++	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
++	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
++	DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
++#ifdef CONFIG_PPC32
++	DEFINE(TI_TASK, offsetof(struct thread_info, task));
++	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
++	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
++#endif /* CONFIG_PPC32 */
++
++#ifdef CONFIG_PPC64
++	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
++	DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
++	DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page));
++	DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
++	DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
++	DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
++	DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
++	DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
++
++	/* paca */
++	DEFINE(PACA_SIZE, sizeof(struct paca_struct));
++	DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
++	DEFINE(PACAPROCSTART, offsetof(struct paca_struct, cpu_start));
++	DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack));
++	DEFINE(PACACURRENT, offsetof(struct paca_struct, __current));
++	DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr));
++	DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
++	DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
++	DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
++	DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
++	DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
++	DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled));
++	DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
++	DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
++	DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
++#ifdef CONFIG_HUGETLB_PAGE
++	DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
++	DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
++#endif /* CONFIG_HUGETLB_PAGE */
++	DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
++	DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
++	DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
++	DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
++	DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
++	DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
++	DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
++	DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
++
++	DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
++	DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
++	DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
++	DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
++#endif /* CONFIG_PPC64 */
++
++	/* RTAS */
++	DEFINE(RTASBASE, offsetof(struct rtas_t, base));
++	DEFINE(RTASENTRY, offsetof(struct rtas_t, entry));
++
++	/* Interrupt register frame */
++	DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
++#ifndef CONFIG_PPC64
++	DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
++#else /* CONFIG_PPC64 */
++	DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
++	/* 288 = # of volatile regs, int & fp, for leaf routines */
++	/* which do not stack a frame.  See the PPC64 ABI.       */
++	DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288);
++	/* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
++	DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
++	DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
++#endif /* CONFIG_PPC64 */
++	DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
++	DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
++	DEFINE(GPR2, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[2]));
++	DEFINE(GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[3]));
++	DEFINE(GPR4, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[4]));
++	DEFINE(GPR5, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[5]));
++	DEFINE(GPR6, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[6]));
++	DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7]));
++	DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8]));
++	DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9]));
++	DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10]));
++	DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11]));
++	DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12]));
++	DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13]));
++#ifndef CONFIG_PPC64
++	DEFINE(GPR14, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[14]));
++	DEFINE(GPR15, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[15]));
++	DEFINE(GPR16, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[16]));
++	DEFINE(GPR17, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[17]));
++	DEFINE(GPR18, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[18]));
++	DEFINE(GPR19, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[19]));
++	DEFINE(GPR20, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[20]));
++	DEFINE(GPR21, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[21]));
++	DEFINE(GPR22, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[22]));
++	DEFINE(GPR23, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[23]));
++	DEFINE(GPR24, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[24]));
++	DEFINE(GPR25, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[25]));
++	DEFINE(GPR26, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[26]));
++	DEFINE(GPR27, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[27]));
++	DEFINE(GPR28, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[28]));
++	DEFINE(GPR29, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[29]));
++	DEFINE(GPR30, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[30]));
++	DEFINE(GPR31, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[31]));
++#endif /* CONFIG_PPC64 */
++	/*
++	 * Note: these symbols include _ because they overlap with special
++	 * register names
++	 */
++	DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip));
++	DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr));
++	DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
++	DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link));
++	DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr));
++	DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
++	DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
++	DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
++	DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
++	DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
++	DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
++#ifndef CONFIG_PPC64
++	DEFINE(_MQ, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq));
++	/*
++	 * The PowerPC 400-class & Book-E processors have neither the DAR
++	 * nor the DSISR SPRs. Hence, we overload them to hold the similar
++	 * DEAR and ESR SPRs for such processors.  For critical interrupts
++	 * we use them to hold SRR0 and SRR1.
++	 */
++	DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
++	DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
++#else /* CONFIG_PPC64 */
++	DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
++
++	/* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */
++	DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs));
++	DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
++#endif /* CONFIG_PPC64 */
++
++	DEFINE(CLONE_VM, CLONE_VM);
++	DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
++
++#ifndef CONFIG_PPC64
++	DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
++#endif /* ! CONFIG_PPC64 */
++
++	/* About the CPU features table */
++	DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
++	DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
++	DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
++	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
++	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
++
++#ifndef CONFIG_PPC64
++	DEFINE(pbe_address, offsetof(struct pbe, address));
++	DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
++	DEFINE(pbe_next, offsetof(struct pbe, next));
++
++	DEFINE(TASK_SIZE, TASK_SIZE);
++	DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
++#else /* CONFIG_PPC64 */
++	/* systemcfg offsets for use by vdso */
++	DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp));
++	DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec));
++	DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs));
++	DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec));
++	DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count));
++	DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest));
++	DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime));
++	DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32));
++	DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64));
++
++	/* timeval/timezone offsets for use by vdso */
++	DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
++	DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
++	DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
++	DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
++	DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
++	DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
++#endif /* CONFIG_PPC64 */
++	return 0;
++}
+diff --git a/arch/powerpc/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/binfmt_elf32.c
+@@ -0,0 +1,75 @@
++/*
++ * binfmt_elf32.c: Support 32-bit PPC ELF binaries on Power3 and followons.
++ * based on the SPARC64 version.
++ * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller	(davem at redhat.com)
++ * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek	(jj at ultra.linux.cz)
++ *
++ * Copyright (C) 2000,2001 Ken Aaker (kdaaker at rchland.vnet.ibm.com), IBM Corp
++ * Copyright (C) 2001 Anton Blanchard (anton at au.ibm.com), 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.
++ */
++
++#define ELF_ARCH		EM_PPC
++#define ELF_CLASS		ELFCLASS32
++#define ELF_DATA		ELFDATA2MSB;
++
++#include <asm/processor.h>
++#include <linux/module.h>
++#include <linux/config.h>
++#include <linux/elfcore.h>
++#include <linux/compat.h>
++
++#define elf_prstatus elf_prstatus32
++struct elf_prstatus32
++{
++	struct elf_siginfo pr_info;	/* Info associated with signal */
++	short	pr_cursig;		/* Current signal */
++	unsigned int pr_sigpend;	/* Set of pending signals */
++	unsigned int pr_sighold;	/* Set of held signals */
++	pid_t	pr_pid;
++	pid_t	pr_ppid;
++	pid_t	pr_pgrp;
++	pid_t	pr_sid;
++	struct compat_timeval pr_utime;	/* User time */
++	struct compat_timeval pr_stime;	/* System time */
++	struct compat_timeval pr_cutime;	/* Cumulative user time */
++	struct compat_timeval pr_cstime;	/* Cumulative system time */
++	elf_gregset_t pr_reg;		/* General purpose registers. */
++	int pr_fpvalid;		/* True if math co-processor being used. */
++};
++
++#define elf_prpsinfo elf_prpsinfo32
++struct elf_prpsinfo32
++{
++	char	pr_state;	/* numeric process state */
++	char	pr_sname;	/* char for pr_state */
++	char	pr_zomb;	/* zombie */
++	char	pr_nice;	/* nice val */
++	unsigned int pr_flag;	/* flags */
++	u32	pr_uid;
++	u32	pr_gid;
++	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
++	/* Lots missing */
++	char	pr_fname[16];	/* filename of executable */
++	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
++};
++
++#include <linux/time.h>
++
++#undef cputime_to_timeval
++#define cputime_to_timeval cputime_to_compat_timeval
++static __inline__ void
++cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
++{
++	unsigned long jiffies = cputime_to_jiffies(cputime);
++	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
++	value->tv_sec = jiffies / HZ;
++}
++
++#define init_elf_binfmt init_elf32_binfmt
++
++#include "../../../fs/binfmt_elf.c"
+diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/btext.c
+@@ -0,0 +1,853 @@
++/*
++ * Procedures for drawing on the screen early on in the boot process.
++ *
++ * Benjamin Herrenschmidt <benh at kernel.crashing.org>
++ */
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/module.h>
++
++#include <asm/sections.h>
++#include <asm/prom.h>
++#include <asm/btext.h>
++#include <asm/prom.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/pgtable.h>
++#include <asm/io.h>
++#include <asm/lmb.h>
++#include <asm/processor.h>
++
++#define NO_SCROLL
++
++#ifndef NO_SCROLL
++static void scrollscreen(void);
++#endif
++
++static void draw_byte(unsigned char c, long locX, long locY);
++static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
++static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
++static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
++
++static int g_loc_X;
++static int g_loc_Y;
++static int g_max_loc_X;
++static int g_max_loc_Y;
++
++static int dispDeviceRowBytes;
++static int dispDeviceDepth;
++static int dispDeviceRect[4];
++static unsigned char *dispDeviceBase, *logicalDisplayBase;
++
++unsigned long disp_BAT[2] __initdata = {0, 0};
++
++#define cmapsz	(16*256)
++
++static unsigned char vga_font[cmapsz];
++
++int boot_text_mapped;
++int force_printk_to_btext = 0;
++
++#ifdef CONFIG_PPC32
++/* Calc BAT values for mapping the display and store them
++ * in disp_BAT.  Those values are then used from head.S to map
++ * the display during identify_machine() and MMU_Init()
++ *
++ * The display is mapped to virtual address 0xD0000000, rather
++ * than 1:1, because some some CHRP machines put the frame buffer
++ * in the region starting at 0xC0000000 (KERNELBASE).
++ * This mapping is temporary and will disappear as soon as the
++ * setup done by MMU_Init() is applied.
++ *
++ * For now, we align the BAT and then map 8Mb on 601 and 16Mb
++ * on other PPCs. This may cause trouble if the framebuffer
++ * is really badly aligned, but I didn't encounter this case
++ * yet.
++ */
++void __init
++btext_prepare_BAT(void)
++{
++	unsigned long vaddr = KERNELBASE + 0x10000000;
++	unsigned long addr;
++	unsigned long lowbits;
++
++	addr = (unsigned long)dispDeviceBase;
++	if (!addr) {
++		boot_text_mapped = 0;
++		return;
++	}
++	if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
++		/* 603, 604, G3, G4, ... */
++		lowbits = addr & ~0xFF000000UL;
++		addr &= 0xFF000000UL;
++		disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
++		disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);	
++	} else {
++		/* 601 */
++		lowbits = addr & ~0xFF800000UL;
++		addr &= 0xFF800000UL;
++		disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
++		disp_BAT[1] = addr | BL_8M | 0x40;
++	}
++	logicalDisplayBase = (void *) (vaddr + lowbits);
++}
++#endif
++
++/* This function will enable the early boot text when doing OF booting. This
++ * way, xmon output should work too
++ */
++void __init
++btext_setup_display(int width, int height, int depth, int pitch,
++		    unsigned long address)
++{
++	g_loc_X = 0;
++	g_loc_Y = 0;
++	g_max_loc_X = width / 8;
++	g_max_loc_Y = height / 16;
++	logicalDisplayBase = (unsigned char *)address;
++	dispDeviceBase = (unsigned char *)address;
++	dispDeviceRowBytes = pitch;
++	dispDeviceDepth = depth;
++	dispDeviceRect[0] = dispDeviceRect[1] = 0;
++	dispDeviceRect[2] = width;
++	dispDeviceRect[3] = height;
++	boot_text_mapped = 1;
++}
++
++/* Here's a small text engine to use during early boot
++ * or for debugging purposes
++ *
++ * todo:
++ *
++ *  - build some kind of vgacon with it to enable early printk
++ *  - move to a separate file
++ *  - add a few video driver hooks to keep in sync with display
++ *    changes.
++ */
++
++void map_boot_text(void)
++{
++	unsigned long base, offset, size;
++	unsigned char *vbase;
++
++	/* By default, we are no longer mapped */
++	boot_text_mapped = 0;
++	if (dispDeviceBase == 0)
++		return;
++	base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
++	offset = ((unsigned long) dispDeviceBase) - base;
++	size = dispDeviceRowBytes * dispDeviceRect[3] + offset
++		+ dispDeviceRect[0];
++	vbase = __ioremap(base, size, _PAGE_NO_CACHE);
++	if (vbase == 0)
++		return;
++	logicalDisplayBase = vbase + offset;
++	boot_text_mapped = 1;
++}
++
++int btext_initialize(struct device_node *np)
++{
++	unsigned int width, height, depth, pitch;
++	unsigned long address = 0;
++	u32 *prop;
++
++	prop = (u32 *)get_property(np, "width", NULL);
++	if (prop == NULL)
++		return -EINVAL;
++	width = *prop;
++	prop = (u32 *)get_property(np, "height", NULL);
++	if (prop == NULL)
++		return -EINVAL;
++	height = *prop;
++	prop = (u32 *)get_property(np, "depth", NULL);
++	if (prop == NULL)
++		return -EINVAL;
++	depth = *prop;
++	pitch = width * ((depth + 7) / 8);
++	prop = (u32 *)get_property(np, "linebytes", NULL);
++	if (prop)
++		pitch = *prop;
++	if (pitch == 1)
++		pitch = 0x1000;
++	prop = (u32 *)get_property(np, "address", NULL);
++	if (prop)
++		address = *prop;
++
++	/* FIXME: Add support for PCI reg properties */
++
++	if (address == 0)
++		return -EINVAL;
++
++	g_loc_X = 0;
++	g_loc_Y = 0;
++	g_max_loc_X = width / 8;
++	g_max_loc_Y = height / 16;
++	logicalDisplayBase = (unsigned char *)address;
++	dispDeviceBase = (unsigned char *)address;
++	dispDeviceRowBytes = pitch;
++	dispDeviceDepth = depth;
++	dispDeviceRect[0] = dispDeviceRect[1] = 0;
++	dispDeviceRect[2] = width;
++	dispDeviceRect[3] = height;
++
++	map_boot_text();
++
++	return 0;
++}
++
++void __init init_boot_display(void)
++{
++	char *name;
++	struct device_node *np = NULL; 
++	int rc = -ENODEV;
++
++	printk("trying to initialize btext ...\n");
++
++	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
++	if (name != NULL) {
++		np = of_find_node_by_path(name);
++		if (np != NULL) {
++			if (strcmp(np->type, "display") != 0) {
++				printk("boot stdout isn't a display !\n");
++				of_node_put(np);
++				np = NULL;
++			}
++		}
++	}
++	if (np)
++		rc = btext_initialize(np);
++	if (rc == 0)
++		return;
++
++	for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
++		if (get_property(np, "linux,opened", NULL)) {
++			printk("trying %s ...\n", np->full_name);
++			rc = btext_initialize(np);
++			printk("result: %d\n", rc);
++		}
++		if (rc == 0)
++			return;
++	}
++}
++
++/* Calc the base address of a given point (x,y) */
++static unsigned char * calc_base(int x, int y)
++{
++	unsigned char *base;
++
++	base = logicalDisplayBase;
++	if (base == 0)
++		base = dispDeviceBase;
++	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
++	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
++	return base;
++}
++
++/* Adjust the display to a new resolution */
++void btext_update_display(unsigned long phys, int width, int height,
++			  int depth, int pitch)
++{
++	if (dispDeviceBase == 0)
++		return;
++
++	/* check it's the same frame buffer (within 256MB) */
++	if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
++		return;
++
++	dispDeviceBase = (__u8 *) phys;
++	dispDeviceRect[0] = 0;
++	dispDeviceRect[1] = 0;
++	dispDeviceRect[2] = width;
++	dispDeviceRect[3] = height;
++	dispDeviceDepth = depth;
++	dispDeviceRowBytes = pitch;
++	if (boot_text_mapped) {
++		iounmap(logicalDisplayBase);
++		boot_text_mapped = 0;
++	}
++	map_boot_text();
++	g_loc_X = 0;
++	g_loc_Y = 0;
++	g_max_loc_X = width / 8;
++	g_max_loc_Y = height / 16;
++}
++EXPORT_SYMBOL(btext_update_display);
++
++void btext_clearscreen(void)
++{
++	unsigned long *base	= (unsigned long *)calc_base(0, 0);
++	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
++					(dispDeviceDepth >> 3)) >> 3;
++	int i,j;
++
++	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
++	{
++		unsigned long *ptr = base;
++		for(j=width; j; --j)
++			*(ptr++) = 0;
++		base += (dispDeviceRowBytes >> 3);
++	}
++}
++
++#ifndef NO_SCROLL
++static void scrollscreen(void)
++{
++	unsigned long *src     	= (unsigned long *)calc_base(0,16);
++	unsigned long *dst     	= (unsigned long *)calc_base(0,0);
++	unsigned long width    	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
++				   (dispDeviceDepth >> 3)) >> 3;
++	int i,j;
++
++	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
++	{
++		unsigned long *src_ptr = src;
++		unsigned long *dst_ptr = dst;
++		for(j=width; j; --j)
++			*(dst_ptr++) = *(src_ptr++);
++		src += (dispDeviceRowBytes >> 3);
++		dst += (dispDeviceRowBytes >> 3);
++	}
++	for (i=0; i<16; i++)
++	{
++		unsigned long *dst_ptr = dst;
++		for(j=width; j; --j)
++			*(dst_ptr++) = 0;
++		dst += (dispDeviceRowBytes >> 3);
++	}
++}
++#endif /* ndef NO_SCROLL */
++
++void btext_drawchar(char c)
++{
++	int cline = 0;
++#ifdef NO_SCROLL
++	int x;
++#endif
++	if (!boot_text_mapped)
++		return;
++
++	switch (c) {
++	case '\b':
++		if (g_loc_X > 0)
++			--g_loc_X;
++		break;
++	case '\t':
++		g_loc_X = (g_loc_X & -8) + 8;
++		break;
++	case '\r':
++		g_loc_X = 0;
++		break;
++	case '\n':
++		g_loc_X = 0;
++		g_loc_Y++;
++		cline = 1;
++		break;
++	default:
++		draw_byte(c, g_loc_X++, g_loc_Y);
++	}
++	if (g_loc_X >= g_max_loc_X) {
++		g_loc_X = 0;
++		g_loc_Y++;
++		cline = 1;
++	}
++#ifndef NO_SCROLL
++	while (g_loc_Y >= g_max_loc_Y) {
++		scrollscreen();
++		g_loc_Y--;
++	}
++#else
++	/* wrap around from bottom to top of screen so we don't
++	   waste time scrolling each line.  -- paulus. */
++	if (g_loc_Y >= g_max_loc_Y)
++		g_loc_Y = 0;
++	if (cline) {
++		for (x = 0; x < g_max_loc_X; ++x)
++			draw_byte(' ', x, g_loc_Y);
++	}
++#endif
++}
++
++void btext_drawstring(const char *c)
++{
++	if (!boot_text_mapped)
++		return;
++	while (*c)
++		btext_drawchar(*c++);
++}
++
++void btext_drawhex(unsigned long v)
++{
++	char *hex_table = "0123456789abcdef";
++
++	if (!boot_text_mapped)
++		return;
++#ifdef CONFIG_PPC64
++	btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]);
++#endif
++	btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >>  8) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >>  4) & 0x0000000FUL]);
++	btext_drawchar(hex_table[(v >>  0) & 0x0000000FUL]);
++	btext_drawchar(' ');
++}
++
++static void draw_byte(unsigned char c, long locX, long locY)
++{
++	unsigned char *base	= calc_base(locX << 3, locY << 4);
++	unsigned char *font	= &vga_font[((unsigned int)c) * 16];
++	int rb			= dispDeviceRowBytes;
++
++	switch(dispDeviceDepth) {
++	case 24:
++	case 32:
++		draw_byte_32(font, (unsigned int *)base, rb);
++		break;
++	case 15:
++	case 16:
++		draw_byte_16(font, (unsigned int *)base, rb);
++		break;
++	case 8:
++		draw_byte_8(font, (unsigned int *)base, rb);
++		break;
++	}
++}
++
++static unsigned int expand_bits_8[16] = {
++	0x00000000,
++	0x000000ff,
++	0x0000ff00,
++	0x0000ffff,
++	0x00ff0000,
++	0x00ff00ff,
++	0x00ffff00,
++	0x00ffffff,
++	0xff000000,
++	0xff0000ff,
++	0xff00ff00,
++	0xff00ffff,
++	0xffff0000,
++	0xffff00ff,
++	0xffffff00,
++	0xffffffff
++};
++
++static unsigned int expand_bits_16[4] = {
++	0x00000000,
++	0x0000ffff,
++	0xffff0000,
++	0xffffffff
++};
++
++
++static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
++{
++	int l, bits;
++	int fg = 0xFFFFFFFFUL;
++	int bg = 0x00000000UL;
++
++	for (l = 0; l < 16; ++l)
++	{
++		bits = *font++;
++		base[0] = (-(bits >> 7) & fg) ^ bg;
++		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
++		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
++		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
++		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
++		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
++		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
++		base[7] = (-(bits & 1) & fg) ^ bg;
++		base = (unsigned int *) ((char *)base + rb);
++	}
++}
++
++static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
++{
++	int l, bits;
++	int fg = 0xFFFFFFFFUL;
++	int bg = 0x00000000UL;
++	unsigned int *eb = (int *)expand_bits_16;
++
++	for (l = 0; l < 16; ++l)
++	{
++		bits = *font++;
++		base[0] = (eb[bits >> 6] & fg) ^ bg;
++		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
++		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
++		base[3] = (eb[bits & 3] & fg) ^ bg;
++		base = (unsigned int *) ((char *)base + rb);
++	}
++}
++
++static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
++{
++	int l, bits;
++	int fg = 0x0F0F0F0FUL;
++	int bg = 0x00000000UL;
++	unsigned int *eb = (int *)expand_bits_8;
++
++	for (l = 0; l < 16; ++l)
++	{
++		bits = *font++;
++		base[0] = (eb[bits >> 4] & fg) ^ bg;
++		base[1] = (eb[bits & 0xf] & fg) ^ bg;
++		base = (unsigned int *) ((char *)base + rb);
++	}
++}
++
++static unsigned char vga_font[cmapsz] = {
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
++0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
++0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
++0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
++0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
++0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
++0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
++0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
++0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
++0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
++0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
++0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
++0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
++0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
++0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
++0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
++0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
++0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
++0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
++0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
++0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
++0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
++0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
++0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
++0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
++0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
++0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
++0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
++0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
++0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
++0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
++0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
++0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
++0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
++0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
++0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
++0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
++0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
++0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
++0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
++0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
++0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
++0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
++0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
++0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
++0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
++0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
++0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
++0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
++0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
++0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
++0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
++0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
++0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
++0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
++0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
++0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
++0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
++0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
++0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
++0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
++0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
++0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
++0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
++0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
++0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
++0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
++0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
++0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
++0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
++0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
++0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
++0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
++0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
++0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
++0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
++0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
++0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
++0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
++0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
++0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
++0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
++0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
++0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
++0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
++0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
++0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
++0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
++0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
++0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
++0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
++0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
++0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
++0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
++0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
++0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
++0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
++0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
++0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
++0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
++0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
++0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
++0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
++0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
++0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
++0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
++0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
++0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
++0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
++0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
++0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
++0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
++0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
++0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
++0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
++0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
++0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
++0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
++0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
++0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
++0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
++0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
++0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
++0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
++0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
++0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
++0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
++0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
++0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
++0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
++0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
++0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
++0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
++0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
++0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
++0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
++0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
++0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
++0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
++0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
++0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00,
++};
+diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/cputable.c
+@@ -0,0 +1,996 @@
++/*
++ *  Copyright (C) 2001 Ben. Herrenschmidt (benh at kernel.crashing.org)
++ *
++ *  Modifications for ppc64:
++ *      Copyright (C) 2003 Dave Engebretsen <engebret at 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 <linux/config.h>
++#include <linux/string.h>
++#include <linux/sched.h>
++#include <linux/threads.h>
++#include <linux/init.h>
++#include <linux/module.h>
++
++#include <asm/oprofile_impl.h>
++#include <asm/cputable.h>
++
++struct cpu_spec* cur_cpu_spec = NULL;
++EXPORT_SYMBOL(cur_cpu_spec);
++
++/* NOTE:
++ * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's
++ * the responsibility of the appropriate CPU save/restore functions to
++ * eventually copy these settings over. Those save/restore aren't yet
++ * part of the cputable though. That has to be fixed for both ppc32
++ * and ppc64
++ */
++#ifdef CONFIG_PPC64
++extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
++#else
++extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_750cx(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_750fx(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
++#endif /* CONFIG_PPC32 */
++extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
++
++/* This table only contains "desktop" CPUs, it need to be filled with embedded
++ * ones as well...
++ */
++#define COMMON_USER		(PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
++				 PPC_FEATURE_HAS_MMU)
++#define COMMON_USER_PPC64	(COMMON_USER | PPC_FEATURE_64)
++
++
++/* We only set the spe features if the kernel was compiled with
++ * spe support
++ */
++#ifdef CONFIG_SPE
++#define PPC_FEATURE_SPE_COMP	PPC_FEATURE_HAS_SPE
++#else
++#define PPC_FEATURE_SPE_COMP	0
++#endif
++
++struct cpu_spec	cpu_specs[] = {
++#ifdef CONFIG_PPC64
++	{	/* Power3 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00400000,
++		.cpu_name		= "POWER3 (630)",
++		.cpu_features		= CPU_FTRS_POWER3,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_power3,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/power3",
++		.oprofile_model		= &op_model_rs64,
++#endif
++	},
++	{	/* Power3+ */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00410000,
++		.cpu_name		= "POWER3 (630+)",
++		.cpu_features		= CPU_FTRS_POWER3,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_power3,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/power3",
++		.oprofile_model		= &op_model_rs64,
++#endif
++	},
++	{	/* Northstar */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00330000,
++		.cpu_name		= "RS64-II (northstar)",
++		.cpu_features		= CPU_FTRS_RS64,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_power3,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/rs64",
++		.oprofile_model		= &op_model_rs64,
++#endif
++	},
++	{	/* Pulsar */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00340000,
++		.cpu_name		= "RS64-III (pulsar)",
++		.cpu_features		= CPU_FTRS_RS64,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_power3,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/rs64",
++		.oprofile_model		= &op_model_rs64,
++#endif
++	},
++	{	/* I-star */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00360000,
++		.cpu_name		= "RS64-III (icestar)",
++		.cpu_features		= CPU_FTRS_RS64,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_power3,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/rs64",
++		.oprofile_model		= &op_model_rs64,
++#endif
++	},
++	{	/* S-star */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00370000,
++		.cpu_name		= "RS64-IV (sstar)",
++		.cpu_features		= CPU_FTRS_RS64,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_power3,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/rs64",
++		.oprofile_model		= &op_model_rs64,
++#endif
++	},
++	{	/* Power4 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00350000,
++		.cpu_name		= "POWER4 (gp)",
++		.cpu_features		= CPU_FTRS_POWER4,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_power4,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/power4",
++		.oprofile_model		= &op_model_rs64,
++#endif
++	},
++	{	/* Power4+ */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00380000,
++		.cpu_name		= "POWER4+ (gq)",
++		.cpu_features		= CPU_FTRS_POWER4,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_power4,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/power4",
++		.oprofile_model		= &op_model_power4,
++#endif
++	},
++	{	/* PPC970 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00390000,
++		.cpu_name		= "PPC970",
++		.cpu_features		= CPU_FTRS_PPC970,
++		.cpu_user_features	= COMMON_USER_PPC64 |
++			PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_ppc970,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/970",
++		.oprofile_model		= &op_model_power4,
++#endif
++	},
++#endif /* CONFIG_PPC64 */
++#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4)
++	{	/* PPC970FX */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x003c0000,
++		.cpu_name		= "PPC970FX",
++#ifdef CONFIG_PPC32
++		.cpu_features		= CPU_FTRS_970_32,
++#else
++		.cpu_features		= CPU_FTRS_PPC970,
++#endif
++		.cpu_user_features	= COMMON_USER_PPC64 |
++			PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 8,
++		.cpu_setup		= __setup_cpu_ppc970,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/970",
++		.oprofile_model		= &op_model_power4,
++#endif
++	},
++#endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */
++#ifdef CONFIG_PPC64
++	{	/* PPC970MP */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00440000,
++		.cpu_name		= "PPC970MP",
++		.cpu_features		= CPU_FTRS_PPC970,
++		.cpu_user_features	= COMMON_USER_PPC64 |
++			PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.cpu_setup		= __setup_cpu_ppc970,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/970",
++		.oprofile_model		= &op_model_power4,
++#endif
++	},
++	{	/* Power5 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x003a0000,
++		.cpu_name		= "POWER5 (gr)",
++		.cpu_features		= CPU_FTRS_POWER5,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_power4,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/power5",
++		.oprofile_model		= &op_model_power4,
++#endif
++	},
++	{	/* Power5 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x003b0000,
++		.cpu_name		= "POWER5 (gs)",
++		.cpu_features		= CPU_FTRS_POWER5,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_power4,
++#ifdef CONFIG_OPROFILE
++		.oprofile_cpu_type	= "ppc64/power5",
++		.oprofile_model		= &op_model_power4,
++#endif
++	},
++	{	/* BE DD1.x */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00700000,
++		.cpu_name		= "Cell Broadband Engine",
++		.cpu_features		= CPU_FTRS_CELL,
++		.cpu_user_features	= COMMON_USER_PPC64 |
++			PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.cpu_setup		= __setup_cpu_be,
++	},
++	{	/* default match */
++		.pvr_mask		= 0x00000000,
++		.pvr_value		= 0x00000000,
++		.cpu_name		= "POWER4 (compatible)",
++		.cpu_features		= CPU_FTRS_COMPATIBLE,
++		.cpu_user_features	= COMMON_USER_PPC64,
++		.icache_bsize		= 128,
++		.dcache_bsize		= 128,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_power4,
++	}
++#endif	/* CONFIG_PPC64 */
++#ifdef CONFIG_PPC32
++#if CLASSIC_PPC
++	{	/* 601 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00010000,
++		.cpu_name		= "601",
++		.cpu_features		= CPU_FTRS_PPC601,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_601_INSTR |
++			PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* 603 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00030000,
++		.cpu_name		= "603",
++		.cpu_features		= CPU_FTRS_603,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_603
++	},
++	{	/* 603e */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00060000,
++		.cpu_name		= "603e",
++		.cpu_features		= CPU_FTRS_603,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_603
++	},
++	{	/* 603ev */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00070000,
++		.cpu_name		= "603ev",
++		.cpu_features		= CPU_FTRS_603,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_603
++	},
++	{	/* 604 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00040000,
++		.cpu_name		= "604",
++		.cpu_features		= CPU_FTRS_604,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 2,
++		.cpu_setup		= __setup_cpu_604
++	},
++	{	/* 604e */
++		.pvr_mask		= 0xfffff000,
++		.pvr_value		= 0x00090000,
++		.cpu_name		= "604e",
++		.cpu_features		= CPU_FTRS_604,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_604
++	},
++	{	/* 604r */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00090000,
++		.cpu_name		= "604r",
++		.cpu_features		= CPU_FTRS_604,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_604
++	},
++	{	/* 604ev */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x000a0000,
++		.cpu_name		= "604ev",
++		.cpu_features		= CPU_FTRS_604,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_604
++	},
++	{	/* 740/750 (0x4202, don't support TAU ?) */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x00084202,
++		.cpu_name		= "740/750",
++		.cpu_features		= CPU_FTRS_740_NOTAU,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750
++	},
++	{	/* 750CX (80100 and 8010x?) */
++		.pvr_mask		= 0xfffffff0,
++		.pvr_value		= 0x00080100,
++		.cpu_name		= "750CX",
++		.cpu_features		= CPU_FTRS_750,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750cx
++	},
++	{	/* 750CX (82201 and 82202) */
++		.pvr_mask		= 0xfffffff0,
++		.pvr_value		= 0x00082200,
++		.cpu_name		= "750CX",
++		.cpu_features		= CPU_FTRS_750,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750cx
++	},
++	{	/* 750CXe (82214) */
++		.pvr_mask		= 0xfffffff0,
++		.pvr_value		= 0x00082210,
++		.cpu_name		= "750CXe",
++		.cpu_features		= CPU_FTRS_750,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750cx
++	},
++	{	/* 750CXe "Gekko" (83214) */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x00083214,
++		.cpu_name		= "750CXe",
++		.cpu_features		= CPU_FTRS_750,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750cx
++	},
++	{	/* 745/755 */
++		.pvr_mask		= 0xfffff000,
++		.pvr_value		= 0x00083000,
++		.cpu_name		= "745/755",
++		.cpu_features		= CPU_FTRS_750,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750
++	},
++	{	/* 750FX rev 1.x */
++		.pvr_mask		= 0xffffff00,
++		.pvr_value		= 0x70000100,
++		.cpu_name		= "750FX",
++		.cpu_features		= CPU_FTRS_750FX1,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750
++	},
++	{	/* 750FX rev 2.0 must disable HID0[DPM] */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x70000200,
++		.cpu_name		= "750FX",
++		.cpu_features		= CPU_FTRS_750FX2,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750
++	},
++	{	/* 750FX (All revs except 2.0) */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x70000000,
++		.cpu_name		= "750FX",
++		.cpu_features		= CPU_FTRS_750FX,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750fx
++	},
++	{	/* 750GX */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x70020000,
++		.cpu_name		= "750GX",
++		.cpu_features		= CPU_FTRS_750GX,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750fx
++	},
++	{	/* 740/750 (L2CR bit need fixup for 740) */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00080000,
++		.cpu_name		= "740/750",
++		.cpu_features		= CPU_FTRS_740,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750
++	},
++	{	/* 7400 rev 1.1 ? (no TAU) */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x000c1101,
++		.cpu_name		= "7400 (1.1)",
++		.cpu_features		= CPU_FTRS_7400_NOTAU,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_7400
++	},
++	{	/* 7400 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x000c0000,
++		.cpu_name		= "7400",
++		.cpu_features		= CPU_FTRS_7400,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_7400
++	},
++	{	/* 7410 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x800c0000,
++		.cpu_name		= "7410",
++		.cpu_features		= CPU_FTRS_7400,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_7410
++	},
++	{	/* 7450 2.0 - no doze/nap */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x80000200,
++		.cpu_name		= "7450",
++		.cpu_features		= CPU_FTRS_7450_20,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7450 2.1 */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x80000201,
++		.cpu_name		= "7450",
++		.cpu_features		= CPU_FTRS_7450_21,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7450 2.3 and newer */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x80000000,
++		.cpu_name		= "7450",
++		.cpu_features		= CPU_FTRS_7450_23,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7455 rev 1.x */
++		.pvr_mask		= 0xffffff00,
++		.pvr_value		= 0x80010100,
++		.cpu_name		= "7455",
++		.cpu_features		= CPU_FTRS_7455_1,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7455 rev 2.0 */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x80010200,
++		.cpu_name		= "7455",
++		.cpu_features		= CPU_FTRS_7455_20,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7455 others */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x80010000,
++		.cpu_name		= "7455",
++		.cpu_features		= CPU_FTRS_7455,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7447/7457 Rev 1.0 */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x80020100,
++		.cpu_name		= "7447/7457",
++		.cpu_features		= CPU_FTRS_7447_10,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7447/7457 Rev 1.1 */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x80020101,
++		.cpu_name		= "7447/7457",
++		.cpu_features		= CPU_FTRS_7447_10,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7447/7457 Rev 1.2 and later */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x80020000,
++		.cpu_name		= "7447/7457",
++		.cpu_features		= CPU_FTRS_7447,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7447A */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x80030000,
++		.cpu_name		= "7447A",
++		.cpu_features		= CPU_FTRS_7447A,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 7448 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x80040000,
++		.cpu_name		= "7448",
++		.cpu_features		= CPU_FTRS_7447A,
++		.cpu_user_features	= COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 6,
++		.cpu_setup		= __setup_cpu_745x
++	},
++	{	/* 82xx (8240, 8245, 8260 are all 603e cores) */
++		.pvr_mask		= 0x7fff0000,
++		.pvr_value		= 0x00810000,
++		.cpu_name		= "82xx",
++		.cpu_features		= CPU_FTRS_82XX,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_603
++	},
++	{	/* All G2_LE (603e core, plus some) have the same pvr */
++		.pvr_mask		= 0x7fff0000,
++		.pvr_value		= 0x00820000,
++		.cpu_name		= "G2_LE",
++		.cpu_features		= CPU_FTRS_G2_LE,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_603
++	},
++	{	/* e300 (a 603e core, plus some) on 83xx */
++		.pvr_mask		= 0x7fff0000,
++		.pvr_value		= 0x00830000,
++		.cpu_name		= "e300",
++		.cpu_features		= CPU_FTRS_E300,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_603
++	},
++	{	/* default match, we assume split I/D cache & TB (non-601)... */
++		.pvr_mask		= 0x00000000,
++		.pvr_value		= 0x00000000,
++		.cpu_name		= "(generic PPC)",
++		.cpu_features		= CPU_FTRS_CLASSIC32,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++#endif /* CLASSIC_PPC */
++#ifdef CONFIG_8xx
++	{	/* 8xx */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00500000,
++		.cpu_name		= "8xx",
++		/* CPU_FTR_MAYBE_CAN_DOZE is possible,
++		 * if the 8xx code is there.... */
++		.cpu_features		= CPU_FTRS_8XX,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 16,
++		.dcache_bsize		= 16,
++	},
++#endif /* CONFIG_8xx */
++#ifdef CONFIG_40x
++	{	/* 403GC */
++		.pvr_mask		= 0xffffff00,
++		.pvr_value		= 0x00200200,
++		.cpu_name		= "403GC",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 16,
++		.dcache_bsize		= 16,
++	},
++	{	/* 403GCX */
++		.pvr_mask		= 0xffffff00,
++		.pvr_value		= 0x00201400,
++		.cpu_name		= "403GCX",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++		 	PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
++		.icache_bsize		= 16,
++		.dcache_bsize		= 16,
++	},
++	{	/* 403G ?? */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x00200000,
++		.cpu_name		= "403G ??",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 16,
++		.dcache_bsize		= 16,
++	},
++	{	/* 405GP */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x40110000,
++		.cpu_name		= "405GP",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* STB 03xxx */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x40130000,
++		.cpu_name		= "STB03xxx",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* STB 04xxx */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x41810000,
++		.cpu_name		= "STB04xxx",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* NP405L */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x41610000,
++		.cpu_name		= "NP405L",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* NP4GS3 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x40B10000,
++		.cpu_name		= "NP4GS3",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{   /* NP405H */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x41410000,
++		.cpu_name		= "NP405H",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* 405GPr */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x50910000,
++		.cpu_name		= "405GPr",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{   /* STBx25xx */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x51510000,
++		.cpu_name		= "STBx25xx",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* 405LP */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x41F10000,
++		.cpu_name		= "405LP",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* Xilinx Virtex-II Pro  */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x20010000,
++		.cpu_name		= "Virtex-II Pro",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* 405EP */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x51210000,
++		.cpu_name		= "405EP",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++
++#endif /* CONFIG_40x */
++#ifdef CONFIG_44x
++	{
++		.pvr_mask		= 0xf0000fff,
++		.pvr_value		= 0x40000850,
++		.cpu_name		= "440EP Rev. A",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= COMMON_USER, /* 440EP has an FPU */
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{
++		.pvr_mask		= 0xf0000fff,
++		.pvr_value		= 0x400008d3,
++		.cpu_name		= "440EP Rev. B",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= COMMON_USER, /* 440EP has an FPU */
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* 440GP Rev. B */
++		.pvr_mask		= 0xf0000fff,
++		.pvr_value		= 0x40000440,
++		.cpu_name		= "440GP Rev. B",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{	/* 440GP Rev. C */
++		.pvr_mask		= 0xf0000fff,
++		.pvr_value		= 0x40000481,
++		.cpu_name		= "440GP Rev. C",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{ /* 440GX Rev. A */
++		.pvr_mask		= 0xf0000fff,
++		.pvr_value		= 0x50000850,
++		.cpu_name		= "440GX Rev. A",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{ /* 440GX Rev. B */
++		.pvr_mask		= 0xf0000fff,
++		.pvr_value		= 0x50000851,
++		.cpu_name		= "440GX Rev. B",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{ /* 440GX Rev. C */
++		.pvr_mask		= 0xf0000fff,
++		.pvr_value		= 0x50000892,
++		.cpu_name		= "440GX Rev. C",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{ /* 440GX Rev. F */
++		.pvr_mask		= 0xf0000fff,
++		.pvr_value		= 0x50000894,
++		.cpu_name		= "440GX Rev. F",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++	{ /* 440SP Rev. A */
++		.pvr_mask		= 0xff000fff,
++		.pvr_value		= 0x53000891,
++		.cpu_name		= "440SP Rev. A",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	},
++#endif /* CONFIG_44x */
++#ifdef CONFIG_FSL_BOOKE
++	{	/* e200z5 */
++		.pvr_mask		= 0xfff00000,
++		.pvr_value		= 0x81000000,
++		.cpu_name		= "e200z5",
++		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
++		.cpu_features		= CPU_FTRS_E200,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE |
++			PPC_FEATURE_UNIFIED_CACHE,
++		.dcache_bsize		= 32,
++	},
++	{	/* e200z6 */
++		.pvr_mask		= 0xfff00000,
++		.pvr_value		= 0x81100000,
++		.cpu_name		= "e200z6",
++		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
++		.cpu_features		= CPU_FTRS_E200,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
++			PPC_FEATURE_HAS_EFP_SINGLE |
++			PPC_FEATURE_UNIFIED_CACHE,
++		.dcache_bsize		= 32,
++	},
++	{	/* e500 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x80200000,
++		.cpu_name		= "e500",
++		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
++		.cpu_features		= CPU_FTRS_E500,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
++			PPC_FEATURE_HAS_EFP_SINGLE,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++	},
++	{	/* e500v2 */
++		.pvr_mask		= 0xffff0000,
++		.pvr_value		= 0x80210000,
++		.cpu_name		= "e500v2",
++		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
++		.cpu_features		= CPU_FTRS_E500_2,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
++			PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++	},
++#endif
++#if !CLASSIC_PPC
++	{	/* default match */
++		.pvr_mask		= 0x00000000,
++		.pvr_value		= 0x00000000,
++		.cpu_name		= "(generic PPC)",
++		.cpu_features		= CPU_FTRS_GENERIC_32,
++		.cpu_user_features	= PPC_FEATURE_32,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++	}
++#endif /* !CLASSIC_PPC */
++#endif /* CONFIG_PPC32 */
++};
+diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/entry_32.S
+@@ -0,0 +1,1000 @@
++/*
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *  Rewritten by Cort Dougan (cort at fsmlabs.com) for PReP
++ *    Copyright (C) 1996 Cort Dougan <cort at fsmlabs.com>
++ *  Adapted for Power Macintosh by Paul Mackerras.
++ *  Low-level exception handlers and MMU support
++ *  rewritten by Paul Mackerras.
++ *    Copyright (C) 1996 Paul Mackerras.
++ *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek at jlc.net).
++ *
++ *  This file contains the system call entry code, context switch
++ *  code, and exception/interrupt return code for PowerPC.
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/errno.h>
++#include <linux/sys.h>
++#include <linux/threads.h>
++#include <asm/reg.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/cputable.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++#include <asm/unistd.h>
++
++#undef SHOW_SYSCALLS
++#undef SHOW_SYSCALLS_TASK
++
++/*
++ * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
++ */
++#if MSR_KERNEL >= 0x10000
++#define LOAD_MSR_KERNEL(r, x)	lis r,(x)@h; ori r,r,(x)@l
++#else
++#define LOAD_MSR_KERNEL(r, x)	li r,(x)
++#endif
++
++#ifdef CONFIG_BOOKE
++#include "head_booke.h"
++#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level)	\
++	mtspr	exc_level##_SPRG,r8;			\
++	BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);		\
++	lwz	r0,GPR10-INT_FRAME_SIZE(r8);		\
++	stw	r0,GPR10(r11);				\
++	lwz	r0,GPR11-INT_FRAME_SIZE(r8);		\
++	stw	r0,GPR11(r11);				\
++	mfspr	r8,exc_level##_SPRG
++
++	.globl	mcheck_transfer_to_handler
++mcheck_transfer_to_handler:
++	TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
++	b	transfer_to_handler_full
++
++	.globl	debug_transfer_to_handler
++debug_transfer_to_handler:
++	TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
++	b	transfer_to_handler_full
++
++	.globl	crit_transfer_to_handler
++crit_transfer_to_handler:
++	TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
++	/* fall through */
++#endif
++
++#ifdef CONFIG_40x
++	.globl	crit_transfer_to_handler
++crit_transfer_to_handler:
++	lwz	r0,crit_r10 at l(0)
++	stw	r0,GPR10(r11)
++	lwz	r0,crit_r11 at l(0)
++	stw	r0,GPR11(r11)
++	/* fall through */
++#endif
++
++/*
++ * This code finishes saving the registers to the exception frame
++ * and jumps to the appropriate handler for the exception, turning
++ * on address translation.
++ * Note that we rely on the caller having set cr0.eq iff the exception
++ * occurred in kernel mode (i.e. MSR:PR = 0).
++ */
++	.globl	transfer_to_handler_full
++transfer_to_handler_full:
++	SAVE_NVGPRS(r11)
++	/* fall through */
++
++	.globl	transfer_to_handler
++transfer_to_handler:
++	stw	r2,GPR2(r11)
++	stw	r12,_NIP(r11)
++	stw	r9,_MSR(r11)
++	andi.	r2,r9,MSR_PR
++	mfctr	r12
++	mfspr	r2,SPRN_XER
++	stw	r12,_CTR(r11)
++	stw	r2,_XER(r11)
++	mfspr	r12,SPRN_SPRG3
++	addi	r2,r12,-THREAD
++	tovirt(r2,r2)			/* set r2 to current */
++	beq	2f			/* if from user, fix up THREAD.regs */
++	addi	r11,r1,STACK_FRAME_OVERHEAD
++	stw	r11,PT_REGS(r12)
++#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
++	/* Check to see if the dbcr0 register is set up to debug.  Use the
++	   single-step bit to do this. */
++	lwz	r12,THREAD_DBCR0(r12)
++	andis.	r12,r12,DBCR0_IC at h
++	beq+	3f
++	/* From user and task is ptraced - load up global dbcr0 */
++	li	r12,-1			/* clear all pending debug events */
++	mtspr	SPRN_DBSR,r12
++	lis	r11,global_dbcr0 at ha
++	tophys(r11,r11)
++	addi	r11,r11,global_dbcr0 at l
++	lwz	r12,0(r11)
++	mtspr	SPRN_DBCR0,r12
++	lwz	r12,4(r11)
++	addi	r12,r12,-1
++	stw	r12,4(r11)
++#endif
++	b	3f
++2:	/* if from kernel, check interrupted DOZE/NAP mode and
++         * check for stack overflow
++         */
++#ifdef CONFIG_6xx
++	mfspr	r11,SPRN_HID0
++	mtcr	r11
++BEGIN_FTR_SECTION
++	bt-	8,power_save_6xx_restore	/* Check DOZE */
++END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
++BEGIN_FTR_SECTION
++	bt-	9,power_save_6xx_restore	/* Check NAP */
++END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
++#endif /* CONFIG_6xx */
++	.globl transfer_to_handler_cont
++transfer_to_handler_cont:
++	lwz	r11,THREAD_INFO-THREAD(r12)
++	cmplw	r1,r11			/* if r1 <= current->thread_info */
++	ble-	stack_ovf		/* then the kernel stack overflowed */
++3:
++	mflr	r9
++	lwz	r11,0(r9)		/* virtual address of handler */
++	lwz	r9,4(r9)		/* where to go when done */
++	FIX_SRR1(r10,r12)
++	mtspr	SPRN_SRR0,r11
++	mtspr	SPRN_SRR1,r10
++	mtlr	r9
++	SYNC
++	RFI				/* jump to handler, enable MMU */
++
++/*
++ * On kernel stack overflow, load up an initial stack pointer
++ * and call StackOverflow(regs), which should not return.
++ */
++stack_ovf:
++	/* sometimes we use a statically-allocated stack, which is OK. */
++	lis	r11,_end at h
++	ori	r11,r11,_end at l
++	cmplw	r1,r11
++	ble	3b			/* r1 <= &_end is OK */
++	SAVE_NVGPRS(r11)
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	lis	r1,init_thread_union at ha
++	addi	r1,r1,init_thread_union at l
++	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
++	lis	r9,StackOverflow at ha
++	addi	r9,r9,StackOverflow at l
++	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
++	FIX_SRR1(r10,r12)
++	mtspr	SPRN_SRR0,r9
++	mtspr	SPRN_SRR1,r10
++	SYNC
++	RFI
++
++/*
++ * Handle a system call.
++ */
++	.stabs	"arch/powerpc/kernel/",N_SO,0,0,0f
++	.stabs	"entry_32.S",N_SO,0,0,0f
++0:
++
++_GLOBAL(DoSyscall)
++	stw	r0,THREAD+LAST_SYSCALL(r2)
++	stw	r3,ORIG_GPR3(r1)
++	li	r12,0
++	stw	r12,RESULT(r1)
++	lwz	r11,_CCR(r1)	/* Clear SO bit in CR */
++	rlwinm	r11,r11,0,4,2
++	stw	r11,_CCR(r1)
++#ifdef SHOW_SYSCALLS
++	bl	do_show_syscall
++#endif /* SHOW_SYSCALLS */
++	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
++	li	r11,0
++	stb	r11,TI_SC_NOERR(r10)
++	lwz	r11,TI_FLAGS(r10)
++	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
++	bne-	syscall_dotrace
++syscall_dotrace_cont:
++	cmplwi	0,r0,NR_syscalls
++	lis	r10,sys_call_table at h
++	ori	r10,r10,sys_call_table at l
++	slwi	r0,r0,2
++	bge-	66f
++	lwzx	r10,r10,r0	/* Fetch system call handler [ptr] */
++	mtlr	r10
++	addi	r9,r1,STACK_FRAME_OVERHEAD
++	PPC440EP_ERR42
++	blrl			/* Call handler */
++	.globl	ret_from_syscall
++ret_from_syscall:
++#ifdef SHOW_SYSCALLS
++	bl	do_show_syscall_exit
++#endif
++	mr	r6,r3
++	li	r11,-_LAST_ERRNO
++	cmplw	0,r3,r11
++	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
++	blt+	30f
++	lbz	r11,TI_SC_NOERR(r12)
++	cmpwi	r11,0
++	bne	30f
++	neg	r3,r3
++	lwz	r10,_CCR(r1)	/* Set SO bit in CR */
++	oris	r10,r10,0x1000
++	stw	r10,_CCR(r1)
++
++	/* disable interrupts so current_thread_info()->flags can't change */
++30:	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
++	SYNC
++	MTMSRD(r10)
++	lwz	r9,TI_FLAGS(r12)
++	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
++	bne-	syscall_exit_work
++syscall_exit_cont:
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++	/* If the process has its own DBCR0 value, load it up.  The single
++	   step bit tells us that dbcr0 should be loaded. */
++	lwz	r0,THREAD+THREAD_DBCR0(r2)
++	andis.	r10,r0,DBCR0_IC at h
++	bnel-	load_dbcr0
++#endif
++	stwcx.	r0,0,r1			/* to clear the reservation */
++	lwz	r4,_LINK(r1)
++	lwz	r5,_CCR(r1)
++	mtlr	r4
++	mtcr	r5
++	lwz	r7,_NIP(r1)
++	lwz	r8,_MSR(r1)
++	FIX_SRR1(r8, r0)
++	lwz	r2,GPR2(r1)
++	lwz	r1,GPR1(r1)
++	mtspr	SPRN_SRR0,r7
++	mtspr	SPRN_SRR1,r8
++	SYNC
++	RFI
++
++66:	li	r3,-ENOSYS
++	b	ret_from_syscall
++
++	.globl	ret_from_fork
++ret_from_fork:
++	REST_NVGPRS(r1)
++	bl	schedule_tail
++	li	r3,0
++	b	ret_from_syscall
++
++/* Traced system call support */
++syscall_dotrace:
++	SAVE_NVGPRS(r1)
++	li	r0,0xc00
++	stw	r0,_TRAP(r1)
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	do_syscall_trace_enter
++	lwz	r0,GPR0(r1)	/* Restore original registers */
++	lwz	r3,GPR3(r1)
++	lwz	r4,GPR4(r1)
++	lwz	r5,GPR5(r1)
++	lwz	r6,GPR6(r1)
++	lwz	r7,GPR7(r1)
++	lwz	r8,GPR8(r1)
++	REST_NVGPRS(r1)
++	b	syscall_dotrace_cont
++
++syscall_exit_work:
++	stw	r6,RESULT(r1)	/* Save result */
++	stw	r3,GPR3(r1)	/* Update return value */
++	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
++	beq	5f
++	ori	r10,r10,MSR_EE
++	SYNC
++	MTMSRD(r10)		/* re-enable interrupts */
++	lwz	r4,_TRAP(r1)
++	andi.	r4,r4,1
++	beq	4f
++	SAVE_NVGPRS(r1)
++	li	r4,0xc00
++	stw	r4,_TRAP(r1)
++4:
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	do_syscall_trace_leave
++	REST_NVGPRS(r1)
++2:
++	lwz	r3,GPR3(r1)
++	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
++	SYNC
++	MTMSRD(r10)		/* disable interrupts again */
++	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
++	lwz	r9,TI_FLAGS(r12)
++5:
++	andi.	r0,r9,_TIF_NEED_RESCHED
++	bne	1f
++	lwz	r5,_MSR(r1)
++	andi.	r5,r5,MSR_PR
++	beq	syscall_exit_cont
++	andi.	r0,r9,_TIF_SIGPENDING
++	beq	syscall_exit_cont
++	b	do_user_signal
++1:
++	ori	r10,r10,MSR_EE
++	SYNC
++	MTMSRD(r10)		/* re-enable interrupts */
++	bl	schedule
++	b	2b
++
++#ifdef SHOW_SYSCALLS
++do_show_syscall:
++#ifdef SHOW_SYSCALLS_TASK
++	lis	r11,show_syscalls_task at ha
++	lwz	r11,show_syscalls_task at l(r11)
++	cmp	0,r2,r11
++	bnelr
++#endif
++	stw	r31,GPR31(r1)
++	mflr	r31
++	lis	r3,7f at ha
++	addi	r3,r3,7f at l
++	lwz	r4,GPR0(r1)
++	lwz	r5,GPR3(r1)
++	lwz	r6,GPR4(r1)
++	lwz	r7,GPR5(r1)
++	lwz	r8,GPR6(r1)
++	lwz	r9,GPR7(r1)
++	bl	printk
++	lis	r3,77f at ha
++	addi	r3,r3,77f at l
++	lwz	r4,GPR8(r1)
++	mr	r5,r2
++	bl	printk
++	lwz	r0,GPR0(r1)
++	lwz	r3,GPR3(r1)
++	lwz	r4,GPR4(r1)
++	lwz	r5,GPR5(r1)
++	lwz	r6,GPR6(r1)
++	lwz	r7,GPR7(r1)
++	lwz	r8,GPR8(r1)
++	mtlr	r31
++	lwz	r31,GPR31(r1)
++	blr
++
++do_show_syscall_exit:
++#ifdef SHOW_SYSCALLS_TASK
++	lis	r11,show_syscalls_task at ha
++	lwz	r11,show_syscalls_task at l(r11)
++	cmp	0,r2,r11
++	bnelr
++#endif
++	stw	r31,GPR31(r1)
++	mflr	r31
++	stw	r3,RESULT(r1)	/* Save result */
++	mr	r4,r3
++	lis	r3,79f at ha
++	addi	r3,r3,79f at l
++	bl	printk
++	lwz	r3,RESULT(r1)
++	mtlr	r31
++	lwz	r31,GPR31(r1)
++	blr
++
++7:	.string	"syscall %d(%x, %x, %x, %x, %x, "
++77:	.string	"%x), current=%p\n"
++79:	.string	" -> %x\n"
++	.align	2,0
++
++#ifdef SHOW_SYSCALLS_TASK
++	.data
++	.globl	show_syscalls_task
++show_syscalls_task:
++	.long	-1
++	.text
++#endif
++#endif /* SHOW_SYSCALLS */
++
++/*
++ * The sigsuspend and rt_sigsuspend system calls can call do_signal
++ * and thus put the process into the stopped state where we might
++ * want to examine its user state with ptrace.  Therefore we need
++ * to save all the nonvolatile registers (r13 - r31) before calling
++ * the C code.
++ */
++	.globl	ppc_sigsuspend
++ppc_sigsuspend:
++	SAVE_NVGPRS(r1)
++	lwz	r0,_TRAP(r1)
++	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
++	stw	r0,_TRAP(r1)		/* register set saved */
++	b	sys_sigsuspend
++
++	.globl	ppc_rt_sigsuspend
++ppc_rt_sigsuspend:
++	SAVE_NVGPRS(r1)
++	lwz	r0,_TRAP(r1)
++	rlwinm	r0,r0,0,0,30
++	stw	r0,_TRAP(r1)
++	b	sys_rt_sigsuspend
++
++	.globl	ppc_fork
++ppc_fork:
++	SAVE_NVGPRS(r1)
++	lwz	r0,_TRAP(r1)
++	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
++	stw	r0,_TRAP(r1)		/* register set saved */
++	b	sys_fork
++
++	.globl	ppc_vfork
++ppc_vfork:
++	SAVE_NVGPRS(r1)
++	lwz	r0,_TRAP(r1)
++	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
++	stw	r0,_TRAP(r1)		/* register set saved */
++	b	sys_vfork
++
++	.globl	ppc_clone
++ppc_clone:
++	SAVE_NVGPRS(r1)
++	lwz	r0,_TRAP(r1)
++	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
++	stw	r0,_TRAP(r1)		/* register set saved */
++	b	sys_clone
++
++	.globl	ppc_swapcontext
++ppc_swapcontext:
++	SAVE_NVGPRS(r1)
++	lwz	r0,_TRAP(r1)
++	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
++	stw	r0,_TRAP(r1)		/* register set saved */
++	b	sys_swapcontext
++
++/*
++ * Top-level page fault handling.
++ * This is in assembler because if do_page_fault tells us that
++ * it is a bad kernel page fault, we want to save the non-volatile
++ * registers before calling bad_page_fault.
++ */
++	.globl	handle_page_fault
++handle_page_fault:
++	stw	r4,_DAR(r1)
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	do_page_fault
++	cmpwi	r3,0
++	beq+	ret_from_except
++	SAVE_NVGPRS(r1)
++	lwz	r0,_TRAP(r1)
++	clrrwi	r0,r0,1
++	stw	r0,_TRAP(r1)
++	mr	r5,r3
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	lwz	r4,_DAR(r1)
++	bl	bad_page_fault
++	b	ret_from_except_full
++
++/*
++ * This routine switches between two different tasks.  The process
++ * state of one is saved on its kernel stack.  Then the state
++ * of the other is restored from its kernel stack.  The memory
++ * management hardware is updated to the second process's state.
++ * Finally, we can return to the second process.
++ * On entry, r3 points to the THREAD for the current task, r4
++ * points to the THREAD for the new task.
++ *
++ * This routine is always called with interrupts disabled.
++ *
++ * Note: there are two ways to get to the "going out" portion
++ * of this code; either by coming in via the entry (_switch)
++ * or via "fork" which must set up an environment equivalent
++ * to the "_switch" path.  If you change this , you'll have to
++ * change the fork code also.
++ *
++ * The code which creates the new task context is in 'copy_thread'
++ * in arch/ppc/kernel/process.c
++ */
++_GLOBAL(_switch)
++	stwu	r1,-INT_FRAME_SIZE(r1)
++	mflr	r0
++	stw	r0,INT_FRAME_SIZE+4(r1)
++	/* r3-r12 are caller saved -- Cort */
++	SAVE_NVGPRS(r1)
++	stw	r0,_NIP(r1)	/* Return to switch caller */
++	mfmsr	r11
++	li	r0,MSR_FP	/* Disable floating-point */
++#ifdef CONFIG_ALTIVEC
++BEGIN_FTR_SECTION
++	oris	r0,r0,MSR_VEC at h	/* Disable altivec */
++	mfspr	r12,SPRN_VRSAVE	/* save vrsave register value */
++	stw	r12,THREAD+THREAD_VRSAVE(r2)
++END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_SPE
++	oris	r0,r0,MSR_SPE at h	 /* Disable SPE */
++	mfspr	r12,SPRN_SPEFSCR /* save spefscr register value */
++	stw	r12,THREAD+THREAD_SPEFSCR(r2)
++#endif /* CONFIG_SPE */
++	and.	r0,r0,r11	/* FP or altivec or SPE enabled? */
++	beq+	1f
++	andc	r11,r11,r0
++	MTMSRD(r11)
++	isync
++1:	stw	r11,_MSR(r1)
++	mfcr	r10
++	stw	r10,_CCR(r1)
++	stw	r1,KSP(r3)	/* Set old stack pointer */
++
++#ifdef CONFIG_SMP
++	/* We need a sync somewhere here to make sure that if the
++	 * previous task gets rescheduled on another CPU, it sees all
++	 * stores it has performed on this one.
++	 */
++	sync
++#endif /* CONFIG_SMP */
++
++	tophys(r0,r4)
++	CLR_TOP32(r0)
++	mtspr	SPRN_SPRG3,r0	/* Update current THREAD phys addr */
++	lwz	r1,KSP(r4)	/* Load new stack pointer */
++
++	/* save the old current 'last' for return value */
++	mr	r3,r2
++	addi	r2,r4,-THREAD	/* Update current */
++
++#ifdef CONFIG_ALTIVEC
++BEGIN_FTR_SECTION
++	lwz	r0,THREAD+THREAD_VRSAVE(r2)
++	mtspr	SPRN_VRSAVE,r0		/* if G4, restore VRSAVE reg */
++END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_SPE
++	lwz	r0,THREAD+THREAD_SPEFSCR(r2)
++	mtspr	SPRN_SPEFSCR,r0		/* restore SPEFSCR reg */
++#endif /* CONFIG_SPE */
++
++	lwz	r0,_CCR(r1)
++	mtcrf	0xFF,r0
++	/* r3-r12 are destroyed -- Cort */
++	REST_NVGPRS(r1)
++
++	lwz	r4,_NIP(r1)	/* Return to _switch caller in new task */
++	mtlr	r4
++	addi	r1,r1,INT_FRAME_SIZE
++	blr
++
++	.globl	fast_exception_return
++fast_exception_return:
++#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
++	andi.	r10,r9,MSR_RI		/* check for recoverable interrupt */
++	beq	1f			/* if not, we've got problems */
++#endif
++
++2:	REST_4GPRS(3, r11)
++	lwz	r10,_CCR(r11)
++	REST_GPR(1, r11)
++	mtcr	r10
++	lwz	r10,_LINK(r11)
++	mtlr	r10
++	REST_GPR(10, r11)
++	mtspr	SPRN_SRR1,r9
++	mtspr	SPRN_SRR0,r12
++	REST_GPR(9, r11)
++	REST_GPR(12, r11)
++	lwz	r11,GPR11(r11)
++	SYNC
++	RFI
++
++#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
++/* check if the exception happened in a restartable section */
++1:	lis	r3,exc_exit_restart_end at ha
++	addi	r3,r3,exc_exit_restart_end at l
++	cmplw	r12,r3
++	bge	3f
++	lis	r4,exc_exit_restart at ha
++	addi	r4,r4,exc_exit_restart at l
++	cmplw	r12,r4
++	blt	3f
++	lis	r3,fee_restarts at ha
++	tophys(r3,r3)
++	lwz	r5,fee_restarts at l(r3)
++	addi	r5,r5,1
++	stw	r5,fee_restarts at l(r3)
++	mr	r12,r4		/* restart at exc_exit_restart */
++	b	2b
++
++	.comm	fee_restarts,4
++
++/* aargh, a nonrecoverable interrupt, panic */
++/* aargh, we don't know which trap this is */
++/* but the 601 doesn't implement the RI bit, so assume it's OK */
++3:
++BEGIN_FTR_SECTION
++	b	2b
++END_FTR_SECTION_IFSET(CPU_FTR_601)
++	li	r10,-1
++	stw	r10,_TRAP(r11)
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	lis	r10,MSR_KERNEL at h
++	ori	r10,r10,MSR_KERNEL at l
++	bl	transfer_to_handler_full
++	.long	nonrecoverable_exception
++	.long	ret_from_except
++#endif
++
++	.globl	sigreturn_exit
++sigreturn_exit:
++	subi	r1,r3,STACK_FRAME_OVERHEAD
++	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
++	lwz	r9,TI_FLAGS(r12)
++	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
++	beq+	ret_from_except_full
++	bl	do_syscall_trace_leave
++	/* fall through */
++
++	.globl	ret_from_except_full
++ret_from_except_full:
++	REST_NVGPRS(r1)
++	/* fall through */
++
++	.globl	ret_from_except
++ret_from_except:
++	/* Hard-disable interrupts so that current_thread_info()->flags
++	 * can't change between when we test it and when we return
++	 * from the interrupt. */
++	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
++	SYNC			/* Some chip revs have problems here... */
++	MTMSRD(r10)		/* disable interrupts */
++
++	lwz	r3,_MSR(r1)	/* Returning to user mode? */
++	andi.	r0,r3,MSR_PR
++	beq	resume_kernel
++
++user_exc_return:		/* r10 contains MSR_KERNEL here */
++	/* Check current_thread_info()->flags */
++	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
++	lwz	r9,TI_FLAGS(r9)
++	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED)
++	bne	do_work
++
++restore_user:
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++	/* Check whether this process has its own DBCR0 value.  The single
++	   step bit tells us that dbcr0 should be loaded. */
++	lwz	r0,THREAD+THREAD_DBCR0(r2)
++	andis.	r10,r0,DBCR0_IC at h
++	bnel-	load_dbcr0
++#endif
++
++#ifdef CONFIG_PREEMPT
++	b	restore
++
++/* N.B. the only way to get here is from the beq following ret_from_except. */
++resume_kernel:
++	/* check current_thread_info->preempt_count */
++	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
++	lwz	r0,TI_PREEMPT(r9)
++	cmpwi	0,r0,0		/* if non-zero, just restore regs and return */
++	bne	restore
++	lwz	r0,TI_FLAGS(r9)
++	andi.	r0,r0,_TIF_NEED_RESCHED
++	beq+	restore
++	andi.	r0,r3,MSR_EE	/* interrupts off? */
++	beq	restore		/* don't schedule if so */
++1:	bl	preempt_schedule_irq
++	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
++	lwz	r3,TI_FLAGS(r9)
++	andi.	r0,r3,_TIF_NEED_RESCHED
++	bne-	1b
++#else
++resume_kernel:
++#endif /* CONFIG_PREEMPT */
++
++	/* interrupts are hard-disabled at this point */
++restore:
++	lwz	r0,GPR0(r1)
++	lwz	r2,GPR2(r1)
++	REST_4GPRS(3, r1)
++	REST_2GPRS(7, r1)
++
++	lwz	r10,_XER(r1)
++	lwz	r11,_CTR(r1)
++	mtspr	SPRN_XER,r10
++	mtctr	r11
++
++	PPC405_ERR77(0,r1)
++	stwcx.	r0,0,r1			/* to clear the reservation */
++
++#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
++	lwz	r9,_MSR(r1)
++	andi.	r10,r9,MSR_RI		/* check if this exception occurred */
++	beql	nonrecoverable		/* at a bad place (MSR:RI = 0) */
++
++	lwz	r10,_CCR(r1)
++	lwz	r11,_LINK(r1)
++	mtcrf	0xFF,r10
++	mtlr	r11
++
++	/*
++	 * Once we put values in SRR0 and SRR1, we are in a state
++	 * where exceptions are not recoverable, since taking an
++	 * exception will trash SRR0 and SRR1.  Therefore we clear the
++	 * MSR:RI bit to indicate this.  If we do take an exception,
++	 * we can't return to the point of the exception but we
++	 * can restart the exception exit path at the label
++	 * exc_exit_restart below.  -- paulus
++	 */
++	LOAD_MSR_KERNEL(r10,MSR_KERNEL & ~MSR_RI)
++	SYNC
++	MTMSRD(r10)		/* clear the RI bit */
++	.globl exc_exit_restart
++exc_exit_restart:
++	lwz	r9,_MSR(r1)
++	lwz	r12,_NIP(r1)
++	FIX_SRR1(r9,r10)
++	mtspr	SPRN_SRR0,r12
++	mtspr	SPRN_SRR1,r9
++	REST_4GPRS(9, r1)
++	lwz	r1,GPR1(r1)
++	.globl exc_exit_restart_end
++exc_exit_restart_end:
++	SYNC
++	RFI
++
++#else /* !(CONFIG_4xx || CONFIG_BOOKE) */
++	/*
++	 * This is a bit different on 4xx/Book-E because it doesn't have
++	 * the RI bit in the MSR.
++	 * The TLB miss handler checks if we have interrupted
++	 * the exception exit path and restarts it if so
++	 * (well maybe one day it will... :).
++	 */
++	lwz	r11,_LINK(r1)
++	mtlr	r11
++	lwz	r10,_CCR(r1)
++	mtcrf	0xff,r10
++	REST_2GPRS(9, r1)
++	.globl exc_exit_restart
++exc_exit_restart:
++	lwz	r11,_NIP(r1)
++	lwz	r12,_MSR(r1)
++exc_exit_start:
++	mtspr	SPRN_SRR0,r11
++	mtspr	SPRN_SRR1,r12
++	REST_2GPRS(11, r1)
++	lwz	r1,GPR1(r1)
++	.globl exc_exit_restart_end
++exc_exit_restart_end:
++	PPC405_ERR77_SYNC
++	rfi
++	b	.			/* prevent prefetch past rfi */
++
++/*
++ * Returning from a critical interrupt in user mode doesn't need
++ * to be any different from a normal exception.  For a critical
++ * interrupt in the kernel, we just return (without checking for
++ * preemption) since the interrupt may have happened at some crucial
++ * place (e.g. inside the TLB miss handler), and because we will be
++ * running with r1 pointing into critical_stack, not the current
++ * process's kernel stack (and therefore current_thread_info() will
++ * give the wrong answer).
++ * We have to restore various SPRs that may have been in use at the
++ * time of the critical interrupt.
++ *
++ */
++#ifdef CONFIG_40x
++#define PPC_40x_TURN_OFF_MSR_DR						    \
++	/* avoid any possible TLB misses here by turning off MSR.DR, we	    \
++	 * assume the instructions here are mapped by a pinned TLB entry */ \
++	li	r10,MSR_IR;						    \
++	mtmsr	r10;							    \
++	isync;								    \
++	tophys(r1, r1);
++#else
++#define PPC_40x_TURN_OFF_MSR_DR
++#endif
++
++#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi)	\
++	REST_NVGPRS(r1);						\
++	lwz	r3,_MSR(r1);						\
++	andi.	r3,r3,MSR_PR;						\
++	LOAD_MSR_KERNEL(r10,MSR_KERNEL);				\
++	bne	user_exc_return;					\
++	lwz	r0,GPR0(r1);						\
++	lwz	r2,GPR2(r1);						\
++	REST_4GPRS(3, r1);						\
++	REST_2GPRS(7, r1);						\
++	lwz	r10,_XER(r1);						\
++	lwz	r11,_CTR(r1);						\
++	mtspr	SPRN_XER,r10;						\
++	mtctr	r11;							\
++	PPC405_ERR77(0,r1);						\
++	stwcx.	r0,0,r1;		/* to clear the reservation */	\
++	lwz	r11,_LINK(r1);						\
++	mtlr	r11;							\
++	lwz	r10,_CCR(r1);						\
++	mtcrf	0xff,r10;						\
++	PPC_40x_TURN_OFF_MSR_DR;					\
++	lwz	r9,_DEAR(r1);						\
++	lwz	r10,_ESR(r1);						\
++	mtspr	SPRN_DEAR,r9;						\
++	mtspr	SPRN_ESR,r10;						\
++	lwz	r11,_NIP(r1);						\
++	lwz	r12,_MSR(r1);						\
++	mtspr	exc_lvl_srr0,r11;					\
++	mtspr	exc_lvl_srr1,r12;					\
++	lwz	r9,GPR9(r1);						\
++	lwz	r12,GPR12(r1);						\
++	lwz	r10,GPR10(r1);						\
++	lwz	r11,GPR11(r1);						\
++	lwz	r1,GPR1(r1);						\
++	PPC405_ERR77_SYNC;						\
++	exc_lvl_rfi;							\
++	b	.;		/* prevent prefetch past exc_lvl_rfi */
++
++	.globl	ret_from_crit_exc
++ret_from_crit_exc:
++	RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
++
++#ifdef CONFIG_BOOKE
++	.globl	ret_from_debug_exc
++ret_from_debug_exc:
++	RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
++
++	.globl	ret_from_mcheck_exc
++ret_from_mcheck_exc:
++	RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
++#endif /* CONFIG_BOOKE */
++
++/*
++ * Load the DBCR0 value for a task that is being ptraced,
++ * having first saved away the global DBCR0.  Note that r0
++ * has the dbcr0 value to set upon entry to this.
++ */
++load_dbcr0:
++	mfmsr	r10		/* first disable debug exceptions */
++	rlwinm	r10,r10,0,~MSR_DE
++	mtmsr	r10
++	isync
++	mfspr	r10,SPRN_DBCR0
++	lis	r11,global_dbcr0 at ha
++	addi	r11,r11,global_dbcr0 at l
++	stw	r10,0(r11)
++	mtspr	SPRN_DBCR0,r0
++	lwz	r10,4(r11)
++	addi	r10,r10,1
++	stw	r10,4(r11)
++	li	r11,-1
++	mtspr	SPRN_DBSR,r11	/* clear all pending debug events */
++	blr
++
++	.comm	global_dbcr0,8
++#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
++
++do_work:			/* r10 contains MSR_KERNEL here */
++	andi.	r0,r9,_TIF_NEED_RESCHED
++	beq	do_user_signal
++
++do_resched:			/* r10 contains MSR_KERNEL here */
++	ori	r10,r10,MSR_EE
++	SYNC
++	MTMSRD(r10)		/* hard-enable interrupts */
++	bl	schedule
++recheck:
++	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
++	SYNC
++	MTMSRD(r10)		/* disable interrupts */
++	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
++	lwz	r9,TI_FLAGS(r9)
++	andi.	r0,r9,_TIF_NEED_RESCHED
++	bne-	do_resched
++	andi.	r0,r9,_TIF_SIGPENDING
++	beq	restore_user
++do_user_signal:			/* r10 contains MSR_KERNEL here */
++	ori	r10,r10,MSR_EE
++	SYNC
++	MTMSRD(r10)		/* hard-enable interrupts */
++	/* save r13-r31 in the exception frame, if not already done */
++	lwz	r3,_TRAP(r1)
++	andi.	r0,r3,1
++	beq	2f
++	SAVE_NVGPRS(r1)
++	rlwinm	r3,r3,0,0,30
++	stw	r3,_TRAP(r1)
++2:	li	r3,0
++	addi	r4,r1,STACK_FRAME_OVERHEAD
++	bl	do_signal
++	REST_NVGPRS(r1)
++	b	recheck
++
++/*
++ * We come here when we are at the end of handling an exception
++ * that occurred at a place where taking an exception will lose
++ * state information, such as the contents of SRR0 and SRR1.
++ */
++nonrecoverable:
++	lis	r10,exc_exit_restart_end at ha
++	addi	r10,r10,exc_exit_restart_end at l
++	cmplw	r12,r10
++	bge	3f
++	lis	r11,exc_exit_restart at ha
++	addi	r11,r11,exc_exit_restart at l
++	cmplw	r12,r11
++	blt	3f
++	lis	r10,ee_restarts at ha
++	lwz	r12,ee_restarts at l(r10)
++	addi	r12,r12,1
++	stw	r12,ee_restarts at l(r10)
++	mr	r12,r11		/* restart at exc_exit_restart */
++	blr
++3:	/* OK, we can't recover, kill this process */
++	/* but the 601 doesn't implement the RI bit, so assume it's OK */
++BEGIN_FTR_SECTION
++	blr
++END_FTR_SECTION_IFSET(CPU_FTR_601)
++	lwz	r3,_TRAP(r1)
++	andi.	r0,r3,1
++	beq	4f
++	SAVE_NVGPRS(r1)
++	rlwinm	r3,r3,0,0,30
++	stw	r3,_TRAP(r1)
++4:	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	nonrecoverable_exception
++	/* shouldn't return */
++	b	4b
++
++	.comm	ee_restarts,4
++
++/*
++ * PROM code for specific machines follows.  Put it
++ * here so it's easy to add arch-specific sections later.
++ * -- Cort
++ */
++#ifdef CONFIG_PPC_RTAS
++/*
++ * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
++ * called with the MMU off.
++ */
++_GLOBAL(enter_rtas)
++	stwu	r1,-INT_FRAME_SIZE(r1)
++	mflr	r0
++	stw	r0,INT_FRAME_SIZE+4(r1)
++	LOADADDR(r4, rtas)
++	lis	r6,1f at ha	/* physical return address for rtas */
++	addi	r6,r6,1f at l
++	tophys(r6,r6)
++	tophys(r7,r1)
++	lwz	r8,RTASENTRY(r4)
++	lwz	r4,RTASBASE(r4)
++	mfmsr	r9
++	stw	r9,8(r1)
++	LOAD_MSR_KERNEL(r0,MSR_KERNEL)
++	SYNC			/* disable interrupts so SRR0/1 */
++	MTMSRD(r0)		/* don't get trashed */
++	li	r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
++	mtlr	r6
++	mtspr	SPRN_SPRG2,r7
++	mtspr	SPRN_SRR0,r8
++	mtspr	SPRN_SRR1,r9
++	RFI
++1:	tophys(r9,r1)
++	lwz	r8,INT_FRAME_SIZE+4(r9)	/* get return address */
++	lwz	r9,8(r9)	/* original msr value */
++	FIX_SRR1(r9,r0)
++	addi	r1,r1,INT_FRAME_SIZE
++	li	r0,0
++	mtspr	SPRN_SPRG2,r0
++	mtspr	SPRN_SRR0,r8
++	mtspr	SPRN_SRR1,r9
++	RFI			/* return to caller */
++
++	.globl	machine_check_in_rtas
++machine_check_in_rtas:
++	twi	31,0,0
++	/* XXX load up BATs and panic */
++
++#endif /* CONFIG_PPC_RTAS */
+diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/entry_64.S
+@@ -0,0 +1,842 @@
++/*
++ *  arch/ppc64/kernel/entry.S
++ *
++ *  PowerPC version 
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *  Rewritten by Cort Dougan (cort at cs.nmt.edu) for PReP
++ *    Copyright (C) 1996 Cort Dougan <cort at cs.nmt.edu>
++ *  Adapted for Power Macintosh by Paul Mackerras.
++ *  Low-level exception handlers and MMU support
++ *  rewritten by Paul Mackerras.
++ *    Copyright (C) 1996 Paul Mackerras.
++ *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek at jlc.net).
++ *
++ *  This file contains the system call entry code, context switch
++ *  code, and exception/interrupt return code for PowerPC.
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/errno.h>
++#include <asm/unistd.h>
++#include <asm/processor.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++#include <asm/cputable.h>
++
++#ifdef CONFIG_PPC_ISERIES
++#define DO_SOFT_DISABLE
++#endif
++
++/*
++ * System calls.
++ */
++	.section	".toc","aw"
++.SYS_CALL_TABLE:
++	.tc .sys_call_table[TC],.sys_call_table
++
++/* This value is used to mark exception frames on the stack. */
++exception_marker:
++	.tc	ID_72656773_68657265[TC],0x7265677368657265
++
++	.section	".text"
++	.align 7
++
++#undef SHOW_SYSCALLS
++
++	.globl system_call_common
++system_call_common:
++	andi.	r10,r12,MSR_PR
++	mr	r10,r1
++	addi	r1,r1,-INT_FRAME_SIZE
++	beq-	1f
++	ld	r1,PACAKSAVE(r13)
++1:	std	r10,0(r1)
++	std	r11,_NIP(r1)
++	std	r12,_MSR(r1)
++	std	r0,GPR0(r1)
++	std	r10,GPR1(r1)
++	std	r2,GPR2(r1)
++	std	r3,GPR3(r1)
++	std	r4,GPR4(r1)
++	std	r5,GPR5(r1)
++	std	r6,GPR6(r1)
++	std	r7,GPR7(r1)
++	std	r8,GPR8(r1)
++	li	r11,0
++	std	r11,GPR9(r1)
++	std	r11,GPR10(r1)
++	std	r11,GPR11(r1)
++	std	r11,GPR12(r1)
++	std	r9,GPR13(r1)
++	crclr	so
++	mfcr	r9
++	mflr	r10
++	li	r11,0xc01
++	std	r9,_CCR(r1)
++	std	r10,_LINK(r1)
++	std	r11,_TRAP(r1)
++	mfxer	r9
++	mfctr	r10
++	std	r9,_XER(r1)
++	std	r10,_CTR(r1)
++	std	r3,ORIG_GPR3(r1)
++	ld	r2,PACATOC(r13)
++	addi	r9,r1,STACK_FRAME_OVERHEAD
++	ld	r11,exception_marker at toc(r2)
++	std	r11,-16(r9)		/* "regshere" marker */
++#ifdef CONFIG_PPC_ISERIES
++	/* Hack for handling interrupts when soft-enabling on iSeries */
++	cmpdi	cr1,r0,0x5555		/* syscall 0x5555 */
++	andi.	r10,r12,MSR_PR		/* from kernel */
++	crand	4*cr0+eq,4*cr1+eq,4*cr0+eq
++	beq	hardware_interrupt_entry
++	lbz	r10,PACAPROCENABLED(r13)
++	std	r10,SOFTE(r1)
++#endif
++	mfmsr	r11
++	ori	r11,r11,MSR_EE
++	mtmsrd	r11,1
++
++#ifdef SHOW_SYSCALLS
++	bl	.do_show_syscall
++	REST_GPR(0,r1)
++	REST_4GPRS(3,r1)
++	REST_2GPRS(7,r1)
++	addi	r9,r1,STACK_FRAME_OVERHEAD
++#endif
++	clrrdi	r11,r1,THREAD_SHIFT
++	li	r12,0
++	ld	r10,TI_FLAGS(r11)
++	stb	r12,TI_SC_NOERR(r11)
++	andi.	r11,r10,_TIF_SYSCALL_T_OR_A
++	bne-	syscall_dotrace
++syscall_dotrace_cont:
++	cmpldi	0,r0,NR_syscalls
++	bge-	syscall_enosys
++
++system_call:			/* label this so stack traces look sane */
++/*
++ * Need to vector to 32 Bit or default sys_call_table here,
++ * based on caller's run-mode / personality.
++ */
++	ld	r11,.SYS_CALL_TABLE at toc(2)
++	andi.	r10,r10,_TIF_32BIT
++	beq	15f
++	addi	r11,r11,8	/* use 32-bit syscall entries */
++	clrldi	r3,r3,32
++	clrldi	r4,r4,32
++	clrldi	r5,r5,32
++	clrldi	r6,r6,32
++	clrldi	r7,r7,32
++	clrldi	r8,r8,32
++15:
++	slwi	r0,r0,4
++	ldx	r10,r11,r0	/* Fetch system call handler [ptr] */
++	mtctr   r10
++	bctrl			/* Call handler */
++
++syscall_exit:
++#ifdef SHOW_SYSCALLS
++	std	r3,GPR3(r1)
++	bl	.do_show_syscall_exit
++	ld	r3,GPR3(r1)
++#endif
++	std	r3,RESULT(r1)
++	ld	r5,_CCR(r1)
++	li	r10,-_LAST_ERRNO
++	cmpld	r3,r10
++	clrrdi	r12,r1,THREAD_SHIFT
++	bge-	syscall_error
++syscall_error_cont:
++
++	/* check for syscall tracing or audit */
++	ld	r9,TI_FLAGS(r12)
++	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
++	bne-	syscall_exit_trace
++syscall_exit_trace_cont:
++
++	/* disable interrupts so current_thread_info()->flags can't change,
++	   and so that we don't get interrupted after loading SRR0/1. */
++	ld	r8,_MSR(r1)
++	andi.	r10,r8,MSR_RI
++	beq-	unrecov_restore
++	mfmsr	r10
++	rldicl	r10,r10,48,1
++	rotldi	r10,r10,16
++	mtmsrd	r10,1
++	ld	r9,TI_FLAGS(r12)
++	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
++	bne-	syscall_exit_work
++	ld	r7,_NIP(r1)
++	stdcx.	r0,0,r1			/* to clear the reservation */
++	andi.	r6,r8,MSR_PR
++	ld	r4,_LINK(r1)
++	beq-	1f			/* only restore r13 if */
++	ld	r13,GPR13(r1)		/* returning to usermode */
++1:	ld	r2,GPR2(r1)
++	li	r12,MSR_RI
++	andc	r10,r10,r12
++	mtmsrd	r10,1			/* clear MSR.RI */
++	ld	r1,GPR1(r1)
++	mtlr	r4
++	mtcr	r5
++	mtspr	SPRN_SRR0,r7
++	mtspr	SPRN_SRR1,r8
++	rfid
++	b	.	/* prevent speculative execution */
++
++syscall_enosys:
++	li	r3,-ENOSYS
++	std	r3,RESULT(r1)
++	clrrdi	r12,r1,THREAD_SHIFT
++	ld	r5,_CCR(r1)
++
++syscall_error:
++	lbz	r11,TI_SC_NOERR(r12)
++	cmpwi	0,r11,0
++	bne-	syscall_error_cont
++	neg	r3,r3
++	oris	r5,r5,0x1000	/* Set SO bit in CR */
++	std	r5,_CCR(r1)
++	b	syscall_error_cont
++        
++/* Traced system call support */
++syscall_dotrace:
++	bl	.save_nvgprs
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.do_syscall_trace_enter
++	ld	r0,GPR0(r1)	/* Restore original registers */
++	ld	r3,GPR3(r1)
++	ld	r4,GPR4(r1)
++	ld	r5,GPR5(r1)
++	ld	r6,GPR6(r1)
++	ld	r7,GPR7(r1)
++	ld	r8,GPR8(r1)
++	addi	r9,r1,STACK_FRAME_OVERHEAD
++	clrrdi	r10,r1,THREAD_SHIFT
++	ld	r10,TI_FLAGS(r10)
++	b	syscall_dotrace_cont
++
++syscall_exit_trace:
++	std	r3,GPR3(r1)
++	bl	.save_nvgprs
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.do_syscall_trace_leave
++	REST_NVGPRS(r1)
++	ld	r3,GPR3(r1)
++	ld	r5,_CCR(r1)
++	clrrdi	r12,r1,THREAD_SHIFT
++	b	syscall_exit_trace_cont
++
++/* Stuff to do on exit from a system call. */
++syscall_exit_work:
++	std	r3,GPR3(r1)
++	std	r5,_CCR(r1)
++	b	.ret_from_except_lite
++
++/* Save non-volatile GPRs, if not already saved. */
++_GLOBAL(save_nvgprs)
++	ld	r11,_TRAP(r1)
++	andi.	r0,r11,1
++	beqlr-
++	SAVE_NVGPRS(r1)
++	clrrdi	r0,r11,1
++	std	r0,_TRAP(r1)
++	blr
++
++/*
++ * The sigsuspend and rt_sigsuspend system calls can call do_signal
++ * and thus put the process into the stopped state where we might
++ * want to examine its user state with ptrace.  Therefore we need
++ * to save all the nonvolatile registers (r14 - r31) before calling
++ * the C code.  Similarly, fork, vfork and clone need the full
++ * register state on the stack so that it can be copied to the child.
++ */
++_GLOBAL(ppc32_sigsuspend)
++	bl	.save_nvgprs
++	bl	.compat_sys_sigsuspend
++	b	70f
++
++_GLOBAL(ppc64_rt_sigsuspend)
++	bl	.save_nvgprs
++	bl	.sys_rt_sigsuspend
++	b	70f
++
++_GLOBAL(ppc32_rt_sigsuspend)
++	bl	.save_nvgprs
++	bl	.compat_sys_rt_sigsuspend
++70:	cmpdi	0,r3,0
++	/* If it returned an error, we need to return via syscall_exit to set
++	   the SO bit in cr0 and potentially stop for ptrace. */
++	bne	syscall_exit
++	/* If sigsuspend() returns zero, we are going into a signal handler. We
++	   may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
++#ifdef CONFIG_AUDITSYSCALL
++	ld	r3,PACACURRENT(r13)
++	ld	r4,AUDITCONTEXT(r3)
++	cmpdi	0,r4,0
++	beq	.ret_from_except	/* No audit_context: Leave immediately. */
++	li	r4, 2			/* AUDITSC_FAILURE */
++	li	r5,-4			/* It's always -EINTR */
++	bl	.audit_syscall_exit
++#endif
++	b	.ret_from_except
++
++_GLOBAL(ppc_fork)
++	bl	.save_nvgprs
++	bl	.sys_fork
++	b	syscall_exit
++
++_GLOBAL(ppc_vfork)
++	bl	.save_nvgprs
++	bl	.sys_vfork
++	b	syscall_exit
++
++_GLOBAL(ppc_clone)
++	bl	.save_nvgprs
++	bl	.sys_clone
++	b	syscall_exit
++
++_GLOBAL(ppc32_swapcontext)
++	bl	.save_nvgprs
++	bl	.compat_sys_swapcontext
++	b	80f
++	
++_GLOBAL(ppc64_swapcontext)
++	bl	.save_nvgprs
++	bl	.sys_swapcontext
++	b	80f
++
++_GLOBAL(ppc32_sigreturn)
++	bl	.compat_sys_sigreturn
++	b	80f
++
++_GLOBAL(ppc32_rt_sigreturn)
++	bl	.compat_sys_rt_sigreturn
++	b	80f
++
++_GLOBAL(ppc64_rt_sigreturn)
++	bl	.sys_rt_sigreturn
++
++80:	cmpdi	0,r3,0
++	blt	syscall_exit
++	clrrdi	r4,r1,THREAD_SHIFT
++	ld	r4,TI_FLAGS(r4)
++	andi.	r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
++	beq+	81f
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.do_syscall_trace_leave
++81:	b	.ret_from_except
++
++_GLOBAL(ret_from_fork)
++	bl	.schedule_tail
++	REST_NVGPRS(r1)
++	li	r3,0
++	b	syscall_exit
++
++/*
++ * This routine switches between two different tasks.  The process
++ * state of one is saved on its kernel stack.  Then the state
++ * of the other is restored from its kernel stack.  The memory
++ * management hardware is updated to the second process's state.
++ * Finally, we can return to the second process, via ret_from_except.
++ * On entry, r3 points to the THREAD for the current task, r4
++ * points to the THREAD for the new task.
++ *
++ * Note: there are two ways to get to the "going out" portion
++ * of this code; either by coming in via the entry (_switch)
++ * or via "fork" which must set up an environment equivalent
++ * to the "_switch" path.  If you change this you'll have to change
++ * the fork code also.
++ *
++ * The code which creates the new task context is in 'copy_thread'
++ * in arch/ppc64/kernel/process.c
++ */
++	.align	7
++_GLOBAL(_switch)
++	mflr	r0
++	std	r0,16(r1)
++	stdu	r1,-SWITCH_FRAME_SIZE(r1)
++	/* r3-r13 are caller saved -- Cort */
++	SAVE_8GPRS(14, r1)
++	SAVE_10GPRS(22, r1)
++	mflr	r20		/* Return to switch caller */
++	mfmsr	r22
++	li	r0, MSR_FP
++#ifdef CONFIG_ALTIVEC
++BEGIN_FTR_SECTION
++	oris	r0,r0,MSR_VEC at h	/* Disable altivec */
++	mfspr	r24,SPRN_VRSAVE	/* save vrsave register value */
++	std	r24,THREAD_VRSAVE(r3)
++END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
++#endif /* CONFIG_ALTIVEC */
++	and.	r0,r0,r22
++	beq+	1f
++	andc	r22,r22,r0
++	mtmsrd	r22
++	isync
++1:	std	r20,_NIP(r1)
++	mfcr	r23
++	std	r23,_CCR(r1)
++	std	r1,KSP(r3)	/* Set old stack pointer */
++
++#ifdef CONFIG_SMP
++	/* We need a sync somewhere here to make sure that if the
++	 * previous task gets rescheduled on another CPU, it sees all
++	 * stores it has performed on this one.
++	 */
++	sync
++#endif /* CONFIG_SMP */
++
++	addi	r6,r4,-THREAD	/* Convert THREAD to 'current' */
++	std	r6,PACACURRENT(r13)	/* Set new 'current' */
++
++	ld	r8,KSP(r4)	/* new stack pointer */
++BEGIN_FTR_SECTION
++	clrrdi	r6,r8,28	/* get its ESID */
++	clrrdi	r9,r1,28	/* get current sp ESID */
++	clrldi.	r0,r6,2		/* is new ESID c00000000? */
++	cmpd	cr1,r6,r9	/* or is new ESID the same as current ESID? */
++	cror	eq,4*cr1+eq,eq
++	beq	2f		/* if yes, don't slbie it */
++
++	/* Bolt in the new stack SLB entry */
++	ld	r7,KSP_VSID(r4)	/* Get new stack's VSID */
++	oris	r0,r6,(SLB_ESID_V)@h
++	ori	r0,r0,(SLB_NUM_BOLTED-1)@l
++	slbie	r6
++	slbie	r6		/* Workaround POWER5 < DD2.1 issue */
++	slbmte	r7,r0
++	isync
++
++2:
++END_FTR_SECTION_IFSET(CPU_FTR_SLB)
++	clrrdi	r7,r8,THREAD_SHIFT	/* base of new stack */
++	/* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
++	   because we don't need to leave the 288-byte ABI gap at the
++	   top of the kernel stack. */
++	addi	r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE
++
++	mr	r1,r8		/* start using new stack pointer */
++	std	r7,PACAKSAVE(r13)
++
++	ld	r6,_CCR(r1)
++	mtcrf	0xFF,r6
++
++#ifdef CONFIG_ALTIVEC
++BEGIN_FTR_SECTION
++	ld	r0,THREAD_VRSAVE(r4)
++	mtspr	SPRN_VRSAVE,r0		/* if G4, restore VRSAVE reg */
++END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
++#endif /* CONFIG_ALTIVEC */
++
++	/* r3-r13 are destroyed -- Cort */
++	REST_8GPRS(14, r1)
++	REST_10GPRS(22, r1)
++
++	/* convert old thread to its task_struct for return value */
++	addi	r3,r3,-THREAD
++	ld	r7,_NIP(r1)	/* Return to _switch caller in new task */
++	mtlr	r7
++	addi	r1,r1,SWITCH_FRAME_SIZE
++	blr
++
++	.align	7
++_GLOBAL(ret_from_except)
++	ld	r11,_TRAP(r1)
++	andi.	r0,r11,1
++	bne	.ret_from_except_lite
++	REST_NVGPRS(r1)
++
++_GLOBAL(ret_from_except_lite)
++	/*
++	 * Disable interrupts so that current_thread_info()->flags
++	 * can't change between when we test it and when we return
++	 * from the interrupt.
++	 */
++	mfmsr	r10		/* Get current interrupt state */
++	rldicl	r9,r10,48,1	/* clear MSR_EE */
++	rotldi	r9,r9,16
++	mtmsrd	r9,1		/* Update machine state */
++
++#ifdef CONFIG_PREEMPT
++	clrrdi	r9,r1,THREAD_SHIFT	/* current_thread_info() */
++	li	r0,_TIF_NEED_RESCHED	/* bits to check */
++	ld	r3,_MSR(r1)
++	ld	r4,TI_FLAGS(r9)
++	/* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */
++	rlwimi	r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING
++	and.	r0,r4,r0	/* check NEED_RESCHED and maybe SIGPENDING */
++	bne	do_work
++
++#else /* !CONFIG_PREEMPT */
++	ld	r3,_MSR(r1)	/* Returning to user mode? */
++	andi.	r3,r3,MSR_PR
++	beq	restore		/* if not, just restore regs and return */
++
++	/* Check current_thread_info()->flags */
++	clrrdi	r9,r1,THREAD_SHIFT
++	ld	r4,TI_FLAGS(r9)
++	andi.	r0,r4,_TIF_USER_WORK_MASK
++	bne	do_work
++#endif
++
++restore:
++#ifdef CONFIG_PPC_ISERIES
++	ld	r5,SOFTE(r1)
++	cmpdi	0,r5,0
++	beq	4f
++	/* Check for pending interrupts (iSeries) */
++	ld	r3,PACALPPACA+LPPACAANYINT(r13)
++	cmpdi	r3,0
++	beq+	4f			/* skip do_IRQ if no interrupts */
++
++	li	r3,0
++	stb	r3,PACAPROCENABLED(r13)	/* ensure we are soft-disabled */
++	ori	r10,r10,MSR_EE
++	mtmsrd	r10			/* hard-enable again */
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.do_IRQ
++	b	.ret_from_except_lite		/* loop back and handle more */
++
++4:	stb	r5,PACAPROCENABLED(r13)
++#endif
++
++	ld	r3,_MSR(r1)
++	andi.	r0,r3,MSR_RI
++	beq-	unrecov_restore
++
++	andi.	r0,r3,MSR_PR
++
++	/*
++	 * r13 is our per cpu area, only restore it if we are returning to
++	 * userspace
++	 */
++	beq	1f
++	REST_GPR(13, r1)
++1:
++	ld	r3,_CTR(r1)
++	ld	r0,_LINK(r1)
++	mtctr	r3
++	mtlr	r0
++	ld	r3,_XER(r1)
++	mtspr	SPRN_XER,r3
++
++	REST_8GPRS(5, r1)
++
++	stdcx.	r0,0,r1		/* to clear the reservation */
++
++	mfmsr	r0
++	li	r2, MSR_RI
++	andc	r0,r0,r2
++	mtmsrd	r0,1
++
++	ld	r0,_MSR(r1)
++	mtspr	SPRN_SRR1,r0
++
++	ld	r2,_CCR(r1)
++	mtcrf	0xFF,r2
++	ld	r2,_NIP(r1)
++	mtspr	SPRN_SRR0,r2
++
++	ld	r0,GPR0(r1)
++	ld	r2,GPR2(r1)
++	ld	r3,GPR3(r1)
++	ld	r4,GPR4(r1)
++	ld	r1,GPR1(r1)
++
++	rfid
++	b	.	/* prevent speculative execution */
++
++/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */
++do_work:
++#ifdef CONFIG_PREEMPT
++	andi.	r0,r3,MSR_PR	/* Returning to user mode? */
++	bne	user_work
++	/* Check that preempt_count() == 0 and interrupts are enabled */
++	lwz	r8,TI_PREEMPT(r9)
++	cmpwi	cr1,r8,0
++#ifdef CONFIG_PPC_ISERIES
++	ld	r0,SOFTE(r1)
++	cmpdi	r0,0
++#else
++	andi.	r0,r3,MSR_EE
++#endif
++	crandc	eq,cr1*4+eq,eq
++	bne	restore
++	/* here we are preempting the current task */
++1:
++#ifdef CONFIG_PPC_ISERIES
++	li	r0,1
++	stb	r0,PACAPROCENABLED(r13)
++#endif
++	ori	r10,r10,MSR_EE
++	mtmsrd	r10,1		/* reenable interrupts */
++	bl	.preempt_schedule
++	mfmsr	r10
++	clrrdi	r9,r1,THREAD_SHIFT
++	rldicl	r10,r10,48,1	/* disable interrupts again */
++	rotldi	r10,r10,16
++	mtmsrd	r10,1
++	ld	r4,TI_FLAGS(r9)
++	andi.	r0,r4,_TIF_NEED_RESCHED
++	bne	1b
++	b	restore
++
++user_work:
++#endif
++	/* Enable interrupts */
++	ori	r10,r10,MSR_EE
++	mtmsrd	r10,1
++
++	andi.	r0,r4,_TIF_NEED_RESCHED
++	beq	1f
++	bl	.schedule
++	b	.ret_from_except_lite
++
++1:	bl	.save_nvgprs
++	li	r3,0
++	addi	r4,r1,STACK_FRAME_OVERHEAD
++	bl	.do_signal
++	b	.ret_from_except
++
++unrecov_restore:
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.unrecoverable_exception
++	b	unrecov_restore
++
++#ifdef CONFIG_PPC_RTAS
++/*
++ * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
++ * called with the MMU off.
++ *
++ * In addition, we need to be in 32b mode, at least for now.
++ * 
++ * Note: r3 is an input parameter to rtas, so don't trash it...
++ */
++_GLOBAL(enter_rtas)
++	mflr	r0
++	std	r0,16(r1)
++        stdu	r1,-RTAS_FRAME_SIZE(r1)	/* Save SP and create stack space. */
++
++	/* Because RTAS is running in 32b mode, it clobbers the high order half
++	 * of all registers that it saves.  We therefore save those registers
++	 * RTAS might touch to the stack.  (r0, r3-r13 are caller saved)
++   	 */
++	SAVE_GPR(2, r1)			/* Save the TOC */
++	SAVE_GPR(13, r1)		/* Save paca */
++	SAVE_8GPRS(14, r1)		/* Save the non-volatiles */
++	SAVE_10GPRS(22, r1)		/* ditto */
++
++	mfcr	r4
++	std	r4,_CCR(r1)
++	mfctr	r5
++	std	r5,_CTR(r1)
++	mfspr	r6,SPRN_XER
++	std	r6,_XER(r1)
++	mfdar	r7
++	std	r7,_DAR(r1)
++	mfdsisr	r8
++	std	r8,_DSISR(r1)
++	mfsrr0	r9
++	std	r9,_SRR0(r1)
++	mfsrr1	r10
++	std	r10,_SRR1(r1)
++
++	/* There is no way it is acceptable to get here with interrupts enabled,
++	 * check it with the asm equivalent of WARN_ON
++	 */
++	mfmsr	r6
++	andi.	r0,r6,MSR_EE
++1:	tdnei	r0,0
++.section __bug_table,"a"
++	.llong	1b,__LINE__ + 0x1000000, 1f, 2f
++.previous
++.section .rodata,"a"
++1:	.asciz	__FILE__
++2:	.asciz "enter_rtas"
++.previous
++	
++	/* Unfortunately, the stack pointer and the MSR are also clobbered,
++	 * so they are saved in the PACA which allows us to restore
++	 * our original state after RTAS returns.
++         */
++	std	r1,PACAR1(r13)
++        std	r6,PACASAVEDMSR(r13)
++
++	/* Setup our real return addr */	
++	SET_REG_TO_LABEL(r4,.rtas_return_loc)
++	SET_REG_TO_CONST(r9,KERNELBASE)
++	sub	r4,r4,r9
++       	mtlr	r4
++
++	li	r0,0
++	ori	r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI
++	andc	r0,r6,r0
++	
++        li      r9,1
++        rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
++	ori	r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP
++	andc	r6,r0,r9
++	ori	r6,r6,MSR_RI
++	sync				/* disable interrupts so SRR0/1 */
++	mtmsrd	r0			/* don't get trashed */
++
++	SET_REG_TO_LABEL(r4,rtas)
++	ld	r5,RTASENTRY(r4)	/* get the rtas->entry value */
++	ld	r4,RTASBASE(r4)		/* get the rtas->base value */
++	
++	mtspr	SPRN_SRR0,r5
++	mtspr	SPRN_SRR1,r6
++	rfid
++	b	.	/* prevent speculative execution */
++
++_STATIC(rtas_return_loc)
++	/* relocation is off at this point */
++	mfspr	r4,SPRN_SPRG3	        /* Get PACA */
++	SET_REG_TO_CONST(r5, KERNELBASE)
++        sub     r4,r4,r5                /* RELOC the PACA base pointer */
++
++	mfmsr   r6
++	li	r0,MSR_RI
++	andc	r6,r6,r0
++	sync	
++	mtmsrd  r6
++        
++        ld	r1,PACAR1(r4)           /* Restore our SP */
++	LOADADDR(r3,.rtas_restore_regs)
++        ld	r4,PACASAVEDMSR(r4)     /* Restore our MSR */
++
++	mtspr	SPRN_SRR0,r3
++	mtspr	SPRN_SRR1,r4
++	rfid
++	b	.	/* prevent speculative execution */
++
++_STATIC(rtas_restore_regs)
++	/* relocation is on at this point */
++	REST_GPR(2, r1)			/* Restore the TOC */
++	REST_GPR(13, r1)		/* Restore paca */
++	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
++	REST_10GPRS(22, r1)		/* ditto */
++
++	mfspr	r13,SPRN_SPRG3
++
++	ld	r4,_CCR(r1)
++	mtcr	r4
++	ld	r5,_CTR(r1)
++	mtctr	r5
++	ld	r6,_XER(r1)
++	mtspr	SPRN_XER,r6
++	ld	r7,_DAR(r1)
++	mtdar	r7
++	ld	r8,_DSISR(r1)
++	mtdsisr	r8
++	ld	r9,_SRR0(r1)
++	mtsrr0	r9
++	ld	r10,_SRR1(r1)
++	mtsrr1	r10
++
++        addi	r1,r1,RTAS_FRAME_SIZE	/* Unstack our frame */
++	ld	r0,16(r1)		/* get return address */
++
++	mtlr    r0
++        blr				/* return to caller */
++
++#endif /* CONFIG_PPC_RTAS */
++
++#ifdef CONFIG_PPC_MULTIPLATFORM
++
++_GLOBAL(enter_prom)
++	mflr	r0
++	std	r0,16(r1)
++        stdu	r1,-PROM_FRAME_SIZE(r1)	/* Save SP and create stack space */
++
++	/* Because PROM is running in 32b mode, it clobbers the high order half
++	 * of all registers that it saves.  We therefore save those registers
++	 * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
++   	 */
++	SAVE_8GPRS(2, r1)
++	SAVE_GPR(13, r1)
++	SAVE_8GPRS(14, r1)
++	SAVE_10GPRS(22, r1)
++	mfcr	r4
++	std	r4,_CCR(r1)
++	mfctr	r5
++	std	r5,_CTR(r1)
++	mfspr	r6,SPRN_XER
++	std	r6,_XER(r1)
++	mfdar	r7
++	std	r7,_DAR(r1)
++	mfdsisr	r8
++	std	r8,_DSISR(r1)
++	mfsrr0	r9
++	std	r9,_SRR0(r1)
++	mfsrr1	r10
++	std	r10,_SRR1(r1)
++	mfmsr	r11
++	std	r11,_MSR(r1)
++
++	/* Get the PROM entrypoint */
++	ld	r0,GPR4(r1)
++	mtlr	r0
++
++	/* Switch MSR to 32 bits mode
++	 */
++        mfmsr   r11
++        li      r12,1
++        rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
++        andc    r11,r11,r12
++        li      r12,1
++        rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
++        andc    r11,r11,r12
++        mtmsrd  r11
++        isync
++
++	/* Restore arguments & enter PROM here... */
++	ld	r3,GPR3(r1)
++	blrl
++
++	/* Just make sure that r1 top 32 bits didn't get
++	 * corrupt by OF
++	 */
++	rldicl	r1,r1,0,32
++
++	/* Restore the MSR (back to 64 bits) */
++	ld	r0,_MSR(r1)
++	mtmsrd	r0
++        isync
++
++	/* Restore other registers */
++	REST_GPR(2, r1)
++	REST_GPR(13, r1)
++	REST_8GPRS(14, r1)
++	REST_10GPRS(22, r1)
++	ld	r4,_CCR(r1)
++	mtcr	r4
++	ld	r5,_CTR(r1)
++	mtctr	r5
++	ld	r6,_XER(r1)
++	mtspr	SPRN_XER,r6
++	ld	r7,_DAR(r1)
++	mtdar	r7
++	ld	r8,_DSISR(r1)
++	mtdsisr	r8
++	ld	r9,_SRR0(r1)
++	mtsrr0	r9
++	ld	r10,_SRR1(r1)
++	mtsrr1	r10
++	
++        addi	r1,r1,PROM_FRAME_SIZE
++	ld	r0,16(r1)
++	mtlr    r0
++        blr
++	
++#endif	/* CONFIG_PPC_MULTIPLATFORM */
+diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/fpu.S
+@@ -0,0 +1,144 @@
++/*
++ *  FPU support code, moved here from head.S so that it can be used
++ *  by chips which use other head-whatever.S files.
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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 <asm/reg.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/pgtable.h>
++#include <asm/cputable.h>
++#include <asm/cache.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++
++/*
++ * This task wants to use the FPU now.
++ * On UP, disable FP for the task which had the FPU previously,
++ * and save its floating-point registers in its thread_struct.
++ * Load up this task's FP registers from its thread_struct,
++ * enable the FPU for the current task and return to the task.
++ */
++_GLOBAL(load_up_fpu)
++	mfmsr	r5
++	ori	r5,r5,MSR_FP
++	SYNC
++	MTMSRD(r5)			/* enable use of fpu now */
++	isync
++/*
++ * For SMP, we don't do lazy FPU switching because it just gets too
++ * horrendously complex, especially when a task switches from one CPU
++ * to another.  Instead we call giveup_fpu in switch_to.
++ */
++#ifndef CONFIG_SMP
++	LOADBASE(r3, last_task_used_math)
++	toreal(r3)
++	LDL	r4,OFF(last_task_used_math)(r3)
++	CMPI	0,r4,0
++	beq	1f
++	toreal(r4)
++	addi	r4,r4,THREAD		/* want last_task_used_math->thread */
++	SAVE_32FPRS(0, r4)
++	mffs	fr0
++	stfd	fr0,THREAD_FPSCR(r4)
++	LDL	r5,PT_REGS(r4)
++	toreal(r5)
++	LDL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++	li	r10,MSR_FP|MSR_FE0|MSR_FE1
++	andc	r4,r4,r10		/* disable FP for previous task */
++	STL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++1:
++#endif /* CONFIG_SMP */
++	/* enable use of FP after return */
++#ifdef CONFIG_PPC32
++	mfspr	r5,SPRN_SPRG3		/* current task's THREAD (phys) */
++	lwz	r4,THREAD_FPEXC_MODE(r5)
++	ori	r9,r9,MSR_FP		/* enable FP for current */
++	or	r9,r9,r4
++#else
++	ld	r4,PACACURRENT(r13)
++	addi	r5,r4,THREAD		/* Get THREAD */
++	ld	r4,THREAD_FPEXC_MODE(r5)
++	ori	r12,r12,MSR_FP
++	or	r12,r12,r4
++	std	r12,_MSR(r1)
++#endif
++	lfd	fr0,THREAD_FPSCR(r5)
++	mtfsf	0xff,fr0
++	REST_32FPRS(0, r5)
++#ifndef CONFIG_SMP
++	subi	r4,r5,THREAD
++	fromreal(r4)
++	STL	r4,OFF(last_task_used_math)(r3)
++#endif /* CONFIG_SMP */
++	/* restore registers and return */
++	/* we haven't used ctr or xer or lr */
++	b	fast_exception_return
++
++/*
++ * giveup_fpu(tsk)
++ * Disable FP for the task given as the argument,
++ * and save the floating-point registers in its thread_struct.
++ * Enables the FPU for use in the kernel on return.
++ */
++_GLOBAL(giveup_fpu)
++	mfmsr	r5
++	ori	r5,r5,MSR_FP
++	SYNC_601
++	ISYNC_601
++	MTMSRD(r5)			/* enable use of fpu now */
++	SYNC_601
++	isync
++	CMPI	0,r3,0
++	beqlr-				/* if no previous owner, done */
++	addi	r3,r3,THREAD	        /* want THREAD of task */
++	LDL	r5,PT_REGS(r3)
++	CMPI	0,r5,0
++	SAVE_32FPRS(0, r3)
++	mffs	fr0
++	stfd	fr0,THREAD_FPSCR(r3)
++	beq	1f
++	LDL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++	li	r3,MSR_FP|MSR_FE0|MSR_FE1
++	andc	r4,r4,r3		/* disable FP for previous task */
++	STL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++1:
++#ifndef CONFIG_SMP
++	li	r5,0
++	LOADBASE(r4,last_task_used_math)
++	STL	r5,OFF(last_task_used_math)(r4)
++#endif /* CONFIG_SMP */
++	blr
++
++/*
++ * These are used in the alignment trap handler when emulating
++ * single-precision loads and stores.
++ * We restore and save the fpscr so the task gets the same result
++ * and exceptions as if the cpu had performed the load or store.
++ */
++
++_GLOBAL(cvt_fd)
++	lfd	0,THREAD_FPSCR(r5)	/* load up fpscr value */
++	mtfsf	0xff,0
++	lfs	0,0(r3)
++	stfd	0,0(r4)
++	mffs	0
++	stfd	0,THREAD_FPSCR(r5)	/* save new fpscr value */
++	blr
++
++_GLOBAL(cvt_df)
++	lfd	0,THREAD_FPSCR(r5)	/* load up fpscr value */
++	mtfsf	0xff,0
++	lfd	0,0(r3)
++	stfs	0,0(r4)
++	mffs	0
++	stfd	0,THREAD_FPSCR(r5)	/* save new fpscr value */
++	blr
+diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/head_32.S
+@@ -0,0 +1,1381 @@
++/*
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Rewritten by Cort Dougan (cort at cs.nmt.edu) for PReP
++ *    Copyright (C) 1996 Cort Dougan <cort at cs.nmt.edu>
++ *  Adapted for Power Macintosh by Paul Mackerras.
++ *  Low-level exception handlers and MMU support
++ *  rewritten by Paul Mackerras.
++ *    Copyright (C) 1996 Paul Mackerras.
++ *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek at jlc.net).
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  This file contains the low-level support and setup for the
++ *  PowerPC platform, including trap and interrupt dispatch.
++ *  (The PPC 8xx embedded CPUs use head_8xx.S instead.)
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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 <asm/reg.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/pgtable.h>
++#include <asm/cputable.h>
++#include <asm/cache.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++
++#ifdef CONFIG_APUS
++#include <asm/amigappc.h>
++#endif
++
++/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
++#define LOAD_BAT(n, reg, RA, RB)	\
++	/* see the comment for clear_bats() -- Cort */ \
++	li	RA,0;			\
++	mtspr	SPRN_IBAT##n##U,RA;	\
++	mtspr	SPRN_DBAT##n##U,RA;	\
++	lwz	RA,(n*16)+0(reg);	\
++	lwz	RB,(n*16)+4(reg);	\
++	mtspr	SPRN_IBAT##n##U,RA;	\
++	mtspr	SPRN_IBAT##n##L,RB;	\
++	beq	1f;			\
++	lwz	RA,(n*16)+8(reg);	\
++	lwz	RB,(n*16)+12(reg);	\
++	mtspr	SPRN_DBAT##n##U,RA;	\
++	mtspr	SPRN_DBAT##n##L,RB;	\
++1:
++
++	.text
++	.stabs	"arch/powerpc/kernel/",N_SO,0,0,0f
++	.stabs	"head_32.S",N_SO,0,0,0f
++0:
++	.globl	_stext
++_stext:
++
++/*
++ * _start is defined this way because the XCOFF loader in the OpenFirmware
++ * on the powermac expects the entry point to be a procedure descriptor.
++ */
++	.text
++	.globl	_start
++_start:
++	/*
++	 * These are here for legacy reasons, the kernel used to
++	 * need to look like a coff function entry for the pmac
++	 * but we're always started by some kind of bootloader now.
++	 *  -- Cort
++	 */
++	nop	/* used by __secondary_hold on prep (mtx) and chrp smp */
++	nop	/* used by __secondary_hold on prep (mtx) and chrp smp */
++	nop
++
++/* PMAC
++ * Enter here with the kernel text, data and bss loaded starting at
++ * 0, running with virtual == physical mapping.
++ * r5 points to the prom entry point (the client interface handler
++ * address).  Address translation is turned on, with the prom
++ * managing the hash table.  Interrupts are disabled.  The stack
++ * pointer (r1) points to just below the end of the half-meg region
++ * from 0x380000 - 0x400000, which is mapped in already.
++ *
++ * If we are booted from MacOS via BootX, we enter with the kernel
++ * image loaded somewhere, and the following values in registers:
++ *  r3: 'BooX' (0x426f6f58)
++ *  r4: virtual address of boot_infos_t
++ *  r5: 0
++ *
++ * APUS
++ *   r3: 'APUS'
++ *   r4: physical address of memory base
++ *   Linux/m68k style BootInfo structure at &_end.
++ *
++ * PREP
++ * This is jumped to on prep systems right after the kernel is relocated
++ * to its proper place in memory by the boot loader.  The expected layout
++ * of the regs is:
++ *   r3: ptr to residual data
++ *   r4: initrd_start or if no initrd then 0
++ *   r5: initrd_end - unused if r4 is 0
++ *   r6: Start of command line string
++ *   r7: End of command line string
++ *
++ * This just gets a minimal mmu environment setup so we can call
++ * start_here() to do the real work.
++ * -- Cort
++ */
++
++	.globl	__start
++__start:
++/*
++ * We have to do any OF calls before we map ourselves to KERNELBASE,
++ * because OF may have I/O devices mapped into that area
++ * (particularly on CHRP).
++ */
++	cmpwi	0,r5,0
++	beq	1f
++	bl	prom_init
++	trap
++
++1:	mr	r31,r3			/* save parameters */
++	mr	r30,r4
++	li	r24,0			/* cpu # */
++
++/*
++ * early_init() does the early machine identification and does
++ * the necessary low-level setup and clears the BSS
++ *  -- Cort <cort at fsmlabs.com>
++ */
++	bl	early_init
++
++#ifdef CONFIG_APUS
++/* On APUS the __va/__pa constants need to be set to the correct
++ * values before continuing.
++ */
++	mr	r4,r30
++	bl	fix_mem_constants
++#endif /* CONFIG_APUS */
++
++/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
++ * the physical address we are running at, returned by early_init()
++ */
++ 	bl	mmu_off
++__after_mmu_off:
++	bl	clear_bats
++	bl	flush_tlbs
++
++	bl	initial_bats
++
++/*
++ * Call setup_cpu for CPU 0 and initialize 6xx Idle
++ */
++	bl	reloc_offset
++	li	r24,0			/* cpu# */
++	bl	call_setup_cpu		/* Call setup_cpu for this CPU */
++#ifdef CONFIG_6xx
++	bl	reloc_offset
++	bl	init_idle_6xx
++#endif /* CONFIG_6xx */
++
++
++#ifndef CONFIG_APUS
++/*
++ * We need to run with _start at physical address 0.
++ * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
++ * the exception vectors at 0 (and therefore this copy
++ * overwrites OF's exception vectors with our own).
++ * The MMU is off at this point.
++ */
++	bl	reloc_offset
++	mr	r26,r3
++	addis	r4,r3,KERNELBASE at h	/* current address of _start */
++	cmpwi	0,r4,0			/* are we already running at 0? */
++	bne	relocate_kernel
++#endif /* CONFIG_APUS */
++/*
++ * we now have the 1st 16M of ram mapped with the bats.
++ * prep needs the mmu to be turned on here, but pmac already has it on.
++ * this shouldn't bother the pmac since it just gets turned on again
++ * as we jump to our code at KERNELBASE. -- Cort
++ * Actually no, pmac doesn't have it on any more. BootX enters with MMU
++ * off, and in other cases, we now turn it off before changing BATs above.
++ */
++turn_on_mmu:
++	mfmsr	r0
++	ori	r0,r0,MSR_DR|MSR_IR
++	mtspr	SPRN_SRR1,r0
++	lis	r0,start_here at h
++	ori	r0,r0,start_here at l
++	mtspr	SPRN_SRR0,r0
++	SYNC
++	RFI				/* enables MMU */
++
++/*
++ * We need __secondary_hold as a place to hold the other cpus on
++ * an SMP machine, even when we are running a UP kernel.
++ */
++	. = 0xc0			/* for prep bootloader */
++	li	r3,1			/* MTX only has 1 cpu */
++	.globl	__secondary_hold
++__secondary_hold:
++	/* tell the master we're here */
++	stw	r3,__secondary_hold_acknowledge at l(0)
++#ifdef CONFIG_SMP
++100:	lwz	r4,0(0)
++	/* wait until we're told to start */
++	cmpw	0,r4,r3
++	bne	100b
++	/* our cpu # was at addr 0 - go */
++	mr	r24,r3			/* cpu # */
++	b	__secondary_start
++#else
++	b	.
++#endif /* CONFIG_SMP */
++
++	.globl	__secondary_hold_spinloop
++__secondary_hold_spinloop:
++	.long	0
++	.globl	__secondary_hold_acknowledge
++__secondary_hold_acknowledge:
++	.long	-1
++
++/*
++ * Exception entry code.  This code runs with address translation
++ * turned off, i.e. using physical addresses.
++ * We assume sprg3 has the physical address of the current
++ * task's thread_struct.
++ */
++#define EXCEPTION_PROLOG	\
++	mtspr	SPRN_SPRG0,r10;	\
++	mtspr	SPRN_SPRG1,r11;	\
++	mfcr	r10;		\
++	EXCEPTION_PROLOG_1;	\
++	EXCEPTION_PROLOG_2
++
++#define EXCEPTION_PROLOG_1	\
++	mfspr	r11,SPRN_SRR1;		/* check whether user or kernel */ \
++	andi.	r11,r11,MSR_PR;	\
++	tophys(r11,r1);			/* use tophys(r1) if kernel */ \
++	beq	1f;		\
++	mfspr	r11,SPRN_SPRG3;	\
++	lwz	r11,THREAD_INFO-THREAD(r11);	\
++	addi	r11,r11,THREAD_SIZE;	\
++	tophys(r11,r11);	\
++1:	subi	r11,r11,INT_FRAME_SIZE	/* alloc exc. frame */
++
++
++#define EXCEPTION_PROLOG_2	\
++	CLR_TOP32(r11);		\
++	stw	r10,_CCR(r11);		/* save registers */ \
++	stw	r12,GPR12(r11);	\
++	stw	r9,GPR9(r11);	\
++	mfspr	r10,SPRN_SPRG0;	\
++	stw	r10,GPR10(r11);	\
++	mfspr	r12,SPRN_SPRG1;	\
++	stw	r12,GPR11(r11);	\
++	mflr	r10;		\
++	stw	r10,_LINK(r11);	\
++	mfspr	r12,SPRN_SRR0;	\
++	mfspr	r9,SPRN_SRR1;	\
++	stw	r1,GPR1(r11);	\
++	stw	r1,0(r11);	\
++	tovirt(r1,r11);			/* set new kernel sp */	\
++	li	r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
++	MTMSRD(r10);			/* (except for mach check in rtas) */ \
++	stw	r0,GPR0(r11);	\
++	lis	r10,0x7265;		/* put exception frame marker */ \
++	addi	r10,r10,0x6773;	\
++	stw	r10,8(r11);	\
++	SAVE_4GPRS(3, r11);	\
++	SAVE_2GPRS(7, r11)
++
++/*
++ * Note: code which follows this uses cr0.eq (set if from kernel),
++ * r11, r12 (SRR0), and r9 (SRR1).
++ *
++ * Note2: once we have set r1 we are in a position to take exceptions
++ * again, and we could thus set MSR:RI at that point.
++ */
++
++/*
++ * Exception vectors.
++ */
++#define EXCEPTION(n, label, hdlr, xfer)		\
++	. = n;					\
++label:						\
++	EXCEPTION_PROLOG;			\
++	addi	r3,r1,STACK_FRAME_OVERHEAD;	\
++	xfer(n, hdlr)
++
++#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret)	\
++	li	r10,trap;					\
++	stw	r10,_TRAP(r11);					\
++	li	r10,MSR_KERNEL;					\
++	copyee(r10, r9);					\
++	bl	tfer;						\
++i##n:								\
++	.long	hdlr;						\
++	.long	ret
++
++#define COPY_EE(d, s)		rlwimi d,s,0,16,16
++#define NOCOPY(d, s)
++
++#define EXC_XFER_STD(n, hdlr)		\
++	EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full,	\
++			  ret_from_except_full)
++
++#define EXC_XFER_LITE(n, hdlr)		\
++	EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
++			  ret_from_except)
++
++#define EXC_XFER_EE(n, hdlr)		\
++	EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
++			  ret_from_except_full)
++
++#define EXC_XFER_EE_LITE(n, hdlr)	\
++	EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
++			  ret_from_except)
++
++/* System reset */
++/* core99 pmac starts the seconary here by changing the vector, and
++   putting it back to what it was (unknown_exception) when done.  */
++#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
++	. = 0x100
++	b	__secondary_start_gemini
++#else
++	EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
++#endif
++
++/* Machine check */
++/*
++ * On CHRP, this is complicated by the fact that we could get a
++ * machine check inside RTAS, and we have no guarantee that certain
++ * critical registers will have the values we expect.  The set of
++ * registers that might have bad values includes all the GPRs
++ * and all the BATs.  We indicate that we are in RTAS by putting
++ * a non-zero value, the address of the exception frame to use,
++ * in SPRG2.  The machine check handler checks SPRG2 and uses its
++ * value if it is non-zero.  If we ever needed to free up SPRG2,
++ * we could use a field in the thread_info or thread_struct instead.
++ * (Other exception handlers assume that r1 is a valid kernel stack
++ * pointer when we take an exception from supervisor mode.)
++ *	-- paulus.
++ */
++	. = 0x200
++	mtspr	SPRN_SPRG0,r10
++	mtspr	SPRN_SPRG1,r11
++	mfcr	r10
++#ifdef CONFIG_PPC_CHRP
++	mfspr	r11,SPRN_SPRG2
++	cmpwi	0,r11,0
++	bne	7f
++#endif /* CONFIG_PPC_CHRP */
++	EXCEPTION_PROLOG_1
++7:	EXCEPTION_PROLOG_2
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++#ifdef CONFIG_PPC_CHRP
++	mfspr	r4,SPRN_SPRG2
++	cmpwi	cr1,r4,0
++	bne	cr1,1f
++#endif
++	EXC_XFER_STD(0x200, machine_check_exception)
++#ifdef CONFIG_PPC_CHRP
++1:	b	machine_check_in_rtas
++#endif
++
++/* Data access exception. */
++	. = 0x300
++DataAccess:
++	EXCEPTION_PROLOG
++	mfspr	r10,SPRN_DSISR
++	andis.	r0,r10,0xa470		/* weird error? */
++	bne	1f			/* if not, try to put a PTE */
++	mfspr	r4,SPRN_DAR		/* into the hash table */
++	rlwinm	r3,r10,32-15,21,21	/* DSISR_STORE -> _PAGE_RW */
++	bl	hash_page
++1:	stw	r10,_DSISR(r11)
++	mr	r5,r10
++	mfspr	r4,SPRN_DAR
++	EXC_XFER_EE_LITE(0x300, handle_page_fault)
++
++
++/* Instruction access exception. */
++	. = 0x400
++InstructionAccess:
++	EXCEPTION_PROLOG
++	andis.	r0,r9,0x4000		/* no pte found? */
++	beq	1f			/* if so, try to put a PTE */
++	li	r3,0			/* into the hash table */
++	mr	r4,r12			/* SRR0 is fault address */
++	bl	hash_page
++1:	mr	r4,r12
++	mr	r5,r9
++	EXC_XFER_EE_LITE(0x400, handle_page_fault)
++
++/* External interrupt */
++	EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
++
++/* Alignment exception */
++	. = 0x600
++Alignment:
++	EXCEPTION_PROLOG
++	mfspr	r4,SPRN_DAR
++	stw	r4,_DAR(r11)
++	mfspr	r5,SPRN_DSISR
++	stw	r5,_DSISR(r11)
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_EE(0x600, alignment_exception)
++
++/* Program check exception */
++	EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
++
++/* Floating-point unavailable */
++	. = 0x800
++FPUnavailable:
++	EXCEPTION_PROLOG
++	bne	load_up_fpu		/* if from user, just load it up */
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
++
++/* Decrementer */
++	EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
++
++	EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
++
++/* System call */
++	. = 0xc00
++SystemCall:
++	EXCEPTION_PROLOG
++	EXC_XFER_EE_LITE(0xc00, DoSyscall)
++
++/* Single step - not used on 601 */
++	EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
++	EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
++
++/*
++ * The Altivec unavailable trap is at 0x0f20.  Foo.
++ * We effectively remap it to 0x3000.
++ * We include an altivec unavailable exception vector even if
++ * not configured for Altivec, so that you can't panic a
++ * non-altivec kernel running on a machine with altivec just
++ * by executing an altivec instruction.
++ */
++	. = 0xf00
++	b	Trap_0f
++
++	. = 0xf20
++	b	AltiVecUnavailable
++
++Trap_0f:
++	EXCEPTION_PROLOG
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_EE(0xf00, unknown_exception)
++
++/*
++ * Handle TLB miss for instruction on 603/603e.
++ * Note: we get an alternate set of r0 - r3 to use automatically.
++ */
++	. = 0x1000
++InstructionTLBMiss:
++/*
++ * r0:	stored ctr
++ * r1:	linux style pte ( later becomes ppc hardware pte )
++ * r2:	ptr to linux-style pte
++ * r3:	scratch
++ */
++	mfctr	r0
++	/* Get PTE (linux-style) and check access */
++	mfspr	r3,SPRN_IMISS
++	lis	r1,KERNELBASE at h		/* check if kernel address */
++	cmplw	0,r3,r1
++	mfspr	r2,SPRN_SPRG3
++	li	r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
++	lwz	r2,PGDIR(r2)
++	blt+	112f
++	lis	r2,swapper_pg_dir at ha	/* if kernel address, use */
++	addi	r2,r2,swapper_pg_dir at l	/* kernel page table */
++	mfspr	r1,SPRN_SRR1		/* and MSR_PR bit from SRR1 */
++	rlwinm	r1,r1,32-12,29,29	/* shift MSR_PR to _PAGE_USER posn */
++112:	tophys(r2,r2)
++	rlwimi	r2,r3,12,20,29		/* insert top 10 bits of address */
++	lwz	r2,0(r2)		/* get pmd entry */
++	rlwinm.	r2,r2,0,0,19		/* extract address of pte page */
++	beq-	InstructionAddressInvalid	/* return if no mapping */
++	rlwimi	r2,r3,22,20,29		/* insert next 10 bits of address */
++	lwz	r3,0(r2)		/* get linux-style pte */
++	andc.	r1,r1,r3		/* check access & ~permission */
++	bne-	InstructionAddressInvalid /* return if access not permitted */
++	ori	r3,r3,_PAGE_ACCESSED	/* set _PAGE_ACCESSED in pte */
++	/*
++	 * NOTE! We are assuming this is not an SMP system, otherwise
++	 * we would need to update the pte atomically with lwarx/stwcx.
++	 */
++	stw	r3,0(r2)		/* update PTE (accessed bit) */
++	/* Convert linux-style PTE to low word of PPC-style PTE */
++	rlwinm	r1,r3,32-10,31,31	/* _PAGE_RW -> PP lsb */
++	rlwinm	r2,r3,32-7,31,31	/* _PAGE_DIRTY -> PP lsb */
++	and	r1,r1,r2		/* writable if _RW and _DIRTY */
++	rlwimi	r3,r3,32-1,30,30	/* _PAGE_USER -> PP msb */
++	rlwimi	r3,r3,32-1,31,31	/* _PAGE_USER -> PP lsb */
++	ori	r1,r1,0xe14		/* clear out reserved bits and M */
++	andc	r1,r3,r1		/* PP = user? (rw&dirty? 2: 3): 0 */
++	mtspr	SPRN_RPA,r1
++	mfspr	r3,SPRN_IMISS
++	tlbli	r3
++	mfspr	r3,SPRN_SRR1		/* Need to restore CR0 */
++	mtcrf	0x80,r3
++	rfi
++InstructionAddressInvalid:
++	mfspr	r3,SPRN_SRR1
++	rlwinm	r1,r3,9,6,6	/* Get load/store bit */
++
++	addis	r1,r1,0x2000
++	mtspr	SPRN_DSISR,r1	/* (shouldn't be needed) */
++	mtctr	r0		/* Restore CTR */
++	andi.	r2,r3,0xFFFF	/* Clear upper bits of SRR1 */
++	or	r2,r2,r1
++	mtspr	SPRN_SRR1,r2
++	mfspr	r1,SPRN_IMISS	/* Get failing address */
++	rlwinm.	r2,r2,0,31,31	/* Check for little endian access */
++	rlwimi	r2,r2,1,30,30	/* change 1 -> 3 */
++	xor	r1,r1,r2
++	mtspr	SPRN_DAR,r1	/* Set fault address */
++	mfmsr	r0		/* Restore "normal" registers */
++	xoris	r0,r0,MSR_TGPR>>16
++	mtcrf	0x80,r3		/* Restore CR0 */
++	mtmsr	r0
++	b	InstructionAccess
++
++/*
++ * Handle TLB miss for DATA Load operation on 603/603e
++ */
++	. = 0x1100
++DataLoadTLBMiss:
++/*
++ * r0:	stored ctr
++ * r1:	linux style pte ( later becomes ppc hardware pte )
++ * r2:	ptr to linux-style pte
++ * r3:	scratch
++ */
++	mfctr	r0
++	/* Get PTE (linux-style) and check access */
++	mfspr	r3,SPRN_DMISS
++	lis	r1,KERNELBASE at h		/* check if kernel address */
++	cmplw	0,r3,r1
++	mfspr	r2,SPRN_SPRG3
++	li	r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
++	lwz	r2,PGDIR(r2)
++	blt+	112f
++	lis	r2,swapper_pg_dir at ha	/* if kernel address, use */
++	addi	r2,r2,swapper_pg_dir at l	/* kernel page table */
++	mfspr	r1,SPRN_SRR1		/* and MSR_PR bit from SRR1 */
++	rlwinm	r1,r1,32-12,29,29	/* shift MSR_PR to _PAGE_USER posn */
++112:	tophys(r2,r2)
++	rlwimi	r2,r3,12,20,29		/* insert top 10 bits of address */
++	lwz	r2,0(r2)		/* get pmd entry */
++	rlwinm.	r2,r2,0,0,19		/* extract address of pte page */
++	beq-	DataAddressInvalid	/* return if no mapping */
++	rlwimi	r2,r3,22,20,29		/* insert next 10 bits of address */
++	lwz	r3,0(r2)		/* get linux-style pte */
++	andc.	r1,r1,r3		/* check access & ~permission */
++	bne-	DataAddressInvalid	/* return if access not permitted */
++	ori	r3,r3,_PAGE_ACCESSED	/* set _PAGE_ACCESSED in pte */
++	/*
++	 * NOTE! We are assuming this is not an SMP system, otherwise
++	 * we would need to update the pte atomically with lwarx/stwcx.
++	 */
++	stw	r3,0(r2)		/* update PTE (accessed bit) */
++	/* Convert linux-style PTE to low word of PPC-style PTE */
++	rlwinm	r1,r3,32-10,31,31	/* _PAGE_RW -> PP lsb */
++	rlwinm	r2,r3,32-7,31,31	/* _PAGE_DIRTY -> PP lsb */
++	and	r1,r1,r2		/* writable if _RW and _DIRTY */
++	rlwimi	r3,r3,32-1,30,30	/* _PAGE_USER -> PP msb */
++	rlwimi	r3,r3,32-1,31,31	/* _PAGE_USER -> PP lsb */
++	ori	r1,r1,0xe14		/* clear out reserved bits and M */
++	andc	r1,r3,r1		/* PP = user? (rw&dirty? 2: 3): 0 */
++	mtspr	SPRN_RPA,r1
++	mfspr	r3,SPRN_DMISS
++	tlbld	r3
++	mfspr	r3,SPRN_SRR1		/* Need to restore CR0 */
++	mtcrf	0x80,r3
++	rfi
++DataAddressInvalid:
++	mfspr	r3,SPRN_SRR1
++	rlwinm	r1,r3,9,6,6	/* Get load/store bit */
++	addis	r1,r1,0x2000
++	mtspr	SPRN_DSISR,r1
++	mtctr	r0		/* Restore CTR */
++	andi.	r2,r3,0xFFFF	/* Clear upper bits of SRR1 */
++	mtspr	SPRN_SRR1,r2
++	mfspr	r1,SPRN_DMISS	/* Get failing address */
++	rlwinm.	r2,r2,0,31,31	/* Check for little endian access */
++	beq	20f		/* Jump if big endian */
++	xori	r1,r1,3
++20:	mtspr	SPRN_DAR,r1	/* Set fault address */
++	mfmsr	r0		/* Restore "normal" registers */
++	xoris	r0,r0,MSR_TGPR>>16
++	mtcrf	0x80,r3		/* Restore CR0 */
++	mtmsr	r0
++	b	DataAccess
++
++/*
++ * Handle TLB miss for DATA Store on 603/603e
++ */
++	. = 0x1200
++DataStoreTLBMiss:
++/*
++ * r0:	stored ctr
++ * r1:	linux style pte ( later becomes ppc hardware pte )
++ * r2:	ptr to linux-style pte
++ * r3:	scratch
++ */
++	mfctr	r0
++	/* Get PTE (linux-style) and check access */
++	mfspr	r3,SPRN_DMISS
++	lis	r1,KERNELBASE at h		/* check if kernel address */
++	cmplw	0,r3,r1
++	mfspr	r2,SPRN_SPRG3
++	li	r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */
++	lwz	r2,PGDIR(r2)
++	blt+	112f
++	lis	r2,swapper_pg_dir at ha	/* if kernel address, use */
++	addi	r2,r2,swapper_pg_dir at l	/* kernel page table */
++	mfspr	r1,SPRN_SRR1		/* and MSR_PR bit from SRR1 */
++	rlwinm	r1,r1,32-12,29,29	/* shift MSR_PR to _PAGE_USER posn */
++112:	tophys(r2,r2)
++	rlwimi	r2,r3,12,20,29		/* insert top 10 bits of address */
++	lwz	r2,0(r2)		/* get pmd entry */
++	rlwinm.	r2,r2,0,0,19		/* extract address of pte page */
++	beq-	DataAddressInvalid	/* return if no mapping */
++	rlwimi	r2,r3,22,20,29		/* insert next 10 bits of address */
++	lwz	r3,0(r2)		/* get linux-style pte */
++	andc.	r1,r1,r3		/* check access & ~permission */
++	bne-	DataAddressInvalid	/* return if access not permitted */
++	ori	r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY
++	/*
++	 * NOTE! We are assuming this is not an SMP system, otherwise
++	 * we would need to update the pte atomically with lwarx/stwcx.
++	 */
++	stw	r3,0(r2)		/* update PTE (accessed/dirty bits) */
++	/* Convert linux-style PTE to low word of PPC-style PTE */
++	rlwimi	r3,r3,32-1,30,30	/* _PAGE_USER -> PP msb */
++	li	r1,0xe15		/* clear out reserved bits and M */
++	andc	r1,r3,r1		/* PP = user? 2: 0 */
++	mtspr	SPRN_RPA,r1
++	mfspr	r3,SPRN_DMISS
++	tlbld	r3
++	mfspr	r3,SPRN_SRR1		/* Need to restore CR0 */
++	mtcrf	0x80,r3
++	rfi
++
++#ifndef CONFIG_ALTIVEC
++#define altivec_assist_exception	unknown_exception
++#endif
++
++	EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE)
++	EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
++	EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE)
++	EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
++	EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE)
++	EXCEPTION(0x2100, Trap_21, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2200, Trap_22, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2300, Trap_23, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2400, Trap_24, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2500, Trap_25, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2600, Trap_26, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2700, Trap_27, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2800, Trap_28, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2900, Trap_29, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2a00, Trap_2a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2b00, Trap_2b, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2f00, MOLTrampoline, unknown_exception, EXC_XFER_EE_LITE)
++
++	.globl mol_trampoline
++	.set mol_trampoline, i0x2f00
++
++	. = 0x3000
++
++AltiVecUnavailable:
++	EXCEPTION_PROLOG
++#ifdef CONFIG_ALTIVEC
++	bne	load_up_altivec		/* if from user, just load it up */
++#endif /* CONFIG_ALTIVEC */
++	EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
++
++#ifdef CONFIG_ALTIVEC
++/* Note that the AltiVec support is closely modeled after the FP
++ * support.  Changes to one are likely to be applicable to the
++ * other!  */
++load_up_altivec:
++/*
++ * Disable AltiVec for the task which had AltiVec previously,
++ * and save its AltiVec registers in its thread_struct.
++ * Enables AltiVec for use in the kernel on return.
++ * On SMP we know the AltiVec units are free, since we give it up every
++ * switch.  -- Kumar
++ */
++	mfmsr	r5
++	oris	r5,r5,MSR_VEC at h
++	MTMSRD(r5)			/* enable use of AltiVec now */
++	isync
++/*
++ * For SMP, we don't do lazy AltiVec switching because it just gets too
++ * horrendously complex, especially when a task switches from one CPU
++ * to another.  Instead we call giveup_altivec in switch_to.
++ */
++#ifndef CONFIG_SMP
++	tophys(r6,0)
++	addis	r3,r6,last_task_used_altivec at ha
++	lwz	r4,last_task_used_altivec at l(r3)
++	cmpwi	0,r4,0
++	beq	1f
++	add	r4,r4,r6
++	addi	r4,r4,THREAD	/* want THREAD of last_task_used_altivec */
++	SAVE_32VRS(0,r10,r4)
++	mfvscr	vr0
++	li	r10,THREAD_VSCR
++	stvx	vr0,r10,r4
++	lwz	r5,PT_REGS(r4)
++	add	r5,r5,r6
++	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++	lis	r10,MSR_VEC at h
++	andc	r4,r4,r10	/* disable altivec for previous task */
++	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++1:
++#endif /* CONFIG_SMP */
++	/* enable use of AltiVec after return */
++	oris	r9,r9,MSR_VEC at h
++	mfspr	r5,SPRN_SPRG3		/* current task's THREAD (phys) */
++	li	r4,1
++	li	r10,THREAD_VSCR
++	stw	r4,THREAD_USED_VR(r5)
++	lvx	vr0,r10,r5
++	mtvscr	vr0
++	REST_32VRS(0,r10,r5)
++#ifndef CONFIG_SMP
++	subi	r4,r5,THREAD
++	sub	r4,r4,r6
++	stw	r4,last_task_used_altivec at l(r3)
++#endif /* CONFIG_SMP */
++	/* restore registers and return */
++	/* we haven't used ctr or xer or lr */
++	b	fast_exception_return
++
++/*
++ * AltiVec unavailable trap from kernel - print a message, but let
++ * the task use AltiVec in the kernel until it returns to user mode.
++ */
++KernelAltiVec:
++	lwz	r3,_MSR(r1)
++	oris	r3,r3,MSR_VEC at h
++	stw	r3,_MSR(r1)	/* enable use of AltiVec after return */
++	lis	r3,87f at h
++	ori	r3,r3,87f at l
++	mr	r4,r2		/* current */
++	lwz	r5,_NIP(r1)
++	bl	printk
++	b	ret_from_except
++87:	.string	"AltiVec used in kernel  (task=%p, pc=%x)  \n"
++	.align	4,0
++
++/*
++ * giveup_altivec(tsk)
++ * Disable AltiVec for the task given as the argument,
++ * and save the AltiVec registers in its thread_struct.
++ * Enables AltiVec for use in the kernel on return.
++ */
++
++	.globl	giveup_altivec
++giveup_altivec:
++	mfmsr	r5
++	oris	r5,r5,MSR_VEC at h
++	SYNC
++	MTMSRD(r5)			/* enable use of AltiVec now */
++	isync
++	cmpwi	0,r3,0
++	beqlr-				/* if no previous owner, done */
++	addi	r3,r3,THREAD		/* want THREAD of task */
++	lwz	r5,PT_REGS(r3)
++	cmpwi	0,r5,0
++	SAVE_32VRS(0, r4, r3)
++	mfvscr	vr0
++	li	r4,THREAD_VSCR
++	stvx	vr0,r4,r3
++	beq	1f
++	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++	lis	r3,MSR_VEC at h
++	andc	r4,r4,r3		/* disable AltiVec for previous task */
++	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++1:
++#ifndef CONFIG_SMP
++	li	r5,0
++	lis	r4,last_task_used_altivec at ha
++	stw	r5,last_task_used_altivec at l(r4)
++#endif /* CONFIG_SMP */
++	blr
++#endif /* CONFIG_ALTIVEC */
++
++/*
++ * This code is jumped to from the startup code to copy
++ * the kernel image to physical address 0.
++ */
++relocate_kernel:
++	addis	r9,r26,klimit at ha	/* fetch klimit */
++	lwz	r25,klimit at l(r9)
++	addis	r25,r25,-KERNELBASE at h
++	li	r3,0			/* Destination base address */
++	li	r6,0			/* Destination offset */
++	li	r5,0x4000		/* # bytes of memory to copy */
++	bl	copy_and_flush		/* copy the first 0x4000 bytes */
++	addi	r0,r3,4f at l		/* jump to the address of 4f */
++	mtctr	r0			/* in copy and do the rest. */
++	bctr				/* jump to the copy */
++4:	mr	r5,r25
++	bl	copy_and_flush		/* copy the rest */
++	b	turn_on_mmu
++
++/*
++ * Copy routine used to copy the kernel to start at physical address 0
++ * and flush and invalidate the caches as needed.
++ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
++ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
++ */
++_GLOBAL(copy_and_flush)
++	addi	r5,r5,-4
++	addi	r6,r6,-4
++4:	li	r0,L1_CACHE_BYTES/4
++	mtctr	r0
++3:	addi	r6,r6,4			/* copy a cache line */
++	lwzx	r0,r6,r4
++	stwx	r0,r6,r3
++	bdnz	3b
++	dcbst	r6,r3			/* write it to memory */
++	sync
++	icbi	r6,r3			/* flush the icache line */
++	cmplw	0,r6,r5
++	blt	4b
++	sync				/* additional sync needed on g4 */
++	isync
++	addi	r5,r5,4
++	addi	r6,r6,4
++	blr
++
++#ifdef CONFIG_APUS
++/*
++ * On APUS the physical base address of the kernel is not known at compile
++ * time, which means the __pa/__va constants used are incorrect. In the
++ * __init section is recorded the virtual addresses of instructions using
++ * these constants, so all that has to be done is fix these before
++ * continuing the kernel boot.
++ *
++ * r4 = The physical address of the kernel base.
++ */
++fix_mem_constants:
++	mr	r10,r4
++	addis	r10,r10,-KERNELBASE at h    /* virt_to_phys constant */
++	neg	r11,r10	                 /* phys_to_virt constant */
++
++	lis	r12,__vtop_table_begin at h
++	ori	r12,r12,__vtop_table_begin at l
++	add	r12,r12,r10	         /* table begin phys address */
++	lis	r13,__vtop_table_end at h
++	ori	r13,r13,__vtop_table_end at l
++	add	r13,r13,r10	         /* table end phys address */
++	subi	r12,r12,4
++	subi	r13,r13,4
++1:	lwzu	r14,4(r12)               /* virt address of instruction */
++	add     r14,r14,r10              /* phys address of instruction */
++	lwz     r15,0(r14)               /* instruction, now insert top */
++	rlwimi  r15,r10,16,16,31         /* half of vp const in low half */
++	stw	r15,0(r14)               /* of instruction and restore. */
++	dcbst	r0,r14			 /* write it to memory */
++	sync
++	icbi	r0,r14			 /* flush the icache line */
++	cmpw	r12,r13
++	bne     1b
++	sync				/* additional sync needed on g4 */
++	isync
++
++/*
++ * Map the memory where the exception handlers will
++ * be copied to when hash constants have been patched.
++ */
++#ifdef CONFIG_APUS_FAST_EXCEPT
++	lis	r8,0xfff0
++#else
++	lis	r8,0
++#endif
++	ori	r8,r8,0x2		/* 128KB, supervisor */
++	mtspr	SPRN_DBAT3U,r8
++	mtspr	SPRN_DBAT3L,r8
++
++	lis	r12,__ptov_table_begin at h
++	ori	r12,r12,__ptov_table_begin at l
++	add	r12,r12,r10	         /* table begin phys address */
++	lis	r13,__ptov_table_end at h
++	ori	r13,r13,__ptov_table_end at l
++	add	r13,r13,r10	         /* table end phys address */
++	subi	r12,r12,4
++	subi	r13,r13,4
++1:	lwzu	r14,4(r12)               /* virt address of instruction */
++	add     r14,r14,r10              /* phys address of instruction */
++	lwz     r15,0(r14)               /* instruction, now insert top */
++	rlwimi  r15,r11,16,16,31         /* half of pv const in low half*/
++	stw	r15,0(r14)               /* of instruction and restore. */
++	dcbst	r0,r14			 /* write it to memory */
++	sync
++	icbi	r0,r14			 /* flush the icache line */
++	cmpw	r12,r13
++	bne     1b
++
++	sync				/* additional sync needed on g4 */
++	isync				/* No speculative loading until now */
++	blr
++
++/***********************************************************************
++ *  Please note that on APUS the exception handlers are located at the
++ *  physical address 0xfff0000. For this reason, the exception handlers
++ *  cannot use relative branches to access the code below.
++ ***********************************************************************/
++#endif /* CONFIG_APUS */
++
++#ifdef CONFIG_SMP
++#ifdef CONFIG_GEMINI
++	.globl	__secondary_start_gemini
++__secondary_start_gemini:
++        mfspr   r4,SPRN_HID0
++        ori     r4,r4,HID0_ICFI
++        li      r3,0
++        ori     r3,r3,HID0_ICE
++        andc    r4,r4,r3
++        mtspr   SPRN_HID0,r4
++        sync
++        b       __secondary_start
++#endif /* CONFIG_GEMINI */
++
++	.globl	__secondary_start_pmac_0
++__secondary_start_pmac_0:
++	/* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
++	li	r24,0
++	b	1f
++	li	r24,1
++	b	1f
++	li	r24,2
++	b	1f
++	li	r24,3
++1:
++	/* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0
++	   set to map the 0xf0000000 - 0xffffffff region */
++	mfmsr	r0
++	rlwinm	r0,r0,0,28,26		/* clear DR (0x10) */
++	SYNC
++	mtmsr	r0
++	isync
++
++	.globl	__secondary_start
++__secondary_start:
++	/* Copy some CPU settings from CPU 0 */
++	bl	__restore_cpu_setup
++
++	lis	r3,-KERNELBASE at h
++	mr	r4,r24
++	bl	call_setup_cpu		/* Call setup_cpu for this CPU */
++#ifdef CONFIG_6xx
++	lis	r3,-KERNELBASE at h
++	bl	init_idle_6xx
++#endif /* CONFIG_6xx */
++
++	/* get current_thread_info and current */
++	lis	r1,secondary_ti at ha
++	tophys(r1,r1)
++	lwz	r1,secondary_ti at l(r1)
++	tophys(r2,r1)
++	lwz	r2,TI_TASK(r2)
++
++	/* stack */
++	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
++	li	r0,0
++	tophys(r3,r1)
++	stw	r0,0(r3)
++
++	/* load up the MMU */
++	bl	load_up_mmu
++
++	/* ptr to phys current thread */
++	tophys(r4,r2)
++	addi	r4,r4,THREAD	/* phys address of our thread_struct */
++	CLR_TOP32(r4)
++	mtspr	SPRN_SPRG3,r4
++	li	r3,0
++	mtspr	SPRN_SPRG2,r3	/* 0 => not in RTAS */
++
++	/* enable MMU and jump to start_secondary */
++	li	r4,MSR_KERNEL
++	FIX_SRR1(r4,r5)
++	lis	r3,start_secondary at h
++	ori	r3,r3,start_secondary at l
++	mtspr	SPRN_SRR0,r3
++	mtspr	SPRN_SRR1,r4
++	SYNC
++	RFI
++#endif /* CONFIG_SMP */
++
++/*
++ * Those generic dummy functions are kept for CPUs not
++ * included in CONFIG_6xx
++ */
++#if !defined(CONFIG_6xx)
++_GLOBAL(__save_cpu_setup)
++	blr
++_GLOBAL(__restore_cpu_setup)
++	blr
++#endif /* !defined(CONFIG_6xx) */
++
++
++/*
++ * Load stuff into the MMU.  Intended to be called with
++ * IR=0 and DR=0.
++ */
++load_up_mmu:
++	sync			/* Force all PTE updates to finish */
++	isync
++	tlbia			/* Clear all TLB entries */
++	sync			/* wait for tlbia/tlbie to finish */
++	TLBSYNC			/* ... on all CPUs */
++	/* Load the SDR1 register (hash table base & size) */
++	lis	r6,_SDR1 at ha
++	tophys(r6,r6)
++	lwz	r6,_SDR1 at l(r6)
++	mtspr	SPRN_SDR1,r6
++	li	r0,16		/* load up segment register values */
++	mtctr	r0		/* for context 0 */
++	lis	r3,0x2000	/* Ku = 1, VSID = 0 */
++	li	r4,0
++3:	mtsrin	r3,r4
++	addi	r3,r3,0x111	/* increment VSID */
++	addis	r4,r4,0x1000	/* address of next segment */
++	bdnz	3b
++
++/* Load the BAT registers with the values set up by MMU_init.
++   MMU_init takes care of whether we're on a 601 or not. */
++	mfpvr	r3
++	srwi	r3,r3,16
++	cmpwi	r3,1
++	lis	r3,BATS at ha
++	addi	r3,r3,BATS at l
++	tophys(r3,r3)
++	LOAD_BAT(0,r3,r4,r5)
++	LOAD_BAT(1,r3,r4,r5)
++	LOAD_BAT(2,r3,r4,r5)
++	LOAD_BAT(3,r3,r4,r5)
++
++	blr
++
++/*
++ * This is where the main kernel code starts.
++ */
++start_here:
++	/* ptr to current */
++	lis	r2,init_task at h
++	ori	r2,r2,init_task at l
++	/* Set up for using our exception vectors */
++	/* ptr to phys current thread */
++	tophys(r4,r2)
++	addi	r4,r4,THREAD	/* init task's THREAD */
++	CLR_TOP32(r4)
++	mtspr	SPRN_SPRG3,r4
++	li	r3,0
++	mtspr	SPRN_SPRG2,r3	/* 0 => not in RTAS */
++
++	/* stack */
++	lis	r1,init_thread_union at ha
++	addi	r1,r1,init_thread_union at l
++	li	r0,0
++	stwu	r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
++/*
++ * Do early platform-specific initialization,
++ * and set up the MMU.
++ */
++	mr	r3,r31
++	mr	r4,r30
++	bl	machine_init
++	bl	MMU_init
++
++#ifdef CONFIG_APUS
++	/* Copy exception code to exception vector base on APUS. */
++	lis	r4,KERNELBASE at h
++#ifdef CONFIG_APUS_FAST_EXCEPT
++	lis	r3,0xfff0		/* Copy to 0xfff00000 */
++#else
++	lis	r3,0			/* Copy to 0x00000000 */
++#endif
++	li	r5,0x4000		/* # bytes of memory to copy */
++	li	r6,0
++	bl	copy_and_flush		/* copy the first 0x4000 bytes */
++#endif  /* CONFIG_APUS */
++
++/*
++ * Go back to running unmapped so we can load up new values
++ * for SDR1 (hash table pointer) and the segment registers
++ * and change to using our exception vectors.
++ */
++	lis	r4,2f at h
++	ori	r4,r4,2f at l
++	tophys(r4,r4)
++	li	r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
++	FIX_SRR1(r3,r5)
++	mtspr	SPRN_SRR0,r4
++	mtspr	SPRN_SRR1,r3
++	SYNC
++	RFI
++/* Load up the kernel context */
++2:	bl	load_up_mmu
++
++#ifdef CONFIG_BDI_SWITCH
++	/* Add helper information for the Abatron bdiGDB debugger.
++	 * We do this here because we know the mmu is disabled, and
++	 * will be enabled for real in just a few instructions.
++	 */
++	lis	r5, abatron_pteptrs at h
++	ori	r5, r5, abatron_pteptrs at l
++	stw	r5, 0xf0(r0)	/* This much match your Abatron config */
++	lis	r6, swapper_pg_dir at h
++	ori	r6, r6, swapper_pg_dir at l
++	tophys(r5, r5)
++	stw	r6, 0(r5)
++#endif /* CONFIG_BDI_SWITCH */
++
++/* Now turn on the MMU for real! */
++	li	r4,MSR_KERNEL
++	FIX_SRR1(r4,r5)
++	lis	r3,start_kernel at h
++	ori	r3,r3,start_kernel at l
++	mtspr	SPRN_SRR0,r3
++	mtspr	SPRN_SRR1,r4
++	SYNC
++	RFI
++
++/*
++ * Set up the segment registers for a new context.
++ */
++_GLOBAL(set_context)
++	mulli	r3,r3,897	/* multiply context by skew factor */
++	rlwinm	r3,r3,4,8,27	/* VSID = (context & 0xfffff) << 4 */
++	addis	r3,r3,0x6000	/* Set Ks, Ku bits */
++	li	r0,NUM_USER_SEGMENTS
++	mtctr	r0
++
++#ifdef CONFIG_BDI_SWITCH
++	/* Context switch the PTE pointer for the Abatron BDI2000.
++	 * The PGDIR is passed as second argument.
++	 */
++	lis	r5, KERNELBASE at h
++	lwz	r5, 0xf0(r5)
++	stw	r4, 0x4(r5)
++#endif
++	li	r4,0
++	isync
++3:
++	mtsrin	r3,r4
++	addi	r3,r3,0x111	/* next VSID */
++	rlwinm	r3,r3,0,8,3	/* clear out any overflow from VSID field */
++	addis	r4,r4,0x1000	/* address of next segment */
++	bdnz	3b
++	sync
++	isync
++	blr
++
++/*
++ * An undocumented "feature" of 604e requires that the v bit
++ * be cleared before changing BAT values.
++ *
++ * Also, newer IBM firmware does not clear bat3 and 4 so
++ * this makes sure it's done.
++ *  -- Cort
++ */
++clear_bats:
++	li	r10,0
++	mfspr	r9,SPRN_PVR
++	rlwinm	r9,r9,16,16,31		/* r9 = 1 for 601, 4 for 604 */
++	cmpwi	r9, 1
++	beq	1f
++
++	mtspr	SPRN_DBAT0U,r10
++	mtspr	SPRN_DBAT0L,r10
++	mtspr	SPRN_DBAT1U,r10
++	mtspr	SPRN_DBAT1L,r10
++	mtspr	SPRN_DBAT2U,r10
++	mtspr	SPRN_DBAT2L,r10
++	mtspr	SPRN_DBAT3U,r10
++	mtspr	SPRN_DBAT3L,r10
++1:
++	mtspr	SPRN_IBAT0U,r10
++	mtspr	SPRN_IBAT0L,r10
++	mtspr	SPRN_IBAT1U,r10
++	mtspr	SPRN_IBAT1L,r10
++	mtspr	SPRN_IBAT2U,r10
++	mtspr	SPRN_IBAT2L,r10
++	mtspr	SPRN_IBAT3U,r10
++	mtspr	SPRN_IBAT3L,r10
++BEGIN_FTR_SECTION
++	/* Here's a tweak: at this point, CPU setup have
++	 * not been called yet, so HIGH_BAT_EN may not be
++	 * set in HID0 for the 745x processors. However, it
++	 * seems that doesn't affect our ability to actually
++	 * write to these SPRs.
++	 */
++	mtspr	SPRN_DBAT4U,r10
++	mtspr	SPRN_DBAT4L,r10
++	mtspr	SPRN_DBAT5U,r10
++	mtspr	SPRN_DBAT5L,r10
++	mtspr	SPRN_DBAT6U,r10
++	mtspr	SPRN_DBAT6L,r10
++	mtspr	SPRN_DBAT7U,r10
++	mtspr	SPRN_DBAT7L,r10
++	mtspr	SPRN_IBAT4U,r10
++	mtspr	SPRN_IBAT4L,r10
++	mtspr	SPRN_IBAT5U,r10
++	mtspr	SPRN_IBAT5L,r10
++	mtspr	SPRN_IBAT6U,r10
++	mtspr	SPRN_IBAT6L,r10
++	mtspr	SPRN_IBAT7U,r10
++	mtspr	SPRN_IBAT7L,r10
++END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
++	blr
++
++flush_tlbs:
++	lis	r10, 0x40
++1:	addic.	r10, r10, -0x1000
++	tlbie	r10
++	blt	1b
++	sync
++	blr
++
++mmu_off:
++ 	addi	r4, r3, __after_mmu_off - _start
++	mfmsr	r3
++	andi.	r0,r3,MSR_DR|MSR_IR		/* MMU enabled? */
++	beqlr
++	andc	r3,r3,r0
++	mtspr	SPRN_SRR0,r4
++	mtspr	SPRN_SRR1,r3
++	sync
++	RFI
++
++/*
++ * Use the first pair of BAT registers to map the 1st 16MB
++ * of RAM to KERNELBASE.  From this point on we can't safely
++ * call OF any more.
++ */
++initial_bats:
++	lis	r11,KERNELBASE at h
++	mfspr	r9,SPRN_PVR
++	rlwinm	r9,r9,16,16,31		/* r9 = 1 for 601, 4 for 604 */
++	cmpwi	0,r9,1
++	bne	4f
++	ori	r11,r11,4		/* set up BAT registers for 601 */
++	li	r8,0x7f			/* valid, block length = 8MB */
++	oris	r9,r11,0x800000 at h	/* set up BAT reg for 2nd 8M */
++	oris	r10,r8,0x800000 at h	/* set up BAT reg for 2nd 8M */
++	mtspr	SPRN_IBAT0U,r11		/* N.B. 601 has valid bit in */
++	mtspr	SPRN_IBAT0L,r8		/* lower BAT register */
++	mtspr	SPRN_IBAT1U,r9
++	mtspr	SPRN_IBAT1L,r10
++	isync
++	blr
++
++4:	tophys(r8,r11)
++#ifdef CONFIG_SMP
++	ori	r8,r8,0x12		/* R/W access, M=1 */
++#else
++	ori	r8,r8,2			/* R/W access */
++#endif /* CONFIG_SMP */
++#ifdef CONFIG_APUS
++	ori	r11,r11,BL_8M<<2|0x2	/* set up 8MB BAT registers for 604 */
++#else
++	ori	r11,r11,BL_256M<<2|0x2	/* set up BAT registers for 604 */
++#endif /* CONFIG_APUS */
++
++	mtspr	SPRN_DBAT0L,r8		/* N.B. 6xx (not 601) have valid */
++	mtspr	SPRN_DBAT0U,r11		/* bit in upper BAT register */
++	mtspr	SPRN_IBAT0L,r8
++	mtspr	SPRN_IBAT0U,r11
++	isync
++	blr
++
++
++#ifdef CONFIG_8260
++/* Jump into the system reset for the rom.
++ * We first disable the MMU, and then jump to the ROM reset address.
++ *
++ * r3 is the board info structure, r4 is the location for starting.
++ * I use this for building a small kernel that can load other kernels,
++ * rather than trying to write or rely on a rom monitor that can tftp load.
++ */
++       .globl  m8260_gorom
++m8260_gorom:
++	mfmsr	r0
++	rlwinm	r0,r0,0,17,15	/* clear MSR_EE in r0 */
++	sync
++	mtmsr	r0
++	sync
++	mfspr	r11, SPRN_HID0
++	lis	r10, 0
++	ori	r10,r10,HID0_ICE|HID0_DCE
++	andc	r11, r11, r10
++	mtspr	SPRN_HID0, r11
++	isync
++	li	r5, MSR_ME|MSR_RI
++	lis	r6,2f at h
++	addis	r6,r6,-KERNELBASE at h
++	ori	r6,r6,2f at l
++	mtspr	SPRN_SRR0,r6
++	mtspr	SPRN_SRR1,r5
++	isync
++	sync
++	rfi
++2:
++	mtlr	r4
++	blr
++#endif
++
++
++/*
++ * We put a few things here that have to be page-aligned.
++ * This stuff goes at the beginning of the data segment,
++ * which is page-aligned.
++ */
++	.data
++	.globl	sdata
++sdata:
++	.globl	empty_zero_page
++empty_zero_page:
++	.space	4096
++
++	.globl	swapper_pg_dir
++swapper_pg_dir:
++	.space	4096
++
++/*
++ * This space gets a copy of optional info passed to us by the bootstrap
++ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
++ */
++	.globl	cmd_line
++cmd_line:
++	.space	512
++
++	.globl intercept_table
++intercept_table:
++	.long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700
++	.long i0x800, 0, 0, 0, 0, i0xd00, 0, 0
++	.long 0, 0, 0, i0x1300, 0, 0, 0, 0
++	.long 0, 0, 0, 0, 0, 0, 0, 0
++	.long 0, 0, 0, 0, 0, 0, 0, 0
++	.long 0, 0, 0, 0, 0, 0, 0, 0
++
++/* Room for two PTE pointers, usually the kernel and current user pointers
++ * to their respective root page table.
++ */
++abatron_pteptrs:
++	.space	8
+diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/head_44x.S
+@@ -0,0 +1,782 @@
++/*
++ * arch/ppc/kernel/head_44x.S
++ *
++ * Kernel execution entry point code.
++ *
++ *    Copyright (c) 1995-1996 Gary Thomas <gdt at linuxppc.org>
++ *      Initial PowerPC version.
++ *    Copyright (c) 1996 Cort Dougan <cort at cs.nmt.edu>
++ *      Rewritten for PReP
++ *    Copyright (c) 1996 Paul Mackerras <paulus at cs.anu.edu.au>
++ *      Low-level exception handers, MMU support, and rewrite.
++ *    Copyright (c) 1997 Dan Malek <dmalek at jlc.net>
++ *      PowerPC 8xx modifications.
++ *    Copyright (c) 1998-1999 TiVo, Inc.
++ *      PowerPC 403GCX modifications.
++ *    Copyright (c) 1999 Grant Erickson <grant at lcse.umn.edu>
++ *      PowerPC 403GCX/405GP modifications.
++ *    Copyright 2000 MontaVista Software Inc.
++ *	PPC405 modifications
++ *      PowerPC 403GCX/405GP modifications.
++ * 	Author: MontaVista Software, Inc.
++ *         	frank_rowand at mvista.com or source at mvista.com
++ * 	   	debbie_chu at mvista.com
++ *    Copyright 2002-2005 MontaVista Software, Inc.
++ *      PowerPC 44x support, Matt Porter <mporter at 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/config.h>
++#include <asm/processor.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/pgtable.h>
++#include <asm/ibm4xx.h>
++#include <asm/ibm44x.h>
++#include <asm/cputable.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++#include "head_booke.h"
++
++
++/* As with the other PowerPC ports, it is expected that when code
++ * execution begins here, the following registers contain valid, yet
++ * optional, information:
++ *
++ *   r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
++ *   r4 - Starting address of the init RAM disk
++ *   r5 - Ending address of the init RAM disk
++ *   r6 - Start of kernel command line string (e.g. "mem=128")
++ *   r7 - End of kernel command line string
++ *
++ */
++	.text
++_GLOBAL(_stext)
++_GLOBAL(_start)
++	/*
++	 * Reserve a word at a fixed location to store the address
++	 * of abatron_pteptrs
++	 */
++	nop
++/*
++ * Save parameters we are passed
++ */
++	mr	r31,r3
++	mr	r30,r4
++	mr	r29,r5
++	mr	r28,r6
++	mr	r27,r7
++	li	r24,0		/* CPU number */
++
++/*
++ * Set up the initial MMU state
++ *
++ * We are still executing code at the virtual address
++ * mappings set by the firmware for the base of RAM.
++ *
++ * We first invalidate all TLB entries but the one
++ * we are running from.  We then load the KERNELBASE
++ * mappings so we can begin to use kernel addresses
++ * natively and so the interrupt vector locations are
++ * permanently pinned (necessary since Book E
++ * implementations always have translation enabled).
++ *
++ * TODO: Use the known TLB entry we are running from to
++ *	 determine which physical region we are located
++ *	 in.  This can be used to determine where in RAM
++ *	 (on a shared CPU system) or PCI memory space
++ *	 (on a DRAMless system) we are located.
++ *       For now, we assume a perfect world which means
++ *	 we are located at the base of DRAM (physical 0).
++ */
++
++/*
++ * Search TLB for entry that we are currently using.
++ * Invalidate all entries but the one we are using.
++ */
++	/* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
++	mfspr	r3,SPRN_PID			/* Get PID */
++	mfmsr	r4				/* Get MSR */
++	andi.	r4,r4,MSR_IS at l			/* TS=1? */
++	beq	wmmucr				/* If not, leave STS=0 */
++	oris	r3,r3,PPC44x_MMUCR_STS at h	/* Set STS=1 */
++wmmucr:	mtspr	SPRN_MMUCR,r3			/* Put MMUCR */
++	sync
++
++	bl	invstr				/* Find our address */
++invstr:	mflr	r5				/* Make it accessible */
++	tlbsx	r23,0,r5			/* Find entry we are in */
++	li	r4,0				/* Start at TLB entry 0 */
++	li	r3,0				/* Set PAGEID inval value */
++1:	cmpw	r23,r4				/* Is this our entry? */
++	beq	skpinv				/* If so, skip the inval */
++	tlbwe	r3,r4,PPC44x_TLB_PAGEID		/* If not, inval the entry */
++skpinv:	addi	r4,r4,1				/* Increment */
++	cmpwi	r4,64				/* Are we done? */
++	bne	1b				/* If not, repeat */
++	isync					/* If so, context change */
++
++/*
++ * Configure and load pinned entry into TLB slot 63.
++ */
++
++	lis	r3,KERNELBASE at h		/* Load the kernel virtual address */
++	ori	r3,r3,KERNELBASE at l
++
++	/* Kernel is at the base of RAM */
++	li r4, 0			/* Load the kernel physical address */
++
++	/* Load the kernel PID = 0 */
++	li	r0,0
++	mtspr	SPRN_PID,r0
++	sync
++
++	/* Initialize MMUCR */
++	li	r5,0
++	mtspr	SPRN_MMUCR,r5
++	sync
++
++ 	/* pageid fields */
++	clrrwi	r3,r3,10		/* Mask off the effective page number */
++	ori	r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
++
++	/* xlat fields */
++	clrrwi	r4,r4,10		/* Mask off the real page number */
++					/* ERPN is 0 for first 4GB page */
++
++	/* attrib fields */
++	/* Added guarded bit to protect against speculative loads/stores */
++	li	r5,0
++	ori	r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
++
++        li      r0,63                    /* TLB slot 63 */
++
++	tlbwe	r3,r0,PPC44x_TLB_PAGEID	/* Load the pageid fields */
++	tlbwe	r4,r0,PPC44x_TLB_XLAT	/* Load the translation fields */
++	tlbwe	r5,r0,PPC44x_TLB_ATTRIB	/* Load the attrib/access fields */
++
++	/* Force context change */
++	mfmsr	r0
++	mtspr	SPRN_SRR1, r0
++	lis	r0,3f at h
++	ori	r0,r0,3f at l
++	mtspr	SPRN_SRR0,r0
++	sync
++	rfi
++
++	/* If necessary, invalidate original entry we used */
++3:	cmpwi	r23,63
++	beq	4f
++	li	r6,0
++	tlbwe   r6,r23,PPC44x_TLB_PAGEID
++	isync
++
++4:
++#ifdef CONFIG_SERIAL_TEXT_DEBUG
++	/*
++	 * Add temporary UART mapping for early debug.
++	 * We can map UART registers wherever we want as long as they don't
++	 * interfere with other system mappings (e.g. with pinned entries).
++	 * For an example of how we handle this - see ocotea.h.       --ebs
++	 */
++ 	/* pageid fields */
++	lis	r3,UART0_IO_BASE at h
++	ori	r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K
++
++	/* xlat fields */
++	lis	r4,UART0_PHYS_IO_BASE at h		/* RPN depends on SoC */
++#ifndef CONFIG_440EP
++	ori	r4,r4,0x0001		/* ERPN is 1 for second 4GB page */
++#endif
++
++	/* attrib fields */
++	li	r5,0
++	ori	r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
++
++        li      r0,0                    /* TLB slot 0 */
++
++	tlbwe	r3,r0,PPC44x_TLB_PAGEID	/* Load the pageid fields */
++	tlbwe	r4,r0,PPC44x_TLB_XLAT	/* Load the translation fields */
++	tlbwe	r5,r0,PPC44x_TLB_ATTRIB	/* Load the attrib/access fields */
++
++	/* Force context change */
++	isync
++#endif /* CONFIG_SERIAL_TEXT_DEBUG */
++
++	/* Establish the interrupt vector offsets */
++	SET_IVOR(0,  CriticalInput);
++	SET_IVOR(1,  MachineCheck);
++	SET_IVOR(2,  DataStorage);
++	SET_IVOR(3,  InstructionStorage);
++	SET_IVOR(4,  ExternalInput);
++	SET_IVOR(5,  Alignment);
++	SET_IVOR(6,  Program);
++	SET_IVOR(7,  FloatingPointUnavailable);
++	SET_IVOR(8,  SystemCall);
++	SET_IVOR(9,  AuxillaryProcessorUnavailable);
++	SET_IVOR(10, Decrementer);
++	SET_IVOR(11, FixedIntervalTimer);
++	SET_IVOR(12, WatchdogTimer);
++	SET_IVOR(13, DataTLBError);
++	SET_IVOR(14, InstructionTLBError);
++	SET_IVOR(15, Debug);
++
++	/* Establish the interrupt vector base */
++	lis	r4,interrupt_base at h	/* IVPR only uses the high 16-bits */
++	mtspr	SPRN_IVPR,r4
++
++#ifdef CONFIG_440EP
++	/* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */
++	mfspr	r2,SPRN_CCR0
++	lis	r3,0xffef
++	ori	r3,r3,0xffff
++	and	r2,r2,r3
++	mtspr	SPRN_CCR0,r2
++	isync
++#endif
++
++	/*
++	 * This is where the main kernel code starts.
++	 */
++
++	/* ptr to current */
++	lis	r2,init_task at h
++	ori	r2,r2,init_task at l
++
++	/* ptr to current thread */
++	addi	r4,r2,THREAD	/* init task's THREAD */
++	mtspr	SPRN_SPRG3,r4
++
++	/* stack */
++	lis	r1,init_thread_union at h
++	ori	r1,r1,init_thread_union at l
++	li	r0,0
++	stwu	r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
++
++	bl	early_init
++
++/*
++ * Decide what sort of machine this is and initialize the MMU.
++ */
++	mr	r3,r31
++	mr	r4,r30
++	mr	r5,r29
++	mr	r6,r28
++	mr	r7,r27
++	bl	machine_init
++	bl	MMU_init
++
++	/* Setup PTE pointers for the Abatron bdiGDB */
++	lis	r6, swapper_pg_dir at h
++	ori	r6, r6, swapper_pg_dir at l
++	lis	r5, abatron_pteptrs at h
++	ori	r5, r5, abatron_pteptrs at l
++	lis	r4, KERNELBASE at h
++	ori	r4, r4, KERNELBASE at l
++	stw	r5, 0(r4)	/* Save abatron_pteptrs at a fixed location */
++	stw	r6, 0(r5)
++
++	/* Let's move on */
++	lis	r4,start_kernel at h
++	ori	r4,r4,start_kernel at l
++	lis	r3,MSR_KERNEL at h
++	ori	r3,r3,MSR_KERNEL at l
++	mtspr	SPRN_SRR0,r4
++	mtspr	SPRN_SRR1,r3
++	rfi			/* change context and jump to start_kernel */
++
++/*
++ * Interrupt vector entry code
++ *
++ * The Book E MMUs are always on so we don't need to handle
++ * interrupts in real mode as with previous PPC processors. In
++ * this case we handle interrupts in the kernel virtual address
++ * space.
++ *
++ * Interrupt vectors are dynamically placed relative to the
++ * interrupt prefix as determined by the address of interrupt_base.
++ * The interrupt vectors offsets are programmed using the labels
++ * for each interrupt vector entry.
++ *
++ * Interrupt vectors must be aligned on a 16 byte boundary.
++ * We align on a 32 byte cache line boundary for good measure.
++ */
++
++interrupt_base:
++	/* Critical Input Interrupt */
++	CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
++
++	/* Machine Check Interrupt */
++#ifdef CONFIG_440A
++	MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
++#else
++	CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
++#endif
++
++	/* Data Storage Interrupt */
++	START_EXCEPTION(DataStorage)
++	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
++	mtspr	SPRN_SPRG1, r11
++	mtspr	SPRN_SPRG4W, r12
++	mtspr	SPRN_SPRG5W, r13
++	mfcr	r11
++	mtspr	SPRN_SPRG7W, r11
++
++	/*
++	 * Check if it was a store fault, if not then bail
++	 * because a user tried to access a kernel or
++	 * read-protected page.  Otherwise, get the
++	 * offending address and handle it.
++	 */
++	mfspr	r10, SPRN_ESR
++	andis.	r10, r10, ESR_ST at h
++	beq	2f
++
++	mfspr	r10, SPRN_DEAR		/* Get faulting address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	lis	r11, TASK_SIZE at h
++	cmplw	r10, r11
++	blt+	3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++
++	mfspr   r12,SPRN_MMUCR
++	rlwinm	r12,r12,0,0,23		/* Clear TID */
++
++	b	4f
++
++	/* Get the PGD for the current thread */
++3:
++	mfspr	r11,SPRN_SPRG3
++	lwz	r11,PGDIR(r11)
++
++	/* Load PID into MMUCR TID */
++	mfspr	r12,SPRN_MMUCR		/* Get MMUCR */
++	mfspr   r13,SPRN_PID		/* Get PID */
++	rlwimi	r12,r13,0,24,31		/* Set TID */
++
++4:
++	mtspr   SPRN_MMUCR,r12
++
++	rlwinm  r12, r10, 13, 19, 29    /* Compute pgdir/pmd offset */
++	lwzx    r11, r12, r11           /* Get pgd/pmd entry */
++	rlwinm. r12, r11, 0, 0, 20      /* Extract pt base address */
++	beq     2f                      /* Bail if no table */
++
++	rlwimi  r12, r10, 23, 20, 28    /* Compute pte address */
++	lwz     r11, 4(r12)             /* Get pte entry */
++
++	andi.	r13, r11, _PAGE_RW	/* Is it writeable? */
++	beq	2f			/* Bail if not */
++
++	/* Update 'changed'.
++	*/
++	ori	r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
++	stw	r11, 4(r12)		/* Update Linux page table */
++
++	li	r13, PPC44x_TLB_SR at l	/* Set SR */
++	rlwimi	r13, r11, 29, 29, 29	/* SX = _PAGE_HWEXEC */
++	rlwimi	r13, r11, 0, 30, 30	/* SW = _PAGE_RW */
++	rlwimi	r13, r11, 29, 28, 28	/* UR = _PAGE_USER */
++	rlwimi	r12, r11, 31, 26, 26	/* (_PAGE_USER>>1)->r12 */
++	rlwimi	r12, r11, 29, 30, 30	/* (_PAGE_USER>>3)->r12 */
++	and	r12, r12, r11		/* HWEXEC/RW & USER */
++	rlwimi	r13, r12, 0, 26, 26	/* UX = HWEXEC & USER */
++	rlwimi	r13, r12, 3, 27, 27	/* UW = RW & USER */
++
++	rlwimi	r11,r13,0,26,31		/* Insert static perms */
++
++	rlwinm	r11,r11,0,20,15		/* Clear U0-U3 */
++
++	/* find the TLB index that caused the fault.  It has to be here. */
++	tlbsx	r10, 0, r10
++
++	tlbwe	r11, r10, PPC44x_TLB_ATTRIB	/* Write ATTRIB */
++
++	/* Done...restore registers and get out of here.
++	*/
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	rfi			/* Force context change */
++
++2:
++	/*
++	 * The bailout.  Restore registers to pre-exception conditions
++	 * and call the heavyweights to help us out.
++	 */
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	b	data_access
++
++	/* Instruction Storage Interrupt */
++	INSTRUCTION_STORAGE_EXCEPTION
++
++	/* External Input Interrupt */
++	EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
++
++	/* Alignment Interrupt */
++	ALIGNMENT_EXCEPTION
++
++	/* Program Interrupt */
++	PROGRAM_EXCEPTION
++
++	/* Floating Point Unavailable Interrupt */
++#ifdef CONFIG_PPC_FPU
++	FP_UNAVAILABLE_EXCEPTION
++#else
++	EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
++#endif
++
++	/* System Call Interrupt */
++	START_EXCEPTION(SystemCall)
++	NORMAL_EXCEPTION_PROLOG
++	EXC_XFER_EE_LITE(0x0c00, DoSyscall)
++
++	/* Auxillary Processor Unavailable Interrupt */
++	EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
++
++	/* Decrementer Interrupt */
++	DECREMENTER_EXCEPTION
++
++	/* Fixed Internal Timer Interrupt */
++	/* TODO: Add FIT support */
++	EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
++
++	/* Watchdog Timer Interrupt */
++	/* TODO: Add watchdog support */
++#ifdef CONFIG_BOOKE_WDT
++	CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException)
++#else
++	CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception)
++#endif
++
++	/* Data TLB Error Interrupt */
++	START_EXCEPTION(DataTLBError)
++	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
++	mtspr	SPRN_SPRG1, r11
++	mtspr	SPRN_SPRG4W, r12
++	mtspr	SPRN_SPRG5W, r13
++	mfcr	r11
++	mtspr	SPRN_SPRG7W, r11
++	mfspr	r10, SPRN_DEAR		/* Get faulting address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	lis	r11, TASK_SIZE at h
++	cmplw	r10, r11
++	blt+	3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++
++	mfspr	r12,SPRN_MMUCR
++	rlwinm	r12,r12,0,0,23		/* Clear TID */
++
++	b	4f
++
++	/* Get the PGD for the current thread */
++3:
++	mfspr	r11,SPRN_SPRG3
++	lwz	r11,PGDIR(r11)
++
++	/* Load PID into MMUCR TID */
++	mfspr	r12,SPRN_MMUCR
++	mfspr   r13,SPRN_PID		/* Get PID */
++	rlwimi	r12,r13,0,24,31		/* Set TID */
++
++4:
++	mtspr	SPRN_MMUCR,r12
++
++	rlwinm 	r12, r10, 13, 19, 29	/* Compute pgdir/pmd offset */
++	lwzx	r11, r12, r11		/* Get pgd/pmd entry */
++	rlwinm.	r12, r11, 0, 0, 20	/* Extract pt base address */
++	beq	2f			/* Bail if no table */
++
++	rlwimi	r12, r10, 23, 20, 28	/* Compute pte address */
++	lwz	r11, 4(r12)		/* Get pte entry */
++	andi.	r13, r11, _PAGE_PRESENT	/* Is the page present? */
++	beq	2f			/* Bail if not present */
++
++	ori	r11, r11, _PAGE_ACCESSED
++	stw	r11, 4(r12)
++
++	 /* Jump to common tlb load */
++	b	finish_tlb_load
++
++2:
++	/* The bailout.  Restore registers to pre-exception conditions
++	 * and call the heavyweights to help us out.
++	 */
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	b	data_access
++
++	/* Instruction TLB Error Interrupt */
++	/*
++	 * Nearly the same as above, except we get our
++	 * information from different registers and bailout
++	 * to a different point.
++	 */
++	START_EXCEPTION(InstructionTLBError)
++	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
++	mtspr	SPRN_SPRG1, r11
++	mtspr	SPRN_SPRG4W, r12
++	mtspr	SPRN_SPRG5W, r13
++	mfcr	r11
++	mtspr	SPRN_SPRG7W, r11
++	mfspr	r10, SPRN_SRR0		/* Get faulting address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	lis	r11, TASK_SIZE at h
++	cmplw	r10, r11
++	blt+	3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++
++	mfspr	r12,SPRN_MMUCR
++	rlwinm	r12,r12,0,0,23		/* Clear TID */
++
++	b	4f
++
++	/* Get the PGD for the current thread */
++3:
++	mfspr	r11,SPRN_SPRG3
++	lwz	r11,PGDIR(r11)
++
++	/* Load PID into MMUCR TID */
++	mfspr	r12,SPRN_MMUCR
++	mfspr   r13,SPRN_PID		/* Get PID */
++	rlwimi	r12,r13,0,24,31		/* Set TID */
++
++4:
++	mtspr	SPRN_MMUCR,r12
++
++	rlwinm	r12, r10, 13, 19, 29	/* Compute pgdir/pmd offset */
++	lwzx	r11, r12, r11		/* Get pgd/pmd entry */
++	rlwinm.	r12, r11, 0, 0, 20	/* Extract pt base address */
++	beq	2f			/* Bail if no table */
++
++	rlwimi	r12, r10, 23, 20, 28	/* Compute pte address */
++	lwz	r11, 4(r12)		/* Get pte entry */
++	andi.	r13, r11, _PAGE_PRESENT	/* Is the page present? */
++	beq	2f			/* Bail if not present */
++
++	ori	r11, r11, _PAGE_ACCESSED
++	stw	r11, 4(r12)
++
++	/* Jump to common TLB load point */
++	b	finish_tlb_load
++
++2:
++	/* The bailout.  Restore registers to pre-exception conditions
++	 * and call the heavyweights to help us out.
++	 */
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	b	InstructionStorage
++
++	/* Debug Interrupt */
++	DEBUG_EXCEPTION
++
++/*
++ * Local functions
++ */
++	/*
++	 * Data TLB exceptions will bail out to this point
++	 * if they can't resolve the lightweight TLB fault.
++	 */
++data_access:
++	NORMAL_EXCEPTION_PROLOG
++	mfspr	r5,SPRN_ESR		/* Grab the ESR, save it, pass arg3 */
++	stw	r5,_ESR(r11)
++	mfspr	r4,SPRN_DEAR		/* Grab the DEAR, save it, pass arg2 */
++	EXC_XFER_EE_LITE(0x0300, handle_page_fault)
++
++/*
++
++ * Both the instruction and data TLB miss get to this
++ * point to load the TLB.
++ * 	r10 - EA of fault
++ * 	r11 - available to use
++ *	r12 - Pointer to the 64-bit PTE
++ *	r13 - available to use
++ *	MMUCR - loaded with proper value when we get here
++ *	Upon exit, we reload everything and RFI.
++ */
++finish_tlb_load:
++	/*
++	 * We set execute, because we don't have the granularity to
++	 * properly set this at the page level (Linux problem).
++	 * If shared is set, we cause a zero PID->TID load.
++	 * Many of these bits are software only.  Bits we don't set
++	 * here we (properly should) assume have the appropriate value.
++	 */
++
++	/* Load the next available TLB index */
++	lis	r13, tlb_44x_index at ha
++	lwz	r13, tlb_44x_index at l(r13)
++	/* Load the TLB high watermark */
++	lis	r11, tlb_44x_hwater at ha
++	lwz	r11, tlb_44x_hwater at l(r11)
++
++	/* Increment, rollover, and store TLB index */
++	addi	r13, r13, 1
++	cmpw	0, r13, r11			/* reserve entries */
++	ble	7f
++	li	r13, 0
++7:
++	/* Store the next available TLB index */
++	lis	r11, tlb_44x_index at ha
++	stw	r13, tlb_44x_index at l(r11)
++
++	lwz	r11, 0(r12)			/* Get MS word of PTE */
++	lwz	r12, 4(r12)			/* Get LS word of PTE */
++	rlwimi	r11, r12, 0, 0 , 19		/* Insert RPN */
++	tlbwe	r11, r13, PPC44x_TLB_XLAT	/* Write XLAT */
++
++	/*
++	 * Create PAGEID. This is the faulting address,
++	 * page size, and valid flag.
++	 */
++	li	r11, PPC44x_TLB_VALID | PPC44x_TLB_4K
++	rlwimi	r10, r11, 0, 20, 31		/* Insert valid and page size */
++	tlbwe	r10, r13, PPC44x_TLB_PAGEID	/* Write PAGEID */
++
++	li	r10, PPC44x_TLB_SR at l		/* Set SR */
++	rlwimi	r10, r12, 0, 30, 30		/* Set SW = _PAGE_RW */
++	rlwimi	r10, r12, 29, 29, 29		/* SX = _PAGE_HWEXEC */
++	rlwimi	r10, r12, 29, 28, 28		/* UR = _PAGE_USER */
++	rlwimi	r11, r12, 31, 26, 26		/* (_PAGE_USER>>1)->r12 */
++	and	r11, r12, r11			/* HWEXEC & USER */
++	rlwimi	r10, r11, 0, 26, 26		/* UX = HWEXEC & USER */
++
++	rlwimi	r12, r10, 0, 26, 31		/* Insert static perms */
++	rlwinm	r12, r12, 0, 20, 15		/* Clear U0-U3 */
++	tlbwe	r12, r13, PPC44x_TLB_ATTRIB	/* Write ATTRIB */
++
++	/* Done...restore registers and get out of here.
++	*/
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	rfi					/* Force context change */
++
++/*
++ * Global functions
++ */
++
++/*
++ * extern void giveup_altivec(struct task_struct *prev)
++ *
++ * The 44x core does not have an AltiVec unit.
++ */
++_GLOBAL(giveup_altivec)
++	blr
++
++/*
++ * extern void giveup_fpu(struct task_struct *prev)
++ *
++ * The 44x core does not have an FPU.
++ */
++#ifndef CONFIG_PPC_FPU
++_GLOBAL(giveup_fpu)
++	blr
++#endif
++
++/*
++ * extern void abort(void)
++ *
++ * At present, this routine just applies a system reset.
++ */
++_GLOBAL(abort)
++        mfspr   r13,SPRN_DBCR0
++        oris    r13,r13,DBCR0_RST_SYSTEM at h
++        mtspr   SPRN_DBCR0,r13
++
++_GLOBAL(set_context)
++
++#ifdef CONFIG_BDI_SWITCH
++	/* Context switch the PTE pointer for the Abatron BDI2000.
++	 * The PGDIR is the second parameter.
++	 */
++	lis	r5, abatron_pteptrs at h
++	ori	r5, r5, abatron_pteptrs at l
++	stw	r4, 0x4(r5)
++#endif
++	mtspr	SPRN_PID,r3
++	isync			/* Force context change */
++	blr
++
++/*
++ * We put a few things here that have to be page-aligned. This stuff
++ * goes at the beginning of the data segment, which is page-aligned.
++ */
++	.data
++	.align	12
++	.globl	sdata
++sdata:
++	.globl	empty_zero_page
++empty_zero_page:
++	.space	4096
++
++/*
++ * To support >32-bit physical addresses, we use an 8KB pgdir.
++ */
++	.globl	swapper_pg_dir
++swapper_pg_dir:
++	.space	8192
++
++/* Reserved 4k for the critical exception stack & 4k for the machine
++ * check stack per CPU for kernel mode exceptions */
++	.section .bss
++        .align 12
++exception_stack_bottom:
++	.space	BOOKE_EXCEPTION_STACK_SIZE
++	.globl	exception_stack_top
++exception_stack_top:
++
++/*
++ * This space gets a copy of optional info passed to us by the bootstrap
++ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
++ */
++	.globl	cmd_line
++cmd_line:
++	.space	512
++
++/*
++ * Room for two PTE pointers, usually the kernel and current user pointers
++ * to their respective root page table.
++ */
++abatron_pteptrs:
++	.space	8
+diff --git a/arch/powerpc/kernel/head_4xx.S b/arch/powerpc/kernel/head_4xx.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/head_4xx.S
+@@ -0,0 +1,1022 @@
++/*
++ *    Copyright (c) 1995-1996 Gary Thomas <gdt at linuxppc.org>
++ *      Initial PowerPC version.
++ *    Copyright (c) 1996 Cort Dougan <cort at cs.nmt.edu>
++ *      Rewritten for PReP
++ *    Copyright (c) 1996 Paul Mackerras <paulus at cs.anu.edu.au>
++ *      Low-level exception handers, MMU support, and rewrite.
++ *    Copyright (c) 1997 Dan Malek <dmalek at jlc.net>
++ *      PowerPC 8xx modifications.
++ *    Copyright (c) 1998-1999 TiVo, Inc.
++ *      PowerPC 403GCX modifications.
++ *    Copyright (c) 1999 Grant Erickson <grant at lcse.umn.edu>
++ *      PowerPC 403GCX/405GP modifications.
++ *    Copyright 2000 MontaVista Software Inc.
++ *	PPC405 modifications
++ *      PowerPC 403GCX/405GP modifications.
++ * 	Author: MontaVista Software, Inc.
++ *         	frank_rowand at mvista.com or source at mvista.com
++ * 	   	debbie_chu at mvista.com
++ *
++ *
++ *    Module name: head_4xx.S
++ *
++ *    Description:
++ *      Kernel execution entry point code.
++ *
++ *    This program is free software; you can redistribute it and/or
++ *    modify it under the terms of the 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 <asm/processor.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/pgtable.h>
++#include <asm/ibm4xx.h>
++#include <asm/cputable.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++
++/* As with the other PowerPC ports, it is expected that when code
++ * execution begins here, the following registers contain valid, yet
++ * optional, information:
++ *
++ *   r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
++ *   r4 - Starting address of the init RAM disk
++ *   r5 - Ending address of the init RAM disk
++ *   r6 - Start of kernel command line string (e.g. "mem=96m")
++ *   r7 - End of kernel command line string
++ *
++ * This is all going to change RSN when we add bi_recs.......  -- Dan
++ */
++	.text
++_GLOBAL(_stext)
++_GLOBAL(_start)
++
++	/* Save parameters we are passed.
++	*/
++	mr	r31,r3
++	mr	r30,r4
++	mr	r29,r5
++	mr	r28,r6
++	mr	r27,r7
++
++	/* We have to turn on the MMU right away so we get cache modes
++	 * set correctly.
++	 */
++	bl	initial_mmu
++
++/* We now have the lower 16 Meg mapped into TLB entries, and the caches
++ * ready to work.
++ */
++turn_on_mmu:
++	lis	r0,MSR_KERNEL at h
++	ori	r0,r0,MSR_KERNEL at l
++	mtspr	SPRN_SRR1,r0
++	lis	r0,start_here at h
++	ori	r0,r0,start_here at l
++	mtspr	SPRN_SRR0,r0
++	SYNC
++	rfi				/* enables MMU */
++	b	.			/* prevent prefetch past rfi */
++
++/*
++ * This area is used for temporarily saving registers during the
++ * critical exception prolog.
++ */
++	. = 0xc0
++crit_save:
++_GLOBAL(crit_r10)
++	.space	4
++_GLOBAL(crit_r11)
++	.space	4
++
++/*
++ * Exception vector entry code. This code runs with address translation
++ * turned off (i.e. using physical addresses). We assume SPRG3 has the
++ * physical address of the current task thread_struct.
++ * Note that we have to have decremented r1 before we write to any fields
++ * of the exception frame, since a critical interrupt could occur at any
++ * time, and it will write to the area immediately below the current r1.
++ */
++#define NORMAL_EXCEPTION_PROLOG						     \
++	mtspr	SPRN_SPRG0,r10;		/* save two registers to work with */\
++	mtspr	SPRN_SPRG1,r11;						     \
++	mtspr	SPRN_SPRG2,r1;						     \
++	mfcr	r10;			/* save CR in r10 for now	   */\
++	mfspr	r11,SPRN_SRR1;		/* check whether user or kernel    */\
++	andi.	r11,r11,MSR_PR;						     \
++	beq	1f;							     \
++	mfspr	r1,SPRN_SPRG3;		/* if from user, start at top of   */\
++	lwz	r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack   */\
++	addi	r1,r1,THREAD_SIZE;					     \
++1:	subi	r1,r1,INT_FRAME_SIZE;	/* Allocate an exception frame     */\
++	tophys(r11,r1);							     \
++	stw	r10,_CCR(r11);          /* save various registers	   */\
++	stw	r12,GPR12(r11);						     \
++	stw	r9,GPR9(r11);						     \
++	mfspr	r10,SPRN_SPRG0;						     \
++	stw	r10,GPR10(r11);						     \
++	mfspr	r12,SPRN_SPRG1;						     \
++	stw	r12,GPR11(r11);						     \
++	mflr	r10;							     \
++	stw	r10,_LINK(r11);						     \
++	mfspr	r10,SPRN_SPRG2;						     \
++	mfspr	r12,SPRN_SRR0;						     \
++	stw	r10,GPR1(r11);						     \
++	mfspr	r9,SPRN_SRR1;						     \
++	stw	r10,0(r11);						     \
++	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
++	stw	r0,GPR0(r11);						     \
++	SAVE_4GPRS(3, r11);						     \
++	SAVE_2GPRS(7, r11)
++
++/*
++ * Exception prolog for critical exceptions.  This is a little different
++ * from the normal exception prolog above since a critical exception
++ * can potentially occur at any point during normal exception processing.
++ * Thus we cannot use the same SPRG registers as the normal prolog above.
++ * Instead we use a couple of words of memory at low physical addresses.
++ * This is OK since we don't support SMP on these processors.
++ */
++#define CRITICAL_EXCEPTION_PROLOG					     \
++	stw	r10,crit_r10 at l(0);	/* save two registers to work with */\
++	stw	r11,crit_r11 at l(0);					     \
++	mfcr	r10;			/* save CR in r10 for now	   */\
++	mfspr	r11,SPRN_SRR3;		/* check whether user or kernel    */\
++	andi.	r11,r11,MSR_PR;						     \
++	lis	r11,critical_stack_top at h;				     \
++	ori	r11,r11,critical_stack_top at l;				     \
++	beq	1f;							     \
++	/* COMING FROM USER MODE */					     \
++	mfspr	r11,SPRN_SPRG3;		/* if from user, start at top of   */\
++	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
++	addi	r11,r11,THREAD_SIZE;					     \
++1:	subi	r11,r11,INT_FRAME_SIZE;	/* Allocate an exception frame     */\
++	tophys(r11,r11);						     \
++	stw	r10,_CCR(r11);          /* save various registers	   */\
++	stw	r12,GPR12(r11);						     \
++	stw	r9,GPR9(r11);						     \
++	mflr	r10;							     \
++	stw	r10,_LINK(r11);						     \
++	mfspr	r12,SPRN_DEAR;		/* save DEAR and ESR in the frame  */\
++	stw	r12,_DEAR(r11);		/* since they may have had stuff   */\
++	mfspr	r9,SPRN_ESR;		/* in them at the point where the  */\
++	stw	r9,_ESR(r11);		/* exception was taken		   */\
++	mfspr	r12,SPRN_SRR2;						     \
++	stw	r1,GPR1(r11);						     \
++	mfspr	r9,SPRN_SRR3;						     \
++	stw	r1,0(r11);						     \
++	tovirt(r1,r11);							     \
++	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
++	stw	r0,GPR0(r11);						     \
++	SAVE_4GPRS(3, r11);						     \
++	SAVE_2GPRS(7, r11)
++
++	/*
++	 * State at this point:
++	 * r9 saved in stack frame, now saved SRR3 & ~MSR_WE
++	 * r10 saved in crit_r10 and in stack frame, trashed
++	 * r11 saved in crit_r11 and in stack frame,
++	 *	now phys stack/exception frame pointer
++	 * r12 saved in stack frame, now saved SRR2
++	 * CR saved in stack frame, CR0.EQ = !SRR3.PR
++	 * LR, DEAR, ESR in stack frame
++	 * r1 saved in stack frame, now virt stack/excframe pointer
++	 * r0, r3-r8 saved in stack frame
++	 */
++
++/*
++ * Exception vectors.
++ */
++#define	START_EXCEPTION(n, label)					     \
++	. = n;								     \
++label:
++
++#define EXCEPTION(n, label, hdlr, xfer)				\
++	START_EXCEPTION(n, label);				\
++	NORMAL_EXCEPTION_PROLOG;				\
++	addi	r3,r1,STACK_FRAME_OVERHEAD;			\
++	xfer(n, hdlr)
++
++#define CRITICAL_EXCEPTION(n, label, hdlr)			\
++	START_EXCEPTION(n, label);				\
++	CRITICAL_EXCEPTION_PROLOG;				\
++	addi	r3,r1,STACK_FRAME_OVERHEAD;			\
++	EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
++			  NOCOPY, crit_transfer_to_handler,	\
++			  ret_from_crit_exc)
++
++#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret)	\
++	li	r10,trap;					\
++	stw	r10,_TRAP(r11);					\
++	lis	r10,msr at h;					\
++	ori	r10,r10,msr at l;					\
++	copyee(r10, r9);					\
++	bl	tfer;		 				\
++	.long	hdlr;						\
++	.long	ret
++
++#define COPY_EE(d, s)		rlwimi d,s,0,16,16
++#define NOCOPY(d, s)
++
++#define EXC_XFER_STD(n, hdlr)		\
++	EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
++			  ret_from_except_full)
++
++#define EXC_XFER_LITE(n, hdlr)		\
++	EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
++			  ret_from_except)
++
++#define EXC_XFER_EE(n, hdlr)		\
++	EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
++			  ret_from_except_full)
++
++#define EXC_XFER_EE_LITE(n, hdlr)	\
++	EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
++			  ret_from_except)
++
++
++/*
++ * 0x0100 - Critical Interrupt Exception
++ */
++	CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
++
++/*
++ * 0x0200 - Machine Check Exception
++ */
++	CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
++
++/*
++ * 0x0300 - Data Storage Exception
++ * This happens for just a few reasons.  U0 set (but we don't do that),
++ * or zone protection fault (user violation, write to protected page).
++ * If this is just an update of modified status, we do that quickly
++ * and exit.  Otherwise, we call heavywight functions to do the work.
++ */
++	START_EXCEPTION(0x0300,	DataStorage)
++	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
++	mtspr	SPRN_SPRG1, r11
++#ifdef CONFIG_403GCX
++	stw     r12, 0(r0)
++	stw     r9, 4(r0)
++	mfcr    r11
++	mfspr   r12, SPRN_PID
++	stw     r11, 8(r0)
++	stw     r12, 12(r0)
++#else
++	mtspr	SPRN_SPRG4, r12
++	mtspr	SPRN_SPRG5, r9
++	mfcr	r11
++	mfspr	r12, SPRN_PID
++	mtspr	SPRN_SPRG7, r11
++	mtspr	SPRN_SPRG6, r12
++#endif
++
++	/* First, check if it was a zone fault (which means a user
++	* tried to access a kernel or read-protected page - always
++	* a SEGV).  All other faults here must be stores, so no
++	* need to check ESR_DST as well. */
++	mfspr	r10, SPRN_ESR
++	andis.	r10, r10, ESR_DIZ at h
++	bne	2f
++
++	mfspr	r10, SPRN_DEAR		/* Get faulting address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	lis	r11, TASK_SIZE at h
++	cmplw	r10, r11
++	blt+	3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++	li	r9, 0
++	mtspr	SPRN_PID, r9		/* TLB will have 0 TID */
++	b	4f
++
++	/* Get the PGD for the current thread.
++	 */
++3:
++	mfspr	r11,SPRN_SPRG3
++	lwz	r11,PGDIR(r11)
++4:
++	tophys(r11, r11)
++	rlwimi	r11, r10, 12, 20, 29	/* Create L1 (pgdir/pmd) address */
++	lwz	r11, 0(r11)		/* Get L1 entry */
++	rlwinm.	r12, r11, 0, 0, 19	/* Extract L2 (pte) base address */
++	beq	2f			/* Bail if no table */
++
++	rlwimi	r12, r10, 22, 20, 29	/* Compute PTE address */
++	lwz	r11, 0(r12)		/* Get Linux PTE */
++
++	andi.	r9, r11, _PAGE_RW	/* Is it writeable? */
++	beq	2f			/* Bail if not */
++
++	/* Update 'changed'.
++	*/
++	ori	r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
++	stw	r11, 0(r12)		/* Update Linux page table */
++
++	/* Most of the Linux PTE is ready to load into the TLB LO.
++	 * We set ZSEL, where only the LS-bit determines user access.
++	 * We set execute, because we don't have the granularity to
++	 * properly set this at the page level (Linux problem).
++	 * If shared is set, we cause a zero PID->TID load.
++	 * Many of these bits are software only.  Bits we don't set
++	 * here we (properly should) assume have the appropriate value.
++	 */
++	li	r12, 0x0ce2
++	andc	r11, r11, r12		/* Make sure 20, 21 are zero */
++
++	/* find the TLB index that caused the fault.  It has to be here.
++	*/
++	tlbsx	r9, 0, r10
++
++	tlbwe	r11, r9, TLB_DATA		/* Load TLB LO */
++
++	/* Done...restore registers and get out of here.
++	*/
++#ifdef CONFIG_403GCX
++	lwz     r12, 12(r0)
++	lwz     r11, 8(r0)
++	mtspr   SPRN_PID, r12
++	mtcr    r11
++	lwz     r9, 4(r0)
++	lwz     r12, 0(r0)
++#else
++	mfspr	r12, SPRN_SPRG6
++	mfspr	r11, SPRN_SPRG7
++	mtspr	SPRN_PID, r12
++	mtcr	r11
++	mfspr	r9, SPRN_SPRG5
++	mfspr	r12, SPRN_SPRG4
++#endif
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	PPC405_ERR77_SYNC
++	rfi			/* Should sync shadow TLBs */
++	b	.		/* prevent prefetch past rfi */
++
++2:
++	/* The bailout.  Restore registers to pre-exception conditions
++	 * and call the heavyweights to help us out.
++	 */
++#ifdef CONFIG_403GCX
++	lwz     r12, 12(r0)
++	lwz     r11, 8(r0)
++	mtspr   SPRN_PID, r12
++	mtcr    r11
++	lwz     r9, 4(r0)
++	lwz     r12, 0(r0)
++#else
++	mfspr	r12, SPRN_SPRG6
++	mfspr	r11, SPRN_SPRG7
++	mtspr	SPRN_PID, r12
++	mtcr	r11
++	mfspr	r9, SPRN_SPRG5
++	mfspr	r12, SPRN_SPRG4
++#endif
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	b	DataAccess
++
++/*
++ * 0x0400 - Instruction Storage Exception
++ * This is caused by a fetch from non-execute or guarded pages.
++ */
++	START_EXCEPTION(0x0400, InstructionAccess)
++	NORMAL_EXCEPTION_PROLOG
++	mr	r4,r12			/* Pass SRR0 as arg2 */
++	li	r5,0			/* Pass zero as arg3 */
++	EXC_XFER_EE_LITE(0x400, handle_page_fault)
++
++/* 0x0500 - External Interrupt Exception */
++	EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
++
++/* 0x0600 - Alignment Exception */
++	START_EXCEPTION(0x0600, Alignment)
++	NORMAL_EXCEPTION_PROLOG
++	mfspr	r4,SPRN_DEAR		/* Grab the DEAR and save it */
++	stw	r4,_DEAR(r11)
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_EE(0x600, alignment_exception)
++
++/* 0x0700 - Program Exception */
++	START_EXCEPTION(0x0700, ProgramCheck)
++	NORMAL_EXCEPTION_PROLOG
++	mfspr	r4,SPRN_ESR		/* Grab the ESR and save it */
++	stw	r4,_ESR(r11)
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_STD(0x700, program_check_exception)
++
++	EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_EE)
++
++/* 0x0C00 - System Call Exception */
++	START_EXCEPTION(0x0C00,	SystemCall)
++	NORMAL_EXCEPTION_PROLOG
++	EXC_XFER_EE_LITE(0xc00, DoSyscall)
++
++	EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_EE)
++
++/* 0x1000 - Programmable Interval Timer (PIT) Exception */
++	START_EXCEPTION(0x1000, Decrementer)
++	NORMAL_EXCEPTION_PROLOG
++	lis	r0,TSR_PIS at h
++	mtspr	SPRN_TSR,r0		/* Clear the PIT exception */
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_LITE(0x1000, timer_interrupt)
++
++#if 0
++/* NOTE:
++ * FIT and WDT handlers are not implemented yet.
++ */
++
++/* 0x1010 - Fixed Interval Timer (FIT) Exception
++*/
++	STND_EXCEPTION(0x1010,	FITException,		unknown_exception)
++
++/* 0x1020 - Watchdog Timer (WDT) Exception
++*/
++#ifdef CONFIG_BOOKE_WDT
++	CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException)
++#else
++	CRITICAL_EXCEPTION(0x1020, WDTException, unknown_exception)
++#endif
++#endif
++
++/* 0x1100 - Data TLB Miss Exception
++ * As the name implies, translation is not in the MMU, so search the
++ * page tables and fix it.  The only purpose of this function is to
++ * load TLB entries from the page table if they exist.
++ */
++	START_EXCEPTION(0x1100,	DTLBMiss)
++	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
++	mtspr	SPRN_SPRG1, r11
++#ifdef CONFIG_403GCX
++	stw     r12, 0(r0)
++	stw     r9, 4(r0)
++	mfcr    r11
++	mfspr   r12, SPRN_PID
++	stw     r11, 8(r0)
++	stw     r12, 12(r0)
++#else
++	mtspr	SPRN_SPRG4, r12
++	mtspr	SPRN_SPRG5, r9
++	mfcr	r11
++	mfspr	r12, SPRN_PID
++	mtspr	SPRN_SPRG7, r11
++	mtspr	SPRN_SPRG6, r12
++#endif
++	mfspr	r10, SPRN_DEAR		/* Get faulting address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	lis	r11, TASK_SIZE at h
++	cmplw	r10, r11
++	blt+	3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++	li	r9, 0
++	mtspr	SPRN_PID, r9		/* TLB will have 0 TID */
++	b	4f
++
++	/* Get the PGD for the current thread.
++	 */
++3:
++	mfspr	r11,SPRN_SPRG3
++	lwz	r11,PGDIR(r11)
++4:
++	tophys(r11, r11)
++	rlwimi	r11, r10, 12, 20, 29	/* Create L1 (pgdir/pmd) address */
++	lwz	r12, 0(r11)		/* Get L1 entry */
++	andi.	r9, r12, _PMD_PRESENT	/* Check if it points to a PTE page */
++	beq	2f			/* Bail if no table */
++
++	rlwimi	r12, r10, 22, 20, 29	/* Compute PTE address */
++	lwz	r11, 0(r12)		/* Get Linux PTE */
++	andi.	r9, r11, _PAGE_PRESENT
++	beq	5f
++
++	ori	r11, r11, _PAGE_ACCESSED
++	stw	r11, 0(r12)
++
++	/* Create TLB tag.  This is the faulting address plus a static
++	 * set of bits.  These are size, valid, E, U0.
++	*/
++	li	r12, 0x00c0
++	rlwimi	r10, r12, 0, 20, 31
++
++	b	finish_tlb_load
++
++2:	/* Check for possible large-page pmd entry */
++	rlwinm.	r9, r12, 2, 22, 24
++	beq	5f
++
++	/* Create TLB tag.  This is the faulting address, plus a static
++	 * set of bits (valid, E, U0) plus the size from the PMD.
++	 */
++	ori	r9, r9, 0x40
++	rlwimi	r10, r9, 0, 20, 31
++	mr	r11, r12
++
++	b	finish_tlb_load
++
++5:
++	/* The bailout.  Restore registers to pre-exception conditions
++	 * and call the heavyweights to help us out.
++	 */
++#ifdef CONFIG_403GCX
++	lwz     r12, 12(r0)
++	lwz     r11, 8(r0)
++	mtspr   SPRN_PID, r12
++	mtcr    r11
++	lwz     r9, 4(r0)
++	lwz     r12, 0(r0)
++#else
++	mfspr	r12, SPRN_SPRG6
++	mfspr	r11, SPRN_SPRG7
++	mtspr	SPRN_PID, r12
++	mtcr	r11
++	mfspr	r9, SPRN_SPRG5
++	mfspr	r12, SPRN_SPRG4
++#endif
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	b	DataAccess
++
++/* 0x1200 - Instruction TLB Miss Exception
++ * Nearly the same as above, except we get our information from different
++ * registers and bailout to a different point.
++ */
++	START_EXCEPTION(0x1200,	ITLBMiss)
++	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
++	mtspr	SPRN_SPRG1, r11
++#ifdef CONFIG_403GCX
++	stw     r12, 0(r0)
++	stw     r9, 4(r0)
++	mfcr    r11
++	mfspr   r12, SPRN_PID
++	stw     r11, 8(r0)
++	stw     r12, 12(r0)
++#else
++	mtspr	SPRN_SPRG4, r12
++	mtspr	SPRN_SPRG5, r9
++	mfcr	r11
++	mfspr	r12, SPRN_PID
++	mtspr	SPRN_SPRG7, r11
++	mtspr	SPRN_SPRG6, r12
++#endif
++	mfspr	r10, SPRN_SRR0		/* Get faulting address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	lis	r11, TASK_SIZE at h
++	cmplw	r10, r11
++	blt+	3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++	li	r9, 0
++	mtspr	SPRN_PID, r9		/* TLB will have 0 TID */
++	b	4f
++
++	/* Get the PGD for the current thread.
++	 */
++3:
++	mfspr	r11,SPRN_SPRG3
++	lwz	r11,PGDIR(r11)
++4:
++	tophys(r11, r11)
++	rlwimi	r11, r10, 12, 20, 29	/* Create L1 (pgdir/pmd) address */
++	lwz	r12, 0(r11)		/* Get L1 entry */
++	andi.	r9, r12, _PMD_PRESENT	/* Check if it points to a PTE page */
++	beq	2f			/* Bail if no table */
++
++	rlwimi	r12, r10, 22, 20, 29	/* Compute PTE address */
++	lwz	r11, 0(r12)		/* Get Linux PTE */
++	andi.	r9, r11, _PAGE_PRESENT
++	beq	5f
++
++	ori	r11, r11, _PAGE_ACCESSED
++	stw	r11, 0(r12)
++
++	/* Create TLB tag.  This is the faulting address plus a static
++	 * set of bits.  These are size, valid, E, U0.
++	*/
++	li	r12, 0x00c0
++	rlwimi	r10, r12, 0, 20, 31
++
++	b	finish_tlb_load
++
++2:	/* Check for possible large-page pmd entry */
++	rlwinm.	r9, r12, 2, 22, 24
++	beq	5f
++
++	/* Create TLB tag.  This is the faulting address, plus a static
++	 * set of bits (valid, E, U0) plus the size from the PMD.
++	 */
++	ori	r9, r9, 0x40
++	rlwimi	r10, r9, 0, 20, 31
++	mr	r11, r12
++
++	b	finish_tlb_load
++
++5:
++	/* The bailout.  Restore registers to pre-exception conditions
++	 * and call the heavyweights to help us out.
++	 */
++#ifdef CONFIG_403GCX
++	lwz     r12, 12(r0)
++	lwz     r11, 8(r0)
++	mtspr   SPRN_PID, r12
++	mtcr    r11
++	lwz     r9, 4(r0)
++	lwz     r12, 0(r0)
++#else
++	mfspr	r12, SPRN_SPRG6
++	mfspr	r11, SPRN_SPRG7
++	mtspr	SPRN_PID, r12
++	mtcr	r11
++	mfspr	r9, SPRN_SPRG5
++	mfspr	r12, SPRN_SPRG4
++#endif
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	b	InstructionAccess
++
++	EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
++#ifdef CONFIG_IBM405_ERR51
++	/* 405GP errata 51 */
++	START_EXCEPTION(0x1700, Trap_17)
++	b DTLBMiss
++#else
++	EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
++#endif
++	EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_EE)
++
++/* Check for a single step debug exception while in an exception
++ * handler before state has been saved.  This is to catch the case
++ * where an instruction that we are trying to single step causes
++ * an exception (eg ITLB/DTLB miss) and thus the first instruction of
++ * the exception handler generates a single step debug exception.
++ *
++ * If we get a debug trap on the first instruction of an exception handler,
++ * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
++ * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
++ * The exception handler was handling a non-critical interrupt, so it will
++ * save (and later restore) the MSR via SPRN_SRR1, which will still have
++ * the MSR_DE bit set.
++ */
++	/* 0x2000 - Debug Exception */
++	START_EXCEPTION(0x2000, DebugTrap)
++	CRITICAL_EXCEPTION_PROLOG
++
++	/*
++	 * If this is a single step or branch-taken exception in an
++	 * exception entry sequence, it was probably meant to apply to
++	 * the code where the exception occurred (since exception entry
++	 * doesn't turn off DE automatically).  We simulate the effect
++	 * of turning off DE on entry to an exception handler by turning
++	 * off DE in the SRR3 value and clearing the debug status.
++	 */
++	mfspr	r10,SPRN_DBSR		/* check single-step/branch taken */
++	andis.	r10,r10,DBSR_IC at h
++	beq+	2f
++
++	andi.	r10,r9,MSR_IR|MSR_PR	/* check supervisor + MMU off */
++	beq	1f			/* branch and fix it up */
++
++	mfspr   r10,SPRN_SRR2		/* Faulting instruction address */
++	cmplwi  r10,0x2100
++	bgt+    2f			/* address above exception vectors */
++
++	/* here it looks like we got an inappropriate debug exception. */
++1:	rlwinm	r9,r9,0,~MSR_DE		/* clear DE in the SRR3 value */
++	lis	r10,DBSR_IC at h		/* clear the IC event */
++	mtspr	SPRN_DBSR,r10
++	/* restore state and get out */
++	lwz	r10,_CCR(r11)
++	lwz	r0,GPR0(r11)
++	lwz	r1,GPR1(r11)
++	mtcrf	0x80,r10
++	mtspr	SPRN_SRR2,r12
++	mtspr	SPRN_SRR3,r9
++	lwz	r9,GPR9(r11)
++	lwz	r12,GPR12(r11)
++	lwz	r10,crit_r10 at l(0)
++	lwz	r11,crit_r11 at l(0)
++	PPC405_ERR77_SYNC
++	rfci
++	b	.
++
++	/* continue normal handling for a critical exception... */
++2:	mfspr	r4,SPRN_DBSR
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_TEMPLATE(DebugException, 0x2002, \
++		(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
++		NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
++
++/*
++ * The other Data TLB exceptions bail out to this point
++ * if they can't resolve the lightweight TLB fault.
++ */
++DataAccess:
++	NORMAL_EXCEPTION_PROLOG
++	mfspr	r5,SPRN_ESR		/* Grab the ESR, save it, pass arg3 */
++	stw	r5,_ESR(r11)
++	mfspr	r4,SPRN_DEAR		/* Grab the DEAR, save it, pass arg2 */
++	EXC_XFER_EE_LITE(0x300, handle_page_fault)
++
++/* Other PowerPC processors, namely those derived from the 6xx-series
++ * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
++ * However, for the 4xx-series processors these are neither defined nor
++ * reserved.
++ */
++
++	/* Damn, I came up one instruction too many to fit into the
++	 * exception space :-).  Both the instruction and data TLB
++	 * miss get to this point to load the TLB.
++	 * 	r10 - TLB_TAG value
++	 * 	r11 - Linux PTE
++	 *	r12, r9 - avilable to use
++	 *	PID - loaded with proper value when we get here
++	 *	Upon exit, we reload everything and RFI.
++	 * Actually, it will fit now, but oh well.....a common place
++	 * to load the TLB.
++	 */
++tlb_4xx_index:
++	.long	0
++finish_tlb_load:
++	/* load the next available TLB index.
++	*/
++	lwz	r9, tlb_4xx_index at l(0)
++	addi	r9, r9, 1
++	andi.	r9, r9, (PPC4XX_TLB_SIZE-1)
++	stw	r9, tlb_4xx_index at l(0)
++
++6:
++	/*
++	 * Clear out the software-only bits in the PTE to generate the
++	 * TLB_DATA value.  These are the bottom 2 bits of the RPM, the
++	 * top 3 bits of the zone field, and M.
++	 */
++	li	r12, 0x0ce2
++	andc	r11, r11, r12
++
++	tlbwe	r11, r9, TLB_DATA		/* Load TLB LO */
++	tlbwe	r10, r9, TLB_TAG		/* Load TLB HI */
++
++	/* Done...restore registers and get out of here.
++	*/
++#ifdef CONFIG_403GCX
++	lwz     r12, 12(r0)
++	lwz     r11, 8(r0)
++	mtspr   SPRN_PID, r12
++	mtcr    r11
++	lwz     r9, 4(r0)
++	lwz     r12, 0(r0)
++#else
++	mfspr	r12, SPRN_SPRG6
++	mfspr	r11, SPRN_SPRG7
++	mtspr	SPRN_PID, r12
++	mtcr	r11
++	mfspr	r9, SPRN_SPRG5
++	mfspr	r12, SPRN_SPRG4
++#endif
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	PPC405_ERR77_SYNC
++	rfi			/* Should sync shadow TLBs */
++	b	.		/* prevent prefetch past rfi */
++
++/* extern void giveup_fpu(struct task_struct *prev)
++ *
++ * The PowerPC 4xx family of processors do not have an FPU, so this just
++ * returns.
++ */
++_GLOBAL(giveup_fpu)
++	blr
++
++/* This is where the main kernel code starts.
++ */
++start_here:
++
++	/* ptr to current */
++	lis	r2,init_task at h
++	ori	r2,r2,init_task at l
++
++	/* ptr to phys current thread */
++	tophys(r4,r2)
++	addi	r4,r4,THREAD	/* init task's THREAD */
++	mtspr	SPRN_SPRG3,r4
++
++	/* stack */
++	lis	r1,init_thread_union at ha
++	addi	r1,r1,init_thread_union at l
++	li	r0,0
++	stwu	r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
++
++	bl	early_init	/* We have to do this with MMU on */
++
++/*
++ * Decide what sort of machine this is and initialize the MMU.
++ */
++	mr	r3,r31
++	mr	r4,r30
++	mr	r5,r29
++	mr	r6,r28
++	mr	r7,r27
++	bl	machine_init
++	bl	MMU_init
++
++/* Go back to running unmapped so we can load up new values
++ * and change to using our exception vectors.
++ * On the 4xx, all we have to do is invalidate the TLB to clear
++ * the old 16M byte TLB mappings.
++ */
++	lis	r4,2f at h
++	ori	r4,r4,2f at l
++	tophys(r4,r4)
++	lis	r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
++	ori	r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
++	mtspr	SPRN_SRR0,r4
++	mtspr	SPRN_SRR1,r3
++	rfi
++	b	.		/* prevent prefetch past rfi */
++
++/* Load up the kernel context */
++2:
++	sync			/* Flush to memory before changing TLB */
++	tlbia
++	isync			/* Flush shadow TLBs */
++
++	/* set up the PTE pointers for the Abatron bdiGDB.
++	*/
++	lis	r6, swapper_pg_dir at h
++	ori	r6, r6, swapper_pg_dir at l
++	lis	r5, abatron_pteptrs at h
++	ori	r5, r5, abatron_pteptrs at l
++	stw	r5, 0xf0(r0)	/* Must match your Abatron config file */
++	tophys(r5,r5)
++	stw	r6, 0(r5)
++
++/* Now turn on the MMU for real! */
++	lis	r4,MSR_KERNEL at h
++	ori	r4,r4,MSR_KERNEL at l
++	lis	r3,start_kernel at h
++	ori	r3,r3,start_kernel at l
++	mtspr	SPRN_SRR0,r3
++	mtspr	SPRN_SRR1,r4
++	rfi			/* enable MMU and jump to start_kernel */
++	b	.		/* prevent prefetch past rfi */
++
++/* Set up the initial MMU state so we can do the first level of
++ * kernel initialization.  This maps the first 16 MBytes of memory 1:1
++ * virtual to physical and more importantly sets the cache mode.
++ */
++initial_mmu:
++	tlbia			/* Invalidate all TLB entries */
++	isync
++
++	/* We should still be executing code at physical address 0x0000xxxx
++	 * at this point. However, start_here is at virtual address
++	 * 0xC000xxxx. So, set up a TLB mapping to cover this once
++	 * translation is enabled.
++	 */
++
++	lis	r3,KERNELBASE at h		/* Load the kernel virtual address */
++	ori	r3,r3,KERNELBASE at l
++	tophys(r4,r3)			/* Load the kernel physical address */
++
++	iccci	r0,r3			/* Invalidate the i-cache before use */
++
++	/* Load the kernel PID.
++	*/
++	li	r0,0
++	mtspr	SPRN_PID,r0
++	sync
++
++	/* Configure and load two entries into TLB slots 62 and 63.
++	 * In case we are pinning TLBs, these are reserved in by the
++	 * other TLB functions.  If not reserving, then it doesn't
++	 * matter where they are loaded.
++	 */
++	clrrwi	r4,r4,10		/* Mask off the real page number */
++	ori	r4,r4,(TLB_WR | TLB_EX)	/* Set the write and execute bits */
++
++	clrrwi	r3,r3,10		/* Mask off the effective page number */
++	ori	r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
++
++        li      r0,63                    /* TLB slot 63 */
++
++	tlbwe	r4,r0,TLB_DATA		/* Load the data portion of the entry */
++	tlbwe	r3,r0,TLB_TAG		/* Load the tag portion of the entry */
++
++#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE)
++
++	/* Load a TLB entry for the UART, so that ppc4xx_progress() can use
++	 * the UARTs nice and early.  We use a 4k real==virtual mapping. */
++
++	lis	r3,SERIAL_DEBUG_IO_BASE at h
++	ori	r3,r3,SERIAL_DEBUG_IO_BASE at l
++	mr	r4,r3
++	clrrwi	r4,r4,12
++	ori	r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)
++
++	clrrwi	r3,r3,12
++	ori	r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))
++
++	li	r0,0			/* TLB slot 0 */
++	tlbwe	r4,r0,TLB_DATA
++	tlbwe	r3,r0,TLB_TAG
++#endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */
++
++	isync
++
++	/* Establish the exception vector base
++	*/
++	lis	r4,KERNELBASE at h		/* EVPR only uses the high 16-bits */
++	tophys(r0,r4)			/* Use the physical address */
++	mtspr	SPRN_EVPR,r0
++
++	blr
++
++_GLOBAL(abort)
++        mfspr   r13,SPRN_DBCR0
++        oris    r13,r13,DBCR0_RST_SYSTEM at h
++        mtspr   SPRN_DBCR0,r13
++
++_GLOBAL(set_context)
++
++#ifdef CONFIG_BDI_SWITCH
++	/* Context switch the PTE pointer for the Abatron BDI2000.
++	 * The PGDIR is the second parameter.
++	 */
++	lis	r5, KERNELBASE at h
++	lwz	r5, 0xf0(r5)
++	stw	r4, 0x4(r5)
++#endif
++	sync
++	mtspr	SPRN_PID,r3
++	isync				/* Need an isync to flush shadow */
++					/* TLBs after changing PID */
++	blr
++
++/* We put a few things here that have to be page-aligned. This stuff
++ * goes at the beginning of the data segment, which is page-aligned.
++ */
++	.data
++	.align	12
++	.globl	sdata
++sdata:
++	.globl	empty_zero_page
++empty_zero_page:
++	.space	4096
++	.globl	swapper_pg_dir
++swapper_pg_dir:
++	.space	4096
++
++
++/* Stack for handling critical exceptions from kernel mode */
++	.section .bss
++        .align 12
++exception_stack_bottom:
++	.space	4096
++critical_stack_top:
++	.globl	exception_stack_top
++exception_stack_top:
++
++/* This space gets a copy of optional info passed to us by the bootstrap
++ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
++ */
++	.globl	cmd_line
++cmd_line:
++	.space	512
++
++/* Room for two PTE pointers, usually the kernel and current user pointers
++ * to their respective root page table.
++ */
++abatron_pteptrs:
++	.space	8
+diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/head_64.S
+@@ -0,0 +1,1957 @@
++/*
++ *  arch/ppc64/kernel/head.S
++ *
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Rewritten by Cort Dougan (cort at cs.nmt.edu) for PReP
++ *    Copyright (C) 1996 Cort Dougan <cort at cs.nmt.edu>
++ *  Adapted for Power Macintosh by Paul Mackerras.
++ *  Low-level exception handlers and MMU support
++ *  rewritten by Paul Mackerras.
++ *    Copyright (C) 1996 Paul Mackerras.
++ *
++ *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
++ *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
++ *
++ *  This file contains the low-level support and setup for the
++ *  PowerPC-64 platform, including trap and interrupt dispatch.
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/threads.h>
++#include <asm/reg.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/systemcfg.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++#include <asm/bug.h>
++#include <asm/cputable.h>
++#include <asm/setup.h>
++#include <asm/hvcall.h>
++#include <asm/iSeries/LparMap.h>
++#include <asm/thread_info.h>
++
++#ifdef CONFIG_PPC_ISERIES
++#define DO_SOFT_DISABLE
++#endif
++
++/*
++ * We layout physical memory as follows:
++ * 0x0000 - 0x00ff : Secondary processor spin code
++ * 0x0100 - 0x2fff : pSeries Interrupt prologs
++ * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
++ * 0x6000 - 0x6fff : Initial (CPU0) segment table
++ * 0x7000 - 0x7fff : FWNMI data area
++ * 0x8000 -        : Early init and support code
++ */
++
++/*
++ *   SPRG Usage
++ *
++ *   Register	Definition
++ *
++ *   SPRG0	reserved for hypervisor
++ *   SPRG1	temp - used to save gpr
++ *   SPRG2	temp - used to save gpr
++ *   SPRG3	virt addr of paca
++ */
++
++/*
++ * Entering into this code we make the following assumptions:
++ *  For pSeries:
++ *   1. The MMU is off & open firmware is running in real mode.
++ *   2. The kernel is entered at __start
++ *
++ *  For iSeries:
++ *   1. The MMU is on (as it always is for iSeries)
++ *   2. The kernel is entered at system_reset_iSeries
++ */
++
++	.text
++	.globl  _stext
++_stext:
++#ifdef CONFIG_PPC_MULTIPLATFORM
++_GLOBAL(__start)
++	/* NOP this out unconditionally */
++BEGIN_FTR_SECTION
++	b	.__start_initialization_multiplatform
++END_FTR_SECTION(0, 1)
++#endif /* CONFIG_PPC_MULTIPLATFORM */
++
++	/* Catch branch to 0 in real mode */
++	trap
++
++#ifdef CONFIG_PPC_ISERIES
++	/*
++	 * At offset 0x20, there is a pointer to iSeries LPAR data.
++	 * This is required by the hypervisor
++	 */
++	. = 0x20
++	.llong hvReleaseData-KERNELBASE
++
++	/*
++	 * At offset 0x28 and 0x30 are offsets to the mschunks_map
++	 * array (used by the iSeries LPAR debugger to do translation
++	 * between physical addresses and absolute addresses) and
++	 * to the pidhash table (also used by the debugger)
++	 */
++	.llong mschunks_map-KERNELBASE
++	.llong 0	/* pidhash-KERNELBASE SFRXXX */
++
++	/* Offset 0x38 - Pointer to start of embedded System.map */
++	.globl	embedded_sysmap_start
++embedded_sysmap_start:
++	.llong	0
++	/* Offset 0x40 - Pointer to end of embedded System.map */
++	.globl	embedded_sysmap_end
++embedded_sysmap_end:
++	.llong	0
++
++#endif /* CONFIG_PPC_ISERIES */
++
++	/* Secondary processors spin on this value until it goes to 1. */
++	.globl  __secondary_hold_spinloop
++__secondary_hold_spinloop:
++	.llong	0x0
++
++	/* Secondary processors write this value with their cpu # */
++	/* after they enter the spin loop immediately below.	  */
++	.globl	__secondary_hold_acknowledge
++__secondary_hold_acknowledge:
++	.llong	0x0
++
++	. = 0x60
++/*
++ * The following code is used on pSeries to hold secondary processors
++ * in a spin loop after they have been freed from OpenFirmware, but
++ * before the bulk of the kernel has been relocated.  This code
++ * is relocated to physical address 0x60 before prom_init is run.
++ * All of it must fit below the first exception vector at 0x100.
++ */
++_GLOBAL(__secondary_hold)
++	mfmsr	r24
++	ori	r24,r24,MSR_RI
++	mtmsrd	r24			/* RI on */
++
++	/* Grab our linux cpu number */
++	mr	r24,r3
++
++	/* Tell the master cpu we're here */
++	/* Relocation is off & we are located at an address less */
++	/* than 0x100, so only need to grab low order offset.    */
++	std	r24,__secondary_hold_acknowledge at l(0)
++	sync
++
++	/* All secondary cpus wait here until told to start. */
++100:	ld	r4,__secondary_hold_spinloop at l(0)
++	cmpdi	0,r4,1
++	bne	100b
++
++#ifdef CONFIG_HMT
++	b	.hmt_init
++#else
++#ifdef CONFIG_SMP
++	mr	r3,r24
++	b	.pSeries_secondary_smp_init
++#else
++	BUG_OPCODE
++#endif
++#endif
++
++/* This value is used to mark exception frames on the stack. */
++	.section ".toc","aw"
++exception_marker:
++	.tc	ID_72656773_68657265[TC],0x7265677368657265
++	.text
++
++/*
++ * The following macros define the code that appears as
++ * the prologue to each of the exception handlers.  They
++ * are split into two parts to allow a single kernel binary
++ * to be used for pSeries and iSeries.
++ * LOL.  One day... - paulus
++ */
++
++/*
++ * We make as much of the exception code common between native
++ * exception handlers (including pSeries LPAR) and iSeries LPAR
++ * implementations as possible.
++ */
++
++/*
++ * This is the start of the interrupt handlers for pSeries
++ * This code runs with relocation off.
++ */
++#define EX_R9		0
++#define EX_R10		8
++#define EX_R11		16
++#define EX_R12		24
++#define EX_R13		32
++#define EX_SRR0		40
++#define EX_R3		40	/* SLB miss saves R3, but not SRR0 */
++#define EX_DAR		48
++#define EX_LR		48	/* SLB miss saves LR, but not DAR */
++#define EX_DSISR	56
++#define EX_CCR		60
++
++#define EXCEPTION_PROLOG_PSERIES(area, label)				\
++	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
++	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
++	std	r10,area+EX_R10(r13);					\
++	std	r11,area+EX_R11(r13);					\
++	std	r12,area+EX_R12(r13);					\
++	mfspr	r9,SPRN_SPRG1;						\
++	std	r9,area+EX_R13(r13);					\
++	mfcr	r9;							\
++	clrrdi	r12,r13,32;		/* get high part of &label */	\
++	mfmsr	r10;							\
++	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
++	ori	r12,r12,(label)@l;	/* virt addr of handler */	\
++	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI;				\
++	mtspr	SPRN_SRR0,r12;						\
++	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
++	mtspr	SPRN_SRR1,r10;						\
++	rfid;								\
++	b	.	/* prevent speculative execution */
++
++/*
++ * This is the start of the interrupt handlers for iSeries
++ * This code runs with relocation on.
++ */
++#define EXCEPTION_PROLOG_ISERIES_1(area)				\
++	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
++	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
++	std	r10,area+EX_R10(r13);					\
++	std	r11,area+EX_R11(r13);					\
++	std	r12,area+EX_R12(r13);					\
++	mfspr	r9,SPRN_SPRG1;						\
++	std	r9,area+EX_R13(r13);					\
++	mfcr	r9
++
++#define EXCEPTION_PROLOG_ISERIES_2					\
++	mfmsr	r10;							\
++	ld	r11,PACALPPACA+LPPACASRR0(r13);				\
++	ld	r12,PACALPPACA+LPPACASRR1(r13);				\
++	ori	r10,r10,MSR_RI;						\
++	mtmsrd	r10,1
++
++/*
++ * The common exception prolog is used for all except a few exceptions
++ * such as a segment miss on a kernel address.  We have to be prepared
++ * to take another exception from the point where we first touch the
++ * kernel stack onwards.
++ *
++ * On entry r13 points to the paca, r9-r13 are saved in the paca,
++ * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
++ * SRR1, and relocation is on.
++ */
++#define EXCEPTION_PROLOG_COMMON(n, area)				   \
++	andi.	r10,r12,MSR_PR;		/* See if coming from user	*/ \
++	mr	r10,r1;			/* Save r1			*/ \
++	subi	r1,r1,INT_FRAME_SIZE;	/* alloc frame on kernel stack	*/ \
++	beq-	1f;							   \
++	ld	r1,PACAKSAVE(r13);	/* kernel stack to use		*/ \
++1:	cmpdi	cr1,r1,0;		/* check if r1 is in userspace	*/ \
++	bge-	cr1,bad_stack;		/* abort if it is		*/ \
++	std	r9,_CCR(r1);		/* save CR in stackframe	*/ \
++	std	r11,_NIP(r1);		/* save SRR0 in stackframe	*/ \
++	std	r12,_MSR(r1);		/* save SRR1 in stackframe	*/ \
++	std	r10,0(r1);		/* make stack chain pointer	*/ \
++	std	r0,GPR0(r1);		/* save r0 in stackframe	*/ \
++	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
++	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
++	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe	*/ \
++	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
++	ld	r9,area+EX_R9(r13);	/* move r9, r10 to stackframe	*/ \
++	ld	r10,area+EX_R10(r13);					   \
++	std	r9,GPR9(r1);						   \
++	std	r10,GPR10(r1);						   \
++	ld	r9,area+EX_R11(r13);	/* move r11 - r13 to stackframe	*/ \
++	ld	r10,area+EX_R12(r13);					   \
++	ld	r11,area+EX_R13(r13);					   \
++	std	r9,GPR11(r1);						   \
++	std	r10,GPR12(r1);						   \
++	std	r11,GPR13(r1);						   \
++	ld	r2,PACATOC(r13);	/* get kernel TOC into r2	*/ \
++	mflr	r9;			/* save LR in stackframe	*/ \
++	std	r9,_LINK(r1);						   \
++	mfctr	r10;			/* save CTR in stackframe	*/ \
++	std	r10,_CTR(r1);						   \
++	mfspr	r11,SPRN_XER;		/* save XER in stackframe	*/ \
++	std	r11,_XER(r1);						   \
++	li	r9,(n)+1;						   \
++	std	r9,_TRAP(r1);		/* set trap number		*/ \
++	li	r10,0;							   \
++	ld	r11,exception_marker at toc(r2);				   \
++	std	r10,RESULT(r1);		/* clear regs->result		*/ \
++	std	r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame	*/
++
++/*
++ * Exception vectors.
++ */
++#define STD_EXCEPTION_PSERIES(n, label)			\
++	. = n;						\
++	.globl label##_pSeries;				\
++label##_pSeries:					\
++	HMT_MEDIUM;					\
++	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
++	RUNLATCH_ON(r13);				\
++	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
++
++#define STD_EXCEPTION_ISERIES(n, label, area)		\
++	.globl label##_iSeries;				\
++label##_iSeries:					\
++	HMT_MEDIUM;					\
++	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
++	RUNLATCH_ON(r13);				\
++	EXCEPTION_PROLOG_ISERIES_1(area);		\
++	EXCEPTION_PROLOG_ISERIES_2;			\
++	b	label##_common
++
++#define MASKABLE_EXCEPTION_ISERIES(n, label)				\
++	.globl label##_iSeries;						\
++label##_iSeries:							\
++	HMT_MEDIUM;							\
++	mtspr	SPRN_SPRG1,r13;		/* save r13 */			\
++	RUNLATCH_ON(r13);						\
++	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);				\
++	lbz	r10,PACAPROCENABLED(r13);				\
++	cmpwi	0,r10,0;						\
++	beq-	label##_iSeries_masked;					\
++	EXCEPTION_PROLOG_ISERIES_2;					\
++	b	label##_common;						\
++
++#ifdef DO_SOFT_DISABLE
++#define DISABLE_INTS				\
++	lbz	r10,PACAPROCENABLED(r13);	\
++	li	r11,0;				\
++	std	r10,SOFTE(r1);			\
++	mfmsr	r10;				\
++	stb	r11,PACAPROCENABLED(r13);	\
++	ori	r10,r10,MSR_EE;			\
++	mtmsrd	r10,1
++
++#define ENABLE_INTS				\
++	lbz	r10,PACAPROCENABLED(r13);	\
++	mfmsr	r11;				\
++	std	r10,SOFTE(r1);			\
++	ori	r11,r11,MSR_EE;			\
++	mtmsrd	r11,1
++
++#else	/* hard enable/disable interrupts */
++#define DISABLE_INTS
++
++#define ENABLE_INTS				\
++	ld	r12,_MSR(r1);			\
++	mfmsr	r11;				\
++	rlwimi	r11,r12,0,MSR_EE;		\
++	mtmsrd	r11,1
++
++#endif
++
++#define STD_EXCEPTION_COMMON(trap, label, hdlr)		\
++	.align	7;					\
++	.globl label##_common;				\
++label##_common:						\
++	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
++	DISABLE_INTS;					\
++	bl	.save_nvgprs;				\
++	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
++	bl	hdlr;					\
++	b	.ret_from_except
++
++#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr)	\
++	.align	7;					\
++	.globl label##_common;				\
++label##_common:						\
++	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
++	DISABLE_INTS;					\
++	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
++	bl	hdlr;					\
++	b	.ret_from_except_lite
++
++/*
++ * Start of pSeries system interrupt routines
++ */
++	. = 0x100
++	.globl __start_interrupts
++__start_interrupts:
++
++	STD_EXCEPTION_PSERIES(0x100, system_reset)
++
++	. = 0x200
++_machine_check_pSeries:
++	HMT_MEDIUM
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
++	RUNLATCH_ON(r13)
++	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
++
++	. = 0x300
++	.globl data_access_pSeries
++data_access_pSeries:
++	HMT_MEDIUM
++	mtspr	SPRN_SPRG1,r13
++BEGIN_FTR_SECTION
++	mtspr	SPRN_SPRG2,r12
++	mfspr	r13,SPRN_DAR
++	mfspr	r12,SPRN_DSISR
++	srdi	r13,r13,60
++	rlwimi	r13,r12,16,0x20
++	mfcr	r12
++	cmpwi	r13,0x2c
++	beq	.do_stab_bolted_pSeries
++	mtcrf	0x80,r12
++	mfspr	r12,SPRN_SPRG2
++END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
++	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
++
++	. = 0x380
++	.globl data_access_slb_pSeries
++data_access_slb_pSeries:
++	HMT_MEDIUM
++	mtspr	SPRN_SPRG1,r13
++	RUNLATCH_ON(r13)
++	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
++	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
++	std	r10,PACA_EXSLB+EX_R10(r13)
++	std	r11,PACA_EXSLB+EX_R11(r13)
++	std	r12,PACA_EXSLB+EX_R12(r13)
++	std	r3,PACA_EXSLB+EX_R3(r13)
++	mfspr	r9,SPRN_SPRG1
++	std	r9,PACA_EXSLB+EX_R13(r13)
++	mfcr	r9
++	mfspr	r12,SPRN_SRR1		/* and SRR1 */
++	mfspr	r3,SPRN_DAR
++	b	.do_slb_miss		/* Rel. branch works in real mode */
++
++	STD_EXCEPTION_PSERIES(0x400, instruction_access)
++
++	. = 0x480
++	.globl instruction_access_slb_pSeries
++instruction_access_slb_pSeries:
++	HMT_MEDIUM
++	mtspr	SPRN_SPRG1,r13
++	RUNLATCH_ON(r13)
++	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
++	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
++	std	r10,PACA_EXSLB+EX_R10(r13)
++	std	r11,PACA_EXSLB+EX_R11(r13)
++	std	r12,PACA_EXSLB+EX_R12(r13)
++	std	r3,PACA_EXSLB+EX_R3(r13)
++	mfspr	r9,SPRN_SPRG1
++	std	r9,PACA_EXSLB+EX_R13(r13)
++	mfcr	r9
++	mfspr	r12,SPRN_SRR1		/* and SRR1 */
++	mfspr	r3,SPRN_SRR0			/* SRR0 is faulting address */
++	b	.do_slb_miss		/* Rel. branch works in real mode */
++
++	STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
++	STD_EXCEPTION_PSERIES(0x600, alignment)
++	STD_EXCEPTION_PSERIES(0x700, program_check)
++	STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
++	STD_EXCEPTION_PSERIES(0x900, decrementer)
++	STD_EXCEPTION_PSERIES(0xa00, trap_0a)
++	STD_EXCEPTION_PSERIES(0xb00, trap_0b)
++
++	. = 0xc00
++	.globl	system_call_pSeries
++system_call_pSeries:
++	HMT_MEDIUM
++	RUNLATCH_ON(r9)
++	mr	r9,r13
++	mfmsr	r10
++	mfspr	r13,SPRN_SPRG3
++	mfspr	r11,SPRN_SRR0
++	clrrdi	r12,r13,32
++	oris	r12,r12,system_call_common at h
++	ori	r12,r12,system_call_common at l
++	mtspr	SPRN_SRR0,r12
++	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI
++	mfspr	r12,SPRN_SRR1
++	mtspr	SPRN_SRR1,r10
++	rfid
++	b	.	/* prevent speculative execution */
++
++	STD_EXCEPTION_PSERIES(0xd00, single_step)
++	STD_EXCEPTION_PSERIES(0xe00, trap_0e)
++
++	/* We need to deal with the Altivec unavailable exception
++	 * here which is at 0xf20, thus in the middle of the
++	 * prolog code of the PerformanceMonitor one. A little
++	 * trickery is thus necessary
++	 */
++	. = 0xf00
++	b	performance_monitor_pSeries
++
++	STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable)
++
++	STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
++	STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
++
++	. = 0x3000
++
++/*** pSeries interrupt support ***/
++
++	/* moved from 0xf00 */
++	STD_EXCEPTION_PSERIES(., performance_monitor)
++
++	.align	7
++_GLOBAL(do_stab_bolted_pSeries)
++	mtcrf	0x80,r12
++	mfspr	r12,SPRN_SPRG2
++	EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
++
++/*
++ * Vectors for the FWNMI option.  Share common code.
++ */
++	.globl system_reset_fwnmi
++system_reset_fwnmi:
++	HMT_MEDIUM
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
++	RUNLATCH_ON(r13)
++	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
++
++	.globl machine_check_fwnmi
++machine_check_fwnmi:
++	HMT_MEDIUM
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
++	RUNLATCH_ON(r13)
++	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
++
++#ifdef CONFIG_PPC_ISERIES
++/***  ISeries-LPAR interrupt handlers ***/
++
++	STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
++
++	.globl data_access_iSeries
++data_access_iSeries:
++	mtspr	SPRN_SPRG1,r13
++BEGIN_FTR_SECTION
++	mtspr	SPRN_SPRG2,r12
++	mfspr	r13,SPRN_DAR
++	mfspr	r12,SPRN_DSISR
++	srdi	r13,r13,60
++	rlwimi	r13,r12,16,0x20
++	mfcr	r12
++	cmpwi	r13,0x2c
++	beq	.do_stab_bolted_iSeries
++	mtcrf	0x80,r12
++	mfspr	r12,SPRN_SPRG2
++END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
++	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
++	EXCEPTION_PROLOG_ISERIES_2
++	b	data_access_common
++
++.do_stab_bolted_iSeries:
++	mtcrf	0x80,r12
++	mfspr	r12,SPRN_SPRG2
++	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
++	EXCEPTION_PROLOG_ISERIES_2
++	b	.do_stab_bolted
++
++	.globl	data_access_slb_iSeries
++data_access_slb_iSeries:
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
++	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
++	std	r3,PACA_EXSLB+EX_R3(r13)
++	ld	r12,PACALPPACA+LPPACASRR1(r13)
++	mfspr	r3,SPRN_DAR
++	b	.do_slb_miss
++
++	STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
++
++	.globl	instruction_access_slb_iSeries
++instruction_access_slb_iSeries:
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
++	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
++	std	r3,PACA_EXSLB+EX_R3(r13)
++	ld	r12,PACALPPACA+LPPACASRR1(r13)
++	ld	r3,PACALPPACA+LPPACASRR0(r13)
++	b	.do_slb_miss
++
++	MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
++	STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
++	STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN)
++	STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN)
++	MASKABLE_EXCEPTION_ISERIES(0x900, decrementer)
++	STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN)
++	STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN)
++
++	.globl	system_call_iSeries
++system_call_iSeries:
++	mr	r9,r13
++	mfspr	r13,SPRN_SPRG3
++	EXCEPTION_PROLOG_ISERIES_2
++	b	system_call_common
++
++	STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN)
++	STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN)
++	STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN)
++
++	.globl system_reset_iSeries
++system_reset_iSeries:
++	mfspr	r13,SPRN_SPRG3		/* Get paca address */
++	mfmsr	r24
++	ori	r24,r24,MSR_RI
++	mtmsrd	r24			/* RI on */
++	lhz	r24,PACAPACAINDEX(r13)	/* Get processor # */
++	cmpwi	0,r24,0			/* Are we processor 0? */
++	beq	.__start_initialization_iSeries	/* Start up the first processor */
++	mfspr	r4,SPRN_CTRLF
++	li	r5,CTRL_RUNLATCH	/* Turn off the run light */
++	andc	r4,r4,r5
++	mtspr	SPRN_CTRLT,r4
++
++1:
++	HMT_LOW
++#ifdef CONFIG_SMP
++	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor
++					 * should start */
++	sync
++	LOADADDR(r3,current_set)
++	sldi	r28,r24,3		/* get current_set[cpu#] */
++	ldx	r3,r3,r28
++	addi	r1,r3,THREAD_SIZE
++	subi	r1,r1,STACK_FRAME_OVERHEAD
++
++	cmpwi	0,r23,0
++	beq	iSeries_secondary_smp_loop	/* Loop until told to go */
++	bne	.__secondary_start		/* Loop until told to go */
++iSeries_secondary_smp_loop:
++	/* Let the Hypervisor know we are alive */
++	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
++	lis	r3,0x8002
++	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */
++#else /* CONFIG_SMP */
++	/* Yield the processor.  This is required for non-SMP kernels
++		which are running on multi-threaded machines. */
++	lis	r3,0x8000
++	rldicr	r3,r3,32,15		/* r3 = (r3 << 32) & 0xffff000000000000 */
++	addi	r3,r3,18		/* r3 = 0x8000000000000012 which is "yield" */
++	li	r4,0			/* "yield timed" */
++	li	r5,-1			/* "yield forever" */
++#endif /* CONFIG_SMP */
++	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
++	sc				/* Invoke the hypervisor via a system call */
++	mfspr	r13,SPRN_SPRG3		/* Put r13 back ???? */
++	b	1b			/* If SMP not configured, secondaries
++					 * loop forever */
++
++	.globl decrementer_iSeries_masked
++decrementer_iSeries_masked:
++	li	r11,1
++	stb	r11,PACALPPACA+LPPACADECRINT(r13)
++	lwz	r12,PACADEFAULTDECR(r13)
++	mtspr	SPRN_DEC,r12
++	/* fall through */
++
++	.globl hardware_interrupt_iSeries_masked
++hardware_interrupt_iSeries_masked:
++	mtcrf	0x80,r9		/* Restore regs */
++	ld	r11,PACALPPACA+LPPACASRR0(r13)
++	ld	r12,PACALPPACA+LPPACASRR1(r13)
++	mtspr	SPRN_SRR0,r11
++	mtspr	SPRN_SRR1,r12
++	ld	r9,PACA_EXGEN+EX_R9(r13)
++	ld	r10,PACA_EXGEN+EX_R10(r13)
++	ld	r11,PACA_EXGEN+EX_R11(r13)
++	ld	r12,PACA_EXGEN+EX_R12(r13)
++	ld	r13,PACA_EXGEN+EX_R13(r13)
++	rfid
++	b	.	/* prevent speculative execution */
++#endif /* CONFIG_PPC_ISERIES */
++
++/*** Common interrupt handlers ***/
++
++	STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
++
++	/*
++	 * Machine check is different because we use a different
++	 * save area: PACA_EXMC instead of PACA_EXGEN.
++	 */
++	.align	7
++	.globl machine_check_common
++machine_check_common:
++	EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
++	DISABLE_INTS
++	bl	.save_nvgprs
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.machine_check_exception
++	b	.ret_from_except
++
++	STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
++	STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
++	STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
++	STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
++	STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
++	STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception)
++	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
++#ifdef CONFIG_ALTIVEC
++	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
++#else
++	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
++#endif
++
++/*
++ * Here we have detected that the kernel stack pointer is bad.
++ * R9 contains the saved CR, r13 points to the paca,
++ * r10 contains the (bad) kernel stack pointer,
++ * r11 and r12 contain the saved SRR0 and SRR1.
++ * We switch to using an emergency stack, save the registers there,
++ * and call kernel_bad_stack(), which panics.
++ */
++bad_stack:
++	ld	r1,PACAEMERGSP(r13)
++	subi	r1,r1,64+INT_FRAME_SIZE
++	std	r9,_CCR(r1)
++	std	r10,GPR1(r1)
++	std	r11,_NIP(r1)
++	std	r12,_MSR(r1)
++	mfspr	r11,SPRN_DAR
++	mfspr	r12,SPRN_DSISR
++	std	r11,_DAR(r1)
++	std	r12,_DSISR(r1)
++	mflr	r10
++	mfctr	r11
++	mfxer	r12
++	std	r10,_LINK(r1)
++	std	r11,_CTR(r1)
++	std	r12,_XER(r1)
++	SAVE_GPR(0,r1)
++	SAVE_GPR(2,r1)
++	SAVE_4GPRS(3,r1)
++	SAVE_2GPRS(7,r1)
++	SAVE_10GPRS(12,r1)
++	SAVE_10GPRS(22,r1)
++	addi	r11,r1,INT_FRAME_SIZE
++	std	r11,0(r1)
++	li	r12,0
++	std	r12,0(r11)
++	ld	r2,PACATOC(r13)
++1:	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.kernel_bad_stack
++	b	1b
++
++/*
++ * Return from an exception with minimal checks.
++ * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
++ * If interrupts have been enabled, or anything has been
++ * done that might have changed the scheduling status of
++ * any task or sent any task a signal, you should use
++ * ret_from_except or ret_from_except_lite instead of this.
++ */
++	.globl	fast_exception_return
++fast_exception_return:
++	ld	r12,_MSR(r1)
++	ld	r11,_NIP(r1)
++	andi.	r3,r12,MSR_RI		/* check if RI is set */
++	beq-	unrecov_fer
++	ld	r3,_CCR(r1)
++	ld	r4,_LINK(r1)
++	ld	r5,_CTR(r1)
++	ld	r6,_XER(r1)
++	mtcr	r3
++	mtlr	r4
++	mtctr	r5
++	mtxer	r6
++	REST_GPR(0, r1)
++	REST_8GPRS(2, r1)
++
++	mfmsr	r10
++	clrrdi	r10,r10,2		/* clear RI (LE is 0 already) */
++	mtmsrd	r10,1
++
++	mtspr	SPRN_SRR1,r12
++	mtspr	SPRN_SRR0,r11
++	REST_4GPRS(10, r1)
++	ld	r1,GPR1(r1)
++	rfid
++	b	.	/* prevent speculative execution */
++
++unrecov_fer:
++	bl	.save_nvgprs
++1:	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.unrecoverable_exception
++	b	1b
++
++/*
++ * Here r13 points to the paca, r9 contains the saved CR,
++ * SRR0 and SRR1 are saved in r11 and r12,
++ * r9 - r13 are saved in paca->exgen.
++ */
++	.align	7
++	.globl data_access_common
++data_access_common:
++	RUNLATCH_ON(r10)		/* It wont fit in the 0x300 handler */
++	mfspr	r10,SPRN_DAR
++	std	r10,PACA_EXGEN+EX_DAR(r13)
++	mfspr	r10,SPRN_DSISR
++	stw	r10,PACA_EXGEN+EX_DSISR(r13)
++	EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
++	ld	r3,PACA_EXGEN+EX_DAR(r13)
++	lwz	r4,PACA_EXGEN+EX_DSISR(r13)
++	li	r5,0x300
++	b	.do_hash_page	 	/* Try to handle as hpte fault */
++
++	.align	7
++	.globl instruction_access_common
++instruction_access_common:
++	EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
++	ld	r3,_NIP(r1)
++	andis.	r4,r12,0x5820
++	li	r5,0x400
++	b	.do_hash_page		/* Try to handle as hpte fault */
++
++	.align	7
++	.globl hardware_interrupt_common
++	.globl hardware_interrupt_entry
++hardware_interrupt_common:
++	EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
++hardware_interrupt_entry:
++	DISABLE_INTS
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.do_IRQ
++	b	.ret_from_except_lite
++
++	.align	7
++	.globl alignment_common
++alignment_common:
++	mfspr	r10,SPRN_DAR
++	std	r10,PACA_EXGEN+EX_DAR(r13)
++	mfspr	r10,SPRN_DSISR
++	stw	r10,PACA_EXGEN+EX_DSISR(r13)
++	EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
++	ld	r3,PACA_EXGEN+EX_DAR(r13)
++	lwz	r4,PACA_EXGEN+EX_DSISR(r13)
++	std	r3,_DAR(r1)
++	std	r4,_DSISR(r1)
++	bl	.save_nvgprs
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	ENABLE_INTS
++	bl	.alignment_exception
++	b	.ret_from_except
++
++	.align	7
++	.globl program_check_common
++program_check_common:
++	EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
++	bl	.save_nvgprs
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	ENABLE_INTS
++	bl	.program_check_exception
++	b	.ret_from_except
++
++	.align	7
++	.globl fp_unavailable_common
++fp_unavailable_common:
++	EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
++	bne	.load_up_fpu		/* if from user, just load it up */
++	bl	.save_nvgprs
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	ENABLE_INTS
++	bl	.kernel_fp_unavailable_exception
++	BUG_OPCODE
++
++	.align	7
++	.globl altivec_unavailable_common
++altivec_unavailable_common:
++	EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
++#ifdef CONFIG_ALTIVEC
++BEGIN_FTR_SECTION
++	bne	.load_up_altivec	/* if from user, just load it up */
++END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
++#endif
++	bl	.save_nvgprs
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	ENABLE_INTS
++	bl	.altivec_unavailable_exception
++	b	.ret_from_except
++
++#ifdef CONFIG_ALTIVEC
++/*
++ * load_up_altivec(unused, unused, tsk)
++ * Disable VMX for the task which had it previously,
++ * and save its vector registers in its thread_struct.
++ * Enables the VMX for use in the kernel on return.
++ * On SMP we know the VMX is free, since we give it up every
++ * switch (ie, no lazy save of the vector registers).
++ * On entry: r13 == 'current' && last_task_used_altivec != 'current'
++ */
++_STATIC(load_up_altivec)
++	mfmsr	r5			/* grab the current MSR */
++	oris	r5,r5,MSR_VEC at h
++	mtmsrd	r5			/* enable use of VMX now */
++	isync
++
++/*
++ * For SMP, we don't do lazy VMX switching because it just gets too
++ * horrendously complex, especially when a task switches from one CPU
++ * to another.  Instead we call giveup_altvec in switch_to.
++ * VRSAVE isn't dealt with here, that is done in the normal context
++ * switch code. Note that we could rely on vrsave value to eventually
++ * avoid saving all of the VREGs here...
++ */
++#ifndef CONFIG_SMP
++	ld	r3,last_task_used_altivec at got(r2)
++	ld	r4,0(r3)
++	cmpdi	0,r4,0
++	beq	1f
++	/* Save VMX state to last_task_used_altivec's THREAD struct */
++	addi	r4,r4,THREAD
++	SAVE_32VRS(0,r5,r4)
++	mfvscr	vr0
++	li	r10,THREAD_VSCR
++	stvx	vr0,r10,r4
++	/* Disable VMX for last_task_used_altivec */
++	ld	r5,PT_REGS(r4)
++	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++	lis	r6,MSR_VEC at h
++	andc	r4,r4,r6
++	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++1:
++#endif /* CONFIG_SMP */
++	/* Hack: if we get an altivec unavailable trap with VRSAVE
++	 * set to all zeros, we assume this is a broken application
++	 * that fails to set it properly, and thus we switch it to
++	 * all 1's
++	 */
++	mfspr	r4,SPRN_VRSAVE
++	cmpdi	0,r4,0
++	bne+	1f
++	li	r4,-1
++	mtspr	SPRN_VRSAVE,r4
++1:
++	/* enable use of VMX after return */
++	ld	r4,PACACURRENT(r13)
++	addi	r5,r4,THREAD		/* Get THREAD */
++	oris	r12,r12,MSR_VEC at h
++	std	r12,_MSR(r1)
++	li	r4,1
++	li	r10,THREAD_VSCR
++	stw	r4,THREAD_USED_VR(r5)
++	lvx	vr0,r10,r5
++	mtvscr	vr0
++	REST_32VRS(0,r4,r5)
++#ifndef CONFIG_SMP
++	/* Update last_task_used_math to 'current' */
++	subi	r4,r5,THREAD		/* Back to 'current' */
++	std	r4,0(r3)
++#endif /* CONFIG_SMP */
++	/* restore registers and return */
++	b	fast_exception_return
++#endif /* CONFIG_ALTIVEC */
++
++/*
++ * Hash table stuff
++ */
++	.align	7
++_GLOBAL(do_hash_page)
++	std	r3,_DAR(r1)
++	std	r4,_DSISR(r1)
++
++	andis.	r0,r4,0xa450		/* weird error? */
++	bne-	.handle_page_fault	/* if not, try to insert a HPTE */
++BEGIN_FTR_SECTION
++	andis.	r0,r4,0x0020		/* Is it a segment table fault? */
++	bne-	.do_ste_alloc		/* If so handle it */
++END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
++
++	/*
++	 * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
++	 * accessing a userspace segment (even from the kernel). We assume
++	 * kernel addresses always have the high bit set.
++	 */
++	rlwinm	r4,r4,32-25+9,31-9,31-9	/* DSISR_STORE -> _PAGE_RW */
++	rotldi	r0,r3,15		/* Move high bit into MSR_PR posn */
++	orc	r0,r12,r0		/* MSR_PR | ~high_bit */
++	rlwimi	r4,r0,32-13,30,30	/* becomes _PAGE_USER access bit */
++	ori	r4,r4,1			/* add _PAGE_PRESENT */
++	rlwimi	r4,r5,22+2,31-2,31-2	/* Set _PAGE_EXEC if trap is 0x400 */
++
++	/*
++	 * On iSeries, we soft-disable interrupts here, then
++	 * hard-enable interrupts so that the hash_page code can spin on
++	 * the hash_table_lock without problems on a shared processor.
++	 */
++	DISABLE_INTS
++
++	/*
++	 * r3 contains the faulting address
++	 * r4 contains the required access permissions
++	 * r5 contains the trap number
++	 *
++	 * at return r3 = 0 for success
++	 */
++	bl	.hash_page		/* build HPTE if possible */
++	cmpdi	r3,0			/* see if hash_page succeeded */
++
++#ifdef DO_SOFT_DISABLE
++	/*
++	 * If we had interrupts soft-enabled at the point where the
++	 * DSI/ISI occurred, and an interrupt came in during hash_page,
++	 * handle it now.
++	 * We jump to ret_from_except_lite rather than fast_exception_return
++	 * because ret_from_except_lite will check for and handle pending
++	 * interrupts if necessary.
++	 */
++	beq	.ret_from_except_lite
++	/* For a hash failure, we don't bother re-enabling interrupts */
++	ble-	12f
++
++	/*
++	 * hash_page couldn't handle it, set soft interrupt enable back
++	 * to what it was before the trap.  Note that .local_irq_restore
++	 * handles any interrupts pending at this point.
++	 */
++	ld	r3,SOFTE(r1)
++	bl	.local_irq_restore
++	b	11f
++#else
++	beq	fast_exception_return   /* Return from exception on success */
++	ble-	12f			/* Failure return from hash_page */
++
++	/* fall through */
++#endif
++
++/* Here we have a page fault that hash_page can't handle. */
++_GLOBAL(handle_page_fault)
++	ENABLE_INTS
++11:	ld	r4,_DAR(r1)
++	ld	r5,_DSISR(r1)
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.do_page_fault
++	cmpdi	r3,0
++	beq+	.ret_from_except_lite
++	bl	.save_nvgprs
++	mr	r5,r3
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	lwz	r4,_DAR(r1)
++	bl	.bad_page_fault
++	b	.ret_from_except
++
++/* We have a page fault that hash_page could handle but HV refused
++ * the PTE insertion
++ */
++12:	bl	.save_nvgprs
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	lwz	r4,_DAR(r1)
++	bl	.low_hash_fault
++	b	.ret_from_except
++
++	/* here we have a segment miss */
++_GLOBAL(do_ste_alloc)
++	bl	.ste_allocate		/* try to insert stab entry */
++	cmpdi	r3,0
++	beq+	fast_exception_return
++	b	.handle_page_fault
++
++/*
++ * r13 points to the PACA, r9 contains the saved CR,
++ * r11 and r12 contain the saved SRR0 and SRR1.
++ * r9 - r13 are saved in paca->exslb.
++ * We assume we aren't going to take any exceptions during this procedure.
++ * We assume (DAR >> 60) == 0xc.
++ */
++	.align	7
++_GLOBAL(do_stab_bolted)
++	stw	r9,PACA_EXSLB+EX_CCR(r13)	/* save CR in exc. frame */
++	std	r11,PACA_EXSLB+EX_SRR0(r13)	/* save SRR0 in exc. frame */
++
++	/* Hash to the primary group */
++	ld	r10,PACASTABVIRT(r13)
++	mfspr	r11,SPRN_DAR
++	srdi	r11,r11,28
++	rldimi	r10,r11,7,52	/* r10 = first ste of the group */
++
++	/* Calculate VSID */
++	/* This is a kernel address, so protovsid = ESID */
++	ASM_VSID_SCRAMBLE(r11, r9)
++	rldic	r9,r11,12,16	/* r9 = vsid << 12 */
++
++	/* Search the primary group for a free entry */
++1:	ld	r11,0(r10)	/* Test valid bit of the current ste	*/
++	andi.	r11,r11,0x80
++	beq	2f
++	addi	r10,r10,16
++	andi.	r11,r10,0x70
++	bne	1b
++
++	/* Stick for only searching the primary group for now.		*/
++	/* At least for now, we use a very simple random castout scheme */
++	/* Use the TB as a random number ;  OR in 1 to avoid entry 0	*/
++	mftb	r11
++	rldic	r11,r11,4,57	/* r11 = (r11 << 4) & 0x70 */
++	ori	r11,r11,0x10
++
++	/* r10 currently points to an ste one past the group of interest */
++	/* make it point to the randomly selected entry			*/
++	subi	r10,r10,128
++	or 	r10,r10,r11	/* r10 is the entry to invalidate	*/
++
++	isync			/* mark the entry invalid		*/
++	ld	r11,0(r10)
++	rldicl	r11,r11,56,1	/* clear the valid bit */
++	rotldi	r11,r11,8
++	std	r11,0(r10)
++	sync
++
++	clrrdi	r11,r11,28	/* Get the esid part of the ste		*/
++	slbie	r11
++
++2:	std	r9,8(r10)	/* Store the vsid part of the ste	*/
++	eieio
++
++	mfspr	r11,SPRN_DAR		/* Get the new esid			*/
++	clrrdi	r11,r11,28	/* Permits a full 32b of ESID		*/
++	ori	r11,r11,0x90	/* Turn on valid and kp			*/
++	std	r11,0(r10)	/* Put new entry back into the stab	*/
++
++	sync
++
++	/* All done -- return from exception. */
++	lwz	r9,PACA_EXSLB+EX_CCR(r13)	/* get saved CR */
++	ld	r11,PACA_EXSLB+EX_SRR0(r13)	/* get saved SRR0 */
++
++	andi.	r10,r12,MSR_RI
++	beq-	unrecov_slb
++
++	mtcrf	0x80,r9			/* restore CR */
++
++	mfmsr	r10
++	clrrdi	r10,r10,2
++	mtmsrd	r10,1
++
++	mtspr	SPRN_SRR0,r11
++	mtspr	SPRN_SRR1,r12
++	ld	r9,PACA_EXSLB+EX_R9(r13)
++	ld	r10,PACA_EXSLB+EX_R10(r13)
++	ld	r11,PACA_EXSLB+EX_R11(r13)
++	ld	r12,PACA_EXSLB+EX_R12(r13)
++	ld	r13,PACA_EXSLB+EX_R13(r13)
++	rfid
++	b	.	/* prevent speculative execution */
++
++/*
++ * r13 points to the PACA, r9 contains the saved CR,
++ * r11 and r12 contain the saved SRR0 and SRR1.
++ * r3 has the faulting address
++ * r9 - r13 are saved in paca->exslb.
++ * r3 is saved in paca->slb_r3
++ * We assume we aren't going to take any exceptions during this procedure.
++ */
++_GLOBAL(do_slb_miss)
++	mflr	r10
++
++	stw	r9,PACA_EXSLB+EX_CCR(r13)	/* save CR in exc. frame */
++	std	r10,PACA_EXSLB+EX_LR(r13)	/* save LR */
++
++	bl	.slb_allocate			/* handle it */
++
++	/* All done -- return from exception. */
++
++	ld	r10,PACA_EXSLB+EX_LR(r13)
++	ld	r3,PACA_EXSLB+EX_R3(r13)
++	lwz	r9,PACA_EXSLB+EX_CCR(r13)	/* get saved CR */
++#ifdef CONFIG_PPC_ISERIES
++	ld	r11,PACALPPACA+LPPACASRR0(r13)	/* get SRR0 value */
++#endif /* CONFIG_PPC_ISERIES */
++
++	mtlr	r10
++
++	andi.	r10,r12,MSR_RI	/* check for unrecoverable exception */
++	beq-	unrecov_slb
++
++.machine	push
++.machine	"power4"
++	mtcrf	0x80,r9
++	mtcrf	0x01,r9		/* slb_allocate uses cr0 and cr7 */
++.machine	pop
++
++#ifdef CONFIG_PPC_ISERIES
++	mtspr	SPRN_SRR0,r11
++	mtspr	SPRN_SRR1,r12
++#endif /* CONFIG_PPC_ISERIES */
++	ld	r9,PACA_EXSLB+EX_R9(r13)
++	ld	r10,PACA_EXSLB+EX_R10(r13)
++	ld	r11,PACA_EXSLB+EX_R11(r13)
++	ld	r12,PACA_EXSLB+EX_R12(r13)
++	ld	r13,PACA_EXSLB+EX_R13(r13)
++	rfid
++	b	.	/* prevent speculative execution */
++
++unrecov_slb:
++	EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
++	DISABLE_INTS
++	bl	.save_nvgprs
++1:	addi	r3,r1,STACK_FRAME_OVERHEAD
++	bl	.unrecoverable_exception
++	b	1b
++
++/*
++ * Space for CPU0's segment table.
++ *
++ * On iSeries, the hypervisor must fill in at least one entry before
++ * we get control (with relocate on).  The address is give to the hv
++ * as a page number (see xLparMap in lpardata.c), so this must be at a
++ * fixed address (the linker can't compute (u64)&initial_stab >>
++ * PAGE_SHIFT).
++ */
++	. = STAB0_PHYS_ADDR	/* 0x6000 */
++	.globl initial_stab
++initial_stab:
++	.space	4096
++
++/*
++ * Data area reserved for FWNMI option.
++ * This address (0x7000) is fixed by the RPA.
++ */
++	.= 0x7000
++	.globl fwnmi_data_area
++fwnmi_data_area:
++
++	/* iSeries does not use the FWNMI stuff, so it is safe to put
++	 * this here, even if we later allow kernels that will boot on
++	 * both pSeries and iSeries */
++#ifdef CONFIG_PPC_ISERIES
++        . = LPARMAP_PHYS
++#include "lparmap.s"
++/*
++ * This ".text" is here for old compilers that generate a trailing
++ * .note section when compiling .c files to .s
++ */
++	.text
++#endif /* CONFIG_PPC_ISERIES */
++
++        . = 0x8000
++
++/*
++ * On pSeries, secondary processors spin in the following code.
++ * At entry, r3 = this processor's number (physical cpu id)
++ */
++_GLOBAL(pSeries_secondary_smp_init)
++	mr	r24,r3
++	
++	/* turn on 64-bit mode */
++	bl	.enable_64b_mode
++	isync
++
++	/* Copy some CPU settings from CPU 0 */
++	bl	.__restore_cpu_setup
++
++	/* Set up a paca value for this processor. Since we have the
++	 * physical cpu id in r24, we need to search the pacas to find
++	 * which logical id maps to our physical one.
++	 */
++	LOADADDR(r13, paca) 		/* Get base vaddr of paca array	 */
++	li	r5,0			/* logical cpu id                */
++1:	lhz	r6,PACAHWCPUID(r13)	/* Load HW procid from paca      */
++	cmpw	r6,r24			/* Compare to our id             */
++	beq	2f
++	addi	r13,r13,PACA_SIZE	/* Loop to next PACA on miss     */
++	addi	r5,r5,1
++	cmpwi	r5,NR_CPUS
++	blt	1b
++
++	mr	r3,r24			/* not found, copy phys to r3	 */
++	b	.kexec_wait		/* next kernel might do better	 */
++
++2:	mtspr	SPRN_SPRG3,r13		/* Save vaddr of paca in SPRG3	 */
++	/* From now on, r24 is expected to be logical cpuid */
++	mr	r24,r5
++3:	HMT_LOW
++	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
++					/* start.			 */
++	sync
++
++	/* Create a temp kernel stack for use before relocation is on.	*/
++	ld	r1,PACAEMERGSP(r13)
++	subi	r1,r1,STACK_FRAME_OVERHEAD
++
++	cmpwi	0,r23,0
++#ifdef CONFIG_SMP
++	bne	.__secondary_start
++#endif
++	b 	3b			/* Loop until told to go	 */
++
++#ifdef CONFIG_PPC_ISERIES
++_STATIC(__start_initialization_iSeries)
++	/* Clear out the BSS */
++	LOADADDR(r11,__bss_stop)
++	LOADADDR(r8,__bss_start)
++	sub	r11,r11,r8		/* bss size			*/
++	addi	r11,r11,7		/* round up to an even double word */
++	rldicl. r11,r11,61,3		/* shift right by 3		*/
++	beq	4f
++	addi	r8,r8,-8
++	li	r0,0
++	mtctr	r11			/* zero this many doublewords	*/
++3:	stdu	r0,8(r8)
++	bdnz	3b
++4:
++	LOADADDR(r1,init_thread_union)
++	addi	r1,r1,THREAD_SIZE
++	li	r0,0
++	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
++
++	LOADADDR(r3,cpu_specs)
++	LOADADDR(r4,cur_cpu_spec)
++	li	r5,0
++	bl	.identify_cpu
++
++	LOADADDR(r2,__toc_start)
++	addi	r2,r2,0x4000
++	addi	r2,r2,0x4000
++
++	bl	.iSeries_early_setup
++	bl	.early_setup
++
++	/* relocation is on at this point */
++
++	b	.start_here_common
++#endif /* CONFIG_PPC_ISERIES */
++
++#ifdef CONFIG_PPC_MULTIPLATFORM
++
++_STATIC(__mmu_off)
++	mfmsr	r3
++	andi.	r0,r3,MSR_IR|MSR_DR
++	beqlr
++	andc	r3,r3,r0
++	mtspr	SPRN_SRR0,r4
++	mtspr	SPRN_SRR1,r3
++	sync
++	rfid
++	b	.	/* prevent speculative execution */
++
++
++/*
++ * Here is our main kernel entry point. We support currently 2 kind of entries
++ * depending on the value of r5.
++ *
++ *   r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content
++ *                 in r3...r7
++ *   
++ *   r5 == NULL -> kexec style entry. r3 is a physical pointer to the
++ *                 DT block, r4 is a physical pointer to the kernel itself
++ *
++ */
++_GLOBAL(__start_initialization_multiplatform)
++	/*
++	 * Are we booted from a PROM Of-type client-interface ?
++	 */
++	cmpldi	cr0,r5,0
++	bne	.__boot_from_prom		/* yes -> prom */
++
++	/* Save parameters */
++	mr	r31,r3
++	mr	r30,r4
++
++	/* Make sure we are running in 64 bits mode */
++	bl	.enable_64b_mode
++
++	/* Setup some critical 970 SPRs before switching MMU off */
++	bl	.__970_cpu_preinit
++
++	/* cpu # */
++	li	r24,0
++
++	/* Switch off MMU if not already */
++	LOADADDR(r4, .__after_prom_start - KERNELBASE)
++	add	r4,r4,r30
++	bl	.__mmu_off
++	b	.__after_prom_start
++
++_STATIC(__boot_from_prom)
++	/* Save parameters */
++	mr	r31,r3
++	mr	r30,r4
++	mr	r29,r5
++	mr	r28,r6
++	mr	r27,r7
++
++	/* Make sure we are running in 64 bits mode */
++	bl	.enable_64b_mode
++
++	/* put a relocation offset into r3 */
++	bl	.reloc_offset
++
++	LOADADDR(r2,__toc_start)
++	addi	r2,r2,0x4000
++	addi	r2,r2,0x4000
++
++	/* Relocate the TOC from a virt addr to a real addr */
++	add	r2,r2,r3
++
++	/* Restore parameters */
++	mr	r3,r31
++	mr	r4,r30
++	mr	r5,r29
++	mr	r6,r28
++	mr	r7,r27
++
++	/* Do all of the interaction with OF client interface */
++	bl	.prom_init
++	/* We never return */
++	trap
++
++/*
++ * At this point, r3 contains the physical address we are running at,
++ * returned by prom_init()
++ */
++_STATIC(__after_prom_start)
++
++/*
++ * We need to run with __start at physical address 0.
++ * This will leave some code in the first 256B of
++ * real memory, which are reserved for software use.
++ * The remainder of the first page is loaded with the fixed
++ * interrupt vectors.  The next two pages are filled with
++ * unknown exception placeholders.
++ *
++ * Note: This process overwrites the OF exception vectors.
++ *	r26 == relocation offset
++ *	r27 == KERNELBASE
++ */
++	bl	.reloc_offset
++	mr	r26,r3
++	SET_REG_TO_CONST(r27,KERNELBASE)
++
++	li	r3,0			/* target addr */
++
++	// XXX FIXME: Use phys returned by OF (r30)
++	add	r4,r27,r26 		/* source addr			 */
++					/* current address of _start	 */
++					/*   i.e. where we are running	 */
++					/*	the source addr		 */
++
++	LOADADDR(r5,copy_to_here)	/* # bytes of memory to copy	 */
++	sub	r5,r5,r27
++
++	li	r6,0x100		/* Start offset, the first 0x100 */
++					/* bytes were copied earlier.	 */
++
++	bl	.copy_and_flush		/* copy the first n bytes	 */
++					/* this includes the code being	 */
++					/* executed here.		 */
++
++	LOADADDR(r0, 4f)		/* Jump to the copy of this code */
++	mtctr	r0			/* that we just made/relocated	 */
++	bctr
++
++4:	LOADADDR(r5,klimit)
++	add	r5,r5,r26
++	ld	r5,0(r5)		/* get the value of klimit */
++	sub	r5,r5,r27
++	bl	.copy_and_flush		/* copy the rest */
++	b	.start_here_multiplatform
++
++#endif /* CONFIG_PPC_MULTIPLATFORM */
++
++/*
++ * Copy routine used to copy the kernel to start at physical address 0
++ * and flush and invalidate the caches as needed.
++ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
++ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
++ *
++ * Note: this routine *only* clobbers r0, r6 and lr
++ */
++_GLOBAL(copy_and_flush)
++	addi	r5,r5,-8
++	addi	r6,r6,-8
++4:	li	r0,16			/* Use the least common		*/
++					/* denominator cache line	*/
++					/* size.  This results in	*/
++					/* extra cache line flushes	*/
++					/* but operation is correct.	*/
++					/* Can't get cache line size	*/
++					/* from NACA as it is being	*/
++					/* moved too.			*/
++
++	mtctr	r0			/* put # words/line in ctr	*/
++3:	addi	r6,r6,8			/* copy a cache line		*/
++	ldx	r0,r6,r4
++	stdx	r0,r6,r3
++	bdnz	3b
++	dcbst	r6,r3			/* write it to memory		*/
++	sync
++	icbi	r6,r3			/* flush the icache line	*/
++	cmpld	0,r6,r5
++	blt	4b
++	sync
++	addi	r5,r5,8
++	addi	r6,r6,8
++	blr
++
++.align 8
++copy_to_here:
++
++#ifdef CONFIG_SMP
++#ifdef CONFIG_PPC_PMAC
++/*
++ * On PowerMac, secondary processors starts from the reset vector, which
++ * is temporarily turned into a call to one of the functions below.
++ */
++	.section ".text";
++	.align 2 ;
++
++	.globl	__secondary_start_pmac_0
++__secondary_start_pmac_0:
++	/* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
++	li	r24,0
++	b	1f
++	li	r24,1
++	b	1f
++	li	r24,2
++	b	1f
++	li	r24,3
++1:
++	
++_GLOBAL(pmac_secondary_start)
++	/* turn on 64-bit mode */
++	bl	.enable_64b_mode
++	isync
++
++	/* Copy some CPU settings from CPU 0 */
++	bl	.__restore_cpu_setup
++
++	/* pSeries do that early though I don't think we really need it */
++	mfmsr	r3
++	ori	r3,r3,MSR_RI
++	mtmsrd	r3			/* RI on */
++
++	/* Set up a paca value for this processor. */
++	LOADADDR(r4, paca) 		 /* Get base vaddr of paca array	*/
++	mulli	r13,r24,PACA_SIZE	 /* Calculate vaddr of right paca */
++	add	r13,r13,r4		/* for this processor.		*/
++	mtspr	SPRN_SPRG3,r13		 /* Save vaddr of paca in SPRG3	*/
++
++	/* Create a temp kernel stack for use before relocation is on.	*/
++	ld	r1,PACAEMERGSP(r13)
++	subi	r1,r1,STACK_FRAME_OVERHEAD
++
++	b	.__secondary_start
++
++#endif /* CONFIG_PPC_PMAC */
++
++/*
++ * This function is called after the master CPU has released the
++ * secondary processors.  The execution environment is relocation off.
++ * The paca for this processor has the following fields initialized at
++ * this point:
++ *   1. Processor number
++ *   2. Segment table pointer (virtual address)
++ * On entry the following are set:
++ *   r1	= stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
++ *   r24   = cpu# (in Linux terms)
++ *   r13   = paca virtual address
++ *   SPRG3 = paca virtual address
++ */
++_GLOBAL(__secondary_start)
++
++	HMT_MEDIUM			/* Set thread priority to MEDIUM */
++
++	ld	r2,PACATOC(r13)
++	li	r6,0
++	stb	r6,PACAPROCENABLED(r13)
++
++#ifndef CONFIG_PPC_ISERIES
++	/* Initialize the page table pointer register. */
++	LOADADDR(r6,_SDR1)
++	ld	r6,0(r6)		/* get the value of _SDR1	 */
++	mtspr	SPRN_SDR1,r6			/* set the htab location	 */
++#endif
++	/* Initialize the first segment table (or SLB) entry		 */
++	ld	r3,PACASTABVIRT(r13)	/* get addr of segment table	 */
++	bl	.stab_initialize
++
++	/* Initialize the kernel stack.  Just a repeat for iSeries.	 */
++	LOADADDR(r3,current_set)
++	sldi	r28,r24,3		/* get current_set[cpu#]	 */
++	ldx	r1,r3,r28
++	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
++	std	r1,PACAKSAVE(r13)
++
++	ld	r3,PACASTABREAL(r13)	/* get raddr of segment table	 */
++	ori	r4,r3,1			/* turn on valid bit		 */
++
++#ifdef CONFIG_PPC_ISERIES
++	li	r0,-1			/* hypervisor call */
++	li	r3,1
++	sldi	r3,r3,63		/* 0x8000000000000000 */
++	ori	r3,r3,4			/* 0x8000000000000004 */
++	sc				/* HvCall_setASR */
++#else
++	/* set the ASR */
++	ld	r3,systemcfg at got(r2)	/* r3 = ptr to systemcfg	 */
++	ld	r3,0(r3)
++	lwz	r3,PLATFORM(r3)		/* r3 = platform flags		 */
++	andi.	r3,r3,PLATFORM_LPAR	/* Test if bit 0 is set (LPAR bit) */
++	beq	98f			/* branch if result is 0  */
++	mfspr	r3,SPRN_PVR
++	srwi	r3,r3,16
++	cmpwi	r3,0x37			/* SStar  */
++	beq	97f
++	cmpwi	r3,0x36			/* IStar  */
++	beq	97f
++	cmpwi	r3,0x34			/* Pulsar */
++	bne	98f
++97:	li	r3,H_SET_ASR		/* hcall = H_SET_ASR */
++	HVSC				/* Invoking hcall */
++	b	99f
++98:					/* !(rpa hypervisor) || !(star)  */
++	mtasr	r4			/* set the stab location	 */
++99:
++#endif
++	li	r7,0
++	mtlr	r7
++
++	/* enable MMU and jump to start_secondary */
++	LOADADDR(r3,.start_secondary_prolog)
++	SET_REG_TO_CONST(r4, MSR_KERNEL)
++#ifdef DO_SOFT_DISABLE
++	ori	r4,r4,MSR_EE
++#endif
++	mtspr	SPRN_SRR0,r3
++	mtspr	SPRN_SRR1,r4
++	rfid
++	b	.	/* prevent speculative execution */
++
++/* 
++ * Running with relocation on at this point.  All we want to do is
++ * zero the stack back-chain pointer before going into C code.
++ */
++_GLOBAL(start_secondary_prolog)
++	li	r3,0
++	std	r3,0(r1)		/* Zero the stack frame pointer	*/
++	bl	.start_secondary
++#endif
++
++/*
++ * This subroutine clobbers r11 and r12
++ */
++_GLOBAL(enable_64b_mode)
++	mfmsr	r11			/* grab the current MSR */
++	li	r12,1
++	rldicr	r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
++	or	r11,r11,r12
++	li	r12,1
++	rldicr	r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
++	or	r11,r11,r12
++	mtmsrd	r11
++	isync
++	blr
++
++#ifdef CONFIG_PPC_MULTIPLATFORM
++/*
++ * This is where the main kernel code starts.
++ */
++_STATIC(start_here_multiplatform)
++	/* get a new offset, now that the kernel has moved. */
++	bl	.reloc_offset
++	mr	r26,r3
++
++	/* Clear out the BSS. It may have been done in prom_init,
++	 * already but that's irrelevant since prom_init will soon
++	 * be detached from the kernel completely. Besides, we need
++	 * to clear it now for kexec-style entry.
++	 */
++	LOADADDR(r11,__bss_stop)
++	LOADADDR(r8,__bss_start)
++	sub	r11,r11,r8		/* bss size			*/
++	addi	r11,r11,7		/* round up to an even double word */
++	rldicl. r11,r11,61,3		/* shift right by 3		*/
++	beq	4f
++	addi	r8,r8,-8
++	li	r0,0
++	mtctr	r11			/* zero this many doublewords	*/
++3:	stdu	r0,8(r8)
++	bdnz	3b
++4:
++
++	mfmsr	r6
++	ori	r6,r6,MSR_RI
++	mtmsrd	r6			/* RI on */
++
++#ifdef CONFIG_HMT
++	/* Start up the second thread on cpu 0 */
++	mfspr	r3,SPRN_PVR
++	srwi	r3,r3,16
++	cmpwi	r3,0x34			/* Pulsar  */
++	beq	90f
++	cmpwi	r3,0x36			/* Icestar */
++	beq	90f
++	cmpwi	r3,0x37			/* SStar   */
++	beq	90f
++	b	91f			/* HMT not supported */
++90:	li	r3,0
++	bl	.hmt_start_secondary
++91:
++#endif
++
++	/* The following gets the stack and TOC set up with the regs */
++	/* pointing to the real addr of the kernel stack.  This is   */
++	/* all done to support the C function call below which sets  */
++	/* up the htab.  This is done because we have relocated the  */
++	/* kernel but are still running in real mode. */
++
++	LOADADDR(r3,init_thread_union)
++	add	r3,r3,r26
++
++	/* set up a stack pointer (physical address) */
++	addi	r1,r3,THREAD_SIZE
++	li	r0,0
++	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
++
++	/* set up the TOC (physical address) */
++	LOADADDR(r2,__toc_start)
++	addi	r2,r2,0x4000
++	addi	r2,r2,0x4000
++	add	r2,r2,r26
++
++	LOADADDR(r3,cpu_specs)
++	add	r3,r3,r26
++	LOADADDR(r4,cur_cpu_spec)
++	add	r4,r4,r26
++	mr	r5,r26
++	bl	.identify_cpu
++
++	/* Save some low level config HIDs of CPU0 to be copied to
++	 * other CPUs later on, or used for suspend/resume
++	 */
++	bl	.__save_cpu_setup
++	sync
++
++	/* Setup a valid physical PACA pointer in SPRG3 for early_setup
++	 * note that boot_cpuid can always be 0 nowadays since there is
++	 * nowhere it can be initialized differently before we reach this
++	 * code
++	 */
++	LOADADDR(r27, boot_cpuid)
++	add	r27,r27,r26
++	lwz	r27,0(r27)
++
++	LOADADDR(r24, paca) 		/* Get base vaddr of paca array	 */
++	mulli	r13,r27,PACA_SIZE	/* Calculate vaddr of right paca */
++	add	r13,r13,r24		/* for this processor.		 */
++	add	r13,r13,r26		/* convert to physical addr	 */
++	mtspr	SPRN_SPRG3,r13		/* PPPBBB: Temp... -Peter */
++	
++	/* Do very early kernel initializations, including initial hash table,
++	 * stab and slb setup before we turn on relocation.	*/
++
++	/* Restore parameters passed from prom_init/kexec */
++	mr	r3,r31
++ 	bl	.early_setup
++
++	/* set the ASR */
++	ld	r3,PACASTABREAL(r13)
++	ori	r4,r3,1			/* turn on valid bit		 */
++	ld	r3,systemcfg at got(r2)	/* r3 = ptr to systemcfg */
++	ld	r3,0(r3)
++	lwz	r3,PLATFORM(r3)		/* r3 = platform flags */
++	andi.	r3,r3,PLATFORM_LPAR	/* Test if bit 0 is set (LPAR bit) */
++	beq	98f			/* branch if result is 0  */
++	mfspr	r3,SPRN_PVR
++	srwi	r3,r3,16
++	cmpwi	r3,0x37			/* SStar */
++	beq	97f
++	cmpwi	r3,0x36			/* IStar  */
++	beq	97f
++	cmpwi	r3,0x34			/* Pulsar */
++	bne	98f
++97:	li	r3,H_SET_ASR		/* hcall = H_SET_ASR */
++	HVSC				/* Invoking hcall */
++	b	99f
++98:					/* !(rpa hypervisor) || !(star) */
++	mtasr	r4			/* set the stab location	*/
++99:
++	/* Set SDR1 (hash table pointer) */
++	ld	r3,systemcfg at got(r2)	/* r3 = ptr to systemcfg */
++	ld	r3,0(r3)
++	lwz	r3,PLATFORM(r3)		/* r3 = platform flags */
++	/* Test if bit 0 is set (LPAR bit) */
++	andi.	r3,r3,PLATFORM_LPAR
++	bne	98f			/* branch if result is !0  */
++	LOADADDR(r6,_SDR1)		/* Only if NOT LPAR */
++	add	r6,r6,r26
++	ld	r6,0(r6)		/* get the value of _SDR1 */
++	mtspr	SPRN_SDR1,r6			/* set the htab location  */
++98: 
++	LOADADDR(r3,.start_here_common)
++	SET_REG_TO_CONST(r4, MSR_KERNEL)
++	mtspr	SPRN_SRR0,r3
++	mtspr	SPRN_SRR1,r4
++	rfid
++	b	.	/* prevent speculative execution */
++#endif /* CONFIG_PPC_MULTIPLATFORM */
++	
++	/* This is where all platforms converge execution */
++_STATIC(start_here_common)
++	/* relocation is on at this point */
++
++	/* The following code sets up the SP and TOC now that we are */
++	/* running with translation enabled. */
++
++	LOADADDR(r3,init_thread_union)
++
++	/* set up the stack */
++	addi	r1,r3,THREAD_SIZE
++	li	r0,0
++	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
++
++	/* Apply the CPUs-specific fixups (nop out sections not relevant
++	 * to this CPU
++	 */
++	li	r3,0
++	bl	.do_cpu_ftr_fixups
++
++	LOADADDR(r26, boot_cpuid)
++	lwz	r26,0(r26)
++
++	LOADADDR(r24, paca) 		/* Get base vaddr of paca array  */
++	mulli	r13,r26,PACA_SIZE	/* Calculate vaddr of right paca */
++	add	r13,r13,r24		/* for this processor.		 */
++	mtspr	SPRN_SPRG3,r13
++
++	/* ptr to current */
++	LOADADDR(r4,init_task)
++	std	r4,PACACURRENT(r13)
++
++	/* Load the TOC */
++	ld	r2,PACATOC(r13)
++	std	r1,PACAKSAVE(r13)
++
++	bl	.setup_system
++
++	/* Load up the kernel context */
++5:
++#ifdef DO_SOFT_DISABLE
++	li	r5,0
++	stb	r5,PACAPROCENABLED(r13)	/* Soft Disabled */
++	mfmsr	r5
++	ori	r5,r5,MSR_EE		/* Hard Enabled */
++	mtmsrd	r5
++#endif
++
++	bl .start_kernel
++
++_GLOBAL(hmt_init)
++#ifdef CONFIG_HMT
++	LOADADDR(r5, hmt_thread_data)
++	mfspr	r7,SPRN_PVR
++	srwi	r7,r7,16
++	cmpwi	r7,0x34			/* Pulsar  */
++	beq	90f
++	cmpwi	r7,0x36			/* Icestar */
++	beq	91f
++	cmpwi	r7,0x37			/* SStar   */
++	beq	91f
++	b	101f
++90:	mfspr	r6,SPRN_PIR
++	andi.	r6,r6,0x1f
++	b	92f
++91:	mfspr	r6,SPRN_PIR
++	andi.	r6,r6,0x3ff
++92:	sldi	r4,r24,3
++	stwx	r6,r5,r4
++	bl	.hmt_start_secondary
++	b	101f
++
++__hmt_secondary_hold:
++	LOADADDR(r5, hmt_thread_data)
++	clrldi	r5,r5,4
++	li	r7,0
++	mfspr	r6,SPRN_PIR
++	mfspr	r8,SPRN_PVR
++	srwi	r8,r8,16
++	cmpwi	r8,0x34
++	bne	93f
++	andi.	r6,r6,0x1f
++	b	103f
++93:	andi.	r6,r6,0x3f
++
++103:	lwzx	r8,r5,r7
++	cmpw	r8,r6
++	beq	104f
++	addi	r7,r7,8
++	b	103b
++
++104:	addi	r7,r7,4
++	lwzx	r9,r5,r7
++	mr	r24,r9
++101:
++#endif
++	mr	r3,r24
++	b	.pSeries_secondary_smp_init
++
++#ifdef CONFIG_HMT
++_GLOBAL(hmt_start_secondary)
++	LOADADDR(r4,__hmt_secondary_hold)
++	clrldi	r4,r4,4
++	mtspr	SPRN_NIADORM, r4
++	mfspr	r4, SPRN_MSRDORM
++	li	r5, -65
++	and	r4, r4, r5
++	mtspr	SPRN_MSRDORM, r4
++	lis	r4,0xffef
++	ori	r4,r4,0x7403
++	mtspr	SPRN_TSC, r4
++	li	r4,0x1f4
++	mtspr	SPRN_TST, r4
++	mfspr	r4, SPRN_HID0
++	ori	r4, r4, 0x1
++	mtspr	SPRN_HID0, r4
++	mfspr	r4, SPRN_CTRLF
++	oris	r4, r4, 0x40
++	mtspr	SPRN_CTRLT, r4
++	blr
++#endif
++
++#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP)
++_GLOBAL(smp_release_cpus)
++	/* All secondary cpus are spinning on a common
++	 * spinloop, release them all now so they can start
++	 * to spin on their individual paca spinloops.
++	 * For non SMP kernels, the secondary cpus never
++	 * get out of the common spinloop.
++	 * XXX This does nothing useful on iSeries, secondaries are
++	 * already waiting on their paca.
++	 */
++	li	r3,1
++	LOADADDR(r5,__secondary_hold_spinloop)
++	std	r3,0(r5)
++	sync
++	blr
++#endif /* CONFIG_SMP */
++
++
++/*
++ * We put a few things here that have to be page-aligned.
++ * This stuff goes at the beginning of the bss, which is page-aligned.
++ */
++	.section ".bss"
++
++	.align	PAGE_SHIFT
++
++	.globl	empty_zero_page
++empty_zero_page:
++	.space	PAGE_SIZE
++
++	.globl	swapper_pg_dir
++swapper_pg_dir:
++	.space	PAGE_SIZE
++
++/*
++ * This space gets a copy of optional info passed to us by the bootstrap
++ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
++ */
++	.globl	cmd_line
++cmd_line:
++	.space	COMMAND_LINE_SIZE
+diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/head_8xx.S
+@@ -0,0 +1,860 @@
++/*
++ *  arch/ppc/kernel/except_8xx.S
++ *
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *  Rewritten by Cort Dougan (cort at cs.nmt.edu) for PReP
++ *    Copyright (C) 1996 Cort Dougan <cort at cs.nmt.edu>
++ *  Low-level exception handlers and MMU support
++ *  rewritten by Paul Mackerras.
++ *    Copyright (C) 1996 Paul Mackerras.
++ *  MPC8xx modifications by Dan Malek
++ *    Copyright (C) 1997 Dan Malek (dmalek at jlc.net).
++ *
++ *  This file contains low-level support and setup for PowerPC 8xx
++ *  embedded processors, including trap and interrupt dispatch.
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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 <asm/processor.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/cache.h>
++#include <asm/pgtable.h>
++#include <asm/cputable.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++
++/* Macro to make the code more readable. */
++#ifdef CONFIG_8xx_CPU6
++#define DO_8xx_CPU6(val, reg)	\
++	li	reg, val;	\
++	stw	reg, 12(r0);	\
++	lwz	reg, 12(r0);
++#else
++#define DO_8xx_CPU6(val, reg)
++#endif
++	.text
++	.globl	_stext
++_stext:
++	.text
++	.globl	_start
++_start:
++
++/* MPC8xx
++ * This port was done on an MBX board with an 860.  Right now I only
++ * support an ELF compressed (zImage) boot from EPPC-Bug because the
++ * code there loads up some registers before calling us:
++ *   r3: ptr to board info data
++ *   r4: initrd_start or if no initrd then 0
++ *   r5: initrd_end - unused if r4 is 0
++ *   r6: Start of command line string
++ *   r7: End of command line string
++ *
++ * I decided to use conditional compilation instead of checking PVR and
++ * adding more processor specific branches around code I don't need.
++ * Since this is an embedded processor, I also appreciate any memory
++ * savings I can get.
++ *
++ * The MPC8xx does not have any BATs, but it supports large page sizes.
++ * We first initialize the MMU to support 8M byte pages, then load one
++ * entry into each of the instruction and data TLBs to map the first
++ * 8M 1:1.  I also mapped an additional I/O space 1:1 so we can get to
++ * the "internal" processor registers before MMU_init is called.
++ *
++ * The TLB code currently contains a major hack.  Since I use the condition
++ * code register, I have to save and restore it.  I am out of registers, so
++ * I just store it in memory location 0 (the TLB handlers are not reentrant).
++ * To avoid making any decisions, I need to use the "segment" valid bit
++ * in the first level table, but that would require many changes to the
++ * Linux page directory/table functions that I don't want to do right now.
++ *
++ * I used to use SPRG2 for a temporary register in the TLB handler, but it
++ * has since been put to other uses.  I now use a hack to save a register
++ * and the CCR at memory location 0.....Someday I'll fix this.....
++ *	-- Dan
++ */
++	.globl	__start
++__start:
++	mr	r31,r3			/* save parameters */
++	mr	r30,r4
++	mr	r29,r5
++	mr	r28,r6
++	mr	r27,r7
++
++	/* We have to turn on the MMU right away so we get cache modes
++	 * set correctly.
++	 */
++	bl	initial_mmu
++
++/* We now have the lower 8 Meg mapped into TLB entries, and the caches
++ * ready to work.
++ */
++
++turn_on_mmu:
++	mfmsr	r0
++	ori	r0,r0,MSR_DR|MSR_IR
++	mtspr	SPRN_SRR1,r0
++	lis	r0,start_here at h
++	ori	r0,r0,start_here at l
++	mtspr	SPRN_SRR0,r0
++	SYNC
++	rfi				/* enables MMU */
++
++/*
++ * Exception entry code.  This code runs with address translation
++ * turned off, i.e. using physical addresses.
++ * We assume sprg3 has the physical address of the current
++ * task's thread_struct.
++ */
++#define EXCEPTION_PROLOG	\
++	mtspr	SPRN_SPRG0,r10;	\
++	mtspr	SPRN_SPRG1,r11;	\
++	mfcr	r10;		\
++	EXCEPTION_PROLOG_1;	\
++	EXCEPTION_PROLOG_2
++
++#define EXCEPTION_PROLOG_1	\
++	mfspr	r11,SPRN_SRR1;		/* check whether user or kernel */ \
++	andi.	r11,r11,MSR_PR;	\
++	tophys(r11,r1);			/* use tophys(r1) if kernel */ \
++	beq	1f;		\
++	mfspr	r11,SPRN_SPRG3;	\
++	lwz	r11,THREAD_INFO-THREAD(r11);	\
++	addi	r11,r11,THREAD_SIZE;	\
++	tophys(r11,r11);	\
++1:	subi	r11,r11,INT_FRAME_SIZE	/* alloc exc. frame */
++
++
++#define EXCEPTION_PROLOG_2	\
++	CLR_TOP32(r11);		\
++	stw	r10,_CCR(r11);		/* save registers */ \
++	stw	r12,GPR12(r11);	\
++	stw	r9,GPR9(r11);	\
++	mfspr	r10,SPRN_SPRG0;	\
++	stw	r10,GPR10(r11);	\
++	mfspr	r12,SPRN_SPRG1;	\
++	stw	r12,GPR11(r11);	\
++	mflr	r10;		\
++	stw	r10,_LINK(r11);	\
++	mfspr	r12,SPRN_SRR0;	\
++	mfspr	r9,SPRN_SRR1;	\
++	stw	r1,GPR1(r11);	\
++	stw	r1,0(r11);	\
++	tovirt(r1,r11);			/* set new kernel sp */	\
++	li	r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
++	MTMSRD(r10);			/* (except for mach check in rtas) */ \
++	stw	r0,GPR0(r11);	\
++	SAVE_4GPRS(3, r11);	\
++	SAVE_2GPRS(7, r11)
++
++/*
++ * Note: code which follows this uses cr0.eq (set if from kernel),
++ * r11, r12 (SRR0), and r9 (SRR1).
++ *
++ * Note2: once we have set r1 we are in a position to take exceptions
++ * again, and we could thus set MSR:RI at that point.
++ */
++
++/*
++ * Exception vectors.
++ */
++#define EXCEPTION(n, label, hdlr, xfer)		\
++	. = n;					\
++label:						\
++	EXCEPTION_PROLOG;			\
++	addi	r3,r1,STACK_FRAME_OVERHEAD;	\
++	xfer(n, hdlr)
++
++#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret)	\
++	li	r10,trap;					\
++	stw	r10,_TRAP(r11);					\
++	li	r10,MSR_KERNEL;					\
++	copyee(r10, r9);					\
++	bl	tfer;						\
++i##n:								\
++	.long	hdlr;						\
++	.long	ret
++
++#define COPY_EE(d, s)		rlwimi d,s,0,16,16
++#define NOCOPY(d, s)
++
++#define EXC_XFER_STD(n, hdlr)		\
++	EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full,	\
++			  ret_from_except_full)
++
++#define EXC_XFER_LITE(n, hdlr)		\
++	EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
++			  ret_from_except)
++
++#define EXC_XFER_EE(n, hdlr)		\
++	EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
++			  ret_from_except_full)
++
++#define EXC_XFER_EE_LITE(n, hdlr)	\
++	EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
++			  ret_from_except)
++
++/* System reset */
++	EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
++
++/* Machine check */
++	. = 0x200
++MachineCheck:
++	EXCEPTION_PROLOG
++	mfspr r4,SPRN_DAR
++	stw r4,_DAR(r11)
++	mfspr r5,SPRN_DSISR
++	stw r5,_DSISR(r11)
++	addi r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_STD(0x200, machine_check_exception)
++
++/* Data access exception.
++ * This is "never generated" by the MPC8xx.  We jump to it for other
++ * translation errors.
++ */
++	. = 0x300
++DataAccess:
++	EXCEPTION_PROLOG
++	mfspr	r10,SPRN_DSISR
++	stw	r10,_DSISR(r11)
++	mr	r5,r10
++	mfspr	r4,SPRN_DAR
++	EXC_XFER_EE_LITE(0x300, handle_page_fault)
++
++/* Instruction access exception.
++ * This is "never generated" by the MPC8xx.  We jump to it for other
++ * translation errors.
++ */
++	. = 0x400
++InstructionAccess:
++	EXCEPTION_PROLOG
++	mr	r4,r12
++	mr	r5,r9
++	EXC_XFER_EE_LITE(0x400, handle_page_fault)
++
++/* External interrupt */
++	EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
++
++/* Alignment exception */
++	. = 0x600
++Alignment:
++	EXCEPTION_PROLOG
++	mfspr	r4,SPRN_DAR
++	stw	r4,_DAR(r11)
++	mfspr	r5,SPRN_DSISR
++	stw	r5,_DSISR(r11)
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_EE(0x600, alignment_exception)
++
++/* Program check exception */
++	EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
++
++/* No FPU on MPC8xx.  This exception is not supposed to happen.
++*/
++	EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
++
++/* Decrementer */
++	EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
++
++	EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
++
++/* System call */
++	. = 0xc00
++SystemCall:
++	EXCEPTION_PROLOG
++	EXC_XFER_EE_LITE(0xc00, DoSyscall)
++
++/* Single step - not used on 601 */
++	EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
++	EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE)
++
++/* On the MPC8xx, this is a software emulation interrupt.  It occurs
++ * for all unimplemented and illegal instructions.
++ */
++	EXCEPTION(0x1000, SoftEmu, SoftwareEmulation, EXC_XFER_STD)
++
++	. = 0x1100
++/*
++ * For the MPC8xx, this is a software tablewalk to load the instruction
++ * TLB.  It is modelled after the example in the Motorola manual.  The task
++ * switch loads the M_TWB register with the pointer to the first level table.
++ * If we discover there is no second level table (value is zero) or if there
++ * is an invalid pte, we load that into the TLB, which causes another fault
++ * into the TLB Error interrupt where we can handle such problems.
++ * We have to use the MD_xxx registers for the tablewalk because the
++ * equivalent MI_xxx registers only perform the attribute functions.
++ */
++InstructionTLBMiss:
++#ifdef CONFIG_8xx_CPU6
++	stw	r3, 8(r0)
++#endif
++	DO_8xx_CPU6(0x3f80, r3)
++	mtspr	SPRN_M_TW, r10	/* Save a couple of working registers */
++	mfcr	r10
++	stw	r10, 0(r0)
++	stw	r11, 4(r0)
++	mfspr	r10, SPRN_SRR0	/* Get effective address of fault */
++	DO_8xx_CPU6(0x3780, r3)
++	mtspr	SPRN_MD_EPN, r10	/* Have to use MD_EPN for walk, MI_EPN can't */
++	mfspr	r10, SPRN_M_TWB	/* Get level 1 table entry address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	andi.	r11, r10, 0x0800	/* Address >= 0x80000000 */
++	beq	3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++	rlwimi	r10, r11, 0, 2, 19
++3:
++	lwz	r11, 0(r10)	/* Get the level 1 entry */
++	rlwinm.	r10, r11,0,0,19	/* Extract page descriptor page address */
++	beq	2f		/* If zero, don't try to find a pte */
++
++	/* We have a pte table, so load the MI_TWC with the attributes
++	 * for this "segment."
++	 */
++	ori	r11,r11,1		/* Set valid bit */
++	DO_8xx_CPU6(0x2b80, r3)
++	mtspr	SPRN_MI_TWC, r11	/* Set segment attributes */
++	DO_8xx_CPU6(0x3b80, r3)
++	mtspr	SPRN_MD_TWC, r11	/* Load pte table base address */
++	mfspr	r11, SPRN_MD_TWC	/* ....and get the pte address */
++	lwz	r10, 0(r11)	/* Get the pte */
++
++	ori	r10, r10, _PAGE_ACCESSED
++	stw	r10, 0(r11)
++
++	/* The Linux PTE won't go exactly into the MMU TLB.
++	 * Software indicator bits 21, 22 and 28 must be clear.
++	 * Software indicator bits 24, 25, 26, and 27 must be
++	 * set.  All other Linux PTE bits control the behavior
++	 * of the MMU.
++	 */
++2:	li	r11, 0x00f0
++	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
++	DO_8xx_CPU6(0x2d80, r3)
++	mtspr	SPRN_MI_RPN, r10	/* Update TLB entry */
++
++	mfspr	r10, SPRN_M_TW	/* Restore registers */
++	lwz	r11, 0(r0)
++	mtcr	r11
++	lwz	r11, 4(r0)
++#ifdef CONFIG_8xx_CPU6
++	lwz	r3, 8(r0)
++#endif
++	rfi
++
++	. = 0x1200
++DataStoreTLBMiss:
++#ifdef CONFIG_8xx_CPU6
++	stw	r3, 8(r0)
++#endif
++	DO_8xx_CPU6(0x3f80, r3)
++	mtspr	SPRN_M_TW, r10	/* Save a couple of working registers */
++	mfcr	r10
++	stw	r10, 0(r0)
++	stw	r11, 4(r0)
++	mfspr	r10, SPRN_M_TWB	/* Get level 1 table entry address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	andi.	r11, r10, 0x0800
++	beq	3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++	rlwimi	r10, r11, 0, 2, 19
++3:
++	lwz	r11, 0(r10)	/* Get the level 1 entry */
++	rlwinm.	r10, r11,0,0,19	/* Extract page descriptor page address */
++	beq	2f		/* If zero, don't try to find a pte */
++
++	/* We have a pte table, so load fetch the pte from the table.
++	 */
++	ori	r11, r11, 1	/* Set valid bit in physical L2 page */
++	DO_8xx_CPU6(0x3b80, r3)
++	mtspr	SPRN_MD_TWC, r11	/* Load pte table base address */
++	mfspr	r10, SPRN_MD_TWC	/* ....and get the pte address */
++	lwz	r10, 0(r10)	/* Get the pte */
++
++	/* Insert the Guarded flag into the TWC from the Linux PTE.
++	 * It is bit 27 of both the Linux PTE and the TWC (at least
++	 * I got that right :-).  It will be better when we can put
++	 * this into the Linux pgd/pmd and load it in the operation
++	 * above.
++	 */
++	rlwimi	r11, r10, 0, 27, 27
++	DO_8xx_CPU6(0x3b80, r3)
++	mtspr	SPRN_MD_TWC, r11
++
++	mfspr	r11, SPRN_MD_TWC	/* get the pte address again */
++	ori	r10, r10, _PAGE_ACCESSED
++	stw	r10, 0(r11)
++
++	/* The Linux PTE won't go exactly into the MMU TLB.
++	 * Software indicator bits 21, 22 and 28 must be clear.
++	 * Software indicator bits 24, 25, 26, and 27 must be
++	 * set.  All other Linux PTE bits control the behavior
++	 * of the MMU.
++	 */
++2:	li	r11, 0x00f0
++	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
++	DO_8xx_CPU6(0x3d80, r3)
++	mtspr	SPRN_MD_RPN, r10	/* Update TLB entry */
++
++	mfspr	r10, SPRN_M_TW	/* Restore registers */
++	lwz	r11, 0(r0)
++	mtcr	r11
++	lwz	r11, 4(r0)
++#ifdef CONFIG_8xx_CPU6
++	lwz	r3, 8(r0)
++#endif
++	rfi
++
++/* This is an instruction TLB error on the MPC8xx.  This could be due
++ * to many reasons, such as executing guarded memory or illegal instruction
++ * addresses.  There is nothing to do but handle a big time error fault.
++ */
++	. = 0x1300
++InstructionTLBError:
++	b	InstructionAccess
++
++/* This is the data TLB error on the MPC8xx.  This could be due to
++ * many reasons, including a dirty update to a pte.  We can catch that
++ * one here, but anything else is an error.  First, we track down the
++ * Linux pte.  If it is valid, write access is allowed, but the
++ * page dirty bit is not set, we will set it and reload the TLB.  For
++ * any other case, we bail out to a higher level function that can
++ * handle it.
++ */
++	. = 0x1400
++DataTLBError:
++#ifdef CONFIG_8xx_CPU6
++	stw	r3, 8(r0)
++#endif
++	DO_8xx_CPU6(0x3f80, r3)
++	mtspr	SPRN_M_TW, r10	/* Save a couple of working registers */
++	mfcr	r10
++	stw	r10, 0(r0)
++	stw	r11, 4(r0)
++
++	/* First, make sure this was a store operation.
++	*/
++	mfspr	r10, SPRN_DSISR
++	andis.	r11, r10, 0x0200	/* If set, indicates store op */
++	beq	2f
++
++	/* The EA of a data TLB miss is automatically stored in the MD_EPN
++	 * register.  The EA of a data TLB error is automatically stored in
++	 * the DAR, but not the MD_EPN register.  We must copy the 20 most
++	 * significant bits of the EA from the DAR to MD_EPN before we
++	 * start walking the page tables.  We also need to copy the CASID
++	 * value from the M_CASID register.
++	 * Addendum:  The EA of a data TLB error is _supposed_ to be stored
++	 * in DAR, but it seems that this doesn't happen in some cases, such
++	 * as when the error is due to a dcbi instruction to a page with a
++	 * TLB that doesn't have the changed bit set.  In such cases, there
++	 * does not appear to be any way  to recover the EA of the error
++	 * since it is neither in DAR nor MD_EPN.  As a workaround, the
++	 * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs
++	 * are initialized in mapin_ram().  This will avoid the problem,
++	 * assuming we only use the dcbi instruction on kernel addresses.
++	 */
++	mfspr	r10, SPRN_DAR
++	rlwinm	r11, r10, 0, 0, 19
++	ori	r11, r11, MD_EVALID
++	mfspr	r10, SPRN_M_CASID
++	rlwimi	r11, r10, 0, 28, 31
++	DO_8xx_CPU6(0x3780, r3)
++	mtspr	SPRN_MD_EPN, r11
++
++	mfspr	r10, SPRN_M_TWB	/* Get level 1 table entry address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	andi.	r11, r10, 0x0800
++	beq	3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++	rlwimi	r10, r11, 0, 2, 19
++3:
++	lwz	r11, 0(r10)	/* Get the level 1 entry */
++	rlwinm.	r10, r11,0,0,19	/* Extract page descriptor page address */
++	beq	2f		/* If zero, bail */
++
++	/* We have a pte table, so fetch the pte from the table.
++	 */
++	ori	r11, r11, 1		/* Set valid bit in physical L2 page */
++	DO_8xx_CPU6(0x3b80, r3)
++	mtspr	SPRN_MD_TWC, r11		/* Load pte table base address */
++	mfspr	r11, SPRN_MD_TWC		/* ....and get the pte address */
++	lwz	r10, 0(r11)		/* Get the pte */
++
++	andi.	r11, r10, _PAGE_RW	/* Is it writeable? */
++	beq	2f			/* Bail out if not */
++
++	/* Update 'changed', among others.
++	*/
++	ori	r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
++	mfspr	r11, SPRN_MD_TWC		/* Get pte address again */
++	stw	r10, 0(r11)		/* and update pte in table */
++
++	/* The Linux PTE won't go exactly into the MMU TLB.
++	 * Software indicator bits 21, 22 and 28 must be clear.
++	 * Software indicator bits 24, 25, 26, and 27 must be
++	 * set.  All other Linux PTE bits control the behavior
++	 * of the MMU.
++	 */
++	li	r11, 0x00f0
++	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
++	DO_8xx_CPU6(0x3d80, r3)
++	mtspr	SPRN_MD_RPN, r10	/* Update TLB entry */
++
++	mfspr	r10, SPRN_M_TW	/* Restore registers */
++	lwz	r11, 0(r0)
++	mtcr	r11
++	lwz	r11, 4(r0)
++#ifdef CONFIG_8xx_CPU6
++	lwz	r3, 8(r0)
++#endif
++	rfi
++2:
++	mfspr	r10, SPRN_M_TW	/* Restore registers */
++	lwz	r11, 0(r0)
++	mtcr	r11
++	lwz	r11, 4(r0)
++#ifdef CONFIG_8xx_CPU6
++	lwz	r3, 8(r0)
++#endif
++	b	DataAccess
++
++	EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
++
++/* On the MPC8xx, these next four traps are used for development
++ * support of breakpoints and such.  Someday I will get around to
++ * using them.
++ */
++	EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
++
++	. = 0x2000
++
++	.globl	giveup_fpu
++giveup_fpu:
++	blr
++
++/*
++ * This is where the main kernel code starts.
++ */
++start_here:
++	/* ptr to current */
++	lis	r2,init_task at h
++	ori	r2,r2,init_task at l
++
++	/* ptr to phys current thread */
++	tophys(r4,r2)
++	addi	r4,r4,THREAD	/* init task's THREAD */
++	mtspr	SPRN_SPRG3,r4
++	li	r3,0
++	mtspr	SPRN_SPRG2,r3	/* 0 => r1 has kernel sp */
++
++	/* stack */
++	lis	r1,init_thread_union at ha
++	addi	r1,r1,init_thread_union at l
++	li	r0,0
++	stwu	r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
++
++	bl	early_init	/* We have to do this with MMU on */
++
++/*
++ * Decide what sort of machine this is and initialize the MMU.
++ */
++	mr	r3,r31
++	mr	r4,r30
++	mr	r5,r29
++	mr	r6,r28
++	mr	r7,r27
++	bl	machine_init
++	bl	MMU_init
++
++/*
++ * Go back to running unmapped so we can load up new values
++ * and change to using our exception vectors.
++ * On the 8xx, all we have to do is invalidate the TLB to clear
++ * the old 8M byte TLB mappings and load the page table base register.
++ */
++	/* The right way to do this would be to track it down through
++	 * init's THREAD like the context switch code does, but this is
++	 * easier......until someone changes init's static structures.
++	 */
++	lis	r6, swapper_pg_dir at h
++	ori	r6, r6, swapper_pg_dir at l
++	tophys(r6,r6)
++#ifdef CONFIG_8xx_CPU6
++	lis	r4, cpu6_errata_word at h
++	ori	r4, r4, cpu6_errata_word at l
++	li	r3, 0x3980
++	stw	r3, 12(r4)
++	lwz	r3, 12(r4)
++#endif
++	mtspr	SPRN_M_TWB, r6
++	lis	r4,2f at h
++	ori	r4,r4,2f at l
++	tophys(r4,r4)
++	li	r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
++	mtspr	SPRN_SRR0,r4
++	mtspr	SPRN_SRR1,r3
++	rfi
++/* Load up the kernel context */
++2:
++	SYNC			/* Force all PTE updates to finish */
++	tlbia			/* Clear all TLB entries */
++	sync			/* wait for tlbia/tlbie to finish */
++	TLBSYNC			/* ... on all CPUs */
++
++	/* set up the PTE pointers for the Abatron bdiGDB.
++	*/
++	tovirt(r6,r6)
++	lis	r5, abatron_pteptrs at h
++	ori	r5, r5, abatron_pteptrs at l
++	stw	r5, 0xf0(r0)	/* Must match your Abatron config file */
++	tophys(r5,r5)
++	stw	r6, 0(r5)
++
++/* Now turn on the MMU for real! */
++	li	r4,MSR_KERNEL
++	lis	r3,start_kernel at h
++	ori	r3,r3,start_kernel at l
++	mtspr	SPRN_SRR0,r3
++	mtspr	SPRN_SRR1,r4
++	rfi			/* enable MMU and jump to start_kernel */
++
++/* Set up the initial MMU state so we can do the first level of
++ * kernel initialization.  This maps the first 8 MBytes of memory 1:1
++ * virtual to physical.  Also, set the cache mode since that is defined
++ * by TLB entries and perform any additional mapping (like of the IMMR).
++ * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
++ * 24 Mbytes of data, and the 8M IMMR space.  Anything not covered by
++ * these mappings is mapped by page tables.
++ */
++initial_mmu:
++	tlbia			/* Invalidate all TLB entries */
++#ifdef CONFIG_PIN_TLB
++	lis	r8, MI_RSV4I at h
++	ori	r8, r8, 0x1c00
++#else
++	li	r8, 0
++#endif
++	mtspr	SPRN_MI_CTR, r8	/* Set instruction MMU control */
++
++#ifdef CONFIG_PIN_TLB
++	lis	r10, (MD_RSV4I | MD_RESETVAL)@h
++	ori	r10, r10, 0x1c00
++	mr	r8, r10
++#else
++	lis	r10, MD_RESETVAL at h
++#endif
++#ifndef CONFIG_8xx_COPYBACK
++	oris	r10, r10, MD_WTDEF at h
++#endif
++	mtspr	SPRN_MD_CTR, r10	/* Set data TLB control */
++
++	/* Now map the lower 8 Meg into the TLBs.  For this quick hack,
++	 * we can load the instruction and data TLB registers with the
++	 * same values.
++	 */
++	lis	r8, KERNELBASE at h	/* Create vaddr for TLB */
++	ori	r8, r8, MI_EVALID	/* Mark it valid */
++	mtspr	SPRN_MI_EPN, r8
++	mtspr	SPRN_MD_EPN, r8
++	li	r8, MI_PS8MEG		/* Set 8M byte page */
++	ori	r8, r8, MI_SVALID	/* Make it valid */
++	mtspr	SPRN_MI_TWC, r8
++	mtspr	SPRN_MD_TWC, r8
++	li	r8, MI_BOOTINIT		/* Create RPN for address 0 */
++	mtspr	SPRN_MI_RPN, r8		/* Store TLB entry */
++	mtspr	SPRN_MD_RPN, r8
++	lis	r8, MI_Kp at h		/* Set the protection mode */
++	mtspr	SPRN_MI_AP, r8
++	mtspr	SPRN_MD_AP, r8
++
++	/* Map another 8 MByte at the IMMR to get the processor
++	 * internal registers (among other things).
++	 */
++#ifdef CONFIG_PIN_TLB
++	addi	r10, r10, 0x0100
++	mtspr	SPRN_MD_CTR, r10
++#endif
++	mfspr	r9, 638			/* Get current IMMR */
++	andis.	r9, r9, 0xff80		/* Get 8Mbyte boundary */
++
++	mr	r8, r9			/* Create vaddr for TLB */
++	ori	r8, r8, MD_EVALID	/* Mark it valid */
++	mtspr	SPRN_MD_EPN, r8
++	li	r8, MD_PS8MEG		/* Set 8M byte page */
++	ori	r8, r8, MD_SVALID	/* Make it valid */
++	mtspr	SPRN_MD_TWC, r8
++	mr	r8, r9			/* Create paddr for TLB */
++	ori	r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
++	mtspr	SPRN_MD_RPN, r8
++
++#ifdef CONFIG_PIN_TLB
++	/* Map two more 8M kernel data pages.
++	*/
++	addi	r10, r10, 0x0100
++	mtspr	SPRN_MD_CTR, r10
++
++	lis	r8, KERNELBASE at h	/* Create vaddr for TLB */
++	addis	r8, r8, 0x0080		/* Add 8M */
++	ori	r8, r8, MI_EVALID	/* Mark it valid */
++	mtspr	SPRN_MD_EPN, r8
++	li	r9, MI_PS8MEG		/* Set 8M byte page */
++	ori	r9, r9, MI_SVALID	/* Make it valid */
++	mtspr	SPRN_MD_TWC, r9
++	li	r11, MI_BOOTINIT	/* Create RPN for address 0 */
++	addis	r11, r11, 0x0080	/* Add 8M */
++	mtspr	SPRN_MD_RPN, r8
++
++	addis	r8, r8, 0x0080		/* Add 8M */
++	mtspr	SPRN_MD_EPN, r8
++	mtspr	SPRN_MD_TWC, r9
++	addis	r11, r11, 0x0080	/* Add 8M */
++	mtspr	SPRN_MD_RPN, r8
++#endif
++
++	/* Since the cache is enabled according to the information we
++	 * just loaded into the TLB, invalidate and enable the caches here.
++	 * We should probably check/set other modes....later.
++	 */
++	lis	r8, IDC_INVALL at h
++	mtspr	SPRN_IC_CST, r8
++	mtspr	SPRN_DC_CST, r8
++	lis	r8, IDC_ENABLE at h
++	mtspr	SPRN_IC_CST, r8
++#ifdef CONFIG_8xx_COPYBACK
++	mtspr	SPRN_DC_CST, r8
++#else
++	/* For a debug option, I left this here to easily enable
++	 * the write through cache mode
++	 */
++	lis	r8, DC_SFWT at h
++	mtspr	SPRN_DC_CST, r8
++	lis	r8, IDC_ENABLE at h
++	mtspr	SPRN_DC_CST, r8
++#endif
++	blr
++
++
++/*
++ * Set up to use a given MMU context.
++ * r3 is context number, r4 is PGD pointer.
++ *
++ * We place the physical address of the new task page directory loaded
++ * into the MMU base register, and set the ASID compare register with
++ * the new "context."
++ */
++_GLOBAL(set_context)
++
++#ifdef CONFIG_BDI_SWITCH
++	/* Context switch the PTE pointer for the Abatron BDI2000.
++	 * The PGDIR is passed as second argument.
++	 */
++	lis	r5, KERNELBASE at h
++	lwz	r5, 0xf0(r5)
++	stw	r4, 0x4(r5)
++#endif
++
++#ifdef CONFIG_8xx_CPU6
++	lis	r6, cpu6_errata_word at h
++	ori	r6, r6, cpu6_errata_word at l
++	tophys	(r4, r4)
++	li	r7, 0x3980
++	stw	r7, 12(r6)
++	lwz	r7, 12(r6)
++        mtspr   SPRN_M_TWB, r4               /* Update MMU base address */
++	li	r7, 0x3380
++	stw	r7, 12(r6)
++	lwz	r7, 12(r6)
++        mtspr   SPRN_M_CASID, r3             /* Update context */
++#else
++        mtspr   SPRN_M_CASID,r3		/* Update context */
++	tophys	(r4, r4)
++	mtspr	SPRN_M_TWB, r4		/* and pgd */
++#endif
++	SYNC
++	blr
++
++#ifdef CONFIG_8xx_CPU6
++/* It's here because it is unique to the 8xx.
++ * It is important we get called with interrupts disabled.  I used to
++ * do that, but it appears that all code that calls this already had
++ * interrupt disabled.
++ */
++	.globl	set_dec_cpu6
++set_dec_cpu6:
++	lis	r7, cpu6_errata_word at h
++	ori	r7, r7, cpu6_errata_word at l
++	li	r4, 0x2c00
++	stw	r4, 8(r7)
++	lwz	r4, 8(r7)
++        mtspr   22, r3		/* Update Decrementer */
++	SYNC
++	blr
++#endif
++
++/*
++ * We put a few things here that have to be page-aligned.
++ * This stuff goes at the beginning of the data segment,
++ * which is page-aligned.
++ */
++	.data
++	.globl	sdata
++sdata:
++	.globl	empty_zero_page
++empty_zero_page:
++	.space	4096
++
++	.globl	swapper_pg_dir
++swapper_pg_dir:
++	.space	4096
++
++/*
++ * This space gets a copy of optional info passed to us by the bootstrap
++ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
++ */
++	.globl	cmd_line
++cmd_line:
++	.space	512
++
++/* Room for two PTE table poiners, usually the kernel and current user
++ * pointer to their respective root page table (pgdir).
++ */
++abatron_pteptrs:
++	.space	8
++
++#ifdef CONFIG_8xx_CPU6
++	.globl	cpu6_errata_word
++cpu6_errata_word:
++	.space	16
++#endif
++
+diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/head_fsl_booke.S
+@@ -0,0 +1,1063 @@
++/*
++ * arch/ppc/kernel/head_fsl_booke.S
++ *
++ * Kernel execution entry point code.
++ *
++ *    Copyright (c) 1995-1996 Gary Thomas <gdt at linuxppc.org>
++ *      Initial PowerPC version.
++ *    Copyright (c) 1996 Cort Dougan <cort at cs.nmt.edu>
++ *      Rewritten for PReP
++ *    Copyright (c) 1996 Paul Mackerras <paulus at cs.anu.edu.au>
++ *      Low-level exception handers, MMU support, and rewrite.
++ *    Copyright (c) 1997 Dan Malek <dmalek at jlc.net>
++ *      PowerPC 8xx modifications.
++ *    Copyright (c) 1998-1999 TiVo, Inc.
++ *      PowerPC 403GCX modifications.
++ *    Copyright (c) 1999 Grant Erickson <grant at lcse.umn.edu>
++ *      PowerPC 403GCX/405GP modifications.
++ *    Copyright 2000 MontaVista Software Inc.
++ *	PPC405 modifications
++ *      PowerPC 403GCX/405GP modifications.
++ * 	Author: MontaVista Software, Inc.
++ *         	frank_rowand at mvista.com or source at mvista.com
++ * 	   	debbie_chu at mvista.com
++ *    Copyright 2002-2004 MontaVista Software, Inc.
++ *      PowerPC 44x support, Matt Porter <mporter at kernel.crashing.org>
++ *    Copyright 2004 Freescale Semiconductor, Inc
++ *      PowerPC e500 modifications, Kumar Gala <kumar.gala 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.
++ */
++
++#include <linux/config.h>
++#include <linux/threads.h>
++#include <asm/processor.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/pgtable.h>
++#include <asm/cputable.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++#include "head_booke.h"
++
++/* As with the other PowerPC ports, it is expected that when code
++ * execution begins here, the following registers contain valid, yet
++ * optional, information:
++ *
++ *   r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
++ *   r4 - Starting address of the init RAM disk
++ *   r5 - Ending address of the init RAM disk
++ *   r6 - Start of kernel command line string (e.g. "mem=128")
++ *   r7 - End of kernel command line string
++ *
++ */
++	.text
++_GLOBAL(_stext)
++_GLOBAL(_start)
++	/*
++	 * Reserve a word at a fixed location to store the address
++	 * of abatron_pteptrs
++	 */
++	nop
++/*
++ * Save parameters we are passed
++ */
++	mr	r31,r3
++	mr	r30,r4
++	mr	r29,r5
++	mr	r28,r6
++	mr	r27,r7
++	li	r24,0		/* CPU number */
++
++/* We try to not make any assumptions about how the boot loader
++ * setup or used the TLBs.  We invalidate all mappings from the
++ * boot loader and load a single entry in TLB1[0] to map the
++ * first 16M of kernel memory.  Any boot info passed from the
++ * bootloader needs to live in this first 16M.
++ *
++ * Requirement on bootloader:
++ *  - The page we're executing in needs to reside in TLB1 and
++ *    have IPROT=1.  If not an invalidate broadcast could
++ *    evict the entry we're currently executing in.
++ *
++ *  r3 = Index of TLB1 were executing in
++ *  r4 = Current MSR[IS]
++ *  r5 = Index of TLB1 temp mapping
++ *
++ * Later in mapin_ram we will correctly map lowmem, and resize TLB1[0]
++ * if needed
++ */
++
++/* 1. Find the index of the entry we're executing in */
++	bl	invstr				/* Find our address */
++invstr:	mflr	r6				/* Make it accessible */
++	mfmsr	r7
++	rlwinm	r4,r7,27,31,31			/* extract MSR[IS] */
++	mfspr	r7, SPRN_PID0
++	slwi	r7,r7,16
++	or	r7,r7,r4
++	mtspr	SPRN_MAS6,r7
++	tlbsx	0,r6				/* search MSR[IS], SPID=PID0 */
++#ifndef CONFIG_E200
++	mfspr	r7,SPRN_MAS1
++	andis.	r7,r7,MAS1_VALID at h
++	bne	match_TLB
++	mfspr	r7,SPRN_PID1
++	slwi	r7,r7,16
++	or	r7,r7,r4
++	mtspr	SPRN_MAS6,r7
++	tlbsx	0,r6				/* search MSR[IS], SPID=PID1 */
++	mfspr	r7,SPRN_MAS1
++	andis.	r7,r7,MAS1_VALID at h
++	bne	match_TLB
++	mfspr	r7, SPRN_PID2
++	slwi	r7,r7,16
++	or	r7,r7,r4
++	mtspr	SPRN_MAS6,r7
++	tlbsx	0,r6				/* Fall through, we had to match */
++#endif
++match_TLB:
++	mfspr	r7,SPRN_MAS0
++	rlwinm	r3,r7,16,20,31			/* Extract MAS0(Entry) */
++
++	mfspr	r7,SPRN_MAS1			/* Insure IPROT set */
++	oris	r7,r7,MAS1_IPROT at h
++	mtspr	SPRN_MAS1,r7
++	tlbwe
++
++/* 2. Invalidate all entries except the entry we're executing in */
++	mfspr	r9,SPRN_TLB1CFG
++	andi.	r9,r9,0xfff
++	li	r6,0				/* Set Entry counter to 0 */
++1:	lis	r7,0x1000			/* Set MAS0(TLBSEL) = 1 */
++	rlwimi	r7,r6,16,4,15			/* Setup MAS0 = TLBSEL | ESEL(r6) */
++	mtspr	SPRN_MAS0,r7
++	tlbre
++	mfspr	r7,SPRN_MAS1
++	rlwinm	r7,r7,0,2,31			/* Clear MAS1 Valid and IPROT */
++	cmpw	r3,r6
++	beq	skpinv				/* Dont update the current execution TLB */
++	mtspr	SPRN_MAS1,r7
++	tlbwe
++	isync
++skpinv:	addi	r6,r6,1				/* Increment */
++	cmpw	r6,r9				/* Are we done? */
++	bne	1b				/* If not, repeat */
++
++	/* Invalidate TLB0 */
++	li      r6,0x04
++	tlbivax 0,r6
++#ifdef CONFIG_SMP
++	tlbsync
++#endif
++	/* Invalidate TLB1 */
++	li      r6,0x0c
++	tlbivax 0,r6
++#ifdef CONFIG_SMP
++	tlbsync
++#endif
++	msync
++
++/* 3. Setup a temp mapping and jump to it */
++	andi.	r5, r3, 0x1	/* Find an entry not used and is non-zero */
++	addi	r5, r5, 0x1
++	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
++	rlwimi	r7,r3,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r3) */
++	mtspr	SPRN_MAS0,r7
++	tlbre
++
++	/* Just modify the entry ID and EPN for the temp mapping */
++	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
++	rlwimi	r7,r5,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r5) */
++	mtspr	SPRN_MAS0,r7
++	xori	r6,r4,1		/* Setup TMP mapping in the other Address space */
++	slwi	r6,r6,12
++	oris	r6,r6,(MAS1_VALID|MAS1_IPROT)@h
++	ori	r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
++	mtspr	SPRN_MAS1,r6
++	mfspr	r6,SPRN_MAS2
++	li	r7,0		/* temp EPN = 0 */
++	rlwimi	r7,r6,0,20,31
++	mtspr	SPRN_MAS2,r7
++	tlbwe
++
++	xori	r6,r4,1
++	slwi	r6,r6,5		/* setup new context with other address space */
++	bl	1f		/* Find our address */
++1:	mflr	r9
++	rlwimi	r7,r9,0,20,31
++	addi	r7,r7,24
++	mtspr	SPRN_SRR0,r7
++	mtspr	SPRN_SRR1,r6
++	rfi
++
++/* 4. Clear out PIDs & Search info */
++	li	r6,0
++	mtspr	SPRN_PID0,r6
++#ifndef CONFIG_E200
++	mtspr	SPRN_PID1,r6
++	mtspr	SPRN_PID2,r6
++#endif
++	mtspr	SPRN_MAS6,r6
++
++/* 5. Invalidate mapping we started in */
++	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
++	rlwimi	r7,r3,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r3) */
++	mtspr	SPRN_MAS0,r7
++	tlbre
++	li	r6,0
++	mtspr	SPRN_MAS1,r6
++	tlbwe
++	/* Invalidate TLB1 */
++	li      r9,0x0c
++	tlbivax 0,r9
++#ifdef CONFIG_SMP
++	tlbsync
++#endif
++	msync
++
++/* 6. Setup KERNELBASE mapping in TLB1[0] */
++	lis	r6,0x1000		/* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
++	mtspr	SPRN_MAS0,r6
++	lis	r6,(MAS1_VALID|MAS1_IPROT)@h
++	ori	r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_16M))@l
++	mtspr	SPRN_MAS1,r6
++	li	r7,0
++	lis	r6,KERNELBASE at h
++	ori	r6,r6,KERNELBASE at l
++	rlwimi	r6,r7,0,20,31
++	mtspr	SPRN_MAS2,r6
++	li	r7,(MAS3_SX|MAS3_SW|MAS3_SR)
++	mtspr	SPRN_MAS3,r7
++	tlbwe
++
++/* 7. Jump to KERNELBASE mapping */
++	lis	r7,MSR_KERNEL at h
++	ori	r7,r7,MSR_KERNEL at l
++	bl	1f			/* Find our address */
++1:	mflr	r9
++	rlwimi	r6,r9,0,20,31
++	addi	r6,r6,24
++	mtspr	SPRN_SRR0,r6
++	mtspr	SPRN_SRR1,r7
++	rfi				/* start execution out of TLB1[0] entry */
++
++/* 8. Clear out the temp mapping */
++	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
++	rlwimi	r7,r5,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r5) */
++	mtspr	SPRN_MAS0,r7
++	tlbre
++	mtspr	SPRN_MAS1,r8
++	tlbwe
++	/* Invalidate TLB1 */
++	li      r9,0x0c
++	tlbivax 0,r9
++#ifdef CONFIG_SMP
++	tlbsync
++#endif
++	msync
++
++	/* Establish the interrupt vector offsets */
++	SET_IVOR(0,  CriticalInput);
++	SET_IVOR(1,  MachineCheck);
++	SET_IVOR(2,  DataStorage);
++	SET_IVOR(3,  InstructionStorage);
++	SET_IVOR(4,  ExternalInput);
++	SET_IVOR(5,  Alignment);
++	SET_IVOR(6,  Program);
++	SET_IVOR(7,  FloatingPointUnavailable);
++	SET_IVOR(8,  SystemCall);
++	SET_IVOR(9,  AuxillaryProcessorUnavailable);
++	SET_IVOR(10, Decrementer);
++	SET_IVOR(11, FixedIntervalTimer);
++	SET_IVOR(12, WatchdogTimer);
++	SET_IVOR(13, DataTLBError);
++	SET_IVOR(14, InstructionTLBError);
++	SET_IVOR(15, Debug);
++	SET_IVOR(32, SPEUnavailable);
++	SET_IVOR(33, SPEFloatingPointData);
++	SET_IVOR(34, SPEFloatingPointRound);
++#ifndef CONFIG_E200
++	SET_IVOR(35, PerformanceMonitor);
++#endif
++
++	/* Establish the interrupt vector base */
++	lis	r4,interrupt_base at h	/* IVPR only uses the high 16-bits */
++	mtspr	SPRN_IVPR,r4
++
++	/* Setup the defaults for TLB entries */
++	li	r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
++#ifdef CONFIG_E200
++	oris	r2,r2,MAS4_TLBSELD(1)@h
++#endif
++   	mtspr	SPRN_MAS4, r2
++
++#if 0
++	/* Enable DOZE */
++	mfspr	r2,SPRN_HID0
++	oris	r2,r2,HID0_DOZE at h
++	mtspr	SPRN_HID0, r2
++#endif
++#ifdef CONFIG_E200
++	/* enable dedicated debug exception handling resources (Debug APU) */
++	mfspr	r2,SPRN_HID0
++	ori 	r2,r2,HID0_DAPUEN at l
++	mtspr	SPRN_HID0,r2
++#endif
++
++#if !defined(CONFIG_BDI_SWITCH)
++	/*
++	 * The Abatron BDI JTAG debugger does not tolerate others
++	 * mucking with the debug registers.
++	 */
++	lis	r2,DBCR0_IDM at h
++	mtspr	SPRN_DBCR0,r2
++	/* clear any residual debug events */
++	li	r2,-1
++	mtspr	SPRN_DBSR,r2
++#endif
++
++	/*
++	 * This is where the main kernel code starts.
++	 */
++
++	/* ptr to current */
++	lis	r2,init_task at h
++	ori	r2,r2,init_task at l
++
++	/* ptr to current thread */
++	addi	r4,r2,THREAD	/* init task's THREAD */
++	mtspr	SPRN_SPRG3,r4
++
++	/* stack */
++	lis	r1,init_thread_union at h
++	ori	r1,r1,init_thread_union at l
++	li	r0,0
++	stwu	r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
++
++	bl	early_init
++
++	mfspr	r3,SPRN_TLB1CFG
++	andi.	r3,r3,0xfff
++	lis	r4,num_tlbcam_entries at ha
++	stw	r3,num_tlbcam_entries at l(r4)
++/*
++ * Decide what sort of machine this is and initialize the MMU.
++ */
++	mr	r3,r31
++	mr	r4,r30
++	mr	r5,r29
++	mr	r6,r28
++	mr	r7,r27
++	bl	machine_init
++	bl	MMU_init
++
++	/* Setup PTE pointers for the Abatron bdiGDB */
++	lis	r6, swapper_pg_dir at h
++	ori	r6, r6, swapper_pg_dir at l
++	lis	r5, abatron_pteptrs at h
++	ori	r5, r5, abatron_pteptrs at l
++	lis	r4, KERNELBASE at h
++	ori	r4, r4, KERNELBASE at l
++	stw	r5, 0(r4)	/* Save abatron_pteptrs at a fixed location */
++	stw	r6, 0(r5)
++
++	/* Let's move on */
++	lis	r4,start_kernel at h
++	ori	r4,r4,start_kernel at l
++	lis	r3,MSR_KERNEL at h
++	ori	r3,r3,MSR_KERNEL at l
++	mtspr	SPRN_SRR0,r4
++	mtspr	SPRN_SRR1,r3
++	rfi			/* change context and jump to start_kernel */
++
++/* Macros to hide the PTE size differences
++ *
++ * FIND_PTE -- walks the page tables given EA & pgdir pointer
++ *   r10 -- EA of fault
++ *   r11 -- PGDIR pointer
++ *   r12 -- free
++ *   label 2: is the bailout case
++ *
++ * if we find the pte (fall through):
++ *   r11 is low pte word
++ *   r12 is pointer to the pte
++ */
++#ifdef CONFIG_PTE_64BIT
++#define PTE_FLAGS_OFFSET	4
++#define FIND_PTE	\
++	rlwinm 	r12, r10, 13, 19, 29;	/* Compute pgdir/pmd offset */	\
++	lwzx	r11, r12, r11;		/* Get pgd/pmd entry */		\
++	rlwinm.	r12, r11, 0, 0, 20;	/* Extract pt base address */	\
++	beq	2f;			/* Bail if no table */		\
++	rlwimi	r12, r10, 23, 20, 28;	/* Compute pte address */	\
++	lwz	r11, 4(r12);		/* Get pte entry */
++#else
++#define PTE_FLAGS_OFFSET	0
++#define FIND_PTE	\
++	rlwimi	r11, r10, 12, 20, 29;	/* Create L1 (pgdir/pmd) address */	\
++	lwz	r11, 0(r11);		/* Get L1 entry */			\
++	rlwinm.	r12, r11, 0, 0, 19;	/* Extract L2 (pte) base address */	\
++	beq	2f;			/* Bail if no table */			\
++	rlwimi	r12, r10, 22, 20, 29;	/* Compute PTE address */		\
++	lwz	r11, 0(r12);		/* Get Linux PTE */
++#endif
++
++/*
++ * Interrupt vector entry code
++ *
++ * The Book E MMUs are always on so we don't need to handle
++ * interrupts in real mode as with previous PPC processors. In
++ * this case we handle interrupts in the kernel virtual address
++ * space.
++ *
++ * Interrupt vectors are dynamically placed relative to the
++ * interrupt prefix as determined by the address of interrupt_base.
++ * The interrupt vectors offsets are programmed using the labels
++ * for each interrupt vector entry.
++ *
++ * Interrupt vectors must be aligned on a 16 byte boundary.
++ * We align on a 32 byte cache line boundary for good measure.
++ */
++
++interrupt_base:
++	/* Critical Input Interrupt */
++	CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
++
++	/* Machine Check Interrupt */
++#ifdef CONFIG_E200
++	/* no RFMCI, MCSRRs on E200 */
++	CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
++#else
++	MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
++#endif
++
++	/* Data Storage Interrupt */
++	START_EXCEPTION(DataStorage)
++	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
++	mtspr	SPRN_SPRG1, r11
++	mtspr	SPRN_SPRG4W, r12
++	mtspr	SPRN_SPRG5W, r13
++	mfcr	r11
++	mtspr	SPRN_SPRG7W, r11
++
++	/*
++	 * Check if it was a store fault, if not then bail
++	 * because a user tried to access a kernel or
++	 * read-protected page.  Otherwise, get the
++	 * offending address and handle it.
++	 */
++	mfspr	r10, SPRN_ESR
++	andis.	r10, r10, ESR_ST at h
++	beq	2f
++
++	mfspr	r10, SPRN_DEAR		/* Get faulting address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	lis	r11, TASK_SIZE at h
++	ori	r11, r11, TASK_SIZE at l
++	cmplw	0, r10, r11
++	bge	2f
++
++	/* Get the PGD for the current thread */
++3:
++	mfspr	r11,SPRN_SPRG3
++	lwz	r11,PGDIR(r11)
++4:
++	FIND_PTE
++
++	/* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */
++	andi.	r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE
++	cmpwi	0, r13, _PAGE_RW|_PAGE_USER
++	bne	2f			/* Bail if not */
++
++	/* Update 'changed'. */
++	ori	r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
++	stw	r11, PTE_FLAGS_OFFSET(r12) /* Update Linux page table */
++
++	/* MAS2 not updated as the entry does exist in the tlb, this
++	   fault taken to detect state transition (eg: COW -> DIRTY)
++	 */
++	andi.	r11, r11, _PAGE_HWEXEC
++	rlwimi	r11, r11, 31, 27, 27	/* SX <- _PAGE_HWEXEC */
++	ori     r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static perms */
++
++	/* update search PID in MAS6, AS = 0 */
++	mfspr	r12, SPRN_PID0
++	slwi	r12, r12, 16
++	mtspr	SPRN_MAS6, r12
++
++	/* find the TLB index that caused the fault.  It has to be here. */
++	tlbsx	0, r10
++
++	/* only update the perm bits, assume the RPN is fine */
++	mfspr	r12, SPRN_MAS3
++	rlwimi	r12, r11, 0, 20, 31
++	mtspr	SPRN_MAS3,r12
++	tlbwe
++
++	/* Done...restore registers and get out of here.  */
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	rfi			/* Force context change */
++
++2:
++	/*
++	 * The bailout.  Restore registers to pre-exception conditions
++	 * and call the heavyweights to help us out.
++	 */
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	b	data_access
++
++	/* Instruction Storage Interrupt */
++	INSTRUCTION_STORAGE_EXCEPTION
++
++	/* External Input Interrupt */
++	EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
++
++	/* Alignment Interrupt */
++	ALIGNMENT_EXCEPTION
++
++	/* Program Interrupt */
++	PROGRAM_EXCEPTION
++
++	/* Floating Point Unavailable Interrupt */
++#ifdef CONFIG_PPC_FPU
++	FP_UNAVAILABLE_EXCEPTION
++#else
++#ifdef CONFIG_E200
++	/* E200 treats 'normal' floating point instructions as FP Unavail exception */
++	EXCEPTION(0x0800, FloatingPointUnavailable, program_check_exception, EXC_XFER_EE)
++#else
++	EXCEPTION(0x0800, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
++#endif
++#endif
++
++	/* System Call Interrupt */
++	START_EXCEPTION(SystemCall)
++	NORMAL_EXCEPTION_PROLOG
++	EXC_XFER_EE_LITE(0x0c00, DoSyscall)
++
++	/* Auxillary Processor Unavailable Interrupt */
++	EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
++
++	/* Decrementer Interrupt */
++	DECREMENTER_EXCEPTION
++
++	/* Fixed Internal Timer Interrupt */
++	/* TODO: Add FIT support */
++	EXCEPTION(0x3100, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
++
++	/* Watchdog Timer Interrupt */
++#ifdef CONFIG_BOOKE_WDT
++	CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException)
++#else
++	CRITICAL_EXCEPTION(0x3200, WatchdogTimer, unknown_exception)
++#endif
++
++	/* Data TLB Error Interrupt */
++	START_EXCEPTION(DataTLBError)
++	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
++	mtspr	SPRN_SPRG1, r11
++	mtspr	SPRN_SPRG4W, r12
++	mtspr	SPRN_SPRG5W, r13
++	mfcr	r11
++	mtspr	SPRN_SPRG7W, r11
++	mfspr	r10, SPRN_DEAR		/* Get faulting address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	lis	r11, TASK_SIZE at h
++	ori	r11, r11, TASK_SIZE at l
++	cmplw	5, r10, r11
++	blt	5, 3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++
++	mfspr	r12,SPRN_MAS1		/* Set TID to 0 */
++	rlwinm	r12,r12,0,16,1
++	mtspr	SPRN_MAS1,r12
++
++	b	4f
++
++	/* Get the PGD for the current thread */
++3:
++	mfspr	r11,SPRN_SPRG3
++	lwz	r11,PGDIR(r11)
++
++4:
++	FIND_PTE
++	andi.	r13, r11, _PAGE_PRESENT	/* Is the page present? */
++	beq	2f			/* Bail if not present */
++
++#ifdef CONFIG_PTE_64BIT
++	lwz	r13, 0(r12)
++#endif
++	ori	r11, r11, _PAGE_ACCESSED
++	stw	r11, PTE_FLAGS_OFFSET(r12)
++
++	 /* Jump to common tlb load */
++	b	finish_tlb_load
++2:
++	/* The bailout.  Restore registers to pre-exception conditions
++	 * and call the heavyweights to help us out.
++	 */
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	b	data_access
++
++	/* Instruction TLB Error Interrupt */
++	/*
++	 * Nearly the same as above, except we get our
++	 * information from different registers and bailout
++	 * to a different point.
++	 */
++	START_EXCEPTION(InstructionTLBError)
++	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
++	mtspr	SPRN_SPRG1, r11
++	mtspr	SPRN_SPRG4W, r12
++	mtspr	SPRN_SPRG5W, r13
++	mfcr	r11
++	mtspr	SPRN_SPRG7W, r11
++	mfspr	r10, SPRN_SRR0		/* Get faulting address */
++
++	/* If we are faulting a kernel address, we have to use the
++	 * kernel page tables.
++	 */
++	lis	r11, TASK_SIZE at h
++	ori	r11, r11, TASK_SIZE at l
++	cmplw	5, r10, r11
++	blt	5, 3f
++	lis	r11, swapper_pg_dir at h
++	ori	r11, r11, swapper_pg_dir at l
++
++	mfspr	r12,SPRN_MAS1		/* Set TID to 0 */
++	rlwinm	r12,r12,0,16,1
++	mtspr	SPRN_MAS1,r12
++
++	b	4f
++
++	/* Get the PGD for the current thread */
++3:
++	mfspr	r11,SPRN_SPRG3
++	lwz	r11,PGDIR(r11)
++
++4:
++	FIND_PTE
++	andi.	r13, r11, _PAGE_PRESENT	/* Is the page present? */
++	beq	2f			/* Bail if not present */
++
++#ifdef CONFIG_PTE_64BIT
++	lwz	r13, 0(r12)
++#endif
++	ori	r11, r11, _PAGE_ACCESSED
++	stw	r11, PTE_FLAGS_OFFSET(r12)
++
++	/* Jump to common TLB load point */
++	b	finish_tlb_load
++
++2:
++	/* The bailout.  Restore registers to pre-exception conditions
++	 * and call the heavyweights to help us out.
++	 */
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	b	InstructionStorage
++
++#ifdef CONFIG_SPE
++	/* SPE Unavailable */
++	START_EXCEPTION(SPEUnavailable)
++	NORMAL_EXCEPTION_PROLOG
++	bne	load_up_spe
++	addi    r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_EE_LITE(0x2010, KernelSPE)
++#else
++	EXCEPTION(0x2020, SPEUnavailable, unknown_exception, EXC_XFER_EE)
++#endif /* CONFIG_SPE */
++
++	/* SPE Floating Point Data */
++#ifdef CONFIG_SPE
++	EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
++#else
++	EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
++#endif /* CONFIG_SPE */
++
++	/* SPE Floating Point Round */
++	EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
++
++	/* Performance Monitor */
++	EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
++
++
++	/* Debug Interrupt */
++	DEBUG_EXCEPTION
++
++/*
++ * Local functions
++ */
++
++	/*
++	 * Data TLB exceptions will bail out to this point
++	 * if they can't resolve the lightweight TLB fault.
++	 */
++data_access:
++	NORMAL_EXCEPTION_PROLOG
++	mfspr	r5,SPRN_ESR		/* Grab the ESR, save it, pass arg3 */
++	stw	r5,_ESR(r11)
++	mfspr	r4,SPRN_DEAR		/* Grab the DEAR, save it, pass arg2 */
++	andis.	r10,r5,(ESR_ILK|ESR_DLK)@h
++	bne	1f
++	EXC_XFER_EE_LITE(0x0300, handle_page_fault)
++1:
++	addi	r3,r1,STACK_FRAME_OVERHEAD
++	EXC_XFER_EE_LITE(0x0300, CacheLockingException)
++
++/*
++
++ * Both the instruction and data TLB miss get to this
++ * point to load the TLB.
++ * 	r10 - EA of fault
++ * 	r11 - TLB (info from Linux PTE)
++ * 	r12, r13 - available to use
++ * 	CR5 - results of addr < TASK_SIZE
++ *	MAS0, MAS1 - loaded with proper value when we get here
++ *	MAS2, MAS3 - will need additional info from Linux PTE
++ *	Upon exit, we reload everything and RFI.
++ */
++finish_tlb_load:
++	/*
++	 * We set execute, because we don't have the granularity to
++	 * properly set this at the page level (Linux problem).
++	 * Many of these bits are software only.  Bits we don't set
++	 * here we (properly should) assume have the appropriate value.
++	 */
++
++	mfspr	r12, SPRN_MAS2
++#ifdef CONFIG_PTE_64BIT
++	rlwimi	r12, r11, 26, 24, 31	/* extract ...WIMGE from pte */
++#else
++	rlwimi	r12, r11, 26, 27, 31	/* extract WIMGE from pte */
++#endif
++	mtspr	SPRN_MAS2, r12
++
++	bge	5, 1f
++
++	/* is user addr */
++	andi.	r12, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC)
++	andi.	r10, r11, _PAGE_USER	/* Test for _PAGE_USER */
++	srwi	r10, r12, 1
++	or	r12, r12, r10	/* Copy user perms into supervisor */
++	iseleq	r12, 0, r12
++	b	2f
++
++	/* is kernel addr */
++1:	rlwinm	r12, r11, 31, 29, 29	/* Extract _PAGE_HWWRITE into SW */
++	ori	r12, r12, (MAS3_SX | MAS3_SR)
++
++#ifdef CONFIG_PTE_64BIT
++2:	rlwimi	r12, r13, 24, 0, 7	/* grab RPN[32:39] */
++	rlwimi	r12, r11, 24, 8, 19	/* grab RPN[40:51] */
++	mtspr	SPRN_MAS3, r12
++BEGIN_FTR_SECTION
++	srwi	r10, r13, 8		/* grab RPN[8:31] */
++	mtspr	SPRN_MAS7, r10
++END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS)
++#else
++2:	rlwimi	r11, r12, 0, 20, 31	/* Extract RPN from PTE and merge with perms */
++	mtspr	SPRN_MAS3, r11
++#endif
++#ifdef CONFIG_E200
++	/* Round robin TLB1 entries assignment */
++	mfspr	r12, SPRN_MAS0
++
++	/* Extract TLB1CFG(NENTRY) */
++	mfspr	r11, SPRN_TLB1CFG
++	andi.	r11, r11, 0xfff
++
++	/* Extract MAS0(NV) */
++	andi.	r13, r12, 0xfff
++	addi	r13, r13, 1
++	cmpw	0, r13, r11
++	addi	r12, r12, 1
++
++	/* check if we need to wrap */
++	blt	7f
++
++	/* wrap back to first free tlbcam entry */
++	lis	r13, tlbcam_index at ha
++	lwz	r13, tlbcam_index at l(r13)
++	rlwimi	r12, r13, 0, 20, 31
++7:
++	mtspr   SPRN_MAS0,r12
++#endif /* CONFIG_E200 */
++
++	tlbwe
++
++	/* Done...restore registers and get out of here.  */
++	mfspr	r11, SPRN_SPRG7R
++	mtcr	r11
++	mfspr	r13, SPRN_SPRG5R
++	mfspr	r12, SPRN_SPRG4R
++	mfspr	r11, SPRN_SPRG1
++	mfspr	r10, SPRN_SPRG0
++	rfi					/* Force context change */
++
++#ifdef CONFIG_SPE
++/* Note that the SPE support is closely modeled after the AltiVec
++ * support.  Changes to one are likely to be applicable to the
++ * other!  */
++load_up_spe:
++/*
++ * Disable SPE for the task which had SPE previously,
++ * and save its SPE registers in its thread_struct.
++ * Enables SPE for use in the kernel on return.
++ * On SMP we know the SPE units are free, since we give it up every
++ * switch.  -- Kumar
++ */
++	mfmsr	r5
++	oris	r5,r5,MSR_SPE at h
++	mtmsr	r5			/* enable use of SPE now */
++	isync
++/*
++ * For SMP, we don't do lazy SPE switching because it just gets too
++ * horrendously complex, especially when a task switches from one CPU
++ * to another.  Instead we call giveup_spe in switch_to.
++ */
++#ifndef CONFIG_SMP
++	lis	r3,last_task_used_spe at ha
++	lwz	r4,last_task_used_spe at l(r3)
++	cmpi	0,r4,0
++	beq	1f
++	addi	r4,r4,THREAD	/* want THREAD of last_task_used_spe */
++	SAVE_32EVRS(0,r10,r4)
++   	evxor	evr10, evr10, evr10	/* clear out evr10 */
++	evmwumiaa evr10, evr10, evr10	/* evr10 <- ACC = 0 * 0 + ACC */
++	li	r5,THREAD_ACC
++   	evstddx	evr10, r4, r5		/* save off accumulator */
++	lwz	r5,PT_REGS(r4)
++	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++	lis	r10,MSR_SPE at h
++	andc	r4,r4,r10	/* disable SPE for previous task */
++	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++1:
++#endif /* CONFIG_SMP */
++	/* enable use of SPE after return */
++	oris	r9,r9,MSR_SPE at h
++	mfspr	r5,SPRN_SPRG3		/* current task's THREAD (phys) */
++	li	r4,1
++	li	r10,THREAD_ACC
++	stw	r4,THREAD_USED_SPE(r5)
++	evlddx	evr4,r10,r5
++	evmra	evr4,evr4
++	REST_32EVRS(0,r10,r5)
++#ifndef CONFIG_SMP
++	subi	r4,r5,THREAD
++	stw	r4,last_task_used_spe at l(r3)
++#endif /* CONFIG_SMP */
++	/* restore registers and return */
++2:	REST_4GPRS(3, r11)
++	lwz	r10,_CCR(r11)
++	REST_GPR(1, r11)
++	mtcr	r10
++	lwz	r10,_LINK(r11)
++	mtlr	r10
++	REST_GPR(10, r11)
++	mtspr	SPRN_SRR1,r9
++	mtspr	SPRN_SRR0,r12
++	REST_GPR(9, r11)
++	REST_GPR(12, r11)
++	lwz	r11,GPR11(r11)
++	SYNC
++	rfi
++
++/*
++ * SPE unavailable trap from kernel - print a message, but let
++ * the task use SPE in the kernel until it returns to user mode.
++ */
++KernelSPE:
++	lwz	r3,_MSR(r1)
++	oris	r3,r3,MSR_SPE at h
++	stw	r3,_MSR(r1)	/* enable use of SPE after return */
++	lis	r3,87f at h
++	ori	r3,r3,87f at l
++	mr	r4,r2		/* current */
++	lwz	r5,_NIP(r1)
++	bl	printk
++	b	ret_from_except
++87:	.string	"SPE used in kernel  (task=%p, pc=%x)  \n"
++	.align	4,0
++
++#endif /* CONFIG_SPE */
++
++/*
++ * Global functions
++ */
++
++/*
++ * extern void loadcam_entry(unsigned int index)
++ *
++ * Load TLBCAM[index] entry in to the L2 CAM MMU
++ */
++_GLOBAL(loadcam_entry)
++	lis	r4,TLBCAM at ha
++	addi	r4,r4,TLBCAM at l
++	mulli	r5,r3,20
++	add	r3,r5,r4
++	lwz	r4,0(r3)
++	mtspr	SPRN_MAS0,r4
++	lwz	r4,4(r3)
++	mtspr	SPRN_MAS1,r4
++	lwz	r4,8(r3)
++	mtspr	SPRN_MAS2,r4
++	lwz	r4,12(r3)
++	mtspr	SPRN_MAS3,r4
++	tlbwe
++	isync
++	blr
++
++/*
++ * extern void giveup_altivec(struct task_struct *prev)
++ *
++ * The e500 core does not have an AltiVec unit.
++ */
++_GLOBAL(giveup_altivec)
++	blr
++
++#ifdef CONFIG_SPE
++/*
++ * extern void giveup_spe(struct task_struct *prev)
++ *
++ */
++_GLOBAL(giveup_spe)
++	mfmsr	r5
++	oris	r5,r5,MSR_SPE at h
++	SYNC
++	mtmsr	r5			/* enable use of SPE now */
++	isync
++	cmpi	0,r3,0
++	beqlr-				/* if no previous owner, done */
++	addi	r3,r3,THREAD		/* want THREAD of task */
++	lwz	r5,PT_REGS(r3)
++	cmpi	0,r5,0
++	SAVE_32EVRS(0, r4, r3)
++   	evxor	evr6, evr6, evr6	/* clear out evr6 */
++	evmwumiaa evr6, evr6, evr6	/* evr6 <- ACC = 0 * 0 + ACC */
++	li	r4,THREAD_ACC
++   	evstddx	evr6, r4, r3		/* save off accumulator */
++	mfspr	r6,SPRN_SPEFSCR
++	stw	r6,THREAD_SPEFSCR(r3)	/* save spefscr register value */
++	beq	1f
++	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++	lis	r3,MSR_SPE at h
++	andc	r4,r4,r3		/* disable SPE for previous task */
++	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++1:
++#ifndef CONFIG_SMP
++	li	r5,0
++	lis	r4,last_task_used_spe at ha
++	stw	r5,last_task_used_spe at l(r4)
++#endif /* CONFIG_SMP */
++	blr
++#endif /* CONFIG_SPE */
++
++/*
++ * extern void giveup_fpu(struct task_struct *prev)
++ *
++ * Not all FSL Book-E cores have an FPU
++ */
++#ifndef CONFIG_PPC_FPU
++_GLOBAL(giveup_fpu)
++	blr
++#endif
++
++/*
++ * extern void abort(void)
++ *
++ * At present, this routine just applies a system reset.
++ */
++_GLOBAL(abort)
++	li	r13,0
++        mtspr   SPRN_DBCR0,r13		/* disable all debug events */
++	mfmsr	r13
++	ori	r13,r13,MSR_DE at l	/* Enable Debug Events */
++	mtmsr	r13
++        mfspr   r13,SPRN_DBCR0
++        lis	r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h
++        mtspr   SPRN_DBCR0,r13
++
++_GLOBAL(set_context)
++
++#ifdef CONFIG_BDI_SWITCH
++	/* Context switch the PTE pointer for the Abatron BDI2000.
++	 * The PGDIR is the second parameter.
++	 */
++	lis	r5, abatron_pteptrs at h
++	ori	r5, r5, abatron_pteptrs at l
++	stw	r4, 0x4(r5)
++#endif
++	mtspr	SPRN_PID,r3
++	isync			/* Force context change */
++	blr
++
++/*
++ * We put a few things here that have to be page-aligned. This stuff
++ * goes at the beginning of the data segment, which is page-aligned.
++ */
++	.data
++	.align	12
++	.globl	sdata
++sdata:
++	.globl	empty_zero_page
++empty_zero_page:
++	.space	4096
++	.globl	swapper_pg_dir
++swapper_pg_dir:
++	.space	4096
++
++/* Reserved 4k for the critical exception stack & 4k for the machine
++ * check stack per CPU for kernel mode exceptions */
++	.section .bss
++        .align 12
++exception_stack_bottom:
++	.space	BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
++	.globl	exception_stack_top
++exception_stack_top:
++
++/*
++ * This space gets a copy of optional info passed to us by the bootstrap
++ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
++ */
++	.globl	cmd_line
++cmd_line:
++	.space	512
++
++/*
++ * Room for two PTE pointers, usually the kernel and current user pointers
++ * to their respective root page table.
++ */
++abatron_pteptrs:
++	.space	8
+diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/idle_6xx.S
+@@ -0,0 +1,233 @@
++/*
++ *  This file contains the power_save function for 6xx & 7xxx CPUs
++ *  rewritten in assembler
++ *
++ *  Warning ! This code assumes that if your machine has a 750fx
++ *  it will have PLL 1 set to low speed mode (used during NAP/DOZE).
++ *  if this is not the case some additional changes will have to
++ *  be done to check a runtime var (a bit like powersave-nap)
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/threads.h>
++#include <asm/reg.h>
++#include <asm/page.h>
++#include <asm/cputable.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++
++#undef DEBUG
++
++	.text
++
++/*
++ * Init idle, called at early CPU setup time from head.S for each CPU
++ * Make sure no rest of NAP mode remains in HID0, save default
++ * values for some CPU specific registers. Called with r24
++ * containing CPU number and r3 reloc offset
++ */
++_GLOBAL(init_idle_6xx)
++BEGIN_FTR_SECTION
++	mfspr	r4,SPRN_HID0
++	rlwinm	r4,r4,0,10,8	/* Clear NAP */
++	mtspr	SPRN_HID0, r4
++	b	1f
++END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
++	blr
++1:
++	slwi	r5,r24,2
++	add	r5,r5,r3
++BEGIN_FTR_SECTION
++	mfspr	r4,SPRN_MSSCR0
++	addis	r6,r5, nap_save_msscr0 at ha
++	stw	r4,nap_save_msscr0 at l(r6)
++END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
++BEGIN_FTR_SECTION
++	mfspr	r4,SPRN_HID1
++	addis	r6,r5,nap_save_hid1 at ha
++	stw	r4,nap_save_hid1 at l(r6)
++END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
++	blr
++
++/*
++ * Here is the power_save_6xx function. This could eventually be
++ * split into several functions & changing the function pointer
++ * depending on the various features.
++ */
++_GLOBAL(ppc6xx_idle)
++	/* Check if we can nap or doze, put HID0 mask in r3
++	 */
++	lis	r3, 0
++BEGIN_FTR_SECTION
++	lis	r3,HID0_DOZE at h
++END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
++BEGIN_FTR_SECTION
++	/* We must dynamically check for the NAP feature as it
++	 * can be cleared by CPU init after the fixups are done
++	 */
++	lis	r4,cur_cpu_spec at ha
++	lwz	r4,cur_cpu_spec at l(r4)
++	lwz	r4,CPU_SPEC_FEATURES(r4)
++	andi.	r0,r4,CPU_FTR_CAN_NAP
++	beq	1f
++	/* Now check if user or arch enabled NAP mode */
++	lis	r4,powersave_nap at ha
++	lwz	r4,powersave_nap at l(r4)
++	cmpwi	0,r4,0
++	beq	1f
++	lis	r3,HID0_NAP at h
++1:	
++END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
++	cmpwi	0,r3,0
++	beqlr
++
++	/* Clear MSR:EE */
++	mfmsr	r7
++	rlwinm	r0,r7,0,17,15
++	mtmsr	r0
++
++	/* Check current_thread_info()->flags */
++	rlwinm	r4,r1,0,0,18
++	lwz	r4,TI_FLAGS(r4)
++	andi.	r0,r4,_TIF_NEED_RESCHED
++	beq	1f
++	mtmsr	r7	/* out of line this ? */
++	blr
++1:	
++	/* Some pre-nap cleanups needed on some CPUs */
++	andis.	r0,r3,HID0_NAP at h
++	beq	2f
++BEGIN_FTR_SECTION
++	/* Disable L2 prefetch on some 745x and try to ensure
++	 * L2 prefetch engines are idle. As explained by errata
++	 * text, we can't be sure they are, we just hope very hard
++	 * that well be enough (sic !). At least I noticed Apple
++	 * doesn't even bother doing the dcbf's here...
++	 */
++	mfspr	r4,SPRN_MSSCR0
++	rlwinm	r4,r4,0,0,29
++	sync
++	mtspr	SPRN_MSSCR0,r4
++	sync
++	isync
++	lis	r4,KERNELBASE at h
++	dcbf	0,r4
++	dcbf	0,r4
++	dcbf	0,r4
++	dcbf	0,r4
++END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
++#ifdef DEBUG
++	lis	r6,nap_enter_count at ha
++	lwz	r4,nap_enter_count at l(r6)
++	addi	r4,r4,1
++	stw	r4,nap_enter_count at l(r6)
++#endif	
++2:
++BEGIN_FTR_SECTION
++	/* Go to low speed mode on some 750FX */
++	lis	r4,powersave_lowspeed at ha
++	lwz	r4,powersave_lowspeed at l(r4)
++	cmpwi	0,r4,0
++	beq	1f
++	mfspr	r4,SPRN_HID1
++	oris	r4,r4,0x0001
++	mtspr	SPRN_HID1,r4
++1:	
++END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
++
++	/* Go to NAP or DOZE now */	
++	mfspr	r4,SPRN_HID0
++	lis	r5,(HID0_NAP|HID0_SLEEP)@h
++BEGIN_FTR_SECTION
++	oris	r5,r5,HID0_DOZE at h
++END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
++	andc	r4,r4,r5
++	or	r4,r4,r3
++BEGIN_FTR_SECTION
++	oris	r4,r4,HID0_DPM at h	/* that should be done once for all  */
++END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
++	mtspr	SPRN_HID0,r4
++BEGIN_FTR_SECTION
++	DSSALL
++	sync
++END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
++	ori	r7,r7,MSR_EE /* Could be ommited (already set) */
++	oris	r7,r7,MSR_POW at h
++	sync
++	isync
++	mtmsr	r7
++	isync
++	sync
++	blr
++	
++/*
++ * Return from NAP/DOZE mode, restore some CPU specific registers,
++ * we are called with DR/IR still off and r2 containing physical
++ * address of current.
++ */
++_GLOBAL(power_save_6xx_restore)
++	mfspr	r11,SPRN_HID0
++	rlwinm.	r11,r11,0,10,8	/* Clear NAP & copy NAP bit !state to cr1 EQ */
++	cror	4*cr1+eq,4*cr0+eq,4*cr0+eq
++BEGIN_FTR_SECTION
++	rlwinm	r11,r11,0,9,7	/* Clear DOZE */
++END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
++	mtspr	SPRN_HID0, r11
++
++#ifdef DEBUG
++	beq	cr1,1f
++	lis	r11,(nap_return_count-KERNELBASE)@ha
++	lwz	r9,nap_return_count at l(r11)
++	addi	r9,r9,1
++	stw	r9,nap_return_count at l(r11)
++1:
++#endif
++	
++	rlwinm	r9,r1,0,0,18
++	tophys(r9,r9)
++	lwz	r11,TI_CPU(r9)
++	slwi	r11,r11,2
++	/* Todo make sure all these are in the same page
++	 * and load r22 (@ha part + CPU offset) only once
++	 */
++BEGIN_FTR_SECTION
++	beq	cr1,1f
++	addis	r9,r11,(nap_save_msscr0-KERNELBASE)@ha
++	lwz	r9,nap_save_msscr0 at l(r9)
++	mtspr	SPRN_MSSCR0, r9
++	sync
++	isync
++1:
++END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
++BEGIN_FTR_SECTION
++	addis	r9,r11,(nap_save_hid1-KERNELBASE)@ha
++	lwz	r9,nap_save_hid1 at l(r9)
++	mtspr	SPRN_HID1, r9
++END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
++	b	transfer_to_handler_cont
++
++	.data
++
++_GLOBAL(nap_save_msscr0)
++	.space	4*NR_CPUS
++
++_GLOBAL(nap_save_hid1)
++	.space	4*NR_CPUS
++
++_GLOBAL(powersave_nap)
++	.long	0
++_GLOBAL(powersave_lowspeed)
++	.long	0
++
++#ifdef DEBUG
++_GLOBAL(nap_enter_count)
++	.space	4
++_GLOBAL(nap_return_count)
++	.space	4
++#endif
+diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/idle_power4.S
+@@ -0,0 +1,78 @@
++/*
++ *  This file contains the power_save function for 6xx & 7xxx CPUs
++ *  rewritten in assembler
++ *
++ *  Warning ! This code assumes that if your machine has a 750fx
++ *  it will have PLL 1 set to low speed mode (used during NAP/DOZE).
++ *  if this is not the case some additional changes will have to
++ *  be done to check a runtime var (a bit like powersave-nap)
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/threads.h>
++#include <asm/processor.h>
++#include <asm/page.h>
++#include <asm/cputable.h>
++#include <asm/thread_info.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++
++#undef DEBUG
++
++	.text
++
++/*
++ * Here is the power_save_6xx function. This could eventually be
++ * split into several functions & changing the function pointer
++ * depending on the various features.
++ */
++_GLOBAL(power4_idle)
++BEGIN_FTR_SECTION
++	blr
++END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
++	/* We must dynamically check for the NAP feature as it
++	 * can be cleared by CPU init after the fixups are done
++	 */
++	LOADBASE(r3,cur_cpu_spec)
++	ld	r4,OFF(cur_cpu_spec)(r3)
++	ld	r4,CPU_SPEC_FEATURES(r4)
++	andi.	r0,r4,CPU_FTR_CAN_NAP
++	beqlr
++	/* Now check if user or arch enabled NAP mode */
++	LOADBASE(r3,powersave_nap)
++	lwz	r4,OFF(powersave_nap)(r3)
++	cmpwi	0,r4,0
++	beqlr
++
++	/* Clear MSR:EE */
++	mfmsr	r7
++	li	r4,0
++	ori	r4,r4,MSR_EE
++	andc	r0,r7,r4
++	mtmsrd	r0
++
++	/* Check current_thread_info()->flags */
++	clrrdi	r4,r1,THREAD_SHIFT
++	ld	r4,TI_FLAGS(r4)
++	andi.	r0,r4,_TIF_NEED_RESCHED
++	beq	1f
++	mtmsrd	r7	/* out of line this ? */
++	blr
++1:
++	/* Go to NAP now */
++BEGIN_FTR_SECTION
++	DSSALL
++	sync
++END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
++	oris	r7,r7,MSR_POW at h
++	sync
++	isync
++	mtmsrd	r7
++	isync
++	sync
++	blr
+diff --git a/arch/powerpc/kernel/init_task.c b/arch/powerpc/kernel/init_task.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/init_task.c
+@@ -0,0 +1,36 @@
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/init.h>
++#include <linux/init_task.h>
++#include <linux/fs.h>
++#include <linux/mqueue.h>
++#include <asm/uaccess.h>
++
++static struct fs_struct init_fs = INIT_FS;
++static struct files_struct init_files = INIT_FILES;
++static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
++static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
++struct mm_struct init_mm = INIT_MM(init_mm);
++
++EXPORT_SYMBOL(init_mm);
++
++/*
++ * Initial thread structure.
++ *
++ * We need to make sure that this is 16384-byte aligned due to the
++ * way process stacks are handled. This is done by having a special
++ * "init_task" linker map entry..
++ */
++union thread_union init_thread_union 
++	__attribute__((__section__(".data.init_task"))) =
++		{ INIT_THREAD_INFO(init_task) };
++
++/*
++ * Initial task structure.
++ *
++ * All other task structs will be allocated on slabs in fork.c
++ */
++struct task_struct init_task = INIT_TASK(init_task);
++
++EXPORT_SYMBOL(init_task);
+diff --git a/arch/powerpc/kernel/lparmap.c b/arch/powerpc/kernel/lparmap.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/lparmap.c
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (C) 2005  Stephen Rothwell  IBM Corp.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <asm/mmu.h>
++#include <asm/page.h>
++#include <asm/iSeries/LparMap.h>
++
++const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
++	.xNumberEsids = HvEsidsToMap,
++	.xNumberRanges = HvRangesToMap,
++	.xSegmentTableOffs = STAB0_PAGE,
++
++	.xEsids = {
++		{ .xKernelEsid = GET_ESID(KERNELBASE),
++		  .xKernelVsid = KERNEL_VSID(KERNELBASE), },
++		{ .xKernelEsid = GET_ESID(VMALLOCBASE),
++		  .xKernelVsid = KERNEL_VSID(VMALLOCBASE), },
++	},
++
++	.xRanges = {
++		{ .xPages = HvPagesToMap,
++		  .xOffset = 0,
++		  .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT),
++		},
++	},
++};
+diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/misc_32.S
+@@ -0,0 +1,1037 @@
++/*
++ * This file contains miscellaneous low-level functions.
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ * Largely rewritten by Cort Dougan (cort at cs.nmt.edu)
++ * and Paul Mackerras.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/sys.h>
++#include <asm/unistd.h>
++#include <asm/errno.h>
++#include <asm/reg.h>
++#include <asm/page.h>
++#include <asm/cache.h>
++#include <asm/cputable.h>
++#include <asm/mmu.h>
++#include <asm/ppc_asm.h>
++#include <asm/thread_info.h>
++#include <asm/asm-offsets.h>
++
++	.text
++
++	.align	5
++_GLOBAL(__delay)
++	cmpwi	0,r3,0
++	mtctr	r3
++	beqlr
++1:	bdnz	1b
++	blr
++
++/*
++ * This returns the high 64 bits of the product of two 64-bit numbers.
++ */
++_GLOBAL(mulhdu)
++	cmpwi	r6,0
++	cmpwi	cr1,r3,0
++	mr	r10,r4
++	mulhwu	r4,r4,r5
++	beq	1f
++	mulhwu	r0,r10,r6
++	mullw	r7,r10,r5
++	addc	r7,r0,r7
++	addze	r4,r4
++1:	beqlr	cr1		/* all done if high part of A is 0 */
++	mr	r10,r3
++	mullw	r9,r3,r5
++	mulhwu	r3,r3,r5
++	beq	2f
++	mullw	r0,r10,r6
++	mulhwu	r8,r10,r6
++	addc	r7,r0,r7
++	adde	r4,r4,r8
++	addze	r3,r3
++2:	addc	r4,r4,r9
++	addze	r3,r3
++	blr
++
++/*
++ * Returns (address we're 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
++	LOADADDR(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
++	LOADADDR(r4,1b)
++	subf	r5,r4,r5
++	add	r3,r3,r5
++	mtlr	r0
++	blr
++
++/*
++ * sub_reloc_offset(x) returns x - reloc_offset().
++ */
++_GLOBAL(sub_reloc_offset)
++	mflr	r0
++	bl	1f
++1:	mflr	r5
++	lis	r4,1b at ha
++	addi	r4,r4,1b at l
++	subf	r5,r4,r5
++	subf	r3,r5,r3
++	mtlr	r0
++	blr
++
++/*
++ * reloc_got2 runs through the .got2 section adding an offset
++ * to each entry.
++ */
++_GLOBAL(reloc_got2)
++	mflr	r11
++	lis	r7,__got2_start at ha
++	addi	r7,r7,__got2_start at l
++	lis	r8,__got2_end at ha
++	addi	r8,r8,__got2_end at l
++	subf	r8,r7,r8
++	srwi.	r8,r8,2
++	beqlr
++	mtctr	r8
++	bl	1f
++1:	mflr	r0
++	lis	r4,1b at ha
++	addi	r4,r4,1b at l
++	subf	r0,r4,r0
++	add	r7,r0,r7
++2:	lwz	r0,0(r7)
++	add	r0,r0,r3
++	stw	r0,0(r7)
++	addi	r7,r7,4
++	bdnz	2b
++	mtlr	r11
++	blr
++
++/*
++ * identify_cpu,
++ * called with r3 = data offset and r4 = CPU number
++ * doesn't change r3
++ */
++_GLOBAL(identify_cpu)
++	addis	r8,r3,cpu_specs at ha
++	addi	r8,r8,cpu_specs at l
++	mfpvr	r7
++1:
++	lwz	r5,CPU_SPEC_PVR_MASK(r8)
++	and	r5,r5,r7
++	lwz	r6,CPU_SPEC_PVR_VALUE(r8)
++	cmplw	0,r6,r5
++	beq	1f
++	addi	r8,r8,CPU_SPEC_ENTRY_SIZE
++	b	1b
++1:
++	addis	r6,r3,cur_cpu_spec at ha
++	addi	r6,r6,cur_cpu_spec at l
++	sub	r8,r8,r3
++	stw	r8,0(r6)
++	blr
++
++/*
++ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
++ * and writes nop's over sections of code that don't apply for this cpu.
++ * r3 = data offset (not changed)
++ */
++_GLOBAL(do_cpu_ftr_fixups)
++	/* Get CPU 0 features */
++	addis	r6,r3,cur_cpu_spec at ha
++	addi	r6,r6,cur_cpu_spec at l
++	lwz	r4,0(r6)
++	add	r4,r4,r3
++	lwz	r4,CPU_SPEC_FEATURES(r4)
++
++	/* Get the fixup table */
++	addis	r6,r3,__start___ftr_fixup at ha
++	addi	r6,r6,__start___ftr_fixup at l
++	addis	r7,r3,__stop___ftr_fixup at ha
++	addi	r7,r7,__stop___ftr_fixup at l
++
++	/* Do the fixup */
++1:	cmplw	0,r6,r7
++	bgelr
++	addi	r6,r6,16
++	lwz	r8,-16(r6)	/* mask */
++	and	r8,r8,r4
++	lwz	r9,-12(r6)	/* value */
++	cmplw	0,r8,r9
++	beq	1b
++	lwz	r8,-8(r6)	/* section begin */
++	lwz	r9,-4(r6)	/* section end */
++	subf.	r9,r8,r9
++	beq	1b
++	/* write nops over the section of code */
++	/* todo: if large section, add a branch at the start of it */
++	srwi	r9,r9,2
++	mtctr	r9
++	add	r8,r8,r3
++	lis	r0,0x60000000 at h	/* nop */
++3:	stw	r0,0(r8)
++	andi.	r10,r4,CPU_FTR_SPLIT_ID_CACHE at l
++	beq	2f
++	dcbst	0,r8		/* suboptimal, but simpler */
++	sync
++	icbi	0,r8
++2:	addi	r8,r8,4
++	bdnz	3b
++	sync			/* additional sync needed on g4 */
++	isync
++	b	1b
++
++/*
++ * call_setup_cpu - call the setup_cpu function for this cpu
++ * r3 = data offset, r24 = cpu number
++ *
++ * Setup function is called with:
++ *   r3 = data offset
++ *   r4 = ptr to CPU spec (relocated)
++ */
++_GLOBAL(call_setup_cpu)
++	addis	r4,r3,cur_cpu_spec at ha
++	addi	r4,r4,cur_cpu_spec at l
++	lwz	r4,0(r4)
++	add	r4,r4,r3
++	lwz	r5,CPU_SPEC_SETUP(r4)
++	cmpi	0,r5,0
++	add	r5,r5,r3
++	beqlr
++	mtctr	r5
++	bctr
++
++#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
++
++/* This gets called by via-pmu.c to switch the PLL selection
++ * on 750fx CPU. This function should really be moved to some
++ * other place (as most of the cpufreq code in via-pmu
++ */
++_GLOBAL(low_choose_750fx_pll)
++	/* Clear MSR:EE */
++	mfmsr	r7
++	rlwinm	r0,r7,0,17,15
++	mtmsr	r0
++
++	/* If switching to PLL1, disable HID0:BTIC */
++	cmplwi	cr0,r3,0
++	beq	1f
++	mfspr	r5,SPRN_HID0
++	rlwinm	r5,r5,0,27,25
++	sync
++	mtspr	SPRN_HID0,r5
++	isync
++	sync
++
++1:
++	/* Calc new HID1 value */
++	mfspr	r4,SPRN_HID1	/* Build a HID1:PS bit from parameter */
++	rlwinm	r5,r3,16,15,15	/* Clear out HID1:PS from value read */
++	rlwinm	r4,r4,0,16,14	/* Could have I used rlwimi here ? */
++	or	r4,r4,r5
++	mtspr	SPRN_HID1,r4
++
++	/* Store new HID1 image */
++	rlwinm	r6,r1,0,0,18
++	lwz	r6,TI_CPU(r6)
++	slwi	r6,r6,2
++	addis	r6,r6,nap_save_hid1 at ha
++	stw	r4,nap_save_hid1 at l(r6)
++
++	/* If switching to PLL0, enable HID0:BTIC */
++	cmplwi	cr0,r3,0
++	bne	1f
++	mfspr	r5,SPRN_HID0
++	ori	r5,r5,HID0_BTIC
++	sync
++	mtspr	SPRN_HID0,r5
++	isync
++	sync
++
++1:
++	/* Return */
++	mtmsr	r7
++	blr
++
++_GLOBAL(low_choose_7447a_dfs)
++	/* Clear MSR:EE */
++	mfmsr	r7
++	rlwinm	r0,r7,0,17,15
++	mtmsr	r0
++	
++	/* Calc new HID1 value */
++	mfspr	r4,SPRN_HID1
++	insrwi	r4,r3,1,9	/* insert parameter into bit 9 */
++	sync
++	mtspr	SPRN_HID1,r4
++	sync
++	isync
++
++	/* Return */
++	mtmsr	r7
++	blr
++
++#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
++
++/*
++ * complement mask on the msr then "or" some values on.
++ *     _nmask_and_or_msr(nmask, value_to_or)
++ */
++_GLOBAL(_nmask_and_or_msr)
++	mfmsr	r0		/* Get current msr */
++	andc	r0,r0,r3	/* And off the bits set in r3 (first parm) */
++	or	r0,r0,r4	/* Or on the bits in r4 (second parm) */
++	SYNC			/* Some chip revs have problems here... */
++	mtmsr	r0		/* Update machine state */
++	isync
++	blr			/* Done */
++
++
++/*
++ * Flush MMU TLB
++ */
++_GLOBAL(_tlbia)
++#if defined(CONFIG_40x)
++	sync			/* Flush to memory before changing mapping */
++	tlbia
++	isync			/* Flush shadow TLB */
++#elif defined(CONFIG_44x)
++	li	r3,0
++	sync
++
++	/* Load high watermark */
++	lis	r4,tlb_44x_hwater at ha
++	lwz	r5,tlb_44x_hwater at l(r4)
++
++1:	tlbwe	r3,r3,PPC44x_TLB_PAGEID
++	addi	r3,r3,1
++	cmpw	0,r3,r5
++	ble	1b
++
++	isync
++#elif defined(CONFIG_FSL_BOOKE)
++	/* Invalidate all entries in TLB0 */
++	li	r3, 0x04
++	tlbivax	0,3
++	/* Invalidate all entries in TLB1 */
++	li	r3, 0x0c
++	tlbivax	0,3
++	/* Invalidate all entries in TLB2 */
++	li	r3, 0x14
++	tlbivax	0,3
++	/* Invalidate all entries in TLB3 */
++	li	r3, 0x1c
++	tlbivax	0,3
++	msync
++#ifdef CONFIG_SMP
++	tlbsync
++#endif /* CONFIG_SMP */
++#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
++#if defined(CONFIG_SMP)
++	rlwinm	r8,r1,0,0,18
++	lwz	r8,TI_CPU(r8)
++	oris	r8,r8,10
++	mfmsr	r10
++	SYNC
++	rlwinm	r0,r10,0,17,15		/* clear bit 16 (MSR_EE) */
++	rlwinm	r0,r0,0,28,26		/* clear DR */
++	mtmsr	r0
++	SYNC_601
++	isync
++	lis	r9,mmu_hash_lock at h
++	ori	r9,r9,mmu_hash_lock at l
++	tophys(r9,r9)
++10:	lwarx	r7,0,r9
++	cmpwi	0,r7,0
++	bne-	10b
++	stwcx.	r8,0,r9
++	bne-	10b
++	sync
++	tlbia
++	sync
++	TLBSYNC
++	li	r0,0
++	stw	r0,0(r9)		/* clear mmu_hash_lock */
++	mtmsr	r10
++	SYNC_601
++	isync
++#else /* CONFIG_SMP */
++	sync
++	tlbia
++	sync
++#endif /* CONFIG_SMP */
++#endif /* ! defined(CONFIG_40x) */
++	blr
++
++/*
++ * Flush MMU TLB for a particular address
++ */
++_GLOBAL(_tlbie)
++#if defined(CONFIG_40x)
++	tlbsx.	r3, 0, r3
++	bne	10f
++	sync
++	/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
++	 * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate
++	 * the TLB entry. */
++	tlbwe	r3, r3, TLB_TAG
++	isync
++10:
++#elif defined(CONFIG_44x)
++	mfspr	r4,SPRN_MMUCR
++	mfspr	r5,SPRN_PID			/* Get PID */
++	rlwimi	r4,r5,0,24,31			/* Set TID */
++	mtspr	SPRN_MMUCR,r4
++
++	tlbsx.	r3, 0, r3
++	bne	10f
++	sync
++	/* There are only 64 TLB entries, so r3 < 64,
++	 * which means bit 22, is clear.  Since 22 is
++	 * the V bit in the TLB_PAGEID, loading this
++	 * value will invalidate the TLB entry.
++	 */
++	tlbwe	r3, r3, PPC44x_TLB_PAGEID
++	isync
++10:
++#elif defined(CONFIG_FSL_BOOKE)
++	rlwinm	r4, r3, 0, 0, 19
++	ori	r5, r4, 0x08	/* TLBSEL = 1 */
++	ori	r6, r4, 0x10	/* TLBSEL = 2 */
++	ori	r7, r4, 0x18	/* TLBSEL = 3 */
++	tlbivax	0, r4
++	tlbivax	0, r5
++	tlbivax	0, r6
++	tlbivax	0, r7
++	msync
++#if defined(CONFIG_SMP)
++	tlbsync
++#endif /* CONFIG_SMP */
++#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
++#if defined(CONFIG_SMP)
++	rlwinm	r8,r1,0,0,18
++	lwz	r8,TI_CPU(r8)
++	oris	r8,r8,11
++	mfmsr	r10
++	SYNC
++	rlwinm	r0,r10,0,17,15		/* clear bit 16 (MSR_EE) */
++	rlwinm	r0,r0,0,28,26		/* clear DR */
++	mtmsr	r0
++	SYNC_601
++	isync
++	lis	r9,mmu_hash_lock at h
++	ori	r9,r9,mmu_hash_lock at l
++	tophys(r9,r9)
++10:	lwarx	r7,0,r9
++	cmpwi	0,r7,0
++	bne-	10b
++	stwcx.	r8,0,r9
++	bne-	10b
++	eieio
++	tlbie	r3
++	sync
++	TLBSYNC
++	li	r0,0
++	stw	r0,0(r9)		/* clear mmu_hash_lock */
++	mtmsr	r10
++	SYNC_601
++	isync
++#else /* CONFIG_SMP */
++	tlbie	r3
++	sync
++#endif /* CONFIG_SMP */
++#endif /* ! CONFIG_40x */
++	blr
++
++/*
++ * Flush instruction cache.
++ * This is a no-op on the 601.
++ */
++_GLOBAL(flush_instruction_cache)
++#if defined(CONFIG_8xx)
++	isync
++	lis	r5, IDC_INVALL at h
++	mtspr	SPRN_IC_CST, r5
++#elif defined(CONFIG_4xx)
++#ifdef CONFIG_403GCX
++	li      r3, 512
++	mtctr   r3
++	lis     r4, KERNELBASE at h
++1:	iccci   0, r4
++	addi    r4, r4, 16
++	bdnz    1b
++#else
++	lis	r3, KERNELBASE at h
++	iccci	0,r3
++#endif
++#elif CONFIG_FSL_BOOKE
++BEGIN_FTR_SECTION
++	mfspr   r3,SPRN_L1CSR0
++	ori     r3,r3,L1CSR0_CFI|L1CSR0_CLFC
++	/* msync; isync recommended here */
++	mtspr   SPRN_L1CSR0,r3
++	isync
++	blr
++END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
++	mfspr	r3,SPRN_L1CSR1
++	ori	r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
++	mtspr	SPRN_L1CSR1,r3
++#else
++	mfspr	r3,SPRN_PVR
++	rlwinm	r3,r3,16,16,31
++	cmpwi	0,r3,1
++	beqlr			/* for 601, do nothing */
++	/* 603/604 processor - use invalidate-all bit in HID0 */
++	mfspr	r3,SPRN_HID0
++	ori	r3,r3,HID0_ICFI
++	mtspr	SPRN_HID0,r3
++#endif /* CONFIG_8xx/4xx */
++	isync
++	blr
++
++/*
++ * Write any modified data cache blocks out to memory
++ * and invalidate the corresponding instruction cache blocks.
++ * This is a no-op on the 601.
++ *
++ * flush_icache_range(unsigned long start, unsigned long stop)
++ */
++_GLOBAL(flush_icache_range)
++BEGIN_FTR_SECTION
++	blr				/* for 601, do nothing */
++END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
++	li	r5,L1_CACHE_BYTES-1
++	andc	r3,r3,r5
++	subf	r4,r3,r4
++	add	r4,r4,r5
++	srwi.	r4,r4,L1_CACHE_SHIFT
++	beqlr
++	mtctr	r4
++	mr	r6,r3
++1:	dcbst	0,r3
++	addi	r3,r3,L1_CACHE_BYTES
++	bdnz	1b
++	sync				/* wait for dcbst's to get to ram */
++	mtctr	r4
++2:	icbi	0,r6
++	addi	r6,r6,L1_CACHE_BYTES
++	bdnz	2b
++	sync				/* additional sync needed on g4 */
++	isync
++	blr
++/*
++ * Write any modified data cache blocks out to memory.
++ * Does not invalidate the corresponding cache lines (especially for
++ * any corresponding instruction cache).
++ *
++ * clean_dcache_range(unsigned long start, unsigned long stop)
++ */
++_GLOBAL(clean_dcache_range)
++	li	r5,L1_CACHE_BYTES-1
++	andc	r3,r3,r5
++	subf	r4,r3,r4
++	add	r4,r4,r5
++	srwi.	r4,r4,L1_CACHE_SHIFT
++	beqlr
++	mtctr	r4
++
++1:	dcbst	0,r3
++	addi	r3,r3,L1_CACHE_BYTES
++	bdnz	1b
++	sync				/* wait for dcbst's to get to ram */
++	blr
++
++/*
++ * Write any modified data cache blocks out to memory and invalidate them.
++ * Does not invalidate the corresponding instruction cache blocks.
++ *
++ * flush_dcache_range(unsigned long start, unsigned long stop)
++ */
++_GLOBAL(flush_dcache_range)
++	li	r5,L1_CACHE_BYTES-1
++	andc	r3,r3,r5
++	subf	r4,r3,r4
++	add	r4,r4,r5
++	srwi.	r4,r4,L1_CACHE_SHIFT
++	beqlr
++	mtctr	r4
++
++1:	dcbf	0,r3
++	addi	r3,r3,L1_CACHE_BYTES
++	bdnz	1b
++	sync				/* wait for dcbst's to get to ram */
++	blr
++
++/*
++ * Like above, but invalidate the D-cache.  This is used by the 8xx
++ * to invalidate the cache so the PPC core doesn't get stale data
++ * from the CPM (no cache snooping here :-).
++ *
++ * invalidate_dcache_range(unsigned long start, unsigned long stop)
++ */
++_GLOBAL(invalidate_dcache_range)
++	li	r5,L1_CACHE_BYTES-1
++	andc	r3,r3,r5
++	subf	r4,r3,r4
++	add	r4,r4,r5
++	srwi.	r4,r4,L1_CACHE_SHIFT
++	beqlr
++	mtctr	r4
++
++1:	dcbi	0,r3
++	addi	r3,r3,L1_CACHE_BYTES
++	bdnz	1b
++	sync				/* wait for dcbi's to get to ram */
++	blr
++
++#ifdef CONFIG_NOT_COHERENT_CACHE
++/*
++ * 40x cores have 8K or 16K dcache and 32 byte line size.
++ * 44x has a 32K dcache and 32 byte line size.
++ * 8xx has 1, 2, 4, 8K variants.
++ * For now, cover the worst case of the 44x.
++ * Must be called with external interrupts disabled.
++ */
++#define CACHE_NWAYS	64
++#define CACHE_NLINES	16
++
++_GLOBAL(flush_dcache_all)
++	li	r4, (2 * CACHE_NWAYS * CACHE_NLINES)
++	mtctr	r4
++	lis     r5, KERNELBASE at h
++1:	lwz	r3, 0(r5)		/* Load one word from every line */
++	addi	r5, r5, L1_CACHE_BYTES
++	bdnz    1b
++	blr
++#endif /* CONFIG_NOT_COHERENT_CACHE */
++
++/*
++ * Flush a particular page from the data cache to RAM.
++ * Note: this is necessary because the instruction cache does *not*
++ * snoop from the data cache.
++ * This is a no-op on the 601 which has a unified cache.
++ *
++ *	void __flush_dcache_icache(void *page)
++ */
++_GLOBAL(__flush_dcache_icache)
++BEGIN_FTR_SECTION
++	blr					/* for 601, do nothing */
++END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
++	rlwinm	r3,r3,0,0,19			/* Get page base address */
++	li	r4,4096/L1_CACHE_BYTES	/* Number of lines in a page */
++	mtctr	r4
++	mr	r6,r3
++0:	dcbst	0,r3				/* Write line to ram */
++	addi	r3,r3,L1_CACHE_BYTES
++	bdnz	0b
++	sync
++	mtctr	r4
++1:	icbi	0,r6
++	addi	r6,r6,L1_CACHE_BYTES
++	bdnz	1b
++	sync
++	isync
++	blr
++
++/*
++ * Flush a particular page from the data cache to RAM, identified
++ * by its physical address.  We turn off the MMU so we can just use
++ * the physical address (this may be a highmem page without a kernel
++ * mapping).
++ *
++ *	void __flush_dcache_icache_phys(unsigned long physaddr)
++ */
++_GLOBAL(__flush_dcache_icache_phys)
++BEGIN_FTR_SECTION
++	blr					/* for 601, do nothing */
++END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
++	mfmsr	r10
++	rlwinm	r0,r10,0,28,26			/* clear DR */
++	mtmsr	r0
++	isync
++	rlwinm	r3,r3,0,0,19			/* Get page base address */
++	li	r4,4096/L1_CACHE_BYTES	/* Number of lines in a page */
++	mtctr	r4
++	mr	r6,r3
++0:	dcbst	0,r3				/* Write line to ram */
++	addi	r3,r3,L1_CACHE_BYTES
++	bdnz	0b
++	sync
++	mtctr	r4
++1:	icbi	0,r6
++	addi	r6,r6,L1_CACHE_BYTES
++	bdnz	1b
++	sync
++	mtmsr	r10				/* restore DR */
++	isync
++	blr
++
++/*
++ * Clear pages using the dcbz instruction, which doesn't cause any
++ * memory traffic (except to write out any cache lines which get
++ * displaced).  This only works on cacheable memory.
++ *
++ * void clear_pages(void *page, int order) ;
++ */
++_GLOBAL(clear_pages)
++	li	r0,4096/L1_CACHE_BYTES
++	slw	r0,r0,r4
++	mtctr	r0
++#ifdef CONFIG_8xx
++	li	r4, 0
++1:	stw	r4, 0(r3)
++	stw	r4, 4(r3)
++	stw	r4, 8(r3)
++	stw	r4, 12(r3)
++#else
++1:	dcbz	0,r3
++#endif
++	addi	r3,r3,L1_CACHE_BYTES
++	bdnz	1b
++	blr
++
++/*
++ * Copy a whole page.  We use the dcbz instruction on the destination
++ * to reduce memory traffic (it eliminates the unnecessary reads of
++ * the destination into cache).  This requires that the destination
++ * is cacheable.
++ */
++#define COPY_16_BYTES		\
++	lwz	r6,4(r4);	\
++	lwz	r7,8(r4);	\
++	lwz	r8,12(r4);	\
++	lwzu	r9,16(r4);	\
++	stw	r6,4(r3);	\
++	stw	r7,8(r3);	\
++	stw	r8,12(r3);	\
++	stwu	r9,16(r3)
++
++_GLOBAL(copy_page)
++	addi	r3,r3,-4
++	addi	r4,r4,-4
++
++#ifdef CONFIG_8xx
++	/* don't use prefetch on 8xx */
++    	li	r0,4096/L1_CACHE_BYTES
++	mtctr	r0
++1:	COPY_16_BYTES
++	bdnz	1b
++	blr
++
++#else	/* not 8xx, we can prefetch */
++	li	r5,4
++
++#if MAX_COPY_PREFETCH > 1
++	li	r0,MAX_COPY_PREFETCH
++	li	r11,4
++	mtctr	r0
++11:	dcbt	r11,r4
++	addi	r11,r11,L1_CACHE_BYTES
++	bdnz	11b
++#else /* MAX_COPY_PREFETCH == 1 */
++	dcbt	r5,r4
++	li	r11,L1_CACHE_BYTES+4
++#endif /* MAX_COPY_PREFETCH */
++	li	r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH
++	crclr	4*cr0+eq
++2:
++	mtctr	r0
++1:
++	dcbt	r11,r4
++	dcbz	r5,r3
++	COPY_16_BYTES
++#if L1_CACHE_BYTES >= 32
++	COPY_16_BYTES
++#if L1_CACHE_BYTES >= 64
++	COPY_16_BYTES
++	COPY_16_BYTES
++#if L1_CACHE_BYTES >= 128
++	COPY_16_BYTES
++	COPY_16_BYTES
++	COPY_16_BYTES
++	COPY_16_BYTES
++#endif
++#endif
++#endif
++	bdnz	1b
++	beqlr
++	crnot	4*cr0+eq,4*cr0+eq
++	li	r0,MAX_COPY_PREFETCH
++	li	r11,4
++	b	2b
++#endif	/* CONFIG_8xx */
++
++/*
++ * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
++ * void atomic_set_mask(atomic_t mask, atomic_t *addr);
++ */
++_GLOBAL(atomic_clear_mask)
++10:	lwarx	r5,0,r4
++	andc	r5,r5,r3
++	PPC405_ERR77(0,r4)
++	stwcx.	r5,0,r4
++	bne-	10b
++	blr
++_GLOBAL(atomic_set_mask)
++10:	lwarx	r5,0,r4
++	or	r5,r5,r3
++	PPC405_ERR77(0,r4)
++	stwcx.	r5,0,r4
++	bne-	10b
++	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)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,1
++	blelr-
++00:	lbz	r5,0(r3)
++	eieio
++	stbu	r5,1(r4)
++	bdnz	00b
++	blr
++
++_GLOBAL(_outsb)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,1
++	blelr-
++00:	lbzu	r5,1(r4)
++	stb	r5,0(r3)
++	eieio
++	bdnz	00b
++	blr
++
++_GLOBAL(_insw)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,2
++	blelr-
++00:	lhbrx	r5,0,r3
++	eieio
++	sthu	r5,2(r4)
++	bdnz	00b
++	blr
++
++_GLOBAL(_outsw)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,2
++	blelr-
++00:	lhzu	r5,2(r4)
++	eieio
++	sthbrx	r5,0,r3
++	bdnz	00b
++	blr
++
++_GLOBAL(_insl)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,4
++	blelr-
++00:	lwbrx	r5,0,r3
++	eieio
++	stwu	r5,4(r4)
++	bdnz	00b
++	blr
++
++_GLOBAL(_outsl)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,4
++	blelr-
++00:	lwzu	r5,4(r4)
++	stwbrx	r5,0,r3
++	eieio
++	bdnz	00b
++	blr
++
++_GLOBAL(__ide_mm_insw)
++_GLOBAL(_insw_ns)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,2
++	blelr-
++00:	lhz	r5,0(r3)
++	eieio
++	sthu	r5,2(r4)
++	bdnz	00b
++	blr
++
++_GLOBAL(__ide_mm_outsw)
++_GLOBAL(_outsw_ns)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,2
++	blelr-
++00:	lhzu	r5,2(r4)
++	sth	r5,0(r3)
++	eieio
++	bdnz	00b
++	blr
++
++_GLOBAL(__ide_mm_insl)
++_GLOBAL(_insl_ns)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,4
++	blelr-
++00:	lwz	r5,0(r3)
++	eieio
++	stwu	r5,4(r4)
++	bdnz	00b
++	blr
++
++_GLOBAL(__ide_mm_outsl)
++_GLOBAL(_outsl_ns)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,4
++	blelr-
++00:	lwzu	r5,4(r4)
++	stw	r5,0(r3)
++	eieio
++	bdnz	00b
++	blr
++
++/*
++ * Extended precision shifts.
++ *
++ * Updated to be valid for shift counts from 0 to 63 inclusive.
++ * -- Gabriel
++ *
++ * R3/R4 has 64 bit value
++ * R5    has shift count
++ * result in R3/R4
++ *
++ *  ashrdi3: arithmetic right shift (sign propagation)	
++ *  lshrdi3: logical right shift
++ *  ashldi3: left shift
++ */
++_GLOBAL(__ashrdi3)
++	subfic	r6,r5,32
++	srw	r4,r4,r5	# LSW = count > 31 ? 0 : LSW >> count
++	addi	r7,r5,32	# could be xori, or addi with -32
++	slw	r6,r3,r6	# t1 = count > 31 ? 0 : MSW << (32-count)
++	rlwinm	r8,r7,0,32	# t3 = (count < 32) ? 32 : 0
++	sraw	r7,r3,r7	# t2 = MSW >> (count-32)
++	or	r4,r4,r6	# LSW |= t1
++	slw	r7,r7,r8	# t2 = (count < 32) ? 0 : t2
++	sraw	r3,r3,r5	# MSW = MSW >> count
++	or	r4,r4,r7	# LSW |= t2
++	blr
++
++_GLOBAL(__ashldi3)
++	subfic	r6,r5,32
++	slw	r3,r3,r5	# MSW = count > 31 ? 0 : MSW << count
++	addi	r7,r5,32	# could be xori, or addi with -32
++	srw	r6,r4,r6	# t1 = count > 31 ? 0 : LSW >> (32-count)
++	slw	r7,r4,r7	# t2 = count < 32 ? 0 : LSW << (count-32)
++	or	r3,r3,r6	# MSW |= t1
++	slw	r4,r4,r5	# LSW = LSW << count
++	or	r3,r3,r7	# MSW |= t2
++	blr
++
++_GLOBAL(__lshrdi3)
++	subfic	r6,r5,32
++	srw	r4,r4,r5	# LSW = count > 31 ? 0 : LSW >> count
++	addi	r7,r5,32	# could be xori, or addi with -32
++	slw	r6,r3,r6	# t1 = count > 31 ? 0 : MSW << (32-count)
++	srw	r7,r3,r7	# t2 = count < 32 ? 0 : MSW >> (count-32)
++	or	r4,r4,r6	# LSW |= t1
++	srw	r3,r3,r5	# MSW = MSW >> count
++	or	r4,r4,r7	# LSW |= t2
++	blr
++
++_GLOBAL(abs)
++	srawi	r4,r3,31
++	xor	r3,r3,r4
++	sub	r3,r3,r4
++	blr
++
++_GLOBAL(_get_SP)
++	mr	r3,r1		/* Close enough */
++	blr
++
++/*
++ * Create a kernel thread
++ *   kernel_thread(fn, arg, flags)
++ */
++_GLOBAL(kernel_thread)
++	stwu	r1,-16(r1)
++	stw	r30,8(r1)
++	stw	r31,12(r1)
++	mr	r30,r3		/* function */
++	mr	r31,r4		/* argument */
++	ori	r3,r5,CLONE_VM	/* flags */
++	oris	r3,r3,CLONE_UNTRACED>>16
++	li	r4,0		/* new sp (unused) */
++	li	r0,__NR_clone
++	sc
++	cmpwi	0,r3,0		/* parent or child? */
++	bne	1f		/* return if parent */
++	li	r0,0		/* make top-level stack frame */
++	stwu	r0,-16(r1)
++	mtlr	r30		/* fn addr in lr */
++	mr	r3,r31		/* load arg and call fn */
++	PPC440EP_ERR42
++	blrl
++	li	r0,__NR_exit	/* exit if function returns */
++	li	r3,0
++	sc
++1:	lwz	r30,8(r1)
++	lwz	r31,12(r1)
++	addi	r1,r1,16
++	blr
++
++_GLOBAL(execve)
++	li	r0,__NR_execve
++	sc
++	bnslr
++	neg	r3,r3
++	blr
++
++/*
++ * This routine is just here to keep GCC happy - sigh...
++ */
++_GLOBAL(__main)
++	blr
+diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/misc_64.S
+@@ -0,0 +1,880 @@
++/*
++ *  arch/powerpc/kernel/misc64.S
++ *
++ * This file contains miscellaneous low-level functions.
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ * Largely rewritten by Cort Dougan (cort at cs.nmt.edu)
++ * and Paul Mackerras.
++ * Adapted for iSeries by Mike Corrigan (mikejc at us.ibm.com)
++ * PPC64 updates by Dave Engebretsen (engebret at 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 <linux/config.h>
++#include <linux/sys.h>
++#include <asm/unistd.h>
++#include <asm/errno.h>
++#include <asm/processor.h>
++#include <asm/page.h>
++#include <asm/cache.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++#include <asm/cputable.h>
++#include <asm/thread_info.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
++	LOADADDR(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
++	LOADADDR(r4,1b)
++	subf	r5,r4,r5
++	add	r3,r3,r5
++	mtlr	r0
++	blr
++
++_GLOBAL(get_msr)
++	mfmsr	r3
++	blr
++
++_GLOBAL(get_dar)
++	mfdar	r3
++	blr
++
++_GLOBAL(get_srr0)
++	mfsrr0  r3
++	blr
++
++_GLOBAL(get_srr1)
++	mfsrr1  r3
++	blr
++	
++_GLOBAL(get_sp)
++	mr	r3,r1
++	blr
++
++#ifdef CONFIG_IRQSTACKS
++_GLOBAL(call_do_softirq)
++	mflr	r0
++	std	r0,16(r1)
++	stdu	r1,THREAD_SIZE-112(r3)
++	mr	r1,r3
++	bl	.__do_softirq
++	ld	r1,0(r1)
++	ld	r0,16(r1)
++	mtlr	r0
++	blr
++
++_GLOBAL(call_handle_IRQ_event)
++	mflr	r0
++	std	r0,16(r1)
++	stdu	r1,THREAD_SIZE-112(r6)
++	mr	r1,r6
++	bl	.handle_IRQ_event
++	ld	r1,0(r1)
++	ld	r0,16(r1)
++	mtlr	r0
++	blr
++#endif /* CONFIG_IRQSTACKS */
++
++	/*
++ * To be called by C code which needs to do some operations with MMU
++ * disabled. Note that interrupts have to be disabled by the caller
++ * prior to calling us. The code called _MUST_ be in the RMO of course
++ * and part of the linear mapping as we don't attempt to translate the
++ * stack pointer at all. The function is called with the stack switched
++ * to this CPU emergency stack
++ *
++ * prototype is void *call_with_mmu_off(void *func, void *data);
++ *
++ * the called function is expected to be of the form
++ *
++ * void *called(void *data); 
++ */
++_GLOBAL(call_with_mmu_off)
++	mflr	r0			/* get link, save it on stackframe */
++	std	r0,16(r1)
++	mr	r1,r5			/* save old stack ptr */
++	ld	r1,PACAEMERGSP(r13)	/* get emerg. stack */
++	subi	r1,r1,STACK_FRAME_OVERHEAD
++	std	r0,16(r1)		/* save link on emerg. stack */
++	std	r5,0(r1)		/* save old stack ptr in backchain */
++	ld	r3,0(r3)		/* get to real function ptr (assume same TOC) */
++	bl	2f			/* we need LR to return, continue at label 2 */
++
++	ld	r0,16(r1)		/* we return here from the call, get LR and */
++	ld	r1,0(r1)		/* .. old stack ptr */
++	mtspr	SPRN_SRR0,r0		/* and get back to virtual mode with these */
++	mfmsr	r4
++	ori	r4,r4,MSR_IR|MSR_DR
++	mtspr	SPRN_SRR1,r4
++	rfid
++
++2:	mtspr	SPRN_SRR0,r3		/* coming from above, enter real mode */
++	mr	r3,r4			/* get parameter */
++	mfmsr	r0
++	ori	r0,r0,MSR_IR|MSR_DR
++	xori	r0,r0,MSR_IR|MSR_DR
++	mtspr	SPRN_SRR1,r0
++	rfid
++
++
++	.section	".toc","aw"
++PPC64_CACHES:
++	.tc		ppc64_caches[TC],ppc64_caches
++	.section	".text"
++
++/*
++ * Write any modified data cache blocks out to memory
++ * and invalidate the corresponding instruction cache blocks.
++ *
++ * flush_icache_range(unsigned long start, unsigned long stop)
++ *
++ *   flush all bytes from start through stop-1 inclusive
++ */
++
++_KPROBE(__flush_icache_range)
++
++/*
++ * Flush the data cache to memory 
++ * 
++ * Different systems have different cache line sizes
++ * and in some cases i-cache and d-cache line sizes differ from
++ * each other.
++ */
++ 	ld	r10,PPC64_CACHES at toc(r2)
++	lwz	r7,DCACHEL1LINESIZE(r10)/* Get cache line size */
++	addi	r5,r7,-1
++	andc	r6,r3,r5		/* round low to line bdy */
++	subf	r8,r6,r4		/* compute length */
++	add	r8,r8,r5		/* ensure we get enough */
++	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of cache line size */
++	srw.	r8,r8,r9		/* compute line count */
++	beqlr				/* nothing to do? */
++	mtctr	r8
++1:	dcbst	0,r6
++	add	r6,r6,r7
++	bdnz	1b
++	sync
++
++/* Now invalidate the instruction cache */
++	
++	lwz	r7,ICACHEL1LINESIZE(r10)	/* Get Icache line size */
++	addi	r5,r7,-1
++	andc	r6,r3,r5		/* round low to line bdy */
++	subf	r8,r6,r4		/* compute length */
++	add	r8,r8,r5
++	lwz	r9,ICACHEL1LOGLINESIZE(r10)	/* Get log-2 of Icache line size */
++	srw.	r8,r8,r9		/* compute line count */
++	beqlr				/* nothing to do? */
++	mtctr	r8
++2:	icbi	0,r6
++	add	r6,r6,r7
++	bdnz	2b
++	isync
++	blr
++	.previous .text
++/*
++ * Like above, but only do the D-cache.
++ *
++ * flush_dcache_range(unsigned long start, unsigned long stop)
++ *
++ *    flush all bytes from start to stop-1 inclusive
++ */
++_GLOBAL(flush_dcache_range)
++
++/*
++ * Flush the data cache to memory 
++ * 
++ * Different systems have different cache line sizes
++ */
++ 	ld	r10,PPC64_CACHES at toc(r2)
++	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
++	addi	r5,r7,-1
++	andc	r6,r3,r5		/* round low to line bdy */
++	subf	r8,r6,r4		/* compute length */
++	add	r8,r8,r5		/* ensure we get enough */
++	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */
++	srw.	r8,r8,r9		/* compute line count */
++	beqlr				/* nothing to do? */
++	mtctr	r8
++0:	dcbst	0,r6
++	add	r6,r6,r7
++	bdnz	0b
++	sync
++	blr
++
++/*
++ * Like above, but works on non-mapped physical addresses.
++ * Use only for non-LPAR setups ! It also assumes real mode
++ * is cacheable. Used for flushing out the DART before using
++ * it as uncacheable memory 
++ *
++ * flush_dcache_phys_range(unsigned long start, unsigned long stop)
++ *
++ *    flush all bytes from start to stop-1 inclusive
++ */
++_GLOBAL(flush_dcache_phys_range)
++ 	ld	r10,PPC64_CACHES at toc(r2)
++	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
++	addi	r5,r7,-1
++	andc	r6,r3,r5		/* round low to line bdy */
++	subf	r8,r6,r4		/* compute length */
++	add	r8,r8,r5		/* ensure we get enough */
++	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */
++	srw.	r8,r8,r9		/* compute line count */
++	beqlr				/* nothing to do? */
++	mfmsr	r5			/* Disable MMU Data Relocation */
++	ori	r0,r5,MSR_DR
++	xori	r0,r0,MSR_DR
++	sync
++	mtmsr	r0
++	sync
++	isync
++	mtctr	r8
++0:	dcbst	0,r6
++	add	r6,r6,r7
++	bdnz	0b
++	sync
++	isync
++	mtmsr	r5			/* Re-enable MMU Data Relocation */
++	sync
++	isync
++	blr
++
++_GLOBAL(flush_inval_dcache_range)
++ 	ld	r10,PPC64_CACHES at toc(r2)
++	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
++	addi	r5,r7,-1
++	andc	r6,r3,r5		/* round low to line bdy */
++	subf	r8,r6,r4		/* compute length */
++	add	r8,r8,r5		/* ensure we get enough */
++	lwz	r9,DCACHEL1LOGLINESIZE(r10)/* Get log-2 of dcache line size */
++	srw.	r8,r8,r9		/* compute line count */
++	beqlr				/* nothing to do? */
++	sync
++	isync
++	mtctr	r8
++0:	dcbf	0,r6
++	add	r6,r6,r7
++	bdnz	0b
++	sync
++	isync
++	blr
++
++
++/*
++ * Flush a particular page from the data cache to RAM.
++ * Note: this is necessary because the instruction cache does *not*
++ * snoop from the data cache.
++ *
++ *	void __flush_dcache_icache(void *page)
++ */
++_GLOBAL(__flush_dcache_icache)
++/*
++ * Flush the data cache to memory 
++ * 
++ * Different systems have different cache line sizes
++ */
++
++/* Flush the dcache */
++ 	ld	r7,PPC64_CACHES at toc(r2)
++	clrrdi	r3,r3,PAGE_SHIFT           	    /* Page align */
++	lwz	r4,DCACHEL1LINESPERPAGE(r7)	/* Get # dcache lines per page */
++	lwz	r5,DCACHEL1LINESIZE(r7)		/* Get dcache line size */
++	mr	r6,r3
++	mtctr	r4
++0:	dcbst	0,r6
++	add	r6,r6,r5
++	bdnz	0b
++	sync
++
++/* Now invalidate the icache */	
++
++	lwz	r4,ICACHEL1LINESPERPAGE(r7)	/* Get # icache lines per page */
++	lwz	r5,ICACHEL1LINESIZE(r7)		/* Get icache line size */
++	mtctr	r4
++1:	icbi	0,r3
++	add	r3,r3,r5
++	bdnz	1b
++	isync
++	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)
++	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-
++00:	lbzu	r5,1(r4)
++	stb	r5,0(r3)
++	bdnz	00b
++	sync
++	blr	
++
++_GLOBAL(_insw)
++	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-
++00:	lhzu	r5,2(r4)
++	sthbrx	r5,0,r3	
++	bdnz	00b
++	sync
++	blr	
++
++_GLOBAL(_insl)
++	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-
++00:	lwzu	r5,4(r4)
++	stwbrx	r5,0,r3
++	bdnz	00b
++	sync
++	blr	
++
++/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */
++_GLOBAL(_insw_ns)
++	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
++
++/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */
++_GLOBAL(_outsw_ns)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,2
++	blelr-
++00:	lhzu	r5,2(r4)
++	sth	r5,0(r3)
++	bdnz	00b
++	sync
++	blr	
++
++_GLOBAL(_insl_ns)
++	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
++
++_GLOBAL(_outsl_ns)
++	cmpwi	0,r5,0
++	mtctr	r5
++	subi	r4,r4,4
++	blelr-
++00:	lwzu	r5,4(r4)
++	stw	r5,0(r3)
++	bdnz	00b
++	sync
++	blr	
++
++/*
++ * identify_cpu and calls setup_cpu
++ * In:	r3 = base of the cpu_specs array
++ *	r4 = address of cur_cpu_spec
++ *	r5 = relocation offset
++ */
++_GLOBAL(identify_cpu)
++	mfpvr	r7
++1:
++	lwz	r8,CPU_SPEC_PVR_MASK(r3)
++	and	r8,r8,r7
++	lwz	r9,CPU_SPEC_PVR_VALUE(r3)
++	cmplw	0,r9,r8
++	beq	1f
++	addi	r3,r3,CPU_SPEC_ENTRY_SIZE
++	b	1b
++1:
++	sub	r0,r3,r5
++	std	r0,0(r4)
++	ld	r4,CPU_SPEC_SETUP(r3)
++	add	r4,r4,r5
++	ld	r4,0(r4)
++	add	r4,r4,r5
++	mtctr	r4
++	/* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */
++	mr	r4,r3
++	mr	r3,r5
++	bctr
++
++/*
++ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
++ * and writes nop's over sections of code that don't apply for this cpu.
++ * r3 = data offset (not changed)
++ */
++_GLOBAL(do_cpu_ftr_fixups)
++	/* Get CPU 0 features */
++	LOADADDR(r6,cur_cpu_spec)
++	sub	r6,r6,r3
++	ld	r4,0(r6)
++	sub	r4,r4,r3
++	ld	r4,CPU_SPEC_FEATURES(r4)
++	/* Get the fixup table */
++	LOADADDR(r6,__start___ftr_fixup)
++	sub	r6,r6,r3
++	LOADADDR(r7,__stop___ftr_fixup)
++	sub	r7,r7,r3
++	/* Do the fixup */
++1:	cmpld	r6,r7
++	bgelr
++	addi	r6,r6,32
++	ld	r8,-32(r6)	/* mask */
++	and	r8,r8,r4
++	ld	r9,-24(r6)	/* value */
++	cmpld	r8,r9
++	beq	1b
++	ld	r8,-16(r6)	/* section begin */
++	ld	r9,-8(r6)	/* section end */
++	subf.	r9,r8,r9
++	beq	1b
++	/* write nops over the section of code */
++	/* todo: if large section, add a branch at the start of it */
++	srwi	r9,r9,2
++	mtctr	r9
++	sub	r8,r8,r3
++	lis	r0,0x60000000 at h	/* nop */
++3:	stw	r0,0(r8)
++	andi.	r10,r4,CPU_FTR_SPLIT_ID_CACHE at l
++	beq	2f
++	dcbst	0,r8		/* suboptimal, but simpler */
++	sync
++	icbi	0,r8
++2:	addi	r8,r8,4
++	bdnz	3b
++	sync			/* additional sync needed on g4 */
++	isync
++	b	1b
++
++#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
++/*
++ * Do an IO access in real mode
++ */
++_GLOBAL(real_readb)
++	mfmsr	r7
++	ori	r0,r7,MSR_DR
++	xori	r0,r0,MSR_DR
++	sync
++	mtmsrd	r0
++	sync
++	isync
++	mfspr	r6,SPRN_HID4
++	rldicl	r5,r6,32,0
++	ori	r5,r5,0x100
++	rldicl	r5,r5,32,0
++	sync
++	mtspr	SPRN_HID4,r5
++	isync
++	slbia
++	isync
++	lbz	r3,0(r3)
++	sync
++	mtspr	SPRN_HID4,r6
++	isync
++	slbia
++	isync
++	mtmsrd	r7
++	sync
++	isync
++	blr
++
++	/*
++ * Do an IO access in real mode
++ */
++_GLOBAL(real_writeb)
++	mfmsr	r7
++	ori	r0,r7,MSR_DR
++	xori	r0,r0,MSR_DR
++	sync
++	mtmsrd	r0
++	sync
++	isync
++	mfspr	r6,SPRN_HID4
++	rldicl	r5,r6,32,0
++	ori	r5,r5,0x100
++	rldicl	r5,r5,32,0
++	sync
++	mtspr	SPRN_HID4,r5
++	isync
++	slbia
++	isync
++	stb	r3,0(r4)
++	sync
++	mtspr	SPRN_HID4,r6
++	isync
++	slbia
++	isync
++	mtmsrd	r7
++	sync
++	isync
++	blr
++#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
++
++/*
++ * Create a kernel thread
++ *   kernel_thread(fn, arg, flags)
++ */
++_GLOBAL(kernel_thread)
++	std	r29,-24(r1)
++	std	r30,-16(r1)
++	stdu	r1,-STACK_FRAME_OVERHEAD(r1)
++	mr	r29,r3
++	mr	r30,r4
++	ori	r3,r5,CLONE_VM	/* flags */
++	oris	r3,r3,(CLONE_UNTRACED>>16)
++	li	r4,0		/* new sp (unused) */
++	li	r0,__NR_clone
++	sc
++	cmpdi	0,r3,0		/* parent or child? */
++	bne	1f		/* return if parent */
++	li	r0,0
++	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
++	ld	r2,8(r29)
++	ld	r29,0(r29)
++	mtlr	r29              /* fn addr in lr */
++	mr	r3,r30	        /* load arg and call fn */
++	blrl
++	li	r0,__NR_exit	/* exit after child exits */
++        li	r3,0
++	sc
++1:	addi	r1,r1,STACK_FRAME_OVERHEAD	
++	ld	r29,-24(r1)
++	ld	r30,-16(r1)
++	blr
++
++/*
++ * disable_kernel_fp()
++ * Disable the FPU.
++ */
++_GLOBAL(disable_kernel_fp)
++	mfmsr	r3
++	rldicl	r0,r3,(63-MSR_FP_LG),1
++	rldicl	r3,r0,(MSR_FP_LG+1),0
++	mtmsrd	r3			/* disable use of fpu now */
++	isync
++	blr
++
++#ifdef CONFIG_ALTIVEC
++
++#if 0 /* this has no callers for now */
++/*
++ * disable_kernel_altivec()
++ * Disable the VMX.
++ */
++_GLOBAL(disable_kernel_altivec)
++	mfmsr	r3
++	rldicl	r0,r3,(63-MSR_VEC_LG),1
++	rldicl	r3,r0,(MSR_VEC_LG+1),0
++	mtmsrd	r3			/* disable use of VMX now */
++	isync
++	blr
++#endif /* 0 */
++
++/*
++ * giveup_altivec(tsk)
++ * Disable VMX for the task given as the argument,
++ * and save the vector registers in its thread_struct.
++ * Enables the VMX for use in the kernel on return.
++ */
++_GLOBAL(giveup_altivec)
++	mfmsr	r5
++	oris	r5,r5,MSR_VEC at h
++	mtmsrd	r5			/* enable use of VMX now */
++	isync
++	cmpdi	0,r3,0
++	beqlr-				/* if no previous owner, done */
++	addi	r3,r3,THREAD		/* want THREAD of task */
++	ld	r5,PT_REGS(r3)
++	cmpdi	0,r5,0
++	SAVE_32VRS(0,r4,r3)
++	mfvscr	vr0
++	li	r4,THREAD_VSCR
++	stvx	vr0,r4,r3
++	beq	1f
++	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++	lis	r3,MSR_VEC at h
++	andc	r4,r4,r3		/* disable FP for previous task */
++	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
++1:
++#ifndef CONFIG_SMP
++	li	r5,0
++	ld	r4,last_task_used_altivec at got(r2)
++	std	r5,0(r4)
++#endif /* CONFIG_SMP */
++	blr
++
++#endif /* CONFIG_ALTIVEC */
++
++_GLOBAL(__setup_cpu_power3)
++	blr
++
++_GLOBAL(execve)
++	li	r0,__NR_execve
++	sc
++	bnslr
++	neg	r3,r3
++	blr
++
++/* kexec_wait(phys_cpu)
++ *
++ * wait for the flag to change, indicating this kernel is going away but
++ * the slave code for the next one is at addresses 0 to 100.
++ *
++ * This is used by all slaves.
++ *
++ * Physical (hardware) cpu id should be in r3.
++ */
++_GLOBAL(kexec_wait)
++	bl	1f
++1:	mflr	r5
++	addi	r5,r5,kexec_flag-1b
++
++99:	HMT_LOW
++#ifdef CONFIG_KEXEC		/* use no memory without kexec */
++	lwz	r4,0(r5)
++	cmpwi	0,r4,0
++	bnea	0x60
++#endif
++	b	99b
++
++/* this can be in text because we won't change it until we are
++ * running in real anyways
++ */
++kexec_flag:
++	.long	0
++
++
++#ifdef CONFIG_KEXEC
++
++/* kexec_smp_wait(void)
++ *
++ * call with interrupts off
++ * note: this is a terminal routine, it does not save lr
++ *
++ * get phys id from paca
++ * set paca id to -1 to say we got here
++ * switch to real mode
++ * join other cpus in kexec_wait(phys_id)
++ */
++_GLOBAL(kexec_smp_wait)
++	lhz	r3,PACAHWCPUID(r13)
++	li	r4,-1
++	sth	r4,PACAHWCPUID(r13)	/* let others know we left */
++	bl	real_mode
++	b	.kexec_wait
++
++/*
++ * switch to real mode (turn mmu off)
++ * we use the early kernel trick that the hardware ignores bits
++ * 0 and 1 (big endian) of the effective address in real mode
++ *
++ * don't overwrite r3 here, it is live for kexec_wait above.
++ */
++real_mode:	/* assume normal blr return */
++1:	li	r9,MSR_RI
++	li	r10,MSR_DR|MSR_IR
++	mflr	r11		/* return address to SRR0 */
++	mfmsr	r12
++	andc	r9,r12,r9
++	andc	r10,r12,r10
++
++	mtmsrd	r9,1
++	mtspr	SPRN_SRR1,r10
++	mtspr	SPRN_SRR0,r11
++	rfid
++
++
++/*
++ * kexec_sequence(newstack, start, image, control, clear_all())
++ *
++ * does the grungy work with stack switching and real mode switches
++ * also does simple calls to other code
++ */
++
++_GLOBAL(kexec_sequence)
++	mflr	r0
++	std	r0,16(r1)
++
++	/* switch stacks to newstack -- &kexec_stack.stack */
++	stdu	r1,THREAD_SIZE-112(r3)
++	mr	r1,r3
++
++	li	r0,0
++	std	r0,16(r1)
++
++	/* save regs for local vars on new stack.
++	 * yes, we won't go back, but ...
++	 */
++	std	r31,-8(r1)
++	std	r30,-16(r1)
++	std	r29,-24(r1)
++	std	r28,-32(r1)
++	std	r27,-40(r1)
++	std	r26,-48(r1)
++	std	r25,-56(r1)
++
++	stdu	r1,-112-64(r1)
++
++	/* save args into preserved regs */
++	mr	r31,r3			/* newstack (both) */
++	mr	r30,r4			/* start (real) */
++	mr	r29,r5			/* image (virt) */
++	mr	r28,r6			/* control, unused */
++	mr	r27,r7			/* clear_all() fn desc */
++	mr	r26,r8			/* spare */
++	lhz	r25,PACAHWCPUID(r13)	/* get our phys cpu from paca */
++
++	/* disable interrupts, we are overwriting kernel data next */
++	mfmsr	r3
++	rlwinm	r3,r3,0,17,15
++	mtmsrd	r3,1
++
++	/* copy dest pages, flush whole dest image */
++	mr	r3,r29
++	bl	.kexec_copy_flush	/* (image) */
++
++	/* turn off mmu */
++	bl	real_mode
++
++	/* clear out hardware hash page table and tlb */
++	ld	r5,0(r27)		/* deref function descriptor */
++	mtctr	r5
++	bctrl				/* ppc_md.hash_clear_all(void); */
++
++/*
++ *   kexec image calling is:
++ *      the first 0x100 bytes of the entry point are copied to 0
++ *
++ *      all slaves branch to slave = 0x60 (absolute)
++ *              slave(phys_cpu_id);
++ *
++ *      master goes to start = entry point
++ *              start(phys_cpu_id, start, 0);
++ *
++ *
++ *   a wrapper is needed to call existing kernels, here is an approximate
++ *   description of one method:
++ *
++ * v2: (2.6.10)
++ *   start will be near the boot_block (maybe 0x100 bytes before it?)
++ *   it will have a 0x60, which will b to boot_block, where it will wait
++ *   and 0 will store phys into struct boot-block and load r3 from there,
++ *   copy kernel 0-0x100 and tell slaves to back down to 0x60 again
++ *
++ * v1: (2.6.9)
++ *    boot block will have all cpus scanning device tree to see if they
++ *    are the boot cpu ?????
++ *    other device tree differences (prop sizes, va vs pa, etc)...
++ */
++
++	/* copy  0x100 bytes starting at start to 0 */
++	li	r3,0
++	mr	r4,r30
++	li	r5,0x100
++	li	r6,0
++	bl	.copy_and_flush	/* (dest, src, copy limit, start offset) */
++1:	/* assume normal blr return */
++
++	/* release other cpus to the new kernel secondary start at 0x60 */
++	mflr	r5
++	li	r6,1
++	stw	r6,kexec_flag-1b(5)
++	mr	r3,r25	# my phys cpu
++	mr	r4,r30	# start, aka phys mem offset
++	mtlr	4
++	li	r5,0
++	blr	/* image->start(physid, image->start, 0); */
++#endif /* CONFIG_KEXEC */
+diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/of_device.c
+@@ -0,0 +1,276 @@
++#include <linux/config.h>
++#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 &= 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;
++}
++
++struct bus_type of_platform_bus_type = {
++       .name	= "of_platform",
++       .match	= of_platform_bus_match,
++       .suspend	= of_device_suspend,
++       .resume	= of_device_resume,
++};
++
++static int __init of_bus_driver_init(void)
++{
++	return bus_register(&of_platform_bus_type);
++}
++
++postcore_initcall(of_bus_driver_init);
++
++int of_register_driver(struct of_platform_driver *drv)
++{
++	int count = 0;
++
++	/* initialize common driver fields */
++	drv->driver.name = drv->name;
++	drv->driver.bus = &of_platform_bus_type;
++	drv->driver.probe = of_device_probe;
++	drv->driver.remove = of_device_remove;
++
++	/* register with core */
++	count = driver_register(&drv->driver);
++	return count ? count : 1;
++}
++
++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);
++	of_node_put(ofdev->node);
++	kfree(ofdev);
++}
++
++int of_device_register(struct of_device *ofdev)
++{
++	int rc;
++	struct of_device **odprop;
++
++	BUG_ON(ofdev->node == NULL);
++
++	odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
++	if (!odprop) {
++		struct property *new_prop;
++	
++		new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *),
++			GFP_KERNEL);
++		if (new_prop == NULL)
++			return -ENOMEM;
++		new_prop->name = "linux,device";
++		new_prop->length = sizeof(sizeof(struct of_device *));
++		new_prop->value = (unsigned char *)&new_prop[1];
++		odprop = (struct of_device **)new_prop->value;
++		*odprop = NULL;
++		prom_add_property(ofdev->node, new_prop);
++	}
++	*odprop = ofdev;
++
++	rc = device_register(&ofdev->dev);
++	if (rc)
++		return rc;
++
++	device_create_file(&ofdev->dev, &dev_attr_devspec);
++
++	return 0;
++}
++
++void of_device_unregister(struct of_device *ofdev)
++{
++	struct of_device **odprop;
++
++	device_remove_file(&ofdev->dev, &dev_attr_devspec);
++
++	odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
++	if (odprop)
++		*odprop = NULL;
++
++	device_unregister(&ofdev->dev);
++}
++
++struct of_device* of_platform_device_create(struct device_node *np,
++					    const char *bus_id,
++					    struct device *parent)
++{
++	struct of_device *dev;
++
++	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
++	if (!dev)
++		return NULL;
++	memset(dev, 0, sizeof(*dev));
++
++	dev->node = of_node_get(np);
++	dev->dma_mask = 0xffffffffUL;
++	dev->dev.dma_mask = &dev->dma_mask;
++	dev->dev.parent = parent;
++	dev->dev.bus = &of_platform_bus_type;
++	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_platform_bus_type);
++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/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/pmc.c
+@@ -0,0 +1,112 @@
++/*
++ *  arch/powerpc/kernel/pmc.c
++ *
++ *  Copyright (C) 2004 David Gibson, IBM Corporation.
++ *  Includes code formerly from arch/ppc/kernel/perfmon.c:
++ *    Author: Andy Fleming
++ *    Copyright (c) 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.
++ */
++
++#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/spinlock.h>
++#include <linux/module.h>
++
++#include <asm/processor.h>
++#include <asm/pmc.h>
++
++#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200)
++static void dummy_perf(struct pt_regs *regs)
++{
++	unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
++
++	pmgc0 &= ~PMGC0_PMIE;
++	mtpmr(PMRN_PMGC0, pmgc0);
++}
++#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx)
++
++#ifndef MMCR0_PMAO
++#define MMCR0_PMAO	0
++#endif
++
++/* Ensure exceptions are disabled */
++static void dummy_perf(struct pt_regs *regs)
++{
++	unsigned int mmcr0 = mfspr(SPRN_MMCR0);
++
++	mmcr0 &= ~(MMCR0_PMXE|MMCR0_PMAO);
++	mtspr(SPRN_MMCR0, mmcr0);
++}
++#else
++static void dummy_perf(struct pt_regs *regs)
++{
++}
++#endif
++
++static DEFINE_SPINLOCK(pmc_owner_lock);
++static void *pmc_owner_caller; /* mostly for debugging */
++perf_irq_t perf_irq = dummy_perf;
++
++int reserve_pmc_hardware(perf_irq_t new_perf_irq)
++{
++	int err = 0;
++
++	spin_lock(&pmc_owner_lock);
++
++	if (pmc_owner_caller) {
++		printk(KERN_WARNING "reserve_pmc_hardware: "
++		       "PMC hardware busy (reserved by caller %p)\n",
++		       pmc_owner_caller);
++		err = -EBUSY;
++		goto out;
++	}
++
++	pmc_owner_caller = __builtin_return_address(0);
++	perf_irq = new_perf_irq ? : dummy_perf;
++
++ out:
++	spin_unlock(&pmc_owner_lock);
++	return err;
++}
++EXPORT_SYMBOL_GPL(reserve_pmc_hardware);
++
++void release_pmc_hardware(void)
++{
++	spin_lock(&pmc_owner_lock);
++
++	WARN_ON(! pmc_owner_caller);
++
++	pmc_owner_caller = NULL;
++	perf_irq = dummy_perf;
++
++	spin_unlock(&pmc_owner_lock);
++}
++EXPORT_SYMBOL_GPL(release_pmc_hardware);
++
++#ifdef CONFIG_PPC64
++void power4_enable_pmcs(void)
++{
++	unsigned long hid0;
++
++	hid0 = mfspr(SPRN_HID0);
++	hid0 |= 1UL << (63 - 20);
++
++	/* POWER4 requires the following sequence */
++	asm volatile(
++		"sync\n"
++		"mtspr     %1, %0\n"
++		"mfspr     %0, %1\n"
++		"mfspr     %0, %1\n"
++		"mfspr     %0, %1\n"
++		"mfspr     %0, %1\n"
++		"mfspr     %0, %1\n"
++		"mfspr     %0, %1\n"
++		"isync" : "=&r" (hid0) : "i" (SPRN_HID0), "0" (hid0):
++		"memory");
++}
++#endif /* CONFIG_PPC64 */
+diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/ppc_ksyms.c
+@@ -0,0 +1,273 @@
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/threads.h>
++#include <linux/smp.h>
++#include <linux/sched.h>
++#include <linux/elfcore.h>
++#include <linux/string.h>
++#include <linux/interrupt.h>
++#include <linux/tty.h>
++#include <linux/vt_kern.h>
++#include <linux/nvram.h>
++#include <linux/console.h>
++#include <linux/irq.h>
++#include <linux/pci.h>
++#include <linux/delay.h>
++#include <linux/ide.h>
++#include <linux/bitops.h>
++
++#include <asm/page.h>
++#include <asm/semaphore.h>
++#include <asm/processor.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <asm/ide.h>
++#include <asm/atomic.h>
++#include <asm/checksum.h>
++#include <asm/pgtable.h>
++#include <asm/tlbflush.h>
++#include <linux/adb.h>
++#include <linux/cuda.h>
++#include <linux/pmu.h>
++#include <asm/prom.h>
++#include <asm/system.h>
++#include <asm/pci-bridge.h>
++#include <asm/irq.h>
++#include <asm/pmac_feature.h>
++#include <asm/dma.h>
++#include <asm/machdep.h>
++#include <asm/hw_irq.h>
++#include <asm/nvram.h>
++#include <asm/mmu_context.h>
++#include <asm/backlight.h>
++#include <asm/time.h>
++#include <asm/cputable.h>
++#include <asm/btext.h>
++#include <asm/div64.h>
++
++#ifdef  CONFIG_8xx
++#include <asm/commproc.h>
++#endif
++
++#ifdef CONFIG_PPC32
++extern void transfer_to_handler(void);
++extern void do_IRQ(struct pt_regs *regs);
++extern void machine_check_exception(struct pt_regs *regs);
++extern void alignment_exception(struct pt_regs *regs);
++extern void program_check_exception(struct pt_regs *regs);
++extern void single_step_exception(struct pt_regs *regs);
++extern int do_signal(sigset_t *, struct pt_regs *);
++extern int pmac_newworld;
++extern int sys_sigreturn(struct pt_regs *regs);
++
++EXPORT_SYMBOL(clear_pages);
++EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
++EXPORT_SYMBOL(DMA_MODE_READ);
++EXPORT_SYMBOL(DMA_MODE_WRITE);
++EXPORT_SYMBOL(__div64_32);
++
++EXPORT_SYMBOL(do_signal);
++EXPORT_SYMBOL(transfer_to_handler);
++EXPORT_SYMBOL(do_IRQ);
++EXPORT_SYMBOL(machine_check_exception);
++EXPORT_SYMBOL(alignment_exception);
++EXPORT_SYMBOL(program_check_exception);
++EXPORT_SYMBOL(single_step_exception);
++EXPORT_SYMBOL(sys_sigreturn);
++#endif
++
++#if defined(CONFIG_PPC_PREP)
++EXPORT_SYMBOL(_prep_type);
++EXPORT_SYMBOL(ucSystemType);
++#endif
++
++#if !defined(__INLINE_BITOPS)
++EXPORT_SYMBOL(set_bit);
++EXPORT_SYMBOL(clear_bit);
++EXPORT_SYMBOL(change_bit);
++EXPORT_SYMBOL(test_and_set_bit);
++EXPORT_SYMBOL(test_and_clear_bit);
++EXPORT_SYMBOL(test_and_change_bit);
++#endif /* __INLINE_BITOPS */
++
++EXPORT_SYMBOL(strcpy);
++EXPORT_SYMBOL(strncpy);
++EXPORT_SYMBOL(strcat);
++EXPORT_SYMBOL(strncat);
++EXPORT_SYMBOL(strchr);
++EXPORT_SYMBOL(strrchr);
++EXPORT_SYMBOL(strpbrk);
++EXPORT_SYMBOL(strstr);
++EXPORT_SYMBOL(strlen);
++EXPORT_SYMBOL(strnlen);
++EXPORT_SYMBOL(strcmp);
++EXPORT_SYMBOL(strncmp);
++EXPORT_SYMBOL(strcasecmp);
++
++EXPORT_SYMBOL(csum_partial);
++EXPORT_SYMBOL(csum_partial_copy_generic);
++EXPORT_SYMBOL(ip_fast_csum);
++EXPORT_SYMBOL(csum_tcpudp_magic);
++
++EXPORT_SYMBOL(__copy_tofrom_user);
++EXPORT_SYMBOL(__clear_user);
++EXPORT_SYMBOL(__strncpy_from_user);
++EXPORT_SYMBOL(__strnlen_user);
++
++EXPORT_SYMBOL(_insb);
++EXPORT_SYMBOL(_outsb);
++EXPORT_SYMBOL(_insw);
++EXPORT_SYMBOL(_outsw);
++EXPORT_SYMBOL(_insl);
++EXPORT_SYMBOL(_outsl);
++EXPORT_SYMBOL(_insw_ns);
++EXPORT_SYMBOL(_outsw_ns);
++EXPORT_SYMBOL(_insl_ns);
++EXPORT_SYMBOL(_outsl_ns);
++EXPORT_SYMBOL(ioremap);
++#ifdef CONFIG_44x
++EXPORT_SYMBOL(ioremap64);
++#endif
++EXPORT_SYMBOL(__ioremap);
++EXPORT_SYMBOL(iounmap);
++#ifdef CONFIG_PPC32
++EXPORT_SYMBOL(ioremap_bot);	/* aka VMALLOC_END */
++#endif
++
++#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
++EXPORT_SYMBOL(ppc_ide_md);
++#endif
++
++#if defined(CONFIG_PCI) && defined(CONFIG_PPC32)
++EXPORT_SYMBOL(isa_io_base);
++EXPORT_SYMBOL(isa_mem_base);
++EXPORT_SYMBOL(pci_dram_offset);
++EXPORT_SYMBOL(pci_alloc_consistent);
++EXPORT_SYMBOL(pci_free_consistent);
++EXPORT_SYMBOL(pci_bus_io_base);
++EXPORT_SYMBOL(pci_bus_io_base_phys);
++EXPORT_SYMBOL(pci_bus_mem_base_phys);
++EXPORT_SYMBOL(pci_bus_to_hose);
++EXPORT_SYMBOL(pci_resource_to_bus);
++EXPORT_SYMBOL(pci_phys_to_bus);
++EXPORT_SYMBOL(pci_bus_to_phys);
++#endif /* CONFIG_PCI */
++
++#ifdef CONFIG_NOT_COHERENT_CACHE
++EXPORT_SYMBOL(flush_dcache_all);
++#endif
++
++EXPORT_SYMBOL(start_thread);
++EXPORT_SYMBOL(kernel_thread);
++
++EXPORT_SYMBOL(giveup_fpu);
++#ifdef CONFIG_ALTIVEC
++EXPORT_SYMBOL(giveup_altivec);
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_SPE
++EXPORT_SYMBOL(giveup_spe);
++#endif /* CONFIG_SPE */
++
++#ifdef CONFIG_PPC64
++EXPORT_SYMBOL(__flush_icache_range);
++#else
++EXPORT_SYMBOL(flush_instruction_cache);
++EXPORT_SYMBOL(flush_icache_range);
++EXPORT_SYMBOL(flush_tlb_kernel_range);
++EXPORT_SYMBOL(flush_tlb_page);
++EXPORT_SYMBOL(_tlbie);
++#endif
++EXPORT_SYMBOL(flush_dcache_range);
++
++#ifdef CONFIG_SMP
++EXPORT_SYMBOL(smp_call_function);
++#ifdef CONFIG_PPC32
++EXPORT_SYMBOL(smp_hw_index);
++#endif
++#endif
++
++#ifdef CONFIG_ADB
++EXPORT_SYMBOL(adb_request);
++EXPORT_SYMBOL(adb_register);
++EXPORT_SYMBOL(adb_unregister);
++EXPORT_SYMBOL(adb_poll);
++EXPORT_SYMBOL(adb_try_handler_change);
++#endif /* CONFIG_ADB */
++#ifdef CONFIG_ADB_CUDA
++EXPORT_SYMBOL(cuda_request);
++EXPORT_SYMBOL(cuda_poll);
++#endif /* CONFIG_ADB_CUDA */
++#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32)
++EXPORT_SYMBOL(_machine);
++#endif
++#ifdef CONFIG_PPC_PMAC
++EXPORT_SYMBOL(sys_ctrler);
++#endif
++#ifdef CONFIG_VT
++EXPORT_SYMBOL(kd_mksound);
++#endif
++EXPORT_SYMBOL(to_tm);
++
++#ifdef CONFIG_PPC32
++long long __ashrdi3(long long, int);
++long long __ashldi3(long long, int);
++long long __lshrdi3(long long, int);
++EXPORT_SYMBOL(__ashrdi3);
++EXPORT_SYMBOL(__ashldi3);
++EXPORT_SYMBOL(__lshrdi3);
++#endif
++
++EXPORT_SYMBOL(memcpy);
++EXPORT_SYMBOL(memset);
++EXPORT_SYMBOL(memmove);
++EXPORT_SYMBOL(memscan);
++EXPORT_SYMBOL(memcmp);
++EXPORT_SYMBOL(memchr);
++
++#if defined(CONFIG_FB_VGA16_MODULE)
++EXPORT_SYMBOL(screen_info);
++#endif
++
++#ifdef CONFIG_PPC32
++EXPORT_SYMBOL(__delay);
++EXPORT_SYMBOL(timer_interrupt);
++EXPORT_SYMBOL(irq_desc);
++EXPORT_SYMBOL(tb_ticks_per_jiffy);
++EXPORT_SYMBOL(console_drivers);
++EXPORT_SYMBOL(cacheable_memcpy);
++#endif
++
++EXPORT_SYMBOL(__up);
++EXPORT_SYMBOL(__down);
++EXPORT_SYMBOL(__down_interruptible);
++
++#ifdef  CONFIG_8xx
++EXPORT_SYMBOL(cpm_install_handler);
++EXPORT_SYMBOL(cpm_free_handler);
++#endif /* CONFIG_8xx */
++#if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx) ||\
++	defined(CONFIG_83xx)
++EXPORT_SYMBOL(__res);
++#endif
++
++#ifdef CONFIG_PPC32
++EXPORT_SYMBOL(next_mmu_context);
++EXPORT_SYMBOL(set_context);
++#endif
++
++#ifdef CONFIG_PPC_STD_MMU_32
++extern long mol_trampoline;
++EXPORT_SYMBOL(mol_trampoline); /* For MOL */
++EXPORT_SYMBOL(flush_hash_pages); /* For MOL */
++EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */
++#ifdef CONFIG_SMP
++extern int mmu_hash_lock;
++EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */
++#endif /* CONFIG_SMP */
++extern long *intercept_table;
++EXPORT_SYMBOL(intercept_table);
++#endif /* CONFIG_PPC_STD_MMU_32 */
++#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
++EXPORT_SYMBOL(__mtdcr);
++EXPORT_SYMBOL(__mfdcr);
++#endif
+diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/process.c
+@@ -0,0 +1,919 @@
++/*
++ *  arch/ppc/kernel/process.c
++ *
++ *  Derived from "arch/i386/kernel/process.c"
++ *    Copyright (C) 1995  Linus Torvalds
++ *
++ *  Updated and modified by Cort Dougan (cort at cs.nmt.edu) and
++ *  Paul Mackerras (paulus at cs.anu.edu.au)
++ *
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.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/config.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/smp.h>
++#include <linux/smp_lock.h>
++#include <linux/stddef.h>
++#include <linux/unistd.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/user.h>
++#include <linux/elf.h>
++#include <linux/init.h>
++#include <linux/prctl.h>
++#include <linux/init_task.h>
++#include <linux/module.h>
++#include <linux/kallsyms.h>
++#include <linux/mqueue.h>
++#include <linux/hardirq.h>
++#include <linux/utsname.h>
++#include <linux/kprobes.h>
++
++#include <asm/pgtable.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/processor.h>
++#include <asm/mmu.h>
++#include <asm/prom.h>
++#ifdef CONFIG_PPC64
++#include <asm/firmware.h>
++#include <asm/plpar_wrappers.h>
++#include <asm/time.h>
++#endif
++
++extern unsigned long _get_SP(void);
++
++#ifndef CONFIG_SMP
++struct task_struct *last_task_used_math = NULL;
++struct task_struct *last_task_used_altivec = NULL;
++struct task_struct *last_task_used_spe = NULL;
++#endif
++
++/*
++ * Make sure the floating-point register state in the
++ * the thread_struct is up to date for task tsk.
++ */
++void flush_fp_to_thread(struct task_struct *tsk)
++{
++	if (tsk->thread.regs) {
++		/*
++		 * We need to disable preemption here because if we didn't,
++		 * another process could get scheduled after the regs->msr
++		 * test but before we have finished saving the FP registers
++		 * to the thread_struct.  That process could take over the
++		 * FPU, and then when we get scheduled again we would store
++		 * bogus values for the remaining FP registers.
++		 */
++		preempt_disable();
++		if (tsk->thread.regs->msr & MSR_FP) {
++#ifdef CONFIG_SMP
++			/*
++			 * This should only ever be called for current or
++			 * for a stopped child process.  Since we save away
++			 * the FP register state on context switch on SMP,
++			 * there is something wrong if a stopped child appears
++			 * to still have its FP state in the CPU registers.
++			 */
++			BUG_ON(tsk != current);
++#endif
++			giveup_fpu(current);
++		}
++		preempt_enable();
++	}
++}
++
++void enable_kernel_fp(void)
++{
++	WARN_ON(preemptible());
++
++#ifdef CONFIG_SMP
++	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
++		giveup_fpu(current);
++	else
++		giveup_fpu(NULL);	/* just enables FP for kernel */
++#else
++	giveup_fpu(last_task_used_math);
++#endif /* CONFIG_SMP */
++}
++EXPORT_SYMBOL(enable_kernel_fp);
++
++int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
++{
++	if (!tsk->thread.regs)
++		return 0;
++	flush_fp_to_thread(current);
++
++	memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
++
++	return 1;
++}
++
++#ifdef CONFIG_ALTIVEC
++void enable_kernel_altivec(void)
++{
++	WARN_ON(preemptible());
++
++#ifdef CONFIG_SMP
++	if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
++		giveup_altivec(current);
++	else
++		giveup_altivec(NULL);	/* just enable AltiVec for kernel - force */
++#else
++	giveup_altivec(last_task_used_altivec);
++#endif /* CONFIG_SMP */
++}
++EXPORT_SYMBOL(enable_kernel_altivec);
++
++/*
++ * Make sure the VMX/Altivec register state in the
++ * the thread_struct is up to date for task tsk.
++ */
++void flush_altivec_to_thread(struct task_struct *tsk)
++{
++	if (tsk->thread.regs) {
++		preempt_disable();
++		if (tsk->thread.regs->msr & MSR_VEC) {
++#ifdef CONFIG_SMP
++			BUG_ON(tsk != current);
++#endif
++			giveup_altivec(current);
++		}
++		preempt_enable();
++	}
++}
++
++int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
++{
++	flush_altivec_to_thread(current);
++	memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
++	return 1;
++}
++#endif /* CONFIG_ALTIVEC */
++
++#ifdef CONFIG_SPE
++
++void enable_kernel_spe(void)
++{
++	WARN_ON(preemptible());
++
++#ifdef CONFIG_SMP
++	if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
++		giveup_spe(current);
++	else
++		giveup_spe(NULL);	/* just enable SPE for kernel - force */
++#else
++	giveup_spe(last_task_used_spe);
++#endif /* __SMP __ */
++}
++EXPORT_SYMBOL(enable_kernel_spe);
++
++void flush_spe_to_thread(struct task_struct *tsk)
++{
++	if (tsk->thread.regs) {
++		preempt_disable();
++		if (tsk->thread.regs->msr & MSR_SPE) {
++#ifdef CONFIG_SMP
++			BUG_ON(tsk != current);
++#endif
++			giveup_spe(current);
++		}
++		preempt_enable();
++	}
++}
++
++int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
++{
++	flush_spe_to_thread(current);
++	/* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
++	memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
++	return 1;
++}
++#endif /* CONFIG_SPE */
++
++static void set_dabr_spr(unsigned long val)
++{
++	mtspr(SPRN_DABR, val);
++}
++
++int set_dabr(unsigned long dabr)
++{
++	int ret = 0;
++
++#ifdef CONFIG_PPC64
++	if (firmware_has_feature(FW_FEATURE_XDABR)) {
++		/* We want to catch accesses from kernel and userspace */
++		unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
++		ret = plpar_set_xdabr(dabr, flags);
++	} else if (firmware_has_feature(FW_FEATURE_DABR)) {
++		ret = plpar_set_dabr(dabr);
++	} else
++#endif
++		set_dabr_spr(dabr);
++
++	return ret;
++}
++
++#ifdef CONFIG_PPC64
++DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
++static DEFINE_PER_CPU(unsigned long, current_dabr);
++#endif
++
++struct task_struct *__switch_to(struct task_struct *prev,
++	struct task_struct *new)
++{
++	struct thread_struct *new_thread, *old_thread;
++	unsigned long flags;
++	struct task_struct *last;
++
++#ifdef CONFIG_SMP
++	/* avoid complexity of lazy save/restore of fpu
++	 * by just saving it every time we switch out if
++	 * this task used the fpu during the last quantum.
++	 *
++	 * If it tries to use the fpu again, it'll trap and
++	 * reload its fp regs.  So we don't have to do a restore
++	 * every switch, just a save.
++	 *  -- Cort
++	 */
++	if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
++		giveup_fpu(prev);
++#ifdef CONFIG_ALTIVEC
++	/*
++	 * If the previous thread used altivec in the last quantum
++	 * (thus changing altivec regs) then save them.
++	 * We used to check the VRSAVE register but not all apps
++	 * set it, so we don't rely on it now (and in fact we need
++	 * to save & restore VSCR even if VRSAVE == 0).  -- paulus
++	 *
++	 * On SMP we always save/restore altivec regs just to avoid the
++	 * complexity of changing processors.
++	 *  -- Cort
++	 */
++	if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
++		giveup_altivec(prev);
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_SPE
++	/*
++	 * If the previous thread used spe in the last quantum
++	 * (thus changing spe regs) then save them.
++	 *
++	 * On SMP we always save/restore spe regs just to avoid the
++	 * complexity of changing processors.
++	 */
++	if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
++		giveup_spe(prev);
++#endif /* CONFIG_SPE */
++
++#else  /* CONFIG_SMP */
++#ifdef CONFIG_ALTIVEC
++	/* Avoid the trap.  On smp this this never happens since
++	 * we don't set last_task_used_altivec -- Cort
++	 */
++	if (new->thread.regs && last_task_used_altivec == new)
++		new->thread.regs->msr |= MSR_VEC;
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_SPE
++	/* Avoid the trap.  On smp this this never happens since
++	 * we don't set last_task_used_spe
++	 */
++	if (new->thread.regs && last_task_used_spe == new)
++		new->thread.regs->msr |= MSR_SPE;
++#endif /* CONFIG_SPE */
++
++#endif /* CONFIG_SMP */
++
++#ifdef CONFIG_PPC64	/* for now */
++	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
++		set_dabr(new->thread.dabr);
++		__get_cpu_var(current_dabr) = new->thread.dabr;
++	}
++
++	flush_tlb_pending();
++#endif
++
++	new_thread = &new->thread;
++	old_thread = &current->thread;
++
++#ifdef CONFIG_PPC64
++	/*
++	 * Collect processor utilization data per process
++	 */
++	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
++		struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
++		long unsigned start_tb, current_tb;
++		start_tb = old_thread->start_tb;
++		cu->current_tb = current_tb = mfspr(SPRN_PURR);
++		old_thread->accum_tb += (current_tb - start_tb);
++		new_thread->start_tb = current_tb;
++	}
++#endif
++
++	local_irq_save(flags);
++	last = _switch(old_thread, new_thread);
++
++	local_irq_restore(flags);
++
++	return last;
++}
++
++static int instructions_to_print = 16;
++
++#ifdef CONFIG_PPC64
++#define BAD_PC(pc)	((REGION_ID(pc) != KERNEL_REGION_ID) && \
++		         (REGION_ID(pc) != VMALLOC_REGION_ID))
++#else
++#define BAD_PC(pc)	((pc) < KERNELBASE)
++#endif
++
++static void show_instructions(struct pt_regs *regs)
++{
++	int i;
++	unsigned long pc = regs->nip - (instructions_to_print * 3 / 4 *
++			sizeof(int));
++
++	printk("Instruction dump:");
++
++	for (i = 0; i < instructions_to_print; i++) {
++		int instr;
++
++		if (!(i % 8))
++			printk("\n");
++
++		if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) {
++			printk("XXXXXXXX ");
++		} else {
++			if (regs->nip == pc)
++				printk("<%08x> ", instr);
++			else
++				printk("%08x ", instr);
++		}
++
++		pc += sizeof(int);
++	}
++
++	printk("\n");
++}
++
++static struct regbit {
++	unsigned long bit;
++	const char *name;
++} msr_bits[] = {
++	{MSR_EE,	"EE"},
++	{MSR_PR,	"PR"},
++	{MSR_FP,	"FP"},
++	{MSR_ME,	"ME"},
++	{MSR_IR,	"IR"},
++	{MSR_DR,	"DR"},
++	{0,		NULL}
++};
++
++static void printbits(unsigned long val, struct regbit *bits)
++{
++	const char *sep = "";
++
++	printk("<");
++	for (; bits->bit; ++bits)
++		if (val & bits->bit) {
++			printk("%s%s", sep, bits->name);
++			sep = ",";
++		}
++	printk(">");
++}
++
++#ifdef CONFIG_PPC64
++#define REG		"%016lX"
++#define REGS_PER_LINE	4
++#define LAST_VOLATILE	13
++#else
++#define REG		"%08lX"
++#define REGS_PER_LINE	8
++#define LAST_VOLATILE	12
++#endif
++
++void show_regs(struct pt_regs * regs)
++{
++	int i, trap;
++
++	printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
++	       regs->nip, regs->link, regs->ctr);
++	printk("REGS: %p TRAP: %04lx   %s  (%s)\n",
++	       regs, regs->trap, print_tainted(), system_utsname.release);
++	printk("MSR: "REG" ", regs->msr);
++	printbits(regs->msr, msr_bits);
++	printk("  CR: %08lX  XER: %08lX\n", regs->ccr, regs->xer);
++	trap = TRAP(regs);
++	if (trap == 0x300 || trap == 0x600)
++		printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
++	printk("TASK = %p[%d] '%s' THREAD: %p",
++	       current, current->pid, current->comm, current->thread_info);
++
++#ifdef CONFIG_SMP
++	printk(" CPU: %d", smp_processor_id());
++#endif /* CONFIG_SMP */
++
++	for (i = 0;  i < 32;  i++) {
++		if ((i % REGS_PER_LINE) == 0)
++			printk("\n" KERN_INFO "GPR%02d: ", i);
++		printk(REG " ", regs->gpr[i]);
++		if (i == LAST_VOLATILE && !FULL_REGS(regs))
++			break;
++	}
++	printk("\n");
++#ifdef CONFIG_KALLSYMS
++	/*
++	 * Lookup NIP late so we have the best change of getting the
++	 * above info out without failing
++	 */
++	printk("NIP ["REG"] ", regs->nip);
++	print_symbol("%s\n", regs->nip);
++	printk("LR ["REG"] ", regs->link);
++	print_symbol("%s\n", regs->link);
++#endif
++	show_stack(current, (unsigned long *) regs->gpr[1]);
++	if (!user_mode(regs))
++		show_instructions(regs);
++}
++
++void exit_thread(void)
++{
++	kprobe_flush_task(current);
++
++#ifndef CONFIG_SMP
++	if (last_task_used_math == current)
++		last_task_used_math = NULL;
++#ifdef CONFIG_ALTIVEC
++	if (last_task_used_altivec == current)
++		last_task_used_altivec = NULL;
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_SPE
++	if (last_task_used_spe == current)
++		last_task_used_spe = NULL;
++#endif
++#endif /* CONFIG_SMP */
++}
++
++void flush_thread(void)
++{
++#ifdef CONFIG_PPC64
++	struct thread_info *t = current_thread_info();
++
++	if (t->flags & _TIF_ABI_PENDING)
++		t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
++#endif
++	kprobe_flush_task(current);
++
++#ifndef CONFIG_SMP
++	if (last_task_used_math == current)
++		last_task_used_math = NULL;
++#ifdef CONFIG_ALTIVEC
++	if (last_task_used_altivec == current)
++		last_task_used_altivec = NULL;
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_SPE
++	if (last_task_used_spe == current)
++		last_task_used_spe = NULL;
++#endif
++#endif /* CONFIG_SMP */
++
++#ifdef CONFIG_PPC64	/* for now */
++	if (current->thread.dabr) {
++		current->thread.dabr = 0;
++		set_dabr(0);
++	}
++#endif
++}
++
++void
++release_thread(struct task_struct *t)
++{
++}
++
++/*
++ * This gets called before we allocate a new thread and copy
++ * the current task into it.
++ */
++void prepare_to_copy(struct task_struct *tsk)
++{
++	flush_fp_to_thread(current);
++	flush_altivec_to_thread(current);
++	flush_spe_to_thread(current);
++}
++
++/*
++ * Copy a thread..
++ */
++int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
++		unsigned long unused, struct task_struct *p,
++		struct pt_regs *regs)
++{
++	struct pt_regs *childregs, *kregs;
++	extern void ret_from_fork(void);
++	unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
++
++	CHECK_FULL_REGS(regs);
++	/* Copy registers */
++	sp -= sizeof(struct pt_regs);
++	childregs = (struct pt_regs *) sp;
++	*childregs = *regs;
++	if ((childregs->msr & MSR_PR) == 0) {
++		/* for kernel thread, set `current' and stackptr in new task */
++		childregs->gpr[1] = sp + sizeof(struct pt_regs);
++#ifdef CONFIG_PPC32
++		childregs->gpr[2] = (unsigned long) p;
++#else
++		clear_ti_thread_flag(p->thread_info, TIF_32BIT);
++#endif
++		p->thread.regs = NULL;	/* no user register state */
++	} else {
++		childregs->gpr[1] = usp;
++		p->thread.regs = childregs;
++		if (clone_flags & CLONE_SETTLS) {
++#ifdef CONFIG_PPC64
++			if (!test_thread_flag(TIF_32BIT))
++				childregs->gpr[13] = childregs->gpr[6];
++			else
++#endif
++				childregs->gpr[2] = childregs->gpr[6];
++		}
++	}
++	childregs->gpr[3] = 0;  /* Result from fork() */
++	sp -= STACK_FRAME_OVERHEAD;
++
++	/*
++	 * The way this works is that at some point in the future
++	 * some task will call _switch to switch to the new task.
++	 * That will pop off the stack frame created below and start
++	 * the new task running at ret_from_fork.  The new task will
++	 * do some house keeping and then return from the fork or clone
++	 * system call, using the stack frame created above.
++	 */
++	sp -= sizeof(struct pt_regs);
++	kregs = (struct pt_regs *) sp;
++	sp -= STACK_FRAME_OVERHEAD;
++	p->thread.ksp = sp;
++
++#ifdef CONFIG_PPC64
++	if (cpu_has_feature(CPU_FTR_SLB)) {
++		unsigned long sp_vsid = get_kernel_vsid(sp);
++
++		sp_vsid <<= SLB_VSID_SHIFT;
++		sp_vsid |= SLB_VSID_KERNEL;
++		if (cpu_has_feature(CPU_FTR_16M_PAGE))
++			sp_vsid |= SLB_VSID_L;
++
++		p->thread.ksp_vsid = sp_vsid;
++	}
++
++	/*
++	 * The PPC64 ABI makes use of a TOC to contain function 
++	 * pointers.  The function (ret_from_except) is actually a pointer
++	 * to the TOC entry.  The first entry is a pointer to the actual
++	 * function.
++ 	 */
++	kregs->nip = *((unsigned long *)ret_from_fork);
++#else
++	kregs->nip = (unsigned long)ret_from_fork;
++	p->thread.last_syscall = -1;
++#endif
++
++	return 0;
++}
++
++/*
++ * Set up a thread for executing a new program
++ */
++void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
++{
++#ifdef CONFIG_PPC64
++	unsigned long load_addr = regs->gpr[2];	/* saved by ELF_PLAT_INIT */
++#endif
++
++	set_fs(USER_DS);
++
++	/*
++	 * If we exec out of a kernel thread then thread.regs will not be
++	 * set.  Do it now.
++	 */
++	if (!current->thread.regs) {
++		unsigned long childregs = (unsigned long)current->thread_info +
++						THREAD_SIZE;
++		childregs -= sizeof(struct pt_regs);
++		current->thread.regs = (struct pt_regs *)childregs;
++	}
++
++	memset(regs->gpr, 0, sizeof(regs->gpr));
++	regs->ctr = 0;
++	regs->link = 0;
++	regs->xer = 0;
++	regs->ccr = 0;
++	regs->gpr[1] = sp;
++
++#ifdef CONFIG_PPC32
++	regs->mq = 0;
++	regs->nip = start;
++	regs->msr = MSR_USER;
++#else
++	if (!test_thread_flag(TIF_32BIT)) {
++		unsigned long entry, toc;
++
++		/* start is a relocated pointer to the function descriptor for
++		 * the elf _start routine.  The first entry in the function
++		 * descriptor is the entry address of _start and the second
++		 * entry is the TOC value we need to use.
++		 */
++		__get_user(entry, (unsigned long __user *)start);
++		__get_user(toc, (unsigned long __user *)start+1);
++
++		/* Check whether the e_entry function descriptor entries
++		 * need to be relocated before we can use them.
++		 */
++		if (load_addr != 0) {
++			entry += load_addr;
++			toc   += load_addr;
++		}
++		regs->nip = entry;
++		regs->gpr[2] = toc;
++		regs->msr = MSR_USER64;
++	} else {
++		regs->nip = start;
++		regs->gpr[2] = 0;
++		regs->msr = MSR_USER32;
++	}
++#endif
++
++#ifndef CONFIG_SMP
++	if (last_task_used_math == current)
++		last_task_used_math = NULL;
++#ifdef CONFIG_ALTIVEC
++	if (last_task_used_altivec == current)
++		last_task_used_altivec = NULL;
++#endif
++#ifdef CONFIG_SPE
++	if (last_task_used_spe == current)
++		last_task_used_spe = NULL;
++#endif
++#endif /* CONFIG_SMP */
++	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
++	current->thread.fpscr.val = 0;
++#ifdef CONFIG_ALTIVEC
++	memset(current->thread.vr, 0, sizeof(current->thread.vr));
++	memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
++	current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
++	current->thread.vrsave = 0;
++	current->thread.used_vr = 0;
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_SPE
++	memset(current->thread.evr, 0, sizeof(current->thread.evr));
++	current->thread.acc = 0;
++	current->thread.spefscr = 0;
++	current->thread.used_spe = 0;
++#endif /* CONFIG_SPE */
++}
++
++#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
++		| PR_FP_EXC_RES | PR_FP_EXC_INV)
++
++int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
++{
++	struct pt_regs *regs = tsk->thread.regs;
++
++	/* This is a bit hairy.  If we are an SPE enabled  processor
++	 * (have embedded fp) we store the IEEE exception enable flags in
++	 * fpexc_mode.  fpexc_mode is also used for setting FP exception
++	 * mode (asyn, precise, disabled) for 'Classic' FP. */
++	if (val & PR_FP_EXC_SW_ENABLE) {
++#ifdef CONFIG_SPE
++		tsk->thread.fpexc_mode = val &
++			(PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
++		return 0;
++#else
++		return -EINVAL;
++#endif
++	}
++
++	/* on a CONFIG_SPE this does not hurt us.  The bits that
++	 * __pack_fe01 use do not overlap with bits used for
++	 * PR_FP_EXC_SW_ENABLE.  Additionally, the MSR[FE0,FE1] bits
++	 * on CONFIG_SPE implementations are reserved so writing to
++	 * them does not change anything */
++	if (val > PR_FP_EXC_PRECISE)
++		return -EINVAL;
++	tsk->thread.fpexc_mode = __pack_fe01(val);
++	if (regs != NULL && (regs->msr & MSR_FP) != 0)
++		regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
++			| tsk->thread.fpexc_mode;
++	return 0;
++}
++
++int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
++{
++	unsigned int val;
++
++	if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
++#ifdef CONFIG_SPE
++		val = tsk->thread.fpexc_mode;
++#else
++		return -EINVAL;
++#endif
++	else
++		val = __unpack_fe01(tsk->thread.fpexc_mode);
++	return put_user(val, (unsigned int __user *) adr);
++}
++
++#define TRUNC_PTR(x)	((typeof(x))(((unsigned long)(x)) & 0xffffffff))
++
++int sys_clone(unsigned long clone_flags, unsigned long usp,
++	      int __user *parent_tidp, void __user *child_threadptr,
++	      int __user *child_tidp, int p6,
++	      struct pt_regs *regs)
++{
++	CHECK_FULL_REGS(regs);
++	if (usp == 0)
++		usp = regs->gpr[1];	/* stack pointer for child */
++#ifdef CONFIG_PPC64
++	if (test_thread_flag(TIF_32BIT)) {
++		parent_tidp = TRUNC_PTR(parent_tidp);
++		child_tidp = TRUNC_PTR(child_tidp);
++	}
++#endif
++ 	return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
++}
++
++int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
++	     unsigned long p4, unsigned long p5, unsigned long p6,
++	     struct pt_regs *regs)
++{
++	CHECK_FULL_REGS(regs);
++	return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
++}
++
++int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
++	      unsigned long p4, unsigned long p5, unsigned long p6,
++	      struct pt_regs *regs)
++{
++	CHECK_FULL_REGS(regs);
++	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
++			regs, 0, NULL, NULL);
++}
++
++int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
++	       unsigned long a3, unsigned long a4, unsigned long a5,
++	       struct pt_regs *regs)
++{
++	int error;
++	char *filename;
++
++	filename = getname((char __user *) a0);
++	error = PTR_ERR(filename);
++	if (IS_ERR(filename))
++		goto out;
++	flush_fp_to_thread(current);
++	flush_altivec_to_thread(current);
++	flush_spe_to_thread(current);
++	error = do_execve(filename, (char __user * __user *) a1,
++			  (char __user * __user *) a2, regs);
++	if (error == 0) {
++		task_lock(current);
++		current->ptrace &= ~PT_DTRACE;
++		task_unlock(current);
++	}
++	putname(filename);
++out:
++	return error;
++}
++
++static int validate_sp(unsigned long sp, struct task_struct *p,
++		       unsigned long nbytes)
++{
++	unsigned long stack_page = (unsigned long)p->thread_info;
++
++	if (sp >= stack_page + sizeof(struct thread_struct)
++	    && sp <= stack_page + THREAD_SIZE - nbytes)
++		return 1;
++
++#ifdef CONFIG_IRQSTACKS
++	stack_page = (unsigned long) hardirq_ctx[task_cpu(p)];
++	if (sp >= stack_page + sizeof(struct thread_struct)
++	    && sp <= stack_page + THREAD_SIZE - nbytes)
++		return 1;
++
++	stack_page = (unsigned long) softirq_ctx[task_cpu(p)];
++	if (sp >= stack_page + sizeof(struct thread_struct)
++	    && sp <= stack_page + THREAD_SIZE - nbytes)
++		return 1;
++#endif
++
++	return 0;
++}
++
++#ifdef CONFIG_PPC64
++#define MIN_STACK_FRAME	112	/* same as STACK_FRAME_OVERHEAD, in fact */
++#define FRAME_LR_SAVE	2
++#define INT_FRAME_SIZE	(sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD + 288)
++#define REGS_MARKER	0x7265677368657265ul
++#define FRAME_MARKER	12
++#else
++#define MIN_STACK_FRAME	16
++#define FRAME_LR_SAVE	1
++#define INT_FRAME_SIZE	(sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
++#define REGS_MARKER	0x72656773ul
++#define FRAME_MARKER	2
++#endif
++
++unsigned long get_wchan(struct task_struct *p)
++{
++	unsigned long ip, sp;
++	int count = 0;
++
++	if (!p || p == current || p->state == TASK_RUNNING)
++		return 0;
++
++	sp = p->thread.ksp;
++	if (!validate_sp(sp, p, MIN_STACK_FRAME))
++		return 0;
++
++	do {
++		sp = *(unsigned long *)sp;
++		if (!validate_sp(sp, p, MIN_STACK_FRAME))
++			return 0;
++		if (count > 0) {
++			ip = ((unsigned long *)sp)[FRAME_LR_SAVE];
++			if (!in_sched_functions(ip))
++				return ip;
++		}
++	} while (count++ < 16);
++	return 0;
++}
++EXPORT_SYMBOL(get_wchan);
++
++static int kstack_depth_to_print = 64;
++
++void show_stack(struct task_struct *tsk, unsigned long *stack)
++{
++	unsigned long sp, ip, lr, newsp;
++	int count = 0;
++	int firstframe = 1;
++
++	sp = (unsigned long) stack;
++	if (tsk == NULL)
++		tsk = current;
++	if (sp == 0) {
++		if (tsk == current)
++			asm("mr %0,1" : "=r" (sp));
++		else
++			sp = tsk->thread.ksp;
++	}
++
++	lr = 0;
++	printk("Call Trace:\n");
++	do {
++		if (!validate_sp(sp, tsk, MIN_STACK_FRAME))
++			return;
++
++		stack = (unsigned long *) sp;
++		newsp = stack[0];
++		ip = stack[FRAME_LR_SAVE];
++		if (!firstframe || ip != lr) {
++			printk("["REG"] ["REG"] ", sp, ip);
++			print_symbol("%s", ip);
++			if (firstframe)
++				printk(" (unreliable)");
++			printk("\n");
++		}
++		firstframe = 0;
++
++		/*
++		 * See if this is an exception frame.
++		 * We look for the "regshere" marker in the current frame.
++		 */
++		if (validate_sp(sp, tsk, INT_FRAME_SIZE)
++		    && stack[FRAME_MARKER] == REGS_MARKER) {
++			struct pt_regs *regs = (struct pt_regs *)
++				(sp + STACK_FRAME_OVERHEAD);
++			printk("--- Exception: %lx", regs->trap);
++			print_symbol(" at %s\n", regs->nip);
++			lr = regs->link;
++			print_symbol("    LR = %s\n", lr);
++			firstframe = 1;
++		}
++
++		sp = newsp;
++	} while (count++ < kstack_depth_to_print);
++}
++
++void dump_stack(void)
++{
++	show_stack(current, NULL);
++}
++EXPORT_SYMBOL(dump_stack);
+diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/prom.c
+@@ -0,0 +1,2170 @@
++/*
++ * 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 
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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 <stdarg.h>
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/threads.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/stringify.h>
++#include <linux/delay.h>
++#include <linux/initrd.h>
++#include <linux/bitops.h>
++#include <linux/module.h>
++
++#include <asm/prom.h>
++#include <asm/rtas.h>
++#include <asm/lmb.h>
++#include <asm/page.h>
++#include <asm/processor.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/smp.h>
++#include <asm/system.h>
++#include <asm/mmu.h>
++#include <asm/pgtable.h>
++#include <asm/pci.h>
++#include <asm/iommu.h>
++#include <asm/btext.h>
++#include <asm/sections.h>
++#include <asm/machdep.h>
++#include <asm/pSeries_reconfig.h>
++#include <asm/pci-bridge.h>
++#ifdef CONFIG_PPC64
++#include <asm/systemcfg.h>
++#endif
++
++#ifdef DEBUG
++#define DBG(fmt...) printk(KERN_ERR fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++struct pci_reg_property {
++	struct pci_address addr;
++	u32 size_hi;
++	u32 size_lo;
++};
++
++struct isa_reg_property {
++	u32 space;
++	u32 address;
++	u32 size;
++};
++
++
++typedef int interpret_func(struct device_node *, unsigned long *,
++			   int, int, int);
++
++extern struct rtas_t rtas;
++extern struct lmb lmb;
++extern unsigned long klimit;
++
++static int __initdata dt_root_addr_cells;
++static int __initdata dt_root_size_cells;
++
++#ifdef CONFIG_PPC64
++static int __initdata iommu_is_off;
++int __initdata iommu_force_on;
++unsigned long tce_alloc_start, tce_alloc_end;
++#endif
++
++typedef u32 cell_t;
++
++#if 0
++static struct boot_param_header *initial_boot_params __initdata;
++#else
++struct boot_param_header *initial_boot_params;
++#endif
++
++static struct device_node *allnodes = NULL;
++
++/* use when traversing tree through the allnext, child, sibling,
++ * or parent members of struct device_node.
++ */
++static DEFINE_RWLOCK(devtree_lock);
++
++/* export that to outside world */
++struct device_node *of_chosen;
++
++struct device_node *dflt_interrupt_controller;
++int num_interrupt_controllers;
++
++/*
++ * Wrapper for allocating memory for various data that needs to be
++ * attached to device nodes as they are processed at boot or when
++ * added to the device tree later (e.g. DLPAR).  At boot there is
++ * already a region reserved so we just increment *mem_start by size;
++ * otherwise we call kmalloc.
++ */
++static void * prom_alloc(unsigned long size, unsigned long *mem_start)
++{
++	unsigned long tmp;
++
++	if (!mem_start)
++		return kmalloc(size, GFP_KERNEL);
++
++	tmp = *mem_start;
++	*mem_start += size;
++	return (void *)tmp;
++}
++
++/*
++ * Find the device_node with a given phandle.
++ */
++static struct device_node * find_phandle(phandle ph)
++{
++	struct device_node *np;
++
++	for (np = allnodes; np != 0; np = np->allnext)
++		if (np->linux_phandle == ph)
++			return np;
++	return NULL;
++}
++
++/*
++ * Find the interrupt parent of a node.
++ */
++static struct device_node * __devinit intr_parent(struct device_node *p)
++{
++	phandle *parp;
++
++	parp = (phandle *) get_property(p, "interrupt-parent", NULL);
++	if (parp == NULL)
++		return p->parent;
++	p = find_phandle(*parp);
++	if (p != NULL)
++		return p;
++	/*
++	 * On a powermac booted with BootX, we don't get to know the
++	 * phandles for any nodes, so find_phandle will return NULL.
++	 * Fortunately these machines only have one interrupt controller
++	 * so there isn't in fact any ambiguity.  -- paulus
++	 */
++	if (num_interrupt_controllers == 1)
++		p = dflt_interrupt_controller;
++	return p;
++}
++
++/*
++ * Find out the size of each entry of the interrupts property
++ * for a node.
++ */
++int __devinit prom_n_intr_cells(struct device_node *np)
++{
++	struct device_node *p;
++	unsigned int *icp;
++
++	for (p = np; (p = intr_parent(p)) != NULL; ) {
++		icp = (unsigned int *)
++			get_property(p, "#interrupt-cells", NULL);
++		if (icp != NULL)
++			return *icp;
++		if (get_property(p, "interrupt-controller", NULL) != NULL
++		    || get_property(p, "interrupt-map", NULL) != NULL) {
++			printk("oops, node %s doesn't have #interrupt-cells\n",
++			       p->full_name);
++			return 1;
++		}
++	}
++#ifdef DEBUG_IRQ
++	printk("prom_n_intr_cells failed for %s\n", np->full_name);
++#endif
++	return 1;
++}
++
++/*
++ * Map an interrupt from a device up to the platform interrupt
++ * descriptor.
++ */
++static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler,
++				   struct device_node *np, unsigned int *ints,
++				   int nintrc)
++{
++	struct device_node *p, *ipar;
++	unsigned int *imap, *imask, *ip;
++	int i, imaplen, match;
++	int newintrc = 0, newaddrc = 0;
++	unsigned int *reg;
++	int naddrc;
++
++	reg = (unsigned int *) get_property(np, "reg", NULL);
++	naddrc = prom_n_addr_cells(np);
++	p = intr_parent(np);
++	while (p != NULL) {
++		if (get_property(p, "interrupt-controller", NULL) != NULL)
++			/* this node is an interrupt controller, stop here */
++			break;
++		imap = (unsigned int *)
++			get_property(p, "interrupt-map", &imaplen);
++		if (imap == NULL) {
++			p = intr_parent(p);
++			continue;
++		}
++		imask = (unsigned int *)
++			get_property(p, "interrupt-map-mask", NULL);
++		if (imask == NULL) {
++			printk("oops, %s has interrupt-map but no mask\n",
++			       p->full_name);
++			return 0;
++		}
++		imaplen /= sizeof(unsigned int);
++		match = 0;
++		ipar = NULL;
++		while (imaplen > 0 && !match) {
++			/* check the child-interrupt field */
++			match = 1;
++			for (i = 0; i < naddrc && match; ++i)
++				match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
++			for (; i < naddrc + nintrc && match; ++i)
++				match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
++			imap += naddrc + nintrc;
++			imaplen -= naddrc + nintrc;
++			/* grab the interrupt parent */
++			ipar = find_phandle((phandle) *imap++);
++			--imaplen;
++			if (ipar == NULL && num_interrupt_controllers == 1)
++				/* cope with BootX not giving us phandles */
++				ipar = dflt_interrupt_controller;
++			if (ipar == NULL) {
++				printk("oops, no int parent %x in map of %s\n",
++				       imap[-1], p->full_name);
++				return 0;
++			}
++			/* find the parent's # addr and intr cells */
++			ip = (unsigned int *)
++				get_property(ipar, "#interrupt-cells", NULL);
++			if (ip == NULL) {
++				printk("oops, no #interrupt-cells on %s\n",
++				       ipar->full_name);
++				return 0;
++			}
++			newintrc = *ip;
++			ip = (unsigned int *)
++				get_property(ipar, "#address-cells", NULL);
++			newaddrc = (ip == NULL)? 0: *ip;
++			imap += newaddrc + newintrc;
++			imaplen -= newaddrc + newintrc;
++		}
++		if (imaplen < 0) {
++			printk("oops, error decoding int-map on %s, len=%d\n",
++			       p->full_name, imaplen);
++			return 0;
++		}
++		if (!match) {
++#ifdef DEBUG_IRQ
++			printk("oops, no match in %s int-map for %s\n",
++			       p->full_name, np->full_name);
++#endif
++			return 0;
++		}
++		p = ipar;
++		naddrc = newaddrc;
++		nintrc = newintrc;
++		ints = imap - nintrc;
++		reg = ints - naddrc;
++	}
++	if (p == NULL) {
++#ifdef DEBUG_IRQ
++		printk("hmmm, int tree for %s doesn't have ctrler\n",
++		       np->full_name);
++#endif
++		return 0;
++	}
++	*irq = ints;
++	*ictrler = p;
++	return nintrc;
++}
++
++static unsigned char map_isa_senses[4] = {
++	IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE,
++	IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE,
++	IRQ_SENSE_EDGE  | IRQ_POLARITY_NEGATIVE,
++	IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE
++};
++
++static unsigned char map_mpic_senses[4] = {
++	IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE,
++	IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE,
++	/* 2 seems to be used for the 8259 cascade... */
++	IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE,
++	IRQ_SENSE_EDGE  | IRQ_POLARITY_NEGATIVE,
++};
++
++static int __devinit finish_node_interrupts(struct device_node *np,
++					    unsigned long *mem_start,
++					    int measure_only)
++{
++	unsigned int *ints;
++	int intlen, intrcells, intrcount;
++	int i, j, n, sense;
++	unsigned int *irq, virq;
++	struct device_node *ic;
++
++	if (num_interrupt_controllers == 0) {
++		/*
++		 * Old machines just have a list of interrupt numbers
++		 * and no interrupt-controller nodes.
++		 */
++		ints = (unsigned int *) get_property(np, "AAPL,interrupts",
++						     &intlen);
++		/* XXX old interpret_pci_props looked in parent too */
++		/* XXX old interpret_macio_props looked for interrupts
++		   before AAPL,interrupts */
++		if (ints == NULL)
++			ints = (unsigned int *) get_property(np, "interrupts",
++							     &intlen);
++		if (ints == NULL)
++			return 0;
++
++		np->n_intrs = intlen / sizeof(unsigned int);
++		np->intrs = prom_alloc(np->n_intrs * sizeof(np->intrs[0]),
++				       mem_start);
++		if (!np->intrs)
++			return -ENOMEM;
++		if (measure_only)
++			return 0;
++
++		for (i = 0; i < np->n_intrs; ++i) {
++			np->intrs[i].line = *ints++;
++			np->intrs[i].sense = IRQ_SENSE_LEVEL
++				| IRQ_POLARITY_NEGATIVE;
++		}
++		return 0;
++	}
++
++	ints = (unsigned int *) get_property(np, "interrupts", &intlen);
++	if (ints == NULL)
++		return 0;
++	intrcells = prom_n_intr_cells(np);
++	intlen /= intrcells * sizeof(unsigned int);
++
++	np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
++	if (!np->intrs)
++		return -ENOMEM;
++
++	if (measure_only)
++		return 0;
++
++	intrcount = 0;
++	for (i = 0; i < intlen; ++i, ints += intrcells) {
++		n = map_interrupt(&irq, &ic, np, ints, intrcells);
++		if (n <= 0)
++			continue;
++
++		/* don't map IRQ numbers under a cascaded 8259 controller */
++		if (ic && device_is_compatible(ic, "chrp,iic")) {
++			np->intrs[intrcount].line = irq[0];
++			sense = (n > 1)? (irq[1] & 3): 3;
++			np->intrs[intrcount].sense = map_isa_senses[sense];
++		} else {
++			virq = virt_irq_create_mapping(irq[0]);
++#ifdef CONFIG_PPC64
++			if (virq == NO_IRQ) {
++				printk(KERN_CRIT "Could not allocate interrupt"
++				       " number for %s\n", np->full_name);
++				continue;
++			}
++#endif
++			np->intrs[intrcount].line = irq_offset_up(virq);
++			sense = (n > 1)? (irq[1] & 3): 1;
++			np->intrs[intrcount].sense = map_mpic_senses[sense];
++		}
++
++#ifdef CONFIG_PPC64
++		/* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
++		if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
++			char *name = get_property(ic->parent, "name", NULL);
++			if (name && !strcmp(name, "u3"))
++				np->intrs[intrcount].line += 128;
++			else if (!(name && !strcmp(name, "mac-io")))
++				/* ignore other cascaded controllers, such as
++				   the k2-sata-root */
++				break;
++		}
++#endif
++		if (n > 2) {
++			printk("hmmm, got %d intr cells for %s:", n,
++			       np->full_name);
++			for (j = 0; j < n; ++j)
++				printk(" %d", irq[j]);
++			printk("\n");
++		}
++		++intrcount;
++	}
++	np->n_intrs = intrcount;
++
++	return 0;
++}
++
++static int __devinit interpret_pci_props(struct device_node *np,
++					 unsigned long *mem_start,
++					 int naddrc, int nsizec,
++					 int measure_only)
++{
++	struct address_range *adr;
++	struct pci_reg_property *pci_addrs;
++	int i, l, n_addrs;
++
++	pci_addrs = (struct pci_reg_property *)
++		get_property(np, "assigned-addresses", &l);
++	if (!pci_addrs)
++		return 0;
++
++	n_addrs = l / sizeof(*pci_addrs);
++
++	adr = prom_alloc(n_addrs * sizeof(*adr), mem_start);
++	if (!adr)
++		return -ENOMEM;
++
++ 	if (measure_only)
++ 		return 0;
++
++ 	np->addrs = adr;
++ 	np->n_addrs = n_addrs;
++
++ 	for (i = 0; i < n_addrs; i++) {
++ 		adr[i].space = pci_addrs[i].addr.a_hi;
++ 		adr[i].address = pci_addrs[i].addr.a_lo |
++			((u64)pci_addrs[i].addr.a_mid << 32);
++ 		adr[i].size = pci_addrs[i].size_lo;
++	}
++
++	return 0;
++}
++
++static int __init interpret_dbdma_props(struct device_node *np,
++					unsigned long *mem_start,
++					int naddrc, int nsizec,
++					int measure_only)
++{
++	struct reg_property32 *rp;
++	struct address_range *adr;
++	unsigned long base_address;
++	int i, l;
++	struct device_node *db;
++
++	base_address = 0;
++	if (!measure_only) {
++		for (db = np->parent; db != NULL; db = db->parent) {
++			if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
++				base_address = db->addrs[0].address;
++				break;
++			}
++		}
++	}
++
++	rp = (struct reg_property32 *) get_property(np, "reg", &l);
++	if (rp != 0 && l >= sizeof(struct reg_property32)) {
++		i = 0;
++		adr = (struct address_range *) (*mem_start);
++		while ((l -= sizeof(struct reg_property32)) >= 0) {
++			if (!measure_only) {
++				adr[i].space = 2;
++				adr[i].address = rp[i].address + base_address;
++				adr[i].size = rp[i].size;
++			}
++			++i;
++		}
++		np->addrs = adr;
++		np->n_addrs = i;
++		(*mem_start) += i * sizeof(struct address_range);
++	}
++
++	return 0;
++}
++
++static int __init interpret_macio_props(struct device_node *np,
++					unsigned long *mem_start,
++					int naddrc, int nsizec,
++					int measure_only)
++{
++	struct reg_property32 *rp;
++	struct address_range *adr;
++	unsigned long base_address;
++	int i, l;
++	struct device_node *db;
++
++	base_address = 0;
++	if (!measure_only) {
++		for (db = np->parent; db != NULL; db = db->parent) {
++			if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
++				base_address = db->addrs[0].address;
++				break;
++			}
++		}
++	}
++
++	rp = (struct reg_property32 *) get_property(np, "reg", &l);
++	if (rp != 0 && l >= sizeof(struct reg_property32)) {
++		i = 0;
++		adr = (struct address_range *) (*mem_start);
++		while ((l -= sizeof(struct reg_property32)) >= 0) {
++			if (!measure_only) {
++				adr[i].space = 2;
++				adr[i].address = rp[i].address + base_address;
++				adr[i].size = rp[i].size;
++			}
++			++i;
++		}
++		np->addrs = adr;
++		np->n_addrs = i;
++		(*mem_start) += i * sizeof(struct address_range);
++	}
++
++	return 0;
++}
++
++static int __init interpret_isa_props(struct device_node *np,
++				      unsigned long *mem_start,
++				      int naddrc, int nsizec,
++				      int measure_only)
++{
++	struct isa_reg_property *rp;
++	struct address_range *adr;
++	int i, l;
++
++	rp = (struct isa_reg_property *) get_property(np, "reg", &l);
++	if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
++		i = 0;
++		adr = (struct address_range *) (*mem_start);
++		while ((l -= sizeof(struct isa_reg_property)) >= 0) {
++			if (!measure_only) {
++				adr[i].space = rp[i].space;
++				adr[i].address = rp[i].address;
++				adr[i].size = rp[i].size;
++			}
++			++i;
++		}
++		np->addrs = adr;
++		np->n_addrs = i;
++		(*mem_start) += i * sizeof(struct address_range);
++	}
++
++	return 0;
++}
++
++static int __init interpret_root_props(struct device_node *np,
++				       unsigned long *mem_start,
++				       int naddrc, int nsizec,
++				       int measure_only)
++{
++	struct address_range *adr;
++	int i, l;
++	unsigned int *rp;
++	int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
++
++	rp = (unsigned int *) get_property(np, "reg", &l);
++	if (rp != 0 && l >= rpsize) {
++		i = 0;
++		adr = (struct address_range *) (*mem_start);
++		while ((l -= rpsize) >= 0) {
++			if (!measure_only) {
++				adr[i].space = 0;
++				adr[i].address = rp[naddrc - 1];
++				adr[i].size = rp[naddrc + nsizec - 1];
++			}
++			++i;
++			rp += naddrc + nsizec;
++		}
++		np->addrs = adr;
++		np->n_addrs = i;
++		(*mem_start) += i * sizeof(struct address_range);
++	}
++
++	return 0;
++}
++
++static int __devinit finish_node(struct device_node *np,
++				 unsigned long *mem_start,
++				 interpret_func *ifunc,
++				 int naddrc, int nsizec,
++				 int measure_only)
++{
++	struct device_node *child;
++	int *ip, rc = 0;
++
++	/* get the device addresses and interrupts */
++	if (ifunc != NULL)
++		rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
++	if (rc)
++		goto out;
++
++	rc = finish_node_interrupts(np, mem_start, measure_only);
++	if (rc)
++		goto out;
++
++	/* Look for #address-cells and #size-cells properties. */
++	ip = (int *) get_property(np, "#address-cells", NULL);
++	if (ip != NULL)
++		naddrc = *ip;
++	ip = (int *) get_property(np, "#size-cells", NULL);
++	if (ip != NULL)
++		nsizec = *ip;
++
++	if (!strcmp(np->name, "device-tree") || np->parent == NULL)
++		ifunc = interpret_root_props;
++	else if (np->type == 0)
++		ifunc = NULL;
++	else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
++		ifunc = interpret_pci_props;
++	else if (!strcmp(np->type, "dbdma"))
++		ifunc = interpret_dbdma_props;
++	else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
++		ifunc = interpret_macio_props;
++	else if (!strcmp(np->type, "isa"))
++		ifunc = interpret_isa_props;
++	else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
++		ifunc = interpret_root_props;
++	else if (!((ifunc == interpret_dbdma_props
++		    || ifunc == interpret_macio_props)
++		   && (!strcmp(np->type, "escc")
++		       || !strcmp(np->type, "media-bay"))))
++		ifunc = NULL;
++
++	for (child = np->child; child != NULL; child = child->sibling) {
++		rc = finish_node(child, mem_start, ifunc,
++				 naddrc, nsizec, measure_only);
++		if (rc)
++			goto out;
++	}
++out:
++	return rc;
++}
++
++static void __init scan_interrupt_controllers(void)
++{
++	struct device_node *np;
++	int n = 0;
++	char *name, *ic;
++	int iclen;
++
++	for (np = allnodes; np != NULL; np = np->allnext) {
++		ic = get_property(np, "interrupt-controller", &iclen);
++		name = get_property(np, "name", NULL);
++		/* checking iclen makes sure we don't get a false
++		   match on /chosen.interrupt_controller */
++		if ((name != NULL
++		     && strcmp(name, "interrupt-controller") == 0)
++		    || (ic != NULL && iclen == 0
++			&& strcmp(name, "AppleKiwi"))) {
++			if (n == 0)
++				dflt_interrupt_controller = np;
++			++n;
++		}
++	}
++	num_interrupt_controllers = n;
++}
++
++/**
++ * finish_device_tree is called once things are running normally
++ * (i.e. with text and data mapped to the address they were linked at).
++ * It traverses the device tree and fills in some of the additional,
++ * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt
++ * mapping is also initialized at this point.
++ */
++void __init finish_device_tree(void)
++{
++	unsigned long start, end, size = 0;
++
++	DBG(" -> finish_device_tree\n");
++
++#ifdef CONFIG_PPC64
++	/* Initialize virtual IRQ map */
++	virt_irq_init();
++#endif
++	scan_interrupt_controllers();
++
++	/*
++	 * Finish device-tree (pre-parsing some properties etc...)
++	 * We do this in 2 passes. One with "measure_only" set, which
++	 * will only measure the amount of memory needed, then we can
++	 * allocate that memory, and call finish_node again. However,
++	 * we must be careful as most routines will fail nowadays when
++	 * prom_alloc() returns 0, so we must make sure our first pass
++	 * doesn't start at 0. We pre-initialize size to 16 for that
++	 * reason and then remove those additional 16 bytes
++	 */
++	size = 16;
++	finish_node(allnodes, &size, NULL, 0, 0, 1);
++	size -= 16;
++	end = start = (unsigned long) __va(lmb_alloc(size, 128));
++	finish_node(allnodes, &end, NULL, 0, 0, 0);
++	BUG_ON(end != start + size);
++
++	DBG(" <- finish_device_tree\n");
++}
++
++static inline char *find_flat_dt_string(u32 offset)
++{
++	return ((char *)initial_boot_params) +
++		initial_boot_params->off_dt_strings + offset;
++}
++
++/**
++ * This function is used to scan the flattened device-tree, it is
++ * used to extract the memory informations at boot before we can
++ * unflatten the tree
++ */
++static int __init scan_flat_dt(int (*it)(unsigned long node,
++					 const char *uname, int depth,
++					 void *data),
++			       void *data)
++{
++	unsigned long p = ((unsigned long)initial_boot_params) +
++		initial_boot_params->off_dt_struct;
++	int rc = 0;
++	int depth = -1;
++
++	do {
++		u32 tag = *((u32 *)p);
++		char *pathp;
++		
++		p += 4;
++		if (tag == OF_DT_END_NODE) {
++			depth --;
++			continue;
++		}
++		if (tag == OF_DT_NOP)
++			continue;
++		if (tag == OF_DT_END)
++			break;
++		if (tag == OF_DT_PROP) {
++			u32 sz = *((u32 *)p);
++			p += 8;
++			if (initial_boot_params->version < 0x10)
++				p = _ALIGN(p, sz >= 8 ? 8 : 4);
++			p += sz;
++			p = _ALIGN(p, 4);
++			continue;
++		}
++		if (tag != OF_DT_BEGIN_NODE) {
++			printk(KERN_WARNING "Invalid tag %x scanning flattened"
++			       " device tree !\n", tag);
++			return -EINVAL;
++		}
++		depth++;
++		pathp = (char *)p;
++		p = _ALIGN(p + strlen(pathp) + 1, 4);
++		if ((*pathp) == '/') {
++			char *lp, *np;
++			for (lp = NULL, np = pathp; *np; np++)
++				if ((*np) == '/')
++					lp = np+1;
++			if (lp != NULL)
++				pathp = lp;
++		}
++		rc = it(p, pathp, depth, data);
++		if (rc != 0)
++			break;		
++	} while(1);
++
++	return rc;
++}
++
++/**
++ * This  function can be used within scan_flattened_dt callback to get
++ * access to properties
++ */
++static void* __init get_flat_dt_prop(unsigned long node, const char *name,
++				     unsigned long *size)
++{
++	unsigned long p = node;
++
++	do {
++		u32 tag = *((u32 *)p);
++		u32 sz, noff;
++		const char *nstr;
++
++		p += 4;
++		if (tag == OF_DT_NOP)
++			continue;
++		if (tag != OF_DT_PROP)
++			return NULL;
++
++		sz = *((u32 *)p);
++		noff = *((u32 *)(p + 4));
++		p += 8;
++		if (initial_boot_params->version < 0x10)
++			p = _ALIGN(p, sz >= 8 ? 8 : 4);
++
++		nstr = find_flat_dt_string(noff);
++		if (nstr == NULL) {
++			printk(KERN_WARNING "Can't find property index"
++			       " name !\n");
++			return NULL;
++		}
++		if (strcmp(name, nstr) == 0) {
++			if (size)
++				*size = sz;
++			return (void *)p;
++		}
++		p += sz;
++		p = _ALIGN(p, 4);
++	} while(1);
++}
++
++static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
++				       unsigned long align)
++{
++	void *res;
++
++	*mem = _ALIGN(*mem, align);
++	res = (void *)*mem;
++	*mem += size;
++
++	return res;
++}
++
++static unsigned long __init unflatten_dt_node(unsigned long mem,
++					      unsigned long *p,
++					      struct device_node *dad,
++					      struct device_node ***allnextpp,
++					      unsigned long fpsize)
++{
++	struct device_node *np;
++	struct property *pp, **prev_pp = NULL;
++	char *pathp;
++	u32 tag;
++	unsigned int l, allocl;
++	int has_name = 0;
++	int new_format = 0;
++
++	tag = *((u32 *)(*p));
++	if (tag != OF_DT_BEGIN_NODE) {
++		printk("Weird tag at start of node: %x\n", tag);
++		return mem;
++	}
++	*p += 4;
++	pathp = (char *)*p;
++	l = allocl = strlen(pathp) + 1;
++	*p = _ALIGN(*p + l, 4);
++
++	/* version 0x10 has a more compact unit name here instead of the full
++	 * path. we accumulate the full path size using "fpsize", we'll rebuild
++	 * it later. We detect this because the first character of the name is
++	 * not '/'.
++	 */
++	if ((*pathp) != '/') {
++		new_format = 1;
++		if (fpsize == 0) {
++			/* root node: special case. fpsize accounts for path
++			 * plus terminating zero. root node only has '/', so
++			 * fpsize should be 2, but we want to avoid the first
++			 * level nodes to have two '/' so we use fpsize 1 here
++			 */
++			fpsize = 1;
++			allocl = 2;
++		} else {
++			/* account for '/' and path size minus terminal 0
++			 * already in 'l'
++			 */
++			fpsize += l;
++			allocl = fpsize;
++		}
++	}
++
++
++	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
++				__alignof__(struct device_node));
++	if (allnextpp) {
++		memset(np, 0, sizeof(*np));
++		np->full_name = ((char*)np) + sizeof(struct device_node);
++		if (new_format) {
++			char *p = np->full_name;
++			/* rebuild full path for new format */
++			if (dad && dad->parent) {
++				strcpy(p, dad->full_name);
++#ifdef DEBUG
++				if ((strlen(p) + l + 1) != allocl) {
++					DBG("%s: p: %d, l: %d, a: %d\n",
++					    pathp, strlen(p), l, allocl);
++				}
++#endif
++				p += strlen(p);
++			}
++			*(p++) = '/';
++			memcpy(p, pathp, l);
++		} else
++			memcpy(np->full_name, pathp, l);
++		prev_pp = &np->properties;
++		**allnextpp = np;
++		*allnextpp = &np->allnext;
++		if (dad != NULL) {
++			np->parent = dad;
++			/* we temporarily use the next field as `last_child'*/
++			if (dad->next == 0)
++				dad->child = np;
++			else
++				dad->next->sibling = np;
++			dad->next = np;
++		}
++		kref_init(&np->kref);
++	}
++	while(1) {
++		u32 sz, noff;
++		char *pname;
++
++		tag = *((u32 *)(*p));
++		if (tag == OF_DT_NOP) {
++			*p += 4;
++			continue;
++		}
++		if (tag != OF_DT_PROP)
++			break;
++		*p += 4;
++		sz = *((u32 *)(*p));
++		noff = *((u32 *)((*p) + 4));
++		*p += 8;
++		if (initial_boot_params->version < 0x10)
++			*p = _ALIGN(*p, sz >= 8 ? 8 : 4);
++
++		pname = find_flat_dt_string(noff);
++		if (pname == NULL) {
++			printk("Can't find property name in list !\n");
++			break;
++		}
++		if (strcmp(pname, "name") == 0)
++			has_name = 1;
++		l = strlen(pname) + 1;
++		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
++					__alignof__(struct property));
++		if (allnextpp) {
++			if (strcmp(pname, "linux,phandle") == 0) {
++				np->node = *((u32 *)*p);
++				if (np->linux_phandle == 0)
++					np->linux_phandle = np->node;
++			}
++			if (strcmp(pname, "ibm,phandle") == 0)
++				np->linux_phandle = *((u32 *)*p);
++			pp->name = pname;
++			pp->length = sz;
++			pp->value = (void *)*p;
++			*prev_pp = pp;
++			prev_pp = &pp->next;
++		}
++		*p = _ALIGN((*p) + sz, 4);
++	}
++	/* with version 0x10 we may not have the name property, recreate
++	 * it here from the unit name if absent
++	 */
++	if (!has_name) {
++		char *p = pathp, *ps = pathp, *pa = NULL;
++		int sz;
++
++		while (*p) {
++			if ((*p) == '@')
++				pa = p;
++			if ((*p) == '/')
++				ps = p + 1;
++			p++;
++		}
++		if (pa < ps)
++			pa = p;
++		sz = (pa - ps) + 1;
++		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
++					__alignof__(struct property));
++		if (allnextpp) {
++			pp->name = "name";
++			pp->length = sz;
++			pp->value = (unsigned char *)(pp + 1);
++			*prev_pp = pp;
++			prev_pp = &pp->next;
++			memcpy(pp->value, ps, sz - 1);
++			((char *)pp->value)[sz - 1] = 0;
++			DBG("fixed up name for %s -> %s\n", pathp, pp->value);
++		}
++	}
++	if (allnextpp) {
++		*prev_pp = NULL;
++		np->name = get_property(np, "name", NULL);
++		np->type = get_property(np, "device_type", NULL);
++
++		if (!np->name)
++			np->name = "<NULL>";
++		if (!np->type)
++			np->type = "<NULL>";
++	}
++	while (tag == OF_DT_BEGIN_NODE) {
++		mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
++		tag = *((u32 *)(*p));
++	}
++	if (tag != OF_DT_END_NODE) {
++		printk("Weird tag at end of node: %x\n", tag);
++		return mem;
++	}
++	*p += 4;
++	return mem;
++}
++
++
++/**
++ * unflattens the device-tree passed by the firmware, creating the
++ * tree of struct device_node. It also fills the "name" and "type"
++ * pointers of the nodes so the normal device-tree walking functions
++ * can be used (this used to be done by finish_device_tree)
++ */
++void __init unflatten_device_tree(void)
++{
++	unsigned long start, mem, size;
++	struct device_node **allnextp = &allnodes;
++	char *p = NULL;
++	int l = 0;
++
++	DBG(" -> unflatten_device_tree()\n");
++
++	/* First pass, scan for size */
++	start = ((unsigned long)initial_boot_params) +
++		initial_boot_params->off_dt_struct;
++	size = unflatten_dt_node(0, &start, NULL, NULL, 0);
++	size = (size | 3) + 1;
++
++	DBG("  size is %lx, allocating...\n", size);
++
++	/* Allocate memory for the expanded device tree */
++	mem = lmb_alloc(size + 4, __alignof__(struct device_node));
++	if (!mem) {
++		DBG("Couldn't allocate memory with lmb_alloc()!\n");
++		panic("Couldn't allocate memory with lmb_alloc()!\n");
++	}
++	mem = (unsigned long) __va(mem);
++
++	((u32 *)mem)[size / 4] = 0xdeadbeef;
++
++	DBG("  unflattening %lx...\n", mem);
++
++	/* Second pass, do actual unflattening */
++	start = ((unsigned long)initial_boot_params) +
++		initial_boot_params->off_dt_struct;
++	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
++	if (*((u32 *)start) != OF_DT_END)
++		printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start));
++	if (((u32 *)mem)[size / 4] != 0xdeadbeef)
++		printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
++		       ((u32 *)mem)[size / 4] );
++	*allnextp = NULL;
++
++	/* Get pointer to OF "/chosen" node for use everywhere */
++	of_chosen = of_find_node_by_path("/chosen");
++	if (of_chosen == NULL)
++		of_chosen = of_find_node_by_path("/chosen at 0");
++
++	/* Retreive command line */
++	if (of_chosen != NULL) {
++		p = (char *)get_property(of_chosen, "bootargs", &l);
++		if (p != NULL && l > 0)
++			strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE));
++	}
++#ifdef CONFIG_CMDLINE
++	if (l == 0 || (l == 1 && (*p) == 0))
++		strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
++#endif /* CONFIG_CMDLINE */
++
++	DBG("Command line is: %s\n", cmd_line);
++
++	DBG(" <- unflatten_device_tree()\n");
++}
++
++
++static int __init early_init_dt_scan_cpus(unsigned long node,
++					  const char *uname, int depth, void *data)
++{
++	char *type = get_flat_dt_prop(node, "device_type", NULL);
++	u32 *prop;
++	unsigned long size = 0;
++
++	/* We are scanning "cpu" nodes only */
++	if (type == NULL || strcmp(type, "cpu") != 0)
++		return 0;
++
++#ifdef CONFIG_PPC_PSERIES
++	/* On LPAR, look for the first ibm,pft-size property for the  hash table size
++	 */
++	if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) {
++		u32 *pft_size;
++		pft_size = get_flat_dt_prop(node, "ibm,pft-size", NULL);
++		if (pft_size != NULL) {
++			/* pft_size[0] is the NUMA CEC cookie */
++			ppc64_pft_size = pft_size[1];
++		}
++	}
++#endif
++
++	boot_cpuid = 0;
++	boot_cpuid_phys = 0;
++	if (initial_boot_params && initial_boot_params->version >= 2) {
++		/* version 2 of the kexec param format adds the phys cpuid
++		 * of booted proc.
++		 */
++		boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
++	} else {
++		/* Check if it's the boot-cpu, set it's hw index now */
++		if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) {
++			prop = get_flat_dt_prop(node, "reg", NULL);
++			if (prop != NULL)
++				boot_cpuid_phys = *prop;
++		}
++	}
++	set_hard_smp_processor_id(0, boot_cpuid_phys);
++
++#ifdef CONFIG_ALTIVEC
++	/* Check if we have a VMX and eventually update CPU features */
++	prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", &size);
++	if (prop && (*prop) > 0) {
++		cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
++		cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
++	}
++
++	/* Same goes for Apple's "altivec" property */
++	prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL);
++	if (prop) {
++		cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
++		cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
++	}
++#endif /* CONFIG_ALTIVEC */
++
++#ifdef CONFIG_PPC_PSERIES
++	/*
++	 * Check for an SMT capable CPU and set the CPU feature. We do
++	 * this by looking at the size of the ibm,ppc-interrupt-server#s
++	 * property
++	 */
++	prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
++				       &size);
++	cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
++	if (prop && ((size / sizeof(u32)) > 1))
++		cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
++#endif
++
++	return 0;
++}
++
++static int __init early_init_dt_scan_chosen(unsigned long node,
++					    const char *uname, int depth, void *data)
++{
++	u32 *prop;
++	unsigned long *lprop;
++
++	DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
++
++	if (depth != 1 ||
++	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen at 0") != 0))
++		return 0;
++
++	/* get platform type */
++	prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL);
++	if (prop == NULL)
++		return 0;
++#ifdef CONFIG_PPC64
++	systemcfg->platform = *prop;
++#else
++#ifdef CONFIG_PPC_MULTIPLATFORM
++	_machine = *prop;
++#endif
++#endif
++
++#ifdef CONFIG_PPC64
++	/* check if iommu is forced on or off */
++	if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
++		iommu_is_off = 1;
++	if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
++		iommu_force_on = 1;
++#endif
++
++ 	lprop = get_flat_dt_prop(node, "linux,memory-limit", NULL);
++ 	if (lprop)
++ 		memory_limit = *lprop;
++
++#ifdef CONFIG_PPC64
++ 	lprop = get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
++ 	if (lprop)
++ 		tce_alloc_start = *lprop;
++ 	lprop = get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
++ 	if (lprop)
++ 		tce_alloc_end = *lprop;
++#endif
++
++#ifdef CONFIG_PPC_RTAS
++	/* To help early debugging via the front panel, we retreive a minimal
++	 * set of RTAS infos now if available
++	 */
++	{
++		u64 *basep, *entryp;
++
++		basep = get_flat_dt_prop(node, "linux,rtas-base", NULL);
++		entryp = get_flat_dt_prop(node, "linux,rtas-entry", NULL);
++		prop = get_flat_dt_prop(node, "linux,rtas-size", NULL);
++		if (basep && entryp && prop) {
++			rtas.base = *basep;
++			rtas.entry = *entryp;
++			rtas.size = *prop;
++		}
++	}
++#endif /* CONFIG_PPC_RTAS */
++
++	/* break now */
++	return 1;
++}
++
++static int __init early_init_dt_scan_root(unsigned long node,
++					  const char *uname, int depth, void *data)
++{
++	u32 *prop;
++
++	if (depth != 0)
++		return 0;
++
++	prop = get_flat_dt_prop(node, "#size-cells", NULL);
++	dt_root_size_cells = (prop == NULL) ? 1 : *prop;
++	DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
++
++	prop = get_flat_dt_prop(node, "#address-cells", NULL);
++	dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
++	DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
++	
++	/* break now */
++	return 1;
++}
++
++static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
++{
++	cell_t *p = *cellp;
++	unsigned long r;
++
++	/* Ignore more than 2 cells */
++	while (s > sizeof(unsigned long) / 4) {
++		p++;
++		s--;
++	}
++	r = *p++;
++#ifdef CONFIG_PPC64
++	if (s > 1) {
++		r <<= 32;
++		r |= *(p++);
++		s--;
++	}
++#endif
++
++	*cellp = p;
++	return r;
++}
++
++
++static int __init early_init_dt_scan_memory(unsigned long node,
++					    const char *uname, int depth, void *data)
++{
++	char *type = get_flat_dt_prop(node, "device_type", NULL);
++	cell_t *reg, *endp;
++	unsigned long l;
++
++	/* We are scanning "memory" nodes only */
++	if (type == NULL || strcmp(type, "memory") != 0)
++		return 0;
++
++	reg = (cell_t *)get_flat_dt_prop(node, "reg", &l);
++	if (reg == NULL)
++		return 0;
++
++	endp = reg + (l / sizeof(cell_t));
++
++	DBG("memory scan node %s ..., reg size %ld, data: %x %x %x %x, ...\n",
++	    uname, l, reg[0], reg[1], reg[2], reg[3]);
++
++	while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
++		unsigned long base, size;
++
++		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
++		size = dt_mem_next_cell(dt_root_size_cells, &reg);
++
++		if (size == 0)
++			continue;
++		DBG(" - %lx ,  %lx\n", base, size);
++#ifdef CONFIG_PPC64
++		if (iommu_is_off) {
++			if (base >= 0x80000000ul)
++				continue;
++			if ((base + size) > 0x80000000ul)
++				size = 0x80000000ul - base;
++		}
++#endif
++		lmb_add(base, size);
++	}
++	return 0;
++}
++
++static void __init early_reserve_mem(void)
++{
++	unsigned long base, size;
++	unsigned long *reserve_map;
++
++	reserve_map = (unsigned long *)(((unsigned long)initial_boot_params) +
++					initial_boot_params->off_mem_rsvmap);
++	while (1) {
++		base = *(reserve_map++);
++		size = *(reserve_map++);
++		if (size == 0)
++			break;
++		DBG("reserving: %lx -> %lx\n", base, size);
++		lmb_reserve(base, size);
++	}
++
++#if 0
++	DBG("memory reserved, lmbs :\n");
++      	lmb_dump_all();
++#endif
++}
++
++void __init early_init_devtree(void *params)
++{
++	DBG(" -> early_init_devtree()\n");
++
++	/* Setup flat device-tree pointer */
++	initial_boot_params = params;
++
++	/* Retrieve various informations from the /chosen node of the
++	 * device-tree, including the platform type, initrd location and
++	 * size, TCE reserve, and more ...
++	 */
++	scan_flat_dt(early_init_dt_scan_chosen, NULL);
++
++	/* Scan memory nodes and rebuild LMBs */
++	lmb_init();
++	scan_flat_dt(early_init_dt_scan_root, NULL);
++	scan_flat_dt(early_init_dt_scan_memory, NULL);
++	lmb_enforce_memory_limit(memory_limit);
++	lmb_analyze();
++#ifdef CONFIG_PPC64
++	systemcfg->physicalMemorySize = lmb_phys_mem_size();
++#endif
++	lmb_reserve(0, __pa(klimit));
++
++	DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
++
++	/* Reserve LMB regions used by kernel, initrd, dt, etc... */
++	early_reserve_mem();
++
++	DBG("Scanning CPUs ...\n");
++
++	/* Retreive hash table size from flattened tree plus other
++	 * CPU related informations (altivec support, boot CPU ID, ...)
++	 */
++	scan_flat_dt(early_init_dt_scan_cpus, NULL);
++
++	DBG(" <- early_init_devtree()\n");
++}
++
++#undef printk
++
++int
++prom_n_addr_cells(struct device_node* np)
++{
++	int* ip;
++	do {
++		if (np->parent)
++			np = np->parent;
++		ip = (int *) get_property(np, "#address-cells", NULL);
++		if (ip != NULL)
++			return *ip;
++	} while (np->parent);
++	/* No #address-cells property for the root node, default to 1 */
++	return 1;
++}
++
++int
++prom_n_size_cells(struct device_node* np)
++{
++	int* ip;
++	do {
++		if (np->parent)
++			np = np->parent;
++		ip = (int *) 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;
++}
++
++/**
++ * Work out the sense (active-low level / active-high edge)
++ * of each interrupt from the device tree.
++ */
++void __init prom_get_irq_senses(unsigned char *senses, int off, int max)
++{
++	struct device_node *np;
++	int i, j;
++
++	/* default to level-triggered */
++	memset(senses, IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, max - off);
++
++	for (np = allnodes; np != 0; np = np->allnext) {
++		for (j = 0; j < np->n_intrs; j++) {
++			i = np->intrs[j].line;
++			if (i >= off && i < max)
++				senses[i-off] = np->intrs[j].sense;
++		}
++	}
++}
++
++/**
++ * Construct and return a list of the device_nodes with a given name.
++ */
++struct device_node *find_devices(const char *name)
++{
++	struct device_node *head, **prevp, *np;
++
++	prevp = &head;
++	for (np = allnodes; np != 0; np = np->allnext) {
++		if (np->name != 0 && strcasecmp(np->name, name) == 0) {
++			*prevp = np;
++			prevp = &np->next;
++		}
++	}
++	*prevp = NULL;
++	return head;
++}
++EXPORT_SYMBOL(find_devices);
++
++/**
++ * Construct and return a list of the device_nodes with a given type.
++ */
++struct device_node *find_type_devices(const char *type)
++{
++	struct device_node *head, **prevp, *np;
++
++	prevp = &head;
++	for (np = allnodes; np != 0; np = np->allnext) {
++		if (np->type != 0 && strcasecmp(np->type, type) == 0) {
++			*prevp = np;
++			prevp = &np->next;
++		}
++	}
++	*prevp = NULL;
++	return head;
++}
++EXPORT_SYMBOL(find_type_devices);
++
++/**
++ * Returns all nodes linked together
++ */
++struct device_node *find_all_nodes(void)
++{
++	struct device_node *head, **prevp, *np;
++
++	prevp = &head;
++	for (np = allnodes; np != 0; np = np->allnext) {
++		*prevp = np;
++		prevp = &np->next;
++	}
++	*prevp = NULL;
++	return head;
++}
++EXPORT_SYMBOL(find_all_nodes);
++
++/** Checks if the given "compat" string matches one of the strings in
++ * the device's "compatible" property
++ */
++int device_is_compatible(struct device_node *device, const char *compat)
++{
++	const char* cp;
++	int cplen, l;
++
++	cp = (char *) get_property(device, "compatible", &cplen);
++	if (cp == NULL)
++		return 0;
++	while (cplen > 0) {
++		if (strncasecmp(cp, compat, strlen(compat)) == 0)
++			return 1;
++		l = strlen(cp) + 1;
++		cp += l;
++		cplen -= l;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL(device_is_compatible);
++
++
++/**
++ * Indicates whether the root node has a given value in its
++ * compatible property.
++ */
++int machine_is_compatible(const char *compat)
++{
++	struct device_node *root;
++	int rc = 0;
++
++	root = of_find_node_by_path("/");
++	if (root) {
++		rc = device_is_compatible(root, compat);
++		of_node_put(root);
++	}
++	return rc;
++}
++EXPORT_SYMBOL(machine_is_compatible);
++
++/**
++ * Construct and return a list of the device_nodes with a given type
++ * and compatible property.
++ */
++struct device_node *find_compatible_devices(const char *type,
++					    const char *compat)
++{
++	struct device_node *head, **prevp, *np;
++
++	prevp = &head;
++	for (np = allnodes; np != 0; np = np->allnext) {
++		if (type != NULL
++		    && !(np->type != 0 && strcasecmp(np->type, type) == 0))
++			continue;
++		if (device_is_compatible(np, compat)) {
++			*prevp = np;
++			prevp = &np->next;
++		}
++	}
++	*prevp = NULL;
++	return head;
++}
++EXPORT_SYMBOL(find_compatible_devices);
++
++/**
++ * Find the device_node with a given full_name.
++ */
++struct device_node *find_path_device(const char *path)
++{
++	struct device_node *np;
++
++	for (np = allnodes; np != 0; np = np->allnext)
++		if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
++			return np;
++	return NULL;
++}
++EXPORT_SYMBOL(find_path_device);
++
++/*******
++ *
++ * New implementation of the OF "find" APIs, return a refcounted
++ * object, call of_node_put() when done.  The device tree and list
++ * are protected by a rw_lock.
++ *
++ * Note that property management will need some locking as well,
++ * this isn't dealt with yet.
++ *
++ *******/
++
++/**
++ *	of_find_node_by_name - Find a node by its "name" property
++ *	@from:	The node to start searching from or NULL, the node
++ *		you pass will not be searched, only the next one
++ *		will; typically, you pass what the previous call
++ *		returned. of_node_put() will be called on it
++ *	@name:	The name string to match against
++ *
++ *	Returns a node pointer with refcount incremented, use
++ *	of_node_put() on it when done.
++ */
++struct device_node *of_find_node_by_name(struct device_node *from,
++	const char *name)
++{
++	struct device_node *np;
++
++	read_lock(&devtree_lock);
++	np = from ? from->allnext : allnodes;
++	for (; np != 0; np = np->allnext)
++		if (np->name != 0 && strcasecmp(np->name, name) == 0
++		    && of_node_get(np))
++			break;
++	if (from)
++		of_node_put(from);
++	read_unlock(&devtree_lock);
++	return np;
++}
++EXPORT_SYMBOL(of_find_node_by_name);
++
++/**
++ *	of_find_node_by_type - Find a node by its "device_type" property
++ *	@from:	The node to start searching from or NULL, the node
++ *		you pass will not be searched, only the next one
++ *		will; typically, you pass what the previous call
++ *		returned. of_node_put() will be called on it
++ *	@name:	The type string to match against
++ *
++ *	Returns a node pointer with refcount incremented, use
++ *	of_node_put() on it when done.
++ */
++struct device_node *of_find_node_by_type(struct device_node *from,
++	const char *type)
++{
++	struct device_node *np;
++
++	read_lock(&devtree_lock);
++	np = from ? from->allnext : allnodes;
++	for (; np != 0; np = np->allnext)
++		if (np->type != 0 && strcasecmp(np->type, type) == 0
++		    && of_node_get(np))
++			break;
++	if (from)
++		of_node_put(from);
++	read_unlock(&devtree_lock);
++	return np;
++}
++EXPORT_SYMBOL(of_find_node_by_type);
++
++/**
++ *	of_find_compatible_node - Find a node based on type and one of the
++ *                                tokens in its "compatible" property
++ *	@from:		The node to start searching from or NULL, the node
++ *			you pass will not be searched, only the next one
++ *			will; typically, you pass what the previous call
++ *			returned. of_node_put() will be called on it
++ *	@type:		The type string to match "device_type" or NULL to ignore
++ *	@compatible:	The string to match to one of the tokens in the device
++ *			"compatible" list.
++ *
++ *	Returns a node pointer with refcount incremented, use
++ *	of_node_put() on it when done.
++ */
++struct device_node *of_find_compatible_node(struct device_node *from,
++	const char *type, const char *compatible)
++{
++	struct device_node *np;
++
++	read_lock(&devtree_lock);
++	np = from ? from->allnext : allnodes;
++	for (; np != 0; np = np->allnext) {
++		if (type != NULL
++		    && !(np->type != 0 && strcasecmp(np->type, type) == 0))
++			continue;
++		if (device_is_compatible(np, compatible) && of_node_get(np))
++			break;
++	}
++	if (from)
++		of_node_put(from);
++	read_unlock(&devtree_lock);
++	return np;
++}
++EXPORT_SYMBOL(of_find_compatible_node);
++
++/**
++ *	of_find_node_by_path - Find a node matching a full OF path
++ *	@path:	The full path to match
++ *
++ *	Returns a node pointer with refcount incremented, use
++ *	of_node_put() on it when done.
++ */
++struct device_node *of_find_node_by_path(const char *path)
++{
++	struct device_node *np = allnodes;
++
++	read_lock(&devtree_lock);
++	for (; np != 0; np = np->allnext) {
++		if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
++		    && of_node_get(np))
++			break;
++	}
++	read_unlock(&devtree_lock);
++	return np;
++}
++EXPORT_SYMBOL(of_find_node_by_path);
++
++/**
++ *	of_find_node_by_phandle - Find a node given a phandle
++ *	@handle:	phandle of the node to find
++ *
++ *	Returns a node pointer with refcount incremented, use
++ *	of_node_put() on it when done.
++ */
++struct device_node *of_find_node_by_phandle(phandle handle)
++{
++	struct device_node *np;
++
++	read_lock(&devtree_lock);
++	for (np = allnodes; np != 0; np = np->allnext)
++		if (np->linux_phandle == handle)
++			break;
++	if (np)
++		of_node_get(np);
++	read_unlock(&devtree_lock);
++	return np;
++}
++EXPORT_SYMBOL(of_find_node_by_phandle);
++
++/**
++ *	of_find_all_nodes - Get next node in global list
++ *	@prev:	Previous node or NULL to start iteration
++ *		of_node_put() will be called on it
++ *
++ *	Returns a node pointer with refcount incremented, use
++ *	of_node_put() on it when done.
++ */
++struct device_node *of_find_all_nodes(struct device_node *prev)
++{
++	struct device_node *np;
++
++	read_lock(&devtree_lock);
++	np = prev ? prev->allnext : allnodes;
++	for (; np != 0; np = np->allnext)
++		if (of_node_get(np))
++			break;
++	if (prev)
++		of_node_put(prev);
++	read_unlock(&devtree_lock);
++	return np;
++}
++EXPORT_SYMBOL(of_find_all_nodes);
++
++/**
++ *	of_get_parent - Get a node's parent if any
++ *	@node:	Node to get parent
++ *
++ *	Returns a node pointer with refcount incremented, use
++ *	of_node_put() on it when done.
++ */
++struct device_node *of_get_parent(const struct device_node *node)
++{
++	struct device_node *np;
++
++	if (!node)
++		return NULL;
++
++	read_lock(&devtree_lock);
++	np = of_node_get(node->parent);
++	read_unlock(&devtree_lock);
++	return np;
++}
++EXPORT_SYMBOL(of_get_parent);
++
++/**
++ *	of_get_next_child - Iterate a node childs
++ *	@node:	parent node
++ *	@prev:	previous child of the parent node, or NULL to get first
++ *
++ *	Returns a node pointer with refcount incremented, use
++ *	of_node_put() on it when done.
++ */
++struct device_node *of_get_next_child(const struct device_node *node,
++	struct device_node *prev)
++{
++	struct device_node *next;
++
++	read_lock(&devtree_lock);
++	next = prev ? prev->sibling : node->child;
++	for (; next != 0; next = next->sibling)
++		if (of_node_get(next))
++			break;
++	if (prev)
++		of_node_put(prev);
++	read_unlock(&devtree_lock);
++	return next;
++}
++EXPORT_SYMBOL(of_get_next_child);
++
++/**
++ *	of_node_get - Increment refcount of a node
++ *	@node:	Node to inc refcount, NULL is supported to
++ *		simplify writing of callers
++ *
++ *	Returns node.
++ */
++struct device_node *of_node_get(struct device_node *node)
++{
++	if (node)
++		kref_get(&node->kref);
++	return node;
++}
++EXPORT_SYMBOL(of_node_get);
++
++static inline struct device_node * kref_to_device_node(struct kref *kref)
++{
++	return container_of(kref, struct device_node, kref);
++}
++
++/**
++ *	of_node_release - release a dynamically allocated node
++ *	@kref:  kref element of the node to be released
++ *
++ *	In of_node_put() this function is passed to kref_put()
++ *	as the destructor.
++ */
++static void of_node_release(struct kref *kref)
++{
++	struct device_node *node = kref_to_device_node(kref);
++	struct property *prop = node->properties;
++
++	if (!OF_IS_DYNAMIC(node))
++		return;
++	while (prop) {
++		struct property *next = prop->next;
++		kfree(prop->name);
++		kfree(prop->value);
++		kfree(prop);
++		prop = next;
++	}
++	kfree(node->intrs);
++	kfree(node->addrs);
++	kfree(node->full_name);
++	kfree(node->data);
++	kfree(node);
++}
++
++/**
++ *	of_node_put - Decrement refcount of a node
++ *	@node:	Node to dec refcount, NULL is supported to
++ *		simplify writing of callers
++ *
++ */
++void of_node_put(struct device_node *node)
++{
++	if (node)
++		kref_put(&node->kref, of_node_release);
++}
++EXPORT_SYMBOL(of_node_put);
++
++/*
++ * Plug a device node into the tree and global list.
++ */
++void of_attach_node(struct device_node *np)
++{
++	write_lock(&devtree_lock);
++	np->sibling = np->parent->child;
++	np->allnext = allnodes;
++	np->parent->child = np;
++	allnodes = np;
++	write_unlock(&devtree_lock);
++}
++
++/*
++ * "Unplug" a node from the device tree.  The caller must hold
++ * a reference to the node.  The memory associated with the node
++ * is not freed until its refcount goes to zero.
++ */
++void of_detach_node(const struct device_node *np)
++{
++	struct device_node *parent;
++
++	write_lock(&devtree_lock);
++
++	parent = np->parent;
++
++	if (allnodes == np)
++		allnodes = np->allnext;
++	else {
++		struct device_node *prev;
++		for (prev = allnodes;
++		     prev->allnext != np;
++		     prev = prev->allnext)
++			;
++		prev->allnext = np->allnext;
++	}
++
++	if (parent->child == np)
++		parent->child = np->sibling;
++	else {
++		struct device_node *prevsib;
++		for (prevsib = np->parent->child;
++		     prevsib->sibling != np;
++		     prevsib = prevsib->sibling)
++			;
++		prevsib->sibling = np->sibling;
++	}
++
++	write_unlock(&devtree_lock);
++}
++
++#ifdef CONFIG_PPC_PSERIES
++/*
++ * Fix up the uninitialized fields in a new device node:
++ * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
++ *
++ * A lot of boot-time code is duplicated here, because functions such
++ * as finish_node_interrupts, interpret_pci_props, etc. cannot use the
++ * slab allocator.
++ *
++ * This should probably be split up into smaller chunks.
++ */
++
++static int of_finish_dynamic_node(struct device_node *node,
++				  unsigned long *unused1, int unused2,
++				  int unused3, int unused4)
++{
++	struct device_node *parent = of_get_parent(node);
++	int err = 0;
++	phandle *ibm_phandle;
++
++	node->name = get_property(node, "name", NULL);
++	node->type = get_property(node, "device_type", NULL);
++
++	if (!parent) {
++		err = -ENODEV;
++		goto out;
++	}
++
++	/* We don't support that function on PowerMac, at least
++	 * not yet
++	 */
++	if (systemcfg->platform == PLATFORM_POWERMAC)
++		return -ENODEV;
++
++	/* fix up new node's linux_phandle field */
++	if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
++		node->linux_phandle = *ibm_phandle;
++
++out:
++	of_node_put(parent);
++	return err;
++}
++
++static int prom_reconfig_notifier(struct notifier_block *nb,
++				  unsigned long action, void *node)
++{
++	int err;
++
++	switch (action) {
++	case PSERIES_RECONFIG_ADD:
++		err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0);
++		if (err < 0) {
++			printk(KERN_ERR "finish_node returned %d\n", err);
++			err = NOTIFY_BAD;
++		}
++		break;
++	default:
++		err = NOTIFY_DONE;
++		break;
++	}
++	return err;
++}
++
++static struct notifier_block prom_reconfig_nb = {
++	.notifier_call = prom_reconfig_notifier,
++	.priority = 10, /* This one needs to run first */
++};
++
++static int __init prom_reconfig_setup(void)
++{
++	return pSeries_reconfig_notifier_register(&prom_reconfig_nb);
++}
++__initcall(prom_reconfig_setup);
++#endif
++
++/*
++ * Find a property with a given name for a given node
++ * and return the value.
++ */
++unsigned char *get_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;
++			return pp->value;
++		}
++	return NULL;
++}
++EXPORT_SYMBOL(get_property);
++
++/*
++ * Add a property to a node
++ */
++void prom_add_property(struct device_node* np, struct property* prop)
++{
++	struct property **next = &np->properties;
++
++	prop->next = NULL;	
++	while (*next)
++		next = &(*next)->next;
++	*next = prop;
++}
++
++/* I quickly hacked that one, check against spec ! */
++static inline unsigned long
++bus_space_to_resource_flags(unsigned int bus_space)
++{
++	u8 space = (bus_space >> 24) & 0xf;
++	if (space == 0)
++		space = 0x02;
++	if (space == 0x02)
++		return IORESOURCE_MEM;
++	else if (space == 0x01)
++		return IORESOURCE_IO;
++	else {
++		printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
++		    	bus_space);
++		return 0;
++	}
++}
++
++#ifdef CONFIG_PCI
++static struct resource *find_parent_pci_resource(struct pci_dev* pdev,
++						 struct address_range *range)
++{
++	unsigned long mask;
++	int i;
++
++	/* Check this one */
++	mask = bus_space_to_resource_flags(range->space);
++	for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
++		if ((pdev->resource[i].flags & mask) == mask &&
++			pdev->resource[i].start <= range->address &&
++			pdev->resource[i].end > range->address) {
++				if ((range->address + range->size - 1) > pdev->resource[i].end) {
++					/* Add better message */
++					printk(KERN_WARNING "PCI/OF resource overlap !\n");
++					return NULL;
++				}
++				break;
++			}
++	}
++	if (i == DEVICE_COUNT_RESOURCE)
++		return NULL;
++	return &pdev->resource[i];
++}
++
++/*
++ * Request an OF device resource. Currently handles child of PCI devices,
++ * or other nodes attached to the root node. Ultimately, put some
++ * link to resources in the OF node.
++ */
++struct resource *request_OF_resource(struct device_node* node, int index,
++				     const char* name_postfix)
++{
++	struct pci_dev* pcidev;
++	u8 pci_bus, pci_devfn;
++	unsigned long iomask;
++	struct device_node* nd;
++	struct resource* parent;
++	struct resource *res = NULL;
++	int nlen, plen;
++
++	if (index >= node->n_addrs)
++		goto fail;
++
++	/* Sanity check on bus space */
++	iomask = bus_space_to_resource_flags(node->addrs[index].space);
++	if (iomask & IORESOURCE_MEM)
++		parent = &iomem_resource;
++	else if (iomask & IORESOURCE_IO)
++		parent = &ioport_resource;
++	else
++		goto fail;
++
++	/* Find a PCI parent if any */
++	nd = node;
++	pcidev = NULL;
++	while (nd) {
++		if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
++			pcidev = pci_find_slot(pci_bus, pci_devfn);
++		if (pcidev) break;
++		nd = nd->parent;
++	}
++	if (pcidev)
++		parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
++	if (!parent) {
++		printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
++			node->name);
++		goto fail;
++	}
++
++	res = __request_region(parent, node->addrs[index].address,
++			       node->addrs[index].size, NULL);
++	if (!res)
++		goto fail;
++	nlen = strlen(node->name);
++	plen = name_postfix ? strlen(name_postfix) : 0;
++	res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
++	if (res->name) {
++		strcpy((char *)res->name, node->name);
++		if (plen)
++			strcpy((char *)res->name+nlen, name_postfix);
++	}
++	return res;
++fail:
++	return NULL;
++}
++EXPORT_SYMBOL(request_OF_resource);
++
++int release_OF_resource(struct device_node *node, int index)
++{
++	struct pci_dev* pcidev;
++	u8 pci_bus, pci_devfn;
++	unsigned long iomask, start, end;
++	struct device_node* nd;
++	struct resource* parent;
++	struct resource *res = NULL;
++
++	if (index >= node->n_addrs)
++		return -EINVAL;
++
++	/* Sanity check on bus space */
++	iomask = bus_space_to_resource_flags(node->addrs[index].space);
++	if (iomask & IORESOURCE_MEM)
++		parent = &iomem_resource;
++	else if (iomask & IORESOURCE_IO)
++		parent = &ioport_resource;
++	else
++		return -EINVAL;
++
++	/* Find a PCI parent if any */
++	nd = node;
++	pcidev = NULL;
++	while(nd) {
++		if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
++			pcidev = pci_find_slot(pci_bus, pci_devfn);
++		if (pcidev) break;
++		nd = nd->parent;
++	}
++	if (pcidev)
++		parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
++	if (!parent) {
++		printk(KERN_WARNING "release_OF_resource(%s), parent not found\n",
++			node->name);
++		return -ENODEV;
++	}
++
++	/* Find us in the parent and its childs */
++	res = parent->child;
++	start = node->addrs[index].address;
++	end = start + node->addrs[index].size - 1;
++	while (res) {
++		if (res->start == start && res->end == end &&
++		    (res->flags & IORESOURCE_BUSY))
++		    	break;
++		if (res->start <= start && res->end >= end)
++			res = res->child;
++		else
++			res = res->sibling;
++	}
++	if (!res)
++		return -ENODEV;
++
++	if (res->name) {
++		kfree(res->name);
++		res->name = NULL;
++	}
++	release_resource(res);
++	kfree(res);
++
++	return 0;
++}
++EXPORT_SYMBOL(release_OF_resource);
++#endif /* CONFIG_PCI */
+diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/prom_init.c
+@@ -0,0 +1,2109 @@
++/*
++ * Procedures for interfacing to Open Firmware.
++ *
++ * 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 
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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_PROM
++
++#include <stdarg.h>
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/threads.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/proc_fs.h>
++#include <linux/stringify.h>
++#include <linux/delay.h>
++#include <linux/initrd.h>
++#include <linux/bitops.h>
++#include <asm/prom.h>
++#include <asm/rtas.h>
++#include <asm/page.h>
++#include <asm/processor.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/smp.h>
++#include <asm/system.h>
++#include <asm/mmu.h>
++#include <asm/pgtable.h>
++#include <asm/pci.h>
++#include <asm/iommu.h>
++#include <asm/btext.h>
++#include <asm/sections.h>
++#include <asm/machdep.h>
++
++#ifdef CONFIG_LOGO_LINUX_CLUT224
++#include <linux/linux_logo.h>
++extern const struct linux_logo logo_linux_clut224;
++#endif
++
++/*
++ * Properties whose value is longer than this get excluded from our
++ * copy of the device tree. This value does need to be big enough to
++ * ensure that we don't lose things like the interrupt-map property
++ * on a PCI-PCI bridge.
++ */
++#define MAX_PROPERTY_LENGTH	(1UL * 1024 * 1024)
++
++/*
++ * Eventually bump that one up
++ */
++#define DEVTREE_CHUNK_SIZE	0x100000
++
++/*
++ * This is the size of the local memory reserve map that gets copied
++ * into the boot params passed to the kernel. That size is totally
++ * flexible as the kernel just reads the list until it encounters an
++ * entry with size 0, so it can be changed without breaking binary
++ * compatibility
++ */
++#define MEM_RESERVE_MAP_SIZE	8
++
++/*
++ * prom_init() is called very early on, before the kernel text
++ * and data have been mapped to KERNELBASE.  At this point the code
++ * is running at whatever address it has been loaded at.
++ * On ppc32 we compile with -mrelocatable, which means that references
++ * to extern and static variables get relocated automatically.
++ * On ppc64 we have to relocate the references explicitly with
++ * RELOC.  (Note that strings count as static variables.)
++ *
++ * Because OF may have mapped I/O devices into the area starting at
++ * KERNELBASE, particularly on CHRP machines, we can't safely call
++ * OF once the kernel has been mapped to KERNELBASE.  Therefore all
++ * OF calls must be done within prom_init().
++ *
++ * ADDR is used in calls to call_prom.  The 4th and following
++ * arguments to call_prom should be 32-bit values.
++ * On ppc64, 64 bit values are truncated to 32 bits (and
++ * fortunately don't get interpreted as two arguments).
++ */
++#ifdef CONFIG_PPC64
++#define RELOC(x)        (*PTRRELOC(&(x)))
++#define ADDR(x)		(u32) add_reloc_offset((unsigned long)(x))
++#else
++#define RELOC(x)	(x)
++#define ADDR(x)		(u32) (x)
++#endif
++
++#define PROM_BUG() do {						\
++        prom_printf("kernel BUG at %s line 0x%x!\n",		\
++		    RELOC(__FILE__), __LINE__);			\
++        __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR);	\
++} while (0)
++
++#ifdef DEBUG_PROM
++#define prom_debug(x...)	prom_printf(x)
++#else
++#define prom_debug(x...)
++#endif
++
++#ifdef CONFIG_PPC32
++#define PLATFORM_POWERMAC	_MACH_Pmac
++#define PLATFORM_CHRP		_MACH_chrp
++#endif
++
++
++typedef u32 prom_arg_t;
++
++struct prom_args {
++        u32 service;
++        u32 nargs;
++        u32 nret;
++        prom_arg_t args[10];
++};
++
++struct prom_t {
++	ihandle root;
++	ihandle chosen;
++	int cpu;
++	ihandle stdout;
++	ihandle mmumap;
++};
++
++struct mem_map_entry {
++	unsigned long	base;
++	unsigned long	size;
++};
++
++typedef u32 cell_t;
++
++extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
++
++#ifdef CONFIG_PPC64
++extern int enter_prom(struct prom_args *args, unsigned long entry);
++#else
++static inline int enter_prom(struct prom_args *args, unsigned long entry)
++{
++	return ((int (*)(struct prom_args *))entry)(args);
++}
++#endif
++
++extern void copy_and_flush(unsigned long dest, unsigned long src,
++			   unsigned long size, unsigned long offset);
++
++/* prom structure */
++static struct prom_t __initdata prom;
++
++static unsigned long prom_entry __initdata;
++
++#define PROM_SCRATCH_SIZE 256
++
++static char __initdata of_stdout_device[256];
++static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
++
++static unsigned long __initdata dt_header_start;
++static unsigned long __initdata dt_struct_start, dt_struct_end;
++static unsigned long __initdata dt_string_start, dt_string_end;
++
++static unsigned long __initdata prom_initrd_start, prom_initrd_end;
++
++#ifdef CONFIG_PPC64
++static int __initdata iommu_force_on;
++static int __initdata ppc64_iommu_off;
++static unsigned long __initdata prom_tce_alloc_start;
++static unsigned long __initdata prom_tce_alloc_end;
++#endif
++
++static int __initdata of_platform;
++
++static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
++
++static unsigned long __initdata prom_memory_limit;
++
++static unsigned long __initdata alloc_top;
++static unsigned long __initdata alloc_top_high;
++static unsigned long __initdata alloc_bottom;
++static unsigned long __initdata rmo_top;
++static unsigned long __initdata ram_top;
++
++static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
++static int __initdata mem_reserve_cnt;
++
++static cell_t __initdata regbuf[1024];
++
++
++#define MAX_CPU_THREADS 2
++
++/* TO GO */
++#ifdef CONFIG_HMT
++struct {
++	unsigned int pir;
++	unsigned int threadid;
++} hmt_thread_data[NR_CPUS];
++#endif /* CONFIG_HMT */
++
++/*
++ * Error results ... some OF calls will return "-1" on error, some
++ * will return 0, some will return either. To simplify, here are
++ * macros to use with any ihandle or phandle return value to check if
++ * it is valid
++ */
++
++#define PROM_ERROR		(-1u)
++#define PHANDLE_VALID(p)	((p) != 0 && (p) != PROM_ERROR)
++#define IHANDLE_VALID(i)	((i) != 0 && (i) != PROM_ERROR)
++
++
++/* This is the one and *ONLY* place where we actually call open
++ * firmware.
++ */
++
++static int __init call_prom(const char *service, int nargs, int nret, ...)
++{
++	int i;
++	struct prom_args args;
++	va_list list;
++
++	args.service = ADDR(service);
++	args.nargs = nargs;
++	args.nret = nret;
++
++	va_start(list, nret);
++	for (i = 0; i < nargs; i++)
++		args.args[i] = va_arg(list, prom_arg_t);
++	va_end(list);
++
++	for (i = 0; i < nret; i++)
++		args.args[nargs+i] = 0;
++
++	if (enter_prom(&args, RELOC(prom_entry)) < 0)
++		return PROM_ERROR;
++
++	return (nret > 0) ? args.args[nargs] : 0;
++}
++
++static int __init call_prom_ret(const char *service, int nargs, int nret,
++				prom_arg_t *rets, ...)
++{
++	int i;
++	struct prom_args args;
++	va_list list;
++
++	args.service = ADDR(service);
++	args.nargs = nargs;
++	args.nret = nret;
++
++	va_start(list, rets);
++	for (i = 0; i < nargs; i++)
++		args.args[i] = va_arg(list, prom_arg_t);
++	va_end(list);
++
++	for (i = 0; i < nret; i++)
++		rets[nargs+i] = 0;
++
++	if (enter_prom(&args, RELOC(prom_entry)) < 0)
++		return PROM_ERROR;
++
++	if (rets != NULL)
++		for (i = 1; i < nret; ++i)
++			rets[i-1] = args.args[nargs+i];
++
++	return (nret > 0) ? args.args[nargs] : 0;
++}
++
++
++static void __init prom_print(const char *msg)
++{
++	const char *p, *q;
++	struct prom_t *_prom = &RELOC(prom);
++
++	if (_prom->stdout == 0)
++		return;
++
++	for (p = msg; *p != 0; p = q) {
++		for (q = p; *q != 0 && *q != '\n'; ++q)
++			;
++		if (q > p)
++			call_prom("write", 3, 1, _prom->stdout, p, q - p);
++		if (*q == 0)
++			break;
++		++q;
++		call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
++	}
++}
++
++
++static void __init prom_print_hex(unsigned long val)
++{
++	int i, nibbles = sizeof(val)*2;
++	char buf[sizeof(val)*2+1];
++	struct prom_t *_prom = &RELOC(prom);
++
++	for (i = nibbles-1;  i >= 0;  i--) {
++		buf[i] = (val & 0xf) + '0';
++		if (buf[i] > '9')
++			buf[i] += ('a'-'0'-10);
++		val >>= 4;
++	}
++	buf[nibbles] = '\0';
++	call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
++}
++
++
++static void __init prom_printf(const char *format, ...)
++{
++	const char *p, *q, *s;
++	va_list args;
++	unsigned long v;
++	struct prom_t *_prom = &RELOC(prom);
++
++	va_start(args, format);
++#ifdef CONFIG_PPC64
++	format = PTRRELOC(format);
++#endif
++	for (p = format; *p != 0; p = q) {
++		for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
++			;
++		if (q > p)
++			call_prom("write", 3, 1, _prom->stdout, p, q - p);
++		if (*q == 0)
++			break;
++		if (*q == '\n') {
++			++q;
++			call_prom("write", 3, 1, _prom->stdout,
++				  ADDR("\r\n"), 2);
++			continue;
++		}
++		++q;
++		if (*q == 0)
++			break;
++		switch (*q) {
++		case 's':
++			++q;
++			s = va_arg(args, const char *);
++			prom_print(s);
++			break;
++		case 'x':
++			++q;
++			v = va_arg(args, unsigned long);
++			prom_print_hex(v);
++			break;
++		}
++	}
++}
++
++
++static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
++				unsigned long align)
++{
++	int ret;
++	struct prom_t *_prom = &RELOC(prom);
++
++	ret = call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
++			(prom_arg_t)align);
++	if (ret != -1 && _prom->mmumap != 0)
++		/* old pmacs need us to map as well */
++		call_prom("call-method", 6, 1,
++			  ADDR("map"), _prom->mmumap, 0, size, virt, virt);
++	return ret;
++}
++
++static void __init __attribute__((noreturn)) prom_panic(const char *reason)
++{
++#ifdef CONFIG_PPC64
++	reason = PTRRELOC(reason);
++#endif
++	prom_print(reason);
++	/* ToDo: should put up an SRC here on p/iSeries */
++	call_prom("exit", 0, 0);
++
++	for (;;)			/* should never get here */
++		;
++}
++
++
++static int __init prom_next_node(phandle *nodep)
++{
++	phandle node;
++
++	if ((node = *nodep) != 0
++	    && (*nodep = call_prom("child", 1, 1, node)) != 0)
++		return 1;
++	if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
++		return 1;
++	for (;;) {
++		if ((node = call_prom("parent", 1, 1, node)) == 0)
++			return 0;
++		if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
++			return 1;
++	}
++}
++
++static int __init prom_getprop(phandle node, const char *pname,
++			       void *value, size_t valuelen)
++{
++	return call_prom("getprop", 4, 1, node, ADDR(pname),
++			 (u32)(unsigned long) value, (u32) valuelen);
++}
++
++static int __init prom_getproplen(phandle node, const char *pname)
++{
++	return call_prom("getproplen", 2, 1, node, ADDR(pname));
++}
++
++static int __init prom_setprop(phandle node, const char *pname,
++			       void *value, size_t valuelen)
++{
++	return call_prom("setprop", 4, 1, node, ADDR(pname),
++			 (u32)(unsigned long) value, (u32) valuelen);
++}
++
++/* We can't use the standard versions because of RELOC headaches. */
++#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
++			 || ('a' <= (c) && (c) <= 'f') \
++			 || ('A' <= (c) && (c) <= 'F'))
++
++#define isdigit(c)	('0' <= (c) && (c) <= '9')
++#define islower(c)	('a' <= (c) && (c) <= 'z')
++#define toupper(c)	(islower(c) ? ((c) - 'a' + 'A') : (c))
++
++unsigned long prom_strtoul(const char *cp, const char **endp)
++{
++	unsigned long result = 0, base = 10, value;
++
++	if (*cp == '0') {
++		base = 8;
++		cp++;
++		if (toupper(*cp) == 'X') {
++			cp++;
++			base = 16;
++		}
++	}
++
++	while (isxdigit(*cp) &&
++	       (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
++		result = result * base + value;
++		cp++;
++	}
++
++	if (endp)
++		*endp = cp;
++
++	return result;
++}
++
++unsigned long prom_memparse(const char *ptr, const char **retptr)
++{
++	unsigned long ret = prom_strtoul(ptr, retptr);
++	int shift = 0;
++
++	/*
++	 * We can't use a switch here because GCC *may* generate a
++	 * jump table which won't work, because we're not running at
++	 * the address we're linked at.
++	 */
++	if ('G' == **retptr || 'g' == **retptr)
++		shift = 30;
++
++	if ('M' == **retptr || 'm' == **retptr)
++		shift = 20;
++
++	if ('K' == **retptr || 'k' == **retptr)
++		shift = 10;
++
++	if (shift) {
++		ret <<= shift;
++		(*retptr)++;
++	}
++
++	return ret;
++}
++
++/*
++ * Early parsing of the command line passed to the kernel, used for
++ * "mem=x" and the options that affect the iommu
++ */
++static void __init early_cmdline_parse(void)
++{
++	struct prom_t *_prom = &RELOC(prom);
++	char *opt, *p;
++	int l = 0;
++
++	RELOC(prom_cmd_line[0]) = 0;
++	p = RELOC(prom_cmd_line);
++	if ((long)_prom->chosen > 0)
++		l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
++#ifdef CONFIG_CMDLINE
++	if (l == 0) /* dbl check */
++		strlcpy(RELOC(prom_cmd_line),
++			RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
++#endif /* CONFIG_CMDLINE */
++	prom_printf("command line: %s\n", RELOC(prom_cmd_line));
++
++#ifdef CONFIG_PPC64
++	opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
++	if (opt) {
++		prom_printf("iommu opt is: %s\n", opt);
++		opt += 6;
++		while (*opt && *opt == ' ')
++			opt++;
++		if (!strncmp(opt, RELOC("off"), 3))
++			RELOC(ppc64_iommu_off) = 1;
++		else if (!strncmp(opt, RELOC("force"), 5))
++			RELOC(iommu_force_on) = 1;
++	}
++#endif
++
++	opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
++	if (opt) {
++		opt += 4;
++		RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
++#ifdef CONFIG_PPC64
++		/* Align to 16 MB == size of ppc64 large page */
++		RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
++#endif
++	}
++}
++
++#ifdef CONFIG_PPC_PSERIES
++/*
++ * To tell the firmware what our capabilities are, we have to pass
++ * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
++ * that contain structures that contain the actual values.
++ */
++static struct fake_elf {
++	Elf32_Ehdr	elfhdr;
++	Elf32_Phdr	phdr[2];
++	struct chrpnote {
++		u32	namesz;
++		u32	descsz;
++		u32	type;
++		char	name[8];	/* "PowerPC" */
++		struct chrpdesc {
++			u32	real_mode;
++			u32	real_base;
++			u32	real_size;
++			u32	virt_base;
++			u32	virt_size;
++			u32	load_base;
++		} chrpdesc;
++	} chrpnote;
++	struct rpanote {
++		u32	namesz;
++		u32	descsz;
++		u32	type;
++		char	name[24];	/* "IBM,RPA-Client-Config" */
++		struct rpadesc {
++			u32	lpar_affinity;
++			u32	min_rmo_size;
++			u32	min_rmo_percent;
++			u32	max_pft_size;
++			u32	splpar;
++			u32	min_load;
++			u32	new_mem_def;
++			u32	ignore_me;
++		} rpadesc;
++	} rpanote;
++} fake_elf = {
++	.elfhdr = {
++		.e_ident = { 0x7f, 'E', 'L', 'F',
++			     ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
++		.e_type = ET_EXEC,	/* yeah right */
++		.e_machine = EM_PPC,
++		.e_version = EV_CURRENT,
++		.e_phoff = offsetof(struct fake_elf, phdr),
++		.e_phentsize = sizeof(Elf32_Phdr),
++		.e_phnum = 2
++	},
++	.phdr = {
++		[0] = {
++			.p_type = PT_NOTE,
++			.p_offset = offsetof(struct fake_elf, chrpnote),
++			.p_filesz = sizeof(struct chrpnote)
++		}, [1] = {
++			.p_type = PT_NOTE,
++			.p_offset = offsetof(struct fake_elf, rpanote),
++			.p_filesz = sizeof(struct rpanote)
++		}
++	},
++	.chrpnote = {
++		.namesz = sizeof("PowerPC"),
++		.descsz = sizeof(struct chrpdesc),
++		.type = 0x1275,
++		.name = "PowerPC",
++		.chrpdesc = {
++			.real_mode = ~0U,	/* ~0 means "don't care" */
++			.real_base = ~0U,
++			.real_size = ~0U,
++			.virt_base = ~0U,
++			.virt_size = ~0U,
++			.load_base = ~0U
++		},
++	},
++	.rpanote = {
++		.namesz = sizeof("IBM,RPA-Client-Config"),
++		.descsz = sizeof(struct rpadesc),
++		.type = 0x12759999,
++		.name = "IBM,RPA-Client-Config",
++		.rpadesc = {
++			.lpar_affinity = 0,
++			.min_rmo_size = 64,	/* in megabytes */
++			.min_rmo_percent = 0,
++			.max_pft_size = 48,	/* 2^48 bytes max PFT size */
++			.splpar = 1,
++			.min_load = ~0U,
++			.new_mem_def = 0
++		}
++	}
++};
++
++static void __init prom_send_capabilities(void)
++{
++	ihandle elfloader;
++
++	elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
++	if (elfloader == 0) {
++		prom_printf("couldn't open /packages/elf-loader\n");
++		return;
++	}
++	call_prom("call-method", 3, 1, ADDR("process-elf-header"),
++			elfloader, ADDR(&fake_elf));
++	call_prom("close", 1, 0, elfloader);
++}
++#endif
++
++/*
++ * Memory allocation strategy... our layout is normally:
++ *
++ *  at 14Mb or more we have vmlinux, then a gap and initrd.  In some
++ *  rare cases, initrd might end up being before the kernel though.
++ *  We assume this won't override the final kernel at 0, we have no
++ *  provision to handle that in this version, but it should hopefully
++ *  never happen.
++ *
++ *  alloc_top is set to the top of RMO, eventually shrink down if the
++ *  TCEs overlap
++ *
++ *  alloc_bottom is set to the top of kernel/initrd
++ *
++ *  from there, allocations are done this way : rtas is allocated
++ *  topmost, and the device-tree is allocated from the bottom. We try
++ *  to grow the device-tree allocation as we progress. If we can't,
++ *  then we fail, we don't currently have a facility to restart
++ *  elsewhere, but that shouldn't be necessary.
++ *
++ *  Note that calls to reserve_mem have to be done explicitly, memory
++ *  allocated with either alloc_up or alloc_down isn't automatically
++ *  reserved.
++ */
++
++
++/*
++ * Allocates memory in the RMO upward from the kernel/initrd
++ *
++ * When align is 0, this is a special case, it means to allocate in place
++ * at the current location of alloc_bottom or fail (that is basically
++ * extending the previous allocation). Used for the device-tree flattening
++ */
++static unsigned long __init alloc_up(unsigned long size, unsigned long align)
++{
++	unsigned long base = RELOC(alloc_bottom);
++	unsigned long addr = 0;
++
++	if (align)
++		base = _ALIGN_UP(base, align);
++	prom_debug("alloc_up(%x, %x)\n", size, align);
++	if (RELOC(ram_top) == 0)
++		prom_panic("alloc_up() called with mem not initialized\n");
++
++	if (align)
++		base = _ALIGN_UP(RELOC(alloc_bottom), align);
++	else
++		base = RELOC(alloc_bottom);
++
++	for(; (base + size) <= RELOC(alloc_top); 
++	    base = _ALIGN_UP(base + 0x100000, align)) {
++		prom_debug("    trying: 0x%x\n\r", base);
++		addr = (unsigned long)prom_claim(base, size, 0);
++		if (addr != PROM_ERROR && addr != 0)
++			break;
++		addr = 0;
++		if (align == 0)
++			break;
++	}
++	if (addr == 0)
++		return 0;
++	RELOC(alloc_bottom) = addr;
++
++	prom_debug(" -> %x\n", addr);
++	prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
++	prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
++	prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
++	prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
++	prom_debug("  ram_top      : %x\n", RELOC(ram_top));
++
++	return addr;
++}
++
++/*
++ * Allocates memory downward, either from top of RMO, or if highmem
++ * is set, from the top of RAM.  Note that this one doesn't handle
++ * failures.  It does claim memory if highmem is not set.
++ */
++static unsigned long __init alloc_down(unsigned long size, unsigned long align,
++				       int highmem)
++{
++	unsigned long base, addr = 0;
++
++	prom_debug("alloc_down(%x, %x, %s)\n", size, align,
++		   highmem ? RELOC("(high)") : RELOC("(low)"));
++	if (RELOC(ram_top) == 0)
++		prom_panic("alloc_down() called with mem not initialized\n");
++
++	if (highmem) {
++		/* Carve out storage for the TCE table. */
++		addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
++		if (addr <= RELOC(alloc_bottom))
++			return 0;
++		/* Will we bump into the RMO ? If yes, check out that we
++		 * didn't overlap existing allocations there, if we did,
++		 * we are dead, we must be the first in town !
++		 */
++		if (addr < RELOC(rmo_top)) {
++			/* Good, we are first */
++			if (RELOC(alloc_top) == RELOC(rmo_top))
++				RELOC(alloc_top) = RELOC(rmo_top) = addr;
++			else
++				return 0;
++		}
++		RELOC(alloc_top_high) = addr;
++		goto bail;
++	}
++
++	base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
++	for (; base > RELOC(alloc_bottom);
++	     base = _ALIGN_DOWN(base - 0x100000, align))  {
++		prom_debug("    trying: 0x%x\n\r", base);
++		addr = (unsigned long)prom_claim(base, size, 0);
++		if (addr != PROM_ERROR && addr != 0)
++			break;
++		addr = 0;
++	}
++	if (addr == 0)
++		return 0;
++	RELOC(alloc_top) = addr;
++
++ bail:
++	prom_debug(" -> %x\n", addr);
++	prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
++	prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
++	prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
++	prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
++	prom_debug("  ram_top      : %x\n", RELOC(ram_top));
++
++	return addr;
++}
++
++/*
++ * Parse a "reg" cell
++ */
++static unsigned long __init prom_next_cell(int s, cell_t **cellp)
++{
++	cell_t *p = *cellp;
++	unsigned long r = 0;
++
++	/* Ignore more than 2 cells */
++	while (s > sizeof(unsigned long) / 4) {
++		p++;
++		s--;
++	}
++	r = *p++;
++#ifdef CONFIG_PPC64
++	if (s > 1) {
++		r <<= 32;
++		r |= *(p++);
++	}
++#endif
++	*cellp = p;
++	return r;
++}
++
++/*
++ * Very dumb function for adding to the memory reserve list, but
++ * we don't need anything smarter at this point
++ *
++ * XXX Eventually check for collisions.  They should NEVER happen.
++ * If problems seem to show up, it would be a good start to track
++ * them down.
++ */
++static void reserve_mem(unsigned long base, unsigned long size)
++{
++	unsigned long top = base + size;
++	unsigned long cnt = RELOC(mem_reserve_cnt);
++
++	if (size == 0)
++		return;
++
++	/* We need to always keep one empty entry so that we
++	 * have our terminator with "size" set to 0 since we are
++	 * dumb and just copy this entire array to the boot params
++	 */
++	base = _ALIGN_DOWN(base, PAGE_SIZE);
++	top = _ALIGN_UP(top, PAGE_SIZE);
++	size = top - base;
++
++	if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
++		prom_panic("Memory reserve map exhausted !\n");
++	RELOC(mem_reserve_map)[cnt].base = base;
++	RELOC(mem_reserve_map)[cnt].size = size;
++	RELOC(mem_reserve_cnt) = cnt + 1;
++}
++
++/*
++ * Initialize memory allocation mecanism, parse "memory" nodes and
++ * obtain that way the top of memory and RMO to setup out local allocator
++ */
++static void __init prom_init_mem(void)
++{
++	phandle node;
++	char *path, type[64];
++	unsigned int plen;
++	cell_t *p, *endp;
++	struct prom_t *_prom = &RELOC(prom);
++	u32 rac, rsc;
++
++	/*
++	 * We iterate the memory nodes to find
++	 * 1) top of RMO (first node)
++	 * 2) top of memory
++	 */
++	rac = 2;
++	prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
++	rsc = 1;
++	prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
++	prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
++	prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
++
++	prom_debug("scanning memory:\n");
++	path = RELOC(prom_scratch);
++
++	for (node = 0; prom_next_node(&node); ) {
++		type[0] = 0;
++		prom_getprop(node, "device_type", type, sizeof(type));
++
++		if (type[0] == 0) {
++			/*
++			 * CHRP Longtrail machines have no device_type
++			 * on the memory node, so check the name instead...
++			 */
++			prom_getprop(node, "name", type, sizeof(type));
++		}
++		if (strcmp(type, RELOC("memory")))
++			continue;
++
++		plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
++		if (plen > sizeof(regbuf)) {
++			prom_printf("memory node too large for buffer !\n");
++			plen = sizeof(regbuf);
++		}
++		p = RELOC(regbuf);
++		endp = p + (plen / sizeof(cell_t));
++
++#ifdef DEBUG_PROM
++		memset(path, 0, PROM_SCRATCH_SIZE);
++		call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
++		prom_debug("  node %s :\n", path);
++#endif /* DEBUG_PROM */
++
++		while ((endp - p) >= (rac + rsc)) {
++			unsigned long base, size;
++
++			base = prom_next_cell(rac, &p);
++			size = prom_next_cell(rsc, &p);
++
++			if (size == 0)
++				continue;
++			prom_debug("    %x %x\n", base, size);
++			if (base == 0)
++				RELOC(rmo_top) = size;
++			if ((base + size) > RELOC(ram_top))
++				RELOC(ram_top) = base + size;
++		}
++	}
++
++	RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
++
++	/* Check if we have an initrd after the kernel, if we do move our bottom
++	 * point to after it
++	 */
++	if (RELOC(prom_initrd_start)) {
++		if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
++			RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
++	}
++
++	/*
++	 * If prom_memory_limit is set we reduce the upper limits *except* for
++	 * alloc_top_high. This must be the real top of RAM so we can put
++	 * TCE's up there.
++	 */
++
++	RELOC(alloc_top_high) = RELOC(ram_top);
++
++	if (RELOC(prom_memory_limit)) {
++		if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
++			prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
++				RELOC(prom_memory_limit));
++			RELOC(prom_memory_limit) = 0;
++		} else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
++			prom_printf("Ignoring mem=%x >= ram_top.\n",
++				RELOC(prom_memory_limit));
++			RELOC(prom_memory_limit) = 0;
++		} else {
++			RELOC(ram_top) = RELOC(prom_memory_limit);
++			RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
++		}
++	}
++
++	/*
++	 * Setup our top alloc point, that is top of RMO or top of
++	 * segment 0 when running non-LPAR.
++	 * Some RS64 machines have buggy firmware where claims up at
++	 * 1GB fail.  Cap at 768MB as a workaround.
++	 * Since 768MB is plenty of room, and we need to cap to something
++	 * reasonable on 32-bit, cap at 768MB on all machines.
++	 */
++	if (!RELOC(rmo_top))
++		RELOC(rmo_top) = RELOC(ram_top);
++	RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
++	RELOC(alloc_top) = RELOC(rmo_top);
++
++	prom_printf("memory layout at init:\n");
++	prom_printf("  memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
++	prom_printf("  alloc_bottom : %x\n", RELOC(alloc_bottom));
++	prom_printf("  alloc_top    : %x\n", RELOC(alloc_top));
++	prom_printf("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
++	prom_printf("  rmo_top      : %x\n", RELOC(rmo_top));
++	prom_printf("  ram_top      : %x\n", RELOC(ram_top));
++}
++
++
++/*
++ * Allocate room for and instantiate RTAS
++ */
++static void __init prom_instantiate_rtas(void)
++{
++	phandle rtas_node;
++	ihandle rtas_inst;
++	u32 base, entry = 0;
++	u32 size = 0;
++
++	prom_debug("prom_instantiate_rtas: start...\n");
++
++	rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
++	prom_debug("rtas_node: %x\n", rtas_node);
++	if (!PHANDLE_VALID(rtas_node))
++		return;
++
++	prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
++	if (size == 0)
++		return;
++
++	base = alloc_down(size, PAGE_SIZE, 0);
++	if (base == 0) {
++		prom_printf("RTAS allocation failed !\n");
++		return;
++	}
++
++	rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
++	if (!IHANDLE_VALID(rtas_inst)) {
++		prom_printf("opening rtas package failed");
++		return;
++	}
++
++	prom_printf("instantiating rtas at 0x%x ...", base);
++
++	if (call_prom_ret("call-method", 3, 2, &entry,
++			  ADDR("instantiate-rtas"),
++			  rtas_inst, base) == PROM_ERROR
++	    || entry == 0) {
++		prom_printf(" failed\n");
++		return;
++	}
++	prom_printf(" done\n");
++
++	reserve_mem(base, size);
++
++	prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
++	prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
++
++	prom_debug("rtas base     = 0x%x\n", base);
++	prom_debug("rtas entry    = 0x%x\n", entry);
++	prom_debug("rtas size     = 0x%x\n", (long)size);
++
++	prom_debug("prom_instantiate_rtas: end...\n");
++}
++
++#ifdef CONFIG_PPC64
++/*
++ * Allocate room for and initialize TCE tables
++ */
++static void __init prom_initialize_tce_table(void)
++{
++	phandle node;
++	ihandle phb_node;
++	char compatible[64], type[64], model[64];
++	char *path = RELOC(prom_scratch);
++	u64 base, align;
++	u32 minalign, minsize;
++	u64 tce_entry, *tce_entryp;
++	u64 local_alloc_top, local_alloc_bottom;
++	u64 i;
++
++	if (RELOC(ppc64_iommu_off))
++		return;
++
++	prom_debug("starting prom_initialize_tce_table\n");
++
++	/* Cache current top of allocs so we reserve a single block */
++	local_alloc_top = RELOC(alloc_top_high);
++	local_alloc_bottom = local_alloc_top;
++
++	/* Search all nodes looking for PHBs. */
++	for (node = 0; prom_next_node(&node); ) {
++		compatible[0] = 0;
++		type[0] = 0;
++		model[0] = 0;
++		prom_getprop(node, "compatible",
++			     compatible, sizeof(compatible));
++		prom_getprop(node, "device_type", type, sizeof(type));
++		prom_getprop(node, "model", model, sizeof(model));
++
++		if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
++			continue;
++
++		/* Keep the old logic in tack to avoid regression. */
++		if (compatible[0] != 0) {
++			if ((strstr(compatible, RELOC("python")) == NULL) &&
++			    (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
++			    (strstr(compatible, RELOC("Winnipeg")) == NULL))
++				continue;
++		} else if (model[0] != 0) {
++			if ((strstr(model, RELOC("ython")) == NULL) &&
++			    (strstr(model, RELOC("peedwagon")) == NULL) &&
++			    (strstr(model, RELOC("innipeg")) == NULL))
++				continue;
++		}
++
++		if (prom_getprop(node, "tce-table-minalign", &minalign,
++				 sizeof(minalign)) == PROM_ERROR)
++			minalign = 0;
++		if (prom_getprop(node, "tce-table-minsize", &minsize,
++				 sizeof(minsize)) == PROM_ERROR)
++			minsize = 4UL << 20;
++
++		/*
++		 * Even though we read what OF wants, we just set the table
++		 * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
++		 * By doing this, we avoid the pitfalls of trying to DMA to
++		 * MMIO space and the DMA alias hole.
++		 *
++		 * On POWER4, firmware sets the TCE region by assuming
++		 * each TCE table is 8MB. Using this memory for anything
++		 * else will impact performance, so we always allocate 8MB.
++		 * Anton
++		 */
++		if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
++			minsize = 8UL << 20;
++		else
++			minsize = 4UL << 20;
++
++		/* Align to the greater of the align or size */
++		align = max(minalign, minsize);
++		base = alloc_down(minsize, align, 1);
++		if (base == 0)
++			prom_panic("ERROR, cannot find space for TCE table.\n");
++		if (base < local_alloc_bottom)
++			local_alloc_bottom = base;
++
++		/* Save away the TCE table attributes for later use. */
++		prom_setprop(node, "linux,tce-base", &base, sizeof(base));
++		prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
++
++		/* It seems OF doesn't null-terminate the path :-( */
++		memset(path, 0, sizeof(path));
++		/* Call OF to setup the TCE hardware */
++		if (call_prom("package-to-path", 3, 1, node,
++			      path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
++			prom_printf("package-to-path failed\n");
++		}
++
++		prom_debug("TCE table: %s\n", path);
++		prom_debug("\tnode = 0x%x\n", node);
++		prom_debug("\tbase = 0x%x\n", base);
++		prom_debug("\tsize = 0x%x\n", minsize);
++
++		/* Initialize the table to have a one-to-one mapping
++		 * over the allocated size.
++		 */
++		tce_entryp = (unsigned long *)base;
++		for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
++			tce_entry = (i << PAGE_SHIFT);
++			tce_entry |= 0x3;
++			*tce_entryp = tce_entry;
++		}
++
++		prom_printf("opening PHB %s", path);
++		phb_node = call_prom("open", 1, 1, path);
++		if (phb_node == 0)
++			prom_printf("... failed\n");
++		else
++			prom_printf("... done\n");
++
++		call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
++			  phb_node, -1, minsize,
++			  (u32) base, (u32) (base >> 32));
++		call_prom("close", 1, 0, phb_node);
++	}
++
++	reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
++
++	if (RELOC(prom_memory_limit)) {
++		/*
++		 * We align the start to a 16MB boundary so we can map
++		 * the TCE area using large pages if possible.
++		 * The end should be the top of RAM so no need to align it.
++		 */
++		RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom,
++							  0x1000000);
++		RELOC(prom_tce_alloc_end) = local_alloc_top;
++	}
++
++	/* Flag the first invalid entry */
++	prom_debug("ending prom_initialize_tce_table\n");
++}
++#endif
++
++/*
++ * With CHRP SMP we need to use the OF to start the other processors.
++ * We can't wait until smp_boot_cpus (the OF is trashed by then)
++ * so we have to put the processors into a holding pattern controlled
++ * by the kernel (not OF) before we destroy the OF.
++ *
++ * This uses a chunk of low memory, puts some holding pattern
++ * code there and sends the other processors off to there until
++ * smp_boot_cpus tells them to do something.  The holding pattern
++ * checks that address until its cpu # is there, when it is that
++ * cpu jumps to __secondary_start().  smp_boot_cpus() takes care
++ * of setting those values.
++ *
++ * We also use physical address 0x4 here to tell when a cpu
++ * is in its holding pattern code.
++ *
++ * -- Cort
++ */
++extern void __secondary_hold(void);
++extern unsigned long __secondary_hold_spinloop;
++extern unsigned long __secondary_hold_acknowledge;
++
++/*
++ * We want to reference the copy of __secondary_hold_* in the
++ * 0 - 0x100 address range
++ */
++#define LOW_ADDR(x)	(((unsigned long) &(x)) & 0xff)
++
++static void __init prom_hold_cpus(void)
++{
++	unsigned long i;
++	unsigned int reg;
++	phandle node;
++	char type[64];
++	int cpuid = 0;
++	unsigned int interrupt_server[MAX_CPU_THREADS];
++	unsigned int cpu_threads, hw_cpu_num;
++	int propsize;
++	struct prom_t *_prom = &RELOC(prom);
++	unsigned long *spinloop
++		= (void *) LOW_ADDR(__secondary_hold_spinloop);
++	unsigned long *acknowledge
++		= (void *) LOW_ADDR(__secondary_hold_acknowledge);
++#ifdef CONFIG_PPC64
++	/* __secondary_hold is actually a descriptor, not the text address */
++	unsigned long secondary_hold
++		= __pa(*PTRRELOC((unsigned long *)__secondary_hold));
++#else
++	unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
++#endif
++
++	prom_debug("prom_hold_cpus: start...\n");
++	prom_debug("    1) spinloop       = 0x%x\n", (unsigned long)spinloop);
++	prom_debug("    1) *spinloop      = 0x%x\n", *spinloop);
++	prom_debug("    1) acknowledge    = 0x%x\n",
++		   (unsigned long)acknowledge);
++	prom_debug("    1) *acknowledge   = 0x%x\n", *acknowledge);
++	prom_debug("    1) secondary_hold = 0x%x\n", secondary_hold);
++
++	/* Set the common spinloop variable, so all of the secondary cpus
++	 * will block when they are awakened from their OF spinloop.
++	 * This must occur for both SMP and non SMP kernels, since OF will
++	 * be trashed when we move the kernel.
++	 */
++	*spinloop = 0;
++
++#ifdef CONFIG_HMT
++	for (i = 0; i < NR_CPUS; i++)
++		RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
++#endif
++	/* look for cpus */
++	for (node = 0; prom_next_node(&node); ) {
++		type[0] = 0;
++		prom_getprop(node, "device_type", type, sizeof(type));
++		if (strcmp(type, RELOC("cpu")) != 0)
++			continue;
++
++		/* Skip non-configured cpus. */
++		if (prom_getprop(node, "status", type, sizeof(type)) > 0)
++			if (strcmp(type, RELOC("okay")) != 0)
++				continue;
++
++		reg = -1;
++		prom_getprop(node, "reg", &reg, sizeof(reg));
++
++		prom_debug("\ncpuid        = 0x%x\n", cpuid);
++		prom_debug("cpu hw idx   = 0x%x\n", reg);
++
++		/* Init the acknowledge var which will be reset by
++		 * the secondary cpu when it awakens from its OF
++		 * spinloop.
++		 */
++		*acknowledge = (unsigned long)-1;
++
++		propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
++					&interrupt_server,
++					sizeof(interrupt_server));
++		if (propsize < 0) {
++			/* no property.  old hardware has no SMT */
++			cpu_threads = 1;
++			interrupt_server[0] = reg; /* fake it with phys id */
++		} else {
++			/* We have a threaded processor */
++			cpu_threads = propsize / sizeof(u32);
++			if (cpu_threads > MAX_CPU_THREADS) {
++				prom_printf("SMT: too many threads!\n"
++					    "SMT: found %x, max is %x\n",
++					    cpu_threads, MAX_CPU_THREADS);
++				cpu_threads = 1; /* ToDo: panic? */
++			}
++		}
++
++		hw_cpu_num = interrupt_server[0];
++		if (hw_cpu_num != _prom->cpu) {
++			/* Primary Thread of non-boot cpu */
++			prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
++			call_prom("start-cpu", 3, 0, node,
++				  secondary_hold, reg);
++
++			for (i = 0; (i < 100000000) && 
++			     (*acknowledge == ((unsigned long)-1)); i++ )
++				mb();
++
++			if (*acknowledge == reg)
++				prom_printf("done\n");
++			else
++				prom_printf("failed: %x\n", *acknowledge);
++		}
++#ifdef CONFIG_SMP
++		else
++			prom_printf("%x : boot cpu     %x\n", cpuid, reg);
++#endif /* CONFIG_SMP */
++
++		/* Reserve cpu #s for secondary threads.   They start later. */
++		cpuid += cpu_threads;
++	}
++#ifdef CONFIG_HMT
++	/* Only enable HMT on processors that provide support. */
++	if (__is_processor(PV_PULSAR) || 
++	    __is_processor(PV_ICESTAR) ||
++	    __is_processor(PV_SSTAR)) {
++		prom_printf("    starting secondary threads\n");
++
++		for (i = 0; i < NR_CPUS; i += 2) {
++			if (!cpu_online(i))
++				continue;
++
++			if (i == 0) {
++				unsigned long pir = mfspr(SPRN_PIR);
++				if (__is_processor(PV_PULSAR)) {
++					RELOC(hmt_thread_data)[i].pir = 
++						pir & 0x1f;
++				} else {
++					RELOC(hmt_thread_data)[i].pir = 
++						pir & 0x3ff;
++				}
++			}
++		}
++	} else {
++		prom_printf("Processor is not HMT capable\n");
++	}
++#endif
++
++	if (cpuid > NR_CPUS)
++		prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
++			    ") exceeded: ignoring extras\n");
++
++	prom_debug("prom_hold_cpus: end...\n");
++}
++
++
++static void __init prom_init_client_services(unsigned long pp)
++{
++	struct prom_t *_prom = &RELOC(prom);
++
++	/* Get a handle to the prom entry point before anything else */
++	RELOC(prom_entry) = pp;
++
++	/* get a handle for the stdout device */
++	_prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
++	if (!PHANDLE_VALID(_prom->chosen))
++		prom_panic("cannot find chosen"); /* msg won't be printed :( */
++
++	/* get device tree root */
++	_prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
++	if (!PHANDLE_VALID(_prom->root))
++		prom_panic("cannot find device tree root"); /* msg won't be printed :( */
++
++	_prom->mmumap = 0;
++}
++
++#ifdef CONFIG_PPC32
++/*
++ * For really old powermacs, we need to map things we claim.
++ * For that, we need the ihandle of the mmu.
++ */
++static void __init prom_find_mmu(void)
++{
++	struct prom_t *_prom = &RELOC(prom);
++	phandle oprom;
++	char version[64];
++
++	oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
++	if (!PHANDLE_VALID(oprom))
++		return;
++	if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
++		return;
++	version[sizeof(version) - 1] = 0;
++	prom_printf("OF version is '%s'\n", version);
++	/* XXX might need to add other versions here */
++	if (strcmp(version, "Open Firmware, 1.0.5") != 0)
++		return;
++	prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
++		     sizeof(_prom->mmumap));
++}
++#else
++#define prom_find_mmu()
++#endif
++
++static void __init prom_init_stdout(void)
++{
++	struct prom_t *_prom = &RELOC(prom);
++	char *path = RELOC(of_stdout_device);
++	char type[16];
++	u32 val;
++
++	if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
++		prom_panic("cannot find stdout");
++
++	_prom->stdout = val;
++
++	/* Get the full OF pathname of the stdout device */
++	memset(path, 0, 256);
++	call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
++	val = call_prom("instance-to-package", 1, 1, _prom->stdout);
++	prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val));
++	prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
++	prom_setprop(_prom->chosen, "linux,stdout-path",
++		     RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1);
++
++	/* If it's a display, note it */
++	memset(type, 0, sizeof(type));
++	prom_getprop(val, "device_type", type, sizeof(type));
++	if (strcmp(type, RELOC("display")) == 0)
++		prom_setprop(val, "linux,boot-display", NULL, 0);
++}
++
++static void __init prom_close_stdin(void)
++{
++	struct prom_t *_prom = &RELOC(prom);
++	ihandle val;
++
++	if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
++		call_prom("close", 1, 0, val);
++}
++
++static int __init prom_find_machine_type(void)
++{
++	struct prom_t *_prom = &RELOC(prom);
++	char compat[256];
++	int len, i = 0;
++	phandle rtas;
++
++	len = prom_getprop(_prom->root, "compatible",
++			   compat, sizeof(compat)-1);
++	if (len > 0) {
++		compat[len] = 0;
++		while (i < len) {
++			char *p = &compat[i];
++			int sl = strlen(p);
++			if (sl == 0)
++				break;
++			if (strstr(p, RELOC("Power Macintosh")) ||
++			    strstr(p, RELOC("MacRISC")))
++				return PLATFORM_POWERMAC;
++#ifdef CONFIG_PPC64
++			if (strstr(p, RELOC("Momentum,Maple")))
++				return PLATFORM_MAPLE;
++#endif
++			i += sl + 1;
++		}
++	}
++#ifdef CONFIG_PPC64
++	/* Default to pSeries. We need to know if we are running LPAR */
++	rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
++	if (PHANDLE_VALID(rtas)) {
++		int x = prom_getproplen(rtas, "ibm,hypertas-functions");
++		if (x != PROM_ERROR) {
++			prom_printf("Hypertas detected, assuming LPAR !\n");
++			return PLATFORM_PSERIES_LPAR;
++		}
++	}
++	return PLATFORM_PSERIES;
++#else
++	return PLATFORM_CHRP;
++#endif
++}
++
++static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
++{
++	return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
++}
++
++/*
++ * If we have a display that we don't know how to drive,
++ * we will want to try to execute OF's open method for it
++ * later.  However, OF will probably fall over if we do that
++ * we've taken over the MMU.
++ * So we check whether we will need to open the display,
++ * and if so, open it now.
++ */
++static void __init prom_check_displays(void)
++{
++	char type[16], *path;
++	phandle node;
++	ihandle ih;
++	int i;
++
++	static unsigned char default_colors[] = {
++		0x00, 0x00, 0x00,
++		0x00, 0x00, 0xaa,
++		0x00, 0xaa, 0x00,
++		0x00, 0xaa, 0xaa,
++		0xaa, 0x00, 0x00,
++		0xaa, 0x00, 0xaa,
++		0xaa, 0xaa, 0x00,
++		0xaa, 0xaa, 0xaa,
++		0x55, 0x55, 0x55,
++		0x55, 0x55, 0xff,
++		0x55, 0xff, 0x55,
++		0x55, 0xff, 0xff,
++		0xff, 0x55, 0x55,
++		0xff, 0x55, 0xff,
++		0xff, 0xff, 0x55,
++		0xff, 0xff, 0xff
++	};
++	const unsigned char *clut;
++
++	prom_printf("Looking for displays\n");
++	for (node = 0; prom_next_node(&node); ) {
++		memset(type, 0, sizeof(type));
++		prom_getprop(node, "device_type", type, sizeof(type));
++		if (strcmp(type, RELOC("display")) != 0)
++			continue;
++
++		/* It seems OF doesn't null-terminate the path :-( */
++		path = RELOC(prom_scratch);
++		memset(path, 0, PROM_SCRATCH_SIZE);
++
++		/*
++		 * leave some room at the end of the path for appending extra
++		 * arguments
++		 */
++		if (call_prom("package-to-path", 3, 1, node, path,
++			      PROM_SCRATCH_SIZE-10) == PROM_ERROR)
++			continue;
++		prom_printf("found display   : %s, opening ... ", path);
++		
++		ih = call_prom("open", 1, 1, path);
++		if (ih == 0) {
++			prom_printf("failed\n");
++			continue;
++		}
++
++		/* Success */
++		prom_printf("done\n");
++		prom_setprop(node, "linux,opened", NULL, 0);
++
++		/* Setup a usable color table when the appropriate
++		 * method is available. Should update this to set-colors */
++		clut = RELOC(default_colors);
++		for (i = 0; i < 32; i++, clut += 3)
++			if (prom_set_color(ih, i, clut[0], clut[1],
++					   clut[2]) != 0)
++				break;
++
++#ifdef CONFIG_LOGO_LINUX_CLUT224
++		clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
++		for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
++			if (prom_set_color(ih, i + 32, clut[0], clut[1],
++					   clut[2]) != 0)
++				break;
++#endif /* CONFIG_LOGO_LINUX_CLUT224 */
++	}
++}
++
++
++/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
++static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
++			      unsigned long needed, unsigned long align)
++{
++	void *ret;
++
++	*mem_start = _ALIGN(*mem_start, align);
++	while ((*mem_start + needed) > *mem_end) {
++		unsigned long room, chunk;
++
++		prom_debug("Chunk exhausted, claiming more at %x...\n",
++			   RELOC(alloc_bottom));
++		room = RELOC(alloc_top) - RELOC(alloc_bottom);
++		if (room > DEVTREE_CHUNK_SIZE)
++			room = DEVTREE_CHUNK_SIZE;
++		if (room < PAGE_SIZE)
++			prom_panic("No memory for flatten_device_tree (no room)");
++		chunk = alloc_up(room, 0);
++		if (chunk == 0)
++			prom_panic("No memory for flatten_device_tree (claim failed)");
++		*mem_end = RELOC(alloc_top);
++	}
++
++	ret = (void *)*mem_start;
++	*mem_start += needed;
++
++	return ret;
++}
++
++#define dt_push_token(token, mem_start, mem_end) \
++	do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
++
++static unsigned long __init dt_find_string(char *str)
++{
++	char *s, *os;
++
++	s = os = (char *)RELOC(dt_string_start);
++	s += 4;
++	while (s <  (char *)RELOC(dt_string_end)) {
++		if (strcmp(s, str) == 0)
++			return s - os;
++		s += strlen(s) + 1;
++	}
++	return 0;
++}
++
++/*
++ * The Open Firmware 1275 specification states properties must be 31 bytes or
++ * less, however not all firmwares obey this. Make it 64 bytes to be safe.
++ */
++#define MAX_PROPERTY_NAME 64
++
++static void __init scan_dt_build_strings(phandle node,
++					 unsigned long *mem_start,
++					 unsigned long *mem_end)
++{
++	char *prev_name, *namep, *sstart;
++	unsigned long soff;
++	phandle child;
++
++	sstart =  (char *)RELOC(dt_string_start);
++
++	/* get and store all property names */
++	prev_name = RELOC("");
++	for (;;) {
++		/* 64 is max len of name including nul. */
++		namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
++		if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
++			/* No more nodes: unwind alloc */
++			*mem_start = (unsigned long)namep;
++			break;
++		}
++
++ 		/* skip "name" */
++ 		if (strcmp(namep, RELOC("name")) == 0) {
++ 			*mem_start = (unsigned long)namep;
++ 			prev_name = RELOC("name");
++ 			continue;
++ 		}
++		/* get/create string entry */
++		soff = dt_find_string(namep);
++		if (soff != 0) {
++			*mem_start = (unsigned long)namep;
++			namep = sstart + soff;
++		} else {
++			/* Trim off some if we can */
++			*mem_start = (unsigned long)namep + strlen(namep) + 1;
++			RELOC(dt_string_end) = *mem_start;
++		}
++		prev_name = namep;
++	}
++
++	/* do all our children */
++	child = call_prom("child", 1, 1, node);
++	while (child != 0) {
++		scan_dt_build_strings(child, mem_start, mem_end);
++		child = call_prom("peer", 1, 1, child);
++	}
++}
++
++static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
++					unsigned long *mem_end)
++{
++	phandle child;
++	char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
++	unsigned long soff;
++	unsigned char *valp;
++	static char pname[MAX_PROPERTY_NAME];
++	int l, room;
++
++	dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
++
++	/* get the node's full name */
++	namep = (char *)*mem_start;
++	room = *mem_end - *mem_start;
++	if (room > 255)
++		room = 255;
++	l = call_prom("package-to-path", 3, 1, node, namep, room);
++	if (l >= 0) {
++		/* Didn't fit?  Get more room. */
++		if (l >= room) {
++			if (l >= *mem_end - *mem_start)
++				namep = make_room(mem_start, mem_end, l+1, 1);
++			call_prom("package-to-path", 3, 1, node, namep, l);
++		}
++		namep[l] = '\0';
++
++		/* Fixup an Apple bug where they have bogus \0 chars in the
++		 * middle of the path in some properties, and extract
++		 * the unit name (everything after the last '/').
++		 */
++		for (lp = p = namep, ep = namep + l; p < ep; p++) {
++			if (*p == '/')
++				lp = namep;
++			else if (*p != 0)
++				*lp++ = *p;
++		}
++		*lp = 0;
++		*mem_start = _ALIGN((unsigned long)lp + 1, 4);
++	}
++
++	/* get it again for debugging */
++	path = RELOC(prom_scratch);
++	memset(path, 0, PROM_SCRATCH_SIZE);
++	call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
++
++	/* get and store all properties */
++	prev_name = RELOC("");
++	sstart = (char *)RELOC(dt_string_start);
++	for (;;) {
++		if (call_prom("nextprop", 3, 1, node, prev_name,
++			      RELOC(pname)) != 1)
++			break;
++
++ 		/* skip "name" */
++ 		if (strcmp(RELOC(pname), RELOC("name")) == 0) {
++ 			prev_name = RELOC("name");
++ 			continue;
++ 		}
++
++		/* find string offset */
++		soff = dt_find_string(RELOC(pname));
++		if (soff == 0) {
++			prom_printf("WARNING: Can't find string index for"
++				    " <%s>, node %s\n", RELOC(pname), path);
++			break;
++		}
++		prev_name = sstart + soff;
++
++		/* get length */
++		l = call_prom("getproplen", 2, 1, node, RELOC(pname));
++
++		/* sanity checks */
++		if (l == PROM_ERROR)
++			continue;
++		if (l > MAX_PROPERTY_LENGTH) {
++			prom_printf("WARNING: ignoring large property ");
++			/* It seems OF doesn't null-terminate the path :-( */
++			prom_printf("[%s] ", path);
++			prom_printf("%s length 0x%x\n", RELOC(pname), l);
++			continue;
++		}
++
++		/* push property head */
++		dt_push_token(OF_DT_PROP, mem_start, mem_end);
++		dt_push_token(l, mem_start, mem_end);
++		dt_push_token(soff, mem_start, mem_end);
++
++		/* push property content */
++		valp = make_room(mem_start, mem_end, l, 4);
++		call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
++		*mem_start = _ALIGN(*mem_start, 4);
++	}
++
++	/* Add a "linux,phandle" property. */
++	soff = dt_find_string(RELOC("linux,phandle"));
++	if (soff == 0)
++		prom_printf("WARNING: Can't find string index for"
++			    " <linux-phandle> node %s\n", path);
++	else {
++		dt_push_token(OF_DT_PROP, mem_start, mem_end);
++		dt_push_token(4, mem_start, mem_end);
++		dt_push_token(soff, mem_start, mem_end);
++		valp = make_room(mem_start, mem_end, 4, 4);
++		*(u32 *)valp = node;
++	}
++
++	/* do all our children */
++	child = call_prom("child", 1, 1, node);
++	while (child != 0) {
++		scan_dt_build_struct(child, mem_start, mem_end);
++		child = call_prom("peer", 1, 1, child);
++	}
++
++	dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
++}
++
++static void __init flatten_device_tree(void)
++{
++	phandle root;
++	unsigned long mem_start, mem_end, room;
++	struct boot_param_header *hdr;
++	struct prom_t *_prom = &RELOC(prom);
++	char *namep;
++	u64 *rsvmap;
++
++	/*
++	 * Check how much room we have between alloc top & bottom (+/- a
++	 * few pages), crop to 4Mb, as this is our "chuck" size
++	 */
++	room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
++	if (room > DEVTREE_CHUNK_SIZE)
++		room = DEVTREE_CHUNK_SIZE;
++	prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
++
++	/* Now try to claim that */
++	mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
++	if (mem_start == 0)
++		prom_panic("Can't allocate initial device-tree chunk\n");
++	mem_end = RELOC(alloc_top);
++
++	/* Get root of tree */
++	root = call_prom("peer", 1, 1, (phandle)0);
++	if (root == (phandle)0)
++		prom_panic ("couldn't get device tree root\n");
++
++	/* Build header and make room for mem rsv map */ 
++	mem_start = _ALIGN(mem_start, 4);
++	hdr = make_room(&mem_start, &mem_end,
++			sizeof(struct boot_param_header), 4);
++	RELOC(dt_header_start) = (unsigned long)hdr;
++	rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
++
++	/* Start of strings */
++	mem_start = PAGE_ALIGN(mem_start);
++	RELOC(dt_string_start) = mem_start;
++	mem_start += 4; /* hole */
++
++	/* Add "linux,phandle" in there, we'll need it */
++	namep = make_room(&mem_start, &mem_end, 16, 1);
++	strcpy(namep, RELOC("linux,phandle"));
++	mem_start = (unsigned long)namep + strlen(namep) + 1;
++
++	/* Build string array */
++	prom_printf("Building dt strings...\n"); 
++	scan_dt_build_strings(root, &mem_start, &mem_end);
++	RELOC(dt_string_end) = mem_start;
++
++	/* Build structure */
++	mem_start = PAGE_ALIGN(mem_start);
++	RELOC(dt_struct_start) = mem_start;
++	prom_printf("Building dt structure...\n"); 
++	scan_dt_build_struct(root, &mem_start, &mem_end);
++	dt_push_token(OF_DT_END, &mem_start, &mem_end);
++	RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
++
++	/* Finish header */
++	hdr->boot_cpuid_phys = _prom->cpu;
++	hdr->magic = OF_DT_HEADER;
++	hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
++	hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
++	hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
++	hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
++	hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
++	hdr->version = OF_DT_VERSION;
++	/* Version 16 is not backward compatible */
++	hdr->last_comp_version = 0x10;
++
++	/* Reserve the whole thing and copy the reserve map in, we
++	 * also bump mem_reserve_cnt to cause further reservations to
++	 * fail since it's too late.
++	 */
++	reserve_mem(RELOC(dt_header_start), hdr->totalsize);
++	memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
++
++#ifdef DEBUG_PROM
++	{
++		int i;
++		prom_printf("reserved memory map:\n");
++		for (i = 0; i < RELOC(mem_reserve_cnt); i++)
++			prom_printf("  %x - %x\n",
++				    RELOC(mem_reserve_map)[i].base,
++				    RELOC(mem_reserve_map)[i].size);
++	}
++#endif
++	RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
++
++	prom_printf("Device tree strings 0x%x -> 0x%x\n",
++		    RELOC(dt_string_start), RELOC(dt_string_end)); 
++	prom_printf("Device tree struct  0x%x -> 0x%x\n",
++		    RELOC(dt_struct_start), RELOC(dt_struct_end));
++
++}
++
++
++static void __init fixup_device_tree(void)
++{
++#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
++	phandle u3, i2c, mpic;
++	u32 u3_rev;
++	u32 interrupts[2];
++	u32 parent;
++
++	/* Some G5s have a missing interrupt definition, fix it up here */
++	u3 = call_prom("finddevice", 1, 1, ADDR("/u3 at 0,f8000000"));
++	if (!PHANDLE_VALID(u3))
++		return;
++	i2c = call_prom("finddevice", 1, 1, ADDR("/u3 at 0,f8000000/i2c at f8001000"));
++	if (!PHANDLE_VALID(i2c))
++		return;
++	mpic = call_prom("finddevice", 1, 1, ADDR("/u3 at 0,f8000000/mpic at f8040000"));
++	if (!PHANDLE_VALID(mpic))
++		return;
++
++	/* check if proper rev of u3 */
++	if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
++	    == PROM_ERROR)
++		return;
++	if (u3_rev != 0x35 && u3_rev != 0x37)
++		return;
++	/* does it need fixup ? */
++	if (prom_getproplen(i2c, "interrupts") > 0)
++		return;
++
++	prom_printf("fixing up bogus interrupts for u3 i2c...\n");
++
++	/* interrupt on this revision of u3 is number 0 and level */
++	interrupts[0] = 0;
++	interrupts[1] = 1;
++	prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
++	parent = (u32)mpic;
++	prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
++#endif
++}
++
++
++static void __init prom_find_boot_cpu(void)
++{
++       	struct prom_t *_prom = &RELOC(prom);
++	u32 getprop_rval;
++	ihandle prom_cpu;
++	phandle cpu_pkg;
++
++	_prom->cpu = 0;
++	if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
++		return;
++
++	cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
++
++	prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
++	_prom->cpu = getprop_rval;
++
++	prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
++}
++
++static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
++{
++#ifdef CONFIG_BLK_DEV_INITRD
++       	struct prom_t *_prom = &RELOC(prom);
++
++	if (r3 && r4 && r4 != 0xdeadbeef) {
++		unsigned long val;
++
++		RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
++		RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
++
++		val = RELOC(prom_initrd_start);
++		prom_setprop(_prom->chosen, "linux,initrd-start", &val,
++			     sizeof(val));
++		val = RELOC(prom_initrd_end);
++		prom_setprop(_prom->chosen, "linux,initrd-end", &val,
++			     sizeof(val));
++
++		reserve_mem(RELOC(prom_initrd_start),
++			    RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
++
++		prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
++		prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
++	}
++#endif /* CONFIG_BLK_DEV_INITRD */
++}
++
++/*
++ * We enter here early on, when the Open Firmware prom is still
++ * handling exceptions and the MMU hash table for us.
++ */
++
++unsigned long __init prom_init(unsigned long r3, unsigned long r4,
++			       unsigned long pp,
++			       unsigned long r6, unsigned long r7)
++{	
++       	struct prom_t *_prom;
++	unsigned long hdr;
++	u32 getprop_rval;
++	unsigned long offset = reloc_offset();
++
++#ifdef CONFIG_PPC32
++	reloc_got2(offset);
++#endif
++
++	_prom = &RELOC(prom);
++
++	/*
++	 * First zero the BSS
++	 */
++	memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
++
++	/*
++	 * Init interface to Open Firmware, get some node references,
++	 * like /chosen
++	 */
++	prom_init_client_services(pp);
++
++	/*
++	 * Init prom stdout device
++	 */
++	prom_init_stdout();
++
++	/*
++	 * See if this OF is old enough that we need to do explicit maps
++	 */
++	prom_find_mmu();
++
++	/*
++	 * Check for an initrd
++	 */
++	prom_check_initrd(r3, r4);
++
++	/*
++	 * Get default machine type. At this point, we do not differentiate
++	 * between pSeries SMP and pSeries LPAR
++	 */
++	RELOC(of_platform) = prom_find_machine_type();
++	getprop_rval = RELOC(of_platform);
++	prom_setprop(_prom->chosen, "linux,platform",
++		     &getprop_rval, sizeof(getprop_rval));
++
++#ifdef CONFIG_PPC_PSERIES
++	/*
++	 * On pSeries, inform the firmware about our capabilities
++	 */
++	if (RELOC(of_platform) & PLATFORM_PSERIES)
++		prom_send_capabilities();
++#endif
++
++	/*
++	 * On pSeries and BPA, copy the CPU hold code
++	 */
++       	if (RELOC(of_platform) != PLATFORM_POWERMAC)
++       		copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
++
++	/*
++	 * Do early parsing of command line
++	 */
++	early_cmdline_parse();
++
++	/*
++	 * Initialize memory management within prom_init
++	 */
++	prom_init_mem();
++
++	/*
++	 * Determine which cpu is actually running right _now_
++	 */
++	prom_find_boot_cpu();
++
++	/* 
++	 * Initialize display devices
++	 */
++	prom_check_displays();
++
++#ifdef CONFIG_PPC64
++	/*
++	 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
++	 * that uses the allocator, we need to make sure we get the top of memory
++	 * available for us here...
++	 */
++	if (RELOC(of_platform) == PLATFORM_PSERIES)
++		prom_initialize_tce_table();
++#endif
++
++	/*
++	 * On non-powermacs, try to instantiate RTAS and puts all CPUs
++	 * in spin-loops. PowerMacs don't have a working RTAS and use
++	 * a different way to spin CPUs
++	 */
++	if (RELOC(of_platform) != PLATFORM_POWERMAC) {
++		prom_instantiate_rtas();
++		prom_hold_cpus();
++	}
++
++	/*
++	 * Fill in some infos for use by the kernel later on
++	 */
++	if (RELOC(prom_memory_limit))
++		prom_setprop(_prom->chosen, "linux,memory-limit",
++			     &RELOC(prom_memory_limit),
++			     sizeof(prom_memory_limit));
++#ifdef CONFIG_PPC64
++	if (RELOC(ppc64_iommu_off))
++		prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
++
++	if (RELOC(iommu_force_on))
++		prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
++
++	if (RELOC(prom_tce_alloc_start)) {
++		prom_setprop(_prom->chosen, "linux,tce-alloc-start",
++			     &RELOC(prom_tce_alloc_start),
++			     sizeof(prom_tce_alloc_start));
++		prom_setprop(_prom->chosen, "linux,tce-alloc-end",
++			     &RELOC(prom_tce_alloc_end),
++			     sizeof(prom_tce_alloc_end));
++	}
++#endif
++
++	/*
++	 * Fixup any known bugs in the device-tree
++	 */
++	fixup_device_tree();
++
++	/*
++	 * Now finally create the flattened device-tree
++	 */
++	prom_printf("copying OF device tree ...\n");
++	flatten_device_tree();
++
++	/* in case stdin is USB and still active on IBM machines... */
++	prom_close_stdin();
++
++	/*
++	 * Call OF "quiesce" method to shut down pending DMA's from
++	 * devices etc...
++	 */
++	prom_printf("Calling quiesce ...\n");
++	call_prom("quiesce", 0, 0);
++
++	/*
++	 * And finally, call the kernel passing it the flattened device
++	 * tree and NULL as r5, thus triggering the new entry point which
++	 * is common to us and kexec
++	 */
++	hdr = RELOC(dt_header_start);
++	prom_printf("returning from prom_init\n");
++	prom_debug("->dt_header_start=0x%x\n", hdr);
++
++#ifdef CONFIG_PPC32
++	reloc_got2(-offset);
++#endif
++
++	__start(hdr, KERNELBASE + offset, 0);
++
++	return 0;
++}
+diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/ptrace.c
+@@ -0,0 +1,613 @@
++/*
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Derived from "arch/m68k/kernel/ptrace.c"
++ *  Copyright (C) 1994 by Hamish Macdonald
++ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
++ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
++ *
++ * Modified by Cort Dougan (cort at hq.fsmlabs.com)
++ * and Paul Mackerras (paulus at samba.org).
++ *
++ * This file is subject to the terms and conditions of the GNU General
++ * Public License.  See the file README.legal in the main directory of
++ * this archive for more details.
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/smp.h>
++#include <linux/smp_lock.h>
++#include <linux/errno.h>
++#include <linux/ptrace.h>
++#include <linux/user.h>
++#include <linux/security.h>
++#include <linux/signal.h>
++#include <linux/seccomp.h>
++#include <linux/audit.h>
++#ifdef CONFIG_PPC32
++#include <linux/module.h>
++#endif
++
++#include <asm/uaccess.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/system.h>
++#ifdef CONFIG_PPC64
++#include <asm/ptrace-common.h>
++#endif
++
++#ifdef CONFIG_PPC32
++/*
++ * Set of msr bits that gdb can change on behalf of a process.
++ */
++#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
++#define MSR_DEBUGCHANGE	0
++#else
++#define MSR_DEBUGCHANGE	(MSR_SE | MSR_BE)
++#endif
++#endif /* CONFIG_PPC32 */
++
++/*
++ * does not yet catch signals sent when the child dies.
++ * in exit.c or in signal.c.
++ */
++
++#ifdef CONFIG_PPC32
++/*
++ * Get contents of register REGNO in task TASK.
++ */
++static inline unsigned long get_reg(struct task_struct *task, int regno)
++{
++	if (regno < sizeof(struct pt_regs) / sizeof(unsigned long)
++	    && task->thread.regs != NULL)
++		return ((unsigned long *)task->thread.regs)[regno];
++	return (0);
++}
++
++/*
++ * Write contents of register REGNO in task TASK.
++ */
++static inline int put_reg(struct task_struct *task, int regno,
++			  unsigned long data)
++{
++	if (regno <= PT_MQ && task->thread.regs != NULL) {
++		if (regno == PT_MSR)
++			data = (data & MSR_DEBUGCHANGE)
++				| (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
++		((unsigned long *)task->thread.regs)[regno] = data;
++		return 0;
++	}
++	return -EIO;
++}
++
++#ifdef CONFIG_ALTIVEC
++/*
++ * Get contents of AltiVec register state in task TASK
++ */
++static inline int get_vrregs(unsigned long __user *data, struct task_struct *task)
++{
++	int i, j;
++
++	if (!access_ok(VERIFY_WRITE, data, 133 * sizeof(unsigned long)))
++		return -EFAULT;
++
++	/* copy AltiVec registers VR[0] .. VR[31] */
++	for (i = 0; i < 32; i++)
++		for (j = 0; j < 4; j++, data++)
++			if (__put_user(task->thread.vr[i].u[j], data))
++				return -EFAULT;
++
++	/* copy VSCR */
++	for (i = 0; i < 4; i++, data++)
++		if (__put_user(task->thread.vscr.u[i], data))
++			return -EFAULT;
++
++        /* copy VRSAVE */
++	if (__put_user(task->thread.vrsave, data))
++		return -EFAULT;
++
++	return 0;
++}
++
++/*
++ * Write contents of AltiVec register state into task TASK.
++ */
++static inline int set_vrregs(struct task_struct *task, unsigned long __user *data)
++{
++	int i, j;
++
++	if (!access_ok(VERIFY_READ, data, 133 * sizeof(unsigned long)))
++		return -EFAULT;
++
++	/* copy AltiVec registers VR[0] .. VR[31] */
++	for (i = 0; i < 32; i++)
++		for (j = 0; j < 4; j++, data++)
++			if (__get_user(task->thread.vr[i].u[j], data))
++				return -EFAULT;
++
++	/* copy VSCR */
++	for (i = 0; i < 4; i++, data++)
++		if (__get_user(task->thread.vscr.u[i], data))
++			return -EFAULT;
++
++	/* copy VRSAVE */
++	if (__get_user(task->thread.vrsave, data))
++		return -EFAULT;
++
++	return 0;
++}
++#endif
++
++#ifdef CONFIG_SPE
++
++/*
++ * For get_evrregs/set_evrregs functions 'data' has the following layout:
++ *
++ * struct {
++ *   u32 evr[32];
++ *   u64 acc;
++ *   u32 spefscr;
++ * }
++ */
++
++/*
++ * Get contents of SPE register state in task TASK.
++ */
++static inline int get_evrregs(unsigned long *data, struct task_struct *task)
++{
++	int i;
++
++	if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long)))
++		return -EFAULT;
++
++	/* copy SPEFSCR */
++	if (__put_user(task->thread.spefscr, &data[34]))
++		return -EFAULT;
++
++	/* copy SPE registers EVR[0] .. EVR[31] */
++	for (i = 0; i < 32; i++, data++)
++		if (__put_user(task->thread.evr[i], data))
++			return -EFAULT;
++
++	/* copy ACC */
++	if (__put_user64(task->thread.acc, (unsigned long long *)data))
++		return -EFAULT;
++
++	return 0;
++}
++
++/*
++ * Write contents of SPE register state into task TASK.
++ */
++static inline int set_evrregs(struct task_struct *task, unsigned long *data)
++{
++	int i;
++
++	if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long)))
++		return -EFAULT;
++
++	/* copy SPEFSCR */
++	if (__get_user(task->thread.spefscr, &data[34]))
++		return -EFAULT;
++
++	/* copy SPE registers EVR[0] .. EVR[31] */
++	for (i = 0; i < 32; i++, data++)
++		if (__get_user(task->thread.evr[i], data))
++			return -EFAULT;
++	/* copy ACC */
++	if (__get_user64(task->thread.acc, (unsigned long long*)data))
++		return -EFAULT;
++
++	return 0;
++}
++#endif /* CONFIG_SPE */
++
++static inline void
++set_single_step(struct task_struct *task)
++{
++	struct pt_regs *regs = task->thread.regs;
++
++	if (regs != NULL) {
++#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
++		task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
++		regs->msr |= MSR_DE;
++#else
++		regs->msr |= MSR_SE;
++#endif
++	}
++}
++
++static inline void
++clear_single_step(struct task_struct *task)
++{
++	struct pt_regs *regs = task->thread.regs;
++
++	if (regs != NULL) {
++#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
++		task->thread.dbcr0 = 0;
++		regs->msr &= ~MSR_DE;
++#else
++		regs->msr &= ~MSR_SE;
++#endif
++	}
++}
++#endif /* CONFIG_PPC32 */
++
++/*
++ * Called by kernel/ptrace.c when detaching..
++ *
++ * Make sure single step bits etc are not set.
++ */
++void ptrace_disable(struct task_struct *child)
++{
++	/* make sure the single step bit is not set. */
++	clear_single_step(child);
++}
++
++long sys_ptrace(long request, long pid, long addr, long data)
++{
++	struct task_struct *child;
++	int ret = -EPERM;
++
++	lock_kernel();
++	if (request == PTRACE_TRACEME) {
++		/* are we already being traced? */
++		if (current->ptrace & PT_PTRACED)
++			goto out;
++		ret = security_ptrace(current->parent, current);
++		if (ret)
++			goto out;
++		/* set the ptrace bit in the process flags. */
++		current->ptrace |= PT_PTRACED;
++		ret = 0;
++		goto out;
++	}
++	ret = -ESRCH;
++	read_lock(&tasklist_lock);
++	child = find_task_by_pid(pid);
++	if (child)
++		get_task_struct(child);
++	read_unlock(&tasklist_lock);
++	if (!child)
++		goto out;
++
++	ret = -EPERM;
++	if (pid == 1)		/* you may not mess with init */
++		goto out_tsk;
++
++	if (request == PTRACE_ATTACH) {
++		ret = ptrace_attach(child);
++		goto out_tsk;
++	}
++
++	ret = ptrace_check_attach(child, request == PTRACE_KILL);
++	if (ret < 0)
++		goto out_tsk;
++
++	switch (request) {
++	/* when I and D space are separate, these will need to be fixed. */
++	case PTRACE_PEEKTEXT: /* read word at location addr. */
++	case PTRACE_PEEKDATA: {
++		unsigned long tmp;
++		int copied;
++
++		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
++		ret = -EIO;
++		if (copied != sizeof(tmp))
++			break;
++		ret = put_user(tmp,(unsigned long __user *) data);
++		break;
++	}
++
++	/* read the word at location addr in the USER area. */
++	case PTRACE_PEEKUSR: {
++		unsigned long index, tmp;
++
++		ret = -EIO;
++		/* convert to index and check */
++#ifdef CONFIG_PPC32
++		index = (unsigned long) addr >> 2;
++		if ((addr & 3) || (index > PT_FPSCR)
++		    || (child->thread.regs == NULL))
++#else
++		index = (unsigned long) addr >> 3;
++		if ((addr & 7) || (index > PT_FPSCR))
++#endif
++			break;
++
++#ifdef CONFIG_PPC32
++		CHECK_FULL_REGS(child->thread.regs);
++#endif
++		if (index < PT_FPR0) {
++			tmp = get_reg(child, (int) index);
++		} else {
++			flush_fp_to_thread(child);
++			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
++		}
++		ret = put_user(tmp,(unsigned long __user *) data);
++		break;
++	}
++
++	/* If I and D space are separate, this will have to be fixed. */
++	case PTRACE_POKETEXT: /* write the word at location addr. */
++	case PTRACE_POKEDATA:
++		ret = 0;
++		if (access_process_vm(child, addr, &data, sizeof(data), 1)
++				== sizeof(data))
++			break;
++		ret = -EIO;
++		break;
++
++	/* write the word at location addr in the USER area */
++	case PTRACE_POKEUSR: {
++		unsigned long index;
++
++		ret = -EIO;
++		/* convert to index and check */
++#ifdef CONFIG_PPC32
++		index = (unsigned long) addr >> 2;
++		if ((addr & 3) || (index > PT_FPSCR)
++		    || (child->thread.regs == NULL))
++#else
++		index = (unsigned long) addr >> 3;
++		if ((addr & 7) || (index > PT_FPSCR))
++#endif
++			break;
++
++#ifdef CONFIG_PPC32
++		CHECK_FULL_REGS(child->thread.regs);
++#endif
++		if (index == PT_ORIG_R3)
++			break;
++		if (index < PT_FPR0) {
++			ret = put_reg(child, index, data);
++		} else {
++			flush_fp_to_thread(child);
++			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
++			ret = 0;
++		}
++		break;
++	}
++
++	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
++	case PTRACE_CONT: { /* restart after signal. */
++		ret = -EIO;
++		if (!valid_signal(data))
++			break;
++		if (request == PTRACE_SYSCALL)
++			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++		else
++			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++		child->exit_code = data;
++		/* make sure the single step bit is not set. */
++		clear_single_step(child);
++		wake_up_process(child);
++		ret = 0;
++		break;
++	}
++
++/*
++ * make the child exit.  Best I can do is send it a sigkill.
++ * perhaps it should be put in the status that it wants to
++ * exit.
++ */
++	case PTRACE_KILL: {
++		ret = 0;
++		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
++			break;
++		child->exit_code = SIGKILL;
++		/* make sure the single step bit is not set. */
++		clear_single_step(child);
++		wake_up_process(child);
++		break;
++	}
++
++	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
++		ret = -EIO;
++		if (!valid_signal(data))
++			break;
++		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++		set_single_step(child);
++		child->exit_code = data;
++		/* give it a chance to run. */
++		wake_up_process(child);
++		ret = 0;
++		break;
++	}
++
++#ifdef CONFIG_PPC64
++	case PTRACE_GET_DEBUGREG: {
++		ret = -EINVAL;
++		/* We only support one DABR and no IABRS at the moment */
++		if (addr > 0)
++			break;
++		ret = put_user(child->thread.dabr,
++			       (unsigned long __user *)data);
++		break;
++	}
++
++	case PTRACE_SET_DEBUGREG:
++		ret = ptrace_set_debugreg(child, addr, data);
++		break;
++#endif
++
++	case PTRACE_DETACH:
++		ret = ptrace_detach(child, data);
++		break;
++
++#ifdef CONFIG_PPC64
++	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
++		int i;
++		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
++		unsigned long __user *tmp = (unsigned long __user *)addr;
++
++		for (i = 0; i < 32; i++) {
++			ret = put_user(*reg, tmp);
++			if (ret)
++				break;
++			reg++;
++			tmp++;
++		}
++		break;
++	}
++
++	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
++		int i;
++		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
++		unsigned long __user *tmp = (unsigned long __user *)addr;
++
++		for (i = 0; i < 32; i++) {
++			ret = get_user(*reg, tmp);
++			if (ret)
++				break;
++			reg++;
++			tmp++;
++		}
++		break;
++	}
++
++	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
++		int i;
++		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
++		unsigned long __user *tmp = (unsigned long __user *)addr;
++
++		flush_fp_to_thread(child);
++
++		for (i = 0; i < 32; i++) {
++			ret = put_user(*reg, tmp);
++			if (ret)
++				break;
++			reg++;
++			tmp++;
++		}
++		break;
++	}
++
++	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
++		int i;
++		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
++		unsigned long __user *tmp = (unsigned long __user *)addr;
++
++		flush_fp_to_thread(child);
++
++		for (i = 0; i < 32; i++) {
++			ret = get_user(*reg, tmp);
++			if (ret)
++				break;
++			reg++;
++			tmp++;
++		}
++		break;
++	}
++#endif /* CONFIG_PPC64 */
++
++#ifdef CONFIG_ALTIVEC
++	case PTRACE_GETVRREGS:
++		/* Get the child altivec register state. */
++		flush_altivec_to_thread(child);
++		ret = get_vrregs((unsigned long __user *)data, child);
++		break;
++
++	case PTRACE_SETVRREGS:
++		/* Set the child altivec register state. */
++		flush_altivec_to_thread(child);
++		ret = set_vrregs(child, (unsigned long __user *)data);
++		break;
++#endif
++#ifdef CONFIG_SPE
++	case PTRACE_GETEVRREGS:
++		/* Get the child spe register state. */
++		if (child->thread.regs->msr & MSR_SPE)
++			giveup_spe(child);
++		ret = get_evrregs((unsigned long __user *)data, child);
++		break;
++
++	case PTRACE_SETEVRREGS:
++		/* Set the child spe register state. */
++		/* this is to clear the MSR_SPE bit to force a reload
++		 * of register state from memory */
++		if (child->thread.regs->msr & MSR_SPE)
++			giveup_spe(child);
++		ret = set_evrregs(child, (unsigned long __user *)data);
++		break;
++#endif
++
++	default:
++		ret = ptrace_request(child, request, addr, data);
++		break;
++	}
++out_tsk:
++	put_task_struct(child);
++out:
++	unlock_kernel();
++	return ret;
++}
++
++static void do_syscall_trace(void)
++{
++	/* the 0x80 provides a way for the tracing parent to distinguish
++	   between a syscall stop and SIGTRAP delivery */
++	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
++				 ? 0x80 : 0));
++
++	/*
++	 * this isn't the same as continuing with a signal, but it will do
++	 * for normal use.  strace only continues with a signal if the
++	 * stopping signal is not SIGTRAP.  -brl
++	 */
++	if (current->exit_code) {
++		send_sig(current->exit_code, current, 1);
++		current->exit_code = 0;
++	}
++}
++
++void do_syscall_trace_enter(struct pt_regs *regs)
++{
++#ifdef CONFIG_PPC64
++	secure_computing(regs->gpr[0]);
++#endif
++
++	if (test_thread_flag(TIF_SYSCALL_TRACE)
++	    && (current->ptrace & PT_PTRACED))
++		do_syscall_trace();
++
++	if (unlikely(current->audit_context))
++		audit_syscall_entry(current,
++#ifdef CONFIG_PPC32
++				    AUDIT_ARCH_PPC,
++#else
++				    test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
++#endif
++				    regs->gpr[0],
++				    regs->gpr[3], regs->gpr[4],
++				    regs->gpr[5], regs->gpr[6]);
++}
++
++void do_syscall_trace_leave(struct pt_regs *regs)
++{
++#ifdef CONFIG_PPC32
++	secure_computing(regs->gpr[0]);
++#endif
++
++	if (unlikely(current->audit_context))
++		audit_syscall_exit(current,
++				   (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
++				   regs->result);
++
++	if ((test_thread_flag(TIF_SYSCALL_TRACE)
++#ifdef CONFIG_PPC64
++	     || test_thread_flag(TIF_SINGLESTEP)
++#endif
++	     )
++	    && (current->ptrace & PT_PTRACED))
++		do_syscall_trace();
++}
++
++#ifdef CONFIG_PPC32
++EXPORT_SYMBOL(do_syscall_trace_enter);
++EXPORT_SYMBOL(do_syscall_trace_leave);
++#endif
+diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/ptrace32.c
+@@ -0,0 +1,450 @@
++/*
++ * ptrace for 32-bit processes running on a 64-bit kernel.
++ *
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Derived from "arch/m68k/kernel/ptrace.c"
++ *  Copyright (C) 1994 by Hamish Macdonald
++ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
++ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
++ *
++ * Modified by Cort Dougan (cort at hq.fsmlabs.com)
++ * and Paul Mackerras (paulus at samba.org).
++ *
++ * 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/config.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/smp.h>
++#include <linux/smp_lock.h>
++#include <linux/errno.h>
++#include <linux/ptrace.h>
++#include <linux/user.h>
++#include <linux/security.h>
++#include <linux/signal.h>
++
++#include <asm/uaccess.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/system.h>
++#include <asm/ptrace-common.h>
++
++/*
++ * does not yet catch signals sent when the child dies.
++ * in exit.c or in signal.c.
++ */
++
++long compat_sys_ptrace(int request, int pid, unsigned long addr,
++		       unsigned long data)
++{
++	struct task_struct *child;
++	int ret = -EPERM;
++
++	lock_kernel();
++	if (request == PTRACE_TRACEME) {
++		/* are we already being traced? */
++		if (current->ptrace & PT_PTRACED)
++			goto out;
++		ret = security_ptrace(current->parent, current);
++		if (ret)
++			goto out;
++		/* set the ptrace bit in the process flags. */
++		current->ptrace |= PT_PTRACED;
++		ret = 0;
++		goto out;
++	}
++	ret = -ESRCH;
++	read_lock(&tasklist_lock);
++	child = find_task_by_pid(pid);
++	if (child)
++		get_task_struct(child);
++	read_unlock(&tasklist_lock);
++	if (!child)
++		goto out;
++
++	ret = -EPERM;
++	if (pid == 1)		/* you may not mess with init */
++		goto out_tsk;
++
++	if (request == PTRACE_ATTACH) {
++		ret = ptrace_attach(child);
++		goto out_tsk;
++	}
++
++	ret = ptrace_check_attach(child, request == PTRACE_KILL);
++	if (ret < 0)
++		goto out_tsk;
++
++	switch (request) {
++	/* when I and D space are separate, these will need to be fixed. */
++	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
++	case PTRACE_PEEKDATA: {
++		unsigned int tmp;
++		int copied;
++
++		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
++		ret = -EIO;
++		if (copied != sizeof(tmp))
++			break;
++		ret = put_user(tmp, (u32 __user *)data);
++		break;
++	}
++
++	/*
++	 * Read 4 bytes of the other process' storage
++	 *  data is a pointer specifying where the user wants the
++	 *	4 bytes copied into
++	 *  addr is a pointer in the user's storage that contains an 8 byte
++	 *	address in the other process of the 4 bytes that is to be read
++	 * (this is run in a 32-bit process looking at a 64-bit process)
++	 * when I and D space are separate, these will need to be fixed.
++	 */
++	case PPC_PTRACE_PEEKTEXT_3264:
++	case PPC_PTRACE_PEEKDATA_3264: {
++		u32 tmp;
++		int copied;
++		u32 __user * addrOthers;
++
++		ret = -EIO;
++
++		/* Get the addr in the other process that we want to read */
++		if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
++			break;
++
++		copied = access_process_vm(child, (u64)addrOthers, &tmp,
++				sizeof(tmp), 0);
++		if (copied != sizeof(tmp))
++			break;
++		ret = put_user(tmp, (u32 __user *)data);
++		break;
++	}
++
++	/* Read a register (specified by ADDR) out of the "user area" */
++	case PTRACE_PEEKUSR: {
++		int index;
++		unsigned long tmp;
++
++		ret = -EIO;
++		/* convert to index and check */
++		index = (unsigned long) addr >> 2;
++		if ((addr & 3) || (index > PT_FPSCR32))
++			break;
++
++		if (index < PT_FPR0) {
++			tmp = get_reg(child, index);
++		} else {
++			flush_fp_to_thread(child);
++			/*
++			 * the user space code considers the floating point
++			 * to be an array of unsigned int (32 bits) - the
++			 * index passed in is based on this assumption.
++			 */
++			tmp = ((unsigned int *)child->thread.fpr)[index - PT_FPR0];
++		}
++		ret = put_user((unsigned int)tmp, (u32 __user *)data);
++		break;
++	}
++  
++	/*
++	 * Read 4 bytes out of the other process' pt_regs area
++	 *  data is a pointer specifying where the user wants the
++	 *	4 bytes copied into
++	 *  addr is the offset into the other process' pt_regs structure
++	 *	that is to be read
++	 * (this is run in a 32-bit process looking at a 64-bit process)
++	 */
++	case PPC_PTRACE_PEEKUSR_3264: {
++		u32 index;
++		u32 reg32bits;
++		u64 tmp;
++		u32 numReg;
++		u32 part;
++
++		ret = -EIO;
++		/* Determine which register the user wants */
++		index = (u64)addr >> 2;
++		numReg = index / 2;
++		/* Determine which part of the register the user wants */
++		if (index % 2)
++			part = 1;  /* want the 2nd half of the register (right-most). */
++		else
++			part = 0;  /* want the 1st half of the register (left-most). */
++
++		/* Validate the input - check to see if address is on the wrong boundary or beyond the end of the user area */
++		if ((addr & 3) || numReg > PT_FPSCR)
++			break;
++
++		if (numReg >= PT_FPR0) {
++			flush_fp_to_thread(child);
++			tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
++		} else { /* register within PT_REGS struct */
++			tmp = get_reg(child, numReg);
++		} 
++		reg32bits = ((u32*)&tmp)[part];
++		ret = put_user(reg32bits, (u32 __user *)data);
++		break;
++	}
++
++	/* If I and D space are separate, this will have to be fixed. */
++	case PTRACE_POKETEXT: /* write the word at location addr. */
++	case PTRACE_POKEDATA: {
++		unsigned int tmp;
++		tmp = data;
++		ret = 0;
++		if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1)
++				== sizeof(tmp))
++			break;
++		ret = -EIO;
++		break;
++	}
++
++	/*
++	 * Write 4 bytes into the other process' storage
++	 *  data is the 4 bytes that the user wants written
++	 *  addr is a pointer in the user's storage that contains an
++	 *	8 byte address in the other process where the 4 bytes
++	 *	that is to be written
++	 * (this is run in a 32-bit process looking at a 64-bit process)
++	 * when I and D space are separate, these will need to be fixed.
++	 */
++	case PPC_PTRACE_POKETEXT_3264:
++	case PPC_PTRACE_POKEDATA_3264: {
++		u32 tmp = data;
++		u32 __user * addrOthers;
++
++		/* Get the addr in the other process that we want to write into */
++		ret = -EIO;
++		if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
++			break;
++		ret = 0;
++		if (access_process_vm(child, (u64)addrOthers, &tmp,
++					sizeof(tmp), 1) == sizeof(tmp))
++			break;
++		ret = -EIO;
++		break;
++	}
++
++	/* write the word at location addr in the USER area */
++	case PTRACE_POKEUSR: {
++		unsigned long index;
++
++		ret = -EIO;
++		/* convert to index and check */
++		index = (unsigned long) addr >> 2;
++		if ((addr & 3) || (index > PT_FPSCR32))
++			break;
++
++		if (index == PT_ORIG_R3)
++			break;
++		if (index < PT_FPR0) {
++			ret = put_reg(child, index, data);
++		} else {
++			flush_fp_to_thread(child);
++			/*
++			 * the user space code considers the floating point
++			 * to be an array of unsigned int (32 bits) - the
++			 * index passed in is based on this assumption.
++			 */
++			((unsigned int *)child->thread.fpr)[index - PT_FPR0] = data;
++			ret = 0;
++		}
++		break;
++	}
++
++	/*
++	 * Write 4 bytes into the other process' pt_regs area
++	 *  data is the 4 bytes that the user wants written
++	 *  addr is the offset into the other process' pt_regs structure
++	 *	that is to be written into
++	 * (this is run in a 32-bit process looking at a 64-bit process)
++	 */
++	case PPC_PTRACE_POKEUSR_3264: {
++		u32 index;
++		u32 numReg;
++
++		ret = -EIO;
++		/* Determine which register the user wants */
++		index = (u64)addr >> 2;
++		numReg = index / 2;
++		/*
++		 * Validate the input - check to see if address is on the
++		 * wrong boundary or beyond the end of the user area
++		 */
++		if ((addr & 3) || (numReg > PT_FPSCR))
++			break;
++		/* Insure it is a register we let them change */
++		if ((numReg == PT_ORIG_R3)
++				|| ((numReg > PT_CCR) && (numReg < PT_FPR0)))
++			break;
++		if (numReg >= PT_FPR0) {
++			flush_fp_to_thread(child);
++		}
++		if (numReg == PT_MSR)
++			data = (data & MSR_DEBUGCHANGE)
++				| (child->thread.regs->msr & ~MSR_DEBUGCHANGE);
++		((u32*)child->thread.regs)[index] = data;
++		ret = 0;
++		break;
++	}
++
++	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
++	case PTRACE_CONT: { /* restart after signal. */
++		ret = -EIO;
++		if (!valid_signal(data))
++			break;
++		if (request == PTRACE_SYSCALL)
++			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++		else
++			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++		child->exit_code = data;
++		/* make sure the single step bit is not set. */
++		clear_single_step(child);
++		wake_up_process(child);
++		ret = 0;
++		break;
++	}
++
++	/*
++	 * make the child exit.  Best I can do is send it a sigkill.
++	 * perhaps it should be put in the status that it wants to
++	 * exit.
++	 */
++	case PTRACE_KILL: {
++		ret = 0;
++		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
++			break;
++		child->exit_code = SIGKILL;
++		/* make sure the single step bit is not set. */
++		clear_single_step(child);
++		wake_up_process(child);
++		break;
++	}
++
++	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
++		ret = -EIO;
++		if (!valid_signal(data))
++			break;
++		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++		set_single_step(child);
++		child->exit_code = data;
++		/* give it a chance to run. */
++		wake_up_process(child);
++		ret = 0;
++		break;
++	}
++
++	case PTRACE_GET_DEBUGREG: {
++		ret = -EINVAL;
++		/* We only support one DABR and no IABRS at the moment */
++		if (addr > 0)
++			break;
++		ret = put_user(child->thread.dabr, (u32 __user *)data);
++		break;
++	}
++
++	case PTRACE_SET_DEBUGREG:
++		ret = ptrace_set_debugreg(child, addr, data);
++		break;
++
++	case PTRACE_DETACH:
++		ret = ptrace_detach(child, data);
++		break;
++
++	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
++		int i;
++		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
++		unsigned int __user *tmp = (unsigned int __user *)addr;
++
++		for (i = 0; i < 32; i++) {
++			ret = put_user(*reg, tmp);
++			if (ret)
++				break;
++			reg++;
++			tmp++;
++		}
++		break;
++	}
++
++	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
++		int i;
++		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
++		unsigned int __user *tmp = (unsigned int __user *)addr;
++
++		for (i = 0; i < 32; i++) {
++			ret = get_user(*reg, tmp);
++			if (ret)
++				break;
++			reg++;
++			tmp++;
++		}
++		break;
++	}
++
++	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
++		int i;
++		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
++		unsigned int __user *tmp = (unsigned int __user *)addr;
++
++		flush_fp_to_thread(child);
++
++		for (i = 0; i < 32; i++) {
++			ret = put_user(*reg, tmp);
++			if (ret)
++				break;
++			reg++;
++			tmp++;
++		}
++		break;
++	}
++
++	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
++		int i;
++		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
++		unsigned int __user *tmp = (unsigned int __user *)addr;
++
++		flush_fp_to_thread(child);
++
++		for (i = 0; i < 32; i++) {
++			ret = get_user(*reg, tmp);
++			if (ret)
++				break;
++			reg++;
++			tmp++;
++		}
++		break;
++	}
++
++	case PTRACE_GETEVENTMSG:
++		ret = put_user(child->ptrace_message, (unsigned int __user *) data);
++		break;
++
++#ifdef CONFIG_ALTIVEC
++	case PTRACE_GETVRREGS:
++		/* Get the child altivec register state. */
++		flush_altivec_to_thread(child);
++		ret = get_vrregs((unsigned long __user *)data, child);
++		break;
++
++	case PTRACE_SETVRREGS:
++		/* Set the child altivec register state. */
++		flush_altivec_to_thread(child);
++		ret = set_vrregs(child, (unsigned long __user *)data);
++		break;
++#endif
++
++	default:
++		ret = ptrace_request(child, request, addr, data);
++		break;
++	}
++out_tsk:
++	put_task_struct(child);
++out:
++	unlock_kernel();
++	return ret;
++}
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/rtas.c
+@@ -0,0 +1,680 @@
++/*
++ *
++ * Procedures for interfacing to the RTAS on CHRP machines.
++ *
++ * Peter Bergner, IBM	March 2001.
++ * Copyright (C) 2001 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 <stdarg.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/spinlock.h>
++#include <linux/module.h>
++#include <linux/init.h>
++
++#include <asm/prom.h>
++#include <asm/rtas.h>
++#include <asm/semaphore.h>
++#include <asm/machdep.h>
++#include <asm/page.h>
++#include <asm/param.h>
++#include <asm/system.h>
++#include <asm/delay.h>
++#include <asm/uaccess.h>
++#include <asm/lmb.h>
++#ifdef CONFIG_PPC64
++#include <asm/systemcfg.h>
++#endif
++
++struct rtas_t rtas = {
++	.lock = SPIN_LOCK_UNLOCKED
++};
++
++EXPORT_SYMBOL(rtas);
++
++DEFINE_SPINLOCK(rtas_data_buf_lock);
++char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
++unsigned long rtas_rmo_buf;
++
++/*
++ * call_rtas_display_status and call_rtas_display_status_delay
++ * are designed only for very early low-level debugging, which
++ * is why the token is hard-coded to 10.
++ */
++void call_rtas_display_status(unsigned char c)
++{
++	struct rtas_args *args = &rtas.args;
++	unsigned long s;
++
++	if (!rtas.base)
++		return;
++	spin_lock_irqsave(&rtas.lock, s);
++
++	args->token = 10;
++	args->nargs = 1;
++	args->nret  = 1;
++	args->rets  = (rtas_arg_t *)&(args->args[1]);
++	args->args[0] = (int)c;
++
++	enter_rtas(__pa(args));
++
++	spin_unlock_irqrestore(&rtas.lock, s);
++}
++
++void call_rtas_display_status_delay(unsigned char c)
++{
++	static int pending_newline = 0;  /* did last write end with unprinted newline? */
++	static int width = 16;
++
++	if (c == '\n') {	
++		while (width-- > 0)
++			call_rtas_display_status(' ');
++		width = 16;
++		udelay(500000);
++		pending_newline = 1;
++	} else {
++		if (pending_newline) {
++			call_rtas_display_status('\r');
++			call_rtas_display_status('\n');
++		} 
++		pending_newline = 0;
++		if (width--) {
++			call_rtas_display_status(c);
++			udelay(10000);
++		}
++	}
++}
++
++void rtas_progress(char *s, unsigned short hex)
++{
++	struct device_node *root;
++	int width, *p;
++	char *os;
++	static int display_character, set_indicator;
++	static int display_width, display_lines, *row_width, form_feed;
++	static DEFINE_SPINLOCK(progress_lock);
++	static int current_line;
++	static int pending_newline = 0;  /* did last write end with unprinted newline? */
++
++	if (!rtas.base)
++		return;
++
++	if (display_width == 0) {
++		display_width = 0x10;
++		if ((root = find_path_device("/rtas"))) {
++			if ((p = (unsigned int *)get_property(root,
++					"ibm,display-line-length", NULL)))
++				display_width = *p;
++			if ((p = (unsigned int *)get_property(root,
++					"ibm,form-feed", NULL)))
++				form_feed = *p;
++			if ((p = (unsigned int *)get_property(root,
++					"ibm,display-number-of-lines", NULL)))
++				display_lines = *p;
++			row_width = (unsigned int *)get_property(root,
++					"ibm,display-truncation-length", NULL);
++		}
++		display_character = rtas_token("display-character");
++		set_indicator = rtas_token("set-indicator");
++	}
++
++	if (display_character == RTAS_UNKNOWN_SERVICE) {
++		/* use hex display if available */
++		if (set_indicator != RTAS_UNKNOWN_SERVICE)
++			rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
++		return;
++	}
++
++	spin_lock(&progress_lock);
++
++	/*
++	 * Last write ended with newline, but we didn't print it since
++	 * it would just clear the bottom line of output. Print it now
++	 * instead.
++	 *
++	 * If no newline is pending and form feed is supported, clear the
++	 * display with a form feed; otherwise, print a CR to start output
++	 * at the beginning of the line.
++	 */
++	if (pending_newline) {
++		rtas_call(display_character, 1, 1, NULL, '\r');
++		rtas_call(display_character, 1, 1, NULL, '\n');
++		pending_newline = 0;
++	} else {
++		current_line = 0;
++		if (form_feed)
++			rtas_call(display_character, 1, 1, NULL,
++				  (char)form_feed);
++		else
++			rtas_call(display_character, 1, 1, NULL, '\r');
++	}
++ 
++	if (row_width)
++		width = row_width[current_line];
++	else
++		width = display_width;
++	os = s;
++	while (*os) {
++		if (*os == '\n' || *os == '\r') {
++			/* If newline is the last character, save it
++			 * until next call to avoid bumping up the
++			 * display output.
++			 */
++			if (*os == '\n' && !os[1]) {
++				pending_newline = 1;
++				current_line++;
++				if (current_line > display_lines-1)
++					current_line = display_lines-1;
++				spin_unlock(&progress_lock);
++				return;
++			}
++ 
++			/* RTAS wants CR-LF, not just LF */
++ 
++			if (*os == '\n') {
++				rtas_call(display_character, 1, 1, NULL, '\r');
++				rtas_call(display_character, 1, 1, NULL, '\n');
++			} else {
++				/* CR might be used to re-draw a line, so we'll
++				 * leave it alone and not add LF.
++				 */
++				rtas_call(display_character, 1, 1, NULL, *os);
++			}
++ 
++			if (row_width)
++				width = row_width[current_line];
++			else
++				width = display_width;
++		} else {
++			width--;
++			rtas_call(display_character, 1, 1, NULL, *os);
++		}
++ 
++		os++;
++ 
++		/* if we overwrite the screen length */
++		if (width <= 0)
++			while ((*os != 0) && (*os != '\n') && (*os != '\r'))
++				os++;
++	}
++ 
++	spin_unlock(&progress_lock);
++}
++
++int rtas_token(const char *service)
++{
++	int *tokp;
++	if (rtas.dev == NULL)
++		return RTAS_UNKNOWN_SERVICE;
++	tokp = (int *) get_property(rtas.dev, service, NULL);
++	return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
++}
++
++#ifdef CONFIG_RTAS_ERROR_LOGGING
++/*
++ * Return the firmware-specified size of the error log buffer
++ *  for all rtas calls that require an error buffer argument.
++ *  This includes 'check-exception' and 'rtas-last-error'.
++ */
++int rtas_get_error_log_max(void)
++{
++	static int rtas_error_log_max;
++	if (rtas_error_log_max)
++		return rtas_error_log_max;
++
++	rtas_error_log_max = rtas_token ("rtas-error-log-max");
++	if ((rtas_error_log_max == RTAS_UNKNOWN_SERVICE) ||
++	    (rtas_error_log_max > RTAS_ERROR_LOG_MAX)) {
++		printk (KERN_WARNING "RTAS: bad log buffer size %d\n",
++			rtas_error_log_max);
++		rtas_error_log_max = RTAS_ERROR_LOG_MAX;
++	}
++	return rtas_error_log_max;
++}
++EXPORT_SYMBOL(rtas_get_error_log_max);
++
++
++char rtas_err_buf[RTAS_ERROR_LOG_MAX];
++int rtas_last_error_token;
++
++/** Return a copy of the detailed error text associated with the
++ *  most recent failed call to rtas.  Because the error text
++ *  might go stale if there are any other intervening rtas calls,
++ *  this routine must be called atomically with whatever produced
++ *  the error (i.e. with rtas.lock still held from the previous call).
++ */
++static char *__fetch_rtas_last_error(char *altbuf)
++{
++	struct rtas_args err_args, save_args;
++	u32 bufsz;
++	char *buf = NULL;
++
++	if (rtas_last_error_token == -1)
++		return NULL;
++
++	bufsz = rtas_get_error_log_max();
++
++	err_args.token = rtas_last_error_token;
++	err_args.nargs = 2;
++	err_args.nret = 1;
++	err_args.args[0] = (rtas_arg_t)__pa(rtas_err_buf);
++	err_args.args[1] = bufsz;
++	err_args.args[2] = 0;
++
++	save_args = rtas.args;
++	rtas.args = err_args;
++
++	enter_rtas(__pa(&rtas.args));
++
++	err_args = rtas.args;
++	rtas.args = save_args;
++
++	/* Log the error in the unlikely case that there was one. */
++	if (unlikely(err_args.args[2] == 0)) {
++		if (altbuf) {
++			buf = altbuf;
++		} else {
++			buf = rtas_err_buf;
++			if (mem_init_done)
++				buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
++		}
++		if (buf)
++			memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX);
++	}
++
++	return buf;
++}
++
++#define get_errorlog_buffer()	kmalloc(RTAS_ERROR_LOG_MAX, GFP_KERNEL)
++
++#else /* CONFIG_RTAS_ERROR_LOGGING */
++#define __fetch_rtas_last_error(x)	NULL
++#define get_errorlog_buffer()		NULL
++#endif
++
++int rtas_call(int token, int nargs, int nret, int *outputs, ...)
++{
++	va_list list;
++	int i;
++	unsigned long s;
++	struct rtas_args *rtas_args;
++	char *buff_copy = NULL;
++	int ret;
++
++	if (token == RTAS_UNKNOWN_SERVICE)
++		return -1;
++
++	/* Gotta do something different here, use global lock for now... */
++	spin_lock_irqsave(&rtas.lock, s);
++	rtas_args = &rtas.args;
++
++	rtas_args->token = token;
++	rtas_args->nargs = nargs;
++	rtas_args->nret  = nret;
++	rtas_args->rets  = (rtas_arg_t *)&(rtas_args->args[nargs]);
++	va_start(list, outputs);
++	for (i = 0; i < nargs; ++i)
++		rtas_args->args[i] = va_arg(list, rtas_arg_t);
++	va_end(list);
++
++	for (i = 0; i < nret; ++i)
++		rtas_args->rets[i] = 0;
++
++	enter_rtas(__pa(rtas_args));
++
++	/* A -1 return code indicates that the last command couldn't
++	   be completed due to a hardware error. */
++	if (rtas_args->rets[0] == -1)
++		buff_copy = __fetch_rtas_last_error(NULL);
++
++	if (nret > 1 && outputs != NULL)
++		for (i = 0; i < nret-1; ++i)
++			outputs[i] = rtas_args->rets[i+1];
++	ret = (nret > 0)? rtas_args->rets[0]: 0;
++
++	/* Gotta do something different here, use global lock for now... */
++	spin_unlock_irqrestore(&rtas.lock, s);
++
++	if (buff_copy) {
++		log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0);
++		if (mem_init_done)
++			kfree(buff_copy);
++	}
++	return ret;
++}
++
++/* Given an RTAS status code of 990n compute the hinted delay of 10^n
++ * (last digit) milliseconds.  For now we bound at n=5 (100 sec).
++ */
++unsigned int rtas_extended_busy_delay_time(int status)
++{
++	int order = status - 9900;
++	unsigned long ms;
++
++	if (order < 0)
++		order = 0;	/* RTC depends on this for -2 clock busy */
++	else if (order > 5)
++		order = 5;	/* bound */
++
++	/* Use microseconds for reasonable accuracy */
++	for (ms = 1; order > 0; order--)
++		ms *= 10;
++
++	return ms; 
++}
++
++int rtas_error_rc(int rtas_rc)
++{
++	int rc;
++
++	switch (rtas_rc) {
++		case -1: 		/* Hardware Error */
++			rc = -EIO;
++			break;
++		case -3:		/* Bad indicator/domain/etc */
++			rc = -EINVAL;
++			break;
++		case -9000:		/* Isolation error */
++			rc = -EFAULT;
++			break;
++		case -9001:		/* Outstanding TCE/PTE */
++			rc = -EEXIST;
++			break;
++		case -9002:		/* No usable slot */
++			rc = -ENODEV;
++			break;
++		default:
++			printk(KERN_ERR "%s: unexpected RTAS error %d\n",
++					__FUNCTION__, rtas_rc);
++			rc = -ERANGE;
++			break;
++	}
++	return rc;
++}
++
++int rtas_get_power_level(int powerdomain, int *level)
++{
++	int token = rtas_token("get-power-level");
++	int rc;
++
++	if (token == RTAS_UNKNOWN_SERVICE)
++		return -ENOENT;
++
++	while ((rc = rtas_call(token, 1, 2, level, powerdomain)) == RTAS_BUSY)
++		udelay(1);
++
++	if (rc < 0)
++		return rtas_error_rc(rc);
++	return rc;
++}
++
++int rtas_set_power_level(int powerdomain, int level, int *setlevel)
++{
++	int token = rtas_token("set-power-level");
++	unsigned int wait_time;
++	int rc;
++
++	if (token == RTAS_UNKNOWN_SERVICE)
++		return -ENOENT;
++
++	while (1) {
++		rc = rtas_call(token, 2, 2, setlevel, powerdomain, level);
++		if (rc == RTAS_BUSY)
++			udelay(1);
++		else if (rtas_is_extended_busy(rc)) {
++			wait_time = rtas_extended_busy_delay_time(rc);
++			udelay(wait_time * 1000);
++		} else
++			break;
++	}
++
++	if (rc < 0)
++		return rtas_error_rc(rc);
++	return rc;
++}
++
++int rtas_get_sensor(int sensor, int index, int *state)
++{
++	int token = rtas_token("get-sensor-state");
++	unsigned int wait_time;
++	int rc;
++
++	if (token == RTAS_UNKNOWN_SERVICE)
++		return -ENOENT;
++
++	while (1) {
++		rc = rtas_call(token, 2, 2, state, sensor, index);
++		if (rc == RTAS_BUSY)
++			udelay(1);
++		else if (rtas_is_extended_busy(rc)) {
++			wait_time = rtas_extended_busy_delay_time(rc);
++			udelay(wait_time * 1000);
++		} else
++			break;
++	}
++
++	if (rc < 0)
++		return rtas_error_rc(rc);
++	return rc;
++}
++
++int rtas_set_indicator(int indicator, int index, int new_value)
++{
++	int token = rtas_token("set-indicator");
++	unsigned int wait_time;
++	int rc;
++
++	if (token == RTAS_UNKNOWN_SERVICE)
++		return -ENOENT;
++
++	while (1) {
++		rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value);
++		if (rc == RTAS_BUSY)
++			udelay(1);
++		else if (rtas_is_extended_busy(rc)) {
++			wait_time = rtas_extended_busy_delay_time(rc);
++			udelay(wait_time * 1000);
++		}
++		else
++			break;
++	}
++
++	if (rc < 0)
++		return rtas_error_rc(rc);
++	return rc;
++}
++
++void rtas_restart(char *cmd)
++{
++	printk("RTAS system-reboot returned %d\n",
++	       rtas_call(rtas_token("system-reboot"), 0, 1, NULL));
++	for (;;);
++}
++
++void rtas_power_off(void)
++{
++	/* allow power on only with power button press */
++	printk("RTAS power-off returned %d\n",
++	       rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
++	for (;;);
++}
++
++void rtas_halt(void)
++{
++	rtas_power_off();
++}
++
++/* Must be in the RMO region, so we place it here */
++static char rtas_os_term_buf[2048];
++
++void rtas_os_term(char *str)
++{
++	int status;
++
++	if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
++		return;
++
++	snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
++
++	do {
++		status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
++				   __pa(rtas_os_term_buf));
++
++		if (status == RTAS_BUSY)
++			udelay(1);
++		else if (status != 0)
++			printk(KERN_EMERG "ibm,os-term call failed %d\n",
++			       status);
++	} while (status == RTAS_BUSY);
++}
++
++
++asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
++{
++	struct rtas_args args;
++	unsigned long flags;
++	char *buff_copy, *errbuf = NULL;
++	int nargs;
++
++	if (!capable(CAP_SYS_ADMIN))
++		return -EPERM;
++
++	if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
++		return -EFAULT;
++
++	nargs = args.nargs;
++	if (nargs > ARRAY_SIZE(args.args)
++	    || args.nret > ARRAY_SIZE(args.args)
++	    || nargs + args.nret > ARRAY_SIZE(args.args))
++		return -EINVAL;
++
++	/* Copy in args. */
++	if (copy_from_user(args.args, uargs->args,
++			   nargs * sizeof(rtas_arg_t)) != 0)
++		return -EFAULT;
++
++	buff_copy = get_errorlog_buffer();
++
++	spin_lock_irqsave(&rtas.lock, flags);
++
++	rtas.args = args;
++	enter_rtas(__pa(&rtas.args));
++	args = rtas.args;
++
++	args.rets = &args.args[nargs];
++
++	/* A -1 return code indicates that the last command couldn't
++	   be completed due to a hardware error. */
++	if (args.rets[0] == -1)
++		errbuf = __fetch_rtas_last_error(buff_copy);
++
++	spin_unlock_irqrestore(&rtas.lock, flags);
++
++	if (buff_copy) {
++		if (errbuf)
++			log_error(errbuf, ERR_TYPE_RTAS_LOG, 0);
++		kfree(buff_copy);
++	}
++
++	/* Copy out args. */
++	if (copy_to_user(uargs->args + nargs,
++			 args.args + nargs,
++			 args.nret * sizeof(rtas_arg_t)) != 0)
++		return -EFAULT;
++
++	return 0;
++}
++
++#ifdef CONFIG_SMP
++/* This version can't take the spinlock, because it never returns */
++
++struct rtas_args rtas_stop_self_args = {
++	/* The token is initialized for real in setup_system() */
++	.token = RTAS_UNKNOWN_SERVICE,
++	.nargs = 0,
++	.nret = 1,
++	.rets = &rtas_stop_self_args.args[0],
++};
++
++void rtas_stop_self(void)
++{
++	struct rtas_args *rtas_args = &rtas_stop_self_args;
++
++	local_irq_disable();
++
++	BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE);
++
++	printk("cpu %u (hwid %u) Ready to die...\n",
++	       smp_processor_id(), hard_smp_processor_id());
++	enter_rtas(__pa(rtas_args));
++
++	panic("Alas, I survived.\n");
++}
++#endif
++
++/*
++ * Call early during boot, before mem init or bootmem, to retreive the RTAS
++ * informations from the device-tree and allocate the RMO buffer for userland
++ * accesses.
++ */
++void __init rtas_initialize(void)
++{
++	unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
++
++	/* Get RTAS dev node and fill up our "rtas" structure with infos
++	 * about it.
++	 */
++	rtas.dev = of_find_node_by_name(NULL, "rtas");
++	if (rtas.dev) {
++		u32 *basep, *entryp;
++		u32 *sizep;
++
++		basep = (u32 *)get_property(rtas.dev, "linux,rtas-base", NULL);
++		sizep = (u32 *)get_property(rtas.dev, "rtas-size", NULL);
++		if (basep != NULL && sizep != NULL) {
++			rtas.base = *basep;
++			rtas.size = *sizep;
++			entryp = (u32 *)get_property(rtas.dev, "linux,rtas-entry", NULL);
++			if (entryp == NULL) /* Ugh */
++				rtas.entry = rtas.base;
++			else
++				rtas.entry = *entryp;
++		} else
++			rtas.dev = NULL;
++	}
++	if (!rtas.dev)
++		return;
++
++	/* If RTAS was found, allocate the RMO buffer for it and look for
++	 * the stop-self token if any
++	 */
++#ifdef CONFIG_PPC64
++	if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
++		rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
++#endif
++	rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region);
++
++#ifdef CONFIG_HOTPLUG_CPU
++	rtas_stop_self_args.token = rtas_token("stop-self");
++#endif /* CONFIG_HOTPLUG_CPU */
++#ifdef CONFIG_RTAS_ERROR_LOGGING
++	rtas_last_error_token = rtas_token("rtas-last-error");
++#endif
++}
++
++
++EXPORT_SYMBOL(rtas_token);
++EXPORT_SYMBOL(rtas_call);
++EXPORT_SYMBOL(rtas_data_buf);
++EXPORT_SYMBOL(rtas_data_buf_lock);
++EXPORT_SYMBOL(rtas_extended_busy_delay_time);
++EXPORT_SYMBOL(rtas_get_sensor);
++EXPORT_SYMBOL(rtas_get_power_level);
++EXPORT_SYMBOL(rtas_set_power_level);
++EXPORT_SYMBOL(rtas_set_indicator);
+diff --git a/arch/powerpc/kernel/semaphore.c b/arch/powerpc/kernel/semaphore.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/semaphore.c
+@@ -0,0 +1,135 @@
++/*
++ * PowerPC-specific semaphore code.
++ *
++ * Copyright (C) 1999 Cort Dougan <cort at cs.nmt.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.
++ *
++ * April 2001 - Reworked by Paul Mackerras <paulus at samba.org>
++ * to eliminate the SMP races in the old version between the updates
++ * of `count' and `waking'.  Now we use negative `count' values to
++ * indicate that some process(es) are waiting for the semaphore.
++ */
++
++#include <linux/sched.h>
++#include <linux/init.h>
++#include <linux/module.h>
++
++#include <asm/atomic.h>
++#include <asm/semaphore.h>
++#include <asm/errno.h>
++
++/*
++ * Atomically update sem->count.
++ * This does the equivalent of the following:
++ *
++ *	old_count = sem->count;
++ *	tmp = MAX(old_count, 0) + incr;
++ *	sem->count = tmp;
++ *	return old_count;
++ */
++static inline int __sem_update_count(struct semaphore *sem, int incr)
++{
++	int old_count, tmp;
++
++	__asm__ __volatile__("\n"
++"1:	lwarx	%0,0,%3\n"
++"	srawi	%1,%0,31\n"
++"	andc	%1,%0,%1\n"
++"	add	%1,%1,%4\n"
++	PPC405_ERR77(0,%3)
++"	stwcx.	%1,0,%3\n"
++"	bne	1b"
++	: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
++	: "r" (&sem->count), "r" (incr), "m" (sem->count)
++	: "cc");
++
++	return old_count;
++}
++
++void __up(struct semaphore *sem)
++{
++	/*
++	 * Note that we incremented count in up() before we came here,
++	 * but that was ineffective since the result was <= 0, and
++	 * any negative value of count is equivalent to 0.
++	 * This ends up setting count to 1, unless count is now > 0
++	 * (i.e. because some other cpu has called up() in the meantime),
++	 * in which case we just increment count.
++	 */
++	__sem_update_count(sem, 1);
++	wake_up(&sem->wait);
++}
++EXPORT_SYMBOL(__up);
++
++/*
++ * Note that when we come in to __down or __down_interruptible,
++ * we have already decremented count, but that decrement was
++ * ineffective since the result was < 0, and any negative value
++ * of count is equivalent to 0.
++ * Thus it is only when we decrement count from some value > 0
++ * that we have actually got the semaphore.
++ */
++void __sched __down(struct semaphore *sem)
++{
++	struct task_struct *tsk = current;
++	DECLARE_WAITQUEUE(wait, tsk);
++
++	__set_task_state(tsk, TASK_UNINTERRUPTIBLE);
++	add_wait_queue_exclusive(&sem->wait, &wait);
++
++	/*
++	 * Try to get the semaphore.  If the count is > 0, then we've
++	 * got the semaphore; we decrement count and exit the loop.
++	 * If the count is 0 or negative, we set it to -1, indicating
++	 * that we are asleep, and then sleep.
++	 */
++	while (__sem_update_count(sem, -1) <= 0) {
++		schedule();
++		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
++	}
++	remove_wait_queue(&sem->wait, &wait);
++	__set_task_state(tsk, TASK_RUNNING);
++
++	/*
++	 * If there are any more sleepers, wake one of them up so
++	 * that it can either get the semaphore, or set count to -1
++	 * indicating that there are still processes sleeping.
++	 */
++	wake_up(&sem->wait);
++}
++EXPORT_SYMBOL(__down);
++
++int __sched __down_interruptible(struct semaphore * sem)
++{
++	int retval = 0;
++	struct task_struct *tsk = current;
++	DECLARE_WAITQUEUE(wait, tsk);
++
++	__set_task_state(tsk, TASK_INTERRUPTIBLE);
++	add_wait_queue_exclusive(&sem->wait, &wait);
++
++	while (__sem_update_count(sem, -1) <= 0) {
++		if (signal_pending(current)) {
++			/*
++			 * A signal is pending - give up trying.
++			 * Set sem->count to 0 if it is negative,
++			 * since we are no longer sleeping.
++			 */
++			__sem_update_count(sem, 0);
++			retval = -EINTR;
++			break;
++		}
++		schedule();
++		set_task_state(tsk, TASK_INTERRUPTIBLE);
++	}
++	remove_wait_queue(&sem->wait, &wait);
++	__set_task_state(tsk, TASK_RUNNING);
++
++	wake_up(&sem->wait);
++	return retval;
++}
++EXPORT_SYMBOL(__down_interruptible);
+diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/setup-common.c
+@@ -0,0 +1,410 @@
++/*
++ * Common boot and setup code for both 32-bit and 64-bit.
++ * Extracted from arch/powerpc/kernel/setup_64.c.
++ *
++ * Copyright (C) 2001 PPC64 Team, IBM Corp
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ */
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/sched.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/reboot.h>
++#include <linux/delay.h>
++#include <linux/initrd.h>
++#include <linux/ide.h>
++#include <linux/seq_file.h>
++#include <linux/ioport.h>
++#include <linux/console.h>
++#include <linux/utsname.h>
++#include <linux/tty.h>
++#include <linux/root_dev.h>
++#include <linux/notifier.h>
++#include <linux/cpu.h>
++#include <linux/unistd.h>
++#include <linux/serial.h>
++#include <linux/serial_8250.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/processor.h>
++#include <asm/pgtable.h>
++#include <asm/smp.h>
++#include <asm/elf.h>
++#include <asm/machdep.h>
++#include <asm/time.h>
++#include <asm/cputable.h>
++#include <asm/sections.h>
++#include <asm/btext.h>
++#include <asm/nvram.h>
++#include <asm/setup.h>
++#include <asm/system.h>
++#include <asm/rtas.h>
++#include <asm/iommu.h>
++#include <asm/serial.h>
++#include <asm/cache.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/lmb.h>
++
++#undef DEBUG
++
++#ifdef DEBUG
++#define DBG(fmt...) udbg_printf(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++/*
++ * This still seems to be needed... -- paulus
++ */ 
++struct screen_info screen_info = {
++	.orig_x = 0,
++	.orig_y = 25,
++	.orig_video_cols = 80,
++	.orig_video_lines = 25,
++	.orig_video_isVGA = 1,
++	.orig_video_points = 16
++};
++
++#ifdef __DO_IRQ_CANON
++/* XXX should go elsewhere eventually */
++int ppc_do_canonicalize_irqs;
++EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
++#endif
++
++/* also used by kexec */
++void machine_shutdown(void)
++{
++	if (ppc_md.nvram_sync)
++		ppc_md.nvram_sync();
++}
++
++void machine_restart(char *cmd)
++{
++	machine_shutdown();
++	ppc_md.restart(cmd);
++#ifdef CONFIG_SMP
++	smp_send_stop();
++#endif
++	printk(KERN_EMERG "System Halted, OK to turn off power\n");
++	local_irq_disable();
++	while (1) ;
++}
++
++void machine_power_off(void)
++{
++	machine_shutdown();
++	ppc_md.power_off();
++#ifdef CONFIG_SMP
++	smp_send_stop();
++#endif
++	printk(KERN_EMERG "System Halted, OK to turn off power\n");
++	local_irq_disable();
++	while (1) ;
++}
++/* Used by the G5 thermal driver */
++EXPORT_SYMBOL_GPL(machine_power_off);
++
++void (*pm_power_off)(void) = machine_power_off;
++EXPORT_SYMBOL_GPL(pm_power_off);
++
++void machine_halt(void)
++{
++	machine_shutdown();
++	ppc_md.halt();
++#ifdef CONFIG_SMP
++	smp_send_stop();
++#endif
++	printk(KERN_EMERG "System Halted, OK to turn off power\n");
++	local_irq_disable();
++	while (1) ;
++}
++
++
++#ifdef CONFIG_TAU
++extern u32 cpu_temp(unsigned long cpu);
++extern u32 cpu_temp_both(unsigned long cpu);
++#endif /* CONFIG_TAU */
++
++#ifdef CONFIG_SMP
++DEFINE_PER_CPU(unsigned int, pvr);
++#endif
++
++static int show_cpuinfo(struct seq_file *m, void *v)
++{
++	unsigned long cpu_id = (unsigned long)v - 1;
++	unsigned int pvr;
++	unsigned short maj;
++	unsigned short min;
++
++	if (cpu_id == NR_CPUS) {
++#if defined(CONFIG_SMP) && defined(CONFIG_PPC32)
++		unsigned long bogosum = 0;
++		int i;
++		for (i = 0; i < NR_CPUS; ++i)
++			if (cpu_online(i))
++				bogosum += loops_per_jiffy;
++		seq_printf(m, "total bogomips\t: %lu.%02lu\n",
++			   bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
++#endif /* CONFIG_SMP && CONFIG_PPC32 */
++		seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
++
++		if (ppc_md.show_cpuinfo != NULL)
++			ppc_md.show_cpuinfo(m);
++
++		return 0;
++	}
++
++	/* We only show online cpus: disable preempt (overzealous, I
++	 * knew) to prevent cpu going down. */
++	preempt_disable();
++	if (!cpu_online(cpu_id)) {
++		preempt_enable();
++		return 0;
++	}
++
++#ifdef CONFIG_SMP
++#ifdef CONFIG_PPC64	/* XXX for now */
++	pvr = per_cpu(pvr, cpu_id);
++#else
++	pvr = cpu_data[cpu_id].pvr;
++#endif
++#else
++	pvr = mfspr(SPRN_PVR);
++#endif
++	maj = (pvr >> 8) & 0xFF;
++	min = pvr & 0xFF;
++
++	seq_printf(m, "processor\t: %lu\n", cpu_id);
++	seq_printf(m, "cpu\t\t: ");
++
++	if (cur_cpu_spec->pvr_mask)
++		seq_printf(m, "%s", cur_cpu_spec->cpu_name);
++	else
++		seq_printf(m, "unknown (%08x)", pvr);
++
++#ifdef CONFIG_ALTIVEC
++	if (cpu_has_feature(CPU_FTR_ALTIVEC))
++		seq_printf(m, ", altivec supported");
++#endif /* CONFIG_ALTIVEC */
++
++	seq_printf(m, "\n");
++
++#ifdef CONFIG_TAU
++	if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
++#ifdef CONFIG_TAU_AVERAGE
++		/* more straightforward, but potentially misleading */
++		seq_printf(m,  "temperature \t: %u C (uncalibrated)\n",
++			   cpu_temp(i));
++#else
++		/* show the actual temp sensor range */
++		u32 temp;
++		temp = cpu_temp_both(i);
++		seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n",
++			   temp & 0xff, temp >> 16);
++#endif
++	}
++#endif /* CONFIG_TAU */
++
++	/*
++	 * Assume here that all clock rates are the same in a
++	 * smp system.  -- Cort
++	 */
++	if (ppc_proc_freq)
++		seq_printf(m, "clock\t\t: %lu.%06luMHz\n",
++			   ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
++
++	if (ppc_md.show_percpuinfo != NULL)
++		ppc_md.show_percpuinfo(m, cpu_id);
++
++	/* If we are a Freescale core do a simple check so
++	 * we dont have to keep adding cases in the future */
++	if (PVR_VER(pvr) & 0x8000) {
++		maj = PVR_MAJ(pvr);
++		min = PVR_MIN(pvr);
++	} else {
++		switch (PVR_VER(pvr)) {
++			case 0x0020:	/* 403 family */
++				maj = PVR_MAJ(pvr) + 1;
++				min = PVR_MIN(pvr);
++				break;
++			case 0x1008:	/* 740P/750P ?? */
++				maj = ((pvr >> 8) & 0xFF) - 1;
++				min = pvr & 0xFF;
++				break;
++			default:
++				maj = (pvr >> 8) & 0xFF;
++				min = pvr & 0xFF;
++				break;
++		}
++	}
++
++	seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
++		   maj, min, PVR_VER(pvr), PVR_REV(pvr));
++
++#ifdef CONFIG_PPC32
++	seq_printf(m, "bogomips\t: %lu.%02lu\n",
++		   loops_per_jiffy / (500000/HZ),
++		   (loops_per_jiffy / (5000/HZ)) % 100);
++#endif
++
++#ifdef CONFIG_SMP
++	seq_printf(m, "\n");
++#endif
++
++	preempt_enable();
++	return 0;
++}
++
++static void *c_start(struct seq_file *m, loff_t *pos)
++{
++	unsigned long i = *pos;
++
++	return i <= NR_CPUS ? (void *)(i + 1) : NULL;
++}
++
++static void *c_next(struct seq_file *m, void *v, loff_t *pos)
++{
++	++*pos;
++	return c_start(m, pos);
++}
++
++static void c_stop(struct seq_file *m, void *v)
++{
++}
++
++struct seq_operations cpuinfo_op = {
++	.start =c_start,
++	.next =	c_next,
++	.stop =	c_stop,
++	.show =	show_cpuinfo,
++};
++
++#ifdef CONFIG_PPC_MULTIPLATFORM
++static int __init set_preferred_console(void)
++{
++	struct device_node *prom_stdout = NULL;
++	char *name;
++	u32 *spd;
++	int offset = 0;
++
++	DBG(" -> set_preferred_console()\n");
++
++	/* The user has requested a console so this is already set up. */
++	if (strstr(saved_command_line, "console=")) {
++		DBG(" console was specified !\n");
++		return -EBUSY;
++	}
++
++	if (!of_chosen) {
++		DBG(" of_chosen is NULL !\n");
++		return -ENODEV;
++	}
++	/* We are getting a weird phandle from OF ... */
++	/* ... So use the full path instead */
++	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
++	if (name == NULL) {
++		DBG(" no linux,stdout-path !\n");
++		return -ENODEV;
++	}
++	prom_stdout = of_find_node_by_path(name);
++	if (!prom_stdout) {
++		DBG(" can't find stdout package %s !\n", name);
++		return -ENODEV;
++	}	
++	DBG("stdout is %s\n", prom_stdout->full_name);
++
++	name = (char *)get_property(prom_stdout, "name", NULL);
++	if (!name) {
++		DBG(" stdout package has no name !\n");
++		goto not_found;
++	}
++	spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
++
++	if (0)
++		;
++#ifdef CONFIG_SERIAL_8250_CONSOLE
++	else if (strcmp(name, "serial") == 0) {
++		int i;
++		u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
++		if (i > 8) {
++			switch (reg[1]) {
++				case 0x3f8:
++					offset = 0;
++					break;
++				case 0x2f8:
++					offset = 1;
++					break;
++				case 0x898:
++					offset = 2;
++					break;
++				case 0x890:
++					offset = 3;
++					break;
++				default:
++					/* We dont recognise the serial port */
++					goto not_found;
++			}
++		}
++	}
++#endif /* CONFIG_SERIAL_8250_CONSOLE */
++#ifdef CONFIG_PPC_PSERIES
++	else if (strcmp(name, "vty") == 0) {
++ 		u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
++ 		char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
++
++ 		if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
++ 			/* Host Virtual Serial Interface */
++ 			switch (reg[0]) {
++ 				case 0x30000000:
++ 					offset = 0;
++ 					break;
++ 				case 0x30000001:
++ 					offset = 1;
++ 					break;
++ 				default:
++					goto not_found;
++ 			}
++			of_node_put(prom_stdout);
++			DBG("Found hvsi console at offset %d\n", offset);
++ 			return add_preferred_console("hvsi", offset, NULL);
++ 		} else {
++ 			/* pSeries LPAR virtual console */
++			of_node_put(prom_stdout);
++			DBG("Found hvc console\n");
++ 			return add_preferred_console("hvc", 0, NULL);
++ 		}
++	}
++#endif /* CONFIG_PPC_PSERIES */
++#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
++	else if (strcmp(name, "ch-a") == 0)
++		offset = 0;
++	else if (strcmp(name, "ch-b") == 0)
++		offset = 1;
++#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
++	else
++		goto not_found;
++	of_node_put(prom_stdout);
++
++	DBG("Found serial console at ttyS%d\n", offset);
++
++	if (spd) {
++		static char __initdata opt[16];
++		sprintf(opt, "%d", *spd);
++		return add_preferred_console("ttyS", offset, opt);
++	} else
++		return add_preferred_console("ttyS", offset, NULL);
++
++ not_found:
++	DBG("No preferred console found !\n");
++	of_node_put(prom_stdout);
++	return -ENODEV;
++}
++console_initcall(set_preferred_console);
++#endif /* CONFIG_PPC_MULTIPLATFORM */
+diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/setup_32.c
+@@ -0,0 +1,372 @@
++/*
++ * Common prep/pmac/chrp boot and setup code.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/sched.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/reboot.h>
++#include <linux/delay.h>
++#include <linux/initrd.h>
++#include <linux/ide.h>
++#include <linux/tty.h>
++#include <linux/bootmem.h>
++#include <linux/seq_file.h>
++#include <linux/root_dev.h>
++#include <linux/cpu.h>
++#include <linux/console.h>
++
++#include <asm/residual.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/processor.h>
++#include <asm/pgtable.h>
++#include <asm/setup.h>
++#include <asm/amigappc.h>
++#include <asm/smp.h>
++#include <asm/elf.h>
++#include <asm/cputable.h>
++#include <asm/bootx.h>
++#include <asm/btext.h>
++#include <asm/machdep.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++#include <asm/pmac_feature.h>
++#include <asm/sections.h>
++#include <asm/nvram.h>
++#include <asm/xmon.h>
++#include <asm/time.h>
++
++#define DBG(fmt...)
++
++#if defined CONFIG_KGDB
++#include <asm/kgdb.h>
++#endif
++
++extern void platform_init(void);
++extern void bootx_init(unsigned long r4, unsigned long phys);
++
++extern void ppc6xx_idle(void);
++extern void power4_idle(void);
++
++boot_infos_t *boot_infos;
++struct ide_machdep_calls ppc_ide_md;
++
++/* XXX should go elsewhere */
++int __irq_offset_value;
++EXPORT_SYMBOL(__irq_offset_value);
++
++int boot_cpuid;
++EXPORT_SYMBOL_GPL(boot_cpuid);
++int boot_cpuid_phys;
++
++unsigned long ISA_DMA_THRESHOLD;
++unsigned int DMA_MODE_READ;
++unsigned int DMA_MODE_WRITE;
++
++int have_of = 1;
++
++#ifdef CONFIG_PPC_MULTIPLATFORM
++int _machine = 0;
++
++extern void prep_init(void);
++extern void pmac_init(void);
++extern void chrp_init(void);
++
++dev_t boot_dev;
++#endif /* CONFIG_PPC_MULTIPLATFORM */
++
++#ifdef CONFIG_MAGIC_SYSRQ
++unsigned long SYSRQ_KEY = 0x54;
++#endif /* CONFIG_MAGIC_SYSRQ */
++
++#ifdef CONFIG_VGA_CONSOLE
++unsigned long vgacon_remap_base;
++#endif
++
++struct machdep_calls ppc_md;
++EXPORT_SYMBOL(ppc_md);
++
++/*
++ * These are used in binfmt_elf.c to put aux entries on the stack
++ * for each elf executable being started.
++ */
++int dcache_bsize;
++int icache_bsize;
++int ucache_bsize;
++
++/*
++ * We're called here very early in the boot.  We determine the machine
++ * type and call the appropriate low-level setup functions.
++ *  -- Cort <cort at fsmlabs.com>
++ *
++ * Note that the kernel may be running at an address which is different
++ * from the address that it was linked at, so we must use RELOC/PTRRELOC
++ * to access static data (including strings).  -- paulus
++ */
++unsigned long __init early_init(unsigned long dt_ptr)
++{
++	unsigned long offset = reloc_offset();
++
++	/* First zero the BSS -- use memset_io, some platforms don't have
++	 * caches on yet */
++	memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start);
++
++	/*
++	 * Identify the CPU type and fix up code sections
++	 * that depend on which cpu we have.
++	 */
++	identify_cpu(offset, 0);
++	do_cpu_ftr_fixups(offset);
++
++	return KERNELBASE + offset;
++}
++
++#ifdef CONFIG_PPC_MULTIPLATFORM
++/*
++ * The PPC_MULTIPLATFORM version of platform_init...
++ */
++void __init platform_init(void)
++{
++	/* if we didn't get any bootinfo telling us what we are... */
++	if (_machine == 0) {
++		/* prep boot loader tells us if we're prep or not */
++		if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
++			_machine = _MACH_prep;
++	}
++
++#ifdef CONFIG_PPC_PREP
++	/* not much more to do here, if prep */
++	if (_machine == _MACH_prep) {
++		prep_init();
++		return;
++	}
++#endif
++
++#ifdef CONFIG_ADB
++	if (strstr(cmd_line, "adb_sync")) {
++		extern int __adb_probe_sync;
++		__adb_probe_sync = 1;
++	}
++#endif /* CONFIG_ADB */
++
++	switch (_machine) {
++#ifdef CONFIG_PPC_PMAC
++	case _MACH_Pmac:
++		pmac_init();
++		break;
++#endif
++#ifdef CONFIG_PPC_CHRP
++	case _MACH_chrp:
++		chrp_init();
++		break;
++#endif
++	}
++}
++#endif
++
++/*
++ * Find out what kind of machine we're on and save any data we need
++ * from the early boot process (devtree is copied on pmac by prom_init()).
++ * This is called very early on the boot process, after a minimal
++ * MMU environment has been set up but before MMU_init is called.
++ */
++void __init machine_init(unsigned long dt_ptr, unsigned long phys)
++{
++	early_init_devtree(__va(dt_ptr));
++
++#ifdef CONFIG_CMDLINE
++	strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
++#endif /* CONFIG_CMDLINE */
++
++	platform_init();
++
++#ifdef CONFIG_6xx
++	ppc_md.power_save = ppc6xx_idle;
++#endif
++
++	if (ppc_md.progress)
++		ppc_md.progress("id mach(): done", 0x200);
++}
++
++#ifdef CONFIG_BOOKE_WDT
++/* Checks wdt=x and wdt_period=xx command-line option */
++int __init early_parse_wdt(char *p)
++{
++	if (p && strncmp(p, "0", 1) != 0)
++	       booke_wdt_enabled = 1;
++
++	return 0;
++}
++early_param("wdt", early_parse_wdt);
++
++int __init early_parse_wdt_period (char *p)
++{
++	if (p)
++		booke_wdt_period = simple_strtoul(p, NULL, 0);
++
++	return 0;
++}
++early_param("wdt_period", early_parse_wdt_period);
++#endif	/* CONFIG_BOOKE_WDT */
++
++/* Checks "l2cr=xxxx" command-line option */
++int __init ppc_setup_l2cr(char *str)
++{
++	if (cpu_has_feature(CPU_FTR_L2CR)) {
++		unsigned long val = simple_strtoul(str, NULL, 0);
++		printk(KERN_INFO "l2cr set to %lx\n", val);
++		_set_L2CR(0);		/* force invalidate by disable cache */
++		_set_L2CR(val);		/* and enable it */
++	}
++	return 1;
++}
++__setup("l2cr=", ppc_setup_l2cr);
++
++#ifdef CONFIG_GENERIC_NVRAM
++
++/* Generic nvram hooks used by drivers/char/gen_nvram.c */
++unsigned char nvram_read_byte(int addr)
++{
++	if (ppc_md.nvram_read_val)
++		return ppc_md.nvram_read_val(addr);
++	return 0xff;
++}
++EXPORT_SYMBOL(nvram_read_byte);
++
++void nvram_write_byte(unsigned char val, int addr)
++{
++	if (ppc_md.nvram_write_val)
++		ppc_md.nvram_write_val(addr, val);
++}
++EXPORT_SYMBOL(nvram_write_byte);
++
++void nvram_sync(void)
++{
++	if (ppc_md.nvram_sync)
++		ppc_md.nvram_sync();
++}
++EXPORT_SYMBOL(nvram_sync);
++
++#endif /* CONFIG_NVRAM */
++
++static struct cpu cpu_devices[NR_CPUS];
++
++int __init ppc_init(void)
++{
++	int i;
++
++	/* clear the progress line */
++	if ( ppc_md.progress ) ppc_md.progress("             ", 0xffff);
++
++	/* register CPU devices */
++	for (i = 0; i < NR_CPUS; i++)
++		if (cpu_possible(i))
++			register_cpu(&cpu_devices[i], i, NULL);
++
++	/* call platform init */
++	if (ppc_md.init != NULL) {
++		ppc_md.init();
++	}
++	return 0;
++}
++
++arch_initcall(ppc_init);
++
++/* Warning, IO base is not yet inited */
++void __init setup_arch(char **cmdline_p)
++{
++	extern char *klimit;
++	extern void do_init_bootmem(void);
++
++	/* so udelay does something sensible, assume <= 1000 bogomips */
++	loops_per_jiffy = 500000000 / HZ;
++
++	unflatten_device_tree();
++	finish_device_tree();
++
++#ifdef CONFIG_BOOTX_TEXT
++	init_boot_display();
++#endif
++
++#ifdef CONFIG_PPC_PMAC
++	/* This could be called "early setup arch", it must be done
++	 * now because xmon need it
++	 */
++	if (_machine == _MACH_Pmac)
++		pmac_feature_init();	/* New cool way */
++#endif
++
++#ifdef CONFIG_XMON
++	xmon_map_scc();
++	if (strstr(cmd_line, "xmon")) {
++		xmon_init(1);
++		debugger(NULL);
++	}
++#endif /* CONFIG_XMON */
++	if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
++
++#if defined(CONFIG_KGDB)
++	if (ppc_md.kgdb_map_scc)
++		ppc_md.kgdb_map_scc();
++	set_debug_traps();
++	if (strstr(cmd_line, "gdb")) {
++		if (ppc_md.progress)
++			ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
++		printk("kgdb breakpoint activated\n");
++		breakpoint();
++	}
++#endif
++
++	/*
++	 * Set cache line size based on type of cpu as a default.
++	 * Systems with OF can look in the properties on the cpu node(s)
++	 * for a possibly more accurate value.
++	 */
++	if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
++		dcache_bsize = cur_cpu_spec->dcache_bsize;
++		icache_bsize = cur_cpu_spec->icache_bsize;
++		ucache_bsize = 0;
++	} else
++		ucache_bsize = dcache_bsize = icache_bsize
++			= cur_cpu_spec->dcache_bsize;
++
++	/* reboot on panic */
++	panic_timeout = 180;
++
++	init_mm.start_code = PAGE_OFFSET;
++	init_mm.end_code = (unsigned long) _etext;
++	init_mm.end_data = (unsigned long) _edata;
++	init_mm.brk = (unsigned long) klimit;
++
++	/* Save unparsed command line copy for /proc/cmdline */
++	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
++	*cmdline_p = cmd_line;
++
++	parse_early_param();
++
++	/* set up the bootmem stuff with available memory */
++	do_init_bootmem();
++	if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
++
++#ifdef CONFIG_PPC_OCP
++	/* Initialize OCP device list */
++	ocp_early_init();
++	if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
++#endif
++
++#ifdef CONFIG_DUMMY_CONSOLE
++	conswitchp = &dummy_con;
++#endif
++
++	ppc_md.setup_arch();
++	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
++
++	paging_init();
++
++	/* this is for modules since _machine can be a define -- Cort */
++	ppc_md.ppc_machine = _machine;
++}
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -0,0 +1,1028 @@
++/*
++ * 
++ * Common boot and setup code.
++ *
++ * Copyright (C) 2001 PPC64 Team, IBM Corp
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ */
++
++#undef DEBUG
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/sched.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/reboot.h>
++#include <linux/delay.h>
++#include <linux/initrd.h>
++#include <linux/ide.h>
++#include <linux/seq_file.h>
++#include <linux/ioport.h>
++#include <linux/console.h>
++#include <linux/utsname.h>
++#include <linux/tty.h>
++#include <linux/root_dev.h>
++#include <linux/notifier.h>
++#include <linux/cpu.h>
++#include <linux/unistd.h>
++#include <linux/serial.h>
++#include <linux/serial_8250.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/processor.h>
++#include <asm/pgtable.h>
++#include <asm/smp.h>
++#include <asm/elf.h>
++#include <asm/machdep.h>
++#include <asm/paca.h>
++#include <asm/ppcdebug.h>
++#include <asm/time.h>
++#include <asm/cputable.h>
++#include <asm/sections.h>
++#include <asm/btext.h>
++#include <asm/nvram.h>
++#include <asm/setup.h>
++#include <asm/system.h>
++#include <asm/rtas.h>
++#include <asm/iommu.h>
++#include <asm/serial.h>
++#include <asm/cache.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/lmb.h>
++#include <asm/iSeries/ItLpNaca.h>
++#include <asm/firmware.h>
++#include <asm/systemcfg.h>
++#include <asm/xmon.h>
++
++#ifdef DEBUG
++#define DBG(fmt...) udbg_printf(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++/*
++ * Here are some early debugging facilities. You can enable one
++ * but your kernel will not boot on anything else if you do so
++ */
++
++/* This one is for use on LPAR machines that support an HVC console
++ * on vterm 0
++ */
++extern void udbg_init_debug_lpar(void);
++/* This one is for use on Apple G5 machines
++ */
++extern void udbg_init_pmac_realmode(void);
++/* That's RTAS panel debug */
++extern void call_rtas_display_status_delay(unsigned char c);
++/* Here's maple real mode debug */
++extern void udbg_init_maple_realmode(void);
++
++#define EARLY_DEBUG_INIT() do {} while(0)
++
++#if 0
++#define EARLY_DEBUG_INIT() udbg_init_debug_lpar()
++#define EARLY_DEBUG_INIT() udbg_init_maple_realmode()
++#define EARLY_DEBUG_INIT() udbg_init_pmac_realmode()
++#define EARLY_DEBUG_INIT()						\
++	do { udbg_putc = call_rtas_display_status_delay; } while(0)
++#endif
++
++/* extern void *stab; */
++extern unsigned long klimit;
++
++extern void mm_init_ppc64(void);
++extern void stab_initialize(unsigned long stab);
++extern void htab_initialize(void);
++extern void early_init_devtree(void *flat_dt);
++extern void unflatten_device_tree(void);
++
++extern void smp_release_cpus(void);
++
++int have_of = 1;
++int boot_cpuid = 0;
++int boot_cpuid_phys = 0;
++dev_t boot_dev;
++u64 ppc64_pft_size;
++
++struct ppc64_caches ppc64_caches;
++EXPORT_SYMBOL_GPL(ppc64_caches);
++
++/*
++ * These are used in binfmt_elf.c to put aux entries on the stack
++ * for each elf executable being started.
++ */
++int dcache_bsize;
++int icache_bsize;
++int ucache_bsize;
++
++/* The main machine-dep calls structure
++ */
++struct machdep_calls ppc_md;
++EXPORT_SYMBOL(ppc_md);
++
++#ifdef CONFIG_MAGIC_SYSRQ
++unsigned long SYSRQ_KEY;
++#endif /* CONFIG_MAGIC_SYSRQ */
++
++
++static int ppc64_panic_event(struct notifier_block *, unsigned long, void *);
++static struct notifier_block ppc64_panic_block = {
++	.notifier_call = ppc64_panic_event,
++	.priority = INT_MIN /* may not return; must be done last */
++};
++
++#ifdef CONFIG_SMP
++
++static int smt_enabled_cmdline;
++
++/* Look for ibm,smt-enabled OF option */
++static void check_smt_enabled(void)
++{
++	struct device_node *dn;
++	char *smt_option;
++
++	/* Allow the command line to overrule the OF option */
++	if (smt_enabled_cmdline)
++		return;
++
++	dn = of_find_node_by_path("/options");
++
++	if (dn) {
++		smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL);
++
++                if (smt_option) {
++			if (!strcmp(smt_option, "on"))
++				smt_enabled_at_boot = 1;
++			else if (!strcmp(smt_option, "off"))
++				smt_enabled_at_boot = 0;
++                }
++        }
++}
++
++/* Look for smt-enabled= cmdline option */
++static int __init early_smt_enabled(char *p)
++{
++	smt_enabled_cmdline = 1;
++
++	if (!p)
++		return 0;
++
++	if (!strcmp(p, "on") || !strcmp(p, "1"))
++		smt_enabled_at_boot = 1;
++	else if (!strcmp(p, "off") || !strcmp(p, "0"))
++		smt_enabled_at_boot = 0;
++
++	return 0;
++}
++early_param("smt-enabled", early_smt_enabled);
++
++/**
++ * setup_cpu_maps - initialize the following cpu maps:
++ *                  cpu_possible_map
++ *                  cpu_present_map
++ *                  cpu_sibling_map
++ *
++ * Having the possible map set up early allows us to restrict allocations
++ * of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
++ *
++ * We do not initialize the online map here; cpus set their own bits in
++ * cpu_online_map as they come up.
++ *
++ * This function is valid only for Open Firmware systems.  finish_device_tree
++ * must be called before using this.
++ *
++ * While we're here, we may as well set the "physical" cpu ids in the paca.
++ */
++static void __init setup_cpu_maps(void)
++{
++	struct device_node *dn = NULL;
++	int cpu = 0;
++	int swap_cpuid = 0;
++
++	check_smt_enabled();
++
++	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
++		u32 *intserv;
++		int j, len = sizeof(u32), nthreads;
++
++		intserv = (u32 *)get_property(dn, "ibm,ppc-interrupt-server#s",
++					      &len);
++		if (!intserv)
++			intserv = (u32 *)get_property(dn, "reg", NULL);
++
++		nthreads = len / sizeof(u32);
++
++		for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
++			cpu_set(cpu, cpu_present_map);
++			set_hard_smp_processor_id(cpu, intserv[j]);
++
++			if (intserv[j] == boot_cpuid_phys)
++				swap_cpuid = cpu;
++			cpu_set(cpu, cpu_possible_map);
++			cpu++;
++		}
++	}
++
++	/* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
++	 * boot cpu is logical 0.
++	 */
++	if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
++		u32 tmp;
++		tmp = get_hard_smp_processor_id(0);
++		set_hard_smp_processor_id(0, boot_cpuid_phys);
++		set_hard_smp_processor_id(swap_cpuid, tmp);
++	}
++
++	/*
++	 * On pSeries LPAR, we need to know how many cpus
++	 * could possibly be added to this partition.
++	 */
++	if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
++				(dn = of_find_node_by_path("/rtas"))) {
++		int num_addr_cell, num_size_cell, maxcpus;
++		unsigned int *ireg;
++
++		num_addr_cell = prom_n_addr_cells(dn);
++		num_size_cell = prom_n_size_cells(dn);
++
++		ireg = (unsigned int *)
++			get_property(dn, "ibm,lrdr-capacity", NULL);
++
++		if (!ireg)
++			goto out;
++
++		maxcpus = ireg[num_addr_cell + num_size_cell];
++
++		/* Double maxcpus for processors which have SMT capability */
++		if (cpu_has_feature(CPU_FTR_SMT))
++			maxcpus *= 2;
++
++		if (maxcpus > NR_CPUS) {
++			printk(KERN_WARNING
++			       "Partition configured for %d cpus, "
++			       "operating system maximum is %d.\n",
++			       maxcpus, NR_CPUS);
++			maxcpus = NR_CPUS;
++		} else
++			printk(KERN_INFO "Partition configured for %d cpus.\n",
++			       maxcpus);
++
++		for (cpu = 0; cpu < maxcpus; cpu++)
++			cpu_set(cpu, cpu_possible_map);
++	out:
++		of_node_put(dn);
++	}
++
++	/*
++	 * Do the sibling map; assume only two threads per processor.
++	 */
++	for_each_cpu(cpu) {
++		cpu_set(cpu, cpu_sibling_map[cpu]);
++		if (cpu_has_feature(CPU_FTR_SMT))
++			cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
++	}
++
++	systemcfg->processorCount = num_present_cpus();
++}
++#endif /* CONFIG_SMP */
++
++extern struct machdep_calls pSeries_md;
++extern struct machdep_calls pmac_md;
++extern struct machdep_calls maple_md;
++extern struct machdep_calls bpa_md;
++extern struct machdep_calls iseries_md;
++
++/* Ultimately, stuff them in an elf section like initcalls... */
++static struct machdep_calls __initdata *machines[] = {
++#ifdef CONFIG_PPC_PSERIES
++	&pSeries_md,
++#endif /* CONFIG_PPC_PSERIES */
++#ifdef CONFIG_PPC_PMAC
++	&pmac_md,
++#endif /* CONFIG_PPC_PMAC */
++#ifdef CONFIG_PPC_MAPLE
++	&maple_md,
++#endif /* CONFIG_PPC_MAPLE */
++#ifdef CONFIG_PPC_BPA
++	&bpa_md,
++#endif
++#ifdef CONFIG_PPC_ISERIES
++	&iseries_md,
++#endif
++	NULL
++};
++
++/*
++ * Early initialization entry point. This is called by head.S
++ * with MMU translation disabled. We rely on the "feature" of
++ * the CPU that ignores the top 2 bits of the address in real
++ * mode so we can access kernel globals normally provided we
++ * only toy with things in the RMO region. From here, we do
++ * some early parsing of the device-tree to setup out LMB
++ * data structures, and allocate & initialize the hash table
++ * and segment tables so we can start running with translation
++ * enabled.
++ *
++ * It is this function which will call the probe() callback of
++ * the various platform types and copy the matching one to the
++ * global ppc_md structure. Your platform can eventually do
++ * some very early initializations from the probe() routine, but
++ * this is not recommended, be very careful as, for example, the
++ * device-tree is not accessible via normal means at this point.
++ */
++
++void __init early_setup(unsigned long dt_ptr)
++{
++	struct paca_struct *lpaca = get_paca();
++	static struct machdep_calls **mach;
++
++	/*
++	 * Enable early debugging if any specified (see top of
++	 * this file)
++	 */
++	EARLY_DEBUG_INIT();
++
++	DBG(" -> early_setup()\n");
++
++	/*
++	 * Fill the default DBG level (do we want to keep
++	 * that old mecanism around forever ?)
++	 */
++	ppcdbg_initialize();
++
++	/*
++	 * Do early initializations using the flattened device
++	 * tree, like retreiving the physical memory map or
++	 * calculating/retreiving the hash table size
++	 */
++	early_init_devtree(__va(dt_ptr));
++
++	/*
++	 * Iterate all ppc_md structures until we find the proper
++	 * one for the current machine type
++	 */
++	DBG("Probing machine type for platform %x...\n",
++	    systemcfg->platform);
++
++	for (mach = machines; *mach; mach++) {
++		if ((*mach)->probe(systemcfg->platform))
++			break;
++	}
++	/* What can we do if we didn't find ? */
++	if (*mach == NULL) {
++		DBG("No suitable machine found !\n");
++		for (;;);
++	}
++	ppc_md = **mach;
++
++	DBG("Found, Initializing memory management...\n");
++
++	/*
++	 * Initialize stab / SLB management
++	 */
++	if (!firmware_has_feature(FW_FEATURE_ISERIES))
++		stab_initialize(lpaca->stab_real);
++
++	/*
++	 * Initialize the MMU Hash table and create the linear mapping
++	 * of memory
++	 */
++	htab_initialize();
++
++	DBG(" <- early_setup()\n");
++}
++
++
++/*
++ * Initialize some remaining members of the ppc64_caches and systemcfg structures
++ * (at least until we get rid of them completely). This is mostly some
++ * cache informations about the CPU that will be used by cache flush
++ * routines and/or provided to userland
++ */
++static void __init initialize_cache_info(void)
++{
++	struct device_node *np;
++	unsigned long num_cpus = 0;
++
++	DBG(" -> initialize_cache_info()\n");
++
++	for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) {
++		num_cpus += 1;
++
++		/* We're assuming *all* of the CPUs have the same
++		 * d-cache and i-cache sizes... -Peter
++		 */
++
++		if ( num_cpus == 1 ) {
++			u32 *sizep, *lsizep;
++			u32 size, lsize;
++			const char *dc, *ic;
++
++			/* Then read cache informations */
++			if (systemcfg->platform == PLATFORM_POWERMAC) {
++				dc = "d-cache-block-size";
++				ic = "i-cache-block-size";
++			} else {
++				dc = "d-cache-line-size";
++				ic = "i-cache-line-size";
++			}
++
++			size = 0;
++			lsize = cur_cpu_spec->dcache_bsize;
++			sizep = (u32 *)get_property(np, "d-cache-size", NULL);
++			if (sizep != NULL)
++				size = *sizep;
++			lsizep = (u32 *) get_property(np, dc, NULL);
++			if (lsizep != NULL)
++				lsize = *lsizep;
++			if (sizep == 0 || lsizep == 0)
++				DBG("Argh, can't find dcache properties ! "
++				    "sizep: %p, lsizep: %p\n", sizep, lsizep);
++
++			systemcfg->dcache_size = ppc64_caches.dsize = size;
++			systemcfg->dcache_line_size =
++				ppc64_caches.dline_size = lsize;
++			ppc64_caches.log_dline_size = __ilog2(lsize);
++			ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
++
++			size = 0;
++			lsize = cur_cpu_spec->icache_bsize;
++			sizep = (u32 *)get_property(np, "i-cache-size", NULL);
++			if (sizep != NULL)
++				size = *sizep;
++			lsizep = (u32 *)get_property(np, ic, NULL);
++			if (lsizep != NULL)
++				lsize = *lsizep;
++			if (sizep == 0 || lsizep == 0)
++				DBG("Argh, can't find icache properties ! "
++				    "sizep: %p, lsizep: %p\n", sizep, lsizep);
++
++			systemcfg->icache_size = ppc64_caches.isize = size;
++			systemcfg->icache_line_size =
++				ppc64_caches.iline_size = lsize;
++			ppc64_caches.log_iline_size = __ilog2(lsize);
++			ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
++		}
++	}
++
++	/* Add an eye catcher and the systemcfg layout version number */
++	strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
++	systemcfg->version.major = SYSTEMCFG_MAJOR;
++	systemcfg->version.minor = SYSTEMCFG_MINOR;
++	systemcfg->processor = mfspr(SPRN_PVR);
++
++	DBG(" <- initialize_cache_info()\n");
++}
++
++static void __init check_for_initrd(void)
++{
++#ifdef CONFIG_BLK_DEV_INITRD
++	u64 *prop;
++
++	DBG(" -> check_for_initrd()\n");
++
++	if (of_chosen) {
++		prop = (u64 *)get_property(of_chosen,
++				"linux,initrd-start", NULL);
++		if (prop != NULL) {
++			initrd_start = (unsigned long)__va(*prop);
++			prop = (u64 *)get_property(of_chosen,
++					"linux,initrd-end", NULL);
++			if (prop != NULL) {
++				initrd_end = (unsigned long)__va(*prop);
++				initrd_below_start_ok = 1;
++			} else
++				initrd_start = 0;
++		}
++	}
++
++	/* If we were passed an initrd, set the ROOT_DEV properly if the values
++	 * look sensible. If not, clear initrd reference.
++	 */
++	if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
++	    initrd_end > initrd_start)
++		ROOT_DEV = Root_RAM0;
++	else
++		initrd_start = initrd_end = 0;
++
++	if (initrd_start)
++		printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end);
++
++	DBG(" <- check_for_initrd()\n");
++#endif /* CONFIG_BLK_DEV_INITRD */
++}
++
++/*
++ * Do some initial setup of the system.  The parameters are those which 
++ * were passed in from the bootloader.
++ */
++void __init setup_system(void)
++{
++	DBG(" -> setup_system()\n");
++
++	/*
++	 * Unflatten the device-tree passed by prom_init or kexec
++	 */
++	unflatten_device_tree();
++
++	/*
++	 * Fill the ppc64_caches & systemcfg structures with informations
++	 * retreived from the device-tree. Need to be called before
++	 * finish_device_tree() since the later requires some of the
++	 * informations filled up here to properly parse the interrupt
++	 * tree.
++	 * It also sets up the cache line sizes which allows to call
++	 * routines like flush_icache_range (used by the hash init
++	 * later on).
++	 */
++	initialize_cache_info();
++
++#ifdef CONFIG_PPC_RTAS
++	/*
++	 * Initialize RTAS if available
++	 */
++	rtas_initialize();
++#endif /* CONFIG_PPC_RTAS */
++
++	/*
++	 * Check if we have an initrd provided via the device-tree
++	 */
++	check_for_initrd();
++
++	/*
++	 * Do some platform specific early initializations, that includes
++	 * setting up the hash table pointers. It also sets up some interrupt-mapping
++	 * related options that will be used by finish_device_tree()
++	 */
++	ppc_md.init_early();
++
++	/*
++	 * "Finish" the device-tree, that is do the actual parsing of
++	 * some of the properties like the interrupt map
++	 */
++	finish_device_tree();
++
++#ifdef CONFIG_BOOTX_TEXT
++	init_boot_display();
++#endif
++
++	/*
++	 * Initialize xmon
++	 */
++#ifdef CONFIG_XMON_DEFAULT
++	xmon_init(1);
++#endif
++	/*
++	 * Register early console
++	 */
++	register_early_udbg_console();
++
++	/* Save unparsed command line copy for /proc/cmdline */
++	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
++
++	parse_early_param();
++
++#ifdef CONFIG_SMP
++	/*
++	 * iSeries has already initialized the cpu maps at this point.
++	 */
++	setup_cpu_maps();
++
++	/* Release secondary cpus out of their spinloops at 0x60 now that
++	 * we can map physical -> logical CPU ids
++	 */
++	smp_release_cpus();
++#endif
++
++	printk("Starting Linux PPC64 %s\n", system_utsname.version);
++
++	printk("-----------------------------------------------------\n");
++	printk("ppc64_pft_size                = 0x%lx\n", ppc64_pft_size);
++	printk("ppc64_debug_switch            = 0x%lx\n", ppc64_debug_switch);
++	printk("ppc64_interrupt_controller    = 0x%ld\n", ppc64_interrupt_controller);
++	printk("systemcfg                     = 0x%p\n", systemcfg);
++	printk("systemcfg->platform           = 0x%x\n", systemcfg->platform);
++	printk("systemcfg->processorCount     = 0x%lx\n", systemcfg->processorCount);
++	printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
++	printk("ppc64_caches.dcache_line_size = 0x%x\n",
++			ppc64_caches.dline_size);
++	printk("ppc64_caches.icache_line_size = 0x%x\n",
++			ppc64_caches.iline_size);
++	printk("htab_address                  = 0x%p\n", htab_address);
++	printk("htab_hash_mask                = 0x%lx\n", htab_hash_mask);
++	printk("-----------------------------------------------------\n");
++
++	mm_init_ppc64();
++
++	DBG(" <- setup_system()\n");
++}
++
++static int ppc64_panic_event(struct notifier_block *this,
++                             unsigned long event, void *ptr)
++{
++	ppc_md.panic((char *)ptr);  /* May not return */
++	return NOTIFY_DONE;
++}
++
++#ifdef CONFIG_PPC_ISERIES
++/*
++ * On iSeries we just parse the mem=X option from the command line.
++ * On pSeries it's a bit more complicated, see prom_init_mem()
++ */
++static int __init early_parsemem(char *p)
++{
++	if (!p)
++		return 0;
++
++	memory_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
++
++	return 0;
++}
++early_param("mem", early_parsemem);
++#endif /* CONFIG_PPC_ISERIES */
++
++#ifdef CONFIG_IRQSTACKS
++static void __init irqstack_early_init(void)
++{
++	unsigned int i;
++
++	/*
++	 * interrupt stacks must be under 256MB, we cannot afford to take
++	 * SLB misses on them.
++	 */
++	for_each_cpu(i) {
++		softirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
++					THREAD_SIZE, 0x10000000));
++		hardirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
++					THREAD_SIZE, 0x10000000));
++	}
++}
++#else
++#define irqstack_early_init()
++#endif
++
++/*
++ * Stack space used when we detect a bad kernel stack pointer, and
++ * early in SMP boots before relocation is enabled.
++ */
++static void __init emergency_stack_init(void)
++{
++	unsigned long limit;
++	unsigned int i;
++
++	/*
++	 * Emergency stacks must be under 256MB, we cannot afford to take
++	 * SLB misses on them. The ABI also requires them to be 128-byte
++	 * aligned.
++	 *
++	 * Since we use these as temporary stacks during secondary CPU
++	 * bringup, we need to get at them in real mode. This means they
++	 * must also be within the RMO region.
++	 */
++	limit = min(0x10000000UL, lmb.rmo_size);
++
++	for_each_cpu(i)
++		paca[i].emergency_sp = __va(lmb_alloc_base(PAGE_SIZE, 128,
++						limit)) + PAGE_SIZE;
++}
++
++/*
++ * Called from setup_arch to initialize the bitmap of available
++ * syscalls in the systemcfg page
++ */
++void __init setup_syscall_map(void)
++{
++	unsigned int i, count64 = 0, count32 = 0;
++	extern unsigned long *sys_call_table;
++	extern unsigned long sys_ni_syscall;
++
++
++	for (i = 0; i < __NR_syscalls; i++) {
++		if (sys_call_table[i*2] != sys_ni_syscall) {
++			count64++;
++			systemcfg->syscall_map_64[i >> 5] |=
++				0x80000000UL >> (i & 0x1f);
++		}
++		if (sys_call_table[i*2+1] != sys_ni_syscall) {
++			count32++;
++			systemcfg->syscall_map_32[i >> 5] |=
++				0x80000000UL >> (i & 0x1f);
++		}
++	}
++	printk(KERN_INFO "Syscall map setup, %d 32-bit and %d 64-bit syscalls\n",
++	       count32, count64);
++}
++
++/*
++ * Called into from start_kernel, after lock_kernel has been called.
++ * Initializes bootmem, which is unsed to manage page allocation until
++ * mem_init is called.
++ */
++void __init setup_arch(char **cmdline_p)
++{
++	extern void do_init_bootmem(void);
++
++	ppc64_boot_msg(0x12, "Setup Arch");
++
++	*cmdline_p = cmd_line;
++
++	/*
++	 * Set cache line size based on type of cpu as a default.
++	 * Systems with OF can look in the properties on the cpu node(s)
++	 * for a possibly more accurate value.
++	 */
++	dcache_bsize = ppc64_caches.dline_size;
++	icache_bsize = ppc64_caches.iline_size;
++
++	/* reboot on panic */
++	panic_timeout = 180;
++
++	if (ppc_md.panic)
++		notifier_chain_register(&panic_notifier_list, &ppc64_panic_block);
++
++	init_mm.start_code = PAGE_OFFSET;
++	init_mm.end_code = (unsigned long) _etext;
++	init_mm.end_data = (unsigned long) _edata;
++	init_mm.brk = klimit;
++	
++	irqstack_early_init();
++	emergency_stack_init();
++
++	stabs_alloc();
++
++	/* set up the bootmem stuff with available memory */
++	do_init_bootmem();
++	sparse_init();
++
++	/* initialize the syscall map in systemcfg */
++	setup_syscall_map();
++
++#ifdef CONFIG_DUMMY_CONSOLE
++	conswitchp = &dummy_con;
++#endif
++
++	ppc_md.setup_arch();
++
++	/* Use the default idle loop if the platform hasn't provided one. */
++	if (NULL == ppc_md.idle_loop) {
++		ppc_md.idle_loop = default_idle;
++		printk(KERN_INFO "Using default idle loop\n");
++	}
++
++	paging_init();
++	ppc64_boot_msg(0x15, "Setup Done");
++}
++
++
++/* ToDo: do something useful if ppc_md is not yet setup. */
++#define PPC64_LINUX_FUNCTION 0x0f000000
++#define PPC64_IPL_MESSAGE 0xc0000000
++#define PPC64_TERM_MESSAGE 0xb0000000
++
++static void ppc64_do_msg(unsigned int src, const char *msg)
++{
++	if (ppc_md.progress) {
++		char buf[128];
++
++		sprintf(buf, "%08X\n", src);
++		ppc_md.progress(buf, 0);
++		snprintf(buf, 128, "%s", msg);
++		ppc_md.progress(buf, 0);
++	}
++}
++
++/* Print a boot progress message. */
++void ppc64_boot_msg(unsigned int src, const char *msg)
++{
++	ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg);
++	printk("[boot]%04x %s\n", src, msg);
++}
++
++/* Print a termination message (print only -- does not stop the kernel) */
++void ppc64_terminate_msg(unsigned int src, const char *msg)
++{
++	ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg);
++	printk("[terminate]%04x %s\n", src, msg);
++}
++
++#ifndef CONFIG_PPC_ISERIES
++/*
++ * This function can be used by platforms to "find" legacy serial ports.
++ * It works for "serial" nodes under an "isa" node, and will try to
++ * respect the "ibm,aix-loc" property if any. It works with up to 8
++ * ports.
++ */
++
++#define MAX_LEGACY_SERIAL_PORTS	8
++static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
++static unsigned int old_serial_count;
++
++void __init generic_find_legacy_serial_ports(u64 *physport,
++		unsigned int *default_speed)
++{
++	struct device_node *np;
++	u32 *sizeprop;
++
++	struct isa_reg_property {
++		u32 space;
++		u32 address;
++		u32 size;
++	};
++	struct pci_reg_property {
++		struct pci_address addr;
++		u32 size_hi;
++		u32 size_lo;
++	};                                                                        
++
++	DBG(" -> generic_find_legacy_serial_port()\n");
++
++	*physport = 0;
++	if (default_speed)
++		*default_speed = 0;
++
++	np = of_find_node_by_path("/");
++	if (!np)
++		return;
++
++	/* First fill our array */
++	for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
++		struct device_node *isa, *pci;
++		struct isa_reg_property *reg;
++		unsigned long phys_size, addr_size, io_base;
++		u32 *rangesp;
++		u32 *interrupts, *clk, *spd;
++		char *typep;
++		int index, rlen, rentsize;
++
++		/* Ok, first check if it's under an "isa" parent */
++		isa = of_get_parent(np);
++		if (!isa || strcmp(isa->name, "isa")) {
++			DBG("%s: no isa parent found\n", np->full_name);
++			continue;
++		}
++		
++		/* Now look for an "ibm,aix-loc" property that gives us ordering
++		 * if any...
++		 */
++	 	typep = (char *)get_property(np, "ibm,aix-loc", NULL);
++
++		/* Get the ISA port number */
++		reg = (struct isa_reg_property *)get_property(np, "reg", NULL);	
++		if (reg == NULL)
++			goto next_port;
++		/* We assume the interrupt number isn't translated ... */
++		interrupts = (u32 *)get_property(np, "interrupts", NULL);
++		/* get clock freq. if present */
++		clk = (u32 *)get_property(np, "clock-frequency", NULL);
++		/* get default speed if present */
++		spd = (u32 *)get_property(np, "current-speed", NULL);
++		/* Default to locate at end of array */
++		index = old_serial_count; /* end of the array by default */
++
++		/* If we have a location index, then use it */
++		if (typep && *typep == 'S') {
++			index = simple_strtol(typep+1, NULL, 0) - 1;
++			/* if index is out of range, use end of array instead */
++			if (index >= MAX_LEGACY_SERIAL_PORTS)
++				index = old_serial_count;
++			/* if our index is still out of range, that mean that
++			 * array is full, we could scan for a free slot but that
++			 * make little sense to bother, just skip the port
++			 */
++			if (index >= MAX_LEGACY_SERIAL_PORTS)
++				goto next_port;
++			if (index >= old_serial_count)
++				old_serial_count = index + 1;
++			/* Check if there is a port who already claimed our slot */
++			if (serial_ports[index].iobase != 0) {
++				/* if we still have some room, move it, else override */
++				if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
++					DBG("Moved legacy port %d -> %d\n", index,
++					    old_serial_count);
++					serial_ports[old_serial_count++] =
++						serial_ports[index];
++				} else {
++					DBG("Replacing legacy port %d\n", index);
++				}
++			}
++		}
++		if (index >= MAX_LEGACY_SERIAL_PORTS)
++			goto next_port;
++		if (index >= old_serial_count)
++			old_serial_count = index + 1;
++
++		/* Now fill the entry */
++		memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port));
++		serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16;
++		serial_ports[index].iobase = reg->address;
++		serial_ports[index].irq = interrupts ? interrupts[0] : 0;
++		serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
++
++		DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
++		    index,
++		    serial_ports[index].iobase,
++		    serial_ports[index].irq,
++		    serial_ports[index].uartclk);
++
++		/* Get phys address of IO reg for port 1 */
++		if (index != 0)
++			goto next_port;
++
++		pci = of_get_parent(isa);
++		if (!pci) {
++			DBG("%s: no pci parent found\n", np->full_name);
++			goto next_port;
++		}
++
++		rangesp = (u32 *)get_property(pci, "ranges", &rlen);
++		if (rangesp == NULL) {
++			of_node_put(pci);
++			goto next_port;
++		}
++		rlen /= 4;
++
++		/* we need the #size-cells of the PCI bridge node itself */
++		phys_size = 1;
++		sizeprop = (u32 *)get_property(pci, "#size-cells", NULL);
++		if (sizeprop != NULL)
++			phys_size = *sizeprop;
++		/* we need the parent #addr-cells */
++		addr_size = prom_n_addr_cells(pci);
++		rentsize = 3 + addr_size + phys_size;
++		io_base = 0;
++		for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) {
++			if (((rangesp[0] >> 24) & 0x3) != 1)
++				continue; /* not IO space */
++			io_base = rangesp[3];
++			if (addr_size == 2)
++				io_base = (io_base << 32) | rangesp[4];
++		}
++		if (io_base != 0) {
++			*physport = io_base + reg->address;
++			if (default_speed && spd)
++				*default_speed = *spd;
++		}
++		of_node_put(pci);
++	next_port:
++		of_node_put(isa);
++	}
++
++	DBG(" <- generic_find_legacy_serial_port()\n");
++}
++
++static struct platform_device serial_device = {
++	.name	= "serial8250",
++	.id	= PLAT8250_DEV_PLATFORM,
++	.dev	= {
++		.platform_data = serial_ports,
++	},
++};
++
++static int __init serial_dev_init(void)
++{
++	return platform_device_register(&serial_device);
++}
++arch_initcall(serial_dev_init);
++
++#endif /* CONFIG_PPC_ISERIES */
++
++int check_legacy_ioport(unsigned long base_port)
++{
++	if (ppc_md.check_legacy_ioport == NULL)
++		return 0;
++	return ppc_md.check_legacy_ioport(base_port);
++}
++EXPORT_SYMBOL(check_legacy_ioport);
++
++#ifdef CONFIG_XMON
++static int __init early_xmon(char *p)
++{
++	/* ensure xmon is enabled */
++	if (p) {
++		if (strncmp(p, "on", 2) == 0)
++			xmon_init(1);
++		if (strncmp(p, "off", 3) == 0)
++			xmon_init(0);
++		if (strncmp(p, "early", 5) != 0)
++			return 0;
++	}
++	xmon_init(1);
++	debugger(NULL);
++
++	return 0;
++}
++early_param("xmon", early_xmon);
++#endif
++
++void cpu_die(void)
++{
++	if (ppc_md.cpu_die)
++		ppc_md.cpu_die();
++}
+diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -0,0 +1,1269 @@
++/*
++ * Signal handling for 32bit PPC and 32bit tasks on 64bit PPC
++ *
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ * Copyright (C) 2001 IBM
++ * Copyright (C) 1997,1998 Jakub Jelinek (jj at sunsite.mff.cuni.cz)
++ * Copyright (C) 1997 David S. Miller (davem at caip.rutgers.edu)
++ *
++ *  Derived from "arch/i386/kernel/signal.c"
++ *    Copyright (C) 1991, 1992 Linus Torvalds
++ *    1997-11-28  Modified for POSIX.1b signals by Richard Henderson
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/sched.h>
++#include <linux/mm.h>
++#include <linux/smp.h>
++#include <linux/smp_lock.h>
++#include <linux/kernel.h>
++#include <linux/signal.h>
++#include <linux/errno.h>
++#include <linux/elf.h>
++#ifdef CONFIG_PPC64
++#include <linux/syscalls.h>
++#include <linux/compat.h>
++#include <linux/ptrace.h>
++#else
++#include <linux/wait.h>
++#include <linux/ptrace.h>
++#include <linux/unistd.h>
++#include <linux/stddef.h>
++#include <linux/tty.h>
++#include <linux/binfmts.h>
++#include <linux/suspend.h>
++#endif
++
++#include <asm/uaccess.h>
++#include <asm/cacheflush.h>
++#ifdef CONFIG_PPC64
++#include <asm/ppc32.h>
++#include <asm/ppcdebug.h>
++#include <asm/unistd.h>
++#include <asm/vdso.h>
++#else
++#include <asm/ucontext.h>
++#include <asm/pgtable.h>
++#endif
++
++#undef DEBUG_SIG
++
++#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
++
++#ifdef CONFIG_PPC64
++#define do_signal	do_signal32
++#define sys_sigsuspend	compat_sys_sigsuspend
++#define sys_rt_sigsuspend	compat_sys_rt_sigsuspend
++#define sys_rt_sigreturn	compat_sys_rt_sigreturn
++#define sys_sigaction	compat_sys_sigaction
++#define sys_swapcontext	compat_sys_swapcontext
++#define sys_sigreturn	compat_sys_sigreturn
++
++#define old_sigaction	old_sigaction32
++#define sigcontext	sigcontext32
++#define mcontext	mcontext32
++#define ucontext	ucontext32
++
++/*
++ * Returning 0 means we return to userspace via
++ * ret_from_except and thus restore all user
++ * registers from *regs.  This is what we need
++ * to do when a signal has been delivered.
++ */
++#define sigreturn_exit(regs)	return 0
++
++#define GP_REGS_SIZE	min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
++#undef __SIGNAL_FRAMESIZE
++#define __SIGNAL_FRAMESIZE	__SIGNAL_FRAMESIZE32
++#undef ELF_NVRREG
++#define ELF_NVRREG	ELF_NVRREG32
++
++/*
++ * Functions for flipping sigsets (thanks to brain dead generic
++ * implementation that makes things simple for little endian only)
++ */
++static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
++{
++	compat_sigset_t	cset;
++
++	switch (_NSIG_WORDS) {
++	case 4: cset.sig[5] = set->sig[3] & 0xffffffffull;
++		cset.sig[7] = set->sig[3] >> 32;
++	case 3: cset.sig[4] = set->sig[2] & 0xffffffffull;
++		cset.sig[5] = set->sig[2] >> 32;
++	case 2: cset.sig[2] = set->sig[1] & 0xffffffffull;
++		cset.sig[3] = set->sig[1] >> 32;
++	case 1: cset.sig[0] = set->sig[0] & 0xffffffffull;
++		cset.sig[1] = set->sig[0] >> 32;
++	}
++	return copy_to_user(uset, &cset, sizeof(*uset));
++}
++
++static inline int get_sigset_t(sigset_t *set,
++			       const compat_sigset_t __user *uset)
++{
++	compat_sigset_t s32;
++
++	if (copy_from_user(&s32, uset, sizeof(*uset)))
++		return -EFAULT;
++
++	/*
++	 * Swap the 2 words of the 64-bit sigset_t (they are stored
++	 * in the "wrong" endian in 32-bit user storage).
++	 */
++	switch (_NSIG_WORDS) {
++	case 4: set->sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
++	case 3: set->sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
++	case 2: set->sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
++	case 1: set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
++	}
++	return 0;
++}
++
++static inline int get_old_sigaction(struct k_sigaction *new_ka,
++		struct old_sigaction __user *act)
++{
++	compat_old_sigset_t mask;
++	compat_uptr_t handler, restorer;
++
++	if (get_user(handler, &act->sa_handler) ||
++	    __get_user(restorer, &act->sa_restorer) ||
++	    __get_user(new_ka->sa.sa_flags, &act->sa_flags) ||
++	    __get_user(mask, &act->sa_mask))
++		return -EFAULT;
++	new_ka->sa.sa_handler = compat_ptr(handler);
++	new_ka->sa.sa_restorer = compat_ptr(restorer);
++	siginitset(&new_ka->sa.sa_mask, mask);
++	return 0;
++}
++
++static inline compat_uptr_t to_user_ptr(void *kp)
++{
++	return (compat_uptr_t)(u64)kp;
++}
++
++#define from_user_ptr(p)	compat_ptr(p)
++
++static inline int save_general_regs(struct pt_regs *regs,
++		struct mcontext __user *frame)
++{
++	elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
++	int i;
++
++	for (i = 0; i <= PT_RESULT; i ++)
++		if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
++			return -EFAULT;
++	return 0;
++}
++
++static inline int restore_general_regs(struct pt_regs *regs,
++		struct mcontext __user *sr)
++{
++	elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
++	int i;
++
++	for (i = 0; i <= PT_RESULT; i++) {
++		if ((i == PT_MSR) || (i == PT_SOFTE))
++			continue;
++		if (__get_user(gregs[i], &sr->mc_gregs[i]))
++			return -EFAULT;
++	}
++	return 0;
++}
++
++#else /* CONFIG_PPC64 */
++
++extern void sigreturn_exit(struct pt_regs *);
++
++#define GP_REGS_SIZE	min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
++
++static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
++{
++	return copy_to_user(uset, set, sizeof(*uset));
++}
++
++static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset)
++{
++	return copy_from_user(set, uset, sizeof(*uset));
++}
++
++static inline int get_old_sigaction(struct k_sigaction *new_ka,
++		struct old_sigaction __user *act)
++{
++	old_sigset_t mask;
++
++	if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
++			__get_user(new_ka->sa.sa_handler, &act->sa_handler) ||
++			__get_user(new_ka->sa.sa_restorer, &act->sa_restorer))
++		return -EFAULT;
++	__get_user(new_ka->sa.sa_flags, &act->sa_flags);
++	__get_user(mask, &act->sa_mask);
++	siginitset(&new_ka->sa.sa_mask, mask);
++	return 0;
++}
++
++#define to_user_ptr(p)		(p)
++#define from_user_ptr(p)	(p)
++
++static inline int save_general_regs(struct pt_regs *regs,
++		struct mcontext __user *frame)
++{
++	return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
++}
++
++static inline int restore_general_regs(struct pt_regs *regs,
++		struct mcontext __user *sr)
++{
++	/* copy up to but not including MSR */
++	if (__copy_from_user(regs, &sr->mc_gregs,
++				PT_MSR * sizeof(elf_greg_t)))
++		return -EFAULT;
++	/* copy from orig_r3 (the word after the MSR) up to the end */
++	if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
++				GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
++		return -EFAULT;
++	return 0;
++}
++
++#endif /* CONFIG_PPC64 */
++
++int do_signal(sigset_t *oldset, struct pt_regs *regs);
++
++/*
++ * Atomically swap in the new signal mask, and wait for a signal.
++ */
++long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
++	       struct pt_regs *regs)
++{
++	sigset_t saveset;
++
++	mask &= _BLOCKABLE;
++	spin_lock_irq(&current->sighand->siglock);
++	saveset = current->blocked;
++	siginitset(&current->blocked, mask);
++	recalc_sigpending();
++	spin_unlock_irq(&current->sighand->siglock);
++
++	regs->result = -EINTR;
++	regs->gpr[3] = EINTR;
++	regs->ccr |= 0x10000000;
++	while (1) {
++		current->state = TASK_INTERRUPTIBLE;
++		schedule();
++		if (do_signal(&saveset, regs))
++			sigreturn_exit(regs);
++	}
++}
++
++long sys_rt_sigsuspend(
++#ifdef CONFIG_PPC64
++		compat_sigset_t __user *unewset,
++#else
++		sigset_t __user *unewset,
++#endif
++		size_t sigsetsize, int p3, int p4,
++		int p6, int p7, struct pt_regs *regs)
++{
++	sigset_t saveset, newset;
++
++	/* XXX: Don't preclude handling different sized sigset_t's.  */
++	if (sigsetsize != sizeof(sigset_t))
++		return -EINVAL;
++
++	if (get_sigset_t(&newset, unewset))
++		return -EFAULT;
++	sigdelsetmask(&newset, ~_BLOCKABLE);
++
++	spin_lock_irq(&current->sighand->siglock);
++	saveset = current->blocked;
++	current->blocked = newset;
++	recalc_sigpending();
++	spin_unlock_irq(&current->sighand->siglock);
++
++	regs->result = -EINTR;
++	regs->gpr[3] = EINTR;
++	regs->ccr |= 0x10000000;
++	while (1) {
++		current->state = TASK_INTERRUPTIBLE;
++		schedule();
++		if (do_signal(&saveset, regs))
++			sigreturn_exit(regs);
++	}
++}
++
++#ifdef CONFIG_PPC32
++long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5,
++		int r6, int r7, int r8, struct pt_regs *regs)
++{
++	return do_sigaltstack(uss, uoss, regs->gpr[1]);
++}
++#endif
++
++long sys_sigaction(int sig, struct old_sigaction __user *act,
++		struct old_sigaction __user *oact)
++{
++	struct k_sigaction new_ka, old_ka;
++	int ret;
++
++#ifdef CONFIG_PPC64
++	if (sig < 0)
++		sig = -sig;
++#endif
++
++	if (act) {
++		if (get_old_sigaction(&new_ka, act))
++			return -EFAULT;
++	}
++
++	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
++	if (!ret && oact) {
++		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
++		    __put_user(to_user_ptr(old_ka.sa.sa_handler),
++			    &oact->sa_handler) ||
++		    __put_user(to_user_ptr(old_ka.sa.sa_restorer),
++			    &oact->sa_restorer) ||
++		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
++		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
++			return -EFAULT;
++	}
++
++	return ret;
++}
++
++/*
++ * When we have signals to deliver, we set up on the
++ * user stack, going down from the original stack pointer:
++ *	a sigregs struct
++ *	a sigcontext struct
++ *	a gap of __SIGNAL_FRAMESIZE bytes
++ *
++ * Each of these things must be a multiple of 16 bytes in size.
++ *
++ */
++struct sigregs {
++	struct mcontext	mctx;		/* all the register values */
++	/*
++	 * Programs using the rs6000/xcoff abi can save up to 19 gp
++	 * regs and 18 fp regs below sp before decrementing it.
++	 */
++	int			abigap[56];
++};
++
++/* We use the mc_pad field for the signal return trampoline. */
++#define tramp	mc_pad
++
++/*
++ *  When we have rt signals to deliver, we set up on the
++ *  user stack, going down from the original stack pointer:
++ *	one rt_sigframe struct (siginfo + ucontext + ABI gap)
++ *	a gap of __SIGNAL_FRAMESIZE+16 bytes
++ *  (the +16 is to get the siginfo and ucontext in the same
++ *  positions as in older kernels).
++ *
++ *  Each of these things must be a multiple of 16 bytes in size.
++ *
++ */
++struct rt_sigframe {
++#ifdef CONFIG_PPC64
++	compat_siginfo_t info;
++#else
++	struct siginfo info;
++#endif
++	struct ucontext	uc;
++	/*
++	 * Programs using the rs6000/xcoff abi can save up to 19 gp
++	 * regs and 18 fp regs below sp before decrementing it.
++	 */
++	int			abigap[56];
++};
++
++/*
++ * Save the current user registers on the user stack.
++ * We only save the altivec/spe registers if the process has used
++ * altivec/spe instructions at some point.
++ */
++static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
++		int sigret)
++{
++#ifdef CONFIG_PPC32
++	CHECK_FULL_REGS(regs);
++#endif
++	/* Make sure floating point registers are stored in regs */
++	flush_fp_to_thread(current);
++
++	/* save general and floating-point registers */
++	if (save_general_regs(regs, frame) ||
++	    __copy_to_user(&frame->mc_fregs, current->thread.fpr,
++		    ELF_NFPREG * sizeof(double)))
++		return 1;
++
++	current->thread.fpscr.val = 0;	/* turn off all fp exceptions */
++
++#ifdef CONFIG_ALTIVEC
++	/* save altivec registers */
++	if (current->thread.used_vr) {
++		flush_altivec_to_thread(current);
++		if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
++				   ELF_NVRREG * sizeof(vector128)))
++			return 1;
++		/* set MSR_VEC in the saved MSR value to indicate that
++		   frame->mc_vregs contains valid data */
++		if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
++			return 1;
++	}
++	/* else assert((regs->msr & MSR_VEC) == 0) */
++
++	/* We always copy to/from vrsave, it's 0 if we don't have or don't
++	 * use altivec. Since VSCR only contains 32 bits saved in the least
++	 * significant bits of a vector, we "cheat" and stuff VRSAVE in the
++	 * most significant bits of that same vector. --BenH
++	 */
++	if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
++		return 1;
++#endif /* CONFIG_ALTIVEC */
++
++#ifdef CONFIG_SPE
++	/* save spe registers */
++	if (current->thread.used_spe) {
++		flush_spe_to_thread(current);
++		if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
++				   ELF_NEVRREG * sizeof(u32)))
++			return 1;
++		/* set MSR_SPE in the saved MSR value to indicate that
++		   frame->mc_vregs contains valid data */
++		if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR]))
++			return 1;
++	}
++	/* else assert((regs->msr & MSR_SPE) == 0) */
++
++	/* We always copy to/from spefscr */
++	if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG))
++		return 1;
++#endif /* CONFIG_SPE */
++
++	if (sigret) {
++		/* Set up the sigreturn trampoline: li r0,sigret; sc */
++		if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
++		    || __put_user(0x44000002UL, &frame->tramp[1]))
++			return 1;
++		flush_icache_range((unsigned long) &frame->tramp[0],
++				   (unsigned long) &frame->tramp[2]);
++	}
++
++	return 0;
++}
++
++/*
++ * Restore the current user register values from the user stack,
++ * (except for MSR).
++ */
++static long restore_user_regs(struct pt_regs *regs,
++			      struct mcontext __user *sr, int sig)
++{
++	long err;
++	unsigned int save_r2 = 0;
++#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
++	unsigned long msr;
++#endif
++
++	/*
++	 * restore general registers but not including MSR or SOFTE. Also
++	 * take care of keeping r2 (TLS) intact if not a signal
++	 */
++	if (!sig)
++		save_r2 = (unsigned int)regs->gpr[2];
++	err = restore_general_regs(regs, sr);
++	if (!sig)
++		regs->gpr[2] = (unsigned long) save_r2;
++	if (err)
++		return 1;
++
++	/* force the process to reload the FP registers from
++	   current->thread when it next does FP instructions */
++	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
++	if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
++			     sizeof(sr->mc_fregs)))
++		return 1;
++
++#ifdef CONFIG_ALTIVEC
++	/* force the process to reload the altivec registers from
++	   current->thread when it next does altivec instructions */
++	regs->msr &= ~MSR_VEC;
++	if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
++		/* restore altivec registers from the stack */
++		if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
++				     sizeof(sr->mc_vregs)))
++			return 1;
++	} else if (current->thread.used_vr)
++		memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
++
++	/* Always get VRSAVE back */
++	if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
++		return 1;
++#endif /* CONFIG_ALTIVEC */
++
++#ifdef CONFIG_SPE
++	/* force the process to reload the spe registers from
++	   current->thread when it next does spe instructions */
++	regs->msr &= ~MSR_SPE;
++	if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
++		/* restore spe registers from the stack */
++		if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
++				     ELF_NEVRREG * sizeof(u32)))
++			return 1;
++	} else if (current->thread.used_spe)
++		memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
++
++	/* Always get SPEFSCR back */
++	if (__get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs + ELF_NEVRREG))
++		return 1;
++#endif /* CONFIG_SPE */
++
++#ifndef CONFIG_SMP
++	preempt_disable();
++	if (last_task_used_math == current)
++		last_task_used_math = NULL;
++	if (last_task_used_altivec == current)
++		last_task_used_altivec = NULL;
++#ifdef CONFIG_SPE
++	if (last_task_used_spe == current)
++		last_task_used_spe = NULL;
++#endif
++	preempt_enable();
++#endif
++	return 0;
++}
++
++#ifdef CONFIG_PPC64
++long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act,
++		struct sigaction32 __user *oact, size_t sigsetsize)
++{
++	struct k_sigaction new_ka, old_ka;
++	int ret;
++
++	/* XXX: Don't preclude handling different sized sigset_t's.  */
++	if (sigsetsize != sizeof(compat_sigset_t))
++		return -EINVAL;
++
++	if (act) {
++		compat_uptr_t handler;
++
++		ret = get_user(handler, &act->sa_handler);
++		new_ka.sa.sa_handler = compat_ptr(handler);
++		ret |= get_sigset_t(&new_ka.sa.sa_mask, &act->sa_mask);
++		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
++		if (ret)
++			return -EFAULT;
++	}
++
++	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
++	if (!ret && oact) {
++		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
++		ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask);
++		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
++	}
++	return ret;
++}
++
++/*
++ * Note: it is necessary to treat how as an unsigned int, with the
++ * corresponding cast to a signed int to insure that the proper
++ * conversion (sign extension) between the register representation
++ * of a signed int (msr in 32-bit mode) and the register representation
++ * of a signed int (msr in 64-bit mode) is performed.
++ */
++long compat_sys_rt_sigprocmask(u32 how, compat_sigset_t __user *set,
++		compat_sigset_t __user *oset, size_t sigsetsize)
++{
++	sigset_t s;
++	sigset_t __user *up;
++	int ret;
++	mm_segment_t old_fs = get_fs();
++
++	if (set) {
++		if (get_sigset_t(&s, set))
++			return -EFAULT;
++	}
++
++	set_fs(KERNEL_DS);
++	/* This is valid because of the set_fs() */
++	up = (sigset_t __user *) &s;
++	ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL,
++				 sigsetsize);
++	set_fs(old_fs);
++	if (ret)
++		return ret;
++	if (oset) {
++		if (put_sigset_t(oset, &s))
++			return -EFAULT;
++	}
++	return 0;
++}
++
++long compat_sys_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
++{
++	sigset_t s;
++	int ret;
++	mm_segment_t old_fs = get_fs();
++
++	set_fs(KERNEL_DS);
++	/* The __user pointer cast is valid because of the set_fs() */
++	ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
++	set_fs(old_fs);
++	if (!ret) {
++		if (put_sigset_t(set, &s))
++			return -EFAULT;
++	}
++	return ret;
++}
++
++
++int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
++{
++	int err;
++
++	if (!access_ok (VERIFY_WRITE, d, sizeof(*d)))
++		return -EFAULT;
++
++	/* If you change siginfo_t structure, please be sure
++	 * this code is fixed accordingly.
++	 * It should never copy any pad contained in the structure
++	 * to avoid security leaks, but must copy the generic
++	 * 3 ints plus the relevant union member.
++	 * This routine must convert siginfo from 64bit to 32bit as well
++	 * at the same time.
++	 */
++	err = __put_user(s->si_signo, &d->si_signo);
++	err |= __put_user(s->si_errno, &d->si_errno);
++	err |= __put_user((short)s->si_code, &d->si_code);
++	if (s->si_code < 0)
++		err |= __copy_to_user(&d->_sifields._pad, &s->_sifields._pad,
++				      SI_PAD_SIZE32);
++	else switch(s->si_code >> 16) {
++	case __SI_CHLD >> 16:
++		err |= __put_user(s->si_pid, &d->si_pid);
++		err |= __put_user(s->si_uid, &d->si_uid);
++		err |= __put_user(s->si_utime, &d->si_utime);
++		err |= __put_user(s->si_stime, &d->si_stime);
++		err |= __put_user(s->si_status, &d->si_status);
++		break;
++	case __SI_FAULT >> 16:
++		err |= __put_user((unsigned int)(unsigned long)s->si_addr,
++				  &d->si_addr);
++		break;
++	case __SI_POLL >> 16:
++		err |= __put_user(s->si_band, &d->si_band);
++		err |= __put_user(s->si_fd, &d->si_fd);
++		break;
++	case __SI_TIMER >> 16:
++		err |= __put_user(s->si_tid, &d->si_tid);
++		err |= __put_user(s->si_overrun, &d->si_overrun);
++		err |= __put_user(s->si_int, &d->si_int);
++		break;
++	case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
++	case __SI_MESGQ >> 16:
++		err |= __put_user(s->si_int, &d->si_int);
++		/* fallthrough */
++	case __SI_KILL >> 16:
++	default:
++		err |= __put_user(s->si_pid, &d->si_pid);
++		err |= __put_user(s->si_uid, &d->si_uid);
++		break;
++	}
++	return err;
++}
++
++#define copy_siginfo_to_user	copy_siginfo_to_user32
++
++/*
++ * Note: it is necessary to treat pid and sig as unsigned ints, with the
++ * corresponding cast to a signed int to insure that the proper conversion
++ * (sign extension) between the register representation of a signed int
++ * (msr in 32-bit mode) and the register representation of a signed int
++ * (msr in 64-bit mode) is performed.
++ */
++long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
++{
++	siginfo_t info;
++	int ret;
++	mm_segment_t old_fs = get_fs();
++
++	if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
++	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32))
++		return -EFAULT;
++	set_fs (KERNEL_DS);
++	/* The __user pointer cast is valid becasuse of the set_fs() */
++	ret = sys_rt_sigqueueinfo((int)pid, (int)sig, (siginfo_t __user *) &info);
++	set_fs (old_fs);
++	return ret;
++}
++/*
++ *  Start Alternate signal stack support
++ *
++ *  System Calls
++ *       sigaltatck               compat_sys_sigaltstack
++ */
++
++int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
++		      int r6, int r7, int r8, struct pt_regs *regs)
++{
++	stack_32_t __user * newstack = (stack_32_t __user *)(long) __new;
++	stack_32_t __user * oldstack = (stack_32_t __user *)(long) __old;
++	stack_t uss, uoss;
++	int ret;
++	mm_segment_t old_fs;
++	unsigned long sp;
++	compat_uptr_t ss_sp;
++
++	/*
++	 * set sp to the user stack on entry to the system call
++	 * the system call router sets R9 to the saved registers
++	 */
++	sp = regs->gpr[1];
++
++	/* Put new stack info in local 64 bit stack struct */
++	if (newstack) {
++		if (get_user(ss_sp, &newstack->ss_sp) ||
++		    __get_user(uss.ss_flags, &newstack->ss_flags) ||
++		    __get_user(uss.ss_size, &newstack->ss_size))
++			return -EFAULT;
++		uss.ss_sp = compat_ptr(ss_sp);
++	}
++
++	old_fs = get_fs();
++	set_fs(KERNEL_DS);
++	/* The __user pointer casts are valid because of the set_fs() */
++	ret = do_sigaltstack(
++		newstack ? (stack_t __user *) &uss : NULL,
++		oldstack ? (stack_t __user *) &uoss : NULL,
++		sp);
++	set_fs(old_fs);
++	/* Copy the stack information to the user output buffer */
++	if (!ret && oldstack  &&
++		(put_user((long)uoss.ss_sp, &oldstack->ss_sp) ||
++		 __put_user(uoss.ss_flags, &oldstack->ss_flags) ||
++		 __put_user(uoss.ss_size, &oldstack->ss_size)))
++		return -EFAULT;
++	return ret;
++}
++#endif /* CONFIG_PPC64 */
++
++
++/*
++ * Restore the user process's signal mask
++ */
++#ifdef CONFIG_PPC64
++extern void restore_sigmask(sigset_t *set);
++#else /* CONFIG_PPC64 */
++static void restore_sigmask(sigset_t *set)
++{
++	sigdelsetmask(set, ~_BLOCKABLE);
++	spin_lock_irq(&current->sighand->siglock);
++	current->blocked = *set;
++	recalc_sigpending();
++	spin_unlock_irq(&current->sighand->siglock);
++}
++#endif
++
++/*
++ * Set up a signal frame for a "real-time" signal handler
++ * (one which gets siginfo).
++ */
++static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
++		siginfo_t *info, sigset_t *oldset,
++		struct pt_regs *regs, unsigned long newsp)
++{
++	struct rt_sigframe __user *rt_sf;
++	struct mcontext __user *frame;
++	unsigned long origsp = newsp;
++
++	/* Set up Signal Frame */
++	/* Put a Real Time Context onto stack */
++	newsp -= sizeof(*rt_sf);
++	rt_sf = (struct rt_sigframe __user *)newsp;
++
++	/* create a stack frame for the caller of the handler */
++	newsp -= __SIGNAL_FRAMESIZE + 16;
++
++	if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp))
++		goto badframe;
++
++	/* Put the siginfo & fill in most of the ucontext */
++	if (copy_siginfo_to_user(&rt_sf->info, info)
++	    || __put_user(0, &rt_sf->uc.uc_flags)
++	    || __put_user(0, &rt_sf->uc.uc_link)
++	    || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
++	    || __put_user(sas_ss_flags(regs->gpr[1]),
++			  &rt_sf->uc.uc_stack.ss_flags)
++	    || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
++	    || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
++		    &rt_sf->uc.uc_regs)
++	    || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
++		goto badframe;
++
++	/* Save user registers on the stack */
++	frame = &rt_sf->uc.uc_mcontext;
++#ifdef CONFIG_PPC64
++	if (vdso32_rt_sigtramp && current->thread.vdso_base) {
++		if (save_user_regs(regs, frame, 0))
++			goto badframe;
++		regs->link = current->thread.vdso_base + vdso32_rt_sigtramp;
++	} else
++#endif
++	{
++		if (save_user_regs(regs, frame, __NR_rt_sigreturn))
++			goto badframe;
++		regs->link = (unsigned long) frame->tramp;
++	}
++	if (put_user(regs->gpr[1], (u32 __user *)newsp))
++		goto badframe;
++	regs->gpr[1] = newsp;
++	regs->gpr[3] = sig;
++	regs->gpr[4] = (unsigned long) &rt_sf->info;
++	regs->gpr[5] = (unsigned long) &rt_sf->uc;
++	regs->gpr[6] = (unsigned long) rt_sf;
++	regs->nip = (unsigned long) ka->sa.sa_handler;
++	regs->trap = 0;
++#ifdef CONFIG_PPC64
++	regs->result = 0;
++
++	if (test_thread_flag(TIF_SINGLESTEP))
++		ptrace_notify(SIGTRAP);
++#endif
++	return 1;
++
++badframe:
++#ifdef DEBUG_SIG
++	printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
++	       regs, frame, newsp);
++#endif
++	force_sigsegv(sig, current);
++	return 0;
++}
++
++static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
++{
++	sigset_t set;
++	struct mcontext __user *mcp;
++
++	if (get_sigset_t(&set, &ucp->uc_sigmask))
++		return -EFAULT;
++#ifdef CONFIG_PPC64
++	{
++		u32 cmcp;
++
++		if (__get_user(cmcp, &ucp->uc_regs))
++			return -EFAULT;
++		mcp = (struct mcontext __user *)(u64)cmcp;
++	}
++#else
++	if (__get_user(mcp, &ucp->uc_regs))
++		return -EFAULT;
++#endif
++	restore_sigmask(&set);
++	if (restore_user_regs(regs, mcp, sig))
++		return -EFAULT;
++
++	return 0;
++}
++
++long sys_swapcontext(struct ucontext __user *old_ctx,
++		       struct ucontext __user *new_ctx,
++		       int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
++{
++	unsigned char tmp;
++
++	/* Context size is for future use. Right now, we only make sure
++	 * we are passed something we understand
++	 */
++	if (ctx_size < sizeof(struct ucontext))
++		return -EINVAL;
++
++	if (old_ctx != NULL) {
++		if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
++		    || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
++		    || put_sigset_t(&old_ctx->uc_sigmask, &current->blocked)
++		    || __put_user(to_user_ptr(&old_ctx->uc_mcontext),
++			    &old_ctx->uc_regs))
++			return -EFAULT;
++	}
++	if (new_ctx == NULL)
++		return 0;
++	if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx))
++	    || __get_user(tmp, (u8 __user *) new_ctx)
++	    || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
++		return -EFAULT;
++
++	/*
++	 * If we get a fault copying the context into the kernel's
++	 * image of the user's registers, we can't just return -EFAULT
++	 * because the user's registers will be corrupted.  For instance
++	 * the NIP value may have been updated but not some of the
++	 * other registers.  Given that we have done the access_ok
++	 * and successfully read the first and last bytes of the region
++	 * above, this should only happen in an out-of-memory situation
++	 * or if another thread unmaps the region containing the context.
++	 * We kill the task with a SIGSEGV in this situation.
++	 */
++	if (do_setcontext(new_ctx, regs, 0))
++		do_exit(SIGSEGV);
++	sigreturn_exit(regs);
++	/* doesn't actually return back to here */
++	return 0;
++}
++
++long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
++		     struct pt_regs *regs)
++{
++	struct rt_sigframe __user *rt_sf;
++
++	/* Always make any pending restarted system calls return -EINTR */
++	current_thread_info()->restart_block.fn = do_no_restart_syscall;
++
++	rt_sf = (struct rt_sigframe __user *)
++		(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
++	if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
++		goto bad;
++	if (do_setcontext(&rt_sf->uc, regs, 1))
++		goto bad;
++
++	/*
++	 * It's not clear whether or why it is desirable to save the
++	 * sigaltstack setting on signal delivery and restore it on
++	 * signal return.  But other architectures do this and we have
++	 * always done it up until now so it is probably better not to
++	 * change it.  -- paulus
++	 */
++#ifdef CONFIG_PPC64
++	/*
++	 * We use the compat_sys_ version that does the 32/64 bits conversion
++	 * and takes userland pointer directly. What about error checking ?
++	 * nobody does any...
++	 */
++	compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
++	return (int)regs->result;
++#else
++	do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
++	sigreturn_exit(regs);		/* doesn't return here */
++	return 0;
++#endif
++
++ bad:
++	force_sig(SIGSEGV, current);
++	return 0;
++}
++
++#ifdef CONFIG_PPC32
++int sys_debug_setcontext(struct ucontext __user *ctx,
++			 int ndbg, struct sig_dbg_op __user *dbg,
++			 int r6, int r7, int r8,
++			 struct pt_regs *regs)
++{
++	struct sig_dbg_op op;
++	int i;
++	unsigned long new_msr = regs->msr;
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++	unsigned long new_dbcr0 = current->thread.dbcr0;
++#endif
++
++	for (i=0; i<ndbg; i++) {
++		if (__copy_from_user(&op, dbg, sizeof(op)))
++			return -EFAULT;
++		switch (op.dbg_type) {
++		case SIG_DBG_SINGLE_STEPPING:
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++			if (op.dbg_value) {
++				new_msr |= MSR_DE;
++				new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
++			} else {
++				new_msr &= ~MSR_DE;
++				new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
++			}
++#else
++			if (op.dbg_value)
++				new_msr |= MSR_SE;
++			else
++				new_msr &= ~MSR_SE;
++#endif
++			break;
++		case SIG_DBG_BRANCH_TRACING:
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++			return -EINVAL;
++#else
++			if (op.dbg_value)
++				new_msr |= MSR_BE;
++			else
++				new_msr &= ~MSR_BE;
++#endif
++			break;
++
++		default:
++			return -EINVAL;
++		}
++	}
++
++	/* We wait until here to actually install the values in the
++	   registers so if we fail in the above loop, it will not
++	   affect the contents of these registers.  After this point,
++	   failure is a problem, anyway, and it's very unlikely unless
++	   the user is really doing something wrong. */
++	regs->msr = new_msr;
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++	current->thread.dbcr0 = new_dbcr0;
++#endif
++
++	/*
++	 * If we get a fault copying the context into the kernel's
++	 * image of the user's registers, we can't just return -EFAULT
++	 * because the user's registers will be corrupted.  For instance
++	 * the NIP value may have been updated but not some of the
++	 * other registers.  Given that we have done the access_ok
++	 * and successfully read the first and last bytes of the region
++	 * above, this should only happen in an out-of-memory situation
++	 * or if another thread unmaps the region containing the context.
++	 * We kill the task with a SIGSEGV in this situation.
++	 */
++	if (do_setcontext(ctx, regs, 1)) {
++		force_sig(SIGSEGV, current);
++		goto out;
++	}
++
++	/*
++	 * It's not clear whether or why it is desirable to save the
++	 * sigaltstack setting on signal delivery and restore it on
++	 * signal return.  But other architectures do this and we have
++	 * always done it up until now so it is probably better not to
++	 * change it.  -- paulus
++	 */
++	do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
++
++	sigreturn_exit(regs);
++	/* doesn't actually return back to here */
++
++ out:
++	return 0;
++}
++#endif
++
++/*
++ * OK, we're invoking a handler
++ */
++static int handle_signal(unsigned long sig, struct k_sigaction *ka,
++		siginfo_t *info, sigset_t *oldset, struct pt_regs *regs,
++		unsigned long newsp)
++{
++	struct sigcontext __user *sc;
++	struct sigregs __user *frame;
++	unsigned long origsp = newsp;
++
++	/* Set up Signal Frame */
++	newsp -= sizeof(struct sigregs);
++	frame = (struct sigregs __user *) newsp;
++
++	/* Put a sigcontext on the stack */
++	newsp -= sizeof(*sc);
++	sc = (struct sigcontext __user *) newsp;
++
++	/* create a stack frame for the caller of the handler */
++	newsp -= __SIGNAL_FRAMESIZE;
++
++	if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
++		goto badframe;
++
++#if _NSIG != 64
++#error "Please adjust handle_signal()"
++#endif
++	if (__put_user(to_user_ptr(ka->sa.sa_handler), &sc->handler)
++	    || __put_user(oldset->sig[0], &sc->oldmask)
++#ifdef CONFIG_PPC64
++	    || __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
++#else
++	    || __put_user(oldset->sig[1], &sc->_unused[3])
++#endif
++	    || __put_user(to_user_ptr(frame), &sc->regs)
++	    || __put_user(sig, &sc->signal))
++		goto badframe;
++
++#ifdef CONFIG_PPC64
++	if (vdso32_sigtramp && current->thread.vdso_base) {
++		if (save_user_regs(regs, &frame->mctx, 0))
++			goto badframe;
++		regs->link = current->thread.vdso_base + vdso32_sigtramp;
++	} else
++#endif
++	{
++		if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
++			goto badframe;
++		regs->link = (unsigned long) frame->mctx.tramp;
++	}
++
++	if (put_user(regs->gpr[1], (u32 __user *)newsp))
++		goto badframe;
++	regs->gpr[1] = newsp;
++	regs->gpr[3] = sig;
++	regs->gpr[4] = (unsigned long) sc;
++	regs->nip = (unsigned long) ka->sa.sa_handler;
++	regs->trap = 0;
++#ifdef CONFIG_PPC64
++	regs->result = 0;
++
++	if (test_thread_flag(TIF_SINGLESTEP))
++		ptrace_notify(SIGTRAP);
++#endif
++
++	return 1;
++
++badframe:
++#ifdef DEBUG_SIG
++	printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
++	       regs, frame, newsp);
++#endif
++	force_sigsegv(sig, current);
++	return 0;
++}
++
++/*
++ * Do a signal return; undo the signal stack.
++ */
++long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
++		       struct pt_regs *regs)
++{
++	struct sigcontext __user *sc;
++	struct sigcontext sigctx;
++	struct mcontext __user *sr;
++	sigset_t set;
++
++	/* Always make any pending restarted system calls return -EINTR */
++	current_thread_info()->restart_block.fn = do_no_restart_syscall;
++
++	sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
++	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
++		goto badframe;
++
++#ifdef CONFIG_PPC64
++	/*
++	 * Note that PPC32 puts the upper 32 bits of the sigmask in the
++	 * unused part of the signal stackframe
++	 */
++	set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32);
++#else
++	set.sig[0] = sigctx.oldmask;
++	set.sig[1] = sigctx._unused[3];
++#endif
++	restore_sigmask(&set);
++
++	sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
++	if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
++	    || restore_user_regs(regs, sr, 1))
++		goto badframe;
++
++#ifdef CONFIG_PPC64
++	return (int)regs->result;
++#else
++	sigreturn_exit(regs);		/* doesn't return */
++	return 0;
++#endif
++
++badframe:
++	force_sig(SIGSEGV, current);
++	return 0;
++}
++
++/*
++ * Note that 'init' is a special process: it doesn't get signals it doesn't
++ * want to handle. Thus you cannot kill init even with a SIGKILL even by
++ * mistake.
++ */
++int do_signal(sigset_t *oldset, struct pt_regs *regs)
++{
++	siginfo_t info;
++	struct k_sigaction ka;
++	unsigned int frame, newsp;
++	int signr, ret;
++
++#ifdef CONFIG_PPC32
++	if (try_to_freeze()) {
++		signr = 0;
++		if (!signal_pending(current))
++			goto no_signal;
++	}
++#endif
++
++	if (!oldset)
++		oldset = &current->blocked;
++
++	newsp = frame = 0;
++
++	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
++#ifdef CONFIG_PPC32
++no_signal:
++#endif
++	if (TRAP(regs) == 0x0C00		/* System Call! */
++	    && regs->ccr & 0x10000000		/* error signalled */
++	    && ((ret = regs->gpr[3]) == ERESTARTSYS
++		|| ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
++		|| ret == ERESTART_RESTARTBLOCK)) {
++
++		if (signr > 0
++		    && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
++			|| (ret == ERESTARTSYS
++			    && !(ka.sa.sa_flags & SA_RESTART)))) {
++			/* make the system call return an EINTR error */
++			regs->result = -EINTR;
++			regs->gpr[3] = EINTR;
++			/* note that the cr0.SO bit is already set */
++		} else {
++			regs->nip -= 4;	/* Back up & retry system call */
++			regs->result = 0;
++			regs->trap = 0;
++			if (ret == ERESTART_RESTARTBLOCK)
++				regs->gpr[0] = __NR_restart_syscall;
++			else
++				regs->gpr[3] = regs->orig_gpr3;
++		}
++	}
++
++	if (signr == 0)
++		return 0;		/* no signals delivered */
++
++	if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
++	    && !on_sig_stack(regs->gpr[1]))
++		newsp = current->sas_ss_sp + current->sas_ss_size;
++	else
++		newsp = regs->gpr[1];
++	newsp &= ~0xfUL;
++
++#ifdef CONFIG_PPC64
++	/*
++	 * Reenable the DABR before delivering the signal to
++	 * user space. The DABR will have been cleared if it
++	 * triggered inside the kernel.
++	 */
++	if (current->thread.dabr)
++		set_dabr(current->thread.dabr);
++#endif
++
++	/* Whee!  Actually deliver the signal.  */
++	if (ka.sa.sa_flags & SA_SIGINFO)
++		ret = handle_rt_signal(signr, &ka, &info, oldset, regs, newsp);
++	else
++		ret = handle_signal(signr, &ka, &info, oldset, regs, newsp);
++
++	if (ret) {
++		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 ret;
++}
+diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/sys_ppc32.c
+@@ -0,0 +1,1008 @@
++/*
++ * sys_ppc32.c: Conversion between 32bit and 64bit native syscalls.
++ *
++ * Copyright (C) 2001 IBM
++ * Copyright (C) 1997,1998 Jakub Jelinek (jj at sunsite.mff.cuni.cz)
++ * Copyright (C) 1997 David S. Miller (davem at caip.rutgers.edu)
++ *
++ * These routines maintain argument size conversion between 32bit and 64bit
++ * environment.
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/fs.h> 
++#include <linux/mm.h> 
++#include <linux/file.h> 
++#include <linux/signal.h>
++#include <linux/resource.h>
++#include <linux/times.h>
++#include <linux/utsname.h>
++#include <linux/timex.h>
++#include <linux/smp.h>
++#include <linux/smp_lock.h>
++#include <linux/sem.h>
++#include <linux/msg.h>
++#include <linux/shm.h>
++#include <linux/poll.h>
++#include <linux/personality.h>
++#include <linux/stat.h>
++#include <linux/mman.h>
++#include <linux/in.h>
++#include <linux/syscalls.h>
++#include <linux/unistd.h>
++#include <linux/sysctl.h>
++#include <linux/binfmts.h>
++#include <linux/security.h>
++#include <linux/compat.h>
++#include <linux/ptrace.h>
++#include <linux/elf.h>
++
++#include <asm/ptrace.h>
++#include <asm/types.h>
++#include <asm/ipc.h>
++#include <asm/uaccess.h>
++#include <asm/unistd.h>
++#include <asm/semaphore.h>
++#include <asm/time.h>
++#include <asm/mmu_context.h>
++#include <asm/systemcfg.h>
++#include <asm/ppc-pci.h>
++
++/* readdir & getdents */
++#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
++#define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
++
++struct old_linux_dirent32 {
++	u32		d_ino;
++	u32		d_offset;
++	unsigned short	d_namlen;
++	char		d_name[1];
++};
++
++struct readdir_callback32 {
++	struct old_linux_dirent32 __user * dirent;
++	int count;
++};
++
++static int fillonedir(void * __buf, const char * name, int namlen,
++		                  off_t offset, ino_t ino, unsigned int d_type)
++{
++	struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
++	struct old_linux_dirent32 __user * dirent;
++
++	if (buf->count)
++		return -EINVAL;
++	buf->count++;
++	dirent = buf->dirent;
++	put_user(ino, &dirent->d_ino);
++	put_user(offset, &dirent->d_offset);
++	put_user(namlen, &dirent->d_namlen);
++	copy_to_user(dirent->d_name, name, namlen);
++	put_user(0, dirent->d_name + namlen);
++	return 0;
++}
++
++asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 __user *dirent, unsigned int count)
++{
++	int error = -EBADF;
++	struct file * file;
++	struct readdir_callback32 buf;
++
++	file = fget(fd);
++	if (!file)
++		goto out;
++
++	buf.count = 0;
++	buf.dirent = dirent;
++
++	error = vfs_readdir(file, (filldir_t)fillonedir, &buf);
++	if (error < 0)
++		goto out_putf;
++	error = buf.count;
++
++out_putf:
++	fput(file);
++out:
++	return error;
++}
++
++asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
++		compat_ulong_t __user *outp, compat_ulong_t __user *exp,
++		compat_uptr_t tvp_x)
++{
++	/* sign extend n */
++	return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x));
++}
++
++int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
++{
++	long err;
++
++	if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
++	    !new_valid_dev(stat->rdev))
++		return -EOVERFLOW;
++
++	err  = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT;
++	err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
++	err |= __put_user(stat->ino, &statbuf->st_ino);
++	err |= __put_user(stat->mode, &statbuf->st_mode);
++	err |= __put_user(stat->nlink, &statbuf->st_nlink);
++	err |= __put_user(stat->uid, &statbuf->st_uid);
++	err |= __put_user(stat->gid, &statbuf->st_gid);
++	err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
++	err |= __put_user(stat->size, &statbuf->st_size);
++	err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime);
++	err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
++	err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
++	err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
++	err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
++	err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
++	err |= __put_user(stat->blksize, &statbuf->st_blksize);
++	err |= __put_user(stat->blocks, &statbuf->st_blocks);
++	err |= __put_user(0, &statbuf->__unused4[0]);
++	err |= __put_user(0, &statbuf->__unused4[1]);
++
++	return err;
++}
++
++/* Note: it is necessary to treat option as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2)
++{
++	return sys_sysfs((int)option, arg1, arg2);
++}
++
++/* Handle adjtimex compatibility. */
++struct timex32 {
++	u32 modes;
++	s32 offset, freq, maxerror, esterror;
++	s32 status, constant, precision, tolerance;
++	struct compat_timeval time;
++	s32 tick;
++	s32 ppsfreq, jitter, shift, stabil;
++	s32 jitcnt, calcnt, errcnt, stbcnt;
++	s32  :32; s32  :32; s32  :32; s32  :32;
++	s32  :32; s32  :32; s32  :32; s32  :32;
++	s32  :32; s32  :32; s32  :32; s32  :32;
++};
++
++extern int do_adjtimex(struct timex *);
++extern void ppc_adjtimex(void);
++
++asmlinkage long compat_sys_adjtimex(struct timex32 __user *utp)
++{
++	struct timex txc;
++	int ret;
++	
++	memset(&txc, 0, sizeof(struct timex));
++
++	if(get_user(txc.modes, &utp->modes) ||
++	   __get_user(txc.offset, &utp->offset) ||
++	   __get_user(txc.freq, &utp->freq) ||
++	   __get_user(txc.maxerror, &utp->maxerror) ||
++	   __get_user(txc.esterror, &utp->esterror) ||
++	   __get_user(txc.status, &utp->status) ||
++	   __get_user(txc.constant, &utp->constant) ||
++	   __get_user(txc.precision, &utp->precision) ||
++	   __get_user(txc.tolerance, &utp->tolerance) ||
++	   __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
++	   __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
++	   __get_user(txc.tick, &utp->tick) ||
++	   __get_user(txc.ppsfreq, &utp->ppsfreq) ||
++	   __get_user(txc.jitter, &utp->jitter) ||
++	   __get_user(txc.shift, &utp->shift) ||
++	   __get_user(txc.stabil, &utp->stabil) ||
++	   __get_user(txc.jitcnt, &utp->jitcnt) ||
++	   __get_user(txc.calcnt, &utp->calcnt) ||
++	   __get_user(txc.errcnt, &utp->errcnt) ||
++	   __get_user(txc.stbcnt, &utp->stbcnt))
++		return -EFAULT;
++
++	ret = do_adjtimex(&txc);
++
++	/* adjust the conversion of TB to time of day to track adjtimex */
++	ppc_adjtimex();
++
++	if(put_user(txc.modes, &utp->modes) ||
++	   __put_user(txc.offset, &utp->offset) ||
++	   __put_user(txc.freq, &utp->freq) ||
++	   __put_user(txc.maxerror, &utp->maxerror) ||
++	   __put_user(txc.esterror, &utp->esterror) ||
++	   __put_user(txc.status, &utp->status) ||
++	   __put_user(txc.constant, &utp->constant) ||
++	   __put_user(txc.precision, &utp->precision) ||
++	   __put_user(txc.tolerance, &utp->tolerance) ||
++	   __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
++	   __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
++	   __put_user(txc.tick, &utp->tick) ||
++	   __put_user(txc.ppsfreq, &utp->ppsfreq) ||
++	   __put_user(txc.jitter, &utp->jitter) ||
++	   __put_user(txc.shift, &utp->shift) ||
++	   __put_user(txc.stabil, &utp->stabil) ||
++	   __put_user(txc.jitcnt, &utp->jitcnt) ||
++	   __put_user(txc.calcnt, &utp->calcnt) ||
++	   __put_user(txc.errcnt, &utp->errcnt) ||
++	   __put_user(txc.stbcnt, &utp->stbcnt))
++		ret = -EFAULT;
++
++	return ret;
++}
++
++asmlinkage long compat_sys_pause(void)
++{
++	current->state = TASK_INTERRUPTIBLE;
++	schedule();
++	
++	return -ERESTARTNOHAND;
++}
++
++static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
++{
++	long usec;
++
++	if (!access_ok(VERIFY_READ, i, sizeof(*i)))
++		return -EFAULT;
++	if (__get_user(o->tv_sec, &i->tv_sec))
++		return -EFAULT;
++	if (__get_user(usec, &i->tv_usec))
++		return -EFAULT;
++	o->tv_nsec = usec * 1000;
++	return 0;
++}
++
++static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
++{
++	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
++		(__put_user(i->tv_sec, &o->tv_sec) |
++		 __put_user(i->tv_usec, &o->tv_usec)));
++}
++
++struct sysinfo32 {
++        s32 uptime;
++        u32 loads[3];
++        u32 totalram;
++        u32 freeram;
++        u32 sharedram;
++        u32 bufferram;
++        u32 totalswap;
++        u32 freeswap;
++        unsigned short procs;
++	unsigned short pad;
++	u32 totalhigh;
++	u32 freehigh;
++	u32 mem_unit;
++	char _f[20-2*sizeof(int)-sizeof(int)];
++};
++
++asmlinkage long compat_sys_sysinfo(struct sysinfo32 __user *info)
++{
++	struct sysinfo s;
++	int ret, err;
++	int bitcount=0;
++	mm_segment_t old_fs = get_fs ();
++	
++	/* The __user cast is valid due to set_fs() */
++	set_fs (KERNEL_DS);
++	ret = sys_sysinfo((struct sysinfo __user *)&s);
++	set_fs (old_fs);
++
++	/* Check to see if any memory value is too large for 32-bit and
++         * scale down if needed.
++         */
++	if ((s.totalram >> 32) || (s.totalswap >> 32)) {
++	    while (s.mem_unit < PAGE_SIZE) {
++		s.mem_unit <<= 1;
++		bitcount++;
++	    }
++	    s.totalram >>=bitcount;
++	    s.freeram >>= bitcount;
++	    s.sharedram >>= bitcount;
++	    s.bufferram >>= bitcount;
++	    s.totalswap >>= bitcount;
++	    s.freeswap >>= bitcount;
++	    s.totalhigh >>= bitcount;
++	    s.freehigh >>= bitcount;
++	}
++
++	err = put_user (s.uptime, &info->uptime);
++	err |= __put_user (s.loads[0], &info->loads[0]);
++	err |= __put_user (s.loads[1], &info->loads[1]);
++	err |= __put_user (s.loads[2], &info->loads[2]);
++	err |= __put_user (s.totalram, &info->totalram);
++	err |= __put_user (s.freeram, &info->freeram);
++	err |= __put_user (s.sharedram, &info->sharedram);
++	err |= __put_user (s.bufferram, &info->bufferram);
++	err |= __put_user (s.totalswap, &info->totalswap);
++	err |= __put_user (s.freeswap, &info->freeswap);
++	err |= __put_user (s.procs, &info->procs);
++	err |= __put_user (s.totalhigh, &info->totalhigh);
++	err |= __put_user (s.freehigh, &info->freehigh);
++	err |= __put_user (s.mem_unit, &info->mem_unit);
++	if (err)
++		return -EFAULT;
++	
++	return ret;
++}
++
++
++
++
++/* Translations due to time_t size differences.  Which affects all
++   sorts of things, like timeval and itimerval.  */
++extern struct timezone sys_tz;
++
++asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
++{
++	if (tv) {
++		struct timeval ktv;
++		do_gettimeofday(&ktv);
++		if (put_tv32(tv, &ktv))
++			return -EFAULT;
++	}
++	if (tz) {
++		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
++			return -EFAULT;
++	}
++	
++	return 0;
++}
++
++
++
++asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
++{
++	struct timespec kts;
++	struct timezone ktz;
++	
++ 	if (tv) {
++		if (get_ts32(&kts, tv))
++			return -EFAULT;
++	}
++	if (tz) {
++		if (copy_from_user(&ktz, tz, sizeof(ktz)))
++			return -EFAULT;
++	}
++
++	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
++}
++
++#ifdef CONFIG_SYSVIPC
++long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
++	       u32 fifth)
++{
++	int version;
++
++	version = call >> 16; /* hack for backward compatibility */
++	call &= 0xffff;
++
++	switch (call) {
++
++	case SEMTIMEDOP:
++		if (fifth)
++			/* sign extend semid */
++			return compat_sys_semtimedop((int)first,
++						     compat_ptr(ptr), second,
++						     compat_ptr(fifth));
++		/* else fall through for normal semop() */
++	case SEMOP:
++		/* struct sembuf is the same on 32 and 64bit :)) */
++		/* sign extend semid */
++		return sys_semtimedop((int)first, compat_ptr(ptr), second,
++				      NULL);
++	case SEMGET:
++		/* sign extend key, nsems */
++		return sys_semget((int)first, (int)second, third);
++	case SEMCTL:
++		/* sign extend semid, semnum */
++		return compat_sys_semctl((int)first, (int)second, third,
++					 compat_ptr(ptr));
++
++	case MSGSND:
++		/* sign extend msqid */
++		return compat_sys_msgsnd((int)first, (int)second, third,
++					 compat_ptr(ptr));
++	case MSGRCV:
++		/* sign extend msqid, msgtyp */
++		return compat_sys_msgrcv((int)first, second, (int)fifth,
++					 third, version, compat_ptr(ptr));
++	case MSGGET:
++		/* sign extend key */
++		return sys_msgget((int)first, second);
++	case MSGCTL:
++		/* sign extend msqid */
++		return compat_sys_msgctl((int)first, second, compat_ptr(ptr));
++
++	case SHMAT:
++		/* sign extend shmid */
++		return compat_sys_shmat((int)first, second, third, version,
++					compat_ptr(ptr));
++	case SHMDT:
++		return sys_shmdt(compat_ptr(ptr));
++	case SHMGET:
++		/* sign extend key_t */
++		return sys_shmget((int)first, second, third);
++	case SHMCTL:
++		/* sign extend shmid */
++		return compat_sys_shmctl((int)first, second, compat_ptr(ptr));
++
++	default:
++		return -ENOSYS;
++	}
++
++	return -ENOSYS;
++}
++#endif
++
++/* Note: it is necessary to treat out_fd and in_fd as unsigned ints, 
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
++{
++	mm_segment_t old_fs = get_fs();
++	int ret;
++	off_t of;
++	off_t __user *up;
++
++	if (offset && get_user(of, offset))
++		return -EFAULT;
++
++	/* The __user pointer cast is valid because of the set_fs() */		
++	set_fs(KERNEL_DS);
++	up = offset ? (off_t __user *) &of : NULL;
++	ret = sys_sendfile((int)out_fd, (int)in_fd, up, count);
++	set_fs(old_fs);
++	
++	if (offset && put_user(of, offset))
++		return -EFAULT;
++		
++	return ret;
++}
++
++asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
++{
++	mm_segment_t old_fs = get_fs();
++	int ret;
++	loff_t lof;
++	loff_t __user *up;
++	
++	if (offset && get_user(lof, offset))
++		return -EFAULT;
++		
++	/* The __user pointer cast is valid because of the set_fs() */		
++	set_fs(KERNEL_DS);
++	up = offset ? (loff_t __user *) &lof : NULL;
++	ret = sys_sendfile64(out_fd, in_fd, up, count);
++	set_fs(old_fs);
++	
++	if (offset && put_user(lof, offset))
++		return -EFAULT;
++		
++	return ret;
++}
++
++long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
++		  unsigned long a3, unsigned long a4, unsigned long a5,
++		  struct pt_regs *regs)
++{
++	int error;
++	char * filename;
++	
++	filename = getname((char __user *) a0);
++	error = PTR_ERR(filename);
++	if (IS_ERR(filename))
++		goto out;
++	flush_fp_to_thread(current);
++	flush_altivec_to_thread(current);
++
++	error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
++
++	if (error == 0) {
++		task_lock(current);
++		current->ptrace &= ~PT_DTRACE;
++		task_unlock(current);
++	}
++	putname(filename);
++
++out:
++	return error;
++}
++
++/* Note: it is necessary to treat option as an unsigned int, 
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
++{
++	return sys_prctl((int)option,
++			 (unsigned long) arg2,
++			 (unsigned long) arg3,
++			 (unsigned long) arg4,
++			 (unsigned long) arg5);
++}
++
++/* Note: it is necessary to treat pid as an unsigned int, 
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval)
++{
++	struct timespec t;
++	int ret;
++	mm_segment_t old_fs = get_fs ();
++
++	/* The __user pointer cast is valid because of the set_fs() */
++	set_fs (KERNEL_DS);
++	ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t);
++	set_fs (old_fs);
++	if (put_compat_timespec(&t, interval))
++		return -EFAULT;
++	return ret;
++}
++
++asmlinkage int compat_sys_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
++{
++	return sys_pciconfig_read((unsigned long) bus,
++				  (unsigned long) dfn,
++				  (unsigned long) off,
++				  (unsigned long) len,
++				  compat_ptr(ubuf));
++}
++
++asmlinkage int compat_sys_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
++{
++	return sys_pciconfig_write((unsigned long) bus,
++				   (unsigned long) dfn,
++				   (unsigned long) off,
++				   (unsigned long) len,
++				   compat_ptr(ubuf));
++}
++
++asmlinkage int compat_sys_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
++{
++	return sys_pciconfig_iobase(which, in_bus, in_devfn);
++}
++
++
++/* Note: it is necessary to treat mode as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_access(const char __user * filename, u32 mode)
++{
++	return sys_access(filename, (int)mode);
++}
++
++
++/* Note: it is necessary to treat mode as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_creat(const char __user * pathname, u32 mode)
++{
++	return sys_creat(pathname, (int)mode);
++}
++
++
++/* Note: it is necessary to treat pid and options as unsigned ints,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options)
++{
++	return sys_waitpid((int)pid, stat_addr, (int)options);
++}
++
++
++/* Note: it is necessary to treat gidsetsize as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_getgroups(u32 gidsetsize, gid_t __user *grouplist)
++{
++	return sys_getgroups((int)gidsetsize, grouplist);
++}
++
++
++/* Note: it is necessary to treat pid as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_getpgid(u32 pid)
++{
++	return sys_getpgid((int)pid);
++}
++
++
++
++/* Note: it is necessary to treat pid as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_getsid(u32 pid)
++{
++	return sys_getsid((int)pid);
++}
++
++
++/* Note: it is necessary to treat pid and sig as unsigned ints,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_kill(u32 pid, u32 sig)
++{
++	return sys_kill((int)pid, (int)sig);
++}
++
++
++/* Note: it is necessary to treat mode as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_mkdir(const char __user * pathname, u32 mode)
++{
++	return sys_mkdir(pathname, (int)mode);
++}
++
++long compat_sys_nice(u32 increment)
++{
++	/* sign extend increment */
++	return sys_nice((int)increment);
++}
++
++off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin)
++{
++	/* sign extend n */
++	return sys_lseek(fd, (int)offset, origin);
++}
++
++/* Note: it is necessary to treat bufsiz as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_readlink(const char __user * path, char __user * buf, u32 bufsiz)
++{
++	return sys_readlink(path, buf, (int)bufsiz);
++}
++
++/* Note: it is necessary to treat option as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_sched_get_priority_max(u32 policy)
++{
++	return sys_sched_get_priority_max((int)policy);
++}
++
++
++/* Note: it is necessary to treat policy as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_sched_get_priority_min(u32 policy)
++{
++	return sys_sched_get_priority_min((int)policy);
++}
++
++
++/* Note: it is necessary to treat pid as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_sched_getparam(u32 pid, struct sched_param __user *param)
++{
++	return sys_sched_getparam((int)pid, param);
++}
++
++
++/* Note: it is necessary to treat pid as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_sched_getscheduler(u32 pid)
++{
++	return sys_sched_getscheduler((int)pid);
++}
++
++
++/* Note: it is necessary to treat pid as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_sched_setparam(u32 pid, struct sched_param __user *param)
++{
++	return sys_sched_setparam((int)pid, param);
++}
++
++
++/* Note: it is necessary to treat pid and policy as unsigned ints,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param)
++{
++	return sys_sched_setscheduler((int)pid, (int)policy, param);
++}
++
++
++/* Note: it is necessary to treat len as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_setdomainname(char __user *name, u32 len)
++{
++	return sys_setdomainname(name, (int)len);
++}
++
++
++/* Note: it is necessary to treat gidsetsize as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_setgroups(u32 gidsetsize, gid_t __user *grouplist)
++{
++	return sys_setgroups((int)gidsetsize, grouplist);
++}
++
++
++asmlinkage long compat_sys_sethostname(char __user *name, u32 len)
++{
++	/* sign extend len */
++	return sys_sethostname(name, (int)len);
++}
++
++
++/* Note: it is necessary to treat pid and pgid as unsigned ints,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_setpgid(u32 pid, u32 pgid)
++{
++	return sys_setpgid((int)pid, (int)pgid);
++}
++
++long compat_sys_getpriority(u32 which, u32 who)
++{
++	/* sign extend which and who */
++	return sys_getpriority((int)which, (int)who);
++}
++
++long compat_sys_setpriority(u32 which, u32 who, u32 niceval)
++{
++	/* sign extend which, who and niceval */
++	return sys_setpriority((int)which, (int)who, (int)niceval);
++}
++
++long compat_sys_ioprio_get(u32 which, u32 who)
++{
++	/* sign extend which and who */
++	return sys_ioprio_get((int)which, (int)who);
++}
++
++long compat_sys_ioprio_set(u32 which, u32 who, u32 ioprio)
++{
++	/* sign extend which, who and ioprio */
++	return sys_ioprio_set((int)which, (int)who, (int)ioprio);
++}
++
++/* Note: it is necessary to treat newmask as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_ssetmask(u32 newmask)
++{
++	return sys_ssetmask((int) newmask);
++}
++
++asmlinkage long compat_sys_syslog(u32 type, char __user * buf, u32 len)
++{
++	/* sign extend len */
++	return sys_syslog(type, buf, (int)len);
++}
++
++
++/* Note: it is necessary to treat mask as an unsigned int,
++ * with the corresponding cast to a signed int to insure that the 
++ * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
++ * and the register representation of a signed int (msr in 64-bit mode) is performed.
++ */
++asmlinkage long compat_sys_umask(u32 mask)
++{
++	return sys_umask((int)mask);
++}
++
++#ifdef CONFIG_SYSCTL
++struct __sysctl_args32 {
++	u32 name;
++	int nlen;
++	u32 oldval;
++	u32 oldlenp;
++	u32 newval;
++	u32 newlen;
++	u32 __unused[4];
++};
++
++asmlinkage long compat_sys_sysctl(struct __sysctl_args32 __user *args)
++{
++	struct __sysctl_args32 tmp;
++	int error;
++	size_t oldlen;
++	size_t __user *oldlenp = NULL;
++	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
++
++	if (copy_from_user(&tmp, args, sizeof(tmp)))
++		return -EFAULT;
++
++	if (tmp.oldval && tmp.oldlenp) {
++		/* Duh, this is ugly and might not work if sysctl_args
++		   is in read-only memory, but do_sysctl does indirectly
++		   a lot of uaccess in both directions and we'd have to
++		   basically copy the whole sysctl.c here, and
++		   glibc's __sysctl uses rw memory for the structure
++		   anyway.  */
++		oldlenp = (size_t __user *)addr;
++		if (get_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) ||
++		    put_user(oldlen, oldlenp))
++			return -EFAULT;
++	}
++
++	lock_kernel();
++	error = do_sysctl(compat_ptr(tmp.name), tmp.nlen,
++			  compat_ptr(tmp.oldval), oldlenp,
++			  compat_ptr(tmp.newval), tmp.newlen);
++	unlock_kernel();
++	if (oldlenp) {
++		if (!error) {
++			if (get_user(oldlen, oldlenp) ||
++			    put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)))
++				error = -EFAULT;
++		}
++		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
++	}
++	return error;
++}
++#endif
++
++unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
++			  unsigned long prot, unsigned long flags,
++			  unsigned long fd, unsigned long pgoff)
++{
++	/* This should remain 12 even if PAGE_SIZE changes */
++	return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
++}
++
++long compat_sys_tgkill(u32 tgid, u32 pid, int sig)
++{
++	/* sign extend tgid, pid */
++	return sys_tgkill((int)tgid, (int)pid, sig);
++}
++
++/* 
++ * long long munging:
++ * The 32 bit ABI passes long longs in an odd even register pair.
++ */
++
++compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
++			     u32 reg6, u32 poshi, u32 poslo)
++{
++	return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
++}
++
++compat_ssize_t compat_sys_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count,
++			      u32 reg6, u32 poshi, u32 poslo)
++{
++	return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
++}
++
++compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
++{
++	return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count);
++}
++
++asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4,
++				unsigned long high, unsigned long low)
++{
++	return sys_truncate(path, (high << 32) | low);
++}
++
++asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high,
++				 unsigned long low)
++{
++	return sys_ftruncate(fd, (high << 32) | low);
++}
++
++long ppc32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf,
++			  size_t len)
++{
++	return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
++				  buf, len);
++}
++
++long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low,
++		     size_t len, int advice)
++{
++	return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, len,
++			     advice);
++}
++
++long ppc32_timer_create(clockid_t clock,
++			struct compat_sigevent __user *ev32,
++			timer_t __user *timer_id)
++{
++	sigevent_t event;
++	timer_t t;
++	long err;
++	mm_segment_t savefs;
++
++	if (ev32 == NULL)
++		return sys_timer_create(clock, NULL, timer_id);
++
++	if (get_compat_sigevent(&event, ev32))
++		return -EFAULT;
++
++	if (!access_ok(VERIFY_WRITE, timer_id, sizeof(timer_t)))
++		return -EFAULT;
++
++	savefs = get_fs();
++	set_fs(KERNEL_DS);
++	/* The __user pointer casts are valid due to the set_fs() */
++	err = sys_timer_create(clock,
++		(sigevent_t __user *) &event,
++		(timer_t __user *) &t);
++	set_fs(savefs);
++
++	if (err == 0)
++		err = __put_user(t, timer_id);
++
++	return err;
++}
++
++asmlinkage long compat_sys_add_key(const char __user *_type,
++			      const char __user *_description,
++			      const void __user *_payload,
++			      u32 plen,
++			      u32 ringid)
++{
++	return sys_add_key(_type, _description, _payload, plen, ringid);
++}
++
++asmlinkage long compat_sys_request_key(const char __user *_type,
++				  const char __user *_description,
++				  const char __user *_callout_info,
++				  u32 destringid)
++{
++	return sys_request_key(_type, _description, _callout_info, destringid);
++}
++
+diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/syscalls.c
+@@ -0,0 +1,358 @@
++/*
++ *  Implementation of various system calls for Linux/PowerPC
++ *
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ * Derived from "arch/i386/kernel/sys_i386.c"
++ * Adapted from the i386 version by Gary Thomas
++ * Modified by Cort Dougan (cort at cs.nmt.edu)
++ * and Paul Mackerras (paulus at cs.anu.edu.au).
++ *
++ * This file contains various random system calls that
++ * have a non-standard calling sequence on the Linux/PPC
++ * platform.
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/sched.h>
++#include <linux/syscalls.h>
++#include <linux/mm.h>
++#include <linux/smp.h>
++#include <linux/smp_lock.h>
++#include <linux/sem.h>
++#include <linux/msg.h>
++#include <linux/shm.h>
++#include <linux/stat.h>
++#include <linux/mman.h>
++#include <linux/sys.h>
++#include <linux/ipc.h>
++#include <linux/utsname.h>
++#include <linux/file.h>
++#include <linux/init.h>
++#include <linux/personality.h>
++
++#include <asm/uaccess.h>
++#include <asm/ipc.h>
++#include <asm/semaphore.h>
++#include <asm/time.h>
++#include <asm/unistd.h>
++
++extern unsigned long wall_jiffies;
++
++
++/*
++ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
++ *
++ * This is really horribly ugly.
++ */
++int sys_ipc(uint call, int first, unsigned long second, long third,
++	    void __user *ptr, long fifth)
++{
++	int version, ret;
++
++	version = call >> 16; /* hack for backward compatibility */
++	call &= 0xffff;
++
++	ret = -ENOSYS;
++	switch (call) {
++	case SEMOP:
++		ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
++				      (unsigned)second, NULL);
++		break;
++	case SEMTIMEDOP:
++		ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
++				      (unsigned)second,
++				      (const struct timespec __user *) fifth);
++		break;
++	case SEMGET:
++		ret = sys_semget (first, (int)second, third);
++		break;
++	case SEMCTL: {
++		union semun fourth;
++
++		ret = -EINVAL;
++		if (!ptr)
++			break;
++		if ((ret = get_user(fourth.__pad, (void __user * __user *)ptr)))
++			break;
++		ret = sys_semctl(first, (int)second, third, fourth);
++		break;
++	}
++	case MSGSND:
++		ret = sys_msgsnd(first, (struct msgbuf __user *)ptr,
++				 (size_t)second, third);
++		break;
++	case MSGRCV:
++		switch (version) {
++		case 0: {
++			struct ipc_kludge tmp;
++
++			ret = -EINVAL;
++			if (!ptr)
++				break;
++			if ((ret = copy_from_user(&tmp,
++						(struct ipc_kludge __user *) ptr,
++						sizeof (tmp)) ? -EFAULT : 0))
++				break;
++			ret = sys_msgrcv(first, tmp.msgp, (size_t) second,
++					  tmp.msgtyp, third);
++			break;
++		}
++		default:
++			ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
++					  (size_t)second, fifth, third);
++			break;
++		}
++		break;
++	case MSGGET:
++		ret = sys_msgget((key_t)first, (int)second);
++		break;
++	case MSGCTL:
++		ret = sys_msgctl(first, (int)second,
++				  (struct msqid_ds __user *)ptr);
++		break;
++	case SHMAT: {
++		ulong raddr;
++		ret = do_shmat(first, (char __user *)ptr, (int)second, &raddr);
++		if (ret)
++			break;
++		ret = put_user(raddr, (ulong __user *) third);
++		break;
++	}
++	case SHMDT:
++		ret = sys_shmdt((char __user *)ptr);
++		break;
++	case SHMGET:
++		ret = sys_shmget(first, (size_t)second, third);
++		break;
++	case SHMCTL:
++		ret = sys_shmctl(first, (int)second,
++				 (struct shmid_ds __user *)ptr);
++		break;
++	}
++
++	return ret;
++}
++
++/*
++ * sys_pipe() is the normal C calling standard for creating
++ * a pipe. It's not the way unix traditionally does this, though.
++ */
++int sys_pipe(int __user *fildes)
++{
++	int fd[2];
++	int error;
++
++	error = do_pipe(fd);
++	if (!error) {
++		if (copy_to_user(fildes, fd, 2*sizeof(int)))
++			error = -EFAULT;
++	}
++	return error;
++}
++
++static inline unsigned long do_mmap2(unsigned long addr, size_t len,
++			unsigned long prot, unsigned long flags,
++			unsigned long fd, unsigned long off, int shift)
++{
++	struct file * file = NULL;
++	unsigned long ret = -EINVAL;
++
++	if (shift) {
++		if (off & ((1 << shift) - 1))
++			goto out;
++		off >>= shift;
++	}
++		
++	ret = -EBADF;
++	if (!(flags & MAP_ANONYMOUS)) {
++		if (!(file = fget(fd)))
++			goto out;
++	}
++
++	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++	down_write(&current->mm->mmap_sem);
++	ret = do_mmap_pgoff(file, addr, len, prot, flags, off);
++	up_write(&current->mm->mmap_sem);
++	if (file)
++		fput(file);
++out:
++	return ret;
++}
++
++unsigned long sys_mmap2(unsigned long addr, size_t len,
++			unsigned long prot, unsigned long flags,
++			unsigned long fd, unsigned long pgoff)
++{
++	return do_mmap2(addr, len, prot, flags, fd, pgoff, PAGE_SHIFT-12);
++}
++
++unsigned long sys_mmap(unsigned long addr, size_t len,
++		       unsigned long prot, unsigned long flags,
++		       unsigned long fd, off_t offset)
++{
++	return do_mmap2(addr, len, prot, flags, fd, offset, PAGE_SHIFT);
++}
++
++#ifdef CONFIG_PPC32
++/*
++ * Due to some executables calling the wrong select we sometimes
++ * get wrong args.  This determines how the args are being passed
++ * (a single ptr to them all args passed) then calls
++ * sys_select() with the appropriate args. -- Cort
++ */
++int
++ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp)
++{
++	if ( (unsigned long)n >= 4096 )
++	{
++		unsigned long __user *buffer = (unsigned long __user *)n;
++		if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long))
++		    || __get_user(n, buffer)
++		    || __get_user(inp, ((fd_set __user * __user *)(buffer+1)))
++		    || __get_user(outp, ((fd_set  __user * __user *)(buffer+2)))
++		    || __get_user(exp, ((fd_set  __user * __user *)(buffer+3)))
++		    || __get_user(tvp, ((struct timeval  __user * __user *)(buffer+4))))
++			return -EFAULT;
++	}
++	return sys_select(n, inp, outp, exp, tvp);
++}
++#endif
++
++#ifdef CONFIG_PPC64
++long ppc64_personality(unsigned long personality)
++{
++	long ret;
++
++	if (personality(current->personality) == PER_LINUX32
++	    && personality == PER_LINUX)
++		personality = PER_LINUX32;
++	ret = sys_personality(personality);
++	if (ret == PER_LINUX32)
++		ret = PER_LINUX;
++	return ret;
++}
++#endif
++
++#ifdef CONFIG_PPC64
++#define OVERRIDE_MACHINE    (personality(current->personality) == PER_LINUX32)
++#else
++#define OVERRIDE_MACHINE    0
++#endif
++
++static inline int override_machine(char *mach)
++{
++	if (OVERRIDE_MACHINE) {
++		/* change ppc64 to ppc */
++		if (__put_user(0, mach+3) || __put_user(0, mach+4))
++			return -EFAULT;
++	}
++	return 0;
++}
++
++long ppc_newuname(struct new_utsname __user * name)
++{
++	int err = 0;
++
++	down_read(&uts_sem);
++	if (copy_to_user(name, &system_utsname, sizeof(*name)))
++		err = -EFAULT;
++	up_read(&uts_sem);
++	if (!err)
++		err = override_machine(name->machine);
++	return err;
++}
++
++int sys_uname(struct old_utsname __user *name)
++{
++	int err = 0;
++	
++	down_read(&uts_sem);
++	if (copy_to_user(name, &system_utsname, sizeof(*name)))
++		err = -EFAULT;
++	up_read(&uts_sem);
++	if (!err)
++		err = override_machine(name->machine);
++	return err;
++}
++
++int sys_olduname(struct oldold_utsname __user *name)
++{
++	int error;
++
++	if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
++		return -EFAULT;
++  
++	down_read(&uts_sem);
++	error = __copy_to_user(&name->sysname, &system_utsname.sysname,
++			       __OLD_UTS_LEN);
++	error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
++	error |= __copy_to_user(&name->nodename, &system_utsname.nodename,
++				__OLD_UTS_LEN);
++	error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
++	error |= __copy_to_user(&name->release, &system_utsname.release,
++				__OLD_UTS_LEN);
++	error |= __put_user(0, name->release + __OLD_UTS_LEN);
++	error |= __copy_to_user(&name->version, &system_utsname.version,
++				__OLD_UTS_LEN);
++	error |= __put_user(0, name->version + __OLD_UTS_LEN);
++	error |= __copy_to_user(&name->machine, &system_utsname.machine,
++				__OLD_UTS_LEN);
++	error |= override_machine(name->machine);
++	up_read(&uts_sem);
++
++	return error? -EFAULT: 0;
++}
++
++#ifdef CONFIG_PPC64
++time_t sys64_time(time_t __user * tloc)
++{
++	time_t secs;
++	time_t usecs;
++
++	long tb_delta = tb_ticks_since(tb_last_stamp);
++	tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
++
++	secs  = xtime.tv_sec;  
++	usecs = (xtime.tv_nsec/1000) + tb_delta / tb_ticks_per_usec;
++	while (usecs >= USEC_PER_SEC) {
++		++secs;
++		usecs -= USEC_PER_SEC;
++	}
++
++	if (tloc) {
++		if (put_user(secs,tloc))
++			secs = -EFAULT;
++	}
++
++	return secs;
++}
++#endif
++
++long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
++		      u32 len_high, u32 len_low)
++{
++	return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low,
++			     (u64)len_high << 32 | len_low, advice);
++}
++
++void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5,
++		     unsigned long r6, unsigned long r7, unsigned long r8,
++		     struct pt_regs *regs)
++{
++	printk("syscall %ld(%lx, %lx, %lx, %lx, %lx, %lx) regs=%p current=%p"
++	       " cpu=%d\n", regs->gpr[0], r3, r4, r5, r6, r7, r8, regs,
++	       current, smp_processor_id());
++}
++
++void do_show_syscall_exit(unsigned long r3)
++{
++	printk(" -> %lx, current=%p cpu=%d\n", r3, current, smp_processor_id());
++}
+diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/systbl.S
+@@ -0,0 +1,321 @@
++/*
++ * This file contains the table of syscall-handling functions.
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ * Largely rewritten by Cort Dougan (cort at cs.nmt.edu)
++ * and Paul Mackerras.
++ *
++ * Adapted for iSeries by Mike Corrigan (mikejc at us.ibm.com)
++ * PPC64 updates by Dave Engebretsen (engebret at 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 <linux/config.h>
++#include <asm/ppc_asm.h>
++
++#ifdef CONFIG_PPC64
++#define SYSCALL(func)		.llong	.sys_##func,.sys_##func
++#define COMPAT_SYS(func)	.llong	.sys_##func,.compat_sys_##func
++#define PPC_SYS(func)		.llong	.ppc_##func,.ppc_##func
++#define OLDSYS(func)		.llong	.sys_ni_syscall,.sys_ni_syscall
++#define SYS32ONLY(func)		.llong	.sys_ni_syscall,.compat_sys_##func
++#define SYSX(f, f3264, f32)	.llong	.f,.f3264
++#else
++#define SYSCALL(func)		.long	sys_##func
++#define COMPAT_SYS(func)	.long	sys_##func
++#define PPC_SYS(func)		.long	ppc_##func
++#define OLDSYS(func)		.long	sys_##func
++#define SYS32ONLY(func)		.long	sys_##func
++#define SYSX(f, f3264, f32)	.long	f32
++#endif
++
++#ifdef CONFIG_PPC64
++#define sys_sigpending	sys_ni_syscall
++#define sys_old_getrlimit sys_ni_syscall
++#else
++#define ppc_rtas	sys_ni_syscall
++#endif
++
++_GLOBAL(sys_call_table)
++SYSCALL(restart_syscall)
++SYSCALL(exit)
++PPC_SYS(fork)
++SYSCALL(read)
++SYSCALL(write)
++COMPAT_SYS(open)
++SYSCALL(close)
++COMPAT_SYS(waitpid)
++COMPAT_SYS(creat)
++SYSCALL(link)
++SYSCALL(unlink)
++COMPAT_SYS(execve)
++SYSCALL(chdir)
++SYSX(sys64_time,compat_sys_time,sys_time)
++SYSCALL(mknod)
++SYSCALL(chmod)
++SYSCALL(lchown)
++SYSCALL(ni_syscall)
++OLDSYS(stat)
++SYSX(sys_lseek,ppc32_lseek,sys_lseek)
++SYSCALL(getpid)
++COMPAT_SYS(mount)
++SYSX(sys_ni_syscall,sys_oldumount,sys_oldumount)
++SYSCALL(setuid)
++SYSCALL(getuid)
++COMPAT_SYS(stime)
++COMPAT_SYS(ptrace)
++SYSCALL(alarm)
++OLDSYS(fstat)
++COMPAT_SYS(pause)
++COMPAT_SYS(utime)
++SYSCALL(ni_syscall)
++SYSCALL(ni_syscall)
++COMPAT_SYS(access)
++COMPAT_SYS(nice)
++SYSCALL(ni_syscall)
++SYSCALL(sync)
++COMPAT_SYS(kill)
++SYSCALL(rename)
++COMPAT_SYS(mkdir)
++SYSCALL(rmdir)
++SYSCALL(dup)
++SYSCALL(pipe)
++COMPAT_SYS(times)
++SYSCALL(ni_syscall)
++SYSCALL(brk)
++SYSCALL(setgid)
++SYSCALL(getgid)
++SYSCALL(signal)
++SYSCALL(geteuid)
++SYSCALL(getegid)
++SYSCALL(acct)
++SYSCALL(umount)
++SYSCALL(ni_syscall)
++COMPAT_SYS(ioctl)
++COMPAT_SYS(fcntl)
++SYSCALL(ni_syscall)
++COMPAT_SYS(setpgid)
++SYSCALL(ni_syscall)
++SYSX(sys_ni_syscall,sys_olduname, sys_olduname)
++COMPAT_SYS(umask)
++SYSCALL(chroot)
++SYSCALL(ustat)
++SYSCALL(dup2)
++SYSCALL(getppid)
++SYSCALL(getpgrp)
++SYSCALL(setsid)
++SYS32ONLY(sigaction)
++SYSCALL(sgetmask)
++COMPAT_SYS(ssetmask)
++SYSCALL(setreuid)
++SYSCALL(setregid)
++SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend)
++COMPAT_SYS(sigpending)
++COMPAT_SYS(sethostname)
++COMPAT_SYS(setrlimit)
++COMPAT_SYS(old_getrlimit)
++COMPAT_SYS(getrusage)
++COMPAT_SYS(gettimeofday)
++COMPAT_SYS(settimeofday)
++COMPAT_SYS(getgroups)
++COMPAT_SYS(setgroups)
++SYSX(sys_ni_syscall,sys_ni_syscall,ppc_select)
++SYSCALL(symlink)
++OLDSYS(lstat)
++COMPAT_SYS(readlink)
++SYSCALL(uselib)
++SYSCALL(swapon)
++SYSCALL(reboot)
++SYSX(sys_ni_syscall,old32_readdir,old_readdir)
++SYSCALL(mmap)
++SYSCALL(munmap)
++SYSCALL(truncate)
++SYSCALL(ftruncate)
++SYSCALL(fchmod)
++SYSCALL(fchown)
++COMPAT_SYS(getpriority)
++COMPAT_SYS(setpriority)
++SYSCALL(ni_syscall)
++COMPAT_SYS(statfs)
++COMPAT_SYS(fstatfs)
++SYSCALL(ni_syscall)
++COMPAT_SYS(socketcall)
++COMPAT_SYS(syslog)
++COMPAT_SYS(setitimer)
++COMPAT_SYS(getitimer)
++COMPAT_SYS(newstat)
++COMPAT_SYS(newlstat)
++COMPAT_SYS(newfstat)
++SYSX(sys_ni_syscall,sys_uname,sys_uname)
++SYSCALL(ni_syscall)
++SYSCALL(vhangup)
++SYSCALL(ni_syscall)
++SYSCALL(ni_syscall)
++COMPAT_SYS(wait4)
++SYSCALL(swapoff)
++COMPAT_SYS(sysinfo)
++COMPAT_SYS(ipc)
++SYSCALL(fsync)
++SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn)
++PPC_SYS(clone)
++COMPAT_SYS(setdomainname)
++PPC_SYS(newuname)
++SYSCALL(ni_syscall)
++COMPAT_SYS(adjtimex)
++SYSCALL(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(getpgid)
++SYSCALL(fchdir)
++SYSCALL(bdflush)
++COMPAT_SYS(sysfs)
++SYSX(ppc64_personality,ppc64_personality,sys_personality)
++SYSCALL(ni_syscall)
++SYSCALL(setfsuid)
++SYSCALL(setfsgid)
++SYSCALL(llseek)
++COMPAT_SYS(getdents)
++SYSX(sys_select,ppc32_select,ppc_select)
++SYSCALL(flock)
++SYSCALL(msync)
++COMPAT_SYS(readv)
++COMPAT_SYS(writev)
++COMPAT_SYS(getsid)
++SYSCALL(fdatasync)
++COMPAT_SYS(sysctl)
++SYSCALL(mlock)
++SYSCALL(munlock)
++SYSCALL(mlockall)
++SYSCALL(munlockall)
++COMPAT_SYS(sched_setparam)
++COMPAT_SYS(sched_getparam)
++COMPAT_SYS(sched_setscheduler)
++COMPAT_SYS(sched_getscheduler)
++SYSCALL(sched_yield)
++COMPAT_SYS(sched_get_priority_max)
++COMPAT_SYS(sched_get_priority_min)
++COMPAT_SYS(sched_rr_get_interval)
++COMPAT_SYS(nanosleep)
++SYSCALL(mremap)
++SYSCALL(setresuid)
++SYSCALL(getresuid)
++SYSCALL(ni_syscall)
++SYSCALL(poll)
++COMPAT_SYS(nfsservctl)
++SYSCALL(setresgid)
++SYSCALL(getresgid)
++COMPAT_SYS(prctl)
++SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn)
++COMPAT_SYS(rt_sigaction)
++COMPAT_SYS(rt_sigprocmask)
++COMPAT_SYS(rt_sigpending)
++COMPAT_SYS(rt_sigtimedwait)
++COMPAT_SYS(rt_sigqueueinfo)
++SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend)
++COMPAT_SYS(pread64)
++COMPAT_SYS(pwrite64)
++SYSCALL(chown)
++SYSCALL(getcwd)
++SYSCALL(capget)
++SYSCALL(capset)
++COMPAT_SYS(sigaltstack)
++SYSX(sys_sendfile64,compat_sys_sendfile,sys_sendfile)
++SYSCALL(ni_syscall)
++SYSCALL(ni_syscall)
++PPC_SYS(vfork)
++COMPAT_SYS(getrlimit)
++COMPAT_SYS(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)
++COMPAT_SYS(pciconfig_read)
++COMPAT_SYS(pciconfig_write)
++COMPAT_SYS(pciconfig_iobase)
++SYSCALL(ni_syscall)
++SYSCALL(getdents64)
++SYSCALL(pivot_root)
++SYSX(sys_ni_syscall,compat_sys_fcntl64,sys_fcntl64)
++SYSCALL(madvise)
++SYSCALL(mincore)
++SYSCALL(gettid)
++SYSCALL(tkill)
++SYSCALL(setxattr)
++SYSCALL(lsetxattr)
++SYSCALL(fsetxattr)
++SYSCALL(getxattr)
++SYSCALL(lgetxattr)
++SYSCALL(fgetxattr)
++SYSCALL(listxattr)
++SYSCALL(llistxattr)
++SYSCALL(flistxattr)
++SYSCALL(removexattr)
++SYSCALL(lremovexattr)
++SYSCALL(fremovexattr)
++COMPAT_SYS(futex)
++COMPAT_SYS(sched_setaffinity)
++COMPAT_SYS(sched_getaffinity)
++SYSCALL(ni_syscall)
++SYSCALL(ni_syscall)
++SYS32ONLY(sendfile64)
++COMPAT_SYS(io_setup)
++SYSCALL(io_destroy)
++COMPAT_SYS(io_getevents)
++COMPAT_SYS(io_submit)
++SYSCALL(io_cancel)
++SYSCALL(set_tid_address)
++SYSX(sys_fadvise64,ppc32_fadvise64,sys_fadvise64)
++SYSCALL(exit_group)
++SYSX(sys_lookup_dcookie,ppc32_lookup_dcookie,sys_lookup_dcookie)
++SYSCALL(epoll_create)
++SYSCALL(epoll_ctl)
++SYSCALL(epoll_wait)
++SYSCALL(remap_file_pages)
++SYSX(sys_timer_create,ppc32_timer_create,sys_timer_create)
++COMPAT_SYS(timer_settime)
++COMPAT_SYS(timer_gettime)
++SYSCALL(timer_getoverrun)
++SYSCALL(timer_delete)
++COMPAT_SYS(clock_settime)
++COMPAT_SYS(clock_gettime)
++COMPAT_SYS(clock_getres)
++COMPAT_SYS(clock_nanosleep)
++SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext)
++COMPAT_SYS(tgkill)
++COMPAT_SYS(utimes)
++COMPAT_SYS(statfs64)
++COMPAT_SYS(fstatfs64)
++SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64)
++PPC_SYS(rtas)
++OLDSYS(debug_setcontext)
++SYSCALL(ni_syscall)
++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)
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/time.c
+@@ -0,0 +1,1005 @@
++/*
++ * Common time routines among all ppc machines.
++ *
++ * Written by Cort Dougan (cort at cs.nmt.edu) to merge
++ * Paul Mackerras' version and mine for PReP and Pmac.
++ * MPC8xx/MBX changes by Dan Malek (dmalek at jlc.net).
++ * Converted for 64-bit by Mike Corrigan (mikejc at us.ibm.com)
++ *
++ * First round of bugfixes by Gabriel Paubert (paubert at iram.es)
++ * to make clock more stable (2.4.0-test5). The only thing
++ * that this code assumes is that the timebases have been synchronized
++ * by firmware on SMP and are never stopped (never do sleep
++ * on SMP then, nap and doze are OK).
++ * 
++ * Speeded up do_gettimeofday by getting rid of references to
++ * xtime (which required locks for consistency). (mikejc at us.ibm.com)
++ *
++ * TODO (not necessarily in this file):
++ * - improve precision and reproducibility of timebase frequency
++ * measurement at boot time. (for iSeries, we calibrate the timebase
++ * against the Titan chip's clock.)
++ * - for astronomical applications: add a new function to get
++ * non ambiguous timestamps even around leap seconds. This needs
++ * a new timestamp format and a good name.
++ *
++ * 1997-09-10  Updated NTP code according to technical memorandum Jan '96
++ *             "A Kernel Model for Precision Timekeeping" by Dave Mills
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/errno.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/param.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/interrupt.h>
++#include <linux/timex.h>
++#include <linux/kernel_stat.h>
++#include <linux/time.h>
++#include <linux/init.h>
++#include <linux/profile.h>
++#include <linux/cpu.h>
++#include <linux/security.h>
++#include <linux/percpu.h>
++#include <linux/rtc.h>
++
++#include <asm/io.h>
++#include <asm/processor.h>
++#include <asm/nvram.h>
++#include <asm/cache.h>
++#include <asm/machdep.h>
++#include <asm/uaccess.h>
++#include <asm/time.h>
++#include <asm/prom.h>
++#include <asm/irq.h>
++#include <asm/div64.h>
++#ifdef CONFIG_PPC64
++#include <asm/systemcfg.h>
++#include <asm/firmware.h>
++#endif
++#ifdef CONFIG_PPC_ISERIES
++#include <asm/iSeries/ItLpQueue.h>
++#include <asm/iSeries/HvCallXm.h>
++#endif
++
++/* keep track of when we need to update the rtc */
++time_t last_rtc_update;
++extern int piranha_simulator;
++#ifdef CONFIG_PPC_ISERIES
++unsigned long iSeries_recal_titan = 0;
++unsigned long iSeries_recal_tb = 0; 
++static unsigned long first_settimeofday = 1;
++#endif
++
++/* The decrementer counts down by 128 every 128ns on a 601. */
++#define DECREMENTER_COUNT_601	(1000000000 / HZ)
++
++#define XSEC_PER_SEC (1024*1024)
++
++#ifdef CONFIG_PPC64
++#define SCALE_XSEC(xsec, max)	(((xsec) * max) / XSEC_PER_SEC)
++#else
++/* compute ((xsec << 12) * max) >> 32 */
++#define SCALE_XSEC(xsec, max)	mulhwu((xsec) << 12, max)
++#endif
++
++unsigned long tb_ticks_per_jiffy;
++unsigned long tb_ticks_per_usec = 100; /* sane default */
++EXPORT_SYMBOL(tb_ticks_per_usec);
++unsigned long tb_ticks_per_sec;
++u64 tb_to_xs;
++unsigned tb_to_us;
++unsigned long processor_freq;
++DEFINE_SPINLOCK(rtc_lock);
++EXPORT_SYMBOL_GPL(rtc_lock);
++
++u64 tb_to_ns_scale;
++unsigned tb_to_ns_shift;
++
++struct gettimeofday_struct do_gtod;
++
++extern unsigned long wall_jiffies;
++
++extern struct timezone sys_tz;
++static long timezone_offset;
++
++void ppc_adjtimex(void);
++
++static unsigned adjusting_time = 0;
++
++unsigned long ppc_proc_freq;
++unsigned long ppc_tb_freq;
++
++#ifdef CONFIG_PPC32	/* XXX for now */
++#define boot_cpuid	0
++#endif
++
++u64 tb_last_jiffy __cacheline_aligned_in_smp;
++unsigned long tb_last_stamp;
++
++/*
++ * Note that on ppc32 this only stores the bottom 32 bits of
++ * the timebase value, but that's enough to tell when a jiffy
++ * has passed.
++ */
++DEFINE_PER_CPU(unsigned long, last_jiffy);
++
++static __inline__ void timer_check_rtc(void)
++{
++        /*
++         * update the rtc when needed, this should be performed on the
++         * right fraction of a second. Half or full second ?
++         * Full second works on mk48t59 clocks, others need testing.
++         * Note that this update is basically only used through 
++         * the adjtimex system calls. Setting the HW clock in
++         * any other way is a /dev/rtc and userland business.
++         * This is still wrong by -0.5/+1.5 jiffies because of the
++         * timer interrupt resolution and possible delay, but here we 
++         * hit a quantization limit which can only be solved by higher
++         * resolution timers and decoupling time management from timer
++         * interrupts. This is also wrong on the clocks
++         * which require being written at the half second boundary.
++         * We should have an rtc call that only sets the minutes and
++         * seconds like on Intel to avoid problems with non UTC clocks.
++         */
++        if (ppc_md.set_rtc_time && ntp_synced() &&
++	    xtime.tv_sec - last_rtc_update >= 659 &&
++	    abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ &&
++	    jiffies - wall_jiffies == 1) {
++		struct rtc_time tm;
++		to_tm(xtime.tv_sec + 1 + timezone_offset, &tm);
++		tm.tm_year -= 1900;
++		tm.tm_mon -= 1;
++		if (ppc_md.set_rtc_time(&tm) == 0)
++			last_rtc_update = xtime.tv_sec + 1;
++		else
++			/* Try again one minute later */
++			last_rtc_update += 60;
++        }
++}
++
++/*
++ * This version of gettimeofday has microsecond resolution.
++ */
++static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val)
++{
++	unsigned long sec, usec;
++	u64 tb_ticks, xsec;
++	struct gettimeofday_vars *temp_varp;
++	u64 temp_tb_to_xs, temp_stamp_xsec;
++
++	/*
++	 * These calculations are faster (gets rid of divides)
++	 * if done in units of 1/2^20 rather than microseconds.
++	 * The conversion to microseconds at the end is done
++	 * without a divide (and in fact, without a multiply)
++	 */
++	temp_varp = do_gtod.varp;
++	tb_ticks = tb_val - temp_varp->tb_orig_stamp;
++	temp_tb_to_xs = temp_varp->tb_to_xs;
++	temp_stamp_xsec = temp_varp->stamp_xsec;
++	xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs);
++	sec = xsec / XSEC_PER_SEC;
++	usec = (unsigned long)xsec & (XSEC_PER_SEC - 1);
++	usec = SCALE_XSEC(usec, 1000000);
++
++	tv->tv_sec = sec;
++	tv->tv_usec = usec;
++}
++
++void do_gettimeofday(struct timeval *tv)
++{
++	if (__USE_RTC()) {
++		/* do this the old way */
++		unsigned long flags, seq;
++		unsigned int sec, nsec, usec, lost;
++
++		do {
++			seq = read_seqbegin_irqsave(&xtime_lock, flags);
++			sec = xtime.tv_sec;
++			nsec = xtime.tv_nsec + tb_ticks_since(tb_last_stamp);
++			lost = jiffies - wall_jiffies;
++		} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
++		usec = nsec / 1000 + lost * (1000000 / HZ);
++		while (usec >= 1000000) {
++			usec -= 1000000;
++			++sec;
++		}
++		tv->tv_sec = sec;
++		tv->tv_usec = usec;
++		return;
++	}
++	__do_gettimeofday(tv, get_tb());
++}
++
++EXPORT_SYMBOL(do_gettimeofday);
++
++/* Synchronize xtime with do_gettimeofday */ 
++
++static inline void timer_sync_xtime(unsigned long cur_tb)
++{
++#ifdef CONFIG_PPC64
++	/* why do we do this? */
++	struct timeval my_tv;
++
++	__do_gettimeofday(&my_tv, cur_tb);
++
++	if (xtime.tv_sec <= my_tv.tv_sec) {
++		xtime.tv_sec = my_tv.tv_sec;
++		xtime.tv_nsec = my_tv.tv_usec * 1000;
++	}
++#endif
++}
++
++/*
++ * There are two copies of tb_to_xs and stamp_xsec so that no
++ * lock is needed to access and use these values in
++ * do_gettimeofday.  We alternate the copies and as long as a
++ * reasonable time elapses between changes, there will never
++ * be inconsistent values.  ntpd has a minimum of one minute
++ * between updates.
++ */
++static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
++			       u64 new_tb_to_xs)
++{
++	unsigned temp_idx;
++	struct gettimeofday_vars *temp_varp;
++
++	temp_idx = (do_gtod.var_idx == 0);
++	temp_varp = &do_gtod.vars[temp_idx];
++
++	temp_varp->tb_to_xs = new_tb_to_xs;
++	temp_varp->tb_orig_stamp = new_tb_stamp;
++	temp_varp->stamp_xsec = new_stamp_xsec;
++	smp_mb();
++	do_gtod.varp = temp_varp;
++	do_gtod.var_idx = temp_idx;
++
++#ifdef CONFIG_PPC64
++	/*
++	 * tb_update_count is used to allow the userspace gettimeofday code
++	 * to assure itself that it sees a consistent view of the tb_to_xs and
++	 * stamp_xsec variables.  It reads the tb_update_count, then reads
++	 * tb_to_xs and stamp_xsec and then reads tb_update_count again.  If
++	 * the two values of tb_update_count match and are even then the
++	 * tb_to_xs and stamp_xsec values are consistent.  If not, then it
++	 * loops back and reads them again until this criteria is met.
++	 */
++	++(systemcfg->tb_update_count);
++	smp_wmb();
++	systemcfg->tb_orig_stamp = new_tb_stamp;
++	systemcfg->stamp_xsec = new_stamp_xsec;
++	systemcfg->tb_to_xs = new_tb_to_xs;
++	smp_wmb();
++	++(systemcfg->tb_update_count);
++#endif
++}
++
++/*
++ * When the timebase - tb_orig_stamp gets too big, we do a manipulation
++ * between tb_orig_stamp and stamp_xsec. The goal here is to keep the
++ * difference tb - tb_orig_stamp small enough to always fit inside a
++ * 32 bits number. This is a requirement of our fast 32 bits userland
++ * implementation in the vdso. If we "miss" a call to this function
++ * (interrupt latency, CPU locked in a spinlock, ...) and we end up
++ * with a too big difference, then the vdso will fallback to calling
++ * the syscall
++ */
++static __inline__ void timer_recalc_offset(u64 cur_tb)
++{
++	unsigned long offset;
++	u64 new_stamp_xsec;
++
++	if (__USE_RTC())
++		return;
++	offset = cur_tb - do_gtod.varp->tb_orig_stamp;
++	if ((offset & 0x80000000u) == 0)
++		return;
++	new_stamp_xsec = do_gtod.varp->stamp_xsec
++		+ mulhdu(offset, do_gtod.varp->tb_to_xs);
++	update_gtod(cur_tb, new_stamp_xsec, do_gtod.varp->tb_to_xs);
++}
++
++#ifdef CONFIG_SMP
++unsigned long profile_pc(struct pt_regs *regs)
++{
++	unsigned long pc = instruction_pointer(regs);
++
++	if (in_lock_functions(pc))
++		return regs->link;
++
++	return pc;
++}
++EXPORT_SYMBOL(profile_pc);
++#endif
++
++#ifdef CONFIG_PPC_ISERIES
++
++/* 
++ * This function recalibrates the timebase based on the 49-bit time-of-day
++ * value in the Titan chip.  The Titan is much more accurate than the value
++ * returned by the service processor for the timebase frequency.  
++ */
++
++static void iSeries_tb_recal(void)
++{
++	struct div_result divres;
++	unsigned long titan, tb;
++	tb = get_tb();
++	titan = HvCallXm_loadTod();
++	if ( iSeries_recal_titan ) {
++		unsigned long tb_ticks = tb - iSeries_recal_tb;
++		unsigned long titan_usec = (titan - iSeries_recal_titan) >> 12;
++		unsigned long new_tb_ticks_per_sec   = (tb_ticks * USEC_PER_SEC)/titan_usec;
++		unsigned long new_tb_ticks_per_jiffy = (new_tb_ticks_per_sec+(HZ/2))/HZ;
++		long tick_diff = new_tb_ticks_per_jiffy - tb_ticks_per_jiffy;
++		char sign = '+';		
++		/* make sure tb_ticks_per_sec and tb_ticks_per_jiffy are consistent */
++		new_tb_ticks_per_sec = new_tb_ticks_per_jiffy * HZ;
++
++		if ( tick_diff < 0 ) {
++			tick_diff = -tick_diff;
++			sign = '-';
++		}
++		if ( tick_diff ) {
++			if ( tick_diff < tb_ticks_per_jiffy/25 ) {
++				printk( "Titan recalibrate: new tb_ticks_per_jiffy = %lu (%c%ld)\n",
++						new_tb_ticks_per_jiffy, sign, tick_diff );
++				tb_ticks_per_jiffy = new_tb_ticks_per_jiffy;
++				tb_ticks_per_sec   = new_tb_ticks_per_sec;
++				div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres );
++				do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
++				tb_to_xs = divres.result_low;
++				do_gtod.varp->tb_to_xs = tb_to_xs;
++				systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
++				systemcfg->tb_to_xs = tb_to_xs;
++			}
++			else {
++				printk( "Titan recalibrate: FAILED (difference > 4 percent)\n"
++					"                   new tb_ticks_per_jiffy = %lu\n"
++					"                   old tb_ticks_per_jiffy = %lu\n",
++					new_tb_ticks_per_jiffy, tb_ticks_per_jiffy );
++			}
++		}
++	}
++	iSeries_recal_titan = titan;
++	iSeries_recal_tb = tb;
++}
++#endif
++
++/*
++ * For iSeries shared processors, we have to let the hypervisor
++ * set the hardware decrementer.  We set a virtual decrementer
++ * in the lppaca and call the hypervisor if the virtual
++ * decrementer is less than the current value in the hardware
++ * decrementer. (almost always the new decrementer value will
++ * be greater than the current hardware decementer so the hypervisor
++ * call will not be needed)
++ */
++
++/*
++ * timer_interrupt - gets called when the decrementer overflows,
++ * with interrupts disabled.
++ */
++void timer_interrupt(struct pt_regs * regs)
++{
++	int next_dec;
++	int cpu = smp_processor_id();
++	unsigned long ticks;
++
++#ifdef CONFIG_PPC32
++	if (atomic_read(&ppc_n_lost_interrupts) != 0)
++		do_IRQ(regs);
++#endif
++
++	irq_enter();
++
++	profile_tick(CPU_PROFILING, regs);
++
++#ifdef CONFIG_PPC_ISERIES
++	get_paca()->lppaca.int_dword.fields.decr_int = 0;
++#endif
++
++	while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))
++	       >= tb_ticks_per_jiffy) {
++		/* Update last_jiffy */
++		per_cpu(last_jiffy, cpu) += tb_ticks_per_jiffy;
++		/* Handle RTCL overflow on 601 */
++		if (__USE_RTC() && per_cpu(last_jiffy, cpu) >= 1000000000)
++			per_cpu(last_jiffy, cpu) -= 1000000000;
++
++		/*
++		 * We cannot disable the decrementer, so in the period
++		 * between this cpu's being marked offline in cpu_online_map
++		 * and calling stop-self, it is taking timer interrupts.
++		 * Avoid calling into the scheduler rebalancing code if this
++		 * is the case.
++		 */
++		if (!cpu_is_offline(cpu))
++			update_process_times(user_mode(regs));
++
++		/*
++		 * No need to check whether cpu is offline here; boot_cpuid
++		 * should have been fixed up by now.
++		 */
++		if (cpu != boot_cpuid)
++			continue;
++
++		write_seqlock(&xtime_lock);
++		tb_last_jiffy += tb_ticks_per_jiffy;
++		tb_last_stamp = per_cpu(last_jiffy, cpu);
++		timer_recalc_offset(tb_last_jiffy);
++		do_timer(regs);
++		timer_sync_xtime(tb_last_jiffy);
++		timer_check_rtc();
++		write_sequnlock(&xtime_lock);
++		if (adjusting_time && (time_adjust == 0))
++			ppc_adjtimex();
++	}
++	
++	next_dec = tb_ticks_per_jiffy - ticks;
++	set_dec(next_dec);
++
++#ifdef CONFIG_PPC_ISERIES
++	if (hvlpevent_is_pending())
++		process_hvlpevents(regs);
++#endif
++
++#ifdef CONFIG_PPC64
++	/* collect purr register values often, for accurate calculations */
++	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
++		struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
++		cu->current_tb = mfspr(SPRN_PURR);
++	}
++#endif
++
++	irq_exit();
++}
++
++void wakeup_decrementer(void)
++{
++	int i;
++
++	set_dec(tb_ticks_per_jiffy);
++	/*
++	 * We don't expect this to be called on a machine with a 601,
++	 * so using get_tbl is fine.
++	 */
++	tb_last_stamp = tb_last_jiffy = get_tb();
++	for_each_cpu(i)
++		per_cpu(last_jiffy, i) = tb_last_stamp;
++}
++
++#ifdef CONFIG_SMP
++void __init smp_space_timers(unsigned int max_cpus)
++{
++	int i;
++	unsigned long offset = tb_ticks_per_jiffy / max_cpus;
++	unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
++
++	for_each_cpu(i) {
++		if (i != boot_cpuid) {
++			previous_tb += offset;
++			per_cpu(last_jiffy, i) = previous_tb;
++		}
++	}
++}
++#endif
++
++/*
++ * Scheduler clock - returns current time in nanosec units.
++ *
++ * Note: mulhdu(a, b) (multiply high double unsigned) returns
++ * the high 64 bits of a * b, i.e. (a * b) >> 64, where a and b
++ * are 64-bit unsigned numbers.
++ */
++unsigned long long sched_clock(void)
++{
++	if (__USE_RTC())
++		return get_rtc();
++	return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift;
++}
++
++int do_settimeofday(struct timespec *tv)
++{
++	time_t wtm_sec, new_sec = tv->tv_sec;
++	long wtm_nsec, new_nsec = tv->tv_nsec;
++	unsigned long flags;
++	long int tb_delta;
++	u64 new_xsec, tb_delta_xs;
++
++	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
++		return -EINVAL;
++
++	write_seqlock_irqsave(&xtime_lock, flags);
++
++	/*
++	 * Updating the RTC is not the job of this code. If the time is
++	 * stepped under NTP, the RTC will be updated after STA_UNSYNC
++	 * is cleared.  Tools like clock/hwclock either copy the RTC
++	 * to the system time, in which case there is no point in writing
++	 * to the RTC again, or write to the RTC but then they don't call
++	 * settimeofday to perform this operation.
++	 */
++#ifdef CONFIG_PPC_ISERIES
++	if (first_settimeofday) {
++		iSeries_tb_recal();
++		first_settimeofday = 0;
++	}
++#endif
++	tb_delta = tb_ticks_since(tb_last_stamp);
++	tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
++	tb_delta_xs = mulhdu(tb_delta, do_gtod.varp->tb_to_xs);
++
++	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec);
++	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec);
++
++ 	set_normalized_timespec(&xtime, new_sec, new_nsec);
++	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
++
++	/* In case of a large backwards jump in time with NTP, we want the 
++	 * clock to be updated as soon as the PLL is again in lock.
++	 */
++	last_rtc_update = new_sec - 658;
++
++	ntp_clear();
++
++	new_xsec = 0;
++	if (new_nsec != 0) {
++		new_xsec = (u64)new_nsec * XSEC_PER_SEC;
++		do_div(new_xsec, NSEC_PER_SEC);
++	}
++	new_xsec += (u64)new_sec * XSEC_PER_SEC - tb_delta_xs;
++	update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
++
++#ifdef CONFIG_PPC64
++	systemcfg->tz_minuteswest = sys_tz.tz_minuteswest;
++	systemcfg->tz_dsttime = sys_tz.tz_dsttime;
++#endif
++
++	write_sequnlock_irqrestore(&xtime_lock, flags);
++	clock_was_set();
++	return 0;
++}
++
++EXPORT_SYMBOL(do_settimeofday);
++
++void __init generic_calibrate_decr(void)
++{
++	struct device_node *cpu;
++	unsigned int *fp;
++	int node_found;
++
++	/*
++	 * The cpu node should have a timebase-frequency property
++	 * to tell us the rate at which the decrementer counts.
++	 */
++	cpu = of_find_node_by_type(NULL, "cpu");
++
++	ppc_tb_freq = DEFAULT_TB_FREQ;		/* hardcoded default */
++	node_found = 0;
++	if (cpu != 0) {
++		fp = (unsigned int *)get_property(cpu, "timebase-frequency",
++						  NULL);
++		if (fp != 0) {
++			node_found = 1;
++			ppc_tb_freq = *fp;
++		}
++	}
++	if (!node_found)
++		printk(KERN_ERR "WARNING: Estimating decrementer frequency "
++				"(not found)\n");
++
++	ppc_proc_freq = DEFAULT_PROC_FREQ;
++	node_found = 0;
++	if (cpu != 0) {
++		fp = (unsigned int *)get_property(cpu, "clock-frequency",
++						  NULL);
++		if (fp != 0) {
++			node_found = 1;
++			ppc_proc_freq = *fp;
++		}
++	}
++#ifdef CONFIG_BOOKE
++	/* Set the time base to zero */
++	mtspr(SPRN_TBWL, 0);
++	mtspr(SPRN_TBWU, 0);
++
++	/* Clear any pending timer interrupts */
++	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
++
++	/* Enable decrementer interrupt */
++	mtspr(SPRN_TCR, TCR_DIE);
++#endif
++	if (!node_found)
++		printk(KERN_ERR "WARNING: Estimating processor frequency "
++				"(not found)\n");
++
++	of_node_put(cpu);
++}
++
++unsigned long get_boot_time(void)
++{
++	struct rtc_time tm;
++
++	if (ppc_md.get_boot_time)
++		return ppc_md.get_boot_time();
++	if (!ppc_md.get_rtc_time)
++		return 0;
++	ppc_md.get_rtc_time(&tm);
++	return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
++		      tm.tm_hour, tm.tm_min, tm.tm_sec);
++}
++
++/* This function is only called on the boot processor */
++void __init time_init(void)
++{
++	unsigned long flags;
++	unsigned long tm = 0;
++	struct div_result res;
++	u64 scale;
++	unsigned shift;
++
++        if (ppc_md.time_init != NULL)
++                timezone_offset = ppc_md.time_init();
++
++	if (__USE_RTC()) {
++		/* 601 processor: dec counts down by 128 every 128ns */
++		ppc_tb_freq = 1000000000;
++		tb_last_stamp = get_rtcl();
++		tb_last_jiffy = tb_last_stamp;
++	} else {
++		/* Normal PowerPC with timebase register */
++		ppc_md.calibrate_decr();
++		printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
++		       ppc_tb_freq / 1000000, ppc_tb_freq % 1000000);
++		printk(KERN_INFO "time_init: processor frequency   = %lu.%.6lu MHz\n",
++		       ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
++		tb_last_stamp = tb_last_jiffy = get_tb();
++	}
++
++	tb_ticks_per_jiffy = ppc_tb_freq / HZ;
++	tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
++	tb_ticks_per_usec = ppc_tb_freq / 1000000;
++	tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
++	div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res);
++	tb_to_xs = res.result_low;
++
++#ifdef CONFIG_PPC64
++	get_paca()->default_decr = tb_ticks_per_jiffy;
++#endif
++
++	/*
++	 * Compute scale factor for sched_clock.
++	 * The calibrate_decr() function has set tb_ticks_per_sec,
++	 * which is the timebase frequency.
++	 * We compute 1e9 * 2^64 / tb_ticks_per_sec and interpret
++	 * the 128-bit result as a 64.64 fixed-point number.
++	 * We then shift that number right until it is less than 1.0,
++	 * giving us the scale factor and shift count to use in
++	 * sched_clock().
++	 */
++	div128_by_32(1000000000, 0, tb_ticks_per_sec, &res);
++	scale = res.result_low;
++	for (shift = 0; res.result_high != 0; ++shift) {
++		scale = (scale >> 1) | (res.result_high << 63);
++		res.result_high >>= 1;
++	}
++	tb_to_ns_scale = scale;
++	tb_to_ns_shift = shift;
++
++#ifdef CONFIG_PPC_ISERIES
++	if (!piranha_simulator)
++#endif
++		tm = get_boot_time();
++
++	write_seqlock_irqsave(&xtime_lock, flags);
++	xtime.tv_sec = tm;
++	xtime.tv_nsec = 0;
++	do_gtod.varp = &do_gtod.vars[0];
++	do_gtod.var_idx = 0;
++	do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
++	__get_cpu_var(last_jiffy) = tb_last_stamp;
++	do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC;
++	do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
++	do_gtod.varp->tb_to_xs = tb_to_xs;
++	do_gtod.tb_to_us = tb_to_us;
++#ifdef CONFIG_PPC64
++	systemcfg->tb_orig_stamp = tb_last_jiffy;
++	systemcfg->tb_update_count = 0;
++	systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
++	systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
++	systemcfg->tb_to_xs = tb_to_xs;
++#endif
++
++	time_freq = 0;
++
++	/* If platform provided a timezone (pmac), we correct the time */
++        if (timezone_offset) {
++		sys_tz.tz_minuteswest = -timezone_offset / 60;
++		sys_tz.tz_dsttime = 0;
++		xtime.tv_sec -= timezone_offset;
++        }
++
++	last_rtc_update = xtime.tv_sec;
++	set_normalized_timespec(&wall_to_monotonic,
++	                        -xtime.tv_sec, -xtime.tv_nsec);
++	write_sequnlock_irqrestore(&xtime_lock, flags);
++
++	/* Not exact, but the timer interrupt takes care of this */
++	set_dec(tb_ticks_per_jiffy);
++}
++
++/* 
++ * After adjtimex is called, adjust the conversion of tb ticks
++ * to microseconds to keep do_gettimeofday synchronized 
++ * with ntpd.
++ *
++ * Use the time_adjust, time_freq and time_offset computed by adjtimex to 
++ * adjust the frequency.
++ */
++
++/* #define DEBUG_PPC_ADJTIMEX 1 */
++
++void ppc_adjtimex(void)
++{
++#ifdef CONFIG_PPC64
++	unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec,
++		new_tb_to_xs, new_xsec, new_stamp_xsec;
++	unsigned long tb_ticks_per_sec_delta;
++	long delta_freq, ltemp;
++	struct div_result divres; 
++	unsigned long flags;
++	long singleshot_ppm = 0;
++
++	/*
++	 * Compute parts per million frequency adjustment to
++	 * accomplish the time adjustment implied by time_offset to be
++	 * applied over the elapsed time indicated by time_constant.
++	 * Use SHIFT_USEC to get it into the same units as
++	 * time_freq.
++	 */
++	if ( time_offset < 0 ) {
++		ltemp = -time_offset;
++		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
++		ltemp >>= SHIFT_KG + time_constant;
++		ltemp = -ltemp;
++	} else {
++		ltemp = time_offset;
++		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
++		ltemp >>= SHIFT_KG + time_constant;
++	}
++	
++	/* If there is a single shot time adjustment in progress */
++	if ( time_adjust ) {
++#ifdef DEBUG_PPC_ADJTIMEX
++		printk("ppc_adjtimex: ");
++		if ( adjusting_time == 0 )
++			printk("starting ");
++		printk("single shot time_adjust = %ld\n", time_adjust);
++#endif	
++	
++		adjusting_time = 1;
++		
++		/*
++		 * Compute parts per million frequency adjustment
++		 * to match time_adjust
++		 */
++		singleshot_ppm = tickadj * HZ;	
++		/*
++		 * The adjustment should be tickadj*HZ to match the code in
++		 * linux/kernel/timer.c, but experiments show that this is too
++		 * large. 3/4 of tickadj*HZ seems about right
++		 */
++		singleshot_ppm -= singleshot_ppm / 4;
++		/* Use SHIFT_USEC to get it into the same units as time_freq */
++		singleshot_ppm <<= SHIFT_USEC;
++		if ( time_adjust < 0 )
++			singleshot_ppm = -singleshot_ppm;
++	}
++	else {
++#ifdef DEBUG_PPC_ADJTIMEX
++		if ( adjusting_time )
++			printk("ppc_adjtimex: ending single shot time_adjust\n");
++#endif
++		adjusting_time = 0;
++	}
++	
++	/* Add up all of the frequency adjustments */
++	delta_freq = time_freq + ltemp + singleshot_ppm;
++	
++	/*
++	 * Compute a new value for tb_ticks_per_sec based on
++	 * the frequency adjustment
++	 */
++	den = 1000000 * (1 << (SHIFT_USEC - 8));
++	if ( delta_freq < 0 ) {
++		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( (-delta_freq) >> (SHIFT_USEC - 8))) / den;
++		new_tb_ticks_per_sec = tb_ticks_per_sec + tb_ticks_per_sec_delta;
++	}
++	else {
++		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( delta_freq >> (SHIFT_USEC - 8))) / den;
++		new_tb_ticks_per_sec = tb_ticks_per_sec - tb_ticks_per_sec_delta;
++	}
++	
++#ifdef DEBUG_PPC_ADJTIMEX
++	printk("ppc_adjtimex: ltemp = %ld, time_freq = %ld, singleshot_ppm = %ld\n", ltemp, time_freq, singleshot_ppm);
++	printk("ppc_adjtimex: tb_ticks_per_sec - base = %ld  new = %ld\n", tb_ticks_per_sec, new_tb_ticks_per_sec);
++#endif
++
++	/*
++	 * Compute a new value of tb_to_xs (used to convert tb to
++	 * microseconds) and a new value of stamp_xsec which is the
++	 * time (in 1/2^20 second units) corresponding to
++	 * tb_orig_stamp.  This new value of stamp_xsec compensates
++	 * for the change in frequency (implied by the new tb_to_xs)
++	 * which guarantees that the current time remains the same.
++	 */
++	write_seqlock_irqsave( &xtime_lock, flags );
++	tb_ticks = get_tb() - do_gtod.varp->tb_orig_stamp;
++	div128_by_32(1024*1024, 0, new_tb_ticks_per_sec, &divres);
++	new_tb_to_xs = divres.result_low;
++	new_xsec = mulhdu(tb_ticks, new_tb_to_xs);
++
++	old_xsec = mulhdu(tb_ticks, do_gtod.varp->tb_to_xs);
++	new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec;
++
++	update_gtod(do_gtod.varp->tb_orig_stamp, new_stamp_xsec, new_tb_to_xs);
++
++	write_sequnlock_irqrestore( &xtime_lock, flags );
++#endif /* CONFIG_PPC64 */
++}
++
++
++#define FEBRUARY	2
++#define	STARTOFTIME	1970
++#define SECDAY		86400L
++#define SECYR		(SECDAY * 365)
++#define	leapyear(year)		((year) % 4 == 0 && \
++				 ((year) % 100 != 0 || (year) % 400 == 0))
++#define	days_in_year(a) 	(leapyear(a) ? 366 : 365)
++#define	days_in_month(a) 	(month_days[(a) - 1])
++
++static int month_days[12] = {
++	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
++};
++
++/*
++ * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
++ */
++void GregorianDay(struct rtc_time * tm)
++{
++	int leapsToDate;
++	int lastYear;
++	int day;
++	int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
++
++	lastYear = tm->tm_year - 1;
++
++	/*
++	 * Number of leap corrections to apply up to end of last year
++	 */
++	leapsToDate = lastYear / 4 - lastYear / 100 + lastYear / 400;
++
++	/*
++	 * This year is a leap year if it is divisible by 4 except when it is
++	 * divisible by 100 unless it is divisible by 400
++	 *
++	 * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 was
++	 */
++	day = tm->tm_mon > 2 && leapyear(tm->tm_year);
++
++	day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
++		   tm->tm_mday;
++
++	tm->tm_wday = day % 7;
++}
++
++void to_tm(int tim, struct rtc_time * tm)
++{
++	register int    i;
++	register long   hms, day;
++
++	day = tim / SECDAY;
++	hms = tim % SECDAY;
++
++	/* Hours, minutes, seconds are easy */
++	tm->tm_hour = hms / 3600;
++	tm->tm_min = (hms % 3600) / 60;
++	tm->tm_sec = (hms % 3600) % 60;
++
++	/* Number of years in days */
++	for (i = STARTOFTIME; day >= days_in_year(i); i++)
++		day -= days_in_year(i);
++	tm->tm_year = i;
++
++	/* Number of months in days left */
++	if (leapyear(tm->tm_year))
++		days_in_month(FEBRUARY) = 29;
++	for (i = 1; day >= days_in_month(i); i++)
++		day -= days_in_month(i);
++	days_in_month(FEBRUARY) = 28;
++	tm->tm_mon = i;
++
++	/* Days are what is left over (+1) from all that. */
++	tm->tm_mday = day + 1;
++
++	/*
++	 * Determine the day of week
++	 */
++	GregorianDay(tm);
++}
++
++/* Auxiliary function to compute scaling factors */
++/* Actually the choice of a timebase running at 1/4 the of the bus
++ * frequency giving resolution of a few tens of nanoseconds is quite nice.
++ * It makes this computation very precise (27-28 bits typically) which
++ * is optimistic considering the stability of most processor clock
++ * oscillators and the precision with which the timebase frequency
++ * is measured but does not harm.
++ */
++unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale)
++{
++        unsigned mlt=0, tmp, err;
++        /* No concern for performance, it's done once: use a stupid
++         * but safe and compact method to find the multiplier.
++         */
++  
++        for (tmp = 1U<<31; tmp != 0; tmp >>= 1) {
++                if (mulhwu(inscale, mlt|tmp) < outscale)
++			mlt |= tmp;
++        }
++  
++        /* We might still be off by 1 for the best approximation.
++         * A side effect of this is that if outscale is too large
++         * the returned value will be zero.
++         * Many corner cases have been checked and seem to work,
++         * some might have been forgotten in the test however.
++         */
++  
++        err = inscale * (mlt+1);
++        if (err <= inscale/2)
++		mlt++;
++        return mlt;
++}
++
++/*
++ * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit
++ * result.
++ */
++void div128_by_32(u64 dividend_high, u64 dividend_low,
++		  unsigned divisor, struct div_result *dr)
++{
++	unsigned long a, b, c, d;
++	unsigned long w, x, y, z;
++	u64 ra, rb, rc;
++
++	a = dividend_high >> 32;
++	b = dividend_high & 0xffffffff;
++	c = dividend_low >> 32;
++	d = dividend_low & 0xffffffff;
++
++	w = a / divisor;
++	ra = ((u64)(a - (w * divisor)) << 32) + b;
++
++	rb = ((u64) do_div(ra, divisor) << 32) + c;
++	x = ra;
++
++	rc = ((u64) do_div(rb, divisor) << 32) + d;
++	y = rb;
++
++	do_div(rc, divisor);
++	z = rc;
++
++	dr->result_high = ((u64)w << 32) + x;
++	dr->result_low  = ((u64)y << 32) + z;
++
++}
+diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/traps.c
+@@ -0,0 +1,1101 @@
++/*
++ *  Copyright (C) 1995-1996  Gary Thomas (gdt at linuxppc.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.
++ *
++ *  Modified by Cort Dougan (cort at cs.nmt.edu)
++ *  and Paul Mackerras (paulus at samba.org)
++ */
++
++/*
++ * This file handles the architecture-dependent parts of hardware exceptions
++ */
++
++#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/stddef.h>
++#include <linux/unistd.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/user.h>
++#include <linux/a.out.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/prctl.h>
++#include <linux/delay.h>
++#include <linux/kprobes.h>
++
++#include <asm/kdebug.h>
++#include <asm/pgtable.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/machdep.h>
++#include <asm/rtas.h>
++#include <asm/xmon.h>
++#include <asm/pmc.h>
++#ifdef CONFIG_PPC32
++#include <asm/reg.h>
++#endif
++#ifdef CONFIG_PMAC_BACKLIGHT
++#include <asm/backlight.h>
++#endif
++#ifdef CONFIG_PPC64
++#include <asm/firmware.h>
++#include <asm/processor.h>
++#include <asm/systemcfg.h>
++#endif
++
++#ifdef CONFIG_PPC64	/* XXX */
++#define _IO_BASE	pci_io_base
++#endif
++
++#ifdef CONFIG_DEBUGGER
++int (*__debugger)(struct pt_regs *regs);
++int (*__debugger_ipi)(struct pt_regs *regs);
++int (*__debugger_bpt)(struct pt_regs *regs);
++int (*__debugger_sstep)(struct pt_regs *regs);
++int (*__debugger_iabr_match)(struct pt_regs *regs);
++int (*__debugger_dabr_match)(struct pt_regs *regs);
++int (*__debugger_fault_handler)(struct pt_regs *regs);
++
++EXPORT_SYMBOL(__debugger);
++EXPORT_SYMBOL(__debugger_ipi);
++EXPORT_SYMBOL(__debugger_bpt);
++EXPORT_SYMBOL(__debugger_sstep);
++EXPORT_SYMBOL(__debugger_iabr_match);
++EXPORT_SYMBOL(__debugger_dabr_match);
++EXPORT_SYMBOL(__debugger_fault_handler);
++#endif
++
++struct notifier_block *powerpc_die_chain;
++static DEFINE_SPINLOCK(die_notifier_lock);
++
++int register_die_notifier(struct notifier_block *nb)
++{
++	int err = 0;
++	unsigned long flags;
++
++	spin_lock_irqsave(&die_notifier_lock, flags);
++	err = notifier_chain_register(&powerpc_die_chain, nb);
++	spin_unlock_irqrestore(&die_notifier_lock, flags);
++	return err;
++}
++
++/*
++ * Trap & Exception support
++ */
++
++static DEFINE_SPINLOCK(die_lock);
++
++int die(const char *str, struct pt_regs *regs, long err)
++{
++	static int die_counter;
++	int nl = 0;
++
++	if (debugger(regs))
++		return 1;
++
++	console_verbose();
++	spin_lock_irq(&die_lock);
++	bust_spinlocks(1);
++#ifdef CONFIG_PMAC_BACKLIGHT
++	if (_machine == _MACH_Pmac) {
++		set_backlight_enable(1);
++		set_backlight_level(BACKLIGHT_MAX);
++	}
++#endif
++	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
++#ifdef CONFIG_PREEMPT
++	printk("PREEMPT ");
++	nl = 1;
++#endif
++#ifdef CONFIG_SMP
++	printk("SMP NR_CPUS=%d ", NR_CPUS);
++	nl = 1;
++#endif
++#ifdef CONFIG_DEBUG_PAGEALLOC
++	printk("DEBUG_PAGEALLOC ");
++	nl = 1;
++#endif
++#ifdef CONFIG_NUMA
++	printk("NUMA ");
++	nl = 1;
++#endif
++#ifdef CONFIG_PPC64
++	switch (systemcfg->platform) {
++	case PLATFORM_PSERIES:
++		printk("PSERIES ");
++		nl = 1;
++		break;
++	case PLATFORM_PSERIES_LPAR:
++		printk("PSERIES LPAR ");
++		nl = 1;
++		break;
++	case PLATFORM_ISERIES_LPAR:
++		printk("ISERIES LPAR ");
++		nl = 1;
++		break;
++	case PLATFORM_POWERMAC:
++		printk("POWERMAC ");
++		nl = 1;
++		break;
++	case PLATFORM_BPA:
++		printk("BPA ");
++		nl = 1;
++		break;
++	}
++#endif
++	if (nl)
++		printk("\n");
++	print_modules();
++	show_regs(regs);
++	bust_spinlocks(0);
++	spin_unlock_irq(&die_lock);
++
++	if (in_interrupt())
++		panic("Fatal exception in interrupt");
++
++	if (panic_on_oops) {
++#ifdef CONFIG_PPC64
++		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
++		ssleep(5);
++#endif
++		panic("Fatal exception");
++	}
++	do_exit(err);
++
++	return 0;
++}
++
++void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
++{
++	siginfo_t info;
++
++	if (!user_mode(regs)) {
++		if (die("Exception in kernel mode", regs, signr))
++			return;
++	}
++
++	memset(&info, 0, sizeof(info));
++	info.si_signo = signr;
++	info.si_code = code;
++	info.si_addr = (void __user *) addr;
++	force_sig_info(signr, &info, current);
++
++	/*
++	 * Init gets no signals that it doesn't have a handler for.
++	 * That's all very well, but if it has caused a synchronous
++	 * exception and we ignore the resulting signal, it will just
++	 * generate the same exception over and over again and we get
++	 * nowhere.  Better to kill it and let the kernel panic.
++	 */
++	if (current->pid == 1) {
++		__sighandler_t handler;
++
++		spin_lock_irq(&current->sighand->siglock);
++		handler = current->sighand->action[signr-1].sa.sa_handler;
++		spin_unlock_irq(&current->sighand->siglock);
++		if (handler == SIG_DFL) {
++			/* init has generated a synchronous exception
++			   and it doesn't have a handler for the signal */
++			printk(KERN_CRIT "init has generated signal %d "
++			       "but has no handler for it\n", signr);
++			do_exit(signr);
++		}
++	}
++}
++
++#ifdef CONFIG_PPC64
++void system_reset_exception(struct pt_regs *regs)
++{
++	/* See if any machine dependent calls */
++	if (ppc_md.system_reset_exception)
++		ppc_md.system_reset_exception(regs);
++
++	die("System Reset", regs, SIGABRT);
++
++	/* Must die if the interrupt is not recoverable */
++	if (!(regs->msr & MSR_RI))
++		panic("Unrecoverable System Reset");
++
++	/* What should we do here? We could issue a shutdown or hard reset. */
++}
++#endif
++
++/*
++ * I/O accesses can cause machine checks on powermacs.
++ * Check if the NIP corresponds to the address of a sync
++ * instruction for which there is an entry in the exception
++ * table.
++ * Note that the 601 only takes a machine check on TEA
++ * (transfer error ack) signal assertion, and does not
++ * set any of the top 16 bits of SRR1.
++ *  -- paulus.
++ */
++static inline int check_io_access(struct pt_regs *regs)
++{
++#ifdef CONFIG_PPC_PMAC
++	unsigned long msr = regs->msr;
++	const struct exception_table_entry *entry;
++	unsigned int *nip = (unsigned int *)regs->nip;
++
++	if (((msr & 0xffff0000) == 0 || (msr & (0x80000 | 0x40000)))
++	    && (entry = search_exception_tables(regs->nip)) != NULL) {
++		/*
++		 * Check that it's a sync instruction, or somewhere
++		 * in the twi; isync; nop sequence that inb/inw/inl uses.
++		 * As the address is in the exception table
++		 * we should be able to read the instr there.
++		 * For the debug message, we look at the preceding
++		 * load or store.
++		 */
++		if (*nip == 0x60000000)		/* nop */
++			nip -= 2;
++		else if (*nip == 0x4c00012c)	/* isync */
++			--nip;
++		if (*nip == 0x7c0004ac || (*nip >> 26) == 3) {
++			/* sync or twi */
++			unsigned int rb;
++
++			--nip;
++			rb = (*nip >> 11) & 0x1f;
++			printk(KERN_DEBUG "%s bad port %lx at %p\n",
++			       (*nip & 0x100)? "OUT to": "IN from",
++			       regs->gpr[rb] - _IO_BASE, nip);
++			regs->msr |= MSR_RI;
++			regs->nip = entry->fixup;
++			return 1;
++		}
++	}
++#endif /* CONFIG_PPC_PMAC */
++	return 0;
++}
++
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++/* On 4xx, the reason for the machine check or program exception
++   is in the ESR. */
++#define get_reason(regs)	((regs)->dsisr)
++#ifndef CONFIG_FSL_BOOKE
++#define get_mc_reason(regs)	((regs)->dsisr)
++#else
++#define get_mc_reason(regs)	(mfspr(SPRN_MCSR))
++#endif
++#define REASON_FP		ESR_FP
++#define REASON_ILLEGAL		(ESR_PIL | ESR_PUO)
++#define REASON_PRIVILEGED	ESR_PPR
++#define REASON_TRAP		ESR_PTR
++
++/* single-step stuff */
++#define single_stepping(regs)	(current->thread.dbcr0 & DBCR0_IC)
++#define clear_single_step(regs)	(current->thread.dbcr0 &= ~DBCR0_IC)
++
++#else
++/* On non-4xx, the reason for the machine check or program
++   exception is in the MSR. */
++#define get_reason(regs)	((regs)->msr)
++#define get_mc_reason(regs)	((regs)->msr)
++#define REASON_FP		0x100000
++#define REASON_ILLEGAL		0x80000
++#define REASON_PRIVILEGED	0x40000
++#define REASON_TRAP		0x20000
++
++#define single_stepping(regs)	((regs)->msr & MSR_SE)
++#define clear_single_step(regs)	((regs)->msr &= ~MSR_SE)
++#endif
++
++/*
++ * This is "fall-back" implementation for configurations
++ * which don't provide platform-specific machine check info
++ */
++void __attribute__ ((weak))
++platform_machine_check(struct pt_regs *regs)
++{
++}
++
++void machine_check_exception(struct pt_regs *regs)
++{
++#ifdef CONFIG_PPC64
++	int recover = 0;
++
++	/* See if any machine dependent calls */
++	if (ppc_md.machine_check_exception)
++		recover = ppc_md.machine_check_exception(regs);
++
++	if (recover)
++		return;
++#else
++	unsigned long reason = get_mc_reason(regs);
++
++	if (user_mode(regs)) {
++		regs->msr |= MSR_RI;
++		_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
++		return;
++	}
++
++#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
++	/* the qspan pci read routines can cause machine checks -- Cort */
++	bad_page_fault(regs, regs->dar, SIGBUS);
++	return;
++#endif
++
++	if (debugger_fault_handler(regs)) {
++		regs->msr |= MSR_RI;
++		return;
++	}
++
++	if (check_io_access(regs))
++		return;
++
++#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
++	if (reason & ESR_IMCP) {
++		printk("Instruction");
++		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
++	} else
++		printk("Data");
++	printk(" machine check in kernel mode.\n");
++#elif defined(CONFIG_440A)
++	printk("Machine check in kernel mode.\n");
++	if (reason & ESR_IMCP){
++		printk("Instruction Synchronous Machine Check exception\n");
++		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
++	}
++	else {
++		u32 mcsr = mfspr(SPRN_MCSR);
++		if (mcsr & MCSR_IB)
++			printk("Instruction Read PLB Error\n");
++		if (mcsr & MCSR_DRB)
++			printk("Data Read PLB Error\n");
++		if (mcsr & MCSR_DWB)
++			printk("Data Write PLB Error\n");
++		if (mcsr & MCSR_TLBP)
++			printk("TLB Parity Error\n");
++		if (mcsr & MCSR_ICP){
++			flush_instruction_cache();
++			printk("I-Cache Parity Error\n");
++		}
++		if (mcsr & MCSR_DCSP)
++			printk("D-Cache Search Parity Error\n");
++		if (mcsr & MCSR_DCFP)
++			printk("D-Cache Flush Parity Error\n");
++		if (mcsr & MCSR_IMPE)
++			printk("Machine Check exception is imprecise\n");
++
++		/* Clear MCSR */
++		mtspr(SPRN_MCSR, mcsr);
++	}
++#elif defined (CONFIG_E500)
++	printk("Machine check in kernel mode.\n");
++	printk("Caused by (from MCSR=%lx): ", reason);
++
++	if (reason & MCSR_MCP)
++		printk("Machine Check Signal\n");
++	if (reason & MCSR_ICPERR)
++		printk("Instruction Cache Parity Error\n");
++	if (reason & MCSR_DCP_PERR)
++		printk("Data Cache Push Parity Error\n");
++	if (reason & MCSR_DCPERR)
++		printk("Data Cache Parity Error\n");
++	if (reason & MCSR_GL_CI)
++		printk("Guarded Load or Cache-Inhibited stwcx.\n");
++	if (reason & MCSR_BUS_IAERR)
++		printk("Bus - Instruction Address Error\n");
++	if (reason & MCSR_BUS_RAERR)
++		printk("Bus - Read Address Error\n");
++	if (reason & MCSR_BUS_WAERR)
++		printk("Bus - Write Address Error\n");
++	if (reason & MCSR_BUS_IBERR)
++		printk("Bus - Instruction Data Error\n");
++	if (reason & MCSR_BUS_RBERR)
++		printk("Bus - Read Data Bus Error\n");
++	if (reason & MCSR_BUS_WBERR)
++		printk("Bus - Read Data Bus Error\n");
++	if (reason & MCSR_BUS_IPERR)
++		printk("Bus - Instruction Parity Error\n");
++	if (reason & MCSR_BUS_RPERR)
++		printk("Bus - Read Parity Error\n");
++#elif defined (CONFIG_E200)
++	printk("Machine check in kernel mode.\n");
++	printk("Caused by (from MCSR=%lx): ", reason);
++
++	if (reason & MCSR_MCP)
++		printk("Machine Check Signal\n");
++	if (reason & MCSR_CP_PERR)
++		printk("Cache Push Parity Error\n");
++	if (reason & MCSR_CPERR)
++		printk("Cache Parity Error\n");
++	if (reason & MCSR_EXCP_ERR)
++		printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n");
++	if (reason & MCSR_BUS_IRERR)
++		printk("Bus - Read Bus Error on instruction fetch\n");
++	if (reason & MCSR_BUS_DRERR)
++		printk("Bus - Read Bus Error on data load\n");
++	if (reason & MCSR_BUS_WRERR)
++		printk("Bus - Write Bus Error on buffered store or cache line push\n");
++#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
++	printk("Machine check in kernel mode.\n");
++	printk("Caused by (from SRR1=%lx): ", reason);
++	switch (reason & 0x601F0000) {
++	case 0x80000:
++		printk("Machine check signal\n");
++		break;
++	case 0:		/* for 601 */
++	case 0x40000:
++	case 0x140000:	/* 7450 MSS error and TEA */
++		printk("Transfer error ack signal\n");
++		break;
++	case 0x20000:
++		printk("Data parity error signal\n");
++		break;
++	case 0x10000:
++		printk("Address parity error signal\n");
++		break;
++	case 0x20000000:
++		printk("L1 Data Cache error\n");
++		break;
++	case 0x40000000:
++		printk("L1 Instruction Cache error\n");
++		break;
++	case 0x00100000:
++		printk("L2 data cache parity error\n");
++		break;
++	default:
++		printk("Unknown values in msr\n");
++	}
++#endif /* CONFIG_4xx */
++
++	/*
++	 * Optional platform-provided routine to print out
++	 * additional info, e.g. bus error registers.
++	 */
++	platform_machine_check(regs);
++#endif /* CONFIG_PPC64 */
++
++	if (debugger_fault_handler(regs))
++		return;
++	die("Machine check", regs, SIGBUS);
++
++	/* Must die if the interrupt is not recoverable */
++	if (!(regs->msr & MSR_RI))
++		panic("Unrecoverable Machine check");
++}
++
++void SMIException(struct pt_regs *regs)
++{
++	die("System Management Interrupt", regs, SIGABRT);
++}
++
++void unknown_exception(struct pt_regs *regs)
++{
++	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
++	       regs->nip, regs->msr, regs->trap);
++
++	_exception(SIGTRAP, regs, 0, 0);
++}
++
++void instruction_breakpoint_exception(struct pt_regs *regs)
++{
++	if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
++					5, SIGTRAP) == NOTIFY_STOP)
++		return;
++	if (debugger_iabr_match(regs))
++		return;
++	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
++}
++
++void RunModeException(struct pt_regs *regs)
++{
++	_exception(SIGTRAP, regs, 0, 0);
++}
++
++void __kprobes single_step_exception(struct pt_regs *regs)
++{
++	regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
++
++	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
++					5, SIGTRAP) == NOTIFY_STOP)
++		return;
++	if (debugger_sstep(regs))
++		return;
++
++	_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
++}
++
++/*
++ * After we have successfully emulated an instruction, we have to
++ * check if the instruction was being single-stepped, and if so,
++ * pretend we got a single-step exception.  This was pointed out
++ * by Kumar Gala.  -- paulus
++ */
++static void emulate_single_step(struct pt_regs *regs)
++{
++	if (single_stepping(regs)) {
++		clear_single_step(regs);
++		_exception(SIGTRAP, regs, TRAP_TRACE, 0);
++	}
++}
++
++static void parse_fpe(struct pt_regs *regs)
++{
++	int code = 0;
++	unsigned long fpscr;
++
++	flush_fp_to_thread(current);
++
++	fpscr = current->thread.fpscr.val;
++
++	/* Invalid operation */
++	if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
++		code = FPE_FLTINV;
++
++	/* Overflow */
++	else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
++		code = FPE_FLTOVF;
++
++	/* Underflow */
++	else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
++		code = FPE_FLTUND;
++
++	/* Divide by zero */
++	else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
++		code = FPE_FLTDIV;
++
++	/* Inexact result */
++	else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
++		code = FPE_FLTRES;
++
++	_exception(SIGFPE, regs, code, regs->nip);
++}
++
++/*
++ * Illegal instruction emulation support.  Originally written to
++ * provide the PVR to user applications using the mfspr rd, PVR.
++ * Return non-zero if we can't emulate, or -EFAULT if the associated
++ * memory access caused an access fault.  Return zero on success.
++ *
++ * There are a couple of ways to do this, either "decode" the instruction
++ * or directly match lots of bits.  In this case, matching lots of
++ * bits is faster and easier.
++ *
++ */
++#define INST_MFSPR_PVR		0x7c1f42a6
++#define INST_MFSPR_PVR_MASK	0xfc1fffff
++
++#define INST_DCBA		0x7c0005ec
++#define INST_DCBA_MASK		0x7c0007fe
++
++#define INST_MCRXR		0x7c000400
++#define INST_MCRXR_MASK		0x7c0007fe
++
++#define INST_STRING		0x7c00042a
++#define INST_STRING_MASK	0x7c0007fe
++#define INST_STRING_GEN_MASK	0x7c00067e
++#define INST_LSWI		0x7c0004aa
++#define INST_LSWX		0x7c00042a
++#define INST_STSWI		0x7c0005aa
++#define INST_STSWX		0x7c00052a
++
++static int emulate_string_inst(struct pt_regs *regs, u32 instword)
++{
++	u8 rT = (instword >> 21) & 0x1f;
++	u8 rA = (instword >> 16) & 0x1f;
++	u8 NB_RB = (instword >> 11) & 0x1f;
++	u32 num_bytes;
++	unsigned long EA;
++	int pos = 0;
++
++	/* Early out if we are an invalid form of lswx */
++	if ((instword & INST_STRING_MASK) == INST_LSWX)
++		if ((rT == rA) || (rT == NB_RB))
++			return -EINVAL;
++
++	EA = (rA == 0) ? 0 : regs->gpr[rA];
++
++	switch (instword & INST_STRING_MASK) {
++		case INST_LSWX:
++		case INST_STSWX:
++			EA += NB_RB;
++			num_bytes = regs->xer & 0x7f;
++			break;
++		case INST_LSWI:
++		case INST_STSWI:
++			num_bytes = (NB_RB == 0) ? 32 : NB_RB;
++			break;
++		default:
++			return -EINVAL;
++	}
++
++	while (num_bytes != 0)
++	{
++		u8 val;
++		u32 shift = 8 * (3 - (pos & 0x3));
++
++		switch ((instword & INST_STRING_MASK)) {
++			case INST_LSWX:
++			case INST_LSWI:
++				if (get_user(val, (u8 __user *)EA))
++					return -EFAULT;
++				/* first time updating this reg,
++				 * zero it out */
++				if (pos == 0)
++					regs->gpr[rT] = 0;
++				regs->gpr[rT] |= val << shift;
++				break;
++			case INST_STSWI:
++			case INST_STSWX:
++				val = regs->gpr[rT] >> shift;
++				if (put_user(val, (u8 __user *)EA))
++					return -EFAULT;
++				break;
++		}
++		/* move EA to next address */
++		EA += 1;
++		num_bytes--;
++
++		/* manage our position within the register */
++		if (++pos == 4) {
++			pos = 0;
++			if (++rT == 32)
++				rT = 0;
++		}
++	}
++
++	return 0;
++}
++
++static int emulate_instruction(struct pt_regs *regs)
++{
++	u32 instword;
++	u32 rd;
++
++	if (!user_mode(regs))
++		return -EINVAL;
++	CHECK_FULL_REGS(regs);
++
++	if (get_user(instword, (u32 __user *)(regs->nip)))
++		return -EFAULT;
++
++	/* Emulate the mfspr rD, PVR. */
++	if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
++		rd = (instword >> 21) & 0x1f;
++		regs->gpr[rd] = mfspr(SPRN_PVR);
++		return 0;
++	}
++
++	/* Emulating the dcba insn is just a no-op.  */
++	if ((instword & INST_DCBA_MASK) == INST_DCBA)
++		return 0;
++
++	/* Emulate the mcrxr insn.  */
++	if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
++		int shift = (instword >> 21) & 0x1c;
++		unsigned long msk = 0xf0000000UL >> shift;
++
++		regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
++		regs->xer &= ~0xf0000000UL;
++		return 0;
++	}
++
++	/* Emulate load/store string insn. */
++	if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
++		return emulate_string_inst(regs, instword);
++
++	return -EINVAL;
++}
++
++/*
++ * Look through the list of trap instructions that are used for BUG(),
++ * BUG_ON() and WARN_ON() and see if we hit one.  At this point we know
++ * that the exception was caused by a trap instruction of some kind.
++ * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
++ * otherwise.
++ */
++extern struct bug_entry __start___bug_table[], __stop___bug_table[];
++
++#ifndef CONFIG_MODULES
++#define module_find_bug(x)	NULL
++#endif
++
++struct bug_entry *find_bug(unsigned long bugaddr)
++{
++	struct bug_entry *bug;
++
++	for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
++		if (bugaddr == bug->bug_addr)
++			return bug;
++	return module_find_bug(bugaddr);
++}
++
++static int check_bug_trap(struct pt_regs *regs)
++{
++	struct bug_entry *bug;
++	unsigned long addr;
++
++	if (regs->msr & MSR_PR)
++		return 0;	/* not in kernel */
++	addr = regs->nip;	/* address of trap instruction */
++	if (addr < PAGE_OFFSET)
++		return 0;
++	bug = find_bug(regs->nip);
++	if (bug == NULL)
++		return 0;
++	if (bug->line & BUG_WARNING_TRAP) {
++		/* this is a WARN_ON rather than BUG/BUG_ON */
++#ifdef CONFIG_XMON
++		xmon_printf(KERN_ERR "Badness in %s at %s:%d\n",
++		       bug->function, bug->file,
++		       bug->line & ~BUG_WARNING_TRAP);
++#endif /* CONFIG_XMON */		
++		printk(KERN_ERR "Badness in %s at %s:%d\n",
++		       bug->function, bug->file,
++		       bug->line & ~BUG_WARNING_TRAP);
++		dump_stack();
++		return 1;
++	}
++#ifdef CONFIG_XMON
++	xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
++	       bug->function, bug->file, bug->line);
++	xmon(regs);
++#endif /* CONFIG_XMON */
++	printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
++	       bug->function, bug->file, bug->line);
++
++	return 0;
++}
++
++void __kprobes program_check_exception(struct pt_regs *regs)
++{
++	unsigned int reason = get_reason(regs);
++	extern int do_mathemu(struct pt_regs *regs);
++
++#ifdef CONFIG_MATH_EMULATION
++	/* (reason & REASON_ILLEGAL) would be the obvious thing here,
++	 * but there seems to be a hardware bug on the 405GP (RevD)
++	 * that means ESR is sometimes set incorrectly - either to
++	 * ESR_DST (!?) or 0.  In the process of chasing this with the
++	 * hardware people - not sure if it can happen on any illegal
++	 * instruction or only on FP instructions, whether there is a
++	 * pattern to occurences etc. -dgibson 31/Mar/2003 */
++	if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
++		emulate_single_step(regs);
++		return;
++	}
++#endif /* CONFIG_MATH_EMULATION */
++
++	if (reason & REASON_FP) {
++		/* IEEE FP exception */
++		parse_fpe(regs);
++		return;
++	}
++	if (reason & REASON_TRAP) {
++		/* trap exception */
++		if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP)
++				== NOTIFY_STOP)
++			return;
++		if (debugger_bpt(regs))
++			return;
++		if (check_bug_trap(regs)) {
++			regs->nip += 4;
++			return;
++		}
++		_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
++		return;
++	}
++
++	/* Try to emulate it if we should. */
++	if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
++		switch (emulate_instruction(regs)) {
++		case 0:
++			regs->nip += 4;
++			emulate_single_step(regs);
++			return;
++		case -EFAULT:
++			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
++			return;
++		}
++	}
++
++	if (reason & REASON_PRIVILEGED)
++		_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
++	else
++		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
++}
++
++void alignment_exception(struct pt_regs *regs)
++{
++	int fixed;
++
++	fixed = fix_alignment(regs);
++
++	if (fixed == 1) {
++		regs->nip += 4;	/* skip over emulated instruction */
++		emulate_single_step(regs);
++		return;
++	}
++
++	/* Operand address was bad */
++	if (fixed == -EFAULT) {
++		if (user_mode(regs))
++			_exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
++		else
++			/* Search exception table */
++			bad_page_fault(regs, regs->dar, SIGSEGV);
++		return;
++	}
++	_exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
++}
++
++void StackOverflow(struct pt_regs *regs)
++{
++	printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n",
++	       current, regs->gpr[1]);
++	debugger(regs);
++	show_regs(regs);
++	panic("kernel stack overflow");
++}
++
++void nonrecoverable_exception(struct pt_regs *regs)
++{
++	printk(KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n",
++	       regs->nip, regs->msr);
++	debugger(regs);
++	die("nonrecoverable exception", regs, SIGKILL);
++}
++
++void trace_syscall(struct pt_regs *regs)
++{
++	printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
++	       current, current->pid, regs->nip, regs->link, regs->gpr[0],
++	       regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
++}
++
++void kernel_fp_unavailable_exception(struct pt_regs *regs)
++{
++	printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
++			  "%lx at %lx\n", regs->trap, regs->nip);
++	die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
++}
++
++void altivec_unavailable_exception(struct pt_regs *regs)
++{
++#if !defined(CONFIG_ALTIVEC)
++	if (user_mode(regs)) {
++		/* A user program has executed an altivec instruction,
++		   but this kernel doesn't support altivec. */
++		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
++		return;
++	}
++#endif
++	printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
++			"%lx at %lx\n", regs->trap, regs->nip);
++	die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
++}
++
++#ifdef CONFIG_PPC64
++extern perf_irq_t perf_irq;
++#endif
++
++#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
++void performance_monitor_exception(struct pt_regs *regs)
++{
++	perf_irq(regs);
++}
++#endif
++
++#ifdef CONFIG_8xx
++void SoftwareEmulation(struct pt_regs *regs)
++{
++	extern int do_mathemu(struct pt_regs *);
++	extern int Soft_emulate_8xx(struct pt_regs *);
++	int errcode;
++
++	CHECK_FULL_REGS(regs);
++
++	if (!user_mode(regs)) {
++		debugger(regs);
++		die("Kernel Mode Software FPU Emulation", regs, SIGFPE);
++	}
++
++#ifdef CONFIG_MATH_EMULATION
++	errcode = do_mathemu(regs);
++#else
++	errcode = Soft_emulate_8xx(regs);
++#endif
++	if (errcode) {
++		if (errcode > 0)
++			_exception(SIGFPE, regs, 0, 0);
++		else if (errcode == -EFAULT)
++			_exception(SIGSEGV, regs, 0, 0);
++		else
++			_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
++	} else
++		emulate_single_step(regs);
++}
++#endif /* CONFIG_8xx */
++
++#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
++
++void DebugException(struct pt_regs *regs, unsigned long debug_status)
++{
++	if (debug_status & DBSR_IC) {	/* instruction completion */
++		regs->msr &= ~MSR_DE;
++		if (user_mode(regs)) {
++			current->thread.dbcr0 &= ~DBCR0_IC;
++		} else {
++			/* Disable instruction completion */
++			mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC);
++			/* Clear the instruction completion event */
++			mtspr(SPRN_DBSR, DBSR_IC);
++			if (debugger_sstep(regs))
++				return;
++		}
++		_exception(SIGTRAP, regs, TRAP_TRACE, 0);
++	}
++}
++#endif /* CONFIG_4xx || CONFIG_BOOKE */
++
++#if !defined(CONFIG_TAU_INT)
++void TAUException(struct pt_regs *regs)
++{
++	printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx    %s\n",
++	       regs->nip, regs->msr, regs->trap, print_tainted());
++}
++#endif /* CONFIG_INT_TAU */
++
++#ifdef CONFIG_ALTIVEC
++void altivec_assist_exception(struct pt_regs *regs)
++{
++	int err;
++
++	if (!user_mode(regs)) {
++		printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
++		       " at %lx\n", regs->nip);
++		die("Kernel VMX/Altivec assist exception", regs, SIGILL);
++	}
++
++	flush_altivec_to_thread(current);
++
++	err = emulate_altivec(regs);
++	if (err == 0) {
++		regs->nip += 4;		/* skip emulated instruction */
++		emulate_single_step(regs);
++		return;
++	}
++
++	if (err == -EFAULT) {
++		/* got an error reading the instruction */
++		_exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
++	} else {
++		/* didn't recognize the instruction */
++		/* XXX quick hack for now: set the non-Java bit in the VSCR */
++		if (printk_ratelimit())
++			printk(KERN_ERR "Unrecognized altivec instruction "
++			       "in %s at %lx\n", current->comm, regs->nip);
++		current->thread.vscr.u[3] |= 0x10000;
++	}
++}
++#endif /* CONFIG_ALTIVEC */
++
++#ifdef CONFIG_FSL_BOOKE
++void CacheLockingException(struct pt_regs *regs, unsigned long address,
++			   unsigned long error_code)
++{
++	/* We treat cache locking instructions from the user
++	 * as priv ops, in the future we could try to do
++	 * something smarter
++	 */
++	if (error_code & (ESR_DLK|ESR_ILK))
++		_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
++	return;
++}
++#endif /* CONFIG_FSL_BOOKE */
++
++#ifdef CONFIG_SPE
++void SPEFloatingPointException(struct pt_regs *regs)
++{
++	unsigned long spefscr;
++	int fpexc_mode;
++	int code = 0;
++
++	spefscr = current->thread.spefscr;
++	fpexc_mode = current->thread.fpexc_mode;
++
++	/* Hardware does not neccessarily set sticky
++	 * underflow/overflow/invalid flags */
++	if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
++		code = FPE_FLTOVF;
++		spefscr |= SPEFSCR_FOVFS;
++	}
++	else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) {
++		code = FPE_FLTUND;
++		spefscr |= SPEFSCR_FUNFS;
++	}
++	else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV))
++		code = FPE_FLTDIV;
++	else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) {
++		code = FPE_FLTINV;
++		spefscr |= SPEFSCR_FINVS;
++	}
++	else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES))
++		code = FPE_FLTRES;
++
++	current->thread.spefscr = spefscr;
++
++	_exception(SIGFPE, regs, code, regs->nip);
++	return;
++}
++#endif
++
++/*
++ * We enter here if we get an unrecoverable exception, that is, one
++ * that happened at a point where the RI (recoverable interrupt) bit
++ * in the MSR is 0.  This indicates that SRR0/1 are live, and that
++ * we therefore lost state by taking this exception.
++ */
++void unrecoverable_exception(struct pt_regs *regs)
++{
++	printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
++	       regs->trap, regs->nip);
++	die("Unrecoverable exception", regs, SIGABRT);
++}
++
++#ifdef CONFIG_BOOKE_WDT
++/*
++ * Default handler for a Watchdog exception,
++ * spins until a reboot occurs
++ */
++void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs)
++{
++	/* Generic WatchdogHandler, implement your own */
++	mtspr(SPRN_TCR, mfspr(SPRN_TCR)&(~TCR_WIE));
++	return;
++}
++
++void WatchdogException(struct pt_regs *regs)
++{
++	printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n");
++	WatchdogHandler(regs);
++}
++#endif
++
++/*
++ * We enter here if we discover during exception entry that we are
++ * running in supervisor mode with a userspace value in the stack pointer.
++ */
++void kernel_bad_stack(struct pt_regs *regs)
++{
++	printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
++	       regs->gpr[1], regs->nip);
++	die("Bad kernel stack pointer", regs, SIGABRT);
++}
++
++void __init trap_init(void)
++{
++}
+diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/vecemu.c
+@@ -0,0 +1,345 @@
++/*
++ * Routines to emulate some Altivec/VMX instructions, specifically
++ * those that can trap when given denormalized operands in Java mode.
++ */
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <asm/ptrace.h>
++#include <asm/processor.h>
++#include <asm/uaccess.h>
++
++/* Functions in vector.S */
++extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b);
++extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b);
++extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
++extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
++extern void vrefp(vector128 *dst, vector128 *src);
++extern void vrsqrtefp(vector128 *dst, vector128 *src);
++extern void vexptep(vector128 *dst, vector128 *src);
++
++static unsigned int exp2s[8] = {
++	0x800000,
++	0x8b95c2,
++	0x9837f0,
++	0xa5fed7,
++	0xb504f3,
++	0xc5672a,
++	0xd744fd,
++	0xeac0c7
++};
++
++/*
++ * Computes an estimate of 2^x.  The `s' argument is the 32-bit
++ * single-precision floating-point representation of x.
++ */
++static unsigned int eexp2(unsigned int s)
++{
++	int exp, pwr;
++	unsigned int mant, frac;
++
++	/* extract exponent field from input */
++	exp = ((s >> 23) & 0xff) - 127;
++	if (exp > 7) {
++		/* check for NaN input */
++		if (exp == 128 && (s & 0x7fffff) != 0)
++			return s | 0x400000;	/* return QNaN */
++		/* 2^-big = 0, 2^+big = +Inf */
++		return (s & 0x80000000)? 0: 0x7f800000;	/* 0 or +Inf */
++	}
++	if (exp < -23)
++		return 0x3f800000;	/* 1.0 */
++
++	/* convert to fixed point integer in 9.23 representation */
++	pwr = (s & 0x7fffff) | 0x800000;
++	if (exp > 0)
++		pwr <<= exp;
++	else
++		pwr >>= -exp;
++	if (s & 0x80000000)
++		pwr = -pwr;
++
++	/* extract integer part, which becomes exponent part of result */
++	exp = (pwr >> 23) + 126;
++	if (exp >= 254)
++		return 0x7f800000;
++	if (exp < -23)
++		return 0;
++
++	/* table lookup on top 3 bits of fraction to get mantissa */
++	mant = exp2s[(pwr >> 20) & 7];
++
++	/* linear interpolation using remaining 20 bits of fraction */
++	asm("mulhwu %0,%1,%2" : "=r" (frac)
++	    : "r" (pwr << 12), "r" (0x172b83ff));
++	asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant));
++	mant += frac;
++
++	if (exp >= 0)
++		return mant + (exp << 23);
++
++	/* denormalized result */
++	exp = -exp;
++	mant += 1 << (exp - 1);
++	return mant >> exp;
++}
++
++/*
++ * Computes an estimate of log_2(x).  The `s' argument is the 32-bit
++ * single-precision floating-point representation of x.
++ */
++static unsigned int elog2(unsigned int s)
++{
++	int exp, mant, lz, frac;
++
++	exp = s & 0x7f800000;
++	mant = s & 0x7fffff;
++	if (exp == 0x7f800000) {	/* Inf or NaN */
++		if (mant != 0)
++			s |= 0x400000;	/* turn NaN into QNaN */
++		return s;
++	}
++	if ((exp | mant) == 0)		/* +0 or -0 */
++		return 0xff800000;	/* return -Inf */
++
++	if (exp == 0) {
++		/* denormalized */
++		asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant));
++		mant <<= lz - 8;
++		exp = (-118 - lz) << 23;
++	} else {
++		mant |= 0x800000;
++		exp -= 127 << 23;
++	}
++
++	if (mant >= 0xb504f3) {				/* 2^0.5 * 2^23 */
++		exp |= 0x400000;			/* 0.5 * 2^23 */
++		asm("mulhwu %0,%1,%2" : "=r" (mant)
++		    : "r" (mant), "r" (0xb504f334));	/* 2^-0.5 * 2^32 */
++	}
++	if (mant >= 0x9837f0) {				/* 2^0.25 * 2^23 */
++		exp |= 0x200000;			/* 0.25 * 2^23 */
++		asm("mulhwu %0,%1,%2" : "=r" (mant)
++		    : "r" (mant), "r" (0xd744fccb));	/* 2^-0.25 * 2^32 */
++	}
++	if (mant >= 0x8b95c2) {				/* 2^0.125 * 2^23 */
++		exp |= 0x100000;			/* 0.125 * 2^23 */
++		asm("mulhwu %0,%1,%2" : "=r" (mant)
++		    : "r" (mant), "r" (0xeac0c6e8));	/* 2^-0.125 * 2^32 */
++	}
++	if (mant > 0x800000) {				/* 1.0 * 2^23 */
++		/* calculate (mant - 1) * 1.381097463 */
++		/* 1.381097463 == 0.125 / (2^0.125 - 1) */
++		asm("mulhwu %0,%1,%2" : "=r" (frac)
++		    : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a));
++		exp += frac;
++	}
++	s = exp & 0x80000000;
++	if (exp != 0) {
++		if (s)
++			exp = -exp;
++		asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp));
++		lz = 8 - lz;
++		if (lz > 0)
++			exp >>= lz;
++		else if (lz < 0)
++			exp <<= -lz;
++		s += ((lz + 126) << 23) + exp;
++	}
++	return s;
++}
++
++#define VSCR_SAT	1
++
++static int ctsxs(unsigned int x, int scale, unsigned int *vscrp)
++{
++	int exp, mant;
++
++	exp = (x >> 23) & 0xff;
++	mant = x & 0x7fffff;
++	if (exp == 255 && mant != 0)
++		return 0;		/* NaN -> 0 */
++	exp = exp - 127 + scale;
++	if (exp < 0)
++		return 0;		/* round towards zero */
++	if (exp >= 31) {
++		/* saturate, unless the result would be -2^31 */
++		if (x + (scale << 23) != 0xcf000000)
++			*vscrp |= VSCR_SAT;
++		return (x & 0x80000000)? 0x80000000: 0x7fffffff;
++	}
++	mant |= 0x800000;
++	mant = (mant << 7) >> (30 - exp);
++	return (x & 0x80000000)? -mant: mant;
++}
++
++static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp)
++{
++	int exp;
++	unsigned int mant;
++
++	exp = (x >> 23) & 0xff;
++	mant = x & 0x7fffff;
++	if (exp == 255 && mant != 0)
++		return 0;		/* NaN -> 0 */
++	exp = exp - 127 + scale;
++	if (exp < 0)
++		return 0;		/* round towards zero */
++	if (x & 0x80000000) {
++		/* negative => saturate to 0 */
++		*vscrp |= VSCR_SAT;
++		return 0;
++	}
++	if (exp >= 32) {
++		/* saturate */
++		*vscrp |= VSCR_SAT;
++		return 0xffffffff;
++	}
++	mant |= 0x800000;
++	mant = (mant << 8) >> (31 - exp);
++	return mant;
++}
++
++/* Round to floating integer, towards 0 */
++static unsigned int rfiz(unsigned int x)
++{
++	int exp;
++
++	exp = ((x >> 23) & 0xff) - 127;
++	if (exp == 128 && (x & 0x7fffff) != 0)
++		return x | 0x400000;	/* NaN -> make it a QNaN */
++	if (exp >= 23)
++		return x;		/* it's an integer already (or Inf) */
++	if (exp < 0)
++		return x & 0x80000000;	/* |x| < 1.0 rounds to 0 */
++	return x & ~(0x7fffff >> exp);
++}
++
++/* Round to floating integer, towards +/- Inf */
++static unsigned int rfii(unsigned int x)
++{
++	int exp, mask;
++
++	exp = ((x >> 23) & 0xff) - 127;
++	if (exp == 128 && (x & 0x7fffff) != 0)
++		return x | 0x400000;	/* NaN -> make it a QNaN */
++	if (exp >= 23)
++		return x;		/* it's an integer already (or Inf) */
++	if ((x & 0x7fffffff) == 0)
++		return x;		/* +/-0 -> +/-0 */
++	if (exp < 0)
++		/* 0 < |x| < 1.0 rounds to +/- 1.0 */
++		return (x & 0x80000000) | 0x3f800000;
++	mask = 0x7fffff >> exp;
++	/* mantissa overflows into exponent - that's OK,
++	   it can't overflow into the sign bit */
++	return (x + mask) & ~mask;
++}
++
++/* Round to floating integer, to nearest */
++static unsigned int rfin(unsigned int x)
++{
++	int exp, half;
++
++	exp = ((x >> 23) & 0xff) - 127;
++	if (exp == 128 && (x & 0x7fffff) != 0)
++		return x | 0x400000;	/* NaN -> make it a QNaN */
++	if (exp >= 23)
++		return x;		/* it's an integer already (or Inf) */
++	if (exp < -1)
++		return x & 0x80000000;	/* |x| < 0.5 -> +/-0 */
++	if (exp == -1)
++		/* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */
++		return (x & 0x80000000) | 0x3f800000;
++	half = 0x400000 >> exp;
++	/* add 0.5 to the magnitude and chop off the fraction bits */
++	return (x + half) & ~(0x7fffff >> exp);
++}
++
++int emulate_altivec(struct pt_regs *regs)
++{
++	unsigned int instr, i;
++	unsigned int va, vb, vc, vd;
++	vector128 *vrs;
++
++	if (get_user(instr, (unsigned int __user *) regs->nip))
++		return -EFAULT;
++	if ((instr >> 26) != 4)
++		return -EINVAL;		/* not an altivec instruction */
++	vd = (instr >> 21) & 0x1f;
++	va = (instr >> 16) & 0x1f;
++	vb = (instr >> 11) & 0x1f;
++	vc = (instr >> 6) & 0x1f;
++
++	vrs = current->thread.vr;
++	switch (instr & 0x3f) {
++	case 10:
++		switch (vc) {
++		case 0:	/* vaddfp */
++			vaddfp(&vrs[vd], &vrs[va], &vrs[vb]);
++			break;
++		case 1:	/* vsubfp */
++			vsubfp(&vrs[vd], &vrs[va], &vrs[vb]);
++			break;
++		case 4:	/* vrefp */
++			vrefp(&vrs[vd], &vrs[vb]);
++			break;
++		case 5:	/* vrsqrtefp */
++			vrsqrtefp(&vrs[vd], &vrs[vb]);
++			break;
++		case 6:	/* vexptefp */
++			for (i = 0; i < 4; ++i)
++				vrs[vd].u[i] = eexp2(vrs[vb].u[i]);
++			break;
++		case 7:	/* vlogefp */
++			for (i = 0; i < 4; ++i)
++				vrs[vd].u[i] = elog2(vrs[vb].u[i]);
++			break;
++		case 8:		/* vrfin */
++			for (i = 0; i < 4; ++i)
++				vrs[vd].u[i] = rfin(vrs[vb].u[i]);
++			break;
++		case 9:		/* vrfiz */
++			for (i = 0; i < 4; ++i)
++				vrs[vd].u[i] = rfiz(vrs[vb].u[i]);
++			break;
++		case 10:	/* vrfip */
++			for (i = 0; i < 4; ++i) {
++				u32 x = vrs[vb].u[i];
++				x = (x & 0x80000000)? rfiz(x): rfii(x);
++				vrs[vd].u[i] = x;
++			}
++			break;
++		case 11:	/* vrfim */
++			for (i = 0; i < 4; ++i) {
++				u32 x = vrs[vb].u[i];
++				x = (x & 0x80000000)? rfii(x): rfiz(x);
++				vrs[vd].u[i] = x;
++			}
++			break;
++		case 14:	/* vctuxs */
++			for (i = 0; i < 4; ++i)
++				vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
++						&current->thread.vscr.u[3]);
++			break;
++		case 15:	/* vctsxs */
++			for (i = 0; i < 4; ++i)
++				vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
++						&current->thread.vscr.u[3]);
++			break;
++		default:
++			return -EINVAL;
++		}
++		break;
++	case 46:	/* vmaddfp */
++		vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
++		break;
++	case 47:	/* vnmsubfp */
++		vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
+diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/vector.S
+@@ -0,0 +1,197 @@
++#include <linux/config.h>
++#include <asm/ppc_asm.h>
++#include <asm/reg.h>
++
++/*
++ * The routines below are in assembler so we can closely control the
++ * usage of floating-point registers.  These routines must be called
++ * with preempt disabled.
++ */
++#ifdef CONFIG_PPC32
++	.data
++fpzero:
++	.long	0
++fpone:
++	.long	0x3f800000	/* 1.0 in single-precision FP */
++fphalf:
++	.long	0x3f000000	/* 0.5 in single-precision FP */
++
++#define LDCONST(fr, name)	\
++	lis	r11,name at ha;	\
++	lfs	fr,name at l(r11)
++#else
++
++	.section ".toc","aw"
++fpzero:
++	.tc	FD_0_0[TC],0
++fpone:
++	.tc	FD_3ff00000_0[TC],0x3ff0000000000000	/* 1.0 */
++fphalf:
++	.tc	FD_3fe00000_0[TC],0x3fe0000000000000	/* 0.5 */
++
++#define LDCONST(fr, name)	\
++	lfd	fr,name at toc(r2)
++#endif
++
++	.text
++/*
++ * Internal routine to enable floating point and set FPSCR to 0.
++ * Don't call it from C; it doesn't use the normal calling convention.
++ */
++fpenable:
++#ifdef CONFIG_PPC32
++	stwu	r1,-64(r1)
++#else
++	stdu	r1,-64(r1)
++#endif
++	mfmsr	r10
++	ori	r11,r10,MSR_FP
++	mtmsr	r11
++	isync
++	stfd	fr0,24(r1)
++	stfd	fr1,16(r1)
++	stfd	fr31,8(r1)
++	LDCONST(fr1, fpzero)
++	mffs	fr31
++	mtfsf	0xff,fr1
++	blr
++
++fpdisable:
++	mtlr	r12
++	mtfsf	0xff,fr31
++	lfd	fr31,8(r1)
++	lfd	fr1,16(r1)
++	lfd	fr0,24(r1)
++	mtmsr	r10
++	isync
++	addi	r1,r1,64
++	blr
++
++/*
++ * Vector add, floating point.
++ */
++_GLOBAL(vaddfp)
++	mflr	r12
++	bl	fpenable
++	li	r0,4
++	mtctr	r0
++	li	r6,0
++1:	lfsx	fr0,r4,r6
++	lfsx	fr1,r5,r6
++	fadds	fr0,fr0,fr1
++	stfsx	fr0,r3,r6
++	addi	r6,r6,4
++	bdnz	1b
++	b	fpdisable
++
++/*
++ * Vector subtract, floating point.
++ */
++_GLOBAL(vsubfp)
++	mflr	r12
++	bl	fpenable
++	li	r0,4
++	mtctr	r0
++	li	r6,0
++1:	lfsx	fr0,r4,r6
++	lfsx	fr1,r5,r6
++	fsubs	fr0,fr0,fr1
++	stfsx	fr0,r3,r6
++	addi	r6,r6,4
++	bdnz	1b
++	b	fpdisable
++
++/*
++ * Vector multiply and add, floating point.
++ */
++_GLOBAL(vmaddfp)
++	mflr	r12
++	bl	fpenable
++	stfd	fr2,32(r1)
++	li	r0,4
++	mtctr	r0
++	li	r7,0
++1:	lfsx	fr0,r4,r7
++	lfsx	fr1,r5,r7
++	lfsx	fr2,r6,r7
++	fmadds	fr0,fr0,fr2,fr1
++	stfsx	fr0,r3,r7
++	addi	r7,r7,4
++	bdnz	1b
++	lfd	fr2,32(r1)
++	b	fpdisable
++
++/*
++ * Vector negative multiply and subtract, floating point.
++ */
++_GLOBAL(vnmsubfp)
++	mflr	r12
++	bl	fpenable
++	stfd	fr2,32(r1)
++	li	r0,4
++	mtctr	r0
++	li	r7,0
++1:	lfsx	fr0,r4,r7
++	lfsx	fr1,r5,r7
++	lfsx	fr2,r6,r7
++	fnmsubs	fr0,fr0,fr2,fr1
++	stfsx	fr0,r3,r7
++	addi	r7,r7,4
++	bdnz	1b
++	lfd	fr2,32(r1)
++	b	fpdisable
++
++/*
++ * Vector reciprocal estimate.  We just compute 1.0/x.
++ * r3 -> destination, r4 -> source.
++ */
++_GLOBAL(vrefp)
++	mflr	r12
++	bl	fpenable
++	li	r0,4
++	LDCONST(fr1, fpone)
++	mtctr	r0
++	li	r6,0
++1:	lfsx	fr0,r4,r6
++	fdivs	fr0,fr1,fr0
++	stfsx	fr0,r3,r6
++	addi	r6,r6,4
++	bdnz	1b
++	b	fpdisable
++
++/*
++ * Vector reciprocal square-root estimate, floating point.
++ * We use the frsqrte instruction for the initial estimate followed
++ * by 2 iterations of Newton-Raphson to get sufficient accuracy.
++ * r3 -> destination, r4 -> source.
++ */
++_GLOBAL(vrsqrtefp)
++	mflr	r12
++	bl	fpenable
++	stfd	fr2,32(r1)
++	stfd	fr3,40(r1)
++	stfd	fr4,48(r1)
++	stfd	fr5,56(r1)
++	li	r0,4
++	LDCONST(fr4, fpone)
++	LDCONST(fr5, fphalf)
++	mtctr	r0
++	li	r6,0
++1:	lfsx	fr0,r4,r6
++	frsqrte	fr1,fr0		/* r = frsqrte(s) */
++	fmuls	fr3,fr1,fr0	/* r * s */
++	fmuls	fr2,fr1,fr5	/* r * 0.5 */
++	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
++	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
++	fmuls	fr3,fr1,fr0	/* r * s */
++	fmuls	fr2,fr1,fr5	/* r * 0.5 */
++	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
++	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
++	stfsx	fr1,r3,r6
++	addi	r6,r6,4
++	bdnz	1b
++	lfd	fr5,56(r1)
++	lfd	fr4,48(r1)
++	lfd	fr3,40(r1)
++	lfd	fr2,32(r1)
++	b	fpdisable
+diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/vio.c
+@@ -0,0 +1,271 @@
++/*
++ * IBM PowerPC Virtual I/O Infrastructure Support.
++ *
++ *    Copyright (c) 2003-2005 IBM Corp.
++ *     Dave Engebretsen engebret at us.ibm.com
++ *     Santiago Leon santil at us.ibm.com
++ *     Hollis Blanchard <hollisb at us.ibm.com>
++ *     Stephen Rothwell
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/console.h>
++#include <linux/module.h>
++#include <linux/mm.h>
++#include <linux/dma-mapping.h>
++#include <asm/iommu.h>
++#include <asm/dma.h>
++#include <asm/vio.h>
++
++static const struct vio_device_id *vio_match_device(
++		const struct vio_device_id *, const struct vio_dev *);
++
++struct vio_dev vio_bus_device  = { /* fake "parent" device */
++	.name = vio_bus_device.dev.bus_id,
++	.type = "",
++	.dev.bus_id = "vio",
++	.dev.bus = &vio_bus_type,
++};
++
++static struct vio_bus_ops vio_bus_ops;
++
++/*
++ * Convert from struct device to struct vio_dev and pass to driver.
++ * dev->driver has already been set by generic code because vio_bus_match
++ * succeeded.
++ */
++static int vio_bus_probe(struct device *dev)
++{
++	struct vio_dev *viodev = to_vio_dev(dev);
++	struct vio_driver *viodrv = to_vio_driver(dev->driver);
++	const struct vio_device_id *id;
++	int error = -ENODEV;
++
++	if (!viodrv->probe)
++		return error;
++
++	id = vio_match_device(viodrv->id_table, viodev);
++	if (id)
++		error = viodrv->probe(viodev, id);
++
++	return error;
++}
++
++/* convert from struct device to struct vio_dev and pass to driver. */
++static int vio_bus_remove(struct device *dev)
++{
++	struct vio_dev *viodev = to_vio_dev(dev);
++	struct vio_driver *viodrv = to_vio_driver(dev->driver);
++
++	if (viodrv->remove)
++		return viodrv->remove(viodev);
++
++	/* driver can't remove */
++	return 1;
++}
++
++/* convert from struct device to struct vio_dev and pass to driver. */
++static void vio_bus_shutdown(struct device *dev)
++{
++	struct vio_dev *viodev = to_vio_dev(dev);
++	struct vio_driver *viodrv = to_vio_driver(dev->driver);
++
++	if (viodrv->shutdown)
++		viodrv->shutdown(viodev);
++}
++
++/**
++ * vio_register_driver: - Register a new vio driver
++ * @drv:	The vio_driver structure to be registered.
++ */
++int vio_register_driver(struct vio_driver *viodrv)
++{
++	printk(KERN_DEBUG "%s: driver %s registering\n", __FUNCTION__,
++		viodrv->driver.name);
++
++	/* fill in 'struct driver' fields */
++	viodrv->driver.bus = &vio_bus_type;
++	viodrv->driver.probe = vio_bus_probe;
++	viodrv->driver.remove = vio_bus_remove;
++	viodrv->driver.shutdown = vio_bus_shutdown;
++
++	return driver_register(&viodrv->driver);
++}
++EXPORT_SYMBOL(vio_register_driver);
++
++/**
++ * vio_unregister_driver - Remove registration of vio driver.
++ * @driver:	The vio_driver struct to be removed form registration
++ */
++void vio_unregister_driver(struct vio_driver *viodrv)
++{
++	driver_unregister(&viodrv->driver);
++}
++EXPORT_SYMBOL(vio_unregister_driver);
++
++/**
++ * vio_match_device: - Tell if a VIO device has a matching
++ *			VIO device id structure.
++ * @ids:	array of VIO device id structures to search in
++ * @dev:	the VIO device structure to match against
++ *
++ * Used by a driver to check whether a VIO device present in the
++ * system is in its list of supported devices. Returns the matching
++ * vio_device_id structure or NULL if there is no match.
++ */
++static const struct vio_device_id *vio_match_device(
++		const struct vio_device_id *ids, const struct vio_dev *dev)
++{
++	while (ids->type[0] != '\0') {
++		if (vio_bus_ops.match(ids, dev))
++			return ids;
++		ids++;
++	}
++	return NULL;
++}
++
++/**
++ * vio_bus_init: - Initialize the virtual IO bus
++ */
++int __init vio_bus_init(struct vio_bus_ops *ops)
++{
++	int err;
++
++	vio_bus_ops = *ops;
++
++	err = bus_register(&vio_bus_type);
++	if (err) {
++		printk(KERN_ERR "failed to register VIO bus\n");
++		return err;
++	}
++
++	/*
++	 * The fake parent of all vio devices, just to give us
++	 * a nice directory
++	 */
++	err = device_register(&vio_bus_device.dev);
++	if (err) {
++		printk(KERN_WARNING "%s: device_register returned %i\n",
++				__FUNCTION__, err);
++		return err;
++	}
++
++	return 0;
++}
++
++/* vio_dev refcount hit 0 */
++static void __devinit vio_dev_release(struct device *dev)
++{
++	if (vio_bus_ops.release_device)
++		vio_bus_ops.release_device(dev);
++	kfree(to_vio_dev(dev));
++}
++
++static ssize_t viodev_show_name(struct device *dev,
++		struct device_attribute *attr, char *buf)
++{
++	return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
++}
++DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL);
++
++struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev)
++{
++	/* init generic 'struct device' fields: */
++	viodev->dev.parent = &vio_bus_device.dev;
++	viodev->dev.bus = &vio_bus_type;
++	viodev->dev.release = vio_dev_release;
++
++	/* register with generic device framework */
++	if (device_register(&viodev->dev)) {
++		printk(KERN_ERR "%s: failed to register device %s\n",
++				__FUNCTION__, viodev->dev.bus_id);
++		return NULL;
++	}
++	device_create_file(&viodev->dev, &dev_attr_name);
++
++	return viodev;
++}
++
++void __devinit vio_unregister_device(struct vio_dev *viodev)
++{
++	if (vio_bus_ops.unregister_device)
++		vio_bus_ops.unregister_device(viodev);
++	device_remove_file(&viodev->dev, &dev_attr_name);
++	device_unregister(&viodev->dev);
++}
++EXPORT_SYMBOL(vio_unregister_device);
++
++static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
++			  size_t size, enum dma_data_direction direction)
++{
++	return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
++			direction);
++}
++
++static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
++		      size_t size, enum dma_data_direction direction)
++{
++	iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size,
++			direction);
++}
++
++static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
++		int nelems, enum dma_data_direction direction)
++{
++	return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
++			nelems, direction);
++}
++
++static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
++		int nelems, enum dma_data_direction direction)
++{
++	iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction);
++}
++
++static void *vio_alloc_coherent(struct device *dev, size_t size,
++			   dma_addr_t *dma_handle, gfp_t flag)
++{
++	return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
++			dma_handle, flag);
++}
++
++static void vio_free_coherent(struct device *dev, size_t size,
++			 void *vaddr, dma_addr_t dma_handle)
++{
++	iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr,
++			dma_handle);
++}
++
++static int vio_dma_supported(struct device *dev, u64 mask)
++{
++	return 1;
++}
++
++struct dma_mapping_ops vio_dma_ops = {
++	.alloc_coherent = vio_alloc_coherent,
++	.free_coherent = vio_free_coherent,
++	.map_single = vio_map_single,
++	.unmap_single = vio_unmap_single,
++	.map_sg = vio_map_sg,
++	.unmap_sg = vio_unmap_sg,
++	.dma_supported = vio_dma_supported,
++};
++
++static int vio_bus_match(struct device *dev, struct device_driver *drv)
++{
++	const struct vio_dev *vio_dev = to_vio_dev(dev);
++	struct vio_driver *vio_drv = to_vio_driver(drv);
++	const struct vio_device_id *ids = vio_drv->id_table;
++
++	return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
++}
++
++struct bus_type vio_bus_type = {
++	.name = "vio",
++	.match = vio_bus_match,
++};
+diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/kernel/vmlinux.lds.S
+@@ -0,0 +1,279 @@
++#include <linux/config.h>
++#ifdef CONFIG_PPC64
++#include <asm/page.h>
++#else
++#define PAGE_SIZE	4096
++#endif
++#include <asm-generic/vmlinux.lds.h>
++
++#ifdef CONFIG_PPC64
++OUTPUT_ARCH(powerpc:common64)
++jiffies = jiffies_64;
++#else
++OUTPUT_ARCH(powerpc:common)
++jiffies = jiffies_64 + 4;
++#endif
++SECTIONS
++{
++  /* Sections to be discarded. */
++  /DISCARD/ : {
++    *(.exitcall.exit)
++    *(.exit.data)
++  }
++
++
++  /* Read-only sections, merged into text segment: */
++#ifdef CONFIG_PPC32
++  . = + SIZEOF_HEADERS;
++  .interp : { *(.interp) }
++  .hash          : { *(.hash)		}
++  .dynsym        : { *(.dynsym)		}
++  .dynstr        : { *(.dynstr)		}
++  .rel.text      : { *(.rel.text)		}
++  .rela.text     : { *(.rela.text) 	}
++  .rel.data      : { *(.rel.data)		}
++  .rela.data     : { *(.rela.data) 	}
++  .rel.rodata    : { *(.rel.rodata) 	}
++  .rela.rodata   : { *(.rela.rodata) 	}
++  .rel.got       : { *(.rel.got)		}
++  .rela.got      : { *(.rela.got)		}
++  .rel.ctors     : { *(.rel.ctors)	}
++  .rela.ctors    : { *(.rela.ctors)	}
++  .rel.dtors     : { *(.rel.dtors)	}
++  .rela.dtors    : { *(.rela.dtors)	}
++  .rel.bss       : { *(.rel.bss)		}
++  .rela.bss      : { *(.rela.bss)		}
++  .rel.plt       : { *(.rel.plt)		}
++  .rela.plt      : { *(.rela.plt)		}
++/*  .init          : { *(.init)	} =0*/
++  .plt : { *(.plt) }
++#endif
++  .text : {
++    *(.text .text.*)
++    SCHED_TEXT
++    LOCK_TEXT
++    KPROBES_TEXT
++    *(.fixup)
++#ifdef CONFIG_PPC32
++    *(.got1)
++    __got2_start = .;
++    *(.got2)
++    __got2_end = .;
++#else
++    . = ALIGN(PAGE_SIZE);
++    _etext = .;
++#endif
++  }
++#ifdef CONFIG_PPC32
++  _etext = .;
++  PROVIDE (etext = .);
++
++  RODATA
++  .fini      : { *(.fini)    } =0
++  .ctors     : { *(.ctors)   }
++  .dtors     : { *(.dtors)   }
++
++  .fixup   : { *(.fixup) }
++#endif
++
++	__ex_table : {
++		__start___ex_table = .;
++		*(__ex_table)
++		__stop___ex_table = .;
++	}
++
++	__bug_table : {
++		__start___bug_table = .;
++		*(__bug_table)
++		__stop___bug_table = .;
++	}
++
++#ifdef CONFIG_PPC64
++	__ftr_fixup : {
++		__start___ftr_fixup = .;
++		*(__ftr_fixup)
++		__stop___ftr_fixup = .;
++	}
++
++  RODATA
++#endif
++
++#ifdef CONFIG_PPC32
++  /* Read-write section, merged into data segment: */
++  . = ALIGN(PAGE_SIZE);
++  _sdata = .;
++  .data    :
++  {
++    *(.data)
++    *(.data1)
++    *(.sdata)
++    *(.sdata2)
++    *(.got.plt) *(.got)
++    *(.dynamic)
++    CONSTRUCTORS
++  }
++
++  . = ALIGN(PAGE_SIZE);
++  __nosave_begin = .;
++  .data_nosave : { *(.data.nosave) }
++  . = ALIGN(PAGE_SIZE);
++  __nosave_end = .;
++
++  . = ALIGN(32);
++  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
++
++  _edata  =  .;
++  PROVIDE (edata = .);
++
++  . = ALIGN(8192);
++  .data.init_task : { *(.data.init_task) }
++#endif
++
++  /* will be freed after init */
++  . = ALIGN(PAGE_SIZE);
++  __init_begin = .;
++  .init.text : {
++	_sinittext = .;
++	*(.init.text)
++	_einittext = .;
++  }
++#ifdef CONFIG_PPC32
++  /* .exit.text is discarded at runtime, not link time,
++     to deal with references from __bug_table */
++  .exit.text : { *(.exit.text) }
++#endif
++  .init.data : {
++    *(.init.data);
++    __vtop_table_begin = .;
++    *(.vtop_fixup);
++    __vtop_table_end = .;
++    __ptov_table_begin = .;
++    *(.ptov_fixup);
++    __ptov_table_end = .;
++  }
++
++  . = ALIGN(16);
++  .init.setup : {
++    __setup_start = .;
++    *(.init.setup)
++    __setup_end = .;
++  }
++
++  .initcall.init : {
++	__initcall_start = .;
++	*(.initcall1.init)
++	*(.initcall2.init)
++	*(.initcall3.init)
++	*(.initcall4.init)
++	*(.initcall5.init)
++	*(.initcall6.init)
++	*(.initcall7.init)
++	__initcall_end = .;
++  }
++
++  .con_initcall.init : {
++    __con_initcall_start = .;
++    *(.con_initcall.init)
++    __con_initcall_end = .;
++  }
++
++  SECURITY_INIT
++
++#ifdef CONFIG_PPC32
++  __start___ftr_fixup = .;
++  __ftr_fixup : { *(__ftr_fixup) }
++  __stop___ftr_fixup = .;
++#else
++  . = ALIGN(PAGE_SIZE);
++  .init.ramfs : {
++    __initramfs_start = .;
++    *(.init.ramfs)
++    __initramfs_end = .;
++  }
++#endif
++
++#ifdef CONFIG_PPC32
++  . = ALIGN(32);
++#endif
++  .data.percpu : {
++    __per_cpu_start = .;
++    *(.data.percpu)
++    __per_cpu_end = .;
++  }
++
++ . = ALIGN(PAGE_SIZE);
++#ifdef CONFIG_PPC64
++ . = ALIGN(16384);
++ __init_end = .;
++ /* freed after init ends here */
++
++ /* Read/write sections */
++ . = ALIGN(PAGE_SIZE);
++ . = ALIGN(16384);
++ _sdata = .;
++ /* The initial task and kernel stack */
++ .data.init_task : {
++      *(.data.init_task)
++      }
++
++ . = ALIGN(PAGE_SIZE);
++ .data.page_aligned : {
++      *(.data.page_aligned)
++      }
++
++ .data.cacheline_aligned : {
++      *(.data.cacheline_aligned)
++      }
++
++ .data : {
++      *(.data .data.rel* .toc1)
++      *(.branch_lt)
++      }
++
++ .opd : {
++      *(.opd)
++      }
++
++ .got : {
++      __toc_start = .;
++      *(.got)
++      *(.toc)
++      . = ALIGN(PAGE_SIZE);
++      _edata = .;
++      }
++
++  . = ALIGN(PAGE_SIZE);
++#else
++  __initramfs_start = .;
++  .init.ramfs : {
++    *(.init.ramfs)
++  }
++  __initramfs_end = .;
++
++  . = ALIGN(4096);
++  __init_end = .;
++
++  . = ALIGN(4096);
++  _sextratext = .;
++  _eextratext = .;
++
++  __bss_start = .;
++#endif
++
++  .bss : {
++    __bss_start = .;
++   *(.sbss) *(.scommon)
++   *(.dynbss)
++   *(.bss)
++   *(COMMON)
++  __bss_stop = .;
++  }
++
++#ifdef CONFIG_PPC64
++  . = ALIGN(PAGE_SIZE);
++#endif
++  _end = . ;
++#ifdef CONFIG_PPC32
++  PROVIDE (end = .);
++#endif
++}
+diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/Makefile
+@@ -0,0 +1,19 @@
++#
++# Makefile for ppc-specific library files..
++#
++
++ifeq ($(CONFIG_PPC_MERGE),y)
++obj-y			:= string.o
++endif
++
++obj-y			+= strcase.o
++obj-$(CONFIG_PPC32)	+= div64.o copy_32.o checksum_32.o
++obj-$(CONFIG_PPC64)	+= checksum_64.o copypage_64.o copyuser_64.o \
++			   memcpy_64.o usercopy_64.o mem_64.o
++obj-$(CONFIG_PPC_ISERIES) += e2a.o
++obj-$(CONFIG_XMON)	+= sstep.o
++
++ifeq ($(CONFIG_PPC64),y)
++obj-$(CONFIG_SMP)	+= locks.o
++obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
++endif
+diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/checksum_32.S
+@@ -0,0 +1,225 @@
++/*
++ * This file contains assembly-language implementations
++ * of IP-style 1's complement checksum routines.
++ *	
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.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.
++ *
++ * Severely hacked about by Paul Mackerras (paulus at cs.anu.edu.au).
++ */
++
++#include <linux/sys.h>
++#include <asm/processor.h>
++#include <asm/errno.h>
++#include <asm/ppc_asm.h>
++
++	.text
++
++/*
++ * ip_fast_csum(buf, len) -- Optimized for IP header
++ * len is in words and is always >= 5.
++ */
++_GLOBAL(ip_fast_csum)
++	lwz	r0,0(r3)
++	lwzu	r5,4(r3)
++	addic.	r4,r4,-2
++	addc	r0,r0,r5
++	mtctr	r4
++	blelr-
++1:	lwzu	r4,4(r3)
++	adde	r0,r0,r4
++	bdnz	1b
++	addze	r0,r0		/* add in final carry */
++	rlwinm	r3,r0,16,0,31	/* fold two halves together */
++	add	r3,r0,r3
++	not	r3,r3
++	srwi	r3,r3,16
++	blr
++
++/*
++ * Compute checksum of TCP or UDP pseudo-header:
++ *   csum_tcpudp_magic(saddr, daddr, len, proto, sum)
++ */	
++_GLOBAL(csum_tcpudp_magic)
++	rlwimi	r5,r6,16,0,15	/* put proto in upper half of len */
++	addc	r0,r3,r4	/* add 4 32-bit words together */
++	adde	r0,r0,r5
++	adde	r0,r0,r7
++	addze	r0,r0		/* add in final carry */
++	rlwinm	r3,r0,16,0,31	/* fold two halves together */
++	add	r3,r0,r3
++	not	r3,r3
++	srwi	r3,r3,16
++	blr
++
++/*
++ * computes the checksum of a memory block at buff, length len,
++ * and adds in "sum" (32-bit)
++ *
++ * csum_partial(buff, len, sum)
++ */
++_GLOBAL(csum_partial)
++	addic	r0,r5,0
++	subi	r3,r3,4
++	srwi.	r6,r4,2
++	beq	3f		/* if we're doing < 4 bytes */
++	andi.	r5,r3,2		/* Align buffer to longword boundary */
++	beq+	1f
++	lhz	r5,4(r3)	/* do 2 bytes to get aligned */
++	addi	r3,r3,2
++	subi	r4,r4,2
++	addc	r0,r0,r5
++	srwi.	r6,r4,2		/* # words to do */
++	beq	3f
++1:	mtctr	r6
++2:	lwzu	r5,4(r3)	/* the bdnz has zero overhead, so it should */
++	adde	r0,r0,r5	/* be unnecessary to unroll this loop */
++	bdnz	2b
++	andi.	r4,r4,3
++3:	cmpwi	0,r4,2
++	blt+	4f
++	lhz	r5,4(r3)
++	addi	r3,r3,2
++	subi	r4,r4,2
++	adde	r0,r0,r5
++4:	cmpwi	0,r4,1
++	bne+	5f
++	lbz	r5,4(r3)
++	slwi	r5,r5,8		/* Upper byte of word */
++	adde	r0,r0,r5
++5:	addze	r3,r0		/* add in final carry */
++	blr
++
++/*
++ * Computes the checksum of a memory block at src, length len,
++ * and adds in "sum" (32-bit), while copying the block to dst.
++ * If an access exception occurs on src or dst, it stores -EFAULT
++ * to *src_err or *dst_err respectively, and (for an error on
++ * src) zeroes the rest of dst.
++ *
++ * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err)
++ */
++_GLOBAL(csum_partial_copy_generic)
++	addic	r0,r6,0
++	subi	r3,r3,4
++	subi	r4,r4,4
++	srwi.	r6,r5,2
++	beq	3f		/* if we're doing < 4 bytes */
++	andi.	r9,r4,2		/* Align dst to longword boundary */
++	beq+	1f
++81:	lhz	r6,4(r3)	/* do 2 bytes to get aligned */
++	addi	r3,r3,2
++	subi	r5,r5,2
++91:	sth	r6,4(r4)
++	addi	r4,r4,2
++	addc	r0,r0,r6
++	srwi.	r6,r5,2		/* # words to do */
++	beq	3f
++1:	srwi.	r6,r5,4		/* # groups of 4 words to do */
++	beq	10f
++	mtctr	r6
++71:	lwz	r6,4(r3)
++72:	lwz	r9,8(r3)
++73:	lwz	r10,12(r3)
++74:	lwzu	r11,16(r3)
++	adde	r0,r0,r6
++75:	stw	r6,4(r4)
++	adde	r0,r0,r9
++76:	stw	r9,8(r4)
++	adde	r0,r0,r10
++77:	stw	r10,12(r4)
++	adde	r0,r0,r11
++78:	stwu	r11,16(r4)
++	bdnz	71b
++10:	rlwinm.	r6,r5,30,30,31	/* # words left to do */
++	beq	13f
++	mtctr	r6
++82:	lwzu	r9,4(r3)
++92:	stwu	r9,4(r4)
++	adde	r0,r0,r9
++	bdnz	82b
++13:	andi.	r5,r5,3
++3:	cmpwi	0,r5,2
++	blt+	4f
++83:	lhz	r6,4(r3)
++	addi	r3,r3,2
++	subi	r5,r5,2
++93:	sth	r6,4(r4)
++	addi	r4,r4,2
++	adde	r0,r0,r6
++4:	cmpwi	0,r5,1
++	bne+	5f
++84:	lbz	r6,4(r3)
++94:	stb	r6,4(r4)
++	slwi	r6,r6,8		/* Upper byte of word */
++	adde	r0,r0,r6
++5:	addze	r3,r0		/* add in final carry */
++	blr
++
++/* These shouldn't go in the fixup section, since that would
++   cause the ex_table addresses to get out of order. */
++
++src_error_4:
++	mfctr	r6		/* update # bytes remaining from ctr */
++	rlwimi	r5,r6,4,0,27
++	b	79f
++src_error_1:
++	li	r6,0
++	subi	r5,r5,2
++95:	sth	r6,4(r4)
++	addi	r4,r4,2
++79:	srwi.	r6,r5,2
++	beq	3f
++	mtctr	r6
++src_error_2:
++	li	r6,0
++96:	stwu	r6,4(r4)
++	bdnz	96b
++3:	andi.	r5,r5,3
++	beq	src_error
++src_error_3:
++	li	r6,0
++	mtctr	r5
++	addi	r4,r4,3
++97:	stbu	r6,1(r4)
++	bdnz	97b
++src_error:
++	cmpwi	0,r7,0
++	beq	1f
++	li	r6,-EFAULT
++	stw	r6,0(r7)
++1:	addze	r3,r0
++	blr
++
++dst_error:
++	cmpwi	0,r8,0
++	beq	1f
++	li	r6,-EFAULT
++	stw	r6,0(r8)
++1:	addze	r3,r0
++	blr
++
++.section __ex_table,"a"
++	.long	81b,src_error_1
++	.long	91b,dst_error
++	.long	71b,src_error_4
++	.long	72b,src_error_4
++	.long	73b,src_error_4
++	.long	74b,src_error_4
++	.long	75b,dst_error
++	.long	76b,dst_error
++	.long	77b,dst_error
++	.long	78b,dst_error
++	.long	82b,src_error_2
++	.long	92b,dst_error
++	.long	83b,src_error_3
++	.long	93b,dst_error
++	.long	84b,src_error_3
++	.long	94b,dst_error
++	.long	95b,dst_error
++	.long	96b,dst_error
++	.long	97b,dst_error
+diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/checksum_64.S
+@@ -0,0 +1,229 @@
++/*
++ * This file contains assembly-language implementations
++ * of IP-style 1's complement checksum routines.
++ *	
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.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.
++ *
++ * Severely hacked about by Paul Mackerras (paulus at cs.anu.edu.au).
++ */
++
++#include <linux/sys.h>
++#include <asm/processor.h>
++#include <asm/errno.h>
++#include <asm/ppc_asm.h>
++
++/*
++ * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header
++ * len is in words and is always >= 5.
++ *
++ * In practice len == 5, but this is not guaranteed.  So this code does not
++ * attempt to use doubleword instructions.
++ */
++_GLOBAL(ip_fast_csum)
++	lwz	r0,0(r3)
++	lwzu	r5,4(r3)
++	addic.	r4,r4,-2
++	addc	r0,r0,r5
++	mtctr	r4
++	blelr-
++1:	lwzu	r4,4(r3)
++	adde	r0,r0,r4
++	bdnz	1b
++	addze	r0,r0		/* add in final carry */
++        rldicl  r4,r0,32,0      /* fold two 32-bit halves together */
++        add     r0,r0,r4
++        srdi    r0,r0,32
++	rlwinm	r3,r0,16,0,31	/* fold two halves together */
++	add	r3,r0,r3
++	not	r3,r3
++	srwi	r3,r3,16
++	blr
++
++/*
++ * Compute checksum of TCP or UDP pseudo-header:
++ *   csum_tcpudp_magic(r3=saddr, r4=daddr, r5=len, r6=proto, r7=sum)
++ * No real gain trying to do this specially for 64 bit, but
++ * the 32 bit addition may spill into the upper bits of
++ * the doubleword so we still must fold it down from 64.
++ */	
++_GLOBAL(csum_tcpudp_magic)
++	rlwimi	r5,r6,16,0,15	/* put proto in upper half of len */
++	addc	r0,r3,r4	/* add 4 32-bit words together */
++	adde	r0,r0,r5
++	adde	r0,r0,r7
++        rldicl  r4,r0,32,0      /* fold 64 bit value */
++        add     r0,r4,r0
++        srdi    r0,r0,32
++	rlwinm	r3,r0,16,0,31	/* fold two halves together */
++	add	r3,r0,r3
++	not	r3,r3
++	srwi	r3,r3,16
++	blr
++
++/*
++ * Computes the checksum of a memory block at buff, length len,
++ * and adds in "sum" (32-bit).
++ *
++ * This code assumes at least halfword alignment, though the length
++ * can be any number of bytes.  The sum is accumulated in r5.
++ *
++ * csum_partial(r3=buff, r4=len, r5=sum)
++ */
++_GLOBAL(csum_partial)
++        subi	r3,r3,8		/* we'll offset by 8 for the loads */
++        srdi.	r6,r4,3         /* divide by 8 for doubleword count */
++        addic   r5,r5,0         /* clear carry */
++        beq	3f              /* if we're doing < 8 bytes */
++        andi.	r0,r3,2         /* aligned on a word boundary already? */
++        beq+	1f
++        lhz     r6,8(r3)        /* do 2 bytes to get aligned */
++        addi    r3,r3,2
++        subi    r4,r4,2
++        addc    r5,r5,r6
++        srdi.   r6,r4,3         /* recompute number of doublewords */
++        beq     3f              /* any left? */
++1:      mtctr   r6
++2:      ldu     r6,8(r3)        /* main sum loop */
++        adde    r5,r5,r6
++        bdnz    2b
++        andi.	r4,r4,7         /* compute bytes left to sum after doublewords */
++3:	cmpwi	0,r4,4		/* is at least a full word left? */
++	blt	4f
++	lwz	r6,8(r3)	/* sum this word */
++	addi	r3,r3,4
++	subi	r4,r4,4
++	adde	r5,r5,r6
++4:	cmpwi	0,r4,2		/* is at least a halfword left? */
++        blt+	5f
++        lhz     r6,8(r3)        /* sum this halfword */
++        addi    r3,r3,2
++        subi    r4,r4,2
++        adde    r5,r5,r6
++5:	cmpwi	0,r4,1		/* is at least a byte left? */
++        bne+    6f
++        lbz     r6,8(r3)        /* sum this byte */
++        slwi    r6,r6,8         /* this byte is assumed to be the upper byte of a halfword */
++        adde    r5,r5,r6
++6:      addze	r5,r5		/* add in final carry */
++	rldicl  r4,r5,32,0      /* fold two 32-bit halves together */
++        add     r3,r4,r5
++        srdi    r3,r3,32
++        blr
++
++/*
++ * Computes the checksum of a memory block at src, length len,
++ * and adds in "sum" (32-bit), while copying the block to dst.
++ * If an access exception occurs on src or dst, it stores -EFAULT
++ * to *src_err or *dst_err respectively, and (for an error on
++ * src) zeroes the rest of dst.
++ *
++ * This code needs to be reworked to take advantage of 64 bit sum+copy.
++ * However, due to tokenring halfword alignment problems this will be very
++ * tricky.  For now we'll leave it until we instrument it somehow.
++ *
++ * csum_partial_copy_generic(r3=src, r4=dst, r5=len, r6=sum, r7=src_err, r8=dst_err)
++ */
++_GLOBAL(csum_partial_copy_generic)
++	addic	r0,r6,0
++	subi	r3,r3,4
++	subi	r4,r4,4
++	srwi.	r6,r5,2
++	beq	3f		/* if we're doing < 4 bytes */
++	andi.	r9,r4,2		/* Align dst to longword boundary */
++	beq+	1f
++81:	lhz	r6,4(r3)	/* do 2 bytes to get aligned */
++	addi	r3,r3,2
++	subi	r5,r5,2
++91:	sth	r6,4(r4)
++	addi	r4,r4,2
++	addc	r0,r0,r6
++	srwi.	r6,r5,2		/* # words to do */
++	beq	3f
++1:	mtctr	r6
++82:	lwzu	r6,4(r3)	/* the bdnz has zero overhead, so it should */
++92:	stwu	r6,4(r4)	/* be unnecessary to unroll this loop */
++	adde	r0,r0,r6
++	bdnz	82b
++	andi.	r5,r5,3
++3:	cmpwi	0,r5,2
++	blt+	4f
++83:	lhz	r6,4(r3)
++	addi	r3,r3,2
++	subi	r5,r5,2
++93:	sth	r6,4(r4)
++	addi	r4,r4,2
++	adde	r0,r0,r6
++4:	cmpwi	0,r5,1
++	bne+	5f
++84:	lbz	r6,4(r3)
++94:	stb	r6,4(r4)
++	slwi	r6,r6,8		/* Upper byte of word */
++	adde	r0,r0,r6
++5:	addze	r3,r0		/* add in final carry (unlikely with 64-bit regs) */
++        rldicl  r4,r3,32,0      /* fold 64 bit value */
++        add     r3,r4,r3
++        srdi    r3,r3,32
++	blr
++
++/* These shouldn't go in the fixup section, since that would
++   cause the ex_table addresses to get out of order. */
++
++	.globl src_error_1
++src_error_1:
++	li	r6,0
++	subi	r5,r5,2
++95:	sth	r6,4(r4)
++	addi	r4,r4,2
++	srwi.	r6,r5,2
++	beq	3f
++	mtctr	r6
++	.globl src_error_2
++src_error_2:
++	li	r6,0
++96:	stwu	r6,4(r4)
++	bdnz	96b
++3:	andi.	r5,r5,3
++	beq	src_error
++	.globl src_error_3
++src_error_3:
++	li	r6,0
++	mtctr	r5
++	addi	r4,r4,3
++97:	stbu	r6,1(r4)
++	bdnz	97b
++	.globl src_error
++src_error:
++	cmpdi	0,r7,0
++	beq	1f
++	li	r6,-EFAULT
++	stw	r6,0(r7)
++1:	addze	r3,r0
++	blr
++
++	.globl dst_error
++dst_error:
++	cmpdi	0,r8,0
++	beq	1f
++	li	r6,-EFAULT
++	stw	r6,0(r8)
++1:	addze	r3,r0
++	blr
++
++.section __ex_table,"a"
++	.align  3
++	.llong	81b,src_error_1
++	.llong	91b,dst_error
++	.llong	82b,src_error_2
++	.llong	92b,dst_error
++	.llong	83b,src_error_3
++	.llong	93b,dst_error
++	.llong	84b,src_error_3
++	.llong	94b,dst_error
++	.llong	95b,dst_error
++	.llong	96b,dst_error
++	.llong	97b,dst_error
+diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/copy_32.S
+@@ -0,0 +1,543 @@
++/*
++ * Memory copy functions for 32-bit PowerPC.
++ *
++ * Copyright (C) 1996-2005 Paul Mackerras.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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 <asm/processor.h>
++#include <asm/cache.h>
++#include <asm/errno.h>
++#include <asm/ppc_asm.h>
++
++#define COPY_16_BYTES		\
++	lwz	r7,4(r4);	\
++	lwz	r8,8(r4);	\
++	lwz	r9,12(r4);	\
++	lwzu	r10,16(r4);	\
++	stw	r7,4(r6);	\
++	stw	r8,8(r6);	\
++	stw	r9,12(r6);	\
++	stwu	r10,16(r6)
++
++#define COPY_16_BYTES_WITHEX(n)	\
++8 ## n ## 0:			\
++	lwz	r7,4(r4);	\
++8 ## n ## 1:			\
++	lwz	r8,8(r4);	\
++8 ## n ## 2:			\
++	lwz	r9,12(r4);	\
++8 ## n ## 3:			\
++	lwzu	r10,16(r4);	\
++8 ## n ## 4:			\
++	stw	r7,4(r6);	\
++8 ## n ## 5:			\
++	stw	r8,8(r6);	\
++8 ## n ## 6:			\
++	stw	r9,12(r6);	\
++8 ## n ## 7:			\
++	stwu	r10,16(r6)
++
++#define COPY_16_BYTES_EXCODE(n)			\
++9 ## n ## 0:					\
++	addi	r5,r5,-(16 * n);		\
++	b	104f;				\
++9 ## n ## 1:					\
++	addi	r5,r5,-(16 * n);		\
++	b	105f;				\
++.section __ex_table,"a";			\
++	.align	2;				\
++	.long	8 ## n ## 0b,9 ## n ## 0b;	\
++	.long	8 ## n ## 1b,9 ## n ## 0b;	\
++	.long	8 ## n ## 2b,9 ## n ## 0b;	\
++	.long	8 ## n ## 3b,9 ## n ## 0b;	\
++	.long	8 ## n ## 4b,9 ## n ## 1b;	\
++	.long	8 ## n ## 5b,9 ## n ## 1b;	\
++	.long	8 ## n ## 6b,9 ## n ## 1b;	\
++	.long	8 ## n ## 7b,9 ## n ## 1b;	\
++	.text
++
++	.text
++	.stabs	"arch/powerpc/lib/",N_SO,0,0,0f
++	.stabs	"copy32.S",N_SO,0,0,0f
++0:
++
++CACHELINE_BYTES = L1_CACHE_BYTES
++LG_CACHELINE_BYTES = L1_CACHE_SHIFT
++CACHELINE_MASK = (L1_CACHE_BYTES-1)
++
++/*
++ * Use dcbz on the complete cache lines in the destination
++ * to set them to zero.  This requires that the destination
++ * area is cacheable.  -- paulus
++ */
++_GLOBAL(cacheable_memzero)
++	mr	r5,r4
++	li	r4,0
++	addi	r6,r3,-4
++	cmplwi	0,r5,4
++	blt	7f
++	stwu	r4,4(r6)
++	beqlr
++	andi.	r0,r6,3
++	add	r5,r0,r5
++	subf	r6,r0,r6
++	clrlwi	r7,r6,32-LG_CACHELINE_BYTES
++	add	r8,r7,r5
++	srwi	r9,r8,LG_CACHELINE_BYTES
++	addic.	r9,r9,-1	/* total number of complete cachelines */
++	ble	2f
++	xori	r0,r7,CACHELINE_MASK & ~3
++	srwi.	r0,r0,2
++	beq	3f
++	mtctr	r0
++4:	stwu	r4,4(r6)
++	bdnz	4b
++3:	mtctr	r9
++	li	r7,4
++#if !defined(CONFIG_8xx)
++10:	dcbz	r7,r6
++#else
++10:	stw	r4, 4(r6)
++	stw	r4, 8(r6)
++	stw	r4, 12(r6)
++	stw	r4, 16(r6)
++#if CACHE_LINE_SIZE >= 32
++	stw	r4, 20(r6)
++	stw	r4, 24(r6)
++	stw	r4, 28(r6)
++	stw	r4, 32(r6)
++#endif /* CACHE_LINE_SIZE */
++#endif
++	addi	r6,r6,CACHELINE_BYTES
++	bdnz	10b
++	clrlwi	r5,r8,32-LG_CACHELINE_BYTES
++	addi	r5,r5,4
++2:	srwi	r0,r5,2
++	mtctr	r0
++	bdz	6f
++1:	stwu	r4,4(r6)
++	bdnz	1b
++6:	andi.	r5,r5,3
++7:	cmpwi	0,r5,0
++	beqlr
++	mtctr	r5
++	addi	r6,r6,3
++8:	stbu	r4,1(r6)
++	bdnz	8b
++	blr
++
++_GLOBAL(memset)
++	rlwimi	r4,r4,8,16,23
++	rlwimi	r4,r4,16,0,15
++	addi	r6,r3,-4
++	cmplwi	0,r5,4
++	blt	7f
++	stwu	r4,4(r6)
++	beqlr
++	andi.	r0,r6,3
++	add	r5,r0,r5
++	subf	r6,r0,r6
++	srwi	r0,r5,2
++	mtctr	r0
++	bdz	6f
++1:	stwu	r4,4(r6)
++	bdnz	1b
++6:	andi.	r5,r5,3
++7:	cmpwi	0,r5,0
++	beqlr
++	mtctr	r5
++	addi	r6,r6,3
++8:	stbu	r4,1(r6)
++	bdnz	8b
++	blr
++
++/*
++ * This version uses dcbz on the complete cache lines in the
++ * destination area to reduce memory traffic.  This requires that
++ * the destination area is cacheable.
++ * We only use this version if the source and dest don't overlap.
++ * -- paulus.
++ */
++_GLOBAL(cacheable_memcpy)
++	add	r7,r3,r5		/* test if the src & dst overlap */
++	add	r8,r4,r5
++	cmplw	0,r4,r7
++	cmplw	1,r3,r8
++	crand	0,0,4			/* cr0.lt &= cr1.lt */
++	blt	memcpy			/* if regions overlap */
++
++	addi	r4,r4,-4
++	addi	r6,r3,-4
++	neg	r0,r3
++	andi.	r0,r0,CACHELINE_MASK	/* # bytes to start of cache line */
++	beq	58f
++
++	cmplw	0,r5,r0			/* is this more than total to do? */
++	blt	63f			/* if not much to do */
++	andi.	r8,r0,3			/* get it word-aligned first */
++	subf	r5,r0,r5
++	mtctr	r8
++	beq+	61f
++70:	lbz	r9,4(r4)		/* do some bytes */
++	stb	r9,4(r6)
++	addi	r4,r4,1
++	addi	r6,r6,1
++	bdnz	70b
++61:	srwi.	r0,r0,2
++	mtctr	r0
++	beq	58f
++72:	lwzu	r9,4(r4)		/* do some words */
++	stwu	r9,4(r6)
++	bdnz	72b
++
++58:	srwi.	r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
++	clrlwi	r5,r5,32-LG_CACHELINE_BYTES
++	li	r11,4
++	mtctr	r0
++	beq	63f
++53:
++#if !defined(CONFIG_8xx)
++	dcbz	r11,r6
++#endif
++	COPY_16_BYTES
++#if L1_CACHE_BYTES >= 32
++	COPY_16_BYTES
++#if L1_CACHE_BYTES >= 64
++	COPY_16_BYTES
++	COPY_16_BYTES
++#if L1_CACHE_BYTES >= 128
++	COPY_16_BYTES
++	COPY_16_BYTES
++	COPY_16_BYTES
++	COPY_16_BYTES
++#endif
++#endif
++#endif
++	bdnz	53b
++
++63:	srwi.	r0,r5,2
++	mtctr	r0
++	beq	64f
++30:	lwzu	r0,4(r4)
++	stwu	r0,4(r6)
++	bdnz	30b
++
++64:	andi.	r0,r5,3
++	mtctr	r0
++	beq+	65f
++40:	lbz	r0,4(r4)
++	stb	r0,4(r6)
++	addi	r4,r4,1
++	addi	r6,r6,1
++	bdnz	40b
++65:	blr
++
++_GLOBAL(memmove)
++	cmplw	0,r3,r4
++	bgt	backwards_memcpy
++	/* fall through */
++
++_GLOBAL(memcpy)
++	srwi.	r7,r5,3
++	addi	r6,r3,-4
++	addi	r4,r4,-4
++	beq	2f			/* if less than 8 bytes to do */
++	andi.	r0,r6,3			/* get dest word aligned */
++	mtctr	r7
++	bne	5f
++1:	lwz	r7,4(r4)
++	lwzu	r8,8(r4)
++	stw	r7,4(r6)
++	stwu	r8,8(r6)
++	bdnz	1b
++	andi.	r5,r5,7
++2:	cmplwi	0,r5,4
++	blt	3f
++	lwzu	r0,4(r4)
++	addi	r5,r5,-4
++	stwu	r0,4(r6)
++3:	cmpwi	0,r5,0
++	beqlr
++	mtctr	r5
++	addi	r4,r4,3
++	addi	r6,r6,3
++4:	lbzu	r0,1(r4)
++	stbu	r0,1(r6)
++	bdnz	4b
++	blr
++5:	subfic	r0,r0,4
++	mtctr	r0
++6:	lbz	r7,4(r4)
++	addi	r4,r4,1
++	stb	r7,4(r6)
++	addi	r6,r6,1
++	bdnz	6b
++	subf	r5,r0,r5
++	rlwinm.	r7,r5,32-3,3,31
++	beq	2b
++	mtctr	r7
++	b	1b
++
++_GLOBAL(backwards_memcpy)
++	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
++	add	r6,r3,r5
++	add	r4,r4,r5
++	beq	2f
++	andi.	r0,r6,3
++	mtctr	r7
++	bne	5f
++1:	lwz	r7,-4(r4)
++	lwzu	r8,-8(r4)
++	stw	r7,-4(r6)
++	stwu	r8,-8(r6)
++	bdnz	1b
++	andi.	r5,r5,7
++2:	cmplwi	0,r5,4
++	blt	3f
++	lwzu	r0,-4(r4)
++	subi	r5,r5,4
++	stwu	r0,-4(r6)
++3:	cmpwi	0,r5,0
++	beqlr
++	mtctr	r5
++4:	lbzu	r0,-1(r4)
++	stbu	r0,-1(r6)
++	bdnz	4b
++	blr
++5:	mtctr	r0
++6:	lbzu	r7,-1(r4)
++	stbu	r7,-1(r6)
++	bdnz	6b
++	subf	r5,r0,r5
++	rlwinm.	r7,r5,32-3,3,31
++	beq	2b
++	mtctr	r7
++	b	1b
++
++_GLOBAL(__copy_tofrom_user)
++	addi	r4,r4,-4
++	addi	r6,r3,-4
++	neg	r0,r3
++	andi.	r0,r0,CACHELINE_MASK	/* # bytes to start of cache line */
++	beq	58f
++
++	cmplw	0,r5,r0			/* is this more than total to do? */
++	blt	63f			/* if not much to do */
++	andi.	r8,r0,3			/* get it word-aligned first */
++	mtctr	r8
++	beq+	61f
++70:	lbz	r9,4(r4)		/* do some bytes */
++71:	stb	r9,4(r6)
++	addi	r4,r4,1
++	addi	r6,r6,1
++	bdnz	70b
++61:	subf	r5,r0,r5
++	srwi.	r0,r0,2
++	mtctr	r0
++	beq	58f
++72:	lwzu	r9,4(r4)		/* do some words */
++73:	stwu	r9,4(r6)
++	bdnz	72b
++
++	.section __ex_table,"a"
++	.align	2
++	.long	70b,100f
++	.long	71b,101f
++	.long	72b,102f
++	.long	73b,103f
++	.text
++
++58:	srwi.	r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
++	clrlwi	r5,r5,32-LG_CACHELINE_BYTES
++	li	r11,4
++	beq	63f
++
++#ifdef CONFIG_8xx
++	/* Don't use prefetch on 8xx */
++	mtctr	r0
++	li	r0,0
++53:	COPY_16_BYTES_WITHEX(0)
++	bdnz	53b
++
++#else /* not CONFIG_8xx */
++	/* Here we decide how far ahead to prefetch the source */
++	li	r3,4
++	cmpwi	r0,1
++	li	r7,0
++	ble	114f
++	li	r7,1
++#if MAX_COPY_PREFETCH > 1
++	/* Heuristically, for large transfers we prefetch
++	   MAX_COPY_PREFETCH cachelines ahead.  For small transfers
++	   we prefetch 1 cacheline ahead. */
++	cmpwi	r0,MAX_COPY_PREFETCH
++	ble	112f
++	li	r7,MAX_COPY_PREFETCH
++112:	mtctr	r7
++111:	dcbt	r3,r4
++	addi	r3,r3,CACHELINE_BYTES
++	bdnz	111b
++#else
++	dcbt	r3,r4
++	addi	r3,r3,CACHELINE_BYTES
++#endif /* MAX_COPY_PREFETCH > 1 */
++
++114:	subf	r8,r7,r0
++	mr	r0,r7
++	mtctr	r8
++
++53:	dcbt	r3,r4
++54:	dcbz	r11,r6
++	.section __ex_table,"a"
++	.align	2
++	.long	54b,105f
++	.text
++/* the main body of the cacheline loop */
++	COPY_16_BYTES_WITHEX(0)
++#if L1_CACHE_BYTES >= 32
++	COPY_16_BYTES_WITHEX(1)
++#if L1_CACHE_BYTES >= 64
++	COPY_16_BYTES_WITHEX(2)
++	COPY_16_BYTES_WITHEX(3)
++#if L1_CACHE_BYTES >= 128
++	COPY_16_BYTES_WITHEX(4)
++	COPY_16_BYTES_WITHEX(5)
++	COPY_16_BYTES_WITHEX(6)
++	COPY_16_BYTES_WITHEX(7)
++#endif
++#endif
++#endif
++	bdnz	53b
++	cmpwi	r0,0
++	li	r3,4
++	li	r7,0
++	bne	114b
++#endif /* CONFIG_8xx */
++
++63:	srwi.	r0,r5,2
++	mtctr	r0
++	beq	64f
++30:	lwzu	r0,4(r4)
++31:	stwu	r0,4(r6)
++	bdnz	30b
++
++64:	andi.	r0,r5,3
++	mtctr	r0
++	beq+	65f
++40:	lbz	r0,4(r4)
++41:	stb	r0,4(r6)
++	addi	r4,r4,1
++	addi	r6,r6,1
++	bdnz	40b
++65:	li	r3,0
++	blr
++
++/* read fault, initial single-byte copy */
++100:	li	r9,0
++	b	90f
++/* write fault, initial single-byte copy */
++101:	li	r9,1
++90:	subf	r5,r8,r5
++	li	r3,0
++	b	99f
++/* read fault, initial word copy */
++102:	li	r9,0
++	b	91f
++/* write fault, initial word copy */
++103:	li	r9,1
++91:	li	r3,2
++	b	99f
++
++/*
++ * this stuff handles faults in the cacheline loop and branches to either
++ * 104f (if in read part) or 105f (if in write part), after updating r5
++ */
++	COPY_16_BYTES_EXCODE(0)
++#if L1_CACHE_BYTES >= 32
++	COPY_16_BYTES_EXCODE(1)
++#if L1_CACHE_BYTES >= 64
++	COPY_16_BYTES_EXCODE(2)
++	COPY_16_BYTES_EXCODE(3)
++#if L1_CACHE_BYTES >= 128
++	COPY_16_BYTES_EXCODE(4)
++	COPY_16_BYTES_EXCODE(5)
++	COPY_16_BYTES_EXCODE(6)
++	COPY_16_BYTES_EXCODE(7)
++#endif
++#endif
++#endif
++
++/* read fault in cacheline loop */
++104:	li	r9,0
++	b	92f
++/* fault on dcbz (effectively a write fault) */
++/* or write fault in cacheline loop */
++105:	li	r9,1
++92:	li	r3,LG_CACHELINE_BYTES
++	mfctr	r8
++	add	r0,r0,r8
++	b	106f
++/* read fault in final word loop */
++108:	li	r9,0
++	b	93f
++/* write fault in final word loop */
++109:	li	r9,1
++93:	andi.	r5,r5,3
++	li	r3,2
++	b	99f
++/* read fault in final byte loop */
++110:	li	r9,0
++	b	94f
++/* write fault in final byte loop */
++111:	li	r9,1
++94:	li	r5,0
++	li	r3,0
++/*
++ * At this stage the number of bytes not copied is
++ * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
++ */
++99:	mfctr	r0
++106:	slw	r3,r0,r3
++	add.	r3,r3,r5
++	beq	120f			/* shouldn't happen */
++	cmpwi	0,r9,0
++	bne	120f
++/* for a read fault, first try to continue the copy one byte at a time */
++	mtctr	r3
++130:	lbz	r0,4(r4)
++131:	stb	r0,4(r6)
++	addi	r4,r4,1
++	addi	r6,r6,1
++	bdnz	130b
++/* then clear out the destination: r3 bytes starting at 4(r6) */
++132:	mfctr	r3
++	srwi.	r0,r3,2
++	li	r9,0
++	mtctr	r0
++	beq	113f
++112:	stwu	r9,4(r6)
++	bdnz	112b
++113:	andi.	r0,r3,3
++	mtctr	r0
++	beq	120f
++114:	stb	r9,4(r6)
++	addi	r6,r6,1
++	bdnz	114b
++120:	blr
++
++	.section __ex_table,"a"
++	.align	2
++	.long	30b,108b
++	.long	31b,109b
++	.long	40b,110b
++	.long	41b,111b
++	.long	130b,132b
++	.long	131b,120b
++	.long	112b,120b
++	.long	114b,120b
++	.text
+diff --git a/arch/powerpc/lib/copypage_64.S b/arch/powerpc/lib/copypage_64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/copypage_64.S
+@@ -0,0 +1,121 @@
++/*
++ * arch/ppc64/lib/copypage.S
++ *
++ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <asm/processor.h>
++#include <asm/ppc_asm.h>
++
++_GLOBAL(copy_page)
++	std	r31,-8(1)
++	std	r30,-16(1)
++	std	r29,-24(1)
++	std	r28,-32(1)
++	std	r27,-40(1)
++	std	r26,-48(1)
++	std	r25,-56(1)
++	std	r24,-64(1)
++	std	r23,-72(1)
++	std	r22,-80(1)
++	std	r21,-88(1)
++	std	r20,-96(1)
++	li	r5,4096/32 - 1
++	addi	r3,r3,-8
++	li	r12,5
++0:	addi	r5,r5,-24
++	mtctr	r12
++	ld	r22,640(4)
++	ld	r21,512(4)
++	ld	r20,384(4)
++	ld	r11,256(4)
++	ld	r9,128(4)
++	ld	r7,0(4)
++	ld	r25,648(4)
++	ld	r24,520(4)
++	ld	r23,392(4)
++	ld	r10,264(4)
++	ld	r8,136(4)
++	ldu	r6,8(4)
++	cmpwi	r5,24
++1:	std	r22,648(3)
++	std	r21,520(3)
++	std	r20,392(3)
++	std	r11,264(3)
++	std	r9,136(3)
++	std	r7,8(3)
++	ld	r28,648(4)
++	ld	r27,520(4)
++	ld	r26,392(4)
++	ld	r31,264(4)
++	ld	r30,136(4)
++	ld	r29,8(4)
++	std	r25,656(3)
++	std	r24,528(3)
++	std	r23,400(3)
++	std	r10,272(3)
++	std	r8,144(3)
++	std	r6,16(3)
++	ld	r22,656(4)
++	ld	r21,528(4)
++	ld	r20,400(4)
++	ld	r11,272(4)
++	ld	r9,144(4)
++	ld	r7,16(4)
++	std	r28,664(3)
++	std	r27,536(3)
++	std	r26,408(3)
++	std	r31,280(3)
++	std	r30,152(3)
++	stdu	r29,24(3)
++	ld	r25,664(4)
++	ld	r24,536(4)
++	ld	r23,408(4)
++	ld	r10,280(4)
++	ld	r8,152(4)
++	ldu	r6,24(4)
++	bdnz	1b
++	std	r22,648(3)
++	std	r21,520(3)
++	std	r20,392(3)
++	std	r11,264(3)
++	std	r9,136(3)
++	std	r7,8(3)
++	addi	r4,r4,640
++	addi	r3,r3,648
++	bge	0b
++	mtctr	r5
++	ld	r7,0(4)
++	ld	r8,8(4)
++	ldu	r9,16(4)
++3:	ld	r10,8(4)
++	std	r7,8(3)
++	ld	r7,16(4)
++	std	r8,16(3)
++	ld	r8,24(4)
++	std	r9,24(3)
++	ldu	r9,32(4)
++	stdu	r10,32(3)
++	bdnz	3b
++4:	ld	r10,8(4)
++	std	r7,8(3)
++	std	r8,16(3)
++	std	r9,24(3)
++	std	r10,32(3)
++9:	ld	r20,-96(1)
++	ld	r21,-88(1)
++	ld	r22,-80(1)
++	ld	r23,-72(1)
++	ld	r24,-64(1)
++	ld	r25,-56(1)
++	ld	r26,-48(1)
++	ld	r27,-40(1)
++	ld	r28,-32(1)
++	ld	r29,-24(1)
++	ld	r30,-16(1)
++	ld	r31,-8(1)
++	blr
+diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/copyuser_64.S
+@@ -0,0 +1,576 @@
++/*
++ * arch/ppc64/lib/copyuser.S
++ *
++ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <asm/processor.h>
++#include <asm/ppc_asm.h>
++
++	.align	7
++_GLOBAL(__copy_tofrom_user)
++	/* first check for a whole page copy on a page boundary */
++	cmpldi	cr1,r5,16
++	cmpdi	cr6,r5,4096
++	or	r0,r3,r4
++	neg	r6,r3		/* LS 3 bits = # bytes to 8-byte dest bdry */
++	andi.	r0,r0,4095
++	std	r3,-24(r1)
++	crand	cr0*4+2,cr0*4+2,cr6*4+2
++	std	r4,-16(r1)
++	std	r5,-8(r1)
++	dcbt	0,r4
++	beq	.Lcopy_page
++	andi.	r6,r6,7
++	mtcrf	0x01,r5
++	blt	cr1,.Lshort_copy
++	bne	.Ldst_unaligned
++.Ldst_aligned:
++	andi.	r0,r4,7
++	addi	r3,r3,-16
++	bne	.Lsrc_unaligned
++	srdi	r7,r5,4
++20:	ld	r9,0(r4)
++	addi	r4,r4,-8
++	mtctr	r7
++	andi.	r5,r5,7
++	bf	cr7*4+0,22f
++	addi	r3,r3,8
++	addi	r4,r4,8
++	mr	r8,r9
++	blt	cr1,72f
++21:	ld	r9,8(r4)
++70:	std	r8,8(r3)
++22:	ldu	r8,16(r4)
++71:	stdu	r9,16(r3)
++	bdnz	21b
++72:	std	r8,8(r3)
++	beq+	3f
++	addi	r3,r3,16
++23:	ld	r9,8(r4)
++.Ldo_tail:
++	bf	cr7*4+1,1f
++	rotldi	r9,r9,32
++73:	stw	r9,0(r3)
++	addi	r3,r3,4
++1:	bf	cr7*4+2,2f
++	rotldi	r9,r9,16
++74:	sth	r9,0(r3)
++	addi	r3,r3,2
++2:	bf	cr7*4+3,3f
++	rotldi	r9,r9,8
++75:	stb	r9,0(r3)
++3:	li	r3,0
++	blr
++
++.Lsrc_unaligned:
++	srdi	r6,r5,3
++	addi	r5,r5,-16
++	subf	r4,r0,r4
++	srdi	r7,r5,4
++	sldi	r10,r0,3
++	cmpldi	cr6,r6,3
++	andi.	r5,r5,7
++	mtctr	r7
++	subfic	r11,r10,64
++	add	r5,r5,r0
++	bt	cr7*4+0,28f
++
++24:	ld	r9,0(r4)	/* 3+2n loads, 2+2n stores */
++25:	ld	r0,8(r4)
++	sld	r6,r9,r10
++26:	ldu	r9,16(r4)
++	srd	r7,r0,r11
++	sld	r8,r0,r10
++	or	r7,r7,r6
++	blt	cr6,79f
++27:	ld	r0,8(r4)
++	b	2f
++
++28:	ld	r0,0(r4)	/* 4+2n loads, 3+2n stores */
++29:	ldu	r9,8(r4)
++	sld	r8,r0,r10
++	addi	r3,r3,-8
++	blt	cr6,5f
++30:	ld	r0,8(r4)
++	srd	r12,r9,r11
++	sld	r6,r9,r10
++31:	ldu	r9,16(r4)
++	or	r12,r8,r12
++	srd	r7,r0,r11
++	sld	r8,r0,r10
++	addi	r3,r3,16
++	beq	cr6,78f
++
++1:	or	r7,r7,r6
++32:	ld	r0,8(r4)
++76:	std	r12,8(r3)
++2:	srd	r12,r9,r11
++	sld	r6,r9,r10
++33:	ldu	r9,16(r4)
++	or	r12,r8,r12
++77:	stdu	r7,16(r3)
++	srd	r7,r0,r11
++	sld	r8,r0,r10
++	bdnz	1b
++
++78:	std	r12,8(r3)
++	or	r7,r7,r6
++79:	std	r7,16(r3)
++5:	srd	r12,r9,r11
++	or	r12,r8,r12
++80:	std	r12,24(r3)
++	bne	6f
++	li	r3,0
++	blr
++6:	cmpwi	cr1,r5,8
++	addi	r3,r3,32
++	sld	r9,r9,r10
++	ble	cr1,.Ldo_tail
++34:	ld	r0,8(r4)
++	srd	r7,r0,r11
++	or	r9,r7,r9
++	b	.Ldo_tail
++
++.Ldst_unaligned:
++	mtcrf	0x01,r6		/* put #bytes to 8B bdry into cr7 */
++	subf	r5,r6,r5
++	li	r7,0
++	cmpldi	r1,r5,16
++	bf	cr7*4+3,1f
++35:	lbz	r0,0(r4)
++81:	stb	r0,0(r3)
++	addi	r7,r7,1
++1:	bf	cr7*4+2,2f
++36:	lhzx	r0,r7,r4
++82:	sthx	r0,r7,r3
++	addi	r7,r7,2
++2:	bf	cr7*4+1,3f
++37:	lwzx	r0,r7,r4
++83:	stwx	r0,r7,r3
++3:	mtcrf	0x01,r5
++	add	r4,r6,r4
++	add	r3,r6,r3
++	b	.Ldst_aligned
++
++.Lshort_copy:
++	bf	cr7*4+0,1f
++38:	lwz	r0,0(r4)
++39:	lwz	r9,4(r4)
++	addi	r4,r4,8
++84:	stw	r0,0(r3)
++85:	stw	r9,4(r3)
++	addi	r3,r3,8
++1:	bf	cr7*4+1,2f
++40:	lwz	r0,0(r4)
++	addi	r4,r4,4
++86:	stw	r0,0(r3)
++	addi	r3,r3,4
++2:	bf	cr7*4+2,3f
++41:	lhz	r0,0(r4)
++	addi	r4,r4,2
++87:	sth	r0,0(r3)
++	addi	r3,r3,2
++3:	bf	cr7*4+3,4f
++42:	lbz	r0,0(r4)
++88:	stb	r0,0(r3)
++4:	li	r3,0
++	blr
++
++/*
++ * exception handlers follow
++ * we have to return the number of bytes not copied
++ * for an exception on a load, we set the rest of the destination to 0
++ */
++
++136:
++137:
++	add	r3,r3,r7
++	b	1f
++130:
++131:
++	addi	r3,r3,8
++120:
++122:
++124:
++125:
++126:
++127:
++128:
++129:
++133:
++	addi	r3,r3,8
++121:
++132:
++	addi	r3,r3,8
++123:
++134:
++135:
++138:
++139:
++140:
++141:
++142:
++
++/*
++ * here we have had a fault on a load and r3 points to the first
++ * unmodified byte of the destination
++ */
++1:	ld	r6,-24(r1)
++	ld	r4,-16(r1)
++	ld	r5,-8(r1)
++	subf	r6,r6,r3
++	add	r4,r4,r6
++	subf	r5,r6,r5	/* #bytes left to go */
++
++/*
++ * first see if we can copy any more bytes before hitting another exception
++ */
++	mtctr	r5
++43:	lbz	r0,0(r4)
++	addi	r4,r4,1
++89:	stb	r0,0(r3)
++	addi	r3,r3,1
++	bdnz	43b
++	li	r3,0		/* huh? all copied successfully this time? */
++	blr
++
++/*
++ * here we have trapped again, need to clear ctr bytes starting at r3
++ */
++143:	mfctr	r5
++	li	r0,0
++	mr	r4,r3
++	mr	r3,r5		/* return the number of bytes not copied */
++1:	andi.	r9,r4,7
++	beq	3f
++90:	stb	r0,0(r4)
++	addic.	r5,r5,-1
++	addi	r4,r4,1
++	bne	1b
++	blr
++3:	cmpldi	cr1,r5,8
++	srdi	r9,r5,3
++	andi.	r5,r5,7
++	blt	cr1,93f
++	mtctr	r9
++91:	std	r0,0(r4)
++	addi	r4,r4,8
++	bdnz	91b
++93:	beqlr
++	mtctr	r5	
++92:	stb	r0,0(r4)
++	addi	r4,r4,1
++	bdnz	92b
++	blr
++
++/*
++ * exception handlers for stores: we just need to work
++ * out how many bytes weren't copied
++ */
++182:
++183:
++	add	r3,r3,r7
++	b	1f
++180:
++	addi	r3,r3,8
++171:
++177:
++	addi	r3,r3,8
++170:
++172:
++176:
++178:
++	addi	r3,r3,4
++185:
++	addi	r3,r3,4
++173:
++174:
++175:
++179:
++181:
++184:
++186:
++187:
++188:
++189:	
++1:
++	ld	r6,-24(r1)
++	ld	r5,-8(r1)
++	add	r6,r6,r5
++	subf	r3,r3,r6	/* #bytes not copied */
++190:
++191:
++192:
++	blr			/* #bytes not copied in r3 */
++
++	.section __ex_table,"a"
++	.align	3
++	.llong	20b,120b
++	.llong	21b,121b
++	.llong	70b,170b
++	.llong	22b,122b
++	.llong	71b,171b
++	.llong	72b,172b
++	.llong	23b,123b
++	.llong	73b,173b
++	.llong	74b,174b
++	.llong	75b,175b
++	.llong	24b,124b
++	.llong	25b,125b
++	.llong	26b,126b
++	.llong	27b,127b
++	.llong	28b,128b
++	.llong	29b,129b
++	.llong	30b,130b
++	.llong	31b,131b
++	.llong	32b,132b
++	.llong	76b,176b
++	.llong	33b,133b
++	.llong	77b,177b
++	.llong	78b,178b
++	.llong	79b,179b
++	.llong	80b,180b
++	.llong	34b,134b
++	.llong	35b,135b
++	.llong	81b,181b
++	.llong	36b,136b
++	.llong	82b,182b
++	.llong	37b,137b
++	.llong	83b,183b
++	.llong	38b,138b
++	.llong	39b,139b
++	.llong	84b,184b
++	.llong	85b,185b
++	.llong	40b,140b
++	.llong	86b,186b
++	.llong	41b,141b
++	.llong	87b,187b
++	.llong	42b,142b
++	.llong	88b,188b
++	.llong	43b,143b
++	.llong	89b,189b
++	.llong	90b,190b
++	.llong	91b,191b
++	.llong	92b,192b
++	
++	.text
++
++/*
++ * Routine to copy a whole page of data, optimized for POWER4.
++ * On POWER4 it is more than 50% faster than the simple loop
++ * above (following the .Ldst_aligned label) but it runs slightly
++ * slower on POWER3.
++ */
++.Lcopy_page:
++	std	r31,-32(1)
++	std	r30,-40(1)
++	std	r29,-48(1)
++	std	r28,-56(1)
++	std	r27,-64(1)
++	std	r26,-72(1)
++	std	r25,-80(1)
++	std	r24,-88(1)
++	std	r23,-96(1)
++	std	r22,-104(1)
++	std	r21,-112(1)
++	std	r20,-120(1)
++	li	r5,4096/32 - 1
++	addi	r3,r3,-8
++	li	r0,5
++0:	addi	r5,r5,-24
++	mtctr	r0
++20:	ld	r22,640(4)
++21:	ld	r21,512(4)
++22:	ld	r20,384(4)
++23:	ld	r11,256(4)
++24:	ld	r9,128(4)
++25:	ld	r7,0(4)
++26:	ld	r25,648(4)
++27:	ld	r24,520(4)
++28:	ld	r23,392(4)
++29:	ld	r10,264(4)
++30:	ld	r8,136(4)
++31:	ldu	r6,8(4)
++	cmpwi	r5,24
++1:
++32:	std	r22,648(3)
++33:	std	r21,520(3)
++34:	std	r20,392(3)
++35:	std	r11,264(3)
++36:	std	r9,136(3)
++37:	std	r7,8(3)
++38:	ld	r28,648(4)
++39:	ld	r27,520(4)
++40:	ld	r26,392(4)
++41:	ld	r31,264(4)
++42:	ld	r30,136(4)
++43:	ld	r29,8(4)
++44:	std	r25,656(3)
++45:	std	r24,528(3)
++46:	std	r23,400(3)
++47:	std	r10,272(3)
++48:	std	r8,144(3)
++49:	std	r6,16(3)
++50:	ld	r22,656(4)
++51:	ld	r21,528(4)
++52:	ld	r20,400(4)
++53:	ld	r11,272(4)
++54:	ld	r9,144(4)
++55:	ld	r7,16(4)
++56:	std	r28,664(3)
++57:	std	r27,536(3)
++58:	std	r26,408(3)
++59:	std	r31,280(3)
++60:	std	r30,152(3)
++61:	stdu	r29,24(3)
++62:	ld	r25,664(4)
++63:	ld	r24,536(4)
++64:	ld	r23,408(4)
++65:	ld	r10,280(4)
++66:	ld	r8,152(4)
++67:	ldu	r6,24(4)
++	bdnz	1b
++68:	std	r22,648(3)
++69:	std	r21,520(3)
++70:	std	r20,392(3)
++71:	std	r11,264(3)
++72:	std	r9,136(3)
++73:	std	r7,8(3)
++74:	addi	r4,r4,640
++75:	addi	r3,r3,648
++	bge	0b
++	mtctr	r5
++76:	ld	r7,0(4)
++77:	ld	r8,8(4)
++78:	ldu	r9,16(4)
++3:
++79:	ld	r10,8(4)
++80:	std	r7,8(3)
++81:	ld	r7,16(4)
++82:	std	r8,16(3)
++83:	ld	r8,24(4)
++84:	std	r9,24(3)
++85:	ldu	r9,32(4)
++86:	stdu	r10,32(3)
++	bdnz	3b
++4:
++87:	ld	r10,8(4)
++88:	std	r7,8(3)
++89:	std	r8,16(3)
++90:	std	r9,24(3)
++91:	std	r10,32(3)
++9:	ld	r20,-120(1)
++	ld	r21,-112(1)
++	ld	r22,-104(1)
++	ld	r23,-96(1)
++	ld	r24,-88(1)
++	ld	r25,-80(1)
++	ld	r26,-72(1)
++	ld	r27,-64(1)
++	ld	r28,-56(1)
++	ld	r29,-48(1)
++	ld	r30,-40(1)
++	ld	r31,-32(1)
++	li	r3,0
++	blr
++
++/*
++ * on an exception, reset to the beginning and jump back into the
++ * standard __copy_tofrom_user
++ */
++100:	ld	r20,-120(1)
++	ld	r21,-112(1)
++	ld	r22,-104(1)
++	ld	r23,-96(1)
++	ld	r24,-88(1)
++	ld	r25,-80(1)
++	ld	r26,-72(1)
++	ld	r27,-64(1)
++	ld	r28,-56(1)
++	ld	r29,-48(1)
++	ld	r30,-40(1)
++	ld	r31,-32(1)
++	ld	r3,-24(r1)
++	ld	r4,-16(r1)
++	li	r5,4096
++	b	.Ldst_aligned
++
++	.section __ex_table,"a"
++	.align	3
++	.llong	20b,100b
++	.llong	21b,100b
++	.llong	22b,100b
++	.llong	23b,100b
++	.llong	24b,100b
++	.llong	25b,100b
++	.llong	26b,100b
++	.llong	27b,100b
++	.llong	28b,100b
++	.llong	29b,100b
++	.llong	30b,100b
++	.llong	31b,100b
++	.llong	32b,100b
++	.llong	33b,100b
++	.llong	34b,100b
++	.llong	35b,100b
++	.llong	36b,100b
++	.llong	37b,100b
++	.llong	38b,100b
++	.llong	39b,100b
++	.llong	40b,100b
++	.llong	41b,100b
++	.llong	42b,100b
++	.llong	43b,100b
++	.llong	44b,100b
++	.llong	45b,100b
++	.llong	46b,100b
++	.llong	47b,100b
++	.llong	48b,100b
++	.llong	49b,100b
++	.llong	50b,100b
++	.llong	51b,100b
++	.llong	52b,100b
++	.llong	53b,100b
++	.llong	54b,100b
++	.llong	55b,100b
++	.llong	56b,100b
++	.llong	57b,100b
++	.llong	58b,100b
++	.llong	59b,100b
++	.llong	60b,100b
++	.llong	61b,100b
++	.llong	62b,100b
++	.llong	63b,100b
++	.llong	64b,100b
++	.llong	65b,100b
++	.llong	66b,100b
++	.llong	67b,100b
++	.llong	68b,100b
++	.llong	69b,100b
++	.llong	70b,100b
++	.llong	71b,100b
++	.llong	72b,100b
++	.llong	73b,100b
++	.llong	74b,100b
++	.llong	75b,100b
++	.llong	76b,100b
++	.llong	77b,100b
++	.llong	78b,100b
++	.llong	79b,100b
++	.llong	80b,100b
++	.llong	81b,100b
++	.llong	82b,100b
++	.llong	83b,100b
++	.llong	84b,100b
++	.llong	85b,100b
++	.llong	86b,100b
++	.llong	87b,100b
++	.llong	88b,100b
++	.llong	89b,100b
++	.llong	90b,100b
++	.llong	91b,100b
+diff --git a/arch/powerpc/lib/div64.S b/arch/powerpc/lib/div64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/div64.S
+@@ -0,0 +1,59 @@
++/*
++ * Divide a 64-bit unsigned number by a 32-bit unsigned number.
++ * This routine assumes that the top 32 bits of the dividend are
++ * non-zero to start with.
++ * On entry, r3 points to the dividend, which get overwritten with
++ * the 64-bit quotient, and r4 contains the divisor.
++ * On exit, r3 contains the remainder.
++ *
++ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <asm/ppc_asm.h>
++#include <asm/processor.h>
++
++_GLOBAL(__div64_32)
++	lwz	r5,0(r3)	# get the dividend into r5/r6
++	lwz	r6,4(r3)
++	cmplw	r5,r4
++	li	r7,0
++	li	r8,0
++	blt	1f
++	divwu	r7,r5,r4	# if dividend.hi >= divisor,
++	mullw	r0,r7,r4	# quotient.hi = dividend.hi / divisor
++	subf.	r5,r0,r5	# dividend.hi %= divisor
++	beq	3f
++1:	mr	r11,r5		# here dividend.hi != 0
++	andis.	r0,r5,0xc000
++	bne	2f
++	cntlzw	r0,r5		# we are shifting the dividend right
++	li	r10,-1		# to make it < 2^32, and shifting
++	srw	r10,r10,r0	# the divisor right the same amount,
++	addc	r9,r4,r10	# rounding up (so the estimate cannot
++	andc	r11,r6,r10	# ever be too large, only too small)
++	andc	r9,r9,r10
++	addze	r9,r9
++	or	r11,r5,r11
++	rotlw	r9,r9,r0
++	rotlw	r11,r11,r0
++	divwu	r11,r11,r9	# then we divide the shifted quantities
++2:	mullw	r10,r11,r4	# to get an estimate of the quotient,
++	mulhwu	r9,r11,r4	# multiply the estimate by the divisor,
++	subfc	r6,r10,r6	# take the product from the divisor,
++	add	r8,r8,r11	# and add the estimate to the accumulated
++	subfe.	r5,r9,r5	# quotient
++	bne	1b
++3:	cmplw	r6,r4
++	blt	4f
++	divwu	r0,r6,r4	# perform the remaining 32-bit division
++	mullw	r10,r0,r4	# and get the remainder
++	add	r8,r8,r0
++	subf	r6,r10,r6
++4:	stw	r7,0(r3)	# return the quotient in *r3
++	stw	r8,4(r3)
++	mr	r3,r6		# return the remainder in r3
++	blr
+diff --git a/arch/powerpc/lib/e2a.c b/arch/powerpc/lib/e2a.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/e2a.c
+@@ -0,0 +1,108 @@
++/*
++ *  arch/ppc64/lib/e2a.c
++ *
++ *  EBCDIC to ASCII conversion
++ *
++ * This function moved here from arch/ppc64/kernel/viopath.c
++ *
++ * (C) Copyright 2000-2004 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) anyu 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>
++
++unsigned char e2a(unsigned char x)
++{
++	switch (x) {
++	case 0xF0:
++		return '0';
++	case 0xF1:
++		return '1';
++	case 0xF2:
++		return '2';
++	case 0xF3:
++		return '3';
++	case 0xF4:
++		return '4';
++	case 0xF5:
++		return '5';
++	case 0xF6:
++		return '6';
++	case 0xF7:
++		return '7';
++	case 0xF8:
++		return '8';
++	case 0xF9:
++		return '9';
++	case 0xC1:
++		return 'A';
++	case 0xC2:
++		return 'B';
++	case 0xC3:
++		return 'C';
++	case 0xC4:
++		return 'D';
++	case 0xC5:
++		return 'E';
++	case 0xC6:
++		return 'F';
++	case 0xC7:
++		return 'G';
++	case 0xC8:
++		return 'H';
++	case 0xC9:
++		return 'I';
++	case 0xD1:
++		return 'J';
++	case 0xD2:
++		return 'K';
++	case 0xD3:
++		return 'L';
++	case 0xD4:
++		return 'M';
++	case 0xD5:
++		return 'N';
++	case 0xD6:
++		return 'O';
++	case 0xD7:
++		return 'P';
++	case 0xD8:
++		return 'Q';
++	case 0xD9:
++		return 'R';
++	case 0xE2:
++		return 'S';
++	case 0xE3:
++		return 'T';
++	case 0xE4:
++		return 'U';
++	case 0xE5:
++		return 'V';
++	case 0xE6:
++		return 'W';
++	case 0xE7:
++		return 'X';
++	case 0xE8:
++		return 'Y';
++	case 0xE9:
++		return 'Z';
++	}
++	return ' ';
++}
++EXPORT_SYMBOL(e2a);
++
++
+diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/locks.c
+@@ -0,0 +1,96 @@
++/*
++ * Spin and read/write lock operations.
++ *
++ * Copyright (C) 2001-2004 Paul Mackerras <paulus at au.ibm.com>, IBM
++ * Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, IBM
++ * Copyright (C) 2002 Dave Engebretsen <engebret at us.ibm.com>, IBM
++ *   Rework to support virtual processors
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/spinlock.h>
++#include <linux/module.h>
++#include <linux/stringify.h>
++#include <linux/smp.h>
++
++/* waiting for a spinlock... */
++#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
++#include <asm/hvcall.h>
++#include <asm/iSeries/HvCall.h>
++
++void __spin_yield(raw_spinlock_t *lock)
++{
++	unsigned int lock_value, holder_cpu, yield_count;
++	struct paca_struct *holder_paca;
++
++	lock_value = lock->slock;
++	if (lock_value == 0)
++		return;
++	holder_cpu = lock_value & 0xffff;
++	BUG_ON(holder_cpu >= NR_CPUS);
++	holder_paca = &paca[holder_cpu];
++	yield_count = holder_paca->lppaca.yield_count;
++	if ((yield_count & 1) == 0)
++		return;		/* virtual cpu is currently running */
++	rmb();
++	if (lock->slock != lock_value)
++		return;		/* something has changed */
++#ifdef CONFIG_PPC_ISERIES
++	HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
++		((u64)holder_cpu << 32) | yield_count);
++#else
++	plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
++			   yield_count);
++#endif
++}
++
++/*
++ * Waiting for a read lock or a write lock on a rwlock...
++ * This turns out to be the same for read and write locks, since
++ * we only know the holder if it is write-locked.
++ */
++void __rw_yield(raw_rwlock_t *rw)
++{
++	int lock_value;
++	unsigned int holder_cpu, yield_count;
++	struct paca_struct *holder_paca;
++
++	lock_value = rw->lock;
++	if (lock_value >= 0)
++		return;		/* no write lock at present */
++	holder_cpu = lock_value & 0xffff;
++	BUG_ON(holder_cpu >= NR_CPUS);
++	holder_paca = &paca[holder_cpu];
++	yield_count = holder_paca->lppaca.yield_count;
++	if ((yield_count & 1) == 0)
++		return;		/* virtual cpu is currently running */
++	rmb();
++	if (rw->lock != lock_value)
++		return;		/* something has changed */
++#ifdef CONFIG_PPC_ISERIES
++	HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
++		((u64)holder_cpu << 32) | yield_count);
++#else
++	plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
++			   yield_count);
++#endif
++}
++#endif
++
++void __raw_spin_unlock_wait(raw_spinlock_t *lock)
++{
++	while (lock->slock) {
++		HMT_low();
++		if (SHARED_PROCESSOR)
++			__spin_yield(lock);
++	}
++	HMT_medium();
++}
++
++EXPORT_SYMBOL(__raw_spin_unlock_wait);
+diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/mem_64.S
+@@ -0,0 +1,119 @@
++/*
++ * String handling functions for PowerPC.
++ *
++ * Copyright (C) 1996 Paul Mackerras.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/processor.h>
++#include <asm/errno.h>
++#include <asm/ppc_asm.h>
++
++_GLOBAL(memset)
++	neg	r0,r3
++	rlwimi	r4,r4,8,16,23
++	andi.	r0,r0,7			/* # bytes to be 8-byte aligned */
++	rlwimi	r4,r4,16,0,15
++	cmplw	cr1,r5,r0		/* do we get that far? */
++	rldimi	r4,r4,32,0
++	mtcrf	1,r0
++	mr	r6,r3
++	blt	cr1,8f
++	beq+	3f			/* if already 8-byte aligned */
++	subf	r5,r0,r5
++	bf	31,1f
++	stb	r4,0(r6)
++	addi	r6,r6,1
++1:	bf	30,2f
++	sth	r4,0(r6)
++	addi	r6,r6,2
++2:	bf	29,3f
++	stw	r4,0(r6)
++	addi	r6,r6,4
++3:	srdi.	r0,r5,6
++	clrldi	r5,r5,58
++	mtctr	r0
++	beq	5f
++4:	std	r4,0(r6)
++	std	r4,8(r6)
++	std	r4,16(r6)
++	std	r4,24(r6)
++	std	r4,32(r6)
++	std	r4,40(r6)
++	std	r4,48(r6)
++	std	r4,56(r6)
++	addi	r6,r6,64
++	bdnz	4b
++5:	srwi.	r0,r5,3
++	clrlwi	r5,r5,29
++	mtcrf	1,r0
++	beq	8f
++	bf	29,6f
++	std	r4,0(r6)
++	std	r4,8(r6)
++	std	r4,16(r6)
++	std	r4,24(r6)
++	addi	r6,r6,32
++6:	bf	30,7f
++	std	r4,0(r6)
++	std	r4,8(r6)
++	addi	r6,r6,16
++7:	bf	31,8f
++	std	r4,0(r6)
++	addi	r6,r6,8
++8:	cmpwi	r5,0
++	mtcrf	1,r5
++	beqlr+
++	bf	29,9f
++	stw	r4,0(r6)
++	addi	r6,r6,4
++9:	bf	30,10f
++	sth	r4,0(r6)
++	addi	r6,r6,2
++10:	bflr	31
++	stb	r4,0(r6)
++	blr
++
++_GLOBAL(memmove)
++	cmplw	0,r3,r4
++	bgt	.backwards_memcpy
++	b	.memcpy
++
++_GLOBAL(backwards_memcpy)
++	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
++	add	r6,r3,r5
++	add	r4,r4,r5
++	beq	2f
++	andi.	r0,r6,3
++	mtctr	r7
++	bne	5f
++1:	lwz	r7,-4(r4)
++	lwzu	r8,-8(r4)
++	stw	r7,-4(r6)
++	stwu	r8,-8(r6)
++	bdnz	1b
++	andi.	r5,r5,7
++2:	cmplwi	0,r5,4
++	blt	3f
++	lwzu	r0,-4(r4)
++	subi	r5,r5,4
++	stwu	r0,-4(r6)
++3:	cmpwi	0,r5,0
++	beqlr
++	mtctr	r5
++4:	lbzu	r0,-1(r4)
++	stbu	r0,-1(r6)
++	bdnz	4b
++	blr
++5:	mtctr	r0
++6:	lbzu	r7,-1(r4)
++	stbu	r7,-1(r6)
++	bdnz	6b
++	subf	r5,r0,r5
++	rlwinm.	r7,r5,32-3,3,31
++	beq	2b
++	mtctr	r7
++	b	1b
+diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/memcpy_64.S
+@@ -0,0 +1,172 @@
++/*
++ * arch/ppc64/lib/memcpy.S
++ *
++ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <asm/processor.h>
++#include <asm/ppc_asm.h>
++
++	.align	7
++_GLOBAL(memcpy)
++	mtcrf	0x01,r5
++	cmpldi	cr1,r5,16
++	neg	r6,r3		# LS 3 bits = # bytes to 8-byte dest bdry
++	andi.	r6,r6,7
++	dcbt	0,r4
++	blt	cr1,.Lshort_copy
++	bne	.Ldst_unaligned
++.Ldst_aligned:
++	andi.	r0,r4,7
++	addi	r3,r3,-16
++	bne	.Lsrc_unaligned
++	srdi	r7,r5,4
++	ld	r9,0(r4)
++	addi	r4,r4,-8
++	mtctr	r7
++	andi.	r5,r5,7
++	bf	cr7*4+0,2f
++	addi	r3,r3,8
++	addi	r4,r4,8
++	mr	r8,r9
++	blt	cr1,3f
++1:	ld	r9,8(r4)
++	std	r8,8(r3)
++2:	ldu	r8,16(r4)
++	stdu	r9,16(r3)
++	bdnz	1b
++3:	std	r8,8(r3)
++	beqlr
++	addi	r3,r3,16
++	ld	r9,8(r4)
++.Ldo_tail:
++	bf	cr7*4+1,1f
++	rotldi	r9,r9,32
++	stw	r9,0(r3)
++	addi	r3,r3,4
++1:	bf	cr7*4+2,2f
++	rotldi	r9,r9,16
++	sth	r9,0(r3)
++	addi	r3,r3,2
++2:	bf	cr7*4+3,3f
++	rotldi	r9,r9,8
++	stb	r9,0(r3)
++3:	blr
++
++.Lsrc_unaligned:
++	srdi	r6,r5,3
++	addi	r5,r5,-16
++	subf	r4,r0,r4
++	srdi	r7,r5,4
++	sldi	r10,r0,3
++	cmpdi	cr6,r6,3
++	andi.	r5,r5,7
++	mtctr	r7
++	subfic	r11,r10,64
++	add	r5,r5,r0
++
++	bt	cr7*4+0,0f
++
++	ld	r9,0(r4)	# 3+2n loads, 2+2n stores
++	ld	r0,8(r4)
++	sld	r6,r9,r10
++	ldu	r9,16(r4)
++	srd	r7,r0,r11
++	sld	r8,r0,r10
++	or	r7,r7,r6
++	blt	cr6,4f
++	ld	r0,8(r4)
++	# s1<< in r8, d0=(s0<<|s1>>) in r7, s3 in r0, s2 in r9, nix in r6 & r12
++	b	2f
++
++0:	ld	r0,0(r4)	# 4+2n loads, 3+2n stores
++	ldu	r9,8(r4)
++	sld	r8,r0,r10
++	addi	r3,r3,-8
++	blt	cr6,5f
++	ld	r0,8(r4)
++	srd	r12,r9,r11
++	sld	r6,r9,r10
++	ldu	r9,16(r4)
++	or	r12,r8,r12
++	srd	r7,r0,r11
++	sld	r8,r0,r10
++	addi	r3,r3,16
++	beq	cr6,3f
++
++	# d0=(s0<<|s1>>) in r12, s1<< in r6, s2>> in r7, s2<< in r8, s3 in r9
++1:	or	r7,r7,r6
++	ld	r0,8(r4)
++	std	r12,8(r3)
++2:	srd	r12,r9,r11
++	sld	r6,r9,r10
++	ldu	r9,16(r4)
++	or	r12,r8,r12
++	stdu	r7,16(r3)
++	srd	r7,r0,r11
++	sld	r8,r0,r10
++	bdnz	1b
++
++3:	std	r12,8(r3)
++	or	r7,r7,r6
++4:	std	r7,16(r3)
++5:	srd	r12,r9,r11
++	or	r12,r8,r12
++	std	r12,24(r3)
++	beqlr
++	cmpwi	cr1,r5,8
++	addi	r3,r3,32
++	sld	r9,r9,r10
++	ble	cr1,.Ldo_tail
++	ld	r0,8(r4)
++	srd	r7,r0,r11
++	or	r9,r7,r9
++	b	.Ldo_tail
++
++.Ldst_unaligned:
++	mtcrf	0x01,r6		# put #bytes to 8B bdry into cr7
++	subf	r5,r6,r5
++	li	r7,0
++	cmpldi	r1,r5,16
++	bf	cr7*4+3,1f
++	lbz	r0,0(r4)
++	stb	r0,0(r3)
++	addi	r7,r7,1
++1:	bf	cr7*4+2,2f
++	lhzx	r0,r7,r4
++	sthx	r0,r7,r3
++	addi	r7,r7,2
++2:	bf	cr7*4+1,3f
++	lwzx	r0,r7,r4
++	stwx	r0,r7,r3
++3:	mtcrf	0x01,r5
++	add	r4,r6,r4
++	add	r3,r6,r3
++	b	.Ldst_aligned
++
++.Lshort_copy:
++	bf	cr7*4+0,1f
++	lwz	r0,0(r4)
++	lwz	r9,4(r4)
++	addi	r4,r4,8
++	stw	r0,0(r3)
++	stw	r9,4(r3)
++	addi	r3,r3,8
++1:	bf	cr7*4+1,2f
++	lwz	r0,0(r4)
++	addi	r4,r4,4
++	stw	r0,0(r3)
++	addi	r3,r3,4
++2:	bf	cr7*4+2,3f
++	lhz	r0,0(r4)
++	addi	r4,r4,2
++	sth	r0,0(r3)
++	addi	r3,r3,2
++3:	bf	cr7*4+3,4f
++	lbz	r0,0(r4)
++	stb	r0,0(r3)
++4:	blr
+diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/rheap.c
+@@ -0,0 +1,693 @@
++/*
++ * arch/ppc/syslib/rheap.c
++ *
++ * A Remote Heap.  Remote means that we don't touch the memory that the
++ * heap points to. Normal heap implementations use the memory they manage
++ * to place their list. We cannot do that because the memory we manage may
++ * have special properties, for example it is uncachable or of different
++ * endianess.
++ *
++ * Author: Pantelis Antoniou <panto at intracom.gr>
++ *
++ * 2004 (c) INTRACOM S.A. Greece. 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/errno.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++
++#include <asm/rheap.h>
++
++/*
++ * Fixup a list_head, needed when copying lists.  If the pointers fall
++ * between s and e, apply the delta.  This assumes that
++ * sizeof(struct list_head *) == sizeof(unsigned long *).
++ */
++static inline void fixup(unsigned long s, unsigned long e, int d,
++			 struct list_head *l)
++{
++	unsigned long *pp;
++
++	pp = (unsigned long *)&l->next;
++	if (*pp >= s && *pp < e)
++		*pp += d;
++
++	pp = (unsigned long *)&l->prev;
++	if (*pp >= s && *pp < e)
++		*pp += d;
++}
++
++/* Grow the allocated blocks */
++static int grow(rh_info_t * info, int max_blocks)
++{
++	rh_block_t *block, *blk;
++	int i, new_blocks;
++	int delta;
++	unsigned long blks, blke;
++
++	if (max_blocks <= info->max_blocks)
++		return -EINVAL;
++
++	new_blocks = max_blocks - info->max_blocks;
++
++	block = kmalloc(sizeof(rh_block_t) * max_blocks, GFP_KERNEL);
++	if (block == NULL)
++		return -ENOMEM;
++
++	if (info->max_blocks > 0) {
++
++		/* copy old block area */
++		memcpy(block, info->block,
++		       sizeof(rh_block_t) * info->max_blocks);
++
++		delta = (char *)block - (char *)info->block;
++
++		/* and fixup list pointers */
++		blks = (unsigned long)info->block;
++		blke = (unsigned long)(info->block + info->max_blocks);
++
++		for (i = 0, blk = block; i < info->max_blocks; i++, blk++)
++			fixup(blks, blke, delta, &blk->list);
++
++		fixup(blks, blke, delta, &info->empty_list);
++		fixup(blks, blke, delta, &info->free_list);
++		fixup(blks, blke, delta, &info->taken_list);
++
++		/* free the old allocated memory */
++		if ((info->flags & RHIF_STATIC_BLOCK) == 0)
++			kfree(info->block);
++	}
++
++	info->block = block;
++	info->empty_slots += new_blocks;
++	info->max_blocks = max_blocks;
++	info->flags &= ~RHIF_STATIC_BLOCK;
++
++	/* add all new blocks to the free list */
++	for (i = 0, blk = block + info->max_blocks; i < new_blocks; i++, blk++)
++		list_add(&blk->list, &info->empty_list);
++
++	return 0;
++}
++
++/*
++ * Assure at least the required amount of empty slots.  If this function
++ * causes a grow in the block area then all pointers kept to the block
++ * area are invalid!
++ */
++static int assure_empty(rh_info_t * info, int slots)
++{
++	int max_blocks;
++
++	/* This function is not meant to be used to grow uncontrollably */
++	if (slots >= 4)
++		return -EINVAL;
++
++	/* Enough space */
++	if (info->empty_slots >= slots)
++		return 0;
++
++	/* Next 16 sized block */
++	max_blocks = ((info->max_blocks + slots) + 15) & ~15;
++
++	return grow(info, max_blocks);
++}
++
++static rh_block_t *get_slot(rh_info_t * info)
++{
++	rh_block_t *blk;
++
++	/* If no more free slots, and failure to extend. */
++	/* XXX: You should have called assure_empty before */
++	if (info->empty_slots == 0) {
++		printk(KERN_ERR "rh: out of slots; crash is imminent.\n");
++		return NULL;
++	}
++
++	/* Get empty slot to use */
++	blk = list_entry(info->empty_list.next, rh_block_t, list);
++	list_del_init(&blk->list);
++	info->empty_slots--;
++
++	/* Initialize */
++	blk->start = NULL;
++	blk->size = 0;
++	blk->owner = NULL;
++
++	return blk;
++}
++
++static inline void release_slot(rh_info_t * info, rh_block_t * blk)
++{
++	list_add(&blk->list, &info->empty_list);
++	info->empty_slots++;
++}
++
++static void attach_free_block(rh_info_t * info, rh_block_t * blkn)
++{
++	rh_block_t *blk;
++	rh_block_t *before;
++	rh_block_t *after;
++	rh_block_t *next;
++	int size;
++	unsigned long s, e, bs, be;
++	struct list_head *l;
++
++	/* We assume that they are aligned properly */
++	size = blkn->size;
++	s = (unsigned long)blkn->start;
++	e = s + size;
++
++	/* Find the blocks immediately before and after the given one
++	 * (if any) */
++	before = NULL;
++	after = NULL;
++	next = NULL;
++
++	list_for_each(l, &info->free_list) {
++		blk = list_entry(l, rh_block_t, list);
++
++		bs = (unsigned long)blk->start;
++		be = bs + blk->size;
++
++		if (next == NULL && s >= bs)
++			next = blk;
++
++		if (be == s)
++			before = blk;
++
++		if (e == bs)
++			after = blk;
++
++		/* If both are not null, break now */
++		if (before != NULL && after != NULL)
++			break;
++	}
++
++	/* Now check if they are really adjacent */
++	if (before != NULL && s != (unsigned long)before->start + before->size)
++		before = NULL;
++
++	if (after != NULL && e != (unsigned long)after->start)
++		after = NULL;
++
++	/* No coalescing; list insert and return */
++	if (before == NULL && after == NULL) {
++
++		if (next != NULL)
++			list_add(&blkn->list, &next->list);
++		else
++			list_add(&blkn->list, &info->free_list);
++
++		return;
++	}
++
++	/* We don't need it anymore */
++	release_slot(info, blkn);
++
++	/* Grow the before block */
++	if (before != NULL && after == NULL) {
++		before->size += size;
++		return;
++	}
++
++	/* Grow the after block backwards */
++	if (before == NULL && after != NULL) {
++		after->start = (int8_t *)after->start - size;
++		after->size += size;
++		return;
++	}
++
++	/* Grow the before block, and release the after block */
++	before->size += size + after->size;
++	list_del(&after->list);
++	release_slot(info, after);
++}
++
++static void attach_taken_block(rh_info_t * info, rh_block_t * blkn)
++{
++	rh_block_t *blk;
++	struct list_head *l;
++
++	/* Find the block immediately before the given one (if any) */
++	list_for_each(l, &info->taken_list) {
++		blk = list_entry(l, rh_block_t, list);
++		if (blk->start > blkn->start) {
++			list_add_tail(&blkn->list, &blk->list);
++			return;
++		}
++	}
++
++	list_add_tail(&blkn->list, &info->taken_list);
++}
++
++/*
++ * Create a remote heap dynamically.  Note that no memory for the blocks
++ * are allocated.  It will upon the first allocation
++ */
++rh_info_t *rh_create(unsigned int alignment)
++{
++	rh_info_t *info;
++
++	/* Alignment must be a power of two */
++	if ((alignment & (alignment - 1)) != 0)
++		return ERR_PTR(-EINVAL);
++
++	info = kmalloc(sizeof(*info), GFP_KERNEL);
++	if (info == NULL)
++		return ERR_PTR(-ENOMEM);
++
++	info->alignment = alignment;
++
++	/* Initially everything as empty */
++	info->block = NULL;
++	info->max_blocks = 0;
++	info->empty_slots = 0;
++	info->flags = 0;
++
++	INIT_LIST_HEAD(&info->empty_list);
++	INIT_LIST_HEAD(&info->free_list);
++	INIT_LIST_HEAD(&info->taken_list);
++
++	return info;
++}
++
++/*
++ * Destroy a dynamically created remote heap.  Deallocate only if the areas
++ * are not static
++ */
++void rh_destroy(rh_info_t * info)
++{
++	if ((info->flags & RHIF_STATIC_BLOCK) == 0 && info->block != NULL)
++		kfree(info->block);
++
++	if ((info->flags & RHIF_STATIC_INFO) == 0)
++		kfree(info);
++}
++
++/*
++ * Initialize in place a remote heap info block.  This is needed to support
++ * operation very early in the startup of the kernel, when it is not yet safe
++ * to call kmalloc.
++ */
++void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks,
++	     rh_block_t * block)
++{
++	int i;
++	rh_block_t *blk;
++
++	/* Alignment must be a power of two */
++	if ((alignment & (alignment - 1)) != 0)
++		return;
++
++	info->alignment = alignment;
++
++	/* Initially everything as empty */
++	info->block = block;
++	info->max_blocks = max_blocks;
++	info->empty_slots = max_blocks;
++	info->flags = RHIF_STATIC_INFO | RHIF_STATIC_BLOCK;
++
++	INIT_LIST_HEAD(&info->empty_list);
++	INIT_LIST_HEAD(&info->free_list);
++	INIT_LIST_HEAD(&info->taken_list);
++
++	/* Add all new blocks to the free list */
++	for (i = 0, blk = block; i < max_blocks; i++, blk++)
++		list_add(&blk->list, &info->empty_list);
++}
++
++/* Attach a free memory region, coalesces regions if adjuscent */
++int rh_attach_region(rh_info_t * info, void *start, int size)
++{
++	rh_block_t *blk;
++	unsigned long s, e, m;
++	int r;
++
++	/* The region must be aligned */
++	s = (unsigned long)start;
++	e = s + size;
++	m = info->alignment - 1;
++
++	/* Round start up */
++	s = (s + m) & ~m;
++
++	/* Round end down */
++	e = e & ~m;
++
++	/* Take final values */
++	start = (void *)s;
++	size = (int)(e - s);
++
++	/* Grow the blocks, if needed */
++	r = assure_empty(info, 1);
++	if (r < 0)
++		return r;
++
++	blk = get_slot(info);
++	blk->start = start;
++	blk->size = size;
++	blk->owner = NULL;
++
++	attach_free_block(info, blk);
++
++	return 0;
++}
++
++/* Detatch given address range, splits free block if needed. */
++void *rh_detach_region(rh_info_t * info, void *start, int size)
++{
++	struct list_head *l;
++	rh_block_t *blk, *newblk;
++	unsigned long s, e, m, bs, be;
++
++	/* Validate size */
++	if (size <= 0)
++		return ERR_PTR(-EINVAL);
++
++	/* The region must be aligned */
++	s = (unsigned long)start;
++	e = s + size;
++	m = info->alignment - 1;
++
++	/* Round start up */
++	s = (s + m) & ~m;
++
++	/* Round end down */
++	e = e & ~m;
++
++	if (assure_empty(info, 1) < 0)
++		return ERR_PTR(-ENOMEM);
++
++	blk = NULL;
++	list_for_each(l, &info->free_list) {
++		blk = list_entry(l, rh_block_t, list);
++		/* The range must lie entirely inside one free block */
++		bs = (unsigned long)blk->start;
++		be = (unsigned long)blk->start + blk->size;
++		if (s >= bs && e <= be)
++			break;
++		blk = NULL;
++	}
++
++	if (blk == NULL)
++		return ERR_PTR(-ENOMEM);
++
++	/* Perfect fit */
++	if (bs == s && be == e) {
++		/* Delete from free list, release slot */
++		list_del(&blk->list);
++		release_slot(info, blk);
++		return (void *)s;
++	}
++
++	/* blk still in free list, with updated start and/or size */
++	if (bs == s || be == e) {
++		if (bs == s)
++			blk->start = (int8_t *)blk->start + size;
++		blk->size -= size;
++
++	} else {
++		/* The front free fragment */
++		blk->size = s - bs;
++
++		/* the back free fragment */
++		newblk = get_slot(info);
++		newblk->start = (void *)e;
++		newblk->size = be - e;
++
++		list_add(&newblk->list, &blk->list);
++	}
++
++	return (void *)s;
++}
++
++void *rh_alloc(rh_info_t * info, int size, const char *owner)
++{
++	struct list_head *l;
++	rh_block_t *blk;
++	rh_block_t *newblk;
++	void *start;
++
++	/* Validate size */
++	if (size <= 0)
++		return ERR_PTR(-EINVAL);
++
++	/* Align to configured alignment */
++	size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
++
++	if (assure_empty(info, 1) < 0)
++		return ERR_PTR(-ENOMEM);
++
++	blk = NULL;
++	list_for_each(l, &info->free_list) {
++		blk = list_entry(l, rh_block_t, list);
++		if (size <= blk->size)
++			break;
++		blk = NULL;
++	}
++
++	if (blk == NULL)
++		return ERR_PTR(-ENOMEM);
++
++	/* Just fits */
++	if (blk->size == size) {
++		/* Move from free list to taken list */
++		list_del(&blk->list);
++		blk->owner = owner;
++		start = blk->start;
++
++		attach_taken_block(info, blk);
++
++		return start;
++	}
++
++	newblk = get_slot(info);
++	newblk->start = blk->start;
++	newblk->size = size;
++	newblk->owner = owner;
++
++	/* blk still in free list, with updated start, size */
++	blk->start = (int8_t *)blk->start + size;
++	blk->size -= size;
++
++	start = newblk->start;
++
++	attach_taken_block(info, newblk);
++
++	return start;
++}
++
++/* allocate at precisely the given address */
++void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
++{
++	struct list_head *l;
++	rh_block_t *blk, *newblk1, *newblk2;
++	unsigned long s, e, m, bs, be;
++
++	/* Validate size */
++	if (size <= 0)
++		return ERR_PTR(-EINVAL);
++
++	/* The region must be aligned */
++	s = (unsigned long)start;
++	e = s + size;
++	m = info->alignment - 1;
++
++	/* Round start up */
++	s = (s + m) & ~m;
++
++	/* Round end down */
++	e = e & ~m;
++
++	if (assure_empty(info, 2) < 0)
++		return ERR_PTR(-ENOMEM);
++
++	blk = NULL;
++	list_for_each(l, &info->free_list) {
++		blk = list_entry(l, rh_block_t, list);
++		/* The range must lie entirely inside one free block */
++		bs = (unsigned long)blk->start;
++		be = (unsigned long)blk->start + blk->size;
++		if (s >= bs && e <= be)
++			break;
++	}
++
++	if (blk == NULL)
++		return ERR_PTR(-ENOMEM);
++
++	/* Perfect fit */
++	if (bs == s && be == e) {
++		/* Move from free list to taken list */
++		list_del(&blk->list);
++		blk->owner = owner;
++
++		start = blk->start;
++		attach_taken_block(info, blk);
++
++		return start;
++
++	}
++
++	/* blk still in free list, with updated start and/or size */
++	if (bs == s || be == e) {
++		if (bs == s)
++			blk->start = (int8_t *)blk->start + size;
++		blk->size -= size;
++
++	} else {
++		/* The front free fragment */
++		blk->size = s - bs;
++
++		/* The back free fragment */
++		newblk2 = get_slot(info);
++		newblk2->start = (void *)e;
++		newblk2->size = be - e;
++
++		list_add(&newblk2->list, &blk->list);
++	}
++
++	newblk1 = get_slot(info);
++	newblk1->start = (void *)s;
++	newblk1->size = e - s;
++	newblk1->owner = owner;
++
++	start = newblk1->start;
++	attach_taken_block(info, newblk1);
++
++	return start;
++}
++
++int rh_free(rh_info_t * info, void *start)
++{
++	rh_block_t *blk, *blk2;
++	struct list_head *l;
++	int size;
++
++	/* Linear search for block */
++	blk = NULL;
++	list_for_each(l, &info->taken_list) {
++		blk2 = list_entry(l, rh_block_t, list);
++		if (start < blk2->start)
++			break;
++		blk = blk2;
++	}
++
++	if (blk == NULL || start > (blk->start + blk->size))
++		return -EINVAL;
++
++	/* Remove from taken list */
++	list_del(&blk->list);
++
++	/* Get size of freed block */
++	size = blk->size;
++	attach_free_block(info, blk);
++
++	return size;
++}
++
++int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)
++{
++	rh_block_t *blk;
++	struct list_head *l;
++	struct list_head *h;
++	int nr;
++
++	switch (what) {
++
++	case RHGS_FREE:
++		h = &info->free_list;
++		break;
++
++	case RHGS_TAKEN:
++		h = &info->taken_list;
++		break;
++
++	default:
++		return -EINVAL;
++	}
++
++	/* Linear search for block */
++	nr = 0;
++	list_for_each(l, h) {
++		blk = list_entry(l, rh_block_t, list);
++		if (stats != NULL && nr < max_stats) {
++			stats->start = blk->start;
++			stats->size = blk->size;
++			stats->owner = blk->owner;
++			stats++;
++		}
++		nr++;
++	}
++
++	return nr;
++}
++
++int rh_set_owner(rh_info_t * info, void *start, const char *owner)
++{
++	rh_block_t *blk, *blk2;
++	struct list_head *l;
++	int size;
++
++	/* Linear search for block */
++	blk = NULL;
++	list_for_each(l, &info->taken_list) {
++		blk2 = list_entry(l, rh_block_t, list);
++		if (start < blk2->start)
++			break;
++		blk = blk2;
++	}
++
++	if (blk == NULL || start > (blk->start + blk->size))
++		return -EINVAL;
++
++	blk->owner = owner;
++	size = blk->size;
++
++	return size;
++}
++
++void rh_dump(rh_info_t * info)
++{
++	static rh_stats_t st[32];	/* XXX maximum 32 blocks */
++	int maxnr;
++	int i, nr;
++
++	maxnr = sizeof(st) / sizeof(st[0]);
++
++	printk(KERN_INFO
++	       "info @0x%p (%d slots empty / %d max)\n",
++	       info, info->empty_slots, info->max_blocks);
++
++	printk(KERN_INFO "  Free:\n");
++	nr = rh_get_stats(info, RHGS_FREE, maxnr, st);
++	if (nr > maxnr)
++		nr = maxnr;
++	for (i = 0; i < nr; i++)
++		printk(KERN_INFO
++		       "    0x%p-0x%p (%u)\n",
++		       st[i].start, (int8_t *) st[i].start + st[i].size,
++		       st[i].size);
++	printk(KERN_INFO "\n");
++
++	printk(KERN_INFO "  Taken:\n");
++	nr = rh_get_stats(info, RHGS_TAKEN, maxnr, st);
++	if (nr > maxnr)
++		nr = maxnr;
++	for (i = 0; i < nr; i++)
++		printk(KERN_INFO
++		       "    0x%p-0x%p (%u) %s\n",
++		       st[i].start, (int8_t *) st[i].start + st[i].size,
++		       st[i].size, st[i].owner != NULL ? st[i].owner : "");
++	printk(KERN_INFO "\n");
++}
++
++void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
++{
++	printk(KERN_INFO
++	       "blk @0x%p: 0x%p-0x%p (%u)\n",
++	       blk, blk->start, (int8_t *) blk->start + blk->size, blk->size);
++}
+diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/sstep.c
+@@ -0,0 +1,158 @@
++/*
++ * Single-step support.
++ *
++ * Copyright (C) 2004 Paul Mackerras <paulus at au.ibm.com>, 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/kernel.h>
++#include <linux/ptrace.h>
++#include <linux/config.h>
++#include <asm/sstep.h>
++#include <asm/processor.h>
++
++extern char system_call_common[];
++
++#ifdef CONFIG_PPC64
++/* Bits in SRR1 that are copied from MSR */
++#define MSR_MASK	0xffffffff87c0ffff
++#else
++#define MSR_MASK	0x87c0ffff
++#endif
++
++/*
++ * Determine whether a conditional branch instruction would branch.
++ */
++static int branch_taken(unsigned int instr, struct pt_regs *regs)
++{
++	unsigned int bo = (instr >> 21) & 0x1f;
++	unsigned int bi;
++
++	if ((bo & 4) == 0) {
++		/* decrement counter */
++		--regs->ctr;
++		if (((bo >> 1) & 1) ^ (regs->ctr == 0))
++			return 0;
++	}
++	if ((bo & 0x10) == 0) {
++		/* check bit from CR */
++		bi = (instr >> 16) & 0x1f;
++		if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1))
++			return 0;
++	}
++	return 1;
++}
++
++/*
++ * Emulate instructions that cause a transfer of control.
++ * Returns 1 if the step was emulated, 0 if not,
++ * or -1 if the instruction is one that should not be stepped,
++ * such as an rfid, or a mtmsrd that would clear MSR_RI.
++ */
++int emulate_step(struct pt_regs *regs, unsigned int instr)
++{
++	unsigned int opcode, rd;
++	unsigned long int imm;
++
++	opcode = instr >> 26;
++	switch (opcode) {
++	case 16:	/* bc */
++		imm = (signed short)(instr & 0xfffc);
++		if ((instr & 2) == 0)
++			imm += regs->nip;
++		regs->nip += 4;
++		if ((regs->msr & MSR_SF) == 0)
++			regs->nip &= 0xffffffffUL;
++		if (instr & 1)
++			regs->link = regs->nip;
++		if (branch_taken(instr, regs))
++			regs->nip = imm;
++		return 1;
++#ifdef CONFIG_PPC64
++	case 17:	/* sc */
++		/*
++		 * N.B. this uses knowledge about how the syscall
++		 * entry code works.  If that is changed, this will
++		 * need to be changed also.
++		 */
++		regs->gpr[9] = regs->gpr[13];
++		regs->gpr[11] = regs->nip + 4;
++		regs->gpr[12] = regs->msr & MSR_MASK;
++		regs->gpr[13] = (unsigned long) get_paca();
++		regs->nip = (unsigned long) &system_call_common;
++		regs->msr = MSR_KERNEL;
++		return 1;
++#endif
++	case 18:	/* b */
++		imm = instr & 0x03fffffc;
++		if (imm & 0x02000000)
++			imm -= 0x04000000;
++		if ((instr & 2) == 0)
++			imm += regs->nip;
++		if (instr & 1) {
++			regs->link = regs->nip + 4;
++			if ((regs->msr & MSR_SF) == 0)
++				regs->link &= 0xffffffffUL;
++		}
++		if ((regs->msr & MSR_SF) == 0)
++			imm &= 0xffffffffUL;
++		regs->nip = imm;
++		return 1;
++	case 19:
++		switch (instr & 0x7fe) {
++		case 0x20:	/* bclr */
++		case 0x420:	/* bcctr */
++			imm = (instr & 0x400)? regs->ctr: regs->link;
++			regs->nip += 4;
++			if ((regs->msr & MSR_SF) == 0) {
++				regs->nip &= 0xffffffffUL;
++				imm &= 0xffffffffUL;
++			}
++			if (instr & 1)
++				regs->link = regs->nip;
++			if (branch_taken(instr, regs))
++				regs->nip = imm;
++			return 1;
++		case 0x24:	/* rfid, scary */
++			return -1;
++		}
++	case 31:
++		rd = (instr >> 21) & 0x1f;
++		switch (instr & 0x7fe) {
++		case 0xa6:	/* mfmsr */
++			regs->gpr[rd] = regs->msr & MSR_MASK;
++			regs->nip += 4;
++			if ((regs->msr & MSR_SF) == 0)
++				regs->nip &= 0xffffffffUL;
++			return 1;
++		case 0x124:	/* mtmsr */
++			imm = regs->gpr[rd];
++			if ((imm & MSR_RI) == 0)
++				/* can't step mtmsr that would clear MSR_RI */
++				return -1;
++			regs->msr = imm;
++			regs->nip += 4;
++			return 1;
++#ifdef CONFIG_PPC64
++		case 0x164:	/* mtmsrd */
++			/* only MSR_EE and MSR_RI get changed if bit 15 set */
++			/* mtmsrd doesn't change MSR_HV and MSR_ME */
++			imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL;
++			imm = (regs->msr & MSR_MASK & ~imm)
++				| (regs->gpr[rd] & imm);
++			if ((imm & MSR_RI) == 0)
++				/* can't step mtmsrd that would clear MSR_RI */
++				return -1;
++			regs->msr = imm;
++			regs->nip += 4;
++			if ((imm & MSR_SF) == 0)
++				regs->nip &= 0xffffffffUL;
++			return 1;
++#endif
++		}
++	}
++	return 0;
++}
+diff --git a/arch/powerpc/lib/strcase.c b/arch/powerpc/lib/strcase.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/strcase.c
+@@ -0,0 +1,23 @@
++#include <linux/ctype.h>
++
++int strcasecmp(const char *s1, const char *s2)
++{
++	int c1, c2;
++
++	do {
++		c1 = tolower(*s1++);
++		c2 = tolower(*s2++);
++	} while (c1 == c2 && c1 != 0);
++	return c1 - c2;
++}
++
++int strncasecmp(const char *s1, const char *s2, int n)
++{
++	int c1, c2;
++
++	do {
++		c1 = tolower(*s1++);
++		c2 = tolower(*s2++);
++	} while ((--n > 0) && c1 == c2 && c1 != 0);
++	return c1 - c2;
++}
+diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/string.S
+@@ -0,0 +1,198 @@
++/*
++ * String handling functions for PowerPC.
++ *
++ * Copyright (C) 1996 Paul Mackerras.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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 <asm/processor.h>
++#include <asm/errno.h>
++#include <asm/ppc_asm.h>
++
++	.section __ex_table,"a"
++#ifdef CONFIG_PPC64
++	.align	3
++#define EXTBL	.llong
++#else
++	.align	2
++#define EXTBL	.long
++#endif
++	.text
++	
++_GLOBAL(strcpy)
++	addi	r5,r3,-1
++	addi	r4,r4,-1
++1:	lbzu	r0,1(r4)
++	cmpwi	0,r0,0
++	stbu	r0,1(r5)
++	bne	1b
++	blr
++
++/* This clears out any unused part of the destination buffer,
++   just as the libc version does.  -- paulus */
++_GLOBAL(strncpy)
++	cmpwi	0,r5,0
++	beqlr
++	mtctr	r5
++	addi	r6,r3,-1
++	addi	r4,r4,-1
++1:	lbzu	r0,1(r4)
++	cmpwi	0,r0,0
++	stbu	r0,1(r6)
++	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
++	bnelr			/* if we didn't hit a null char, we're done */
++	mfctr	r5
++	cmpwi	0,r5,0		/* any space left in destination buffer? */
++	beqlr			/* we know r0 == 0 here */
++2:	stbu	r0,1(r6)	/* clear it out if so */
++	bdnz	2b
++	blr
++
++_GLOBAL(strcat)
++	addi	r5,r3,-1
++	addi	r4,r4,-1
++1:	lbzu	r0,1(r5)
++	cmpwi	0,r0,0
++	bne	1b
++	addi	r5,r5,-1
++1:	lbzu	r0,1(r4)
++	cmpwi	0,r0,0
++	stbu	r0,1(r5)
++	bne	1b
++	blr
++
++_GLOBAL(strcmp)
++	addi	r5,r3,-1
++	addi	r4,r4,-1
++1:	lbzu	r3,1(r5)
++	cmpwi	1,r3,0
++	lbzu	r0,1(r4)
++	subf.	r3,r0,r3
++	beqlr	1
++	beq	1b
++	blr
++
++_GLOBAL(strlen)
++	addi	r4,r3,-1
++1:	lbzu	r0,1(r4)
++	cmpwi	0,r0,0
++	bne	1b
++	subf	r3,r3,r4
++	blr
++
++_GLOBAL(memcmp)
++	cmpwi	0,r5,0
++	ble-	2f
++	mtctr	r5
++	addi	r6,r3,-1
++	addi	r4,r4,-1
++1:	lbzu	r3,1(r6)
++	lbzu	r0,1(r4)
++	subf.	r3,r0,r3
++	bdnzt	2,1b
++	blr
++2:	li	r3,0
++	blr
++
++_GLOBAL(memchr)
++	cmpwi	0,r5,0
++	ble-	2f
++	mtctr	r5
++	addi	r3,r3,-1
++1:	lbzu	r0,1(r3)
++	cmpw	0,r0,r4
++	bdnzf	2,1b
++	beqlr
++2:	li	r3,0
++	blr
++
++_GLOBAL(__clear_user)
++	addi	r6,r3,-4
++	li	r3,0
++	li	r5,0
++	cmplwi	0,r4,4
++	blt	7f
++	/* clear a single word */
++11:	stwu	r5,4(r6)
++	beqlr
++	/* clear word sized chunks */
++	andi.	r0,r6,3
++	add	r4,r0,r4
++	subf	r6,r0,r6
++	srwi	r0,r4,2
++	andi.	r4,r4,3
++	mtctr	r0
++	bdz	7f
++1:	stwu	r5,4(r6)
++	bdnz	1b
++	/* clear byte sized chunks */
++7:	cmpwi	0,r4,0
++	beqlr
++	mtctr	r4
++	addi	r6,r6,3
++8:	stbu	r5,1(r6)
++	bdnz	8b
++	blr
++90:	mr	r3,r4
++	blr
++91:	mfctr	r3
++	slwi	r3,r3,2
++	add	r3,r3,r4
++	blr
++92:	mfctr	r3
++	blr
++
++	.section __ex_table,"a"
++	EXTBL	11b,90b
++	EXTBL	1b,91b
++	EXTBL	8b,92b
++	.text
++
++_GLOBAL(__strncpy_from_user)
++	addi	r6,r3,-1
++	addi	r4,r4,-1
++	cmpwi	0,r5,0
++	beq	2f
++	mtctr	r5
++1:	lbzu	r0,1(r4)
++	cmpwi	0,r0,0
++	stbu	r0,1(r6)
++	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
++	beq	3f
++2:	addi	r6,r6,1
++3:	subf	r3,r3,r6
++	blr
++99:	li	r3,-EFAULT
++	blr
++
++	.section __ex_table,"a"
++	EXTBL	1b,99b
++	.text
++
++/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
++_GLOBAL(__strnlen_user)
++	addi	r7,r3,-1
++	subf	r6,r7,r5	/* top+1 - str */
++	cmplw	0,r4,r6
++	bge	0f
++	mr	r6,r4
++0:	mtctr	r6		/* ctr = min(len, top - str) */
++1:	lbzu	r0,1(r7)	/* get next byte */
++	cmpwi	0,r0,0
++	bdnzf	2,1b		/* loop if --ctr != 0 && byte != 0 */
++	addi	r7,r7,1
++	subf	r3,r3,r7	/* number of bytes we have looked at */
++	beqlr			/* return if we found a 0 byte */
++	cmpw	0,r3,r4		/* did we look at all len bytes? */
++	blt	99f		/* if not, must have hit top */
++	addi	r3,r4,1		/* return len + 1 to indicate no null found */
++	blr
++99:	li	r3,0		/* bad address, return 0 */
++	blr
++
++	.section __ex_table,"a"
++	EXTBL	1b,99b
+diff --git a/arch/powerpc/lib/usercopy_64.c b/arch/powerpc/lib/usercopy_64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/lib/usercopy_64.c
+@@ -0,0 +1,41 @@
++/*
++ * Functions which are too large to be inlined.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/uaccess.h>
++
++unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
++{
++	if (likely(access_ok(VERIFY_READ, from, n)))
++		n = __copy_from_user(to, from, n);
++	else
++		memset(to, 0, n);
++	return n;
++}
++
++unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
++{
++	if (likely(access_ok(VERIFY_WRITE, to, n)))
++		n = __copy_to_user(to, from, n);
++	return n;
++}
++
++unsigned long copy_in_user(void __user *to, const void __user *from,
++			   unsigned long n)
++{
++	might_sleep();
++	if (likely(access_ok(VERIFY_READ, from, n) &&
++	    access_ok(VERIFY_WRITE, to, n)))
++		n =__copy_tofrom_user(to, from, n);
++	return n;
++}
++
++EXPORT_SYMBOL(copy_from_user);
++EXPORT_SYMBOL(copy_to_user);
++EXPORT_SYMBOL(copy_in_user);
++
+diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/44x_mmu.c
+@@ -0,0 +1,120 @@
++/*
++ * Modifications by Matt Porter (mporter at mvista.com) to support
++ * PPC44x Book E processors.
++ *
++ * This file contains the routines for initializing the MMU
++ * on the 4xx series of chips.
++ *  -- paulus
++ *
++ *  Derived from arch/ppc/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/signal.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/ptrace.h>
++#include <linux/mman.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/stddef.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/highmem.h>
++
++#include <asm/pgalloc.h>
++#include <asm/prom.h>
++#include <asm/io.h>
++#include <asm/mmu_context.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/uaccess.h>
++#include <asm/smp.h>
++#include <asm/bootx.h>
++#include <asm/machdep.h>
++#include <asm/setup.h>
++
++#include "mmu_decl.h"
++
++extern char etext[], _stext[];
++
++/* Used by the 44x TLB replacement exception handler.
++ * Just needed it declared someplace.
++ */
++unsigned int tlb_44x_index = 0;
++unsigned int tlb_44x_hwater = 62;
++
++/*
++ * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
++ */
++static void __init
++ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys)
++{
++	unsigned long attrib = 0;
++
++	__asm__ __volatile__("\
++	clrrwi	%2,%2,10\n\
++	ori	%2,%2,%4\n\
++	clrrwi	%1,%1,10\n\
++	li	%0,0\n\
++	ori	%0,%0,%5\n\
++	tlbwe	%2,%3,%6\n\
++	tlbwe	%1,%3,%7\n\
++	tlbwe	%0,%3,%8"
++	:
++	: "r" (attrib), "r" (phys), "r" (virt), "r" (slot),
++	  "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M),
++	  "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
++	  "i" (PPC44x_TLB_PAGEID),
++	  "i" (PPC44x_TLB_XLAT),
++	  "i" (PPC44x_TLB_ATTRIB));
++}
++
++/*
++ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
++ */
++void __init MMU_init_hw(void)
++{
++	flush_instruction_cache();
++}
++
++unsigned long __init mmu_mapin_ram(void)
++{
++	unsigned int pinned_tlbs = 1;
++	int i;
++
++	/* Determine number of entries necessary to cover lowmem */
++	pinned_tlbs = (unsigned int)
++		(_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT);
++
++	/* Write upper watermark to save location */
++	tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
++
++	/* If necessary, set additional pinned TLBs */
++	if (pinned_tlbs > 1)
++		for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) {
++			unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE;
++			ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr);
++		}
++
++	return total_lowmem;
++}
+diff --git a/arch/powerpc/mm/4xx_mmu.c b/arch/powerpc/mm/4xx_mmu.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/4xx_mmu.c
+@@ -0,0 +1,141 @@
++/*
++ * This file contains the routines for initializing the MMU
++ * on the 4xx series of chips.
++ *  -- paulus
++ *
++ *  Derived from arch/ppc/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/signal.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/ptrace.h>
++#include <linux/mman.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/stddef.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/highmem.h>
++
++#include <asm/pgalloc.h>
++#include <asm/prom.h>
++#include <asm/io.h>
++#include <asm/mmu_context.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/uaccess.h>
++#include <asm/smp.h>
++#include <asm/bootx.h>
++#include <asm/machdep.h>
++#include <asm/setup.h>
++#include "mmu_decl.h"
++
++extern int __map_without_ltlbs;
++/*
++ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
++ */
++void __init MMU_init_hw(void)
++{
++	/*
++	 * The Zone Protection Register (ZPR) defines how protection will
++	 * be applied to every page which is a member of a given zone. At
++	 * present, we utilize only two of the 4xx's zones.
++	 * The zone index bits (of ZSEL) in the PTE are used for software
++	 * indicators, except the LSB.  For user access, zone 1 is used,
++	 * for kernel access, zone 0 is used.  We set all but zone 1
++	 * to zero, allowing only kernel access as indicated in the PTE.
++	 * For zone 1, we set a 01 binary (a value of 10 will not work)
++	 * to allow user access as indicated in the PTE.  This also allows
++	 * kernel access as indicated in the PTE.
++	 */
++
++        mtspr(SPRN_ZPR, 0x10000000);
++
++	flush_instruction_cache();
++
++	/*
++	 * Set up the real-mode cache parameters for the exception vector
++	 * handlers (which are run in real-mode).
++	 */
++
++        mtspr(SPRN_DCWR, 0x00000000);	/* All caching is write-back */
++
++        /*
++	 * Cache instruction and data space where the exception
++	 * vectors and the kernel live in real-mode.
++	 */
++
++        mtspr(SPRN_DCCR, 0xF0000000);	/* 512 MB of data space at 0x0. */
++        mtspr(SPRN_ICCR, 0xF0000000);	/* 512 MB of instr. space at 0x0. */
++}
++
++#define LARGE_PAGE_SIZE_16M	(1<<24)
++#define LARGE_PAGE_SIZE_4M	(1<<22)
++
++unsigned long __init mmu_mapin_ram(void)
++{
++	unsigned long v, s;
++	phys_addr_t p;
++
++	v = KERNELBASE;
++	p = PPC_MEMSTART;
++	s = 0;
++
++	if (__map_without_ltlbs) {
++		return s;
++	}
++
++	while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) {
++		pmd_t *pmdp;
++		unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
++
++		spin_lock(&init_mm.page_table_lock);
++		pmdp = pmd_offset(pgd_offset_k(v), v);
++		pmd_val(*pmdp++) = val;
++		pmd_val(*pmdp++) = val;
++		pmd_val(*pmdp++) = val;
++		pmd_val(*pmdp++) = val;
++		spin_unlock(&init_mm.page_table_lock);
++
++		v += LARGE_PAGE_SIZE_16M;
++		p += LARGE_PAGE_SIZE_16M;
++		s += LARGE_PAGE_SIZE_16M;
++	}
++
++	while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) {
++		pmd_t *pmdp;
++		unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
++
++		spin_lock(&init_mm.page_table_lock);
++		pmdp = pmd_offset(pgd_offset_k(v), v);
++		pmd_val(*pmdp) = val;
++		spin_unlock(&init_mm.page_table_lock);
++
++		v += LARGE_PAGE_SIZE_4M;
++		p += LARGE_PAGE_SIZE_4M;
++		s += LARGE_PAGE_SIZE_4M;
++	}
++
++	return s;
++}
+diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/Makefile
+@@ -0,0 +1,21 @@
++#
++# Makefile for the linux ppc-specific parts of the memory manager.
++#
++
++ifeq ($(CONFIG_PPC64),y)
++EXTRA_CFLAGS	+= -mno-minimal-toc
++endif
++
++obj-y				:= fault.o mem.o lmb.o
++obj-$(CONFIG_PPC32)		+= init_32.o pgtable_32.o mmu_context_32.o
++hash-$(CONFIG_PPC_MULTIPLATFORM) := hash_native_64.o
++obj-$(CONFIG_PPC64)		+= init_64.o pgtable_64.o mmu_context_64.o \
++				   hash_utils_64.o hash_low_64.o tlb_64.o \
++				   slb_low.o slb.o stab.o mmap.o imalloc.o \
++				   $(hash-y)
++obj-$(CONFIG_PPC_STD_MMU_32)	+= ppc_mmu_32.o hash_low_32.o tlb_32.o
++obj-$(CONFIG_40x)		+= 4xx_mmu.o
++obj-$(CONFIG_44x)		+= 44x_mmu.o
++obj-$(CONFIG_FSL_BOOKE)		+= fsl_booke_mmu.o
++obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
++obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
+diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/fault.c
+@@ -0,0 +1,393 @@
++/*
++ *  arch/ppc/mm/fault.c
++ *
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Derived from "arch/i386/mm/fault.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  Modified by Cort Dougan and Paul Mackerras.
++ *
++ *  Modified for PPC64 by Dave Engebretsen (engebret at 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 <linux/config.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/ptrace.h>
++#include <linux/mman.h>
++#include <linux/mm.h>
++#include <linux/interrupt.h>
++#include <linux/highmem.h>
++#include <linux/module.h>
++#include <linux/kprobes.h>
++
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/mmu_context.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++#include <asm/tlbflush.h>
++#include <asm/kdebug.h>
++#include <asm/siginfo.h>
++
++/*
++ * Check whether the instruction at regs->nip is a store using
++ * an update addressing form which will update r1.
++ */
++static int store_updates_sp(struct pt_regs *regs)
++{
++	unsigned int inst;
++
++	if (get_user(inst, (unsigned int __user *)regs->nip))
++		return 0;
++	/* check for 1 in the rA field */
++	if (((inst >> 16) & 0x1f) != 1)
++		return 0;
++	/* check major opcode */
++	switch (inst >> 26) {
++	case 37:	/* stwu */
++	case 39:	/* stbu */
++	case 45:	/* sthu */
++	case 53:	/* stfsu */
++	case 55:	/* stfdu */
++		return 1;
++	case 62:	/* std or stdu */
++		return (inst & 3) == 1;
++	case 31:
++		/* check minor opcode */
++		switch ((inst >> 1) & 0x3ff) {
++		case 181:	/* stdux */
++		case 183:	/* stwux */
++		case 247:	/* stbux */
++		case 439:	/* sthux */
++		case 695:	/* stfsux */
++		case 759:	/* stfdux */
++			return 1;
++		}
++	}
++	return 0;
++}
++
++#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
++static void do_dabr(struct pt_regs *regs, unsigned long error_code)
++{
++	siginfo_t info;
++
++	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
++			11, SIGSEGV) == NOTIFY_STOP)
++		return;
++
++	if (debugger_dabr_match(regs))
++		return;
++
++	/* Clear the DABR */
++	set_dabr(0);
++
++	/* Deliver the signal to userspace */
++	info.si_signo = SIGTRAP;
++	info.si_errno = 0;
++	info.si_code = TRAP_HWBKPT;
++	info.si_addr = (void __user *)regs->nip;
++	force_sig_info(SIGTRAP, &info, current);
++}
++#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
++
++/*
++ * For 600- and 800-family processors, the error_code parameter is DSISR
++ * for a data fault, SRR1 for an instruction fault. For 400-family processors
++ * the error_code parameter is ESR for a data fault, 0 for an instruction
++ * fault.
++ * For 64-bit processors, the error_code parameter is
++ *  - DSISR for a non-SLB data access fault,
++ *  - SRR1 & 0x08000000 for a non-SLB instruction access fault
++ *  - 0 any SLB fault.
++ *
++ * The return value is 0 if the fault was handled, or the signal
++ * number if this is a kernel fault that can't be handled here.
++ */
++int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
++			    unsigned long error_code)
++{
++	struct vm_area_struct * vma;
++	struct mm_struct *mm = current->mm;
++	siginfo_t info;
++	int code = SEGV_MAPERR;
++	int is_write = 0;
++	int trap = TRAP(regs);
++ 	int is_exec = trap == 0x400;
++
++#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
++	/*
++	 * Fortunately the bit assignments in SRR1 for an instruction
++	 * fault and DSISR for a data fault are mostly the same for the
++	 * bits we are interested in.  But there are some bits which
++	 * indicate errors in DSISR but can validly be set in SRR1.
++	 */
++	if (trap == 0x400)
++		error_code &= 0x48200000;
++	else
++		is_write = error_code & DSISR_ISSTORE;
++#else
++	is_write = error_code & ESR_DST;
++#endif /* CONFIG_4xx || CONFIG_BOOKE */
++
++	if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code,
++				11, SIGSEGV) == NOTIFY_STOP)
++		return 0;
++
++	if (trap == 0x300) {
++		if (debugger_fault_handler(regs))
++			return 0;
++	}
++
++	/* On a kernel SLB miss we can only check for a valid exception entry */
++	if (!user_mode(regs) && (address >= TASK_SIZE))
++		return SIGSEGV;
++
++#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
++  	if (error_code & DSISR_DABRMATCH) {
++		/* DABR match */
++		do_dabr(regs, error_code);
++		return 0;
++	}
++#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
++
++	if (in_atomic() || mm == NULL) {
++		if (!user_mode(regs))
++			return SIGSEGV;
++		/* in_atomic() in user mode is really bad,
++		   as is current->mm == NULL. */
++		printk(KERN_EMERG "Page fault in user mode with"
++		       "in_atomic() = %d mm = %p\n", in_atomic(), mm);
++		printk(KERN_EMERG "NIP = %lx  MSR = %lx\n",
++		       regs->nip, regs->msr);
++		die("Weird page fault", regs, SIGSEGV);
++	}
++
++	/* When running in the kernel we expect faults to occur only to
++	 * addresses in user space.  All other faults represent errors in the
++	 * kernel and should generate an OOPS.  Unfortunatly, in the case of an
++	 * erroneous fault occuring in a code path which already holds mmap_sem
++	 * we will deadlock attempting to validate the fault against the
++	 * address space.  Luckily the kernel only validly references user
++	 * space from well defined areas of code, which are listed in the
++	 * exceptions table.
++	 *
++	 * As the vast majority of faults will be valid we will only perform
++	 * the source reference check when there is a possibilty of a deadlock.
++	 * Attempt to lock the address space, if we cannot we then validate the
++	 * source.  If this is invalid we can skip the address space check,
++	 * thus avoiding the deadlock.
++	 */
++	if (!down_read_trylock(&mm->mmap_sem)) {
++		if (!user_mode(regs) && !search_exception_tables(regs->nip))
++			goto bad_area_nosemaphore;
++
++		down_read(&mm->mmap_sem);
++	}
++
++	vma = find_vma(mm, address);
++	if (!vma)
++		goto bad_area;
++	if (vma->vm_start <= address)
++		goto good_area;
++	if (!(vma->vm_flags & VM_GROWSDOWN))
++		goto bad_area;
++
++	/*
++	 * N.B. The POWER/Open ABI allows programs to access up to
++	 * 288 bytes below the stack pointer.
++	 * The kernel signal delivery code writes up to about 1.5kB
++	 * below the stack pointer (r1) before decrementing it.
++	 * The exec code can write slightly over 640kB to the stack
++	 * before setting the user r1.  Thus we allow the stack to
++	 * expand to 1MB without further checks.
++	 */
++	if (address + 0x100000 < vma->vm_end) {
++		/* get user regs even if this fault is in kernel mode */
++		struct pt_regs *uregs = current->thread.regs;
++		if (uregs == NULL)
++			goto bad_area;
++
++		/*
++		 * A user-mode access to an address a long way below
++		 * the stack pointer is only valid if the instruction
++		 * is one which would update the stack pointer to the
++		 * address accessed if the instruction completed,
++		 * i.e. either stwu rs,n(r1) or stwux rs,r1,rb
++		 * (or the byte, halfword, float or double forms).
++		 *
++		 * If we don't check this then any write to the area
++		 * between the last mapped region and the stack will
++		 * expand the stack rather than segfaulting.
++		 */
++		if (address + 2048 < uregs->gpr[1]
++		    && (!user_mode(regs) || !store_updates_sp(regs)))
++			goto bad_area;
++	}
++	if (expand_stack(vma, address))
++		goto bad_area;
++
++good_area:
++	code = SEGV_ACCERR;
++#if defined(CONFIG_6xx)
++	if (error_code & 0x95700000)
++		/* an error such as lwarx to I/O controller space,
++		   address matching DABR, eciwx, etc. */
++		goto bad_area;
++#endif /* CONFIG_6xx */
++#if defined(CONFIG_8xx)
++        /* The MPC8xx seems to always set 0x80000000, which is
++         * "undefined".  Of those that can be set, this is the only
++         * one which seems bad.
++         */
++	if (error_code & 0x10000000)
++                /* Guarded storage error. */
++		goto bad_area;
++#endif /* CONFIG_8xx */
++
++	if (is_exec) {
++#ifdef CONFIG_PPC64
++		/* protection fault */
++		if (error_code & DSISR_PROTFAULT)
++			goto bad_area;
++		if (!(vma->vm_flags & VM_EXEC))
++			goto bad_area;
++#endif
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++		pte_t *ptep;
++
++		/* Since 4xx/Book-E supports per-page execute permission,
++		 * we lazily flush dcache to icache. */
++		ptep = NULL;
++		if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) {
++			struct page *page = pte_page(*ptep);
++
++			if (! test_bit(PG_arch_1, &page->flags)) {
++				flush_dcache_icache_page(page);
++				set_bit(PG_arch_1, &page->flags);
++			}
++			pte_update(ptep, 0, _PAGE_HWEXEC);
++			_tlbie(address);
++			pte_unmap(ptep);
++			up_read(&mm->mmap_sem);
++			return 0;
++		}
++		if (ptep != NULL)
++			pte_unmap(ptep);
++#endif
++	/* a write */
++	} else if (is_write) {
++		if (!(vma->vm_flags & VM_WRITE))
++			goto bad_area;
++	/* a read */
++	} else {
++		/* protection fault */
++		if (error_code & 0x08000000)
++			goto bad_area;
++		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
++			goto bad_area;
++	}
++
++	/*
++	 * If for any reason at all we couldn't handle the fault,
++	 * make sure we exit gracefully rather than endlessly redo
++	 * the fault.
++	 */
++ 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:
++		goto do_sigbus;
++	case VM_FAULT_OOM:
++		goto out_of_memory;
++	default:
++		BUG();
++	}
++
++	up_read(&mm->mmap_sem);
++	return 0;
++
++bad_area:
++	up_read(&mm->mmap_sem);
++
++bad_area_nosemaphore:
++	/* User mode accesses cause a SIGSEGV */
++	if (user_mode(regs)) {
++		_exception(SIGSEGV, regs, code, address);
++		return 0;
++	}
++
++	if (is_exec && (error_code & DSISR_PROTFAULT)
++	    && printk_ratelimit())
++		printk(KERN_CRIT "kernel tried to execute NX-protected"
++		       " page (%lx) - exploit attempt? (uid: %d)\n",
++		       address, current->uid);
++
++	return SIGSEGV;
++
++/*
++ * 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:
++	up_read(&mm->mmap_sem);
++	if (current->pid == 1) {
++		yield();
++		down_read(&mm->mmap_sem);
++		goto survive;
++	}
++	printk("VM: killing process %s\n", current->comm);
++	if (user_mode(regs))
++		do_exit(SIGKILL);
++	return SIGKILL;
++
++do_sigbus:
++	up_read(&mm->mmap_sem);
++	if (user_mode(regs)) {
++		info.si_signo = SIGBUS;
++		info.si_errno = 0;
++		info.si_code = BUS_ADRERR;
++		info.si_addr = (void __user *)address;
++		force_sig_info(SIGBUS, &info, current);
++		return 0;
++	}
++	return SIGBUS;
++}
++
++/*
++ * bad_page_fault is called when we have a bad access from the kernel.
++ * It is called from the DSI and ISI handlers in head.S and from some
++ * of the procedures in traps.c.
++ */
++void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
++{
++	const struct exception_table_entry *entry;
++
++	/* Are we prepared to handle this fault?  */
++	if ((entry = search_exception_tables(regs->nip)) != NULL) {
++		regs->nip = entry->fixup;
++		return;
++	}
++
++	/* kernel has accessed a bad area */
++	die("Kernel access of bad area", regs, sig);
++}
+diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/fsl_booke_mmu.c
+@@ -0,0 +1,237 @@
++/*
++ * Modifications by Kumar Gala (kumar.gala at freescale.com) to support
++ * E500 Book E processors.
++ *
++ * Copyright 2004 Freescale Semiconductor, Inc
++ *
++ * This file contains the routines for initializing the MMU
++ * on the 4xx series of chips.
++ *  -- paulus
++ *
++ *  Derived from arch/ppc/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/signal.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/ptrace.h>
++#include <linux/mman.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/stddef.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/highmem.h>
++
++#include <asm/pgalloc.h>
++#include <asm/prom.h>
++#include <asm/io.h>
++#include <asm/mmu_context.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/uaccess.h>
++#include <asm/smp.h>
++#include <asm/bootx.h>
++#include <asm/machdep.h>
++#include <asm/setup.h>
++
++extern void loadcam_entry(unsigned int index);
++unsigned int tlbcam_index;
++unsigned int num_tlbcam_entries;
++static unsigned long __cam0, __cam1, __cam2;
++extern unsigned long total_lowmem;
++extern unsigned long __max_low_memory;
++#define MAX_LOW_MEM	CONFIG_LOWMEM_SIZE
++
++#define NUM_TLBCAMS	(16)
++
++struct tlbcam {
++   	u32	MAS0;
++	u32	MAS1;
++	u32	MAS2;
++	u32	MAS3;
++	u32	MAS7;
++} TLBCAM[NUM_TLBCAMS];
++
++struct tlbcamrange {
++   	unsigned long start;
++	unsigned long limit;
++	phys_addr_t phys;
++} tlbcam_addrs[NUM_TLBCAMS];
++
++extern unsigned int tlbcam_index;
++
++/*
++ * Return PA for this VA if it is mapped by a CAM, or 0
++ */
++unsigned long v_mapped_by_tlbcam(unsigned long va)
++{
++	int b;
++	for (b = 0; b < tlbcam_index; ++b)
++		if (va >= tlbcam_addrs[b].start && va < tlbcam_addrs[b].limit)
++			return tlbcam_addrs[b].phys + (va - tlbcam_addrs[b].start);
++	return 0;
++}
++
++/*
++ * Return VA for a given PA or 0 if not mapped
++ */
++unsigned long p_mapped_by_tlbcam(unsigned long pa)
++{
++	int b;
++	for (b = 0; b < tlbcam_index; ++b)
++		if (pa >= tlbcam_addrs[b].phys
++	    	    && pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start)
++		              +tlbcam_addrs[b].phys)
++			return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys);
++	return 0;
++}
++
++/*
++ * Set up one of the I/D BAT (block address translation) register pairs.
++ * The parameters are not checked; in particular size must be a power
++ * of 4 between 4k and 256M.
++ */
++void settlbcam(int index, unsigned long virt, phys_addr_t phys,
++		unsigned int size, int flags, unsigned int pid)
++{
++	unsigned int tsize, lz;
++
++	asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
++	tsize = (21 - lz) / 2;
++
++#ifdef CONFIG_SMP
++	if ((flags & _PAGE_NO_CACHE) == 0)
++		flags |= _PAGE_COHERENT;
++#endif
++
++	TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1);
++	TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
++	TLBCAM[index].MAS2 = virt & PAGE_MASK;
++
++	TLBCAM[index].MAS2 |= (flags & _PAGE_WRITETHRU) ? MAS2_W : 0;
++	TLBCAM[index].MAS2 |= (flags & _PAGE_NO_CACHE) ? MAS2_I : 0;
++	TLBCAM[index].MAS2 |= (flags & _PAGE_COHERENT) ? MAS2_M : 0;
++	TLBCAM[index].MAS2 |= (flags & _PAGE_GUARDED) ? MAS2_G : 0;
++	TLBCAM[index].MAS2 |= (flags & _PAGE_ENDIAN) ? MAS2_E : 0;
++
++	TLBCAM[index].MAS3 = (phys & PAGE_MASK) | MAS3_SX | MAS3_SR;
++	TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
++
++#ifndef CONFIG_KGDB /* want user access for breakpoints */
++	if (flags & _PAGE_USER) {
++	   TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
++	   TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
++	}
++#else
++	TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
++	TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
++#endif
++
++	tlbcam_addrs[index].start = virt;
++	tlbcam_addrs[index].limit = virt + size - 1;
++	tlbcam_addrs[index].phys = phys;
++
++	loadcam_entry(index);
++}
++
++void invalidate_tlbcam_entry(int index)
++{
++	TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index);
++	TLBCAM[index].MAS1 = ~MAS1_VALID;
++
++	loadcam_entry(index);
++}
++
++void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1,
++		unsigned long cam2)
++{
++	settlbcam(0, KERNELBASE, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0);
++	tlbcam_index++;
++	if (cam1) {
++		tlbcam_index++;
++		settlbcam(1, KERNELBASE+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0);
++	}
++	if (cam2) {
++		tlbcam_index++;
++		settlbcam(2, KERNELBASE+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0);
++	}
++}
++
++/*
++ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
++ */
++void __init MMU_init_hw(void)
++{
++	flush_instruction_cache();
++}
++
++unsigned long __init mmu_mapin_ram(void)
++{
++	cam_mapin_ram(__cam0, __cam1, __cam2);
++
++	return __cam0 + __cam1 + __cam2;
++}
++
++
++void __init
++adjust_total_lowmem(void)
++{
++	unsigned long max_low_mem = MAX_LOW_MEM;
++	unsigned long cam_max = 0x10000000;
++	unsigned long ram;
++
++	/* adjust CAM size to max_low_mem */
++	if (max_low_mem < cam_max)
++		cam_max = max_low_mem;
++
++	/* adjust lowmem size to max_low_mem */
++	if (max_low_mem < total_lowmem)
++		ram = max_low_mem;
++	else
++		ram = total_lowmem;
++
++	/* Calculate CAM values */
++	__cam0 = 1UL << 2 * (__ilog2(ram) / 2);
++	if (__cam0 > cam_max)
++		__cam0 = cam_max;
++	ram -= __cam0;
++	if (ram) {
++		__cam1 = 1UL << 2 * (__ilog2(ram) / 2);
++		if (__cam1 > cam_max)
++			__cam1 = cam_max;
++		ram -= __cam1;
++	}
++	if (ram) {
++		__cam2 = 1UL << 2 * (__ilog2(ram) / 2);
++		if (__cam2 > cam_max)
++			__cam2 = cam_max;
++		ram -= __cam2;
++	}
++
++	printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb,"
++			" CAM2=%ldMb residual: %ldMb\n",
++			__cam0 >> 20, __cam1 >> 20, __cam2 >> 20,
++			(total_lowmem - __cam0 - __cam1 - __cam2) >> 20);
++	__max_low_memory = max_low_mem = __cam0 + __cam1 + __cam2;
++}
+diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/hash_low_32.S
+@@ -0,0 +1,618 @@
++/*
++ *  arch/ppc/kernel/hashtable.S
++ *
++ *  $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
++ *
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *  Rewritten by Cort Dougan (cort at cs.nmt.edu) for PReP
++ *    Copyright (C) 1996 Cort Dougan <cort at cs.nmt.edu>
++ *  Adapted for Power Macintosh by Paul Mackerras.
++ *  Low-level exception handlers and MMU support
++ *  rewritten by Paul Mackerras.
++ *    Copyright (C) 1996 Paul Mackerras.
++ *
++ *  This file contains low-level assembler routines for managing
++ *  the PowerPC MMU hash table.  (PPC 8xx processors don't use a
++ *  hash table, so this file is not used on them.)
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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 <asm/reg.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/cputable.h>
++#include <asm/ppc_asm.h>
++#include <asm/thread_info.h>
++#include <asm/asm-offsets.h>
++
++#ifdef CONFIG_SMP
++	.comm	mmu_hash_lock,4
++#endif /* CONFIG_SMP */
++
++/*
++ * Sync CPUs with hash_page taking & releasing the hash
++ * table lock
++ */
++#ifdef CONFIG_SMP
++	.text
++_GLOBAL(hash_page_sync)
++	lis	r8,mmu_hash_lock at h
++	ori	r8,r8,mmu_hash_lock at l
++	lis	r0,0x0fff
++	b	10f
++11:	lwz	r6,0(r8)
++	cmpwi	0,r6,0
++	bne	11b
++10:	lwarx	r6,0,r8
++	cmpwi	0,r6,0
++	bne-	11b
++	stwcx.	r0,0,r8
++	bne-	10b
++	isync
++	eieio
++	li	r0,0
++	stw	r0,0(r8)
++	blr	
++#endif
++
++/*
++ * Load a PTE into the hash table, if possible.
++ * The address is in r4, and r3 contains an access flag:
++ * _PAGE_RW (0x400) if a write.
++ * r9 contains the SRR1 value, from which we use the MSR_PR bit.
++ * SPRG3 contains the physical address of the current task's thread.
++ *
++ * Returns to the caller if the access is illegal or there is no
++ * mapping for the address.  Otherwise it places an appropriate PTE
++ * in the hash table and returns from the exception.
++ * Uses r0, r3 - r8, ctr, lr.
++ */
++	.text
++_GLOBAL(hash_page)
++#ifdef CONFIG_PPC64BRIDGE
++	mfmsr	r0
++	clrldi	r0,r0,1		/* make sure it's in 32-bit mode */
++	MTMSRD(r0)
++	isync
++#endif
++	tophys(r7,0)			/* gets -KERNELBASE into r7 */
++#ifdef CONFIG_SMP
++	addis	r8,r7,mmu_hash_lock at h
++	ori	r8,r8,mmu_hash_lock at l
++	lis	r0,0x0fff
++	b	10f
++11:	lwz	r6,0(r8)
++	cmpwi	0,r6,0
++	bne	11b
++10:	lwarx	r6,0,r8
++	cmpwi	0,r6,0
++	bne-	11b
++	stwcx.	r0,0,r8
++	bne-	10b
++	isync
++#endif
++	/* Get PTE (linux-style) and check access */
++	lis	r0,KERNELBASE at h		/* check if kernel address */
++	cmplw	0,r4,r0
++	mfspr	r8,SPRN_SPRG3		/* current task's THREAD (phys) */
++	ori	r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */
++	lwz	r5,PGDIR(r8)		/* virt page-table root */
++	blt+	112f			/* assume user more likely */
++	lis	r5,swapper_pg_dir at ha	/* if kernel address, use */
++	addi	r5,r5,swapper_pg_dir at l	/* kernel page table */
++	rlwimi	r3,r9,32-12,29,29	/* MSR_PR -> _PAGE_USER */
++112:	add	r5,r5,r7		/* convert to phys addr */
++	rlwimi	r5,r4,12,20,29		/* insert top 10 bits of address */
++	lwz	r8,0(r5)		/* get pmd entry */
++	rlwinm.	r8,r8,0,0,19		/* extract address of pte page */
++#ifdef CONFIG_SMP
++	beq-	hash_page_out		/* return if no mapping */
++#else
++	/* XXX it seems like the 601 will give a machine fault on the
++	   rfi if its alignment is wrong (bottom 4 bits of address are
++	   8 or 0xc) and we have had a not-taken conditional branch
++	   to the address following the rfi. */
++	beqlr-
++#endif
++	rlwimi	r8,r4,22,20,29		/* insert next 10 bits of address */
++	rlwinm	r0,r3,32-3,24,24	/* _PAGE_RW access -> _PAGE_DIRTY */
++	ori	r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE
++
++	/*
++	 * Update the linux PTE atomically.  We do the lwarx up-front
++	 * because almost always, there won't be a permission violation
++	 * and there won't already be an HPTE, and thus we will have
++	 * to update the PTE to set _PAGE_HASHPTE.  -- paulus.
++	 */
++retry:
++	lwarx	r6,0,r8			/* get linux-style pte */
++	andc.	r5,r3,r6		/* check access & ~permission */
++#ifdef CONFIG_SMP
++	bne-	hash_page_out		/* return if access not permitted */
++#else
++	bnelr-
++#endif
++	or	r5,r0,r6		/* set accessed/dirty bits */
++	stwcx.	r5,0,r8			/* attempt to update PTE */
++	bne-	retry			/* retry if someone got there first */
++
++	mfsrin	r3,r4			/* get segment reg for segment */
++	mfctr	r0
++	stw	r0,_CTR(r11)
++	bl	create_hpte		/* add the hash table entry */
++
++#ifdef CONFIG_SMP
++	eieio
++	addis	r8,r7,mmu_hash_lock at ha
++	li	r0,0
++	stw	r0,mmu_hash_lock at l(r8)
++#endif
++
++	/* Return from the exception */
++	lwz	r5,_CTR(r11)
++	mtctr	r5
++	lwz	r0,GPR0(r11)
++	lwz	r7,GPR7(r11)
++	lwz	r8,GPR8(r11)
++	b	fast_exception_return
++
++#ifdef CONFIG_SMP
++hash_page_out:
++	eieio
++	addis	r8,r7,mmu_hash_lock at ha
++	li	r0,0
++	stw	r0,mmu_hash_lock at l(r8)
++	blr
++#endif /* CONFIG_SMP */
++
++/*
++ * Add an entry for a particular page to the hash table.
++ *
++ * add_hash_page(unsigned context, unsigned long va, unsigned long pmdval)
++ *
++ * We assume any necessary modifications to the pte (e.g. setting
++ * the accessed bit) have already been done and that there is actually
++ * a hash table in use (i.e. we're not on a 603).
++ */
++_GLOBAL(add_hash_page)
++	mflr	r0
++	stw	r0,4(r1)
++
++	/* Convert context and va to VSID */
++	mulli	r3,r3,897*16		/* multiply context by context skew */
++	rlwinm	r0,r4,4,28,31		/* get ESID (top 4 bits of va) */
++	mulli	r0,r0,0x111		/* multiply by ESID skew */
++	add	r3,r3,r0		/* note create_hpte trims to 24 bits */
++
++#ifdef CONFIG_SMP
++	rlwinm	r8,r1,0,0,18		/* use cpu number to make tag */
++	lwz	r8,TI_CPU(r8)		/* to go in mmu_hash_lock */
++	oris	r8,r8,12
++#endif /* CONFIG_SMP */
++
++	/*
++	 * We disable interrupts here, even on UP, because we don't
++	 * want to race with hash_page, and because we want the
++	 * _PAGE_HASHPTE bit to be a reliable indication of whether
++	 * the HPTE exists (or at least whether one did once).
++	 * We also turn off the MMU for data accesses so that we
++	 * we can't take a hash table miss (assuming the code is
++	 * covered by a BAT).  -- paulus
++	 */
++	mfmsr	r10
++	SYNC
++	rlwinm	r0,r10,0,17,15		/* clear bit 16 (MSR_EE) */
++	rlwinm	r0,r0,0,28,26		/* clear MSR_DR */
++	mtmsr	r0
++	SYNC_601
++	isync
++
++	tophys(r7,0)
++
++#ifdef CONFIG_SMP
++	addis	r9,r7,mmu_hash_lock at ha
++	addi	r9,r9,mmu_hash_lock at l
++10:	lwarx	r0,0,r9			/* take the mmu_hash_lock */
++	cmpi	0,r0,0
++	bne-	11f
++	stwcx.	r8,0,r9
++	beq+	12f
++11:	lwz	r0,0(r9)
++	cmpi	0,r0,0
++	beq	10b
++	b	11b
++12:	isync
++#endif
++
++	/*
++	 * Fetch the linux pte and test and set _PAGE_HASHPTE atomically.
++	 * If _PAGE_HASHPTE was already set, we don't replace the existing
++	 * HPTE, so we just unlock and return.
++	 */
++	mr	r8,r5
++	rlwimi	r8,r4,22,20,29
++1:	lwarx	r6,0,r8
++	andi.	r0,r6,_PAGE_HASHPTE
++	bne	9f			/* if HASHPTE already set, done */
++	ori	r5,r6,_PAGE_HASHPTE
++	stwcx.	r5,0,r8
++	bne-	1b
++
++	bl	create_hpte
++
++9:
++#ifdef CONFIG_SMP
++	eieio
++	li	r0,0
++	stw	r0,0(r9)		/* clear mmu_hash_lock */
++#endif
++
++	/* reenable interrupts and DR */
++	mtmsr	r10
++	SYNC_601
++	isync
++
++	lwz	r0,4(r1)
++	mtlr	r0
++	blr
++
++/*
++ * This routine adds a hardware PTE to the hash table.
++ * It is designed to be called with the MMU either on or off.
++ * r3 contains the VSID, r4 contains the virtual address,
++ * r5 contains the linux PTE, r6 contains the old value of the
++ * linux PTE (before setting _PAGE_HASHPTE) and r7 contains the
++ * offset to be added to addresses (0 if the MMU is on,
++ * -KERNELBASE if it is off).
++ * On SMP, the caller should have the mmu_hash_lock held.
++ * We assume that the caller has (or will) set the _PAGE_HASHPTE
++ * bit in the linux PTE in memory.  The value passed in r6 should
++ * be the old linux PTE value; if it doesn't have _PAGE_HASHPTE set
++ * this routine will skip the search for an existing HPTE.
++ * This procedure modifies r0, r3 - r6, r8, cr0.
++ *  -- paulus.
++ *
++ * For speed, 4 of the instructions get patched once the size and
++ * physical address of the hash table are known.  These definitions
++ * of Hash_base and Hash_bits below are just an example.
++ */
++Hash_base = 0xc0180000
++Hash_bits = 12				/* e.g. 256kB hash table */
++Hash_msk = (((1 << Hash_bits) - 1) * 64)
++
++#ifndef CONFIG_PPC64BRIDGE
++/* defines for the PTE format for 32-bit PPCs */
++#define PTE_SIZE	8
++#define PTEG_SIZE	64
++#define LG_PTEG_SIZE	6
++#define LDPTEu		lwzu
++#define STPTE		stw
++#define CMPPTE		cmpw
++#define PTE_H		0x40
++#define PTE_V		0x80000000
++#define TST_V(r)	rlwinm. r,r,0,0,0
++#define SET_V(r)	oris r,r,PTE_V at h
++#define CLR_V(r,t)	rlwinm r,r,0,1,31
++
++#else
++/* defines for the PTE format for 64-bit PPCs */
++#define PTE_SIZE	16
++#define PTEG_SIZE	128
++#define LG_PTEG_SIZE	7
++#define LDPTEu		ldu
++#define STPTE		std
++#define CMPPTE		cmpd
++#define PTE_H		2
++#define PTE_V		1
++#define TST_V(r)	andi. r,r,PTE_V
++#define SET_V(r)	ori r,r,PTE_V
++#define CLR_V(r,t)	li t,PTE_V; andc r,r,t
++#endif /* CONFIG_PPC64BRIDGE */
++
++#define HASH_LEFT	31-(LG_PTEG_SIZE+Hash_bits-1)
++#define HASH_RIGHT	31-LG_PTEG_SIZE
++
++_GLOBAL(create_hpte)
++	/* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */
++	rlwinm	r8,r5,32-10,31,31	/* _PAGE_RW -> PP lsb */
++	rlwinm	r0,r5,32-7,31,31	/* _PAGE_DIRTY -> PP lsb */
++	and	r8,r8,r0		/* writable if _RW & _DIRTY */
++	rlwimi	r5,r5,32-1,30,30	/* _PAGE_USER -> PP msb */
++	rlwimi	r5,r5,32-2,31,31	/* _PAGE_USER -> PP lsb */
++	ori	r8,r8,0xe14		/* clear out reserved bits and M */
++	andc	r8,r5,r8		/* PP = user? (rw&dirty? 2: 3): 0 */
++BEGIN_FTR_SECTION
++	ori	r8,r8,_PAGE_COHERENT	/* set M (coherence required) */
++END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT)
++
++	/* Construct the high word of the PPC-style PTE (r5) */
++#ifndef CONFIG_PPC64BRIDGE
++	rlwinm	r5,r3,7,1,24		/* put VSID in 0x7fffff80 bits */
++	rlwimi	r5,r4,10,26,31		/* put in API (abbrev page index) */
++#else /* CONFIG_PPC64BRIDGE */
++	clrlwi	r3,r3,8			/* reduce vsid to 24 bits */
++	sldi	r5,r3,12		/* shift vsid into position */
++	rlwimi	r5,r4,16,20,24		/* put in API (abbrev page index) */
++#endif /* CONFIG_PPC64BRIDGE */
++	SET_V(r5)			/* set V (valid) bit */
++
++	/* Get the address of the primary PTE group in the hash table (r3) */
++_GLOBAL(hash_page_patch_A)
++	addis	r0,r7,Hash_base at h	/* base address of hash table */
++	rlwimi	r0,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT    /* VSID -> hash */
++	rlwinm	r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
++	xor	r3,r3,r0		/* make primary hash */
++	li	r0,8			/* PTEs/group */
++
++	/*
++	 * Test the _PAGE_HASHPTE bit in the old linux PTE, and skip the search
++	 * if it is clear, meaning that the HPTE isn't there already...
++	 */
++	andi.	r6,r6,_PAGE_HASHPTE
++	beq+	10f			/* no PTE: go look for an empty slot */
++	tlbie	r4
++
++	addis	r4,r7,htab_hash_searches at ha
++	lwz	r6,htab_hash_searches at l(r4)
++	addi	r6,r6,1			/* count how many searches we do */
++	stw	r6,htab_hash_searches at l(r4)
++
++	/* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
++	mtctr	r0
++	addi	r4,r3,-PTE_SIZE
++1:	LDPTEu	r6,PTE_SIZE(r4)		/* get next PTE */
++	CMPPTE	0,r6,r5
++	bdnzf	2,1b			/* loop while ctr != 0 && !cr0.eq */
++	beq+	found_slot
++
++	/* Search the secondary PTEG for a matching PTE */
++	ori	r5,r5,PTE_H		/* set H (secondary hash) bit */
++_GLOBAL(hash_page_patch_B)
++	xoris	r4,r3,Hash_msk>>16	/* compute secondary hash */
++	xori	r4,r4,(-PTEG_SIZE & 0xffff)
++	addi	r4,r4,-PTE_SIZE
++	mtctr	r0
++2:	LDPTEu	r6,PTE_SIZE(r4)
++	CMPPTE	0,r6,r5
++	bdnzf	2,2b
++	beq+	found_slot
++	xori	r5,r5,PTE_H		/* clear H bit again */
++
++	/* Search the primary PTEG for an empty slot */
++10:	mtctr	r0
++	addi	r4,r3,-PTE_SIZE		/* search primary PTEG */
++1:	LDPTEu	r6,PTE_SIZE(r4)		/* get next PTE */
++	TST_V(r6)			/* test valid bit */
++	bdnzf	2,1b			/* loop while ctr != 0 && !cr0.eq */
++	beq+	found_empty
++
++	/* update counter of times that the primary PTEG is full */
++	addis	r4,r7,primary_pteg_full at ha
++	lwz	r6,primary_pteg_full at l(r4)
++	addi	r6,r6,1
++	stw	r6,primary_pteg_full at l(r4)
++
++	/* Search the secondary PTEG for an empty slot */
++	ori	r5,r5,PTE_H		/* set H (secondary hash) bit */
++_GLOBAL(hash_page_patch_C)
++	xoris	r4,r3,Hash_msk>>16	/* compute secondary hash */
++	xori	r4,r4,(-PTEG_SIZE & 0xffff)
++	addi	r4,r4,-PTE_SIZE
++	mtctr	r0
++2:	LDPTEu	r6,PTE_SIZE(r4)
++	TST_V(r6)
++	bdnzf	2,2b
++	beq+	found_empty
++	xori	r5,r5,PTE_H		/* clear H bit again */
++
++	/*
++	 * Choose an arbitrary slot in the primary PTEG to overwrite.
++	 * Since both the primary and secondary PTEGs are full, and we
++	 * have no information that the PTEs in the primary PTEG are
++	 * more important or useful than those in the secondary PTEG,
++	 * and we know there is a definite (although small) speed
++	 * advantage to putting the PTE in the primary PTEG, we always
++	 * put the PTE in the primary PTEG.
++	 */
++	addis	r4,r7,next_slot at ha
++	lwz	r6,next_slot at l(r4)
++	addi	r6,r6,PTE_SIZE
++	andi.	r6,r6,7*PTE_SIZE
++	stw	r6,next_slot at l(r4)
++	add	r4,r3,r6
++
++#ifndef CONFIG_SMP
++	/* Store PTE in PTEG */
++found_empty:
++	STPTE	r5,0(r4)
++found_slot:
++	STPTE	r8,PTE_SIZE/2(r4)
++
++#else /* CONFIG_SMP */
++/*
++ * Between the tlbie above and updating the hash table entry below,
++ * another CPU could read the hash table entry and put it in its TLB.
++ * There are 3 cases:
++ * 1. using an empty slot
++ * 2. updating an earlier entry to change permissions (i.e. enable write)
++ * 3. taking over the PTE for an unrelated address
++ *
++ * In each case it doesn't really matter if the other CPUs have the old
++ * PTE in their TLB.  So we don't need to bother with another tlbie here,
++ * which is convenient as we've overwritten the register that had the
++ * address. :-)  The tlbie above is mainly to make sure that this CPU comes
++ * and gets the new PTE from the hash table.
++ *
++ * We do however have to make sure that the PTE is never in an invalid
++ * state with the V bit set.
++ */
++found_empty:
++found_slot:
++	CLR_V(r5,r0)		/* clear V (valid) bit in PTE */
++	STPTE	r5,0(r4)
++	sync
++	TLBSYNC
++	STPTE	r8,PTE_SIZE/2(r4) /* put in correct RPN, WIMG, PP bits */
++	sync
++	SET_V(r5)
++	STPTE	r5,0(r4)	/* finally set V bit in PTE */
++#endif /* CONFIG_SMP */
++
++	sync		/* make sure pte updates get to memory */
++	blr
++
++	.comm	next_slot,4
++	.comm	primary_pteg_full,4
++	.comm	htab_hash_searches,4
++
++/*
++ * Flush the entry for a particular page from the hash table.
++ *
++ * flush_hash_pages(unsigned context, unsigned long va, unsigned long pmdval,
++ *		    int count)
++ *
++ * We assume that there is a hash table in use (Hash != 0).
++ */
++_GLOBAL(flush_hash_pages)
++	tophys(r7,0)
++
++	/*
++	 * We disable interrupts here, even on UP, because we want
++	 * the _PAGE_HASHPTE bit to be a reliable indication of
++	 * whether the HPTE exists (or at least whether one did once).
++	 * We also turn off the MMU for data accesses so that we
++	 * we can't take a hash table miss (assuming the code is
++	 * covered by a BAT).  -- paulus
++	 */
++	mfmsr	r10
++	SYNC
++	rlwinm	r0,r10,0,17,15		/* clear bit 16 (MSR_EE) */
++	rlwinm	r0,r0,0,28,26		/* clear MSR_DR */
++	mtmsr	r0
++	SYNC_601
++	isync
++
++	/* First find a PTE in the range that has _PAGE_HASHPTE set */
++	rlwimi	r5,r4,22,20,29
++1:	lwz	r0,0(r5)
++	cmpwi	cr1,r6,1
++	andi.	r0,r0,_PAGE_HASHPTE
++	bne	2f
++	ble	cr1,19f
++	addi	r4,r4,0x1000
++	addi	r5,r5,4
++	addi	r6,r6,-1
++	b	1b
++
++	/* Convert context and va to VSID */
++2:	mulli	r3,r3,897*16		/* multiply context by context skew */
++	rlwinm	r0,r4,4,28,31		/* get ESID (top 4 bits of va) */
++	mulli	r0,r0,0x111		/* multiply by ESID skew */
++	add	r3,r3,r0		/* note code below trims to 24 bits */
++
++	/* Construct the high word of the PPC-style PTE (r11) */
++#ifndef CONFIG_PPC64BRIDGE
++	rlwinm	r11,r3,7,1,24		/* put VSID in 0x7fffff80 bits */
++	rlwimi	r11,r4,10,26,31		/* put in API (abbrev page index) */
++#else /* CONFIG_PPC64BRIDGE */
++	clrlwi	r3,r3,8			/* reduce vsid to 24 bits */
++	sldi	r11,r3,12		/* shift vsid into position */
++	rlwimi	r11,r4,16,20,24		/* put in API (abbrev page index) */
++#endif /* CONFIG_PPC64BRIDGE */
++	SET_V(r11)			/* set V (valid) bit */
++
++#ifdef CONFIG_SMP
++	addis	r9,r7,mmu_hash_lock at ha
++	addi	r9,r9,mmu_hash_lock at l
++	rlwinm	r8,r1,0,0,18
++	add	r8,r8,r7
++	lwz	r8,TI_CPU(r8)
++	oris	r8,r8,9
++10:	lwarx	r0,0,r9
++	cmpi	0,r0,0
++	bne-	11f
++	stwcx.	r8,0,r9
++	beq+	12f
++11:	lwz	r0,0(r9)
++	cmpi	0,r0,0
++	beq	10b
++	b	11b
++12:	isync
++#endif
++
++	/*
++	 * Check the _PAGE_HASHPTE bit in the linux PTE.  If it is
++	 * already clear, we're done (for this pte).  If not,
++	 * clear it (atomically) and proceed.  -- paulus.
++	 */
++33:	lwarx	r8,0,r5			/* fetch the pte */
++	andi.	r0,r8,_PAGE_HASHPTE
++	beq	8f			/* done if HASHPTE is already clear */
++	rlwinm	r8,r8,0,31,29		/* clear HASHPTE bit */
++	stwcx.	r8,0,r5			/* update the pte */
++	bne-	33b
++
++	/* Get the address of the primary PTE group in the hash table (r3) */
++_GLOBAL(flush_hash_patch_A)
++	addis	r8,r7,Hash_base at h	/* base address of hash table */
++	rlwimi	r8,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT    /* VSID -> hash */
++	rlwinm	r0,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
++	xor	r8,r0,r8		/* make primary hash */
++
++	/* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
++	li	r0,8			/* PTEs/group */
++	mtctr	r0
++	addi	r12,r8,-PTE_SIZE
++1:	LDPTEu	r0,PTE_SIZE(r12)	/* get next PTE */
++	CMPPTE	0,r0,r11
++	bdnzf	2,1b			/* loop while ctr != 0 && !cr0.eq */
++	beq+	3f
++
++	/* Search the secondary PTEG for a matching PTE */
++	ori	r11,r11,PTE_H		/* set H (secondary hash) bit */
++	li	r0,8			/* PTEs/group */
++_GLOBAL(flush_hash_patch_B)
++	xoris	r12,r8,Hash_msk>>16	/* compute secondary hash */
++	xori	r12,r12,(-PTEG_SIZE & 0xffff)
++	addi	r12,r12,-PTE_SIZE
++	mtctr	r0
++2:	LDPTEu	r0,PTE_SIZE(r12)
++	CMPPTE	0,r0,r11
++	bdnzf	2,2b
++	xori	r11,r11,PTE_H		/* clear H again */
++	bne-	4f			/* should rarely fail to find it */
++
++3:	li	r0,0
++	STPTE	r0,0(r12)		/* invalidate entry */
++4:	sync
++	tlbie	r4			/* in hw tlb too */
++	sync
++
++8:	ble	cr1,9f			/* if all ptes checked */
++81:	addi	r6,r6,-1
++	addi	r5,r5,4			/* advance to next pte */
++	addi	r4,r4,0x1000
++	lwz	r0,0(r5)		/* check next pte */
++	cmpwi	cr1,r6,1
++	andi.	r0,r0,_PAGE_HASHPTE
++	bne	33b
++	bgt	cr1,81b
++
++9:
++#ifdef CONFIG_SMP
++	TLBSYNC
++	li	r0,0
++	stw	r0,0(r9)		/* clear mmu_hash_lock */
++#endif
++
++19:	mtmsr	r10
++	SYNC_601
++	isync
++	blr
+diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/hash_low_64.S
+@@ -0,0 +1,288 @@
++/*
++ * ppc64 MMU hashtable management routines
++ *
++ * (c) Copyright IBM Corp. 2003
++ *
++ * Maintained by: Benjamin Herrenschmidt
++ *                <benh at kernel.crashing.org>
++ *
++ * This file is covered by the GNU Public Licence v2 as
++ * described in the kernel's COPYING file.
++ */
++
++#include <asm/reg.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/page.h>
++#include <asm/types.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++#include <asm/cputable.h>
++
++	.text
++
++/*
++ * Stackframe:
++ *		
++ *         +-> Back chain			(SP + 256)
++ *         |   General register save area	(SP + 112)
++ *         |   Parameter save area		(SP + 48)
++ *         |   TOC save area			(SP + 40)
++ *         |   link editor doubleword		(SP + 32)
++ *         |   compiler doubleword		(SP + 24)
++ *         |   LR save area			(SP + 16)
++ *         |   CR save area			(SP + 8)
++ * SP ---> +-- Back chain			(SP + 0)
++ */
++#define STACKFRAMESIZE	256
++
++/* Save parameters offsets */
++#define STK_PARM(i)	(STACKFRAMESIZE + 48 + ((i)-3)*8)
++
++/* Save non-volatile offsets */
++#define STK_REG(i)	(112 + ((i)-14)*8)
++
++/*
++ * _hash_page(unsigned long ea, unsigned long access, unsigned long vsid,
++ *		pte_t *ptep, unsigned long trap, int local)
++ *
++ * Adds a page to the hash table. This is the non-LPAR version for now
++ */
++
++_GLOBAL(__hash_page)
++	mflr	r0
++	std	r0,16(r1)
++	stdu	r1,-STACKFRAMESIZE(r1)
++	/* Save all params that we need after a function call */
++	std	r6,STK_PARM(r6)(r1)
++	std	r8,STK_PARM(r8)(r1)
++	
++	/* Add _PAGE_PRESENT to access */
++	ori	r4,r4,_PAGE_PRESENT
++
++	/* Save non-volatile registers.
++	 * r31 will hold "old PTE"
++	 * r30 is "new PTE"
++	 * r29 is "va"
++	 * r28 is a hash value
++	 * r27 is hashtab mask (maybe dynamic patched instead ?)
++	 */
++	std	r27,STK_REG(r27)(r1)
++	std	r28,STK_REG(r28)(r1)
++	std	r29,STK_REG(r29)(r1)
++	std	r30,STK_REG(r30)(r1)
++	std	r31,STK_REG(r31)(r1)
++	
++	/* Step 1:
++	 *
++	 * Check permissions, atomically mark the linux PTE busy
++	 * and hashed.
++	 */ 
++1:
++	ldarx	r31,0,r6
++	/* Check access rights (access & ~(pte_val(*ptep))) */
++	andc.	r0,r4,r31
++	bne-	htab_wrong_access
++	/* Check if PTE is busy */
++	andi.	r0,r31,_PAGE_BUSY
++	/* If so, just bail out and refault if needed. Someone else
++	 * is changing this PTE anyway and might hash it.
++	 */
++	bne-	bail_ok
++	/* Prepare new PTE value (turn access RW into DIRTY, then
++	 * add BUSY,HASHPTE and ACCESSED)
++	 */
++	rlwinm	r30,r4,32-9+7,31-7,31-7	/* _PAGE_RW -> _PAGE_DIRTY */
++	or	r30,r30,r31
++	ori	r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
++	/* Write the linux PTE atomically (setting busy) */
++	stdcx.	r30,0,r6
++	bne-	1b
++	isync
++
++	/* Step 2:
++	 *
++	 * Insert/Update the HPTE in the hash table. At this point,
++	 * r4 (access) is re-useable, we use it for the new HPTE flags
++	 */
++
++	/* Calc va and put it in r29 */
++	rldicr	r29,r5,28,63-28
++	rldicl	r3,r3,0,36
++	or	r29,r3,r29
++
++	/* Calculate hash value for primary slot and store it in r28 */
++	rldicl	r5,r5,0,25		/* vsid & 0x0000007fffffffff */
++	rldicl	r0,r3,64-12,48		/* (ea >> 12) & 0xffff */
++	xor	r28,r5,r0
++
++	/* Convert linux PTE bits into HW equivalents */
++	andi.	r3,r30,0x1fe		/* Get basic set of flags */
++	xori	r3,r3,HW_NO_EXEC	/* _PAGE_EXEC -> NOEXEC */
++	rlwinm	r0,r30,32-9+1,30,30	/* _PAGE_RW -> _PAGE_USER (r0) */
++	rlwinm	r4,r30,32-7+1,30,30	/* _PAGE_DIRTY -> _PAGE_USER (r4) */
++	and	r0,r0,r4		/* _PAGE_RW & _PAGE_DIRTY -> r0 bit 30 */
++	andc	r0,r30,r0		/* r0 = pte & ~r0 */
++	rlwimi	r3,r0,32-1,31,31	/* Insert result into PP lsb */
++
++	/* We eventually do the icache sync here (maybe inline that
++	 * code rather than call a C function...) 
++	 */
++BEGIN_FTR_SECTION
++	mr	r4,r30
++	mr	r5,r7
++	bl	.hash_page_do_lazy_icache
++END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
++
++	/* At this point, r3 contains new PP bits, save them in
++	 * place of "access" in the param area (sic)
++	 */
++	std	r3,STK_PARM(r4)(r1)
++
++	/* Get htab_hash_mask */
++	ld	r4,htab_hash_mask at got(2)
++	ld	r27,0(r4)	/* htab_hash_mask -> r27 */
++
++	/* Check if we may already be in the hashtable, in this case, we
++	 * go to out-of-line code to try to modify the HPTE
++	 */
++	andi.	r0,r31,_PAGE_HASHPTE
++	bne	htab_modify_pte
++
++htab_insert_pte:
++	/* Clear hpte bits in new pte (we also clear BUSY btw) and
++	 * add _PAGE_HASHPTE
++	 */
++	lis	r0,_PAGE_HPTEFLAGS at h
++	ori	r0,r0,_PAGE_HPTEFLAGS at l
++	andc	r30,r30,r0
++	ori	r30,r30,_PAGE_HASHPTE
++
++	/* page number in r5 */
++	rldicl	r5,r31,64-PTE_SHIFT,PTE_SHIFT
++
++	/* Calculate primary group hash */
++	and	r0,r28,r27
++	rldicr	r3,r0,3,63-3	/* r0 = (hash & mask) << 3 */
++
++	/* Call ppc_md.hpte_insert */
++	ld	r7,STK_PARM(r4)(r1)	/* Retreive new pp bits */
++	mr	r4,r29			/* Retreive va */
++	li	r6,0			/* no vflags */
++_GLOBAL(htab_call_hpte_insert1)
++	bl	.			/* Will be patched by htab_finish_init() */
++	cmpdi	0,r3,0
++	bge	htab_pte_insert_ok	/* Insertion successful */
++	cmpdi	0,r3,-2			/* Critical failure */
++	beq-	htab_pte_insert_failure
++
++	/* Now try secondary slot */
++	
++	/* page number in r5 */
++	rldicl	r5,r31,64-PTE_SHIFT,PTE_SHIFT
++
++	/* Calculate secondary group hash */
++	andc	r0,r27,r28
++	rldicr	r3,r0,3,63-3	/* r0 = (~hash & mask) << 3 */
++	
++	/* Call ppc_md.hpte_insert */
++	ld	r7,STK_PARM(r4)(r1)	/* Retreive new pp bits */
++	mr	r4,r29			/* Retreive va */
++	li	r6,HPTE_V_SECONDARY at l	/* secondary slot */
++_GLOBAL(htab_call_hpte_insert2)
++	bl	.			/* Will be patched by htab_finish_init() */
++	cmpdi	0,r3,0
++	bge+	htab_pte_insert_ok	/* Insertion successful */
++	cmpdi	0,r3,-2			/* Critical failure */
++	beq-	htab_pte_insert_failure
++
++	/* Both are full, we need to evict something */
++	mftb	r0
++	/* Pick a random group based on TB */
++	andi.	r0,r0,1
++	mr	r5,r28
++	bne	2f
++	not	r5,r5
++2:	and	r0,r5,r27
++	rldicr	r3,r0,3,63-3	/* r0 = (hash & mask) << 3 */	
++	/* Call ppc_md.hpte_remove */
++_GLOBAL(htab_call_hpte_remove)
++	bl	.			/* Will be patched by htab_finish_init() */
++
++	/* Try all again */
++	b	htab_insert_pte	
++
++bail_ok:
++	li	r3,0
++	b	bail
++
++htab_pte_insert_ok:
++	/* Insert slot number & secondary bit in PTE */
++	rldimi	r30,r3,12,63-15
++		
++	/* Write out the PTE with a normal write
++	 * (maybe add eieio may be good still ?)
++	 */
++htab_write_out_pte:
++	ld	r6,STK_PARM(r6)(r1)
++	std	r30,0(r6)
++	li	r3, 0
++bail:
++	ld	r27,STK_REG(r27)(r1)
++	ld	r28,STK_REG(r28)(r1)
++	ld	r29,STK_REG(r29)(r1)
++	ld      r30,STK_REG(r30)(r1)
++	ld      r31,STK_REG(r31)(r1)
++	addi    r1,r1,STACKFRAMESIZE
++	ld      r0,16(r1)
++	mtlr    r0
++	blr
++
++htab_modify_pte:
++	/* Keep PP bits in r4 and slot idx from the PTE around in r3 */
++	mr	r4,r3
++	rlwinm	r3,r31,32-12,29,31
++
++	/* Secondary group ? if yes, get a inverted hash value */
++	mr	r5,r28
++	andi.	r0,r31,_PAGE_SECONDARY
++	beq	1f
++	not	r5,r5
++1:
++	/* Calculate proper slot value for ppc_md.hpte_updatepp */
++	and	r0,r5,r27
++	rldicr	r0,r0,3,63-3	/* r0 = (hash & mask) << 3 */
++	add	r3,r0,r3	/* add slot idx */
++
++	/* Call ppc_md.hpte_updatepp */
++	mr	r5,r29			/* va */
++	li	r6,0			/* large is 0 */
++	ld	r7,STK_PARM(r8)(r1)	/* get "local" param */
++_GLOBAL(htab_call_hpte_updatepp)
++	bl	.			/* Will be patched by htab_finish_init() */
++
++	/* if we failed because typically the HPTE wasn't really here
++	 * we try an insertion. 
++	 */
++	cmpdi	0,r3,-1
++	beq-	htab_insert_pte
++
++	/* Clear the BUSY bit and Write out the PTE */
++	li	r0,_PAGE_BUSY
++	andc	r30,r30,r0
++	b	htab_write_out_pte
++
++htab_wrong_access:
++	/* Bail out clearing reservation */
++	stdcx.	r31,0,r6
++	li	r3,1
++	b	bail
++
++htab_pte_insert_failure:
++	/* Bail out restoring old PTE */
++	ld	r6,STK_PARM(r6)(r1)
++	std	r31,0(r6)
++	li	r3,-1
++	b	bail
++
++
+diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/hash_native_64.c
+@@ -0,0 +1,446 @@
++/*
++ * native hashtable management.
++ *
++ * SMP scalability work:
++ *    Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, 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/spinlock.h>
++#include <linux/bitops.h>
++#include <linux/threads.h>
++#include <linux/smp.h>
++
++#include <asm/abs_addr.h>
++#include <asm/machdep.h>
++#include <asm/mmu.h>
++#include <asm/mmu_context.h>
++#include <asm/pgtable.h>
++#include <asm/tlbflush.h>
++#include <asm/tlb.h>
++#include <asm/cputable.h>
++
++#define HPTE_LOCK_BIT 3
++
++static DEFINE_SPINLOCK(native_tlbie_lock);
++
++static inline void native_lock_hpte(hpte_t *hptep)
++{
++	unsigned long *word = &hptep->v;
++
++	while (1) {
++		if (!test_and_set_bit(HPTE_LOCK_BIT, word))
++			break;
++		while(test_bit(HPTE_LOCK_BIT, word))
++			cpu_relax();
++	}
++}
++
++static inline void native_unlock_hpte(hpte_t *hptep)
++{
++	unsigned long *word = &hptep->v;
++
++	asm volatile("lwsync":::"memory");
++	clear_bit(HPTE_LOCK_BIT, word);
++}
++
++long native_hpte_insert(unsigned long hpte_group, unsigned long va,
++			unsigned long prpn, unsigned long vflags,
++			unsigned long rflags)
++{
++	hpte_t *hptep = htab_address + hpte_group;
++	unsigned long hpte_v, hpte_r;
++	int i;
++
++	for (i = 0; i < HPTES_PER_GROUP; i++) {
++		if (! (hptep->v & HPTE_V_VALID)) {
++			/* retry with lock held */
++			native_lock_hpte(hptep);
++			if (! (hptep->v & HPTE_V_VALID))
++				break;
++			native_unlock_hpte(hptep);
++		}
++
++		hptep++;
++	}
++
++	if (i == HPTES_PER_GROUP)
++		return -1;
++
++	hpte_v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
++	if (vflags & HPTE_V_LARGE)
++		va &= ~(1UL << HPTE_V_AVPN_SHIFT);
++	hpte_r = (prpn << HPTE_R_RPN_SHIFT) | rflags;
++
++	hptep->r = hpte_r;
++	/* Guarantee the second dword is visible before the valid bit */
++	__asm__ __volatile__ ("eieio" : : : "memory");
++	/*
++	 * Now set the first dword including the valid bit
++	 * NOTE: this also unlocks the hpte
++	 */
++	hptep->v = hpte_v;
++
++	__asm__ __volatile__ ("ptesync" : : : "memory");
++
++	return i | (!!(vflags & HPTE_V_SECONDARY) << 3);
++}
++
++static long native_hpte_remove(unsigned long hpte_group)
++{
++	hpte_t *hptep;
++	int i;
++	int slot_offset;
++	unsigned long hpte_v;
++
++	/* pick a random entry to start at */
++	slot_offset = mftb() & 0x7;
++
++	for (i = 0; i < HPTES_PER_GROUP; i++) {
++		hptep = htab_address + hpte_group + slot_offset;
++		hpte_v = hptep->v;
++
++		if ((hpte_v & HPTE_V_VALID) && !(hpte_v & HPTE_V_BOLTED)) {
++			/* retry with lock held */
++			native_lock_hpte(hptep);
++			hpte_v = hptep->v;
++			if ((hpte_v & HPTE_V_VALID)
++			    && !(hpte_v & HPTE_V_BOLTED))
++				break;
++			native_unlock_hpte(hptep);
++		}
++
++		slot_offset++;
++		slot_offset &= 0x7;
++	}
++
++	if (i == HPTES_PER_GROUP)
++		return -1;
++
++	/* Invalidate the hpte. NOTE: this also unlocks it */
++	hptep->v = 0;
++
++	return i;
++}
++
++static inline void set_pp_bit(unsigned long pp, hpte_t *addr)
++{
++	unsigned long old;
++	unsigned long *p = &addr->r;
++
++	__asm__ __volatile__(
++	"1:	ldarx	%0,0,%3\n\
++		rldimi	%0,%2,0,61\n\
++		stdcx.	%0,0,%3\n\
++		bne	1b"
++	: "=&r" (old), "=m" (*p)
++	: "r" (pp), "r" (p), "m" (*p)
++	: "cc");
++}
++
++/*
++ * Only works on small pages. Yes its ugly to have to check each slot in
++ * the group but we only use this during bootup.
++ */
++static long native_hpte_find(unsigned long vpn)
++{
++	hpte_t *hptep;
++	unsigned long hash;
++	unsigned long i, j;
++	long slot;
++	unsigned long hpte_v;
++
++	hash = hpt_hash(vpn, 0);
++
++	for (j = 0; j < 2; j++) {
++		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
++		for (i = 0; i < HPTES_PER_GROUP; i++) {
++			hptep = htab_address + slot;
++			hpte_v = hptep->v;
++
++			if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
++			    && (hpte_v & HPTE_V_VALID)
++			    && ( !!(hpte_v & HPTE_V_SECONDARY) == j)) {
++				/* HPTE matches */
++				if (j)
++					slot = -slot;
++				return slot;
++			}
++			++slot;
++		}
++		hash = ~hash;
++	}
++
++	return -1;
++}
++
++static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
++				 unsigned long va, int large, int local)
++{
++	hpte_t *hptep = htab_address + slot;
++	unsigned long hpte_v;
++	unsigned long avpn = va >> 23;
++	int ret = 0;
++
++	if (large)
++		avpn &= ~1;
++
++	native_lock_hpte(hptep);
++
++	hpte_v = hptep->v;
++
++	/* Even if we miss, we need to invalidate the TLB */
++	if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
++	    || !(hpte_v & HPTE_V_VALID)) {
++		native_unlock_hpte(hptep);
++		ret = -1;
++	} else {
++		set_pp_bit(newpp, hptep);
++		native_unlock_hpte(hptep);
++	}
++
++	/* Ensure it is out of the tlb too */
++	if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
++		tlbiel(va);
++	} else {
++		int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
++
++		if (lock_tlbie)
++			spin_lock(&native_tlbie_lock);
++		tlbie(va, large);
++		if (lock_tlbie)
++			spin_unlock(&native_tlbie_lock);
++	}
++
++	return ret;
++}
++
++/*
++ * Update the page protection bits. Intended to be used to create
++ * guard pages for kernel data structures on pages which are bolted
++ * in the HPT. Assumes pages being operated on will not be stolen.
++ * Does not work on large pages.
++ *
++ * No need to lock here because we should be the only user.
++ */
++static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
++{
++	unsigned long vsid, va, vpn, flags = 0;
++	long slot;
++	hpte_t *hptep;
++	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
++
++	vsid = get_kernel_vsid(ea);
++	va = (vsid << 28) | (ea & 0x0fffffff);
++	vpn = va >> PAGE_SHIFT;
++
++	slot = native_hpte_find(vpn);
++	if (slot == -1)
++		panic("could not find page to bolt\n");
++	hptep = htab_address + slot;
++
++	set_pp_bit(newpp, hptep);
++
++	/* Ensure it is out of the tlb too */
++	if (lock_tlbie)
++		spin_lock_irqsave(&native_tlbie_lock, flags);
++	tlbie(va, 0);
++	if (lock_tlbie)
++		spin_unlock_irqrestore(&native_tlbie_lock, flags);
++}
++
++static void native_hpte_invalidate(unsigned long slot, unsigned long va,
++				    int large, int local)
++{
++	hpte_t *hptep = htab_address + slot;
++	unsigned long hpte_v;
++	unsigned long avpn = va >> 23;
++	unsigned long flags;
++	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
++
++	if (large)
++		avpn &= ~1;
++
++	local_irq_save(flags);
++	native_lock_hpte(hptep);
++
++	hpte_v = hptep->v;
++
++	/* Even if we miss, we need to invalidate the TLB */
++	if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
++	    || !(hpte_v & HPTE_V_VALID)) {
++		native_unlock_hpte(hptep);
++	} else {
++		/* Invalidate the hpte. NOTE: this also unlocks it */
++		hptep->v = 0;
++	}
++
++	/* Invalidate the tlb */
++	if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
++		tlbiel(va);
++	} else {
++		if (lock_tlbie)
++			spin_lock(&native_tlbie_lock);
++		tlbie(va, large);
++		if (lock_tlbie)
++			spin_unlock(&native_tlbie_lock);
++	}
++	local_irq_restore(flags);
++}
++
++/*
++ * clear all mappings on kexec.  All cpus are in real mode (or they will
++ * be when they isi), and we are the only one left.  We rely on our kernel
++ * mapping being 0xC0's and the hardware ignoring those two real bits.
++ *
++ * TODO: add batching support when enabled.  remember, no dynamic memory here,
++ * athough there is the control page available...
++ */
++static void native_hpte_clear(void)
++{
++	unsigned long slot, slots, flags;
++	hpte_t *hptep = htab_address;
++	unsigned long hpte_v;
++	unsigned long pteg_count;
++
++	pteg_count = htab_hash_mask + 1;
++
++	local_irq_save(flags);
++
++	/* we take the tlbie lock and hold it.  Some hardware will
++	 * deadlock if we try to tlbie from two processors at once.
++	 */
++	spin_lock(&native_tlbie_lock);
++
++	slots = pteg_count * HPTES_PER_GROUP;
++
++	for (slot = 0; slot < slots; slot++, hptep++) {
++		/*
++		 * we could lock the pte here, but we are the only cpu
++		 * running,  right?  and for crash dump, we probably
++		 * don't want to wait for a maybe bad cpu.
++		 */
++		hpte_v = hptep->v;
++
++		if (hpte_v & HPTE_V_VALID) {
++			hptep->v = 0;
++			tlbie(slot2va(hpte_v, slot), hpte_v & HPTE_V_LARGE);
++		}
++	}
++
++	spin_unlock(&native_tlbie_lock);
++	local_irq_restore(flags);
++}
++
++static void native_flush_hash_range(unsigned long number, int local)
++{
++	unsigned long va, vpn, hash, secondary, slot, flags, avpn;
++	int i, j;
++	hpte_t *hptep;
++	unsigned long hpte_v;
++	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
++	unsigned long large = batch->large;
++
++	local_irq_save(flags);
++
++	j = 0;
++	for (i = 0; i < number; i++) {
++		va = batch->vaddr[j];
++		if (large)
++			vpn = va >> HPAGE_SHIFT;
++		else
++			vpn = va >> PAGE_SHIFT;
++		hash = hpt_hash(vpn, large);
++		secondary = (pte_val(batch->pte[i]) & _PAGE_SECONDARY) >> 15;
++		if (secondary)
++			hash = ~hash;
++		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
++		slot += (pte_val(batch->pte[i]) & _PAGE_GROUP_IX) >> 12;
++
++		hptep = htab_address + slot;
++
++		avpn = va >> 23;
++		if (large)
++			avpn &= ~0x1UL;
++
++		native_lock_hpte(hptep);
++
++		hpte_v = hptep->v;
++
++		/* Even if we miss, we need to invalidate the TLB */
++		if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
++		    || !(hpte_v & HPTE_V_VALID)) {
++			native_unlock_hpte(hptep);
++		} else {
++			/* Invalidate the hpte. NOTE: this also unlocks it */
++			hptep->v = 0;
++		}
++
++		j++;
++	}
++
++	if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
++		asm volatile("ptesync":::"memory");
++
++		for (i = 0; i < j; i++)
++			__tlbiel(batch->vaddr[i]);
++
++		asm volatile("ptesync":::"memory");
++	} else {
++		int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
++
++		if (lock_tlbie)
++			spin_lock(&native_tlbie_lock);
++
++		asm volatile("ptesync":::"memory");
++
++		for (i = 0; i < j; i++)
++			__tlbie(batch->vaddr[i], large);
++
++		asm volatile("eieio; tlbsync; ptesync":::"memory");
++
++		if (lock_tlbie)
++			spin_unlock(&native_tlbie_lock);
++	}
++
++	local_irq_restore(flags);
++}
++
++#ifdef CONFIG_PPC_PSERIES
++/* Disable TLB batching on nighthawk */
++static inline int tlb_batching_enabled(void)
++{
++	struct device_node *root = of_find_node_by_path("/");
++	int enabled = 1;
++
++	if (root) {
++		const char *model = get_property(root, "model", NULL);
++		if (model && !strcmp(model, "IBM,9076-N81"))
++			enabled = 0;
++		of_node_put(root);
++	}
++
++	return enabled;
++}
++#else
++static inline int tlb_batching_enabled(void)
++{
++	return 1;
++}
++#endif
++
++void hpte_init_native(void)
++{
++	ppc_md.hpte_invalidate	= native_hpte_invalidate;
++	ppc_md.hpte_updatepp	= native_hpte_updatepp;
++	ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp;
++	ppc_md.hpte_insert	= native_hpte_insert;
++	ppc_md.hpte_remove	= native_hpte_remove;
++	ppc_md.hpte_clear_all	= native_hpte_clear;
++	if (tlb_batching_enabled())
++		ppc_md.flush_hash_range = native_flush_hash_range;
++	htab_finish_init();
++}
+diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/hash_utils_64.c
+@@ -0,0 +1,459 @@
++/*
++ * PowerPC64 port by Mike Corrigan and Dave Engebretsen
++ *   {mikejc|engebret}@us.ibm.com
++ *
++ *    Copyright (c) 2000 Mike Corrigan <mikejc at us.ibm.com>
++ *
++ * SMP scalability work:
++ *    Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, IBM
++ * 
++ *    Module name: htab.c
++ *
++ *    Description:
++ *      PowerPC Hashed Page Table 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.
++ */
++
++#undef DEBUG
++
++#include <linux/config.h>
++#include <linux/spinlock.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/proc_fs.h>
++#include <linux/stat.h>
++#include <linux/sysctl.h>
++#include <linux/ctype.h>
++#include <linux/cache.h>
++#include <linux/init.h>
++#include <linux/signal.h>
++
++#include <asm/ppcdebug.h>
++#include <asm/processor.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/mmu_context.h>
++#include <asm/page.h>
++#include <asm/types.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++#include <asm/machdep.h>
++#include <asm/lmb.h>
++#include <asm/abs_addr.h>
++#include <asm/tlbflush.h>
++#include <asm/io.h>
++#include <asm/eeh.h>
++#include <asm/tlb.h>
++#include <asm/cacheflush.h>
++#include <asm/cputable.h>
++#include <asm/abs_addr.h>
++#include <asm/sections.h>
++
++#ifdef DEBUG
++#define DBG(fmt...) udbg_printf(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++/*
++ * Note:  pte   --> Linux PTE
++ *        HPTE  --> PowerPC Hashed Page Table Entry
++ *
++ * Execution context:
++ *   htab_initialize is called with the MMU off (of course), but
++ *   the kernel has been copied down to zero so it can directly
++ *   reference global data.  At this point it is very difficult
++ *   to print debug info.
++ *
++ */
++
++#ifdef CONFIG_U3_DART
++extern unsigned long dart_tablebase;
++#endif /* CONFIG_U3_DART */
++
++hpte_t *htab_address;
++unsigned long htab_hash_mask;
++
++unsigned long _SDR1;
++
++#define KB (1024)
++#define MB (1024*KB)
++
++static inline void loop_forever(void)
++{
++	volatile unsigned long x = 1;
++	for(;x;x|=1)
++		;
++}
++
++static inline void create_pte_mapping(unsigned long start, unsigned long end,
++				      unsigned long mode, int large)
++{
++	unsigned long addr;
++	unsigned int step;
++	unsigned long tmp_mode;
++	unsigned long vflags;
++
++	if (large) {
++		step = 16*MB;
++		vflags = HPTE_V_BOLTED | HPTE_V_LARGE;
++	} else {
++		step = 4*KB;
++		vflags = HPTE_V_BOLTED;
++	}
++
++	for (addr = start; addr < end; addr += step) {
++		unsigned long vpn, hash, hpteg;
++		unsigned long vsid = get_kernel_vsid(addr);
++		unsigned long va = (vsid << 28) | (addr & 0xfffffff);
++		int ret = -1;
++
++		if (large)
++			vpn = va >> HPAGE_SHIFT;
++		else
++			vpn = va >> PAGE_SHIFT;
++
++
++		tmp_mode = mode;
++		
++		/* Make non-kernel text non-executable */
++		if (!in_kernel_text(addr))
++			tmp_mode = mode | HW_NO_EXEC;
++
++		hash = hpt_hash(vpn, large);
++
++		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
++
++#ifdef CONFIG_PPC_ISERIES
++		if (systemcfg->platform & PLATFORM_ISERIES_LPAR)
++			ret = iSeries_hpte_bolt_or_insert(hpteg, va,
++				virt_to_abs(addr) >> PAGE_SHIFT,
++				vflags, tmp_mode);
++		else
++#endif
++#ifdef CONFIG_PPC_PSERIES
++		if (systemcfg->platform & PLATFORM_LPAR)
++			ret = pSeries_lpar_hpte_insert(hpteg, va,
++				virt_to_abs(addr) >> PAGE_SHIFT,
++				vflags, tmp_mode);
++		else
++#endif
++#ifdef CONFIG_PPC_MULTIPLATFORM
++			ret = native_hpte_insert(hpteg, va,
++				virt_to_abs(addr) >> PAGE_SHIFT,
++				vflags, tmp_mode);
++#endif
++
++		if (ret == -1) {
++			ppc64_terminate_msg(0x20, "create_pte_mapping");
++			loop_forever();
++		}
++	}
++}
++
++static unsigned long get_hashtable_size(void)
++{
++	unsigned long rnd_mem_size, pteg_count;
++
++	/* If hash size wasn't obtained in prom.c, we calculate it now based on
++	 * the total RAM size
++	 */
++	if (ppc64_pft_size)
++		return 1UL << ppc64_pft_size;
++
++	/* round mem_size up to next power of 2 */
++	rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize);
++	if (rnd_mem_size < systemcfg->physicalMemorySize)
++		rnd_mem_size <<= 1;
++
++	/* # pages / 2 */
++	pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
++
++	return pteg_count << 7;
++}
++
++void __init htab_initialize(void)
++{
++	unsigned long table, htab_size_bytes;
++	unsigned long pteg_count;
++	unsigned long mode_rw;
++	int i, use_largepages = 0;
++	unsigned long base = 0, size = 0;
++	extern unsigned long tce_alloc_start, tce_alloc_end;
++
++	DBG(" -> htab_initialize()\n");
++
++	/*
++	 * Calculate the required size of the htab.  We want the number of
++	 * PTEGs to equal one half the number of real pages.
++	 */ 
++	htab_size_bytes = get_hashtable_size();
++	pteg_count = htab_size_bytes >> 7;
++
++	/* For debug, make the HTAB 1/8 as big as it normally would be. */
++	ifppcdebug(PPCDBG_HTABSIZE) {
++		pteg_count >>= 3;
++		htab_size_bytes = pteg_count << 7;
++	}
++
++	htab_hash_mask = pteg_count - 1;
++
++	if (systemcfg->platform & PLATFORM_LPAR) {
++		/* Using a hypervisor which owns the htab */
++		htab_address = NULL;
++		_SDR1 = 0; 
++	} else {
++		/* Find storage for the HPT.  Must be contiguous in
++		 * the absolute address space.
++		 */
++		table = lmb_alloc(htab_size_bytes, htab_size_bytes);
++
++		DBG("Hash table allocated at %lx, size: %lx\n", table,
++		    htab_size_bytes);
++
++		if ( !table ) {
++			ppc64_terminate_msg(0x20, "hpt space");
++			loop_forever();
++		}
++		htab_address = abs_to_virt(table);
++
++		/* htab absolute addr + encoded htabsize */
++		_SDR1 = table + __ilog2(pteg_count) - 11;
++
++		/* Initialize the HPT with no entries */
++		memset((void *)table, 0, htab_size_bytes);
++	}
++
++	mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
++
++	/* On U3 based machines, we need to reserve the DART area and
++	 * _NOT_ map it to avoid cache paradoxes as it's remapped non
++	 * cacheable later on
++	 */
++	if (cpu_has_feature(CPU_FTR_16M_PAGE))
++		use_largepages = 1;
++
++	/* create bolted the linear mapping in the hash table */
++	for (i=0; i < lmb.memory.cnt; i++) {
++		base = lmb.memory.region[i].base + KERNELBASE;
++		size = lmb.memory.region[i].size;
++
++		DBG("creating mapping for region: %lx : %lx\n", base, size);
++
++#ifdef CONFIG_U3_DART
++		/* Do not map the DART space. Fortunately, it will be aligned
++		 * in such a way that it will not cross two lmb regions and will
++		 * fit within a single 16Mb page.
++		 * The DART space is assumed to be a full 16Mb region even if we
++		 * only use 2Mb of that space. We will use more of it later for
++		 * AGP GART. We have to use a full 16Mb large page.
++		 */
++		DBG("DART base: %lx\n", dart_tablebase);
++
++		if (dart_tablebase != 0 && dart_tablebase >= base
++		    && dart_tablebase < (base + size)) {
++			if (base != dart_tablebase)
++				create_pte_mapping(base, dart_tablebase, mode_rw,
++						   use_largepages);
++			if ((base + size) > (dart_tablebase + 16*MB))
++				create_pte_mapping(dart_tablebase + 16*MB, base + size,
++						   mode_rw, use_largepages);
++			continue;
++		}
++#endif /* CONFIG_U3_DART */
++		create_pte_mapping(base, base + size, mode_rw, use_largepages);
++	}
++
++	/*
++	 * If we have a memory_limit and we've allocated TCEs then we need to
++	 * explicitly map the TCE area at the top of RAM. We also cope with the
++	 * case that the TCEs start below memory_limit.
++	 * tce_alloc_start/end are 16MB aligned so the mapping should work
++	 * for either 4K or 16MB pages.
++	 */
++	if (tce_alloc_start) {
++		tce_alloc_start += KERNELBASE;
++		tce_alloc_end += KERNELBASE;
++
++		if (base + size >= tce_alloc_start)
++			tce_alloc_start = base + size + 1;
++
++		create_pte_mapping(tce_alloc_start, tce_alloc_end,
++			mode_rw, use_largepages);
++	}
++
++	DBG(" <- htab_initialize()\n");
++}
++#undef KB
++#undef MB
++
++/*
++ * Called by asm hashtable.S for doing lazy icache flush
++ */
++unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
++{
++	struct page *page;
++
++	if (!pfn_valid(pte_pfn(pte)))
++		return pp;
++
++	page = pte_page(pte);
++
++	/* page is dirty */
++	if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
++		if (trap == 0x400) {
++			__flush_dcache_icache(page_address(page));
++			set_bit(PG_arch_1, &page->flags);
++		} else
++			pp |= HW_NO_EXEC;
++	}
++	return pp;
++}
++
++/* Result code is:
++ *  0 - handled
++ *  1 - normal page fault
++ * -1 - critical hash insertion error
++ */
++int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
++{
++	void *pgdir;
++	unsigned long vsid;
++	struct mm_struct *mm;
++	pte_t *ptep;
++	int ret;
++	int user_region = 0;
++	int local = 0;
++	cpumask_t tmp;
++
++	if ((ea & ~REGION_MASK) >= PGTABLE_RANGE)
++		return 1;
++
++ 	switch (REGION_ID(ea)) {
++	case USER_REGION_ID:
++		user_region = 1;
++		mm = current->mm;
++		if (! mm)
++			return 1;
++
++		vsid = get_vsid(mm->context.id, ea);
++		break;
++	case VMALLOC_REGION_ID:
++		mm = &init_mm;
++		vsid = get_kernel_vsid(ea);
++		break;
++#if 0
++	case KERNEL_REGION_ID:
++		/*
++		 * Should never get here - entire 0xC0... region is bolted.
++		 * Send the problem up to do_page_fault 
++		 */
++#endif
++	default:
++		/* Not a valid range
++		 * Send the problem up to do_page_fault 
++		 */
++		return 1;
++		break;
++	}
++
++	pgdir = mm->pgd;
++
++	if (pgdir == NULL)
++		return 1;
++
++	tmp = cpumask_of_cpu(smp_processor_id());
++	if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
++		local = 1;
++
++	/* Is this a huge page ? */
++	if (unlikely(in_hugepage_area(mm->context, ea)))
++		ret = hash_huge_page(mm, access, ea, vsid, local);
++	else {
++		ptep = find_linux_pte(pgdir, ea);
++		if (ptep == NULL)
++			return 1;
++		ret = __hash_page(ea, access, vsid, ptep, trap, local);
++	}
++
++	return ret;
++}
++
++void flush_hash_page(unsigned long va, pte_t pte, int local)
++{
++	unsigned long vpn, hash, secondary, slot;
++	unsigned long huge = pte_huge(pte);
++
++	if (huge)
++		vpn = va >> HPAGE_SHIFT;
++	else
++		vpn = va >> PAGE_SHIFT;
++	hash = hpt_hash(vpn, huge);
++	secondary = (pte_val(pte) & _PAGE_SECONDARY) >> 15;
++	if (secondary)
++		hash = ~hash;
++	slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
++	slot += (pte_val(pte) & _PAGE_GROUP_IX) >> 12;
++
++	ppc_md.hpte_invalidate(slot, va, huge, local);
++}
++
++void flush_hash_range(unsigned long number, int local)
++{
++	if (ppc_md.flush_hash_range) {
++		ppc_md.flush_hash_range(number, local);
++	} else {
++		int i;
++		struct ppc64_tlb_batch *batch =
++			&__get_cpu_var(ppc64_tlb_batch);
++
++		for (i = 0; i < number; i++)
++			flush_hash_page(batch->vaddr[i], batch->pte[i], local);
++	}
++}
++
++static inline void make_bl(unsigned int *insn_addr, void *func)
++{
++	unsigned long funcp = *((unsigned long *)func);
++	int offset = funcp - (unsigned long)insn_addr;
++
++	*insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
++	flush_icache_range((unsigned long)insn_addr, 4+
++			   (unsigned long)insn_addr);
++}
++
++/*
++ * low_hash_fault is called when we the low level hash code failed
++ * to instert a PTE due to an hypervisor error
++ */
++void low_hash_fault(struct pt_regs *regs, unsigned long address)
++{
++	if (user_mode(regs)) {
++		siginfo_t info;
++
++		info.si_signo = SIGBUS;
++		info.si_errno = 0;
++		info.si_code = BUS_ADRERR;
++		info.si_addr = (void __user *)address;
++		force_sig_info(SIGBUS, &info, current);
++		return;
++	}
++	bad_page_fault(regs, address, SIGBUS);
++}
++
++void __init htab_finish_init(void)
++{
++	extern unsigned int *htab_call_hpte_insert1;
++	extern unsigned int *htab_call_hpte_insert2;
++	extern unsigned int *htab_call_hpte_remove;
++	extern unsigned int *htab_call_hpte_updatepp;
++
++	make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
++	make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
++	make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
++	make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
++}
+diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/hugetlbpage.c
+@@ -0,0 +1,745 @@
++/*
++ * PPC64 (POWER4) Huge TLB Page Support for Kernel.
++ *
++ * Copyright (C) 2003 David Gibson, IBM Corporation.
++ *
++ * Based on the IA-32 version:
++ * Copyright (C) 2002, Rohit Seth <rohit.seth at intel.com>
++ */
++
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/mm.h>
++#include <linux/hugetlb.h>
++#include <linux/pagemap.h>
++#include <linux/smp_lock.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++#include <linux/sysctl.h>
++#include <asm/mman.h>
++#include <asm/pgalloc.h>
++#include <asm/tlb.h>
++#include <asm/tlbflush.h>
++#include <asm/mmu_context.h>
++#include <asm/machdep.h>
++#include <asm/cputable.h>
++#include <asm/tlb.h>
++
++#include <linux/sysctl.h>
++
++#define NUM_LOW_AREAS	(0x100000000UL >> SID_SHIFT)
++#define NUM_HIGH_AREAS	(PGTABLE_RANGE >> HTLB_AREA_SHIFT)
++
++/* Modelled after find_linux_pte() */
++pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
++{
++	pgd_t *pg;
++	pud_t *pu;
++	pmd_t *pm;
++	pte_t *pt;
++
++	BUG_ON(! in_hugepage_area(mm->context, addr));
++
++	addr &= HPAGE_MASK;
++
++	pg = pgd_offset(mm, addr);
++	if (!pgd_none(*pg)) {
++		pu = pud_offset(pg, addr);
++		if (!pud_none(*pu)) {
++			pm = pmd_offset(pu, addr);
++			pt = (pte_t *)pm;
++			BUG_ON(!pmd_none(*pm)
++			       && !(pte_present(*pt) && pte_huge(*pt)));
++			return pt;
++		}
++	}
++
++	return NULL;
++}
++
++pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
++{
++	pgd_t *pg;
++	pud_t *pu;
++	pmd_t *pm;
++	pte_t *pt;
++
++	BUG_ON(! in_hugepage_area(mm->context, addr));
++
++	addr &= HPAGE_MASK;
++
++	pg = pgd_offset(mm, addr);
++	pu = pud_alloc(mm, pg, addr);
++
++	if (pu) {
++		pm = pmd_alloc(mm, pu, addr);
++		if (pm) {
++			pt = (pte_t *)pm;
++			BUG_ON(!pmd_none(*pm)
++			       && !(pte_present(*pt) && pte_huge(*pt)));
++			return pt;
++		}
++	}
++
++	return NULL;
++}
++
++#define HUGEPTE_BATCH_SIZE	(HPAGE_SIZE / PMD_SIZE)
++
++void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
++		     pte_t *ptep, pte_t pte)
++{
++	int i;
++
++	if (pte_present(*ptep)) {
++		pte_clear(mm, addr, ptep);
++		flush_tlb_pending();
++	}
++
++	for (i = 0; i < HUGEPTE_BATCH_SIZE; i++) {
++		*ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
++		ptep++;
++	}
++}
++
++pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
++			      pte_t *ptep)
++{
++	unsigned long old = pte_update(ptep, ~0UL);
++	int i;
++
++	if (old & _PAGE_HASHPTE)
++		hpte_update(mm, addr, old, 0);
++
++	for (i = 1; i < HUGEPTE_BATCH_SIZE; i++)
++		ptep[i] = __pte(0);
++
++	return __pte(old);
++}
++
++/*
++ * This function checks for proper alignment of input addr and len parameters.
++ */
++int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
++{
++	if (len & ~HPAGE_MASK)
++		return -EINVAL;
++	if (addr & ~HPAGE_MASK)
++		return -EINVAL;
++	if (! (within_hugepage_low_range(addr, len)
++	       || within_hugepage_high_range(addr, len)) )
++		return -EINVAL;
++	return 0;
++}
++
++static void flush_low_segments(void *parm)
++{
++	u16 areas = (unsigned long) parm;
++	unsigned long i;
++
++	asm volatile("isync" : : : "memory");
++
++	BUILD_BUG_ON((sizeof(areas)*8) != NUM_LOW_AREAS);
++
++	for (i = 0; i < NUM_LOW_AREAS; i++) {
++		if (! (areas & (1U << i)))
++			continue;
++		asm volatile("slbie %0"
++			     : : "r" ((i << SID_SHIFT) | SLBIE_C));
++	}
++
++	asm volatile("isync" : : : "memory");
++}
++
++static void flush_high_segments(void *parm)
++{
++	u16 areas = (unsigned long) parm;
++	unsigned long i, j;
++
++	asm volatile("isync" : : : "memory");
++
++	BUILD_BUG_ON((sizeof(areas)*8) != NUM_HIGH_AREAS);
++
++	for (i = 0; i < NUM_HIGH_AREAS; i++) {
++		if (! (areas & (1U << i)))
++			continue;
++		for (j = 0; j < (1UL << (HTLB_AREA_SHIFT-SID_SHIFT)); j++)
++			asm volatile("slbie %0"
++				     :: "r" (((i << HTLB_AREA_SHIFT)
++					     + (j << SID_SHIFT)) | SLBIE_C));
++	}
++
++	asm volatile("isync" : : : "memory");
++}
++
++static int prepare_low_area_for_htlb(struct mm_struct *mm, unsigned long area)
++{
++	unsigned long start = area << SID_SHIFT;
++	unsigned long end = (area+1) << SID_SHIFT;
++	struct vm_area_struct *vma;
++
++	BUG_ON(area >= NUM_LOW_AREAS);
++
++	/* Check no VMAs are in the region */
++	vma = find_vma(mm, start);
++	if (vma && (vma->vm_start < end))
++		return -EBUSY;
++
++	return 0;
++}
++
++static int prepare_high_area_for_htlb(struct mm_struct *mm, unsigned long area)
++{
++	unsigned long start = area << HTLB_AREA_SHIFT;
++	unsigned long end = (area+1) << HTLB_AREA_SHIFT;
++	struct vm_area_struct *vma;
++
++	BUG_ON(area >= NUM_HIGH_AREAS);
++
++	/* Check no VMAs are in the region */
++	vma = find_vma(mm, start);
++	if (vma && (vma->vm_start < end))
++		return -EBUSY;
++
++	return 0;
++}
++
++static int open_low_hpage_areas(struct mm_struct *mm, u16 newareas)
++{
++	unsigned long i;
++
++	BUILD_BUG_ON((sizeof(newareas)*8) != NUM_LOW_AREAS);
++	BUILD_BUG_ON((sizeof(mm->context.low_htlb_areas)*8) != NUM_LOW_AREAS);
++
++	newareas &= ~(mm->context.low_htlb_areas);
++	if (! newareas)
++		return 0; /* The segments we want are already open */
++
++	for (i = 0; i < NUM_LOW_AREAS; i++)
++		if ((1 << i) & newareas)
++			if (prepare_low_area_for_htlb(mm, i) != 0)
++				return -EBUSY;
++
++	mm->context.low_htlb_areas |= newareas;
++
++	/* update the paca copy of the context struct */
++	get_paca()->context = mm->context;
++
++	/* the context change must make it to memory before the flush,
++	 * so that further SLB misses do the right thing. */
++	mb();
++	on_each_cpu(flush_low_segments, (void *)(unsigned long)newareas, 0, 1);
++
++	return 0;
++}
++
++static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas)
++{
++	unsigned long i;
++
++	BUILD_BUG_ON((sizeof(newareas)*8) != NUM_HIGH_AREAS);
++	BUILD_BUG_ON((sizeof(mm->context.high_htlb_areas)*8)
++		     != NUM_HIGH_AREAS);
++
++	newareas &= ~(mm->context.high_htlb_areas);
++	if (! newareas)
++		return 0; /* The areas we want are already open */
++
++	for (i = 0; i < NUM_HIGH_AREAS; i++)
++		if ((1 << i) & newareas)
++			if (prepare_high_area_for_htlb(mm, i) != 0)
++				return -EBUSY;
++
++	mm->context.high_htlb_areas |= newareas;
++
++	/* update the paca copy of the context struct */
++	get_paca()->context = mm->context;
++
++	/* the context change must make it to memory before the flush,
++	 * so that further SLB misses do the right thing. */
++	mb();
++	on_each_cpu(flush_high_segments, (void *)(unsigned long)newareas, 0, 1);
++
++	return 0;
++}
++
++int prepare_hugepage_range(unsigned long addr, unsigned long len)
++{
++	int err;
++
++	if ( (addr+len) < addr )
++		return -EINVAL;
++
++	if ((addr + len) < 0x100000000UL)
++		err = open_low_hpage_areas(current->mm,
++					  LOW_ESID_MASK(addr, len));
++	else
++		err = open_high_hpage_areas(current->mm,
++					    HTLB_AREA_MASK(addr, len));
++	if (err) {
++		printk(KERN_DEBUG "prepare_hugepage_range(%lx, %lx)"
++		       " failed (lowmask: 0x%04hx, highmask: 0x%04hx)\n",
++		       addr, len,
++		       LOW_ESID_MASK(addr, len), HTLB_AREA_MASK(addr, len));
++		return err;
++	}
++
++	return 0;
++}
++
++struct page *
++follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
++{
++	pte_t *ptep;
++	struct page *page;
++
++	if (! in_hugepage_area(mm->context, address))
++		return ERR_PTR(-EINVAL);
++
++	ptep = huge_pte_offset(mm, address);
++	page = pte_page(*ptep);
++	if (page)
++		page += (address % HPAGE_SIZE) / PAGE_SIZE;
++
++	return page;
++}
++
++int pmd_huge(pmd_t pmd)
++{
++	return 0;
++}
++
++struct page *
++follow_huge_pmd(struct mm_struct *mm, unsigned long address,
++		pmd_t *pmd, int write)
++{
++	BUG();
++	return NULL;
++}
++
++/* Because we have an exclusive hugepage region which lies within the
++ * normal user address space, we have to take special measures to make
++ * non-huge mmap()s evade the hugepage reserved regions. */
++unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
++				     unsigned long len, unsigned long pgoff,
++				     unsigned long flags)
++{
++	struct mm_struct *mm = current->mm;
++	struct vm_area_struct *vma;
++	unsigned long start_addr;
++
++	if (len > TASK_SIZE)
++		return -ENOMEM;
++
++	if (addr) {
++		addr = PAGE_ALIGN(addr);
++		vma = find_vma(mm, addr);
++		if (((TASK_SIZE - len) >= addr)
++		    && (!vma || (addr+len) <= vma->vm_start)
++		    && !is_hugepage_only_range(mm, addr,len))
++			return addr;
++	}
++	if (len > mm->cached_hole_size) {
++	        start_addr = addr = mm->free_area_cache;
++	} else {
++	        start_addr = addr = TASK_UNMAPPED_BASE;
++	        mm->cached_hole_size = 0;
++	}
++
++full_search:
++	vma = find_vma(mm, addr);
++	while (TASK_SIZE - len >= addr) {
++		BUG_ON(vma && (addr >= vma->vm_end));
++
++		if (touches_hugepage_low_range(mm, addr, len)) {
++			addr = ALIGN(addr+1, 1<<SID_SHIFT);
++			vma = find_vma(mm, addr);
++			continue;
++		}
++		if (touches_hugepage_high_range(mm, addr, len)) {
++			addr = ALIGN(addr+1, 1UL<<HTLB_AREA_SHIFT);
++			vma = find_vma(mm, addr);
++			continue;
++		}
++		if (!vma || addr + len <= vma->vm_start) {
++			/*
++			 * Remember the place where we stopped the search:
++			 */
++			mm->free_area_cache = addr + len;
++			return addr;
++		}
++		if (addr + mm->cached_hole_size < vma->vm_start)
++		        mm->cached_hole_size = vma->vm_start - addr;
++		addr = vma->vm_end;
++		vma = vma->vm_next;
++	}
++
++	/* Make sure we didn't miss any holes */
++	if (start_addr != TASK_UNMAPPED_BASE) {
++		start_addr = addr = TASK_UNMAPPED_BASE;
++		mm->cached_hole_size = 0;
++		goto full_search;
++	}
++	return -ENOMEM;
++}
++
++/*
++ * This mmap-allocator allocates new areas top-down from below the
++ * stack's low limit (the base):
++ *
++ * Because we have an exclusive hugepage region which lies within the
++ * normal user address space, we have to take special measures to make
++ * non-huge mmap()s evade the hugepage reserved regions.
++ */
++unsigned long
++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
++			  const unsigned long len, const unsigned long pgoff,
++			  const unsigned long flags)
++{
++	struct vm_area_struct *vma, *prev_vma;
++	struct mm_struct *mm = current->mm;
++	unsigned long base = mm->mmap_base, addr = addr0;
++	unsigned long largest_hole = mm->cached_hole_size;
++	int first_time = 1;
++
++	/* requested length too big for entire address space */
++	if (len > TASK_SIZE)
++		return -ENOMEM;
++
++	/* dont allow allocations above current base */
++	if (mm->free_area_cache > base)
++		mm->free_area_cache = base;
++
++	/* requesting a specific address */
++	if (addr) {
++		addr = PAGE_ALIGN(addr);
++		vma = find_vma(mm, addr);
++		if (TASK_SIZE - len >= addr &&
++				(!vma || addr + len <= vma->vm_start)
++				&& !is_hugepage_only_range(mm, addr,len))
++			return addr;
++	}
++
++	if (len <= largest_hole) {
++	        largest_hole = 0;
++		mm->free_area_cache = base;
++	}
++try_again:
++	/* make sure it can fit in the remaining address space */
++	if (mm->free_area_cache < len)
++		goto fail;
++
++	/* either no address requested or cant fit in requested address hole */
++	addr = (mm->free_area_cache - len) & PAGE_MASK;
++	do {
++hugepage_recheck:
++		if (touches_hugepage_low_range(mm, addr, len)) {
++			addr = (addr & ((~0) << SID_SHIFT)) - len;
++			goto hugepage_recheck;
++		} else if (touches_hugepage_high_range(mm, addr, len)) {
++			addr = (addr & ((~0UL) << HTLB_AREA_SHIFT)) - len;
++			goto hugepage_recheck;
++		}
++
++		/*
++		 * Lookup failure means no vma is above this address,
++		 * i.e. return with success:
++		 */
++ 	 	if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
++			return addr;
++
++		/*
++		 * new region fits between prev_vma->vm_end and
++		 * vma->vm_start, use it:
++		 */
++		if (addr+len <= vma->vm_start &&
++		          (!prev_vma || (addr >= prev_vma->vm_end))) {
++			/* remember the address as a hint for next time */
++		        mm->cached_hole_size = largest_hole;
++		        return (mm->free_area_cache = addr);
++		} else {
++			/* pull free_area_cache down to the first hole */
++		        if (mm->free_area_cache == vma->vm_end) {
++				mm->free_area_cache = vma->vm_start;
++				mm->cached_hole_size = largest_hole;
++			}
++		}
++
++		/* remember the largest hole we saw so far */
++		if (addr + largest_hole < vma->vm_start)
++		        largest_hole = vma->vm_start - addr;
++
++		/* try just below the current vma->vm_start */
++		addr = vma->vm_start-len;
++	} while (len <= vma->vm_start);
++
++fail:
++	/*
++	 * if hint left us with no space for the requested
++	 * mapping then try again:
++	 */
++	if (first_time) {
++		mm->free_area_cache = base;
++		largest_hole = 0;
++		first_time = 0;
++		goto try_again;
++	}
++	/*
++	 * A failed mmap() very likely causes application failure,
++	 * so fall back to the bottom-up function here. This scenario
++	 * can happen with large stack limits and large mmap()
++	 * allocations.
++	 */
++	mm->free_area_cache = TASK_UNMAPPED_BASE;
++	mm->cached_hole_size = ~0UL;
++	addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
++	/*
++	 * Restore the topdown base:
++	 */
++	mm->free_area_cache = base;
++	mm->cached_hole_size = ~0UL;
++
++	return addr;
++}
++
++static unsigned long htlb_get_low_area(unsigned long len, u16 segmask)
++{
++	unsigned long addr = 0;
++	struct vm_area_struct *vma;
++
++	vma = find_vma(current->mm, addr);
++	while (addr + len <= 0x100000000UL) {
++		BUG_ON(vma && (addr >= vma->vm_end)); /* invariant */
++
++		if (! __within_hugepage_low_range(addr, len, segmask)) {
++			addr = ALIGN(addr+1, 1<<SID_SHIFT);
++			vma = find_vma(current->mm, addr);
++			continue;
++		}
++
++		if (!vma || (addr + len) <= vma->vm_start)
++			return addr;
++		addr = ALIGN(vma->vm_end, HPAGE_SIZE);
++		/* Depending on segmask this might not be a confirmed
++		 * hugepage region, so the ALIGN could have skipped
++		 * some VMAs */
++		vma = find_vma(current->mm, addr);
++	}
++
++	return -ENOMEM;
++}
++
++static unsigned long htlb_get_high_area(unsigned long len, u16 areamask)
++{
++	unsigned long addr = 0x100000000UL;
++	struct vm_area_struct *vma;
++
++	vma = find_vma(current->mm, addr);
++	while (addr + len <= TASK_SIZE_USER64) {
++		BUG_ON(vma && (addr >= vma->vm_end)); /* invariant */
++
++		if (! __within_hugepage_high_range(addr, len, areamask)) {
++			addr = ALIGN(addr+1, 1UL<<HTLB_AREA_SHIFT);
++			vma = find_vma(current->mm, addr);
++			continue;
++		}
++
++		if (!vma || (addr + len) <= vma->vm_start)
++			return addr;
++		addr = ALIGN(vma->vm_end, HPAGE_SIZE);
++		/* Depending on segmask this might not be a confirmed
++		 * hugepage region, so the ALIGN could have skipped
++		 * some VMAs */
++		vma = find_vma(current->mm, addr);
++	}
++
++	return -ENOMEM;
++}
++
++unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
++					unsigned long len, unsigned long pgoff,
++					unsigned long flags)
++{
++	int lastshift;
++	u16 areamask, curareas;
++
++	if (len & ~HPAGE_MASK)
++		return -EINVAL;
++
++	if (!cpu_has_feature(CPU_FTR_16M_PAGE))
++		return -EINVAL;
++
++	if (test_thread_flag(TIF_32BIT)) {
++		curareas = current->mm->context.low_htlb_areas;
++
++		/* First see if we can do the mapping in the existing
++		 * low areas */
++		addr = htlb_get_low_area(len, curareas);
++		if (addr != -ENOMEM)
++			return addr;
++
++		lastshift = 0;
++		for (areamask = LOW_ESID_MASK(0x100000000UL-len, len);
++		     ! lastshift; areamask >>=1) {
++			if (areamask & 1)
++				lastshift = 1;
++
++			addr = htlb_get_low_area(len, curareas | areamask);
++			if ((addr != -ENOMEM)
++			    && open_low_hpage_areas(current->mm, areamask) == 0)
++				return addr;
++		}
++	} else {
++		curareas = current->mm->context.high_htlb_areas;
++
++		/* First see if we can do the mapping in the existing
++		 * high areas */
++		addr = htlb_get_high_area(len, curareas);
++		if (addr != -ENOMEM)
++			return addr;
++
++		lastshift = 0;
++		for (areamask = HTLB_AREA_MASK(TASK_SIZE_USER64-len, len);
++		     ! lastshift; areamask >>=1) {
++			if (areamask & 1)
++				lastshift = 1;
++
++			addr = htlb_get_high_area(len, curareas | areamask);
++			if ((addr != -ENOMEM)
++			    && open_high_hpage_areas(current->mm, areamask) == 0)
++				return addr;
++		}
++	}
++	printk(KERN_DEBUG "hugetlb_get_unmapped_area() unable to open"
++	       " enough areas\n");
++	return -ENOMEM;
++}
++
++int hash_huge_page(struct mm_struct *mm, unsigned long access,
++		   unsigned long ea, unsigned long vsid, int local)
++{
++	pte_t *ptep;
++	unsigned long va, vpn;
++	pte_t old_pte, new_pte;
++	unsigned long rflags, prpn;
++	long slot;
++	int err = 1;
++
++	spin_lock(&mm->page_table_lock);
++
++	ptep = huge_pte_offset(mm, ea);
++
++	/* Search the Linux page table for a match with va */
++	va = (vsid << 28) | (ea & 0x0fffffff);
++	vpn = va >> HPAGE_SHIFT;
++
++	/*
++	 * If no pte found or not present, send the problem up to
++	 * do_page_fault
++	 */
++	if (unlikely(!ptep || pte_none(*ptep)))
++		goto out;
++
++/* 	BUG_ON(pte_bad(*ptep)); */
++
++	/* 
++	 * Check the user's access rights to the page.  If access should be
++	 * prevented then send the problem up to do_page_fault.
++	 */
++	if (unlikely(access & ~pte_val(*ptep)))
++		goto out;
++	/*
++	 * At this point, we have a pte (old_pte) which can be used to build
++	 * or update an HPTE. There are 2 cases:
++	 *
++	 * 1. There is a valid (present) pte with no associated HPTE (this is 
++	 *	the most common case)
++	 * 2. There is a valid (present) pte with an associated HPTE. The
++	 *	current values of the pp bits in the HPTE prevent access
++	 *	because we are doing software DIRTY bit management and the
++	 *	page is currently not DIRTY. 
++	 */
++
++
++	old_pte = *ptep;
++	new_pte = old_pte;
++
++	rflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW));
++ 	/* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */
++	rflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC);
++
++	/* Check if pte already has an hpte (case 2) */
++	if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) {
++		/* There MIGHT be an HPTE for this pte */
++		unsigned long hash, slot;
++
++		hash = hpt_hash(vpn, 1);
++		if (pte_val(old_pte) & _PAGE_SECONDARY)
++			hash = ~hash;
++		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
++		slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12;
++
++		if (ppc_md.hpte_updatepp(slot, rflags, va, 1, local) == -1)
++			pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;
++	}
++
++	if (likely(!(pte_val(old_pte) & _PAGE_HASHPTE))) {
++		unsigned long hash = hpt_hash(vpn, 1);
++		unsigned long hpte_group;
++
++		prpn = pte_pfn(old_pte);
++
++repeat:
++		hpte_group = ((hash & htab_hash_mask) *
++			      HPTES_PER_GROUP) & ~0x7UL;
++
++		/* Update the linux pte with the HPTE slot */
++		pte_val(new_pte) &= ~_PAGE_HPTEFLAGS;
++		pte_val(new_pte) |= _PAGE_HASHPTE;
++
++		/* Add in WIMG bits */
++		/* XXX We should store these in the pte */
++		rflags |= _PAGE_COHERENT;
++
++		slot = ppc_md.hpte_insert(hpte_group, va, prpn,
++					  HPTE_V_LARGE, rflags);
++
++		/* Primary is full, try the secondary */
++		if (unlikely(slot == -1)) {
++			pte_val(new_pte) |= _PAGE_SECONDARY;
++			hpte_group = ((~hash & htab_hash_mask) *
++				      HPTES_PER_GROUP) & ~0x7UL; 
++			slot = ppc_md.hpte_insert(hpte_group, va, prpn,
++						  HPTE_V_LARGE |
++						  HPTE_V_SECONDARY,
++						  rflags);
++			if (slot == -1) {
++				if (mftb() & 0x1)
++					hpte_group = ((hash & htab_hash_mask) *
++						      HPTES_PER_GROUP)&~0x7UL;
++
++				ppc_md.hpte_remove(hpte_group);
++				goto repeat;
++                        }
++		}
++
++		if (unlikely(slot == -2))
++			panic("hash_huge_page: pte_insert failed\n");
++
++		pte_val(new_pte) |= (slot<<12) & _PAGE_GROUP_IX;
++
++		/* 
++		 * No need to use ldarx/stdcx here because all who
++		 * might be updating the pte will hold the
++		 * page_table_lock
++		 */
++		*ptep = new_pte;
++	}
++
++	err = 0;
++
++ out:
++	spin_unlock(&mm->page_table_lock);
++
++	return err;
++}
+diff --git a/arch/powerpc/mm/imalloc.c b/arch/powerpc/mm/imalloc.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/imalloc.c
+@@ -0,0 +1,312 @@
++/*
++ * c 2001 PPC 64 Team, IBM Corp
++ * 
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ */
++
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++
++#include <asm/uaccess.h>
++#include <asm/pgalloc.h>
++#include <asm/pgtable.h>
++#include <asm/semaphore.h>
++#include <asm/imalloc.h>
++#include <asm/cacheflush.h>
++
++static DECLARE_MUTEX(imlist_sem);
++struct vm_struct * imlist = NULL;
++
++static int get_free_im_addr(unsigned long size, unsigned long *im_addr)
++{
++	unsigned long addr;
++	struct vm_struct **p, *tmp;
++
++	addr = ioremap_bot;
++	for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
++		if (size + addr < (unsigned long) tmp->addr)
++			break;
++		if ((unsigned long)tmp->addr >= ioremap_bot)
++			addr = tmp->size + (unsigned long) tmp->addr;
++		if (addr >= IMALLOC_END-size)
++			return 1;
++	}
++	*im_addr = addr;
++
++	return 0;
++}
++
++/* Return whether the region described by v_addr and size is a subset
++ * of the region described by parent
++ */
++static inline int im_region_is_subset(unsigned long v_addr, unsigned long size,
++			struct vm_struct *parent)
++{
++	return (int) (v_addr >= (unsigned long) parent->addr &&
++	              v_addr < (unsigned long) parent->addr + parent->size &&
++	    	      size < parent->size);
++}
++
++/* Return whether the region described by v_addr and size is a superset
++ * of the region described by child
++ */
++static int im_region_is_superset(unsigned long v_addr, unsigned long size,
++		struct vm_struct *child)
++{
++	struct vm_struct parent;
++
++	parent.addr = (void *) v_addr;
++	parent.size = size;
++
++	return im_region_is_subset((unsigned long) child->addr, child->size,
++			&parent);
++}
++
++/* Return whether the region described by v_addr and size overlaps
++ * the region described by vm.  Overlapping regions meet the
++ * following conditions:
++ * 1) The regions share some part of the address space
++ * 2) The regions aren't identical
++ * 3) Neither region is a subset of the other
++ */
++static int im_region_overlaps(unsigned long v_addr, unsigned long size,
++		     struct vm_struct *vm)
++{
++	if (im_region_is_superset(v_addr, size, vm))
++		return 0;
++
++	return (v_addr + size > (unsigned long) vm->addr + vm->size &&
++		v_addr < (unsigned long) vm->addr + vm->size) ||
++	       (v_addr < (unsigned long) vm->addr &&
++		v_addr + size > (unsigned long) vm->addr);
++}
++
++/* Determine imalloc status of region described by v_addr and size.
++ * Can return one of the following:
++ * IM_REGION_UNUSED   -  Entire region is unallocated in imalloc space.
++ * IM_REGION_SUBSET -    Region is a subset of a region that is already
++ * 			 allocated in imalloc space.
++ * 		         vm will be assigned to a ptr to the parent region.
++ * IM_REGION_EXISTS -    Exact region already allocated in imalloc space.
++ *                       vm will be assigned to a ptr to the existing imlist
++ *                       member.
++ * IM_REGION_OVERLAPS -  Region overlaps an allocated region in imalloc space.
++ * IM_REGION_SUPERSET -  Region is a superset of a region that is already
++ *                       allocated in imalloc space.
++ */
++static int im_region_status(unsigned long v_addr, unsigned long size,
++		    struct vm_struct **vm)
++{
++	struct vm_struct *tmp;
++
++	for (tmp = imlist; tmp; tmp = tmp->next)
++		if (v_addr < (unsigned long) tmp->addr + tmp->size)
++			break;
++
++	if (tmp) {
++		if (im_region_overlaps(v_addr, size, tmp))
++			return IM_REGION_OVERLAP;
++
++		*vm = tmp;
++		if (im_region_is_subset(v_addr, size, tmp)) {
++			/* Return with tmp pointing to superset */
++			return IM_REGION_SUBSET;
++		}
++		if (im_region_is_superset(v_addr, size, tmp)) {
++			/* Return with tmp pointing to first subset */
++			return IM_REGION_SUPERSET;
++		}
++		else if (v_addr == (unsigned long) tmp->addr &&
++		 	 size == tmp->size) {
++			/* Return with tmp pointing to exact region */
++			return IM_REGION_EXISTS;
++		}
++	}
++
++	*vm = NULL;
++	return IM_REGION_UNUSED;
++}
++
++static struct vm_struct * split_im_region(unsigned long v_addr, 
++		unsigned long size, struct vm_struct *parent)
++{
++	struct vm_struct *vm1 = NULL;
++	struct vm_struct *vm2 = NULL;
++	struct vm_struct *new_vm = NULL;
++	
++	vm1 = (struct vm_struct *) kmalloc(sizeof(*vm1), GFP_KERNEL);
++	if (vm1	== NULL) {
++		printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
++		return NULL;
++	}
++
++	if (v_addr == (unsigned long) parent->addr) {
++	        /* Use existing parent vm_struct to represent child, allocate
++		 * new one for the remainder of parent range
++		 */
++		vm1->size = parent->size - size;
++		vm1->addr = (void *) (v_addr + size);
++		vm1->next = parent->next;
++
++		parent->size = size;
++		parent->next = vm1;
++		new_vm = parent;
++	} else if (v_addr + size == (unsigned long) parent->addr + 
++			parent->size) {
++		/* Allocate new vm_struct to represent child, use existing
++		 * parent one for remainder of parent range
++		 */
++		vm1->size = size;
++		vm1->addr = (void *) v_addr;
++		vm1->next = parent->next;
++		new_vm = vm1;
++
++		parent->size -= size;
++		parent->next = vm1;
++	} else {
++	        /* Allocate two new vm_structs for the new child and 
++		 * uppermost remainder, and use existing parent one for the
++		 * lower remainder of parent range
++		 */
++		vm2 = (struct vm_struct *) kmalloc(sizeof(*vm2), GFP_KERNEL);
++		if (vm2 == NULL) {
++			printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
++			kfree(vm1);
++			return NULL;
++		}
++
++		vm1->size = size;
++		vm1->addr = (void *) v_addr;
++		vm1->next = vm2;
++		new_vm = vm1;
++
++		vm2->size = ((unsigned long) parent->addr + parent->size) - 
++				(v_addr + size);
++		vm2->addr = (void *) v_addr + size;
++		vm2->next = parent->next;
++
++		parent->size = v_addr - (unsigned long) parent->addr;
++		parent->next = vm1;
++	}
++
++	return new_vm;
++}
++
++static struct vm_struct * __add_new_im_area(unsigned long req_addr, 
++					    unsigned long size)
++{
++	struct vm_struct **p, *tmp, *area;
++		
++	for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
++		if (req_addr + size <= (unsigned long)tmp->addr)
++			break;
++	}
++	
++	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
++	if (!area)
++		return NULL;
++	area->flags = 0;
++	area->addr = (void *)req_addr;
++	area->size = size;
++	area->next = *p;
++	*p = area;
++
++	return area;
++}
++
++static struct vm_struct * __im_get_area(unsigned long req_addr, 
++					unsigned long size,
++					int criteria)
++{
++	struct vm_struct *tmp;
++	int status;
++
++	status = im_region_status(req_addr, size, &tmp);
++	if ((criteria & status) == 0) {
++		return NULL;
++	}
++	
++	switch (status) {
++	case IM_REGION_UNUSED:
++		tmp = __add_new_im_area(req_addr, size);
++		break;
++	case IM_REGION_SUBSET:
++		tmp = split_im_region(req_addr, size, tmp);
++		break;
++	case IM_REGION_EXISTS:
++		/* Return requested region */
++		break;
++	case IM_REGION_SUPERSET:
++		/* Return first existing subset of requested region */
++		break;
++	default:
++		printk(KERN_ERR "%s() unexpected imalloc region status\n",
++				__FUNCTION__);
++		tmp = NULL;
++	}
++
++	return tmp;
++}
++
++struct vm_struct * im_get_free_area(unsigned long size)
++{
++	struct vm_struct *area;
++	unsigned long addr;
++	
++	down(&imlist_sem);
++	if (get_free_im_addr(size, &addr)) {
++		printk(KERN_ERR "%s() cannot obtain addr for size 0x%lx\n",
++				__FUNCTION__, size);
++		area = NULL;
++		goto next_im_done;
++	}
++
++	area = __im_get_area(addr, size, IM_REGION_UNUSED);
++	if (area == NULL) {
++		printk(KERN_ERR 
++		       "%s() cannot obtain area for addr 0x%lx size 0x%lx\n",
++			__FUNCTION__, addr, size);
++	}
++next_im_done:
++	up(&imlist_sem);
++	return area;
++}
++
++struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
++		int criteria)
++{
++	struct vm_struct *area;
++
++	down(&imlist_sem);
++	area = __im_get_area(v_addr, size, criteria);
++	up(&imlist_sem);
++	return area;
++}
++
++void im_free(void * addr)
++{
++	struct vm_struct **p, *tmp;
++  
++	if (!addr)
++		return;
++	if ((unsigned long) addr & ~PAGE_MASK) {
++		printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__,			addr);
++		return;
++	}
++	down(&imlist_sem);
++	for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
++		if (tmp->addr == addr) {
++			*p = tmp->next;
++			unmap_vm_area(tmp);
++			kfree(tmp);
++			up(&imlist_sem);
++			return;
++		}
++	}
++	up(&imlist_sem);
++	printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__,
++			addr);
++}
+diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/init_32.c
+@@ -0,0 +1,254 @@
++/*
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *  PPC44x/36-bit changes by Matt Porter (mporter at mvista.com)
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/module.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/mm.h>
++#include <linux/stddef.h>
++#include <linux/init.h>
++#include <linux/bootmem.h>
++#include <linux/highmem.h>
++#include <linux/initrd.h>
++#include <linux/pagemap.h>
++
++#include <asm/pgalloc.h>
++#include <asm/prom.h>
++#include <asm/io.h>
++#include <asm/mmu_context.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/smp.h>
++#include <asm/machdep.h>
++#include <asm/btext.h>
++#include <asm/tlb.h>
++#include <asm/prom.h>
++#include <asm/lmb.h>
++#include <asm/sections.h>
++
++#include "mmu_decl.h"
++
++#if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
++/* The ammount of lowmem must be within 0xF0000000 - KERNELBASE. */
++#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - KERNELBASE))
++#error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL"
++#endif
++#endif
++#define MAX_LOW_MEM	CONFIG_LOWMEM_SIZE
++
++DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
++
++unsigned long total_memory;
++unsigned long total_lowmem;
++
++unsigned long ppc_memstart;
++unsigned long ppc_memoffset = PAGE_OFFSET;
++
++int boot_mapsize;
++#ifdef CONFIG_PPC_PMAC
++unsigned long agp_special_page;
++EXPORT_SYMBOL(agp_special_page);
++#endif
++
++#ifdef CONFIG_HIGHMEM
++pte_t *kmap_pte;
++pgprot_t kmap_prot;
++
++EXPORT_SYMBOL(kmap_prot);
++EXPORT_SYMBOL(kmap_pte);
++#endif
++
++void MMU_init(void);
++
++/* XXX should be in current.h  -- paulus */
++extern struct task_struct *current_set[NR_CPUS];
++
++char *klimit = _end;
++struct device_node *memory_node;
++
++extern int init_bootmem_done;
++
++/*
++ * this tells the system to map all of ram with the segregs
++ * (i.e. page tables) instead of the bats.
++ * -- Cort
++ */
++int __map_without_bats;
++int __map_without_ltlbs;
++
++/* max amount of low RAM to map in */
++unsigned long __max_low_memory = MAX_LOW_MEM;
++
++/*
++ * limit of what is accessible with initial MMU setup -
++ * 256MB usually, but only 16MB on 601.
++ */
++unsigned long __initial_memory_limit = 0x10000000;
++
++/*
++ * Check for command-line options that affect what MMU_init will do.
++ */
++void MMU_setup(void)
++{
++	/* Check for nobats option (used in mapin_ram). */
++	if (strstr(cmd_line, "nobats")) {
++		__map_without_bats = 1;
++	}
++
++	if (strstr(cmd_line, "noltlbs")) {
++		__map_without_ltlbs = 1;
++	}
++}
++
++/*
++ * MMU_init sets up the basic memory mappings for the kernel,
++ * including both RAM and possibly some I/O regions,
++ * and sets up the page tables and the MMU hardware ready to go.
++ */
++void __init MMU_init(void)
++{
++	if (ppc_md.progress)
++		ppc_md.progress("MMU:enter", 0x111);
++
++	/* 601 can only access 16MB at the moment */
++	if (PVR_VER(mfspr(SPRN_PVR)) == 1)
++		__initial_memory_limit = 0x01000000;
++
++	/* parse args from command line */
++	MMU_setup();
++
++	if (lmb.memory.cnt > 1) {
++		lmb.memory.cnt = 1;
++		lmb_analyze();
++		printk(KERN_WARNING "Only using first contiguous memory region");
++	}
++
++	total_memory = lmb_end_of_DRAM();
++	total_lowmem = total_memory;
++
++#ifdef CONFIG_FSL_BOOKE
++	/* Freescale Book-E parts expect lowmem to be mapped by fixed TLB
++	 * entries, so we need to adjust lowmem to match the amount we can map
++	 * in the fixed entries */
++	adjust_total_lowmem();
++#endif /* CONFIG_FSL_BOOKE */
++
++	if (total_lowmem > __max_low_memory) {
++		total_lowmem = __max_low_memory;
++#ifndef CONFIG_HIGHMEM
++		total_memory = total_lowmem;
++		lmb_enforce_memory_limit(total_lowmem);
++		lmb_analyze();
++#endif /* CONFIG_HIGHMEM */
++	}
++
++	/* Initialize the MMU hardware */
++	if (ppc_md.progress)
++		ppc_md.progress("MMU:hw init", 0x300);
++	MMU_init_hw();
++
++	/* Map in all of RAM starting at KERNELBASE */
++	if (ppc_md.progress)
++		ppc_md.progress("MMU:mapin", 0x301);
++	mapin_ram();
++
++#ifdef CONFIG_HIGHMEM
++	ioremap_base = PKMAP_BASE;
++#else
++	ioremap_base = 0xfe000000UL;	/* for now, could be 0xfffff000 */
++#endif /* CONFIG_HIGHMEM */
++	ioremap_bot = ioremap_base;
++
++	/* Map in I/O resources */
++	if (ppc_md.progress)
++		ppc_md.progress("MMU:setio", 0x302);
++	if (ppc_md.setup_io_mappings)
++		ppc_md.setup_io_mappings();
++
++	/* Initialize the context management stuff */
++	mmu_context_init();
++
++	if (ppc_md.progress)
++		ppc_md.progress("MMU:exit", 0x211);
++}
++
++/* This is only called until mem_init is done. */
++void __init *early_get_page(void)
++{
++	void *p;
++
++	if (init_bootmem_done) {
++		p = alloc_bootmem_pages(PAGE_SIZE);
++	} else {
++		p = __va(lmb_alloc_base(PAGE_SIZE, PAGE_SIZE,
++					__initial_memory_limit));
++	}
++	return p;
++}
++
++/* Free up now-unused memory */
++static void free_sec(unsigned long start, unsigned long end, const char *name)
++{
++	unsigned long cnt = 0;
++
++	while (start < end) {
++		ClearPageReserved(virt_to_page(start));
++		set_page_count(virt_to_page(start), 1);
++		free_page(start);
++		cnt++;
++		start += PAGE_SIZE;
++ 	}
++	if (cnt) {
++		printk(" %ldk %s", cnt << (PAGE_SHIFT - 10), name);
++		totalram_pages += cnt;
++	}
++}
++
++void free_initmem(void)
++{
++#define FREESEC(TYPE) \
++	free_sec((unsigned long)(&__ ## TYPE ## _begin), \
++		 (unsigned long)(&__ ## TYPE ## _end), \
++		 #TYPE);
++
++	printk ("Freeing unused kernel memory:");
++	FREESEC(init);
++ 	printk("\n");
++	ppc_md.progress = NULL;
++#undef FREESEC
++}
++
++#ifdef CONFIG_BLK_DEV_INITRD
++void free_initrd_mem(unsigned long start, unsigned long end)
++{
++	if (start < end)
++		printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
++	for (; start < end; start += PAGE_SIZE) {
++		ClearPageReserved(virt_to_page(start));
++		set_page_count(virt_to_page(start), 1);
++		free_page(start);
++		totalram_pages++;
++	}
++}
++#endif
+diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/init_64.c
+@@ -0,0 +1,223 @@
++/*
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  Dave Engebretsen <engebret at us.ibm.com>
++ *      Rework for PPC64 port.
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/signal.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/mman.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/stddef.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/bootmem.h>
++#include <linux/highmem.h>
++#include <linux/idr.h>
++#include <linux/nodemask.h>
++#include <linux/module.h>
++
++#include <asm/pgalloc.h>
++#include <asm/page.h>
++#include <asm/prom.h>
++#include <asm/lmb.h>
++#include <asm/rtas.h>
++#include <asm/io.h>
++#include <asm/mmu_context.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/uaccess.h>
++#include <asm/smp.h>
++#include <asm/machdep.h>
++#include <asm/tlb.h>
++#include <asm/eeh.h>
++#include <asm/processor.h>
++#include <asm/mmzone.h>
++#include <asm/cputable.h>
++#include <asm/ppcdebug.h>
++#include <asm/sections.h>
++#include <asm/system.h>
++#include <asm/iommu.h>
++#include <asm/abs_addr.h>
++#include <asm/vdso.h>
++#include <asm/imalloc.h>
++
++#if PGTABLE_RANGE > USER_VSID_RANGE
++#warning Limited user VSID range means pagetable space is wasted
++#endif
++
++#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE)
++#warning TASK_SIZE is smaller than it needs to be.
++#endif
++
++unsigned long klimit = (unsigned long)_end;
++
++/* max amount of RAM to use */
++unsigned long __max_memory;
++
++/* info on what we think the IO hole is */
++unsigned long 	io_hole_start;
++unsigned long	io_hole_size;
++
++/*
++ * Do very early mm setup.
++ */
++void __init mm_init_ppc64(void)
++{
++#ifndef CONFIG_PPC_ISERIES
++	unsigned long i;
++#endif
++
++	ppc64_boot_msg(0x100, "MM Init");
++
++	/* This is the story of the IO hole... please, keep seated,
++	 * unfortunately, we are out of oxygen masks at the moment.
++	 * So we need some rough way to tell where your big IO hole
++	 * is. On pmac, it's between 2G and 4G, on POWER3, it's around
++	 * that area as well, on POWER4 we don't have one, etc...
++	 * We need that as a "hint" when sizing the TCE table on POWER3
++	 * So far, the simplest way that seem work well enough for us it
++	 * to just assume that the first discontinuity in our physical
++	 * RAM layout is the IO hole. That may not be correct in the future
++	 * (and isn't on iSeries but then we don't care ;)
++	 */
++
++#ifndef CONFIG_PPC_ISERIES
++	for (i = 1; i < lmb.memory.cnt; i++) {
++		unsigned long base, prevbase, prevsize;
++
++		prevbase = lmb.memory.region[i-1].base;
++		prevsize = lmb.memory.region[i-1].size;
++		base = lmb.memory.region[i].base;
++		if (base > (prevbase + prevsize)) {
++			io_hole_start = prevbase + prevsize;
++			io_hole_size = base  - (prevbase + prevsize);
++			break;
++		}
++	}
++#endif /* CONFIG_PPC_ISERIES */
++	if (io_hole_start)
++		printk("IO Hole assumed to be %lx -> %lx\n",
++		       io_hole_start, io_hole_start + io_hole_size - 1);
++
++	ppc64_boot_msg(0x100, "MM Init Done");
++}
++
++void free_initmem(void)
++{
++	unsigned long addr;
++
++	addr = (unsigned long)__init_begin;
++	for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
++		memset((void *)addr, 0xcc, PAGE_SIZE);
++		ClearPageReserved(virt_to_page(addr));
++		set_page_count(virt_to_page(addr), 1);
++		free_page(addr);
++		totalram_pages++;
++	}
++	printk ("Freeing unused kernel memory: %luk freed\n",
++		((unsigned long)__init_end - (unsigned long)__init_begin) >> 10);
++}
++
++#ifdef CONFIG_BLK_DEV_INITRD
++void free_initrd_mem(unsigned long start, unsigned long end)
++{
++	if (start < end)
++		printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
++	for (; start < end; start += PAGE_SIZE) {
++		ClearPageReserved(virt_to_page(start));
++		set_page_count(virt_to_page(start), 1);
++		free_page(start);
++		totalram_pages++;
++	}
++}
++#endif
++
++static struct kcore_list kcore_vmem;
++
++static int __init setup_kcore(void)
++{
++	int i;
++
++	for (i=0; i < lmb.memory.cnt; i++) {
++		unsigned long base, size;
++		struct kcore_list *kcore_mem;
++
++		base = lmb.memory.region[i].base;
++		size = lmb.memory.region[i].size;
++
++		/* GFP_ATOMIC to avoid might_sleep warnings during boot */
++		kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
++		if (!kcore_mem)
++			panic("mem_init: kmalloc failed\n");
++
++		kclist_add(kcore_mem, __va(base), size);
++	}
++
++	kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
++
++	return 0;
++}
++module_init(setup_kcore);
++
++static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
++{
++	memset(addr, 0, kmem_cache_size(cache));
++}
++
++static const int pgtable_cache_size[2] = {
++	PTE_TABLE_SIZE, PMD_TABLE_SIZE
++};
++static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
++	"pgd_pte_cache", "pud_pmd_cache",
++};
++
++kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
++
++void pgtable_cache_init(void)
++{
++	int i;
++
++	BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]);
++	BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]);
++	BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]);
++	BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]);
++
++	for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) {
++		int size = pgtable_cache_size[i];
++		const char *name = pgtable_cache_name[i];
++
++		pgtable_cache[i] = kmem_cache_create(name,
++						     size, size,
++						     SLAB_HWCACHE_ALIGN
++						     | SLAB_MUST_HWCACHE_ALIGN,
++						     zero_ctor,
++						     NULL);
++		if (! pgtable_cache[i])
++			panic("pgtable_cache_init(): could not create %s!\n",
++			      name);
++	}
++}
+diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/lmb.c
+@@ -0,0 +1,296 @@
++/*
++ * Procedures for maintaining information about logical memory blocks.
++ *
++ * Peter Bergner, IBM Corp.	June 2001.
++ * Copyright (C) 2001 Peter Bergner.
++ * 
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/init.h>
++#include <linux/bitops.h>
++#include <asm/types.h>
++#include <asm/page.h>
++#include <asm/prom.h>
++#include <asm/lmb.h>
++#ifdef CONFIG_PPC32
++#include "mmu_decl.h"		/* for __max_low_memory */
++#endif
++
++struct lmb lmb;
++
++#undef DEBUG
++
++void lmb_dump_all(void)
++{
++#ifdef DEBUG
++	unsigned long i;
++
++	udbg_printf("lmb_dump_all:\n");
++	udbg_printf("    memory.cnt		  = 0x%lx\n",
++		    lmb.memory.cnt);
++	udbg_printf("    memory.size		  = 0x%lx\n",
++		    lmb.memory.size);
++	for (i=0; i < lmb.memory.cnt ;i++) {
++		udbg_printf("    memory.region[0x%x].base       = 0x%lx\n",
++			    i, lmb.memory.region[i].base);
++		udbg_printf("		      .size     = 0x%lx\n",
++			    lmb.memory.region[i].size);
++	}
++
++	udbg_printf("\n    reserved.cnt	  = 0x%lx\n",
++		    lmb.reserved.cnt);
++	udbg_printf("    reserved.size	  = 0x%lx\n",
++		    lmb.reserved.size);
++	for (i=0; i < lmb.reserved.cnt ;i++) {
++		udbg_printf("    reserved.region[0x%x].base       = 0x%lx\n",
++			    i, lmb.reserved.region[i].base);
++		udbg_printf("		      .size     = 0x%lx\n",
++			    lmb.reserved.region[i].size);
++	}
++#endif /* DEBUG */
++}
++
++static unsigned long __init lmb_addrs_overlap(unsigned long base1,
++		unsigned long size1, unsigned long base2, unsigned long size2)
++{
++	return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
++}
++
++static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
++		unsigned long base2, unsigned long size2)
++{
++	if (base2 == base1 + size1)
++		return 1;
++	else if (base1 == base2 + size2)
++		return -1;
++
++	return 0;
++}
++
++static long __init lmb_regions_adjacent(struct lmb_region *rgn,
++		unsigned long r1, unsigned long r2)
++{
++	unsigned long base1 = rgn->region[r1].base;
++	unsigned long size1 = rgn->region[r1].size;
++	unsigned long base2 = rgn->region[r2].base;
++	unsigned long size2 = rgn->region[r2].size;
++
++	return lmb_addrs_adjacent(base1, size1, base2, size2);
++}
++
++/* Assumption: base addr of region 1 < base addr of region 2 */
++static void __init lmb_coalesce_regions(struct lmb_region *rgn,
++		unsigned long r1, unsigned long r2)
++{
++	unsigned long i;
++
++	rgn->region[r1].size += rgn->region[r2].size;
++	for (i=r2; i < rgn->cnt-1; i++) {
++		rgn->region[i].base = rgn->region[i+1].base;
++		rgn->region[i].size = rgn->region[i+1].size;
++	}
++	rgn->cnt--;
++}
++
++/* This routine called with relocation disabled. */
++void __init lmb_init(void)
++{
++	/* Create a dummy zero size LMB which will get coalesced away later.
++	 * This simplifies the lmb_add() code below...
++	 */
++	lmb.memory.region[0].base = 0;
++	lmb.memory.region[0].size = 0;
++	lmb.memory.cnt = 1;
++
++	/* Ditto. */
++	lmb.reserved.region[0].base = 0;
++	lmb.reserved.region[0].size = 0;
++	lmb.reserved.cnt = 1;
++}
++
++/* This routine may be called with relocation disabled. */
++void __init lmb_analyze(void)
++{
++	int i;
++
++	lmb.memory.size = 0;
++
++	for (i = 0; i < lmb.memory.cnt; i++)
++		lmb.memory.size += lmb.memory.region[i].size;
++}
++
++/* This routine called with relocation disabled. */
++static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
++				  unsigned long size)
++{
++	unsigned long i, coalesced = 0;
++	long adjacent;
++
++	/* First try and coalesce this LMB with another. */
++	for (i=0; i < rgn->cnt; i++) {
++		unsigned long rgnbase = rgn->region[i].base;
++		unsigned long rgnsize = rgn->region[i].size;
++
++		adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
++		if ( adjacent > 0 ) {
++			rgn->region[i].base -= size;
++			rgn->region[i].size += size;
++			coalesced++;
++			break;
++		}
++		else if ( adjacent < 0 ) {
++			rgn->region[i].size += size;
++			coalesced++;
++			break;
++		}
++	}
++
++	if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
++		lmb_coalesce_regions(rgn, i, i+1);
++		coalesced++;
++	}
++
++	if (coalesced)
++		return coalesced;
++	if (rgn->cnt >= MAX_LMB_REGIONS)
++		return -1;
++
++	/* Couldn't coalesce the LMB, so add it to the sorted table. */
++	for (i = rgn->cnt-1; i >= 0; i--) {
++		if (base < rgn->region[i].base) {
++			rgn->region[i+1].base = rgn->region[i].base;
++			rgn->region[i+1].size = rgn->region[i].size;
++		} else {
++			rgn->region[i+1].base = base;
++			rgn->region[i+1].size = size;
++			break;
++		}
++	}
++	rgn->cnt++;
++
++	return 0;
++}
++
++/* This routine may be called with relocation disabled. */
++long __init lmb_add(unsigned long base, unsigned long size)
++{
++	struct lmb_region *_rgn = &(lmb.memory);
++
++	/* On pSeries LPAR systems, the first LMB is our RMO region. */
++	if (base == 0)
++		lmb.rmo_size = size;
++
++	return lmb_add_region(_rgn, base, size);
++
++}
++
++long __init lmb_reserve(unsigned long base, unsigned long size)
++{
++	struct lmb_region *_rgn = &(lmb.reserved);
++
++	return lmb_add_region(_rgn, base, size);
++}
++
++long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
++				unsigned long size)
++{
++	unsigned long i;
++
++	for (i=0; i < rgn->cnt; i++) {
++		unsigned long rgnbase = rgn->region[i].base;
++		unsigned long rgnsize = rgn->region[i].size;
++		if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
++			break;
++		}
++	}
++
++	return (i < rgn->cnt) ? i : -1;
++}
++
++unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
++{
++	return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
++}
++
++unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
++				    unsigned long max_addr)
++{
++	long i, j;
++	unsigned long base = 0;
++
++#ifdef CONFIG_PPC32
++	/* On 32-bit, make sure we allocate lowmem */
++	if (max_addr == LMB_ALLOC_ANYWHERE)
++		max_addr = __max_low_memory;
++#endif
++	for (i = lmb.memory.cnt-1; i >= 0; i--) {
++		unsigned long lmbbase = lmb.memory.region[i].base;
++		unsigned long lmbsize = lmb.memory.region[i].size;
++
++		if (max_addr == LMB_ALLOC_ANYWHERE)
++			base = _ALIGN_DOWN(lmbbase + lmbsize - size, align);
++		else if (lmbbase < max_addr) {
++			base = min(lmbbase + lmbsize, max_addr);
++			base = _ALIGN_DOWN(base - size, align);
++		} else
++			continue;
++
++		while ((lmbbase <= base) &&
++		       ((j = lmb_overlaps_region(&lmb.reserved, base, size)) >= 0) )
++			base = _ALIGN_DOWN(lmb.reserved.region[j].base - size,
++					   align);
++
++		if ((base != 0) && (lmbbase <= base))
++			break;
++	}
++
++	if (i < 0)
++		return 0;
++
++	lmb_add_region(&lmb.reserved, base, size);
++
++	return base;
++}
++
++/* You must call lmb_analyze() before this. */
++unsigned long __init lmb_phys_mem_size(void)
++{
++	return lmb.memory.size;
++}
++
++unsigned long __init lmb_end_of_DRAM(void)
++{
++	int idx = lmb.memory.cnt - 1;
++
++	return (lmb.memory.region[idx].base + lmb.memory.region[idx].size);
++}
++
++/*
++ * Truncate the lmb list to memory_limit if it's set
++ * You must call lmb_analyze() after this.
++ */
++void __init lmb_enforce_memory_limit(unsigned long memory_limit)
++{
++	unsigned long i, limit;
++
++	if (! memory_limit)
++		return;
++
++	limit = memory_limit;
++	for (i = 0; i < lmb.memory.cnt; i++) {
++		if (limit > lmb.memory.region[i].size) {
++			limit -= lmb.memory.region[i].size;
++			continue;
++		}
++
++		lmb.memory.region[i].size = limit;
++		lmb.memory.cnt = i + 1;
++		break;
++	}
++}
+diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/mem.c
+@@ -0,0 +1,564 @@
++/*
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *  PPC44x/36-bit changes by Matt Porter (mporter at mvista.com)
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/module.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/mm.h>
++#include <linux/stddef.h>
++#include <linux/init.h>
++#include <linux/bootmem.h>
++#include <linux/highmem.h>
++#include <linux/initrd.h>
++#include <linux/pagemap.h>
++
++#include <asm/pgalloc.h>
++#include <asm/prom.h>
++#include <asm/io.h>
++#include <asm/mmu_context.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/smp.h>
++#include <asm/machdep.h>
++#include <asm/btext.h>
++#include <asm/tlb.h>
++#include <asm/prom.h>
++#include <asm/lmb.h>
++#include <asm/sections.h>
++#ifdef CONFIG_PPC64
++#include <asm/vdso.h>
++#endif
++
++#include "mmu_decl.h"
++
++#ifndef CPU_FTR_COHERENT_ICACHE
++#define CPU_FTR_COHERENT_ICACHE	0	/* XXX for now */
++#define CPU_FTR_NOEXECUTE	0
++#endif
++
++int init_bootmem_done;
++int mem_init_done;
++unsigned long memory_limit;
++
++/*
++ * This is called by /dev/mem to know if a given address has to
++ * be mapped non-cacheable or not
++ */
++int page_is_ram(unsigned long pfn)
++{
++	unsigned long paddr = (pfn << PAGE_SHIFT);
++
++#ifndef CONFIG_PPC64	/* XXX for now */
++	return paddr < __pa(high_memory);
++#else
++	int i;
++	for (i=0; i < lmb.memory.cnt; i++) {
++		unsigned long base;
++
++		base = lmb.memory.region[i].base;
++
++		if ((paddr >= base) &&
++			(paddr < (base + lmb.memory.region[i].size))) {
++			return 1;
++		}
++	}
++
++	return 0;
++#endif
++}
++EXPORT_SYMBOL(page_is_ram);
++
++pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
++			      unsigned long size, pgprot_t vma_prot)
++{
++	if (ppc_md.phys_mem_access_prot)
++		return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot);
++
++	if (!page_is_ram(pfn))
++		vma_prot = __pgprot(pgprot_val(vma_prot)
++				    | _PAGE_GUARDED | _PAGE_NO_CACHE);
++	return vma_prot;
++}
++EXPORT_SYMBOL(phys_mem_access_prot);
++
++#ifdef CONFIG_MEMORY_HOTPLUG
++
++void online_page(struct page *page)
++{
++	ClearPageReserved(page);
++	free_cold_page(page);
++	totalram_pages++;
++	num_physpages++;
++}
++
++/*
++ * This works only for the non-NUMA case.  Later, we'll need a lookup
++ * to convert from real physical addresses to nid, that doesn't use
++ * pfn_to_nid().
++ */
++int __devinit add_memory(u64 start, u64 size)
++{
++	struct pglist_data *pgdata = NODE_DATA(0);
++	struct zone *zone;
++	unsigned long start_pfn = start >> PAGE_SHIFT;
++	unsigned long nr_pages = size >> PAGE_SHIFT;
++
++	/* this should work for most non-highmem platforms */
++	zone = pgdata->node_zones;
++
++	return __add_pages(zone, start_pfn, nr_pages);
++
++	return 0;
++}
++
++/*
++ * First pass at this code will check to determine if the remove
++ * request is within the RMO.  Do not allow removal within the RMO.
++ */
++int __devinit remove_memory(u64 start, u64 size)
++{
++	struct zone *zone;
++	unsigned long start_pfn, end_pfn, nr_pages;
++
++	start_pfn = start >> PAGE_SHIFT;
++	nr_pages = size >> PAGE_SHIFT;
++	end_pfn = start_pfn + nr_pages;
++
++	printk("%s(): Attempting to remove memoy in range "
++			"%lx to %lx\n", __func__, start, start+size);
++	/*
++	 * check for range within RMO
++	 */
++	zone = page_zone(pfn_to_page(start_pfn));
++
++	printk("%s(): memory will be removed from "
++			"the %s zone\n", __func__, zone->name);
++
++	/*
++	 * not handling removing memory ranges that
++	 * overlap multiple zones yet
++	 */
++	if (end_pfn > (zone->zone_start_pfn + zone->spanned_pages))
++		goto overlap;
++
++	/* make sure it is NOT in RMO */
++	if ((start < lmb.rmo_size) || ((start+size) < lmb.rmo_size)) {
++		printk("%s(): range to be removed must NOT be in RMO!\n",
++			__func__);
++		goto in_rmo;
++	}
++
++	return __remove_pages(zone, start_pfn, nr_pages);
++
++overlap:
++	printk("%s(): memory range to be removed overlaps "
++		"multiple zones!!!\n", __func__);
++in_rmo:
++	return -1;
++}
++#endif /* CONFIG_MEMORY_HOTPLUG */
++
++void show_mem(void)
++{
++	unsigned long total = 0, reserved = 0;
++	unsigned long shared = 0, cached = 0;
++	unsigned long highmem = 0;
++	struct page *page;
++	pg_data_t *pgdat;
++	unsigned long i;
++
++	printk("Mem-info:\n");
++	show_free_areas();
++	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
++	for_each_pgdat(pgdat) {
++		unsigned long flags;
++		pgdat_resize_lock(pgdat, &flags);
++		for (i = 0; i < pgdat->node_spanned_pages; i++) {
++			page = pgdat_page_nr(pgdat, i);
++			total++;
++			if (PageHighMem(page))
++				highmem++;
++			if (PageReserved(page))
++				reserved++;
++			else if (PageSwapCache(page))
++				cached++;
++			else if (page_count(page))
++				shared += page_count(page) - 1;
++		}
++		pgdat_resize_unlock(pgdat, &flags);
++	}
++	printk("%ld pages of RAM\n", total);
++#ifdef CONFIG_HIGHMEM
++	printk("%ld pages of HIGHMEM\n", highmem);
++#endif
++	printk("%ld reserved pages\n", reserved);
++	printk("%ld pages shared\n", shared);
++	printk("%ld pages swap cached\n", cached);
++}
++
++/*
++ * Initialize the bootmem system and give it all the memory we
++ * have available.  If we are using highmem, we only put the
++ * lowmem into the bootmem system.
++ */
++#ifndef CONFIG_NEED_MULTIPLE_NODES
++void __init do_init_bootmem(void)
++{
++	unsigned long i;
++	unsigned long start, bootmap_pages;
++	unsigned long total_pages;
++	int boot_mapsize;
++
++	max_pfn = total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
++#ifdef CONFIG_HIGHMEM
++	total_pages = total_lowmem >> PAGE_SHIFT;
++#endif
++
++	/*
++	 * Find an area to use for the bootmem bitmap.  Calculate the size of
++	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
++	 * Add 1 additional page in case the address isn't page-aligned.
++	 */
++	bootmap_pages = bootmem_bootmap_pages(total_pages);
++
++	start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
++	BUG_ON(!start);
++
++	boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
++
++	/* Add all physical memory to the bootmem map, mark each area
++	 * present.
++	 */
++	for (i = 0; i < lmb.memory.cnt; i++) {
++		unsigned long base = lmb.memory.region[i].base;
++		unsigned long size = lmb_size_bytes(&lmb.memory, i);
++#ifdef CONFIG_HIGHMEM
++		if (base >= total_lowmem)
++			continue;
++		if (base + size > total_lowmem)
++			size = total_lowmem - base;
++#endif
++		free_bootmem(base, size);
++	}
++
++	/* reserve the sections we're already using */
++	for (i = 0; i < lmb.reserved.cnt; i++)
++		reserve_bootmem(lmb.reserved.region[i].base,
++				lmb_size_bytes(&lmb.reserved, i));
++
++	/* XXX need to clip this if using highmem? */
++	for (i = 0; i < lmb.memory.cnt; i++)
++		memory_present(0, lmb_start_pfn(&lmb.memory, i),
++			       lmb_end_pfn(&lmb.memory, i));
++	init_bootmem_done = 1;
++}
++
++/*
++ * paging_init() sets up the page tables - in fact we've already done this.
++ */
++void __init paging_init(void)
++{
++	unsigned long zones_size[MAX_NR_ZONES];
++	unsigned long zholes_size[MAX_NR_ZONES];
++	unsigned long total_ram = lmb_phys_mem_size();
++	unsigned long top_of_ram = lmb_end_of_DRAM();
++
++#ifdef CONFIG_HIGHMEM
++	map_page(PKMAP_BASE, 0, 0);	/* XXX gross */
++	pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k
++			(PKMAP_BASE), PKMAP_BASE), PKMAP_BASE);
++	map_page(KMAP_FIX_BEGIN, 0, 0);	/* XXX gross */
++	kmap_pte = pte_offset_kernel(pmd_offset(pgd_offset_k
++			(KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN);
++	kmap_prot = PAGE_KERNEL;
++#endif /* CONFIG_HIGHMEM */
++
++	printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
++	       top_of_ram, total_ram);
++	printk(KERN_INFO "Memory hole size: %ldMB\n",
++	       (top_of_ram - total_ram) >> 20);
++	/*
++	 * All pages are DMA-able so we put them all in the DMA zone.
++	 */
++	memset(zones_size, 0, sizeof(zones_size));
++	memset(zholes_size, 0, sizeof(zholes_size));
++
++	zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
++	zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
++
++#ifdef CONFIG_HIGHMEM
++	zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
++	zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT;
++	zholes_size[ZONE_HIGHMEM] = (top_of_ram - total_ram) >> PAGE_SHIFT;
++#else
++	zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
++	zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
++#endif /* CONFIG_HIGHMEM */
++
++	free_area_init_node(0, NODE_DATA(0), zones_size,
++			    __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
++}
++#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
++
++void __init mem_init(void)
++{
++#ifdef CONFIG_NEED_MULTIPLE_NODES
++	int nid;
++#endif
++	pg_data_t *pgdat;
++	unsigned long i;
++	struct page *page;
++	unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
++
++	num_physpages = max_pfn;	/* RAM is assumed contiguous */
++	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
++
++#ifdef CONFIG_NEED_MULTIPLE_NODES
++        for_each_online_node(nid) {
++		if (NODE_DATA(nid)->node_spanned_pages != 0) {
++			printk("freeing bootmem node %x\n", nid);
++			totalram_pages +=
++				free_all_bootmem_node(NODE_DATA(nid));
++		}
++	}
++#else
++	max_mapnr = num_physpages;
++	totalram_pages += free_all_bootmem();
++#endif
++	for_each_pgdat(pgdat) {
++		for (i = 0; i < pgdat->node_spanned_pages; i++) {
++			page = pgdat_page_nr(pgdat, i);
++			if (PageReserved(page))
++				reservedpages++;
++		}
++	}
++
++	codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
++	datasize = (unsigned long)&__init_begin - (unsigned long)&_sdata;
++	initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
++	bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
++
++#ifdef CONFIG_HIGHMEM
++	{
++		unsigned long pfn, highmem_mapnr;
++
++		highmem_mapnr = total_lowmem >> PAGE_SHIFT;
++		for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
++			struct page *page = pfn_to_page(pfn);
++
++			ClearPageReserved(page);
++			set_page_count(page, 1);
++			__free_page(page);
++			totalhigh_pages++;
++		}
++		totalram_pages += totalhigh_pages;
++		printk(KERN_INFO "High memory: %luk\n",
++		       totalhigh_pages << (PAGE_SHIFT-10));
++	}
++#endif /* CONFIG_HIGHMEM */
++
++	printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, "
++	       "%luk reserved, %luk data, %luk bss, %luk init)\n",
++		(unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
++		num_physpages << (PAGE_SHIFT-10),
++		codesize >> 10,
++		reservedpages << (PAGE_SHIFT-10),
++		datasize >> 10,
++		bsssize >> 10,
++		initsize >> 10);
++
++	mem_init_done = 1;
++
++#ifdef CONFIG_PPC64
++	/* Initialize the vDSO */
++	vdso_init();
++#endif
++}
++
++/*
++ * This is called when a page has been modified by the kernel.
++ * It just marks the page as not i-cache clean.  We do the i-cache
++ * flush later when the page is given to a user process, if necessary.
++ */
++void flush_dcache_page(struct page *page)
++{
++	if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
++		return;
++	/* avoid an atomic op if possible */
++	if (test_bit(PG_arch_1, &page->flags))
++		clear_bit(PG_arch_1, &page->flags);
++}
++EXPORT_SYMBOL(flush_dcache_page);
++
++void flush_dcache_icache_page(struct page *page)
++{
++#ifdef CONFIG_BOOKE
++	void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE);
++	__flush_dcache_icache(start);
++	kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
++#elif defined(CONFIG_8xx) || defined(CONFIG_PPC64)
++	/* On 8xx there is no need to kmap since highmem is not supported */
++	__flush_dcache_icache(page_address(page)); 
++#else
++	__flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
++#endif
++
++}
++void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
++{
++	clear_page(page);
++
++	if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
++		return;
++	/*
++	 * We shouldnt have to do this, but some versions of glibc
++	 * require it (ld.so assumes zero filled pages are icache clean)
++	 * - Anton
++	 */
++
++	/* avoid an atomic op if possible */
++	if (test_bit(PG_arch_1, &pg->flags))
++		clear_bit(PG_arch_1, &pg->flags);
++}
++EXPORT_SYMBOL(clear_user_page);
++
++void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
++		    struct page *pg)
++{
++	copy_page(vto, vfrom);
++
++	/*
++	 * We should be able to use the following optimisation, however
++	 * there are two problems.
++	 * Firstly a bug in some versions of binutils meant PLT sections
++	 * were not marked executable.
++	 * Secondly the first word in the GOT section is blrl, used
++	 * to establish the GOT address. Until recently the GOT was
++	 * not marked executable.
++	 * - Anton
++	 */
++#if 0
++	if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0))
++		return;
++#endif
++
++	if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
++		return;
++
++	/* avoid an atomic op if possible */
++	if (test_bit(PG_arch_1, &pg->flags))
++		clear_bit(PG_arch_1, &pg->flags);
++}
++
++void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
++			     unsigned long addr, int len)
++{
++	unsigned long maddr;
++
++	maddr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
++	flush_icache_range(maddr, maddr + len);
++	kunmap(page);
++}
++EXPORT_SYMBOL(flush_icache_user_range);
++
++/*
++ * This is called at the end of handling a user page fault, when the
++ * fault has been handled by updating a PTE in the linux page tables.
++ * We use it to preload an HPTE into the hash table corresponding to
++ * the updated linux PTE.
++ * 
++ * This must always be called with the mm->page_table_lock held
++ */
++void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
++		      pte_t pte)
++{
++	/* handle i-cache coherency */
++	unsigned long pfn = pte_pfn(pte);
++#ifdef CONFIG_PPC32
++	pmd_t *pmd;
++#else
++	unsigned long vsid;
++	void *pgdir;
++	pte_t *ptep;
++	int local = 0;
++	cpumask_t tmp;
++	unsigned long flags;
++#endif
++
++	/* handle i-cache coherency */
++	if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
++	    !cpu_has_feature(CPU_FTR_NOEXECUTE) &&
++	    pfn_valid(pfn)) {
++		struct page *page = pfn_to_page(pfn);
++		if (!PageReserved(page)
++		    && !test_bit(PG_arch_1, &page->flags)) {
++			if (vma->vm_mm == current->active_mm) {
++#ifdef CONFIG_8xx
++			/* On 8xx, cache control instructions (particularly 
++		 	 * "dcbst" from flush_dcache_icache) fault as write 
++			 * operation if there is an unpopulated TLB entry 
++			 * for the address in question. To workaround that, 
++			 * we invalidate the TLB here, thus avoiding dcbst 
++			 * misbehaviour.
++			 */
++				_tlbie(address);
++#endif
++				__flush_dcache_icache((void *) address);
++			} else
++				flush_dcache_icache_page(page);
++			set_bit(PG_arch_1, &page->flags);
++		}
++	}
++
++#ifdef CONFIG_PPC_STD_MMU
++	/* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
++	if (!pte_young(pte) || address >= TASK_SIZE)
++		return;
++#ifdef CONFIG_PPC32
++	if (Hash == 0)
++		return;
++	pmd = pmd_offset(pgd_offset(vma->vm_mm, address), address);
++	if (!pmd_none(*pmd))
++		add_hash_page(vma->vm_mm->context, address, pmd_val(*pmd));
++#else
++	pgdir = vma->vm_mm->pgd;
++	if (pgdir == NULL)
++		return;
++
++	ptep = find_linux_pte(pgdir, address);
++	if (!ptep)
++		return;
++
++	vsid = get_vsid(vma->vm_mm->context.id, address);
++
++	local_irq_save(flags);
++	tmp = cpumask_of_cpu(smp_processor_id());
++	if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
++		local = 1;
++
++	__hash_page(address, 0, vsid, ptep, 0x300, local);
++	local_irq_restore(flags);
++#endif
++#endif
++}
+diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/mmap.c
+@@ -0,0 +1,86 @@
++/*
++ *  linux/arch/ppc64/mm/mmap.c
++ *
++ *  flexible mmap layout support
++ *
++ * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
++ * 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
++ *
++ *
++ * Started by Ingo Molnar <mingo at elte.hu>
++ */
++
++#include <linux/personality.h>
++#include <linux/mm.h>
++
++/*
++ * Top of mmap area (just below the process stack).
++ *
++ * Leave an at least ~128 MB hole.
++ */
++#define MIN_GAP (128*1024*1024)
++#define MAX_GAP (TASK_SIZE/6*5)
++
++static inline unsigned long mmap_base(void)
++{
++	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
++
++	if (gap < MIN_GAP)
++		gap = MIN_GAP;
++	else if (gap > MAX_GAP)
++		gap = MAX_GAP;
++
++	return TASK_SIZE - (gap & PAGE_MASK);
++}
++
++static inline int mmap_is_legacy(void)
++{
++	/*
++	 * Force standard allocation for 64 bit programs.
++	 */
++	if (!test_thread_flag(TIF_32BIT))
++		return 1;
++
++	if (current->personality & ADDR_COMPAT_LAYOUT)
++		return 1;
++
++	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
++		return 1;
++
++	return sysctl_legacy_va_layout;
++}
++
++/*
++ * This function, called very early during the creation of a new
++ * process VM image, sets up which VM layout function to use:
++ */
++void arch_pick_mmap_layout(struct mm_struct *mm)
++{
++	/*
++	 * Fall back to the standard layout if the personality
++	 * bit is set, or if the expected stack growth is unlimited:
++	 */
++	if (mmap_is_legacy()) {
++		mm->mmap_base = TASK_UNMAPPED_BASE;
++		mm->get_unmapped_area = arch_get_unmapped_area;
++		mm->unmap_area = arch_unmap_area;
++	} else {
++		mm->mmap_base = mmap_base();
++		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
++		mm->unmap_area = arch_unmap_area_topdown;
++	}
++}
+diff --git a/arch/powerpc/mm/mmu_context_32.c b/arch/powerpc/mm/mmu_context_32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/mmu_context_32.c
+@@ -0,0 +1,86 @@
++/*
++ * This file contains the routines for handling the MMU on those
++ * PowerPC implementations where the MMU substantially follows the
++ * architecture specification.  This includes the 6xx, 7xx, 7xxx,
++ * 8260, and POWER3 implementations but excludes the 8xx and 4xx.
++ *  -- paulus
++ *
++ *  Derived from arch/ppc/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/mm.h>
++#include <linux/init.h>
++
++#include <asm/mmu_context.h>
++#include <asm/tlbflush.h>
++
++mm_context_t next_mmu_context;
++unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
++#ifdef FEW_CONTEXTS
++atomic_t nr_free_contexts;
++struct mm_struct *context_mm[LAST_CONTEXT+1];
++void steal_context(void);
++#endif /* FEW_CONTEXTS */
++
++/*
++ * Initialize the context management stuff.
++ */
++void __init
++mmu_context_init(void)
++{
++	/*
++	 * Some processors have too few contexts to reserve one for
++	 * init_mm, and require using context 0 for a normal task.
++	 * Other processors reserve the use of context zero for the kernel.
++	 * This code assumes FIRST_CONTEXT < 32.
++	 */
++	context_map[0] = (1 << FIRST_CONTEXT) - 1;
++	next_mmu_context = FIRST_CONTEXT;
++#ifdef FEW_CONTEXTS
++	atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
++#endif /* FEW_CONTEXTS */
++}
++
++#ifdef FEW_CONTEXTS
++/*
++ * Steal a context from a task that has one at the moment.
++ * This is only used on 8xx and 4xx and we presently assume that
++ * they don't do SMP.  If they do then this will have to check
++ * whether the MM we steal is in use.
++ * We also assume that this is only used on systems that don't
++ * use an MMU hash table - this is true for 8xx and 4xx.
++ * This isn't an LRU system, it just frees up each context in
++ * turn (sort-of pseudo-random replacement :).  This would be the
++ * place to implement an LRU scheme if anyone was motivated to do it.
++ *  -- paulus
++ */
++void
++steal_context(void)
++{
++	struct mm_struct *mm;
++
++	/* free up context `next_mmu_context' */
++	/* if we shouldn't free context 0, don't... */
++	if (next_mmu_context < FIRST_CONTEXT)
++		next_mmu_context = FIRST_CONTEXT;
++	mm = context_mm[next_mmu_context];
++	flush_tlb_mm(mm);
++	destroy_context(mm);
++}
++#endif /* FEW_CONTEXTS */
+diff --git a/arch/powerpc/mm/mmu_context_64.c b/arch/powerpc/mm/mmu_context_64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/mmu_context_64.c
+@@ -0,0 +1,63 @@
++/*
++ *  MMU context allocation for 64-bit kernels.
++ *
++ *  Copyright (C) 2004 Anton Blanchard, IBM Corp. <anton at samba.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/config.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/mm.h>
++#include <linux/spinlock.h>
++#include <linux/idr.h>
++
++#include <asm/mmu_context.h>
++
++static DEFINE_SPINLOCK(mmu_context_lock);
++static DEFINE_IDR(mmu_context_idr);
++
++int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
++{
++	int index;
++	int err;
++
++again:
++	if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL))
++		return -ENOMEM;
++
++	spin_lock(&mmu_context_lock);
++	err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index);
++	spin_unlock(&mmu_context_lock);
++
++	if (err == -EAGAIN)
++		goto again;
++	else if (err)
++		return err;
++
++	if (index > MAX_CONTEXT) {
++		idr_remove(&mmu_context_idr, index);
++		return -ENOMEM;
++	}
++
++	mm->context.id = index;
++
++	return 0;
++}
++
++void destroy_context(struct mm_struct *mm)
++{
++	spin_lock(&mmu_context_lock);
++	idr_remove(&mmu_context_idr, mm->context.id);
++	spin_unlock(&mmu_context_lock);
++
++	mm->context.id = NO_CONTEXT;
++}
+diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/mmu_decl.h
+@@ -0,0 +1,87 @@
++/*
++ * Declarations of procedures and variables shared between files
++ * in arch/ppc/mm/.
++ *
++ *  Derived from arch/ppc/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/tlbflush.h>
++#include <asm/mmu.h>
++
++#ifdef CONFIG_PPC32
++extern void mapin_ram(void);
++extern int map_page(unsigned long va, phys_addr_t pa, int flags);
++extern void setbat(int index, unsigned long virt, unsigned long phys,
++		   unsigned int size, int flags);
++extern void settlbcam(int index, unsigned long virt, phys_addr_t phys,
++		      unsigned int size, int flags, unsigned int pid);
++extern void invalidate_tlbcam_entry(int index);
++
++extern int __map_without_bats;
++extern unsigned long ioremap_base;
++extern unsigned long ioremap_bot;
++extern unsigned int rtas_data, rtas_size;
++
++extern PTE *Hash, *Hash_end;
++extern unsigned long Hash_size, Hash_mask;
++
++extern unsigned int num_tlbcam_entries;
++#endif
++
++extern unsigned long __max_low_memory;
++extern unsigned long __initial_memory_limit;
++extern unsigned long total_memory;
++extern unsigned long total_lowmem;
++
++/* ...and now those things that may be slightly different between processor
++ * architectures.  -- Dan
++ */
++#if defined(CONFIG_8xx)
++#define flush_HPTE(X, va, pg)	_tlbie(va)
++#define MMU_init_hw()		do { } while(0)
++#define mmu_mapin_ram()		(0UL)
++
++#elif defined(CONFIG_4xx)
++#define flush_HPTE(X, va, pg)	_tlbie(va)
++extern void MMU_init_hw(void);
++extern unsigned long mmu_mapin_ram(void);
++
++#elif defined(CONFIG_FSL_BOOKE)
++#define flush_HPTE(X, va, pg)	_tlbie(va)
++extern void MMU_init_hw(void);
++extern unsigned long mmu_mapin_ram(void);
++extern void adjust_total_lowmem(void);
++
++#elif defined(CONFIG_PPC32)
++/* anything 32-bit except 4xx or 8xx */
++extern void MMU_init_hw(void);
++extern unsigned long mmu_mapin_ram(void);
++
++/* Be careful....this needs to be updated if we ever encounter 603 SMPs,
++ * which includes all new 82xx processors.  We need tlbie/tlbsync here
++ * in that case (I think). -- Dan.
++ */
++static inline void flush_HPTE(unsigned context, unsigned long va,
++			      unsigned long pdval)
++{
++	if ((Hash != 0) &&
++	    cpu_has_feature(CPU_FTR_HPTE_TABLE))
++		flush_hash_pages(0, va, pdval, 1);
++	else
++		_tlbie(va);
++}
++#endif
+diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/numa.c
+@@ -0,0 +1,779 @@
++/*
++ * pSeries NUMA support
++ *
++ * Copyright (C) 2002 Anton Blanchard <anton at au.ibm.com>, 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/threads.h>
++#include <linux/bootmem.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/mmzone.h>
++#include <linux/module.h>
++#include <linux/nodemask.h>
++#include <linux/cpu.h>
++#include <linux/notifier.h>
++#include <asm/lmb.h>
++#include <asm/machdep.h>
++#include <asm/abs_addr.h>
++#include <asm/system.h>
++
++static int numa_enabled = 1;
++
++static int numa_debug;
++#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); }
++
++#ifdef DEBUG_NUMA
++#define ARRAY_INITIALISER -1
++#else
++#define ARRAY_INITIALISER 0
++#endif
++
++int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] =
++	ARRAY_INITIALISER};
++char *numa_memory_lookup_table;
++cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
++int nr_cpus_in_node[MAX_NUMNODES] = { [0 ... (MAX_NUMNODES -1)] = 0};
++
++struct pglist_data *node_data[MAX_NUMNODES];
++bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
++static int min_common_depth;
++
++/*
++ * We need somewhere to store start/span for each node until we have
++ * allocated the real node_data structures.
++ */
++static struct {
++	unsigned long node_start_pfn;
++	unsigned long node_end_pfn;
++	unsigned long node_present_pages;
++} init_node_data[MAX_NUMNODES] __initdata;
++
++EXPORT_SYMBOL(node_data);
++EXPORT_SYMBOL(numa_cpu_lookup_table);
++EXPORT_SYMBOL(numa_memory_lookup_table);
++EXPORT_SYMBOL(numa_cpumask_lookup_table);
++EXPORT_SYMBOL(nr_cpus_in_node);
++
++static inline void map_cpu_to_node(int cpu, int node)
++{
++	numa_cpu_lookup_table[cpu] = node;
++	if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node]))) {
++		cpu_set(cpu, numa_cpumask_lookup_table[node]);
++		nr_cpus_in_node[node]++;
++	}
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++static void unmap_cpu_from_node(unsigned long cpu)
++{
++	int node = numa_cpu_lookup_table[cpu];
++
++	dbg("removing cpu %lu from node %d\n", cpu, node);
++
++	if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) {
++		cpu_clear(cpu, numa_cpumask_lookup_table[node]);
++		nr_cpus_in_node[node]--;
++	} else {
++		printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n",
++		       cpu, node);
++	}
++}
++#endif /* CONFIG_HOTPLUG_CPU */
++
++static struct device_node * __devinit find_cpu_node(unsigned int cpu)
++{
++	unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
++	struct device_node *cpu_node = NULL;
++	unsigned int *interrupt_server, *reg;
++	int len;
++
++	while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
++		/* Try interrupt server first */
++		interrupt_server = (unsigned int *)get_property(cpu_node,
++					"ibm,ppc-interrupt-server#s", &len);
++
++		len = len / sizeof(u32);
++
++		if (interrupt_server && (len > 0)) {
++			while (len--) {
++				if (interrupt_server[len] == hw_cpuid)
++					return cpu_node;
++			}
++		} else {
++			reg = (unsigned int *)get_property(cpu_node,
++							   "reg", &len);
++			if (reg && (len > 0) && (reg[0] == hw_cpuid))
++				return cpu_node;
++		}
++	}
++
++	return NULL;
++}
++
++/* must hold reference to node during call */
++static int *of_get_associativity(struct device_node *dev)
++{
++	return (unsigned int *)get_property(dev, "ibm,associativity", NULL);
++}
++
++static int of_node_numa_domain(struct device_node *device)
++{
++	int numa_domain;
++	unsigned int *tmp;
++
++	if (min_common_depth == -1)
++		return 0;
++
++	tmp = of_get_associativity(device);
++	if (tmp && (tmp[0] >= min_common_depth)) {
++		numa_domain = tmp[min_common_depth];
++	} else {
++		dbg("WARNING: no NUMA information for %s\n",
++		    device->full_name);
++		numa_domain = 0;
++	}
++	return numa_domain;
++}
++
++/*
++ * In theory, the "ibm,associativity" property may contain multiple
++ * associativity lists because a resource may be multiply connected
++ * into the machine.  This resource then has different associativity
++ * characteristics relative to its multiple connections.  We ignore
++ * this for now.  We also assume that all cpu and memory sets have
++ * their distances represented at a common level.  This won't be
++ * true for heirarchical NUMA.
++ *
++ * In any case the ibm,associativity-reference-points should give
++ * the correct depth for a normal NUMA system.
++ *
++ * - Dave Hansen <haveblue at us.ibm.com>
++ */
++static int __init find_min_common_depth(void)
++{
++	int depth;
++	unsigned int *ref_points;
++	struct device_node *rtas_root;
++	unsigned int len;
++
++	rtas_root = of_find_node_by_path("/rtas");
++
++	if (!rtas_root)
++		return -1;
++
++	/*
++	 * this property is 2 32-bit integers, each representing a level of
++	 * depth in the associativity nodes.  The first is for an SMP
++	 * configuration (should be all 0's) and the second is for a normal
++	 * NUMA configuration.
++	 */
++	ref_points = (unsigned int *)get_property(rtas_root,
++			"ibm,associativity-reference-points", &len);
++
++	if ((len >= 1) && ref_points) {
++		depth = ref_points[1];
++	} else {
++		dbg("WARNING: could not find NUMA "
++		    "associativity reference point\n");
++		depth = -1;
++	}
++	of_node_put(rtas_root);
++
++	return depth;
++}
++
++static int __init get_mem_addr_cells(void)
++{
++	struct device_node *memory = NULL;
++	int rc;
++
++	memory = of_find_node_by_type(memory, "memory");
++	if (!memory)
++		return 0; /* it won't matter */
++
++	rc = prom_n_addr_cells(memory);
++	return rc;
++}
++
++static int __init get_mem_size_cells(void)
++{
++	struct device_node *memory = NULL;
++	int rc;
++
++	memory = of_find_node_by_type(memory, "memory");
++	if (!memory)
++		return 0; /* it won't matter */
++	rc = prom_n_size_cells(memory);
++	return rc;
++}
++
++static unsigned long read_n_cells(int n, unsigned int **buf)
++{
++	unsigned long result = 0;
++
++	while (n--) {
++		result = (result << 32) | **buf;
++		(*buf)++;
++	}
++	return result;
++}
++
++/*
++ * Figure out to which domain a cpu belongs and stick it there.
++ * Return the id of the domain used.
++ */
++static int numa_setup_cpu(unsigned long lcpu)
++{
++	int numa_domain = 0;
++	struct device_node *cpu = find_cpu_node(lcpu);
++
++	if (!cpu) {
++		WARN_ON(1);
++		goto out;
++	}
++
++	numa_domain = of_node_numa_domain(cpu);
++
++	if (numa_domain >= num_online_nodes()) {
++		/*
++		 * POWER4 LPAR uses 0xffff as invalid node,
++		 * dont warn in this case.
++		 */
++		if (numa_domain != 0xffff)
++			printk(KERN_ERR "WARNING: cpu %ld "
++			       "maps to invalid NUMA node %d\n",
++			       lcpu, numa_domain);
++		numa_domain = 0;
++	}
++out:
++	node_set_online(numa_domain);
++
++	map_cpu_to_node(lcpu, numa_domain);
++
++	of_node_put(cpu);
++
++	return numa_domain;
++}
++
++static int cpu_numa_callback(struct notifier_block *nfb,
++			     unsigned long action,
++			     void *hcpu)
++{
++	unsigned long lcpu = (unsigned long)hcpu;
++	int ret = NOTIFY_DONE;
++
++	switch (action) {
++	case CPU_UP_PREPARE:
++		if (min_common_depth == -1 || !numa_enabled)
++			map_cpu_to_node(lcpu, 0);
++		else
++			numa_setup_cpu(lcpu);
++		ret = NOTIFY_OK;
++		break;
++#ifdef CONFIG_HOTPLUG_CPU
++	case CPU_DEAD:
++	case CPU_UP_CANCELED:
++		unmap_cpu_from_node(lcpu);
++		break;
++		ret = NOTIFY_OK;
++#endif
++	}
++	return ret;
++}
++
++/*
++ * Check and possibly modify a memory region to enforce the memory limit.
++ *
++ * Returns the size the region should have to enforce the memory limit.
++ * This will either be the original value of size, a truncated value,
++ * or zero. If the returned value of size is 0 the region should be
++ * discarded as it lies wholy above the memory limit.
++ */
++static unsigned long __init numa_enforce_memory_limit(unsigned long start, unsigned long size)
++{
++	/*
++	 * We use lmb_end_of_DRAM() in here instead of memory_limit because
++	 * we've already adjusted it for the limit and it takes care of
++	 * having memory holes below the limit.
++	 */
++
++	if (! memory_limit)
++		return size;
++
++	if (start + size <= lmb_end_of_DRAM())
++		return size;
++
++	if (start >= lmb_end_of_DRAM())
++		return 0;
++
++	return lmb_end_of_DRAM() - start;
++}
++
++static int __init parse_numa_properties(void)
++{
++	struct device_node *cpu = NULL;
++	struct device_node *memory = NULL;
++	int addr_cells, size_cells;
++	int max_domain = 0;
++	long entries = lmb_end_of_DRAM() >> MEMORY_INCREMENT_SHIFT;
++	unsigned long i;
++
++	if (numa_enabled == 0) {
++		printk(KERN_WARNING "NUMA disabled by user\n");
++		return -1;
++	}
++
++	numa_memory_lookup_table =
++		(char *)abs_to_virt(lmb_alloc(entries * sizeof(char), 1));
++	memset(numa_memory_lookup_table, 0, entries * sizeof(char));
++
++	for (i = 0; i < entries ; i++)
++		numa_memory_lookup_table[i] = ARRAY_INITIALISER;
++
++	min_common_depth = find_min_common_depth();
++
++	dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
++	if (min_common_depth < 0)
++		return min_common_depth;
++
++	max_domain = numa_setup_cpu(boot_cpuid);
++
++	/*
++	 * Even though we connect cpus to numa domains later in SMP init,
++	 * we need to know the maximum node id now. This is because each
++	 * node id must have NODE_DATA etc backing it.
++	 * As a result of hotplug we could still have cpus appear later on
++	 * with larger node ids. In that case we force the cpu into node 0.
++	 */
++	for_each_cpu(i) {
++		int numa_domain;
++
++		cpu = find_cpu_node(i);
++
++		if (cpu) {
++			numa_domain = of_node_numa_domain(cpu);
++			of_node_put(cpu);
++
++			if (numa_domain < MAX_NUMNODES &&
++			    max_domain < numa_domain)
++				max_domain = numa_domain;
++		}
++	}
++
++	addr_cells = get_mem_addr_cells();
++	size_cells = get_mem_size_cells();
++	memory = NULL;
++	while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
++		unsigned long start;
++		unsigned long size;
++		int numa_domain;
++		int ranges;
++		unsigned int *memcell_buf;
++		unsigned int len;
++
++		memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
++		if (!memcell_buf || len <= 0)
++			continue;
++
++		ranges = memory->n_addrs;
++new_range:
++		/* these are order-sensitive, and modify the buffer pointer */
++		start = read_n_cells(addr_cells, &memcell_buf);
++		size = read_n_cells(size_cells, &memcell_buf);
++
++		start = _ALIGN_DOWN(start, MEMORY_INCREMENT);
++		size = _ALIGN_UP(size, MEMORY_INCREMENT);
++
++		numa_domain = of_node_numa_domain(memory);
++
++		if (numa_domain >= MAX_NUMNODES) {
++			if (numa_domain != 0xffff)
++				printk(KERN_ERR "WARNING: memory at %lx maps "
++				       "to invalid NUMA node %d\n", start,
++				       numa_domain);
++			numa_domain = 0;
++		}
++
++		if (max_domain < numa_domain)
++			max_domain = numa_domain;
++
++		if (! (size = numa_enforce_memory_limit(start, size))) {
++			if (--ranges)
++				goto new_range;
++			else
++				continue;
++		}
++
++		/*
++		 * Initialize new node struct, or add to an existing one.
++		 */
++		if (init_node_data[numa_domain].node_end_pfn) {
++			if ((start / PAGE_SIZE) <
++			    init_node_data[numa_domain].node_start_pfn)
++				init_node_data[numa_domain].node_start_pfn =
++					start / PAGE_SIZE;
++			if (((start / PAGE_SIZE) + (size / PAGE_SIZE)) >
++			    init_node_data[numa_domain].node_end_pfn)
++				init_node_data[numa_domain].node_end_pfn =
++					(start / PAGE_SIZE) +
++					(size / PAGE_SIZE);
++
++			init_node_data[numa_domain].node_present_pages +=
++				size / PAGE_SIZE;
++		} else {
++			node_set_online(numa_domain);
++
++			init_node_data[numa_domain].node_start_pfn =
++				start / PAGE_SIZE;
++			init_node_data[numa_domain].node_end_pfn =
++				init_node_data[numa_domain].node_start_pfn +
++				size / PAGE_SIZE;
++			init_node_data[numa_domain].node_present_pages =
++				size / PAGE_SIZE;
++		}
++
++		for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
++			numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
++				numa_domain;
++
++		if (--ranges)
++			goto new_range;
++	}
++
++	for (i = 0; i <= max_domain; i++)
++		node_set_online(i);
++
++	return 0;
++}
++
++static void __init setup_nonnuma(void)
++{
++	unsigned long top_of_ram = lmb_end_of_DRAM();
++	unsigned long total_ram = lmb_phys_mem_size();
++	unsigned long i;
++
++	printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
++	       top_of_ram, total_ram);
++	printk(KERN_INFO "Memory hole size: %ldMB\n",
++	       (top_of_ram - total_ram) >> 20);
++
++	if (!numa_memory_lookup_table) {
++		long entries = top_of_ram >> MEMORY_INCREMENT_SHIFT;
++		numa_memory_lookup_table =
++			(char *)abs_to_virt(lmb_alloc(entries * sizeof(char), 1));
++		memset(numa_memory_lookup_table, 0, entries * sizeof(char));
++		for (i = 0; i < entries ; i++)
++			numa_memory_lookup_table[i] = ARRAY_INITIALISER;
++	}
++
++	map_cpu_to_node(boot_cpuid, 0);
++
++	node_set_online(0);
++
++	init_node_data[0].node_start_pfn = 0;
++	init_node_data[0].node_end_pfn = lmb_end_of_DRAM() / PAGE_SIZE;
++	init_node_data[0].node_present_pages = total_ram / PAGE_SIZE;
++
++	for (i = 0 ; i < top_of_ram; i += MEMORY_INCREMENT)
++		numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0;
++}
++
++static void __init dump_numa_topology(void)
++{
++	unsigned int node;
++	unsigned int count;
++
++	if (min_common_depth == -1 || !numa_enabled)
++		return;
++
++	for_each_online_node(node) {
++		unsigned long i;
++
++		printk(KERN_INFO "Node %d Memory:", node);
++
++		count = 0;
++
++		for (i = 0; i < lmb_end_of_DRAM(); i += MEMORY_INCREMENT) {
++			if (numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] == node) {
++				if (count == 0)
++					printk(" 0x%lx", i);
++				++count;
++			} else {
++				if (count > 0)
++					printk("-0x%lx", i);
++				count = 0;
++			}
++		}
++
++		if (count > 0)
++			printk("-0x%lx", i);
++		printk("\n");
++	}
++	return;
++}
++
++/*
++ * Allocate some memory, satisfying the lmb or bootmem allocator where
++ * required. nid is the preferred node and end is the physical address of
++ * the highest address in the node.
++ *
++ * Returns the physical address of the memory.
++ */
++static unsigned long careful_allocation(int nid, unsigned long size,
++					unsigned long align, unsigned long end)
++{
++	unsigned long ret = lmb_alloc_base(size, align, end);
++
++	/* retry over all memory */
++	if (!ret)
++		ret = lmb_alloc_base(size, align, lmb_end_of_DRAM());
++
++	if (!ret)
++		panic("numa.c: cannot allocate %lu bytes on node %d",
++		      size, nid);
++
++	/*
++	 * If the memory came from a previously allocated node, we must
++	 * retry with the bootmem allocator.
++	 */
++	if (pa_to_nid(ret) < nid) {
++		nid = pa_to_nid(ret);
++		ret = (unsigned long)__alloc_bootmem_node(NODE_DATA(nid),
++				size, align, 0);
++
++		if (!ret)
++			panic("numa.c: cannot allocate %lu bytes on node %d",
++			      size, nid);
++
++		ret = virt_to_abs(ret);
++
++		dbg("alloc_bootmem %lx %lx\n", ret, size);
++	}
++
++	return ret;
++}
++
++void __init do_init_bootmem(void)
++{
++	int nid;
++	int addr_cells, size_cells;
++	struct device_node *memory = NULL;
++	static struct notifier_block ppc64_numa_nb = {
++		.notifier_call = cpu_numa_callback,
++		.priority = 1 /* Must run before sched domains notifier. */
++	};
++
++	min_low_pfn = 0;
++	max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
++	max_pfn = max_low_pfn;
++
++	if (parse_numa_properties())
++		setup_nonnuma();
++	else
++		dump_numa_topology();
++
++	register_cpu_notifier(&ppc64_numa_nb);
++
++	for_each_online_node(nid) {
++		unsigned long start_paddr, end_paddr;
++		int i;
++		unsigned long bootmem_paddr;
++		unsigned long bootmap_pages;
++
++		start_paddr = init_node_data[nid].node_start_pfn * PAGE_SIZE;
++		end_paddr = init_node_data[nid].node_end_pfn * PAGE_SIZE;
++
++		/* Allocate the node structure node local if possible */
++		NODE_DATA(nid) = (struct pglist_data *)careful_allocation(nid,
++					sizeof(struct pglist_data),
++					SMP_CACHE_BYTES, end_paddr);
++		NODE_DATA(nid) = abs_to_virt(NODE_DATA(nid));
++		memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
++
++  		dbg("node %d\n", nid);
++		dbg("NODE_DATA() = %p\n", NODE_DATA(nid));
++
++		NODE_DATA(nid)->bdata = &plat_node_bdata[nid];
++		NODE_DATA(nid)->node_start_pfn =
++			init_node_data[nid].node_start_pfn;
++		NODE_DATA(nid)->node_spanned_pages =
++			end_paddr - start_paddr;
++
++		if (NODE_DATA(nid)->node_spanned_pages == 0)
++  			continue;
++
++  		dbg("start_paddr = %lx\n", start_paddr);
++  		dbg("end_paddr = %lx\n", end_paddr);
++
++		bootmap_pages = bootmem_bootmap_pages((end_paddr - start_paddr) >> PAGE_SHIFT);
++
++		bootmem_paddr = careful_allocation(nid,
++				bootmap_pages << PAGE_SHIFT,
++				PAGE_SIZE, end_paddr);
++		memset(abs_to_virt(bootmem_paddr), 0,
++		       bootmap_pages << PAGE_SHIFT);
++		dbg("bootmap_paddr = %lx\n", bootmem_paddr);
++
++		init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
++				  start_paddr >> PAGE_SHIFT,
++				  end_paddr >> PAGE_SHIFT);
++
++		/*
++		 * We need to do another scan of all memory sections to
++		 * associate memory with the correct node.
++		 */
++		addr_cells = get_mem_addr_cells();
++		size_cells = get_mem_size_cells();
++		memory = NULL;
++		while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
++			unsigned long mem_start, mem_size;
++			int numa_domain, ranges;
++			unsigned int *memcell_buf;
++			unsigned int len;
++
++			memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
++			if (!memcell_buf || len <= 0)
++				continue;
++
++			ranges = memory->n_addrs;	/* ranges in cell */
++new_range:
++			mem_start = read_n_cells(addr_cells, &memcell_buf);
++			mem_size = read_n_cells(size_cells, &memcell_buf);
++			if (numa_enabled) {
++				numa_domain = of_node_numa_domain(memory);
++				if (numa_domain  >= MAX_NUMNODES)
++					numa_domain = 0;
++			} else
++				numa_domain =  0;
++
++			if (numa_domain != nid)
++				continue;
++
++			mem_size = numa_enforce_memory_limit(mem_start, mem_size);
++  			if (mem_size) {
++  				dbg("free_bootmem %lx %lx\n", mem_start, mem_size);
++  				free_bootmem_node(NODE_DATA(nid), mem_start, mem_size);
++			}
++
++			if (--ranges)		/* process all ranges in cell */
++				goto new_range;
++		}
++
++		/*
++		 * Mark reserved regions on this node
++		 */
++		for (i = 0; i < lmb.reserved.cnt; i++) {
++			unsigned long physbase = lmb.reserved.region[i].base;
++			unsigned long size = lmb.reserved.region[i].size;
++
++			if (pa_to_nid(physbase) != nid &&
++			    pa_to_nid(physbase+size-1) != nid)
++				continue;
++
++			if (physbase < end_paddr &&
++			    (physbase+size) > start_paddr) {
++				/* overlaps */
++				if (physbase < start_paddr) {
++					size -= start_paddr - physbase;
++					physbase = start_paddr;
++				}
++
++				if (size > end_paddr - physbase)
++					size = end_paddr - physbase;
++
++				dbg("reserve_bootmem %lx %lx\n", physbase,
++				    size);
++				reserve_bootmem_node(NODE_DATA(nid), physbase,
++						     size);
++			}
++		}
++		/*
++		 * This loop may look famaliar, but we have to do it again
++		 * after marking our reserved memory to mark memory present
++		 * for sparsemem.
++		 */
++		addr_cells = get_mem_addr_cells();
++		size_cells = get_mem_size_cells();
++		memory = NULL;
++		while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
++			unsigned long mem_start, mem_size;
++			int numa_domain, ranges;
++			unsigned int *memcell_buf;
++			unsigned int len;
++
++			memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
++			if (!memcell_buf || len <= 0)
++				continue;
++
++			ranges = memory->n_addrs;	/* ranges in cell */
++new_range2:
++			mem_start = read_n_cells(addr_cells, &memcell_buf);
++			mem_size = read_n_cells(size_cells, &memcell_buf);
++			if (numa_enabled) {
++				numa_domain = of_node_numa_domain(memory);
++				if (numa_domain  >= MAX_NUMNODES)
++					numa_domain = 0;
++			} else
++				numa_domain =  0;
++
++			if (numa_domain != nid)
++				continue;
++
++			mem_size = numa_enforce_memory_limit(mem_start, mem_size);
++			memory_present(numa_domain, mem_start >> PAGE_SHIFT,
++				       (mem_start + mem_size) >> PAGE_SHIFT);
++
++			if (--ranges)		/* process all ranges in cell */
++				goto new_range2;
++		}
++
++	}
++}
++
++void __init paging_init(void)
++{
++	unsigned long zones_size[MAX_NR_ZONES];
++	unsigned long zholes_size[MAX_NR_ZONES];
++	int nid;
++
++	memset(zones_size, 0, sizeof(zones_size));
++	memset(zholes_size, 0, sizeof(zholes_size));
++
++	for_each_online_node(nid) {
++		unsigned long start_pfn;
++		unsigned long end_pfn;
++
++		start_pfn = init_node_data[nid].node_start_pfn;
++		end_pfn = init_node_data[nid].node_end_pfn;
++
++		zones_size[ZONE_DMA] = end_pfn - start_pfn;
++		zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] -
++			init_node_data[nid].node_present_pages;
++
++		dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid,
++		    zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]);
++
++		free_area_init_node(nid, NODE_DATA(nid), zones_size,
++							start_pfn, zholes_size);
++	}
++}
++
++static int __init early_numa(char *p)
++{
++	if (!p)
++		return 0;
++
++	if (strstr(p, "off"))
++		numa_enabled = 0;
++
++	if (strstr(p, "debug"))
++		numa_debug = 1;
++
++	return 0;
++}
++early_param("numa", early_numa);
+diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/pgtable_32.c
+@@ -0,0 +1,467 @@
++/*
++ * This file contains the routines setting up the linux page tables.
++ *  -- paulus
++ *
++ *  Derived from arch/ppc/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/module.h>
++#include <linux/types.h>
++#include <linux/mm.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++#include <linux/highmem.h>
++
++#include <asm/pgtable.h>
++#include <asm/pgalloc.h>
++#include <asm/io.h>
++
++#include "mmu_decl.h"
++
++unsigned long ioremap_base;
++unsigned long ioremap_bot;
++int io_bat_index;
++
++#if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
++#define HAVE_BATS	1
++#endif
++
++#if defined(CONFIG_FSL_BOOKE)
++#define HAVE_TLBCAM	1
++#endif
++
++extern char etext[], _stext[];
++
++#ifdef CONFIG_SMP
++extern void hash_page_sync(void);
++#endif
++
++#ifdef HAVE_BATS
++extern unsigned long v_mapped_by_bats(unsigned long va);
++extern unsigned long p_mapped_by_bats(unsigned long pa);
++void setbat(int index, unsigned long virt, unsigned long phys,
++	    unsigned int size, int flags);
++
++#else /* !HAVE_BATS */
++#define v_mapped_by_bats(x)	(0UL)
++#define p_mapped_by_bats(x)	(0UL)
++#endif /* HAVE_BATS */
++
++#ifdef HAVE_TLBCAM
++extern unsigned int tlbcam_index;
++extern unsigned long v_mapped_by_tlbcam(unsigned long va);
++extern unsigned long p_mapped_by_tlbcam(unsigned long pa);
++#else /* !HAVE_TLBCAM */
++#define v_mapped_by_tlbcam(x)	(0UL)
++#define p_mapped_by_tlbcam(x)	(0UL)
++#endif /* HAVE_TLBCAM */
++
++#ifdef CONFIG_PTE_64BIT
++/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */
++#define PGDIR_ORDER	1
++#else
++#define PGDIR_ORDER	0
++#endif
++
++pgd_t *pgd_alloc(struct mm_struct *mm)
++{
++	pgd_t *ret;
++
++	ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGDIR_ORDER);
++	return ret;
++}
++
++void pgd_free(pgd_t *pgd)
++{
++	free_pages((unsigned long)pgd, PGDIR_ORDER);
++}
++
++pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
++{
++	pte_t *pte;
++	extern int mem_init_done;
++	extern void *early_get_page(void);
++
++	if (mem_init_done) {
++		pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
++	} else {
++		pte = (pte_t *)early_get_page();
++		if (pte)
++			clear_page(pte);
++	}
++	return pte;
++}
++
++struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
++{
++	struct page *ptepage;
++
++#ifdef CONFIG_HIGHPTE
++	gfp_t flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT;
++#else
++	gfp_t flags = GFP_KERNEL | __GFP_REPEAT;
++#endif
++
++	ptepage = alloc_pages(flags, 0);
++	if (ptepage)
++		clear_highpage(ptepage);
++	return ptepage;
++}
++
++void pte_free_kernel(pte_t *pte)
++{
++#ifdef CONFIG_SMP
++	hash_page_sync();
++#endif
++	free_page((unsigned long)pte);
++}
++
++void pte_free(struct page *ptepage)
++{
++#ifdef CONFIG_SMP
++	hash_page_sync();
++#endif
++	__free_page(ptepage);
++}
++
++#ifndef CONFIG_PHYS_64BIT
++void __iomem *
++ioremap(phys_addr_t addr, unsigned long size)
++{
++	return __ioremap(addr, size, _PAGE_NO_CACHE);
++}
++#else /* CONFIG_PHYS_64BIT */
++void __iomem *
++ioremap64(unsigned long long addr, unsigned long size)
++{
++	return __ioremap(addr, size, _PAGE_NO_CACHE);
++}
++
++void __iomem *
++ioremap(phys_addr_t addr, unsigned long size)
++{
++	phys_addr_t addr64 = fixup_bigphys_addr(addr, size);
++
++	return ioremap64(addr64, size);
++}
++#endif /* CONFIG_PHYS_64BIT */
++
++void __iomem *
++__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
++{
++	unsigned long v, i;
++	phys_addr_t p;
++	int err;
++
++	/*
++	 * Choose an address to map it to.
++	 * Once the vmalloc system is running, we use it.
++	 * Before then, we use space going down from ioremap_base
++	 * (ioremap_bot records where we're up to).
++	 */
++	p = addr & PAGE_MASK;
++	size = PAGE_ALIGN(addr + size) - p;
++
++	/*
++	 * If the address lies within the first 16 MB, assume it's in ISA
++	 * memory space
++	 */
++	if (p < 16*1024*1024)
++		p += _ISA_MEM_BASE;
++
++	/*
++	 * Don't allow anybody to remap normal RAM that we're using.
++	 * mem_init() sets high_memory so only do the check after that.
++	 */
++	if (mem_init_done && (p < virt_to_phys(high_memory))) {
++		printk("__ioremap(): phys addr "PHYS_FMT" is RAM lr %p\n", p,
++		       __builtin_return_address(0));
++		return NULL;
++	}
++
++	if (size == 0)
++		return NULL;
++
++	/*
++	 * Is it already mapped?  Perhaps overlapped by a previous
++	 * BAT mapping.  If the whole area is mapped then we're done,
++	 * otherwise remap it since we want to keep the virt addrs for
++	 * each request contiguous.
++	 *
++	 * We make the assumption here that if the bottom and top
++	 * of the range we want are mapped then it's mapped to the
++	 * same virt address (and this is contiguous).
++	 *  -- Cort
++	 */
++	if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
++		goto out;
++
++	if ((v = p_mapped_by_tlbcam(p)))
++		goto out;
++
++	if (mem_init_done) {
++		struct vm_struct *area;
++		area = get_vm_area(size, VM_IOREMAP);
++		if (area == 0)
++			return NULL;
++		v = (unsigned long) area->addr;
++	} else {
++		v = (ioremap_bot -= size);
++	}
++
++	if ((flags & _PAGE_PRESENT) == 0)
++		flags |= _PAGE_KERNEL;
++	if (flags & _PAGE_NO_CACHE)
++		flags |= _PAGE_GUARDED;
++
++	/*
++	 * Should check if it is a candidate for a BAT mapping
++	 */
++
++	err = 0;
++	for (i = 0; i < size && err == 0; i += PAGE_SIZE)
++		err = map_page(v+i, p+i, flags);
++	if (err) {
++		if (mem_init_done)
++			vunmap((void *)v);
++		return NULL;
++	}
++
++out:
++	return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK));
++}
++
++void iounmap(volatile void __iomem *addr)
++{
++	/*
++	 * If mapped by BATs then there is nothing to do.
++	 * Calling vfree() generates a benign warning.
++	 */
++	if (v_mapped_by_bats((unsigned long)addr)) return;
++
++	if (addr > high_memory && (unsigned long) addr < ioremap_bot)
++		vunmap((void *) (PAGE_MASK & (unsigned long)addr));
++}
++
++void __iomem *ioport_map(unsigned long port, unsigned int len)
++{
++	return (void __iomem *) (port + _IO_BASE);
++}
++
++void ioport_unmap(void __iomem *addr)
++{
++	/* Nothing to do */
++}
++EXPORT_SYMBOL(ioport_map);
++EXPORT_SYMBOL(ioport_unmap);
++
++int
++map_page(unsigned long va, phys_addr_t pa, int flags)
++{
++	pmd_t *pd;
++	pte_t *pg;
++	int err = -ENOMEM;
++
++	/* Use upper 10 bits of VA to index the first level map */
++	pd = pmd_offset(pgd_offset_k(va), va);
++	/* Use middle 10 bits of VA to index the second-level map */
++	pg = pte_alloc_kernel(pd, va);
++	if (pg != 0) {
++		err = 0;
++		set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags)));
++		if (mem_init_done)
++			flush_HPTE(0, va, pmd_val(*pd));
++	}
++	return err;
++}
++
++/*
++ * Map in all of physical memory starting at KERNELBASE.
++ */
++void __init mapin_ram(void)
++{
++	unsigned long v, p, s, f;
++
++	s = mmu_mapin_ram();
++	v = KERNELBASE + s;
++	p = PPC_MEMSTART + s;
++	for (; s < total_lowmem; s += PAGE_SIZE) {
++		if ((char *) v >= _stext && (char *) v < etext)
++			f = _PAGE_RAM_TEXT;
++		else
++			f = _PAGE_RAM;
++		map_page(v, p, f);
++		v += PAGE_SIZE;
++		p += PAGE_SIZE;
++	}
++}
++
++/* is x a power of 2? */
++#define is_power_of_2(x)	((x) != 0 && (((x) & ((x) - 1)) == 0))
++
++/* is x a power of 4? */
++#define is_power_of_4(x)	((x) != 0 && (((x) & (x-1)) == 0) && (ffs(x) & 1))
++
++/*
++ * Set up a mapping for a block of I/O.
++ * virt, phys, size must all be page-aligned.
++ * This should only be called before ioremap is called.
++ */
++void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
++			     unsigned int size, int flags)
++{
++	int i;
++
++	if (virt > KERNELBASE && virt < ioremap_bot)
++		ioremap_bot = ioremap_base = virt;
++
++#ifdef HAVE_BATS
++	/*
++	 * Use a BAT for this if possible...
++	 */
++	if (io_bat_index < 2 && is_power_of_2(size)
++	    && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
++		setbat(io_bat_index, virt, phys, size, flags);
++		++io_bat_index;
++		return;
++	}
++#endif /* HAVE_BATS */
++
++#ifdef HAVE_TLBCAM
++	/*
++	 * Use a CAM for this if possible...
++	 */
++	if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size)
++	    && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
++		settlbcam(tlbcam_index, virt, phys, size, flags, 0);
++		++tlbcam_index;
++		return;
++	}
++#endif /* HAVE_TLBCAM */
++
++	/* No BATs available, put it in the page tables. */
++	for (i = 0; i < size; i += PAGE_SIZE)
++		map_page(virt + i, phys + i, flags);
++}
++
++/* Scan the real Linux page tables and return a PTE pointer for
++ * a virtual address in a context.
++ * Returns true (1) if PTE was found, zero otherwise.  The pointer to
++ * the PTE pointer is unmodified if PTE is not found.
++ */
++int
++get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
++{
++        pgd_t	*pgd;
++        pmd_t	*pmd;
++        pte_t	*pte;
++        int     retval = 0;
++
++        pgd = pgd_offset(mm, addr & PAGE_MASK);
++        if (pgd) {
++                pmd = pmd_offset(pgd, addr & PAGE_MASK);
++                if (pmd_present(*pmd)) {
++                        pte = pte_offset_map(pmd, addr & PAGE_MASK);
++                        if (pte) {
++				retval = 1;
++				*ptep = pte;
++				/* XXX caller needs to do pte_unmap, yuck */
++                        }
++                }
++        }
++        return(retval);
++}
++
++/* Find physical address for this virtual address.  Normally used by
++ * I/O functions, but anyone can call it.
++ */
++unsigned long iopa(unsigned long addr)
++{
++	unsigned long pa;
++
++	/* I don't know why this won't work on PMacs or CHRP.  It
++	 * appears there is some bug, or there is some implicit
++	 * mapping done not properly represented by BATs or in page
++	 * tables.......I am actively working on resolving this, but
++	 * can't hold up other stuff.  -- Dan
++	 */
++	pte_t *pte;
++	struct mm_struct *mm;
++
++	/* Check the BATs */
++	pa = v_mapped_by_bats(addr);
++	if (pa)
++		return pa;
++
++	/* Allow mapping of user addresses (within the thread)
++	 * for DMA if necessary.
++	 */
++	if (addr < TASK_SIZE)
++		mm = current->mm;
++	else
++		mm = &init_mm;
++
++	pa = 0;
++	if (get_pteptr(mm, addr, &pte)) {
++		pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
++		pte_unmap(pte);
++	}
++
++	return(pa);
++}
++
++/* This is will find the virtual address for a physical one....
++ * Swiped from APUS, could be dangerous :-).
++ * This is only a placeholder until I really find a way to make this
++ * work.  -- Dan
++ */
++unsigned long
++mm_ptov (unsigned long paddr)
++{
++	unsigned long ret;
++#if 0
++	if (paddr < 16*1024*1024)
++		ret = ZTWO_VADDR(paddr);
++	else {
++		int i;
++
++		for (i = 0; i < kmap_chunk_count;){
++			unsigned long phys = kmap_chunks[i++];
++			unsigned long size = kmap_chunks[i++];
++			unsigned long virt = kmap_chunks[i++];
++			if (paddr >= phys
++			    && paddr < (phys + size)){
++				ret = virt + paddr - phys;
++				goto exit;
++			}
++		}
++	
++		ret = (unsigned long) __va(paddr);
++	}
++exit:
++#ifdef DEBUGPV
++	printk ("PTOV(%lx)=%lx\n", paddr, ret);
++#endif
++#else
++	ret = (unsigned long)paddr + KERNELBASE;
++#endif
++	return ret;
++}
++
+diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/pgtable_64.c
+@@ -0,0 +1,347 @@
++/*
++ *  This file contains ioremap and related functions for 64-bit machines.
++ *
++ *  Derived from arch/ppc64/mm/init.c
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at samba.org)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  Dave Engebretsen <engebret at us.ibm.com>
++ *      Rework for PPC64 port.
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/signal.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/mman.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/stddef.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/bootmem.h>
++#include <linux/highmem.h>
++#include <linux/idr.h>
++#include <linux/nodemask.h>
++#include <linux/module.h>
++
++#include <asm/pgalloc.h>
++#include <asm/page.h>
++#include <asm/prom.h>
++#include <asm/lmb.h>
++#include <asm/rtas.h>
++#include <asm/io.h>
++#include <asm/mmu_context.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/uaccess.h>
++#include <asm/smp.h>
++#include <asm/machdep.h>
++#include <asm/tlb.h>
++#include <asm/eeh.h>
++#include <asm/processor.h>
++#include <asm/mmzone.h>
++#include <asm/cputable.h>
++#include <asm/ppcdebug.h>
++#include <asm/sections.h>
++#include <asm/system.h>
++#include <asm/iommu.h>
++#include <asm/abs_addr.h>
++#include <asm/vdso.h>
++#include <asm/imalloc.h>
++
++unsigned long ioremap_bot = IMALLOC_BASE;
++static unsigned long phbs_io_bot = PHBS_IO_BASE;
++
++#ifdef CONFIG_PPC_ISERIES
++
++void __iomem *ioremap(unsigned long addr, unsigned long size)
++{
++	return (void __iomem *)addr;
++}
++
++extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
++		       unsigned long flags)
++{
++	return (void __iomem *)addr;
++}
++
++void iounmap(volatile void __iomem *addr)
++{
++	return;
++}
++
++#else
++
++/*
++ * map_io_page currently only called by __ioremap
++ * map_io_page adds an entry to the ioremap page table
++ * and adds an entry to the HPT, possibly bolting it
++ */
++static int map_io_page(unsigned long ea, unsigned long pa, int flags)
++{
++	pgd_t *pgdp;
++	pud_t *pudp;
++	pmd_t *pmdp;
++	pte_t *ptep;
++	unsigned long vsid;
++
++	if (mem_init_done) {
++		pgdp = pgd_offset_k(ea);
++		pudp = pud_alloc(&init_mm, pgdp, ea);
++		if (!pudp)
++			return -ENOMEM;
++		pmdp = pmd_alloc(&init_mm, pudp, ea);
++		if (!pmdp)
++			return -ENOMEM;
++		ptep = pte_alloc_kernel(pmdp, ea);
++		if (!ptep)
++			return -ENOMEM;
++		set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
++							  __pgprot(flags)));
++	} else {
++		unsigned long va, vpn, hash, hpteg;
++
++		/*
++		 * If the mm subsystem is not fully up, we cannot create a
++		 * linux page table entry for this mapping.  Simply bolt an
++		 * entry in the hardware page table.
++		 */
++		vsid = get_kernel_vsid(ea);
++		va = (vsid << 28) | (ea & 0xFFFFFFF);
++		vpn = va >> PAGE_SHIFT;
++
++		hash = hpt_hash(vpn, 0);
++
++		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
++
++		/* Panic if a pte grpup is full */
++		if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT,
++				       HPTE_V_BOLTED,
++				       _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX)
++		    == -1) {
++			panic("map_io_page: could not insert mapping");
++		}
++	}
++	return 0;
++}
++
++
++static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
++			    unsigned long ea, unsigned long size,
++			    unsigned long flags)
++{
++	unsigned long i;
++
++	if ((flags & _PAGE_PRESENT) == 0)
++		flags |= pgprot_val(PAGE_KERNEL);
++
++	for (i = 0; i < size; i += PAGE_SIZE)
++		if (map_io_page(ea+i, pa+i, flags))
++			return NULL;
++
++	return (void __iomem *) (ea + (addr & ~PAGE_MASK));
++}
++
++
++void __iomem *
++ioremap(unsigned long addr, unsigned long size)
++{
++	return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
++}
++
++void __iomem * __ioremap(unsigned long addr, unsigned long size,
++			 unsigned long flags)
++{
++	unsigned long pa, ea;
++	void __iomem *ret;
++
++	/*
++	 * Choose an address to map it to.
++	 * Once the imalloc system is running, we use it.
++	 * Before that, we map using addresses going
++	 * up from ioremap_bot.  imalloc will use
++	 * the addresses from ioremap_bot through
++	 * IMALLOC_END
++	 * 
++	 */
++	pa = addr & PAGE_MASK;
++	size = PAGE_ALIGN(addr + size) - pa;
++
++	if (size == 0)
++		return NULL;
++
++	if (mem_init_done) {
++		struct vm_struct *area;
++		area = im_get_free_area(size);
++		if (area == NULL)
++			return NULL;
++		ea = (unsigned long)(area->addr);
++		ret = __ioremap_com(addr, pa, ea, size, flags);
++		if (!ret)
++			im_free(area->addr);
++	} else {
++		ea = ioremap_bot;
++		ret = __ioremap_com(addr, pa, ea, size, flags);
++		if (ret)
++			ioremap_bot += size;
++	}
++	return ret;
++}
++
++#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
++
++int __ioremap_explicit(unsigned long pa, unsigned long ea,
++		       unsigned long size, unsigned long flags)
++{
++	struct vm_struct *area;
++	void __iomem *ret;
++	
++	/* For now, require page-aligned values for pa, ea, and size */
++	if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
++	    !IS_PAGE_ALIGNED(size)) {
++		printk(KERN_ERR	"unaligned value in %s\n", __FUNCTION__);
++		return 1;
++	}
++	
++	if (!mem_init_done) {
++		/* Two things to consider in this case:
++		 * 1) No records will be kept (imalloc, etc) that the region
++		 *    has been remapped
++		 * 2) It won't be easy to iounmap() the region later (because
++		 *    of 1)
++		 */
++		;
++	} else {
++		area = im_get_area(ea, size,
++			IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS);
++		if (area == NULL) {
++			/* Expected when PHB-dlpar is in play */
++			return 1;
++		}
++		if (ea != (unsigned long) area->addr) {
++			printk(KERN_ERR "unexpected addr return from "
++			       "im_get_area\n");
++			return 1;
++		}
++	}
++	
++	ret = __ioremap_com(pa, pa, ea, size, flags);
++	if (ret == NULL) {
++		printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
++		return 1;
++	}
++	if (ret != (void *) ea) {
++		printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
++		return 1;
++	}
++
++	return 0;
++}
++
++/*  
++ * Unmap an IO region and remove it from imalloc'd list.
++ * Access to IO memory should be serialized by driver.
++ * This code is modeled after vmalloc code - unmap_vm_area()
++ *
++ * XXX	what about calls before mem_init_done (ie python_countermeasures())
++ */
++void iounmap(volatile void __iomem *token)
++{
++	void *addr;
++
++	if (!mem_init_done)
++		return;
++	
++	addr = (void *) ((unsigned long __force) token & PAGE_MASK);
++
++	im_free(addr);
++}
++
++static int iounmap_subset_regions(unsigned long addr, unsigned long size)
++{
++	struct vm_struct *area;
++
++	/* Check whether subsets of this region exist */
++	area = im_get_area(addr, size, IM_REGION_SUPERSET);
++	if (area == NULL)
++		return 1;
++
++	while (area) {
++		iounmap((void __iomem *) area->addr);
++		area = im_get_area(addr, size,
++				IM_REGION_SUPERSET);
++	}
++
++	return 0;
++}
++
++int iounmap_explicit(volatile void __iomem *start, unsigned long size)
++{
++	struct vm_struct *area;
++	unsigned long addr;
++	int rc;
++	
++	addr = (unsigned long __force) start & PAGE_MASK;
++
++	/* Verify that the region either exists or is a subset of an existing
++	 * region.  In the latter case, split the parent region to create 
++	 * the exact region 
++	 */
++	area = im_get_area(addr, size, 
++			    IM_REGION_EXISTS | IM_REGION_SUBSET);
++	if (area == NULL) {
++		/* Determine whether subset regions exist.  If so, unmap */
++		rc = iounmap_subset_regions(addr, size);
++		if (rc) {
++			printk(KERN_ERR
++			       "%s() cannot unmap nonexistent range 0x%lx\n",
++ 				__FUNCTION__, addr);
++			return 1;
++		}
++	} else {
++		iounmap((void __iomem *) area->addr);
++	}
++	/*
++	 * FIXME! This can't be right:
++	iounmap(area->addr);
++	 * Maybe it should be "iounmap(area);"
++	 */
++	return 0;
++}
++
++#endif
++
++EXPORT_SYMBOL(ioremap);
++EXPORT_SYMBOL(__ioremap);
++EXPORT_SYMBOL(iounmap);
++
++void __iomem * reserve_phb_iospace(unsigned long size)
++{
++	void __iomem *virt_addr;
++		
++	if (phbs_io_bot >= IMALLOC_BASE) 
++		panic("reserve_phb_iospace(): phb io space overflow\n");
++			
++	virt_addr = (void __iomem *) phbs_io_bot;
++	phbs_io_bot += size;
++
++	return virt_addr;
++}
+diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/ppc_mmu_32.c
+@@ -0,0 +1,285 @@
++/*
++ * This file contains the routines for handling the MMU on those
++ * PowerPC implementations where the MMU substantially follows the
++ * architecture specification.  This includes the 6xx, 7xx, 7xxx,
++ * 8260, and POWER3 implementations but excludes the 8xx and 4xx.
++ *  -- paulus
++ *
++ *  Derived from arch/ppc/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/mm.h>
++#include <linux/init.h>
++#include <linux/highmem.h>
++
++#include <asm/prom.h>
++#include <asm/mmu.h>
++#include <asm/machdep.h>
++#include <asm/lmb.h>
++
++#include "mmu_decl.h"
++
++PTE *Hash, *Hash_end;
++unsigned long Hash_size, Hash_mask;
++unsigned long _SDR1;
++
++union ubat {			/* BAT register values to be loaded */
++	BAT	bat;
++#ifdef CONFIG_PPC64BRIDGE
++	u64	word[2];
++#else
++	u32	word[2];
++#endif
++} BATS[4][2];			/* 4 pairs of IBAT, DBAT */
++
++struct batrange {		/* stores address ranges mapped by BATs */
++	unsigned long start;
++	unsigned long limit;
++	unsigned long phys;
++} bat_addrs[4];
++
++/*
++ * Return PA for this VA if it is mapped by a BAT, or 0
++ */
++unsigned long v_mapped_by_bats(unsigned long va)
++{
++	int b;
++	for (b = 0; b < 4; ++b)
++		if (va >= bat_addrs[b].start && va < bat_addrs[b].limit)
++			return bat_addrs[b].phys + (va - bat_addrs[b].start);
++	return 0;
++}
++
++/*
++ * Return VA for a given PA or 0 if not mapped
++ */
++unsigned long p_mapped_by_bats(unsigned long pa)
++{
++	int b;
++	for (b = 0; b < 4; ++b)
++		if (pa >= bat_addrs[b].phys
++	    	    && pa < (bat_addrs[b].limit-bat_addrs[b].start)
++		              +bat_addrs[b].phys)
++			return bat_addrs[b].start+(pa-bat_addrs[b].phys);
++	return 0;
++}
++
++unsigned long __init mmu_mapin_ram(void)
++{
++#ifdef CONFIG_POWER4
++	return 0;
++#else
++	unsigned long tot, bl, done;
++	unsigned long max_size = (256<<20);
++	unsigned long align;
++
++	if (__map_without_bats)
++		return 0;
++
++	/* Set up BAT2 and if necessary BAT3 to cover RAM. */
++
++	/* Make sure we don't map a block larger than the
++	   smallest alignment of the physical address. */
++	/* alignment of PPC_MEMSTART */
++	align = ~(PPC_MEMSTART-1) & PPC_MEMSTART;
++	/* set BAT block size to MIN(max_size, align) */
++	if (align && align < max_size)
++		max_size = align;
++
++	tot = total_lowmem;
++	for (bl = 128<<10; bl < max_size; bl <<= 1) {
++		if (bl * 2 > tot)
++			break;
++	}
++
++	setbat(2, KERNELBASE, PPC_MEMSTART, bl, _PAGE_RAM);
++	done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
++	if ((done < tot) && !bat_addrs[3].limit) {
++		/* use BAT3 to cover a bit more */
++		tot -= done;
++		for (bl = 128<<10; bl < max_size; bl <<= 1)
++			if (bl * 2 > tot)
++				break;
++		setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bl, _PAGE_RAM);
++		done = (unsigned long)bat_addrs[3].limit - KERNELBASE + 1;
++	}
++
++	return done;
++#endif
++}
++
++/*
++ * Set up one of the I/D BAT (block address translation) register pairs.
++ * The parameters are not checked; in particular size must be a power
++ * of 2 between 128k and 256M.
++ */
++void __init setbat(int index, unsigned long virt, unsigned long phys,
++		   unsigned int size, int flags)
++{
++	unsigned int bl;
++	int wimgxpp;
++	union ubat *bat = BATS[index];
++
++	if (((flags & _PAGE_NO_CACHE) == 0) &&
++	    cpu_has_feature(CPU_FTR_NEED_COHERENT))
++		flags |= _PAGE_COHERENT;
++
++	bl = (size >> 17) - 1;
++	if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
++		/* 603, 604, etc. */
++		/* Do DBAT first */
++		wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
++				   | _PAGE_COHERENT | _PAGE_GUARDED);
++		wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
++		bat[1].word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
++		bat[1].word[1] = phys | wimgxpp;
++#ifndef CONFIG_KGDB /* want user access for breakpoints */
++		if (flags & _PAGE_USER)
++#endif
++			bat[1].bat.batu.vp = 1;
++		if (flags & _PAGE_GUARDED) {
++			/* G bit must be zero in IBATs */
++			bat[0].word[0] = bat[0].word[1] = 0;
++		} else {
++			/* make IBAT same as DBAT */
++			bat[0] = bat[1];
++		}
++	} else {
++		/* 601 cpu */
++		if (bl > BL_8M)
++			bl = BL_8M;
++		wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
++				   | _PAGE_COHERENT);
++		wimgxpp |= (flags & _PAGE_RW)?
++			((flags & _PAGE_USER)? PP_RWRW: PP_RWXX): PP_RXRX;
++		bat->word[0] = virt | wimgxpp | 4;	/* Ks=0, Ku=1 */
++		bat->word[1] = phys | bl | 0x40;	/* V=1 */
++	}
++
++	bat_addrs[index].start = virt;
++	bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1;
++	bat_addrs[index].phys = phys;
++}
++
++/*
++ * Initialize the hash table and patch the instructions in hashtable.S.
++ */
++void __init MMU_init_hw(void)
++{
++	unsigned int hmask, mb, mb2;
++	unsigned int n_hpteg, lg_n_hpteg;
++
++	extern unsigned int hash_page_patch_A[];
++	extern unsigned int hash_page_patch_B[], hash_page_patch_C[];
++	extern unsigned int hash_page[];
++	extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[];
++
++	if (!cpu_has_feature(CPU_FTR_HPTE_TABLE)) {
++		/*
++		 * Put a blr (procedure return) instruction at the
++		 * start of hash_page, since we can still get DSI
++		 * exceptions on a 603.
++		 */
++		hash_page[0] = 0x4e800020;
++		flush_icache_range((unsigned long) &hash_page[0],
++				   (unsigned long) &hash_page[1]);
++		return;
++	}
++
++	if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
++
++#ifdef CONFIG_PPC64BRIDGE
++#define LG_HPTEG_SIZE	7		/* 128 bytes per HPTEG */
++#define SDR1_LOW_BITS	(lg_n_hpteg - 11)
++#define MIN_N_HPTEG	2048		/* min 256kB hash table */
++#else
++#define LG_HPTEG_SIZE	6		/* 64 bytes per HPTEG */
++#define SDR1_LOW_BITS	((n_hpteg - 1) >> 10)
++#define MIN_N_HPTEG	1024		/* min 64kB hash table */
++#endif
++
++	/*
++	 * Allow 1 HPTE (1/8 HPTEG) for each page of memory.
++	 * This is less than the recommended amount, but then
++	 * Linux ain't AIX.
++	 */
++	n_hpteg = total_memory / (PAGE_SIZE * 8);
++	if (n_hpteg < MIN_N_HPTEG)
++		n_hpteg = MIN_N_HPTEG;
++	lg_n_hpteg = __ilog2(n_hpteg);
++	if (n_hpteg & (n_hpteg - 1)) {
++		++lg_n_hpteg;		/* round up if not power of 2 */
++		n_hpteg = 1 << lg_n_hpteg;
++	}
++	Hash_size = n_hpteg << LG_HPTEG_SIZE;
++
++	/*
++	 * Find some memory for the hash table.
++	 */
++	if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
++	Hash = __va(lmb_alloc_base(Hash_size, Hash_size,
++				   __initial_memory_limit));
++	cacheable_memzero(Hash, Hash_size);
++	_SDR1 = __pa(Hash) | SDR1_LOW_BITS;
++
++	Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
++
++	printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
++	       total_memory >> 20, Hash_size >> 10, Hash);
++
++
++	/*
++	 * Patch up the instructions in hashtable.S:create_hpte
++	 */
++	if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345);
++	Hash_mask = n_hpteg - 1;
++	hmask = Hash_mask >> (16 - LG_HPTEG_SIZE);
++	mb2 = mb = 32 - LG_HPTEG_SIZE - lg_n_hpteg;
++	if (lg_n_hpteg > 16)
++		mb2 = 16 - LG_HPTEG_SIZE;
++
++	hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff)
++		| ((unsigned int)(Hash) >> 16);
++	hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0) | (mb << 6);
++	hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0) | (mb2 << 6);
++	hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff) | hmask;
++	hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff) | hmask;
++
++	/*
++	 * Ensure that the locations we've patched have been written
++	 * out from the data cache and invalidated in the instruction
++	 * cache, on those machines with split caches.
++	 */
++	flush_icache_range((unsigned long) &hash_page_patch_A[0],
++			   (unsigned long) &hash_page_patch_C[1]);
++
++	/*
++	 * Patch up the instructions in hashtable.S:flush_hash_page
++	 */
++	flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff)
++		| ((unsigned int)(Hash) >> 16);
++	flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0) | (mb << 6);
++	flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0) | (mb2 << 6);
++	flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff) | hmask;
++	flush_icache_range((unsigned long) &flush_hash_patch_A[0],
++			   (unsigned long) &flush_hash_patch_B[1]);
++
++	if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205);
++}
+diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/slb.c
+@@ -0,0 +1,158 @@
++/*
++ * PowerPC64 SLB support.
++ *
++ * Copyright (C) 2004 David Gibson <dwg at au.ibm.com>, IBM
++ * Based on earlier code writteh by:
++ * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
++ *    Copyright (c) 2001 Dave Engebretsen
++ * Copyright (C) 2002 Anton Blanchard <anton at au.ibm.com>, 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/config.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/mmu_context.h>
++#include <asm/paca.h>
++#include <asm/cputable.h>
++
++extern void slb_allocate(unsigned long ea);
++
++static inline unsigned long mk_esid_data(unsigned long ea, unsigned long slot)
++{
++	return (ea & ESID_MASK) | SLB_ESID_V | slot;
++}
++
++static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags)
++{
++	return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
++}
++
++static inline void create_slbe(unsigned long ea, unsigned long flags,
++			       unsigned long entry)
++{
++	asm volatile("slbmte  %0,%1" :
++		     : "r" (mk_vsid_data(ea, flags)),
++		       "r" (mk_esid_data(ea, entry))
++		     : "memory" );
++}
++
++static void slb_flush_and_rebolt(void)
++{
++	/* If you change this make sure you change SLB_NUM_BOLTED
++	 * appropriately too. */
++	unsigned long ksp_flags = SLB_VSID_KERNEL;
++	unsigned long ksp_esid_data;
++
++	WARN_ON(!irqs_disabled());
++
++	if (cpu_has_feature(CPU_FTR_16M_PAGE))
++		ksp_flags |= SLB_VSID_L;
++
++	ksp_esid_data = mk_esid_data(get_paca()->kstack, 2);
++	if ((ksp_esid_data & ESID_MASK) == KERNELBASE)
++		ksp_esid_data &= ~SLB_ESID_V;
++
++	/* We need to do this all in asm, so we're sure we don't touch
++	 * the stack between the slbia and rebolting it. */
++	asm volatile("isync\n"
++		     "slbia\n"
++		     /* Slot 1 - first VMALLOC segment */
++		     "slbmte	%0,%1\n"
++		     /* Slot 2 - kernel stack */
++		     "slbmte	%2,%3\n"
++		     "isync"
++		     :: "r"(mk_vsid_data(VMALLOCBASE, SLB_VSID_KERNEL)),
++		        "r"(mk_esid_data(VMALLOCBASE, 1)),
++		        "r"(mk_vsid_data(ksp_esid_data, ksp_flags)),
++		        "r"(ksp_esid_data)
++		     : "memory");
++}
++
++/* Flush all user entries from the segment table of the current processor. */
++void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
++{
++	unsigned long offset = get_paca()->slb_cache_ptr;
++	unsigned long esid_data = 0;
++	unsigned long pc = KSTK_EIP(tsk);
++	unsigned long stack = KSTK_ESP(tsk);
++	unsigned long unmapped_base;
++
++	if (offset <= SLB_CACHE_ENTRIES) {
++		int i;
++		asm volatile("isync" : : : "memory");
++		for (i = 0; i < offset; i++) {
++			esid_data = ((unsigned long)get_paca()->slb_cache[i]
++				<< SID_SHIFT) | SLBIE_C;
++			asm volatile("slbie %0" : : "r" (esid_data));
++		}
++		asm volatile("isync" : : : "memory");
++	} else {
++		slb_flush_and_rebolt();
++	}
++
++	/* Workaround POWER5 < DD2.1 issue */
++	if (offset == 1 || offset > SLB_CACHE_ENTRIES)
++		asm volatile("slbie %0" : : "r" (esid_data));
++
++	get_paca()->slb_cache_ptr = 0;
++	get_paca()->context = mm->context;
++
++	/*
++	 * preload some userspace segments into the SLB.
++	 */
++	if (test_tsk_thread_flag(tsk, TIF_32BIT))
++		unmapped_base = TASK_UNMAPPED_BASE_USER32;
++	else
++		unmapped_base = TASK_UNMAPPED_BASE_USER64;
++
++	if (pc >= KERNELBASE)
++		return;
++	slb_allocate(pc);
++
++	if (GET_ESID(pc) == GET_ESID(stack))
++		return;
++
++	if (stack >= KERNELBASE)
++		return;
++	slb_allocate(stack);
++
++	if ((GET_ESID(pc) == GET_ESID(unmapped_base))
++	    || (GET_ESID(stack) == GET_ESID(unmapped_base)))
++		return;
++
++	if (unmapped_base >= KERNELBASE)
++		return;
++	slb_allocate(unmapped_base);
++}
++
++void slb_initialize(void)
++{
++	/* On iSeries the bolted entries have already been set up by
++	 * the hypervisor from the lparMap data in head.S */
++#ifndef CONFIG_PPC_ISERIES
++	unsigned long flags = SLB_VSID_KERNEL;
++
++ 	/* Invalidate the entire SLB (even slot 0) & all the ERATS */
++ 	if (cpu_has_feature(CPU_FTR_16M_PAGE))
++ 		flags |= SLB_VSID_L;
++
++ 	asm volatile("isync":::"memory");
++ 	asm volatile("slbmte  %0,%0"::"r" (0) : "memory");
++	asm volatile("isync; slbia; isync":::"memory");
++	create_slbe(KERNELBASE, flags, 0);
++	create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1);
++	/* We don't bolt the stack for the time being - we're in boot,
++	 * so the stack is in the bolted segment.  By the time it goes
++	 * elsewhere, we'll call _switch() which will bolt in the new
++	 * one. */
++	asm volatile("isync":::"memory");
++#endif
++
++	get_paca()->stab_rr = SLB_NUM_BOLTED;
++}
+diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/slb_low.S
+@@ -0,0 +1,151 @@
++/*
++ * arch/ppc64/mm/slb_low.S
++ *
++ * Low-level SLB routines
++ *
++ * Copyright (C) 2004 David Gibson <dwg at au.ibm.com>, IBM
++ *
++ * Based on earlier C version:
++ * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
++ *    Copyright (c) 2001 Dave Engebretsen
++ * Copyright (C) 2002 Anton Blanchard <anton at au.ibm.com>, 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/config.h>
++#include <asm/processor.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++#include <asm/cputable.h>
++
++/* void slb_allocate(unsigned long ea);
++ *
++ * Create an SLB entry for the given EA (user or kernel).
++ * 	r3 = faulting address, r13 = PACA
++ *	r9, r10, r11 are clobbered by this function
++ * No other registers are examined or changed.
++ */
++_GLOBAL(slb_allocate)
++	/*
++	 * First find a slot, round robin. Previously we tried to find
++	 * a free slot first but that took too long. Unfortunately we
++	 * dont have any LRU information to help us choose a slot.
++	 */
++#ifdef CONFIG_PPC_ISERIES
++	/*
++	 * On iSeries, the "bolted" stack segment can be cast out on
++	 * shared processor switch so we need to check for a miss on
++	 * it and restore it to the right slot.
++	 */
++	ld	r9,PACAKSAVE(r13)
++	clrrdi	r9,r9,28
++	clrrdi	r11,r3,28
++	li	r10,SLB_NUM_BOLTED-1	/* Stack goes in last bolted slot */
++	cmpld	r9,r11
++	beq	3f
++#endif /* CONFIG_PPC_ISERIES */
++
++	ld	r10,PACASTABRR(r13)
++	addi	r10,r10,1
++	/* use a cpu feature mask if we ever change our slb size */
++	cmpldi	r10,SLB_NUM_ENTRIES
++
++	blt+	4f
++	li	r10,SLB_NUM_BOLTED
++
++4:
++	std	r10,PACASTABRR(r13)
++3:
++	/* r3 = faulting address, r10 = entry */
++
++	srdi	r9,r3,60		/* get region */
++	srdi	r3,r3,28		/* get esid */
++	cmpldi	cr7,r9,0xc		/* cmp KERNELBASE for later use */
++
++	rldimi	r10,r3,28,0		/* r10= ESID<<28 | entry */
++	oris	r10,r10,SLB_ESID_V at h	/* r10 |= SLB_ESID_V */
++
++	/* r3 = esid, r10 = esid_data, cr7 = <>KERNELBASE */
++
++	blt	cr7,0f			/* user or kernel? */
++
++	/* kernel address: proto-VSID = ESID */
++	/* WARNING - MAGIC: we don't use the VSID 0xfffffffff, but
++	 * this code will generate the protoVSID 0xfffffffff for the
++	 * top segment.  That's ok, the scramble below will translate
++	 * it to VSID 0, which is reserved as a bad VSID - one which
++	 * will never have any pages in it.  */
++	li	r11,SLB_VSID_KERNEL
++BEGIN_FTR_SECTION
++	bne	cr7,9f
++	li	r11,(SLB_VSID_KERNEL|SLB_VSID_L)
++END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
++	b	9f
++
++0:	/* user address: proto-VSID = context<<15 | ESID */
++	srdi.	r9,r3,USER_ESID_BITS
++	bne-	8f			/* invalid ea bits set */
++
++#ifdef CONFIG_HUGETLB_PAGE
++BEGIN_FTR_SECTION
++	lhz	r9,PACAHIGHHTLBAREAS(r13)
++	srdi	r11,r3,(HTLB_AREA_SHIFT-SID_SHIFT)
++	srd	r9,r9,r11
++	lhz	r11,PACALOWHTLBAREAS(r13)
++	srd	r11,r11,r3
++	or	r9,r9,r11
++END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
++#endif /* CONFIG_HUGETLB_PAGE */
++
++	li	r11,SLB_VSID_USER
++
++#ifdef CONFIG_HUGETLB_PAGE
++BEGIN_FTR_SECTION
++	rldimi	r11,r9,8,55		/* shift masked bit into SLB_VSID_L */
++END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
++#endif /* CONFIG_HUGETLB_PAGE */
++
++	ld	r9,PACACONTEXTID(r13)
++	rldimi	r3,r9,USER_ESID_BITS,0
++
++9:	/* r3 = protovsid, r11 = flags, r10 = esid_data, cr7 = <>KERNELBASE */
++	ASM_VSID_SCRAMBLE(r3,r9)
++
++	rldimi	r11,r3,SLB_VSID_SHIFT,16	/* combine VSID and flags */
++
++	/*
++	 * No need for an isync before or after this slbmte. The exception
++	 * we enter with and the rfid we exit with are context synchronizing.
++	 */
++	slbmte	r11,r10
++
++	bgelr	cr7			/* we're done for kernel addresses */
++
++	/* Update the slb cache */
++	lhz	r3,PACASLBCACHEPTR(r13)	/* offset = paca->slb_cache_ptr */
++	cmpldi	r3,SLB_CACHE_ENTRIES
++	bge	1f
++
++	/* still room in the slb cache */
++	sldi	r11,r3,1		/* r11 = offset * sizeof(u16) */
++	rldicl	r10,r10,36,28		/* get low 16 bits of the ESID */
++	add	r11,r11,r13		/* r11 = (u16 *)paca + offset */
++	sth	r10,PACASLBCACHE(r11)	/* paca->slb_cache[offset] = esid */
++	addi	r3,r3,1			/* offset++ */
++	b	2f
++1:					/* offset >= SLB_CACHE_ENTRIES */
++	li	r3,SLB_CACHE_ENTRIES+1
++2:
++	sth	r3,PACASLBCACHEPTR(r13)	/* paca->slb_cache_ptr = offset */
++	blr
++
++8:	/* invalid EA */
++	li	r3,0			/* BAD_VSID */
++	li	r11,SLB_VSID_USER	/* flags don't much matter */
++	b	9b
+diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/stab.c
+@@ -0,0 +1,279 @@
++/*
++ * PowerPC64 Segment Translation Support.
++ *
++ * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
++ *    Copyright (c) 2001 Dave Engebretsen
++ *
++ * Copyright (C) 2002 Anton Blanchard <anton at au.ibm.com>, 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/config.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/mmu_context.h>
++#include <asm/paca.h>
++#include <asm/cputable.h>
++#include <asm/lmb.h>
++#include <asm/abs_addr.h>
++
++struct stab_entry {
++	unsigned long esid_data;
++	unsigned long vsid_data;
++};
++
++/* Both the segment table and SLB code uses the following cache */
++#define NR_STAB_CACHE_ENTRIES 8
++DEFINE_PER_CPU(long, stab_cache_ptr);
++DEFINE_PER_CPU(long, stab_cache[NR_STAB_CACHE_ENTRIES]);
++
++/*
++ * Create a segment table entry for the given esid/vsid pair.
++ */
++static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
++{
++	unsigned long esid_data, vsid_data;
++	unsigned long entry, group, old_esid, castout_entry, i;
++	unsigned int global_entry;
++	struct stab_entry *ste, *castout_ste;
++	unsigned long kernel_segment = (esid << SID_SHIFT) >= KERNELBASE;
++
++	vsid_data = vsid << STE_VSID_SHIFT;
++	esid_data = esid << SID_SHIFT | STE_ESID_KP | STE_ESID_V;
++	if (! kernel_segment)
++		esid_data |= STE_ESID_KS;
++
++	/* Search the primary group first. */
++	global_entry = (esid & 0x1f) << 3;
++	ste = (struct stab_entry *)(stab | ((esid & 0x1f) << 7));
++
++	/* Find an empty entry, if one exists. */
++	for (group = 0; group < 2; group++) {
++		for (entry = 0; entry < 8; entry++, ste++) {
++			if (!(ste->esid_data & STE_ESID_V)) {
++				ste->vsid_data = vsid_data;
++				asm volatile("eieio":::"memory");
++				ste->esid_data = esid_data;
++				return (global_entry | entry);
++			}
++		}
++		/* Now search the secondary group. */
++		global_entry = ((~esid) & 0x1f) << 3;
++		ste = (struct stab_entry *)(stab | (((~esid) & 0x1f) << 7));
++	}
++
++	/*
++	 * Could not find empty entry, pick one with a round robin selection.
++	 * Search all entries in the two groups.
++	 */
++	castout_entry = get_paca()->stab_rr;
++	for (i = 0; i < 16; i++) {
++		if (castout_entry < 8) {
++			global_entry = (esid & 0x1f) << 3;
++			ste = (struct stab_entry *)(stab | ((esid & 0x1f) << 7));
++			castout_ste = ste + castout_entry;
++		} else {
++			global_entry = ((~esid) & 0x1f) << 3;
++			ste = (struct stab_entry *)(stab | (((~esid) & 0x1f) << 7));
++			castout_ste = ste + (castout_entry - 8);
++		}
++
++		/* Dont cast out the first kernel segment */
++		if ((castout_ste->esid_data & ESID_MASK) != KERNELBASE)
++			break;
++
++		castout_entry = (castout_entry + 1) & 0xf;
++	}
++
++	get_paca()->stab_rr = (castout_entry + 1) & 0xf;
++
++	/* Modify the old entry to the new value. */
++
++	/* Force previous translations to complete. DRENG */
++	asm volatile("isync" : : : "memory");
++
++	old_esid = castout_ste->esid_data >> SID_SHIFT;
++	castout_ste->esid_data = 0;		/* Invalidate old entry */
++
++	asm volatile("sync" : : : "memory");    /* Order update */
++
++	castout_ste->vsid_data = vsid_data;
++	asm volatile("eieio" : : : "memory");   /* Order update */
++	castout_ste->esid_data = esid_data;
++
++	asm volatile("slbie  %0" : : "r" (old_esid << SID_SHIFT));
++	/* Ensure completion of slbie */
++	asm volatile("sync" : : : "memory");
++
++	return (global_entry | (castout_entry & 0x7));
++}
++
++/*
++ * Allocate a segment table entry for the given ea and mm
++ */
++static int __ste_allocate(unsigned long ea, struct mm_struct *mm)
++{
++	unsigned long vsid;
++	unsigned char stab_entry;
++	unsigned long offset;
++
++	/* Kernel or user address? */
++	if (ea >= KERNELBASE) {
++		vsid = get_kernel_vsid(ea);
++	} else {
++		if ((ea >= TASK_SIZE_USER64) || (! mm))
++			return 1;
++
++		vsid = get_vsid(mm->context.id, ea);
++	}
++
++	stab_entry = make_ste(get_paca()->stab_addr, GET_ESID(ea), vsid);
++
++	if (ea < KERNELBASE) {
++		offset = __get_cpu_var(stab_cache_ptr);
++		if (offset < NR_STAB_CACHE_ENTRIES)
++			__get_cpu_var(stab_cache[offset++]) = stab_entry;
++		else
++			offset = NR_STAB_CACHE_ENTRIES+1;
++		__get_cpu_var(stab_cache_ptr) = offset;
++
++		/* Order update */
++		asm volatile("sync":::"memory");
++	}
++
++	return 0;
++}
++
++int ste_allocate(unsigned long ea)
++{
++	return __ste_allocate(ea, current->mm);
++}
++
++/*
++ * Do the segment table work for a context switch: flush all user
++ * entries from the table, then preload some probably useful entries
++ * for the new task
++ */
++void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
++{
++	struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr;
++	struct stab_entry *ste;
++	unsigned long offset = __get_cpu_var(stab_cache_ptr);
++	unsigned long pc = KSTK_EIP(tsk);
++	unsigned long stack = KSTK_ESP(tsk);
++	unsigned long unmapped_base;
++
++	/* Force previous translations to complete. DRENG */
++	asm volatile("isync" : : : "memory");
++
++	if (offset <= NR_STAB_CACHE_ENTRIES) {
++		int i;
++
++		for (i = 0; i < offset; i++) {
++			ste = stab + __get_cpu_var(stab_cache[i]);
++			ste->esid_data = 0; /* invalidate entry */
++		}
++	} else {
++		unsigned long entry;
++
++		/* Invalidate all entries. */
++		ste = stab;
++
++		/* Never flush the first entry. */
++		ste += 1;
++		for (entry = 1;
++		     entry < (PAGE_SIZE / sizeof(struct stab_entry));
++		     entry++, ste++) {
++			unsigned long ea;
++			ea = ste->esid_data & ESID_MASK;
++			if (ea < KERNELBASE) {
++				ste->esid_data = 0;
++			}
++		}
++	}
++
++	asm volatile("sync; slbia; sync":::"memory");
++
++	__get_cpu_var(stab_cache_ptr) = 0;
++
++	/* Now preload some entries for the new task */
++	if (test_tsk_thread_flag(tsk, TIF_32BIT))
++		unmapped_base = TASK_UNMAPPED_BASE_USER32;
++	else
++		unmapped_base = TASK_UNMAPPED_BASE_USER64;
++
++	__ste_allocate(pc, mm);
++
++	if (GET_ESID(pc) == GET_ESID(stack))
++		return;
++
++	__ste_allocate(stack, mm);
++
++	if ((GET_ESID(pc) == GET_ESID(unmapped_base))
++	    || (GET_ESID(stack) == GET_ESID(unmapped_base)))
++		return;
++
++	__ste_allocate(unmapped_base, mm);
++
++	/* Order update */
++	asm volatile("sync" : : : "memory");
++}
++
++extern void slb_initialize(void);
++
++/*
++ * Allocate segment tables for secondary CPUs.  These must all go in
++ * the first (bolted) segment, so that do_stab_bolted won't get a
++ * recursive segment miss on the segment table itself.
++ */
++void stabs_alloc(void)
++{
++	int cpu;
++
++	if (cpu_has_feature(CPU_FTR_SLB))
++		return;
++
++	for_each_cpu(cpu) {
++		unsigned long newstab;
++
++		if (cpu == 0)
++			continue; /* stab for CPU 0 is statically allocated */
++
++		newstab = lmb_alloc_base(PAGE_SIZE, PAGE_SIZE, 1<<SID_SHIFT);
++		if (! newstab)
++			panic("Unable to allocate segment table for CPU %d.\n",
++			      cpu);
++
++		newstab += KERNELBASE;
++
++		memset((void *)newstab, 0, PAGE_SIZE);
++
++		paca[cpu].stab_addr = newstab;
++		paca[cpu].stab_real = virt_to_abs(newstab);
++		printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx virtual, 0x%lx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
++	}
++}
++
++/*
++ * Build an entry for the base kernel segment and put it into
++ * the segment table or SLB.  All other segment table or SLB
++ * entries are faulted in.
++ */
++void stab_initialize(unsigned long stab)
++{
++	unsigned long vsid = get_kernel_vsid(KERNELBASE);
++
++	if (cpu_has_feature(CPU_FTR_SLB)) {
++		slb_initialize();
++	} else {
++		asm volatile("isync; slbia; isync":::"memory");
++		make_ste(stab, GET_ESID(KERNELBASE), vsid);
++
++		/* Order update */
++		asm volatile("sync":::"memory");
++	}
++}
+diff --git a/arch/powerpc/mm/tlb_32.c b/arch/powerpc/mm/tlb_32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/tlb_32.c
+@@ -0,0 +1,183 @@
++/*
++ * This file contains the routines for TLB flushing.
++ * On machines where the MMU uses a hash table to store virtual to
++ * physical translations, these routines flush entries from the
++ * hash table also.
++ *  -- paulus
++ *
++ *  Derived from arch/ppc/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/mm.h>
++#include <linux/init.h>
++#include <linux/highmem.h>
++#include <asm/tlbflush.h>
++#include <asm/tlb.h>
++
++#include "mmu_decl.h"
++
++/*
++ * Called when unmapping pages to flush entries from the TLB/hash table.
++ */
++void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr)
++{
++	unsigned long ptephys;
++
++	if (Hash != 0) {
++		ptephys = __pa(ptep) & PAGE_MASK;
++		flush_hash_pages(mm->context, addr, ptephys, 1);
++	}
++}
++
++/*
++ * Called by ptep_set_access_flags, must flush on CPUs for which the
++ * DSI handler can't just "fixup" the TLB on a write fault
++ */
++void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr)
++{
++	if (Hash != 0)
++		return;
++	_tlbie(addr);
++}
++
++/*
++ * Called at the end of a mmu_gather operation to make sure the
++ * TLB flush is completely done.
++ */
++void tlb_flush(struct mmu_gather *tlb)
++{
++	if (Hash == 0) {
++		/*
++		 * 603 needs to flush the whole TLB here since
++		 * it doesn't use a hash table.
++		 */
++		_tlbia();
++	}
++}
++
++/*
++ * TLB flushing:
++ *
++ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
++ *  - flush_tlb_page(vma, vmaddr) flushes one page
++ *  - flush_tlb_range(vma, start, end) flushes a range of pages
++ *  - flush_tlb_kernel_range(start, end) flushes kernel pages
++ *
++ * since the hardware hash table functions as an extension of the
++ * tlb as far as the linux tables are concerned, flush it too.
++ *    -- Cort
++ */
++
++/*
++ * 750 SMP is a Bad Idea because the 750 doesn't broadcast all
++ * the cache operations on the bus.  Hence we need to use an IPI
++ * to get the other CPU(s) to invalidate their TLBs.
++ */
++#ifdef CONFIG_SMP_750
++#define FINISH_FLUSH	smp_send_tlb_invalidate(0)
++#else
++#define FINISH_FLUSH	do { } while (0)
++#endif
++
++static void flush_range(struct mm_struct *mm, unsigned long start,
++			unsigned long end)
++{
++	pmd_t *pmd;
++	unsigned long pmd_end;
++	int count;
++	unsigned int ctx = mm->context;
++
++	if (Hash == 0) {
++		_tlbia();
++		return;
++	}
++	start &= PAGE_MASK;
++	if (start >= end)
++		return;
++	end = (end - 1) | ~PAGE_MASK;
++	pmd = pmd_offset(pgd_offset(mm, start), start);
++	for (;;) {
++		pmd_end = ((start + PGDIR_SIZE) & PGDIR_MASK) - 1;
++		if (pmd_end > end)
++			pmd_end = end;
++		if (!pmd_none(*pmd)) {
++			count = ((pmd_end - start) >> PAGE_SHIFT) + 1;
++			flush_hash_pages(ctx, start, pmd_val(*pmd), count);
++		}
++		if (pmd_end == end)
++			break;
++		start = pmd_end + 1;
++		++pmd;
++	}
++}
++
++/*
++ * Flush kernel TLB entries in the given range
++ */
++void flush_tlb_kernel_range(unsigned long start, unsigned long end)
++{
++	flush_range(&init_mm, start, end);
++	FINISH_FLUSH;
++}
++
++/*
++ * Flush all the (user) entries for the address space described by mm.
++ */
++void flush_tlb_mm(struct mm_struct *mm)
++{
++	struct vm_area_struct *mp;
++
++	if (Hash == 0) {
++		_tlbia();
++		return;
++	}
++
++	for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)
++		flush_range(mp->vm_mm, mp->vm_start, mp->vm_end);
++	FINISH_FLUSH;
++}
++
++void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
++{
++	struct mm_struct *mm;
++	pmd_t *pmd;
++
++	if (Hash == 0) {
++		_tlbie(vmaddr);
++		return;
++	}
++	mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm;
++	pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr);
++	if (!pmd_none(*pmd))
++		flush_hash_pages(mm->context, vmaddr, pmd_val(*pmd), 1);
++	FINISH_FLUSH;
++}
++
++/*
++ * For each address in the range, find the pte for the address
++ * and check _PAGE_HASHPTE bit; if it is set, find and destroy
++ * the corresponding HPTE.
++ */
++void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
++		     unsigned long end)
++{
++	flush_range(vma->vm_mm, start, end);
++	FINISH_FLUSH;
++}
+diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/mm/tlb_64.c
+@@ -0,0 +1,196 @@
++/*
++ * This file contains the routines for flushing entries from the
++ * TLB and MMU hash table.
++ *
++ *  Derived from arch/ppc64/mm/init.c:
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
++ *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
++ *    Copyright (C) 1996 Paul Mackerras
++ *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
++ *
++ *  Derived from "arch/i386/mm/init.c"
++ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
++ *
++ *  Dave Engebretsen <engebret at us.ibm.com>
++ *      Rework for PPC64 port.
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/mm.h>
++#include <linux/init.h>
++#include <linux/percpu.h>
++#include <linux/hardirq.h>
++#include <asm/pgalloc.h>
++#include <asm/tlbflush.h>
++#include <asm/tlb.h>
++#include <linux/highmem.h>
++
++DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
++
++/* This is declared as we are using the more or less generic
++ * include/asm-ppc64/tlb.h file -- tgall
++ */
++DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
++DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
++unsigned long pte_freelist_forced_free;
++
++struct pte_freelist_batch
++{
++	struct rcu_head	rcu;
++	unsigned int	index;
++	pgtable_free_t	tables[0];
++};
++
++DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
++unsigned long pte_freelist_forced_free;
++
++#define PTE_FREELIST_SIZE \
++	((PAGE_SIZE - sizeof(struct pte_freelist_batch)) \
++	  / sizeof(pgtable_free_t))
++
++#ifdef CONFIG_SMP
++static void pte_free_smp_sync(void *arg)
++{
++	/* Do nothing, just ensure we sync with all CPUs */
++}
++#endif
++
++/* This is only called when we are critically out of memory
++ * (and fail to get a page in pte_free_tlb).
++ */
++static void pgtable_free_now(pgtable_free_t pgf)
++{
++	pte_freelist_forced_free++;
++
++	smp_call_function(pte_free_smp_sync, NULL, 0, 1);
++
++	pgtable_free(pgf);
++}
++
++static void pte_free_rcu_callback(struct rcu_head *head)
++{
++	struct pte_freelist_batch *batch =
++		container_of(head, struct pte_freelist_batch, rcu);
++	unsigned int i;
++
++	for (i = 0; i < batch->index; i++)
++		pgtable_free(batch->tables[i]);
++
++	free_page((unsigned long)batch);
++}
++
++static void pte_free_submit(struct pte_freelist_batch *batch)
++{
++	INIT_RCU_HEAD(&batch->rcu);
++	call_rcu(&batch->rcu, pte_free_rcu_callback);
++}
++
++void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
++{
++	/* This is safe as we are holding page_table_lock */
++        cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
++	struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
++
++	if (atomic_read(&tlb->mm->mm_users) < 2 ||
++	    cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
++		pgtable_free(pgf);
++		return;
++	}
++
++	if (*batchp == NULL) {
++		*batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
++		if (*batchp == NULL) {
++			pgtable_free_now(pgf);
++			return;
++		}
++		(*batchp)->index = 0;
++	}
++	(*batchp)->tables[(*batchp)->index++] = pgf;
++	if ((*batchp)->index == PTE_FREELIST_SIZE) {
++		pte_free_submit(*batchp);
++		*batchp = NULL;
++	}
++}
++
++/*
++ * Update the MMU hash table to correspond with a change to
++ * a Linux PTE.  If wrprot is true, it is permissible to
++ * change the existing HPTE to read-only rather than removing it
++ * (if we remove it we should clear the _PTE_HPTEFLAGS bits).
++ */
++void hpte_update(struct mm_struct *mm, unsigned long addr,
++		 unsigned long pte, int wrprot)
++{
++	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
++	unsigned long vsid;
++	int i;
++
++	i = batch->index;
++
++	/*
++	 * This can happen when we are in the middle of a TLB batch and
++	 * we encounter memory pressure (eg copy_page_range when it tries
++	 * to allocate a new pte). If we have to reclaim memory and end
++	 * up scanning and resetting referenced bits then our batch context
++	 * will change mid stream.
++	 */
++	if (i != 0 && (mm != batch->mm || batch->large != pte_huge(pte))) {
++		flush_tlb_pending();
++		i = 0;
++	}
++	if (i == 0) {
++		batch->mm = mm;
++		batch->large = pte_huge(pte);
++	}
++	if (addr < KERNELBASE) {
++		vsid = get_vsid(mm->context.id, addr);
++		WARN_ON(vsid == 0);
++	} else
++		vsid = get_kernel_vsid(addr);
++	batch->vaddr[i] = (vsid << 28 ) | (addr & 0x0fffffff);
++	batch->pte[i] = __pte(pte);
++	batch->index = ++i;
++	if (i >= PPC64_TLB_BATCH_NR)
++		flush_tlb_pending();
++}
++
++void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
++{
++	int i;
++	int cpu;
++	cpumask_t tmp;
++	int local = 0;
++
++	BUG_ON(in_interrupt());
++
++	cpu = get_cpu();
++	i = batch->index;
++	tmp = cpumask_of_cpu(cpu);
++	if (cpus_equal(batch->mm->cpu_vm_mask, tmp))
++		local = 1;
++
++	if (i == 1)
++		flush_hash_page(batch->vaddr[0], batch->pte[0], local);
++	else
++		flush_hash_range(i, local);
++	batch->index = 0;
++	put_cpu();
++}
++
++void pte_free_finish(void)
++{
++	/* This is safe as we are holding page_table_lock */
++	struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
++
++	if (*batchp == NULL)
++		return;
++	pte_free_submit(*batchp);
++	*batchp = NULL;
++}
+diff --git a/arch/powerpc/oprofile/Kconfig b/arch/powerpc/oprofile/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/oprofile/Kconfig
+@@ -0,0 +1,23 @@
++
++menu "Profiling support"
++	depends on EXPERIMENTAL
++
++config PROFILING
++	bool "Profiling support (EXPERIMENTAL)"
++	help
++	  Say Y here to enable the extended profiling support mechanisms used
++	  by profilers such as OProfile.
++
++
++config OPROFILE
++	tristate "OProfile system profiling (EXPERIMENTAL)"
++	depends on PROFILING
++	help
++	  OProfile is a profiling system capable of profiling the
++	  whole system, include the kernel, kernel modules, libraries,
++	  and applications.
++
++	  If unsure, say N.
++
++endmenu
++
+diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/oprofile/Makefile
+@@ -0,0 +1,11 @@
++obj-$(CONFIG_OPROFILE) += oprofile.o
++
++DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
++		oprof.o cpu_buffer.o buffer_sync.o \
++		event_buffer.o oprofile_files.o \
++		oprofilefs.o oprofile_stats.o \
++		timer_int.o )
++
++oprofile-y := $(DRIVER_OBJS) common.o
++oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
++oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
+diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/oprofile/common.c
+@@ -0,0 +1,195 @@
++/*
++ * PPC 64 oprofile support:
++ * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, IBM
++ * PPC 32 oprofile support: (based on PPC 64 support)
++ * Copyright (C) Freescale Semiconductor, Inc 2004
++ *	Author: Andy Fleming
++ *
++ * Based on alpha version.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/oprofile.h>
++#ifndef __powerpc64__
++#include <linux/slab.h>
++#endif /* ! __powerpc64__ */
++#include <linux/init.h>
++#include <linux/smp.h>
++#include <linux/errno.h>
++#include <asm/ptrace.h>
++#include <asm/system.h>
++#include <asm/pmc.h>
++#include <asm/cputable.h>
++#include <asm/oprofile_impl.h>
++
++static struct op_powerpc_model *model;
++
++static struct op_counter_config ctr[OP_MAX_COUNTER];
++static struct op_system_config sys;
++
++#ifndef __powerpc64__
++static char *cpu_type;
++#endif /* ! __powerpc64__ */
++
++static void op_handle_interrupt(struct pt_regs *regs)
++{
++	model->handle_interrupt(regs, ctr);
++}
++
++static int op_powerpc_setup(void)
++{
++	int err;
++
++	/* Grab the hardware */
++	err = reserve_pmc_hardware(op_handle_interrupt);
++	if (err)
++		return err;
++
++	/* Pre-compute the values to stuff in the hardware registers.  */
++	model->reg_setup(ctr, &sys, model->num_counters);
++
++	/* Configure the registers on all cpus.  */
++#ifdef __powerpc64__
++	on_each_cpu(model->cpu_setup, NULL, 0, 1);
++#else /* __powerpc64__ */
++#if 0
++	/* FIXME: Make multi-cpu work */
++	on_each_cpu(model->reg_setup, NULL, 0, 1);
++#endif
++#endif /* __powerpc64__ */
++
++	return 0;
++}
++
++static void op_powerpc_shutdown(void)
++{
++	release_pmc_hardware();
++}
++
++static void op_powerpc_cpu_start(void *dummy)
++{
++	model->start(ctr);
++}
++
++static int op_powerpc_start(void)
++{
++	on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1);
++	return 0;
++}
++
++static inline void op_powerpc_cpu_stop(void *dummy)
++{
++	model->stop();
++}
++
++static void op_powerpc_stop(void)
++{
++	on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1);
++}
++
++static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
++{
++	int i;
++
++#ifdef __powerpc64__
++	/*
++	 * There is one mmcr0, mmcr1 and mmcra for setting the events for
++	 * all of the counters.
++	 */
++	oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0);
++	oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1);
++	oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra);
++#endif /* __powerpc64__ */
++
++	for (i = 0; i < model->num_counters; ++i) {
++		struct dentry *dir;
++		char buf[3];
++
++		snprintf(buf, sizeof buf, "%d", i);
++		dir = oprofilefs_mkdir(sb, root, buf);
++
++		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
++		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
++		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
++#ifdef __powerpc64__
++		/*
++		 * We dont support per counter user/kernel selection, but
++		 * we leave the entries because userspace expects them
++		 */
++#endif /* __powerpc64__ */
++		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
++		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
++
++#ifndef __powerpc64__
++		/* FIXME: Not sure if this is used */
++#endif /* ! __powerpc64__ */
++		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
++	}
++
++	oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
++	oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
++#ifdef __powerpc64__
++	oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
++				&sys.backtrace_spinlocks);
++#endif /* __powerpc64__ */
++
++	/* Default to tracing both kernel and user */
++	sys.enable_kernel = 1;
++	sys.enable_user = 1;
++#ifdef __powerpc64__
++	/* Turn on backtracing through spinlocks by default */
++	sys.backtrace_spinlocks = 1;
++#endif /* __powerpc64__ */
++
++	return 0;
++}
++
++int __init oprofile_arch_init(struct oprofile_operations *ops)
++{
++#ifndef __powerpc64__
++#ifdef CONFIG_FSL_BOOKE
++	model = &op_model_fsl_booke;
++#else
++	return -ENODEV;
++#endif
++
++	cpu_type = kmalloc(32, GFP_KERNEL);
++	if (NULL == cpu_type)
++		return -ENOMEM;
++
++	sprintf(cpu_type, "ppc/%s", cur_cpu_spec->cpu_name);
++
++	model->num_counters = cur_cpu_spec->num_pmcs;
++
++	ops->cpu_type = cpu_type;
++#else /* __powerpc64__ */
++	if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type)
++		return -ENODEV;
++	model = cur_cpu_spec->oprofile_model;
++	model->num_counters = cur_cpu_spec->num_pmcs;
++
++	ops->cpu_type = cur_cpu_spec->oprofile_cpu_type;
++#endif /* __powerpc64__ */
++	ops->create_files = op_powerpc_create_files;
++	ops->setup = op_powerpc_setup;
++	ops->shutdown = op_powerpc_shutdown;
++	ops->start = op_powerpc_start;
++	ops->stop = op_powerpc_stop;
++
++	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
++	       ops->cpu_type);
++
++	return 0;
++}
++
++void oprofile_arch_exit(void)
++{
++#ifndef __powerpc64__
++	kfree(cpu_type);
++	cpu_type = NULL;
++#endif /* ! __powerpc64__ */
++}
+diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
+@@ -0,0 +1,183 @@
++/*
++ * oprofile/op_model_e500.c
++ *
++ * Freescale Book-E oprofile support, based on ppc64 oprofile support
++ * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, IBM
++ *
++ * Copyright (c) 2004 Freescale Semiconductor, Inc
++ *
++ * Author: Andy Fleming
++ * Maintainer: Kumar Gala <Kumar.Gala 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.
++ */
++
++#include <linux/oprofile.h>
++#include <linux/init.h>
++#include <linux/smp.h>
++#include <asm/ptrace.h>
++#include <asm/system.h>
++#include <asm/processor.h>
++#include <asm/cputable.h>
++#include <asm/reg_booke.h>
++#include <asm/page.h>
++#include <asm/pmc.h>
++#include <asm/oprofile_impl.h>
++
++static unsigned long reset_value[OP_MAX_COUNTER];
++
++static int num_counters;
++static int oprofile_running;
++
++static inline unsigned int ctr_read(unsigned int i)
++{
++	switch(i) {
++		case 0:
++			return mfpmr(PMRN_PMC0);
++		case 1:
++			return mfpmr(PMRN_PMC1);
++		case 2:
++			return mfpmr(PMRN_PMC2);
++		case 3:
++			return mfpmr(PMRN_PMC3);
++		default:
++			return 0;
++	}
++}
++
++static inline void ctr_write(unsigned int i, unsigned int val)
++{
++	switch(i) {
++		case 0:
++			mtpmr(PMRN_PMC0, val);
++			break;
++		case 1:
++			mtpmr(PMRN_PMC1, val);
++			break;
++		case 2:
++			mtpmr(PMRN_PMC2, val);
++			break;
++		case 3:
++			mtpmr(PMRN_PMC3, val);
++			break;
++		default:
++			break;
++	}
++}
++
++
++static void fsl_booke_reg_setup(struct op_counter_config *ctr,
++			     struct op_system_config *sys,
++			     int num_ctrs)
++{
++	int i;
++
++	num_counters = num_ctrs;
++
++	/* freeze all counters */
++	pmc_stop_ctrs();
++
++	/* Our counters count up, and "count" refers to
++	 * how much before the next interrupt, and we interrupt
++	 * on overflow.  So we calculate the starting value
++	 * which will give us "count" until overflow.
++	 * Then we set the events on the enabled counters */
++	for (i = 0; i < num_counters; ++i) {
++		reset_value[i] = 0x80000000UL - ctr[i].count;
++
++		init_pmc_stop(i);
++
++		set_pmc_event(i, ctr[i].event);
++
++		set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
++	}
++}
++
++static void fsl_booke_start(struct op_counter_config *ctr)
++{
++	int i;
++
++	mtmsr(mfmsr() | MSR_PMM);
++
++	for (i = 0; i < num_counters; ++i) {
++		if (ctr[i].enabled) {
++			ctr_write(i, reset_value[i]);
++			/* Set Each enabled counterd to only
++			 * count when the Mark bit is not set */
++			set_pmc_marked(i, 1, 0);
++			pmc_start_ctr(i, 1);
++		} else {
++			ctr_write(i, 0);
++
++			/* Set the ctr to be stopped */
++			pmc_start_ctr(i, 0);
++		}
++	}
++
++	/* Clear the freeze bit, and enable the interrupt.
++	 * The counters won't actually start until the rfi clears
++	 * the PMM bit */
++	pmc_start_ctrs(1);
++
++	oprofile_running = 1;
++
++	pr_debug("start on cpu %d, pmgc0 %x\n", smp_processor_id(),
++			mfpmr(PMRN_PMGC0));
++}
++
++static void fsl_booke_stop(void)
++{
++	/* freeze counters */
++	pmc_stop_ctrs();
++
++	oprofile_running = 0;
++
++	pr_debug("stop on cpu %d, pmgc0 %x\n", smp_processor_id(),
++			mfpmr(PMRN_PMGC0));
++
++	mb();
++}
++
++
++static void fsl_booke_handle_interrupt(struct pt_regs *regs,
++				    struct op_counter_config *ctr)
++{
++	unsigned long pc;
++	int is_kernel;
++	int val;
++	int i;
++
++	/* set the PMM bit (see comment below) */
++	mtmsr(mfmsr() | MSR_PMM);
++
++	pc = regs->nip;
++	is_kernel = (pc >= KERNELBASE);
++
++	for (i = 0; i < num_counters; ++i) {
++		val = ctr_read(i);
++		if (val < 0) {
++			if (oprofile_running && ctr[i].enabled) {
++				oprofile_add_pc(pc, is_kernel, i);
++				ctr_write(i, reset_value[i]);
++			} else {
++				ctr_write(i, 0);
++			}
++		}
++	}
++
++	/* The freeze bit was set by the interrupt. */
++	/* Clear the freeze bit, and reenable the interrupt.
++	 * The counters won't actually start until the rfi clears
++	 * the PMM bit */
++	pmc_start_ctrs(1);
++}
++
++struct op_powerpc_model op_model_fsl_booke = {
++	.reg_setup		= fsl_booke_reg_setup,
++	.start			= fsl_booke_start,
++	.stop			= fsl_booke_stop,
++	.handle_interrupt	= fsl_booke_handle_interrupt,
++};
+diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/oprofile/op_model_power4.c
+@@ -0,0 +1,309 @@
++/*
++ * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, 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/oprofile.h>
++#include <linux/init.h>
++#include <linux/smp.h>
++#include <asm/ptrace.h>
++#include <asm/system.h>
++#include <asm/processor.h>
++#include <asm/cputable.h>
++#include <asm/systemcfg.h>
++#include <asm/rtas.h>
++#include <asm/oprofile_impl.h>
++
++#define dbg(args...)
++
++static unsigned long reset_value[OP_MAX_COUNTER];
++
++static int oprofile_running;
++static int mmcra_has_sihv;
++
++/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
++static u32 mmcr0_val;
++static u64 mmcr1_val;
++static u32 mmcra_val;
++
++/*
++ * Since we do not have an NMI, backtracing through spinlocks is
++ * only a best guess. In light of this, allow it to be disabled at
++ * runtime.
++ */
++static int backtrace_spinlocks;
++
++static void power4_reg_setup(struct op_counter_config *ctr,
++			     struct op_system_config *sys,
++			     int num_ctrs)
++{
++	int i;
++
++	/*
++	 * SIHV / SIPR bits are only implemented on POWER4+ (GQ) and above.
++	 * However we disable it on all POWER4 until we verify it works
++	 * (I was seeing some strange behaviour last time I tried).
++	 *
++	 * It has been verified to work on POWER5 so we enable it there.
++	 */
++	if (cpu_has_feature(CPU_FTR_MMCRA_SIHV))
++		mmcra_has_sihv = 1;
++
++	/*
++	 * The performance counter event settings are given in the mmcr0,
++	 * mmcr1 and mmcra values passed from the user in the
++	 * op_system_config structure (sys variable).
++	 */
++	mmcr0_val = sys->mmcr0;
++	mmcr1_val = sys->mmcr1;
++	mmcra_val = sys->mmcra;
++
++	backtrace_spinlocks = sys->backtrace_spinlocks;
++
++	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)
++		reset_value[i] = 0x80000000UL - ctr[i].count;
++
++	/* setup user and kernel profiling */
++	if (sys->enable_kernel)
++		mmcr0_val &= ~MMCR0_KERNEL_DISABLE;
++	else
++		mmcr0_val |= MMCR0_KERNEL_DISABLE;
++
++	if (sys->enable_user)
++		mmcr0_val &= ~MMCR0_PROBLEM_DISABLE;
++	else
++		mmcr0_val |= MMCR0_PROBLEM_DISABLE;
++}
++
++extern void ppc64_enable_pmcs(void);
++
++static void power4_cpu_setup(void *unused)
++{
++	unsigned int mmcr0 = mmcr0_val;
++	unsigned long mmcra = mmcra_val;
++
++	ppc64_enable_pmcs();
++
++	/* set the freeze bit */
++	mmcr0 |= MMCR0_FC;
++	mtspr(SPRN_MMCR0, mmcr0);
++
++	mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE;
++	mmcr0 |= MMCR0_PMC1CE|MMCR0_PMCjCE;
++	mtspr(SPRN_MMCR0, mmcr0);
++
++	mtspr(SPRN_MMCR1, mmcr1_val);
++
++	mmcra |= MMCRA_SAMPLE_ENABLE;
++	mtspr(SPRN_MMCRA, mmcra);
++
++	dbg("setup on cpu %d, mmcr0 %lx\n", smp_processor_id(),
++	    mfspr(SPRN_MMCR0));
++	dbg("setup on cpu %d, mmcr1 %lx\n", smp_processor_id(),
++	    mfspr(SPRN_MMCR1));
++	dbg("setup on cpu %d, mmcra %lx\n", smp_processor_id(),
++	    mfspr(SPRN_MMCRA));
++}
++
++static void power4_start(struct op_counter_config *ctr)
++{
++	int i;
++	unsigned int mmcr0;
++
++	/* set the PMM bit (see comment below) */
++	mtmsrd(mfmsr() | MSR_PMM);
++
++	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
++		if (ctr[i].enabled) {
++			ctr_write(i, reset_value[i]);
++		} else {
++			ctr_write(i, 0);
++		}
++	}
++
++	mmcr0 = mfspr(SPRN_MMCR0);
++
++	/*
++	 * We must clear the PMAO bit on some (GQ) chips. Just do it
++	 * all the time
++	 */
++	mmcr0 &= ~MMCR0_PMAO;
++
++	/*
++	 * now clear the freeze bit, counting will not start until we
++	 * rfid from this excetion, because only at that point will
++	 * the PMM bit be cleared
++	 */
++	mmcr0 &= ~MMCR0_FC;
++	mtspr(SPRN_MMCR0, mmcr0);
++
++	oprofile_running = 1;
++
++	dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
++}
++
++static void power4_stop(void)
++{
++	unsigned int mmcr0;
++
++	/* freeze counters */
++	mmcr0 = mfspr(SPRN_MMCR0);
++	mmcr0 |= MMCR0_FC;
++	mtspr(SPRN_MMCR0, mmcr0);
++
++	oprofile_running = 0;
++
++	dbg("stop on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
++
++	mb();
++}
++
++/* Fake functions used by canonicalize_pc */
++static void __attribute_used__ hypervisor_bucket(void)
++{
++}
++
++static void __attribute_used__ rtas_bucket(void)
++{
++}
++
++static void __attribute_used__ kernel_unknown_bucket(void)
++{
++}
++
++static unsigned long check_spinlock_pc(struct pt_regs *regs,
++				       unsigned long profile_pc)
++{
++	unsigned long pc = instruction_pointer(regs);
++
++	/*
++	 * If both the SIAR (sampled instruction) and the perfmon exception
++	 * occurred in a spinlock region then we account the sample to the
++	 * calling function. This isnt 100% correct, we really need soft
++	 * IRQ disable so we always get the perfmon exception at the
++	 * point at which the SIAR is set.
++	 */
++	if (backtrace_spinlocks && in_lock_functions(pc) &&
++			in_lock_functions(profile_pc))
++		return regs->link;
++	else
++		return profile_pc;
++}
++
++/*
++ * On GQ and newer the MMCRA stores the HV and PR bits at the time
++ * the SIAR was sampled. We use that to work out if the SIAR was sampled in
++ * the hypervisor, our exception vectors or RTAS.
++ */
++static unsigned long get_pc(struct pt_regs *regs)
++{
++	unsigned long pc = mfspr(SPRN_SIAR);
++	unsigned long mmcra;
++
++	/* Cant do much about it */
++	if (!mmcra_has_sihv)
++		return check_spinlock_pc(regs, pc);
++
++	mmcra = mfspr(SPRN_MMCRA);
++
++	/* Were we in the hypervisor? */
++	if ((systemcfg->platform == PLATFORM_PSERIES_LPAR) &&
++	    (mmcra & MMCRA_SIHV))
++		/* function descriptor madness */
++		return *((unsigned long *)hypervisor_bucket);
++
++	/* We were in userspace, nothing to do */
++	if (mmcra & MMCRA_SIPR)
++		return pc;
++
++#ifdef CONFIG_PPC_RTAS
++	/* Were we in RTAS? */
++	if (pc >= rtas.base && pc < (rtas.base + rtas.size))
++		/* function descriptor madness */
++		return *((unsigned long *)rtas_bucket);
++#endif
++
++	/* Were we in our exception vectors or SLB real mode miss handler? */
++	if (pc < 0x1000000UL)
++		return (unsigned long)__va(pc);
++
++	/* Not sure where we were */
++	if (pc < KERNELBASE)
++		/* function descriptor madness */
++		return *((unsigned long *)kernel_unknown_bucket);
++
++	return check_spinlock_pc(regs, pc);
++}
++
++static int get_kernel(unsigned long pc)
++{
++	int is_kernel;
++
++	if (!mmcra_has_sihv) {
++		is_kernel = (pc >= KERNELBASE);
++	} else {
++		unsigned long mmcra = mfspr(SPRN_MMCRA);
++		is_kernel = ((mmcra & MMCRA_SIPR) == 0);
++	}
++
++	return is_kernel;
++}
++
++static void power4_handle_interrupt(struct pt_regs *regs,
++				    struct op_counter_config *ctr)
++{
++	unsigned long pc;
++	int is_kernel;
++	int val;
++	int i;
++	unsigned int mmcr0;
++
++	pc = get_pc(regs);
++	is_kernel = get_kernel(pc);
++
++	/* set the PMM bit (see comment below) */
++	mtmsrd(mfmsr() | MSR_PMM);
++
++	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
++		val = ctr_read(i);
++		if (val < 0) {
++			if (oprofile_running && ctr[i].enabled) {
++				oprofile_add_pc(pc, is_kernel, i);
++				ctr_write(i, reset_value[i]);
++			} else {
++				ctr_write(i, 0);
++			}
++		}
++	}
++
++	mmcr0 = mfspr(SPRN_MMCR0);
++
++	/* reset the perfmon trigger */
++	mmcr0 |= MMCR0_PMXE;
++
++	/*
++	 * We must clear the PMAO bit on some (GQ) chips. Just do it
++	 * all the time
++	 */
++	mmcr0 &= ~MMCR0_PMAO;
++
++	/*
++	 * now clear the freeze bit, counting will not start until we
++	 * rfid from this exception, because only at that point will
++	 * the PMM bit be cleared
++	 */
++	mmcr0 &= ~MMCR0_FC;
++	mtspr(SPRN_MMCR0, mmcr0);
++}
++
++struct op_powerpc_model op_model_power4 = {
++	.reg_setup		= power4_reg_setup,
++	.cpu_setup		= power4_cpu_setup,
++	.start			= power4_start,
++	.stop			= power4_stop,
++	.handle_interrupt	= power4_handle_interrupt,
++};
+diff --git a/arch/powerpc/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/oprofile/op_model_rs64.c
+@@ -0,0 +1,218 @@
++/*
++ * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, 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/oprofile.h>
++#include <linux/init.h>
++#include <linux/smp.h>
++#include <asm/ptrace.h>
++#include <asm/system.h>
++#include <asm/processor.h>
++#include <asm/cputable.h>
++#include <asm/oprofile_impl.h>
++
++#define dbg(args...)
++
++static void ctrl_write(unsigned int i, unsigned int val)
++{
++	unsigned int tmp = 0;
++	unsigned long shift = 0, mask = 0;
++
++	dbg("ctrl_write %d %x\n", i, val);
++
++	switch(i) {
++	case 0:
++		tmp = mfspr(SPRN_MMCR0);
++		shift = 6;
++		mask = 0x7F;
++		break;
++	case 1:
++		tmp = mfspr(SPRN_MMCR0);
++		shift = 0;
++		mask = 0x3F;
++		break;
++	case 2:
++		tmp = mfspr(SPRN_MMCR1);
++		shift = 31 - 4;
++		mask = 0x1F;
++		break;
++	case 3:
++		tmp = mfspr(SPRN_MMCR1);
++		shift = 31 - 9;
++		mask = 0x1F;
++		break;
++	case 4:
++		tmp = mfspr(SPRN_MMCR1);
++		shift = 31 - 14;
++		mask = 0x1F;
++		break;
++	case 5:
++		tmp = mfspr(SPRN_MMCR1);
++		shift = 31 - 19;
++		mask = 0x1F;
++		break;
++	case 6:
++		tmp = mfspr(SPRN_MMCR1);
++		shift = 31 - 24;
++		mask = 0x1F;
++		break;
++	case 7:
++		tmp = mfspr(SPRN_MMCR1);
++		shift = 31 - 28;
++		mask = 0xF;
++		break;
++	}
++
++	tmp = tmp & ~(mask << shift);
++	tmp |= val << shift;
++
++	switch(i) {
++		case 0:
++		case 1:
++			mtspr(SPRN_MMCR0, tmp);
++			break;
++		default:
++			mtspr(SPRN_MMCR1, tmp);
++	}
++
++	dbg("ctrl_write mmcr0 %lx mmcr1 %lx\n", mfspr(SPRN_MMCR0),
++	       mfspr(SPRN_MMCR1));
++}
++
++static unsigned long reset_value[OP_MAX_COUNTER];
++
++static int num_counters;
++
++static void rs64_reg_setup(struct op_counter_config *ctr,
++			   struct op_system_config *sys,
++			   int num_ctrs)
++{
++	int i;
++
++	num_counters = num_ctrs;
++
++	for (i = 0; i < num_counters; ++i)
++		reset_value[i] = 0x80000000UL - ctr[i].count;
++
++	/* XXX setup user and kernel profiling */
++}
++
++static void rs64_cpu_setup(void *unused)
++{
++	unsigned int mmcr0;
++
++	/* reset MMCR0 and set the freeze bit */
++	mmcr0 = MMCR0_FC;
++	mtspr(SPRN_MMCR0, mmcr0);
++
++	/* reset MMCR1, MMCRA */
++	mtspr(SPRN_MMCR1, 0);
++
++	if (cpu_has_feature(CPU_FTR_MMCRA))
++		mtspr(SPRN_MMCRA, 0);
++
++	mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE;
++	/* Only applies to POWER3, but should be safe on RS64 */
++	mmcr0 |= MMCR0_PMC1CE|MMCR0_PMCjCE;
++	mtspr(SPRN_MMCR0, mmcr0);
++
++	dbg("setup on cpu %d, mmcr0 %lx\n", smp_processor_id(),
++	    mfspr(SPRN_MMCR0));
++	dbg("setup on cpu %d, mmcr1 %lx\n", smp_processor_id(),
++	    mfspr(SPRN_MMCR1));
++}
++
++static void rs64_start(struct op_counter_config *ctr)
++{
++	int i;
++	unsigned int mmcr0;
++
++	/* set the PMM bit (see comment below) */
++	mtmsrd(mfmsr() | MSR_PMM);
++
++	for (i = 0; i < num_counters; ++i) {
++		if (ctr[i].enabled) {
++			ctr_write(i, reset_value[i]);
++			ctrl_write(i, ctr[i].event);
++		} else {
++			ctr_write(i, 0);
++		}
++	}
++
++	mmcr0 = mfspr(SPRN_MMCR0);
++
++	/*
++	 * now clear the freeze bit, counting will not start until we
++	 * rfid from this excetion, because only at that point will
++	 * the PMM bit be cleared
++	 */
++	mmcr0 &= ~MMCR0_FC;
++	mtspr(SPRN_MMCR0, mmcr0);
++
++	dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
++}
++
++static void rs64_stop(void)
++{
++	unsigned int mmcr0;
++
++	/* freeze counters */
++	mmcr0 = mfspr(SPRN_MMCR0);
++	mmcr0 |= MMCR0_FC;
++	mtspr(SPRN_MMCR0, mmcr0);
++
++	dbg("stop on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
++
++	mb();
++}
++
++static void rs64_handle_interrupt(struct pt_regs *regs,
++				  struct op_counter_config *ctr)
++{
++	unsigned int mmcr0;
++	int val;
++	int i;
++	unsigned long pc = mfspr(SPRN_SIAR);
++	int is_kernel = (pc >= KERNELBASE);
++
++	/* set the PMM bit (see comment below) */
++	mtmsrd(mfmsr() | MSR_PMM);
++
++	for (i = 0; i < num_counters; ++i) {
++		val = ctr_read(i);
++		if (val < 0) {
++			if (ctr[i].enabled) {
++				oprofile_add_pc(pc, is_kernel, i);
++				ctr_write(i, reset_value[i]);
++			} else {
++				ctr_write(i, 0);
++			}
++		}
++	}
++
++	mmcr0 = mfspr(SPRN_MMCR0);
++
++	/* reset the perfmon trigger */
++	mmcr0 |= MMCR0_PMXE;
++
++	/*
++	 * now clear the freeze bit, counting will not start until we
++	 * rfid from this exception, because only at that point will
++	 * the PMM bit be cleared
++	 */
++	mmcr0 &= ~MMCR0_FC;
++	mtspr(SPRN_MMCR0, mmcr0);
++}
++
++struct op_powerpc_model op_model_rs64 = {
++	.reg_setup		= rs64_reg_setup,
++	.cpu_setup		= rs64_cpu_setup,
++	.start			= rs64_start,
++	.stop			= rs64_stop,
++	.handle_interrupt	= rs64_handle_interrupt,
++};
+diff --git a/arch/powerpc/platforms/4xx/Kconfig b/arch/powerpc/platforms/4xx/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/4xx/Kconfig
+@@ -0,0 +1,280 @@
++config 4xx
++	bool
++	depends on 40x || 44x
++	default y
++
++config WANT_EARLY_SERIAL
++	bool
++	select SERIAL_8250
++	default n
++
++menu "AMCC 4xx options"
++	depends on 4xx
++
++choice
++	prompt "Machine Type"
++	depends on 40x
++	default WALNUT
++
++config BUBINGA
++	bool "Bubinga"
++	select WANT_EARLY_SERIAL
++	help
++	  This option enables support for the IBM 405EP evaluation board.
++
++config CPCI405
++	bool "CPCI405"
++	help
++	  This option enables support for the CPCI405 board.
++
++config EP405
++	bool "EP405/EP405PC"
++	help
++	  This option enables support for the EP405/EP405PC boards.
++
++config REDWOOD_5
++	bool "Redwood-5"
++	help
++	  This option enables support for the IBM STB04 evaluation board.
++
++config REDWOOD_6
++	bool "Redwood-6"
++	help
++	  This option enables support for the IBM STBx25xx evaluation board.
++
++config SYCAMORE
++	bool "Sycamore"
++	help
++	  This option enables support for the IBM PPC405GPr evaluation board.
++
++config WALNUT
++	bool "Walnut"
++	help
++	  This option enables support for the IBM PPC405GP evaluation board.
++
++config XILINX_ML300
++	bool "Xilinx-ML300"
++	help
++	  This option enables support for the Xilinx ML300 evaluation board.
++
++endchoice
++
++choice
++	prompt "Machine Type"
++	depends on 44x
++	default EBONY
++
++config BAMBOO
++	bool "Bamboo"
++	select WANT_EARLY_SERIAL
++	help
++	  This option enables support for the IBM PPC440EP evaluation board.
++
++config EBONY
++	bool "Ebony"
++	select WANT_EARLY_SERIAL
++	help
++	  This option enables support for the IBM PPC440GP evaluation board.
++
++config LUAN
++	bool "Luan"
++	select WANT_EARLY_SERIAL
++	help
++	  This option enables support for the IBM PPC440SP evaluation board.
++
++config OCOTEA
++	bool "Ocotea"
++	select WANT_EARLY_SERIAL
++	help
++	  This option enables support for the IBM PPC440GX evaluation board.
++
++endchoice
++
++config EP405PC
++	bool "EP405PC Support"
++	depends on EP405
++
++
++# It's often necessary to know the specific 4xx processor type.
++# Fortunately, it is impled (so far) from the board type, so we
++# don't need to ask more redundant questions.
++config NP405H
++	bool
++	depends on ASH
++	default y
++
++config 440EP
++	bool
++	depends on BAMBOO
++	select PPC_FPU
++	default y
++
++config 440GP
++	bool
++	depends on EBONY
++	default y
++
++config 440GX
++	bool
++	depends on OCOTEA
++	default y
++
++config 440SP
++	bool
++	depends on LUAN
++	default y
++
++config 440
++	bool
++	depends on 440GP || 440SP || 440EP
++	default y
++
++config 440A
++	bool
++	depends on 440GX
++	default y
++
++config IBM440EP_ERR42
++	bool
++	depends on 440EP
++	default y
++
++# All 405-based cores up until the 405GPR and 405EP have this errata.
++config IBM405_ERR77
++	bool
++	depends on 40x && !403GCX && !405GPR && !405EP
++	default y
++
++# All 40x-based cores, up until the 405GPR and 405EP have this errata.
++config IBM405_ERR51
++	bool
++	depends on 40x && !405GPR && !405EP
++	default y
++
++config BOOKE
++	bool
++	depends on 44x
++	default y
++
++config IBM_OCP
++	bool
++	depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
++	default y
++
++config XILINX_OCP
++	bool
++	depends on XILINX_ML300
++	default y
++
++config IBM_EMAC4
++	bool
++	depends on 440GX || 440SP
++	default y
++
++config BIOS_FIXUP
++	bool
++	depends on BUBINGA || EP405 || SYCAMORE || WALNUT
++	default y
++
++# OAK doesn't exist but wanted to keep this around for any future 403GCX boards
++config 403GCX
++	bool
++	depends OAK
++	default y
++
++config 405EP
++	bool
++	depends on BUBINGA
++	default y
++
++config 405GP
++	bool
++	depends on CPCI405 || EP405 || WALNUT
++	default y
++
++config 405GPR
++	bool
++	depends on SYCAMORE
++	default y
++
++config VIRTEX_II_PRO
++	bool
++	depends on XILINX_ML300
++	default y
++
++config STB03xxx
++	bool
++	depends on REDWOOD_5 || REDWOOD_6
++	default y
++
++config EMBEDDEDBOOT
++	bool
++	depends on EP405 || XILINX_ML300
++	default y
++
++config IBM_OPENBIOS
++	bool
++	depends on ASH || BUBINGA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
++	default y
++
++config PPC4xx_DMA
++	bool "PPC4xx DMA controller support"
++	depends on 4xx
++
++config PPC4xx_EDMA
++	bool
++	depends on !STB03xxx && PPC4xx_DMA
++	default y
++
++config PPC_GEN550
++	bool
++	depends on 4xx
++	default y
++
++choice
++	prompt "TTYS0 device and default console"
++	depends on 40x
++	default UART0_TTYS0
++
++config UART0_TTYS0
++	bool "UART0"
++
++config UART0_TTYS1
++	bool "UART1"
++
++endchoice
++
++config SERIAL_SICC
++	bool "SICC Serial port support"
++	depends on STB03xxx
++
++config UART1_DFLT_CONSOLE
++	bool
++	depends on SERIAL_SICC && UART0_TTYS1
++	default y
++
++config SERIAL_SICC_CONSOLE
++	bool
++	depends on SERIAL_SICC && UART0_TTYS1
++	default y
++endmenu
++
++
++menu "IBM 40x options"
++	depends on 40x
++
++config SERIAL_SICC
++	bool "SICC Serial port"
++	depends on STB03xxx
++
++config UART1_DFLT_CONSOLE
++	bool
++	depends on SERIAL_SICC && UART0_TTYS1
++	default y
++
++config SERIAL_SICC_CONSOLE
++	bool
++	depends on SERIAL_SICC && UART0_TTYS1
++	default y
++
++endmenu
+diff --git a/arch/powerpc/platforms/4xx/Makefile b/arch/powerpc/platforms/4xx/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/4xx/Makefile
+@@ -0,0 +1 @@
++# empty makefile so make clean works
+\ No newline at end of file
+diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/85xx/Kconfig
+@@ -0,0 +1,86 @@
++config 85xx
++	bool
++	depends on E500
++	default y
++
++config PPC_INDIRECT_PCI_BE
++	bool
++	depends on 85xx
++	default y
++
++menu "Freescale 85xx options"
++	depends on E500
++
++choice
++	prompt "Machine Type"
++	depends on 85xx
++	default MPC8540_ADS
++
++config MPC8540_ADS
++	bool "Freescale MPC8540 ADS"
++	help
++	  This option enables support for the MPC 8540 ADS evaluation board.
++
++config MPC8548_CDS
++	bool "Freescale MPC8548 CDS"
++	help
++	  This option enablese support for the MPC8548 CDS evaluation board.
++
++config MPC8555_CDS
++	bool "Freescale MPC8555 CDS"
++	help
++	  This option enablese support for the MPC8555 CDS evaluation board.
++
++config MPC8560_ADS
++	bool "Freescale MPC8560 ADS"
++	help
++	  This option enables support for the MPC 8560 ADS evaluation board.
++
++config SBC8560
++	bool "WindRiver PowerQUICC III SBC8560"
++	help
++	  This option enables support for the WindRiver PowerQUICC III 
++	  SBC8560 board.
++
++config STX_GP3
++	bool "Silicon Turnkey Express GP3"
++	help
++	  This option enables support for the Silicon Turnkey Express GP3
++	  board.
++
++endchoice
++
++# It's often necessary to know the specific 85xx processor type.
++# Fortunately, it is implied (so far) from the board type, so we
++# don't need to ask more redundant questions.
++config MPC8540
++	bool
++	depends on MPC8540_ADS
++	default y
++
++config MPC8548
++	bool
++	depends on MPC8548_CDS
++	default y
++
++config MPC8555
++	bool
++	depends on MPC8555_CDS
++	default y
++
++config MPC8560
++	bool
++	depends on SBC8560 || MPC8560_ADS || STX_GP3
++	default y
++
++config 85xx_PCI2
++	bool "Supprt for 2nd PCI host controller"
++	depends on MPC8555_CDS
++	default y
++
++config PPC_GEN550
++	bool
++	depends on MPC8540 || SBC8560 || MPC8555
++	default y
++
++endmenu
+diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/85xx/Makefile
+@@ -0,0 +1 @@
++# empty makefile so make clean works
+diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/8xx/Kconfig
+@@ -0,0 +1,352 @@
++config FADS
++	bool
++
++choice
++	prompt "8xx Machine Type"
++	depends on 8xx
++	default RPXLITE
++
++config RPXLITE
++	bool "RPX-Lite"
++	---help---
++	  Single-board computers based around the PowerPC MPC8xx chips and
++	  intended for embedded applications.  The following types are
++	  supported:
++
++	  RPX-Lite:
++	  Embedded Planet RPX Lite. PC104 form-factor SBC based on the MPC823.
++
++	  RPX-Classic:
++	  Embedded Planet RPX Classic Low-fat. Credit-card-size SBC based on
++	  the MPC 860
++
++	  BSE-IP:
++	  Bright Star Engineering ip-Engine.
++
++	  TQM823L:
++	  TQM850L:
++	  TQM855L:
++	  TQM860L:
++	  MPC8xx based family of mini modules, half credit card size,
++	  up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports,
++	  2 x CAN bus interface, ...
++	  Manufacturer: TQ Components, www.tq-group.de
++	  Date of Release: October (?) 1999
++	  End of Life: not yet :-)
++	  URL:
++	  - module: <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>
++	  - starter kit: <http://www.denx.de/PDF/STK8xxLHWM201.pdf>
++	  - images: <http://www.denx.de/embedded-ppc-en.html>
++
++	  FPS850L:
++	  FingerPrint Sensor System (based on TQM850L)
++	  Manufacturer: IKENDI AG, <http://www.ikendi.com/>
++	  Date of Release: November 1999
++	  End of life: end 2000 ?
++	  URL: see TQM850L
++
++	  IVMS8:
++	  MPC860 based board used in the "Integrated Voice Mail System",
++	  Small Version (8 voice channels)
++	  Manufacturer: Speech Design, <http://www.speech-design.de/>
++	  Date of Release: December 2000 (?)
++	  End of life: -
++	  URL: <http://www.speech-design.de/>
++
++	  IVML24:
++	  MPC860 based board used in the "Integrated Voice Mail System",
++	  Large Version (24 voice channels)
++	  Manufacturer: Speech Design, <http://www.speech-design.de/>
++	  Date of Release: March 2001  (?)
++	  End of life: -
++	  URL: <http://www.speech-design.de/>
++
++	  HERMES:
++	  Hermes-Pro ISDN/LAN router with integrated 8 x hub
++	  Manufacturer: Multidata Gesellschaft fur Datentechnik und Informatik
++	  <http://www.multidata.de/>
++	  Date of Release: 2000 (?)
++	  End of life: -
++	  URL: <http://www.multidata.de/english/products/hpro.htm>
++
++	  IP860:
++	  VMEBus IP (Industry Pack) carrier board with MPC860
++	  Manufacturer: MicroSys GmbH, <http://www.microsys.de/>
++	  Date of Release: ?
++	  End of life: -
++	  URL: <http://www.microsys.de/html/ip860.html>
++
++	  PCU_E:
++	  PCU = Peripheral Controller Unit, Extended
++	  Manufacturer: Siemens AG, ICN (Information and Communication Networks)
++	  	<http://www.siemens.de/page/1,3771,224315-1-999_2_226207-0,00.html>
++	  Date of Release: April 2001
++	  End of life: August 2001
++	  URL: n. a.
++
++config RPXCLASSIC
++	bool "RPX-Classic"
++	help
++	  The RPX-Classic is a single-board computer based on the Motorola
++	  MPC860.  It features 16MB of DRAM and a variable amount of flash,
++	  I2C EEPROM, thermal monitoring, a PCMCIA slot, a DIP switch and two
++	  LEDs.  Variants with Ethernet ports exist.  Say Y here to support it
++	  directly.
++
++config BSEIP
++	bool "BSE-IP"
++	help
++	  Say Y here to support the Bright Star Engineering ipEngine SBC.
++	  This is a credit-card-sized device featuring a MPC823 processor,
++	  26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video
++	  controller, and two RS232 ports.
++
++config MPC8XXFADS
++	bool "FADS"
++	select FADS
++
++config MPC86XADS
++	bool "MPC86XADS"
++	help
++	  MPC86x Application Development System by Freescale Semiconductor.
++	  The MPC86xADS is meant to serve as a platform for s/w and h/w
++	  development around the MPC86X processor families.
++	select FADS
++
++config MPC885ADS
++	bool "MPC885ADS"
++	help
++	  Freescale Semiconductor MPC885 Application Development System (ADS).
++	  Also known as DUET.
++	  The MPC885ADS is meant to serve as a platform for s/w and h/w
++	  development around the MPC885 processor family.
++
++config TQM823L
++	bool "TQM823L"
++	help
++	  Say Y here to support the TQM823L, one of an MPC8xx-based family of
++	  mini SBCs (half credit-card size) from TQ Components first released
++	  in late 1999.  Technical references are at
++	  <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
++	  <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
++	  <http://www.denx.de/embedded-ppc-en.html>.
++
++config TQM850L
++	bool "TQM850L"
++	help
++	  Say Y here to support the TQM850L, one of an MPC8xx-based family of
++	  mini SBCs (half credit-card size) from TQ Components first released
++	  in late 1999.  Technical references are at
++	  <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
++	  <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
++	  <http://www.denx.de/embedded-ppc-en.html>.
++
++config TQM855L
++	bool "TQM855L"
++	help
++	  Say Y here to support the TQM855L, one of an MPC8xx-based family of
++	  mini SBCs (half credit-card size) from TQ Components first released
++	  in late 1999.  Technical references are at
++	  <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
++	  <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
++	  <http://www.denx.de/embedded-ppc-en.html>.
++
++config TQM860L
++	bool "TQM860L"
++	help
++	  Say Y here to support the TQM860L, one of an MPC8xx-based family of
++	  mini SBCs (half credit-card size) from TQ Components first released
++	  in late 1999.  Technical references are at
++	  <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
++	  <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
++	  <http://www.denx.de/embedded-ppc-en.html>.
++
++config FPS850L
++	bool "FPS850L"
++
++config IVMS8
++	bool "IVMS8"
++	help
++	  Say Y here to support the Integrated Voice-Mail Small 8-channel SBC
++	  from Speech Design, released March 2001.  The manufacturer's website
++	  is at <http://www.speech-design.de/>.
++
++config IVML24
++	bool "IVML24"
++	help
++	  Say Y here to support the Integrated Voice-Mail Large 24-channel SBC
++	  from Speech Design, released March 2001.  The manufacturer's website
++	  is at <http://www.speech-design.de/>.
++
++config HERMES_PRO
++	bool "HERMES"
++
++config IP860
++	bool "IP860"
++
++config LWMON
++	bool "LWMON"
++
++config PCU_E
++	bool "PCU_E"
++
++config CCM
++	bool "CCM"
++
++config LANTEC
++	bool "LANTEC"
++
++config MBX
++	bool "MBX"
++	help
++	  MBX is a line of Motorola single-board computer based around the
++	  MPC821 and MPC860 processors, and intended for embedded-controller
++	  applications.  Say Y here to support these boards directly.
++
++config WINCEPT
++	bool "WinCept"
++	help
++	  The Wincept 100/110 is a Motorola single-board computer based on the
++	  MPC821 PowerPC, introduced in 1998 and designed to be used in
++	  thin-client machines.  Say Y to support it directly.
++
++endchoice
++
++#
++# MPC8xx Communication options
++#
++
++menu "MPC8xx CPM Options"
++	depends on 8xx
++
++config SCC_ENET
++	bool "CPM SCC Ethernet"
++	depends on NET_ETHERNET
++	help
++	  Enable Ethernet support via the Motorola MPC8xx serial
++	  communications controller.
++
++choice
++	prompt "SCC used for Ethernet"
++	depends on SCC_ENET
++	default SCC1_ENET
++
++config SCC1_ENET
++	bool "SCC1"
++	help
++	  Use MPC8xx serial communications controller 1 to drive Ethernet
++	  (default).
++
++config SCC2_ENET
++	bool "SCC2"
++	help
++	  Use MPC8xx serial communications controller 2 to drive Ethernet.
++
++config SCC3_ENET
++	bool "SCC3"
++	help
++	  Use MPC8xx serial communications controller 3 to drive Ethernet.
++
++endchoice
++
++config FEC_ENET
++	bool "860T FEC Ethernet"
++	depends on NET_ETHERNET
++	help
++	  Enable Ethernet support via the Fast Ethernet Controller (FCC) on
++	  the Motorola MPC8260.
++
++config USE_MDIO
++	bool "Use MDIO for PHY configuration"
++	depends on FEC_ENET
++	help
++	  On some boards the hardware configuration of the ethernet PHY can be
++	  used without any software interaction over the MDIO interface, so
++	  all MII code can be omitted. Say N here if unsure or if you don't
++	  need link status reports.
++
++config  FEC_AM79C874
++	bool "Support AMD79C874 PHY"
++	depends on USE_MDIO
++
++config FEC_LXT970
++	bool "Support LXT970 PHY"
++	depends on USE_MDIO
++
++config FEC_LXT971
++	bool "Support LXT971 PHY"
++	depends on USE_MDIO
++	
++config FEC_QS6612
++	bool "Support QS6612 PHY"
++	depends on USE_MDIO
++	
++config ENET_BIG_BUFFERS
++	bool "Use Big CPM Ethernet Buffers"
++	depends on SCC_ENET || FEC_ENET
++	help
++	  Allocate large buffers for MPC8xx Ethernet. Increases throughput
++	  and decreases the likelihood of dropped packets, but costs memory.
++
++config HTDMSOUND
++	bool "Embedded Planet HIOX Audio"
++	depends on SOUND=y
++
++# This doesn't really belong here, but it is convenient to ask
++# 8xx specific questions.
++comment "Generic MPC8xx Options"
++
++config 8xx_COPYBACK
++	bool "Copy-Back Data Cache (else Writethrough)"
++	help
++	  Saying Y here will cause the cache on an MPC8xx processor to be used
++	  in Copy-Back mode.  If you say N here, it is used in Writethrough
++	  mode.
++
++	  If in doubt, say Y here.
++
++config 8xx_CPU6
++	bool "CPU6 Silicon Errata (860 Pre Rev. C)"
++	help
++	  MPC860 CPUs, prior to Rev C have some bugs in the silicon, which
++	  require workarounds for Linux (and most other OSes to work).  If you
++	  get a BUG() very early in boot, this might fix the problem.  For
++	  more details read the document entitled "MPC860 Family Device Errata
++	  Reference" on Motorola's website.  This option also incurs a
++	  performance hit.
++
++	  If in doubt, say N here.
++
++choice
++	prompt "Microcode patch selection"
++	default NO_UCODE_PATCH
++	help
++	  Help not implemented yet, coming soon.
++
++config NO_UCODE_PATCH
++	bool "None"
++
++config USB_SOF_UCODE_PATCH
++	bool "USB SOF patch"
++	help
++	  Help not implemented yet, coming soon.
++
++config I2C_SPI_UCODE_PATCH
++	bool "I2C/SPI relocation patch"
++	help
++	  Help not implemented yet, coming soon.
++
++config I2C_SPI_SMC1_UCODE_PATCH
++	bool "I2C/SPI/SMC1 relocation patch"
++	help
++	  Help not implemented yet, coming soon.
++
++endchoice
++
++config UCODE_PATCH
++	bool
++	default y
++	depends on !NO_UCODE_PATCH
++
++endmenu
++
+diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/Makefile
+@@ -0,0 +1,13 @@
++ifeq ($(CONFIG_PPC_MERGE),y)
++obj-$(CONFIG_PPC_PMAC)		+= powermac/
++else
++ifeq ($(CONFIG_PPC64),y)
++obj-$(CONFIG_PPC_PMAC)		+= powermac/
++endif
++endif
++obj-$(CONFIG_PPC_CHRP)		+= chrp/
++obj-$(CONFIG_4xx)		+= 4xx/
++obj-$(CONFIG_85xx)		+= 85xx/
++obj-$(CONFIG_PPC_PSERIES)	+= pseries/
++obj-$(CONFIG_PPC_ISERIES)	+= iseries/
++obj-$(CONFIG_PPC_MAPLE)		+= maple/
+diff --git a/arch/powerpc/platforms/apus/Kconfig b/arch/powerpc/platforms/apus/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/apus/Kconfig
+@@ -0,0 +1,130 @@
++
++config AMIGA
++	bool
++	depends on APUS
++	default y
++	help
++	  This option enables support for the Amiga series of computers.
++
++config ZORRO
++	bool
++	depends on APUS
++	default y
++	help
++	  This enables support for the Zorro bus in the Amiga. If you have
++	  expansion cards in your Amiga that conform to the Amiga
++	  AutoConfig(tm) specification, say Y, otherwise N. Note that even
++	  expansion cards that do not fit in the Zorro slots but fit in e.g.
++	  the CPU slot may fall in this category, so you have to say Y to let
++	  Linux use these.
++
++config ABSTRACT_CONSOLE
++	bool
++	depends on APUS
++	default y
++
++config APUS_FAST_EXCEPT
++	bool
++	depends on APUS
++	default y
++
++config AMIGA_PCMCIA
++	bool "Amiga 1200/600 PCMCIA support"
++	depends on APUS && EXPERIMENTAL
++	help
++	  Include support in the kernel for pcmcia on Amiga 1200 and Amiga
++	  600. If you intend to use pcmcia cards say Y; otherwise say N.
++
++config AMIGA_BUILTIN_SERIAL
++	tristate "Amiga builtin serial support"
++	depends on APUS
++	help
++	  If you want to use your Amiga's built-in serial port in Linux,
++	  answer Y.
++
++	  To compile this driver as a module, choose M here.
++
++config GVPIOEXT
++	tristate "GVP IO-Extender support"
++	depends on APUS
++	help
++	  If you want to use a GVP IO-Extender serial card in Linux, say Y.
++	  Otherwise, say N.
++
++config GVPIOEXT_LP
++	tristate "GVP IO-Extender parallel printer support"
++	depends on GVPIOEXT
++	help
++	  Say Y to enable driving a printer from the parallel port on your
++	  GVP IO-Extender card, N otherwise.
++
++config GVPIOEXT_PLIP
++	tristate "GVP IO-Extender PLIP support"
++	depends on GVPIOEXT
++	help
++	  Say Y to enable doing IP over the parallel port on your GVP
++	  IO-Extender card, N otherwise.
++
++config MULTIFACE_III_TTY
++	tristate "Multiface Card III serial support"
++	depends on APUS
++	help
++	  If you want to use a Multiface III card's serial port in Linux,
++	  answer Y.
++
++	  To compile this driver as a module, choose M here.
++
++config A2232
++	tristate "Commodore A2232 serial support (EXPERIMENTAL)"
++	depends on EXPERIMENTAL && APUS
++	---help---
++	  This option supports the 2232 7-port serial card shipped with the
++	  Amiga 2000 and other Zorro-bus machines, dating from 1989.  At
++	  a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip
++	  each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The
++	  ports were connected with 8 pin DIN connectors on the card bracket,
++	  for which 8 pin to DB25 adapters were supplied. The card also had
++	  jumpers internally to toggle various pinning configurations.
++
++	  This driver can be built as a module; but then "generic_serial"
++	  will also be built as a module. This has to be loaded before
++	  "ser_a2232". If you want to do this, answer M here.
++
++config WHIPPET_SERIAL
++	tristate "Hisoft Whippet PCMCIA serial support"
++	depends on AMIGA_PCMCIA
++	help
++	  HiSoft has a web page at <http://www.hisoft.co.uk/>, but there
++	  is no listing for the Whippet in their Amiga section.
++
++config APNE
++	tristate "PCMCIA NE2000 support"
++	depends on AMIGA_PCMCIA
++	help
++	  If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise,
++	  say N.
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called apne.
++
++config SERIAL_CONSOLE
++	bool "Support for serial port console"
++	depends on APUS && (AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y)
++
++config HEARTBEAT
++	bool "Use power LED as a heartbeat"
++	depends on APUS
++	help
++	  Use the power-on LED on your machine as a load meter.  The exact
++	  behavior is platform-dependent, but normally the flash frequency is
++	  a hyperbolic function of the 5-minute load average.
++
++config PROC_HARDWARE
++	bool "/proc/hardware support"
++	depends on APUS
++
++source "drivers/zorro/Kconfig"
++
++config PCI_PERMEDIA
++	bool "PCI for Permedia2"
++	depends on !4xx && !8xx && APUS
+diff --git a/arch/powerpc/platforms/chrp/Makefile b/arch/powerpc/platforms/chrp/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/chrp/Makefile
+@@ -0,0 +1,4 @@
++obj-y				+= setup.o time.o pegasos_eth.o
++obj-$(CONFIG_PCI)		+= pci.o
++obj-$(CONFIG_SMP)		+= smp.o
++obj-$(CONFIG_NVRAM)		+= nvram.o
+diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/chrp/chrp.h
+@@ -0,0 +1,12 @@
++/*
++ * Declarations of CHRP platform-specific things.
++ */
++
++extern void chrp_nvram_init(void);
++extern void chrp_get_rtc_time(struct rtc_time *);
++extern int chrp_set_rtc_time(struct rtc_time *);
++extern void chrp_calibrate_decr(void);
++extern long chrp_time_init(void);
++
++extern void chrp_find_bridges(void);
++extern void chrp_event_scan(void);
+diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/chrp/nvram.c
+@@ -0,0 +1,84 @@
++/*
++ *  c 2001 PPC 64 Team, IBM Corp
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ *
++ * /dev/nvram driver for PPC
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <asm/uaccess.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++#include "chrp.h"
++
++static unsigned int nvram_size;
++static unsigned char nvram_buf[4];
++static DEFINE_SPINLOCK(nvram_lock);
++
++static unsigned char chrp_nvram_read(int addr)
++{
++	unsigned long done, flags;
++	unsigned char ret;
++
++	if (addr >= nvram_size) {
++		printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n",
++		       current->comm, addr, nvram_size);
++		return 0xff;
++	}
++	spin_lock_irqsave(&nvram_lock, flags);
++	if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
++		ret = 0xff;
++	else
++		ret = nvram_buf[0];
++	spin_unlock_irqrestore(&nvram_lock, flags);
++
++	return ret;
++}
++
++static void chrp_nvram_write(int addr, unsigned char val)
++{
++	unsigned long done, flags;
++
++	if (addr >= nvram_size) {
++		printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n",
++		       current->comm, addr, nvram_size);
++		return;
++	}
++	spin_lock_irqsave(&nvram_lock, flags);
++	nvram_buf[0] = val;
++	if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
++		printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr);
++	spin_unlock_irqrestore(&nvram_lock, flags);
++}
++
++void __init chrp_nvram_init(void)
++{
++	struct device_node *nvram;
++	unsigned int *nbytes_p, proplen;
++
++	nvram = of_find_node_by_type(NULL, "nvram");
++	if (nvram == NULL)
++		return;
++
++	nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
++	if (nbytes_p == NULL || proplen != sizeof(unsigned int))
++		return;
++
++	nvram_size = *nbytes_p;
++
++	printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
++	of_node_put(nvram);
++
++	ppc_md.nvram_read_val = chrp_nvram_read;
++	ppc_md.nvram_write_val = chrp_nvram_write;
++
++	return;
++}
+diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/chrp/pci.c
+@@ -0,0 +1,310 @@
++/*
++ * CHRP pci routines.
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/ide.h>
++
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/irq.h>
++#include <asm/hydra.h>
++#include <asm/prom.h>
++#include <asm/gg2.h>
++#include <asm/machdep.h>
++#include <asm/sections.h>
++#include <asm/pci-bridge.h>
++#include <asm/open_pic.h>
++#include <asm/grackle.h>
++#include <asm/rtas.h>
++
++/* LongTrail */
++void __iomem *gg2_pci_config_base;
++
++/*
++ * The VLSI Golden Gate II has only 512K of PCI configuration space, so we
++ * limit the bus number to 3 bits
++ */
++
++int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
++			   int len, u32 *val)
++{
++	volatile void __iomem *cfg_data;
++	struct pci_controller *hose = bus->sysdata;
++
++	if (bus->number > 7)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	/*
++	 * Note: the caller has already checked that off is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
++	switch (len) {
++	case 1:
++		*val =  in_8(cfg_data);
++		break;
++	case 2:
++		*val = in_le16(cfg_data);
++		break;
++	default:
++		*val = in_le32(cfg_data);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
++			    int len, u32 val)
++{
++	volatile void __iomem *cfg_data;
++	struct pci_controller *hose = bus->sysdata;
++
++	if (bus->number > 7)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	/*
++	 * Note: the caller has already checked that off is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
++	switch (len) {
++	case 1:
++		out_8(cfg_data, val);
++		break;
++	case 2:
++		out_le16(cfg_data, val);
++		break;
++	default:
++		out_le32(cfg_data, val);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops gg2_pci_ops =
++{
++	gg2_read_config,
++	gg2_write_config
++};
++
++/*
++ * Access functions for PCI config space using RTAS calls.
++ */
++int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
++		     int len, u32 *val)
++{
++	struct pci_controller *hose = bus->sysdata;
++	unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
++		| (((bus->number - hose->first_busno) & 0xff) << 16)
++		| (hose->index << 24);
++        int ret = -1;
++	int rval;
++
++	rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len);
++	*val = ret;
++	return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
++}
++
++int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
++		      int len, u32 val)
++{
++	struct pci_controller *hose = bus->sysdata;
++	unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
++		| (((bus->number - hose->first_busno) & 0xff) << 16)
++		| (hose->index << 24);
++	int rval;
++
++	rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
++			 addr, len, val);
++	return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops rtas_pci_ops =
++{
++	rtas_read_config,
++	rtas_write_config
++};
++
++volatile struct Hydra __iomem *Hydra = NULL;
++
++int __init
++hydra_init(void)
++{
++	struct device_node *np;
++
++	np = find_devices("mac-io");
++	if (np == NULL || np->n_addrs == 0)
++		return 0;
++	Hydra = ioremap(np->addrs[0].address, np->addrs[0].size);
++	printk("Hydra Mac I/O at %lx\n", np->addrs[0].address);
++	printk("Hydra Feature_Control was %x",
++	       in_le32(&Hydra->Feature_Control));
++	out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN |
++					   HYDRA_FC_SCSI_CELL_EN |
++					   HYDRA_FC_SCCA_ENABLE |
++					   HYDRA_FC_SCCB_ENABLE |
++					   HYDRA_FC_ARB_BYPASS |
++					   HYDRA_FC_MPIC_ENABLE |
++					   HYDRA_FC_SLOW_SCC_PCLK |
++					   HYDRA_FC_MPIC_IS_MASTER));
++	printk(", now %x\n", in_le32(&Hydra->Feature_Control));
++	return 1;
++}
++
++void __init
++chrp_pcibios_fixup(void)
++{
++	struct pci_dev *dev = NULL;
++	struct device_node *np;
++
++	/* PCI interrupts are controlled by the OpenPIC */
++	for_each_pci_dev(dev) {
++		np = pci_device_to_OF_node(dev);
++		if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
++			dev->irq = np->intrs[0].line;
++		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
++	}
++}
++
++#define PRG_CL_RESET_VALID 0x00010000
++
++static void __init
++setup_python(struct pci_controller *hose, struct device_node *dev)
++{
++	u32 __iomem *reg;
++	u32 val;
++	unsigned long addr = dev->addrs[0].address;
++
++	setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010);
++
++	/* Clear the magic go-slow bit */
++	reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40);
++	val = in_be32(&reg[12]);
++	if (val & PRG_CL_RESET_VALID) {
++		out_be32(&reg[12], val & ~PRG_CL_RESET_VALID);
++		in_be32(&reg[12]);
++	}
++	iounmap(reg);
++}
++
++/* Marvell Discovery II based Pegasos 2 */
++static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev)
++{
++	struct device_node *root = find_path_device("/");
++	struct device_node *rtas;
++
++	rtas = of_find_node_by_name (root, "rtas");
++	if (rtas) {
++		hose->ops = &rtas_pci_ops;
++	} else {
++		printk ("RTAS supporting Pegasos OF not found, please upgrade"
++			" your firmware\n");
++	}
++	pci_assign_all_buses = 1;
++}
++
++void __init
++chrp_find_bridges(void)
++{
++	struct device_node *dev;
++	int *bus_range;
++	int len, index = -1;
++	struct pci_controller *hose;
++	unsigned int *dma;
++	char *model, *machine;
++	int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
++	struct device_node *root = find_path_device("/");
++
++	/*
++	 * The PCI host bridge nodes on some machines don't have
++	 * properties to adequately identify them, so we have to
++	 * look at what sort of machine this is as well.
++	 */
++	machine = get_property(root, "model", NULL);
++	if (machine != NULL) {
++		is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0;
++		is_mot = strncmp(machine, "MOT", 3) == 0;
++		if (strncmp(machine, "Pegasos2", 8) == 0)
++			is_pegasos = 2;
++		else if (strncmp(machine, "Pegasos", 7) == 0)
++			is_pegasos = 1;
++	}
++	for (dev = root->child; dev != NULL; dev = dev->sibling) {
++		if (dev->type == NULL || strcmp(dev->type, "pci") != 0)
++			continue;
++		++index;
++		/* The GG2 bridge on the LongTrail doesn't have an address */
++		if (dev->n_addrs < 1 && !is_longtrail) {
++			printk(KERN_WARNING "Can't use %s: no address\n",
++			       dev->full_name);
++			continue;
++		}
++		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\n",
++				dev->full_name);
++			continue;
++		}
++		if (bus_range[1] == bus_range[0])
++			printk(KERN_INFO "PCI bus %d", bus_range[0]);
++		else
++			printk(KERN_INFO "PCI buses %d..%d",
++			       bus_range[0], bus_range[1]);
++		printk(" controlled by %s", dev->type);
++		if (dev->n_addrs > 0)
++			printk(" at %lx", dev->addrs[0].address);
++		printk("\n");
++
++		hose = pcibios_alloc_controller();
++		if (!hose) {
++			printk("Can't allocate PCI controller structure for %s\n",
++				dev->full_name);
++			continue;
++		}
++		hose->arch_data = dev;
++		hose->first_busno = bus_range[0];
++		hose->last_busno = bus_range[1];
++
++		model = get_property(dev, "model", NULL);
++		if (model == NULL)
++			model = "<none>";
++		if (device_is_compatible(dev, "IBM,python")) {
++			setup_python(hose, dev);
++		} else if (is_mot
++			   || strncmp(model, "Motorola, Grackle", 17) == 0) {
++			setup_grackle(hose);
++		} else if (is_longtrail) {
++			void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
++			hose->ops = &gg2_pci_ops;
++			hose->cfg_data = p;
++			gg2_pci_config_base = p;
++		} else if (is_pegasos == 1) {
++			setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
++		} else if (is_pegasos == 2) {
++			setup_peg2(hose, dev);
++		} else {
++			printk("No methods for %s (model %s), using RTAS\n",
++			       dev->full_name, model);
++			hose->ops = &rtas_pci_ops;
++		}
++
++		pci_process_bridge_OF_ranges(hose, dev, index == 0);
++
++		/* check the first bridge for a property that we can
++		   use to set pci_dram_offset */
++		dma = (unsigned int *)
++			get_property(dev, "ibm,dma-ranges", &len);
++		if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
++			pci_dram_offset = dma[2] - dma[3];
++			printk("pci_dram_offset = %lx\n", pci_dram_offset);
++		}
++	}
++
++	/* Do not fixup interrupts from OF tree on pegasos */
++	if (is_pegasos == 0)
++		ppc_md.pcibios_fixup = chrp_pcibios_fixup;
++}
+diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
+@@ -0,0 +1,213 @@
++/*
++ *  arch/ppc/platforms/chrp_pegasos_eth.c
++ *
++ *  Copyright (C) 2005 Sven Luther <sl at bplan-gmbh.de>
++ *  Thanks to :
++ *	Dale Farnsworth <dale at farnsworth.org>
++ *	Mark A. Greer <mgreer at mvista.com>
++ *	Nicolas DET <nd at bplan-gmbh.de>
++ *	Benjamin Herrenschmidt <benh at kernel.crashing.org>
++ *  And anyone else who helped me on this.
++ */
++
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/device.h>
++#include <linux/mv643xx.h>
++#include <linux/pci.h>
++
++#define PEGASOS2_MARVELL_REGBASE 		(0xf1000000)
++#define PEGASOS2_MARVELL_REGSIZE 		(0x00004000)
++#define PEGASOS2_SRAM_BASE 			(0xf2000000)
++#define PEGASOS2_SRAM_SIZE			(256*1024)
++
++#define PEGASOS2_SRAM_BASE_ETH0			(PEGASOS2_SRAM_BASE)
++#define PEGASOS2_SRAM_BASE_ETH1			(PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) )
++
++
++#define PEGASOS2_SRAM_RXRING_SIZE		(PEGASOS2_SRAM_SIZE/4)
++#define PEGASOS2_SRAM_TXRING_SIZE		(PEGASOS2_SRAM_SIZE/4)
++
++#undef BE_VERBOSE
++
++static struct resource mv643xx_eth_shared_resources[] = {
++	[0] = {
++		.name	= "ethernet shared base",
++		.start	= 0xf1000000 + MV643XX_ETH_SHARED_REGS,
++		.end	= 0xf1000000 + MV643XX_ETH_SHARED_REGS +
++					MV643XX_ETH_SHARED_REGS_SIZE - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++};
++
++static struct platform_device mv643xx_eth_shared_device = {
++	.name		= MV643XX_ETH_SHARED_NAME,
++	.id		= 0,
++	.num_resources	= ARRAY_SIZE(mv643xx_eth_shared_resources),
++	.resource	= mv643xx_eth_shared_resources,
++};
++
++static struct resource mv643xx_eth0_resources[] = {
++	[0] = {
++		.name	= "eth0 irq",
++		.start	= 9,
++		.end	= 9,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++
++static struct mv643xx_eth_platform_data eth0_pd = {
++	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
++	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
++	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
++
++	.rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE,
++	.rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
++	.rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
++};
++
++static struct platform_device eth0_device = {
++	.name		= MV643XX_ETH_NAME,
++	.id		= 0,
++	.num_resources	= ARRAY_SIZE(mv643xx_eth0_resources),
++	.resource	= mv643xx_eth0_resources,
++	.dev = {
++		.platform_data = &eth0_pd,
++	},
++};
++
++static struct resource mv643xx_eth1_resources[] = {
++	[0] = {
++		.name	= "eth1 irq",
++		.start	= 9,
++		.end	= 9,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct mv643xx_eth_platform_data eth1_pd = {
++	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
++	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
++	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
++
++	.rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE,
++	.rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
++	.rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
++};
++
++static struct platform_device eth1_device = {
++	.name		= MV643XX_ETH_NAME,
++	.id		= 1,
++	.num_resources	= ARRAY_SIZE(mv643xx_eth1_resources),
++	.resource	= mv643xx_eth1_resources,
++	.dev = {
++		.platform_data = &eth1_pd,
++	},
++};
++
++static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
++	&mv643xx_eth_shared_device,
++	&eth0_device,
++	&eth1_device,
++};
++
++/***********/
++/***********/
++#define MV_READ(offset,val) 	{ val = readl(mv643xx_reg_base + offset); }
++#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset)
++
++static void __iomem *mv643xx_reg_base;
++
++static int Enable_SRAM(void)
++{
++	u32 ALong;
++
++	if (mv643xx_reg_base == NULL)
++		mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE,
++					PEGASOS2_MARVELL_REGSIZE);
++
++	if (mv643xx_reg_base == NULL)
++		return -ENOMEM;
++
++#ifdef BE_VERBOSE
++	printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n",
++		(void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base);
++#endif
++
++	MV_WRITE(MV64340_SRAM_CONFIG, 0);
++
++	MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16);
++
++	MV_READ(MV64340_BASE_ADDR_ENABLE, ALong);
++	ALong &= ~(1 << 19);
++	MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong);
++
++	ALong = 0x02;
++	ALong |= PEGASOS2_SRAM_BASE & 0xffff0000;
++	MV_WRITE(MV643XX_ETH_BAR_4, ALong);
++
++	MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000);
++
++	MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
++	ALong &= ~(1 << 4);
++	MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
++
++#ifdef BE_VERBOSE
++	printk("Pegasos II/Marvell MV64361: register unmapped\n");
++	printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE);
++#endif
++
++	iounmap(mv643xx_reg_base);
++	mv643xx_reg_base = NULL;
++
++	return 1;
++}
++
++
++/***********/
++/***********/
++int mv643xx_eth_add_pds(void)
++{
++	int ret = 0;
++	static struct pci_device_id pci_marvell_mv64360[] = {
++		{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) },
++		{ }
++	};
++
++#ifdef BE_VERBOSE
++	printk("Pegasos II/Marvell MV64361: init\n");
++#endif
++
++	if (pci_dev_present(pci_marvell_mv64360)) {
++		ret = platform_add_devices(mv643xx_eth_pd_devs,
++				ARRAY_SIZE(mv643xx_eth_pd_devs));
++
++		if ( Enable_SRAM() < 0)
++		{
++			eth0_pd.tx_sram_addr = 0;
++			eth0_pd.tx_sram_size = 0;
++			eth0_pd.rx_sram_addr = 0;
++			eth0_pd.rx_sram_size = 0;
++
++			eth1_pd.tx_sram_addr = 0;
++			eth1_pd.tx_sram_size = 0;
++			eth1_pd.rx_sram_addr = 0;
++			eth1_pd.rx_sram_size = 0;
++
++#ifdef BE_VERBOSE
++			printk("Pegasos II/Marvell MV64361: Can't enable the "
++				"SRAM\n");
++#endif
++		}
++	}
++
++#ifdef BE_VERBOSE
++	printk("Pegasos II/Marvell MV64361: init is over\n");
++#endif
++
++	return ret;
++}
++
++device_initcall(mv643xx_eth_add_pds);
+diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/chrp/setup.c
+@@ -0,0 +1,522 @@
++/*
++ *  arch/ppc/platforms/setup.c
++ *
++ *  Copyright (C) 1995  Linus Torvalds
++ *  Adapted from 'alpha' version by Gary Thomas
++ *  Modified by Cort Dougan (cort at cs.nmt.edu)
++ */
++
++/*
++ * bootup setup stuff..
++ */
++
++#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/stddef.h>
++#include <linux/unistd.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/user.h>
++#include <linux/a.out.h>
++#include <linux/tty.h>
++#include <linux/major.h>
++#include <linux/interrupt.h>
++#include <linux/reboot.h>
++#include <linux/init.h>
++#include <linux/pci.h>
++#include <linux/version.h>
++#include <linux/adb.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/ide.h>
++#include <linux/console.h>
++#include <linux/seq_file.h>
++#include <linux/root_dev.h>
++#include <linux/initrd.h>
++#include <linux/module.h>
++
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/prom.h>
++#include <asm/gg2.h>
++#include <asm/pci-bridge.h>
++#include <asm/dma.h>
++#include <asm/machdep.h>
++#include <asm/irq.h>
++#include <asm/hydra.h>
++#include <asm/sections.h>
++#include <asm/time.h>
++#include <asm/btext.h>
++#include <asm/i8259.h>
++#include <asm/mpic.h>
++#include <asm/rtas.h>
++#include <asm/xmon.h>
++
++#include "chrp.h"
++
++void rtas_indicator_progress(char *, unsigned short);
++void btext_progress(char *, unsigned short);
++
++int _chrp_type;
++EXPORT_SYMBOL(_chrp_type);
++
++struct mpic *chrp_mpic;
++
++/*
++ * XXX this should be in xmon.h, but putting it there means xmon.h
++ * has to include <linux/interrupt.h> (to get irqreturn_t), which
++ * causes all sorts of problems.  -- paulus
++ */
++extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
++
++extern unsigned long loops_per_jiffy;
++
++#ifdef CONFIG_SMP
++extern struct smp_ops_t chrp_smp_ops;
++#endif
++
++static const char *gg2_memtypes[4] = {
++	"FPM", "SDRAM", "EDO", "BEDO"
++};
++static const char *gg2_cachesizes[4] = {
++	"256 KB", "512 KB", "1 MB", "Reserved"
++};
++static const char *gg2_cachetypes[4] = {
++	"Asynchronous", "Reserved", "Flow-Through Synchronous",
++	"Pipelined Synchronous"
++};
++static const char *gg2_cachemodes[4] = {
++	"Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
++};
++
++void chrp_show_cpuinfo(struct seq_file *m)
++{
++	int i, sdramen;
++	unsigned int t;
++	struct device_node *root;
++	const char *model = "";
++
++	root = find_path_device("/");
++	if (root)
++		model = get_property(root, "model", NULL);
++	seq_printf(m, "machine\t\t: CHRP %s\n", model);
++
++	/* longtrail (goldengate) stuff */
++	if (!strncmp(model, "IBM,LongTrail", 13)) {
++		/* VLSI VAS96011/12 `Golden Gate 2' */
++		/* Memory banks */
++		sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL)
++			   >>31) & 1;
++		for (i = 0; i < (sdramen ? 4 : 6); i++) {
++			t = in_le32(gg2_pci_config_base+
++						 GG2_PCI_DRAM_BANK0+
++						 i*4);
++			if (!(t & 1))
++				continue;
++			switch ((t>>8) & 0x1f) {
++			case 0x1f:
++				model = "4 MB";
++				break;
++			case 0x1e:
++				model = "8 MB";
++				break;
++			case 0x1c:
++				model = "16 MB";
++				break;
++			case 0x18:
++				model = "32 MB";
++				break;
++			case 0x10:
++				model = "64 MB";
++				break;
++			case 0x00:
++				model = "128 MB";
++				break;
++			default:
++				model = "Reserved";
++				break;
++			}
++			seq_printf(m, "memory bank %d\t: %s %s\n", i, model,
++				   gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]);
++		}
++		/* L2 cache */
++		t = in_le32(gg2_pci_config_base+GG2_PCI_CC_CTRL);
++		seq_printf(m, "board l2\t: %s %s (%s)\n",
++			   gg2_cachesizes[(t>>7) & 3],
++			   gg2_cachetypes[(t>>2) & 3],
++			   gg2_cachemodes[t & 3]);
++	}
++}
++
++/*
++ *  Fixes for the National Semiconductor PC78308VUL SuperI/O
++ *
++ *  Some versions of Open Firmware incorrectly initialize the IRQ settings
++ *  for keyboard and mouse
++ */
++static inline void __init sio_write(u8 val, u8 index)
++{
++	outb(index, 0x15c);
++	outb(val, 0x15d);
++}
++
++static inline u8 __init sio_read(u8 index)
++{
++	outb(index, 0x15c);
++	return inb(0x15d);
++}
++
++static void __init sio_fixup_irq(const char *name, u8 device, u8 level,
++				     u8 type)
++{
++	u8 level0, type0, active;
++
++	/* select logical device */
++	sio_write(device, 0x07);
++	active = sio_read(0x30);
++	level0 = sio_read(0x70);
++	type0 = sio_read(0x71);
++	if (level0 != level || type0 != type || !active) {
++		printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: "
++		       "remapping to level %d, type %d, active\n",
++		       name, level0, type0, !active ? "in" : "", level, type);
++		sio_write(0x01, 0x30);
++		sio_write(level, 0x70);
++		sio_write(type, 0x71);
++	}
++}
++
++static void __init sio_init(void)
++{
++	struct device_node *root;
++
++	if ((root = find_path_device("/")) &&
++	    !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) {
++		/* logical device 0 (KBC/Keyboard) */
++		sio_fixup_irq("keyboard", 0, 1, 2);
++		/* select logical device 1 (KBC/Mouse) */
++		sio_fixup_irq("mouse", 1, 12, 2);
++	}
++}
++
++
++static void __init pegasos_set_l2cr(void)
++{
++	struct device_node *np;
++
++	/* On Pegasos, enable the l2 cache if needed, as the OF forgets it */
++	if (_chrp_type != _CHRP_Pegasos)
++		return;
++
++	/* Enable L2 cache if needed */
++	np = find_type_devices("cpu");
++	if (np != NULL) {
++		unsigned int *l2cr = (unsigned int *)
++			get_property (np, "l2cr", NULL);
++		if (l2cr == NULL) {
++			printk ("Pegasos l2cr : no cpu l2cr property found\n");
++			return;
++		}
++		if (!((*l2cr) & 0x80000000)) {
++			printk ("Pegasos l2cr : L2 cache was not active, "
++				"activating\n");
++			_set_L2CR(0);
++			_set_L2CR((*l2cr) | 0x80000000);
++		}
++	}
++}
++
++void __init chrp_setup_arch(void)
++{
++	struct device_node *root = find_path_device ("/");
++	char *machine = NULL;
++	struct device_node *device;
++	unsigned int *p = NULL;
++
++	/* init to some ~sane value until calibrate_delay() runs */
++	loops_per_jiffy = 50000000/HZ;
++
++	if (root)
++		machine = get_property(root, "model", NULL);
++	if (machine && strncmp(machine, "Pegasos", 7) == 0) {
++		_chrp_type = _CHRP_Pegasos;
++	} else if (machine && strncmp(machine, "IBM", 3) == 0) {
++		_chrp_type = _CHRP_IBM;
++	} else if (machine && strncmp(machine, "MOT", 3) == 0) {
++		_chrp_type = _CHRP_Motorola;
++	} else {
++		/* Let's assume it is an IBM chrp if all else fails */
++		_chrp_type = _CHRP_IBM;
++	}
++	printk("chrp type = %x\n", _chrp_type);
++
++	rtas_initialize();
++	if (rtas_token("display-character") >= 0)
++		ppc_md.progress = rtas_progress;
++
++#ifdef CONFIG_BOOTX_TEXT
++	if (ppc_md.progress == NULL && boot_text_mapped)
++		ppc_md.progress = btext_progress;
++#endif
++
++#ifdef CONFIG_BLK_DEV_INITRD
++	/* this is fine for chrp */
++	initrd_below_start_ok = 1;
++
++	if (initrd_start)
++		ROOT_DEV = Root_RAM0;
++	else
++#endif
++		ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
++
++	/* On pegasos, enable the L2 cache if not already done by OF */
++	pegasos_set_l2cr();
++
++	/* Lookup PCI host bridges */
++	chrp_find_bridges();
++
++	/*
++	 *  Temporary fixes for PCI devices.
++	 *  -- Geert
++	 */
++	hydra_init();		/* Mac I/O */
++
++	/*
++	 *  Fix the Super I/O configuration
++	 */
++	sio_init();
++
++	/* Get the event scan rate for the rtas so we know how
++	 * often it expects a heartbeat. -- Cort
++	 */
++	device = find_devices("rtas");
++	if (device)
++		p = (unsigned int *) get_property
++			(device, "rtas-event-scan-rate", NULL);
++	if (p && *p) {
++		ppc_md.heartbeat = chrp_event_scan;
++		ppc_md.heartbeat_reset = HZ / (*p * 30) - 1;
++		ppc_md.heartbeat_count = 1;
++		printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
++		       *p, ppc_md.heartbeat_reset);
++	}
++
++	pci_create_OF_bus_map();
++
++	/*
++	 * Print the banner, then scroll down so boot progress
++	 * can be printed.  -- Cort
++	 */
++	if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
++}
++
++void
++chrp_event_scan(void)
++{
++	unsigned char log[1024];
++	int ret = 0;
++
++	/* XXX: we should loop until the hardware says no more error logs -- Cort */
++	rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0,
++		  __pa(log), 1024);
++	ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
++}
++
++/*
++ * Finds the open-pic node and sets up the mpic driver.
++ */
++static void __init chrp_find_openpic(void)
++{
++	struct device_node *np, *root;
++	int len, i, j, irq_count;
++	int isu_size, idu_size;
++	unsigned int *iranges, *opprop = NULL;
++	int oplen = 0;
++	unsigned long opaddr;
++	int na = 1;
++	unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
++
++	np = find_type_devices("open-pic");
++	if (np == NULL)
++		return;
++	root = find_path_device("/");
++	if (root) {
++		opprop = (unsigned int *) get_property
++			(root, "platform-open-pic", &oplen);
++		na = prom_n_addr_cells(root);
++	}
++	if (opprop && oplen >= na * sizeof(unsigned int)) {
++		opaddr = opprop[na-1];	/* assume 32-bit */
++		oplen /= na * sizeof(unsigned int);
++	} else {
++		if (np->n_addrs == 0)
++			return;
++		opaddr = np->addrs[0].address;
++		oplen = 0;
++	}
++
++	printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
++
++	irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
++	prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS - 4);
++
++	iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
++	if (iranges == NULL)
++		len = 0;	/* non-distributed mpic */
++	else
++		len /= 2 * sizeof(unsigned int);
++
++	/*
++	 * The first pair of cells in interrupt-ranges refers to the
++	 * IDU; subsequent pairs refer to the ISUs.
++	 */
++	if (oplen < len) {
++		printk(KERN_ERR "Insufficient addresses for distributed"
++		       " OpenPIC (%d < %d)\n", np->n_addrs, len);
++		len = oplen;
++	}
++
++	isu_size = 0;
++	idu_size = 0;
++	if (len > 0 && iranges[1] != 0) {
++		printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n",
++		       iranges[0], iranges[0] + iranges[1] - 1);
++		idu_size = iranges[1];
++	}
++	if (len > 1)
++		isu_size = iranges[3];
++
++	chrp_mpic = mpic_alloc(opaddr, MPIC_PRIMARY,
++			       isu_size, NUM_ISA_INTERRUPTS, irq_count,
++			       NR_IRQS - 4, init_senses, irq_count,
++			       " MPIC    ");
++	if (chrp_mpic == NULL) {
++		printk(KERN_ERR "Failed to allocate MPIC structure\n");
++		return;
++	}
++
++	j = na - 1;
++	for (i = 1; i < len; ++i) {
++		iranges += 2;
++		j += na;
++		printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x\n",
++		       iranges[0], iranges[0] + iranges[1] - 1,
++		       opprop[j]);
++		mpic_assign_isu(chrp_mpic, i - 1, opprop[j]);
++	}
++
++	mpic_init(chrp_mpic);
++	mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL);
++}
++
++#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
++static struct irqaction xmon_irqaction = {
++	.handler = xmon_irq,
++	.mask = CPU_MASK_NONE,
++	.name = "XMON break",
++};
++#endif
++
++void __init chrp_init_IRQ(void)
++{
++	struct device_node *np;
++	unsigned long chrp_int_ack = 0;
++#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
++	struct device_node *kbd;
++#endif
++
++	for (np = find_devices("pci"); np != NULL; np = np->next) {
++		unsigned int *addrp = (unsigned int *)
++			get_property(np, "8259-interrupt-acknowledge", NULL);
++
++		if (addrp == NULL)
++			continue;
++		chrp_int_ack = addrp[prom_n_addr_cells(np)-1];
++		break;
++	}
++	if (np == NULL)
++		printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n");
++
++	chrp_find_openpic();
++
++	i8259_init(chrp_int_ack, 0);
++
++	if (_chrp_type == _CHRP_Pegasos)
++		ppc_md.get_irq        = i8259_irq;
++	else
++		ppc_md.get_irq        = mpic_get_irq;
++
++#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
++	/* see if there is a keyboard in the device tree
++	   with a parent of type "adb" */
++	for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next)
++		if (kbd->parent && kbd->parent->type
++		    && strcmp(kbd->parent->type, "adb") == 0)
++			break;
++	if (kbd)
++		setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction);
++#endif
++}
++
++void __init
++chrp_init2(void)
++{
++#ifdef CONFIG_NVRAM
++	chrp_nvram_init();
++#endif
++
++	request_region(0x20,0x20,"pic1");
++	request_region(0xa0,0x20,"pic2");
++	request_region(0x00,0x20,"dma1");
++	request_region(0x40,0x20,"timer");
++	request_region(0x80,0x10,"dma page reg");
++	request_region(0xc0,0x20,"dma2");
++
++	if (ppc_md.progress)
++		ppc_md.progress("  Have fun!    ", 0x7777);
++}
++
++void __init chrp_init(void)
++{
++	ISA_DMA_THRESHOLD = ~0L;
++	DMA_MODE_READ = 0x44;
++	DMA_MODE_WRITE = 0x48;
++	isa_io_base = CHRP_ISA_IO_BASE;		/* default value */
++	ppc_do_canonicalize_irqs = 1;
++
++	/* Assume we have an 8259... */
++	__irq_offset_value = NUM_ISA_INTERRUPTS;
++
++	ppc_md.setup_arch     = chrp_setup_arch;
++	ppc_md.show_cpuinfo   = chrp_show_cpuinfo;
++
++	ppc_md.init_IRQ       = chrp_init_IRQ;
++	ppc_md.init           = chrp_init2;
++
++	ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
++
++	ppc_md.restart        = rtas_restart;
++	ppc_md.power_off      = rtas_power_off;
++	ppc_md.halt           = rtas_halt;
++
++	ppc_md.time_init      = chrp_time_init;
++	ppc_md.set_rtc_time   = chrp_set_rtc_time;
++	ppc_md.get_rtc_time   = chrp_get_rtc_time;
++	ppc_md.calibrate_decr = chrp_calibrate_decr;
++
++#ifdef CONFIG_SMP
++	smp_ops = &chrp_smp_ops;
++#endif /* CONFIG_SMP */
++}
++
++#ifdef CONFIG_BOOTX_TEXT
++void
++btext_progress(char *s, unsigned short hex)
++{
++	btext_drawstring(s);
++	btext_drawstring("\n");
++}
++#endif /* CONFIG_BOOTX_TEXT */
+diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/chrp/smp.c
+@@ -0,0 +1,122 @@
++/*
++ * Smp support for CHRP machines.
++ *
++ * Written by Cort Dougan (cort at cs.nmt.edu) borrowing a great
++ * deal of code from the sparc and intel versions.
++ *
++ * Copyright (C) 1999 Cort Dougan <cort at cs.nmt.edu>
++ *
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
++#include <linux/kernel_stat.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/spinlock.h>
++
++#include <asm/ptrace.h>
++#include <asm/atomic.h>
++#include <asm/irq.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/sections.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/smp.h>
++#include <asm/residual.h>
++#include <asm/time.h>
++#include <asm/open_pic.h>
++#include <asm/machdep.h>
++#include <asm/smp.h>
++#include <asm/mpic.h>
++
++extern unsigned long smp_chrp_cpu_nr;
++
++static int __init smp_chrp_probe(void)
++{
++	struct device_node *cpus = NULL;
++	unsigned int *reg;
++	int reglen;
++	int ncpus = 0;
++	int cpuid;
++	unsigned int phys;
++
++	/* Count CPUs in the device-tree */
++	cpuid = 1;	/* the boot cpu is logical cpu 0 */
++	while ((cpus = of_find_node_by_type(cpus, "cpu")) != NULL) {
++		phys = ncpus;
++		reg = (unsigned int *) get_property(cpus, "reg", &reglen);
++		if (reg && reglen >= sizeof(unsigned int))
++			/* hmmm, not having a reg property would be bad */
++			phys = *reg;
++		if (phys != boot_cpuid_phys) {
++			set_hard_smp_processor_id(cpuid, phys);
++			++cpuid;
++		}
++	       	++ncpus;
++	}
++
++	printk(KERN_INFO "CHRP SMP probe found %d cpus\n", ncpus);
++
++	/* Nothing more to do if less than 2 of them */
++	if (ncpus <= 1)
++		return 1;
++
++	mpic_request_ipis();
++
++	return ncpus;
++}
++
++static void __devinit smp_chrp_kick_cpu(int nr)
++{
++	*(unsigned long *)KERNELBASE = nr;
++	asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
++}
++
++static void __devinit smp_chrp_setup_cpu(int cpu_nr)
++{
++	mpic_setup_this_cpu();
++}
++
++static DEFINE_SPINLOCK(timebase_lock);
++static unsigned int timebase_upper = 0, timebase_lower = 0;
++
++void __devinit smp_chrp_give_timebase(void)
++{
++	spin_lock(&timebase_lock);
++	rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
++	timebase_upper = get_tbu();
++	timebase_lower = get_tbl();
++	spin_unlock(&timebase_lock);
++
++	while (timebase_upper || timebase_lower)
++		barrier();
++	rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
++}
++
++void __devinit smp_chrp_take_timebase(void)
++{
++	while (!(timebase_upper || timebase_lower))
++		barrier();
++	spin_lock(&timebase_lock);
++	set_tb(timebase_upper, timebase_lower);
++	timebase_upper = 0;
++	timebase_lower = 0;
++	spin_unlock(&timebase_lock);
++	printk("CPU %i taken timebase\n", smp_processor_id());
++}
++
++/* CHRP with openpic */
++struct smp_ops_t chrp_smp_ops = {
++	.message_pass = smp_mpic_message_pass,
++	.probe = smp_chrp_probe,
++	.kick_cpu = smp_chrp_kick_cpu,
++	.setup_cpu = smp_chrp_setup_cpu,
++	.give_timebase = smp_chrp_give_timebase,
++	.take_timebase = smp_chrp_take_timebase,
++};
+diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/chrp/time.c
+@@ -0,0 +1,188 @@
++/*
++ *  arch/ppc/platforms/chrp_time.c
++ *
++ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
++ *
++ * Adapted for PowerPC (PReP) by Gary Thomas
++ * Modified by Cort Dougan (cort at cs.nmt.edu).
++ * Copied and modified from arch/i386/kernel/time.c
++ *
++ */
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/param.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/timex.h>
++#include <linux/kernel_stat.h>
++#include <linux/mc146818rtc.h>
++#include <linux/init.h>
++#include <linux/bcd.h>
++
++#include <asm/io.h>
++#include <asm/nvram.h>
++#include <asm/prom.h>
++#include <asm/sections.h>
++#include <asm/time.h>
++
++extern spinlock_t rtc_lock;
++
++static int nvram_as1 = NVRAM_AS1;
++static int nvram_as0 = NVRAM_AS0;
++static int nvram_data = NVRAM_DATA;
++
++long __init chrp_time_init(void)
++{
++	struct device_node *rtcs;
++	int base;
++
++	rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
++	if (rtcs == NULL)
++		rtcs = find_compatible_devices("rtc", "ds1385-rtc");
++	if (rtcs == NULL || rtcs->addrs == NULL)
++		return 0;
++	base = rtcs->addrs[0].address;
++	nvram_as1 = 0;
++	nvram_as0 = base;
++	nvram_data = base + 1;
++
++	return 0;
++}
++
++int chrp_cmos_clock_read(int addr)
++{
++	if (nvram_as1 != 0)
++		outb(addr>>8, nvram_as1);
++	outb(addr, nvram_as0);
++	return (inb(nvram_data));
++}
++
++void chrp_cmos_clock_write(unsigned long val, int addr)
++{
++	if (nvram_as1 != 0)
++		outb(addr>>8, nvram_as1);
++	outb(addr, nvram_as0);
++	outb(val, nvram_data);
++	return;
++}
++
++/*
++ * Set the hardware clock. -- Cort
++ */
++int chrp_set_rtc_time(struct rtc_time *tmarg)
++{
++	unsigned char save_control, save_freq_select;
++	struct rtc_time tm = *tmarg;
++
++	spin_lock(&rtc_lock);
++
++	save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */
++
++	chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL);
++
++	save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
++
++	chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
++
++        tm.tm_year -= 1900;
++	if (!(save_control & RTC_DM_BINARY) || 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);
++	}
++	chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
++	chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES);
++	chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS);
++	chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH);
++	chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH);
++	chrp_cmos_clock_write(tm.tm_year,RTC_YEAR);
++
++	/* The following flags have to be released exactly in this order,
++	 * otherwise the DS12887 (popular MC146818A clone with integrated
++	 * battery and quartz) will not reset the oscillator and will not
++	 * update precisely 500 ms later. You won't find this mentioned in
++	 * the Dallas Semiconductor data sheets, but who believes data
++	 * sheets anyway ...                           -- Markus Kuhn
++	 */
++	chrp_cmos_clock_write(save_control, RTC_CONTROL);
++	chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT);
++
++	spin_unlock(&rtc_lock);
++	return 0;
++}
++
++void chrp_get_rtc_time(struct rtc_time *tm)
++{
++	unsigned int year, mon, day, hour, min, sec;
++	int uip, i;
++
++	/* The Linux interpretation of the CMOS clock register contents:
++	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
++	 * RTC registers show the second which has precisely just started.
++	 * Let's hope other operating systems interpret the RTC the same way.
++	 */
++
++	/* Since the UIP flag is set for about 2.2 ms and the clock
++	 * is typically written with a precision of 1 jiffy, trying
++	 * to obtain a precision better than a few milliseconds is
++	 * an illusion. Only consistency is interesting, this also
++	 * allows to use the routine for /dev/rtc without a potential
++	 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
++	 */
++
++	for ( i = 0; i<1000000; i++) {
++		uip = chrp_cmos_clock_read(RTC_FREQ_SELECT);
++		sec = chrp_cmos_clock_read(RTC_SECONDS);
++		min = chrp_cmos_clock_read(RTC_MINUTES);
++		hour = chrp_cmos_clock_read(RTC_HOURS);
++		day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
++		mon = chrp_cmos_clock_read(RTC_MONTH);
++		year = chrp_cmos_clock_read(RTC_YEAR);
++		uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT);
++		if ((uip & RTC_UIP)==0) break;
++	}
++
++	if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
++		BCD_TO_BIN(sec);
++		BCD_TO_BIN(min);
++		BCD_TO_BIN(hour);
++		BCD_TO_BIN(day);
++		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 = day;
++	tm->tm_mon = mon;
++	tm->tm_year = year;
++}
++
++
++void __init chrp_calibrate_decr(void)
++{
++	struct device_node *cpu;
++	unsigned int freq, *fp;
++
++	/*
++	 * The cpu node should have a timebase-frequency property
++	 * to tell us the rate at which the decrementer counts.
++	 */
++	freq = 16666000;		/* hardcoded default */
++	cpu = find_type_devices("cpu");
++	if (cpu != 0) {
++		fp = (unsigned int *)
++			get_property(cpu, "timebase-frequency", NULL);
++		if (fp != 0)
++			freq = *fp;
++	}
++	ppc_tb_freq = freq;
++}
+diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/Kconfig
+@@ -0,0 +1,318 @@
++choice
++	prompt "Machine Type"
++	depends on EMBEDDED6xx
++
++config KATANA
++	bool "Artesyn-Katana"
++	help
++	  Select KATANA if configuring an Artesyn KATANA 750i or 3750
++	  cPCI board.
++
++config WILLOW
++	bool "Cogent-Willow"
++
++config CPCI690
++	bool "Force-CPCI690"
++	help
++	  Select CPCI690 if configuring a Force CPCI690 cPCI board.
++
++config POWERPMC250
++	bool "Force-PowerPMC250"
++
++config CHESTNUT
++	bool "IBM 750FX Eval board or 750GX Eval board"
++	help
++	  Select CHESTNUT if configuring an IBM 750FX Eval Board or a
++	  IBM 750GX Eval board.
++
++config SPRUCE
++	bool "IBM-Spruce"
++	select PPC_INDIRECT_PCI
++
++config HDPU
++	bool "Sky-HDPU"
++	help
++	  Select HDPU if configuring a Sky Computers Compute Blade.
++
++config HDPU_FEATURES
++	depends HDPU
++	tristate "HDPU-Features"
++	help
++	  Select to enable HDPU enhanced features.
++
++config EV64260
++	bool "Marvell-EV64260BP"
++	help
++	  Select EV64260 if configuring a Marvell (formerly Galileo)
++	  EV64260BP Evaluation platform.
++
++config LOPEC
++	bool "Motorola-LoPEC"
++	select PPC_I8259
++
++config MVME5100
++	bool "Motorola-MVME5100"
++	select PPC_INDIRECT_PCI
++
++config PPLUS
++	bool "Motorola-PowerPlus"
++	select PPC_I8259
++	select PPC_INDIRECT_PCI
++
++config PRPMC750
++	bool "Motorola-PrPMC750"
++	select PPC_INDIRECT_PCI
++
++config PRPMC800
++	bool "Motorola-PrPMC800"
++	select PPC_INDIRECT_PCI
++
++config SANDPOINT
++	bool "Motorola-Sandpoint"
++	select PPC_I8259
++	help
++	  Select SANDPOINT if configuring for a Motorola Sandpoint X3
++	  (any flavor).
++
++config RADSTONE_PPC7D
++	bool "Radstone Technology PPC7D board"
++	select PPC_I8259
++
++config PAL4
++	bool "SBS-Palomar4"
++
++config GEMINI
++	bool "Synergy-Gemini"
++	select PPC_INDIRECT_PCI
++	depends on BROKEN
++	help
++	  Select Gemini if configuring for a Synergy Microsystems' Gemini
++	  series Single Board Computer.  More information is available at:
++	  <http://www.synergymicro.com/PressRel/97_10_15.html>.
++
++config EST8260
++	bool "EST8260"
++	---help---
++	  The EST8260 is a single-board computer manufactured by Wind River
++	  Systems, Inc. (formerly Embedded Support Tools Corp.) and based on
++	  the MPC8260.  Wind River Systems has a website at
++	  <http://www.windriver.com/>, but the EST8260 cannot be found on it
++	  and has probably been discontinued or rebadged.
++
++config SBC82xx
++	bool "SBC82xx"
++	---help---
++	  SBC PowerQUICC II, single-board computer with MPC82xx CPU
++	  Manufacturer: Wind River Systems, Inc.
++	  Date of Release: May 2003
++	  End of Life: -
++	  URL: <http://www.windriver.com/>
++
++config SBS8260
++	bool "SBS8260"
++
++config RPX8260
++	bool "RPXSUPER"
++
++config TQM8260
++	bool "TQM8260"
++	---help---
++	  MPC8260 based module, little larger than credit card,
++	  up to 128 MB global + 64 MB local RAM, 32 MB Flash,
++	  32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet,
++	  2 x serial ports, ...
++	  Manufacturer: TQ Components, www.tq-group.de
++	  Date of Release: June 2001
++	  End of Life: not yet :-)
++	  URL: <http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf>
++
++config ADS8272
++	bool "ADS8272"
++
++config PQ2FADS
++	bool "Freescale-PQ2FADS"
++	help
++	  Select PQ2FADS if you wish to configure for a Freescale
++	  PQ2FADS board (-VR or -ZU).
++
++config LITE5200
++	bool "Freescale LITE5200 / (IceCube)"
++	select PPC_MPC52xx
++	help
++	  Support for the LITE5200 dev board for the MPC5200 from Freescale.
++	  This is for the LITE5200 version 2.0 board. Don't know if it changes
++	  much but it's only been tested on this board version. I think this
++	  board is also known as IceCube.
++
++config MPC834x_SYS
++	bool "Freescale MPC834x SYS"
++	help
++	  This option enables support for the MPC 834x SYS evaluation board.
++
++	  Be aware that PCI buses can only function when SYS board is plugged
++	  into the PIB (Platform IO Board) board from Freescale which provide
++	  3 PCI slots.  The PIBs PCI initialization is the bootloader's
++	  responsiblilty.
++
++config EV64360
++	bool "Marvell-EV64360BP"
++	help
++	  Select EV64360 if configuring a Marvell EV64360BP Evaluation
++	  platform.
++endchoice
++
++config PQ2ADS
++	bool
++	depends on ADS8272
++	default y
++
++config TQM8xxL
++	bool
++	depends on 8xx && (TQM823L || TQM850L || FPS850L || TQM855L || TQM860L)
++	default y
++
++config PPC_MPC52xx
++	bool
++
++config 8260
++	bool "CPM2 Support" if WILLOW
++	depends on 6xx
++	default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx || PQ2FADS
++	help
++	  The MPC8260 is a typical embedded CPU made by Motorola.  Selecting
++	  this option means that you wish to build a kernel for a machine with
++	  an 8260 class CPU.
++
++config 8272
++	bool
++	depends on 6xx
++	default y if ADS8272
++	select 8260
++	help
++	  The MPC8272 CPM has a different internal dpram setup than other CPM2
++	  devices
++
++config 83xx
++	bool
++	default y if MPC834x_SYS
++
++config MPC834x
++	bool
++	default y if MPC834x_SYS
++
++config CPM2
++	bool
++	depends on 8260 || MPC8560 || MPC8555
++	default y
++	help
++	  The CPM2 (Communications Processor Module) is a coprocessor on
++	  embedded CPUs made by Motorola.  Selecting this option means that
++	  you wish to build a kernel for a machine with a CPM2 coprocessor
++	  on it (826x, 827x, 8560).
++
++config PPC_GEN550
++	bool
++	depends on SANDPOINT || SPRUCE || PPLUS || \
++		PRPMC750 || PRPMC800 || LOPEC || \
++		(EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \
++		83xx
++	default y
++
++config FORCE
++	bool
++	depends on 6xx && POWERPMC250
++	default y
++
++config GT64260
++	bool
++	depends on EV64260 || CPCI690
++	default y
++
++config MV64360		# Really MV64360 & MV64460
++	bool
++	depends on CHESTNUT || KATANA || RADSTONE_PPC7D || HDPU || EV64360
++	default y
++
++config MV64X60
++	bool
++	depends on (GT64260 || MV64360)
++	select PPC_INDIRECT_PCI
++	default y
++
++menu "Set bridge options"
++	depends on MV64X60
++
++config NOT_COHERENT_CACHE
++	bool "Turn off Cache Coherency"
++	default n
++	help
++	  Some 64x60 bridges lock up when trying to enforce cache coherency.
++	  When this option is selected, cache coherency will be turned off.
++	  Note that this can cause other problems (e.g., stale data being
++	  speculatively loaded via a cached mapping).  Use at your own risk.
++
++config MV64X60_BASE
++	hex "Set bridge base used by firmware"
++	default "0xf1000000"
++	help
++	  A firmware can leave the base address of the bridge's registers at
++	  a non-standard location.  If so, set this value to reflect the
++	  address of that non-standard location.
++
++config MV64X60_NEW_BASE
++	hex "Set bridge base used by kernel"
++	default "0xf1000000"
++	help
++	  If the current base address of the bridge's registers is not where
++	  you want it, set this value to the address that you want it moved to.
++
++endmenu
++
++config NONMONARCH_SUPPORT
++	bool "Enable Non-Monarch Support"
++	depends on PRPMC800
++
++config HARRIER
++	bool
++	depends on PRPMC800
++	default y
++
++config EPIC_SERIAL_MODE
++	bool
++	depends on 6xx && (LOPEC || SANDPOINT)
++	default y
++
++config MPC10X_BRIDGE
++	bool
++	depends on POWERPMC250 || LOPEC || SANDPOINT
++	select PPC_INDIRECT_PCI
++	default y
++
++config MPC10X_OPENPIC
++	bool
++	depends on POWERPMC250 || LOPEC || SANDPOINT
++	default y
++
++config MPC10X_STORE_GATHERING
++	bool "Enable MPC10x store gathering"
++	depends on MPC10X_BRIDGE
++
++config SANDPOINT_ENABLE_UART1
++	bool "Enable DUART mode on Sandpoint"
++	depends on SANDPOINT
++	help
++	  If this option is enabled then the MPC824x processor will run
++	  in DUART mode instead of UART mode.
++
++config HARRIER_STORE_GATHERING
++	bool "Enable Harrier store gathering"
++	depends on HARRIER
++
++config MVME5100_IPMC761_PRESENT
++	bool "MVME5100 configured with an IPMC761"
++	depends on MVME5100
++	select PPC_I8259
++
++config SPRUCE_BAUD_33M
++	bool "Spruce baud clock support"
++	depends on SPRUCE
+diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/Kconfig
+@@ -0,0 +1,31 @@
++
++menu "iSeries device drivers"
++	depends on PPC_ISERIES
++
++config VIOCONS
++	tristate "iSeries Virtual Console Support"
++
++config VIODASD
++	tristate "iSeries Virtual I/O disk support"
++	help
++	  If you are running on an iSeries system and you want to use
++ 	  virtual disks created and managed by OS/400, say Y.
++
++config VIOCD
++	tristate "iSeries Virtual I/O CD support"
++	help
++	  If you are running Linux on an IBM iSeries system and you want to
++	  read a CD drive owned by OS/400, say Y here.
++
++config VIOTAPE
++	tristate "iSeries Virtual Tape Support"
++	help
++	  If you are running Linux on an iSeries system and you want Linux
++	  to read and/or write a tape drive owned by OS/400, say Y here.
++
++endmenu
++
++config VIOPATH
++	bool
++	depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
++	default y
+diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/Makefile
+@@ -0,0 +1,9 @@
++EXTRA_CFLAGS	+= -mno-minimal-toc
++
++obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
++	hvcall.o proc.o htab.o iommu.o misc.o
++obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o
++obj-$(CONFIG_IBMVIO) += vio.o
++obj-$(CONFIG_SMP) += smp.o
++obj-$(CONFIG_VIOPATH) += viopath.o
++obj-$(CONFIG_MODULES) += ksyms.o
+diff --git a/arch/powerpc/platforms/iseries/call_hpt.h b/arch/powerpc/platforms/iseries/call_hpt.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/call_hpt.h
+@@ -0,0 +1,101 @@
++/*
++ * Copyright (C) 2001  Mike Corrigan 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
++ */
++#ifndef _PLATFORMS_ISERIES_CALL_HPT_H
++#define _PLATFORMS_ISERIES_CALL_HPT_H
++
++/*
++ * This file contains the "hypervisor call" interface which is used to
++ * drive the hypervisor from the OS.
++ */
++
++#include <asm/iSeries/HvCallSc.h>
++#include <asm/iSeries/HvTypes.h>
++#include <asm/mmu.h>
++
++#define HvCallHptGetHptAddress		HvCallHpt +  0
++#define HvCallHptGetHptPages		HvCallHpt +  1
++#define HvCallHptSetPp			HvCallHpt +  5
++#define HvCallHptSetSwBits		HvCallHpt +  6
++#define HvCallHptUpdate			HvCallHpt +  7
++#define HvCallHptInvalidateNoSyncICache	HvCallHpt +  8
++#define HvCallHptGet			HvCallHpt + 11
++#define HvCallHptFindNextValid		HvCallHpt + 12
++#define HvCallHptFindValid		HvCallHpt + 13
++#define HvCallHptAddValidate		HvCallHpt + 16
++#define HvCallHptInvalidateSetSwBitsGet HvCallHpt + 18
++
++
++static inline u64 HvCallHpt_getHptAddress(void)
++{
++	return HvCall0(HvCallHptGetHptAddress);
++}
++
++static inline u64 HvCallHpt_getHptPages(void)
++{
++	return HvCall0(HvCallHptGetHptPages);
++}
++
++static inline void HvCallHpt_setPp(u32 hpteIndex, u8 value)
++{
++	HvCall2(HvCallHptSetPp, hpteIndex, value);
++}
++
++static inline void HvCallHpt_setSwBits(u32 hpteIndex, u8 bitson, u8 bitsoff)
++{
++	HvCall3(HvCallHptSetSwBits, hpteIndex, bitson, bitsoff);
++}
++
++static inline void HvCallHpt_invalidateNoSyncICache(u32 hpteIndex)
++{
++	HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex);
++}
++
++static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson,
++		u8 bitsoff)
++{
++	u64 compressedStatus;
++
++	compressedStatus = HvCall4(HvCallHptInvalidateSetSwBitsGet,
++			hpteIndex, bitson, bitsoff, 1);
++	HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex);
++	return compressedStatus;
++}
++
++static inline u64 HvCallHpt_findValid(hpte_t *hpte, u64 vpn)
++{
++	return HvCall3Ret16(HvCallHptFindValid, hpte, vpn, 0, 0);
++}
++
++static inline u64 HvCallHpt_findNextValid(hpte_t *hpte, u32 hpteIndex,
++		u8 bitson, u8 bitsoff)
++{
++	return HvCall3Ret16(HvCallHptFindNextValid, hpte, hpteIndex,
++			bitson, bitsoff);
++}
++
++static inline void HvCallHpt_get(hpte_t *hpte, u32 hpteIndex)
++{
++	HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0);
++}
++
++static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, hpte_t *hpte)
++{
++	HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r);
++}
++
++#endif /* _PLATFORMS_ISERIES_CALL_HPT_H */
+diff --git a/arch/powerpc/platforms/iseries/call_pci.h b/arch/powerpc/platforms/iseries/call_pci.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/call_pci.h
+@@ -0,0 +1,290 @@
++/*
++ * Provides the Hypervisor PCI calls for iSeries Linux Parition.
++ * Copyright (C) 2001  <Wayne G Holm> <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
++ *
++ * Change Activity:
++ *   Created, Jan 9, 2001
++ */
++
++#ifndef _PLATFORMS_ISERIES_CALL_PCI_H
++#define _PLATFORMS_ISERIES_CALL_PCI_H
++
++#include <asm/iSeries/HvCallSc.h>
++#include <asm/iSeries/HvTypes.h>
++
++/*
++ * DSA == Direct Select Address
++ * this struct must be 64 bits in total
++ */
++struct HvCallPci_DsaAddr {
++	u16		busNumber;		/* PHB index? */
++	u8		subBusNumber;		/* PCI bus number? */
++	u8		deviceId;		/* device and function? */
++	u8		barNumber;
++	u8		reserved[3];
++};
++
++union HvDsaMap {
++	u64	DsaAddr;
++	struct HvCallPci_DsaAddr Dsa;
++};
++
++struct HvCallPci_LoadReturn {
++	u64		rc;
++	u64		value;
++};
++
++enum HvCallPci_DeviceType {
++	HvCallPci_NodeDevice	= 1,
++	HvCallPci_SpDevice	= 2,
++	HvCallPci_IopDevice     = 3,
++	HvCallPci_BridgeDevice	= 4,
++	HvCallPci_MultiFunctionDevice = 5,
++	HvCallPci_IoaDevice	= 6
++};
++
++
++struct HvCallPci_DeviceInfo {
++	u32	deviceType;		/* See DeviceType enum for values */
++};
++
++struct HvCallPci_BusUnitInfo {
++	u32	sizeReturned;		/* length of data returned */
++	u32	deviceType;		/* see DeviceType enum for values */
++};
++
++struct HvCallPci_BridgeInfo {
++	struct HvCallPci_BusUnitInfo busUnitInfo;  /* Generic bus unit info */
++	u8		subBusNumber;	/* Bus number of secondary bus */
++	u8		maxAgents;	/* Max idsels on secondary bus */
++        u8              maxSubBusNumber; /* Max Sub Bus */
++	u8		logicalSlotNumber; /* Logical Slot Number for IOA */
++};
++
++
++/*
++ * Maximum BusUnitInfo buffer size.  Provided for clients so
++ * they can allocate a buffer big enough for any type of bus
++ * unit.  Increase as needed.
++ */
++enum {HvCallPci_MaxBusUnitInfoSize = 128};
++
++struct HvCallPci_BarParms {
++	u64		vaddr;
++	u64		raddr;
++	u64		size;
++	u64		protectStart;
++	u64		protectEnd;
++	u64		relocationOffset;
++	u64		pciAddress;
++	u64		reserved[3];
++};
++
++enum HvCallPci_VpdType {
++	HvCallPci_BusVpd	= 1,
++	HvCallPci_BusAdapterVpd	= 2
++};
++
++#define HvCallPciConfigLoad8		HvCallPci + 0
++#define HvCallPciConfigLoad16		HvCallPci + 1
++#define HvCallPciConfigLoad32		HvCallPci + 2
++#define HvCallPciConfigStore8		HvCallPci + 3
++#define HvCallPciConfigStore16		HvCallPci + 4
++#define HvCallPciConfigStore32		HvCallPci + 5
++#define HvCallPciEoi			HvCallPci + 16
++#define HvCallPciGetBarParms		HvCallPci + 18
++#define HvCallPciMaskFisr		HvCallPci + 20
++#define HvCallPciUnmaskFisr		HvCallPci + 21
++#define HvCallPciSetSlotReset		HvCallPci + 25
++#define HvCallPciGetDeviceInfo		HvCallPci + 27
++#define HvCallPciGetCardVpd		HvCallPci + 28
++#define HvCallPciBarLoad8		HvCallPci + 40
++#define HvCallPciBarLoad16		HvCallPci + 41
++#define HvCallPciBarLoad32		HvCallPci + 42
++#define HvCallPciBarLoad64		HvCallPci + 43
++#define HvCallPciBarStore8		HvCallPci + 44
++#define HvCallPciBarStore16		HvCallPci + 45
++#define HvCallPciBarStore32		HvCallPci + 46
++#define HvCallPciBarStore64		HvCallPci + 47
++#define HvCallPciMaskInterrupts		HvCallPci + 48
++#define HvCallPciUnmaskInterrupts	HvCallPci + 49
++#define HvCallPciGetBusUnitInfo		HvCallPci + 50
++
++static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
++		u8 deviceId, u32 offset, u16 *value)
++{
++	struct HvCallPci_DsaAddr dsa;
++	struct HvCallPci_LoadReturn retVal;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumber;
++	dsa.subBusNumber = subBusNumber;
++	dsa.deviceId = deviceId;
++
++	HvCall3Ret16(HvCallPciConfigLoad16, &retVal, *(u64 *)&dsa, offset, 0);
++
++	*value = retVal.value;
++
++	return retVal.rc;
++}
++
++static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
++		u8 deviceId, u32 offset, u8 value)
++{
++	struct HvCallPci_DsaAddr dsa;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumber;
++	dsa.subBusNumber = subBusNumber;
++	dsa.deviceId = deviceId;
++
++	return HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0);
++}
++
++static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm,
++		u8 deviceIdParm)
++{
++	struct HvCallPci_DsaAddr dsa;
++	struct HvCallPci_LoadReturn retVal;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumberParm;
++	dsa.subBusNumber = subBusParm;
++	dsa.deviceId = deviceIdParm;
++
++	HvCall1Ret16(HvCallPciEoi, &retVal, *(u64*)&dsa);
++
++	return retVal.rc;
++}
++
++static inline u64 HvCallPci_getBarParms(u16 busNumberParm, u8 subBusParm,
++		u8 deviceIdParm, u8 barNumberParm, u64 parms, u32 sizeofParms)
++{
++	struct HvCallPci_DsaAddr dsa;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumberParm;
++	dsa.subBusNumber = subBusParm;
++	dsa.deviceId = deviceIdParm;
++	dsa.barNumber = barNumberParm;
++
++	return HvCall3(HvCallPciGetBarParms, *(u64*)&dsa, parms, sizeofParms);
++}
++
++static inline u64 HvCallPci_maskFisr(u16 busNumberParm, u8 subBusParm,
++		u8 deviceIdParm, u64 fisrMask)
++{
++	struct HvCallPci_DsaAddr dsa;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumberParm;
++	dsa.subBusNumber = subBusParm;
++	dsa.deviceId = deviceIdParm;
++
++	return HvCall2(HvCallPciMaskFisr, *(u64*)&dsa, fisrMask);
++}
++
++static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm,
++		u8 deviceIdParm, u64 fisrMask)
++{
++	struct HvCallPci_DsaAddr dsa;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumberParm;
++	dsa.subBusNumber = subBusParm;
++	dsa.deviceId = deviceIdParm;
++
++	return HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask);
++}
++
++static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm,
++		u8 deviceNumberParm, u64 parms, u32 sizeofParms)
++{
++	struct HvCallPci_DsaAddr dsa;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumberParm;
++	dsa.subBusNumber = subBusParm;
++	dsa.deviceId = deviceNumberParm << 4;
++
++	return HvCall3(HvCallPciGetDeviceInfo, *(u64*)&dsa, parms, sizeofParms);
++}
++
++static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, u8 subBusParm,
++		u8 deviceIdParm, u64 interruptMask)
++{
++	struct HvCallPci_DsaAddr dsa;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumberParm;
++	dsa.subBusNumber = subBusParm;
++	dsa.deviceId = deviceIdParm;
++
++	return HvCall2(HvCallPciMaskInterrupts, *(u64*)&dsa, interruptMask);
++}
++
++static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, u8 subBusParm,
++		u8 deviceIdParm, u64 interruptMask)
++{
++	struct HvCallPci_DsaAddr dsa;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumberParm;
++	dsa.subBusNumber = subBusParm;
++	dsa.deviceId = deviceIdParm;
++
++	return HvCall2(HvCallPciUnmaskInterrupts, *(u64*)&dsa, interruptMask);
++}
++
++static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, u8 subBusParm,
++		u8 deviceIdParm, u64 parms, u32 sizeofParms)
++{
++	struct HvCallPci_DsaAddr dsa;
++
++	*((u64*)&dsa) = 0;
++
++	dsa.busNumber = busNumberParm;
++	dsa.subBusNumber = subBusParm;
++	dsa.deviceId = deviceIdParm;
++
++	return HvCall3(HvCallPciGetBusUnitInfo, *(u64*)&dsa, parms,
++			sizeofParms);
++}
++
++static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm,
++		u16 sizeParm)
++{
++	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm,
++			sizeParm, HvCallPci_BusVpd);
++	if (xRc == -1)
++		return -1;
++	else
++		return xRc & 0xFFFF;
++}
++
++#endif /* _PLATFORMS_ISERIES_CALL_PCI_H */
+diff --git a/arch/powerpc/platforms/iseries/call_sm.h b/arch/powerpc/platforms/iseries/call_sm.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/call_sm.h
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2001  Mike Corrigan 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
++ */
++#ifndef _ISERIES_CALL_SM_H
++#define _ISERIES_CALL_SM_H
++
++/*
++ * This file contains the "hypervisor call" interface which is used to
++ * drive the hypervisor from the OS.
++ */
++
++#include <asm/iSeries/HvCallSc.h>
++#include <asm/iSeries/HvTypes.h>
++
++#define HvCallSmGet64BitsOfAccessMap	HvCallSm  + 11
++
++static inline u64 HvCallSm_get64BitsOfAccessMap(HvLpIndex lpIndex,
++		u64 indexIntoBitMap)
++{
++	return HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, indexIntoBitMap);
++}
++
++#endif /* _ISERIES_CALL_SM_H */
+diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/htab.c
+@@ -0,0 +1,257 @@
++/*
++ * iSeries hashtable management.
++ *	Derived from pSeries_htab.c
++ *
++ * SMP scalability work:
++ *    Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, 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 <asm/machdep.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/mmu_context.h>
++#include <asm/abs_addr.h>
++#include <linux/spinlock.h>
++
++#include "call_hpt.h"
++
++static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp =
++	{ [0 ... 63] = SPIN_LOCK_UNLOCKED};
++
++/*
++ * Very primitive algorithm for picking up a lock
++ */
++static inline void iSeries_hlock(unsigned long slot)
++{
++	if (slot & 0x8)
++		slot = ~slot;
++	spin_lock(&iSeries_hlocks[(slot >> 4) & 0x3f]);
++}
++
++static inline void iSeries_hunlock(unsigned long slot)
++{
++	if (slot & 0x8)
++		slot = ~slot;
++	spin_unlock(&iSeries_hlocks[(slot >> 4) & 0x3f]);
++}
++
++static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
++				unsigned long prpn, unsigned long vflags,
++				unsigned long rflags)
++{
++	unsigned long arpn;
++	long slot;
++	hpte_t lhpte;
++	int secondary = 0;
++
++	/*
++	 * The hypervisor tries both primary and secondary.
++	 * If we are being called to insert in the secondary,
++	 * it means we have already tried both primary and secondary,
++	 * so we return failure immediately.
++	 */
++	if (vflags & HPTE_V_SECONDARY)
++		return -1;
++
++	iSeries_hlock(hpte_group);
++
++	slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
++	BUG_ON(lhpte.v & HPTE_V_VALID);
++
++	if (slot == -1)	{ /* No available entry found in either group */
++		iSeries_hunlock(hpte_group);
++		return -1;
++	}
++
++	if (slot < 0) {		/* MSB set means secondary group */
++		vflags |= HPTE_V_SECONDARY;
++		secondary = 1;
++		slot &= 0x7fffffffffffffff;
++	}
++
++	arpn = phys_to_abs(prpn << PAGE_SHIFT) >> PAGE_SHIFT;
++
++	lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
++	lhpte.r = (arpn << HPTE_R_RPN_SHIFT) | rflags;
++
++	/* Now fill in the actual HPTE */
++	HvCallHpt_addValidate(slot, secondary, &lhpte);
++
++	iSeries_hunlock(hpte_group);
++
++	return (secondary << 3) | (slot & 7);
++}
++
++long iSeries_hpte_bolt_or_insert(unsigned long hpte_group,
++		unsigned long va, unsigned long prpn, unsigned long vflags,
++		unsigned long rflags)
++{
++	long slot;
++	hpte_t lhpte;
++
++	slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
++
++	if (lhpte.v & HPTE_V_VALID) {
++		/* Bolt the existing HPTE */
++		HvCallHpt_setSwBits(slot, 0x10, 0);
++		HvCallHpt_setPp(slot, PP_RWXX);
++		return 0;
++	}
++
++	return iSeries_hpte_insert(hpte_group, va, prpn, vflags, rflags);
++}
++
++static unsigned long iSeries_hpte_getword0(unsigned long slot)
++{
++	hpte_t hpte;
++
++	HvCallHpt_get(&hpte, slot);
++	return hpte.v;
++}
++
++static long iSeries_hpte_remove(unsigned long hpte_group)
++{
++	unsigned long slot_offset;
++	int i;
++	unsigned long hpte_v;
++
++	/* Pick a random slot to start at */
++	slot_offset = mftb() & 0x7;
++
++	iSeries_hlock(hpte_group);
++
++	for (i = 0; i < HPTES_PER_GROUP; i++) {
++		hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);
++
++		if (! (hpte_v & HPTE_V_BOLTED)) {
++			HvCallHpt_invalidateSetSwBitsGet(hpte_group +
++							 slot_offset, 0, 0);
++			iSeries_hunlock(hpte_group);
++			return i;
++		}
++
++		slot_offset++;
++		slot_offset &= 0x7;
++	}
++
++	iSeries_hunlock(hpte_group);
++
++	return -1;
++}
++
++/*
++ * The HyperVisor expects the "flags" argument in this form:
++ *	bits  0..59 : reserved
++ *	bit      60 : N
++ *	bits 61..63 : PP2,PP1,PP0
++ */
++static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
++				  unsigned long va, int large, int local)
++{
++	hpte_t hpte;
++	unsigned long avpn = va >> 23;
++
++	iSeries_hlock(slot);
++
++	HvCallHpt_get(&hpte, slot);
++	if ((HPTE_V_AVPN_VAL(hpte.v) == avpn) && (hpte.v & HPTE_V_VALID)) {
++		/*
++		 * Hypervisor expects bits as NPPP, which is
++		 * different from how they are mapped in our PP.
++		 */
++		HvCallHpt_setPp(slot, (newpp & 0x3) | ((newpp & 0x4) << 1));
++		iSeries_hunlock(slot);
++		return 0;
++	}
++	iSeries_hunlock(slot);
++
++	return -1;
++}
++
++/*
++ * Functions used to find the PTE for a particular virtual address.
++ * Only used during boot when bolting pages.
++ *
++ * Input : vpn      : virtual page number
++ * Output: PTE index within the page table of the entry
++ *         -1 on failure
++ */
++static long iSeries_hpte_find(unsigned long vpn)
++{
++	hpte_t hpte;
++	long slot;
++
++	/*
++	 * The HvCallHpt_findValid interface is as follows:
++	 * 0xffffffffffffffff : No entry found.
++	 * 0x00000000xxxxxxxx : Entry found in primary group, slot x
++	 * 0x80000000xxxxxxxx : Entry found in secondary group, slot x
++	 */
++	slot = HvCallHpt_findValid(&hpte, vpn);
++	if (hpte.v & HPTE_V_VALID) {
++		if (slot < 0) {
++			slot &= 0x7fffffffffffffff;
++			slot = -slot;
++		}
++	} else
++		slot = -1;
++	return slot;
++}
++
++/*
++ * Update the page protection bits. Intended to be used to create
++ * guard pages for kernel data structures on pages which are bolted
++ * in the HPT. Assumes pages being operated on will not be stolen.
++ * Does not work on large pages.
++ *
++ * No need to lock here because we should be the only user.
++ */
++static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
++{
++	unsigned long vsid,va,vpn;
++	long slot;
++
++	vsid = get_kernel_vsid(ea);
++	va = (vsid << 28) | (ea & 0x0fffffff);
++	vpn = va >> PAGE_SHIFT;
++	slot = iSeries_hpte_find(vpn);
++	if (slot == -1)
++		panic("updateboltedpp: Could not find page to bolt\n");
++	HvCallHpt_setPp(slot, newpp);
++}
++
++static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
++				    int large, int local)
++{
++	unsigned long hpte_v;
++	unsigned long avpn = va >> 23;
++	unsigned long flags;
++
++	local_irq_save(flags);
++
++	iSeries_hlock(slot);
++
++	hpte_v = iSeries_hpte_getword0(slot);
++
++	if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))
++		HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
++
++	iSeries_hunlock(slot);
++
++	local_irq_restore(flags);
++}
++
++void hpte_init_iSeries(void)
++{
++	ppc_md.hpte_invalidate	= iSeries_hpte_invalidate;
++	ppc_md.hpte_updatepp	= iSeries_hpte_updatepp;
++	ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
++	ppc_md.hpte_insert	= iSeries_hpte_insert;
++	ppc_md.hpte_remove	= iSeries_hpte_remove;
++
++	htab_finish_init();
++}
+diff --git a/arch/powerpc/platforms/iseries/hvcall.S b/arch/powerpc/platforms/iseries/hvcall.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/hvcall.S
+@@ -0,0 +1,94 @@
++/*
++ * This file contains the code to perform calls to the
++ * iSeries LPAR hypervisor
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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>
++#include <asm/processor.h>
++#include <asm/ptrace.h>		/* XXX for STACK_FRAME_OVERHEAD */
++
++	.text
++
++/*
++ * Hypervisor call
++ *
++ * Invoke the iSeries hypervisor via the System Call instruction
++ * Parameters are passed to this routine in registers r3 - r10
++ *
++ * r3 contains the HV function to be called
++ * r4-r10 contain the operands to the hypervisor function
++ *
++ */
++
++_GLOBAL(HvCall)
++_GLOBAL(HvCall0)
++_GLOBAL(HvCall1)
++_GLOBAL(HvCall2)
++_GLOBAL(HvCall3)
++_GLOBAL(HvCall4)
++_GLOBAL(HvCall5)
++_GLOBAL(HvCall6)
++_GLOBAL(HvCall7)
++
++
++	mfcr	r0
++	std	r0,-8(r1)
++	stdu	r1,-(STACK_FRAME_OVERHEAD+16)(r1)
++
++	/* r0 = 0xffffffffffffffff indicates a hypervisor call */
++
++	li	r0,-1
++
++	/* Invoke the hypervisor */
++
++	sc
++
++	ld	r1,0(r1)
++	ld	r0,-8(r1)
++	mtcrf	0xff,r0
++
++	/*  return to caller, return value in r3 */
++
++	blr
++
++_GLOBAL(HvCall0Ret16)
++_GLOBAL(HvCall1Ret16)
++_GLOBAL(HvCall2Ret16)
++_GLOBAL(HvCall3Ret16)
++_GLOBAL(HvCall4Ret16)
++_GLOBAL(HvCall5Ret16)
++_GLOBAL(HvCall6Ret16)
++_GLOBAL(HvCall7Ret16)
++
++	mfcr	r0
++	std	r0,-8(r1)
++	std	r31,-16(r1)
++	stdu	r1,-(STACK_FRAME_OVERHEAD+32)(r1)
++
++	mr	r31,r4
++	li	r0,-1
++	mr	r4,r5
++	mr	r5,r6
++	mr	r6,r7
++	mr	r7,r8
++	mr	r8,r9
++	mr	r9,r10
++
++	sc
++
++	std	r3,0(r31)
++	std	r4,8(r31)
++
++	mr	r3,r5
++
++	ld	r1,0(r1)
++	ld	r0,-8(r1)
++	mtcrf	0xff,r0
++	ld	r31,-16(r1)
++
++	blr
+diff --git a/arch/powerpc/platforms/iseries/hvlog.c b/arch/powerpc/platforms/iseries/hvlog.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/hvlog.c
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (C) 2001  Mike Corrigan 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.
++ */
++
++#include <asm/page.h>
++#include <asm/abs_addr.h>
++#include <asm/iSeries/HvCall.h>
++#include <asm/iSeries/HvCallSc.h>
++#include <asm/iSeries/HvTypes.h>
++
++
++void HvCall_writeLogBuffer(const void *buffer, u64 len)
++{
++	struct HvLpBufferList hv_buf;
++	u64 left_this_page;
++	u64 cur = virt_to_abs(buffer);
++
++	while (len) {
++		hv_buf.addr = cur;
++		left_this_page = ((cur & PAGE_MASK) + PAGE_SIZE) - cur;
++		if (left_this_page > len)
++			left_this_page = len;
++		hv_buf.len = left_this_page;
++		len -= left_this_page;
++		HvCall2(HvCallBaseWriteLogBuffer,
++				virt_to_abs(&hv_buf),
++				left_this_page);
++		cur = (cur & PAGE_MASK) + PAGE_SIZE;
++	}
++}
+diff --git a/arch/powerpc/platforms/iseries/hvlpconfig.c b/arch/powerpc/platforms/iseries/hvlpconfig.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/hvlpconfig.c
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2001  Kyle A. Lucke, 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
++ */
++
++#include <linux/module.h>
++#include <asm/iSeries/HvLpConfig.h>
++
++HvLpIndex HvLpConfig_getLpIndex_outline(void)
++{
++	return HvLpConfig_getLpIndex();
++}
++EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline);
+diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/iommu.c
+@@ -0,0 +1,178 @@
++/*
++ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
++ *
++ * Rewrite, cleanup:
++ *
++ * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, IBM Corporation
++ *
++ * Dynamic DMA mapping support, iSeries-specific parts.
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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/dma-mapping.h>
++#include <linux/list.h>
++
++#include <asm/iommu.h>
++#include <asm/tce.h>
++#include <asm/machdep.h>
++#include <asm/abs_addr.h>
++#include <asm/pci-bridge.h>
++#include <asm/iSeries/HvCallXm.h>
++
++extern struct list_head iSeries_Global_Device_List;
++
++
++static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
++		unsigned long uaddr, enum dma_data_direction direction)
++{
++	u64 rc;
++	union tce_entry tce;
++
++	while (npages--) {
++		tce.te_word = 0;
++		tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> PAGE_SHIFT;
++
++		if (tbl->it_type == TCE_VB) {
++			/* Virtual Bus */
++			tce.te_bits.tb_valid = 1;
++			tce.te_bits.tb_allio = 1;
++			if (direction != DMA_TO_DEVICE)
++				tce.te_bits.tb_rdwr = 1;
++		} else {
++			/* PCI Bus */
++			tce.te_bits.tb_rdwr = 1; /* Read allowed */
++			if (direction != DMA_TO_DEVICE)
++				tce.te_bits.tb_pciwr = 1;
++		}
++
++		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index,
++				tce.te_word);
++		if (rc)
++			panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
++					rc);
++		index++;
++		uaddr += PAGE_SIZE;
++	}
++}
++
++static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
++{
++	u64 rc;
++
++	while (npages--) {
++		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0);
++		if (rc)
++			panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
++					rc);
++		index++;
++	}
++}
++
++#ifdef CONFIG_PCI
++/*
++ * This function compares the known tables to find an iommu_table
++ * that has already been built for hardware TCEs.
++ */
++static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
++{
++	struct pci_dn *pdn;
++
++	list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) {
++		struct iommu_table *it = pdn->iommu_table;
++		if ((it != NULL) &&
++		    (it->it_type == TCE_PCI) &&
++		    (it->it_offset == tbl->it_offset) &&
++		    (it->it_index == tbl->it_index) &&
++		    (it->it_size == tbl->it_size))
++			return it;
++	}
++	return NULL;
++}
++
++/*
++ * Call Hv with the architected data structure to get TCE table info.
++ * info. Put the returned data into the Linux representation of the
++ * TCE table data.
++ * The Hardware Tce table comes in three flavors.
++ * 1. TCE table shared between Buses.
++ * 2. TCE table per Bus.
++ * 3. TCE Table per IOA.
++ */
++static void iommu_table_getparms(struct pci_dn *pdn,
++				 struct iommu_table* tbl)
++{
++	struct iommu_table_cb *parms;
++
++	parms = kmalloc(sizeof(*parms), GFP_KERNEL);
++	if (parms == NULL)
++		panic("PCI_DMA: TCE Table Allocation failed.");
++
++	memset(parms, 0, sizeof(*parms));
++
++	parms->itc_busno = pdn->busno;
++	parms->itc_slotno = pdn->LogicalSlot;
++	parms->itc_virtbus = 0;
++
++	HvCallXm_getTceTableParms(iseries_hv_addr(parms));
++
++	if (parms->itc_size == 0)
++		panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);
++
++	/* itc_size is in pages worth of table, it_size is in # of entries */
++	tbl->it_size = (parms->itc_size * PAGE_SIZE) / sizeof(union tce_entry);
++	tbl->it_busno = parms->itc_busno;
++	tbl->it_offset = parms->itc_offset;
++	tbl->it_index = parms->itc_index;
++	tbl->it_blocksize = 1;
++	tbl->it_type = TCE_PCI;
++
++	kfree(parms);
++}
++
++
++void iommu_devnode_init_iSeries(struct device_node *dn)
++{
++	struct iommu_table *tbl;
++	struct pci_dn *pdn = PCI_DN(dn);
++
++	tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
++
++	iommu_table_getparms(pdn, tbl);
++
++	/* Look for existing tce table */
++	pdn->iommu_table = iommu_table_find(tbl);
++	if (pdn->iommu_table == NULL)
++		pdn->iommu_table = iommu_init_table(tbl);
++	else
++		kfree(tbl);
++}
++#endif
++
++static void iommu_dev_setup_iSeries(struct pci_dev *dev) { }
++static void iommu_bus_setup_iSeries(struct pci_bus *bus) { }
++
++void iommu_init_early_iSeries(void)
++{
++	ppc_md.tce_build = tce_build_iSeries;
++	ppc_md.tce_free  = tce_free_iSeries;
++
++	ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries;
++	ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries;
++
++	pci_iommu_init();
++}
+diff --git a/arch/powerpc/platforms/iseries/ipl_parms.h b/arch/powerpc/platforms/iseries/ipl_parms.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/ipl_parms.h
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (C) 2001  Mike Corrigan 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
++ */
++#ifndef _ISERIES_IPL_PARMS_H
++#define _ISERIES_IPL_PARMS_H
++
++/*
++ *	This struct maps the IPL Parameters DMA'd from the SP.
++ *
++ * Warning:
++ *	This data must map in exactly 64 bytes and match the architecture for
++ *	the IPL parms
++ */
++
++#include <asm/types.h>
++
++struct ItIplParmsReal {
++	u8	xFormat;		// Defines format of IplParms	x00-x00
++	u8	xRsvd01:6;		// Reserved			x01-x01
++	u8	xAlternateSearch:1;	// Alternate search indicator	...
++	u8	xUaSupplied:1;		// UA Supplied on programmed IPL...
++	u8	xLsUaFormat;		// Format byte for UA		x02-x02
++	u8	xRsvd02;		// Reserved			x03-x03
++	u32	xLsUa;			// LS UA			x04-x07
++	u32	xUnusedLsLid;		// First OS LID to load		x08-x0B
++	u16	xLsBusNumber;		// LS Bus Number		x0C-x0D
++	u8	xLsCardAdr;		// LS Card Address		x0E-x0E
++	u8	xLsBoardAdr;		// LS Board Address		x0F-x0F
++	u32	xRsvd03;		// Reserved			x10-x13
++	u8	xSpcnPresent:1;		// SPCN present			x14-x14
++	u8	xCpmPresent:1;		// CPM present			...
++	u8	xRsvd04:6;		// Reserved			...
++	u8	xRsvd05:4;		// Reserved			x15-x15
++	u8	xKeyLock:4;		// Keylock setting		...
++	u8	xRsvd06:6;		// Reserved			x16-x16
++	u8	xIplMode:2;		// Ipl mode (A|B|C|D)		...
++	u8	xHwIplType;		// Fast v slow v slow EC HW IPL	x17-x17
++	u16	xCpmEnabledIpl:1;	// CPM in effect when IPL initiatedx18-x19
++	u16	xPowerOnResetIpl:1;	// Indicate POR condition	...
++	u16	xMainStorePreserved:1;	// Main Storage is preserved	...
++	u16	xRsvd07:13;		// Reserved			...
++	u16	xIplSource:16;		// Ipl source			x1A-x1B
++	u8	xIplReason:8;		// Reason for this IPL		x1C-x1C
++	u8	xRsvd08;		// Reserved			x1D-x1D
++	u16	xRsvd09;		// Reserved			x1E-x1F
++	u16	xSysBoxType;		// System Box Type		x20-x21
++	u16	xSysProcType;		// System Processor Type	x22-x23
++	u32	xRsvd10;		// Reserved			x24-x27
++	u64	xRsvd11;		// Reserved			x28-x2F
++	u64	xRsvd12;		// Reserved			x30-x37
++	u64	xRsvd13;		// Reserved			x38-x3F
++};
++
++extern struct ItIplParmsReal	xItIplParmsReal;
++
++#endif /* _ISERIES_IPL_PARMS_H */
+diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/irq.c
+@@ -0,0 +1,366 @@
++/*
++ * This module supports the iSeries PCI bus interrupt handling
++ * Copyright (C) 20yy  <Robert L Holtorf> <IBM Corp>
++ * Copyright (C) 2004-2005 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
++ *
++ * Change Activity:
++ *   Created, December 13, 2000 by Wayne Holm
++ * End Change Activity
++ */
++#include <linux/config.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/threads.h>
++#include <linux/smp.h>
++#include <linux/param.h>
++#include <linux/string.h>
++#include <linux/bootmem.h>
++#include <linux/ide.h>
++#include <linux/irq.h>
++#include <linux/spinlock.h>
++
++#include <asm/ppcdebug.h>
++#include <asm/iSeries/HvTypes.h>
++#include <asm/iSeries/HvLpEvent.h>
++#include <asm/iSeries/HvCallXm.h>
++
++#include "irq.h"
++#include "call_pci.h"
++
++/* This maps virtual irq numbers to real irqs */
++unsigned int virt_irq_to_real_map[NR_IRQS];
++
++/* The next available virtual irq number */
++/* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */
++static int next_virtual_irq = 2;
++
++static long Pci_Interrupt_Count;
++static long Pci_Event_Count;
++
++enum XmPciLpEvent_Subtype {
++	XmPciLpEvent_BusCreated		= 0,	// PHB has been created
++	XmPciLpEvent_BusError		= 1,	// PHB has failed
++	XmPciLpEvent_BusFailed		= 2,	// Msg to Secondary, Primary failed bus
++	XmPciLpEvent_NodeFailed		= 4,	// Multi-adapter bridge has failed
++	XmPciLpEvent_NodeRecovered	= 5,	// Multi-adapter bridge has recovered
++	XmPciLpEvent_BusRecovered	= 12,	// PHB has been recovered
++	XmPciLpEvent_UnQuiesceBus	= 18,	// Secondary bus unqiescing
++	XmPciLpEvent_BridgeError	= 21,	// Bridge Error
++	XmPciLpEvent_SlotInterrupt	= 22	// Slot interrupt
++};
++
++struct XmPciLpEvent_BusInterrupt {
++	HvBusNumber	busNumber;
++	HvSubBusNumber	subBusNumber;
++};
++
++struct XmPciLpEvent_NodeInterrupt {
++	HvBusNumber	busNumber;
++	HvSubBusNumber	subBusNumber;
++	HvAgentId	deviceId;
++};
++
++struct XmPciLpEvent {
++	struct HvLpEvent hvLpEvent;
++
++	union {
++		u64 alignData;			// Align on an 8-byte boundary
++
++		struct {
++			u32		fisr;
++			HvBusNumber	busNumber;
++			HvSubBusNumber	subBusNumber;
++			HvAgentId	deviceId;
++		} slotInterrupt;
++
++		struct XmPciLpEvent_BusInterrupt busFailed;
++		struct XmPciLpEvent_BusInterrupt busRecovered;
++		struct XmPciLpEvent_BusInterrupt busCreated;
++
++		struct XmPciLpEvent_NodeInterrupt nodeFailed;
++		struct XmPciLpEvent_NodeInterrupt nodeRecovered;
++
++	} eventData;
++
++};
++
++static void intReceived(struct XmPciLpEvent *eventParm,
++		struct pt_regs *regsParm)
++{
++	int irq;
++
++	++Pci_Interrupt_Count;
++
++	switch (eventParm->hvLpEvent.xSubtype) {
++	case XmPciLpEvent_SlotInterrupt:
++		irq = eventParm->hvLpEvent.xCorrelationToken;
++		/* Dispatch the interrupt handlers for this irq */
++		ppc_irq_dispatch_handler(regsParm, irq);
++		HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
++			eventParm->eventData.slotInterrupt.subBusNumber,
++			eventParm->eventData.slotInterrupt.deviceId);
++		break;
++		/* Ignore error recovery events for now */
++	case XmPciLpEvent_BusCreated:
++		printk(KERN_INFO "intReceived: system bus %d created\n",
++			eventParm->eventData.busCreated.busNumber);
++		break;
++	case XmPciLpEvent_BusError:
++	case XmPciLpEvent_BusFailed:
++		printk(KERN_INFO "intReceived: system bus %d failed\n",
++			eventParm->eventData.busFailed.busNumber);
++		break;
++	case XmPciLpEvent_BusRecovered:
++	case XmPciLpEvent_UnQuiesceBus:
++		printk(KERN_INFO "intReceived: system bus %d recovered\n",
++			eventParm->eventData.busRecovered.busNumber);
++		break;
++	case XmPciLpEvent_NodeFailed:
++	case XmPciLpEvent_BridgeError:
++		printk(KERN_INFO
++			"intReceived: multi-adapter bridge %d/%d/%d failed\n",
++			eventParm->eventData.nodeFailed.busNumber,
++			eventParm->eventData.nodeFailed.subBusNumber,
++			eventParm->eventData.nodeFailed.deviceId);
++		break;
++	case XmPciLpEvent_NodeRecovered:
++		printk(KERN_INFO
++			"intReceived: multi-adapter bridge %d/%d/%d recovered\n",
++			eventParm->eventData.nodeRecovered.busNumber,
++			eventParm->eventData.nodeRecovered.subBusNumber,
++			eventParm->eventData.nodeRecovered.deviceId);
++		break;
++	default:
++		printk(KERN_ERR
++			"intReceived: unrecognized event subtype 0x%x\n",
++			eventParm->hvLpEvent.xSubtype);
++		break;
++	}
++}
++
++static void XmPciLpEvent_handler(struct HvLpEvent *eventParm,
++		struct pt_regs *regsParm)
++{
++#ifdef CONFIG_PCI
++	++Pci_Event_Count;
++
++	if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) {
++		switch (eventParm->xFlags.xFunction) {
++		case HvLpEvent_Function_Int:
++			intReceived((struct XmPciLpEvent *)eventParm, regsParm);
++			break;
++		case HvLpEvent_Function_Ack:
++			printk(KERN_ERR
++				"XmPciLpEvent_handler: unexpected ack received\n");
++			break;
++		default:
++			printk(KERN_ERR
++				"XmPciLpEvent_handler: unexpected event function %d\n",
++				(int)eventParm->xFlags.xFunction);
++			break;
++		}
++	} else if (eventParm)
++		printk(KERN_ERR
++			"XmPciLpEvent_handler: Unrecognized PCI event type 0x%x\n",
++			(int)eventParm->xType);
++	else
++		printk(KERN_ERR "XmPciLpEvent_handler: NULL event received\n");
++#endif
++}
++
++/*
++ * This is called by init_IRQ.  set in ppc_md.init_IRQ by iSeries_setup.c
++ * It must be called before the bus walk.
++ */
++void __init iSeries_init_IRQ(void)
++{
++	/* Register PCI event handler and open an event path */
++	int xRc;
++
++	xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo,
++			&XmPciLpEvent_handler);
++	if (xRc == 0) {
++		xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
++		if (xRc != 0)
++			printk(KERN_ERR "iSeries_init_IRQ: open event path "
++					"failed with rc 0x%x\n", xRc);
++	} else
++		printk(KERN_ERR "iSeries_init_IRQ: register handler "
++				"failed with rc 0x%x\n", xRc);
++}
++
++#define REAL_IRQ_TO_BUS(irq)	((((irq) >> 6) & 0xff) + 1)
++#define REAL_IRQ_TO_IDSEL(irq)	((((irq) >> 3) & 7) + 1)
++#define REAL_IRQ_TO_FUNC(irq)	((irq) & 7)
++
++/*
++ * This will be called by device drivers (via enable_IRQ)
++ * to enable INTA in the bridge interrupt status register.
++ */
++static void iSeries_enable_IRQ(unsigned int irq)
++{
++	u32 bus, deviceId, function, mask;
++	const u32 subBus = 0;
++	unsigned int rirq = virt_irq_to_real_map[irq];
++
++	/* The IRQ has already been locked by the caller */
++	bus = REAL_IRQ_TO_BUS(rirq);
++	function = REAL_IRQ_TO_FUNC(rirq);
++	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
++
++	/* Unmask secondary INTA */
++	mask = 0x80000000;
++	HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask);
++	PPCDBG(PPCDBG_BUSWALK, "iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n",
++			bus, subBus, deviceId, irq);
++}
++
++/* This is called by iSeries_activate_IRQs */
++static unsigned int iSeries_startup_IRQ(unsigned int irq)
++{
++	u32 bus, deviceId, function, mask;
++	const u32 subBus = 0;
++	unsigned int rirq = virt_irq_to_real_map[irq];
++
++	bus = REAL_IRQ_TO_BUS(rirq);
++	function = REAL_IRQ_TO_FUNC(rirq);
++	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
++
++	/* Link the IRQ number to the bridge */
++	HvCallXm_connectBusUnit(bus, subBus, deviceId, irq);
++
++	/* Unmask bridge interrupts in the FISR */
++	mask = 0x01010000 << function;
++	HvCallPci_unmaskFisr(bus, subBus, deviceId, mask);
++	iSeries_enable_IRQ(irq);
++	return 0;
++}
++
++/*
++ * This is called out of iSeries_fixup to activate interrupt
++ * generation for usable slots
++ */
++void __init iSeries_activate_IRQs()
++{
++	int irq;
++	unsigned long flags;
++
++	for_each_irq (irq) {
++		irq_desc_t *desc = get_irq_desc(irq);
++
++		if (desc && desc->handler && desc->handler->startup) {
++			spin_lock_irqsave(&desc->lock, flags);
++			desc->handler->startup(irq);
++			spin_unlock_irqrestore(&desc->lock, flags);
++		}
++	}
++}
++
++/*  this is not called anywhere currently */
++static void iSeries_shutdown_IRQ(unsigned int irq)
++{
++	u32 bus, deviceId, function, mask;
++	const u32 subBus = 0;
++	unsigned int rirq = virt_irq_to_real_map[irq];
++
++	/* irq should be locked by the caller */
++	bus = REAL_IRQ_TO_BUS(rirq);
++	function = REAL_IRQ_TO_FUNC(rirq);
++	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
++
++	/* Invalidate the IRQ number in the bridge */
++	HvCallXm_connectBusUnit(bus, subBus, deviceId, 0);
++
++	/* Mask bridge interrupts in the FISR */
++	mask = 0x01010000 << function;
++	HvCallPci_maskFisr(bus, subBus, deviceId, mask);
++}
++
++/*
++ * This will be called by device drivers (via disable_IRQ)
++ * to disable INTA in the bridge interrupt status register.
++ */
++static void iSeries_disable_IRQ(unsigned int irq)
++{
++	u32 bus, deviceId, function, mask;
++	const u32 subBus = 0;
++	unsigned int rirq = virt_irq_to_real_map[irq];
++
++	/* The IRQ has already been locked by the caller */
++	bus = REAL_IRQ_TO_BUS(rirq);
++	function = REAL_IRQ_TO_FUNC(rirq);
++	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
++
++	/* Mask secondary INTA   */
++	mask = 0x80000000;
++	HvCallPci_maskInterrupts(bus, subBus, deviceId, mask);
++	PPCDBG(PPCDBG_BUSWALK, "iSeries_disable_IRQ 0x%02X.%02X.%02X 0x%04X\n",
++			bus, subBus, deviceId, irq);
++}
++
++/*
++ * Need to define this so ppc_irq_dispatch_handler will NOT call
++ * enable_IRQ at the end of interrupt handling.  However, this does
++ * nothing because there is not enough information provided to do
++ * the EOI HvCall.  This is done by XmPciLpEvent.c
++ */
++static void iSeries_end_IRQ(unsigned int irq)
++{
++}
++
++static hw_irq_controller iSeries_IRQ_handler = {
++	.typename = "iSeries irq controller",
++	.startup = iSeries_startup_IRQ,
++	.shutdown = iSeries_shutdown_IRQ,
++	.enable = iSeries_enable_IRQ,
++	.disable = iSeries_disable_IRQ,
++	.end = iSeries_end_IRQ
++};
++
++/*
++ * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot
++ * It calculates the irq value for the slot.
++ * Note that subBusNumber is always 0 (at the moment at least).
++ */
++int __init iSeries_allocate_IRQ(HvBusNumber busNumber,
++		HvSubBusNumber subBusNumber, HvAgentId deviceId)
++{
++	unsigned int realirq, virtirq;
++	u8 idsel = (deviceId >> 4);
++	u8 function = deviceId & 7;
++
++	virtirq = next_virtual_irq++;
++	realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function;
++	virt_irq_to_real_map[virtirq] = realirq;
++
++	irq_desc[virtirq].handler = &iSeries_IRQ_handler;
++	return virtirq;
++}
++
++int virt_irq_create_mapping(unsigned int real_irq)
++{
++	BUG(); /* Don't call this on iSeries, yet */
++
++	return 0;
++}
++
++void virt_irq_init(void)
++{
++	return;
++}
+diff --git a/arch/powerpc/platforms/iseries/irq.h b/arch/powerpc/platforms/iseries/irq.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/irq.h
+@@ -0,0 +1,8 @@
++#ifndef	_ISERIES_IRQ_H
++#define	_ISERIES_IRQ_H
++
++extern void iSeries_init_IRQ(void);
++extern int  iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
++extern void iSeries_activate_IRQs(void);
++
++#endif /* _ISERIES_IRQ_H */
+diff --git a/arch/powerpc/platforms/iseries/ksyms.c b/arch/powerpc/platforms/iseries/ksyms.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/ksyms.c
+@@ -0,0 +1,27 @@
++/*
++ * (C) 2001-2005 PPC 64 Team, IBM Corp
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ */
++#include <linux/module.h>
++
++#include <asm/hw_irq.h>
++#include <asm/iSeries/HvCallSc.h>
++
++EXPORT_SYMBOL(HvCall0);
++EXPORT_SYMBOL(HvCall1);
++EXPORT_SYMBOL(HvCall2);
++EXPORT_SYMBOL(HvCall3);
++EXPORT_SYMBOL(HvCall4);
++EXPORT_SYMBOL(HvCall5);
++EXPORT_SYMBOL(HvCall6);
++EXPORT_SYMBOL(HvCall7);
++
++#ifdef CONFIG_SMP
++EXPORT_SYMBOL(local_get_flags);
++EXPORT_SYMBOL(local_irq_disable);
++EXPORT_SYMBOL(local_irq_restore);
++#endif
+diff --git a/arch/powerpc/platforms/iseries/lpardata.c b/arch/powerpc/platforms/iseries/lpardata.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/lpardata.c
+@@ -0,0 +1,227 @@
++/*
++ * Copyright 2001 Mike Corrigan, IBM Corp
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/threads.h>
++#include <linux/module.h>
++#include <linux/bitops.h>
++#include <asm/processor.h>
++#include <asm/ptrace.h>
++#include <asm/naca.h>
++#include <asm/abs_addr.h>
++#include <asm/iSeries/ItLpNaca.h>
++#include <asm/lppaca.h>
++#include <asm/iSeries/ItLpRegSave.h>
++#include <asm/paca.h>
++#include <asm/iSeries/LparMap.h>
++#include <asm/iSeries/ItExtVpdPanel.h>
++#include <asm/iSeries/ItLpQueue.h>
++
++#include "vpd_areas.h"
++#include "spcomm_area.h"
++#include "ipl_parms.h"
++#include "processor_vpd.h"
++#include "release_data.h"
++
++/* The HvReleaseData is the root of the information shared between
++ * the hypervisor and Linux.
++ */
++struct HvReleaseData hvReleaseData = {
++	.xDesc = 0xc8a5d9c4,	/* "HvRD" ebcdic */
++	.xSize = sizeof(struct HvReleaseData),
++	.xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas),
++	.xSlicNacaAddr = &naca,		/* 64-bit Naca address */
++	.xMsNucDataOffset = LPARMAP_PHYS,
++	.xFlags = HVREL_TAGSINACTIVE	/* tags inactive       */
++					/* 64 bit              */
++					/* shared processors   */
++					/* HMT allowed         */
++		  | 6,			/* TEMP: This allows non-GA driver */
++	.xVrmIndex = 4,			/* We are v5r2m0               */
++	.xMinSupportedPlicVrmIndex = 3,		/* v5r1m0 */
++	.xMinCompatablePlicVrmIndex = 3,	/* v5r1m0 */
++	.xVrmName = { 0xd3, 0x89, 0x95, 0xa4,	/* "Linux 2.4.64" ebcdic */
++		0xa7, 0x40, 0xf2, 0x4b,
++		0xf4, 0x4b, 0xf6, 0xf4 },
++};
++
++/*
++ * The NACA.  The first dword of the naca is required by the iSeries
++ * hypervisor to point to itVpdAreas.  The hypervisor finds the NACA
++ * through the pointer in hvReleaseData.
++ */
++struct naca_struct naca = {
++	.xItVpdAreas = &itVpdAreas,
++	.xRamDisk = 0,
++	.xRamDiskSize = 0,
++};
++
++extern void system_reset_iSeries(void);
++extern void machine_check_iSeries(void);
++extern void data_access_iSeries(void);
++extern void instruction_access_iSeries(void);
++extern void hardware_interrupt_iSeries(void);
++extern void alignment_iSeries(void);
++extern void program_check_iSeries(void);
++extern void fp_unavailable_iSeries(void);
++extern void decrementer_iSeries(void);
++extern void trap_0a_iSeries(void);
++extern void trap_0b_iSeries(void);
++extern void system_call_iSeries(void);
++extern void single_step_iSeries(void);
++extern void trap_0e_iSeries(void);
++extern void performance_monitor_iSeries(void);
++extern void data_access_slb_iSeries(void);
++extern void instruction_access_slb_iSeries(void);
++
++struct ItLpNaca itLpNaca = {
++	.xDesc = 0xd397d581,		/* "LpNa" ebcdic */
++	.xSize = 0x0400,		/* size of ItLpNaca */
++	.xIntHdlrOffset = 0x0300,	/* offset to int array */
++	.xMaxIntHdlrEntries = 19,	/* # ents */
++	.xPrimaryLpIndex = 0,		/* Part # of primary */
++	.xServiceLpIndex = 0,		/* Part # of serv */
++	.xLpIndex = 0,			/* Part # of me */
++	.xMaxLpQueues = 0,		/* # of LP queues */
++	.xLpQueueOffset = 0x100,	/* offset of start of LP queues */
++	.xPirEnvironMode = 0,		/* Piranha stuff */
++	.xPirConsoleMode = 0,
++	.xPirDasdMode = 0,
++	.xLparInstalled = 0,
++	.xSysPartitioned = 0,
++	.xHwSyncedTBs = 0,
++	.xIntProcUtilHmt = 0,
++	.xSpVpdFormat = 0,
++	.xIntProcRatio = 0,
++	.xPlicVrmIndex = 0,		/* VRM index of PLIC */
++	.xMinSupportedSlicVrmInd = 0,	/* min supported SLIC */
++	.xMinCompatableSlicVrmInd = 0,	/* min compat SLIC */
++	.xLoadAreaAddr = 0,		/* 64-bit addr of load area */
++	.xLoadAreaChunks = 0,		/* chunks for load area */
++	.xPaseSysCallCRMask = 0,	/* PASE mask */
++	.xSlicSegmentTablePtr = 0,	/* seg table */
++	.xOldLpQueue = { 0 },		/* Old LP Queue */
++	.xInterruptHdlr = {
++		(u64)system_reset_iSeries,	/* 0x100 System Reset */
++		(u64)machine_check_iSeries,	/* 0x200 Machine Check */
++		(u64)data_access_iSeries,	/* 0x300 Data Access */
++		(u64)instruction_access_iSeries, /* 0x400 Instruction Access */
++		(u64)hardware_interrupt_iSeries, /* 0x500 External */
++		(u64)alignment_iSeries,		/* 0x600 Alignment */
++		(u64)program_check_iSeries,	/* 0x700 Program Check */
++		(u64)fp_unavailable_iSeries,	/* 0x800 FP Unavailable */
++		(u64)decrementer_iSeries,	/* 0x900 Decrementer */
++		(u64)trap_0a_iSeries,		/* 0xa00 Trap 0A */
++		(u64)trap_0b_iSeries,		/* 0xb00 Trap 0B */
++		(u64)system_call_iSeries,	/* 0xc00 System Call */
++		(u64)single_step_iSeries,	/* 0xd00 Single Step */
++		(u64)trap_0e_iSeries,		/* 0xe00 Trap 0E */
++		(u64)performance_monitor_iSeries,/* 0xf00 Performance Monitor */
++		0,				/* int 0x1000 */
++		0,				/* int 0x1010 */
++		0,				/* int 0x1020 CPU ctls */
++		(u64)hardware_interrupt_iSeries, /* SC Ret Hdlr */
++		(u64)data_access_slb_iSeries,	/* 0x380 D-SLB */
++		(u64)instruction_access_slb_iSeries /* 0x480 I-SLB */
++	}
++};
++EXPORT_SYMBOL(itLpNaca);
++
++/* May be filled in by the hypervisor so cannot end up in the BSS */
++struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
++
++/* May be filled in by the hypervisor so cannot end up in the BSS */
++struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
++EXPORT_SYMBOL(xItExtVpdPanel);
++
++#define maxPhysicalProcessors 32
++
++struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
++	{
++		.xInstCacheOperandSize = 32,
++		.xDataCacheOperandSize = 32,
++		.xProcFreq     = 50000000,
++		.xTimeBaseFreq = 50000000,
++		.xPVR = 0x3600
++	}
++};
++
++/* Space for Main Store Vpd 27,200 bytes */
++/* May be filled in by the hypervisor so cannot end up in the BSS */
++u64    xMsVpd[3400] __attribute__((__section__(".data")));
++
++/* Space for Recovery Log Buffer */
++/* May be filled in by the hypervisor so cannot end up in the BSS */
++u64    xRecoveryLogBuffer[32] __attribute__((__section__(".data")));
++
++struct SpCommArea xSpCommArea = {
++	.xDesc = 0xE2D7C3C2,
++	.xFormat = 1,
++};
++
++/* The LparMap data is now located at offset 0x6000 in head.S
++ * It was put there so that the HvReleaseData could address it
++ * with a 32-bit offset as required by the iSeries hypervisor
++ *
++ * The Naca has a pointer to the ItVpdAreas.  The hypervisor finds
++ * the Naca via the HvReleaseData area.  The HvReleaseData has the
++ * offset into the Naca of the pointer to the ItVpdAreas.
++ */
++struct ItVpdAreas itVpdAreas = {
++	.xSlicDesc = 0xc9a3e5c1,		/* "ItVA" */
++	.xSlicSize = sizeof(struct ItVpdAreas),
++	.xSlicVpdEntries = ItVpdMaxEntries,	/* # VPD array entries */
++	.xSlicDmaEntries = ItDmaMaxEntries,	/* # DMA array entries */
++	.xSlicMaxLogicalProcs = NR_CPUS * 2,	/* Max logical procs */
++	.xSlicMaxPhysicalProcs = maxPhysicalProcessors,	/* Max physical procs */
++	.xSlicDmaToksOffset = offsetof(struct ItVpdAreas, xPlicDmaToks),
++	.xSlicVpdAdrsOffset = offsetof(struct ItVpdAreas, xSlicVpdAdrs),
++	.xSlicDmaLensOffset = offsetof(struct ItVpdAreas, xPlicDmaLens),
++	.xSlicVpdLensOffset = offsetof(struct ItVpdAreas, xSlicVpdLens),
++	.xSlicMaxSlotLabels = 0,		/* max slot labels */
++	.xSlicMaxLpQueues = 1,			/* max LP queues */
++	.xPlicDmaLens = { 0 },			/* DMA lengths */
++	.xPlicDmaToks = { 0 },			/* DMA tokens */
++	.xSlicVpdLens = {			/* VPD lengths */
++	        0,0,0,		        /*  0 - 2 */
++		sizeof(xItExtVpdPanel), /*       3 Extended VPD   */
++		sizeof(struct paca_struct),	/*       4 length of Paca  */
++		0,			/*       5 */
++		sizeof(struct ItIplParmsReal),/* 6 length of IPL parms */
++		26992,			/*	 7 length of MS VPD */
++		0,			/*       8 */
++		sizeof(struct ItLpNaca),/*       9 length of LP Naca */
++		0,			/*	10 */
++		256,			/*	11 length of Recovery Log Buf */
++		sizeof(struct SpCommArea), /*   12 length of SP Comm Area */
++		0,0,0,			/* 13 - 15 */
++		sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */
++		0,0,0,0,0,0,		/* 17 - 22  */
++		sizeof(struct hvlpevent_queue),	/* 23 length of Lp Queue */
++		0,0			/* 24 - 25 */
++		},
++	.xSlicVpdAdrs = {			/* VPD addresses */
++		0,0,0,			/*	 0 -  2 */
++		&xItExtVpdPanel,        /*       3 Extended VPD */
++		&paca[0],		/*       4 first Paca */
++		0,			/*       5 */
++		&xItIplParmsReal,	/*	 6 IPL parms */
++		&xMsVpd,		/*	 7 MS Vpd */
++		0,			/*       8 */
++		&itLpNaca,		/*       9 LpNaca */
++		0,			/*	10 */
++		&xRecoveryLogBuffer,	/*	11 Recovery Log Buffer */
++		&xSpCommArea,		/*	12 SP Comm Area */
++		0,0,0,			/* 13 - 15 */
++		&xIoHriProcessorVpd,	/*      16 Proc Vpd */
++		0,0,0,0,0,0,		/* 17 - 22 */
++		&hvlpevent_queue,	/*      23 Lp Queue */
++		0,0
++	}
++};
+diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/lpevents.c
+@@ -0,0 +1,325 @@
++/*
++ * Copyright (C) 2001 Mike Corrigan  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.
++ */
++
++#include <linux/stddef.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/bootmem.h>
++#include <linux/seq_file.h>
++#include <linux/proc_fs.h>
++#include <linux/module.h>
++
++#include <asm/system.h>
++#include <asm/paca.h>
++#include <asm/iSeries/ItLpQueue.h>
++#include <asm/iSeries/HvLpEvent.h>
++#include <asm/iSeries/HvCallEvent.h>
++#include <asm/iSeries/ItLpNaca.h>
++
++/*
++ * The LpQueue is used to pass event data from the hypervisor to
++ * the partition.  This is where I/O interrupt events are communicated.
++ *
++ * It is written to by the hypervisor so cannot end up in the BSS.
++ */
++struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data")));
++
++DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts);
++
++static char *event_types[HvLpEvent_Type_NumTypes] = {
++	"Hypervisor",
++	"Machine Facilities",
++	"Session Manager",
++	"SPD I/O",
++	"Virtual Bus",
++	"PCI I/O",
++	"RIO I/O",
++	"Virtual Lan",
++	"Virtual I/O"
++};
++
++/* Array of LpEvent handler functions */
++static LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
++static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
++
++static struct HvLpEvent * get_next_hvlpevent(void)
++{
++	struct HvLpEvent * event;
++	event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
++
++	if (event->xFlags.xValid) {
++		/* rmb() needed only for weakly consistent machines (regatta) */
++		rmb();
++		/* Set pointer to next potential event */
++		hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 +
++				LpEventAlign) / LpEventAlign) * LpEventAlign;
++
++		/* Wrap to beginning if no room at end */
++		if (hvlpevent_queue.xSlicCurEventPtr >
++				hvlpevent_queue.xSlicLastValidEventPtr) {
++			hvlpevent_queue.xSlicCurEventPtr =
++				hvlpevent_queue.xSlicEventStackPtr;
++		}
++	} else {
++		event = NULL;
++	}
++
++	return event;
++}
++
++static unsigned long spread_lpevents = NR_CPUS;
++
++int hvlpevent_is_pending(void)
++{
++	struct HvLpEvent *next_event;
++
++	if (smp_processor_id() >= spread_lpevents)
++		return 0;
++
++	next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
++
++	return next_event->xFlags.xValid |
++		hvlpevent_queue.xPlicOverflowIntPending;
++}
++
++static void hvlpevent_clear_valid(struct HvLpEvent * event)
++{
++	/* Tell the Hypervisor that we're done with this event.
++	 * Also clear bits within this event that might look like valid bits.
++	 * ie. on 64-byte boundaries.
++	 */
++	struct HvLpEvent *tmp;
++	unsigned extra = ((event->xSizeMinus1 + LpEventAlign) /
++						 LpEventAlign) - 1;
++
++	switch (extra) {
++	case 3:
++		tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign);
++		tmp->xFlags.xValid = 0;
++	case 2:
++		tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign);
++		tmp->xFlags.xValid = 0;
++	case 1:
++		tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign);
++		tmp->xFlags.xValid = 0;
++	}
++
++	mb();
++
++	event->xFlags.xValid = 0;
++}
++
++void process_hvlpevents(struct pt_regs *regs)
++{
++	struct HvLpEvent * event;
++
++	/* If we have recursed, just return */
++	if (!spin_trylock(&hvlpevent_queue.lock))
++		return;
++
++	for (;;) {
++		event = get_next_hvlpevent();
++		if (event) {
++			/* Call appropriate handler here, passing
++			 * a pointer to the LpEvent.  The handler
++			 * must make a copy of the LpEvent if it
++			 * needs it in a bottom half. (perhaps for
++			 * an ACK)
++			 *
++			 *  Handlers are responsible for ACK processing
++			 *
++			 * The Hypervisor guarantees that LpEvents will
++			 * only be delivered with types that we have
++			 * registered for, so no type check is necessary
++			 * here!
++			 */
++			if (event->xType < HvLpEvent_Type_NumTypes)
++				__get_cpu_var(hvlpevent_counts)[event->xType]++;
++			if (event->xType < HvLpEvent_Type_NumTypes &&
++					lpEventHandler[event->xType])
++				lpEventHandler[event->xType](event, regs);
++			else
++				printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType );
++
++			hvlpevent_clear_valid(event);
++		} else if (hvlpevent_queue.xPlicOverflowIntPending)
++			/*
++			 * No more valid events. If overflow events are
++			 * pending process them
++			 */
++			HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex);
++		else
++			break;
++	}
++
++	spin_unlock(&hvlpevent_queue.lock);
++}
++
++static int set_spread_lpevents(char *str)
++{
++	unsigned long val = simple_strtoul(str, NULL, 0);
++
++	/*
++	 * The parameter is the number of processors to share in processing
++	 * lp events.
++	 */
++	if (( val > 0) && (val <= NR_CPUS)) {
++		spread_lpevents = val;
++		printk("lpevent processing spread over %ld processors\n", val);
++	} else {
++		printk("invalid spread_lpevents %ld\n", val);
++	}
++
++	return 1;
++}
++__setup("spread_lpevents=", set_spread_lpevents);
++
++void setup_hvlpevent_queue(void)
++{
++	void *eventStack;
++
++	/* Allocate a page for the Event Stack. */
++	eventStack = alloc_bootmem_pages(LpEventStackSize);
++	memset(eventStack, 0, LpEventStackSize);
++
++	/* Invoke the hypervisor to initialize the event stack */
++	HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize);
++
++	hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack;
++	hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack;
++	hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack +
++					(LpEventStackSize - LpEventMaxSize);
++	hvlpevent_queue.xIndex = 0;
++}
++
++/* Register a handler for an LpEvent type */
++int HvLpEvent_registerHandler(HvLpEvent_Type eventType, LpEventHandler handler)
++{
++	if (eventType < HvLpEvent_Type_NumTypes) {
++		lpEventHandler[eventType] = handler;
++		return 0;
++	}
++	return 1;
++}
++EXPORT_SYMBOL(HvLpEvent_registerHandler);
++
++int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType)
++{
++	might_sleep();
++
++	if (eventType < HvLpEvent_Type_NumTypes) {
++		if (!lpEventHandlerPaths[eventType]) {
++			lpEventHandler[eventType] = NULL;
++			/*
++			 * We now sleep until all other CPUs have scheduled.
++			 * This ensures that the deletion is seen by all
++			 * other CPUs, and that the deleted handler isn't
++			 * still running on another CPU when we return.
++			 */
++			synchronize_rcu();
++			return 0;
++		}
++	}
++	return 1;
++}
++EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
++
++/*
++ * lpIndex is the partition index of the target partition.
++ * needed only for VirtualIo, VirtualLan and SessionMgr.  Zero
++ * indicates to use our partition index - for the other types.
++ */
++int HvLpEvent_openPath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
++{
++	if ((eventType < HvLpEvent_Type_NumTypes) &&
++			lpEventHandler[eventType]) {
++		if (lpIndex == 0)
++			lpIndex = itLpNaca.xLpIndex;
++		HvCallEvent_openLpEventPath(lpIndex, eventType);
++		++lpEventHandlerPaths[eventType];
++		return 0;
++	}
++	return 1;
++}
++
++int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
++{
++	if ((eventType < HvLpEvent_Type_NumTypes) &&
++			lpEventHandler[eventType] &&
++			lpEventHandlerPaths[eventType]) {
++		if (lpIndex == 0)
++			lpIndex = itLpNaca.xLpIndex;
++		HvCallEvent_closeLpEventPath(lpIndex, eventType);
++		--lpEventHandlerPaths[eventType];
++		return 0;
++	}
++	return 1;
++}
++
++static int proc_lpevents_show(struct seq_file *m, void *v)
++{
++	int cpu, i;
++	unsigned long sum;
++	static unsigned long cpu_totals[NR_CPUS];
++
++	/* FIXME: do we care that there's no locking here? */
++	sum = 0;
++	for_each_online_cpu(cpu) {
++		cpu_totals[cpu] = 0;
++		for (i = 0; i < HvLpEvent_Type_NumTypes; i++) {
++			cpu_totals[cpu] += per_cpu(hvlpevent_counts, cpu)[i];
++		}
++		sum += cpu_totals[cpu];
++	}
++
++	seq_printf(m, "LpEventQueue 0\n");
++	seq_printf(m, "  events processed:\t%lu\n", sum);
++
++	for (i = 0; i < HvLpEvent_Type_NumTypes; ++i) {
++		sum = 0;
++		for_each_online_cpu(cpu) {
++			sum += per_cpu(hvlpevent_counts, cpu)[i];
++		}
++
++		seq_printf(m, "    %-20s %10lu\n", event_types[i], sum);
++	}
++
++	seq_printf(m, "\n  events processed by processor:\n");
++
++	for_each_online_cpu(cpu) {
++		seq_printf(m, "    CPU%02d  %10lu\n", cpu, cpu_totals[cpu]);
++	}
++
++	return 0;
++}
++
++static int proc_lpevents_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, proc_lpevents_show, NULL);
++}
++
++static struct file_operations proc_lpevents_operations = {
++	.open		= proc_lpevents_open,
++	.read		= seq_read,
++	.llseek		= seq_lseek,
++	.release	= single_release,
++};
++
++static int __init proc_lpevents_init(void)
++{
++	struct proc_dir_entry *e;
++
++	e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL);
++	if (e)
++		e->proc_fops = &proc_lpevents_operations;
++
++	return 0;
++}
++__initcall(proc_lpevents_init);
++
+diff --git a/arch/powerpc/platforms/iseries/main_store.h b/arch/powerpc/platforms/iseries/main_store.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/main_store.h
+@@ -0,0 +1,165 @@
++/*
++ * Copyright (C) 2001  Mike Corrigan 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
++ */
++
++#ifndef _ISERIES_MAIN_STORE_H
++#define _ISERIES_MAIN_STORE_H
++
++/* Main Store Vpd for Condor,iStar,sStar */
++struct IoHriMainStoreSegment4 {
++	u8	msArea0Exists:1;
++	u8	msArea1Exists:1;
++	u8	msArea2Exists:1;
++	u8	msArea3Exists:1;
++	u8	reserved1:4;
++	u8	reserved2;
++
++	u8	msArea0Functional:1;
++	u8	msArea1Functional:1;
++	u8	msArea2Functional:1;
++	u8	msArea3Functional:1;
++	u8	reserved3:4;
++	u8	reserved4;
++
++	u32	totalMainStore;
++
++	u64	msArea0Ptr;
++	u64	msArea1Ptr;
++	u64	msArea2Ptr;
++	u64	msArea3Ptr;
++
++	u32	cardProductionLevel;
++
++	u32	msAdrHole;
++
++	u8	msArea0HasRiserVpd:1;
++	u8	msArea1HasRiserVpd:1;
++	u8	msArea2HasRiserVpd:1;
++	u8	msArea3HasRiserVpd:1;
++	u8	reserved5:4;
++	u8	reserved6;
++	u16	reserved7;
++
++	u8	reserved8[28];
++
++	u64	nonInterleavedBlocksStartAdr;
++	u64	nonInterleavedBlocksEndAdr;
++};
++
++/* Main Store VPD for Power4 */
++struct IoHriMainStoreChipInfo1 {
++	u32	chipMfgID	__attribute((packed));
++	char	chipECLevel[4]	__attribute((packed));
++};
++
++struct IoHriMainStoreVpdIdData {
++	char	typeNumber[4];
++	char	modelNumber[4];
++	char	partNumber[12];
++	char	serialNumber[12];
++};
++
++struct IoHriMainStoreVpdFruData {
++	char	fruLabel[8]	__attribute((packed));
++	u8	numberOfSlots	__attribute((packed));
++	u8	pluggingType	__attribute((packed));
++	u16	slotMapIndex	__attribute((packed));
++};
++
++struct IoHriMainStoreAdrRangeBlock {
++	void	*blockStart      __attribute((packed));
++	void	*blockEnd        __attribute((packed));
++	u32	blockProcChipId __attribute((packed));
++};
++
++#define MaxAreaAdrRangeBlocks 4
++
++struct IoHriMainStoreArea4 {
++	u32	msVpdFormat			__attribute((packed));
++	u8	containedVpdType		__attribute((packed));
++	u8	reserved1			__attribute((packed));
++	u16	reserved2			__attribute((packed));
++
++	u64	msExists			__attribute((packed));
++	u64	msFunctional			__attribute((packed));
++
++	u32	memorySize			__attribute((packed));
++	u32	procNodeId			__attribute((packed));
++
++	u32	numAdrRangeBlocks		__attribute((packed));
++	struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks]	__attribute((packed));
++
++	struct IoHriMainStoreChipInfo1	chipInfo0	__attribute((packed));
++	struct IoHriMainStoreChipInfo1	chipInfo1	__attribute((packed));
++	struct IoHriMainStoreChipInfo1	chipInfo2	__attribute((packed));
++	struct IoHriMainStoreChipInfo1	chipInfo3	__attribute((packed));
++	struct IoHriMainStoreChipInfo1	chipInfo4	__attribute((packed));
++	struct IoHriMainStoreChipInfo1	chipInfo5	__attribute((packed));
++	struct IoHriMainStoreChipInfo1	chipInfo6	__attribute((packed));
++	struct IoHriMainStoreChipInfo1	chipInfo7	__attribute((packed));
++
++	void	*msRamAreaArray			__attribute((packed));
++	u32	msRamAreaArrayNumEntries	__attribute((packed));
++	u32	msRamAreaArrayEntrySize		__attribute((packed));
++
++	u32	numaDimmExists			__attribute((packed));
++	u32	numaDimmFunctional		__attribute((packed));
++	void	*numaDimmArray			__attribute((packed));
++	u32	numaDimmArrayNumEntries		__attribute((packed));
++	u32	numaDimmArrayEntrySize		__attribute((packed));
++
++	struct IoHriMainStoreVpdIdData idData	__attribute((packed));
++
++	u64	powerData			__attribute((packed));
++	u64	cardAssemblyPartNum		__attribute((packed));
++	u64	chipSerialNum			__attribute((packed));
++
++	u64	reserved3			__attribute((packed));
++	char	reserved4[16]			__attribute((packed));
++
++	struct IoHriMainStoreVpdFruData fruData	__attribute((packed));
++
++	u8	vpdPortNum			__attribute((packed));
++	u8	reserved5			__attribute((packed));
++	u8	frameId				__attribute((packed));
++	u8	rackUnit			__attribute((packed));
++	char	asciiKeywordVpd[256]		__attribute((packed));
++	u32	reserved6			__attribute((packed));
++};
++
++
++struct IoHriMainStoreSegment5 {
++	u16	reserved1;
++	u8	reserved2;
++	u8	msVpdFormat;
++
++	u32	totalMainStore;
++	u64	maxConfiguredMsAdr;
++
++	struct IoHriMainStoreArea4	*msAreaArray;
++	u32	msAreaArrayNumEntries;
++	u32	msAreaArrayEntrySize;
++
++	u32	msAreaExists;
++	u32	msAreaFunctional;
++
++	u64	reserved3;
++};
++
++extern u64	xMsVpd[];
++
++#endif	/* _ISERIES_MAIN_STORE_H */
+diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/mf.c
+@@ -0,0 +1,1321 @@
++/*
++ * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
++ * Copyright (C) 2004-2005 Stephen Rothwell  IBM Corporation
++ *
++ * This modules exists as an interface between a Linux secondary partition
++ * running on an iSeries and the primary partition's Virtual Service
++ * Processor (VSP) object.  The VSP has final authority over powering on/off
++ * all partitions in the iSeries.  It also provides miscellaneous low-level
++ * machine facility type operations.
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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/errno.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/completion.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/bcd.h>
++#include <linux/rtc.h>
++
++#include <asm/time.h>
++#include <asm/uaccess.h>
++#include <asm/paca.h>
++#include <asm/abs_addr.h>
++#include <asm/iSeries/vio.h>
++#include <asm/iSeries/mf.h>
++#include <asm/iSeries/HvLpConfig.h>
++#include <asm/iSeries/ItLpQueue.h>
++
++#include "setup.h"
++
++extern int piranha_simulator;
++
++/*
++ * This is the structure layout for the Machine Facilites LPAR event
++ * flows.
++ */
++struct vsp_cmd_data {
++	u64 token;
++	u16 cmd;
++	HvLpIndex lp_index;
++	u8 result_code;
++	u32 reserved;
++	union {
++		u64 state;	/* GetStateOut */
++		u64 ipl_type;	/* GetIplTypeOut, Function02SelectIplTypeIn */
++		u64 ipl_mode;	/* GetIplModeOut, Function02SelectIplModeIn */
++		u64 page[4];	/* GetSrcHistoryIn */
++		u64 flag;	/* GetAutoIplWhenPrimaryIplsOut,
++				   SetAutoIplWhenPrimaryIplsIn,
++				   WhiteButtonPowerOffIn,
++				   Function08FastPowerOffIn,
++				   IsSpcnRackPowerIncompleteOut */
++		struct {
++			u64 token;
++			u64 address_type;
++			u64 side;
++			u32 length;
++			u32 offset;
++		} kern;		/* SetKernelImageIn, GetKernelImageIn,
++				   SetKernelCmdLineIn, GetKernelCmdLineIn */
++		u32 length_out;	/* GetKernelImageOut, GetKernelCmdLineOut */
++		u8 reserved[80];
++	} sub_data;
++};
++
++struct vsp_rsp_data {
++	struct completion com;
++	struct vsp_cmd_data *response;
++};
++
++struct alloc_data {
++	u16 size;
++	u16 type;
++	u32 count;
++	u16 reserved1;
++	u8 reserved2;
++	HvLpIndex target_lp;
++};
++
++struct ce_msg_data;
++
++typedef void (*ce_msg_comp_hdlr)(void *token, struct ce_msg_data *vsp_cmd_rsp);
++
++struct ce_msg_comp_data {
++	ce_msg_comp_hdlr handler;
++	void *token;
++};
++
++struct ce_msg_data {
++	u8 ce_msg[12];
++	char reserved[4];
++	struct ce_msg_comp_data *completion;
++};
++
++struct io_mf_lp_event {
++	struct HvLpEvent hp_lp_event;
++	u16 subtype_result_code;
++	u16 reserved1;
++	u32 reserved2;
++	union {
++		struct alloc_data alloc;
++		struct ce_msg_data ce_msg;
++		struct vsp_cmd_data vsp_cmd;
++	} data;
++};
++
++#define subtype_data(a, b, c, d)	\
++		(((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
++
++/*
++ * All outgoing event traffic is kept on a FIFO queue.  The first
++ * pointer points to the one that is outstanding, and all new
++ * requests get stuck on the end.  Also, we keep a certain number of
++ * preallocated pending events so that we can operate very early in
++ * the boot up sequence (before kmalloc is ready).
++ */
++struct pending_event {
++	struct pending_event *next;
++	struct io_mf_lp_event event;
++	MFCompleteHandler hdlr;
++	char dma_data[72];
++	unsigned dma_data_length;
++	unsigned remote_address;
++};
++static spinlock_t pending_event_spinlock;
++static struct pending_event *pending_event_head;
++static struct pending_event *pending_event_tail;
++static struct pending_event *pending_event_avail;
++static struct pending_event pending_event_prealloc[16];
++
++/*
++ * Put a pending event onto the available queue, so it can get reused.
++ * Attention! You must have the pending_event_spinlock before calling!
++ */
++static void free_pending_event(struct pending_event *ev)
++{
++	if (ev != NULL) {
++		ev->next = pending_event_avail;
++		pending_event_avail = ev;
++	}
++}
++
++/*
++ * Enqueue the outbound event onto the stack.  If the queue was
++ * empty to begin with, we must also issue it via the Hypervisor
++ * interface.  There is a section of code below that will touch
++ * the first stack pointer without the protection of the pending_event_spinlock.
++ * This is OK, because we know that nobody else will be modifying
++ * the first pointer when we do this.
++ */
++static int signal_event(struct pending_event *ev)
++{
++	int rc = 0;
++	unsigned long flags;
++	int go = 1;
++	struct pending_event *ev1;
++	HvLpEvent_Rc hv_rc;
++
++	/* enqueue the event */
++	if (ev != NULL) {
++		ev->next = NULL;
++		spin_lock_irqsave(&pending_event_spinlock, flags);
++		if (pending_event_head == NULL)
++			pending_event_head = ev;
++		else {
++			go = 0;
++			pending_event_tail->next = ev;
++		}
++		pending_event_tail = ev;
++		spin_unlock_irqrestore(&pending_event_spinlock, flags);
++	}
++
++	/* send the event */
++	while (go) {
++		go = 0;
++
++		/* any DMA data to send beforehand? */
++		if (pending_event_head->dma_data_length > 0)
++			HvCallEvent_dmaToSp(pending_event_head->dma_data,
++					pending_event_head->remote_address,
++					pending_event_head->dma_data_length,
++					HvLpDma_Direction_LocalToRemote);
++
++		hv_rc = HvCallEvent_signalLpEvent(
++				&pending_event_head->event.hp_lp_event);
++		if (hv_rc != HvLpEvent_Rc_Good) {
++			printk(KERN_ERR "mf.c: HvCallEvent_signalLpEvent() "
++					"failed with %d\n", (int)hv_rc);
++
++			spin_lock_irqsave(&pending_event_spinlock, flags);
++			ev1 = pending_event_head;
++			pending_event_head = pending_event_head->next;
++			if (pending_event_head != NULL)
++				go = 1;
++			spin_unlock_irqrestore(&pending_event_spinlock, flags);
++
++			if (ev1 == ev)
++				rc = -EIO;
++			else if (ev1->hdlr != NULL)
++				(*ev1->hdlr)((void *)ev1->event.hp_lp_event.xCorrelationToken, -EIO);
++
++			spin_lock_irqsave(&pending_event_spinlock, flags);
++			free_pending_event(ev1);
++			spin_unlock_irqrestore(&pending_event_spinlock, flags);
++		}
++	}
++
++	return rc;
++}
++
++/*
++ * Allocate a new pending_event structure, and initialize it.
++ */
++static struct pending_event *new_pending_event(void)
++{
++	struct pending_event *ev = NULL;
++	HvLpIndex primary_lp = HvLpConfig_getPrimaryLpIndex();
++	unsigned long flags;
++	struct HvLpEvent *hev;
++
++	spin_lock_irqsave(&pending_event_spinlock, flags);
++	if (pending_event_avail != NULL) {
++		ev = pending_event_avail;
++		pending_event_avail = pending_event_avail->next;
++	}
++	spin_unlock_irqrestore(&pending_event_spinlock, flags);
++	if (ev == NULL) {
++		ev = kmalloc(sizeof(struct pending_event), GFP_ATOMIC);
++		if (ev == NULL) {
++			printk(KERN_ERR "mf.c: unable to kmalloc %ld bytes\n",
++					sizeof(struct pending_event));
++			return NULL;
++		}
++	}
++	memset(ev, 0, sizeof(struct pending_event));
++	hev = &ev->event.hp_lp_event;
++	hev->xFlags.xValid = 1;
++	hev->xFlags.xAckType = HvLpEvent_AckType_ImmediateAck;
++	hev->xFlags.xAckInd = HvLpEvent_AckInd_DoAck;
++	hev->xFlags.xFunction = HvLpEvent_Function_Int;
++	hev->xType = HvLpEvent_Type_MachineFac;
++	hev->xSourceLp = HvLpConfig_getLpIndex();
++	hev->xTargetLp = primary_lp;
++	hev->xSizeMinus1 = sizeof(ev->event) - 1;
++	hev->xRc = HvLpEvent_Rc_Good;
++	hev->xSourceInstanceId = HvCallEvent_getSourceLpInstanceId(primary_lp,
++			HvLpEvent_Type_MachineFac);
++	hev->xTargetInstanceId = HvCallEvent_getTargetLpInstanceId(primary_lp,
++			HvLpEvent_Type_MachineFac);
++
++	return ev;
++}
++
++static int signal_vsp_instruction(struct vsp_cmd_data *vsp_cmd)
++{
++	struct pending_event *ev = new_pending_event();
++	int rc;
++	struct vsp_rsp_data response;
++
++	if (ev == NULL)
++		return -ENOMEM;
++
++	init_completion(&response.com);
++	response.response = vsp_cmd;
++	ev->event.hp_lp_event.xSubtype = 6;
++	ev->event.hp_lp_event.x.xSubtypeData =
++		subtype_data('M', 'F',  'V',  'I');
++	ev->event.data.vsp_cmd.token = (u64)&response;
++	ev->event.data.vsp_cmd.cmd = vsp_cmd->cmd;
++	ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex();
++	ev->event.data.vsp_cmd.result_code = 0xFF;
++	ev->event.data.vsp_cmd.reserved = 0;
++	memcpy(&(ev->event.data.vsp_cmd.sub_data),
++			&(vsp_cmd->sub_data), sizeof(vsp_cmd->sub_data));
++	mb();
++
++	rc = signal_event(ev);
++	if (rc == 0)
++		wait_for_completion(&response.com);
++	return rc;
++}
++
++
++/*
++ * Send a 12-byte CE message to the primary partition VSP object
++ */
++static int signal_ce_msg(char *ce_msg, struct ce_msg_comp_data *completion)
++{
++	struct pending_event *ev = new_pending_event();
++
++	if (ev == NULL)
++		return -ENOMEM;
++
++	ev->event.hp_lp_event.xSubtype = 0;
++	ev->event.hp_lp_event.x.xSubtypeData =
++		subtype_data('M',  'F',  'C',  'E');
++	memcpy(ev->event.data.ce_msg.ce_msg, ce_msg, 12);
++	ev->event.data.ce_msg.completion = completion;
++	return signal_event(ev);
++}
++
++/*
++ * Send a 12-byte CE message (with no data) to the primary partition VSP object
++ */
++static int signal_ce_msg_simple(u8 ce_op, struct ce_msg_comp_data *completion)
++{
++	u8 ce_msg[12];
++
++	memset(ce_msg, 0, sizeof(ce_msg));
++	ce_msg[3] = ce_op;
++	return signal_ce_msg(ce_msg, completion);
++}
++
++/*
++ * Send a 12-byte CE message and DMA data to the primary partition VSP object
++ */
++static int dma_and_signal_ce_msg(char *ce_msg,
++		struct ce_msg_comp_data *completion, void *dma_data,
++		unsigned dma_data_length, unsigned remote_address)
++{
++	struct pending_event *ev = new_pending_event();
++
++	if (ev == NULL)
++		return -ENOMEM;
++
++	ev->event.hp_lp_event.xSubtype = 0;
++	ev->event.hp_lp_event.x.xSubtypeData =
++		subtype_data('M', 'F', 'C', 'E');
++	memcpy(ev->event.data.ce_msg.ce_msg, ce_msg, 12);
++	ev->event.data.ce_msg.completion = completion;
++	memcpy(ev->dma_data, dma_data, dma_data_length);
++	ev->dma_data_length = dma_data_length;
++	ev->remote_address = remote_address;
++	return signal_event(ev);
++}
++
++/*
++ * Initiate a nice (hopefully) shutdown of Linux.  We simply are
++ * going to try and send the init process a SIGINT signal.  If
++ * this fails (why?), we'll simply force it off in a not-so-nice
++ * manner.
++ */
++static int shutdown(void)
++{
++	int rc = kill_proc(1, SIGINT, 1);
++
++	if (rc) {
++		printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), "
++				"hard shutdown commencing\n", rc);
++		mf_power_off();
++	} else
++		printk(KERN_INFO "mf.c: init has been successfully notified "
++				"to proceed with shutdown\n");
++	return rc;
++}
++
++/*
++ * The primary partition VSP object is sending us a new
++ * event flow.  Handle it...
++ */
++static void handle_int(struct io_mf_lp_event *event)
++{
++	struct ce_msg_data *ce_msg_data;
++	struct ce_msg_data *pce_msg_data;
++	unsigned long flags;
++	struct pending_event *pev;
++
++	/* ack the interrupt */
++	event->hp_lp_event.xRc = HvLpEvent_Rc_Good;
++	HvCallEvent_ackLpEvent(&event->hp_lp_event);
++
++	/* process interrupt */
++	switch (event->hp_lp_event.xSubtype) {
++	case 0:	/* CE message */
++		ce_msg_data = &event->data.ce_msg;
++		switch (ce_msg_data->ce_msg[3]) {
++		case 0x5B:	/* power control notification */
++			if ((ce_msg_data->ce_msg[5] & 0x20) != 0) {
++				printk(KERN_INFO "mf.c: Commencing partition shutdown\n");
++				if (shutdown() == 0)
++					signal_ce_msg_simple(0xDB, NULL);
++			}
++			break;
++		case 0xC0:	/* get time */
++			spin_lock_irqsave(&pending_event_spinlock, flags);
++			pev = pending_event_head;
++			if (pev != NULL)
++				pending_event_head = pending_event_head->next;
++			spin_unlock_irqrestore(&pending_event_spinlock, flags);
++			if (pev == NULL)
++				break;
++			pce_msg_data = &pev->event.data.ce_msg;
++			if (pce_msg_data->ce_msg[3] != 0x40)
++				break;
++			if (pce_msg_data->completion != NULL) {
++				ce_msg_comp_hdlr handler =
++					pce_msg_data->completion->handler;
++				void *token = pce_msg_data->completion->token;
++
++				if (handler != NULL)
++					(*handler)(token, ce_msg_data);
++			}
++			spin_lock_irqsave(&pending_event_spinlock, flags);
++			free_pending_event(pev);
++			spin_unlock_irqrestore(&pending_event_spinlock, flags);
++			/* send next waiting event */
++			if (pending_event_head != NULL)
++				signal_event(NULL);
++			break;
++		}
++		break;
++	case 1:	/* IT sys shutdown */
++		printk(KERN_INFO "mf.c: Commencing system shutdown\n");
++		shutdown();
++		break;
++	}
++}
++
++/*
++ * The primary partition VSP object is acknowledging the receipt
++ * of a flow we sent to them.  If there are other flows queued
++ * up, we must send another one now...
++ */
++static void handle_ack(struct io_mf_lp_event *event)
++{
++	unsigned long flags;
++	struct pending_event *two = NULL;
++	unsigned long free_it = 0;
++	struct ce_msg_data *ce_msg_data;
++	struct ce_msg_data *pce_msg_data;
++	struct vsp_rsp_data *rsp;
++
++	/* handle current event */
++	if (pending_event_head == NULL) {
++		printk(KERN_ERR "mf.c: stack empty for receiving ack\n");
++		return;
++	}
++
++	switch (event->hp_lp_event.xSubtype) {
++	case 0:     /* CE msg */
++		ce_msg_data = &event->data.ce_msg;
++		if (ce_msg_data->ce_msg[3] != 0x40) {
++			free_it = 1;
++			break;
++		}
++		if (ce_msg_data->ce_msg[2] == 0)
++			break;
++		free_it = 1;
++		pce_msg_data = &pending_event_head->event.data.ce_msg;
++		if (pce_msg_data->completion != NULL) {
++			ce_msg_comp_hdlr handler =
++				pce_msg_data->completion->handler;
++			void *token = pce_msg_data->completion->token;
++
++			if (handler != NULL)
++				(*handler)(token, ce_msg_data);
++		}
++		break;
++	case 4:	/* allocate */
++	case 5:	/* deallocate */
++		if (pending_event_head->hdlr != NULL)
++			(*pending_event_head->hdlr)((void *)event->hp_lp_event.xCorrelationToken, event->data.alloc.count);
++		free_it = 1;
++		break;
++	case 6:
++		free_it = 1;
++		rsp = (struct vsp_rsp_data *)event->data.vsp_cmd.token;
++		if (rsp == NULL) {
++			printk(KERN_ERR "mf.c: no rsp\n");
++			break;
++		}
++		if (rsp->response != NULL)
++			memcpy(rsp->response, &event->data.vsp_cmd,
++					sizeof(event->data.vsp_cmd));
++		complete(&rsp->com);
++		break;
++	}
++
++	/* remove from queue */
++	spin_lock_irqsave(&pending_event_spinlock, flags);
++	if ((pending_event_head != NULL) && (free_it == 1)) {
++		struct pending_event *oldHead = pending_event_head;
++
++		pending_event_head = pending_event_head->next;
++		two = pending_event_head;
++		free_pending_event(oldHead);
++	}
++	spin_unlock_irqrestore(&pending_event_spinlock, flags);
++
++	/* send next waiting event */
++	if (two != NULL)
++		signal_event(NULL);
++}
++
++/*
++ * This is the generic event handler we are registering with
++ * the Hypervisor.  Ensure the flows are for us, and then
++ * parse it enough to know if it is an interrupt or an
++ * acknowledge.
++ */
++static void hv_handler(struct HvLpEvent *event, struct pt_regs *regs)
++{
++	if ((event != NULL) && (event->xType == HvLpEvent_Type_MachineFac)) {
++		switch(event->xFlags.xFunction) {
++		case HvLpEvent_Function_Ack:
++			handle_ack((struct io_mf_lp_event *)event);
++			break;
++		case HvLpEvent_Function_Int:
++			handle_int((struct io_mf_lp_event *)event);
++			break;
++		default:
++			printk(KERN_ERR "mf.c: non ack/int event received\n");
++			break;
++		}
++	} else
++		printk(KERN_ERR "mf.c: alien event received\n");
++}
++
++/*
++ * Global kernel interface to allocate and seed events into the
++ * Hypervisor.
++ */
++void mf_allocate_lp_events(HvLpIndex target_lp, HvLpEvent_Type type,
++		unsigned size, unsigned count, MFCompleteHandler hdlr,
++		void *user_token)
++{
++	struct pending_event *ev = new_pending_event();
++	int rc;
++
++	if (ev == NULL) {
++		rc = -ENOMEM;
++	} else {
++		ev->event.hp_lp_event.xSubtype = 4;
++		ev->event.hp_lp_event.xCorrelationToken = (u64)user_token;
++		ev->event.hp_lp_event.x.xSubtypeData =
++			subtype_data('M', 'F', 'M', 'A');
++		ev->event.data.alloc.target_lp = target_lp;
++		ev->event.data.alloc.type = type;
++		ev->event.data.alloc.size = size;
++		ev->event.data.alloc.count = count;
++		ev->hdlr = hdlr;
++		rc = signal_event(ev);
++	}
++	if ((rc != 0) && (hdlr != NULL))
++		(*hdlr)(user_token, rc);
++}
++EXPORT_SYMBOL(mf_allocate_lp_events);
++
++/*
++ * Global kernel interface to unseed and deallocate events already in
++ * Hypervisor.
++ */
++void mf_deallocate_lp_events(HvLpIndex target_lp, HvLpEvent_Type type,
++		unsigned count, MFCompleteHandler hdlr, void *user_token)
++{
++	struct pending_event *ev = new_pending_event();
++	int rc;
++
++	if (ev == NULL)
++		rc = -ENOMEM;
++	else {
++		ev->event.hp_lp_event.xSubtype = 5;
++		ev->event.hp_lp_event.xCorrelationToken = (u64)user_token;
++		ev->event.hp_lp_event.x.xSubtypeData =
++			subtype_data('M', 'F', 'M', 'D');
++		ev->event.data.alloc.target_lp = target_lp;
++		ev->event.data.alloc.type = type;
++		ev->event.data.alloc.count = count;
++		ev->hdlr = hdlr;
++		rc = signal_event(ev);
++	}
++	if ((rc != 0) && (hdlr != NULL))
++		(*hdlr)(user_token, rc);
++}
++EXPORT_SYMBOL(mf_deallocate_lp_events);
++
++/*
++ * Global kernel interface to tell the VSP object in the primary
++ * partition to power this partition off.
++ */
++void mf_power_off(void)
++{
++	printk(KERN_INFO "mf.c: Down it goes...\n");
++	signal_ce_msg_simple(0x4d, NULL);
++	for (;;)
++		;
++}
++
++/*
++ * Global kernel interface to tell the VSP object in the primary
++ * partition to reboot this partition.
++ */
++void mf_reboot(void)
++{
++	printk(KERN_INFO "mf.c: Preparing to bounce...\n");
++	signal_ce_msg_simple(0x4e, NULL);
++	for (;;)
++		;
++}
++
++/*
++ * Display a single word SRC onto the VSP control panel.
++ */
++void mf_display_src(u32 word)
++{
++	u8 ce[12];
++
++	memset(ce, 0, sizeof(ce));
++	ce[3] = 0x4a;
++	ce[7] = 0x01;
++	ce[8] = word >> 24;
++	ce[9] = word >> 16;
++	ce[10] = word >> 8;
++	ce[11] = word;
++	signal_ce_msg(ce, NULL);
++}
++
++/*
++ * Display a single word SRC of the form "PROGXXXX" on the VSP control panel.
++ */
++void mf_display_progress(u16 value)
++{
++	u8 ce[12];
++	u8 src[72];
++
++	memcpy(ce, "\x00\x00\x04\x4A\x00\x00\x00\x48\x00\x00\x00\x00", 12);
++	memcpy(src, "\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
++		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
++		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
++		"\x00\x00\x00\x00PROGxxxx                        ",
++		72);
++	src[6] = value >> 8;
++	src[7] = value & 255;
++	src[44] = "0123456789ABCDEF"[(value >> 12) & 15];
++	src[45] = "0123456789ABCDEF"[(value >> 8) & 15];
++	src[46] = "0123456789ABCDEF"[(value >> 4) & 15];
++	src[47] = "0123456789ABCDEF"[value & 15];
++	dma_and_signal_ce_msg(ce, NULL, src, sizeof(src), 9 * 64 * 1024);
++}
++
++/*
++ * Clear the VSP control panel.  Used to "erase" an SRC that was
++ * previously displayed.
++ */
++void mf_clear_src(void)
++{
++	signal_ce_msg_simple(0x4b, NULL);
++}
++
++/*
++ * Initialization code here.
++ */
++void mf_init(void)
++{
++	int i;
++
++	/* initialize */
++	spin_lock_init(&pending_event_spinlock);
++	for (i = 0;
++	     i < sizeof(pending_event_prealloc) / sizeof(*pending_event_prealloc);
++	     ++i)
++		free_pending_event(&pending_event_prealloc[i]);
++	HvLpEvent_registerHandler(HvLpEvent_Type_MachineFac, &hv_handler);
++
++	/* virtual continue ack */
++	signal_ce_msg_simple(0x57, NULL);
++
++	/* initialization complete */
++	printk(KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities "
++			"initialized\n");
++}
++
++struct rtc_time_data {
++	struct completion com;
++	struct ce_msg_data ce_msg;
++	int rc;
++};
++
++static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
++{
++	struct rtc_time_data *rtc = token;
++
++	memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
++	rtc->rc = 0;
++	complete(&rtc->com);
++}
++
++static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
++{
++	tm->tm_wday = 0;
++	tm->tm_yday = 0;
++	tm->tm_isdst = 0;
++	if (rc) {
++		tm->tm_sec = 0;
++		tm->tm_min = 0;
++		tm->tm_hour = 0;
++		tm->tm_mday = 15;
++		tm->tm_mon = 5;
++		tm->tm_year = 52;
++		return rc;
++	}
++
++	if ((ce_msg[2] == 0xa9) ||
++	    (ce_msg[2] == 0xaf)) {
++		/* TOD clock is not set */
++		tm->tm_sec = 1;
++		tm->tm_min = 1;
++		tm->tm_hour = 1;
++		tm->tm_mday = 10;
++		tm->tm_mon = 8;
++		tm->tm_year = 71;
++		mf_set_rtc(tm);
++	}
++	{
++		u8 year = ce_msg[5];
++		u8 sec = ce_msg[6];
++		u8 min = ce_msg[7];
++		u8 hour = ce_msg[8];
++		u8 day = ce_msg[10];
++		u8 mon = ce_msg[11];
++
++		BCD_TO_BIN(sec);
++		BCD_TO_BIN(min);
++		BCD_TO_BIN(hour);
++		BCD_TO_BIN(day);
++		BCD_TO_BIN(mon);
++		BCD_TO_BIN(year);
++
++		if (year <= 69)
++			year += 100;
++
++		tm->tm_sec = sec;
++		tm->tm_min = min;
++		tm->tm_hour = hour;
++		tm->tm_mday = day;
++		tm->tm_mon = mon;
++		tm->tm_year = year;
++	}
++
++	return 0;
++}
++
++int mf_get_rtc(struct rtc_time *tm)
++{
++	struct ce_msg_comp_data ce_complete;
++	struct rtc_time_data rtc_data;
++	int rc;
++
++	memset(&ce_complete, 0, sizeof(ce_complete));
++	memset(&rtc_data, 0, sizeof(rtc_data));
++	init_completion(&rtc_data.com);
++	ce_complete.handler = &get_rtc_time_complete;
++	ce_complete.token = &rtc_data;
++	rc = signal_ce_msg_simple(0x40, &ce_complete);
++	if (rc)
++		return rc;
++	wait_for_completion(&rtc_data.com);
++	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
++}
++
++struct boot_rtc_time_data {
++	int busy;
++	struct ce_msg_data ce_msg;
++	int rc;
++};
++
++static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
++{
++	struct boot_rtc_time_data *rtc = token;
++
++	memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
++	rtc->rc = 0;
++	rtc->busy = 0;
++}
++
++int mf_get_boot_rtc(struct rtc_time *tm)
++{
++	struct ce_msg_comp_data ce_complete;
++	struct boot_rtc_time_data rtc_data;
++	int rc;
++
++	memset(&ce_complete, 0, sizeof(ce_complete));
++	memset(&rtc_data, 0, sizeof(rtc_data));
++	rtc_data.busy = 1;
++	ce_complete.handler = &get_boot_rtc_time_complete;
++	ce_complete.token = &rtc_data;
++	rc = signal_ce_msg_simple(0x40, &ce_complete);
++	if (rc)
++		return rc;
++	/* We need to poll here as we are not yet taking interrupts */
++	while (rtc_data.busy) {
++		if (hvlpevent_is_pending())
++			process_hvlpevents(NULL);
++	}
++	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
++}
++
++int mf_set_rtc(struct rtc_time *tm)
++{
++	char ce_time[12];
++	u8 day, mon, hour, min, sec, y1, y2;
++	unsigned year;
++
++	year = 1900 + tm->tm_year;
++	y1 = year / 100;
++	y2 = year % 100;
++
++	sec = tm->tm_sec;
++	min = tm->tm_min;
++	hour = tm->tm_hour;
++	day = tm->tm_mday;
++	mon = tm->tm_mon + 1;
++
++	BIN_TO_BCD(sec);
++	BIN_TO_BCD(min);
++	BIN_TO_BCD(hour);
++	BIN_TO_BCD(mon);
++	BIN_TO_BCD(day);
++	BIN_TO_BCD(y1);
++	BIN_TO_BCD(y2);
++
++	memset(ce_time, 0, sizeof(ce_time));
++	ce_time[3] = 0x41;
++	ce_time[4] = y1;
++	ce_time[5] = y2;
++	ce_time[6] = sec;
++	ce_time[7] = min;
++	ce_time[8] = hour;
++	ce_time[10] = day;
++	ce_time[11] = mon;
++
++	return signal_ce_msg(ce_time, NULL);
++}
++
++#ifdef CONFIG_PROC_FS
++
++static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
++		int count, int *eof, void *data)
++{
++	int len;
++	char *p;
++	struct vsp_cmd_data vsp_cmd;
++	int rc;
++	dma_addr_t dma_addr;
++
++	/* The HV appears to return no more than 256 bytes of command line */
++	if (off >= 256)
++		return 0;
++	if ((off + count) > 256)
++		count = 256 - off;
++
++	dma_addr = dma_map_single(iSeries_vio_dev, page, off + count,
++			DMA_FROM_DEVICE);
++	if (dma_mapping_error(dma_addr))
++		return -ENOMEM;
++	memset(page, 0, off + count);
++	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
++	vsp_cmd.cmd = 33;
++	vsp_cmd.sub_data.kern.token = dma_addr;
++	vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
++	vsp_cmd.sub_data.kern.side = (u64)data;
++	vsp_cmd.sub_data.kern.length = off + count;
++	mb();
++	rc = signal_vsp_instruction(&vsp_cmd);
++	dma_unmap_single(iSeries_vio_dev, dma_addr, off + count,
++			DMA_FROM_DEVICE);
++	if (rc)
++		return rc;
++	if (vsp_cmd.result_code != 0)
++		return -ENOMEM;
++	p = page;
++	len = 0;
++	while (len < (off + count)) {
++		if ((*p == '\0') || (*p == '\n')) {
++			if (*p == '\0')
++				*p = '\n';
++			p++;
++			len++;
++			*eof = 1;
++			break;
++		}
++		p++;
++		len++;
++	}
++
++	if (len < off) {
++		*eof = 1;
++		len = 0;
++	}
++	return len;
++}
++
++#if 0
++static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side)
++{
++	struct vsp_cmd_data vsp_cmd;
++	int rc;
++	int len = *size;
++	dma_addr_t dma_addr;
++
++	dma_addr = dma_map_single(iSeries_vio_dev, buffer, len,
++			DMA_FROM_DEVICE);
++	memset(buffer, 0, len);
++	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
++	vsp_cmd.cmd = 32;
++	vsp_cmd.sub_data.kern.token = dma_addr;
++	vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
++	vsp_cmd.sub_data.kern.side = side;
++	vsp_cmd.sub_data.kern.offset = offset;
++	vsp_cmd.sub_data.kern.length = len;
++	mb();
++	rc = signal_vsp_instruction(&vsp_cmd);
++	if (rc == 0) {
++		if (vsp_cmd.result_code == 0)
++			*size = vsp_cmd.sub_data.length_out;
++		else
++			rc = -ENOMEM;
++	}
++
++	dma_unmap_single(iSeries_vio_dev, dma_addr, len, DMA_FROM_DEVICE);
++
++	return rc;
++}
++
++static int proc_mf_dump_vmlinux(char *page, char **start, off_t off,
++		int count, int *eof, void *data)
++{
++	int sizeToGet = count;
++
++	if (!capable(CAP_SYS_ADMIN))
++		return -EACCES;
++
++	if (mf_getVmlinuxChunk(page, &sizeToGet, off, (u64)data) == 0) {
++		if (sizeToGet != 0) {
++			*start = page + off;
++			return sizeToGet;
++		}
++		*eof = 1;
++		return 0;
++	}
++	*eof = 1;
++	return 0;
++}
++#endif
++
++static int proc_mf_dump_side(char *page, char **start, off_t off,
++		int count, int *eof, void *data)
++{
++	int len;
++	char mf_current_side = ' ';
++	struct vsp_cmd_data vsp_cmd;
++
++	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
++	vsp_cmd.cmd = 2;
++	vsp_cmd.sub_data.ipl_type = 0;
++	mb();
++
++	if (signal_vsp_instruction(&vsp_cmd) == 0) {
++		if (vsp_cmd.result_code == 0) {
++			switch (vsp_cmd.sub_data.ipl_type) {
++			case 0:	mf_current_side = 'A';
++				break;
++			case 1:	mf_current_side = 'B';
++				break;
++			case 2:	mf_current_side = 'C';
++				break;
++			default:	mf_current_side = 'D';
++				break;
++			}
++		}
++	}
++
++	len = sprintf(page, "%c\n", mf_current_side);
++
++	if (len <= (off + count))
++		*eof = 1;
++	*start = page + off;
++	len -= off;
++	if (len > count)
++		len = count;
++	if (len < 0)
++		len = 0;
++	return len;
++}
++
++static int proc_mf_change_side(struct file *file, const char __user *buffer,
++		unsigned long count, void *data)
++{
++	char side;
++	u64 newSide;
++	struct vsp_cmd_data vsp_cmd;
++
++	if (!capable(CAP_SYS_ADMIN))
++		return -EACCES;
++
++	if (count == 0)
++		return 0;
++
++	if (get_user(side, buffer))
++		return -EFAULT;
++
++	switch (side) {
++	case 'A':	newSide = 0;
++			break;
++	case 'B':	newSide = 1;
++			break;
++	case 'C':	newSide = 2;
++			break;
++	case 'D':	newSide = 3;
++			break;
++	default:
++		printk(KERN_ERR "mf_proc.c: proc_mf_change_side: invalid side\n");
++		return -EINVAL;
++	}
++
++	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
++	vsp_cmd.sub_data.ipl_type = newSide;
++	vsp_cmd.cmd = 10;
++
++	(void)signal_vsp_instruction(&vsp_cmd);
++
++	return count;
++}
++
++#if 0
++static void mf_getSrcHistory(char *buffer, int size)
++{
++	struct IplTypeReturnStuff return_stuff;
++	struct pending_event *ev = new_pending_event();
++	int rc = 0;
++	char *pages[4];
++
++	pages[0] = kmalloc(4096, GFP_ATOMIC);
++	pages[1] = kmalloc(4096, GFP_ATOMIC);
++	pages[2] = kmalloc(4096, GFP_ATOMIC);
++	pages[3] = kmalloc(4096, GFP_ATOMIC);
++	if ((ev == NULL) || (pages[0] == NULL) || (pages[1] == NULL)
++			 || (pages[2] == NULL) || (pages[3] == NULL))
++		return -ENOMEM;
++
++	return_stuff.xType = 0;
++	return_stuff.xRc = 0;
++	return_stuff.xDone = 0;
++	ev->event.hp_lp_event.xSubtype = 6;
++	ev->event.hp_lp_event.x.xSubtypeData =
++		subtype_data('M', 'F', 'V', 'I');
++	ev->event.data.vsp_cmd.xEvent = &return_stuff;
++	ev->event.data.vsp_cmd.cmd = 4;
++	ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex();
++	ev->event.data.vsp_cmd.result_code = 0xFF;
++	ev->event.data.vsp_cmd.reserved = 0;
++	ev->event.data.vsp_cmd.sub_data.page[0] = iseries_hv_addr(pages[0]);
++	ev->event.data.vsp_cmd.sub_data.page[1] = iseries_hv_addr(pages[1]);
++	ev->event.data.vsp_cmd.sub_data.page[2] = iseries_hv_addr(pages[2]);
++	ev->event.data.vsp_cmd.sub_data.page[3] = iseries_hv_addr(pages[3]);
++	mb();
++	if (signal_event(ev) != 0)
++		return;
++
++ 	while (return_stuff.xDone != 1)
++ 		udelay(10);
++ 	if (return_stuff.xRc == 0)
++ 		memcpy(buffer, pages[0], size);
++	kfree(pages[0]);
++	kfree(pages[1]);
++	kfree(pages[2]);
++	kfree(pages[3]);
++}
++#endif
++
++static int proc_mf_dump_src(char *page, char **start, off_t off,
++		int count, int *eof, void *data)
++{
++#if 0
++	int len;
++
++	mf_getSrcHistory(page, count);
++	len = count;
++	len -= off;
++	if (len < count) {
++		*eof = 1;
++		if (len <= 0)
++			return 0;
++	} else
++		len = count;
++	*start = page + off;
++	return len;
++#else
++	return 0;
++#endif
++}
++
++static int proc_mf_change_src(struct file *file, const char __user *buffer,
++		unsigned long count, void *data)
++{
++	char stkbuf[10];
++
++	if (!capable(CAP_SYS_ADMIN))
++		return -EACCES;
++
++	if ((count < 4) && (count != 1)) {
++		printk(KERN_ERR "mf_proc: invalid src\n");
++		return -EINVAL;
++	}
++
++	if (count > (sizeof(stkbuf) - 1))
++		count = sizeof(stkbuf) - 1;
++	if (copy_from_user(stkbuf, buffer, count))
++		return -EFAULT;
++
++	if ((count == 1) && (*stkbuf == '\0'))
++		mf_clear_src();
++	else
++		mf_display_src(*(u32 *)stkbuf);
++
++	return count;
++}
++
++static int proc_mf_change_cmdline(struct file *file, const char __user *buffer,
++		unsigned long count, void *data)
++{
++	struct vsp_cmd_data vsp_cmd;
++	dma_addr_t dma_addr;
++	char *page;
++	int ret = -EACCES;
++
++	if (!capable(CAP_SYS_ADMIN))
++		goto out;
++
++	dma_addr = 0;
++	page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr,
++			GFP_ATOMIC);
++	ret = -ENOMEM;
++	if (page == NULL)
++		goto out;
++
++	ret = -EFAULT;
++	if (copy_from_user(page, buffer, count))
++		goto out_free;
++
++	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
++	vsp_cmd.cmd = 31;
++	vsp_cmd.sub_data.kern.token = dma_addr;
++	vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
++	vsp_cmd.sub_data.kern.side = (u64)data;
++	vsp_cmd.sub_data.kern.length = count;
++	mb();
++	(void)signal_vsp_instruction(&vsp_cmd);
++	ret = count;
++
++out_free:
++	dma_free_coherent(iSeries_vio_dev, count, page, dma_addr);
++out:
++	return ret;
++}
++
++static ssize_t proc_mf_change_vmlinux(struct file *file,
++				      const char __user *buf,
++				      size_t count, loff_t *ppos)
++{
++	struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
++	ssize_t rc;
++	dma_addr_t dma_addr;
++	char *page;
++	struct vsp_cmd_data vsp_cmd;
++
++	rc = -EACCES;
++	if (!capable(CAP_SYS_ADMIN))
++		goto out;
++
++	dma_addr = 0;
++	page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr,
++			GFP_ATOMIC);
++	rc = -ENOMEM;
++	if (page == NULL) {
++		printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n");
++		goto out;
++	}
++	rc = -EFAULT;
++	if (copy_from_user(page, buf, count))
++		goto out_free;
++
++	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
++	vsp_cmd.cmd = 30;
++	vsp_cmd.sub_data.kern.token = dma_addr;
++	vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
++	vsp_cmd.sub_data.kern.side = (u64)dp->data;
++	vsp_cmd.sub_data.kern.offset = *ppos;
++	vsp_cmd.sub_data.kern.length = count;
++	mb();
++	rc = signal_vsp_instruction(&vsp_cmd);
++	if (rc)
++		goto out_free;
++	rc = -ENOMEM;
++	if (vsp_cmd.result_code != 0)
++		goto out_free;
++
++	*ppos += count;
++	rc = count;
++out_free:
++	dma_free_coherent(iSeries_vio_dev, count, page, dma_addr);
++out:
++	return rc;
++}
++
++static struct file_operations proc_vmlinux_operations = {
++	.write		= proc_mf_change_vmlinux,
++};
++
++static int __init mf_proc_init(void)
++{
++	struct proc_dir_entry *mf_proc_root;
++	struct proc_dir_entry *ent;
++	struct proc_dir_entry *mf;
++	char name[2];
++	int i;
++
++	mf_proc_root = proc_mkdir("iSeries/mf", NULL);
++	if (!mf_proc_root)
++		return 1;
++
++	name[1] = '\0';
++	for (i = 0; i < 4; i++) {
++		name[0] = 'A' + i;
++		mf = proc_mkdir(name, mf_proc_root);
++		if (!mf)
++			return 1;
++
++		ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf);
++		if (!ent)
++			return 1;
++		ent->nlink = 1;
++		ent->data = (void *)(long)i;
++		ent->read_proc = proc_mf_dump_cmdline;
++		ent->write_proc = proc_mf_change_cmdline;
++
++		if (i == 3)	/* no vmlinux entry for 'D' */
++			continue;
++
++		ent = create_proc_entry("vmlinux", S_IFREG|S_IWUSR, mf);
++		if (!ent)
++			return 1;
++		ent->nlink = 1;
++		ent->data = (void *)(long)i;
++		ent->proc_fops = &proc_vmlinux_operations;
++	}
++
++	ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
++	if (!ent)
++		return 1;
++	ent->nlink = 1;
++	ent->data = (void *)0;
++	ent->read_proc = proc_mf_dump_side;
++	ent->write_proc = proc_mf_change_side;
++
++	ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
++	if (!ent)
++		return 1;
++	ent->nlink = 1;
++	ent->data = (void *)0;
++	ent->read_proc = proc_mf_dump_src;
++	ent->write_proc = proc_mf_change_src;
++
++	return 0;
++}
++
++__initcall(mf_proc_init);
++
++#endif /* CONFIG_PROC_FS */
++
++/*
++ * Get the RTC from the virtual service processor
++ * This requires flowing LpEvents to the primary partition
++ */
++void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
++{
++	if (piranha_simulator)
++		return;
++
++	mf_get_rtc(rtc_tm);
++	rtc_tm->tm_mon--;
++}
++
++/*
++ * Set the RTC in the virtual service processor
++ * This requires flowing LpEvents to the primary partition
++ */
++int iSeries_set_rtc_time(struct rtc_time *tm)
++{
++	mf_set_rtc(tm);
++	return 0;
++}
++
++unsigned long iSeries_get_boot_time(void)
++{
++	struct rtc_time tm;
++
++	if (piranha_simulator)
++		return 0;
++
++	mf_get_boot_rtc(&tm);
++	return mktime(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday,
++		      tm.tm_hour, tm.tm_min, tm.tm_sec);
++}
+diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/misc.S
+@@ -0,0 +1,55 @@
++/*
++ * This file contains miscellaneous low-level functions.
++ *    Copyright (C) 1995-2005 IBM Corp
++ *
++ * Largely rewritten by Cort Dougan (cort at cs.nmt.edu)
++ * and Paul Mackerras.
++ * Adapted for iSeries by Mike Corrigan (mikejc at us.ibm.com)
++ * PPC64 updates by Dave Engebretsen (engebret at 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/processor.h>
++#include <asm/asm-offsets.h>
++
++	.text
++
++/* unsigned long local_save_flags(void) */
++_GLOBAL(local_get_flags)
++	lbz	r3,PACAPROCENABLED(r13)
++	blr
++
++/* unsigned long local_irq_disable(void) */
++_GLOBAL(local_irq_disable)
++	lbz	r3,PACAPROCENABLED(r13)
++	li	r4,0
++	stb	r4,PACAPROCENABLED(r13)
++	blr			/* Done */
++
++/* void local_irq_restore(unsigned long flags) */
++_GLOBAL(local_irq_restore)
++	lbz	r5,PACAPROCENABLED(r13)
++	 /* Check if things are setup the way we want _already_. */
++	cmpw	0,r3,r5
++	beqlr
++	/* are we enabling interrupts? */
++	cmpdi	0,r3,0
++	stb	r3,PACAPROCENABLED(r13)
++	beqlr
++	/* Check pending interrupts */
++	/*   A decrementer, IPI or PMC interrupt may have occurred
++	 *   while we were in the hypervisor (which enables) */
++	ld	r4,PACALPPACA+LPPACAANYINT(r13)
++	cmpdi	r4,0
++	beqlr
++
++	/*
++	 * Handle pending interrupts in interrupt context
++	 */
++	li	r0,0x5555
++	sc
++	blr
+diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/pci.c
+@@ -0,0 +1,906 @@
++/*
++ * Copyright (C) 2001 Allan Trautman, IBM Corporation
++ *
++ * iSeries specific routines for PCI.
++ *
++ * Based on code from pci.c and iSeries_pci.c 32bit
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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/list.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/ide.h>
++#include <linux/pci.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++#include <asm/pci-bridge.h>
++#include <asm/ppcdebug.h>
++#include <asm/iommu.h>
++#include <asm/abs_addr.h>
++
++#include <asm/iSeries/HvCallXm.h>
++#include <asm/iSeries/mf.h>
++
++#include <asm/ppc-pci.h>
++
++#include "irq.h"
++#include "pci.h"
++#include "call_pci.h"
++
++extern unsigned long io_page_mask;
++
++/*
++ * Forward declares of prototypes.
++ */
++static struct device_node *find_Device_Node(int bus, int devfn);
++static void scan_PHB_slots(struct pci_controller *Phb);
++static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
++static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);
++
++LIST_HEAD(iSeries_Global_Device_List);
++
++static int DeviceCount;
++
++/* Counters and control flags. */
++static long Pci_Io_Read_Count;
++static long Pci_Io_Write_Count;
++#if 0
++static long Pci_Cfg_Read_Count;
++static long Pci_Cfg_Write_Count;
++#endif
++static long Pci_Error_Count;
++
++static int Pci_Retry_Max = 3;	/* Only retry 3 times  */
++static int Pci_Error_Flag = 1;	/* Set Retry Error on. */
++
++static struct pci_ops iSeries_pci_ops;
++
++/*
++ * Table defines
++ * Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space.
++ */
++#define IOMM_TABLE_MAX_ENTRIES	1024
++#define IOMM_TABLE_ENTRY_SIZE	0x0000000000400000UL
++#define BASE_IO_MEMORY		0xE000000000000000UL
++
++static unsigned long max_io_memory = 0xE000000000000000UL;
++static long current_iomm_table_entry;
++
++/*
++ * Lookup Tables.
++ */
++static struct device_node **iomm_table;
++static u8 *iobar_table;
++
++/*
++ * Static and Global variables
++ */
++static char *pci_io_text = "iSeries PCI I/O";
++static DEFINE_SPINLOCK(iomm_table_lock);
++
++/*
++ * iomm_table_initialize
++ *
++ * Allocates and initalizes the Address Translation Table and Bar
++ * Tables to get them ready for use.  Must be called before any
++ * I/O space is handed out to the device BARs.
++ */
++static void iomm_table_initialize(void)
++{
++	spin_lock(&iomm_table_lock);
++	iomm_table = kmalloc(sizeof(*iomm_table) * IOMM_TABLE_MAX_ENTRIES,
++			GFP_KERNEL);
++	iobar_table = kmalloc(sizeof(*iobar_table) * IOMM_TABLE_MAX_ENTRIES,
++			GFP_KERNEL);
++	spin_unlock(&iomm_table_lock);
++	if ((iomm_table == NULL) || (iobar_table == NULL))
++		panic("PCI: I/O tables allocation failed.\n");
++}
++
++/*
++ * iomm_table_allocate_entry
++ *
++ * Adds pci_dev entry in address translation table
++ *
++ * - Allocates the number of entries required in table base on BAR
++ *   size.
++ * - Allocates starting at BASE_IO_MEMORY and increases.
++ * - The size is round up to be a multiple of entry size.
++ * - CurrentIndex is incremented to keep track of the last entry.
++ * - Builds the resource entry for allocated BARs.
++ */
++static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
++{
++	struct resource *bar_res = &dev->resource[bar_num];
++	long bar_size = pci_resource_len(dev, bar_num);
++
++	/*
++	 * No space to allocate, quick exit, skip Allocation.
++	 */
++	if (bar_size == 0)
++		return;
++	/*
++	 * Set Resource values.
++	 */
++	spin_lock(&iomm_table_lock);
++	bar_res->name = pci_io_text;
++	bar_res->start =
++		IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
++	bar_res->start += BASE_IO_MEMORY;
++	bar_res->end = bar_res->start + bar_size - 1;
++	/*
++	 * Allocate the number of table entries needed for BAR.
++	 */
++	while (bar_size > 0 ) {
++		iomm_table[current_iomm_table_entry] = dev->sysdata;
++		iobar_table[current_iomm_table_entry] = bar_num;
++		bar_size -= IOMM_TABLE_ENTRY_SIZE;
++		++current_iomm_table_entry;
++	}
++	max_io_memory = BASE_IO_MEMORY +
++		(IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry);
++	spin_unlock(&iomm_table_lock);
++}
++
++/*
++ * allocate_device_bars
++ *
++ * - Allocates ALL pci_dev BAR's and updates the resources with the
++ *   BAR value.  BARS with zero length will have the resources
++ *   The HvCallPci_getBarParms is used to get the size of the BAR
++ *   space.  It calls iomm_table_allocate_entry to allocate
++ *   each entry.
++ * - Loops through The Bar resources(0 - 5) including the ROM
++ *   is resource(6).
++ */
++static void allocate_device_bars(struct pci_dev *dev)
++{
++	struct resource *bar_res;
++	int bar_num;
++
++	for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) {
++		bar_res = &dev->resource[bar_num];
++		iomm_table_allocate_entry(dev, bar_num);
++	}
++}
++
++/*
++ * Log error information to system console.
++ * Filter out the device not there errors.
++ * PCI: EADs Connect Failed 0x18.58.10 Rc: 0x00xx
++ * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
++ * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
++ */
++static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
++		int AgentId, int HvRc)
++{
++	if (HvRc == 0x0302)
++		return;
++	printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",
++	       Error_Text, Bus, SubBus, AgentId, HvRc);
++}
++
++/*
++ * build_device_node(u16 Bus, int SubBus, u8 DevFn)
++ */
++static struct device_node *build_device_node(HvBusNumber Bus,
++		HvSubBusNumber SubBus, int AgentId, int Function)
++{
++	struct device_node *node;
++	struct pci_dn *pdn;
++
++	PPCDBG(PPCDBG_BUSWALK,
++			"-build_device_node 0x%02X.%02X.%02X Function: %02X\n",
++			Bus, SubBus, AgentId, Function);
++
++	node = kmalloc(sizeof(struct device_node), GFP_KERNEL);
++	if (node == NULL)
++		return NULL;
++	memset(node, 0, sizeof(struct device_node));
++	pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
++	if (pdn == NULL) {
++		kfree(node);
++		return NULL;
++	}
++	node->data = pdn;
++	pdn->node = node;
++	list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List);
++	pdn->busno = Bus;
++	pdn->bussubno = SubBus;
++	pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
++	return node;
++}
++
++/*
++ * unsigned long __init find_and_init_phbs(void)
++ *
++ * Description:
++ *   This function checks for all possible system PCI host bridges that connect
++ *   PCI buses.  The system hypervisor is queried as to the guest partition
++ *   ownership status.  A pci_controller is built for any bus which is partially
++ *   owned or fully owned by this guest partition.
++ */
++unsigned long __init find_and_init_phbs(void)
++{
++	struct pci_controller *phb;
++	HvBusNumber bus;
++
++	PPCDBG(PPCDBG_BUSWALK, "find_and_init_phbs Entry\n");
++
++	/* Check all possible buses. */
++	for (bus = 0; bus < 256; bus++) {
++		int ret = HvCallXm_testBus(bus);
++		if (ret == 0) {
++			printk("bus %d appears to exist\n", bus);
++
++			phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
++			if (phb == NULL)
++				return -ENOMEM;
++			pci_setup_pci_controller(phb);
++
++			phb->pci_mem_offset = phb->local_number = bus;
++			phb->first_busno = bus;
++			phb->last_busno = bus;
++			phb->ops = &iSeries_pci_ops;
++
++			PPCDBG(PPCDBG_BUSWALK, "PCI:Create iSeries pci_controller(%p), Bus: %04X\n",
++					phb, bus);
++
++			/* Find and connect the devices. */
++			scan_PHB_slots(phb);
++		}
++		/*
++		 * Check for Unexpected Return code, a clue that something
++		 * has gone wrong.
++		 */
++		else if (ret != 0x0301)
++			printk(KERN_ERR "Unexpected Return on Probe(0x%04X): 0x%04X",
++			       bus, ret);
++	}
++	return 0;
++}
++
++/*
++ * iSeries_pcibios_init
++ *
++ * Chance to initialize and structures or variable before PCI Bus walk.
++ */
++void iSeries_pcibios_init(void)
++{
++	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n");
++	iomm_table_initialize();
++	find_and_init_phbs();
++	io_page_mask = -1;
++	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n");
++}
++
++/*
++ * iSeries_pci_final_fixup(void)
++ */
++void __init iSeries_pci_final_fixup(void)
++{
++	struct pci_dev *pdev = NULL;
++	struct device_node *node;
++	int DeviceCount = 0;
++
++	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n");
++
++	/* Fix up at the device node and pci_dev relationship */
++	mf_display_src(0xC9000100);
++
++	printk("pcibios_final_fixup\n");
++	for_each_pci_dev(pdev) {
++		node = find_Device_Node(pdev->bus->number, pdev->devfn);
++		printk("pci dev %p (%x.%x), node %p\n", pdev,
++		       pdev->bus->number, pdev->devfn, node);
++
++		if (node != NULL) {
++			++DeviceCount;
++			pdev->sysdata = (void *)node;
++			PCI_DN(node)->pcidev = pdev;
++			PPCDBG(PPCDBG_BUSWALK,
++					"pdev 0x%p <==> DevNode 0x%p\n",
++					pdev, node);
++			allocate_device_bars(pdev);
++			iSeries_Device_Information(pdev, DeviceCount);
++			iommu_devnode_init_iSeries(node);
++		} else
++			printk("PCI: Device Tree not found for 0x%016lX\n",
++					(unsigned long)pdev);
++		pdev->irq = PCI_DN(node)->Irq;
++	}
++	iSeries_activate_IRQs();
++	mf_display_src(0xC9000200);
++}
++
++void pcibios_fixup_bus(struct pci_bus *PciBus)
++{
++	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",
++			PciBus->number);
++}
++
++void pcibios_fixup_resources(struct pci_dev *pdev)
++{
++	PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev);
++}
++
++/*
++ * Loop through each node function to find usable EADs bridges.
++ */
++static void scan_PHB_slots(struct pci_controller *Phb)
++{
++	struct HvCallPci_DeviceInfo *DevInfo;
++	HvBusNumber bus = Phb->local_number;	/* System Bus */
++	const HvSubBusNumber SubBus = 0;	/* EADs is always 0. */
++	int HvRc = 0;
++	int IdSel;
++	const int MaxAgents = 8;
++
++	DevInfo = (struct HvCallPci_DeviceInfo*)
++		kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);
++	if (DevInfo == NULL)
++		return;
++
++	/*
++	 * Probe for EADs Bridges
++	 */
++	for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
++		HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
++				iseries_hv_addr(DevInfo),
++				sizeof(struct HvCallPci_DeviceInfo));
++		if (HvRc == 0) {
++			if (DevInfo->deviceType == HvCallPci_NodeDevice)
++				scan_EADS_bridge(bus, SubBus, IdSel);
++			else
++				printk("PCI: Invalid System Configuration(0x%02X)"
++				       " for bus 0x%02x id 0x%02x.\n",
++				       DevInfo->deviceType, bus, IdSel);
++		}
++		else
++			pci_Log_Error("getDeviceInfo", bus, SubBus, IdSel, HvRc);
++	}
++	kfree(DevInfo);
++}
++
++static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
++		int IdSel)
++{
++	struct HvCallPci_BridgeInfo *BridgeInfo;
++	HvAgentId AgentId;
++	int Function;
++	int HvRc;
++
++	BridgeInfo = (struct HvCallPci_BridgeInfo *)
++		kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL);
++	if (BridgeInfo == NULL)
++		return;
++
++	/* Note: hvSubBus and irq is always be 0 at this level! */
++	for (Function = 0; Function < 8; ++Function) {
++		AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
++		HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
++		if (HvRc == 0) {
++			printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
++			       bus, IdSel, Function, AgentId);
++			/*  Connect EADs: 0x18.00.12 = 0x00 */
++			PPCDBG(PPCDBG_BUSWALK,
++					"PCI:Connect EADs: 0x%02X.%02X.%02X\n",
++					bus, SubBus, AgentId);
++			HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
++					iseries_hv_addr(BridgeInfo),
++					sizeof(struct HvCallPci_BridgeInfo));
++			if (HvRc == 0) {
++				printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
++					BridgeInfo->busUnitInfo.deviceType,
++					BridgeInfo->subBusNumber,
++					BridgeInfo->maxAgents,
++					BridgeInfo->maxSubBusNumber,
++					BridgeInfo->logicalSlotNumber);
++				PPCDBG(PPCDBG_BUSWALK,
++					"PCI: BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X\n",
++					BridgeInfo->busUnitInfo.deviceType,
++					BridgeInfo->subBusNumber,
++					BridgeInfo->maxAgents,
++					BridgeInfo->maxSubBusNumber,
++					BridgeInfo->logicalSlotNumber);
++
++				if (BridgeInfo->busUnitInfo.deviceType ==
++						HvCallPci_BridgeDevice)  {
++					/* Scan_Bridge_Slot...: 0x18.00.12 */
++					scan_bridge_slot(bus, BridgeInfo);
++				} else
++					printk("PCI: Invalid Bridge Configuration(0x%02X)",
++						BridgeInfo->busUnitInfo.deviceType);
++			}
++		} else if (HvRc != 0x000B)
++			pci_Log_Error("EADs Connect",
++					bus, SubBus, AgentId, HvRc);
++	}
++	kfree(BridgeInfo);
++}
++
++/*
++ * This assumes that the node slot is always on the primary bus!
++ */
++static int scan_bridge_slot(HvBusNumber Bus,
++		struct HvCallPci_BridgeInfo *BridgeInfo)
++{
++	struct device_node *node;
++	HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
++	u16 VendorId = 0;
++	int HvRc = 0;
++	u8 Irq = 0;
++	int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
++	int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
++	HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
++
++	/* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
++	Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
++	PPCDBG(PPCDBG_BUSWALK,
++		"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",
++		Bus, 0, EADsIdSel, Irq);
++
++	/*
++	 * Connect all functions of any device found.
++	 */
++	for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
++		for (Function = 0; Function < 8; ++Function) {
++			HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
++			HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
++					AgentId, Irq);
++			if (HvRc != 0) {
++				pci_Log_Error("Connect Bus Unit",
++					      Bus, SubBus, AgentId, HvRc);
++				continue;
++			}
++
++			HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId,
++						      PCI_VENDOR_ID, &VendorId);
++			if (HvRc != 0) {
++				pci_Log_Error("Read Vendor",
++					      Bus, SubBus, AgentId, HvRc);
++				continue;
++			}
++			printk("read vendor ID: %x\n", VendorId);
++
++			/* FoundDevice: 0x18.28.10 = 0x12AE */
++			PPCDBG(PPCDBG_BUSWALK,
++			       "PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n",
++			       Bus, SubBus, AgentId, VendorId, Irq);
++			HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
++						      PCI_INTERRUPT_LINE, Irq);
++			if (HvRc != 0)
++				pci_Log_Error("PciCfgStore Irq Failed!",
++					      Bus, SubBus, AgentId, HvRc);
++
++			++DeviceCount;
++			node = build_device_node(Bus, SubBus, EADsIdSel, Function);
++			PCI_DN(node)->Irq = Irq;
++			PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber;
++
++		} /* for (Function = 0; Function < 8; ++Function) */
++	} /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
++	return HvRc;
++}
++
++/*
++ * I/0 Memory copy MUST use mmio commands on iSeries
++ * To do; For performance, include the hv call directly
++ */
++void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
++{
++	u8 ByteValue = c;
++	long NumberOfBytes = Count;
++
++	while (NumberOfBytes > 0) {
++		iSeries_Write_Byte(ByteValue, dest++);
++		-- NumberOfBytes;
++	}
++}
++EXPORT_SYMBOL(iSeries_memset_io);
++
++void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
++{
++	char *src = source;
++	long NumberOfBytes = count;
++
++	while (NumberOfBytes > 0) {
++		iSeries_Write_Byte(*src++, dest++);
++		-- NumberOfBytes;
++	}
++}
++EXPORT_SYMBOL(iSeries_memcpy_toio);
++
++void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
++{
++	char *dst = dest;
++	long NumberOfBytes = count;
++
++	while (NumberOfBytes > 0) {
++		*dst++ = iSeries_Read_Byte(src++);
++		-- NumberOfBytes;
++	}
++}
++EXPORT_SYMBOL(iSeries_memcpy_fromio);
++
++/*
++ * Look down the chain to find the matching Device Device
++ */
++static struct device_node *find_Device_Node(int bus, int devfn)
++{
++	struct pci_dn *pdn;
++
++	list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) {
++		if ((bus == pdn->busno) && (devfn == pdn->devfn))
++			return pdn->node;
++	}
++	return NULL;
++}
++
++#if 0
++/*
++ * Returns the device node for the passed pci_dev
++ * Sanity Check Node PciDev to passed pci_dev
++ * If none is found, returns a NULL which the client must handle.
++ */
++static struct device_node *get_Device_Node(struct pci_dev *pdev)
++{
++	struct device_node *node;
++
++	node = pdev->sysdata;
++	if (node == NULL || PCI_DN(node)->pcidev != pdev)
++		node = find_Device_Node(pdev->bus->number, pdev->devfn);
++	return node;
++}
++#endif
++
++/*
++ * Config space read and write functions.
++ * For now at least, we look for the device node for the bus and devfn
++ * that we are asked to access.  It may be possible to translate the devfn
++ * to a subbus and deviceid more directly.
++ */
++static u64 hv_cfg_read_func[4]  = {
++	HvCallPciConfigLoad8, HvCallPciConfigLoad16,
++	HvCallPciConfigLoad32, HvCallPciConfigLoad32
++};
++
++static u64 hv_cfg_write_func[4] = {
++	HvCallPciConfigStore8, HvCallPciConfigStore16,
++	HvCallPciConfigStore32, HvCallPciConfigStore32
++};
++
++/*
++ * Read PCI config space
++ */
++static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
++		int offset, int size, u32 *val)
++{
++	struct device_node *node = find_Device_Node(bus->number, devfn);
++	u64 fn;
++	struct HvCallPci_LoadReturn ret;
++
++	if (node == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	if (offset > 255) {
++		*val = ~0;
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++	}
++
++	fn = hv_cfg_read_func[(size - 1) & 3];
++	HvCall3Ret16(fn, &ret, iseries_ds_addr(node), offset, 0);
++
++	if (ret.rc != 0) {
++		*val = ~0;
++		return PCIBIOS_DEVICE_NOT_FOUND;	/* or something */
++	}
++
++	*val = ret.value;
++	return 0;
++}
++
++/*
++ * Write PCI config space
++ */
++
++static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
++		int offset, int size, u32 val)
++{
++	struct device_node *node = find_Device_Node(bus->number, devfn);
++	u64 fn;
++	u64 ret;
++
++	if (node == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	if (offset > 255)
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	fn = hv_cfg_write_func[(size - 1) & 3];
++	ret = HvCall4(fn, iseries_ds_addr(node), offset, val, 0);
++
++	if (ret != 0)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	return 0;
++}
++
++static struct pci_ops iSeries_pci_ops = {
++	.read = iSeries_pci_read_config,
++	.write = iSeries_pci_write_config
++};
++
++/*
++ * Check Return Code
++ * -> On Failure, print and log information.
++ *    Increment Retry Count, if exceeds max, panic partition.
++ *
++ * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234
++ * PCI: Device 23.90 ReadL Retry( 1)
++ * PCI: Device 23.90 ReadL Retry Successful(1)
++ */
++static int CheckReturnCode(char *TextHdr, struct device_node *DevNode,
++		int *retry, u64 ret)
++{
++	if (ret != 0)  {
++		struct pci_dn *pdn = PCI_DN(DevNode);
++
++		++Pci_Error_Count;
++		(*retry)++;
++		printk("PCI: %s: Device 0x%04X:%02X  I/O Error(%2d): 0x%04X\n",
++				TextHdr, pdn->busno, pdn->devfn,
++				*retry, (int)ret);
++		/*
++		 * Bump the retry and check for retry count exceeded.
++		 * If, Exceeded, panic the system.
++		 */
++		if (((*retry) > Pci_Retry_Max) &&
++				(Pci_Error_Flag > 0)) {
++			mf_display_src(0xB6000103);
++			panic_timeout = 0;
++			panic("PCI: Hardware I/O Error, SRC B6000103, "
++					"Automatic Reboot Disabled.\n");
++		}
++		return -1;	/* Retry Try */
++	}
++	return 0;
++}
++
++/*
++ * Translate the I/O Address into a device node, bar, and bar offset.
++ * Note: Make sure the passed variable end up on the stack to avoid
++ * the exposure of being device global.
++ */
++static inline struct device_node *xlate_iomm_address(
++		const volatile void __iomem *IoAddress,
++		u64 *dsaptr, u64 *BarOffsetPtr)
++{
++	unsigned long OrigIoAddr;
++	unsigned long BaseIoAddr;
++	unsigned long TableIndex;
++	struct device_node *DevNode;
++
++	OrigIoAddr = (unsigned long __force)IoAddress;
++	if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory))
++		return NULL;
++	BaseIoAddr = OrigIoAddr - BASE_IO_MEMORY;
++	TableIndex = BaseIoAddr / IOMM_TABLE_ENTRY_SIZE;
++	DevNode = iomm_table[TableIndex];
++
++	if (DevNode != NULL) {
++		int barnum = iobar_table[TableIndex];
++		*dsaptr = iseries_ds_addr(DevNode) | (barnum << 24);
++		*BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE;
++	} else
++		panic("PCI: Invalid PCI IoAddress detected!\n");
++	return DevNode;
++}
++
++/*
++ * Read MM I/O Instructions for the iSeries
++ * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
++ * else, data is returned in big Endian format.
++ *
++ * iSeries_Read_Byte = Read Byte  ( 8 bit)
++ * iSeries_Read_Word = Read Word  (16 bit)
++ * iSeries_Read_Long = Read Long  (32 bit)
++ */
++u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
++{
++	u64 BarOffset;
++	u64 dsa;
++	int retry = 0;
++	struct HvCallPci_LoadReturn ret;
++	struct device_node *DevNode =
++		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
++
++	if (DevNode == NULL) {
++		static unsigned long last_jiffies;
++		static int num_printed;
++
++		if ((jiffies - last_jiffies) > 60 * HZ) {
++			last_jiffies = jiffies;
++			num_printed = 0;
++		}
++		if (num_printed++ < 10)
++			printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", IoAddress);
++		return 0xff;
++	}
++	do {
++		++Pci_Io_Read_Count;
++		HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
++	} while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0);
++
++	return (u8)ret.value;
++}
++EXPORT_SYMBOL(iSeries_Read_Byte);
++
++u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
++{
++	u64 BarOffset;
++	u64 dsa;
++	int retry = 0;
++	struct HvCallPci_LoadReturn ret;
++	struct device_node *DevNode =
++		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
++
++	if (DevNode == NULL) {
++		static unsigned long last_jiffies;
++		static int num_printed;
++
++		if ((jiffies - last_jiffies) > 60 * HZ) {
++			last_jiffies = jiffies;
++			num_printed = 0;
++		}
++		if (num_printed++ < 10)
++			printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", IoAddress);
++		return 0xffff;
++	}
++	do {
++		++Pci_Io_Read_Count;
++		HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
++				BarOffset, 0);
++	} while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0);
++
++	return swab16((u16)ret.value);
++}
++EXPORT_SYMBOL(iSeries_Read_Word);
++
++u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
++{
++	u64 BarOffset;
++	u64 dsa;
++	int retry = 0;
++	struct HvCallPci_LoadReturn ret;
++	struct device_node *DevNode =
++		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
++
++	if (DevNode == NULL) {
++		static unsigned long last_jiffies;
++		static int num_printed;
++
++		if ((jiffies - last_jiffies) > 60 * HZ) {
++			last_jiffies = jiffies;
++			num_printed = 0;
++		}
++		if (num_printed++ < 10)
++			printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", IoAddress);
++		return 0xffffffff;
++	}
++	do {
++		++Pci_Io_Read_Count;
++		HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
++				BarOffset, 0);
++	} while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0);
++
++	return swab32((u32)ret.value);
++}
++EXPORT_SYMBOL(iSeries_Read_Long);
++
++/*
++ * Write MM I/O Instructions for the iSeries
++ *
++ * iSeries_Write_Byte = Write Byte (8 bit)
++ * iSeries_Write_Word = Write Word(16 bit)
++ * iSeries_Write_Long = Write Long(32 bit)
++ */
++void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
++{
++	u64 BarOffset;
++	u64 dsa;
++	int retry = 0;
++	u64 rc;
++	struct device_node *DevNode =
++		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
++
++	if (DevNode == NULL) {
++		static unsigned long last_jiffies;
++		static int num_printed;
++
++		if ((jiffies - last_jiffies) > 60 * HZ) {
++			last_jiffies = jiffies;
++			num_printed = 0;
++		}
++		if (num_printed++ < 10)
++			printk(KERN_ERR "iSeries_Write_Byte: invalid access at IO address %p\n", IoAddress);
++		return;
++	}
++	do {
++		++Pci_Io_Write_Count;
++		rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
++	} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
++}
++EXPORT_SYMBOL(iSeries_Write_Byte);
++
++void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
++{
++	u64 BarOffset;
++	u64 dsa;
++	int retry = 0;
++	u64 rc;
++	struct device_node *DevNode =
++		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
++
++	if (DevNode == NULL) {
++		static unsigned long last_jiffies;
++		static int num_printed;
++
++		if ((jiffies - last_jiffies) > 60 * HZ) {
++			last_jiffies = jiffies;
++			num_printed = 0;
++		}
++		if (num_printed++ < 10)
++			printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", IoAddress);
++		return;
++	}
++	do {
++		++Pci_Io_Write_Count;
++		rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
++	} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
++}
++EXPORT_SYMBOL(iSeries_Write_Word);
++
++void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
++{
++	u64 BarOffset;
++	u64 dsa;
++	int retry = 0;
++	u64 rc;
++	struct device_node *DevNode =
++		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
++
++	if (DevNode == NULL) {
++		static unsigned long last_jiffies;
++		static int num_printed;
++
++		if ((jiffies - last_jiffies) > 60 * HZ) {
++			last_jiffies = jiffies;
++			num_printed = 0;
++		}
++		if (num_printed++ < 10)
++			printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", IoAddress);
++		return;
++	}
++	do {
++		++Pci_Io_Write_Count;
++		rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
++	} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
++}
++EXPORT_SYMBOL(iSeries_Write_Long);
+diff --git a/arch/powerpc/platforms/iseries/pci.h b/arch/powerpc/platforms/iseries/pci.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/pci.h
+@@ -0,0 +1,63 @@
++#ifndef _PLATFORMS_ISERIES_PCI_H
++#define _PLATFORMS_ISERIES_PCI_H
++
++/*
++ * Created by Allan Trautman on Tue Feb 20, 2001.
++ *
++ * Define some useful macros for the iSeries pci routines.
++ * Copyright (C) 2001  Allan H Trautman, 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
++ *
++ * Change Activity:
++ *   Created Feb 20, 2001
++ *   Added device reset, March 22, 2001
++ *   Ported to ppc64, May 25, 2001
++ * End Change Activity
++ */
++
++#include <asm/pci-bridge.h>
++
++struct pci_dev;				/* For Forward Reference */
++
++/*
++ * Decodes Linux DevFn to iSeries DevFn, bridge device, or function.
++ * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h
++ */
++
++#define ISERIES_PCI_AGENTID(idsel, func)	\
++	(((idsel & 0x0F) << 4) | (func & 0x07))
++#define ISERIES_ENCODE_DEVICE(agentid)		\
++	((0x10) | ((agentid & 0x20) >> 2) | (agentid & 0x07))
++
++#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus)		((subbus >> 5) & 0x7)
++#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)	((subbus >> 2) & 0x7)
++
++/*
++ * Generate a Direct Select Address for the Hypervisor
++ */
++static inline u64 iseries_ds_addr(struct device_node *node)
++{
++	struct pci_dn *pdn = PCI_DN(node);
++
++	return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40)
++			+ ((u64)0x10 << 32);
++}
++
++extern void	iSeries_Device_Information(struct pci_dev*, int);
++
++#endif /* _PLATFORMS_ISERIES_PCI_H */
+diff --git a/arch/powerpc/platforms/iseries/proc.c b/arch/powerpc/platforms/iseries/proc.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/proc.c
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (C) 2001  Kyle A. Lucke IBM Corporation
++ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen 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
++ */
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include <linux/param.h>		/* for HZ */
++#include <asm/paca.h>
++#include <asm/processor.h>
++#include <asm/time.h>
++#include <asm/lppaca.h>
++#include <asm/iSeries/ItLpQueue.h>
++#include <asm/iSeries/HvCallXm.h>
++
++#include "processor_vpd.h"
++#include "main_store.h"
++
++static int __init iseries_proc_create(void)
++{
++	struct proc_dir_entry *e = proc_mkdir("iSeries", 0);
++	if (!e)
++		return 1;
++
++	return 0;
++}
++core_initcall(iseries_proc_create);
++
++static unsigned long startTitan = 0;
++static unsigned long startTb = 0;
++
++static int proc_titantod_show(struct seq_file *m, void *v)
++{
++	unsigned long tb0, titan_tod;
++
++	tb0 = get_tb();
++	titan_tod = HvCallXm_loadTod();
++
++	seq_printf(m, "Titan\n" );
++	seq_printf(m, "  time base =          %016lx\n", tb0);
++	seq_printf(m, "  titan tod =          %016lx\n", titan_tod);
++	seq_printf(m, "  xProcFreq =          %016x\n",
++		   xIoHriProcessorVpd[0].xProcFreq);
++	seq_printf(m, "  xTimeBaseFreq =      %016x\n",
++		   xIoHriProcessorVpd[0].xTimeBaseFreq);
++	seq_printf(m, "  tb_ticks_per_jiffy = %lu\n", tb_ticks_per_jiffy);
++	seq_printf(m, "  tb_ticks_per_usec  = %lu\n", tb_ticks_per_usec);
++
++	if (!startTitan) {
++		startTitan = titan_tod;
++		startTb = tb0;
++	} else {
++		unsigned long titan_usec = (titan_tod - startTitan) >> 12;
++		unsigned long tb_ticks = (tb0 - startTb);
++		unsigned long titan_jiffies = titan_usec / (1000000/HZ);
++		unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ);
++		unsigned long titan_jiff_rem_usec =
++			titan_usec - titan_jiff_usec;
++		unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy;
++		unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy;
++		unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks;
++		unsigned long tb_jiff_rem_usec =
++			tb_jiff_rem_ticks / tb_ticks_per_usec;
++		unsigned long new_tb_ticks_per_jiffy =
++			(tb_ticks * (1000000/HZ))/titan_usec;
++
++		seq_printf(m, "  titan elapsed = %lu uSec\n", titan_usec);
++		seq_printf(m, "  tb elapsed    = %lu ticks\n", tb_ticks);
++		seq_printf(m, "  titan jiffies = %lu.%04lu \n", titan_jiffies,
++			   titan_jiff_rem_usec);
++		seq_printf(m, "  tb jiffies    = %lu.%04lu\n", tb_jiffies,
++			   tb_jiff_rem_usec);
++		seq_printf(m, "  new tb_ticks_per_jiffy = %lu\n",
++			   new_tb_ticks_per_jiffy);
++	}
++
++	return 0;
++}
++
++static int proc_titantod_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, proc_titantod_show, NULL);
++}
++
++static struct file_operations proc_titantod_operations = {
++	.open		= proc_titantod_open,
++	.read		= seq_read,
++	.llseek		= seq_lseek,
++	.release	= single_release,
++};
++
++static int __init iseries_proc_init(void)
++{
++	struct proc_dir_entry *e;
++
++	e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL);
++	if (e)
++		e->proc_fops = &proc_titantod_operations;
++
++	return 0;
++}
++__initcall(iseries_proc_init);
+diff --git a/arch/powerpc/platforms/iseries/processor_vpd.h b/arch/powerpc/platforms/iseries/processor_vpd.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/processor_vpd.h
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (C) 2001  Mike Corrigan 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
++ */
++#ifndef _ISERIES_PROCESSOR_VPD_H
++#define _ISERIES_PROCESSOR_VPD_H
++
++#include <asm/types.h>
++
++/*
++ * This struct maps Processor Vpd that is DMAd to SLIC by CSP
++ */
++struct IoHriProcessorVpd {
++	u8	xFormat;		// VPD format indicator		x00-x00
++	u8	xProcStatus:8;		// Processor State		x01-x01
++	u8	xSecondaryThreadCount;	// Secondary thread cnt		x02-x02
++	u8	xSrcType:1;		// Src Type			x03-x03
++	u8	xSrcSoft:1;		// Src stay soft		...
++	u8	xSrcParable:1;		// Src parable			...
++	u8	xRsvd1:5;		// Reserved			...
++	u16	xHvPhysicalProcIndex;	// Hypervisor physical proc index04-x05
++	u16	xRsvd2;			// Reserved			x06-x07
++	u32	xHwNodeId;		// Hardware node id		x08-x0B
++	u32	xHwProcId;		// Hardware processor id	x0C-x0F
++
++	u32	xTypeNum;		// Card Type/CCIN number	x10-x13
++	u32	xModelNum;		// Model/Feature number		x14-x17
++	u64	xSerialNum;		// Serial number		x18-x1F
++	char	xPartNum[12];		// Book Part or FPU number	x20-x2B
++	char	xMfgID[4];		// Manufacturing ID		x2C-x2F
++
++	u32	xProcFreq;		// Processor Frequency		x30-x33
++	u32	xTimeBaseFreq;		// Time Base Frequency		x34-x37
++
++	u32	xChipEcLevel;		// Chip EC Levels		x38-x3B
++	u32	xProcIdReg;		// PIR SPR value		x3C-x3F
++	u32	xPVR;			// PVR value			x40-x43
++	u8	xRsvd3[12];		// Reserved			x44-x4F
++
++	u32	xInstCacheSize;		// Instruction cache size in KB	x50-x53
++	u32	xInstBlockSize;		// Instruction cache block size	x54-x57
++	u32	xDataCacheOperandSize;	// Data cache operand size	x58-x5B
++	u32	xInstCacheOperandSize;	// Inst cache operand size	x5C-x5F
++
++	u32	xDataL1CacheSizeKB;	// L1 data cache size in KB	x60-x63
++	u32	xDataL1CacheLineSize;	// L1 data cache block size	x64-x67
++	u64	xRsvd4;			// Reserved			x68-x6F
++
++	u32	xDataL2CacheSizeKB;	// L2 data cache size in KB	x70-x73
++	u32	xDataL2CacheLineSize;	// L2 data cache block size	x74-x77
++	u64	xRsvd5;			// Reserved			x78-x7F
++
++	u32	xDataL3CacheSizeKB;	// L3 data cache size in KB	x80-x83
++	u32	xDataL3CacheLineSize;	// L3 data cache block size	x84-x87
++	u64	xRsvd6;			// Reserved			x88-x8F
++
++	u64	xFruLabel;		// Card Location Label		x90-x97
++	u8	xSlotsOnCard;		// Slots on card (0=no slots)	x98-x98
++	u8	xPartLocFlag;		// Location flag (0-pluggable 1-imbedded) x99-x99
++	u16	xSlotMapIndex;		// Index in slot map table	x9A-x9B
++	u8	xSmartCardPortNo;	// Smart card port number	x9C-x9C
++	u8	xRsvd7;			// Reserved			x9D-x9D
++	u16	xFrameIdAndRackUnit;	// Frame ID and rack unit adr	x9E-x9F
++
++	u8	xRsvd8[24];		// Reserved			xA0-xB7
++
++	char	xProcSrc[72];		// CSP format SRC		xB8-xFF
++};
++
++extern struct IoHriProcessorVpd	xIoHriProcessorVpd[];
++
++#endif /* _ISERIES_PROCESSOR_VPD_H */
+diff --git a/arch/powerpc/platforms/iseries/release_data.h b/arch/powerpc/platforms/iseries/release_data.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/release_data.h
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (C) 2001  Mike Corrigan 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
++ */
++#ifndef _ISERIES_RELEASE_DATA_H
++#define _ISERIES_RELEASE_DATA_H
++
++/*
++ * This control block contains the critical information about the
++ * release so that it can be changed in the future (ie, the virtual
++ * address of the OS's NACA).
++ */
++#include <asm/types.h>
++#include <asm/naca.h>
++
++/*
++ * When we IPL a secondary partition, we will check if if the
++ * secondary xMinPlicVrmIndex > the primary xVrmIndex.
++ * If it is then this tells PLIC that this secondary is not
++ * supported running on this "old" of a level of PLIC.
++ *
++ * Likewise, we will compare the primary xMinSlicVrmIndex to
++ * the secondary xVrmIndex.
++ * If the primary xMinSlicVrmDelta > secondary xVrmDelta then we
++ * know that this PLIC does not support running an OS "that old".
++ */
++
++#define	HVREL_TAGSINACTIVE	0x8000
++#define HVREL_32BIT		0x4000
++#define HVREL_NOSHAREDPROCS	0x2000
++#define HVREL_NOHMT		0x1000
++
++struct HvReleaseData {
++	u32	xDesc;		/* Descriptor "HvRD" ebcdic	x00-x03 */
++	u16	xSize;		/* Size of this control block	x04-x05 */
++	u16	xVpdAreasPtrOffset; /* Offset in NACA of ItVpdAreas x06-x07 */
++	struct  naca_struct	*xSlicNacaAddr; /* Virt addr of SLIC NACA x08-x0F */
++	u32	xMsNucDataOffset; /* Offset of Linux Mapping Data x10-x13 */
++	u32	xRsvd1;		/* Reserved			x14-x17 */
++	u16	xFlags;
++	u16	xVrmIndex;	/* VRM Index of OS image	x1A-x1B */
++	u16	xMinSupportedPlicVrmIndex; /* Min PLIC level  (soft) x1C-x1D */
++	u16	xMinCompatablePlicVrmIndex; /* Min PLIC levelP (hard) x1E-x1F */
++	char	xVrmName[12];	/* Displayable name		x20-x2B */
++	char	xRsvd3[20];	/* Reserved			x2C-x3F */
++};
++
++extern struct HvReleaseData	hvReleaseData;
++
++#endif /* _ISERIES_RELEASE_DATA_H */
+diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/setup.c
+@@ -0,0 +1,996 @@
++/*
++ *    Copyright (c) 2000 Mike Corrigan <mikejc at us.ibm.com>
++ *    Copyright (c) 1999-2000 Grant Erickson <grant at lcse.umn.edu>
++ *
++ *    Description:
++ *      Architecture- / platform-specific boot-time initialization code for
++ *      the IBM iSeries LPAR.  Adapted from original code by Grant Erickson and
++ *      code by Gary Thomas, Cort Dougan <cort at fsmlabs.com>, and Dan Malek
++ *      <dan at net4x.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.
++ */
++
++#undef DEBUG
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/threads.h>
++#include <linux/smp.h>
++#include <linux/param.h>
++#include <linux/string.h>
++#include <linux/initrd.h>
++#include <linux/seq_file.h>
++#include <linux/kdev_t.h>
++#include <linux/major.h>
++#include <linux/root_dev.h>
++
++#include <asm/processor.h>
++#include <asm/machdep.h>
++#include <asm/page.h>
++#include <asm/mmu.h>
++#include <asm/pgtable.h>
++#include <asm/mmu_context.h>
++#include <asm/cputable.h>
++#include <asm/sections.h>
++#include <asm/iommu.h>
++#include <asm/firmware.h>
++
++#include <asm/time.h>
++#include <asm/naca.h>
++#include <asm/paca.h>
++#include <asm/cache.h>
++#include <asm/sections.h>
++#include <asm/abs_addr.h>
++#include <asm/iSeries/HvLpConfig.h>
++#include <asm/iSeries/HvCallEvent.h>
++#include <asm/iSeries/HvCallXm.h>
++#include <asm/iSeries/ItLpQueue.h>
++#include <asm/iSeries/mf.h>
++#include <asm/iSeries/HvLpEvent.h>
++#include <asm/iSeries/LparMap.h>
++
++#include "setup.h"
++#include "irq.h"
++#include "vpd_areas.h"
++#include "processor_vpd.h"
++#include "main_store.h"
++#include "call_sm.h"
++#include "call_hpt.h"
++
++extern void hvlog(char *fmt, ...);
++
++#ifdef DEBUG
++#define DBG(fmt...) hvlog(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++/* Function Prototypes */
++extern void ppcdbg_initialize(void);
++
++static void build_iSeries_Memory_Map(void);
++static void iseries_shared_idle(void);
++static void iseries_dedicated_idle(void);
++#ifdef CONFIG_PCI
++extern void iSeries_pci_final_fixup(void);
++#else
++static void iSeries_pci_final_fixup(void) { }
++#endif
++
++/* Global Variables */
++int piranha_simulator;
++
++extern int rd_size;		/* Defined in drivers/block/rd.c */
++extern unsigned long klimit;
++extern unsigned long embedded_sysmap_start;
++extern unsigned long embedded_sysmap_end;
++
++extern unsigned long iSeries_recal_tb;
++extern unsigned long iSeries_recal_titan;
++
++static int mf_initialized;
++
++struct MemoryBlock {
++	unsigned long absStart;
++	unsigned long absEnd;
++	unsigned long logicalStart;
++	unsigned long logicalEnd;
++};
++
++/*
++ * Process the main store vpd to determine where the holes in memory are
++ * and return the number of physical blocks and fill in the array of
++ * block data.
++ */
++static unsigned long iSeries_process_Condor_mainstore_vpd(
++		struct MemoryBlock *mb_array, unsigned long max_entries)
++{
++	unsigned long holeFirstChunk, holeSizeChunks;
++	unsigned long numMemoryBlocks = 1;
++	struct IoHriMainStoreSegment4 *msVpd =
++		(struct IoHriMainStoreSegment4 *)xMsVpd;
++	unsigned long holeStart = msVpd->nonInterleavedBlocksStartAdr;
++	unsigned long holeEnd = msVpd->nonInterleavedBlocksEndAdr;
++	unsigned long holeSize = holeEnd - holeStart;
++
++	printk("Mainstore_VPD: Condor\n");
++	/*
++	 * Determine if absolute memory has any
++	 * holes so that we can interpret the
++	 * access map we get back from the hypervisor
++	 * correctly.
++	 */
++	mb_array[0].logicalStart = 0;
++	mb_array[0].logicalEnd = 0x100000000;
++	mb_array[0].absStart = 0;
++	mb_array[0].absEnd = 0x100000000;
++
++	if (holeSize) {
++		numMemoryBlocks = 2;
++		holeStart = holeStart & 0x000fffffffffffff;
++		holeStart = addr_to_chunk(holeStart);
++		holeFirstChunk = holeStart;
++		holeSize = addr_to_chunk(holeSize);
++		holeSizeChunks = holeSize;
++		printk( "Main store hole: start chunk = %0lx, size = %0lx chunks\n",
++				holeFirstChunk, holeSizeChunks );
++		mb_array[0].logicalEnd = holeFirstChunk;
++		mb_array[0].absEnd = holeFirstChunk;
++		mb_array[1].logicalStart = holeFirstChunk;
++		mb_array[1].logicalEnd = 0x100000000 - holeSizeChunks;
++		mb_array[1].absStart = holeFirstChunk + holeSizeChunks;
++		mb_array[1].absEnd = 0x100000000;
++	}
++	return numMemoryBlocks;
++}
++
++#define MaxSegmentAreas			32
++#define MaxSegmentAdrRangeBlocks	128
++#define MaxAreaRangeBlocks		4
++
++static unsigned long iSeries_process_Regatta_mainstore_vpd(
++		struct MemoryBlock *mb_array, unsigned long max_entries)
++{
++	struct IoHriMainStoreSegment5 *msVpdP =
++		(struct IoHriMainStoreSegment5 *)xMsVpd;
++	unsigned long numSegmentBlocks = 0;
++	u32 existsBits = msVpdP->msAreaExists;
++	unsigned long area_num;
++
++	printk("Mainstore_VPD: Regatta\n");
++
++	for (area_num = 0; area_num < MaxSegmentAreas; ++area_num ) {
++		unsigned long numAreaBlocks;
++		struct IoHriMainStoreArea4 *currentArea;
++
++		if (existsBits & 0x80000000) {
++			unsigned long block_num;
++
++			currentArea = &msVpdP->msAreaArray[area_num];
++			numAreaBlocks = currentArea->numAdrRangeBlocks;
++			printk("ms_vpd: processing area %2ld  blocks=%ld",
++					area_num, numAreaBlocks);
++			for (block_num = 0; block_num < numAreaBlocks;
++					++block_num ) {
++				/* Process an address range block */
++				struct MemoryBlock tempBlock;
++				unsigned long i;
++
++				tempBlock.absStart =
++					(unsigned long)currentArea->xAdrRangeBlock[block_num].blockStart;
++				tempBlock.absEnd =
++					(unsigned long)currentArea->xAdrRangeBlock[block_num].blockEnd;
++				tempBlock.logicalStart = 0;
++				tempBlock.logicalEnd   = 0;
++				printk("\n          block %ld absStart=%016lx absEnd=%016lx",
++						block_num, tempBlock.absStart,
++						tempBlock.absEnd);
++
++				for (i = 0; i < numSegmentBlocks; ++i) {
++					if (mb_array[i].absStart ==
++							tempBlock.absStart)
++						break;
++				}
++				if (i == numSegmentBlocks) {
++					if (numSegmentBlocks == max_entries)
++						panic("iSeries_process_mainstore_vpd: too many memory blocks");
++					mb_array[numSegmentBlocks] = tempBlock;
++					++numSegmentBlocks;
++				} else
++					printk(" (duplicate)");
++			}
++			printk("\n");
++		}
++		existsBits <<= 1;
++	}
++	/* Now sort the blocks found into ascending sequence */
++	if (numSegmentBlocks > 1) {
++		unsigned long m, n;
++
++		for (m = 0; m < numSegmentBlocks - 1; ++m) {
++			for (n = numSegmentBlocks - 1; m < n; --n) {
++				if (mb_array[n].absStart <
++						mb_array[n-1].absStart) {
++					struct MemoryBlock tempBlock;
++
++					tempBlock = mb_array[n];
++					mb_array[n] = mb_array[n-1];
++					mb_array[n-1] = tempBlock;
++				}
++			}
++		}
++	}
++	/*
++	 * Assign "logical" addresses to each block.  These
++	 * addresses correspond to the hypervisor "bitmap" space.
++	 * Convert all addresses into units of 256K chunks.
++	 */
++	{
++	unsigned long i, nextBitmapAddress;
++
++	printk("ms_vpd: %ld sorted memory blocks\n", numSegmentBlocks);
++	nextBitmapAddress = 0;
++	for (i = 0; i < numSegmentBlocks; ++i) {
++		unsigned long length = mb_array[i].absEnd -
++			mb_array[i].absStart;
++
++		mb_array[i].logicalStart = nextBitmapAddress;
++		mb_array[i].logicalEnd = nextBitmapAddress + length;
++		nextBitmapAddress += length;
++		printk("          Bitmap range: %016lx - %016lx\n"
++				"        Absolute range: %016lx - %016lx\n",
++				mb_array[i].logicalStart,
++				mb_array[i].logicalEnd,
++				mb_array[i].absStart, mb_array[i].absEnd);
++		mb_array[i].absStart = addr_to_chunk(mb_array[i].absStart &
++				0x000fffffffffffff);
++		mb_array[i].absEnd = addr_to_chunk(mb_array[i].absEnd &
++				0x000fffffffffffff);
++		mb_array[i].logicalStart =
++			addr_to_chunk(mb_array[i].logicalStart);
++		mb_array[i].logicalEnd = addr_to_chunk(mb_array[i].logicalEnd);
++	}
++	}
++
++	return numSegmentBlocks;
++}
++
++static unsigned long iSeries_process_mainstore_vpd(struct MemoryBlock *mb_array,
++		unsigned long max_entries)
++{
++	unsigned long i;
++	unsigned long mem_blocks = 0;
++
++	if (cpu_has_feature(CPU_FTR_SLB))
++		mem_blocks = iSeries_process_Regatta_mainstore_vpd(mb_array,
++				max_entries);
++	else
++		mem_blocks = iSeries_process_Condor_mainstore_vpd(mb_array,
++				max_entries);
++
++	printk("Mainstore_VPD: numMemoryBlocks = %ld \n", mem_blocks);
++	for (i = 0; i < mem_blocks; ++i) {
++		printk("Mainstore_VPD: block %3ld logical chunks %016lx - %016lx\n"
++		       "                             abs chunks %016lx - %016lx\n",
++			i, mb_array[i].logicalStart, mb_array[i].logicalEnd,
++			mb_array[i].absStart, mb_array[i].absEnd);
++	}
++	return mem_blocks;
++}
++
++static void __init iSeries_get_cmdline(void)
++{
++	char *p, *q;
++
++	/* copy the command line parameter from the primary VSP  */
++	HvCallEvent_dmaToSp(cmd_line, 2 * 64* 1024, 256,
++			HvLpDma_Direction_RemoteToLocal);
++
++	p = cmd_line;
++	q = cmd_line + 255;
++	while(p < q) {
++		if (!*p || *p == '\n')
++			break;
++		++p;
++	}
++	*p = 0;
++}
++
++static void __init iSeries_init_early(void)
++{
++	DBG(" -> iSeries_init_early()\n");
++
++	ppc64_firmware_features = FW_FEATURE_ISERIES;
++
++	ppcdbg_initialize();
++
++	ppc64_interrupt_controller = IC_ISERIES;
++
++#if defined(CONFIG_BLK_DEV_INITRD)
++	/*
++	 * If the init RAM disk has been configured and there is
++	 * a non-zero starting address for it, set it up
++	 */
++	if (naca.xRamDisk) {
++		initrd_start = (unsigned long)__va(naca.xRamDisk);
++		initrd_end = initrd_start + naca.xRamDiskSize * PAGE_SIZE;
++		initrd_below_start_ok = 1;	// ramdisk in kernel space
++		ROOT_DEV = Root_RAM0;
++		if (((rd_size * 1024) / PAGE_SIZE) < naca.xRamDiskSize)
++			rd_size = (naca.xRamDiskSize * PAGE_SIZE) / 1024;
++	} else
++#endif /* CONFIG_BLK_DEV_INITRD */
++	{
++	    /* ROOT_DEV = MKDEV(VIODASD_MAJOR, 1); */
++	}
++
++	iSeries_recal_tb = get_tb();
++	iSeries_recal_titan = HvCallXm_loadTod();
++
++	/*
++	 * Initialize the hash table management pointers
++	 */
++	hpte_init_iSeries();
++
++	/*
++	 * Initialize the DMA/TCE management
++	 */
++	iommu_init_early_iSeries();
++
++	iSeries_get_cmdline();
++
++	/* Save unparsed command line copy for /proc/cmdline */
++	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
++
++	/* Parse early parameters, in particular mem=x */
++	parse_early_param();
++
++	if (memory_limit) {
++		if (memory_limit < systemcfg->physicalMemorySize)
++			systemcfg->physicalMemorySize = memory_limit;
++		else {
++			printk("Ignoring mem=%lu >= ram_top.\n", memory_limit);
++			memory_limit = 0;
++		}
++	}
++
++	/* Initialize machine-dependency vectors */
++#ifdef CONFIG_SMP
++	smp_init_iSeries();
++#endif
++	if (itLpNaca.xPirEnvironMode == 0)
++		piranha_simulator = 1;
++
++	/* Associate Lp Event Queue 0 with processor 0 */
++	HvCallEvent_setLpEventQueueInterruptProc(0, 0);
++
++	mf_init();
++	mf_initialized = 1;
++	mb();
++
++	/* If we were passed an initrd, set the ROOT_DEV properly if the values
++	 * look sensible. If not, clear initrd reference.
++	 */
++#ifdef CONFIG_BLK_DEV_INITRD
++	if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
++	    initrd_end > initrd_start)
++		ROOT_DEV = Root_RAM0;
++	else
++		initrd_start = initrd_end = 0;
++#endif /* CONFIG_BLK_DEV_INITRD */
++
++	DBG(" <- iSeries_init_early()\n");
++}
++
++struct mschunks_map mschunks_map = {
++	/* XXX We don't use these, but Piranha might need them. */
++	.chunk_size  = MSCHUNKS_CHUNK_SIZE,
++	.chunk_shift = MSCHUNKS_CHUNK_SHIFT,
++	.chunk_mask  = MSCHUNKS_OFFSET_MASK,
++};
++EXPORT_SYMBOL(mschunks_map);
++
++void mschunks_alloc(unsigned long num_chunks)
++{
++	klimit = _ALIGN(klimit, sizeof(u32));
++	mschunks_map.mapping = (u32 *)klimit;
++	klimit += num_chunks * sizeof(u32);
++	mschunks_map.num_chunks = num_chunks;
++}
++
++/*
++ * The iSeries may have very large memories ( > 128 GB ) and a partition
++ * may get memory in "chunks" that may be anywhere in the 2**52 real
++ * address space.  The chunks are 256K in size.  To map this to the
++ * memory model Linux expects, the AS/400 specific code builds a
++ * translation table to translate what Linux thinks are "physical"
++ * addresses to the actual real addresses.  This allows us to make
++ * it appear to Linux that we have contiguous memory starting at
++ * physical address zero while in fact this could be far from the truth.
++ * To avoid confusion, I'll let the words physical and/or real address
++ * apply to the Linux addresses while I'll use "absolute address" to
++ * refer to the actual hardware real address.
++ *
++ * build_iSeries_Memory_Map gets information from the Hypervisor and
++ * looks at the Main Store VPD to determine the absolute addresses
++ * of the memory that has been assigned to our partition and builds
++ * a table used to translate Linux's physical addresses to these
++ * absolute addresses.  Absolute addresses are needed when
++ * communicating with the hypervisor (e.g. to build HPT entries)
++ */
++
++static void __init build_iSeries_Memory_Map(void)
++{
++	u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize;
++	u32 nextPhysChunk;
++	u32 hptFirstChunk, hptLastChunk, hptSizeChunks, hptSizePages;
++	u32 totalChunks,moreChunks;
++	u32 currChunk, thisChunk, absChunk;
++	u32 currDword;
++	u32 chunkBit;
++	u64 map;
++	struct MemoryBlock mb[32];
++	unsigned long numMemoryBlocks, curBlock;
++
++	/* Chunk size on iSeries is 256K bytes */
++	totalChunks = (u32)HvLpConfig_getMsChunks();
++	mschunks_alloc(totalChunks);
++
++	/*
++	 * Get absolute address of our load area
++	 * and map it to physical address 0
++	 * This guarantees that the loadarea ends up at physical 0
++	 * otherwise, it might not be returned by PLIC as the first
++	 * chunks
++	 */
++
++	loadAreaFirstChunk = (u32)addr_to_chunk(itLpNaca.xLoadAreaAddr);
++	loadAreaSize =  itLpNaca.xLoadAreaChunks;
++
++	/*
++	 * Only add the pages already mapped here.
++	 * Otherwise we might add the hpt pages
++	 * The rest of the pages of the load area
++	 * aren't in the HPT yet and can still
++	 * be assigned an arbitrary physical address
++	 */
++	if ((loadAreaSize * 64) > HvPagesToMap)
++		loadAreaSize = HvPagesToMap / 64;
++
++	loadAreaLastChunk = loadAreaFirstChunk + loadAreaSize - 1;
++
++	/*
++	 * TODO Do we need to do something if the HPT is in the 64MB load area?
++	 * This would be required if the itLpNaca.xLoadAreaChunks includes
++	 * the HPT size
++	 */
++
++	printk("Mapping load area - physical addr = 0000000000000000\n"
++		"                    absolute addr = %016lx\n",
++		chunk_to_addr(loadAreaFirstChunk));
++	printk("Load area size %dK\n", loadAreaSize * 256);
++
++	for (nextPhysChunk = 0; nextPhysChunk < loadAreaSize; ++nextPhysChunk)
++		mschunks_map.mapping[nextPhysChunk] =
++			loadAreaFirstChunk + nextPhysChunk;
++
++	/*
++	 * Get absolute address of our HPT and remember it so
++	 * we won't map it to any physical address
++	 */
++	hptFirstChunk = (u32)addr_to_chunk(HvCallHpt_getHptAddress());
++	hptSizePages = (u32)HvCallHpt_getHptPages();
++	hptSizeChunks = hptSizePages >> (MSCHUNKS_CHUNK_SHIFT - PAGE_SHIFT);
++	hptLastChunk = hptFirstChunk + hptSizeChunks - 1;
++
++	printk("HPT absolute addr = %016lx, size = %dK\n",
++			chunk_to_addr(hptFirstChunk), hptSizeChunks * 256);
++
++	ppc64_pft_size = __ilog2(hptSizePages * PAGE_SIZE);
++
++	/*
++	 * The actual hashed page table is in the hypervisor,
++	 * we have no direct access
++	 */
++	htab_address = NULL;
++
++	/*
++	 * Determine if absolute memory has any
++	 * holes so that we can interpret the
++	 * access map we get back from the hypervisor
++	 * correctly.
++	 */
++	numMemoryBlocks = iSeries_process_mainstore_vpd(mb, 32);
++
++	/*
++	 * Process the main store access map from the hypervisor
++	 * to build up our physical -> absolute translation table
++	 */
++	curBlock = 0;
++	currChunk = 0;
++	currDword = 0;
++	moreChunks = totalChunks;
++
++	while (moreChunks) {
++		map = HvCallSm_get64BitsOfAccessMap(itLpNaca.xLpIndex,
++				currDword);
++		thisChunk = currChunk;
++		while (map) {
++			chunkBit = map >> 63;
++			map <<= 1;
++			if (chunkBit) {
++				--moreChunks;
++				while (thisChunk >= mb[curBlock].logicalEnd) {
++					++curBlock;
++					if (curBlock >= numMemoryBlocks)
++						panic("out of memory blocks");
++				}
++				if (thisChunk < mb[curBlock].logicalStart)
++					panic("memory block error");
++
++				absChunk = mb[curBlock].absStart +
++					(thisChunk - mb[curBlock].logicalStart);
++				if (((absChunk < hptFirstChunk) ||
++				     (absChunk > hptLastChunk)) &&
++				    ((absChunk < loadAreaFirstChunk) ||
++				     (absChunk > loadAreaLastChunk))) {
++					mschunks_map.mapping[nextPhysChunk] =
++						absChunk;
++					++nextPhysChunk;
++				}
++			}
++			++thisChunk;
++		}
++		++currDword;
++		currChunk += 64;
++	}
++
++	/*
++	 * main store size (in chunks) is
++	 *   totalChunks - hptSizeChunks
++	 * which should be equal to
++	 *   nextPhysChunk
++	 */
++	systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk);
++}
++
++/*
++ * Document me.
++ */
++static void __init iSeries_setup_arch(void)
++{
++	unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
++
++	if (get_paca()->lppaca.shared_proc) {
++		ppc_md.idle_loop = iseries_shared_idle;
++		printk(KERN_INFO "Using shared processor idle loop\n");
++	} else {
++		ppc_md.idle_loop = iseries_dedicated_idle;
++		printk(KERN_INFO "Using dedicated idle loop\n");
++	}
++
++	/* Setup the Lp Event Queue */
++	setup_hvlpevent_queue();
++
++	printk("Max  logical processors = %d\n",
++			itVpdAreas.xSlicMaxLogicalProcs);
++	printk("Max physical processors = %d\n",
++			itVpdAreas.xSlicMaxPhysicalProcs);
++
++	systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
++	printk("Processor version = %x\n", systemcfg->processor);
++}
++
++static void iSeries_show_cpuinfo(struct seq_file *m)
++{
++	seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n");
++}
++
++/*
++ * Document me.
++ * and Implement me.
++ */
++static int iSeries_get_irq(struct pt_regs *regs)
++{
++	/* -2 means ignore this interrupt */
++	return -2;
++}
++
++/*
++ * Document me.
++ */
++static void iSeries_restart(char *cmd)
++{
++	mf_reboot();
++}
++
++/*
++ * Document me.
++ */
++static void iSeries_power_off(void)
++{
++	mf_power_off();
++}
++
++/*
++ * Document me.
++ */
++static void iSeries_halt(void)
++{
++	mf_power_off();
++}
++
++static void __init iSeries_progress(char * st, unsigned short code)
++{
++	printk("Progress: [%04x] - %s\n", (unsigned)code, st);
++	if (!piranha_simulator && mf_initialized) {
++		if (code != 0xffff)
++			mf_display_progress(code);
++		else
++			mf_clear_src();
++	}
++}
++
++static void __init iSeries_fixup_klimit(void)
++{
++	/*
++	 * Change klimit to take into account any ram disk
++	 * that may be included
++	 */
++	if (naca.xRamDisk)
++		klimit = KERNELBASE + (u64)naca.xRamDisk +
++			(naca.xRamDiskSize * PAGE_SIZE);
++	else {
++		/*
++		 * No ram disk was included - check and see if there
++		 * was an embedded system map.  Change klimit to take
++		 * into account any embedded system map
++		 */
++		if (embedded_sysmap_end)
++			klimit = KERNELBASE + ((embedded_sysmap_end + 4095) &
++					0xfffffffffffff000);
++	}
++}
++
++static int __init iSeries_src_init(void)
++{
++        /* clear the progress line */
++        ppc_md.progress(" ", 0xffff);
++        return 0;
++}
++
++late_initcall(iSeries_src_init);
++
++static inline void process_iSeries_events(void)
++{
++	asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
++}
++
++static void yield_shared_processor(void)
++{
++	unsigned long tb;
++
++	HvCall_setEnabledInterrupts(HvCall_MaskIPI |
++				    HvCall_MaskLpEvent |
++				    HvCall_MaskLpProd |
++				    HvCall_MaskTimeout);
++
++	tb = get_tb();
++	/* Compute future tb value when yield should expire */
++	HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
++
++	/*
++	 * The decrementer stops during the yield.  Force a fake decrementer
++	 * here and let the timer_interrupt code sort out the actual time.
++	 */
++	get_paca()->lppaca.int_dword.fields.decr_int = 1;
++	process_iSeries_events();
++}
++
++static void iseries_shared_idle(void)
++{
++	while (1) {
++		while (!need_resched() && !hvlpevent_is_pending()) {
++			local_irq_disable();
++			ppc64_runlatch_off();
++
++			/* Recheck with irqs off */
++			if (!need_resched() && !hvlpevent_is_pending())
++				yield_shared_processor();
++
++			HMT_medium();
++			local_irq_enable();
++		}
++
++		ppc64_runlatch_on();
++
++		if (hvlpevent_is_pending())
++			process_iSeries_events();
++
++		schedule();
++	}
++}
++
++static void iseries_dedicated_idle(void)
++{
++	long oldval;
++
++	while (1) {
++		oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
++
++		if (!oldval) {
++			set_thread_flag(TIF_POLLING_NRFLAG);
++
++			while (!need_resched()) {
++				ppc64_runlatch_off();
++				HMT_low();
++
++				if (hvlpevent_is_pending()) {
++					HMT_medium();
++					ppc64_runlatch_on();
++					process_iSeries_events();
++				}
++			}
++
++			HMT_medium();
++			clear_thread_flag(TIF_POLLING_NRFLAG);
++		} else {
++			set_need_resched();
++		}
++
++		ppc64_runlatch_on();
++		schedule();
++	}
++}
++
++#ifndef CONFIG_PCI
++void __init iSeries_init_IRQ(void) { }
++#endif
++
++static int __init iseries_probe(int platform)
++{
++	return PLATFORM_ISERIES_LPAR == platform;
++}
++
++struct machdep_calls __initdata iseries_md = {
++	.setup_arch	= iSeries_setup_arch,
++	.show_cpuinfo	= iSeries_show_cpuinfo,
++	.init_IRQ	= iSeries_init_IRQ,
++	.get_irq	= iSeries_get_irq,
++	.init_early	= iSeries_init_early,
++	.pcibios_fixup	= iSeries_pci_final_fixup,
++	.restart	= iSeries_restart,
++	.power_off	= iSeries_power_off,
++	.halt		= iSeries_halt,
++	.get_boot_time	= iSeries_get_boot_time,
++	.set_rtc_time	= iSeries_set_rtc_time,
++	.get_rtc_time	= iSeries_get_rtc_time,
++	.calibrate_decr	= generic_calibrate_decr,
++	.progress	= iSeries_progress,
++	.probe		= iseries_probe,
++	/* XXX Implement enable_pmcs for iSeries */
++};
++
++struct blob {
++	unsigned char data[PAGE_SIZE];
++	unsigned long next;
++};
++
++struct iseries_flat_dt {
++	struct boot_param_header header;
++	u64 reserve_map[2];
++	struct blob dt;
++	struct blob strings;
++};
++
++struct iseries_flat_dt iseries_dt;
++
++void dt_init(struct iseries_flat_dt *dt)
++{
++	dt->header.off_mem_rsvmap =
++		offsetof(struct iseries_flat_dt, reserve_map);
++	dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt);
++	dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings);
++	dt->header.totalsize = sizeof(struct iseries_flat_dt);
++	dt->header.dt_strings_size = sizeof(struct blob);
++
++	/* There is no notion of hardware cpu id on iSeries */
++	dt->header.boot_cpuid_phys = smp_processor_id();
++
++	dt->dt.next = (unsigned long)&dt->dt.data;
++	dt->strings.next = (unsigned long)&dt->strings.data;
++
++	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;
++}
++
++void dt_check_blob(struct blob *b)
++{
++	if (b->next >= (unsigned long)&b->next) {
++		DBG("Ran out of space in flat device tree blob!\n");
++		BUG();
++	}
++}
++
++void dt_push_u32(struct iseries_flat_dt *dt, u32 value)
++{
++	*((u32*)dt->dt.next) = value;
++	dt->dt.next += sizeof(u32);
++
++	dt_check_blob(&dt->dt);
++}
++
++void dt_push_u64(struct iseries_flat_dt *dt, u64 value)
++{
++	*((u64*)dt->dt.next) = value;
++	dt->dt.next += sizeof(u64);
++
++	dt_check_blob(&dt->dt);
++}
++
++unsigned long dt_push_bytes(struct blob *blob, char *data, int len)
++{
++	unsigned long start = blob->next - (unsigned long)blob->data;
++
++	memcpy((char *)blob->next, data, len);
++	blob->next = _ALIGN(blob->next + len, 4);
++
++	dt_check_blob(blob);
++
++	return start;
++}
++
++void dt_start_node(struct iseries_flat_dt *dt, char *name)
++{
++	dt_push_u32(dt, OF_DT_BEGIN_NODE);
++	dt_push_bytes(&dt->dt, name, strlen(name) + 1);
++}
++
++#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
++
++void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len)
++{
++	unsigned long offset;
++
++	dt_push_u32(dt, OF_DT_PROP);
++
++	/* Length of the data */
++	dt_push_u32(dt, len);
++
++	/* Put the property name in the string blob. */
++	offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1);
++
++	/* The offset of the properties name in the string blob. */
++	dt_push_u32(dt, (u32)offset);
++
++	/* The actual data. */
++	dt_push_bytes(&dt->dt, data, len);
++}
++
++void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data)
++{
++	dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */
++}
++
++void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data)
++{
++	dt_prop(dt, name, (char *)&data, sizeof(u32));
++}
++
++void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data)
++{
++	dt_prop(dt, name, (char *)&data, sizeof(u64));
++}
++
++void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n)
++{
++	dt_prop(dt, name, (char *)data, sizeof(u64) * n);
++}
++
++void dt_prop_empty(struct iseries_flat_dt *dt, char *name)
++{
++	dt_prop(dt, name, NULL, 0);
++}
++
++void dt_cpus(struct iseries_flat_dt *dt)
++{
++	unsigned char buf[32];
++	unsigned char *p;
++	unsigned int i, index;
++	struct IoHriProcessorVpd *d;
++
++	/* 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);
++
++	for (i = 0; i < NR_CPUS; i++) {
++		if (paca[i].lppaca.dyn_proc_status >= 2)
++			continue;
++
++		snprintf(p, 32 - (p - buf), "@%d", i);
++		dt_start_node(dt, buf);
++
++		dt_prop_str(dt, "device_type", "cpu");
++
++		index = paca[i].lppaca.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_end_node(dt);
++	}
++
++	dt_end_node(dt);
++}
++
++void build_flat_dt(struct iseries_flat_dt *dt)
++{
++	u64 tmp[2];
++
++	dt_init(dt);
++
++	dt_start_node(dt, "");
++
++	dt_prop_u32(dt, "#address-cells", 2);
++	dt_prop_u32(dt, "#size-cells", 2);
++
++	/* /memory */
++	dt_start_node(dt, "memory at 0");
++	dt_prop_str(dt, "name", "memory");
++	dt_prop_str(dt, "device_type", "memory");
++	tmp[0] = 0;
++	tmp[1] = systemcfg->physicalMemorySize;
++	dt_prop_u64_list(dt, "reg", tmp, 2);
++	dt_end_node(dt);
++
++	/* /chosen */
++	dt_start_node(dt, "chosen");
++	dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
++	dt_end_node(dt);
++
++	dt_cpus(dt);
++
++	dt_end_node(dt);
++
++	dt_push_u32(dt, OF_DT_END);
++}
++
++void * __init iSeries_early_setup(void)
++{
++	iSeries_fixup_klimit();
++
++	/*
++	 * Initialize the table which translate Linux physical addresses to
++	 * AS/400 absolute addresses
++	 */
++	build_iSeries_Memory_Map();
++
++	build_flat_dt(&iseries_dt);
++
++	return (void *) __pa(&iseries_dt);
++}
+diff --git a/arch/powerpc/platforms/iseries/setup.h b/arch/powerpc/platforms/iseries/setup.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/setup.h
+@@ -0,0 +1,24 @@
++/*
++ *    Copyright (c) 2000 Mike Corrigan <mikejc at us.ibm.com>
++ *    Copyright (c) 1999-2000 Grant Erickson <grant at lcse.umn.edu>
++ *
++ *    Description:
++ *      Architecture- / platform-specific boot-time initialization code for
++ *      the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and
++ *      code by Gary Thomas, Cort Dougan <cort at cs.nmt.edu>, and Dan Malek
++ *      <dan at netx4.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	__ISERIES_SETUP_H__
++#define	__ISERIES_SETUP_H__
++
++extern unsigned long iSeries_get_boot_time(void);
++extern int iSeries_set_rtc_time(struct rtc_time *tm);
++extern void iSeries_get_rtc_time(struct rtc_time *tm);
++
++#endif /* __ISERIES_SETUP_H__ */
+diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/smp.c
+@@ -0,0 +1,121 @@
++/*
++ * SMP support for iSeries machines.
++ *
++ * Dave Engebretsen, Peter Bergner, and
++ * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
++ *
++ * Plus various changes from other IBM teams...
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
++#include <linux/kernel_stat.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/spinlock.h>
++#include <linux/cache.h>
++#include <linux/err.h>
++#include <linux/sysdev.h>
++#include <linux/cpu.h>
++
++#include <asm/ptrace.h>
++#include <asm/atomic.h>
++#include <asm/irq.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/io.h>
++#include <asm/smp.h>
++#include <asm/paca.h>
++#include <asm/iSeries/HvCall.h>
++#include <asm/time.h>
++#include <asm/ppcdebug.h>
++#include <asm/machdep.h>
++#include <asm/cputable.h>
++#include <asm/system.h>
++
++static unsigned long iSeries_smp_message[NR_CPUS];
++
++void iSeries_smp_message_recv(struct pt_regs *regs)
++{
++	int cpu = smp_processor_id();
++	int msg;
++
++	if (num_online_cpus() < 2)
++		return;
++
++	for (msg = 0; msg < 4; msg++)
++		if (test_and_clear_bit(msg, &iSeries_smp_message[cpu]))
++			smp_message_recv(msg, regs);
++}
++
++static inline void smp_iSeries_do_message(int cpu, int msg)
++{
++	set_bit(msg, &iSeries_smp_message[cpu]);
++	HvCall_sendIPI(&(paca[cpu]));
++}
++
++static void smp_iSeries_message_pass(int target, int msg)
++{
++	int i;
++
++	if (target < NR_CPUS)
++		smp_iSeries_do_message(target, msg);
++	else {
++		for_each_online_cpu(i) {
++			if ((target == MSG_ALL_BUT_SELF) &&
++					(i == smp_processor_id()))
++				continue;
++			smp_iSeries_do_message(i, msg);
++		}
++	}
++}
++
++static int smp_iSeries_probe(void)
++{
++	return cpus_weight(cpu_possible_map);
++}
++
++static void smp_iSeries_kick_cpu(int nr)
++{
++	BUG_ON((nr < 0) || (nr >= NR_CPUS));
++
++	/* Verify that our partition has a processor nr */
++	if (paca[nr].lppaca.dyn_proc_status >= 2)
++		return;
++
++	/* The processor is currently spinning, waiting
++	 * for the cpu_start field to become non-zero
++	 * After we set cpu_start, the processor will
++	 * continue on to secondary_start in iSeries_head.S
++	 */
++	paca[nr].cpu_start = 1;
++}
++
++static void __devinit smp_iSeries_setup_cpu(int nr)
++{
++}
++
++static struct smp_ops_t iSeries_smp_ops = {
++	.message_pass = smp_iSeries_message_pass,
++	.probe        = smp_iSeries_probe,
++	.kick_cpu     = smp_iSeries_kick_cpu,
++	.setup_cpu    = smp_iSeries_setup_cpu,
++};
++
++/* This is called very early. */
++void __init smp_init_iSeries(void)
++{
++	smp_ops = &iSeries_smp_ops;
++}
+diff --git a/arch/powerpc/platforms/iseries/spcomm_area.h b/arch/powerpc/platforms/iseries/spcomm_area.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/spcomm_area.h
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (C) 2001  Mike Corrigan 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
++ */
++
++#ifndef _ISERIES_SPCOMM_AREA_H
++#define _ISERIES_SPCOMM_AREA_H
++
++
++struct SpCommArea {
++	u32	xDesc;			// Descriptor (only in new formats)	000-003
++	u8	xFormat;		// Format (only in new formats)		004-004
++	u8	xRsvd1[11];		// Reserved				005-00F
++	u64	xRawTbAtIplStart;	// Raw HW TB value when IPL is started	010-017
++	u64	xRawTodAtIplStart;	// Raw HW TOD value when IPL is started	018-01F
++	u64	xBcdTimeAtIplStart;	// BCD time when IPL is started		020-027
++	u64	xBcdTimeAtOsStart;	// BCD time when OS passed control	028-02F
++	u8	xRsvd2[80];		// Reserved				030-07F
++};
++
++extern struct SpCommArea xSpCommArea;
++
++#endif /* _ISERIES_SPCOMM_AREA_H */
+diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/vio.c
+@@ -0,0 +1,156 @@
++/*
++ * IBM PowerPC iSeries Virtual I/O Infrastructure Support.
++ *
++ *    Copyright (c) 2005 Stephen Rothwell, IBM Corp.
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ */
++#include <linux/types.h>
++#include <linux/device.h>
++#include <linux/init.h>
++
++#include <asm/vio.h>
++#include <asm/iommu.h>
++#include <asm/tce.h>
++#include <asm/abs_addr.h>
++#include <asm/page.h>
++#include <asm/iSeries/vio.h>
++#include <asm/iSeries/HvTypes.h>
++#include <asm/iSeries/HvLpConfig.h>
++#include <asm/iSeries/HvCallXm.h>
++
++struct device *iSeries_vio_dev = &vio_bus_device.dev;
++EXPORT_SYMBOL(iSeries_vio_dev);
++
++static struct iommu_table veth_iommu_table;
++static struct iommu_table vio_iommu_table;
++
++static void __init iommu_vio_init(void)
++{
++	struct iommu_table *t;
++	struct iommu_table_cb cb;
++	unsigned long cbp;
++	unsigned long itc_entries;
++
++	cb.itc_busno = 255;    /* Bus 255 is the virtual bus */
++	cb.itc_virtbus = 0xff; /* Ask for virtual bus */
++
++	cbp = virt_to_abs(&cb);
++	HvCallXm_getTceTableParms(cbp);
++
++	itc_entries = cb.itc_size * PAGE_SIZE / sizeof(union tce_entry);
++	veth_iommu_table.it_size        = itc_entries / 2;
++	veth_iommu_table.it_busno       = cb.itc_busno;
++	veth_iommu_table.it_offset      = cb.itc_offset;
++	veth_iommu_table.it_index       = cb.itc_index;
++	veth_iommu_table.it_type        = TCE_VB;
++	veth_iommu_table.it_blocksize	= 1;
++
++	t = iommu_init_table(&veth_iommu_table);
++
++	if (!t)
++		printk("Virtual Bus VETH TCE table failed.\n");
++
++	vio_iommu_table.it_size         = itc_entries - veth_iommu_table.it_size;
++	vio_iommu_table.it_busno        = cb.itc_busno;
++	vio_iommu_table.it_offset       = cb.itc_offset +
++					  veth_iommu_table.it_size;
++	vio_iommu_table.it_index        = cb.itc_index;
++	vio_iommu_table.it_type         = TCE_VB;
++	vio_iommu_table.it_blocksize	= 1;
++
++	t = iommu_init_table(&vio_iommu_table);
++
++	if (!t)
++		printk("Virtual Bus VIO TCE table failed.\n");
++}
++
++/**
++ * vio_register_device_iseries: - Register a new iSeries vio device.
++ * @voidev:	The device to register.
++ */
++static struct vio_dev *__init vio_register_device_iseries(char *type,
++		uint32_t unit_num)
++{
++	struct vio_dev *viodev;
++
++	/* allocate a vio_dev for this device */
++	viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
++	if (!viodev)
++		return NULL;
++	memset(viodev, 0, sizeof(struct vio_dev));
++
++	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num);
++
++	viodev->name = viodev->dev.bus_id;
++	viodev->type = type;
++	viodev->unit_address = unit_num;
++	viodev->iommu_table = &vio_iommu_table;
++	if (vio_register_device(viodev) == NULL) {
++		kfree(viodev);
++		return NULL;
++	}
++	return viodev;
++}
++
++void __init probe_bus_iseries(void)
++{
++	HvLpIndexMap vlan_map;
++	struct vio_dev *viodev;
++	int i;
++
++	/* there is only one of each of these */
++	vio_register_device_iseries("viocons", 0);
++	vio_register_device_iseries("vscsi", 0);
++
++	vlan_map = HvLpConfig_getVirtualLanIndexMap();
++	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
++		if ((vlan_map & (0x8000 >> i)) == 0)
++			continue;
++		viodev = vio_register_device_iseries("vlan", i);
++		/* veth is special and has it own iommu_table */
++		viodev->iommu_table = &veth_iommu_table;
++	}
++	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
++		vio_register_device_iseries("viodasd", i);
++	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
++		vio_register_device_iseries("viocd", i);
++	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
++		vio_register_device_iseries("viotape", i);
++}
++
++/**
++ * vio_match_device_iseries: - Tell if a iSeries VIO device matches a
++ *	vio_device_id
++ */
++static int vio_match_device_iseries(const struct vio_device_id *id,
++		const struct vio_dev *dev)
++{
++	return strncmp(dev->type, id->type, strlen(id->type)) == 0;
++}
++
++static struct vio_bus_ops vio_bus_ops_iseries = {
++	.match = vio_match_device_iseries,
++};
++
++/**
++ * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus
++ */
++static int __init vio_bus_init_iseries(void)
++{
++	int err;
++
++	err = vio_bus_init(&vio_bus_ops_iseries);
++	if (err == 0) {
++		iommu_vio_init();
++		vio_bus_device.iommu_table = &vio_iommu_table;
++		iSeries_vio_dev = &vio_bus_device.dev;
++		probe_bus_iseries();
++	}
++	return err;
++}
++
++__initcall(vio_bus_init_iseries);
+diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/viopath.c
+@@ -0,0 +1,672 @@
++/* -*- linux-c -*-
++ *
++ *  iSeries Virtual I/O Message Path code
++ *
++ *  Authors: Dave Boutcher <boutcher at us.ibm.com>
++ *           Ryan Arnold <ryanarn at us.ibm.com>
++ *           Colin Devilbiss <devilbis at us.ibm.com>
++ *
++ * (C) Copyright 2000-2005 IBM Corporation
++ *
++ * This code is used by the iSeries virtual disk, cd,
++ * tape, and console to communicate with OS/400 in another
++ * partition.
++ *
++ * This program is free software;  you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) anyu 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/errno.h>
++#include <linux/vmalloc.h>
++#include <linux/string.h>
++#include <linux/proc_fs.h>
++#include <linux/dma-mapping.h>
++#include <linux/wait.h>
++#include <linux/seq_file.h>
++#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
++
++#include <asm/system.h>
++#include <asm/uaccess.h>
++#include <asm/iSeries/HvTypes.h>
++#include <asm/iSeries/ItExtVpdPanel.h>
++#include <asm/iSeries/HvLpEvent.h>
++#include <asm/iSeries/HvLpConfig.h>
++#include <asm/iSeries/mf.h>
++#include <asm/iSeries/vio.h>
++
++/* Status of the path to each other partition in the system.
++ * This is overkill, since we will only ever establish connections
++ * to our hosting partition and the primary partition on the system.
++ * But this allows for other support in the future.
++ */
++static struct viopathStatus {
++	int isOpen;		/* Did we open the path?            */
++	int isActive;		/* Do we have a mon msg outstanding */
++	int users[VIO_MAX_SUBTYPES];
++	HvLpInstanceId mSourceInst;
++	HvLpInstanceId mTargetInst;
++	int numberAllocated;
++} viopathStatus[HVMAXARCHITECTEDLPS];
++
++static DEFINE_SPINLOCK(statuslock);
++
++/*
++ * For each kind of event we allocate a buffer that is
++ * guaranteed not to cross a page boundary
++ */
++static unsigned char event_buffer[VIO_MAX_SUBTYPES * 256] __page_aligned;
++static atomic_t event_buffer_available[VIO_MAX_SUBTYPES];
++static int event_buffer_initialised;
++
++static void handleMonitorEvent(struct HvLpEvent *event);
++
++/*
++ * We use this structure to handle asynchronous responses.  The caller
++ * blocks on the semaphore and the handler posts the semaphore.  However,
++ * if system_state is not SYSTEM_RUNNING, then wait_atomic is used ...
++ */
++struct alloc_parms {
++	struct semaphore sem;
++	int number;
++	atomic_t wait_atomic;
++	int used_wait_atomic;
++};
++
++/* Put a sequence number in each mon msg.  The value is not
++ * important.  Start at something other than 0 just for
++ * readability.  wrapping this is ok.
++ */
++static u8 viomonseq = 22;
++
++/* Our hosting logical partition.  We get this at startup
++ * time, and different modules access this variable directly.
++ */
++HvLpIndex viopath_hostLp = HvLpIndexInvalid;
++EXPORT_SYMBOL(viopath_hostLp);
++HvLpIndex viopath_ourLp = HvLpIndexInvalid;
++EXPORT_SYMBOL(viopath_ourLp);
++
++/* For each kind of incoming event we set a pointer to a
++ * routine to call.
++ */
++static vio_event_handler_t *vio_handler[VIO_MAX_SUBTYPES];
++
++#define VIOPATH_KERN_WARN	KERN_WARNING "viopath: "
++#define VIOPATH_KERN_INFO	KERN_INFO "viopath: "
++
++static int proc_viopath_show(struct seq_file *m, void *v)
++{
++	char *buf;
++	u16 vlanMap;
++	dma_addr_t handle;
++	HvLpEvent_Rc hvrc;
++	DECLARE_MUTEX_LOCKED(Semaphore);
++
++	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
++	if (!buf)
++		return 0;
++	memset(buf, 0, PAGE_SIZE);
++
++	handle = dma_map_single(iSeries_vio_dev, buf, PAGE_SIZE,
++				DMA_FROM_DEVICE);
++
++	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
++			HvLpEvent_Type_VirtualIo,
++			viomajorsubtype_config | vioconfigget,
++			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
++			viopath_sourceinst(viopath_hostLp),
++			viopath_targetinst(viopath_hostLp),
++			(u64)(unsigned long)&Semaphore, VIOVERSION << 16,
++			((u64)handle) << 32, PAGE_SIZE, 0, 0);
++
++	if (hvrc != HvLpEvent_Rc_Good)
++		printk(VIOPATH_KERN_WARN "hv error on op %d\n", (int)hvrc);
++
++	down(&Semaphore);
++
++	vlanMap = HvLpConfig_getVirtualLanIndexMap();
++
++	buf[PAGE_SIZE-1] = '\0';
++	seq_printf(m, "%s", buf);
++	seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
++	seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n",
++		   e2a(xItExtVpdPanel.mfgID[2]),
++		   e2a(xItExtVpdPanel.mfgID[3]),
++		   e2a(xItExtVpdPanel.systemSerial[1]),
++		   e2a(xItExtVpdPanel.systemSerial[2]),
++		   e2a(xItExtVpdPanel.systemSerial[3]),
++		   e2a(xItExtVpdPanel.systemSerial[4]),
++		   e2a(xItExtVpdPanel.systemSerial[5]));
++
++	dma_unmap_single(iSeries_vio_dev, handle, PAGE_SIZE, DMA_FROM_DEVICE);
++	kfree(buf);
++
++	return 0;
++}
++
++static int proc_viopath_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, proc_viopath_show, NULL);
++}
++
++static struct file_operations proc_viopath_operations = {
++	.open		= proc_viopath_open,
++	.read		= seq_read,
++	.llseek		= seq_lseek,
++	.release	= single_release,
++};
++
++static int __init vio_proc_init(void)
++{
++	struct proc_dir_entry *e;
++
++	e = create_proc_entry("iSeries/config", 0, NULL);
++	if (e)
++		e->proc_fops = &proc_viopath_operations;
++
++        return 0;
++}
++__initcall(vio_proc_init);
++
++/* See if a given LP is active.  Allow for invalid lps to be passed in
++ * and just return invalid
++ */
++int viopath_isactive(HvLpIndex lp)
++{
++	if (lp == HvLpIndexInvalid)
++		return 0;
++	if (lp < HVMAXARCHITECTEDLPS)
++		return viopathStatus[lp].isActive;
++	else
++		return 0;
++}
++EXPORT_SYMBOL(viopath_isactive);
++
++/*
++ * We cache the source and target instance ids for each
++ * partition.
++ */
++HvLpInstanceId viopath_sourceinst(HvLpIndex lp)
++{
++	return viopathStatus[lp].mSourceInst;
++}
++EXPORT_SYMBOL(viopath_sourceinst);
++
++HvLpInstanceId viopath_targetinst(HvLpIndex lp)
++{
++	return viopathStatus[lp].mTargetInst;
++}
++EXPORT_SYMBOL(viopath_targetinst);
++
++/*
++ * Send a monitor message.  This is a message with the acknowledge
++ * bit on that the other side will NOT explicitly acknowledge.  When
++ * the other side goes down, the hypervisor will acknowledge any
++ * outstanding messages....so we will know when the other side dies.
++ */
++static void sendMonMsg(HvLpIndex remoteLp)
++{
++	HvLpEvent_Rc hvrc;
++
++	viopathStatus[remoteLp].mSourceInst =
++		HvCallEvent_getSourceLpInstanceId(remoteLp,
++				HvLpEvent_Type_VirtualIo);
++	viopathStatus[remoteLp].mTargetInst =
++		HvCallEvent_getTargetLpInstanceId(remoteLp,
++				HvLpEvent_Type_VirtualIo);
++
++	/*
++	 * Deliberately ignore the return code here.  if we call this
++	 * more than once, we don't care.
++	 */
++	vio_setHandler(viomajorsubtype_monitor, handleMonitorEvent);
++
++	hvrc = HvCallEvent_signalLpEventFast(remoteLp, HvLpEvent_Type_VirtualIo,
++			viomajorsubtype_monitor, HvLpEvent_AckInd_DoAck,
++			HvLpEvent_AckType_DeferredAck,
++			viopathStatus[remoteLp].mSourceInst,
++			viopathStatus[remoteLp].mTargetInst,
++			viomonseq++, 0, 0, 0, 0, 0);
++
++	if (hvrc == HvLpEvent_Rc_Good)
++		viopathStatus[remoteLp].isActive = 1;
++	else {
++		printk(VIOPATH_KERN_WARN "could not connect to partition %d\n",
++				remoteLp);
++		viopathStatus[remoteLp].isActive = 0;
++	}
++}
++
++static void handleMonitorEvent(struct HvLpEvent *event)
++{
++	HvLpIndex remoteLp;
++	int i;
++
++	/*
++	 * This handler is _also_ called as part of the loop
++	 * at the end of this routine, so it must be able to
++	 * ignore NULL events...
++	 */
++	if (!event)
++		return;
++
++	/*
++	 * First see if this is just a normal monitor message from the
++	 * other partition
++	 */
++	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
++		remoteLp = event->xSourceLp;
++		if (!viopathStatus[remoteLp].isActive)
++			sendMonMsg(remoteLp);
++		return;
++	}
++
++	/*
++	 * This path is for an acknowledgement; the other partition
++	 * died
++	 */
++	remoteLp = event->xTargetLp;
++	if ((event->xSourceInstanceId != viopathStatus[remoteLp].mSourceInst) ||
++	    (event->xTargetInstanceId != viopathStatus[remoteLp].mTargetInst)) {
++		printk(VIOPATH_KERN_WARN "ignoring ack....mismatched instances\n");
++		return;
++	}
++
++	printk(VIOPATH_KERN_WARN "partition %d ended\n", remoteLp);
++
++	viopathStatus[remoteLp].isActive = 0;
++
++	/*
++	 * For each active handler, pass them a NULL
++	 * message to indicate that the other partition
++	 * died
++	 */
++	for (i = 0; i < VIO_MAX_SUBTYPES; i++) {
++		if (vio_handler[i] != NULL)
++			(*vio_handler[i])(NULL);
++	}
++}
++
++int vio_setHandler(int subtype, vio_event_handler_t *beh)
++{
++	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
++	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
++		return -EINVAL;
++	if (vio_handler[subtype] != NULL)
++		return -EBUSY;
++	vio_handler[subtype] = beh;
++	return 0;
++}
++EXPORT_SYMBOL(vio_setHandler);
++
++int vio_clearHandler(int subtype)
++{
++	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
++	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
++		return -EINVAL;
++	if (vio_handler[subtype] == NULL)
++		return -EAGAIN;
++	vio_handler[subtype] = NULL;
++	return 0;
++}
++EXPORT_SYMBOL(vio_clearHandler);
++
++static void handleConfig(struct HvLpEvent *event)
++{
++	if (!event)
++		return;
++	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
++		printk(VIOPATH_KERN_WARN
++		       "unexpected config request from partition %d",
++		       event->xSourceLp);
++
++		if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
++		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
++			event->xRc = HvLpEvent_Rc_InvalidSubtype;
++			HvCallEvent_ackLpEvent(event);
++		}
++		return;
++	}
++
++	up((struct semaphore *)event->xCorrelationToken);
++}
++
++/*
++ * Initialization of the hosting partition
++ */
++void vio_set_hostlp(void)
++{
++	/*
++	 * If this has already been set then we DON'T want to either change
++	 * it or re-register the proc file system
++	 */
++	if (viopath_hostLp != HvLpIndexInvalid)
++		return;
++
++	/*
++	 * Figure out our hosting partition.  This isn't allowed to change
++	 * while we're active
++	 */
++	viopath_ourLp = HvLpConfig_getLpIndex();
++	viopath_hostLp = HvLpConfig_getHostingLpIndex(viopath_ourLp);
++
++	if (viopath_hostLp != HvLpIndexInvalid)
++		vio_setHandler(viomajorsubtype_config, handleConfig);
++}
++EXPORT_SYMBOL(vio_set_hostlp);
++
++static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs)
++{
++	HvLpIndex remoteLp;
++	int subtype = (event->xSubtype & VIOMAJOR_SUBTYPE_MASK)
++		>> VIOMAJOR_SUBTYPE_SHIFT;
++
++	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
++		remoteLp = event->xSourceLp;
++		/*
++		 * The isActive is checked because if the hosting partition
++		 * went down and came back up it would not be active but it
++		 * would have different source and target instances, in which
++		 * case we'd want to reset them.  This case really protects
++		 * against an unauthorized active partition sending interrupts
++		 * or acks to this linux partition.
++		 */
++		if (viopathStatus[remoteLp].isActive
++		    && (event->xSourceInstanceId !=
++			viopathStatus[remoteLp].mTargetInst)) {
++			printk(VIOPATH_KERN_WARN
++			       "message from invalid partition. "
++			       "int msg rcvd, source inst (%d) doesnt match (%d)\n",
++			       viopathStatus[remoteLp].mTargetInst,
++			       event->xSourceInstanceId);
++			return;
++		}
++
++		if (viopathStatus[remoteLp].isActive
++		    && (event->xTargetInstanceId !=
++			viopathStatus[remoteLp].mSourceInst)) {
++			printk(VIOPATH_KERN_WARN
++			       "message from invalid partition. "
++			       "int msg rcvd, target inst (%d) doesnt match (%d)\n",
++			       viopathStatus[remoteLp].mSourceInst,
++			       event->xTargetInstanceId);
++			return;
++		}
++	} else {
++		remoteLp = event->xTargetLp;
++		if (event->xSourceInstanceId !=
++		    viopathStatus[remoteLp].mSourceInst) {
++			printk(VIOPATH_KERN_WARN
++			       "message from invalid partition. "
++			       "ack msg rcvd, source inst (%d) doesnt match (%d)\n",
++			       viopathStatus[remoteLp].mSourceInst,
++			       event->xSourceInstanceId);
++			return;
++		}
++
++		if (event->xTargetInstanceId !=
++		    viopathStatus[remoteLp].mTargetInst) {
++			printk(VIOPATH_KERN_WARN
++			       "message from invalid partition. "
++			       "viopath: ack msg rcvd, target inst (%d) doesnt match (%d)\n",
++			       viopathStatus[remoteLp].mTargetInst,
++			       event->xTargetInstanceId);
++			return;
++		}
++	}
++
++	if (vio_handler[subtype] == NULL) {
++		printk(VIOPATH_KERN_WARN
++		       "unexpected virtual io event subtype %d from partition %d\n",
++		       event->xSubtype, remoteLp);
++		/* No handler.  Ack if necessary */
++		if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
++		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
++			event->xRc = HvLpEvent_Rc_InvalidSubtype;
++			HvCallEvent_ackLpEvent(event);
++		}
++		return;
++	}
++
++	/* This innocuous little line is where all the real work happens */
++	(*vio_handler[subtype])(event);
++}
++
++static void viopath_donealloc(void *parm, int number)
++{
++	struct alloc_parms *parmsp = parm;
++
++	parmsp->number = number;
++	if (parmsp->used_wait_atomic)
++		atomic_set(&parmsp->wait_atomic, 0);
++	else
++		up(&parmsp->sem);
++}
++
++static int allocateEvents(HvLpIndex remoteLp, int numEvents)
++{
++	struct alloc_parms parms;
++
++	if (system_state != SYSTEM_RUNNING) {
++		parms.used_wait_atomic = 1;
++		atomic_set(&parms.wait_atomic, 1);
++	} else {
++		parms.used_wait_atomic = 0;
++		init_MUTEX_LOCKED(&parms.sem);
++	}
++	mf_allocate_lp_events(remoteLp, HvLpEvent_Type_VirtualIo, 250,	/* It would be nice to put a real number here! */
++			    numEvents, &viopath_donealloc, &parms);
++	if (system_state != SYSTEM_RUNNING) {
++		while (atomic_read(&parms.wait_atomic))
++			mb();
++	} else
++		down(&parms.sem);
++	return parms.number;
++}
++
++int viopath_open(HvLpIndex remoteLp, int subtype, int numReq)
++{
++	int i;
++	unsigned long flags;
++	int tempNumAllocated;
++
++	if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid))
++		return -EINVAL;
++
++	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
++	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
++		return -EINVAL;
++
++	spin_lock_irqsave(&statuslock, flags);
++
++	if (!event_buffer_initialised) {
++		for (i = 0; i < VIO_MAX_SUBTYPES; i++)
++			atomic_set(&event_buffer_available[i], 1);
++		event_buffer_initialised = 1;
++	}
++
++	viopathStatus[remoteLp].users[subtype]++;
++
++	if (!viopathStatus[remoteLp].isOpen) {
++		viopathStatus[remoteLp].isOpen = 1;
++		HvCallEvent_openLpEventPath(remoteLp, HvLpEvent_Type_VirtualIo);
++
++		/*
++		 * Don't hold the spinlock during an operation that
++		 * can sleep.
++		 */
++		spin_unlock_irqrestore(&statuslock, flags);
++		tempNumAllocated = allocateEvents(remoteLp, 1);
++		spin_lock_irqsave(&statuslock, flags);
++
++		viopathStatus[remoteLp].numberAllocated += tempNumAllocated;
++
++		if (viopathStatus[remoteLp].numberAllocated == 0) {
++			HvCallEvent_closeLpEventPath(remoteLp,
++					HvLpEvent_Type_VirtualIo);
++
++			spin_unlock_irqrestore(&statuslock, flags);
++			return -ENOMEM;
++		}
++
++		viopathStatus[remoteLp].mSourceInst =
++			HvCallEvent_getSourceLpInstanceId(remoteLp,
++					HvLpEvent_Type_VirtualIo);
++		viopathStatus[remoteLp].mTargetInst =
++			HvCallEvent_getTargetLpInstanceId(remoteLp,
++					HvLpEvent_Type_VirtualIo);
++		HvLpEvent_registerHandler(HvLpEvent_Type_VirtualIo,
++					  &vio_handleEvent);
++		sendMonMsg(remoteLp);
++		printk(VIOPATH_KERN_INFO "opening connection to partition %d, "
++				"setting sinst %d, tinst %d\n",
++				remoteLp, viopathStatus[remoteLp].mSourceInst,
++				viopathStatus[remoteLp].mTargetInst);
++	}
++
++	spin_unlock_irqrestore(&statuslock, flags);
++	tempNumAllocated = allocateEvents(remoteLp, numReq);
++	spin_lock_irqsave(&statuslock, flags);
++	viopathStatus[remoteLp].numberAllocated += tempNumAllocated;
++	spin_unlock_irqrestore(&statuslock, flags);
++
++	return 0;
++}
++EXPORT_SYMBOL(viopath_open);
++
++int viopath_close(HvLpIndex remoteLp, int subtype, int numReq)
++{
++	unsigned long flags;
++	int i;
++	int numOpen;
++	struct alloc_parms parms;
++
++	if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid))
++		return -EINVAL;
++
++	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
++	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
++		return -EINVAL;
++
++	spin_lock_irqsave(&statuslock, flags);
++	/*
++	 * If the viopath_close somehow gets called before a
++	 * viopath_open it could decrement to -1 which is a non
++	 * recoverable state so we'll prevent this from
++	 * happening.
++	 */
++	if (viopathStatus[remoteLp].users[subtype] > 0)
++		viopathStatus[remoteLp].users[subtype]--;
++
++	spin_unlock_irqrestore(&statuslock, flags);
++
++	parms.used_wait_atomic = 0;
++	init_MUTEX_LOCKED(&parms.sem);
++	mf_deallocate_lp_events(remoteLp, HvLpEvent_Type_VirtualIo,
++			      numReq, &viopath_donealloc, &parms);
++	down(&parms.sem);
++
++	spin_lock_irqsave(&statuslock, flags);
++	for (i = 0, numOpen = 0; i < VIO_MAX_SUBTYPES; i++)
++		numOpen += viopathStatus[remoteLp].users[i];
++
++	if ((viopathStatus[remoteLp].isOpen) && (numOpen == 0)) {
++		printk(VIOPATH_KERN_INFO "closing connection to partition %d",
++				remoteLp);
++
++		HvCallEvent_closeLpEventPath(remoteLp,
++					     HvLpEvent_Type_VirtualIo);
++		viopathStatus[remoteLp].isOpen = 0;
++		viopathStatus[remoteLp].isActive = 0;
++
++		for (i = 0; i < VIO_MAX_SUBTYPES; i++)
++			atomic_set(&event_buffer_available[i], 0);
++		event_buffer_initialised = 0;
++	}
++	spin_unlock_irqrestore(&statuslock, flags);
++	return 0;
++}
++EXPORT_SYMBOL(viopath_close);
++
++void *vio_get_event_buffer(int subtype)
++{
++	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
++	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
++		return NULL;
++
++	if (atomic_dec_if_positive(&event_buffer_available[subtype]) == 0)
++		return &event_buffer[subtype * 256];
++	else
++		return NULL;
++}
++EXPORT_SYMBOL(vio_get_event_buffer);
++
++void vio_free_event_buffer(int subtype, void *buffer)
++{
++	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
++	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES)) {
++		printk(VIOPATH_KERN_WARN
++		       "unexpected subtype %d freeing event buffer\n", subtype);
++		return;
++	}
++
++	if (atomic_read(&event_buffer_available[subtype]) != 0) {
++		printk(VIOPATH_KERN_WARN
++		       "freeing unallocated event buffer, subtype %d\n",
++		       subtype);
++		return;
++	}
++
++	if (buffer != &event_buffer[subtype * 256]) {
++		printk(VIOPATH_KERN_WARN
++		       "freeing invalid event buffer, subtype %d\n", subtype);
++	}
++
++	atomic_set(&event_buffer_available[subtype], 1);
++}
++EXPORT_SYMBOL(vio_free_event_buffer);
++
++static const struct vio_error_entry vio_no_error =
++    { 0, 0, "Non-VIO Error" };
++static const struct vio_error_entry vio_unknown_error =
++    { 0, EIO, "Unknown Error" };
++
++static const struct vio_error_entry vio_default_errors[] = {
++	{0x0001, EIO, "No Connection"},
++	{0x0002, EIO, "No Receiver"},
++	{0x0003, EIO, "No Buffer Available"},
++	{0x0004, EBADRQC, "Invalid Message Type"},
++	{0x0000, 0, NULL},
++};
++
++const struct vio_error_entry *vio_lookup_rc(
++		const struct vio_error_entry *local_table, u16 rc)
++{
++	const struct vio_error_entry *cur;
++
++	if (!rc)
++		return &vio_no_error;
++	if (local_table)
++		for (cur = local_table; cur->rc; ++cur)
++			if (cur->rc == rc)
++				return cur;
++	for (cur = vio_default_errors; cur->rc; ++cur)
++		if (cur->rc == rc)
++			return cur;
++	return &vio_unknown_error;
++}
++EXPORT_SYMBOL(vio_lookup_rc);
+diff --git a/arch/powerpc/platforms/iseries/vpd_areas.h b/arch/powerpc/platforms/iseries/vpd_areas.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/vpd_areas.h
+@@ -0,0 +1,88 @@
++/*
++ * Copyright (C) 2001  Mike Corrigan 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
++ */
++#ifndef _ISERIES_VPD_AREAS_H
++#define _ISERIES_VPD_AREAS_H
++
++/*
++ * This file defines the address and length of all of the VPD area passed to
++ * the OS from PLIC (most of which start from the SP).
++ */
++
++#include <asm/types.h>
++
++/* VPD Entry index is carved in stone - cannot be changed (easily). */
++#define ItVpdCecVpd				0
++#define ItVpdDynamicSpace			1
++#define ItVpdExtVpd				2
++#define ItVpdExtVpdOnPanel			3
++#define ItVpdFirstPaca				4
++#define ItVpdIoVpd				5
++#define ItVpdIplParms				6
++#define ItVpdMsVpd				7
++#define ItVpdPanelVpd				8
++#define ItVpdLpNaca				9
++#define ItVpdBackplaneAndMaybeClockCardVpd	10
++#define ItVpdRecoveryLogBuffer			11
++#define ItVpdSpCommArea				12
++#define ItVpdSpLogBuffer			13
++#define ItVpdSpLogBufferSave			14
++#define ItVpdSpCardVpd				15
++#define ItVpdFirstProcVpd			16
++#define ItVpdApModelVpd				17
++#define ItVpdClockCardVpd			18
++#define ItVpdBusExtCardVpd			19
++#define ItVpdProcCapacityVpd			20
++#define ItVpdInteractiveCapacityVpd		21
++#define ItVpdFirstSlotLabel			22
++#define ItVpdFirstLpQueue			23
++#define ItVpdFirstL3CacheVpd			24
++#define ItVpdFirstProcFruVpd			25
++
++#define ItVpdMaxEntries				26
++
++#define ItDmaMaxEntries				10
++
++#define ItVpdAreasMaxSlotLabels			192
++
++
++struct ItVpdAreas {
++	u32	xSlicDesc;		// Descriptor			000-003
++	u16	xSlicSize;		// Size of this control block	004-005
++	u16	xPlicAdjustVpdLens:1;	// Flag to indicate new interface006-007
++	u16	xRsvd1:15;		// Reserved bits		...
++	u16	xSlicVpdEntries;	// Number of VPD entries	008-009
++	u16	xSlicDmaEntries;	// Number of DMA entries	00A-00B
++	u16	xSlicMaxLogicalProcs;	// Maximum logical processors	00C-00D
++	u16	xSlicMaxPhysicalProcs;	// Maximum physical processors	00E-00F
++	u16	xSlicDmaToksOffset;	// Offset into this of array	010-011
++	u16	xSlicVpdAdrsOffset;	// Offset into this of array	012-013
++	u16	xSlicDmaLensOffset;	// Offset into this of array	014-015
++	u16	xSlicVpdLensOffset;	// Offset into this of array	016-017
++	u16	xSlicMaxSlotLabels;	// Maximum number of slot labels018-019
++	u16	xSlicMaxLpQueues;	// Maximum number of LP Queues	01A-01B
++	u8	xRsvd2[4];		// Reserved			01C-01F
++	u64	xRsvd3[12];		// Reserved			020-07F
++	u32	xPlicDmaLens[ItDmaMaxEntries];// Array of DMA lengths	080-0A7
++	u32	xPlicDmaToks[ItDmaMaxEntries];// Array of DMA tokens	0A8-0CF
++	u32	xSlicVpdLens[ItVpdMaxEntries];// Array of VPD lengths	0D0-12F
++	void	*xSlicVpdAdrs[ItVpdMaxEntries];// Array of VPD buffers	130-1EF
++};
++
++extern struct ItVpdAreas	itVpdAreas;
++
++#endif /* _ISERIES_VPD_AREAS_H */
+diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/iseries/vpdinfo.c
+@@ -0,0 +1,271 @@
++/*
++ * This code gets the card location of the hardware
++ * Copyright (C) 2001  <Allan H Trautman> <IBM Corp>
++ * Copyright (C) 2005  Stephen Rothwel, IBM Corp
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the:
++ * Free Software Foundation, Inc.,
++ * 59 Temple Place, Suite 330,
++ * Boston, MA  02111-1307  USA
++ *
++ * Change Activity:
++ *   Created, Feb 2, 2001
++ *   Ported to ppc64, August 20, 2001
++ * End Change Activity
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++
++#include <asm/types.h>
++#include <asm/resource.h>
++#include <asm/abs_addr.h>
++#include <asm/pci-bridge.h>
++#include <asm/iSeries/HvTypes.h>
++
++#include "pci.h"
++#include "call_pci.h"
++
++/*
++ * Size of Bus VPD data
++ */
++#define BUS_VPDSIZE      1024
++
++/*
++ * Bus Vpd Tags
++ */
++#define  VpdEndOfAreaTag   0x79
++#define  VpdIdStringTag    0x82
++#define  VpdVendorAreaTag  0x84
++
++/*
++ * Mfg Area Tags
++ */
++#define  VpdFruFrameId    0x4649     // "FI"
++#define  VpdSlotMapFormat 0x4D46     // "MF"
++#define  VpdSlotMap       0x534D     // "SM"
++
++/*
++ * Structures of the areas
++ */
++struct MfgVpdAreaStruct {
++	u16 Tag;
++	u8  TagLength;
++	u8  AreaData1;
++	u8  AreaData2;
++};
++typedef struct MfgVpdAreaStruct MfgArea;
++#define MFG_ENTRY_SIZE   3
++
++struct SlotMapStruct {
++	u8   AgentId;
++	u8   SecondaryAgentId;
++	u8   PhbId;
++	char CardLocation[3];
++	char Parms[8];
++	char Reserved[2];
++};
++typedef struct SlotMapStruct SlotMap;
++#define SLOT_ENTRY_SIZE   16
++
++/*
++ * Parse the Slot Area
++ */
++static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
++		HvAgentId agent, u8 *PhbId, char card[4])
++{
++	int SlotMapLen = MapLen;
++	SlotMap *SlotMapPtr = MapPtr;
++
++	/*
++	 * Parse Slot label until we find the one requested
++	 */
++	while (SlotMapLen > 0) {
++		if (SlotMapPtr->AgentId == agent) {
++			/*
++			 * If Phb wasn't found, grab the entry first one found.
++			 */
++			if (*PhbId == 0xff)
++				*PhbId = SlotMapPtr->PhbId;
++			/* Found it, extract the data. */
++			if (SlotMapPtr->PhbId == *PhbId) {
++				memcpy(card, &SlotMapPtr->CardLocation, 3);
++				card[3]  = 0;
++				break;
++			}
++		}
++		/* Point to the next Slot */
++		SlotMapPtr = (SlotMap *)((char *)SlotMapPtr + SLOT_ENTRY_SIZE);
++		SlotMapLen -= SLOT_ENTRY_SIZE;
++	}
++}
++
++/*
++ * Parse the Mfg Area
++ */
++static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
++		HvAgentId agent, u8 *PhbId,
++		u8 *frame, char card[4])
++{
++	MfgArea *MfgAreaPtr = (MfgArea *)AreaData;
++	int MfgAreaLen = AreaLen;
++	u16 SlotMapFmt = 0;
++
++	/* Parse Mfg Data */
++	while (MfgAreaLen > 0) {
++		int MfgTagLen = MfgAreaPtr->TagLength;
++		/* Frame ID         (FI 4649020310 ) */
++		if (MfgAreaPtr->Tag == VpdFruFrameId)		/* FI  */
++			*frame = MfgAreaPtr->AreaData1;
++		/* Slot Map Format  (MF 4D46020004 ) */
++		else if (MfgAreaPtr->Tag == VpdSlotMapFormat)	/* MF  */
++			SlotMapFmt = (MfgAreaPtr->AreaData1 * 256)
++				+ MfgAreaPtr->AreaData2;
++		/* Slot Map         (SM 534D90 */
++		else if (MfgAreaPtr->Tag == VpdSlotMap)	{	/* SM  */
++			SlotMap *SlotMapPtr;
++
++			if (SlotMapFmt == 0x1004)
++				SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
++						+ MFG_ENTRY_SIZE + 1);
++			else
++				SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
++						+ MFG_ENTRY_SIZE);
++			iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen,
++					agent, PhbId, card);
++		}
++		/*
++		 * Point to the next Mfg Area
++		 * Use defined size, sizeof give wrong answer
++		 */
++		MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen
++				+ MFG_ENTRY_SIZE);
++		MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE);
++	}
++}
++
++/*
++ * Look for "BUS".. Data is not Null terminated.
++ * PHBID of 0xFF indicates PHB was not found in VPD Data.
++ */
++static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
++{
++	u8 *PhbPtr = AreaPtr;
++	int DataLen = AreaLength;
++	char PhbId = 0xFF;
++
++	while (DataLen > 0) {
++		if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U')
++				&& (*(PhbPtr + 2) == 'S')) {
++			PhbPtr += 3;
++			while (*PhbPtr == ' ')
++				++PhbPtr;
++			PhbId = (*PhbPtr & 0x0F);
++			break;
++		}
++		++PhbPtr;
++		--DataLen;
++	}
++	return PhbId;
++}
++
++/*
++ * Parse out the VPD Areas
++ */
++static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
++		HvAgentId agent, u8 *frame, char card[4])
++{
++	u8 *TagPtr = VpdData;
++	int DataLen = VpdDataLen - 3;
++	u8 PhbId;
++
++	while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
++		int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
++		u8 *AreaData  = TagPtr + 3;
++
++		if (*TagPtr == VpdIdStringTag)
++			PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
++		else if (*TagPtr == VpdVendorAreaTag)
++			iSeries_Parse_MfgArea(AreaData, AreaLen,
++					agent, &PhbId, frame, card);
++		/* Point to next Area. */
++		TagPtr  = AreaData + AreaLen;
++		DataLen -= AreaLen;
++	}
++}
++
++static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
++		u8 *frame, char card[4])
++{
++	int BusVpdLen = 0;
++	u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
++
++	if (BusVpdPtr == NULL) {
++		printk("PCI: Bus VPD Buffer allocation failure.\n");
++		return;
++	}
++	BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
++					BUS_VPDSIZE);
++	if (BusVpdLen == 0) {
++		printk("PCI: Bus VPD Buffer zero length.\n");
++		goto out_free;
++	}
++	/* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */
++	/* Make sure this is what I think it is */
++	if (*BusVpdPtr != VpdIdStringTag) {	/* 0x82 */
++		printk("PCI: Bus VPD Buffer missing starting tag.\n");
++		goto out_free;
++	}
++	iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
++out_free:
++	kfree(BusVpdPtr);
++}
++
++/*
++ * Prints the device information.
++ * - Pass in pci_dev* pointer to the device.
++ * - Pass in the device count
++ *
++ * Format:
++ * PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet
++ * controller
++ */
++void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
++{
++	struct device_node *DevNode = PciDev->sysdata;
++	struct pci_dn *pdn;
++	u16 bus;
++	u8 frame;
++	char card[4];
++	HvSubBusNumber subbus;
++	HvAgentId agent;
++
++	if (DevNode == NULL) {
++		printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n",
++				count);
++		return;
++	}
++
++	pdn = PCI_DN(DevNode);
++	bus = pdn->busno;
++	subbus = pdn->bussubno;
++	agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
++			ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
++	iSeries_Get_Location_Code(bus, agent, &frame, card);
++
++	printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s  ",
++			count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor,
++			frame, card);
++	printk("0x%04X\n", (int)(PciDev->class >> 8));
++}
+diff --git a/arch/powerpc/platforms/maple/Makefile b/arch/powerpc/platforms/maple/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/maple/Makefile
+@@ -0,0 +1 @@
++obj-y	+= setup.o pci.o time.o
+diff --git a/arch/powerpc/platforms/maple/maple.h b/arch/powerpc/platforms/maple/maple.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/maple/maple.h
+@@ -0,0 +1,12 @@
++/*
++ * Declarations for maple-specific code.
++ *
++ * Maple is the name of a PPC970 evaluation board.
++ */
++extern int maple_set_rtc_time(struct rtc_time *tm);
++extern void maple_get_rtc_time(struct rtc_time *tm);
++extern unsigned long maple_get_boot_time(void);
++extern void maple_calibrate_decr(void);
++extern void maple_pci_init(void);
++extern void maple_pcibios_fixup(void);
++extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
+diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/maple/pci.c
+@@ -0,0 +1,522 @@
++/*
++ * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org),
++ *		      IBM Corp.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++#define DEBUG
++
++#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/sections.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/pci-bridge.h>
++#include <asm/machdep.h>
++#include <asm/iommu.h>
++#include <asm/ppc-pci.h>
++
++#include "maple.h"
++
++#ifdef DEBUG
++#define DBG(x...) printk(x)
++#else
++#define DBG(x...)
++#endif
++
++static struct pci_controller *u3_agp, *u3_ht;
++
++static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
++{
++	for (; node != 0;node = node->sibling) {
++		int * bus_range;
++		unsigned int *class_code;
++		int len;
++
++		/* For PCI<->PCI bridges or CardBus bridges, we go down */
++		class_code = (unsigned int *) get_property(node, "class-code", NULL);
++		if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
++			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
++			continue;
++		bus_range = (int *) get_property(node, "bus-range", &len);
++		if (bus_range != NULL && len > 2 * sizeof(int)) {
++			if (bus_range[1] > higher)
++				higher = bus_range[1];
++		}
++		higher = fixup_one_level_bus_range(node->child, higher);
++	}
++	return higher;
++}
++
++/* This routine fixes the "bus-range" property of all bridges in the
++ * system since they tend to have their "last" member wrong on macs
++ *
++ * Note that the bus numbers manipulated here are OF bus numbers, they
++ * are not Linux bus numbers.
++ */
++static void __init fixup_bus_range(struct device_node *bridge)
++{
++	int * bus_range;
++	int len;
++
++	/* Lookup the "bus-range" property for the hose */
++	bus_range = (int *) get_property(bridge, "bus-range", &len);
++	if (bus_range == NULL || len < 2 * sizeof(int)) {
++		printk(KERN_WARNING "Can't get bus-range for %s\n",
++			       bridge->full_name);
++		return;
++	}
++	bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
++}
++
++
++#define U3_AGP_CFA0(devfn, off)	\
++	((1 << (unsigned long)PCI_SLOT(dev_fn)) \
++	| (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
++	| (((unsigned long)(off)) & 0xFCUL))
++
++#define U3_AGP_CFA1(bus, devfn, off)	\
++	((((unsigned long)(bus)) << 16) \
++	|(((unsigned long)(devfn)) << 8) \
++	|(((unsigned long)(off)) & 0xFCUL) \
++	|1UL)
++
++static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
++				       u8 bus, u8 dev_fn, u8 offset)
++{
++	unsigned int caddr;
++
++	if (bus == hose->first_busno) {
++		if (dev_fn < (11 << 3))
++			return 0;
++		caddr = U3_AGP_CFA0(dev_fn, offset);
++	} else
++		caddr = U3_AGP_CFA1(bus, dev_fn, offset);
++
++	/* Uninorth will return garbage if we don't read back the value ! */
++	do {
++		out_le32(hose->cfg_addr, caddr);
++	} while (in_le32(hose->cfg_addr) != caddr);
++
++	offset &= 0x07;
++	return ((unsigned long)hose->cfg_data) + offset;
++}
++
++static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
++			      int offset, int len, u32 *val)
++{
++	struct pci_controller *hose;
++	unsigned long addr;
++
++	hose = pci_bus_to_host(bus);
++	if (hose == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = u3_agp_cfg_access(hose, bus->number, devfn, offset);
++	if (!addr)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	switch (len) {
++	case 1:
++		*val = in_8((u8 *)addr);
++		break;
++	case 2:
++		*val = in_le16((u16 *)addr);
++		break;
++	default:
++		*val = in_le32((u32 *)addr);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
++			       int offset, int len, u32 val)
++{
++	struct pci_controller *hose;
++	unsigned long addr;
++
++	hose = pci_bus_to_host(bus);
++	if (hose == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = u3_agp_cfg_access(hose, bus->number, devfn, offset);
++	if (!addr)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	switch (len) {
++	case 1:
++		out_8((u8 *)addr, val);
++		(void) in_8((u8 *)addr);
++		break;
++	case 2:
++		out_le16((u16 *)addr, val);
++		(void) in_le16((u16 *)addr);
++		break;
++	default:
++		out_le32((u32 *)addr, val);
++		(void) in_le32((u32 *)addr);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops u3_agp_pci_ops =
++{
++	u3_agp_read_config,
++	u3_agp_write_config
++};
++
++
++#define U3_HT_CFA0(devfn, off)		\
++		((((unsigned long)devfn) << 8) | offset)
++#define U3_HT_CFA1(bus, devfn, off)	\
++		(U3_HT_CFA0(devfn, off) \
++		+ (((unsigned long)bus) << 16) \
++		+ 0x01000000UL)
++
++static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
++				      u8 bus, u8 devfn, u8 offset)
++{
++	if (bus == hose->first_busno) {
++		if (PCI_SLOT(devfn) == 0)
++			return 0;
++		return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
++	} else
++		return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
++}
++
++static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
++			     int offset, int len, u32 *val)
++{
++	struct pci_controller *hose;
++	unsigned long addr;
++
++	hose = pci_bus_to_host(bus);
++	if (hose == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
++	if (!addr)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	switch (len) {
++	case 1:
++		*val = in_8((u8 *)addr);
++		break;
++	case 2:
++		*val = in_le16((u16 *)addr);
++		break;
++	default:
++		*val = in_le32((u32 *)addr);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
++			      int offset, int len, u32 val)
++{
++	struct pci_controller *hose;
++	unsigned long addr;
++
++	hose = pci_bus_to_host(bus);
++	if (hose == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
++	if (!addr)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	switch (len) {
++	case 1:
++		out_8((u8 *)addr, val);
++		(void) in_8((u8 *)addr);
++		break;
++	case 2:
++		out_le16((u16 *)addr, val);
++		(void) in_le16((u16 *)addr);
++		break;
++	default:
++		out_le32((u32 *)addr, val);
++		(void) in_le32((u32 *)addr);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops u3_ht_pci_ops =
++{
++	u3_ht_read_config,
++	u3_ht_write_config
++};
++
++static void __init setup_u3_agp(struct pci_controller* hose)
++{
++	/* On G5, we move AGP up to high bus number so we don't need
++	 * to reassign bus numbers for HT. If we ever have P2P bridges
++	 * on AGP, we'll have to move pci_assign_all_buses to the
++	 * pci_controller structure so we enable it for AGP and not for
++	 * HT childs.
++	 * We hard code the address because of the different size of
++	 * the reg address cell, we shall fix that by killing struct
++	 * reg_property and using some accessor functions instead
++	 */
++	hose->first_busno = 0xf0;
++	hose->last_busno = 0xff;
++	hose->ops = &u3_agp_pci_ops;
++	hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
++	hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
++
++	u3_agp = hose;
++}
++
++static void __init setup_u3_ht(struct pci_controller* hose)
++{
++	hose->ops = &u3_ht_pci_ops;
++
++	/* We hard code the address because of the different size of
++	 * the reg address cell, we shall fix that by killing struct
++	 * reg_property and using some accessor functions instead
++	 */
++	hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
++
++	hose->first_busno = 0;
++	hose->last_busno = 0xef;
++
++	u3_ht = hose;
++}
++
++static int __init add_bridge(struct device_node *dev)
++{
++	int len;
++	struct pci_controller *hose;
++	char* disp_name;
++	int *bus_range;
++	int primary = 1;
++	struct property *of_prop;
++
++	DBG("Adding PCI host bridge %s\n", dev->full_name);
++
++	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 = alloc_bootmem(sizeof(struct pci_controller));
++	if (hose == NULL)
++		return -ENOMEM;
++	pci_setup_pci_controller(hose);
++
++	hose->arch_data = dev;
++	hose->first_busno = bus_range ? bus_range[0] : 0;
++	hose->last_busno = bus_range ? bus_range[1] : 0xff;
++
++	of_prop = alloc_bootmem(sizeof(struct property) +
++				sizeof(hose->global_number));
++	if (of_prop) {
++		memset(of_prop, 0, sizeof(struct property));
++		of_prop->name = "linux,pci-domain";
++		of_prop->length = sizeof(hose->global_number);
++		of_prop->value = (unsigned char *)&of_prop[1];
++		memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
++		prom_add_property(dev, of_prop);
++	}
++
++	disp_name = NULL;
++	if (device_is_compatible(dev, "u3-agp")) {
++		setup_u3_agp(hose);
++		disp_name = "U3-AGP";
++		primary = 0;
++	} else if (device_is_compatible(dev, "u3-ht")) {
++		setup_u3_ht(hose);
++		disp_name = "U3-HT";
++		primary = 1;
++	}
++	printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
++		disp_name, 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);
++	pci_setup_phb_io(hose, primary);
++
++	/* Fixup "bus-range" OF property */
++	fixup_bus_range(dev);
++
++	return 0;
++}
++
++
++void __init maple_pcibios_fixup(void)
++{
++	struct pci_dev *dev = NULL;
++
++	DBG(" -> maple_pcibios_fixup\n");
++
++	for_each_pci_dev(dev)
++		pci_read_irq_line(dev);
++
++	/* Do the mapping of the IO space */
++	phbs_remap_io();
++
++	DBG(" <- maple_pcibios_fixup\n");
++}
++
++static void __init maple_fixup_phb_resources(void)
++{
++	struct pci_controller *hose, *tmp;
++	
++	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
++		unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
++		hose->io_resource.start += offset;
++		hose->io_resource.end += offset;
++		printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
++		       hose->global_number,
++		       hose->io_resource.start, hose->io_resource.end);
++	}
++}
++
++void __init maple_pci_init(void)
++{
++	struct device_node *np, *root;
++	struct device_node *ht = NULL;
++
++	/* Probe root PCI hosts, that is on U3 the AGP host and the
++	 * HyperTransport host. That one is actually "kept" around
++	 * and actually added last as it's resource management relies
++	 * on the AGP resources to have been setup first
++	 */
++	root = of_find_node_by_path("/");
++	if (root == NULL) {
++		printk(KERN_CRIT "maple_find_bridges: can't find root of device tree\n");
++		return;
++	}
++	for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
++		if (np->name == NULL)
++			continue;
++		if (strcmp(np->name, "pci") == 0) {
++			if (add_bridge(np) == 0)
++				of_node_get(np);
++		}
++		if (strcmp(np->name, "ht") == 0) {
++			of_node_get(np);
++			ht = np;
++		}
++	}
++	of_node_put(root);
++
++	/* Now setup the HyperTransport host if we found any
++	 */
++	if (ht && add_bridge(ht) != 0)
++		of_node_put(ht);
++
++	/* Fixup the IO resources on our host bridges as the common code
++	 * does it only for childs of the host bridges
++	 */
++	maple_fixup_phb_resources();
++
++	/* Setup the linkage between OF nodes and PHBs */ 
++	pci_devs_phb_init();
++
++	/* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
++	 * assume there is no P2P bridge on the AGP bus, which should be a
++	 * safe assumptions hopefully.
++	 */
++	if (u3_agp) {
++		struct device_node *np = u3_agp->arch_data;
++		PCI_DN(np)->busno = 0xf0;
++		for (np = np->child; np; np = np->sibling)
++			PCI_DN(np)->busno = 0xf0;
++	}
++
++	/* Tell pci.c to use the common resource allocation mecanism */
++	pci_probe_only = 0;
++	
++	/* Allow all IO */
++	io_page_mask = -1;
++}
++
++int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel)
++{
++	struct device_node *np;
++	int irq = channel ? 15 : 14;
++
++	if (pdev->vendor != PCI_VENDOR_ID_AMD ||
++	    pdev->device != PCI_DEVICE_ID_AMD_8111_IDE)
++		return irq;
++
++	np = pci_device_to_OF_node(pdev);
++	if (np == NULL)
++		return irq;
++	if (np->n_intrs < 2)
++		return irq;
++	return np->intrs[channel & 0x1].line;
++}
++
++/* XXX: To remove once all firmwares are ok */
++static void fixup_maple_ide(struct pci_dev* dev)
++{
++#if 0 /* Enable this to enable IDE port 0 */
++	{
++		u8 v;
++
++		pci_read_config_byte(dev, 0x40, &v);
++		v |= 2;
++		pci_write_config_byte(dev, 0x40, v);
++	}
++#endif
++#if 0 /* fix bus master base */
++	pci_write_config_dword(dev, 0x20, 0xcc01);
++	printk("old ide resource: %lx -> %lx \n",
++	       dev->resource[4].start, dev->resource[4].end);
++	dev->resource[4].start = 0xcc00;
++	dev->resource[4].end = 0xcc10;
++#endif
++#if 1 /* Enable this to fixup IDE sense/polarity of irqs in IO-APICs */
++	{
++		struct pci_dev *apicdev;
++		u32 v;
++
++		apicdev = pci_get_slot (dev->bus, PCI_DEVFN(5,0));
++		if (apicdev == NULL)
++			printk("IDE Fixup IRQ: Can't find IO-APIC !\n");
++		else {
++			pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*14);
++			pci_read_config_dword(apicdev, 0xf4, &v);
++			v &= ~0x00000022;
++			pci_write_config_dword(apicdev, 0xf4, v);
++			pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*15);
++			pci_read_config_dword(apicdev, 0xf4, &v);
++			v &= ~0x00000022;
++			pci_write_config_dword(apicdev, 0xf4, v);
++			pci_dev_put(apicdev);
++		}
++	}
++#endif
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE,
++			 fixup_maple_ide);
+diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/maple/setup.c
+@@ -0,0 +1,295 @@
++/*
++ *  Maple (970 eval board) setup code
++ *
++ *  (c) Copyright 2004 Benjamin Herrenschmidt (benh at kernel.crashing.org),
++ *                     IBM Corp. 
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the GNU General Public License
++ *  as published by the Free Software Foundation; either version
++ *  2 of the License, or (at your option) any later version.
++ *
++ */
++
++#define DEBUG
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/stddef.h>
++#include <linux/unistd.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/user.h>
++#include <linux/a.out.h>
++#include <linux/tty.h>
++#include <linux/string.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/major.h>
++#include <linux/initrd.h>
++#include <linux/vt_kern.h>
++#include <linux/console.h>
++#include <linux/ide.h>
++#include <linux/pci.h>
++#include <linux/adb.h>
++#include <linux/cuda.h>
++#include <linux/pmu.h>
++#include <linux/irq.h>
++#include <linux/seq_file.h>
++#include <linux/root_dev.h>
++#include <linux/serial.h>
++#include <linux/smp.h>
++
++#include <asm/processor.h>
++#include <asm/sections.h>
++#include <asm/prom.h>
++#include <asm/system.h>
++#include <asm/pgtable.h>
++#include <asm/bitops.h>
++#include <asm/io.h>
++#include <asm/pci-bridge.h>
++#include <asm/iommu.h>
++#include <asm/machdep.h>
++#include <asm/dma.h>
++#include <asm/cputable.h>
++#include <asm/time.h>
++#include <asm/of_device.h>
++#include <asm/lmb.h>
++#include <asm/mpic.h>
++#include <asm/udbg.h>
++
++#include "maple.h"
++
++#ifdef DEBUG
++#define DBG(fmt...) udbg_printf(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++extern void generic_find_legacy_serial_ports(u64 *physport,
++		unsigned int *default_speed);
++
++static void maple_restart(char *cmd)
++{
++	unsigned int maple_nvram_base;
++	unsigned int maple_nvram_offset;
++	unsigned int maple_nvram_command;
++	struct device_node *rtcs;
++
++	/* find NVRAM device */
++	rtcs = find_compatible_devices("nvram", "AMD8111");
++	if (rtcs && rtcs->addrs) {
++		maple_nvram_base = rtcs->addrs[0].address;
++	} else {
++		printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
++		printk(KERN_EMERG "Maple: Manual Restart Required\n");
++		return;
++	}
++
++	/* find service processor device */
++	rtcs = find_devices("service-processor");
++	if (!rtcs) {
++		printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
++		printk(KERN_EMERG "Maple: Manual Restart Required\n");
++		return;
++	}
++	maple_nvram_offset = *(unsigned int*) get_property(rtcs,
++			"restart-addr", NULL);
++	maple_nvram_command = *(unsigned int*) get_property(rtcs,
++			"restart-value", NULL);
++
++	/* send command */
++	outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
++	for (;;) ;
++}
++
++static void maple_power_off(void)
++{
++	unsigned int maple_nvram_base;
++	unsigned int maple_nvram_offset;
++	unsigned int maple_nvram_command;
++	struct device_node *rtcs;
++
++	/* find NVRAM device */
++	rtcs = find_compatible_devices("nvram", "AMD8111");
++	if (rtcs && rtcs->addrs) {
++		maple_nvram_base = rtcs->addrs[0].address;
++	} else {
++		printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
++		printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
++		return;
++	}
++
++	/* find service processor device */
++	rtcs = find_devices("service-processor");
++	if (!rtcs) {
++		printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
++		printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
++		return;
++	}
++	maple_nvram_offset = *(unsigned int*) get_property(rtcs,
++			"power-off-addr", NULL);
++	maple_nvram_command = *(unsigned int*) get_property(rtcs,
++			"power-off-value", NULL);
++
++	/* send command */
++	outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
++	for (;;) ;
++}
++
++static void maple_halt(void)
++{
++	maple_power_off();
++}
++
++#ifdef CONFIG_SMP
++struct smp_ops_t maple_smp_ops = {
++	.probe		= smp_mpic_probe,
++	.message_pass	= smp_mpic_message_pass,
++	.kick_cpu	= smp_generic_kick_cpu,
++	.setup_cpu	= smp_mpic_setup_cpu,
++	.give_timebase	= smp_generic_give_timebase,
++	.take_timebase	= smp_generic_take_timebase,
++};
++#endif /* CONFIG_SMP */
++
++void __init maple_setup_arch(void)
++{
++	/* init to some ~sane value until calibrate_delay() runs */
++	loops_per_jiffy = 50000000;
++
++	/* Setup SMP callback */
++#ifdef CONFIG_SMP
++	smp_ops = &maple_smp_ops;
++#endif
++	/* Lookup PCI hosts */
++       	maple_pci_init();
++
++#ifdef CONFIG_DUMMY_CONSOLE
++	conswitchp = &dummy_con;
++#endif
++
++	printk(KERN_INFO "Using native/NAP idle loop\n");
++}
++
++/* 
++ * Early initialization.
++ */
++static void __init maple_init_early(void)
++{
++	unsigned int default_speed;
++	u64 physport;
++
++	DBG(" -> maple_init_early\n");
++
++	/* Initialize hash table, from now on, we can take hash faults
++	 * and call ioremap
++	 */
++	hpte_init_native();
++
++	/* Find the serial port */
++	generic_find_legacy_serial_ports(&physport, &default_speed);
++
++	DBG("phys port addr: %lx\n", (long)physport);
++
++	if (physport) {
++		void *comport;
++		/* Map the uart for udbg. */
++		comport = (void *)ioremap(physport, 16);
++		udbg_init_uart(comport, default_speed);
++
++		DBG("Hello World !\n");
++	}
++
++	/* Setup interrupt mapping options */
++	ppc64_interrupt_controller = IC_OPEN_PIC;
++
++	iommu_init_early_u3();
++
++	DBG(" <- maple_init_early\n");
++}
++
++
++static __init void maple_init_IRQ(void)
++{
++	struct device_node *root;
++	unsigned int *opprop;
++	unsigned long opic_addr;
++	struct mpic *mpic;
++	unsigned char senses[128];
++	int n;
++
++	DBG(" -> maple_init_IRQ\n");
++
++	/* XXX: Non standard, replace that with a proper openpic/mpic node
++	 * in the device-tree. Find the Open PIC if present */
++	root = of_find_node_by_path("/");
++	opprop = (unsigned int *) get_property(root,
++				"platform-open-pic", NULL);
++	if (opprop == 0)
++		panic("OpenPIC not found !\n");
++
++	n = prom_n_addr_cells(root);
++	for (opic_addr = 0; n > 0; --n)
++		opic_addr = (opic_addr << 32) + *opprop++;
++	of_node_put(root);
++
++	/* Obtain sense values from device-tree */
++	prom_get_irq_senses(senses, 0, 128);
++
++	mpic = mpic_alloc(opic_addr,
++			  MPIC_PRIMARY | MPIC_BIG_ENDIAN |
++			  MPIC_BROKEN_U3 | MPIC_WANTS_RESET,
++			  0, 0, 128, 128, senses, 128, "U3-MPIC");
++	BUG_ON(mpic == NULL);
++	mpic_init(mpic);
++
++	DBG(" <- maple_init_IRQ\n");
++}
++
++static void __init maple_progress(char *s, unsigned short hex)
++{
++	printk("*** %04x : %s\n", hex, s ? s : "");
++}
++
++
++/*
++ * Called very early, MMU is off, device-tree isn't unflattened
++ */
++static int __init maple_probe(int platform)
++{
++	if (platform != PLATFORM_MAPLE)
++		return 0;
++	/*
++	 * On U3, the DART (iommu) must be allocated now since it
++	 * has an impact on htab_initialize (due to the large page it
++	 * occupies having to be broken up so the DART itself is not
++	 * part of the cacheable linar mapping
++	 */
++	alloc_u3_dart_table();
++
++	return 1;
++}
++
++struct machdep_calls __initdata maple_md = {
++	.probe			= maple_probe,
++	.setup_arch		= maple_setup_arch,
++	.init_early		= maple_init_early,
++	.init_IRQ		= maple_init_IRQ,
++	.get_irq		= mpic_get_irq,
++	.pcibios_fixup		= maple_pcibios_fixup,
++	.pci_get_legacy_ide_irq	= maple_pci_get_legacy_ide_irq,
++	.restart		= maple_restart,
++	.power_off		= maple_power_off,
++	.halt			= maple_halt,
++       	.get_boot_time		= maple_get_boot_time,
++       	.set_rtc_time		= maple_set_rtc_time,
++       	.get_rtc_time		= maple_get_rtc_time,
++      	.calibrate_decr		= generic_calibrate_decr,
++	.progress		= maple_progress,
++	.idle_loop		= native_idle,
++};
+diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/maple/time.c
+@@ -0,0 +1,180 @@
++/*
++ *  arch/ppc64/kernel/maple_time.c
++ *
++ *  (c) Copyright 2004 Benjamin Herrenschmidt (benh at kernel.crashing.org),
++ *                     IBM Corp. 
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the GNU General Public License
++ *  as published by the Free Software Foundation; either version
++ *  2 of the License, or (at your option) any later version.
++ *
++ */
++
++#undef DEBUG
++
++#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/param.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/time.h>
++#include <linux/adb.h>
++#include <linux/pmu.h>
++#include <linux/interrupt.h>
++#include <linux/mc146818rtc.h>
++#include <linux/bcd.h>
++
++#include <asm/sections.h>
++#include <asm/prom.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/machdep.h>
++#include <asm/time.h>
++
++#include "maple.h"
++
++#ifdef DEBUG
++#define DBG(x...) printk(x)
++#else
++#define DBG(x...)
++#endif
++
++extern void GregorianDay(struct rtc_time * tm);
++
++static int maple_rtc_addr;
++
++static int maple_clock_read(int addr)
++{
++	outb_p(addr, maple_rtc_addr);
++	return inb_p(maple_rtc_addr+1);
++}
++
++static void maple_clock_write(unsigned long val, int addr)
++{
++	outb_p(addr, maple_rtc_addr);
++	outb_p(val, maple_rtc_addr+1);
++}
++
++void maple_get_rtc_time(struct rtc_time *tm)
++{
++	int uip, i;
++
++	/* The Linux interpretation of the CMOS clock register contents:
++	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
++	 * RTC registers show the second which has precisely just started.
++	 * Let's hope other operating systems interpret the RTC the same way.
++	 */
++
++	/* Since the UIP flag is set for about 2.2 ms and the clock
++	 * is typically written with a precision of 1 jiffy, trying
++	 * to obtain a precision better than a few milliseconds is
++	 * an illusion. Only consistency is interesting, this also
++	 * allows to use the routine for /dev/rtc without a potential
++	 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
++	 */
++
++	for (i = 0; i<1000000; i++) {
++		uip = maple_clock_read(RTC_FREQ_SELECT);
++		tm->tm_sec = maple_clock_read(RTC_SECONDS);
++		tm->tm_min = maple_clock_read(RTC_MINUTES);
++		tm->tm_hour = maple_clock_read(RTC_HOURS);
++		tm->tm_mday = maple_clock_read(RTC_DAY_OF_MONTH);
++		tm->tm_mon = maple_clock_read(RTC_MONTH);
++		tm->tm_year = maple_clock_read(RTC_YEAR);
++		uip |= maple_clock_read(RTC_FREQ_SELECT);
++		if ((uip & RTC_UIP)==0)
++			break;
++	}
++
++	if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY)
++	    || RTC_ALWAYS_BCD) {
++		BCD_TO_BIN(tm->tm_sec);
++		BCD_TO_BIN(tm->tm_min);
++		BCD_TO_BIN(tm->tm_hour);
++		BCD_TO_BIN(tm->tm_mday);
++		BCD_TO_BIN(tm->tm_mon);
++		BCD_TO_BIN(tm->tm_year);
++	  }
++	if ((tm->tm_year + 1900) < 1970)
++		tm->tm_year += 100;
++
++	GregorianDay(tm);
++}
++
++int maple_set_rtc_time(struct rtc_time *tm)
++{
++	unsigned char save_control, save_freq_select;
++	int sec, min, hour, mon, mday, year;
++
++	spin_lock(&rtc_lock);
++
++	save_control = maple_clock_read(RTC_CONTROL); /* tell the clock it's being set */
++
++	maple_clock_write((save_control|RTC_SET), RTC_CONTROL);
++
++	save_freq_select = maple_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
++
++	maple_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
++
++	sec = tm->tm_sec;
++	min = tm->tm_min;
++	hour = tm->tm_hour;
++	mon = tm->tm_mon;
++	mday = tm->tm_mday;
++	year = tm->tm_year;
++
++	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
++		BIN_TO_BCD(sec);
++		BIN_TO_BCD(min);
++		BIN_TO_BCD(hour);
++		BIN_TO_BCD(mon);
++		BIN_TO_BCD(mday);
++		BIN_TO_BCD(year);
++	}
++	maple_clock_write(sec, RTC_SECONDS);
++	maple_clock_write(min, RTC_MINUTES);
++	maple_clock_write(hour, RTC_HOURS);
++	maple_clock_write(mon, RTC_MONTH);
++	maple_clock_write(mday, RTC_DAY_OF_MONTH);
++	maple_clock_write(year, RTC_YEAR);
++
++	/* The following flags have to be released exactly in this order,
++	 * otherwise the DS12887 (popular MC146818A clone with integrated
++	 * battery and quartz) will not reset the oscillator and will not
++	 * update precisely 500 ms later. You won't find this mentioned in
++	 * the Dallas Semiconductor data sheets, but who believes data
++	 * sheets anyway ...                           -- Markus Kuhn
++	 */
++	maple_clock_write(save_control, RTC_CONTROL);
++	maple_clock_write(save_freq_select, RTC_FREQ_SELECT);
++
++	spin_unlock(&rtc_lock);
++
++	return 0;
++}
++
++unsigned long __init maple_get_boot_time(void)
++{
++	struct rtc_time tm;
++	struct device_node *rtcs;
++
++	rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
++	if (rtcs && rtcs->addrs) {
++		maple_rtc_addr = rtcs->addrs[0].address;
++		printk(KERN_INFO "Maple: Found RTC at 0x%x\n", maple_rtc_addr);
++	} else {
++		maple_rtc_addr = RTC_PORT(0); /* legacy address */
++		printk(KERN_INFO "Maple: No device node for RTC, assuming "
++		       "legacy address (0x%x)\n", maple_rtc_addr);
++	}
++	
++	maple_get_rtc_time(&tm);
++	return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
++		      tm.tm_hour, tm.tm_min, tm.tm_sec);
++}
++
+diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/Makefile
+@@ -0,0 +1,8 @@
++obj-y				+= pic.o setup.o time.o feature.o pci.o \
++				   sleep.o low_i2c.o cache.o
++obj-$(CONFIG_PMAC_BACKLIGHT)	+= backlight.o
++obj-$(CONFIG_CPU_FREQ_PMAC)	+= cpufreq.o
++obj-$(CONFIG_NVRAM)		+= nvram.o
++# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
++obj-$(CONFIG_PPC64)		+= nvram.o
++obj-$(CONFIG_SMP)		+= smp.o
+diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/backlight.c
+@@ -0,0 +1,202 @@
++/*
++ * Miscellaneous procedures for dealing with the PowerMac hardware.
++ * Contains support for the backlight.
++ *
++ *   Copyright (C) 2000 Benjamin Herrenschmidt
++ *
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/stddef.h>
++#include <linux/reboot.h>
++#include <linux/nvram.h>
++#include <linux/console.h>
++#include <asm/sections.h>
++#include <asm/ptrace.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/system.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++#include <asm/nvram.h>
++#include <asm/backlight.h>
++
++#include <linux/adb.h>
++#include <linux/pmu.h>
++
++static struct backlight_controller *backlighter;
++static void* backlighter_data;
++static int backlight_autosave;
++static int backlight_level = BACKLIGHT_MAX;
++static int backlight_enabled = 1;
++static int backlight_req_level = -1;
++static int backlight_req_enable = -1;
++
++static void backlight_callback(void *);
++static DECLARE_WORK(backlight_work, backlight_callback, NULL);
++
++void register_backlight_controller(struct backlight_controller *ctrler,
++					  void *data, char *type)
++{
++	struct device_node* bk_node;
++	char *prop;
++	int valid = 0;
++
++	/* There's already a matching controller, bail out */
++	if (backlighter != NULL)
++		return;
++
++	bk_node = find_devices("backlight");
++
++#ifdef CONFIG_ADB_PMU
++	/* Special case for the old PowerBook since I can't test on it */
++	backlight_autosave = machine_is_compatible("AAPL,3400/2400")
++		|| machine_is_compatible("AAPL,3500");
++	if ((backlight_autosave
++	     || machine_is_compatible("AAPL,PowerBook1998")
++	     || machine_is_compatible("PowerBook1,1"))
++	    && !strcmp(type, "pmu"))
++		valid = 1;
++#endif
++	if (bk_node) {
++		prop = get_property(bk_node, "backlight-control", NULL);
++		if (prop && !strncmp(prop, type, strlen(type)))
++			valid = 1;
++	}
++	if (!valid)
++		return;
++	backlighter = ctrler;
++	backlighter_data = data;
++
++	if (bk_node && !backlight_autosave)
++		prop = get_property(bk_node, "bklt", NULL);
++	else
++		prop = NULL;
++	if (prop) {
++		backlight_level = ((*prop)+1) >> 1;
++		if (backlight_level > BACKLIGHT_MAX)
++			backlight_level = BACKLIGHT_MAX;
++	}
++
++#ifdef CONFIG_ADB_PMU
++	if (backlight_autosave) {
++		struct adb_request req;
++		pmu_request(&req, NULL, 2, 0xd9, 0);
++		while (!req.complete)
++			pmu_poll();
++		backlight_level = req.reply[0] >> 4;
++	}
++#endif
++	acquire_console_sem();
++	if (!backlighter->set_enable(1, backlight_level, data))
++		backlight_enabled = 1;
++	release_console_sem();
++
++	printk(KERN_INFO "Registered \"%s\" backlight controller,"
++	       "level: %d/15\n", type, backlight_level);
++}
++EXPORT_SYMBOL(register_backlight_controller);
++
++void unregister_backlight_controller(struct backlight_controller
++					    *ctrler, void *data)
++{
++	/* We keep the current backlight level (for now) */
++	if (ctrler == backlighter && data == backlighter_data)
++		backlighter = NULL;
++}
++EXPORT_SYMBOL(unregister_backlight_controller);
++
++static int __set_backlight_enable(int enable)
++{
++	int rc;
++
++	if (!backlighter)
++		return -ENODEV;
++	acquire_console_sem();
++	rc = backlighter->set_enable(enable, backlight_level,
++				     backlighter_data);
++	if (!rc)
++		backlight_enabled = enable;
++	release_console_sem();
++	return rc;
++}
++int set_backlight_enable(int enable)
++{
++	if (!backlighter)
++		return -ENODEV;
++	backlight_req_enable = enable;
++	schedule_work(&backlight_work);
++	return 0;
++}
++
++EXPORT_SYMBOL(set_backlight_enable);
++
++int get_backlight_enable(void)
++{
++	if (!backlighter)
++		return -ENODEV;
++	return backlight_enabled;
++}
++EXPORT_SYMBOL(get_backlight_enable);
++
++static int __set_backlight_level(int level)
++{
++	int rc = 0;
++
++	if (!backlighter)
++		return -ENODEV;
++	if (level < BACKLIGHT_MIN)
++		level = BACKLIGHT_OFF;
++	if (level > BACKLIGHT_MAX)
++		level = BACKLIGHT_MAX;
++	acquire_console_sem();
++	if (backlight_enabled)
++		rc = backlighter->set_level(level, backlighter_data);
++	if (!rc)
++		backlight_level = level;
++	release_console_sem();
++	if (!rc && !backlight_autosave) {
++		level <<=1;
++		if (level & 0x10)
++			level |= 0x01;
++		// -- todo: save to property "bklt"
++	}
++	return rc;
++}
++int set_backlight_level(int level)
++{
++	if (!backlighter)
++		return -ENODEV;
++	backlight_req_level = level;
++	schedule_work(&backlight_work);
++	return 0;
++}
++
++EXPORT_SYMBOL(set_backlight_level);
++
++int get_backlight_level(void)
++{
++	if (!backlighter)
++		return -ENODEV;
++	return backlight_level;
++}
++EXPORT_SYMBOL(get_backlight_level);
++
++static void backlight_callback(void *dummy)
++{
++	int level, enable;
++
++	do {
++		level = backlight_req_level;
++		enable = backlight_req_enable;
++		mb();
++
++		if (level >= 0)
++			__set_backlight_level(level);
++		if (enable >= 0)
++			__set_backlight_enable(enable);
++	} while(cmpxchg(&backlight_req_level, level, -1) != level ||
++		cmpxchg(&backlight_req_enable, enable, -1) != enable);
++}
+diff --git a/arch/powerpc/platforms/powermac/cache.S b/arch/powerpc/platforms/powermac/cache.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/cache.S
+@@ -0,0 +1,359 @@
++/*
++ * This file contains low-level cache management functions
++ * used for sleep and CPU speed changes on Apple machines.
++ * (In fact the only thing that is Apple-specific is that we assume
++ * that we can read from ROM at physical address 0xfff00000.)
++ *
++ *    Copyright (C) 2004 Paul Mackerras (paulus at samba.org) and
++ *                       Benjamin Herrenschmidt (benh at 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/config.h>
++#include <asm/processor.h>
++#include <asm/ppc_asm.h>
++#include <asm/cputable.h>
++
++/*
++ * Flush and disable all data caches (dL1, L2, L3). This is used
++ * when going to sleep, when doing a PMU based cpufreq transition,
++ * or when "offlining" a CPU on SMP machines. This code is over
++ * paranoid, but I've had enough issues with various CPU revs and
++ * bugs that I decided it was worth beeing over cautious
++ */
++
++_GLOBAL(flush_disable_caches)
++#ifndef CONFIG_6xx
++	blr
++#else
++BEGIN_FTR_SECTION
++	b	flush_disable_745x
++END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
++BEGIN_FTR_SECTION
++	b	flush_disable_75x
++END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
++	b	__flush_disable_L1
++
++/* This is the code for G3 and 74[01]0 */
++flush_disable_75x:
++	mflr	r10
++
++	/* Turn off EE and DR in MSR */
++	mfmsr	r11
++	rlwinm	r0,r11,0,~MSR_EE
++	rlwinm	r0,r0,0,~MSR_DR
++	sync
++	mtmsr	r0
++	isync
++
++	/* Stop DST streams */
++BEGIN_FTR_SECTION
++	DSSALL
++	sync
++END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
++
++	/* Stop DPM */
++	mfspr	r8,SPRN_HID0		/* Save SPRN_HID0 in r8 */
++	rlwinm	r4,r8,0,12,10		/* Turn off HID0[DPM] */
++	sync
++	mtspr	SPRN_HID0,r4		/* Disable DPM */
++	sync
++
++	/* Disp-flush L1. We have a weird problem here that I never
++	 * totally figured out. On 750FX, using the ROM for the flush
++	 * results in a non-working flush. We use that workaround for
++	 * now until I finally understand what's going on. --BenH
++	 */
++
++	/* ROM base by default */
++	lis	r4,0xfff0
++	mfpvr	r3
++	srwi	r3,r3,16
++	cmplwi	cr0,r3,0x7000
++	bne+	1f
++	/* RAM base on 750FX */
++	li	r4,0
++1:	li	r4,0x4000
++	mtctr	r4
++1:	lwz	r0,0(r4)
++	addi	r4,r4,32
++	bdnz	1b
++	sync
++	isync
++
++	/* Disable / invalidate / enable L1 data */
++	mfspr	r3,SPRN_HID0
++	rlwinm	r3,r3,0,~(HID0_DCE | HID0_ICE)
++	mtspr	SPRN_HID0,r3
++	sync
++	isync
++	ori	r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
++	sync
++	isync
++	mtspr	SPRN_HID0,r3
++	xori	r3,r3,(HID0_DCI|HID0_ICFI)
++	mtspr	SPRN_HID0,r3
++	sync
++
++	/* Get the current enable bit of the L2CR into r4 */
++	mfspr	r5,SPRN_L2CR
++	/* Set to data-only (pre-745x bit) */
++	oris	r3,r5,L2CR_L2DO at h
++	b	2f
++	/* When disabling L2, code must be in L1 */
++	.balign 32
++1:	mtspr	SPRN_L2CR,r3
++3:	sync
++	isync
++	b	1f
++2:	b	3f
++3:	sync
++	isync
++	b	1b
++1:	/* disp-flush L2. The interesting thing here is that the L2 can be
++	 * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
++	 * but that is probbaly fine. We disp-flush over 4Mb to be safe
++	 */
++	lis	r4,2
++	mtctr	r4
++	lis	r4,0xfff0
++1:	lwz	r0,0(r4)
++	addi	r4,r4,32
++	bdnz	1b
++	sync
++	isync
++	lis	r4,2
++	mtctr	r4
++	lis	r4,0xfff0
++1:	dcbf	0,r4
++	addi	r4,r4,32
++	bdnz	1b
++	sync
++	isync
++
++	/* now disable L2 */
++	rlwinm	r5,r5,0,~L2CR_L2E
++	b	2f
++	/* When disabling L2, code must be in L1 */
++	.balign 32
++1:	mtspr	SPRN_L2CR,r5
++3:	sync
++	isync
++	b	1f
++2:	b	3f
++3:	sync
++	isync
++	b	1b
++1:	sync
++	isync
++	/* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
++	oris	r4,r5,L2CR_L2I at h
++	mtspr	SPRN_L2CR,r4
++	sync
++	isync
++
++	/* Wait for the invalidation to complete */
++1:	mfspr	r3,SPRN_L2CR
++	rlwinm.	r0,r3,0,31,31
++	bne	1b
++
++	/* Clear L2I */
++	xoris	r4,r4,L2CR_L2I at h
++	sync
++	mtspr	SPRN_L2CR,r4
++	sync
++
++	/* now disable the L1 data cache */
++	mfspr	r0,SPRN_HID0
++	rlwinm	r0,r0,0,~(HID0_DCE|HID0_ICE)
++	mtspr	SPRN_HID0,r0
++	sync
++	isync
++
++	/* Restore HID0[DPM] to whatever it was before */
++	sync
++	mfspr	r0,SPRN_HID0
++	rlwimi	r0,r8,0,11,11		/* Turn back HID0[DPM] */
++	mtspr	SPRN_HID0,r0
++	sync
++
++	/* restore DR and EE */
++	sync
++	mtmsr	r11
++	isync
++
++	mtlr	r10
++	blr
++
++/* This code is for 745x processors */
++flush_disable_745x:
++	/* Turn off EE and DR in MSR */
++	mfmsr	r11
++	rlwinm	r0,r11,0,~MSR_EE
++	rlwinm	r0,r0,0,~MSR_DR
++	sync
++	mtmsr	r0
++	isync
++
++	/* Stop prefetch streams */
++	DSSALL
++	sync
++
++	/* Disable L2 prefetching */
++	mfspr	r0,SPRN_MSSCR0
++	rlwinm	r0,r0,0,0,29
++	mtspr	SPRN_MSSCR0,r0
++	sync
++	isync
++	lis	r4,0
++	dcbf	0,r4
++	dcbf	0,r4
++	dcbf	0,r4
++	dcbf	0,r4
++	dcbf	0,r4
++	dcbf	0,r4
++	dcbf	0,r4
++	dcbf	0,r4
++
++	/* Due to a bug with the HW flush on some CPU revs, we occasionally
++	 * experience data corruption. I'm adding a displacement flush along
++	 * with a dcbf loop over a few Mb to "help". The problem isn't totally
++	 * fixed by this in theory, but at least, in practice, I couldn't reproduce
++	 * it even with a big hammer...
++	 */
++
++        lis     r4,0x0002
++        mtctr   r4
++ 	li      r4,0
++1:
++        lwz     r0,0(r4)
++        addi    r4,r4,32                /* Go to start of next cache line */
++        bdnz    1b
++        isync
++
++        /* Now, flush the first 4MB of memory */
++        lis     r4,0x0002
++        mtctr   r4
++	li      r4,0
++        sync
++1:
++        dcbf    0,r4
++        addi    r4,r4,32                /* Go to start of next cache line */
++        bdnz    1b
++
++	/* Flush and disable the L1 data cache */
++	mfspr	r6,SPRN_LDSTCR
++	lis	r3,0xfff0	/* read from ROM for displacement flush */
++	li	r4,0xfe		/* start with only way 0 unlocked */
++	li	r5,128		/* 128 lines in each way */
++1:	mtctr	r5
++	rlwimi	r6,r4,0,24,31
++	mtspr	SPRN_LDSTCR,r6
++	sync
++	isync
++2:	lwz	r0,0(r3)	/* touch each cache line */
++	addi	r3,r3,32
++	bdnz	2b
++	rlwinm	r4,r4,1,24,30	/* move on to the next way */
++	ori	r4,r4,1
++	cmpwi	r4,0xff		/* all done? */
++	bne	1b
++	/* now unlock the L1 data cache */
++	li	r4,0
++	rlwimi	r6,r4,0,24,31
++	sync
++	mtspr	SPRN_LDSTCR,r6
++	sync
++	isync
++
++	/* Flush the L2 cache using the hardware assist */
++	mfspr	r3,SPRN_L2CR
++	cmpwi	r3,0		/* check if it is enabled first */
++	bge	4f
++	oris	r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
++	b	2f
++	/* When disabling/locking L2, code must be in L1 */
++	.balign 32
++1:	mtspr	SPRN_L2CR,r0	/* lock the L2 cache */
++3:	sync
++	isync
++	b	1f
++2:	b	3f
++3:	sync
++	isync
++	b	1b
++1:	sync
++	isync
++	ori	r0,r3,L2CR_L2HWF_745x
++	sync
++	mtspr	SPRN_L2CR,r0	/* set the hardware flush bit */
++3:	mfspr	r0,SPRN_L2CR	/* wait for it to go to 0 */
++	andi.	r0,r0,L2CR_L2HWF_745x
++	bne	3b
++	sync
++	rlwinm	r3,r3,0,~L2CR_L2E
++	b	2f
++	/* When disabling L2, code must be in L1 */
++	.balign 32
++1:	mtspr	SPRN_L2CR,r3	/* disable the L2 cache */
++3:	sync
++	isync
++	b	1f
++2:	b	3f
++3:	sync
++	isync
++	b	1b
++1:	sync
++	isync
++	oris	r4,r3,L2CR_L2I at h
++	mtspr	SPRN_L2CR,r4
++	sync
++	isync
++1:	mfspr	r4,SPRN_L2CR
++	andis.	r0,r4,L2CR_L2I at h
++	bne	1b
++	sync
++
++BEGIN_FTR_SECTION
++	/* Flush the L3 cache using the hardware assist */
++4:	mfspr	r3,SPRN_L3CR
++	cmpwi	r3,0		/* check if it is enabled */
++	bge	6f
++	oris	r0,r3,L3CR_L3IO at h
++	ori	r0,r0,L3CR_L3DO
++	sync
++	mtspr	SPRN_L3CR,r0	/* lock the L3 cache */
++	sync
++	isync
++	ori	r0,r0,L3CR_L3HWF
++	sync
++	mtspr	SPRN_L3CR,r0	/* set the hardware flush bit */
++5:	mfspr	r0,SPRN_L3CR	/* wait for it to go to zero */
++	andi.	r0,r0,L3CR_L3HWF
++	bne	5b
++	rlwinm	r3,r3,0,~L3CR_L3E
++	sync
++	mtspr	SPRN_L3CR,r3	/* disable the L3 cache */
++	sync
++	ori	r4,r3,L3CR_L3I
++	mtspr	SPRN_L3CR,r4
++1:	mfspr	r4,SPRN_L3CR
++	andi.	r0,r4,L3CR_L3I
++	bne	1b
++	sync
++END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
++
++6:	mfspr	r0,SPRN_HID0	/* now disable the L1 data cache */
++	rlwinm	r0,r0,0,~HID0_DCE
++	mtspr	SPRN_HID0,r0
++	sync
++	isync
++	mtmsr	r11		/* restore DR and EE */
++	isync
++	blr
++#endif	/* CONFIG_6xx */
+diff --git a/arch/powerpc/platforms/powermac/cpufreq.c b/arch/powerpc/platforms/powermac/cpufreq.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/cpufreq.c
+@@ -0,0 +1,726 @@
++/*
++ *  arch/ppc/platforms/pmac_cpufreq.c
++ *
++ *  Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh at kernel.crashing.org>
++ *  Copyright (C) 2004        John Steele Scott <toojays at toojays.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.
++ *
++ * TODO: Need a big cleanup here. Basically, we need to have different
++ * cpufreq_driver structures for the different type of HW instead of the
++ * current mess. We also need to better deal with the detection of the
++ * type of machine.
++ *
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/adb.h>
++#include <linux/pmu.h>
++#include <linux/slab.h>
++#include <linux/cpufreq.h>
++#include <linux/init.h>
++#include <linux/sysdev.h>
++#include <linux/i2c.h>
++#include <linux/hardirq.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++#include <asm/irq.h>
++#include <asm/pmac_feature.h>
++#include <asm/mmu_context.h>
++#include <asm/sections.h>
++#include <asm/cputable.h>
++#include <asm/time.h>
++#include <asm/system.h>
++#include <asm/mpic.h>
++#include <asm/keylargo.h>
++
++/* WARNING !!! This will cause calibrate_delay() to be called,
++ * but this is an __init function ! So you MUST go edit
++ * init/main.c to make it non-init before enabling DEBUG_FREQ
++ */
++#undef DEBUG_FREQ
++
++/*
++ * There is a problem with the core cpufreq code on SMP kernels,
++ * it won't recalculate the Bogomips properly
++ */
++#ifdef CONFIG_SMP
++#warning "WARNING, CPUFREQ not recommended on SMP kernels"
++#endif
++
++extern void low_choose_7447a_dfs(int dfs);
++extern void low_choose_750fx_pll(int pll);
++extern void low_sleep_handler(void);
++
++/*
++ * Currently, PowerMac cpufreq supports only high & low frequencies
++ * that are set by the firmware
++ */
++static unsigned int low_freq;
++static unsigned int hi_freq;
++static unsigned int cur_freq;
++static unsigned int sleep_freq;
++
++/*
++ * Different models uses different mecanisms to switch the frequency
++ */
++static int (*set_speed_proc)(int low_speed);
++static unsigned int (*get_speed_proc)(void);
++
++/*
++ * Some definitions used by the various speedprocs
++ */
++static u32 voltage_gpio;
++static u32 frequency_gpio;
++static u32 slew_done_gpio;
++static int no_schedule;
++static int has_cpu_l2lve;
++static int is_pmu_based;
++
++/* There are only two frequency states for each processor. Values
++ * are in kHz for the time being.
++ */
++#define CPUFREQ_HIGH                  0
++#define CPUFREQ_LOW                   1
++
++static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
++	{CPUFREQ_HIGH, 		0},
++	{CPUFREQ_LOW,		0},
++	{0,			CPUFREQ_TABLE_END},
++};
++
++static struct freq_attr* pmac_cpu_freqs_attr[] = {
++	&cpufreq_freq_attr_scaling_available_freqs,
++	NULL,
++};
++
++static inline void local_delay(unsigned long ms)
++{
++	if (no_schedule)
++		mdelay(ms);
++	else
++		msleep(ms);
++}
++
++#ifdef DEBUG_FREQ
++static inline void debug_calc_bogomips(void)
++{
++	/* This will cause a recalc of bogomips and display the
++	 * result. We backup/restore the value to avoid affecting the
++	 * core cpufreq framework's own calculation.
++	 */
++	extern void calibrate_delay(void);
++
++	unsigned long save_lpj = loops_per_jiffy;
++	calibrate_delay();
++	loops_per_jiffy = save_lpj;
++}
++#endif /* DEBUG_FREQ */
++
++/* Switch CPU speed under 750FX CPU control
++ */
++static int cpu_750fx_cpu_speed(int low_speed)
++{
++	u32 hid2;
++
++	if (low_speed == 0) {
++		/* ramping up, set voltage first */
++		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
++		/* Make sure we sleep for at least 1ms */
++		local_delay(10);
++
++		/* tweak L2 for high voltage */
++		if (has_cpu_l2lve) {
++			hid2 = mfspr(SPRN_HID2);
++			hid2 &= ~0x2000;
++			mtspr(SPRN_HID2, hid2);
++		}
++	}
++#ifdef CONFIG_6xx
++	low_choose_750fx_pll(low_speed);
++#endif
++	if (low_speed == 1) {
++		/* tweak L2 for low voltage */
++		if (has_cpu_l2lve) {
++			hid2 = mfspr(SPRN_HID2);
++			hid2 |= 0x2000;
++			mtspr(SPRN_HID2, hid2);
++		}
++
++		/* ramping down, set voltage last */
++		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
++		local_delay(10);
++	}
++
++	return 0;
++}
++
++static unsigned int cpu_750fx_get_cpu_speed(void)
++{
++	if (mfspr(SPRN_HID1) & HID1_PS)
++		return low_freq;
++	else
++		return hi_freq;
++}
++
++/* Switch CPU speed using DFS */
++static int dfs_set_cpu_speed(int low_speed)
++{
++	if (low_speed == 0) {
++		/* ramping up, set voltage first */
++		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
++		/* Make sure we sleep for at least 1ms */
++		local_delay(1);
++	}
++
++	/* set frequency */
++#ifdef CONFIG_6xx
++	low_choose_7447a_dfs(low_speed);
++#endif
++	udelay(100);
++
++	if (low_speed == 1) {
++		/* ramping down, set voltage last */
++		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
++		local_delay(1);
++	}
++
++	return 0;
++}
++
++static unsigned int dfs_get_cpu_speed(void)
++{
++	if (mfspr(SPRN_HID1) & HID1_DFS)
++		return low_freq;
++	else
++		return hi_freq;
++}
++
++
++/* Switch CPU speed using slewing GPIOs
++ */
++static int gpios_set_cpu_speed(int low_speed)
++{
++	int gpio, timeout = 0;
++
++	/* If ramping up, set voltage first */
++	if (low_speed == 0) {
++		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
++		/* Delay is way too big but it's ok, we schedule */
++		local_delay(10);
++	}
++
++	/* Set frequency */
++	gpio = 	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
++	if (low_speed == ((gpio & 0x01) == 0))
++		goto skip;
++
++	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
++			  low_speed ? 0x04 : 0x05);
++	udelay(200);
++	do {
++		if (++timeout > 100)
++			break;
++		local_delay(1);
++		gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
++	} while((gpio & 0x02) == 0);
++ skip:
++	/* If ramping down, set voltage last */
++	if (low_speed == 1) {
++		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
++		/* Delay is way too big but it's ok, we schedule */
++		local_delay(10);
++	}
++
++#ifdef DEBUG_FREQ
++	debug_calc_bogomips();
++#endif
++
++	return 0;
++}
++
++/* Switch CPU speed under PMU control
++ */
++static int pmu_set_cpu_speed(int low_speed)
++{
++	struct adb_request req;
++	unsigned long save_l2cr;
++	unsigned long save_l3cr;
++	unsigned int pic_prio;
++	unsigned long flags;
++
++	preempt_disable();
++
++#ifdef DEBUG_FREQ
++	printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
++#endif
++	pmu_suspend();
++
++	/* Disable all interrupt sources on openpic */
++ 	pic_prio = mpic_cpu_get_priority();
++	mpic_cpu_set_priority(0xf);
++
++	/* Make sure the decrementer won't interrupt us */
++	asm volatile("mtdec %0" : : "r" (0x7fffffff));
++	/* Make sure any pending DEC interrupt occuring while we did
++	 * the above didn't re-enable the DEC */
++	mb();
++	asm volatile("mtdec %0" : : "r" (0x7fffffff));
++
++	/* We can now disable MSR_EE */
++	local_irq_save(flags);
++
++	/* Giveup the FPU & vec */
++	enable_kernel_fp();
++
++#ifdef CONFIG_ALTIVEC
++	if (cpu_has_feature(CPU_FTR_ALTIVEC))
++		enable_kernel_altivec();
++#endif /* CONFIG_ALTIVEC */
++
++	/* Save & disable L2 and L3 caches */
++	save_l3cr = _get_L3CR();	/* (returns -1 if not available) */
++	save_l2cr = _get_L2CR();	/* (returns -1 if not available) */
++
++	/* Send the new speed command. My assumption is that this command
++	 * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
++	 */
++	pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
++	while (!req.complete)
++		pmu_poll();
++
++	/* Prepare the northbridge for the speed transition */
++	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
++
++	/* Call low level code to backup CPU state and recover from
++	 * hardware reset
++	 */
++	low_sleep_handler();
++
++	/* Restore the northbridge */
++	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
++
++	/* Restore L2 cache */
++	if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
++ 		_set_L2CR(save_l2cr);
++	/* Restore L3 cache */
++	if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
++ 		_set_L3CR(save_l3cr);
++
++	/* Restore userland MMU context */
++	set_context(current->active_mm->context, current->active_mm->pgd);
++
++#ifdef DEBUG_FREQ
++	printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
++#endif
++
++	/* Restore low level PMU operations */
++	pmu_unlock();
++
++	/* Restore decrementer */
++	wakeup_decrementer();
++
++	/* Restore interrupts */
++ 	mpic_cpu_set_priority(pic_prio);
++
++	/* Let interrupts flow again ... */
++	local_irq_restore(flags);
++
++#ifdef DEBUG_FREQ
++	debug_calc_bogomips();
++#endif
++
++	pmu_resume();
++
++	preempt_enable();
++
++	return 0;
++}
++
++static int do_set_cpu_speed(int speed_mode, int notify)
++{
++	struct cpufreq_freqs freqs;
++	unsigned long l3cr;
++	static unsigned long prev_l3cr;
++
++	freqs.old = cur_freq;
++	freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
++	freqs.cpu = smp_processor_id();
++
++	if (freqs.old == freqs.new)
++		return 0;
++
++	if (notify)
++		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++	if (speed_mode == CPUFREQ_LOW &&
++	    cpu_has_feature(CPU_FTR_L3CR)) {
++		l3cr = _get_L3CR();
++		if (l3cr & L3CR_L3E) {
++			prev_l3cr = l3cr;
++			_set_L3CR(0);
++		}
++	}
++	set_speed_proc(speed_mode == CPUFREQ_LOW);
++	if (speed_mode == CPUFREQ_HIGH &&
++	    cpu_has_feature(CPU_FTR_L3CR)) {
++		l3cr = _get_L3CR();
++		if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
++			_set_L3CR(prev_l3cr);
++	}
++	if (notify)
++		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++	cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
++
++	return 0;
++}
++
++static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
++{
++	return cur_freq;
++}
++
++static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
++{
++	return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
++}
++
++static int pmac_cpufreq_target(	struct cpufreq_policy *policy,
++					unsigned int target_freq,
++					unsigned int relation)
++{
++	unsigned int    newstate = 0;
++
++	if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
++			target_freq, relation, &newstate))
++		return -EINVAL;
++
++	return do_set_cpu_speed(newstate, 1);
++}
++
++unsigned int pmac_get_one_cpufreq(int i)
++{
++	/* Supports only one CPU for now */
++	return (i == 0) ? cur_freq : 0;
++}
++
++static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
++{
++	if (policy->cpu != 0)
++		return -ENODEV;
++
++	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
++	policy->cpuinfo.transition_latency	= CPUFREQ_ETERNAL;
++	policy->cur = cur_freq;
++
++	cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
++	return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
++}
++
++static u32 read_gpio(struct device_node *np)
++{
++	u32 *reg = (u32 *)get_property(np, "reg", NULL);
++	u32 offset;
++
++	if (reg == NULL)
++		return 0;
++	/* That works for all keylargos but shall be fixed properly
++	 * some day... The problem is that it seems we can't rely
++	 * on the "reg" property of the GPIO nodes, they are either
++	 * relative to the base of KeyLargo or to the base of the
++	 * GPIO space, and the device-tree doesn't help.
++	 */
++	offset = *reg;
++	if (offset < KEYLARGO_GPIO_LEVELS0)
++		offset += KEYLARGO_GPIO_LEVELS0;
++	return offset;
++}
++
++static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
++{
++	/* Ok, this could be made a bit smarter, but let's be robust for now. We
++	 * always force a speed change to high speed before sleep, to make sure
++	 * we have appropriate voltage and/or bus speed for the wakeup process,
++	 * and to make sure our loops_per_jiffies are "good enough", that is will
++	 * not cause too short delays if we sleep in low speed and wake in high
++	 * speed..
++	 */
++	no_schedule = 1;
++	sleep_freq = cur_freq;
++	if (cur_freq == low_freq && !is_pmu_based)
++		do_set_cpu_speed(CPUFREQ_HIGH, 0);
++	return 0;
++}
++
++static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
++{
++	/* If we resume, first check if we have a get() function */
++	if (get_speed_proc)
++		cur_freq = get_speed_proc();
++	else
++		cur_freq = 0;
++
++	/* We don't, hrm... we don't really know our speed here, best
++	 * is that we force a switch to whatever it was, which is
++	 * probably high speed due to our suspend() routine
++	 */
++	do_set_cpu_speed(sleep_freq == low_freq ?
++			 CPUFREQ_LOW : CPUFREQ_HIGH, 0);
++
++	no_schedule = 0;
++	return 0;
++}
++
++static struct cpufreq_driver pmac_cpufreq_driver = {
++	.verify 	= pmac_cpufreq_verify,
++	.target 	= pmac_cpufreq_target,
++	.get		= pmac_cpufreq_get_speed,
++	.init		= pmac_cpufreq_cpu_init,
++	.suspend	= pmac_cpufreq_suspend,
++	.resume		= pmac_cpufreq_resume,
++	.flags		= CPUFREQ_PM_NO_WARN,
++	.attr		= pmac_cpu_freqs_attr,
++	.name		= "powermac",
++	.owner		= THIS_MODULE,
++};
++
++
++static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
++{
++	struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
++								"voltage-gpio");
++	struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
++								"frequency-gpio");
++	struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
++								     "slewing-done");
++	u32 *value;
++
++	/*
++	 * Check to see if it's GPIO driven or PMU only
++	 *
++	 * The way we extract the GPIO address is slightly hackish, but it
++	 * works well enough for now. We need to abstract the whole GPIO
++	 * stuff sooner or later anyway
++	 */
++
++	if (volt_gpio_np)
++		voltage_gpio = read_gpio(volt_gpio_np);
++	if (freq_gpio_np)
++		frequency_gpio = read_gpio(freq_gpio_np);
++	if (slew_done_gpio_np)
++		slew_done_gpio = read_gpio(slew_done_gpio_np);
++
++	/* If we use the frequency GPIOs, calculate the min/max speeds based
++	 * on the bus frequencies
++	 */
++	if (frequency_gpio && slew_done_gpio) {
++		int lenp, rc;
++		u32 *freqs, *ratio;
++
++		freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp);
++		lenp /= sizeof(u32);
++		if (freqs == NULL || lenp != 2) {
++			printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
++			return 1;
++		}
++		ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL);
++		if (ratio == NULL) {
++			printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
++			return 1;
++		}
++
++		/* Get the min/max bus frequencies */
++		low_freq = min(freqs[0], freqs[1]);
++		hi_freq = max(freqs[0], freqs[1]);
++
++		/* Grrrr.. It _seems_ that the device-tree is lying on the low bus
++		 * frequency, it claims it to be around 84Mhz on some models while
++		 * it appears to be approx. 101Mhz on all. Let's hack around here...
++		 * fortunately, we don't need to be too precise
++		 */
++		if (low_freq < 98000000)
++			low_freq = 101000000;
++			
++		/* Convert those to CPU core clocks */
++		low_freq = (low_freq * (*ratio)) / 2000;
++		hi_freq = (hi_freq * (*ratio)) / 2000;
++
++		/* Now we get the frequencies, we read the GPIO to see what is out current
++		 * speed
++		 */
++		rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
++		cur_freq = (rc & 0x01) ? hi_freq : low_freq;
++
++		set_speed_proc = gpios_set_cpu_speed;
++		return 1;
++	}
++
++	/* If we use the PMU, look for the min & max frequencies in the
++	 * device-tree
++	 */
++	value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
++	if (!value)
++		return 1;
++	low_freq = (*value) / 1000;
++	/* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
++	 * here */
++	if (low_freq < 100000)
++		low_freq *= 10;
++
++	value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
++	if (!value)
++		return 1;
++	hi_freq = (*value) / 1000;
++	set_speed_proc = pmu_set_cpu_speed;
++	is_pmu_based = 1;
++
++	return 0;
++}
++
++static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
++{
++	struct device_node *volt_gpio_np;
++
++	if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
++		return 1;
++
++	volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
++	if (volt_gpio_np)
++		voltage_gpio = read_gpio(volt_gpio_np);
++	if (!voltage_gpio){
++		printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
++		return 1;
++	}
++
++	/* OF only reports the high frequency */
++	hi_freq = cur_freq;
++	low_freq = cur_freq/2;
++
++	/* Read actual frequency from CPU */
++	cur_freq = dfs_get_cpu_speed();
++	set_speed_proc = dfs_set_cpu_speed;
++	get_speed_proc = dfs_get_cpu_speed;
++
++	return 0;
++}
++
++static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
++{
++	struct device_node *volt_gpio_np;
++	u32 pvr, *value;
++
++	if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
++		return 1;
++
++	hi_freq = cur_freq;
++	value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);
++	if (!value)
++		return 1;
++	low_freq = (*value) / 1000;
++
++	volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
++	if (volt_gpio_np)
++		voltage_gpio = read_gpio(volt_gpio_np);
++
++	pvr = mfspr(SPRN_PVR);
++	has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
++
++	set_speed_proc = cpu_750fx_cpu_speed;
++	get_speed_proc = cpu_750fx_get_cpu_speed;
++	cur_freq = cpu_750fx_get_cpu_speed();
++
++	return 0;
++}
++
++/* Currently, we support the following machines:
++ *
++ *  - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
++ *  - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
++ *  - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
++ *  - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
++ *  - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
++ *  - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
++ *  - Recent MacRISC3 laptops
++ *  - All new machines with 7447A CPUs
++ */
++static int __init pmac_cpufreq_setup(void)
++{
++	struct device_node	*cpunode;
++	u32			*value;
++
++	if (strstr(cmd_line, "nocpufreq"))
++		return 0;
++
++	/* Assume only one CPU */
++	cpunode = find_type_devices("cpu");
++	if (!cpunode)
++		goto out;
++
++	/* Get current cpu clock freq */
++	value = (u32 *)get_property(cpunode, "clock-frequency", NULL);
++	if (!value)
++		goto out;
++	cur_freq = (*value) / 1000;
++
++	/*  Check for 7447A based MacRISC3 */
++	if (machine_is_compatible("MacRISC3") &&
++	    get_property(cpunode, "dynamic-power-step", NULL) &&
++	    PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
++		pmac_cpufreq_init_7447A(cpunode);
++	/* Check for other MacRISC3 machines */
++	} else if (machine_is_compatible("PowerBook3,4") ||
++		   machine_is_compatible("PowerBook3,5") ||
++		   machine_is_compatible("MacRISC3")) {
++		pmac_cpufreq_init_MacRISC3(cpunode);
++	/* Else check for iBook2 500/600 */
++	} else if (machine_is_compatible("PowerBook4,1")) {
++		hi_freq = cur_freq;
++		low_freq = 400000;
++		set_speed_proc = pmu_set_cpu_speed;
++		is_pmu_based = 1;
++	}
++	/* Else check for TiPb 550 */
++	else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
++		hi_freq = cur_freq;
++		low_freq = 500000;
++		set_speed_proc = pmu_set_cpu_speed;
++		is_pmu_based = 1;
++	}
++	/* Else check for TiPb 400 & 500 */
++	else if (machine_is_compatible("PowerBook3,2")) {
++		/* We only know about the 400 MHz and the 500Mhz model
++		 * they both have 300 MHz as low frequency
++		 */
++		if (cur_freq < 350000 || cur_freq > 550000)
++			goto out;
++		hi_freq = cur_freq;
++		low_freq = 300000;
++		set_speed_proc = pmu_set_cpu_speed;
++		is_pmu_based = 1;
++	}
++	/* Else check for 750FX */
++	else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
++		pmac_cpufreq_init_750FX(cpunode);
++out:
++	if (set_speed_proc == NULL)
++		return -ENODEV;
++
++	pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
++	pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
++
++	printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
++	printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
++	       low_freq/1000, hi_freq/1000, cur_freq/1000);
++
++	return cpufreq_register_driver(&pmac_cpufreq_driver);
++}
++
++module_init(pmac_cpufreq_setup);
++
+diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/feature.c
+@@ -0,0 +1,3063 @@
++/*
++ *  arch/ppc/platforms/pmac_feature.c
++ *
++ *  Copyright (C) 1996-2001 Paul Mackerras (paulus at cs.anu.edu.au)
++ *                          Ben. Herrenschmidt (benh at 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.
++ *
++ *  TODO:
++ *
++ *   - Replace mdelay with some schedule loop if possible
++ *   - Shorten some obfuscated delays on some routines (like modem
++ *     power)
++ *   - Refcount some clocks (see darwin)
++ *   - Split split split...
++ *
++ */
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/spinlock.h>
++#include <linux/adb.h>
++#include <linux/pmu.h>
++#include <linux/ioport.h>
++#include <linux/pci.h>
++#include <asm/sections.h>
++#include <asm/errno.h>
++#include <asm/ohare.h>
++#include <asm/heathrow.h>
++#include <asm/keylargo.h>
++#include <asm/uninorth.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++#include <asm/pmac_feature.h>
++#include <asm/dbdma.h>
++#include <asm/pci-bridge.h>
++#include <asm/pmac_low_i2c.h>
++
++#undef DEBUG_FEATURE
++
++#ifdef DEBUG_FEATURE
++#define DBG(fmt...) printk(KERN_DEBUG fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++#ifdef CONFIG_6xx
++extern int powersave_lowspeed;
++#endif
++
++extern int powersave_nap;
++extern struct device_node *k2_skiplist[2];
++
++
++/*
++ * We use a single global lock to protect accesses. Each driver has
++ * to take care of its own locking
++ */
++static DEFINE_SPINLOCK(feature_lock);
++
++#define LOCK(flags)	spin_lock_irqsave(&feature_lock, flags);
++#define UNLOCK(flags)	spin_unlock_irqrestore(&feature_lock, flags);
++
++
++/*
++ * Instance of some macio stuffs
++ */
++struct macio_chip macio_chips[MAX_MACIO_CHIPS];
++
++struct macio_chip *macio_find(struct device_node *child, int type)
++{
++	while(child) {
++		int	i;
++
++		for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
++			if (child == macio_chips[i].of_node &&
++			    (!type || macio_chips[i].type == type))
++				return &macio_chips[i];
++		child = child->parent;
++	}
++	return NULL;
++}
++EXPORT_SYMBOL_GPL(macio_find);
++
++static const char *macio_names[] =
++{
++	"Unknown",
++	"Grand Central",
++	"OHare",
++	"OHareII",
++	"Heathrow",
++	"Gatwick",
++	"Paddington",
++	"Keylargo",
++	"Pangea",
++	"Intrepid",
++	"K2"
++};
++
++
++
++/*
++ * Uninorth reg. access. Note that Uni-N regs are big endian
++ */
++
++#define UN_REG(r)	(uninorth_base + ((r) >> 2))
++#define UN_IN(r)	(in_be32(UN_REG(r)))
++#define UN_OUT(r,v)	(out_be32(UN_REG(r), (v)))
++#define UN_BIS(r,v)	(UN_OUT((r), UN_IN(r) | (v)))
++#define UN_BIC(r,v)	(UN_OUT((r), UN_IN(r) & ~(v)))
++
++static struct device_node *uninorth_node;
++static u32 __iomem *uninorth_base;
++static u32 uninorth_rev;
++static int uninorth_u3;
++static void __iomem *u3_ht;
++
++/*
++ * For each motherboard family, we have a table of functions pointers
++ * that handle the various features.
++ */
++
++typedef long (*feature_call)(struct device_node *node, long param, long value);
++
++struct feature_table_entry {
++	unsigned int	selector;
++	feature_call	function;
++};
++
++struct pmac_mb_def
++{
++	const char*			model_string;
++	const char*			model_name;
++	int				model_id;
++	struct feature_table_entry*	features;
++	unsigned long			board_flags;
++};
++static struct pmac_mb_def pmac_mb;
++
++/*
++ * Here are the chip specific feature functions
++ */
++
++static inline int simple_feature_tweak(struct device_node *node, int type,
++				       int reg, u32 mask, int value)
++{
++	struct macio_chip*	macio;
++	unsigned long		flags;
++
++	macio = macio_find(node, type);
++	if (!macio)
++		return -ENODEV;
++	LOCK(flags);
++	if (value)
++		MACIO_BIS(reg, mask);
++	else
++		MACIO_BIC(reg, mask);
++	(void)MACIO_IN32(reg);
++	UNLOCK(flags);
++
++	return 0;
++}
++
++#ifndef CONFIG_POWER4
++
++static long ohare_htw_scc_enable(struct device_node *node, long param,
++				 long value)
++{
++	struct macio_chip*	macio;
++	unsigned long		chan_mask;
++	unsigned long		fcr;
++	unsigned long		flags;
++	int			htw, trans;
++	unsigned long		rmask;
++
++	macio = macio_find(node, 0);
++	if (!macio)
++		return -ENODEV;
++	if (!strcmp(node->name, "ch-a"))
++		chan_mask = MACIO_FLAG_SCCA_ON;
++	else if (!strcmp(node->name, "ch-b"))
++		chan_mask = MACIO_FLAG_SCCB_ON;
++	else
++		return -ENODEV;
++
++	htw = (macio->type == macio_heathrow || macio->type == macio_paddington
++		|| macio->type == macio_gatwick);
++	/* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
++	trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
++		 pmac_mb.model_id != PMAC_TYPE_YIKES);
++	if (value) {
++#ifdef CONFIG_ADB_PMU
++		if ((param & 0xfff) == PMAC_SCC_IRDA)
++			pmu_enable_irled(1);
++#endif /* CONFIG_ADB_PMU */
++		LOCK(flags);
++		fcr = MACIO_IN32(OHARE_FCR);
++		/* Check if scc cell need enabling */
++		if (!(fcr & OH_SCC_ENABLE)) {
++			fcr |= OH_SCC_ENABLE;
++			if (htw) {
++				/* Side effect: this will also power up the
++				 * modem, but it's too messy to figure out on which
++				 * ports this controls the tranceiver and on which
++				 * it controls the modem
++				 */
++				if (trans)
++					fcr &= ~HRW_SCC_TRANS_EN_N;
++				MACIO_OUT32(OHARE_FCR, fcr);
++				fcr |= (rmask = HRW_RESET_SCC);
++				MACIO_OUT32(OHARE_FCR, fcr);
++			} else {
++				fcr |= (rmask = OH_SCC_RESET);
++				MACIO_OUT32(OHARE_FCR, fcr);
++			}
++			UNLOCK(flags);
++			(void)MACIO_IN32(OHARE_FCR);
++			mdelay(15);
++			LOCK(flags);
++			fcr &= ~rmask;
++			MACIO_OUT32(OHARE_FCR, fcr);
++		}
++		if (chan_mask & MACIO_FLAG_SCCA_ON)
++			fcr |= OH_SCCA_IO;
++		if (chan_mask & MACIO_FLAG_SCCB_ON)
++			fcr |= OH_SCCB_IO;
++		MACIO_OUT32(OHARE_FCR, fcr);
++		macio->flags |= chan_mask;
++		UNLOCK(flags);
++		if (param & PMAC_SCC_FLAG_XMON)
++			macio->flags |= MACIO_FLAG_SCC_LOCKED;
++	} else {
++		if (macio->flags & MACIO_FLAG_SCC_LOCKED)
++			return -EPERM;
++		LOCK(flags);
++		fcr = MACIO_IN32(OHARE_FCR);
++		if (chan_mask & MACIO_FLAG_SCCA_ON)
++			fcr &= ~OH_SCCA_IO;
++		if (chan_mask & MACIO_FLAG_SCCB_ON)
++			fcr &= ~OH_SCCB_IO;
++		MACIO_OUT32(OHARE_FCR, fcr);
++		if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
++			fcr &= ~OH_SCC_ENABLE;
++			if (htw && trans)
++				fcr |= HRW_SCC_TRANS_EN_N;
++			MACIO_OUT32(OHARE_FCR, fcr);
++		}
++		macio->flags &= ~(chan_mask);
++		UNLOCK(flags);
++		mdelay(10);
++#ifdef CONFIG_ADB_PMU
++		if ((param & 0xfff) == PMAC_SCC_IRDA)
++			pmu_enable_irled(0);
++#endif /* CONFIG_ADB_PMU */
++	}
++	return 0;
++}
++
++static long ohare_floppy_enable(struct device_node *node, long param,
++				long value)
++{
++	return simple_feature_tweak(node, macio_ohare,
++		OHARE_FCR, OH_FLOPPY_ENABLE, value);
++}
++
++static long ohare_mesh_enable(struct device_node *node, long param, long value)
++{
++	return simple_feature_tweak(node, macio_ohare,
++		OHARE_FCR, OH_MESH_ENABLE, value);
++}
++
++static long ohare_ide_enable(struct device_node *node, long param, long value)
++{
++	switch(param) {
++	case 0:
++		/* For some reason, setting the bit in set_initial_features()
++		 * doesn't stick. I'm still investigating... --BenH.
++		 */
++		if (value)
++			simple_feature_tweak(node, macio_ohare,
++				OHARE_FCR, OH_IOBUS_ENABLE, 1);
++		return simple_feature_tweak(node, macio_ohare,
++			OHARE_FCR, OH_IDE0_ENABLE, value);
++	case 1:
++		return simple_feature_tweak(node, macio_ohare,
++			OHARE_FCR, OH_BAY_IDE_ENABLE, value);
++	default:
++		return -ENODEV;
++	}
++}
++
++static long ohare_ide_reset(struct device_node *node, long param, long value)
++{
++	switch(param) {
++	case 0:
++		return simple_feature_tweak(node, macio_ohare,
++			OHARE_FCR, OH_IDE0_RESET_N, !value);
++	case 1:
++		return simple_feature_tweak(node, macio_ohare,
++			OHARE_FCR, OH_IDE1_RESET_N, !value);
++	default:
++		return -ENODEV;
++	}
++}
++
++static long ohare_sleep_state(struct device_node *node, long param, long value)
++{
++	struct macio_chip*	macio = &macio_chips[0];
++
++	if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
++		return -EPERM;
++	if (value == 1) {
++		MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE);
++	} else if (value == 0) {
++		MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
++	}
++
++	return 0;
++}
++
++static long heathrow_modem_enable(struct device_node *node, long param,
++				  long value)
++{
++	struct macio_chip*	macio;
++	u8			gpio;
++	unsigned long		flags;
++
++	macio = macio_find(node, macio_unknown);
++	if (!macio)
++		return -ENODEV;
++	gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1;
++	if (!value) {
++		LOCK(flags);
++		MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
++		UNLOCK(flags);
++		(void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
++		mdelay(250);
++	}
++	if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
++	    pmac_mb.model_id != PMAC_TYPE_YIKES) {
++		LOCK(flags);
++		if (value)
++			MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
++		else
++			MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
++		UNLOCK(flags);
++		(void)MACIO_IN32(HEATHROW_FCR);
++		mdelay(250);
++	}
++	if (value) {
++		LOCK(flags);
++		MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
++		(void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
++		UNLOCK(flags); mdelay(250); LOCK(flags);
++		MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
++		(void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
++		UNLOCK(flags); mdelay(250); LOCK(flags);
++		MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
++		(void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
++		UNLOCK(flags); mdelay(250);
++	}
++	return 0;
++}
++
++static long heathrow_floppy_enable(struct device_node *node, long param,
++				   long value)
++{
++	return simple_feature_tweak(node, macio_unknown,
++		HEATHROW_FCR,
++		HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE,
++		value);
++}
++
++static long heathrow_mesh_enable(struct device_node *node, long param,
++				 long value)
++{
++	struct macio_chip*	macio;
++	unsigned long		flags;
++
++	macio = macio_find(node, macio_unknown);
++	if (!macio)
++		return -ENODEV;
++	LOCK(flags);
++	/* Set clear mesh cell enable */
++	if (value)
++		MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE);
++	else
++		MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE);
++	(void)MACIO_IN32(HEATHROW_FCR);
++	udelay(10);
++	/* Set/Clear termination power */
++	if (value)
++		MACIO_BIC(HEATHROW_MBCR, 0x04000000);
++	else
++		MACIO_BIS(HEATHROW_MBCR, 0x04000000);
++	(void)MACIO_IN32(HEATHROW_MBCR);
++	udelay(10);
++	UNLOCK(flags);
++
++	return 0;
++}
++
++static long heathrow_ide_enable(struct device_node *node, long param,
++				long value)
++{
++	switch(param) {
++	case 0:
++		return simple_feature_tweak(node, macio_unknown,
++			HEATHROW_FCR, HRW_IDE0_ENABLE, value);
++	case 1:
++		return simple_feature_tweak(node, macio_unknown,
++			HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value);
++	default:
++		return -ENODEV;
++	}
++}
++
++static long heathrow_ide_reset(struct device_node *node, long param,
++			       long value)
++{
++	switch(param) {
++	case 0:
++		return simple_feature_tweak(node, macio_unknown,
++			HEATHROW_FCR, HRW_IDE0_RESET_N, !value);
++	case 1:
++		return simple_feature_tweak(node, macio_unknown,
++			HEATHROW_FCR, HRW_IDE1_RESET_N, !value);
++	default:
++		return -ENODEV;
++	}
++}
++
++static long heathrow_bmac_enable(struct device_node *node, long param,
++				 long value)
++{
++	struct macio_chip*	macio;
++	unsigned long		flags;
++
++	macio = macio_find(node, 0);
++	if (!macio)
++		return -ENODEV;
++	if (value) {
++		LOCK(flags);
++		MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
++		MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET);
++		UNLOCK(flags);
++		(void)MACIO_IN32(HEATHROW_FCR);
++		mdelay(10);
++		LOCK(flags);
++		MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET);
++		UNLOCK(flags);
++		(void)MACIO_IN32(HEATHROW_FCR);
++		mdelay(10);
++	} else {
++		LOCK(flags);
++		MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
++		UNLOCK(flags);
++	}
++	return 0;
++}
++
++static long heathrow_sound_enable(struct device_node *node, long param,
++				  long value)
++{
++	struct macio_chip*	macio;
++	unsigned long		flags;
++
++	/* B&W G3 and Yikes don't support that properly (the
++	 * sound appear to never come back after beeing shut down).
++	 */
++	if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
++	    pmac_mb.model_id == PMAC_TYPE_YIKES)
++		return 0;
++
++	macio = macio_find(node, 0);
++	if (!macio)
++		return -ENODEV;
++	if (value) {
++		LOCK(flags);
++		MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
++		MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
++		UNLOCK(flags);
++		(void)MACIO_IN32(HEATHROW_FCR);
++	} else {
++		LOCK(flags);
++		MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
++		MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
++		UNLOCK(flags);
++	}
++	return 0;
++}
++
++static u32 save_fcr[6];
++static u32 save_mbcr;
++static u32 save_gpio_levels[2];
++static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
++static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
++static u32 save_unin_clock_ctl;
++static struct dbdma_regs save_dbdma[13];
++static struct dbdma_regs save_alt_dbdma[13];
++
++static void dbdma_save(struct macio_chip *macio, struct dbdma_regs *save)
++{
++	int i;
++
++	/* Save state & config of DBDMA channels */
++	for (i = 0; i < 13; i++) {
++		volatile struct dbdma_regs __iomem * chan = (void __iomem *)
++			(macio->base + ((0x8000+i*0x100)>>2));
++		save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);
++		save[i].cmdptr = in_le32(&chan->cmdptr);
++		save[i].intr_sel = in_le32(&chan->intr_sel);
++		save[i].br_sel = in_le32(&chan->br_sel);
++		save[i].wait_sel = in_le32(&chan->wait_sel);
++	}
++}
++
++static void dbdma_restore(struct macio_chip *macio, struct dbdma_regs *save)
++{
++	int i;
++
++	/* Save state & config of DBDMA channels */
++	for (i = 0; i < 13; i++) {
++		volatile struct dbdma_regs __iomem * chan = (void __iomem *)
++			(macio->base + ((0x8000+i*0x100)>>2));
++		out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);
++		while (in_le32(&chan->status) & ACTIVE)
++			mb();
++		out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi);
++		out_le32(&chan->cmdptr, save[i].cmdptr);
++		out_le32(&chan->intr_sel, save[i].intr_sel);
++		out_le32(&chan->br_sel, save[i].br_sel);
++		out_le32(&chan->wait_sel, save[i].wait_sel);
++	}
++}
++
++static void heathrow_sleep(struct macio_chip *macio, int secondary)
++{
++	if (secondary) {
++		dbdma_save(macio, save_alt_dbdma);
++		save_fcr[2] = MACIO_IN32(0x38);
++		save_fcr[3] = MACIO_IN32(0x3c);
++	} else {
++		dbdma_save(macio, save_dbdma);
++		save_fcr[0] = MACIO_IN32(0x38);
++		save_fcr[1] = MACIO_IN32(0x3c);
++		save_mbcr = MACIO_IN32(0x34);
++		/* Make sure sound is shut down */
++		MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
++		MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
++		/* This seems to be necessary as well or the fan
++		 * keeps coming up and battery drains fast */
++		MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
++		MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N);
++		/* Make sure eth is down even if module or sleep
++		 * won't work properly */
++		MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
++	}
++	/* Make sure modem is shut down */
++	MACIO_OUT8(HRW_GPIO_MODEM_RESET,
++		MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
++	MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
++	MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
++
++	/* Let things settle */
++	(void)MACIO_IN32(HEATHROW_FCR);
++}
++
++static void heathrow_wakeup(struct macio_chip *macio, int secondary)
++{
++	if (secondary) {
++		MACIO_OUT32(0x38, save_fcr[2]);
++		(void)MACIO_IN32(0x38);
++		mdelay(1);
++		MACIO_OUT32(0x3c, save_fcr[3]);
++		(void)MACIO_IN32(0x38);
++		mdelay(10);
++		dbdma_restore(macio, save_alt_dbdma);
++	} else {
++		MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE);
++		(void)MACIO_IN32(0x38);
++		mdelay(1);
++		MACIO_OUT32(0x3c, save_fcr[1]);
++		(void)MACIO_IN32(0x38);
++		mdelay(1);
++		MACIO_OUT32(0x34, save_mbcr);
++		(void)MACIO_IN32(0x38);
++		mdelay(10);
++		dbdma_restore(macio, save_dbdma);
++	}
++}
++
++static long heathrow_sleep_state(struct device_node *node, long param,
++				 long value)
++{
++	if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
++		return -EPERM;
++	if (value == 1) {
++		if (macio_chips[1].type == macio_gatwick)
++			heathrow_sleep(&macio_chips[0], 1);
++		heathrow_sleep(&macio_chips[0], 0);
++	} else if (value == 0) {
++		heathrow_wakeup(&macio_chips[0], 0);
++		if (macio_chips[1].type == macio_gatwick)
++			heathrow_wakeup(&macio_chips[0], 1);
++	}
++	return 0;
++}
++
++static long core99_scc_enable(struct device_node *node, long param, long value)
++{
++	struct macio_chip*	macio;
++	unsigned long		flags;
++	unsigned long		chan_mask;
++	u32			fcr;
++
++	macio = macio_find(node, 0);
++	if (!macio)
++		return -ENODEV;
++	if (!strcmp(node->name, "ch-a"))
++		chan_mask = MACIO_FLAG_SCCA_ON;
++	else if (!strcmp(node->name, "ch-b"))
++		chan_mask = MACIO_FLAG_SCCB_ON;
++	else
++		return -ENODEV;
++
++	if (value) {
++		int need_reset_scc = 0;
++		int need_reset_irda = 0;
++
++		LOCK(flags);
++		fcr = MACIO_IN32(KEYLARGO_FCR0);
++		/* Check if scc cell need enabling */
++		if (!(fcr & KL0_SCC_CELL_ENABLE)) {
++			fcr |= KL0_SCC_CELL_ENABLE;
++			need_reset_scc = 1;
++		}
++		if (chan_mask & MACIO_FLAG_SCCA_ON) {
++			fcr |= KL0_SCCA_ENABLE;
++			/* Don't enable line drivers for I2S modem */
++			if ((param & 0xfff) == PMAC_SCC_I2S1)
++				fcr &= ~KL0_SCC_A_INTF_ENABLE;
++			else
++				fcr |= KL0_SCC_A_INTF_ENABLE;
++		}
++		if (chan_mask & MACIO_FLAG_SCCB_ON) {
++			fcr |= KL0_SCCB_ENABLE;
++			/* Perform irda specific inits */
++			if ((param & 0xfff) == PMAC_SCC_IRDA) {
++				fcr &= ~KL0_SCC_B_INTF_ENABLE;
++				fcr |= KL0_IRDA_ENABLE;
++				fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE;
++				fcr |= KL0_IRDA_SOURCE1_SEL;
++				fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
++				fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
++				need_reset_irda = 1;
++			} else
++				fcr |= KL0_SCC_B_INTF_ENABLE;
++		}
++		MACIO_OUT32(KEYLARGO_FCR0, fcr);
++		macio->flags |= chan_mask;
++		if (need_reset_scc)  {
++			MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET);
++			(void)MACIO_IN32(KEYLARGO_FCR0);
++			UNLOCK(flags);
++			mdelay(15);
++			LOCK(flags);
++			MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET);
++		}
++		if (need_reset_irda)  {
++			MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET);
++			(void)MACIO_IN32(KEYLARGO_FCR0);
++			UNLOCK(flags);
++			mdelay(15);
++			LOCK(flags);
++			MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET);
++		}
++		UNLOCK(flags);
++		if (param & PMAC_SCC_FLAG_XMON)
++			macio->flags |= MACIO_FLAG_SCC_LOCKED;
++	} else {
++		if (macio->flags & MACIO_FLAG_SCC_LOCKED)
++			return -EPERM;
++		LOCK(flags);
++		fcr = MACIO_IN32(KEYLARGO_FCR0);
++		if (chan_mask & MACIO_FLAG_SCCA_ON)
++			fcr &= ~KL0_SCCA_ENABLE;
++		if (chan_mask & MACIO_FLAG_SCCB_ON) {
++			fcr &= ~KL0_SCCB_ENABLE;
++			/* Perform irda specific clears */
++			if ((param & 0xfff) == PMAC_SCC_IRDA) {
++				fcr &= ~KL0_IRDA_ENABLE;
++				fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE);
++				fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
++				fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
++			}
++		}
++		MACIO_OUT32(KEYLARGO_FCR0, fcr);
++		if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) {
++			fcr &= ~KL0_SCC_CELL_ENABLE;
++			MACIO_OUT32(KEYLARGO_FCR0, fcr);
++		}
++		macio->flags &= ~(chan_mask);
++		UNLOCK(flags);
++		mdelay(10);
++	}
++	return 0;
++}
++
++static long
++core99_modem_enable(struct device_node *node, long param, long value)
++{
++	struct macio_chip*	macio;
++	u8			gpio;
++	unsigned long		flags;
++
++	/* Hack for internal USB modem */
++	if (node == NULL) {
++		if (macio_chips[0].type != macio_keylargo)
++			return -ENODEV;
++		node = macio_chips[0].of_node;
++	}
++	macio = macio_find(node, 0);
++	if (!macio)
++		return -ENODEV;
++	gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
++	gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
++	gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
++
++	if (!value) {
++		LOCK(flags);
++		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
++		UNLOCK(flags);
++		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
++		mdelay(250);
++	}
++	LOCK(flags);
++	if (value) {
++		MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
++		UNLOCK(flags);
++		(void)MACIO_IN32(KEYLARGO_FCR2);
++		mdelay(250);
++	} else {
++		MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
++		UNLOCK(flags);
++	}
++	if (value) {
++		LOCK(flags);
++		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
++		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
++		UNLOCK(flags); mdelay(250); LOCK(flags);
++		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
++		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
++		UNLOCK(flags); mdelay(250); LOCK(flags);
++		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
++		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
++		UNLOCK(flags); mdelay(250);
++	}
++	return 0;
++}
++
++static long
++pangea_modem_enable(struct device_node *node, long param, long value)
++{
++	struct macio_chip*	macio;
++	u8			gpio;
++	unsigned long		flags;
++
++	/* Hack for internal USB modem */
++	if (node == NULL) {
++		if (macio_chips[0].type != macio_pangea &&
++		    macio_chips[0].type != macio_intrepid)
++			return -ENODEV;
++		node = macio_chips[0].of_node;
++	}
++	macio = macio_find(node, 0);
++	if (!macio)
++		return -ENODEV;
++	gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
++	gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
++	gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
++
++	if (!value) {
++		LOCK(flags);
++		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
++		UNLOCK(flags);
++		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
++		mdelay(250);
++	}
++	LOCK(flags);
++	if (value) {
++		MACIO_OUT8(KL_GPIO_MODEM_POWER,
++			KEYLARGO_GPIO_OUTPUT_ENABLE);
++		UNLOCK(flags);
++		(void)MACIO_IN32(KEYLARGO_FCR2);
++		mdelay(250);
++	} else {
++		MACIO_OUT8(KL_GPIO_MODEM_POWER,
++			KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
++		UNLOCK(flags);
++	}
++	if (value) {
++		LOCK(flags);
++		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
++		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
++		UNLOCK(flags); mdelay(250); LOCK(flags);
++		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
++		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
++		UNLOCK(flags); mdelay(250); LOCK(flags);
++		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
++		(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
++		UNLOCK(flags); mdelay(250);
++	}
++	return 0;
++}
++
++static long
++core99_ata100_enable(struct device_node *node, long value)
++{
++	unsigned long flags;
++	struct pci_dev *pdev = NULL;
++	u8 pbus, pid;
++
++	if (uninorth_rev < 0x24)
++		return -ENODEV;
++
++	LOCK(flags);
++	if (value)
++		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
++	else
++		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
++	(void)UN_IN(UNI_N_CLOCK_CNTL);
++	UNLOCK(flags);
++	udelay(20);
++
++	if (value) {
++		if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
++			pdev = pci_find_slot(pbus, pid);
++		if (pdev == NULL)
++			return 0;
++		pci_enable_device(pdev);
++		pci_set_master(pdev);
++	}
++	return 0;
++}
++
++static long
++core99_ide_enable(struct device_node *node, long param, long value)
++{
++	/* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
++	 * based ata-100
++	 */
++	switch(param) {
++	    case 0:
++		return simple_feature_tweak(node, macio_unknown,
++			KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value);
++	    case 1:
++		return simple_feature_tweak(node, macio_unknown,
++			KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value);
++	    case 2:
++		return simple_feature_tweak(node, macio_unknown,
++			KEYLARGO_FCR1, KL1_UIDE_ENABLE, value);
++	    case 3:
++		return core99_ata100_enable(node, value);
++	    default:
++		return -ENODEV;
++	}
++}
++
++static long
++core99_ide_reset(struct device_node *node, long param, long value)
++{
++	switch(param) {
++	    case 0:
++		return simple_feature_tweak(node, macio_unknown,
++			KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value);
++	    case 1:
++		return simple_feature_tweak(node, macio_unknown,
++			KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value);
++	    case 2:
++		return simple_feature_tweak(node, macio_unknown,
++			KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value);
++	    default:
++		return -ENODEV;
++	}
++}
++
++static long
++core99_gmac_enable(struct device_node *node, long param, long value)
++{
++	unsigned long flags;
++
++	LOCK(flags);
++	if (value)
++		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
++	else
++		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
++	(void)UN_IN(UNI_N_CLOCK_CNTL);
++	UNLOCK(flags);
++	udelay(20);
++
++	return 0;
++}
++
++static long
++core99_gmac_phy_reset(struct device_node *node, long param, long value)
++{
++	unsigned long flags;
++	struct macio_chip *macio;
++
++	macio = &macio_chips[0];
++	if (macio->type != macio_keylargo && macio->type != macio_pangea &&
++	    macio->type != macio_intrepid)
++		return -ENODEV;
++
++	LOCK(flags);
++	MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
++	(void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET);
++	UNLOCK(flags);
++	mdelay(10);
++	LOCK(flags);
++	MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */
++		KEYLARGO_GPIO_OUTOUT_DATA);
++	UNLOCK(flags);
++	mdelay(10);
++
++	return 0;
++}
++
++static long
++core99_sound_chip_enable(struct device_node *node, long param, long value)
++{
++	struct macio_chip*	macio;
++	unsigned long		flags;
++
++	macio = macio_find(node, 0);
++	if (!macio)
++		return -ENODEV;
++
++	/* Do a better probe code, screamer G4 desktops &
++	 * iMacs can do that too, add a recalibrate  in
++	 * the driver as well
++	 */
++	if (pmac_mb.model_id == PMAC_TYPE_PISMO ||
++	    pmac_mb.model_id == PMAC_TYPE_TITANIUM) {
++		LOCK(flags);
++		if (value)
++			MACIO_OUT8(KL_GPIO_SOUND_POWER,
++				KEYLARGO_GPIO_OUTPUT_ENABLE |
++				KEYLARGO_GPIO_OUTOUT_DATA);
++		else
++			MACIO_OUT8(KL_GPIO_SOUND_POWER,
++				KEYLARGO_GPIO_OUTPUT_ENABLE);
++		(void)MACIO_IN8(KL_GPIO_SOUND_POWER);
++		UNLOCK(flags);
++	}
++	return 0;
++}
++
++static long
++core99_airport_enable(struct device_node *node, long param, long value)
++{
++	struct macio_chip*	macio;
++	unsigned long		flags;
++	int			state;
++
++	macio = macio_find(node, 0);
++	if (!macio)
++		return -ENODEV;
++
++	/* Hint: we allow passing of macio itself for the sake of the
++	 * sleep code
++	 */
++	if (node != macio->of_node &&
++	    (!node->parent || node->parent != macio->of_node))
++		return -ENODEV;
++	state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0;
++	if (value == state)
++		return 0;
++	if (value) {
++		/* This code is a reproduction of OF enable-cardslot
++		 * and init-wireless methods, slightly hacked until
++		 * I got it working.
++		 */
++		LOCK(flags);
++		MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5);
++		(void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
++		UNLOCK(flags);
++		mdelay(10);
++		LOCK(flags);
++		MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4);
++		(void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
++		UNLOCK(flags);
++
++		mdelay(10);
++
++		LOCK(flags);
++		MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
++		(void)MACIO_IN32(KEYLARGO_FCR2);
++		udelay(10);
++		MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0);
++		(void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb);
++		udelay(10);
++		MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28);
++		(void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa);
++		udelay(10);
++		MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28);
++		(void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd);
++		udelay(10);
++		MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28);
++		(void)MACIO_IN8(KEYLARGO_GPIO_0+0xd);
++		udelay(10);
++		MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28);
++		(void)MACIO_IN8(KEYLARGO_GPIO_0+0xe);
++		UNLOCK(flags);
++		udelay(10);
++		MACIO_OUT32(0x1c000, 0);
++		mdelay(1);
++		MACIO_OUT8(0x1a3e0, 0x41);
++		(void)MACIO_IN8(0x1a3e0);
++		udelay(10);
++		LOCK(flags);
++		MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16);
++		(void)MACIO_IN32(KEYLARGO_FCR2);
++		UNLOCK(flags);
++		mdelay(100);
++
++		macio->flags |= MACIO_FLAG_AIRPORT_ON;
++	} else {
++		LOCK(flags);
++		MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
++		(void)MACIO_IN32(KEYLARGO_FCR2);
++		MACIO_OUT8(KL_GPIO_AIRPORT_0, 0);
++		MACIO_OUT8(KL_GPIO_AIRPORT_1, 0);
++		MACIO_OUT8(KL_GPIO_AIRPORT_2, 0);
++		MACIO_OUT8(KL_GPIO_AIRPORT_3, 0);
++		MACIO_OUT8(KL_GPIO_AIRPORT_4, 0);
++		(void)MACIO_IN8(KL_GPIO_AIRPORT_4);
++		UNLOCK(flags);
++
++		macio->flags &= ~MACIO_FLAG_AIRPORT_ON;
++	}
++	return 0;
++}
++
++#ifdef CONFIG_SMP
++static long
++core99_reset_cpu(struct device_node *node, long param, long value)
++{
++	unsigned int reset_io = 0;
++	unsigned long flags;
++	struct macio_chip *macio;
++	struct device_node *np;
++	const int dflt_reset_lines[] = {	KL_GPIO_RESET_CPU0,
++						KL_GPIO_RESET_CPU1,
++						KL_GPIO_RESET_CPU2,
++						KL_GPIO_RESET_CPU3 };
++
++	macio = &macio_chips[0];
++	if (macio->type != macio_keylargo)
++		return -ENODEV;
++
++	np = find_path_device("/cpus");
++	if (np == NULL)
++		return -ENODEV;
++	for (np = np->child; np != NULL; np = np->sibling) {
++		u32 *num = (u32 *)get_property(np, "reg", NULL);
++		u32 *rst = (u32 *)get_property(np, "soft-reset", NULL);
++		if (num == NULL || rst == NULL)
++			continue;
++		if (param == *num) {
++			reset_io = *rst;
++			break;
++		}
++	}
++	if (np == NULL || reset_io == 0)
++		reset_io = dflt_reset_lines[param];
++
++	LOCK(flags);
++	MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
++	(void)MACIO_IN8(reset_io);
++	udelay(1);
++	MACIO_OUT8(reset_io, 0);
++	(void)MACIO_IN8(reset_io);
++	UNLOCK(flags);
++
++	return 0;
++}
++#endif /* CONFIG_SMP */
++
++static long
++core99_usb_enable(struct device_node *node, long param, long value)
++{
++	struct macio_chip *macio;
++	unsigned long flags;
++	char *prop;
++	int number;
++	u32 reg;
++
++	macio = &macio_chips[0];
++	if (macio->type != macio_keylargo && macio->type != macio_pangea &&
++	    macio->type != macio_intrepid)
++		return -ENODEV;
++
++	prop = (char *)get_property(node, "AAPL,clock-id", NULL);
++	if (!prop)
++		return -ENODEV;
++	if (strncmp(prop, "usb0u048", 8) == 0)
++		number = 0;
++	else if (strncmp(prop, "usb1u148", 8) == 0)
++		number = 2;
++	else if (strncmp(prop, "usb2u248", 8) == 0)
++		number = 4;
++	else
++		return -ENODEV;
++
++	/* Sorry for the brute-force locking, but this is only used during
++	 * sleep and the timing seem to be critical
++	 */
++	LOCK(flags);
++	if (value) {
++		/* Turn ON */
++		if (number == 0) {
++			MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
++			(void)MACIO_IN32(KEYLARGO_FCR0);
++			UNLOCK(flags);
++			mdelay(1);
++			LOCK(flags);
++			MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
++		} else if (number == 2) {
++			MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
++			UNLOCK(flags);
++			(void)MACIO_IN32(KEYLARGO_FCR0);
++			mdelay(1);
++			LOCK(flags);
++			MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
++		} else if (number == 4) {
++			MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
++			UNLOCK(flags);
++			(void)MACIO_IN32(KEYLARGO_FCR1);
++			mdelay(1);
++			LOCK(flags);
++			MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
++		}
++		if (number < 4) {
++			reg = MACIO_IN32(KEYLARGO_FCR4);
++			reg &=	~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
++				KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
++			reg &=	~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
++				KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
++			MACIO_OUT32(KEYLARGO_FCR4, reg);
++			(void)MACIO_IN32(KEYLARGO_FCR4);
++			udelay(10);
++		} else {
++			reg = MACIO_IN32(KEYLARGO_FCR3);
++			reg &=	~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
++				KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0));
++			reg &=	~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
++				KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1));
++			MACIO_OUT32(KEYLARGO_FCR3, reg);
++			(void)MACIO_IN32(KEYLARGO_FCR3);
++			udelay(10);
++		}
++		if (macio->type == macio_intrepid) {
++			/* wait for clock stopped bits to clear */
++			u32 test0 = 0, test1 = 0;
++			u32 status0, status1;
++			int timeout = 1000;
++
++			UNLOCK(flags);
++			switch (number) {
++			case 0:
++				test0 = UNI_N_CLOCK_STOPPED_USB0;
++				test1 = UNI_N_CLOCK_STOPPED_USB0PCI;
++				break;
++			case 2:
++				test0 = UNI_N_CLOCK_STOPPED_USB1;
++				test1 = UNI_N_CLOCK_STOPPED_USB1PCI;
++				break;
++			case 4:
++				test0 = UNI_N_CLOCK_STOPPED_USB2;
++				test1 = UNI_N_CLOCK_STOPPED_USB2PCI;
++				break;
++			}
++			do {
++				if (--timeout <= 0) {
++					printk(KERN_ERR "core99_usb_enable: "
++					       "Timeout waiting for clocks\n");
++					break;
++				}
++				mdelay(1);
++				status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0);
++				status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1);
++			} while ((status0 & test0) | (status1 & test1));
++			LOCK(flags);
++		}
++	} else {
++		/* Turn OFF */
++		if (number < 4) {
++			reg = MACIO_IN32(KEYLARGO_FCR4);
++			reg |=	KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
++				KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
++			reg |=	KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
++				KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
++			MACIO_OUT32(KEYLARGO_FCR4, reg);
++			(void)MACIO_IN32(KEYLARGO_FCR4);
++			udelay(1);
++		} else {
++			reg = MACIO_IN32(KEYLARGO_FCR3);
++			reg |=	KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
++				KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0);
++			reg |=	KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
++				KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1);
++			MACIO_OUT32(KEYLARGO_FCR3, reg);
++			(void)MACIO_IN32(KEYLARGO_FCR3);
++			udelay(1);
++		}
++		if (number == 0) {
++			if (macio->type != macio_intrepid)
++				MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
++			(void)MACIO_IN32(KEYLARGO_FCR0);
++			udelay(1);
++			MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
++			(void)MACIO_IN32(KEYLARGO_FCR0);
++		} else if (number == 2) {
++			if (macio->type != macio_intrepid)
++				MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
++			(void)MACIO_IN32(KEYLARGO_FCR0);
++			udelay(1);
++			MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
++			(void)MACIO_IN32(KEYLARGO_FCR0);
++		} else if (number == 4) {
++			udelay(1);
++			MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
++			(void)MACIO_IN32(KEYLARGO_FCR1);
++		}
++		udelay(1);
++	}
++	UNLOCK(flags);
++
++	return 0;
++}
++
++static long
++core99_firewire_enable(struct device_node *node, long param, long value)
++{
++	unsigned long flags;
++	struct macio_chip *macio;
++
++	macio = &macio_chips[0];
++	if (macio->type != macio_keylargo && macio->type != macio_pangea &&
++	    macio->type != macio_intrepid)
++		return -ENODEV;
++	if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
++		return -ENODEV;
++
++	LOCK(flags);
++	if (value) {
++		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
++		(void)UN_IN(UNI_N_CLOCK_CNTL);
++	} else {
++		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
++		(void)UN_IN(UNI_N_CLOCK_CNTL);
++	}
++	UNLOCK(flags);
++	mdelay(1);
++
++	return 0;
++}
++
++static long
++core99_firewire_cable_power(struct device_node *node, long param, long value)
++{
++	unsigned long flags;
++	struct macio_chip *macio;
++
++	/* Trick: we allow NULL node */
++	if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0)
++		return -ENODEV;
++	macio = &macio_chips[0];
++	if (macio->type != macio_keylargo && macio->type != macio_pangea &&
++	    macio->type != macio_intrepid)
++		return -ENODEV;
++	if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
++		return -ENODEV;
++
++	LOCK(flags);
++	if (value) {
++		MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0);
++		MACIO_IN8(KL_GPIO_FW_CABLE_POWER);
++		udelay(10);
++	} else {
++		MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4);
++		MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10);
++	}
++	UNLOCK(flags);
++	mdelay(1);
++
++	return 0;
++}
++
++static long
++intrepid_aack_delay_enable(struct device_node *node, long param, long value)
++{
++	unsigned long flags;
++
++	if (uninorth_rev < 0xd2)
++		return -ENODEV;
++
++	LOCK(flags);
++	if (param)
++		UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
++	else
++		UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
++	UNLOCK(flags);
++
++	return 0;
++}
++
++
++#endif /* CONFIG_POWER4 */
++
++static long
++core99_read_gpio(struct device_node *node, long param, long value)
++{
++	struct macio_chip *macio = &macio_chips[0];
++
++	return MACIO_IN8(param);
++}
++
++
++static long
++core99_write_gpio(struct device_node *node, long param, long value)
++{
++	struct macio_chip *macio = &macio_chips[0];
++
++	MACIO_OUT8(param, (u8)(value & 0xff));
++	return 0;
++}
++
++#ifdef CONFIG_POWER4
++static long g5_gmac_enable(struct device_node *node, long param, long value)
++{
++	struct macio_chip *macio = &macio_chips[0];
++	unsigned long flags;
++
++	if (node == NULL)
++		return -ENODEV;
++
++	LOCK(flags);
++	if (value) {
++		MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
++		mb();
++		k2_skiplist[0] = NULL;
++	} else {
++		k2_skiplist[0] = node;
++		mb();
++		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
++	}
++	
++	UNLOCK(flags);
++	mdelay(1);
++
++	return 0;
++}
++
++static long g5_fw_enable(struct device_node *node, long param, long value)
++{
++	struct macio_chip *macio = &macio_chips[0];
++	unsigned long flags;
++
++	if (node == NULL)
++		return -ENODEV;
++
++	LOCK(flags);
++	if (value) {
++		MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
++		mb();
++		k2_skiplist[1] = NULL;
++	} else {
++		k2_skiplist[1] = node;
++		mb();
++		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
++	}
++	
++	UNLOCK(flags);
++	mdelay(1);
++
++	return 0;
++}
++
++static long g5_mpic_enable(struct device_node *node, long param, long value)
++{
++	unsigned long flags;
++
++	if (node->parent == NULL || strcmp(node->parent->name, "u3"))
++		return 0;
++
++	LOCK(flags);
++	UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
++	UNLOCK(flags);
++
++	return 0;
++}
++
++static long g5_eth_phy_reset(struct device_node *node, long param, long value)
++{
++	struct macio_chip *macio = &macio_chips[0];
++	struct device_node *phy;
++	int need_reset;
++
++	/*
++	 * We must not reset the combo PHYs, only the BCM5221 found in
++	 * the iMac G5.
++	 */
++	phy = of_get_next_child(node, NULL);
++	if (!phy)
++		return -ENODEV;
++	need_reset = device_is_compatible(phy, "B5221");
++	of_node_put(phy);
++	if (!need_reset)
++		return 0;
++
++	/* PHY reset is GPIO 29, not in device-tree unfortunately */
++	MACIO_OUT8(K2_GPIO_EXTINT_0 + 29,
++		   KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
++	/* Thankfully, this is now always called at a time when we can
++	 * schedule by sungem.
++	 */
++	msleep(10);
++	MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0);
++
++	return 0;
++}
++
++static long g5_i2s_enable(struct device_node *node, long param, long value)
++{
++	/* Very crude implementation for now */
++	struct macio_chip *macio = &macio_chips[0];
++	unsigned long flags;
++
++	if (value == 0)
++		return 0; /* don't disable yet */
++
++	LOCK(flags);
++	MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE |
++		  KL3_I2S0_CLK18_ENABLE);
++	udelay(10);
++	MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE |
++		  K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE);
++	udelay(10);
++	MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET);
++	UNLOCK(flags);
++	udelay(10);
++
++	return 0;
++}
++
++
++#ifdef CONFIG_SMP
++static long g5_reset_cpu(struct device_node *node, long param, long value)
++{
++	unsigned int reset_io = 0;
++	unsigned long flags;
++	struct macio_chip *macio;
++	struct device_node *np;
++
++	macio = &macio_chips[0];
++	if (macio->type != macio_keylargo2)
++		return -ENODEV;
++
++	np = find_path_device("/cpus");
++	if (np == NULL)
++		return -ENODEV;
++	for (np = np->child; np != NULL; np = np->sibling) {
++		u32 *num = (u32 *)get_property(np, "reg", NULL);
++		u32 *rst = (u32 *)get_property(np, "soft-reset", NULL);
++		if (num == NULL || rst == NULL)
++			continue;
++		if (param == *num) {
++			reset_io = *rst;
++			break;
++		}
++	}
++	if (np == NULL || reset_io == 0)
++		return -ENODEV;
++
++	LOCK(flags);
++	MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
++	(void)MACIO_IN8(reset_io);
++	udelay(1);
++	MACIO_OUT8(reset_io, 0);
++	(void)MACIO_IN8(reset_io);
++	UNLOCK(flags);
++
++	return 0;
++}
++#endif /* CONFIG_SMP */
++
++/*
++ * This can be called from pmac_smp so isn't static
++ *
++ * This takes the second CPU off the bus on dual CPU machines
++ * running UP
++ */
++void g5_phy_disable_cpu1(void)
++{
++	UN_OUT(U3_API_PHY_CONFIG_1, 0);
++}
++#endif /* CONFIG_POWER4 */
++
++#ifndef CONFIG_POWER4
++
++static void
++keylargo_shutdown(struct macio_chip *macio, int sleep_mode)
++{
++	u32 temp;
++
++	if (sleep_mode) {
++		mdelay(1);
++		MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
++		(void)MACIO_IN32(KEYLARGO_FCR0);
++		mdelay(1);
++	}
++
++	MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
++				KL0_SCC_CELL_ENABLE |
++				KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
++				KL0_IRDA_CLK19_ENABLE);
++
++	MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
++	MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
++
++	MACIO_BIC(KEYLARGO_FCR1,
++		KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
++		KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
++		KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
++		KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
++		KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
++		KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
++		KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
++		KL1_UIDE_ENABLE);
++
++	MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
++	MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
++
++	temp = MACIO_IN32(KEYLARGO_FCR3);
++	if (macio->rev >= 2) {
++		temp |= KL3_SHUTDOWN_PLL2X;
++		if (sleep_mode)
++			temp |= KL3_SHUTDOWN_PLL_TOTAL;
++	}
++
++	temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
++		KL3_SHUTDOWN_PLLKW35;
++	if (sleep_mode)
++		temp |= KL3_SHUTDOWN_PLLKW12;
++	temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
++		| KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
++	if (sleep_mode)
++		temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
++	MACIO_OUT32(KEYLARGO_FCR3, temp);
++
++	/* Flush posted writes & wait a bit */
++	(void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
++}
++
++static void
++pangea_shutdown(struct macio_chip *macio, int sleep_mode)
++{
++	u32 temp;
++
++	MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
++				KL0_SCC_CELL_ENABLE |
++				KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
++
++	MACIO_BIC(KEYLARGO_FCR1,
++		KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
++		KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
++		KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
++		KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
++		KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
++		KL1_UIDE_ENABLE);
++	if (pmac_mb.board_flags & PMAC_MB_MOBILE)
++		MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
++
++	MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
++
++	temp = MACIO_IN32(KEYLARGO_FCR3);
++	temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
++		KL3_SHUTDOWN_PLLKW35;
++	temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE
++		| KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE);
++	if (sleep_mode)
++		temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE);
++	MACIO_OUT32(KEYLARGO_FCR3, temp);
++
++	/* Flush posted writes & wait a bit */
++	(void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
++}
++
++static void
++intrepid_shutdown(struct macio_chip *macio, int sleep_mode)
++{
++	u32 temp;
++
++	MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
++		  KL0_SCC_CELL_ENABLE);
++
++	MACIO_BIC(KEYLARGO_FCR1,
++		  /*KL1_USB2_CELL_ENABLE |*/
++		KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
++		KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
++		KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE);
++	if (pmac_mb.board_flags & PMAC_MB_MOBILE)
++		MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
++
++	temp = MACIO_IN32(KEYLARGO_FCR3);
++	temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE |
++		  KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
++	if (sleep_mode)
++		temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE);
++	MACIO_OUT32(KEYLARGO_FCR3, temp);
++
++	/* Flush posted writes & wait a bit */
++	(void)MACIO_IN32(KEYLARGO_FCR0);
++	mdelay(10);
++}
++
++
++void pmac_tweak_clock_spreading(int enable)
++{
++	struct macio_chip *macio = &macio_chips[0];
++
++	/* Hack for doing clock spreading on some machines PowerBooks and
++	 * iBooks. This implements the "platform-do-clockspreading" OF
++	 * property as decoded manually on various models. For safety, we also
++	 * check the product ID in the device-tree in cases we'll whack the i2c
++	 * chip to make reasonably sure we won't set wrong values in there
++	 *
++	 * Of course, ultimately, we have to implement a real parser for
++	 * the platform-do-* stuff...
++	 */
++
++	if (macio->type == macio_intrepid) {
++		if (enable)
++			UN_OUT(UNI_N_CLOCK_SPREADING, 2);
++		else
++			UN_OUT(UNI_N_CLOCK_SPREADING, 0);
++		mdelay(40);
++	}
++
++	while (machine_is_compatible("PowerBook5,2") ||
++	       machine_is_compatible("PowerBook5,3") ||
++	       machine_is_compatible("PowerBook6,2") ||
++	       machine_is_compatible("PowerBook6,3")) {
++		struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
++		struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
++		u8 buffer[9];
++		u32 *productID;
++		int i, rc, changed = 0;
++
++		if (dt == NULL)
++			break;
++		productID = (u32 *)get_property(dt, "pid#", NULL);
++		if (productID == NULL)
++			break;
++		while(ui2c) {
++			struct device_node *p = of_get_parent(ui2c);
++			if (p && !strcmp(p->name, "uni-n"))
++				break;
++			ui2c = of_find_node_by_type(ui2c, "i2c");
++		}
++		if (ui2c == NULL)
++			break;
++		DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
++		rc = pmac_low_i2c_open(ui2c, 1);
++		if (rc != 0)
++			break;
++		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
++		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
++		DBG("read result: %d,", rc);
++		if (rc != 0) {
++			pmac_low_i2c_close(ui2c);
++			break;
++		}
++		for (i=0; i<9; i++)
++			DBG(" %02x", buffer[i]);
++		DBG("\n");
++
++		switch(*productID) {
++		case 0x1182:	/* AlBook 12" rev 2 */
++		case 0x1183:	/* iBook G4 12" */
++			buffer[0] = (buffer[0] & 0x8f) | 0x70;
++			buffer[2] = (buffer[2] & 0x7f) | 0x00;
++			buffer[5] = (buffer[5] & 0x80) | 0x31;
++			buffer[6] = (buffer[6] & 0x40) | 0xb0;
++			buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba);
++			buffer[8] = (buffer[8] & 0x00) | 0x30;
++			changed = 1;
++			break;
++		case 0x3142:	/* AlBook 15" (ATI M10) */
++		case 0x3143:	/* AlBook 17" (ATI M10) */
++			buffer[0] = (buffer[0] & 0xaf) | 0x50;
++			buffer[2] = (buffer[2] & 0x7f) | 0x00;
++			buffer[5] = (buffer[5] & 0x80) | 0x31;
++			buffer[6] = (buffer[6] & 0x40) | 0xb0;
++			buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0);
++			buffer[8] = (buffer[8] & 0x00) | 0x30;
++			changed = 1;
++			break;
++		default:
++			DBG("i2c-hwclock: Machine model not handled\n");
++			break;
++		}
++		if (!changed) {
++			pmac_low_i2c_close(ui2c);
++			break;
++		}
++		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
++		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
++		DBG("write result: %d,", rc);
++		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
++		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
++		DBG("read result: %d,", rc);
++		if (rc != 0) {
++			pmac_low_i2c_close(ui2c);
++			break;
++		}
++		for (i=0; i<9; i++)
++			DBG(" %02x", buffer[i]);
++		pmac_low_i2c_close(ui2c);
++		break;
++	}
++}
++
++
++static int
++core99_sleep(void)
++{
++	struct macio_chip *macio;
++	int i;
++
++	macio = &macio_chips[0];
++	if (macio->type != macio_keylargo && macio->type != macio_pangea &&
++	    macio->type != macio_intrepid)
++		return -ENODEV;
++
++	/* We power off the wireless slot in case it was not done
++	 * by the driver. We don't power it on automatically however
++	 */
++	if (macio->flags & MACIO_FLAG_AIRPORT_ON)
++		core99_airport_enable(macio->of_node, 0, 0);
++
++	/* We power off the FW cable. Should be done by the driver... */
++	if (macio->flags & MACIO_FLAG_FW_SUPPORTED) {
++		core99_firewire_enable(NULL, 0, 0);
++		core99_firewire_cable_power(NULL, 0, 0);
++	}
++
++	/* We make sure int. modem is off (in case driver lost it) */
++	if (macio->type == macio_keylargo)
++		core99_modem_enable(macio->of_node, 0, 0);
++	else
++		pangea_modem_enable(macio->of_node, 0, 0);
++
++	/* We make sure the sound is off as well */
++	core99_sound_chip_enable(macio->of_node, 0, 0);
++
++	/*
++	 * Save various bits of KeyLargo
++	 */
++
++	/* Save the state of the various GPIOs */
++	save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0);
++	save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1);
++	for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
++		save_gpio_extint[i] = MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+i);
++	for (i=0; i<KEYLARGO_GPIO_CNT; i++)
++		save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i);
++
++	/* Save the FCRs */
++	if (macio->type == macio_keylargo)
++		save_mbcr = MACIO_IN32(KEYLARGO_MBCR);
++	save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0);
++	save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1);
++	save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2);
++	save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3);
++	save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4);
++	if (macio->type == macio_pangea || macio->type == macio_intrepid)
++		save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5);
++
++	/* Save state & config of DBDMA channels */
++	dbdma_save(macio, save_dbdma);
++
++	/*
++	 * Turn off as much as we can
++	 */
++	if (macio->type == macio_pangea)
++		pangea_shutdown(macio, 1);
++	else if (macio->type == macio_intrepid)
++		intrepid_shutdown(macio, 1);
++	else if (macio->type == macio_keylargo)
++		keylargo_shutdown(macio, 1);
++
++	/*
++	 * Put the host bridge to sleep
++	 */
++
++	save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
++	/* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it
++	 * enabled !
++	 */
++	UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
++	       ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
++	udelay(100);
++	UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
++	UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
++	mdelay(10);
++
++	/*
++	 * FIXME: A bit of black magic with OpenPIC (don't ask me why)
++	 */
++	if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
++		MACIO_BIS(0x506e0, 0x00400000);
++		MACIO_BIS(0x506e0, 0x80000000);
++	}
++	return 0;
++}
++
++static int
++core99_wake_up(void)
++{
++	struct macio_chip *macio;
++	int i;
++
++	macio = &macio_chips[0];
++	if (macio->type != macio_keylargo && macio->type != macio_pangea &&
++	    macio->type != macio_intrepid)
++		return -ENODEV;
++
++	/*
++	 * Wakeup the host bridge
++	 */
++	UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
++	udelay(10);
++	UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
++	udelay(10);
++
++	/*
++	 * Restore KeyLargo
++	 */
++
++	if (macio->type == macio_keylargo) {
++		MACIO_OUT32(KEYLARGO_MBCR, save_mbcr);
++		(void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
++	}
++	MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]);
++	(void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
++	MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]);
++	(void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
++	MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]);
++	(void)MACIO_IN32(KEYLARGO_FCR2); udelay(10);
++	MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]);
++	(void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
++	MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]);
++	(void)MACIO_IN32(KEYLARGO_FCR4); udelay(10);
++	if (macio->type == macio_pangea || macio->type == macio_intrepid) {
++		MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]);
++		(void)MACIO_IN32(KEYLARGO_FCR5); udelay(10);
++	}
++
++	dbdma_restore(macio, save_dbdma);
++
++	MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
++	MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
++	for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
++		MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+i, save_gpio_extint[i]);
++	for (i=0; i<KEYLARGO_GPIO_CNT; i++)
++		MACIO_OUT8(KEYLARGO_GPIO_0+i, save_gpio_normal[i]);
++
++	/* FIXME more black magic with OpenPIC ... */
++	if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
++		MACIO_BIC(0x506e0, 0x00400000);
++		MACIO_BIC(0x506e0, 0x80000000);
++	}
++
++	UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
++	udelay(100);
++
++	return 0;
++}
++
++static long
++core99_sleep_state(struct device_node *node, long param, long value)
++{
++	/* Param == 1 means to enter the "fake sleep" mode that is
++	 * used for CPU speed switch
++	 */
++	if (param == 1) {
++		if (value == 1) {
++			UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
++			UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_IDLE2);
++		} else {
++			UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
++			udelay(10);
++			UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
++			udelay(10);
++		}
++		return 0;
++	}
++	if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
++		return -EPERM;
++
++	if (value == 1)
++		return core99_sleep();
++	else if (value == 0)
++		return core99_wake_up();
++	return 0;
++}
++
++#endif /* CONFIG_POWER4 */
++
++static long
++generic_dev_can_wake(struct device_node *node, long param, long value)
++{
++	/* Todo: eventually check we are really dealing with on-board
++	 * video device ...
++	 */
++
++	if (pmac_mb.board_flags & PMAC_MB_MAY_SLEEP)
++		pmac_mb.board_flags |= PMAC_MB_CAN_SLEEP;
++	return 0;
++}
++
++static long generic_get_mb_info(struct device_node *node, long param, long value)
++{
++	switch(param) {
++		case PMAC_MB_INFO_MODEL:
++			return pmac_mb.model_id;
++		case PMAC_MB_INFO_FLAGS:
++			return pmac_mb.board_flags;
++		case PMAC_MB_INFO_NAME:
++			/* hack hack hack... but should work */
++			*((const char **)value) = pmac_mb.model_name;
++			return 0;
++	}
++	return -EINVAL;
++}
++
++
++/*
++ * Table definitions
++ */
++
++/* Used on any machine
++ */
++static struct feature_table_entry any_features[] = {
++	{ PMAC_FTR_GET_MB_INFO,		generic_get_mb_info },
++	{ PMAC_FTR_DEVICE_CAN_WAKE,	generic_dev_can_wake },
++	{ 0, NULL }
++};
++
++#ifndef CONFIG_POWER4
++
++/* OHare based motherboards. Currently, we only use these on the
++ * 2400,3400 and 3500 series powerbooks. Some older desktops seem
++ * to have issues with turning on/off those asic cells
++ */
++static struct feature_table_entry ohare_features[] = {
++	{ PMAC_FTR_SCC_ENABLE,		ohare_htw_scc_enable },
++	{ PMAC_FTR_SWIM3_ENABLE,	ohare_floppy_enable },
++	{ PMAC_FTR_MESH_ENABLE,		ohare_mesh_enable },
++	{ PMAC_FTR_IDE_ENABLE,		ohare_ide_enable},
++	{ PMAC_FTR_IDE_RESET,		ohare_ide_reset},
++	{ PMAC_FTR_SLEEP_STATE,		ohare_sleep_state },
++	{ 0, NULL }
++};
++
++/* Heathrow desktop machines (Beige G3).
++ * Separated as some features couldn't be properly tested
++ * and the serial port control bits appear to confuse it.
++ */
++static struct feature_table_entry heathrow_desktop_features[] = {
++	{ PMAC_FTR_SWIM3_ENABLE,	heathrow_floppy_enable },
++	{ PMAC_FTR_MESH_ENABLE,		heathrow_mesh_enable },
++	{ PMAC_FTR_IDE_ENABLE,		heathrow_ide_enable },
++	{ PMAC_FTR_IDE_RESET,		heathrow_ide_reset },
++	{ PMAC_FTR_BMAC_ENABLE,		heathrow_bmac_enable },
++	{ 0, NULL }
++};
++
++/* Heathrow based laptop, that is the Wallstreet and mainstreet
++ * powerbooks.
++ */
++static struct feature_table_entry heathrow_laptop_features[] = {
++	{ PMAC_FTR_SCC_ENABLE,		ohare_htw_scc_enable },
++	{ PMAC_FTR_MODEM_ENABLE,	heathrow_modem_enable },
++	{ PMAC_FTR_SWIM3_ENABLE,	heathrow_floppy_enable },
++	{ PMAC_FTR_MESH_ENABLE,		heathrow_mesh_enable },
++	{ PMAC_FTR_IDE_ENABLE,		heathrow_ide_enable },
++	{ PMAC_FTR_IDE_RESET,		heathrow_ide_reset },
++	{ PMAC_FTR_BMAC_ENABLE,		heathrow_bmac_enable },
++	{ PMAC_FTR_SOUND_CHIP_ENABLE,	heathrow_sound_enable },
++	{ PMAC_FTR_SLEEP_STATE,		heathrow_sleep_state },
++	{ 0, NULL }
++};
++
++/* Paddington based machines
++ * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
++ */
++static struct feature_table_entry paddington_features[] = {
++	{ PMAC_FTR_SCC_ENABLE,		ohare_htw_scc_enable },
++	{ PMAC_FTR_MODEM_ENABLE,	heathrow_modem_enable },
++	{ PMAC_FTR_SWIM3_ENABLE,	heathrow_floppy_enable },
++	{ PMAC_FTR_MESH_ENABLE,		heathrow_mesh_enable },
++	{ PMAC_FTR_IDE_ENABLE,		heathrow_ide_enable },
++	{ PMAC_FTR_IDE_RESET,		heathrow_ide_reset },
++	{ PMAC_FTR_BMAC_ENABLE,		heathrow_bmac_enable },
++	{ PMAC_FTR_SOUND_CHIP_ENABLE,	heathrow_sound_enable },
++	{ PMAC_FTR_SLEEP_STATE,		heathrow_sleep_state },
++	{ 0, NULL }
++};
++
++/* Core99 & MacRISC 2 machines (all machines released since the
++ * iBook (included), that is all AGP machines, except pangea
++ * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
++ * used on iBook2 & iMac "flow power".
++ */
++static struct feature_table_entry core99_features[] = {
++	{ PMAC_FTR_SCC_ENABLE,		core99_scc_enable },
++	{ PMAC_FTR_MODEM_ENABLE,	core99_modem_enable },
++	{ PMAC_FTR_IDE_ENABLE,		core99_ide_enable },
++	{ PMAC_FTR_IDE_RESET,		core99_ide_reset },
++	{ PMAC_FTR_GMAC_ENABLE,		core99_gmac_enable },
++	{ PMAC_FTR_GMAC_PHY_RESET,	core99_gmac_phy_reset },
++	{ PMAC_FTR_SOUND_CHIP_ENABLE,	core99_sound_chip_enable },
++	{ PMAC_FTR_AIRPORT_ENABLE,	core99_airport_enable },
++	{ PMAC_FTR_USB_ENABLE,		core99_usb_enable },
++	{ PMAC_FTR_1394_ENABLE,		core99_firewire_enable },
++	{ PMAC_FTR_1394_CABLE_POWER,	core99_firewire_cable_power },
++	{ PMAC_FTR_SLEEP_STATE,		core99_sleep_state },
++#ifdef CONFIG_SMP
++	{ PMAC_FTR_RESET_CPU,		core99_reset_cpu },
++#endif /* CONFIG_SMP */
++	{ PMAC_FTR_READ_GPIO,		core99_read_gpio },
++	{ PMAC_FTR_WRITE_GPIO,		core99_write_gpio },
++	{ 0, NULL }
++};
++
++/* RackMac
++ */
++static struct feature_table_entry rackmac_features[] = {
++	{ PMAC_FTR_SCC_ENABLE,		core99_scc_enable },
++	{ PMAC_FTR_IDE_ENABLE,		core99_ide_enable },
++	{ PMAC_FTR_IDE_RESET,		core99_ide_reset },
++	{ PMAC_FTR_GMAC_ENABLE,		core99_gmac_enable },
++	{ PMAC_FTR_GMAC_PHY_RESET,	core99_gmac_phy_reset },
++	{ PMAC_FTR_USB_ENABLE,		core99_usb_enable },
++	{ PMAC_FTR_1394_ENABLE,		core99_firewire_enable },
++	{ PMAC_FTR_1394_CABLE_POWER,	core99_firewire_cable_power },
++	{ PMAC_FTR_SLEEP_STATE,		core99_sleep_state },
++#ifdef CONFIG_SMP
++	{ PMAC_FTR_RESET_CPU,		core99_reset_cpu },
++#endif /* CONFIG_SMP */
++	{ PMAC_FTR_READ_GPIO,		core99_read_gpio },
++	{ PMAC_FTR_WRITE_GPIO,		core99_write_gpio },
++	{ 0, NULL }
++};
++
++/* Pangea features
++ */
++static struct feature_table_entry pangea_features[] = {
++	{ PMAC_FTR_SCC_ENABLE,		core99_scc_enable },
++	{ PMAC_FTR_MODEM_ENABLE,	pangea_modem_enable },
++	{ PMAC_FTR_IDE_ENABLE,		core99_ide_enable },
++	{ PMAC_FTR_IDE_RESET,		core99_ide_reset },
++	{ PMAC_FTR_GMAC_ENABLE,		core99_gmac_enable },
++	{ PMAC_FTR_GMAC_PHY_RESET,	core99_gmac_phy_reset },
++	{ PMAC_FTR_SOUND_CHIP_ENABLE,	core99_sound_chip_enable },
++	{ PMAC_FTR_AIRPORT_ENABLE,	core99_airport_enable },
++	{ PMAC_FTR_USB_ENABLE,		core99_usb_enable },
++	{ PMAC_FTR_1394_ENABLE,		core99_firewire_enable },
++	{ PMAC_FTR_1394_CABLE_POWER,	core99_firewire_cable_power },
++	{ PMAC_FTR_SLEEP_STATE,		core99_sleep_state },
++	{ PMAC_FTR_READ_GPIO,		core99_read_gpio },
++	{ PMAC_FTR_WRITE_GPIO,		core99_write_gpio },
++	{ 0, NULL }
++};
++
++/* Intrepid features
++ */
++static struct feature_table_entry intrepid_features[] = {
++	{ PMAC_FTR_SCC_ENABLE,		core99_scc_enable },
++	{ PMAC_FTR_MODEM_ENABLE,	pangea_modem_enable },
++	{ PMAC_FTR_IDE_ENABLE,		core99_ide_enable },
++	{ PMAC_FTR_IDE_RESET,		core99_ide_reset },
++	{ PMAC_FTR_GMAC_ENABLE,		core99_gmac_enable },
++	{ PMAC_FTR_GMAC_PHY_RESET,	core99_gmac_phy_reset },
++	{ PMAC_FTR_SOUND_CHIP_ENABLE,	core99_sound_chip_enable },
++	{ PMAC_FTR_AIRPORT_ENABLE,	core99_airport_enable },
++	{ PMAC_FTR_USB_ENABLE,		core99_usb_enable },
++	{ PMAC_FTR_1394_ENABLE,		core99_firewire_enable },
++	{ PMAC_FTR_1394_CABLE_POWER,	core99_firewire_cable_power },
++	{ PMAC_FTR_SLEEP_STATE,		core99_sleep_state },
++	{ PMAC_FTR_READ_GPIO,		core99_read_gpio },
++	{ PMAC_FTR_WRITE_GPIO,		core99_write_gpio },
++	{ PMAC_FTR_AACK_DELAY_ENABLE,	intrepid_aack_delay_enable },
++	{ 0, NULL }
++};
++
++#else /* CONFIG_POWER4 */
++
++/* G5 features
++ */
++static struct feature_table_entry g5_features[] = {
++	{ PMAC_FTR_GMAC_ENABLE,		g5_gmac_enable },
++	{ PMAC_FTR_1394_ENABLE,		g5_fw_enable },
++	{ PMAC_FTR_ENABLE_MPIC,		g5_mpic_enable },
++	{ PMAC_FTR_GMAC_PHY_RESET,	g5_eth_phy_reset },
++	{ PMAC_FTR_SOUND_CHIP_ENABLE,	g5_i2s_enable },
++#ifdef CONFIG_SMP
++	{ PMAC_FTR_RESET_CPU,		g5_reset_cpu },
++#endif /* CONFIG_SMP */
++	{ PMAC_FTR_READ_GPIO,		core99_read_gpio },
++	{ PMAC_FTR_WRITE_GPIO,		core99_write_gpio },
++	{ 0, NULL }
++};
++
++#endif /* CONFIG_POWER4 */
++
++static struct pmac_mb_def pmac_mb_defs[] = {
++#ifndef CONFIG_POWER4
++	/*
++	 * Desktops
++	 */
++
++	{	"AAPL,8500",			"PowerMac 8500/8600",
++		PMAC_TYPE_PSURGE,		NULL,
++		0
++	},
++	{	"AAPL,9500",			"PowerMac 9500/9600",
++		PMAC_TYPE_PSURGE,		NULL,
++		0
++	},
++	{	"AAPL,7200",			"PowerMac 7200",
++		PMAC_TYPE_PSURGE,		NULL,
++		0
++	},
++	{	"AAPL,7300",			"PowerMac 7200/7300",
++		PMAC_TYPE_PSURGE,		NULL,
++		0
++	},
++	{	"AAPL,7500",			"PowerMac 7500",
++		PMAC_TYPE_PSURGE,		NULL,
++		0
++	},
++	{	"AAPL,ShinerESB",		"Apple Network Server",
++		PMAC_TYPE_ANS,			NULL,
++		0
++	},
++	{	"AAPL,e407",			"Alchemy",
++		PMAC_TYPE_ALCHEMY,		NULL,
++		0
++	},
++	{	"AAPL,e411",			"Gazelle",
++		PMAC_TYPE_GAZELLE,		NULL,
++		0
++	},
++	{	"AAPL,Gossamer",		"PowerMac G3 (Gossamer)",
++		PMAC_TYPE_GOSSAMER,		heathrow_desktop_features,
++		0
++	},
++	{	"AAPL,PowerMac G3",		"PowerMac G3 (Silk)",
++		PMAC_TYPE_SILK,			heathrow_desktop_features,
++		0
++	},
++	{	"PowerMac1,1",			"Blue&White G3",
++		PMAC_TYPE_YOSEMITE,		paddington_features,
++		0
++	},
++	{	"PowerMac1,2",			"PowerMac G4 PCI Graphics",
++		PMAC_TYPE_YIKES,		paddington_features,
++		0
++	},
++	{	"PowerMac2,1",			"iMac FireWire",
++		PMAC_TYPE_FW_IMAC,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
++	},
++	{	"PowerMac2,2",			"iMac FireWire",
++		PMAC_TYPE_FW_IMAC,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
++	},
++	{	"PowerMac3,1",			"PowerMac G4 AGP Graphics",
++		PMAC_TYPE_SAWTOOTH,		core99_features,
++		PMAC_MB_OLD_CORE99
++	},
++	{	"PowerMac3,2",			"PowerMac G4 AGP Graphics",
++		PMAC_TYPE_SAWTOOTH,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
++	},
++	{	"PowerMac3,3",			"PowerMac G4 AGP Graphics",
++		PMAC_TYPE_SAWTOOTH,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
++	},
++	{	"PowerMac3,4",			"PowerMac G4 Silver",
++		PMAC_TYPE_QUICKSILVER,		core99_features,
++		PMAC_MB_MAY_SLEEP
++	},
++	{	"PowerMac3,5",			"PowerMac G4 Silver",
++		PMAC_TYPE_QUICKSILVER,		core99_features,
++		PMAC_MB_MAY_SLEEP
++	},
++	{	"PowerMac3,6",			"PowerMac G4 Windtunnel",
++		PMAC_TYPE_WINDTUNNEL,		core99_features,
++		PMAC_MB_MAY_SLEEP,
++	},
++	{	"PowerMac4,1",			"iMac \"Flower Power\"",
++		PMAC_TYPE_PANGEA_IMAC,		pangea_features,
++		PMAC_MB_MAY_SLEEP
++	},
++	{	"PowerMac4,2",			"Flat panel iMac",
++		PMAC_TYPE_FLAT_PANEL_IMAC,	pangea_features,
++		PMAC_MB_CAN_SLEEP
++	},
++	{	"PowerMac4,4",			"eMac",
++		PMAC_TYPE_EMAC,			core99_features,
++		PMAC_MB_MAY_SLEEP
++	},
++	{	"PowerMac5,1",			"PowerMac G4 Cube",
++		PMAC_TYPE_CUBE,			core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
++	},
++	{	"PowerMac6,1",			"Flat panel iMac",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP,
++	},
++	{	"PowerMac6,3",			"Flat panel iMac",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP,
++	},
++	{	"PowerMac6,4",			"eMac",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP,
++	},
++	{	"PowerMac10,1",			"Mac mini",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER,
++	},
++	{	"iMac,1",			"iMac (first generation)",
++		PMAC_TYPE_ORIG_IMAC,		paddington_features,
++		0
++	},
++
++	/*
++	 * Xserve's
++	 */
++
++	{	"RackMac1,1",			"XServe",
++		PMAC_TYPE_RACKMAC,		rackmac_features,
++		0,
++	},
++	{	"RackMac1,2",			"XServe rev. 2",
++		PMAC_TYPE_RACKMAC,		rackmac_features,
++		0,
++	},
++
++	/*
++	 * Laptops
++	 */
++
++	{	"AAPL,3400/2400",		"PowerBook 3400",
++		PMAC_TYPE_HOOPER,		ohare_features,
++		PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
++	},
++	{	"AAPL,3500",			"PowerBook 3500",
++		PMAC_TYPE_KANGA,		ohare_features,
++		PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
++	},
++	{	"AAPL,PowerBook1998",		"PowerBook Wallstreet",
++		PMAC_TYPE_WALLSTREET,		heathrow_laptop_features,
++		PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
++	},
++	{	"PowerBook1,1",			"PowerBook 101 (Lombard)",
++		PMAC_TYPE_101_PBOOK,		paddington_features,
++		PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
++	},
++	{	"PowerBook2,1",			"iBook (first generation)",
++		PMAC_TYPE_ORIG_IBOOK,		core99_features,
++		PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
++	},
++	{	"PowerBook2,2",			"iBook FireWire",
++		PMAC_TYPE_FW_IBOOK,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
++		PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
++	},
++	{	"PowerBook3,1",			"PowerBook Pismo",
++		PMAC_TYPE_PISMO,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
++		PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
++	},
++	{	"PowerBook3,2",			"PowerBook Titanium",
++		PMAC_TYPE_TITANIUM,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
++	},
++	{	"PowerBook3,3",			"PowerBook Titanium II",
++		PMAC_TYPE_TITANIUM2,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
++	},
++	{	"PowerBook3,4",			"PowerBook Titanium III",
++		PMAC_TYPE_TITANIUM3,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
++	},
++	{	"PowerBook3,5",			"PowerBook Titanium IV",
++		PMAC_TYPE_TITANIUM4,		core99_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
++	},
++	{	"PowerBook4,1",			"iBook 2",
++		PMAC_TYPE_IBOOK2,		pangea_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
++	},
++	{	"PowerBook4,2",			"iBook 2",
++		PMAC_TYPE_IBOOK2,		pangea_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
++	},
++	{	"PowerBook4,3",			"iBook 2 rev. 2",
++		PMAC_TYPE_IBOOK2,		pangea_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
++	},
++	{	"PowerBook5,1",			"PowerBook G4 17\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook5,2",			"PowerBook G4 15\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook5,3",			"PowerBook G4 17\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook5,4",			"PowerBook G4 15\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook5,5",			"PowerBook G4 17\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook5,6",			"PowerBook G4 15\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook5,7",			"PowerBook G4 17\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook6,1",			"PowerBook G4 12\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook6,2",			"PowerBook G4",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook6,3",			"iBook G4",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook6,4",			"PowerBook G4 12\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook6,5",			"iBook G4",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook6,7",			"iBook G4",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++	{	"PowerBook6,8",			"PowerBook G4 12\"",
++		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
++		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
++	},
++#else /* CONFIG_POWER4 */
++	{	"PowerMac7,2",			"PowerMac G5",
++		PMAC_TYPE_POWERMAC_G5,		g5_features,
++		0,
++	},
++#ifdef CONFIG_PPC64
++	{	"PowerMac7,3",			"PowerMac G5",
++		PMAC_TYPE_POWERMAC_G5,		g5_features,
++		0,
++	},
++	{	"PowerMac8,1",			"iMac G5",
++		PMAC_TYPE_IMAC_G5,		g5_features,
++		0,
++	},
++	{	"PowerMac9,1",			"PowerMac G5",
++		PMAC_TYPE_POWERMAC_G5_U3L,	g5_features,
++		0,
++	},
++	{       "RackMac3,1",                   "XServe G5",
++		PMAC_TYPE_XSERVE_G5,		g5_features,
++		0,
++	},
++#endif /* CONFIG_PPC64 */
++#endif /* CONFIG_POWER4 */
++};
++
++/*
++ * The toplevel feature_call callback
++ */
++long pmac_do_feature_call(unsigned int selector, ...)
++{
++	struct device_node *node;
++	long param, value;
++	int i;
++	feature_call func = NULL;
++	va_list args;
++
++	if (pmac_mb.features)
++		for (i=0; pmac_mb.features[i].function; i++)
++			if (pmac_mb.features[i].selector == selector) {
++				func = pmac_mb.features[i].function;
++				break;
++			}
++	if (!func)
++		for (i=0; any_features[i].function; i++)
++			if (any_features[i].selector == selector) {
++				func = any_features[i].function;
++				break;
++			}
++	if (!func)
++		return -ENODEV;
++
++	va_start(args, selector);
++	node = (struct device_node*)va_arg(args, void*);
++	param = va_arg(args, long);
++	value = va_arg(args, long);
++	va_end(args);
++
++	return func(node, param, value);
++}
++
++static int __init probe_motherboard(void)
++{
++	int i;
++	struct macio_chip *macio = &macio_chips[0];
++	const char *model = NULL;
++	struct device_node *dt;
++
++	/* Lookup known motherboard type in device-tree. First try an
++	 * exact match on the "model" property, then try a "compatible"
++	 * match is none is found.
++	 */
++	dt = find_devices("device-tree");
++	if (dt != NULL)
++		model = (const char *) get_property(dt, "model", NULL);
++	for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
++	    if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
++		pmac_mb = pmac_mb_defs[i];
++		goto found;
++	    }
++	}
++	for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
++	    if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
++		pmac_mb = pmac_mb_defs[i];
++		goto found;
++	    }
++	}
++
++	/* Fallback to selection depending on mac-io chip type */
++	switch(macio->type) {
++#ifndef CONFIG_POWER4
++	    case macio_grand_central:
++		pmac_mb.model_id = PMAC_TYPE_PSURGE;
++		pmac_mb.model_name = "Unknown PowerSurge";
++		break;
++	    case macio_ohare:
++		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE;
++		pmac_mb.model_name = "Unknown OHare-based";
++		break;
++	    case macio_heathrow:
++		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW;
++		pmac_mb.model_name = "Unknown Heathrow-based";
++		pmac_mb.features = heathrow_desktop_features;
++		break;
++	    case macio_paddington:
++		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON;
++		pmac_mb.model_name = "Unknown Paddington-based";
++		pmac_mb.features = paddington_features;
++		break;
++	    case macio_keylargo:
++		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99;
++		pmac_mb.model_name = "Unknown Keylargo-based";
++		pmac_mb.features = core99_features;
++		break;
++	    case macio_pangea:
++		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
++		pmac_mb.model_name = "Unknown Pangea-based";
++		pmac_mb.features = pangea_features;
++		break;
++	    case macio_intrepid:
++		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
++		pmac_mb.model_name = "Unknown Intrepid-based";
++		pmac_mb.features = intrepid_features;
++		break;
++#else /* CONFIG_POWER4 */
++	case macio_keylargo2:
++		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
++		pmac_mb.model_name = "Unknown K2-based";
++		pmac_mb.features = g5_features;
++		break;
++#endif /* CONFIG_POWER4 */
++	default:
++		return -ENODEV;
++	}
++found:
++#ifndef CONFIG_POWER4
++	/* Fixup Hooper vs. Comet */
++	if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {
++		u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4);
++		if (!mach_id_ptr)
++			return -ENODEV;
++		/* Here, I used to disable the media-bay on comet. It
++		 * appears this is wrong, the floppy connector is actually
++		 * a kind of media-bay and works with the current driver.
++		 */
++		if (__raw_readl(mach_id_ptr) & 0x20000000UL)
++			pmac_mb.model_id = PMAC_TYPE_COMET;
++		iounmap(mach_id_ptr);
++	}
++#endif /* CONFIG_POWER4 */
++
++#ifdef CONFIG_6xx
++	/* Set default value of powersave_nap on machines that support it.
++	 * It appears that uninorth rev 3 has a problem with it, we don't
++	 * enable it on those. In theory, the flush-on-lock property is
++	 * supposed to be set when not supported, but I'm not very confident
++	 * that all Apple OF revs did it properly, I do it the paranoid way.
++	 */
++	while (uninorth_base && uninorth_rev > 3) {
++		struct device_node *np = find_path_device("/cpus");
++		if (!np || !np->child) {
++			printk(KERN_WARNING "Can't find CPU(s) in device tree !\n");
++			break;
++		}
++		np = np->child;
++		/* Nap mode not supported on SMP */
++		if (np->sibling)
++			break;
++		/* Nap mode not supported if flush-on-lock property is present */
++		if (get_property(np, "flush-on-lock", NULL))
++			break;
++		powersave_nap = 1;
++		printk(KERN_INFO "Processor NAP mode on idle enabled.\n");
++		break;
++	}
++
++	/* On CPUs that support it (750FX), lowspeed by default during
++	 * NAP mode
++	 */
++	powersave_lowspeed = 1;
++#endif /* CONFIG_6xx */
++#ifdef CONFIG_POWER4
++	powersave_nap = 1;
++#endif
++	/* Check for "mobile" machine */
++	if (model && (strncmp(model, "PowerBook", 9) == 0
++		   || strncmp(model, "iBook", 5) == 0))
++		pmac_mb.board_flags |= PMAC_MB_MOBILE;
++
++
++	printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
++	return 0;
++}
++
++/* Initialize the Core99 UniNorth host bridge and memory controller
++ */
++static void __init probe_uninorth(void)
++{
++	unsigned long actrl;
++
++	/* Locate core99 Uni-N */
++	uninorth_node = of_find_node_by_name(NULL, "uni-n");
++	/* Locate G5 u3 */
++	if (uninorth_node == NULL) {
++		uninorth_node = of_find_node_by_name(NULL, "u3");
++		uninorth_u3 = 1;
++	}
++	if (uninorth_node && uninorth_node->n_addrs > 0) {
++		unsigned long address = uninorth_node->addrs[0].address;
++		uninorth_base = ioremap(address, 0x40000);
++		uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
++		if (uninorth_u3)
++			u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
++	} else
++		uninorth_node = NULL;
++
++	if (!uninorth_node)
++		return;
++
++	printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n",
++	       uninorth_u3 ? "U3" : "UniNorth", uninorth_rev);
++	printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
++
++	/* Set the arbitrer QAck delay according to what Apple does
++	 */
++	if (uninorth_rev < 0x11) {
++		actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
++		actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
++			UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
++		UN_OUT(UNI_N_ARB_CTRL, actrl);
++	}
++
++	/* Some more magic as done by them in recent MacOS X on UniNorth
++	 * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI
++	 * memory timeout
++	 */
++	if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0)
++		UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
++}
++
++static void __init probe_one_macio(const char *name, const char *compat, int type)
++{
++	struct device_node*	node;
++	int			i;
++	volatile u32 __iomem *	base;
++	u32*			revp;
++
++	node = find_devices(name);
++	if (!node || !node->n_addrs)
++		return;
++	if (compat)
++		do {
++			if (device_is_compatible(node, compat))
++				break;
++			node = node->next;
++		} while (node);
++	if (!node)
++		return;
++	for(i=0; i<MAX_MACIO_CHIPS; i++) {
++		if (!macio_chips[i].of_node)
++			break;
++		if (macio_chips[i].of_node == node)
++			return;
++	}
++	if (i >= MAX_MACIO_CHIPS) {
++		printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
++		printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
++		return;
++	}
++	base = ioremap(node->addrs[0].address, node->addrs[0].size);
++	if (!base) {
++		printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
++		return;
++	}
++	if (type == macio_keylargo) {
++		u32 *did = (u32 *)get_property(node, "device-id", NULL);
++		if (*did == 0x00000025)
++			type = macio_pangea;
++		if (*did == 0x0000003e)
++			type = macio_intrepid;
++	}
++	macio_chips[i].of_node	= node;
++	macio_chips[i].type	= type;
++	macio_chips[i].base	= base;
++	macio_chips[i].flags	= MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
++	macio_chips[i].name	= macio_names[type];
++	revp = (u32 *)get_property(node, "revision-id", NULL);
++	if (revp)
++		macio_chips[i].rev = *revp;
++	printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
++		macio_names[type], macio_chips[i].rev, macio_chips[i].base);
++}
++
++static int __init
++probe_macios(void)
++{
++	/* Warning, ordering is important */
++	probe_one_macio("gc", NULL, macio_grand_central);
++	probe_one_macio("ohare", NULL, macio_ohare);
++	probe_one_macio("pci106b,7", NULL, macio_ohareII);
++	probe_one_macio("mac-io", "keylargo", macio_keylargo);
++	probe_one_macio("mac-io", "paddington", macio_paddington);
++	probe_one_macio("mac-io", "gatwick", macio_gatwick);
++	probe_one_macio("mac-io", "heathrow", macio_heathrow);
++	probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
++
++	/* Make sure the "main" macio chip appear first */
++	if (macio_chips[0].type == macio_gatwick
++	    && macio_chips[1].type == macio_heathrow) {
++		struct macio_chip temp = macio_chips[0];
++		macio_chips[0] = macio_chips[1];
++		macio_chips[1] = temp;
++	}
++	if (macio_chips[0].type == macio_ohareII
++	    && macio_chips[1].type == macio_ohare) {
++		struct macio_chip temp = macio_chips[0];
++		macio_chips[0] = macio_chips[1];
++		macio_chips[1] = temp;
++	}
++	macio_chips[0].lbus.index = 0;
++	macio_chips[1].lbus.index = 1;
++
++	return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
++}
++
++static void __init
++initial_serial_shutdown(struct device_node *np)
++{
++	int len;
++	struct slot_names_prop {
++		int	count;
++		char	name[1];
++	} *slots;
++	char *conn;
++	int port_type = PMAC_SCC_ASYNC;
++	int modem = 0;
++
++	slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
++	conn = get_property(np, "AAPL,connector", &len);
++	if (conn && (strcmp(conn, "infrared") == 0))
++		port_type = PMAC_SCC_IRDA;
++	else if (device_is_compatible(np, "cobalt"))
++		modem = 1;
++	else if (slots && slots->count > 0) {
++		if (strcmp(slots->name, "IrDA") == 0)
++			port_type = PMAC_SCC_IRDA;
++		else if (strcmp(slots->name, "Modem") == 0)
++			modem = 1;
++	}
++	if (modem)
++		pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0);
++	pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0);
++}
++
++static void __init
++set_initial_features(void)
++{
++	struct device_node *np;
++
++	/* That hack appears to be necessary for some StarMax motherboards
++	 * but I'm not too sure it was audited for side-effects on other
++	 * ohare based machines...
++	 * Since I still have difficulties figuring the right way to
++	 * differenciate them all and since that hack was there for a long
++	 * time, I'll keep it around
++	 */
++	if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) {
++		struct macio_chip *macio = &macio_chips[0];
++		MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES);
++	} else if (macio_chips[0].type == macio_ohare) {
++		struct macio_chip *macio = &macio_chips[0];
++		MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
++	} else if (macio_chips[1].type == macio_ohare) {
++		struct macio_chip *macio = &macio_chips[1];
++		MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
++	}
++
++#ifdef CONFIG_POWER4
++	if (macio_chips[0].type == macio_keylargo2) {
++#ifndef CONFIG_SMP
++		/* On SMP machines running UP, we have the second CPU eating
++		 * bus cycles. We need to take it off the bus. This is done
++		 * from pmac_smp for SMP kernels running on one CPU
++		 */
++		np = of_find_node_by_type(NULL, "cpu");
++		if (np != NULL)
++			np = of_find_node_by_type(np, "cpu");
++		if (np != NULL) {
++			g5_phy_disable_cpu1();
++			of_node_put(np);
++		}
++#endif /* CONFIG_SMP */
++		/* Enable GMAC for now for PCI probing. It will be disabled
++		 * later on after PCI probe
++		 */
++		np = of_find_node_by_name(NULL, "ethernet");
++		while(np) {
++			if (device_is_compatible(np, "K2-GMAC"))
++				g5_gmac_enable(np, 0, 1);
++			np = of_find_node_by_name(np, "ethernet");
++		}
++
++		/* Enable FW before PCI probe. Will be disabled later on
++		 * Note: We should have a batter way to check that we are
++		 * dealing with uninorth internal cell and not a PCI cell
++		 * on the external PCI. The code below works though.
++		 */
++		np = of_find_node_by_name(NULL, "firewire");
++		while(np) {
++			if (device_is_compatible(np, "pci106b,5811")) {
++				macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
++				g5_fw_enable(np, 0, 1);
++			}
++			np = of_find_node_by_name(np, "firewire");
++		}
++	}
++#else /* CONFIG_POWER4 */
++
++	if (macio_chips[0].type == macio_keylargo ||
++	    macio_chips[0].type == macio_pangea ||
++	    macio_chips[0].type == macio_intrepid) {
++		/* Enable GMAC for now for PCI probing. It will be disabled
++		 * later on after PCI probe
++		 */
++		np = of_find_node_by_name(NULL, "ethernet");
++		while(np) {
++			if (np->parent
++			    && device_is_compatible(np->parent, "uni-north")
++			    && device_is_compatible(np, "gmac"))
++				core99_gmac_enable(np, 0, 1);
++			np = of_find_node_by_name(np, "ethernet");
++		}
++
++		/* Enable FW before PCI probe. Will be disabled later on
++		 * Note: We should have a batter way to check that we are
++		 * dealing with uninorth internal cell and not a PCI cell
++		 * on the external PCI. The code below works though.
++		 */
++		np = of_find_node_by_name(NULL, "firewire");
++		while(np) {
++			if (np->parent
++			    && device_is_compatible(np->parent, "uni-north")
++			    && (device_is_compatible(np, "pci106b,18") ||
++			        device_is_compatible(np, "pci106b,30") ||
++			        device_is_compatible(np, "pci11c1,5811"))) {
++				macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
++				core99_firewire_enable(np, 0, 1);
++			}
++			np = of_find_node_by_name(np, "firewire");
++		}
++
++		/* Enable ATA-100 before PCI probe. */
++		np = of_find_node_by_name(NULL, "ata-6");
++		while(np) {
++			if (np->parent
++			    && device_is_compatible(np->parent, "uni-north")
++			    && device_is_compatible(np, "kauai-ata")) {
++				core99_ata100_enable(np, 1);
++			}
++			np = of_find_node_by_name(np, "ata-6");
++		}
++
++		/* Switch airport off */
++		np = find_devices("radio");
++		while(np) {
++			if (np && np->parent == macio_chips[0].of_node) {
++				macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
++				core99_airport_enable(np, 0, 0);
++			}
++			np = np->next;
++		}
++	}
++
++	/* On all machines that support sound PM, switch sound off */
++	if (macio_chips[0].of_node)
++		pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
++			macio_chips[0].of_node, 0, 0);
++
++	/* While on some desktop G3s, we turn it back on */
++	if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
++		&& (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
++		    pmac_mb.model_id == PMAC_TYPE_SILK)) {
++		struct macio_chip *macio = &macio_chips[0];
++		MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
++		MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
++	}
++
++	/* Some machine models need the clock chip to be properly setup for
++	 * clock spreading now. This should be a platform function but we
++	 * don't do these at the moment
++	 */
++	pmac_tweak_clock_spreading(1);
++
++#endif /* CONFIG_POWER4 */
++
++	/* On all machines, switch modem & serial ports off */
++	np = find_devices("ch-a");
++	while(np) {
++		initial_serial_shutdown(np);
++		np = np->next;
++	}
++	np = find_devices("ch-b");
++	while(np) {
++		initial_serial_shutdown(np);
++		np = np->next;
++	}
++}
++
++void __init
++pmac_feature_init(void)
++{
++	/* Detect the UniNorth memory controller */
++	probe_uninorth();
++
++	/* Probe mac-io controllers */
++	if (probe_macios()) {
++		printk(KERN_WARNING "No mac-io chip found\n");
++		return;
++	}
++
++	/* Setup low-level i2c stuffs */
++	pmac_init_low_i2c();
++
++	/* Probe machine type */
++	if (probe_motherboard())
++		printk(KERN_WARNING "Unknown PowerMac !\n");
++
++	/* Set some initial features (turn off some chips that will
++	 * be later turned on)
++	 */
++	set_initial_features();
++}
++
++int __init pmac_feature_late_init(void)
++{
++#if 0
++	struct device_node *np;
++
++	/* Request some resources late */
++	if (uninorth_node)
++		request_OF_resource(uninorth_node, 0, NULL);
++	np = find_devices("hammerhead");
++	if (np)
++		request_OF_resource(np, 0, NULL);
++	np = find_devices("interrupt-controller");
++	if (np)
++		request_OF_resource(np, 0, NULL);
++#endif
++	return 0;
++}
++
++device_initcall(pmac_feature_late_init);
++
++#if 0
++static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
++{
++	int	freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
++	int	bits[8] = { 8,16,0,32,2,4,0,0 };
++	int	freq = (frq >> 8) & 0xf;
++
++	if (freqs[freq] == 0)
++		printk("%s: Unknown HT link frequency %x\n", name, freq);
++	else
++		printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
++		       name, freqs[freq],
++		       bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
++}
++
++void __init pmac_check_ht_link(void)
++{
++	u32	ufreq, freq, ucfg, cfg;
++	struct device_node *pcix_node;
++	u8	px_bus, px_devfn;
++	struct pci_controller *px_hose;
++
++	(void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
++	ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
++	ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
++	dump_HT_speeds("U3 HyperTransport", cfg, freq);
++
++	pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
++	if (pcix_node == NULL) {
++		printk("No PCI-X bridge found\n");
++		return;
++	}
++	if (pci_device_from_OF_node(pcix_node, &px_bus, &px_devfn) != 0) {
++		printk("PCI-X bridge found but not matched to pci\n");
++		return;
++	}
++	px_hose = pci_find_hose_for_OF_device(pcix_node);
++	if (px_hose == NULL) {
++		printk("PCI-X bridge found but not matched to host\n");
++		return;
++	}	
++	early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
++	early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
++	dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
++	early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
++	early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
++	dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
++}
++#endif /* 0 */
++
++/*
++ * Early video resume hook
++ */
++
++static void (*pmac_early_vresume_proc)(void *data);
++static void *pmac_early_vresume_data;
++
++void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
++{
++	if (_machine != _MACH_Pmac)
++		return;
++	preempt_disable();
++	pmac_early_vresume_proc = proc;
++	pmac_early_vresume_data = data;
++	preempt_enable();
++}
++EXPORT_SYMBOL(pmac_set_early_video_resume);
++
++void pmac_call_early_video_resume(void)
++{
++	if (pmac_early_vresume_proc)
++		pmac_early_vresume_proc(pmac_early_vresume_data);
++}
++
++/*
++ * AGP related suspend/resume code
++ */
++
++static struct pci_dev *pmac_agp_bridge;
++static int (*pmac_agp_suspend)(struct pci_dev *bridge);
++static int (*pmac_agp_resume)(struct pci_dev *bridge);
++
++void pmac_register_agp_pm(struct pci_dev *bridge,
++				 int (*suspend)(struct pci_dev *bridge),
++				 int (*resume)(struct pci_dev *bridge))
++{
++	if (suspend || resume) {
++		pmac_agp_bridge = bridge;
++		pmac_agp_suspend = suspend;
++		pmac_agp_resume = resume;
++		return;
++	}
++	if (bridge != pmac_agp_bridge)
++		return;
++	pmac_agp_suspend = pmac_agp_resume = NULL;
++	return;
++}
++EXPORT_SYMBOL(pmac_register_agp_pm);
++
++void pmac_suspend_agp_for_card(struct pci_dev *dev)
++{
++	if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
++		return;
++	if (pmac_agp_bridge->bus != dev->bus)
++		return;
++	pmac_agp_suspend(pmac_agp_bridge);
++}
++EXPORT_SYMBOL(pmac_suspend_agp_for_card);
++
++void pmac_resume_agp_for_card(struct pci_dev *dev)
++{
++	if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
++		return;
++	if (pmac_agp_bridge->bus != dev->bus)
++		return;
++	pmac_agp_resume(pmac_agp_bridge);
++}
++EXPORT_SYMBOL(pmac_resume_agp_for_card);
+diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/low_i2c.c
+@@ -0,0 +1,523 @@
++/*
++ *  arch/ppc/platforms/pmac_low_i2c.c
++ *
++ *  Copyright (C) 2003 Ben. Herrenschmidt (benh at 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.
++ *
++ *  This file contains some low-level i2c access routines that
++ *  need to be used by various bits of the PowerMac platform code
++ *  at times where the real asynchronous & interrupt driven driver
++ *  cannot be used. The API borrows some semantics from the darwin
++ *  driver in order to ease the implementation of the platform
++ *  properties parser
++ */
++
++#undef DEBUG
++
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/adb.h>
++#include <linux/pmu.h>
++#include <asm/keylargo.h>
++#include <asm/uninorth.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++#include <asm/pmac_low_i2c.h>
++
++#define MAX_LOW_I2C_HOST	4
++
++#ifdef DEBUG
++#define DBG(x...) do {\
++		printk(KERN_DEBUG "KW:" x);	\
++	} while(0)
++#else
++#define DBG(x...)
++#endif
++
++struct low_i2c_host;
++
++typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len);
++
++struct low_i2c_host
++{
++	struct device_node	*np;		/* OF device node */
++	struct semaphore	mutex;		/* Access mutex for use by i2c-keywest */
++	low_i2c_func_t		func;		/* Access function */
++	unsigned int		is_open : 1;	/* Poor man's access control */
++	int			mode;		/* Current mode */
++	int			channel;	/* Current channel */
++	int			num_channels;	/* Number of channels */
++	void __iomem		*base;		/* For keywest-i2c, base address */
++	int			bsteps;		/* And register stepping */
++	int			speed;		/* And speed */
++};
++
++static struct low_i2c_host	low_i2c_hosts[MAX_LOW_I2C_HOST];
++
++/* No locking is necessary on allocation, we are running way before
++ * anything can race with us
++ */
++static struct low_i2c_host *find_low_i2c_host(struct device_node *np)
++{
++	int i;
++
++	for (i = 0; i < MAX_LOW_I2C_HOST; i++)
++		if (low_i2c_hosts[i].np == np)
++			return &low_i2c_hosts[i];
++	return NULL;
++}
++
++/*
++ *
++ * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's)
++ *
++ */
++
++/*
++ * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h,
++ * should be moved somewhere in include/asm-ppc/
++ */
++/* Register indices */
++typedef enum {
++	reg_mode = 0,
++	reg_control,
++	reg_status,
++	reg_isr,
++	reg_ier,
++	reg_addr,
++	reg_subaddr,
++	reg_data
++} reg_t;
++
++
++/* Mode register */
++#define KW_I2C_MODE_100KHZ	0x00
++#define KW_I2C_MODE_50KHZ	0x01
++#define KW_I2C_MODE_25KHZ	0x02
++#define KW_I2C_MODE_DUMB	0x00
++#define KW_I2C_MODE_STANDARD	0x04
++#define KW_I2C_MODE_STANDARDSUB	0x08
++#define KW_I2C_MODE_COMBINED	0x0C
++#define KW_I2C_MODE_MODE_MASK	0x0C
++#define KW_I2C_MODE_CHAN_MASK	0xF0
++
++/* Control register */
++#define KW_I2C_CTL_AAK		0x01
++#define KW_I2C_CTL_XADDR	0x02
++#define KW_I2C_CTL_STOP		0x04
++#define KW_I2C_CTL_START	0x08
++
++/* Status register */
++#define KW_I2C_STAT_BUSY	0x01
++#define KW_I2C_STAT_LAST_AAK	0x02
++#define KW_I2C_STAT_LAST_RW	0x04
++#define KW_I2C_STAT_SDA		0x08
++#define KW_I2C_STAT_SCL		0x10
++
++/* IER & ISR registers */
++#define KW_I2C_IRQ_DATA		0x01
++#define KW_I2C_IRQ_ADDR		0x02
++#define KW_I2C_IRQ_STOP		0x04
++#define KW_I2C_IRQ_START	0x08
++#define KW_I2C_IRQ_MASK		0x0F
++
++/* State machine states */
++enum {
++	state_idle,
++	state_addr,
++	state_read,
++	state_write,
++	state_stop,
++	state_dead
++};
++
++#define WRONG_STATE(name) do {\
++		printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \
++		       name, __kw_state_names[state], isr); \
++	} while(0)
++
++static const char *__kw_state_names[] = {
++	"state_idle",
++	"state_addr",
++	"state_read",
++	"state_write",
++	"state_stop",
++	"state_dead"
++};
++
++static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg)
++{
++	return readb(host->base + (((unsigned int)reg) << host->bsteps));
++}
++
++static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val)
++{
++	writeb(val, host->base + (((unsigned)reg) << host->bsteps));
++	(void)__kw_read_reg(host, reg_subaddr);
++}
++
++#define kw_write_reg(reg, val)	__kw_write_reg(host, reg, val) 
++#define kw_read_reg(reg)	__kw_read_reg(host, reg) 
++
++
++/* Don't schedule, the g5 fan controller is too
++ * timing sensitive
++ */
++static u8 kw_wait_interrupt(struct low_i2c_host* host)
++{
++	int i, j;
++	u8 isr;
++	
++	for (i = 0; i < 100000; i++) {
++		isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK;
++		if (isr != 0)
++			return isr;
++
++		/* This code is used with the timebase frozen, we cannot rely
++		 * on udelay ! For now, just use a bogus loop
++		 */
++		for (j = 1; j < 10000; j++)
++			mb();
++	}
++	return isr;
++}
++
++static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr)
++{
++	u8 ack;
++
++	DBG("kw_handle_interrupt(%s, isr: %x)\n", __kw_state_names[state], isr);
++
++	if (isr == 0) {
++		if (state != state_stop) {
++			DBG("KW: Timeout !\n");
++			*rc = -EIO;
++			goto stop;
++		}
++		if (state == state_stop) {
++			ack = kw_read_reg(reg_status);
++			if (!(ack & KW_I2C_STAT_BUSY)) {
++				state = state_idle;
++				kw_write_reg(reg_ier, 0x00);
++			}
++		}
++		return state;
++	}
++
++	if (isr & KW_I2C_IRQ_ADDR) {
++		ack = kw_read_reg(reg_status);
++		if (state != state_addr) {
++			kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
++			WRONG_STATE("KW_I2C_IRQ_ADDR"); 
++			*rc = -EIO;
++			goto stop;
++		}
++		if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {			
++			*rc = -ENODEV;
++			DBG("KW: NAK on address\n");
++			return state_stop;		     
++		} else {
++			if (rw) {
++				state = state_read;
++				if (*len > 1)
++					kw_write_reg(reg_control, KW_I2C_CTL_AAK);
++			} else {
++				state = state_write;
++				kw_write_reg(reg_data, **data);
++				(*data)++; (*len)--;
++			}
++		}
++		kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
++	}
++
++	if (isr & KW_I2C_IRQ_DATA) {
++		if (state == state_read) {
++			**data = kw_read_reg(reg_data);
++			(*data)++; (*len)--;
++			kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
++			if ((*len) == 0)
++				state = state_stop;
++			else if ((*len) == 1)
++				kw_write_reg(reg_control, 0);
++		} else if (state == state_write) {
++			ack = kw_read_reg(reg_status);
++			if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
++				DBG("KW: nack on data write\n");
++				*rc = -EIO;
++				goto stop;
++			} else if (*len) {
++				kw_write_reg(reg_data, **data);
++				(*data)++; (*len)--;
++			} else {
++				kw_write_reg(reg_control, KW_I2C_CTL_STOP);
++				state = state_stop;
++				*rc = 0;
++			}
++			kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
++		} else {
++			kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
++			WRONG_STATE("KW_I2C_IRQ_DATA"); 
++			if (state != state_stop) {
++				*rc = -EIO;
++				goto stop;
++			}
++		}
++	}
++
++	if (isr & KW_I2C_IRQ_STOP) {
++		kw_write_reg(reg_isr, KW_I2C_IRQ_STOP);
++		if (state != state_stop) {
++			WRONG_STATE("KW_I2C_IRQ_STOP");
++			*rc = -EIO;
++		}
++		return state_idle;
++	}
++
++	if (isr & KW_I2C_IRQ_START)
++		kw_write_reg(reg_isr, KW_I2C_IRQ_START);
++
++	return state;
++
++ stop:
++	kw_write_reg(reg_control, KW_I2C_CTL_STOP);	
++	return state_stop;
++}
++
++static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len)
++{
++	u8 mode_reg = host->speed;
++	int state = state_addr;
++	int rc = 0;
++
++	/* Setup mode & subaddress if any */
++	switch(host->mode) {
++	case pmac_low_i2c_mode_dumb:
++		printk(KERN_ERR "low_i2c: Dumb mode not supported !\n");
++		return -EINVAL;
++	case pmac_low_i2c_mode_std:
++		mode_reg |= KW_I2C_MODE_STANDARD;
++		break;
++	case pmac_low_i2c_mode_stdsub:
++		mode_reg |= KW_I2C_MODE_STANDARDSUB;
++		break;
++	case pmac_low_i2c_mode_combined:
++		mode_reg |= KW_I2C_MODE_COMBINED;
++		break;
++	}
++
++	/* Setup channel & clear pending irqs */
++	kw_write_reg(reg_isr, kw_read_reg(reg_isr));
++	kw_write_reg(reg_mode, mode_reg | (host->channel << 4));
++	kw_write_reg(reg_status, 0);
++
++	/* Set up address and r/w bit */
++	kw_write_reg(reg_addr, addr);
++
++	/* Set up the sub address */
++	if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB
++	    || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED)
++		kw_write_reg(reg_subaddr, subaddr);
++
++	/* Start sending address & disable interrupt*/
++	kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/);
++	kw_write_reg(reg_control, KW_I2C_CTL_XADDR);
++
++	/* State machine, to turn into an interrupt handler */
++	while(state != state_idle) {
++		u8 isr = kw_wait_interrupt(host);
++		state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr);
++	}
++
++	return rc;
++}
++
++static void keywest_low_i2c_add(struct device_node *np)
++{
++	struct low_i2c_host	*host = find_low_i2c_host(NULL);
++	u32			*psteps, *prate, steps, aoffset = 0;
++	struct device_node	*parent;
++
++	if (host == NULL) {
++		printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
++		       np->full_name);
++		return;
++	}
++	memset(host, 0, sizeof(*host));
++
++	init_MUTEX(&host->mutex);
++	host->np = of_node_get(np);	
++	psteps = (u32 *)get_property(np, "AAPL,address-step", NULL);
++	steps = psteps ? (*psteps) : 0x10;
++	for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
++		steps >>= 1;
++	parent = of_get_parent(np);
++	host->num_channels = 1;
++	if (parent && parent->name[0] == 'u') {
++		host->num_channels = 2;
++		aoffset = 3;
++	}
++	/* Select interface rate */
++	host->speed = KW_I2C_MODE_100KHZ;
++	prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL);
++	if (prate) switch(*prate) {
++	case 100:
++		host->speed = KW_I2C_MODE_100KHZ;
++		break;
++	case 50:
++		host->speed = KW_I2C_MODE_50KHZ;
++		break;
++	case 25:
++		host->speed = KW_I2C_MODE_25KHZ;
++		break;
++	}	
++
++	host->mode = pmac_low_i2c_mode_std;
++	host->base = ioremap(np->addrs[0].address + aoffset,
++						np->addrs[0].size);
++	host->func = keywest_low_i2c_func;
++}
++
++/*
++ *
++ * PMU implementation
++ *
++ */
++
++
++#ifdef CONFIG_ADB_PMU
++
++static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len)
++{
++	// TODO
++	return -ENODEV;
++}
++
++static void pmu_low_i2c_add(struct device_node *np)
++{
++	struct low_i2c_host	*host = find_low_i2c_host(NULL);
++
++	if (host == NULL) {
++		printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
++		       np->full_name);
++		return;
++	}
++	memset(host, 0, sizeof(*host));
++
++	init_MUTEX(&host->mutex);
++	host->np = of_node_get(np);	
++	host->num_channels = 3;
++	host->mode = pmac_low_i2c_mode_std;
++	host->func = pmu_low_i2c_func;
++}
++
++#endif /* CONFIG_ADB_PMU */
++
++void __init pmac_init_low_i2c(void)
++{
++	struct device_node *np;
++
++	/* Probe keywest-i2c busses */
++	np = of_find_compatible_node(NULL, "i2c", "keywest-i2c");
++	while(np) {
++		keywest_low_i2c_add(np);
++		np = of_find_compatible_node(np, "i2c", "keywest-i2c");
++	}
++
++#ifdef CONFIG_ADB_PMU
++	/* Probe PMU busses */
++	np = of_find_node_by_name(NULL, "via-pmu");
++	if (np)
++		pmu_low_i2c_add(np);
++#endif /* CONFIG_ADB_PMU */
++
++	/* TODO: Add CUDA support as well */
++}
++
++int pmac_low_i2c_lock(struct device_node *np)
++{
++	struct low_i2c_host *host = find_low_i2c_host(np);
++
++	if (!host)
++		return -ENODEV;
++	down(&host->mutex);
++	return 0;
++}
++EXPORT_SYMBOL(pmac_low_i2c_lock);
++
++int pmac_low_i2c_unlock(struct device_node *np)
++{
++	struct low_i2c_host *host = find_low_i2c_host(np);
++
++	if (!host)
++		return -ENODEV;
++	up(&host->mutex);
++	return 0;
++}
++EXPORT_SYMBOL(pmac_low_i2c_unlock);
++
++
++int pmac_low_i2c_open(struct device_node *np, int channel)
++{
++	struct low_i2c_host *host = find_low_i2c_host(np);
++
++	if (!host)
++		return -ENODEV;
++
++	if (channel >= host->num_channels)
++		return -EINVAL;
++
++	down(&host->mutex);
++	host->is_open = 1;
++	host->channel = channel;
++
++	return 0;
++}
++EXPORT_SYMBOL(pmac_low_i2c_open);
++
++int pmac_low_i2c_close(struct device_node *np)
++{
++	struct low_i2c_host *host = find_low_i2c_host(np);
++
++	if (!host)
++		return -ENODEV;
++
++	host->is_open = 0;
++	up(&host->mutex);
++
++	return 0;
++}
++EXPORT_SYMBOL(pmac_low_i2c_close);
++
++int pmac_low_i2c_setmode(struct device_node *np, int mode)
++{
++	struct low_i2c_host *host = find_low_i2c_host(np);
++
++	if (!host)
++		return -ENODEV;
++	WARN_ON(!host->is_open);
++	host->mode = mode;
++
++	return 0;
++}
++EXPORT_SYMBOL(pmac_low_i2c_setmode);
++
++int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len)
++{
++	struct low_i2c_host *host = find_low_i2c_host(np);
++
++	if (!host)
++		return -ENODEV;
++	WARN_ON(!host->is_open);
++
++	return host->func(host, addrdir, subaddr, data, len);
++}
++EXPORT_SYMBOL(pmac_low_i2c_xfer);
++
+diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/nvram.c
+@@ -0,0 +1,645 @@
++/*
++ *  arch/ppc/platforms/pmac_nvram.c
++ *
++ *  Copyright (C) 2002 Benjamin Herrenschmidt (benh at 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.
++ *
++ *  Todo: - add support for the OF persistent properties
++ */
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/stddef.h>
++#include <linux/string.h>
++#include <linux/nvram.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/adb.h>
++#include <linux/pmu.h>
++#include <linux/bootmem.h>
++#include <linux/completion.h>
++#include <linux/spinlock.h>
++#include <asm/sections.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++#include <asm/nvram.h>
++
++#define DEBUG
++
++#ifdef DEBUG
++#define DBG(x...) printk(x)
++#else
++#define DBG(x...)
++#endif
++
++#define NVRAM_SIZE		0x2000	/* 8kB of non-volatile RAM */
++
++#define CORE99_SIGNATURE	0x5a
++#define CORE99_ADLER_START	0x14
++
++/* On Core99, nvram is either a sharp, a micron or an AMD flash */
++#define SM_FLASH_STATUS_DONE	0x80
++#define SM_FLASH_STATUS_ERR	0x38
++
++#define SM_FLASH_CMD_ERASE_CONFIRM	0xd0
++#define SM_FLASH_CMD_ERASE_SETUP	0x20
++#define SM_FLASH_CMD_RESET		0xff
++#define SM_FLASH_CMD_WRITE_SETUP	0x40
++#define SM_FLASH_CMD_CLEAR_STATUS	0x50
++#define SM_FLASH_CMD_READ_STATUS	0x70
++
++/* CHRP NVRAM header */
++struct chrp_header {
++  u8		signature;
++  u8		cksum;
++  u16		len;
++  char          name[12];
++  u8		data[0];
++};
++
++struct core99_header {
++  struct chrp_header	hdr;
++  u32			adler;
++  u32			generation;
++  u32			reserved[2];
++};
++
++/*
++ * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
++ */
++static int nvram_naddrs;
++static volatile unsigned char *nvram_data;
++static int is_core_99;
++static int core99_bank = 0;
++static int nvram_partitions[3];
++// XXX Turn that into a sem
++static DEFINE_SPINLOCK(nv_lock);
++
++extern int pmac_newworld;
++extern int system_running;
++
++static int (*core99_write_bank)(int bank, u8* datas);
++static int (*core99_erase_bank)(int bank);
++
++static char *nvram_image;
++
++
++static unsigned char core99_nvram_read_byte(int addr)
++{
++	if (nvram_image == NULL)
++		return 0xff;
++	return nvram_image[addr];
++}
++
++static void core99_nvram_write_byte(int addr, unsigned char val)
++{
++	if (nvram_image == NULL)
++		return;
++	nvram_image[addr] = val;
++}
++
++static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index)
++{
++	int i;
++
++	if (nvram_image == NULL)
++		return -ENODEV;
++	if (*index > NVRAM_SIZE)
++		return 0;
++
++	i = *index;
++	if (i + count > NVRAM_SIZE)
++		count = NVRAM_SIZE - i;
++
++	memcpy(buf, &nvram_image[i], count);
++	*index = i + count;
++	return count;
++}
++
++static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index)
++{
++	int i;
++
++	if (nvram_image == NULL)
++		return -ENODEV;
++	if (*index > NVRAM_SIZE)
++		return 0;
++
++	i = *index;
++	if (i + count > NVRAM_SIZE)
++		count = NVRAM_SIZE - i;
++
++	memcpy(&nvram_image[i], buf, count);
++	*index = i + count;
++	return count;
++}
++
++static ssize_t core99_nvram_size(void)
++{
++	if (nvram_image == NULL)
++		return -ENODEV;
++	return NVRAM_SIZE;
++}
++
++#ifdef CONFIG_PPC32
++static volatile unsigned char *nvram_addr;
++static int nvram_mult;
++
++static unsigned char direct_nvram_read_byte(int addr)
++{
++	return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
++}
++
++static void direct_nvram_write_byte(int addr, unsigned char val)
++{
++	out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
++}
++
++
++static unsigned char indirect_nvram_read_byte(int addr)
++{
++	unsigned char val;
++	unsigned long flags;
++
++	spin_lock_irqsave(&nv_lock, flags);
++	out_8(nvram_addr, addr >> 5);
++	val = in_8(&nvram_data[(addr & 0x1f) << 4]);
++	spin_unlock_irqrestore(&nv_lock, flags);
++
++	return val;
++}
++
++static void indirect_nvram_write_byte(int addr, unsigned char val)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&nv_lock, flags);
++	out_8(nvram_addr, addr >> 5);
++	out_8(&nvram_data[(addr & 0x1f) << 4], val);
++	spin_unlock_irqrestore(&nv_lock, flags);
++}
++
++
++#ifdef CONFIG_ADB_PMU
++
++static void pmu_nvram_complete(struct adb_request *req)
++{
++	if (req->arg)
++		complete((struct completion *)req->arg);
++}
++
++static unsigned char pmu_nvram_read_byte(int addr)
++{
++	struct adb_request req;
++	DECLARE_COMPLETION(req_complete); 
++	
++	req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
++	if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
++			(addr >> 8) & 0xff, addr & 0xff))
++		return 0xff;
++	if (system_state == SYSTEM_RUNNING)
++		wait_for_completion(&req_complete);
++	while (!req.complete)
++		pmu_poll();
++	return req.reply[0];
++}
++
++static void pmu_nvram_write_byte(int addr, unsigned char val)
++{
++	struct adb_request req;
++	DECLARE_COMPLETION(req_complete); 
++	
++	req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
++	if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
++			(addr >> 8) & 0xff, addr & 0xff, val))
++		return;
++	if (system_state == SYSTEM_RUNNING)
++		wait_for_completion(&req_complete);
++	while (!req.complete)
++		pmu_poll();
++}
++
++#endif /* CONFIG_ADB_PMU */
++#endif /* CONFIG_PPC32 */
++
++static u8 chrp_checksum(struct chrp_header* hdr)
++{
++	u8 *ptr;
++	u16 sum = hdr->signature;
++	for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
++		sum += *ptr;
++	while (sum > 0xFF)
++		sum = (sum & 0xFF) + (sum>>8);
++	return sum;
++}
++
++static u32 core99_calc_adler(u8 *buffer)
++{
++	int cnt;
++	u32 low, high;
++
++   	buffer += CORE99_ADLER_START;
++	low = 1;
++	high = 0;
++	for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
++		if ((cnt % 5000) == 0) {
++			high  %= 65521UL;
++			high %= 65521UL;
++		}
++		low += buffer[cnt];
++		high += low;
++	}
++	low  %= 65521UL;
++	high %= 65521UL;
++
++	return (high << 16) | low;
++}
++
++static u32 core99_check(u8* datas)
++{
++	struct core99_header* hdr99 = (struct core99_header*)datas;
++
++	if (hdr99->hdr.signature != CORE99_SIGNATURE) {
++		DBG("Invalid signature\n");
++		return 0;
++	}
++	if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
++		DBG("Invalid checksum\n");
++		return 0;
++	}
++	if (hdr99->adler != core99_calc_adler(datas)) {
++		DBG("Invalid adler\n");
++		return 0;
++	}
++	return hdr99->generation;
++}
++
++static int sm_erase_bank(int bank)
++{
++	int stat, i;
++	unsigned long timeout;
++
++	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
++
++       	DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
++
++	out_8(base, SM_FLASH_CMD_ERASE_SETUP);
++	out_8(base, SM_FLASH_CMD_ERASE_CONFIRM);
++	timeout = 0;
++	do {
++		if (++timeout > 1000000) {
++			printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n");
++			break;
++		}
++		out_8(base, SM_FLASH_CMD_READ_STATUS);
++		stat = in_8(base);
++	} while (!(stat & SM_FLASH_STATUS_DONE));
++
++	out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
++	out_8(base, SM_FLASH_CMD_RESET);
++
++	for (i=0; i<NVRAM_SIZE; i++)
++		if (base[i] != 0xff) {
++			printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n");
++			return -ENXIO;
++		}
++	return 0;
++}
++
++static int sm_write_bank(int bank, u8* datas)
++{
++	int i, stat = 0;
++	unsigned long timeout;
++
++	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
++
++       	DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
++
++	for (i=0; i<NVRAM_SIZE; i++) {
++		out_8(base+i, SM_FLASH_CMD_WRITE_SETUP);
++		udelay(1);
++		out_8(base+i, datas[i]);
++		timeout = 0;
++		do {
++			if (++timeout > 1000000) {
++				printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n");
++				break;
++			}
++			out_8(base, SM_FLASH_CMD_READ_STATUS);
++			stat = in_8(base);
++		} while (!(stat & SM_FLASH_STATUS_DONE));
++		if (!(stat & SM_FLASH_STATUS_DONE))
++			break;
++	}
++	out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
++	out_8(base, SM_FLASH_CMD_RESET);
++	for (i=0; i<NVRAM_SIZE; i++)
++		if (base[i] != datas[i]) {
++			printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n");
++			return -ENXIO;
++		}
++	return 0;
++}
++
++static int amd_erase_bank(int bank)
++{
++	int i, stat = 0;
++	unsigned long timeout;
++
++	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
++
++       	DBG("nvram: AMD Erasing bank %d...\n", bank);
++
++	/* Unlock 1 */
++	out_8(base+0x555, 0xaa);
++	udelay(1);
++	/* Unlock 2 */
++	out_8(base+0x2aa, 0x55);
++	udelay(1);
++
++	/* Sector-Erase */
++	out_8(base+0x555, 0x80);
++	udelay(1);
++	out_8(base+0x555, 0xaa);
++	udelay(1);
++	out_8(base+0x2aa, 0x55);
++	udelay(1);
++	out_8(base, 0x30);
++	udelay(1);
++
++	timeout = 0;
++	do {
++		if (++timeout > 1000000) {
++			printk(KERN_ERR "nvram: AMD flash erase timeout !\n");
++			break;
++		}
++		stat = in_8(base) ^ in_8(base);
++	} while (stat != 0);
++	
++	/* Reset */
++	out_8(base, 0xf0);
++	udelay(1);
++	
++	for (i=0; i<NVRAM_SIZE; i++)
++		if (base[i] != 0xff) {
++			printk(KERN_ERR "nvram: AMD flash erase failed !\n");
++			return -ENXIO;
++		}
++	return 0;
++}
++
++static int amd_write_bank(int bank, u8* datas)
++{
++	int i, stat = 0;
++	unsigned long timeout;
++
++	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
++
++       	DBG("nvram: AMD Writing bank %d...\n", bank);
++
++	for (i=0; i<NVRAM_SIZE; i++) {
++		/* Unlock 1 */
++		out_8(base+0x555, 0xaa);
++		udelay(1);
++		/* Unlock 2 */
++		out_8(base+0x2aa, 0x55);
++		udelay(1);
++
++		/* Write single word */
++		out_8(base+0x555, 0xa0);
++		udelay(1);
++		out_8(base+i, datas[i]);
++		
++		timeout = 0;
++		do {
++			if (++timeout > 1000000) {
++				printk(KERN_ERR "nvram: AMD flash write timeout !\n");
++				break;
++			}
++			stat = in_8(base) ^ in_8(base);
++		} while (stat != 0);
++		if (stat != 0)
++			break;
++	}
++
++	/* Reset */
++	out_8(base, 0xf0);
++	udelay(1);
++
++	for (i=0; i<NVRAM_SIZE; i++)
++		if (base[i] != datas[i]) {
++			printk(KERN_ERR "nvram: AMD flash write failed !\n");
++			return -ENXIO;
++		}
++	return 0;
++}
++
++static void __init lookup_partitions(void)
++{
++	u8 buffer[17];
++	int i, offset;
++	struct chrp_header* hdr;
++
++	if (pmac_newworld) {
++		nvram_partitions[pmac_nvram_OF] = -1;
++		nvram_partitions[pmac_nvram_XPRAM] = -1;
++		nvram_partitions[pmac_nvram_NR] = -1;
++		hdr = (struct chrp_header *)buffer;
++
++		offset = 0;
++		buffer[16] = 0;
++		do {
++			for (i=0;i<16;i++)
++				buffer[i] = ppc_md.nvram_read_val(offset+i);
++			if (!strcmp(hdr->name, "common"))
++				nvram_partitions[pmac_nvram_OF] = offset + 0x10;
++			if (!strcmp(hdr->name, "APL,MacOS75")) {
++				nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
++				nvram_partitions[pmac_nvram_NR] = offset + 0x110;
++			}
++			offset += (hdr->len * 0x10);
++		} while(offset < NVRAM_SIZE);
++	} else {
++		nvram_partitions[pmac_nvram_OF] = 0x1800;
++		nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
++		nvram_partitions[pmac_nvram_NR] = 0x1400;
++	}
++	DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
++	DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
++	DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
++}
++
++static void core99_nvram_sync(void)
++{
++	struct core99_header* hdr99;
++	unsigned long flags;
++
++	if (!is_core_99 || !nvram_data || !nvram_image)
++		return;
++
++	spin_lock_irqsave(&nv_lock, flags);
++	if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
++		NVRAM_SIZE))
++		goto bail;
++
++	DBG("Updating nvram...\n");
++
++	hdr99 = (struct core99_header*)nvram_image;
++	hdr99->generation++;
++	hdr99->hdr.signature = CORE99_SIGNATURE;
++	hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
++	hdr99->adler = core99_calc_adler(nvram_image);
++	core99_bank = core99_bank ? 0 : 1;
++	if (core99_erase_bank)
++		if (core99_erase_bank(core99_bank)) {
++			printk("nvram: Error erasing bank %d\n", core99_bank);
++			goto bail;
++		}
++	if (core99_write_bank)
++		if (core99_write_bank(core99_bank, nvram_image))
++			printk("nvram: Error writing bank %d\n", core99_bank);
++ bail:
++	spin_unlock_irqrestore(&nv_lock, flags);
++
++#ifdef DEBUG
++       	mdelay(2000);
++#endif
++}
++
++static int __init core99_nvram_setup(struct device_node *dp)
++{
++	int i;
++	u32 gen_bank0, gen_bank1;
++
++	if (nvram_naddrs < 1) {
++		printk(KERN_ERR "nvram: no address\n");
++		return -EINVAL;
++	}
++	nvram_image = alloc_bootmem(NVRAM_SIZE);
++	if (nvram_image == NULL) {
++		printk(KERN_ERR "nvram: can't allocate ram image\n");
++		return -ENOMEM;
++	}
++	nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
++	nvram_naddrs = 1; /* Make sure we get the correct case */
++
++	DBG("nvram: Checking bank 0...\n");
++
++	gen_bank0 = core99_check((u8 *)nvram_data);
++	gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
++	core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
++
++	DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
++	DBG("nvram: Active bank is: %d\n", core99_bank);
++
++	for (i=0; i<NVRAM_SIZE; i++)
++		nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
++
++	ppc_md.nvram_read_val	= core99_nvram_read_byte;
++	ppc_md.nvram_write_val	= core99_nvram_write_byte;
++	ppc_md.nvram_read	= core99_nvram_read;
++	ppc_md.nvram_write	= core99_nvram_write;
++	ppc_md.nvram_size	= core99_nvram_size;
++	ppc_md.nvram_sync	= core99_nvram_sync;
++	/* 
++	 * Maybe we could be smarter here though making an exclusive list
++	 * of known flash chips is a bit nasty as older OF didn't provide us
++	 * with a useful "compatible" entry. A solution would be to really
++	 * identify the chip using flash id commands and base ourselves on
++	 * a list of known chips IDs
++	 */
++	if (device_is_compatible(dp, "amd-0137")) {
++		core99_erase_bank = amd_erase_bank;
++		core99_write_bank = amd_write_bank;
++	} else {
++		core99_erase_bank = sm_erase_bank;
++		core99_write_bank = sm_write_bank;
++	}
++	return 0;
++}
++
++int __init pmac_nvram_init(void)
++{
++	struct device_node *dp;
++	int err = 0;
++
++	nvram_naddrs = 0;
++
++	dp = find_devices("nvram");
++	if (dp == NULL) {
++		printk(KERN_ERR "Can't find NVRAM device\n");
++		return -ENODEV;
++	}
++	nvram_naddrs = dp->n_addrs;
++	is_core_99 = device_is_compatible(dp, "nvram,flash");
++	if (is_core_99)
++		err = core99_nvram_setup(dp);
++#ifdef CONFIG_PPC32
++	else if (_machine == _MACH_chrp && nvram_naddrs == 1) {
++		nvram_data = ioremap(dp->addrs[0].address + isa_mem_base,
++				     dp->addrs[0].size);
++		nvram_mult = 1;
++		ppc_md.nvram_read_val	= direct_nvram_read_byte;
++		ppc_md.nvram_write_val	= direct_nvram_write_byte;
++	} else if (nvram_naddrs == 1) {
++		nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
++		nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE;
++		ppc_md.nvram_read_val	= direct_nvram_read_byte;
++		ppc_md.nvram_write_val	= direct_nvram_write_byte;
++	} else if (nvram_naddrs == 2) {
++		nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size);
++		nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size);
++		ppc_md.nvram_read_val	= indirect_nvram_read_byte;
++		ppc_md.nvram_write_val	= indirect_nvram_write_byte;
++	} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
++#ifdef CONFIG_ADB_PMU
++		nvram_naddrs = -1;
++		ppc_md.nvram_read_val	= pmu_nvram_read_byte;
++		ppc_md.nvram_write_val	= pmu_nvram_write_byte;
++#endif /* CONFIG_ADB_PMU */
++	}
++#endif
++	else {
++		printk(KERN_ERR "Incompatible type of NVRAM\n");
++		return -ENXIO;
++	}
++	lookup_partitions();
++	return err;
++}
++
++int pmac_get_partition(int partition)
++{
++	return nvram_partitions[partition];
++}
++
++u8 pmac_xpram_read(int xpaddr)
++{
++	int offset = pmac_get_partition(pmac_nvram_XPRAM);
++
++	if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
++		return 0xff;
++
++	return ppc_md.nvram_read_val(xpaddr + offset);
++}
++
++void pmac_xpram_write(int xpaddr, u8 data)
++{
++	int offset = pmac_get_partition(pmac_nvram_XPRAM);
++
++	if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
++		return;
++
++	ppc_md.nvram_write_val(xpaddr + offset, data);
++}
++
++EXPORT_SYMBOL(pmac_get_partition);
++EXPORT_SYMBOL(pmac_xpram_read);
++EXPORT_SYMBOL(pmac_xpram_write);
+diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/pci.c
+@@ -0,0 +1,1170 @@
++/*
++ * Support for PCI bridges found on Power Macintoshes.
++ *
++ * Copyright (C) 2003 Benjamin Herrenschmuidt (benh at kernel.crashing.org)
++ * Copyright (C) 1997 Paul Mackerras (paulus at samba.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/pci.h>
++#include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/bootmem.h>
++
++#include <asm/sections.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/pci-bridge.h>
++#include <asm/machdep.h>
++#include <asm/pmac_feature.h>
++#include <asm/grackle.h>
++#ifdef CONFIG_PPC64
++#include <asm/iommu.h>
++#include <asm/ppc-pci.h>
++#endif
++
++#undef DEBUG
++
++#ifdef DEBUG
++#define DBG(x...) printk(x)
++#else
++#define DBG(x...)
++#endif
++
++static int add_bridge(struct device_node *dev);
++
++/* XXX Could be per-controller, but I don't think we risk anything by
++ * assuming we won't have both UniNorth and Bandit */
++static int has_uninorth;
++#ifdef CONFIG_PPC64
++static struct pci_controller *u3_agp;
++static struct pci_controller *u3_ht;
++#endif /* CONFIG_PPC64 */
++
++extern u8 pci_cache_line_size;
++extern int pcibios_assign_bus_offset;
++
++struct device_node *k2_skiplist[2];
++
++/*
++ * Magic constants for enabling cache coherency in the bandit/PSX bridge.
++ */
++#define BANDIT_DEVID_2	8
++#define BANDIT_REVID	3
++
++#define BANDIT_DEVNUM	11
++#define BANDIT_MAGIC	0x50
++#define BANDIT_COHERENT	0x40
++
++static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
++{
++	for (; node != 0;node = node->sibling) {
++		int * bus_range;
++		unsigned int *class_code;
++		int len;
++
++		/* For PCI<->PCI bridges or CardBus bridges, we go down */
++		class_code = (unsigned int *) get_property(node, "class-code", NULL);
++		if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
++			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
++			continue;
++		bus_range = (int *) get_property(node, "bus-range", &len);
++		if (bus_range != NULL && len > 2 * sizeof(int)) {
++			if (bus_range[1] > higher)
++				higher = bus_range[1];
++		}
++		higher = fixup_one_level_bus_range(node->child, higher);
++	}
++	return higher;
++}
++
++/* This routine fixes the "bus-range" property of all bridges in the
++ * system since they tend to have their "last" member wrong on macs
++ *
++ * Note that the bus numbers manipulated here are OF bus numbers, they
++ * are not Linux bus numbers.
++ */
++static void __init fixup_bus_range(struct device_node *bridge)
++{
++	int * bus_range;
++	int len;
++
++	/* Lookup the "bus-range" property for the hose */
++	bus_range = (int *) get_property(bridge, "bus-range", &len);
++	if (bus_range == NULL || len < 2 * sizeof(int)) {
++		printk(KERN_WARNING "Can't get bus-range for %s\n",
++			       bridge->full_name);
++		return;
++	}
++	bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
++}
++
++/*
++ * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
++ *
++ * The "Bandit" version is present in all early PCI PowerMacs,
++ * and up to the first ones using Grackle. Some machines may
++ * have 2 bandit controllers (2 PCI busses).
++ *
++ * "Chaos" is used in some "Bandit"-type machines as a bridge
++ * for the separate display bus. It is accessed the same
++ * way as bandit, but cannot be probed for devices. It therefore
++ * has its own config access functions.
++ *
++ * The "UniNorth" version is present in all Core99 machines
++ * (iBook, G4, new IMacs, and all the recent Apple machines).
++ * It contains 3 controllers in one ASIC.
++ *
++ * The U3 is the bridge used on G5 machines. It contains an
++ * AGP bus which is dealt with the old UniNorth access routines
++ * and a HyperTransport bus which uses its own set of access
++ * functions.
++ */
++
++#define MACRISC_CFA0(devfn, off)	\
++	((1 << (unsigned long)PCI_SLOT(dev_fn)) \
++	| (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
++	| (((unsigned long)(off)) & 0xFCUL))
++
++#define MACRISC_CFA1(bus, devfn, off)	\
++	((((unsigned long)(bus)) << 16) \
++	|(((unsigned long)(devfn)) << 8) \
++	|(((unsigned long)(off)) & 0xFCUL) \
++	|1UL)
++
++static unsigned long macrisc_cfg_access(struct pci_controller* hose,
++					       u8 bus, u8 dev_fn, u8 offset)
++{
++	unsigned int caddr;
++
++	if (bus == hose->first_busno) {
++		if (dev_fn < (11 << 3))
++			return 0;
++		caddr = MACRISC_CFA0(dev_fn, offset);
++	} else
++		caddr = MACRISC_CFA1(bus, dev_fn, offset);
++
++	/* Uninorth will return garbage if we don't read back the value ! */
++	do {
++		out_le32(hose->cfg_addr, caddr);
++	} while (in_le32(hose->cfg_addr) != caddr);
++
++	offset &= has_uninorth ? 0x07 : 0x03;
++	return ((unsigned long)hose->cfg_data) + offset;
++}
++
++static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
++				      int offset, int len, u32 *val)
++{
++	struct pci_controller *hose;
++	unsigned long addr;
++
++	hose = pci_bus_to_host(bus);
++	if (hose == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
++	if (!addr)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	switch (len) {
++	case 1:
++		*val = in_8((u8 *)addr);
++		break;
++	case 2:
++		*val = in_le16((u16 *)addr);
++		break;
++	default:
++		*val = in_le32((u32 *)addr);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
++				       int offset, int len, u32 val)
++{
++	struct pci_controller *hose;
++	unsigned long addr;
++
++	hose = pci_bus_to_host(bus);
++	if (hose == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
++	if (!addr)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	switch (len) {
++	case 1:
++		out_8((u8 *)addr, val);
++		(void) in_8((u8 *)addr);
++		break;
++	case 2:
++		out_le16((u16 *)addr, val);
++		(void) in_le16((u16 *)addr);
++		break;
++	default:
++		out_le32((u32 *)addr, val);
++		(void) in_le32((u32 *)addr);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops macrisc_pci_ops =
++{
++	macrisc_read_config,
++	macrisc_write_config
++};
++
++#ifdef CONFIG_PPC32
++/*
++ * Verify that a specific (bus, dev_fn) exists on chaos
++ */
++static int
++chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
++{
++	struct device_node *np;
++	u32 *vendor, *device;
++
++	np = pci_busdev_to_OF_node(bus, devfn);
++	if (np == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	vendor = (u32 *)get_property(np, "vendor-id", NULL);
++	device = (u32 *)get_property(np, "device-id", NULL);
++	if (vendor == NULL || device == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10)
++	    && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24))
++		return PCIBIOS_BAD_REGISTER_NUMBER;
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int
++chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
++		  int len, u32 *val)
++{
++	int result = chaos_validate_dev(bus, devfn, offset);
++	if (result == PCIBIOS_BAD_REGISTER_NUMBER)
++		*val = ~0U;
++	if (result != PCIBIOS_SUCCESSFUL)
++		return result;
++	return macrisc_read_config(bus, devfn, offset, len, val);
++}
++
++static int
++chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
++		   int len, u32 val)
++{
++	int result = chaos_validate_dev(bus, devfn, offset);
++	if (result != PCIBIOS_SUCCESSFUL)
++		return result;
++	return macrisc_write_config(bus, devfn, offset, len, val);
++}
++
++static struct pci_ops chaos_pci_ops =
++{
++	chaos_read_config,
++	chaos_write_config
++};
++
++static void __init setup_chaos(struct pci_controller *hose,
++			       struct reg_property *addr)
++{
++	/* assume a `chaos' bridge */
++	hose->ops = &chaos_pci_ops;
++	hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
++	hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
++}
++#else
++#define setup_chaos(hose, addr)
++#endif /* CONFIG_PPC32 */
++
++#ifdef CONFIG_PPC64
++/*
++ * These versions of U3 HyperTransport config space access ops do not
++ * implement self-view of the HT host yet
++ */
++
++/*
++ * This function deals with some "special cases" devices.
++ *
++ *  0 -> No special case
++ *  1 -> Skip the device but act as if the access was successfull
++ *       (return 0xff's on reads, eventually, cache config space
++ *       accesses in a later version)
++ * -1 -> Hide the device (unsuccessful acess)
++ */
++static int u3_ht_skip_device(struct pci_controller *hose,
++			     struct pci_bus *bus, unsigned int devfn)
++{
++	struct device_node *busdn, *dn;
++	int i;
++
++	/* We only allow config cycles to devices that are in OF device-tree
++	 * as we are apparently having some weird things going on with some
++	 * revs of K2 on recent G5s
++	 */
++	if (bus->self)
++		busdn = pci_device_to_OF_node(bus->self);
++	else
++		busdn = hose->arch_data;
++	for (dn = busdn->child; dn; dn = dn->sibling)
++		if (dn->data && PCI_DN(dn)->devfn == devfn)
++			break;
++	if (dn == NULL)
++		return -1;
++
++	/*
++	 * When a device in K2 is powered down, we die on config
++	 * cycle accesses. Fix that here.
++	 */
++	for (i=0; i<2; i++)
++		if (k2_skiplist[i] == dn)
++			return 1;
++
++	return 0;
++}
++
++#define U3_HT_CFA0(devfn, off)		\
++		((((unsigned long)devfn) << 8) | offset)
++#define U3_HT_CFA1(bus, devfn, off)	\
++		(U3_HT_CFA0(devfn, off) \
++		+ (((unsigned long)bus) << 16) \
++		+ 0x01000000UL)
++
++static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
++					     u8 bus, u8 devfn, u8 offset)
++{
++	if (bus == hose->first_busno) {
++		/* For now, we don't self probe U3 HT bridge */
++		if (PCI_SLOT(devfn) == 0)
++			return 0;
++		return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
++	} else
++		return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
++}
++
++static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
++				    int offset, int len, u32 *val)
++{
++	struct pci_controller *hose;
++	unsigned long addr;
++
++	hose = pci_bus_to_host(bus);
++	if (hose == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
++	if (!addr)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	switch (u3_ht_skip_device(hose, bus, devfn)) {
++	case 0:
++		break;
++	case 1:
++		switch (len) {
++		case 1:
++			*val = 0xff; break;
++		case 2:
++			*val = 0xffff; break;
++		default:
++			*val = 0xfffffffful; break;
++		}
++		return PCIBIOS_SUCCESSFUL;
++	default:
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	}
++
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	switch (len) {
++	case 1:
++		*val = in_8((u8 *)addr);
++		break;
++	case 2:
++		*val = in_le16((u16 *)addr);
++		break;
++	default:
++		*val = in_le32((u32 *)addr);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
++				     int offset, int len, u32 val)
++{
++	struct pci_controller *hose;
++	unsigned long addr;
++
++	hose = pci_bus_to_host(bus);
++	if (hose == NULL)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
++	if (!addr)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	switch (u3_ht_skip_device(hose, bus, devfn)) {
++	case 0:
++		break;
++	case 1:
++		return PCIBIOS_SUCCESSFUL;
++	default:
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	}
++
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	switch (len) {
++	case 1:
++		out_8((u8 *)addr, val);
++		(void) in_8((u8 *)addr);
++		break;
++	case 2:
++		out_le16((u16 *)addr, val);
++		(void) in_le16((u16 *)addr);
++		break;
++	default:
++		out_le32((u32 *)addr, val);
++		(void) in_le32((u32 *)addr);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops u3_ht_pci_ops =
++{
++	u3_ht_read_config,
++	u3_ht_write_config
++};
++#endif /* CONFIG_PPC64 */
++
++#ifdef CONFIG_PPC32
++/*
++ * For a bandit bridge, turn on cache coherency if necessary.
++ * N.B. we could clean this up using the hose ops directly.
++ */
++static void __init init_bandit(struct pci_controller *bp)
++{
++	unsigned int vendev, magic;
++	int rev;
++
++	/* read the word at offset 0 in config space for device 11 */
++	out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
++	udelay(2);
++	vendev = in_le32(bp->cfg_data);
++	if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +
++			PCI_VENDOR_ID_APPLE) {
++		/* read the revision id */
++		out_le32(bp->cfg_addr,
++			 (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
++		udelay(2);
++		rev = in_8(bp->cfg_data);
++		if (rev != BANDIT_REVID)
++			printk(KERN_WARNING
++			       "Unknown revision %d for bandit\n", rev);
++	} else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {
++		printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
++		return;
++	}
++
++	/* read the word at offset 0x50 */
++	out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
++	udelay(2);
++	magic = in_le32(bp->cfg_data);
++	if ((magic & BANDIT_COHERENT) != 0)
++		return;
++	magic |= BANDIT_COHERENT;
++	udelay(2);
++	out_le32(bp->cfg_data, magic);
++	printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
++}
++
++/*
++ * Tweak the PCI-PCI bridge chip on the blue & white G3s.
++ */
++static void __init init_p2pbridge(void)
++{
++	struct device_node *p2pbridge;
++	struct pci_controller* hose;
++	u8 bus, devfn;
++	u16 val;
++
++	/* XXX it would be better here to identify the specific
++	   PCI-PCI bridge chip we have. */
++	if ((p2pbridge = find_devices("pci-bridge")) == 0
++	    || p2pbridge->parent == NULL
++	    || strcmp(p2pbridge->parent->name, "pci") != 0)
++		return;
++	if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
++		DBG("Can't find PCI infos for PCI<->PCI bridge\n");
++		return;
++	}
++	/* Warning: At this point, we have not yet renumbered all busses.
++	 * So we must use OF walking to find out hose
++	 */
++	hose = pci_find_hose_for_OF_device(p2pbridge);
++	if (!hose) {
++		DBG("Can't find hose for PCI<->PCI bridge\n");
++		return;
++	}
++	if (early_read_config_word(hose, bus, devfn,
++				   PCI_BRIDGE_CONTROL, &val) < 0) {
++		printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
++		return;
++	}
++	val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
++	early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
++}
++
++/*
++ * Some Apple desktop machines have a NEC PD720100A USB2 controller
++ * on the motherboard. Open Firmware, on these, will disable the
++ * EHCI part of it so it behaves like a pair of OHCI's. This fixup
++ * code re-enables it ;)
++ */
++static void __init fixup_nec_usb2(void)
++{
++	struct device_node *nec;
++
++	for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {
++		struct pci_controller *hose;
++		u32 data, *prop;
++		u8 bus, devfn;
++
++		prop = (u32 *)get_property(nec, "vendor-id", NULL);
++		if (prop == NULL)
++			continue;
++		if (0x1033 != *prop)
++			continue;
++		prop = (u32 *)get_property(nec, "device-id", NULL);
++		if (prop == NULL)
++			continue;
++		if (0x0035 != *prop)
++			continue;
++		prop = (u32 *)get_property(nec, "reg", NULL);
++		if (prop == NULL)
++			continue;
++		devfn = (prop[0] >> 8) & 0xff;
++		bus = (prop[0] >> 16) & 0xff;
++		if (PCI_FUNC(devfn) != 0)
++			continue;
++		hose = pci_find_hose_for_OF_device(nec);
++		if (!hose)
++			continue;
++		early_read_config_dword(hose, bus, devfn, 0xe4, &data);
++		if (data & 1UL) {
++			printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n");
++			data &= ~1UL;
++			early_write_config_dword(hose, bus, devfn, 0xe4, data);
++			early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE,
++				nec->intrs[0].line);
++		}
++	}
++}
++
++static void __init setup_bandit(struct pci_controller *hose,
++				struct reg_property *addr)
++{
++	hose->ops = &macrisc_pci_ops;
++	hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
++	hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
++	init_bandit(hose);
++}
++
++static int __init setup_uninorth(struct pci_controller *hose,
++				 struct reg_property *addr)
++{
++	pci_assign_all_buses = 1;
++	has_uninorth = 1;
++	hose->ops = &macrisc_pci_ops;
++	hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
++	hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
++	/* We "know" that the bridge at f2000000 has the PCI slots. */
++	return addr->address == 0xf2000000;
++}
++#endif
++
++#ifdef CONFIG_PPC64
++static void __init setup_u3_agp(struct pci_controller* hose)
++{
++	/* On G5, we move AGP up to high bus number so we don't need
++	 * to reassign bus numbers for HT. If we ever have P2P bridges
++	 * on AGP, we'll have to move pci_assign_all_busses to the
++	 * pci_controller structure so we enable it for AGP and not for
++	 * HT childs.
++	 * We hard code the address because of the different size of
++	 * the reg address cell, we shall fix that by killing struct
++	 * reg_property and using some accessor functions instead
++	 */
++	hose->first_busno = 0xf0;
++	hose->last_busno = 0xff;
++	has_uninorth = 1;
++	hose->ops = &macrisc_pci_ops;
++	hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
++	hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
++
++	u3_agp = hose;
++}
++
++static void __init setup_u3_ht(struct pci_controller* hose)
++{
++	struct device_node *np = (struct device_node *)hose->arch_data;
++	int i, cur;
++
++	hose->ops = &u3_ht_pci_ops;
++
++	/* We hard code the address because of the different size of
++	 * the reg address cell, we shall fix that by killing struct
++	 * reg_property and using some accessor functions instead
++	 */
++	hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
++
++	/*
++	 * /ht node doesn't expose a "ranges" property, so we "remove" regions that
++	 * have been allocated to AGP. So far, this version of the code doesn't assign
++	 * any of the 0xfxxxxxxx "fine" memory regions to /ht.
++	 * We need to fix that sooner or later by either parsing all child "ranges"
++	 * properties or figuring out the U3 address space decoding logic and
++	 * then read its configuration register (if any).
++	 */
++	hose->io_base_phys = 0xf4000000;
++	hose->pci_io_size = 0x00400000;
++	hose->io_resource.name = np->full_name;
++	hose->io_resource.start = 0;
++	hose->io_resource.end = 0x003fffff;
++	hose->io_resource.flags = IORESOURCE_IO;
++	hose->pci_mem_offset = 0;
++	hose->first_busno = 0;
++	hose->last_busno = 0xef;
++	hose->mem_resources[0].name = np->full_name;
++	hose->mem_resources[0].start = 0x80000000;
++	hose->mem_resources[0].end = 0xefffffff;
++	hose->mem_resources[0].flags = IORESOURCE_MEM;
++
++	u3_ht = hose;
++
++	if (u3_agp == NULL) {
++		DBG("U3 has no AGP, using full resource range\n");
++		return;
++	}
++
++	/* We "remove" the AGP resources from the resources allocated to HT, that
++	 * is we create "holes". However, that code does assumptions that so far
++	 * happen to be true (cross fingers...), typically that resources in the
++	 * AGP node are properly ordered
++	 */
++	cur = 0;
++	for (i=0; i<3; i++) {
++		struct resource *res = &u3_agp->mem_resources[i];
++		if (res->flags != IORESOURCE_MEM)
++			continue;
++		/* We don't care about "fine" resources */
++		if (res->start >= 0xf0000000)
++			continue;
++		/* Check if it's just a matter of "shrinking" us in one direction */
++		if (hose->mem_resources[cur].start == res->start) {
++			DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
++			    cur, hose->mem_resources[cur].start, res->end + 1);
++			hose->mem_resources[cur].start = res->end + 1;
++			continue;
++		}
++		if (hose->mem_resources[cur].end == res->end) {
++			DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
++			    cur, hose->mem_resources[cur].end, res->start - 1);
++			hose->mem_resources[cur].end = res->start - 1;
++			continue;
++		}
++		/* No, it's not the case, we need a hole */
++		if (cur == 2) {
++			/* not enough resources for a hole, we drop part of the range */
++			printk(KERN_WARNING "Running out of resources for /ht host !\n");
++			hose->mem_resources[cur].end = res->start - 1;
++			continue;
++		}
++		cur++;
++		DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
++		    cur-1, res->start - 1, cur, res->end + 1);
++		hose->mem_resources[cur].name = np->full_name;
++		hose->mem_resources[cur].flags = IORESOURCE_MEM;
++		hose->mem_resources[cur].start = res->end + 1;
++		hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
++		hose->mem_resources[cur-1].end = res->start - 1;
++	}
++}
++
++/* XXX this needs to be converged between ppc32 and ppc64... */
++static struct pci_controller * __init pcibios_alloc_controller(void)
++{
++	struct pci_controller *hose;
++
++	hose = alloc_bootmem(sizeof(struct pci_controller));
++	if (hose)
++		pci_setup_pci_controller(hose);
++	return hose;
++}
++#endif
++
++/*
++ * We assume that if we have a G3 powermac, we have one bridge called
++ * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
++ * if we have one or more bandit or chaos bridges, we don't have a MPC106.
++ */
++static int __init add_bridge(struct device_node *dev)
++{
++	int len;
++	struct pci_controller *hose;
++#ifdef CONFIG_PPC32
++	struct reg_property *addr;
++#endif
++	char *disp_name;
++	int *bus_range;
++	int primary = 1;
++
++	DBG("Adding PCI host bridge %s\n", dev->full_name);
++
++#ifdef CONFIG_PPC32
++	/* XXX fix this */
++	addr = (struct reg_property *) get_property(dev, "reg", &len);
++	if (addr == NULL || len < sizeof(*addr)) {
++		printk(KERN_WARNING "Can't use %s: no address\n",
++		       dev->full_name);
++		return -ENODEV;
++	}
++#endif
++	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->first_busno = bus_range ? bus_range[0] : 0;
++	hose->last_busno = bus_range ? bus_range[1] : 0xff;
++
++	disp_name = NULL;
++#ifdef CONFIG_POWER4
++	if (device_is_compatible(dev, "u3-agp")) {
++		setup_u3_agp(hose);
++		disp_name = "U3-AGP";
++		primary = 0;
++	} else if (device_is_compatible(dev, "u3-ht")) {
++		setup_u3_ht(hose);
++		disp_name = "U3-HT";
++		primary = 1;
++	}
++	printk(KERN_INFO "Found %s PCI host bridge.  Firmware bus number: %d->%d\n",
++		disp_name, hose->first_busno, hose->last_busno);
++#else
++	if (device_is_compatible(dev, "uni-north")) {
++		primary = setup_uninorth(hose, addr);
++		disp_name = "UniNorth";
++	} else if (strcmp(dev->name, "pci") == 0) {
++		/* XXX assume this is a mpc106 (grackle) */
++		setup_grackle(hose);
++		disp_name = "Grackle (MPC106)";
++	} else if (strcmp(dev->name, "bandit") == 0) {
++		setup_bandit(hose, addr);
++		disp_name = "Bandit";
++	} else if (strcmp(dev->name, "chaos") == 0) {
++		setup_chaos(hose, addr);
++		disp_name = "Chaos";
++		primary = 0;
++	}
++	printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n",
++		disp_name, addr->address, hose->first_busno, hose->last_busno);
++#endif
++	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);
++
++	/* Fixup "bus-range" OF property */
++	fixup_bus_range(dev);
++
++	return 0;
++}
++
++static void __init
++pcibios_fixup_OF_interrupts(void)
++{
++	struct pci_dev* dev = NULL;
++
++	/*
++	 * Open Firmware often doesn't initialize the
++	 * PCI_INTERRUPT_LINE config register properly, so we
++	 * should find the device node and apply the interrupt
++	 * obtained from the OF device-tree
++	 */
++	for_each_pci_dev(dev) {
++		struct device_node *node;
++		node = pci_device_to_OF_node(dev);
++		/* this is the node, see if it has interrupts */
++		if (node && node->n_intrs > 0)
++			dev->irq = node->intrs[0].line;
++		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
++	}
++}
++
++void __init
++pmac_pcibios_fixup(void)
++{
++	/* Fixup interrupts according to OF tree */
++	pcibios_fixup_OF_interrupts();
++}
++
++#ifdef CONFIG_PPC64
++static void __init pmac_fixup_phb_resources(void)
++{
++	struct pci_controller *hose, *tmp;
++
++	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
++		printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
++		       hose->global_number,
++		       hose->io_resource.start, hose->io_resource.end);
++	}
++}
++#endif
++
++void __init pmac_pci_init(void)
++{
++	struct device_node *np, *root;
++	struct device_node *ht = NULL;
++
++	root = of_find_node_by_path("/");
++	if (root == NULL) {
++		printk(KERN_CRIT "pmac_pci_init: can't find root "
++		       "of device tree\n");
++		return;
++	}
++	for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
++		if (np->name == NULL)
++			continue;
++		if (strcmp(np->name, "bandit") == 0
++		    || strcmp(np->name, "chaos") == 0
++		    || strcmp(np->name, "pci") == 0) {
++			if (add_bridge(np) == 0)
++				of_node_get(np);
++		}
++		if (strcmp(np->name, "ht") == 0) {
++			of_node_get(np);
++			ht = np;
++		}
++	}
++	of_node_put(root);
++
++#ifdef CONFIG_PPC64
++	/* Probe HT last as it relies on the agp resources to be already
++	 * setup
++	 */
++	if (ht && add_bridge(ht) != 0)
++		of_node_put(ht);
++
++	/*
++	 * We need to call pci_setup_phb_io for the HT bridge first
++	 * so it gets the I/O port numbers starting at 0, and we
++	 * need to call it for the AGP bridge after that so it gets
++	 * small positive I/O port numbers.
++	 */
++	if (u3_ht)
++		pci_setup_phb_io(u3_ht, 1);
++	if (u3_agp)
++		pci_setup_phb_io(u3_agp, 0);
++
++	/*
++	 * On ppc64, fixup the IO resources on our host bridges as
++	 * the common code does it only for children of the host bridges
++	 */
++	pmac_fixup_phb_resources();
++
++	/* Setup the linkage between OF nodes and PHBs */
++	pci_devs_phb_init();
++
++	/* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
++	 * assume there is no P2P bridge on the AGP bus, which should be a
++	 * safe assumptions hopefully.
++	 */
++	if (u3_agp) {
++		struct device_node *np = u3_agp->arch_data;
++		PCI_DN(np)->busno = 0xf0;
++		for (np = np->child; np; np = np->sibling)
++			PCI_DN(np)->busno = 0xf0;
++	}
++
++	/* map in PCI I/O space */
++	phbs_remap_io();
++
++	/* pmac_check_ht_link(); */
++
++	/* Tell pci.c to not use the common resource allocation mechanism */
++	pci_probe_only = 1;
++
++	/* Allow all IO */
++	io_page_mask = -1;
++
++#else /* CONFIG_PPC64 */
++	init_p2pbridge();
++	fixup_nec_usb2();
++
++	/* We are still having some issues with the Xserve G4, enabling
++	 * some offset between bus number and domains for now when we
++	 * assign all busses should help for now
++	 */
++	if (pci_assign_all_buses)
++		pcibios_assign_bus_offset = 0x10;
++#endif
++}
++
++int
++pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
++{
++	struct device_node* node;
++	int updatecfg = 0;
++	int uninorth_child;
++
++	node = pci_device_to_OF_node(dev);
++
++	/* We don't want to enable USB controllers absent from the OF tree
++	 * (iBook second controller)
++	 */
++	if (dev->vendor == PCI_VENDOR_ID_APPLE
++	    && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10))
++	    && !node) {
++		printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
++		       pci_name(dev));
++		return -EINVAL;
++	}
++
++	if (!node)
++		return 0;
++
++	uninorth_child = node->parent &&
++		device_is_compatible(node->parent, "uni-north");
++
++	/* Firewire & GMAC were disabled after PCI probe, the driver is
++	 * claiming them, we must re-enable them now.
++	 */
++	if (uninorth_child && !strcmp(node->name, "firewire") &&
++	    (device_is_compatible(node, "pci106b,18") ||
++	     device_is_compatible(node, "pci106b,30") ||
++	     device_is_compatible(node, "pci11c1,5811"))) {
++		pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
++		pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
++		updatecfg = 1;
++	}
++	if (uninorth_child && !strcmp(node->name, "ethernet") &&
++	    device_is_compatible(node, "gmac")) {
++		pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
++		updatecfg = 1;
++	}
++
++	if (updatecfg) {
++		u16 cmd;
++
++		/*
++		 * Make sure PCI is correctly configured
++		 *
++		 * We use old pci_bios versions of the function since, by
++		 * default, gmac is not powered up, and so will be absent
++		 * from the kernel initial PCI lookup.
++		 *
++		 * Should be replaced by 2.4 new PCI mechanisms and really
++		 * register the device.
++		 */
++		pci_read_config_word(dev, PCI_COMMAND, &cmd);
++		cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
++			| PCI_COMMAND_INVALIDATE;
++		pci_write_config_word(dev, PCI_COMMAND, cmd);
++		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
++		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
++				      L1_CACHE_BYTES >> 2);
++	}
++
++	return 0;
++}
++
++/* We power down some devices after they have been probed. They'll
++ * be powered back on later on
++ */
++void __init pmac_pcibios_after_init(void)
++{
++	struct device_node* nd;
++
++#ifdef CONFIG_BLK_DEV_IDE
++	struct pci_dev *dev = NULL;
++
++	/* OF fails to initialize IDE controllers on macs
++	 * (and maybe other machines)
++	 *
++	 * Ideally, this should be moved to the IDE layer, but we need
++	 * to check specifically with Andre Hedrick how to do it cleanly
++	 * since the common IDE code seem to care about the fact that the
++	 * BIOS may have disabled a controller.
++	 *
++	 * -- BenH
++	 */
++	for_each_pci_dev(dev) {
++		if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
++			pci_enable_device(dev);
++	}
++#endif /* CONFIG_BLK_DEV_IDE */
++
++	nd = find_devices("firewire");
++	while (nd) {
++		if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||
++				   device_is_compatible(nd, "pci106b,30") ||
++				   device_is_compatible(nd, "pci11c1,5811"))
++		    && device_is_compatible(nd->parent, "uni-north")) {
++			pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);
++			pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
++		}
++		nd = nd->next;
++	}
++	nd = find_devices("ethernet");
++	while (nd) {
++		if (nd->parent && device_is_compatible(nd, "gmac")
++		    && device_is_compatible(nd->parent, "uni-north"))
++			pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
++		nd = nd->next;
++	}
++}
++
++#ifdef CONFIG_PPC32
++void pmac_pci_fixup_cardbus(struct pci_dev* dev)
++{
++	if (_machine != _MACH_Pmac)
++		return;
++	/*
++	 * Fix the interrupt routing on the various cardbus bridges
++	 * used on powerbooks
++	 */
++	if (dev->vendor != PCI_VENDOR_ID_TI)
++		return;
++	if (dev->device == PCI_DEVICE_ID_TI_1130 ||
++	    dev->device == PCI_DEVICE_ID_TI_1131) {
++		u8 val;
++		/* Enable PCI interrupt */
++		if (pci_read_config_byte(dev, 0x91, &val) == 0)
++			pci_write_config_byte(dev, 0x91, val | 0x30);
++		/* Disable ISA interrupt mode */
++		if (pci_read_config_byte(dev, 0x92, &val) == 0)
++			pci_write_config_byte(dev, 0x92, val & ~0x06);
++	}
++	if (dev->device == PCI_DEVICE_ID_TI_1210 ||
++	    dev->device == PCI_DEVICE_ID_TI_1211 ||
++	    dev->device == PCI_DEVICE_ID_TI_1410 ||
++	    dev->device == PCI_DEVICE_ID_TI_1510) {
++		u8 val;
++		/* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
++		   signal out the MFUNC0 pin */
++		if (pci_read_config_byte(dev, 0x8c, &val) == 0)
++			pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2);
++		/* Disable ISA interrupt mode */
++		if (pci_read_config_byte(dev, 0x92, &val) == 0)
++			pci_write_config_byte(dev, 0x92, val & ~0x06);
++	}
++}
++
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus);
++
++void pmac_pci_fixup_pciata(struct pci_dev* dev)
++{
++       u8 progif = 0;
++
++       /*
++        * On PowerMacs, we try to switch any PCI ATA controller to
++	* fully native mode
++        */
++	if (_machine != _MACH_Pmac)
++		return;
++	/* Some controllers don't have the class IDE */
++	if (dev->vendor == PCI_VENDOR_ID_PROMISE)
++		switch(dev->device) {
++		case PCI_DEVICE_ID_PROMISE_20246:
++		case PCI_DEVICE_ID_PROMISE_20262:
++		case PCI_DEVICE_ID_PROMISE_20263:
++		case PCI_DEVICE_ID_PROMISE_20265:
++		case PCI_DEVICE_ID_PROMISE_20267:
++		case PCI_DEVICE_ID_PROMISE_20268:
++		case PCI_DEVICE_ID_PROMISE_20269:
++		case PCI_DEVICE_ID_PROMISE_20270:
++		case PCI_DEVICE_ID_PROMISE_20271:
++		case PCI_DEVICE_ID_PROMISE_20275:
++		case PCI_DEVICE_ID_PROMISE_20276:
++		case PCI_DEVICE_ID_PROMISE_20277:
++			goto good;
++		}
++	/* Others, check PCI class */
++	if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
++		return;
++ good:
++	pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
++	if ((progif & 5) != 5) {
++		printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev));
++		(void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
++		if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
++		    (progif & 5) != 5)
++			printk(KERN_ERR "Rewrite of PROGIF failed !\n");
++	}
++}
++DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
++#endif
++
++/*
++ * Disable second function on K2-SATA, it's broken
++ * and disable IO BARs on first one
++ */
++static void fixup_k2_sata(struct pci_dev* dev)
++{
++	int i;
++	u16 cmd;
++
++	if (PCI_FUNC(dev->devfn) > 0) {
++		pci_read_config_word(dev, PCI_COMMAND, &cmd);
++		cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
++		pci_write_config_word(dev, PCI_COMMAND, cmd);
++		for (i = 0; i < 6; i++) {
++			dev->resource[i].start = dev->resource[i].end = 0;
++			dev->resource[i].flags = 0;
++			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
++		}
++	} else {
++		pci_read_config_word(dev, PCI_COMMAND, &cmd);
++		cmd &= ~PCI_COMMAND_IO;
++		pci_write_config_word(dev, PCI_COMMAND, cmd);
++		for (i = 0; i < 5; i++) {
++			dev->resource[i].start = dev->resource[i].end = 0;
++			dev->resource[i].flags = 0;
++			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
++		}
++	}
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);
++
+diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/pic.c
+@@ -0,0 +1,678 @@
++/*
++ *  Support for the interrupt controllers found on Power Macintosh,
++ *  currently Apple's "Grand Central" interrupt controller in all
++ *  it's incarnations. OpenPIC support used on newer machines is
++ *  in a separate file
++ *
++ *  Copyright (C) 1997 Paul Mackerras (paulus at samba.org)
++ *
++ *  Maintained by Benjamin Herrenschmidt (benh at 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/config.h>
++#include <linux/stddef.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/signal.h>
++#include <linux/pci.h>
++#include <linux/interrupt.h>
++#include <linux/sysdev.h>
++#include <linux/adb.h>
++#include <linux/pmu.h>
++#include <linux/module.h>
++
++#include <asm/sections.h>
++#include <asm/io.h>
++#include <asm/smp.h>
++#include <asm/prom.h>
++#include <asm/pci-bridge.h>
++#include <asm/time.h>
++#include <asm/pmac_feature.h>
++#include <asm/mpic.h>
++
++#include "pmac.h"
++
++/*
++ * XXX this should be in xmon.h, but putting it there means xmon.h
++ * has to include <linux/interrupt.h> (to get irqreturn_t), which
++ * causes all sorts of problems.  -- paulus
++ */
++extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
++
++#ifdef CONFIG_PPC32
++struct pmac_irq_hw {
++        unsigned int    event;
++        unsigned int    enable;
++        unsigned int    ack;
++        unsigned int    level;
++};
++
++/* Default addresses */
++static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
++        (struct pmac_irq_hw *) 0xf3000020,
++        (struct pmac_irq_hw *) 0xf3000010,
++        (struct pmac_irq_hw *) 0xf4000020,
++        (struct pmac_irq_hw *) 0xf4000010,
++};
++
++#define GC_LEVEL_MASK		0x3ff00000
++#define OHARE_LEVEL_MASK	0x1ff00000
++#define HEATHROW_LEVEL_MASK	0x1ff00000
++
++static int max_irqs;
++static int max_real_irqs;
++static u32 level_mask[4];
++
++static DEFINE_SPINLOCK(pmac_pic_lock);
++
++#define GATWICK_IRQ_POOL_SIZE        10
++static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
++
++/*
++ * Mark an irq as "lost".  This is only used on the pmac
++ * since it can lose interrupts (see pmac_set_irq_mask).
++ * -- Cort
++ */
++void
++__set_lost(unsigned long irq_nr, int nokick)
++{
++	if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
++		atomic_inc(&ppc_n_lost_interrupts);
++		if (!nokick)
++			set_dec(1);
++	}
++}
++
++static void
++pmac_mask_and_ack_irq(unsigned int irq_nr)
++{
++        unsigned long bit = 1UL << (irq_nr & 0x1f);
++        int i = irq_nr >> 5;
++        unsigned long flags;
++
++        if ((unsigned)irq_nr >= max_irqs)
++                return;
++
++        clear_bit(irq_nr, ppc_cached_irq_mask);
++        if (test_and_clear_bit(irq_nr, ppc_lost_interrupts))
++                atomic_dec(&ppc_n_lost_interrupts);
++	spin_lock_irqsave(&pmac_pic_lock, flags);
++        out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
++        out_le32(&pmac_irq_hw[i]->ack, bit);
++        do {
++                /* make sure ack gets to controller before we enable
++                   interrupts */
++                mb();
++        } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
++                != (ppc_cached_irq_mask[i] & bit));
++	spin_unlock_irqrestore(&pmac_pic_lock, flags);
++}
++
++static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
++{
++        unsigned long bit = 1UL << (irq_nr & 0x1f);
++        int i = irq_nr >> 5;
++        unsigned long flags;
++
++        if ((unsigned)irq_nr >= max_irqs)
++                return;
++
++	spin_lock_irqsave(&pmac_pic_lock, flags);
++        /* enable unmasked interrupts */
++        out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
++
++        do {
++                /* make sure mask gets to controller before we
++                   return to user */
++                mb();
++        } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
++                != (ppc_cached_irq_mask[i] & bit));
++
++        /*
++         * Unfortunately, setting the bit in the enable register
++         * when the device interrupt is already on *doesn't* set
++         * the bit in the flag register or request another interrupt.
++         */
++        if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))
++		__set_lost((ulong)irq_nr, nokicklost);
++	spin_unlock_irqrestore(&pmac_pic_lock, flags);
++}
++
++/* When an irq gets requested for the first client, if it's an
++ * edge interrupt, we clear any previous one on the controller
++ */
++static unsigned int pmac_startup_irq(unsigned int irq_nr)
++{
++        unsigned long bit = 1UL << (irq_nr & 0x1f);
++        int i = irq_nr >> 5;
++
++	if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
++		out_le32(&pmac_irq_hw[i]->ack, bit);
++        set_bit(irq_nr, ppc_cached_irq_mask);
++        pmac_set_irq_mask(irq_nr, 0);
++
++	return 0;
++}
++
++static void pmac_mask_irq(unsigned int irq_nr)
++{
++        clear_bit(irq_nr, ppc_cached_irq_mask);
++        pmac_set_irq_mask(irq_nr, 0);
++        mb();
++}
++
++static void pmac_unmask_irq(unsigned int irq_nr)
++{
++        set_bit(irq_nr, ppc_cached_irq_mask);
++        pmac_set_irq_mask(irq_nr, 0);
++}
++
++static void pmac_end_irq(unsigned int irq_nr)
++{
++	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
++	    && irq_desc[irq_nr].action) {
++        	set_bit(irq_nr, ppc_cached_irq_mask);
++	        pmac_set_irq_mask(irq_nr, 1);
++	}
++}
++
++
++struct hw_interrupt_type pmac_pic = {
++	.typename	= " PMAC-PIC ",
++	.startup	= pmac_startup_irq,
++	.enable		= pmac_unmask_irq,
++	.disable	= pmac_mask_irq,
++	.ack		= pmac_mask_and_ack_irq,
++	.end		= pmac_end_irq,
++};
++
++struct hw_interrupt_type gatwick_pic = {
++	.typename	= " GATWICK  ",
++	.startup	= pmac_startup_irq,
++	.enable		= pmac_unmask_irq,
++	.disable	= pmac_mask_irq,
++	.ack		= pmac_mask_and_ack_irq,
++	.end		= pmac_end_irq,
++};
++
++static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
++{
++	int irq, bits;
++
++	for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
++		int i = irq >> 5;
++		bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
++		/* We must read level interrupts from the level register */
++		bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
++		bits &= ppc_cached_irq_mask[i];
++		if (bits == 0)
++			continue;
++		irq += __ilog2(bits);
++		__do_IRQ(irq, regs);
++		return IRQ_HANDLED;
++	}
++	printk("gatwick irq not from gatwick pic\n");
++	return IRQ_NONE;
++}
++
++int
++pmac_get_irq(struct pt_regs *regs)
++{
++	int irq;
++	unsigned long bits = 0;
++
++#ifdef CONFIG_SMP
++	void psurge_smp_message_recv(struct pt_regs *);
++
++       	/* IPI's are a hack on the powersurge -- Cort */
++       	if ( smp_processor_id() != 0 ) {
++		psurge_smp_message_recv(regs);
++		return -2;	/* ignore, already handled */
++        }
++#endif /* CONFIG_SMP */
++	for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
++		int i = irq >> 5;
++		bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
++		/* We must read level interrupts from the level register */
++		bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
++		bits &= ppc_cached_irq_mask[i];
++		if (bits == 0)
++			continue;
++		irq += __ilog2(bits);
++		break;
++	}
++
++	return irq;
++}
++
++/* This routine will fix some missing interrupt values in the device tree
++ * on the gatwick mac-io controller used by some PowerBooks
++ */
++static void __init
++pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
++{
++	struct device_node *node;
++	int count;
++
++	memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
++	node = gw->child;
++	count = 0;
++	while(node)
++	{
++		/* Fix SCC */
++		if (strcasecmp(node->name, "escc") == 0)
++			if (node->child) {
++				if (node->child->n_intrs < 3) {
++					node->child->intrs = &gatwick_int_pool[count];
++					count += 3;
++				}
++				node->child->n_intrs = 3;
++				node->child->intrs[0].line = 15+irq_base;
++				node->child->intrs[1].line =  4+irq_base;
++				node->child->intrs[2].line =  5+irq_base;
++				printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",
++					node->child->intrs[0].line,
++					node->child->intrs[1].line,
++					node->child->intrs[2].line);
++			}
++		/* Fix media-bay & left SWIM */
++		if (strcasecmp(node->name, "media-bay") == 0) {
++			struct device_node* ya_node;
++
++			if (node->n_intrs == 0)
++				node->intrs = &gatwick_int_pool[count++];
++			node->n_intrs = 1;
++			node->intrs[0].line = 29+irq_base;
++			printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
++					node->intrs[0].line);
++
++			ya_node = node->child;
++			while(ya_node)
++			{
++				if (strcasecmp(ya_node->name, "floppy") == 0) {
++					if (ya_node->n_intrs < 2) {
++						ya_node->intrs = &gatwick_int_pool[count];
++						count += 2;
++					}
++					ya_node->n_intrs = 2;
++					ya_node->intrs[0].line = 19+irq_base;
++					ya_node->intrs[1].line =  1+irq_base;
++					printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
++						ya_node->intrs[0].line, ya_node->intrs[1].line);
++				}
++				if (strcasecmp(ya_node->name, "ata4") == 0) {
++					if (ya_node->n_intrs < 2) {
++						ya_node->intrs = &gatwick_int_pool[count];
++						count += 2;
++					}
++					ya_node->n_intrs = 2;
++					ya_node->intrs[0].line = 14+irq_base;
++					ya_node->intrs[1].line =  3+irq_base;
++					printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
++						ya_node->intrs[0].line, ya_node->intrs[1].line);
++				}
++				ya_node = ya_node->sibling;
++			}
++		}
++		node = node->sibling;
++	}
++	if (count > 10) {
++		printk("WARNING !! Gatwick interrupt pool overflow\n");
++		printk("  GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
++		printk("              requested = %d\n", count);
++	}
++}
++
++/*
++ * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
++ * card which includes an ohare chip that acts as a second interrupt
++ * controller.  If we find this second ohare, set it up and fix the
++ * interrupt value in the device tree for the ethernet chip.
++ */
++static int __init enable_second_ohare(void)
++{
++	unsigned char bus, devfn;
++	unsigned short cmd;
++        unsigned long addr;
++	struct device_node *irqctrler = find_devices("pci106b,7");
++	struct device_node *ether;
++
++	if (irqctrler == NULL || irqctrler->n_addrs <= 0)
++		return -1;
++	addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);
++	pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);
++	max_irqs = 64;
++	if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) {
++		struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler);
++		if (!hose)
++		    printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
++		else {
++		    early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
++		    cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
++	  	    cmd &= ~PCI_COMMAND_IO;
++		    early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
++		}
++	}
++
++	/* Fix interrupt for the modem/ethernet combo controller. The number
++	   in the device tree (27) is bogus (correct for the ethernet-only
++	   board but not the combo ethernet/modem board).
++	   The real interrupt is 28 on the second controller -> 28+32 = 60.
++	*/
++	ether = find_devices("pci1011,14");
++	if (ether && ether->n_intrs > 0) {
++		ether->intrs[0].line = 60;
++		printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
++		       ether->intrs[0].line);
++	}
++
++	/* Return the interrupt number of the cascade */
++	return irqctrler->intrs[0].line;
++}
++
++#ifdef CONFIG_XMON
++static struct irqaction xmon_action = {
++	.handler	= xmon_irq,
++	.flags		= 0,
++	.mask		= CPU_MASK_NONE,
++	.name		= "NMI - XMON"
++};
++#endif
++
++static struct irqaction gatwick_cascade_action = {
++	.handler	= gatwick_action,
++	.flags		= SA_INTERRUPT,
++	.mask		= CPU_MASK_NONE,
++	.name		= "cascade",
++};
++#endif /* CONFIG_PPC32 */
++
++static int pmac_u3_cascade(struct pt_regs *regs, void *data)
++{
++	return mpic_get_one_irq((struct mpic *)data, regs);
++}
++
++void __init pmac_pic_init(void)
++{
++        struct device_node *irqctrler  = NULL;
++        struct device_node *irqctrler2 = NULL;
++	struct device_node *np;
++#ifdef CONFIG_PPC32
++        int i;
++        unsigned long addr;
++	int irq_cascade = -1;
++#endif
++	struct mpic *mpic1, *mpic2;
++
++	/* We first try to detect Apple's new Core99 chipset, since mac-io
++	 * is quite different on those machines and contains an IBM MPIC2.
++	 */
++	np = find_type_devices("open-pic");
++	while (np) {
++		if (np->parent && !strcmp(np->parent->name, "u3"))
++			irqctrler2 = np;
++		else
++			irqctrler = np;
++		np = np->next;
++	}
++	if (irqctrler != NULL && irqctrler->n_addrs > 0) {
++		unsigned char senses[128];
++
++		printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
++		       (unsigned int)irqctrler->addrs[0].address);
++		pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);
++
++		prom_get_irq_senses(senses, 0, 128);
++		mpic1 = mpic_alloc(irqctrler->addrs[0].address,
++				   MPIC_PRIMARY | MPIC_WANTS_RESET,
++				   0, 0, 128, 252, senses, 128, " OpenPIC  ");
++		BUG_ON(mpic1 == NULL);
++		mpic_init(mpic1);		
++
++		if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
++		    irqctrler2->n_addrs > 0) {
++			printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
++			       (u32)irqctrler2->addrs[0].address,
++			       irqctrler2->intrs[0].line);
++
++			pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
++			prom_get_irq_senses(senses, 128, 128 + 124);
++
++			/* We don't need to set MPIC_BROKEN_U3 here since we don't have
++			 * hypertransport interrupts routed to it
++			 */
++			mpic2 = mpic_alloc(irqctrler2->addrs[0].address,
++					   MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
++					   0, 128, 124, 0, senses, 124,
++					   " U3-MPIC  ");
++			BUG_ON(mpic2 == NULL);
++			mpic_init(mpic2);
++			mpic_setup_cascade(irqctrler2->intrs[0].line,
++					   pmac_u3_cascade, mpic2);
++		}
++#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
++		{
++			struct device_node* pswitch;
++			int nmi_irq;
++
++			pswitch = find_devices("programmer-switch");
++			if (pswitch && pswitch->n_intrs) {
++				nmi_irq = pswitch->intrs[0].line;
++				mpic_irq_set_priority(nmi_irq, 9);
++				setup_irq(nmi_irq, &xmon_action);
++			}
++		}
++#endif	/* CONFIG_XMON */
++		return;
++	}
++	irqctrler = NULL;
++
++#ifdef CONFIG_PPC32
++	/* Get the level/edge settings, assume if it's not
++	 * a Grand Central nor an OHare, then it's an Heathrow
++	 * (or Paddington).
++	 */
++	ppc_md.get_irq = pmac_get_irq;
++	if (find_devices("gc"))
++		level_mask[0] = GC_LEVEL_MASK;
++	else if (find_devices("ohare")) {
++		level_mask[0] = OHARE_LEVEL_MASK;
++		/* We might have a second cascaded ohare */
++		level_mask[1] = OHARE_LEVEL_MASK;
++	} else {
++		level_mask[0] = HEATHROW_LEVEL_MASK;
++		level_mask[1] = 0;
++		/* We might have a second cascaded heathrow */
++		level_mask[2] = HEATHROW_LEVEL_MASK;
++		level_mask[3] = 0;
++	}
++
++	/*
++	 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
++	 * 1998 G3 Series PowerBooks have 128,
++	 * other powermacs have 32.
++	 * The combo ethernet/modem card for the Powerstar powerbooks
++	 * (2400/3400/3500, ohare based) has a second ohare chip
++	 * effectively making a total of 64.
++	 */
++	max_irqs = max_real_irqs = 32;
++	irqctrler = find_devices("mac-io");
++	if (irqctrler)
++	{
++		max_real_irqs = 64;
++		if (irqctrler->next)
++			max_irqs = 128;
++		else
++			max_irqs = 64;
++	}
++	for ( i = 0; i < max_real_irqs ; i++ )
++		irq_desc[i].handler = &pmac_pic;
++
++	/* get addresses of first controller */
++	if (irqctrler) {
++		if  (irqctrler->n_addrs > 0) {
++			addr = (unsigned long)
++				ioremap(irqctrler->addrs[0].address, 0x40);
++			for (i = 0; i < 2; ++i)
++				pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
++					(addr + (2 - i) * 0x10);
++		}
++
++		/* get addresses of second controller */
++		irqctrler = irqctrler->next;
++		if (irqctrler && irqctrler->n_addrs > 0) {
++			addr = (unsigned long)
++				ioremap(irqctrler->addrs[0].address, 0x40);
++			for (i = 2; i < 4; ++i)
++				pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
++					(addr + (4 - i) * 0x10);
++			irq_cascade = irqctrler->intrs[0].line;
++			if (device_is_compatible(irqctrler, "gatwick"))
++				pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
++		}
++	} else {
++		/* older powermacs have a GC (grand central) or ohare at
++		   f3000000, with interrupt control registers at f3000020. */
++		addr = (unsigned long) ioremap(0xf3000000, 0x40);
++		pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20);
++	}
++
++	/* PowerBooks 3400 and 3500 can have a second controller in a second
++	   ohare chip, on the combo ethernet/modem card */
++	if (machine_is_compatible("AAPL,3400/2400")
++	     || machine_is_compatible("AAPL,3500"))
++		irq_cascade = enable_second_ohare();
++
++	/* disable all interrupts in all controllers */
++	for (i = 0; i * 32 < max_irqs; ++i)
++		out_le32(&pmac_irq_hw[i]->enable, 0);
++	/* mark level interrupts */
++	for (i = 0; i < max_irqs; i++)
++		if (level_mask[i >> 5] & (1UL << (i & 0x1f)))
++			irq_desc[i].status = IRQ_LEVEL;
++
++	/* get interrupt line of secondary interrupt controller */
++	if (irq_cascade >= 0) {
++		printk(KERN_INFO "irq: secondary controller on irq %d\n",
++			(int)irq_cascade);
++		for ( i = max_real_irqs ; i < max_irqs ; i++ )
++			irq_desc[i].handler = &gatwick_pic;
++		setup_irq(irq_cascade, &gatwick_cascade_action);
++	}
++	printk("System has %d possible interrupts\n", max_irqs);
++	if (max_irqs != max_real_irqs)
++		printk(KERN_DEBUG "%d interrupts on main controller\n",
++			max_real_irqs);
++
++#ifdef CONFIG_XMON
++	setup_irq(20, &xmon_action);
++#endif	/* CONFIG_XMON */
++#endif	/* CONFIG_PPC32 */
++}
++
++#ifdef CONFIG_PM
++/*
++ * These procedures are used in implementing sleep on the powerbooks.
++ * sleep_save_intrs() saves the states of all interrupt enables
++ * and disables all interrupts except for the nominated one.
++ * sleep_restore_intrs() restores the states of all interrupt enables.
++ */
++unsigned long sleep_save_mask[2];
++
++/* This used to be passed by the PMU driver but that link got
++ * broken with the new driver model. We use this tweak for now...
++ */
++static int pmacpic_find_viaint(void)
++{
++	int viaint = -1;
++
++#ifdef CONFIG_ADB_PMU
++	struct device_node *np;
++
++	if (pmu_get_model() != PMU_OHARE_BASED)
++		goto not_found;
++	np = of_find_node_by_name(NULL, "via-pmu");
++	if (np == NULL)
++		goto not_found;
++	viaint = np->intrs[0].line;
++#endif /* CONFIG_ADB_PMU */
++
++not_found:
++	return viaint;
++}
++
++static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)
++{
++	int viaint = pmacpic_find_viaint();
++
++	sleep_save_mask[0] = ppc_cached_irq_mask[0];
++	sleep_save_mask[1] = ppc_cached_irq_mask[1];
++	ppc_cached_irq_mask[0] = 0;
++	ppc_cached_irq_mask[1] = 0;
++	if (viaint > 0)
++		set_bit(viaint, ppc_cached_irq_mask);
++	out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
++	if (max_real_irqs > 32)
++		out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
++	(void)in_le32(&pmac_irq_hw[0]->event);
++	/* make sure mask gets to controller before we return to caller */
++	mb();
++        (void)in_le32(&pmac_irq_hw[0]->enable);
++
++        return 0;
++}
++
++static int pmacpic_resume(struct sys_device *sysdev)
++{
++	int i;
++
++	out_le32(&pmac_irq_hw[0]->enable, 0);
++	if (max_real_irqs > 32)
++		out_le32(&pmac_irq_hw[1]->enable, 0);
++	mb();
++	for (i = 0; i < max_real_irqs; ++i)
++		if (test_bit(i, sleep_save_mask))
++			pmac_unmask_irq(i);
++
++	return 0;
++}
++
++#endif /* CONFIG_PM */
++
++static struct sysdev_class pmacpic_sysclass = {
++	set_kset_name("pmac_pic"),
++};
++
++static struct sys_device device_pmacpic = {
++	.id		= 0,
++	.cls		= &pmacpic_sysclass,
++};
++
++static struct sysdev_driver driver_pmacpic = {
++#ifdef CONFIG_PM
++	.suspend	= &pmacpic_suspend,
++	.resume		= &pmacpic_resume,
++#endif /* CONFIG_PM */
++};
++
++static int __init init_pmacpic_sysfs(void)
++{
++#ifdef CONFIG_PPC32
++	if (max_irqs == 0)
++		return -ENODEV;
++#endif
++	printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
++	sysdev_class_register(&pmacpic_sysclass);
++	sysdev_register(&device_pmacpic);
++	sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
++	return 0;
++}
++
++subsys_initcall(init_pmacpic_sysfs);
++
+diff --git a/arch/powerpc/platforms/powermac/pic.h b/arch/powerpc/platforms/powermac/pic.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/pic.h
+@@ -0,0 +1,11 @@
++#ifndef __PPC_PLATFORMS_PMAC_PIC_H
++#define __PPC_PLATFORMS_PMAC_PIC_H
++
++#include <linux/irq.h>
++
++extern struct hw_interrupt_type pmac_pic;
++
++void pmac_pic_init(void);
++int pmac_get_irq(struct pt_regs *regs);
++
++#endif /* __PPC_PLATFORMS_PMAC_PIC_H */
+diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/pmac.h
+@@ -0,0 +1,51 @@
++#ifndef __PMAC_H__
++#define __PMAC_H__
++
++#include <linux/pci.h>
++#include <linux/ide.h>
++#include <linux/irq.h>
++
++/*
++ * Declaration for the various functions exported by the
++ * pmac_* files. Mostly for use by pmac_setup
++ */
++
++struct rtc_time;
++
++extern long pmac_time_init(void);
++extern unsigned long pmac_get_boot_time(void);
++extern void pmac_get_rtc_time(struct rtc_time *);
++extern int pmac_set_rtc_time(struct rtc_time *);
++extern void pmac_read_rtc_time(void);
++extern void pmac_calibrate_decr(void);
++extern void pmac_pcibios_fixup(void);
++extern void pmac_pci_init(void);
++extern unsigned long pmac_ide_get_base(int index);
++extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
++	unsigned long data_port, unsigned long ctrl_port, int *irq);
++
++extern void pmac_nvram_update(void);
++extern unsigned char pmac_nvram_read_byte(int addr);
++extern void pmac_nvram_write_byte(int addr, unsigned char val);
++extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
++extern void pmac_pcibios_after_init(void);
++extern int of_show_percpuinfo(struct seq_file *m, int i);
++
++extern void pmac_pci_init(void);
++extern void pmac_setup_pci_dma(void);
++extern void pmac_check_ht_link(void);
++
++extern void pmac_setup_smp(void);
++
++extern unsigned long pmac_ide_get_base(int index);
++extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
++	unsigned long data_port, unsigned long ctrl_port, int *irq);
++
++extern int pmac_nvram_init(void);
++
++extern struct hw_interrupt_type pmac_pic;
++
++void pmac_pic_init(void);
++int pmac_get_irq(struct pt_regs *regs);
++
++#endif /* __PMAC_H__ */
+diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/setup.c
+@@ -0,0 +1,794 @@
++/*
++ *  Powermac setup and early boot code plus other random bits.
++ *
++ *  PowerPC version
++ *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
++ *
++ *  Adapted for Power Macintosh by Paul Mackerras
++ *    Copyright (C) 1996 Paul Mackerras (paulus at samba.org)
++ *
++ *  Derived from "arch/alpha/kernel/setup.c"
++ *    Copyright (C) 1995 Linus Torvalds
++ *
++ *  Maintained by Benjamin Herrenschmidt (benh at 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.
++ *
++ */
++
++/*
++ * bootup setup stuff..
++ */
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/stddef.h>
++#include <linux/unistd.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/user.h>
++#include <linux/a.out.h>
++#include <linux/tty.h>
++#include <linux/string.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/major.h>
++#include <linux/initrd.h>
++#include <linux/vt_kern.h>
++#include <linux/console.h>
++#include <linux/ide.h>
++#include <linux/pci.h>
++#include <linux/adb.h>
++#include <linux/cuda.h>
++#include <linux/pmu.h>
++#include <linux/irq.h>
++#include <linux/seq_file.h>
++#include <linux/root_dev.h>
++#include <linux/bitops.h>
++#include <linux/suspend.h>
++
++#include <asm/reg.h>
++#include <asm/sections.h>
++#include <asm/prom.h>
++#include <asm/system.h>
++#include <asm/pgtable.h>
++#include <asm/io.h>
++#include <asm/pci-bridge.h>
++#include <asm/ohare.h>
++#include <asm/mediabay.h>
++#include <asm/machdep.h>
++#include <asm/dma.h>
++#include <asm/cputable.h>
++#include <asm/btext.h>
++#include <asm/pmac_feature.h>
++#include <asm/time.h>
++#include <asm/of_device.h>
++#include <asm/mmu_context.h>
++#include <asm/iommu.h>
++#include <asm/smu.h>
++#include <asm/pmc.h>
++#include <asm/mpic.h>
++
++#include "pmac.h"
++
++#undef SHOW_GATWICK_IRQS
++
++unsigned char drive_info;
++
++int ppc_override_l2cr = 0;
++int ppc_override_l2cr_value;
++int has_l2cache = 0;
++
++int pmac_newworld = 1;
++
++static int current_root_goodness = -1;
++
++extern int pmac_newworld;
++extern struct machdep_calls pmac_md;
++
++#define DEFAULT_ROOT_DEVICE Root_SDA1	/* sda1 - slightly silly choice */
++
++#ifdef CONFIG_PPC64
++#include <asm/udbg.h>
++int sccdbg;
++#endif
++
++extern void zs_kgdb_hook(int tty_num);
++
++sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
++EXPORT_SYMBOL(sys_ctrler);
++
++#ifdef CONFIG_PMAC_SMU
++unsigned long smu_cmdbuf_abs;
++EXPORT_SYMBOL(smu_cmdbuf_abs);
++#endif
++
++#ifdef CONFIG_SMP
++extern struct smp_ops_t psurge_smp_ops;
++extern struct smp_ops_t core99_smp_ops;
++#endif /* CONFIG_SMP */
++
++static void pmac_show_cpuinfo(struct seq_file *m)
++{
++	struct device_node *np;
++	char *pp;
++	int plen;
++	int mbmodel;
++	unsigned int mbflags;
++	char* mbname;
++
++	mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
++				    PMAC_MB_INFO_MODEL, 0);
++	mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
++				    PMAC_MB_INFO_FLAGS, 0);
++	if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME,
++			      (long) &mbname) != 0)
++		mbname = "Unknown";
++
++	/* find motherboard type */
++	seq_printf(m, "machine\t\t: ");
++	np = of_find_node_by_path("/");
++	if (np != NULL) {
++		pp = (char *) get_property(np, "model", NULL);
++		if (pp != NULL)
++			seq_printf(m, "%s\n", pp);
++		else
++			seq_printf(m, "PowerMac\n");
++		pp = (char *) get_property(np, "compatible", &plen);
++		if (pp != NULL) {
++			seq_printf(m, "motherboard\t:");
++			while (plen > 0) {
++				int l = strlen(pp) + 1;
++				seq_printf(m, " %s", pp);
++				plen -= l;
++				pp += l;
++			}
++			seq_printf(m, "\n");
++		}
++		of_node_put(np);
++	} else
++		seq_printf(m, "PowerMac\n");
++
++	/* print parsed model */
++	seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
++	seq_printf(m, "pmac flags\t: %08x\n", mbflags);
++
++	/* find l2 cache info */
++	np = of_find_node_by_name(NULL, "l2-cache");
++	if (np == NULL)
++		np = of_find_node_by_type(NULL, "cache");
++	if (np != NULL) {
++		unsigned int *ic = (unsigned int *)
++			get_property(np, "i-cache-size", NULL);
++		unsigned int *dc = (unsigned int *)
++			get_property(np, "d-cache-size", NULL);
++		seq_printf(m, "L2 cache\t:");
++		has_l2cache = 1;
++		if (get_property(np, "cache-unified", NULL) != 0 && dc) {
++			seq_printf(m, " %dK unified", *dc / 1024);
++		} else {
++			if (ic)
++				seq_printf(m, " %dK instruction", *ic / 1024);
++			if (dc)
++				seq_printf(m, "%s %dK data",
++					   (ic? " +": ""), *dc / 1024);
++		}
++		pp = get_property(np, "ram-type", NULL);
++		if (pp)
++			seq_printf(m, " %s", pp);
++		seq_printf(m, "\n");
++		of_node_put(np);
++	}
++
++	/* Indicate newworld/oldworld */
++	seq_printf(m, "pmac-generation\t: %s\n",
++		   pmac_newworld ? "NewWorld" : "OldWorld");
++}
++
++static void pmac_show_percpuinfo(struct seq_file *m, int i)
++{
++#ifdef CONFIG_CPU_FREQ_PMAC
++	extern unsigned int pmac_get_one_cpufreq(int i);
++	unsigned int freq = pmac_get_one_cpufreq(i);
++	if (freq != 0) {
++		seq_printf(m, "clock\t\t: %dMHz\n", freq/1000);
++		return;
++	}
++#endif /* CONFIG_CPU_FREQ_PMAC */
++}
++
++#ifndef CONFIG_ADB_CUDA
++int find_via_cuda(void)
++{
++	if (!find_devices("via-cuda"))
++		return 0;
++	printk("WARNING ! Your machine is CUDA-based but your kernel\n");
++	printk("          wasn't compiled with CONFIG_ADB_CUDA option !\n");
++	return 0;
++}
++#endif
++
++#ifndef CONFIG_ADB_PMU
++int find_via_pmu(void)
++{
++	if (!find_devices("via-pmu"))
++		return 0;
++	printk("WARNING ! Your machine is PMU-based but your kernel\n");
++	printk("          wasn't compiled with CONFIG_ADB_PMU option !\n");
++	return 0;
++}
++#endif
++
++#ifndef CONFIG_PMAC_SMU
++int smu_init(void)
++{
++	/* should check and warn if SMU is present */
++	return 0;
++}
++#endif
++
++#ifdef CONFIG_PPC32
++static volatile u32 *sysctrl_regs;
++
++static void __init ohare_init(void)
++{
++	/* this area has the CPU identification register
++	   and some registers used by smp boards */
++	sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
++
++	/*
++	 * Turn on the L2 cache.
++	 * We assume that we have a PSX memory controller iff
++	 * we have an ohare I/O controller.
++	 */
++	if (find_devices("ohare") != NULL) {
++		if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
++			if (sysctrl_regs[4] & 0x10)
++				sysctrl_regs[4] |= 0x04000020;
++			else
++				sysctrl_regs[4] |= 0x04000000;
++			if(has_l2cache)
++				printk(KERN_INFO "Level 2 cache enabled\n");
++		}
++	}
++}
++
++static void __init l2cr_init(void)
++{
++	/* Checks "l2cr-value" property in the registry */
++	if (cpu_has_feature(CPU_FTR_L2CR)) {
++		struct device_node *np = find_devices("cpus");
++		if (np == 0)
++			np = find_type_devices("cpu");
++		if (np != 0) {
++			unsigned int *l2cr = (unsigned int *)
++				get_property(np, "l2cr-value", NULL);
++			if (l2cr != 0) {
++				ppc_override_l2cr = 1;
++				ppc_override_l2cr_value = *l2cr;
++				_set_L2CR(0);
++				_set_L2CR(ppc_override_l2cr_value);
++			}
++		}
++	}
++
++	if (ppc_override_l2cr)
++		printk(KERN_INFO "L2CR overridden (0x%x), "
++		       "backside cache is %s\n",
++		       ppc_override_l2cr_value,
++		       (ppc_override_l2cr_value & 0x80000000)
++				? "enabled" : "disabled");
++}
++#endif
++
++void __init pmac_setup_arch(void)
++{
++	struct device_node *cpu, *ic;
++	int *fp;
++	unsigned long pvr;
++
++	pvr = PVR_VER(mfspr(SPRN_PVR));
++
++	/* Set loops_per_jiffy to a half-way reasonable value,
++	   for use until calibrate_delay gets called. */
++	loops_per_jiffy = 50000000 / HZ;
++	cpu = of_find_node_by_type(NULL, "cpu");
++	if (cpu != NULL) {
++		fp = (int *) get_property(cpu, "clock-frequency", NULL);
++		if (fp != NULL) {
++			if (pvr >= 0x30 && pvr < 0x80)
++				/* PPC970 etc. */
++				loops_per_jiffy = *fp / (3 * HZ);
++			else if (pvr == 4 || pvr >= 8)
++				/* 604, G3, G4 etc. */
++				loops_per_jiffy = *fp / HZ;
++			else
++				/* 601, 603, etc. */
++				loops_per_jiffy = *fp / (2 * HZ);
++		}
++		of_node_put(cpu);
++	}
++
++	/* See if newworld or oldworld */
++	for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; )
++		if (get_property(ic, "interrupt-controller", NULL))
++			break;
++	pmac_newworld = (ic != NULL);
++	if (ic)
++		of_node_put(ic);
++
++	/* Lookup PCI hosts */
++	pmac_pci_init();
++
++#ifdef CONFIG_PPC32
++	ohare_init();
++	l2cr_init();
++#endif /* CONFIG_PPC32 */
++
++#ifdef CONFIG_PPC64
++	/* Probe motherboard chipset */
++	/* this is done earlier in setup_arch for 32-bit */
++	pmac_feature_init();
++
++	/* We can NAP */
++	powersave_nap = 1;
++	printk(KERN_INFO "Using native/NAP idle loop\n");
++#endif
++
++#ifdef CONFIG_KGDB
++	zs_kgdb_hook(0);
++#endif
++
++	find_via_cuda();
++	find_via_pmu();
++	smu_init();
++
++#ifdef CONFIG_NVRAM
++	pmac_nvram_init();
++#endif
++
++#ifdef CONFIG_PPC32
++#ifdef CONFIG_BLK_DEV_INITRD
++	if (initrd_start)
++		ROOT_DEV = Root_RAM0;
++	else
++#endif
++		ROOT_DEV = DEFAULT_ROOT_DEVICE;
++#endif
++
++#ifdef CONFIG_SMP
++	/* Check for Core99 */
++	if (find_devices("uni-n") || find_devices("u3"))
++		smp_ops = &core99_smp_ops;
++#ifdef CONFIG_PPC32
++	else
++		smp_ops = &psurge_smp_ops;
++#endif
++#endif /* CONFIG_SMP */
++}
++
++char *bootpath;
++char *bootdevice;
++void *boot_host;
++int boot_target;
++int boot_part;
++extern dev_t boot_dev;
++
++#ifdef CONFIG_SCSI
++void __init note_scsi_host(struct device_node *node, void *host)
++{
++	int l;
++	char *p;
++
++	l = strlen(node->full_name);
++	if (bootpath != NULL && bootdevice != NULL
++	    && strncmp(node->full_name, bootdevice, l) == 0
++	    && (bootdevice[l] == '/' || bootdevice[l] == 0)) {
++		boot_host = host;
++		/*
++		 * There's a bug in OF 1.0.5.  (Why am I not surprised.)
++		 * If you pass a path like scsi/sd at 1:0 to canon, it returns
++		 * something like /bandit at F2000000/gc at 10/53c94 at 10000/sd at 0,0
++		 * That is, the scsi target number doesn't get preserved.
++		 * So we pick the target number out of bootpath and use that.
++		 */
++		p = strstr(bootpath, "/sd@");
++		if (p != NULL) {
++			p += 4;
++			boot_target = simple_strtoul(p, NULL, 10);
++			p = strchr(p, ':');
++			if (p != NULL)
++				boot_part = simple_strtoul(p + 1, NULL, 10);
++		}
++	}
++}
++EXPORT_SYMBOL(note_scsi_host);
++#endif
++
++#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
++static dev_t __init find_ide_boot(void)
++{
++	char *p;
++	int n;
++	dev_t __init pmac_find_ide_boot(char *bootdevice, int n);
++
++	if (bootdevice == NULL)
++		return 0;
++	p = strrchr(bootdevice, '/');
++	if (p == NULL)
++		return 0;
++	n = p - bootdevice;
++
++	return pmac_find_ide_boot(bootdevice, n);
++}
++#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
++
++static void __init find_boot_device(void)
++{
++#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
++	boot_dev = find_ide_boot();
++#endif
++}
++
++/* TODO: Merge the suspend-to-ram with the common code !!!
++ * currently, this is a stub implementation for suspend-to-disk
++ * only
++ */
++
++#ifdef CONFIG_SOFTWARE_SUSPEND
++
++static int pmac_pm_prepare(suspend_state_t state)
++{
++	printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
++
++	return 0;
++}
++
++static int pmac_pm_enter(suspend_state_t state)
++{
++	printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
++
++	/* Giveup the lazy FPU & vec so we don't have to back them
++	 * up from the low level code
++	 */
++	enable_kernel_fp();
++
++#ifdef CONFIG_ALTIVEC
++	if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
++		enable_kernel_altivec();
++#endif /* CONFIG_ALTIVEC */
++
++	return 0;
++}
++
++static int pmac_pm_finish(suspend_state_t state)
++{
++	printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
++
++	/* Restore userland MMU context */
++	set_context(current->active_mm->context, current->active_mm->pgd);
++
++	return 0;
++}
++
++static struct pm_ops pmac_pm_ops = {
++	.pm_disk_mode	= PM_DISK_SHUTDOWN,
++	.prepare	= pmac_pm_prepare,
++	.enter		= pmac_pm_enter,
++	.finish		= pmac_pm_finish,
++};
++
++#endif /* CONFIG_SOFTWARE_SUSPEND */
++
++static int initializing = 1;
++
++static int pmac_late_init(void)
++{
++	initializing = 0;
++#ifdef CONFIG_SOFTWARE_SUSPEND
++	pm_set_ops(&pmac_pm_ops);
++#endif /* CONFIG_SOFTWARE_SUSPEND */
++	return 0;
++}
++
++late_initcall(pmac_late_init);
++
++/* can't be __init - can be called whenever a disk is first accessed */
++void note_bootable_part(dev_t dev, int part, int goodness)
++{
++	static int found_boot = 0;
++	char *p;
++
++	if (!initializing)
++		return;
++	if ((goodness <= current_root_goodness) &&
++	    ROOT_DEV != DEFAULT_ROOT_DEVICE)
++		return;
++	p = strstr(saved_command_line, "root=");
++	if (p != NULL && (p == saved_command_line || p[-1] == ' '))
++		return;
++
++	if (!found_boot) {
++		find_boot_device();
++		found_boot = 1;
++	}
++	if (!boot_dev || dev == boot_dev) {
++		ROOT_DEV = dev + part;
++		boot_dev = 0;
++		current_root_goodness = goodness;
++	}
++}
++
++#ifdef CONFIG_ADB_CUDA
++static void cuda_restart(void)
++{
++	struct adb_request req;
++
++	cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM);
++	for (;;)
++		cuda_poll();
++}
++
++static void cuda_shutdown(void)
++{
++	struct adb_request req;
++
++	cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN);
++	for (;;)
++		cuda_poll();
++}
++
++#else
++#define cuda_restart()
++#define cuda_shutdown()
++#endif
++
++#ifndef CONFIG_ADB_PMU
++#define pmu_restart()
++#define pmu_shutdown()
++#endif
++
++#ifndef CONFIG_PMAC_SMU
++#define smu_restart()
++#define smu_shutdown()
++#endif
++
++static void pmac_restart(char *cmd)
++{
++	switch (sys_ctrler) {
++	case SYS_CTRLER_CUDA:
++		cuda_restart();
++		break;
++	case SYS_CTRLER_PMU:
++		pmu_restart();
++		break;
++	case SYS_CTRLER_SMU:
++		smu_restart();
++		break;
++	default: ;
++	}
++}
++
++static void pmac_power_off(void)
++{
++	switch (sys_ctrler) {
++	case SYS_CTRLER_CUDA:
++		cuda_shutdown();
++		break;
++	case SYS_CTRLER_PMU:
++		pmu_shutdown();
++		break;
++	case SYS_CTRLER_SMU:
++		smu_shutdown();
++		break;
++	default: ;
++	}
++}
++
++static void
++pmac_halt(void)
++{
++	pmac_power_off();
++}
++
++#ifdef CONFIG_PPC32
++void __init pmac_init(void)
++{
++	/* isa_io_base gets set in pmac_pci_init */
++	isa_mem_base = PMAC_ISA_MEM_BASE;
++	pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
++	ISA_DMA_THRESHOLD = ~0L;
++	DMA_MODE_READ = 1;
++	DMA_MODE_WRITE = 2;
++
++	ppc_md = pmac_md;
++
++#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
++#ifdef CONFIG_BLK_DEV_IDE_PMAC
++        ppc_ide_md.ide_init_hwif	= pmac_ide_init_hwif_ports;
++        ppc_ide_md.default_io_base	= pmac_ide_get_base;
++#endif /* CONFIG_BLK_DEV_IDE_PMAC */
++#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
++
++	if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
++
++}
++#endif
++
++/* 
++ * Early initialization.
++ */
++static void __init pmac_init_early(void)
++{
++#ifdef CONFIG_PPC64
++	/* Initialize hash table, from now on, we can take hash faults
++	 * and call ioremap
++	 */
++	hpte_init_native();
++
++	/* Init SCC */
++	if (strstr(cmd_line, "sccdbg")) {
++		sccdbg = 1;
++		udbg_init_scc(NULL);
++	}
++
++	/* Setup interrupt mapping options */
++	ppc64_interrupt_controller = IC_OPEN_PIC;
++
++	iommu_init_early_u3();
++#endif
++}
++
++static void __init pmac_progress(char *s, unsigned short hex)
++{
++#ifdef CONFIG_PPC64
++	if (sccdbg) {
++		udbg_puts(s);
++		udbg_puts("\n");
++		return;
++	}
++#endif
++#ifdef CONFIG_BOOTX_TEXT
++	if (boot_text_mapped) {
++		btext_drawstring(s);
++		btext_drawchar('\n');
++	}
++#endif /* CONFIG_BOOTX_TEXT */
++}
++
++/*
++ * pmac has no legacy IO, anything calling this function has to
++ * fail or bad things will happen
++ */
++static int pmac_check_legacy_ioport(unsigned int baseport)
++{
++	return -ENODEV;
++}
++
++static int __init pmac_declare_of_platform_devices(void)
++{
++	struct device_node *np, *npp;
++
++	np = find_devices("uni-n");
++	if (np) {
++		for (np = np->child; np != NULL; np = np->sibling)
++			if (strncmp(np->name, "i2c", 3) == 0) {
++				of_platform_device_create(np, "uni-n-i2c",
++							  NULL);
++				break;
++			}
++	}
++	np = find_devices("valkyrie");
++	if (np)
++		of_platform_device_create(np, "valkyrie", NULL);
++	np = find_devices("platinum");
++	if (np)
++		of_platform_device_create(np, "platinum", NULL);
++
++	npp = of_find_node_by_name(NULL, "u3");
++	if (npp) {
++		for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
++			if (strncmp(np->name, "i2c", 3) == 0) {
++				of_platform_device_create(np, "u3-i2c", NULL);
++				of_node_put(np);
++				break;
++			}
++		}
++		of_node_put(npp);
++	}
++        np = of_find_node_by_type(NULL, "smu");
++        if (np) {
++		of_platform_device_create(np, "smu", NULL);
++		of_node_put(np);
++	}
++
++	return 0;
++}
++
++device_initcall(pmac_declare_of_platform_devices);
++
++/*
++ * Called very early, MMU is off, device-tree isn't unflattened
++ */
++static int __init pmac_probe(int platform)
++{
++#ifdef CONFIG_PPC64
++	if (platform != PLATFORM_POWERMAC)
++		return 0;
++
++	/*
++	 * On U3, the DART (iommu) must be allocated now since it
++	 * has an impact on htab_initialize (due to the large page it
++	 * occupies having to be broken up so the DART itself is not
++	 * part of the cacheable linar mapping
++	 */
++	alloc_u3_dart_table();
++#endif
++
++#ifdef CONFIG_PMAC_SMU
++	/*
++	 * SMU based G5s need some memory below 2Gb, at least the current
++	 * driver needs that. We have to allocate it now. We allocate 4k
++	 * (1 small page) for now.
++	 */
++	smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL);
++#endif /* CONFIG_PMAC_SMU */
++
++	return 1;
++}
++
++#ifdef CONFIG_PPC64
++static int pmac_probe_mode(struct pci_bus *bus)
++{
++	struct device_node *node = bus->sysdata;
++
++	/* We need to use normal PCI probing for the AGP bus,
++	   since the device for the AGP bridge isn't in the tree. */
++	if (bus->self == NULL && device_is_compatible(node, "u3-agp"))
++		return PCI_PROBE_NORMAL;
++
++	return PCI_PROBE_DEVTREE;
++}
++#endif
++
++struct machdep_calls __initdata pmac_md = {
++#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
++	.cpu_die		= generic_mach_cpu_die,
++#endif
++	.probe			= pmac_probe,
++	.setup_arch		= pmac_setup_arch,
++	.init_early		= pmac_init_early,
++	.show_cpuinfo		= pmac_show_cpuinfo,
++	.show_percpuinfo	= pmac_show_percpuinfo,
++	.init_IRQ		= pmac_pic_init,
++	.get_irq		= mpic_get_irq,	/* changed later */
++	.pcibios_fixup		= pmac_pcibios_fixup,
++	.restart		= pmac_restart,
++	.power_off		= pmac_power_off,
++	.halt			= pmac_halt,
++	.time_init		= pmac_time_init,
++	.get_boot_time		= pmac_get_boot_time,
++	.set_rtc_time		= pmac_set_rtc_time,
++	.get_rtc_time		= pmac_get_rtc_time,
++	.calibrate_decr		= pmac_calibrate_decr,
++	.feature_call		= pmac_do_feature_call,
++	.check_legacy_ioport	= pmac_check_legacy_ioport,
++	.progress		= pmac_progress,
++#ifdef CONFIG_PPC64
++	.pci_probe_mode		= pmac_probe_mode,
++	.idle_loop		= native_idle,
++	.enable_pmcs		= power4_enable_pmcs,
++#endif
++#ifdef CONFIG_PPC32
++	.pcibios_enable_device_hook = pmac_pci_enable_device_hook,
++	.pcibios_after_init	= pmac_pcibios_after_init,
++	.phys_mem_access_prot	= pci_phys_mem_access_prot,
++#endif
++};
+diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/sleep.S
+@@ -0,0 +1,396 @@
++/*
++ * This file contains sleep low-level functions for PowerBook G3.
++ *    Copyright (C) 1999 Benjamin Herrenschmidt (benh at kernel.crashing.org)
++ *    and Paul Mackerras (paulus at samba.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/config.h>
++#include <asm/processor.h>
++#include <asm/page.h>
++#include <asm/ppc_asm.h>
++#include <asm/cputable.h>
++#include <asm/cache.h>
++#include <asm/thread_info.h>
++#include <asm/asm-offsets.h>
++
++#define MAGIC	0x4c617273	/* 'Lars' */
++
++/*
++ * Structure for storing CPU registers on the stack.
++ */
++#define SL_SP		0
++#define SL_PC		4
++#define SL_MSR		8
++#define SL_SDR1		0xc
++#define SL_SPRG0	0x10	/* 4 sprg's */
++#define SL_DBAT0	0x20
++#define SL_IBAT0	0x28
++#define SL_DBAT1	0x30
++#define SL_IBAT1	0x38
++#define SL_DBAT2	0x40
++#define SL_IBAT2	0x48
++#define SL_DBAT3	0x50
++#define SL_IBAT3	0x58
++#define SL_TB		0x60
++#define SL_R2		0x68
++#define SL_CR		0x6c
++#define SL_R12		0x70	/* r12 to r31 */
++#define SL_SIZE		(SL_R12 + 80)
++
++	.section .text
++	.align	5
++
++#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)
++
++/* This gets called by via-pmu.c late during the sleep process.
++ * The PMU was already send the sleep command and will shut us down
++ * soon. We need to save all that is needed and setup the wakeup
++ * vector that will be called by the ROM on wakeup
++ */
++_GLOBAL(low_sleep_handler)
++#ifndef CONFIG_6xx
++	blr
++#else
++	mflr	r0
++	stw	r0,4(r1)
++	stwu	r1,-SL_SIZE(r1)
++	mfcr	r0
++	stw	r0,SL_CR(r1)
++	stw	r2,SL_R2(r1)
++	stmw	r12,SL_R12(r1)
++
++	/* Save MSR & SDR1 */
++	mfmsr	r4
++	stw	r4,SL_MSR(r1)
++	mfsdr1	r4
++	stw	r4,SL_SDR1(r1)
++
++	/* Get a stable timebase and save it */
++1:	mftbu	r4
++	stw	r4,SL_TB(r1)
++	mftb	r5
++	stw	r5,SL_TB+4(r1)
++	mftbu	r3
++	cmpw	r3,r4
++	bne	1b
++
++	/* Save SPRGs */
++	mfsprg	r4,0
++	stw	r4,SL_SPRG0(r1)
++	mfsprg	r4,1
++	stw	r4,SL_SPRG0+4(r1)
++	mfsprg	r4,2
++	stw	r4,SL_SPRG0+8(r1)
++	mfsprg	r4,3
++	stw	r4,SL_SPRG0+12(r1)
++
++	/* Save BATs */
++	mfdbatu	r4,0
++	stw	r4,SL_DBAT0(r1)
++	mfdbatl	r4,0
++	stw	r4,SL_DBAT0+4(r1)
++	mfdbatu	r4,1
++	stw	r4,SL_DBAT1(r1)
++	mfdbatl	r4,1
++	stw	r4,SL_DBAT1+4(r1)
++	mfdbatu	r4,2
++	stw	r4,SL_DBAT2(r1)
++	mfdbatl	r4,2
++	stw	r4,SL_DBAT2+4(r1)
++	mfdbatu	r4,3
++	stw	r4,SL_DBAT3(r1)
++	mfdbatl	r4,3
++	stw	r4,SL_DBAT3+4(r1)
++	mfibatu	r4,0
++	stw	r4,SL_IBAT0(r1)
++	mfibatl	r4,0
++	stw	r4,SL_IBAT0+4(r1)
++	mfibatu	r4,1
++	stw	r4,SL_IBAT1(r1)
++	mfibatl	r4,1
++	stw	r4,SL_IBAT1+4(r1)
++	mfibatu	r4,2
++	stw	r4,SL_IBAT2(r1)
++	mfibatl	r4,2
++	stw	r4,SL_IBAT2+4(r1)
++	mfibatu	r4,3
++	stw	r4,SL_IBAT3(r1)
++	mfibatl	r4,3
++	stw	r4,SL_IBAT3+4(r1)
++
++	/* Backup various CPU config stuffs */
++	bl	__save_cpu_setup
++
++	/* The ROM can wake us up via 2 different vectors:
++	 *  - On wallstreet & lombard, we must write a magic
++	 *    value 'Lars' at address 4 and a pointer to a
++	 *    memory location containing the PC to resume from
++	 *    at address 0.
++	 *  - On Core99, we must store the wakeup vector at
++	 *    address 0x80 and eventually it's parameters
++	 *    at address 0x84. I've have some trouble with those
++	 *    parameters however and I no longer use them.
++	 */
++	lis	r5,grackle_wake_up at ha
++	addi	r5,r5,grackle_wake_up at l
++	tophys(r5,r5)
++	stw	r5,SL_PC(r1)
++	lis	r4,KERNELBASE at h
++	tophys(r5,r1)
++	addi	r5,r5,SL_PC
++	lis	r6,MAGIC at ha
++	addi	r6,r6,MAGIC at l
++	stw	r5,0(r4)
++	stw	r6,4(r4)
++	/* Setup stuffs at 0x80-0x84 for Core99 */
++	lis	r3,core99_wake_up at ha
++	addi	r3,r3,core99_wake_up at l
++	tophys(r3,r3)
++	stw	r3,0x80(r4)
++	stw	r5,0x84(r4)
++	/* Store a pointer to our backup storage into
++	 * a kernel global
++	 */
++	lis r3,sleep_storage at ha
++	addi r3,r3,sleep_storage at l
++	stw r5,0(r3)
++
++	.globl	low_cpu_die
++low_cpu_die:
++	/* Flush & disable all caches */
++	bl	flush_disable_caches
++
++	/* Turn off data relocation. */
++	mfmsr	r3		/* Save MSR in r7 */
++	rlwinm	r3,r3,0,28,26	/* Turn off DR bit */
++	sync
++	mtmsr	r3
++	isync
++
++BEGIN_FTR_SECTION
++	/* Flush any pending L2 data prefetches to work around HW bug */
++	sync
++	lis	r3,0xfff0
++	lwz	r0,0(r3)	/* perform cache-inhibited load to ROM */
++	sync			/* (caches are disabled at this point) */
++END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
++
++/*
++ * Set the HID0 and MSR for sleep.
++ */
++	mfspr	r2,SPRN_HID0
++	rlwinm	r2,r2,0,10,7	/* clear doze, nap */
++	oris	r2,r2,HID0_SLEEP at h
++	sync
++	isync
++	mtspr	SPRN_HID0,r2
++	sync
++
++/* This loop puts us back to sleep in case we have a spurrious
++ * wakeup so that the host bridge properly stays asleep. The
++ * CPU will be turned off, either after a known time (about 1
++ * second) on wallstreet & lombard, or as soon as the CPU enters
++ * SLEEP mode on core99
++ */
++	mfmsr	r2
++	oris	r2,r2,MSR_POW at h
++1:	sync
++	mtmsr	r2
++	isync
++	b	1b
++
++/*
++ * Here is the resume code.
++ */
++
++
++/*
++ * Core99 machines resume here
++ * r4 has the physical address of SL_PC(sp) (unused)
++ */
++_GLOBAL(core99_wake_up)
++	/* Make sure HID0 no longer contains any sleep bit and that data cache
++	 * is disabled
++	 */
++	mfspr	r3,SPRN_HID0
++	rlwinm	r3,r3,0,11,7		/* clear SLEEP, NAP, DOZE bits */
++	rlwinm	3,r3,0,18,15		/* clear DCE, ICE */
++	mtspr	SPRN_HID0,r3
++	sync
++	isync
++
++	/* sanitize MSR */
++	mfmsr	r3
++	ori	r3,r3,MSR_EE|MSR_IP
++	xori	r3,r3,MSR_EE|MSR_IP
++	sync
++	isync
++	mtmsr	r3
++	sync
++	isync
++
++	/* Recover sleep storage */
++	lis	r3,sleep_storage at ha
++	addi	r3,r3,sleep_storage at l
++	tophys(r3,r3)
++	lwz	r1,0(r3)
++
++	/* Pass thru to older resume code ... */
++/*
++ * Here is the resume code for older machines.
++ * r1 has the physical address of SL_PC(sp).
++ */
++
++grackle_wake_up:
++
++	/* Restore the kernel's segment registers before
++	 * we do any r1 memory access as we are not sure they
++	 * are in a sane state above the first 256Mb region
++	 */
++	li	r0,16		/* load up segment register values */
++	mtctr	r0		/* for context 0 */
++	lis	r3,0x2000	/* Ku = 1, VSID = 0 */
++	li	r4,0
++3:	mtsrin	r3,r4
++	addi	r3,r3,0x111	/* increment VSID */
++	addis	r4,r4,0x1000	/* address of next segment */
++	bdnz	3b
++	sync
++	isync
++
++	subi	r1,r1,SL_PC
++
++	/* Restore various CPU config stuffs */
++	bl	__restore_cpu_setup
++
++	/* Make sure all FPRs have been initialized */
++	bl	reloc_offset
++	bl	__init_fpu_registers
++
++	/* Invalidate & enable L1 cache, we don't care about
++	 * whatever the ROM may have tried to write to memory
++	 */
++	bl	__inval_enable_L1
++
++	/* Restore the BATs, and SDR1.  Then we can turn on the MMU. */
++	lwz	r4,SL_SDR1(r1)
++	mtsdr1	r4
++	lwz	r4,SL_SPRG0(r1)
++	mtsprg	0,r4
++	lwz	r4,SL_SPRG0+4(r1)
++	mtsprg	1,r4
++	lwz	r4,SL_SPRG0+8(r1)
++	mtsprg	2,r4
++	lwz	r4,SL_SPRG0+12(r1)
++	mtsprg	3,r4
++
++	lwz	r4,SL_DBAT0(r1)
++	mtdbatu	0,r4
++	lwz	r4,SL_DBAT0+4(r1)
++	mtdbatl	0,r4
++	lwz	r4,SL_DBAT1(r1)
++	mtdbatu	1,r4
++	lwz	r4,SL_DBAT1+4(r1)
++	mtdbatl	1,r4
++	lwz	r4,SL_DBAT2(r1)
++	mtdbatu	2,r4
++	lwz	r4,SL_DBAT2+4(r1)
++	mtdbatl	2,r4
++	lwz	r4,SL_DBAT3(r1)
++	mtdbatu	3,r4
++	lwz	r4,SL_DBAT3+4(r1)
++	mtdbatl	3,r4
++	lwz	r4,SL_IBAT0(r1)
++	mtibatu	0,r4
++	lwz	r4,SL_IBAT0+4(r1)
++	mtibatl	0,r4
++	lwz	r4,SL_IBAT1(r1)
++	mtibatu	1,r4
++	lwz	r4,SL_IBAT1+4(r1)
++	mtibatl	1,r4
++	lwz	r4,SL_IBAT2(r1)
++	mtibatu	2,r4
++	lwz	r4,SL_IBAT2+4(r1)
++	mtibatl	2,r4
++	lwz	r4,SL_IBAT3(r1)
++	mtibatu	3,r4
++	lwz	r4,SL_IBAT3+4(r1)
++	mtibatl	3,r4
++
++BEGIN_FTR_SECTION
++	li	r4,0
++	mtspr	SPRN_DBAT4U,r4
++	mtspr	SPRN_DBAT4L,r4
++	mtspr	SPRN_DBAT5U,r4
++	mtspr	SPRN_DBAT5L,r4
++	mtspr	SPRN_DBAT6U,r4
++	mtspr	SPRN_DBAT6L,r4
++	mtspr	SPRN_DBAT7U,r4
++	mtspr	SPRN_DBAT7L,r4
++	mtspr	SPRN_IBAT4U,r4
++	mtspr	SPRN_IBAT4L,r4
++	mtspr	SPRN_IBAT5U,r4
++	mtspr	SPRN_IBAT5L,r4
++	mtspr	SPRN_IBAT6U,r4
++	mtspr	SPRN_IBAT6L,r4
++	mtspr	SPRN_IBAT7U,r4
++	mtspr	SPRN_IBAT7L,r4
++END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
++
++	/* Flush all TLBs */
++	lis	r4,0x1000
++1:	addic.	r4,r4,-0x1000
++	tlbie	r4
++	blt	1b
++	sync
++
++	/* restore the MSR and turn on the MMU */
++	lwz	r3,SL_MSR(r1)
++	bl	turn_on_mmu
++
++	/* get back the stack pointer */
++	tovirt(r1,r1)
++
++	/* Restore TB */
++	li	r3,0
++	mttbl	r3
++	lwz	r3,SL_TB(r1)
++	lwz	r4,SL_TB+4(r1)
++	mttbu	r3
++	mttbl	r4
++
++	/* Restore the callee-saved registers and return */
++	lwz	r0,SL_CR(r1)
++	mtcr	r0
++	lwz	r2,SL_R2(r1)
++	lmw	r12,SL_R12(r1)
++	addi	r1,r1,SL_SIZE
++	lwz	r0,4(r1)
++	mtlr	r0
++	blr
++
++turn_on_mmu:
++	mflr	r4
++	tovirt(r4,r4)
++	mtsrr0	r4
++	mtsrr1	r3
++	sync
++	isync
++	rfi
++
++#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
++
++	.section .data
++	.balign	L1_CACHE_BYTES
++sleep_storage:
++	.long 0
++	.balign	L1_CACHE_BYTES, 0
++
++#endif /* CONFIG_6xx */
++	.section .text
+diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/smp.c
+@@ -0,0 +1,865 @@
++/*
++ * SMP support for power macintosh.
++ *
++ * We support both the old "powersurge" SMP architecture
++ * and the current Core99 (G4 PowerMac) machines.
++ *
++ * Note that we don't support the very first rev. of
++ * Apple/DayStar 2 CPUs board, the one with the funky
++ * watchdog. Hopefully, none of these should be there except
++ * maybe internally to Apple. I should probably still add some
++ * code to detect this card though and disable SMP. --BenH.
++ *
++ * Support Macintosh G4 SMP by Troy Benjegerdes (hozer at drgw.net)
++ * and Ben Herrenschmidt <benh at kernel.crashing.org>.
++ *
++ * Support for DayStar quad CPU cards
++ * Copyright (C) XLR8, Inc. 1994-2000
++ *
++ *  This program is free software; you can redistribute it and/or
++ *  modify it under the terms of the 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/smp.h>
++#include <linux/smp_lock.h>
++#include <linux/interrupt.h>
++#include <linux/kernel_stat.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/spinlock.h>
++#include <linux/errno.h>
++#include <linux/hardirq.h>
++#include <linux/cpu.h>
++
++#include <asm/ptrace.h>
++#include <asm/atomic.h>
++#include <asm/irq.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/sections.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/smp.h>
++#include <asm/machdep.h>
++#include <asm/pmac_feature.h>
++#include <asm/time.h>
++#include <asm/mpic.h>
++#include <asm/cacheflush.h>
++#include <asm/keylargo.h>
++#include <asm/pmac_low_i2c.h>
++
++#undef DEBUG
++
++#ifdef DEBUG
++#define DBG(fmt...) udbg_printf(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++extern void __secondary_start_pmac_0(void);
++
++#ifdef CONFIG_PPC32
++
++/* Sync flag for HW tb sync */
++static volatile int sec_tb_reset = 0;
++
++/*
++ * Powersurge (old powermac SMP) support.
++ */
++
++/* Addresses for powersurge registers */
++#define HAMMERHEAD_BASE		0xf8000000
++#define HHEAD_CONFIG		0x90
++#define HHEAD_SEC_INTR		0xc0
++
++/* register for interrupting the primary processor on the powersurge */
++/* N.B. this is actually the ethernet ROM! */
++#define PSURGE_PRI_INTR		0xf3019000
++
++/* register for storing the start address for the secondary processor */
++/* N.B. this is the PCI config space address register for the 1st bridge */
++#define PSURGE_START		0xf2800000
++
++/* Daystar/XLR8 4-CPU card */
++#define PSURGE_QUAD_REG_ADDR	0xf8800000
++
++#define PSURGE_QUAD_IRQ_SET	0
++#define PSURGE_QUAD_IRQ_CLR	1
++#define PSURGE_QUAD_IRQ_PRIMARY	2
++#define PSURGE_QUAD_CKSTOP_CTL	3
++#define PSURGE_QUAD_PRIMARY_ARB	4
++#define PSURGE_QUAD_BOARD_ID	6
++#define PSURGE_QUAD_WHICH_CPU	7
++#define PSURGE_QUAD_CKSTOP_RDBK	8
++#define PSURGE_QUAD_RESET_CTL	11
++
++#define PSURGE_QUAD_OUT(r, v)	(out_8(quad_base + ((r) << 4) + 4, (v)))
++#define PSURGE_QUAD_IN(r)	(in_8(quad_base + ((r) << 4) + 4) & 0x0f)
++#define PSURGE_QUAD_BIS(r, v)	(PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
++#define PSURGE_QUAD_BIC(r, v)	(PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
++
++/* virtual addresses for the above */
++static volatile u8 __iomem *hhead_base;
++static volatile u8 __iomem *quad_base;
++static volatile u32 __iomem *psurge_pri_intr;
++static volatile u8 __iomem *psurge_sec_intr;
++static volatile u32 __iomem *psurge_start;
++
++/* values for psurge_type */
++#define PSURGE_NONE		-1
++#define PSURGE_DUAL		0
++#define PSURGE_QUAD_OKEE	1
++#define PSURGE_QUAD_COTTON	2
++#define PSURGE_QUAD_ICEGRASS	3
++
++/* what sort of powersurge board we have */
++static int psurge_type = PSURGE_NONE;
++
++/*
++ * Set and clear IPIs for powersurge.
++ */
++static inline void psurge_set_ipi(int cpu)
++{
++	if (psurge_type == PSURGE_NONE)
++		return;
++	if (cpu == 0)
++		in_be32(psurge_pri_intr);
++	else if (psurge_type == PSURGE_DUAL)
++		out_8(psurge_sec_intr, 0);
++	else
++		PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
++}
++
++static inline void psurge_clr_ipi(int cpu)
++{
++	if (cpu > 0) {
++		switch(psurge_type) {
++		case PSURGE_DUAL:
++			out_8(psurge_sec_intr, ~0);
++		case PSURGE_NONE:
++			break;
++		default:
++			PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
++		}
++	}
++}
++
++/*
++ * On powersurge (old SMP powermac architecture) we don't have
++ * separate IPIs for separate messages like openpic does.  Instead
++ * we have a bitmap for each processor, where a 1 bit means that
++ * the corresponding message is pending for that processor.
++ * Ideally each cpu's entry would be in a different cache line.
++ *  -- paulus.
++ */
++static unsigned long psurge_smp_message[NR_CPUS];
++
++void psurge_smp_message_recv(struct pt_regs *regs)
++{
++	int cpu = smp_processor_id();
++	int msg;
++
++	/* clear interrupt */
++	psurge_clr_ipi(cpu);
++
++	if (num_online_cpus() < 2)
++		return;
++
++	/* make sure there is a message there */
++	for (msg = 0; msg < 4; msg++)
++		if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
++			smp_message_recv(msg, regs);
++}
++
++irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
++{
++	psurge_smp_message_recv(regs);
++	return IRQ_HANDLED;
++}
++
++static void smp_psurge_message_pass(int target, int msg)
++{
++	int i;
++
++	if (num_online_cpus() < 2)
++		return;
++
++	for (i = 0; i < NR_CPUS; i++) {
++		if (!cpu_online(i))
++			continue;
++		if (target == MSG_ALL
++		    || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
++		    || target == i) {
++			set_bit(msg, &psurge_smp_message[i]);
++			psurge_set_ipi(i);
++		}
++	}
++}
++
++/*
++ * Determine a quad card presence. We read the board ID register, we
++ * force the data bus to change to something else, and we read it again.
++ * It it's stable, then the register probably exist (ugh !)
++ */
++static int __init psurge_quad_probe(void)
++{
++	int type;
++	unsigned int i;
++
++	type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
++	if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
++	    || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
++		return PSURGE_DUAL;
++
++	/* looks OK, try a slightly more rigorous test */
++	/* bogus is not necessarily cacheline-aligned,
++	   though I don't suppose that really matters.  -- paulus */
++	for (i = 0; i < 100; i++) {
++		volatile u32 bogus[8];
++		bogus[(0+i)%8] = 0x00000000;
++		bogus[(1+i)%8] = 0x55555555;
++		bogus[(2+i)%8] = 0xFFFFFFFF;
++		bogus[(3+i)%8] = 0xAAAAAAAA;
++		bogus[(4+i)%8] = 0x33333333;
++		bogus[(5+i)%8] = 0xCCCCCCCC;
++		bogus[(6+i)%8] = 0xCCCCCCCC;
++		bogus[(7+i)%8] = 0x33333333;
++		wmb();
++		asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
++		mb();
++		if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
++			return PSURGE_DUAL;
++	}
++	return type;
++}
++
++static void __init psurge_quad_init(void)
++{
++	int procbits;
++
++	if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
++	procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
++	if (psurge_type == PSURGE_QUAD_ICEGRASS)
++		PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
++	else
++		PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
++	mdelay(33);
++	out_8(psurge_sec_intr, ~0);
++	PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
++	PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
++	if (psurge_type != PSURGE_QUAD_ICEGRASS)
++		PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
++	PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
++	mdelay(33);
++	PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
++	mdelay(33);
++	PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
++	mdelay(33);
++}
++
++static int __init smp_psurge_probe(void)
++{
++	int i, ncpus;
++
++	/* We don't do SMP on the PPC601 -- paulus */
++	if (PVR_VER(mfspr(SPRN_PVR)) == 1)
++		return 1;
++
++	/*
++	 * The powersurge cpu board can be used in the generation
++	 * of powermacs that have a socket for an upgradeable cpu card,
++	 * including the 7500, 8500, 9500, 9600.
++	 * The device tree doesn't tell you if you have 2 cpus because
++	 * OF doesn't know anything about the 2nd processor.
++	 * Instead we look for magic bits in magic registers,
++	 * in the hammerhead memory controller in the case of the
++	 * dual-cpu powersurge board.  -- paulus.
++	 */
++	if (find_devices("hammerhead") == NULL)
++		return 1;
++
++	hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
++	quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
++	psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
++
++	psurge_type = psurge_quad_probe();
++	if (psurge_type != PSURGE_DUAL) {
++		psurge_quad_init();
++		/* All released cards using this HW design have 4 CPUs */
++		ncpus = 4;
++	} else {
++		iounmap(quad_base);
++		if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
++			/* not a dual-cpu card */
++			iounmap(hhead_base);
++			psurge_type = PSURGE_NONE;
++			return 1;
++		}
++		ncpus = 2;
++	}
++
++	psurge_start = ioremap(PSURGE_START, 4);
++	psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
++
++	/* this is not actually strictly necessary -- paulus. */
++	for (i = 1; i < ncpus; ++i)
++		smp_hw_index[i] = i;
++
++	if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
++
++	return ncpus;
++}
++
++static void __init smp_psurge_kick_cpu(int nr)
++{
++	unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
++	unsigned long a;
++
++	/* may need to flush here if secondary bats aren't setup */
++	for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
++		asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
++	asm volatile("sync");
++
++	if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
++
++	out_be32(psurge_start, start);
++	mb();
++
++	psurge_set_ipi(nr);
++	udelay(10);
++	psurge_clr_ipi(nr);
++
++	if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
++}
++
++/*
++ * With the dual-cpu powersurge board, the decrementers and timebases
++ * of both cpus are frozen after the secondary cpu is started up,
++ * until we give the secondary cpu another interrupt.  This routine
++ * uses this to get the timebases synchronized.
++ *  -- paulus.
++ */
++static void __init psurge_dual_sync_tb(int cpu_nr)
++{
++	int t;
++
++	set_dec(tb_ticks_per_jiffy);
++	set_tb(0, 0);
++	last_jiffy_stamp(cpu_nr) = 0;
++
++	if (cpu_nr > 0) {
++		mb();
++		sec_tb_reset = 1;
++		return;
++	}
++
++	/* wait for the secondary to have reset its TB before proceeding */
++	for (t = 10000000; t > 0 && !sec_tb_reset; --t)
++		;
++
++	/* now interrupt the secondary, starting both TBs */
++	psurge_set_ipi(1);
++
++	smp_tb_synchronized = 1;
++}
++
++static struct irqaction psurge_irqaction = {
++	.handler = psurge_primary_intr,
++	.flags = SA_INTERRUPT,
++	.mask = CPU_MASK_NONE,
++	.name = "primary IPI",
++};
++
++static void __init smp_psurge_setup_cpu(int cpu_nr)
++{
++
++	if (cpu_nr == 0) {
++		/* If we failed to start the second CPU, we should still
++		 * send it an IPI to start the timebase & DEC or we might
++		 * have them stuck.
++		 */
++		if (num_online_cpus() < 2) {
++			if (psurge_type == PSURGE_DUAL)
++				psurge_set_ipi(1);
++			return;
++		}
++		/* reset the entry point so if we get another intr we won't
++		 * try to startup again */
++		out_be32(psurge_start, 0x100);
++		if (setup_irq(30, &psurge_irqaction))
++			printk(KERN_ERR "Couldn't get primary IPI interrupt");
++	}
++
++	if (psurge_type == PSURGE_DUAL)
++		psurge_dual_sync_tb(cpu_nr);
++}
++
++void __init smp_psurge_take_timebase(void)
++{
++	/* Dummy implementation */
++}
++
++void __init smp_psurge_give_timebase(void)
++{
++	/* Dummy implementation */
++}
++
++/* PowerSurge-style Macs */
++struct smp_ops_t psurge_smp_ops = {
++	.message_pass	= smp_psurge_message_pass,
++	.probe		= smp_psurge_probe,
++	.kick_cpu	= smp_psurge_kick_cpu,
++	.setup_cpu	= smp_psurge_setup_cpu,
++	.give_timebase	= smp_psurge_give_timebase,
++	.take_timebase	= smp_psurge_take_timebase,
++};
++#endif /* CONFIG_PPC32 - actually powersurge support */
++
++#ifdef CONFIG_PPC64
++/*
++ * G5s enable/disable the timebase via an i2c-connected clock chip.
++ */
++static struct device_node *pmac_tb_clock_chip_host;
++static u8 pmac_tb_pulsar_addr;
++static void (*pmac_tb_freeze)(int freeze);
++static DEFINE_SPINLOCK(timebase_lock);
++static unsigned long timebase;
++
++static void smp_core99_cypress_tb_freeze(int freeze)
++{
++	u8 data;
++	int rc;
++
++	/* Strangely, the device-tree says address is 0xd2, but darwin
++	 * accesses 0xd0 ...
++	 */
++	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
++	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
++			       0xd0 | pmac_low_i2c_read,
++			       0x81, &data, 1);
++	if (rc != 0)
++		goto bail;
++
++	data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
++
++       	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
++	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
++			       0xd0 | pmac_low_i2c_write,
++			       0x81, &data, 1);
++
++ bail:
++	if (rc != 0) {
++		printk("Cypress Timebase %s rc: %d\n",
++		       freeze ? "freeze" : "unfreeze", rc);
++		panic("Timebase freeze failed !\n");
++	}
++}
++
++
++static void smp_core99_pulsar_tb_freeze(int freeze)
++{
++	u8 data;
++	int rc;
++
++	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
++	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
++			       pmac_tb_pulsar_addr | pmac_low_i2c_read,
++			       0x2e, &data, 1);
++	if (rc != 0)
++		goto bail;
++
++	data = (data & 0x88) | (freeze ? 0x11 : 0x22);
++
++	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
++	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
++			       pmac_tb_pulsar_addr | pmac_low_i2c_write,
++			       0x2e, &data, 1);
++ bail:
++	if (rc != 0) {
++		printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
++		       freeze ? "freeze" : "unfreeze", rc);
++		panic("Timebase freeze failed !\n");
++	}
++}
++
++
++static void smp_core99_give_timebase(void)
++{
++	/* Open i2c bus for synchronous access */
++	if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0))
++		panic("Can't open i2c for TB sync !\n");
++
++	spin_lock(&timebase_lock);
++	(*pmac_tb_freeze)(1);
++	mb();
++	timebase = get_tb();
++	spin_unlock(&timebase_lock);
++
++	while (timebase)
++		barrier();
++
++	spin_lock(&timebase_lock);
++	(*pmac_tb_freeze)(0);
++	spin_unlock(&timebase_lock);
++
++	/* Close i2c bus */
++	pmac_low_i2c_close(pmac_tb_clock_chip_host);
++}
++
++
++static void __devinit smp_core99_take_timebase(void)
++{
++	while (!timebase)
++		barrier();
++	spin_lock(&timebase_lock);
++	set_tb(timebase >> 32, timebase & 0xffffffff);
++	timebase = 0;
++	spin_unlock(&timebase_lock);
++}
++
++static void __init smp_core99_setup(int ncpus)
++{
++	struct device_node *cc = NULL;	
++	struct device_node *p;
++	u32 *reg;
++	int ok;
++
++	/* HW sync only on these platforms */
++	if (!machine_is_compatible("PowerMac7,2") &&
++	    !machine_is_compatible("PowerMac7,3") &&
++	    !machine_is_compatible("RackMac3,1"))
++		return;
++
++	/* Look for the clock chip */
++	while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) {
++		p = of_get_parent(cc);
++		ok = p && device_is_compatible(p, "uni-n-i2c");
++		of_node_put(p);
++		if (!ok)
++			continue;
++
++		reg = (u32 *)get_property(cc, "reg", NULL);
++		if (reg == NULL)
++			continue;
++
++		switch (*reg) {
++		case 0xd2:
++			if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
++				pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
++				pmac_tb_pulsar_addr = 0xd2;
++				printk(KERN_INFO "Timebase clock is Pulsar chip\n");
++			} else if (device_is_compatible(cc, "cy28508")) {
++				pmac_tb_freeze = smp_core99_cypress_tb_freeze;
++				printk(KERN_INFO "Timebase clock is Cypress chip\n");
++			}
++			break;
++		case 0xd4:
++			pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
++			pmac_tb_pulsar_addr = 0xd4;
++			printk(KERN_INFO "Timebase clock is Pulsar chip\n");
++			break;
++		}
++		if (pmac_tb_freeze != NULL) {
++			pmac_tb_clock_chip_host = of_get_parent(cc);
++			of_node_put(cc);
++			break;
++		}
++	}
++	if (pmac_tb_freeze == NULL) {
++		smp_ops->give_timebase = smp_generic_give_timebase;
++		smp_ops->take_timebase = smp_generic_take_timebase;
++	}
++}
++
++/* nothing to do here, caches are already set up by service processor */
++static inline void __devinit core99_init_caches(int cpu)
++{
++}
++
++#else /* CONFIG_PPC64 */
++
++/*
++ * SMP G4 powermacs use a GPIO to enable/disable the timebase.
++ */
++
++static unsigned int core99_tb_gpio;	/* Timebase freeze GPIO */
++
++static unsigned int pri_tb_hi, pri_tb_lo;
++static unsigned int pri_tb_stamp;
++
++/* not __init, called in sleep/wakeup code */
++void smp_core99_give_timebase(void)
++{
++	unsigned long flags;
++	unsigned int t;
++
++	/* wait for the secondary to be in take_timebase */
++	for (t = 100000; t > 0 && !sec_tb_reset; --t)
++		udelay(10);
++	if (!sec_tb_reset) {
++		printk(KERN_WARNING "Timeout waiting sync on second CPU\n");
++		return;
++	}
++
++	/* freeze the timebase and read it */
++	/* disable interrupts so the timebase is disabled for the
++	   shortest possible time */
++	local_irq_save(flags);
++	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
++	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
++	mb();
++	pri_tb_hi = get_tbu();
++	pri_tb_lo = get_tbl();
++	pri_tb_stamp = last_jiffy_stamp(smp_processor_id());
++	mb();
++
++	/* tell the secondary we're ready */
++	sec_tb_reset = 2;
++	mb();
++
++	/* wait for the secondary to have taken it */
++	for (t = 100000; t > 0 && sec_tb_reset; --t)
++		udelay(10);
++	if (sec_tb_reset)
++		printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
++	else
++		smp_tb_synchronized = 1;
++
++	/* Now, restart the timebase by leaving the GPIO to an open collector */
++       	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
++        pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
++	local_irq_restore(flags);
++}
++
++/* not __init, called in sleep/wakeup code */
++void smp_core99_take_timebase(void)
++{
++	unsigned long flags;
++
++	/* tell the primary we're here */
++	sec_tb_reset = 1;
++	mb();
++
++	/* wait for the primary to set pri_tb_hi/lo */
++	while (sec_tb_reset < 2)
++		mb();
++
++	/* set our stuff the same as the primary */
++	local_irq_save(flags);
++	set_dec(1);
++	set_tb(pri_tb_hi, pri_tb_lo);
++	last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp;
++	mb();
++
++	/* tell the primary we're done */
++       	sec_tb_reset = 0;
++	mb();
++	local_irq_restore(flags);
++}
++
++/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */
++volatile static long int core99_l2_cache;
++volatile static long int core99_l3_cache;
++
++static void __devinit core99_init_caches(int cpu)
++{
++	if (!cpu_has_feature(CPU_FTR_L2CR))
++		return;
++
++	if (cpu == 0) {
++		core99_l2_cache = _get_L2CR();
++		printk("CPU0: L2CR is %lx\n", core99_l2_cache);
++	} else {
++		printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
++		_set_L2CR(0);
++		_set_L2CR(core99_l2_cache);
++		printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
++	}
++
++	if (!cpu_has_feature(CPU_FTR_L3CR))
++		return;
++
++	if (cpu == 0){
++		core99_l3_cache = _get_L3CR();
++		printk("CPU0: L3CR is %lx\n", core99_l3_cache);
++	} else {
++		printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
++		_set_L3CR(0);
++		_set_L3CR(core99_l3_cache);
++		printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
++	}
++}
++
++static void __init smp_core99_setup(int ncpus)
++{
++	struct device_node *cpu;
++	u32 *tbprop = NULL;
++	int i;
++
++	core99_tb_gpio = KL_GPIO_TB_ENABLE;	/* default value */
++	cpu = of_find_node_by_type(NULL, "cpu");
++	if (cpu != NULL) {
++		tbprop = (u32 *)get_property(cpu, "timebase-enable", NULL);
++		if (tbprop)
++			core99_tb_gpio = *tbprop;
++		of_node_put(cpu);
++	}
++
++	/* XXX should get this from reg properties */
++	for (i = 1; i < ncpus; ++i)
++		smp_hw_index[i] = i;
++	powersave_nap = 0;
++}
++#endif
++
++static int __init smp_core99_probe(void)
++{
++	struct device_node *cpus;
++	int ncpus = 0;
++
++	if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
++
++	/* Count CPUs in the device-tree */
++       	for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;)
++	       	++ncpus;
++
++	printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
++
++	/* Nothing more to do if less than 2 of them */
++	if (ncpus <= 1)
++		return 1;
++
++	smp_core99_setup(ncpus);
++	mpic_request_ipis();
++	core99_init_caches(0);
++
++	return ncpus;
++}
++
++static void __devinit smp_core99_kick_cpu(int nr)
++{
++	unsigned int save_vector;
++	unsigned long new_vector;
++	unsigned long flags;
++	volatile unsigned int *vector
++		 = ((volatile unsigned int *)(KERNELBASE+0x100));
++
++	if (nr < 0 || nr > 3)
++		return;
++	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
++
++	local_irq_save(flags);
++	local_irq_disable();
++
++	/* Save reset vector */
++	save_vector = *vector;
++
++	/* Setup fake reset vector that does	
++	 *   b __secondary_start_pmac_0 + nr*8 - KERNELBASE
++	 */
++	new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8;
++	*vector = 0x48000002 + new_vector - KERNELBASE;
++
++	/* flush data cache and inval instruction cache */
++	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
++
++	/* Put some life in our friend */
++	pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
++
++	/* FIXME: We wait a bit for the CPU to take the exception, I should
++	 * instead wait for the entry code to set something for me. Well,
++	 * ideally, all that crap will be done in prom.c and the CPU left
++	 * in a RAM-based wait loop like CHRP.
++	 */
++	mdelay(1);
++
++	/* Restore our exception vector */
++	*vector = save_vector;
++	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
++
++	local_irq_restore(flags);
++	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
++}
++
++static void __devinit smp_core99_setup_cpu(int cpu_nr)
++{
++	/* Setup L2/L3 */
++	if (cpu_nr != 0)
++		core99_init_caches(cpu_nr);
++
++	/* Setup openpic */
++	mpic_setup_this_cpu();
++
++	if (cpu_nr == 0) {
++#ifdef CONFIG_POWER4
++		extern void g5_phy_disable_cpu1(void);
++
++		/* If we didn't start the second CPU, we must take
++		 * it off the bus
++		 */
++		if (machine_is_compatible("MacRISC4") &&
++		    num_online_cpus() < 2)		
++			g5_phy_disable_cpu1();
++#endif /* CONFIG_POWER4 */
++		if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
++	}
++}
++
++
++/* Core99 Macs (dual G4s and G5s) */
++struct smp_ops_t core99_smp_ops = {
++	.message_pass	= smp_mpic_message_pass,
++	.probe		= smp_core99_probe,
++	.kick_cpu	= smp_core99_kick_cpu,
++	.setup_cpu	= smp_core99_setup_cpu,
++	.give_timebase	= smp_core99_give_timebase,
++	.take_timebase	= smp_core99_take_timebase,
++};
++
++#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
++
++int __cpu_disable(void)
++{
++	cpu_clear(smp_processor_id(), cpu_online_map);
++
++	/* XXX reset cpu affinity here */
++	mpic_cpu_set_priority(0xf);
++	asm volatile("mtdec %0" : : "r" (0x7fffffff));
++	mb();
++	udelay(20);
++	asm volatile("mtdec %0" : : "r" (0x7fffffff));
++	return 0;
++}
++
++extern void low_cpu_die(void) __attribute__((noreturn)); /* in sleep.S */
++static int cpu_dead[NR_CPUS];
++
++void cpu_die(void)
++{
++	local_irq_disable();
++	cpu_dead[smp_processor_id()] = 1;
++	mb();
++	low_cpu_die();
++}
++
++void __cpu_die(unsigned int cpu)
++{
++	int timeout;
++
++	timeout = 1000;
++	while (!cpu_dead[cpu]) {
++		if (--timeout == 0) {
++			printk("CPU %u refused to die!\n", cpu);
++			break;
++		}
++		msleep(1);
++	}
++	cpu_callin_map[cpu] = 0;
++	cpu_dead[cpu] = 0;
++}
++
++#endif
+diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/powermac/time.c
+@@ -0,0 +1,360 @@
++/*
++ * Support for periodic interrupts (100 per second) and for getting
++ * the current time from the RTC on Power Macintoshes.
++ *
++ * We use the decrementer register for our periodic interrupts.
++ *
++ * Paul Mackerras	August 1996.
++ * Copyright (C) 1996 Paul Mackerras.
++ * Copyright (C) 2003-2005 Benjamin Herrenschmidt.
++ *
++ */
++#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/param.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/time.h>
++#include <linux/adb.h>
++#include <linux/cuda.h>
++#include <linux/pmu.h>
++#include <linux/interrupt.h>
++#include <linux/hardirq.h>
++#include <linux/rtc.h>
++
++#include <asm/sections.h>
++#include <asm/prom.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/machdep.h>
++#include <asm/time.h>
++#include <asm/nvram.h>
++#include <asm/smu.h>
++
++#undef DEBUG
++
++#ifdef DEBUG
++#define DBG(x...) printk(x)
++#else
++#define DBG(x...)
++#endif
++
++/* Apparently the RTC stores seconds since 1 Jan 1904 */
++#define RTC_OFFSET	2082844800
++
++/*
++ * Calibrate the decrementer frequency with the VIA timer 1.
++ */
++#define VIA_TIMER_FREQ_6	4700000	/* time 1 frequency * 6 */
++
++/* VIA registers */
++#define RS		0x200		/* skip between registers */
++#define T1CL		(4*RS)		/* Timer 1 ctr/latch (low 8 bits) */
++#define T1CH		(5*RS)		/* Timer 1 counter (high 8 bits) */
++#define T1LL		(6*RS)		/* Timer 1 latch (low 8 bits) */
++#define T1LH		(7*RS)		/* Timer 1 latch (high 8 bits) */
++#define ACR		(11*RS)		/* Auxiliary control register */
++#define IFR		(13*RS)		/* Interrupt flag register */
++
++/* Bits in ACR */
++#define T1MODE		0xc0		/* Timer 1 mode */
++#define T1MODE_CONT	0x40		/*  continuous interrupts */
++
++/* Bits in IFR and IER */
++#define T1_INT		0x40		/* Timer 1 interrupt */
++
++long __init pmac_time_init(void)
++{
++	s32 delta = 0;
++#ifdef CONFIG_NVRAM
++	int dst;
++	
++	delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
++	delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
++	delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
++	if (delta & 0x00800000UL)
++		delta |= 0xFF000000UL;
++	dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
++	printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
++		dst ? "on" : "off");
++#endif
++	return delta;
++}
++
++static void to_rtc_time(unsigned long now, struct rtc_time *tm)
++{
++	to_tm(now, tm);
++	tm->tm_year -= 1900;
++	tm->tm_mon -= 1;
++}
++
++static unsigned long from_rtc_time(struct rtc_time *tm)
++{
++	return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
++		      tm->tm_hour, tm->tm_min, tm->tm_sec);
++}
++
++#ifdef CONFIG_ADB_CUDA
++static unsigned long cuda_get_time(void)
++{
++	struct adb_request req;
++	unsigned long now;
++
++	if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
++		return 0;
++	while (!req.complete)
++		cuda_poll();
++	if (req.reply_len != 7)
++		printk(KERN_ERR "cuda_get_time: got %d byte reply\n",
++		       req.reply_len);
++	now = (req.reply[3] << 24) + (req.reply[4] << 16)
++		+ (req.reply[5] << 8) + req.reply[6];
++	return now - RTC_OFFSET;
++}
++
++#define cuda_get_rtc_time(tm)	to_rtc_time(cuda_get_time(), (tm))
++
++static int cuda_set_rtc_time(struct rtc_time *tm)
++{
++	unsigned int nowtime;
++	struct adb_request req;
++
++	nowtime = from_rtc_time(tm) + RTC_OFFSET;
++	if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
++			 nowtime >> 24, nowtime >> 16, nowtime >> 8,
++			 nowtime) < 0)
++		return -ENXIO;
++	while (!req.complete)
++		cuda_poll();
++	if ((req.reply_len != 3) && (req.reply_len != 7))
++		printk(KERN_ERR "cuda_set_rtc_time: got %d byte reply\n",
++		       req.reply_len);
++	return 0;
++}
++
++#else
++#define cuda_get_time()		0
++#define cuda_get_rtc_time(tm)
++#define cuda_set_rtc_time(tm)	0
++#endif
++
++#ifdef CONFIG_ADB_PMU
++static unsigned long pmu_get_time(void)
++{
++	struct adb_request req;
++	unsigned long now;
++
++	if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
++		return 0;
++	pmu_wait_complete(&req);
++	if (req.reply_len != 4)
++		printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n",
++		       req.reply_len);
++	now = (req.reply[0] << 24) + (req.reply[1] << 16)
++		+ (req.reply[2] << 8) + req.reply[3];
++	return now - RTC_OFFSET;
++}
++
++#define pmu_get_rtc_time(tm)	to_rtc_time(pmu_get_time(), (tm))
++
++static int pmu_set_rtc_time(struct rtc_time *tm)
++{
++	unsigned int nowtime;
++	struct adb_request req;
++
++	nowtime = from_rtc_time(tm) + RTC_OFFSET;
++	if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24,
++			nowtime >> 16, nowtime >> 8, nowtime) < 0)
++		return -ENXIO;
++	pmu_wait_complete(&req);
++	if (req.reply_len != 0)
++		printk(KERN_ERR "pmu_set_rtc_time: %d byte reply from PMU\n",
++		       req.reply_len);
++	return 0;
++}
++
++#else
++#define pmu_get_time()		0
++#define pmu_get_rtc_time(tm)
++#define pmu_set_rtc_time(tm)	0
++#endif
++
++#ifdef CONFIG_PMAC_SMU
++static unsigned long smu_get_time(void)
++{
++	struct rtc_time tm;
++
++	if (smu_get_rtc_time(&tm, 1))
++		return 0;
++	return from_rtc_time(&tm);
++}
++
++#else
++#define smu_get_time()			0
++#define smu_get_rtc_time(tm, spin)
++#define smu_set_rtc_time(tm, spin)	0
++#endif
++
++unsigned long pmac_get_boot_time(void)
++{
++	/* Get the time from the RTC, used only at boot time */
++	switch (sys_ctrler) {
++	case SYS_CTRLER_CUDA:
++		return cuda_get_time();
++	case SYS_CTRLER_PMU:
++		return pmu_get_time();
++	case SYS_CTRLER_SMU:
++		return smu_get_time();
++	default:
++		return 0;
++	}
++}
++
++void pmac_get_rtc_time(struct rtc_time *tm)
++{
++	/* Get the time from the RTC, used only at boot time */
++	switch (sys_ctrler) {
++	case SYS_CTRLER_CUDA:
++		cuda_get_rtc_time(tm);
++		break;
++	case SYS_CTRLER_PMU:
++		pmu_get_rtc_time(tm);
++		break;
++	case SYS_CTRLER_SMU:
++		smu_get_rtc_time(tm, 1);
++		break;
++	default:
++		;
++	}
++}
++
++int pmac_set_rtc_time(struct rtc_time *tm)
++{
++	switch (sys_ctrler) {
++	case SYS_CTRLER_CUDA:
++		return cuda_set_rtc_time(tm);
++	case SYS_CTRLER_PMU:
++		return pmu_set_rtc_time(tm);
++	case SYS_CTRLER_SMU:
++		return smu_set_rtc_time(tm, 1);
++	default:
++		return -ENODEV;
++	}
++}
++
++#ifdef CONFIG_PPC32
++/*
++ * Calibrate the decrementer register using VIA timer 1.
++ * This is used both on powermacs and CHRP machines.
++ */
++int __init via_calibrate_decr(void)
++{
++	struct device_node *vias;
++	volatile unsigned char __iomem *via;
++	int count = VIA_TIMER_FREQ_6 / 100;
++	unsigned int dstart, dend;
++
++	vias = find_devices("via-cuda");
++	if (vias == 0)
++		vias = find_devices("via-pmu");
++	if (vias == 0)
++		vias = find_devices("via");
++	if (vias == 0 || vias->n_addrs == 0)
++		return 0;
++	via = ioremap(vias->addrs[0].address, vias->addrs[0].size);
++
++	/* set timer 1 for continuous interrupts */
++	out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
++	/* set the counter to a small value */
++	out_8(&via[T1CH], 2);
++	/* set the latch to `count' */
++	out_8(&via[T1LL], count);
++	out_8(&via[T1LH], count >> 8);
++	/* wait until it hits 0 */
++	while ((in_8(&via[IFR]) & T1_INT) == 0)
++		;
++	dstart = get_dec();
++	/* clear the interrupt & wait until it hits 0 again */
++	in_8(&via[T1CL]);
++	while ((in_8(&via[IFR]) & T1_INT) == 0)
++		;
++	dend = get_dec();
++
++	ppc_tb_freq = (dstart - dend) * 100 / 6;
++
++	iounmap(via);
++	
++	return 1;
++}
++#endif
++
++#ifdef CONFIG_PM
++/*
++ * Reset the time after a sleep.
++ */
++static int
++time_sleep_notify(struct pmu_sleep_notifier *self, int when)
++{
++	static unsigned long time_diff;
++	unsigned long flags;
++	unsigned long seq;
++	struct timespec tv;
++
++	switch (when) {
++	case PBOOK_SLEEP_NOW:
++		do {
++			seq = read_seqbegin_irqsave(&xtime_lock, flags);
++			time_diff = xtime.tv_sec - pmac_get_boot_time();
++		} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
++		break;
++	case PBOOK_WAKE:
++		tv.tv_sec = pmac_get_boot_time() + time_diff;
++		tv.tv_nsec = 0;
++		do_settimeofday(&tv);
++		break;
++	}
++	return PBOOK_SLEEP_OK;
++}
++
++static struct pmu_sleep_notifier time_sleep_notifier = {
++	time_sleep_notify, SLEEP_LEVEL_MISC,
++};
++#endif /* CONFIG_PM */
++
++/*
++ * Query the OF and get the decr frequency.
++ */
++void __init pmac_calibrate_decr(void)
++{
++#ifdef CONFIG_PM
++	/* XXX why here? */
++	pmu_register_sleep_notifier(&time_sleep_notifier);
++#endif /* CONFIG_PM */
++
++	generic_calibrate_decr();
++
++#ifdef CONFIG_PPC32
++	/* We assume MacRISC2 machines have correct device-tree
++	 * calibration. That's better since the VIA itself seems
++	 * to be slightly off. --BenH
++	 */
++	if (!machine_is_compatible("MacRISC2") &&
++	    !machine_is_compatible("MacRISC3") &&
++	    !machine_is_compatible("MacRISC4"))
++		if (via_calibrate_decr())
++			return;
++
++	/* Special case: QuickSilver G4s seem to have a badly calibrated
++	 * timebase-frequency in OF, VIA is much better on these. We should
++	 * probably implement calibration based on the KL timer on these
++	 * machines anyway... -BenH
++	 */
++	if (machine_is_compatible("PowerMac3,5"))
++		if (via_calibrate_decr())
++			return;
++#endif
++}
+diff --git a/arch/powerpc/platforms/prep/Kconfig b/arch/powerpc/platforms/prep/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/prep/Kconfig
+@@ -0,0 +1,22 @@
++
++config PREP_RESIDUAL
++	bool "Support for PReP Residual Data"
++	depends on PPC_PREP
++	help
++	  Some PReP systems have residual data passed to the kernel by the
++	  firmware.  This allows detection of memory size, devices present and
++	  other useful pieces of information.  Sometimes this information is
++	  not present or incorrect, in which case it could lead to the machine 
++	  behaving incorrectly.  If this happens, either disable PREP_RESIDUAL
++	  or pass the 'noresidual' option to the kernel.
++
++	  If you are running a PReP system, say Y here, otherwise say N.
++
++config PROC_PREPRESIDUAL
++	bool "Support for reading of PReP Residual Data in /proc"
++	depends on PREP_RESIDUAL && PROC_FS
++	help
++	  Enabling this option will create a /proc/residual file which allows
++	  you to get at the residual data on PReP systems.  You will need a tool
++	  (lsresidual) to parse it.  If you aren't on a PReP system, you don't
++	  want this.
+diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/Kconfig
+@@ -0,0 +1,42 @@
++
++config PPC_SPLPAR
++	depends on PPC_PSERIES
++	bool "Support for shared-processor logical partitions"
++	default n
++	help
++	  Enabling this option will make the kernel run more efficiently
++	  on logically-partitioned pSeries systems which use shared
++	  processors, that is, which share physical processors between
++	  two or more partitions.
++
++config HMT
++	bool "Hardware multithreading"
++	depends on SMP && PPC_PSERIES && BROKEN
++	help
++	  This option enables hardware multithreading on RS64 cpus.
++	  pSeries systems p620 and p660 have such a cpu type.
++
++config EEH
++	bool "PCI Extended Error Handling (EEH)" if EMBEDDED
++	depends on PPC_PSERIES
++	default y if !EMBEDDED
++
++config RTAS_PROC
++	bool "Proc interface to RTAS"
++	depends on PPC_RTAS
++	default y
++
++config RTAS_FLASH
++	tristate "Firmware flash interface"
++	depends on PPC64 && RTAS_PROC
++
++config SCANLOG
++	tristate "Scanlog dump interface"
++	depends on RTAS_PROC && PPC_PSERIES
++
++config LPARCFG
++	tristate "LPAR Configuration Data"
++	depends on PPC_PSERIES || PPC_ISERIES
++	help
++	Provide system capacity information via human readable
++	<key word>=<value> pairs through a /proc/ppc64/lparcfg interface.
+diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/Makefile
+@@ -0,0 +1,5 @@
++obj-y			:= pci.o lpar.o hvCall.o nvram.o reconfig.o \
++			   setup.o iommu.o rtas-fw.o ras.o
++obj-$(CONFIG_SMP)	+= smp.o
++obj-$(CONFIG_IBMVIO)	+= vio.o
++obj-$(CONFIG_XICS)	+= xics.o
+diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/hvCall.S
+@@ -0,0 +1,131 @@
++/*
++ * arch/ppc64/kernel/pSeries_hvCall.S
++ *
++ * This file contains the generic code to perform a call to the
++ * pSeries LPAR hypervisor.
++ * NOTE: this file will go away when we move to inline this work.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/hvcall.h>
++#include <asm/processor.h>
++#include <asm/ppc_asm.h>
++	
++#define STK_PARM(i)     (48 + ((i)-3)*8)
++
++	.text
++
++/* long plpar_hcall(unsigned long opcode,		R3
++			unsigned long arg1,		R4
++			unsigned long arg2,		R5
++			unsigned long arg3,		R6
++			unsigned long arg4,		R7
++			unsigned long *out1,		R8
++			unsigned long *out2,		R9
++			unsigned long *out3);		R10
++ */
++_GLOBAL(plpar_hcall)
++	HMT_MEDIUM
++
++	mfcr	r0
++
++	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
++	std	r9,STK_PARM(r9)(r1)
++	std	r10,STK_PARM(r10)(r1)
++
++	stw	r0,8(r1)
++
++	HVSC				/* invoke the hypervisor */
++
++	lwz	r0,8(r1)
++
++	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r6 ret args */
++	ld	r9,STK_PARM(r9)(r1)
++	ld	r10,STK_PARM(r10)(r1)
++	std	r4,0(r8)
++	std	r5,0(r9)
++	std	r6,0(r10)
++
++	mtcrf	0xff,r0
++	blr				/* return r3 = status */
++
++
++/* Simple interface with no output values (other than status) */
++_GLOBAL(plpar_hcall_norets)
++	HMT_MEDIUM
++
++	mfcr	r0
++	stw	r0,8(r1)
++
++	HVSC				/* invoke the hypervisor */
++
++	lwz	r0,8(r1)
++	mtcrf	0xff,r0
++	blr				/* return r3 = status */
++
++
++/* long plpar_hcall_8arg_2ret(unsigned long opcode,	R3
++			unsigned long arg1,		R4
++			unsigned long arg2,		R5
++			unsigned long arg3,		R6
++			unsigned long arg4,		R7
++			unsigned long arg5,		R8
++			unsigned long arg6,		R9
++			unsigned long arg7,		R10
++			unsigned long arg8,		112(R1)
++			unsigned long *out1);		120(R1)
++ */
++_GLOBAL(plpar_hcall_8arg_2ret)
++	HMT_MEDIUM
++
++	mfcr	r0
++	ld	r11,STK_PARM(r11)(r1)	/* put arg8 in R11 */
++	stw	r0,8(r1)
++
++	HVSC				/* invoke the hypervisor */
++
++	lwz	r0,8(r1)
++	ld	r10,STK_PARM(r12)(r1)	/* Fetch r4 ret arg */
++	std	r4,0(r10)
++	mtcrf	0xff,r0
++	blr				/* return r3 = status */
++
++
++/* long plpar_hcall_4out(unsigned long opcode,		R3
++		 	unsigned long arg1,		R4
++		 	unsigned long arg2,		R5
++		 	unsigned long arg3,		R6
++		 	unsigned long arg4,		R7
++		 	unsigned long *out1,		R8
++		 	unsigned long *out2,		R9
++		 	unsigned long *out3,		R10
++		 	unsigned long *out4);		112(R1)
++ */
++_GLOBAL(plpar_hcall_4out)
++	HMT_MEDIUM
++
++	mfcr	r0
++	stw	r0,8(r1)
++
++	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
++	std	r9,STK_PARM(r9)(r1)
++	std	r10,STK_PARM(r10)(r1)
++
++	HVSC				/* invoke the hypervisor */
++
++	lwz	r0,8(r1)
++
++	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r7 ret args */
++	ld	r9,STK_PARM(r9)(r1)
++	ld	r10,STK_PARM(r10)(r1)
++	ld	r11,STK_PARM(r11)(r1)
++	std	r4,0(r8)
++	std	r5,0(r9)
++	std	r6,0(r10)
++	std	r7,0(r11)
++
++	mtcrf	0xff,r0
++	blr				/* return r3 = status */
+diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/iommu.c
+@@ -0,0 +1,606 @@
++/*
++ * arch/ppc64/kernel/pSeries_iommu.c
++ *
++ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
++ *
++ * Rewrite, cleanup: 
++ *
++ * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, IBM Corporation
++ *
++ * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR.
++ *
++ * 
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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/config.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/pci.h>
++#include <linux/dma-mapping.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/rtas.h>
++#include <asm/ppcdebug.h>
++#include <asm/iommu.h>
++#include <asm/pci-bridge.h>
++#include <asm/machdep.h>
++#include <asm/abs_addr.h>
++#include <asm/plpar_wrappers.h>
++#include <asm/pSeries_reconfig.h>
++#include <asm/systemcfg.h>
++#include <asm/firmware.h>
++#include <asm/tce.h>
++#include <asm/ppc-pci.h>
++
++#define DBG(fmt...)
++
++extern int is_python(struct device_node *);
++
++static void tce_build_pSeries(struct iommu_table *tbl, long index, 
++			      long npages, unsigned long uaddr, 
++			      enum dma_data_direction direction)
++{
++	union tce_entry t;
++	union tce_entry *tp;
++
++	index <<= TCE_PAGE_FACTOR;
++	npages <<= TCE_PAGE_FACTOR;
++
++	t.te_word = 0;
++	t.te_rdwr = 1; // Read allowed 
++
++	if (direction != DMA_TO_DEVICE)
++		t.te_pciwr = 1;
++
++	tp = ((union tce_entry *)tbl->it_base) + index;
++
++	while (npages--) {
++		/* can't move this out since we might cross LMB boundary */
++		t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
++	
++		tp->te_word = t.te_word;
++
++		uaddr += TCE_PAGE_SIZE;
++		tp++;
++	}
++}
++
++
++static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
++{
++	union tce_entry t;
++	union tce_entry *tp;
++
++	npages <<= TCE_PAGE_FACTOR;
++	index <<= TCE_PAGE_FACTOR;
++
++	t.te_word = 0;
++	tp  = ((union tce_entry *)tbl->it_base) + index;
++		
++	while (npages--) {
++		tp->te_word = t.te_word;
++		
++		tp++;
++	}
++}
++
++
++static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
++				long npages, unsigned long uaddr,
++				enum dma_data_direction direction)
++{
++	u64 rc;
++	union tce_entry tce;
++
++	tce.te_word = 0;
++	tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
++	tce.te_rdwr = 1;
++	if (direction != DMA_TO_DEVICE)
++		tce.te_pciwr = 1;
++
++	while (npages--) {
++		rc = plpar_tce_put((u64)tbl->it_index, 
++				   (u64)tcenum << 12, 
++				   tce.te_word );
++		
++		if (rc && printk_ratelimit()) {
++			printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
++			printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
++			printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
++			printk("\ttce val = 0x%lx\n", tce.te_word );
++			show_stack(current, (unsigned long *)__get_SP());
++		}
++			
++		tcenum++;
++		tce.te_rpn++;
++	}
++}
++
++static DEFINE_PER_CPU(void *, tce_page) = NULL;
++
++static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
++				     long npages, unsigned long uaddr,
++				     enum dma_data_direction direction)
++{
++	u64 rc;
++	union tce_entry tce, *tcep;
++	long l, limit;
++
++	tcenum <<= TCE_PAGE_FACTOR;
++	npages <<= TCE_PAGE_FACTOR;
++
++	if (npages == 1)
++		return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
++					   direction);
++
++	tcep = __get_cpu_var(tce_page);
++
++	/* This is safe to do since interrupts are off when we're called
++	 * from iommu_alloc{,_sg}()
++	 */
++	if (!tcep) {
++		tcep = (void *)__get_free_page(GFP_ATOMIC);
++		/* If allocation fails, fall back to the loop implementation */
++		if (!tcep)
++			return tce_build_pSeriesLP(tbl, tcenum, npages,
++						   uaddr, direction);
++		__get_cpu_var(tce_page) = tcep;
++	}
++
++	tce.te_word = 0;
++	tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
++	tce.te_rdwr = 1;
++	if (direction != DMA_TO_DEVICE)
++		tce.te_pciwr = 1;
++
++	/* We can map max one pageful of TCEs at a time */
++	do {
++		/*
++		 * Set up the page with TCE data, looping through and setting
++		 * the values.
++		 */
++		limit = min_t(long, npages, 4096/sizeof(union tce_entry));
++
++		for (l = 0; l < limit; l++) {
++			tcep[l] = tce;
++			tce.te_rpn++;
++		}
++
++		rc = plpar_tce_put_indirect((u64)tbl->it_index,
++					    (u64)tcenum << 12,
++					    (u64)virt_to_abs(tcep),
++					    limit);
++
++		npages -= limit;
++		tcenum += limit;
++	} while (npages > 0 && !rc);
++
++	if (rc && printk_ratelimit()) {
++		printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
++		printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
++		printk("\tnpages  = 0x%lx\n", (u64)npages);
++		printk("\ttce[0] val = 0x%lx\n", tcep[0].te_word);
++		show_stack(current, (unsigned long *)__get_SP());
++	}
++}
++
++static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
++{
++	u64 rc;
++	union tce_entry tce;
++
++	tcenum <<= TCE_PAGE_FACTOR;
++	npages <<= TCE_PAGE_FACTOR;
++
++	tce.te_word = 0;
++
++	while (npages--) {
++		rc = plpar_tce_put((u64)tbl->it_index,
++				   (u64)tcenum << 12,
++				   tce.te_word);
++
++		if (rc && printk_ratelimit()) {
++			printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
++			printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
++			printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
++			printk("\ttce val = 0x%lx\n", tce.te_word );
++			show_stack(current, (unsigned long *)__get_SP());
++		}
++
++		tcenum++;
++	}
++}
++
++
++static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
++{
++	u64 rc;
++	union tce_entry tce;
++
++	tcenum <<= TCE_PAGE_FACTOR;
++	npages <<= TCE_PAGE_FACTOR;
++
++	tce.te_word = 0;
++
++	rc = plpar_tce_stuff((u64)tbl->it_index,
++			   (u64)tcenum << 12,
++			   tce.te_word,
++			   npages);
++
++	if (rc && printk_ratelimit()) {
++		printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n");
++		printk("\trc      = %ld\n", rc);
++		printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
++		printk("\tnpages  = 0x%lx\n", (u64)npages);
++		printk("\ttce val = 0x%lx\n", tce.te_word );
++		show_stack(current, (unsigned long *)__get_SP());
++	}
++}
++
++static void iommu_table_setparms(struct pci_controller *phb,
++				 struct device_node *dn,
++				 struct iommu_table *tbl) 
++{
++	struct device_node *node;
++	unsigned long *basep;
++	unsigned int *sizep;
++
++	node = (struct device_node *)phb->arch_data;
++
++	basep = (unsigned long *)get_property(node, "linux,tce-base", NULL);
++	sizep = (unsigned int *)get_property(node, "linux,tce-size", NULL);
++	if (basep == NULL || sizep == NULL) {
++		printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has "
++				"missing tce entries !\n", dn->full_name);
++		return;
++	}
++
++	tbl->it_base = (unsigned long)__va(*basep);
++	memset((void *)tbl->it_base, 0, *sizep);
++
++	tbl->it_busno = phb->bus->number;
++	
++	/* Units of tce entries */
++	tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
++	
++	/* Test if we are going over 2GB of DMA space */
++	if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
++		udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
++		panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 
++	}
++	
++	phb->dma_window_base_cur += phb->dma_window_size;
++
++	/* Set the tce table size - measured in entries */
++	tbl->it_size = phb->dma_window_size >> PAGE_SHIFT;
++
++	tbl->it_index = 0;
++	tbl->it_blocksize = 16;
++	tbl->it_type = TCE_PCI;
++}
++
++/*
++ * iommu_table_setparms_lpar
++ *
++ * Function: On pSeries LPAR systems, return TCE table info, given a pci bus.
++ *
++ * ToDo: properly interpret the ibm,dma-window property.  The definition is:
++ *	logical-bus-number	(1 word)
++ *	phys-address		(#address-cells words)
++ *	size			(#cell-size words)
++ *
++ * Currently we hard code these sizes (more or less).
++ */
++static void iommu_table_setparms_lpar(struct pci_controller *phb,
++				      struct device_node *dn,
++				      struct iommu_table *tbl,
++				      unsigned int *dma_window)
++{
++	tbl->it_busno  = PCI_DN(dn)->bussubno;
++
++	/* TODO: Parse field size properties properly. */
++	tbl->it_size   = (((unsigned long)dma_window[4] << 32) |
++			   (unsigned long)dma_window[5]) >> PAGE_SHIFT;
++	tbl->it_offset = (((unsigned long)dma_window[2] << 32) |
++			   (unsigned long)dma_window[3]) >> PAGE_SHIFT;
++	tbl->it_base   = 0;
++	tbl->it_index  = dma_window[0];
++	tbl->it_blocksize  = 16;
++	tbl->it_type = TCE_PCI;
++}
++
++static void iommu_bus_setup_pSeries(struct pci_bus *bus)
++{
++	struct device_node *dn;
++	struct iommu_table *tbl;
++	struct device_node *isa_dn, *isa_dn_orig;
++	struct device_node *tmp;
++	struct pci_dn *pci;
++	int children;
++
++	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
++
++	dn = pci_bus_to_OF_node(bus);
++	pci = PCI_DN(dn);
++
++	if (bus->self) {
++		/* This is not a root bus, any setup will be done for the
++		 * device-side of the bridge in iommu_dev_setup_pSeries().
++		 */
++		return;
++	}
++
++	/* Check if the ISA bus on the system is under
++	 * this PHB.
++	 */
++	isa_dn = isa_dn_orig = of_find_node_by_type(NULL, "isa");
++
++	while (isa_dn && isa_dn != dn)
++		isa_dn = isa_dn->parent;
++
++	if (isa_dn_orig)
++		of_node_put(isa_dn_orig);
++
++	/* Count number of direct PCI children of the PHB.
++	 * All PCI device nodes have class-code property, so it's
++	 * an easy way to find them.
++	 */
++	for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
++		if (get_property(tmp, "class-code", NULL))
++			children++;
++
++	DBG("Children: %d\n", children);
++
++	/* Calculate amount of DMA window per slot. Each window must be
++	 * a power of two (due to pci_alloc_consistent requirements).
++	 *
++	 * Keep 256MB aside for PHBs with ISA.
++	 */
++
++	if (!isa_dn) {
++		/* No ISA/IDE - just set window size and return */
++		pci->phb->dma_window_size = 0x80000000ul; /* To be divided */
++
++		while (pci->phb->dma_window_size * children > 0x80000000ul)
++			pci->phb->dma_window_size >>= 1;
++		DBG("No ISA/IDE, window size is 0x%lx\n",
++			pci->phb->dma_window_size);
++		pci->phb->dma_window_base_cur = 0;
++
++		return;
++	}
++
++	/* If we have ISA, then we probably have an IDE
++	 * controller too. Allocate a 128MB table but
++	 * skip the first 128MB to avoid stepping on ISA
++	 * space.
++	 */
++	pci->phb->dma_window_size = 0x8000000ul;
++	pci->phb->dma_window_base_cur = 0x8000000ul;
++
++	tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
++
++	iommu_table_setparms(pci->phb, dn, tbl);
++	pci->iommu_table = iommu_init_table(tbl);
++
++	/* Divide the rest (1.75GB) among the children */
++	pci->phb->dma_window_size = 0x80000000ul;
++	while (pci->phb->dma_window_size * children > 0x70000000ul)
++		pci->phb->dma_window_size >>= 1;
++
++	DBG("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);
++
++}
++
++
++static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
++{
++	struct iommu_table *tbl;
++	struct device_node *dn, *pdn;
++	struct pci_dn *ppci;
++	unsigned int *dma_window = NULL;
++
++	DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
++
++	dn = pci_bus_to_OF_node(bus);
++
++	/* Find nearest ibm,dma-window, walking up the device tree */
++	for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
++		dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
++		if (dma_window != NULL)
++			break;
++	}
++
++	if (dma_window == NULL) {
++		DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name);
++		return;
++	}
++
++	ppci = pdn->data;
++	if (!ppci->iommu_table) {
++		/* Bussubno hasn't been copied yet.
++		 * Do it now because iommu_table_setparms_lpar needs it.
++		 */
++
++		ppci->bussubno = bus->number;
++
++		tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
++						    GFP_KERNEL);
++	
++		iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
++
++		ppci->iommu_table = iommu_init_table(tbl);
++	}
++
++	if (pdn != dn)
++		PCI_DN(dn)->iommu_table = ppci->iommu_table;
++}
++
++
++static void iommu_dev_setup_pSeries(struct pci_dev *dev)
++{
++	struct device_node *dn, *mydn;
++	struct iommu_table *tbl;
++
++	DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev));
++
++	mydn = dn = pci_device_to_OF_node(dev);
++
++	/* If we're the direct child of a root bus, then we need to allocate
++	 * an iommu table ourselves. The bus setup code should have setup
++	 * the window sizes already.
++	 */
++	if (!dev->bus->self) {
++		DBG(" --> first child, no bridge. Allocating iommu table.\n");
++		tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
++		iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
++		PCI_DN(mydn)->iommu_table = iommu_init_table(tbl);
++
++		return;
++	}
++
++	/* If this device is further down the bus tree, search upwards until
++	 * an already allocated iommu table is found and use that.
++	 */
++
++	while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)
++		dn = dn->parent;
++
++	if (dn && dn->data) {
++		PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
++	} else {
++		DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev));
++	}
++}
++
++static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
++{
++	int err = NOTIFY_OK;
++	struct device_node *np = node;
++	struct pci_dn *pci = np->data;
++
++	switch (action) {
++	case PSERIES_RECONFIG_REMOVE:
++		if (pci->iommu_table &&
++		    get_property(np, "ibm,dma-window", NULL))
++			iommu_free_table(np);
++		break;
++	default:
++		err = NOTIFY_DONE;
++		break;
++	}
++	return err;
++}
++
++static struct notifier_block iommu_reconfig_nb = {
++	.notifier_call = iommu_reconfig_notifier,
++};
++
++static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
++{
++	struct device_node *pdn, *dn;
++	struct iommu_table *tbl;
++	int *dma_window = NULL;
++	struct pci_dn *pci;
++
++	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
++
++	/* dev setup for LPAR is a little tricky, since the device tree might
++	 * contain the dma-window properties per-device and not neccesarily
++	 * for the bus. So we need to search upwards in the tree until we
++	 * either hit a dma-window property, OR find a parent with a table
++	 * already allocated.
++	 */
++	dn = pci_device_to_OF_node(dev);
++
++	for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table;
++	     pdn = pdn->parent) {
++		dma_window = (unsigned int *)
++			get_property(pdn, "ibm,dma-window", NULL);
++		if (dma_window)
++			break;
++	}
++
++	/* Check for parent == NULL so we don't try to setup the empty EADS
++	 * slots on POWER4 machines.
++	 */
++	if (dma_window == NULL || pdn->parent == NULL) {
++		DBG("No dma window for device, linking to parent\n");
++		PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table;
++		return;
++	} else {
++		DBG("Found DMA window, allocating table\n");
++	}
++
++	pci = pdn->data;
++	if (!pci->iommu_table) {
++		/* iommu_table_setparms_lpar needs bussubno. */
++		pci->bussubno = pci->phb->bus->number;
++
++		tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
++						    GFP_KERNEL);
++
++		iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
++
++		pci->iommu_table = iommu_init_table(tbl);
++	}
++
++	if (pdn != dn)
++		PCI_DN(dn)->iommu_table = pci->iommu_table;
++}
++
++static void iommu_bus_setup_null(struct pci_bus *b) { }
++static void iommu_dev_setup_null(struct pci_dev *d) { }
++
++/* These are called very early. */
++void iommu_init_early_pSeries(void)
++{
++	if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) {
++		/* Direct I/O, IOMMU off */
++		ppc_md.iommu_dev_setup = iommu_dev_setup_null;
++		ppc_md.iommu_bus_setup = iommu_bus_setup_null;
++		pci_direct_iommu_init();
++
++		return;
++	}
++
++	if (systemcfg->platform & PLATFORM_LPAR) {
++		if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
++			ppc_md.tce_build = tce_buildmulti_pSeriesLP;
++			ppc_md.tce_free	 = tce_freemulti_pSeriesLP;
++		} else {
++			ppc_md.tce_build = tce_build_pSeriesLP;
++			ppc_md.tce_free	 = tce_free_pSeriesLP;
++		}
++		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP;
++		ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP;
++	} else {
++		ppc_md.tce_build = tce_build_pSeries;
++		ppc_md.tce_free  = tce_free_pSeries;
++		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries;
++		ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries;
++	}
++
++
++	pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
++
++	pci_iommu_init();
++}
++
+diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -0,0 +1,517 @@
++/*
++ * pSeries_lpar.c
++ * Copyright (C) 2001 Todd Inglett, IBM Corporation
++ *
++ * pSeries LPAR 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
++ */
++
++#define DEBUG
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/dma-mapping.h>
++#include <asm/processor.h>
++#include <asm/mmu.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/machdep.h>
++#include <asm/abs_addr.h>
++#include <asm/mmu_context.h>
++#include <asm/ppcdebug.h>
++#include <asm/iommu.h>
++#include <asm/tlbflush.h>
++#include <asm/tlb.h>
++#include <asm/prom.h>
++#include <asm/abs_addr.h>
++#include <asm/cputable.h>
++#include <asm/plpar_wrappers.h>
++
++#ifdef DEBUG
++#define DBG(fmt...) udbg_printf(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++/* in pSeries_hvCall.S */
++EXPORT_SYMBOL(plpar_hcall);
++EXPORT_SYMBOL(plpar_hcall_4out);
++EXPORT_SYMBOL(plpar_hcall_norets);
++EXPORT_SYMBOL(plpar_hcall_8arg_2ret);
++
++extern void pSeries_find_serial_port(void);
++
++
++int vtermno;	/* virtual terminal# for udbg  */
++
++#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
++static void udbg_hvsi_putc(unsigned char c)
++{
++	/* packet's seqno isn't used anyways */
++	uint8_t packet[] __ALIGNED__ = { 0xff, 5, 0, 0, c };
++	int rc;
++
++	if (c == '\n')
++		udbg_hvsi_putc('\r');
++
++	do {
++		rc = plpar_put_term_char(vtermno, sizeof(packet), packet);
++	} while (rc == H_Busy);
++}
++
++static long hvsi_udbg_buf_len;
++static uint8_t hvsi_udbg_buf[256];
++
++static int udbg_hvsi_getc_poll(void)
++{
++	unsigned char ch;
++	int rc, i;
++
++	if (hvsi_udbg_buf_len == 0) {
++		rc = plpar_get_term_char(vtermno, &hvsi_udbg_buf_len, hvsi_udbg_buf);
++		if (rc != H_Success || hvsi_udbg_buf[0] != 0xff) {
++			/* bad read or non-data packet */
++			hvsi_udbg_buf_len = 0;
++		} else {
++			/* remove the packet header */
++			for (i = 4; i < hvsi_udbg_buf_len; i++)
++				hvsi_udbg_buf[i-4] = hvsi_udbg_buf[i];
++			hvsi_udbg_buf_len -= 4;
++		}
++	}
++
++	if (hvsi_udbg_buf_len <= 0 || hvsi_udbg_buf_len > 256) {
++		/* no data ready */
++		hvsi_udbg_buf_len = 0;
++		return -1;
++	}
++
++	ch = hvsi_udbg_buf[0];
++	/* shift remaining data down */
++	for (i = 1; i < hvsi_udbg_buf_len; i++) {
++		hvsi_udbg_buf[i-1] = hvsi_udbg_buf[i];
++	}
++	hvsi_udbg_buf_len--;
++
++	return ch;
++}
++
++static unsigned char udbg_hvsi_getc(void)
++{
++	int ch;
++	for (;;) {
++		ch = udbg_hvsi_getc_poll();
++		if (ch == -1) {
++			/* This shouldn't be needed...but... */
++			volatile unsigned long delay;
++			for (delay=0; delay < 2000000; delay++)
++				;
++		} else {
++			return ch;
++		}
++	}
++}
++
++static void udbg_putcLP(unsigned char c)
++{
++	char buf[16];
++	unsigned long rc;
++
++	if (c == '\n')
++		udbg_putcLP('\r');
++
++	buf[0] = c;
++	do {
++		rc = plpar_put_term_char(vtermno, 1, buf);
++	} while(rc == H_Busy);
++}
++
++/* Buffered chars getc */
++static long inbuflen;
++static long inbuf[2];	/* must be 2 longs */
++
++static int udbg_getc_pollLP(void)
++{
++	/* The interface is tricky because it may return up to 16 chars.
++	 * We save them statically for future calls to udbg_getc().
++	 */
++	char ch, *buf = (char *)inbuf;
++	int i;
++	long rc;
++	if (inbuflen == 0) {
++		/* get some more chars. */
++		inbuflen = 0;
++		rc = plpar_get_term_char(vtermno, &inbuflen, buf);
++		if (rc != H_Success)
++			inbuflen = 0;	/* otherwise inbuflen is garbage */
++	}
++	if (inbuflen <= 0 || inbuflen > 16) {
++		/* Catch error case as well as other oddities (corruption) */
++		inbuflen = 0;
++		return -1;
++	}
++	ch = buf[0];
++	for (i = 1; i < inbuflen; i++)	/* shuffle them down. */
++		buf[i-1] = buf[i];
++	inbuflen--;
++	return ch;
++}
++
++static unsigned char udbg_getcLP(void)
++{
++	int ch;
++	for (;;) {
++		ch = udbg_getc_pollLP();
++		if (ch == -1) {
++			/* This shouldn't be needed...but... */
++			volatile unsigned long delay;
++			for (delay=0; delay < 2000000; delay++)
++				;
++		} else {
++			return ch;
++		}
++	}
++}
++
++/* call this from early_init() for a working debug console on
++ * vterm capable LPAR machines
++ */
++void udbg_init_debug_lpar(void)
++{
++	vtermno = 0;
++	udbg_putc = udbg_putcLP;
++	udbg_getc = udbg_getcLP;
++	udbg_getc_poll = udbg_getc_pollLP;
++}
++
++/* returns 0 if couldn't find or use /chosen/stdout as console */
++int find_udbg_vterm(void)
++{
++	struct device_node *stdout_node;
++	u32 *termno;
++	char *name;
++	int found = 0;
++
++	/* find the boot console from /chosen/stdout */
++	if (!of_chosen)
++		return 0;
++	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
++	if (name == NULL)
++		return 0;
++	stdout_node = of_find_node_by_path(name);
++	if (!stdout_node)
++		return 0;
++
++	/* now we have the stdout node; figure out what type of device it is. */
++	name = (char *)get_property(stdout_node, "name", NULL);
++	if (!name) {
++		printk(KERN_WARNING "stdout node missing 'name' property!\n");
++		goto out;
++	}
++
++	if (strncmp(name, "vty", 3) == 0) {
++		if (device_is_compatible(stdout_node, "hvterm1")) {
++			termno = (u32 *)get_property(stdout_node, "reg", NULL);
++			if (termno) {
++				vtermno = termno[0];
++				udbg_putc = udbg_putcLP;
++				udbg_getc = udbg_getcLP;
++				udbg_getc_poll = udbg_getc_pollLP;
++				found = 1;
++			}
++		} else if (device_is_compatible(stdout_node, "hvterm-protocol")) {
++			termno = (u32 *)get_property(stdout_node, "reg", NULL);
++			if (termno) {
++				vtermno = termno[0];
++				udbg_putc = udbg_hvsi_putc;
++				udbg_getc = udbg_hvsi_getc;
++				udbg_getc_poll = udbg_hvsi_getc_poll;
++				found = 1;
++			}
++		}
++	} else if (strncmp(name, "serial", 6)) {
++		/* XXX fix ISA serial console */
++		printk(KERN_WARNING "serial stdout on LPAR ('%s')! "
++				"can't print udbg messages\n",
++		       stdout_node->full_name);
++	} else {
++		printk(KERN_WARNING "don't know how to print to stdout '%s'\n",
++		       stdout_node->full_name);
++	}
++
++out:
++	of_node_put(stdout_node);
++	return found;
++}
++
++void vpa_init(int cpu)
++{
++	int hwcpu = get_hard_smp_processor_id(cpu);
++	unsigned long vpa = (unsigned long)&(paca[cpu].lppaca);
++	long ret;
++	unsigned long flags;
++
++	/* Register the Virtual Processor Area (VPA) */
++	flags = 1UL << (63 - 18);
++
++	if (cpu_has_feature(CPU_FTR_ALTIVEC))
++		paca[cpu].lppaca.vmxregs_in_use = 1;
++
++	ret = register_vpa(flags, hwcpu, __pa(vpa));
++
++	if (ret)
++		printk(KERN_ERR "WARNING: vpa_init: VPA registration for "
++				"cpu %d (hw %d) of area %lx returns %ld\n",
++				cpu, hwcpu, __pa(vpa), ret);
++}
++
++long pSeries_lpar_hpte_insert(unsigned long hpte_group,
++			      unsigned long va, unsigned long prpn,
++			      unsigned long vflags, unsigned long rflags)
++{
++	unsigned long lpar_rc;
++	unsigned long flags;
++	unsigned long slot;
++	unsigned long hpte_v, hpte_r;
++	unsigned long dummy0, dummy1;
++
++	hpte_v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | vflags | HPTE_V_VALID;
++	if (vflags & HPTE_V_LARGE)
++		hpte_v &= ~(1UL << HPTE_V_AVPN_SHIFT);
++
++	hpte_r = (prpn << HPTE_R_RPN_SHIFT) | rflags;
++
++	/* Now fill in the actual HPTE */
++	/* Set CEC cookie to 0         */
++	/* Zero page = 0               */
++	/* I-cache Invalidate = 0      */
++	/* I-cache synchronize = 0     */
++	/* Exact = 0                   */
++	flags = 0;
++
++	/* XXX why is this here? - Anton */
++	if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
++		hpte_r &= ~_PAGE_COHERENT;
++
++	lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v,
++			      hpte_r, &slot, &dummy0, &dummy1);
++
++	if (unlikely(lpar_rc == H_PTEG_Full))
++		return -1;
++
++	/*
++	 * Since we try and ioremap PHBs we don't own, the pte insert
++	 * will fail. However we must catch the failure in hash_page
++	 * or we will loop forever, so return -2 in this case.
++	 */
++	if (unlikely(lpar_rc != H_Success))
++		return -2;
++
++	/* Because of iSeries, we have to pass down the secondary
++	 * bucket bit here as well
++	 */
++	return (slot & 7) | (!!(vflags & HPTE_V_SECONDARY) << 3);
++}
++
++static DEFINE_SPINLOCK(pSeries_lpar_tlbie_lock);
++
++static long pSeries_lpar_hpte_remove(unsigned long hpte_group)
++{
++	unsigned long slot_offset;
++	unsigned long lpar_rc;
++	int i;
++	unsigned long dummy1, dummy2;
++
++	/* pick a random slot to start at */
++	slot_offset = mftb() & 0x7;
++
++	for (i = 0; i < HPTES_PER_GROUP; i++) {
++
++		/* don't remove a bolted entry */
++		lpar_rc = plpar_pte_remove(H_ANDCOND, hpte_group + slot_offset,
++					   (0x1UL << 4), &dummy1, &dummy2);
++
++		if (lpar_rc == H_Success)
++			return i;
++
++		BUG_ON(lpar_rc != H_Not_Found);
++
++		slot_offset++;
++		slot_offset &= 0x7;
++	}
++
++	return -1;
++}
++
++static void pSeries_lpar_hptab_clear(void)
++{
++	unsigned long size_bytes = 1UL << ppc64_pft_size;
++	unsigned long hpte_count = size_bytes >> 4;
++	unsigned long dummy1, dummy2;
++	int i;
++
++	/* TODO: Use bulk call */
++	for (i = 0; i < hpte_count; i++)
++		plpar_pte_remove(0, i, 0, &dummy1, &dummy2);
++}
++
++/*
++ * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
++ * the low 3 bits of flags happen to line up.  So no transform is needed.
++ * We can probably optimize here and assume the high bits of newpp are
++ * already zero.  For now I am paranoid.
++ */
++static long pSeries_lpar_hpte_updatepp(unsigned long slot, unsigned long newpp,
++				       unsigned long va, int large, int local)
++{
++	unsigned long lpar_rc;
++	unsigned long flags = (newpp & 7) | H_AVPN;
++	unsigned long avpn = va >> 23;
++
++	if (large)
++		avpn &= ~0x1UL;
++
++	lpar_rc = plpar_pte_protect(flags, slot, (avpn << 7));
++
++	if (lpar_rc == H_Not_Found)
++		return -1;
++
++	BUG_ON(lpar_rc != H_Success);
++
++	return 0;
++}
++
++static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot)
++{
++	unsigned long dword0;
++	unsigned long lpar_rc;
++	unsigned long dummy_word1;
++	unsigned long flags;
++
++	/* Read 1 pte at a time                        */
++	/* Do not need RPN to logical page translation */
++	/* No cross CEC PFT access                     */
++	flags = 0;
++
++	lpar_rc = plpar_pte_read(flags, slot, &dword0, &dummy_word1);
++
++	BUG_ON(lpar_rc != H_Success);
++
++	return dword0;
++}
++
++static long pSeries_lpar_hpte_find(unsigned long vpn)
++{
++	unsigned long hash;
++	unsigned long i, j;
++	long slot;
++	unsigned long hpte_v;
++
++	hash = hpt_hash(vpn, 0);
++
++	for (j = 0; j < 2; j++) {
++		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
++		for (i = 0; i < HPTES_PER_GROUP; i++) {
++			hpte_v = pSeries_lpar_hpte_getword0(slot);
++
++			if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
++			    && (hpte_v & HPTE_V_VALID)
++			    && (!!(hpte_v & HPTE_V_SECONDARY) == j)) {
++				/* HPTE matches */
++				if (j)
++					slot = -slot;
++				return slot;
++			}
++			++slot;
++		}
++		hash = ~hash;
++	}
++
++	return -1;
++} 
++
++static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
++					     unsigned long ea)
++{
++	unsigned long lpar_rc;
++	unsigned long vsid, va, vpn, flags;
++	long slot;
++
++	vsid = get_kernel_vsid(ea);
++	va = (vsid << 28) | (ea & 0x0fffffff);
++	vpn = va >> PAGE_SHIFT;
++
++	slot = pSeries_lpar_hpte_find(vpn);
++	BUG_ON(slot == -1);
++
++	flags = newpp & 7;
++	lpar_rc = plpar_pte_protect(flags, slot, 0);
++
++	BUG_ON(lpar_rc != H_Success);
++}
++
++static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
++					 int large, int local)
++{
++	unsigned long avpn = va >> 23;
++	unsigned long lpar_rc;
++	unsigned long dummy1, dummy2;
++
++	if (large)
++		avpn &= ~0x1UL;
++
++	lpar_rc = plpar_pte_remove(H_AVPN, slot, (avpn << 7), &dummy1,
++				   &dummy2);
++
++	if (lpar_rc == H_Not_Found)
++		return;
++
++	BUG_ON(lpar_rc != H_Success);
++}
++
++/*
++ * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
++ * lock.
++ */
++void pSeries_lpar_flush_hash_range(unsigned long number, int local)
++{
++	int i;
++	unsigned long flags = 0;
++	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
++	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
++
++	if (lock_tlbie)
++		spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
++
++	for (i = 0; i < number; i++)
++		flush_hash_page(batch->vaddr[i], batch->pte[i], local);
++
++	if (lock_tlbie)
++		spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
++}
++
++void hpte_init_lpar(void)
++{
++	ppc_md.hpte_invalidate	= pSeries_lpar_hpte_invalidate;
++	ppc_md.hpte_updatepp	= pSeries_lpar_hpte_updatepp;
++	ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp;
++	ppc_md.hpte_insert	= pSeries_lpar_hpte_insert;
++	ppc_md.hpte_remove	= pSeries_lpar_hpte_remove;
++	ppc_md.flush_hash_range	= pSeries_lpar_flush_hash_range;
++	ppc_md.hpte_clear_all   = pSeries_lpar_hptab_clear;
++
++	htab_finish_init();
++}
+diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/nvram.c
+@@ -0,0 +1,148 @@
++/*
++ *  c 2001 PPC 64 Team, IBM Corp
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ *
++ * /dev/nvram driver for PPC64
++ *
++ * This perhaps should live in drivers/char
++ */
++
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <asm/uaccess.h>
++#include <asm/nvram.h>
++#include <asm/rtas.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++
++static unsigned int nvram_size;
++static int nvram_fetch, nvram_store;
++static char nvram_buf[NVRW_CNT];	/* assume this is in the first 4GB */
++static DEFINE_SPINLOCK(nvram_lock);
++
++
++static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
++{
++	unsigned int i;
++	unsigned long len;
++	int done;
++	unsigned long flags;
++	char *p = buf;
++
++
++	if (nvram_size == 0 || nvram_fetch == RTAS_UNKNOWN_SERVICE)
++		return -ENODEV;
++
++	if (*index >= nvram_size)
++		return 0;
++
++	i = *index;
++	if (i + count > nvram_size)
++		count = nvram_size - i;
++
++	spin_lock_irqsave(&nvram_lock, flags);
++
++	for (; count != 0; count -= len) {
++		len = count;
++		if (len > NVRW_CNT)
++			len = NVRW_CNT;
++		
++		if ((rtas_call(nvram_fetch, 3, 2, &done, i, __pa(nvram_buf),
++			       len) != 0) || len != done) {
++			spin_unlock_irqrestore(&nvram_lock, flags);
++			return -EIO;
++		}
++		
++		memcpy(p, nvram_buf, len);
++
++		p += len;
++		i += len;
++	}
++
++	spin_unlock_irqrestore(&nvram_lock, flags);
++	
++	*index = i;
++	return p - buf;
++}
++
++static ssize_t pSeries_nvram_write(char *buf, size_t count, loff_t *index)
++{
++	unsigned int i;
++	unsigned long len;
++	int done;
++	unsigned long flags;
++	const char *p = buf;
++
++	if (nvram_size == 0 || nvram_store == RTAS_UNKNOWN_SERVICE)
++		return -ENODEV;
++
++	if (*index >= nvram_size)
++		return 0;
++
++	i = *index;
++	if (i + count > nvram_size)
++		count = nvram_size - i;
++
++	spin_lock_irqsave(&nvram_lock, flags);
++
++	for (; count != 0; count -= len) {
++		len = count;
++		if (len > NVRW_CNT)
++			len = NVRW_CNT;
++
++		memcpy(nvram_buf, p, len);
++
++		if ((rtas_call(nvram_store, 3, 2, &done, i, __pa(nvram_buf),
++			       len) != 0) || len != done) {
++			spin_unlock_irqrestore(&nvram_lock, flags);
++			return -EIO;
++		}
++		
++		p += len;
++		i += len;
++	}
++	spin_unlock_irqrestore(&nvram_lock, flags);
++	
++	*index = i;
++	return p - buf;
++}
++
++static ssize_t pSeries_nvram_get_size(void)
++{
++	return nvram_size ? nvram_size : -ENODEV;
++}
++
++int __init pSeries_nvram_init(void)
++{
++	struct device_node *nvram;
++	unsigned int *nbytes_p, proplen;
++
++	nvram = of_find_node_by_type(NULL, "nvram");
++	if (nvram == NULL)
++		return -ENODEV;
++
++	nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
++	if (nbytes_p == NULL || proplen != sizeof(unsigned int))
++		return -EIO;
++
++	nvram_size = *nbytes_p;
++
++	nvram_fetch = rtas_token("nvram-fetch");
++	nvram_store = rtas_token("nvram-store");
++	printk(KERN_INFO "PPC64 nvram contains %d bytes\n", nvram_size);
++	of_node_put(nvram);
++
++	ppc_md.nvram_read	= pSeries_nvram_read;
++	ppc_md.nvram_write	= pSeries_nvram_write;
++	ppc_md.nvram_size	= pSeries_nvram_get_size;
++
++	return 0;
++}
+diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/pci.c
+@@ -0,0 +1,142 @@
++/*
++ * arch/ppc64/kernel/pSeries_pci.c
++ *
++ * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
++ * Copyright (C) 2003 Anton Blanchard <anton at au.ibm.com>, IBM
++ *
++ * pSeries specific routines for PCI.
++ * 
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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/ioport.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/string.h>
++
++#include <asm/pci-bridge.h>
++#include <asm/prom.h>
++#include <asm/ppc-pci.h>
++
++static int __devinitdata s7a_workaround = -1;
++
++#if 0
++void pcibios_name_device(struct pci_dev *dev)
++{
++	struct device_node *dn;
++
++	/*
++	 * Add IBM loc code (slot) as a prefix to the device names for service
++	 */
++	dn = pci_device_to_OF_node(dev);
++	if (dn) {
++		char *loc_code = get_property(dn, "ibm,loc-code", 0);
++		if (loc_code) {
++			int loc_len = strlen(loc_code);
++			if (loc_len < sizeof(dev->dev.name)) {
++				memmove(dev->dev.name+loc_len+1, dev->dev.name,
++					sizeof(dev->dev.name)-loc_len-1);
++				memcpy(dev->dev.name, loc_code, loc_len);
++				dev->dev.name[loc_len] = ' ';
++				dev->dev.name[sizeof(dev->dev.name)-1] = '\0';
++			}
++		}
++	}
++}   
++DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
++#endif
++
++static void __devinit check_s7a(void)
++{
++	struct device_node *root;
++	char *model;
++
++	s7a_workaround = 0;
++	root = of_find_node_by_path("/");
++	if (root) {
++		model = get_property(root, "model", NULL);
++		if (model && !strcmp(model, "IBM,7013-S7A"))
++			s7a_workaround = 1;
++		of_node_put(root);
++	}
++}
++
++void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
++{
++	struct pci_dev *dev;
++
++	if (s7a_workaround < 0)
++		check_s7a();
++	list_for_each_entry(dev, &bus->devices, bus_list) {
++		pci_read_irq_line(dev);
++		if (s7a_workaround) {
++			if (dev->irq > 16) {
++				dev->irq -= 3;
++				pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
++					dev->irq);
++			}
++		}
++	}
++}
++
++static void __init pSeries_request_regions(void)
++{
++	if (!isa_io_base)
++		return;
++
++	request_region(0x20,0x20,"pic1");
++	request_region(0xa0,0x20,"pic2");
++	request_region(0x00,0x20,"dma1");
++	request_region(0x40,0x20,"timer");
++	request_region(0x80,0x10,"dma page reg");
++	request_region(0xc0,0x20,"dma2");
++}
++
++void __init pSeries_final_fixup(void)
++{
++	phbs_remap_io();
++	pSeries_request_regions();
++
++	pci_addr_cache_build();
++}
++
++/*
++ * Assume the winbond 82c105 is the IDE controller on a
++ * p610.  We should probably be more careful in case
++ * someone tries to plug in a similar adapter.
++ */
++static void fixup_winbond_82c105(struct pci_dev* dev)
++{
++	int i;
++	unsigned int reg;
++
++	if (!(systemcfg->platform & PLATFORM_PSERIES))
++		return;
++
++	printk("Using INTC for W82c105 IDE controller.\n");
++	pci_read_config_dword(dev, 0x40, &reg);
++	/* Enable LEGIRQ to use INTC instead of ISA interrupts */
++	pci_write_config_dword(dev, 0x40, reg | (1<<11));
++
++	for (i = 0; i < DEVICE_COUNT_RESOURCE; ++i) {
++		/* zap the 2nd function of the winbond chip */
++		if (dev->resource[i].flags & IORESOURCE_IO
++		    && dev->bus->number == 0 && dev->devfn == 0x81)
++			dev->resource[i].flags &= ~IORESOURCE_IO;
++	}
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
++			 fixup_winbond_82c105);
+diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/ras.c
+@@ -0,0 +1,352 @@
++/*
++ * Copyright (C) 2001 Dave Engebretsen 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
++ */
++
++/* Change Activity:
++ * 2001/09/21 : engebret : Created with minimal EPOW and HW exception support.
++ * End Change Activity
++ */
++
++#include <linux/errno.h>
++#include <linux/threads.h>
++#include <linux/kernel_stat.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/timex.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/pci.h>
++#include <linux/delay.h>
++#include <linux/irq.h>
++#include <linux/random.h>
++#include <linux/sysrq.h>
++#include <linux/bitops.h>
++
++#include <asm/uaccess.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/irq.h>
++#include <asm/cache.h>
++#include <asm/prom.h>
++#include <asm/ptrace.h>
++#include <asm/machdep.h>
++#include <asm/rtas.h>
++#include <asm/ppcdebug.h>
++
++static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
++static DEFINE_SPINLOCK(ras_log_buf_lock);
++
++char mce_data_buf[RTAS_ERROR_LOG_MAX]
++;
++/* This is true if we are using the firmware NMI handler (typically LPAR) */
++extern int fwnmi_active;
++
++static int ras_get_sensor_state_token;
++static int ras_check_exception_token;
++
++#define EPOW_SENSOR_TOKEN	9
++#define EPOW_SENSOR_INDEX	0
++#define RAS_VECTOR_OFFSET	0x500
++
++static irqreturn_t ras_epow_interrupt(int irq, void *dev_id,
++					struct pt_regs * regs);
++static irqreturn_t ras_error_interrupt(int irq, void *dev_id,
++					struct pt_regs * regs);
++
++/* #define DEBUG */
++
++static void request_ras_irqs(struct device_node *np, char *propname,
++			irqreturn_t (*handler)(int, void *, struct pt_regs *),
++			const char *name)
++{
++	unsigned int *ireg, len, i;
++	int virq, n_intr;
++
++	ireg = (unsigned int *)get_property(np, propname, &len);
++	if (ireg == NULL)
++		return;
++	n_intr = prom_n_intr_cells(np);
++	len /= n_intr * sizeof(*ireg);
++
++	for (i = 0; i < len; i++) {
++		virq = virt_irq_create_mapping(*ireg);
++		if (virq == NO_IRQ) {
++			printk(KERN_ERR "Unable to allocate interrupt "
++			       "number for %s\n", np->full_name);
++			return;
++		}
++		if (request_irq(irq_offset_up(virq), handler, 0, name, NULL)) {
++			printk(KERN_ERR "Unable to request interrupt %d for "
++			       "%s\n", irq_offset_up(virq), np->full_name);
++			return;
++		}
++		ireg += n_intr;
++	}
++}
++
++/*
++ * Initialize handlers for the set of interrupts caused by hardware errors
++ * and power system events.
++ */
++static int __init init_ras_IRQ(void)
++{
++	struct device_node *np;
++
++	ras_get_sensor_state_token = rtas_token("get-sensor-state");
++	ras_check_exception_token = rtas_token("check-exception");
++
++	/* Internal Errors */
++	np = of_find_node_by_path("/event-sources/internal-errors");
++	if (np != NULL) {
++		request_ras_irqs(np, "open-pic-interrupt", ras_error_interrupt,
++				 "RAS_ERROR");
++		request_ras_irqs(np, "interrupts", ras_error_interrupt,
++				 "RAS_ERROR");
++		of_node_put(np);
++	}
++
++	/* EPOW Events */
++	np = of_find_node_by_path("/event-sources/epow-events");
++	if (np != NULL) {
++		request_ras_irqs(np, "open-pic-interrupt", ras_epow_interrupt,
++				 "RAS_EPOW");
++		request_ras_irqs(np, "interrupts", ras_epow_interrupt,
++				 "RAS_EPOW");
++		of_node_put(np);
++	}
++
++	return 1;
++}
++__initcall(init_ras_IRQ);
++
++/*
++ * Handle power subsystem events (EPOW).
++ *
++ * Presently we just log the event has occurred.  This should be fixed
++ * to examine the type of power failure and take appropriate action where
++ * the time horizon permits something useful to be done.
++ */
++static irqreturn_t
++ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs)
++{
++	int status = 0xdeadbeef;
++	int state = 0;
++	int critical;
++
++	status = rtas_call(ras_get_sensor_state_token, 2, 2, &state,
++			   EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX);
++
++	if (state > 3)
++		critical = 1;  /* Time Critical */
++	else
++		critical = 0;
++
++	spin_lock(&ras_log_buf_lock);
++
++	status = rtas_call(ras_check_exception_token, 6, 1, NULL,
++			   RAS_VECTOR_OFFSET,
++			   virt_irq_to_real(irq_offset_down(irq)),
++			   RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS,
++			   critical, __pa(&ras_log_buf),
++				rtas_get_error_log_max());
++
++	udbg_printf("EPOW <0x%lx 0x%x 0x%x>\n",
++		    *((unsigned long *)&ras_log_buf), status, state);
++	printk(KERN_WARNING "EPOW <0x%lx 0x%x 0x%x>\n",
++	       *((unsigned long *)&ras_log_buf), status, state);
++
++	/* format and print the extended information */
++	log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, 0);
++
++	spin_unlock(&ras_log_buf_lock);
++	return IRQ_HANDLED;
++}
++
++/*
++ * Handle hardware error interrupts.
++ *
++ * RTAS check-exception is called to collect data on the exception.  If
++ * the error is deemed recoverable, we log a warning and return.
++ * For nonrecoverable errors, an error is logged and we stop all processing
++ * as quickly as possible in order to prevent propagation of the failure.
++ */
++static irqreturn_t
++ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs)
++{
++	struct rtas_error_log *rtas_elog;
++	int status = 0xdeadbeef;
++	int fatal;
++
++	spin_lock(&ras_log_buf_lock);
++
++	status = rtas_call(ras_check_exception_token, 6, 1, NULL,
++			   RAS_VECTOR_OFFSET,
++			   virt_irq_to_real(irq_offset_down(irq)),
++			   RTAS_INTERNAL_ERROR, 1 /*Time Critical */,
++			   __pa(&ras_log_buf),
++				rtas_get_error_log_max());
++
++	rtas_elog = (struct rtas_error_log *)ras_log_buf;
++
++	if ((status == 0) && (rtas_elog->severity >= RTAS_SEVERITY_ERROR_SYNC))
++		fatal = 1;
++	else
++		fatal = 0;
++
++	/* format and print the extended information */
++	log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, fatal);
++
++	if (fatal) {
++		udbg_printf("Fatal HW Error <0x%lx 0x%x>\n",
++			    *((unsigned long *)&ras_log_buf), status);
++		printk(KERN_EMERG "Error: Fatal hardware error <0x%lx 0x%x>\n",
++		       *((unsigned long *)&ras_log_buf), status);
++
++#ifndef DEBUG
++		/* Don't actually power off when debugging so we can test
++		 * without actually failing while injecting errors.
++		 * Error data will not be logged to syslog.
++		 */
++		ppc_md.power_off();
++#endif
++	} else {
++		udbg_printf("Recoverable HW Error <0x%lx 0x%x>\n",
++			    *((unsigned long *)&ras_log_buf), status);
++		printk(KERN_WARNING
++		       "Warning: Recoverable hardware error <0x%lx 0x%x>\n",
++		       *((unsigned long *)&ras_log_buf), status);
++	}
++
++	spin_unlock(&ras_log_buf_lock);
++	return IRQ_HANDLED;
++}
++
++/* Get the error information for errors coming through the
++ * FWNMI vectors.  The pt_regs' r3 will be updated to reflect
++ * the actual r3 if possible, and a ptr to the error log entry
++ * will be returned if found.
++ *
++ * The mce_data_buf does not have any locks or protection around it,
++ * if a second machine check comes in, or a system reset is done
++ * before we have logged the error, then we will get corruption in the
++ * error log.  This is preferable over holding off on calling
++ * ibm,nmi-interlock which would result in us checkstopping if a
++ * second machine check did come in.
++ */
++static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
++{
++	unsigned long errdata = regs->gpr[3];
++	struct rtas_error_log *errhdr = NULL;
++	unsigned long *savep;
++
++	if ((errdata >= 0x7000 && errdata < 0x7fff0) ||
++	    (errdata >= rtas.base && errdata < rtas.base + rtas.size - 16)) {
++		savep = __va(errdata);
++		regs->gpr[3] = savep[0];	/* restore original r3 */
++		memset(mce_data_buf, 0, RTAS_ERROR_LOG_MAX);
++		memcpy(mce_data_buf, (char *)(savep + 1), RTAS_ERROR_LOG_MAX);
++		errhdr = (struct rtas_error_log *)mce_data_buf;
++	} else {
++		printk("FWNMI: corrupt r3\n");
++	}
++	return errhdr;
++}
++
++/* Call this when done with the data returned by FWNMI_get_errinfo.
++ * It will release the saved data area for other CPUs in the
++ * partition to receive FWNMI errors.
++ */
++static void fwnmi_release_errinfo(void)
++{
++	int ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL);
++	if (ret != 0)
++		printk("FWNMI: nmi-interlock failed: %d\n", ret);
++}
++
++void pSeries_system_reset_exception(struct pt_regs *regs)
++{
++	if (fwnmi_active) {
++		struct rtas_error_log *errhdr = fwnmi_get_errinfo(regs);
++		if (errhdr) {
++			/* XXX Should look at FWNMI information */
++		}
++		fwnmi_release_errinfo();
++	}
++}
++
++/*
++ * See if we can recover from a machine check exception.
++ * This is only called on power4 (or above) and only via
++ * the Firmware Non-Maskable Interrupts (fwnmi) handler
++ * which provides the error analysis for us.
++ *
++ * Return 1 if corrected (or delivered a signal).
++ * Return 0 if there is nothing we can do.
++ */
++static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
++{
++	int nonfatal = 0;
++
++	if (err->disposition == RTAS_DISP_FULLY_RECOVERED) {
++		/* Platform corrected itself */
++		nonfatal = 1;
++	} else if ((regs->msr & MSR_RI) &&
++		   user_mode(regs) &&
++		   err->severity == RTAS_SEVERITY_ERROR_SYNC &&
++		   err->disposition == RTAS_DISP_NOT_RECOVERED &&
++		   err->target == RTAS_TARGET_MEMORY &&
++		   err->type == RTAS_TYPE_ECC_UNCORR &&
++		   !(current->pid == 0 || current->pid == 1)) {
++		/* Kill off a user process with an ECC error */
++		printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
++		       current->pid);
++		/* XXX something better for ECC error? */
++		_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
++		nonfatal = 1;
++	}
++
++	log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal);
++
++	return nonfatal;
++}
++
++/*
++ * Handle a machine check.
++ *
++ * Note that on Power 4 and beyond Firmware Non-Maskable Interrupts (fwnmi)
++ * should be present.  If so the handler which called us tells us if the
++ * error was recovered (never true if RI=0).
++ *
++ * On hardware prior to Power 4 these exceptions were asynchronous which
++ * means we can't tell exactly where it occurred and so we can't recover.
++ */
++int pSeries_machine_check_exception(struct pt_regs *regs)
++{
++	struct rtas_error_log *errp;
++
++	if (fwnmi_active) {
++		errp = fwnmi_get_errinfo(regs);
++		fwnmi_release_errinfo();
++		if (errp && recover_mce(regs, errp))
++			return 1;
++	}
++
++	return 0;
++}
+diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/reconfig.c
+@@ -0,0 +1,426 @@
++/*
++ * pSeries_reconfig.c - support for dynamic reconfiguration (including PCI
++ * Hotplug and Dynamic Logical Partitioning on RPA platforms).
++ *
++ * Copyright (C) 2005 Nathan Lynch
++ * Copyright (C) 2005 IBM 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.
++ */
++
++#include <linux/kernel.h>
++#include <linux/kref.h>
++#include <linux/notifier.h>
++#include <linux/proc_fs.h>
++
++#include <asm/prom.h>
++#include <asm/pSeries_reconfig.h>
++#include <asm/uaccess.h>
++
++
++
++/*
++ * Routines for "runtime" addition and removal of device tree nodes.
++ */
++#ifdef CONFIG_PROC_DEVICETREE
++/*
++ * Add a node to /proc/device-tree.
++ */
++static void add_node_proc_entries(struct device_node *np)
++{
++	struct proc_dir_entry *ent;
++
++	ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
++	if (ent)
++		proc_device_tree_add_node(np, ent);
++}
++
++static void remove_node_proc_entries(struct device_node *np)
++{
++	struct property *pp = np->properties;
++	struct device_node *parent = np->parent;
++
++	while (pp) {
++		remove_proc_entry(pp->name, np->pde);
++		pp = pp->next;
++	}
++	if (np->pde)
++		remove_proc_entry(np->pde->name, parent->pde);
++}
++#else /* !CONFIG_PROC_DEVICETREE */
++static void add_node_proc_entries(struct device_node *np)
++{
++	return;
++}
++
++static void remove_node_proc_entries(struct device_node *np)
++{
++	return;
++}
++#endif /* CONFIG_PROC_DEVICETREE */
++
++/**
++ *	derive_parent - basically like dirname(1)
++ *	@path:  the full_name of a node to be added to the tree
++ *
++ *	Returns the node which should be the parent of the node
++ *	described by path.  E.g., for path = "/foo/bar", returns
++ *	the node with full_name = "/foo".
++ */
++static struct device_node *derive_parent(const char *path)
++{
++	struct device_node *parent = NULL;
++	char *parent_path = "/";
++	size_t parent_path_len = strrchr(path, '/') - path + 1;
++
++	/* reject if path is "/" */
++	if (!strcmp(path, "/"))
++		return ERR_PTR(-EINVAL);
++
++	if (strrchr(path, '/') != path) {
++		parent_path = kmalloc(parent_path_len, GFP_KERNEL);
++		if (!parent_path)
++			return ERR_PTR(-ENOMEM);
++		strlcpy(parent_path, path, parent_path_len);
++	}
++	parent = of_find_node_by_path(parent_path);
++	if (!parent)
++		return ERR_PTR(-EINVAL);
++	if (strcmp(parent_path, "/"))
++		kfree(parent_path);
++	return parent;
++}
++
++static struct notifier_block *pSeries_reconfig_chain;
++
++int pSeries_reconfig_notifier_register(struct notifier_block *nb)
++{
++	return notifier_chain_register(&pSeries_reconfig_chain, nb);
++}
++
++void pSeries_reconfig_notifier_unregister(struct notifier_block *nb)
++{
++	notifier_chain_unregister(&pSeries_reconfig_chain, nb);
++}
++
++static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
++{
++	struct device_node *np;
++	int err = -ENOMEM;
++
++	np = kzalloc(sizeof(*np), GFP_KERNEL);
++	if (!np)
++		goto out_err;
++
++	np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
++	if (!np->full_name)
++		goto out_err;
++
++	strcpy(np->full_name, path);
++
++	np->properties = proplist;
++	OF_MARK_DYNAMIC(np);
++	kref_init(&np->kref);
++
++	np->parent = derive_parent(path);
++	if (IS_ERR(np->parent)) {
++		err = PTR_ERR(np->parent);
++		goto out_err;
++	}
++
++	err = notifier_call_chain(&pSeries_reconfig_chain,
++				  PSERIES_RECONFIG_ADD, np);
++	if (err == NOTIFY_BAD) {
++		printk(KERN_ERR "Failed to add device node %s\n", path);
++		err = -ENOMEM; /* For now, safe to assume kmalloc failure */
++		goto out_err;
++	}
++
++	of_attach_node(np);
++
++	add_node_proc_entries(np);
++
++	of_node_put(np->parent);
++
++	return 0;
++
++out_err:
++	if (np) {
++		of_node_put(np->parent);
++		kfree(np->full_name);
++		kfree(np);
++	}
++	return err;
++}
++
++static int pSeries_reconfig_remove_node(struct device_node *np)
++{
++	struct device_node *parent, *child;
++
++	parent = of_get_parent(np);
++	if (!parent)
++		return -EINVAL;
++
++	if ((child = of_get_next_child(np, NULL))) {
++		of_node_put(child);
++		return -EBUSY;
++	}
++
++	remove_node_proc_entries(np);
++
++	notifier_call_chain(&pSeries_reconfig_chain,
++			    PSERIES_RECONFIG_REMOVE, np);
++	of_detach_node(np);
++
++	of_node_put(parent);
++	of_node_put(np); /* Must decrement the refcount */
++	return 0;
++}
++
++/*
++ * /proc/ppc64/ofdt - yucky binary interface for adding and removing
++ * OF device nodes.  Should be deprecated as soon as we get an
++ * in-kernel wrapper for the RTAS ibm,configure-connector call.
++ */
++
++static void release_prop_list(const struct property *prop)
++{
++	struct property *next;
++	for (; prop; prop = next) {
++		next = prop->next;
++		kfree(prop->name);
++		kfree(prop->value);
++		kfree(prop);
++	}
++
++}
++
++/**
++ * parse_next_property - process the next property from raw input buffer
++ * @buf: input buffer, must be nul-terminated
++ * @end: end of the input buffer + 1, for validation
++ * @name: return value; set to property name in buf
++ * @length: return value; set to length of value
++ * @value: return value; set to the property value in buf
++ *
++ * Note that the caller must make copies of the name and value returned,
++ * this function does no allocation or copying of the data.  Return value
++ * is set to the next name in buf, or NULL on error.
++ */
++static char * parse_next_property(char *buf, char *end, char **name, int *length,
++				  unsigned char **value)
++{
++	char *tmp;
++
++	*name = buf;
++
++	tmp = strchr(buf, ' ');
++	if (!tmp) {
++		printk(KERN_ERR "property parse failed in %s at line %d\n",
++		       __FUNCTION__, __LINE__);
++		return NULL;
++	}
++	*tmp = '\0';
++
++	if (++tmp >= end) {
++		printk(KERN_ERR "property parse failed in %s at line %d\n",
++		       __FUNCTION__, __LINE__);
++		return NULL;
++	}
++
++	/* now we're on the length */
++	*length = -1;
++	*length = simple_strtoul(tmp, &tmp, 10);
++	if (*length == -1) {
++		printk(KERN_ERR "property parse failed in %s at line %d\n",
++		       __FUNCTION__, __LINE__);
++		return NULL;
++	}
++	if (*tmp != ' ' || ++tmp >= end) {
++		printk(KERN_ERR "property parse failed in %s at line %d\n",
++		       __FUNCTION__, __LINE__);
++		return NULL;
++	}
++
++	/* now we're on the value */
++	*value = tmp;
++	tmp += *length;
++	if (tmp > end) {
++		printk(KERN_ERR "property parse failed in %s at line %d\n",
++		       __FUNCTION__, __LINE__);
++		return NULL;
++	}
++	else if (tmp < end && *tmp != ' ' && *tmp != '\0') {
++		printk(KERN_ERR "property parse failed in %s at line %d\n",
++		       __FUNCTION__, __LINE__);
++		return NULL;
++	}
++	tmp++;
++
++	/* and now we should be on the next name, or the end */
++	return tmp;
++}
++
++static struct property *new_property(const char *name, const int length,
++				     const unsigned char *value, struct property *last)
++{
++	struct property *new = kmalloc(sizeof(*new), GFP_KERNEL);
++
++	if (!new)
++		return NULL;
++	memset(new, 0, sizeof(*new));
++
++	if (!(new->name = kmalloc(strlen(name) + 1, GFP_KERNEL)))
++		goto cleanup;
++	if (!(new->value = kmalloc(length + 1, GFP_KERNEL)))
++		goto cleanup;
++
++	strcpy(new->name, name);
++	memcpy(new->value, value, length);
++	*(((char *)new->value) + length) = 0;
++	new->length = length;
++	new->next = last;
++	return new;
++
++cleanup:
++	if (new->name)
++		kfree(new->name);
++	if (new->value)
++		kfree(new->value);
++	kfree(new);
++	return NULL;
++}
++
++static int do_add_node(char *buf, size_t bufsize)
++{
++	char *path, *end, *name;
++	struct device_node *np;
++	struct property *prop = NULL;
++	unsigned char* value;
++	int length, rv = 0;
++
++	end = buf + bufsize;
++	path = buf;
++	buf = strchr(buf, ' ');
++	if (!buf)
++		return -EINVAL;
++	*buf = '\0';
++	buf++;
++
++	if ((np = of_find_node_by_path(path))) {
++		of_node_put(np);
++		return -EINVAL;
++	}
++
++	/* rv = build_prop_list(tmp, bufsize - (tmp - buf), &proplist); */
++	while (buf < end &&
++	       (buf = parse_next_property(buf, end, &name, &length, &value))) {
++		struct property *last = prop;
++
++		prop = new_property(name, length, value, last);
++		if (!prop) {
++			rv = -ENOMEM;
++			prop = last;
++			goto out;
++		}
++	}
++	if (!buf) {
++		rv = -EINVAL;
++		goto out;
++	}
++
++	rv = pSeries_reconfig_add_node(path, prop);
++
++out:
++	if (rv)
++		release_prop_list(prop);
++	return rv;
++}
++
++static int do_remove_node(char *buf)
++{
++	struct device_node *node;
++	int rv = -ENODEV;
++
++	if ((node = of_find_node_by_path(buf)))
++		rv = pSeries_reconfig_remove_node(node);
++
++	of_node_put(node);
++	return rv;
++}
++
++/**
++ * ofdt_write - perform operations on the Open Firmware device tree
++ *
++ * @file: not used
++ * @buf: command and arguments
++ * @count: size of the command buffer
++ * @off: not used
++ *
++ * Operations supported at this time are addition and removal of
++ * whole nodes along with their properties.  Operations on individual
++ * properties are not implemented (yet).
++ */
++static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t count,
++			  loff_t *off)
++{
++	int rv = 0;
++	char *kbuf;
++	char *tmp;
++
++	if (!(kbuf = kmalloc(count + 1, GFP_KERNEL))) {
++		rv = -ENOMEM;
++		goto out;
++	}
++	if (copy_from_user(kbuf, buf, count)) {
++		rv = -EFAULT;
++		goto out;
++	}
++
++	kbuf[count] = '\0';
++
++	tmp = strchr(kbuf, ' ');
++	if (!tmp) {
++		rv = -EINVAL;
++		goto out;
++	}
++	*tmp = '\0';
++	tmp++;
++
++	if (!strcmp(kbuf, "add_node"))
++		rv = do_add_node(tmp, count - (tmp - kbuf));
++	else if (!strcmp(kbuf, "remove_node"))
++		rv = do_remove_node(tmp);
++	else
++		rv = -EINVAL;
++out:
++	kfree(kbuf);
++	return rv ? rv : count;
++}
++
++static struct file_operations ofdt_fops = {
++	.write = ofdt_write
++};
++
++/* create /proc/ppc64/ofdt write-only by root */
++static int proc_ppc64_create_ofdt(void)
++{
++	struct proc_dir_entry *ent;
++
++	if (!(systemcfg->platform & PLATFORM_PSERIES))
++		return 0;
++
++	ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL);
++	if (ent) {
++		ent->nlink = 1;
++		ent->data = NULL;
++		ent->size = 0;
++		ent->proc_fops = &ofdt_fops;
++	}
++
++	return 0;
++}
++__initcall(proc_ppc64_create_ofdt);
+diff --git a/arch/powerpc/platforms/pseries/rtas-fw.c b/arch/powerpc/platforms/pseries/rtas-fw.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/rtas-fw.c
+@@ -0,0 +1,138 @@
++/*
++ *
++ * Procedures for firmware flash updates on pSeries systems.
++ *
++ * Peter Bergner, IBM	March 2001.
++ * Copyright (C) 2001 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 <stdarg.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/spinlock.h>
++#include <linux/module.h>
++#include <linux/init.h>
++
++#include <asm/prom.h>
++#include <asm/rtas.h>
++#include <asm/semaphore.h>
++#include <asm/machdep.h>
++#include <asm/page.h>
++#include <asm/param.h>
++#include <asm/system.h>
++#include <asm/abs_addr.h>
++#include <asm/udbg.h>
++#include <asm/delay.h>
++#include <asm/uaccess.h>
++#include <asm/systemcfg.h>
++
++#include "rtas-fw.h"
++
++struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
++
++#define FLASH_BLOCK_LIST_VERSION (1UL)
++
++static void rtas_flash_firmware(void)
++{
++	unsigned long image_size;
++	struct flash_block_list *f, *next, *flist;
++	unsigned long rtas_block_list;
++	int i, status, update_token;
++
++	update_token = rtas_token("ibm,update-flash-64-and-reboot");
++	if (update_token == RTAS_UNKNOWN_SERVICE) {
++		printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n");
++		printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
++		return;
++	}
++
++	/* NOTE: the "first" block list is a global var with no data
++	 * blocks in the kernel data segment.  We do this because
++	 * we want to ensure this block_list addr is under 4GB.
++	 */
++	rtas_firmware_flash_list.num_blocks = 0;
++	flist = (struct flash_block_list *)&rtas_firmware_flash_list;
++	rtas_block_list = virt_to_abs(flist);
++	if (rtas_block_list >= 4UL*1024*1024*1024) {
++		printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
++		return;
++	}
++
++	printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
++	/* Update the block_list in place. */
++	image_size = 0;
++	for (f = flist; f; f = next) {
++		/* Translate data addrs to absolute */
++		for (i = 0; i < f->num_blocks; i++) {
++			f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
++			image_size += f->blocks[i].length;
++		}
++		next = f->next;
++		/* Don't translate NULL pointer for last entry */
++		if (f->next)
++			f->next = (struct flash_block_list *)virt_to_abs(f->next);
++		else
++			f->next = NULL;
++		/* make num_blocks into the version/length field */
++		f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
++	}
++
++	printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
++	printk(KERN_ALERT "FLASH: performing flash and reboot\n");
++	rtas_progress("Flashing        \n", 0x0);
++	rtas_progress("Please Wait...  ", 0x0);
++	printk(KERN_ALERT "FLASH: this will take several minutes.  Do not power off!\n");
++	status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
++	switch (status) {	/* should only get "bad" status */
++	    case 0:
++		printk(KERN_ALERT "FLASH: success\n");
++		break;
++	    case -1:
++		printk(KERN_ALERT "FLASH: hardware error.  Firmware may not be not flashed\n");
++		break;
++	    case -3:
++		printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform.  Firmware not flashed\n");
++		break;
++	    case -4:
++		printk(KERN_ALERT "FLASH: flash failed when partially complete.  System may not reboot\n");
++		break;
++	    default:
++		printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
++		break;
++	}
++}
++
++void rtas_flash_bypass_warning(void)
++{
++	printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
++	printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
++}
++
++
++void rtas_fw_restart(char *cmd)
++{
++	if (rtas_firmware_flash_list.next)
++		rtas_flash_firmware();
++	rtas_restart(cmd);
++}
++
++void rtas_fw_power_off(void)
++{
++	if (rtas_firmware_flash_list.next)
++		rtas_flash_bypass_warning();
++	rtas_power_off();
++}
++
++void rtas_fw_halt(void)
++{
++	if (rtas_firmware_flash_list.next)
++		rtas_flash_bypass_warning();
++	rtas_halt();
++}
++
++EXPORT_SYMBOL(rtas_firmware_flash_list);
+diff --git a/arch/powerpc/platforms/pseries/rtas-fw.h b/arch/powerpc/platforms/pseries/rtas-fw.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/rtas-fw.h
+@@ -0,0 +1,3 @@
++void rtas_fw_restart(char *cmd);
++void rtas_fw_power_off(void);
++void rtas_fw_halt(void);
+diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -0,0 +1,607 @@
++/*
++ *  64-bit pSeries and RS/6000 setup code.
++ *
++ *  Copyright (C) 1995  Linus Torvalds
++ *  Adapted from 'alpha' version by Gary Thomas
++ *  Modified by Cort Dougan (cort at cs.nmt.edu)
++ *  Modified by PPC64 Team, IBM Corp
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++/*
++ * bootup setup stuff..
++ */
++
++#undef DEBUG
++
++#include <linux/config.h>
++#include <linux/cpu.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/stddef.h>
++#include <linux/unistd.h>
++#include <linux/slab.h>
++#include <linux/user.h>
++#include <linux/a.out.h>
++#include <linux/tty.h>
++#include <linux/major.h>
++#include <linux/interrupt.h>
++#include <linux/reboot.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/console.h>
++#include <linux/pci.h>
++#include <linux/utsname.h>
++#include <linux/adb.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/irq.h>
++#include <linux/seq_file.h>
++#include <linux/root_dev.h>
++
++#include <asm/mmu.h>
++#include <asm/processor.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/prom.h>
++#include <asm/rtas.h>
++#include <asm/pci-bridge.h>
++#include <asm/iommu.h>
++#include <asm/dma.h>
++#include <asm/machdep.h>
++#include <asm/irq.h>
++#include <asm/time.h>
++#include <asm/nvram.h>
++#include <asm/plpar_wrappers.h>
++#include "xics.h"
++#include <asm/firmware.h>
++#include <asm/pmc.h>
++#include <asm/mpic.h>
++#include <asm/ppc-pci.h>
++#include <asm/i8259.h>
++#include <asm/udbg.h>
++
++#include "rtas-fw.h"
++
++#ifdef DEBUG
++#define DBG(fmt...) udbg_printf(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++extern void find_udbg_vterm(void);
++extern void system_reset_fwnmi(void);	/* from head.S */
++extern void machine_check_fwnmi(void);	/* from head.S */
++extern void generic_find_legacy_serial_ports(u64 *physport,
++		unsigned int *default_speed);
++
++int fwnmi_active;  /* TRUE if an FWNMI handler is present */
++
++extern void pSeries_system_reset_exception(struct pt_regs *regs);
++extern int pSeries_machine_check_exception(struct pt_regs *regs);
++
++static void pseries_shared_idle(void);
++static void pseries_dedicated_idle(void);
++
++struct mpic *pSeries_mpic;
++
++void pSeries_show_cpuinfo(struct seq_file *m)
++{
++	struct device_node *root;
++	const char *model = "";
++
++	root = of_find_node_by_path("/");
++	if (root)
++		model = get_property(root, "model", NULL);
++	seq_printf(m, "machine\t\t: CHRP %s\n", model);
++	of_node_put(root);
++}
++
++/* Initialize firmware assisted non-maskable interrupts if
++ * the firmware supports this feature.
++ *
++ */
++static void __init fwnmi_init(void)
++{
++	int ret;
++	int ibm_nmi_register = rtas_token("ibm,nmi-register");
++	if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
++		return;
++	ret = rtas_call(ibm_nmi_register, 2, 1, NULL,
++			__pa((unsigned long)system_reset_fwnmi),
++			__pa((unsigned long)machine_check_fwnmi));
++	if (ret == 0)
++		fwnmi_active = 1;
++}
++
++static void __init pSeries_init_mpic(void)
++{
++        unsigned int *addrp;
++	struct device_node *np;
++	unsigned long intack = 0;
++
++	/* All ISUs are setup, complete initialization */
++	mpic_init(pSeries_mpic);
++
++	/* Check what kind of cascade ACK we have */
++        if (!(np = of_find_node_by_name(NULL, "pci"))
++            || !(addrp = (unsigned int *)
++                 get_property(np, "8259-interrupt-acknowledge", NULL)))
++                printk(KERN_ERR "Cannot find pci to get ack address\n");
++        else
++		intack = addrp[prom_n_addr_cells(np)-1];
++	of_node_put(np);
++
++	/* Setup the legacy interrupts & controller */
++	i8259_init(intack, 0);
++
++	/* Hook cascade to mpic */
++	mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL);
++}
++
++static void __init pSeries_setup_mpic(void)
++{
++	unsigned int *opprop;
++	unsigned long openpic_addr = 0;
++        unsigned char senses[NR_IRQS - NUM_ISA_INTERRUPTS];
++        struct device_node *root;
++	int irq_count;
++
++	/* Find the Open PIC if present */
++	root = of_find_node_by_path("/");
++	opprop = (unsigned int *) get_property(root, "platform-open-pic", NULL);
++	if (opprop != 0) {
++		int n = prom_n_addr_cells(root);
++
++		for (openpic_addr = 0; n > 0; --n)
++			openpic_addr = (openpic_addr << 32) + *opprop++;
++		printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
++	}
++	of_node_put(root);
++
++	BUG_ON(openpic_addr == 0);
++
++	/* Get the sense values from OF */
++	prom_get_irq_senses(senses, NUM_ISA_INTERRUPTS, NR_IRQS);
++	
++	/* Setup the openpic driver */
++	irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
++	pSeries_mpic = mpic_alloc(openpic_addr, MPIC_PRIMARY,
++				  16, 16, irq_count, /* isu size, irq offset, irq count */ 
++				  NR_IRQS - 4, /* ipi offset */
++				  senses, irq_count, /* sense & sense size */
++				  " MPIC     ");
++}
++
++static void pseries_lpar_enable_pmcs(void)
++{
++	unsigned long set, reset;
++
++	power4_enable_pmcs();
++
++	set = 1UL << 63;
++	reset = 0;
++	plpar_hcall_norets(H_PERFMON, set, reset);
++
++	/* instruct hypervisor to maintain PMCs */
++	if (firmware_has_feature(FW_FEATURE_SPLPAR))
++		get_paca()->lppaca.pmcregs_in_use = 1;
++}
++
++static void __init pSeries_setup_arch(void)
++{
++	/* Fixup ppc_md depending on the type of interrupt controller */
++	if (ppc64_interrupt_controller == IC_OPEN_PIC) {
++		ppc_md.init_IRQ       = pSeries_init_mpic;
++		ppc_md.get_irq        = mpic_get_irq;
++	 	ppc_md.cpu_irq_down   = mpic_teardown_this_cpu;
++		/* Allocate the mpic now, so that find_and_init_phbs() can
++		 * fill the ISUs */
++		pSeries_setup_mpic();
++	} else {
++		ppc_md.init_IRQ       = xics_init_IRQ;
++		ppc_md.get_irq        = xics_get_irq;
++		ppc_md.cpu_irq_down   = xics_teardown_cpu;
++	}
++
++#ifdef CONFIG_SMP
++	smp_init_pSeries();
++#endif
++	/* openpic global configuration register (64-bit format). */
++	/* openpic Interrupt Source Unit pointer (64-bit format). */
++	/* python0 facility area (mmio) (64-bit format) REAL address. */
++
++	/* init to some ~sane value until calibrate_delay() runs */
++	loops_per_jiffy = 50000000;
++
++	if (ROOT_DEV == 0) {
++		printk("No ramdisk, default root is /dev/sda2\n");
++		ROOT_DEV = Root_SDA2;
++	}
++
++	fwnmi_init();
++
++	/* Find and initialize PCI host bridges */
++	init_pci_config_tokens();
++	find_and_init_phbs();
++	eeh_init();
++
++	pSeries_nvram_init();
++
++	/* Choose an idle loop */
++	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
++		vpa_init(boot_cpuid);
++		if (get_paca()->lppaca.shared_proc) {
++			printk(KERN_INFO "Using shared processor idle loop\n");
++			ppc_md.idle_loop = pseries_shared_idle;
++		} else {
++			printk(KERN_INFO "Using dedicated idle loop\n");
++			ppc_md.idle_loop = pseries_dedicated_idle;
++		}
++	} else {
++		printk(KERN_INFO "Using default idle loop\n");
++		ppc_md.idle_loop = default_idle;
++	}
++
++	if (systemcfg->platform & PLATFORM_LPAR)
++		ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
++	else
++		ppc_md.enable_pmcs = power4_enable_pmcs;
++}
++
++static int __init pSeries_init_panel(void)
++{
++	/* Manually leave the kernel version on the panel. */
++	ppc_md.progress("Linux ppc64\n", 0);
++	ppc_md.progress(system_utsname.version, 0);
++
++	return 0;
++}
++arch_initcall(pSeries_init_panel);
++
++
++/* Build up the ppc64_firmware_features bitmask field
++ * using contents of device-tree/ibm,hypertas-functions.
++ * Ultimately this functionality may be moved into prom.c prom_init().
++ */
++static void __init fw_feature_init(void)
++{
++	struct device_node * dn;
++	char * hypertas;
++	unsigned int len;
++
++	DBG(" -> fw_feature_init()\n");
++
++	ppc64_firmware_features = 0;
++	dn = of_find_node_by_path("/rtas");
++	if (dn == NULL) {
++		printk(KERN_ERR "WARNING ! Cannot find RTAS in device-tree !\n");
++		goto no_rtas;
++	}
++
++	hypertas = get_property(dn, "ibm,hypertas-functions", &len);
++	if (hypertas) {
++		while (len > 0){
++			int i, hypertas_len;
++			/* check value against table of strings */
++			for(i=0; i < FIRMWARE_MAX_FEATURES ;i++) {
++				if ((firmware_features_table[i].name) &&
++				    (strcmp(firmware_features_table[i].name,hypertas))==0) {
++					/* we have a match */
++					ppc64_firmware_features |= 
++						(firmware_features_table[i].val);
++					break;
++				} 
++			}
++			hypertas_len = strlen(hypertas);
++			len -= hypertas_len +1;
++			hypertas+= hypertas_len +1;
++		}
++	}
++
++	of_node_put(dn);
++ no_rtas:
++	printk(KERN_INFO "firmware_features = 0x%lx\n", 
++	       ppc64_firmware_features);
++
++	DBG(" <- fw_feature_init()\n");
++}
++
++
++static  void __init pSeries_discover_pic(void)
++{
++	struct device_node *np;
++	char *typep;
++
++	/*
++	 * Setup interrupt mapping options that are needed for finish_device_tree
++	 * to properly parse the OF interrupt tree & do the virtual irq mapping
++	 */
++	__irq_offset_value = NUM_ISA_INTERRUPTS;
++	ppc64_interrupt_controller = IC_INVALID;
++	for (np = NULL; (np = of_find_node_by_name(np, "interrupt-controller"));) {
++		typep = (char *)get_property(np, "compatible", NULL);
++		if (strstr(typep, "open-pic"))
++			ppc64_interrupt_controller = IC_OPEN_PIC;
++		else if (strstr(typep, "ppc-xicp"))
++			ppc64_interrupt_controller = IC_PPC_XIC;
++		else
++			printk("pSeries_discover_pic: failed to recognize"
++			       " interrupt-controller\n");
++		break;
++	}
++}
++
++static void pSeries_mach_cpu_die(void)
++{
++	local_irq_disable();
++	idle_task_exit();
++	/* Some hardware requires clearing the CPPR, while other hardware does not
++	 * it is safe either way
++	 */
++	pSeriesLP_cppr_info(0, 0);
++	rtas_stop_self();
++	/* Should never get here... */
++	BUG();
++	for(;;);
++}
++
++
++/*
++ * Early initialization.  Relocation is on but do not reference unbolted pages
++ */
++static void __init pSeries_init_early(void)
++{
++	void *comport;
++	int iommu_off = 0;
++	unsigned int default_speed;
++	u64 physport;
++
++	DBG(" -> pSeries_init_early()\n");
++
++	fw_feature_init();
++	
++	if (systemcfg->platform & PLATFORM_LPAR)
++		hpte_init_lpar();
++	else {
++		hpte_init_native();
++		iommu_off = (of_chosen &&
++			     get_property(of_chosen, "linux,iommu-off", NULL));
++	}
++
++	generic_find_legacy_serial_ports(&physport, &default_speed);
++
++	if (systemcfg->platform & PLATFORM_LPAR)
++		find_udbg_vterm();
++	else if (physport) {
++		/* Map the uart for udbg. */
++		comport = (void *)ioremap(physport, 16);
++		udbg_init_uart(comport, default_speed);
++
++		DBG("Hello World !\n");
++	}
++
++
++	iommu_init_early_pSeries();
++
++	pSeries_discover_pic();
++
++	DBG(" <- pSeries_init_early()\n");
++}
++
++
++static int pSeries_check_legacy_ioport(unsigned int baseport)
++{
++	struct device_node *np;
++
++#define I8042_DATA_REG	0x60
++#define FDC_BASE	0x3f0
++
++
++	switch(baseport) {
++	case I8042_DATA_REG:
++		np = of_find_node_by_type(NULL, "8042");
++		if (np == NULL)
++			return -ENODEV;
++		of_node_put(np);
++		break;
++	case FDC_BASE:
++		np = of_find_node_by_type(NULL, "fdc");
++		if (np == NULL)
++			return -ENODEV;
++		of_node_put(np);
++		break;
++	}
++	return 0;
++}
++
++/*
++ * Called very early, MMU is off, device-tree isn't unflattened
++ */
++extern struct machdep_calls pSeries_md;
++
++static int __init pSeries_probe(int platform)
++{
++	if (platform != PLATFORM_PSERIES &&
++	    platform != PLATFORM_PSERIES_LPAR)
++		return 0;
++
++	/* if we have some ppc_md fixups for LPAR to do, do
++	 * it here ...
++	 */
++
++	return 1;
++}
++
++DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
++
++static inline void dedicated_idle_sleep(unsigned int cpu)
++{
++	struct paca_struct *ppaca = &paca[cpu ^ 1];
++
++	/* Only sleep if the other thread is not idle */
++	if (!(ppaca->lppaca.idle)) {
++		local_irq_disable();
++
++		/*
++		 * We are about to sleep the thread and so wont be polling any
++		 * more.
++		 */
++		clear_thread_flag(TIF_POLLING_NRFLAG);
++
++		/*
++		 * SMT dynamic mode. Cede will result in this thread going
++		 * dormant, if the partner thread is still doing work.  Thread
++		 * wakes up if partner goes idle, an interrupt is presented, or
++		 * a prod occurs.  Returning from the cede enables external
++		 * interrupts.
++		 */
++		if (!need_resched())
++			cede_processor();
++		else
++			local_irq_enable();
++	} else {
++		/*
++		 * Give the HV an opportunity at the processor, since we are
++		 * not doing any work.
++		 */
++		poll_pending();
++	}
++}
++
++static void pseries_dedicated_idle(void)
++{ 
++	long oldval;
++	struct paca_struct *lpaca = get_paca();
++	unsigned int cpu = smp_processor_id();
++	unsigned long start_snooze;
++	unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
++
++	while (1) {
++		/*
++		 * Indicate to the HV that we are idle. Now would be
++		 * a good time to find other work to dispatch.
++		 */
++		lpaca->lppaca.idle = 1;
++
++		oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
++		if (!oldval) {
++			set_thread_flag(TIF_POLLING_NRFLAG);
++
++			start_snooze = __get_tb() +
++				*smt_snooze_delay * tb_ticks_per_usec;
++
++			while (!need_resched() && !cpu_is_offline(cpu)) {
++				ppc64_runlatch_off();
++
++				/*
++				 * Go into low thread priority and possibly
++				 * low power mode.
++				 */
++				HMT_low();
++				HMT_very_low();
++
++				if (*smt_snooze_delay != 0 &&
++				    __get_tb() > start_snooze) {
++					HMT_medium();
++					dedicated_idle_sleep(cpu);
++				}
++
++			}
++
++			HMT_medium();
++			clear_thread_flag(TIF_POLLING_NRFLAG);
++		} else {
++			set_need_resched();
++		}
++
++		lpaca->lppaca.idle = 0;
++		ppc64_runlatch_on();
++
++		schedule();
++
++		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
++			cpu_die();
++	}
++}
++
++static void pseries_shared_idle(void)
++{
++	struct paca_struct *lpaca = get_paca();
++	unsigned int cpu = smp_processor_id();
++
++	while (1) {
++		/*
++		 * Indicate to the HV that we are idle. Now would be
++		 * a good time to find other work to dispatch.
++		 */
++		lpaca->lppaca.idle = 1;
++
++		while (!need_resched() && !cpu_is_offline(cpu)) {
++			local_irq_disable();
++			ppc64_runlatch_off();
++
++			/*
++			 * Yield the processor to the hypervisor.  We return if
++			 * an external interrupt occurs (which are driven prior
++			 * to returning here) or if a prod occurs from another
++			 * processor. When returning here, external interrupts
++			 * are enabled.
++			 *
++			 * Check need_resched() again with interrupts disabled
++			 * to avoid a race.
++			 */
++			if (!need_resched())
++				cede_processor();
++			else
++				local_irq_enable();
++
++			HMT_medium();
++		}
++
++		lpaca->lppaca.idle = 0;
++		ppc64_runlatch_on();
++
++		schedule();
++
++		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
++			cpu_die();
++	}
++}
++
++static int pSeries_pci_probe_mode(struct pci_bus *bus)
++{
++	if (systemcfg->platform & PLATFORM_LPAR)
++		return PCI_PROBE_DEVTREE;
++	return PCI_PROBE_NORMAL;
++}
++
++struct machdep_calls __initdata pSeries_md = {
++	.probe			= pSeries_probe,
++	.setup_arch		= pSeries_setup_arch,
++	.init_early		= pSeries_init_early,
++	.show_cpuinfo		= pSeries_show_cpuinfo,
++	.log_error		= pSeries_log_error,
++	.pcibios_fixup		= pSeries_final_fixup,
++	.pci_probe_mode		= pSeries_pci_probe_mode,
++	.irq_bus_setup		= pSeries_irq_bus_setup,
++	.restart		= rtas_fw_restart,
++	.power_off		= rtas_fw_power_off,
++	.halt			= rtas_fw_halt,
++	.panic			= rtas_os_term,
++	.cpu_die		= pSeries_mach_cpu_die,
++	.get_boot_time		= rtas_get_boot_time,
++	.get_rtc_time		= rtas_get_rtc_time,
++	.set_rtc_time		= rtas_set_rtc_time,
++	.calibrate_decr		= generic_calibrate_decr,
++	.progress		= rtas_progress,
++	.check_legacy_ioport	= pSeries_check_legacy_ioport,
++	.system_reset_exception = pSeries_system_reset_exception,
++	.machine_check_exception = pSeries_machine_check_exception,
++};
+diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/smp.c
+@@ -0,0 +1,471 @@
++/*
++ * SMP support for pSeries machines.
++ *
++ * Dave Engebretsen, Peter Bergner, and
++ * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
++ *
++ * Plus various changes from other IBM teams...
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/spinlock.h>
++#include <linux/cache.h>
++#include <linux/err.h>
++#include <linux/sysdev.h>
++#include <linux/cpu.h>
++
++#include <asm/ptrace.h>
++#include <asm/atomic.h>
++#include <asm/irq.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/smp.h>
++#include <asm/paca.h>
++#include <asm/time.h>
++#include <asm/machdep.h>
++#include "xics.h"
++#include <asm/cputable.h>
++#include <asm/firmware.h>
++#include <asm/system.h>
++#include <asm/rtas.h>
++#include <asm/plpar_wrappers.h>
++#include <asm/pSeries_reconfig.h>
++#include <asm/mpic.h>
++
++#ifdef DEBUG
++#define DBG(fmt...) udbg_printf(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++/*
++ * The primary thread of each non-boot processor is recorded here before
++ * smp init.
++ */
++static cpumask_t of_spin_map;
++
++extern void pSeries_secondary_smp_init(unsigned long);
++
++#ifdef CONFIG_HOTPLUG_CPU
++
++/* Get state of physical CPU.
++ * Return codes:
++ *	0	- The processor is in the RTAS stopped state
++ *	1	- stop-self is in progress
++ *	2	- The processor is not in the RTAS stopped state
++ *	-1	- Hardware Error
++ *	-2	- Hardware Busy, Try again later.
++ */
++static int query_cpu_stopped(unsigned int pcpu)
++{
++	int cpu_status;
++	int status, qcss_tok;
++
++	qcss_tok = rtas_token("query-cpu-stopped-state");
++	if (qcss_tok == RTAS_UNKNOWN_SERVICE)
++		return -1;
++	status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu);
++	if (status != 0) {
++		printk(KERN_ERR
++		       "RTAS query-cpu-stopped-state failed: %i\n", status);
++		return status;
++	}
++
++	return cpu_status;
++}
++
++int pSeries_cpu_disable(void)
++{
++	int cpu = smp_processor_id();
++
++	cpu_clear(cpu, cpu_online_map);
++	systemcfg->processorCount--;
++
++	/*fix boot_cpuid here*/
++	if (cpu == boot_cpuid)
++		boot_cpuid = any_online_cpu(cpu_online_map);
++
++	/* FIXME: abstract this to not be platform specific later on */
++	xics_migrate_irqs_away();
++	return 0;
++}
++
++void pSeries_cpu_die(unsigned int cpu)
++{
++	int tries;
++	int cpu_status;
++	unsigned int pcpu = get_hard_smp_processor_id(cpu);
++
++	for (tries = 0; tries < 25; tries++) {
++		cpu_status = query_cpu_stopped(pcpu);
++		if (cpu_status == 0 || cpu_status == -1)
++			break;
++		msleep(200);
++	}
++	if (cpu_status != 0) {
++		printk("Querying DEAD? cpu %i (%i) shows %i\n",
++		       cpu, pcpu, cpu_status);
++	}
++
++	/* Isolation and deallocation are definatly done by
++	 * drslot_chrp_cpu.  If they were not they would be
++	 * done here.  Change isolate state to Isolate and
++	 * change allocation-state to Unusable.
++	 */
++	paca[cpu].cpu_start = 0;
++}
++
++/*
++ * Update cpu_present_map and paca(s) for a new cpu node.  The wrinkle
++ * here is that a cpu device node may represent up to two logical cpus
++ * in the SMT case.  We must honor the assumption in other code that
++ * the logical ids for sibling SMT threads x and y are adjacent, such
++ * that x^1 == y and y^1 == x.
++ */
++static int pSeries_add_processor(struct device_node *np)
++{
++	unsigned int cpu;
++	cpumask_t candidate_map, tmp = CPU_MASK_NONE;
++	int err = -ENOSPC, len, nthreads, i;
++	u32 *intserv;
++
++	intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len);
++	if (!intserv)
++		return 0;
++
++	nthreads = len / sizeof(u32);
++	for (i = 0; i < nthreads; i++)
++		cpu_set(i, tmp);
++
++	lock_cpu_hotplug();
++
++	BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));
++
++	/* Get a bitmap of unoccupied slots. */
++	cpus_xor(candidate_map, cpu_possible_map, cpu_present_map);
++	if (cpus_empty(candidate_map)) {
++		/* If we get here, it most likely means that NR_CPUS is
++		 * less than the partition's max processors setting.
++		 */
++		printk(KERN_ERR "Cannot add cpu %s; this system configuration"
++		       " supports %d logical cpus.\n", np->full_name,
++		       cpus_weight(cpu_possible_map));
++		goto out_unlock;
++	}
++
++	while (!cpus_empty(tmp))
++		if (cpus_subset(tmp, candidate_map))
++			/* Found a range where we can insert the new cpu(s) */
++			break;
++		else
++			cpus_shift_left(tmp, tmp, nthreads);
++
++	if (cpus_empty(tmp)) {
++		printk(KERN_ERR "Unable to find space in cpu_present_map for"
++		       " processor %s with %d thread(s)\n", np->name,
++		       nthreads);
++		goto out_unlock;
++	}
++
++	for_each_cpu_mask(cpu, tmp) {
++		BUG_ON(cpu_isset(cpu, cpu_present_map));
++		cpu_set(cpu, cpu_present_map);
++		set_hard_smp_processor_id(cpu, *intserv++);
++	}
++	err = 0;
++out_unlock:
++	unlock_cpu_hotplug();
++	return err;
++}
++
++/*
++ * Update the present map for a cpu node which is going away, and set
++ * the hard id in the paca(s) to -1 to be consistent with boot time
++ * convention for non-present cpus.
++ */
++static void pSeries_remove_processor(struct device_node *np)
++{
++	unsigned int cpu;
++	int len, nthreads, i;
++	u32 *intserv;
++
++	intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len);
++	if (!intserv)
++		return;
++
++	nthreads = len / sizeof(u32);
++
++	lock_cpu_hotplug();
++	for (i = 0; i < nthreads; i++) {
++		for_each_present_cpu(cpu) {
++			if (get_hard_smp_processor_id(cpu) != intserv[i])
++				continue;
++			BUG_ON(cpu_online(cpu));
++			cpu_clear(cpu, cpu_present_map);
++			set_hard_smp_processor_id(cpu, -1);
++			break;
++		}
++		if (cpu == NR_CPUS)
++			printk(KERN_WARNING "Could not find cpu to remove "
++			       "with physical id 0x%x\n", intserv[i]);
++	}
++	unlock_cpu_hotplug();
++}
++
++static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node)
++{
++	int err = NOTIFY_OK;
++
++	switch (action) {
++	case PSERIES_RECONFIG_ADD:
++		if (pSeries_add_processor(node))
++			err = NOTIFY_BAD;
++		break;
++	case PSERIES_RECONFIG_REMOVE:
++		pSeries_remove_processor(node);
++		break;
++	default:
++		err = NOTIFY_DONE;
++		break;
++	}
++	return err;
++}
++
++static struct notifier_block pSeries_smp_nb = {
++	.notifier_call = pSeries_smp_notifier,
++};
++
++#endif /* CONFIG_HOTPLUG_CPU */
++
++/**
++ * smp_startup_cpu() - start the given cpu
++ *
++ * At boot time, there is nothing to do for primary threads which were
++ * started from Open Firmware.  For anything else, call RTAS with the
++ * appropriate start location.
++ *
++ * Returns:
++ *	0	- failure
++ *	1	- success
++ */
++static inline int __devinit smp_startup_cpu(unsigned int lcpu)
++{
++	int status;
++	unsigned long start_here = __pa((u32)*((unsigned long *)
++					       pSeries_secondary_smp_init));
++	unsigned int pcpu;
++	int start_cpu;
++
++	if (cpu_isset(lcpu, of_spin_map))
++		/* Already started by OF and sitting in spin loop */
++		return 1;
++
++	pcpu = get_hard_smp_processor_id(lcpu);
++
++	/* Fixup atomic count: it exited inside IRQ handler. */
++	paca[lcpu].__current->thread_info->preempt_count	= 0;
++
++	/* 
++	 * If the RTAS start-cpu token does not exist then presume the
++	 * cpu is already spinning.
++	 */
++	start_cpu = rtas_token("start-cpu");
++	if (start_cpu == RTAS_UNKNOWN_SERVICE)
++		return 1;
++
++	status = rtas_call(start_cpu, 3, 1, NULL, pcpu, start_here, lcpu);
++	if (status != 0) {
++		printk(KERN_ERR "start-cpu failed: %i\n", status);
++		return 0;
++	}
++
++	return 1;
++}
++
++#ifdef CONFIG_XICS
++static inline void smp_xics_do_message(int cpu, int msg)
++{
++	set_bit(msg, &xics_ipi_message[cpu].value);
++	mb();
++	xics_cause_IPI(cpu);
++}
++
++static void smp_xics_message_pass(int target, int msg)
++{
++	unsigned int i;
++
++	if (target < NR_CPUS) {
++		smp_xics_do_message(target, msg);
++	} else {
++		for_each_online_cpu(i) {
++			if (target == MSG_ALL_BUT_SELF
++			    && i == smp_processor_id())
++				continue;
++			smp_xics_do_message(i, msg);
++		}
++	}
++}
++
++static int __init smp_xics_probe(void)
++{
++	xics_request_IPIs();
++
++	return cpus_weight(cpu_possible_map);
++}
++
++static void __devinit smp_xics_setup_cpu(int cpu)
++{
++	if (cpu != boot_cpuid)
++		xics_setup_cpu();
++
++	if (firmware_has_feature(FW_FEATURE_SPLPAR))
++		vpa_init(cpu);
++
++	cpu_clear(cpu, of_spin_map);
++
++}
++#endif /* CONFIG_XICS */
++
++static DEFINE_SPINLOCK(timebase_lock);
++static unsigned long timebase = 0;
++
++static void __devinit pSeries_give_timebase(void)
++{
++	spin_lock(&timebase_lock);
++	rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
++	timebase = get_tb();
++	spin_unlock(&timebase_lock);
++
++	while (timebase)
++		barrier();
++	rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
++}
++
++static void __devinit pSeries_take_timebase(void)
++{
++	while (!timebase)
++		barrier();
++	spin_lock(&timebase_lock);
++	set_tb(timebase >> 32, timebase & 0xffffffff);
++	timebase = 0;
++	spin_unlock(&timebase_lock);
++}
++
++static void __devinit smp_pSeries_kick_cpu(int nr)
++{
++	BUG_ON(nr < 0 || nr >= NR_CPUS);
++
++	if (!smp_startup_cpu(nr))
++		return;
++
++	/*
++	 * The processor is currently spinning, waiting for the
++	 * cpu_start field to become non-zero After we set cpu_start,
++	 * the processor will continue on to secondary_start
++	 */
++	paca[nr].cpu_start = 1;
++}
++
++static int smp_pSeries_cpu_bootable(unsigned int nr)
++{
++	/* Special case - we inhibit secondary thread startup
++	 * during boot if the user requests it.  Odd-numbered
++	 * cpus are assumed to be secondary threads.
++	 */
++	if (system_state < SYSTEM_RUNNING &&
++	    cpu_has_feature(CPU_FTR_SMT) &&
++	    !smt_enabled_at_boot && nr % 2 != 0)
++		return 0;
++
++	return 1;
++}
++#ifdef CONFIG_MPIC
++static struct smp_ops_t pSeries_mpic_smp_ops = {
++	.message_pass	= smp_mpic_message_pass,
++	.probe		= smp_mpic_probe,
++	.kick_cpu	= smp_pSeries_kick_cpu,
++	.setup_cpu	= smp_mpic_setup_cpu,
++};
++#endif
++#ifdef CONFIG_XICS
++static struct smp_ops_t pSeries_xics_smp_ops = {
++	.message_pass	= smp_xics_message_pass,
++	.probe		= smp_xics_probe,
++	.kick_cpu	= smp_pSeries_kick_cpu,
++	.setup_cpu	= smp_xics_setup_cpu,
++	.cpu_bootable	= smp_pSeries_cpu_bootable,
++};
++#endif
++
++/* This is called very early */
++void __init smp_init_pSeries(void)
++{
++	int i;
++
++	DBG(" -> smp_init_pSeries()\n");
++
++	switch (ppc64_interrupt_controller) {
++#ifdef CONFIG_MPIC
++	case IC_OPEN_PIC:
++		smp_ops = &pSeries_mpic_smp_ops;
++		break;
++#endif
++#ifdef CONFIG_XICS
++	case IC_PPC_XIC:
++		smp_ops = &pSeries_xics_smp_ops;
++		break;
++#endif
++	default:
++		panic("Invalid interrupt controller");
++	}
++
++#ifdef CONFIG_HOTPLUG_CPU
++	smp_ops->cpu_disable = pSeries_cpu_disable;
++	smp_ops->cpu_die = pSeries_cpu_die;
++
++	/* Processors can be added/removed only on LPAR */
++	if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
++		pSeries_reconfig_notifier_register(&pSeries_smp_nb);
++#endif
++
++	/* Mark threads which are still spinning in hold loops. */
++	if (cpu_has_feature(CPU_FTR_SMT)) {
++		for_each_present_cpu(i) { 
++			if (i % 2 == 0)
++				/*
++				 * Even-numbered logical cpus correspond to
++				 * primary threads.
++				 */
++				cpu_set(i, of_spin_map);
++		}
++	} else {
++		of_spin_map = cpu_present_map;
++	}
++
++	cpu_clear(boot_cpuid, of_spin_map);
++
++	/* Non-lpar has additional take/give timebase */
++	if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
++		smp_ops->give_timebase = pSeries_give_timebase;
++		smp_ops->take_timebase = pSeries_take_timebase;
++	}
++
++	DBG(" <- smp_init_pSeries()\n");
++}
++
+diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/vio.c
+@@ -0,0 +1,274 @@
++/*
++ * IBM PowerPC pSeries Virtual I/O Infrastructure Support.
++ *
++ *    Copyright (c) 2003-2005 IBM Corp.
++ *     Dave Engebretsen engebret at us.ibm.com
++ *     Santiago Leon santil at us.ibm.com
++ *     Hollis Blanchard <hollisb at us.ibm.com>
++ *     Stephen Rothwell
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/module.h>
++#include <linux/mm.h>
++#include <linux/kobject.h>
++#include <asm/iommu.h>
++#include <asm/dma.h>
++#include <asm/prom.h>
++#include <asm/vio.h>
++#include <asm/hvcall.h>
++#include <asm/tce.h>
++
++extern struct subsystem devices_subsys; /* needed for vio_find_name() */
++
++static void probe_bus_pseries(void)
++{
++	struct device_node *node_vroot, *of_node;
++
++	node_vroot = find_devices("vdevice");
++	if ((node_vroot == NULL) || (node_vroot->child == NULL))
++		/* this machine doesn't do virtual IO, and that's ok */
++		return;
++
++	/*
++	 * Create struct vio_devices for each virtual device in the device tree.
++	 * Drivers will associate with them later.
++	 */
++	for (of_node = node_vroot->child; of_node != NULL;
++			of_node = of_node->sibling) {
++		printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node);
++		vio_register_device_node(of_node);
++	}
++}
++
++/**
++ * vio_match_device_pseries: - Tell if a pSeries VIO device matches a
++ *	vio_device_id
++ */
++static int vio_match_device_pseries(const struct vio_device_id *id,
++		const struct vio_dev *dev)
++{
++	return (strncmp(dev->type, id->type, strlen(id->type)) == 0) &&
++			device_is_compatible(dev->dev.platform_data, id->compat);
++}
++
++static void vio_release_device_pseries(struct device *dev)
++{
++	/* XXX free TCE table */
++	of_node_put(dev->platform_data);
++}
++
++static ssize_t viodev_show_devspec(struct device *dev,
++		struct device_attribute *attr, char *buf)
++{
++	struct device_node *of_node = dev->platform_data;
++
++	return sprintf(buf, "%s\n", of_node->full_name);
++}
++DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
++
++static void vio_unregister_device_pseries(struct vio_dev *viodev)
++{
++	device_remove_file(&viodev->dev, &dev_attr_devspec);
++}
++
++static struct vio_bus_ops vio_bus_ops_pseries = {
++	.match = vio_match_device_pseries,
++	.unregister_device = vio_unregister_device_pseries,
++	.release_device = vio_release_device_pseries,
++};
++
++/**
++ * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
++ */
++static int __init vio_bus_init_pseries(void)
++{
++	int err;
++
++	err = vio_bus_init(&vio_bus_ops_pseries);
++	if (err == 0)
++		probe_bus_pseries();
++	return err;
++}
++
++__initcall(vio_bus_init_pseries);
++
++/**
++ * vio_build_iommu_table: - gets the dma information from OF and
++ *	builds the TCE tree.
++ * @dev: the virtual device.
++ *
++ * Returns a pointer to the built tce tree, or NULL if it can't
++ * find property.
++*/
++static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
++{
++	unsigned int *dma_window;
++	struct iommu_table *newTceTable;
++	unsigned long offset;
++	int dma_window_property_size;
++
++	dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
++	if(!dma_window) {
++		return NULL;
++	}
++
++	newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
++
++	/*  There should be some code to extract the phys-encoded offset
++		using prom_n_addr_cells(). However, according to a comment
++		on earlier versions, it's always zero, so we don't bother */
++	offset = dma_window[1] >>  PAGE_SHIFT;
++
++	/* TCE table size - measured in tce entries */
++	newTceTable->it_size		= dma_window[4] >> PAGE_SHIFT;
++	/* offset for VIO should always be 0 */
++	newTceTable->it_offset		= offset;
++	newTceTable->it_busno		= 0;
++	newTceTable->it_index		= (unsigned long)dma_window[0];
++	newTceTable->it_type		= TCE_VB;
++
++	return iommu_init_table(newTceTable);
++}
++
++/**
++ * vio_register_device_node: - Register a new vio device.
++ * @of_node:	The OF node for this device.
++ *
++ * Creates and initializes a vio_dev structure from the data in
++ * of_node (dev.platform_data) and adds it to the list of virtual devices.
++ * Returns a pointer to the created vio_dev or NULL if node has
++ * NULL device_type or compatible fields.
++ */
++struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
++{
++	struct vio_dev *viodev;
++	unsigned int *unit_address;
++	unsigned int *irq_p;
++
++	/* we need the 'device_type' property, in order to match with drivers */
++	if ((NULL == of_node->type)) {
++		printk(KERN_WARNING
++			"%s: node %s missing 'device_type'\n", __FUNCTION__,
++			of_node->name ? of_node->name : "<unknown>");
++		return NULL;
++	}
++
++	unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
++	if (!unit_address) {
++		printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__,
++			of_node->name ? of_node->name : "<unknown>");
++		return NULL;
++	}
++
++	/* allocate a vio_dev for this node */
++	viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
++	if (!viodev) {
++		return NULL;
++	}
++	memset(viodev, 0, sizeof(struct vio_dev));
++
++	viodev->dev.platform_data = of_node_get(of_node);
++
++	viodev->irq = NO_IRQ;
++	irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
++	if (irq_p) {
++		int virq = virt_irq_create_mapping(*irq_p);
++		if (virq == NO_IRQ) {
++			printk(KERN_ERR "Unable to allocate interrupt "
++			       "number for %s\n", of_node->full_name);
++		} else
++			viodev->irq = irq_offset_up(virq);
++	}
++
++	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
++	viodev->name = of_node->name;
++	viodev->type = of_node->type;
++	viodev->unit_address = *unit_address;
++	viodev->iommu_table = vio_build_iommu_table(viodev);
++
++	/* register with generic device framework */
++	if (vio_register_device(viodev) == NULL) {
++		/* XXX free TCE table */
++		kfree(viodev);
++		return NULL;
++	}
++	device_create_file(&viodev->dev, &dev_attr_devspec);
++
++	return viodev;
++}
++EXPORT_SYMBOL(vio_register_device_node);
++
++/**
++ * vio_get_attribute: - get attribute for virtual device
++ * @vdev:	The vio device to get property.
++ * @which:	The property/attribute to be extracted.
++ * @length:	Pointer to length of returned data size (unused if NULL).
++ *
++ * Calls prom.c's get_property() to return the value of the
++ * attribute specified by the preprocessor constant @which
++*/
++const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
++{
++	return get_property(vdev->dev.platform_data, (char*)which, length);
++}
++EXPORT_SYMBOL(vio_get_attribute);
++
++/* vio_find_name() - internal because only vio.c knows how we formatted the
++ * kobject name
++ * XXX once vio_bus_type.devices is actually used as a kset in
++ * drivers/base/bus.c, this function should be removed in favor of
++ * "device_find(kobj_name, &vio_bus_type)"
++ */
++static struct vio_dev *vio_find_name(const char *kobj_name)
++{
++	struct kobject *found;
++
++	found = kset_find_obj(&devices_subsys.kset, kobj_name);
++	if (!found)
++		return NULL;
++
++	return to_vio_dev(container_of(found, struct device, kobj));
++}
++
++/**
++ * vio_find_node - find an already-registered vio_dev
++ * @vnode: device_node of the virtual device we're looking for
++ */
++struct vio_dev *vio_find_node(struct device_node *vnode)
++{
++	uint32_t *unit_address;
++	char kobj_name[BUS_ID_SIZE];
++
++	/* construct the kobject name from the device node */
++	unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
++	if (!unit_address)
++		return NULL;
++	snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
++
++	return vio_find_name(kobj_name);
++}
++EXPORT_SYMBOL(vio_find_node);
++
++int vio_enable_interrupts(struct vio_dev *dev)
++{
++	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
++	if (rc != H_Success)
++		printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
++	return rc;
++}
++EXPORT_SYMBOL(vio_enable_interrupts);
++
++int vio_disable_interrupts(struct vio_dev *dev)
++{
++	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
++	if (rc != H_Success)
++		printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
++	return rc;
++}
++EXPORT_SYMBOL(vio_disable_interrupts);
+diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/xics.c
+@@ -0,0 +1,747 @@
++/*
++ * arch/powerpc/platforms/pseries/xics.c
++ *
++ * Copyright 2000 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.
++ */
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/threads.h>
++#include <linux/kernel.h>
++#include <linux/irq.h>
++#include <linux/smp.h>
++#include <linux/interrupt.h>
++#include <linux/signal.h>
++#include <linux/init.h>
++#include <linux/gfp.h>
++#include <linux/radix-tree.h>
++#include <linux/cpu.h>
++#include <asm/prom.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/smp.h>
++#include <asm/rtas.h>
++#include <asm/hvcall.h>
++#include <asm/machdep.h>
++#include <asm/i8259.h>
++
++#include "xics.h"
++
++static unsigned int xics_startup(unsigned int irq);
++static void xics_enable_irq(unsigned int irq);
++static void xics_disable_irq(unsigned int irq);
++static void xics_mask_and_ack_irq(unsigned int irq);
++static void xics_end_irq(unsigned int irq);
++static void xics_set_affinity(unsigned int irq_nr, cpumask_t cpumask);
++
++static struct hw_interrupt_type xics_pic = {
++	.typename = " XICS     ",
++	.startup = xics_startup,
++	.enable = xics_enable_irq,
++	.disable = xics_disable_irq,
++	.ack = xics_mask_and_ack_irq,
++	.end = xics_end_irq,
++	.set_affinity = xics_set_affinity
++};
++
++static struct hw_interrupt_type xics_8259_pic = {
++	.typename = " XICS/8259",
++	.ack = xics_mask_and_ack_irq,
++};
++
++/* This is used to map real irq numbers to virtual */
++static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC);
++
++#define XICS_IPI		2
++#define XICS_IRQ_SPURIOUS	0
++
++/* Want a priority other than 0.  Various HW issues require this. */
++#define	DEFAULT_PRIORITY	5
++
++/*
++ * Mark IPIs as higher priority so we can take them inside interrupts that
++ * arent marked SA_INTERRUPT
++ */
++#define IPI_PRIORITY		4
++
++struct xics_ipl {
++	union {
++		u32 word;
++		u8 bytes[4];
++	} xirr_poll;
++	union {
++		u32 word;
++		u8 bytes[4];
++	} xirr;
++	u32 dummy;
++	union {
++		u32 word;
++		u8 bytes[4];
++	} qirr;
++};
++
++static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS];
++
++static int xics_irq_8259_cascade = 0;
++static int xics_irq_8259_cascade_real = 0;
++static unsigned int default_server = 0xFF;
++static unsigned int default_distrib_server = 0;
++static unsigned int interrupt_server_size = 8;
++
++/*
++ * XICS only has a single IPI, so encode the messages per CPU
++ */
++struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
++
++/* RTAS service tokens */
++static int ibm_get_xive;
++static int ibm_set_xive;
++static int ibm_int_on;
++static int ibm_int_off;
++
++typedef struct {
++	int (*xirr_info_get)(int cpu);
++	void (*xirr_info_set)(int cpu, int val);
++	void (*cppr_info)(int cpu, u8 val);
++	void (*qirr_info)(int cpu, u8 val);
++} xics_ops;
++
++
++/* SMP */
++
++static int pSeries_xirr_info_get(int n_cpu)
++{
++	return in_be32(&xics_per_cpu[n_cpu]->xirr.word);
++}
++
++static void pSeries_xirr_info_set(int n_cpu, int value)
++{
++	out_be32(&xics_per_cpu[n_cpu]->xirr.word, value);
++}
++
++static void pSeries_cppr_info(int n_cpu, u8 value)
++{
++	out_8(&xics_per_cpu[n_cpu]->xirr.bytes[0], value);
++}
++
++static void pSeries_qirr_info(int n_cpu, u8 value)
++{
++	out_8(&xics_per_cpu[n_cpu]->qirr.bytes[0], value);
++}
++
++static xics_ops pSeries_ops = {
++	pSeries_xirr_info_get,
++	pSeries_xirr_info_set,
++	pSeries_cppr_info,
++	pSeries_qirr_info
++};
++
++static xics_ops *ops = &pSeries_ops;
++
++
++/* LPAR */
++
++static inline long plpar_eoi(unsigned long xirr)
++{
++	return plpar_hcall_norets(H_EOI, xirr);
++}
++
++static inline long plpar_cppr(unsigned long cppr)
++{
++	return plpar_hcall_norets(H_CPPR, cppr);
++}
++
++static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
++{
++	return plpar_hcall_norets(H_IPI, servernum, mfrr);
++}
++
++static inline long plpar_xirr(unsigned long *xirr_ret)
++{
++	unsigned long dummy;
++	return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy);
++}
++
++static int pSeriesLP_xirr_info_get(int n_cpu)
++{
++	unsigned long lpar_rc;
++	unsigned long return_value;
++
++	lpar_rc = plpar_xirr(&return_value);
++	if (lpar_rc != H_Success)
++		panic(" bad return code xirr - rc = %lx \n", lpar_rc);
++	return (int)return_value;
++}
++
++static void pSeriesLP_xirr_info_set(int n_cpu, int value)
++{
++	unsigned long lpar_rc;
++	unsigned long val64 = value & 0xffffffff;
++
++	lpar_rc = plpar_eoi(val64);
++	if (lpar_rc != H_Success)
++		panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc,
++		      val64);
++}
++
++void pSeriesLP_cppr_info(int n_cpu, u8 value)
++{
++	unsigned long lpar_rc;
++
++	lpar_rc = plpar_cppr(value);
++	if (lpar_rc != H_Success)
++		panic("bad return code cppr - rc = %lx\n", lpar_rc);
++}
++
++static void pSeriesLP_qirr_info(int n_cpu , u8 value)
++{
++	unsigned long lpar_rc;
++
++	lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu), value);
++	if (lpar_rc != H_Success)
++		panic("bad return code qirr - rc = %lx\n", lpar_rc);
++}
++
++xics_ops pSeriesLP_ops = {
++	pSeriesLP_xirr_info_get,
++	pSeriesLP_xirr_info_set,
++	pSeriesLP_cppr_info,
++	pSeriesLP_qirr_info
++};
++
++static unsigned int xics_startup(unsigned int virq)
++{
++	unsigned int irq;
++
++	irq = irq_offset_down(virq);
++	if (radix_tree_insert(&irq_map, virt_irq_to_real(irq),
++			      &virt_irq_to_real_map[irq]) == -ENOMEM)
++		printk(KERN_CRIT "Out of memory creating real -> virtual"
++		       " IRQ mapping for irq %u (real 0x%x)\n",
++		       virq, virt_irq_to_real(irq));
++	xics_enable_irq(virq);
++	return 0;	/* return value is ignored */
++}
++
++static unsigned int real_irq_to_virt(unsigned int real_irq)
++{
++	unsigned int *ptr;
++
++	ptr = radix_tree_lookup(&irq_map, real_irq);
++	if (ptr == NULL)
++		return NO_IRQ;
++	return ptr - virt_irq_to_real_map;
++}
++
++#ifdef CONFIG_SMP
++static int get_irq_server(unsigned int irq)
++{
++	unsigned int server;
++	/* For the moment only implement delivery to all cpus or one cpu */
++	cpumask_t cpumask = irq_affinity[irq];
++	cpumask_t tmp = CPU_MASK_NONE;
++
++	if (!distribute_irqs)
++		return default_server;
++
++	if (cpus_equal(cpumask, CPU_MASK_ALL)) {
++		server = default_distrib_server;
++	} else {
++		cpus_and(tmp, cpu_online_map, cpumask);
++
++		if (cpus_empty(tmp))
++			server = default_distrib_server;
++		else
++			server = get_hard_smp_processor_id(first_cpu(tmp));
++	}
++
++	return server;
++
++}
++#else
++static int get_irq_server(unsigned int irq)
++{
++	return default_server;
++}
++#endif
++
++static void xics_enable_irq(unsigned int virq)
++{
++	unsigned int irq;
++	int call_status;
++	unsigned int server;
++
++	irq = virt_irq_to_real(irq_offset_down(virq));
++	if (irq == XICS_IPI)
++		return;
++
++	server = get_irq_server(virq);
++	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
++				DEFAULT_PRIORITY);
++	if (call_status != 0) {
++		printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_set_xive "
++		       "returned %d\n", irq, call_status);
++		printk("set_xive %x, server %x\n", ibm_set_xive, server);
++		return;
++	}
++
++	/* Now unmask the interrupt (often a no-op) */
++	call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
++	if (call_status != 0) {
++		printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_int_on "
++		       "returned %d\n", irq, call_status);
++		return;
++	}
++}
++
++static void xics_disable_real_irq(unsigned int irq)
++{
++	int call_status;
++	unsigned int server;
++
++	if (irq == XICS_IPI)
++		return;
++
++	call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
++	if (call_status != 0) {
++		printk(KERN_ERR "xics_disable_real_irq: irq=%u: "
++		       "ibm_int_off returned %d\n", irq, call_status);
++		return;
++	}
++
++	server = get_irq_server(irq);
++	/* Have to set XIVE to 0xff to be able to remove a slot */
++	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 0xff);
++	if (call_status != 0) {
++		printk(KERN_ERR "xics_disable_irq: irq=%u: ibm_set_xive(0xff)"
++		       " returned %d\n", irq, call_status);
++		return;
++	}
++}
++
++static void xics_disable_irq(unsigned int virq)
++{
++	unsigned int irq;
++
++	irq = virt_irq_to_real(irq_offset_down(virq));
++	xics_disable_real_irq(irq);
++}
++
++static void xics_end_irq(unsigned int irq)
++{
++	int cpu = smp_processor_id();
++
++	iosync();
++	ops->xirr_info_set(cpu, ((0xff << 24) |
++				 (virt_irq_to_real(irq_offset_down(irq)))));
++
++}
++
++static void xics_mask_and_ack_irq(unsigned int irq)
++{
++	int cpu = smp_processor_id();
++
++	if (irq < irq_offset_value()) {
++		i8259_pic.ack(irq);
++		iosync();
++		ops->xirr_info_set(cpu, ((0xff<<24) |
++					 xics_irq_8259_cascade_real));
++		iosync();
++	}
++}
++
++int xics_get_irq(struct pt_regs *regs)
++{
++	unsigned int cpu = smp_processor_id();
++	unsigned int vec;
++	int irq;
++
++	vec = ops->xirr_info_get(cpu);
++	/*  (vec >> 24) == old priority */
++	vec &= 0x00ffffff;
++
++	/* for sanity, this had better be < NR_IRQS - 16 */
++	if (vec == xics_irq_8259_cascade_real) {
++		irq = i8259_irq(regs);
++		if (irq == -1) {
++			/* Spurious cascaded interrupt.  Still must ack xics */
++			xics_end_irq(irq_offset_up(xics_irq_8259_cascade));
++
++			irq = -1;
++		}
++	} else if (vec == XICS_IRQ_SPURIOUS) {
++		irq = -1;
++	} else {
++		irq = real_irq_to_virt(vec);
++		if (irq == NO_IRQ)
++			irq = real_irq_to_virt_slowpath(vec);
++		if (irq == NO_IRQ) {
++			printk(KERN_ERR "Interrupt %u (real) is invalid,"
++			       " disabling it.\n", vec);
++			xics_disable_real_irq(vec);
++		} else
++			irq = irq_offset_up(irq);
++	}
++	return irq;
++}
++
++#ifdef CONFIG_SMP
++
++irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
++{
++	int cpu = smp_processor_id();
++
++	ops->qirr_info(cpu, 0xff);
++
++	WARN_ON(cpu_is_offline(cpu));
++
++	while (xics_ipi_message[cpu].value) {
++		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
++				       &xics_ipi_message[cpu].value)) {
++			mb();
++			smp_message_recv(PPC_MSG_CALL_FUNCTION, regs);
++		}
++		if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
++				       &xics_ipi_message[cpu].value)) {
++			mb();
++			smp_message_recv(PPC_MSG_RESCHEDULE, regs);
++		}
++#if 0
++		if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK,
++				       &xics_ipi_message[cpu].value)) {
++			mb();
++			smp_message_recv(PPC_MSG_MIGRATE_TASK, regs);
++		}
++#endif
++#ifdef CONFIG_DEBUGGER
++		if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
++				       &xics_ipi_message[cpu].value)) {
++			mb();
++			smp_message_recv(PPC_MSG_DEBUGGER_BREAK, regs);
++		}
++#endif
++	}
++	return IRQ_HANDLED;
++}
++
++void xics_cause_IPI(int cpu)
++{
++	ops->qirr_info(cpu, IPI_PRIORITY);
++}
++#endif /* CONFIG_SMP */
++
++void xics_setup_cpu(void)
++{
++	int cpu = smp_processor_id();
++
++	ops->cppr_info(cpu, 0xff);
++	iosync();
++
++	/*
++	 * Put the calling processor into the GIQ.  This is really only
++	 * necessary from a secondary thread as the OF start-cpu interface
++	 * performs this function for us on primary threads.
++	 *
++	 * XXX: undo of teardown on kexec needs this too, as may hotplug
++	 */
++	rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
++		(1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
++}
++
++void xics_init_IRQ(void)
++{
++	int i;
++	unsigned long intr_size = 0;
++	struct device_node *np;
++	uint *ireg, ilen, indx = 0;
++	unsigned long intr_base = 0;
++	struct xics_interrupt_node {
++		unsigned long addr;
++		unsigned long size;
++	} intnodes[NR_CPUS];
++
++	ppc64_boot_msg(0x20, "XICS Init");
++
++	ibm_get_xive = rtas_token("ibm,get-xive");
++	ibm_set_xive = rtas_token("ibm,set-xive");
++	ibm_int_on  = rtas_token("ibm,int-on");
++	ibm_int_off = rtas_token("ibm,int-off");
++
++	np = of_find_node_by_type(NULL, "PowerPC-External-Interrupt-Presentation");
++	if (!np)
++		panic("xics_init_IRQ: can't find interrupt presentation");
++
++nextnode:
++	ireg = (uint *)get_property(np, "ibm,interrupt-server-ranges", NULL);
++	if (ireg) {
++		/*
++		 * set node starting index for this node
++		 */
++		indx = *ireg;
++	}
++
++	ireg = (uint *)get_property(np, "reg", &ilen);
++	if (!ireg)
++		panic("xics_init_IRQ: can't find interrupt reg property");
++
++	while (ilen) {
++		intnodes[indx].addr = (unsigned long)*ireg++ << 32;
++		ilen -= sizeof(uint);
++		intnodes[indx].addr |= *ireg++;
++		ilen -= sizeof(uint);
++		intnodes[indx].size = (unsigned long)*ireg++ << 32;
++		ilen -= sizeof(uint);
++		intnodes[indx].size |= *ireg++;
++		ilen -= sizeof(uint);
++		indx++;
++		if (indx >= NR_CPUS) break;
++	}
++
++	np = of_find_node_by_type(np, "PowerPC-External-Interrupt-Presentation");
++	if ((indx < NR_CPUS) && np) goto nextnode;
++
++	/* Find the server numbers for the boot cpu. */
++	for (np = of_find_node_by_type(NULL, "cpu");
++	     np;
++	     np = of_find_node_by_type(np, "cpu")) {
++		ireg = (uint *)get_property(np, "reg", &ilen);
++		if (ireg && ireg[0] == boot_cpuid_phys) {
++			ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s",
++						    &ilen);
++			i = ilen / sizeof(int);
++			if (ireg && i > 0) {
++				default_server = ireg[0];
++				default_distrib_server = ireg[i-1]; /* take last element */
++			}
++			ireg = (uint *)get_property(np,
++					"ibm,interrupt-server#-size", NULL);
++			if (ireg)
++				interrupt_server_size = *ireg;
++			break;
++		}
++	}
++	of_node_put(np);
++
++	intr_base = intnodes[0].addr;
++	intr_size = intnodes[0].size;
++
++	np = of_find_node_by_type(NULL, "interrupt-controller");
++	if (!np) {
++		printk(KERN_WARNING "xics: no ISA interrupt controller\n");
++		xics_irq_8259_cascade_real = -1;
++		xics_irq_8259_cascade = -1;
++	} else {
++		ireg = (uint *) get_property(np, "interrupts", NULL);
++		if (!ireg)
++			panic("xics_init_IRQ: can't find ISA interrupts property");
++
++		xics_irq_8259_cascade_real = *ireg;
++		xics_irq_8259_cascade
++			= virt_irq_create_mapping(xics_irq_8259_cascade_real);
++		of_node_put(np);
++	}
++
++	if (systemcfg->platform == PLATFORM_PSERIES) {
++#ifdef CONFIG_SMP
++		for_each_cpu(i) {
++			int hard_id;
++
++			/* FIXME: Do this dynamically! --RR */
++			if (!cpu_present(i))
++				continue;
++
++			hard_id = get_hard_smp_processor_id(i);
++			xics_per_cpu[i] = ioremap(intnodes[hard_id].addr,
++						  intnodes[hard_id].size);
++		}
++#else
++		xics_per_cpu[0] = ioremap(intr_base, intr_size);
++#endif /* CONFIG_SMP */
++	} else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
++		ops = &pSeriesLP_ops;
++	}
++
++	xics_8259_pic.enable = i8259_pic.enable;
++	xics_8259_pic.disable = i8259_pic.disable;
++	for (i = 0; i < 16; ++i)
++		get_irq_desc(i)->handler = &xics_8259_pic;
++	for (; i < NR_IRQS; ++i)
++		get_irq_desc(i)->handler = &xics_pic;
++
++	xics_setup_cpu();
++
++	ppc64_boot_msg(0x21, "XICS Done");
++}
++
++/*
++ * We cant do this in init_IRQ because we need the memory subsystem up for
++ * request_irq()
++ */
++static int __init xics_setup_i8259(void)
++{
++	if (ppc64_interrupt_controller == IC_PPC_XIC &&
++	    xics_irq_8259_cascade != -1) {
++		if (request_irq(irq_offset_up(xics_irq_8259_cascade),
++				no_action, 0, "8259 cascade", NULL))
++			printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 "
++					"cascade\n");
++		i8259_init(0, 0);
++	}
++	return 0;
++}
++arch_initcall(xics_setup_i8259);
++
++#ifdef CONFIG_SMP
++void xics_request_IPIs(void)
++{
++	virt_irq_to_real_map[XICS_IPI] = XICS_IPI;
++
++	/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
++	request_irq(irq_offset_up(XICS_IPI), xics_ipi_action, SA_INTERRUPT,
++		    "IPI", NULL);
++	get_irq_desc(irq_offset_up(XICS_IPI))->status |= IRQ_PER_CPU;
++}
++#endif
++
++static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
++{
++	unsigned int irq;
++	int status;
++	int xics_status[2];
++	unsigned long newmask;
++	cpumask_t tmp = CPU_MASK_NONE;
++
++	irq = virt_irq_to_real(irq_offset_down(virq));
++	if (irq == XICS_IPI || irq == NO_IRQ)
++		return;
++
++	status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
++
++	if (status) {
++		printk(KERN_ERR "xics_set_affinity: irq=%u ibm,get-xive "
++		       "returns %d\n", irq, status);
++		return;
++	}
++
++	/* For the moment only implement delivery to all cpus or one cpu */
++	if (cpus_equal(cpumask, CPU_MASK_ALL)) {
++		newmask = default_distrib_server;
++	} else {
++		cpus_and(tmp, cpu_online_map, cpumask);
++		if (cpus_empty(tmp))
++			return;
++		newmask = get_hard_smp_processor_id(first_cpu(tmp));
++	}
++
++	status = rtas_call(ibm_set_xive, 3, 1, NULL,
++				irq, newmask, xics_status[1]);
++
++	if (status) {
++		printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive "
++		       "returns %d\n", irq, status);
++		return;
++	}
++}
++
++void xics_teardown_cpu(int secondary)
++{
++	int cpu = smp_processor_id();
++
++	ops->cppr_info(cpu, 0x00);
++	iosync();
++
++	/*
++	 * Some machines need to have at least one cpu in the GIQ,
++	 * so leave the master cpu in the group.
++	 */
++	if (secondary) {
++		/*
++		 * we need to EOI the IPI if we got here from kexec down IPI
++		 *
++		 * probably need to check all the other interrupts too
++		 * should we be flagging idle loop instead?
++		 * or creating some task to be scheduled?
++		 */
++		ops->xirr_info_set(cpu, XICS_IPI);
++		rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
++			(1UL << interrupt_server_size) - 1 -
++			default_distrib_server, 0);
++	}
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++
++/* Interrupts are disabled. */
++void xics_migrate_irqs_away(void)
++{
++	int status;
++	unsigned int irq, virq, cpu = smp_processor_id();
++
++	/* Reject any interrupt that was queued to us... */
++	ops->cppr_info(cpu, 0);
++	iosync();
++
++	/* remove ourselves from the global interrupt queue */
++	status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
++		(1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
++	WARN_ON(status < 0);
++
++	/* Allow IPIs again... */
++	ops->cppr_info(cpu, DEFAULT_PRIORITY);
++	iosync();
++
++	for_each_irq(virq) {
++		irq_desc_t *desc;
++		int xics_status[2];
++		unsigned long flags;
++
++		/* We cant set affinity on ISA interrupts */
++		if (virq < irq_offset_value())
++			continue;
++
++		desc = get_irq_desc(virq);
++		irq = virt_irq_to_real(irq_offset_down(virq));
++
++		/* We need to get IPIs still. */
++		if (irq == XICS_IPI || irq == NO_IRQ)
++			continue;
++
++		/* We only need to migrate enabled IRQS */
++		if (desc == NULL || desc->handler == NULL
++		    || desc->action == NULL
++		    || desc->handler->set_affinity == NULL)
++			continue;
++
++		spin_lock_irqsave(&desc->lock, flags);
++
++		status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
++		if (status) {
++			printk(KERN_ERR "migrate_irqs_away: irq=%u "
++					"ibm,get-xive returns %d\n",
++					virq, status);
++			goto unlock;
++		}
++
++		/*
++		 * We only support delivery to all cpus or to one cpu.
++		 * The irq has to be migrated only in the single cpu
++		 * case.
++		 */
++		if (xics_status[0] != get_hard_smp_processor_id(cpu))
++			goto unlock;
++
++		printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
++		       virq, cpu);
++
++		/* Reset affinity to all cpus */
++		desc->handler->set_affinity(virq, CPU_MASK_ALL);
++		irq_affinity[virq] = CPU_MASK_ALL;
++unlock:
++		spin_unlock_irqrestore(&desc->lock, flags);
++	}
++}
++#endif
+diff --git a/arch/powerpc/platforms/pseries/xics.h b/arch/powerpc/platforms/pseries/xics.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/platforms/pseries/xics.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/powerpc/platforms/pseries/xics.h
++ *
++ * Copyright 2000 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.
++ */
++
++#ifndef _POWERPC_KERNEL_XICS_H
++#define _POWERPC_KERNEL_XICS_H
++
++#include <linux/cache.h>
++
++void xics_init_IRQ(void);
++int xics_get_irq(struct pt_regs *);
++void xics_setup_cpu(void);
++void xics_teardown_cpu(int secondary);
++void xics_cause_IPI(int cpu);
++void xics_request_IPIs(void);
++void xics_migrate_irqs_away(void);
++
++/* first argument is ignored for now*/
++void pSeriesLP_cppr_info(int n_cpu, u8 value);
++
++struct xics_ipi_struct {
++	volatile unsigned long value;
++} ____cacheline_aligned;
++
++extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
++
++#endif /* _POWERPC_KERNEL_XICS_H */
+diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/sysdev/Makefile
+@@ -0,0 +1,7 @@
++obj-$(CONFIG_MPIC)		+= mpic.o
++obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
++obj-$(CONFIG_PPC_I8259)		+= i8259.o
++obj-$(CONFIG_PPC_MPC106)	+= grackle.o
++obj-$(CONFIG_BOOKE)		+= dcr.o
++obj-$(CONFIG_40x)		+= dcr.o
++obj-$(CONFIG_U3_DART)		+= u3_iommu.o
+diff --git a/arch/powerpc/sysdev/dcr.S b/arch/powerpc/sysdev/dcr.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/sysdev/dcr.S
+@@ -0,0 +1,41 @@
++/*
++ * arch/ppc/syslib/dcr.S
++ *
++ * "Indirect" DCR access
++ *
++ * Copyright (c) 2004 Eugene Surovegin <ebs at ebshome.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 <asm/ppc_asm.h>
++#include <asm/processor.h>
++
++#define DCR_ACCESS_PROLOG(table) \
++	rlwinm  r3,r3,4,18,27;   \
++	lis     r5,table at h;      \
++	ori     r5,r5,table at l;   \
++	add     r3,r3,r5;        \
++	mtctr   r3;              \
++	bctr
++
++_GLOBAL(__mfdcr)
++	DCR_ACCESS_PROLOG(__mfdcr_table)
++
++_GLOBAL(__mtdcr)
++	DCR_ACCESS_PROLOG(__mtdcr_table)
++
++__mfdcr_table:
++	mfdcr  r3,0; blr
++__mtdcr_table:
++	mtdcr  0,r4; blr
++
++dcr     = 1
++        .rept   1023
++	mfdcr   r3,dcr; blr
++	mtdcr   dcr,r4; blr
++	dcr     = dcr + 1
++	.endr
+diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/sysdev/grackle.c
+@@ -0,0 +1,64 @@
++/*
++ * Functions for setting up and using a MPC106 northbridge
++ * Extracted from arch/powerpc/platforms/powermac/pci.c.
++ *
++ * Copyright (C) 2003 Benjamin Herrenschmuidt (benh at kernel.crashing.org)
++ * Copyright (C) 1997 Paul Mackerras (paulus at samba.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/pci.h>
++#include <linux/init.h>
++
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/pci-bridge.h>
++#include <asm/grackle.h>
++
++#define GRACKLE_CFA(b, d, o)	(0x80 | ((b) << 8) | ((d) << 16) \
++				 | (((o) & ~3) << 24))
++
++#define GRACKLE_PICR1_STG		0x00000040
++#define GRACKLE_PICR1_LOOPSNOOP		0x00000010
++
++/* N.B. this is called before bridges is initialized, so we can't
++   use grackle_pcibios_{read,write}_config_dword. */
++static inline void grackle_set_stg(struct pci_controller* bp, int enable)
++{
++	unsigned int val;
++
++	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
++	val = in_le32(bp->cfg_data);
++	val = enable? (val | GRACKLE_PICR1_STG) :
++		(val & ~GRACKLE_PICR1_STG);
++	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
++	out_le32(bp->cfg_data, val);
++	(void)in_le32(bp->cfg_data);
++}
++
++static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
++{
++	unsigned int val;
++
++	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
++	val = in_le32(bp->cfg_data);
++	val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :
++		(val & ~GRACKLE_PICR1_LOOPSNOOP);
++	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
++	out_le32(bp->cfg_data, val);
++	(void)in_le32(bp->cfg_data);
++}
++
++void __init setup_grackle(struct pci_controller *hose)
++{
++	setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
++	if (machine_is_compatible("AAPL,PowerBook1998"))
++		grackle_set_loop_snoop(hose, 1);
++#if 0	/* Disabled for now, HW problems ??? */
++	grackle_set_stg(hose, 1);
++#endif
++}
+diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/sysdev/i8259.c
+@@ -0,0 +1,221 @@
++/*
++ * i8259 interrupt controller driver.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/ioport.h>
++#include <linux/interrupt.h>
++#include <asm/io.h>
++#include <asm/i8259.h>
++
++static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */
++
++static unsigned char cached_8259[2] = { 0xff, 0xff };
++#define cached_A1 (cached_8259[0])
++#define cached_21 (cached_8259[1])
++
++static DEFINE_SPINLOCK(i8259_lock);
++
++static int i8259_pic_irq_offset;
++
++/*
++ * Acknowledge the IRQ using either the PCI host bridge's interrupt
++ * acknowledge feature or poll.  How i8259_init() is called determines
++ * which is called.  It should be noted that polling is broken on some
++ * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
++ */
++int i8259_irq(struct pt_regs *regs)
++{
++	int irq;
++
++	spin_lock(&i8259_lock);
++
++	/* Either int-ack or poll for the IRQ */
++	if (pci_intack)
++		irq = readb(pci_intack);
++	else {
++		/* Perform an interrupt acknowledge cycle on controller 1. */
++		outb(0x0C, 0x20);		/* prepare for poll */
++		irq = inb(0x20) & 7;
++		if (irq == 2 ) {
++			/*
++			 * Interrupt is cascaded so perform interrupt
++			 * acknowledge on controller 2.
++			 */
++			outb(0x0C, 0xA0);	/* prepare for poll */
++			irq = (inb(0xA0) & 7) + 8;
++		}
++	}
++
++	if (irq == 7) {
++		/*
++		 * This may be a spurious interrupt.
++		 *
++		 * Read the interrupt status register (ISR). If the most
++		 * significant bit is not set then there is no valid
++		 * interrupt.
++		 */
++		if (!pci_intack)
++			outb(0x0B, 0x20);	/* ISR register */
++		if(~inb(0x20) & 0x80)
++			irq = -1;
++	}
++
++	spin_unlock(&i8259_lock);
++	return irq + i8259_pic_irq_offset;
++}
++
++int i8259_irq_cascade(struct pt_regs *regs, void *unused)
++{
++	return i8259_irq(regs);
++}
++
++static void i8259_mask_and_ack_irq(unsigned int irq_nr)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&i8259_lock, flags);
++	irq_nr -= i8259_pic_irq_offset;
++	if (irq_nr > 7) {
++		cached_A1 |= 1 << (irq_nr-8);
++		inb(0xA1); 	/* DUMMY */
++		outb(cached_A1, 0xA1);
++		outb(0x20, 0xA0);	/* Non-specific EOI */
++		outb(0x20, 0x20);	/* Non-specific EOI to cascade */
++	} else {
++		cached_21 |= 1 << irq_nr;
++		inb(0x21); 	/* DUMMY */
++		outb(cached_21, 0x21);
++		outb(0x20, 0x20);	/* Non-specific EOI */
++	}
++	spin_unlock_irqrestore(&i8259_lock, flags);
++}
++
++static void i8259_set_irq_mask(int irq_nr)
++{
++	outb(cached_A1,0xA1);
++	outb(cached_21,0x21);
++}
++
++static void i8259_mask_irq(unsigned int irq_nr)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&i8259_lock, flags);
++	irq_nr -= i8259_pic_irq_offset;
++	if (irq_nr < 8)
++		cached_21 |= 1 << irq_nr;
++	else
++		cached_A1 |= 1 << (irq_nr-8);
++	i8259_set_irq_mask(irq_nr);
++	spin_unlock_irqrestore(&i8259_lock, flags);
++}
++
++static void i8259_unmask_irq(unsigned int irq_nr)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&i8259_lock, flags);
++	irq_nr -= i8259_pic_irq_offset;
++	if (irq_nr < 8)
++		cached_21 &= ~(1 << irq_nr);
++	else
++		cached_A1 &= ~(1 << (irq_nr-8));
++	i8259_set_irq_mask(irq_nr);
++	spin_unlock_irqrestore(&i8259_lock, flags);
++}
++
++static void i8259_end_irq(unsigned int irq)
++{
++	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))
++	    && irq_desc[irq].action)
++		i8259_unmask_irq(irq);
++}
++
++struct hw_interrupt_type i8259_pic = {
++	.typename = " i8259    ",
++	.enable = i8259_unmask_irq,
++	.disable = i8259_mask_irq,
++	.ack = i8259_mask_and_ack_irq,
++	.end = i8259_end_irq,
++};
++
++static struct resource pic1_iores = {
++	.name = "8259 (master)",
++	.start = 0x20,
++	.end = 0x21,
++	.flags = IORESOURCE_BUSY,
++};
++
++static struct resource pic2_iores = {
++	.name = "8259 (slave)",
++	.start = 0xa0,
++	.end = 0xa1,
++	.flags = IORESOURCE_BUSY,
++};
++
++static struct resource pic_edgectrl_iores = {
++	.name = "8259 edge control",
++	.start = 0x4d0,
++	.end = 0x4d1,
++	.flags = IORESOURCE_BUSY,
++};
++
++static struct irqaction i8259_irqaction = {
++	.handler = no_action,
++	.flags = SA_INTERRUPT,
++	.mask = CPU_MASK_NONE,
++	.name = "82c59 secondary cascade",
++};
++
++/*
++ * i8259_init()
++ * intack_addr - PCI interrupt acknowledge (real) address which will return
++ *               the active irq from the 8259
++ */
++void __init i8259_init(unsigned long intack_addr, int offset)
++{
++	unsigned long flags;
++	int i;
++
++	spin_lock_irqsave(&i8259_lock, flags);
++	i8259_pic_irq_offset = offset;
++
++	/* init master interrupt controller */
++	outb(0x11, 0x20); /* Start init sequence */
++	outb(0x00, 0x21); /* Vector base */
++	outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
++	outb(0x01, 0x21); /* Select 8086 mode */
++
++	/* init slave interrupt controller */
++	outb(0x11, 0xA0); /* Start init sequence */
++	outb(0x08, 0xA1); /* Vector base */
++	outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
++	outb(0x01, 0xA1); /* Select 8086 mode */
++
++	/* always read ISR */
++	outb(0x0B, 0x20);
++	outb(0x0B, 0xA0);
++
++	/* Mask all interrupts */
++	outb(cached_A1, 0xA1);
++	outb(cached_21, 0x21);
++
++	spin_unlock_irqrestore(&i8259_lock, flags);
++
++	/* reserve our resources */
++	setup_irq(offset + 2, &i8259_irqaction);
++	request_resource(&ioport_resource, &pic1_iores);
++	request_resource(&ioport_resource, &pic2_iores);
++	request_resource(&ioport_resource, &pic_edgectrl_iores);
++
++	if (intack_addr != 0)
++		pci_intack = ioremap(intack_addr, 1);
++
++	for (i = 0; i < NUM_ISA_INTERRUPTS; ++i)
++		irq_desc[offset + i].handler = &i8259_pic;
++}
+diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/sysdev/indirect_pci.c
+@@ -0,0 +1,134 @@
++/*
++ * 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.
++ */
++
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/init.h>
++
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/pci-bridge.h>
++#include <asm/machdep.h>
++
++#ifdef CONFIG_PPC_INDIRECT_PCI_BE
++#define PCI_CFG_OUT out_be32
++#else
++#define PCI_CFG_OUT out_le32
++#endif
++
++static int
++indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
++		     int len, u32 *val)
++{
++	struct pci_controller *hose = bus->sysdata;
++	volatile void __iomem *cfg_data;
++	u8 cfg_type = 0;
++
++	if (ppc_md.pci_exclude_device)
++		if (ppc_md.pci_exclude_device(bus->number, devfn))
++			return PCIBIOS_DEVICE_NOT_FOUND;
++	
++	if (hose->set_cfg_type)
++		if (bus->number != hose->first_busno)
++			cfg_type = 1;
++
++	PCI_CFG_OUT(hose->cfg_addr, 					 
++		 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
++		  | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
++
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	cfg_data = hose->cfg_data + (offset & 3);
++	switch (len) {
++	case 1:
++		*val = in_8(cfg_data);
++		break;
++	case 2:
++		*val = in_le16(cfg_data);
++		break;
++	default:
++		*val = in_le32(cfg_data);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int
++indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
++		      int len, u32 val)
++{
++	struct pci_controller *hose = bus->sysdata;
++	volatile void __iomem *cfg_data;
++	u8 cfg_type = 0;
++
++	if (ppc_md.pci_exclude_device)
++		if (ppc_md.pci_exclude_device(bus->number, devfn))
++			return PCIBIOS_DEVICE_NOT_FOUND;
++
++	if (hose->set_cfg_type)
++		if (bus->number != hose->first_busno)
++			cfg_type = 1;
++
++	PCI_CFG_OUT(hose->cfg_addr, 					 
++		 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
++		  | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
++
++	/*
++	 * Note: the caller has already checked that offset is
++	 * suitably aligned and that len is 1, 2 or 4.
++	 */
++	cfg_data = hose->cfg_data + (offset & 3);
++	switch (len) {
++	case 1:
++		out_8(cfg_data, val);
++		break;
++	case 2:
++		out_le16(cfg_data, val);
++		break;
++	default:
++		out_le32(cfg_data, val);
++		break;
++	}
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops indirect_pci_ops =
++{
++	indirect_read_config,
++	indirect_write_config
++};
++
++void __init
++setup_indirect_pci_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_pci_ops;
++}
++
++void __init
++setup_indirect_pci(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_pci_nomap(hose, addr, data);
++}
+diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/sysdev/mpic.c
+@@ -0,0 +1,927 @@
++/*
++ *  arch/powerpc/kernel/mpic.c
++ *
++ *  Driver for interrupt controllers following the OpenPIC standard, the
++ *  common implementation beeing IBM's MPIC. This driver also can deal
++ *  with various broken implementations of this HW.
++ *
++ *  Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
++ *
++ *  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/config.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/smp.h>
++#include <linux/interrupt.h>
++#include <linux/bootmem.h>
++#include <linux/spinlock.h>
++#include <linux/pci.h>
++
++#include <asm/ptrace.h>
++#include <asm/signal.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/irq.h>
++#include <asm/machdep.h>
++#include <asm/mpic.h>
++#include <asm/smp.h>
++
++#ifdef DEBUG
++#define DBG(fmt...) printk(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++static struct mpic *mpics;
++static struct mpic *mpic_primary;
++static DEFINE_SPINLOCK(mpic_lock);
++
++#ifdef CONFIG_PPC32	/* XXX for now */
++#define distribute_irqs	CONFIG_IRQ_ALL_CPUS
++#endif
++
++/*
++ * Register accessor functions
++ */
++
++
++static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base,
++			    unsigned int reg)
++{
++	if (be)
++		return in_be32(base + (reg >> 2));
++	else
++		return in_le32(base + (reg >> 2));
++}
++
++static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base,
++			      unsigned int reg, u32 value)
++{
++	if (be)
++		out_be32(base + (reg >> 2), value);
++	else
++		out_le32(base + (reg >> 2), value);
++}
++
++static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
++{
++	unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
++	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
++
++	if (mpic->flags & MPIC_BROKEN_IPI)
++		be = !be;
++	return _mpic_read(be, mpic->gregs, offset);
++}
++
++static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
++{
++	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
++
++	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
++}
++
++static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
++{
++	unsigned int cpu = 0;
++
++	if (mpic->flags & MPIC_PRIMARY)
++		cpu = hard_smp_processor_id();
++
++	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg);
++}
++
++static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value)
++{
++	unsigned int cpu = 0;
++
++	if (mpic->flags & MPIC_PRIMARY)
++		cpu = hard_smp_processor_id();
++
++	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg, value);
++}
++
++static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg)
++{
++	unsigned int	isu = src_no >> mpic->isu_shift;
++	unsigned int	idx = src_no & mpic->isu_mask;
++
++	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
++			  reg + (idx * MPIC_IRQ_STRIDE));
++}
++
++static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
++				   unsigned int reg, u32 value)
++{
++	unsigned int	isu = src_no >> mpic->isu_shift;
++	unsigned int	idx = src_no & mpic->isu_mask;
++
++	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
++		    reg + (idx * MPIC_IRQ_STRIDE), value);
++}
++
++#define mpic_read(b,r)		_mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
++#define mpic_write(b,r,v)	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN,(b),(r),(v))
++#define mpic_ipi_read(i)	_mpic_ipi_read(mpic,(i))
++#define mpic_ipi_write(i,v)	_mpic_ipi_write(mpic,(i),(v))
++#define mpic_cpu_read(i)	_mpic_cpu_read(mpic,(i))
++#define mpic_cpu_write(i,v)	_mpic_cpu_write(mpic,(i),(v))
++#define mpic_irq_read(s,r)	_mpic_irq_read(mpic,(s),(r))
++#define mpic_irq_write(s,r,v)	_mpic_irq_write(mpic,(s),(r),(v))
++
++
++/*
++ * Low level utility functions
++ */
++
++
++
++/* Check if we have one of those nice broken MPICs with a flipped endian on
++ * reads from IPI registers
++ */
++static void __init mpic_test_broken_ipi(struct mpic *mpic)
++{
++	u32 r;
++
++	mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK);
++	r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0);
++
++	if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
++		printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
++		mpic->flags |= MPIC_BROKEN_IPI;
++	}
++}
++
++#ifdef CONFIG_MPIC_BROKEN_U3
++
++/* Test if an interrupt is sourced from HyperTransport (used on broken U3s)
++ * to force the edge setting on the MPIC and do the ack workaround.
++ */
++static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source_no)
++{
++	if (source_no >= 128 || !mpic->fixups)
++		return 0;
++	return mpic->fixups[source_no].base != NULL;
++}
++
++static inline void mpic_apic_end_irq(struct mpic *mpic, unsigned int source_no)
++{
++	struct mpic_irq_fixup *fixup = &mpic->fixups[source_no];
++	u32 tmp;
++
++	spin_lock(&mpic->fixup_lock);
++	writeb(0x11 + 2 * fixup->irq, fixup->base);
++	tmp = readl(fixup->base + 2);
++	writel(tmp | 0x80000000ul, fixup->base + 2);
++	/* config writes shouldn't be posted but let's be safe ... */
++	(void)readl(fixup->base + 2);
++	spin_unlock(&mpic->fixup_lock);
++}
++
++
++static void __init mpic_amd8111_read_irq(struct mpic *mpic, u8 __iomem *devbase)
++{
++	int i, irq;
++	u32 tmp;
++
++	printk(KERN_INFO "mpic:    - Workarounds on AMD 8111 @ %p\n", devbase);
++
++	for (i=0; i < 24; i++) {
++		writeb(0x10 + 2*i, devbase + 0xf2);
++		tmp = readl(devbase + 0xf4);
++		if ((tmp & 0x1) || !(tmp & 0x20))
++			continue;
++		irq = (tmp >> 16) & 0xff;
++		mpic->fixups[irq].irq = i;
++		mpic->fixups[irq].base = devbase + 0xf2;
++	}
++}
++ 
++static void __init mpic_amd8131_read_irq(struct mpic *mpic, u8 __iomem *devbase)
++{
++	int i, irq;
++	u32 tmp;
++
++	printk(KERN_INFO "mpic:    - Workarounds on AMD 8131 @ %p\n", devbase);
++
++	for (i=0; i < 4; i++) {
++		writeb(0x10 + 2*i, devbase + 0xba);
++		tmp = readl(devbase + 0xbc);
++		if ((tmp & 0x1) || !(tmp & 0x20))
++			continue;
++		irq = (tmp >> 16) & 0xff;
++		mpic->fixups[irq].irq = i;
++		mpic->fixups[irq].base = devbase + 0xba;
++	}
++}
++ 
++static void __init mpic_scan_ioapics(struct mpic *mpic)
++{
++	unsigned int devfn;
++	u8 __iomem *cfgspace;
++
++	printk(KERN_INFO "mpic: Setting up IO-APICs workarounds for U3\n");
++
++	/* Allocate fixups array */
++	mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup));
++	BUG_ON(mpic->fixups == NULL);
++	memset(mpic->fixups, 0, 128 * sizeof(struct mpic_irq_fixup));
++
++	/* Init spinlock */
++	spin_lock_init(&mpic->fixup_lock);
++
++	/* Map u3 config space. We assume all IO-APICs are on the primary bus
++	 * and slot will never be above "0xf" so we only need to map 32k
++	 */
++	cfgspace = (unsigned char __iomem *)ioremap(0xf2000000, 0x8000);
++	BUG_ON(cfgspace == NULL);
++
++	/* Now we scan all slots. We do a very quick scan, we read the header type,
++	 * vendor ID and device ID only, that's plenty enough
++	 */
++	for (devfn = 0; devfn < PCI_DEVFN(0x10,0); devfn ++) {
++		u8 __iomem *devbase = cfgspace + (devfn << 8);
++		u8 hdr_type = readb(devbase + PCI_HEADER_TYPE);
++		u32 l = readl(devbase + PCI_VENDOR_ID);
++		u16 vendor_id, device_id;
++		int multifunc = 0;
++
++		DBG("devfn %x, l: %x\n", devfn, l);
++
++		/* If no device, skip */
++		if (l == 0xffffffff || l == 0x00000000 ||
++		    l == 0x0000ffff || l == 0xffff0000)
++			goto next;
++
++		/* Check if it's a multifunction device (only really used
++		 * to function 0 though
++		 */
++		multifunc = !!(hdr_type & 0x80);
++		vendor_id = l & 0xffff;
++		device_id = (l >> 16) & 0xffff;
++
++		/* If a known device, go to fixup setup code */
++		if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7460)
++			mpic_amd8111_read_irq(mpic, devbase);
++		if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7450)
++			mpic_amd8131_read_irq(mpic, devbase);
++	next:
++		/* next device, if function 0 */
++		if ((PCI_FUNC(devfn) == 0) && !multifunc)
++			devfn += 7;
++	}
++}
++
++#endif /* CONFIG_MPIC_BROKEN_U3 */
++
++
++/* Find an mpic associated with a given linux interrupt */
++static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi)
++{
++	struct mpic *mpic = mpics;
++
++	while(mpic) {
++		/* search IPIs first since they may override the main interrupts */
++		if (irq >= mpic->ipi_offset && irq < (mpic->ipi_offset + 4)) {
++			if (is_ipi)
++				*is_ipi = 1;
++			return mpic;
++		}
++		if (irq >= mpic->irq_offset &&
++		    irq < (mpic->irq_offset + mpic->irq_count)) {
++			if (is_ipi)
++				*is_ipi = 0;
++			return mpic;
++		}
++		mpic = mpic -> next;
++	}
++	return NULL;
++}
++
++/* Convert a cpu mask from logical to physical cpu numbers. */
++static inline u32 mpic_physmask(u32 cpumask)
++{
++	int i;
++	u32 mask = 0;
++
++	for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1)
++		mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
++	return mask;
++}
++
++#ifdef CONFIG_SMP
++/* Get the mpic structure from the IPI number */
++static inline struct mpic * mpic_from_ipi(unsigned int ipi)
++{
++	return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi);
++}
++#endif
++
++/* Get the mpic structure from the irq number */
++static inline struct mpic * mpic_from_irq(unsigned int irq)
++{
++	return container_of(irq_desc[irq].handler, struct mpic, hc_irq);
++}
++
++/* Send an EOI */
++static inline void mpic_eoi(struct mpic *mpic)
++{
++	mpic_cpu_write(MPIC_CPU_EOI, 0);
++	(void)mpic_cpu_read(MPIC_CPU_WHOAMI);
++}
++
++#ifdef CONFIG_SMP
++static irqreturn_t mpic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct mpic *mpic = dev_id;
++
++	smp_message_recv(irq - mpic->ipi_offset, regs);
++	return IRQ_HANDLED;
++}
++#endif /* CONFIG_SMP */
++
++/*
++ * Linux descriptor level callbacks
++ */
++
++
++static void mpic_enable_irq(unsigned int irq)
++{
++	unsigned int loops = 100000;
++	struct mpic *mpic = mpic_from_irq(irq);
++	unsigned int src = irq - mpic->irq_offset;
++
++	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
++
++	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
++		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK);
++
++	/* make sure mask gets to controller before we return to user */
++	do {
++		if (!loops--) {
++			printk(KERN_ERR "mpic_enable_irq timeout\n");
++			break;
++		}
++	} while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);	
++}
++
++static void mpic_disable_irq(unsigned int irq)
++{
++	unsigned int loops = 100000;
++	struct mpic *mpic = mpic_from_irq(irq);
++	unsigned int src = irq - mpic->irq_offset;
++
++	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
++
++	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
++		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK);
++
++	/* make sure mask gets to controller before we return to user */
++	do {
++		if (!loops--) {
++			printk(KERN_ERR "mpic_enable_irq timeout\n");
++			break;
++		}
++	} while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
++}
++
++static void mpic_end_irq(unsigned int irq)
++{
++	struct mpic *mpic = mpic_from_irq(irq);
++
++	DBG("%s: end_irq: %d\n", mpic->name, irq);
++
++	/* We always EOI on end_irq() even for edge interrupts since that
++	 * should only lower the priority, the MPIC should have properly
++	 * latched another edge interrupt coming in anyway
++	 */
++
++#ifdef CONFIG_MPIC_BROKEN_U3
++	if (mpic->flags & MPIC_BROKEN_U3) {
++		unsigned int src = irq - mpic->irq_offset;
++		if (mpic_is_ht_interrupt(mpic, src))
++			mpic_apic_end_irq(mpic, src);
++	}
++#endif /* CONFIG_MPIC_BROKEN_U3 */
++
++	mpic_eoi(mpic);
++}
++
++#ifdef CONFIG_SMP
++
++static void mpic_enable_ipi(unsigned int irq)
++{
++	struct mpic *mpic = mpic_from_ipi(irq);
++	unsigned int src = irq - mpic->ipi_offset;
++
++	DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src);
++	mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
++}
++
++static void mpic_disable_ipi(unsigned int irq)
++{
++	/* NEVER disable an IPI... that's just plain wrong! */
++}
++
++static void mpic_end_ipi(unsigned int irq)
++{
++	struct mpic *mpic = mpic_from_ipi(irq);
++
++	/*
++	 * IPIs are marked IRQ_PER_CPU. This has the side effect of
++	 * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
++	 * applying to them. We EOI them late to avoid re-entering.
++	 * We mark IPI's with SA_INTERRUPT as they must run with
++	 * irqs disabled.
++	 */
++	mpic_eoi(mpic);
++}
++
++#endif /* CONFIG_SMP */
++
++static void mpic_set_affinity(unsigned int irq, cpumask_t cpumask)
++{
++	struct mpic *mpic = mpic_from_irq(irq);
++
++	cpumask_t tmp;
++
++	cpus_and(tmp, cpumask, cpu_online_map);
++
++	mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION,
++		       mpic_physmask(cpus_addr(tmp)[0]));	
++}
++
++
++/*
++ * Exported functions
++ */
++
++
++struct mpic * __init mpic_alloc(unsigned long phys_addr,
++				unsigned int flags,
++				unsigned int isu_size,
++				unsigned int irq_offset,
++				unsigned int irq_count,
++				unsigned int ipi_offset,
++				unsigned char *senses,
++				unsigned int senses_count,
++				const char *name)
++{
++	struct mpic	*mpic;
++	u32		reg;
++	const char	*vers;
++	int		i;
++
++	mpic = alloc_bootmem(sizeof(struct mpic));
++	if (mpic == NULL)
++		return NULL;
++	
++
++	memset(mpic, 0, sizeof(struct mpic));
++	mpic->name = name;
++
++	mpic->hc_irq.typename = name;
++	mpic->hc_irq.enable = mpic_enable_irq;
++	mpic->hc_irq.disable = mpic_disable_irq;
++	mpic->hc_irq.end = mpic_end_irq;
++	if (flags & MPIC_PRIMARY)
++		mpic->hc_irq.set_affinity = mpic_set_affinity;
++#ifdef CONFIG_SMP
++	mpic->hc_ipi.typename = name;
++	mpic->hc_ipi.enable = mpic_enable_ipi;
++	mpic->hc_ipi.disable = mpic_disable_ipi;
++	mpic->hc_ipi.end = mpic_end_ipi;
++#endif /* CONFIG_SMP */
++
++	mpic->flags = flags;
++	mpic->isu_size = isu_size;
++	mpic->irq_offset = irq_offset;
++	mpic->irq_count = irq_count;
++	mpic->ipi_offset = ipi_offset;
++	mpic->num_sources = 0; /* so far */
++	mpic->senses = senses;
++	mpic->senses_count = senses_count;
++
++	/* Map the global registers */
++	mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
++	mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
++	BUG_ON(mpic->gregs == NULL);
++
++	/* Reset */
++	if (flags & MPIC_WANTS_RESET) {
++		mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
++			   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
++			   | MPIC_GREG_GCONF_RESET);
++		while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
++		       & MPIC_GREG_GCONF_RESET)
++			mb();
++	}
++
++	/* Read feature register, calculate num CPUs and, for non-ISU
++	 * MPICs, num sources as well. On ISU MPICs, sources are counted
++	 * as ISUs are added
++	 */
++	reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
++	mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
++			  >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
++	if (isu_size == 0)
++		mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK)
++				     >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
++
++	/* Map the per-CPU registers */
++	for (i = 0; i < mpic->num_cpus; i++) {
++		mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
++					   i * MPIC_CPU_STRIDE, 0x1000);
++		BUG_ON(mpic->cpuregs[i] == NULL);
++	}
++
++	/* Initialize main ISU if none provided */
++	if (mpic->isu_size == 0) {
++		mpic->isu_size = mpic->num_sources;
++		mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
++					MPIC_IRQ_STRIDE * mpic->isu_size);
++		BUG_ON(mpic->isus[0] == NULL);
++	}
++	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
++	mpic->isu_mask = (1 << mpic->isu_shift) - 1;
++
++	/* Display version */
++	switch (reg & MPIC_GREG_FEATURE_VERSION_MASK) {
++	case 1:
++		vers = "1.0";
++		break;
++	case 2:
++		vers = "1.2";
++		break;
++	case 3:
++		vers = "1.3";
++		break;
++	default:
++		vers = "<unknown>";
++		break;
++	}
++	printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %lx, max %d CPUs\n",
++	       name, vers, phys_addr, mpic->num_cpus);
++	printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", mpic->isu_size,
++	       mpic->isu_shift, mpic->isu_mask);
++
++	mpic->next = mpics;
++	mpics = mpic;
++
++	if (flags & MPIC_PRIMARY)
++		mpic_primary = mpic;
++
++	return mpic;
++}
++
++void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
++			    unsigned long phys_addr)
++{
++	unsigned int isu_first = isu_num * mpic->isu_size;
++
++	BUG_ON(isu_num >= MPIC_MAX_ISU);
++
++	mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size);
++	if ((isu_first + mpic->isu_size) > mpic->num_sources)
++		mpic->num_sources = isu_first + mpic->isu_size;
++}
++
++void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler,
++			       void *data)
++{
++	struct mpic *mpic = mpic_find(irq, NULL);
++	unsigned long flags;
++
++	/* Synchronization here is a bit dodgy, so don't try to replace cascade
++	 * interrupts on the fly too often ... but normally it's set up at boot.
++	 */
++	spin_lock_irqsave(&mpic_lock, flags);
++	if (mpic->cascade)	       
++		mpic_disable_irq(mpic->cascade_vec + mpic->irq_offset);
++	mpic->cascade = NULL;
++	wmb();
++	mpic->cascade_vec = irq - mpic->irq_offset;
++	mpic->cascade_data = data;
++	wmb();
++	mpic->cascade = handler;
++	mpic_enable_irq(irq);
++	spin_unlock_irqrestore(&mpic_lock, flags);
++}
++
++void __init mpic_init(struct mpic *mpic)
++{
++	int i;
++
++	BUG_ON(mpic->num_sources == 0);
++
++	printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);
++
++	/* Set current processor priority to max */
++	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
++
++	/* Initialize timers: just disable them all */
++	for (i = 0; i < 4; i++) {
++		mpic_write(mpic->tmregs,
++			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
++		mpic_write(mpic->tmregs,
++			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
++			   MPIC_VECPRI_MASK |
++			   (MPIC_VEC_TIMER_0 + i));
++	}
++
++	/* Initialize IPIs to our reserved vectors and mark them disabled for now */
++	mpic_test_broken_ipi(mpic);
++	for (i = 0; i < 4; i++) {
++		mpic_ipi_write(i,
++			       MPIC_VECPRI_MASK |
++			       (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
++			       (MPIC_VEC_IPI_0 + i));
++#ifdef CONFIG_SMP
++		if (!(mpic->flags & MPIC_PRIMARY))
++			continue;
++		irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU;
++		irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi;
++#endif /* CONFIG_SMP */
++	}
++
++	/* Initialize interrupt sources */
++	if (mpic->irq_count == 0)
++		mpic->irq_count = mpic->num_sources;
++
++#ifdef CONFIG_MPIC_BROKEN_U3
++	/* Do the ioapic fixups on U3 broken mpic */
++	DBG("MPIC flags: %x\n", mpic->flags);
++	if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY))
++		mpic_scan_ioapics(mpic);
++#endif /* CONFIG_MPIC_BROKEN_U3 */
++
++	for (i = 0; i < mpic->num_sources; i++) {
++		/* start with vector = source number, and masked */
++		u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT);
++		int level = 0;
++		
++		/* if it's an IPI, we skip it */
++		if ((mpic->irq_offset + i) >= (mpic->ipi_offset + i) &&
++		    (mpic->irq_offset + i) <  (mpic->ipi_offset + i + 4))
++			continue;
++
++		/* do senses munging */
++		if (mpic->senses && i < mpic->senses_count) {
++			if (mpic->senses[i] & IRQ_SENSE_LEVEL)
++				vecpri |= MPIC_VECPRI_SENSE_LEVEL;
++			if (mpic->senses[i] & IRQ_POLARITY_POSITIVE)
++				vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
++		} else
++			vecpri |= MPIC_VECPRI_SENSE_LEVEL;
++
++		/* remember if it was a level interrupts */
++		level = (vecpri & MPIC_VECPRI_SENSE_LEVEL);
++
++		/* deal with broken U3 */
++		if (mpic->flags & MPIC_BROKEN_U3) {
++#ifdef CONFIG_MPIC_BROKEN_U3
++			if (mpic_is_ht_interrupt(mpic, i)) {
++				vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
++					    MPIC_VECPRI_POLARITY_MASK);
++				vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
++			}
++#else
++			printk(KERN_ERR "mpic: BROKEN_U3 set, but CONFIG doesn't match\n");
++#endif
++		}
++
++		DBG("setup source %d, vecpri: %08x, level: %d\n", i, vecpri,
++		    (level != 0));
++
++		/* init hw */
++		mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
++		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
++			       1 << hard_smp_processor_id());
++
++		/* init linux descriptors */
++		if (i < mpic->irq_count) {
++			irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0;
++			irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq;
++		}
++	}
++	
++	/* Init spurrious vector */
++	mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS);
++
++	/* Disable 8259 passthrough */
++	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
++		   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
++		   | MPIC_GREG_GCONF_8259_PTHROU_DIS);
++
++	/* Set current processor priority to 0 */
++	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
++}
++
++
++
++void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
++{
++	int is_ipi;
++	struct mpic *mpic = mpic_find(irq, &is_ipi);
++	unsigned long flags;
++	u32 reg;
++
++	spin_lock_irqsave(&mpic_lock, flags);
++	if (is_ipi) {
++		reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK;
++		mpic_ipi_write(irq - mpic->ipi_offset,
++			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
++	} else {
++		reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI)
++			& MPIC_VECPRI_PRIORITY_MASK;
++		mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
++			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
++	}
++	spin_unlock_irqrestore(&mpic_lock, flags);
++}
++
++unsigned int mpic_irq_get_priority(unsigned int irq)
++{
++	int is_ipi;
++	struct mpic *mpic = mpic_find(irq, &is_ipi);
++	unsigned long flags;
++	u32 reg;
++
++	spin_lock_irqsave(&mpic_lock, flags);
++	if (is_ipi)
++		reg = mpic_ipi_read(irq - mpic->ipi_offset);
++	else
++		reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI);
++	spin_unlock_irqrestore(&mpic_lock, flags);
++	return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT;
++}
++
++void mpic_setup_this_cpu(void)
++{
++#ifdef CONFIG_SMP
++	struct mpic *mpic = mpic_primary;
++	unsigned long flags;
++	u32 msk = 1 << hard_smp_processor_id();
++	unsigned int i;
++
++	BUG_ON(mpic == NULL);
++
++	DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
++
++	spin_lock_irqsave(&mpic_lock, flags);
++
++ 	/* let the mpic know we want intrs. default affinity is 0xffffffff
++	 * until changed via /proc. That's how it's done on x86. If we want
++	 * it differently, then we should make sure we also change the default
++	 * values of irq_affinity in irq.c.
++ 	 */
++	if (distribute_irqs) {
++	 	for (i = 0; i < mpic->num_sources ; i++)
++			mpic_irq_write(i, MPIC_IRQ_DESTINATION,
++				mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
++	}
++
++	/* Set current processor priority to 0 */
++	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
++
++	spin_unlock_irqrestore(&mpic_lock, flags);
++#endif /* CONFIG_SMP */
++}
++
++int mpic_cpu_get_priority(void)
++{
++	struct mpic *mpic = mpic_primary;
++
++	return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
++}
++
++void mpic_cpu_set_priority(int prio)
++{
++	struct mpic *mpic = mpic_primary;
++
++	prio &= MPIC_CPU_TASKPRI_MASK;
++	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
++}
++
++/*
++ * XXX: someone who knows mpic should check this.
++ * do we need to eoi the ipi including for kexec cpu here (see xics comments)?
++ * or can we reset the mpic in the new kernel?
++ */
++void mpic_teardown_this_cpu(int secondary)
++{
++	struct mpic *mpic = mpic_primary;
++	unsigned long flags;
++	u32 msk = 1 << hard_smp_processor_id();
++	unsigned int i;
++
++	BUG_ON(mpic == NULL);
++
++	DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
++	spin_lock_irqsave(&mpic_lock, flags);
++
++	/* let the mpic know we don't want intrs.  */
++	for (i = 0; i < mpic->num_sources ; i++)
++		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
++			mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
++
++	/* Set current processor priority to max */
++	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
++
++	spin_unlock_irqrestore(&mpic_lock, flags);
++}
++
++
++void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
++{
++	struct mpic *mpic = mpic_primary;
++
++	BUG_ON(mpic == NULL);
++
++	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
++
++	mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
++		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
++}
++
++int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
++{
++	u32 irq;
++
++	irq = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
++	DBG("%s: get_one_irq(): %d\n", mpic->name, irq);
++
++	if (mpic->cascade && irq == mpic->cascade_vec) {
++		DBG("%s: cascading ...\n", mpic->name);
++		irq = mpic->cascade(regs, mpic->cascade_data);
++		mpic_eoi(mpic);
++		return irq;
++	}
++	if (unlikely(irq == MPIC_VEC_SPURRIOUS))
++		return -1;
++	if (irq < MPIC_VEC_IPI_0) 
++		return irq + mpic->irq_offset;
++       	DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
++	return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset;
++}
++
++int mpic_get_irq(struct pt_regs *regs)
++{
++	struct mpic *mpic = mpic_primary;
++
++	BUG_ON(mpic == NULL);
++
++	return mpic_get_one_irq(mpic, regs);
++}
++
++
++#ifdef CONFIG_SMP
++void mpic_request_ipis(void)
++{
++	struct mpic *mpic = mpic_primary;
++
++	BUG_ON(mpic == NULL);
++	
++	printk("requesting IPIs ... \n");
++
++	/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
++	request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT,
++		    "IPI0 (call function)", mpic);
++	request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT,
++		   "IPI1 (reschedule)", mpic);
++	request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT,
++		   "IPI2 (unused)", mpic);
++	request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT,
++		   "IPI3 (debugger break)", mpic);
++
++	printk("IPIs requested... \n");
++}
++
++void smp_mpic_message_pass(int target, int msg)
++{
++	/* make sure we're sending something that translates to an IPI */
++	if ((unsigned int)msg > 3) {
++		printk("SMP %d: smp_message_pass: unknown msg %d\n",
++		       smp_processor_id(), msg);
++		return;
++	}
++	switch (target) {
++	case MSG_ALL:
++		mpic_send_ipi(msg, 0xffffffff);
++		break;
++	case MSG_ALL_BUT_SELF:
++		mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id()));
++		break;
++	default:
++		mpic_send_ipi(msg, 1 << target);
++		break;
++	}
++}
++#endif /* CONFIG_SMP */
+diff --git a/arch/powerpc/sysdev/u3_iommu.c b/arch/powerpc/sysdev/u3_iommu.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/sysdev/u3_iommu.c
+@@ -0,0 +1,327 @@
++/*
++ * arch/ppc64/kernel/u3_iommu.c
++ *
++ * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, IBM Corporation
++ *
++ * Based on pSeries_iommu.c:
++ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
++ * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, IBM Corporation
++ *
++ * Dynamic DMA mapping support, Apple U3 & IBM CPC925 "DART" iommu.
++ *
++ * 
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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/config.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/pci.h>
++#include <linux/dma-mapping.h>
++#include <linux/vmalloc.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++#include <asm/ppcdebug.h>
++#include <asm/iommu.h>
++#include <asm/pci-bridge.h>
++#include <asm/machdep.h>
++#include <asm/abs_addr.h>
++#include <asm/cacheflush.h>
++#include <asm/lmb.h>
++#include <asm/dart.h>
++#include <asm/ppc-pci.h>
++
++extern int iommu_force_on;
++
++/* Physical base address and size of the DART table */
++unsigned long dart_tablebase; /* exported to htab_initialize */
++static unsigned long dart_tablesize;
++
++/* Virtual base address of the DART table */
++static u32 *dart_vbase;
++
++/* Mapped base address for the dart */
++static unsigned int *dart; 
++
++/* Dummy val that entries are set to when unused */
++static unsigned int dart_emptyval;
++
++static struct iommu_table iommu_table_u3;
++static int iommu_table_u3_inited;
++static int dart_dirty;
++
++#define DBG(...)
++
++static inline void dart_tlb_invalidate_all(void)
++{
++	unsigned long l = 0;
++	unsigned int reg;
++	unsigned long limit;
++
++	DBG("dart: flush\n");
++
++	/* To invalidate the DART, set the DARTCNTL_FLUSHTLB bit in the
++	 * control register and wait for it to clear.
++	 *
++	 * Gotcha: Sometimes, the DART won't detect that the bit gets
++	 * set. If so, clear it and set it again.
++	 */ 
++
++	limit = 0;
++
++retry:
++	reg = in_be32((unsigned int *)dart+DARTCNTL);
++	reg |= DARTCNTL_FLUSHTLB;
++	out_be32((unsigned int *)dart+DARTCNTL, reg);
++
++	l = 0;
++	while ((in_be32((unsigned int *)dart+DARTCNTL) & DARTCNTL_FLUSHTLB) &&
++		l < (1L<<limit)) {
++		l++;
++	}
++	if (l == (1L<<limit)) {
++		if (limit < 4) {
++			limit++;
++		        reg = in_be32((unsigned int *)dart+DARTCNTL);
++		        reg &= ~DARTCNTL_FLUSHTLB;
++		        out_be32((unsigned int *)dart+DARTCNTL, reg);
++			goto retry;
++		} else
++			panic("U3-DART: TLB did not flush after waiting a long "
++			      "time. Buggy U3 ?");
++	}
++}
++
++static void dart_flush(struct iommu_table *tbl)
++{
++	if (dart_dirty)
++		dart_tlb_invalidate_all();
++	dart_dirty = 0;
++}
++
++static void dart_build(struct iommu_table *tbl, long index, 
++		       long npages, unsigned long uaddr,
++		       enum dma_data_direction direction)
++{
++	unsigned int *dp;
++	unsigned int rpn;
++
++	DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);
++
++	index <<= DART_PAGE_FACTOR;
++	npages <<= DART_PAGE_FACTOR;
++
++	dp = ((unsigned int*)tbl->it_base) + index;
++	
++	/* On U3, all memory is contigous, so we can move this
++	 * out of the loop.
++	 */
++	while (npages--) {
++		rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT;
++
++		*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
++
++		rpn++;
++		uaddr += DART_PAGE_SIZE;
++	}
++
++	dart_dirty = 1;
++}
++
++
++static void dart_free(struct iommu_table *tbl, long index, long npages)
++{
++	unsigned int *dp;
++	
++	/* We don't worry about flushing the TLB cache. The only drawback of
++	 * not doing it is that we won't catch buggy device drivers doing
++	 * bad DMAs, but then no 32-bit architecture ever does either.
++	 */
++
++	DBG("dart: free at: %lx, %lx\n", index, npages);
++
++	index <<= DART_PAGE_FACTOR;
++	npages <<= DART_PAGE_FACTOR;
++
++	dp  = ((unsigned int *)tbl->it_base) + index;
++		
++	while (npages--)
++		*(dp++) = dart_emptyval;
++}
++
++
++static int dart_init(struct device_node *dart_node)
++{
++	unsigned int regword;
++	unsigned int i;
++	unsigned long tmp;
++
++	if (dart_tablebase == 0 || dart_tablesize == 0) {
++		printk(KERN_INFO "U3-DART: table not allocated, using direct DMA\n");
++		return -ENODEV;
++	}
++
++	/* Make sure nothing from the DART range remains in the CPU cache
++	 * from a previous mapping that existed before the kernel took
++	 * over
++	 */
++	flush_dcache_phys_range(dart_tablebase, dart_tablebase + dart_tablesize);
++
++	/* Allocate a spare page to map all invalid DART pages. We need to do
++	 * that to work around what looks like a problem with the HT bridge
++	 * prefetching into invalid pages and corrupting data
++	 */
++	tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
++	if (!tmp)
++		panic("U3-DART: Cannot allocate spare page!");
++	dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & DARTMAP_RPNMASK);
++
++	/* Map in DART registers. FIXME: Use device node to get base address */
++	dart = ioremap(DART_BASE, 0x7000);
++	if (dart == NULL)
++		panic("U3-DART: Cannot map registers!");
++
++	/* Set initial control register contents: table base, 
++	 * table size and enable bit
++	 */
++	regword = DARTCNTL_ENABLE | 
++		((dart_tablebase >> DART_PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
++		(((dart_tablesize >> DART_PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
++				 << DARTCNTL_SIZE_SHIFT);
++	dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize);
++
++	/* Fill initial table */
++	for (i = 0; i < dart_tablesize/4; i++)
++		dart_vbase[i] = dart_emptyval;
++
++	/* Initialize DART with table base and enable it. */
++	out_be32((unsigned int *)dart, regword);
++
++	/* Invalidate DART to get rid of possible stale TLBs */
++	dart_tlb_invalidate_all();
++
++	printk(KERN_INFO "U3/CPC925 DART IOMMU initialized\n");
++
++	return 0;
++}
++
++static void iommu_table_u3_setup(void)
++{
++	iommu_table_u3.it_busno = 0;
++	iommu_table_u3.it_offset = 0;
++	/* it_size is in number of entries */
++	iommu_table_u3.it_size = dart_tablesize / sizeof(u32);
++
++	/* Initialize the common IOMMU code */
++	iommu_table_u3.it_base = (unsigned long)dart_vbase;
++	iommu_table_u3.it_index = 0;
++	iommu_table_u3.it_blocksize = 1;
++	iommu_init_table(&iommu_table_u3);
++
++	/* Reserve the last page of the DART to avoid possible prefetch
++	 * past the DART mapped area
++	 */
++	set_bit(iommu_table_u3.it_size - 1, iommu_table_u3.it_map);
++}
++
++static void iommu_dev_setup_u3(struct pci_dev *dev)
++{
++	struct device_node *dn;
++
++	/* We only have one iommu table on the mac for now, which makes
++	 * things simple. Setup all PCI devices to point to this table
++	 *
++	 * We must use pci_device_to_OF_node() to make sure that
++	 * we get the real "final" pointer to the device in the
++	 * pci_dev sysdata and not the temporary PHB one
++	 */
++	dn = pci_device_to_OF_node(dev);
++
++	if (dn)
++		PCI_DN(dn)->iommu_table = &iommu_table_u3;
++}
++
++static void iommu_bus_setup_u3(struct pci_bus *bus)
++{
++	struct device_node *dn;
++
++	if (!iommu_table_u3_inited) {
++		iommu_table_u3_inited = 1;
++		iommu_table_u3_setup();
++	}
++
++	dn = pci_bus_to_OF_node(bus);
++
++	if (dn)
++		PCI_DN(dn)->iommu_table = &iommu_table_u3;
++}
++
++static void iommu_dev_setup_null(struct pci_dev *dev) { }
++static void iommu_bus_setup_null(struct pci_bus *bus) { }
++
++void iommu_init_early_u3(void)
++{
++	struct device_node *dn;
++
++	/* Find the DART in the device-tree */
++	dn = of_find_compatible_node(NULL, "dart", "u3-dart");
++	if (dn == NULL)
++		return;
++
++	/* Setup low level TCE operations for the core IOMMU code */
++	ppc_md.tce_build = dart_build;
++	ppc_md.tce_free  = dart_free;
++	ppc_md.tce_flush = dart_flush;
++
++	/* Initialize the DART HW */
++	if (dart_init(dn)) {
++		/* If init failed, use direct iommu and null setup functions */
++		ppc_md.iommu_dev_setup = iommu_dev_setup_null;
++		ppc_md.iommu_bus_setup = iommu_bus_setup_null;
++
++		/* Setup pci_dma ops */
++		pci_direct_iommu_init();
++	} else {
++		ppc_md.iommu_dev_setup = iommu_dev_setup_u3;
++		ppc_md.iommu_bus_setup = iommu_bus_setup_u3;
++
++		/* Setup pci_dma ops */
++		pci_iommu_init();
++	}
++}
++
++
++void __init alloc_u3_dart_table(void)
++{
++	/* Only reserve DART space if machine has more than 2GB of RAM
++	 * or if requested with iommu=on on cmdline.
++	 */
++	if (lmb_end_of_DRAM() <= 0x80000000ull && !iommu_force_on)
++		return;
++
++	/* 512 pages (2MB) is max DART tablesize. */
++	dart_tablesize = 1UL << 21;
++	/* 16MB (1 << 24) alignment. We allocate a full 16Mb chuck since we
++	 * will blow up an entire large page anyway in the kernel mapping
++	 */
++	dart_tablebase = (unsigned long)
++		abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
++
++	printk(KERN_INFO "U3-DART allocated at: %lx\n", dart_tablebase);
++}
+diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/Makefile
+@@ -0,0 +1,11 @@
++# Makefile for xmon
++
++ifdef CONFIG_PPC64
++EXTRA_CFLAGS += -mno-minimal-toc
++endif
++
++obj-$(CONFIG_8xx)	+= start_8xx.o
++obj-$(CONFIG_6xx)	+= start_32.o
++obj-$(CONFIG_4xx)	+= start_32.o
++obj-$(CONFIG_PPC64)	+= start_64.o
++obj-y			+= xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
+diff --git a/arch/powerpc/xmon/ansidecl.h b/arch/powerpc/xmon/ansidecl.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/ansidecl.h
+@@ -0,0 +1,141 @@
++/* ANSI and traditional C compatibility macros
++   Copyright 1991, 1992 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++This program is free software; you can redistribute it and/or modify
++it under the terms of the 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.  */
++
++/* ANSI and traditional C compatibility macros
++
++   ANSI C is assumed if __STDC__ is #defined.
++
++   Macro	ANSI C definition	Traditional C definition
++   -----	---- - ----------	----------- - ----------
++   PTR		`void *'		`char *'
++   LONG_DOUBLE	`long double'		`double'
++   VOLATILE	`volatile'		`'
++   SIGNED	`signed'		`'
++   PTRCONST	`void *const'		`char *'
++   ANSI_PROTOTYPES  1			not defined
++
++   CONST is also defined, but is obsolete.  Just use const.
++
++   DEFUN (name, arglist, args)
++
++	Defines function NAME.
++
++	ARGLIST lists the arguments, separated by commas and enclosed in
++	parentheses.  ARGLIST becomes the argument list in traditional C.
++
++	ARGS list the arguments with their types.  It becomes a prototype in
++	ANSI C, and the type declarations in traditional C.  Arguments should
++	be separated with `AND'.  For functions with a variable number of
++	arguments, the last thing listed should be `DOTS'.
++
++   DEFUN_VOID (name)
++
++	Defines a function NAME, which takes no arguments.
++
++   obsolete --     EXFUN (name, (prototype))	-- obsolete.
++
++	Replaced by PARAMS.  Do not use; will disappear someday soon.
++	Was used in external function declarations.
++	In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
++	parentheses).  In traditional C it is `NAME()'.
++	For a function that takes no arguments, PROTOTYPE should be `(void)'.
++
++    PARAMS ((args))
++
++	We could use the EXFUN macro to handle prototype declarations, but
++	the name is misleading and the result is ugly.  So we just define a
++	simple macro to handle the parameter lists, as in:
++
++	      static int foo PARAMS ((int, char));
++
++	This produces:  `static int foo();' or `static int foo (int, char);'
++
++	EXFUN would have done it like this:
++
++	      static int EXFUN (foo, (int, char));
++
++	but the function is not external...and it's hard to visually parse
++	the function name out of the mess.   EXFUN should be considered
++	obsolete; new code should be written to use PARAMS.
++
++    For example:
++	extern int printf PARAMS ((CONST char *format DOTS));
++	int DEFUN(fprintf, (stream, format),
++		  FILE *stream AND CONST char *format DOTS) { ... }
++	void DEFUN_VOID(abort) { ... }
++*/
++
++#ifndef	_ANSIDECL_H
++
++#define	_ANSIDECL_H	1
++
++
++/* Every source file includes this file,
++   so they will all get the switch for lint.  */
++/* LINTLIBRARY */
++
++
++#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32)
++/* All known AIX compilers implement these things (but don't always
++   define __STDC__).  The RISC/OS MIPS compiler defines these things
++   in SVR4 mode, but does not define __STDC__.  */
++
++#define	PTR		void *
++#define	PTRCONST	void *CONST
++#define	LONG_DOUBLE	long double
++
++#define	AND		,
++#define	NOARGS		void
++#define	CONST		const
++#define	VOLATILE	volatile
++#define	SIGNED		signed
++#define	DOTS		, ...
++
++#define	EXFUN(name, proto)		name proto
++#define	DEFUN(name, arglist, args)	name(args)
++#define	DEFUN_VOID(name)		name(void)
++
++#define PROTO(type, name, arglist)	type name arglist
++#define PARAMS(paramlist)		paramlist
++#define ANSI_PROTOTYPES			1
++
++#else	/* Not ANSI C.  */
++
++#define	PTR		char *
++#define	PTRCONST	PTR
++#define	LONG_DOUBLE	double
++
++#define	AND		;
++#define	NOARGS
++#define	CONST
++#ifndef const /* some systems define it in header files for non-ansi mode */
++#define	const
++#endif
++#define	VOLATILE
++#define	SIGNED
++#define	DOTS
++
++#define	EXFUN(name, proto)		name()
++#define	DEFUN(name, arglist, args)	name arglist args;
++#define	DEFUN_VOID(name)		name()
++#define PROTO(type, name, arglist) type name ()
++#define PARAMS(paramlist)		()
++
++#endif	/* ANSI C.  */
++
++#endif	/* ansidecl.h	*/
+diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/nonstdio.h
+@@ -0,0 +1,22 @@
++typedef int	FILE;
++extern FILE *xmon_stdin, *xmon_stdout;
++#define EOF	(-1)
++#define stdin	xmon_stdin
++#define stdout	xmon_stdout
++#define printf	xmon_printf
++#define fprintf	xmon_fprintf
++#define fputs	xmon_fputs
++#define fgets	xmon_fgets
++#define putchar	xmon_putchar
++#define getchar	xmon_getchar
++#define putc	xmon_putc
++#define getc	xmon_getc
++#define fopen(n, m)	NULL
++#define fflush(f)	do {} while (0)
++#define fclose(f)	do {} while (0)
++extern char *fgets(char *, int, void *);
++extern void xmon_printf(const char *, ...);
++extern void xmon_fprintf(void *, const char *, ...);
++extern void xmon_sprintf(char *, const char *, ...);
++
++#define perror(s)	printf("%s: no files!\n", (s))
+diff --git a/arch/powerpc/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/ppc-dis.c
+@@ -0,0 +1,184 @@
++/* ppc-dis.c -- Disassemble PowerPC instructions
++   Copyright 1994 Free Software Foundation, Inc.
++   Written by Ian Lance Taylor, Cygnus Support
++
++This file is part of GDB, GAS, and the GNU binutils.
++
++GDB, GAS, and the GNU binutils are free software; you can redistribute
++them and/or modify them 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.
++
++GDB, GAS, and the GNU binutils are distributed in the hope that they
++will be useful, but WITHOUT ANY WARRANTY; without even the implied
++warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++the GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this file; see the file COPYING.  If not, write to the Free
++Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
++
++#include "nonstdio.h"
++#include "ansidecl.h"
++#include "ppc.h"
++
++extern void print_address (unsigned long memaddr);
++
++/* Print a PowerPC or POWER instruction.  */
++
++int
++print_insn_powerpc (unsigned long insn, unsigned long memaddr, int dialect)
++{
++  const struct powerpc_opcode *opcode;
++  const struct powerpc_opcode *opcode_end;
++  unsigned long op;
++
++  if (dialect == 0)
++    dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON
++	      | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC;
++
++  /* Get the major opcode of the instruction.  */
++  op = PPC_OP (insn);
++
++  /* Find the first match in the opcode table.  We could speed this up
++     a bit by doing a binary search on the major opcode.  */
++  opcode_end = powerpc_opcodes + powerpc_num_opcodes;
++ again:
++  for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
++    {
++      unsigned long table_op;
++      const unsigned char *opindex;
++      const struct powerpc_operand *operand;
++      int invalid;
++      int need_comma;
++      int need_paren;
++
++      table_op = PPC_OP (opcode->opcode);
++      if (op < table_op)
++	break;
++      if (op > table_op)
++	continue;
++
++      if ((insn & opcode->mask) != opcode->opcode
++	  || (opcode->flags & dialect) == 0)
++	continue;
++
++      /* Make two passes over the operands.  First see if any of them
++	 have extraction functions, and, if they do, make sure the
++	 instruction is valid.  */
++      invalid = 0;
++      for (opindex = opcode->operands; *opindex != 0; opindex++)
++	{
++	  operand = powerpc_operands + *opindex;
++	  if (operand->extract)
++	    (*operand->extract) (insn, dialect, &invalid);
++	}
++      if (invalid)
++	continue;
++
++      /* The instruction is valid.  */
++      printf("%s", opcode->name);
++      if (opcode->operands[0] != 0)
++	printf("\t");
++
++      /* Now extract and print the operands.  */
++      need_comma = 0;
++      need_paren = 0;
++      for (opindex = opcode->operands; *opindex != 0; opindex++)
++	{
++	  long value;
++
++	  operand = powerpc_operands + *opindex;
++
++	  /* Operands that are marked FAKE are simply ignored.  We
++	     already made sure that the extract function considered
++	     the instruction to be valid.  */
++	  if ((operand->flags & PPC_OPERAND_FAKE) != 0)
++	    continue;
++
++	  /* Extract the value from the instruction.  */
++	  if (operand->extract)
++	    value = (*operand->extract) (insn, dialect, &invalid);
++	  else
++	    {
++	      value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
++	      if ((operand->flags & PPC_OPERAND_SIGNED) != 0
++		  && (value & (1 << (operand->bits - 1))) != 0)
++		value -= 1 << operand->bits;
++	    }
++
++	  /* If the operand is optional, and the value is zero, don't
++	     print anything.  */
++	  if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
++	      && (operand->flags & PPC_OPERAND_NEXT) == 0
++	      && value == 0)
++	    continue;
++
++	  if (need_comma)
++	    {
++	      printf(",");
++	      need_comma = 0;
++	    }
++
++	  /* Print the operand as directed by the flags.  */
++	  if ((operand->flags & PPC_OPERAND_GPR) != 0)
++	    printf("r%ld", value);
++	  else if ((operand->flags & PPC_OPERAND_FPR) != 0)
++	    printf("f%ld", value);
++	  else if ((operand->flags & PPC_OPERAND_VR) != 0)
++	    printf("v%ld", value);
++	  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
++	    print_address (memaddr + value);
++	  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
++	    print_address (value & 0xffffffff);
++	  else if ((operand->flags & PPC_OPERAND_CR) == 0
++		   || (dialect & PPC_OPCODE_PPC) == 0)
++	    printf("%ld", value);
++	  else
++	    {
++	      if (operand->bits == 3)
++		printf("cr%d", value);
++	      else
++		{
++		  static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
++		  int cr;
++		  int cc;
++
++		  cr = value >> 2;
++		  if (cr != 0)
++		    printf("4*cr%d+", cr);
++		  cc = value & 3;
++		  printf("%s", cbnames[cc]);
++		}
++	    }
++
++	  if (need_paren)
++	    {
++	      printf(")");
++	      need_paren = 0;
++	    }
++
++	  if ((operand->flags & PPC_OPERAND_PARENS) == 0)
++	    need_comma = 1;
++	  else
++	    {
++	      printf("(");
++	      need_paren = 1;
++	    }
++	}
++
++      /* We have found and printed an instruction; return.  */
++      return 4;
++    }
++
++  if ((dialect & PPC_OPCODE_ANY) != 0)
++    {
++      dialect = ~PPC_OPCODE_ANY;
++      goto again;
++    }
++
++  /* We could not find a match.  */
++  printf(".long 0x%lx", insn);
++
++  return 4;
++}
+diff --git a/arch/powerpc/xmon/ppc-opc.c b/arch/powerpc/xmon/ppc-opc.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/ppc-opc.c
+@@ -0,0 +1,4621 @@
++/* ppc-opc.c -- PowerPC opcode list
++   Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
++   Free Software Foundation, Inc.
++   Written by Ian Lance Taylor, Cygnus Support
++
++   This file is part of GDB, GAS, and the GNU binutils.
++
++   GDB, GAS, and the GNU binutils are free software; you can redistribute
++   them and/or modify them 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.
++
++   GDB, GAS, and the GNU binutils are distributed in the hope that they
++   will be useful, but WITHOUT ANY WARRANTY; without even the implied
++   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++   the GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this file; see the file COPYING.  If not, write to the Free
++   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
++   02111-1307, USA.  */
++
++#include <linux/stddef.h>
++#include "nonstdio.h"
++#include "ppc.h"
++
++#define ATTRIBUTE_UNUSED
++#define _(x)	x
++
++/* This file holds the PowerPC opcode table.  The opcode table
++   includes almost all of the extended instruction mnemonics.  This
++   permits the disassembler to use them, and simplifies the assembler
++   logic, at the cost of increasing the table size.  The table is
++   strictly constant data, so the compiler should be able to put it in
++   the .text section.
++
++   This file also holds the operand table.  All knowledge about
++   inserting operands into instructions and vice-versa is kept in this
++   file.  */
++
++/* Local insertion and extraction functions.  */
++
++static unsigned long insert_bat (unsigned long, long, int, const char **);
++static long extract_bat (unsigned long, int, int *);
++static unsigned long insert_bba (unsigned long, long, int, const char **);
++static long extract_bba (unsigned long, int, int *);
++static unsigned long insert_bd (unsigned long, long, int, const char **);
++static long extract_bd (unsigned long, int, int *);
++static unsigned long insert_bdm (unsigned long, long, int, const char **);
++static long extract_bdm (unsigned long, int, int *);
++static unsigned long insert_bdp (unsigned long, long, int, const char **);
++static long extract_bdp (unsigned long, int, int *);
++static unsigned long insert_bo (unsigned long, long, int, const char **);
++static long extract_bo (unsigned long, int, int *);
++static unsigned long insert_boe (unsigned long, long, int, const char **);
++static long extract_boe (unsigned long, int, int *);
++static unsigned long insert_dq (unsigned long, long, int, const char **);
++static long extract_dq (unsigned long, int, int *);
++static unsigned long insert_ds (unsigned long, long, int, const char **);
++static long extract_ds (unsigned long, int, int *);
++static unsigned long insert_de (unsigned long, long, int, const char **);
++static long extract_de (unsigned long, int, int *);
++static unsigned long insert_des (unsigned long, long, int, const char **);
++static long extract_des (unsigned long, int, int *);
++static unsigned long insert_fxm (unsigned long, long, int, const char **);
++static long extract_fxm (unsigned long, int, int *);
++static unsigned long insert_li (unsigned long, long, int, const char **);
++static long extract_li (unsigned long, int, int *);
++static unsigned long insert_mbe (unsigned long, long, int, const char **);
++static long extract_mbe (unsigned long, int, int *);
++static unsigned long insert_mb6 (unsigned long, long, int, const char **);
++static long extract_mb6 (unsigned long, int, int *);
++static unsigned long insert_nb (unsigned long, long, int, const char **);
++static long extract_nb (unsigned long, int, int *);
++static unsigned long insert_nsi (unsigned long, long, int, const char **);
++static long extract_nsi (unsigned long, int, int *);
++static unsigned long insert_ral (unsigned long, long, int, const char **);
++static unsigned long insert_ram (unsigned long, long, int, const char **);
++static unsigned long insert_raq (unsigned long, long, int, const char **);
++static unsigned long insert_ras (unsigned long, long, int, const char **);
++static unsigned long insert_rbs (unsigned long, long, int, const char **);
++static long extract_rbs (unsigned long, int, int *);
++static unsigned long insert_rsq (unsigned long, long, int, const char **);
++static unsigned long insert_rtq (unsigned long, long, int, const char **);
++static unsigned long insert_sh6 (unsigned long, long, int, const char **);
++static long extract_sh6 (unsigned long, int, int *);
++static unsigned long insert_spr (unsigned long, long, int, const char **);
++static long extract_spr (unsigned long, int, int *);
++static unsigned long insert_tbr (unsigned long, long, int, const char **);
++static long extract_tbr (unsigned long, int, int *);
++static unsigned long insert_ev2 (unsigned long, long, int, const char **);
++static long extract_ev2 (unsigned long, int, int *);
++static unsigned long insert_ev4 (unsigned long, long, int, const char **);
++static long extract_ev4 (unsigned long, int, int *);
++static unsigned long insert_ev8 (unsigned long, long, int, const char **);
++static long extract_ev8 (unsigned long, int, int *);
++
++/* The operands table.
++
++   The fields are bits, shift, insert, extract, flags.
++
++   We used to put parens around the various additions, like the one
++   for BA just below.  However, that caused trouble with feeble
++   compilers with a limit on depth of a parenthesized expression, like
++   (reportedly) the compiler in Microsoft Developer Studio 5.  So we
++   omit the parens, since the macros are never used in a context where
++   the addition will be ambiguous.  */
++
++const struct powerpc_operand powerpc_operands[] =
++{
++  /* The zero index is used to indicate the end of the list of
++     operands.  */
++#define UNUSED 0
++  { 0, 0, NULL, NULL, 0 },
++
++  /* The BA field in an XL form instruction.  */
++#define BA UNUSED + 1
++#define BA_MASK (0x1f << 16)
++  { 5, 16, NULL, NULL, PPC_OPERAND_CR },
++
++  /* The BA field in an XL form instruction when it must be the same
++     as the BT field in the same instruction.  */
++#define BAT BA + 1
++  { 5, 16, insert_bat, extract_bat, PPC_OPERAND_FAKE },
++
++  /* The BB field in an XL form instruction.  */
++#define BB BAT + 1
++#define BB_MASK (0x1f << 11)
++  { 5, 11, NULL, NULL, PPC_OPERAND_CR },
++
++  /* The BB field in an XL form instruction when it must be the same
++     as the BA field in the same instruction.  */
++#define BBA BB + 1
++  { 5, 11, insert_bba, extract_bba, PPC_OPERAND_FAKE },
++
++  /* The BD field in a B form instruction.  The lower two bits are
++     forced to zero.  */
++#define BD BBA + 1
++  { 16, 0, insert_bd, extract_bd, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
++
++  /* The BD field in a B form instruction when absolute addressing is
++     used.  */
++#define BDA BD + 1
++  { 16, 0, insert_bd, extract_bd, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
++
++  /* The BD field in a B form instruction when the - modifier is used.
++     This sets the y bit of the BO field appropriately.  */
++#define BDM BDA + 1
++  { 16, 0, insert_bdm, extract_bdm,
++      PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
++
++  /* The BD field in a B form instruction when the - modifier is used
++     and absolute address is used.  */
++#define BDMA BDM + 1
++  { 16, 0, insert_bdm, extract_bdm,
++      PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
++
++  /* The BD field in a B form instruction when the + modifier is used.
++     This sets the y bit of the BO field appropriately.  */
++#define BDP BDMA + 1
++  { 16, 0, insert_bdp, extract_bdp,
++      PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
++
++  /* The BD field in a B form instruction when the + modifier is used
++     and absolute addressing is used.  */
++#define BDPA BDP + 1
++  { 16, 0, insert_bdp, extract_bdp,
++      PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
++
++  /* The BF field in an X or XL form instruction.  */
++#define BF BDPA + 1
++  { 3, 23, NULL, NULL, PPC_OPERAND_CR },
++
++  /* An optional BF field.  This is used for comparison instructions,
++     in which an omitted BF field is taken as zero.  */
++#define OBF BF + 1
++  { 3, 23, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
++
++  /* The BFA field in an X or XL form instruction.  */
++#define BFA OBF + 1
++  { 3, 18, NULL, NULL, PPC_OPERAND_CR },
++
++  /* The BI field in a B form or XL form instruction.  */
++#define BI BFA + 1
++#define BI_MASK (0x1f << 16)
++  { 5, 16, NULL, NULL, PPC_OPERAND_CR },
++
++  /* The BO field in a B form instruction.  Certain values are
++     illegal.  */
++#define BO BI + 1
++#define BO_MASK (0x1f << 21)
++  { 5, 21, insert_bo, extract_bo, 0 },
++
++  /* The BO field in a B form instruction when the + or - modifier is
++     used.  This is like the BO field, but it must be even.  */
++#define BOE BO + 1
++  { 5, 21, insert_boe, extract_boe, 0 },
++
++  /* The BT field in an X or XL form instruction.  */
++#define BT BOE + 1
++  { 5, 21, NULL, NULL, PPC_OPERAND_CR },
++
++  /* The condition register number portion of the BI field in a B form
++     or XL form instruction.  This is used for the extended
++     conditional branch mnemonics, which set the lower two bits of the
++     BI field.  This field is optional.  */
++#define CR BT + 1
++  { 3, 18, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
++
++  /* The CRB field in an X form instruction.  */
++#define CRB CR + 1
++  { 5, 6, NULL, NULL, 0 },
++
++  /* The CRFD field in an X form instruction.  */
++#define CRFD CRB + 1
++  { 3, 23, NULL, NULL, PPC_OPERAND_CR },
++
++  /* The CRFS field in an X form instruction.  */
++#define CRFS CRFD + 1
++  { 3, 0, NULL, NULL, PPC_OPERAND_CR },
++
++  /* The CT field in an X form instruction.  */
++#define CT CRFS + 1
++  { 5, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
++
++  /* The D field in a D form instruction.  This is a displacement off
++     a register, and implies that the next operand is a register in
++     parentheses.  */
++#define D CT + 1
++  { 16, 0, NULL, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
++
++  /* The DE field in a DE form instruction.  This is like D, but is 12
++     bits only.  */
++#define DE D + 1
++  { 14, 0, insert_de, extract_de, PPC_OPERAND_PARENS },
++
++  /* The DES field in a DES form instruction.  This is like DS, but is 14
++     bits only (12 stored.)  */
++#define DES DE + 1
++  { 14, 0, insert_des, extract_des, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
++
++  /* The DQ field in a DQ form instruction.  This is like D, but the
++     lower four bits are forced to zero. */
++#define DQ DES + 1
++  { 16, 0, insert_dq, extract_dq,
++      PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DQ },
++
++  /* The DS field in a DS form instruction.  This is like D, but the
++     lower two bits are forced to zero.  */
++#define DS DQ + 1
++  { 16, 0, insert_ds, extract_ds,
++      PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS },
++
++  /* The E field in a wrteei instruction.  */
++#define E DS + 1
++  { 1, 15, NULL, NULL, 0 },
++
++  /* The FL1 field in a POWER SC form instruction.  */
++#define FL1 E + 1
++  { 4, 12, NULL, NULL, 0 },
++
++  /* The FL2 field in a POWER SC form instruction.  */
++#define FL2 FL1 + 1
++  { 3, 2, NULL, NULL, 0 },
++
++  /* The FLM field in an XFL form instruction.  */
++#define FLM FL2 + 1
++  { 8, 17, NULL, NULL, 0 },
++
++  /* The FRA field in an X or A form instruction.  */
++#define FRA FLM + 1
++#define FRA_MASK (0x1f << 16)
++  { 5, 16, NULL, NULL, PPC_OPERAND_FPR },
++
++  /* The FRB field in an X or A form instruction.  */
++#define FRB FRA + 1
++#define FRB_MASK (0x1f << 11)
++  { 5, 11, NULL, NULL, PPC_OPERAND_FPR },
++
++  /* The FRC field in an A form instruction.  */
++#define FRC FRB + 1
++#define FRC_MASK (0x1f << 6)
++  { 5, 6, NULL, NULL, PPC_OPERAND_FPR },
++
++  /* The FRS field in an X form instruction or the FRT field in a D, X
++     or A form instruction.  */
++#define FRS FRC + 1
++#define FRT FRS
++  { 5, 21, NULL, NULL, PPC_OPERAND_FPR },
++
++  /* The FXM field in an XFX instruction.  */
++#define FXM FRS + 1
++#define FXM_MASK (0xff << 12)
++  { 8, 12, insert_fxm, extract_fxm, 0 },
++
++  /* Power4 version for mfcr.  */
++#define FXM4 FXM + 1
++  { 8, 12, insert_fxm, extract_fxm, PPC_OPERAND_OPTIONAL },
++
++  /* The L field in a D or X form instruction.  */
++#define L FXM4 + 1
++  { 1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
++
++  /* The LEV field in a POWER SC form instruction.  */
++#define LEV L + 1
++  { 7, 5, NULL, NULL, 0 },
++
++  /* The LI field in an I form instruction.  The lower two bits are
++     forced to zero.  */
++#define LI LEV + 1
++  { 26, 0, insert_li, extract_li, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
++
++  /* The LI field in an I form instruction when used as an absolute
++     address.  */
++#define LIA LI + 1
++  { 26, 0, insert_li, extract_li, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
++
++  /* The LS field in an X (sync) form instruction.  */
++#define LS LIA + 1
++  { 2, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
++
++  /* The MB field in an M form instruction.  */
++#define MB LS + 1
++#define MB_MASK (0x1f << 6)
++  { 5, 6, NULL, NULL, 0 },
++
++  /* The ME field in an M form instruction.  */
++#define ME MB + 1
++#define ME_MASK (0x1f << 1)
++  { 5, 1, NULL, NULL, 0 },
++
++  /* The MB and ME fields in an M form instruction expressed a single
++     operand which is a bitmask indicating which bits to select.  This
++     is a two operand form using PPC_OPERAND_NEXT.  See the
++     description in opcode/ppc.h for what this means.  */
++#define MBE ME + 1
++  { 5, 6, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT },
++  { 32, 0, insert_mbe, extract_mbe, 0 },
++
++  /* The MB or ME field in an MD or MDS form instruction.  The high
++     bit is wrapped to the low end.  */
++#define MB6 MBE + 2
++#define ME6 MB6
++#define MB6_MASK (0x3f << 5)
++  { 6, 5, insert_mb6, extract_mb6, 0 },
++
++  /* The MO field in an mbar instruction.  */
++#define MO MB6 + 1
++  { 5, 21, NULL, NULL, 0 },
++
++  /* The NB field in an X form instruction.  The value 32 is stored as
++     0.  */
++#define NB MO + 1
++  { 6, 11, insert_nb, extract_nb, 0 },
++
++  /* The NSI field in a D form instruction.  This is the same as the
++     SI field, only negated.  */
++#define NSI NB + 1
++  { 16, 0, insert_nsi, extract_nsi,
++      PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
++
++  /* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction.  */
++#define RA NSI + 1
++#define RA_MASK (0x1f << 16)
++  { 5, 16, NULL, NULL, PPC_OPERAND_GPR },
++
++  /* The RA field in the DQ form lq instruction, which has special
++     value restrictions.  */
++#define RAQ RA + 1
++  { 5, 16, insert_raq, NULL, PPC_OPERAND_GPR },
++
++  /* The RA field in a D or X form instruction which is an updating
++     load, which means that the RA field may not be zero and may not
++     equal the RT field.  */
++#define RAL RAQ + 1
++  { 5, 16, insert_ral, NULL, PPC_OPERAND_GPR },
++
++  /* The RA field in an lmw instruction, which has special value
++     restrictions.  */
++#define RAM RAL + 1
++  { 5, 16, insert_ram, NULL, PPC_OPERAND_GPR },
++
++  /* The RA field in a D or X form instruction which is an updating
++     store or an updating floating point load, which means that the RA
++     field may not be zero.  */
++#define RAS RAM + 1
++  { 5, 16, insert_ras, NULL, PPC_OPERAND_GPR },
++
++  /* The RB field in an X, XO, M, or MDS form instruction.  */
++#define RB RAS + 1
++#define RB_MASK (0x1f << 11)
++  { 5, 11, NULL, NULL, PPC_OPERAND_GPR },
++
++  /* The RB field in an X form instruction when it must be the same as
++     the RS field in the instruction.  This is used for extended
++     mnemonics like mr.  */
++#define RBS RB + 1
++  { 5, 1, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
++
++  /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
++     instruction or the RT field in a D, DS, X, XFX or XO form
++     instruction.  */
++#define RS RBS + 1
++#define RT RS
++#define RT_MASK (0x1f << 21)
++  { 5, 21, NULL, NULL, PPC_OPERAND_GPR },
++
++  /* The RS field of the DS form stq instruction, which has special
++     value restrictions.  */
++#define RSQ RS + 1
++  { 5, 21, insert_rsq, NULL, PPC_OPERAND_GPR },
++
++  /* The RT field of the DQ form lq instruction, which has special
++     value restrictions.  */
++#define RTQ RSQ + 1
++  { 5, 21, insert_rtq, NULL, PPC_OPERAND_GPR },
++
++  /* The SH field in an X or M form instruction.  */
++#define SH RTQ + 1
++#define SH_MASK (0x1f << 11)
++  { 5, 11, NULL, NULL, 0 },
++
++  /* The SH field in an MD form instruction.  This is split.  */
++#define SH6 SH + 1
++#define SH6_MASK ((0x1f << 11) | (1 << 1))
++  { 6, 1, insert_sh6, extract_sh6, 0 },
++
++  /* The SI field in a D form instruction.  */
++#define SI SH6 + 1
++  { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED },
++
++  /* The SI field in a D form instruction when we accept a wide range
++     of positive values.  */
++#define SISIGNOPT SI + 1
++  { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT },
++
++  /* The SPR field in an XFX form instruction.  This is flipped--the
++     lower 5 bits are stored in the upper 5 and vice- versa.  */
++#define SPR SISIGNOPT + 1
++#define PMR SPR
++#define SPR_MASK (0x3ff << 11)
++  { 10, 11, insert_spr, extract_spr, 0 },
++
++  /* The BAT index number in an XFX form m[ft]ibat[lu] instruction.  */
++#define SPRBAT SPR + 1
++#define SPRBAT_MASK (0x3 << 17)
++  { 2, 17, NULL, NULL, 0 },
++
++  /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
++#define SPRG SPRBAT + 1
++#define SPRG_MASK (0x3 << 16)
++  { 2, 16, NULL, NULL, 0 },
++
++  /* The SR field in an X form instruction.  */
++#define SR SPRG + 1
++  { 4, 16, NULL, NULL, 0 },
++
++  /* The STRM field in an X AltiVec form instruction.  */
++#define STRM SR + 1
++#define STRM_MASK (0x3 << 21)
++  { 2, 21, NULL, NULL, 0 },
++
++  /* The SV field in a POWER SC form instruction.  */
++#define SV STRM + 1
++  { 14, 2, NULL, NULL, 0 },
++
++  /* The TBR field in an XFX form instruction.  This is like the SPR
++     field, but it is optional.  */
++#define TBR SV + 1
++  { 10, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
++
++  /* The TO field in a D or X form instruction.  */
++#define TO TBR + 1
++#define TO_MASK (0x1f << 21)
++  { 5, 21, NULL, NULL, 0 },
++
++  /* The U field in an X form instruction.  */
++#define U TO + 1
++  { 4, 12, NULL, NULL, 0 },
++
++  /* The UI field in a D form instruction.  */
++#define UI U + 1
++  { 16, 0, NULL, NULL, 0 },
++
++  /* The VA field in a VA, VX or VXR form instruction.  */
++#define VA UI + 1
++#define VA_MASK	(0x1f << 16)
++  { 5, 16, NULL, NULL, PPC_OPERAND_VR },
++
++  /* The VB field in a VA, VX or VXR form instruction.  */
++#define VB VA + 1
++#define VB_MASK (0x1f << 11)
++  { 5, 11, NULL, NULL, PPC_OPERAND_VR },
++
++  /* The VC field in a VA form instruction.  */
++#define VC VB + 1
++#define VC_MASK (0x1f << 6)
++  { 5, 6, NULL, NULL, PPC_OPERAND_VR },
++
++  /* The VD or VS field in a VA, VX, VXR or X form instruction.  */
++#define VD VC + 1
++#define VS VD
++#define VD_MASK (0x1f << 21)
++  { 5, 21, NULL, NULL, PPC_OPERAND_VR },
++
++  /* The SIMM field in a VX form instruction.  */
++#define SIMM VD + 1
++  { 5, 16, NULL, NULL, PPC_OPERAND_SIGNED},
++
++  /* The UIMM field in a VX form instruction.  */
++#define UIMM SIMM + 1
++  { 5, 16, NULL, NULL, 0 },
++
++  /* The SHB field in a VA form instruction.  */
++#define SHB UIMM + 1
++  { 4, 6, NULL, NULL, 0 },
++
++  /* The other UIMM field in a EVX form instruction.  */
++#define EVUIMM SHB + 1
++  { 5, 11, NULL, NULL, 0 },
++
++  /* The other UIMM field in a half word EVX form instruction.  */
++#define EVUIMM_2 EVUIMM + 1
++  { 32, 11, insert_ev2, extract_ev2, PPC_OPERAND_PARENS },
++
++  /* The other UIMM field in a word EVX form instruction.  */
++#define EVUIMM_4 EVUIMM_2 + 1
++  { 32, 11, insert_ev4, extract_ev4, PPC_OPERAND_PARENS },
++
++  /* The other UIMM field in a double EVX form instruction.  */
++#define EVUIMM_8 EVUIMM_4 + 1
++  { 32, 11, insert_ev8, extract_ev8, PPC_OPERAND_PARENS },
++
++  /* The WS field.  */
++#define WS EVUIMM_8 + 1
++#define WS_MASK (0x7 << 11)
++  { 3, 11, NULL, NULL, 0 },
++
++  /* The L field in an mtmsrd instruction */
++#define MTMSRD_L WS + 1
++  { 1, 16, NULL, NULL, PPC_OPERAND_OPTIONAL },
++
++};
++
++/* The functions used to insert and extract complicated operands.  */
++
++/* The BA field in an XL form instruction when it must be the same as
++   the BT field in the same instruction.  This operand is marked FAKE.
++   The insertion function just copies the BT field into the BA field,
++   and the extraction function just checks that the fields are the
++   same.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_bat (unsigned long insn,
++	    long value ATTRIBUTE_UNUSED,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  return insn | (((insn >> 21) & 0x1f) << 16);
++}
++
++static long
++extract_bat (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid)
++{
++  if (((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f))
++    *invalid = 1;
++  return 0;
++}
++
++/* The BB field in an XL form instruction when it must be the same as
++   the BA field in the same instruction.  This operand is marked FAKE.
++   The insertion function just copies the BA field into the BB field,
++   and the extraction function just checks that the fields are the
++   same.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_bba (unsigned long insn,
++	    long value ATTRIBUTE_UNUSED,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  return insn | (((insn >> 16) & 0x1f) << 11);
++}
++
++static long
++extract_bba (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid)
++{
++  if (((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f))
++    *invalid = 1;
++  return 0;
++}
++
++/* The BD field in a B form instruction.  The lower two bits are
++   forced to zero.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_bd (unsigned long insn,
++	   long value,
++	   int dialect ATTRIBUTE_UNUSED,
++	   const char **errmsg ATTRIBUTE_UNUSED)
++{
++  return insn | (value & 0xfffc);
++}
++
++/*ARGSUSED*/
++static long
++extract_bd (unsigned long insn,
++	    int dialect ATTRIBUTE_UNUSED,
++	    int *invalid ATTRIBUTE_UNUSED)
++{
++  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
++}
++
++/* The BD field in a B form instruction when the - modifier is used.
++   This modifier means that the branch is not expected to be taken.
++   For chips built to versions of the architecture prior to version 2
++   (ie. not Power4 compatible), we set the y bit of the BO field to 1
++   if the offset is negative.  When extracting, we require that the y
++   bit be 1 and that the offset be positive, since if the y bit is 0
++   we just want to print the normal form of the instruction.
++   Power4 compatible targets use two bits, "a", and "t", instead of
++   the "y" bit.  "at" == 00 => no hint, "at" == 01 => unpredictable,
++   "at" == 10 => not taken, "at" == 11 => taken.  The "t" bit is 00001
++   in BO field, the "a" bit is 00010 for branch on CR(BI) and 01000
++   for branch on CTR.  We only handle the taken/not-taken hint here.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_bdm (unsigned long insn,
++	    long value,
++	    int dialect,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  if ((dialect & PPC_OPCODE_POWER4) == 0)
++    {
++      if ((value & 0x8000) != 0)
++	insn |= 1 << 21;
++    }
++  else
++    {
++      if ((insn & (0x14 << 21)) == (0x04 << 21))
++	insn |= 0x02 << 21;
++      else if ((insn & (0x14 << 21)) == (0x10 << 21))
++	insn |= 0x08 << 21;
++    }
++  return insn | (value & 0xfffc);
++}
++
++static long
++extract_bdm (unsigned long insn,
++	     int dialect,
++	     int *invalid)
++{
++  if ((dialect & PPC_OPCODE_POWER4) == 0)
++    {
++      if (((insn & (1 << 21)) == 0) != ((insn & (1 << 15)) == 0))
++	*invalid = 1;
++    }
++  else
++    {
++      if ((insn & (0x17 << 21)) != (0x06 << 21)
++	  && (insn & (0x1d << 21)) != (0x18 << 21))
++	*invalid = 1;
++    }
++
++  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
++}
++
++/* The BD field in a B form instruction when the + modifier is used.
++   This is like BDM, above, except that the branch is expected to be
++   taken.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_bdp (unsigned long insn,
++	    long value,
++	    int dialect,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  if ((dialect & PPC_OPCODE_POWER4) == 0)
++    {
++      if ((value & 0x8000) == 0)
++	insn |= 1 << 21;
++    }
++  else
++    {
++      if ((insn & (0x14 << 21)) == (0x04 << 21))
++	insn |= 0x03 << 21;
++      else if ((insn & (0x14 << 21)) == (0x10 << 21))
++	insn |= 0x09 << 21;
++    }
++  return insn | (value & 0xfffc);
++}
++
++static long
++extract_bdp (unsigned long insn,
++	     int dialect,
++	     int *invalid)
++{
++  if ((dialect & PPC_OPCODE_POWER4) == 0)
++    {
++      if (((insn & (1 << 21)) == 0) == ((insn & (1 << 15)) == 0))
++	*invalid = 1;
++    }
++  else
++    {
++      if ((insn & (0x17 << 21)) != (0x07 << 21)
++	  && (insn & (0x1d << 21)) != (0x19 << 21))
++	*invalid = 1;
++    }
++
++  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
++}
++
++/* Check for legal values of a BO field.  */
++
++static int
++valid_bo (long value, int dialect)
++{
++  if ((dialect & PPC_OPCODE_POWER4) == 0)
++    {
++      /* Certain encodings have bits that are required to be zero.
++	 These are (z must be zero, y may be anything):
++	     001zy
++	     011zy
++	     1z00y
++	     1z01y
++	     1z1zz
++      */
++      switch (value & 0x14)
++	{
++	default:
++	case 0:
++	  return 1;
++	case 0x4:
++	  return (value & 0x2) == 0;
++	case 0x10:
++	  return (value & 0x8) == 0;
++	case 0x14:
++	  return value == 0x14;
++	}
++    }
++  else
++    {
++      /* Certain encodings have bits that are required to be zero.
++	 These are (z must be zero, a & t may be anything):
++	     0000z
++	     0001z
++	     0100z
++	     0101z
++	     001at
++	     011at
++	     1a00t
++	     1a01t
++	     1z1zz
++      */
++      if ((value & 0x14) == 0)
++	return (value & 0x1) == 0;
++      else if ((value & 0x14) == 0x14)
++	return value == 0x14;
++      else
++	return 1;
++    }
++}
++
++/* The BO field in a B form instruction.  Warn about attempts to set
++   the field to an illegal value.  */
++
++static unsigned long
++insert_bo (unsigned long insn,
++	   long value,
++	   int dialect,
++	   const char **errmsg)
++{
++  if (!valid_bo (value, dialect))
++    *errmsg = _("invalid conditional option");
++  return insn | ((value & 0x1f) << 21);
++}
++
++static long
++extract_bo (unsigned long insn,
++	    int dialect,
++	    int *invalid)
++{
++  long value;
++
++  value = (insn >> 21) & 0x1f;
++  if (!valid_bo (value, dialect))
++    *invalid = 1;
++  return value;
++}
++
++/* The BO field in a B form instruction when the + or - modifier is
++   used.  This is like the BO field, but it must be even.  When
++   extracting it, we force it to be even.  */
++
++static unsigned long
++insert_boe (unsigned long insn,
++	    long value,
++	    int dialect,
++	    const char **errmsg)
++{
++  if (!valid_bo (value, dialect))
++    *errmsg = _("invalid conditional option");
++  else if ((value & 1) != 0)
++    *errmsg = _("attempt to set y bit when using + or - modifier");
++
++  return insn | ((value & 0x1f) << 21);
++}
++
++static long
++extract_boe (unsigned long insn,
++	     int dialect,
++	     int *invalid)
++{
++  long value;
++
++  value = (insn >> 21) & 0x1f;
++  if (!valid_bo (value, dialect))
++    *invalid = 1;
++  return value & 0x1e;
++}
++
++/* The DQ field in a DQ form instruction.  This is like D, but the
++   lower four bits are forced to zero. */
++
++/*ARGSUSED*/
++static unsigned long
++insert_dq (unsigned long insn,
++	   long value,
++	   int dialect ATTRIBUTE_UNUSED,
++	   const char **errmsg)
++{
++  if ((value & 0xf) != 0)
++    *errmsg = _("offset not a multiple of 16");
++  return insn | (value & 0xfff0);
++}
++
++/*ARGSUSED*/
++static long
++extract_dq (unsigned long insn,
++	    int dialect ATTRIBUTE_UNUSED,
++	    int *invalid ATTRIBUTE_UNUSED)
++{
++  return ((insn & 0xfff0) ^ 0x8000) - 0x8000;
++}
++
++static unsigned long
++insert_ev2 (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  if ((value & 1) != 0)
++    *errmsg = _("offset not a multiple of 2");
++  if ((value > 62) != 0)
++    *errmsg = _("offset greater than 62");
++  return insn | ((value & 0x3e) << 10);
++}
++
++static long
++extract_ev2 (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid ATTRIBUTE_UNUSED)
++{
++  return (insn >> 10) & 0x3e;
++}
++
++static unsigned long
++insert_ev4 (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  if ((value & 3) != 0)
++    *errmsg = _("offset not a multiple of 4");
++  if ((value > 124) != 0)
++    *errmsg = _("offset greater than 124");
++  return insn | ((value & 0x7c) << 9);
++}
++
++static long
++extract_ev4 (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid ATTRIBUTE_UNUSED)
++{
++  return (insn >> 9) & 0x7c;
++}
++
++static unsigned long
++insert_ev8 (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  if ((value & 7) != 0)
++    *errmsg = _("offset not a multiple of 8");
++  if ((value > 248) != 0)
++    *errmsg = _("offset greater than 248");
++  return insn | ((value & 0xf8) << 8);
++}
++
++static long
++extract_ev8 (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid ATTRIBUTE_UNUSED)
++{
++  return (insn >> 8) & 0xf8;
++}
++
++/* The DS field in a DS form instruction.  This is like D, but the
++   lower two bits are forced to zero.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_ds (unsigned long insn,
++	   long value,
++	   int dialect ATTRIBUTE_UNUSED,
++	   const char **errmsg)
++{
++  if ((value & 3) != 0)
++    *errmsg = _("offset not a multiple of 4");
++  return insn | (value & 0xfffc);
++}
++
++/*ARGSUSED*/
++static long
++extract_ds (unsigned long insn,
++	    int dialect ATTRIBUTE_UNUSED,
++	    int *invalid ATTRIBUTE_UNUSED)
++{
++  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
++}
++
++/* The DE field in a DE form instruction.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_de (unsigned long insn,
++	   long value,
++	   int dialect ATTRIBUTE_UNUSED,
++	   const char **errmsg)
++{
++  if (value > 2047 || value < -2048)
++    *errmsg = _("offset not between -2048 and 2047");
++  return insn | ((value << 4) & 0xfff0);
++}
++
++/*ARGSUSED*/
++static long
++extract_de (unsigned long insn,
++	    int dialect ATTRIBUTE_UNUSED,
++	    int *invalid ATTRIBUTE_UNUSED)
++{
++  return (insn & 0xfff0) >> 4;
++}
++
++/* The DES field in a DES form instruction.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_des (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  if (value > 8191 || value < -8192)
++    *errmsg = _("offset not between -8192 and 8191");
++  else if ((value & 3) != 0)
++    *errmsg = _("offset not a multiple of 4");
++  return insn | ((value << 2) & 0xfff0);
++}
++
++/*ARGSUSED*/
++static long
++extract_des (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid ATTRIBUTE_UNUSED)
++{
++  return (((insn >> 2) & 0x3ffc) ^ 0x2000) - 0x2000;
++}
++
++/* FXM mask in mfcr and mtcrf instructions.  */
++
++static unsigned long
++insert_fxm (unsigned long insn,
++	    long value,
++	    int dialect,
++	    const char **errmsg)
++{
++  /* If the optional field on mfcr is missing that means we want to use
++     the old form of the instruction that moves the whole cr.  In that
++     case we'll have VALUE zero.  There doesn't seem to be a way to
++     distinguish this from the case where someone writes mfcr %r3,0.  */
++  if (value == 0)
++    ;
++
++  /* If only one bit of the FXM field is set, we can use the new form
++     of the instruction, which is faster.  Unlike the Power4 branch hint
++     encoding, this is not backward compatible.  */
++  else if ((dialect & PPC_OPCODE_POWER4) != 0 && (value & -value) == value)
++    insn |= 1 << 20;
++
++  /* Any other value on mfcr is an error.  */
++  else if ((insn & (0x3ff << 1)) == 19 << 1)
++    {
++      *errmsg = _("ignoring invalid mfcr mask");
++      value = 0;
++    }
++
++  return insn | ((value & 0xff) << 12);
++}
++
++static long
++extract_fxm (unsigned long insn,
++	     int dialect,
++	     int *invalid)
++{
++  long mask = (insn >> 12) & 0xff;
++
++  /* Is this a Power4 insn?  */
++  if ((insn & (1 << 20)) != 0)
++    {
++      if ((dialect & PPC_OPCODE_POWER4) == 0)
++	*invalid = 1;
++      else
++	{
++	  /* Exactly one bit of MASK should be set.  */
++	  if (mask == 0 || (mask & -mask) != mask)
++	    *invalid = 1;
++	}
++    }
++
++  /* Check that non-power4 form of mfcr has a zero MASK.  */
++  else if ((insn & (0x3ff << 1)) == 19 << 1)
++    {
++      if (mask != 0)
++	*invalid = 1;
++    }
++
++  return mask;
++}
++
++/* The LI field in an I form instruction.  The lower two bits are
++   forced to zero.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_li (unsigned long insn,
++	   long value,
++	   int dialect ATTRIBUTE_UNUSED,
++	   const char **errmsg)
++{
++  if ((value & 3) != 0)
++    *errmsg = _("ignoring least significant bits in branch offset");
++  return insn | (value & 0x3fffffc);
++}
++
++/*ARGSUSED*/
++static long
++extract_li (unsigned long insn,
++	    int dialect ATTRIBUTE_UNUSED,
++	    int *invalid ATTRIBUTE_UNUSED)
++{
++  return ((insn & 0x3fffffc) ^ 0x2000000) - 0x2000000;
++}
++
++/* The MB and ME fields in an M form instruction expressed as a single
++   operand which is itself a bitmask.  The extraction function always
++   marks it as invalid, since we never want to recognize an
++   instruction which uses a field of this type.  */
++
++static unsigned long
++insert_mbe (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  unsigned long uval, mask;
++  int mb, me, mx, count, last;
++
++  uval = value;
++
++  if (uval == 0)
++    {
++      *errmsg = _("illegal bitmask");
++      return insn;
++    }
++
++  mb = 0;
++  me = 32;
++  if ((uval & 1) != 0)
++    last = 1;
++  else
++    last = 0;
++  count = 0;
++
++  /* mb: location of last 0->1 transition */
++  /* me: location of last 1->0 transition */
++  /* count: # transitions */
++
++  for (mx = 0, mask = 1L << 31; mx < 32; ++mx, mask >>= 1)
++    {
++      if ((uval & mask) && !last)
++	{
++	  ++count;
++	  mb = mx;
++	  last = 1;
++	}
++      else if (!(uval & mask) && last)
++	{
++	  ++count;
++	  me = mx;
++	  last = 0;
++	}
++    }
++  if (me == 0)
++    me = 32;
++
++  if (count != 2 && (count != 0 || ! last))
++    *errmsg = _("illegal bitmask");
++
++  return insn | (mb << 6) | ((me - 1) << 1);
++}
++
++static long
++extract_mbe (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid)
++{
++  long ret;
++  int mb, me;
++  int i;
++
++  *invalid = 1;
++
++  mb = (insn >> 6) & 0x1f;
++  me = (insn >> 1) & 0x1f;
++  if (mb < me + 1)
++    {
++      ret = 0;
++      for (i = mb; i <= me; i++)
++	ret |= 1L << (31 - i);
++    }
++  else if (mb == me + 1)
++    ret = ~0;
++  else /* (mb > me + 1) */
++    {
++      ret = ~0;
++      for (i = me + 1; i < mb; i++)
++	ret &= ~(1L << (31 - i));
++    }
++  return ret;
++}
++
++/* The MB or ME field in an MD or MDS form instruction.  The high bit
++   is wrapped to the low end.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_mb6 (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  return insn | ((value & 0x1f) << 6) | (value & 0x20);
++}
++
++/*ARGSUSED*/
++static long
++extract_mb6 (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid ATTRIBUTE_UNUSED)
++{
++  return ((insn >> 6) & 0x1f) | (insn & 0x20);
++}
++
++/* The NB field in an X form instruction.  The value 32 is stored as
++   0.  */
++
++static unsigned long
++insert_nb (unsigned long insn,
++	   long value,
++	   int dialect ATTRIBUTE_UNUSED,
++	   const char **errmsg)
++{
++  if (value < 0 || value > 32)
++    *errmsg = _("value out of range");
++  if (value == 32)
++    value = 0;
++  return insn | ((value & 0x1f) << 11);
++}
++
++/*ARGSUSED*/
++static long
++extract_nb (unsigned long insn,
++	    int dialect ATTRIBUTE_UNUSED,
++	    int *invalid ATTRIBUTE_UNUSED)
++{
++  long ret;
++
++  ret = (insn >> 11) & 0x1f;
++  if (ret == 0)
++    ret = 32;
++  return ret;
++}
++
++/* The NSI field in a D form instruction.  This is the same as the SI
++   field, only negated.  The extraction function always marks it as
++   invalid, since we never want to recognize an instruction which uses
++   a field of this type.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_nsi (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  return insn | (-value & 0xffff);
++}
++
++static long
++extract_nsi (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid)
++{
++  *invalid = 1;
++  return -(((insn & 0xffff) ^ 0x8000) - 0x8000);
++}
++
++/* The RA field in a D or X form instruction which is an updating
++   load, which means that the RA field may not be zero and may not
++   equal the RT field.  */
++
++static unsigned long
++insert_ral (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  if (value == 0
++      || (unsigned long) value == ((insn >> 21) & 0x1f))
++    *errmsg = "invalid register operand when updating";
++  return insn | ((value & 0x1f) << 16);
++}
++
++/* The RA field in an lmw instruction, which has special value
++   restrictions.  */
++
++static unsigned long
++insert_ram (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  if ((unsigned long) value >= ((insn >> 21) & 0x1f))
++    *errmsg = _("index register in load range");
++  return insn | ((value & 0x1f) << 16);
++}
++
++/* The RA field in the DQ form lq instruction, which has special
++   value restrictions.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_raq (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  long rtvalue = (insn & RT_MASK) >> 21;
++
++  if (value == rtvalue)
++    *errmsg = _("source and target register operands must be different");
++  return insn | ((value & 0x1f) << 16);
++}
++
++/* The RA field in a D or X form instruction which is an updating
++   store or an updating floating point load, which means that the RA
++   field may not be zero.  */
++
++static unsigned long
++insert_ras (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  if (value == 0)
++    *errmsg = _("invalid register operand when updating");
++  return insn | ((value & 0x1f) << 16);
++}
++
++/* The RB field in an X form instruction when it must be the same as
++   the RS field in the instruction.  This is used for extended
++   mnemonics like mr.  This operand is marked FAKE.  The insertion
++   function just copies the BT field into the BA field, and the
++   extraction function just checks that the fields are the same.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_rbs (unsigned long insn,
++	    long value ATTRIBUTE_UNUSED,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  return insn | (((insn >> 21) & 0x1f) << 11);
++}
++
++static long
++extract_rbs (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid)
++{
++  if (((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f))
++    *invalid = 1;
++  return 0;
++}
++
++/* The RT field of the DQ form lq instruction, which has special
++   value restrictions.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_rtq (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  if ((value & 1) != 0)
++    *errmsg = _("target register operand must be even");
++  return insn | ((value & 0x1f) << 21);
++}
++
++/* The RS field of the DS form stq instruction, which has special
++   value restrictions.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_rsq (unsigned long insn,
++	    long value ATTRIBUTE_UNUSED,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg)
++{
++  if ((value & 1) != 0)
++    *errmsg = _("source register operand must be even");
++  return insn | ((value & 0x1f) << 21);
++}
++
++/* The SH field in an MD form instruction.  This is split.  */
++
++/*ARGSUSED*/
++static unsigned long
++insert_sh6 (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
++}
++
++/*ARGSUSED*/
++static long
++extract_sh6 (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid ATTRIBUTE_UNUSED)
++{
++  return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);
++}
++
++/* The SPR field in an XFX form instruction.  This is flipped--the
++   lower 5 bits are stored in the upper 5 and vice- versa.  */
++
++static unsigned long
++insert_spr (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
++}
++
++static long
++extract_spr (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid ATTRIBUTE_UNUSED)
++{
++  return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
++}
++
++/* The TBR field in an XFX instruction.  This is just like SPR, but it
++   is optional.  When TBR is omitted, it must be inserted as 268 (the
++   magic number of the TB register).  These functions treat 0
++   (indicating an omitted optional operand) as 268.  This means that
++   ``mftb 4,0'' is not handled correctly.  This does not matter very
++   much, since the architecture manual does not define mftb as
++   accepting any values other than 268 or 269.  */
++
++#define TB (268)
++
++static unsigned long
++insert_tbr (unsigned long insn,
++	    long value,
++	    int dialect ATTRIBUTE_UNUSED,
++	    const char **errmsg ATTRIBUTE_UNUSED)
++{
++  if (value == 0)
++    value = TB;
++  return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
++}
++
++static long
++extract_tbr (unsigned long insn,
++	     int dialect ATTRIBUTE_UNUSED,
++	     int *invalid ATTRIBUTE_UNUSED)
++{
++  long ret;
++
++  ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
++  if (ret == TB)
++    ret = 0;
++  return ret;
++}
++
++/* Macros used to form opcodes.  */
++
++/* The main opcode.  */
++#define OP(x) ((((unsigned long)(x)) & 0x3f) << 26)
++#define OP_MASK OP (0x3f)
++
++/* The main opcode combined with a trap code in the TO field of a D
++   form instruction.  Used for extended mnemonics for the trap
++   instructions.  */
++#define OPTO(x,to) (OP (x) | ((((unsigned long)(to)) & 0x1f) << 21))
++#define OPTO_MASK (OP_MASK | TO_MASK)
++
++/* The main opcode combined with a comparison size bit in the L field
++   of a D form or X form instruction.  Used for extended mnemonics for
++   the comparison instructions.  */
++#define OPL(x,l) (OP (x) | ((((unsigned long)(l)) & 1) << 21))
++#define OPL_MASK OPL (0x3f,1)
++
++/* An A form instruction.  */
++#define A(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1) | (((unsigned long)(rc)) & 1))
++#define A_MASK A (0x3f, 0x1f, 1)
++
++/* An A_MASK with the FRB field fixed.  */
++#define AFRB_MASK (A_MASK | FRB_MASK)
++
++/* An A_MASK with the FRC field fixed.  */
++#define AFRC_MASK (A_MASK | FRC_MASK)
++
++/* An A_MASK with the FRA and FRC fields fixed.  */
++#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)
++
++/* A B form instruction.  */
++#define B(op, aa, lk) (OP (op) | ((((unsigned long)(aa)) & 1) << 1) | ((lk) & 1))
++#define B_MASK B (0x3f, 1, 1)
++
++/* A B form instruction setting the BO field.  */
++#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21))
++#define BBO_MASK BBO (0x3f, 0x1f, 1, 1)
++
++/* A BBO_MASK with the y bit of the BO field removed.  This permits
++   matching a conditional branch regardless of the setting of the y
++   bit.  Similarly for the 'at' bits used for power4 branch hints.  */
++#define Y_MASK   (((unsigned long) 1) << 21)
++#define AT1_MASK (((unsigned long) 3) << 21)
++#define AT2_MASK (((unsigned long) 9) << 21)
++#define BBOY_MASK  (BBO_MASK &~ Y_MASK)
++#define BBOAT_MASK (BBO_MASK &~ AT1_MASK)
++
++/* A B form instruction setting the BO field and the condition bits of
++   the BI field.  */
++#define BBOCB(op, bo, cb, aa, lk) \
++  (BBO ((op), (bo), (aa), (lk)) | ((((unsigned long)(cb)) & 0x3) << 16))
++#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1)
++
++/* A BBOCB_MASK with the y bit of the BO field removed.  */
++#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK)
++#define BBOATCB_MASK (BBOCB_MASK &~ AT1_MASK)
++#define BBOAT2CB_MASK (BBOCB_MASK &~ AT2_MASK)
++
++/* A BBOYCB_MASK in which the BI field is fixed.  */
++#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK)
++#define BBOATBI_MASK (BBOAT2CB_MASK | BI_MASK)
++
++/* An Context form instruction.  */
++#define CTX(op, xop)   (OP (op) | (((unsigned long)(xop)) & 0x7))
++#define CTX_MASK       CTX(0x3f, 0x7)
++
++/* An User Context form instruction.  */
++#define UCTX(op, xop)  (OP (op) | (((unsigned long)(xop)) & 0x1f))
++#define UCTX_MASK      UCTX(0x3f, 0x1f)
++
++/* The main opcode mask with the RA field clear.  */
++#define DRA_MASK (OP_MASK | RA_MASK)
++
++/* A DS form instruction.  */
++#define DSO(op, xop) (OP (op) | ((xop) & 0x3))
++#define DS_MASK DSO (0x3f, 3)
++
++/* A DE form instruction.  */
++#define DEO(op, xop) (OP (op) | ((xop) & 0xf))
++#define DE_MASK DEO (0x3e, 0xf)
++
++/* An EVSEL form instruction.  */
++#define EVSEL(op, xop) (OP (op) | (((unsigned long)(xop)) & 0xff) << 3)
++#define EVSEL_MASK EVSEL(0x3f, 0xff)
++
++/* An M form instruction.  */
++#define M(op, rc) (OP (op) | ((rc) & 1))
++#define M_MASK M (0x3f, 1)
++
++/* An M form instruction with the ME field specified.  */
++#define MME(op, me, rc) (M ((op), (rc)) | ((((unsigned long)(me)) & 0x1f) << 1))
++
++/* An M_MASK with the MB and ME fields fixed.  */
++#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK)
++
++/* An M_MASK with the SH and ME fields fixed.  */
++#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK)
++
++/* An MD form instruction.  */
++#define MD(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x7) << 2) | ((rc) & 1))
++#define MD_MASK MD (0x3f, 0x7, 1)
++
++/* An MD_MASK with the MB field fixed.  */
++#define MDMB_MASK (MD_MASK | MB6_MASK)
++
++/* An MD_MASK with the SH field fixed.  */
++#define MDSH_MASK (MD_MASK | SH6_MASK)
++
++/* An MDS form instruction.  */
++#define MDS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0xf) << 1) | ((rc) & 1))
++#define MDS_MASK MDS (0x3f, 0xf, 1)
++
++/* An MDS_MASK with the MB field fixed.  */
++#define MDSMB_MASK (MDS_MASK | MB6_MASK)
++
++/* An SC form instruction.  */
++#define SC(op, sa, lk) (OP (op) | ((((unsigned long)(sa)) & 1) << 1) | ((lk) & 1))
++#define SC_MASK (OP_MASK | (((unsigned long)0x3ff) << 16) | (((unsigned long)1) << 1) | 1)
++
++/* An VX form instruction.  */
++#define VX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7ff))
++
++/* The mask for an VX form instruction.  */
++#define VX_MASK	VX(0x3f, 0x7ff)
++
++/* An VA form instruction.  */
++#define VXA(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x03f))
++
++/* The mask for an VA form instruction.  */
++#define VXA_MASK VXA(0x3f, 0x3f)
++
++/* An VXR form instruction.  */
++#define VXR(op, xop, rc) (OP (op) | (((rc) & 1) << 10) | (((unsigned long)(xop)) & 0x3ff))
++
++/* The mask for a VXR form instruction.  */
++#define VXR_MASK VXR(0x3f, 0x3ff, 1)
++
++/* An X form instruction.  */
++#define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1))
++
++/* An X form instruction with the RC bit specified.  */
++#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
++
++/* The mask for an X form instruction.  */
++#define X_MASK XRC (0x3f, 0x3ff, 1)
++
++/* An X_MASK with the RA field fixed.  */
++#define XRA_MASK (X_MASK | RA_MASK)
++
++/* An X_MASK with the RB field fixed.  */
++#define XRB_MASK (X_MASK | RB_MASK)
++
++/* An X_MASK with the RT field fixed.  */
++#define XRT_MASK (X_MASK | RT_MASK)
++
++/* An X_MASK with the RA and RB fields fixed.  */
++#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
++
++/* An XRARB_MASK, but with the L bit clear.  */
++#define XRLARB_MASK (XRARB_MASK & ~((unsigned long) 1 << 16))
++
++/* An X_MASK with the RT and RA fields fixed.  */
++#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK)
++
++/* An XRTRA_MASK, but with L bit clear.  */
++#define XRTLRA_MASK (XRTRA_MASK & ~((unsigned long) 1 << 21))
++
++/* An X form comparison instruction.  */
++#define XCMPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21))
++
++/* The mask for an X form comparison instruction.  */
++#define XCMP_MASK (X_MASK | (((unsigned long)1) << 22))
++
++/* The mask for an X form comparison instruction with the L field
++   fixed.  */
++#define XCMPL_MASK (XCMP_MASK | (((unsigned long)1) << 21))
++
++/* An X form trap instruction with the TO field specified.  */
++#define XTO(op, xop, to) (X ((op), (xop)) | ((((unsigned long)(to)) & 0x1f) << 21))
++#define XTO_MASK (X_MASK | TO_MASK)
++
++/* An X form tlb instruction with the SH field specified.  */
++#define XTLB(op, xop, sh) (X ((op), (xop)) | ((((unsigned long)(sh)) & 0x1f) << 11))
++#define XTLB_MASK (X_MASK | SH_MASK)
++
++/* An X form sync instruction.  */
++#define XSYNC(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 3) << 21))
++
++/* An X form sync instruction with everything filled in except the LS field.  */
++#define XSYNC_MASK (0xff9fffff)
++
++/* An X form AltiVec dss instruction.  */
++#define XDSS(op, xop, a) (X ((op), (xop)) | ((((unsigned long)(a)) & 1) << 25))
++#define XDSS_MASK XDSS(0x3f, 0x3ff, 1)
++
++/* An XFL form instruction.  */
++#define XFL(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1) | (((unsigned long)(rc)) & 1))
++#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (((unsigned long)1) << 25) | (((unsigned long)1) << 16))
++
++/* An X form isel instruction.  */
++#define XISEL(op, xop)  (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1))
++#define XISEL_MASK      XISEL(0x3f, 0x1f)
++
++/* An XL form instruction with the LK field set to 0.  */
++#define XL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1))
++
++/* An XL form instruction which uses the LK field.  */
++#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1))
++
++/* The mask for an XL form instruction.  */
++#define XL_MASK XLLK (0x3f, 0x3ff, 1)
++
++/* An XL form instruction which explicitly sets the BO field.  */
++#define XLO(op, bo, xop, lk) \
++  (XLLK ((op), (xop), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21))
++#define XLO_MASK (XL_MASK | BO_MASK)
++
++/* An XL form instruction which explicitly sets the y bit of the BO
++   field.  */
++#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | ((((unsigned long)(y)) & 1) << 21))
++#define XLYLK_MASK (XL_MASK | Y_MASK)
++
++/* An XL form instruction which sets the BO field and the condition
++   bits of the BI field.  */
++#define XLOCB(op, bo, cb, xop, lk) \
++  (XLO ((op), (bo), (xop), (lk)) | ((((unsigned long)(cb)) & 3) << 16))
++#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1)
++
++/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed.  */
++#define XLBB_MASK (XL_MASK | BB_MASK)
++#define XLYBB_MASK (XLYLK_MASK | BB_MASK)
++#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK)
++
++/* An XL_MASK with the BO and BB fields fixed.  */
++#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK)
++
++/* An XL_MASK with the BO, BI and BB fields fixed.  */
++#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK)
++
++/* An XO form instruction.  */
++#define XO(op, xop, oe, rc) \
++  (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1) | ((((unsigned long)(oe)) & 1) << 10) | (((unsigned long)(rc)) & 1))
++#define XO_MASK XO (0x3f, 0x1ff, 1, 1)
++
++/* An XO_MASK with the RB field fixed.  */
++#define XORB_MASK (XO_MASK | RB_MASK)
++
++/* An XS form instruction.  */
++#define XS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 2) | (((unsigned long)(rc)) & 1))
++#define XS_MASK XS (0x3f, 0x1ff, 1)
++
++/* A mask for the FXM version of an XFX form instruction.  */
++#define XFXFXM_MASK (X_MASK | (1 << 11))
++
++/* An XFX form instruction with the FXM field filled in.  */
++#define XFXM(op, xop, fxm) \
++  (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12))
++
++/* An XFX form instruction with the SPR field filled in.  */
++#define XSPR(op, xop, spr) \
++  (X ((op), (xop)) | ((((unsigned long)(spr)) & 0x1f) << 16) | ((((unsigned long)(spr)) & 0x3e0) << 6))
++#define XSPR_MASK (X_MASK | SPR_MASK)
++
++/* An XFX form instruction with the SPR field filled in except for the
++   SPRBAT field.  */
++#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK)
++
++/* An XFX form instruction with the SPR field filled in except for the
++   SPRG field.  */
++#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK)
++
++/* An X form instruction with everything filled in except the E field.  */
++#define XE_MASK (0xffff7fff)
++
++/* An X form user context instruction.  */
++#define XUC(op, xop)  (OP (op) | (((unsigned long)(xop)) & 0x1f))
++#define XUC_MASK      XUC(0x3f, 0x1f)
++
++/* The BO encodings used in extended conditional branch mnemonics.  */
++#define BODNZF	(0x0)
++#define BODNZFP	(0x1)
++#define BODZF	(0x2)
++#define BODZFP	(0x3)
++#define BODNZT	(0x8)
++#define BODNZTP	(0x9)
++#define BODZT	(0xa)
++#define BODZTP	(0xb)
++
++#define BOF	(0x4)
++#define BOFP	(0x5)
++#define BOFM4	(0x6)
++#define BOFP4	(0x7)
++#define BOT	(0xc)
++#define BOTP	(0xd)
++#define BOTM4	(0xe)
++#define BOTP4	(0xf)
++
++#define BODNZ	(0x10)
++#define BODNZP	(0x11)
++#define BODZ	(0x12)
++#define BODZP	(0x13)
++#define BODNZM4 (0x18)
++#define BODNZP4 (0x19)
++#define BODZM4	(0x1a)
++#define BODZP4	(0x1b)
++
++#define BOU	(0x14)
++
++/* The BI condition bit encodings used in extended conditional branch
++   mnemonics.  */
++#define CBLT	(0)
++#define CBGT	(1)
++#define CBEQ	(2)
++#define CBSO	(3)
++
++/* The TO encodings used in extended trap mnemonics.  */
++#define TOLGT	(0x1)
++#define TOLLT	(0x2)
++#define TOEQ	(0x4)
++#define TOLGE	(0x5)
++#define TOLNL	(0x5)
++#define TOLLE	(0x6)
++#define TOLNG	(0x6)
++#define TOGT	(0x8)
++#define TOGE	(0xc)
++#define TONL	(0xc)
++#define TOLT	(0x10)
++#define TOLE	(0x14)
++#define TONG	(0x14)
++#define TONE	(0x18)
++#define TOU	(0x1f)
++
++/* Smaller names for the flags so each entry in the opcodes table will
++   fit on a single line.  */
++#undef	PPC
++#define PPC     PPC_OPCODE_PPC
++#define PPCCOM	PPC_OPCODE_PPC | PPC_OPCODE_COMMON
++#define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM
++#define POWER4	PPC_OPCODE_POWER4
++#define PPC32   PPC_OPCODE_32 | PPC_OPCODE_PPC
++#define PPC64   PPC_OPCODE_64 | PPC_OPCODE_PPC
++#define PPC403	PPC_OPCODE_403
++#define PPC405	PPC403
++#define PPC440	PPC_OPCODE_440
++#define PPC750	PPC
++#define PPC860	PPC
++#define PPCVEC	PPC_OPCODE_ALTIVEC | PPC_OPCODE_PPC
++#define	POWER   PPC_OPCODE_POWER
++#define	POWER2	PPC_OPCODE_POWER | PPC_OPCODE_POWER2
++#define PPCPWR2	PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2
++#define	POWER32	PPC_OPCODE_POWER | PPC_OPCODE_32
++#define	COM     PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON
++#define	COM32   PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_32
++#define	M601    PPC_OPCODE_POWER | PPC_OPCODE_601
++#define PWRCOM	PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON
++#define	MFDEC1	PPC_OPCODE_POWER
++#define	MFDEC2	PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_BOOKE
++#define BOOKE	PPC_OPCODE_BOOKE
++#define BOOKE64	PPC_OPCODE_BOOKE64
++#define CLASSIC	PPC_OPCODE_CLASSIC
++#define PPCSPE	PPC_OPCODE_SPE
++#define PPCISEL	PPC_OPCODE_ISEL
++#define PPCEFS	PPC_OPCODE_EFS
++#define PPCBRLK	PPC_OPCODE_BRLOCK
++#define PPCPMR	PPC_OPCODE_PMR
++#define PPCCHLK	PPC_OPCODE_CACHELCK
++#define PPCCHLK64	PPC_OPCODE_CACHELCK | PPC_OPCODE_BOOKE64
++#define PPCRFMCI	PPC_OPCODE_RFMCI
++
++/* The opcode table.
++
++   The format of the opcode table is:
++
++   NAME	     OPCODE	MASK		FLAGS		{ OPERANDS }
++
++   NAME is the name of the instruction.
++   OPCODE is the instruction opcode.
++   MASK is the opcode mask; this is used to tell the disassembler
++     which bits in the actual opcode must match OPCODE.
++   FLAGS are flags indicated what processors support the instruction.
++   OPERANDS is the list of operands.
++
++   The disassembler reads the table in order and prints the first
++   instruction which matches, so this table is sorted to put more
++   specific instructions before more general instructions.  It is also
++   sorted by major opcode.  */
++
++const struct powerpc_opcode powerpc_opcodes[] = {
++{ "attn",    X(0,256), X_MASK,		POWER4,		{ 0 } },
++{ "tdlgti",  OPTO(2,TOLGT), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdllti",  OPTO(2,TOLLT), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdeqi",   OPTO(2,TOEQ), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdlgei",  OPTO(2,TOLGE), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdlnli",  OPTO(2,TOLNL), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdllei",  OPTO(2,TOLLE), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdlngi",  OPTO(2,TOLNG), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdgti",   OPTO(2,TOGT), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdgei",   OPTO(2,TOGE), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdnli",   OPTO(2,TONL), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdlti",   OPTO(2,TOLT), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdlei",   OPTO(2,TOLE), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdngi",   OPTO(2,TONG), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdnei",   OPTO(2,TONE), OPTO_MASK,	PPC64,		{ RA, SI } },
++{ "tdi",     OP(2),	OP_MASK,	PPC64,		{ TO, RA, SI } },
++
++{ "twlgti",  OPTO(3,TOLGT), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tlgti",   OPTO(3,TOLGT), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twllti",  OPTO(3,TOLLT), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tllti",   OPTO(3,TOLLT), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "tweqi",   OPTO(3,TOEQ), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "teqi",    OPTO(3,TOEQ), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twlgei",  OPTO(3,TOLGE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tlgei",   OPTO(3,TOLGE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twlnli",  OPTO(3,TOLNL), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tlnli",   OPTO(3,TOLNL), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twllei",  OPTO(3,TOLLE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tllei",   OPTO(3,TOLLE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twlngi",  OPTO(3,TOLNG), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tlngi",   OPTO(3,TOLNG), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twgti",   OPTO(3,TOGT), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tgti",    OPTO(3,TOGT), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twgei",   OPTO(3,TOGE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tgei",    OPTO(3,TOGE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twnli",   OPTO(3,TONL), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tnli",    OPTO(3,TONL), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twlti",   OPTO(3,TOLT), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tlti",    OPTO(3,TOLT), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twlei",   OPTO(3,TOLE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tlei",    OPTO(3,TOLE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twngi",   OPTO(3,TONG), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tngi",    OPTO(3,TONG), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twnei",   OPTO(3,TONE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
++{ "tnei",    OPTO(3,TONE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
++{ "twi",     OP(3),	OP_MASK,	PPCCOM,		{ TO, RA, SI } },
++{ "ti",      OP(3),	OP_MASK,	PWRCOM,		{ TO, RA, SI } },
++
++{ "macchw",	XO(4,172,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchw.",	XO(4,172,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwo",	XO(4,172,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwo.",	XO(4,172,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchws",	XO(4,236,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchws.",	XO(4,236,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwso",	XO(4,236,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwso.",	XO(4,236,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwsu",	XO(4,204,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwsu.",	XO(4,204,0,1), XO_MASK, PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwsuo",	XO(4,204,1,0), XO_MASK, PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwsuo.",	XO(4,204,1,1), XO_MASK, PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwu",	XO(4,140,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwu.",	XO(4,140,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwuo",	XO(4,140,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "macchwuo.",	XO(4,140,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhw",	XO(4,44,0,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhw.",	XO(4,44,0,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwo",	XO(4,44,1,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwo.",	XO(4,44,1,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhws",	XO(4,108,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhws.",	XO(4,108,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwso",	XO(4,108,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwso.",	XO(4,108,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwsu",	XO(4,76,0,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwsu.",	XO(4,76,0,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwsuo",	XO(4,76,1,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwsuo.",	XO(4,76,1,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwu",	XO(4,12,0,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwu.",	XO(4,12,0,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwuo",	XO(4,12,1,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "machhwuo.",	XO(4,12,1,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhw",	XO(4,428,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhw.",	XO(4,428,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwo",	XO(4,428,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwo.",	XO(4,428,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhws",	XO(4,492,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhws.",	XO(4,492,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwso",	XO(4,492,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwso.",	XO(4,492,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwsu",	XO(4,460,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwsu.",	XO(4,460,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwsuo",	XO(4,460,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwsuo.",	XO(4,460,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwu",	XO(4,396,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwu.",	XO(4,396,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwuo",	XO(4,396,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "maclhwuo.",	XO(4,396,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mulchw",	XRC(4,168,0),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mulchw.",	XRC(4,168,1),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mulchwu",	XRC(4,136,0),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mulchwu.",	XRC(4,136,1),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mulhhw",	XRC(4,40,0),   X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mulhhw.",	XRC(4,40,1),   X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mulhhwu",	XRC(4,8,0),    X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mulhhwu.",	XRC(4,8,1),    X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mullhw",	XRC(4,424,0),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mullhw.",	XRC(4,424,1),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mullhwu",	XRC(4,392,0),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mullhwu.",	XRC(4,392,1),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmacchw",	XO(4,174,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmacchw.",	XO(4,174,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmacchwo",	XO(4,174,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmacchwo.",	XO(4,174,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmacchws",	XO(4,238,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmacchws.",	XO(4,238,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmacchwso",	XO(4,238,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmacchwso.",	XO(4,238,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmachhw",	XO(4,46,0,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmachhw.",	XO(4,46,0,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmachhwo",	XO(4,46,1,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmachhwo.",	XO(4,46,1,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmachhws",	XO(4,110,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmachhws.",	XO(4,110,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmachhwso",	XO(4,110,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmachhwso.",	XO(4,110,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmaclhw",	XO(4,430,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmaclhw.",	XO(4,430,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmaclhwo",	XO(4,430,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmaclhwo.",	XO(4,430,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmaclhws",	XO(4,494,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmaclhws.",	XO(4,494,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmaclhwso",	XO(4,494,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "nmaclhwso.",	XO(4,494,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
++{ "mfvscr",  VX(4, 1540), VX_MASK,	PPCVEC,		{ VD } },
++{ "mtvscr",  VX(4, 1604), VX_MASK,	PPCVEC,		{ VB } },
++{ "vaddcuw", VX(4,  384), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vaddfp",  VX(4,   10), VX_MASK, 	PPCVEC,		{ VD, VA, VB } },
++{ "vaddsbs", VX(4,  768), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vaddshs", VX(4,  832), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vaddsws", VX(4,  896), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vaddubm", VX(4,    0), VX_MASK, 	PPCVEC,		{ VD, VA, VB } },
++{ "vaddubs", VX(4,  512), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vadduhm", VX(4,   64), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vadduhs", VX(4,  576), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vadduwm", VX(4,  128), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vadduws", VX(4,  640), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vand",    VX(4, 1028), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vandc",   VX(4, 1092), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vavgsb",  VX(4, 1282), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vavgsh",  VX(4, 1346), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vavgsw",  VX(4, 1410), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vavgub",  VX(4, 1026), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vavguh",  VX(4, 1090), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vavguw",  VX(4, 1154), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vcfsx",   VX(4,  842), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
++{ "vcfux",   VX(4,  778), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
++{ "vcmpbfp",   VXR(4, 966, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpbfp.",  VXR(4, 966, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpeqfp",  VXR(4, 198, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpeqfp.", VXR(4, 198, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpequb",  VXR(4,   6, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpequb.", VXR(4,   6, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpequh",  VXR(4,  70, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpequh.", VXR(4,  70, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpequw",  VXR(4, 134, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpequw.", VXR(4, 134, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgefp",  VXR(4, 454, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgefp.", VXR(4, 454, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtfp",  VXR(4, 710, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtfp.", VXR(4, 710, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtsb",  VXR(4, 774, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtsb.", VXR(4, 774, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtsh",  VXR(4, 838, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtsh.", VXR(4, 838, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtsw",  VXR(4, 902, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtsw.", VXR(4, 902, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtub",  VXR(4, 518, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtub.", VXR(4, 518, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtuh",  VXR(4, 582, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtuh.", VXR(4, 582, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtuw",  VXR(4, 646, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vcmpgtuw.", VXR(4, 646, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
++{ "vctsxs",    VX(4,  970), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
++{ "vctuxs",    VX(4,  906), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
++{ "vexptefp",  VX(4,  394), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vlogefp",   VX(4,  458), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vmaddfp",   VXA(4,  46), VXA_MASK,	PPCVEC,		{ VD, VA, VC, VB } },
++{ "vmaxfp",    VX(4, 1034), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmaxsb",    VX(4,  258), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmaxsh",    VX(4,  322), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmaxsw",    VX(4,  386), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmaxub",    VX(4,    2), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmaxuh",    VX(4,   66), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmaxuw",    VX(4,  130), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmhaddshs", VXA(4,  32), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
++{ "vmhraddshs", VXA(4, 33), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
++{ "vminfp",    VX(4, 1098), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vminsb",    VX(4,  770), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vminsh",    VX(4,  834), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vminsw",    VX(4,  898), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vminub",    VX(4,  514), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vminuh",    VX(4,  578), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vminuw",    VX(4,  642), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmladduhm", VXA(4,  34), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
++{ "vmrghb",    VX(4,   12), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmrghh",    VX(4,   76), VX_MASK,    PPCVEC,		{ VD, VA, VB } },
++{ "vmrghw",    VX(4,  140), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmrglb",    VX(4,  268), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmrglh",    VX(4,  332), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmrglw",    VX(4,  396), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmsummbm",  VXA(4,  37), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
++{ "vmsumshm",  VXA(4,  40), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
++{ "vmsumshs",  VXA(4,  41), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
++{ "vmsumubm",  VXA(4,  36), VXA_MASK,   PPCVEC,		{ VD, VA, VB, VC } },
++{ "vmsumuhm",  VXA(4,  38), VXA_MASK,   PPCVEC,		{ VD, VA, VB, VC } },
++{ "vmsumuhs",  VXA(4,  39), VXA_MASK,   PPCVEC,		{ VD, VA, VB, VC } },
++{ "vmulesb",   VX(4,  776), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmulesh",   VX(4,  840), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmuleub",   VX(4,  520), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmuleuh",   VX(4,  584), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmulosb",   VX(4,  264), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmulosh",   VX(4,  328), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmuloub",   VX(4,    8), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vmulouh",   VX(4,   72), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vnmsubfp",  VXA(4,  47), VXA_MASK,	PPCVEC,		{ VD, VA, VC, VB } },
++{ "vnor",      VX(4, 1284), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vor",       VX(4, 1156), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vperm",     VXA(4,  43), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
++{ "vpkpx",     VX(4,  782), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vpkshss",   VX(4,  398), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vpkshus",   VX(4,  270), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vpkswss",   VX(4,  462), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vpkswus",   VX(4,  334), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vpkuhum",   VX(4,   14), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vpkuhus",   VX(4,  142), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vpkuwum",   VX(4,   78), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vpkuwus",   VX(4,  206), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vrefp",     VX(4,  266), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vrfim",     VX(4,  714), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vrfin",     VX(4,  522), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vrfip",     VX(4,  650), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vrfiz",     VX(4,  586), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vrlb",      VX(4,    4), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vrlh",      VX(4,   68), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vrlw",      VX(4,  132), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vrsqrtefp", VX(4,  330), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vsel",      VXA(4,  42), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
++{ "vsl",       VX(4,  452), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vslb",      VX(4,  260), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsldoi",    VXA(4,  44), VXA_MASK,	PPCVEC,		{ VD, VA, VB, SHB } },
++{ "vslh",      VX(4,  324), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vslo",      VX(4, 1036), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vslw",      VX(4,  388), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vspltb",    VX(4,  524), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
++{ "vsplth",    VX(4,  588), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
++{ "vspltisb",  VX(4,  780), VX_MASK,	PPCVEC,		{ VD, SIMM } },
++{ "vspltish",  VX(4,  844), VX_MASK,	PPCVEC,		{ VD, SIMM } },
++{ "vspltisw",  VX(4,  908), VX_MASK,	PPCVEC,		{ VD, SIMM } },
++{ "vspltw",    VX(4,  652), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
++{ "vsr",       VX(4,  708), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsrab",     VX(4,  772), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsrah",     VX(4,  836), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsraw",     VX(4,  900), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsrb",      VX(4,  516), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsrh",      VX(4,  580), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsro",      VX(4, 1100), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsrw",      VX(4,  644), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsubcuw",   VX(4, 1408), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsubfp",    VX(4,   74), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsubsbs",   VX(4, 1792), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsubshs",   VX(4, 1856), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsubsws",   VX(4, 1920), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsububm",   VX(4, 1024), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsububs",   VX(4, 1536), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsubuhm",   VX(4, 1088), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsubuhs",   VX(4, 1600), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsubuwm",   VX(4, 1152), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsubuws",   VX(4, 1664), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsumsws",   VX(4, 1928), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsum2sws",  VX(4, 1672), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsum4sbs",  VX(4, 1800), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsum4shs",  VX(4, 1608), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vsum4ubs",  VX(4, 1544), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++{ "vupkhpx",   VX(4,  846), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vupkhsb",   VX(4,  526), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vupkhsh",   VX(4,  590), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vupklpx",   VX(4,  974), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vupklsb",   VX(4,  654), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vupklsh",   VX(4,  718), VX_MASK,	PPCVEC,		{ VD, VB } },
++{ "vxor",      VX(4, 1220), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
++
++{ "evaddw",    VX(4, 512), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evaddiw",   VX(4, 514), VX_MASK,	PPCSPE,		{ RS, RB, UIMM } },
++{ "evsubfw",   VX(4, 516), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evsubw",    VX(4, 516), VX_MASK,	PPCSPE,		{ RS, RB, RA } },
++{ "evsubifw",  VX(4, 518), VX_MASK,	PPCSPE,		{ RS, UIMM, RB } },
++{ "evsubiw",   VX(4, 518), VX_MASK,	PPCSPE,		{ RS, RB, UIMM } },
++{ "evabs",     VX(4, 520), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evneg",     VX(4, 521), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evextsb",   VX(4, 522), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evextsh",   VX(4, 523), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evrndw",    VX(4, 524), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evcntlzw",  VX(4, 525), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evcntlsw",  VX(4, 526), VX_MASK,	PPCSPE,		{ RS, RA } },
++
++{ "brinc",     VX(4, 527), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evand",     VX(4, 529), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evandc",    VX(4, 530), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmr",      VX(4, 535), VX_MASK,	PPCSPE,		{ RS, RA, BBA } },
++{ "evor",      VX(4, 535), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evorc",     VX(4, 539), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evxor",     VX(4, 534), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "eveqv",     VX(4, 537), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evnand",    VX(4, 542), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evnot",     VX(4, 536), VX_MASK,	PPCSPE,		{ RS, RA, BBA } },
++{ "evnor",     VX(4, 536), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evrlw",     VX(4, 552), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evrlwi",    VX(4, 554), VX_MASK,	PPCSPE,		{ RS, RA, EVUIMM } },
++{ "evslw",     VX(4, 548), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evslwi",    VX(4, 550), VX_MASK,	PPCSPE,		{ RS, RA, EVUIMM } },
++{ "evsrws",    VX(4, 545), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evsrwu",    VX(4, 544), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evsrwis",   VX(4, 547), VX_MASK,	PPCSPE,		{ RS, RA, EVUIMM } },
++{ "evsrwiu",   VX(4, 546), VX_MASK,	PPCSPE,		{ RS, RA, EVUIMM } },
++{ "evsplati",  VX(4, 553), VX_MASK,	PPCSPE,		{ RS, SIMM } },
++{ "evsplatfi", VX(4, 555), VX_MASK,	PPCSPE,		{ RS, SIMM } },
++{ "evmergehi", VX(4, 556), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmergelo", VX(4, 557), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmergehilo",VX(4,558), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmergelohi",VX(4,559), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evcmpgts",  VX(4, 561), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evcmpgtu",  VX(4, 560), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evcmplts",  VX(4, 563), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evcmpltu",  VX(4, 562), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evcmpeq",   VX(4, 564), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evsel",     EVSEL(4,79),EVSEL_MASK,	PPCSPE,		{ RS, RA, RB, CRFS } },
++
++{ "evldd",     VX(4, 769), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
++{ "evlddx",    VX(4, 768), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evldw",     VX(4, 771), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
++{ "evldwx",    VX(4, 770), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evldh",     VX(4, 773), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
++{ "evldhx",    VX(4, 772), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evlwhe",    VX(4, 785), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
++{ "evlwhex",   VX(4, 784), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evlwhou",   VX(4, 789), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
++{ "evlwhoux",  VX(4, 788), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evlwhos",   VX(4, 791), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
++{ "evlwhosx",  VX(4, 790), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evlwwsplat",VX(4, 793), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
++{ "evlwwsplatx",VX(4, 792), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evlwhsplat",VX(4, 797), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
++{ "evlwhsplatx",VX(4, 796), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evlhhesplat",VX(4, 777), VX_MASK,	PPCSPE,		{ RS, EVUIMM_2, RA } },
++{ "evlhhesplatx",VX(4, 776), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evlhhousplat",VX(4, 781), VX_MASK,	PPCSPE,		{ RS, EVUIMM_2, RA } },
++{ "evlhhousplatx",VX(4, 780), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evlhhossplat",VX(4, 783), VX_MASK,	PPCSPE,		{ RS, EVUIMM_2, RA } },
++{ "evlhhossplatx",VX(4, 782), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evstdd",    VX(4, 801), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
++{ "evstddx",   VX(4, 800), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evstdw",    VX(4, 803), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
++{ "evstdwx",   VX(4, 802), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evstdh",    VX(4, 805), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
++{ "evstdhx",   VX(4, 804), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evstwwe",   VX(4, 825), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
++{ "evstwwex",  VX(4, 824), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evstwwo",   VX(4, 829), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
++{ "evstwwox",  VX(4, 828), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evstwhe",   VX(4, 817), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
++{ "evstwhex",  VX(4, 816), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evstwho",   VX(4, 821), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
++{ "evstwhox",  VX(4, 820), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evfsabs",   VX(4, 644), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evfsnabs",  VX(4, 645), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evfsneg",   VX(4, 646), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evfsadd",   VX(4, 640), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evfssub",   VX(4, 641), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evfsmul",   VX(4, 648), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evfsdiv",   VX(4, 649), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evfscmpgt", VX(4, 652), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evfscmplt", VX(4, 653), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evfscmpeq", VX(4, 654), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evfststgt", VX(4, 668), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evfststlt", VX(4, 669), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evfststeq", VX(4, 670), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
++{ "evfscfui",  VX(4, 656), VX_MASK,	PPCSPE,		{ RS, RB } },
++{ "evfsctuiz", VX(4, 664), VX_MASK,	PPCSPE,		{ RS, RB } },
++{ "evfscfsi",  VX(4, 657), VX_MASK,	PPCSPE,		{ RS, RB } },
++{ "evfscfuf",  VX(4, 658), VX_MASK,	PPCSPE,		{ RS, RB } },
++{ "evfscfsf",  VX(4, 659), VX_MASK,	PPCSPE,		{ RS, RB } },
++{ "evfsctui",  VX(4, 660), VX_MASK,	PPCSPE,		{ RS, RB } },
++{ "evfsctsi",  VX(4, 661), VX_MASK,	PPCSPE,		{ RS, RB } },
++{ "evfsctsiz", VX(4, 666), VX_MASK,	PPCSPE,		{ RS, RB } },
++{ "evfsctuf",  VX(4, 662), VX_MASK,	PPCSPE,		{ RS, RB } },
++{ "evfsctsf",  VX(4, 663), VX_MASK,	PPCSPE,		{ RS, RB } },
++
++{ "efsabs",   VX(4, 708), VX_MASK,	PPCEFS,		{ RS, RA } },
++{ "efsnabs",  VX(4, 709), VX_MASK,	PPCEFS,		{ RS, RA } },
++{ "efsneg",   VX(4, 710), VX_MASK,	PPCEFS,		{ RS, RA } },
++{ "efsadd",   VX(4, 704), VX_MASK,	PPCEFS,		{ RS, RA, RB } },
++{ "efssub",   VX(4, 705), VX_MASK,	PPCEFS,		{ RS, RA, RB } },
++{ "efsmul",   VX(4, 712), VX_MASK,	PPCEFS,		{ RS, RA, RB } },
++{ "efsdiv",   VX(4, 713), VX_MASK,	PPCEFS,		{ RS, RA, RB } },
++{ "efscmpgt", VX(4, 716), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
++{ "efscmplt", VX(4, 717), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
++{ "efscmpeq", VX(4, 718), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
++{ "efststgt", VX(4, 732), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
++{ "efststlt", VX(4, 733), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
++{ "efststeq", VX(4, 734), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
++{ "efscfui",  VX(4, 720), VX_MASK,	PPCEFS,		{ RS, RB } },
++{ "efsctuiz", VX(4, 728), VX_MASK,	PPCEFS,		{ RS, RB } },
++{ "efscfsi",  VX(4, 721), VX_MASK,	PPCEFS,		{ RS, RB } },
++{ "efscfuf",  VX(4, 722), VX_MASK,	PPCEFS,		{ RS, RB } },
++{ "efscfsf",  VX(4, 723), VX_MASK,	PPCEFS,		{ RS, RB } },
++{ "efsctui",  VX(4, 724), VX_MASK,	PPCEFS,		{ RS, RB } },
++{ "efsctsi",  VX(4, 725), VX_MASK,	PPCEFS,		{ RS, RB } },
++{ "efsctsiz", VX(4, 730), VX_MASK,	PPCEFS,		{ RS, RB } },
++{ "efsctuf",  VX(4, 726), VX_MASK,	PPCEFS,		{ RS, RB } },
++{ "efsctsf",  VX(4, 727), VX_MASK,	PPCEFS,		{ RS, RB } },
++
++{ "evmhossf",  VX(4, 1031), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhossfa", VX(4, 1063), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhosmf",  VX(4, 1039), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhosmfa", VX(4, 1071), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhosmi",  VX(4, 1037), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhosmia", VX(4, 1069), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhoumi",  VX(4, 1036), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhoumia", VX(4, 1068), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhessf",  VX(4, 1027), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhessfa", VX(4, 1059), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhesmf",  VX(4, 1035), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhesmfa", VX(4, 1067), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhesmi",  VX(4, 1033), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhesmia", VX(4, 1065), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmheumi",  VX(4, 1032), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmheumia", VX(4, 1064), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmhossfaaw",VX(4, 1287), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhossiaaw",VX(4, 1285), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhosmfaaw",VX(4, 1295), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhosmiaaw",VX(4, 1293), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhousiaaw",VX(4, 1284), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhoumiaaw",VX(4, 1292), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhessfaaw",VX(4, 1283), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhessiaaw",VX(4, 1281), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhesmfaaw",VX(4, 1291), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhesmiaaw",VX(4, 1289), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmheusiaaw",VX(4, 1280), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmheumiaaw",VX(4, 1288), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmhossfanw",VX(4, 1415), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhossianw",VX(4, 1413), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhosmfanw",VX(4, 1423), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhosmianw",VX(4, 1421), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhousianw",VX(4, 1412), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhoumianw",VX(4, 1420), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhessfanw",VX(4, 1411), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhessianw",VX(4, 1409), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhesmfanw",VX(4, 1419), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhesmianw",VX(4, 1417), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmheusianw",VX(4, 1408), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmheumianw",VX(4, 1416), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmhogsmfaa",VX(4, 1327), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhogsmiaa",VX(4, 1325), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhogumiaa",VX(4, 1324), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhegsmfaa",VX(4, 1323), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhegsmiaa",VX(4, 1321), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhegumiaa",VX(4, 1320), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmhogsmfan",VX(4, 1455), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhogsmian",VX(4, 1453), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhogumian",VX(4, 1452), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhegsmfan",VX(4, 1451), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhegsmian",VX(4, 1449), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmhegumian",VX(4, 1448), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmwhssf",  VX(4, 1095), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwhssfa", VX(4, 1127), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwhsmf",  VX(4, 1103), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwhsmfa", VX(4, 1135), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwhsmi",  VX(4, 1101), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwhsmia", VX(4, 1133), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwhumi",  VX(4, 1100), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwhumia", VX(4, 1132), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmwlumi",  VX(4, 1096), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwlumia", VX(4, 1128), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmwlssiaaw",VX(4, 1345), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwlsmiaaw",VX(4, 1353), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwlusiaaw",VX(4, 1344), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwlumiaaw",VX(4, 1352), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmwlssianw",VX(4, 1473), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwlsmianw",VX(4, 1481), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwlusianw",VX(4, 1472), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwlumianw",VX(4, 1480), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmwssf",   VX(4, 1107), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwssfa",  VX(4, 1139), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwsmf",   VX(4, 1115), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwsmfa",  VX(4, 1147), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwsmi",   VX(4, 1113), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwsmia",  VX(4, 1145), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwumi",   VX(4, 1112), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwumia",  VX(4, 1144), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmwssfaa", VX(4, 1363), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwsmfaa", VX(4, 1371), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwsmiaa", VX(4, 1369), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwumiaa", VX(4, 1368), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evmwssfan", VX(4, 1491), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwsmfan", VX(4, 1499), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwsmian", VX(4, 1497), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evmwumian", VX(4, 1496), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "evaddssiaaw",VX(4, 1217), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evaddsmiaaw",VX(4, 1225), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evaddusiaaw",VX(4, 1216), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evaddumiaaw",VX(4, 1224), VX_MASK,	PPCSPE,		{ RS, RA } },
++
++{ "evsubfssiaaw",VX(4, 1219), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evsubfsmiaaw",VX(4, 1227), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evsubfusiaaw",VX(4, 1218), VX_MASK,	PPCSPE,		{ RS, RA } },
++{ "evsubfumiaaw",VX(4, 1226), VX_MASK,	PPCSPE,		{ RS, RA } },
++
++{ "evmra",    VX(4, 1220), VX_MASK,	PPCSPE,		{ RS, RA } },
++
++{ "evdivws",  VX(4, 1222), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++{ "evdivwu",  VX(4, 1223), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
++
++{ "mulli",   OP(7),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
++{ "muli",    OP(7),	OP_MASK,	PWRCOM,		{ RT, RA, SI } },
++
++{ "subfic",  OP(8),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
++{ "sfi",     OP(8),	OP_MASK,	PWRCOM,		{ RT, RA, SI } },
++
++{ "dozi",    OP(9),	OP_MASK,	M601,		{ RT, RA, SI } },
++
++{ "bce",     B(9,0,0),	B_MASK,		BOOKE64,	{ BO, BI, BD } },
++{ "bcel",    B(9,0,1),	B_MASK,		BOOKE64,	{ BO, BI, BD } },
++{ "bcea",    B(9,1,0),	B_MASK,		BOOKE64,	{ BO, BI, BDA } },
++{ "bcela",   B(9,1,1),	B_MASK,		BOOKE64,	{ BO, BI, BDA } },
++
++{ "cmplwi",  OPL(10,0),	OPL_MASK,	PPCCOM,		{ OBF, RA, UI } },
++{ "cmpldi",  OPL(10,1), OPL_MASK,	PPC64,		{ OBF, RA, UI } },
++{ "cmpli",   OP(10),	OP_MASK,	PPC,		{ BF, L, RA, UI } },
++{ "cmpli",   OP(10),	OP_MASK,	PWRCOM,		{ BF, RA, UI } },
++
++{ "cmpwi",   OPL(11,0),	OPL_MASK,	PPCCOM,		{ OBF, RA, SI } },
++{ "cmpdi",   OPL(11,1),	OPL_MASK,	PPC64,		{ OBF, RA, SI } },
++{ "cmpi",    OP(11),	OP_MASK,	PPC,		{ BF, L, RA, SI } },
++{ "cmpi",    OP(11),	OP_MASK,	PWRCOM,		{ BF, RA, SI } },
++
++{ "addic",   OP(12),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
++{ "ai",	     OP(12),	OP_MASK,	PWRCOM,		{ RT, RA, SI } },
++{ "subic",   OP(12),	OP_MASK,	PPCCOM,		{ RT, RA, NSI } },
++
++{ "addic.",  OP(13),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
++{ "ai.",     OP(13),	OP_MASK,	PWRCOM,		{ RT, RA, SI } },
++{ "subic.",  OP(13),	OP_MASK,	PPCCOM,		{ RT, RA, NSI } },
++
++{ "li",	     OP(14),	DRA_MASK,	PPCCOM,		{ RT, SI } },
++{ "lil",     OP(14),	DRA_MASK,	PWRCOM,		{ RT, SI } },
++{ "addi",    OP(14),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
++{ "cal",     OP(14),	OP_MASK,	PWRCOM,		{ RT, D, RA } },
++{ "subi",    OP(14),	OP_MASK,	PPCCOM,		{ RT, RA, NSI } },
++{ "la",	     OP(14),	OP_MASK,	PPCCOM,		{ RT, D, RA } },
++
++{ "lis",     OP(15),	DRA_MASK,	PPCCOM,		{ RT, SISIGNOPT } },
++{ "liu",     OP(15),	DRA_MASK,	PWRCOM,		{ RT, SISIGNOPT } },
++{ "addis",   OP(15),	OP_MASK,	PPCCOM,		{ RT,RA,SISIGNOPT } },
++{ "cau",     OP(15),	OP_MASK,	PWRCOM,		{ RT,RA,SISIGNOPT } },
++{ "subis",   OP(15),	OP_MASK,	PPCCOM,		{ RT, RA, NSI } },
++
++{ "bdnz-",   BBO(16,BODNZ,0,0),      BBOATBI_MASK, PPCCOM,	{ BDM } },
++{ "bdnz+",   BBO(16,BODNZ,0,0),      BBOATBI_MASK, PPCCOM,	{ BDP } },
++{ "bdnz",    BBO(16,BODNZ,0,0),      BBOATBI_MASK, PPCCOM,	{ BD } },
++{ "bdn",     BBO(16,BODNZ,0,0),      BBOATBI_MASK, PWRCOM,	{ BD } },
++{ "bdnzl-",  BBO(16,BODNZ,0,1),      BBOATBI_MASK, PPCCOM,	{ BDM } },
++{ "bdnzl+",  BBO(16,BODNZ,0,1),      BBOATBI_MASK, PPCCOM,	{ BDP } },
++{ "bdnzl",   BBO(16,BODNZ,0,1),      BBOATBI_MASK, PPCCOM,	{ BD } },
++{ "bdnl",    BBO(16,BODNZ,0,1),      BBOATBI_MASK, PWRCOM,	{ BD } },
++{ "bdnza-",  BBO(16,BODNZ,1,0),      BBOATBI_MASK, PPCCOM,	{ BDMA } },
++{ "bdnza+",  BBO(16,BODNZ,1,0),      BBOATBI_MASK, PPCCOM,	{ BDPA } },
++{ "bdnza",   BBO(16,BODNZ,1,0),      BBOATBI_MASK, PPCCOM,	{ BDA } },
++{ "bdna",    BBO(16,BODNZ,1,0),      BBOATBI_MASK, PWRCOM,	{ BDA } },
++{ "bdnzla-", BBO(16,BODNZ,1,1),      BBOATBI_MASK, PPCCOM,	{ BDMA } },
++{ "bdnzla+", BBO(16,BODNZ,1,1),      BBOATBI_MASK, PPCCOM,	{ BDPA } },
++{ "bdnzla",  BBO(16,BODNZ,1,1),      BBOATBI_MASK, PPCCOM,	{ BDA } },
++{ "bdnla",   BBO(16,BODNZ,1,1),      BBOATBI_MASK, PWRCOM,	{ BDA } },
++{ "bdz-",    BBO(16,BODZ,0,0),       BBOATBI_MASK, PPCCOM,	{ BDM } },
++{ "bdz+",    BBO(16,BODZ,0,0),       BBOATBI_MASK, PPCCOM,	{ BDP } },
++{ "bdz",     BBO(16,BODZ,0,0),       BBOATBI_MASK, COM,		{ BD } },
++{ "bdzl-",   BBO(16,BODZ,0,1),       BBOATBI_MASK, PPCCOM,	{ BDM } },
++{ "bdzl+",   BBO(16,BODZ,0,1),       BBOATBI_MASK, PPCCOM,	{ BDP } },
++{ "bdzl",    BBO(16,BODZ,0,1),       BBOATBI_MASK, COM,		{ BD } },
++{ "bdza-",   BBO(16,BODZ,1,0),       BBOATBI_MASK, PPCCOM,	{ BDMA } },
++{ "bdza+",   BBO(16,BODZ,1,0),       BBOATBI_MASK, PPCCOM,	{ BDPA } },
++{ "bdza",    BBO(16,BODZ,1,0),       BBOATBI_MASK, COM,		{ BDA } },
++{ "bdzla-",  BBO(16,BODZ,1,1),       BBOATBI_MASK, PPCCOM,	{ BDMA } },
++{ "bdzla+",  BBO(16,BODZ,1,1),       BBOATBI_MASK, PPCCOM,	{ BDPA } },
++{ "bdzla",   BBO(16,BODZ,1,1),       BBOATBI_MASK, COM,		{ BDA } },
++{ "blt-",    BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "blt+",    BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "blt",     BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bltl-",   BBOCB(16,BOT,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bltl+",   BBOCB(16,BOT,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bltl",    BBOCB(16,BOT,CBLT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "blta-",   BBOCB(16,BOT,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "blta+",   BBOCB(16,BOT,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "blta",    BBOCB(16,BOT,CBLT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bltla-",  BBOCB(16,BOT,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bltla+",  BBOCB(16,BOT,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bltla",   BBOCB(16,BOT,CBLT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bgt-",    BBOCB(16,BOT,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bgt+",    BBOCB(16,BOT,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bgt",     BBOCB(16,BOT,CBGT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bgtl-",   BBOCB(16,BOT,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bgtl+",   BBOCB(16,BOT,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bgtl",    BBOCB(16,BOT,CBGT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bgta-",   BBOCB(16,BOT,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bgta+",   BBOCB(16,BOT,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bgta",    BBOCB(16,BOT,CBGT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bgtla-",  BBOCB(16,BOT,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bgtla+",  BBOCB(16,BOT,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bgtla",   BBOCB(16,BOT,CBGT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "beq-",    BBOCB(16,BOT,CBEQ,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "beq+",    BBOCB(16,BOT,CBEQ,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "beq",     BBOCB(16,BOT,CBEQ,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "beql-",   BBOCB(16,BOT,CBEQ,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "beql+",   BBOCB(16,BOT,CBEQ,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "beql",    BBOCB(16,BOT,CBEQ,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "beqa-",   BBOCB(16,BOT,CBEQ,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "beqa+",   BBOCB(16,BOT,CBEQ,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "beqa",    BBOCB(16,BOT,CBEQ,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "beqla-",  BBOCB(16,BOT,CBEQ,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "beqla+",  BBOCB(16,BOT,CBEQ,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "beqla",   BBOCB(16,BOT,CBEQ,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bso-",    BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bso+",    BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bso",     BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bsol-",   BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bsol+",   BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bsol",    BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bsoa-",   BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bsoa+",   BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bsoa",    BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bsola-",  BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bsola+",  BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bsola",   BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bun-",    BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bun+",    BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bun",     BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BD } },
++{ "bunl-",   BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bunl+",   BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bunl",    BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BD } },
++{ "buna-",   BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "buna+",   BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "buna",    BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDA } },
++{ "bunla-",  BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bunla+",  BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bunla",   BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDA } },
++{ "bge-",    BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bge+",    BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bge",     BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bgel-",   BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bgel+",   BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bgel",    BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bgea-",   BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bgea+",   BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bgea",    BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bgela-",  BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bgela+",  BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bgela",   BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bnl-",    BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bnl+",    BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bnl",     BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bnll-",   BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bnll+",   BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bnll",    BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bnla-",   BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bnla+",   BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bnla",    BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bnlla-",  BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bnlla+",  BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bnlla",   BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "ble-",    BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "ble+",    BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "ble",     BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "blel-",   BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "blel+",   BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "blel",    BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "blea-",   BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "blea+",   BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "blea",    BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "blela-",  BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "blela+",  BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "blela",   BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bng-",    BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bng+",    BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bng",     BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bngl-",   BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bngl+",   BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bngl",    BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bnga-",   BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bnga+",   BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bnga",    BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bngla-",  BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bngla+",  BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bngla",   BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bne-",    BBOCB(16,BOF,CBEQ,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bne+",    BBOCB(16,BOF,CBEQ,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bne",     BBOCB(16,BOF,CBEQ,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bnel-",   BBOCB(16,BOF,CBEQ,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bnel+",   BBOCB(16,BOF,CBEQ,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bnel",    BBOCB(16,BOF,CBEQ,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bnea-",   BBOCB(16,BOF,CBEQ,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bnea+",   BBOCB(16,BOF,CBEQ,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bnea",    BBOCB(16,BOF,CBEQ,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bnela-",  BBOCB(16,BOF,CBEQ,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bnela+",  BBOCB(16,BOF,CBEQ,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bnela",   BBOCB(16,BOF,CBEQ,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bns-",    BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bns+",    BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bns",     BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bnsl-",   BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bnsl+",   BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bnsl",    BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
++{ "bnsa-",   BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bnsa+",   BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bnsa",    BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bnsla-",  BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bnsla+",  BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bnsla",   BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
++{ "bnu-",    BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bnu+",    BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bnu",     BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BD } },
++{ "bnul-",   BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
++{ "bnul+",   BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
++{ "bnul",    BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BD } },
++{ "bnua-",   BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bnua+",   BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bnua",    BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDA } },
++{ "bnula-",  BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
++{ "bnula+",  BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
++{ "bnula",   BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDA } },
++{ "bdnzt-",  BBO(16,BODNZT,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
++{ "bdnzt+",  BBO(16,BODNZT,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
++{ "bdnzt",   BBO(16,BODNZT,0,0), BBOY_MASK, PPCCOM,	{ BI, BD } },
++{ "bdnztl-", BBO(16,BODNZT,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
++{ "bdnztl+", BBO(16,BODNZT,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
++{ "bdnztl",  BBO(16,BODNZT,0,1), BBOY_MASK, PPCCOM,	{ BI, BD } },
++{ "bdnzta-", BBO(16,BODNZT,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
++{ "bdnzta+", BBO(16,BODNZT,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
++{ "bdnzta",  BBO(16,BODNZT,1,0), BBOY_MASK, PPCCOM,	{ BI, BDA } },
++{ "bdnztla-",BBO(16,BODNZT,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
++{ "bdnztla+",BBO(16,BODNZT,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
++{ "bdnztla", BBO(16,BODNZT,1,1), BBOY_MASK, PPCCOM,	{ BI, BDA } },
++{ "bdnzf-",  BBO(16,BODNZF,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
++{ "bdnzf+",  BBO(16,BODNZF,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
++{ "bdnzf",   BBO(16,BODNZF,0,0), BBOY_MASK, PPCCOM,	{ BI, BD } },
++{ "bdnzfl-", BBO(16,BODNZF,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
++{ "bdnzfl+", BBO(16,BODNZF,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
++{ "bdnzfl",  BBO(16,BODNZF,0,1), BBOY_MASK, PPCCOM,	{ BI, BD } },
++{ "bdnzfa-", BBO(16,BODNZF,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
++{ "bdnzfa+", BBO(16,BODNZF,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
++{ "bdnzfa",  BBO(16,BODNZF,1,0), BBOY_MASK, PPCCOM,	{ BI, BDA } },
++{ "bdnzfla-",BBO(16,BODNZF,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
++{ "bdnzfla+",BBO(16,BODNZF,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
++{ "bdnzfla", BBO(16,BODNZF,1,1), BBOY_MASK, PPCCOM,	{ BI, BDA } },
++{ "bt-",     BBO(16,BOT,0,0), BBOAT_MASK, PPCCOM,	{ BI, BDM } },
++{ "bt+",     BBO(16,BOT,0,0), BBOAT_MASK, PPCCOM,	{ BI, BDP } },
++{ "bt",	     BBO(16,BOT,0,0), BBOAT_MASK, PPCCOM,	{ BI, BD } },
++{ "bbt",     BBO(16,BOT,0,0), BBOAT_MASK, PWRCOM,	{ BI, BD } },
++{ "btl-",    BBO(16,BOT,0,1), BBOAT_MASK, PPCCOM,	{ BI, BDM } },
++{ "btl+",    BBO(16,BOT,0,1), BBOAT_MASK, PPCCOM,	{ BI, BDP } },
++{ "btl",     BBO(16,BOT,0,1), BBOAT_MASK, PPCCOM,	{ BI, BD } },
++{ "bbtl",    BBO(16,BOT,0,1), BBOAT_MASK, PWRCOM,	{ BI, BD } },
++{ "bta-",    BBO(16,BOT,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDMA } },
++{ "bta+",    BBO(16,BOT,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDPA } },
++{ "bta",     BBO(16,BOT,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDA } },
++{ "bbta",    BBO(16,BOT,1,0), BBOAT_MASK, PWRCOM,	{ BI, BDA } },
++{ "btla-",   BBO(16,BOT,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDMA } },
++{ "btla+",   BBO(16,BOT,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDPA } },
++{ "btla",    BBO(16,BOT,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDA } },
++{ "bbtla",   BBO(16,BOT,1,1), BBOAT_MASK, PWRCOM,	{ BI, BDA } },
++{ "bf-",     BBO(16,BOF,0,0), BBOAT_MASK, PPCCOM,	{ BI, BDM } },
++{ "bf+",     BBO(16,BOF,0,0), BBOAT_MASK, PPCCOM,	{ BI, BDP } },
++{ "bf",	     BBO(16,BOF,0,0), BBOAT_MASK, PPCCOM,	{ BI, BD } },
++{ "bbf",     BBO(16,BOF,0,0), BBOAT_MASK, PWRCOM,	{ BI, BD } },
++{ "bfl-",    BBO(16,BOF,0,1), BBOAT_MASK, PPCCOM,	{ BI, BDM } },
++{ "bfl+",    BBO(16,BOF,0,1), BBOAT_MASK, PPCCOM,	{ BI, BDP } },
++{ "bfl",     BBO(16,BOF,0,1), BBOAT_MASK, PPCCOM,	{ BI, BD } },
++{ "bbfl",    BBO(16,BOF,0,1), BBOAT_MASK, PWRCOM,	{ BI, BD } },
++{ "bfa-",    BBO(16,BOF,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDMA } },
++{ "bfa+",    BBO(16,BOF,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDPA } },
++{ "bfa",     BBO(16,BOF,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDA } },
++{ "bbfa",    BBO(16,BOF,1,0), BBOAT_MASK, PWRCOM,	{ BI, BDA } },
++{ "bfla-",   BBO(16,BOF,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDMA } },
++{ "bfla+",   BBO(16,BOF,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDPA } },
++{ "bfla",    BBO(16,BOF,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDA } },
++{ "bbfla",   BBO(16,BOF,1,1), BBOAT_MASK, PWRCOM,	{ BI, BDA } },
++{ "bdzt-",   BBO(16,BODZT,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
++{ "bdzt+",   BBO(16,BODZT,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
++{ "bdzt",    BBO(16,BODZT,0,0), BBOY_MASK, PPCCOM,	{ BI, BD } },
++{ "bdztl-",  BBO(16,BODZT,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
++{ "bdztl+",  BBO(16,BODZT,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
++{ "bdztl",   BBO(16,BODZT,0,1), BBOY_MASK, PPCCOM,	{ BI, BD } },
++{ "bdzta-",  BBO(16,BODZT,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
++{ "bdzta+",  BBO(16,BODZT,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
++{ "bdzta",   BBO(16,BODZT,1,0), BBOY_MASK, PPCCOM,	{ BI, BDA } },
++{ "bdztla-", BBO(16,BODZT,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
++{ "bdztla+", BBO(16,BODZT,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
++{ "bdztla",  BBO(16,BODZT,1,1), BBOY_MASK, PPCCOM,	{ BI, BDA } },
++{ "bdzf-",   BBO(16,BODZF,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
++{ "bdzf+",   BBO(16,BODZF,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
++{ "bdzf",    BBO(16,BODZF,0,0), BBOY_MASK, PPCCOM,	{ BI, BD } },
++{ "bdzfl-",  BBO(16,BODZF,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
++{ "bdzfl+",  BBO(16,BODZF,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
++{ "bdzfl",   BBO(16,BODZF,0,1), BBOY_MASK, PPCCOM,	{ BI, BD } },
++{ "bdzfa-",  BBO(16,BODZF,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
++{ "bdzfa+",  BBO(16,BODZF,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
++{ "bdzfa",   BBO(16,BODZF,1,0), BBOY_MASK, PPCCOM,	{ BI, BDA } },
++{ "bdzfla-", BBO(16,BODZF,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
++{ "bdzfla+", BBO(16,BODZF,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
++{ "bdzfla",  BBO(16,BODZF,1,1), BBOY_MASK, PPCCOM,	{ BI, BDA } },
++{ "bc-",     B(16,0,0),	B_MASK,		PPCCOM,		{ BOE, BI, BDM } },
++{ "bc+",     B(16,0,0),	B_MASK,		PPCCOM,		{ BOE, BI, BDP } },
++{ "bc",	     B(16,0,0),	B_MASK,		COM,		{ BO, BI, BD } },
++{ "bcl-",    B(16,0,1),	B_MASK,		PPCCOM,		{ BOE, BI, BDM } },
++{ "bcl+",    B(16,0,1),	B_MASK,		PPCCOM,		{ BOE, BI, BDP } },
++{ "bcl",     B(16,0,1),	B_MASK,		COM,		{ BO, BI, BD } },
++{ "bca-",    B(16,1,0),	B_MASK,		PPCCOM,		{ BOE, BI, BDMA } },
++{ "bca+",    B(16,1,0),	B_MASK,		PPCCOM,		{ BOE, BI, BDPA } },
++{ "bca",     B(16,1,0),	B_MASK,		COM,		{ BO, BI, BDA } },
++{ "bcla-",   B(16,1,1),	B_MASK,		PPCCOM,		{ BOE, BI, BDMA } },
++{ "bcla+",   B(16,1,1),	B_MASK,		PPCCOM,		{ BOE, BI, BDPA } },
++{ "bcla",    B(16,1,1),	B_MASK,		COM,		{ BO, BI, BDA } },
++
++{ "sc",      SC(17,1,0), 0xffffffff,	PPC,		{ 0 } },
++{ "svc",     SC(17,0,0), SC_MASK,	POWER,		{ LEV, FL1, FL2 } },
++{ "svcl",    SC(17,0,1), SC_MASK,	POWER,		{ LEV, FL1, FL2 } },
++{ "svca",    SC(17,1,0), SC_MASK,	PWRCOM,		{ SV } },
++{ "svcla",   SC(17,1,1), SC_MASK,	POWER,		{ SV } },
++
++{ "b",	     B(18,0,0),	B_MASK,		COM,		{ LI } },
++{ "bl",      B(18,0,1),	B_MASK,		COM,		{ LI } },
++{ "ba",      B(18,1,0),	B_MASK,		COM,		{ LIA } },
++{ "bla",     B(18,1,1),	B_MASK,		COM,		{ LIA } },
++
++{ "mcrf",    XL(19,0),	XLBB_MASK|(3 << 21)|(3 << 16), COM,	{ BF, BFA } },
++
++{ "blr",     XLO(19,BOU,16,0), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
++{ "br",      XLO(19,BOU,16,0), XLBOBIBB_MASK, PWRCOM,	{ 0 } },
++{ "blrl",    XLO(19,BOU,16,1), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
++{ "brl",     XLO(19,BOU,16,1), XLBOBIBB_MASK, PWRCOM,	{ 0 } },
++{ "bdnzlr",  XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
++{ "bdnzlr-", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
++{ "bdnzlr-", XLO(19,BODNZM4,16,0), XLBOBIBB_MASK, POWER4,	{ 0 } },
++{ "bdnzlr+", XLO(19,BODNZP,16,0), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
++{ "bdnzlr+", XLO(19,BODNZP4,16,0), XLBOBIBB_MASK, POWER4,	{ 0 } },
++{ "bdnzlrl", XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
++{ "bdnzlrl-",XLO(19,BODNZ,16,1), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
++{ "bdnzlrl-",XLO(19,BODNZM4,16,1), XLBOBIBB_MASK, POWER4,	{ 0 } },
++{ "bdnzlrl+",XLO(19,BODNZP,16,1), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
++{ "bdnzlrl+",XLO(19,BODNZP4,16,1), XLBOBIBB_MASK, POWER4,	{ 0 } },
++{ "bdzlr",   XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
++{ "bdzlr-",  XLO(19,BODZ,16,0), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
++{ "bdzlr-",  XLO(19,BODZM4,16,0), XLBOBIBB_MASK, POWER4,	{ 0 } },
++{ "bdzlr+",  XLO(19,BODZP,16,0), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
++{ "bdzlr+",  XLO(19,BODZP4,16,0), XLBOBIBB_MASK, POWER4,	{ 0 } },
++{ "bdzlrl",  XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
++{ "bdzlrl-", XLO(19,BODZ,16,1), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
++{ "bdzlrl-", XLO(19,BODZM4,16,1), XLBOBIBB_MASK, POWER4,	{ 0 } },
++{ "bdzlrl+", XLO(19,BODZP,16,1), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
++{ "bdzlrl+", XLO(19,BODZP4,16,1), XLBOBIBB_MASK, POWER4,	{ 0 } },
++{ "bltlr",   XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bltlr-",  XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bltlr-",  XLOCB(19,BOTM4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bltlr+",  XLOCB(19,BOTP,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bltlr+",  XLOCB(19,BOTP4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bltr",    XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bltlrl",  XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bltlrl-", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bltlrl-", XLOCB(19,BOTM4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bltlrl+", XLOCB(19,BOTP,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bltlrl+", XLOCB(19,BOTP4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bltrl",   XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bgtlr",   XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bgtlr-",  XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgtlr-",  XLOCB(19,BOTM4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgtlr+",  XLOCB(19,BOTP,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgtlr+",  XLOCB(19,BOTP4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgtr",    XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bgtlrl",  XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bgtlrl-", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgtlrl-", XLOCB(19,BOTM4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgtlrl+", XLOCB(19,BOTP,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgtlrl+", XLOCB(19,BOTP4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgtrl",   XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "beqlr",   XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "beqlr-",  XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "beqlr-",  XLOCB(19,BOTM4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "beqlr+",  XLOCB(19,BOTP,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "beqlr+",  XLOCB(19,BOTP4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "beqr",    XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "beqlrl",  XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "beqlrl-", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "beqlrl-", XLOCB(19,BOTM4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "beqlrl+", XLOCB(19,BOTP,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "beqlrl+", XLOCB(19,BOTP4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "beqrl",   XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bsolr",   XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bsolr-",  XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bsolr-",  XLOCB(19,BOTM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bsolr+",  XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bsolr+",  XLOCB(19,BOTP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bsor",    XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bsolrl",  XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bsolrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bsolrl-", XLOCB(19,BOTM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bsolrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bsolrl+", XLOCB(19,BOTP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bsorl",   XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bunlr",   XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bunlr-",  XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bunlr-",  XLOCB(19,BOTM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bunlr+",  XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bunlr+",  XLOCB(19,BOTP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bunlrl",  XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bunlrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bunlrl-", XLOCB(19,BOTM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bunlrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bunlrl+", XLOCB(19,BOTP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgelr",   XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bgelr-",  XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgelr-",  XLOCB(19,BOFM4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgelr+",  XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgelr+",  XLOCB(19,BOFP4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bger",    XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bgelrl",  XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bgelrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgelrl-", XLOCB(19,BOFM4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgelrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgelrl+", XLOCB(19,BOFP4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgerl",   XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bnllr",   XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnllr-",  XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnllr-",  XLOCB(19,BOFM4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnllr+",  XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnllr+",  XLOCB(19,BOFP4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnlr",    XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bnllrl",  XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnllrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnllrl-", XLOCB(19,BOFM4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnllrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnllrl+", XLOCB(19,BOFP4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnlrl",   XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "blelr",   XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "blelr-",  XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "blelr-",  XLOCB(19,BOFM4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "blelr+",  XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "blelr+",  XLOCB(19,BOFP4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bler",    XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "blelrl",  XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "blelrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "blelrl-", XLOCB(19,BOFM4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "blelrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "blelrl+", XLOCB(19,BOFP4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "blerl",   XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bnglr",   XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnglr-",  XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnglr-",  XLOCB(19,BOFM4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnglr+",  XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnglr+",  XLOCB(19,BOFP4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bngr",    XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bnglrl",  XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnglrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnglrl-", XLOCB(19,BOFM4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnglrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnglrl+", XLOCB(19,BOFP4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bngrl",   XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bnelr",   XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnelr-",  XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnelr-",  XLOCB(19,BOFM4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnelr+",  XLOCB(19,BOFP,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnelr+",  XLOCB(19,BOFP4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bner",    XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bnelrl",  XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnelrl-", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnelrl-", XLOCB(19,BOFM4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnelrl+", XLOCB(19,BOFP,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnelrl+", XLOCB(19,BOFP4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnerl",   XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bnslr",   XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnslr-",  XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnslr-",  XLOCB(19,BOFM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnslr+",  XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnslr+",  XLOCB(19,BOFP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnsr",    XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bnslrl",  XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnslrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnslrl-", XLOCB(19,BOFM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnslrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnslrl+", XLOCB(19,BOFP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnsrl",   XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
++{ "bnulr",   XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnulr-",  XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnulr-",  XLOCB(19,BOFM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnulr+",  XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnulr+",  XLOCB(19,BOFP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnulrl",  XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
++{ "bnulrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnulrl-", XLOCB(19,BOFM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnulrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnulrl+", XLOCB(19,BOFP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "btlr",    XLO(19,BOT,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "btlr-",   XLO(19,BOT,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "btlr-",   XLO(19,BOTM4,16,0), XLBOBB_MASK, POWER4,	{ BI } },
++{ "btlr+",   XLO(19,BOTP,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "btlr+",   XLO(19,BOTP4,16,0), XLBOBB_MASK, POWER4,	{ BI } },
++{ "bbtr",    XLO(19,BOT,16,0), XLBOBB_MASK, PWRCOM,	{ BI } },
++{ "btlrl",   XLO(19,BOT,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "btlrl-",  XLO(19,BOT,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "btlrl-",  XLO(19,BOTM4,16,1), XLBOBB_MASK, POWER4,	{ BI } },
++{ "btlrl+",  XLO(19,BOTP,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "btlrl+",  XLO(19,BOTP4,16,1), XLBOBB_MASK, POWER4,	{ BI } },
++{ "bbtrl",   XLO(19,BOT,16,1), XLBOBB_MASK, PWRCOM,	{ BI } },
++{ "bflr",    XLO(19,BOF,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bflr-",   XLO(19,BOF,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "bflr-",   XLO(19,BOFM4,16,0), XLBOBB_MASK, POWER4,	{ BI } },
++{ "bflr+",   XLO(19,BOFP,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "bflr+",   XLO(19,BOFP4,16,0), XLBOBB_MASK, POWER4,	{ BI } },
++{ "bbfr",    XLO(19,BOF,16,0), XLBOBB_MASK, PWRCOM,	{ BI } },
++{ "bflrl",   XLO(19,BOF,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bflrl-",  XLO(19,BOF,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "bflrl-",  XLO(19,BOFM4,16,1), XLBOBB_MASK, POWER4,	{ BI } },
++{ "bflrl+",  XLO(19,BOFP,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "bflrl+",  XLO(19,BOFP4,16,1), XLBOBB_MASK, POWER4,	{ BI } },
++{ "bbfrl",   XLO(19,BOF,16,1), XLBOBB_MASK, PWRCOM,	{ BI } },
++{ "bdnztlr", XLO(19,BODNZT,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bdnztlr-",XLO(19,BODNZT,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdnztlr+",XLO(19,BODNZTP,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdnztlrl",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bdnztlrl-",XLO(19,BODNZT,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdnztlrl+",XLO(19,BODNZTP,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdnzflr", XLO(19,BODNZF,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bdnzflr-",XLO(19,BODNZF,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdnzflr+",XLO(19,BODNZFP,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdnzflrl",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bdnzflrl-",XLO(19,BODNZF,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdnzflrl+",XLO(19,BODNZFP,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdztlr",  XLO(19,BODZT,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bdztlr-", XLO(19,BODZT,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "bdztlr+", XLO(19,BODZTP,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdztlrl", XLO(19,BODZT,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bdztlrl-",XLO(19,BODZT,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "bdztlrl+",XLO(19,BODZTP,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdzflr",  XLO(19,BODZF,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bdzflr-", XLO(19,BODZF,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "bdzflr+", XLO(19,BODZFP,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bclr",    XLLK(19,16,0), XLYBB_MASK,	PPCCOM,		{ BO, BI } },
++{ "bclrl",   XLLK(19,16,1), XLYBB_MASK,	PPCCOM,		{ BO, BI } },
++{ "bclr+",   XLYLK(19,16,1,0), XLYBB_MASK, PPCCOM,	{ BOE, BI } },
++{ "bclrl+",  XLYLK(19,16,1,1), XLYBB_MASK, PPCCOM,	{ BOE, BI } },
++{ "bclr-",   XLYLK(19,16,0,0), XLYBB_MASK, PPCCOM,	{ BOE, BI } },
++{ "bclrl-",  XLYLK(19,16,0,1), XLYBB_MASK, PPCCOM,	{ BOE, BI } },
++{ "bcr",     XLLK(19,16,0), XLBB_MASK,	PWRCOM,		{ BO, BI } },
++{ "bcrl",    XLLK(19,16,1), XLBB_MASK,	PWRCOM,		{ BO, BI } },
++{ "bclre",   XLLK(19,17,0), XLBB_MASK,	BOOKE64,	{ BO, BI } },
++{ "bclrel",  XLLK(19,17,1), XLBB_MASK,	BOOKE64,	{ BO, BI } },
++
++{ "rfid",    XL(19,18),	0xffffffff,	PPC64,		{ 0 } },
++
++{ "crnot",   XL(19,33), XL_MASK,	PPCCOM,		{ BT, BA, BBA } },
++{ "crnor",   XL(19,33),	XL_MASK,	COM,		{ BT, BA, BB } },
++{ "rfmci",    X(19,38), 0xffffffff,	PPCRFMCI,	{ 0 } },
++
++{ "rfi",     XL(19,50),	0xffffffff,	COM,		{ 0 } },
++{ "rfci",    XL(19,51),	0xffffffff,	PPC403 | BOOKE,	{ 0 } },
++
++{ "rfsvc",   XL(19,82),	0xffffffff,	POWER,		{ 0 } },
++
++{ "crandc",  XL(19,129), XL_MASK,	COM,		{ BT, BA, BB } },
++
++{ "isync",   XL(19,150), 0xffffffff,	PPCCOM,		{ 0 } },
++{ "ics",     XL(19,150), 0xffffffff,	PWRCOM,		{ 0 } },
++
++{ "crclr",   XL(19,193), XL_MASK,	PPCCOM,		{ BT, BAT, BBA } },
++{ "crxor",   XL(19,193), XL_MASK,	COM,		{ BT, BA, BB } },
++
++{ "crnand",  XL(19,225), XL_MASK,	COM,		{ BT, BA, BB } },
++
++{ "crand",   XL(19,257), XL_MASK,	COM,		{ BT, BA, BB } },
++
++{ "crset",   XL(19,289), XL_MASK,	PPCCOM,		{ BT, BAT, BBA } },
++{ "creqv",   XL(19,289), XL_MASK,	COM,		{ BT, BA, BB } },
++
++{ "crorc",   XL(19,417), XL_MASK,	COM,		{ BT, BA, BB } },
++
++{ "crmove",  XL(19,449), XL_MASK,	PPCCOM,		{ BT, BA, BBA } },
++{ "cror",    XL(19,449), XL_MASK,	COM,		{ BT, BA, BB } },
++
++{ "bctr",    XLO(19,BOU,528,0), XLBOBIBB_MASK, COM,	{ 0 } },
++{ "bctrl",   XLO(19,BOU,528,1), XLBOBIBB_MASK, COM,	{ 0 } },
++{ "bltctr",  XLOCB(19,BOT,CBLT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bltctr-", XLOCB(19,BOT,CBLT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bltctr-", XLOCB(19,BOTM4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bltctr+", XLOCB(19,BOTP,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bltctr+", XLOCB(19,BOTP4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bltctrl", XLOCB(19,BOT,CBLT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bltctrl-",XLOCB(19,BOT,CBLT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bltctrl-",XLOCB(19,BOTM4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bltctrl+",XLOCB(19,BOTP,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bltctrl+",XLOCB(19,BOTP4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgtctr",  XLOCB(19,BOT,CBGT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bgtctr-", XLOCB(19,BOT,CBGT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgtctr-", XLOCB(19,BOTM4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgtctr+", XLOCB(19,BOTP,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgtctr+", XLOCB(19,BOTP4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgtctrl", XLOCB(19,BOT,CBGT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bgtctrl-",XLOCB(19,BOT,CBGT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgtctrl-",XLOCB(19,BOTM4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgtctrl+",XLOCB(19,BOTP,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgtctrl+",XLOCB(19,BOTP4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "beqctr",  XLOCB(19,BOT,CBEQ,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "beqctr-", XLOCB(19,BOT,CBEQ,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "beqctr-", XLOCB(19,BOTM4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "beqctr+", XLOCB(19,BOTP,CBEQ,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "beqctr+", XLOCB(19,BOTP4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "beqctrl", XLOCB(19,BOT,CBEQ,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "beqctrl-",XLOCB(19,BOT,CBEQ,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "beqctrl-",XLOCB(19,BOTM4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "beqctrl+",XLOCB(19,BOTP,CBEQ,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "beqctrl+",XLOCB(19,BOTP4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bsoctr",  XLOCB(19,BOT,CBSO,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bsoctr-", XLOCB(19,BOT,CBSO,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bsoctr-", XLOCB(19,BOTM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bsoctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bsoctr+", XLOCB(19,BOTP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bsoctrl", XLOCB(19,BOT,CBSO,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bsoctrl-",XLOCB(19,BOT,CBSO,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bsoctrl-",XLOCB(19,BOTM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bsoctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bsoctrl+",XLOCB(19,BOTP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bunctr",  XLOCB(19,BOT,CBSO,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bunctr-", XLOCB(19,BOT,CBSO,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bunctr-", XLOCB(19,BOTM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bunctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bunctr+", XLOCB(19,BOTP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bunctrl", XLOCB(19,BOT,CBSO,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bunctrl-",XLOCB(19,BOT,CBSO,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bunctrl-",XLOCB(19,BOTM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bunctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bunctrl+",XLOCB(19,BOTP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgectr",  XLOCB(19,BOF,CBLT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bgectr-", XLOCB(19,BOF,CBLT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgectr-", XLOCB(19,BOFM4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgectr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgectr+", XLOCB(19,BOFP4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgectrl", XLOCB(19,BOF,CBLT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bgectrl-",XLOCB(19,BOF,CBLT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgectrl-",XLOCB(19,BOFM4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bgectrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bgectrl+",XLOCB(19,BOFP4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnlctr",  XLOCB(19,BOF,CBLT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bnlctr-", XLOCB(19,BOF,CBLT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnlctr-", XLOCB(19,BOFM4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnlctr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnlctr+", XLOCB(19,BOFP4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnlctrl", XLOCB(19,BOF,CBLT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bnlctrl-",XLOCB(19,BOF,CBLT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnlctrl-",XLOCB(19,BOFM4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnlctrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnlctrl+",XLOCB(19,BOFP4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "blectr",  XLOCB(19,BOF,CBGT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "blectr-", XLOCB(19,BOF,CBGT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "blectr-", XLOCB(19,BOFM4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "blectr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "blectr+", XLOCB(19,BOFP4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "blectrl", XLOCB(19,BOF,CBGT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "blectrl-",XLOCB(19,BOF,CBGT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "blectrl-",XLOCB(19,BOFM4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "blectrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "blectrl+",XLOCB(19,BOFP4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bngctr",  XLOCB(19,BOF,CBGT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bngctr-", XLOCB(19,BOF,CBGT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bngctr-", XLOCB(19,BOFM4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bngctr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bngctr+", XLOCB(19,BOFP4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bngctrl", XLOCB(19,BOF,CBGT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bngctrl-",XLOCB(19,BOF,CBGT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bngctrl-",XLOCB(19,BOFM4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bngctrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bngctrl+",XLOCB(19,BOFP4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnectr",  XLOCB(19,BOF,CBEQ,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bnectr-", XLOCB(19,BOF,CBEQ,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnectr-", XLOCB(19,BOFM4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnectr+", XLOCB(19,BOFP,CBEQ,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnectr+", XLOCB(19,BOFP4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnectrl", XLOCB(19,BOF,CBEQ,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bnectrl-",XLOCB(19,BOF,CBEQ,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnectrl-",XLOCB(19,BOFM4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnectrl+",XLOCB(19,BOFP,CBEQ,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnectrl+",XLOCB(19,BOFP4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnsctr",  XLOCB(19,BOF,CBSO,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bnsctr-", XLOCB(19,BOF,CBSO,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnsctr-", XLOCB(19,BOFM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnsctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnsctr+", XLOCB(19,BOFP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnsctrl", XLOCB(19,BOF,CBSO,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bnsctrl-",XLOCB(19,BOF,CBSO,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnsctrl-",XLOCB(19,BOFM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnsctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnsctrl+",XLOCB(19,BOFP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnuctr",  XLOCB(19,BOF,CBSO,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bnuctr-", XLOCB(19,BOF,CBSO,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnuctr-", XLOCB(19,BOFM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnuctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnuctr+", XLOCB(19,BOFP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnuctrl", XLOCB(19,BOF,CBSO,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
++{ "bnuctrl-",XLOCB(19,BOF,CBSO,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnuctrl-",XLOCB(19,BOFM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "bnuctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
++{ "bnuctrl+",XLOCB(19,BOFP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
++{ "btctr",   XLO(19,BOT,528,0),  XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "btctr-",  XLO(19,BOT,528,0),  XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "btctr-",  XLO(19,BOTM4,528,0), XLBOBB_MASK, POWER4, { BI } },
++{ "btctr+",  XLO(19,BOTP,528,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "btctr+",  XLO(19,BOTP4,528,0), XLBOBB_MASK, POWER4, { BI } },
++{ "btctrl",  XLO(19,BOT,528,1),  XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "btctrl-", XLO(19,BOT,528,1),  XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "btctrl-", XLO(19,BOTM4,528,1), XLBOBB_MASK, POWER4, { BI } },
++{ "btctrl+", XLO(19,BOTP,528,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
++{ "btctrl+", XLO(19,BOTP4,528,1), XLBOBB_MASK, POWER4, { BI } },
++{ "bfctr",   XLO(19,BOF,528,0),  XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bfctr-",  XLO(19,BOF,528,0),  XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bfctr-",  XLO(19,BOFM4,528,0), XLBOBB_MASK, POWER4, { BI } },
++{ "bfctr+",  XLO(19,BOFP,528,0), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bfctr+",  XLO(19,BOFP4,528,0), XLBOBB_MASK, POWER4, { BI } },
++{ "bfctrl",  XLO(19,BOF,528,1),  XLBOBB_MASK, PPCCOM,	{ BI } },
++{ "bfctrl-", XLO(19,BOF,528,1),  XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bfctrl-", XLO(19,BOFM4,528,1), XLBOBB_MASK, POWER4, { BI } },
++{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, NOPOWER4, { BI } },
++{ "bfctrl+", XLO(19,BOFP4,528,1), XLBOBB_MASK, POWER4, { BI } },
++{ "bcctr",   XLLK(19,528,0),     XLYBB_MASK,  PPCCOM,	{ BO, BI } },
++{ "bcctr-",  XLYLK(19,528,0,0),  XLYBB_MASK,  PPCCOM,	{ BOE, BI } },
++{ "bcctr+",  XLYLK(19,528,1,0),  XLYBB_MASK,  PPCCOM,	{ BOE, BI } },
++{ "bcctrl",  XLLK(19,528,1),     XLYBB_MASK,  PPCCOM,	{ BO, BI } },
++{ "bcctrl-", XLYLK(19,528,0,1),  XLYBB_MASK,  PPCCOM,	{ BOE, BI } },
++{ "bcctrl+", XLYLK(19,528,1,1),  XLYBB_MASK,  PPCCOM,	{ BOE, BI } },
++{ "bcc",     XLLK(19,528,0),     XLBB_MASK,   PWRCOM,	{ BO, BI } },
++{ "bccl",    XLLK(19,528,1),     XLBB_MASK,   PWRCOM,	{ BO, BI } },
++{ "bcctre",  XLLK(19,529,0),     XLYBB_MASK,  BOOKE64,	{ BO, BI } },
++{ "bcctrel", XLLK(19,529,1),     XLYBB_MASK,  BOOKE64,	{ BO, BI } },
++
++{ "rlwimi",  M(20,0),	M_MASK,		PPCCOM,		{ RA,RS,SH,MBE,ME } },
++{ "rlimi",   M(20,0),	M_MASK,		PWRCOM,		{ RA,RS,SH,MBE,ME } },
++
++{ "rlwimi.", M(20,1),	M_MASK,		PPCCOM,		{ RA,RS,SH,MBE,ME } },
++{ "rlimi.",  M(20,1),	M_MASK,		PWRCOM,		{ RA,RS,SH,MBE,ME } },
++
++{ "rotlwi",  MME(21,31,0), MMBME_MASK,	PPCCOM,		{ RA, RS, SH } },
++{ "clrlwi",  MME(21,31,0), MSHME_MASK,	PPCCOM,		{ RA, RS, MB } },
++{ "rlwinm",  M(21,0),	M_MASK,		PPCCOM,		{ RA,RS,SH,MBE,ME } },
++{ "rlinm",   M(21,0),	M_MASK,		PWRCOM,		{ RA,RS,SH,MBE,ME } },
++{ "rotlwi.", MME(21,31,1), MMBME_MASK,	PPCCOM,		{ RA,RS,SH } },
++{ "clrlwi.", MME(21,31,1), MSHME_MASK,	PPCCOM,		{ RA, RS, MB } },
++{ "rlwinm.", M(21,1),	M_MASK,		PPCCOM,		{ RA,RS,SH,MBE,ME } },
++{ "rlinm.",  M(21,1),	M_MASK,		PWRCOM,		{ RA,RS,SH,MBE,ME } },
++
++{ "rlmi",    M(22,0),	M_MASK,		M601,		{ RA,RS,RB,MBE,ME } },
++{ "rlmi.",   M(22,1),	M_MASK,		M601,		{ RA,RS,RB,MBE,ME } },
++
++{ "be",	     B(22,0,0),	B_MASK,		BOOKE64,	{ LI } },
++{ "bel",     B(22,0,1),	B_MASK,		BOOKE64,	{ LI } },
++{ "bea",     B(22,1,0),	B_MASK,		BOOKE64,	{ LIA } },
++{ "bela",    B(22,1,1),	B_MASK,		BOOKE64,	{ LIA } },
++
++{ "rotlw",   MME(23,31,0), MMBME_MASK,	PPCCOM,		{ RA, RS, RB } },
++{ "rlwnm",   M(23,0),	M_MASK,		PPCCOM,		{ RA,RS,RB,MBE,ME } },
++{ "rlnm",    M(23,0),	M_MASK,		PWRCOM,		{ RA,RS,RB,MBE,ME } },
++{ "rotlw.",  MME(23,31,1), MMBME_MASK,	PPCCOM,		{ RA, RS, RB } },
++{ "rlwnm.",  M(23,1),	M_MASK,		PPCCOM,		{ RA,RS,RB,MBE,ME } },
++{ "rlnm.",   M(23,1),	M_MASK,		PWRCOM,		{ RA,RS,RB,MBE,ME } },
++
++{ "nop",     OP(24),	0xffffffff,	PPCCOM,		{ 0 } },
++{ "ori",     OP(24),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
++{ "oril",    OP(24),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
++
++{ "oris",    OP(25),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
++{ "oriu",    OP(25),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
++
++{ "xori",    OP(26),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
++{ "xoril",   OP(26),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
++
++{ "xoris",   OP(27),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
++{ "xoriu",   OP(27),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
++
++{ "andi.",   OP(28),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
++{ "andil.",  OP(28),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
++
++{ "andis.",  OP(29),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
++{ "andiu.",  OP(29),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
++
++{ "rotldi",  MD(30,0,0), MDMB_MASK,	PPC64,		{ RA, RS, SH6 } },
++{ "clrldi",  MD(30,0,0), MDSH_MASK,	PPC64,		{ RA, RS, MB6 } },
++{ "rldicl",  MD(30,0,0), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
++{ "rotldi.", MD(30,0,1), MDMB_MASK,	PPC64,		{ RA, RS, SH6 } },
++{ "clrldi.", MD(30,0,1), MDSH_MASK,	PPC64,		{ RA, RS, MB6 } },
++{ "rldicl.", MD(30,0,1), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
++
++{ "rldicr",  MD(30,1,0), MD_MASK,	PPC64,		{ RA, RS, SH6, ME6 } },
++{ "rldicr.", MD(30,1,1), MD_MASK,	PPC64,		{ RA, RS, SH6, ME6 } },
++
++{ "rldic",   MD(30,2,0), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
++{ "rldic.",  MD(30,2,1), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
++
++{ "rldimi",  MD(30,3,0), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
++{ "rldimi.", MD(30,3,1), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
++
++{ "rotld",   MDS(30,8,0), MDSMB_MASK,	PPC64,		{ RA, RS, RB } },
++{ "rldcl",   MDS(30,8,0), MDS_MASK,	PPC64,		{ RA, RS, RB, MB6 } },
++{ "rotld.",  MDS(30,8,1), MDSMB_MASK,	PPC64,		{ RA, RS, RB } },
++{ "rldcl.",  MDS(30,8,1), MDS_MASK,	PPC64,		{ RA, RS, RB, MB6 } },
++
++{ "rldcr",   MDS(30,9,0), MDS_MASK,	PPC64,		{ RA, RS, RB, ME6 } },
++{ "rldcr.",  MDS(30,9,1), MDS_MASK,	PPC64,		{ RA, RS, RB, ME6 } },
++
++{ "cmpw",    XCMPL(31,0,0), XCMPL_MASK, PPCCOM,		{ OBF, RA, RB } },
++{ "cmpd",    XCMPL(31,0,1), XCMPL_MASK, PPC64,		{ OBF, RA, RB } },
++{ "cmp",     X(31,0),	XCMP_MASK,	PPC,		{ BF, L, RA, RB } },
++{ "cmp",     X(31,0),	XCMPL_MASK,	PWRCOM,		{ BF, RA, RB } },
++
++{ "twlgt",   XTO(31,4,TOLGT), XTO_MASK, PPCCOM,		{ RA, RB } },
++{ "tlgt",    XTO(31,4,TOLGT), XTO_MASK, PWRCOM,		{ RA, RB } },
++{ "twllt",   XTO(31,4,TOLLT), XTO_MASK, PPCCOM,		{ RA, RB } },
++{ "tllt",    XTO(31,4,TOLLT), XTO_MASK, PWRCOM,		{ RA, RB } },
++{ "tweq",    XTO(31,4,TOEQ), XTO_MASK,	PPCCOM,		{ RA, RB } },
++{ "teq",     XTO(31,4,TOEQ), XTO_MASK,	PWRCOM,		{ RA, RB } },
++{ "twlge",   XTO(31,4,TOLGE), XTO_MASK, PPCCOM,		{ RA, RB } },
++{ "tlge",    XTO(31,4,TOLGE), XTO_MASK, PWRCOM,		{ RA, RB } },
++{ "twlnl",   XTO(31,4,TOLNL), XTO_MASK, PPCCOM,		{ RA, RB } },
++{ "tlnl",    XTO(31,4,TOLNL), XTO_MASK, PWRCOM,		{ RA, RB } },
++{ "twlle",   XTO(31,4,TOLLE), XTO_MASK, PPCCOM,		{ RA, RB } },
++{ "tlle",    XTO(31,4,TOLLE), XTO_MASK, PWRCOM,		{ RA, RB } },
++{ "twlng",   XTO(31,4,TOLNG), XTO_MASK, PPCCOM,		{ RA, RB } },
++{ "tlng",    XTO(31,4,TOLNG), XTO_MASK, PWRCOM,		{ RA, RB } },
++{ "twgt",    XTO(31,4,TOGT), XTO_MASK,	PPCCOM,		{ RA, RB } },
++{ "tgt",     XTO(31,4,TOGT), XTO_MASK,	PWRCOM,		{ RA, RB } },
++{ "twge",    XTO(31,4,TOGE), XTO_MASK,	PPCCOM,		{ RA, RB } },
++{ "tge",     XTO(31,4,TOGE), XTO_MASK,	PWRCOM,		{ RA, RB } },
++{ "twnl",    XTO(31,4,TONL), XTO_MASK,	PPCCOM,		{ RA, RB } },
++{ "tnl",     XTO(31,4,TONL), XTO_MASK,	PWRCOM,		{ RA, RB } },
++{ "twlt",    XTO(31,4,TOLT), XTO_MASK,	PPCCOM,		{ RA, RB } },
++{ "tlt",     XTO(31,4,TOLT), XTO_MASK,	PWRCOM,		{ RA, RB } },
++{ "twle",    XTO(31,4,TOLE), XTO_MASK,	PPCCOM,		{ RA, RB } },
++{ "tle",     XTO(31,4,TOLE), XTO_MASK,	PWRCOM,		{ RA, RB } },
++{ "twng",    XTO(31,4,TONG), XTO_MASK,	PPCCOM,		{ RA, RB } },
++{ "tng",     XTO(31,4,TONG), XTO_MASK,	PWRCOM,		{ RA, RB } },
++{ "twne",    XTO(31,4,TONE), XTO_MASK,	PPCCOM,		{ RA, RB } },
++{ "tne",     XTO(31,4,TONE), XTO_MASK,	PWRCOM,		{ RA, RB } },
++{ "trap",    XTO(31,4,TOU), 0xffffffff,	PPCCOM,		{ 0 } },
++{ "tw",      X(31,4),	X_MASK,		PPCCOM,		{ TO, RA, RB } },
++{ "t",       X(31,4),	X_MASK,		PWRCOM,		{ TO, RA, RB } },
++
++{ "subfc",   XO(31,8,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "sf",      XO(31,8,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "subc",    XO(31,8,0,0), XO_MASK,	PPC,		{ RT, RB, RA } },
++{ "subfc.",  XO(31,8,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "sf.",     XO(31,8,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "subc.",   XO(31,8,0,1), XO_MASK,	PPCCOM,		{ RT, RB, RA } },
++{ "subfco",  XO(31,8,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "sfo",     XO(31,8,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "subco",   XO(31,8,1,0), XO_MASK,	PPC,		{ RT, RB, RA } },
++{ "subfco.", XO(31,8,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "sfo.",    XO(31,8,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "subco.",  XO(31,8,1,1), XO_MASK,	PPC,		{ RT, RB, RA } },
++
++{ "mulhdu",  XO(31,9,0,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "mulhdu.", XO(31,9,0,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
++
++{ "addc",    XO(31,10,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "a",       XO(31,10,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "addc.",   XO(31,10,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "a.",      XO(31,10,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "addco",   XO(31,10,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "ao",      XO(31,10,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "addco.",  XO(31,10,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "ao.",     XO(31,10,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++
++{ "mulhwu",  XO(31,11,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "mulhwu.", XO(31,11,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
++
++{ "isellt",  X(31,15),      X_MASK,	PPCISEL,	{ RT, RA, RB } },
++{ "iselgt",  X(31,47),      X_MASK,	PPCISEL,	{ RT, RA, RB } },
++{ "iseleq",  X(31,79),      X_MASK,	PPCISEL,	{ RT, RA, RB } },
++{ "isel",    XISEL(31,15),  XISEL_MASK,	PPCISEL,	{ RT, RA, RB, CRB } },
++
++{ "mfcr",    X(31,19),	XRARB_MASK,	NOPOWER4,	{ RT } },
++{ "mfcr",    X(31,19),	XFXFXM_MASK,	POWER4,		{ RT, FXM4 } },
++
++{ "lwarx",   X(31,20),	X_MASK,		PPC,		{ RT, RA, RB } },
++
++{ "ldx",     X(31,21),	X_MASK,		PPC64,		{ RT, RA, RB } },
++
++{ "icbt",    X(31,22),	X_MASK,		BOOKE,		{ CT, RA, RB } },
++{ "icbt",    X(31,262),	XRT_MASK,	PPC403,		{ RA, RB } },
++
++{ "lwzx",    X(31,23),	X_MASK,		PPCCOM,		{ RT, RA, RB } },
++{ "lx",      X(31,23),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
++
++{ "slw",     XRC(31,24,0), X_MASK,	PPCCOM,		{ RA, RS, RB } },
++{ "sl",      XRC(31,24,0), X_MASK,	PWRCOM,		{ RA, RS, RB } },
++{ "slw.",    XRC(31,24,1), X_MASK,	PPCCOM,		{ RA, RS, RB } },
++{ "sl.",     XRC(31,24,1), X_MASK,	PWRCOM,		{ RA, RS, RB } },
++
++{ "cntlzw",  XRC(31,26,0), XRB_MASK,	PPCCOM,		{ RA, RS } },
++{ "cntlz",   XRC(31,26,0), XRB_MASK,	PWRCOM,		{ RA, RS } },
++{ "cntlzw.", XRC(31,26,1), XRB_MASK,	PPCCOM,		{ RA, RS } },
++{ "cntlz.",  XRC(31,26,1), XRB_MASK, 	PWRCOM,		{ RA, RS } },
++
++{ "sld",     XRC(31,27,0), X_MASK,	PPC64,		{ RA, RS, RB } },
++{ "sld.",    XRC(31,27,1), X_MASK,	PPC64,		{ RA, RS, RB } },
++
++{ "and",     XRC(31,28,0), X_MASK,	COM,		{ RA, RS, RB } },
++{ "and.",    XRC(31,28,1), X_MASK,	COM,		{ RA, RS, RB } },
++
++{ "maskg",   XRC(31,29,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "maskg.",  XRC(31,29,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "icbte",   X(31,30),	X_MASK,		BOOKE64,	{ CT, RA, RB } },
++
++{ "lwzxe",   X(31,31),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
++
++{ "cmplw",   XCMPL(31,32,0), XCMPL_MASK, PPCCOM,	{ OBF, RA, RB } },
++{ "cmpld",   XCMPL(31,32,1), XCMPL_MASK, PPC64,		{ OBF, RA, RB } },
++{ "cmpl",    X(31,32),	XCMP_MASK,	 PPC,		{ BF, L, RA, RB } },
++{ "cmpl",    X(31,32),	XCMPL_MASK,	 PWRCOM,	{ BF, RA, RB } },
++
++{ "subf",    XO(31,40,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "sub",     XO(31,40,0,0), XO_MASK,	PPC,		{ RT, RB, RA } },
++{ "subf.",   XO(31,40,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "sub.",    XO(31,40,0,1), XO_MASK,	PPC,		{ RT, RB, RA } },
++{ "subfo",   XO(31,40,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "subo",    XO(31,40,1,0), XO_MASK,	PPC,		{ RT, RB, RA } },
++{ "subfo.",  XO(31,40,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "subo.",   XO(31,40,1,1), XO_MASK,	PPC,		{ RT, RB, RA } },
++
++{ "ldux",    X(31,53),	X_MASK,		PPC64,		{ RT, RAL, RB } },
++
++{ "dcbst",   X(31,54),	XRT_MASK,	PPC,		{ RA, RB } },
++
++{ "lwzux",   X(31,55),	X_MASK,		PPCCOM,		{ RT, RAL, RB } },
++{ "lux",     X(31,55),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
++
++{ "dcbste",  X(31,62),	XRT_MASK,	BOOKE64,	{ RA, RB } },
++
++{ "lwzuxe",  X(31,63),	X_MASK,		BOOKE64,	{ RT, RAL, RB } },
++
++{ "cntlzd",  XRC(31,58,0), XRB_MASK,	PPC64,		{ RA, RS } },
++{ "cntlzd.", XRC(31,58,1), XRB_MASK,	PPC64,		{ RA, RS } },
++
++{ "andc",    XRC(31,60,0), X_MASK,	COM,		{ RA, RS, RB } },
++{ "andc.",   XRC(31,60,1), X_MASK,	COM,		{ RA, RS, RB } },
++
++{ "tdlgt",   XTO(31,68,TOLGT), XTO_MASK, PPC64,		{ RA, RB } },
++{ "tdllt",   XTO(31,68,TOLLT), XTO_MASK, PPC64,		{ RA, RB } },
++{ "tdeq",    XTO(31,68,TOEQ), XTO_MASK,  PPC64,		{ RA, RB } },
++{ "tdlge",   XTO(31,68,TOLGE), XTO_MASK, PPC64,		{ RA, RB } },
++{ "tdlnl",   XTO(31,68,TOLNL), XTO_MASK, PPC64,		{ RA, RB } },
++{ "tdlle",   XTO(31,68,TOLLE), XTO_MASK, PPC64,		{ RA, RB } },
++{ "tdlng",   XTO(31,68,TOLNG), XTO_MASK, PPC64,		{ RA, RB } },
++{ "tdgt",    XTO(31,68,TOGT), XTO_MASK,  PPC64,		{ RA, RB } },
++{ "tdge",    XTO(31,68,TOGE), XTO_MASK,  PPC64,		{ RA, RB } },
++{ "tdnl",    XTO(31,68,TONL), XTO_MASK,  PPC64,		{ RA, RB } },
++{ "tdlt",    XTO(31,68,TOLT), XTO_MASK,  PPC64,		{ RA, RB } },
++{ "tdle",    XTO(31,68,TOLE), XTO_MASK,  PPC64,		{ RA, RB } },
++{ "tdng",    XTO(31,68,TONG), XTO_MASK,  PPC64,		{ RA, RB } },
++{ "tdne",    XTO(31,68,TONE), XTO_MASK,  PPC64,		{ RA, RB } },
++{ "td",	     X(31,68),	X_MASK,		 PPC64,		{ TO, RA, RB } },
++
++{ "mulhd",   XO(31,73,0,0), XO_MASK,	 PPC64,		{ RT, RA, RB } },
++{ "mulhd.",  XO(31,73,0,1), XO_MASK,	 PPC64,		{ RT, RA, RB } },
++
++{ "mulhw",   XO(31,75,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "mulhw.",  XO(31,75,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
++
++{ "dlmzb",   XRC(31,78,0),  X_MASK,	PPC403|PPC440,	{ RA, RS, RB } },
++{ "dlmzb.",  XRC(31,78,1),  X_MASK,	PPC403|PPC440,	{ RA, RS, RB } },
++
++{ "mtsrd",   X(31,82),	XRB_MASK|(1<<20), PPC64,	{ SR, RS } },
++
++{ "mfmsr",   X(31,83),	XRARB_MASK,	COM,		{ RT } },
++
++{ "ldarx",   X(31,84),	X_MASK,		PPC64,		{ RT, RA, RB } },
++
++{ "dcbf",    X(31,86),	XRT_MASK,	PPC,		{ RA, RB } },
++
++{ "lbzx",    X(31,87),	X_MASK,		COM,		{ RT, RA, RB } },
++
++{ "dcbfe",   X(31,94),	XRT_MASK,	BOOKE64,	{ RA, RB } },
++
++{ "lbzxe",   X(31,95),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
++
++{ "neg",     XO(31,104,0,0), XORB_MASK,	COM,		{ RT, RA } },
++{ "neg.",    XO(31,104,0,1), XORB_MASK,	COM,		{ RT, RA } },
++{ "nego",    XO(31,104,1,0), XORB_MASK,	COM,		{ RT, RA } },
++{ "nego.",   XO(31,104,1,1), XORB_MASK,	COM,		{ RT, RA } },
++
++{ "mul",     XO(31,107,0,0), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "mul.",    XO(31,107,0,1), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "mulo",    XO(31,107,1,0), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "mulo.",   XO(31,107,1,1), XO_MASK,	M601,		{ RT, RA, RB } },
++
++{ "mtsrdin", X(31,114),	XRA_MASK,	PPC64,		{ RS, RB } },
++
++{ "clf",     X(31,118), XTO_MASK,	POWER,		{ RA, RB } },
++
++{ "lbzux",   X(31,119),	X_MASK,		COM,		{ RT, RAL, RB } },
++
++{ "not",     XRC(31,124,0), X_MASK,	COM,		{ RA, RS, RBS } },
++{ "nor",     XRC(31,124,0), X_MASK,	COM,		{ RA, RS, RB } },
++{ "not.",    XRC(31,124,1), X_MASK,	COM,		{ RA, RS, RBS } },
++{ "nor.",    XRC(31,124,1), X_MASK,	COM,		{ RA, RS, RB } },
++
++{ "lwarxe",  X(31,126),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
++
++{ "lbzuxe",  X(31,127),	X_MASK,		BOOKE64,	{ RT, RAL, RB } },
++
++{ "wrtee",   X(31,131),	XRARB_MASK,	PPC403 | BOOKE,	{ RS } },
++
++{ "dcbtstls",X(31,134),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
++
++{ "subfe",   XO(31,136,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "sfe",     XO(31,136,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "subfe.",  XO(31,136,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "sfe.",    XO(31,136,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "subfeo",  XO(31,136,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "sfeo",    XO(31,136,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "subfeo.", XO(31,136,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "sfeo.",   XO(31,136,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++
++{ "adde",    XO(31,138,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "ae",      XO(31,138,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "adde.",   XO(31,138,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "ae.",     XO(31,138,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "addeo",   XO(31,138,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "aeo",     XO(31,138,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "addeo.",  XO(31,138,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "aeo.",    XO(31,138,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++
++{ "dcbtstlse",X(31,142),X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
++
++{ "mtcr",    XFXM(31,144,0xff), XRARB_MASK, COM,	{ RS }},
++{ "mtcrf",   X(31,144),	XFXFXM_MASK,	COM,		{ FXM, RS } },
++
++{ "mtmsr",   X(31,146),	XRARB_MASK,	COM,		{ RS } },
++
++{ "stdx",    X(31,149), X_MASK,		PPC64,		{ RS, RA, RB } },
++
++{ "stwcx.",  XRC(31,150,1), X_MASK,	PPC,		{ RS, RA, RB } },
++
++{ "stwx",    X(31,151), X_MASK,		PPCCOM,		{ RS, RA, RB } },
++{ "stx",     X(31,151), X_MASK,		PWRCOM,		{ RS, RA, RB } },
++
++{ "stwcxe.", XRC(31,158,1), X_MASK,	BOOKE64,	{ RS, RA, RB } },
++
++{ "stwxe",   X(31,159), X_MASK,		BOOKE64,	{ RS, RA, RB } },
++
++{ "slq",     XRC(31,152,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "slq.",    XRC(31,152,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "sle",     XRC(31,153,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "sle.",    XRC(31,153,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "wrteei",  X(31,163),	XE_MASK,	PPC403 | BOOKE,	{ E } },
++
++{ "dcbtls",  X(31,166),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
++{ "dcbtlse", X(31,174),	X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
++
++{ "mtmsrd",  X(31,178),	XRLARB_MASK,	PPC64,		{ RS, MTMSRD_L } },
++
++{ "stdux",   X(31,181),	X_MASK,		PPC64,		{ RS, RAS, RB } },
++
++{ "stwux",   X(31,183),	X_MASK,		PPCCOM,		{ RS, RAS, RB } },
++{ "stux",    X(31,183),	X_MASK,		PWRCOM,		{ RS, RA, RB } },
++
++{ "sliq",    XRC(31,184,0), X_MASK,	M601,		{ RA, RS, SH } },
++{ "sliq.",   XRC(31,184,1), X_MASK,	M601,		{ RA, RS, SH } },
++
++{ "stwuxe",  X(31,191),	X_MASK,		BOOKE64,	{ RS, RAS, RB } },
++
++{ "subfze",  XO(31,200,0,0), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "sfze",    XO(31,200,0,0), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "subfze.", XO(31,200,0,1), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "sfze.",   XO(31,200,0,1), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "subfzeo", XO(31,200,1,0), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "sfzeo",   XO(31,200,1,0), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "subfzeo.",XO(31,200,1,1), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "sfzeo.",  XO(31,200,1,1), XORB_MASK, PWRCOM,		{ RT, RA } },
++
++{ "addze",   XO(31,202,0,0), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "aze",     XO(31,202,0,0), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "addze.",  XO(31,202,0,1), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "aze.",    XO(31,202,0,1), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "addzeo",  XO(31,202,1,0), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "azeo",    XO(31,202,1,0), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "addzeo.", XO(31,202,1,1), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "azeo.",   XO(31,202,1,1), XORB_MASK, PWRCOM,		{ RT, RA } },
++
++{ "mtsr",    X(31,210),	XRB_MASK|(1<<20), COM32,	{ SR, RS } },
++
++{ "stdcx.",  XRC(31,214,1), X_MASK,	PPC64,		{ RS, RA, RB } },
++
++{ "stbx",    X(31,215),	X_MASK,		COM,		{ RS, RA, RB } },
++
++{ "sllq",    XRC(31,216,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "sllq.",   XRC(31,216,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "sleq",    XRC(31,217,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "sleq.",   XRC(31,217,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "stbxe",   X(31,223),	X_MASK,		BOOKE64,	{ RS, RA, RB } },
++
++{ "icblc",   X(31,230),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
++
++{ "subfme",  XO(31,232,0,0), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "sfme",    XO(31,232,0,0), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "subfme.", XO(31,232,0,1), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "sfme.",   XO(31,232,0,1), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "subfmeo", XO(31,232,1,0), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "sfmeo",   XO(31,232,1,0), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "subfmeo.",XO(31,232,1,1), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "sfmeo.",  XO(31,232,1,1), XORB_MASK, PWRCOM,		{ RT, RA } },
++
++{ "mulld",   XO(31,233,0,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "mulld.",  XO(31,233,0,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "mulldo",  XO(31,233,1,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "mulldo.", XO(31,233,1,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
++
++{ "addme",   XO(31,234,0,0), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "ame",     XO(31,234,0,0), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "addme.",  XO(31,234,0,1), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "ame.",    XO(31,234,0,1), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "addmeo",  XO(31,234,1,0), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "ameo",    XO(31,234,1,0), XORB_MASK, PWRCOM,		{ RT, RA } },
++{ "addmeo.", XO(31,234,1,1), XORB_MASK, PPCCOM,		{ RT, RA } },
++{ "ameo.",   XO(31,234,1,1), XORB_MASK, PWRCOM,		{ RT, RA } },
++
++{ "mullw",   XO(31,235,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "muls",    XO(31,235,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "mullw.",  XO(31,235,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "muls.",   XO(31,235,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "mullwo",  XO(31,235,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "mulso",   XO(31,235,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "mullwo.", XO(31,235,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "mulso.",  XO(31,235,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++
++{ "icblce",  X(31,238),	X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
++{ "mtsrin",  X(31,242),	XRA_MASK,	PPC32,		{ RS, RB } },
++{ "mtsri",   X(31,242),	XRA_MASK,	POWER32,	{ RS, RB } },
++
++{ "dcbtst",  X(31,246),	XRT_MASK,	PPC,		{ CT, RA, RB } },
++
++{ "stbux",   X(31,247),	X_MASK,		COM,		{ RS, RAS, RB } },
++
++{ "slliq",   XRC(31,248,0), X_MASK,	M601,		{ RA, RS, SH } },
++{ "slliq.",  XRC(31,248,1), X_MASK,	M601,		{ RA, RS, SH } },
++
++{ "dcbtste", X(31,253),	X_MASK,		BOOKE64,	{ CT, RA, RB } },
++
++{ "stbuxe",  X(31,255),	X_MASK,		BOOKE64,	{ RS, RAS, RB } },
++
++{ "mfdcrx",  X(31,259),	X_MASK,		BOOKE,		{ RS, RA } },
++
++{ "doz",     XO(31,264,0,0), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "doz.",    XO(31,264,0,1), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "dozo",    XO(31,264,1,0), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "dozo.",   XO(31,264,1,1), XO_MASK,	M601,		{ RT, RA, RB } },
++
++{ "add",     XO(31,266,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "cax",     XO(31,266,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "add.",    XO(31,266,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "cax.",    XO(31,266,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "addo",    XO(31,266,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "caxo",    XO(31,266,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++{ "addo.",   XO(31,266,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
++{ "caxo.",   XO(31,266,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
++
++{ "tlbiel",  X(31,274), XRTRA_MASK,	POWER4,		{ RB } },
++
++{ "mfapidi", X(31,275), X_MASK,		BOOKE,		{ RT, RA } },
++
++{ "lscbx",   XRC(31,277,0), X_MASK,	M601,		{ RT, RA, RB } },
++{ "lscbx.",  XRC(31,277,1), X_MASK,	M601,		{ RT, RA, RB } },
++
++{ "dcbt",    X(31,278),	XRT_MASK,	PPC,		{ CT, RA, RB } },
++
++{ "lhzx",    X(31,279),	X_MASK,		COM,		{ RT, RA, RB } },
++
++{ "eqv",     XRC(31,284,0), X_MASK,	COM,		{ RA, RS, RB } },
++{ "eqv.",    XRC(31,284,1), X_MASK,	COM,		{ RA, RS, RB } },
++
++{ "dcbte",   X(31,286),	X_MASK,		BOOKE64,	{ CT, RA, RB } },
++
++{ "lhzxe",   X(31,287),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
++
++{ "tlbie",   X(31,306),	XRTLRA_MASK,	PPC,		{ RB, L } },
++{ "tlbi",    X(31,306),	XRT_MASK,	POWER,		{ RA, RB } },
++
++{ "eciwx",   X(31,310), X_MASK,		PPC,		{ RT, RA, RB } },
++
++{ "lhzux",   X(31,311),	X_MASK,		COM,		{ RT, RAL, RB } },
++
++{ "xor",     XRC(31,316,0), X_MASK,	COM,		{ RA, RS, RB } },
++{ "xor.",    XRC(31,316,1), X_MASK,	COM,		{ RA, RS, RB } },
++
++{ "lhzuxe",  X(31,319),	X_MASK,		BOOKE64,	{ RT, RAL, RB } },
++
++{ "mfexisr",  XSPR(31,323,64),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfexier",  XSPR(31,323,66),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfbr0",    XSPR(31,323,128), XSPR_MASK, PPC403,	{ RT } },
++{ "mfbr1",    XSPR(31,323,129), XSPR_MASK, PPC403,	{ RT } },
++{ "mfbr2",    XSPR(31,323,130), XSPR_MASK, PPC403,	{ RT } },
++{ "mfbr3",    XSPR(31,323,131), XSPR_MASK, PPC403,	{ RT } },
++{ "mfbr4",    XSPR(31,323,132), XSPR_MASK, PPC403,	{ RT } },
++{ "mfbr5",    XSPR(31,323,133), XSPR_MASK, PPC403,	{ RT } },
++{ "mfbr6",    XSPR(31,323,134), XSPR_MASK, PPC403,	{ RT } },
++{ "mfbr7",    XSPR(31,323,135), XSPR_MASK, PPC403,	{ RT } },
++{ "mfbear",   XSPR(31,323,144), XSPR_MASK, PPC403,	{ RT } },
++{ "mfbesr",   XSPR(31,323,145), XSPR_MASK, PPC403,	{ RT } },
++{ "mfiocr",   XSPR(31,323,160), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmacr0", XSPR(31,323,192), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmact0", XSPR(31,323,193), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmada0", XSPR(31,323,194), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmasa0", XSPR(31,323,195), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmacc0", XSPR(31,323,196), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmacr1", XSPR(31,323,200), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmact1", XSPR(31,323,201), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmada1", XSPR(31,323,202), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmasa1", XSPR(31,323,203), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmacc1", XSPR(31,323,204), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmacr2", XSPR(31,323,208), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmact2", XSPR(31,323,209), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmada2", XSPR(31,323,210), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmasa2", XSPR(31,323,211), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmacc2", XSPR(31,323,212), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmacr3", XSPR(31,323,216), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmact3", XSPR(31,323,217), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmada3", XSPR(31,323,218), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmasa3", XSPR(31,323,219), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmacc3", XSPR(31,323,220), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdmasr",  XSPR(31,323,224), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdcr",    X(31,323),	X_MASK,	PPC403 | BOOKE,	{ RT, SPR } },
++
++{ "div",     XO(31,331,0,0), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "div.",    XO(31,331,0,1), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "divo",    XO(31,331,1,0), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "divo.",   XO(31,331,1,1), XO_MASK,	M601,		{ RT, RA, RB } },
++
++{ "mfpmr",   X(31,334),	X_MASK,		PPCPMR,		{ RT, PMR }},
++
++{ "mfmq",       XSPR(31,339,0),    XSPR_MASK, M601,	{ RT } },
++{ "mfxer",      XSPR(31,339,1),    XSPR_MASK, COM,	{ RT } },
++{ "mfrtcu",     XSPR(31,339,4),    XSPR_MASK, COM,	{ RT } },
++{ "mfrtcl",     XSPR(31,339,5),    XSPR_MASK, COM,	{ RT } },
++{ "mfdec",      XSPR(31,339,6),    XSPR_MASK, MFDEC1,	{ RT } },
++{ "mfdec",      XSPR(31,339,22),   XSPR_MASK, MFDEC2,	{ RT } },
++{ "mflr",       XSPR(31,339,8),    XSPR_MASK, COM,	{ RT } },
++{ "mfctr",      XSPR(31,339,9),    XSPR_MASK, COM,	{ RT } },
++{ "mftid",      XSPR(31,339,17),   XSPR_MASK, POWER,	{ RT } },
++{ "mfdsisr",    XSPR(31,339,18),   XSPR_MASK, COM,	{ RT } },
++{ "mfdar",      XSPR(31,339,19),   XSPR_MASK, COM,	{ RT } },
++{ "mfsdr0",     XSPR(31,339,24),   XSPR_MASK, POWER,	{ RT } },
++{ "mfsdr1",     XSPR(31,339,25),   XSPR_MASK, COM,	{ RT } },
++{ "mfsrr0",     XSPR(31,339,26),   XSPR_MASK, COM,	{ RT } },
++{ "mfsrr1",     XSPR(31,339,27),   XSPR_MASK, COM,	{ RT } },
++{ "mfpid",      XSPR(31,339,48),   XSPR_MASK, BOOKE,    { RT } },
++{ "mfpid",      XSPR(31,339,945),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfcsrr0",    XSPR(31,339,58),   XSPR_MASK, BOOKE,    { RT } },
++{ "mfcsrr1",    XSPR(31,339,59),   XSPR_MASK, BOOKE,    { RT } },
++{ "mfdear",     XSPR(31,339,61),   XSPR_MASK, BOOKE,    { RT } },
++{ "mfdear",     XSPR(31,339,981),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfesr",      XSPR(31,339,62),   XSPR_MASK, BOOKE,    { RT } },
++{ "mfesr",      XSPR(31,339,980),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfivpr",     XSPR(31,339,63),   XSPR_MASK, BOOKE,    { RT } },
++{ "mfcmpa",     XSPR(31,339,144),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfcmpb",     XSPR(31,339,145),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfcmpc",     XSPR(31,339,146),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfcmpd",     XSPR(31,339,147),  XSPR_MASK, PPC860,	{ RT } },
++{ "mficr",      XSPR(31,339,148),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfder",      XSPR(31,339,149),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfcounta",   XSPR(31,339,150),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfcountb",   XSPR(31,339,151),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfcmpe",     XSPR(31,339,152),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfcmpf",     XSPR(31,339,153),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfcmpg",     XSPR(31,339,154),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfcmph",     XSPR(31,339,155),  XSPR_MASK, PPC860,	{ RT } },
++{ "mflctrl1",   XSPR(31,339,156),  XSPR_MASK, PPC860,	{ RT } },
++{ "mflctrl2",   XSPR(31,339,157),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfictrl",    XSPR(31,339,158),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,	{ RT } },
++{ "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,	{ RT } },
++{ "mftb",       X(31,371),	   X_MASK,    CLASSIC,	{ RT, TBR } },
++{ "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
++{ "mftbl",      XSPR(31,371,268),  XSPR_MASK, CLASSIC,	{ RT } },
++{ "mftbl",      XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
++{ "mftbu",      XSPR(31,371,269),  XSPR_MASK, CLASSIC,	{ RT } },
++{ "mftbu",      XSPR(31,339,269),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfsprg",     XSPR(31,339,272),  XSPRG_MASK, PPC,	{ RT, SPRG } },
++{ "mfsprg0",    XSPR(31,339,272),  XSPR_MASK, PPC,	{ RT } },
++{ "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,	{ RT } },
++{ "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,	{ RT } },
++{ "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,	{ RT } },
++{ "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,	{ RT } },
++{ "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,	{ RT } },
++{ "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfpvr",      XSPR(31,339,287),  XSPR_MASK, PPC,	{ RT } },
++{ "mfdbsr",     XSPR(31,339,304),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfdbsr",     XSPR(31,339,1008), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdbcr0",    XSPR(31,339,308),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfdbcr0",    XSPR(31,339,1010), XSPR_MASK, PPC405,	{ RT } },
++{ "mfdbcr1",    XSPR(31,339,309),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfdbcr1",    XSPR(31,339,957),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfdbcr2",    XSPR(31,339,310),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfiac1",     XSPR(31,339,312),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfiac1",     XSPR(31,339,1012), XSPR_MASK, PPC403,	{ RT } },
++{ "mfiac2",     XSPR(31,339,313),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfiac2",     XSPR(31,339,1013), XSPR_MASK, PPC403,	{ RT } },
++{ "mfiac3",     XSPR(31,339,314),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfiac3",     XSPR(31,339,948),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfiac4",     XSPR(31,339,315),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfiac4",     XSPR(31,339,949),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfdac1",     XSPR(31,339,316),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfdac1",     XSPR(31,339,1014), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdac2",     XSPR(31,339,317),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfdac2",     XSPR(31,339,1015), XSPR_MASK, PPC403,	{ RT } },
++{ "mfdvc1",     XSPR(31,339,318),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfdvc1",     XSPR(31,339,950),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfdvc2",     XSPR(31,339,319),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfdvc2",     XSPR(31,339,951),  XSPR_MASK, PPC405,	{ RT } },
++{ "mftsr",      XSPR(31,339,336),  XSPR_MASK, BOOKE,    { RT } },
++{ "mftsr",      XSPR(31,339,984),  XSPR_MASK, PPC403,	{ RT } },
++{ "mftcr",      XSPR(31,339,340),  XSPR_MASK, BOOKE,    { RT } },
++{ "mftcr",      XSPR(31,339,986),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfivor0",    XSPR(31,339,400),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor1",    XSPR(31,339,401),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor2",    XSPR(31,339,402),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor3",    XSPR(31,339,403),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor4",    XSPR(31,339,404),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor5",    XSPR(31,339,405),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor6",    XSPR(31,339,406),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor7",    XSPR(31,339,407),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor8",    XSPR(31,339,408),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor9",    XSPR(31,339,409),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor10",   XSPR(31,339,410),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor11",   XSPR(31,339,411),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor12",   XSPR(31,339,412),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor13",   XSPR(31,339,413),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor14",   XSPR(31,339,414),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfivor15",   XSPR(31,339,415),  XSPR_MASK, BOOKE,    { RT } },
++{ "mfspefscr",  XSPR(31,339,512),  XSPR_MASK, PPCSPE,	{ RT } },
++{ "mfbbear",    XSPR(31,339,513),  XSPR_MASK, PPCBRLK,  { RT } },
++{ "mfbbtar",    XSPR(31,339,514),  XSPR_MASK, PPCBRLK,  { RT } },
++{ "mfibatu",    XSPR(31,339,528),  XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
++{ "mfibatl",    XSPR(31,339,529),  XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
++{ "mfdbatu",    XSPR(31,339,536),  XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
++{ "mfdbatl",    XSPR(31,339,537),  XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
++{ "mfic_cst",   XSPR(31,339,560),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfic_adr",   XSPR(31,339,561),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfic_dat",   XSPR(31,339,562),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfdc_cst",   XSPR(31,339,568),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfdc_adr",   XSPR(31,339,569),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfdc_dat",   XSPR(31,339,570),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmcsrr0",   XSPR(31,339,570),  XSPR_MASK, PPCRFMCI, { RT } },
++{ "mfmcsrr1",   XSPR(31,339,571),  XSPR_MASK, PPCRFMCI, { RT } },
++{ "mfmcsr",     XSPR(31,339,572),  XSPR_MASK, PPCRFMCI, { RT } },
++{ "mfdpdr",     XSPR(31,339,630),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfdpir",     XSPR(31,339,631),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfimmr",     XSPR(31,339,638),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmi_ctr",   XSPR(31,339,784),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmi_ap",    XSPR(31,339,786),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmi_epn",   XSPR(31,339,787),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmi_twc",   XSPR(31,339,789),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmi_rpn",   XSPR(31,339,790),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmd_ctr",   XSPR(31,339,792),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfm_casid",  XSPR(31,339,793),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmd_ap",    XSPR(31,339,794),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmd_epn",   XSPR(31,339,795),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmd_twb",   XSPR(31,339,796),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmd_twc",   XSPR(31,339,797),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmd_rpn",   XSPR(31,339,798),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfm_tw",     XSPR(31,339,799),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmi_dbcam", XSPR(31,339,816),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmi_dbram0",XSPR(31,339,817),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmi_dbram1",XSPR(31,339,818),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmd_dbcam", XSPR(31,339,824),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmd_dbram0",XSPR(31,339,825),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfmd_dbram1",XSPR(31,339,826),  XSPR_MASK, PPC860,	{ RT } },
++{ "mfummcr0",   XSPR(31,339,936),  XSPR_MASK, PPC750,   { RT } },
++{ "mfupmc1",    XSPR(31,339,937),  XSPR_MASK, PPC750,   { RT } },
++{ "mfupmc2",    XSPR(31,339,938),  XSPR_MASK, PPC750,   { RT } },
++{ "mfusia",     XSPR(31,339,939),  XSPR_MASK, PPC750,   { RT } },
++{ "mfummcr1",   XSPR(31,339,940),  XSPR_MASK, PPC750,   { RT } },
++{ "mfupmc3",    XSPR(31,339,941),  XSPR_MASK, PPC750,   { RT } },
++{ "mfupmc4",    XSPR(31,339,942),  XSPR_MASK, PPC750,   { RT } },
++{ "mfzpr",   	XSPR(31,339,944),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfccr0",  	XSPR(31,339,947),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfmmcr0",	XSPR(31,339,952),  XSPR_MASK, PPC750,	{ RT } },
++{ "mfpmc1",	XSPR(31,339,953),  XSPR_MASK, PPC750,	{ RT } },
++{ "mfsgr",	XSPR(31,339,953),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfpmc2",	XSPR(31,339,954),  XSPR_MASK, PPC750,	{ RT } },
++{ "mfdcwr", 	XSPR(31,339,954),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfsia",	XSPR(31,339,955),  XSPR_MASK, PPC750,	{ RT } },
++{ "mfsler",	XSPR(31,339,955),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfmmcr1",	XSPR(31,339,956),  XSPR_MASK, PPC750,	{ RT } },
++{ "mfsu0r",	XSPR(31,339,956),  XSPR_MASK, PPC405,	{ RT } },
++{ "mfpmc3",	XSPR(31,339,957),  XSPR_MASK, PPC750,	{ RT } },
++{ "mfpmc4",	XSPR(31,339,958),  XSPR_MASK, PPC750,	{ RT } },
++{ "mficdbdr",   XSPR(31,339,979),  XSPR_MASK, PPC403,   { RT } },
++{ "mfevpr",     XSPR(31,339,982),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfcdbcr",    XSPR(31,339,983),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfpit",      XSPR(31,339,987),  XSPR_MASK, PPC403,	{ RT } },
++{ "mftbhi",     XSPR(31,339,988),  XSPR_MASK, PPC403,	{ RT } },
++{ "mftblo",     XSPR(31,339,989),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfsrr2",     XSPR(31,339,990),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfsrr3",     XSPR(31,339,991),  XSPR_MASK, PPC403,	{ RT } },
++{ "mfl2cr",     XSPR(31,339,1017), XSPR_MASK, PPC750,   { RT } },
++{ "mfdccr",     XSPR(31,339,1018), XSPR_MASK, PPC403,	{ RT } },
++{ "mficcr",     XSPR(31,339,1019), XSPR_MASK, PPC403,	{ RT } },
++{ "mfictc",     XSPR(31,339,1019), XSPR_MASK, PPC750,   { RT } },
++{ "mfpbl1",     XSPR(31,339,1020), XSPR_MASK, PPC403,	{ RT } },
++{ "mfthrm1",    XSPR(31,339,1020), XSPR_MASK, PPC750,   { RT } },
++{ "mfpbu1",     XSPR(31,339,1021), XSPR_MASK, PPC403,	{ RT } },
++{ "mfthrm2",    XSPR(31,339,1021), XSPR_MASK, PPC750,   { RT } },
++{ "mfpbl2",     XSPR(31,339,1022), XSPR_MASK, PPC403,	{ RT } },
++{ "mfthrm3",    XSPR(31,339,1022), XSPR_MASK, PPC750,   { RT } },
++{ "mfpbu2",     XSPR(31,339,1023), XSPR_MASK, PPC403,	{ RT } },
++{ "mfspr",      X(31,339),	   X_MASK,    COM,	{ RT, SPR } },
++
++{ "lwax",    X(31,341),	X_MASK,		PPC64,		{ RT, RA, RB } },
++
++{ "dst",     XDSS(31,342,0), XDSS_MASK,	PPCVEC,		{ RA, RB, STRM } },
++{ "dstt",    XDSS(31,342,1), XDSS_MASK,	PPCVEC,		{ RA, RB, STRM } },
++
++{ "lhax",    X(31,343),	X_MASK,		COM,		{ RT, RA, RB } },
++
++{ "lhaxe",   X(31,351),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
++
++{ "dstst",   XDSS(31,374,0), XDSS_MASK,	PPCVEC,		{ RA, RB, STRM } },
++{ "dststt",  XDSS(31,374,1), XDSS_MASK,	PPCVEC,		{ RA, RB, STRM } },
++
++{ "dccci",   X(31,454),	XRT_MASK,	PPC403|PPC440,	{ RA, RB } },
++
++{ "abs",     XO(31,360,0,0), XORB_MASK, M601,		{ RT, RA } },
++{ "abs.",    XO(31,360,0,1), XORB_MASK, M601,		{ RT, RA } },
++{ "abso",    XO(31,360,1,0), XORB_MASK, M601,		{ RT, RA } },
++{ "abso.",   XO(31,360,1,1), XORB_MASK, M601,		{ RT, RA } },
++
++{ "divs",    XO(31,363,0,0), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "divs.",   XO(31,363,0,1), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "divso",   XO(31,363,1,0), XO_MASK,	M601,		{ RT, RA, RB } },
++{ "divso.",  XO(31,363,1,1), XO_MASK,	M601,		{ RT, RA, RB } },
++
++{ "tlbia",   X(31,370),	0xffffffff,	PPC,		{ 0 } },
++
++{ "lwaux",   X(31,373),	X_MASK,		PPC64,		{ RT, RAL, RB } },
++
++{ "lhaux",   X(31,375),	X_MASK,		COM,		{ RT, RAL, RB } },
++
++{ "lhauxe",  X(31,383),	X_MASK,		BOOKE64,	{ RT, RAL, RB } },
++
++{ "mtdcrx",  X(31,387),	X_MASK,		BOOKE,		{ RA, RS } },
++
++{ "dcblc",   X(31,390),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
++
++{ "subfe64", XO(31,392,0,0), XO_MASK,	BOOKE64,	{ RT, RA, RB } },
++{ "subfe64o",XO(31,392,1,0), XO_MASK,	BOOKE64,	{ RT, RA, RB } },
++
++{ "adde64",  XO(31,394,0,0), XO_MASK,	BOOKE64,	{ RT, RA, RB } },
++{ "adde64o", XO(31,394,1,0), XO_MASK,	BOOKE64,	{ RT, RA, RB } },
++
++{ "dcblce",  X(31,398),	X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
++
++{ "slbmte",  X(31,402), XRA_MASK,	PPC64,		{ RS, RB } },
++
++{ "sthx",    X(31,407),	X_MASK,		COM,		{ RS, RA, RB } },
++
++{ "lfqx",    X(31,791),	X_MASK,		POWER2,		{ FRT, RA, RB } },
++
++{ "lfqux",   X(31,823),	X_MASK,		POWER2,		{ FRT, RA, RB } },
++
++{ "stfqx",   X(31,919),	X_MASK,		POWER2,		{ FRS, RA, RB } },
++
++{ "stfqux",  X(31,951),	X_MASK,		POWER2,		{ FRS, RA, RB } },
++
++{ "orc",     XRC(31,412,0), X_MASK,	COM,		{ RA, RS, RB } },
++{ "orc.",    XRC(31,412,1), X_MASK,	COM,		{ RA, RS, RB } },
++
++{ "sradi",   XS(31,413,0), XS_MASK,	PPC64,		{ RA, RS, SH6 } },
++{ "sradi.",  XS(31,413,1), XS_MASK,	PPC64,		{ RA, RS, SH6 } },
++
++{ "sthxe",   X(31,415),	X_MASK,		BOOKE64,	{ RS, RA, RB } },
++
++{ "slbie",   X(31,434),	XRTRA_MASK,	PPC64,		{ RB } },
++
++{ "ecowx",   X(31,438),	X_MASK,		PPC,		{ RT, RA, RB } },
++
++{ "sthux",   X(31,439),	X_MASK,		COM,		{ RS, RAS, RB } },
++
++{ "sthuxe",  X(31,447),	X_MASK,		BOOKE64,	{ RS, RAS, RB } },
++
++{ "mr",	     XRC(31,444,0), X_MASK,	COM,		{ RA, RS, RBS } },
++{ "or",      XRC(31,444,0), X_MASK,	COM,		{ RA, RS, RB } },
++{ "mr.",     XRC(31,444,1), X_MASK,	COM,		{ RA, RS, RBS } },
++{ "or.",     XRC(31,444,1), X_MASK,	COM,		{ RA, RS, RB } },
++
++{ "mtexisr",  XSPR(31,451,64),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtexier",  XSPR(31,451,66),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtbr0",    XSPR(31,451,128), XSPR_MASK, PPC403,	{ RS } },
++{ "mtbr1",    XSPR(31,451,129), XSPR_MASK, PPC403,	{ RS } },
++{ "mtbr2",    XSPR(31,451,130), XSPR_MASK, PPC403,	{ RS } },
++{ "mtbr3",    XSPR(31,451,131), XSPR_MASK, PPC403,	{ RS } },
++{ "mtbr4",    XSPR(31,451,132), XSPR_MASK, PPC403,	{ RS } },
++{ "mtbr5",    XSPR(31,451,133), XSPR_MASK, PPC403,	{ RS } },
++{ "mtbr6",    XSPR(31,451,134), XSPR_MASK, PPC403,	{ RS } },
++{ "mtbr7",    XSPR(31,451,135), XSPR_MASK, PPC403,	{ RS } },
++{ "mtbear",   XSPR(31,451,144), XSPR_MASK, PPC403,	{ RS } },
++{ "mtbesr",   XSPR(31,451,145), XSPR_MASK, PPC403,	{ RS } },
++{ "mtiocr",   XSPR(31,451,160), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmacr0", XSPR(31,451,192), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmact0", XSPR(31,451,193), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmada0", XSPR(31,451,194), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmasa0", XSPR(31,451,195), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmacc0", XSPR(31,451,196), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmacr1", XSPR(31,451,200), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmact1", XSPR(31,451,201), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmada1", XSPR(31,451,202), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmasa1", XSPR(31,451,203), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmacc1", XSPR(31,451,204), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmacr2", XSPR(31,451,208), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmact2", XSPR(31,451,209), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmada2", XSPR(31,451,210), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmasa2", XSPR(31,451,211), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmacc2", XSPR(31,451,212), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmacr3", XSPR(31,451,216), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmact3", XSPR(31,451,217), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmada3", XSPR(31,451,218), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmasa3", XSPR(31,451,219), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmacc3", XSPR(31,451,220), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdmasr",  XSPR(31,451,224), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdcr",    X(31,451),	X_MASK,	PPC403 | BOOKE,	{ SPR, RS } },
++
++{ "subfze64",XO(31,456,0,0), XORB_MASK, BOOKE64,	{ RT, RA } },
++{ "subfze64o",XO(31,456,1,0), XORB_MASK, BOOKE64,	{ RT, RA } },
++
++{ "divdu",   XO(31,457,0,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "divdu.",  XO(31,457,0,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "divduo",  XO(31,457,1,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "divduo.", XO(31,457,1,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
++
++{ "addze64", XO(31,458,0,0), XORB_MASK, BOOKE64,	{ RT, RA } },
++{ "addze64o",XO(31,458,1,0), XORB_MASK, BOOKE64,	{ RT, RA } },
++
++{ "divwu",   XO(31,459,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "divwu.",  XO(31,459,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "divwuo",  XO(31,459,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "divwuo.", XO(31,459,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
++
++{ "mtmq",      XSPR(31,467,0),    XSPR_MASK, M601,	{ RS } },
++{ "mtxer",     XSPR(31,467,1),    XSPR_MASK, COM,	{ RS } },
++{ "mtlr",      XSPR(31,467,8),    XSPR_MASK, COM,	{ RS } },
++{ "mtctr",     XSPR(31,467,9),    XSPR_MASK, COM,	{ RS } },
++{ "mttid",     XSPR(31,467,17),   XSPR_MASK, POWER,	{ RS } },
++{ "mtdsisr",   XSPR(31,467,18),   XSPR_MASK, COM,	{ RS } },
++{ "mtdar",     XSPR(31,467,19),   XSPR_MASK, COM,	{ RS } },
++{ "mtrtcu",    XSPR(31,467,20),   XSPR_MASK, COM,	{ RS } },
++{ "mtrtcl",    XSPR(31,467,21),   XSPR_MASK, COM,	{ RS } },
++{ "mtdec",     XSPR(31,467,22),   XSPR_MASK, COM,	{ RS } },
++{ "mtsdr0",    XSPR(31,467,24),   XSPR_MASK, POWER,	{ RS } },
++{ "mtsdr1",    XSPR(31,467,25),   XSPR_MASK, COM,	{ RS } },
++{ "mtsrr0",    XSPR(31,467,26),   XSPR_MASK, COM,	{ RS } },
++{ "mtsrr1",    XSPR(31,467,27),   XSPR_MASK, COM,	{ RS } },
++{ "mtpid",     XSPR(31,467,48),   XSPR_MASK, BOOKE,     { RS } },
++{ "mtpid",     XSPR(31,467,945),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtdecar",   XSPR(31,467,54),   XSPR_MASK, BOOKE,     { RS } },
++{ "mtcsrr0",   XSPR(31,467,58),   XSPR_MASK, BOOKE,     { RS } },
++{ "mtcsrr1",   XSPR(31,467,59),   XSPR_MASK, BOOKE,     { RS } },
++{ "mtdear",    XSPR(31,467,61),   XSPR_MASK, BOOKE,     { RS } },
++{ "mtdear",    XSPR(31,467,981),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtesr",     XSPR(31,467,62),   XSPR_MASK, BOOKE,     { RS } },
++{ "mtesr",     XSPR(31,467,980),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtivpr",    XSPR(31,467,63),   XSPR_MASK, BOOKE,     { RS } },
++{ "mtcmpa",    XSPR(31,467,144),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtcmpb",    XSPR(31,467,145),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtcmpc",    XSPR(31,467,146),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtcmpd",    XSPR(31,467,147),  XSPR_MASK, PPC860,	{ RS } },
++{ "mticr",     XSPR(31,467,148),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtder",     XSPR(31,467,149),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtcounta",  XSPR(31,467,150),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtcountb",  XSPR(31,467,151),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtcmpe",    XSPR(31,467,152),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtcmpf",    XSPR(31,467,153),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtcmpg",    XSPR(31,467,154),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtcmph",    XSPR(31,467,155),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtlctrl1",  XSPR(31,467,156),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtlctrl2",  XSPR(31,467,157),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtictrl",   XSPR(31,467,158),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtbar",     XSPR(31,467,159),  XSPR_MASK, PPC860,	{ RS } },
++{ "mtvrsave",  XSPR(31,467,256),  XSPR_MASK, PPCVEC,	{ RS } },
++{ "mtusprg0",  XSPR(31,467,256),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtsprg",    XSPR(31,467,272),  XSPRG_MASK,PPC,	{ SPRG, RS } },
++{ "mtsprg0",   XSPR(31,467,272),  XSPR_MASK, PPC,	{ RS } },
++{ "mtsprg1",   XSPR(31,467,273),  XSPR_MASK, PPC,	{ RS } },
++{ "mtsprg2",   XSPR(31,467,274),  XSPR_MASK, PPC,	{ RS } },
++{ "mtsprg3",   XSPR(31,467,275),  XSPR_MASK, PPC,	{ RS } },
++{ "mtsprg4",   XSPR(31,467,276),  XSPR_MASK, PPC405 | BOOKE, { RS } },
++{ "mtsprg5",   XSPR(31,467,277),  XSPR_MASK, PPC405 | BOOKE, { RS } },
++{ "mtsprg6",   XSPR(31,467,278),  XSPR_MASK, PPC405 | BOOKE, { RS } },
++{ "mtsprg7",   XSPR(31,467,279),  XSPR_MASK, PPC405 | BOOKE, { RS } },
++{ "mtasr",     XSPR(31,467,280),  XSPR_MASK, PPC64,	{ RS } },
++{ "mtear",     XSPR(31,467,282),  XSPR_MASK, PPC,	{ RS } },
++{ "mttbl",     XSPR(31,467,284),  XSPR_MASK, PPC,	{ RS } },
++{ "mttbu",     XSPR(31,467,285),  XSPR_MASK, PPC,	{ RS } },
++{ "mtdbsr",    XSPR(31,467,304),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtdbsr",    XSPR(31,467,1008), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdbcr0",   XSPR(31,467,308),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtdbcr0",   XSPR(31,467,1010), XSPR_MASK, PPC405,	{ RS } },
++{ "mtdbcr1",   XSPR(31,467,309),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtdbcr1",   XSPR(31,467,957),  XSPR_MASK, PPC405,	{ RS } },
++{ "mtdbcr2",   XSPR(31,467,310),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtiac1",    XSPR(31,467,312),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtiac1",    XSPR(31,467,1012), XSPR_MASK, PPC403,	{ RS } },
++{ "mtiac2",    XSPR(31,467,313),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtiac2",    XSPR(31,467,1013), XSPR_MASK, PPC403,	{ RS } },
++{ "mtiac3",    XSPR(31,467,314),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtiac3",    XSPR(31,467,948),  XSPR_MASK, PPC405,	{ RS } },
++{ "mtiac4",    XSPR(31,467,315),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtiac4",    XSPR(31,467,949),  XSPR_MASK, PPC405,	{ RS } },
++{ "mtdac1",    XSPR(31,467,316),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtdac1",    XSPR(31,467,1014), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdac2",    XSPR(31,467,317),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtdac2",    XSPR(31,467,1015), XSPR_MASK, PPC403,	{ RS } },
++{ "mtdvc1",    XSPR(31,467,318),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtdvc1",    XSPR(31,467,950),  XSPR_MASK, PPC405,	{ RS } },
++{ "mtdvc2",    XSPR(31,467,319),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtdvc2",    XSPR(31,467,951),  XSPR_MASK, PPC405,	{ RS } },
++{ "mttsr",     XSPR(31,467,336),  XSPR_MASK, BOOKE,     { RS } },
++{ "mttsr",     XSPR(31,467,984),  XSPR_MASK, PPC403,	{ RS } },
++{ "mttcr",     XSPR(31,467,340),  XSPR_MASK, BOOKE,     { RS } },
++{ "mttcr",     XSPR(31,467,986),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtivor0",   XSPR(31,467,400),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor1",   XSPR(31,467,401),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor2",   XSPR(31,467,402),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor3",   XSPR(31,467,403),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor4",   XSPR(31,467,404),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor5",   XSPR(31,467,405),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor6",   XSPR(31,467,406),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor7",   XSPR(31,467,407),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor8",   XSPR(31,467,408),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor9",   XSPR(31,467,409),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor10",  XSPR(31,467,410),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor11",  XSPR(31,467,411),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor12",  XSPR(31,467,412),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor13",  XSPR(31,467,413),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor14",  XSPR(31,467,414),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtivor15",  XSPR(31,467,415),  XSPR_MASK, BOOKE,     { RS } },
++{ "mtspefscr",  XSPR(31,467,512),  XSPR_MASK, PPCSPE,   { RS } },
++{ "mtbbear",   XSPR(31,467,513),  XSPR_MASK, PPCBRLK,   { RS } },
++{ "mtbbtar",   XSPR(31,467,514),  XSPR_MASK, PPCBRLK,  { RS } },
++{ "mtibatu",   XSPR(31,467,528),  XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
++{ "mtibatl",   XSPR(31,467,529),  XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
++{ "mtdbatu",   XSPR(31,467,536),  XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
++{ "mtdbatl",   XSPR(31,467,537),  XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
++{ "mtmcsrr0",  XSPR(31,467,570),  XSPR_MASK, PPCRFMCI,  { RS } },
++{ "mtmcsrr1",  XSPR(31,467,571),  XSPR_MASK, PPCRFMCI,  { RS } },
++{ "mtmcsr",    XSPR(31,467,572),  XSPR_MASK, PPCRFMCI,  { RS } },
++{ "mtummcr0",  XSPR(31,467,936),  XSPR_MASK, PPC750,    { RS } },
++{ "mtupmc1",   XSPR(31,467,937),  XSPR_MASK, PPC750,    { RS } },
++{ "mtupmc2",   XSPR(31,467,938),  XSPR_MASK, PPC750,    { RS } },
++{ "mtusia",    XSPR(31,467,939),  XSPR_MASK, PPC750,    { RS } },
++{ "mtummcr1",  XSPR(31,467,940),  XSPR_MASK, PPC750,    { RS } },
++{ "mtupmc3",   XSPR(31,467,941),  XSPR_MASK, PPC750,    { RS } },
++{ "mtupmc4",   XSPR(31,467,942),  XSPR_MASK, PPC750,    { RS } },
++{ "mtzpr",     XSPR(31,467,944),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtccr0",    XSPR(31,467,947),  XSPR_MASK, PPC405,	{ RS } },
++{ "mtmmcr0",   XSPR(31,467,952),  XSPR_MASK, PPC750,    { RS } },
++{ "mtsgr",     XSPR(31,467,953),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtpmc1",    XSPR(31,467,953),  XSPR_MASK, PPC750,    { RS } },
++{ "mtdcwr",    XSPR(31,467,954),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtpmc2",    XSPR(31,467,954),  XSPR_MASK, PPC750,    { RS } },
++{ "mtsler",    XSPR(31,467,955),  XSPR_MASK, PPC405,	{ RS } },
++{ "mtsia",     XSPR(31,467,955),  XSPR_MASK, PPC750,    { RS } },
++{ "mtsu0r",    XSPR(31,467,956),  XSPR_MASK, PPC405,	{ RS } },
++{ "mtmmcr1",   XSPR(31,467,956),  XSPR_MASK, PPC750,    { RS } },
++{ "mtpmc3",    XSPR(31,467,957),  XSPR_MASK, PPC750,    { RS } },
++{ "mtpmc4",    XSPR(31,467,958),  XSPR_MASK, PPC750,    { RS } },
++{ "mticdbdr",  XSPR(31,467,979),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtevpr",    XSPR(31,467,982),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtcdbcr",   XSPR(31,467,983),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtpit",     XSPR(31,467,987),  XSPR_MASK, PPC403,	{ RS } },
++{ "mttbhi",    XSPR(31,467,988),  XSPR_MASK, PPC403,	{ RS } },
++{ "mttblo",    XSPR(31,467,989),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtsrr2",    XSPR(31,467,990),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtsrr3",    XSPR(31,467,991),  XSPR_MASK, PPC403,	{ RS } },
++{ "mtl2cr",    XSPR(31,467,1017), XSPR_MASK, PPC750,    { RS } },
++{ "mtdccr",    XSPR(31,467,1018), XSPR_MASK, PPC403,	{ RS } },
++{ "mticcr",    XSPR(31,467,1019), XSPR_MASK, PPC403,	{ RS } },
++{ "mtictc",    XSPR(31,467,1019), XSPR_MASK, PPC750,    { RS } },
++{ "mtpbl1",    XSPR(31,467,1020), XSPR_MASK, PPC403,	{ RS } },
++{ "mtthrm1",   XSPR(31,467,1020), XSPR_MASK, PPC750,    { RS } },
++{ "mtpbu1",    XSPR(31,467,1021), XSPR_MASK, PPC403,	{ RS } },
++{ "mtthrm2",   XSPR(31,467,1021), XSPR_MASK, PPC750,    { RS } },
++{ "mtpbl2",    XSPR(31,467,1022), XSPR_MASK, PPC403,	{ RS } },
++{ "mtthrm3",   XSPR(31,467,1022), XSPR_MASK, PPC750,    { RS } },
++{ "mtpbu2",    XSPR(31,467,1023), XSPR_MASK, PPC403,	{ RS } },
++{ "mtspr",     X(31,467),	  X_MASK,    COM,	{ SPR, RS } },
++
++{ "dcbi",    X(31,470),	XRT_MASK,	PPC,		{ RA, RB } },
++
++{ "nand",    XRC(31,476,0), X_MASK,	COM,		{ RA, RS, RB } },
++{ "nand.",   XRC(31,476,1), X_MASK,	COM,		{ RA, RS, RB } },
++
++{ "dcbie",   X(31,478),	XRT_MASK,	BOOKE64,	{ RA, RB } },
++
++{ "dcread",  X(31,486),	X_MASK,		PPC403|PPC440,	{ RT, RA, RB }},
++
++{ "mtpmr",   X(31,462),	X_MASK,		PPCPMR,		{ PMR, RS }},
++
++{ "icbtls",  X(31,486),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
++
++{ "nabs",    XO(31,488,0,0), XORB_MASK, M601,		{ RT, RA } },
++{ "subfme64",XO(31,488,0,0), XORB_MASK, BOOKE64,	{ RT, RA } },
++{ "nabs.",   XO(31,488,0,1), XORB_MASK, M601,		{ RT, RA } },
++{ "nabso",   XO(31,488,1,0), XORB_MASK, M601,		{ RT, RA } },
++{ "subfme64o",XO(31,488,1,0), XORB_MASK, BOOKE64,	{ RT, RA } },
++{ "nabso.",  XO(31,488,1,1), XORB_MASK, M601,		{ RT, RA } },
++
++{ "divd",    XO(31,489,0,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "divd.",   XO(31,489,0,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "divdo",   XO(31,489,1,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
++{ "divdo.",  XO(31,489,1,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
++
++{ "addme64", XO(31,490,0,0), XORB_MASK, BOOKE64,	{ RT, RA } },
++{ "addme64o",XO(31,490,1,0), XORB_MASK, BOOKE64,	{ RT, RA } },
++
++{ "divw",    XO(31,491,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "divw.",   XO(31,491,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "divwo",   XO(31,491,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
++{ "divwo.",  XO(31,491,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
++
++{ "icbtlse", X(31,494),	X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
++
++{ "slbia",   X(31,498),	0xffffffff,	PPC64,		{ 0 } },
++
++{ "cli",     X(31,502), XRB_MASK,	POWER,		{ RT, RA } },
++
++{ "stdcxe.", XRC(31,511,1), X_MASK,	BOOKE64,	{ RS, RA, RB } },
++
++{ "mcrxr",   X(31,512),	XRARB_MASK|(3<<21), COM,	{ BF } },
++
++{ "bblels",  X(31,518),	X_MASK,		PPCBRLK,	{ 0 }},
++{ "mcrxr64", X(31,544),	XRARB_MASK|(3<<21), BOOKE64,	{ BF } },
++
++{ "clcs",    X(31,531), XRB_MASK,	M601,		{ RT, RA } },
++
++{ "lswx",    X(31,533),	X_MASK,		PPCCOM,		{ RT, RA, RB } },
++{ "lsx",     X(31,533),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
++
++{ "lwbrx",   X(31,534),	X_MASK,		PPCCOM,		{ RT, RA, RB } },
++{ "lbrx",    X(31,534),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
++
++{ "lfsx",    X(31,535),	X_MASK,		COM,		{ FRT, RA, RB } },
++
++{ "srw",     XRC(31,536,0), X_MASK,	PPCCOM,		{ RA, RS, RB } },
++{ "sr",      XRC(31,536,0), X_MASK,	PWRCOM,		{ RA, RS, RB } },
++{ "srw.",    XRC(31,536,1), X_MASK,	PPCCOM,		{ RA, RS, RB } },
++{ "sr.",     XRC(31,536,1), X_MASK,	PWRCOM,		{ RA, RS, RB } },
++
++{ "rrib",    XRC(31,537,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "rrib.",   XRC(31,537,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "srd",     XRC(31,539,0), X_MASK,	PPC64,		{ RA, RS, RB } },
++{ "srd.",    XRC(31,539,1), X_MASK,	PPC64,		{ RA, RS, RB } },
++
++{ "maskir",  XRC(31,541,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "maskir.", XRC(31,541,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "lwbrxe",  X(31,542),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
++
++{ "lfsxe",   X(31,543),	X_MASK,		BOOKE64,	{ FRT, RA, RB } },
++
++{ "bbelr",   X(31,550),	X_MASK,		PPCBRLK,	{ 0 }},
++{ "tlbsync", X(31,566),	0xffffffff,	PPC,		{ 0 } },
++
++{ "lfsux",   X(31,567),	X_MASK,		COM,		{ FRT, RAS, RB } },
++
++{ "lfsuxe",  X(31,575),	X_MASK,		BOOKE64,	{ FRT, RAS, RB } },
++
++{ "mfsr",    X(31,595),	XRB_MASK|(1<<20), COM32,	{ RT, SR } },
++
++{ "lswi",    X(31,597),	X_MASK,		PPCCOM,		{ RT, RA, NB } },
++{ "lsi",     X(31,597),	X_MASK,		PWRCOM,		{ RT, RA, NB } },
++
++{ "lwsync",  XSYNC(31,598,1), 0xffffffff, PPC,		{ 0 } },
++{ "ptesync", XSYNC(31,598,2), 0xffffffff, PPC64,	{ 0 } },
++{ "msync",   X(31,598), 0xffffffff,	BOOKE,		{ 0 } },
++{ "sync",    X(31,598), XSYNC_MASK,	PPCCOM,		{ LS } },
++{ "dcs",     X(31,598), 0xffffffff,	PWRCOM,		{ 0 } },
++
++{ "lfdx",    X(31,599), X_MASK,		COM,		{ FRT, RA, RB } },
++
++{ "lfdxe",   X(31,607), X_MASK,		BOOKE64,	{ FRT, RA, RB } },
++
++{ "mfsri",   X(31,627), X_MASK,		PWRCOM,		{ RT, RA, RB } },
++
++{ "dclst",   X(31,630), XRB_MASK,	PWRCOM,		{ RS, RA } },
++
++{ "lfdux",   X(31,631), X_MASK,		COM,		{ FRT, RAS, RB } },
++
++{ "lfduxe",  X(31,639), X_MASK,		BOOKE64,	{ FRT, RAS, RB } },
++
++{ "mfsrin",  X(31,659), XRA_MASK,	PPC32,		{ RT, RB } },
++
++{ "stswx",   X(31,661), X_MASK,		PPCCOM,		{ RS, RA, RB } },
++{ "stsx",    X(31,661), X_MASK,		PWRCOM,		{ RS, RA, RB } },
++
++{ "stwbrx",  X(31,662), X_MASK,		PPCCOM,		{ RS, RA, RB } },
++{ "stbrx",   X(31,662), X_MASK,		PWRCOM,		{ RS, RA, RB } },
++
++{ "stfsx",   X(31,663), X_MASK,		COM,		{ FRS, RA, RB } },
++
++{ "srq",     XRC(31,664,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "srq.",    XRC(31,664,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "sre",     XRC(31,665,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "sre.",    XRC(31,665,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "stwbrxe", X(31,670), X_MASK,		BOOKE64,	{ RS, RA, RB } },
++
++{ "stfsxe",  X(31,671), X_MASK,		BOOKE64,	{ FRS, RA, RB } },
++
++{ "stfsux",  X(31,695),	X_MASK,		COM,		{ FRS, RAS, RB } },
++
++{ "sriq",    XRC(31,696,0), X_MASK,	M601,		{ RA, RS, SH } },
++{ "sriq.",   XRC(31,696,1), X_MASK,	M601,		{ RA, RS, SH } },
++
++{ "stfsuxe", X(31,703),	X_MASK,		BOOKE64,	{ FRS, RAS, RB } },
++
++{ "stswi",   X(31,725),	X_MASK,		PPCCOM,		{ RS, RA, NB } },
++{ "stsi",    X(31,725),	X_MASK,		PWRCOM,		{ RS, RA, NB } },
++
++{ "stfdx",   X(31,727),	X_MASK,		COM,		{ FRS, RA, RB } },
++
++{ "srlq",    XRC(31,728,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "srlq.",   XRC(31,728,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "sreq",    XRC(31,729,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "sreq.",   XRC(31,729,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "stfdxe",  X(31,735),	X_MASK,		BOOKE64,	{ FRS, RA, RB } },
++
++{ "dcba",    X(31,758),	XRT_MASK,	PPC405 | BOOKE,	{ RA, RB } },
++
++{ "stfdux",  X(31,759),	X_MASK,		COM,		{ FRS, RAS, RB } },
++
++{ "srliq",   XRC(31,760,0), X_MASK,	M601,		{ RA, RS, SH } },
++{ "srliq.",  XRC(31,760,1), X_MASK,	M601,		{ RA, RS, SH } },
++
++{ "dcbae",   X(31,766),	XRT_MASK,	BOOKE64,	{ RA, RB } },
++
++{ "stfduxe", X(31,767),	X_MASK,		BOOKE64,	{ FRS, RAS, RB } },
++
++{ "tlbivax", X(31,786),	XRT_MASK,	BOOKE,		{ RA, RB } },
++{ "tlbivaxe",X(31,787),	XRT_MASK,	BOOKE64,	{ RA, RB } },
++
++{ "lhbrx",   X(31,790),	X_MASK,		COM,		{ RT, RA, RB } },
++
++{ "sraw",    XRC(31,792,0), X_MASK,	PPCCOM,		{ RA, RS, RB } },
++{ "sra",     XRC(31,792,0), X_MASK,	PWRCOM,		{ RA, RS, RB } },
++{ "sraw.",   XRC(31,792,1), X_MASK,	PPCCOM,		{ RA, RS, RB } },
++{ "sra.",    XRC(31,792,1), X_MASK,	PWRCOM,		{ RA, RS, RB } },
++
++{ "srad",    XRC(31,794,0), X_MASK,	PPC64,		{ RA, RS, RB } },
++{ "srad.",   XRC(31,794,1), X_MASK,	PPC64,		{ RA, RS, RB } },
++
++{ "lhbrxe",  X(31,798),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
++
++{ "ldxe",    X(31,799),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
++{ "lduxe",   X(31,831),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
++
++{ "rac",     X(31,818),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
++
++{ "dss",     XDSS(31,822,0), XDSS_MASK,	PPCVEC,		{ STRM } },
++{ "dssall",  XDSS(31,822,1), XDSS_MASK,	PPCVEC,		{ 0 } },
++
++{ "srawi",   XRC(31,824,0), X_MASK,	PPCCOM,		{ RA, RS, SH } },
++{ "srai",    XRC(31,824,0), X_MASK,	PWRCOM,		{ RA, RS, SH } },
++{ "srawi.",  XRC(31,824,1), X_MASK,	PPCCOM,		{ RA, RS, SH } },
++{ "srai.",   XRC(31,824,1), X_MASK,	PWRCOM,		{ RA, RS, SH } },
++
++{ "slbmfev", X(31,851), XRA_MASK,	PPC64,		{ RT, RB } },
++
++{ "mbar",    X(31,854),	X_MASK,		BOOKE,		{ MO } },
++{ "eieio",   X(31,854),	0xffffffff,	PPC,		{ 0 } },
++
++{ "tlbsx",   XRC(31,914,0), X_MASK,	BOOKE,		{ RA, RB } },
++{ "tlbsx",   XRC(31,914,0), X_MASK, 	PPC403,		{ RT, RA, RB } },
++{ "tlbsx.",  XRC(31,914,1), X_MASK,	BOOKE,		{ RA, RB } },
++{ "tlbsx.",  XRC(31,914,1), X_MASK, 	PPC403,		{ RT, RA, RB } },
++{ "tlbsxe",  XRC(31,915,0), X_MASK,	BOOKE64,	{ RA, RB } },
++{ "tlbsxe.", XRC(31,915,1), X_MASK,	BOOKE64,	{ RA, RB } },
++
++{ "slbmfee", X(31,915), XRA_MASK,	PPC64,		{ RT, RB } },
++
++{ "sthbrx",  X(31,918),	X_MASK,		COM,		{ RS, RA, RB } },
++
++{ "sraq",    XRC(31,920,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "sraq.",   XRC(31,920,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "srea",    XRC(31,921,0), X_MASK,	M601,		{ RA, RS, RB } },
++{ "srea.",   XRC(31,921,1), X_MASK,	M601,		{ RA, RS, RB } },
++
++{ "extsh",   XRC(31,922,0), XRB_MASK,	PPCCOM,		{ RA, RS } },
++{ "exts",    XRC(31,922,0), XRB_MASK,	PWRCOM,		{ RA, RS } },
++{ "extsh.",  XRC(31,922,1), XRB_MASK,	PPCCOM,		{ RA, RS } },
++{ "exts.",   XRC(31,922,1), XRB_MASK,	PWRCOM,		{ RA, RS } },
++
++{ "sthbrxe", X(31,926),	X_MASK,		BOOKE64,	{ RS, RA, RB } },
++
++{ "stdxe",   X(31,927), X_MASK,		BOOKE64,	{ RS, RA, RB } },
++
++{ "tlbrehi", XTLB(31,946,0), XTLB_MASK,	PPC403,		{ RT, RA } },
++{ "tlbrelo", XTLB(31,946,1), XTLB_MASK,	PPC403,		{ RT, RA } },
++{ "tlbre",   X(31,946),	X_MASK,		BOOKE,		{ 0 } },
++{ "tlbre",   X(31,946),	X_MASK,		PPC403,		{ RS, RA, SH } },
++
++{ "sraiq",   XRC(31,952,0), X_MASK,	M601,		{ RA, RS, SH } },
++{ "sraiq.",  XRC(31,952,1), X_MASK,	M601,		{ RA, RS, SH } },
++
++{ "extsb",   XRC(31,954,0), XRB_MASK,	PPC,		{ RA, RS} },
++{ "extsb.",  XRC(31,954,1), XRB_MASK,	PPC,		{ RA, RS} },
++
++{ "stduxe",  X(31,959),	X_MASK,		BOOKE64,	{ RS, RAS, RB } },
++
++{ "iccci",   X(31,966),	XRT_MASK,	PPC403|PPC440,	{ RA, RB } },
++
++{ "tlbwehi", XTLB(31,978,0), XTLB_MASK,	PPC403,		{ RT, RA } },
++{ "tlbwelo", XTLB(31,978,1), XTLB_MASK,	PPC403,		{ RT, RA } },
++{ "tlbwe",   X(31,978),	X_MASK,		BOOKE,		{ 0 } },
++{ "tlbwe",   X(31,978),	X_MASK,		PPC403,		{ RS, RA, SH } },
++{ "tlbld",   X(31,978),	XRTRA_MASK,	PPC,		{ RB } },
++
++{ "icbi",    X(31,982),	XRT_MASK,	PPC,		{ RA, RB } },
++
++{ "stfiwx",  X(31,983),	X_MASK,		PPC,		{ FRS, RA, RB } },
++
++{ "extsw",   XRC(31,986,0), XRB_MASK,	PPC64 | BOOKE64,{ RA, RS } },
++{ "extsw.",  XRC(31,986,1), XRB_MASK,	PPC64,		{ RA, RS } },
++
++{ "icread",  X(31,998),	XRT_MASK,	PPC403|PPC440,	{ RA, RB } },
++
++{ "icbie",   X(31,990),	XRT_MASK,	BOOKE64,	{ RA, RB } },
++{ "stfiwxe", X(31,991),	X_MASK,		BOOKE64,	{ FRS, RA, RB } },
++
++{ "tlbli",   X(31,1010), XRTRA_MASK,	PPC,		{ RB } },
++
++{ "dcbz",    X(31,1014), XRT_MASK,	PPC,		{ RA, RB } },
++{ "dclz",    X(31,1014), XRT_MASK,	PPC,		{ RA, RB } },
++
++{ "dcbze",   X(31,1022), XRT_MASK,	BOOKE64,	{ RA, RB } },
++
++{ "lvebx",   X(31,   7), X_MASK,	PPCVEC,		{ VD, RA, RB } },
++{ "lvehx",   X(31,  39), X_MASK,	PPCVEC,		{ VD, RA, RB } },
++{ "lvewx",   X(31,  71), X_MASK,	PPCVEC,		{ VD, RA, RB } },
++{ "lvsl",    X(31,   6), X_MASK,	PPCVEC,		{ VD, RA, RB } },
++{ "lvsr",    X(31,  38), X_MASK,	PPCVEC,		{ VD, RA, RB } },
++{ "lvx",     X(31, 103), X_MASK,	PPCVEC,		{ VD, RA, RB } },
++{ "lvxl",    X(31, 359), X_MASK,	PPCVEC,		{ VD, RA, RB } },
++{ "stvebx",  X(31, 135), X_MASK,	PPCVEC,		{ VS, RA, RB } },
++{ "stvehx",  X(31, 167), X_MASK,	PPCVEC,		{ VS, RA, RB } },
++{ "stvewx",  X(31, 199), X_MASK,	PPCVEC,		{ VS, RA, RB } },
++{ "stvx",    X(31, 231), X_MASK,	PPCVEC,		{ VS, RA, RB } },
++{ "stvxl",   X(31, 487), X_MASK,	PPCVEC,		{ VS, RA, RB } },
++
++{ "lwz",     OP(32),	OP_MASK,	PPCCOM,		{ RT, D, RA } },
++{ "l",	     OP(32),	OP_MASK,	PWRCOM,		{ RT, D, RA } },
++
++{ "lwzu",    OP(33),	OP_MASK,	PPCCOM,		{ RT, D, RAL } },
++{ "lu",      OP(33),	OP_MASK,	PWRCOM,		{ RT, D, RA } },
++
++{ "lbz",     OP(34),	OP_MASK,	COM,		{ RT, D, RA } },
++
++{ "lbzu",    OP(35),	OP_MASK,	COM,		{ RT, D, RAL } },
++
++{ "stw",     OP(36),	OP_MASK,	PPCCOM,		{ RS, D, RA } },
++{ "st",      OP(36),	OP_MASK,	PWRCOM,		{ RS, D, RA } },
++
++{ "stwu",    OP(37),	OP_MASK,	PPCCOM,		{ RS, D, RAS } },
++{ "stu",     OP(37),	OP_MASK,	PWRCOM,		{ RS, D, RA } },
++
++{ "stb",     OP(38),	OP_MASK,	COM,		{ RS, D, RA } },
++
++{ "stbu",    OP(39),	OP_MASK,	COM,		{ RS, D, RAS } },
++
++{ "lhz",     OP(40),	OP_MASK,	COM,		{ RT, D, RA } },
++
++{ "lhzu",    OP(41),	OP_MASK,	COM,		{ RT, D, RAL } },
++
++{ "lha",     OP(42),	OP_MASK,	COM,		{ RT, D, RA } },
++
++{ "lhau",    OP(43),	OP_MASK,	COM,		{ RT, D, RAL } },
++
++{ "sth",     OP(44),	OP_MASK,	COM,		{ RS, D, RA } },
++
++{ "sthu",    OP(45),	OP_MASK,	COM,		{ RS, D, RAS } },
++
++{ "lmw",     OP(46),	OP_MASK,	PPCCOM,		{ RT, D, RAM } },
++{ "lm",      OP(46),	OP_MASK,	PWRCOM,		{ RT, D, RA } },
++
++{ "stmw",    OP(47),	OP_MASK,	PPCCOM,		{ RS, D, RA } },
++{ "stm",     OP(47),	OP_MASK,	PWRCOM,		{ RS, D, RA } },
++
++{ "lfs",     OP(48),	OP_MASK,	COM,		{ FRT, D, RA } },
++
++{ "lfsu",    OP(49),	OP_MASK,	COM,		{ FRT, D, RAS } },
++
++{ "lfd",     OP(50),	OP_MASK,	COM,		{ FRT, D, RA } },
++
++{ "lfdu",    OP(51),	OP_MASK,	COM,		{ FRT, D, RAS } },
++
++{ "stfs",    OP(52),	OP_MASK,	COM,		{ FRS, D, RA } },
++
++{ "stfsu",   OP(53),	OP_MASK,	COM,		{ FRS, D, RAS } },
++
++{ "stfd",    OP(54),	OP_MASK,	COM,		{ FRS, D, RA } },
++
++{ "stfdu",   OP(55),	OP_MASK,	COM,		{ FRS, D, RAS } },
++
++{ "lq",      OP(56),	OP_MASK,	POWER4,		{ RTQ, DQ, RAQ } },
++
++{ "lfq",     OP(56),	OP_MASK,	POWER2,		{ FRT, D, RA } },
++
++{ "lfqu",    OP(57),	OP_MASK,	POWER2,		{ FRT, D, RA } },
++
++{ "lbze",    DEO(58,0), DE_MASK,	BOOKE64,	{ RT, DE, RA } },
++{ "lbzue",   DEO(58,1), DE_MASK,	BOOKE64,	{ RT, DE, RAL } },
++{ "lhze",    DEO(58,2), DE_MASK,	BOOKE64,	{ RT, DE, RA } },
++{ "lhzue",   DEO(58,3), DE_MASK,	BOOKE64,	{ RT, DE, RAL } },
++{ "lhae",    DEO(58,4), DE_MASK,	BOOKE64,	{ RT, DE, RA } },
++{ "lhaue",   DEO(58,5), DE_MASK,	BOOKE64,	{ RT, DE, RAL } },
++{ "lwze",    DEO(58,6), DE_MASK,	BOOKE64,	{ RT, DE, RA } },
++{ "lwzue",   DEO(58,7), DE_MASK,	BOOKE64,	{ RT, DE, RAL } },
++{ "stbe",    DEO(58,8), DE_MASK,	BOOKE64,	{ RS, DE, RA } },
++{ "stbue",   DEO(58,9), DE_MASK,	BOOKE64,	{ RS, DE, RAS } },
++{ "sthe",    DEO(58,10), DE_MASK,	BOOKE64,	{ RS, DE, RA } },
++{ "sthue",   DEO(58,11), DE_MASK,	BOOKE64,	{ RS, DE, RAS } },
++{ "stwe",    DEO(58,14), DE_MASK,	BOOKE64,	{ RS, DE, RA } },
++{ "stwue",   DEO(58,15), DE_MASK,	BOOKE64,	{ RS, DE, RAS } },
++
++{ "ld",      DSO(58,0),	DS_MASK,	PPC64,		{ RT, DS, RA } },
++
++{ "ldu",     DSO(58,1), DS_MASK,	PPC64,		{ RT, DS, RAL } },
++
++{ "lwa",     DSO(58,2), DS_MASK,	PPC64,		{ RT, DS, RA } },
++
++{ "fdivs",   A(59,18,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
++{ "fdivs.",  A(59,18,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
++
++{ "fsubs",   A(59,20,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
++{ "fsubs.",  A(59,20,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
++
++{ "fadds",   A(59,21,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
++{ "fadds.",  A(59,21,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
++
++{ "fsqrts",  A(59,22,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
++{ "fsqrts.", A(59,22,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
++
++{ "fres",    A(59,24,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
++{ "fres.",   A(59,24,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
++
++{ "fmuls",   A(59,25,0), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
++{ "fmuls.",  A(59,25,1), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
++
++{ "fmsubs",  A(59,28,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++{ "fmsubs.", A(59,28,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++
++{ "fmadds",  A(59,29,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++{ "fmadds.", A(59,29,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++
++{ "fnmsubs", A(59,30,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++{ "fnmsubs.",A(59,30,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++
++{ "fnmadds", A(59,31,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++{ "fnmadds.",A(59,31,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++
++{ "stfq",    OP(60),	OP_MASK,	POWER2,		{ FRS, D, RA } },
++
++{ "stfqu",   OP(61),	OP_MASK,	POWER2,		{ FRS, D, RA } },
++
++{ "lde",     DEO(62,0), DE_MASK,	BOOKE64,	{ RT, DES, RA } },
++{ "ldue",    DEO(62,1), DE_MASK,	BOOKE64,	{ RT, DES, RA } },
++{ "lfse",    DEO(62,4), DE_MASK,	BOOKE64,	{ FRT, DES, RA } },
++{ "lfsue",   DEO(62,5), DE_MASK,	BOOKE64,	{ FRT, DES, RAS } },
++{ "lfde",    DEO(62,6), DE_MASK,	BOOKE64,	{ FRT, DES, RA } },
++{ "lfdue",   DEO(62,7), DE_MASK,	BOOKE64,	{ FRT, DES, RAS } },
++{ "stde",    DEO(62,8), DE_MASK,	BOOKE64,	{ RS, DES, RA } },
++{ "stdue",   DEO(62,9), DE_MASK,	BOOKE64,	{ RS, DES, RAS } },
++{ "stfse",   DEO(62,12), DE_MASK,	BOOKE64,	{ FRS, DES, RA } },
++{ "stfsue",  DEO(62,13), DE_MASK,	BOOKE64,	{ FRS, DES, RAS } },
++{ "stfde",   DEO(62,14), DE_MASK,	BOOKE64,	{ FRS, DES, RA } },
++{ "stfdue",  DEO(62,15), DE_MASK,	BOOKE64,	{ FRS, DES, RAS } },
++
++{ "std",     DSO(62,0),	DS_MASK,	PPC64,		{ RS, DS, RA } },
++
++{ "stdu",    DSO(62,1),	DS_MASK,	PPC64,		{ RS, DS, RAS } },
++
++{ "stq",     DSO(62,2),	DS_MASK,	POWER4,		{ RSQ, DS, RA } },
++
++{ "fcmpu",   X(63,0),	X_MASK|(3<<21),	COM,		{ BF, FRA, FRB } },
++
++{ "frsp",    XRC(63,12,0), XRA_MASK,	COM,		{ FRT, FRB } },
++{ "frsp.",   XRC(63,12,1), XRA_MASK,	COM,		{ FRT, FRB } },
++
++{ "fctiw",   XRC(63,14,0), XRA_MASK,	PPCCOM,		{ FRT, FRB } },
++{ "fcir",    XRC(63,14,0), XRA_MASK,	POWER2,		{ FRT, FRB } },
++{ "fctiw.",  XRC(63,14,1), XRA_MASK,	PPCCOM,		{ FRT, FRB } },
++{ "fcir.",   XRC(63,14,1), XRA_MASK,	POWER2,		{ FRT, FRB } },
++
++{ "fctiwz",  XRC(63,15,0), XRA_MASK,	PPCCOM,		{ FRT, FRB } },
++{ "fcirz",   XRC(63,15,0), XRA_MASK,	POWER2,		{ FRT, FRB } },
++{ "fctiwz.", XRC(63,15,1), XRA_MASK,	PPCCOM,		{ FRT, FRB } },
++{ "fcirz.",  XRC(63,15,1), XRA_MASK,	POWER2,		{ FRT, FRB } },
++
++{ "fdiv",    A(63,18,0), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
++{ "fd",      A(63,18,0), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
++{ "fdiv.",   A(63,18,1), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
++{ "fd.",     A(63,18,1), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
++
++{ "fsub",    A(63,20,0), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
++{ "fs",      A(63,20,0), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
++{ "fsub.",   A(63,20,1), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
++{ "fs.",     A(63,20,1), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
++
++{ "fadd",    A(63,21,0), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
++{ "fa",      A(63,21,0), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
++{ "fadd.",   A(63,21,1), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
++{ "fa.",     A(63,21,1), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
++
++{ "fsqrt",   A(63,22,0), AFRAFRC_MASK,	PPCPWR2,	{ FRT, FRB } },
++{ "fsqrt.",  A(63,22,1), AFRAFRC_MASK,	PPCPWR2,	{ FRT, FRB } },
++
++{ "fsel",    A(63,23,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++{ "fsel.",   A(63,23,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
++
++{ "fmul",    A(63,25,0), AFRB_MASK,	PPCCOM,		{ FRT, FRA, FRC } },
++{ "fm",      A(63,25,0), AFRB_MASK,	PWRCOM,		{ FRT, FRA, FRC } },
++{ "fmul.",   A(63,25,1), AFRB_MASK,	PPCCOM,		{ FRT, FRA, FRC } },
++{ "fm.",     A(63,25,1), AFRB_MASK,	PWRCOM,		{ FRT, FRA, FRC } },
++
++{ "frsqrte", A(63,26,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
++{ "frsqrte.",A(63,26,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
++
++{ "fmsub",   A(63,28,0), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fms",     A(63,28,0), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fmsub.",  A(63,28,1), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fms.",    A(63,28,1), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
++
++{ "fmadd",   A(63,29,0), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fma",     A(63,29,0), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fmadd.",  A(63,29,1), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fma.",    A(63,29,1), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
++
++{ "fnmsub",  A(63,30,0), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fnms",    A(63,30,0), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fnmsub.", A(63,30,1), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fnms.",   A(63,30,1), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
++
++{ "fnmadd",  A(63,31,0), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fnma",    A(63,31,0), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fnmadd.", A(63,31,1), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
++{ "fnma.",   A(63,31,1), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
++
++{ "fcmpo",   X(63,32),	X_MASK|(3<<21),	COM,		{ BF, FRA, FRB } },
++
++{ "mtfsb1",  XRC(63,38,0), XRARB_MASK,	COM,		{ BT } },
++{ "mtfsb1.", XRC(63,38,1), XRARB_MASK,	COM,		{ BT } },
++
++{ "fneg",    XRC(63,40,0), XRA_MASK,	COM,		{ FRT, FRB } },
++{ "fneg.",   XRC(63,40,1), XRA_MASK,	COM,		{ FRT, FRB } },
++
++{ "mcrfs",   X(63,64),	XRB_MASK|(3<<21)|(3<<16), COM,	{ BF, BFA } },
++
++{ "mtfsb0",  XRC(63,70,0), XRARB_MASK,	COM,		{ BT } },
++{ "mtfsb0.", XRC(63,70,1), XRARB_MASK,	COM,		{ BT } },
++
++{ "fmr",     XRC(63,72,0), XRA_MASK,	COM,		{ FRT, FRB } },
++{ "fmr.",    XRC(63,72,1), XRA_MASK,	COM,		{ FRT, FRB } },
++
++{ "mtfsfi",  XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
++{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
++
++{ "fnabs",   XRC(63,136,0), XRA_MASK,	COM,		{ FRT, FRB } },
++{ "fnabs.",  XRC(63,136,1), XRA_MASK,	COM,		{ FRT, FRB } },
++
++{ "fabs",    XRC(63,264,0), XRA_MASK,	COM,		{ FRT, FRB } },
++{ "fabs.",   XRC(63,264,1), XRA_MASK,	COM,		{ FRT, FRB } },
++
++{ "mffs",    XRC(63,583,0), XRARB_MASK,	COM,		{ FRT } },
++{ "mffs.",   XRC(63,583,1), XRARB_MASK,	COM,		{ FRT } },
++
++{ "mtfsf",   XFL(63,711,0), XFL_MASK,	COM,		{ FLM, FRB } },
++{ "mtfsf.",  XFL(63,711,1), XFL_MASK,	COM,		{ FLM, FRB } },
++
++{ "fctid",   XRC(63,814,0), XRA_MASK,	PPC64,		{ FRT, FRB } },
++{ "fctid.",  XRC(63,814,1), XRA_MASK,	PPC64,		{ FRT, FRB } },
++
++{ "fctidz",  XRC(63,815,0), XRA_MASK,	PPC64,		{ FRT, FRB } },
++{ "fctidz.", XRC(63,815,1), XRA_MASK,	PPC64,		{ FRT, FRB } },
++
++{ "fcfid",   XRC(63,846,0), XRA_MASK,	PPC64,		{ FRT, FRB } },
++{ "fcfid.",  XRC(63,846,1), XRA_MASK,	PPC64,		{ FRT, FRB } },
++
++};
++
++const int powerpc_num_opcodes =
++  sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
++
++/* The macro table.  This is only used by the assembler.  */
++
++/* The expressions of the form (-x ! 31) & (x | 31) have the value 0
++   when x=0; 32-x when x is between 1 and 31; are negative if x is
++   negative; and are 32 or more otherwise.  This is what you want
++   when, for instance, you are emulating a right shift by a
++   rotate-left-and-mask, because the underlying instructions support
++   shifts of size 0 but not shifts of size 32.  By comparison, when
++   extracting x bits from some word you want to use just 32-x, because
++   the underlying instructions don't support extracting 0 bits but do
++   support extracting the whole word (32 bits in this case).  */
++
++const struct powerpc_macro powerpc_macros[] = {
++{ "extldi",  4,   PPC64,	"rldicr %0,%1,%3,(%2)-1" },
++{ "extldi.", 4,   PPC64,	"rldicr. %0,%1,%3,(%2)-1" },
++{ "extrdi",  4,   PPC64,	"rldicl %0,%1,(%2)+(%3),64-(%2)" },
++{ "extrdi.", 4,   PPC64,	"rldicl. %0,%1,(%2)+(%3),64-(%2)" },
++{ "insrdi",  4,   PPC64,	"rldimi %0,%1,64-((%2)+(%3)),%3" },
++{ "insrdi.", 4,   PPC64,	"rldimi. %0,%1,64-((%2)+(%3)),%3" },
++{ "rotrdi",  3,   PPC64,	"rldicl %0,%1,(-(%2)!63)&((%2)|63),0" },
++{ "rotrdi.", 3,   PPC64,	"rldicl. %0,%1,(-(%2)!63)&((%2)|63),0" },
++{ "sldi",    3,   PPC64,	"rldicr %0,%1,%2,63-(%2)" },
++{ "sldi.",   3,   PPC64,	"rldicr. %0,%1,%2,63-(%2)" },
++{ "srdi",    3,   PPC64,	"rldicl %0,%1,(-(%2)!63)&((%2)|63),%2" },
++{ "srdi.",   3,   PPC64,	"rldicl. %0,%1,(-(%2)!63)&((%2)|63),%2" },
++{ "clrrdi",  3,   PPC64,	"rldicr %0,%1,0,63-(%2)" },
++{ "clrrdi.", 3,   PPC64,	"rldicr. %0,%1,0,63-(%2)" },
++{ "clrlsldi",4,   PPC64,	"rldic %0,%1,%3,(%2)-(%3)" },
++{ "clrlsldi.",4,  PPC64,	"rldic. %0,%1,%3,(%2)-(%3)" },
++
++{ "extlwi",  4,   PPCCOM,	"rlwinm %0,%1,%3,0,(%2)-1" },
++{ "extlwi.", 4,   PPCCOM,	"rlwinm. %0,%1,%3,0,(%2)-1" },
++{ "extrwi",  4,   PPCCOM,	"rlwinm %0,%1,((%2)+(%3))&((%2)+(%3)<>32),32-(%2),31" },
++{ "extrwi.", 4,   PPCCOM,	"rlwinm. %0,%1,((%2)+(%3))&((%2)+(%3)<>32),32-(%2),31" },
++{ "inslwi",  4,   PPCCOM,	"rlwimi %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1" },
++{ "inslwi.", 4,   PPCCOM,	"rlwimi. %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1"},
++{ "insrwi",  4,   PPCCOM,	"rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" },
++{ "insrwi.", 4,   PPCCOM,	"rlwimi. %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1"},
++{ "rotrwi",  3,   PPCCOM,	"rlwinm %0,%1,(-(%2)!31)&((%2)|31),0,31" },
++{ "rotrwi.", 3,   PPCCOM,	"rlwinm. %0,%1,(-(%2)!31)&((%2)|31),0,31" },
++{ "slwi",    3,   PPCCOM,	"rlwinm %0,%1,%2,0,31-(%2)" },
++{ "sli",     3,   PWRCOM,	"rlinm %0,%1,%2,0,31-(%2)" },
++{ "slwi.",   3,   PPCCOM,	"rlwinm. %0,%1,%2,0,31-(%2)" },
++{ "sli.",    3,   PWRCOM,	"rlinm. %0,%1,%2,0,31-(%2)" },
++{ "srwi",    3,   PPCCOM,	"rlwinm %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
++{ "sri",     3,   PWRCOM,	"rlinm %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
++{ "srwi.",   3,   PPCCOM,	"rlwinm. %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
++{ "sri.",    3,   PWRCOM,	"rlinm. %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
++{ "clrrwi",  3,   PPCCOM,	"rlwinm %0,%1,0,0,31-(%2)" },
++{ "clrrwi.", 3,   PPCCOM,	"rlwinm. %0,%1,0,0,31-(%2)" },
++{ "clrlslwi",4,   PPCCOM,	"rlwinm %0,%1,%3,(%2)-(%3),31-(%3)" },
++{ "clrlslwi.",4,  PPCCOM,	"rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" },
++};
++
++const int powerpc_num_macros =
++  sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
+diff --git a/arch/powerpc/xmon/ppc.h b/arch/powerpc/xmon/ppc.h
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/ppc.h
+@@ -0,0 +1,307 @@
++/* ppc.h -- Header file for PowerPC opcode table
++   Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003
++   Free Software Foundation, Inc.
++   Written by Ian Lance Taylor, Cygnus Support
++
++This file is part of GDB, GAS, and the GNU binutils.
++
++GDB, GAS, and the GNU binutils are free software; you can redistribute
++them and/or modify them under the terms of the GNU General Public
++License as published by the Free Software Foundation; either version
++1, or (at your option) any later version.
++
++GDB, GAS, and the GNU binutils are distributed in the hope that they
++will be useful, but WITHOUT ANY WARRANTY; without even the implied
++warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++the GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this file; see the file COPYING.  If not, write to the Free
++Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
++
++#ifndef PPC_H
++#define PPC_H
++
++/* The opcode table is an array of struct powerpc_opcode.  */
++
++struct powerpc_opcode
++{
++  /* The opcode name.  */
++  const char *name;
++
++  /* The opcode itself.  Those bits which will be filled in with
++     operands are zeroes.  */
++  unsigned long opcode;
++
++  /* The opcode mask.  This is used by the disassembler.  This is a
++     mask containing ones indicating those bits which must match the
++     opcode field, and zeroes indicating those bits which need not
++     match (and are presumably filled in by operands).  */
++  unsigned long mask;
++
++  /* One bit flags for the opcode.  These are used to indicate which
++     specific processors support the instructions.  The defined values
++     are listed below.  */
++  unsigned long flags;
++
++  /* An array of operand codes.  Each code is an index into the
++     operand table.  They appear in the order which the operands must
++     appear in assembly code, and are terminated by a zero.  */
++  unsigned char operands[8];
++};
++
++/* The table itself is sorted by major opcode number, and is otherwise
++   in the order in which the disassembler should consider
++   instructions.  */
++extern const struct powerpc_opcode powerpc_opcodes[];
++extern const int powerpc_num_opcodes;
++
++/* Values defined for the flags field of a struct powerpc_opcode.  */
++
++/* Opcode is defined for the PowerPC architecture.  */
++#define PPC_OPCODE_PPC			 1
++
++/* Opcode is defined for the POWER (RS/6000) architecture.  */
++#define PPC_OPCODE_POWER		 2
++
++/* Opcode is defined for the POWER2 (Rios 2) architecture.  */
++#define PPC_OPCODE_POWER2		 4
++
++/* Opcode is only defined on 32 bit architectures.  */
++#define PPC_OPCODE_32			 8
++
++/* Opcode is only defined on 64 bit architectures.  */
++#define PPC_OPCODE_64		      0x10
++
++/* Opcode is supported by the Motorola PowerPC 601 processor.  The 601
++   is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
++   but it also supports many additional POWER instructions.  */
++#define PPC_OPCODE_601		      0x20
++
++/* Opcode is supported in both the Power and PowerPC architectures
++   (ie, compiler's -mcpu=common or assembler's -mcom).  */
++#define PPC_OPCODE_COMMON	      0x40
++
++/* Opcode is supported for any Power or PowerPC platform (this is
++   for the assembler's -many option, and it eliminates duplicates).  */
++#define PPC_OPCODE_ANY		      0x80
++
++/* Opcode is supported as part of the 64-bit bridge.  */
++#define PPC_OPCODE_64_BRIDGE	     0x100
++
++/* Opcode is supported by Altivec Vector Unit */
++#define PPC_OPCODE_ALTIVEC	     0x200
++
++/* Opcode is supported by PowerPC 403 processor.  */
++#define PPC_OPCODE_403		     0x400
++
++/* Opcode is supported by PowerPC BookE processor.  */
++#define PPC_OPCODE_BOOKE	     0x800
++
++/* Opcode is only supported by 64-bit PowerPC BookE processor.  */
++#define PPC_OPCODE_BOOKE64	    0x1000
++
++/* Opcode is supported by PowerPC 440 processor.  */
++#define PPC_OPCODE_440		    0x2000
++
++/* Opcode is only supported by Power4 architecture.  */
++#define PPC_OPCODE_POWER4	    0x4000
++
++/* Opcode isn't supported by Power4 architecture.  */
++#define PPC_OPCODE_NOPOWER4	    0x8000
++
++/* Opcode is only supported by POWERPC Classic architecture.  */
++#define PPC_OPCODE_CLASSIC	   0x10000
++
++/* Opcode is only supported by e500x2 Core.  */
++#define PPC_OPCODE_SPE		   0x20000
++
++/* Opcode is supported by e500x2 Integer select APU.  */
++#define PPC_OPCODE_ISEL		   0x40000
++
++/* Opcode is an e500 SPE floating point instruction.  */
++#define PPC_OPCODE_EFS		   0x80000
++
++/* Opcode is supported by branch locking APU.  */
++#define PPC_OPCODE_BRLOCK	  0x100000
++
++/* Opcode is supported by performance monitor APU.  */
++#define PPC_OPCODE_PMR		  0x200000
++
++/* Opcode is supported by cache locking APU.  */
++#define PPC_OPCODE_CACHELCK	  0x400000
++
++/* Opcode is supported by machine check APU.  */
++#define PPC_OPCODE_RFMCI	  0x800000
++
++/* A macro to extract the major opcode from an instruction.  */
++#define PPC_OP(i) (((i) >> 26) & 0x3f)
++
++/* The operands table is an array of struct powerpc_operand.  */
++
++struct powerpc_operand
++{
++  /* The number of bits in the operand.  */
++  int bits;
++
++  /* How far the operand is left shifted in the instruction.  */
++  int shift;
++
++  /* Insertion function.  This is used by the assembler.  To insert an
++     operand value into an instruction, check this field.
++
++     If it is NULL, execute
++         i |= (op & ((1 << o->bits) - 1)) << o->shift;
++     (i is the instruction which we are filling in, o is a pointer to
++     this structure, and op is the opcode value; this assumes twos
++     complement arithmetic).
++
++     If this field is not NULL, then simply call it with the
++     instruction and the operand value.  It will return the new value
++     of the instruction.  If the ERRMSG argument is not NULL, then if
++     the operand value is illegal, *ERRMSG will be set to a warning
++     string (the operand will be inserted in any case).  If the
++     operand value is legal, *ERRMSG will be unchanged (most operands
++     can accept any value).  */
++  unsigned long (*insert)
++    (unsigned long instruction, long op, int dialect, const char **errmsg);
++
++  /* Extraction function.  This is used by the disassembler.  To
++     extract this operand type from an instruction, check this field.
++
++     If it is NULL, compute
++         op = ((i) >> o->shift) & ((1 << o->bits) - 1);
++	 if ((o->flags & PPC_OPERAND_SIGNED) != 0
++	     && (op & (1 << (o->bits - 1))) != 0)
++	   op -= 1 << o->bits;
++     (i is the instruction, o is a pointer to this structure, and op
++     is the result; this assumes twos complement arithmetic).
++
++     If this field is not NULL, then simply call it with the
++     instruction value.  It will return the value of the operand.  If
++     the INVALID argument is not NULL, *INVALID will be set to
++     non-zero if this operand type can not actually be extracted from
++     this operand (i.e., the instruction does not match).  If the
++     operand is valid, *INVALID will not be changed.  */
++  long (*extract) (unsigned long instruction, int dialect, int *invalid);
++
++  /* One bit syntax flags.  */
++  unsigned long flags;
++};
++
++/* Elements in the table are retrieved by indexing with values from
++   the operands field of the powerpc_opcodes table.  */
++
++extern const struct powerpc_operand powerpc_operands[];
++
++/* Values defined for the flags field of a struct powerpc_operand.  */
++
++/* This operand takes signed values.  */
++#define PPC_OPERAND_SIGNED (01)
++
++/* This operand takes signed values, but also accepts a full positive
++   range of values when running in 32 bit mode.  That is, if bits is
++   16, it takes any value from -0x8000 to 0xffff.  In 64 bit mode,
++   this flag is ignored.  */
++#define PPC_OPERAND_SIGNOPT (02)
++
++/* This operand does not actually exist in the assembler input.  This
++   is used to support extended mnemonics such as mr, for which two
++   operands fields are identical.  The assembler should call the
++   insert function with any op value.  The disassembler should call
++   the extract function, ignore the return value, and check the value
++   placed in the valid argument.  */
++#define PPC_OPERAND_FAKE (04)
++
++/* The next operand should be wrapped in parentheses rather than
++   separated from this one by a comma.  This is used for the load and
++   store instructions which want their operands to look like
++       reg,displacement(reg)
++   */
++#define PPC_OPERAND_PARENS (010)
++
++/* This operand may use the symbolic names for the CR fields, which
++   are
++       lt  0	gt  1	eq  2	so  3	un  3
++       cr0 0	cr1 1	cr2 2	cr3 3
++       cr4 4	cr5 5	cr6 6	cr7 7
++   These may be combined arithmetically, as in cr2*4+gt.  These are
++   only supported on the PowerPC, not the POWER.  */
++#define PPC_OPERAND_CR (020)
++
++/* This operand names a register.  The disassembler uses this to print
++   register names with a leading 'r'.  */
++#define PPC_OPERAND_GPR (040)
++
++/* This operand names a floating point register.  The disassembler
++   prints these with a leading 'f'.  */
++#define PPC_OPERAND_FPR (0100)
++
++/* This operand is a relative branch displacement.  The disassembler
++   prints these symbolically if possible.  */
++#define PPC_OPERAND_RELATIVE (0200)
++
++/* This operand is an absolute branch address.  The disassembler
++   prints these symbolically if possible.  */
++#define PPC_OPERAND_ABSOLUTE (0400)
++
++/* This operand is optional, and is zero if omitted.  This is used for
++   the optional BF and L fields in the comparison instructions.  The
++   assembler must count the number of operands remaining on the line,
++   and the number of operands remaining for the opcode, and decide
++   whether this operand is present or not.  The disassembler should
++   print this operand out only if it is not zero.  */
++#define PPC_OPERAND_OPTIONAL (01000)
++
++/* This flag is only used with PPC_OPERAND_OPTIONAL.  If this operand
++   is omitted, then for the next operand use this operand value plus
++   1, ignoring the next operand field for the opcode.  This wretched
++   hack is needed because the Power rotate instructions can take
++   either 4 or 5 operands.  The disassembler should print this operand
++   out regardless of the PPC_OPERAND_OPTIONAL field.  */
++#define PPC_OPERAND_NEXT (02000)
++
++/* This operand should be regarded as a negative number for the
++   purposes of overflow checking (i.e., the normal most negative
++   number is disallowed and one more than the normal most positive
++   number is allowed).  This flag will only be set for a signed
++   operand.  */
++#define PPC_OPERAND_NEGATIVE (04000)
++
++/* This operand names a vector unit register.  The disassembler
++   prints these with a leading 'v'.  */
++#define PPC_OPERAND_VR (010000)
++
++/* This operand is for the DS field in a DS form instruction.  */
++#define PPC_OPERAND_DS (020000)
++
++/* This operand is for the DQ field in a DQ form instruction.  */
++#define PPC_OPERAND_DQ (040000)
++
++/* The POWER and PowerPC assemblers use a few macros.  We keep them
++   with the operands table for simplicity.  The macro table is an
++   array of struct powerpc_macro.  */
++
++struct powerpc_macro
++{
++  /* The macro name.  */
++  const char *name;
++
++  /* The number of operands the macro takes.  */
++  unsigned int operands;
++
++  /* One bit flags for the opcode.  These are used to indicate which
++     specific processors support the instructions.  The values are the
++     same as those for the struct powerpc_opcode flags field.  */
++  unsigned long flags;
++
++  /* A format string to turn the macro into a normal instruction.
++     Each %N in the string is replaced with operand number N (zero
++     based).  */
++  const char *format;
++};
++
++extern const struct powerpc_macro powerpc_macros[];
++extern const int powerpc_num_macros;
++
++#endif /* PPC_H */
+diff --git a/arch/powerpc/xmon/setjmp.S b/arch/powerpc/xmon/setjmp.S
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/setjmp.S
+@@ -0,0 +1,135 @@
++/*
++ * Copyright (C) 1996 Paul Mackerras.
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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: assert(sizeof(buf) > 23 * sizeof(long))
++ */
++#include <asm/processor.h>
++#include <asm/ppc_asm.h>
++#include <asm/asm-offsets.h>
++
++_GLOBAL(xmon_setjmp)
++	mflr	r0
++	STL	r0,0(r3)
++	STL	r1,SZL(r3)
++	STL	r2,2*SZL(r3)
++	mfcr	r0
++	STL	r0,3*SZL(r3)
++	STL	r13,4*SZL(r3)
++	STL	r14,5*SZL(r3)
++	STL	r15,6*SZL(r3)
++	STL	r16,7*SZL(r3)
++	STL	r17,8*SZL(r3)
++	STL	r18,9*SZL(r3)
++	STL	r19,10*SZL(r3)
++	STL	r20,11*SZL(r3)
++	STL	r21,12*SZL(r3)
++	STL	r22,13*SZL(r3)
++	STL	r23,14*SZL(r3)
++	STL	r24,15*SZL(r3)
++	STL	r25,16*SZL(r3)
++	STL	r26,17*SZL(r3)
++	STL	r27,18*SZL(r3)
++	STL	r28,19*SZL(r3)
++	STL	r29,20*SZL(r3)
++	STL	r30,21*SZL(r3)
++	STL	r31,22*SZL(r3)
++	li	r3,0
++	blr
++
++_GLOBAL(xmon_longjmp)
++	CMPI	r4,0
++	bne	1f
++	li	r4,1
++1:	LDL	r13,4*SZL(r3)
++	LDL	r14,5*SZL(r3)
++	LDL	r15,6*SZL(r3)
++	LDL	r16,7*SZL(r3)
++	LDL	r17,8*SZL(r3)
++	LDL	r18,9*SZL(r3)
++	LDL	r19,10*SZL(r3)
++	LDL	r20,11*SZL(r3)
++	LDL	r21,12*SZL(r3)
++	LDL	r22,13*SZL(r3)
++	LDL	r23,14*SZL(r3)
++	LDL	r24,15*SZL(r3)
++	LDL	r25,16*SZL(r3)
++	LDL	r26,17*SZL(r3)
++	LDL	r27,18*SZL(r3)
++	LDL	r28,19*SZL(r3)
++	LDL	r29,20*SZL(r3)
++	LDL	r30,21*SZL(r3)
++	LDL	r31,22*SZL(r3)
++	LDL	r0,3*SZL(r3)
++	mtcrf	0x38,r0
++	LDL	r0,0(r3)
++	LDL	r1,SZL(r3)
++	LDL	r2,2*SZL(r3)
++	mtlr	r0
++	mr	r3,r4
++	blr
++
++/*
++ * Grab the register values as they are now.
++ * This won't do a particularily good job because we really
++ * want our caller's caller's registers, and our caller has
++ * already executed its prologue.
++ * ToDo: We could reach back into the caller's save area to do
++ * a better job of representing the caller's state (note that
++ * that will be different for 32-bit and 64-bit, because of the
++ * different ABIs, though).
++ */
++_GLOBAL(xmon_save_regs)
++	STL	r0,0*SZL(r3)
++	STL	r2,2*SZL(r3)
++	STL	r3,3*SZL(r3)
++	STL	r4,4*SZL(r3)
++	STL	r5,5*SZL(r3)
++	STL	r6,6*SZL(r3)
++	STL	r7,7*SZL(r3)
++	STL	r8,8*SZL(r3)
++	STL	r9,9*SZL(r3)
++	STL	r10,10*SZL(r3)
++	STL	r11,11*SZL(r3)
++	STL	r12,12*SZL(r3)
++	STL	r13,13*SZL(r3)
++	STL	r14,14*SZL(r3)
++	STL	r15,15*SZL(r3)
++	STL	r16,16*SZL(r3)
++	STL	r17,17*SZL(r3)
++	STL	r18,18*SZL(r3)
++	STL	r19,19*SZL(r3)
++	STL	r20,20*SZL(r3)
++	STL	r21,21*SZL(r3)
++	STL	r22,22*SZL(r3)
++	STL	r23,23*SZL(r3)
++	STL	r24,24*SZL(r3)
++	STL	r25,25*SZL(r3)
++	STL	r26,26*SZL(r3)
++	STL	r27,27*SZL(r3)
++	STL	r28,28*SZL(r3)
++	STL	r29,29*SZL(r3)
++	STL	r30,30*SZL(r3)
++	STL	r31,31*SZL(r3)
++	/* go up one stack frame for SP */
++	LDL	r4,0(r1)
++	STL	r4,1*SZL(r3)
++	/* get caller's LR */
++	LDL	r0,LRSAVE(r4)
++	STL	r0,_NIP-STACK_FRAME_OVERHEAD(r3)
++	STL	r0,_LINK-STACK_FRAME_OVERHEAD(r3)
++	mfmsr	r0
++	STL	r0,_MSR-STACK_FRAME_OVERHEAD(r3)
++	mfctr	r0
++	STL	r0,_CTR-STACK_FRAME_OVERHEAD(r3)
++	mfxer	r0
++	STL	r0,_XER-STACK_FRAME_OVERHEAD(r3)
++	mfcr	r0
++	STL	r0,_CCR-STACK_FRAME_OVERHEAD(r3)
++	li	r0,0
++	STL	r0,_TRAP-STACK_FRAME_OVERHEAD(r3)
++	blr
+diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/start_32.c
+@@ -0,0 +1,624 @@
++/*
++ * Copyright (C) 1996 Paul Mackerras.
++ */
++#include <linux/config.h>
++#include <linux/string.h>
++#include <asm/machdep.h>
++#include <asm/io.h>
++#include <asm/page.h>
++#include <linux/adb.h>
++#include <linux/pmu.h>
++#include <linux/cuda.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/sysrq.h>
++#include <linux/bitops.h>
++#include <asm/xmon.h>
++#include <asm/prom.h>
++#include <asm/bootx.h>
++#include <asm/machdep.h>
++#include <asm/errno.h>
++#include <asm/pmac_feature.h>
++#include <asm/processor.h>
++#include <asm/delay.h>
++#include <asm/btext.h>
++
++static volatile unsigned char __iomem *sccc, *sccd;
++unsigned int TXRDY, RXRDY, DLAB;
++static int xmon_expect(const char *str, unsigned int timeout);
++
++static int use_serial;
++static int use_screen;
++static int via_modem;
++static int xmon_use_sccb;
++static struct device_node *channel_node;
++
++#define TB_SPEED	25000000
++
++static inline unsigned int readtb(void)
++{
++	unsigned int ret;
++
++	asm volatile("mftb %0" : "=r" (ret) :);
++	return ret;
++}
++
++void buf_access(void)
++{
++	if (DLAB)
++		sccd[3] &= ~DLAB;	/* reset DLAB */
++}
++
++extern int adb_init(void);
++
++#ifdef CONFIG_PPC_CHRP
++/*
++ * This looks in the "ranges" property for the primary PCI host bridge
++ * to find the physical address of the start of PCI/ISA I/O space.
++ * It is basically a cut-down version of pci_process_bridge_OF_ranges.
++ */
++static unsigned long chrp_find_phys_io_base(void)
++{
++	struct device_node *node;
++	unsigned int *ranges;
++	unsigned long base = CHRP_ISA_IO_BASE;
++	int rlen = 0;
++	int np;
++
++	node = find_devices("isa");
++	if (node != NULL) {
++		node = node->parent;
++		if (node == NULL || node->type == NULL
++		    || strcmp(node->type, "pci") != 0)
++			node = NULL;
++	}
++	if (node == NULL)
++		node = find_devices("pci");
++	if (node == NULL)
++		return base;
++
++	ranges = (unsigned int *) get_property(node, "ranges", &rlen);
++	np = prom_n_addr_cells(node) + 5;
++	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
++		if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
++			/* I/O space starting at 0, grab the phys base */
++			base = ranges[np - 3];
++			break;
++		}
++		ranges += np;
++	}
++	return base;
++}
++#endif /* CONFIG_PPC_CHRP */
++
++#ifdef CONFIG_MAGIC_SYSRQ
++static void sysrq_handle_xmon(int key, struct pt_regs *regs,
++			      struct tty_struct *tty)
++{
++	xmon(regs);
++}
++
++static struct sysrq_key_op sysrq_xmon_op =
++{
++	.handler =	sysrq_handle_xmon,
++	.help_msg =	"Xmon",
++	.action_msg =	"Entering xmon",
++};
++#endif
++
++void
++xmon_map_scc(void)
++{
++#ifdef CONFIG_PPC_MULTIPLATFORM
++	volatile unsigned char __iomem *base;
++
++	if (_machine == _MACH_Pmac) {
++		struct device_node *np;
++		unsigned long addr;
++#ifdef CONFIG_BOOTX_TEXT
++		if (!use_screen && !use_serial
++		    && !machine_is_compatible("iMac")) {
++			/* see if there is a keyboard in the device tree
++			   with a parent of type "adb" */
++			for (np = find_devices("keyboard"); np; np = np->next)
++				if (np->parent && np->parent->type
++				    && strcmp(np->parent->type, "adb") == 0)
++					break;
++
++			/* needs to be hacked if xmon_printk is to be used
++			   from within find_via_pmu() */
++#ifdef CONFIG_ADB_PMU
++			if (np != NULL && boot_text_mapped && find_via_pmu())
++				use_screen = 1;
++#endif
++#ifdef CONFIG_ADB_CUDA
++			if (np != NULL && boot_text_mapped && find_via_cuda())
++				use_screen = 1;
++#endif
++		}
++		if (!use_screen && (np = find_devices("escc")) != NULL) {
++			/*
++			 * look for the device node for the serial port
++			 * we're using and see if it says it has a modem
++			 */
++			char *name = xmon_use_sccb? "ch-b": "ch-a";
++			char *slots;
++			int l;
++
++			np = np->child;
++			while (np != NULL && strcmp(np->name, name) != 0)
++				np = np->sibling;
++			if (np != NULL) {
++				/* XXX should parse this properly */
++				channel_node = np;
++				slots = get_property(np, "slot-names", &l);
++				if (slots != NULL && l >= 10
++				    && strcmp(slots+4, "Modem") == 0)
++					via_modem = 1;
++			}
++		}
++		btext_drawstring("xmon uses ");
++		if (use_screen)
++			btext_drawstring("screen and keyboard\n");
++		else {
++			if (via_modem)
++				btext_drawstring("modem on ");
++			btext_drawstring(xmon_use_sccb? "printer": "modem");
++			btext_drawstring(" port\n");
++		}
++
++#endif /* CONFIG_BOOTX_TEXT */
++
++#ifdef CHRP_ESCC
++		addr = 0xc1013020;
++#else
++		addr = 0xf3013020;
++#endif
++		TXRDY = 4;
++		RXRDY = 1;
++	
++		np = find_devices("mac-io");
++		if (np && np->n_addrs)
++			addr = np->addrs[0].address + 0x13020;
++		base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
++		sccc = base + (addr & ~PAGE_MASK);
++		sccd = sccc + 0x10;
++
++	} else {
++		base = (volatile unsigned char *) isa_io_base;
++
++#ifdef CONFIG_PPC_CHRP
++		if (_machine == _MACH_chrp)
++			base = (volatile unsigned char __iomem *)
++				ioremap(chrp_find_phys_io_base(), 0x1000);
++#endif
++
++		sccc = base + 0x3fd;
++		sccd = base + 0x3f8;
++		if (xmon_use_sccb) {
++			sccc -= 0x100;
++			sccd -= 0x100;
++		}
++		TXRDY = 0x20;
++		RXRDY = 1;
++		DLAB = 0x80;
++	}
++#elif defined(CONFIG_GEMINI)
++	/* should already be mapped by the kernel boot */
++	sccc = (volatile unsigned char __iomem *) 0xffeffb0d;
++	sccd = (volatile unsigned char __iomem *) 0xffeffb08;
++	TXRDY = 0x20;
++	RXRDY = 1;
++	DLAB = 0x80;
++#elif defined(CONFIG_405GP)
++	sccc = (volatile unsigned char __iomem *)0xef600305;
++	sccd = (volatile unsigned char __iomem *)0xef600300;
++	TXRDY = 0x20;
++	RXRDY = 1;
++	DLAB = 0x80;
++#endif /* platform */
++
++	register_sysrq_key('x', &sysrq_xmon_op);
++}
++
++static int scc_initialized = 0;
++
++void xmon_init_scc(void);
++extern void cuda_poll(void);
++
++static inline void do_poll_adb(void)
++{
++#ifdef CONFIG_ADB_PMU
++	if (sys_ctrler == SYS_CTRLER_PMU)
++		pmu_poll_adb();
++#endif /* CONFIG_ADB_PMU */
++#ifdef CONFIG_ADB_CUDA
++	if (sys_ctrler == SYS_CTRLER_CUDA)
++		cuda_poll();
++#endif /* CONFIG_ADB_CUDA */
++}
++
++int
++xmon_write(void *handle, void *ptr, int nb)
++{
++	char *p = ptr;
++	int i, c, ct;
++
++#ifdef CONFIG_SMP
++	static unsigned long xmon_write_lock;
++	int lock_wait = 1000000;
++	int locked;
++
++	while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
++		if (--lock_wait == 0)
++			break;
++#endif
++
++#ifdef CONFIG_BOOTX_TEXT
++	if (use_screen) {
++		/* write it on the screen */
++		for (i = 0; i < nb; ++i)
++			btext_drawchar(*p++);
++		goto out;
++	}
++#endif
++	if (!scc_initialized)
++		xmon_init_scc();
++	ct = 0;
++	for (i = 0; i < nb; ++i) {
++		while ((*sccc & TXRDY) == 0)
++			do_poll_adb();
++		c = p[i];
++		if (c == '\n' && !ct) {
++			c = '\r';
++			ct = 1;
++			--i;
++		} else {
++			ct = 0;
++		}
++		buf_access();
++		*sccd = c;
++		eieio();
++	}
++
++ out:
++#ifdef CONFIG_SMP
++	if (!locked)
++		clear_bit(0, &xmon_write_lock);
++#endif
++	return nb;
++}
++
++int xmon_wants_key;
++int xmon_adb_keycode;
++
++#ifdef CONFIG_BOOTX_TEXT
++static int xmon_adb_shiftstate;
++
++static unsigned char xmon_keytab[128] =
++	"asdfhgzxcv\000bqwer"				/* 0x00 - 0x0f */
++	"yt123465=97-80]o"				/* 0x10 - 0x1f */
++	"u[ip\rlj'k;\\,/nm."				/* 0x20 - 0x2f */
++	"\t `\177\0\033\0\0\0\0\0\0\0\0\0\0"		/* 0x30 - 0x3f */
++	"\0.\0*\0+\0\0\0\0\0/\r\0-\0"			/* 0x40 - 0x4f */
++	"\0\0000123456789\0\0\0";			/* 0x50 - 0x5f */
++
++static unsigned char xmon_shift_keytab[128] =
++	"ASDFHGZXCV\000BQWER"				/* 0x00 - 0x0f */
++	"YT!@#$^%+(&_*)}O"				/* 0x10 - 0x1f */
++	"U{IP\rLJ\"K:|<?NM>"				/* 0x20 - 0x2f */
++	"\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0"		/* 0x30 - 0x3f */
++	"\0.\0*\0+\0\0\0\0\0/\r\0-\0"			/* 0x40 - 0x4f */
++	"\0\0000123456789\0\0\0";			/* 0x50 - 0x5f */
++
++static int
++xmon_get_adb_key(void)
++{
++	int k, t, on;
++
++	xmon_wants_key = 1;
++	for (;;) {
++		xmon_adb_keycode = -1;
++		t = 0;
++		on = 0;
++		do {
++			if (--t < 0) {
++				on = 1 - on;
++				btext_drawchar(on? 0xdb: 0x20);
++				btext_drawchar('\b');
++				t = 200000;
++			}
++			do_poll_adb();
++		} while (xmon_adb_keycode == -1);
++		k = xmon_adb_keycode;
++		if (on)
++			btext_drawstring(" \b");
++
++		/* test for shift keys */
++		if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
++			xmon_adb_shiftstate = (k & 0x80) == 0;
++			continue;
++		}
++		if (k >= 0x80)
++			continue;	/* ignore up transitions */
++		k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
++		if (k != 0)
++			break;
++	}
++	xmon_wants_key = 0;
++	return k;
++}
++#endif /* CONFIG_BOOTX_TEXT */
++
++int
++xmon_read(void *handle, void *ptr, int nb)
++{
++    char *p = ptr;
++    int i;
++
++#ifdef CONFIG_BOOTX_TEXT
++    if (use_screen) {
++	for (i = 0; i < nb; ++i)
++	    *p++ = xmon_get_adb_key();
++	return i;
++    }
++#endif
++    if (!scc_initialized)
++	xmon_init_scc();
++    for (i = 0; i < nb; ++i) {
++	while ((*sccc & RXRDY) == 0)
++	    do_poll_adb();
++	buf_access();
++	*p++ = *sccd;
++    }
++    return i;
++}
++
++int
++xmon_read_poll(void)
++{
++	if ((*sccc & RXRDY) == 0) {
++		do_poll_adb();
++		return -1;
++	}
++	buf_access();
++	return *sccd;
++}
++
++static unsigned char scc_inittab[] = {
++    13, 0,		/* set baud rate divisor */
++    12, 1,
++    14, 1,		/* baud rate gen enable, src=rtxc */
++    11, 0x50,		/* clocks = br gen */
++    5,  0xea,		/* tx 8 bits, assert DTR & RTS */
++    4,  0x46,		/* x16 clock, 1 stop */
++    3,  0xc1,		/* rx enable, 8 bits */
++};
++
++void
++xmon_init_scc(void)
++{
++	if ( _machine == _MACH_chrp )
++	{
++		sccd[3] = 0x83; eieio();	/* LCR = 8N1 + DLAB */
++		sccd[0] = 12; eieio();		/* DLL = 9600 baud */
++		sccd[1] = 0; eieio();
++		sccd[2] = 0; eieio();		/* FCR = 0 */
++		sccd[3] = 3; eieio();		/* LCR = 8N1 */
++		sccd[1] = 0; eieio();		/* IER = 0 */
++	}
++	else if ( _machine == _MACH_Pmac )
++	{
++		int i, x;
++
++		if (channel_node != 0)
++			pmac_call_feature(
++				PMAC_FTR_SCC_ENABLE,
++				channel_node,
++				PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
++			printk(KERN_INFO "Serial port locked ON by debugger !\n");
++		if (via_modem && channel_node != 0) {
++			unsigned int t0;
++
++			pmac_call_feature(
++				PMAC_FTR_MODEM_ENABLE,
++				channel_node, 0, 1);
++			printk(KERN_INFO "Modem powered up by debugger !\n");
++			t0 = readtb();
++			while (readtb() - t0 < 3*TB_SPEED)
++				eieio();
++		}
++		/* use the B channel if requested */
++		if (xmon_use_sccb) {
++			sccc = (volatile unsigned char *)
++				((unsigned long)sccc & ~0x20);
++			sccd = sccc + 0x10;
++		}
++		for (i = 20000; i != 0; --i) {
++			x = *sccc; eieio();
++		}
++		*sccc = 9; eieio();		/* reset A or B side */
++		*sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
++		for (i = 0; i < sizeof(scc_inittab); ++i) {
++			*sccc = scc_inittab[i];
++			eieio();
++		}
++	}
++	scc_initialized = 1;
++	if (via_modem) {
++		for (;;) {
++			xmon_write(NULL, "ATE1V1\r", 7);
++			if (xmon_expect("OK", 5)) {
++				xmon_write(NULL, "ATA\r", 4);
++				if (xmon_expect("CONNECT", 40))
++					break;
++			}
++			xmon_write(NULL, "+++", 3);
++			xmon_expect("OK", 3);
++		}
++	}
++}
++
++void *xmon_stdin;
++void *xmon_stdout;
++void *xmon_stderr;
++
++int xmon_putc(int c, void *f)
++{
++    char ch = c;
++
++    if (c == '\n')
++	xmon_putc('\r', f);
++    return xmon_write(f, &ch, 1) == 1? c: -1;
++}
++
++int xmon_putchar(int c)
++{
++	return xmon_putc(c, xmon_stdout);
++}
++
++int xmon_fputs(char *str, void *f)
++{
++	int n = strlen(str);
++
++	return xmon_write(f, str, n) == n? 0: -1;
++}
++
++int
++xmon_readchar(void)
++{
++	char ch;
++
++	for (;;) {
++		switch (xmon_read(xmon_stdin, &ch, 1)) {
++		case 1:
++			return ch;
++		case -1:
++			xmon_printf("read(stdin) returned -1\r\n", 0, 0);
++			return -1;
++		}
++	}
++}
++
++static char line[256];
++static char *lineptr;
++static int lineleft;
++
++int xmon_expect(const char *str, unsigned int timeout)
++{
++	int c;
++	unsigned int t0;
++
++	timeout *= TB_SPEED;
++	t0 = readtb();
++	do {
++		lineptr = line;
++		for (;;) {
++			c = xmon_read_poll();
++			if (c == -1) {
++				if (readtb() - t0 > timeout)
++					return 0;
++				continue;
++			}
++			if (c == '\n')
++				break;
++			if (c != '\r' && lineptr < &line[sizeof(line) - 1])
++				*lineptr++ = c;
++		}
++		*lineptr = 0;
++	} while (strstr(line, str) == NULL);
++	return 1;
++}
++
++int
++xmon_getchar(void)
++{
++    int c;
++
++    if (lineleft == 0) {
++	lineptr = line;
++	for (;;) {
++	    c = xmon_readchar();
++	    if (c == -1 || c == 4)
++		break;
++	    if (c == '\r' || c == '\n') {
++		*lineptr++ = '\n';
++		xmon_putchar('\n');
++		break;
++	    }
++	    switch (c) {
++	    case 0177:
++	    case '\b':
++		if (lineptr > line) {
++		    xmon_putchar('\b');
++		    xmon_putchar(' ');
++		    xmon_putchar('\b');
++		    --lineptr;
++		}
++		break;
++	    case 'U' & 0x1F:
++		while (lineptr > line) {
++		    xmon_putchar('\b');
++		    xmon_putchar(' ');
++		    xmon_putchar('\b');
++		    --lineptr;
++		}
++		break;
++	    default:
++		if (lineptr >= &line[sizeof(line) - 1])
++		    xmon_putchar('\a');
++		else {
++		    xmon_putchar(c);
++		    *lineptr++ = c;
++		}
++	    }
++	}
++	lineleft = lineptr - line;
++	lineptr = line;
++    }
++    if (lineleft == 0)
++	return -1;
++    --lineleft;
++    return *lineptr++;
++}
++
++char *
++xmon_fgets(char *str, int nb, void *f)
++{
++    char *p;
++    int c;
++
++    for (p = str; p < str + nb - 1; ) {
++	c = xmon_getchar();
++	if (c == -1) {
++	    if (p == str)
++		return NULL;
++	    break;
++	}
++	*p++ = c;
++	if (c == '\n')
++	    break;
++    }
++    *p = 0;
++    return str;
++}
++
++void
++xmon_enter(void)
++{
++#ifdef CONFIG_ADB_PMU
++	if (_machine == _MACH_Pmac) {
++		pmu_suspend();
++	}
++#endif
++}
++
++void
++xmon_leave(void)
++{
++#ifdef CONFIG_ADB_PMU
++	if (_machine == _MACH_Pmac) {
++		pmu_resume();
++	}
++#endif
++}
+diff --git a/arch/powerpc/xmon/start_64.c b/arch/powerpc/xmon/start_64.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/start_64.c
+@@ -0,0 +1,187 @@
++/*
++ * Copyright (C) 1996 Paul Mackerras.
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/string.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/sysrq.h>
++#include <linux/init.h>
++#include <asm/machdep.h>
++#include <asm/io.h>
++#include <asm/page.h>
++#include <asm/prom.h>
++#include <asm/processor.h>
++#include <asm/udbg.h>
++#include <asm/system.h>
++#include "nonstdio.h"
++
++#ifdef CONFIG_MAGIC_SYSRQ
++
++static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
++			      struct tty_struct *tty) 
++{
++	/* ensure xmon is enabled */
++	xmon_init(1);
++	debugger(pt_regs);
++}
++
++static struct sysrq_key_op sysrq_xmon_op = 
++{
++	.handler =	sysrq_handle_xmon,
++	.help_msg =	"Xmon",
++	.action_msg =	"Entering xmon",
++};
++
++static int __init setup_xmon_sysrq(void)
++{
++	register_sysrq_key('x', &sysrq_xmon_op);
++	return 0;
++}
++__initcall(setup_xmon_sysrq);
++#endif /* CONFIG_MAGIC_SYSRQ */
++
++int
++xmon_write(void *handle, void *ptr, int nb)
++{
++	return udbg_write(ptr, nb);
++}
++
++int
++xmon_read(void *handle, void *ptr, int nb)
++{
++	return udbg_read(ptr, nb);
++}
++
++int
++xmon_read_poll(void)
++{
++	if (udbg_getc_poll)
++		return udbg_getc_poll();
++	return -1;
++}
++ 
++FILE *xmon_stdin;
++FILE *xmon_stdout;
++
++int
++xmon_putc(int c, void *f)
++{
++	char ch = c;
++
++	if (c == '\n')
++		xmon_putc('\r', f);
++	return xmon_write(f, &ch, 1) == 1? c: -1;
++}
++
++int
++xmon_putchar(int c)
++{
++	return xmon_putc(c, xmon_stdout);
++}
++
++int
++xmon_fputs(char *str, void *f)
++{
++	int n = strlen(str);
++
++	return xmon_write(f, str, n) == n? 0: -1;
++}
++
++int
++xmon_readchar(void)
++{
++	char ch;
++
++	for (;;) {
++		switch (xmon_read(xmon_stdin, &ch, 1)) {
++		case 1:
++			return ch;
++		case -1:
++			xmon_printf("read(stdin) returned -1\r\n", 0, 0);
++			return -1;
++		}
++	}
++}
++
++static char line[256];
++static char *lineptr;
++static int lineleft;
++
++int
++xmon_getchar(void)
++{
++	int c;
++
++	if (lineleft == 0) {
++		lineptr = line;
++		for (;;) {
++			c = xmon_readchar();
++			if (c == -1 || c == 4)
++				break;
++			if (c == '\r' || c == '\n') {
++				*lineptr++ = '\n';
++				xmon_putchar('\n');
++				break;
++			}
++			switch (c) {
++			case 0177:
++			case '\b':
++				if (lineptr > line) {
++					xmon_putchar('\b');
++					xmon_putchar(' ');
++					xmon_putchar('\b');
++					--lineptr;
++				}
++				break;
++			case 'U' & 0x1F:
++				while (lineptr > line) {
++					xmon_putchar('\b');
++					xmon_putchar(' ');
++					xmon_putchar('\b');
++					--lineptr;
++				}
++				break;
++			default:
++				if (lineptr >= &line[sizeof(line) - 1])
++					xmon_putchar('\a');
++				else {
++					xmon_putchar(c);
++					*lineptr++ = c;
++				}
++			}
++		}
++		lineleft = lineptr - line;
++		lineptr = line;
++	}
++	if (lineleft == 0)
++		return -1;
++	--lineleft;
++	return *lineptr++;
++}
++
++char *
++xmon_fgets(char *str, int nb, void *f)
++{
++	char *p;
++	int c;
++
++	for (p = str; p < str + nb - 1; ) {
++		c = xmon_getchar();
++		if (c == -1) {
++			if (p == str)
++				return NULL;
++			break;
++		}
++		*p++ = c;
++		if (c == '\n')
++			break;
++	}
++	*p = 0;
++	return str;
++}
+diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/start_8xx.c
+@@ -0,0 +1,287 @@
++/*
++ * Copyright (C) 1996 Paul Mackerras.
++ * Copyright (C) 2000 Dan Malek.
++ * Quick hack of Paul's code to make XMON work on 8xx processors.  Lots
++ * of assumptions, like the SMC1 is used, it has been initialized by the
++ * loader at some point, and we can just stuff and suck bytes.
++ * We rely upon the 8xx uart driver to support us, as the interface
++ * changes between boot up and operational phases of the kernel.
++ */
++#include <linux/string.h>
++#include <asm/machdep.h>
++#include <asm/io.h>
++#include <asm/page.h>
++#include <linux/kernel.h>
++#include <asm/8xx_immap.h>
++#include <asm/mpc8xx.h>
++#include <asm/commproc.h>
++
++extern void xmon_printf(const char *fmt, ...);
++extern int xmon_8xx_write(char *str, int nb);
++extern int xmon_8xx_read_poll(void);
++extern int xmon_8xx_read_char(void);
++void prom_drawhex(uint);
++void prom_drawstring(const char *str);
++
++static int use_screen = 1; /* default */
++
++#define TB_SPEED	25000000
++
++static inline unsigned int readtb(void)
++{
++	unsigned int ret;
++
++	asm volatile("mftb %0" : "=r" (ret) :);
++	return ret;
++}
++
++void buf_access(void)
++{
++}
++
++void
++xmon_map_scc(void)
++{
++
++	cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
++	use_screen = 0;
++	
++	prom_drawstring("xmon uses serial port\n");
++}
++
++static int scc_initialized = 0;
++
++void xmon_init_scc(void);
++
++int
++xmon_write(void *handle, void *ptr, int nb)
++{
++	char *p = ptr;
++	int i, c, ct;
++
++	if (!scc_initialized)
++		xmon_init_scc();
++
++	return(xmon_8xx_write(ptr, nb));
++}
++
++int xmon_wants_key;
++
++int
++xmon_read(void *handle, void *ptr, int nb)
++{
++	char *p = ptr;
++	int i;
++
++	if (!scc_initialized)
++		xmon_init_scc();
++
++	for (i = 0; i < nb; ++i) {
++		*p++ = xmon_8xx_read_char();
++	}
++	return i;
++}
++
++int
++xmon_read_poll(void)
++{
++	return(xmon_8xx_read_poll());
++}
++
++void
++xmon_init_scc()
++{
++	scc_initialized = 1;
++}
++
++#if 0
++extern int (*prom_entry)(void *);
++
++int
++xmon_exit(void)
++{
++    struct prom_args {
++	char *service;
++    } args;
++
++    for (;;) {
++	args.service = "exit";
++	(*prom_entry)(&args);
++    }
++}
++#endif
++
++void *xmon_stdin;
++void *xmon_stdout;
++void *xmon_stderr;
++
++void
++xmon_init(void)
++{
++}
++
++int
++xmon_putc(int c, void *f)
++{
++    char ch = c;
++
++    if (c == '\n')
++	xmon_putc('\r', f);
++    return xmon_write(f, &ch, 1) == 1? c: -1;
++}
++
++int
++xmon_putchar(int c)
++{
++    return xmon_putc(c, xmon_stdout);
++}
++
++int
++xmon_fputs(char *str, void *f)
++{
++    int n = strlen(str);
++
++    return xmon_write(f, str, n) == n? 0: -1;
++}
++
++int
++xmon_readchar(void)
++{
++    char ch;
++
++    for (;;) {
++	switch (xmon_read(xmon_stdin, &ch, 1)) {
++	case 1:
++	    return ch;
++	case -1:
++	    xmon_printf("read(stdin) returned -1\r\n", 0, 0);
++	    return -1;
++	}
++    }
++}
++
++static char line[256];
++static char *lineptr;
++static int lineleft;
++
++#if 0
++int xmon_expect(const char *str, unsigned int timeout)
++{
++	int c;
++	unsigned int t0;
++
++	timeout *= TB_SPEED;
++	t0 = readtb();
++	do {
++		lineptr = line;
++		for (;;) {
++			c = xmon_read_poll();
++			if (c == -1) {
++				if (readtb() - t0 > timeout)
++					return 0;
++				continue;
++			}
++			if (c == '\n')
++				break;
++			if (c != '\r' && lineptr < &line[sizeof(line) - 1])
++				*lineptr++ = c;
++		}
++		*lineptr = 0;
++	} while (strstr(line, str) == NULL);
++	return 1;
++}
++#endif
++
++int
++xmon_getchar(void)
++{
++    int c;
++
++    if (lineleft == 0) {
++	lineptr = line;
++	for (;;) {
++	    c = xmon_readchar();
++	    if (c == -1 || c == 4)
++		break;
++	    if (c == '\r' || c == '\n') {
++		*lineptr++ = '\n';
++		xmon_putchar('\n');
++		break;
++	    }
++	    switch (c) {
++	    case 0177:
++	    case '\b':
++		if (lineptr > line) {
++		    xmon_putchar('\b');
++		    xmon_putchar(' ');
++		    xmon_putchar('\b');
++		    --lineptr;
++		}
++		break;
++	    case 'U' & 0x1F:
++		while (lineptr > line) {
++		    xmon_putchar('\b');
++		    xmon_putchar(' ');
++		    xmon_putchar('\b');
++		    --lineptr;
++		}
++		break;
++	    default:
++		if (lineptr >= &line[sizeof(line) - 1])
++		    xmon_putchar('\a');
++		else {
++		    xmon_putchar(c);
++		    *lineptr++ = c;
++		}
++	    }
++	}
++	lineleft = lineptr - line;
++	lineptr = line;
++    }
++    if (lineleft == 0)
++	return -1;
++    --lineleft;
++    return *lineptr++;
++}
++
++char *
++xmon_fgets(char *str, int nb, void *f)
++{
++    char *p;
++    int c;
++
++    for (p = str; p < str + nb - 1; ) {
++	c = xmon_getchar();
++	if (c == -1) {
++	    if (p == str)
++		return 0;
++	    break;
++	}
++	*p++ = c;
++	if (c == '\n')
++	    break;
++    }
++    *p = 0;
++    return str;
++}
++
++void
++prom_drawhex(uint val)
++{
++	unsigned char buf[10];
++
++	int i;
++	for (i = 7;  i >= 0;  i--)
++	{
++		buf[i] = "0123456789abcdef"[val & 0x0f];
++		val >>= 4;
++	}
++	buf[8] = '\0';
++	xmon_fputs(buf, xmon_stdout);
++}
++
++void
++prom_drawstring(const char *str)
++{
++	xmon_fputs(str, xmon_stdout);
++}
+diff --git a/arch/powerpc/xmon/subr_prf.c b/arch/powerpc/xmon/subr_prf.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/subr_prf.c
+@@ -0,0 +1,54 @@
++/*
++ * Written by Cort Dougan to replace the version originally used
++ * by Paul Mackerras, which came from NetBSD and thus had copyright
++ * conflicts with Linux.
++ *
++ * This file makes liberal use of the standard linux utility
++ * routines to reduce the size of the binary.  We assume we can
++ * trust some parts of Linux inside the debugger.
++ *   -- Cort (cort at cs.nmt.edu)
++ *
++ * Copyright (C) 1999 Cort Dougan.
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/string.h>
++#include <linux/module.h>
++#include <stdarg.h>
++#include "nonstdio.h"
++
++extern int xmon_write(void *, void *, int);
++
++void xmon_vfprintf(void *f, const char *fmt, va_list ap)
++{
++	static char xmon_buf[2048];
++	int n;
++
++	n = vsprintf(xmon_buf, fmt, ap);
++	xmon_write(f, xmon_buf, n);
++}
++
++void xmon_printf(const char *fmt, ...)
++{
++	va_list ap;
++
++	va_start(ap, fmt);
++	xmon_vfprintf(stdout, fmt, ap);
++	va_end(ap);
++}
++EXPORT_SYMBOL(xmon_printf);
++
++void xmon_fprintf(void *f, const char *fmt, ...)
++{
++	va_list ap;
++
++	va_start(ap, fmt);
++	xmon_vfprintf(f, fmt, ap);
++	va_end(ap);
++}
++
+diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
+new file mode 100644
+--- /dev/null
++++ b/arch/powerpc/xmon/xmon.c
+@@ -0,0 +1,2529 @@
++/*
++ * Routines providing a simple monitor for use on the PowerMac.
++ *
++ * Copyright (C) 1996 Paul Mackerras.
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the 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/errno.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/mm.h>
++#include <linux/reboot.h>
++#include <linux/delay.h>
++#include <linux/kallsyms.h>
++#include <linux/cpumask.h>
++#include <linux/module.h>
++
++#include <asm/ptrace.h>
++#include <asm/string.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++#include <asm/xmon.h>
++#ifdef CONFIG_PMAC_BACKLIGHT
++#include <asm/backlight.h>
++#endif
++#include <asm/processor.h>
++#include <asm/pgtable.h>
++#include <asm/mmu.h>
++#include <asm/mmu_context.h>
++#include <asm/cputable.h>
++#include <asm/rtas.h>
++#include <asm/sstep.h>
++#include <asm/bug.h>
++
++#ifdef CONFIG_PPC64
++#include <asm/hvcall.h>
++#include <asm/paca.h>
++#endif
++
++#include "nonstdio.h"
++
++#define scanhex	xmon_scanhex
++#define skipbl	xmon_skipbl
++
++#ifdef CONFIG_SMP
++cpumask_t cpus_in_xmon = CPU_MASK_NONE;
++static unsigned long xmon_taken = 1;
++static int xmon_owner;
++static int xmon_gate;
++#endif /* CONFIG_SMP */
++
++static unsigned long in_xmon = 0;
++
++static unsigned long adrs;
++static int size = 1;
++#define MAX_DUMP (128 * 1024)
++static unsigned long ndump = 64;
++static unsigned long nidump = 16;
++static unsigned long ncsum = 4096;
++static int termch;
++static char tmpstr[128];
++
++#define JMP_BUF_LEN	23
++static long bus_error_jmp[JMP_BUF_LEN];
++static int catch_memory_errors;
++static long *xmon_fault_jmp[NR_CPUS];
++#define setjmp xmon_setjmp
++#define longjmp xmon_longjmp
++
++/* Breakpoint stuff */
++struct bpt {
++	unsigned long	address;
++	unsigned int	instr[2];
++	atomic_t	ref_count;
++	int		enabled;
++	unsigned long	pad;
++};
++
++/* Bits in bpt.enabled */
++#define BP_IABR_TE	1		/* IABR translation enabled */
++#define BP_IABR		2
++#define BP_TRAP		8
++#define BP_DABR		0x10
++
++#define NBPTS	256
++static struct bpt bpts[NBPTS];
++static struct bpt dabr;
++static struct bpt *iabr;
++static unsigned bpinstr = 0x7fe00008;	/* trap */
++
++#define BP_NUM(bp)	((bp) - bpts + 1)
++
++/* Prototypes */
++static int cmds(struct pt_regs *);
++static int mread(unsigned long, void *, int);
++static int mwrite(unsigned long, void *, int);
++static int handle_fault(struct pt_regs *);
++static void byterev(unsigned char *, int);
++static void memex(void);
++static int bsesc(void);
++static void dump(void);
++static void prdump(unsigned long, long);
++static int ppc_inst_dump(unsigned long, long, int);
++void print_address(unsigned long);
++static void backtrace(struct pt_regs *);
++static void excprint(struct pt_regs *);
++static void prregs(struct pt_regs *);
++static void memops(int);
++static void memlocate(void);
++static void memzcan(void);
++static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
++int skipbl(void);
++int scanhex(unsigned long *valp);
++static void scannl(void);
++static int hexdigit(int);
++void getstring(char *, int);
++static void flush_input(void);
++static int inchar(void);
++static void take_input(char *);
++static unsigned long read_spr(int);
++static void write_spr(int, unsigned long);
++static void super_regs(void);
++static void remove_bpts(void);
++static void insert_bpts(void);
++static void remove_cpu_bpts(void);
++static void insert_cpu_bpts(void);
++static struct bpt *at_breakpoint(unsigned long pc);
++static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
++static int  do_step(struct pt_regs *);
++static void bpt_cmds(void);
++static void cacheflush(void);
++static int  cpu_cmd(void);
++static void csum(void);
++static void bootcmds(void);
++static void proccall(void);
++void dump_segments(void);
++static void symbol_lookup(void);
++static void xmon_print_symbol(unsigned long address, const char *mid,
++			      const char *after);
++static const char *getvecname(unsigned long vec);
++
++extern int print_insn_powerpc(unsigned long, unsigned long, int);
++extern void printf(const char *fmt, ...);
++extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
++extern int xmon_putc(int c, void *f);
++extern int putchar(int ch);
++
++extern void xmon_enter(void);
++extern void xmon_leave(void);
++
++extern int xmon_read_poll(void);
++extern long setjmp(long *);
++extern void longjmp(long *, long);
++extern void xmon_save_regs(struct pt_regs *);
++
++#ifdef CONFIG_PPC64
++#define REG		"%.16lx"
++#define REGS_PER_LINE	4
++#define LAST_VOLATILE	13
++#else
++#define REG		"%.8lx"
++#define REGS_PER_LINE	8
++#define LAST_VOLATILE	12
++#endif
++
++#define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
++
++#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
++			 || ('a' <= (c) && (c) <= 'f') \
++			 || ('A' <= (c) && (c) <= 'F'))
++#define isalnum(c)	(('0' <= (c) && (c) <= '9') \
++			 || ('a' <= (c) && (c) <= 'z') \
++			 || ('A' <= (c) && (c) <= 'Z'))
++#define isspace(c)	(c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
++
++static char *help_string = "\
++Commands:\n\
++  b	show breakpoints\n\
++  bd	set data breakpoint\n\
++  bi	set instruction breakpoint\n\
++  bc	clear breakpoint\n"
++#ifdef CONFIG_SMP
++  "\
++  c	print cpus stopped in xmon\n\
++  c#	try to switch to cpu number h (in hex)\n"
++#endif
++  "\
++  C	checksum\n\
++  d	dump bytes\n\
++  di	dump instructions\n\
++  df	dump float values\n\
++  dd	dump double values\n\
++  e	print exception information\n\
++  f	flush cache\n\
++  la	lookup symbol+offset of specified address\n\
++  ls	lookup address of specified symbol\n\
++  m	examine/change memory\n\
++  mm	move a block of memory\n\
++  ms	set a block of memory\n\
++  md	compare two blocks of memory\n\
++  ml	locate a block of memory\n\
++  mz	zero a block of memory\n\
++  mi	show information about memory allocation\n\
++  p 	call a procedure\n\
++  r	print registers\n\
++  s	single step\n\
++  S	print special registers\n\
++  t	print backtrace\n\
++  x	exit monitor and recover\n\
++  X	exit monitor and dont recover\n"
++#ifdef CONFIG_PPC64
++"  u	dump segment table or SLB\n"
++#endif
++#ifdef CONFIG_PPC_STD_MMU_32
++"  u	dump segment registers\n"
++#endif
++"  ?	help\n"
++"  zr	reboot\n\
++  zh	halt\n"
++;
++
++static struct pt_regs *xmon_regs;
++
++static inline void sync(void)
++{
++	asm volatile("sync; isync");
++}
++
++static inline void store_inst(void *p)
++{
++	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
++}
++
++static inline void cflush(void *p)
++{
++	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
++}
++
++static inline void cinval(void *p)
++{
++	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
++}
++
++/*
++ * Disable surveillance (the service processor watchdog function)
++ * while we are in xmon.
++ * XXX we should re-enable it when we leave. :)
++ */
++#define SURVEILLANCE_TOKEN	9000
++
++static inline void disable_surveillance(void)
++{
++#ifdef CONFIG_PPC_PSERIES
++	/* Since this can't be a module, args should end up below 4GB. */
++	static struct rtas_args args;
++
++	/*
++	 * At this point we have got all the cpus we can into
++	 * xmon, so there is hopefully no other cpu calling RTAS
++	 * at the moment, even though we don't take rtas.lock.
++	 * If we did try to take rtas.lock there would be a
++	 * real possibility of deadlock.
++	 */
++	args.token = rtas_token("set-indicator");
++	if (args.token == RTAS_UNKNOWN_SERVICE)
++		return;
++	args.nargs = 3;
++	args.nret = 1;
++	args.rets = &args.args[3];
++	args.args[0] = SURVEILLANCE_TOKEN;
++	args.args[1] = 0;
++	args.args[2] = 0;
++	enter_rtas(__pa(&args));
++#endif /* CONFIG_PPC_PSERIES */
++}
++
++#ifdef CONFIG_SMP
++static int xmon_speaker;
++
++static void get_output_lock(void)
++{
++	int me = smp_processor_id() + 0x100;
++	int last_speaker = 0, prev;
++	long timeout;
++
++	if (xmon_speaker == me)
++		return;
++	for (;;) {
++		if (xmon_speaker == 0) {
++			last_speaker = cmpxchg(&xmon_speaker, 0, me);
++			if (last_speaker == 0)
++				return;
++		}
++		timeout = 10000000;
++		while (xmon_speaker == last_speaker) {
++			if (--timeout > 0)
++				continue;
++			/* hostile takeover */
++			prev = cmpxchg(&xmon_speaker, last_speaker, me);
++			if (prev == last_speaker)
++				return;
++			break;
++		}
++	}
++}
++
++static void release_output_lock(void)
++{
++	xmon_speaker = 0;
++}
++#endif
++
++int xmon_core(struct pt_regs *regs, int fromipi)
++{
++	int cmd = 0;
++	unsigned long msr;
++	struct bpt *bp;
++	long recurse_jmp[JMP_BUF_LEN];
++	unsigned long offset;
++#ifdef CONFIG_SMP
++	int cpu;
++	int secondary;
++	unsigned long timeout;
++#endif
++
++	msr = mfmsr();
++	mtmsr(msr & ~MSR_EE);	/* disable interrupts */
++
++	bp = in_breakpoint_table(regs->nip, &offset);
++	if (bp != NULL) {
++		regs->nip = bp->address + offset;
++		atomic_dec(&bp->ref_count);
++	}
++
++	remove_cpu_bpts();
++
++#ifdef CONFIG_SMP
++	cpu = smp_processor_id();
++	if (cpu_isset(cpu, cpus_in_xmon)) {
++		get_output_lock();
++		excprint(regs);
++		printf("cpu 0x%x: Exception %lx %s in xmon, "
++		       "returning to main loop\n",
++		       cpu, regs->trap, getvecname(TRAP(regs)));
++		release_output_lock();
++		longjmp(xmon_fault_jmp[cpu], 1);
++	}
++
++	if (setjmp(recurse_jmp) != 0) {
++		if (!in_xmon || !xmon_gate) {
++			get_output_lock();
++			printf("xmon: WARNING: bad recursive fault "
++			       "on cpu 0x%x\n", cpu);
++			release_output_lock();
++			goto waiting;
++		}
++		secondary = !(xmon_taken && cpu == xmon_owner);
++		goto cmdloop;
++	}
++
++	xmon_fault_jmp[cpu] = recurse_jmp;
++	cpu_set(cpu, cpus_in_xmon);
++
++	bp = NULL;
++	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
++		bp = at_breakpoint(regs->nip);
++	if (bp || (regs->msr & MSR_RI) == 0)
++		fromipi = 0;
++
++	if (!fromipi) {
++		get_output_lock();
++		excprint(regs);
++		if (bp) {
++			printf("cpu 0x%x stopped at breakpoint 0x%x (",
++			       cpu, BP_NUM(bp));
++			xmon_print_symbol(regs->nip, " ", ")\n");
++		}
++		if ((regs->msr & MSR_RI) == 0)
++			printf("WARNING: exception is not recoverable, "
++			       "can't continue\n");
++		release_output_lock();
++	}
++
++ waiting:
++	secondary = 1;
++	while (secondary && !xmon_gate) {
++		if (in_xmon == 0) {
++			if (fromipi)
++				goto leave;
++			secondary = test_and_set_bit(0, &in_xmon);
++		}
++		barrier();
++	}
++
++	if (!secondary && !xmon_gate) {
++		/* we are the first cpu to come in */
++		/* interrupt other cpu(s) */
++		int ncpus = num_online_cpus();
++
++		xmon_owner = cpu;
++		mb();
++		if (ncpus > 1) {
++			smp_send_debugger_break(MSG_ALL_BUT_SELF);
++			/* wait for other cpus to come in */
++			for (timeout = 100000000; timeout != 0; --timeout) {
++				if (cpus_weight(cpus_in_xmon) >= ncpus)
++					break;
++				barrier();
++			}
++		}
++		remove_bpts();
++		disable_surveillance();
++		/* for breakpoint or single step, print the current instr. */
++		if (bp || TRAP(regs) == 0xd00)
++			ppc_inst_dump(regs->nip, 1, 0);
++		printf("enter ? for help\n");
++		mb();
++		xmon_gate = 1;
++		barrier();
++	}
++
++ cmdloop:
++	while (in_xmon) {
++		if (secondary) {
++			if (cpu == xmon_owner) {
++				if (!test_and_set_bit(0, &xmon_taken)) {
++					secondary = 0;
++					continue;
++				}
++				/* missed it */
++				while (cpu == xmon_owner)
++					barrier();
++			}
++			barrier();
++		} else {
++			cmd = cmds(regs);
++			if (cmd != 0) {
++				/* exiting xmon */
++				insert_bpts();
++				xmon_gate = 0;
++				wmb();
++				in_xmon = 0;
++				break;
++			}
++			/* have switched to some other cpu */
++			secondary = 1;
++		}
++	}
++ leave:
++	cpu_clear(cpu, cpus_in_xmon);
++	xmon_fault_jmp[cpu] = NULL;
++
++#else
++	/* UP is simple... */
++	if (in_xmon) {
++		printf("Exception %lx %s in xmon, returning to main loop\n",
++		       regs->trap, getvecname(TRAP(regs)));
++		longjmp(xmon_fault_jmp[0], 1);
++	}
++	if (setjmp(recurse_jmp) == 0) {
++		xmon_fault_jmp[0] = recurse_jmp;
++		in_xmon = 1;
++
++		excprint(regs);
++		bp = at_breakpoint(regs->nip);
++		if (bp) {
++			printf("Stopped at breakpoint %x (", BP_NUM(bp));
++			xmon_print_symbol(regs->nip, " ", ")\n");
++		}
++		if ((regs->msr & MSR_RI) == 0)
++			printf("WARNING: exception is not recoverable, "
++			       "can't continue\n");
++		remove_bpts();
++		disable_surveillance();
++		/* for breakpoint or single step, print the current instr. */
++		if (bp || TRAP(regs) == 0xd00)
++			ppc_inst_dump(regs->nip, 1, 0);
++		printf("enter ? for help\n");
++	}
++
++	cmd = cmds(regs);
++
++	insert_bpts();
++	in_xmon = 0;
++#endif
++
++	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
++		bp = at_breakpoint(regs->nip);
++		if (bp != NULL) {
++			int stepped = emulate_step(regs, bp->instr[0]);
++			if (stepped == 0) {
++				regs->nip = (unsigned long) &bp->instr[0];
++				atomic_inc(&bp->ref_count);
++			} else if (stepped < 0) {
++				printf("Couldn't single-step %s instruction\n",
++				    (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
++			}
++		}
++	}
++
++	insert_cpu_bpts();
++
++	mtmsr(msr);		/* restore interrupt enable */
++
++	return cmd != 'X';
++}
++
++int xmon(struct pt_regs *excp)
++{
++	struct pt_regs regs;
++
++	if (excp == NULL) {
++		xmon_save_regs(&regs);
++		excp = &regs;
++	}
++	return xmon_core(excp, 0);
++}
++EXPORT_SYMBOL(xmon);
++
++irqreturn_t
++xmon_irq(int irq, void *d, struct pt_regs *regs)
++{
++	unsigned long flags;
++	local_irq_save(flags);
++	printf("Keyboard interrupt\n");
++	xmon(regs);
++	local_irq_restore(flags);
++	return IRQ_HANDLED;
++}
++
++int xmon_bpt(struct pt_regs *regs)
++{
++	struct bpt *bp;
++	unsigned long offset;
++
++	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
++		return 0;
++
++	/* Are we at the trap at bp->instr[1] for some bp? */
++	bp = in_breakpoint_table(regs->nip, &offset);
++	if (bp != NULL && offset == 4) {
++		regs->nip = bp->address + 4;
++		atomic_dec(&bp->ref_count);
++		return 1;
++	}
++
++	/* Are we at a breakpoint? */
++	bp = at_breakpoint(regs->nip);
++	if (!bp)
++		return 0;
++
++	xmon_core(regs, 0);
++
++	return 1;
++}
++
++int xmon_sstep(struct pt_regs *regs)
++{
++	if (user_mode(regs))
++		return 0;
++	xmon_core(regs, 0);
++	return 1;
++}
++
++int xmon_dabr_match(struct pt_regs *regs)
++{
++	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
++		return 0;
++	if (dabr.enabled == 0)
++		return 0;
++	xmon_core(regs, 0);
++	return 1;
++}
++
++int xmon_iabr_match(struct pt_regs *regs)
++{
++	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
++		return 0;
++	if (iabr == 0)
++		return 0;
++	xmon_core(regs, 0);
++	return 1;
++}
++
++int xmon_ipi(struct pt_regs *regs)
++{
++#ifdef CONFIG_SMP
++	if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
++		xmon_core(regs, 1);
++#endif
++	return 0;
++}
++
++int xmon_fault_handler(struct pt_regs *regs)
++{
++	struct bpt *bp;
++	unsigned long offset;
++
++	if (in_xmon && catch_memory_errors)
++		handle_fault(regs);	/* doesn't return */
++
++	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
++		bp = in_breakpoint_table(regs->nip, &offset);
++		if (bp != NULL) {
++			regs->nip = bp->address + offset;
++			atomic_dec(&bp->ref_count);
++		}
++	}
++
++	return 0;
++}
++
++static struct bpt *at_breakpoint(unsigned long pc)
++{
++	int i;
++	struct bpt *bp;
++
++	bp = bpts;
++	for (i = 0; i < NBPTS; ++i, ++bp)
++		if (bp->enabled && pc == bp->address)
++			return bp;
++	return NULL;
++}
++
++static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
++{
++	unsigned long off;
++
++	off = nip - (unsigned long) bpts;
++	if (off >= sizeof(bpts))
++		return NULL;
++	off %= sizeof(struct bpt);
++	if (off != offsetof(struct bpt, instr[0])
++	    && off != offsetof(struct bpt, instr[1]))
++		return NULL;
++	*offp = off - offsetof(struct bpt, instr[0]);
++	return (struct bpt *) (nip - off);
++}
++
++static struct bpt *new_breakpoint(unsigned long a)
++{
++	struct bpt *bp;
++
++	a &= ~3UL;
++	bp = at_breakpoint(a);
++	if (bp)
++		return bp;
++
++	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
++		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
++			bp->address = a;
++			bp->instr[1] = bpinstr;
++			store_inst(&bp->instr[1]);
++			return bp;
++		}
++	}
++
++	printf("Sorry, no free breakpoints.  Please clear one first.\n");
++	return NULL;
++}
++
++static void insert_bpts(void)
++{
++	int i;
++	struct bpt *bp;
++
++	bp = bpts;
++	for (i = 0; i < NBPTS; ++i, ++bp) {
++		if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
++			continue;
++		if (mread(bp->address, &bp->instr[0], 4) != 4) {
++			printf("Couldn't read instruction at %lx, "
++			       "disabling breakpoint there\n", bp->address);
++			bp->enabled = 0;
++			continue;
++		}
++		if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
++			printf("Breakpoint at %lx is on an mtmsrd or rfid "
++			       "instruction, disabling it\n", bp->address);
++			bp->enabled = 0;
++			continue;
++		}
++		store_inst(&bp->instr[0]);
++		if (bp->enabled & BP_IABR)
++			continue;
++		if (mwrite(bp->address, &bpinstr, 4) != 4) {
++			printf("Couldn't write instruction at %lx, "
++			       "disabling breakpoint there\n", bp->address);
++			bp->enabled &= ~BP_TRAP;
++			continue;
++		}
++		store_inst((void *)bp->address);
++	}
++}
++
++static void insert_cpu_bpts(void)
++{
++	if (dabr.enabled)
++		set_dabr(dabr.address | (dabr.enabled & 7));
++	if (iabr && cpu_has_feature(CPU_FTR_IABR))
++		mtspr(SPRN_IABR, iabr->address
++			 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
++}
++
++static void remove_bpts(void)
++{
++	int i;
++	struct bpt *bp;
++	unsigned instr;
++
++	bp = bpts;
++	for (i = 0; i < NBPTS; ++i, ++bp) {
++		if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
++			continue;
++		if (mread(bp->address, &instr, 4) == 4
++		    && instr == bpinstr
++		    && mwrite(bp->address, &bp->instr, 4) != 4)
++			printf("Couldn't remove breakpoint at %lx\n",
++			       bp->address);
++		else
++			store_inst((void *)bp->address);
++	}
++}
++
++static void remove_cpu_bpts(void)
++{
++	set_dabr(0);
++	if (cpu_has_feature(CPU_FTR_IABR))
++		mtspr(SPRN_IABR, 0);
++}
++
++/* Command interpreting routine */
++static char *last_cmd;
++
++static int
++cmds(struct pt_regs *excp)
++{
++	int cmd = 0;
++
++	last_cmd = NULL;
++	xmon_regs = excp;
++	for(;;) {
++#ifdef CONFIG_SMP
++		printf("%x:", smp_processor_id());
++#endif /* CONFIG_SMP */
++		printf("mon> ");
++		fflush(stdout);
++		flush_input();
++		termch = 0;
++		cmd = skipbl();
++		if( cmd == '\n' ) {
++			if (last_cmd == NULL)
++				continue;
++			take_input(last_cmd);
++			last_cmd = NULL;
++			cmd = inchar();
++		}
++		switch (cmd) {
++		case 'm':
++			cmd = inchar();
++			switch (cmd) {
++			case 'm':
++			case 's':
++			case 'd':
++				memops(cmd);
++				break;
++			case 'l':
++				memlocate();
++				break;
++			case 'z':
++				memzcan();
++				break;
++			case 'i':
++				show_mem();
++				break;
++			default:
++				termch = cmd;
++				memex();
++			}
++			break;
++		case 'd':
++			dump();
++			break;
++		case 'l':
++			symbol_lookup();
++			break;
++		case 'r':
++			prregs(excp);	/* print regs */
++			break;
++		case 'e':
++			excprint(excp);
++			break;
++		case 'S':
++			super_regs();
++			break;
++		case 't':
++			backtrace(excp);
++			break;
++		case 'f':
++			cacheflush();
++			break;
++		case 's':
++			if (do_step(excp))
++				return cmd;
++			break;
++		case 'x':
++		case 'X':
++		case EOF:
++			return cmd;
++		case '?':
++			printf(help_string);
++			break;
++		case 'b':
++			bpt_cmds();
++			break;
++		case 'C':
++			csum();
++			break;
++		case 'c':
++			if (cpu_cmd())
++				return 0;
++			break;
++		case 'z':
++			bootcmds();
++			break;
++		case 'p':
++			proccall();
++			break;
++#ifdef CONFIG_PPC_STD_MMU
++		case 'u':
++			dump_segments();
++			break;
++#endif
++		default:
++			printf("Unrecognized command: ");
++		        do {
++				if (' ' < cmd && cmd <= '~')
++					putchar(cmd);
++				else
++					printf("\\x%x", cmd);
++				cmd = inchar();
++		        } while (cmd != '\n'); 
++			printf(" (type ? for help)\n");
++			break;
++		}
++	}
++}
++
++/*
++ * Step a single instruction.
++ * Some instructions we emulate, others we execute with MSR_SE set.
++ */
++static int do_step(struct pt_regs *regs)
++{
++	unsigned int instr;
++	int stepped;
++
++	/* check we are in 64-bit kernel mode, translation enabled */
++	if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
++		if (mread(regs->nip, &instr, 4) == 4) {
++			stepped = emulate_step(regs, instr);
++			if (stepped < 0) {
++				printf("Couldn't single-step %s instruction\n",
++				       (IS_RFID(instr)? "rfid": "mtmsrd"));
++				return 0;
++			}
++			if (stepped > 0) {
++				regs->trap = 0xd00 | (regs->trap & 1);
++				printf("stepped to ");
++				xmon_print_symbol(regs->nip, " ", "\n");
++				ppc_inst_dump(regs->nip, 1, 0);
++				return 0;
++			}
++		}
++	}
++	regs->msr |= MSR_SE;
++	return 1;
++}
++
++static void bootcmds(void)
++{
++	int cmd;
++
++	cmd = inchar();
++	if (cmd == 'r')
++		ppc_md.restart(NULL);
++	else if (cmd == 'h')
++		ppc_md.halt();
++	else if (cmd == 'p')
++		ppc_md.power_off();
++}
++
++static int cpu_cmd(void)
++{
++#ifdef CONFIG_SMP
++	unsigned long cpu;
++	int timeout;
++	int count;
++
++	if (!scanhex(&cpu)) {
++		/* print cpus waiting or in xmon */
++		printf("cpus stopped:");
++		count = 0;
++		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
++			if (cpu_isset(cpu, cpus_in_xmon)) {
++				if (count == 0)
++					printf(" %x", cpu);
++				++count;
++			} else {
++				if (count > 1)
++					printf("-%x", cpu - 1);
++				count = 0;
++			}
++		}
++		if (count > 1)
++			printf("-%x", NR_CPUS - 1);
++		printf("\n");
++		return 0;
++	}
++	/* try to switch to cpu specified */
++	if (!cpu_isset(cpu, cpus_in_xmon)) {
++		printf("cpu 0x%x isn't in xmon\n", cpu);
++		return 0;
++	}
++	xmon_taken = 0;
++	mb();
++	xmon_owner = cpu;
++	timeout = 10000000;
++	while (!xmon_taken) {
++		if (--timeout == 0) {
++			if (test_and_set_bit(0, &xmon_taken))
++				break;
++			/* take control back */
++			mb();
++			xmon_owner = smp_processor_id();
++			printf("cpu %u didn't take control\n", cpu);
++			return 0;
++		}
++		barrier();
++	}
++	return 1;
++#else
++	return 0;
++#endif /* CONFIG_SMP */
++}
++
++static unsigned short fcstab[256] = {
++	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
++	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
++	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
++	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
++	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
++	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
++	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
++	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
++	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
++	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
++	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
++	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
++	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
++	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
++	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
++	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
++	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
++	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
++	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
++	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
++	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
++	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
++	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
++	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
++	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
++	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
++	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
++	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
++	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
++	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
++	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
++	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
++};
++
++#define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
++
++static void
++csum(void)
++{
++	unsigned int i;
++	unsigned short fcs;
++	unsigned char v;
++
++	if (!scanhex(&adrs))
++		return;
++	if (!scanhex(&ncsum))
++		return;
++	fcs = 0xffff;
++	for (i = 0; i < ncsum; ++i) {
++		if (mread(adrs+i, &v, 1) == 0) {
++			printf("csum stopped at %x\n", adrs+i);
++			break;
++		}
++		fcs = FCS(fcs, v);
++	}
++	printf("%x\n", fcs);
++}
++
++/*
++ * Check if this is a suitable place to put a breakpoint.
++ */
++static long check_bp_loc(unsigned long addr)
++{
++	unsigned int instr;
++
++	addr &= ~3;
++	if (addr < KERNELBASE) {
++		printf("Breakpoints may only be placed at kernel addresses\n");
++		return 0;
++	}
++	if (!mread(addr, &instr, sizeof(instr))) {
++		printf("Can't read instruction at address %lx\n", addr);
++		return 0;
++	}
++	if (IS_MTMSRD(instr) || IS_RFID(instr)) {
++		printf("Breakpoints may not be placed on mtmsrd or rfid "
++		       "instructions\n");
++		return 0;
++	}
++	return 1;
++}
++
++static char *breakpoint_help_string = 
++    "Breakpoint command usage:\n"
++    "b                show breakpoints\n"
++    "b <addr> [cnt]   set breakpoint at given instr addr\n"
++    "bc               clear all breakpoints\n"
++    "bc <n/addr>      clear breakpoint number n or at addr\n"
++    "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
++    "bd <addr> [cnt]  set hardware data breakpoint\n"
++    "";
++
++static void
++bpt_cmds(void)
++{
++	int cmd;
++	unsigned long a;
++	int mode, i;
++	struct bpt *bp;
++	const char badaddr[] = "Only kernel addresses are permitted "
++		"for breakpoints\n";
++
++	cmd = inchar();
++	switch (cmd) {
++#ifndef CONFIG_8xx
++	case 'd':	/* bd - hardware data breakpoint */
++		mode = 7;
++		cmd = inchar();
++		if (cmd == 'r')
++			mode = 5;
++		else if (cmd == 'w')
++			mode = 6;
++		else
++			termch = cmd;
++		dabr.address = 0;
++		dabr.enabled = 0;
++		if (scanhex(&dabr.address)) {
++			if (dabr.address < KERNELBASE) {
++				printf(badaddr);
++				break;
++			}
++			dabr.address &= ~7;
++			dabr.enabled = mode | BP_DABR;
++		}
++		break;
++
++	case 'i':	/* bi - hardware instr breakpoint */
++		if (!cpu_has_feature(CPU_FTR_IABR)) {
++			printf("Hardware instruction breakpoint "
++			       "not supported on this cpu\n");
++			break;
++		}
++		if (iabr) {
++			iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
++			iabr = NULL;
++		}
++		if (!scanhex(&a))
++			break;
++		if (!check_bp_loc(a))
++			break;
++		bp = new_breakpoint(a);
++		if (bp != NULL) {
++			bp->enabled |= BP_IABR | BP_IABR_TE;
++			iabr = bp;
++		}
++		break;
++#endif
++
++	case 'c':
++		if (!scanhex(&a)) {
++			/* clear all breakpoints */
++			for (i = 0; i < NBPTS; ++i)
++				bpts[i].enabled = 0;
++			iabr = NULL;
++			dabr.enabled = 0;
++			printf("All breakpoints cleared\n");
++			break;
++		}
++
++		if (a <= NBPTS && a >= 1) {
++			/* assume a breakpoint number */
++			bp = &bpts[a-1];	/* bp nums are 1 based */
++		} else {
++			/* assume a breakpoint address */
++			bp = at_breakpoint(a);
++			if (bp == 0) {
++				printf("No breakpoint at %x\n", a);
++				break;
++			}
++		}
++
++		printf("Cleared breakpoint %x (", BP_NUM(bp));
++		xmon_print_symbol(bp->address, " ", ")\n");
++		bp->enabled = 0;
++		break;
++
++	default:
++		termch = cmd;
++	        cmd = skipbl();
++		if (cmd == '?') {
++			printf(breakpoint_help_string);
++			break;
++		}
++		termch = cmd;
++		if (!scanhex(&a)) {
++			/* print all breakpoints */
++			printf("   type            address\n");
++			if (dabr.enabled) {
++				printf("   data   "REG"  [", dabr.address);
++				if (dabr.enabled & 1)
++					printf("r");
++				if (dabr.enabled & 2)
++					printf("w");
++				printf("]\n");
++			}
++			for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
++				if (!bp->enabled)
++					continue;
++				printf("%2x %s   ", BP_NUM(bp),
++				    (bp->enabled & BP_IABR)? "inst": "trap");
++				xmon_print_symbol(bp->address, "  ", "\n");
++			}
++			break;
++		}
++
++		if (!check_bp_loc(a))
++			break;
++		bp = new_breakpoint(a);
++		if (bp != NULL)
++			bp->enabled |= BP_TRAP;
++		break;
++	}
++}
++
++/* Very cheap human name for vector lookup. */
++static
++const char *getvecname(unsigned long vec)
++{
++	char *ret;
++
++	switch (vec) {
++	case 0x100:	ret = "(System Reset)"; break;
++	case 0x200:	ret = "(Machine Check)"; break;
++	case 0x300:	ret = "(Data Access)"; break;
++	case 0x380:	ret = "(Data SLB Access)"; break;
++	case 0x400:	ret = "(Instruction Access)"; break;
++	case 0x480:	ret = "(Instruction SLB Access)"; break;
++	case 0x500:	ret = "(Hardware Interrupt)"; break;
++	case 0x600:	ret = "(Alignment)"; break;
++	case 0x700:	ret = "(Program Check)"; break;
++	case 0x800:	ret = "(FPU Unavailable)"; break;
++	case 0x900:	ret = "(Decrementer)"; break;
++	case 0xc00:	ret = "(System Call)"; break;
++	case 0xd00:	ret = "(Single Step)"; break;
++	case 0xf00:	ret = "(Performance Monitor)"; break;
++	case 0xf20:	ret = "(Altivec Unavailable)"; break;
++	case 0x1300:	ret = "(Instruction Breakpoint)"; break;
++	default: ret = "";
++	}
++	return ret;
++}
++
++static void get_function_bounds(unsigned long pc, unsigned long *startp,
++				unsigned long *endp)
++{
++	unsigned long size, offset;
++	const char *name;
++	char *modname;
++
++	*startp = *endp = 0;
++	if (pc == 0)
++		return;
++	if (setjmp(bus_error_jmp) == 0) {
++		catch_memory_errors = 1;
++		sync();
++		name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
++		if (name != NULL) {
++			*startp = pc - offset;
++			*endp = pc - offset + size;
++		}
++		sync();
++	}
++	catch_memory_errors = 0;
++}
++
++static int xmon_depth_to_print = 64;
++
++#ifdef CONFIG_PPC64
++#define LRSAVE_OFFSET		0x10
++#define REG_FRAME_MARKER	0x7265677368657265ul	/* "regshere" */
++#define MARKER_OFFSET		0x60
++#define REGS_OFFSET		0x70
++#else
++#define LRSAVE_OFFSET		4
++#define REG_FRAME_MARKER	0x72656773
++#define MARKER_OFFSET		8
++#define REGS_OFFSET		16
++#endif
++
++static void xmon_show_stack(unsigned long sp, unsigned long lr,
++			    unsigned long pc)
++{
++	unsigned long ip;
++	unsigned long newsp;
++	unsigned long marker;
++	int count = 0;
++	struct pt_regs regs;
++
++	do {
++		if (sp < PAGE_OFFSET) {
++			if (sp != 0)
++				printf("SP (%lx) is in userspace\n", sp);
++			break;
++		}
++
++		if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
++		    || !mread(sp, &newsp, sizeof(unsigned long))) {
++			printf("Couldn't read stack frame at %lx\n", sp);
++			break;
++		}
++
++		/*
++		 * For the first stack frame, try to work out if
++		 * LR and/or the saved LR value in the bottommost
++		 * stack frame are valid.
++		 */
++		if ((pc | lr) != 0) {
++			unsigned long fnstart, fnend;
++			unsigned long nextip;
++			int printip = 1;
++
++			get_function_bounds(pc, &fnstart, &fnend);
++			nextip = 0;
++			if (newsp > sp)
++				mread(newsp + LRSAVE_OFFSET, &nextip,
++				      sizeof(unsigned long));
++			if (lr == ip) {
++				if (lr < PAGE_OFFSET
++				    || (fnstart <= lr && lr < fnend))
++					printip = 0;
++			} else if (lr == nextip) {
++				printip = 0;
++			} else if (lr >= PAGE_OFFSET
++				   && !(fnstart <= lr && lr < fnend)) {
++				printf("[link register   ] ");
++				xmon_print_symbol(lr, " ", "\n");
++			}
++			if (printip) {
++				printf("["REG"] ", sp);
++				xmon_print_symbol(ip, " ", " (unreliable)\n");
++			}
++			pc = lr = 0;
++
++		} else {
++			printf("["REG"] ", sp);
++			xmon_print_symbol(ip, " ", "\n");
++		}
++
++		/* Look for "regshere" marker to see if this is
++		   an exception frame. */
++		if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
++		    && marker == REG_FRAME_MARKER) {
++			if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
++			    != sizeof(regs)) {
++				printf("Couldn't read registers at %lx\n",
++				       sp + REGS_OFFSET);
++				break;
++			}
++                        printf("--- Exception: %lx %s at ", regs.trap,
++			       getvecname(TRAP(&regs)));
++			pc = regs.nip;
++			lr = regs.link;
++			xmon_print_symbol(pc, " ", "\n");
++		}
++
++		if (newsp == 0)
++			break;
++
++		sp = newsp;
++	} while (count++ < xmon_depth_to_print);
++}
++
++static void backtrace(struct pt_regs *excp)
++{
++	unsigned long sp;
++
++	if (scanhex(&sp))
++		xmon_show_stack(sp, 0, 0);
++	else
++		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
++	scannl();
++}
++
++static void print_bug_trap(struct pt_regs *regs)
++{
++	struct bug_entry *bug;
++	unsigned long addr;
++
++	if (regs->msr & MSR_PR)
++		return;		/* not in kernel */
++	addr = regs->nip;	/* address of trap instruction */
++	if (addr < PAGE_OFFSET)
++		return;
++	bug = find_bug(regs->nip);
++	if (bug == NULL)
++		return;
++	if (bug->line & BUG_WARNING_TRAP)
++		return;
++
++	printf("kernel BUG in %s at %s:%d!\n",
++	       bug->function, bug->file, (unsigned int)bug->line);
++}
++
++void excprint(struct pt_regs *fp)
++{
++	unsigned long trap;
++
++#ifdef CONFIG_SMP
++	printf("cpu 0x%x: ", smp_processor_id());
++#endif /* CONFIG_SMP */
++
++	trap = TRAP(fp);
++	printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
++	printf("    pc: ");
++	xmon_print_symbol(fp->nip, ": ", "\n");
++
++	printf("    lr: ", fp->link);
++	xmon_print_symbol(fp->link, ": ", "\n");
++
++	printf("    sp: %lx\n", fp->gpr[1]);
++	printf("   msr: %lx\n", fp->msr);
++
++	if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
++		printf("   dar: %lx\n", fp->dar);
++		if (trap != 0x380)
++			printf(" dsisr: %lx\n", fp->dsisr);
++	}
++
++	printf("  current = 0x%lx\n", current);
++#ifdef CONFIG_PPC64
++	printf("  paca    = 0x%lx\n", get_paca());
++#endif
++	if (current) {
++		printf("    pid   = %ld, comm = %s\n",
++		       current->pid, current->comm);
++	}
++
++	if (trap == 0x700)
++		print_bug_trap(fp);
++}
++
++void prregs(struct pt_regs *fp)
++{
++	int n, trap;
++	unsigned long base;
++	struct pt_regs regs;
++
++	if (scanhex(&base)) {
++		if (setjmp(bus_error_jmp) == 0) {
++			catch_memory_errors = 1;
++			sync();
++			regs = *(struct pt_regs *)base;
++			sync();
++			__delay(200);
++		} else {
++			catch_memory_errors = 0;
++			printf("*** Error reading registers from "REG"\n",
++			       base);
++			return;
++		}
++		catch_memory_errors = 0;
++		fp = &regs;
++	}
++
++#ifdef CONFIG_PPC64
++	if (FULL_REGS(fp)) {
++		for (n = 0; n < 16; ++n)
++			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
++			       n, fp->gpr[n], n+16, fp->gpr[n+16]);
++	} else {
++		for (n = 0; n < 7; ++n)
++			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
++			       n, fp->gpr[n], n+7, fp->gpr[n+7]);
++	}
++#else
++	for (n = 0; n < 32; ++n) {
++		printf("R%.2d = %.8x%s", n, fp->gpr[n],
++		       (n & 3) == 3? "\n": "   ");
++		if (n == 12 && !FULL_REGS(fp)) {
++			printf("\n");
++			break;
++		}
++	}
++#endif
++	printf("pc  = ");
++	xmon_print_symbol(fp->nip, " ", "\n");
++	printf("lr  = ");
++	xmon_print_symbol(fp->link, " ", "\n");
++	printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
++	printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
++	       fp->ctr, fp->xer, fp->trap);
++	trap = TRAP(fp);
++	if (trap == 0x300 || trap == 0x380 || trap == 0x600)
++		printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
++}
++
++void cacheflush(void)
++{
++	int cmd;
++	unsigned long nflush;
++
++	cmd = inchar();
++	if (cmd != 'i')
++		termch = cmd;
++	scanhex((void *)&adrs);
++	if (termch != '\n')
++		termch = 0;
++	nflush = 1;
++	scanhex(&nflush);
++	nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
++	if (setjmp(bus_error_jmp) == 0) {
++		catch_memory_errors = 1;
++		sync();
++
++		if (cmd != 'i') {
++			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
++				cflush((void *) adrs);
++		} else {
++			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
++				cinval((void *) adrs);
++		}
++		sync();
++		/* wait a little while to see if we get a machine check */
++		__delay(200);
++	}
++	catch_memory_errors = 0;
++}
++
++unsigned long
++read_spr(int n)
++{
++	unsigned int instrs[2];
++	unsigned long (*code)(void);
++	unsigned long opd[3];
++	unsigned long ret = -1UL;
++
++	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
++	instrs[1] = 0x4e800020;
++	opd[0] = (unsigned long)instrs;
++	opd[1] = 0;
++	opd[2] = 0;
++	store_inst(instrs);
++	store_inst(instrs+1);
++	code = (unsigned long (*)(void)) opd;
++
++	if (setjmp(bus_error_jmp) == 0) {
++		catch_memory_errors = 1;
++		sync();
++
++		ret = code();
++
++		sync();
++		/* wait a little while to see if we get a machine check */
++		__delay(200);
++		n = size;
++	}
++
++	return ret;
++}
++
++void
++write_spr(int n, unsigned long val)
++{
++	unsigned int instrs[2];
++	unsigned long (*code)(unsigned long);
++	unsigned long opd[3];
++
++	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
++	instrs[1] = 0x4e800020;
++	opd[0] = (unsigned long)instrs;
++	opd[1] = 0;
++	opd[2] = 0;
++	store_inst(instrs);
++	store_inst(instrs+1);
++	code = (unsigned long (*)(unsigned long)) opd;
++
++	if (setjmp(bus_error_jmp) == 0) {
++		catch_memory_errors = 1;
++		sync();
++
++		code(val);
++
++		sync();
++		/* wait a little while to see if we get a machine check */
++		__delay(200);
++		n = size;
++	}
++}
++
++static unsigned long regno;
++extern char exc_prolog;
++extern char dec_exc;
++
++void super_regs(void)
++{
++	int cmd;
++	unsigned long val;
++#ifdef CONFIG_PPC_ISERIES
++	struct paca_struct *ptrPaca = NULL;
++	struct lppaca *ptrLpPaca = NULL;
++	struct ItLpRegSave *ptrLpRegSave = NULL;
++#endif
++
++	cmd = skipbl();
++	if (cmd == '\n') {
++	        unsigned long sp, toc;
++		asm("mr %0,1" : "=r" (sp) :);
++		asm("mr %0,2" : "=r" (toc) :);
++
++		printf("msr  = "REG"  sprg0= "REG"\n",
++		       mfmsr(), mfspr(SPRN_SPRG0));
++		printf("pvr  = "REG"  sprg1= "REG"\n",
++		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 
++		printf("dec  = "REG"  sprg2= "REG"\n",
++		       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
++		printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
++		printf("toc  = "REG"  dar  = "REG"\n", toc, mfspr(SPRN_DAR));
++#ifdef CONFIG_PPC_ISERIES
++		// Dump out relevant Paca data areas.
++		printf("Paca: \n");
++		ptrPaca = get_paca();
++    
++		printf("  Local Processor Control Area (LpPaca): \n");
++		ptrLpPaca = ptrPaca->lppaca_ptr;
++		printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",
++		       ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
++		printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
++		       ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
++		printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
++    
++		printf("  Local Processor Register Save Area (LpRegSave): \n");
++		ptrLpRegSave = ptrPaca->reg_save_ptr;
++		printf("    Saved Sprg0=%.16lx  Saved Sprg1=%.16lx \n",
++		       ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
++		printf("    Saved Sprg2=%.16lx  Saved Sprg3=%.16lx \n",
++		       ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
++		printf("    Saved Msr  =%.16lx  Saved Nia  =%.16lx \n",
++		       ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
++#endif
++
++		return;
++	}
++
++	scanhex(&regno);
++	switch (cmd) {
++	case 'w':
++		val = read_spr(regno);
++		scanhex(&val);
++		write_spr(regno, val);
++		/* fall through */
++	case 'r':
++		printf("spr %lx = %lx\n", regno, read_spr(regno));
++		break;
++	}
++	scannl();
++}
++
++/*
++ * Stuff for reading and writing memory safely
++ */
++int
++mread(unsigned long adrs, void *buf, int size)
++{
++	volatile int n;
++	char *p, *q;
++
++	n = 0;
++	if (setjmp(bus_error_jmp) == 0) {
++		catch_memory_errors = 1;
++		sync();
++		p = (char *)adrs;
++		q = (char *)buf;
++		switch (size) {
++		case 2:
++			*(u16 *)q = *(u16 *)p;
++			break;
++		case 4:
++			*(u32 *)q = *(u32 *)p;
++			break;
++		case 8:
++			*(u64 *)q = *(u64 *)p;
++			break;
++		default:
++			for( ; n < size; ++n) {
++				*q++ = *p++;
++				sync();
++			}
++		}
++		sync();
++		/* wait a little while to see if we get a machine check */
++		__delay(200);
++		n = size;
++	}
++	catch_memory_errors = 0;
++	return n;
++}
++
++int
++mwrite(unsigned long adrs, void *buf, int size)
++{
++	volatile int n;
++	char *p, *q;
++
++	n = 0;
++	if (setjmp(bus_error_jmp) == 0) {
++		catch_memory_errors = 1;
++		sync();
++		p = (char *) adrs;
++		q = (char *) buf;
++		switch (size) {
++		case 2:
++			*(u16 *)p = *(u16 *)q;
++			break;
++		case 4:
++			*(u32 *)p = *(u32 *)q;
++			break;
++		case 8:
++			*(u64 *)p = *(u64 *)q;
++			break;
++		default:
++			for ( ; n < size; ++n) {
++				*p++ = *q++;
++				sync();
++			}
++		}
++		sync();
++		/* wait a little while to see if we get a machine check */
++		__delay(200);
++		n = size;
++	} else {
++		printf("*** Error writing address %x\n", adrs + n);
++	}
++	catch_memory_errors = 0;
++	return n;
++}
++
++static int fault_type;
++static int fault_except;
++static char *fault_chars[] = { "--", "**", "##" };
++
++static int handle_fault(struct pt_regs *regs)
++{
++	fault_except = TRAP(regs);
++	switch (TRAP(regs)) {
++	case 0x200:
++		fault_type = 0;
++		break;
++	case 0x300:
++	case 0x380:
++		fault_type = 1;
++		break;
++	default:
++		fault_type = 2;
++	}
++
++	longjmp(bus_error_jmp, 1);
++
++	return 0;
++}
++
++#define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
++
++void
++byterev(unsigned char *val, int size)
++{
++	int t;
++	
++	switch (size) {
++	case 2:
++		SWAP(val[0], val[1], t);
++		break;
++	case 4:
++		SWAP(val[0], val[3], t);
++		SWAP(val[1], val[2], t);
++		break;
++	case 8: /* is there really any use for this? */
++		SWAP(val[0], val[7], t);
++		SWAP(val[1], val[6], t);
++		SWAP(val[2], val[5], t);
++		SWAP(val[3], val[4], t);
++		break;
++	}
++}
++
++static int brev;
++static int mnoread;
++
++static char *memex_help_string = 
++    "Memory examine command usage:\n"
++    "m [addr] [flags] examine/change memory\n"
++    "  addr is optional.  will start where left off.\n"
++    "  flags may include chars from this set:\n"
++    "    b   modify by bytes (default)\n"
++    "    w   modify by words (2 byte)\n"
++    "    l   modify by longs (4 byte)\n"
++    "    d   modify by doubleword (8 byte)\n"
++    "    r   toggle reverse byte order mode\n"
++    "    n   do not read memory (for i/o spaces)\n"
++    "    .   ok to read (default)\n"
++    "NOTE: flags are saved as defaults\n"
++    "";
++
++static char *memex_subcmd_help_string = 
++    "Memory examine subcommands:\n"
++    "  hexval   write this val to current location\n"
++    "  'string' write chars from string to this location\n"
++    "  '        increment address\n"
++    "  ^        decrement address\n"
++    "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
++    "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
++    "  `        clear no-read flag\n"
++    "  ;        stay at this addr\n"
++    "  v        change to byte mode\n"
++    "  w        change to word (2 byte) mode\n"
++    "  l        change to long (4 byte) mode\n"
++    "  u        change to doubleword (8 byte) mode\n"
++    "  m addr   change current addr\n"
++    "  n        toggle no-read flag\n"
++    "  r        toggle byte reverse flag\n"
++    "  < count  back up count bytes\n"
++    "  > count  skip forward count bytes\n"
++    "  x        exit this mode\n"
++    "";
++
++void
++memex(void)
++{
++	int cmd, inc, i, nslash;
++	unsigned long n;
++	unsigned char val[16];
++
++	scanhex((void *)&adrs);
++	cmd = skipbl();
++	if (cmd == '?') {
++		printf(memex_help_string);
++		return;
++	} else {
++		termch = cmd;
++	}
++	last_cmd = "m\n";
++	while ((cmd = skipbl()) != '\n') {
++		switch( cmd ){
++		case 'b':	size = 1;	break;
++		case 'w':	size = 2;	break;
++		case 'l':	size = 4;	break;
++		case 'd':	size = 8;	break;
++		case 'r': 	brev = !brev;	break;
++		case 'n':	mnoread = 1;	break;
++		case '.':	mnoread = 0;	break;
++		}
++	}
++	if( size <= 0 )
++		size = 1;
++	else if( size > 8 )
++		size = 8;
++	for(;;){
++		if (!mnoread)
++			n = mread(adrs, val, size);
++		printf("%.16x%c", adrs, brev? 'r': ' ');
++		if (!mnoread) {
++			if (brev)
++				byterev(val, size);
++			putchar(' ');
++			for (i = 0; i < n; ++i)
++				printf("%.2x", val[i]);
++			for (; i < size; ++i)
++				printf("%s", fault_chars[fault_type]);
++		}
++		putchar(' ');
++		inc = size;
++		nslash = 0;
++		for(;;){
++			if( scanhex(&n) ){
++				for (i = 0; i < size; ++i)
++					val[i] = n >> (i * 8);
++				if (!brev)
++					byterev(val, size);
++				mwrite(adrs, val, size);
++				inc = size;
++			}
++			cmd = skipbl();
++			if (cmd == '\n')
++				break;
++			inc = 0;
++			switch (cmd) {
++			case '\'':
++				for(;;){
++					n = inchar();
++					if( n == '\\' )
++						n = bsesc();
++					else if( n == '\'' )
++						break;
++					for (i = 0; i < size; ++i)
++						val[i] = n >> (i * 8);
++					if (!brev)
++						byterev(val, size);
++					mwrite(adrs, val, size);
++					adrs += size;
++				}
++				adrs -= size;
++				inc = size;
++				break;
++			case ',':
++				adrs += size;
++				break;
++			case '.':
++				mnoread = 0;
++				break;
++			case ';':
++				break;
++			case 'x':
++			case EOF:
++				scannl();
++				return;
++			case 'b':
++			case 'v':
++				size = 1;
++				break;
++			case 'w':
++				size = 2;
++				break;
++			case 'l':
++				size = 4;
++				break;
++			case 'u':
++				size = 8;
++				break;
++			case '^':
++				adrs -= size;
++				break;
++				break;
++			case '/':
++				if (nslash > 0)
++					adrs -= 1 << nslash;
++				else
++					nslash = 0;
++				nslash += 4;
++				adrs += 1 << nslash;
++				break;
++			case '\\':
++				if (nslash < 0)
++					adrs += 1 << -nslash;
++				else
++					nslash = 0;
++				nslash -= 4;
++				adrs -= 1 << -nslash;
++				break;
++			case 'm':
++				scanhex((void *)&adrs);
++				break;
++			case 'n':
++				mnoread = 1;
++				break;
++			case 'r':
++				brev = !brev;
++				break;
++			case '<':
++				n = size;
++				scanhex(&n);
++				adrs -= n;
++				break;
++			case '>':
++				n = size;
++				scanhex(&n);
++				adrs += n;
++				break;
++			case '?':
++				printf(memex_subcmd_help_string);
++				break;
++			}
++		}
++		adrs += inc;
++	}
++}
++
++int
++bsesc(void)
++{
++	int c;
++
++	c = inchar();
++	switch( c ){
++	case 'n':	c = '\n';	break;
++	case 'r':	c = '\r';	break;
++	case 'b':	c = '\b';	break;
++	case 't':	c = '\t';	break;
++	}
++	return c;
++}
++
++#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
++			 || ('a' <= (c) && (c) <= 'f') \
++			 || ('A' <= (c) && (c) <= 'F'))
++void
++dump(void)
++{
++	int c;
++
++	c = inchar();
++	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
++		termch = c;
++	scanhex((void *)&adrs);
++	if (termch != '\n')
++		termch = 0;
++	if (c == 'i') {
++		scanhex(&nidump);
++		if (nidump == 0)
++			nidump = 16;
++		else if (nidump > MAX_DUMP)
++			nidump = MAX_DUMP;
++		adrs += ppc_inst_dump(adrs, nidump, 1);
++		last_cmd = "di\n";
++	} else {
++		scanhex(&ndump);
++		if (ndump == 0)
++			ndump = 64;
++		else if (ndump > MAX_DUMP)
++			ndump = MAX_DUMP;
++		prdump(adrs, ndump);
++		adrs += ndump;
++		last_cmd = "d\n";
++	}
++}
++
++void
++prdump(unsigned long adrs, long ndump)
++{
++	long n, m, c, r, nr;
++	unsigned char temp[16];
++
++	for (n = ndump; n > 0;) {
++		printf(REG, adrs);
++		putchar(' ');
++		r = n < 16? n: 16;
++		nr = mread(adrs, temp, r);
++		adrs += nr;
++		for (m = 0; m < r; ++m) {
++		        if ((m & 7) == 0 && m > 0)
++			    putchar(' ');
++			if (m < nr)
++				printf("%.2x", temp[m]);
++			else
++				printf("%s", fault_chars[fault_type]);
++		}
++		if (m <= 8)
++			printf(" ");
++		for (; m < 16; ++m)
++			printf("  ");
++		printf("  |");
++		for (m = 0; m < r; ++m) {
++			if (m < nr) {
++				c = temp[m];
++				putchar(' ' <= c && c <= '~'? c: '.');
++			} else
++				putchar(' ');
++		}
++		n -= r;
++		for (; m < 16; ++m)
++			putchar(' ');
++		printf("|\n");
++		if (nr < r)
++			break;
++	}
++}
++
++int
++ppc_inst_dump(unsigned long adr, long count, int praddr)
++{
++	int nr, dotted;
++	unsigned long first_adr;
++	unsigned long inst, last_inst = 0;
++	unsigned char val[4];
++
++	dotted = 0;
++	for (first_adr = adr; count > 0; --count, adr += 4) {
++		nr = mread(adr, val, 4);
++		if (nr == 0) {
++			if (praddr) {
++				const char *x = fault_chars[fault_type];
++				printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
++			}
++			break;
++		}
++		inst = GETWORD(val);
++		if (adr > first_adr && inst == last_inst) {
++			if (!dotted) {
++				printf(" ...\n");
++				dotted = 1;
++			}
++			continue;
++		}
++		dotted = 0;
++		last_inst = inst;
++		if (praddr)
++			printf(REG"  %.8x", adr, inst);
++		printf("\t");
++		print_insn_powerpc(inst, adr, 0);	/* always returns 4 */
++		printf("\n");
++	}
++	return adr - first_adr;
++}
++
++void
++print_address(unsigned long addr)
++{
++	xmon_print_symbol(addr, "\t# ", "");
++}
++
++
++/*
++ * Memory operations - move, set, print differences
++ */
++static unsigned long mdest;		/* destination address */
++static unsigned long msrc;		/* source address */
++static unsigned long mval;		/* byte value to set memory to */
++static unsigned long mcount;		/* # bytes to affect */
++static unsigned long mdiffs;		/* max # differences to print */
++
++void
++memops(int cmd)
++{
++	scanhex((void *)&mdest);
++	if( termch != '\n' )
++		termch = 0;
++	scanhex((void *)(cmd == 's'? &mval: &msrc));
++	if( termch != '\n' )
++		termch = 0;
++	scanhex((void *)&mcount);
++	switch( cmd ){
++	case 'm':
++		memmove((void *)mdest, (void *)msrc, mcount);
++		break;
++	case 's':
++		memset((void *)mdest, mval, mcount);
++		break;
++	case 'd':
++		if( termch != '\n' )
++			termch = 0;
++		scanhex((void *)&mdiffs);
++		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
++		break;
++	}
++}
++
++void
++memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
++{
++	unsigned n, prt;
++
++	prt = 0;
++	for( n = nb; n > 0; --n )
++		if( *p1++ != *p2++ )
++			if( ++prt <= maxpr )
++				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
++					p1[-1], p2 - 1, p2[-1]);
++	if( prt > maxpr )
++		printf("Total of %d differences\n", prt);
++}
++
++static unsigned mend;
++static unsigned mask;
++
++void
++memlocate(void)
++{
++	unsigned a, n;
++	unsigned char val[4];
++
++	last_cmd = "ml";
++	scanhex((void *)&mdest);
++	if (termch != '\n') {
++		termch = 0;
++		scanhex((void *)&mend);
++		if (termch != '\n') {
++			termch = 0;
++			scanhex((void *)&mval);
++			mask = ~0;
++			if (termch != '\n') termch = 0;
++			scanhex((void *)&mask);
++		}
++	}
++	n = 0;
++	for (a = mdest; a < mend; a += 4) {
++		if (mread(a, val, 4) == 4
++			&& ((GETWORD(val) ^ mval) & mask) == 0) {
++			printf("%.16x:  %.16x\n", a, GETWORD(val));
++			if (++n >= 10)
++				break;
++		}
++	}
++}
++
++static unsigned long mskip = 0x1000;
++static unsigned long mlim = 0xffffffff;
++
++void
++memzcan(void)
++{
++	unsigned char v;
++	unsigned a;
++	int ok, ook;
++
++	scanhex(&mdest);
++	if (termch != '\n') termch = 0;
++	scanhex(&mskip);
++	if (termch != '\n') termch = 0;
++	scanhex(&mlim);
++	ook = 0;
++	for (a = mdest; a < mlim; a += mskip) {
++		ok = mread(a, &v, 1);
++		if (ok && !ook) {
++			printf("%.8x .. ", a);
++			fflush(stdout);
++		} else if (!ok && ook)
++			printf("%.8x\n", a - mskip);
++		ook = ok;
++		if (a + mskip < a)
++			break;
++	}
++	if (ook)
++		printf("%.8x\n", a - mskip);
++}
++
++void proccall(void)
++{
++	unsigned long args[8];
++	unsigned long ret;
++	int i;
++	typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
++			unsigned long, unsigned long, unsigned long,
++			unsigned long, unsigned long, unsigned long);
++	callfunc_t func;
++
++	if (!scanhex(&adrs))
++		return;
++	if (termch != '\n')
++		termch = 0;
++	for (i = 0; i < 8; ++i)
++		args[i] = 0;
++	for (i = 0; i < 8; ++i) {
++		if (!scanhex(&args[i]) || termch == '\n')
++			break;
++		termch = 0;
++	}
++	func = (callfunc_t) adrs;
++	ret = 0;
++	if (setjmp(bus_error_jmp) == 0) {
++		catch_memory_errors = 1;
++		sync();
++		ret = func(args[0], args[1], args[2], args[3],
++			   args[4], args[5], args[6], args[7]);
++		sync();
++		printf("return value is %x\n", ret);
++	} else {
++		printf("*** %x exception occurred\n", fault_except);
++	}
++	catch_memory_errors = 0;
++}
++
++/* Input scanning routines */
++int
++skipbl(void)
++{
++	int c;
++
++	if( termch != 0 ){
++		c = termch;
++		termch = 0;
++	} else
++		c = inchar();
++	while( c == ' ' || c == '\t' )
++		c = inchar();
++	return c;
++}
++
++#define N_PTREGS	44
++static char *regnames[N_PTREGS] = {
++	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
++	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
++	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
++	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
++	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
++#ifdef CONFIG_PPC64
++	"softe",
++#else
++	"mq",
++#endif
++	"trap", "dar", "dsisr", "res"
++};
++
++int
++scanhex(unsigned long *vp)
++{
++	int c, d;
++	unsigned long v;
++
++	c = skipbl();
++	if (c == '%') {
++		/* parse register name */
++		char regname[8];
++		int i;
++
++		for (i = 0; i < sizeof(regname) - 1; ++i) {
++			c = inchar();
++			if (!isalnum(c)) {
++				termch = c;
++				break;
++			}
++			regname[i] = c;
++		}
++		regname[i] = 0;
++		for (i = 0; i < N_PTREGS; ++i) {
++			if (strcmp(regnames[i], regname) == 0) {
++				if (xmon_regs == NULL) {
++					printf("regs not available\n");
++					return 0;
++				}
++				*vp = ((unsigned long *)xmon_regs)[i];
++				return 1;
++			}
++		}
++		printf("invalid register name '%%%s'\n", regname);
++		return 0;
++	}
++
++	/* skip leading "0x" if any */
++
++	if (c == '0') {
++		c = inchar();
++		if (c == 'x') {
++			c = inchar();
++		} else {
++			d = hexdigit(c);
++			if (d == EOF) {
++				termch = c;
++				*vp = 0;
++				return 1;
++			}
++		}
++	} else if (c == '$') {
++		int i;
++		for (i=0; i<63; i++) {
++			c = inchar();
++			if (isspace(c)) {
++				termch = c;
++				break;
++			}
++			tmpstr[i] = c;
++		}
++		tmpstr[i++] = 0;
++		*vp = 0;
++		if (setjmp(bus_error_jmp) == 0) {
++			catch_memory_errors = 1;
++			sync();
++			*vp = kallsyms_lookup_name(tmpstr);
++			sync();
++		}
++		catch_memory_errors = 0;
++		if (!(*vp)) {
++			printf("unknown symbol '%s'\n", tmpstr);
++			return 0;
++		}
++		return 1;
++	}
++
++	d = hexdigit(c);
++	if (d == EOF) {
++		termch = c;
++		return 0;
++	}
++	v = 0;
++	do {
++		v = (v << 4) + d;
++		c = inchar();
++		d = hexdigit(c);
++	} while (d != EOF);
++	termch = c;
++	*vp = v;
++	return 1;
++}
++
++void
++scannl(void)
++{
++	int c;
++
++	c = termch;
++	termch = 0;
++	while( c != '\n' )
++		c = inchar();
++}
++
++int hexdigit(int c)
++{
++	if( '0' <= c && c <= '9' )
++		return c - '0';
++	if( 'A' <= c && c <= 'F' )
++		return c - ('A' - 10);
++	if( 'a' <= c && c <= 'f' )
++		return c - ('a' - 10);
++	return EOF;
++}
++
++void
++getstring(char *s, int size)
++{
++	int c;
++
++	c = skipbl();
++	do {
++		if( size > 1 ){
++			*s++ = c;
++			--size;
++		}
++		c = inchar();
++	} while( c != ' ' && c != '\t' && c != '\n' );
++	termch = c;
++	*s = 0;
++}
++
++static char line[256];
++static char *lineptr;
++
++void
++flush_input(void)
++{
++	lineptr = NULL;
++}
++
++int
++inchar(void)
++{
++	if (lineptr == NULL || *lineptr == 0) {
++		if (fgets(line, sizeof(line), stdin) == NULL) {
++			lineptr = NULL;
++			return EOF;
++		}
++		lineptr = line;
++	}
++	return *lineptr++;
++}
++
++void
++take_input(char *str)
++{
++	lineptr = str;
++}
++
++
++static void
++symbol_lookup(void)
++{
++	int type = inchar();
++	unsigned long addr;
++	static char tmp[64];
++
++	switch (type) {
++	case 'a':
++		if (scanhex(&addr))
++			xmon_print_symbol(addr, ": ", "\n");
++		termch = 0;
++		break;
++	case 's':
++		getstring(tmp, 64);
++		if (setjmp(bus_error_jmp) == 0) {
++			catch_memory_errors = 1;
++			sync();
++			addr = kallsyms_lookup_name(tmp);
++			if (addr)
++				printf("%s: %lx\n", tmp, addr);
++			else
++				printf("Symbol '%s' not found.\n", tmp);
++			sync();
++		}
++		catch_memory_errors = 0;
++		termch = 0;
++		break;
++	}
++}
++
++
++/* Print an address in numeric and symbolic form (if possible) */
++static void xmon_print_symbol(unsigned long address, const char *mid,
++			      const char *after)
++{
++	char *modname;
++	const char *name = NULL;
++	unsigned long offset, size;
++
++	printf(REG, address);
++	if (setjmp(bus_error_jmp) == 0) {
++		catch_memory_errors = 1;
++		sync();
++		name = kallsyms_lookup(address, &size, &offset, &modname,
++				       tmpstr);
++		sync();
++		/* wait a little while to see if we get a machine check */
++		__delay(200);
++	}
++
++	catch_memory_errors = 0;
++
++	if (name) {
++		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
++		if (modname)
++			printf(" [%s]", modname);
++	}
++	printf("%s", after);
++}
++
++#ifdef CONFIG_PPC64
++static void dump_slb(void)
++{
++	int i;
++	unsigned long tmp;
++
++	printf("SLB contents of cpu %x\n", smp_processor_id());
++
++	for (i = 0; i < SLB_NUM_ENTRIES; i++) {
++		asm volatile("slbmfee  %0,%1" : "=r" (tmp) : "r" (i));
++		printf("%02d %016lx ", i, tmp);
++
++		asm volatile("slbmfev  %0,%1" : "=r" (tmp) : "r" (i));
++		printf("%016lx\n", tmp);
++	}
++}
++
++static void dump_stab(void)
++{
++	int i;
++	unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
++
++	printf("Segment table contents of cpu %x\n", smp_processor_id());
++
++	for (i = 0; i < PAGE_SIZE/16; i++) {
++		unsigned long a, b;
++
++		a = *tmp++;
++		b = *tmp++;
++
++		if (a || b) {
++			printf("%03d %016lx ", i, a);
++			printf("%016lx\n", b);
++		}
++	}
++}
++
++void dump_segments(void)
++{
++	if (cpu_has_feature(CPU_FTR_SLB))
++		dump_slb();
++	else
++		dump_stab();
++}
++#endif
++
++#ifdef CONFIG_PPC_STD_MMU_32
++void dump_segments(void)
++{
++	int i;
++
++	printf("sr0-15 =");
++	for (i = 0; i < 16; ++i)
++		printf(" %x", mfsrin(i));
++	printf("\n");
++}
++#endif
++
++void xmon_init(int enable)
++{
++	if (enable) {
++		__debugger = xmon;
++		__debugger_ipi = xmon_ipi;
++		__debugger_bpt = xmon_bpt;
++		__debugger_sstep = xmon_sstep;
++		__debugger_iabr_match = xmon_iabr_match;
++		__debugger_dabr_match = xmon_dabr_match;
++		__debugger_fault_handler = xmon_fault_handler;
++	} else {
++		__debugger = NULL;
++		__debugger_ipi = NULL;
++		__debugger_bpt = NULL;
++		__debugger_sstep = NULL;
++		__debugger_iabr_match = NULL;
++		__debugger_dabr_match = NULL;
++		__debugger_fault_handler = NULL;
++	}
++}
+diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
+--- a/arch/ppc/8xx_io/commproc.c
++++ b/arch/ppc/8xx_io/commproc.c
+@@ -73,7 +73,7 @@ cpm_mask_irq(unsigned int irq)
+ {
+ 	int cpm_vec = irq - CPM_IRQ_OFFSET;
+ 
+-	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << cpm_vec);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) & ~(1 << cpm_vec));
+ }
+ 
+ static void
+@@ -81,7 +81,7 @@ cpm_unmask_irq(unsigned int irq)
+ {
+ 	int cpm_vec = irq - CPM_IRQ_OFFSET;
+ 
+-	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << cpm_vec);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) | (1 << cpm_vec));
+ }
+ 
+ static void
+@@ -95,7 +95,7 @@ cpm_eoi(unsigned int irq)
+ {
+ 	int cpm_vec = irq - CPM_IRQ_OFFSET;
+ 
+-	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr = (1 << cpm_vec);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr, (1 << cpm_vec));
+ }
+ 
+ struct hw_interrupt_type cpm_pic = {
+@@ -133,7 +133,7 @@ m8xx_cpm_reset(void)
+ 	 * manual recommends it.
+ 	 * Bit 25, FAM can also be set to use FEC aggressive mode (860T).
+ 	 */
+-	imp->im_siu_conf.sc_sdcr = 1;
++	out_be32(&imp->im_siu_conf.sc_sdcr, 1),
+ 
+ 	/* Reclaim the DP memory for our use. */
+ 	m8xx_cpm_dpinit();
+@@ -178,10 +178,10 @@ cpm_interrupt_init(void)
+ 
+ 	/* Initialize the CPM interrupt controller.
+ 	*/
+-	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr =
++	out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr,
+ 	    (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
+-		((CPM_INTERRUPT/2) << 13) | CICR_HP_MASK;
+-	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr = 0;
++		((CPM_INTERRUPT/2) << 13) | CICR_HP_MASK);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, 0);
+ 
+         /* install the CPM interrupt controller routines for the CPM
+          * interrupt vectors
+@@ -198,7 +198,7 @@ cpm_interrupt_init(void)
+ 	if (setup_irq(CPM_IRQ_OFFSET + CPMVEC_ERROR, &cpm_error_irqaction))
+ 		panic("Could not allocate CPM error IRQ!");
+ 
+-	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr |= CICR_IEN;
++	out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr) | CICR_IEN);
+ }
+ 
+ /*
+@@ -212,8 +212,8 @@ cpm_get_irq(struct pt_regs *regs)
+ 	/* Get the vector by setting the ACK bit and then reading
+ 	 * the register.
+ 	 */
+-	((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1;
+-	cpm_vec = ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr;
++	out_be16(&((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr, 1);
++	cpm_vec = in_be16(&((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr);
+ 	cpm_vec >>= 11;
+ 
+ 	return cpm_vec;
+diff --git a/arch/ppc/8xx_io/cs4218.h b/arch/ppc/8xx_io/cs4218.h
+--- a/arch/ppc/8xx_io/cs4218.h
++++ b/arch/ppc/8xx_io/cs4218.h
+@@ -78,7 +78,7 @@ typedef struct {
+     const char *name2;
+     void (*open)(void);
+     void (*release)(void);
+-    void *(*dma_alloc)(unsigned int, int);
++    void *(*dma_alloc)(unsigned int, gfp_t);
+     void (*dma_free)(void *, unsigned int);
+     int (*irqinit)(void);
+ #ifdef MODULE
+diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
+--- a/arch/ppc/8xx_io/cs4218_tdm.c
++++ b/arch/ppc/8xx_io/cs4218_tdm.c
+@@ -318,7 +318,7 @@ struct cs_sound_settings {
+ 
+ static struct cs_sound_settings sound;
+ 
+-static void *CS_Alloc(unsigned int size, int flags);
++static void *CS_Alloc(unsigned int size, gfp_t flags);
+ static void CS_Free(void *ptr, unsigned int size);
+ static int CS_IrqInit(void);
+ #ifdef MODULE
+@@ -959,7 +959,7 @@ static TRANS transCSNormalRead = {
+ 
+ /*** Low level stuff *********************************************************/
+ 
+-static void *CS_Alloc(unsigned int size, int flags)
++static void *CS_Alloc(unsigned int size, gfp_t flags)
+ {
+ 	int	order;
+ 
+diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
+--- a/arch/ppc/Kconfig
++++ b/arch/ppc/Kconfig
+@@ -568,6 +568,7 @@ config CHESTNUT
+ 
+ config SPRUCE
+ 	bool "IBM-Spruce"
++	select PPC_INDIRECT_PCI
+ 
+ config HDPU
+ 	bool "Sky-HDPU"
+@@ -588,27 +589,35 @@ config EV64260
+ 
+ config LOPEC
+ 	bool "Motorola-LoPEC"
++	select PPC_I8259
+ 
+ config MVME5100
+ 	bool "Motorola-MVME5100"
++	select PPC_INDIRECT_PCI
+ 
+ config PPLUS
+ 	bool "Motorola-PowerPlus"
++	select PPC_I8259
++	select PPC_INDIRECT_PCI
+ 
+ config PRPMC750
+ 	bool "Motorola-PrPMC750"
++	select PPC_INDIRECT_PCI
+ 
+ config PRPMC800
+ 	bool "Motorola-PrPMC800"
++	select PPC_INDIRECT_PCI
+ 
+ config SANDPOINT
+ 	bool "Motorola-Sandpoint"
++	select PPC_I8259
+ 	help
+ 	  Select SANDPOINT if configuring for a Motorola Sandpoint X3
+ 	  (any flavor).
+ 
+ config RADSTONE_PPC7D
+ 	bool "Radstone Technology PPC7D board"
++	select PPC_I8259
+ 
+ config PAL4
+ 	bool "SBS-Palomar4"
+@@ -616,6 +625,7 @@ config PAL4
+ config GEMINI
+ 	bool "Synergy-Gemini"
+ 	depends on BROKEN
++	select PPC_INDIRECT_PCI
+ 	help
+ 	  Select Gemini if configuring for a Synergy Microsystems' Gemini
+ 	  series Single Board Computer.  More information is available at:
+@@ -747,13 +757,16 @@ config CPM2
+ 	  on it (826x, 827x, 8560).
+ 
+ config PPC_CHRP
+-	bool
++	bool "  Common Hardware Reference Platform (CHRP) based machines"
+ 	depends on PPC_MULTIPLATFORM
++	select PPC_I8259
++	select PPC_INDIRECT_PCI
+ 	default y
+ 
+ config PPC_PMAC
+-	bool
++	bool "  Apple PowerMac based machines"
+ 	depends on PPC_MULTIPLATFORM
++	select PPC_INDIRECT_PCI
+ 	default y
+ 
+ config PPC_PMAC64
+@@ -762,8 +775,10 @@ config PPC_PMAC64
+ 	default y
+ 
+ config PPC_PREP
+-	bool
++	bool "  PowerPC Reference Platform (PReP) based machines"
+ 	depends on PPC_MULTIPLATFORM
++	select PPC_I8259
++	select PPC_INDIRECT_PCI
+ 	default y
+ 
+ config PPC_OF
+@@ -797,6 +812,7 @@ config MV64360		# Really MV64360 & MV644
+ config MV64X60
+ 	bool
+ 	depends on (GT64260 || MV64360)
++	select PPC_INDIRECT_PCI
+ 	default y
+ 
+ menu "Set bridge options"
+@@ -845,6 +861,7 @@ config EPIC_SERIAL_MODE
+ config MPC10X_BRIDGE
+ 	bool
+ 	depends on POWERPMC250 || LOPEC || SANDPOINT
++	select PPC_INDIRECT_PCI
+ 	default y
+ 
+ config MPC10X_OPENPIC
+@@ -870,6 +887,7 @@ config HARRIER_STORE_GATHERING
+ config MVME5100_IPMC761_PRESENT
+ 	bool "MVME5100 configured with an IPMC761"
+ 	depends on MVME5100
++	select PPC_I8259
+ 
+ config SPRUCE_BAUD_33M
+ 	bool "Spruce baud clock support"
+@@ -1127,6 +1145,7 @@ menu "Bus options"
+ config ISA
+ 	bool "Support for ISA-bus hardware"
+ 	depends on PPC_PREP || PPC_CHRP
++	select PPC_I8259
+ 	help
+ 	  Find out whether you have ISA slots on your motherboard.  ISA is the
+ 	  name of a bus system, i.e. the way the CPU talks to the other stuff
+@@ -1139,6 +1158,17 @@ config GENERIC_ISA_DMA
+ 	depends on POWER3 || POWER4 || 6xx && !CPM2
+ 	default y
+ 
++config PPC_I8259
++	bool
++	default y if 85xx
++	default n
++
++config PPC_INDIRECT_PCI
++	bool
++	depends on PCI
++	default y if 40x || 44x || 85xx || 83xx
++	default n
++
+ config EISA
+ 	bool
+ 	help
+@@ -1175,6 +1205,7 @@ config MPC83xx_PCI2
+ config PCI_QSPAN
+ 	bool "QSpan PCI"
+ 	depends on !4xx && !CPM2 && 8xx
++	select PPC_I8259
+ 	help
+ 	  Say Y here if you have a system based on a Motorola 8xx-series
+ 	  embedded processor with a QSPAN PCI interface, otherwise say N.
+@@ -1182,6 +1213,7 @@ config PCI_QSPAN
+ config PCI_8260
+ 	bool
+ 	depends on PCI && 8260
++	select PPC_INDIRECT_PCI
+ 	default y
+ 
+ config 8260_PCI9
+@@ -1368,7 +1400,7 @@ endmenu
+ 
+ source "lib/Kconfig"
+ 
+-source "arch/ppc/oprofile/Kconfig"
++source "arch/powerpc/oprofile/Kconfig"
+ 
+ source "arch/ppc/Kconfig.debug"
+ 
+diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
+--- a/arch/ppc/Makefile
++++ b/arch/ppc/Makefile
+@@ -26,6 +26,10 @@ CPPFLAGS	+= -Iarch/$(ARCH) -Iarch/$(ARCH
+ AFLAGS		+= -Iarch/$(ARCH)
+ CFLAGS		+= -Iarch/$(ARCH) -msoft-float -pipe \
+ 		-ffixed-r2 -mmultiple
++
++# No AltiVec instruction when building kernel
++CFLAGS		+= $(call cc-option, -mno-altivec)
++
+ CPP		= $(CC) -E $(CFLAGS)
+ # Temporary hack until we have migrated to asm-powerpc
+ LINUXINCLUDE    += -Iarch/$(ARCH)/include
+@@ -57,10 +61,12 @@ head-$(CONFIG_FSL_BOOKE)	:= arch/ppc/ker
+ 
+ head-$(CONFIG_6xx)		+= arch/ppc/kernel/idle_6xx.o
+ head-$(CONFIG_POWER4)		+= arch/ppc/kernel/idle_power4.o
+-head-$(CONFIG_PPC_FPU)		+= arch/ppc/kernel/fpu.o
++head-$(CONFIG_PPC_FPU)		+= arch/powerpc/kernel/fpu.o
+ 
+-core-y				+= arch/ppc/kernel/ arch/ppc/platforms/ \
+-				   arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
++core-y				+= arch/ppc/kernel/ arch/powerpc/kernel/ \
++				   arch/ppc/platforms/ \
++				   arch/ppc/mm/ arch/ppc/lib/ \
++				   arch/ppc/syslib/ arch/powerpc/sysdev/
+ core-$(CONFIG_4xx)		+= arch/ppc/platforms/4xx/
+ core-$(CONFIG_83xx)		+= arch/ppc/platforms/83xx/
+ core-$(CONFIG_85xx)		+= arch/ppc/platforms/85xx/
+@@ -71,7 +77,7 @@ drivers-$(CONFIG_8xx)		+= arch/ppc/8xx_i
+ drivers-$(CONFIG_4xx)		+= arch/ppc/4xx_io/
+ drivers-$(CONFIG_CPM2)		+= arch/ppc/8260_io/
+ 
+-drivers-$(CONFIG_OPROFILE)	+= arch/ppc/oprofile/
++drivers-$(CONFIG_OPROFILE)	+= arch/powerpc/oprofile/
+ 
+ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
+ 
+diff --git a/arch/ppc/boot/of1275/claim.c b/arch/ppc/boot/of1275/claim.c
+--- a/arch/ppc/boot/of1275/claim.c
++++ b/arch/ppc/boot/of1275/claim.c
+@@ -29,6 +29,7 @@ claim(unsigned int virt, unsigned int si
+     args.virt = virt;
+     args.size = size;
+     args.align = align;
++    args.ret = (void *) 0;
+     (*of_prom_entry)(&args);
+     return args.ret;
+ }
+diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c
+--- a/arch/ppc/boot/openfirmware/chrpmain.c
++++ b/arch/ppc/boot/openfirmware/chrpmain.c
+@@ -78,7 +78,7 @@ boot(int a1, int a2, void *prom)
+ 	begin_avail = avail_high = avail_ram;
+ 	end_avail = scratch + sizeof(scratch);
+ 	printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
+-	gunzip(dst, 0x400000, im, &len);
++	gunzip(dst, PROG_SIZE - PROG_START, im, &len);
+ 	printf("done %u bytes\n\r", len);
+ 	printf("%u bytes of heap consumed, max in use %u\n\r",
+ 	       avail_high - begin_avail, heap_max);
+diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c
+--- a/arch/ppc/boot/openfirmware/coffmain.c
++++ b/arch/ppc/boot/openfirmware/coffmain.c
+@@ -38,7 +38,7 @@ static char heap[SCRATCH_SIZE];
+ static unsigned long ram_start = 0;
+ static unsigned long ram_end = 0x1000000;
+ 
+-static unsigned long prog_start = 0x900000;
++static unsigned long prog_start = 0x800000;
+ static unsigned long prog_size = 0x700000;
+ 
+ typedef void (*kernel_start_t)(int, int, void *);
+diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
+--- a/arch/ppc/kernel/Makefile
++++ b/arch/ppc/kernel/Makefile
+@@ -1,6 +1,7 @@
+ #
+ # Makefile for the linux kernel.
+ #
++ifneq ($(CONFIG_PPC_MERGE),y)
+ 
+ extra-$(CONFIG_PPC_STD_MMU)	:= head.o
+ extra-$(CONFIG_40x)		:= head_4xx.o
+@@ -9,13 +10,12 @@ extra-$(CONFIG_FSL_BOOKE)	:= head_fsl_bo
+ extra-$(CONFIG_8xx)		:= head_8xx.o
+ extra-$(CONFIG_6xx)		+= idle_6xx.o
+ extra-$(CONFIG_POWER4)		+= idle_power4.o
+-extra-$(CONFIG_PPC_FPU)		+= fpu.o
+ extra-y				+= vmlinux.lds
+ 
+ obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
+-					process.o signal.o ptrace.o align.o \
+-					semaphore.o syscalls.o setup.o \
+-					cputable.o ppc_htab.o perfmon.o
++					process.o align.o \
++					setup.o \
++					ppc_htab.o
+ obj-$(CONFIG_6xx)		+= l2cr.o cpu_setup_6xx.o
+ obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o
+ obj-$(CONFIG_POWER4)		+= cpu_setup_power4.o
+@@ -25,7 +25,6 @@ obj-$(CONFIG_PCI)		+= pci.o
+ obj-$(CONFIG_KGDB)		+= ppc-stub.o
+ obj-$(CONFIG_SMP)		+= smp.o smp-tbsync.o
+ obj-$(CONFIG_TAU)		+= temp.o
+-obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
+ ifndef CONFIG_E200
+ obj-$(CONFIG_FSL_BOOKE)		+= perfmon_fsl_booke.o
+ endif
+@@ -35,3 +34,21 @@ ifndef CONFIG_MATH_EMULATION
+ obj-$(CONFIG_8xx)		+= softemu8xx.o
+ endif
+ 
++# These are here while we do the architecture merge
++
++else
++obj-y				:= irq.o idle.o \
++					align.o
++obj-$(CONFIG_6xx)		+= l2cr.o cpu_setup_6xx.o
++obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o
++obj-$(CONFIG_MODULES)		+= module.o
++obj-$(CONFIG_NOT_COHERENT_CACHE)	+= dma-mapping.o
++obj-$(CONFIG_PCI)		+= pci.o
++obj-$(CONFIG_KGDB)		+= ppc-stub.o
++obj-$(CONFIG_SMP)		+= smp.o smp-tbsync.o
++obj-$(CONFIG_TAU)		+= temp.o
++ifndef CONFIG_E200
++obj-$(CONFIG_FSL_BOOKE)		+= perfmon_fsl_booke.o
++endif
++obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
++endif
+diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c
+--- a/arch/ppc/kernel/align.c
++++ b/arch/ppc/kernel/align.c
+@@ -375,7 +375,7 @@ fix_alignment(struct pt_regs *regs)
+ #ifdef CONFIG_PPC_FPU
+ 		preempt_disable();
+ 		enable_kernel_fp();
+-		cvt_fd(&data.f, &data.d, &current->thread.fpscr);
++		cvt_fd(&data.f, &data.d, &current->thread);
+ 		preempt_enable();
+ #else
+ 		return 0;
+@@ -385,7 +385,7 @@ fix_alignment(struct pt_regs *regs)
+ #ifdef CONFIG_PPC_FPU
+ 		preempt_disable();
+ 		enable_kernel_fp();
+-		cvt_df(&data.d, &data.f, &current->thread.fpscr);
++		cvt_df(&data.d, &data.f, &current->thread);
+ 		preempt_enable();
+ #else
+ 		return 0;
+diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c
+--- a/arch/ppc/kernel/asm-offsets.c
++++ b/arch/ppc/kernel/asm-offsets.c
+@@ -130,10 +130,10 @@ main(void)
+ 	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
+ 	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
+ 
++	DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
+ 	DEFINE(TI_TASK, offsetof(struct thread_info, task));
+ 	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
+ 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+-	DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
+ 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+ 	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
+ 
+@@ -141,6 +141,7 @@ main(void)
+ 	DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
+ 	DEFINE(pbe_next, offsetof(struct pbe, next));
+ 
++	DEFINE(TASK_SIZE, TASK_SIZE);
+ 	DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
+ 	return 0;
+ }
+diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S
+--- a/arch/ppc/kernel/cpu_setup_6xx.S
++++ b/arch/ppc/kernel/cpu_setup_6xx.S
+@@ -17,8 +17,6 @@
+ #include <asm/asm-offsets.h>
+ #include <asm/cache.h>
+ 
+-_GLOBAL(__setup_cpu_601)
+-	blr
+ _GLOBAL(__setup_cpu_603)
+ 	b	setup_common_caches
+ _GLOBAL(__setup_cpu_604)
+@@ -292,10 +290,10 @@ _GLOBAL(__init_fpu_registers)
+ #define CS_SIZE		32
+ 
+ 	.data
+-	.balign	L1_CACHE_LINE_SIZE
++	.balign	L1_CACHE_BYTES
+ cpu_state_storage:
+ 	.space	CS_SIZE
+-	.balign	L1_CACHE_LINE_SIZE,0
++	.balign	L1_CACHE_BYTES,0
+ 	.text
+ 
+ /* Called in normal context to backup CPU 0 state. This
+diff --git a/arch/ppc/kernel/cpu_setup_power4.S b/arch/ppc/kernel/cpu_setup_power4.S
+--- a/arch/ppc/kernel/cpu_setup_power4.S
++++ b/arch/ppc/kernel/cpu_setup_power4.S
+@@ -63,8 +63,6 @@ _GLOBAL(__970_cpu_preinit)
+ 	isync
+ 	blr
+ 
+-_GLOBAL(__setup_cpu_power4)
+-	blr
+ _GLOBAL(__setup_cpu_ppc970)
+ 	mfspr	r0,SPRN_HID0
+ 	li	r11,5			/* clear DOZE and SLEEP */
+@@ -88,10 +86,10 @@ _GLOBAL(__setup_cpu_ppc970)
+ #define CS_SIZE		32
+ 
+ 	.data
+-	.balign	L1_CACHE_LINE_SIZE
++	.balign	L1_CACHE_BYTES
+ cpu_state_storage:	
+ 	.space	CS_SIZE
+-	.balign	L1_CACHE_LINE_SIZE,0
++	.balign	L1_CACHE_BYTES,0
+ 	.text
+ 	
+ /* Called in normal context to backup CPU 0 state. This
+diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
+deleted file mode 100644
+--- a/arch/ppc/kernel/cputable.c
++++ /dev/null
+@@ -1,1041 +0,0 @@
+-/*
+- *  arch/ppc/kernel/cputable.c
+- *
+- *  Copyright (C) 2001 Ben. Herrenschmidt (benh at 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/config.h>
+-#include <linux/string.h>
+-#include <linux/sched.h>
+-#include <linux/threads.h>
+-#include <linux/init.h>
+-#include <asm/cputable.h>
+-
+-struct cpu_spec* cur_cpu_spec[NR_CPUS];
+-
+-extern void __setup_cpu_601(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_603(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_604(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_750(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_750cx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_750fx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_7400(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_7410(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_745x(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_power3(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_power4(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_ppc970(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-
+-#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
+-		     !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
+-		     !defined(CONFIG_BOOKE))
+-
+-/* This table only contains "desktop" CPUs, it need to be filled with embedded
+- * ones as well...
+- */
+-#define COMMON_PPC	(PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
+-			 PPC_FEATURE_HAS_MMU)
+-
+-/* We only set the altivec features if the kernel was compiled with altivec
+- * support
+- */
+-#ifdef CONFIG_ALTIVEC
+-#define CPU_FTR_ALTIVEC_COMP		CPU_FTR_ALTIVEC
+-#define PPC_FEATURE_ALTIVEC_COMP    	PPC_FEATURE_HAS_ALTIVEC
+-#else
+-#define CPU_FTR_ALTIVEC_COMP		0
+-#define PPC_FEATURE_ALTIVEC_COMP       	0
+-#endif
+-
+-/* We only set the spe features if the kernel was compiled with
+- * spe support
+- */
+-#ifdef CONFIG_SPE
+-#define PPC_FEATURE_SPE_COMP    	PPC_FEATURE_HAS_SPE
+-#else
+-#define PPC_FEATURE_SPE_COMP       	0
+-#endif
+-
+-/* We need to mark all pages as being coherent if we're SMP or we
+- * have a 74[45]x and an MPC107 host bridge.
+- */
+-#if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE)
+-#define CPU_FTR_COMMON                  CPU_FTR_NEED_COHERENT
+-#else
+-#define CPU_FTR_COMMON                  0
+-#endif
+-
+-/* The powersave features NAP & DOZE seems to confuse BDI when
+-   debugging. So if a BDI is used, disable theses
+- */
+-#ifndef CONFIG_BDI_SWITCH
+-#define CPU_FTR_MAYBE_CAN_DOZE	CPU_FTR_CAN_DOZE
+-#define CPU_FTR_MAYBE_CAN_NAP	CPU_FTR_CAN_NAP
+-#else
+-#define CPU_FTR_MAYBE_CAN_DOZE	0
+-#define CPU_FTR_MAYBE_CAN_NAP	0
+-#endif
+-
+-struct cpu_spec	cpu_specs[] = {
+-#if CLASSIC_PPC
+-	{ 	/* 601 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00010000,
+-		.cpu_name		= "601",
+-		.cpu_features		= CPU_FTR_COMMON | CPU_FTR_601 |
+-			CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features 	= COMMON_PPC | PPC_FEATURE_601_INSTR |
+-			PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.cpu_setup		= __setup_cpu_601
+-	},
+-	{	/* 603 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00030000,
+-		.cpu_name		= "603",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.cpu_setup		= __setup_cpu_603
+-	},
+-	{	/* 603e */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00060000,
+-		.cpu_name		= "603e",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.cpu_setup		= __setup_cpu_603
+-	},
+-	{	/* 603ev */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00070000,
+-		.cpu_name		= "603ev",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.cpu_setup		= __setup_cpu_603
+-	},
+-	{	/* 604 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00040000,
+-		.cpu_name		= "604",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 2,
+-		.cpu_setup		= __setup_cpu_604
+-	},
+-	{	/* 604e */
+-		.pvr_mask		= 0xfffff000,
+-		.pvr_value		= 0x00090000,
+-		.cpu_name		= "604e",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_604
+-	},
+-	{	/* 604r */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00090000,
+-		.cpu_name		= "604r",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_604
+-	},
+-	{	/* 604ev */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x000a0000,
+-		.cpu_name		= "604ev",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_604
+-	},
+-	{	/* 740/750 (0x4202, don't support TAU ?) */
+-		.pvr_mask		= 0xffffffff,
+-		.pvr_value		= 0x00084202,
+-		.cpu_name		= "740/750",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750
+-	},
+-	{	/* 750CX (80100 and 8010x?) */
+-		.pvr_mask		= 0xfffffff0,
+-		.pvr_value		= 0x00080100,
+-		.cpu_name		= "750CX",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750cx
+-	},
+-	{	/* 750CX (82201 and 82202) */
+-		.pvr_mask		= 0xfffffff0,
+-		.pvr_value		= 0x00082200,
+-		.cpu_name		= "750CX",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750cx
+-	},
+-	{	/* 750CXe (82214) */
+-		.pvr_mask		= 0xfffffff0,
+-		.pvr_value		= 0x00082210,
+-		.cpu_name		= "750CXe",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750cx
+-	},
+-	{	/* 750CXe "Gekko" (83214) */
+-		.pvr_mask		= 0xffffffff,
+-		.pvr_value		= 0x00083214,
+-		.cpu_name		= "750CXe",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750cx
+-	},
+-	{	/* 745/755 */
+-		.pvr_mask		= 0xfffff000,
+-		.pvr_value		= 0x00083000,
+-		.cpu_name		= "745/755",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750
+-	},
+-	{	/* 750FX rev 1.x */
+-		.pvr_mask		= 0xffffff00,
+-		.pvr_value		= 0x70000100,
+-		.cpu_name		= "750FX",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+-			CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750
+-	},
+-	{	/* 750FX rev 2.0 must disable HID0[DPM] */
+-		.pvr_mask		= 0xffffffff,
+-		.pvr_value		= 0x70000200,
+-		.cpu_name		= "750FX",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+-			CPU_FTR_NO_DPM,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750
+-	},
+-	{	/* 750FX (All revs except 2.0) */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x70000000,
+-		.cpu_name		= "750FX",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+-			CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750fx
+-	},
+-	{	/* 750GX */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x70020000,
+-		.cpu_name		= "750GX",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
+-			CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_DUAL_PLL_750FX |
+-			CPU_FTR_HAS_HIGH_BATS,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750fx
+-	},
+-	{	/* 740/750 (L2CR bit need fixup for 740) */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00080000,
+-		.cpu_name		= "740/750",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_750
+-	},
+-	{	/* 7400 rev 1.1 ? (no TAU) */
+-		.pvr_mask		= 0xffffffff,
+-		.pvr_value		= 0x000c1101,
+-		.cpu_name		= "7400 (1.1)",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_7400
+-	},
+-	{	/* 7400 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x000c0000,
+-		.cpu_name		= "7400",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_7400
+-	},
+-	{	/* 7410 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x800c0000,
+-		.cpu_name		= "7410",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-		.cpu_setup		= __setup_cpu_7410
+-	},
+-	{	/* 7450 2.0 - no doze/nap */
+-		.pvr_mask		= 0xffffffff,
+-		.pvr_value		= 0x80000200,
+-		.cpu_name		= "7450",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+-			CPU_FTR_NEED_COHERENT,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7450 2.1 */
+-		.pvr_mask		= 0xffffffff,
+-		.pvr_value		= 0x80000201,
+-		.cpu_name		= "7450",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+-			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
+-			CPU_FTR_NEED_COHERENT,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7450 2.3 and newer */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x80000000,
+-		.cpu_name		= "7450",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+-			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7455 rev 1.x */
+-		.pvr_mask		= 0xffffff00,
+-		.pvr_value		= 0x80010100,
+-		.cpu_name		= "7455",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+-			CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7455 rev 2.0 */
+-		.pvr_mask		= 0xffffffff,
+-		.pvr_value		= 0x80010200,
+-		.cpu_name		= "7455",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+-			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
+-			CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7455 others */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x80010000,
+-		.cpu_name		= "7455",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+-			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+-			CPU_FTR_NEED_COHERENT,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7447/7457 Rev 1.0 */
+-		.pvr_mask		= 0xffffffff,
+-		.pvr_value		= 0x80020100,
+-		.cpu_name		= "7447/7457",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+-			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+-			CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7447/7457 Rev 1.1 */
+-		.pvr_mask		= 0xffffffff,
+-		.pvr_value		= 0x80020101,
+-		.cpu_name		= "7447/7457",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+-			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+-			CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7447/7457 Rev 1.2 and later */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x80020000,
+-		.cpu_name		= "7447/7457",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+-			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+-			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+-			CPU_FTR_NEED_COHERENT,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7447A */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x80030000,
+-		.cpu_name		= "7447A",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
+-			CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 7448 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x80040000,
+-		.cpu_name		= "7448",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
+-			CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_745x
+-	},
+-	{	/* 82xx (8240, 8245, 8260 are all 603e cores) */
+-		.pvr_mask		= 0x7fff0000,
+-		.pvr_value		= 0x00810000,
+-		.cpu_name		= "82xx",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.cpu_setup		= __setup_cpu_603
+-	},
+-	{	/* All G2_LE (603e core, plus some) have the same pvr */
+-		.pvr_mask		= 0x7fff0000,
+-		.pvr_value		= 0x00820000,
+-		.cpu_name		= "G2_LE",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.cpu_setup		= __setup_cpu_603
+-	},
+-	{	/* e300 (a 603e core, plus some) on 83xx */
+-		.pvr_mask		= 0x7fff0000,
+-		.pvr_value		= 0x00830000,
+-		.cpu_name		= "e300",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
+-			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.cpu_setup		= __setup_cpu_603
+-	},
+-	{	/* default match, we assume split I/D cache & TB (non-601)... */
+-		.pvr_mask		= 0x00000000,
+-		.pvr_value		= 0x00000000,
+-		.cpu_name		= "(generic PPC)",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.cpu_setup		= __setup_cpu_generic
+-	},
+-#endif /* CLASSIC_PPC */
+-#ifdef CONFIG_PPC64BRIDGE
+-	{	/* Power3 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00400000,
+-		.cpu_name		= "Power3 (630)",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3
+-	},
+-	{	/* Power3+ */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00410000,
+-		.cpu_name		= "Power3 (630+)",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3
+-	},
+-	{	/* I-star */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00360000,
+-		.cpu_name		= "I-star",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3
+-	},
+-	{	/* S-star */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00370000,
+-		.cpu_name		= "S-star",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3
+-	},
+-#endif /* CONFIG_PPC64BRIDGE */
+-#ifdef CONFIG_POWER4
+-	{	/* Power4 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00350000,
+-		.cpu_name		= "Power4",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_HPTE_TABLE,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power4
+-	},
+-	{	/* PPC970 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00390000,
+-		.cpu_name		= "PPC970",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_64 |
+-			PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_ppc970
+-	},
+-	{	/* PPC970FX */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x003c0000,
+-		.cpu_name		= "PPC970FX",
+-		.cpu_features		= CPU_FTR_COMMON |
+-			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+-			CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_ALTIVEC_COMP | CPU_FTR_MAYBE_CAN_NAP,
+-		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_64 |
+-			PPC_FEATURE_ALTIVEC_COMP,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_ppc970
+-	},
+-#endif /* CONFIG_POWER4 */
+-#ifdef CONFIG_8xx
+-	{	/* 8xx */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00500000,
+-		.cpu_name		= "8xx",
+-		/* CPU_FTR_MAYBE_CAN_DOZE is possible,
+-		 * if the 8xx code is there.... */
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 16,
+-		.dcache_bsize		= 16,
+-	},
+-#endif /* CONFIG_8xx */
+-#ifdef CONFIG_40x
+-	{	/* 403GC */
+-		.pvr_mask		= 0xffffff00,
+-		.pvr_value		= 0x00200200,
+-		.cpu_name		= "403GC",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 16,
+-		.dcache_bsize		= 16,
+-	},
+-	{	/* 403GCX */
+-		.pvr_mask		= 0xffffff00,
+-		.pvr_value		= 0x00201400,
+-		.cpu_name		= "403GCX",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-		 	PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
+-		.icache_bsize		= 16,
+-		.dcache_bsize		= 16,
+-	},
+-	{	/* 403G ?? */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00200000,
+-		.cpu_name		= "403G ??",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 16,
+-		.dcache_bsize		= 16,
+-	},
+-	{	/* 405GP */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x40110000,
+-		.cpu_name		= "405GP",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{	/* STB 03xxx */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x40130000,
+-		.cpu_name		= "STB03xxx",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{	/* STB 04xxx */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x41810000,
+-		.cpu_name		= "STB04xxx",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{	/* NP405L */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x41610000,
+-		.cpu_name		= "NP405L",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{	/* NP4GS3 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x40B10000,
+-		.cpu_name		= "NP4GS3",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{   /* NP405H */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x41410000,
+-		.cpu_name		= "NP405H",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{	/* 405GPr */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x50910000,
+-		.cpu_name		= "405GPr",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{   /* STBx25xx */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x51510000,
+-		.cpu_name		= "STBx25xx",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{	/* 405LP */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x41F10000,
+-		.cpu_name		= "405LP",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{	/* Xilinx Virtex-II Pro  */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x20010000,
+-		.cpu_name		= "Virtex-II Pro",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{	/* 405EP */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x51210000,
+-		.cpu_name		= "405EP",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-
+-#endif /* CONFIG_40x */
+-#ifdef CONFIG_44x
+-	{
+-		.pvr_mask		= 0xf0000fff,
+-		.pvr_value		= 0x40000850,
+-		.cpu_name		= "440EP Rev. A",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= COMMON_PPC, /* 440EP has an FPU */
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{
+-		.pvr_mask		= 0xf0000fff,
+-		.pvr_value		= 0x400008d3,
+-		.cpu_name		= "440EP Rev. B",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= COMMON_PPC, /* 440EP has an FPU */
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{ 	/* 440GP Rev. B */
+-		.pvr_mask		= 0xf0000fff,
+-		.pvr_value		= 0x40000440,
+-		.cpu_name		= "440GP Rev. B",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{ 	/* 440GP Rev. C */
+-		.pvr_mask		= 0xf0000fff,
+-		.pvr_value		= 0x40000481,
+-		.cpu_name		= "440GP Rev. C",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{ /* 440GX Rev. A */
+-		.pvr_mask		= 0xf0000fff,
+-		.pvr_value		= 0x50000850,
+-		.cpu_name		= "440GX Rev. A",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{ /* 440GX Rev. B */
+-		.pvr_mask		= 0xf0000fff,
+-		.pvr_value		= 0x50000851,
+-		.cpu_name		= "440GX Rev. B",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{ /* 440GX Rev. C */
+-		.pvr_mask		= 0xf0000fff,
+-		.pvr_value		= 0x50000892,
+-		.cpu_name		= "440GX Rev. C",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{ /* 440GX Rev. F */
+-		.pvr_mask		= 0xf0000fff,
+-		.pvr_value		= 0x50000894,
+-		.cpu_name		= "440GX Rev. F",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-	{ /* 440SP Rev. A */
+-		.pvr_mask		= 0xff000fff,
+-		.pvr_value		= 0x53000891,
+-		.cpu_name		= "440SP Rev. A",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	},
+-#endif /* CONFIG_44x */
+-#ifdef CONFIG_FSL_BOOKE
+-	{ 	/* e200z5 */
+-		.pvr_mask		= 0xfff00000,
+-		.pvr_value		= 0x81000000,
+-		.cpu_name		= "e200z5",
+-		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
+-		.cpu_features		= CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE |
+-			PPC_FEATURE_UNIFIED_CACHE,
+-		.dcache_bsize		= 32,
+-	},
+-	{ 	/* e200z6 */
+-		.pvr_mask		= 0xfff00000,
+-		.pvr_value		= 0x81100000,
+-		.cpu_name		= "e200z6",
+-		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
+-		.cpu_features		= CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
+-			PPC_FEATURE_HAS_EFP_SINGLE |
+-			PPC_FEATURE_UNIFIED_CACHE,
+-		.dcache_bsize		= 32,
+-	},
+-	{ 	/* e500 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x80200000,
+-		.cpu_name		= "e500",
+-		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
+-			PPC_FEATURE_HAS_EFP_SINGLE,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-	},
+-	{ 	/* e500v2 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x80210000,
+-		.cpu_name		= "e500v2",
+-		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_BIG_PHYS,
+-		.cpu_user_features	= PPC_FEATURE_32 |
+-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
+-			PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-		.num_pmcs		= 4,
+-	},
+-#endif
+-#if !CLASSIC_PPC
+-	{	/* default match */
+-		.pvr_mask		= 0x00000000,
+-		.pvr_value		= 0x00000000,
+-		.cpu_name		= "(generic PPC)",
+-		.cpu_features		= CPU_FTR_COMMON,
+-		.cpu_user_features	= PPC_FEATURE_32,
+-		.icache_bsize		= 32,
+-		.dcache_bsize		= 32,
+-	}
+-#endif /* !CLASSIC_PPC */
+-};
+diff --git a/arch/ppc/kernel/dma-mapping.c b/arch/ppc/kernel/dma-mapping.c
+--- a/arch/ppc/kernel/dma-mapping.c
++++ b/arch/ppc/kernel/dma-mapping.c
+@@ -115,7 +115,7 @@ static struct vm_region consistent_head 
+ };
+ 
+ static struct vm_region *
+-vm_region_alloc(struct vm_region *head, size_t size, int gfp)
++vm_region_alloc(struct vm_region *head, size_t size, gfp_t gfp)
+ {
+ 	unsigned long addr = head->vm_start, end = head->vm_end - size;
+ 	unsigned long flags;
+@@ -173,7 +173,7 @@ static struct vm_region *vm_region_find(
+  * virtual and bus address for that space.
+  */
+ void *
+-__dma_alloc_coherent(size_t size, dma_addr_t *handle, int gfp)
++__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
+ {
+ 	struct page *page;
+ 	struct vm_region *c;
+@@ -335,8 +335,6 @@ static int __init dma_alloc_init(void)
+ 	pte_t *pte;
+ 	int ret = 0;
+ 
+-	spin_lock(&init_mm.page_table_lock);
+-
+ 	do {
+ 		pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
+ 		pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
+@@ -347,7 +345,7 @@ static int __init dma_alloc_init(void)
+ 		}
+ 		WARN_ON(!pmd_none(*pmd));
+ 
+-		pte = pte_alloc_kernel(&init_mm, pmd, CONSISTENT_BASE);
++		pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
+ 		if (!pte) {
+ 			printk(KERN_ERR "%s: no pte tables\n", __func__);
+ 			ret = -ENOMEM;
+@@ -357,8 +355,6 @@ static int __init dma_alloc_init(void)
+ 		consistent_pte = pte;
+ 	} while (0);
+ 
+-	spin_unlock(&init_mm.page_table_lock);
+-
+ 	return ret;
+ }
+ 
+diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
+--- a/arch/ppc/kernel/entry.S
++++ b/arch/ppc/kernel/entry.S
+@@ -200,9 +200,8 @@ _GLOBAL(DoSyscall)
+ 	bl	do_show_syscall
+ #endif /* SHOW_SYSCALLS */
+ 	rlwinm	r10,r1,0,0,18	/* current_thread_info() */
+-	lwz	r11,TI_LOCAL_FLAGS(r10)
+-	rlwinm	r11,r11,0,~_TIFL_FORCE_NOERROR
+-	stw	r11,TI_LOCAL_FLAGS(r10)
++	li	r11,0
++	stb	r11,TI_SC_NOERR(r10)
+ 	lwz	r11,TI_FLAGS(r10)
+ 	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
+ 	bne-	syscall_dotrace
+@@ -227,8 +226,8 @@ ret_from_syscall:
+ 	cmplw	0,r3,r11
+ 	rlwinm	r12,r1,0,0,18	/* current_thread_info() */
+ 	blt+	30f
+-	lwz	r11,TI_LOCAL_FLAGS(r12)
+-	andi.	r11,r11,_TIFL_FORCE_NOERROR
++	lbz	r11,TI_SC_NOERR(r12)
++	cmpwi	r11,0
+ 	bne	30f
+ 	neg	r3,r3
+ 	lwz	r10,_CCR(r1)	/* Set SO bit in CR */
+@@ -633,7 +632,8 @@ sigreturn_exit:
+ 	rlwinm	r12,r1,0,0,18	/* current_thread_info() */
+ 	lwz	r9,TI_FLAGS(r12)
+ 	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
+-	bnel-	do_syscall_trace_leave
++	beq+	ret_from_except_full
++	bl	do_syscall_trace_leave
+ 	/* fall through */
+ 
+ 	.globl	ret_from_except_full
+diff --git a/arch/ppc/kernel/fpu.S b/arch/ppc/kernel/fpu.S
+deleted file mode 100644
+--- a/arch/ppc/kernel/fpu.S
++++ /dev/null
+@@ -1,133 +0,0 @@
+-/*
+- *  FPU support code, moved here from head.S so that it can be used
+- *  by chips which use other head-whatever.S files.
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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 <asm/processor.h>
+-#include <asm/page.h>
+-#include <asm/mmu.h>
+-#include <asm/pgtable.h>
+-#include <asm/cputable.h>
+-#include <asm/cache.h>
+-#include <asm/thread_info.h>
+-#include <asm/ppc_asm.h>
+-#include <asm/asm-offsets.h>
+-
+-/*
+- * This task wants to use the FPU now.
+- * On UP, disable FP for the task which had the FPU previously,
+- * and save its floating-point registers in its thread_struct.
+- * Load up this task's FP registers from its thread_struct,
+- * enable the FPU for the current task and return to the task.
+- */
+-	.globl	load_up_fpu
+-load_up_fpu:
+-	mfmsr	r5
+-	ori	r5,r5,MSR_FP
+-#ifdef CONFIG_PPC64BRIDGE
+-	clrldi	r5,r5,1			/* turn off 64-bit mode */
+-#endif /* CONFIG_PPC64BRIDGE */
+-	SYNC
+-	MTMSRD(r5)			/* enable use of fpu now */
+-	isync
+-/*
+- * For SMP, we don't do lazy FPU switching because it just gets too
+- * horrendously complex, especially when a task switches from one CPU
+- * to another.  Instead we call giveup_fpu in switch_to.
+- */
+-#ifndef CONFIG_SMP
+-	tophys(r6,0)			/* get __pa constant */
+-	addis	r3,r6,last_task_used_math at ha
+-	lwz	r4,last_task_used_math at l(r3)
+-	cmpwi	0,r4,0
+-	beq	1f
+-	add	r4,r4,r6
+-	addi	r4,r4,THREAD		/* want last_task_used_math->thread */
+-	SAVE_32FPRS(0, r4)
+-	mffs	fr0
+-	stfd	fr0,THREAD_FPSCR-4(r4)
+-	lwz	r5,PT_REGS(r4)
+-	add	r5,r5,r6
+-	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+-	li	r10,MSR_FP|MSR_FE0|MSR_FE1
+-	andc	r4,r4,r10		/* disable FP for previous task */
+-	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+-1:
+-#endif /* CONFIG_SMP */
+-	/* enable use of FP after return */
+-	mfspr	r5,SPRN_SPRG3		/* current task's THREAD (phys) */
+-	lwz	r4,THREAD_FPEXC_MODE(r5)
+-	ori	r9,r9,MSR_FP		/* enable FP for current */
+-	or	r9,r9,r4
+-	lfd	fr0,THREAD_FPSCR-4(r5)
+-	mtfsf	0xff,fr0
+-	REST_32FPRS(0, r5)
+-#ifndef CONFIG_SMP
+-	subi	r4,r5,THREAD
+-	sub	r4,r4,r6
+-	stw	r4,last_task_used_math at l(r3)
+-#endif /* CONFIG_SMP */
+-	/* restore registers and return */
+-	/* we haven't used ctr or xer or lr */
+-	b	fast_exception_return
+-
+-/*
+- * FP unavailable trap from kernel - print a message, but let
+- * the task use FP in the kernel until it returns to user mode.
+- */
+- 	.globl	KernelFP
+-KernelFP:
+-	lwz	r3,_MSR(r1)
+-	ori	r3,r3,MSR_FP
+-	stw	r3,_MSR(r1)		/* enable use of FP after return */
+-	lis	r3,86f at h
+-	ori	r3,r3,86f at l
+-	mr	r4,r2			/* current */
+-	lwz	r5,_NIP(r1)
+-	bl	printk
+-	b	ret_from_except
+-86:	.string	"floating point used in kernel (task=%p, pc=%x)\n"
+-	.align	4,0
+-
+-/*
+- * giveup_fpu(tsk)
+- * Disable FP for the task given as the argument,
+- * and save the floating-point registers in its thread_struct.
+- * Enables the FPU for use in the kernel on return.
+- */
+-	.globl	giveup_fpu
+-giveup_fpu:
+-	mfmsr	r5
+-	ori	r5,r5,MSR_FP
+-	SYNC_601
+-	ISYNC_601
+-	MTMSRD(r5)			/* enable use of fpu now */
+-	SYNC_601
+-	isync
+-	cmpwi	0,r3,0
+-	beqlr-				/* if no previous owner, done */
+-	addi	r3,r3,THREAD	        /* want THREAD of task */
+-	lwz	r5,PT_REGS(r3)
+-	cmpwi	0,r5,0
+-	SAVE_32FPRS(0, r3)
+-	mffs	fr0
+-	stfd	fr0,THREAD_FPSCR-4(r3)
+-	beq	1f
+-	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+-	li	r3,MSR_FP|MSR_FE0|MSR_FE1
+-	andc	r4,r4,r3		/* disable FP for previous task */
+-	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+-1:
+-#ifndef CONFIG_SMP
+-	li	r5,0
+-	lis	r4,last_task_used_math at ha
+-	stw	r5,last_task_used_math at l(r4)
+-#endif /* CONFIG_SMP */
+-	blr
+diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
+--- a/arch/ppc/kernel/head.S
++++ b/arch/ppc/kernel/head.S
+@@ -349,12 +349,12 @@ i##n:								\
+ 
+ /* System reset */
+ /* core99 pmac starts the seconary here by changing the vector, and
+-   putting it back to what it was (UnknownException) when done.  */
++   putting it back to what it was (unknown_exception) when done.  */
+ #if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
+ 	. = 0x100
+ 	b	__secondary_start_gemini
+ #else
+-	EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD)
++	EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
+ #endif
+ 
+ /* Machine check */
+@@ -389,7 +389,7 @@ i##n:								\
+ 	cmpwi	cr1,r4,0
+ 	bne	cr1,1f
+ #endif
+-	EXC_XFER_STD(0x200, MachineCheckException)
++	EXC_XFER_STD(0x200, machine_check_exception)
+ #ifdef CONFIG_PPC_CHRP
+ 1:	b	machine_check_in_rtas
+ #endif
+@@ -456,10 +456,10 @@ Alignment:
+ 	mfspr	r5,SPRN_DSISR
+ 	stw	r5,_DSISR(r11)
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	EXC_XFER_EE(0x600, AlignmentException)
++	EXC_XFER_EE(0x600, alignment_exception)
+ 
+ /* Program check exception */
+-	EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD)
++	EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
+ 
+ /* Floating-point unavailable */
+ 	. = 0x800
+@@ -467,13 +467,13 @@ FPUnavailable:
+ 	EXCEPTION_PROLOG
+ 	bne	load_up_fpu		/* if from user, just load it up */
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	EXC_XFER_EE_LITE(0x800, KernelFP)
++	EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
+ 
+ /* Decrementer */
+ 	EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
+ 
+-	EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
+ 
+ /* System call */
+ 	. = 0xc00
+@@ -482,8 +482,8 @@ SystemCall:
+ 	EXC_XFER_EE_LITE(0xc00, DoSyscall)
+ 
+ /* Single step - not used on 601 */
+-	EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
+-	EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
++	EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
+ 
+ /*
+  * The Altivec unavailable trap is at 0x0f20.  Foo.
+@@ -502,7 +502,7 @@ SystemCall:
+ Trap_0f:
+ 	EXCEPTION_PROLOG
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	EXC_XFER_EE(0xf00, UnknownException)
++	EXC_XFER_EE(0xf00, unknown_exception)
+ 
+ /*
+  * Handle TLB miss for instruction on 603/603e.
+@@ -702,44 +702,44 @@ DataStoreTLBMiss:
+ 	rfi
+ 
+ #ifndef CONFIG_ALTIVEC
+-#define AltivecAssistException	UnknownException
++#define altivec_assist_exception	unknown_exception
+ #endif
+ 
+-	EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE)
++	EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE)
+ 	EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
+-	EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ #ifdef CONFIG_POWER4
+-	EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1700, Trap_17, AltivecAssistException, EXC_XFER_EE)
++	EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1700, Trap_17, altivec_assist_exception, EXC_XFER_EE)
+ 	EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD)
+ #else /* !CONFIG_POWER4 */
+-	EXCEPTION(0x1600, Trap_16, AltivecAssistException, EXC_XFER_EE)
++	EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE)
+ 	EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
+-	EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ #endif /* CONFIG_POWER4 */
+-	EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
+ 	EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE)
+-	EXCEPTION(0x2100, Trap_21, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2200, Trap_22, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2300, Trap_23, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2400, Trap_24, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2500, Trap_25, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2600, Trap_26, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2700, Trap_27, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2800, Trap_28, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2900, Trap_29, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2a00, Trap_2a, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2b00, Trap_2b, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2c00, Trap_2c, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2d00, Trap_2d, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2e00, Trap_2e, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x2f00, MOLTrampoline, UnknownException, EXC_XFER_EE_LITE)
++	EXCEPTION(0x2100, Trap_21, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2200, Trap_22, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2300, Trap_23, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2400, Trap_24, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2500, Trap_25, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2600, Trap_26, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2700, Trap_27, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2800, Trap_28, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2900, Trap_29, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2a00, Trap_2a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2b00, Trap_2b, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x2f00, MOLTrampoline, unknown_exception, EXC_XFER_EE_LITE)
+ 
+ 	.globl mol_trampoline
+ 	.set mol_trampoline, i0x2f00
+@@ -751,7 +751,7 @@ AltiVecUnavailable:
+ #ifdef CONFIG_ALTIVEC
+ 	bne	load_up_altivec		/* if from user, just load it up */
+ #endif /* CONFIG_ALTIVEC */
+-	EXC_XFER_EE_LITE(0xf20, AltivecUnavailException)
++	EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
+ 
+ #ifdef CONFIG_PPC64BRIDGE
+ DataAccess:
+@@ -767,12 +767,12 @@ DataSegment:
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD
+ 	mfspr	r4,SPRN_DAR
+ 	stw	r4,_DAR(r11)
+-	EXC_XFER_STD(0x380, UnknownException)
++	EXC_XFER_STD(0x380, unknown_exception)
+ 
+ InstructionSegment:
+ 	EXCEPTION_PROLOG
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	EXC_XFER_STD(0x480, UnknownException)
++	EXC_XFER_STD(0x480, unknown_exception)
+ #endif /* CONFIG_PPC64BRIDGE */
+ 
+ #ifdef CONFIG_ALTIVEC
+@@ -804,7 +804,7 @@ load_up_altivec:
+ 	beq	1f
+ 	add	r4,r4,r6
+ 	addi	r4,r4,THREAD	/* want THREAD of last_task_used_altivec */
+-	SAVE_32VR(0,r10,r4)
++	SAVE_32VRS(0,r10,r4)
+ 	mfvscr	vr0
+ 	li	r10,THREAD_VSCR
+ 	stvx	vr0,r10,r4
+@@ -824,7 +824,7 @@ load_up_altivec:
+ 	stw	r4,THREAD_USED_VR(r5)
+ 	lvx	vr0,r10,r5
+ 	mtvscr	vr0
+-	REST_32VR(0,r10,r5)
++	REST_32VRS(0,r10,r5)
+ #ifndef CONFIG_SMP
+ 	subi	r4,r5,THREAD
+ 	sub	r4,r4,r6
+@@ -870,7 +870,7 @@ giveup_altivec:
+ 	addi	r3,r3,THREAD		/* want THREAD of task */
+ 	lwz	r5,PT_REGS(r3)
+ 	cmpwi	0,r5,0
+-	SAVE_32VR(0, r4, r3)
++	SAVE_32VRS(0, r4, r3)
+ 	mfvscr	vr0
+ 	li	r4,THREAD_VSCR
+ 	stvx	vr0,r4,r3
+@@ -916,7 +916,7 @@ relocate_kernel:
+ copy_and_flush:
+ 	addi	r5,r5,-4
+ 	addi	r6,r6,-4
+-4:	li	r0,L1_CACHE_LINE_SIZE/4
++4:	li	r0,L1_CACHE_BYTES/4
+ 	mtctr	r0
+ 3:	addi	r6,r6,4			/* copy a cache line */
+ 	lwzx	r0,r6,r4
+@@ -1059,7 +1059,6 @@ __secondary_start:
+ 
+ 	lis	r3,-KERNELBASE at h
+ 	mr	r4,r24
+-	bl	identify_cpu
+ 	bl	call_setup_cpu		/* Call setup_cpu for this CPU */
+ #ifdef CONFIG_6xx
+ 	lis	r3,-KERNELBASE at h
+@@ -1109,11 +1108,6 @@ __secondary_start:
+  * Those generic dummy functions are kept for CPUs not
+  * included in CONFIG_6xx
+  */
+-_GLOBAL(__setup_cpu_power3)
+-	blr
+-_GLOBAL(__setup_cpu_generic)
+-	blr
+-
+ #if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4)
+ _GLOBAL(__save_cpu_setup)
+ 	blr
+diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
+--- a/arch/ppc/kernel/head_44x.S
++++ b/arch/ppc/kernel/head_44x.S
+@@ -309,13 +309,13 @@ skpinv:	addi	r4,r4,1				/* Increment */
+ 
+ interrupt_base:
+ 	/* Critical Input Interrupt */
+-	CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
++	CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
+ 
+ 	/* Machine Check Interrupt */
+ #ifdef CONFIG_440A
+-	MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
++	MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+ #else
+-	CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
++	CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+ #endif
+ 
+ 	/* Data Storage Interrupt */
+@@ -442,7 +442,7 @@ interrupt_base:
+ #ifdef CONFIG_PPC_FPU
+ 	FP_UNAVAILABLE_EXCEPTION
+ #else
+-	EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
+ #endif
+ 
+ 	/* System Call Interrupt */
+@@ -451,21 +451,21 @@ interrupt_base:
+ 	EXC_XFER_EE_LITE(0x0c00, DoSyscall)
+ 
+ 	/* Auxillary Processor Unavailable Interrupt */
+-	EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
+ 
+ 	/* Decrementer Interrupt */
+ 	DECREMENTER_EXCEPTION
+ 
+ 	/* Fixed Internal Timer Interrupt */
+ 	/* TODO: Add FIT support */
+-	EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
+ 
+ 	/* Watchdog Timer Interrupt */
+ 	/* TODO: Add watchdog support */
+ #ifdef CONFIG_BOOKE_WDT
+ 	CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException)
+ #else
+-	CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException)
++	CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception)
+ #endif
+ 
+ 	/* Data TLB Error Interrupt */
+@@ -743,14 +743,18 @@ _GLOBAL(set_context)
+  * goes at the beginning of the data segment, which is page-aligned.
+  */
+ 	.data
+-_GLOBAL(sdata)
+-_GLOBAL(empty_zero_page)
++	.align	12
++	.globl	sdata
++sdata:
++	.globl	empty_zero_page
++empty_zero_page:
+ 	.space	4096
+ 
+ /*
+  * To support >32-bit physical addresses, we use an 8KB pgdir.
+  */
+-_GLOBAL(swapper_pg_dir)
++	.globl	swapper_pg_dir
++swapper_pg_dir:
+ 	.space	8192
+ 
+ /* Reserved 4k for the critical exception stack & 4k for the machine
+@@ -759,13 +763,15 @@ _GLOBAL(swapper_pg_dir)
+         .align 12
+ exception_stack_bottom:
+ 	.space	BOOKE_EXCEPTION_STACK_SIZE
+-_GLOBAL(exception_stack_top)
++	.globl	exception_stack_top
++exception_stack_top:
+ 
+ /*
+  * This space gets a copy of optional info passed to us by the bootstrap
+  * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+  */
+-_GLOBAL(cmd_line)
++	.globl	cmd_line
++cmd_line:
+ 	.space	512
+ 
+ /*
+@@ -774,5 +780,3 @@ _GLOBAL(cmd_line)
+  */
+ abatron_pteptrs:
+ 	.space	8
+-
+-
+diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
+--- a/arch/ppc/kernel/head_4xx.S
++++ b/arch/ppc/kernel/head_4xx.S
+@@ -245,12 +245,12 @@ label:
+ /*
+  * 0x0100 - Critical Interrupt Exception
+  */
+-	CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, UnknownException)
++	CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
+ 
+ /*
+  * 0x0200 - Machine Check Exception
+  */
+-	CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
++	CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+ 
+ /*
+  * 0x0300 - Data Storage Exception
+@@ -405,7 +405,7 @@ label:
+ 	mfspr	r4,SPRN_DEAR		/* Grab the DEAR and save it */
+ 	stw	r4,_DEAR(r11)
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	EXC_XFER_EE(0x600, AlignmentException)
++	EXC_XFER_EE(0x600, alignment_exception)
+ 
+ /* 0x0700 - Program Exception */
+ 	START_EXCEPTION(0x0700, ProgramCheck)
+@@ -413,21 +413,21 @@ label:
+ 	mfspr	r4,SPRN_ESR		/* Grab the ESR and save it */
+ 	stw	r4,_ESR(r11)
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	EXC_XFER_STD(0x700, ProgramCheckException)
++	EXC_XFER_STD(0x700, program_check_exception)
+ 
+-	EXCEPTION(0x0800, Trap_08, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x0900, Trap_09, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x0A00, Trap_0A, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x0B00, Trap_0B, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_EE)
+ 
+ /* 0x0C00 - System Call Exception */
+ 	START_EXCEPTION(0x0C00,	SystemCall)
+ 	NORMAL_EXCEPTION_PROLOG
+ 	EXC_XFER_EE_LITE(0xc00, DoSyscall)
+ 
+-	EXCEPTION(0x0D00, Trap_0D, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x0E00, Trap_0E, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x0F00, Trap_0F, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_EE)
+ 
+ /* 0x1000 - Programmable Interval Timer (PIT) Exception */
+ 	START_EXCEPTION(0x1000, Decrementer)
+@@ -444,14 +444,14 @@ label:
+ 
+ /* 0x1010 - Fixed Interval Timer (FIT) Exception
+ */
+-	STND_EXCEPTION(0x1010,	FITException,		UnknownException)
++	STND_EXCEPTION(0x1010,	FITException,		unknown_exception)
+ 
+ /* 0x1020 - Watchdog Timer (WDT) Exception
+ */
+ #ifdef CONFIG_BOOKE_WDT
+ 	CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException)
+ #else
+-	CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException)
++	CRITICAL_EXCEPTION(0x1020, WDTException, unknown_exception)
+ #endif
+ #endif
+ 
+@@ -656,25 +656,25 @@ label:
+ 	mfspr	r10, SPRN_SPRG0
+ 	b	InstructionAccess
+ 
+-	EXCEPTION(0x1300, Trap_13, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1400, Trap_14, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
+ #ifdef CONFIG_IBM405_ERR51
+ 	/* 405GP errata 51 */
+ 	START_EXCEPTION(0x1700, Trap_17)
+ 	b DTLBMiss
+ #else
+-	EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
+ #endif
+-	EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1A00, Trap_1A, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1B00, Trap_1B, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1C00, Trap_1C, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1D00, Trap_1D, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1E00, Trap_1E, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1F00, Trap_1F, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_EE)
+ 
+ /* Check for a single step debug exception while in an exception
+  * handler before state has been saved.  This is to catch the case
+@@ -988,10 +988,14 @@ _GLOBAL(set_context)
+  * goes at the beginning of the data segment, which is page-aligned.
+  */
+ 	.data
+-_GLOBAL(sdata)
+-_GLOBAL(empty_zero_page)
++	.align	12
++	.globl	sdata
++sdata:
++	.globl	empty_zero_page
++empty_zero_page:
+ 	.space	4096
+-_GLOBAL(swapper_pg_dir)
++	.globl	swapper_pg_dir
++swapper_pg_dir:
+ 	.space	4096
+ 
+ 
+@@ -1001,12 +1005,14 @@ _GLOBAL(swapper_pg_dir)
+ exception_stack_bottom:
+ 	.space	4096
+ critical_stack_top:
+-_GLOBAL(exception_stack_top)
++	.globl	exception_stack_top
++exception_stack_top:
+ 
+ /* This space gets a copy of optional info passed to us by the bootstrap
+  * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+  */
+-_GLOBAL(cmd_line)
++	.globl	cmd_line
++cmd_line:
+ 	.space	512
+ 
+ /* Room for two PTE pointers, usually the kernel and current user pointers
+diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
+--- a/arch/ppc/kernel/head_8xx.S
++++ b/arch/ppc/kernel/head_8xx.S
+@@ -203,7 +203,7 @@ i##n:								\
+ 			  ret_from_except)
+ 
+ /* System reset */
+-	EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD)
++	EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
+ 
+ /* Machine check */
+ 	. = 0x200
+@@ -214,7 +214,7 @@ MachineCheck:
+ 	mfspr r5,SPRN_DSISR
+ 	stw r5,_DSISR(r11)
+ 	addi r3,r1,STACK_FRAME_OVERHEAD
+-	EXC_XFER_STD(0x200, MachineCheckException)
++	EXC_XFER_STD(0x200, machine_check_exception)
+ 
+ /* Data access exception.
+  * This is "never generated" by the MPC8xx.  We jump to it for other
+@@ -252,20 +252,20 @@ Alignment:
+ 	mfspr	r5,SPRN_DSISR
+ 	stw	r5,_DSISR(r11)
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	EXC_XFER_EE(0x600, AlignmentException)
++	EXC_XFER_EE(0x600, alignment_exception)
+ 
+ /* Program check exception */
+-	EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD)
++	EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
+ 
+ /* No FPU on MPC8xx.  This exception is not supposed to happen.
+ */
+-	EXCEPTION(0x800, FPUnavailable, UnknownException, EXC_XFER_STD)
++	EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
+ 
+ /* Decrementer */
+ 	EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
+ 
+-	EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
+ 
+ /* System call */
+ 	. = 0xc00
+@@ -274,9 +274,9 @@ SystemCall:
+ 	EXC_XFER_EE_LITE(0xc00, DoSyscall)
+ 
+ /* Single step - not used on 601 */
+-	EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
+-	EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0xf00, Trap_0f, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
++	EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE)
+ 
+ /* On the MPC8xx, this is a software emulation interrupt.  It occurs
+  * for all unimplemented and illegal instructions.
+@@ -540,22 +540,22 @@ DataTLBError:
+ #endif
+ 	b	DataAccess
+ 
+-	EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
+ 
+ /* On the MPC8xx, these next four traps are used for development
+  * support of breakpoints and such.  Someday I will get around to
+  * using them.
+  */
+-	EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE)
+-	EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
++	EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
+ 
+ 	. = 0x2000
+ 
+diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
+--- a/arch/ppc/kernel/head_booke.h
++++ b/arch/ppc/kernel/head_booke.h
+@@ -335,7 +335,7 @@ label:
+ 	mfspr   r4,SPRN_DEAR;           /* Grab the DEAR and save it */	      \
+ 	stw     r4,_DEAR(r11);						      \
+ 	addi    r3,r1,STACK_FRAME_OVERHEAD;				      \
+-	EXC_XFER_EE(0x0600, AlignmentException)
++	EXC_XFER_EE(0x0600, alignment_exception)
+ 
+ #define PROGRAM_EXCEPTION						      \
+ 	START_EXCEPTION(Program)					      \
+@@ -343,7 +343,7 @@ label:
+ 	mfspr	r4,SPRN_ESR;		/* Grab the ESR and save it */	      \
+ 	stw	r4,_ESR(r11);						      \
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD;				      \
+-	EXC_XFER_STD(0x0700, ProgramCheckException)
++	EXC_XFER_STD(0x0700, program_check_exception)
+ 
+ #define DECREMENTER_EXCEPTION						      \
+ 	START_EXCEPTION(Decrementer)					      \
+diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
+--- a/arch/ppc/kernel/head_fsl_booke.S
++++ b/arch/ppc/kernel/head_fsl_booke.S
+@@ -426,14 +426,14 @@ skpinv:	addi	r6,r6,1				/* Increment */
+ 
+ interrupt_base:
+ 	/* Critical Input Interrupt */
+-	CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
++	CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
+ 
+ 	/* Machine Check Interrupt */
+ #ifdef CONFIG_E200
+ 	/* no RFMCI, MCSRRs on E200 */
+-	CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
++	CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+ #else
+-	MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
++	MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+ #endif
+ 
+ 	/* Data Storage Interrupt */
+@@ -542,9 +542,9 @@ interrupt_base:
+ #else
+ #ifdef CONFIG_E200
+ 	/* E200 treats 'normal' floating point instructions as FP Unavail exception */
+-	EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE)
++	EXCEPTION(0x0800, FloatingPointUnavailable, program_check_exception, EXC_XFER_EE)
+ #else
+-	EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x0800, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
+ #endif
+ #endif
+ 
+@@ -554,20 +554,20 @@ interrupt_base:
+ 	EXC_XFER_EE_LITE(0x0c00, DoSyscall)
+ 
+ 	/* Auxillary Processor Unavailable Interrupt */
+-	EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
+ 
+ 	/* Decrementer Interrupt */
+ 	DECREMENTER_EXCEPTION
+ 
+ 	/* Fixed Internal Timer Interrupt */
+ 	/* TODO: Add FIT support */
+-	EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x3100, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
+ 
+ 	/* Watchdog Timer Interrupt */
+ #ifdef CONFIG_BOOKE_WDT
+ 	CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException)
+ #else
+-	CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException)
++	CRITICAL_EXCEPTION(0x3200, WatchdogTimer, unknown_exception)
+ #endif
+ 
+ 	/* Data TLB Error Interrupt */
+@@ -696,21 +696,21 @@ interrupt_base:
+ 	addi    r3,r1,STACK_FRAME_OVERHEAD
+ 	EXC_XFER_EE_LITE(0x2010, KernelSPE)
+ #else
+-	EXCEPTION(0x2020, SPEUnavailable, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x2020, SPEUnavailable, unknown_exception, EXC_XFER_EE)
+ #endif /* CONFIG_SPE */
+ 
+ 	/* SPE Floating Point Data */
+ #ifdef CONFIG_SPE
+ 	EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
+ #else
+-	EXCEPTION(0x2040, SPEFloatingPointData, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
+ #endif /* CONFIG_SPE */
+ 
+ 	/* SPE Floating Point Round */
+-	EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE)
++	EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
+ 
+ 	/* Performance Monitor */
+-	EXCEPTION(0x2060, PerformanceMonitor, PerformanceMonitorException, EXC_XFER_STD)
++	EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
+ 
+ 
+ 	/* Debug Interrupt */
+@@ -853,7 +853,7 @@ load_up_spe:
+ 	cmpi	0,r4,0
+ 	beq	1f
+ 	addi	r4,r4,THREAD	/* want THREAD of last_task_used_spe */
+-	SAVE_32EVR(0,r10,r4)
++	SAVE_32EVRS(0,r10,r4)
+    	evxor	evr10, evr10, evr10	/* clear out evr10 */
+ 	evmwumiaa evr10, evr10, evr10	/* evr10 <- ACC = 0 * 0 + ACC */
+ 	li	r5,THREAD_ACC
+@@ -873,7 +873,7 @@ load_up_spe:
+ 	stw	r4,THREAD_USED_SPE(r5)
+ 	evlddx	evr4,r10,r5
+ 	evmra	evr4,evr4
+-	REST_32EVR(0,r10,r5)
++	REST_32EVRS(0,r10,r5)
+ #ifndef CONFIG_SMP
+ 	subi	r4,r5,THREAD
+ 	stw	r4,last_task_used_spe at l(r3)
+@@ -963,7 +963,7 @@ _GLOBAL(giveup_spe)
+ 	addi	r3,r3,THREAD		/* want THREAD of task */
+ 	lwz	r5,PT_REGS(r3)
+ 	cmpi	0,r5,0
+-	SAVE_32EVR(0, r4, r3)
++	SAVE_32EVRS(0, r4, r3)
+    	evxor	evr6, evr6, evr6	/* clear out evr6 */
+ 	evmwumiaa evr6, evr6, evr6	/* evr6 <- ACC = 0 * 0 + ACC */
+ 	li	r4,THREAD_ACC
+@@ -1028,10 +1028,14 @@ _GLOBAL(set_context)
+  * goes at the beginning of the data segment, which is page-aligned.
+  */
+ 	.data
+-_GLOBAL(sdata)
+-_GLOBAL(empty_zero_page)
++	.align	12
++	.globl	sdata
++sdata:
++	.globl	empty_zero_page
++empty_zero_page:
+ 	.space	4096
+-_GLOBAL(swapper_pg_dir)
++	.globl	swapper_pg_dir
++swapper_pg_dir:
+ 	.space	4096
+ 
+ /* Reserved 4k for the critical exception stack & 4k for the machine
+@@ -1040,13 +1044,15 @@ _GLOBAL(swapper_pg_dir)
+         .align 12
+ exception_stack_bottom:
+ 	.space	BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
+-_GLOBAL(exception_stack_top)
++	.globl	exception_stack_top
++exception_stack_top:
+ 
+ /*
+  * This space gets a copy of optional info passed to us by the bootstrap
+  * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+  */
+-_GLOBAL(cmd_line)
++	.globl	cmd_line
++cmd_line:
+ 	.space	512
+ 
+ /*
+@@ -1055,4 +1061,3 @@ _GLOBAL(cmd_line)
+  */
+ abatron_pteptrs:
+ 	.space	8
+-
+diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
+--- a/arch/ppc/kernel/idle.c
++++ b/arch/ppc/kernel/idle.c
+@@ -32,6 +32,7 @@
+ #include <asm/cache.h>
+ #include <asm/cputable.h>
+ #include <asm/machdep.h>
++#include <asm/smp.h>
+ 
+ void default_idle(void)
+ {
+@@ -74,7 +75,7 @@ void cpu_idle(void)
+ /*
+  * Register the sysctl to set/clear powersave_nap.
+  */
+-extern unsigned long powersave_nap;
++extern int powersave_nap;
+ 
+ static ctl_table powersave_nap_ctl_table[]={
+ 	{
+diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
+--- a/arch/ppc/kernel/irq.c
++++ b/arch/ppc/kernel/irq.c
+@@ -57,6 +57,7 @@
+ #include <asm/cache.h>
+ #include <asm/prom.h>
+ #include <asm/ptrace.h>
++#include <asm/machdep.h>
+ 
+ #define NR_MASK_WORDS	((NR_IRQS + 31) / 32)
+ 
+diff --git a/arch/ppc/kernel/l2cr.S b/arch/ppc/kernel/l2cr.S
+--- a/arch/ppc/kernel/l2cr.S
++++ b/arch/ppc/kernel/l2cr.S
+@@ -203,7 +203,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
+ 	 * L1 icache
+ 	 */
+ 	b	20f
+-	.balign	L1_CACHE_LINE_SIZE
++	.balign	L1_CACHE_BYTES
+ 22:
+ 	sync
+ 	mtspr	SPRN_L2CR,r3
+diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
+--- a/arch/ppc/kernel/misc.S
++++ b/arch/ppc/kernel/misc.S
+@@ -125,9 +125,8 @@ _GLOBAL(identify_cpu)
+ 1:
+ 	addis	r6,r3,cur_cpu_spec at ha
+ 	addi	r6,r6,cur_cpu_spec at l
+-	slwi	r4,r4,2
+ 	sub	r8,r8,r3
+-	stwx	r8,r4,r6
++	stw	r8,0(r6)
+ 	blr
+ 
+ /*
+@@ -186,19 +185,18 @@ _GLOBAL(do_cpu_ftr_fixups)
+  *
+  * Setup function is called with:
+  *   r3 = data offset
+- *   r4 = CPU number
+- *   r5 = ptr to CPU spec (relocated)
++ *   r4 = ptr to CPU spec (relocated)
+  */
+ _GLOBAL(call_setup_cpu)
+-	addis	r5,r3,cur_cpu_spec at ha
+-	addi	r5,r5,cur_cpu_spec at l
+-	slwi	r4,r24,2
+-	lwzx	r5,r4,r5
++	addis	r4,r3,cur_cpu_spec at ha
++	addi	r4,r4,cur_cpu_spec at l
++	lwz	r4,0(r4)
++	add	r4,r4,r3
++	lwz	r5,CPU_SPEC_SETUP(r4)
++	cmpi	0,r5,0
+ 	add	r5,r5,r3
+-	lwz	r6,CPU_SPEC_SETUP(r5)
+-	add	r6,r6,r3
+-	mtctr	r6
+-	mr	r4,r24
++	beqlr
++	mtctr	r5
+ 	bctr
+ 
+ #if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
+@@ -273,134 +271,6 @@ _GLOBAL(low_choose_7447a_dfs)
+ 
+ #endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
+ 
+-/* void local_save_flags_ptr(unsigned long *flags) */
+-_GLOBAL(local_save_flags_ptr)
+-	mfmsr	r4
+-	stw	r4,0(r3)
+-	blr
+-	/*
+-	 * Need these nops here for taking over save/restore to
+-	 * handle lost intrs
+-	 * -- Cort
+-	 */
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-_GLOBAL(local_save_flags_ptr_end)
+-
+-/* void local_irq_restore(unsigned long flags) */
+-_GLOBAL(local_irq_restore)
+-/*
+- * Just set/clear the MSR_EE bit through restore/flags but do not
+- * change anything else.  This is needed by the RT system and makes
+- * sense anyway.
+- *    -- Cort
+- */
+-	mfmsr 	r4
+-	/* Copy all except the MSR_EE bit from r4 (current MSR value)
+-	   to r3.  This is the sort of thing the rlwimi instruction is
+-	   designed for.  -- paulus. */
+-	rlwimi	r3,r4,0,17,15
+-	 /* Check if things are setup the way we want _already_. */
+-	cmpw	0,r3,r4
+-	beqlr
+-1:	SYNC
+-	mtmsr	r3
+-	SYNC
+-	blr
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-_GLOBAL(local_irq_restore_end)
+-
+-_GLOBAL(local_irq_disable)
+-	mfmsr	r0		/* Get current interrupt state */
+-	rlwinm	r3,r0,16+1,32-1,31	/* Extract old value of 'EE' */
+-	rlwinm	r0,r0,0,17,15	/* clear MSR_EE in r0 */
+-	SYNC			/* Some chip revs have problems here... */
+-	mtmsr	r0		/* Update machine state */
+-	blr			/* Done */
+-	/*
+-	 * Need these nops here for taking over save/restore to
+-	 * handle lost intrs
+-	 * -- Cort
+-	 */
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-_GLOBAL(local_irq_disable_end)
+-
+-_GLOBAL(local_irq_enable)
+-	mfmsr	r3		/* Get current state */
+-	ori	r3,r3,MSR_EE	/* Turn on 'EE' bit */
+-	SYNC			/* Some chip revs have problems here... */
+-	mtmsr	r3		/* Update machine state */
+-	blr
+-	/*
+-	 * Need these nops here for taking over save/restore to
+-	 * handle lost intrs
+-	 * -- Cort
+-	 */
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-	nop
+-_GLOBAL(local_irq_enable_end)
+-
+ /*
+  * complement mask on the msr then "or" some values on.
+  *     _nmask_and_or_msr(nmask, value_to_or)
+@@ -628,21 +498,21 @@ _GLOBAL(flush_icache_range)
+ BEGIN_FTR_SECTION
+ 	blr				/* for 601, do nothing */
+ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+-	li	r5,L1_CACHE_LINE_SIZE-1
++	li	r5,L1_CACHE_BYTES-1
+ 	andc	r3,r3,r5
+ 	subf	r4,r3,r4
+ 	add	r4,r4,r5
+-	srwi.	r4,r4,LG_L1_CACHE_LINE_SIZE
++	srwi.	r4,r4,L1_CACHE_SHIFT
+ 	beqlr
+ 	mtctr	r4
+ 	mr	r6,r3
+ 1:	dcbst	0,r3
+-	addi	r3,r3,L1_CACHE_LINE_SIZE
++	addi	r3,r3,L1_CACHE_BYTES
+ 	bdnz	1b
+ 	sync				/* wait for dcbst's to get to ram */
+ 	mtctr	r4
+ 2:	icbi	0,r6
+-	addi	r6,r6,L1_CACHE_LINE_SIZE
++	addi	r6,r6,L1_CACHE_BYTES
+ 	bdnz	2b
+ 	sync				/* additional sync needed on g4 */
+ 	isync
+@@ -655,16 +525,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_C
+  * clean_dcache_range(unsigned long start, unsigned long stop)
+  */
+ _GLOBAL(clean_dcache_range)
+-	li	r5,L1_CACHE_LINE_SIZE-1
++	li	r5,L1_CACHE_BYTES-1
+ 	andc	r3,r3,r5
+ 	subf	r4,r3,r4
+ 	add	r4,r4,r5
+-	srwi.	r4,r4,LG_L1_CACHE_LINE_SIZE
++	srwi.	r4,r4,L1_CACHE_SHIFT
+ 	beqlr
+ 	mtctr	r4
+ 
+ 1:	dcbst	0,r3
+-	addi	r3,r3,L1_CACHE_LINE_SIZE
++	addi	r3,r3,L1_CACHE_BYTES
+ 	bdnz	1b
+ 	sync				/* wait for dcbst's to get to ram */
+ 	blr
+@@ -676,16 +546,16 @@ _GLOBAL(clean_dcache_range)
+  * flush_dcache_range(unsigned long start, unsigned long stop)
+  */
+ _GLOBAL(flush_dcache_range)
+-	li	r5,L1_CACHE_LINE_SIZE-1
++	li	r5,L1_CACHE_BYTES-1
+ 	andc	r3,r3,r5
+ 	subf	r4,r3,r4
+ 	add	r4,r4,r5
+-	srwi.	r4,r4,LG_L1_CACHE_LINE_SIZE
++	srwi.	r4,r4,L1_CACHE_SHIFT
+ 	beqlr
+ 	mtctr	r4
+ 
+ 1:	dcbf	0,r3
+-	addi	r3,r3,L1_CACHE_LINE_SIZE
++	addi	r3,r3,L1_CACHE_BYTES
+ 	bdnz	1b
+ 	sync				/* wait for dcbst's to get to ram */
+ 	blr
+@@ -698,16 +568,16 @@ _GLOBAL(flush_dcache_range)
+  * invalidate_dcache_range(unsigned long start, unsigned long stop)
+  */
+ _GLOBAL(invalidate_dcache_range)
+-	li	r5,L1_CACHE_LINE_SIZE-1
++	li	r5,L1_CACHE_BYTES-1
+ 	andc	r3,r3,r5
+ 	subf	r4,r3,r4
+ 	add	r4,r4,r5
+-	srwi.	r4,r4,LG_L1_CACHE_LINE_SIZE
++	srwi.	r4,r4,L1_CACHE_SHIFT
+ 	beqlr
+ 	mtctr	r4
+ 
+ 1:	dcbi	0,r3
+-	addi	r3,r3,L1_CACHE_LINE_SIZE
++	addi	r3,r3,L1_CACHE_BYTES
+ 	bdnz	1b
+ 	sync				/* wait for dcbi's to get to ram */
+ 	blr
+@@ -728,7 +598,7 @@ _GLOBAL(flush_dcache_all)
+ 	mtctr	r4
+ 	lis     r5, KERNELBASE at h
+ 1:	lwz	r3, 0(r5)		/* Load one word from every line */
+-	addi	r5, r5, L1_CACHE_LINE_SIZE
++	addi	r5, r5, L1_CACHE_BYTES
+ 	bdnz    1b
+ 	blr
+ #endif /* CONFIG_NOT_COHERENT_CACHE */
+@@ -746,16 +616,16 @@ BEGIN_FTR_SECTION
+ 	blr					/* for 601, do nothing */
+ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+ 	rlwinm	r3,r3,0,0,19			/* Get page base address */
+-	li	r4,4096/L1_CACHE_LINE_SIZE	/* Number of lines in a page */
++	li	r4,4096/L1_CACHE_BYTES	/* Number of lines in a page */
+ 	mtctr	r4
+ 	mr	r6,r3
+ 0:	dcbst	0,r3				/* Write line to ram */
+-	addi	r3,r3,L1_CACHE_LINE_SIZE
++	addi	r3,r3,L1_CACHE_BYTES
+ 	bdnz	0b
+ 	sync
+ 	mtctr	r4
+ 1:	icbi	0,r6
+-	addi	r6,r6,L1_CACHE_LINE_SIZE
++	addi	r6,r6,L1_CACHE_BYTES
+ 	bdnz	1b
+ 	sync
+ 	isync
+@@ -778,16 +648,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_C
+ 	mtmsr	r0
+ 	isync
+ 	rlwinm	r3,r3,0,0,19			/* Get page base address */
+-	li	r4,4096/L1_CACHE_LINE_SIZE	/* Number of lines in a page */
++	li	r4,4096/L1_CACHE_BYTES	/* Number of lines in a page */
+ 	mtctr	r4
+ 	mr	r6,r3
+ 0:	dcbst	0,r3				/* Write line to ram */
+-	addi	r3,r3,L1_CACHE_LINE_SIZE
++	addi	r3,r3,L1_CACHE_BYTES
+ 	bdnz	0b
+ 	sync
+ 	mtctr	r4
+ 1:	icbi	0,r6
+-	addi	r6,r6,L1_CACHE_LINE_SIZE
++	addi	r6,r6,L1_CACHE_BYTES
+ 	bdnz	1b
+ 	sync
+ 	mtmsr	r10				/* restore DR */
+@@ -802,7 +672,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_C
+  * void clear_pages(void *page, int order) ;
+  */
+ _GLOBAL(clear_pages)
+-	li	r0,4096/L1_CACHE_LINE_SIZE
++	li	r0,4096/L1_CACHE_BYTES
+ 	slw	r0,r0,r4
+ 	mtctr	r0
+ #ifdef CONFIG_8xx
+@@ -814,7 +684,7 @@ _GLOBAL(clear_pages)
+ #else
+ 1:	dcbz	0,r3
+ #endif
+-	addi	r3,r3,L1_CACHE_LINE_SIZE
++	addi	r3,r3,L1_CACHE_BYTES
+ 	bdnz	1b
+ 	blr
+ 
+@@ -840,7 +710,7 @@ _GLOBAL(copy_page)
+ 
+ #ifdef CONFIG_8xx
+ 	/* don't use prefetch on 8xx */
+-    	li	r0,4096/L1_CACHE_LINE_SIZE
++    	li	r0,4096/L1_CACHE_BYTES
+ 	mtctr	r0
+ 1:	COPY_16_BYTES
+ 	bdnz	1b
+@@ -854,13 +724,13 @@ _GLOBAL(copy_page)
+ 	li	r11,4
+ 	mtctr	r0
+ 11:	dcbt	r11,r4
+-	addi	r11,r11,L1_CACHE_LINE_SIZE
++	addi	r11,r11,L1_CACHE_BYTES
+ 	bdnz	11b
+ #else /* MAX_COPY_PREFETCH == 1 */
+ 	dcbt	r5,r4
+-	li	r11,L1_CACHE_LINE_SIZE+4
++	li	r11,L1_CACHE_BYTES+4
+ #endif /* MAX_COPY_PREFETCH */
+-	li	r0,4096/L1_CACHE_LINE_SIZE - MAX_COPY_PREFETCH
++	li	r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH
+ 	crclr	4*cr0+eq
+ 2:
+ 	mtctr	r0
+@@ -868,12 +738,12 @@ _GLOBAL(copy_page)
+ 	dcbt	r11,r4
+ 	dcbz	r5,r3
+ 	COPY_16_BYTES
+-#if L1_CACHE_LINE_SIZE >= 32
++#if L1_CACHE_BYTES >= 32
+ 	COPY_16_BYTES
+-#if L1_CACHE_LINE_SIZE >= 64
++#if L1_CACHE_BYTES >= 64
+ 	COPY_16_BYTES
+ 	COPY_16_BYTES
+-#if L1_CACHE_LINE_SIZE >= 128
++#if L1_CACHE_BYTES >= 128
+ 	COPY_16_BYTES
+ 	COPY_16_BYTES
+ 	COPY_16_BYTES
+@@ -1098,33 +968,6 @@ _GLOBAL(_get_SP)
+ 	blr
+ 
+ /*
+- * These are used in the alignment trap handler when emulating
+- * single-precision loads and stores.
+- * We restore and save the fpscr so the task gets the same result
+- * and exceptions as if the cpu had performed the load or store.
+- */
+-
+-#ifdef CONFIG_PPC_FPU
+-_GLOBAL(cvt_fd)
+-	lfd	0,-4(r5)	/* load up fpscr value */
+-	mtfsf	0xff,0
+-	lfs	0,0(r3)
+-	stfd	0,0(r4)
+-	mffs	0		/* save new fpscr value */
+-	stfd	0,-4(r5)
+-	blr
+-
+-_GLOBAL(cvt_df)
+-	lfd	0,-4(r5)	/* load up fpscr value */
+-	mtfsf	0xff,0
+-	lfd	0,0(r3)
+-	stfs	0,0(r4)
+-	mffs	0		/* save new fpscr value */
+-	stfd	0,-4(r5)
+-	blr
+-#endif
+-
+-/*
+  * Create a kernel thread
+  *   kernel_thread(fn, arg, flags)
+  */
+diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
+--- a/arch/ppc/kernel/pci.c
++++ b/arch/ppc/kernel/pci.c
+@@ -21,6 +21,7 @@
+ #include <asm/byteorder.h>
+ #include <asm/irq.h>
+ #include <asm/uaccess.h>
++#include <asm/machdep.h>
+ 
+ #undef DEBUG
+ 
+@@ -53,7 +54,7 @@ static u8* pci_to_OF_bus_map;
+ /* By default, we don't re-assign bus numbers. We do this only on
+  * some pmacs
+  */
+-int pci_assign_all_busses;
++int pci_assign_all_buses;
+ 
+ struct pci_controller* hose_head;
+ struct pci_controller** hose_tail = &hose_head;
+@@ -644,7 +645,7 @@ pcibios_alloc_controller(void)
+ /*
+  * Functions below are used on OpenFirmware machines.
+  */
+-static void __openfirmware
++static void
+ make_one_node_map(struct device_node* node, u8 pci_bus)
+ {
+ 	int *bus_range;
+@@ -678,7 +679,7 @@ make_one_node_map(struct device_node* no
+ 	}
+ }
+ 	
+-void __openfirmware
++void
+ pcibios_make_OF_bus_map(void)
+ {
+ 	int i;
+@@ -720,7 +721,7 @@ pcibios_make_OF_bus_map(void)
+ 
+ typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
+ 
+-static struct device_node* __openfirmware
++static struct device_node*
+ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)
+ {
+ 	struct device_node* sub_node;
+@@ -761,7 +762,7 @@ scan_OF_pci_childs_iterator(struct devic
+ 	return 0;
+ }
+ 
+-static struct device_node* __openfirmware
++static struct device_node*
+ scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
+ {
+ 	u8 filter_data[2] = {bus, dev_fn};
+@@ -813,18 +814,20 @@ pci_busdev_to_OF_node(struct pci_bus *bu
+ 	/* Now, lookup childs of the hose */
+ 	return scan_OF_childs_for_device(node->child, busnr, devfn);
+ }
++EXPORT_SYMBOL(pci_busdev_to_OF_node);
+ 
+ struct device_node*
+ pci_device_to_OF_node(struct pci_dev *dev)
+ {
+ 	return pci_busdev_to_OF_node(dev->bus, dev->devfn);
+ }
++EXPORT_SYMBOL(pci_device_to_OF_node);
+ 
+ /* This routine is meant to be used early during boot, when the
+  * PCI bus numbers have not yet been assigned, and you need to
+  * issue PCI config cycles to an OF device.
+  * It could also be used to "fix" RTAS config cycles if you want
+- * to set pci_assign_all_busses to 1 and still use RTAS for PCI
++ * to set pci_assign_all_buses to 1 and still use RTAS for PCI
+  * config cycles.
+  */
+ struct pci_controller*
+@@ -842,7 +845,7 @@ pci_find_hose_for_OF_device(struct devic
+ 	return NULL;
+ }
+ 
+-static int __openfirmware
++static int
+ find_OF_pci_device_filter(struct device_node* node, void* data)
+ {
+ 	return ((void *)node == data);
+@@ -890,6 +893,7 @@ pci_device_from_OF_node(struct device_no
+ 	}
+ 	return -ENODEV;
+ }
++EXPORT_SYMBOL(pci_device_from_OF_node);
+ 
+ void __init
+ pci_process_bridge_OF_ranges(struct pci_controller *hose,
+@@ -1030,6 +1034,10 @@ static ssize_t pci_show_devspec(struct d
+ }
+ static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+ 
++#else /* CONFIG_PPC_OF */
++void pcibios_make_OF_bus_map(void)
++{
++}
+ #endif /* CONFIG_PPC_OF */
+ 
+ /* Add sysfs properties */
+@@ -1262,12 +1270,12 @@ pcibios_init(void)
+ 
+ 	/* Scan all of the recorded PCI controllers.  */
+ 	for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
+-		if (pci_assign_all_busses)
++		if (pci_assign_all_buses)
+ 			hose->first_busno = next_busno;
+ 		hose->last_busno = 0xff;
+ 		bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
+ 		hose->last_busno = bus->subordinate;
+-		if (pci_assign_all_busses || next_busno <= hose->last_busno)
++		if (pci_assign_all_buses || next_busno <= hose->last_busno)
+ 			next_busno = hose->last_busno + pcibios_assign_bus_offset;
+ 	}
+ 	pci_bus_count = next_busno;
+@@ -1276,7 +1284,7 @@ pcibios_init(void)
+ 	 * numbers vs. kernel bus numbers since we may have to
+ 	 * remap them.
+ 	 */
+-	if (pci_assign_all_busses && have_of)
++	if (pci_assign_all_buses && have_of)
+ 		pcibios_make_OF_bus_map();
+ 
+ 	/* Do machine dependent PCI interrupt routing */
+@@ -1586,16 +1594,17 @@ static pgprot_t __pci_mmap_set_pgprot(st
+  * above routine
+  */
+ pgprot_t pci_phys_mem_access_prot(struct file *file,
+-				  unsigned long offset,
++				  unsigned long pfn,
+ 				  unsigned long size,
+ 				  pgprot_t protection)
+ {
+ 	struct pci_dev *pdev = NULL;
+ 	struct resource *found = NULL;
+ 	unsigned long prot = pgprot_val(protection);
++	unsigned long offset = pfn << PAGE_SHIFT;
+ 	int i;
+ 
+-	if (page_is_ram(offset >> PAGE_SHIFT))
++	if (page_is_ram(pfn))
+ 		return prot;
+ 
+ 	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c
+deleted file mode 100644
+--- a/arch/ppc/kernel/perfmon.c
++++ /dev/null
+@@ -1,96 +0,0 @@
+-/* kernel/perfmon.c
+- * PPC 32 Performance Monitor Infrastructure
+- *
+- * Author: Andy Fleming
+- * Copyright (c) 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.
+- */
+-
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/mm.h>
+-#include <linux/stddef.h>
+-#include <linux/unistd.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/user.h>
+-#include <linux/a.out.h>
+-#include <linux/interrupt.h>
+-#include <linux/config.h>
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/prctl.h>
+-
+-#include <asm/pgtable.h>
+-#include <asm/uaccess.h>
+-#include <asm/system.h>
+-#include <asm/io.h>
+-#include <asm/reg.h>
+-#include <asm/xmon.h>
+-
+-/* A lock to regulate grabbing the interrupt */
+-DEFINE_SPINLOCK(perfmon_lock);
+-
+-#if defined (CONFIG_FSL_BOOKE) && !defined (CONFIG_E200)
+-static void dummy_perf(struct pt_regs *regs)
+-{
+-	unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
+-
+-	pmgc0 &= ~PMGC0_PMIE;
+-	mtpmr(PMRN_PMGC0, pmgc0);
+-}
+-
+-#elif defined(CONFIG_6xx)
+-/* Ensure exceptions are disabled */
+-static void dummy_perf(struct pt_regs *regs)
+-{
+-	unsigned int mmcr0 = mfspr(SPRN_MMCR0);
+-
+-	mmcr0 &= ~MMCR0_PMXE;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-}
+-#else
+-static void dummy_perf(struct pt_regs *regs)
+-{
+-}
+-#endif
+-
+-void (*perf_irq)(struct pt_regs *) = dummy_perf;
+-
+-/* Grab the interrupt, if it's free.
+- * Returns 0 on success, -1 if the interrupt is taken already */
+-int request_perfmon_irq(void (*handler)(struct pt_regs *))
+-{
+-	int err = 0;
+-
+-	spin_lock(&perfmon_lock);
+-
+-	if (perf_irq == dummy_perf)
+-		perf_irq = handler;
+-	else {
+-		pr_info("perfmon irq already handled by %p\n", perf_irq);
+-		err = -1;
+-	}
+-
+-	spin_unlock(&perfmon_lock);
+-
+-	return err;
+-}
+-
+-void free_perfmon_irq(void)
+-{
+-	spin_lock(&perfmon_lock);
+-
+-	perf_irq = dummy_perf;
+-
+-	spin_unlock(&perfmon_lock);
+-}
+-
+-EXPORT_SYMBOL(perf_irq);
+-EXPORT_SYMBOL(request_perfmon_irq);
+-EXPORT_SYMBOL(free_perfmon_irq);
+diff --git a/arch/ppc/kernel/perfmon_fsl_booke.c b/arch/ppc/kernel/perfmon_fsl_booke.c
+--- a/arch/ppc/kernel/perfmon_fsl_booke.c
++++ b/arch/ppc/kernel/perfmon_fsl_booke.c
+@@ -32,7 +32,7 @@
+ #include <asm/io.h>
+ #include <asm/reg.h>
+ #include <asm/xmon.h>
+-#include <asm/perfmon.h>
++#include <asm/pmc.h>
+ 
+ static inline u32 get_pmlca(int ctr);
+ static inline void set_pmlca(int ctr, u32 pmlca);
+diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
+--- a/arch/ppc/kernel/ppc_ksyms.c
++++ b/arch/ppc/kernel/ppc_ksyms.c
+@@ -53,10 +53,10 @@
+ 
+ extern void transfer_to_handler(void);
+ extern void do_IRQ(struct pt_regs *regs);
+-extern void MachineCheckException(struct pt_regs *regs);
+-extern void AlignmentException(struct pt_regs *regs);
+-extern void ProgramCheckException(struct pt_regs *regs);
+-extern void SingleStepException(struct pt_regs *regs);
++extern void machine_check_exception(struct pt_regs *regs);
++extern void alignment_exception(struct pt_regs *regs);
++extern void program_check_exception(struct pt_regs *regs);
++extern void single_step_exception(struct pt_regs *regs);
+ extern int do_signal(sigset_t *, struct pt_regs *);
+ extern int pmac_newworld;
+ extern int sys_sigreturn(struct pt_regs *regs);
+@@ -72,10 +72,10 @@ EXPORT_SYMBOL(clear_user_page);
+ EXPORT_SYMBOL(do_signal);
+ EXPORT_SYMBOL(transfer_to_handler);
+ EXPORT_SYMBOL(do_IRQ);
+-EXPORT_SYMBOL(MachineCheckException);
+-EXPORT_SYMBOL(AlignmentException);
+-EXPORT_SYMBOL(ProgramCheckException);
+-EXPORT_SYMBOL(SingleStepException);
++EXPORT_SYMBOL(machine_check_exception);
++EXPORT_SYMBOL(alignment_exception);
++EXPORT_SYMBOL(program_check_exception);
++EXPORT_SYMBOL(single_step_exception);
+ EXPORT_SYMBOL(sys_sigreturn);
+ EXPORT_SYMBOL(ppc_n_lost_interrupts);
+ EXPORT_SYMBOL(ppc_lost_interrupts);
+@@ -230,9 +230,6 @@ EXPORT_SYMBOL(find_all_nodes);
+ EXPORT_SYMBOL(get_property);
+ EXPORT_SYMBOL(request_OF_resource);
+ EXPORT_SYMBOL(release_OF_resource);
+-EXPORT_SYMBOL(pci_busdev_to_OF_node);
+-EXPORT_SYMBOL(pci_device_to_OF_node);
+-EXPORT_SYMBOL(pci_device_from_OF_node);
+ EXPORT_SYMBOL(of_find_node_by_name);
+ EXPORT_SYMBOL(of_find_node_by_type);
+ EXPORT_SYMBOL(of_find_compatible_node);
+@@ -272,16 +269,6 @@ EXPORT_SYMBOL(screen_info);
+ #endif
+ 
+ EXPORT_SYMBOL(__delay);
+-#ifndef INLINE_IRQS
+-EXPORT_SYMBOL(local_irq_enable);
+-EXPORT_SYMBOL(local_irq_enable_end);
+-EXPORT_SYMBOL(local_irq_disable);
+-EXPORT_SYMBOL(local_irq_disable_end);
+-EXPORT_SYMBOL(local_save_flags_ptr);
+-EXPORT_SYMBOL(local_save_flags_ptr_end);
+-EXPORT_SYMBOL(local_irq_restore);
+-EXPORT_SYMBOL(local_irq_restore_end);
+-#endif
+ EXPORT_SYMBOL(timer_interrupt);
+ EXPORT_SYMBOL(irq_desc);
+ EXPORT_SYMBOL(tb_ticks_per_jiffy);
+@@ -335,11 +322,6 @@ EXPORT_SYMBOL(mmu_hash_lock); /* For MOL
+ extern long *intercept_table;
+ EXPORT_SYMBOL(intercept_table);
+ #endif /* CONFIG_PPC_STD_MMU */
+-EXPORT_SYMBOL(cur_cpu_spec);
+-#ifdef CONFIG_PPC_PMAC
+-extern unsigned long agp_special_page;
+-EXPORT_SYMBOL(agp_special_page);
+-#endif
+ #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+ EXPORT_SYMBOL(__mtdcr);
+ EXPORT_SYMBOL(__mfdcr);
+diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
+--- a/arch/ppc/kernel/process.c
++++ b/arch/ppc/kernel/process.c
+@@ -152,18 +152,66 @@ int check_stack(struct task_struct *tsk)
+ }
+ #endif /* defined(CHECK_STACK) */
+ 
+-#ifdef CONFIG_ALTIVEC
+-int
+-dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
++/*
++ * Make sure the floating-point register state in the
++ * the thread_struct is up to date for task tsk.
++ */
++void flush_fp_to_thread(struct task_struct *tsk)
+ {
+-	if (regs->msr & MSR_VEC)
+-		giveup_altivec(current);
+-	memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
++	if (tsk->thread.regs) {
++		/*
++		 * We need to disable preemption here because if we didn't,
++		 * another process could get scheduled after the regs->msr
++		 * test but before we have finished saving the FP registers
++		 * to the thread_struct.  That process could take over the
++		 * FPU, and then when we get scheduled again we would store
++		 * bogus values for the remaining FP registers.
++		 */
++		preempt_disable();
++		if (tsk->thread.regs->msr & MSR_FP) {
++#ifdef CONFIG_SMP
++			/*
++			 * This should only ever be called for current or
++			 * for a stopped child process.  Since we save away
++			 * the FP register state on context switch on SMP,
++			 * there is something wrong if a stopped child appears
++			 * to still have its FP state in the CPU registers.
++			 */
++			BUG_ON(tsk != current);
++#endif
++			giveup_fpu(current);
++		}
++		preempt_enable();
++	}
++}
++
++void enable_kernel_fp(void)
++{
++	WARN_ON(preemptible());
++
++#ifdef CONFIG_SMP
++	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
++		giveup_fpu(current);
++	else
++		giveup_fpu(NULL);	/* just enables FP for kernel */
++#else
++	giveup_fpu(last_task_used_math);
++#endif /* CONFIG_SMP */
++}
++EXPORT_SYMBOL(enable_kernel_fp);
++
++int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
++{
++	preempt_disable();
++	if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP))
++		giveup_fpu(tsk);
++	preempt_enable();
++	memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
+ 	return 1;
+ }
+ 
+-void
+-enable_kernel_altivec(void)
++#ifdef CONFIG_ALTIVEC
++void enable_kernel_altivec(void)
+ {
+ 	WARN_ON(preemptible());
+ 
+@@ -177,19 +225,35 @@ enable_kernel_altivec(void)
+ #endif /* __SMP __ */
+ }
+ EXPORT_SYMBOL(enable_kernel_altivec);
+-#endif /* CONFIG_ALTIVEC */
+ 
+-#ifdef CONFIG_SPE
+-int
+-dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
++/*
++ * Make sure the VMX/Altivec register state in the
++ * the thread_struct is up to date for task tsk.
++ */
++void flush_altivec_to_thread(struct task_struct *tsk)
+ {
+-	if (regs->msr & MSR_SPE)
+-		giveup_spe(current);
+-	/* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
+-	memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
++	if (tsk->thread.regs) {
++		preempt_disable();
++		if (tsk->thread.regs->msr & MSR_VEC) {
++#ifdef CONFIG_SMP
++			BUG_ON(tsk != current);
++#endif
++			giveup_altivec(current);
++		}
++		preempt_enable();
++	}
++}
++
++int dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
++{
++	if (regs->msr & MSR_VEC)
++		giveup_altivec(current);
++	memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
+ 	return 1;
+ }
++#endif /* CONFIG_ALTIVEC */
+ 
++#ifdef CONFIG_SPE
+ void
+ enable_kernel_spe(void)
+ {
+@@ -205,34 +269,30 @@ enable_kernel_spe(void)
+ #endif /* __SMP __ */
+ }
+ EXPORT_SYMBOL(enable_kernel_spe);
+-#endif /* CONFIG_SPE */
+ 
+-void
+-enable_kernel_fp(void)
++void flush_spe_to_thread(struct task_struct *tsk)
+ {
+-	WARN_ON(preemptible());
+-
++	if (tsk->thread.regs) {
++		preempt_disable();
++		if (tsk->thread.regs->msr & MSR_SPE) {
+ #ifdef CONFIG_SMP
+-	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
+-		giveup_fpu(current);
+-	else
+-		giveup_fpu(NULL);	/* just enables FP for kernel */
+-#else
+-	giveup_fpu(last_task_used_math);
+-#endif /* CONFIG_SMP */
++			BUG_ON(tsk != current);
++#endif
++			giveup_spe(current);
++		}
++		preempt_enable();
++	}
+ }
+-EXPORT_SYMBOL(enable_kernel_fp);
+ 
+-int
+-dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
++int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
+ {
+-	preempt_disable();
+-	if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP))
+-		giveup_fpu(tsk);
+-	preempt_enable();
+-	memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
++	if (regs->msr & MSR_SPE)
++		giveup_spe(current);
++	/* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
++	memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
+ 	return 1;
+ }
++#endif /* CONFIG_SPE */
+ 
+ struct task_struct *__switch_to(struct task_struct *prev,
+ 	struct task_struct *new)
+@@ -287,11 +347,13 @@ struct task_struct *__switch_to(struct t
+ #endif /* CONFIG_SPE */
+ #endif /* CONFIG_SMP */
+ 
++#ifdef CONFIG_ALTIVEC
+ 	/* Avoid the trap.  On smp this this never happens since
+ 	 * we don't set last_task_used_altivec -- Cort
+ 	 */
+ 	if (new->thread.regs && last_task_used_altivec == new)
+ 		new->thread.regs->msr |= MSR_VEC;
++#endif
+ #ifdef CONFIG_SPE
+ 	/* Avoid the trap.  On smp this this never happens since
+ 	 * we don't set last_task_used_spe
+@@ -482,7 +544,7 @@ void start_thread(struct pt_regs *regs, 
+ 		last_task_used_spe = NULL;
+ #endif
+ 	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
+-	current->thread.fpscr = 0;
++	current->thread.fpscr.val = 0;
+ #ifdef CONFIG_ALTIVEC
+ 	memset(current->thread.vr, 0, sizeof(current->thread.vr));
+ 	memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
+@@ -557,14 +619,16 @@ int sys_clone(unsigned long clone_flags,
+  	return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
+ }
+ 
+-int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
++int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
++	     unsigned long p4, unsigned long p5, unsigned long p6,
+ 	     struct pt_regs *regs)
+ {
+ 	CHECK_FULL_REGS(regs);
+ 	return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
+ }
+ 
+-int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
++int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
++	      unsigned long p4, unsigned long p5, unsigned long p6,
+ 	      struct pt_regs *regs)
+ {
+ 	CHECK_FULL_REGS(regs);
+diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
+deleted file mode 100644
+--- a/arch/ppc/kernel/ptrace.c
++++ /dev/null
+@@ -1,507 +0,0 @@
+-/*
+- *  arch/ppc/kernel/ptrace.c
+- *
+- *  PowerPC version
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- *  Derived from "arch/m68k/kernel/ptrace.c"
+- *  Copyright (C) 1994 by Hamish Macdonald
+- *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+- *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+- *
+- * Modified by Cort Dougan (cort at hq.fsmlabs.com)
+- * and Paul Mackerras (paulus at linuxcare.com.au).
+- *
+- * This file is subject to the terms and conditions of the GNU General
+- * Public License.  See the file README.legal in the main directory of
+- * this archive for more details.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/errno.h>
+-#include <linux/ptrace.h>
+-#include <linux/user.h>
+-#include <linux/security.h>
+-#include <linux/signal.h>
+-#include <linux/seccomp.h>
+-#include <linux/audit.h>
+-#include <linux/module.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/page.h>
+-#include <asm/pgtable.h>
+-#include <asm/system.h>
+-
+-/*
+- * Set of msr bits that gdb can change on behalf of a process.
+- */
+-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+-#define MSR_DEBUGCHANGE	0
+-#else
+-#define MSR_DEBUGCHANGE	(MSR_SE | MSR_BE)
+-#endif
+-
+-/*
+- * does not yet catch signals sent when the child dies.
+- * in exit.c or in signal.c.
+- */
+-
+-/*
+- * Get contents of register REGNO in task TASK.
+- */
+-static inline unsigned long get_reg(struct task_struct *task, int regno)
+-{
+-	if (regno < sizeof(struct pt_regs) / sizeof(unsigned long)
+-	    && task->thread.regs != NULL)
+-		return ((unsigned long *)task->thread.regs)[regno];
+-	return (0);
+-}
+-
+-/*
+- * Write contents of register REGNO in task TASK.
+- */
+-static inline int put_reg(struct task_struct *task, int regno,
+-			  unsigned long data)
+-{
+-	if (regno <= PT_MQ && task->thread.regs != NULL) {
+-		if (regno == PT_MSR)
+-			data = (data & MSR_DEBUGCHANGE)
+-				| (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
+-		((unsigned long *)task->thread.regs)[regno] = data;
+-		return 0;
+-	}
+-	return -EIO;
+-}
+-
+-#ifdef CONFIG_ALTIVEC
+-/*
+- * Get contents of AltiVec register state in task TASK
+- */
+-static inline int get_vrregs(unsigned long __user *data, struct task_struct *task)
+-{
+-	int i, j;
+-
+-	if (!access_ok(VERIFY_WRITE, data, 133 * sizeof(unsigned long)))
+-		return -EFAULT;
+-
+-	/* copy AltiVec registers VR[0] .. VR[31] */
+-	for (i = 0; i < 32; i++)
+-		for (j = 0; j < 4; j++, data++)
+-			if (__put_user(task->thread.vr[i].u[j], data))
+-				return -EFAULT;
+-
+-	/* copy VSCR */
+-	for (i = 0; i < 4; i++, data++)
+-		if (__put_user(task->thread.vscr.u[i], data))
+-			return -EFAULT;
+-
+-        /* copy VRSAVE */
+-	if (__put_user(task->thread.vrsave, data))
+-		return -EFAULT;
+-
+-	return 0;
+-}
+-
+-/*
+- * Write contents of AltiVec register state into task TASK.
+- */
+-static inline int set_vrregs(struct task_struct *task, unsigned long __user *data)
+-{
+-	int i, j;
+-
+-	if (!access_ok(VERIFY_READ, data, 133 * sizeof(unsigned long)))
+-		return -EFAULT;
+-
+-	/* copy AltiVec registers VR[0] .. VR[31] */
+-	for (i = 0; i < 32; i++)
+-		for (j = 0; j < 4; j++, data++)
+-			if (__get_user(task->thread.vr[i].u[j], data))
+-				return -EFAULT;
+-
+-	/* copy VSCR */
+-	for (i = 0; i < 4; i++, data++)
+-		if (__get_user(task->thread.vscr.u[i], data))
+-			return -EFAULT;
+-
+-	/* copy VRSAVE */
+-	if (__get_user(task->thread.vrsave, data))
+-		return -EFAULT;
+-
+-	return 0;
+-}
+-#endif
+-
+-#ifdef CONFIG_SPE
+-
+-/*
+- * For get_evrregs/set_evrregs functions 'data' has the following layout:
+- *
+- * struct {
+- *   u32 evr[32];
+- *   u64 acc;
+- *   u32 spefscr;
+- * }
+- */
+-
+-/*
+- * Get contents of SPE register state in task TASK.
+- */
+-static inline int get_evrregs(unsigned long *data, struct task_struct *task)
+-{
+-	int i;
+-
+-	if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long)))
+-		return -EFAULT;
+-
+-	/* copy SPEFSCR */
+-	if (__put_user(task->thread.spefscr, &data[34]))
+-		return -EFAULT;
+-
+-	/* copy SPE registers EVR[0] .. EVR[31] */
+-	for (i = 0; i < 32; i++, data++)
+-		if (__put_user(task->thread.evr[i], data))
+-			return -EFAULT;
+-
+-	/* copy ACC */
+-	if (__put_user64(task->thread.acc, (unsigned long long *)data))
+-		return -EFAULT;
+-
+-	return 0;
+-}
+-
+-/*
+- * Write contents of SPE register state into task TASK.
+- */
+-static inline int set_evrregs(struct task_struct *task, unsigned long *data)
+-{
+-	int i;
+-
+-	if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long)))
+-		return -EFAULT;
+-
+-	/* copy SPEFSCR */
+-	if (__get_user(task->thread.spefscr, &data[34]))
+-		return -EFAULT;
+-
+-	/* copy SPE registers EVR[0] .. EVR[31] */
+-	for (i = 0; i < 32; i++, data++)
+-		if (__get_user(task->thread.evr[i], data))
+-			return -EFAULT;
+-	/* copy ACC */
+-	if (__get_user64(task->thread.acc, (unsigned long long*)data))
+-		return -EFAULT;
+-
+-	return 0;
+-}
+-#endif /* CONFIG_SPE */
+-
+-static inline void
+-set_single_step(struct task_struct *task)
+-{
+-	struct pt_regs *regs = task->thread.regs;
+-
+-	if (regs != NULL) {
+-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+-		task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
+-		regs->msr |= MSR_DE;
+-#else
+-		regs->msr |= MSR_SE;
+-#endif
+-	}
+-}
+-
+-static inline void
+-clear_single_step(struct task_struct *task)
+-{
+-	struct pt_regs *regs = task->thread.regs;
+-
+-	if (regs != NULL) {
+-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+-		task->thread.dbcr0 = 0;
+-		regs->msr &= ~MSR_DE;
+-#else
+-		regs->msr &= ~MSR_SE;
+-#endif
+-	}
+-}
+-
+-/*
+- * Called by kernel/ptrace.c when detaching..
+- *
+- * Make sure single step bits etc are not set.
+- */
+-void ptrace_disable(struct task_struct *child)
+-{
+-	/* make sure the single step bit is not set. */
+-	clear_single_step(child);
+-}
+-
+-int sys_ptrace(long request, long pid, long addr, long data)
+-{
+-	struct task_struct *child;
+-	int ret = -EPERM;
+-
+-	lock_kernel();
+-	if (request == PTRACE_TRACEME) {
+-		/* are we already being traced? */
+-		if (current->ptrace & PT_PTRACED)
+-			goto out;
+-		ret = security_ptrace(current->parent, current);
+-		if (ret)
+-			goto out;
+-		/* set the ptrace bit in the process flags. */
+-		current->ptrace |= PT_PTRACED;
+-		ret = 0;
+-		goto out;
+-	}
+-	ret = -ESRCH;
+-	read_lock(&tasklist_lock);
+-	child = find_task_by_pid(pid);
+-	if (child)
+-		get_task_struct(child);
+-	read_unlock(&tasklist_lock);
+-	if (!child)
+-		goto out;
+-
+-	ret = -EPERM;
+-	if (pid == 1)		/* you may not mess with init */
+-		goto out_tsk;
+-
+-	if (request == PTRACE_ATTACH) {
+-		ret = ptrace_attach(child);
+-		goto out_tsk;
+-	}
+-
+-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+-	if (ret < 0)
+-		goto out_tsk;
+-
+-	switch (request) {
+-	/* when I and D space are separate, these will need to be fixed. */
+-	case PTRACE_PEEKTEXT: /* read word at location addr. */
+-	case PTRACE_PEEKDATA: {
+-		unsigned long tmp;
+-		int copied;
+-
+-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+-		ret = -EIO;
+-		if (copied != sizeof(tmp))
+-			break;
+-		ret = put_user(tmp,(unsigned long __user *) data);
+-		break;
+-	}
+-
+-	/* read the word at location addr in the USER area. */
+-	/* XXX this will need fixing for 64-bit */
+-	case PTRACE_PEEKUSR: {
+-		unsigned long index, tmp;
+-
+-		ret = -EIO;
+-		/* convert to index and check */
+-		index = (unsigned long) addr >> 2;
+-		if ((addr & 3) || index > PT_FPSCR
+-		    || child->thread.regs == NULL)
+-			break;
+-
+-		CHECK_FULL_REGS(child->thread.regs);
+-		if (index < PT_FPR0) {
+-			tmp = get_reg(child, (int) index);
+-		} else {
+-			preempt_disable();
+-			if (child->thread.regs->msr & MSR_FP)
+-				giveup_fpu(child);
+-			preempt_enable();
+-			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
+-		}
+-		ret = put_user(tmp,(unsigned long __user *) data);
+-		break;
+-	}
+-
+-	/* If I and D space are separate, this will have to be fixed. */
+-	case PTRACE_POKETEXT: /* write the word at location addr. */
+-	case PTRACE_POKEDATA:
+-		ret = 0;
+-		if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+-			break;
+-		ret = -EIO;
+-		break;
+-
+-	/* write the word at location addr in the USER area */
+-	case PTRACE_POKEUSR: {
+-		unsigned long index;
+-
+-		ret = -EIO;
+-		/* convert to index and check */
+-		index = (unsigned long) addr >> 2;
+-		if ((addr & 3) || index > PT_FPSCR
+-		    || child->thread.regs == NULL)
+-			break;
+-
+-		CHECK_FULL_REGS(child->thread.regs);
+-		if (index == PT_ORIG_R3)
+-			break;
+-		if (index < PT_FPR0) {
+-			ret = put_reg(child, index, data);
+-		} else {
+-			preempt_disable();
+-			if (child->thread.regs->msr & MSR_FP)
+-				giveup_fpu(child);
+-			preempt_enable();
+-			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
+-			ret = 0;
+-		}
+-		break;
+-	}
+-
+-	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+-	case PTRACE_CONT: { /* restart after signal. */
+-		ret = -EIO;
+-		if (!valid_signal(data))
+-			break;
+-		if (request == PTRACE_SYSCALL) {
+-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		} else {
+-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		}
+-		child->exit_code = data;
+-		/* make sure the single step bit is not set. */
+-		clear_single_step(child);
+-		wake_up_process(child);
+-		ret = 0;
+-		break;
+-	}
+-
+-/*
+- * make the child exit.  Best I can do is send it a sigkill.
+- * perhaps it should be put in the status that it wants to
+- * exit.
+- */
+-	case PTRACE_KILL: {
+-		ret = 0;
+-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
+-			break;
+-		child->exit_code = SIGKILL;
+-		/* make sure the single step bit is not set. */
+-		clear_single_step(child);
+-		wake_up_process(child);
+-		break;
+-	}
+-
+-	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+-		ret = -EIO;
+-		if (!valid_signal(data))
+-			break;
+-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		set_single_step(child);
+-		child->exit_code = data;
+-		/* give it a chance to run. */
+-		wake_up_process(child);
+-		ret = 0;
+-		break;
+-	}
+-
+-	case PTRACE_DETACH:
+-		ret = ptrace_detach(child, data);
+-		break;
+-
+-#ifdef CONFIG_ALTIVEC
+-	case PTRACE_GETVRREGS:
+-		/* Get the child altivec register state. */
+-		preempt_disable();
+-		if (child->thread.regs->msr & MSR_VEC)
+-			giveup_altivec(child);
+-		preempt_enable();
+-		ret = get_vrregs((unsigned long __user *)data, child);
+-		break;
+-
+-	case PTRACE_SETVRREGS:
+-		/* Set the child altivec register state. */
+-		/* this is to clear the MSR_VEC bit to force a reload
+-		 * of register state from memory */
+-		preempt_disable();
+-		if (child->thread.regs->msr & MSR_VEC)
+-			giveup_altivec(child);
+-		preempt_enable();
+-		ret = set_vrregs(child, (unsigned long __user *)data);
+-		break;
+-#endif
+-#ifdef CONFIG_SPE
+-	case PTRACE_GETEVRREGS:
+-		/* Get the child spe register state. */
+-		if (child->thread.regs->msr & MSR_SPE)
+-			giveup_spe(child);
+-		ret = get_evrregs((unsigned long __user *)data, child);
+-		break;
+-
+-	case PTRACE_SETEVRREGS:
+-		/* Set the child spe register state. */
+-		/* this is to clear the MSR_SPE bit to force a reload
+-		 * of register state from memory */
+-		if (child->thread.regs->msr & MSR_SPE)
+-			giveup_spe(child);
+-		ret = set_evrregs(child, (unsigned long __user *)data);
+-		break;
+-#endif
+-
+-	default:
+-		ret = ptrace_request(child, request, addr, data);
+-		break;
+-	}
+-out_tsk:
+-	put_task_struct(child);
+-out:
+-	unlock_kernel();
+-	return ret;
+-}
+-
+-static void do_syscall_trace(void)
+-{
+-	/* the 0x80 provides a way for the tracing parent to distinguish
+-	   between a syscall stop and SIGTRAP delivery */
+-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+-				 ? 0x80 : 0));
+-
+-	/*
+-	 * this isn't the same as continuing with a signal, but it will do
+-	 * for normal use.  strace only continues with a signal if the
+-	 * stopping signal is not SIGTRAP.  -brl
+-	 */
+-	if (current->exit_code) {
+-		send_sig(current->exit_code, current, 1);
+-		current->exit_code = 0;
+-	}
+-}
+-
+-void do_syscall_trace_enter(struct pt_regs *regs)
+-{
+-	if (test_thread_flag(TIF_SYSCALL_TRACE)
+-	    && (current->ptrace & PT_PTRACED))
+-		do_syscall_trace();
+-
+-	if (unlikely(current->audit_context))
+-		audit_syscall_entry(current, AUDIT_ARCH_PPC,
+-				    regs->gpr[0],
+-				    regs->gpr[3], regs->gpr[4],
+-				    regs->gpr[5], regs->gpr[6]);
+-}
+-
+-void do_syscall_trace_leave(struct pt_regs *regs)
+-{
+-	secure_computing(regs->gpr[0]);
+-
+-	if (unlikely(current->audit_context))
+-		audit_syscall_exit(current,
+-				   (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+-				   regs->result);
+-
+-	if ((test_thread_flag(TIF_SYSCALL_TRACE))
+-	    && (current->ptrace & PT_PTRACED))
+-		do_syscall_trace();
+-}
+-
+-EXPORT_SYMBOL(do_syscall_trace_enter);
+-EXPORT_SYMBOL(do_syscall_trace_leave);
+diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
+--- a/arch/ppc/kernel/setup.c
++++ b/arch/ppc/kernel/setup.c
+@@ -71,7 +71,8 @@ struct ide_machdep_calls ppc_ide_md;
+ unsigned long boot_mem_size;
+ 
+ unsigned long ISA_DMA_THRESHOLD;
+-unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
++unsigned int DMA_MODE_READ;
++unsigned int DMA_MODE_WRITE;
+ 
+ #ifdef CONFIG_PPC_MULTIPLATFORM
+ int _machine = 0;
+@@ -82,8 +83,18 @@ extern void pmac_init(unsigned long r3, 
+ 		unsigned long r5, unsigned long r6, unsigned long r7);
+ extern void chrp_init(unsigned long r3, unsigned long r4,
+ 		unsigned long r5, unsigned long r6, unsigned long r7);
++
++dev_t boot_dev;
+ #endif /* CONFIG_PPC_MULTIPLATFORM */
+ 
++int have_of;
++EXPORT_SYMBOL(have_of);
++
++#ifdef __DO_IRQ_CANON
++int ppc_do_canonicalize_irqs;
++EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
++#endif
++
+ #ifdef CONFIG_MAGIC_SYSRQ
+ unsigned long SYSRQ_KEY = 0x54;
+ #endif /* CONFIG_MAGIC_SYSRQ */
+@@ -185,18 +196,18 @@ int show_cpuinfo(struct seq_file *m, voi
+ 	seq_printf(m, "processor\t: %d\n", i);
+ 	seq_printf(m, "cpu\t\t: ");
+ 
+-	if (cur_cpu_spec[i]->pvr_mask)
+-		seq_printf(m, "%s", cur_cpu_spec[i]->cpu_name);
++	if (cur_cpu_spec->pvr_mask)
++		seq_printf(m, "%s", cur_cpu_spec->cpu_name);
+ 	else
+ 		seq_printf(m, "unknown (%08x)", pvr);
+ #ifdef CONFIG_ALTIVEC
+-	if (cur_cpu_spec[i]->cpu_features & CPU_FTR_ALTIVEC)
++	if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
+ 		seq_printf(m, ", altivec supported");
+ #endif
+ 	seq_printf(m, "\n");
+ 
+ #ifdef CONFIG_TAU
+-	if (cur_cpu_spec[i]->cpu_features & CPU_FTR_TAU) {
++	if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
+ #ifdef CONFIG_TAU_AVERAGE
+ 		/* more straightforward, but potentially misleading */
+ 		seq_printf(m,  "temperature \t: %u C (uncalibrated)\n",
+@@ -339,7 +350,7 @@ early_init(int r3, int r4, int r5)
+  * Assume here that all clock rates are the same in a
+  * smp system.  -- Cort
+  */
+-int __openfirmware
++int
+ of_show_percpuinfo(struct seq_file *m, int i)
+ {
+ 	struct device_node *cpu_node;
+@@ -404,11 +415,15 @@ platform_init(unsigned long r3, unsigned
+ 			_machine = _MACH_prep;
+ 	}
+ 
++#ifdef CONFIG_PPC_PREP
+ 	/* not much more to do here, if prep */
+ 	if (_machine == _MACH_prep) {
+ 		prep_init(r3, r4, r5, r6, r7);
+ 		return;
+ 	}
++#endif
++
++	have_of = 1;
+ 
+ 	/* prom_init has already been called from __start */
+ 	if (boot_infos)
+@@ -479,12 +494,16 @@ platform_init(unsigned long r3, unsigned
+ #endif /* CONFIG_ADB */
+ 
+ 	switch (_machine) {
++#ifdef CONFIG_PPC_PMAC
+ 	case _MACH_Pmac:
+ 		pmac_init(r3, r4, r5, r6, r7);
+ 		break;
++#endif
++#ifdef CONFIG_PPC_CHRP
+ 	case _MACH_chrp:
+ 		chrp_init(r3, r4, r5, r6, r7);
+ 		break;
++#endif
+ 	}
+ }
+ 
+@@ -721,7 +740,7 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+ 
+ #ifdef CONFIG_XMON
+-	xmon_map_scc();
++	xmon_init(1);
+ 	if (strstr(cmd_line, "xmon"))
+ 		xmon(NULL);
+ #endif /* CONFIG_XMON */
+@@ -745,12 +764,12 @@ void __init setup_arch(char **cmdline_p)
+ 	 * for a possibly more accurate value.
+ 	 */
+ 	if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
+-		dcache_bsize = cur_cpu_spec[0]->dcache_bsize;
+-		icache_bsize = cur_cpu_spec[0]->icache_bsize;
++		dcache_bsize = cur_cpu_spec->dcache_bsize;
++		icache_bsize = cur_cpu_spec->icache_bsize;
+ 		ucache_bsize = 0;
+ 	} else
+ 		ucache_bsize = dcache_bsize = icache_bsize
+-			= cur_cpu_spec[0]->dcache_bsize;
++			= cur_cpu_spec->dcache_bsize;
+ 
+ 	/* reboot on panic */
+ 	panic_timeout = 180;
+diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
+deleted file mode 100644
+--- a/arch/ppc/kernel/signal.c
++++ /dev/null
+@@ -1,771 +0,0 @@
+-/*
+- *  arch/ppc/kernel/signal.c
+- *
+- *  PowerPC version
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- *  Derived from "arch/i386/kernel/signal.c"
+- *    Copyright (C) 1991, 1992 Linus Torvalds
+- *    1997-11-28  Modified for POSIX.1b signals by Richard Henderson
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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/sched.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/kernel.h>
+-#include <linux/signal.h>
+-#include <linux/errno.h>
+-#include <linux/wait.h>
+-#include <linux/ptrace.h>
+-#include <linux/unistd.h>
+-#include <linux/stddef.h>
+-#include <linux/elf.h>
+-#include <linux/tty.h>
+-#include <linux/binfmts.h>
+-#include <linux/suspend.h>
+-#include <asm/ucontext.h>
+-#include <asm/uaccess.h>
+-#include <asm/pgtable.h>
+-#include <asm/cacheflush.h>
+-
+-#undef DEBUG_SIG
+-
+-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+-
+-extern void sigreturn_exit(struct pt_regs *);
+-
+-#define GP_REGS_SIZE	min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
+-
+-int do_signal(sigset_t *oldset, struct pt_regs *regs);
+-
+-/*
+- * Atomically swap in the new signal mask, and wait for a signal.
+- */
+-int
+-sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
+-	       struct pt_regs *regs)
+-{
+-	sigset_t saveset;
+-
+-	mask &= _BLOCKABLE;
+-	spin_lock_irq(&current->sighand->siglock);
+-	saveset = current->blocked;
+-	siginitset(&current->blocked, mask);
+-	recalc_sigpending();
+-	spin_unlock_irq(&current->sighand->siglock);
+-
+-	regs->result = -EINTR;
+-	regs->gpr[3] = EINTR;
+-	regs->ccr |= 0x10000000;
+-	while (1) {
+-		current->state = TASK_INTERRUPTIBLE;
+-		schedule();
+-		if (do_signal(&saveset, regs))
+-			sigreturn_exit(regs);
+-	}
+-}
+-
+-int
+-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4,
+-		  int p6, int p7, struct pt_regs *regs)
+-{
+-	sigset_t saveset, newset;
+-
+-	/* XXX: Don't preclude handling different sized sigset_t's.  */
+-	if (sigsetsize != sizeof(sigset_t))
+-		return -EINVAL;
+-
+-	if (copy_from_user(&newset, unewset, sizeof(newset)))
+-		return -EFAULT;
+-	sigdelsetmask(&newset, ~_BLOCKABLE);
+-
+-	spin_lock_irq(&current->sighand->siglock);
+-	saveset = current->blocked;
+-	current->blocked = newset;
+-	recalc_sigpending();
+-	spin_unlock_irq(&current->sighand->siglock);
+-
+-	regs->result = -EINTR;
+-	regs->gpr[3] = EINTR;
+-	regs->ccr |= 0x10000000;
+-	while (1) {
+-		current->state = TASK_INTERRUPTIBLE;
+-		schedule();
+-		if (do_signal(&saveset, regs))
+-			sigreturn_exit(regs);
+-	}
+-}
+-
+-
+-int
+-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5,
+-		int r6, int r7, int r8, struct pt_regs *regs)
+-{
+-	return do_sigaltstack(uss, uoss, regs->gpr[1]);
+-}
+-
+-int
+-sys_sigaction(int sig, const struct old_sigaction __user *act,
+-	      struct old_sigaction __user *oact)
+-{
+-	struct k_sigaction new_ka, old_ka;
+-	int ret;
+-
+-	if (act) {
+-		old_sigset_t mask;
+-		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+-		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+-		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+-			return -EFAULT;
+-		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+-		__get_user(mask, &act->sa_mask);
+-		siginitset(&new_ka.sa.sa_mask, mask);
+-	}
+-
+-	ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL));
+-
+-	if (!ret && oact) {
+-		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+-		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+-		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+-			return -EFAULT;
+-		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+-		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+-	}
+-
+-	return ret;
+-}
+-
+-/*
+- * When we have signals to deliver, we set up on the
+- * user stack, going down from the original stack pointer:
+- *	a sigregs struct
+- *	a sigcontext struct
+- *	a gap of __SIGNAL_FRAMESIZE bytes
+- *
+- * Each of these things must be a multiple of 16 bytes in size.
+- *
+- */
+-struct sigregs {
+-	struct mcontext	mctx;		/* all the register values */
+-	/* Programs using the rs6000/xcoff abi can save up to 19 gp regs
+-	   and 18 fp regs below sp before decrementing it. */
+-	int		abigap[56];
+-};
+-
+-/* We use the mc_pad field for the signal return trampoline. */
+-#define tramp	mc_pad
+-
+-/*
+- *  When we have rt signals to deliver, we set up on the
+- *  user stack, going down from the original stack pointer:
+- *	one rt_sigframe struct (siginfo + ucontext + ABI gap)
+- *	a gap of __SIGNAL_FRAMESIZE+16 bytes
+- *  (the +16 is to get the siginfo and ucontext in the same
+- *  positions as in older kernels).
+- *
+- *  Each of these things must be a multiple of 16 bytes in size.
+- *
+- */
+-struct rt_sigframe
+-{
+-	struct siginfo info;
+-	struct ucontext uc;
+-	/* Programs using the rs6000/xcoff abi can save up to 19 gp regs
+-	   and 18 fp regs below sp before decrementing it. */
+-	int		abigap[56];
+-};
+-
+-/*
+- * Save the current user registers on the user stack.
+- * We only save the altivec/spe registers if the process has used
+- * altivec/spe instructions at some point.
+- */
+-static int
+-save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, int sigret)
+-{
+-	/* save general and floating-point registers */
+-	CHECK_FULL_REGS(regs);
+-	preempt_disable();
+-	if (regs->msr & MSR_FP)
+-		giveup_fpu(current);
+-#ifdef CONFIG_ALTIVEC
+-	if (current->thread.used_vr && (regs->msr & MSR_VEC))
+-		giveup_altivec(current);
+-#endif /* CONFIG_ALTIVEC */
+-#ifdef CONFIG_SPE
+-	if (current->thread.used_spe && (regs->msr & MSR_SPE))
+-		giveup_spe(current);
+-#endif /* CONFIG_ALTIVEC */
+-	preempt_enable();
+-
+-	if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE)
+-	    || __copy_to_user(&frame->mc_fregs, current->thread.fpr,
+-			      ELF_NFPREG * sizeof(double)))
+-		return 1;
+-
+-	current->thread.fpscr = 0;	/* turn off all fp exceptions */
+-
+-#ifdef CONFIG_ALTIVEC
+-	/* save altivec registers */
+-	if (current->thread.used_vr) {
+-		if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
+-				   ELF_NVRREG * sizeof(vector128)))
+-			return 1;
+-		/* set MSR_VEC in the saved MSR value to indicate that
+-		   frame->mc_vregs contains valid data */
+-		if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
+-			return 1;
+-	}
+-	/* else assert((regs->msr & MSR_VEC) == 0) */
+-
+-	/* We always copy to/from vrsave, it's 0 if we don't have or don't
+-	 * use altivec. Since VSCR only contains 32 bits saved in the least
+-	 * significant bits of a vector, we "cheat" and stuff VRSAVE in the
+-	 * most significant bits of that same vector. --BenH
+-	 */
+-	if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
+-		return 1;
+-#endif /* CONFIG_ALTIVEC */
+-
+-#ifdef CONFIG_SPE
+-	/* save spe registers */
+-	if (current->thread.used_spe) {
+-		if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
+-				   ELF_NEVRREG * sizeof(u32)))
+-			return 1;
+-		/* set MSR_SPE in the saved MSR value to indicate that
+-		   frame->mc_vregs contains valid data */
+-		if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR]))
+-			return 1;
+-	}
+-	/* else assert((regs->msr & MSR_SPE) == 0) */
+-
+-	/* We always copy to/from spefscr */
+-	if (__put_user(current->thread.spefscr, (u32 *)&frame->mc_vregs + ELF_NEVRREG))
+-		return 1;
+-#endif /* CONFIG_SPE */
+-
+-	if (sigret) {
+-		/* Set up the sigreturn trampoline: li r0,sigret; sc */
+-		if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
+-		    || __put_user(0x44000002UL, &frame->tramp[1]))
+-			return 1;
+-		flush_icache_range((unsigned long) &frame->tramp[0],
+-				   (unsigned long) &frame->tramp[2]);
+-	}
+-
+-	return 0;
+-}
+-
+-/*
+- * Restore the current user register values from the user stack,
+- * (except for MSR).
+- */
+-static int
+-restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig)
+-{
+-	unsigned long save_r2 = 0;
+-#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
+-	unsigned long msr;
+-#endif
+-
+-	/* backup/restore the TLS as we don't want it to be modified */
+-	if (!sig)
+-		save_r2 = regs->gpr[2];
+-	/* copy up to but not including MSR */
+-	if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t)))
+-		return 1;
+-	/* copy from orig_r3 (the word after the MSR) up to the end */
+-	if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
+-			     GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
+-		return 1;
+-	if (!sig)
+-		regs->gpr[2] = save_r2;
+-
+-	/* force the process to reload the FP registers from
+-	   current->thread when it next does FP instructions */
+-	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
+-	if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
+-			     sizeof(sr->mc_fregs)))
+-		return 1;
+-
+-#ifdef CONFIG_ALTIVEC
+-	/* force the process to reload the altivec registers from
+-	   current->thread when it next does altivec instructions */
+-	regs->msr &= ~MSR_VEC;
+-	if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
+-		/* restore altivec registers from the stack */
+-		if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
+-				     sizeof(sr->mc_vregs)))
+-			return 1;
+-	} else if (current->thread.used_vr)
+-		memset(&current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
+-
+-	/* Always get VRSAVE back */
+-	if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
+-		return 1;
+-#endif /* CONFIG_ALTIVEC */
+-
+-#ifdef CONFIG_SPE
+-	/* force the process to reload the spe registers from
+-	   current->thread when it next does spe instructions */
+-	regs->msr &= ~MSR_SPE;
+-	if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
+-		/* restore spe registers from the stack */
+-		if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
+-				     ELF_NEVRREG * sizeof(u32)))
+-			return 1;
+-	} else if (current->thread.used_spe)
+-		memset(&current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
+-
+-	/* Always get SPEFSCR back */
+-	if (__get_user(current->thread.spefscr, (u32 *)&sr->mc_vregs + ELF_NEVRREG))
+-		return 1;
+-#endif /* CONFIG_SPE */
+-
+-#ifndef CONFIG_SMP
+-	preempt_disable();
+-	if (last_task_used_math == current)
+-		last_task_used_math = NULL;
+-	if (last_task_used_altivec == current)
+-		last_task_used_altivec = NULL;
+-	if (last_task_used_spe == current)
+-		last_task_used_spe = NULL;
+-	preempt_enable();
+-#endif
+-	return 0;
+-}
+-
+-/*
+- * Restore the user process's signal mask
+- */
+-static void
+-restore_sigmask(sigset_t *set)
+-{
+-	sigdelsetmask(set, ~_BLOCKABLE);
+-	spin_lock_irq(&current->sighand->siglock);
+-	current->blocked = *set;
+-	recalc_sigpending();
+-	spin_unlock_irq(&current->sighand->siglock);
+-}
+-
+-/*
+- * Set up a signal frame for a "real-time" signal handler
+- * (one which gets siginfo).
+- */
+-static void
+-handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
+-		 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
+-		 unsigned long newsp)
+-{
+-	struct rt_sigframe __user *rt_sf;
+-	struct mcontext __user *frame;
+-	unsigned long origsp = newsp;
+-
+-	/* Set up Signal Frame */
+-	/* Put a Real Time Context onto stack */
+-	newsp -= sizeof(*rt_sf);
+-	rt_sf = (struct rt_sigframe __user *) newsp;
+-
+-	/* create a stack frame for the caller of the handler */
+-	newsp -= __SIGNAL_FRAMESIZE + 16;
+-
+-	if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
+-		goto badframe;
+-
+-	/* Put the siginfo & fill in most of the ucontext */
+-	if (copy_siginfo_to_user(&rt_sf->info, info)
+-	    || __put_user(0, &rt_sf->uc.uc_flags)
+-	    || __put_user(0, &rt_sf->uc.uc_link)
+-	    || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
+-	    || __put_user(sas_ss_flags(regs->gpr[1]),
+-			  &rt_sf->uc.uc_stack.ss_flags)
+-	    || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
+-	    || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
+-	    || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
+-		goto badframe;
+-
+-	/* Save user registers on the stack */
+-	frame = &rt_sf->uc.uc_mcontext;
+-	if (save_user_regs(regs, frame, __NR_rt_sigreturn))
+-		goto badframe;
+-
+-	if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
+-		goto badframe;
+-	regs->gpr[1] = newsp;
+-	regs->gpr[3] = sig;
+-	regs->gpr[4] = (unsigned long) &rt_sf->info;
+-	regs->gpr[5] = (unsigned long) &rt_sf->uc;
+-	regs->gpr[6] = (unsigned long) rt_sf;
+-	regs->nip = (unsigned long) ka->sa.sa_handler;
+-	regs->link = (unsigned long) frame->tramp;
+-	regs->trap = 0;
+-
+-	return;
+-
+-badframe:
+-#ifdef DEBUG_SIG
+-	printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
+-	       regs, frame, newsp);
+-#endif
+-	force_sigsegv(sig, current);
+-}
+-
+-static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
+-{
+-	sigset_t set;
+-	struct mcontext __user *mcp;
+-
+-	if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set))
+-	    || __get_user(mcp, &ucp->uc_regs))
+-		return -EFAULT;
+-	restore_sigmask(&set);
+-	if (restore_user_regs(regs, mcp, sig))
+-		return -EFAULT;
+-
+-	return 0;
+-}
+-
+-int sys_swapcontext(struct ucontext __user *old_ctx,
+-		    struct ucontext __user *new_ctx,
+-		    int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
+-{
+-	unsigned char tmp;
+-
+-	/* Context size is for future use. Right now, we only make sure
+-	 * we are passed something we understand
+-	 */
+-	if (ctx_size < sizeof(struct ucontext))
+-		return -EINVAL;
+-
+-	if (old_ctx != NULL) {
+-		if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
+-		    || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
+-		    || __copy_to_user(&old_ctx->uc_sigmask,
+-				      &current->blocked, sizeof(sigset_t))
+-		    || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs))
+-			return -EFAULT;
+-	}
+-	if (new_ctx == NULL)
+-		return 0;
+-	if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx))
+-	    || __get_user(tmp, (u8 __user *) new_ctx)
+-	    || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
+-		return -EFAULT;
+-
+-	/*
+-	 * If we get a fault copying the context into the kernel's
+-	 * image of the user's registers, we can't just return -EFAULT
+-	 * because the user's registers will be corrupted.  For instance
+-	 * the NIP value may have been updated but not some of the
+-	 * other registers.  Given that we have done the access_ok
+-	 * and successfully read the first and last bytes of the region
+-	 * above, this should only happen in an out-of-memory situation
+-	 * or if another thread unmaps the region containing the context.
+-	 * We kill the task with a SIGSEGV in this situation.
+-	 */
+-	if (do_setcontext(new_ctx, regs, 0))
+-		do_exit(SIGSEGV);
+-	sigreturn_exit(regs);
+-	/* doesn't actually return back to here */
+-	return 0;
+-}
+-
+-int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+-		     struct pt_regs *regs)
+-{
+-	struct rt_sigframe __user *rt_sf;
+-
+-	/* Always make any pending restarted system calls return -EINTR */
+-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+-
+-	rt_sf = (struct rt_sigframe __user *)
+-		(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
+-	if (!access_ok(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe)))
+-		goto bad;
+-	if (do_setcontext(&rt_sf->uc, regs, 1))
+-		goto bad;
+-
+-	/*
+-	 * It's not clear whether or why it is desirable to save the
+-	 * sigaltstack setting on signal delivery and restore it on
+-	 * signal return.  But other architectures do this and we have
+-	 * always done it up until now so it is probably better not to
+-	 * change it.  -- paulus
+-	 */
+-	do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
+-
+-	sigreturn_exit(regs);		/* doesn't return here */
+-	return 0;
+-
+- bad:
+-	force_sig(SIGSEGV, current);
+-	return 0;
+-}
+-
+-int sys_debug_setcontext(struct ucontext __user *ctx,
+-			 int ndbg, struct sig_dbg_op __user *dbg,
+-			 int r6, int r7, int r8,
+-			 struct pt_regs *regs)
+-{
+-	struct sig_dbg_op op;
+-	int i;
+-	unsigned long new_msr = regs->msr;
+-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+-	unsigned long new_dbcr0 = current->thread.dbcr0;
+-#endif
+-
+-	for (i=0; i<ndbg; i++) {
+-		if (__copy_from_user(&op, dbg, sizeof(op)))
+-			return -EFAULT;
+-		switch (op.dbg_type) {
+-		case SIG_DBG_SINGLE_STEPPING:
+-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+-			if (op.dbg_value) {
+-				new_msr |= MSR_DE;
+-				new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
+-			} else {
+-				new_msr &= ~MSR_DE;
+-				new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
+-			}
+-#else
+-			if (op.dbg_value)
+-				new_msr |= MSR_SE;
+-			else
+-				new_msr &= ~MSR_SE;
+-#endif
+-			break;
+-		case SIG_DBG_BRANCH_TRACING:
+-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+-			return -EINVAL;
+-#else
+-			if (op.dbg_value)
+-				new_msr |= MSR_BE;
+-			else
+-				new_msr &= ~MSR_BE;
+-#endif
+-			break;
+-
+-		default:
+-			return -EINVAL;
+-		}
+-	}
+-
+-	/* We wait until here to actually install the values in the
+-	   registers so if we fail in the above loop, it will not
+-	   affect the contents of these registers.  After this point,
+-	   failure is a problem, anyway, and it's very unlikely unless
+-	   the user is really doing something wrong. */
+-	regs->msr = new_msr;
+-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+-	current->thread.dbcr0 = new_dbcr0;
+-#endif
+-
+-	/*
+-	 * If we get a fault copying the context into the kernel's
+-	 * image of the user's registers, we can't just return -EFAULT
+-	 * because the user's registers will be corrupted.  For instance
+-	 * the NIP value may have been updated but not some of the
+-	 * other registers.  Given that we have done the access_ok
+-	 * and successfully read the first and last bytes of the region
+-	 * above, this should only happen in an out-of-memory situation
+-	 * or if another thread unmaps the region containing the context.
+-	 * We kill the task with a SIGSEGV in this situation.
+-	 */
+-	if (do_setcontext(ctx, regs, 1)) {
+-		force_sig(SIGSEGV, current);
+-		goto out;
+-	}
+-
+-	/*
+-	 * It's not clear whether or why it is desirable to save the
+-	 * sigaltstack setting on signal delivery and restore it on
+-	 * signal return.  But other architectures do this and we have
+-	 * always done it up until now so it is probably better not to
+-	 * change it.  -- paulus
+-	 */
+-	do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
+-
+-	sigreturn_exit(regs);
+-	/* doesn't actually return back to here */
+-
+- out:
+-	return 0;
+-}
+-
+-/*
+- * OK, we're invoking a handler
+- */
+-static void
+-handle_signal(unsigned long sig, struct k_sigaction *ka,
+-	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
+-	      unsigned long newsp)
+-{
+-	struct sigcontext __user *sc;
+-	struct sigregs __user *frame;
+-	unsigned long origsp = newsp;
+-
+-	/* Set up Signal Frame */
+-	newsp -= sizeof(struct sigregs);
+-	frame = (struct sigregs __user *) newsp;
+-
+-	/* Put a sigcontext on the stack */
+-	newsp -= sizeof(*sc);
+-	sc = (struct sigcontext __user *) newsp;
+-
+-	/* create a stack frame for the caller of the handler */
+-	newsp -= __SIGNAL_FRAMESIZE;
+-
+-	if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
+-		goto badframe;
+-
+-#if _NSIG != 64
+-#error "Please adjust handle_signal()"
+-#endif
+-	if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
+-	    || __put_user(oldset->sig[0], &sc->oldmask)
+-	    || __put_user(oldset->sig[1], &sc->_unused[3])
+-	    || __put_user((struct pt_regs __user *)frame, &sc->regs)
+-	    || __put_user(sig, &sc->signal))
+-		goto badframe;
+-
+-	if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
+-		goto badframe;
+-
+-	if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
+-		goto badframe;
+-	regs->gpr[1] = newsp;
+-	regs->gpr[3] = sig;
+-	regs->gpr[4] = (unsigned long) sc;
+-	regs->nip = (unsigned long) ka->sa.sa_handler;
+-	regs->link = (unsigned long) frame->mctx.tramp;
+-	regs->trap = 0;
+-
+-	return;
+-
+-badframe:
+-#ifdef DEBUG_SIG
+-	printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
+-	       regs, frame, newsp);
+-#endif
+-	force_sigsegv(sig, current);
+-}
+-
+-/*
+- * Do a signal return; undo the signal stack.
+- */
+-int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+-		  struct pt_regs *regs)
+-{
+-	struct sigcontext __user *sc;
+-	struct sigcontext sigctx;
+-	struct mcontext __user *sr;
+-	sigset_t set;
+-
+-	/* Always make any pending restarted system calls return -EINTR */
+-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+-
+-	sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+-	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+-		goto badframe;
+-
+-	set.sig[0] = sigctx.oldmask;
+-	set.sig[1] = sigctx._unused[3];
+-	restore_sigmask(&set);
+-
+-	sr = (struct mcontext __user *) sigctx.regs;
+-	if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
+-	    || restore_user_regs(regs, sr, 1))
+-		goto badframe;
+-
+-	sigreturn_exit(regs);		/* doesn't return */
+-	return 0;
+-
+-badframe:
+-	force_sig(SIGSEGV, current);
+-	return 0;
+-}
+-
+-/*
+- * Note that 'init' is a special process: it doesn't get signals it doesn't
+- * want to handle. Thus you cannot kill init even with a SIGKILL even by
+- * mistake.
+- */
+-int do_signal(sigset_t *oldset, struct pt_regs *regs)
+-{
+-	siginfo_t info;
+-	struct k_sigaction ka;
+-	unsigned long frame, newsp;
+-	int signr, ret;
+-
+-	if (try_to_freeze()) {
+-		signr = 0;
+-		if (!signal_pending(current))
+-			goto no_signal;
+-	}
+-
+-	if (!oldset)
+-		oldset = &current->blocked;
+-
+-	newsp = frame = 0;
+-
+-	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+- no_signal:
+-	if (TRAP(regs) == 0x0C00		/* System Call! */
+-	    && regs->ccr & 0x10000000		/* error signalled */
+-	    && ((ret = regs->gpr[3]) == ERESTARTSYS
+-		|| ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
+-		|| ret == ERESTART_RESTARTBLOCK)) {
+-
+-		if (signr > 0
+-		    && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
+-			|| (ret == ERESTARTSYS
+-			    && !(ka.sa.sa_flags & SA_RESTART)))) {
+-			/* make the system call return an EINTR error */
+-			regs->result = -EINTR;
+-			regs->gpr[3] = EINTR;
+-			/* note that the cr0.SO bit is already set */
+-		} else {
+-			regs->nip -= 4;	/* Back up & retry system call */
+-			regs->result = 0;
+-			regs->trap = 0;
+-			if (ret == ERESTART_RESTARTBLOCK)
+-				regs->gpr[0] = __NR_restart_syscall;
+-			else
+-				regs->gpr[3] = regs->orig_gpr3;
+-		}
+-	}
+-
+-	if (signr == 0)
+-		return 0;		/* no signals delivered */
+-
+-	if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
+-	    && !on_sig_stack(regs->gpr[1]))
+-		newsp = current->sas_ss_sp + current->sas_ss_size;
+-	else
+-		newsp = regs->gpr[1];
+-	newsp &= ~0xfUL;
+-
+-	/* Whee!  Actually deliver the signal.  */
+-	if (ka.sa.sa_flags & SA_SIGINFO)
+-		handle_rt_signal(signr, &ka, &info, oldset, regs, newsp);
+-	else
+-		handle_signal(signr, &ka, &info, oldset, regs, newsp);
+-
+-	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 1;
+-}
+-
+diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
+--- a/arch/ppc/kernel/smp.c
++++ b/arch/ppc/kernel/smp.c
+@@ -34,11 +34,11 @@
+ #include <asm/thread_info.h>
+ #include <asm/tlbflush.h>
+ #include <asm/xmon.h>
++#include <asm/machdep.h>
+ 
+ volatile int smp_commenced;
+ int smp_tb_synchronized;
+ struct cpuinfo_PPC cpu_data[NR_CPUS];
+-struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
+ atomic_t ipi_recv;
+ atomic_t ipi_sent;
+ cpumask_t cpu_online_map;
+@@ -51,7 +51,7 @@ EXPORT_SYMBOL(cpu_online_map);
+ EXPORT_SYMBOL(cpu_possible_map);
+ 
+ /* SMP operations for this machine */
+-static struct smp_ops_t *smp_ops;
++struct smp_ops_t *smp_ops;
+ 
+ /* all cpu mappings are 1-1 -- Cort */
+ volatile unsigned long cpu_callin_map[NR_CPUS];
+@@ -74,11 +74,11 @@ extern void __save_cpu_setup(void);
+ #define PPC_MSG_XMON_BREAK	3
+ 
+ static inline void
+-smp_message_pass(int target, int msg, unsigned long data, int wait)
++smp_message_pass(int target, int msg)
+ {
+-	if (smp_ops){
++	if (smp_ops) {
+ 		atomic_inc(&ipi_sent);
+-		smp_ops->message_pass(target,msg,data,wait);
++		smp_ops->message_pass(target, msg);
+ 	}
+ }
+ 
+@@ -119,7 +119,7 @@ void smp_message_recv(int msg, struct pt
+ void smp_send_tlb_invalidate(int cpu)
+ {
+ 	if ( PVR_VER(mfspr(SPRN_PVR)) == 8 )
+-		smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0);
++		smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB);
+ }
+ 
+ void smp_send_reschedule(int cpu)
+@@ -135,13 +135,13 @@ void smp_send_reschedule(int cpu)
+ 	 */
+ 	/* This is only used if `cpu' is running an idle task,
+ 	   so it will reschedule itself anyway... */
+-	smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
++	smp_message_pass(cpu, PPC_MSG_RESCHEDULE);
+ }
+ 
+ #ifdef CONFIG_XMON
+ void smp_send_xmon_break(int cpu)
+ {
+-	smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0);
++	smp_message_pass(cpu, PPC_MSG_XMON_BREAK);
+ }
+ #endif /* CONFIG_XMON */
+ 
+@@ -224,7 +224,7 @@ static int __smp_call_function(void (*fu
+ 	spin_lock(&call_lock);
+ 	call_data = &data;
+ 	/* Send a message to all other CPUs and wait for them to respond */
+-	smp_message_pass(target, PPC_MSG_CALL_FUNCTION, 0, 0);
++	smp_message_pass(target, PPC_MSG_CALL_FUNCTION);
+ 
+ 	/* Wait for response */
+ 	timeout = 1000000;
+@@ -294,7 +294,6 @@ void __init smp_prepare_cpus(unsigned in
+         smp_store_cpu_info(smp_processor_id());
+ 	cpu_callin_map[smp_processor_id()] = 1;
+ 
+-	smp_ops = ppc_md.smp_ops;
+ 	if (smp_ops == NULL) {
+ 		printk("SMP not supported on this machine.\n");
+ 		return;
+@@ -308,9 +307,6 @@ void __init smp_prepare_cpus(unsigned in
+ 	/* Backup CPU 0 state */
+ 	__save_cpu_setup();
+ 
+-	if (smp_ops->space_timers)
+-		smp_ops->space_timers(num_cpus);
+-
+ 	for_each_cpu(cpu) {
+ 		if (cpu == smp_processor_id())
+ 			continue;
+diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
+deleted file mode 100644
+--- a/arch/ppc/kernel/syscalls.c
++++ /dev/null
+@@ -1,268 +0,0 @@
+-/*
+- * arch/ppc/kernel/sys_ppc.c
+- *
+- *  PowerPC version
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- * Derived from "arch/i386/kernel/sys_i386.c"
+- * Adapted from the i386 version by Gary Thomas
+- * Modified by Cort Dougan (cort at cs.nmt.edu)
+- * and Paul Mackerras (paulus at cs.anu.edu.au).
+- *
+- * This file contains various random system calls that
+- * have a non-standard calling sequence on the Linux/PPC
+- * platform.
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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/sched.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/sem.h>
+-#include <linux/msg.h>
+-#include <linux/shm.h>
+-#include <linux/stat.h>
+-#include <linux/syscalls.h>
+-#include <linux/mman.h>
+-#include <linux/sys.h>
+-#include <linux/ipc.h>
+-#include <linux/utsname.h>
+-#include <linux/file.h>
+-#include <linux/unistd.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/ipc.h>
+-#include <asm/semaphore.h>
+-
+-
+-/*
+- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+- *
+- * This is really horribly ugly.
+- */
+-int
+-sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth)
+-{
+-	int version, ret;
+-
+-	version = call >> 16; /* hack for backward compatibility */
+-	call &= 0xffff;
+-
+-	ret = -ENOSYS;
+-	switch (call) {
+-	case SEMOP:
+-		ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
+-				      second, NULL);
+-		break;
+-	case SEMTIMEDOP:
+-		ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
+-				      second, (const struct timespec __user *) fifth);
+-		break;
+-	case SEMGET:
+-		ret = sys_semget (first, second, third);
+-		break;
+-	case SEMCTL: {
+-		union semun fourth;
+-
+-		if (!ptr)
+-			break;
+-		if ((ret = access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
+-		    || (ret = get_user(fourth.__pad, (void __user *__user *)ptr)))
+-			break;
+-		ret = sys_semctl (first, second, third, fourth);
+-		break;
+-		}
+-	case MSGSND:
+-		ret = sys_msgsnd (first, (struct msgbuf __user *) ptr, second, third);
+-		break;
+-	case MSGRCV:
+-		switch (version) {
+-		case 0: {
+-			struct ipc_kludge tmp;
+-
+-			if (!ptr)
+-				break;
+-			if ((ret = access_ok(VERIFY_READ, ptr, sizeof(tmp)) ? 0 : -EFAULT)
+-			    || (ret = copy_from_user(&tmp,
+-					(struct ipc_kludge __user *) ptr,
+-					sizeof (tmp)) ? -EFAULT : 0))
+-				break;
+-			ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
+-					  third);
+-			break;
+-			}
+-		default:
+-			ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
+-					  second, fifth, third);
+-			break;
+-		}
+-		break;
+-	case MSGGET:
+-		ret = sys_msgget ((key_t) first, second);
+-		break;
+-	case MSGCTL:
+-		ret = sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
+-		break;
+-	case SHMAT: {
+-		ulong raddr;
+-
+-		if ((ret = access_ok(VERIFY_WRITE, (ulong __user *) third,
+-				       sizeof(ulong)) ? 0 : -EFAULT))
+-			break;
+-		ret = do_shmat (first, (char __user *) ptr, second, &raddr);
+-		if (ret)
+-			break;
+-		ret = put_user (raddr, (ulong __user *) third);
+-		break;
+-		}
+-	case SHMDT:
+-		ret = sys_shmdt ((char __user *)ptr);
+-		break;
+-	case SHMGET:
+-		ret = sys_shmget (first, second, third);
+-		break;
+-	case SHMCTL:
+-		ret = sys_shmctl (first, second, (struct shmid_ds __user *) ptr);
+-		break;
+-	}
+-
+-	return ret;
+-}
+-
+-/*
+- * sys_pipe() is the normal C calling standard for creating
+- * a pipe. It's not the way unix traditionally does this, though.
+- */
+-int sys_pipe(int __user *fildes)
+-{
+-	int fd[2];
+-	int error;
+-
+-	error = do_pipe(fd);
+-	if (!error) {
+-		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+-			error = -EFAULT;
+-	}
+-	return error;
+-}
+-
+-static inline unsigned long
+-do_mmap2(unsigned long addr, size_t len,
+-	 unsigned long prot, unsigned long flags,
+-	 unsigned long fd, unsigned long pgoff)
+-{
+-	struct file * file = NULL;
+-	int ret = -EBADF;
+-
+-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-	if (!(flags & MAP_ANONYMOUS)) {
+-		if (!(file = fget(fd)))
+-			goto out;
+-	}
+-
+-	down_write(&current->mm->mmap_sem);
+-	ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+-	up_write(&current->mm->mmap_sem);
+-	if (file)
+-		fput(file);
+-out:
+-	return ret;
+-}
+-
+-unsigned long sys_mmap2(unsigned long addr, size_t len,
+-			unsigned long prot, unsigned long flags,
+-			unsigned long fd, unsigned long pgoff)
+-{
+-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+-}
+-
+-unsigned long sys_mmap(unsigned long addr, size_t len,
+-		       unsigned long prot, unsigned long flags,
+-		       unsigned long fd, off_t offset)
+-{
+-	int err = -EINVAL;
+-
+-	if (offset & ~PAGE_MASK)
+-		goto out;
+-
+-	err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+-out:
+-	return err;
+-}
+-
+-/*
+- * Due to some executables calling the wrong select we sometimes
+- * get wrong args.  This determines how the args are being passed
+- * (a single ptr to them all args passed) then calls
+- * sys_select() with the appropriate args. -- Cort
+- */
+-int
+-ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp)
+-{
+-	if ( (unsigned long)n >= 4096 )
+-	{
+-		unsigned long __user *buffer = (unsigned long __user *)n;
+-		if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long))
+-		    || __get_user(n, buffer)
+-		    || __get_user(inp, ((fd_set __user * __user *)(buffer+1)))
+-		    || __get_user(outp, ((fd_set  __user * __user *)(buffer+2)))
+-		    || __get_user(exp, ((fd_set  __user * __user *)(buffer+3)))
+-		    || __get_user(tvp, ((struct timeval  __user * __user *)(buffer+4))))
+-			return -EFAULT;
+-	}
+-	return sys_select(n, inp, outp, exp, tvp);
+-}
+-
+-int sys_uname(struct old_utsname __user * name)
+-{
+-	int err = -EFAULT;
+-
+-	down_read(&uts_sem);
+-	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+-		err = 0;
+-	up_read(&uts_sem);
+-	return err;
+-}
+-
+-int sys_olduname(struct oldold_utsname __user * name)
+-{
+-	int error;
+-
+-	if (!name)
+-		return -EFAULT;
+-	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+-		return -EFAULT;
+-
+-	down_read(&uts_sem);
+-	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
+-	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
+-	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+-	error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
+-	error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+-	error -= __put_user(0,name->release+__OLD_UTS_LEN);
+-	error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+-	error -= __put_user(0,name->version+__OLD_UTS_LEN);
+-	error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+-	error = __put_user(0,name->machine+__OLD_UTS_LEN);
+-	up_read(&uts_sem);
+-
+-	error = error ? -EFAULT : 0;
+-	return error;
+-}
+-
+-/*
+- * We put the arguments in a different order so we only use 6
+- * registers for arguments, rather than 7 as sys_fadvise64_64 needs
+- * (because `offset' goes in r5/r6).
+- */
+-long ppc_fadvise64_64(int fd, int advice, loff_t offset, loff_t len)
+-{
+-	return sys_fadvise64_64(fd, offset, len, advice);
+-}
+diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
+--- a/arch/ppc/kernel/time.c
++++ b/arch/ppc/kernel/time.c
+@@ -66,11 +66,6 @@
+ 
+ #include <asm/time.h>
+ 
+-/* XXX false sharing with below? */
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ unsigned long disarm_decr[NR_CPUS];
+ 
+ extern struct timezone sys_tz;
+@@ -121,6 +116,15 @@ unsigned long profile_pc(struct pt_regs 
+ EXPORT_SYMBOL(profile_pc);
+ #endif
+ 
++void wakeup_decrementer(void)
++{
++	set_dec(tb_ticks_per_jiffy);
++	/* No currently-supported powerbook has a 601,
++	 * so use get_tbl, not native
++	 */
++	last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
++}
++
+ /*
+  * timer_interrupt - gets called when the decrementer overflows,
+  * with interrupts disabled.
+diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
+--- a/arch/ppc/kernel/traps.c
++++ b/arch/ppc/kernel/traps.c
+@@ -41,9 +41,14 @@
+ #ifdef CONFIG_PMAC_BACKLIGHT
+ #include <asm/backlight.h>
+ #endif
+-#include <asm/perfmon.h>
++#include <asm/pmc.h>
+ 
+ #ifdef CONFIG_XMON
++extern int xmon_bpt(struct pt_regs *regs);
++extern int xmon_sstep(struct pt_regs *regs);
++extern int xmon_iabr_match(struct pt_regs *regs);
++extern int xmon_dabr_match(struct pt_regs *regs);
++
+ void (*debugger)(struct pt_regs *regs) = xmon;
+ int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt;
+ int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep;
+@@ -74,7 +79,7 @@ void (*debugger_fault_handler)(struct pt
+ 
+ DEFINE_SPINLOCK(die_lock);
+ 
+-void die(const char * str, struct pt_regs * fp, long err)
++int die(const char * str, struct pt_regs * fp, long err)
+ {
+ 	static int die_counter;
+ 	int nl = 0;
+@@ -232,7 +237,7 @@ platform_machine_check(struct pt_regs *r
+ {
+ }
+ 
+-void MachineCheckException(struct pt_regs *regs)
++void machine_check_exception(struct pt_regs *regs)
+ {
+ 	unsigned long reason = get_mc_reason(regs);
+ 
+@@ -393,14 +398,14 @@ void SMIException(struct pt_regs *regs)
+ #endif
+ }
+ 
+-void UnknownException(struct pt_regs *regs)
++void unknown_exception(struct pt_regs *regs)
+ {
+ 	printk("Bad trap at PC: %lx, MSR: %lx, vector=%lx    %s\n",
+ 	       regs->nip, regs->msr, regs->trap, print_tainted());
+ 	_exception(SIGTRAP, regs, 0, 0);
+ }
+ 
+-void InstructionBreakpoint(struct pt_regs *regs)
++void instruction_breakpoint_exception(struct pt_regs *regs)
+ {
+ 	if (debugger_iabr_match(regs))
+ 		return;
+@@ -575,7 +580,7 @@ extern struct bug_entry __start___bug_ta
+ #define module_find_bug(x)	NULL
+ #endif
+ 
+-static struct bug_entry *find_bug(unsigned long bugaddr)
++struct bug_entry *find_bug(unsigned long bugaddr)
+ {
+ 	struct bug_entry *bug;
+ 
+@@ -622,7 +627,7 @@ int check_bug_trap(struct pt_regs *regs)
+ 	return 0;
+ }
+ 
+-void ProgramCheckException(struct pt_regs *regs)
++void program_check_exception(struct pt_regs *regs)
+ {
+ 	unsigned int reason = get_reason(regs);
+ 	extern int do_mathemu(struct pt_regs *regs);
+@@ -654,7 +659,7 @@ void ProgramCheckException(struct pt_reg
+ 			giveup_fpu(current);
+ 		preempt_enable();
+ 
+-		fpscr = current->thread.fpscr;
++		fpscr = current->thread.fpscr.val;
+ 		fpscr &= fpscr << 22;	/* mask summary bits with enables */
+ 		if (fpscr & FPSCR_VX)
+ 			code = FPE_FLTINV;
+@@ -701,7 +706,7 @@ void ProgramCheckException(struct pt_reg
+ 		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+ }
+ 
+-void SingleStepException(struct pt_regs *regs)
++void single_step_exception(struct pt_regs *regs)
+ {
+ 	regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+ 	if (debugger_sstep(regs))
+@@ -709,7 +714,7 @@ void SingleStepException(struct pt_regs 
+ 	_exception(SIGTRAP, regs, TRAP_TRACE, 0);
+ }
+ 
+-void AlignmentException(struct pt_regs *regs)
++void alignment_exception(struct pt_regs *regs)
+ {
+ 	int fixed;
+ 
+@@ -814,7 +819,18 @@ void TAUException(struct pt_regs *regs)
+ }
+ #endif /* CONFIG_INT_TAU */
+ 
+-void AltivecUnavailException(struct pt_regs *regs)
++/*
++ * FP unavailable trap from kernel - print a message, but let
++ * the task use FP in the kernel until it returns to user mode.
++ */
++void kernel_fp_unavailable_exception(struct pt_regs *regs)
++{
++	regs->msr |= MSR_FP;
++	printk(KERN_ERR "floating point used in kernel (task=%p, pc=%lx)\n",
++	       current, regs->nip);
++}
++
++void altivec_unavailable_exception(struct pt_regs *regs)
+ {
+ 	static int kernel_altivec_count;
+ 
+@@ -835,7 +851,7 @@ void AltivecUnavailException(struct pt_r
+ }
+ 
+ #ifdef CONFIG_ALTIVEC
+-void AltivecAssistException(struct pt_regs *regs)
++void altivec_assist_exception(struct pt_regs *regs)
+ {
+ 	int err;
+ 
+@@ -872,7 +888,7 @@ void AltivecAssistException(struct pt_re
+ #endif /* CONFIG_ALTIVEC */
+ 
+ #ifdef CONFIG_E500
+-void PerformanceMonitorException(struct pt_regs *regs)
++void performance_monitor_exception(struct pt_regs *regs)
+ {
+ 	perf_irq(regs);
+ }
+diff --git a/arch/ppc/kernel/vecemu.c b/arch/ppc/kernel/vecemu.c
+deleted file mode 100644
+--- a/arch/ppc/kernel/vecemu.c
++++ /dev/null
+@@ -1,345 +0,0 @@
+-/*
+- * Routines to emulate some Altivec/VMX instructions, specifically
+- * those that can trap when given denormalized operands in Java mode.
+- */
+-#include <linux/kernel.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <asm/ptrace.h>
+-#include <asm/processor.h>
+-#include <asm/uaccess.h>
+-
+-/* Functions in vector.S */
+-extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b);
+-extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b);
+-extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
+-extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
+-extern void vrefp(vector128 *dst, vector128 *src);
+-extern void vrsqrtefp(vector128 *dst, vector128 *src);
+-extern void vexptep(vector128 *dst, vector128 *src);
+-
+-static unsigned int exp2s[8] = {
+-	0x800000,
+-	0x8b95c2,
+-	0x9837f0,
+-	0xa5fed7,
+-	0xb504f3,
+-	0xc5672a,
+-	0xd744fd,
+-	0xeac0c7
+-};
+-
+-/*
+- * Computes an estimate of 2^x.  The `s' argument is the 32-bit
+- * single-precision floating-point representation of x.
+- */
+-static unsigned int eexp2(unsigned int s)
+-{
+-	int exp, pwr;
+-	unsigned int mant, frac;
+-
+-	/* extract exponent field from input */
+-	exp = ((s >> 23) & 0xff) - 127;
+-	if (exp > 7) {
+-		/* check for NaN input */
+-		if (exp == 128 && (s & 0x7fffff) != 0)
+-			return s | 0x400000;	/* return QNaN */
+-		/* 2^-big = 0, 2^+big = +Inf */
+-		return (s & 0x80000000)? 0: 0x7f800000;	/* 0 or +Inf */
+-	}
+-	if (exp < -23)
+-		return 0x3f800000;	/* 1.0 */
+-
+-	/* convert to fixed point integer in 9.23 representation */
+-	pwr = (s & 0x7fffff) | 0x800000;
+-	if (exp > 0)
+-		pwr <<= exp;
+-	else
+-		pwr >>= -exp;
+-	if (s & 0x80000000)
+-		pwr = -pwr;
+-
+-	/* extract integer part, which becomes exponent part of result */
+-	exp = (pwr >> 23) + 126;
+-	if (exp >= 254)
+-		return 0x7f800000;
+-	if (exp < -23)
+-		return 0;
+-
+-	/* table lookup on top 3 bits of fraction to get mantissa */
+-	mant = exp2s[(pwr >> 20) & 7];
+-
+-	/* linear interpolation using remaining 20 bits of fraction */
+-	asm("mulhwu %0,%1,%2" : "=r" (frac)
+-	    : "r" (pwr << 12), "r" (0x172b83ff));
+-	asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant));
+-	mant += frac;
+-
+-	if (exp >= 0)
+-		return mant + (exp << 23);
+-
+-	/* denormalized result */
+-	exp = -exp;
+-	mant += 1 << (exp - 1);
+-	return mant >> exp;
+-}
+-
+-/*
+- * Computes an estimate of log_2(x).  The `s' argument is the 32-bit
+- * single-precision floating-point representation of x.
+- */
+-static unsigned int elog2(unsigned int s)
+-{
+-	int exp, mant, lz, frac;
+-
+-	exp = s & 0x7f800000;
+-	mant = s & 0x7fffff;
+-	if (exp == 0x7f800000) {	/* Inf or NaN */
+-		if (mant != 0)
+-			s |= 0x400000;	/* turn NaN into QNaN */
+-		return s;
+-	}
+-	if ((exp | mant) == 0)		/* +0 or -0 */
+-		return 0xff800000;	/* return -Inf */
+-
+-	if (exp == 0) {
+-		/* denormalized */
+-		asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant));
+-		mant <<= lz - 8;
+-		exp = (-118 - lz) << 23;
+-	} else {
+-		mant |= 0x800000;
+-		exp -= 127 << 23;
+-	}
+-
+-	if (mant >= 0xb504f3) {				/* 2^0.5 * 2^23 */
+-		exp |= 0x400000;			/* 0.5 * 2^23 */
+-		asm("mulhwu %0,%1,%2" : "=r" (mant)
+-		    : "r" (mant), "r" (0xb504f334));	/* 2^-0.5 * 2^32 */
+-	}
+-	if (mant >= 0x9837f0) {				/* 2^0.25 * 2^23 */
+-		exp |= 0x200000;			/* 0.25 * 2^23 */
+-		asm("mulhwu %0,%1,%2" : "=r" (mant)
+-		    : "r" (mant), "r" (0xd744fccb));	/* 2^-0.25 * 2^32 */
+-	}
+-	if (mant >= 0x8b95c2) {				/* 2^0.125 * 2^23 */
+-		exp |= 0x100000;			/* 0.125 * 2^23 */
+-		asm("mulhwu %0,%1,%2" : "=r" (mant)
+-		    : "r" (mant), "r" (0xeac0c6e8));	/* 2^-0.125 * 2^32 */
+-	}
+-	if (mant > 0x800000) {				/* 1.0 * 2^23 */
+-		/* calculate (mant - 1) * 1.381097463 */
+-		/* 1.381097463 == 0.125 / (2^0.125 - 1) */
+-		asm("mulhwu %0,%1,%2" : "=r" (frac)
+-		    : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a));
+-		exp += frac;
+-	}
+-	s = exp & 0x80000000;
+-	if (exp != 0) {
+-		if (s)
+-			exp = -exp;
+-		asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp));
+-		lz = 8 - lz;
+-		if (lz > 0)
+-			exp >>= lz;
+-		else if (lz < 0)
+-			exp <<= -lz;
+-		s += ((lz + 126) << 23) + exp;
+-	}
+-	return s;
+-}
+-
+-#define VSCR_SAT	1
+-
+-static int ctsxs(unsigned int x, int scale, unsigned int *vscrp)
+-{
+-	int exp, mant;
+-
+-	exp = (x >> 23) & 0xff;
+-	mant = x & 0x7fffff;
+-	if (exp == 255 && mant != 0)
+-		return 0;		/* NaN -> 0 */
+-	exp = exp - 127 + scale;
+-	if (exp < 0)
+-		return 0;		/* round towards zero */
+-	if (exp >= 31) {
+-		/* saturate, unless the result would be -2^31 */
+-		if (x + (scale << 23) != 0xcf000000)
+-			*vscrp |= VSCR_SAT;
+-		return (x & 0x80000000)? 0x80000000: 0x7fffffff;
+-	}
+-	mant |= 0x800000;
+-	mant = (mant << 7) >> (30 - exp);
+-	return (x & 0x80000000)? -mant: mant;
+-}
+-
+-static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp)
+-{
+-	int exp;
+-	unsigned int mant;
+-
+-	exp = (x >> 23) & 0xff;
+-	mant = x & 0x7fffff;
+-	if (exp == 255 && mant != 0)
+-		return 0;		/* NaN -> 0 */
+-	exp = exp - 127 + scale;
+-	if (exp < 0)
+-		return 0;		/* round towards zero */
+-	if (x & 0x80000000) {
+-		/* negative => saturate to 0 */
+-		*vscrp |= VSCR_SAT;
+-		return 0;
+-	}
+-	if (exp >= 32) {
+-		/* saturate */
+-		*vscrp |= VSCR_SAT;
+-		return 0xffffffff;
+-	}
+-	mant |= 0x800000;
+-	mant = (mant << 8) >> (31 - exp);
+-	return mant;
+-}
+-
+-/* Round to floating integer, towards 0 */
+-static unsigned int rfiz(unsigned int x)
+-{
+-	int exp;
+-
+-	exp = ((x >> 23) & 0xff) - 127;
+-	if (exp == 128 && (x & 0x7fffff) != 0)
+-		return x | 0x400000;	/* NaN -> make it a QNaN */
+-	if (exp >= 23)
+-		return x;		/* it's an integer already (or Inf) */
+-	if (exp < 0)
+-		return x & 0x80000000;	/* |x| < 1.0 rounds to 0 */
+-	return x & ~(0x7fffff >> exp);
+-}
+-
+-/* Round to floating integer, towards +/- Inf */
+-static unsigned int rfii(unsigned int x)
+-{
+-	int exp, mask;
+-
+-	exp = ((x >> 23) & 0xff) - 127;
+-	if (exp == 128 && (x & 0x7fffff) != 0)
+-		return x | 0x400000;	/* NaN -> make it a QNaN */
+-	if (exp >= 23)
+-		return x;		/* it's an integer already (or Inf) */
+-	if ((x & 0x7fffffff) == 0)
+-		return x;		/* +/-0 -> +/-0 */
+-	if (exp < 0)
+-		/* 0 < |x| < 1.0 rounds to +/- 1.0 */
+-		return (x & 0x80000000) | 0x3f800000;
+-	mask = 0x7fffff >> exp;
+-	/* mantissa overflows into exponent - that's OK,
+-	   it can't overflow into the sign bit */
+-	return (x + mask) & ~mask;
+-}
+-
+-/* Round to floating integer, to nearest */
+-static unsigned int rfin(unsigned int x)
+-{
+-	int exp, half;
+-
+-	exp = ((x >> 23) & 0xff) - 127;
+-	if (exp == 128 && (x & 0x7fffff) != 0)
+-		return x | 0x400000;	/* NaN -> make it a QNaN */
+-	if (exp >= 23)
+-		return x;		/* it's an integer already (or Inf) */
+-	if (exp < -1)
+-		return x & 0x80000000;	/* |x| < 0.5 -> +/-0 */
+-	if (exp == -1)
+-		/* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */
+-		return (x & 0x80000000) | 0x3f800000;
+-	half = 0x400000 >> exp;
+-	/* add 0.5 to the magnitude and chop off the fraction bits */
+-	return (x + half) & ~(0x7fffff >> exp);
+-}
+-
+-int emulate_altivec(struct pt_regs *regs)
+-{
+-	unsigned int instr, i;
+-	unsigned int va, vb, vc, vd;
+-	vector128 *vrs;
+-
+-	if (get_user(instr, (unsigned int __user *) regs->nip))
+-		return -EFAULT;
+-	if ((instr >> 26) != 4)
+-		return -EINVAL;		/* not an altivec instruction */
+-	vd = (instr >> 21) & 0x1f;
+-	va = (instr >> 16) & 0x1f;
+-	vb = (instr >> 11) & 0x1f;
+-	vc = (instr >> 6) & 0x1f;
+-
+-	vrs = current->thread.vr;
+-	switch (instr & 0x3f) {
+-	case 10:
+-		switch (vc) {
+-		case 0:	/* vaddfp */
+-			vaddfp(&vrs[vd], &vrs[va], &vrs[vb]);
+-			break;
+-		case 1:	/* vsubfp */
+-			vsubfp(&vrs[vd], &vrs[va], &vrs[vb]);
+-			break;
+-		case 4:	/* vrefp */
+-			vrefp(&vrs[vd], &vrs[vb]);
+-			break;
+-		case 5:	/* vrsqrtefp */
+-			vrsqrtefp(&vrs[vd], &vrs[vb]);
+-			break;
+-		case 6:	/* vexptefp */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = eexp2(vrs[vb].u[i]);
+-			break;
+-		case 7:	/* vlogefp */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = elog2(vrs[vb].u[i]);
+-			break;
+-		case 8:		/* vrfin */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = rfin(vrs[vb].u[i]);
+-			break;
+-		case 9:		/* vrfiz */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = rfiz(vrs[vb].u[i]);
+-			break;
+-		case 10:	/* vrfip */
+-			for (i = 0; i < 4; ++i) {
+-				u32 x = vrs[vb].u[i];
+-				x = (x & 0x80000000)? rfiz(x): rfii(x);
+-				vrs[vd].u[i] = x;
+-			}
+-			break;
+-		case 11:	/* vrfim */
+-			for (i = 0; i < 4; ++i) {
+-				u32 x = vrs[vb].u[i];
+-				x = (x & 0x80000000)? rfii(x): rfiz(x);
+-				vrs[vd].u[i] = x;
+-			}
+-			break;
+-		case 14:	/* vctuxs */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
+-						&current->thread.vscr.u[3]);
+-			break;
+-		case 15:	/* vctsxs */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
+-						&current->thread.vscr.u[3]);
+-			break;
+-		default:
+-			return -EINVAL;
+-		}
+-		break;
+-	case 46:	/* vmaddfp */
+-		vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
+-		break;
+-	case 47:	/* vnmsubfp */
+-		vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
+-		break;
+-	default:
+-		return -EINVAL;
+-	}
+-
+-	return 0;
+-}
+diff --git a/arch/ppc/kernel/vector.S b/arch/ppc/kernel/vector.S
+deleted file mode 100644
+--- a/arch/ppc/kernel/vector.S
++++ /dev/null
+@@ -1,217 +0,0 @@
+-#include <asm/ppc_asm.h>
+-#include <asm/processor.h>
+-
+-/*
+- * The routines below are in assembler so we can closely control the
+- * usage of floating-point registers.  These routines must be called
+- * with preempt disabled.
+- */
+-	.data
+-fpzero:
+-	.long	0
+-fpone:
+-	.long	0x3f800000	/* 1.0 in single-precision FP */
+-fphalf:
+-	.long	0x3f000000	/* 0.5 in single-precision FP */
+-
+-	.text
+-/*
+- * Internal routine to enable floating point and set FPSCR to 0.
+- * Don't call it from C; it doesn't use the normal calling convention.
+- */
+-fpenable:
+-	mfmsr	r10
+-	ori	r11,r10,MSR_FP
+-	mtmsr	r11
+-	isync
+-	stfd	fr0,24(r1)
+-	stfd	fr1,16(r1)
+-	stfd	fr31,8(r1)
+-	lis	r11,fpzero at ha
+-	mffs	fr31
+-	lfs	fr1,fpzero at l(r11)
+-	mtfsf	0xff,fr1
+-	blr
+-
+-fpdisable:
+-	mtfsf	0xff,fr31
+-	lfd	fr31,8(r1)
+-	lfd	fr1,16(r1)
+-	lfd	fr0,24(r1)
+-	mtmsr	r10
+-	isync
+-	blr
+-
+-/*
+- * Vector add, floating point.
+- */
+-	.globl	vaddfp
+-vaddfp:
+-	stwu	r1,-32(r1)
+-	mflr	r0
+-	stw	r0,36(r1)
+-	bl	fpenable
+-	li	r0,4
+-	mtctr	r0
+-	li	r6,0
+-1:	lfsx	fr0,r4,r6
+-	lfsx	fr1,r5,r6
+-	fadds	fr0,fr0,fr1
+-	stfsx	fr0,r3,r6
+-	addi	r6,r6,4
+-	bdnz	1b
+-	bl	fpdisable
+-	lwz	r0,36(r1)
+-	mtlr	r0
+-	addi	r1,r1,32
+-	blr
+-
+-/*
+- * Vector subtract, floating point.
+- */
+-	.globl	vsubfp
+-vsubfp:
+-	stwu	r1,-32(r1)
+-	mflr	r0
+-	stw	r0,36(r1)
+-	bl	fpenable
+-	li	r0,4
+-	mtctr	r0
+-	li	r6,0
+-1:	lfsx	fr0,r4,r6
+-	lfsx	fr1,r5,r6
+-	fsubs	fr0,fr0,fr1
+-	stfsx	fr0,r3,r6
+-	addi	r6,r6,4
+-	bdnz	1b
+-	bl	fpdisable
+-	lwz	r0,36(r1)
+-	mtlr	r0
+-	addi	r1,r1,32
+-	blr
+-
+-/*
+- * Vector multiply and add, floating point.
+- */
+-	.globl	vmaddfp
+-vmaddfp:
+-	stwu	r1,-48(r1)
+-	mflr	r0
+-	stw	r0,52(r1)
+-	bl	fpenable
+-	stfd	fr2,32(r1)
+-	li	r0,4
+-	mtctr	r0
+-	li	r7,0
+-1:	lfsx	fr0,r4,r7
+-	lfsx	fr1,r5,r7
+-	lfsx	fr2,r6,r7
+-	fmadds	fr0,fr0,fr2,fr1
+-	stfsx	fr0,r3,r7
+-	addi	r7,r7,4
+-	bdnz	1b
+-	lfd	fr2,32(r1)
+-	bl	fpdisable
+-	lwz	r0,52(r1)
+-	mtlr	r0
+-	addi	r1,r1,48
+-	blr
+-
+-/*
+- * Vector negative multiply and subtract, floating point.
+- */
+-	.globl	vnmsubfp
+-vnmsubfp:
+-	stwu	r1,-48(r1)
+-	mflr	r0
+-	stw	r0,52(r1)
+-	bl	fpenable
+-	stfd	fr2,32(r1)
+-	li	r0,4
+-	mtctr	r0
+-	li	r7,0
+-1:	lfsx	fr0,r4,r7
+-	lfsx	fr1,r5,r7
+-	lfsx	fr2,r6,r7
+-	fnmsubs	fr0,fr0,fr2,fr1
+-	stfsx	fr0,r3,r7
+-	addi	r7,r7,4
+-	bdnz	1b
+-	lfd	fr2,32(r1)
+-	bl	fpdisable
+-	lwz	r0,52(r1)
+-	mtlr	r0
+-	addi	r1,r1,48
+-	blr
+-
+-/*
+- * Vector reciprocal estimate.  We just compute 1.0/x.
+- * r3 -> destination, r4 -> source.
+- */
+-	.globl	vrefp
+-vrefp:
+-	stwu	r1,-32(r1)
+-	mflr	r0
+-	stw	r0,36(r1)
+-	bl	fpenable
+-	lis	r9,fpone at ha
+-	li	r0,4
+-	lfs	fr1,fpone at l(r9)
+-	mtctr	r0
+-	li	r6,0
+-1:	lfsx	fr0,r4,r6
+-	fdivs	fr0,fr1,fr0
+-	stfsx	fr0,r3,r6
+-	addi	r6,r6,4
+-	bdnz	1b
+-	bl	fpdisable
+-	lwz	r0,36(r1)
+-	mtlr	r0
+-	addi	r1,r1,32
+-	blr
+-
+-/*
+- * Vector reciprocal square-root estimate, floating point.
+- * We use the frsqrte instruction for the initial estimate followed
+- * by 2 iterations of Newton-Raphson to get sufficient accuracy.
+- * r3 -> destination, r4 -> source.
+- */
+-	.globl	vrsqrtefp
+-vrsqrtefp:
+-	stwu	r1,-48(r1)
+-	mflr	r0
+-	stw	r0,52(r1)
+-	bl	fpenable
+-	stfd	fr2,32(r1)
+-	stfd	fr3,40(r1)
+-	stfd	fr4,48(r1)
+-	stfd	fr5,56(r1)
+-	lis	r9,fpone at ha
+-	lis	r8,fphalf at ha
+-	li	r0,4
+-	lfs	fr4,fpone at l(r9)
+-	lfs	fr5,fphalf at l(r8)
+-	mtctr	r0
+-	li	r6,0
+-1:	lfsx	fr0,r4,r6
+-	frsqrte	fr1,fr0		/* r = frsqrte(s) */
+-	fmuls	fr3,fr1,fr0	/* r * s */
+-	fmuls	fr2,fr1,fr5	/* r * 0.5 */
+-	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
+-	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
+-	fmuls	fr3,fr1,fr0	/* r * s */
+-	fmuls	fr2,fr1,fr5	/* r * 0.5 */
+-	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
+-	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
+-	stfsx	fr1,r3,r6
+-	addi	r6,r6,4
+-	bdnz	1b
+-	lfd	fr5,56(r1)
+-	lfd	fr4,48(r1)
+-	lfd	fr3,40(r1)
+-	lfd	fr2,32(r1)
+-	bl	fpdisable
+-	lwz	r0,36(r1)
+-	mtlr	r0
+-	addi	r1,r1,32
+-	blr
+diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
+--- a/arch/ppc/kernel/vmlinux.lds.S
++++ b/arch/ppc/kernel/vmlinux.lds.S
+@@ -149,32 +149,6 @@ SECTIONS
+ 
+   . = ALIGN(4096);
+   _sextratext = .;
+-  __pmac_begin = .;
+-  .pmac.text : { *(.pmac.text) }
+-  .pmac.data : { *(.pmac.data) }
+-  . = ALIGN(4096);
+-  __pmac_end = .;
+-
+-  . = ALIGN(4096);
+-  __prep_begin = .;
+-  .prep.text : { *(.prep.text) }
+-  .prep.data : { *(.prep.data) }
+-  . = ALIGN(4096);
+-  __prep_end = .;
+-
+-  . = ALIGN(4096);
+-  __chrp_begin = .;
+-  .chrp.text : { *(.chrp.text) }
+-  .chrp.data : { *(.chrp.data) }
+-  . = ALIGN(4096);
+-  __chrp_end = .;
+-
+-  . = ALIGN(4096);
+-  __openfirmware_begin = .;
+-  .openfirmware.text : { *(.openfirmware.text) }
+-  .openfirmware.data : { *(.openfirmware.data) }
+-  . = ALIGN(4096);
+-  __openfirmware_end = .;
+   _eextratext = .;
+ 
+   __bss_start = .;
+diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S
+--- a/arch/ppc/lib/string.S
++++ b/arch/ppc/lib/string.S
+@@ -65,9 +65,9 @@
+ 	.stabs	"arch/ppc/lib/",N_SO,0,0,0f
+ 	.stabs	"string.S",N_SO,0,0,0f
+ 
+-CACHELINE_BYTES = L1_CACHE_LINE_SIZE
+-LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE
+-CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1)
++CACHELINE_BYTES = L1_CACHE_BYTES
++LG_CACHELINE_BYTES = L1_CACHE_SHIFT
++CACHELINE_MASK = (L1_CACHE_BYTES-1)
+ 
+ _GLOBAL(strcpy)
+ 	addi	r5,r3,-1
+@@ -265,12 +265,12 @@ _GLOBAL(cacheable_memcpy)
+ 	dcbz	r11,r6
+ #endif
+ 	COPY_16_BYTES
+-#if L1_CACHE_LINE_SIZE >= 32
++#if L1_CACHE_BYTES >= 32
+ 	COPY_16_BYTES
+-#if L1_CACHE_LINE_SIZE >= 64
++#if L1_CACHE_BYTES >= 64
+ 	COPY_16_BYTES
+ 	COPY_16_BYTES
+-#if L1_CACHE_LINE_SIZE >= 128
++#if L1_CACHE_BYTES >= 128
+ 	COPY_16_BYTES
+ 	COPY_16_BYTES
+ 	COPY_16_BYTES
+@@ -485,12 +485,12 @@ _GLOBAL(__copy_tofrom_user)
+ 	.text
+ /* the main body of the cacheline loop */
+ 	COPY_16_BYTES_WITHEX(0)
+-#if L1_CACHE_LINE_SIZE >= 32
++#if L1_CACHE_BYTES >= 32
+ 	COPY_16_BYTES_WITHEX(1)
+-#if L1_CACHE_LINE_SIZE >= 64
++#if L1_CACHE_BYTES >= 64
+ 	COPY_16_BYTES_WITHEX(2)
+ 	COPY_16_BYTES_WITHEX(3)
+-#if L1_CACHE_LINE_SIZE >= 128
++#if L1_CACHE_BYTES >= 128
+ 	COPY_16_BYTES_WITHEX(4)
+ 	COPY_16_BYTES_WITHEX(5)
+ 	COPY_16_BYTES_WITHEX(6)
+@@ -544,12 +544,12 @@ _GLOBAL(__copy_tofrom_user)
+  * 104f (if in read part) or 105f (if in write part), after updating r5
+  */
+ 	COPY_16_BYTES_EXCODE(0)
+-#if L1_CACHE_LINE_SIZE >= 32
++#if L1_CACHE_BYTES >= 32
+ 	COPY_16_BYTES_EXCODE(1)
+-#if L1_CACHE_LINE_SIZE >= 64
++#if L1_CACHE_BYTES >= 64
+ 	COPY_16_BYTES_EXCODE(2)
+ 	COPY_16_BYTES_EXCODE(3)
+-#if L1_CACHE_LINE_SIZE >= 128
++#if L1_CACHE_BYTES >= 128
+ 	COPY_16_BYTES_EXCODE(4)
+ 	COPY_16_BYTES_EXCODE(5)
+ 	COPY_16_BYTES_EXCODE(6)
+diff --git a/arch/ppc/math-emu/sfp-machine.h b/arch/ppc/math-emu/sfp-machine.h
+--- a/arch/ppc/math-emu/sfp-machine.h
++++ b/arch/ppc/math-emu/sfp-machine.h
+@@ -166,7 +166,7 @@ extern int  fp_pack_ds(void *, long, uns
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ 
+-#define __FPU_FPSCR	(current->thread.fpscr)
++#define __FPU_FPSCR	(current->thread.fpscr.val)
+ 
+ /* We only actually write to the destination register
+  * if exceptions signalled (if any) will not trap.
+diff --git a/arch/ppc/mm/4xx_mmu.c b/arch/ppc/mm/4xx_mmu.c
+--- a/arch/ppc/mm/4xx_mmu.c
++++ b/arch/ppc/mm/4xx_mmu.c
+@@ -110,13 +110,11 @@ unsigned long __init mmu_mapin_ram(void)
+ 		pmd_t *pmdp;
+ 		unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+ 
+-		spin_lock(&init_mm.page_table_lock);
+ 		pmdp = pmd_offset(pgd_offset_k(v), v);
+ 		pmd_val(*pmdp++) = val;
+ 		pmd_val(*pmdp++) = val;
+ 		pmd_val(*pmdp++) = val;
+ 		pmd_val(*pmdp++) = val;
+-		spin_unlock(&init_mm.page_table_lock);
+ 
+ 		v += LARGE_PAGE_SIZE_16M;
+ 		p += LARGE_PAGE_SIZE_16M;
+@@ -127,10 +125,8 @@ unsigned long __init mmu_mapin_ram(void)
+ 		pmd_t *pmdp;
+ 		unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+ 
+-		spin_lock(&init_mm.page_table_lock);
+ 		pmdp = pmd_offset(pgd_offset_k(v), v);
+ 		pmd_val(*pmdp) = val;
+-		spin_unlock(&init_mm.page_table_lock);
+ 
+ 		v += LARGE_PAGE_SIZE_4M;
+ 		p += LARGE_PAGE_SIZE_4M;
+diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
+--- a/arch/ppc/mm/init.c
++++ b/arch/ppc/mm/init.c
+@@ -69,15 +69,12 @@ int init_bootmem_done;
+ int boot_mapsize;
+ #ifdef CONFIG_PPC_PMAC
+ unsigned long agp_special_page;
++EXPORT_SYMBOL(agp_special_page);
+ #endif
+ 
+ extern char _end[];
+ extern char etext[], _stext[];
+ extern char __init_begin, __init_end;
+-extern char __prep_begin, __prep_end;
+-extern char __chrp_begin, __chrp_end;
+-extern char __pmac_begin, __pmac_end;
+-extern char __openfirmware_begin, __openfirmware_end;
+ 
+ #ifdef CONFIG_HIGHMEM
+ pte_t *kmap_pte;
+@@ -167,14 +164,6 @@ void free_initmem(void)
+ 
+ 	printk ("Freeing unused kernel memory:");
+ 	FREESEC(init);
+-	if (_machine != _MACH_Pmac)
+-		FREESEC(pmac);
+-	if (_machine != _MACH_chrp)
+-		FREESEC(chrp);
+-	if (_machine != _MACH_prep)
+-		FREESEC(prep);
+-	if (!have_of)
+-		FREESEC(openfirmware);
+  	printk("\n");
+ 	ppc_md.progress = NULL;
+ #undef FREESEC
+@@ -648,18 +637,16 @@ void update_mmu_cache(struct vm_area_str
+  */
+ int page_is_ram(unsigned long pfn)
+ {
+-	unsigned long paddr = (pfn << PAGE_SHIFT);
+-
+-	return paddr < __pa(high_memory);
++	return pfn < max_pfn;
+ }
+ 
+-pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
++pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ 			      unsigned long size, pgprot_t vma_prot)
+ {
+ 	if (ppc_md.phys_mem_access_prot)
+-		return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot);
++		return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot);
+ 
+-	if (!page_is_ram(addr >> PAGE_SHIFT))
++	if (!page_is_ram(pfn))
+ 		vma_prot = __pgprot(pgprot_val(vma_prot)
+ 				    | _PAGE_GUARDED | _PAGE_NO_CACHE);
+ 	return vma_prot;
+diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
+--- a/arch/ppc/mm/pgtable.c
++++ b/arch/ppc/mm/pgtable.c
+@@ -114,9 +114,9 @@ struct page *pte_alloc_one(struct mm_str
+ 	struct page *ptepage;
+ 
+ #ifdef CONFIG_HIGHPTE
+-	int flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT;
++	gfp_t flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT;
+ #else
+-	int flags = GFP_KERNEL | __GFP_REPEAT;
++	gfp_t flags = GFP_KERNEL | __GFP_REPEAT;
+ #endif
+ 
+ 	ptepage = alloc_pages(flags, 0);
+@@ -280,18 +280,16 @@ map_page(unsigned long va, phys_addr_t p
+ 	pte_t *pg;
+ 	int err = -ENOMEM;
+ 
+-	spin_lock(&init_mm.page_table_lock);
+ 	/* Use upper 10 bits of VA to index the first level map */
+ 	pd = pmd_offset(pgd_offset_k(va), va);
+ 	/* Use middle 10 bits of VA to index the second-level map */
+-	pg = pte_alloc_kernel(&init_mm, pd, va);
++	pg = pte_alloc_kernel(pd, va);
+ 	if (pg != 0) {
+ 		err = 0;
+ 		set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags)));
+ 		if (mem_init_done)
+ 			flush_HPTE(0, va, pmd_val(*pd));
+ 	}
+-	spin_unlock(&init_mm.page_table_lock);
+ 	return err;
+ }
+ 
+diff --git a/arch/ppc/oprofile/Kconfig b/arch/ppc/oprofile/Kconfig
+deleted file mode 100644
+--- a/arch/ppc/oprofile/Kconfig
++++ /dev/null
+@@ -1,23 +0,0 @@
+-
+-menu "Profiling support"
+-	depends on EXPERIMENTAL
+-
+-config PROFILING
+-	bool "Profiling support (EXPERIMENTAL)"
+-	help
+-	  Say Y here to enable the extended profiling support mechanisms used
+-	  by profilers such as OProfile.
+-
+-
+-config OPROFILE
+-	tristate "OProfile system profiling (EXPERIMENTAL)"
+-	depends on PROFILING
+-	help
+-	  OProfile is a profiling system capable of profiling the
+-	  whole system, include the kernel, kernel modules, libraries,
+-	  and applications.
+-
+-	  If unsure, say N.
+-
+-endmenu
+-
+diff --git a/arch/ppc/oprofile/Makefile b/arch/ppc/oprofile/Makefile
+deleted file mode 100644
+--- a/arch/ppc/oprofile/Makefile
++++ /dev/null
+@@ -1,14 +0,0 @@
+-obj-$(CONFIG_OPROFILE) += oprofile.o
+-
+-DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
+-		oprof.o cpu_buffer.o buffer_sync.o \
+-		event_buffer.o oprofile_files.o \
+-		oprofilefs.o oprofile_stats.o \
+-		timer_int.o )
+-
+-oprofile-y := $(DRIVER_OBJS) common.o
+-
+-ifeq ($(CONFIG_FSL_BOOKE),y)
+-	oprofile-y += op_model_fsl_booke.o
+-endif
+-
+diff --git a/arch/ppc/oprofile/common.c b/arch/ppc/oprofile/common.c
+deleted file mode 100644
+--- a/arch/ppc/oprofile/common.c
++++ /dev/null
+@@ -1,161 +0,0 @@
+-/*
+- * PPC 32 oprofile support
+- * Based on PPC64 oprofile support
+- * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, IBM
+- *
+- * Copyright (C) Freescale Semiconductor, Inc 2004
+- *
+- * Author: Andy Fleming
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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/oprofile.h>
+-#include <linux/slab.h>
+-#include <linux/init.h>
+-#include <linux/smp.h>
+-#include <linux/errno.h>
+-#include <asm/ptrace.h>
+-#include <asm/system.h>
+-#include <asm/perfmon.h>
+-#include <asm/cputable.h>
+-
+-#include "op_impl.h"
+-
+-static struct op_ppc32_model *model;
+-
+-static struct op_counter_config ctr[OP_MAX_COUNTER];
+-static struct op_system_config sys;
+-
+-static void op_handle_interrupt(struct pt_regs *regs)
+-{
+-	model->handle_interrupt(regs, ctr);
+-}
+-
+-static int op_ppc32_setup(void)
+-{
+-	/* Install our interrupt handler into the existing hook.  */
+-	if(request_perfmon_irq(&op_handle_interrupt))
+-		return -EBUSY;
+-
+-	mb();
+-
+-	/* Pre-compute the values to stuff in the hardware registers.  */
+-	model->reg_setup(ctr, &sys, model->num_counters);
+-
+-#if 0
+-	/* FIXME: Make multi-cpu work */
+-	/* Configure the registers on all cpus.  */
+-	on_each_cpu(model->reg_setup, NULL, 0, 1);
+-#endif
+-
+-	return 0;
+-}
+-
+-static void op_ppc32_shutdown(void)
+-{
+-	mb();
+-
+-	/* Remove our interrupt handler. We may be removing this module. */
+-	free_perfmon_irq();
+-}
+-
+-static void op_ppc32_cpu_start(void *dummy)
+-{
+-	model->start(ctr);
+-}
+-
+-static int op_ppc32_start(void)
+-{
+-	on_each_cpu(op_ppc32_cpu_start, NULL, 0, 1);
+-	return 0;
+-}
+-
+-static inline void op_ppc32_cpu_stop(void *dummy)
+-{
+-	model->stop();
+-}
+-
+-static void op_ppc32_stop(void)
+-{
+-	on_each_cpu(op_ppc32_cpu_stop, NULL, 0, 1);
+-}
+-
+-static int op_ppc32_create_files(struct super_block *sb, struct dentry *root)
+-{
+-	int i;
+-
+-	for (i = 0; i < model->num_counters; ++i) {
+-		struct dentry *dir;
+-		char buf[3];
+-
+-		snprintf(buf, sizeof buf, "%d", i);
+-		dir = oprofilefs_mkdir(sb, root, buf);
+-
+-		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+-		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+-		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+-		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+-		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+-
+-		/* FIXME: Not sure if this is used */
+-		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+-	}
+-
+-	oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
+-	oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
+-
+-	/* Default to tracing both kernel and user */
+-	sys.enable_kernel = 1;
+-	sys.enable_user = 1;
+-
+-	return 0;
+-}
+-
+-static struct oprofile_operations oprof_ppc32_ops = {
+-	.create_files	= op_ppc32_create_files,
+-	.setup		= op_ppc32_setup,
+-	.shutdown	= op_ppc32_shutdown,
+-	.start		= op_ppc32_start,
+-	.stop		= op_ppc32_stop,
+-	.cpu_type	= NULL		/* To be filled in below. */
+-};
+-
+-int __init oprofile_arch_init(struct oprofile_operations *ops)
+-{
+-	char *name;
+-	int cpu_id = smp_processor_id();
+-
+-#ifdef CONFIG_FSL_BOOKE
+-	model = &op_model_fsl_booke;
+-#else
+-	return -ENODEV;
+-#endif
+-
+-	name = kmalloc(32, GFP_KERNEL);
+-
+-	if (NULL == name)
+-		return -ENOMEM;
+-
+-	sprintf(name, "ppc/%s", cur_cpu_spec[cpu_id]->cpu_name);
+-
+-	oprof_ppc32_ops.cpu_type = name;
+-
+-	model->num_counters = cur_cpu_spec[cpu_id]->num_pmcs;
+-
+-	*ops = oprof_ppc32_ops;
+-
+-	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+-	       oprof_ppc32_ops.cpu_type);
+-
+-	return 0;
+-}
+-
+-void oprofile_arch_exit(void)
+-{
+-	kfree(oprof_ppc32_ops.cpu_type);
+-	oprof_ppc32_ops.cpu_type = NULL;
+-}
+diff --git a/arch/ppc/oprofile/op_impl.h b/arch/ppc/oprofile/op_impl.h
+deleted file mode 100644
+--- a/arch/ppc/oprofile/op_impl.h
++++ /dev/null
+@@ -1,45 +0,0 @@
+-/*
+- * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, IBM
+- *
+- * Based on alpha version.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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 OP_IMPL_H
+-#define OP_IMPL_H 1
+-
+-#define OP_MAX_COUNTER 8
+-
+-/* Per-counter configuration as set via oprofilefs.  */
+-struct op_counter_config {
+-	unsigned long enabled;
+-	unsigned long event;
+-	unsigned long count;
+-	unsigned long kernel;
+-	unsigned long user;
+-	unsigned long unit_mask;
+-};
+-
+-/* System-wide configuration as set via oprofilefs.  */
+-struct op_system_config {
+-	unsigned long enable_kernel;
+-	unsigned long enable_user;
+-};
+-
+-/* Per-arch configuration */
+-struct op_ppc32_model {
+-	void (*reg_setup) (struct op_counter_config *,
+-			   struct op_system_config *,
+-			   int num_counters);
+-	void (*start) (struct op_counter_config *);
+-	void (*stop) (void);
+-	void (*handle_interrupt) (struct pt_regs *,
+-				  struct op_counter_config *);
+-	int num_counters;
+-};
+-
+-#endif /* OP_IMPL_H */
+diff --git a/arch/ppc/oprofile/op_model_fsl_booke.c b/arch/ppc/oprofile/op_model_fsl_booke.c
+deleted file mode 100644
+--- a/arch/ppc/oprofile/op_model_fsl_booke.c
++++ /dev/null
+@@ -1,184 +0,0 @@
+-/*
+- * oprofile/op_model_e500.c
+- *
+- * Freescale Book-E oprofile support, based on ppc64 oprofile support
+- * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, IBM
+- *
+- * Copyright (c) 2004 Freescale Semiconductor, Inc
+- *
+- * Author: Andy Fleming
+- * Maintainer: Kumar Gala <Kumar.Gala 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.
+- */
+-
+-#include <linux/oprofile.h>
+-#include <linux/init.h>
+-#include <linux/smp.h>
+-#include <asm/ptrace.h>
+-#include <asm/system.h>
+-#include <asm/processor.h>
+-#include <asm/cputable.h>
+-#include <asm/reg_booke.h>
+-#include <asm/page.h>
+-#include <asm/perfmon.h>
+-
+-#include "op_impl.h"
+-
+-static unsigned long reset_value[OP_MAX_COUNTER];
+-
+-static int num_counters;
+-static int oprofile_running;
+-
+-static inline unsigned int ctr_read(unsigned int i)
+-{
+-	switch(i) {
+-		case 0:
+-			return mfpmr(PMRN_PMC0);
+-		case 1:
+-			return mfpmr(PMRN_PMC1);
+-		case 2:
+-			return mfpmr(PMRN_PMC2);
+-		case 3:
+-			return mfpmr(PMRN_PMC3);
+-		default:
+-			return 0;
+-	}
+-}
+-
+-static inline void ctr_write(unsigned int i, unsigned int val)
+-{
+-	switch(i) {
+-		case 0:
+-			mtpmr(PMRN_PMC0, val);
+-			break;
+-		case 1:
+-			mtpmr(PMRN_PMC1, val);
+-			break;
+-		case 2:
+-			mtpmr(PMRN_PMC2, val);
+-			break;
+-		case 3:
+-			mtpmr(PMRN_PMC3, val);
+-			break;
+-		default:
+-			break;
+-	}
+-}
+-
+-
+-static void fsl_booke_reg_setup(struct op_counter_config *ctr,
+-			     struct op_system_config *sys,
+-			     int num_ctrs)
+-{
+-	int i;
+-
+-	num_counters = num_ctrs;
+-
+-	/* freeze all counters */
+-	pmc_stop_ctrs();
+-
+-	/* Our counters count up, and "count" refers to
+-	 * how much before the next interrupt, and we interrupt
+-	 * on overflow.  So we calculate the starting value
+-	 * which will give us "count" until overflow.
+-	 * Then we set the events on the enabled counters */
+-	for (i = 0; i < num_counters; ++i) {
+-		reset_value[i] = 0x80000000UL - ctr[i].count;
+-
+-		init_pmc_stop(i);
+-
+-		set_pmc_event(i, ctr[i].event);
+-
+-		set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
+-	}
+-}
+-
+-static void fsl_booke_start(struct op_counter_config *ctr)
+-{
+-	int i;
+-
+-	mtmsr(mfmsr() | MSR_PMM);
+-
+-	for (i = 0; i < num_counters; ++i) {
+-		if (ctr[i].enabled) {
+-			ctr_write(i, reset_value[i]);
+-			/* Set Each enabled counterd to only
+-			 * count when the Mark bit is not set */
+-			set_pmc_marked(i, 1, 0);
+-			pmc_start_ctr(i, 1);
+-		} else {
+-			ctr_write(i, 0);
+-
+-			/* Set the ctr to be stopped */
+-			pmc_start_ctr(i, 0);
+-		}
+-	}
+-
+-	/* Clear the freeze bit, and enable the interrupt.
+-	 * The counters won't actually start until the rfi clears
+-	 * the PMM bit */
+-	pmc_start_ctrs(1);
+-
+-	oprofile_running = 1;
+-
+-	pr_debug("start on cpu %d, pmgc0 %x\n", smp_processor_id(),
+-			mfpmr(PMRN_PMGC0));
+-}
+-
+-static void fsl_booke_stop(void)
+-{
+-	/* freeze counters */
+-	pmc_stop_ctrs();
+-
+-	oprofile_running = 0;
+-
+-	pr_debug("stop on cpu %d, pmgc0 %x\n", smp_processor_id(),
+-			mfpmr(PMRN_PMGC0));
+-
+-	mb();
+-}
+-
+-
+-static void fsl_booke_handle_interrupt(struct pt_regs *regs,
+-				    struct op_counter_config *ctr)
+-{
+-	unsigned long pc;
+-	int is_kernel;
+-	int val;
+-	int i;
+-
+-	/* set the PMM bit (see comment below) */
+-	mtmsr(mfmsr() | MSR_PMM);
+-
+-	pc = regs->nip;
+-	is_kernel = (pc >= KERNELBASE);
+-
+-	for (i = 0; i < num_counters; ++i) {
+-		val = ctr_read(i);
+-		if (val < 0) {
+-			if (oprofile_running && ctr[i].enabled) {
+-				oprofile_add_pc(pc, is_kernel, i);
+-				ctr_write(i, reset_value[i]);
+-			} else {
+-				ctr_write(i, 0);
+-			}
+-		}
+-	}
+-
+-	/* The freeze bit was set by the interrupt. */
+-	/* Clear the freeze bit, and reenable the interrupt.
+-	 * The counters won't actually start until the rfi clears
+-	 * the PMM bit */
+-	pmc_start_ctrs(1);
+-}
+-
+-struct op_ppc32_model op_model_fsl_booke = {
+-	.reg_setup		= fsl_booke_reg_setup,
+-	.start			= fsl_booke_start,
+-	.stop			= fsl_booke_stop,
+-	.handle_interrupt	= fsl_booke_handle_interrupt,
+-};
+diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c
+--- a/arch/ppc/platforms/4xx/bamboo.c
++++ b/arch/ppc/platforms/4xx/bamboo.c
+@@ -51,7 +51,7 @@
+ #include <syslib/gen550.h>
+ #include <syslib/ibm440gx_common.h>
+ 
+-bd_t __res;
++extern bd_t __res;
+ 
+ static struct ibm44x_clocks clocks __initdata;
+ 
+@@ -425,17 +425,7 @@ bamboo_setup_arch(void)
+ void __init platform_init(unsigned long r3, unsigned long r4,
+ 		unsigned long r5, unsigned long r6, unsigned long r7)
+ {
+-	parse_bootinfo(find_bootinfo());
+-
+-	/*
+-	 * If we were passed in a board information, copy it into the
+-	 * residual data area.
+-	 */
+-	if (r3)
+-		__res = *(bd_t *)(r3 + KERNELBASE);
+-
+-
+-	ibm44x_platform_init();
++	ibm44x_platform_init(r3, r4, r5, r6, r7);
+ 
+ 	ppc_md.setup_arch = bamboo_setup_arch;
+ 	ppc_md.show_cpuinfo = bamboo_show_cpuinfo;
+diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
+--- a/arch/ppc/platforms/4xx/ebony.c
++++ b/arch/ppc/platforms/4xx/ebony.c
+@@ -54,7 +54,7 @@
+ #include <syslib/gen550.h>
+ #include <syslib/ibm440gp_common.h>
+ 
+-bd_t __res;
++extern bd_t __res;
+ 
+ static struct ibm44x_clocks clocks __initdata;
+ 
+@@ -90,7 +90,7 @@ ebony_calibrate_decr(void)
+ 	 * on Rev. C silicon then errata forces us to
+ 	 * use the internal clock.
+ 	 */
+-	if (strcmp(cur_cpu_spec[0]->cpu_name, "440GP Rev. B") == 0)
++	if (strcmp(cur_cpu_spec->cpu_name, "440GP Rev. B") == 0)
+ 		freq = EBONY_440GP_RB_SYSCLK;
+ 	else
+ 		freq = EBONY_440GP_RC_SYSCLK;
+@@ -317,16 +317,7 @@ ebony_setup_arch(void)
+ void __init platform_init(unsigned long r3, unsigned long r4,
+ 		unsigned long r5, unsigned long r6, unsigned long r7)
+ {
+-	parse_bootinfo(find_bootinfo());
+-
+-	/*
+-	 * If we were passed in a board information, copy it into the
+-	 * residual data area.
+-	 */
+-	if (r3)
+-		__res = *(bd_t *)(r3 + KERNELBASE);
+-
+-	ibm44x_platform_init();
++	ibm44x_platform_init(r3, r4, r5, r6, r7);
+ 
+ 	ppc_md.setup_arch = ebony_setup_arch;
+ 	ppc_md.show_cpuinfo = ebony_show_cpuinfo;
+diff --git a/arch/ppc/platforms/4xx/ibm440ep.c b/arch/ppc/platforms/4xx/ibm440ep.c
+--- a/arch/ppc/platforms/4xx/ibm440ep.c
++++ b/arch/ppc/platforms/4xx/ibm440ep.c
+@@ -14,6 +14,7 @@
+  */
+ #include <linux/init.h>
+ #include <linux/module.h>
++#include <linux/platform_device.h>
+ #include <platforms/4xx/ibm440ep.h>
+ #include <asm/ocp.h>
+ #include <asm/ppc4xx_pic.h>
+diff --git a/arch/ppc/platforms/4xx/ibmstb4.c b/arch/ppc/platforms/4xx/ibmstb4.c
+--- a/arch/ppc/platforms/4xx/ibmstb4.c
++++ b/arch/ppc/platforms/4xx/ibmstb4.c
+@@ -10,6 +10,7 @@
+  */
+ 
+ #include <linux/init.h>
++#include <linux/platform_device.h>
+ #include <asm/ocp.h>
+ #include <asm/ppc4xx_pic.h>
+ #include <platforms/4xx/ibmstb4.h>
+diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c
+--- a/arch/ppc/platforms/4xx/luan.c
++++ b/arch/ppc/platforms/4xx/luan.c
+@@ -52,7 +52,7 @@
+ #include <syslib/ibm440gx_common.h>
+ #include <syslib/ibm440sp_common.h>
+ 
+-bd_t __res;
++extern bd_t __res;
+ 
+ static struct ibm44x_clocks clocks __initdata;
+ 
+@@ -355,16 +355,7 @@ luan_setup_arch(void)
+ void __init platform_init(unsigned long r3, unsigned long r4,
+ 		unsigned long r5, unsigned long r6, unsigned long r7)
+ {
+-	parse_bootinfo(find_bootinfo());
+-
+-	/*
+-	 * If we were passed in a board information, copy it into the
+-	 * residual data area.
+-	 */
+-	if (r3)
+-		__res = *(bd_t *)(r3 + KERNELBASE);
+-
+-	ibm44x_platform_init();
++	ibm44x_platform_init(r3, r4, r5, r6, r7);
+ 
+ 	ppc_md.setup_arch = luan_setup_arch;
+ 	ppc_md.show_cpuinfo = luan_show_cpuinfo;
+diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
+--- a/arch/ppc/platforms/4xx/ocotea.c
++++ b/arch/ppc/platforms/4xx/ocotea.c
+@@ -52,7 +52,7 @@
+ #include <syslib/gen550.h>
+ #include <syslib/ibm440gx_common.h>
+ 
+-bd_t __res;
++extern bd_t __res;
+ 
+ static struct ibm44x_clocks clocks __initdata;
+ 
+@@ -286,6 +286,15 @@ ocotea_setup_arch(void)
+ 
+ 	ibm440gx_tah_enable();
+ 
++	/*
++	 * Determine various clocks.
++	 * To be completely correct we should get SysClk
++	 * from FPGA, because it can be changed by on-board switches
++	 * --ebs
++	 */
++	ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
++	ocp_sys_info.opb_bus_freq = clocks.opb;
++
+ 	/* Setup TODC access */
+ 	TODC_INIT(TODC_TYPE_DS1743,
+ 			0,
+@@ -324,25 +333,7 @@ static void __init ocotea_init(void)
+ void __init platform_init(unsigned long r3, unsigned long r4,
+ 		unsigned long r5, unsigned long r6, unsigned long r7)
+ {
+-	parse_bootinfo(find_bootinfo());
+-
+-	/*
+-	 * If we were passed in a board information, copy it into the
+-	 * residual data area.
+-	 */
+-	if (r3)
+-		__res = *(bd_t *)(r3 + KERNELBASE);
+-
+-	/*
+-	 * Determine various clocks.
+-	 * To be completely correct we should get SysClk
+-	 * from FPGA, because it can be changed by on-board switches
+-	 * --ebs
+-	 */
+-	ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
+-	ocp_sys_info.opb_bus_freq = clocks.opb;
+-
+-	ibm44x_platform_init();
++	ibm44x_platform_init(r3, r4, r5, r6, r7);
+ 
+ 	ppc_md.setup_arch = ocotea_setup_arch;
+ 	ppc_md.show_cpuinfo = ocotea_show_cpuinfo;
+diff --git a/arch/ppc/platforms/4xx/redwood5.c b/arch/ppc/platforms/4xx/redwood5.c
+--- a/arch/ppc/platforms/4xx/redwood5.c
++++ b/arch/ppc/platforms/4xx/redwood5.c
+@@ -14,7 +14,7 @@
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/pagemap.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/ioport.h>
+ #include <asm/io.h>
+ #include <asm/machdep.h>
+diff --git a/arch/ppc/platforms/4xx/redwood6.c b/arch/ppc/platforms/4xx/redwood6.c
+--- a/arch/ppc/platforms/4xx/redwood6.c
++++ b/arch/ppc/platforms/4xx/redwood6.c
+@@ -12,7 +12,7 @@
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/pagemap.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/ioport.h>
+ #include <asm/io.h>
+ #include <asm/ppc4xx_pic.h>
+diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
+--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
++++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
+@@ -19,7 +19,6 @@
+ 
+ #include <linux/config.h>
+ #include <linux/init.h>
+-#include <linux/seq_file.h>
+ #include <syslib/ppc83xx_setup.h>
+ #include <asm/ppcboot.h>
+ 
+diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
+--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
++++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
+@@ -52,6 +52,10 @@
+ 
+ #include <syslib/ppc85xx_setup.h>
+ 
++static const char *GFAR_PHY_0 = "phy0:0";
++static const char *GFAR_PHY_1 = "phy0:1";
++static const char *GFAR_PHY_3 = "phy0:3";
++
+ /* ************************************************************************
+  *
+  * Setup the architecture
+@@ -63,6 +67,7 @@ mpc8540ads_setup_arch(void)
+ 	bd_t *binfo = (bd_t *) __res;
+ 	unsigned int freq;
+ 	struct gianfar_platform_data *pdata;
++	struct gianfar_mdio_data *mdata;
+ 
+ 	/* get the core frequency */
+ 	freq = binfo->bi_intfreq;
+@@ -89,34 +94,35 @@ mpc8540ads_setup_arch(void)
+ 	invalidate_tlbcam_entry(num_tlbcam_entries - 1);
+ #endif
+ 
++	/* setup the board related info for the MDIO bus */
++	mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
++
++	mdata->irq[0] = MPC85xx_IRQ_EXT5;
++	mdata->irq[1] = MPC85xx_IRQ_EXT5;
++	mdata->irq[2] = -1;
++	mdata->irq[3] = MPC85xx_IRQ_EXT5;
++	mdata->irq[31] = -1;
++	mdata->paddr += binfo->bi_immr_base;
++
+ 	/* setup the board related information for the enet controllers */
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 0;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_0;
+ 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+ 	}
+ 
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 1;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_1;
+ 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+ 	}
+ 
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
+ 	if (pdata) {
+ 		pdata->board_flags = 0;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 3;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_3;
+ 		memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
+ 	}
+ 
+diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
+--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
++++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
+@@ -56,6 +56,10 @@
+ #include <syslib/ppc85xx_setup.h>
+ 
+ 
++static const char *GFAR_PHY_0 = "phy0:0";
++static const char *GFAR_PHY_1 = "phy0:1";
++static const char *GFAR_PHY_3 = "phy0:3";
++
+ /* ************************************************************************
+  *
+  * Setup the architecture
+@@ -68,6 +72,7 @@ mpc8560ads_setup_arch(void)
+ 	bd_t *binfo = (bd_t *) __res;
+ 	unsigned int freq;
+ 	struct gianfar_platform_data *pdata;
++	struct gianfar_mdio_data *mdata;
+ 
+ 	cpm2_reset();
+ 
+@@ -86,24 +91,28 @@ mpc8560ads_setup_arch(void)
+ 	mpc85xx_setup_hose();
+ #endif
+ 
++	/* setup the board related info for the MDIO bus */
++	mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
++
++	mdata->irq[0] = MPC85xx_IRQ_EXT5;
++	mdata->irq[1] = MPC85xx_IRQ_EXT5;
++	mdata->irq[2] = -1;
++	mdata->irq[3] = MPC85xx_IRQ_EXT5;
++	mdata->irq[31] = -1;
++	mdata->paddr += binfo->bi_immr_base;
++
+ 	/* setup the board related information for the enet controllers */
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 0;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_0;
+ 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+ 	}
+ 
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 1;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_1;
+ 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+ 	}
+ 
+diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
+--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
++++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
+@@ -19,7 +19,6 @@
+ 
+ #include <linux/config.h>
+ #include <linux/init.h>
+-#include <linux/seq_file.h>
+ #include <asm/ppcboot.h>
+ 
+ #define BOARD_CCSRBAR		((uint)0xe0000000)
+diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
++++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+@@ -173,10 +173,7 @@ mpc85xx_cds_init_IRQ(void)
+ #ifdef CONFIG_PCI
+ 	openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
+ 
+-	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
+-		irq_desc[i].handler = &i8259_pic;
+-
+-	i8259_init(0);
++	i8259_init(0, 0);
+ #endif
+ 
+ #ifdef CONFIG_CPM2
+@@ -394,6 +391,9 @@ mpc85xx_cds_pcibios_fixup(void)
+ 
+ TODC_ALLOC();
+ 
++static const char *GFAR_PHY_0 = "phy0:0";
++static const char *GFAR_PHY_1 = "phy0:1";
++
+ /* ************************************************************************
+  *
+  * Setup the architecture
+@@ -405,6 +405,7 @@ mpc85xx_cds_setup_arch(void)
+ 	bd_t *binfo = (bd_t *) __res;
+ 	unsigned int freq;
+ 	struct gianfar_platform_data *pdata;
++	struct gianfar_mdio_data *mdata;
+ 
+ 	/* get the core frequency */
+ 	freq = binfo->bi_intfreq;
+@@ -448,44 +449,42 @@ mpc85xx_cds_setup_arch(void)
+ 	invalidate_tlbcam_entry(num_tlbcam_entries - 1);
+ #endif
+ 
++	/* setup the board related info for the MDIO bus */
++	mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
++
++	mdata->irq[0] = MPC85xx_IRQ_EXT5;
++	mdata->irq[1] = MPC85xx_IRQ_EXT5;
++	mdata->irq[2] = -1;
++	mdata->irq[3] = -1;
++	mdata->irq[31] = -1;
++	mdata->paddr += binfo->bi_immr_base;
++
+ 	/* setup the board related information for the enet controllers */
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 0;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_0;
+ 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+ 	}
+ 
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 1;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_1;
+ 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+ 	}
+ 
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 0;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_0;
+ 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+ 	}
+ 
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 1;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_1;
+ 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+ 	}
+ 
+diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
+--- a/arch/ppc/platforms/85xx/sbc8560.c
++++ b/arch/ppc/platforms/85xx/sbc8560.c
+@@ -91,6 +91,9 @@ sbc8560_early_serial_map(void)
+ }
+ #endif
+ 
++static const char *GFAR_PHY_25 = "phy0:25";
++static const char *GFAR_PHY_26 = "phy0:26";
++
+ /* ************************************************************************
+  *
+  * Setup the architecture
+@@ -102,6 +105,7 @@ sbc8560_setup_arch(void)
+ 	bd_t *binfo = (bd_t *) __res;
+ 	unsigned int freq;
+ 	struct gianfar_platform_data *pdata;
++	struct gianfar_mdio_data *mdata;
+ 
+ 	/* get the core frequency */
+ 	freq = binfo->bi_intfreq;
+@@ -126,24 +130,26 @@ sbc8560_setup_arch(void)
+ 	invalidate_tlbcam_entry(num_tlbcam_entries - 1);
+ #endif
+ 
++	/* setup the board related info for the MDIO bus */
++	mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
++
++	mdata->irq[25] = MPC85xx_IRQ_EXT6;
++	mdata->irq[26] = MPC85xx_IRQ_EXT7;
++	mdata->irq[31] = -1;
++	mdata->paddr += binfo->bi_immr_base;
++
+ 	/* setup the board related information for the enet controllers */
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT6;
+-		pdata->phyid = 25;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_25;
+ 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+ 	}
+ 
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
+ 	if (pdata) {
+ 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT7;
+-		pdata->phyid = 26;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_26;
+ 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+ 	}
+ 
+diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
+--- a/arch/ppc/platforms/85xx/stx_gp3.c
++++ b/arch/ppc/platforms/85xx/stx_gp3.c
+@@ -91,6 +91,9 @@ static u8 gp3_openpic_initsenses[] __ini
+ 	0x0,				/* External 11: */
+ };
+ 
++static const char *GFAR_PHY_2 = "phy0:2";
++static const char *GFAR_PHY_4 = "phy0:4";
++
+ /*
+  * Setup the architecture
+  */
+@@ -100,6 +103,7 @@ gp3_setup_arch(void)
+ 	bd_t *binfo = (bd_t *) __res;
+ 	unsigned int freq;
+ 	struct gianfar_platform_data *pdata;
++	struct gianfar_mdio_data *mdata;
+ 
+ 	cpm2_reset();
+ 
+@@ -118,23 +122,26 @@ gp3_setup_arch(void)
+ 	mpc85xx_setup_hose();
+ #endif
+ 
++	/* setup the board related info for the MDIO bus */
++	mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
++
++	mdata->irq[2] = MPC85xx_IRQ_EXT5;
++	mdata->irq[4] = MPC85xx_IRQ_EXT5;
++	mdata->irq[31] = -1;
++	mdata->paddr += binfo->bi_immr_base;
++
+ 	/* setup the board related information for the enet controllers */
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
+ 	if (pdata) {
+ 	/*	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 2;
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_2;
+ 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+ 	}
+ 
+ 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
+ 	if (pdata) {
+ 	/*	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
+-		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+-		pdata->phyid = 4;
+-		/* fixup phy address */
+-		pdata->phy_reg_addr += binfo->bi_immr_base;
++		pdata->bus_id = GFAR_PHY_4;
+ 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+ 	}
+ 
+diff --git a/arch/ppc/platforms/85xx/stx_gp3.h b/arch/ppc/platforms/85xx/stx_gp3.h
+--- a/arch/ppc/platforms/85xx/stx_gp3.h
++++ b/arch/ppc/platforms/85xx/stx_gp3.h
+@@ -21,7 +21,6 @@
+ 
+ #include <linux/config.h>
+ #include <linux/init.h>
+-#include <linux/seq_file.h>
+ #include <asm/ppcboot.h>
+ 
+ #define BOARD_CCSRBAR		((uint)0xe0000000)
+diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
+--- a/arch/ppc/platforms/Makefile
++++ b/arch/ppc/platforms/Makefile
+@@ -14,6 +14,9 @@ obj-$(CONFIG_PPC_PMAC)		+= pmac_pic.o pm
+ 					pmac_low_i2c.o pmac_cache.o
+ obj-$(CONFIG_PPC_CHRP)		+= chrp_setup.o chrp_time.o chrp_pci.o \
+ 					chrp_pegasos_eth.o
++ifeq ($(CONFIG_PPC_CHRP),y)
++obj-$(CONFIG_NVRAM)		+= chrp_nvram.o
++endif
+ obj-$(CONFIG_PPC_PREP)		+= prep_pci.o prep_setup.o
+ ifeq ($(CONFIG_PPC_PMAC),y)
+ obj-$(CONFIG_NVRAM)		+= pmac_nvram.o
+diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c
+--- a/arch/ppc/platforms/chestnut.c
++++ b/arch/ppc/platforms/chestnut.c
+@@ -541,7 +541,6 @@ platform_init(unsigned long r3, unsigned
+ 
+ 	ppc_md.setup_arch = chestnut_setup_arch;
+ 	ppc_md.show_cpuinfo = chestnut_show_cpuinfo;
+-	ppc_md.irq_canonicalize = NULL;
+ 	ppc_md.init_IRQ = mv64360_init_irq;
+ 	ppc_md.get_irq = mv64360_get_irq;
+ 	ppc_md.init = NULL;
+diff --git a/arch/ppc/platforms/chrp_nvram.c b/arch/ppc/platforms/chrp_nvram.c
+new file mode 100644
+--- /dev/null
++++ b/arch/ppc/platforms/chrp_nvram.c
+@@ -0,0 +1,83 @@
++/*
++ *  c 2001 PPC 64 Team, IBM Corp
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ *
++ * /dev/nvram driver for PPC
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <asm/uaccess.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++
++static unsigned int nvram_size;
++static unsigned char nvram_buf[4];
++static DEFINE_SPINLOCK(nvram_lock);
++
++static unsigned char chrp_nvram_read(int addr)
++{
++	unsigned long done, flags;
++	unsigned char ret;
++
++	if (addr >= nvram_size) {
++		printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n",
++		       current->comm, addr, nvram_size);
++		return 0xff;
++	}
++	spin_lock_irqsave(&nvram_lock, flags);
++	if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
++		ret = 0xff;
++	else
++		ret = nvram_buf[0];
++	spin_unlock_irqrestore(&nvram_lock, flags);
++
++	return ret;
++}
++
++static void chrp_nvram_write(int addr, unsigned char val)
++{
++	unsigned long done, flags;
++
++	if (addr >= nvram_size) {
++		printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n",
++		       current->comm, addr, nvram_size);
++		return;
++	}
++	spin_lock_irqsave(&nvram_lock, flags);
++	nvram_buf[0] = val;
++	if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
++		printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr);
++	spin_unlock_irqrestore(&nvram_lock, flags);
++}
++
++void __init chrp_nvram_init(void)
++{
++	struct device_node *nvram;
++	unsigned int *nbytes_p, proplen;
++
++	nvram = of_find_node_by_type(NULL, "nvram");
++	if (nvram == NULL)
++		return;
++
++	nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
++	if (nbytes_p == NULL || proplen != sizeof(unsigned int))
++		return;
++
++	nvram_size = *nbytes_p;
++
++	printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
++	of_node_put(nvram);
++
++	ppc_md.nvram_read_val = chrp_nvram_read;
++	ppc_md.nvram_write_val = chrp_nvram_write;
++
++	return;
++}
+diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
+--- a/arch/ppc/platforms/chrp_pci.c
++++ b/arch/ppc/platforms/chrp_pci.c
+@@ -29,7 +29,7 @@ void __iomem *gg2_pci_config_base;
+  * limit the bus number to 3 bits
+  */
+ 
+-int __chrp gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
++int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
+ 			   int len, u32 *val)
+ {
+ 	volatile void __iomem *cfg_data;
+@@ -56,7 +56,7 @@ int __chrp gg2_read_config(struct pci_bu
+ 	return PCIBIOS_SUCCESSFUL;
+ }
+ 
+-int __chrp gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
++int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
+ 			    int len, u32 val)
+ {
+ 	volatile void __iomem *cfg_data;
+@@ -92,7 +92,7 @@ static struct pci_ops gg2_pci_ops =
+ /*
+  * Access functions for PCI config space using RTAS calls.
+  */
+-int __chrp
++int
+ rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		 int len, u32 *val)
+ {
+@@ -108,7 +108,7 @@ rtas_read_config(struct pci_bus *bus, un
+ 	return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
+ }
+ 
+-int __chrp
++int
+ rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		  int len, u32 val)
+ {
+@@ -203,7 +203,7 @@ static void __init setup_peg2(struct pci
+ 		printk ("RTAS supporting Pegasos OF not found, please upgrade"
+ 			" your firmware\n");
+ 	}
+-	pci_assign_all_busses = 1;
++	pci_assign_all_buses = 1;
+ }
+ 
+ void __init
+diff --git a/arch/ppc/platforms/chrp_pegasos_eth.c b/arch/ppc/platforms/chrp_pegasos_eth.c
+--- a/arch/ppc/platforms/chrp_pegasos_eth.c
++++ b/arch/ppc/platforms/chrp_pegasos_eth.c
+@@ -13,11 +13,24 @@
+ #include <linux/types.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/mv643xx.h>
+ #include <linux/pci.h>
+ 
+-/* Pegasos 2 specific Marvell MV 64361 gigabit ethernet port setup */
++#define PEGASOS2_MARVELL_REGBASE 		(0xf1000000)
++#define PEGASOS2_MARVELL_REGSIZE 		(0x00004000)
++#define PEGASOS2_SRAM_BASE 			(0xf2000000)
++#define PEGASOS2_SRAM_SIZE			(256*1024)
++
++#define PEGASOS2_SRAM_BASE_ETH0			(PEGASOS2_SRAM_BASE)
++#define PEGASOS2_SRAM_BASE_ETH1			(PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) )
++
++
++#define PEGASOS2_SRAM_RXRING_SIZE		(PEGASOS2_SRAM_SIZE/4)
++#define PEGASOS2_SRAM_TXRING_SIZE		(PEGASOS2_SRAM_SIZE/4)
++
++#undef BE_VERBOSE
++
+ static struct resource mv643xx_eth_shared_resources[] = {
+ 	[0] = {
+ 		.name	= "ethernet shared base",
+@@ -44,7 +57,16 @@ static struct resource mv643xx_eth0_reso
+ 	},
+ };
+ 
+-static struct mv643xx_eth_platform_data eth0_pd;
++
++static struct mv643xx_eth_platform_data eth0_pd = {
++	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
++	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
++	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
++
++	.rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE,
++	.rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
++	.rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
++};
+ 
+ static struct platform_device eth0_device = {
+ 	.name		= MV643XX_ETH_NAME,
+@@ -65,7 +87,15 @@ static struct resource mv643xx_eth1_reso
+ 	},
+ };
+ 
+-static struct mv643xx_eth_platform_data eth1_pd;
++static struct mv643xx_eth_platform_data eth1_pd = {
++	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
++	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
++	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
++
++	.rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE,
++	.rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
++	.rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
++};
+ 
+ static struct platform_device eth1_device = {
+ 	.name		= MV643XX_ETH_NAME,
+@@ -83,9 +113,62 @@ static struct platform_device *mv643xx_e
+ 	&eth1_device,
+ };
+ 
++/***********/
++/***********/
++#define MV_READ(offset,val) 	{ val = readl(mv643xx_reg_base + offset); }
++#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset)
++
++static void __iomem *mv643xx_reg_base;
++
++static int Enable_SRAM(void)
++{
++	u32 ALong;
++
++	if (mv643xx_reg_base == NULL)
++		mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE,
++					PEGASOS2_MARVELL_REGSIZE);
++
++	if (mv643xx_reg_base == NULL)
++		return -ENOMEM;
++
++#ifdef BE_VERBOSE
++	printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n",
++		(void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base);
++#endif
++
++	MV_WRITE(MV64340_SRAM_CONFIG, 0);
+ 
+-int
+-mv643xx_eth_add_pds(void)
++	MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16);
++
++	MV_READ(MV64340_BASE_ADDR_ENABLE, ALong);
++	ALong &= ~(1 << 19);
++	MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong);
++
++	ALong = 0x02;
++	ALong |= PEGASOS2_SRAM_BASE & 0xffff0000;
++	MV_WRITE(MV643XX_ETH_BAR_4, ALong);
++
++	MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000);
++
++	MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
++	ALong &= ~(1 << 4);
++	MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
++
++#ifdef BE_VERBOSE
++	printk("Pegasos II/Marvell MV64361: register unmapped\n");
++	printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE);
++#endif
++
++	iounmap(mv643xx_reg_base);
++	mv643xx_reg_base = NULL;
++
++	return 1;
++}
++
++
++/***********/
++/***********/
++int mv643xx_eth_add_pds(void)
+ {
+ 	int ret = 0;
+ 	static struct pci_device_id pci_marvell_mv64360[] = {
+@@ -93,9 +176,38 @@ mv643xx_eth_add_pds(void)
+ 		{ }
+ 	};
+ 
++#ifdef BE_VERBOSE
++	printk("Pegasos II/Marvell MV64361: init\n");
++#endif
++
+ 	if (pci_dev_present(pci_marvell_mv64360)) {
+-		ret = platform_add_devices(mv643xx_eth_pd_devs, ARRAY_SIZE(mv643xx_eth_pd_devs));
++		ret = platform_add_devices(mv643xx_eth_pd_devs,
++				ARRAY_SIZE(mv643xx_eth_pd_devs));
++
++		if ( Enable_SRAM() < 0)
++		{
++			eth0_pd.tx_sram_addr = 0;
++			eth0_pd.tx_sram_size = 0;
++			eth0_pd.rx_sram_addr = 0;
++			eth0_pd.rx_sram_size = 0;
++
++			eth1_pd.tx_sram_addr = 0;
++			eth1_pd.tx_sram_size = 0;
++			eth1_pd.rx_sram_addr = 0;
++			eth1_pd.rx_sram_size = 0;
++
++#ifdef BE_VERBOSE
++			printk("Pegasos II/Marvell MV64361: Can't enable the "
++				"SRAM\n");
++#endif
++		}
+ 	}
++
++#ifdef BE_VERBOSE
++	printk("Pegasos II/Marvell MV64361: init is over\n");
++#endif
++
+ 	return ret;
+ }
++
+ device_initcall(mv643xx_eth_add_pds);
+diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
+--- a/arch/ppc/platforms/chrp_setup.c
++++ b/arch/ppc/platforms/chrp_setup.c
+@@ -104,7 +104,7 @@ static const char *gg2_cachemodes[4] = {
+ 	"Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
+ };
+ 
+-int __chrp
++int
+ chrp_show_cpuinfo(struct seq_file *m)
+ {
+ 	int i, sdramen;
+@@ -302,7 +302,7 @@ void __init chrp_setup_arch(void)
+ 	pci_create_OF_bus_map();
+ }
+ 
+-void __chrp
++void
+ chrp_event_scan(void)
+ {
+ 	unsigned char log[1024];
+@@ -313,7 +313,7 @@ chrp_event_scan(void)
+ 	ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
+ }
+ 
+-void __chrp
++void
+ chrp_restart(char *cmd)
+ {
+ 	printk("RTAS system-reboot returned %d\n",
+@@ -321,7 +321,7 @@ chrp_restart(char *cmd)
+ 	for (;;);
+ }
+ 
+-void __chrp
++void
+ chrp_power_off(void)
+ {
+ 	/* allow power on only with power button press */
+@@ -330,20 +330,12 @@ chrp_power_off(void)
+ 	for (;;);
+ }
+ 
+-void __chrp
++void
+ chrp_halt(void)
+ {
+ 	chrp_power_off();
+ }
+ 
+-u_int __chrp
+-chrp_irq_canonicalize(u_int irq)
+-{
+-	if (irq == 2)
+-		return 9;
+-	return irq;
+-}
+-
+ /*
+  * Finds the open-pic node and sets OpenPIC_Addr based on its reg property.
+  * Then checks if it has an interrupt-ranges property.  If it does then
+@@ -444,9 +436,7 @@ void __init chrp_init_IRQ(void)
+ 				       i8259_irq);
+ 
+ 	}
+-	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
+-		irq_desc[i].handler = &i8259_pic;
+-	i8259_init(chrp_int_ack);
++	i8259_init(chrp_int_ack, 0);
+ 
+ #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
+ 	/* see if there is a keyboard in the device tree
+@@ -464,8 +454,7 @@ void __init
+ chrp_init2(void)
+ {
+ #ifdef CONFIG_NVRAM
+-// XX replace this in a more saner way
+-//	pmac_nvram_init();
++	chrp_nvram_init();
+ #endif
+ 
+ 	request_region(0x20,0x20,"pic1");
+@@ -499,6 +488,7 @@ chrp_init(unsigned long r3, unsigned lon
+ 	DMA_MODE_READ = 0x44;
+ 	DMA_MODE_WRITE = 0x48;
+ 	isa_io_base = CHRP_ISA_IO_BASE;		/* default value */
++	ppc_do_canonicalize_irqs = 1;
+ 
+ 	if (root)
+ 		machine = get_property(root, "model", NULL);
+@@ -517,7 +507,6 @@ chrp_init(unsigned long r3, unsigned lon
+ 	ppc_md.show_percpuinfo = of_show_percpuinfo;
+ 	ppc_md.show_cpuinfo   = chrp_show_cpuinfo;
+ 
+-	ppc_md.irq_canonicalize = chrp_irq_canonicalize;
+ 	ppc_md.init_IRQ       = chrp_init_IRQ;
+ 	if (_chrp_type == _CHRP_Pegasos)
+ 		ppc_md.get_irq        = i8259_irq;
+@@ -561,7 +550,7 @@ chrp_init(unsigned long r3, unsigned lon
+ #endif
+ 
+ #ifdef CONFIG_SMP
+-	ppc_md.smp_ops = &chrp_smp_ops;
++	smp_ops = &chrp_smp_ops;
+ #endif /* CONFIG_SMP */
+ 
+ 	/*
+@@ -571,7 +560,7 @@ chrp_init(unsigned long r3, unsigned lon
+ 	if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
+ }
+ 
+-void __chrp
++void
+ rtas_display_progress(char *s, unsigned short hex)
+ {
+ 	int width;
+@@ -598,7 +587,7 @@ rtas_display_progress(char *s, unsigned 
+ 	call_rtas( "display-character", 1, 1, NULL, ' ' );
+ }
+ 
+-void __chrp
++void
+ rtas_indicator_progress(char *s, unsigned short hex)
+ {
+ 	call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);
+diff --git a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c
+--- a/arch/ppc/platforms/chrp_smp.c
++++ b/arch/ppc/platforms/chrp_smp.c
+@@ -31,6 +31,7 @@
+ #include <asm/residual.h>
+ #include <asm/time.h>
+ #include <asm/open_pic.h>
++#include <asm/machdep.h>
+ 
+ extern unsigned long smp_chrp_cpu_nr;
+ 
+@@ -88,7 +89,7 @@ smp_chrp_take_timebase(void)
+ }
+ 
+ /* CHRP with openpic */
+-struct smp_ops_t chrp_smp_ops __chrpdata = {
++struct smp_ops_t chrp_smp_ops = {
+ 	.message_pass = smp_openpic_message_pass,
+ 	.probe = smp_chrp_probe,
+ 	.kick_cpu = smp_chrp_kick_cpu,
+diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
+--- a/arch/ppc/platforms/chrp_time.c
++++ b/arch/ppc/platforms/chrp_time.c
+@@ -52,7 +52,7 @@ long __init chrp_time_init(void)
+ 	return 0;
+ }
+ 
+-int __chrp chrp_cmos_clock_read(int addr)
++int chrp_cmos_clock_read(int addr)
+ {
+ 	if (nvram_as1 != 0)
+ 		outb(addr>>8, nvram_as1);
+@@ -60,7 +60,7 @@ int __chrp chrp_cmos_clock_read(int addr
+ 	return (inb(nvram_data));
+ }
+ 
+-void __chrp chrp_cmos_clock_write(unsigned long val, int addr)
++void chrp_cmos_clock_write(unsigned long val, int addr)
+ {
+ 	if (nvram_as1 != 0)
+ 		outb(addr>>8, nvram_as1);
+@@ -72,7 +72,7 @@ void __chrp chrp_cmos_clock_write(unsign
+ /*
+  * Set the hardware clock. -- Cort
+  */
+-int __chrp chrp_set_rtc_time(unsigned long nowtime)
++int chrp_set_rtc_time(unsigned long nowtime)
+ {
+ 	unsigned char save_control, save_freq_select;
+ 	struct rtc_time tm;
+@@ -118,7 +118,7 @@ int __chrp chrp_set_rtc_time(unsigned lo
+ 	return 0;
+ }
+ 
+-unsigned long __chrp chrp_get_rtc_time(void)
++unsigned long chrp_get_rtc_time(void)
+ {
+ 	unsigned int year, mon, day, hour, min, sec;
+ 	int uip, i;
+diff --git a/arch/ppc/platforms/cpci690.c b/arch/ppc/platforms/cpci690.c
+--- a/arch/ppc/platforms/cpci690.c
++++ b/arch/ppc/platforms/cpci690.c
+@@ -21,6 +21,7 @@
+ #include <linux/initrd.h>
+ #include <linux/root_dev.h>
+ #include <linux/mv643xx.h>
++#include <linux/platform_device.h>
+ #include <asm/bootinfo.h>
+ #include <asm/machdep.h>
+ #include <asm/todc.h>
+diff --git a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c
+--- a/arch/ppc/platforms/ev64260.c
++++ b/arch/ppc/platforms/ev64260.c
+@@ -33,6 +33,7 @@
+ #include <linux/console.h>
+ #include <linux/initrd.h>
+ #include <linux/root_dev.h>
++#include <linux/platform_device.h>
+ #if !defined(CONFIG_SERIAL_MPSC_CONSOLE)
+ #include <linux/serial.h>
+ #include <linux/tty.h>
+diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c
+--- a/arch/ppc/platforms/ev64360.c
++++ b/arch/ppc/platforms/ev64360.c
+@@ -25,6 +25,7 @@
+ #include <linux/bootmem.h>
+ #include <linux/mtd/physmap.h>
+ #include <linux/mv643xx.h>
++#include <linux/platform_device.h>
+ #ifdef CONFIG_BOOTIMG
+ #include <linux/bootimg.h>
+ #endif
+@@ -35,6 +36,7 @@
+ #include <asm/bootinfo.h>
+ #include <asm/ppcboot.h>
+ #include <asm/mv64x60.h>
++#include <asm/machdep.h>
+ #include <platforms/ev64360.h>
+ 
+ #define BOARD_VENDOR    "Marvell"
+diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h
+--- a/arch/ppc/platforms/fads.h
++++ b/arch/ppc/platforms/fads.h
+@@ -25,6 +25,8 @@
+ 
+ #if defined(CONFIG_MPC86XADS)
+ 
++#define BOARD_CHIP_NAME "MPC86X"
++
+ /* U-Boot maps BCSR to 0xff080000 */
+ #define BCSR_ADDR		((uint)0xff080000)
+ 
+diff --git a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c
+--- a/arch/ppc/platforms/gemini_setup.c
++++ b/arch/ppc/platforms/gemini_setup.c
+@@ -35,6 +35,7 @@
+ #include <asm/time.h>
+ #include <asm/open_pic.h>
+ #include <asm/bootinfo.h>
++#include <asm/machdep.h>
+ 
+ void gemini_find_bridges(void);
+ static int gemini_get_clock_speed(void);
+@@ -555,7 +556,6 @@ void __init platform_init(unsigned long 
+ 
+ 	ppc_md.setup_arch = gemini_setup_arch;
+ 	ppc_md.show_cpuinfo = gemini_show_cpuinfo;
+-	ppc_md.irq_canonicalize = NULL;
+ 	ppc_md.init_IRQ = gemini_init_IRQ;
+ 	ppc_md.get_irq = openpic_get_irq;
+ 	ppc_md.init = NULL;
+@@ -575,6 +575,6 @@ void __init platform_init(unsigned long 
+ 	ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup;
+ 
+ #ifdef CONFIG_SMP
+-	ppc_md.smp_ops = &gemini_smp_ops;
++	smp_ops = &gemini_smp_ops;
+ #endif /* CONFIG_SMP */
+ }
+diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
+--- a/arch/ppc/platforms/hdpu.c
++++ b/arch/ppc/platforms/hdpu.c
+@@ -22,6 +22,7 @@
+ #include <linux/irq.h>
+ #include <linux/ide.h>
+ #include <linux/seq_file.h>
++#include <linux/platform_device.h>
+ 
+ #include <linux/initrd.h>
+ #include <linux/root_dev.h>
+@@ -609,11 +610,6 @@ static void parse_bootinfo(unsigned long
+ }
+ 
+ #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+-static int hdpu_ide_check_region(ide_ioreg_t from, unsigned int extent)
+-{
+-	return check_region(from, extent);
+-}
+-
+ static void
+ hdpu_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
+ {
+@@ -753,7 +749,7 @@ static int smp_hdpu_probe(void)
+ }
+ 
+ static void
+-smp_hdpu_message_pass(int target, int msg, unsigned long data, int wait)
++smp_hdpu_message_pass(int target, int msg)
+ {
+ 	if (msg > 0x3) {
+ 		printk("SMP %d: smp_message_pass: unknown msg %d\n",
+@@ -949,7 +945,7 @@ platform_init(unsigned long r3, unsigned
+ #endif				/* CONFIG_SERIAL_TEXT_DEBUG */
+ 
+ #ifdef CONFIG_SMP
+-	ppc_md.smp_ops = &hdpu_smp_ops;
++	smp_ops = &hdpu_smp_ops;
+ #endif				/* CONFIG_SMP */
+ 
+ #if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH)
+diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
+--- a/arch/ppc/platforms/katana.c
++++ b/arch/ppc/platforms/katana.c
+@@ -29,6 +29,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/mtd/physmap.h>
+ #include <linux/mv643xx.h>
++#include <linux/platform_device.h>
+ #ifdef CONFIG_BOOTIMG
+ #include <linux/bootimg.h>
+ #endif
+@@ -42,6 +43,7 @@
+ #include <asm/ppcboot.h>
+ #include <asm/mv64x60.h>
+ #include <platforms/katana.h>
++#include <asm/machdep.h>
+ 
+ static struct mv64x60_handle	bh;
+ static katana_id_t		katana_id;
+@@ -520,7 +522,7 @@ katana_fixup_resources(struct pci_dev *d
+ {
+ 	u16	v16;
+ 
+-	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_LINE_SIZE>>2);
++	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES>>2);
+ 
+ 	pci_read_config_word(dev, PCI_COMMAND, &v16);
+ 	v16 |= PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK;
+diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
+--- a/arch/ppc/platforms/lite5200.c
++++ b/arch/ppc/platforms/lite5200.c
+@@ -35,6 +35,7 @@
+ #include <asm/io.h>
+ #include <asm/mpc52xx.h>
+ #include <asm/ppc_sys.h>
++#include <asm/machdep.h>
+ 
+ #include <syslib/mpc52xx_pci.h>
+ 
+diff --git a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c
+--- a/arch/ppc/platforms/lopec.c
++++ b/arch/ppc/platforms/lopec.c
+@@ -144,15 +144,6 @@ lopec_show_cpuinfo(struct seq_file *m)
+ 	return 0;
+ }
+ 
+-static u32
+-lopec_irq_canonicalize(u32 irq)
+-{
+-	if (irq == 2)
+-		return 9;
+-	else
+-		return irq;
+-}
+-
+ static void
+ lopec_restart(char *cmd)
+ {
+@@ -276,15 +267,11 @@ lopec_init_IRQ(void)
+ 	openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
+ 			&i8259_irq);
+ 
+-	/* Map i8259 interrupts */
+-	for(i = 0; i < NUM_8259_INTERRUPTS; i++)
+-		irq_desc[i].handler = &i8259_pic;
+-
+ 	/*
+ 	 * The EPIC allows for a read in the range of 0xFEF00000 ->
+ 	 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
+ 	 */
+-	i8259_init(0xfef00000);
++	i8259_init(0xfef00000, 0);
+ }
+ 
+ static int __init
+@@ -379,10 +366,10 @@ platform_init(unsigned long r3, unsigned
+ 	ISA_DMA_THRESHOLD = 0x00ffffff;
+ 	DMA_MODE_READ = 0x44;
+ 	DMA_MODE_WRITE = 0x48;
++	ppc_do_canonicalize_irqs = 1;
+ 
+ 	ppc_md.setup_arch = lopec_setup_arch;
+ 	ppc_md.show_cpuinfo = lopec_show_cpuinfo;
+-	ppc_md.irq_canonicalize = lopec_irq_canonicalize;
+ 	ppc_md.init_IRQ = lopec_init_IRQ;
+ 	ppc_md.get_irq = openpic_get_irq;
+ 
+diff --git a/arch/ppc/platforms/mpc885ads.h b/arch/ppc/platforms/mpc885ads.h
+--- a/arch/ppc/platforms/mpc885ads.h
++++ b/arch/ppc/platforms/mpc885ads.h
+@@ -88,5 +88,7 @@
+ #define SICR_ENET_MASK	((uint)0x00ff0000)
+ #define SICR_ENET_CLKRT	((uint)0x002c0000)
+ 
++#define BOARD_CHIP_NAME "MPC885"
++
+ #endif /* __ASM_MPC885ADS_H__ */
+ #endif /* __KERNEL__ */
+diff --git a/arch/ppc/platforms/mvme5100.c b/arch/ppc/platforms/mvme5100.c
+--- a/arch/ppc/platforms/mvme5100.c
++++ b/arch/ppc/platforms/mvme5100.c
+@@ -223,11 +223,7 @@ mvme5100_init_IRQ(void)
+ 	openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
+ 			&i8259_irq);
+ 
+-	/* Map i8259 interrupts. */
+-	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
+-		irq_desc[i].handler = &i8259_pic;
+-
+-	i8259_init(0);
++	i8259_init(0, 0);
+ #else
+ 	openpic_init(0);
+ #endif
+diff --git a/arch/ppc/platforms/pal4_setup.c b/arch/ppc/platforms/pal4_setup.c
+--- a/arch/ppc/platforms/pal4_setup.c
++++ b/arch/ppc/platforms/pal4_setup.c
+@@ -28,6 +28,7 @@
+ #include <asm/io.h>
+ #include <asm/todc.h>
+ #include <asm/bootinfo.h>
++#include <asm/machdep.h>
+ 
+ #include <syslib/cpc700.h>
+ 
+diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c
+--- a/arch/ppc/platforms/pmac_backlight.c
++++ b/arch/ppc/platforms/pmac_backlight.c
+@@ -37,7 +37,7 @@ static int backlight_req_enable = -1;
+ static void backlight_callback(void *);
+ static DECLARE_WORK(backlight_work, backlight_callback, NULL);
+ 
+-void __pmac register_backlight_controller(struct backlight_controller *ctrler,
++void register_backlight_controller(struct backlight_controller *ctrler,
+ 					  void *data, char *type)
+ {
+ 	struct device_node* bk_node;
+@@ -99,7 +99,7 @@ void __pmac register_backlight_controlle
+ }
+ EXPORT_SYMBOL(register_backlight_controller);
+ 
+-void __pmac unregister_backlight_controller(struct backlight_controller
++void unregister_backlight_controller(struct backlight_controller
+ 					    *ctrler, void *data)
+ {
+ 	/* We keep the current backlight level (for now) */
+@@ -108,7 +108,7 @@ void __pmac unregister_backlight_control
+ }
+ EXPORT_SYMBOL(unregister_backlight_controller);
+ 
+-static int __pmac __set_backlight_enable(int enable)
++static int __set_backlight_enable(int enable)
+ {
+ 	int rc;
+ 
+@@ -122,7 +122,7 @@ static int __pmac __set_backlight_enable
+ 	release_console_sem();
+ 	return rc;
+ }
+-int __pmac set_backlight_enable(int enable)
++int set_backlight_enable(int enable)
+ {
+ 	if (!backlighter)
+ 		return -ENODEV;
+@@ -133,7 +133,7 @@ int __pmac set_backlight_enable(int enab
+ 
+ EXPORT_SYMBOL(set_backlight_enable);
+ 
+-int __pmac get_backlight_enable(void)
++int get_backlight_enable(void)
+ {
+ 	if (!backlighter)
+ 		return -ENODEV;
+@@ -141,7 +141,7 @@ int __pmac get_backlight_enable(void)
+ }
+ EXPORT_SYMBOL(get_backlight_enable);
+ 
+-static int __pmac __set_backlight_level(int level)
++static int __set_backlight_level(int level)
+ {
+ 	int rc = 0;
+ 
+@@ -165,7 +165,7 @@ static int __pmac __set_backlight_level(
+ 	}
+ 	return rc;
+ }
+-int __pmac set_backlight_level(int level)
++int set_backlight_level(int level)
+ {
+ 	if (!backlighter)
+ 		return -ENODEV;
+@@ -176,7 +176,7 @@ int __pmac set_backlight_level(int level
+ 
+ EXPORT_SYMBOL(set_backlight_level);
+ 
+-int __pmac get_backlight_level(void)
++int get_backlight_level(void)
+ {
+ 	if (!backlighter)
+ 		return -ENODEV;
+diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
+--- a/arch/ppc/platforms/pmac_cpufreq.c
++++ b/arch/ppc/platforms/pmac_cpufreq.c
+@@ -136,7 +136,7 @@ static inline void debug_calc_bogomips(v
+ 
+ /* Switch CPU speed under 750FX CPU control
+  */
+-static int __pmac cpu_750fx_cpu_speed(int low_speed)
++static int cpu_750fx_cpu_speed(int low_speed)
+ {
+ 	u32 hid2;
+ 
+@@ -172,7 +172,7 @@ static int __pmac cpu_750fx_cpu_speed(in
+ 	return 0;
+ }
+ 
+-static unsigned int __pmac cpu_750fx_get_cpu_speed(void)
++static unsigned int cpu_750fx_get_cpu_speed(void)
+ {
+ 	if (mfspr(SPRN_HID1) & HID1_PS)
+ 		return low_freq;
+@@ -181,7 +181,7 @@ static unsigned int __pmac cpu_750fx_get
+ }
+ 
+ /* Switch CPU speed using DFS */
+-static int __pmac dfs_set_cpu_speed(int low_speed)
++static int dfs_set_cpu_speed(int low_speed)
+ {
+ 	if (low_speed == 0) {
+ 		/* ramping up, set voltage first */
+@@ -205,7 +205,7 @@ static int __pmac dfs_set_cpu_speed(int 
+ 	return 0;
+ }
+ 
+-static unsigned int __pmac dfs_get_cpu_speed(void)
++static unsigned int dfs_get_cpu_speed(void)
+ {
+ 	if (mfspr(SPRN_HID1) & HID1_DFS)
+ 		return low_freq;
+@@ -216,7 +216,7 @@ static unsigned int __pmac dfs_get_cpu_s
+ 
+ /* Switch CPU speed using slewing GPIOs
+  */
+-static int __pmac gpios_set_cpu_speed(int low_speed)
++static int gpios_set_cpu_speed(int low_speed)
+ {
+ 	int gpio, timeout = 0;
+ 
+@@ -258,7 +258,7 @@ static int __pmac gpios_set_cpu_speed(in
+ 
+ /* Switch CPU speed under PMU control
+  */
+-static int __pmac pmu_set_cpu_speed(int low_speed)
++static int pmu_set_cpu_speed(int low_speed)
+ {
+ 	struct adb_request req;
+ 	unsigned long save_l2cr;
+@@ -354,7 +354,7 @@ static int __pmac pmu_set_cpu_speed(int 
+ 	return 0;
+ }
+ 
+-static int __pmac do_set_cpu_speed(int speed_mode, int notify)
++static int do_set_cpu_speed(int speed_mode, int notify)
+ {
+ 	struct cpufreq_freqs freqs;
+ 	unsigned long l3cr;
+@@ -391,17 +391,17 @@ static int __pmac do_set_cpu_speed(int s
+ 	return 0;
+ }
+ 
+-static unsigned int __pmac pmac_cpufreq_get_speed(unsigned int cpu)
++static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
+ {
+ 	return cur_freq;
+ }
+ 
+-static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy)
++static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
+ {
+ 	return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
+ }
+ 
+-static int __pmac pmac_cpufreq_target(	struct cpufreq_policy *policy,
++static int pmac_cpufreq_target(	struct cpufreq_policy *policy,
+ 					unsigned int target_freq,
+ 					unsigned int relation)
+ {
+@@ -414,13 +414,13 @@ static int __pmac pmac_cpufreq_target(	s
+ 	return do_set_cpu_speed(newstate, 1);
+ }
+ 
+-unsigned int __pmac pmac_get_one_cpufreq(int i)
++unsigned int pmac_get_one_cpufreq(int i)
+ {
+ 	/* Supports only one CPU for now */
+ 	return (i == 0) ? cur_freq : 0;
+ }
+ 
+-static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
++static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
+ {
+ 	if (policy->cpu != 0)
+ 		return -ENODEV;
+@@ -433,7 +433,7 @@ static int __pmac pmac_cpufreq_cpu_init(
+ 	return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
+ }
+ 
+-static u32 __pmac read_gpio(struct device_node *np)
++static u32 read_gpio(struct device_node *np)
+ {
+ 	u32 *reg = (u32 *)get_property(np, "reg", NULL);
+ 	u32 offset;
+@@ -452,7 +452,7 @@ static u32 __pmac read_gpio(struct devic
+ 	return offset;
+ }
+ 
+-static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
++static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
+ {
+ 	/* Ok, this could be made a bit smarter, but let's be robust for now. We
+ 	 * always force a speed change to high speed before sleep, to make sure
+@@ -468,7 +468,7 @@ static int __pmac pmac_cpufreq_suspend(s
+ 	return 0;
+ }
+ 
+-static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy)
++static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
+ {
+ 	/* If we resume, first check if we have a get() function */
+ 	if (get_speed_proc)
+@@ -501,7 +501,7 @@ static struct cpufreq_driver pmac_cpufre
+ };
+ 
+ 
+-static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
++static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
+ {
+ 	struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
+ 								"voltage-gpio");
+@@ -593,7 +593,7 @@ static int __pmac pmac_cpufreq_init_MacR
+ 	return 0;
+ }
+ 
+-static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode)
++static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
+ {
+ 	struct device_node *volt_gpio_np;
+ 
+@@ -620,7 +620,7 @@ static int __pmac pmac_cpufreq_init_7447
+ 	return 0;
+ }
+ 
+-static int __pmac pmac_cpufreq_init_750FX(struct device_node *cpunode)
++static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
+ {
+ 	struct device_node *volt_gpio_np;
+ 	u32 pvr, *value;
+diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
+--- a/arch/ppc/platforms/pmac_feature.c
++++ b/arch/ppc/platforms/pmac_feature.c
+@@ -63,7 +63,7 @@ extern struct device_node *k2_skiplist[2
+  * We use a single global lock to protect accesses. Each driver has
+  * to take care of its own locking
+  */
+-static DEFINE_SPINLOCK(feature_lock  __pmacdata);
++static DEFINE_SPINLOCK(feature_lock);
+ 
+ #define LOCK(flags)	spin_lock_irqsave(&feature_lock, flags);
+ #define UNLOCK(flags)	spin_unlock_irqrestore(&feature_lock, flags);
+@@ -72,9 +72,9 @@ static DEFINE_SPINLOCK(feature_lock  __p
+ /*
+  * Instance of some macio stuffs
+  */
+-struct macio_chip macio_chips[MAX_MACIO_CHIPS]  __pmacdata;
++struct macio_chip macio_chips[MAX_MACIO_CHIPS];
+ 
+-struct macio_chip* __pmac macio_find(struct device_node* child, int type)
++struct macio_chip* macio_find(struct device_node* child, int type)
+ {
+ 	while(child) {
+ 		int	i;
+@@ -89,7 +89,7 @@ struct macio_chip* __pmac macio_find(str
+ }
+ EXPORT_SYMBOL_GPL(macio_find);
+ 
+-static const char* macio_names[] __pmacdata =
++static const char* macio_names[] =
+ {
+ 	"Unknown",
+ 	"Grand Central",
+@@ -116,10 +116,10 @@ static const char* macio_names[] __pmacd
+ #define UN_BIS(r,v)	(UN_OUT((r), UN_IN(r) | (v)))
+ #define UN_BIC(r,v)	(UN_OUT((r), UN_IN(r) & ~(v)))
+ 
+-static struct device_node* uninorth_node __pmacdata;
+-static u32 __iomem * uninorth_base __pmacdata;
+-static u32 uninorth_rev __pmacdata;
+-static int uninorth_u3 __pmacdata;
++static struct device_node* uninorth_node;
++static u32 __iomem * uninorth_base;
++static u32 uninorth_rev;
++static int uninorth_u3;
+ static void __iomem *u3_ht;
+ 
+ /*
+@@ -142,13 +142,13 @@ struct pmac_mb_def
+ 	struct feature_table_entry* 	features;
+ 	unsigned long			board_flags;
+ };
+-static struct pmac_mb_def pmac_mb __pmacdata;
++static struct pmac_mb_def pmac_mb;
+ 
+ /*
+  * Here are the chip specific feature functions
+  */
+ 
+-static inline int __pmac
++static inline int
+ simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value)
+ {
+ 	struct macio_chip*	macio;
+@@ -170,7 +170,7 @@ simple_feature_tweak(struct device_node*
+ 
+ #ifndef CONFIG_POWER4
+ 
+-static long __pmac
++static long
+ ohare_htw_scc_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -263,21 +263,21 @@ ohare_htw_scc_enable(struct device_node*
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ ohare_floppy_enable(struct device_node* node, long param, long value)
+ {
+ 	return simple_feature_tweak(node, macio_ohare,
+ 		OHARE_FCR, OH_FLOPPY_ENABLE, value);
+ }
+ 
+-static long __pmac
++static long
+ ohare_mesh_enable(struct device_node* node, long param, long value)
+ {
+ 	return simple_feature_tweak(node, macio_ohare,
+ 		OHARE_FCR, OH_MESH_ENABLE, value);
+ }
+ 
+-static long __pmac
++static long
+ ohare_ide_enable(struct device_node* node, long param, long value)
+ {
+ 	switch(param) {
+@@ -298,7 +298,7 @@ ohare_ide_enable(struct device_node* nod
+ 	}
+ }
+ 
+-static long __pmac
++static long
+ ohare_ide_reset(struct device_node* node, long param, long value)
+ {
+ 	switch(param) {
+@@ -313,7 +313,7 @@ ohare_ide_reset(struct device_node* node
+ 	}
+ }
+ 
+-static long __pmac
++static long
+ ohare_sleep_state(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio = &macio_chips[0];
+@@ -329,7 +329,7 @@ ohare_sleep_state(struct device_node* no
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ heathrow_modem_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -373,7 +373,7 @@ heathrow_modem_enable(struct device_node
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ heathrow_floppy_enable(struct device_node* node, long param, long value)
+ {
+ 	return simple_feature_tweak(node, macio_unknown,
+@@ -382,7 +382,7 @@ heathrow_floppy_enable(struct device_nod
+ 		value);
+ }
+ 
+-static long __pmac
++static long
+ heathrow_mesh_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -411,7 +411,7 @@ heathrow_mesh_enable(struct device_node*
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ heathrow_ide_enable(struct device_node* node, long param, long value)
+ {
+ 	switch(param) {
+@@ -426,7 +426,7 @@ heathrow_ide_enable(struct device_node* 
+ 	}
+ }
+ 
+-static long __pmac
++static long
+ heathrow_ide_reset(struct device_node* node, long param, long value)
+ {
+ 	switch(param) {
+@@ -441,7 +441,7 @@ heathrow_ide_reset(struct device_node* n
+ 	}
+ }
+ 
+-static long __pmac
++static long
+ heathrow_bmac_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -470,7 +470,7 @@ heathrow_bmac_enable(struct device_node*
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ heathrow_sound_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -501,16 +501,16 @@ heathrow_sound_enable(struct device_node
+ 	return 0;
+ }
+ 
+-static u32 save_fcr[6] __pmacdata;
+-static u32 save_mbcr __pmacdata;
+-static u32 save_gpio_levels[2] __pmacdata;
+-static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata;
+-static u8 save_gpio_normal[KEYLARGO_GPIO_CNT] __pmacdata;
+-static u32 save_unin_clock_ctl __pmacdata;
+-static struct dbdma_regs save_dbdma[13] __pmacdata;
+-static struct dbdma_regs save_alt_dbdma[13] __pmacdata;
++static u32 save_fcr[6];
++static u32 save_mbcr;
++static u32 save_gpio_levels[2];
++static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
++static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
++static u32 save_unin_clock_ctl;
++static struct dbdma_regs save_dbdma[13];
++static struct dbdma_regs save_alt_dbdma[13];
+ 
+-static void __pmac
++static void
+ dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
+ {
+ 	int i;
+@@ -527,7 +527,7 @@ dbdma_save(struct macio_chip* macio, str
+ 	}
+ }
+ 
+-static void __pmac
++static void
+ dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
+ {
+ 	int i;
+@@ -547,7 +547,7 @@ dbdma_restore(struct macio_chip* macio, 
+ 	}
+ }
+ 
+-static void __pmac
++static void
+ heathrow_sleep(struct macio_chip* macio, int secondary)
+ {
+ 	if (secondary) {
+@@ -580,7 +580,7 @@ heathrow_sleep(struct macio_chip* macio,
+ 	(void)MACIO_IN32(HEATHROW_FCR);
+ }
+ 
+-static void __pmac
++static void
+ heathrow_wakeup(struct macio_chip* macio, int secondary)
+ {
+ 	if (secondary) {
+@@ -605,7 +605,7 @@ heathrow_wakeup(struct macio_chip* macio
+ 	}
+ }
+ 
+-static long __pmac
++static long
+ heathrow_sleep_state(struct device_node* node, long param, long value)
+ {
+ 	if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
+@@ -622,7 +622,7 @@ heathrow_sleep_state(struct device_node*
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_scc_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -723,7 +723,7 @@ core99_scc_enable(struct device_node* no
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_modem_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -775,7 +775,7 @@ core99_modem_enable(struct device_node* 
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ pangea_modem_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -830,7 +830,7 @@ pangea_modem_enable(struct device_node* 
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_ata100_enable(struct device_node* node, long value)
+ {
+ 	unsigned long flags;
+@@ -860,7 +860,7 @@ core99_ata100_enable(struct device_node*
+     	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_ide_enable(struct device_node* node, long param, long value)
+ {
+ 	/* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
+@@ -883,7 +883,7 @@ core99_ide_enable(struct device_node* no
+ 	}
+ }
+ 
+-static long __pmac
++static long
+ core99_ide_reset(struct device_node* node, long param, long value)
+ {
+ 	switch(param) {
+@@ -901,7 +901,7 @@ core99_ide_reset(struct device_node* nod
+ 	}
+ }
+ 
+-static long __pmac
++static long
+ core99_gmac_enable(struct device_node* node, long param, long value)
+ {
+ 	unsigned long flags;
+@@ -918,7 +918,7 @@ core99_gmac_enable(struct device_node* n
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_gmac_phy_reset(struct device_node* node, long param, long value)
+ {
+ 	unsigned long flags;
+@@ -943,7 +943,7 @@ core99_gmac_phy_reset(struct device_node
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_sound_chip_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -973,7 +973,7 @@ core99_sound_chip_enable(struct device_n
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_airport_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip*	macio;
+@@ -1060,7 +1060,7 @@ core99_airport_enable(struct device_node
+ }
+ 
+ #ifdef CONFIG_SMP
+-static long __pmac
++static long
+ core99_reset_cpu(struct device_node* node, long param, long value)
+ {
+ 	unsigned int reset_io = 0;
+@@ -1104,7 +1104,7 @@ core99_reset_cpu(struct device_node* nod
+ }
+ #endif /* CONFIG_SMP */
+ 
+-static long __pmac
++static long
+ core99_usb_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip* macio;
+@@ -1257,7 +1257,7 @@ core99_usb_enable(struct device_node* no
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_firewire_enable(struct device_node* node, long param, long value)
+ {
+ 	unsigned long flags;
+@@ -1284,7 +1284,7 @@ core99_firewire_enable(struct device_nod
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_firewire_cable_power(struct device_node* node, long param, long value)
+ {
+ 	unsigned long flags;
+@@ -1315,7 +1315,7 @@ core99_firewire_cable_power(struct devic
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ intrepid_aack_delay_enable(struct device_node* node, long param, long value)
+ {
+ 	unsigned long flags;
+@@ -1336,7 +1336,7 @@ intrepid_aack_delay_enable(struct device
+ 
+ #endif /* CONFIG_POWER4 */
+ 
+-static long __pmac
++static long
+ core99_read_gpio(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip* macio = &macio_chips[0];
+@@ -1345,7 +1345,7 @@ core99_read_gpio(struct device_node* nod
+ }
+ 
+ 
+-static long __pmac
++static long
+ core99_write_gpio(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip* macio = &macio_chips[0];
+@@ -1356,7 +1356,7 @@ core99_write_gpio(struct device_node* no
+ 
+ #ifdef CONFIG_POWER4
+ 
+-static long __pmac
++static long
+ g5_gmac_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip* macio = &macio_chips[0];
+@@ -1380,7 +1380,7 @@ g5_gmac_enable(struct device_node* node,
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ g5_fw_enable(struct device_node* node, long param, long value)
+ {
+ 	struct macio_chip* macio = &macio_chips[0];
+@@ -1403,7 +1403,7 @@ g5_fw_enable(struct device_node* node, l
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ g5_mpic_enable(struct device_node* node, long param, long value)
+ {
+ 	unsigned long flags;
+@@ -1419,7 +1419,7 @@ g5_mpic_enable(struct device_node* node,
+ }
+ 
+ #ifdef CONFIG_SMP
+-static long __pmac
++static long
+ g5_reset_cpu(struct device_node* node, long param, long value)
+ {
+ 	unsigned int reset_io = 0;
+@@ -1465,7 +1465,7 @@ g5_reset_cpu(struct device_node* node, l
+  * This takes the second CPU off the bus on dual CPU machines
+  * running UP
+  */
+-void __pmac g5_phy_disable_cpu1(void)
++void g5_phy_disable_cpu1(void)
+ {
+ 	UN_OUT(U3_API_PHY_CONFIG_1, 0);
+ }
+@@ -1474,7 +1474,7 @@ void __pmac g5_phy_disable_cpu1(void)
+ 
+ #ifndef CONFIG_POWER4
+ 
+-static void __pmac
++static void
+ keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
+ {
+ 	u32 temp;
+@@ -1528,7 +1528,7 @@ keylargo_shutdown(struct macio_chip* mac
+ 	(void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
+ }
+ 
+-static void __pmac
++static void
+ pangea_shutdown(struct macio_chip* macio, int sleep_mode)
+ {
+ 	u32 temp;
+@@ -1562,7 +1562,7 @@ pangea_shutdown(struct macio_chip* macio
+ 	(void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
+ }
+ 
+-static void __pmac
++static void
+ intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
+ {
+ 	u32 temp;
+@@ -1591,7 +1591,7 @@ intrepid_shutdown(struct macio_chip* mac
+ }
+ 
+ 
+-void __pmac pmac_tweak_clock_spreading(int enable)
++void pmac_tweak_clock_spreading(int enable)
+ {
+ 	struct macio_chip* macio = &macio_chips[0];
+ 
+@@ -1698,7 +1698,7 @@ void __pmac pmac_tweak_clock_spreading(i
+ }
+ 
+ 
+-static int __pmac
++static int
+ core99_sleep(void)
+ {
+ 	struct macio_chip* macio;
+@@ -1791,7 +1791,7 @@ core99_sleep(void)
+ 	return 0;
+ }
+ 
+-static int __pmac
++static int
+ core99_wake_up(void)
+ {
+ 	struct macio_chip* macio;
+@@ -1854,7 +1854,7 @@ core99_wake_up(void)
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ core99_sleep_state(struct device_node* node, long param, long value)
+ {
+ 	/* Param == 1 means to enter the "fake sleep" mode that is
+@@ -1884,7 +1884,7 @@ core99_sleep_state(struct device_node* n
+ 
+ #endif /* CONFIG_POWER4 */
+ 
+-static long __pmac
++static long
+ generic_dev_can_wake(struct device_node* node, long param, long value)
+ {
+ 	/* Todo: eventually check we are really dealing with on-board
+@@ -1896,7 +1896,7 @@ generic_dev_can_wake(struct device_node*
+ 	return 0;
+ }
+ 
+-static long __pmac
++static long
+ generic_get_mb_info(struct device_node* node, long param, long value)
+ {
+ 	switch(param) {
+@@ -1919,7 +1919,7 @@ generic_get_mb_info(struct device_node* 
+ 
+ /* Used on any machine
+  */
+-static struct feature_table_entry any_features[]  __pmacdata = {
++static struct feature_table_entry any_features[] = {
+ 	{ PMAC_FTR_GET_MB_INFO,		generic_get_mb_info },
+ 	{ PMAC_FTR_DEVICE_CAN_WAKE,	generic_dev_can_wake },
+ 	{ 0, NULL }
+@@ -1931,7 +1931,7 @@ static struct feature_table_entry any_fe
+  * 2400,3400 and 3500 series powerbooks. Some older desktops seem
+  * to have issues with turning on/off those asic cells
+  */
+-static struct feature_table_entry ohare_features[]  __pmacdata = {
++static struct feature_table_entry ohare_features[] = {
+ 	{ PMAC_FTR_SCC_ENABLE,		ohare_htw_scc_enable },
+ 	{ PMAC_FTR_SWIM3_ENABLE,	ohare_floppy_enable },
+ 	{ PMAC_FTR_MESH_ENABLE,		ohare_mesh_enable },
+@@ -1945,7 +1945,7 @@ static struct feature_table_entry ohare_
+  * Separated as some features couldn't be properly tested
+  * and the serial port control bits appear to confuse it.
+  */
+-static struct feature_table_entry heathrow_desktop_features[]  __pmacdata = {
++static struct feature_table_entry heathrow_desktop_features[] = {
+ 	{ PMAC_FTR_SWIM3_ENABLE,	heathrow_floppy_enable },
+ 	{ PMAC_FTR_MESH_ENABLE,		heathrow_mesh_enable },
+ 	{ PMAC_FTR_IDE_ENABLE,		heathrow_ide_enable },
+@@ -1957,7 +1957,7 @@ static struct feature_table_entry heathr
+ /* Heathrow based laptop, that is the Wallstreet and mainstreet
+  * powerbooks.
+  */
+-static struct feature_table_entry heathrow_laptop_features[]  __pmacdata = {
++static struct feature_table_entry heathrow_laptop_features[] = {
+ 	{ PMAC_FTR_SCC_ENABLE,		ohare_htw_scc_enable },
+ 	{ PMAC_FTR_MODEM_ENABLE,	heathrow_modem_enable },
+ 	{ PMAC_FTR_SWIM3_ENABLE,	heathrow_floppy_enable },
+@@ -1973,7 +1973,7 @@ static struct feature_table_entry heathr
+ /* Paddington based machines
+  * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
+  */
+-static struct feature_table_entry paddington_features[]  __pmacdata = {
++static struct feature_table_entry paddington_features[] = {
+ 	{ PMAC_FTR_SCC_ENABLE,		ohare_htw_scc_enable },
+ 	{ PMAC_FTR_MODEM_ENABLE,	heathrow_modem_enable },
+ 	{ PMAC_FTR_SWIM3_ENABLE,	heathrow_floppy_enable },
+@@ -1991,7 +1991,7 @@ static struct feature_table_entry paddin
+  * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
+  * used on iBook2 & iMac "flow power".
+  */
+-static struct feature_table_entry core99_features[]  __pmacdata = {
++static struct feature_table_entry core99_features[] = {
+ 	{ PMAC_FTR_SCC_ENABLE,		core99_scc_enable },
+ 	{ PMAC_FTR_MODEM_ENABLE,	core99_modem_enable },
+ 	{ PMAC_FTR_IDE_ENABLE,		core99_ide_enable },
+@@ -2014,7 +2014,7 @@ static struct feature_table_entry core99
+ 
+ /* RackMac
+  */
+-static struct feature_table_entry rackmac_features[]  __pmacdata = {
++static struct feature_table_entry rackmac_features[] = {
+ 	{ PMAC_FTR_SCC_ENABLE,		core99_scc_enable },
+ 	{ PMAC_FTR_IDE_ENABLE,		core99_ide_enable },
+ 	{ PMAC_FTR_IDE_RESET,		core99_ide_reset },
+@@ -2034,7 +2034,7 @@ static struct feature_table_entry rackma
+ 
+ /* Pangea features
+  */
+-static struct feature_table_entry pangea_features[]  __pmacdata = {
++static struct feature_table_entry pangea_features[] = {
+ 	{ PMAC_FTR_SCC_ENABLE,		core99_scc_enable },
+ 	{ PMAC_FTR_MODEM_ENABLE,	pangea_modem_enable },
+ 	{ PMAC_FTR_IDE_ENABLE,		core99_ide_enable },
+@@ -2054,7 +2054,7 @@ static struct feature_table_entry pangea
+ 
+ /* Intrepid features
+  */
+-static struct feature_table_entry intrepid_features[]  __pmacdata = {
++static struct feature_table_entry intrepid_features[] = {
+ 	{ PMAC_FTR_SCC_ENABLE,		core99_scc_enable },
+ 	{ PMAC_FTR_MODEM_ENABLE,	pangea_modem_enable },
+ 	{ PMAC_FTR_IDE_ENABLE,		core99_ide_enable },
+@@ -2077,7 +2077,7 @@ static struct feature_table_entry intrep
+ 
+ /* G5 features
+  */
+-static struct feature_table_entry g5_features[]  __pmacdata = {
++static struct feature_table_entry g5_features[] = {
+ 	{ PMAC_FTR_GMAC_ENABLE,		g5_gmac_enable },
+ 	{ PMAC_FTR_1394_ENABLE,		g5_fw_enable },
+ 	{ PMAC_FTR_ENABLE_MPIC,		g5_mpic_enable },
+@@ -2091,7 +2091,7 @@ static struct feature_table_entry g5_fea
+ 
+ #endif /* CONFIG_POWER4 */
+ 
+-static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
++static struct pmac_mb_def pmac_mb_defs[] = {
+ #ifndef CONFIG_POWER4
+ 	/*
+ 	 * Desktops
+@@ -2356,7 +2356,7 @@ static struct pmac_mb_def pmac_mb_defs[]
+ /*
+  * The toplevel feature_call callback
+  */
+-long __pmac
++long
+ pmac_do_feature_call(unsigned int selector, ...)
+ {
+ 	struct device_node* node;
+@@ -2939,8 +2939,8 @@ void __init pmac_check_ht_link(void)
+  * Early video resume hook
+  */
+ 
+-static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
+-static void *pmac_early_vresume_data __pmacdata;
++static void (*pmac_early_vresume_proc)(void *data);
++static void *pmac_early_vresume_data;
+ 
+ void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
+ {
+@@ -2953,7 +2953,7 @@ void pmac_set_early_video_resume(void (*
+ }
+ EXPORT_SYMBOL(pmac_set_early_video_resume);
+ 
+-void __pmac pmac_call_early_video_resume(void)
++void pmac_call_early_video_resume(void)
+ {
+ 	if (pmac_early_vresume_proc)
+ 		pmac_early_vresume_proc(pmac_early_vresume_data);
+@@ -2963,11 +2963,11 @@ void __pmac pmac_call_early_video_resume
+  * AGP related suspend/resume code
+  */
+ 
+-static struct pci_dev *pmac_agp_bridge __pmacdata;
+-static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
+-static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
++static struct pci_dev *pmac_agp_bridge;
++static int (*pmac_agp_suspend)(struct pci_dev *bridge);
++static int (*pmac_agp_resume)(struct pci_dev *bridge);
+ 
+-void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
++void pmac_register_agp_pm(struct pci_dev *bridge,
+ 				 int (*suspend)(struct pci_dev *bridge),
+ 				 int (*resume)(struct pci_dev *bridge))
+ {
+@@ -2984,7 +2984,7 @@ void __pmac pmac_register_agp_pm(struct 
+ }
+ EXPORT_SYMBOL(pmac_register_agp_pm);
+ 
+-void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
++void pmac_suspend_agp_for_card(struct pci_dev *dev)
+ {
+ 	if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
+ 		return;
+@@ -2994,7 +2994,7 @@ void __pmac pmac_suspend_agp_for_card(st
+ }
+ EXPORT_SYMBOL(pmac_suspend_agp_for_card);
+ 
+-void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
++void pmac_resume_agp_for_card(struct pci_dev *dev)
+ {
+ 	if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
+ 		return;
+diff --git a/arch/ppc/platforms/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c
+--- a/arch/ppc/platforms/pmac_nvram.c
++++ b/arch/ppc/platforms/pmac_nvram.c
+@@ -88,17 +88,17 @@ extern int system_running;
+ static int (*core99_write_bank)(int bank, u8* datas);
+ static int (*core99_erase_bank)(int bank);
+ 
+-static char *nvram_image __pmacdata;
++static char *nvram_image;
+ 
+ 
+-static unsigned char __pmac core99_nvram_read_byte(int addr)
++static unsigned char core99_nvram_read_byte(int addr)
+ {
+ 	if (nvram_image == NULL)
+ 		return 0xff;
+ 	return nvram_image[addr];
+ }
+ 
+-static void __pmac core99_nvram_write_byte(int addr, unsigned char val)
++static void core99_nvram_write_byte(int addr, unsigned char val)
+ {
+ 	if (nvram_image == NULL)
+ 		return;
+@@ -106,18 +106,18 @@ static void __pmac core99_nvram_write_by
+ }
+ 
+ 
+-static unsigned char __openfirmware direct_nvram_read_byte(int addr)
++static unsigned char direct_nvram_read_byte(int addr)
+ {
+ 	return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
+ }
+ 
+-static void __openfirmware direct_nvram_write_byte(int addr, unsigned char val)
++static void direct_nvram_write_byte(int addr, unsigned char val)
+ {
+ 	out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
+ }
+ 
+ 
+-static unsigned char __pmac indirect_nvram_read_byte(int addr)
++static unsigned char indirect_nvram_read_byte(int addr)
+ {
+ 	unsigned char val;
+ 	unsigned long flags;
+@@ -130,7 +130,7 @@ static unsigned char __pmac indirect_nvr
+ 	return val;
+ }
+ 
+-static void __pmac indirect_nvram_write_byte(int addr, unsigned char val)
++static void indirect_nvram_write_byte(int addr, unsigned char val)
+ {
+ 	unsigned long flags;
+ 
+@@ -143,13 +143,13 @@ static void __pmac indirect_nvram_write_
+ 
+ #ifdef CONFIG_ADB_PMU
+ 
+-static void __pmac pmu_nvram_complete(struct adb_request *req)
++static void pmu_nvram_complete(struct adb_request *req)
+ {
+ 	if (req->arg)
+ 		complete((struct completion *)req->arg);
+ }
+ 
+-static unsigned char __pmac pmu_nvram_read_byte(int addr)
++static unsigned char pmu_nvram_read_byte(int addr)
+ {
+ 	struct adb_request req;
+ 	DECLARE_COMPLETION(req_complete); 
+@@ -165,7 +165,7 @@ static unsigned char __pmac pmu_nvram_re
+ 	return req.reply[0];
+ }
+ 
+-static void __pmac pmu_nvram_write_byte(int addr, unsigned char val)
++static void pmu_nvram_write_byte(int addr, unsigned char val)
+ {
+ 	struct adb_request req;
+ 	DECLARE_COMPLETION(req_complete); 
+@@ -183,7 +183,7 @@ static void __pmac pmu_nvram_write_byte(
+ #endif /* CONFIG_ADB_PMU */
+ 
+ 
+-static u8 __pmac chrp_checksum(struct chrp_header* hdr)
++static u8 chrp_checksum(struct chrp_header* hdr)
+ {
+ 	u8 *ptr;
+ 	u16 sum = hdr->signature;
+@@ -194,7 +194,7 @@ static u8 __pmac chrp_checksum(struct ch
+ 	return sum;
+ }
+ 
+-static u32 __pmac core99_calc_adler(u8 *buffer)
++static u32 core99_calc_adler(u8 *buffer)
+ {
+ 	int cnt;
+ 	u32 low, high;
+@@ -216,7 +216,7 @@ static u32 __pmac core99_calc_adler(u8 *
+ 	return (high << 16) | low;
+ }
+ 
+-static u32 __pmac core99_check(u8* datas)
++static u32 core99_check(u8* datas)
+ {
+ 	struct core99_header* hdr99 = (struct core99_header*)datas;
+ 
+@@ -235,7 +235,7 @@ static u32 __pmac core99_check(u8* datas
+ 	return hdr99->generation;
+ }
+ 
+-static int __pmac sm_erase_bank(int bank)
++static int sm_erase_bank(int bank)
+ {
+ 	int stat, i;
+ 	unsigned long timeout;
+@@ -267,7 +267,7 @@ static int __pmac sm_erase_bank(int bank
+ 	return 0;
+ }
+ 
+-static int __pmac sm_write_bank(int bank, u8* datas)
++static int sm_write_bank(int bank, u8* datas)
+ {
+ 	int i, stat = 0;
+ 	unsigned long timeout;
+@@ -302,7 +302,7 @@ static int __pmac sm_write_bank(int bank
+ 	return 0;
+ }
+ 
+-static int __pmac amd_erase_bank(int bank)
++static int amd_erase_bank(int bank)
+ {
+ 	int i, stat = 0;
+ 	unsigned long timeout;
+@@ -349,7 +349,7 @@ static int __pmac amd_erase_bank(int ban
+ 	return 0;
+ }
+ 
+-static int __pmac amd_write_bank(int bank, u8* datas)
++static int amd_write_bank(int bank, u8* datas)
+ {
+ 	int i, stat = 0;
+ 	unsigned long timeout;
+@@ -430,7 +430,7 @@ static void __init lookup_partitions(voi
+ 	DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
+ }
+ 
+-static void __pmac core99_nvram_sync(void)
++static void core99_nvram_sync(void)
+ {
+ 	struct core99_header* hdr99;
+ 	unsigned long flags;
+@@ -554,12 +554,12 @@ void __init pmac_nvram_init(void)
+ 	lookup_partitions();
+ }
+ 
+-int __pmac pmac_get_partition(int partition)
++int pmac_get_partition(int partition)
+ {
+ 	return nvram_partitions[partition];
+ }
+ 
+-u8 __pmac pmac_xpram_read(int xpaddr)
++u8 pmac_xpram_read(int xpaddr)
+ {
+ 	int offset = nvram_partitions[pmac_nvram_XPRAM];
+ 
+@@ -569,7 +569,7 @@ u8 __pmac pmac_xpram_read(int xpaddr)
+ 	return ppc_md.nvram_read_val(xpaddr + offset);
+ }
+ 
+-void __pmac pmac_xpram_write(int xpaddr, u8 data)
++void pmac_xpram_write(int xpaddr, u8 data)
+ {
+ 	int offset = nvram_partitions[pmac_nvram_XPRAM];
+ 
+diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c
+--- a/arch/ppc/platforms/pmac_pci.c
++++ b/arch/ppc/platforms/pmac_pci.c
+@@ -141,7 +141,7 @@ fixup_bus_range(struct device_node *brid
+ 	|(((unsigned long)(off)) & 0xFCUL) \
+ 	|1UL)
+ 
+-static void volatile __iomem * __pmac
++static void volatile __iomem *
+ macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
+ {
+ 	unsigned int caddr;
+@@ -162,7 +162,7 @@ macrisc_cfg_access(struct pci_controller
+ 	return hose->cfg_data + offset;
+ }
+ 
+-static int __pmac
++static int
+ macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		    int len, u32 *val)
+ {
+@@ -190,7 +190,7 @@ macrisc_read_config(struct pci_bus *bus,
+ 	return PCIBIOS_SUCCESSFUL;
+ }
+ 
+-static int __pmac
++static int
+ macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		     int len, u32 val)
+ {
+@@ -230,7 +230,7 @@ static struct pci_ops macrisc_pci_ops =
+ /*
+  * Verifiy that a specific (bus, dev_fn) exists on chaos
+  */
+-static int __pmac
++static int
+ chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
+ {
+ 	struct device_node *np;
+@@ -252,7 +252,7 @@ chaos_validate_dev(struct pci_bus *bus, 
+ 	return PCIBIOS_SUCCESSFUL;
+ }
+ 
+-static int __pmac
++static int
+ chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		  int len, u32 *val)
+ {
+@@ -264,7 +264,7 @@ chaos_read_config(struct pci_bus *bus, u
+ 	return macrisc_read_config(bus, devfn, offset, len, val);
+ }
+ 
+-static int __pmac
++static int
+ chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		   int len, u32 val)
+ {
+@@ -294,7 +294,7 @@ static struct pci_ops chaos_pci_ops =
+ 		+ (((unsigned long)bus) << 16) \
+ 		+ 0x01000000UL)
+ 
+-static void volatile __iomem * __pmac
++static void volatile __iomem *
+ u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)
+ {
+ 	if (bus == hose->first_busno) {
+@@ -307,7 +307,7 @@ u3_ht_cfg_access(struct pci_controller* 
+ 		return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
+ }
+ 
+-static int __pmac
++static int
+ u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		    int len, u32 *val)
+ {
+@@ -357,7 +357,7 @@ u3_ht_read_config(struct pci_bus *bus, u
+ 	return PCIBIOS_SUCCESSFUL;
+ }
+ 
+-static int __pmac
++static int
+ u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		     int len, u32 val)
+ {
+@@ -575,7 +575,7 @@ pmac_find_bridges(void)
+ 	 * some offset between bus number and domains for now when we
+ 	 * assign all busses should help for now
+ 	 */
+-	if (pci_assign_all_busses)
++	if (pci_assign_all_buses)
+ 		pcibios_assign_bus_offset = 0x10;
+ 
+ #ifdef CONFIG_POWER4 
+@@ -643,7 +643,7 @@ static inline void grackle_set_loop_snoo
+ static int __init
+ setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
+ {
+-	pci_assign_all_busses = 1;
++	pci_assign_all_buses = 1;
+ 	has_uninorth = 1;
+ 	hose->ops = &macrisc_pci_ops;
+ 	hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+@@ -677,7 +677,7 @@ setup_u3_agp(struct pci_controller* hose
+ {
+ 	/* On G5, we move AGP up to high bus number so we don't need
+ 	 * to reassign bus numbers for HT. If we ever have P2P bridges
+-	 * on AGP, we'll have to move pci_assign_all_busses to the
++	 * on AGP, we'll have to move pci_assign_all_buses to the
+ 	 * pci_controller structure so we enable it for AGP and not for
+ 	 * HT childs.
+ 	 * We hard code the address because of the different size of
+@@ -899,7 +899,7 @@ pmac_pcibios_fixup(void)
+ 	pcibios_fixup_OF_interrupts();
+ }
+ 
+-int __pmac
++int
+ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
+ {
+ 	struct device_node* node;
+@@ -1096,7 +1096,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_
+  * Disable second function on K2-SATA, it's broken
+  * and disable IO BARs on first one
+  */
+-void __pmac pmac_pci_fixup_k2_sata(struct pci_dev* dev)
++void pmac_pci_fixup_k2_sata(struct pci_dev* dev)
+ {
+ 	int i;
+ 	u16 cmd;
+diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c
+--- a/arch/ppc/platforms/pmac_pic.c
++++ b/arch/ppc/platforms/pmac_pic.c
+@@ -35,6 +35,7 @@
+ #include <asm/open_pic.h>
+ #include <asm/xmon.h>
+ #include <asm/pmac_feature.h>
++#include <asm/machdep.h>
+ 
+ #include "pmac_pic.h"
+ 
+@@ -53,7 +54,7 @@ struct pmac_irq_hw {
+ };
+ 
+ /* Default addresses */
+-static volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmacdata = {
++static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
+         (struct pmac_irq_hw *) 0xf3000020,
+         (struct pmac_irq_hw *) 0xf3000010,
+         (struct pmac_irq_hw *) 0xf4000020,
+@@ -64,22 +65,22 @@ static volatile struct pmac_irq_hw *pmac
+ #define OHARE_LEVEL_MASK	0x1ff00000
+ #define HEATHROW_LEVEL_MASK	0x1ff00000
+ 
+-static int max_irqs __pmacdata;
+-static int max_real_irqs __pmacdata;
+-static u32 level_mask[4] __pmacdata;
++static int max_irqs;
++static int max_real_irqs;
++static u32 level_mask[4];
+ 
+-static DEFINE_SPINLOCK(pmac_pic_lock __pmacdata);
++static DEFINE_SPINLOCK(pmac_pic_lock);
+ 
+ 
+ #define GATWICK_IRQ_POOL_SIZE        10
+-static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE] __pmacdata;
++static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
+ 
+ /*
+  * Mark an irq as "lost".  This is only used on the pmac
+  * since it can lose interrupts (see pmac_set_irq_mask).
+  * -- Cort
+  */
+-void __pmac
++void
+ __set_lost(unsigned long irq_nr, int nokick)
+ {
+ 	if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
+@@ -89,7 +90,7 @@ __set_lost(unsigned long irq_nr, int nok
+ 	}
+ }
+ 
+-static void __pmac
++static void
+ pmac_mask_and_ack_irq(unsigned int irq_nr)
+ {
+         unsigned long bit = 1UL << (irq_nr & 0x1f);
+@@ -114,7 +115,7 @@ pmac_mask_and_ack_irq(unsigned int irq_n
+ 	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ }
+ 
+-static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
++static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
+ {
+         unsigned long bit = 1UL << (irq_nr & 0x1f);
+         int i = irq_nr >> 5;
+@@ -147,7 +148,7 @@ static void __pmac pmac_set_irq_mask(uns
+ /* When an irq gets requested for the first client, if it's an
+  * edge interrupt, we clear any previous one on the controller
+  */
+-static unsigned int __pmac pmac_startup_irq(unsigned int irq_nr)
++static unsigned int pmac_startup_irq(unsigned int irq_nr)
+ {
+         unsigned long bit = 1UL << (irq_nr & 0x1f);
+         int i = irq_nr >> 5;
+@@ -160,20 +161,20 @@ static unsigned int __pmac pmac_startup_
+ 	return 0;
+ }
+ 
+-static void __pmac pmac_mask_irq(unsigned int irq_nr)
++static void pmac_mask_irq(unsigned int irq_nr)
+ {
+         clear_bit(irq_nr, ppc_cached_irq_mask);
+         pmac_set_irq_mask(irq_nr, 0);
+         mb();
+ }
+ 
+-static void __pmac pmac_unmask_irq(unsigned int irq_nr)
++static void pmac_unmask_irq(unsigned int irq_nr)
+ {
+         set_bit(irq_nr, ppc_cached_irq_mask);
+         pmac_set_irq_mask(irq_nr, 0);
+ }
+ 
+-static void __pmac pmac_end_irq(unsigned int irq_nr)
++static void pmac_end_irq(unsigned int irq_nr)
+ {
+ 	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+ 	    && irq_desc[irq_nr].action) {
+diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
+--- a/arch/ppc/platforms/pmac_setup.c
++++ b/arch/ppc/platforms/pmac_setup.c
+@@ -122,7 +122,7 @@ extern struct smp_ops_t psurge_smp_ops;
+ extern struct smp_ops_t core99_smp_ops;
+ #endif /* CONFIG_SMP */
+ 
+-static int __pmac
++static int
+ pmac_show_cpuinfo(struct seq_file *m)
+ {
+ 	struct device_node *np;
+@@ -226,7 +226,7 @@ pmac_show_cpuinfo(struct seq_file *m)
+ 	return 0;
+ }
+ 
+-static int __openfirmware
++static int
+ pmac_show_percpuinfo(struct seq_file *m, int i)
+ {
+ #ifdef CONFIG_CPU_FREQ_PMAC
+@@ -330,9 +330,9 @@ pmac_setup_arch(void)
+ #ifdef CONFIG_SMP
+ 	/* Check for Core99 */
+ 	if (find_devices("uni-n") || find_devices("u3"))
+-		ppc_md.smp_ops = &core99_smp_ops;
++		smp_ops = &core99_smp_ops;
+ 	else
+-		ppc_md.smp_ops = &psurge_smp_ops;
++		smp_ops = &psurge_smp_ops;
+ #endif /* CONFIG_SMP */
+ 
+ 	pci_create_OF_bus_map();
+@@ -447,7 +447,7 @@ static int pmac_pm_enter(suspend_state_t
+ 	enable_kernel_fp();
+ 
+ #ifdef CONFIG_ALTIVEC
+-	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC)
++	if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
+ 		enable_kernel_altivec();
+ #endif /* CONFIG_ALTIVEC */
+ 
+@@ -485,7 +485,7 @@ static int pmac_late_init(void)
+ late_initcall(pmac_late_init);
+ 
+ /* can't be __init - can be called whenever a disk is first accessed */
+-void __pmac
++void
+ note_bootable_part(dev_t dev, int part, int goodness)
+ {
+ 	static int found_boot = 0;
+@@ -511,7 +511,7 @@ note_bootable_part(dev_t dev, int part, 
+ 	}
+ }
+ 
+-static void __pmac
++static void
+ pmac_restart(char *cmd)
+ {
+ #ifdef CONFIG_ADB_CUDA
+@@ -536,7 +536,7 @@ pmac_restart(char *cmd)
+ 	}
+ }
+ 
+-static void __pmac
++static void
+ pmac_power_off(void)
+ {
+ #ifdef CONFIG_ADB_CUDA
+@@ -561,7 +561,7 @@ pmac_power_off(void)
+ 	}
+ }
+ 
+-static void __pmac
++static void
+ pmac_halt(void)
+ {
+    pmac_power_off();
+@@ -661,7 +661,6 @@ pmac_init(unsigned long r3, unsigned lon
+ 	ppc_md.setup_arch     = pmac_setup_arch;
+ 	ppc_md.show_cpuinfo   = pmac_show_cpuinfo;
+ 	ppc_md.show_percpuinfo = pmac_show_percpuinfo;
+-	ppc_md.irq_canonicalize = NULL;
+ 	ppc_md.init_IRQ       = pmac_pic_init;
+ 	ppc_md.get_irq        = pmac_get_irq; /* Changed later on ... */
+ 
+diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
+--- a/arch/ppc/platforms/pmac_sleep.S
++++ b/arch/ppc/platforms/pmac_sleep.S
+@@ -387,10 +387,10 @@ turn_on_mmu:
+ #endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
+ 
+ 	.section .data
+-	.balign	L1_CACHE_LINE_SIZE
++	.balign	L1_CACHE_BYTES
+ sleep_storage:
+ 	.long 0
+-	.balign	L1_CACHE_LINE_SIZE, 0
++	.balign	L1_CACHE_BYTES, 0
+ 
+ #endif /* CONFIG_6xx */
+ 	.section .text
+diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c
+--- a/arch/ppc/platforms/pmac_smp.c
++++ b/arch/ppc/platforms/pmac_smp.c
+@@ -186,7 +186,7 @@ static inline void psurge_clr_ipi(int cp
+  */
+ static unsigned long psurge_smp_message[NR_CPUS];
+ 
+-void __pmac psurge_smp_message_recv(struct pt_regs *regs)
++void psurge_smp_message_recv(struct pt_regs *regs)
+ {
+ 	int cpu = smp_processor_id();
+ 	int msg;
+@@ -203,14 +203,13 @@ void __pmac psurge_smp_message_recv(stru
+ 			smp_message_recv(msg, regs);
+ }
+ 
+-irqreturn_t __pmac psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
++irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
+ {
+ 	psurge_smp_message_recv(regs);
+ 	return IRQ_HANDLED;
+ }
+ 
+-static void __pmac smp_psurge_message_pass(int target, int msg, unsigned long data,
+-					   int wait)
++static void smp_psurge_message_pass(int target, int msg)
+ {
+ 	int i;
+ 
+@@ -629,7 +628,7 @@ void smp_core99_give_timebase(void)
+ 
+ 
+ /* PowerSurge-style Macs */
+-struct smp_ops_t psurge_smp_ops __pmacdata = {
++struct smp_ops_t psurge_smp_ops = {
+ 	.message_pass	= smp_psurge_message_pass,
+ 	.probe		= smp_psurge_probe,
+ 	.kick_cpu	= smp_psurge_kick_cpu,
+@@ -639,7 +638,7 @@ struct smp_ops_t psurge_smp_ops __pmacda
+ };
+ 
+ /* Core99 Macs (dual G4s) */
+-struct smp_ops_t core99_smp_ops __pmacdata = {
++struct smp_ops_t core99_smp_ops = {
+ 	.message_pass	= smp_openpic_message_pass,
+ 	.probe		= smp_core99_probe,
+ 	.kick_cpu	= smp_core99_kick_cpu,
+diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c
+--- a/arch/ppc/platforms/pmac_time.c
++++ b/arch/ppc/platforms/pmac_time.c
+@@ -77,7 +77,7 @@ pmac_time_init(void)
+ #endif
+ }
+ 
+-unsigned long __pmac
++unsigned long
+ pmac_get_rtc_time(void)
+ {
+ #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
+@@ -118,7 +118,7 @@ pmac_get_rtc_time(void)
+ 	return 0;
+ }
+ 
+-int __pmac
++int
+ pmac_set_rtc_time(unsigned long nowtime)
+ {
+ #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
+@@ -210,7 +210,7 @@ via_calibrate_decr(void)
+ /*
+  * Reset the time after a sleep.
+  */
+-static int __pmac
++static int
+ time_sleep_notify(struct pmu_sleep_notifier *self, int when)
+ {
+ 	static unsigned long time_diff;
+@@ -235,7 +235,7 @@ time_sleep_notify(struct pmu_sleep_notif
+ 	return PBOOK_SLEEP_OK;
+ }
+ 
+-static struct pmu_sleep_notifier time_sleep_notifier __pmacdata = {
++static struct pmu_sleep_notifier time_sleep_notifier = {
+ 	time_sleep_notify, SLEEP_LEVEL_MISC,
+ };
+ #endif /* CONFIG_PM */
+diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
+--- a/arch/ppc/platforms/pplus.c
++++ b/arch/ppc/platforms/pplus.c
+@@ -646,14 +646,6 @@ static void pplus_power_off(void)
+ 	pplus_halt();
+ }
+ 
+-static unsigned int pplus_irq_canonicalize(u_int irq)
+-{
+-	if (irq == 2)
+-		return 9;
+-	else
+-		return irq;
+-}
+-
+ static void __init pplus_init_IRQ(void)
+ {
+ 	int i;
+@@ -673,10 +665,7 @@ static void __init pplus_init_IRQ(void)
+ 		ppc_md.get_irq = openpic_get_irq;
+ 	}
+ 
+-	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
+-		irq_desc[i].handler = &i8259_pic;
+-
+-	i8259_init(0);
++	i8259_init(0, 0);
+ 
+ 	if (ppc_md.progress)
+ 		ppc_md.progress("init_irq: exit", 0);
+@@ -872,10 +861,10 @@ platform_init(unsigned long r3, unsigned
+ 	ISA_DMA_THRESHOLD = 0x00ffffff;
+ 	DMA_MODE_READ = 0x44;
+ 	DMA_MODE_WRITE = 0x48;
++	ppc_do_canonicalize_irqs = 1;
+ 
+ 	ppc_md.setup_arch = pplus_setup_arch;
+ 	ppc_md.show_cpuinfo = pplus_show_cpuinfo;
+-	ppc_md.irq_canonicalize = pplus_irq_canonicalize;
+ 	ppc_md.init_IRQ = pplus_init_IRQ;
+ 	/* this gets changed later on if we have an OpenPIC -- Cort */
+ 	ppc_md.get_irq = i8259_irq;
+@@ -911,6 +900,6 @@ platform_init(unsigned long r3, unsigned
+ 	ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
+ #endif
+ #ifdef CONFIG_SMP
+-	ppc_md.smp_ops = &pplus_smp_ops;
++	smp_ops = &pplus_smp_ops;
+ #endif				/* CONFIG_SMP */
+ }
+diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
+--- a/arch/ppc/platforms/prep_pci.c
++++ b/arch/ppc/platforms/prep_pci.c
+@@ -43,7 +43,7 @@ static unsigned long	*ProcInfo;
+ /* Tables for known hardware */
+ 
+ /* Motorola PowerStackII - Utah */
+-static char Utah_pci_IRQ_map[23] __prepdata =
++static char Utah_pci_IRQ_map[23] =
+ {
+         0,   /* Slot 0  - unused */
+         0,   /* Slot 1  - unused */
+@@ -72,7 +72,7 @@ static char Utah_pci_IRQ_map[23] __prepd
+         0,   /* Slot 22 - unused */
+ };
+ 
+-static char Utah_pci_IRQ_routes[] __prepdata =
++static char Utah_pci_IRQ_routes[] =
+ {
+         0,   /* Line 0 - Unused */
+         9,   /* Line 1 */
+@@ -84,7 +84,7 @@ static char Utah_pci_IRQ_routes[] __prep
+ 
+ /* Motorola PowerStackII - Omaha */
+ /* no integrated SCSI or ethernet */
+-static char Omaha_pci_IRQ_map[23] __prepdata =
++static char Omaha_pci_IRQ_map[23] =
+ {
+         0,   /* Slot 0  - unused */
+         0,   /* Slot 1  - unused */
+@@ -111,7 +111,7 @@ static char Omaha_pci_IRQ_map[23] __prep
+         0,
+ };
+ 
+-static char Omaha_pci_IRQ_routes[] __prepdata =
++static char Omaha_pci_IRQ_routes[] =
+ {
+         0,   /* Line 0 - Unused */
+         9,   /* Line 1 */
+@@ -121,7 +121,7 @@ static char Omaha_pci_IRQ_routes[] __pre
+ };
+ 
+ /* Motorola PowerStack */
+-static char Blackhawk_pci_IRQ_map[19] __prepdata =
++static char Blackhawk_pci_IRQ_map[19] =
+ {
+   	0,	/* Slot 0  - unused */
+   	0,	/* Slot 1  - unused */
+@@ -144,7 +144,7 @@ static char Blackhawk_pci_IRQ_map[19] __
+  	3,	/* Slot P5 */
+ };
+ 
+-static char Blackhawk_pci_IRQ_routes[] __prepdata =
++static char Blackhawk_pci_IRQ_routes[] =
+ {
+    	0,	/* Line 0 - Unused */
+    	9,	/* Line 1 */
+@@ -154,7 +154,7 @@ static char Blackhawk_pci_IRQ_routes[] _
+ };
+ 
+ /* Motorola Mesquite */
+-static char Mesquite_pci_IRQ_map[23] __prepdata =
++static char Mesquite_pci_IRQ_map[23] =
+ {
+ 	0,	/* Slot 0  - unused */
+ 	0,	/* Slot 1  - unused */
+@@ -182,7 +182,7 @@ static char Mesquite_pci_IRQ_map[23] __p
+ };
+ 
+ /* Motorola Sitka */
+-static char Sitka_pci_IRQ_map[21] __prepdata =
++static char Sitka_pci_IRQ_map[21] =
+ {
+ 	0,      /* Slot 0  - unused */
+ 	0,      /* Slot 1  - unused */
+@@ -208,7 +208,7 @@ static char Sitka_pci_IRQ_map[21] __prep
+ };
+ 
+ /* Motorola MTX */
+-static char MTX_pci_IRQ_map[23] __prepdata =
++static char MTX_pci_IRQ_map[23] =
+ {
+ 	0,	/* Slot 0  - unused */
+ 	0,	/* Slot 1  - unused */
+@@ -237,7 +237,7 @@ static char MTX_pci_IRQ_map[23] __prepda
+ 
+ /* Motorola MTX Plus */
+ /* Secondary bus interrupt routing is not supported yet */
+-static char MTXplus_pci_IRQ_map[23] __prepdata =
++static char MTXplus_pci_IRQ_map[23] =
+ {
+         0,      /* Slot 0  - unused */
+         0,      /* Slot 1  - unused */
+@@ -264,13 +264,13 @@ static char MTXplus_pci_IRQ_map[23] __pr
+         0,      /* Slot 22 - unused */
+ };
+ 
+-static char Raven_pci_IRQ_routes[] __prepdata =
++static char Raven_pci_IRQ_routes[] =
+ {
+    	0,	/* This is a dummy structure */
+ };
+ 
+ /* Motorola MVME16xx */
+-static char Genesis_pci_IRQ_map[16] __prepdata =
++static char Genesis_pci_IRQ_map[16] =
+ {
+   	0,	/* Slot 0  - unused */
+   	0,	/* Slot 1  - unused */
+@@ -290,7 +290,7 @@ static char Genesis_pci_IRQ_map[16] __pr
+   	0,	/* Slot 15 - unused */
+ };
+ 
+-static char Genesis_pci_IRQ_routes[] __prepdata =
++static char Genesis_pci_IRQ_routes[] =
+ {
+    	0,	/* Line 0 - Unused */
+    	10,	/* Line 1 */
+@@ -299,7 +299,7 @@ static char Genesis_pci_IRQ_routes[] __p
+    	15	/* Line 4 */
+ };
+ 
+-static char Genesis2_pci_IRQ_map[23] __prepdata =
++static char Genesis2_pci_IRQ_map[23] =
+ {
+ 	0,	/* Slot 0  - unused */
+ 	0,	/* Slot 1  - unused */
+@@ -327,7 +327,7 @@ static char Genesis2_pci_IRQ_map[23] __p
+ };
+ 
+ /* Motorola Series-E */
+-static char Comet_pci_IRQ_map[23] __prepdata =
++static char Comet_pci_IRQ_map[23] =
+ {
+   	0,	/* Slot 0  - unused */
+   	0,	/* Slot 1  - unused */
+@@ -354,7 +354,7 @@ static char Comet_pci_IRQ_map[23] __prep
+ 	0,
+ };
+ 
+-static char Comet_pci_IRQ_routes[] __prepdata =
++static char Comet_pci_IRQ_routes[] =
+ {
+    	0,	/* Line 0 - Unused */
+    	10,	/* Line 1 */
+@@ -364,7 +364,7 @@ static char Comet_pci_IRQ_routes[] __pre
+ };
+ 
+ /* Motorola Series-EX */
+-static char Comet2_pci_IRQ_map[23] __prepdata =
++static char Comet2_pci_IRQ_map[23] =
+ {
+ 	0,	/* Slot 0  - unused */
+ 	0,	/* Slot 1  - unused */
+@@ -391,7 +391,7 @@ static char Comet2_pci_IRQ_map[23] __pre
+ 	0,
+ };
+ 
+-static char Comet2_pci_IRQ_routes[] __prepdata =
++static char Comet2_pci_IRQ_routes[] =
+ {
+ 	0,	/* Line 0 - Unused */
+ 	10,	/* Line 1 */
+@@ -405,7 +405,7 @@ static char Comet2_pci_IRQ_routes[] __pr
+  * This is actually based on the Carolina motherboard
+  * -- Cort
+  */
+-static char ibm8xx_pci_IRQ_map[23] __prepdata = {
++static char ibm8xx_pci_IRQ_map[23] = {
+         0, /* Slot 0  - unused */
+         0, /* Slot 1  - unused */
+         0, /* Slot 2  - unused */
+@@ -431,7 +431,7 @@ static char ibm8xx_pci_IRQ_map[23] __pre
+         2, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */
+ };
+ 
+-static char ibm8xx_pci_IRQ_routes[] __prepdata = {
++static char ibm8xx_pci_IRQ_routes[] = {
+         0,      /* Line 0 - unused */
+         15,     /* Line 1 */
+         15,     /* Line 2 */
+@@ -443,7 +443,7 @@ static char ibm8xx_pci_IRQ_routes[] __pr
+  * a 6015 ibm board
+  * -- Cort
+  */
+-static char ibm6015_pci_IRQ_map[23] __prepdata = {
++static char ibm6015_pci_IRQ_map[23] = {
+         0, /* Slot 0  - unused */
+         0, /* Slot 1  - unused */
+         0, /* Slot 2  - unused */
+@@ -469,7 +469,7 @@ static char ibm6015_pci_IRQ_map[23] __pr
+         2, /* Slot 22 -  */
+ };
+ 
+-static char ibm6015_pci_IRQ_routes[] __prepdata = {
++static char ibm6015_pci_IRQ_routes[] = {
+         0,      /* Line 0 - unused */
+         13,     /* Line 1 */
+         15,     /* Line 2 */
+@@ -479,7 +479,7 @@ static char ibm6015_pci_IRQ_routes[] __p
+ 
+ 
+ /* IBM Nobis and Thinkpad 850 */
+-static char Nobis_pci_IRQ_map[23] __prepdata ={
++static char Nobis_pci_IRQ_map[23] ={
+         0, /* Slot 0  - unused */
+         0, /* Slot 1  - unused */
+         0, /* Slot 2  - unused */
+@@ -498,7 +498,7 @@ static char Nobis_pci_IRQ_map[23] __prep
+         0, /* Slot 15 - unused */
+ };
+ 
+-static char Nobis_pci_IRQ_routes[] __prepdata = {
++static char Nobis_pci_IRQ_routes[] = {
+         0, /* Line 0 - Unused */
+         13, /* Line 1 */
+         13, /* Line 2 */
+@@ -510,7 +510,7 @@ static char Nobis_pci_IRQ_routes[] __pre
+  * IBM RS/6000 43p/140  -- paulus
+  * XXX we should get all this from the residual data
+  */
+-static char ibm43p_pci_IRQ_map[23] __prepdata = {
++static char ibm43p_pci_IRQ_map[23] = {
+         0, /* Slot 0  - unused */
+         0, /* Slot 1  - unused */
+         0, /* Slot 2  - unused */
+@@ -536,7 +536,7 @@ static char ibm43p_pci_IRQ_map[23] __pre
+         1, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */
+ };
+ 
+-static char ibm43p_pci_IRQ_routes[] __prepdata = {
++static char ibm43p_pci_IRQ_routes[] = {
+         0,      /* Line 0 - unused */
+         15,     /* Line 1 */
+         15,     /* Line 2 */
+@@ -559,7 +559,7 @@ struct powerplus_irq_list
+  * are routed to OpenPIC inputs 5-8.  These values are offset by
+  * 16 in the table to reflect the Linux kernel interrupt value.
+  */
+-struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata =
++struct powerplus_irq_list Powerplus_pci_IRQ_list =
+ {
+ 	{25, 26, 27, 28},
+ 	{21, 22, 23, 24}
+@@ -572,7 +572,7 @@ struct powerplus_irq_list Powerplus_pci_
+  * are routed to OpenPIC inputs 12-15. These values are offset by
+  * 16 in the table to reflect the Linux kernel interrupt value.
+  */
+-struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata =
++struct powerplus_irq_list Mesquite_pci_IRQ_list =
+ {
+ 	{24, 25, 26, 27},
+ 	{28, 29, 30, 31}
+@@ -582,7 +582,7 @@ struct powerplus_irq_list Mesquite_pci_I
+  * This table represents the standard PCI swizzle defined in the
+  * PCI bus specification.
+  */
+-static unsigned char prep_pci_intpins[4][4] __prepdata =
++static unsigned char prep_pci_intpins[4][4] =
+ {
+ 	{ 1, 2, 3, 4},  /* Buses 0, 4, 8, ... */
+ 	{ 2, 3, 4, 1},  /* Buses 1, 5, 9, ... */
+@@ -622,7 +622,7 @@ static unsigned char prep_pci_intpins[4]
+ #define MIN_DEVNR	11
+ #define MAX_DEVNR	22
+ 
+-static int __prep
++static int
+ prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		 int len, u32 *val)
+ {
+@@ -652,7 +652,7 @@ prep_read_config(struct pci_bus *bus, un
+ 	return PCIBIOS_SUCCESSFUL;
+ }
+ 
+-static int __prep
++static int
+ prep_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ 		  int len, u32 val)
+ {
+@@ -804,7 +804,7 @@ struct mot_info {
+ 	void            (*map_non0_bus)(struct pci_dev *);      /* For boards with more than bus 0 devices. */
+ 	struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */
+ 	unsigned char   secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */
+-} mot_info[] __prepdata = {
++} mot_info[] = {
+ 	{0x300, 0x00, 0x00, "MVME 2400",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ 	{0x010, 0x00, 0x00, "Genesis",				Genesis_pci_IRQ_map,	Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+ 	{0x020, 0x00, 0x00, "Powerstack (Series E)",		Comet_pci_IRQ_map,	Comet_pci_IRQ_routes, NULL, NULL, 0x00},
+diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
+--- a/arch/ppc/platforms/prep_setup.c
++++ b/arch/ppc/platforms/prep_setup.c
+@@ -89,9 +89,6 @@ extern void prep_tiger1_setup_pci(char *
+ #define cached_21	(((char *)(ppc_cached_irq_mask))[3])
+ #define cached_A1	(((char *)(ppc_cached_irq_mask))[2])
+ 
+-/* for the mac fs */
+-dev_t boot_dev;
+-
+ #ifdef CONFIG_SOUND_CS4232
+ long ppc_cs4232_dma, ppc_cs4232_dma2;
+ #endif
+@@ -173,7 +170,7 @@ prep_carolina_enable_l2(void)
+ }
+ 
+ /* cpuinfo code common to all IBM PReP */
+-static void __prep
++static void
+ prep_ibm_cpuinfo(struct seq_file *m)
+ {
+ 	unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
+@@ -209,14 +206,14 @@ prep_ibm_cpuinfo(struct seq_file *m)
+ 	}
+ }
+ 
+-static int __prep
++static int
+ prep_gen_cpuinfo(struct seq_file *m)
+ {
+ 	prep_ibm_cpuinfo(m);
+ 	return 0;
+ }
+ 
+-static int __prep
++static int
+ prep_sandalfoot_cpuinfo(struct seq_file *m)
+ {
+ 	unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
+@@ -243,7 +240,7 @@ prep_sandalfoot_cpuinfo(struct seq_file 
+ 	return 0;
+ }
+ 
+-static int __prep
++static int
+ prep_thinkpad_cpuinfo(struct seq_file *m)
+ {
+ 	unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
+@@ -314,7 +311,7 @@ prep_thinkpad_cpuinfo(struct seq_file *m
+ 	return 0;
+ }
+ 
+-static int __prep
++static int
+ prep_carolina_cpuinfo(struct seq_file *m)
+ {
+ 	unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
+@@ -350,7 +347,7 @@ prep_carolina_cpuinfo(struct seq_file *m
+ 	return 0;
+ }
+ 
+-static int __prep
++static int
+ prep_tiger1_cpuinfo(struct seq_file *m)
+ {
+ 	unsigned int l2_reg = inb(PREP_IBM_L2INFO);
+@@ -393,7 +390,7 @@ prep_tiger1_cpuinfo(struct seq_file *m)
+ 
+ 
+ /* Used by all Motorola PReP */
+-static int __prep
++static int
+ prep_mot_cpuinfo(struct seq_file *m)
+ {
+ 	unsigned int cachew = *((unsigned char *)CACHECRBA);
+@@ -454,7 +451,7 @@ no_l2:
+ 	return 0;
+ }
+ 
+-static void __prep
++static void
+ prep_restart(char *cmd)
+ {
+ #define PREP_SP92	0x92	/* Special Port 92 */
+@@ -473,7 +470,7 @@ prep_restart(char *cmd)
+ #undef PREP_SP92
+ }
+ 
+-static void __prep
++static void
+ prep_halt(void)
+ {
+ 	local_irq_disable(); /* no interrupts */
+@@ -488,7 +485,7 @@ prep_halt(void)
+ /* Carrera is the power manager in the Thinkpads. Unfortunately not much is
+  * known about it, so we can't power down.
+  */
+-static void __prep
++static void
+ prep_carrera_poweroff(void)
+ {
+ 	prep_halt();
+@@ -501,7 +498,7 @@ prep_carrera_poweroff(void)
+  * somewhat in the IBM Carolina Technical Specification.
+  * -Hollis
+  */
+-static void __prep
++static void
+ utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value)
+ {
+ 	/*
+@@ -539,7 +536,7 @@ utah_sig87c750_setbit(unsigned int byten
+ 	udelay(100);				/* important: let controller recover */
+ }
+ 
+-static void __prep
++static void
+ prep_sig750_poweroff(void)
+ {
+ 	/* tweak the power manager found in most IBM PRePs (except Thinkpads) */
+@@ -554,7 +551,7 @@ prep_sig750_poweroff(void)
+ 	/* not reached */
+ }
+ 
+-static int __prep
++static int
+ prep_show_percpuinfo(struct seq_file *m, int i)
+ {
+ 	/* PREP's without residual data will give incorrect values here */
+@@ -700,12 +697,12 @@ prep_set_bat(void)
+ /*
+  * IBM 3-digit status LED
+  */
+-static unsigned int ibm_statusled_base __prepdata;
++static unsigned int ibm_statusled_base;
+ 
+-static void __prep
++static void
+ ibm_statusled_progress(char *s, unsigned short hex);
+ 
+-static int __prep
++static int
+ ibm_statusled_panic(struct notifier_block *dummy1, unsigned long dummy2,
+ 		    void * dummy3)
+ {
+@@ -713,13 +710,13 @@ ibm_statusled_panic(struct notifier_bloc
+ 	return NOTIFY_DONE;
+ }
+ 
+-static struct notifier_block ibm_statusled_block __prepdata = {
++static struct notifier_block ibm_statusled_block = {
+ 	ibm_statusled_panic,
+ 	NULL,
+ 	INT_MAX /* try to do it first */
+ };
+ 
+-static void __prep
++static void
+ ibm_statusled_progress(char *s, unsigned short hex)
+ {
+ 	static int notifier_installed;
+@@ -945,19 +942,6 @@ prep_calibrate_decr(void)
+ 		todc_calibrate_decr();
+ }
+ 
+-static unsigned int __prep
+-prep_irq_canonicalize(u_int irq)
+-{
+-	if (irq == 2)
+-	{
+-		return 9;
+-	}
+-	else
+-	{
+-		return irq;
+-	}
+-}
+-
+ static void __init
+ prep_init_IRQ(void)
+ {
+@@ -970,11 +954,9 @@ prep_init_IRQ(void)
+ 		openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
+ 				       i8259_irq);
+ 	}
+-	for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
+-		irq_desc[i].handler = &i8259_pic;
+ 
+ 	if (have_residual_data) {
+-		i8259_init(residual_isapic_addr());
++		i8259_init(residual_isapic_addr(), 0);
+ 		return;
+ 	}
+ 
+@@ -985,18 +967,18 @@ prep_init_IRQ(void)
+ 	if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
+ 			&& ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN)
+ 				|| (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK)))
+-		i8259_init(0);
++		i8259_init(0, 0);
+ 	else
+ 		/* PCI interrupt ack address given in section 6.1.8 of the
+ 		 * PReP specification. */
+-		i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR);
++		i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR, 0);
+ }
+ 
+ #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+ /*
+  * IDE stuff.
+  */
+-static int __prep
++static int
+ prep_ide_default_irq(unsigned long base)
+ {
+ 	switch (base) {
+@@ -1010,7 +992,7 @@ prep_ide_default_irq(unsigned long base)
+ 	}
+ }
+ 
+-static unsigned long __prep
++static unsigned long
+ prep_ide_default_io_base(int index)
+ {
+ 	switch (index) {
+@@ -1055,7 +1037,7 @@ smp_prep_setup_cpu(int cpu_nr)
+ 		do_openpic_setup_cpu();
+ }
+ 
+-static struct smp_ops_t prep_smp_ops __prepdata = {
++static struct smp_ops_t prep_smp_ops = {
+ 	smp_openpic_message_pass,
+ 	smp_prep_probe,
+ 	smp_prep_kick_cpu,
+@@ -1113,6 +1095,7 @@ prep_init(unsigned long r3, unsigned lon
+ 	ISA_DMA_THRESHOLD = 0x00ffffff;
+ 	DMA_MODE_READ = 0x44;
+ 	DMA_MODE_WRITE = 0x48;
++	ppc_do_canonicalize_irqs = 1;
+ 
+ 	/* figure out what kind of prep workstation we are */
+ 	if (have_residual_data) {
+@@ -1139,7 +1122,6 @@ prep_init(unsigned long r3, unsigned lon
+ 	ppc_md.setup_arch     = prep_setup_arch;
+ 	ppc_md.show_percpuinfo = prep_show_percpuinfo;
+ 	ppc_md.show_cpuinfo   = NULL; /* set in prep_setup_arch() */
+-	ppc_md.irq_canonicalize = prep_irq_canonicalize;
+ 	ppc_md.init_IRQ       = prep_init_IRQ;
+ 	/* this gets changed later on if we have an OpenPIC -- Cort */
+ 	ppc_md.get_irq        = i8259_irq;
+@@ -1176,6 +1158,6 @@ prep_init(unsigned long r3, unsigned lon
+ #endif
+ 
+ #ifdef CONFIG_SMP
+-	ppc_md.smp_ops		 = &prep_smp_ops;
++	smp_ops			 = &prep_smp_ops;
+ #endif /* CONFIG_SMP */
+ }
+diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
+--- a/arch/ppc/platforms/radstone_ppc7d.c
++++ b/arch/ppc/platforms/radstone_ppc7d.c
+@@ -40,6 +40,7 @@
+ #include <linux/serial_core.h>
+ #include <linux/mv643xx.h>
+ #include <linux/netdevice.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/system.h>
+ #include <asm/pgtable.h>
+@@ -514,13 +515,9 @@ static void __init ppc7d_init_irq(void)
+ 	int irq;
+ 
+ 	pr_debug("%s\n", __FUNCTION__);
+-	i8259_init(0);
++	i8259_init(0, 0);
+ 	mv64360_init_irq();
+ 
+-	/* IRQ 0..15 are handled by the cascaded 8259's of the Ali1535 */
+-	for (irq = 0; irq < 16; irq++) {
+-		irq_desc[irq].handler = &i8259_pic;
+-	}
+ 	/* IRQs 5,6,9,10,11,14,15 are level sensitive */
+ 	irq_desc[5].status |= IRQ_LEVEL;
+ 	irq_desc[6].status |= IRQ_LEVEL;
+@@ -1183,18 +1180,18 @@ static void __init ppc7d_setup_arch(void
+ 		ROOT_DEV = Root_HDA1;
+ #endif
+ 
+-	if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) ||
+-	    (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR))
++	if ((cur_cpu_spec->cpu_features & CPU_FTR_SPEC7450) ||
++	    (cur_cpu_spec->cpu_features & CPU_FTR_L3CR))
+ 		/* 745x is different.  We only want to pass along enable. */
+ 		_set_L2CR(L2CR_L2E);
+-	else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)
++	else if (cur_cpu_spec->cpu_features & CPU_FTR_L2CR)
+ 		/* All modules have 1MB of L2.  We also assume that an
+ 		 * L2 divisor of 3 will work.
+ 		 */
+ 		_set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3
+ 			  | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF);
+ 
+-	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)
++	if (cur_cpu_spec->cpu_features & CPU_FTR_L3CR)
+ 		/* No L3 cache */
+ 		_set_L3CR(0);
+ 
+@@ -1424,6 +1421,7 @@ void __init platform_init(unsigned long 
+ 	ppc_md.setup_arch = ppc7d_setup_arch;
+ 	ppc_md.init = ppc7d_init2;
+ 	ppc_md.show_cpuinfo = ppc7d_show_cpuinfo;
++	/* XXX this is broken... */
+ 	ppc_md.irq_canonicalize = ppc7d_irq_canonicalize;
+ 	ppc_md.init_IRQ = ppc7d_init_irq;
+ 	ppc_md.get_irq = ppc7d_get_irq;
+diff --git a/arch/ppc/platforms/residual.c b/arch/ppc/platforms/residual.c
+--- a/arch/ppc/platforms/residual.c
++++ b/arch/ppc/platforms/residual.c
+@@ -47,7 +47,7 @@
+ #include <asm/ide.h>
+ 
+ 
+-unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,};
++unsigned char __res[sizeof(RESIDUAL)] = {0,};
+ RESIDUAL *res = (RESIDUAL *)&__res;
+ 
+ char * PnP_BASE_TYPES[] __initdata = {
+diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
+--- a/arch/ppc/platforms/sandpoint.c
++++ b/arch/ppc/platforms/sandpoint.c
+@@ -494,27 +494,10 @@ sandpoint_init_IRQ(void)
+ 			i8259_irq);
+ 
+ 	/*
+-	 * openpic_init() has set up irq_desc[16-31] to be openpic
+-	 * interrupts.  We need to set irq_desc[0-15] to be i8259
+-	 * interrupts.
+-	 */
+-	for(i=0; i < NUM_8259_INTERRUPTS; i++)
+-		irq_desc[i].handler = &i8259_pic;
+-
+-	/*
+ 	 * The EPIC allows for a read in the range of 0xFEF00000 ->
+ 	 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
+ 	 */
+-	i8259_init(0xfef00000);
+-}
+-
+-static u32
+-sandpoint_irq_canonicalize(u32 irq)
+-{
+-	if (irq == 2)
+-		return 9;
+-	else
+-		return irq;
++	i8259_init(0xfef00000, 0);
+ }
+ 
+ static unsigned long __init
+@@ -727,10 +710,10 @@ platform_init(unsigned long r3, unsigned
+ 	ISA_DMA_THRESHOLD = 0x00ffffff;
+ 	DMA_MODE_READ = 0x44;
+ 	DMA_MODE_WRITE = 0x48;
++	ppc_do_canonicalize_irqs = 1;
+ 
+ 	ppc_md.setup_arch = sandpoint_setup_arch;
+ 	ppc_md.show_cpuinfo = sandpoint_show_cpuinfo;
+-	ppc_md.irq_canonicalize = sandpoint_irq_canonicalize;
+ 	ppc_md.init_IRQ = sandpoint_init_IRQ;
+ 	ppc_md.get_irq = openpic_get_irq;
+ 
+diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
+--- a/arch/ppc/syslib/Makefile
++++ b/arch/ppc/syslib/Makefile
+@@ -31,52 +31,49 @@ obj-$(CONFIG_GEN_RTC)		+= todc_time.o
+ obj-$(CONFIG_PPC4xx_DMA)	+= ppc4xx_dma.o
+ obj-$(CONFIG_PPC4xx_EDMA)	+= ppc4xx_sgdma.o
+ ifeq ($(CONFIG_40x),y)
+-obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o ppc405_pci.o
++obj-$(CONFIG_PCI)		+= pci_auto.o ppc405_pci.o
+ endif
+ endif
+ obj-$(CONFIG_8xx)		+= m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
+ 				   ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
+-ifeq ($(CONFIG_8xx),y)
+-obj-$(CONFIG_PCI)		+= qspan_pci.o i8259.o
+-endif
+-obj-$(CONFIG_PPC_OF)		+= prom_init.o prom.o of_device.o
+-obj-$(CONFIG_PPC_PMAC)		+= open_pic.o indirect_pci.o
++obj-$(CONFIG_PCI_QSPAN)		+= qspan_pci.o
++obj-$(CONFIG_PPC_OF)		+= prom_init.o prom.o
++obj-$(CONFIG_PPC_PMAC)		+= open_pic.o
+ obj-$(CONFIG_POWER4)		+= open_pic2.o
+-obj-$(CONFIG_PPC_CHRP)		+= open_pic.o indirect_pci.o i8259.o
+-obj-$(CONFIG_PPC_PREP)		+= open_pic.o indirect_pci.o i8259.o todc_time.o
+-obj-$(CONFIG_BAMBOO)		+= indirect_pci.o pci_auto.o todc_time.o
++obj-$(CONFIG_PPC_CHRP)		+= open_pic.o
++obj-$(CONFIG_PPC_PREP)		+= open_pic.o todc_time.o
++obj-$(CONFIG_BAMBOO)		+= pci_auto.o todc_time.o
+ obj-$(CONFIG_CPCI690)		+= todc_time.o pci_auto.o
+-obj-$(CONFIG_EBONY)		+= indirect_pci.o pci_auto.o todc_time.o
++obj-$(CONFIG_EBONY)		+= pci_auto.o todc_time.o
+ obj-$(CONFIG_EV64260)		+= todc_time.o pci_auto.o
+ obj-$(CONFIG_CHESTNUT)		+= mv64360_pic.o pci_auto.o
+-obj-$(CONFIG_GEMINI)		+= open_pic.o indirect_pci.o
++obj-$(CONFIG_GEMINI)		+= open_pic.o
+ obj-$(CONFIG_GT64260)		+= gt64260_pic.o
+-obj-$(CONFIG_LOPEC)		+= i8259.o pci_auto.o todc_time.o
++obj-$(CONFIG_LOPEC)		+= pci_auto.o todc_time.o
+ obj-$(CONFIG_HDPU)		+= pci_auto.o
+-obj-$(CONFIG_LUAN)		+= indirect_pci.o pci_auto.o todc_time.o
++obj-$(CONFIG_LUAN)		+= pci_auto.o todc_time.o
+ obj-$(CONFIG_KATANA)		+= pci_auto.o
+ obj-$(CONFIG_MV64360)		+= mv64360_pic.o
+-obj-$(CONFIG_MV64X60)		+= mv64x60.o mv64x60_win.o indirect_pci.o
+-obj-$(CONFIG_MVME5100)		+= open_pic.o todc_time.o indirect_pci.o \
++obj-$(CONFIG_MV64X60)		+= mv64x60.o mv64x60_win.o
++obj-$(CONFIG_MVME5100)		+= open_pic.o todc_time.o \
+ 					pci_auto.o hawk_common.o
+-obj-$(CONFIG_MVME5100_IPMC761_PRESENT)	+= i8259.o
+-obj-$(CONFIG_OCOTEA)		+= indirect_pci.o pci_auto.o todc_time.o
++obj-$(CONFIG_OCOTEA)		+= pci_auto.o todc_time.o
+ obj-$(CONFIG_PAL4)		+= cpc700_pic.o
+ obj-$(CONFIG_POWERPMC250)	+= pci_auto.o
+-obj-$(CONFIG_PPLUS)		+= hawk_common.o open_pic.o i8259.o \
+-				   indirect_pci.o todc_time.o pci_auto.o
+-obj-$(CONFIG_PRPMC750)		+= open_pic.o indirect_pci.o pci_auto.o \
++obj-$(CONFIG_PPLUS)		+= hawk_common.o open_pic.o \
++				   todc_time.o pci_auto.o
++obj-$(CONFIG_PRPMC750)		+= open_pic.o pci_auto.o \
+ 					hawk_common.o
+ obj-$(CONFIG_HARRIER)		+= harrier.o
+-obj-$(CONFIG_PRPMC800)		+= open_pic.o indirect_pci.o pci_auto.o
+-obj-$(CONFIG_RADSTONE_PPC7D)	+= i8259.o pci_auto.o
+-obj-$(CONFIG_SANDPOINT)		+= i8259.o pci_auto.o todc_time.o
++obj-$(CONFIG_PRPMC800)		+= open_pic.o pci_auto.o
++obj-$(CONFIG_RADSTONE_PPC7D)	+= pci_auto.o
++obj-$(CONFIG_SANDPOINT)		+= pci_auto.o todc_time.o
+ obj-$(CONFIG_SBC82xx)		+= todc_time.o
+-obj-$(CONFIG_SPRUCE)		+= cpc700_pic.o indirect_pci.o pci_auto.o \
++obj-$(CONFIG_SPRUCE)		+= cpc700_pic.o pci_auto.o \
+ 				   todc_time.o
+ obj-$(CONFIG_8260)		+= m8260_setup.o pq2_devices.o pq2_sys.o \
+ 				   ppc_sys.o
+-obj-$(CONFIG_PCI_8260)		+= m82xx_pci.o indirect_pci.o pci_auto.o
++obj-$(CONFIG_PCI_8260)		+= m82xx_pci.o pci_auto.o
+ obj-$(CONFIG_8260_PCI9)		+= m8260_pci_erratum9.o
+ obj-$(CONFIG_CPM2)		+= cpm2_common.o cpm2_pic.o
+ ifeq ($(CONFIG_PPC_GEN550),y)
+@@ -87,20 +84,18 @@ ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y)
+ obj-$(CONFIG_SERIAL_TEXT_DEBUG)	+= mv64x60_dbg.o
+ endif
+ obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
+-obj-$(CONFIG_MPC10X_BRIDGE)	+= mpc10x_common.o indirect_pci.o ppc_sys.o
++obj-$(CONFIG_MPC10X_BRIDGE)	+= mpc10x_common.o ppc_sys.o
+ obj-$(CONFIG_MPC10X_OPENPIC)	+= open_pic.o
+-obj-$(CONFIG_40x)		+= dcr.o
+-obj-$(CONFIG_BOOKE)		+= dcr.o
+ obj-$(CONFIG_85xx)		+= open_pic.o ppc85xx_common.o ppc85xx_setup.o \
+-					ppc_sys.o i8259.o mpc85xx_sys.o \
++					ppc_sys.o mpc85xx_sys.o \
+ 					mpc85xx_devices.o
+ ifeq ($(CONFIG_85xx),y)
+-obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o
++obj-$(CONFIG_PCI)		+= pci_auto.o
+ endif
+ obj-$(CONFIG_83xx)		+= ipic.o ppc83xx_setup.o ppc_sys.o \
+ 					mpc83xx_sys.o mpc83xx_devices.o
+ ifeq ($(CONFIG_83xx),y)
+-obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o
++obj-$(CONFIG_PCI)		+= pci_auto.o
+ endif
+ obj-$(CONFIG_MPC8548_CDS)	+= todc_time.o
+ obj-$(CONFIG_MPC8555_CDS)	+= todc_time.o
+diff --git a/arch/ppc/syslib/btext.c b/arch/ppc/syslib/btext.c
+--- a/arch/ppc/syslib/btext.c
++++ b/arch/ppc/syslib/btext.c
+@@ -53,8 +53,8 @@ extern char *klimit;
+  * chrp only uses it during early boot.
+  */
+ #ifdef CONFIG_XMON
+-#define BTEXT	__pmac
+-#define BTDATA	__pmacdata
++#define BTEXT
++#define BTDATA
+ #else
+ #define BTEXT	__init
+ #define BTDATA	__initdata
+@@ -187,7 +187,7 @@ btext_setup_display(int width, int heigh
+  *    changes.
+  */
+ 
+-void __openfirmware
++void
+ map_boot_text(void)
+ {
+ 	unsigned long base, offset, size;
+diff --git a/arch/ppc/syslib/dcr.S b/arch/ppc/syslib/dcr.S
+deleted file mode 100644
+--- a/arch/ppc/syslib/dcr.S
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/*
+- * arch/ppc/syslib/dcr.S
+- *
+- * "Indirect" DCR access
+- *
+- * Copyright (c) 2004 Eugene Surovegin <ebs at ebshome.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 <asm/ppc_asm.h>
+-#include <asm/processor.h>
+-
+-#define DCR_ACCESS_PROLOG(table) \
+-	rlwinm  r3,r3,4,18,27;   \
+-	lis     r5,table at h;      \
+-	ori     r5,r5,table at l;   \
+-	add     r3,r3,r5;        \
+-	mtctr   r3;              \
+-	bctr
+-
+-_GLOBAL(__mfdcr)
+-	DCR_ACCESS_PROLOG(__mfdcr_table)
+-
+-_GLOBAL(__mtdcr)
+-	DCR_ACCESS_PROLOG(__mtdcr_table)
+-
+-__mfdcr_table:
+-	mfdcr  r3,0; blr
+-__mtdcr_table:
+-	mtdcr  0,r4; blr
+-
+-dcr     = 1
+-        .rept   1023
+-	mfdcr   r3,dcr; blr
+-	mtdcr   dcr,r4; blr
+-	dcr     = dcr + 1
+-	.endr
+diff --git a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c
+--- a/arch/ppc/syslib/gt64260_pic.c
++++ b/arch/ppc/syslib/gt64260_pic.c
+@@ -45,6 +45,7 @@
+ #include <asm/system.h>
+ #include <asm/irq.h>
+ #include <asm/mv64x60.h>
++#include <asm/machdep.h>
+ 
+ #define CPU_INTR_STR	"gt64260 cpu interface error"
+ #define PCI0_INTR_STR	"gt64260 pci 0 error"
+diff --git a/arch/ppc/syslib/i8259.c b/arch/ppc/syslib/i8259.c
+deleted file mode 100644
+--- a/arch/ppc/syslib/i8259.c
++++ /dev/null
+@@ -1,208 +0,0 @@
+-#include <linux/init.h>
+-#include <linux/ioport.h>
+-#include <linux/interrupt.h>
+-#include <asm/io.h>
+-#include <asm/i8259.h>
+-
+-static volatile unsigned char *pci_intack; /* RO, gives us the irq vector */
+-
+-unsigned char cached_8259[2] = { 0xff, 0xff };
+-#define cached_A1 (cached_8259[0])
+-#define cached_21 (cached_8259[1])
+-
+-static DEFINE_SPINLOCK(i8259_lock);
+-
+-int i8259_pic_irq_offset;
+-
+-/*
+- * Acknowledge the IRQ using either the PCI host bridge's interrupt
+- * acknowledge feature or poll.  How i8259_init() is called determines
+- * which is called.  It should be noted that polling is broken on some
+- * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
+- */
+-int
+-i8259_irq(struct pt_regs *regs)
+-{
+-	int irq;
+-
+-	spin_lock(&i8259_lock);
+-
+-	/* Either int-ack or poll for the IRQ */
+-	if (pci_intack)
+-		irq = *pci_intack;
+-	else {
+-		/* Perform an interrupt acknowledge cycle on controller 1. */
+-		outb(0x0C, 0x20);		/* prepare for poll */
+-		irq = inb(0x20) & 7;
+-		if (irq == 2 ) {
+-			/*
+-			 * Interrupt is cascaded so perform interrupt
+-			 * acknowledge on controller 2.
+-			 */
+-			outb(0x0C, 0xA0);	/* prepare for poll */
+-			irq = (inb(0xA0) & 7) + 8;
+-		}
+-	}
+-
+-	if (irq == 7) {
+-		/*
+-		 * This may be a spurious interrupt.
+-		 *
+-		 * Read the interrupt status register (ISR). If the most
+-		 * significant bit is not set then there is no valid
+-		 * interrupt.
+-		 */
+-		if (!pci_intack)
+-			outb(0x0B, 0x20);	/* ISR register */
+-		if(~inb(0x20) & 0x80)
+-			irq = -1;
+-	}
+-
+-	spin_unlock(&i8259_lock);
+-	return irq;
+-}
+-
+-static void i8259_mask_and_ack_irq(unsigned int irq_nr)
+-{
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&i8259_lock, flags);
+-	if ( irq_nr >= i8259_pic_irq_offset )
+-		irq_nr -= i8259_pic_irq_offset;
+-
+-	if (irq_nr > 7) {
+-		cached_A1 |= 1 << (irq_nr-8);
+-		inb(0xA1); /* DUMMY */
+-		outb(cached_A1,0xA1);
+-		outb(0x20,0xA0); /* Non-specific EOI */
+-		outb(0x20,0x20); /* Non-specific EOI to cascade */
+-	} else {
+-		cached_21 |= 1 << irq_nr;
+-		inb(0x21); /* DUMMY */
+-		outb(cached_21,0x21);
+-		outb(0x20,0x20); /* Non-specific EOI */
+-	}
+-	spin_unlock_irqrestore(&i8259_lock, flags);
+-}
+-
+-static void i8259_set_irq_mask(int irq_nr)
+-{
+-	outb(cached_A1,0xA1);
+-	outb(cached_21,0x21);
+-}
+-
+-static void i8259_mask_irq(unsigned int irq_nr)
+-{
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&i8259_lock, flags);
+-	if ( irq_nr >= i8259_pic_irq_offset )
+-		irq_nr -= i8259_pic_irq_offset;
+-	if ( irq_nr < 8 )
+-		cached_21 |= 1 << irq_nr;
+-	else
+-		cached_A1 |= 1 << (irq_nr-8);
+-	i8259_set_irq_mask(irq_nr);
+-	spin_unlock_irqrestore(&i8259_lock, flags);
+-}
+-
+-static void i8259_unmask_irq(unsigned int irq_nr)
+-{
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&i8259_lock, flags);
+-	if ( irq_nr >= i8259_pic_irq_offset )
+-		irq_nr -= i8259_pic_irq_offset;
+-	if ( irq_nr < 8 )
+-		cached_21 &= ~(1 << irq_nr);
+-	else
+-		cached_A1 &= ~(1 << (irq_nr-8));
+-	i8259_set_irq_mask(irq_nr);
+-	spin_unlock_irqrestore(&i8259_lock, flags);
+-}
+-
+-static void i8259_end_irq(unsigned int irq)
+-{
+-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+-	    && irq_desc[irq].action)
+-		i8259_unmask_irq(irq);
+-}
+-
+-struct hw_interrupt_type i8259_pic = {
+-	.typename = " i8259    ",
+-	.enable = i8259_unmask_irq,
+-	.disable = i8259_mask_irq,
+-	.ack = i8259_mask_and_ack_irq,
+-	.end = i8259_end_irq,
+-};
+-
+-static struct resource pic1_iores = {
+-	.name = "8259 (master)",
+-	.start = 0x20,
+-	.end = 0x21,
+-	.flags = IORESOURCE_BUSY,
+-};
+-
+-static struct resource pic2_iores = {
+-	.name = "8259 (slave)",
+-	.start = 0xa0,
+-	.end = 0xa1,
+-	.flags = IORESOURCE_BUSY,
+-};
+-
+-static struct resource pic_edgectrl_iores = {
+-	.name = "8259 edge control",
+-	.start = 0x4d0,
+-	.end = 0x4d1,
+-	.flags = IORESOURCE_BUSY,
+-};
+-
+-static struct irqaction i8259_irqaction = {
+-	.handler = no_action,
+-	.flags = SA_INTERRUPT,
+-	.mask = CPU_MASK_NONE,
+-	.name = "82c59 secondary cascade",
+-};
+-
+-/*
+- * i8259_init()
+- * intack_addr - PCI interrupt acknowledge (real) address which will return
+- *               the active irq from the 8259
+- */
+-void __init
+-i8259_init(long intack_addr)
+-{
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&i8259_lock, flags);
+-	/* init master interrupt controller */
+-	outb(0x11, 0x20); /* Start init sequence */
+-	outb(0x00, 0x21); /* Vector base */
+-	outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
+-	outb(0x01, 0x21); /* Select 8086 mode */
+-
+-	/* init slave interrupt controller */
+-	outb(0x11, 0xA0); /* Start init sequence */
+-	outb(0x08, 0xA1); /* Vector base */
+-	outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
+-	outb(0x01, 0xA1); /* Select 8086 mode */
+-
+-	/* always read ISR */
+-	outb(0x0B, 0x20);
+-	outb(0x0B, 0xA0);
+-
+-	/* Mask all interrupts */
+-	outb(cached_A1, 0xA1);
+-	outb(cached_21, 0x21);
+-
+-	spin_unlock_irqrestore(&i8259_lock, flags);
+-
+-	/* reserve our resources */
+-	setup_irq( i8259_pic_irq_offset + 2, &i8259_irqaction);
+-	request_resource(&ioport_resource, &pic1_iores);
+-	request_resource(&ioport_resource, &pic2_iores);
+-	request_resource(&ioport_resource, &pic_edgectrl_iores);
+-
+-	if (intack_addr != 0)
+-		pci_intack = ioremap(intack_addr, 1);
+-}
+diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
+--- a/arch/ppc/syslib/ibm440gx_common.c
++++ b/arch/ppc/syslib/ibm440gx_common.c
+@@ -236,9 +236,9 @@ void __init ibm440gx_l2c_setup(struct ib
+ 	/* Disable L2C on rev.A, rev.B and 800MHz version of rev.C,
+ 	   enable it on all other revisions
+ 	 */
+-	if (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. A") == 0 ||
+-			strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. B") == 0
+-			|| (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. C")
++	if (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. A") == 0 ||
++			strcmp(cur_cpu_spec->cpu_name, "440GX Rev. B") == 0
++			|| (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. C")
+ 				== 0 && p->cpu > 667000000))
+ 		ibm440gx_l2c_disable();
+ 	else
+diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c
+--- a/arch/ppc/syslib/ibm44x_common.c
++++ b/arch/ppc/syslib/ibm44x_common.c
+@@ -27,9 +27,14 @@
+ #include <asm/time.h>
+ #include <asm/ppc4xx_pic.h>
+ #include <asm/param.h>
++#include <asm/bootinfo.h>
++#include <asm/ppcboot.h>
+ 
+ #include <syslib/gen550.h>
+ 
++/* Global Variables */
++bd_t __res;
++
+ phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
+ {
+ 	phys_addr_t page_4gb = 0;
+@@ -150,8 +155,36 @@ static unsigned long __init ibm44x_find_
+ 	return mem_size;
+ }
+ 
+-void __init ibm44x_platform_init(void)
++void __init ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++				 unsigned long r6, unsigned long r7)
+ {
++	parse_bootinfo(find_bootinfo());
++
++	/*
++	 * If we were passed in a board information, copy it into the
++	 * residual data area.
++	 */
++	if (r3)
++		__res = *(bd_t *)(r3 + KERNELBASE);
++
++#if defined(CONFIG_BLK_DEV_INITRD)
++	/*
++	 * If the init RAM disk has been configured in, and there's a valid
++	 * starting address for it, set it up.
++	 */
++	if (r4) {
++		initrd_start = r4 + KERNELBASE;
++		initrd_end = r5 + KERNELBASE;
++	}
++#endif  /* CONFIG_BLK_DEV_INITRD */
++
++	/* Copy the kernel command line arguments to a safe place. */
++
++	if (r6) {
++		*(char *) (r7 + KERNELBASE) = 0;
++		strcpy(cmd_line, (char *) (r6 + KERNELBASE));
++	}
++
+ 	ppc_md.init_IRQ = ppc4xx_pic_init;
+ 	ppc_md.find_end_of_memory = ibm44x_find_end_of_memory;
+ 	ppc_md.restart = ibm44x_restart;
+@@ -178,7 +211,7 @@ void __init ibm44x_platform_init(void)
+ #endif
+ }
+ 
+-/* Called from MachineCheckException */
++/* Called from machine_check_exception */
+ void platform_machine_check(struct pt_regs *regs)
+ {
+     	printk("PLB0: BEAR=0x%08x%08x ACR=  0x%08x BESR= 0x%08x\n",
+diff --git a/arch/ppc/syslib/ibm44x_common.h b/arch/ppc/syslib/ibm44x_common.h
+--- a/arch/ppc/syslib/ibm44x_common.h
++++ b/arch/ppc/syslib/ibm44x_common.h
+@@ -36,7 +36,8 @@ struct ibm44x_clocks {
+ };
+ 
+ /* common 44x platform init */
+-void ibm44x_platform_init(void) __init;
++void ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++			  unsigned long r6, unsigned long r7) __init;
+ 
+ /* initialize decrementer and tick-related variables */
+ void ibm44x_calibrate_decr(unsigned int freq) __init;
+diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c
+deleted file mode 100644
+--- a/arch/ppc/syslib/indirect_pci.c
++++ /dev/null
+@@ -1,134 +0,0 @@
+-/*
+- * 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.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/pci.h>
+-#include <linux/delay.h>
+-#include <linux/string.h>
+-#include <linux/init.h>
+-
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/machdep.h>
+-
+-#ifdef CONFIG_PPC_INDIRECT_PCI_BE
+-#define PCI_CFG_OUT out_be32
+-#else
+-#define PCI_CFG_OUT out_le32
+-#endif
+-
+-static int
+-indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+-		     int len, u32 *val)
+-{
+-	struct pci_controller *hose = bus->sysdata;
+-	volatile void __iomem *cfg_data;
+-	u8 cfg_type = 0;
+-
+-	if (ppc_md.pci_exclude_device)
+-		if (ppc_md.pci_exclude_device(bus->number, devfn))
+-			return PCIBIOS_DEVICE_NOT_FOUND;
+-	
+-	if (hose->set_cfg_type)
+-		if (bus->number != hose->first_busno)
+-			cfg_type = 1;
+-
+-	PCI_CFG_OUT(hose->cfg_addr, 					 
+-		 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
+-		  | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
+-
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	cfg_data = hose->cfg_data + (offset & 3);
+-	switch (len) {
+-	case 1:
+-		*val = in_8(cfg_data);
+-		break;
+-	case 2:
+-		*val = in_le16(cfg_data);
+-		break;
+-	default:
+-		*val = in_le32(cfg_data);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static int
+-indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+-		      int len, u32 val)
+-{
+-	struct pci_controller *hose = bus->sysdata;
+-	volatile void __iomem *cfg_data;
+-	u8 cfg_type = 0;
+-
+-	if (ppc_md.pci_exclude_device)
+-		if (ppc_md.pci_exclude_device(bus->number, devfn))
+-			return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	if (hose->set_cfg_type)
+-		if (bus->number != hose->first_busno)
+-			cfg_type = 1;
+-
+-	PCI_CFG_OUT(hose->cfg_addr, 					 
+-		 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
+-		  | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
+-
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	cfg_data = hose->cfg_data + (offset & 3);
+-	switch (len) {
+-	case 1:
+-		out_8(cfg_data, val);
+-		break;
+-	case 2:
+-		out_le16(cfg_data, val);
+-		break;
+-	default:
+-		out_le32(cfg_data, val);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static struct pci_ops indirect_pci_ops =
+-{
+-	indirect_read_config,
+-	indirect_write_config
+-};
+-
+-void __init
+-setup_indirect_pci_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_pci_ops;
+-}
+-
+-void __init
+-setup_indirect_pci(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_pci_nomap(hose, addr, data);
+-}
+diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
+--- a/arch/ppc/syslib/m8260_setup.c
++++ b/arch/ppc/syslib/m8260_setup.c
+@@ -62,6 +62,10 @@ m8260_setup_arch(void)
+ 	if (initrd_start)
+ 		ROOT_DEV = Root_RAM0;
+ #endif
++
++	identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME,
++				in_be32(CPM_MAP_ADDR + CPM_IMMR_OFFSET));
++
+ 	m82xx_board_setup();
+ }
+ 
+diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
+--- a/arch/ppc/syslib/m82xx_pci.c
++++ b/arch/ppc/syslib/m82xx_pci.c
+@@ -302,11 +302,11 @@ pq2ads_setup_pci(struct pci_controller *
+ 
+ void __init pq2_find_bridges(void)
+ {
+-	extern int pci_assign_all_busses;
++	extern int pci_assign_all_buses;
+ 	struct pci_controller * hose;
+ 	int host_bridge;
+ 
+-	pci_assign_all_busses = 1;
++	pci_assign_all_buses = 1;
+ 
+ 	hose = pcibios_alloc_controller();
+ 
+diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
+--- a/arch/ppc/syslib/m8xx_setup.c
++++ b/arch/ppc/syslib/m8xx_setup.c
+@@ -144,12 +144,12 @@ void __init m8xx_calibrate_decr(void)
+ 	int freq, fp, divisor;
+ 
+ 	/* Unlock the SCCR. */
+-	((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = ~KAPWR_KEY;
+-	((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = KAPWR_KEY;
++	out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, ~KAPWR_KEY);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, KAPWR_KEY);
+ 
+ 	/* Force all 8xx processors to use divide by 16 processor clock. */
+-	((volatile immap_t *)IMAP_ADDR)->im_clkrst.car_sccr |= 0x02000000;
+-
++	out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr,
++		in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr)|0x02000000);
+ 	/* Processor frequency is MHz.
+ 	 * The value 'fp' is the number of decrementer ticks per second.
+ 	 */
+@@ -175,28 +175,24 @@ void __init m8xx_calibrate_decr(void)
+ 	 * we guarantee the registers are locked, then we unlock them
+ 	 * for our use.
+ 	 */
+-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = ~KAPWR_KEY;
+-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = ~KAPWR_KEY;
+-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    = ~KAPWR_KEY;
+-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk =  KAPWR_KEY;
+-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck =  KAPWR_KEY;
+-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    =  KAPWR_KEY;
++	out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, ~KAPWR_KEY);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, ~KAPWR_KEY);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, ~KAPWR_KEY);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, KAPWR_KEY);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY);
+ 
+ 	/* Disable the RTC one second and alarm interrupts. */
+-	((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &=
+-						~(RTCSC_SIE | RTCSC_ALE);
++	out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE));
+ 	/* Enable the RTC */
+-	((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc |=
+-						(RTCSC_RTF | RTCSC_RTE);
++	out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE));
+ 
+ 	/* Enabling the decrementer also enables the timebase interrupts
+ 	 * (or from the other point of view, to get decrementer interrupts
+ 	 * we have to enable the timebase).  The decrementer interrupt
+ 	 * is wired into the vector table, nothing to do here for that.
+ 	 */
+-	((volatile immap_t *)IMAP_ADDR)->im_sit.sit_tbscr =
+-				((mk_int_int_mask(DEC_INTERRUPT) << 8) |
+-					 (TBSCR_TBF | TBSCR_TBE));
++	out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_tbscr, (mk_int_int_mask(DEC_INTERRUPT) << 8) | (TBSCR_TBF | TBSCR_TBE));
+ 
+ 	if (setup_irq(DEC_INTERRUPT, &tbint_irqaction))
+ 		panic("Could not allocate timer IRQ!");
+@@ -216,9 +212,9 @@ void __init m8xx_calibrate_decr(void)
+ static int
+ m8xx_set_rtc_time(unsigned long time)
+ {
+-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
+-	((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time;
+-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
++	out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, KAPWR_KEY);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc, time);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, ~KAPWR_KEY);
+ 	return(0);
+ }
+ 
+@@ -226,7 +222,7 @@ static unsigned long
+ m8xx_get_rtc_time(void)
+ {
+ 	/* Get time from the RTC. */
+-	return((unsigned long)(((immap_t *)IMAP_ADDR)->im_sit.sit_rtc));
++	return (unsigned long) in_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc);
+ }
+ 
+ static void
+@@ -235,13 +231,13 @@ m8xx_restart(char *cmd)
+ 	__volatile__ unsigned char dummy;
+ 
+ 	local_irq_disable();
+-	((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr |= 0x00000080;
++	out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr, in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr) | 0x00000080);
+ 
+ 	/* Clear the ME bit in MSR to cause checkstop on machine check
+ 	*/
+ 	mtmsr(mfmsr() & ~0x1000);
+ 
+-	dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
++	dummy = in_8(&((immap_t *)IMAP_ADDR)->im_clkrst.res[0]);
+ 	printk("Restart failed\n");
+ 	while(1);
+ }
+@@ -306,8 +302,7 @@ m8xx_init_IRQ(void)
+ 	i8259_init(0);
+ 
+ 	/* The i8259 cascade interrupt must be level sensitive. */
+-	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel &=
+-		~(0x80000000 >> ISA_BRIDGE_INT);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel, in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel & ~(0x80000000 >> ISA_BRIDGE_INT)));
+ 
+ 	if (setup_irq(ISA_BRIDGE_INT, &mbx_i8259_irqaction))
+ 		enable_irq(ISA_BRIDGE_INT);
+@@ -404,9 +399,10 @@ platform_init(unsigned long r3, unsigned
+ 		strcpy(cmd_line, (char *)(r6+KERNELBASE));
+ 	}
+ 
++	identify_ppc_sys_by_name(BOARD_CHIP_NAME);
++
+ 	ppc_md.setup_arch		= m8xx_setup_arch;
+ 	ppc_md.show_percpuinfo		= m8xx_show_percpuinfo;
+-	ppc_md.irq_canonicalize	= NULL;
+ 	ppc_md.init_IRQ			= m8xx_init_IRQ;
+ 	ppc_md.get_irq			= m8xx_get_irq;
+ 	ppc_md.init			= NULL;
+diff --git a/arch/ppc/syslib/m8xx_wdt.c b/arch/ppc/syslib/m8xx_wdt.c
+--- a/arch/ppc/syslib/m8xx_wdt.c
++++ b/arch/ppc/syslib/m8xx_wdt.c
+@@ -29,8 +29,8 @@ void m8xx_wdt_reset(void)
+ {
+ 	volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
+ 
+-	imap->im_siu_conf.sc_swsr = 0x556c;	/* write magic1 */
+-	imap->im_siu_conf.sc_swsr = 0xaa39;	/* write magic2 */
++	out_be16(imap->im_siu_conf.sc_swsr, 0x556c);	/* write magic1 */
++	out_be16(imap->im_siu_conf.sc_swsr, 0xaa39);	/* write magic2 */
+ }
+ 
+ static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs)
+@@ -39,7 +39,7 @@ static irqreturn_t m8xx_wdt_interrupt(in
+ 
+ 	m8xx_wdt_reset();
+ 
+-	imap->im_sit.sit_piscr |= PISCR_PS;	/* clear irq */
++	out_be16(imap->im_sit.sit_piscr, in_be16(imap->im_sit.sit_piscr | PISCR_PS));	/* clear irq */
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -51,7 +51,7 @@ void __init m8xx_wdt_handler_install(bd_
+ 	u32 sypcr;
+ 	u32 pitrtclk;
+ 
+-	sypcr = imap->im_siu_conf.sc_sypcr;
++	sypcr = in_be32(imap->im_siu_conf.sc_sypcr);
+ 
+ 	if (!(sypcr & 0x04)) {
+ 		printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
+@@ -87,9 +87,9 @@ void __init m8xx_wdt_handler_install(bd_
+ 	else
+ 		pitc = pitrtclk * wdt_timeout / binfo->bi_intfreq / 2;
+ 
+-	imap->im_sit.sit_pitc = pitc << 16;
+-	imap->im_sit.sit_piscr =
+-	    (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE;
++	out_be32(imap->im_sit.sit_pitc, pitc << 16);
++
++	out_be16(imap->im_sit.sit_piscr, (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE);
+ 
+ 	if (setup_irq(PIT_INTERRUPT, &m8xx_wdt_irqaction))
+ 		panic("m8xx_wdt: error setting up the watchdog irq!");
+diff --git a/arch/ppc/syslib/mpc52xx_devices.c b/arch/ppc/syslib/mpc52xx_devices.c
+--- a/arch/ppc/syslib/mpc52xx_devices.c
++++ b/arch/ppc/syslib/mpc52xx_devices.c
+@@ -15,6 +15,7 @@
+ 
+ #include <linux/fsl_devices.h>
+ #include <linux/resource.h>
++#include <linux/platform_device.h>
+ #include <asm/mpc52xx.h>
+ #include <asm/ppc_sys.h>
+ 
+diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
+--- a/arch/ppc/syslib/mpc52xx_pci.c
++++ b/arch/ppc/syslib/mpc52xx_pci.c
+@@ -21,6 +21,7 @@
+ #include "mpc52xx_pci.h"
+ 
+ #include <asm/delay.h>
++#include <asm/machdep.h>
+ 
+ 
+ static int
+@@ -181,7 +182,7 @@ mpc52xx_find_bridges(void)
+ 	struct mpc52xx_pci __iomem *pci_regs;
+ 	struct pci_controller *hose;
+ 
+-	pci_assign_all_busses = 1;
++	pci_assign_all_buses = 1;
+ 
+ 	pci_regs = ioremap(MPC52xx_PA(MPC52xx_PCI_OFFSET), MPC52xx_PCI_SIZE);
+ 	if (!pci_regs)
+diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
+--- a/arch/ppc/syslib/mpc83xx_devices.c
++++ b/arch/ppc/syslib/mpc83xx_devices.c
+@@ -21,6 +21,7 @@
+ #include <asm/mpc83xx.h>
+ #include <asm/irq.h>
+ #include <asm/ppc_sys.h>
++#include <asm/machdep.h>
+ 
+ /* We use offsets for IORESOURCE_MEM since we do not know at compile time
+  * what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup
+diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
+--- a/arch/ppc/syslib/mpc85xx_devices.c
++++ b/arch/ppc/syslib/mpc85xx_devices.c
+@@ -25,19 +25,20 @@
+ /* We use offsets for IORESOURCE_MEM since we do not know at compile time
+  * what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup
+  */
++struct gianfar_mdio_data mpc85xx_mdio_pdata = {
++	.paddr = MPC85xx_MIIM_OFFSET,
++};
+ 
+ static struct gianfar_platform_data mpc85xx_tsec1_pdata = {
+ 	.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
+ 	    FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
+ 	    FSL_GIANFAR_DEV_HAS_MULTI_INTR,
+-	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+ };
+ 
+ static struct gianfar_platform_data mpc85xx_tsec2_pdata = {
+ 	.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
+ 	    FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
+ 	    FSL_GIANFAR_DEV_HAS_MULTI_INTR,
+-	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+ };
+ 
+ static struct gianfar_platform_data mpc85xx_etsec1_pdata = {
+@@ -46,7 +47,6 @@ static struct gianfar_platform_data mpc8
+ 	    FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+ 	    FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
+ 	    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
+-	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+ };
+ 
+ static struct gianfar_platform_data mpc85xx_etsec2_pdata = {
+@@ -55,7 +55,6 @@ static struct gianfar_platform_data mpc8
+ 	    FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+ 	    FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
+ 	    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
+-	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+ };
+ 
+ static struct gianfar_platform_data mpc85xx_etsec3_pdata = {
+@@ -64,7 +63,6 @@ static struct gianfar_platform_data mpc8
+ 	    FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+ 	    FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
+ 	    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
+-	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+ };
+ 
+ static struct gianfar_platform_data mpc85xx_etsec4_pdata = {
+@@ -73,11 +71,10 @@ static struct gianfar_platform_data mpc8
+ 	    FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+ 	    FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
+ 	    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
+-	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+ };
+ 
+ static struct gianfar_platform_data mpc85xx_fec_pdata = {
+-	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
++	.device_flags = 0,
+ };
+ 
+ static struct fsl_i2c_platform_data mpc85xx_fsl_i2c_pdata = {
+@@ -719,6 +716,12 @@ struct platform_device ppc_sys_platform_
+ 			},
+ 		},
+ 	},
++	[MPC85xx_MDIO] = {
++		.name = "fsl-gianfar_mdio",
++		.id = 0,
++		.dev.platform_data = &mpc85xx_mdio_pdata,
++		.num_resources = 0,
++	},
+ };
+ 
+ static int __init mach_mpc85xx_fixup(struct platform_device *pdev)
+diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c
+--- a/arch/ppc/syslib/mpc85xx_sys.c
++++ b/arch/ppc/syslib/mpc85xx_sys.c
+@@ -24,19 +24,19 @@ struct ppc_sys_spec ppc_sys_specs[] = {
+ 		.ppc_sys_name	= "8540",
+ 		.mask 		= 0xFFFF0000,
+ 		.value 		= 0x80300000,
+-		.num_devices	= 10,
++		.num_devices	= 11,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_FEC, MPC85xx_IIC1,
+ 			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+-			MPC85xx_PERFMON, MPC85xx_DUART,
++			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8560",
+ 		.mask 		= 0xFFFF0000,
+ 		.value 		= 0x80700000,
+-		.num_devices	= 19,
++		.num_devices	= 20,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+@@ -45,14 +45,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
+ 			MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_SCC1,
+ 			MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3, MPC85xx_CPM_SCC4,
+ 			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3,
+-			MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2,
++			MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2, MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8541",
+ 		.mask 		= 0xFFFF0000,
+ 		.value 		= 0x80720000,
+-		.num_devices	= 13,
++		.num_devices	= 14,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+@@ -60,13 +60,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
+ 			MPC85xx_PERFMON, MPC85xx_DUART,
+ 			MPC85xx_CPM_SPI, MPC85xx_CPM_I2C,
+ 			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8541E",
+ 		.mask 		= 0xFFFF0000,
+ 		.value 		= 0x807A0000,
+-		.num_devices	= 14,
++		.num_devices	= 15,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+@@ -74,13 +75,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
+ 			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+ 			MPC85xx_CPM_SPI, MPC85xx_CPM_I2C,
+ 			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8555",
+ 		.mask 		= 0xFFFF0000,
+ 		.value 		= 0x80710000,
+-		.num_devices	= 19,
++		.num_devices	= 20,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+@@ -91,13 +93,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
+ 			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
+ 			MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
+ 			MPC85xx_CPM_USB,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8555E",
+ 		.mask 		= 0xFFFF0000,
+ 		.value 		= 0x80790000,
+-		.num_devices	= 20,
++		.num_devices	= 21,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+@@ -108,6 +111,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
+ 			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
+ 			MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
+ 			MPC85xx_CPM_USB,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	/* SVRs on 8548 rev1.0 matches for 8548/8547/8545 */
+@@ -115,104 +119,112 @@ struct ppc_sys_spec ppc_sys_specs[] = {
+ 		.ppc_sys_name	= "8548E",
+ 		.mask 		= 0xFFFF00F0,
+ 		.value 		= 0x80390010,
+-		.num_devices	= 13,
++		.num_devices	= 14,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
+ 			MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
+ 			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+ 			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8548",
+ 		.mask 		= 0xFFFF00F0,
+ 		.value 		= 0x80310010,
+-		.num_devices	= 12,
++		.num_devices	= 13,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
+ 			MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
+ 			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+ 			MPC85xx_PERFMON, MPC85xx_DUART,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8547E",
+ 		.mask 		= 0xFFFF00F0,
+ 		.value 		= 0x80390010,
+-		.num_devices	= 13,
++		.num_devices	= 14,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
+ 			MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
+ 			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+ 			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8547",
+ 		.mask 		= 0xFFFF00F0,
+ 		.value 		= 0x80310010,
+-		.num_devices	= 12,
++		.num_devices	= 13,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
+ 			MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
+ 			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+ 			MPC85xx_PERFMON, MPC85xx_DUART,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8545E",
+ 		.mask 		= 0xFFFF00F0,
+ 		.value 		= 0x80390010,
+-		.num_devices	= 11,
++		.num_devices	= 12,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_eTSEC1, MPC85xx_eTSEC2,
+ 			MPC85xx_IIC1, MPC85xx_IIC2,
+ 			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+ 			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8545",
+ 		.mask 		= 0xFFFF00F0,
+ 		.value 		= 0x80310010,
+-		.num_devices	= 10,
++		.num_devices	= 11,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_eTSEC1, MPC85xx_eTSEC2,
+ 			MPC85xx_IIC1, MPC85xx_IIC2,
+ 			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+ 			MPC85xx_PERFMON, MPC85xx_DUART,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8543E",
+ 		.mask 		= 0xFFFF00F0,
+ 		.value 		= 0x803A0010,
+-		.num_devices	= 11,
++		.num_devices	= 12,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_eTSEC1, MPC85xx_eTSEC2,
+ 			MPC85xx_IIC1, MPC85xx_IIC2,
+ 			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+ 			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{
+ 		.ppc_sys_name	= "8543",
+ 		.mask 		= 0xFFFF00F0,
+ 		.value 		= 0x80320010,
+-		.num_devices	= 10,
++		.num_devices	= 11,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC85xx_eTSEC1, MPC85xx_eTSEC2,
+ 			MPC85xx_IIC1, MPC85xx_IIC2,
+ 			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+ 			MPC85xx_PERFMON, MPC85xx_DUART,
++			MPC85xx_MDIO,
+ 		},
+ 	},
+ 	{	/* default match */
+diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c
+--- a/arch/ppc/syslib/mpc8xx_sys.c
++++ b/arch/ppc/syslib/mpc8xx_sys.c
+@@ -24,7 +24,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
+ 		.ppc_sys_name	= "MPC86X",
+ 		.mask 		= 0xFFFFFFFF,
+ 		.value 		= 0x00000000,
+-		.num_devices	= 2,
++		.num_devices	= 7,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC8xx_CPM_FEC1,
+@@ -40,7 +40,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
+ 		.ppc_sys_name	= "MPC885",
+ 		.mask 		= 0xFFFFFFFF,
+ 		.value 		= 0x00000000,
+-		.num_devices	= 3,
++		.num_devices	= 8,
+ 		.device_list	= (enum ppc_sys_devices[])
+ 		{
+ 			MPC8xx_CPM_FEC1,
+diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c
+--- a/arch/ppc/syslib/mv64360_pic.c
++++ b/arch/ppc/syslib/mv64360_pic.c
+@@ -48,6 +48,7 @@
+ #include <asm/system.h>
+ #include <asm/irq.h>
+ #include <asm/mv64x60.h>
++#include <asm/machdep.h>
+ 
+ #ifdef CONFIG_IRQ_ALL_CPUS
+ #error "The mv64360 does not support distribution of IRQs on all CPUs"
+diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
+--- a/arch/ppc/syslib/mv64x60.c
++++ b/arch/ppc/syslib/mv64x60.c
+@@ -19,6 +19,7 @@
+ #include <linux/string.h>
+ #include <linux/spinlock.h>
+ #include <linux/mv643xx.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/byteorder.h>
+ #include <asm/io.h>
+@@ -1304,7 +1305,7 @@ mv64x60_config_pci_params(struct pci_con
+ 	early_write_config_word(hose, 0, devfn, PCI_COMMAND, u16_val);
+ 
+ 	/* Set latency timer, cache line size, clear BIST */
+-	u16_val = (pi->latency_timer << 8) | (L1_CACHE_LINE_SIZE >> 2);
++	u16_val = (pi->latency_timer << 8) | (L1_CACHE_BYTES >> 2);
+ 	early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val);
+ 
+ 	mv64x60_pci_exclude_bridge = save_exclude;
+diff --git a/arch/ppc/syslib/mv64x60_dbg.c b/arch/ppc/syslib/mv64x60_dbg.c
+--- a/arch/ppc/syslib/mv64x60_dbg.c
++++ b/arch/ppc/syslib/mv64x60_dbg.c
+@@ -24,6 +24,7 @@
+ #include <linux/irq.h>
+ #include <asm/delay.h>
+ #include <asm/mv64x60.h>
++#include <asm/machdep.h>
+ 
+ 
+ #if defined(CONFIG_SERIAL_TEXT_DEBUG)
+diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c
+deleted file mode 100644
+--- a/arch/ppc/syslib/of_device.c
++++ /dev/null
+@@ -1,276 +0,0 @@
+-#include <linux/config.h>
+-#include <linux/string.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/mod_devicetable.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 &= 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;
+-}
+-
+-struct bus_type of_platform_bus_type = {
+-       .name	= "of_platform",
+-       .match	= of_platform_bus_match,
+-       .suspend	= of_device_suspend,
+-       .resume	= of_device_resume,
+-};
+-
+-static int __init of_bus_driver_init(void)
+-{
+-	return bus_register(&of_platform_bus_type);
+-}
+-
+-postcore_initcall(of_bus_driver_init);
+-
+-int of_register_driver(struct of_platform_driver *drv)
+-{
+-	int count = 0;
+-
+-	/* initialize common driver fields */
+-	drv->driver.name = drv->name;
+-	drv->driver.bus = &of_platform_bus_type;
+-	drv->driver.probe = of_device_probe;
+-	drv->driver.remove = of_device_remove;
+-
+-	/* register with core */
+-	count = driver_register(&drv->driver);
+-	return count ? count : 1;
+-}
+-
+-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);
+-	of_node_put(ofdev->node);
+-	kfree(ofdev);
+-}
+-
+-int of_device_register(struct of_device *ofdev)
+-{
+-	int rc;
+-	struct of_device **odprop;
+-
+-	BUG_ON(ofdev->node == NULL);
+-
+-	odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
+-	if (!odprop) {
+-		struct property *new_prop;
+-	
+-		new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *),
+-			GFP_KERNEL);
+-		if (new_prop == NULL)
+-			return -ENOMEM;
+-		new_prop->name = "linux,device";
+-		new_prop->length = sizeof(sizeof(struct of_device *));
+-		new_prop->value = (unsigned char *)&new_prop[1];
+-		odprop = (struct of_device **)new_prop->value;
+-		*odprop = NULL;
+-		prom_add_property(ofdev->node, new_prop);
+-	}
+-	*odprop = ofdev;
+-
+-	rc = device_register(&ofdev->dev);
+-	if (rc)
+-		return rc;
+-
+-	device_create_file(&ofdev->dev, &dev_attr_devspec);
+-
+-	return 0;
+-}
+-
+-void of_device_unregister(struct of_device *ofdev)
+-{
+-	struct of_device **odprop;
+-
+-	device_remove_file(&ofdev->dev, &dev_attr_devspec);
+-
+-	odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
+-	if (odprop)
+-		*odprop = NULL;
+-
+-	device_unregister(&ofdev->dev);
+-}
+-
+-struct of_device* of_platform_device_create(struct device_node *np,
+-					    const char *bus_id,
+-					    struct device *parent)
+-{
+-	struct of_device *dev;
+-	u32 *reg;
+-
+-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+-	if (!dev)
+-		return NULL;
+-	memset(dev, 0, sizeof(*dev));
+-
+-	dev->node = of_node_get(np);
+-	dev->dma_mask = 0xffffffffUL;
+-	dev->dev.dma_mask = &dev->dma_mask;
+-	dev->dev.parent = parent;
+-	dev->dev.bus = &of_platform_bus_type;
+-	dev->dev.release = of_release_dev;
+-
+-	reg = (u32 *)get_property(np, "reg", NULL);
+-	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_platform_bus_type);
+-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/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
+--- a/arch/ppc/syslib/open_pic.c
++++ b/arch/ppc/syslib/open_pic.c
+@@ -23,6 +23,7 @@
+ #include <asm/sections.h>
+ #include <asm/open_pic.h>
+ #include <asm/i8259.h>
++#include <asm/machdep.h>
+ 
+ #include "open_pic_defs.h"
+ 
+@@ -889,7 +890,7 @@ openpic_get_irq(struct pt_regs *regs)
+ 
+ #ifdef CONFIG_SMP
+ void
+-smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
++smp_openpic_message_pass(int target, int msg)
+ {
+ 	cpumask_t mask = CPU_MASK_ALL;
+ 	/* make sure we're sending something that translates to an IPI */
+diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
+--- a/arch/ppc/syslib/open_pic2.c
++++ b/arch/ppc/syslib/open_pic2.c
+@@ -27,6 +27,7 @@
+ #include <asm/sections.h>
+ #include <asm/open_pic.h>
+ #include <asm/i8259.h>
++#include <asm/machdep.h>
+ 
+ #include "open_pic_defs.h"
+ 
+diff --git a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c
+--- a/arch/ppc/syslib/ppc403_pic.c
++++ b/arch/ppc/syslib/ppc403_pic.c
+@@ -26,6 +26,7 @@
+ #include <asm/system.h>
+ #include <asm/irq.h>
+ #include <asm/ppc4xx_pic.h>
++#include <asm/machdep.h>
+ 
+ /* Function Prototypes */
+ 
+diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
+--- a/arch/ppc/syslib/ppc4xx_pic.c
++++ b/arch/ppc/syslib/ppc4xx_pic.c
+@@ -25,6 +25,7 @@
+ #include <asm/system.h>
+ #include <asm/irq.h>
+ #include <asm/ppc4xx_pic.h>
++#include <asm/machdep.h>
+ 
+ /* See comment in include/arch-ppc/ppc4xx_pic.h
+  * for more info about these two variables
+diff --git a/arch/ppc/syslib/ppc4xx_setup.c b/arch/ppc/syslib/ppc4xx_setup.c
+--- a/arch/ppc/syslib/ppc4xx_setup.c
++++ b/arch/ppc/syslib/ppc4xx_setup.c
+@@ -278,7 +278,7 @@ ppc4xx_init(unsigned long r3, unsigned l
+ #endif /* defined(CONFIG_PCI) && defined(CONFIG_IDE) */
+ }
+ 
+-/* Called from MachineCheckException */
++/* Called from machine_check_exception */
+ void platform_machine_check(struct pt_regs *regs)
+ {
+ #if defined(DCRN_PLB0_BEAR)
+diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
+--- a/arch/ppc/syslib/ppc83xx_setup.c
++++ b/arch/ppc/syslib/ppc83xx_setup.c
+@@ -40,6 +40,7 @@
+ #include <asm/ppc_sys.h>
+ #include <asm/kgdb.h>
+ #include <asm/delay.h>
++#include <asm/machdep.h>
+ 
+ #include <syslib/ppc83xx_setup.h>
+ #if defined(CONFIG_PCI)
+diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
+--- a/arch/ppc/syslib/ppc85xx_setup.c
++++ b/arch/ppc/syslib/ppc85xx_setup.c
+@@ -29,6 +29,7 @@
+ #include <asm/mmu.h>
+ #include <asm/ppc_sys.h>
+ #include <asm/kgdb.h>
++#include <asm/machdep.h>
+ 
+ #include <syslib/ppc85xx_setup.h>
+ 
+diff --git a/arch/ppc/syslib/ppc8xx_pic.c b/arch/ppc/syslib/ppc8xx_pic.c
+--- a/arch/ppc/syslib/ppc8xx_pic.c
++++ b/arch/ppc/syslib/ppc8xx_pic.c
+@@ -6,6 +6,7 @@
+ #include <linux/signal.h>
+ #include <linux/interrupt.h>
+ #include <asm/irq.h>
++#include <asm/io.h>
+ #include <asm/8xx_immap.h>
+ #include <asm/mpc8xx.h>
+ #include "ppc8xx_pic.h"
+@@ -29,8 +30,7 @@ static void m8xx_mask_irq(unsigned int i
+ 	word = irq_nr >> 5;
+ 
+ 	ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
+-	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
+-						ppc_cached_irq_mask[word];
++	out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
+ }
+ 
+ static void m8xx_unmask_irq(unsigned int irq_nr)
+@@ -41,8 +41,7 @@ static void m8xx_unmask_irq(unsigned int
+ 	word = irq_nr >> 5;
+ 
+ 	ppc_cached_irq_mask[word] |= (1 << (31-bit));
+-	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
+-						ppc_cached_irq_mask[word];
++	out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
+ }
+ 
+ static void m8xx_end_irq(unsigned int irq_nr)
+@@ -55,8 +54,7 @@ static void m8xx_end_irq(unsigned int ir
+ 		word = irq_nr >> 5;
+ 
+ 		ppc_cached_irq_mask[word] |= (1 << (31-bit));
+-		((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
+-			ppc_cached_irq_mask[word];
++		out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
+ 	}
+ }
+ 
+@@ -69,9 +67,8 @@ static void m8xx_mask_and_ack(unsigned i
+ 	word = irq_nr >> 5;
+ 
+ 	ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
+-	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
+-						ppc_cached_irq_mask[word];
+-	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 1 << (31-bit);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
++	out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend, 1 << (31-bit));
+ }
+ 
+ struct hw_interrupt_type ppc8xx_pic = {
+@@ -93,7 +90,7 @@ m8xx_get_irq(struct pt_regs *regs)
+ 	/* For MPC8xx, read the SIVEC register and shift the bits down
+ 	 * to get the irq number.
+ 	 */
+-	irq = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26;
++	irq = in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec) >> 26;
+ 
+ 	/*
+ 	 * When we read the sivec without an interrupt to process, we will
+diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
+--- a/arch/ppc/syslib/ppc_sys.c
++++ b/arch/ppc/syslib/ppc_sys.c
+@@ -69,6 +69,9 @@ static int __init find_chip_by_name_and_
+ 			matched[j++] = i;
+ 		i++;
+ 	}
++
++	ret = i;
++
+ 	if (j != 0) {
+ 		for (i = 0; i < j; i++) {
+ 			if ((ppc_sys_specs[matched[i]].mask & id) ==
+diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c
+--- a/arch/ppc/syslib/pq2_devices.c
++++ b/arch/ppc/syslib/pq2_devices.c
+@@ -13,11 +13,12 @@
+ 
+ #include <linux/init.h>
+ #include <linux/module.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/ioport.h>
+ #include <asm/cpm2.h>
+ #include <asm/irq.h>
+ #include <asm/ppc_sys.h>
++#include <asm/machdep.h>
+ 
+ struct platform_device ppc_sys_platform_devices[] = {
+ 	[MPC82xx_CPM_FCC1] = {
+diff --git a/arch/ppc/syslib/prep_nvram.c b/arch/ppc/syslib/prep_nvram.c
+--- a/arch/ppc/syslib/prep_nvram.c
++++ b/arch/ppc/syslib/prep_nvram.c
+@@ -22,14 +22,14 @@
+ static char nvramData[MAX_PREP_NVRAM];
+ static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0];
+ 
+-unsigned char __prep prep_nvram_read_val(int addr)
++unsigned char prep_nvram_read_val(int addr)
+ {
+ 	outb(addr, PREP_NVRAM_AS0);
+ 	outb(addr>>8, PREP_NVRAM_AS1);
+ 	return inb(PREP_NVRAM_DATA);
+ }
+ 
+-void __prep prep_nvram_write_val(int           addr,
++void prep_nvram_write_val(int           addr,
+ 			  unsigned char val)
+ {
+ 	outb(addr, PREP_NVRAM_AS0);
+@@ -81,8 +81,7 @@ void __init init_prep_nvram(void)
+ 	}
+ }
+ 
+-__prep
+-char __prep *prep_nvram_get_var(const char *name)
++char *prep_nvram_get_var(const char *name)
+ {
+ 	char *cp;
+ 	int  namelen;
+@@ -101,8 +100,7 @@ char __prep *prep_nvram_get_var(const ch
+ 	return NULL;
+ }
+ 
+-__prep
+-char __prep *prep_nvram_first_var(void)
++char *prep_nvram_first_var(void)
+ {
+         if (nvram->Header.GELength == 0) {
+ 		return NULL;
+@@ -112,8 +110,7 @@ char __prep *prep_nvram_first_var(void)
+ 	}
+ }
+ 
+-__prep
+-char __prep *prep_nvram_next_var(char *name)
++char *prep_nvram_next_var(char *name)
+ {
+ 	char *cp;
+ 
+diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
+--- a/arch/ppc/syslib/prom.c
++++ b/arch/ppc/syslib/prom.c
+@@ -89,7 +89,7 @@ extern char cmd_line[512];	/* XXX */
+ extern boot_infos_t *boot_infos;
+ unsigned long dev_tree_size;
+ 
+-void __openfirmware
++void
+ phys_call_rtas(int service, int nargs, int nret, ...)
+ {
+ 	va_list list;
+@@ -862,7 +862,7 @@ find_type_devices(const char *type)
+ /*
+  * Returns all nodes linked together
+  */
+-struct device_node * __openfirmware
++struct device_node *
+ find_all_nodes(void)
+ {
+ 	struct device_node *head, **prevp, *np;
+@@ -1165,7 +1165,7 @@ get_property(struct device_node *np, con
+ /*
+  * Add a property to a node
+  */
+-void __openfirmware
++void
+ prom_add_property(struct device_node* np, struct property* prop)
+ {
+ 	struct property **next = &np->properties;
+@@ -1177,7 +1177,7 @@ prom_add_property(struct device_node* np
+ }
+ 
+ /* I quickly hacked that one, check against spec ! */
+-static inline unsigned long __openfirmware
++static inline unsigned long
+ bus_space_to_resource_flags(unsigned int bus_space)
+ {
+ 	u8 space = (bus_space >> 24) & 0xf;
+@@ -1194,7 +1194,7 @@ bus_space_to_resource_flags(unsigned int
+ 	}
+ }
+ 
+-static struct resource* __openfirmware
++static struct resource*
+ find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range)
+ {
+ 	unsigned long mask;
+@@ -1224,7 +1224,7 @@ find_parent_pci_resource(struct pci_dev*
+  * or other nodes attached to the root node. Ultimately, put some
+  * link to resources in the OF node.
+  */
+-struct resource* __openfirmware
++struct resource*
+ request_OF_resource(struct device_node* node, int index, const char* name_postfix)
+ {
+ 	struct pci_dev* pcidev;
+@@ -1280,7 +1280,7 @@ fail:
+ 	return NULL;
+ }
+ 
+-int __openfirmware
++int
+ release_OF_resource(struct device_node* node, int index)
+ {
+ 	struct pci_dev* pcidev;
+@@ -1346,7 +1346,7 @@ release_OF_resource(struct device_node* 
+ }
+ 
+ #if 0
+-void __openfirmware
++void
+ print_properties(struct device_node *np)
+ {
+ 	struct property *pp;
+@@ -1400,7 +1400,7 @@ print_properties(struct device_node *np)
+ static DEFINE_SPINLOCK(rtas_lock);
+ 
+ /* this can be called after setup -- Cort */
+-int __openfirmware
++int
+ call_rtas(const char *service, int nargs, int nret,
+ 	  unsigned long *outputs, ...)
+ {
+diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c
+--- a/arch/ppc/syslib/xilinx_pic.c
++++ b/arch/ppc/syslib/xilinx_pic.c
+@@ -17,6 +17,7 @@
+ #include <asm/io.h>
+ #include <asm/xparameters.h>
+ #include <asm/ibm4xx.h>
++#include <asm/machdep.h>
+ 
+ /* No one else should require these constants, so define them locally here. */
+ #define ISR 0			/* Interrupt Status Register */
+diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
+--- a/arch/ppc/xmon/start.c
++++ b/arch/ppc/xmon/start.c
+@@ -478,8 +478,9 @@ void *xmon_stdout;
+ void *xmon_stderr;
+ 
+ void
+-xmon_init(void)
++xmon_init(int arg)
+ {
++	xmon_map_scc();
+ }
+ 
+ int
+diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
+--- a/arch/ppc/xmon/xmon.c
++++ b/arch/ppc/xmon/xmon.c
+@@ -148,9 +148,14 @@ Commands:\n\
+   r	print registers\n\
+   S	print special registers\n\
+   t	print backtrace\n\
+-  la	lookup address in system.map\n\
+-  ls	lookup symbol in system.map\n\
++  la	lookup address\n\
++  ls	lookup symbol\n\
++  C	checksum\n\
++  p	call function with arguments\n\
++  T	print time\n\
+   x	exit monitor\n\
++  zr    reboot\n\
++  zh    halt\n\
+ ";
+ 
+ static int xmon_trace[NR_CPUS];
+diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
+--- a/arch/ppc64/Kconfig
++++ b/arch/ppc64/Kconfig
+@@ -10,6 +10,9 @@ config MMU
+ 	bool
+ 	default y
+ 
++config PPC_STD_MMU
++	def_bool y
++
+ config UID16
+ 	bool
+ 
+@@ -120,6 +123,11 @@ config MPIC
+ 	bool
+ 	default y
+ 
++config PPC_I8259
++	depends on PPC_PSERIES
++	bool
++	default y
++
+ config BPA_IIC
+ 	depends on PPC_BPA
+ 	bool
+@@ -186,6 +194,12 @@ config BOOTX_TEXT
+ 	  Say Y here to see progress messages from the boot firmware in text
+ 	  mode. Requires an Open Firmware compatible video card.
+ 
++config POWER4
++	def_bool y
++
++config PPC_FPU
++	def_bool y
++
+ config POWER4_ONLY
+ 	bool "Optimize for POWER4"
+ 	default n
+@@ -234,6 +248,10 @@ config HMT
+ 	  This option enables hardware multithreading on RS64 cpus.
+ 	  pSeries systems p620 and p660 have such a cpu type.
+ 
++config NUMA
++	bool "NUMA support"
++	default y if SMP && PPC_PSERIES
++
+ config ARCH_SELECT_MEMORY_MODEL
+ 	def_bool y
+ 
+@@ -249,9 +267,6 @@ config ARCH_DISCONTIGMEM_DEFAULT
+ 	def_bool y
+ 	depends on ARCH_DISCONTIGMEM_ENABLE
+ 
+-config ARCH_FLATMEM_ENABLE
+-	def_bool y
+-
+ config ARCH_SPARSEMEM_ENABLE
+ 	def_bool y
+ 	depends on ARCH_DISCONTIGMEM_ENABLE
+@@ -274,10 +289,6 @@ config NODES_SPAN_OTHER_NODES
+ 	def_bool y
+ 	depends on NEED_MULTIPLE_NODES
+ 
+-config NUMA
+-	bool "NUMA support"
+-	default y if DISCONTIGMEM || SPARSEMEM
+-
+ config SCHED_SMT
+ 	bool "SMT (Hyperthreading) scheduler support"
+ 	depends on SMP
+@@ -307,6 +318,11 @@ config PPC_RTAS
+ 	depends on PPC_PSERIES || PPC_BPA
+ 	default y
+ 
++config RTAS_ERROR_LOGGING
++	bool
++	depends on PPC_RTAS
++	default y
++
+ config RTAS_PROC
+ 	bool "Proc interface to RTAS"
+ 	depends on PPC_RTAS
+@@ -357,7 +373,6 @@ config HOTPLUG_CPU
+ 
+ config PROC_DEVICETREE
+ 	bool "Support for Open Firmware device tree in /proc"
+-	depends on !PPC_ISERIES
+ 	help
+ 	  This option adds a device-tree directory under /proc which contains
+ 	  an image of the device tree that the kernel copies from Open
+@@ -461,7 +476,7 @@ config VIOPATH
+ 	depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
+ 	default y
+ 
+-source "arch/ppc64/oprofile/Kconfig"
++source "arch/powerpc/oprofile/Kconfig"
+ 
+ source "arch/ppc64/Kconfig.debug"
+ 
+diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
+--- a/arch/ppc64/Makefile
++++ b/arch/ppc64/Makefile
+@@ -75,17 +75,25 @@ else
+ 	CFLAGS += $(call cc-option,-mtune=power4)
+ endif
+ 
++# No AltiVec instruction when building kernel
++CFLAGS	+= $(call cc-option, -mno-altivec)
++
+ # Enable unit-at-a-time mode when possible. It shrinks the
+ # kernel considerably.
+ CFLAGS += $(call cc-option,-funit-at-a-time)
+ 
+ head-y := arch/ppc64/kernel/head.o
++head-y += arch/powerpc/kernel/fpu.o
++head-y += arch/powerpc/kernel/entry_64.o
+ 
+ libs-y				+= arch/ppc64/lib/
+-core-y				+= arch/ppc64/kernel/
+-core-y				+= arch/ppc64/mm/
+-core-$(CONFIG_XMON)		+= arch/ppc64/xmon/
+-drivers-$(CONFIG_OPROFILE)	+= arch/ppc64/oprofile/
++core-y				+= arch/ppc64/kernel/ arch/powerpc/kernel/
++core-y				+= arch/powerpc/mm/
++core-y				+= arch/powerpc/sysdev/
++core-y				+= arch/powerpc/platforms/
++core-y				+= arch/powerpc/lib/
++core-$(CONFIG_XMON)		+= arch/powerpc/xmon/
++drivers-$(CONFIG_OPROFILE)	+= arch/powerpc/oprofile/
+ 
+ boot := arch/ppc64/boot
+ 
+@@ -100,7 +108,7 @@ $(boottargets-y): vmlinux
+ bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
+ bootimage-$(CONFIG_PPC_PMAC) := vmlinux
+ bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage
+-bootimage-$(CONFIG_PPC_BPA) := zImage
++bootimage-$(CONFIG_PPC_BPA) := $(boot)/zImage
+ bootimage-$(CONFIG_PPC_ISERIES) := vmlinux
+ BOOTIMAGE := $(bootimage-y)
+ install: vmlinux
+diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
+--- a/arch/ppc64/boot/Makefile
++++ b/arch/ppc64/boot/Makefile
+@@ -22,15 +22,46 @@
+ 
+ 
+ HOSTCC		:= gcc
+-BOOTCFLAGS	:= $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include)
++BOOTCFLAGS	:= $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include) -fPIC
+ BOOTAFLAGS	:= -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
+-BOOTLFLAGS	:= -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds
++BOOTLFLAGS	:= -T $(srctree)/$(src)/zImage.lds
+ OBJCOPYFLAGS    := contents,alloc,load,readonly,data
+ 
+-src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c div64.S
++zlib       := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
++zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h
++zliblinuxheader := zlib.h zconf.h zutil.h
++
++$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
++#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
++
++src-boot := string.S prom.c main.c div64.S crt0.S
++src-boot += $(zlib)
+ src-boot := $(addprefix $(obj)/, $(src-boot))
+ obj-boot := $(addsuffix .o, $(basename $(src-boot)))
+ 
++BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(obj)
++
++quiet_cmd_copy_zlib = COPY    $@
++      cmd_copy_zlib = sed "s at __attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
++
++quiet_cmd_copy_zlibheader = COPY    $@
++      cmd_copy_zlibheader = sed "s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
++# stddef.h for NULL
++quiet_cmd_copy_zliblinuxheader = COPY    $@
++      cmd_copy_zliblinuxheader = sed "s@<linux/string.h>@\"string.h\"@;s@<linux/kernel.h>@<stddef.h>@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
++
++$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
++	$(call cmd,copy_zlib)
++
++$(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
++	$(call cmd,copy_zlibheader)
++
++$(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/%
++	$(call cmd,copy_zliblinuxheader)
++
++clean-files := $(zlib) $(zlibheader) $(zliblinuxheader)
++
++
+ quiet_cmd_bootcc = BOOTCC  $@
+       cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
+ 
+@@ -56,7 +87,7 @@ src-sec = $(foreach section, $(1), $(pat
+ gz-sec  = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
+ 
+ hostprogs-y		:= addnote addRamDisk
+-targets 		+= zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \
++targets 		+= zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
+ 			   $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
+ 			   $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
+ 			   $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
+@@ -69,9 +100,9 @@ quiet_cmd_ramdisk = RAMDISK $@
+ quiet_cmd_stripvm = STRIP   $@
+       cmd_stripvm = $(STRIP) -s $< -o $@
+ 
+-vmlinux.strip: vmlinux FORCE
++vmlinux.strip: vmlinux
+ 	$(call if_changed,stripvm)
+-$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE
++$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz
+ 	$(call if_changed,ramdisk)
+ 
+ quiet_cmd_addsection = ADDSEC  $@
+@@ -79,48 +110,38 @@ quiet_cmd_addsection = ADDSEC  $@
+ 		--add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
+ 		--set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
+ 
+-quiet_cmd_imagesize = GENSIZE $@
+-      cmd_imagesize = ls -l vmlinux.strip | \
+-		awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \
+-		> $(obj)/imagesize.c && \
+-		$(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
+-		awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c
+-
+ quiet_cmd_addnote = ADDNOTE $@
+       cmd_addnote = $(obj)/addnote $@
+ 
+-$(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE
++$(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
+ 	$(call if_changed,gzip)
+ 
+ $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
+ 	cp -f $(obj)/ramdisk.image.gz $@
+ 
+-$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE
++$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz
+ 	@touch $@
+ 
+-$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE
++$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c
+ 	$(call if_changed_dep,bootcc)
+ 	$(call cmd,addsection)
+ 
+ $(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required))
+-$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE
++$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds
+ 	$(call cmd,bootld,$(obj-boot))
+ 
+ $(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd))
+-$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE
++$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds
+ 	$(call cmd,bootld,$(obj-boot))
+ 
+-$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE
++$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote
+ 	@cp -f $< $@
+ 	$(call if_changed,addnote)
+ 
+-$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE
++$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote
+ 	@cp -f $< $@
+ 	$(call if_changed,addnote)
+ 
+-$(obj)/imagesize.c: vmlinux.strip
+-	$(call cmd,imagesize)
+-
+ install: $(CONFIGURE) $(BOOTIMAGE)
+ 	sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
+ 
+diff --git a/arch/ppc64/boot/crt0.S b/arch/ppc64/boot/crt0.S
+--- a/arch/ppc64/boot/crt0.S
++++ b/arch/ppc64/boot/crt0.S
+@@ -12,11 +12,40 @@
+ #include "ppc_asm.h"
+ 
+ 	.text
+-	.globl	_start
+-_start:
++	.globl	_zimage_start
++_zimage_start:
++	bl	reloc_offset
++
++reloc_offset:
++	mflr	r0
++	lis	r9,reloc_offset at ha
++	addi	r9,r9,reloc_offset at l
++	subf.	r0,r9,r0
++	beq	clear_caches
++
++reloc_got2:
++	lis	r9,__got2_start at ha
++	addi	r9,r9,__got2_start at l
++	lis	r8,__got2_end at ha
++	addi	r8,r8,__got2_end at l
++	subf.	r8,r9,r8
++	beq	clear_caches
++	srwi.	r8,r8,2
++	mtctr	r8
++	add	r9,r0,r9
++reloc_got2_loop:
++	lwz	r8,0(r9)
++	add	r8,r8,r0
++	stw	r8,0(r9)
++	addi	r9,r9,4
++	bdnz	reloc_got2_loop
++
++clear_caches:
+ 	lis	r9,_start at h
++	add	r9,r0,r9
+ 	lis	r8,_etext at ha
+ 	addi	r8,r8,_etext at l
++	add	r8,r0,r8
+ 1:	dcbf	r0,r9
+ 	icbi	r0,r9
+ 	addi	r9,r9,0x20
+@@ -25,24 +54,6 @@ _start:
+ 	sync
+ 	isync
+ 
+-	## Clear out the BSS as per ANSI C requirements
+-
+-	lis	r7,_end at ha
+-	addi    r7,r7,_end at l		# r7 = &_end 
+-	lis	r8,__bss_start at ha	# 
+-	addi    r8,r8,__bss_start at l	# r8 = &_bss_start
+-
+-	## Determine how large an area, in number of words, to clear
+-
+-	subf	r7,r8,r7		# r7 = &_end - &_bss_start + 1 
+-	addi	r7,r7,3			# r7 += 3 
+-	srwi.	r7,r7,2			# r7 = size in words.
+-	beq	3f			# If the size is zero, don't bother
+-	addi	r8,r8,-4		# r8 -= 4 
+-	mtctr	r7			# SPRN_CTR = number of words to clear
+-	li	r0,0			# r0 = 0
+-2:	stwu	r0,4(r8)		# Clear out a word
+-	bdnz	2b			# Keep clearing until done
+-3:
++	mr	r6,r1
+ 	b	start
+ 
+diff --git a/arch/ppc64/boot/install.sh b/arch/ppc64/boot/install.sh
+--- a/arch/ppc64/boot/install.sh
++++ b/arch/ppc64/boot/install.sh
+@@ -28,7 +28,7 @@ if [ -x /sbin/${CROSS_COMPILE}installker
+ # Default install
+ 
+ # this should work for both the pSeries zImage and the iSeries vmlinux.sm
+-image_name=`basename $5`
++image_name=`basename $2`
+ 
+ if [ -f $4/$image_name ]; then
+ 	mv $4/$image_name $4/$image_name.old
+diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
+--- a/arch/ppc64/boot/main.c
++++ b/arch/ppc64/boot/main.c
+@@ -17,7 +17,6 @@
+ #include "prom.h"
+ #include "zlib.h"
+ 
+-static void gunzip(void *, int, unsigned char *, int *);
+ extern void flush_cache(void *, unsigned long);
+ 
+ 
+@@ -26,31 +25,26 @@ extern void flush_cache(void *, unsigned
+ #define RAM_END		(512<<20) // Fixme: use OF */
+ #define	ONE_MB		0x100000
+ 
+-static char *avail_ram;
+-static char *begin_avail, *end_avail;
+-static char *avail_high;
+-static unsigned int heap_use;
+-static unsigned int heap_max;
+-
+ extern char _start[];
++extern char __bss_start[];
+ extern char _end[];
+ extern char _vmlinux_start[];
+ extern char _vmlinux_end[];
+ extern char _initrd_start[];
+ extern char _initrd_end[];
+-extern unsigned long vmlinux_filesize;
+-extern unsigned long vmlinux_memsize;
+ 
+ struct addr_range {
+ 	unsigned long addr;
+ 	unsigned long size;
+ 	unsigned long memsize;
+ };
+-static struct addr_range vmlinux = {0, 0, 0};
+-static struct addr_range vmlinuz = {0, 0, 0};
+-static struct addr_range initrd  = {0, 0, 0};
++static struct addr_range vmlinux;
++static struct addr_range vmlinuz;
++static struct addr_range initrd;
++
++static char scratch[46912];	/* scratch space for gunzip, from zlib_inflate_workspacesize() */
++static char elfheader[256];
+ 
+-static char scratch[128<<10];	/* 128kB of scratch space for gunzip */
+ 
+ typedef void (*kernel_entry_t)( unsigned long,
+                                 unsigned long,
+@@ -62,6 +56,63 @@ typedef void (*kernel_entry_t)( unsigned
+ 
+ static unsigned long claim_base;
+ 
++#define HEAD_CRC	2
++#define EXTRA_FIELD	4
++#define ORIG_NAME	8
++#define COMMENT		0x10
++#define RESERVED	0xe0
++
++static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
++{
++	z_stream s;
++	int r, i, flags;
++
++	/* skip header */
++	i = 10;
++	flags = src[3];
++	if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
++		printf("bad gzipped data\n\r");
++		exit();
++	}
++	if ((flags & EXTRA_FIELD) != 0)
++		i = 12 + src[10] + (src[11] << 8);
++	if ((flags & ORIG_NAME) != 0)
++		while (src[i++] != 0)
++			;
++	if ((flags & COMMENT) != 0)
++		while (src[i++] != 0)
++			;
++	if ((flags & HEAD_CRC) != 0)
++		i += 2;
++	if (i >= *lenp) {
++		printf("gunzip: ran out of data in header\n\r");
++		exit();
++	}
++
++	if (zlib_inflate_workspacesize() > sizeof(scratch)) {
++		printf("gunzip needs more mem\n");
++		exit();
++	}
++	memset(&s, 0, sizeof(s));
++	s.workspace = scratch;
++	r = zlib_inflateInit2(&s, -MAX_WBITS);
++	if (r != Z_OK) {
++		printf("inflateInit2 returned %d\n\r", r);
++		exit();
++	}
++	s.next_in = src + i;
++	s.avail_in = *lenp - i;
++	s.next_out = dst;
++	s.avail_out = dstlen;
++	r = zlib_inflate(&s, Z_FULL_FLUSH);
++	if (r != Z_OK && r != Z_STREAM_END) {
++		printf("inflate returned %d msg: %s\n\r", r, s.msg);
++		exit();
++	}
++	*lenp = s.next_out - (unsigned char *) dst;
++	zlib_inflateEnd(&s);
++}
++
+ static unsigned long try_claim(unsigned long size)
+ {
+ 	unsigned long addr = 0;
+@@ -80,13 +131,16 @@ static unsigned long try_claim(unsigned 
+ 	return addr;
+ }
+ 
+-void start(unsigned long a1, unsigned long a2, void *promptr)
++void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
+ {
+ 	unsigned long i;
++	int len;
+ 	kernel_entry_t kernel_entry;
+ 	Elf64_Ehdr *elf64;
+ 	Elf64_Phdr *elf64ph;
+ 
++	memset(__bss_start, 0, _end - __bss_start);
++
+ 	prom = (int (*)(void *)) promptr;
+ 	chosen_handle = finddevice("/chosen");
+ 	if (chosen_handle == (void *) -1)
+@@ -97,7 +151,7 @@ void start(unsigned long a1, unsigned lo
+ 	if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
+ 		exit();
+ 
+-	printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) _start);
++	printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
+ 
+ 	/*
+ 	 * The first available claim_base must be above the end of the
+@@ -118,25 +172,45 @@ void start(unsigned long a1, unsigned lo
+ 		claim_base = PROG_START;
+ #endif
+ 
+-	/*
+-	 * Now we try to claim some memory for the kernel itself
+-	 * our "vmlinux_memsize" is the memory footprint in RAM, _HOWEVER_, what
+-	 * our Makefile stuffs in is an image containing all sort of junk including
+-	 * an ELF header. We need to do some calculations here to find the right
+-	 * size... In practice we add 1Mb, that is enough, but we should really
+-	 * consider fixing the Makefile to put a _raw_ kernel in there !
+-	 */
+-	vmlinux_memsize += ONE_MB;
+-	printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize);
+-	vmlinux.addr = try_claim(vmlinux_memsize);
++	vmlinuz.addr = (unsigned long)_vmlinux_start;
++	vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
++
++	/* gunzip the ELF header of the kernel */
++	if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
++		len = vmlinuz.size;
++		gunzip(elfheader, sizeof(elfheader),
++				(unsigned char *)vmlinuz.addr, &len);
++	} else
++		memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
++
++	elf64 = (Elf64_Ehdr *)elfheader;
++	if ( elf64->e_ident[EI_MAG0]  != ELFMAG0	||
++	     elf64->e_ident[EI_MAG1]  != ELFMAG1	||
++	     elf64->e_ident[EI_MAG2]  != ELFMAG2	||
++	     elf64->e_ident[EI_MAG3]  != ELFMAG3	||
++	     elf64->e_ident[EI_CLASS] != ELFCLASS64	||
++	     elf64->e_ident[EI_DATA]  != ELFDATA2MSB	||
++	     elf64->e_type            != ET_EXEC	||
++	     elf64->e_machine         != EM_PPC64 )
++	{
++		printf("Error: not a valid PPC64 ELF file!\n\r");
++		exit();
++	}
++
++	elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
++				(unsigned long)elf64->e_phoff);
++	for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
++		if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
++			break;
++	}
++	vmlinux.size = (unsigned long)elf64ph->p_filesz;
++	vmlinux.memsize = (unsigned long)elf64ph->p_memsz;
++	printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
++	vmlinux.addr = try_claim(vmlinux.memsize);
+ 	if (vmlinux.addr == 0) {
+ 		printf("Can't allocate memory for kernel image !\n\r");
+ 		exit();
+ 	}
+-	vmlinuz.addr = (unsigned long)_vmlinux_start;
+-	vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
+-	vmlinux.size = PAGE_ALIGN(vmlinux_filesize);
+-	vmlinux.memsize = vmlinux_memsize;
+ 
+ 	/*
+ 	 * Now we try to claim memory for the initrd (and copy it there)
+@@ -160,49 +234,22 @@ void start(unsigned long a1, unsigned lo
+ 
+ 	/* Eventually gunzip the kernel */
+ 	if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
+-		int len;
+-		avail_ram = scratch;
+-		begin_avail = avail_high = avail_ram;
+-		end_avail = scratch + sizeof(scratch);
+ 		printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...",
+ 		       vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size);
+ 		len = vmlinuz.size;
+-		gunzip((void *)vmlinux.addr, vmlinux.size,
++		gunzip((void *)vmlinux.addr, vmlinux.memsize,
+ 			(unsigned char *)vmlinuz.addr, &len);
+ 		printf("done 0x%lx bytes\n\r", len);
+-		printf("0x%x bytes of heap consumed, max in use 0x%x\n\r",
+-		       (unsigned)(avail_high - begin_avail), heap_max);
+ 	} else {
+ 		memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
+ 	}
+ 
+ 	/* Skip over the ELF header */
+-	elf64 = (Elf64_Ehdr *)vmlinux.addr;
+-	if ( elf64->e_ident[EI_MAG0]  != ELFMAG0	||
+-	     elf64->e_ident[EI_MAG1]  != ELFMAG1	||
+-	     elf64->e_ident[EI_MAG2]  != ELFMAG2	||
+-	     elf64->e_ident[EI_MAG3]  != ELFMAG3	||
+-	     elf64->e_ident[EI_CLASS] != ELFCLASS64	||
+-	     elf64->e_ident[EI_DATA]  != ELFDATA2MSB	||
+-	     elf64->e_type            != ET_EXEC	||
+-	     elf64->e_machine         != EM_PPC64 )
+-	{
+-		printf("Error: not a valid PPC64 ELF file!\n\r");
+-		exit();
+-	}
+-
+-	elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
+-				(unsigned long)elf64->e_phoff);
+-	for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
+-		if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
+-			break;
+-	}
+ #ifdef DEBUG
+ 	printf("... skipping 0x%lx bytes of ELF header\n\r",
+ 			(unsigned long)elf64ph->p_offset);
+ #endif
+ 	vmlinux.addr += (unsigned long)elf64ph->p_offset;
+-	vmlinux.size -= (unsigned long)elf64ph->p_offset;
+ 
+ 	flush_cache((void *)vmlinux.addr, vmlinux.size);
+ 
+@@ -225,108 +272,3 @@ void start(unsigned long a1, unsigned lo
+ 	exit();
+ }
+ 
+-struct memchunk {
+-	unsigned int size;
+-	unsigned int pad;
+-	struct memchunk *next;
+-};
+-
+-static struct memchunk *freechunks;
+-
+-void *zalloc(void *x, unsigned items, unsigned size)
+-{
+-	void *p;
+-	struct memchunk **mpp, *mp;
+-
+-	size *= items;
+-	size = _ALIGN(size, sizeof(struct memchunk));
+-	heap_use += size;
+-	if (heap_use > heap_max)
+-		heap_max = heap_use;
+-	for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
+-		if (mp->size == size) {
+-			*mpp = mp->next;
+-			return mp;
+-		}
+-	}
+-	p = avail_ram;
+-	avail_ram += size;
+-	if (avail_ram > avail_high)
+-		avail_high = avail_ram;
+-	if (avail_ram > end_avail) {
+-		printf("oops... out of memory\n\r");
+-		pause();
+-	}
+-	return p;
+-}
+-
+-void zfree(void *x, void *addr, unsigned nb)
+-{
+-	struct memchunk *mp = addr;
+-
+-	nb = _ALIGN(nb, sizeof(struct memchunk));
+-	heap_use -= nb;
+-	if (avail_ram == addr + nb) {
+-		avail_ram = addr;
+-		return;
+-	}
+-	mp->size = nb;
+-	mp->next = freechunks;
+-	freechunks = mp;
+-}
+-
+-#define HEAD_CRC	2
+-#define EXTRA_FIELD	4
+-#define ORIG_NAME	8
+-#define COMMENT		0x10
+-#define RESERVED	0xe0
+-
+-#define DEFLATED	8
+-
+-static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+-{
+-	z_stream s;
+-	int r, i, flags;
+-
+-	/* skip header */
+-	i = 10;
+-	flags = src[3];
+-	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+-		printf("bad gzipped data\n\r");
+-		exit();
+-	}
+-	if ((flags & EXTRA_FIELD) != 0)
+-		i = 12 + src[10] + (src[11] << 8);
+-	if ((flags & ORIG_NAME) != 0)
+-		while (src[i++] != 0)
+-			;
+-	if ((flags & COMMENT) != 0)
+-		while (src[i++] != 0)
+-			;
+-	if ((flags & HEAD_CRC) != 0)
+-		i += 2;
+-	if (i >= *lenp) {
+-		printf("gunzip: ran out of data in header\n\r");
+-		exit();
+-	}
+-
+-	s.zalloc = zalloc;
+-	s.zfree = zfree;
+-	r = inflateInit2(&s, -MAX_WBITS);
+-	if (r != Z_OK) {
+-		printf("inflateInit2 returned %d\n\r", r);
+-		exit();
+-	}
+-	s.next_in = src + i;
+-	s.avail_in = *lenp - i;
+-	s.next_out = dst;
+-	s.avail_out = dstlen;
+-	r = inflate(&s, Z_FINISH);
+-	if (r != Z_OK && r != Z_STREAM_END) {
+-		printf("inflate returned %d msg: %s\n\r", r, s.msg);
+-		exit();
+-	}
+-	*lenp = s.next_out - (unsigned char *) dst;
+-	inflateEnd(&s);
+-}
+-
+diff --git a/arch/ppc64/boot/string.S b/arch/ppc64/boot/string.S
+--- a/arch/ppc64/boot/string.S
++++ b/arch/ppc64/boot/string.S
+@@ -104,7 +104,7 @@ memmove:
+ 
+ 	.globl	memcpy
+ memcpy:
+-	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
++	rlwinm.	r7,r5,32-3,3,31		/* r7 = r5 >> 3 */
+ 	addi	r6,r3,-4
+ 	addi	r4,r4,-4
+ 	beq	2f			/* if less than 8 bytes to do */
+@@ -146,7 +146,7 @@ memcpy:
+ 
+ 	.globl	backwards_memcpy
+ backwards_memcpy:
+-	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
++	rlwinm.	r7,r5,32-3,3,31		/* r7 = r5 >> 3 */
+ 	add	r6,r3,r5
+ 	add	r4,r4,r5
+ 	beq	2f
+diff --git a/arch/ppc64/boot/string.h b/arch/ppc64/boot/string.h
+--- a/arch/ppc64/boot/string.h
++++ b/arch/ppc64/boot/string.h
+@@ -1,5 +1,6 @@
+ #ifndef _PPC_BOOT_STRING_H_
+ #define _PPC_BOOT_STRING_H_
++#include <stddef.h>
+ 
+ extern char *strcpy(char *dest, const char *src);
+ extern char *strncpy(char *dest, const char *src, size_t n);
+diff --git a/arch/ppc64/boot/zImage.lds b/arch/ppc64/boot/zImage.lds
+--- a/arch/ppc64/boot/zImage.lds
++++ b/arch/ppc64/boot/zImage.lds
+@@ -1,62 +1,24 @@
+ OUTPUT_ARCH(powerpc:common)
+-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+-/* Do we need any of these for elf?
+-   __DYNAMIC = 0;    */
++ENTRY(_zimage_start)
+ SECTIONS
+ {
+-  /* Read-only sections, merged into text segment: */
+-  . = + SIZEOF_HEADERS;
+-  .interp : { *(.interp) }
+-  .hash          : { *(.hash)      }
+-  .dynsym        : { *(.dynsym)        }
+-  .dynstr        : { *(.dynstr)        }
+-  .rel.text      : { *(.rel.text)      }
+-  .rela.text     : { *(.rela.text)     }
+-  .rel.data      : { *(.rel.data)      }
+-  .rela.data     : { *(.rela.data)     }
+-  .rel.rodata    : { *(.rel.rodata)    }
+-  .rela.rodata   : { *(.rela.rodata)   }
+-  .rel.got       : { *(.rel.got)       }
+-  .rela.got      : { *(.rela.got)      }
+-  .rel.ctors     : { *(.rel.ctors) }
+-  .rela.ctors    : { *(.rela.ctors)    }
+-  .rel.dtors     : { *(.rel.dtors) }
+-  .rela.dtors    : { *(.rela.dtors)    }
+-  .rel.bss       : { *(.rel.bss)       }
+-  .rela.bss      : { *(.rela.bss)      }
+-  .rel.plt       : { *(.rel.plt)       }
+-  .rela.plt      : { *(.rela.plt)      }
+-  .plt : { *(.plt) }
++  . = (4*1024*1024);
++  _start = .;
+   .text      :
+   {
+     *(.text)
+     *(.fixup)
+-    *(.got1)
+   }
+-  . = ALIGN(4096);
+   _etext = .;
+-  PROVIDE (etext = .);
+-  .rodata    :
+-  {
+-    *(.rodata)
+-    *(.rodata1)
+-  }
+-  .kstrtab   : { *(.kstrtab) }
+-  __vermagic : { *(__vermagic) }
+-  .fini      : { *(.fini)    } =0
+-  .ctors     : { *(.ctors)   }
+-  .dtors     : { *(.dtors)   }
+-  /* Read-write section, merged into data segment: */
+   . = ALIGN(4096);
+   .data    :
+   {
+-    *(.data)
+-    *(.data1)
+-    *(.sdata)
+-    *(.sdata2)
+-    *(.got.plt) *(.got)
+-    *(.dynamic)
+-    CONSTRUCTORS
++    *(.rodata*)
++    *(.data*)
++    *(.sdata*)
++    __got2_start = .;
++    *(.got2)
++    __got2_end = .;
+   }
+ 
+   . = ALIGN(4096);
+@@ -71,20 +33,14 @@ SECTIONS
+ 
+   . = ALIGN(4096);
+   _edata  =  .;
+-  PROVIDE (edata = .);
+-
+-  .fixup   : { *(.fixup) }
+ 
+   . = ALIGN(4096);
+   __bss_start = .;
+   .bss       :
+   {
+-   *(.sbss) *(.scommon)
+-   *(.dynbss)
++   *(.sbss)
+    *(.bss)
+-   *(COMMON)
+   }
+   . = ALIGN(4096);
+   _end = . ;
+-  PROVIDE (end = .);
+ }
+diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c
+deleted file mode 100644
+--- a/arch/ppc64/boot/zlib.c
++++ /dev/null
+@@ -1,2195 +0,0 @@
+-/*
+- * This file is derived from various .h and .c files from the zlib-0.95
+- * distribution by Jean-loup Gailly and Mark Adler, with some additions
+- * by Paul Mackerras to aid in implementing Deflate compression and
+- * decompression for PPP packets.  See zlib.h for conditions of
+- * distribution and use.
+- *
+- * Changes that have been made include:
+- * - changed functions not used outside this file to "local"
+- * - added minCompression parameter to deflateInit2
+- * - added Z_PACKET_FLUSH (see zlib.h for details)
+- * - added inflateIncomp
+- *
+-  Copyright (C) 1995 Jean-loup Gailly and Mark Adler
+-
+-  This software is provided 'as-is', without any express or implied
+-  warranty.  In no event will the authors be held liable for any damages
+-  arising from the use of this software.
+-
+-  Permission is granted to anyone to use this software for any purpose,
+-  including commercial applications, and to alter it and redistribute it
+-  freely, subject to the following restrictions:
+-
+-  1. The origin of this software must not be misrepresented; you must not
+-     claim that you wrote the original software. If you use this software
+-     in a product, an acknowledgment in the product documentation would be
+-     appreciated but is not required.
+-  2. Altered source versions must be plainly marked as such, and must not be
+-     misrepresented as being the original software.
+-  3. This notice may not be removed or altered from any source distribution.
+-
+-  Jean-loup Gailly        Mark Adler
+-  gzip at prep.ai.mit.edu    madler at alumni.caltech.edu
+-
+- *
+- * 
+- */
+-
+-/*+++++*/
+-/* zutil.h -- internal interface and configuration of the compression library
+- * Copyright (C) 1995 Jean-loup Gailly.
+- * 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.
+- */
+-
+-/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
+-
+-#define _Z_UTIL_H
+-
+-#include "zlib.h"
+-
+-#ifndef local
+-#  define local static
+-#endif
+-/* compile with -Dlocal if your debugger can't find static symbols */
+-
+-#define FAR
+-
+-typedef unsigned char  uch;
+-typedef uch FAR uchf;
+-typedef unsigned short ush;
+-typedef ush FAR ushf;
+-typedef unsigned long  ulg;
+-
+-extern char *z_errmsg[]; /* indexed by 1-zlib_error */
+-
+-#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
+-/* To be used only when the state is known to be valid */
+-
+-#ifndef NULL
+-#define NULL	((void *) 0)
+-#endif
+-
+-        /* common constants */
+-
+-#define DEFLATED   8
+-
+-#ifndef DEF_WBITS
+-#  define DEF_WBITS MAX_WBITS
+-#endif
+-/* default windowBits for decompression. MAX_WBITS is for compression only */
+-
+-#if MAX_MEM_LEVEL >= 8
+-#  define DEF_MEM_LEVEL 8
+-#else
+-#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+-#endif
+-/* default memLevel */
+-
+-#define STORED_BLOCK 0
+-#define STATIC_TREES 1
+-#define DYN_TREES    2
+-/* The three kinds of block type */
+-
+-#define MIN_MATCH  3
+-#define MAX_MATCH  258
+-/* The minimum and maximum match lengths */
+-
+-         /* functions */
+-
+-extern void *memcpy(void *, const void *, unsigned long);
+-#define zmemcpy memcpy
+-
+-/* Diagnostic functions */
+-#ifdef DEBUG_ZLIB
+-#  include "stdio.h"
+-#  ifndef verbose
+-#    define verbose 0
+-#  endif
+-#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+-#  define Trace(x) fprintf x
+-#  define Tracev(x) {if (verbose) fprintf x ;}
+-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+-#else
+-#  define Assert(cond,msg)
+-#  define Trace(x)
+-#  define Tracev(x)
+-#  define Tracevv(x)
+-#  define Tracec(c,x)
+-#  define Tracecv(c,x)
+-#endif
+-
+-
+-typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
+-
+-/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
+-/* void   zcfree  OF((voidpf opaque, voidpf ptr)); */
+-
+-#define ZALLOC(strm, items, size) \
+-           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+-#define ZFREE(strm, addr, size)	\
+-	   (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
+-#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
+-
+-/* deflate.h -- internal compression state
+- * Copyright (C) 1995 Jean-loup Gailly
+- * 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.
+- */
+-
+-/*+++++*/
+-/* infblock.h -- header to use infblock.c
+- * Copyright (C) 1995 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.
+- */
+-
+-struct inflate_blocks_state;
+-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+-
+-local inflate_blocks_statef * inflate_blocks_new OF((
+-    z_stream *z,
+-    check_func c,               /* check function */
+-    uInt w));                   /* window size */
+-
+-local int inflate_blocks OF((
+-    inflate_blocks_statef *,
+-    z_stream *,
+-    int));                      /* initial return code */
+-
+-local void inflate_blocks_reset OF((
+-    inflate_blocks_statef *,
+-    z_stream *,
+-    uLongf *));                  /* check value on output */
+-
+-local int inflate_blocks_free OF((
+-    inflate_blocks_statef *,
+-    z_stream *,
+-    uLongf *));                  /* check value on output */
+-
+-local int inflate_addhistory OF((
+-    inflate_blocks_statef *,
+-    z_stream *));
+-
+-local int inflate_packet_flush OF((
+-    inflate_blocks_statef *));
+-
+-/*+++++*/
+-/* inftrees.h -- header to use inftrees.c
+- * Copyright (C) 1995 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.
+- */
+-
+-/* Huffman code lookup table entry--this entry is four bytes for machines
+-   that have 16-bit pointers (e.g. PC's in the small or medium model). */
+-
+-typedef struct inflate_huft_s FAR inflate_huft;
+-
+-struct inflate_huft_s {
+-  union {
+-    struct {
+-      Byte Exop;        /* number of extra bits or operation */
+-      Byte Bits;        /* number of bits in this code or subcode */
+-    } what;
+-    uInt Nalloc;	/* number of these allocated here */
+-    Bytef *pad;         /* pad structure to a power of 2 (4 bytes for */
+-  } word;               /*  16-bit, 8 bytes for 32-bit machines) */
+-  union {
+-    uInt Base;          /* literal, length base, or distance base */
+-    inflate_huft *Next; /* pointer to next level of table */
+-  } more;
+-};
+-
+-#ifdef DEBUG_ZLIB
+-  local uInt inflate_hufts;
+-#endif
+-
+-local int inflate_trees_bits OF((
+-    uIntf *,                    /* 19 code lengths */
+-    uIntf *,                    /* bits tree desired/actual depth */
+-    inflate_huft * FAR *,       /* bits tree result */
+-    z_stream *));               /* for zalloc, zfree functions */
+-
+-local int inflate_trees_dynamic OF((
+-    uInt,                       /* number of literal/length codes */
+-    uInt,                       /* number of distance codes */
+-    uIntf *,                    /* that many (total) code lengths */
+-    uIntf *,                    /* literal desired/actual bit depth */
+-    uIntf *,                    /* distance desired/actual bit depth */
+-    inflate_huft * FAR *,       /* literal/length tree result */
+-    inflate_huft * FAR *,       /* distance tree result */
+-    z_stream *));               /* for zalloc, zfree functions */
+-
+-local int inflate_trees_fixed OF((
+-    uIntf *,                    /* literal desired/actual bit depth */
+-    uIntf *,                    /* distance desired/actual bit depth */
+-    inflate_huft * FAR *,       /* literal/length tree result */
+-    inflate_huft * FAR *));     /* distance tree result */
+-
+-local int inflate_trees_free OF((
+-    inflate_huft *,             /* tables to free */
+-    z_stream *));               /* for zfree function */
+-
+-
+-/*+++++*/
+-/* infcodes.h -- header to use infcodes.c
+- * Copyright (C) 1995 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.
+- */
+-
+-struct inflate_codes_state;
+-typedef struct inflate_codes_state FAR inflate_codes_statef;
+-
+-local inflate_codes_statef *inflate_codes_new OF((
+-    uInt, uInt,
+-    inflate_huft *, inflate_huft *,
+-    z_stream *));
+-
+-local int inflate_codes OF((
+-    inflate_blocks_statef *,
+-    z_stream *,
+-    int));
+-
+-local void inflate_codes_free OF((
+-    inflate_codes_statef *,
+-    z_stream *));
+-
+-
+-/*+++++*/
+-/* inflate.c -- zlib interface to inflate modules
+- * Copyright (C) 1995 Mark Adler
+- * For conditions of distribution and use, see copyright notice in zlib.h 
+- */
+-
+-/* inflate private state */
+-struct internal_state {
+-
+-  /* mode */
+-  enum {
+-      METHOD,   /* waiting for method byte */
+-      FLAG,     /* waiting for flag byte */
+-      BLOCKS,   /* decompressing blocks */
+-      CHECK4,   /* four check bytes to go */
+-      CHECK3,   /* three check bytes to go */
+-      CHECK2,   /* two check bytes to go */
+-      CHECK1,   /* one check byte to go */
+-      DONE,     /* finished check, done */
+-      BAD}      /* got an error--stay here */
+-    mode;               /* current inflate mode */
+-
+-  /* mode dependent information */
+-  union {
+-    uInt method;        /* if FLAGS, method byte */
+-    struct {
+-      uLong was;                /* computed check value */
+-      uLong need;               /* stream check value */
+-    } check;            /* if CHECK, check values to compare */
+-    uInt marker;        /* if BAD, inflateSync's marker bytes count */
+-  } sub;        /* submode */
+-
+-  /* mode independent information */
+-  int  nowrap;          /* flag for no wrapper */
+-  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
+-  inflate_blocks_statef 
+-    *blocks;            /* current inflate_blocks state */
+-
+-};
+-
+-
+-int inflateReset(
+-	z_stream *z
+-)
+-{
+-  uLong c;
+-
+-  if (z == Z_NULL || z->state == Z_NULL)
+-    return Z_STREAM_ERROR;
+-  z->total_in = z->total_out = 0;
+-  z->msg = Z_NULL;
+-  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+-  inflate_blocks_reset(z->state->blocks, z, &c);
+-  Trace((stderr, "inflate: reset\n"));
+-  return Z_OK;
+-}
+-
+-
+-int inflateEnd(
+-	z_stream *z
+-)
+-{
+-  uLong c;
+-
+-  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+-    return Z_STREAM_ERROR;
+-  if (z->state->blocks != Z_NULL)
+-    inflate_blocks_free(z->state->blocks, z, &c);
+-  ZFREE(z, z->state, sizeof(struct internal_state));
+-  z->state = Z_NULL;
+-  Trace((stderr, "inflate: end\n"));
+-  return Z_OK;
+-}
+-
+-
+-int inflateInit2(
+-	z_stream *z,
+-	int w
+-)
+-{
+-  /* initialize state */
+-  if (z == Z_NULL)
+-    return Z_STREAM_ERROR;
+-/*  if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
+-/*  if (z->zfree == Z_NULL) z->zfree = zcfree; */
+-  if ((z->state = (struct internal_state FAR *)
+-       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+-    return Z_MEM_ERROR;
+-  z->state->blocks = Z_NULL;
+-
+-  /* handle undocumented nowrap option (no zlib header or check) */
+-  z->state->nowrap = 0;
+-  if (w < 0)
+-  {
+-    w = - w;
+-    z->state->nowrap = 1;
+-  }
+-
+-  /* set window size */
+-  if (w < 8 || w > 15)
+-  {
+-    inflateEnd(z);
+-    return Z_STREAM_ERROR;
+-  }
+-  z->state->wbits = (uInt)w;
+-
+-  /* create inflate_blocks state */
+-  if ((z->state->blocks =
+-       inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
+-      == Z_NULL)
+-  {
+-    inflateEnd(z);
+-    return Z_MEM_ERROR;
+-  }
+-  Trace((stderr, "inflate: allocated\n"));
+-
+-  /* reset state */
+-  inflateReset(z);
+-  return Z_OK;
+-}
+-
+-
+-int inflateInit(
+-	z_stream *z
+-)
+-{
+-  return inflateInit2(z, DEF_WBITS);
+-}
+-
+-
+-#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
+-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+-
+-int inflate(
+-	z_stream *z,
+-	int f	
+-)
+-{
+-  int r;
+-  uInt b;
+-
+-  if (z == Z_NULL || z->next_in == Z_NULL)
+-    return Z_STREAM_ERROR;
+-  r = Z_BUF_ERROR;
+-  while (1) switch (z->state->mode)
+-  {
+-    case METHOD:
+-      NEEDBYTE
+-      if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
+-      {
+-        z->state->mode = BAD;
+-        z->msg = "unknown compression method";
+-        z->state->sub.marker = 5;       /* can't try inflateSync */
+-        break;
+-      }
+-      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+-      {
+-        z->state->mode = BAD;
+-        z->msg = "invalid window size";
+-        z->state->sub.marker = 5;       /* can't try inflateSync */
+-        break;
+-      }
+-      z->state->mode = FLAG;
+-    case FLAG:
+-      NEEDBYTE
+-      if ((b = NEXTBYTE) & 0x20)
+-      {
+-        z->state->mode = BAD;
+-        z->msg = "invalid reserved bit";
+-        z->state->sub.marker = 5;       /* can't try inflateSync */
+-        break;
+-      }
+-      if (((z->state->sub.method << 8) + b) % 31)
+-      {
+-        z->state->mode = BAD;
+-        z->msg = "incorrect header check";
+-        z->state->sub.marker = 5;       /* can't try inflateSync */
+-        break;
+-      }
+-      Trace((stderr, "inflate: zlib header ok\n"));
+-      z->state->mode = BLOCKS;
+-    case BLOCKS:
+-      r = inflate_blocks(z->state->blocks, z, r);
+-      if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
+-	  r = inflate_packet_flush(z->state->blocks);
+-      if (r == Z_DATA_ERROR)
+-      {
+-        z->state->mode = BAD;
+-        z->state->sub.marker = 0;       /* can try inflateSync */
+-        break;
+-      }
+-      if (r != Z_STREAM_END)
+-        return r;
+-      r = Z_OK;
+-      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+-      if (z->state->nowrap)
+-      {
+-        z->state->mode = DONE;
+-        break;
+-      }
+-      z->state->mode = CHECK4;
+-    case CHECK4:
+-      NEEDBYTE
+-      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+-      z->state->mode = CHECK3;
+-    case CHECK3:
+-      NEEDBYTE
+-      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+-      z->state->mode = CHECK2;
+-    case CHECK2:
+-      NEEDBYTE
+-      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+-      z->state->mode = CHECK1;
+-    case CHECK1:
+-      NEEDBYTE
+-      z->state->sub.check.need += (uLong)NEXTBYTE;
+-
+-      if (z->state->sub.check.was != z->state->sub.check.need)
+-      {
+-        z->state->mode = BAD;
+-        z->msg = "incorrect data check";
+-        z->state->sub.marker = 5;       /* can't try inflateSync */
+-        break;
+-      }
+-      Trace((stderr, "inflate: zlib check ok\n"));
+-      z->state->mode = DONE;
+-    case DONE:
+-      return Z_STREAM_END;
+-    case BAD:
+-      return Z_DATA_ERROR;
+-    default:
+-      return Z_STREAM_ERROR;
+-  }
+-
+- empty:
+-  if (f != Z_PACKET_FLUSH)
+-    return r;
+-  z->state->mode = BAD;
+-  z->state->sub.marker = 0;       /* can try inflateSync */
+-  return Z_DATA_ERROR;
+-}
+-
+-/*
+- * This subroutine adds the data at next_in/avail_in to the output history
+- * without performing any output.  The output buffer must be "caught up";
+- * i.e. no pending output (hence s->read equals s->write), and the state must
+- * be BLOCKS (i.e. we should be willing to see the start of a series of
+- * BLOCKS).  On exit, the output will also be caught up, and the checksum
+- * will have been updated if need be.
+- */
+-
+-int inflateIncomp(
+-	z_stream *z
+-)
+-{
+-    if (z->state->mode != BLOCKS)
+-	return Z_DATA_ERROR;
+-    return inflate_addhistory(z->state->blocks, z);
+-}
+-
+-
+-int inflateSync(
+-	z_stream *z
+-)
+-{
+-  uInt n;       /* number of bytes to look at */
+-  Bytef *p;     /* pointer to bytes */
+-  uInt m;       /* number of marker bytes found in a row */
+-  uLong r, w;   /* temporaries to save total_in and total_out */
+-
+-  /* set up */
+-  if (z == Z_NULL || z->state == Z_NULL)
+-    return Z_STREAM_ERROR;
+-  if (z->state->mode != BAD)
+-  {
+-    z->state->mode = BAD;
+-    z->state->sub.marker = 0;
+-  }
+-  if ((n = z->avail_in) == 0)
+-    return Z_BUF_ERROR;
+-  p = z->next_in;
+-  m = z->state->sub.marker;
+-
+-  /* search */
+-  while (n && m < 4)
+-  {
+-    if (*p == (Byte)(m < 2 ? 0 : 0xff))
+-      m++;
+-    else if (*p)
+-      m = 0;
+-    else
+-      m = 4 - m;
+-    p++, n--;
+-  }
+-
+-  /* restore */
+-  z->total_in += p - z->next_in;
+-  z->next_in = p;
+-  z->avail_in = n;
+-  z->state->sub.marker = m;
+-
+-  /* return no joy or set up to restart on a new block */
+-  if (m != 4)
+-    return Z_DATA_ERROR;
+-  r = z->total_in;  w = z->total_out;
+-  inflateReset(z);
+-  z->total_in = r;  z->total_out = w;
+-  z->state->mode = BLOCKS;
+-  return Z_OK;
+-}
+-
+-#undef NEEDBYTE
+-#undef NEXTBYTE
+-
+-/*+++++*/
+-/* infutil.h -- types and macros common to blocks and codes
+- * Copyright (C) 1995 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.
+- */
+-
+-/* inflate blocks semi-private state */
+-struct inflate_blocks_state {
+-
+-  /* mode */
+-  enum {
+-      TYPE,     /* get type bits (3, including end bit) */
+-      LENS,     /* get lengths for stored */
+-      STORED,   /* processing stored block */
+-      TABLE,    /* get table lengths */
+-      BTREE,    /* get bit lengths tree for a dynamic block */
+-      DTREE,    /* get length, distance trees for a dynamic block */
+-      CODES,    /* processing fixed or dynamic block */
+-      DRY,      /* output remaining window bytes */
+-      DONEB,     /* finished last block, done */
+-      BADB}      /* got a data error--stuck here */
+-    mode;               /* current inflate_block mode */
+-
+-  /* mode dependent information */
+-  union {
+-    uInt left;          /* if STORED, bytes left to copy */
+-    struct {
+-      uInt table;               /* table lengths (14 bits) */
+-      uInt index;               /* index into blens (or border) */
+-      uIntf *blens;             /* bit lengths of codes */
+-      uInt bb;                  /* bit length tree depth */
+-      inflate_huft *tb;         /* bit length decoding tree */
+-      int nblens;		/* # elements allocated at blens */
+-    } trees;            /* if DTREE, decoding info for trees */
+-    struct {
+-      inflate_huft *tl, *td;    /* trees to free */
+-      inflate_codes_statef 
+-         *codes;
+-    } decode;           /* if CODES, current state */
+-  } sub;                /* submode */
+-  uInt last;            /* true if this block is the last block */
+-
+-  /* mode independent information */
+-  uInt bitk;            /* bits in bit buffer */
+-  uLong bitb;           /* bit buffer */
+-  Bytef *window;        /* sliding window */
+-  Bytef *end;           /* one byte after sliding window */
+-  Bytef *read;          /* window read pointer */
+-  Bytef *write;         /* window write pointer */
+-  check_func checkfn;   /* check function */
+-  uLong check;          /* check on output */
+-
+-};
+-
+-
+-/* defines for inflate input/output */
+-/*   update pointers and return */
+-#define UPDBITS {s->bitb=b;s->bitk=k;}
+-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+-#define UPDOUT {s->write=q;}
+-#define UPDATE {UPDBITS UPDIN UPDOUT}
+-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+-/*   get bytes and bits */
+-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+-#define NEXTBYTE (n--,*p++)
+-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+-#define DUMPBITS(j) {b>>=(j);k-=(j);}
+-/*   output bytes */
+-#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
+-#define LOADOUT {q=s->write;m=WAVAIL;}
+-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
+-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+-/*   load local pointers */
+-#define LOAD {LOADIN LOADOUT}
+-
+-/* And'ing with mask[n] masks the lower n bits */
+-local uInt inflate_mask[] = {
+-    0x0000,
+-    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+-    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+-};
+-
+-/* copy as much as possible from the sliding window to the output area */
+-local int inflate_flush OF((
+-    inflate_blocks_statef *,
+-    z_stream *,
+-    int));
+-
+-/*+++++*/
+-/* inffast.h -- header to use inffast.c
+- * Copyright (C) 1995 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.
+- */
+-
+-local int inflate_fast OF((
+-    uInt,
+-    uInt,
+-    inflate_huft *,
+-    inflate_huft *,
+-    inflate_blocks_statef *,
+-    z_stream *));
+-
+-
+-/*+++++*/
+-/* infblock.c -- interpret and process block types to last block
+- * Copyright (C) 1995 Mark Adler
+- * For conditions of distribution and use, see copyright notice in zlib.h 
+- */
+-
+-/* Table for deflate from PKZIP's appnote.txt. */
+-local uInt border[] = { /* Order of the bit length code lengths */
+-        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+-
+-/*
+-   Notes beyond the 1.93a appnote.txt:
+-
+-   1. Distance pointers never point before the beginning of the output
+-      stream.
+-   2. Distance pointers can point back across blocks, up to 32k away.
+-   3. There is an implied maximum of 7 bits for the bit length table and
+-      15 bits for the actual data.
+-   4. If only one code exists, then it is encoded using one bit.  (Zero
+-      would be more efficient, but perhaps a little confusing.)  If two
+-      codes exist, they are coded using one bit each (0 and 1).
+-   5. There is no way of sending zero distance codes--a dummy must be
+-      sent if there are none.  (History: a pre 2.0 version of PKZIP would
+-      store blocks with no distance codes, but this was discovered to be
+-      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
+-      zero distance codes, which is sent as one code of zero bits in
+-      length.
+-   6. There are up to 286 literal/length codes.  Code 256 represents the
+-      end-of-block.  Note however that the static length tree defines
+-      288 codes just to fill out the Huffman codes.  Codes 286 and 287
+-      cannot be used though, since there is no length base or extra bits
+-      defined for them.  Similarily, there are up to 30 distance codes.
+-      However, static trees define 32 codes (all 5 bits) to fill out the
+-      Huffman codes, but the last two had better not show up in the data.
+-   7. Unzip can check dynamic Huffman blocks for complete code sets.
+-      The exception is that a single code would not be complete (see #4).
+-   8. The five bits following the block type is really the number of
+-      literal codes sent minus 257.
+-   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+-      (1+6+6).  Therefore, to output three times the length, you output
+-      three codes (1+1+1), whereas to output four times the same length,
+-      you only need two codes (1+3).  Hmm.
+-  10. In the tree reconstruction algorithm, Code = Code + Increment
+-      only if BitLength(i) is not zero.  (Pretty obvious.)
+-  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
+-  12. Note: length code 284 can represent 227-258, but length code 285
+-      really is 258.  The last length deserves its own, short code
+-      since it gets used a lot in very redundant files.  The length
+-      258 is special since 258 - 3 (the min match length) is 255.
+-  13. The literal/length and distance code bit lengths are read as a
+-      single stream of lengths.  It is possible (and advantageous) for
+-      a repeat code (16, 17, or 18) to go across the boundary between
+-      the two sets of lengths.
+- */
+-
+-
+-local void inflate_blocks_reset(
+-	inflate_blocks_statef *s,
+-	z_stream *z,
+-	uLongf *c
+-)
+-{
+-  if (s->checkfn != Z_NULL)
+-    *c = s->check;
+-  if (s->mode == BTREE || s->mode == DTREE)
+-    ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
+-  if (s->mode == CODES)
+-  {
+-    inflate_codes_free(s->sub.decode.codes, z);
+-    inflate_trees_free(s->sub.decode.td, z);
+-    inflate_trees_free(s->sub.decode.tl, z);
+-  }
+-  s->mode = TYPE;
+-  s->bitk = 0;
+-  s->bitb = 0;
+-  s->read = s->write = s->window;
+-  if (s->checkfn != Z_NULL)
+-    s->check = (*s->checkfn)(0L, Z_NULL, 0);
+-  Trace((stderr, "inflate:   blocks reset\n"));
+-}
+-
+-
+-local inflate_blocks_statef *inflate_blocks_new(
+-	z_stream *z,
+-	check_func c,
+-	uInt w
+-)
+-{
+-  inflate_blocks_statef *s;
+-
+-  if ((s = (inflate_blocks_statef *)ZALLOC
+-       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+-    return s;
+-  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+-  {
+-    ZFREE(z, s, sizeof(struct inflate_blocks_state));
+-    return Z_NULL;
+-  }
+-  s->end = s->window + w;
+-  s->checkfn = c;
+-  s->mode = TYPE;
+-  Trace((stderr, "inflate:   blocks allocated\n"));
+-  inflate_blocks_reset(s, z, &s->check);
+-  return s;
+-}
+-
+-
+-local int inflate_blocks(
+-	inflate_blocks_statef *s,
+-	z_stream *z,
+-	int r
+-)
+-{
+-  uInt t;               /* temporary storage */
+-  uLong b;              /* bit buffer */
+-  uInt k;               /* bits in bit buffer */
+-  Bytef *p;             /* input data pointer */
+-  uInt n;               /* bytes available there */
+-  Bytef *q;             /* output window write pointer */
+-  uInt m;               /* bytes to end of window or read pointer */
+-
+-  /* copy input/output information to locals (UPDATE macro restores) */
+-  LOAD
+-
+-  /* process input based on current state */
+-  while (1) switch (s->mode)
+-  {
+-    case TYPE:
+-      NEEDBITS(3)
+-      t = (uInt)b & 7;
+-      s->last = t & 1;
+-      switch (t >> 1)
+-      {
+-        case 0:                         /* stored */
+-          Trace((stderr, "inflate:     stored block%s\n",
+-                 s->last ? " (last)" : ""));
+-          DUMPBITS(3)
+-          t = k & 7;                    /* go to byte boundary */
+-          DUMPBITS(t)
+-          s->mode = LENS;               /* get length of stored block */
+-          break;
+-        case 1:                         /* fixed */
+-          Trace((stderr, "inflate:     fixed codes block%s\n",
+-                 s->last ? " (last)" : ""));
+-          {
+-            uInt bl, bd;
+-            inflate_huft *tl, *td;
+-
+-            inflate_trees_fixed(&bl, &bd, &tl, &td);
+-            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+-            if (s->sub.decode.codes == Z_NULL)
+-            {
+-              r = Z_MEM_ERROR;
+-              LEAVE
+-            }
+-            s->sub.decode.tl = Z_NULL;  /* don't try to free these */
+-            s->sub.decode.td = Z_NULL;
+-          }
+-          DUMPBITS(3)
+-          s->mode = CODES;
+-          break;
+-        case 2:                         /* dynamic */
+-          Trace((stderr, "inflate:     dynamic codes block%s\n",
+-                 s->last ? " (last)" : ""));
+-          DUMPBITS(3)
+-          s->mode = TABLE;
+-          break;
+-        case 3:                         /* illegal */
+-          DUMPBITS(3)
+-          s->mode = BADB;
+-          z->msg = "invalid block type";
+-          r = Z_DATA_ERROR;
+-          LEAVE
+-      }
+-      break;
+-    case LENS:
+-      NEEDBITS(32)
+-      if (((~b) >> 16) != (b & 0xffff))
+-      {
+-        s->mode = BADB;
+-        z->msg = "invalid stored block lengths";
+-        r = Z_DATA_ERROR;
+-        LEAVE
+-      }
+-      s->sub.left = (uInt)b & 0xffff;
+-      b = k = 0;                      /* dump bits */
+-      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
+-      s->mode = s->sub.left ? STORED : TYPE;
+-      break;
+-    case STORED:
+-      if (n == 0)
+-        LEAVE
+-      NEEDOUT
+-      t = s->sub.left;
+-      if (t > n) t = n;
+-      if (t > m) t = m;
+-      zmemcpy(q, p, t);
+-      p += t;  n -= t;
+-      q += t;  m -= t;
+-      if ((s->sub.left -= t) != 0)
+-        break;
+-      Tracev((stderr, "inflate:       stored end, %lu total out\n",
+-              z->total_out + (q >= s->read ? q - s->read :
+-              (s->end - s->read) + (q - s->window))));
+-      s->mode = s->last ? DRY : TYPE;
+-      break;
+-    case TABLE:
+-      NEEDBITS(14)
+-      s->sub.trees.table = t = (uInt)b & 0x3fff;
+-#ifndef PKZIP_BUG_WORKAROUND
+-      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+-      {
+-        s->mode = BADB;
+-        z->msg = "too many length or distance symbols";
+-        r = Z_DATA_ERROR;
+-        LEAVE
+-      }
+-#endif
+-      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+-      if (t < 19)
+-        t = 19;
+-      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+-      {
+-        r = Z_MEM_ERROR;
+-        LEAVE
+-      }
+-      s->sub.trees.nblens = t;
+-      DUMPBITS(14)
+-      s->sub.trees.index = 0;
+-      Tracev((stderr, "inflate:       table sizes ok\n"));
+-      s->mode = BTREE;
+-    case BTREE:
+-      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+-      {
+-        NEEDBITS(3)
+-        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+-        DUMPBITS(3)
+-      }
+-      while (s->sub.trees.index < 19)
+-        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+-      s->sub.trees.bb = 7;
+-      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+-                             &s->sub.trees.tb, z);
+-      if (t != Z_OK)
+-      {
+-        r = t;
+-        if (r == Z_DATA_ERROR)
+-          s->mode = BADB;
+-        LEAVE
+-      }
+-      s->sub.trees.index = 0;
+-      Tracev((stderr, "inflate:       bits tree ok\n"));
+-      s->mode = DTREE;
+-    case DTREE:
+-      while (t = s->sub.trees.table,
+-             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+-      {
+-        inflate_huft *h;
+-        uInt i, j, c;
+-
+-        t = s->sub.trees.bb;
+-        NEEDBITS(t)
+-        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+-        t = h->word.what.Bits;
+-        c = h->more.Base;
+-        if (c < 16)
+-        {
+-          DUMPBITS(t)
+-          s->sub.trees.blens[s->sub.trees.index++] = c;
+-        }
+-        else /* c == 16..18 */
+-        {
+-          i = c == 18 ? 7 : c - 14;
+-          j = c == 18 ? 11 : 3;
+-          NEEDBITS(t + i)
+-          DUMPBITS(t)
+-          j += (uInt)b & inflate_mask[i];
+-          DUMPBITS(i)
+-          i = s->sub.trees.index;
+-          t = s->sub.trees.table;
+-          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+-              (c == 16 && i < 1))
+-          {
+-            s->mode = BADB;
+-            z->msg = "invalid bit length repeat";
+-            r = Z_DATA_ERROR;
+-            LEAVE
+-          }
+-          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+-          do {
+-            s->sub.trees.blens[i++] = c;
+-          } while (--j);
+-          s->sub.trees.index = i;
+-        }
+-      }
+-      inflate_trees_free(s->sub.trees.tb, z);
+-      s->sub.trees.tb = Z_NULL;
+-      {
+-        uInt bl, bd;
+-        inflate_huft *tl, *td;
+-        inflate_codes_statef *c;
+-
+-        bl = 9;         /* must be <= 9 for lookahead assumptions */
+-        bd = 6;         /* must be <= 9 for lookahead assumptions */
+-        t = s->sub.trees.table;
+-        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+-                                  s->sub.trees.blens, &bl, &bd, &tl, &td, z);
+-        if (t != Z_OK)
+-        {
+-          if (t == (uInt)Z_DATA_ERROR)
+-            s->mode = BADB;
+-          r = t;
+-          LEAVE
+-        }
+-        Tracev((stderr, "inflate:       trees ok\n"));
+-        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+-        {
+-          inflate_trees_free(td, z);
+-          inflate_trees_free(tl, z);
+-          r = Z_MEM_ERROR;
+-          LEAVE
+-        }
+-        ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
+-        s->sub.decode.codes = c;
+-        s->sub.decode.tl = tl;
+-        s->sub.decode.td = td;
+-      }
+-      s->mode = CODES;
+-    case CODES:
+-      UPDATE
+-      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+-        return inflate_flush(s, z, r);
+-      r = Z_OK;
+-      inflate_codes_free(s->sub.decode.codes, z);
+-      inflate_trees_free(s->sub.decode.td, z);
+-      inflate_trees_free(s->sub.decode.tl, z);
+-      LOAD
+-      Tracev((stderr, "inflate:       codes end, %lu total out\n",
+-              z->total_out + (q >= s->read ? q - s->read :
+-              (s->end - s->read) + (q - s->window))));
+-      if (!s->last)
+-      {
+-        s->mode = TYPE;
+-        break;
+-      }
+-      if (k > 7)              /* return unused byte, if any */
+-      {
+-        Assert(k < 16, "inflate_codes grabbed too many bytes")
+-        k -= 8;
+-        n++;
+-        p--;                    /* can always return one */
+-      }
+-      s->mode = DRY;
+-    case DRY:
+-      FLUSH
+-      if (s->read != s->write)
+-        LEAVE
+-      s->mode = DONEB;
+-    case DONEB:
+-      r = Z_STREAM_END;
+-      LEAVE
+-    case BADB:
+-      r = Z_DATA_ERROR;
+-      LEAVE
+-    default:
+-      r = Z_STREAM_ERROR;
+-      LEAVE
+-  }
+-}
+-
+-
+-local int inflate_blocks_free(
+-	inflate_blocks_statef *s,
+-	z_stream *z,
+-	uLongf *c
+-)
+-{
+-  inflate_blocks_reset(s, z, c);
+-  ZFREE(z, s->window, s->end - s->window);
+-  ZFREE(z, s, sizeof(struct inflate_blocks_state));
+-  Trace((stderr, "inflate:   blocks freed\n"));
+-  return Z_OK;
+-}
+-
+-/*
+- * This subroutine adds the data at next_in/avail_in to the output history
+- * without performing any output.  The output buffer must be "caught up";
+- * i.e. no pending output (hence s->read equals s->write), and the state must
+- * be BLOCKS (i.e. we should be willing to see the start of a series of
+- * BLOCKS).  On exit, the output will also be caught up, and the checksum
+- * will have been updated if need be.
+- */
+-local int inflate_addhistory(
+-	inflate_blocks_statef *s,
+-	z_stream *z
+-)
+-{
+-    uLong b;              /* bit buffer */  /* NOT USED HERE */
+-    uInt k;               /* bits in bit buffer */ /* NOT USED HERE */
+-    uInt t;               /* temporary storage */
+-    Bytef *p;             /* input data pointer */
+-    uInt n;               /* bytes available there */
+-    Bytef *q;             /* output window write pointer */
+-    uInt m;               /* bytes to end of window or read pointer */
+-
+-    if (s->read != s->write)
+-	return Z_STREAM_ERROR;
+-    if (s->mode != TYPE)
+-	return Z_DATA_ERROR;
+-
+-    /* we're ready to rock */
+-    LOAD
+-    /* while there is input ready, copy to output buffer, moving
+-     * pointers as needed.
+-     */
+-    while (n) {
+-	t = n;  /* how many to do */
+-	/* is there room until end of buffer? */
+-	if (t > m) t = m;
+-	/* update check information */
+-	if (s->checkfn != Z_NULL)
+-	    s->check = (*s->checkfn)(s->check, q, t);
+-	zmemcpy(q, p, t);
+-	q += t;
+-	p += t;
+-	n -= t;
+-	z->total_out += t;
+-	s->read = q;    /* drag read pointer forward */
+-/*      WRAP  */ 	/* expand WRAP macro by hand to handle s->read */
+-	if (q == s->end) {
+-	    s->read = q = s->window;
+-	    m = WAVAIL;
+-	}
+-    }
+-    UPDATE
+-    return Z_OK;
+-}
+-
+-
+-/*
+- * At the end of a Deflate-compressed PPP packet, we expect to have seen
+- * a `stored' block type value but not the (zero) length bytes.
+- */
+-local int inflate_packet_flush(
+-	inflate_blocks_statef *s
+-)
+-{
+-    if (s->mode != LENS)
+-	return Z_DATA_ERROR;
+-    s->mode = TYPE;
+-    return Z_OK;
+-}
+-
+-
+-/*+++++*/
+-/* inftrees.c -- generate Huffman trees for efficient decoding
+- * Copyright (C) 1995 Mark Adler
+- * For conditions of distribution and use, see copyright notice in zlib.h 
+- */
+-
+-/* simplify the use of the inflate_huft type with some defines */
+-#define base more.Base
+-#define next more.Next
+-#define exop word.what.Exop
+-#define bits word.what.Bits
+-
+-
+-local int huft_build OF((
+-    uIntf *,            /* code lengths in bits */
+-    uInt,               /* number of codes */
+-    uInt,               /* number of "simple" codes */
+-    uIntf *,            /* list of base values for non-simple codes */
+-    uIntf *,            /* list of extra bits for non-simple codes */
+-    inflate_huft * FAR*,/* result: starting table */
+-    uIntf *,            /* maximum lookup bits (returns actual) */
+-    z_stream *));       /* for zalloc function */
+-
+-local voidpf falloc OF((
+-    voidpf,             /* opaque pointer (not used) */
+-    uInt,               /* number of items */
+-    uInt));             /* size of item */
+-
+-local void ffree OF((
+-    voidpf q,           /* opaque pointer (not used) */
+-    voidpf p,           /* what to free (not used) */
+-    uInt n));		/* number of bytes (not used) */
+-
+-/* Tables for deflate from PKZIP's appnote.txt. */
+-local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
+-        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+-        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+-        /* actually lengths - 2; also see note #13 above about 258 */
+-local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
+-        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+-        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
+-local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
+-        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+-        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+-        8193, 12289, 16385, 24577};
+-local uInt cpdext[] = { /* Extra bits for distance codes */
+-        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+-        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+-        12, 12, 13, 13};
+-
+-/*
+-   Huffman code decoding is performed using a multi-level table lookup.
+-   The fastest way to decode is to simply build a lookup table whose
+-   size is determined by the longest code.  However, the time it takes
+-   to build this table can also be a factor if the data being decoded
+-   is not very long.  The most common codes are necessarily the
+-   shortest codes, so those codes dominate the decoding time, and hence
+-   the speed.  The idea is you can have a shorter table that decodes the
+-   shorter, more probable codes, and then point to subsidiary tables for
+-   the longer codes.  The time it costs to decode the longer codes is
+-   then traded against the time it takes to make longer tables.
+-
+-   This results of this trade are in the variables lbits and dbits
+-   below.  lbits is the number of bits the first level table for literal/
+-   length codes can decode in one step, and dbits is the same thing for
+-   the distance codes.  Subsequent tables are also less than or equal to
+-   those sizes.  These values may be adjusted either when all of the
+-   codes are shorter than that, in which case the longest code length in
+-   bits is used, or when the shortest code is *longer* than the requested
+-   table size, in which case the length of the shortest code in bits is
+-   used.
+-
+-   There are two different values for the two tables, since they code a
+-   different number of possibilities each.  The literal/length table
+-   codes 286 possible values, or in a flat code, a little over eight
+-   bits.  The distance table codes 30 possible values, or a little less
+-   than five bits, flat.  The optimum values for speed end up being
+-   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+-   The optimum values may differ though from machine to machine, and
+-   possibly even between compilers.  Your mileage may vary.
+- */
+-
+-
+-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+-#define BMAX 15         /* maximum bit length of any code */
+-#define N_MAX 288       /* maximum number of codes in any set */
+-
+-#ifdef DEBUG_ZLIB
+-  uInt inflate_hufts;
+-#endif
+-
+-local int huft_build(
+-	uIntf *b,               /* code lengths in bits (all assumed <= BMAX) */
+-	uInt n,                 /* number of codes (assumed <= N_MAX) */
+-	uInt s,                 /* number of simple-valued codes (0..s-1) */
+-	uIntf *d,               /* list of base values for non-simple codes */
+-	uIntf *e,               /* list of extra bits for non-simple codes */
+-	inflate_huft * FAR *t,  /* result: starting table */
+-	uIntf *m,               /* maximum lookup bits, returns actual */
+-	z_stream *zs            /* for zalloc function */
+-)
+-/* Given a list of code lengths and a maximum table size, make a set of
+-   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
+-   if the given code set is incomplete (the tables are still built in this
+-   case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
+-   over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
+-{
+-
+-  uInt a;                       /* counter for codes of length k */
+-  uInt c[BMAX+1];               /* bit length count table */
+-  uInt f;                       /* i repeats in table every f entries */
+-  int g;                        /* maximum code length */
+-  int h;                        /* table level */
+-  register uInt i;              /* counter, current code */
+-  register uInt j;              /* counter */
+-  register int k;               /* number of bits in current code */
+-  int l;                        /* bits per table (returned in m) */
+-  register uIntf *p;            /* pointer into c[], b[], or v[] */
+-  inflate_huft *q;              /* points to current table */
+-  struct inflate_huft_s r;      /* table entry for structure assignment */
+-  inflate_huft *u[BMAX];        /* table stack */
+-  uInt v[N_MAX];                /* values in order of bit length */
+-  register int w;               /* bits before this table == (l * h) */
+-  uInt x[BMAX+1];               /* bit offsets, then code stack */
+-  uIntf *xp;                    /* pointer into x */
+-  int y;                        /* number of dummy codes added */
+-  uInt z;                       /* number of entries in current table */
+-
+-
+-  /* Generate counts for each bit length */
+-  p = c;
+-#define C0 *p++ = 0;
+-#define C2 C0 C0 C0 C0
+-#define C4 C2 C2 C2 C2
+-  C4                            /* clear c[]--assume BMAX+1 is 16 */
+-  p = b;  i = n;
+-  do {
+-    c[*p++]++;                  /* assume all entries <= BMAX */
+-  } while (--i);
+-  if (c[0] == n)                /* null input--all zero length codes */
+-  {
+-    *t = (inflate_huft *)Z_NULL;
+-    *m = 0;
+-    return Z_DATA_ERROR;
+-  }
+-
+-
+-  /* Find minimum and maximum length, bound *m by those */
+-  l = *m;
+-  for (j = 1; j <= BMAX; j++)
+-    if (c[j])
+-      break;
+-  k = j;                        /* minimum code length */
+-  if ((uInt)l < j)
+-    l = j;
+-  for (i = BMAX; i; i--)
+-    if (c[i])
+-      break;
+-  g = i;                        /* maximum code length */
+-  if ((uInt)l > i)
+-    l = i;
+-  *m = l;
+-
+-
+-  /* Adjust last length count to fill out codes, if needed */
+-  for (y = 1 << j; j < i; j++, y <<= 1)
+-    if ((y -= c[j]) < 0)
+-      return Z_DATA_ERROR;
+-  if ((y -= c[i]) < 0)
+-    return Z_DATA_ERROR;
+-  c[i] += y;
+-
+-
+-  /* Generate starting offsets into the value table for each length */
+-  x[1] = j = 0;
+-  p = c + 1;  xp = x + 2;
+-  while (--i) {                 /* note that i == g from above */
+-    *xp++ = (j += *p++);
+-  }
+-
+-
+-  /* Make a table of values in order of bit lengths */
+-  p = b;  i = 0;
+-  do {
+-    if ((j = *p++) != 0)
+-      v[x[j]++] = i;
+-  } while (++i < n);
+-  n = x[g];			/* set n to length of v */
+-
+-
+-  /* Generate the Huffman codes and for each, make the table entries */
+-  x[0] = i = 0;                 /* first Huffman code is zero */
+-  p = v;                        /* grab values in bit order */
+-  h = -1;                       /* no tables yet--level -1 */
+-  w = -l;                       /* bits decoded == (l * h) */
+-  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
+-  q = (inflate_huft *)Z_NULL;   /* ditto */
+-  z = 0;                        /* ditto */
+-
+-  /* go through the bit lengths (k already is bits in shortest code) */
+-  for (; k <= g; k++)
+-  {
+-    a = c[k];
+-    while (a--)
+-    {
+-      /* here i is the Huffman code of length k bits for value *p */
+-      /* make tables up to required level */
+-      while (k > w + l)
+-      {
+-        h++;
+-        w += l;                 /* previous table always l bits */
+-
+-        /* compute minimum size table less than or equal to l bits */
+-        z = (z = g - w) > (uInt)l ? l : z;      /* table size upper limit */
+-        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+-        {                       /* too few codes for k-w bit table */
+-          f -= a + 1;           /* deduct codes from patterns left */
+-          xp = c + k;
+-          if (j < z)
+-            while (++j < z)     /* try smaller tables up to z bits */
+-            {
+-              if ((f <<= 1) <= *++xp)
+-                break;          /* enough codes to use up j bits */
+-              f -= *xp;         /* else deduct codes from patterns */
+-            }
+-        }
+-        z = 1 << j;             /* table entries for j-bit table */
+-
+-        /* allocate and link in new table */
+-        if ((q = (inflate_huft *)ZALLOC
+-             (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
+-        {
+-          if (h)
+-            inflate_trees_free(u[0], zs);
+-          return Z_MEM_ERROR;   /* not enough memory */
+-        }
+-	q->word.Nalloc = z + 1;
+-#ifdef DEBUG_ZLIB
+-        inflate_hufts += z + 1;
+-#endif
+-        *t = q + 1;             /* link to list for huft_free() */
+-        *(t = &(q->next)) = Z_NULL;
+-        u[h] = ++q;             /* table starts after link */
+-
+-        /* connect to last table, if there is one */
+-        if (h)
+-        {
+-          x[h] = i;             /* save pattern for backing up */
+-          r.bits = (Byte)l;     /* bits to dump before this table */
+-          r.exop = (Byte)j;     /* bits in this table */
+-          r.next = q;           /* pointer to this table */
+-          j = i >> (w - l);     /* (get around Turbo C bug) */
+-          u[h-1][j] = r;        /* connect to last table */
+-        }
+-      }
+-
+-      /* set up table entry in r */
+-      r.bits = (Byte)(k - w);
+-      if (p >= v + n)
+-        r.exop = 128 + 64;      /* out of values--invalid code */
+-      else if (*p < s)
+-      {
+-        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
+-        r.base = *p++;          /* simple code is just the value */
+-      }
+-      else
+-      {
+-        r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
+-        r.base = d[*p++ - s];
+-      }
+-
+-      /* fill code-like entries with r */
+-      f = 1 << (k - w);
+-      for (j = i >> w; j < z; j += f)
+-        q[j] = r;
+-
+-      /* backwards increment the k-bit code i */
+-      for (j = 1 << (k - 1); i & j; j >>= 1)
+-        i ^= j;
+-      i ^= j;
+-
+-      /* backup over finished tables */
+-      while ((i & ((1 << w) - 1)) != x[h])
+-      {
+-        h--;                    /* don't need to update q */
+-        w -= l;
+-      }
+-    }
+-  }
+-
+-
+-  /* Return Z_BUF_ERROR if we were given an incomplete table */
+-  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+-}
+-
+-
+-local int inflate_trees_bits(
+-	uIntf *c,               /* 19 code lengths */
+-	uIntf *bb,              /* bits tree desired/actual depth */
+-	inflate_huft * FAR *tb, /* bits tree result */
+-	z_stream *z             /* for zfree function */
+-)
+-{
+-  int r;
+-
+-  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
+-  if (r == Z_DATA_ERROR)
+-    z->msg = "oversubscribed dynamic bit lengths tree";
+-  else if (r == Z_BUF_ERROR)
+-  {
+-    inflate_trees_free(*tb, z);
+-    z->msg = "incomplete dynamic bit lengths tree";
+-    r = Z_DATA_ERROR;
+-  }
+-  return r;
+-}
+-
+-
+-local int inflate_trees_dynamic(
+-	uInt nl,                /* number of literal/length codes */
+-	uInt nd,                /* number of distance codes */
+-	uIntf *c,               /* that many (total) code lengths */
+-	uIntf *bl,              /* literal desired/actual bit depth */
+-	uIntf *bd,              /* distance desired/actual bit depth */
+-	inflate_huft * FAR *tl, /* literal/length tree result */
+-	inflate_huft * FAR *td, /* distance tree result */
+-	z_stream *z             /* for zfree function */
+-)
+-{
+-  int r;
+-
+-  /* build literal/length tree */
+-  if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
+-  {
+-    if (r == Z_DATA_ERROR)
+-      z->msg = "oversubscribed literal/length tree";
+-    else if (r == Z_BUF_ERROR)
+-    {
+-      inflate_trees_free(*tl, z);
+-      z->msg = "incomplete literal/length tree";
+-      r = Z_DATA_ERROR;
+-    }
+-    return r;
+-  }
+-
+-  /* build distance tree */
+-  if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
+-  {
+-    if (r == Z_DATA_ERROR)
+-      z->msg = "oversubscribed literal/length tree";
+-    else if (r == Z_BUF_ERROR) {
+-#ifdef PKZIP_BUG_WORKAROUND
+-      r = Z_OK;
+-    }
+-#else
+-      inflate_trees_free(*td, z);
+-      z->msg = "incomplete literal/length tree";
+-      r = Z_DATA_ERROR;
+-    }
+-    inflate_trees_free(*tl, z);
+-    return r;
+-#endif
+-  }
+-
+-  /* done */
+-  return Z_OK;
+-}
+-
+-
+-/* build fixed tables only once--keep them here */
+-local int fixed_lock = 0;
+-local int fixed_built = 0;
+-#define FIXEDH 530      /* number of hufts used by fixed tables */
+-local uInt fixed_left = FIXEDH;
+-local inflate_huft fixed_mem[FIXEDH];
+-local uInt fixed_bl;
+-local uInt fixed_bd;
+-local inflate_huft *fixed_tl;
+-local inflate_huft *fixed_td;
+-
+-
+-local voidpf falloc(
+-	voidpf q,       /* opaque pointer (not used) */
+-	uInt n,         /* number of items */
+-	uInt s          /* size of item */
+-)
+-{
+-  Assert(s == sizeof(inflate_huft) && n <= fixed_left,
+-         "inflate_trees falloc overflow");
+-  if (q) s++; /* to make some compilers happy */
+-  fixed_left -= n;
+-  return (voidpf)(fixed_mem + fixed_left);
+-}
+-
+-
+-local void ffree(
+-	voidpf q,
+-	voidpf p,
+-	uInt n
+-)
+-{
+-  Assert(0, "inflate_trees ffree called!");
+-  if (q) q = p; /* to make some compilers happy */
+-}
+-
+-
+-local int inflate_trees_fixed(
+-	uIntf *bl,               /* literal desired/actual bit depth */
+-	uIntf *bd,               /* distance desired/actual bit depth */
+-	inflate_huft * FAR *tl,  /* literal/length tree result */
+-	inflate_huft * FAR *td   /* distance tree result */
+-)
+-{
+-  /* build fixed tables if not built already--lock out other instances */
+-  while (++fixed_lock > 1)
+-    fixed_lock--;
+-  if (!fixed_built)
+-  {
+-    int k;              /* temporary variable */
+-    unsigned c[288];    /* length list for huft_build */
+-    z_stream z;         /* for falloc function */
+-
+-    /* set up fake z_stream for memory routines */
+-    z.zalloc = falloc;
+-    z.zfree = ffree;
+-    z.opaque = Z_NULL;
+-
+-    /* literal table */
+-    for (k = 0; k < 144; k++)
+-      c[k] = 8;
+-    for (; k < 256; k++)
+-      c[k] = 9;
+-    for (; k < 280; k++)
+-      c[k] = 7;
+-    for (; k < 288; k++)
+-      c[k] = 8;
+-    fixed_bl = 7;
+-    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
+-
+-    /* distance table */
+-    for (k = 0; k < 30; k++)
+-      c[k] = 5;
+-    fixed_bd = 5;
+-    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
+-
+-    /* done */
+-    fixed_built = 1;
+-  }
+-  fixed_lock--;
+-  *bl = fixed_bl;
+-  *bd = fixed_bd;
+-  *tl = fixed_tl;
+-  *td = fixed_td;
+-  return Z_OK;
+-}
+-
+-
+-local int inflate_trees_free(
+-	inflate_huft *t,        /* table to free */
+-	z_stream *z             /* for zfree function */
+-)
+-/* Free the malloc'ed tables built by huft_build(), which makes a linked
+-   list of the tables it made, with the links in a dummy first entry of
+-   each table. */
+-{
+-  register inflate_huft *p, *q;
+-
+-  /* Go through linked list, freeing from the malloced (t[-1]) address. */
+-  p = t;
+-  while (p != Z_NULL)
+-  {
+-    q = (--p)->next;
+-    ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
+-    p = q;
+-  } 
+-  return Z_OK;
+-}
+-
+-/*+++++*/
+-/* infcodes.c -- process literals and length/distance pairs
+- * Copyright (C) 1995 Mark Adler
+- * For conditions of distribution and use, see copyright notice in zlib.h 
+- */
+-
+-/* simplify the use of the inflate_huft type with some defines */
+-#define base more.Base
+-#define next more.Next
+-#define exop word.what.Exop
+-#define bits word.what.Bits
+-
+-/* inflate codes private state */
+-struct inflate_codes_state {
+-
+-  /* mode */
+-  enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+-      START,    /* x: set up for LEN */
+-      LEN,      /* i: get length/literal/eob next */
+-      LENEXT,   /* i: getting length extra (have base) */
+-      DIST,     /* i: get distance next */
+-      DISTEXT,  /* i: getting distance extra */
+-      COPY,     /* o: copying bytes in window, waiting for space */
+-      LIT,      /* o: got literal, waiting for output space */
+-      WASH,     /* o: got eob, possibly still output waiting */
+-      END,      /* x: got eob and all data flushed */
+-      BADCODE}  /* x: got error */
+-    mode;               /* current inflate_codes mode */
+-
+-  /* mode dependent information */
+-  uInt len;
+-  union {
+-    struct {
+-      inflate_huft *tree;       /* pointer into tree */
+-      uInt need;                /* bits needed */
+-    } code;             /* if LEN or DIST, where in tree */
+-    uInt lit;           /* if LIT, literal */
+-    struct {
+-      uInt get;                 /* bits to get for extra */
+-      uInt dist;                /* distance back to copy from */
+-    } copy;             /* if EXT or COPY, where and how much */
+-  } sub;                /* submode */
+-
+-  /* mode independent information */
+-  Byte lbits;           /* ltree bits decoded per branch */
+-  Byte dbits;           /* dtree bits decoder per branch */
+-  inflate_huft *ltree;          /* literal/length/eob tree */
+-  inflate_huft *dtree;          /* distance tree */
+-
+-};
+-
+-
+-local inflate_codes_statef *inflate_codes_new(
+-	uInt bl,
+-	uInt bd,
+-	inflate_huft *tl,
+-	inflate_huft *td,
+-	z_stream *z
+-)
+-{
+-  inflate_codes_statef *c;
+-
+-  if ((c = (inflate_codes_statef *)
+-       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+-  {
+-    c->mode = START;
+-    c->lbits = (Byte)bl;
+-    c->dbits = (Byte)bd;
+-    c->ltree = tl;
+-    c->dtree = td;
+-    Tracev((stderr, "inflate:       codes new\n"));
+-  }
+-  return c;
+-}
+-
+-
+-local int inflate_codes(
+-	inflate_blocks_statef *s,
+-	z_stream *z,
+-	int r
+-)
+-{
+-  uInt j;               /* temporary storage */
+-  inflate_huft *t;      /* temporary pointer */
+-  uInt e;               /* extra bits or operation */
+-  uLong b;              /* bit buffer */
+-  uInt k;               /* bits in bit buffer */
+-  Bytef *p;             /* input data pointer */
+-  uInt n;               /* bytes available there */
+-  Bytef *q;             /* output window write pointer */
+-  uInt m;               /* bytes to end of window or read pointer */
+-  Bytef *f;             /* pointer to copy strings from */
+-  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
+-
+-  /* copy input/output information to locals (UPDATE macro restores) */
+-  LOAD
+-
+-  /* process input and output based on current state */
+-  while (1) switch (c->mode)
+-  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+-    case START:         /* x: set up for LEN */
+-#ifndef SLOW
+-      if (m >= 258 && n >= 10)
+-      {
+-        UPDATE
+-        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+-        LOAD
+-        if (r != Z_OK)
+-        {
+-          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+-          break;
+-        }
+-      }
+-#endif /* !SLOW */
+-      c->sub.code.need = c->lbits;
+-      c->sub.code.tree = c->ltree;
+-      c->mode = LEN;
+-    case LEN:           /* i: get length/literal/eob next */
+-      j = c->sub.code.need;
+-      NEEDBITS(j)
+-      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+-      DUMPBITS(t->bits)
+-      e = (uInt)(t->exop);
+-      if (e == 0)               /* literal */
+-      {
+-        c->sub.lit = t->base;
+-        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+-                 "inflate:         literal '%c'\n" :
+-                 "inflate:         literal 0x%02x\n", t->base));
+-        c->mode = LIT;
+-        break;
+-      }
+-      if (e & 16)               /* length */
+-      {
+-        c->sub.copy.get = e & 15;
+-        c->len = t->base;
+-        c->mode = LENEXT;
+-        break;
+-      }
+-      if ((e & 64) == 0)        /* next table */
+-      {
+-        c->sub.code.need = e;
+-        c->sub.code.tree = t->next;
+-        break;
+-      }
+-      if (e & 32)               /* end of block */
+-      {
+-        Tracevv((stderr, "inflate:         end of block\n"));
+-        c->mode = WASH;
+-        break;
+-      }
+-      c->mode = BADCODE;        /* invalid code */
+-      z->msg = "invalid literal/length code";
+-      r = Z_DATA_ERROR;
+-      LEAVE
+-    case LENEXT:        /* i: getting length extra (have base) */
+-      j = c->sub.copy.get;
+-      NEEDBITS(j)
+-      c->len += (uInt)b & inflate_mask[j];
+-      DUMPBITS(j)
+-      c->sub.code.need = c->dbits;
+-      c->sub.code.tree = c->dtree;
+-      Tracevv((stderr, "inflate:         length %u\n", c->len));
+-      c->mode = DIST;
+-    case DIST:          /* i: get distance next */
+-      j = c->sub.code.need;
+-      NEEDBITS(j)
+-      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+-      DUMPBITS(t->bits)
+-      e = (uInt)(t->exop);
+-      if (e & 16)               /* distance */
+-      {
+-        c->sub.copy.get = e & 15;
+-        c->sub.copy.dist = t->base;
+-        c->mode = DISTEXT;
+-        break;
+-      }
+-      if ((e & 64) == 0)        /* next table */
+-      {
+-        c->sub.code.need = e;
+-        c->sub.code.tree = t->next;
+-        break;
+-      }
+-      c->mode = BADCODE;        /* invalid code */
+-      z->msg = "invalid distance code";
+-      r = Z_DATA_ERROR;
+-      LEAVE
+-    case DISTEXT:       /* i: getting distance extra */
+-      j = c->sub.copy.get;
+-      NEEDBITS(j)
+-      c->sub.copy.dist += (uInt)b & inflate_mask[j];
+-      DUMPBITS(j)
+-      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
+-      c->mode = COPY;
+-    case COPY:          /* o: copying bytes in window, waiting for space */
+-#ifndef __TURBOC__ /* Turbo C bug for following expression */
+-      f = (uInt)(q - s->window) < c->sub.copy.dist ?
+-          s->end - (c->sub.copy.dist - (q - s->window)) :
+-          q - c->sub.copy.dist;
+-#else
+-      f = q - c->sub.copy.dist;
+-      if ((uInt)(q - s->window) < c->sub.copy.dist)
+-        f = s->end - (c->sub.copy.dist - (q - s->window));
+-#endif
+-      while (c->len)
+-      {
+-        NEEDOUT
+-        OUTBYTE(*f++)
+-        if (f == s->end)
+-          f = s->window;
+-        c->len--;
+-      }
+-      c->mode = START;
+-      break;
+-    case LIT:           /* o: got literal, waiting for output space */
+-      NEEDOUT
+-      OUTBYTE(c->sub.lit)
+-      c->mode = START;
+-      break;
+-    case WASH:          /* o: got eob, possibly more output */
+-      FLUSH
+-      if (s->read != s->write)
+-        LEAVE
+-      c->mode = END;
+-    case END:
+-      r = Z_STREAM_END;
+-      LEAVE
+-    case BADCODE:       /* x: got error */
+-      r = Z_DATA_ERROR;
+-      LEAVE
+-    default:
+-      r = Z_STREAM_ERROR;
+-      LEAVE
+-  }
+-}
+-
+-
+-local void inflate_codes_free(
+-	inflate_codes_statef *c,
+-	z_stream *z
+-)
+-{
+-  ZFREE(z, c, sizeof(struct inflate_codes_state));
+-  Tracev((stderr, "inflate:       codes free\n"));
+-}
+-
+-/*+++++*/
+-/* inflate_util.c -- data and routines common to blocks and codes
+- * Copyright (C) 1995 Mark Adler
+- * For conditions of distribution and use, see copyright notice in zlib.h 
+- */
+-
+-/* copy as much as possible from the sliding window to the output area */
+-local int inflate_flush(
+-	inflate_blocks_statef *s,
+-	z_stream *z,
+-	int r
+-)
+-{
+-  uInt n;
+-  Bytef *p, *q;
+-
+-  /* local copies of source and destination pointers */
+-  p = z->next_out;
+-  q = s->read;
+-
+-  /* compute number of bytes to copy as far as end of window */
+-  n = (uInt)((q <= s->write ? s->write : s->end) - q);
+-  if (n > z->avail_out) n = z->avail_out;
+-  if (n && r == Z_BUF_ERROR) r = Z_OK;
+-
+-  /* update counters */
+-  z->avail_out -= n;
+-  z->total_out += n;
+-
+-  /* update check information */
+-  if (s->checkfn != Z_NULL)
+-    s->check = (*s->checkfn)(s->check, q, n);
+-
+-  /* copy as far as end of window */
+-  zmemcpy(p, q, n);
+-  p += n;
+-  q += n;
+-
+-  /* see if more to copy at beginning of window */
+-  if (q == s->end)
+-  {
+-    /* wrap pointers */
+-    q = s->window;
+-    if (s->write == s->end)
+-      s->write = s->window;
+-
+-    /* compute bytes to copy */
+-    n = (uInt)(s->write - q);
+-    if (n > z->avail_out) n = z->avail_out;
+-    if (n && r == Z_BUF_ERROR) r = Z_OK;
+-
+-    /* update counters */
+-    z->avail_out -= n;
+-    z->total_out += n;
+-
+-    /* update check information */
+-    if (s->checkfn != Z_NULL)
+-      s->check = (*s->checkfn)(s->check, q, n);
+-
+-    /* copy */
+-    zmemcpy(p, q, n);
+-    p += n;
+-    q += n;
+-  }
+-
+-  /* update pointers */
+-  z->next_out = p;
+-  s->read = q;
+-
+-  /* done */
+-  return r;
+-}
+-
+-
+-/*+++++*/
+-/* inffast.c -- process literals and length/distance pairs fast
+- * Copyright (C) 1995 Mark Adler
+- * For conditions of distribution and use, see copyright notice in zlib.h 
+- */
+-
+-/* simplify the use of the inflate_huft type with some defines */
+-#define base more.Base
+-#define next more.Next
+-#define exop word.what.Exop
+-#define bits word.what.Bits
+-
+-/* macros for bit input with no checking and for returning unused bytes */
+-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+-#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
+-
+-/* Called with number of bytes left to write in window at least 258
+-   (the maximum string length) and number of input bytes available
+-   at least ten.  The ten bytes are six bytes for the longest length/
+-   distance pair plus four bytes for overloading the bit buffer. */
+-
+-local int inflate_fast(
+-	uInt bl,
+-	uInt bd,
+-	inflate_huft *tl,
+-	inflate_huft *td,
+-	inflate_blocks_statef *s,
+-	z_stream *z
+-)
+-{
+-  inflate_huft *t;      /* temporary pointer */
+-  uInt e;               /* extra bits or operation */
+-  uLong b;              /* bit buffer */
+-  uInt k;               /* bits in bit buffer */
+-  Bytef *p;             /* input data pointer */
+-  uInt n;               /* bytes available there */
+-  Bytef *q;             /* output window write pointer */
+-  uInt m;               /* bytes to end of window or read pointer */
+-  uInt ml;              /* mask for literal/length tree */
+-  uInt md;              /* mask for distance tree */
+-  uInt c;               /* bytes to copy */
+-  uInt d;               /* distance back to copy from */
+-  Bytef *r;             /* copy source pointer */
+-
+-  /* load input, output, bit values */
+-  LOAD
+-
+-  /* initialize masks */
+-  ml = inflate_mask[bl];
+-  md = inflate_mask[bd];
+-
+-  /* do until not enough input or output space for fast loop */
+-  do {                          /* assume called with m >= 258 && n >= 10 */
+-    /* get literal/length code */
+-    GRABBITS(20)                /* max bits for literal/length code */
+-    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+-    {
+-      DUMPBITS(t->bits)
+-      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+-                "inflate:         * literal '%c'\n" :
+-                "inflate:         * literal 0x%02x\n", t->base));
+-      *q++ = (Byte)t->base;
+-      m--;
+-      continue;
+-    }
+-    do {
+-      DUMPBITS(t->bits)
+-      if (e & 16)
+-      {
+-        /* get extra bits for length */
+-        e &= 15;
+-        c = t->base + ((uInt)b & inflate_mask[e]);
+-        DUMPBITS(e)
+-        Tracevv((stderr, "inflate:         * length %u\n", c));
+-
+-        /* decode distance base of block to copy */
+-        GRABBITS(15);           /* max bits for distance code */
+-        e = (t = td + ((uInt)b & md))->exop;
+-        do {
+-          DUMPBITS(t->bits)
+-          if (e & 16)
+-          {
+-            /* get extra bits to add to distance base */
+-            e &= 15;
+-            GRABBITS(e)         /* get extra bits (up to 13) */
+-            d = t->base + ((uInt)b & inflate_mask[e]);
+-            DUMPBITS(e)
+-            Tracevv((stderr, "inflate:         * distance %u\n", d));
+-
+-            /* do the copy */
+-            m -= c;
+-            if ((uInt)(q - s->window) >= d)     /* offset before dest */
+-            {                                   /*  just copy */
+-              r = q - d;
+-              *q++ = *r++;  c--;        /* minimum count is three, */
+-              *q++ = *r++;  c--;        /*  so unroll loop a little */
+-            }
+-            else                        /* else offset after destination */
+-            {
+-              e = d - (q - s->window);  /* bytes from offset to end */
+-              r = s->end - e;           /* pointer to offset */
+-              if (c > e)                /* if source crosses, */
+-              {
+-                c -= e;                 /* copy to end of window */
+-                do {
+-                  *q++ = *r++;
+-                } while (--e);
+-                r = s->window;          /* copy rest from start of window */
+-              }
+-            }
+-            do {                        /* copy all or what's left */
+-              *q++ = *r++;
+-            } while (--c);
+-            break;
+-          }
+-          else if ((e & 64) == 0)
+-            e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
+-          else
+-          {
+-            z->msg = "invalid distance code";
+-            UNGRAB
+-            UPDATE
+-            return Z_DATA_ERROR;
+-          }
+-        } while (1);
+-        break;
+-      }
+-      if ((e & 64) == 0)
+-      {
+-        if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
+-        {
+-          DUMPBITS(t->bits)
+-          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+-                    "inflate:         * literal '%c'\n" :
+-                    "inflate:         * literal 0x%02x\n", t->base));
+-          *q++ = (Byte)t->base;
+-          m--;
+-          break;
+-        }
+-      }
+-      else if (e & 32)
+-      {
+-        Tracevv((stderr, "inflate:         * end of block\n"));
+-        UNGRAB
+-        UPDATE
+-        return Z_STREAM_END;
+-      }
+-      else
+-      {
+-        z->msg = "invalid literal/length code";
+-        UNGRAB
+-        UPDATE
+-        return Z_DATA_ERROR;
+-      }
+-    } while (1);
+-  } while (m >= 258 && n >= 10);
+-
+-  /* not enough input or output--restore pointers and return */
+-  UNGRAB
+-  UPDATE
+-  return Z_OK;
+-}
+-
+-
+-/*+++++*/
+-/* zutil.c -- target dependent utility functions for the compression library
+- * Copyright (C) 1995 Jean-loup Gailly.
+- * For conditions of distribution and use, see copyright notice in zlib.h 
+- */
+-
+-/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
+-
+-char *zlib_version = ZLIB_VERSION;
+-
+-char *z_errmsg[] = {
+-"stream end",          /* Z_STREAM_END    1 */
+-"",                    /* Z_OK            0 */
+-"file error",          /* Z_ERRNO        (-1) */
+-"stream error",        /* Z_STREAM_ERROR (-2) */
+-"data error",          /* Z_DATA_ERROR   (-3) */
+-"insufficient memory", /* Z_MEM_ERROR    (-4) */
+-"buffer error",        /* Z_BUF_ERROR    (-5) */
+-""};
+-
+-
+-/*+++++*/
+-/* adler32.c -- compute the Adler-32 checksum of a data stream
+- * Copyright (C) 1995 Mark Adler
+- * For conditions of distribution and use, see copyright notice in zlib.h 
+- */
+-
+-/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
+-
+-#define BASE 65521L /* largest prime smaller than 65536 */
+-#define NMAX 5552
+-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+-
+-#define DO1(buf)  {s1 += *buf++; s2 += s1;}
+-#define DO2(buf)  DO1(buf); DO1(buf);
+-#define DO4(buf)  DO2(buf); DO2(buf);
+-#define DO8(buf)  DO4(buf); DO4(buf);
+-#define DO16(buf) DO8(buf); DO8(buf);
+-
+-/* ========================================================================= */
+-uLong adler32(
+-	uLong adler,
+-	Bytef *buf,
+-	uInt len
+-)
+-{
+-    unsigned long s1 = adler & 0xffff;
+-    unsigned long s2 = (adler >> 16) & 0xffff;
+-    int k;
+-
+-    if (buf == Z_NULL) return 1L;
+-
+-    while (len > 0) {
+-        k = len < NMAX ? len : NMAX;
+-        len -= k;
+-        while (k >= 16) {
+-            DO16(buf);
+-            k -= 16;
+-        }
+-        if (k != 0) do {
+-            DO1(buf);
+-        } while (--k);
+-        s1 %= BASE;
+-        s2 %= BASE;
+-    }
+-    return (s2 << 16) | s1;
+-}
+diff --git a/arch/ppc64/boot/zlib.h b/arch/ppc64/boot/zlib.h
+deleted file mode 100644
+--- a/arch/ppc64/boot/zlib.h
++++ /dev/null
+@@ -1,432 +0,0 @@
+-/*		*/
+-
+-/*
+- * This file is derived from zlib.h and zconf.h from the zlib-0.95
+- * distribution by Jean-loup Gailly and Mark Adler, with some additions
+- * by Paul Mackerras to aid in implementing Deflate compression and
+- * decompression for PPP packets.
+- */
+-
+-/*
+- *  ==FILEVERSION 960122==
+- *
+- * This marker is used by the Linux installation script to determine
+- * whether an up-to-date version of this file is already installed.
+- */
+-
+-/* zlib.h -- interface of the 'zlib' general purpose compression library
+-  version 0.95, Aug 16th, 1995.
+-
+-  Copyright (C) 1995 Jean-loup Gailly and Mark Adler
+-
+-  This software is provided 'as-is', without any express or implied
+-  warranty.  In no event will the authors be held liable for any damages
+-  arising from the use of this software.
+-
+-  Permission is granted to anyone to use this software for any purpose,
+-  including commercial applications, and to alter it and redistribute it
+-  freely, subject to the following restrictions:
+-
+-  1. The origin of this software must not be misrepresented; you must not
+-     claim that you wrote the original software. If you use this software
+-     in a product, an acknowledgment in the product documentation would be
+-     appreciated but is not required.
+-  2. Altered source versions must be plainly marked as such, and must not be
+-     misrepresented as being the original software.
+-  3. This notice may not be removed or altered from any source distribution.
+-
+-  Jean-loup Gailly        Mark Adler
+-  gzip at prep.ai.mit.edu    madler at alumni.caltech.edu
+- */
+-
+-#ifndef _ZLIB_H
+-#define _ZLIB_H
+-
+-/* #include "zconf.h" */	/* included directly here */
+-
+-/* zconf.h -- configuration of the zlib compression library
+- * Copyright (C) 1995 Jean-loup Gailly.
+- * For conditions of distribution and use, see copyright notice in zlib.h 
+- */
+-
+-/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
+-
+-/*
+-     The library does not install any signal handler. It is recommended to
+-  add at least a handler for SIGSEGV when decompressing; the library checks
+-  the consistency of the input data whenever possible but may go nuts
+-  for some forms of corrupted input.
+- */
+-
+-/*
+- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+- * than 64k bytes at a time (needed on systems with 16-bit int).
+- * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
+- * at addresses which are not a multiple of their size.
+- * Under DOS, -DFAR=far or -DFAR=__far may be needed.
+- */
+-
+-#ifndef STDC
+-#  if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
+-#    define STDC
+-#  endif
+-#endif
+-
+-#ifdef	__MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
+-#  include <unix.h>
+-#endif
+-
+-/* Maximum value for memLevel in deflateInit2 */
+-#ifndef MAX_MEM_LEVEL
+-#  ifdef MAXSEG_64K
+-#    define MAX_MEM_LEVEL 8
+-#  else
+-#    define MAX_MEM_LEVEL 9
+-#  endif
+-#endif
+-
+-#ifndef FAR
+-#  define FAR
+-#endif
+-
+-/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
+-#ifndef MAX_WBITS
+-#  define MAX_WBITS   15 /* 32K LZ77 window */
+-#endif
+-
+-/* The memory requirements for deflate are (in bytes):
+-            1 << (windowBits+2)   +  1 << (memLevel+9)
+- that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+- plus a few kilobytes for small objects. For example, if you want to reduce
+- the default memory requirements from 256K to 128K, compile with
+-     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+- Of course this will generally degrade compression (there's no free lunch).
+-
+-   The memory requirements for inflate are (in bytes) 1 << windowBits
+- that is, 32K for windowBits=15 (default value) plus a few kilobytes
+- for small objects.
+-*/
+-
+-                        /* Type declarations */
+-
+-#ifndef OF /* function prototypes */
+-#  ifdef STDC
+-#    define OF(args)  args
+-#  else
+-#    define OF(args)  ()
+-#  endif
+-#endif
+-
+-typedef unsigned char  Byte;  /* 8 bits */
+-typedef unsigned int   uInt;  /* 16 bits or more */
+-typedef unsigned long  uLong; /* 32 bits or more */
+-
+-typedef Byte FAR Bytef;
+-typedef char FAR charf;
+-typedef int FAR intf;
+-typedef uInt FAR uIntf;
+-typedef uLong FAR uLongf;
+-
+-#ifdef STDC
+-   typedef void FAR *voidpf;
+-   typedef void     *voidp;
+-#else
+-   typedef Byte FAR *voidpf;
+-   typedef Byte     *voidp;
+-#endif
+-
+-/* end of original zconf.h */
+-
+-#define ZLIB_VERSION "0.95P"
+-
+-/* 
+-     The 'zlib' compression library provides in-memory compression and
+-  decompression functions, including integrity checks of the uncompressed
+-  data.  This version of the library supports only one compression method
+-  (deflation) but other algorithms may be added later and will have the same
+-  stream interface.
+-
+-     For compression the application must provide the output buffer and
+-  may optionally provide the input buffer for optimization. For decompression,
+-  the application must provide the input buffer and may optionally provide
+-  the output buffer for optimization.
+-
+-     Compression can be done in a single step if the buffers are large
+-  enough (for example if an input file is mmap'ed), or can be done by
+-  repeated calls of the compression function.  In the latter case, the
+-  application must provide more input and/or consume the output
+-  (providing more output space) before each call.
+-*/
+-
+-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+-typedef void   (*free_func)  OF((voidpf opaque, voidpf address, uInt nbytes));
+-
+-struct internal_state;
+-
+-typedef struct z_stream_s {
+-    Bytef    *next_in;  /* next input byte */
+-    uInt     avail_in;  /* number of bytes available at next_in */
+-    uLong    total_in;  /* total nb of input bytes read so far */
+-
+-    Bytef    *next_out; /* next output byte should be put there */
+-    uInt     avail_out; /* remaining free space at next_out */
+-    uLong    total_out; /* total nb of bytes output so far */
+-
+-    char     *msg;      /* last error message, NULL if no error */
+-    struct internal_state FAR *state; /* not visible by applications */
+-
+-    alloc_func zalloc;  /* used to allocate the internal state */
+-    free_func  zfree;   /* used to free the internal state */
+-    voidp      opaque;  /* private data object passed to zalloc and zfree */
+-
+-    Byte     data_type; /* best guess about the data type: ascii or binary */
+-
+-} z_stream;
+-
+-/*
+-   The application must update next_in and avail_in when avail_in has
+-   dropped to zero. It must update next_out and avail_out when avail_out
+-   has dropped to zero. The application must initialize zalloc, zfree and
+-   opaque before calling the init function. All other fields are set by the
+-   compression library and must not be updated by the application.
+-
+-   The opaque value provided by the application will be passed as the first
+-   parameter for calls of zalloc and zfree. This can be useful for custom
+-   memory management. The compression library attaches no meaning to the
+-   opaque value.
+-
+-   zalloc must return Z_NULL if there is not enough memory for the object.
+-   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+-   exactly 65536 bytes, but will not be required to allocate more than this
+-   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+-   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+-   have their offset normalized to zero. The default allocation function
+-   provided by this library ensures this (see zutil.c). To reduce memory
+-   requirements and avoid any allocation of 64K objects, at the expense of
+-   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+-
+-   The fields total_in and total_out can be used for statistics or
+-   progress reports. After compression, total_in holds the total size of
+-   the uncompressed data and may be saved for use in the decompressor
+-   (particularly if the decompressor wants to decompress everything in
+-   a single step).
+-*/
+-
+-                        /* constants */
+-
+-#define Z_NO_FLUSH      0
+-#define Z_PARTIAL_FLUSH 1
+-#define Z_FULL_FLUSH    2
+-#define Z_SYNC_FLUSH    3 /* experimental: partial_flush + byte align */
+-#define Z_FINISH        4
+-#define Z_PACKET_FLUSH	5
+-/* See deflate() below for the usage of these constants */
+-
+-#define Z_OK            0
+-#define Z_STREAM_END    1
+-#define Z_ERRNO        (-1)
+-#define Z_STREAM_ERROR (-2)
+-#define Z_DATA_ERROR   (-3)
+-#define Z_MEM_ERROR    (-4)
+-#define Z_BUF_ERROR    (-5)
+-/* error codes for the compression/decompression functions */
+-
+-#define Z_BEST_SPEED             1
+-#define Z_BEST_COMPRESSION       9
+-#define Z_DEFAULT_COMPRESSION  (-1)
+-/* compression levels */
+-
+-#define Z_FILTERED            1
+-#define Z_HUFFMAN_ONLY        2
+-#define Z_DEFAULT_STRATEGY    0
+-
+-#define Z_BINARY   0
+-#define Z_ASCII    1
+-#define Z_UNKNOWN  2
+-/* Used to set the data_type field */
+-
+-#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+-
+-extern char *zlib_version;
+-/* The application can compare zlib_version and ZLIB_VERSION for consistency.
+-   If the first character differs, the library code actually used is
+-   not compatible with the zlib.h header file used by the application.
+- */
+-
+-                        /* basic functions */
+-
+-extern int inflateInit OF((z_stream *strm));
+-/* 
+-     Initializes the internal stream state for decompression. The fields
+-   zalloc and zfree must be initialized before by the caller.  If zalloc and
+-   zfree are set to Z_NULL, inflateInit updates them to use default allocation
+-   functions.
+-
+-     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+-   enough memory.  msg is set to null if there is no error message.
+-   inflateInit does not perform any decompression: this will be done by
+-   inflate().
+-*/
+-
+-
+-extern int inflate OF((z_stream *strm, int flush));
+-/*
+-  Performs one or both of the following actions:
+-
+-  - Decompress more input starting at next_in and update next_in and avail_in
+-    accordingly. If not all input can be processed (because there is not
+-    enough room in the output buffer), next_in is updated and processing
+-    will resume at this point for the next call of inflate().
+-
+-  - Provide more output starting at next_out and update next_out and avail_out
+-    accordingly.  inflate() always provides as much output as possible
+-    (until there is no more input data or no more space in the output buffer).
+-
+-  Before the call of inflate(), the application should ensure that at least
+-  one of the actions is possible, by providing more input and/or consuming
+-  more output, and updating the next_* and avail_* values accordingly.
+-  The application can consume the uncompressed output when it wants, for
+-  example when the output buffer is full (avail_out == 0), or after each
+-  call of inflate().
+-
+-    If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
+-  inflate flushes as much output as possible to the output buffer. The
+-  flushing behavior of inflate is not specified for values of the flush
+-  parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
+-  current implementation actually flushes as much output as possible
+-  anyway.  For Z_PACKET_FLUSH, inflate checks that once all the input data
+-  has been consumed, it is expecting to see the length field of a stored
+-  block; if not, it returns Z_DATA_ERROR.
+-
+-    inflate() should normally be called until it returns Z_STREAM_END or an
+-  error. However if all decompression is to be performed in a single step
+-  (a single call of inflate), the parameter flush should be set to
+-  Z_FINISH. In this case all pending input is processed and all pending
+-  output is flushed; avail_out must be large enough to hold all the
+-  uncompressed data. (The size of the uncompressed data may have been saved
+-  by the compressor for this purpose.) The next operation on this stream must
+-  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+-  is never required, but can be used to inform inflate that a faster routine
+-  may be used for the single inflate() call.
+-
+-    inflate() returns Z_OK if some progress has been made (more input
+-  processed or more output produced), Z_STREAM_END if the end of the
+-  compressed data has been reached and all uncompressed output has been
+-  produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
+-  the stream structure was inconsistent (for example if next_in or next_out
+-  was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
+-  progress is possible or if there was not enough room in the output buffer
+-  when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
+-  call inflateSync to look for a good compression block.  */
+-
+-
+-extern int inflateEnd OF((z_stream *strm));
+-/*
+-     All dynamically allocated data structures for this stream are freed.
+-   This function discards any unprocessed input and does not flush any
+-   pending output.
+-
+-     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+-   was inconsistent. In the error case, msg may be set but then points to a
+-   static string (which must not be deallocated).
+-*/
+-
+-                        /* advanced functions */
+-
+-extern int inflateInit2 OF((z_stream *strm,
+-                            int  windowBits));
+-/*   
+-     This is another version of inflateInit with more compression options. The
+-   fields next_out, zalloc and zfree must be initialized before by the caller.
+-
+-     The windowBits parameter is the base two logarithm of the maximum window
+-   size (the size of the history buffer).  It should be in the range 8..15 for
+-   this version of the library (the value 16 will be allowed soon). The
+-   default value is 15 if inflateInit is used instead. If a compressed stream
+-   with a larger window size is given as input, inflate() will return with
+-   the error code Z_DATA_ERROR instead of trying to allocate a larger window.
+-
+-     If next_out is not null, the library will use this buffer for the history
+-   buffer; the buffer must either be large enough to hold the entire output
+-   data, or have at least 1<<windowBits bytes.  If next_out is null, the
+-   library will allocate its own buffer (and leave next_out null). next_in
+-   need not be provided here but must be provided by the application for the
+-   next call of inflate().
+-
+-     If the history buffer is provided by the application, next_out must
+-   never be changed by the application since the decompressor maintains
+-   history information inside this buffer from call to call; the application
+-   can only reset next_out to the beginning of the history buffer when
+-   avail_out is zero and all output has been consumed.
+-
+-      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
+-   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
+-   windowBits < 8). msg is set to null if there is no error message.
+-   inflateInit2 does not perform any decompression: this will be done by
+-   inflate().
+-*/
+-
+-extern int inflateSync OF((z_stream *strm));
+-/* 
+-    Skips invalid compressed data until the special marker (see deflate()
+-  above) can be found, or until all available input is skipped. No output
+-  is provided.
+-
+-    inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
+-  if no more input was provided, Z_DATA_ERROR if no marker has been found,
+-  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+-  case, the application may save the current current value of total_in which
+-  indicates where valid compressed data was found. In the error case, the
+-  application may repeatedly call inflateSync, providing more input each time,
+-  until success or end of the input data.
+-*/
+-
+-extern int inflateReset OF((z_stream *strm));
+-/*
+-     This function is equivalent to inflateEnd followed by inflateInit,
+-   but does not free and reallocate all the internal decompression state.
+-   The stream will keep attributes that may have been set by inflateInit2.
+-
+-      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+-   stream state was inconsistent (such as zalloc or state being NULL).
+-*/
+-
+-extern int inflateIncomp OF((z_stream *strm));
+-/*
+-     This function adds the data at next_in (avail_in bytes) to the output
+-   history without performing any output.  There must be no pending output,
+-   and the decompressor must be expecting to see the start of a block.
+-   Calling this function is equivalent to decompressing a stored block
+-   containing the data at next_in (except that the data is not output).
+-*/
+-
+-                        /* checksum functions */
+-
+-/*
+-     This function is not related to compression but is exported
+-   anyway because it might be useful in applications using the
+-   compression library.
+-*/
+-
+-extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
+-
+-/*
+-     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+-   return the updated checksum. If buf is NULL, this function returns
+-   the required initial value for the checksum.
+-   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+-   much faster. Usage example:
+-
+-     uLong adler = adler32(0L, Z_NULL, 0);
+-
+-     while (read_buffer(buffer, length) != EOF) {
+-       adler = adler32(adler, buffer, length);
+-     }
+-     if (adler != original_adler) error();
+-*/
+-
+-#ifndef _Z_UTIL_H
+-    struct internal_state {int dummy;}; /* hack for buggy compilers */
+-#endif
+-
+-#endif /* _ZLIB_H */
+diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig
+--- a/arch/ppc64/defconfig
++++ b/arch/ppc64/defconfig
+@@ -1318,7 +1318,7 @@ CONFIG_MSDOS_PARTITION=y
+ #
+ CONFIG_NLS=y
+ CONFIG_NLS_DEFAULT="iso8859-1"
+-CONFIG_NLS_CODEPAGE_437=m
++CONFIG_NLS_CODEPAGE_437=y
+ CONFIG_NLS_CODEPAGE_737=m
+ CONFIG_NLS_CODEPAGE_775=m
+ CONFIG_NLS_CODEPAGE_850=m
+@@ -1342,7 +1342,7 @@ 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_1=y
+ CONFIG_NLS_ISO8859_2=m
+ CONFIG_NLS_ISO8859_3=m
+ CONFIG_NLS_ISO8859_4=m
+diff --git a/arch/ppc64/kernel/HvCall.c b/arch/ppc64/kernel/HvCall.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/HvCall.c
++++ /dev/null
+@@ -1,36 +0,0 @@
+-/*
+- * HvCall.c
+- * Copyright (C) 2001  Mike Corrigan 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.
+- */
+-
+-#include <asm/page.h>
+-#include <asm/abs_addr.h>
+-#include <asm/iSeries/HvCall.h>
+-#include <asm/iSeries/HvCallSc.h>
+-#include <asm/iSeries/HvTypes.h>
+-
+-
+-void HvCall_writeLogBuffer(const void *buffer, u64 len)
+-{
+-	struct HvLpBufferList hv_buf;
+-	u64 left_this_page;
+-	u64 cur = virt_to_abs(buffer);
+-
+-	while (len) {
+-		hv_buf.addr = cur;
+-		left_this_page = ((cur & PAGE_MASK) + PAGE_SIZE) - cur;
+-		if (left_this_page > len)
+-			left_this_page = len;
+-		hv_buf.len = left_this_page;
+-		len -= left_this_page;
+-		HvCall2(HvCallBaseWriteLogBuffer,
+-				virt_to_abs(&hv_buf),
+-				left_this_page);
+-		cur = (cur & PAGE_MASK) + PAGE_SIZE;
+-	}
+-}
+diff --git a/arch/ppc64/kernel/HvLpConfig.c b/arch/ppc64/kernel/HvLpConfig.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/HvLpConfig.c
++++ /dev/null
+@@ -1,27 +0,0 @@
+-/*
+- * HvLpConfig.c
+- * Copyright (C) 2001  Kyle A. Lucke, 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
+- */
+-
+-#include <linux/module.h>
+-#include <asm/iSeries/HvLpConfig.h>
+-
+-HvLpIndex HvLpConfig_getLpIndex_outline(void)
+-{
+-	return HvLpConfig_getLpIndex();
+-}
+-EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline);
+diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/HvLpEvent.c
++++ /dev/null
+@@ -1,88 +0,0 @@
+-/*
+- * Copyright 2001 Mike Corrigan IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-#include <linux/stddef.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <asm/system.h>
+-#include <asm/iSeries/HvLpEvent.h>
+-#include <asm/iSeries/HvCallEvent.h>
+-#include <asm/iSeries/ItLpNaca.h>
+-
+-/* Array of LpEvent handler functions */
+-LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
+-unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
+-
+-/* Register a handler for an LpEvent type */
+-
+-int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler )
+-{
+-	int rc = 1;
+-	if ( eventType < HvLpEvent_Type_NumTypes ) {
+-		lpEventHandler[eventType] = handler;
+-		rc = 0;
+-	}
+-	return rc;
+-	
+-}
+-
+-int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
+-{
+-	int rc = 1;
+-
+-	might_sleep();
+-
+-	if ( eventType < HvLpEvent_Type_NumTypes ) {
+-		if ( !lpEventHandlerPaths[eventType] ) {
+-			lpEventHandler[eventType] = NULL;
+-			rc = 0;
+-
+-			/* We now sleep until all other CPUs have scheduled. This ensures that
+-			 * the deletion is seen by all other CPUs, and that the deleted handler
+-			 * isn't still running on another CPU when we return. */
+-			synchronize_rcu();
+-		}
+-	}
+-	return rc;
+-}
+-EXPORT_SYMBOL(HvLpEvent_registerHandler);
+-EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
+-
+-/* (lpIndex is the partition index of the target partition.  
+- * needed only for VirtualIo, VirtualLan and SessionMgr.  Zero
+- * indicates to use our partition index - for the other types)
+- */
+-int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
+-{
+-	int rc = 1;
+-	if ( eventType < HvLpEvent_Type_NumTypes &&
+-	     lpEventHandler[eventType] ) {
+-		if ( lpIndex == 0 )
+-			lpIndex = itLpNaca.xLpIndex;
+-		HvCallEvent_openLpEventPath( lpIndex, eventType );
+-		++lpEventHandlerPaths[eventType];
+-		rc = 0;
+-	}
+-	return rc;
+-}
+-
+-int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
+-{
+-	int rc = 1;
+-	if ( eventType < HvLpEvent_Type_NumTypes &&
+-	     lpEventHandler[eventType] &&
+-	     lpEventHandlerPaths[eventType] ) {
+-		if ( lpIndex == 0 )
+-			lpIndex = itLpNaca.xLpIndex;
+-		HvCallEvent_closeLpEventPath( lpIndex, eventType );
+-		--lpEventHandlerPaths[eventType];
+-		rc = 0;
+-	}
+-	return rc;
+-}
+-
+diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/ItLpQueue.c
++++ /dev/null
+@@ -1,262 +0,0 @@
+-/*
+- * ItLpQueue.c
+- * Copyright (C) 2001 Mike Corrigan  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.
+- */
+-
+-#include <linux/stddef.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/bootmem.h>
+-#include <linux/seq_file.h>
+-#include <linux/proc_fs.h>
+-#include <asm/system.h>
+-#include <asm/paca.h>
+-#include <asm/iSeries/ItLpQueue.h>
+-#include <asm/iSeries/HvLpEvent.h>
+-#include <asm/iSeries/HvCallEvent.h>
+-
+-/*
+- * The LpQueue is used to pass event data from the hypervisor to
+- * the partition.  This is where I/O interrupt events are communicated.
+- *
+- * It is written to by the hypervisor so cannot end up in the BSS.
+- */
+-struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data")));
+-
+-DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts);
+-
+-static char *event_types[HvLpEvent_Type_NumTypes] = {
+-	"Hypervisor",
+-	"Machine Facilities",
+-	"Session Manager",
+-	"SPD I/O",
+-	"Virtual Bus",
+-	"PCI I/O",
+-	"RIO I/O",
+-	"Virtual Lan",
+-	"Virtual I/O"
+-};
+-
+-/* Array of LpEvent handler functions */
+-extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
+-
+-static struct HvLpEvent * get_next_hvlpevent(void)
+-{
+-	struct HvLpEvent * event;
+-	event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
+-
+-	if (event->xFlags.xValid) {
+-		/* rmb() needed only for weakly consistent machines (regatta) */
+-		rmb();
+-		/* Set pointer to next potential event */
+-		hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 +
+-				LpEventAlign) / LpEventAlign) * LpEventAlign;
+-
+-		/* Wrap to beginning if no room at end */
+-		if (hvlpevent_queue.xSlicCurEventPtr >
+-				hvlpevent_queue.xSlicLastValidEventPtr) {
+-			hvlpevent_queue.xSlicCurEventPtr =
+-				hvlpevent_queue.xSlicEventStackPtr;
+-		}
+-	} else {
+-		event = NULL;
+-	}
+-
+-	return event;
+-}
+-
+-static unsigned long spread_lpevents = NR_CPUS;
+-
+-int hvlpevent_is_pending(void)
+-{
+-	struct HvLpEvent *next_event;
+-
+-	if (smp_processor_id() >= spread_lpevents)
+-		return 0;
+-
+-	next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
+-
+-	return next_event->xFlags.xValid |
+-		hvlpevent_queue.xPlicOverflowIntPending;
+-}
+-
+-static void hvlpevent_clear_valid(struct HvLpEvent * event)
+-{
+-	/* Tell the Hypervisor that we're done with this event.
+-	 * Also clear bits within this event that might look like valid bits.
+-	 * ie. on 64-byte boundaries.
+-	 */
+-	struct HvLpEvent *tmp;
+-	unsigned extra = ((event->xSizeMinus1 + LpEventAlign) /
+-						 LpEventAlign) - 1;
+-
+-	switch (extra) {
+-	case 3:
+-		tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign);
+-		tmp->xFlags.xValid = 0;
+-	case 2:
+-		tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign);
+-		tmp->xFlags.xValid = 0;
+-	case 1:
+-		tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign);
+-		tmp->xFlags.xValid = 0;
+-	}
+-
+-	mb();
+-
+-	event->xFlags.xValid = 0;
+-}
+-
+-void process_hvlpevents(struct pt_regs *regs)
+-{
+-	struct HvLpEvent * event;
+-
+-	/* If we have recursed, just return */
+-	if (!spin_trylock(&hvlpevent_queue.lock))
+-		return;
+-
+-	for (;;) {
+-		event = get_next_hvlpevent();
+-		if (event) {
+-			/* Call appropriate handler here, passing
+-			 * a pointer to the LpEvent.  The handler
+-			 * must make a copy of the LpEvent if it
+-			 * needs it in a bottom half. (perhaps for
+-			 * an ACK)
+-			 *
+-			 *  Handlers are responsible for ACK processing
+-			 *
+-			 * The Hypervisor guarantees that LpEvents will
+-			 * only be delivered with types that we have
+-			 * registered for, so no type check is necessary
+-			 * here!
+-			 */
+-			if (event->xType < HvLpEvent_Type_NumTypes)
+-				__get_cpu_var(hvlpevent_counts)[event->xType]++;
+-			if (event->xType < HvLpEvent_Type_NumTypes &&
+-					lpEventHandler[event->xType])
+-				lpEventHandler[event->xType](event, regs);
+-			else
+-				printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType );
+-
+-			hvlpevent_clear_valid(event);
+-		} else if (hvlpevent_queue.xPlicOverflowIntPending)
+-			/*
+-			 * No more valid events. If overflow events are
+-			 * pending process them
+-			 */
+-			HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex);
+-		else
+-			break;
+-	}
+-
+-	spin_unlock(&hvlpevent_queue.lock);
+-}
+-
+-static int set_spread_lpevents(char *str)
+-{
+-	unsigned long val = simple_strtoul(str, NULL, 0);
+-
+-	/*
+-	 * The parameter is the number of processors to share in processing
+-	 * lp events.
+-	 */
+-	if (( val > 0) && (val <= NR_CPUS)) {
+-		spread_lpevents = val;
+-		printk("lpevent processing spread over %ld processors\n", val);
+-	} else {
+-		printk("invalid spread_lpevents %ld\n", val);
+-	}
+-
+-	return 1;
+-}
+-__setup("spread_lpevents=", set_spread_lpevents);
+-
+-void setup_hvlpevent_queue(void)
+-{
+-	void *eventStack;
+-
+-	/*
+-	 * Allocate a page for the Event Stack. The Hypervisor needs the
+-	 * absolute real address, so we subtract out the KERNELBASE and add
+-	 * in the absolute real address of the kernel load area.
+-	 */
+-	eventStack = alloc_bootmem_pages(LpEventStackSize);
+-	memset(eventStack, 0, LpEventStackSize);
+-
+-	/* Invoke the hypervisor to initialize the event stack */
+-	HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize);
+-
+-	hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack;
+-	hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack;
+-	hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack +
+-					(LpEventStackSize - LpEventMaxSize);
+-	hvlpevent_queue.xIndex = 0;
+-}
+-
+-static int proc_lpevents_show(struct seq_file *m, void *v)
+-{
+-	int cpu, i;
+-	unsigned long sum;
+-	static unsigned long cpu_totals[NR_CPUS];
+-
+-	/* FIXME: do we care that there's no locking here? */
+-	sum = 0;
+-	for_each_online_cpu(cpu) {
+-		cpu_totals[cpu] = 0;
+-		for (i = 0; i < HvLpEvent_Type_NumTypes; i++) {
+-			cpu_totals[cpu] += per_cpu(hvlpevent_counts, cpu)[i];
+-		}
+-		sum += cpu_totals[cpu];
+-	}
+-
+-	seq_printf(m, "LpEventQueue 0\n");
+-	seq_printf(m, "  events processed:\t%lu\n", sum);
+-
+-	for (i = 0; i < HvLpEvent_Type_NumTypes; ++i) {
+-		sum = 0;
+-		for_each_online_cpu(cpu) {
+-			sum += per_cpu(hvlpevent_counts, cpu)[i];
+-		}
+-
+-		seq_printf(m, "    %-20s %10lu\n", event_types[i], sum);
+-	}
+-
+-	seq_printf(m, "\n  events processed by processor:\n");
+-
+-	for_each_online_cpu(cpu) {
+-		seq_printf(m, "    CPU%02d  %10lu\n", cpu, cpu_totals[cpu]);
+-	}
+-
+-	return 0;
+-}
+-
+-static int proc_lpevents_open(struct inode *inode, struct file *file)
+-{
+-	return single_open(file, proc_lpevents_show, NULL);
+-}
+-
+-static struct file_operations proc_lpevents_operations = {
+-	.open		= proc_lpevents_open,
+-	.read		= seq_read,
+-	.llseek		= seq_lseek,
+-	.release	= single_release,
+-};
+-
+-static int __init proc_lpevents_init(void)
+-{
+-	struct proc_dir_entry *e;
+-
+-	e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL);
+-	if (e)
+-		e->proc_fops = &proc_lpevents_operations;
+-
+-	return 0;
+-}
+-__initcall(proc_lpevents_init);
+-
+diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/LparData.c
++++ /dev/null
+@@ -1,227 +0,0 @@
+-/* 
+- * Copyright 2001 Mike Corrigan, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-#include <linux/config.h>
+-#include <linux/types.h>
+-#include <linux/threads.h>
+-#include <linux/module.h>
+-#include <linux/bitops.h>
+-#include <asm/processor.h>
+-#include <asm/ptrace.h>
+-#include <asm/naca.h>
+-#include <asm/abs_addr.h>
+-#include <asm/iSeries/ItLpNaca.h>
+-#include <asm/lppaca.h>
+-#include <asm/iSeries/ItLpRegSave.h>
+-#include <asm/paca.h>
+-#include <asm/iSeries/HvReleaseData.h>
+-#include <asm/iSeries/LparMap.h>
+-#include <asm/iSeries/ItVpdAreas.h>
+-#include <asm/iSeries/ItIplParmsReal.h>
+-#include <asm/iSeries/ItExtVpdPanel.h>
+-#include <asm/iSeries/ItLpQueue.h>
+-#include <asm/iSeries/IoHriProcessorVpd.h>
+-#include <asm/iSeries/ItSpCommArea.h>
+-
+-
+-/* The HvReleaseData is the root of the information shared between 
+- * the hypervisor and Linux.  
+- */
+-struct HvReleaseData hvReleaseData = {
+-	.xDesc = 0xc8a5d9c4,	/* "HvRD" ebcdic */
+-	.xSize = sizeof(struct HvReleaseData),
+-	.xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas),
+-	.xSlicNacaAddr = &naca,		/* 64-bit Naca address */
+-	.xMsNucDataOffset = LPARMAP_PHYS,
+-	.xFlags = HVREL_TAGSINACTIVE	/* tags inactive       */
+-					/* 64 bit              */
+-					/* shared processors   */
+-					/* HMT allowed         */
+-		  | 6,			/* TEMP: This allows non-GA driver */
+-	.xVrmIndex = 4,			/* We are v5r2m0               */
+-	.xMinSupportedPlicVrmIndex = 3,		/* v5r1m0 */
+-	.xMinCompatablePlicVrmIndex = 3,	/* v5r1m0 */
+-	.xVrmName = { 0xd3, 0x89, 0x95, 0xa4,	/* "Linux 2.4.64" ebcdic */
+-		0xa7, 0x40, 0xf2, 0x4b,
+-		0xf4, 0x4b, 0xf6, 0xf4 },
+-};
+-
+-/*
+- * The NACA.  The first dword of the naca is required by the iSeries
+- * hypervisor to point to itVpdAreas.  The hypervisor finds the NACA
+- * through the pointer in hvReleaseData.
+- */
+-struct naca_struct naca = {
+-	.xItVpdAreas = &itVpdAreas,
+-	.xRamDisk = 0,
+-	.xRamDiskSize = 0,
+-};
+-
+-extern void system_reset_iSeries(void);
+-extern void machine_check_iSeries(void);
+-extern void data_access_iSeries(void);
+-extern void instruction_access_iSeries(void);
+-extern void hardware_interrupt_iSeries(void);
+-extern void alignment_iSeries(void);
+-extern void program_check_iSeries(void);
+-extern void fp_unavailable_iSeries(void);
+-extern void decrementer_iSeries(void);
+-extern void trap_0a_iSeries(void);
+-extern void trap_0b_iSeries(void);
+-extern void system_call_iSeries(void);
+-extern void single_step_iSeries(void);
+-extern void trap_0e_iSeries(void);
+-extern void performance_monitor_iSeries(void);
+-extern void data_access_slb_iSeries(void);
+-extern void instruction_access_slb_iSeries(void);
+-	
+-struct ItLpNaca itLpNaca = {
+-	.xDesc = 0xd397d581,		/* "LpNa" ebcdic */
+-	.xSize = 0x0400,		/* size of ItLpNaca */
+-	.xIntHdlrOffset = 0x0300,	/* offset to int array */
+-	.xMaxIntHdlrEntries = 19,	/* # ents */
+-	.xPrimaryLpIndex = 0,		/* Part # of primary */
+-	.xServiceLpIndex = 0,		/* Part # of serv */
+-	.xLpIndex = 0,			/* Part # of me */
+-	.xMaxLpQueues = 0,		/* # of LP queues */
+-	.xLpQueueOffset = 0x100,	/* offset of start of LP queues */
+-	.xPirEnvironMode = 0,		/* Piranha stuff */
+-	.xPirConsoleMode = 0,
+-	.xPirDasdMode = 0,
+-	.xLparInstalled = 0,
+-	.xSysPartitioned = 0,
+-	.xHwSyncedTBs = 0,
+-	.xIntProcUtilHmt = 0,
+-	.xSpVpdFormat = 0,
+-	.xIntProcRatio = 0,
+-	.xPlicVrmIndex = 0,		/* VRM index of PLIC */
+-	.xMinSupportedSlicVrmInd = 0,	/* min supported SLIC */
+-	.xMinCompatableSlicVrmInd = 0,	/* min compat SLIC */
+-	.xLoadAreaAddr = 0,		/* 64-bit addr of load area */
+-	.xLoadAreaChunks = 0,		/* chunks for load area */
+-	.xPaseSysCallCRMask = 0,	/* PASE mask */
+-	.xSlicSegmentTablePtr = 0,	/* seg table */
+-	.xOldLpQueue = { 0 }, 		/* Old LP Queue */
+-	.xInterruptHdlr = {
+-		(u64)system_reset_iSeries,	/* 0x100 System Reset */
+-		(u64)machine_check_iSeries,	/* 0x200 Machine Check */
+-		(u64)data_access_iSeries,	/* 0x300 Data Access */
+-		(u64)instruction_access_iSeries, /* 0x400 Instruction Access */
+-		(u64)hardware_interrupt_iSeries, /* 0x500 External */
+-		(u64)alignment_iSeries,		/* 0x600 Alignment */
+-		(u64)program_check_iSeries,	/* 0x700 Program Check */
+-		(u64)fp_unavailable_iSeries,	/* 0x800 FP Unavailable */
+-		(u64)decrementer_iSeries,	/* 0x900 Decrementer */
+-		(u64)trap_0a_iSeries,		/* 0xa00 Trap 0A */
+-		(u64)trap_0b_iSeries,		/* 0xb00 Trap 0B */
+-		(u64)system_call_iSeries,	/* 0xc00 System Call */
+-		(u64)single_step_iSeries,	/* 0xd00 Single Step */
+-		(u64)trap_0e_iSeries,		/* 0xe00 Trap 0E */
+-		(u64)performance_monitor_iSeries,/* 0xf00 Performance Monitor */
+-		0,				/* int 0x1000 */
+-		0,				/* int 0x1010 */
+-		0,				/* int 0x1020 CPU ctls */
+-		(u64)hardware_interrupt_iSeries, /* SC Ret Hdlr */
+-		(u64)data_access_slb_iSeries,	/* 0x380 D-SLB */
+-		(u64)instruction_access_slb_iSeries /* 0x480 I-SLB */
+-	}
+-};
+-EXPORT_SYMBOL(itLpNaca);
+-
+-/* May be filled in by the hypervisor so cannot end up in the BSS */
+-struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data"))); 
+-
+-/* May be filled in by the hypervisor so cannot end up in the BSS */
+-struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
+-EXPORT_SYMBOL(xItExtVpdPanel);
+-
+-#define maxPhysicalProcessors 32
+-
+-struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
+-	{
+-		.xInstCacheOperandSize = 32,
+-		.xDataCacheOperandSize = 32,
+-		.xProcFreq     = 50000000,
+-		.xTimeBaseFreq = 50000000,
+-		.xPVR = 0x3600
+-	}
+-};
+-	
+-/* Space for Main Store Vpd 27,200 bytes */
+-/* May be filled in by the hypervisor so cannot end up in the BSS */
+-u64    xMsVpd[3400] __attribute__((__section__(".data")));
+-
+-/* Space for Recovery Log Buffer */
+-/* May be filled in by the hypervisor so cannot end up in the BSS */
+-u64    xRecoveryLogBuffer[32] __attribute__((__section__(".data")));
+-
+-struct SpCommArea xSpCommArea = {
+-	.xDesc = 0xE2D7C3C2,
+-	.xFormat = 1,
+-};
+-
+-/* The LparMap data is now located at offset 0x6000 in head.S
+- * It was put there so that the HvReleaseData could address it
+- * with a 32-bit offset as required by the iSeries hypervisor
+- *
+- * The Naca has a pointer to the ItVpdAreas.  The hypervisor finds
+- * the Naca via the HvReleaseData area.  The HvReleaseData has the
+- * offset into the Naca of the pointer to the ItVpdAreas.
+- */
+-struct ItVpdAreas itVpdAreas = {
+-	.xSlicDesc = 0xc9a3e5c1,		/* "ItVA" */
+-	.xSlicSize = sizeof(struct ItVpdAreas),
+-	.xSlicVpdEntries = ItVpdMaxEntries,	/* # VPD array entries */
+-	.xSlicDmaEntries = ItDmaMaxEntries,	/* # DMA array entries */
+-	.xSlicMaxLogicalProcs = NR_CPUS * 2,	/* Max logical procs */
+-	.xSlicMaxPhysicalProcs = maxPhysicalProcessors,	/* Max physical procs */
+-	.xSlicDmaToksOffset = offsetof(struct ItVpdAreas, xPlicDmaToks),
+-	.xSlicVpdAdrsOffset = offsetof(struct ItVpdAreas, xSlicVpdAdrs),
+-	.xSlicDmaLensOffset = offsetof(struct ItVpdAreas, xPlicDmaLens),
+-	.xSlicVpdLensOffset = offsetof(struct ItVpdAreas, xSlicVpdLens),
+-	.xSlicMaxSlotLabels = 0,		/* max slot labels */
+-	.xSlicMaxLpQueues = 1,			/* max LP queues */
+-	.xPlicDmaLens = { 0 },			/* DMA lengths */
+-	.xPlicDmaToks = { 0 },			/* DMA tokens */
+-	.xSlicVpdLens = {			/* VPD lengths */
+-	        0,0,0,		        /*  0 - 2 */
+-		sizeof(xItExtVpdPanel), /*       3 Extended VPD   */
+-		sizeof(struct paca_struct),	/*       4 length of Paca  */
+-		0,			/*       5 */
+-		sizeof(struct ItIplParmsReal),/* 6 length of IPL parms */
+-		26992,			/*	 7 length of MS VPD */
+-		0,			/*       8 */
+-		sizeof(struct ItLpNaca),/*       9 length of LP Naca */
+-		0, 			/*	10 */
+-		256,			/*	11 length of Recovery Log Buf */
+-		sizeof(struct SpCommArea), /*   12 length of SP Comm Area */
+-		0,0,0,			/* 13 - 15 */
+-		sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */
+-		0,0,0,0,0,0,		/* 17 - 22  */
+-		sizeof(struct hvlpevent_queue),	/* 23 length of Lp Queue */
+-		0,0			/* 24 - 25 */
+-		},
+-	.xSlicVpdAdrs = {			/* VPD addresses */
+-		0,0,0,  		/*	 0 -  2 */
+-		&xItExtVpdPanel,        /*       3 Extended VPD */
+-		&paca[0],		/*       4 first Paca */
+-		0,			/*       5 */
+-		&xItIplParmsReal,	/*	 6 IPL parms */
+-		&xMsVpd,		/*	 7 MS Vpd */
+-		0,			/*       8 */
+-		&itLpNaca,		/*       9 LpNaca */
+-		0,			/*	10 */
+-		&xRecoveryLogBuffer,	/*	11 Recovery Log Buffer */
+-		&xSpCommArea,		/*	12 SP Comm Area */
+-		0,0,0,			/* 13 - 15 */
+-		&xIoHriProcessorVpd,	/*      16 Proc Vpd */
+-		0,0,0,0,0,0,		/* 17 - 22 */
+-		&hvlpevent_queue,	/*      23 Lp Queue */
+-		0,0
+-	}
+-};
+diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
+--- a/arch/ppc64/kernel/Makefile
++++ b/arch/ppc64/kernel/Makefile
+@@ -2,36 +2,34 @@
+ # Makefile for the linux ppc64 kernel.
+ #
+ 
++ifneq ($(CONFIG_PPC_MERGE),y)
++
+ EXTRA_CFLAGS	+= -mno-minimal-toc
+ extra-y		:= head.o vmlinux.lds
+ 
+-obj-y               :=	setup.o entry.o traps.o irq.o idle.o dma.o \
+-			time.o process.o signal.o syscalls.o misc.o ptrace.o \
+-			align.o semaphore.o bitops.o pacaData.o \
+-			udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
+-			ptrace32.o signal32.o rtc.o init_task.o \
+-			lmb.o cputable.o cpu_setup_power4.o idle_power4.o \
+-			iommu.o sysfs.o vdso.o pmc.o firmware.o
+-obj-y += vdso32/ vdso64/
++obj-y               :=	misc.o prom.o
++
++endif
+ 
+-obj-$(CONFIG_PPC_OF) +=	of_device.o
++obj-y               +=	irq.o idle.o dma.o \
++			signal.o \
++			align.o bitops.o pacaData.o \
++			udbg.o ioctl32.o \
++			rtc.o \
++			cpu_setup_power4.o \
++			iommu.o sysfs.o vdso.o firmware.o
++obj-y += vdso32/ vdso64/
+ 
+-pci-obj-$(CONFIG_PPC_ISERIES)	+= iSeries_pci.o iSeries_irq.o \
+-				iSeries_VpdInfo.o
+ pci-obj-$(CONFIG_PPC_MULTIPLATFORM)	+= pci_dn.o pci_direct_iommu.o
+ 
+ obj-$(CONFIG_PCI)	+= pci.o pci_iommu.o iomap.o $(pci-obj-y)
+ 
+-obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
+-			     iSeries_setup.o ItLpQueue.o hvCall.o \
+-			     mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
+-			     iSeries_iommu.o
+-
+-obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o
+-
+-obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
+-			     pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
+-			     pSeries_setup.o pSeries_iommu.o udbg_16550.o
++obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o
++ifneq ($(CONFIG_PPC_MERGE),y)
++obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
++endif
++
++obj-$(CONFIG_PPC_PSERIES) += rtasd.o udbg_16550.o
+ 
+ obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
+ 			 bpa_iic.o spider-pic.o
+@@ -41,45 +39,36 @@ obj-$(CONFIG_EEH)		+= eeh.o
+ obj-$(CONFIG_PROC_FS)		+= proc_ppc64.o
+ obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
+ obj-$(CONFIG_SMP)		+= smp.o
+-obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
+-obj-$(CONFIG_PPC_RTAS)		+= rtas.o rtas_pci.o
++obj-$(CONFIG_MODULES)		+= module.o
++ifneq ($(CONFIG_PPC_MERGE),y)
++obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
++endif
++obj-$(CONFIG_PPC_RTAS)		+= rtas_pci.o
+ obj-$(CONFIG_RTAS_PROC)		+= rtas-proc.o
+ obj-$(CONFIG_SCANLOG)		+= scanlog.o
+-obj-$(CONFIG_VIOPATH)		+= viopath.o
+ obj-$(CONFIG_LPARCFG)		+= lparcfg.o
+ obj-$(CONFIG_HVC_CONSOLE)	+= hvconsole.o
++ifneq ($(CONFIG_PPC_MERGE),y)
+ obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
++endif
+ obj-$(CONFIG_HVCS)		+= hvcserver.o
+ 
+-vio-obj-$(CONFIG_PPC_PSERIES)	+= pSeries_vio.o
+-vio-obj-$(CONFIG_PPC_ISERIES)	+= iSeries_vio.o
+-obj-$(CONFIG_IBMVIO)		+= vio.o $(vio-obj-y)
+-obj-$(CONFIG_XICS)		+= xics.o
+-obj-$(CONFIG_MPIC)		+= mpic.o
+-
+-obj-$(CONFIG_PPC_PMAC)		+= pmac_setup.o pmac_feature.o pmac_pci.o \
+-				   pmac_time.o pmac_nvram.o pmac_low_i2c.o \
+-				   udbg_scc.o
++obj-$(CONFIG_PPC_PMAC)		+= udbg_scc.o
+ 
+-obj-$(CONFIG_PPC_MAPLE)		+= maple_setup.o maple_pci.o maple_time.o \
+-				   udbg_16550.o
+-
+-obj-$(CONFIG_U3_DART)		+= u3_iommu.o
++obj-$(CONFIG_PPC_MAPLE)		+= udbg_16550.o
+ 
+ ifdef CONFIG_SMP
+-obj-$(CONFIG_PPC_PMAC)		+= pmac_smp.o smp-tbsync.o
+-obj-$(CONFIG_PPC_ISERIES)	+= iSeries_smp.o
+-obj-$(CONFIG_PPC_PSERIES)	+= pSeries_smp.o
+-obj-$(CONFIG_PPC_BPA)		+= pSeries_smp.o
++obj-$(CONFIG_PPC_PMAC)		+= smp-tbsync.o
+ obj-$(CONFIG_PPC_MAPLE)		+= smp-tbsync.o
+ endif
+ 
+-obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
+ obj-$(CONFIG_KPROBES)		+= kprobes.o
+ 
+ CFLAGS_ioctl32.o += -Ifs/
+ 
++ifneq ($(CONFIG_PPC_MERGE),y)
+ ifeq ($(CONFIG_PPC_ISERIES),y)
+-arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s
+-AFLAGS_head.o += -Iarch/ppc64/kernel
++arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s
++AFLAGS_head.o += -Iarch/powerpc/kernel
++endif
+ endif
+diff --git a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c
+--- a/arch/ppc64/kernel/align.c
++++ b/arch/ppc64/kernel/align.c
+@@ -313,7 +313,7 @@ fix_alignment(struct pt_regs *regs)
+ 				/* Doing stfs, have to convert to single */
+ 				preempt_disable();
+ 				enable_kernel_fp();
+-				cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr);
++				cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread);
+ 				disable_kernel_fp();
+ 				preempt_enable();
+ 			}
+@@ -349,7 +349,7 @@ fix_alignment(struct pt_regs *regs)
+ 				/* Doing lfs, have to convert to double */
+ 				preempt_disable();
+ 				enable_kernel_fp();
+-				cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr);
++				cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread);
+ 				disable_kernel_fp();
+ 				preempt_enable();
+ 			}
+diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
+--- a/arch/ppc64/kernel/asm-offsets.c
++++ b/arch/ppc64/kernel/asm-offsets.c
+@@ -46,8 +46,6 @@
+ int main(void)
+ {
+ 	/* thread struct on stack */
+-	DEFINE(THREAD_SHIFT, THREAD_SHIFT);
+-	DEFINE(THREAD_SIZE, THREAD_SIZE);
+ 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ 	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
+ 	DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
+@@ -77,6 +75,7 @@ int main(void)
+ 	DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
+ 	DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
+ 	DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
++	DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
+ 
+ 	/* paca */
+         DEFINE(PACA_SIZE, sizeof(struct paca_struct));
+diff --git a/arch/ppc64/kernel/binfmt_elf32.c b/arch/ppc64/kernel/binfmt_elf32.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/binfmt_elf32.c
++++ /dev/null
+@@ -1,78 +0,0 @@
+-/*
+- * binfmt_elf32.c: Support 32-bit PPC ELF binaries on Power3 and followons.
+- * based on the SPARC64 version.
+- * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller	(davem at redhat.com)
+- * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek	(jj at ultra.linux.cz)
+- *
+- * Copyright (C) 2000,2001 Ken Aaker (kdaaker at rchland.vnet.ibm.com), IBM Corp
+- * Copyright (C) 2001 Anton Blanchard (anton at au.ibm.com), 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.
+- */
+-
+-#define ELF_ARCH		EM_PPC
+-#define ELF_CLASS		ELFCLASS32
+-#define ELF_DATA		ELFDATA2MSB;
+-
+-#include <asm/processor.h>
+-#include <linux/module.h>
+-#include <linux/config.h>
+-#include <linux/elfcore.h>
+-#include <linux/compat.h>
+-
+-#define elf_prstatus elf_prstatus32
+-struct elf_prstatus32
+-{
+-	struct elf_siginfo pr_info;	/* Info associated with signal */
+-	short	pr_cursig;		/* Current signal */
+-	unsigned int pr_sigpend;	/* Set of pending signals */
+-	unsigned int pr_sighold;	/* Set of held signals */
+-	pid_t	pr_pid;
+-	pid_t	pr_ppid;
+-	pid_t	pr_pgrp;
+-	pid_t	pr_sid;
+-	struct compat_timeval pr_utime;	/* User time */
+-	struct compat_timeval pr_stime;	/* System time */
+-	struct compat_timeval pr_cutime;	/* Cumulative user time */
+-	struct compat_timeval pr_cstime;	/* Cumulative system time */
+-	elf_gregset_t pr_reg;		/* General purpose registers. */
+-	int pr_fpvalid;		/* True if math co-processor being used. */
+-};
+-
+-#define elf_prpsinfo elf_prpsinfo32
+-struct elf_prpsinfo32
+-{
+-	char	pr_state;	/* numeric process state */
+-	char	pr_sname;	/* char for pr_state */
+-	char	pr_zomb;	/* zombie */
+-	char	pr_nice;	/* nice val */
+-	unsigned int pr_flag;	/* flags */
+-	u32	pr_uid;
+-	u32	pr_gid;
+-	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
+-	/* Lots missing */
+-	char	pr_fname[16];	/* filename of executable */
+-	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
+-};
+-
+-#include <linux/time.h>
+-
+-#undef cputime_to_timeval
+-#define cputime_to_timeval cputime_to_compat_timeval
+-static __inline__ void
+-cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
+-{
+-	unsigned long jiffies = cputime_to_jiffies(cputime);
+-	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+-	value->tv_sec = jiffies / HZ;
+-}
+-
+-extern void start_thread32(struct pt_regs *, unsigned long, unsigned long);
+-#undef start_thread
+-#define start_thread start_thread32
+-#define init_elf_binfmt init_elf32_binfmt
+-
+-#include "../../../fs/binfmt_elf.c"
+diff --git a/arch/ppc64/kernel/bpa_iommu.c b/arch/ppc64/kernel/bpa_iommu.c
+--- a/arch/ppc64/kernel/bpa_iommu.c
++++ b/arch/ppc64/kernel/bpa_iommu.c
+@@ -39,8 +39,8 @@
+ #include <asm/pmac_feature.h>
+ #include <asm/abs_addr.h>
+ #include <asm/system.h>
++#include <asm/ppc-pci.h>
+ 
+-#include "pci.h"
+ #include "bpa_iommu.h"
+ 
+ static inline unsigned long 
+diff --git a/arch/ppc64/kernel/bpa_setup.c b/arch/ppc64/kernel/bpa_setup.c
+--- a/arch/ppc64/kernel/bpa_setup.c
++++ b/arch/ppc64/kernel/bpa_setup.c
+@@ -43,8 +43,9 @@
+ #include <asm/time.h>
+ #include <asm/nvram.h>
+ #include <asm/cputable.h>
++#include <asm/ppc-pci.h>
++#include <asm/irq.h>
+ 
+-#include "pci.h"
+ #include "bpa_iic.h"
+ #include "bpa_iommu.h"
+ 
+@@ -54,7 +55,7 @@
+ #define DBG(fmt...)
+ #endif
+ 
+-void bpa_get_cpuinfo(struct seq_file *m)
++void bpa_show_cpuinfo(struct seq_file *m)
+ {
+ 	struct device_node *root;
+ 	const char *model = "";
+@@ -128,7 +129,7 @@ struct machdep_calls __initdata bpa_md =
+ 	.probe			= bpa_probe,
+ 	.setup_arch		= bpa_setup_arch,
+ 	.init_early		= bpa_init_early,
+-	.get_cpuinfo		= bpa_get_cpuinfo,
++	.show_cpuinfo		= bpa_show_cpuinfo,
+ 	.restart		= rtas_restart,
+ 	.power_off		= rtas_power_off,
+ 	.halt			= rtas_halt,
+diff --git a/arch/ppc64/kernel/btext.c b/arch/ppc64/kernel/btext.c
+--- a/arch/ppc64/kernel/btext.c
++++ b/arch/ppc64/kernel/btext.c
+@@ -18,6 +18,7 @@
+ #include <asm/io.h>
+ #include <asm/lmb.h>
+ #include <asm/processor.h>
++#include <asm/udbg.h>
+ 
+ #undef NO_SCROLL
+ 
+@@ -131,6 +132,47 @@ int btext_initialize(struct device_node 
+ 	return 0;
+ }
+ 
++static void btext_putc(unsigned char c)
++{
++	btext_drawchar(c);
++}
++
++void __init init_boot_display(void)
++{
++	char *name;
++	struct device_node *np = NULL; 
++	int rc = -ENODEV;
++
++	printk("trying to initialize btext ...\n");
++
++	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
++	if (name != NULL) {
++		np = of_find_node_by_path(name);
++		if (np != NULL) {
++			if (strcmp(np->type, "display") != 0) {
++				printk("boot stdout isn't a display !\n");
++				of_node_put(np);
++				np = NULL;
++			}
++		}
++	}
++	if (np)
++		rc = btext_initialize(np);
++	if (rc) {
++		for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
++			if (get_property(np, "linux,opened", NULL)) {
++				printk("trying %s ...\n", np->full_name);
++				rc = btext_initialize(np);
++				printk("result: %d\n", rc);
++			}
++			if (rc == 0)
++				break;
++		}
++	}
++	if (rc == 0 && udbg_putc == NULL)
++		udbg_putc = btext_putc;
++}
++
+ 
+ /* Calc the base address of a given point (x,y) */
+ static unsigned char * calc_base(int x, int y)
+diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/cputable.c
++++ /dev/null
+@@ -1,308 +0,0 @@
+-/*
+- *  arch/ppc64/kernel/cputable.c
+- *
+- *  Copyright (C) 2001 Ben. Herrenschmidt (benh at kernel.crashing.org)
+- *
+- *  Modifications for ppc64:
+- *      Copyright (C) 2003 Dave Engebretsen <engebret at 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 <linux/config.h>
+-#include <linux/string.h>
+-#include <linux/sched.h>
+-#include <linux/threads.h>
+-#include <linux/init.h>
+-#include <linux/module.h>
+-
+-#include <asm/oprofile_impl.h>
+-#include <asm/cputable.h>
+-
+-struct cpu_spec* cur_cpu_spec = NULL;
+-EXPORT_SYMBOL(cur_cpu_spec);
+-
+-/* NOTE:
+- * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's
+- * the responsibility of the appropriate CPU save/restore functions to
+- * eventually copy these settings over. Those save/restore aren't yet
+- * part of the cputable though. That has to be fixed for both ppc32
+- * and ppc64
+- */
+-extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
+-extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
+-extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
+-extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
+-
+-
+-/* We only set the altivec features if the kernel was compiled with altivec
+- * support
+- */
+-#ifdef CONFIG_ALTIVEC
+-#define CPU_FTR_ALTIVEC_COMP	CPU_FTR_ALTIVEC
+-#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
+-#else
+-#define CPU_FTR_ALTIVEC_COMP	0
+-#define PPC_FEATURE_HAS_ALTIVEC_COMP    0
+-#endif
+-
+-struct cpu_spec	cpu_specs[] = {
+-	{	/* Power3 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00400000,
+-		.cpu_name		= "POWER3 (630)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
+-		.cpu_user_features = COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/power3",
+-		.oprofile_model		= &op_model_rs64,
+-#endif
+-	},
+-	{	/* Power3+ */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00410000,
+-		.cpu_name		= "POWER3 (630+)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/power3",
+-		.oprofile_model		= &op_model_rs64,
+-#endif
+-	},
+-	{	/* Northstar */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00330000,
+-		.cpu_name		= "RS64-II (northstar)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+-			CPU_FTR_MMCRA | CPU_FTR_CTRL,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/rs64",
+-		.oprofile_model		= &op_model_rs64,
+-#endif
+-	},
+-	{	/* Pulsar */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00340000,
+-		.cpu_name		= "RS64-III (pulsar)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+-			CPU_FTR_MMCRA | CPU_FTR_CTRL,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/rs64",
+-		.oprofile_model		= &op_model_rs64,
+-#endif
+-	},
+-	{	/* I-star */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00360000,
+-		.cpu_name		= "RS64-III (icestar)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+-			CPU_FTR_MMCRA | CPU_FTR_CTRL,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/rs64",
+-		.oprofile_model		= &op_model_rs64,
+-#endif
+-	},
+-	{	/* S-star */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00370000,
+-		.cpu_name		= "RS64-IV (sstar)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+-			CPU_FTR_MMCRA | CPU_FTR_CTRL,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power3,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/rs64",
+-		.oprofile_model		= &op_model_rs64,
+-#endif
+-	},
+-	{	/* Power4 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00350000,
+-		.cpu_name		= "POWER4 (gp)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power4,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/power4",
+-		.oprofile_model		= &op_model_rs64,
+-#endif
+-	},
+-	{	/* Power4+ */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00380000,
+-		.cpu_name		= "POWER4+ (gq)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_power4,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/power4",
+-		.oprofile_model		= &op_model_power4,
+-#endif
+-	},
+-	{	/* PPC970 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00390000,
+-		.cpu_name		= "PPC970",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
+-			CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
+-		.cpu_user_features	= COMMON_USER_PPC64 |
+-			PPC_FEATURE_HAS_ALTIVEC_COMP,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_ppc970,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/970",
+-		.oprofile_model		= &op_model_power4,
+-#endif
+-	},
+-	{	/* PPC970FX */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x003c0000,
+-		.cpu_name		= "PPC970FX",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
+-			CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
+-		.cpu_user_features	= COMMON_USER_PPC64 |
+-			PPC_FEATURE_HAS_ALTIVEC_COMP,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 8,
+-		.cpu_setup		= __setup_cpu_ppc970,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/970",
+-		.oprofile_model		= &op_model_power4,
+-#endif
+-	},
+-	{	/* PPC970MP */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00440000,
+-		.cpu_name		= "PPC970MP",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
+-			CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
+-		.cpu_user_features	= COMMON_USER_PPC64 |
+-			PPC_FEATURE_HAS_ALTIVEC_COMP,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.cpu_setup		= __setup_cpu_ppc970,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/970",
+-		.oprofile_model		= &op_model_power4,
+-#endif
+-	},
+-	{	/* Power5 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x003a0000,
+-		.cpu_name		= "POWER5 (gr)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
+-			CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
+-			CPU_FTR_MMCRA_SIHV,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_power4,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/power5",
+-		.oprofile_model		= &op_model_power4,
+-#endif
+-	},
+-	{	/* Power5 */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x003b0000,
+-		.cpu_name		= "POWER5 (gs)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
+-			CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
+-			CPU_FTR_MMCRA_SIHV,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_power4,
+-#ifdef CONFIG_OPROFILE
+-		.oprofile_cpu_type	= "ppc64/power5",
+-		.oprofile_model		= &op_model_power4,
+-#endif
+-	},
+-	{	/* BE DD1.x */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x00700000,
+-		.cpu_name		= "Broadband Engine",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
+-			CPU_FTR_SMT,
+-		.cpu_user_features	= COMMON_USER_PPC64 |
+-			PPC_FEATURE_HAS_ALTIVEC_COMP,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.cpu_setup		= __setup_cpu_be,
+-	},
+-	{	/* default match */
+-		.pvr_mask		= 0x00000000,
+-		.pvr_value		= 0x00000000,
+-		.cpu_name		= "POWER4 (compatible)",
+-		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+-			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+-			CPU_FTR_PPCAS_ARCH_V2,
+-		.cpu_user_features	= COMMON_USER_PPC64,
+-		.icache_bsize		= 128,
+-		.dcache_bsize		= 128,
+-		.num_pmcs		= 6,
+-		.cpu_setup		= __setup_cpu_power4,
+-	}
+-};
+diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
+--- a/arch/ppc64/kernel/eeh.c
++++ b/arch/ppc64/kernel/eeh.c
+@@ -33,7 +33,7 @@
+ #include <asm/rtas.h>
+ #include <asm/atomic.h>
+ #include <asm/systemcfg.h>
+-#include "pci.h"
++#include <asm/ppc-pci.h>
+ 
+ #undef DEBUG
+ 
+diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
+deleted file mode 100644
+--- a/arch/ppc64/kernel/entry.S
++++ /dev/null
+@@ -1,845 +0,0 @@
+-/*
+- *  arch/ppc64/kernel/entry.S
+- *
+- *  PowerPC version 
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *  Rewritten by Cort Dougan (cort at cs.nmt.edu) for PReP
+- *    Copyright (C) 1996 Cort Dougan <cort at cs.nmt.edu>
+- *  Adapted for Power Macintosh by Paul Mackerras.
+- *  Low-level exception handlers and MMU support
+- *  rewritten by Paul Mackerras.
+- *    Copyright (C) 1996 Paul Mackerras.
+- *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek at jlc.net).
+- *
+- *  This file contains the system call entry code, context switch
+- *  code, and exception/interrupt return code for PowerPC.
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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/errno.h>
+-#include <asm/unistd.h>
+-#include <asm/processor.h>
+-#include <asm/page.h>
+-#include <asm/mmu.h>
+-#include <asm/thread_info.h>
+-#include <asm/ppc_asm.h>
+-#include <asm/asm-offsets.h>
+-#include <asm/cputable.h>
+-
+-#ifdef CONFIG_PPC_ISERIES
+-#define DO_SOFT_DISABLE
+-#endif
+-
+-/*
+- * System calls.
+- */
+-	.section	".toc","aw"
+-.SYS_CALL_TABLE:
+-	.tc .sys_call_table[TC],.sys_call_table
+-
+-.SYS_CALL_TABLE32:
+-	.tc .sys_call_table32[TC],.sys_call_table32
+-
+-/* This value is used to mark exception frames on the stack. */
+-exception_marker:
+-	.tc	ID_72656773_68657265[TC],0x7265677368657265
+-
+-	.section	".text"
+-	.align 7
+-
+-#undef SHOW_SYSCALLS
+-
+-	.globl system_call_common
+-system_call_common:
+-	andi.	r10,r12,MSR_PR
+-	mr	r10,r1
+-	addi	r1,r1,-INT_FRAME_SIZE
+-	beq-	1f
+-	ld	r1,PACAKSAVE(r13)
+-1:	std	r10,0(r1)
+-	std	r11,_NIP(r1)
+-	std	r12,_MSR(r1)
+-	std	r0,GPR0(r1)
+-	std	r10,GPR1(r1)
+-	std	r2,GPR2(r1)
+-	std	r3,GPR3(r1)
+-	std	r4,GPR4(r1)
+-	std	r5,GPR5(r1)
+-	std	r6,GPR6(r1)
+-	std	r7,GPR7(r1)
+-	std	r8,GPR8(r1)
+-	li	r11,0
+-	std	r11,GPR9(r1)
+-	std	r11,GPR10(r1)
+-	std	r11,GPR11(r1)
+-	std	r11,GPR12(r1)
+-	std	r9,GPR13(r1)
+-	crclr	so
+-	mfcr	r9
+-	mflr	r10
+-	li	r11,0xc01
+-	std	r9,_CCR(r1)
+-	std	r10,_LINK(r1)
+-	std	r11,_TRAP(r1)
+-	mfxer	r9
+-	mfctr	r10
+-	std	r9,_XER(r1)
+-	std	r10,_CTR(r1)
+-	std	r3,ORIG_GPR3(r1)
+-	ld	r2,PACATOC(r13)
+-	addi	r9,r1,STACK_FRAME_OVERHEAD
+-	ld	r11,exception_marker at toc(r2)
+-	std	r11,-16(r9)		/* "regshere" marker */
+-#ifdef CONFIG_PPC_ISERIES
+-	/* Hack for handling interrupts when soft-enabling on iSeries */
+-	cmpdi	cr1,r0,0x5555		/* syscall 0x5555 */
+-	andi.	r10,r12,MSR_PR		/* from kernel */
+-	crand	4*cr0+eq,4*cr1+eq,4*cr0+eq
+-	beq	hardware_interrupt_entry
+-	lbz	r10,PACAPROCENABLED(r13)
+-	std	r10,SOFTE(r1)
+-#endif
+-	mfmsr	r11
+-	ori	r11,r11,MSR_EE
+-	mtmsrd	r11,1
+-
+-#ifdef SHOW_SYSCALLS
+-	bl	.do_show_syscall
+-	REST_GPR(0,r1)
+-	REST_4GPRS(3,r1)
+-	REST_2GPRS(7,r1)
+-	addi	r9,r1,STACK_FRAME_OVERHEAD
+-#endif
+-	clrrdi	r11,r1,THREAD_SHIFT
+-	li	r12,0
+-	ld	r10,TI_FLAGS(r11)
+-	stb	r12,TI_SC_NOERR(r11)
+-	andi.	r11,r10,_TIF_SYSCALL_T_OR_A
+-	bne-	syscall_dotrace
+-syscall_dotrace_cont:
+-	cmpldi	0,r0,NR_syscalls
+-	bge-	syscall_enosys
+-
+-system_call:			/* label this so stack traces look sane */
+-/*
+- * Need to vector to 32 Bit or default sys_call_table here,
+- * based on caller's run-mode / personality.
+- */
+-	ld	r11,.SYS_CALL_TABLE at toc(2)
+-	andi.	r10,r10,_TIF_32BIT
+-	beq	15f
+-	ld	r11,.SYS_CALL_TABLE32 at toc(2)
+-	clrldi	r3,r3,32
+-	clrldi	r4,r4,32
+-	clrldi	r5,r5,32
+-	clrldi	r6,r6,32
+-	clrldi	r7,r7,32
+-	clrldi	r8,r8,32
+-15:
+-	slwi	r0,r0,3
+-	ldx	r10,r11,r0	/* Fetch system call handler [ptr] */
+-	mtctr   r10
+-	bctrl			/* Call handler */
+-
+-syscall_exit:
+-#ifdef SHOW_SYSCALLS
+-	std	r3,GPR3(r1)
+-	bl	.do_show_syscall_exit
+-	ld	r3,GPR3(r1)
+-#endif
+-	std	r3,RESULT(r1)
+-	ld	r5,_CCR(r1)
+-	li	r10,-_LAST_ERRNO
+-	cmpld	r3,r10
+-	clrrdi	r12,r1,THREAD_SHIFT
+-	bge-	syscall_error
+-syscall_error_cont:
+-
+-	/* check for syscall tracing or audit */
+-	ld	r9,TI_FLAGS(r12)
+-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+-	bne-	syscall_exit_trace
+-syscall_exit_trace_cont:
+-
+-	/* disable interrupts so current_thread_info()->flags can't change,
+-	   and so that we don't get interrupted after loading SRR0/1. */
+-	ld	r8,_MSR(r1)
+-	andi.	r10,r8,MSR_RI
+-	beq-	unrecov_restore
+-	mfmsr	r10
+-	rldicl	r10,r10,48,1
+-	rotldi	r10,r10,16
+-	mtmsrd	r10,1
+-	ld	r9,TI_FLAGS(r12)
+-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+-	bne-	syscall_exit_work
+-	ld	r7,_NIP(r1)
+-	stdcx.	r0,0,r1			/* to clear the reservation */
+-	andi.	r6,r8,MSR_PR
+-	ld	r4,_LINK(r1)
+-	beq-	1f			/* only restore r13 if */
+-	ld	r13,GPR13(r1)		/* returning to usermode */
+-1:	ld	r2,GPR2(r1)
+-	li	r12,MSR_RI
+-	andc	r10,r10,r12
+-	mtmsrd	r10,1			/* clear MSR.RI */
+-	ld	r1,GPR1(r1)
+-	mtlr	r4
+-	mtcr	r5
+-	mtspr	SRR0,r7
+-	mtspr	SRR1,r8
+-	rfid
+-	b	.	/* prevent speculative execution */
+-
+-syscall_enosys:
+-	li	r3,-ENOSYS
+-	std	r3,RESULT(r1)
+-	clrrdi	r12,r1,THREAD_SHIFT
+-	ld	r5,_CCR(r1)
+-
+-syscall_error:
+-	lbz	r11,TI_SC_NOERR(r12)
+-	cmpwi	0,r11,0
+-	bne-	syscall_error_cont
+-	neg	r3,r3
+-	oris	r5,r5,0x1000	/* Set SO bit in CR */
+-	std	r5,_CCR(r1)
+-	b	syscall_error_cont
+-        
+-/* Traced system call support */
+-syscall_dotrace:
+-	bl	.save_nvgprs
+-	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	bl	.do_syscall_trace_enter
+-	ld	r0,GPR0(r1)	/* Restore original registers */
+-	ld	r3,GPR3(r1)
+-	ld	r4,GPR4(r1)
+-	ld	r5,GPR5(r1)
+-	ld	r6,GPR6(r1)
+-	ld	r7,GPR7(r1)
+-	ld	r8,GPR8(r1)
+-	addi	r9,r1,STACK_FRAME_OVERHEAD
+-	clrrdi	r10,r1,THREAD_SHIFT
+-	ld	r10,TI_FLAGS(r10)
+-	b	syscall_dotrace_cont
+-
+-syscall_exit_trace:
+-	std	r3,GPR3(r1)
+-	bl	.save_nvgprs
+-	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	bl	.do_syscall_trace_leave
+-	REST_NVGPRS(r1)
+-	ld	r3,GPR3(r1)
+-	ld	r5,_CCR(r1)
+-	clrrdi	r12,r1,THREAD_SHIFT
+-	b	syscall_exit_trace_cont
+-
+-/* Stuff to do on exit from a system call. */
+-syscall_exit_work:
+-	std	r3,GPR3(r1)
+-	std	r5,_CCR(r1)
+-	b	.ret_from_except_lite
+-
+-/* Save non-volatile GPRs, if not already saved. */
+-_GLOBAL(save_nvgprs)
+-	ld	r11,_TRAP(r1)
+-	andi.	r0,r11,1
+-	beqlr-
+-	SAVE_NVGPRS(r1)
+-	clrrdi	r0,r11,1
+-	std	r0,_TRAP(r1)
+-	blr
+-
+-/*
+- * The sigsuspend and rt_sigsuspend system calls can call do_signal
+- * and thus put the process into the stopped state where we might
+- * want to examine its user state with ptrace.  Therefore we need
+- * to save all the nonvolatile registers (r14 - r31) before calling
+- * the C code.  Similarly, fork, vfork and clone need the full
+- * register state on the stack so that it can be copied to the child.
+- */
+-_GLOBAL(ppc32_sigsuspend)
+-	bl	.save_nvgprs
+-	bl	.sys32_sigsuspend
+-	b	70f
+-
+-_GLOBAL(ppc64_rt_sigsuspend)
+-	bl	.save_nvgprs
+-	bl	.sys_rt_sigsuspend
+-	b	70f
+-
+-_GLOBAL(ppc32_rt_sigsuspend)
+-	bl	.save_nvgprs
+-	bl	.sys32_rt_sigsuspend
+-70:	cmpdi	0,r3,0
+-	/* If it returned an error, we need to return via syscall_exit to set
+-	   the SO bit in cr0 and potentially stop for ptrace. */
+-	bne	syscall_exit
+-	/* If sigsuspend() returns zero, we are going into a signal handler. We
+-	   may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
+-#ifdef CONFIG_AUDIT
+-	ld	r3,PACACURRENT(r13)
+-	ld	r4,AUDITCONTEXT(r3)
+-	cmpdi	0,r4,0
+-	beq	.ret_from_except	/* No audit_context: Leave immediately. */
+-	li	r4, 2			/* AUDITSC_FAILURE */
+-	li	r5,-4			/* It's always -EINTR */
+-	bl	.audit_syscall_exit
+-#endif
+-	b	.ret_from_except
+-
+-_GLOBAL(ppc_fork)
+-	bl	.save_nvgprs
+-	bl	.sys_fork
+-	b	syscall_exit
+-
+-_GLOBAL(ppc_vfork)
+-	bl	.save_nvgprs
+-	bl	.sys_vfork
+-	b	syscall_exit
+-
+-_GLOBAL(ppc_clone)
+-	bl	.save_nvgprs
+-	bl	.sys_clone
+-	b	syscall_exit
+-
+-_GLOBAL(ppc32_swapcontext)
+-	bl	.save_nvgprs
+-	bl	.sys32_swapcontext
+-	b	80f
+-	
+-_GLOBAL(ppc64_swapcontext)
+-	bl	.save_nvgprs
+-	bl	.sys_swapcontext
+-	b	80f
+-
+-_GLOBAL(ppc32_sigreturn)
+-	bl	.sys32_sigreturn
+-	b	80f
+-
+-_GLOBAL(ppc32_rt_sigreturn)
+-	bl	.sys32_rt_sigreturn
+-	b	80f
+-
+-_GLOBAL(ppc64_rt_sigreturn)
+-	bl	.sys_rt_sigreturn
+-
+-80:	cmpdi	0,r3,0
+-	blt	syscall_exit
+-	clrrdi	r4,r1,THREAD_SHIFT
+-	ld	r4,TI_FLAGS(r4)
+-	andi.	r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+-	beq+	81f
+-	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	bl	.do_syscall_trace_leave
+-81:	b	.ret_from_except
+-
+-_GLOBAL(ret_from_fork)
+-	bl	.schedule_tail
+-	REST_NVGPRS(r1)
+-	li	r3,0
+-	b	syscall_exit
+-
+-/*
+- * This routine switches between two different tasks.  The process
+- * state of one is saved on its kernel stack.  Then the state
+- * of the other is restored from its kernel stack.  The memory
+- * management hardware is updated to the second process's state.
+- * Finally, we can return to the second process, via ret_from_except.
+- * On entry, r3 points to the THREAD for the current task, r4
+- * points to the THREAD for the new task.
+- *
+- * Note: there are two ways to get to the "going out" portion
+- * of this code; either by coming in via the entry (_switch)
+- * or via "fork" which must set up an environment equivalent
+- * to the "_switch" path.  If you change this you'll have to change
+- * the fork code also.
+- *
+- * The code which creates the new task context is in 'copy_thread'
+- * in arch/ppc64/kernel/process.c
+- */
+-	.align	7
+-_GLOBAL(_switch)
+-	mflr	r0
+-	std	r0,16(r1)
+-	stdu	r1,-SWITCH_FRAME_SIZE(r1)
+-	/* r3-r13 are caller saved -- Cort */
+-	SAVE_8GPRS(14, r1)
+-	SAVE_10GPRS(22, r1)
+-	mflr	r20		/* Return to switch caller */
+-	mfmsr	r22
+-	li	r0, MSR_FP
+-#ifdef CONFIG_ALTIVEC
+-BEGIN_FTR_SECTION
+-	oris	r0,r0,MSR_VEC at h	/* Disable altivec */
+-	mfspr	r24,SPRN_VRSAVE	/* save vrsave register value */
+-	std	r24,THREAD_VRSAVE(r3)
+-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+-#endif /* CONFIG_ALTIVEC */
+-	and.	r0,r0,r22
+-	beq+	1f
+-	andc	r22,r22,r0
+-	mtmsrd	r22
+-	isync
+-1:	std	r20,_NIP(r1)
+-	mfcr	r23
+-	std	r23,_CCR(r1)
+-	std	r1,KSP(r3)	/* Set old stack pointer */
+-
+-#ifdef CONFIG_SMP
+-	/* We need a sync somewhere here to make sure that if the
+-	 * previous task gets rescheduled on another CPU, it sees all
+-	 * stores it has performed on this one.
+-	 */
+-	sync
+-#endif /* CONFIG_SMP */
+-
+-	addi	r6,r4,-THREAD	/* Convert THREAD to 'current' */
+-	std	r6,PACACURRENT(r13)	/* Set new 'current' */
+-
+-	ld	r8,KSP(r4)	/* new stack pointer */
+-BEGIN_FTR_SECTION
+-	clrrdi	r6,r8,28	/* get its ESID */
+-	clrrdi	r9,r1,28	/* get current sp ESID */
+-	clrldi.	r0,r6,2		/* is new ESID c00000000? */
+-	cmpd	cr1,r6,r9	/* or is new ESID the same as current ESID? */
+-	cror	eq,4*cr1+eq,eq
+-	beq	2f		/* if yes, don't slbie it */
+-
+-	/* Bolt in the new stack SLB entry */
+-	ld	r7,KSP_VSID(r4)	/* Get new stack's VSID */
+-	oris	r0,r6,(SLB_ESID_V)@h
+-	ori	r0,r0,(SLB_NUM_BOLTED-1)@l
+-	slbie	r6
+-	slbie	r6		/* Workaround POWER5 < DD2.1 issue */
+-	slbmte	r7,r0
+-	isync
+-
+-2:
+-END_FTR_SECTION_IFSET(CPU_FTR_SLB)
+-	clrrdi	r7,r8,THREAD_SHIFT	/* base of new stack */
+-	/* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
+-	   because we don't need to leave the 288-byte ABI gap at the
+-	   top of the kernel stack. */
+-	addi	r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE
+-
+-	mr	r1,r8		/* start using new stack pointer */
+-	std	r7,PACAKSAVE(r13)
+-
+-	ld	r6,_CCR(r1)
+-	mtcrf	0xFF,r6
+-
+-#ifdef CONFIG_ALTIVEC
+-BEGIN_FTR_SECTION
+-	ld	r0,THREAD_VRSAVE(r4)
+-	mtspr	SPRN_VRSAVE,r0		/* if G4, restore VRSAVE reg */
+-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+-#endif /* CONFIG_ALTIVEC */
+-
+-	/* r3-r13 are destroyed -- Cort */
+-	REST_8GPRS(14, r1)
+-	REST_10GPRS(22, r1)
+-
+-	/* convert old thread to its task_struct for return value */
+-	addi	r3,r3,-THREAD
+-	ld	r7,_NIP(r1)	/* Return to _switch caller in new task */
+-	mtlr	r7
+-	addi	r1,r1,SWITCH_FRAME_SIZE
+-	blr
+-
+-	.align	7
+-_GLOBAL(ret_from_except)
+-	ld	r11,_TRAP(r1)
+-	andi.	r0,r11,1
+-	bne	.ret_from_except_lite
+-	REST_NVGPRS(r1)
+-
+-_GLOBAL(ret_from_except_lite)
+-	/*
+-	 * Disable interrupts so that current_thread_info()->flags
+-	 * can't change between when we test it and when we return
+-	 * from the interrupt.
+-	 */
+-	mfmsr	r10		/* Get current interrupt state */
+-	rldicl	r9,r10,48,1	/* clear MSR_EE */
+-	rotldi	r9,r9,16
+-	mtmsrd	r9,1		/* Update machine state */
+-
+-#ifdef CONFIG_PREEMPT
+-	clrrdi	r9,r1,THREAD_SHIFT	/* current_thread_info() */
+-	li	r0,_TIF_NEED_RESCHED	/* bits to check */
+-	ld	r3,_MSR(r1)
+-	ld	r4,TI_FLAGS(r9)
+-	/* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */
+-	rlwimi	r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING
+-	and.	r0,r4,r0	/* check NEED_RESCHED and maybe SIGPENDING */
+-	bne	do_work
+-
+-#else /* !CONFIG_PREEMPT */
+-	ld	r3,_MSR(r1)	/* Returning to user mode? */
+-	andi.	r3,r3,MSR_PR
+-	beq	restore		/* if not, just restore regs and return */
+-
+-	/* Check current_thread_info()->flags */
+-	clrrdi	r9,r1,THREAD_SHIFT
+-	ld	r4,TI_FLAGS(r9)
+-	andi.	r0,r4,_TIF_USER_WORK_MASK
+-	bne	do_work
+-#endif
+-
+-restore:
+-#ifdef CONFIG_PPC_ISERIES
+-	ld	r5,SOFTE(r1)
+-	cmpdi	0,r5,0
+-	beq	4f
+-	/* Check for pending interrupts (iSeries) */
+-	ld	r3,PACALPPACA+LPPACAANYINT(r13)
+-	cmpdi	r3,0
+-	beq+	4f			/* skip do_IRQ if no interrupts */
+-
+-	li	r3,0
+-	stb	r3,PACAPROCENABLED(r13)	/* ensure we are soft-disabled */
+-	ori	r10,r10,MSR_EE
+-	mtmsrd	r10			/* hard-enable again */
+-	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	bl	.do_IRQ
+-	b	.ret_from_except_lite		/* loop back and handle more */
+-
+-4:	stb	r5,PACAPROCENABLED(r13)
+-#endif
+-
+-	ld	r3,_MSR(r1)
+-	andi.	r0,r3,MSR_RI
+-	beq-	unrecov_restore
+-
+-	andi.	r0,r3,MSR_PR
+-
+-	/*
+-	 * r13 is our per cpu area, only restore it if we are returning to
+-	 * userspace
+-	 */
+-	beq	1f
+-	REST_GPR(13, r1)
+-1:
+-	ld	r3,_CTR(r1)
+-	ld	r0,_LINK(r1)
+-	mtctr	r3
+-	mtlr	r0
+-	ld	r3,_XER(r1)
+-	mtspr	XER,r3
+-
+-	REST_8GPRS(5, r1)
+-
+-	stdcx.	r0,0,r1		/* to clear the reservation */
+-
+-	mfmsr	r0
+-	li	r2, MSR_RI
+-	andc	r0,r0,r2
+-	mtmsrd	r0,1
+-
+-	ld	r0,_MSR(r1)
+-	mtspr	SRR1,r0
+-
+-	ld	r2,_CCR(r1)
+-	mtcrf	0xFF,r2
+-	ld	r2,_NIP(r1)
+-	mtspr	SRR0,r2
+-
+-	ld	r0,GPR0(r1)
+-	ld	r2,GPR2(r1)
+-	ld	r3,GPR3(r1)
+-	ld	r4,GPR4(r1)
+-	ld	r1,GPR1(r1)
+-
+-	rfid
+-	b	.	/* prevent speculative execution */
+-
+-/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */
+-do_work:
+-#ifdef CONFIG_PREEMPT
+-	andi.	r0,r3,MSR_PR	/* Returning to user mode? */
+-	bne	user_work
+-	/* Check that preempt_count() == 0 and interrupts are enabled */
+-	lwz	r8,TI_PREEMPT(r9)
+-	cmpwi	cr1,r8,0
+-#ifdef CONFIG_PPC_ISERIES
+-	ld	r0,SOFTE(r1)
+-	cmpdi	r0,0
+-#else
+-	andi.	r0,r3,MSR_EE
+-#endif
+-	crandc	eq,cr1*4+eq,eq
+-	bne	restore
+-	/* here we are preempting the current task */
+-1:
+-#ifdef CONFIG_PPC_ISERIES
+-	li	r0,1
+-	stb	r0,PACAPROCENABLED(r13)
+-#endif
+-	ori	r10,r10,MSR_EE
+-	mtmsrd	r10,1		/* reenable interrupts */
+-	bl	.preempt_schedule
+-	mfmsr	r10
+-	clrrdi	r9,r1,THREAD_SHIFT
+-	rldicl	r10,r10,48,1	/* disable interrupts again */
+-	rotldi	r10,r10,16
+-	mtmsrd	r10,1
+-	ld	r4,TI_FLAGS(r9)
+-	andi.	r0,r4,_TIF_NEED_RESCHED
+-	bne	1b
+-	b	restore
+-
+-user_work:
+-#endif
+-	/* Enable interrupts */
+-	ori	r10,r10,MSR_EE
+-	mtmsrd	r10,1
+-
+-	andi.	r0,r4,_TIF_NEED_RESCHED
+-	beq	1f
+-	bl	.schedule
+-	b	.ret_from_except_lite
+-
+-1:	bl	.save_nvgprs
+-	li	r3,0
+-	addi	r4,r1,STACK_FRAME_OVERHEAD
+-	bl	.do_signal
+-	b	.ret_from_except
+-
+-unrecov_restore:
+-	addi	r3,r1,STACK_FRAME_OVERHEAD
+-	bl	.unrecoverable_exception
+-	b	unrecov_restore
+-
+-#ifdef CONFIG_PPC_RTAS
+-/*
+- * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
+- * called with the MMU off.
+- *
+- * In addition, we need to be in 32b mode, at least for now.
+- * 
+- * Note: r3 is an input parameter to rtas, so don't trash it...
+- */
+-_GLOBAL(enter_rtas)
+-	mflr	r0
+-	std	r0,16(r1)
+-        stdu	r1,-RTAS_FRAME_SIZE(r1)	/* Save SP and create stack space. */
+-
+-	/* Because RTAS is running in 32b mode, it clobbers the high order half
+-	 * of all registers that it saves.  We therefore save those registers
+-	 * RTAS might touch to the stack.  (r0, r3-r13 are caller saved)
+-   	 */
+-	SAVE_GPR(2, r1)			/* Save the TOC */
+-	SAVE_GPR(13, r1)		/* Save paca */
+-	SAVE_8GPRS(14, r1)		/* Save the non-volatiles */
+-	SAVE_10GPRS(22, r1)		/* ditto */
+-
+-	mfcr	r4
+-	std	r4,_CCR(r1)
+-	mfctr	r5
+-	std	r5,_CTR(r1)
+-	mfspr	r6,XER
+-	std	r6,_XER(r1)
+-	mfdar	r7
+-	std	r7,_DAR(r1)
+-	mfdsisr	r8
+-	std	r8,_DSISR(r1)
+-	mfsrr0	r9
+-	std	r9,_SRR0(r1)
+-	mfsrr1	r10
+-	std	r10,_SRR1(r1)
+-
+-	/* There is no way it is acceptable to get here with interrupts enabled,
+-	 * check it with the asm equivalent of WARN_ON
+-	 */
+-	mfmsr	r6
+-	andi.	r0,r6,MSR_EE
+-1:	tdnei	r0,0
+-.section __bug_table,"a"
+-	.llong	1b,__LINE__ + 0x1000000, 1f, 2f
+-.previous
+-.section .rodata,"a"
+-1:	.asciz	__FILE__
+-2:	.asciz "enter_rtas"
+-.previous
+-	
+-	/* Unfortunately, the stack pointer and the MSR are also clobbered,
+-	 * so they are saved in the PACA which allows us to restore
+-	 * our original state after RTAS returns.
+-         */
+-	std	r1,PACAR1(r13)
+-        std	r6,PACASAVEDMSR(r13)
+-
+-	/* Setup our real return addr */	
+-	SET_REG_TO_LABEL(r4,.rtas_return_loc)
+-	SET_REG_TO_CONST(r9,KERNELBASE)
+-	sub	r4,r4,r9
+-       	mtlr	r4
+-
+-	li	r0,0
+-	ori	r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI
+-	andc	r0,r6,r0
+-	
+-        li      r9,1
+-        rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
+-	ori	r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP
+-	andc	r6,r0,r9
+-	ori	r6,r6,MSR_RI
+-	sync				/* disable interrupts so SRR0/1 */
+-	mtmsrd	r0			/* don't get trashed */
+-
+-	SET_REG_TO_LABEL(r4,rtas)
+-	ld	r5,RTASENTRY(r4)	/* get the rtas->entry value */
+-	ld	r4,RTASBASE(r4)		/* get the rtas->base value */
+-	
+-	mtspr	SRR0,r5
+-	mtspr	SRR1,r6
+-	rfid
+-	b	.	/* prevent speculative execution */
+-
+-_STATIC(rtas_return_loc)
+-	/* relocation is off at this point */
+-	mfspr	r4,SPRG3	        /* Get PACA */
+-	SET_REG_TO_CONST(r5, KERNELBASE)
+-        sub     r4,r4,r5                /* RELOC the PACA base pointer */
+-
+-	mfmsr   r6
+-	li	r0,MSR_RI
+-	andc	r6,r6,r0
+-	sync	
+-	mtmsrd  r6
+-        
+-        ld	r1,PACAR1(r4)           /* Restore our SP */
+-	LOADADDR(r3,.rtas_restore_regs)
+-        ld	r4,PACASAVEDMSR(r4)     /* Restore our MSR */
+-
+-	mtspr	SRR0,r3
+-	mtspr	SRR1,r4
+-	rfid
+-	b	.	/* prevent speculative execution */
+-
+-_STATIC(rtas_restore_regs)
+-	/* relocation is on at this point */
+-	REST_GPR(2, r1)			/* Restore the TOC */
+-	REST_GPR(13, r1)		/* Restore paca */
+-	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
+-	REST_10GPRS(22, r1)		/* ditto */
+-
+-	mfspr	r13,SPRG3
+-
+-	ld	r4,_CCR(r1)
+-	mtcr	r4
+-	ld	r5,_CTR(r1)
+-	mtctr	r5
+-	ld	r6,_XER(r1)
+-	mtspr	XER,r6
+-	ld	r7,_DAR(r1)
+-	mtdar	r7
+-	ld	r8,_DSISR(r1)
+-	mtdsisr	r8
+-	ld	r9,_SRR0(r1)
+-	mtsrr0	r9
+-	ld	r10,_SRR1(r1)
+-	mtsrr1	r10
+-
+-        addi	r1,r1,RTAS_FRAME_SIZE	/* Unstack our frame */
+-	ld	r0,16(r1)		/* get return address */
+-
+-	mtlr    r0
+-        blr				/* return to caller */
+-
+-#endif /* CONFIG_PPC_RTAS */
+-
+-#ifdef CONFIG_PPC_MULTIPLATFORM
+-
+-_GLOBAL(enter_prom)
+-	mflr	r0
+-	std	r0,16(r1)
+-        stdu	r1,-PROM_FRAME_SIZE(r1)	/* Save SP and create stack space */
+-
+-	/* Because PROM is running in 32b mode, it clobbers the high order half
+-	 * of all registers that it saves.  We therefore save those registers
+-	 * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
+-   	 */
+-	SAVE_8GPRS(2, r1)
+-	SAVE_GPR(13, r1)
+-	SAVE_8GPRS(14, r1)
+-	SAVE_10GPRS(22, r1)
+-	mfcr	r4
+-	std	r4,_CCR(r1)
+-	mfctr	r5
+-	std	r5,_CTR(r1)
+-	mfspr	r6,XER
+-	std	r6,_XER(r1)
+-	mfdar	r7
+-	std	r7,_DAR(r1)
+-	mfdsisr	r8
+-	std	r8,_DSISR(r1)
+-	mfsrr0	r9
+-	std	r9,_SRR0(r1)
+-	mfsrr1	r10
+-	std	r10,_SRR1(r1)
+-	mfmsr	r11
+-	std	r11,_MSR(r1)
+-
+-	/* Get the PROM entrypoint */
+-	ld	r0,GPR4(r1)
+-	mtlr	r0
+-
+-	/* Switch MSR to 32 bits mode
+-	 */
+-        mfmsr   r11
+-        li      r12,1
+-        rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
+-        andc    r11,r11,r12
+-        li      r12,1
+-        rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
+-        andc    r11,r11,r12
+-        mtmsrd  r11
+-        isync
+-
+-	/* Restore arguments & enter PROM here... */
+-	ld	r3,GPR3(r1)
+-	blrl
+-
+-	/* Just make sure that r1 top 32 bits didn't get
+-	 * corrupt by OF
+-	 */
+-	rldicl	r1,r1,0,32
+-
+-	/* Restore the MSR (back to 64 bits) */
+-	ld	r0,_MSR(r1)
+-	mtmsrd	r0
+-        isync
+-
+-	/* Restore other registers */
+-	REST_GPR(2, r1)
+-	REST_GPR(13, r1)
+-	REST_8GPRS(14, r1)
+-	REST_10GPRS(22, r1)
+-	ld	r4,_CCR(r1)
+-	mtcr	r4
+-	ld	r5,_CTR(r1)
+-	mtctr	r5
+-	ld	r6,_XER(r1)
+-	mtspr	XER,r6
+-	ld	r7,_DAR(r1)
+-	mtdar	r7
+-	ld	r8,_DSISR(r1)
+-	mtdsisr	r8
+-	ld	r9,_SRR0(r1)
+-	mtsrr0	r9
+-	ld	r10,_SRR1(r1)
+-	mtsrr1	r10
+-	
+-        addi	r1,r1,PROM_FRAME_SIZE
+-	ld	r0,16(r1)
+-	mtlr    r0
+-        blr
+-	
+-#endif	/* CONFIG_PPC_MULTIPLATFORM */
+diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
+--- a/arch/ppc64/kernel/head.S
++++ b/arch/ppc64/kernel/head.S
+@@ -36,6 +36,7 @@
+ #include <asm/setup.h>
+ #include <asm/hvcall.h>
+ #include <asm/iSeries/LparMap.h>
++#include <asm/thread_info.h>
+ 
+ #ifdef CONFIG_PPC_ISERIES
+ #define DO_SOFT_DISABLE
+@@ -80,7 +81,7 @@ _stext:
+ _GLOBAL(__start)
+ 	/* NOP this out unconditionally */
+ BEGIN_FTR_SECTION
+-	b .__start_initialization_multiplatform
++	b	.__start_initialization_multiplatform
+ END_FTR_SECTION(0, 1)
+ #endif /* CONFIG_PPC_MULTIPLATFORM */
+ 
+@@ -201,22 +202,22 @@ exception_marker:
+ #define EX_CCR		60
+ 
+ #define EXCEPTION_PROLOG_PSERIES(area, label)				\
+-	mfspr	r13,SPRG3;		/* get paca address into r13 */	\
++	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
+ 	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
+ 	std	r10,area+EX_R10(r13);					\
+ 	std	r11,area+EX_R11(r13);					\
+ 	std	r12,area+EX_R12(r13);					\
+-	mfspr	r9,SPRG1;						\
++	mfspr	r9,SPRN_SPRG1;						\
+ 	std	r9,area+EX_R13(r13);					\
+ 	mfcr	r9;							\
+ 	clrrdi	r12,r13,32;		/* get high part of &label */	\
+ 	mfmsr	r10;							\
+-	mfspr	r11,SRR0;		/* save SRR0 */			\
++	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
+ 	ori	r12,r12,(label)@l;	/* virt addr of handler */	\
+ 	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI;				\
+-	mtspr	SRR0,r12;						\
+-	mfspr	r12,SRR1;		/* and SRR1 */			\
+-	mtspr	SRR1,r10;						\
++	mtspr	SPRN_SRR0,r12;						\
++	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
++	mtspr	SPRN_SRR1,r10;						\
+ 	rfid;								\
+ 	b	.	/* prevent speculative execution */
+ 
+@@ -225,12 +226,12 @@ exception_marker:
+  * This code runs with relocation on.
+  */
+ #define EXCEPTION_PROLOG_ISERIES_1(area)				\
+-	mfspr	r13,SPRG3;		/* get paca address into r13 */	\
++	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
+ 	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
+ 	std	r10,area+EX_R10(r13);					\
+ 	std	r11,area+EX_R11(r13);					\
+ 	std	r12,area+EX_R12(r13);					\
+-	mfspr	r9,SPRG1;						\
++	mfspr	r9,SPRN_SPRG1;						\
+ 	std	r9,area+EX_R13(r13);					\
+ 	mfcr	r9
+ 
+@@ -283,7 +284,7 @@ exception_marker:
+ 	std	r9,_LINK(r1);						   \
+ 	mfctr	r10;			/* save CTR in stackframe	*/ \
+ 	std	r10,_CTR(r1);						   \
+-	mfspr	r11,XER;		/* save XER in stackframe	*/ \
++	mfspr	r11,SPRN_XER;		/* save XER in stackframe	*/ \
+ 	std	r11,_XER(r1);						   \
+ 	li	r9,(n)+1;						   \
+ 	std	r9,_TRAP(r1);		/* set trap number		*/ \
+@@ -300,7 +301,7 @@ exception_marker:
+ 	.globl label##_pSeries;				\
+ label##_pSeries:					\
+ 	HMT_MEDIUM;					\
+-	mtspr	SPRG1,r13;		/* save r13 */	\
++	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
+ 	RUNLATCH_ON(r13);				\
+ 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+ 
+@@ -308,7 +309,7 @@ label##_pSeries:					\
+ 	.globl label##_iSeries;				\
+ label##_iSeries:					\
+ 	HMT_MEDIUM;					\
+-	mtspr	SPRG1,r13;		/* save r13 */	\
++	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
+ 	RUNLATCH_ON(r13);				\
+ 	EXCEPTION_PROLOG_ISERIES_1(area);		\
+ 	EXCEPTION_PROLOG_ISERIES_2;			\
+@@ -318,7 +319,7 @@ label##_iSeries:					\
+ 	.globl label##_iSeries;						\
+ label##_iSeries:							\
+ 	HMT_MEDIUM;							\
+-	mtspr	SPRG1,r13;		/* save r13 */			\
++	mtspr	SPRN_SPRG1,r13;		/* save r13 */			\
+ 	RUNLATCH_ON(r13);						\
+ 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);				\
+ 	lbz	r10,PACAPROCENABLED(r13);				\
+@@ -388,7 +389,7 @@ __start_interrupts:
+ 	. = 0x200
+ _machine_check_pSeries:
+ 	HMT_MEDIUM
+-	mtspr	SPRG1,r13		/* save r13 */
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
+ 	RUNLATCH_ON(r13)
+ 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+ 
+@@ -396,18 +397,18 @@ _machine_check_pSeries:
+ 	.globl data_access_pSeries
+ data_access_pSeries:
+ 	HMT_MEDIUM
+-	mtspr	SPRG1,r13
++	mtspr	SPRN_SPRG1,r13
+ BEGIN_FTR_SECTION
+-	mtspr	SPRG2,r12
+-	mfspr	r13,DAR
+-	mfspr	r12,DSISR
++	mtspr	SPRN_SPRG2,r12
++	mfspr	r13,SPRN_DAR
++	mfspr	r12,SPRN_DSISR
+ 	srdi	r13,r13,60
+ 	rlwimi	r13,r12,16,0x20
+ 	mfcr	r12
+ 	cmpwi	r13,0x2c
+ 	beq	.do_stab_bolted_pSeries
+ 	mtcrf	0x80,r12
+-	mfspr	r12,SPRG2
++	mfspr	r12,SPRN_SPRG2
+ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
+ 
+@@ -415,19 +416,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ 	.globl data_access_slb_pSeries
+ data_access_slb_pSeries:
+ 	HMT_MEDIUM
+-	mtspr	SPRG1,r13
++	mtspr	SPRN_SPRG1,r13
+ 	RUNLATCH_ON(r13)
+-	mfspr	r13,SPRG3		/* get paca address into r13 */
++	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
+ 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
+ 	std	r10,PACA_EXSLB+EX_R10(r13)
+ 	std	r11,PACA_EXSLB+EX_R11(r13)
+ 	std	r12,PACA_EXSLB+EX_R12(r13)
+ 	std	r3,PACA_EXSLB+EX_R3(r13)
+-	mfspr	r9,SPRG1
++	mfspr	r9,SPRN_SPRG1
+ 	std	r9,PACA_EXSLB+EX_R13(r13)
+ 	mfcr	r9
+-	mfspr	r12,SRR1		/* and SRR1 */
+-	mfspr	r3,DAR
++	mfspr	r12,SPRN_SRR1		/* and SRR1 */
++	mfspr	r3,SPRN_DAR
+ 	b	.do_slb_miss		/* Rel. branch works in real mode */
+ 
+ 	STD_EXCEPTION_PSERIES(0x400, instruction_access)
+@@ -436,19 +437,19 @@ data_access_slb_pSeries:
+ 	.globl instruction_access_slb_pSeries
+ instruction_access_slb_pSeries:
+ 	HMT_MEDIUM
+-	mtspr	SPRG1,r13
++	mtspr	SPRN_SPRG1,r13
+ 	RUNLATCH_ON(r13)
+-	mfspr	r13,SPRG3		/* get paca address into r13 */
++	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
+ 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
+ 	std	r10,PACA_EXSLB+EX_R10(r13)
+ 	std	r11,PACA_EXSLB+EX_R11(r13)
+ 	std	r12,PACA_EXSLB+EX_R12(r13)
+ 	std	r3,PACA_EXSLB+EX_R3(r13)
+-	mfspr	r9,SPRG1
++	mfspr	r9,SPRN_SPRG1
+ 	std	r9,PACA_EXSLB+EX_R13(r13)
+ 	mfcr	r9
+-	mfspr	r12,SRR1		/* and SRR1 */
+-	mfspr	r3,SRR0			/* SRR0 is faulting address */
++	mfspr	r12,SPRN_SRR1		/* and SRR1 */
++	mfspr	r3,SPRN_SRR0			/* SRR0 is faulting address */
+ 	b	.do_slb_miss		/* Rel. branch works in real mode */
+ 
+ 	STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+@@ -466,15 +467,15 @@ system_call_pSeries:
+ 	RUNLATCH_ON(r9)
+ 	mr	r9,r13
+ 	mfmsr	r10
+-	mfspr	r13,SPRG3
+-	mfspr	r11,SRR0
++	mfspr	r13,SPRN_SPRG3
++	mfspr	r11,SPRN_SRR0
+ 	clrrdi	r12,r13,32
+ 	oris	r12,r12,system_call_common at h
+ 	ori	r12,r12,system_call_common at l
+-	mtspr	SRR0,r12
++	mtspr	SPRN_SRR0,r12
+ 	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI
+-	mfspr	r12,SRR1
+-	mtspr	SRR1,r10
++	mfspr	r12,SPRN_SRR1
++	mtspr	SPRN_SRR1,r10
+ 	rfid
+ 	b	.	/* prevent speculative execution */
+ 
+@@ -504,25 +505,25 @@ system_call_pSeries:
+ 	.align	7
+ _GLOBAL(do_stab_bolted_pSeries)
+ 	mtcrf	0x80,r12
+-	mfspr	r12,SPRG2
++	mfspr	r12,SPRN_SPRG2
+ 	EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
+ 
+ /*
+  * Vectors for the FWNMI option.  Share common code.
+  */
+-      .globl system_reset_fwnmi
++	.globl system_reset_fwnmi
+ system_reset_fwnmi:
+-      HMT_MEDIUM
+-      mtspr   SPRG1,r13               /* save r13 */
+-      RUNLATCH_ON(r13)
+-      EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
++	HMT_MEDIUM
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
++	RUNLATCH_ON(r13)
++	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+ 
+-      .globl machine_check_fwnmi
++	.globl machine_check_fwnmi
+ machine_check_fwnmi:
+-      HMT_MEDIUM
+-      mtspr   SPRG1,r13               /* save r13 */
+-      RUNLATCH_ON(r13)
+-      EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
++	HMT_MEDIUM
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
++	RUNLATCH_ON(r13)
++	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+ 
+ #ifdef CONFIG_PPC_ISERIES
+ /***  ISeries-LPAR interrupt handlers ***/
+@@ -531,18 +532,18 @@ machine_check_fwnmi:
+ 
+ 	.globl data_access_iSeries
+ data_access_iSeries:
+-	mtspr	SPRG1,r13
++	mtspr	SPRN_SPRG1,r13
+ BEGIN_FTR_SECTION
+-	mtspr	SPRG2,r12
+-	mfspr	r13,DAR
+-	mfspr	r12,DSISR
++	mtspr	SPRN_SPRG2,r12
++	mfspr	r13,SPRN_DAR
++	mfspr	r12,SPRN_DSISR
+ 	srdi	r13,r13,60
+ 	rlwimi	r13,r12,16,0x20
+ 	mfcr	r12
+ 	cmpwi	r13,0x2c
+ 	beq	.do_stab_bolted_iSeries
+ 	mtcrf	0x80,r12
+-	mfspr	r12,SPRG2
++	mfspr	r12,SPRN_SPRG2
+ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
+ 	EXCEPTION_PROLOG_ISERIES_2
+@@ -550,25 +551,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ 
+ .do_stab_bolted_iSeries:
+ 	mtcrf	0x80,r12
+-	mfspr	r12,SPRG2
++	mfspr	r12,SPRN_SPRG2
+ 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ 	EXCEPTION_PROLOG_ISERIES_2
+ 	b	.do_stab_bolted
+ 
+ 	.globl	data_access_slb_iSeries
+ data_access_slb_iSeries:
+-	mtspr	SPRG1,r13		/* save r13 */
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
+ 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ 	std	r3,PACA_EXSLB+EX_R3(r13)
+ 	ld	r12,PACALPPACA+LPPACASRR1(r13)
+-	mfspr	r3,DAR
++	mfspr	r3,SPRN_DAR
+ 	b	.do_slb_miss
+ 
+ 	STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
+ 
+ 	.globl	instruction_access_slb_iSeries
+ instruction_access_slb_iSeries:
+-	mtspr	SPRG1,r13		/* save r13 */
++	mtspr	SPRN_SPRG1,r13		/* save r13 */
+ 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ 	std	r3,PACA_EXSLB+EX_R3(r13)
+ 	ld	r12,PACALPPACA+LPPACASRR1(r13)
+@@ -586,7 +587,7 @@ instruction_access_slb_iSeries:
+ 	.globl	system_call_iSeries
+ system_call_iSeries:
+ 	mr	r9,r13
+-	mfspr	r13,SPRG3
++	mfspr	r13,SPRN_SPRG3
+ 	EXCEPTION_PROLOG_ISERIES_2
+ 	b	system_call_common
+ 
+@@ -596,7 +597,7 @@ system_call_iSeries:
+ 
+ 	.globl system_reset_iSeries
+ system_reset_iSeries:
+-	mfspr	r13,SPRG3		/* Get paca address */
++	mfspr	r13,SPRN_SPRG3		/* Get paca address */
+ 	mfmsr	r24
+ 	ori	r24,r24,MSR_RI
+ 	mtmsrd	r24			/* RI on */
+@@ -639,7 +640,7 @@ iSeries_secondary_smp_loop:
+ #endif /* CONFIG_SMP */
+ 	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
+ 	sc				/* Invoke the hypervisor via a system call */
+-	mfspr	r13,SPRG3		/* Put r13 back ???? */
++	mfspr	r13,SPRN_SPRG3		/* Put r13 back ???? */
+ 	b	1b			/* If SMP not configured, secondaries
+ 					 * loop forever */
+ 
+@@ -656,8 +657,8 @@ hardware_interrupt_iSeries_masked:
+ 	mtcrf	0x80,r9		/* Restore regs */
+ 	ld	r11,PACALPPACA+LPPACASRR0(r13)
+ 	ld	r12,PACALPPACA+LPPACASRR1(r13)
+-	mtspr	SRR0,r11
+-	mtspr	SRR1,r12
++	mtspr	SPRN_SRR0,r11
++	mtspr	SPRN_SRR1,r12
+ 	ld	r9,PACA_EXGEN+EX_R9(r13)
+ 	ld	r10,PACA_EXGEN+EX_R10(r13)
+ 	ld	r11,PACA_EXGEN+EX_R11(r13)
+@@ -713,8 +714,8 @@ bad_stack:
+ 	std	r10,GPR1(r1)
+ 	std	r11,_NIP(r1)
+ 	std	r12,_MSR(r1)
+-	mfspr	r11,DAR
+-	mfspr	r12,DSISR
++	mfspr	r11,SPRN_DAR
++	mfspr	r12,SPRN_DSISR
+ 	std	r11,_DAR(r1)
+ 	std	r12,_DSISR(r1)
+ 	mflr	r10
+@@ -746,6 +747,7 @@ bad_stack:
+  * any task or sent any task a signal, you should use
+  * ret_from_except or ret_from_except_lite instead of this.
+  */
++	.globl	fast_exception_return
+ fast_exception_return:
+ 	ld	r12,_MSR(r1)
+ 	ld	r11,_NIP(r1)
+@@ -766,8 +768,8 @@ fast_exception_return:
+ 	clrrdi	r10,r10,2		/* clear RI (LE is 0 already) */
+ 	mtmsrd	r10,1
+ 
+-	mtspr	SRR1,r12
+-	mtspr	SRR0,r11
++	mtspr	SPRN_SRR1,r12
++	mtspr	SPRN_SRR0,r11
+ 	REST_4GPRS(10, r1)
+ 	ld	r1,GPR1(r1)
+ 	rfid
+@@ -788,9 +790,9 @@ unrecov_fer:
+ 	.globl data_access_common
+ data_access_common:
+ 	RUNLATCH_ON(r10)		/* It wont fit in the 0x300 handler */
+-	mfspr	r10,DAR
++	mfspr	r10,SPRN_DAR
+ 	std	r10,PACA_EXGEN+EX_DAR(r13)
+-	mfspr	r10,DSISR
++	mfspr	r10,SPRN_DSISR
+ 	stw	r10,PACA_EXGEN+EX_DSISR(r13)
+ 	EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
+ 	ld	r3,PACA_EXGEN+EX_DAR(r13)
+@@ -821,9 +823,9 @@ hardware_interrupt_entry:
+ 	.align	7
+ 	.globl alignment_common
+ alignment_common:
+-	mfspr	r10,DAR
++	mfspr	r10,SPRN_DAR
+ 	std	r10,PACA_EXGEN+EX_DAR(r13)
+-	mfspr	r10,DSISR
++	mfspr	r10,SPRN_DSISR
+ 	stw	r10,PACA_EXGEN+EX_DSISR(r13)
+ 	EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
+ 	ld	r3,PACA_EXGEN+EX_DAR(r13)
+@@ -857,62 +859,6 @@ fp_unavailable_common:
+ 	bl	.kernel_fp_unavailable_exception
+ 	BUG_OPCODE
+ 
+-/*
+- * load_up_fpu(unused, unused, tsk)
+- * Disable FP for the task which had the FPU previously,
+- * and save its floating-point registers in its thread_struct.
+- * Enables the FPU for use in the kernel on return.
+- * On SMP we know the fpu is free, since we give it up every
+- * switch (ie, no lazy save of the FP registers).
+- * On entry: r13 == 'current' && last_task_used_math != 'current'
+- */
+-_STATIC(load_up_fpu)
+-	mfmsr	r5			/* grab the current MSR */
+-	ori	r5,r5,MSR_FP
+-	mtmsrd	r5			/* enable use of fpu now */
+-	isync
+-/*
+- * For SMP, we don't do lazy FPU switching because it just gets too
+- * horrendously complex, especially when a task switches from one CPU
+- * to another.  Instead we call giveup_fpu in switch_to.
+- *
+- */
+-#ifndef CONFIG_SMP
+-	ld	r3,last_task_used_math at got(r2)
+-	ld	r4,0(r3)
+-	cmpdi	0,r4,0
+-	beq	1f
+-	/* Save FP state to last_task_used_math's THREAD struct */
+-	addi	r4,r4,THREAD
+-	SAVE_32FPRS(0, r4)
+-	mffs	fr0
+-	stfd	fr0,THREAD_FPSCR(r4)
+-	/* Disable FP for last_task_used_math */
+-	ld	r5,PT_REGS(r4)
+-	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+-	li	r6,MSR_FP|MSR_FE0|MSR_FE1
+-	andc	r4,r4,r6
+-	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+-1:
+-#endif /* CONFIG_SMP */
+-	/* enable use of FP after return */
+-	ld	r4,PACACURRENT(r13)
+-	addi	r5,r4,THREAD		/* Get THREAD */
+-	ld	r4,THREAD_FPEXC_MODE(r5)
+-	ori	r12,r12,MSR_FP
+-	or	r12,r12,r4
+-	std	r12,_MSR(r1)
+-	lfd	fr0,THREAD_FPSCR(r5)
+-	mtfsf	0xff,fr0
+-	REST_32FPRS(0, r5)
+-#ifndef CONFIG_SMP
+-	/* Update last_task_used_math to 'current' */
+-	subi	r4,r5,THREAD		/* Back to 'current' */
+-	std	r4,0(r3)
+-#endif /* CONFIG_SMP */
+-	/* restore registers and return */
+-	b	fast_exception_return
+-
+ 	.align	7
+ 	.globl altivec_unavailable_common
+ altivec_unavailable_common:
+@@ -1120,7 +1066,7 @@ _GLOBAL(do_stab_bolted)
+ 
+ 	/* Hash to the primary group */
+ 	ld	r10,PACASTABVIRT(r13)
+-	mfspr	r11,DAR
++	mfspr	r11,SPRN_DAR
+ 	srdi	r11,r11,28
+ 	rldimi	r10,r11,7,52	/* r10 = first ste of the group */
+ 
+@@ -1162,7 +1108,7 @@ _GLOBAL(do_stab_bolted)
+ 2:	std	r9,8(r10)	/* Store the vsid part of the ste	*/
+ 	eieio
+ 
+-	mfspr	r11,DAR		/* Get the new esid			*/
++	mfspr	r11,SPRN_DAR		/* Get the new esid			*/
+ 	clrrdi	r11,r11,28	/* Permits a full 32b of ESID		*/
+ 	ori	r11,r11,0x90	/* Turn on valid and kp			*/
+ 	std	r11,0(r10)	/* Put new entry back into the stab	*/
+@@ -1182,8 +1128,8 @@ _GLOBAL(do_stab_bolted)
+ 	clrrdi	r10,r10,2
+ 	mtmsrd	r10,1
+ 
+-	mtspr	SRR0,r11
+-	mtspr	SRR1,r12
++	mtspr	SPRN_SRR0,r11
++	mtspr	SPRN_SRR1,r12
+ 	ld	r9,PACA_EXSLB+EX_R9(r13)
+ 	ld	r10,PACA_EXSLB+EX_R10(r13)
+ 	ld	r11,PACA_EXSLB+EX_R11(r13)
+@@ -1229,8 +1175,8 @@ _GLOBAL(do_slb_miss)
+ .machine	pop
+ 
+ #ifdef CONFIG_PPC_ISERIES
+-	mtspr	SRR0,r11
+-	mtspr	SRR1,r12
++	mtspr	SPRN_SRR0,r11
++	mtspr	SPRN_SRR1,r12
+ #endif /* CONFIG_PPC_ISERIES */
+ 	ld	r9,PACA_EXSLB+EX_R9(r13)
+ 	ld	r10,PACA_EXSLB+EX_R10(r13)
+@@ -1253,7 +1199,7 @@ unrecov_slb:
+  *
+  * On iSeries, the hypervisor must fill in at least one entry before
+  * we get control (with relocate on).  The address is give to the hv
+- * as a page number (see xLparMap in LparData.c), so this must be at a
++ * as a page number (see xLparMap in lpardata.c), so this must be at a
+  * fixed address (the linker can't compute (u64)&initial_stab >>
+  * PAGE_SHIFT).
+  */
+@@ -1316,7 +1262,7 @@ _GLOBAL(pSeries_secondary_smp_init)
+ 	mr	r3,r24			/* not found, copy phys to r3	 */
+ 	b	.kexec_wait		/* next kernel might do better	 */
+ 
+-2:	mtspr	SPRG3,r13		/* Save vaddr of paca in SPRG3	 */
++2:	mtspr	SPRN_SPRG3,r13		/* Save vaddr of paca in SPRG3	 */
+ 	/* From now on, r24 is expected to be logical cpuid */
+ 	mr	r24,r5
+ 3:	HMT_LOW
+@@ -1364,6 +1310,7 @@ _STATIC(__start_initialization_iSeries)
+ 	addi	r2,r2,0x4000
+ 
+ 	bl	.iSeries_early_setup
++	bl	.early_setup
+ 
+ 	/* relocation is on at this point */
+ 
+@@ -1554,20 +1501,17 @@ copy_to_here:
+ 	.section ".text";
+ 	.align 2 ;
+ 
+-	.globl	pmac_secondary_start_1	
+-pmac_secondary_start_1:	
+-	li	r24, 1
+-	b	.pmac_secondary_start
+-	
+-	.globl pmac_secondary_start_2
+-pmac_secondary_start_2:	
+-	li	r24, 2
+-	b	.pmac_secondary_start
+-	
+-	.globl pmac_secondary_start_3
+-pmac_secondary_start_3:
+-	li	r24, 3
+-	b	.pmac_secondary_start
++	.globl	__secondary_start_pmac_0
++__secondary_start_pmac_0:
++	/* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
++	li	r24,0
++	b	1f
++	li	r24,1
++	b	1f
++	li	r24,2
++	b	1f
++	li	r24,3
++1:
+ 	
+ _GLOBAL(pmac_secondary_start)
+ 	/* turn on 64-bit mode */
+@@ -1586,7 +1530,7 @@ _GLOBAL(pmac_secondary_start)
+ 	LOADADDR(r4, paca) 		 /* Get base vaddr of paca array	*/
+ 	mulli	r13,r24,PACA_SIZE	 /* Calculate vaddr of right paca */
+ 	add	r13,r13,r4		/* for this processor.		*/
+-	mtspr	SPRG3,r13		 /* Save vaddr of paca in SPRG3	*/
++	mtspr	SPRN_SPRG3,r13		 /* Save vaddr of paca in SPRG3	*/
+ 
+ 	/* Create a temp kernel stack for use before relocation is on.	*/
+ 	ld	r1,PACAEMERGSP(r13)
+@@ -1621,7 +1565,7 @@ _GLOBAL(__secondary_start)
+ 	/* Initialize the page table pointer register. */
+ 	LOADADDR(r6,_SDR1)
+ 	ld	r6,0(r6)		/* get the value of _SDR1	 */
+-	mtspr	SDR1,r6			/* set the htab location	 */
++	mtspr	SPRN_SDR1,r6			/* set the htab location	 */
+ #endif
+ 	/* Initialize the first segment table (or SLB) entry		 */
+ 	ld	r3,PACASTABVIRT(r13)	/* get addr of segment table	 */
+@@ -1650,7 +1594,7 @@ _GLOBAL(__secondary_start)
+ 	lwz	r3,PLATFORM(r3)		/* r3 = platform flags		 */
+ 	andi.	r3,r3,PLATFORM_LPAR	/* Test if bit 0 is set (LPAR bit) */
+ 	beq	98f			/* branch if result is 0  */
+-	mfspr	r3,PVR
++	mfspr	r3,SPRN_PVR
+ 	srwi	r3,r3,16
+ 	cmpwi	r3,0x37			/* SStar  */
+ 	beq	97f
+@@ -1674,8 +1618,8 @@ _GLOBAL(__secondary_start)
+ #ifdef DO_SOFT_DISABLE
+ 	ori	r4,r4,MSR_EE
+ #endif
+-	mtspr	SRR0,r3
+-	mtspr	SRR1,r4
++	mtspr	SPRN_SRR0,r3
++	mtspr	SPRN_SRR1,r4
+ 	rfid
+ 	b	.	/* prevent speculative execution */
+ 
+@@ -1737,7 +1681,7 @@ _STATIC(start_here_multiplatform)
+ 
+ #ifdef CONFIG_HMT
+ 	/* Start up the second thread on cpu 0 */
+-	mfspr	r3,PVR
++	mfspr	r3,SPRN_PVR
+ 	srwi	r3,r3,16
+ 	cmpwi	r3,0x34			/* Pulsar  */
+ 	beq	90f
+@@ -1797,7 +1741,7 @@ _STATIC(start_here_multiplatform)
+ 	mulli	r13,r27,PACA_SIZE	/* Calculate vaddr of right paca */
+ 	add	r13,r13,r24		/* for this processor.		 */
+ 	sub	r13,r13,r26		/* convert to physical addr	 */
+-	mtspr	SPRG3,r13		/* PPPBBB: Temp... -Peter */
++	mtspr	SPRN_SPRG3,r13		/* PPPBBB: Temp... -Peter */
+ 	
+ 	/* Do very early kernel initializations, including initial hash table,
+ 	 * stab and slb setup before we turn on relocation.	*/
+@@ -1814,7 +1758,7 @@ _STATIC(start_here_multiplatform)
+ 	lwz	r3,PLATFORM(r3)		/* r3 = platform flags */
+ 	andi.	r3,r3,PLATFORM_LPAR	/* Test if bit 0 is set (LPAR bit) */
+ 	beq	98f			/* branch if result is 0  */
+-	mfspr	r3,PVR
++	mfspr	r3,SPRN_PVR
+ 	srwi	r3,r3,16
+ 	cmpwi	r3,0x37			/* SStar */
+ 	beq	97f
+@@ -1838,12 +1782,12 @@ _STATIC(start_here_multiplatform)
+ 	LOADADDR(r6,_SDR1)		/* Only if NOT LPAR */
+ 	sub	r6,r6,r26
+ 	ld	r6,0(r6)		/* get the value of _SDR1 */
+-	mtspr	SDR1,r6			/* set the htab location  */
++	mtspr	SPRN_SDR1,r6			/* set the htab location  */
+ 98: 
+ 	LOADADDR(r3,.start_here_common)
+ 	SET_REG_TO_CONST(r4, MSR_KERNEL)
+-	mtspr	SRR0,r3
+-	mtspr	SRR1,r4
++	mtspr	SPRN_SRR0,r3
++	mtspr	SPRN_SRR1,r4
+ 	rfid
+ 	b	.	/* prevent speculative execution */
+ #endif /* CONFIG_PPC_MULTIPLATFORM */
+@@ -1874,7 +1818,7 @@ _STATIC(start_here_common)
+ 	LOADADDR(r24, paca) 		/* Get base vaddr of paca array  */
+ 	mulli	r13,r26,PACA_SIZE	/* Calculate vaddr of right paca */
+ 	add	r13,r13,r24		/* for this processor.		 */
+-	mtspr	SPRG3,r13
++	mtspr	SPRN_SPRG3,r13
+ 
+ 	/* ptr to current */
+ 	LOADADDR(r4,init_task)
+@@ -1901,7 +1845,7 @@ _STATIC(start_here_common)
+ _GLOBAL(hmt_init)
+ #ifdef CONFIG_HMT
+ 	LOADADDR(r5, hmt_thread_data)
+-	mfspr	r7,PVR
++	mfspr	r7,SPRN_PVR
+ 	srwi	r7,r7,16
+ 	cmpwi	r7,0x34			/* Pulsar  */
+ 	beq	90f
+@@ -1910,10 +1854,10 @@ _GLOBAL(hmt_init)
+ 	cmpwi	r7,0x37			/* SStar   */
+ 	beq	91f
+ 	b	101f
+-90:	mfspr	r6,PIR
++90:	mfspr	r6,SPRN_PIR
+ 	andi.	r6,r6,0x1f
+ 	b	92f
+-91:	mfspr	r6,PIR
++91:	mfspr	r6,SPRN_PIR
+ 	andi.	r6,r6,0x3ff
+ 92:	sldi	r4,r24,3
+ 	stwx	r6,r5,r4
+@@ -1924,8 +1868,8 @@ __hmt_secondary_hold:
+ 	LOADADDR(r5, hmt_thread_data)
+ 	clrldi	r5,r5,4
+ 	li	r7,0
+-	mfspr	r6,PIR
+-	mfspr	r8,PVR
++	mfspr	r6,SPRN_PIR
++	mfspr	r8,SPRN_PVR
+ 	srwi	r8,r8,16
+ 	cmpwi	r8,0x34
+ 	bne	93f
+@@ -1951,39 +1895,41 @@ __hmt_secondary_hold:
+ _GLOBAL(hmt_start_secondary)
+ 	LOADADDR(r4,__hmt_secondary_hold)
+ 	clrldi	r4,r4,4
+-	mtspr	NIADORM, r4
+-	mfspr	r4, MSRDORM
++	mtspr	SPRN_NIADORM, r4
++	mfspr	r4, SPRN_MSRDORM
+ 	li	r5, -65
+ 	and	r4, r4, r5
+-	mtspr	MSRDORM, r4
++	mtspr	SPRN_MSRDORM, r4
+ 	lis	r4,0xffef
+ 	ori	r4,r4,0x7403
+-	mtspr	TSC, r4
++	mtspr	SPRN_TSC, r4
+ 	li	r4,0x1f4
+-	mtspr	TST, r4
+-	mfspr	r4, HID0
++	mtspr	SPRN_TST, r4
++	mfspr	r4, SPRN_HID0
+ 	ori	r4, r4, 0x1
+-	mtspr	HID0, r4
++	mtspr	SPRN_HID0, r4
+ 	mfspr	r4, SPRN_CTRLF
+ 	oris	r4, r4, 0x40
+ 	mtspr	SPRN_CTRLT, r4
+ 	blr
+ #endif
+ 
+-#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES))
++#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP)
+ _GLOBAL(smp_release_cpus)
+ 	/* All secondary cpus are spinning on a common
+ 	 * spinloop, release them all now so they can start
+ 	 * to spin on their individual paca spinloops.
+ 	 * For non SMP kernels, the secondary cpus never
+ 	 * get out of the common spinloop.
++	 * XXX This does nothing useful on iSeries, secondaries are
++	 * already waiting on their paca.
+ 	 */
+ 	li	r3,1
+ 	LOADADDR(r5,__secondary_hold_spinloop)
+ 	std	r3,0(r5)
+ 	sync
+ 	blr
+-#endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */
++#endif /* CONFIG_SMP */
+ 
+ 
+ /*
+@@ -1992,7 +1938,7 @@ _GLOBAL(smp_release_cpus)
+  */
+ 	.section ".bss"
+ 
+-	.align	12
++	.align	PAGE_SHIFT
+ 
+ 	.globl	empty_zero_page
+ empty_zero_page:
+diff --git a/arch/ppc64/kernel/hvCall.S b/arch/ppc64/kernel/hvCall.S
+deleted file mode 100644
+--- a/arch/ppc64/kernel/hvCall.S
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/*
+- * arch/ppc64/kernel/hvCall.S
+- *
+- *
+- * This file contains the code to perform calls to the
+- * iSeries LPAR hypervisor
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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>
+-#include <asm/processor.h>
+-
+-	.text
+-
+-/* 
+- * Hypervisor call
+- * 
+- * Invoke the iSeries hypervisor via the System Call instruction
+- * Parameters are passed to this routine in registers r3 - r10
+- * 
+- * r3 contains the HV function to be called
+- * r4-r10 contain the operands to the hypervisor function
+- *
+- */
+-
+-_GLOBAL(HvCall)
+-_GLOBAL(HvCall0)
+-_GLOBAL(HvCall1)
+-_GLOBAL(HvCall2)
+-_GLOBAL(HvCall3)
+-_GLOBAL(HvCall4)
+-_GLOBAL(HvCall5)
+-_GLOBAL(HvCall6)
+-_GLOBAL(HvCall7)
+-
+-
+-	mfcr	r0
+-	std	r0,-8(r1)
+-	stdu	r1,-(STACK_FRAME_OVERHEAD+16)(r1)
+-	
+-	/* r0 = 0xffffffffffffffff indicates a hypervisor call */
+-	
+-	li	r0,-1
+-	
+-	/* Invoke the hypervisor */
+-
+-	sc
+-
+-	ld	r1,0(r1)
+-	ld	r0,-8(r1)
+-	mtcrf	0xff,r0
+-
+-	/*  return to caller, return value in r3 */
+-	
+-	blr
+-
+-_GLOBAL(HvCall0Ret16)
+-_GLOBAL(HvCall1Ret16)
+-_GLOBAL(HvCall2Ret16)
+-_GLOBAL(HvCall3Ret16)
+-_GLOBAL(HvCall4Ret16)
+-_GLOBAL(HvCall5Ret16)
+-_GLOBAL(HvCall6Ret16)
+-_GLOBAL(HvCall7Ret16)
+-
+-	mfcr	r0
+-	std	r0,-8(r1)
+-	std	r31,-16(r1)
+-	stdu	r1,-(STACK_FRAME_OVERHEAD+32)(r1)
+-
+-	mr	r31,r4
+-	li	r0,-1
+-	mr	r4,r5
+-	mr	r5,r6
+-	mr	r6,r7
+-	mr	r7,r8
+-	mr	r8,r9
+-	mr	r9,r10
+-
+-	sc
+-
+-	std	r3,0(r31)
+-	std	r4,8(r31)
+-
+-	mr	r3,r5
+-
+-	ld	r1,0(r1)
+-	ld	r0,-8(r1)
+-	mtcrf	0xff,r0
+-	ld	r31,-16(r1)
+-	
+-	blr
+-
+-
+diff --git a/arch/ppc64/kernel/hvcserver.c b/arch/ppc64/kernel/hvcserver.c
+--- a/arch/ppc64/kernel/hvcserver.c
++++ b/arch/ppc64/kernel/hvcserver.c
+@@ -22,6 +22,8 @@
+ #include <linux/kernel.h>
+ #include <linux/list.h>
+ #include <linux/module.h>
++#include <linux/slab.h>
++
+ #include <asm/hvcall.h>
+ #include <asm/hvcserver.h>
+ #include <asm/io.h>
+diff --git a/arch/ppc64/kernel/i8259.c b/arch/ppc64/kernel/i8259.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/i8259.c
++++ /dev/null
+@@ -1,177 +0,0 @@
+-/*
+- * c 2001 PPC64 Team, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-#include <linux/stddef.h>
+-#include <linux/init.h>
+-#include <linux/sched.h>
+-#include <linux/signal.h>
+-#include <linux/cache.h>
+-#include <linux/irq.h>
+-#include <linux/interrupt.h>
+-#include <asm/io.h>
+-#include <asm/ppcdebug.h>
+-#include "i8259.h"
+-
+-unsigned char cached_8259[2] = { 0xff, 0xff };
+-#define cached_A1 (cached_8259[0])
+-#define cached_21 (cached_8259[1])
+-
+-static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(i8259_lock);
+-
+-static int i8259_pic_irq_offset;
+-static int i8259_present;
+-
+-int i8259_irq(int cpu)
+-{
+-	int irq;
+-	
+-	spin_lock/*_irqsave*/(&i8259_lock/*, flags*/);
+-        /*
+-         * Perform an interrupt acknowledge cycle on controller 1
+-         */                                                             
+-        outb(0x0C, 0x20);
+-        irq = inb(0x20) & 7;                                   
+-        if (irq == 2)                                                     
+-        {                                                                   
+-                /*                                     
+-                 * Interrupt is cascaded so perform interrupt
+-                 * acknowledge on controller 2
+-                 */
+-                outb(0x0C, 0xA0);                      
+-                irq = (inb(0xA0) & 7) + 8;
+-        }
+-        else if (irq==7)                                
+-        {
+-                /*                               
+-                 * This may be a spurious interrupt
+-                 *                         
+-                 * Read the interrupt status register. If the most
+-                 * significant bit is not set then there is no valid
+-		 * interrupt
+-		 */
+-		outb(0x0b, 0x20);
+-		if(~inb(0x20)&0x80) {
+-			spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
+-			return -1;
+-		}
+-	}
+-	spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
+-	return irq;
+-}
+-
+-static void i8259_mask_and_ack_irq(unsigned int irq_nr)
+-{
+-	unsigned long flags;
+-	
+-	spin_lock_irqsave(&i8259_lock, flags);
+-        if ( irq_nr >= i8259_pic_irq_offset )
+-                irq_nr -= i8259_pic_irq_offset;
+-
+-        if (irq_nr > 7) {                                                   
+-                cached_A1 |= 1 << (irq_nr-8);                                   
+-                inb(0xA1);      /* DUMMY */                                     
+-                outb(cached_A1,0xA1);                                           
+-                outb(0x20,0xA0);        /* Non-specific EOI */             
+-                outb(0x20,0x20);        /* Non-specific EOI to cascade */
+-        } else {                                                            
+-                cached_21 |= 1 << irq_nr;                                   
+-                inb(0x21);      /* DUMMY */                                 
+-                outb(cached_21,0x21);
+-                outb(0x20,0x20);        /* Non-specific EOI */                 
+-        }                                                                
+-	spin_unlock_irqrestore(&i8259_lock, flags);
+-}
+-
+-static void i8259_set_irq_mask(int irq_nr)
+-{
+-        outb(cached_A1,0xA1);
+-        outb(cached_21,0x21);
+-}
+-
+-static void i8259_mask_irq(unsigned int irq_nr)
+-{
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&i8259_lock, flags);
+-        if ( irq_nr >= i8259_pic_irq_offset )
+-                irq_nr -= i8259_pic_irq_offset;
+-        if ( irq_nr < 8 )
+-                cached_21 |= 1 << irq_nr;
+-        else
+-                cached_A1 |= 1 << (irq_nr-8);
+-        i8259_set_irq_mask(irq_nr);
+-	spin_unlock_irqrestore(&i8259_lock, flags);
+-}
+-
+-static void i8259_unmask_irq(unsigned int irq_nr)
+-{
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&i8259_lock, flags);
+-        if ( irq_nr >= i8259_pic_irq_offset )
+-                irq_nr -= i8259_pic_irq_offset;
+-        if ( irq_nr < 8 )
+-                cached_21 &= ~(1 << irq_nr);
+-        else
+-                cached_A1 &= ~(1 << (irq_nr-8));
+-        i8259_set_irq_mask(irq_nr);
+-	spin_unlock_irqrestore(&i8259_lock, flags);
+-}
+-
+-static void i8259_end_irq(unsigned int irq)
+-{
+-	if (!(get_irq_desc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
+-	    get_irq_desc(irq)->action)
+-		i8259_unmask_irq(irq);
+-}
+-
+-struct hw_interrupt_type i8259_pic = {
+-	.typename = " i8259    ",
+-	.enable = i8259_unmask_irq,
+-	.disable = i8259_mask_irq,
+-	.ack = i8259_mask_and_ack_irq,
+-	.end = i8259_end_irq,
+-};
+-
+-void __init i8259_init(int offset)
+-{
+-	unsigned long flags;
+-	
+-	spin_lock_irqsave(&i8259_lock, flags);
+-	i8259_pic_irq_offset = offset;
+-	i8259_present = 1;
+-        /* init master interrupt controller */
+-        outb(0x11, 0x20); /* Start init sequence */
+-        outb(0x00, 0x21); /* Vector base */
+-        outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
+-        outb(0x01, 0x21); /* Select 8086 mode */
+-        outb(0xFF, 0x21); /* Mask all */
+-        /* init slave interrupt controller */
+-        outb(0x11, 0xA0); /* Start init sequence */
+-        outb(0x08, 0xA1); /* Vector base */
+-        outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
+-        outb(0x01, 0xA1); /* Select 8086 mode */
+-        outb(0xFF, 0xA1); /* Mask all */
+-        outb(cached_A1, 0xA1);
+-        outb(cached_21, 0x21);
+-	spin_unlock_irqrestore(&i8259_lock, flags);
+-        
+-}
+-
+-static int i8259_request_cascade(void)
+-{
+-	if (!i8259_present)
+-		return -ENODEV;
+-
+-        request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT,
+-                     "82c59 secondary cascade", NULL );
+-
+-	return 0;
+-}
+-
+-arch_initcall(i8259_request_cascade);
+diff --git a/arch/ppc64/kernel/i8259.h b/arch/ppc64/kernel/i8259.h
+deleted file mode 100644
+--- a/arch/ppc64/kernel/i8259.h
++++ /dev/null
+@@ -1,17 +0,0 @@
+-/*
+- * c 2001 PPC 64 Team, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-#ifndef _PPC_KERNEL_i8259_H
+-#define _PPC_KERNEL_i8259_H
+-
+-extern struct hw_interrupt_type i8259_pic;
+-
+-extern void i8259_init(int offset);
+-extern int i8259_irq(int);
+-
+-#endif /* _PPC_KERNEL_i8259_H */
+diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_VpdInfo.c
++++ /dev/null
+@@ -1,268 +0,0 @@
+-/*
+- * File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb  2 2001.
+- *
+- * This code gets the card location of the hardware
+- * Copyright (C) 2001  <Allan H Trautman> <IBM Corp>
+- * Copyright (C) 2005  Stephen Rothwel, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the:
+- * Free Software Foundation, Inc.,
+- * 59 Temple Place, Suite 330,
+- * Boston, MA  02111-1307  USA
+- *
+- * Change Activity:
+- *   Created, Feb 2, 2001
+- *   Ported to ppc64, August 20, 2001
+- * End Change Activity
+- */
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <asm/types.h>
+-#include <asm/resource.h>
+-
+-#include <asm/iSeries/HvCallPci.h>
+-#include <asm/iSeries/HvTypes.h>
+-#include <asm/iSeries/iSeries_pci.h>
+-
+-/*
+- * Size of Bus VPD data
+- */
+-#define BUS_VPDSIZE      1024
+-
+-/*
+- * Bus Vpd Tags
+- */
+-#define  VpdEndOfAreaTag   0x79
+-#define  VpdIdStringTag    0x82
+-#define  VpdVendorAreaTag  0x84
+-
+-/*
+- * Mfg Area Tags
+- */
+-#define  VpdFruFrameId    0x4649     // "FI"
+-#define  VpdSlotMapFormat 0x4D46     // "MF"
+-#define  VpdSlotMap       0x534D     // "SM"
+-
+-/*
+- * Structures of the areas
+- */
+-struct MfgVpdAreaStruct {
+-	u16 Tag;
+-	u8  TagLength;
+-	u8  AreaData1;
+-	u8  AreaData2;
+-};
+-typedef struct MfgVpdAreaStruct MfgArea;
+-#define MFG_ENTRY_SIZE   3
+-
+-struct SlotMapStruct {
+-	u8   AgentId;
+-	u8   SecondaryAgentId;
+-	u8   PhbId;
+-	char CardLocation[3];
+-	char Parms[8];
+-	char Reserved[2];
+-};
+-typedef struct SlotMapStruct SlotMap;
+-#define SLOT_ENTRY_SIZE   16
+-
+-/*
+- * Parse the Slot Area
+- */
+-static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
+-		HvAgentId agent, u8 *PhbId, char card[4])
+-{
+-	int SlotMapLen = MapLen;
+-	SlotMap *SlotMapPtr = MapPtr;
+-
+-	/*
+-	 * Parse Slot label until we find the one requested
+-	 */
+-	while (SlotMapLen > 0) {
+-		if (SlotMapPtr->AgentId == agent) {
+-			/*
+-			 * If Phb wasn't found, grab the entry first one found.
+-			 */
+-			if (*PhbId == 0xff)
+-				*PhbId = SlotMapPtr->PhbId;
+-			/* Found it, extract the data. */
+-			if (SlotMapPtr->PhbId == *PhbId) {
+-				memcpy(card, &SlotMapPtr->CardLocation, 3);
+-				card[3]  = 0;
+-				break;
+-			}
+-		}
+-		/* Point to the next Slot */
+-		SlotMapPtr = (SlotMap *)((char *)SlotMapPtr + SLOT_ENTRY_SIZE);
+-		SlotMapLen -= SLOT_ENTRY_SIZE;
+-	}
+-}
+-
+-/*
+- * Parse the Mfg Area
+- */
+-static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
+-		HvAgentId agent, u8 *PhbId,
+-		u8 *frame, char card[4])
+-{
+-	MfgArea *MfgAreaPtr = (MfgArea *)AreaData;
+-	int MfgAreaLen = AreaLen;
+-	u16 SlotMapFmt = 0;
+-
+-	/* Parse Mfg Data */
+-	while (MfgAreaLen > 0) {
+-		int MfgTagLen = MfgAreaPtr->TagLength;
+-		/* Frame ID         (FI 4649020310 ) */
+-		if (MfgAreaPtr->Tag == VpdFruFrameId)		/* FI  */
+-			*frame = MfgAreaPtr->AreaData1;
+-		/* Slot Map Format  (MF 4D46020004 ) */
+-		else if (MfgAreaPtr->Tag == VpdSlotMapFormat)	/* MF  */
+-			SlotMapFmt = (MfgAreaPtr->AreaData1 * 256)
+-				+ MfgAreaPtr->AreaData2;
+-		/* Slot Map         (SM 534D90 */
+-		else if (MfgAreaPtr->Tag == VpdSlotMap)	{	/* SM  */
+-			SlotMap *SlotMapPtr;
+-
+-			if (SlotMapFmt == 0x1004)
+-				SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
+-						+ MFG_ENTRY_SIZE + 1);
+-			else
+-				SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
+-						+ MFG_ENTRY_SIZE);
+-			iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen,
+-					agent, PhbId, card);
+-		}
+-		/*
+-		 * Point to the next Mfg Area
+-		 * Use defined size, sizeof give wrong answer
+-		 */
+-		MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen
+-				+ MFG_ENTRY_SIZE);
+-		MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE);
+-	}
+-}
+-
+-/*
+- * Look for "BUS".. Data is not Null terminated.
+- * PHBID of 0xFF indicates PHB was not found in VPD Data.
+- */
+-static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
+-{
+-	u8 *PhbPtr = AreaPtr;
+-	int DataLen = AreaLength;
+-	char PhbId = 0xFF;
+-
+-	while (DataLen > 0) {
+-		if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U')
+-				&& (*(PhbPtr + 2) == 'S')) {
+-			PhbPtr += 3;
+-			while (*PhbPtr == ' ')
+-				++PhbPtr;
+-			PhbId = (*PhbPtr & 0x0F);
+-			break;
+-		}
+-		++PhbPtr;
+-		--DataLen;
+-	}
+-	return PhbId;
+-}
+-
+-/*
+- * Parse out the VPD Areas
+- */
+-static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
+-		HvAgentId agent, u8 *frame, char card[4])
+-{
+-	u8 *TagPtr = VpdData;
+-	int DataLen = VpdDataLen - 3;
+-	u8 PhbId;
+-
+-	while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
+-		int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
+-		u8 *AreaData  = TagPtr + 3;
+-
+-		if (*TagPtr == VpdIdStringTag)
+-			PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
+-		else if (*TagPtr == VpdVendorAreaTag)
+-			iSeries_Parse_MfgArea(AreaData, AreaLen,
+-					agent, &PhbId, frame, card);
+-		/* Point to next Area. */
+-		TagPtr  = AreaData + AreaLen;
+-		DataLen -= AreaLen;
+-	}
+-}
+-
+-static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
+-		u8 *frame, char card[4])
+-{
+-	int BusVpdLen = 0;
+-	u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
+-
+-	if (BusVpdPtr == NULL) {
+-		printk("PCI: Bus VPD Buffer allocation failure.\n");
+-		return;
+-	}
+-	BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr),
+-					BUS_VPDSIZE);
+-	if (BusVpdLen == 0) {
+-		printk("PCI: Bus VPD Buffer zero length.\n");
+-		goto out_free;
+-	}
+-	/* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */
+-	/* Make sure this is what I think it is */
+-	if (*BusVpdPtr != VpdIdStringTag) {	/* 0x82 */
+-		printk("PCI: Bus VPD Buffer missing starting tag.\n");
+-		goto out_free;
+-	}
+-	iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
+-out_free:
+-	kfree(BusVpdPtr);
+-}
+-
+-/*
+- * Prints the device information.
+- * - Pass in pci_dev* pointer to the device.
+- * - Pass in the device count
+- *
+- * Format:
+- * PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet
+- * controller
+- */
+-void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
+-{
+-	struct iSeries_Device_Node *DevNode = PciDev->sysdata;
+-	u16 bus;
+-	u8 frame;
+-	char card[4];
+-	HvSubBusNumber subbus;
+-	HvAgentId agent;
+-
+-	if (DevNode == NULL) {
+-		printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n",
+-				count);
+-		return;
+-	}
+-
+-	bus = ISERIES_BUS(DevNode);
+-	subbus = ISERIES_SUBBUS(DevNode);
+-	agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
+-			ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
+-	iSeries_Get_Location_Code(bus, agent, &frame, card);
+-
+-	printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s  ",
+-			count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor,
+-			frame, card);
+-	printk("0x%04X\n", (int)(PciDev->class >> 8));
+-}
+diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/ppc64/kernel/iSeries_htab.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_htab.c
++++ /dev/null
+@@ -1,236 +0,0 @@
+-/*
+- * iSeries hashtable management.
+- * 	Derived from pSeries_htab.c
+- *
+- * SMP scalability work:
+- *    Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, 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 <asm/machdep.h>
+-#include <asm/pgtable.h>
+-#include <asm/mmu.h>
+-#include <asm/mmu_context.h>
+-#include <asm/iSeries/HvCallHpt.h>
+-#include <asm/abs_addr.h>
+-#include <linux/spinlock.h>
+-
+-static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp = { [0 ... 63] = SPIN_LOCK_UNLOCKED};
+-
+-/*
+- * Very primitive algorithm for picking up a lock
+- */
+-static inline void iSeries_hlock(unsigned long slot)
+-{
+-	if (slot & 0x8)
+-		slot = ~slot;
+-	spin_lock(&iSeries_hlocks[(slot >> 4) & 0x3f]);
+-}
+-
+-static inline void iSeries_hunlock(unsigned long slot)
+-{
+-	if (slot & 0x8)
+-		slot = ~slot;
+-	spin_unlock(&iSeries_hlocks[(slot >> 4) & 0x3f]);
+-}
+-
+-static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
+-				unsigned long prpn, unsigned long vflags,
+-				unsigned long rflags)
+-{
+-	unsigned long arpn;
+-	long slot;
+-	hpte_t lhpte;
+-	int secondary = 0;
+-
+-	/*
+-	 * The hypervisor tries both primary and secondary.
+-	 * If we are being called to insert in the secondary,
+-	 * it means we have already tried both primary and secondary,
+-	 * so we return failure immediately.
+-	 */
+-	if (vflags & HPTE_V_SECONDARY)
+-		return -1;
+-
+-	iSeries_hlock(hpte_group);
+-
+-	slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
+-	BUG_ON(lhpte.v & HPTE_V_VALID);
+-
+-	if (slot == -1)	{ /* No available entry found in either group */
+-		iSeries_hunlock(hpte_group);
+-		return -1;
+-	}
+-
+-	if (slot < 0) {		/* MSB set means secondary group */
+-		vflags |= HPTE_V_SECONDARY;
+-		secondary = 1;
+-		slot &= 0x7fffffffffffffff;
+-	}
+-
+-	arpn = phys_to_abs(prpn << PAGE_SHIFT) >> PAGE_SHIFT;
+-
+-	lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
+-	lhpte.r = (arpn << HPTE_R_RPN_SHIFT) | rflags;
+-
+-	/* Now fill in the actual HPTE */
+-	HvCallHpt_addValidate(slot, secondary, &lhpte);
+-
+-	iSeries_hunlock(hpte_group);
+-
+-	return (secondary << 3) | (slot & 7);
+-}
+-
+-static unsigned long iSeries_hpte_getword0(unsigned long slot)
+-{
+-	hpte_t hpte;
+-
+-	HvCallHpt_get(&hpte, slot);
+-	return hpte.v;
+-}
+-
+-static long iSeries_hpte_remove(unsigned long hpte_group)
+-{
+-	unsigned long slot_offset;
+-	int i;
+-	unsigned long hpte_v;
+-
+-	/* Pick a random slot to start at */
+-	slot_offset = mftb() & 0x7;
+-
+-	iSeries_hlock(hpte_group);
+-
+-	for (i = 0; i < HPTES_PER_GROUP; i++) {
+-		hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);
+-
+-		if (! (hpte_v & HPTE_V_BOLTED)) {
+-			HvCallHpt_invalidateSetSwBitsGet(hpte_group + 
+-							 slot_offset, 0, 0);
+-			iSeries_hunlock(hpte_group);
+-			return i;
+-		}
+-
+-		slot_offset++;
+-		slot_offset &= 0x7;
+-	}
+-
+-	iSeries_hunlock(hpte_group);
+-
+-	return -1;
+-}
+-
+-/*
+- * The HyperVisor expects the "flags" argument in this form:
+- * 	bits  0..59 : reserved
+- * 	bit      60 : N
+- * 	bits 61..63 : PP2,PP1,PP0
+- */
+-static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
+-				  unsigned long va, int large, int local)
+-{
+-	hpte_t hpte;
+-	unsigned long avpn = va >> 23;
+-
+-	iSeries_hlock(slot);
+-
+-	HvCallHpt_get(&hpte, slot);
+-	if ((HPTE_V_AVPN_VAL(hpte.v) == avpn) && (hpte.v & HPTE_V_VALID)) {
+-		/*
+-		 * Hypervisor expects bits as NPPP, which is
+-		 * different from how they are mapped in our PP.
+-		 */
+-		HvCallHpt_setPp(slot, (newpp & 0x3) | ((newpp & 0x4) << 1));
+-		iSeries_hunlock(slot);
+-		return 0;
+-	}
+-	iSeries_hunlock(slot);
+-
+-	return -1;
+-}
+-
+-/*
+- * Functions used to find the PTE for a particular virtual address. 
+- * Only used during boot when bolting pages.
+- *
+- * Input : vpn      : virtual page number
+- * Output: PTE index within the page table of the entry
+- *         -1 on failure
+- */
+-static long iSeries_hpte_find(unsigned long vpn)
+-{
+-	hpte_t hpte;
+-	long slot;
+-
+-	/*
+-	 * The HvCallHpt_findValid interface is as follows:
+-	 * 0xffffffffffffffff : No entry found.
+-	 * 0x00000000xxxxxxxx : Entry found in primary group, slot x
+-	 * 0x80000000xxxxxxxx : Entry found in secondary group, slot x
+-	 */
+-	slot = HvCallHpt_findValid(&hpte, vpn); 
+-	if (hpte.v & HPTE_V_VALID) {
+-		if (slot < 0) {
+-			slot &= 0x7fffffffffffffff;
+-			slot = -slot;
+-		}
+-	} else
+-		slot = -1;
+-	return slot;
+-}
+-
+-/*
+- * Update the page protection bits. Intended to be used to create
+- * guard pages for kernel data structures on pages which are bolted
+- * in the HPT. Assumes pages being operated on will not be stolen.
+- * Does not work on large pages.
+- *
+- * No need to lock here because we should be the only user.
+- */
+-static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
+-{
+-	unsigned long vsid,va,vpn;
+-	long slot;
+-
+-	vsid = get_kernel_vsid(ea);
+-	va = (vsid << 28) | (ea & 0x0fffffff);
+-	vpn = va >> PAGE_SHIFT;
+-	slot = iSeries_hpte_find(vpn); 
+-	if (slot == -1)
+-		panic("updateboltedpp: Could not find page to bolt\n");
+-	HvCallHpt_setPp(slot, newpp);
+-}
+-
+-static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
+-				    int large, int local)
+-{
+-	unsigned long hpte_v;
+-	unsigned long avpn = va >> 23;
+-	unsigned long flags;
+-
+-	local_irq_save(flags);
+-
+-	iSeries_hlock(slot);
+-
+-	hpte_v = iSeries_hpte_getword0(slot);
+-	
+-	if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))
+-		HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
+-
+-	iSeries_hunlock(slot);
+-
+-	local_irq_restore(flags);
+-}
+-
+-void hpte_init_iSeries(void)
+-{
+-	ppc_md.hpte_invalidate	= iSeries_hpte_invalidate;
+-	ppc_md.hpte_updatepp	= iSeries_hpte_updatepp;
+-	ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
+-	ppc_md.hpte_insert	= iSeries_hpte_insert;
+-	ppc_md.hpte_remove     	= iSeries_hpte_remove;
+-
+-	htab_finish_init();
+-}
+diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/ppc64/kernel/iSeries_iommu.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_iommu.c
++++ /dev/null
+@@ -1,176 +0,0 @@
+-/*
+- * arch/ppc64/kernel/iSeries_iommu.c
+- *
+- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+- *
+- * Rewrite, cleanup:
+- *
+- * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, IBM Corporation
+- *
+- * Dynamic DMA mapping support, iSeries-specific parts.
+- *
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the 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/dma-mapping.h>
+-#include <linux/list.h>
+-
+-#include <asm/iommu.h>
+-#include <asm/machdep.h>
+-#include <asm/iSeries/HvCallXm.h>
+-#include <asm/iSeries/iSeries_pci.h>
+-
+-extern struct list_head iSeries_Global_Device_List;
+-
+-
+-static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
+-		unsigned long uaddr, enum dma_data_direction direction)
+-{
+-	u64 rc;
+-	union tce_entry tce;
+-
+-	while (npages--) {
+-		tce.te_word = 0;
+-		tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> PAGE_SHIFT;
+-
+-		if (tbl->it_type == TCE_VB) {
+-			/* Virtual Bus */
+-			tce.te_bits.tb_valid = 1;
+-			tce.te_bits.tb_allio = 1;
+-			if (direction != DMA_TO_DEVICE)
+-				tce.te_bits.tb_rdwr = 1;
+-		} else {
+-			/* PCI Bus */
+-			tce.te_bits.tb_rdwr = 1; /* Read allowed */
+-			if (direction != DMA_TO_DEVICE)
+-				tce.te_bits.tb_pciwr = 1;
+-		}
+-
+-		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index,
+-				tce.te_word);
+-		if (rc)
+-			panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
+-					rc);
+-		index++;
+-		uaddr += PAGE_SIZE;
+-	}
+-}
+-
+-static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
+-{
+-	u64 rc;
+-
+-	while (npages--) {
+-		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0);
+-		if (rc)
+-			panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
+-					rc);
+-		index++;
+-	}
+-}
+-
+-#ifdef CONFIG_PCI
+-/*
+- * This function compares the known tables to find an iommu_table
+- * that has already been built for hardware TCEs.
+- */
+-static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
+-{
+-	struct iSeries_Device_Node *dp;
+-
+-	list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) {
+-		if ((dp->iommu_table != NULL) &&
+-		    (dp->iommu_table->it_type == TCE_PCI) &&
+-		    (dp->iommu_table->it_offset == tbl->it_offset) &&
+-		    (dp->iommu_table->it_index == tbl->it_index) &&
+-		    (dp->iommu_table->it_size == tbl->it_size))
+-			return dp->iommu_table;
+-	}
+-	return NULL;
+-}
+-
+-/*
+- * Call Hv with the architected data structure to get TCE table info.
+- * info. Put the returned data into the Linux representation of the
+- * TCE table data.
+- * The Hardware Tce table comes in three flavors.
+- * 1. TCE table shared between Buses.
+- * 2. TCE table per Bus.
+- * 3. TCE Table per IOA.
+- */
+-static void iommu_table_getparms(struct iSeries_Device_Node* dn,
+-				 struct iommu_table* tbl)
+-{
+-	struct iommu_table_cb *parms;
+-
+-	parms = kmalloc(sizeof(*parms), GFP_KERNEL);
+-	if (parms == NULL)
+-		panic("PCI_DMA: TCE Table Allocation failed.");
+-
+-	memset(parms, 0, sizeof(*parms));
+-
+-	parms->itc_busno = ISERIES_BUS(dn);
+-	parms->itc_slotno = dn->LogicalSlot;
+-	parms->itc_virtbus = 0;
+-
+-	HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms));
+-
+-	if (parms->itc_size == 0)
+-		panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);
+-
+-	/* itc_size is in pages worth of table, it_size is in # of entries */
+-	tbl->it_size = (parms->itc_size * PAGE_SIZE) / sizeof(union tce_entry);
+-	tbl->it_busno = parms->itc_busno;
+-	tbl->it_offset = parms->itc_offset;
+-	tbl->it_index = parms->itc_index;
+-	tbl->it_blocksize = 1;
+-	tbl->it_type = TCE_PCI;
+-
+-	kfree(parms);
+-}
+-
+-
+-void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn)
+-{
+-	struct iommu_table *tbl;
+-
+-	tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+-
+-	iommu_table_getparms(dn, tbl);
+-
+-	/* Look for existing tce table */
+-	dn->iommu_table = iommu_table_find(tbl);
+-	if (dn->iommu_table == NULL)
+-		dn->iommu_table = iommu_init_table(tbl);
+-	else
+-		kfree(tbl);
+-}
+-#endif
+-
+-static void iommu_dev_setup_iSeries(struct pci_dev *dev) { }
+-static void iommu_bus_setup_iSeries(struct pci_bus *bus) { }
+-
+-void iommu_init_early_iSeries(void)
+-{
+-	ppc_md.tce_build = tce_build_iSeries;
+-	ppc_md.tce_free  = tce_free_iSeries;
+-
+-	ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries;
+-	ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries;
+-
+-	pci_iommu_init();
+-}
+diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/ppc64/kernel/iSeries_irq.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_irq.c
++++ /dev/null
+@@ -1,353 +0,0 @@
+-/*
+- * This module supports the iSeries PCI bus interrupt handling
+- * Copyright (C) 20yy  <Robert L Holtorf> <IBM Corp>
+- * Copyright (C) 2004-2005 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
+- *
+- * Change Activity:
+- *   Created, December 13, 2000 by Wayne Holm
+- * End Change Activity
+- */
+-#include <linux/config.h>
+-#include <linux/pci.h>
+-#include <linux/init.h>
+-#include <linux/threads.h>
+-#include <linux/smp.h>
+-#include <linux/param.h>
+-#include <linux/string.h>
+-#include <linux/bootmem.h>
+-#include <linux/ide.h>
+-#include <linux/irq.h>
+-#include <linux/spinlock.h>
+-
+-#include <asm/ppcdebug.h>
+-#include <asm/iSeries/HvTypes.h>
+-#include <asm/iSeries/HvLpEvent.h>
+-#include <asm/iSeries/HvCallPci.h>
+-#include <asm/iSeries/HvCallXm.h>
+-#include <asm/iSeries/iSeries_irq.h>
+-
+-/* This maps virtual irq numbers to real irqs */
+-unsigned int virt_irq_to_real_map[NR_IRQS];
+-
+-/* The next available virtual irq number */
+-/* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */
+-static int next_virtual_irq = 2;
+-
+-static long Pci_Interrupt_Count;
+-static long Pci_Event_Count;
+-
+-enum XmPciLpEvent_Subtype {
+-	XmPciLpEvent_BusCreated		= 0,	// PHB has been created
+-	XmPciLpEvent_BusError		= 1,	// PHB has failed
+-	XmPciLpEvent_BusFailed		= 2,	// Msg to Secondary, Primary failed bus
+-	XmPciLpEvent_NodeFailed		= 4,	// Multi-adapter bridge has failed
+-	XmPciLpEvent_NodeRecovered	= 5,	// Multi-adapter bridge has recovered
+-	XmPciLpEvent_BusRecovered	= 12,	// PHB has been recovered
+-	XmPciLpEvent_UnQuiesceBus	= 18,	// Secondary bus unqiescing
+-	XmPciLpEvent_BridgeError	= 21,	// Bridge Error
+-	XmPciLpEvent_SlotInterrupt	= 22	// Slot interrupt
+-};
+-
+-struct XmPciLpEvent_BusInterrupt {
+-	HvBusNumber	busNumber;
+-	HvSubBusNumber	subBusNumber;
+-};
+-
+-struct XmPciLpEvent_NodeInterrupt {
+-	HvBusNumber	busNumber;
+-	HvSubBusNumber	subBusNumber;
+-	HvAgentId	deviceId;
+-};
+-
+-struct XmPciLpEvent {
+-	struct HvLpEvent hvLpEvent;
+-
+-	union {
+-		u64 alignData;			// Align on an 8-byte boundary
+-
+-		struct {
+-			u32		fisr;
+-			HvBusNumber	busNumber;
+-			HvSubBusNumber	subBusNumber;
+-			HvAgentId	deviceId;
+-		} slotInterrupt;
+-
+-		struct XmPciLpEvent_BusInterrupt busFailed;
+-		struct XmPciLpEvent_BusInterrupt busRecovered;
+-		struct XmPciLpEvent_BusInterrupt busCreated;
+-
+-		struct XmPciLpEvent_NodeInterrupt nodeFailed;
+-		struct XmPciLpEvent_NodeInterrupt nodeRecovered;
+-
+-	} eventData;
+-
+-};
+-
+-static void intReceived(struct XmPciLpEvent *eventParm,
+-		struct pt_regs *regsParm)
+-{
+-	int irq;
+-
+-	++Pci_Interrupt_Count;
+-
+-	switch (eventParm->hvLpEvent.xSubtype) {
+-	case XmPciLpEvent_SlotInterrupt:
+-		irq = eventParm->hvLpEvent.xCorrelationToken;
+-		/* Dispatch the interrupt handlers for this irq */
+-		ppc_irq_dispatch_handler(regsParm, irq);
+-		HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
+-			eventParm->eventData.slotInterrupt.subBusNumber,
+-			eventParm->eventData.slotInterrupt.deviceId);
+-		break;
+-		/* Ignore error recovery events for now */
+-	case XmPciLpEvent_BusCreated:
+-		printk(KERN_INFO "intReceived: system bus %d created\n",
+-			eventParm->eventData.busCreated.busNumber);
+-		break;
+-	case XmPciLpEvent_BusError:
+-	case XmPciLpEvent_BusFailed:
+-		printk(KERN_INFO "intReceived: system bus %d failed\n",
+-			eventParm->eventData.busFailed.busNumber);
+-		break;
+-	case XmPciLpEvent_BusRecovered:
+-	case XmPciLpEvent_UnQuiesceBus:
+-		printk(KERN_INFO "intReceived: system bus %d recovered\n",
+-			eventParm->eventData.busRecovered.busNumber);
+-		break;
+-	case XmPciLpEvent_NodeFailed:
+-	case XmPciLpEvent_BridgeError:
+-		printk(KERN_INFO
+-			"intReceived: multi-adapter bridge %d/%d/%d failed\n",
+-			eventParm->eventData.nodeFailed.busNumber,
+-			eventParm->eventData.nodeFailed.subBusNumber,
+-			eventParm->eventData.nodeFailed.deviceId);
+-		break;
+-	case XmPciLpEvent_NodeRecovered:
+-		printk(KERN_INFO
+-			"intReceived: multi-adapter bridge %d/%d/%d recovered\n",
+-			eventParm->eventData.nodeRecovered.busNumber,
+-			eventParm->eventData.nodeRecovered.subBusNumber,
+-			eventParm->eventData.nodeRecovered.deviceId);
+-		break;
+-	default:
+-		printk(KERN_ERR
+-			"intReceived: unrecognized event subtype 0x%x\n",
+-			eventParm->hvLpEvent.xSubtype);
+-		break;
+-	}
+-}
+-
+-static void XmPciLpEvent_handler(struct HvLpEvent *eventParm,
+-		struct pt_regs *regsParm)
+-{
+-#ifdef CONFIG_PCI
+-	++Pci_Event_Count;
+-
+-	if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) {
+-		switch (eventParm->xFlags.xFunction) {
+-		case HvLpEvent_Function_Int:
+-			intReceived((struct XmPciLpEvent *)eventParm, regsParm);
+-			break;
+-		case HvLpEvent_Function_Ack:
+-			printk(KERN_ERR
+-				"XmPciLpEvent_handler: unexpected ack received\n");
+-			break;
+-		default:
+-			printk(KERN_ERR
+-				"XmPciLpEvent_handler: unexpected event function %d\n",
+-				(int)eventParm->xFlags.xFunction);
+-			break;
+-		}
+-	} else if (eventParm)
+-		printk(KERN_ERR
+-			"XmPciLpEvent_handler: Unrecognized PCI event type 0x%x\n",
+-			(int)eventParm->xType);
+-	else
+-		printk(KERN_ERR "XmPciLpEvent_handler: NULL event received\n");
+-#endif
+-}
+-
+-/*
+- * This is called by init_IRQ.  set in ppc_md.init_IRQ by iSeries_setup.c
+- * It must be called before the bus walk.
+- */
+-void __init iSeries_init_IRQ(void)
+-{
+-	/* Register PCI event handler and open an event path */
+-	int xRc;
+-
+-	xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo,
+-			&XmPciLpEvent_handler);
+-	if (xRc == 0) {
+-		xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
+-		if (xRc != 0)
+-			printk(KERN_ERR "iSeries_init_IRQ: open event path "
+-					"failed with rc 0x%x\n", xRc);
+-	} else
+-		printk(KERN_ERR "iSeries_init_IRQ: register handler "
+-				"failed with rc 0x%x\n", xRc);
+-}
+-
+-#define REAL_IRQ_TO_BUS(irq)	((((irq) >> 6) & 0xff) + 1)
+-#define REAL_IRQ_TO_IDSEL(irq)	((((irq) >> 3) & 7) + 1)
+-#define REAL_IRQ_TO_FUNC(irq)	((irq) & 7)
+-
+-/*
+- * This will be called by device drivers (via enable_IRQ)
+- * to enable INTA in the bridge interrupt status register.
+- */
+-static void iSeries_enable_IRQ(unsigned int irq)
+-{
+-	u32 bus, deviceId, function, mask;
+-	const u32 subBus = 0;
+-	unsigned int rirq = virt_irq_to_real_map[irq];
+-
+-	/* The IRQ has already been locked by the caller */
+-	bus = REAL_IRQ_TO_BUS(rirq);
+-	function = REAL_IRQ_TO_FUNC(rirq);
+-	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
+-
+-	/* Unmask secondary INTA */
+-	mask = 0x80000000;
+-	HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask);
+-	PPCDBG(PPCDBG_BUSWALK, "iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n",
+-			bus, subBus, deviceId, irq);
+-}
+-
+-/* This is called by iSeries_activate_IRQs */
+-static unsigned int iSeries_startup_IRQ(unsigned int irq)
+-{
+-	u32 bus, deviceId, function, mask;
+-	const u32 subBus = 0;
+-	unsigned int rirq = virt_irq_to_real_map[irq];
+-
+-	bus = REAL_IRQ_TO_BUS(rirq);
+-	function = REAL_IRQ_TO_FUNC(rirq);
+-	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
+-
+-	/* Link the IRQ number to the bridge */
+-	HvCallXm_connectBusUnit(bus, subBus, deviceId, irq);
+-
+-	/* Unmask bridge interrupts in the FISR */
+-	mask = 0x01010000 << function;
+-	HvCallPci_unmaskFisr(bus, subBus, deviceId, mask);
+-	iSeries_enable_IRQ(irq);
+-	return 0;
+-}
+-
+-/*
+- * This is called out of iSeries_fixup to activate interrupt
+- * generation for usable slots
+- */
+-void __init iSeries_activate_IRQs()
+-{
+-	int irq;
+-	unsigned long flags;
+-
+-	for_each_irq (irq) {
+-		irq_desc_t *desc = get_irq_desc(irq);
+-
+-		if (desc && desc->handler && desc->handler->startup) {
+-			spin_lock_irqsave(&desc->lock, flags);
+-			desc->handler->startup(irq);
+-			spin_unlock_irqrestore(&desc->lock, flags);
+-		}
+-	}
+-}
+-
+-/*  this is not called anywhere currently */
+-static void iSeries_shutdown_IRQ(unsigned int irq)
+-{
+-	u32 bus, deviceId, function, mask;
+-	const u32 subBus = 0;
+-	unsigned int rirq = virt_irq_to_real_map[irq];
+-
+-	/* irq should be locked by the caller */
+-	bus = REAL_IRQ_TO_BUS(rirq);
+-	function = REAL_IRQ_TO_FUNC(rirq);
+-	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
+-
+-	/* Invalidate the IRQ number in the bridge */
+-	HvCallXm_connectBusUnit(bus, subBus, deviceId, 0);
+-
+-	/* Mask bridge interrupts in the FISR */
+-	mask = 0x01010000 << function;
+-	HvCallPci_maskFisr(bus, subBus, deviceId, mask);
+-}
+-
+-/*
+- * This will be called by device drivers (via disable_IRQ)
+- * to disable INTA in the bridge interrupt status register.
+- */
+-static void iSeries_disable_IRQ(unsigned int irq)
+-{
+-	u32 bus, deviceId, function, mask;
+-	const u32 subBus = 0;
+-	unsigned int rirq = virt_irq_to_real_map[irq];
+-
+-	/* The IRQ has already been locked by the caller */
+-	bus = REAL_IRQ_TO_BUS(rirq);
+-	function = REAL_IRQ_TO_FUNC(rirq);
+-	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
+-
+-	/* Mask secondary INTA   */
+-	mask = 0x80000000;
+-	HvCallPci_maskInterrupts(bus, subBus, deviceId, mask);
+-	PPCDBG(PPCDBG_BUSWALK, "iSeries_disable_IRQ 0x%02X.%02X.%02X 0x%04X\n",
+-			bus, subBus, deviceId, irq);
+-}
+-
+-/*
+- * Need to define this so ppc_irq_dispatch_handler will NOT call
+- * enable_IRQ at the end of interrupt handling.  However, this does
+- * nothing because there is not enough information provided to do
+- * the EOI HvCall.  This is done by XmPciLpEvent.c
+- */
+-static void iSeries_end_IRQ(unsigned int irq)
+-{
+-}
+-
+-static hw_irq_controller iSeries_IRQ_handler = {
+-	.typename = "iSeries irq controller",
+-	.startup = iSeries_startup_IRQ,
+-	.shutdown = iSeries_shutdown_IRQ,
+-	.enable = iSeries_enable_IRQ,
+-	.disable = iSeries_disable_IRQ,
+-	.end = iSeries_end_IRQ
+-};
+-
+-/*
+- * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot
+- * It calculates the irq value for the slot.
+- * Note that subBusNumber is always 0 (at the moment at least).
+- */
+-int __init iSeries_allocate_IRQ(HvBusNumber busNumber,
+-		HvSubBusNumber subBusNumber, HvAgentId deviceId)
+-{
+-	unsigned int realirq, virtirq;
+-	u8 idsel = (deviceId >> 4);
+-	u8 function = deviceId & 7;
+-
+-	virtirq = next_virtual_irq++;
+-	realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function;
+-	virt_irq_to_real_map[virtirq] = realirq;
+-
+-	irq_desc[virtirq].handler = &iSeries_IRQ_handler;
+-	return virtirq;
+-}
+diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_pci.c
++++ /dev/null
+@@ -1,905 +0,0 @@
+-/*
+- * iSeries_pci.c
+- *
+- * Copyright (C) 2001 Allan Trautman, IBM Corporation
+- *
+- * iSeries specific routines for PCI.
+- * 
+- * Based on code from pci.c and iSeries_pci.c 32bit
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the 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/list.h> 
+-#include <linux/string.h>
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/ide.h>
+-#include <linux/pci.h>
+-
+-#include <asm/io.h>
+-#include <asm/irq.h>
+-#include <asm/prom.h>
+-#include <asm/machdep.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/iommu.h>
+-
+-#include <asm/iSeries/HvCallPci.h>
+-#include <asm/iSeries/HvCallXm.h>
+-#include <asm/iSeries/iSeries_irq.h>
+-#include <asm/iSeries/iSeries_pci.h>
+-#include <asm/iSeries/mf.h>
+-
+-#include "pci.h"
+-
+-extern unsigned long io_page_mask;
+-
+-/*
+- * Forward declares of prototypes. 
+- */
+-static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn);
+-static void scan_PHB_slots(struct pci_controller *Phb);
+-static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
+-static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);
+-
+-LIST_HEAD(iSeries_Global_Device_List);
+-
+-static int DeviceCount;
+-
+-/* Counters and control flags. */
+-static long Pci_Io_Read_Count;
+-static long Pci_Io_Write_Count;
+-#if 0
+-static long Pci_Cfg_Read_Count;
+-static long Pci_Cfg_Write_Count;
+-#endif
+-static long Pci_Error_Count;
+-
+-static int Pci_Retry_Max = 3;	/* Only retry 3 times  */	
+-static int Pci_Error_Flag = 1;	/* Set Retry Error on. */
+-
+-static struct pci_ops iSeries_pci_ops;
+-
+-/*
+- * Table defines
+- * Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space.
+- */
+-#define IOMM_TABLE_MAX_ENTRIES	1024
+-#define IOMM_TABLE_ENTRY_SIZE	0x0000000000400000UL
+-#define BASE_IO_MEMORY		0xE000000000000000UL
+-
+-static unsigned long max_io_memory = 0xE000000000000000UL;
+-static long current_iomm_table_entry;
+-
+-/*
+- * Lookup Tables.
+- */
+-static struct iSeries_Device_Node **iomm_table;
+-static u8 *iobar_table;
+-
+-/*
+- * Static and Global variables
+- */
+-static char *pci_io_text = "iSeries PCI I/O";
+-static DEFINE_SPINLOCK(iomm_table_lock);
+-
+-/*
+- * iomm_table_initialize
+- *
+- * Allocates and initalizes the Address Translation Table and Bar
+- * Tables to get them ready for use.  Must be called before any
+- * I/O space is handed out to the device BARs.
+- */
+-static void iomm_table_initialize(void)
+-{
+-	spin_lock(&iomm_table_lock);
+-	iomm_table = kmalloc(sizeof(*iomm_table) * IOMM_TABLE_MAX_ENTRIES,
+-			GFP_KERNEL);
+-	iobar_table = kmalloc(sizeof(*iobar_table) * IOMM_TABLE_MAX_ENTRIES,
+-			GFP_KERNEL);
+-	spin_unlock(&iomm_table_lock);
+-	if ((iomm_table == NULL) || (iobar_table == NULL))
+-		panic("PCI: I/O tables allocation failed.\n");
+-}
+-
+-/*
+- * iomm_table_allocate_entry
+- *
+- * Adds pci_dev entry in address translation table
+- *
+- * - Allocates the number of entries required in table base on BAR
+- *   size.
+- * - Allocates starting at BASE_IO_MEMORY and increases.
+- * - The size is round up to be a multiple of entry size.
+- * - CurrentIndex is incremented to keep track of the last entry.
+- * - Builds the resource entry for allocated BARs.
+- */
+-static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
+-{
+-	struct resource *bar_res = &dev->resource[bar_num];
+-	long bar_size = pci_resource_len(dev, bar_num);
+-
+-	/*
+-	 * No space to allocate, quick exit, skip Allocation.
+-	 */
+-	if (bar_size == 0)
+-		return;
+-	/*
+-	 * Set Resource values.
+-	 */
+-	spin_lock(&iomm_table_lock);
+-	bar_res->name = pci_io_text;
+-	bar_res->start =
+-		IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
+-	bar_res->start += BASE_IO_MEMORY;
+-	bar_res->end = bar_res->start + bar_size - 1;
+-	/*
+-	 * Allocate the number of table entries needed for BAR.
+-	 */
+-	while (bar_size > 0 ) {
+-		iomm_table[current_iomm_table_entry] = dev->sysdata;
+-		iobar_table[current_iomm_table_entry] = bar_num;
+-		bar_size -= IOMM_TABLE_ENTRY_SIZE;
+-		++current_iomm_table_entry;
+-	}
+-	max_io_memory = BASE_IO_MEMORY +
+-		(IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry);
+-	spin_unlock(&iomm_table_lock);
+-}
+-
+-/*
+- * allocate_device_bars
+- *
+- * - Allocates ALL pci_dev BAR's and updates the resources with the
+- *   BAR value.  BARS with zero length will have the resources
+- *   The HvCallPci_getBarParms is used to get the size of the BAR
+- *   space.  It calls iomm_table_allocate_entry to allocate
+- *   each entry.
+- * - Loops through The Bar resources(0 - 5) including the ROM
+- *   is resource(6).
+- */
+-static void allocate_device_bars(struct pci_dev *dev)
+-{
+-	struct resource *bar_res;
+-	int bar_num;
+-
+-	for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) {
+-		bar_res = &dev->resource[bar_num];
+-		iomm_table_allocate_entry(dev, bar_num);
+-    	}
+-}
+-
+-/*
+- * Log error information to system console.
+- * Filter out the device not there errors.
+- * PCI: EADs Connect Failed 0x18.58.10 Rc: 0x00xx
+- * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
+- * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
+- */
+-static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
+-		int AgentId, int HvRc)
+-{
+-	if (HvRc == 0x0302)
+-		return;
+-	printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",
+-	       Error_Text, Bus, SubBus, AgentId, HvRc);
+-}
+-
+-/*
+- * build_device_node(u16 Bus, int SubBus, u8 DevFn)
+- */
+-static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus,
+-		HvSubBusNumber SubBus, int AgentId, int Function)
+-{
+-	struct iSeries_Device_Node *node;
+-
+-	PPCDBG(PPCDBG_BUSWALK,
+-			"-build_device_node 0x%02X.%02X.%02X Function: %02X\n",
+-			Bus, SubBus, AgentId, Function);
+-
+-	node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
+-	if (node == NULL)
+-		return NULL;
+-
+-	memset(node, 0, sizeof(struct iSeries_Device_Node));
+-	list_add_tail(&node->Device_List, &iSeries_Global_Device_List);
+-#if 0
+-	node->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32);
+-#endif
+-	node->DsaAddr.DsaAddr = 0;
+-	node->DsaAddr.Dsa.busNumber = Bus;
+-	node->DsaAddr.Dsa.subBusNumber = SubBus;
+-	node->DsaAddr.Dsa.deviceId = 0x10;
+-	node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
+-	return node;
+-}
+-
+-/*
+- * unsigned long __init find_and_init_phbs(void)
+- *
+- * Description:
+- *   This function checks for all possible system PCI host bridges that connect
+- *   PCI buses.  The system hypervisor is queried as to the guest partition
+- *   ownership status.  A pci_controller is built for any bus which is partially
+- *   owned or fully owned by this guest partition.
+- */
+-unsigned long __init find_and_init_phbs(void)
+-{
+-	struct pci_controller *phb;
+-	HvBusNumber bus;
+-
+-	PPCDBG(PPCDBG_BUSWALK, "find_and_init_phbs Entry\n");
+-
+-	/* Check all possible buses. */
+-	for (bus = 0; bus < 256; bus++) {
+-		int ret = HvCallXm_testBus(bus);
+-		if (ret == 0) {
+-			printk("bus %d appears to exist\n", bus);
+-
+-			phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
+-			if (phb == NULL)
+-				return -ENOMEM;
+-			pci_setup_pci_controller(phb);
+-
+-			phb->pci_mem_offset = phb->local_number = bus;
+-			phb->first_busno = bus;
+-			phb->last_busno = bus;
+-			phb->ops = &iSeries_pci_ops;
+-
+-			PPCDBG(PPCDBG_BUSWALK, "PCI:Create iSeries pci_controller(%p), Bus: %04X\n",
+-					phb, bus);
+-
+-			/* Find and connect the devices. */
+-			scan_PHB_slots(phb);
+-		}
+-		/*
+-		 * Check for Unexpected Return code, a clue that something
+-		 * has gone wrong.
+-		 */
+-		else if (ret != 0x0301)
+-			printk(KERN_ERR "Unexpected Return on Probe(0x%04X): 0x%04X",
+-			       bus, ret);
+-	}
+-	return 0;
+-}
+-
+-/*
+- * iSeries_pcibios_init
+- *  
+- * Chance to initialize and structures or variable before PCI Bus walk.
+- */
+-void iSeries_pcibios_init(void)
+-{
+-	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n"); 
+-	iomm_table_initialize();
+-	find_and_init_phbs();
+-	io_page_mask = -1;
+-	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n"); 
+-}
+-
+-/*
+- * iSeries_pci_final_fixup(void)  
+- */
+-void __init iSeries_pci_final_fixup(void)
+-{
+-	struct pci_dev *pdev = NULL;
+-	struct iSeries_Device_Node *node;
+-    	int DeviceCount = 0;
+-
+-	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); 
+-
+-	/* Fix up at the device node and pci_dev relationship */
+-	mf_display_src(0xC9000100);
+-
+-	printk("pcibios_final_fixup\n");
+-	for_each_pci_dev(pdev) {
+-		node = find_Device_Node(pdev->bus->number, pdev->devfn);
+-		printk("pci dev %p (%x.%x), node %p\n", pdev,
+-		       pdev->bus->number, pdev->devfn, node);
+-
+-		if (node != NULL) {
+-			++DeviceCount;
+-			pdev->sysdata = (void *)node;
+-			node->PciDev = pdev;
+-			PPCDBG(PPCDBG_BUSWALK,
+-					"pdev 0x%p <==> DevNode 0x%p\n",
+-					pdev, node);
+-			allocate_device_bars(pdev);
+-			iSeries_Device_Information(pdev, DeviceCount);
+-			iommu_devnode_init_iSeries(node);
+-		} else
+-			printk("PCI: Device Tree not found for 0x%016lX\n",
+-					(unsigned long)pdev);
+-		pdev->irq = node->Irq;
+-	}
+-	iSeries_activate_IRQs();
+-	mf_display_src(0xC9000200);
+-}
+-
+-void pcibios_fixup_bus(struct pci_bus *PciBus)
+-{
+-	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",
+-			PciBus->number); 
+-}
+-
+-void pcibios_fixup_resources(struct pci_dev *pdev)
+-{
+-	PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev);
+-}   
+-
+-/*
+- * Loop through each node function to find usable EADs bridges.  
+- */
+-static void scan_PHB_slots(struct pci_controller *Phb)
+-{
+-	struct HvCallPci_DeviceInfo *DevInfo;
+-	HvBusNumber bus = Phb->local_number;	/* System Bus */	
+-	const HvSubBusNumber SubBus = 0;	/* EADs is always 0. */
+-	int HvRc = 0;
+-	int IdSel;	
+-	const int MaxAgents = 8;
+-
+-	DevInfo = (struct HvCallPci_DeviceInfo*)
+-		kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);
+-	if (DevInfo == NULL)
+-		return;
+-
+-	/*
+-	 * Probe for EADs Bridges      
+-	 */
+-	for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
+-    		HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
+-				ISERIES_HV_ADDR(DevInfo),
+-				sizeof(struct HvCallPci_DeviceInfo));
+-		if (HvRc == 0) {
+-			if (DevInfo->deviceType == HvCallPci_NodeDevice)
+-				scan_EADS_bridge(bus, SubBus, IdSel);
+-			else
+-				printk("PCI: Invalid System Configuration(0x%02X)"
+-				       " for bus 0x%02x id 0x%02x.\n",
+-				       DevInfo->deviceType, bus, IdSel);
+-		}
+-		else
+-			pci_Log_Error("getDeviceInfo", bus, SubBus, IdSel, HvRc);
+-	}
+-	kfree(DevInfo);
+-}
+-
+-static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
+-		int IdSel)
+-{
+-	struct HvCallPci_BridgeInfo *BridgeInfo;
+-	HvAgentId AgentId;
+-	int Function;
+-	int HvRc;
+-
+-	BridgeInfo = (struct HvCallPci_BridgeInfo *)
+-		kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL);
+-	if (BridgeInfo == NULL)
+-		return;
+-
+-	/* Note: hvSubBus and irq is always be 0 at this level! */
+-	for (Function = 0; Function < 8; ++Function) {
+-	  	AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
+-		HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
+- 		if (HvRc == 0) {
+-			printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
+-			       bus, IdSel, Function, AgentId);
+-  			/*  Connect EADs: 0x18.00.12 = 0x00 */
+-			PPCDBG(PPCDBG_BUSWALK,
+-					"PCI:Connect EADs: 0x%02X.%02X.%02X\n",
+-					bus, SubBus, AgentId);
+-	    		HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
+-					ISERIES_HV_ADDR(BridgeInfo),
+-					sizeof(struct HvCallPci_BridgeInfo));
+-	 		if (HvRc == 0) {
+-				printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
+-					BridgeInfo->busUnitInfo.deviceType,
+-					BridgeInfo->subBusNumber,
+-					BridgeInfo->maxAgents,
+-					BridgeInfo->maxSubBusNumber,
+-					BridgeInfo->logicalSlotNumber);
+-				PPCDBG(PPCDBG_BUSWALK,
+-					"PCI: BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X\n",
+-					BridgeInfo->busUnitInfo.deviceType,
+-					BridgeInfo->subBusNumber,
+-					BridgeInfo->maxAgents,
+-					BridgeInfo->maxSubBusNumber,
+-					BridgeInfo->logicalSlotNumber);
+-
+-				if (BridgeInfo->busUnitInfo.deviceType ==
+-						HvCallPci_BridgeDevice)  {
+-					/* Scan_Bridge_Slot...: 0x18.00.12 */
+-					scan_bridge_slot(bus, BridgeInfo);
+-				} else
+-					printk("PCI: Invalid Bridge Configuration(0x%02X)",
+-						BridgeInfo->busUnitInfo.deviceType);
+-			}
+-    		} else if (HvRc != 0x000B)
+-			pci_Log_Error("EADs Connect",
+-					bus, SubBus, AgentId, HvRc);
+-	}
+-	kfree(BridgeInfo);
+-}
+-
+-/*
+- * This assumes that the node slot is always on the primary bus!
+- */
+-static int scan_bridge_slot(HvBusNumber Bus,
+-		struct HvCallPci_BridgeInfo *BridgeInfo)
+-{
+-	struct iSeries_Device_Node *node;
+-	HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
+-	u16 VendorId = 0;
+-	int HvRc = 0;
+-	u8 Irq = 0;
+-	int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
+-	int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
+-	HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
+-
+-	/* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
+-  	Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
+-	PPCDBG(PPCDBG_BUSWALK,
+-		"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",
+-		Bus, 0, EADsIdSel, Irq);
+-
+-	/*
+-	 * Connect all functions of any device found.  
+-	 */
+-  	for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
+-    		for (Function = 0; Function < 8; ++Function) {
+-			HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
+-			HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
+-					AgentId, Irq);
+-			if (HvRc != 0) {
+-				pci_Log_Error("Connect Bus Unit",
+-					      Bus, SubBus, AgentId, HvRc);
+-				continue;
+-			}
+-
+-			HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId,
+-						      PCI_VENDOR_ID, &VendorId);
+-			if (HvRc != 0) {
+-				pci_Log_Error("Read Vendor",
+-					      Bus, SubBus, AgentId, HvRc);
+-				continue;
+-			}
+-			printk("read vendor ID: %x\n", VendorId);
+-
+-			/* FoundDevice: 0x18.28.10 = 0x12AE */
+-			PPCDBG(PPCDBG_BUSWALK,
+-			       "PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n",
+-			       Bus, SubBus, AgentId, VendorId, Irq);
+-			HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
+-						      PCI_INTERRUPT_LINE, Irq);  
+-			if (HvRc != 0)
+-				pci_Log_Error("PciCfgStore Irq Failed!",
+-					      Bus, SubBus, AgentId, HvRc);
+-
+-			++DeviceCount;
+-			node = build_device_node(Bus, SubBus, EADsIdSel, Function);
+-			node->Irq = Irq;
+-			node->LogicalSlot = BridgeInfo->logicalSlotNumber;
+-
+-		} /* for (Function = 0; Function < 8; ++Function) */
+-	} /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
+-	return HvRc;
+-}
+-
+-/*
+- * I/0 Memory copy MUST use mmio commands on iSeries
+- * To do; For performance, include the hv call directly
+- */
+-void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
+-{
+-	u8 ByteValue = c;
+-	long NumberOfBytes = Count;
+-
+-	while (NumberOfBytes > 0) {
+-		iSeries_Write_Byte(ByteValue, dest++);
+-		-- NumberOfBytes;
+-	}
+-}
+-EXPORT_SYMBOL(iSeries_memset_io);
+-
+-void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
+-{
+-	char *src = source;
+-	long NumberOfBytes = count;
+-
+-	while (NumberOfBytes > 0) {
+-		iSeries_Write_Byte(*src++, dest++);
+-		-- NumberOfBytes;
+-	}
+-}
+-EXPORT_SYMBOL(iSeries_memcpy_toio);
+-
+-void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
+-{
+-	char *dst = dest;
+-	long NumberOfBytes = count;
+-
+-	while (NumberOfBytes > 0) {
+-		*dst++ = iSeries_Read_Byte(src++);
+-		-- NumberOfBytes;
+-	}
+-}
+-EXPORT_SYMBOL(iSeries_memcpy_fromio);
+-
+-/*
+- * Look down the chain to find the matching Device Device
+- */
+-static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
+-{
+-	struct list_head *pos;
+-
+-	list_for_each(pos, &iSeries_Global_Device_List) {
+-		struct iSeries_Device_Node *node =
+-			list_entry(pos, struct iSeries_Device_Node, Device_List);
+-
+-		if ((bus == ISERIES_BUS(node)) && (devfn == node->DevFn))
+-			return node;
+-	}
+-	return NULL;
+-}
+-
+-#if 0
+-/*
+- * Returns the device node for the passed pci_dev
+- * Sanity Check Node PciDev to passed pci_dev
+- * If none is found, returns a NULL which the client must handle.
+- */
+-static struct iSeries_Device_Node *get_Device_Node(struct pci_dev *pdev)
+-{
+-	struct iSeries_Device_Node *node;
+-
+-	node = pdev->sysdata;
+-	if (node == NULL || node->PciDev != pdev)
+-		node = find_Device_Node(pdev->bus->number, pdev->devfn);
+-	return node;
+-}
+-#endif
+-
+-/*
+- * Config space read and write functions.
+- * For now at least, we look for the device node for the bus and devfn
+- * that we are asked to access.  It may be possible to translate the devfn
+- * to a subbus and deviceid more directly.
+- */
+-static u64 hv_cfg_read_func[4]  = {
+-	HvCallPciConfigLoad8, HvCallPciConfigLoad16,
+-	HvCallPciConfigLoad32, HvCallPciConfigLoad32
+-};
+-
+-static u64 hv_cfg_write_func[4] = {
+-	HvCallPciConfigStore8, HvCallPciConfigStore16,
+-	HvCallPciConfigStore32, HvCallPciConfigStore32
+-};
+-
+-/*
+- * Read PCI config space
+- */
+-static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+-		int offset, int size, u32 *val)
+-{
+-	struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
+-	u64 fn;
+-	struct HvCallPci_LoadReturn ret;
+-
+-	if (node == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-	if (offset > 255) {
+-		*val = ~0;
+-		return PCIBIOS_BAD_REGISTER_NUMBER;
+-	}
+-
+-	fn = hv_cfg_read_func[(size - 1) & 3];
+-	HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0);
+-
+-	if (ret.rc != 0) {
+-		*val = ~0;
+-		return PCIBIOS_DEVICE_NOT_FOUND;	/* or something */
+-	}
+-
+-	*val = ret.value;
+-	return 0;
+-}
+-
+-/*
+- * Write PCI config space
+- */
+-
+-static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+-		int offset, int size, u32 val)
+-{
+-	struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
+-	u64 fn;
+-	u64 ret;
+-
+-	if (node == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-	if (offset > 255)
+-		return PCIBIOS_BAD_REGISTER_NUMBER;
+-
+-	fn = hv_cfg_write_func[(size - 1) & 3];
+-	ret = HvCall4(fn, node->DsaAddr.DsaAddr, offset, val, 0);
+-
+-	if (ret != 0)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	return 0;
+-}
+-
+-static struct pci_ops iSeries_pci_ops = {
+-	.read = iSeries_pci_read_config,
+-	.write = iSeries_pci_write_config
+-};
+-
+-/*
+- * Check Return Code
+- * -> On Failure, print and log information.
+- *    Increment Retry Count, if exceeds max, panic partition.
+- *
+- * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234
+- * PCI: Device 23.90 ReadL Retry( 1)
+- * PCI: Device 23.90 ReadL Retry Successful(1)
+- */
+-static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
+-		int *retry, u64 ret)
+-{
+-	if (ret != 0)  {
+-		++Pci_Error_Count;
+-		(*retry)++;
+-		printk("PCI: %s: Device 0x%04X:%02X  I/O Error(%2d): 0x%04X\n",
+-				TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn,
+-				*retry, (int)ret);
+-		/*
+-		 * Bump the retry and check for retry count exceeded.
+-		 * If, Exceeded, panic the system.
+-		 */
+-		if (((*retry) > Pci_Retry_Max) &&
+-				(Pci_Error_Flag > 0)) {
+-			mf_display_src(0xB6000103);
+-			panic_timeout = 0;
+-			panic("PCI: Hardware I/O Error, SRC B6000103, "
+-					"Automatic Reboot Disabled.\n");
+-		}
+-		return -1;	/* Retry Try */
+-	}
+-	return 0;
+-}
+-
+-/*
+- * Translate the I/O Address into a device node, bar, and bar offset.
+- * Note: Make sure the passed variable end up on the stack to avoid
+- * the exposure of being device global.
+- */
+-static inline struct iSeries_Device_Node *xlate_iomm_address(
+-		const volatile void __iomem *IoAddress,
+-		u64 *dsaptr, u64 *BarOffsetPtr)
+-{
+-	unsigned long OrigIoAddr;
+-	unsigned long BaseIoAddr;
+-	unsigned long TableIndex;
+-	struct iSeries_Device_Node *DevNode;
+-
+-	OrigIoAddr = (unsigned long __force)IoAddress;
+-	if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory))
+-		return NULL;
+-	BaseIoAddr = OrigIoAddr - BASE_IO_MEMORY;
+-	TableIndex = BaseIoAddr / IOMM_TABLE_ENTRY_SIZE;
+-	DevNode = iomm_table[TableIndex];
+-
+-	if (DevNode != NULL) {
+-		int barnum = iobar_table[TableIndex];
+-		*dsaptr = DevNode->DsaAddr.DsaAddr | (barnum << 24);
+-		*BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE;
+-	} else
+-		panic("PCI: Invalid PCI IoAddress detected!\n");
+-	return DevNode;
+-}
+-
+-/*
+- * Read MM I/O Instructions for the iSeries
+- * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
+- * else, data is returned in big Endian format.
+- *
+- * iSeries_Read_Byte = Read Byte  ( 8 bit)
+- * iSeries_Read_Word = Read Word  (16 bit)
+- * iSeries_Read_Long = Read Long  (32 bit)
+- */
+-u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
+-{
+-	u64 BarOffset;
+-	u64 dsa;
+-	int retry = 0;
+-	struct HvCallPci_LoadReturn ret;
+-	struct iSeries_Device_Node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
+-
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", IoAddress);
+-		return 0xff;
+-	}
+-	do {
+-		++Pci_Io_Read_Count;
+-		HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
+-	} while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0);
+-
+-	return (u8)ret.value;
+-}
+-EXPORT_SYMBOL(iSeries_Read_Byte);
+-
+-u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
+-{
+-	u64 BarOffset;
+-	u64 dsa;
+-	int retry = 0;
+-	struct HvCallPci_LoadReturn ret;
+-	struct iSeries_Device_Node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
+-
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", IoAddress);
+-		return 0xffff;
+-	}
+-	do {
+-		++Pci_Io_Read_Count;
+-		HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
+-				BarOffset, 0);
+-	} while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0);
+-
+-	return swab16((u16)ret.value);
+-}
+-EXPORT_SYMBOL(iSeries_Read_Word);
+-
+-u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
+-{
+-	u64 BarOffset;
+-	u64 dsa;
+-	int retry = 0;
+-	struct HvCallPci_LoadReturn ret;
+-	struct iSeries_Device_Node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
+-
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", IoAddress);
+-		return 0xffffffff;
+-	}
+-	do {
+-		++Pci_Io_Read_Count;
+-		HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
+-				BarOffset, 0);
+-	} while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0);
+-
+-	return swab32((u32)ret.value);
+-}
+-EXPORT_SYMBOL(iSeries_Read_Long);
+-
+-/*
+- * Write MM I/O Instructions for the iSeries
+- *
+- * iSeries_Write_Byte = Write Byte (8 bit)
+- * iSeries_Write_Word = Write Word(16 bit)
+- * iSeries_Write_Long = Write Long(32 bit)
+- */
+-void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
+-{
+-	u64 BarOffset;
+-	u64 dsa;
+-	int retry = 0;
+-	u64 rc;
+-	struct iSeries_Device_Node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
+-
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Write_Byte: invalid access at IO address %p\n", IoAddress);
+-		return;
+-	}
+-	do {
+-		++Pci_Io_Write_Count;
+-		rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
+-	} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
+-}
+-EXPORT_SYMBOL(iSeries_Write_Byte);
+-
+-void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
+-{
+-	u64 BarOffset;
+-	u64 dsa;
+-	int retry = 0;
+-	u64 rc;
+-	struct iSeries_Device_Node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
+-
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", IoAddress);
+-		return;
+-	}
+-	do {
+-		++Pci_Io_Write_Count;
+-		rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
+-	} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
+-}
+-EXPORT_SYMBOL(iSeries_Write_Word);
+-
+-void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
+-{
+-	u64 BarOffset;
+-	u64 dsa;
+-	int retry = 0;
+-	u64 rc;
+-	struct iSeries_Device_Node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
+-
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", IoAddress);
+-		return;
+-	}
+-	do {
+-		++Pci_Io_Write_Count;
+-		rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
+-	} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
+-}
+-EXPORT_SYMBOL(iSeries_Write_Long);
+diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_proc.c
++++ /dev/null
+@@ -1,113 +0,0 @@
+-/*
+- * iSeries_proc.c
+- * Copyright (C) 2001  Kyle A. Lucke IBM Corporation
+- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen 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
+- */
+-#include <linux/init.h>
+-#include <linux/proc_fs.h>
+-#include <linux/seq_file.h>
+-#include <linux/param.h>		/* for HZ */
+-#include <asm/paca.h>
+-#include <asm/processor.h>
+-#include <asm/time.h>
+-#include <asm/lppaca.h>
+-#include <asm/iSeries/ItLpQueue.h>
+-#include <asm/iSeries/HvCallXm.h>
+-#include <asm/iSeries/IoHriMainStore.h>
+-#include <asm/iSeries/IoHriProcessorVpd.h>
+-
+-static int __init iseries_proc_create(void)
+-{
+-	struct proc_dir_entry *e = proc_mkdir("iSeries", 0);
+-	if (!e)
+-		return 1;
+-
+-	return 0;
+-}
+-core_initcall(iseries_proc_create);
+-
+-static unsigned long startTitan = 0;
+-static unsigned long startTb = 0;
+-
+-static int proc_titantod_show(struct seq_file *m, void *v)
+-{
+-	unsigned long tb0, titan_tod;
+-
+-	tb0 = get_tb();
+-	titan_tod = HvCallXm_loadTod();
+-
+-	seq_printf(m, "Titan\n" );
+-	seq_printf(m, "  time base =          %016lx\n", tb0);
+-	seq_printf(m, "  titan tod =          %016lx\n", titan_tod);
+-	seq_printf(m, "  xProcFreq =          %016x\n",
+-		   xIoHriProcessorVpd[0].xProcFreq);
+-	seq_printf(m, "  xTimeBaseFreq =      %016x\n",
+-		   xIoHriProcessorVpd[0].xTimeBaseFreq);
+-	seq_printf(m, "  tb_ticks_per_jiffy = %lu\n", tb_ticks_per_jiffy);
+-	seq_printf(m, "  tb_ticks_per_usec  = %lu\n", tb_ticks_per_usec);
+-
+-	if (!startTitan) {
+-		startTitan = titan_tod;
+-		startTb = tb0;
+-	} else {
+-		unsigned long titan_usec = (titan_tod - startTitan) >> 12;
+-		unsigned long tb_ticks = (tb0 - startTb);
+-		unsigned long titan_jiffies = titan_usec / (1000000/HZ);
+-		unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ);
+-		unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec;
+-		unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy;
+-		unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy;
+-		unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks;
+-		unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec;
+-		unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec;
+-
+-		seq_printf(m, "  titan elapsed = %lu uSec\n", titan_usec);
+-		seq_printf(m, "  tb elapsed    = %lu ticks\n", tb_ticks);
+-		seq_printf(m, "  titan jiffies = %lu.%04lu \n", titan_jiffies,
+-			   titan_jiff_rem_usec);
+-		seq_printf(m, "  tb jiffies    = %lu.%04lu\n", tb_jiffies,
+-			   tb_jiff_rem_usec);
+-		seq_printf(m, "  new tb_ticks_per_jiffy = %lu\n",
+-			   new_tb_ticks_per_jiffy);
+-	}
+-
+-	return 0;
+-}
+-
+-static int proc_titantod_open(struct inode *inode, struct file *file)
+-{
+-	return single_open(file, proc_titantod_show, NULL);
+-}
+-
+-static struct file_operations proc_titantod_operations = {
+-	.open		= proc_titantod_open,
+-	.read		= seq_read,
+-	.llseek		= seq_lseek,
+-	.release	= single_release,
+-};
+-
+-static int __init iseries_proc_init(void)
+-{
+-	struct proc_dir_entry *e;
+-
+-	e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL);
+-	if (e)
+-		e->proc_fops = &proc_titantod_operations;
+-
+-	return 0;
+-}
+-__initcall(iseries_proc_init);
+diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_setup.c
++++ /dev/null
+@@ -1,977 +0,0 @@
+-/*
+- *    Copyright (c) 2000 Mike Corrigan <mikejc at us.ibm.com>
+- *    Copyright (c) 1999-2000 Grant Erickson <grant at lcse.umn.edu>
+- *
+- *    Module name: iSeries_setup.c
+- *
+- *    Description:
+- *      Architecture- / platform-specific boot-time initialization code for
+- *      the IBM iSeries LPAR.  Adapted from original code by Grant Erickson and
+- *      code by Gary Thomas, Cort Dougan <cort at fsmlabs.com>, and Dan Malek
+- *      <dan at net4x.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.
+- */
+-
+-#undef DEBUG
+-
+-#include <linux/config.h>
+-#include <linux/init.h>
+-#include <linux/threads.h>
+-#include <linux/smp.h>
+-#include <linux/param.h>
+-#include <linux/string.h>
+-#include <linux/initrd.h>
+-#include <linux/seq_file.h>
+-#include <linux/kdev_t.h>
+-#include <linux/major.h>
+-#include <linux/root_dev.h>
+-
+-#include <asm/processor.h>
+-#include <asm/machdep.h>
+-#include <asm/page.h>
+-#include <asm/mmu.h>
+-#include <asm/pgtable.h>
+-#include <asm/mmu_context.h>
+-#include <asm/cputable.h>
+-#include <asm/sections.h>
+-#include <asm/iommu.h>
+-#include <asm/firmware.h>
+-
+-#include <asm/time.h>
+-#include "iSeries_setup.h"
+-#include <asm/naca.h>
+-#include <asm/paca.h>
+-#include <asm/cache.h>
+-#include <asm/sections.h>
+-#include <asm/abs_addr.h>
+-#include <asm/iSeries/HvCallHpt.h>
+-#include <asm/iSeries/HvLpConfig.h>
+-#include <asm/iSeries/HvCallEvent.h>
+-#include <asm/iSeries/HvCallSm.h>
+-#include <asm/iSeries/HvCallXm.h>
+-#include <asm/iSeries/ItLpQueue.h>
+-#include <asm/iSeries/IoHriMainStore.h>
+-#include <asm/iSeries/mf.h>
+-#include <asm/iSeries/HvLpEvent.h>
+-#include <asm/iSeries/iSeries_irq.h>
+-#include <asm/iSeries/IoHriProcessorVpd.h>
+-#include <asm/iSeries/ItVpdAreas.h>
+-#include <asm/iSeries/LparMap.h>
+-
+-extern void hvlog(char *fmt, ...);
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) hvlog(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-/* Function Prototypes */
+-extern void ppcdbg_initialize(void);
+-
+-static void build_iSeries_Memory_Map(void);
+-static void setup_iSeries_cache_sizes(void);
+-static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr);
+-#ifdef CONFIG_PCI
+-extern void iSeries_pci_final_fixup(void);
+-#else
+-static void iSeries_pci_final_fixup(void) { }
+-#endif
+-
+-/* Global Variables */
+-static unsigned long procFreqHz;
+-static unsigned long procFreqMhz;
+-static unsigned long procFreqMhzHundreths;
+-
+-static unsigned long tbFreqHz;
+-static unsigned long tbFreqMhz;
+-static unsigned long tbFreqMhzHundreths;
+-
+-int piranha_simulator;
+-
+-extern int rd_size;		/* Defined in drivers/block/rd.c */
+-extern unsigned long klimit;
+-extern unsigned long embedded_sysmap_start;
+-extern unsigned long embedded_sysmap_end;
+-
+-extern unsigned long iSeries_recal_tb;
+-extern unsigned long iSeries_recal_titan;
+-
+-static int mf_initialized;
+-
+-struct MemoryBlock {
+-	unsigned long absStart;
+-	unsigned long absEnd;
+-	unsigned long logicalStart;
+-	unsigned long logicalEnd;
+-};
+-
+-/*
+- * Process the main store vpd to determine where the holes in memory are
+- * and return the number of physical blocks and fill in the array of
+- * block data.
+- */
+-static unsigned long iSeries_process_Condor_mainstore_vpd(
+-		struct MemoryBlock *mb_array, unsigned long max_entries)
+-{
+-	unsigned long holeFirstChunk, holeSizeChunks;
+-	unsigned long numMemoryBlocks = 1;
+-	struct IoHriMainStoreSegment4 *msVpd =
+-		(struct IoHriMainStoreSegment4 *)xMsVpd;
+-	unsigned long holeStart = msVpd->nonInterleavedBlocksStartAdr;
+-	unsigned long holeEnd = msVpd->nonInterleavedBlocksEndAdr;
+-	unsigned long holeSize = holeEnd - holeStart;
+-
+-	printk("Mainstore_VPD: Condor\n");
+-	/*
+-	 * Determine if absolute memory has any
+-	 * holes so that we can interpret the
+-	 * access map we get back from the hypervisor
+-	 * correctly.
+-	 */
+-	mb_array[0].logicalStart = 0;
+-	mb_array[0].logicalEnd = 0x100000000;
+-	mb_array[0].absStart = 0;
+-	mb_array[0].absEnd = 0x100000000;
+-
+-	if (holeSize) {
+-		numMemoryBlocks = 2;
+-		holeStart = holeStart & 0x000fffffffffffff;
+-		holeStart = addr_to_chunk(holeStart);
+-		holeFirstChunk = holeStart;
+-		holeSize = addr_to_chunk(holeSize);
+-		holeSizeChunks = holeSize;
+-		printk( "Main store hole: start chunk = %0lx, size = %0lx chunks\n",
+-				holeFirstChunk, holeSizeChunks );
+-		mb_array[0].logicalEnd = holeFirstChunk;
+-		mb_array[0].absEnd = holeFirstChunk;
+-		mb_array[1].logicalStart = holeFirstChunk;
+-		mb_array[1].logicalEnd = 0x100000000 - holeSizeChunks;
+-		mb_array[1].absStart = holeFirstChunk + holeSizeChunks;
+-		mb_array[1].absEnd = 0x100000000;
+-	}
+-	return numMemoryBlocks;
+-}
+-
+-#define MaxSegmentAreas			32
+-#define MaxSegmentAdrRangeBlocks	128
+-#define MaxAreaRangeBlocks		4
+-
+-static unsigned long iSeries_process_Regatta_mainstore_vpd(
+-		struct MemoryBlock *mb_array, unsigned long max_entries)
+-{
+-	struct IoHriMainStoreSegment5 *msVpdP =
+-		(struct IoHriMainStoreSegment5 *)xMsVpd;
+-	unsigned long numSegmentBlocks = 0;
+-	u32 existsBits = msVpdP->msAreaExists;
+-	unsigned long area_num;
+-
+-	printk("Mainstore_VPD: Regatta\n");
+-
+-	for (area_num = 0; area_num < MaxSegmentAreas; ++area_num ) {
+-		unsigned long numAreaBlocks;
+-		struct IoHriMainStoreArea4 *currentArea;
+-
+-		if (existsBits & 0x80000000) {
+-			unsigned long block_num;
+-
+-			currentArea = &msVpdP->msAreaArray[area_num];
+-			numAreaBlocks = currentArea->numAdrRangeBlocks;
+-			printk("ms_vpd: processing area %2ld  blocks=%ld",
+-					area_num, numAreaBlocks);
+-			for (block_num = 0; block_num < numAreaBlocks;
+-					++block_num ) {
+-				/* Process an address range block */
+-				struct MemoryBlock tempBlock;
+-				unsigned long i;
+-
+-				tempBlock.absStart =
+-					(unsigned long)currentArea->xAdrRangeBlock[block_num].blockStart;
+-				tempBlock.absEnd =
+-					(unsigned long)currentArea->xAdrRangeBlock[block_num].blockEnd;
+-				tempBlock.logicalStart = 0;
+-				tempBlock.logicalEnd   = 0;
+-				printk("\n          block %ld absStart=%016lx absEnd=%016lx",
+-						block_num, tempBlock.absStart,
+-						tempBlock.absEnd);
+-
+-				for (i = 0; i < numSegmentBlocks; ++i) {
+-					if (mb_array[i].absStart ==
+-							tempBlock.absStart)
+-						break;
+-				}
+-				if (i == numSegmentBlocks) {
+-					if (numSegmentBlocks == max_entries)
+-						panic("iSeries_process_mainstore_vpd: too many memory blocks");
+-					mb_array[numSegmentBlocks] = tempBlock;
+-					++numSegmentBlocks;
+-				} else
+-					printk(" (duplicate)");
+-			}
+-			printk("\n");
+-		}
+-		existsBits <<= 1;
+-	}
+-	/* Now sort the blocks found into ascending sequence */
+-	if (numSegmentBlocks > 1) {
+-		unsigned long m, n;
+-
+-		for (m = 0; m < numSegmentBlocks - 1; ++m) {
+-			for (n = numSegmentBlocks - 1; m < n; --n) {
+-				if (mb_array[n].absStart <
+-						mb_array[n-1].absStart) {
+-					struct MemoryBlock tempBlock;
+-
+-					tempBlock = mb_array[n];
+-					mb_array[n] = mb_array[n-1];
+-					mb_array[n-1] = tempBlock;
+-				}
+-			}
+-		}
+-	}
+-	/*
+-	 * Assign "logical" addresses to each block.  These
+-	 * addresses correspond to the hypervisor "bitmap" space.
+-	 * Convert all addresses into units of 256K chunks.
+-	 */
+-	{
+-	unsigned long i, nextBitmapAddress;
+-
+-	printk("ms_vpd: %ld sorted memory blocks\n", numSegmentBlocks);
+-	nextBitmapAddress = 0;
+-	for (i = 0; i < numSegmentBlocks; ++i) {
+-		unsigned long length = mb_array[i].absEnd -
+-			mb_array[i].absStart;
+-
+-		mb_array[i].logicalStart = nextBitmapAddress;
+-		mb_array[i].logicalEnd = nextBitmapAddress + length;
+-		nextBitmapAddress += length;
+-		printk("          Bitmap range: %016lx - %016lx\n"
+-				"        Absolute range: %016lx - %016lx\n",
+-				mb_array[i].logicalStart,
+-				mb_array[i].logicalEnd,
+-				mb_array[i].absStart, mb_array[i].absEnd);
+-		mb_array[i].absStart = addr_to_chunk(mb_array[i].absStart &
+-				0x000fffffffffffff);
+-		mb_array[i].absEnd = addr_to_chunk(mb_array[i].absEnd &
+-				0x000fffffffffffff);
+-		mb_array[i].logicalStart =
+-			addr_to_chunk(mb_array[i].logicalStart);
+-		mb_array[i].logicalEnd = addr_to_chunk(mb_array[i].logicalEnd);
+-	}
+-	}
+-
+-	return numSegmentBlocks;
+-}
+-
+-static unsigned long iSeries_process_mainstore_vpd(struct MemoryBlock *mb_array,
+-		unsigned long max_entries)
+-{
+-	unsigned long i;
+-	unsigned long mem_blocks = 0;
+-
+-	if (cpu_has_feature(CPU_FTR_SLB))
+-		mem_blocks = iSeries_process_Regatta_mainstore_vpd(mb_array,
+-				max_entries);
+-	else
+-		mem_blocks = iSeries_process_Condor_mainstore_vpd(mb_array,
+-				max_entries);
+-
+-	printk("Mainstore_VPD: numMemoryBlocks = %ld \n", mem_blocks);
+-	for (i = 0; i < mem_blocks; ++i) {
+-		printk("Mainstore_VPD: block %3ld logical chunks %016lx - %016lx\n"
+-		       "                             abs chunks %016lx - %016lx\n",
+-			i, mb_array[i].logicalStart, mb_array[i].logicalEnd,
+-			mb_array[i].absStart, mb_array[i].absEnd);
+-	}
+-	return mem_blocks;
+-}
+-
+-static void __init iSeries_get_cmdline(void)
+-{
+-	char *p, *q;
+-
+-	/* copy the command line parameter from the primary VSP  */
+-	HvCallEvent_dmaToSp(cmd_line, 2 * 64* 1024, 256,
+-			HvLpDma_Direction_RemoteToLocal);
+-
+-	p = cmd_line;
+-	q = cmd_line + 255;
+-	while(p < q) {
+-		if (!*p || *p == '\n')
+-			break;
+-		++p;
+-	}
+-	*p = 0;
+-}
+-
+-static void __init iSeries_init_early(void)
+-{
+-	extern unsigned long memory_limit;
+-
+-	DBG(" -> iSeries_init_early()\n");
+-
+-	ppc64_firmware_features = FW_FEATURE_ISERIES;
+-
+-	ppcdbg_initialize();
+-
+-#if defined(CONFIG_BLK_DEV_INITRD)
+-	/*
+-	 * If the init RAM disk has been configured and there is
+-	 * a non-zero starting address for it, set it up
+-	 */
+-	if (naca.xRamDisk) {
+-		initrd_start = (unsigned long)__va(naca.xRamDisk);
+-		initrd_end = initrd_start + naca.xRamDiskSize * PAGE_SIZE;
+-		initrd_below_start_ok = 1;	// ramdisk in kernel space
+-		ROOT_DEV = Root_RAM0;
+-		if (((rd_size * 1024) / PAGE_SIZE) < naca.xRamDiskSize)
+-			rd_size = (naca.xRamDiskSize * PAGE_SIZE) / 1024;
+-	} else
+-#endif /* CONFIG_BLK_DEV_INITRD */
+-	{
+-	    /* ROOT_DEV = MKDEV(VIODASD_MAJOR, 1); */
+-	}
+-
+-	iSeries_recal_tb = get_tb();
+-	iSeries_recal_titan = HvCallXm_loadTod();
+-
+-	/*
+-	 * Cache sizes must be initialized before hpte_init_iSeries is called
+-	 * as the later need them for flush_icache_range()
+-	 */
+-	setup_iSeries_cache_sizes();
+-
+-	/*
+-	 * Initialize the hash table management pointers
+-	 */
+-	hpte_init_iSeries();
+-
+-	/*
+-	 * Initialize the DMA/TCE management
+-	 */
+-	iommu_init_early_iSeries();
+-
+-	/*
+-	 * Initialize the table which translate Linux physical addresses to
+-	 * AS/400 absolute addresses
+-	 */
+-	build_iSeries_Memory_Map();
+-
+-	iSeries_get_cmdline();
+-
+-	/* Save unparsed command line copy for /proc/cmdline */
+-	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
+-
+-	/* Parse early parameters, in particular mem=x */
+-	parse_early_param();
+-
+-	if (memory_limit) {
+-		if (memory_limit < systemcfg->physicalMemorySize)
+-			systemcfg->physicalMemorySize = memory_limit;
+-		else {
+-			printk("Ignoring mem=%lu >= ram_top.\n", memory_limit);
+-			memory_limit = 0;
+-		}
+-	}
+-
+-	/* Bolt kernel mappings for all of memory (or just a bit if we've got a limit) */
+-	iSeries_bolt_kernel(0, systemcfg->physicalMemorySize);
+-
+-	lmb_init();
+-	lmb_add(0, systemcfg->physicalMemorySize);
+-	lmb_analyze();
+-	lmb_reserve(0, __pa(klimit));
+-
+-	/* Initialize machine-dependency vectors */
+-#ifdef CONFIG_SMP
+-	smp_init_iSeries();
+-#endif
+-	if (itLpNaca.xPirEnvironMode == 0)
+-		piranha_simulator = 1;
+-
+-	/* Associate Lp Event Queue 0 with processor 0 */
+-	HvCallEvent_setLpEventQueueInterruptProc(0, 0);
+-
+-	mf_init();
+-	mf_initialized = 1;
+-	mb();
+-
+-	/* If we were passed an initrd, set the ROOT_DEV properly if the values
+-	 * look sensible. If not, clear initrd reference.
+-	 */
+-#ifdef CONFIG_BLK_DEV_INITRD
+-	if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
+-	    initrd_end > initrd_start)
+-		ROOT_DEV = Root_RAM0;
+-	else
+-		initrd_start = initrd_end = 0;
+-#endif /* CONFIG_BLK_DEV_INITRD */
+-
+-	DBG(" <- iSeries_init_early()\n");
+-}
+-
+-struct mschunks_map mschunks_map = {
+-	/* XXX We don't use these, but Piranha might need them. */
+-	.chunk_size  = MSCHUNKS_CHUNK_SIZE,
+-	.chunk_shift = MSCHUNKS_CHUNK_SHIFT,
+-	.chunk_mask  = MSCHUNKS_OFFSET_MASK,
+-};
+-EXPORT_SYMBOL(mschunks_map);
+-
+-void mschunks_alloc(unsigned long num_chunks)
+-{
+-	klimit = _ALIGN(klimit, sizeof(u32));
+-	mschunks_map.mapping = (u32 *)klimit;
+-	klimit += num_chunks * sizeof(u32);
+-	mschunks_map.num_chunks = num_chunks;
+-}
+-
+-/*
+- * The iSeries may have very large memories ( > 128 GB ) and a partition
+- * may get memory in "chunks" that may be anywhere in the 2**52 real
+- * address space.  The chunks are 256K in size.  To map this to the
+- * memory model Linux expects, the AS/400 specific code builds a
+- * translation table to translate what Linux thinks are "physical"
+- * addresses to the actual real addresses.  This allows us to make
+- * it appear to Linux that we have contiguous memory starting at
+- * physical address zero while in fact this could be far from the truth.
+- * To avoid confusion, I'll let the words physical and/or real address
+- * apply to the Linux addresses while I'll use "absolute address" to
+- * refer to the actual hardware real address.
+- *
+- * build_iSeries_Memory_Map gets information from the Hypervisor and
+- * looks at the Main Store VPD to determine the absolute addresses
+- * of the memory that has been assigned to our partition and builds
+- * a table used to translate Linux's physical addresses to these
+- * absolute addresses.  Absolute addresses are needed when
+- * communicating with the hypervisor (e.g. to build HPT entries)
+- */
+-
+-static void __init build_iSeries_Memory_Map(void)
+-{
+-	u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize;
+-	u32 nextPhysChunk;
+-	u32 hptFirstChunk, hptLastChunk, hptSizeChunks, hptSizePages;
+-	u32 num_ptegs;
+-	u32 totalChunks,moreChunks;
+-	u32 currChunk, thisChunk, absChunk;
+-	u32 currDword;
+-	u32 chunkBit;
+-	u64 map;
+-	struct MemoryBlock mb[32];
+-	unsigned long numMemoryBlocks, curBlock;
+-
+-	/* Chunk size on iSeries is 256K bytes */
+-	totalChunks = (u32)HvLpConfig_getMsChunks();
+-	mschunks_alloc(totalChunks);
+-
+-	/*
+-	 * Get absolute address of our load area
+-	 * and map it to physical address 0
+-	 * This guarantees that the loadarea ends up at physical 0
+-	 * otherwise, it might not be returned by PLIC as the first
+-	 * chunks
+-	 */
+-
+-	loadAreaFirstChunk = (u32)addr_to_chunk(itLpNaca.xLoadAreaAddr);
+-	loadAreaSize =  itLpNaca.xLoadAreaChunks;
+-
+-	/*
+-	 * Only add the pages already mapped here.
+-	 * Otherwise we might add the hpt pages
+-	 * The rest of the pages of the load area
+-	 * aren't in the HPT yet and can still
+-	 * be assigned an arbitrary physical address
+-	 */
+-	if ((loadAreaSize * 64) > HvPagesToMap)
+-		loadAreaSize = HvPagesToMap / 64;
+-
+-	loadAreaLastChunk = loadAreaFirstChunk + loadAreaSize - 1;
+-
+-	/*
+-	 * TODO Do we need to do something if the HPT is in the 64MB load area?
+-	 * This would be required if the itLpNaca.xLoadAreaChunks includes
+-	 * the HPT size
+-	 */
+-
+-	printk("Mapping load area - physical addr = 0000000000000000\n"
+-		"                    absolute addr = %016lx\n",
+-		chunk_to_addr(loadAreaFirstChunk));
+-	printk("Load area size %dK\n", loadAreaSize * 256);
+-
+-	for (nextPhysChunk = 0; nextPhysChunk < loadAreaSize; ++nextPhysChunk)
+-		mschunks_map.mapping[nextPhysChunk] =
+-			loadAreaFirstChunk + nextPhysChunk;
+-
+-	/*
+-	 * Get absolute address of our HPT and remember it so
+-	 * we won't map it to any physical address
+-	 */
+-	hptFirstChunk = (u32)addr_to_chunk(HvCallHpt_getHptAddress());
+-	hptSizePages = (u32)HvCallHpt_getHptPages();
+-	hptSizeChunks = hptSizePages >> (MSCHUNKS_CHUNK_SHIFT - PAGE_SHIFT);
+-	hptLastChunk = hptFirstChunk + hptSizeChunks - 1;
+-
+-	printk("HPT absolute addr = %016lx, size = %dK\n",
+-			chunk_to_addr(hptFirstChunk), hptSizeChunks * 256);
+-
+-	/* Fill in the hashed page table hash mask */
+-	num_ptegs = hptSizePages *
+-		(PAGE_SIZE / (sizeof(hpte_t) * HPTES_PER_GROUP));
+-	htab_hash_mask = num_ptegs - 1;
+-
+-	/*
+-	 * The actual hashed page table is in the hypervisor,
+-	 * we have no direct access
+-	 */
+-	htab_address = NULL;
+-
+-	/*
+-	 * Determine if absolute memory has any
+-	 * holes so that we can interpret the
+-	 * access map we get back from the hypervisor
+-	 * correctly.
+-	 */
+-	numMemoryBlocks = iSeries_process_mainstore_vpd(mb, 32);
+-
+-	/*
+-	 * Process the main store access map from the hypervisor
+-	 * to build up our physical -> absolute translation table
+-	 */
+-	curBlock = 0;
+-	currChunk = 0;
+-	currDword = 0;
+-	moreChunks = totalChunks;
+-
+-	while (moreChunks) {
+-		map = HvCallSm_get64BitsOfAccessMap(itLpNaca.xLpIndex,
+-				currDword);
+-		thisChunk = currChunk;
+-		while (map) {
+-			chunkBit = map >> 63;
+-			map <<= 1;
+-			if (chunkBit) {
+-				--moreChunks;
+-				while (thisChunk >= mb[curBlock].logicalEnd) {
+-					++curBlock;
+-					if (curBlock >= numMemoryBlocks)
+-						panic("out of memory blocks");
+-				}
+-				if (thisChunk < mb[curBlock].logicalStart)
+-					panic("memory block error");
+-
+-				absChunk = mb[curBlock].absStart +
+-					(thisChunk - mb[curBlock].logicalStart);
+-				if (((absChunk < hptFirstChunk) ||
+-				     (absChunk > hptLastChunk)) &&
+-				    ((absChunk < loadAreaFirstChunk) ||
+-				     (absChunk > loadAreaLastChunk))) {
+-					mschunks_map.mapping[nextPhysChunk] =
+-						absChunk;
+-					++nextPhysChunk;
+-				}
+-			}
+-			++thisChunk;
+-		}
+-		++currDword;
+-		currChunk += 64;
+-	}
+-
+-	/*
+-	 * main store size (in chunks) is
+-	 *   totalChunks - hptSizeChunks
+-	 * which should be equal to
+-	 *   nextPhysChunk
+-	 */
+-	systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk);
+-}
+-
+-/*
+- * Set up the variables that describe the cache line sizes
+- * for this machine.
+- */
+-static void __init setup_iSeries_cache_sizes(void)
+-{
+-	unsigned int i, n;
+-	unsigned int procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
+-
+-	systemcfg->icache_size =
+-	ppc64_caches.isize = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
+-	systemcfg->icache_line_size =
+-	ppc64_caches.iline_size =
+-		xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
+-	systemcfg->dcache_size =
+-	ppc64_caches.dsize =
+-		xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024;
+-	systemcfg->dcache_line_size =
+-	ppc64_caches.dline_size =
+-		xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
+-	ppc64_caches.ilines_per_page = PAGE_SIZE / ppc64_caches.iline_size;
+-	ppc64_caches.dlines_per_page = PAGE_SIZE / ppc64_caches.dline_size;
+-
+-	i = ppc64_caches.iline_size;
+-	n = 0;
+-	while ((i = (i / 2)))
+-		++n;
+-	ppc64_caches.log_iline_size = n;
+-
+-	i = ppc64_caches.dline_size;
+-	n = 0;
+-	while ((i = (i / 2)))
+-		++n;
+-	ppc64_caches.log_dline_size = n;
+-
+-	printk("D-cache line size = %d\n",
+-			(unsigned int)ppc64_caches.dline_size);
+-	printk("I-cache line size = %d\n",
+-			(unsigned int)ppc64_caches.iline_size);
+-}
+-
+-/*
+- * Create a pte. Used during initialization only.
+- */
+-static void iSeries_make_pte(unsigned long va, unsigned long pa,
+-			     int mode)
+-{
+-	hpte_t local_hpte, rhpte;
+-	unsigned long hash, vpn;
+-	long slot;
+-
+-	vpn = va >> PAGE_SHIFT;
+-	hash = hpt_hash(vpn, 0);
+-
+-	local_hpte.r = pa | mode;
+-	local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT)
+-		| HPTE_V_BOLTED | HPTE_V_VALID;
+-
+-	slot = HvCallHpt_findValid(&rhpte, vpn);
+-	if (slot < 0) {
+-		/* Must find space in primary group */
+-		panic("hash_page: hpte already exists\n");
+-	}
+-	HvCallHpt_addValidate(slot, 0, &local_hpte);
+-}
+-
+-/*
+- * Bolt the kernel addr space into the HPT
+- */
+-static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr)
+-{
+-	unsigned long pa;
+-	unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
+-	hpte_t hpte;
+-
+-	for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) {
+-		unsigned long ea = (unsigned long)__va(pa);
+-		unsigned long vsid = get_kernel_vsid(ea);
+-		unsigned long va = (vsid << 28) | (pa & 0xfffffff);
+-		unsigned long vpn = va >> PAGE_SHIFT;
+-		unsigned long slot = HvCallHpt_findValid(&hpte, vpn);
+-
+-		/* Make non-kernel text non-executable */
+-		if (!in_kernel_text(ea))
+-			mode_rw |= HW_NO_EXEC;
+-
+-		if (hpte.v & HPTE_V_VALID) {
+-			/* HPTE exists, so just bolt it */
+-			HvCallHpt_setSwBits(slot, 0x10, 0);
+-			/* And make sure the pp bits are correct */
+-			HvCallHpt_setPp(slot, PP_RWXX);
+-		} else
+-			/* No HPTE exists, so create a new bolted one */
+-			iSeries_make_pte(va, phys_to_abs(pa), mode_rw);
+-	}
+-}
+-
+-/*
+- * Document me.
+- */
+-static void __init iSeries_setup_arch(void)
+-{
+-	unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
+-
+-	/* Add an eye catcher and the systemcfg layout version number */
+-	strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
+-	systemcfg->version.major = SYSTEMCFG_MAJOR;
+-	systemcfg->version.minor = SYSTEMCFG_MINOR;
+-
+-	/* Setup the Lp Event Queue */
+-	setup_hvlpevent_queue();
+-
+-	/* Compute processor frequency */
+-	procFreqHz = ((1UL << 34) * 1000000) /
+-			xIoHriProcessorVpd[procIx].xProcFreq;
+-	procFreqMhz = procFreqHz / 1000000;
+-	procFreqMhzHundreths = (procFreqHz / 10000) - (procFreqMhz * 100);
+-	ppc_proc_freq = procFreqHz;
+-
+-	/* Compute time base frequency */
+-	tbFreqHz = ((1UL << 32) * 1000000) /
+-		xIoHriProcessorVpd[procIx].xTimeBaseFreq;
+-	tbFreqMhz = tbFreqHz / 1000000;
+-	tbFreqMhzHundreths = (tbFreqHz / 10000) - (tbFreqMhz * 100);
+-	ppc_tb_freq = tbFreqHz;
+-
+-	printk("Max  logical processors = %d\n",
+-			itVpdAreas.xSlicMaxLogicalProcs);
+-	printk("Max physical processors = %d\n",
+-			itVpdAreas.xSlicMaxPhysicalProcs);
+-	printk("Processor frequency = %lu.%02lu\n", procFreqMhz,
+-			procFreqMhzHundreths);
+-	printk("Time base frequency = %lu.%02lu\n", tbFreqMhz,
+-			tbFreqMhzHundreths);
+-	systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
+-	printk("Processor version = %x\n", systemcfg->processor);
+-}
+-
+-static void iSeries_get_cpuinfo(struct seq_file *m)
+-{
+-	seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n");
+-}
+-
+-/*
+- * Document me.
+- * and Implement me.
+- */
+-static int iSeries_get_irq(struct pt_regs *regs)
+-{
+-	/* -2 means ignore this interrupt */
+-	return -2;
+-}
+-
+-/*
+- * Document me.
+- */
+-static void iSeries_restart(char *cmd)
+-{
+-	mf_reboot();
+-}
+-
+-/*
+- * Document me.
+- */
+-static void iSeries_power_off(void)
+-{
+-	mf_power_off();
+-}
+-
+-/*
+- * Document me.
+- */
+-static void iSeries_halt(void)
+-{
+-	mf_power_off();
+-}
+-
+-/*
+- * void __init iSeries_calibrate_decr()
+- *
+- * Description:
+- *   This routine retrieves the internal processor frequency from the VPD,
+- *   and sets up the kernel timer decrementer based on that value.
+- *
+- */
+-static void __init iSeries_calibrate_decr(void)
+-{
+-	unsigned long	cyclesPerUsec;
+-	struct div_result divres;
+-
+-	/* Compute decrementer (and TB) frequency in cycles/sec */
+-	cyclesPerUsec = ppc_tb_freq / 1000000;
+-
+-	/*
+-	 * Set the amount to refresh the decrementer by.  This
+-	 * is the number of decrementer ticks it takes for
+-	 * 1/HZ seconds.
+-	 */
+-	tb_ticks_per_jiffy = ppc_tb_freq / HZ;
+-
+-#if 0
+-	/* TEST CODE FOR ADJTIME */
+-	tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000;
+-	/* END OF TEST CODE */
+-#endif
+-
+-	/*
+-	 * tb_ticks_per_sec = freq; would give better accuracy
+-	 * but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures
+-	 * that jiffies (and xtime) will match the time returned
+-	 * by do_gettimeofday.
+-	 */
+-	tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
+-	tb_ticks_per_usec = cyclesPerUsec;
+-	tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
+-	div128_by_32(1024 * 1024, 0, tb_ticks_per_sec, &divres);
+-	tb_to_xs = divres.result_low;
+-	setup_default_decr();
+-}
+-
+-static void __init iSeries_progress(char * st, unsigned short code)
+-{
+-	printk("Progress: [%04x] - %s\n", (unsigned)code, st);
+-	if (!piranha_simulator && mf_initialized) {
+-		if (code != 0xffff)
+-			mf_display_progress(code);
+-		else
+-			mf_clear_src();
+-	}
+-}
+-
+-static void __init iSeries_fixup_klimit(void)
+-{
+-	/*
+-	 * Change klimit to take into account any ram disk
+-	 * that may be included
+-	 */
+-	if (naca.xRamDisk)
+-		klimit = KERNELBASE + (u64)naca.xRamDisk +
+-			(naca.xRamDiskSize * PAGE_SIZE);
+-	else {
+-		/*
+-		 * No ram disk was included - check and see if there
+-		 * was an embedded system map.  Change klimit to take
+-		 * into account any embedded system map
+-		 */
+-		if (embedded_sysmap_end)
+-			klimit = KERNELBASE + ((embedded_sysmap_end + 4095) &
+-					0xfffffffffffff000);
+-	}
+-}
+-
+-static int __init iSeries_src_init(void)
+-{
+-        /* clear the progress line */
+-        ppc_md.progress(" ", 0xffff);
+-        return 0;
+-}
+-
+-late_initcall(iSeries_src_init);
+-
+-static inline void process_iSeries_events(void)
+-{
+-	asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
+-}
+-
+-static void yield_shared_processor(void)
+-{
+-	unsigned long tb;
+-
+-	HvCall_setEnabledInterrupts(HvCall_MaskIPI |
+-				    HvCall_MaskLpEvent |
+-				    HvCall_MaskLpProd |
+-				    HvCall_MaskTimeout);
+-
+-	tb = get_tb();
+-	/* Compute future tb value when yield should expire */
+-	HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
+-
+-	/*
+-	 * The decrementer stops during the yield.  Force a fake decrementer
+-	 * here and let the timer_interrupt code sort out the actual time.
+-	 */
+-	get_paca()->lppaca.int_dword.fields.decr_int = 1;
+-	process_iSeries_events();
+-}
+-
+-static int iseries_shared_idle(void)
+-{
+-	while (1) {
+-		while (!need_resched() && !hvlpevent_is_pending()) {
+-			local_irq_disable();
+-			ppc64_runlatch_off();
+-
+-			/* Recheck with irqs off */
+-			if (!need_resched() && !hvlpevent_is_pending())
+-				yield_shared_processor();
+-
+-			HMT_medium();
+-			local_irq_enable();
+-		}
+-
+-		ppc64_runlatch_on();
+-
+-		if (hvlpevent_is_pending())
+-			process_iSeries_events();
+-
+-		schedule();
+-	}
+-
+-	return 0;
+-}
+-
+-static int iseries_dedicated_idle(void)
+-{
+-	long oldval;
+-
+-	while (1) {
+-		oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
+-
+-		if (!oldval) {
+-			set_thread_flag(TIF_POLLING_NRFLAG);
+-
+-			while (!need_resched()) {
+-				ppc64_runlatch_off();
+-				HMT_low();
+-
+-				if (hvlpevent_is_pending()) {
+-					HMT_medium();
+-					ppc64_runlatch_on();
+-					process_iSeries_events();
+-				}
+-			}
+-
+-			HMT_medium();
+-			clear_thread_flag(TIF_POLLING_NRFLAG);
+-		} else {
+-			set_need_resched();
+-		}
+-
+-		ppc64_runlatch_on();
+-		schedule();
+-	}
+-
+-	return 0;
+-}
+-
+-#ifndef CONFIG_PCI
+-void __init iSeries_init_IRQ(void) { }
+-#endif
+-
+-void __init iSeries_early_setup(void)
+-{
+-	iSeries_fixup_klimit();
+-
+-	ppc_md.setup_arch = iSeries_setup_arch;
+-	ppc_md.get_cpuinfo = iSeries_get_cpuinfo;
+-	ppc_md.init_IRQ = iSeries_init_IRQ;
+-	ppc_md.get_irq = iSeries_get_irq;
+-	ppc_md.init_early = iSeries_init_early,
+-
+-	ppc_md.pcibios_fixup  = iSeries_pci_final_fixup;
+-
+-	ppc_md.restart = iSeries_restart;
+-	ppc_md.power_off = iSeries_power_off;
+-	ppc_md.halt = iSeries_halt;
+-
+-	ppc_md.get_boot_time = iSeries_get_boot_time;
+-	ppc_md.set_rtc_time = iSeries_set_rtc_time;
+-	ppc_md.get_rtc_time = iSeries_get_rtc_time;
+-	ppc_md.calibrate_decr = iSeries_calibrate_decr;
+-	ppc_md.progress = iSeries_progress;
+-
+-	/* XXX Implement enable_pmcs for iSeries */
+-
+-	if (get_paca()->lppaca.shared_proc) {
+-		ppc_md.idle_loop = iseries_shared_idle;
+-		printk(KERN_INFO "Using shared processor idle loop\n");
+-	} else {
+-		ppc_md.idle_loop = iseries_dedicated_idle;
+-		printk(KERN_INFO "Using dedicated idle loop\n");
+-	}
+-}
+-
+diff --git a/arch/ppc64/kernel/iSeries_setup.h b/arch/ppc64/kernel/iSeries_setup.h
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_setup.h
++++ /dev/null
+@@ -1,26 +0,0 @@
+-/*
+- *    Copyright (c) 2000 Mike Corrigan <mikejc at us.ibm.com>
+- *    Copyright (c) 1999-2000 Grant Erickson <grant at lcse.umn.edu>
+- *
+- *    Module name: as400_setup.h
+- *
+- *    Description:
+- *      Architecture- / platform-specific boot-time initialization code for
+- *      the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and
+- *      code by Gary Thomas, Cort Dougan <cort at cs.nmt.edu>, and Dan Malek
+- *      <dan at netx4.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	__ISERIES_SETUP_H__
+-#define	__ISERIES_SETUP_H__
+-
+-extern void iSeries_get_boot_time(struct rtc_time *tm);
+-extern int iSeries_set_rtc_time(struct rtc_time *tm);
+-extern void iSeries_get_rtc_time(struct rtc_time *tm);
+-
+-#endif /* __ISERIES_SETUP_H__ */
+diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/ppc64/kernel/iSeries_smp.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_smp.c
++++ /dev/null
+@@ -1,149 +0,0 @@
+-/*
+- * SMP support for iSeries machines.
+- *
+- * Dave Engebretsen, Peter Bergner, and
+- * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
+- *
+- * Plus various changes from other IBM teams...
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/config.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/sched.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/interrupt.h>
+-#include <linux/kernel_stat.h>
+-#include <linux/delay.h>
+-#include <linux/init.h>
+-#include <linux/spinlock.h>
+-#include <linux/cache.h>
+-#include <linux/err.h>
+-#include <linux/sysdev.h>
+-#include <linux/cpu.h>
+-
+-#include <asm/ptrace.h>
+-#include <asm/atomic.h>
+-#include <asm/irq.h>
+-#include <asm/page.h>
+-#include <asm/pgtable.h>
+-#include <asm/io.h>
+-#include <asm/smp.h>
+-#include <asm/paca.h>
+-#include <asm/iSeries/HvCall.h>
+-#include <asm/time.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/machdep.h>
+-#include <asm/cputable.h>
+-#include <asm/system.h>
+-
+-static unsigned long iSeries_smp_message[NR_CPUS];
+-
+-void iSeries_smp_message_recv( struct pt_regs * regs )
+-{
+-	int cpu = smp_processor_id();
+-	int msg;
+-
+-	if ( num_online_cpus() < 2 )
+-		return;
+-
+-	for ( msg = 0; msg < 4; ++msg )
+-		if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) )
+-			smp_message_recv( msg, regs );
+-}
+-
+-static inline void smp_iSeries_do_message(int cpu, int msg)
+-{
+-	set_bit(msg, &iSeries_smp_message[cpu]);
+-	HvCall_sendIPI(&(paca[cpu]));
+-}
+-
+-static void smp_iSeries_message_pass(int target, int msg)
+-{
+-	int i;
+-
+-	if (target < NR_CPUS)
+-		smp_iSeries_do_message(target, msg);
+-	else {
+-		for_each_online_cpu(i) {
+-			if (target == MSG_ALL_BUT_SELF
+-			    && i == smp_processor_id())
+-				continue;
+-			smp_iSeries_do_message(i, msg);
+-		}
+-	}
+-}
+-
+-static int smp_iSeries_numProcs(void)
+-{
+-	unsigned np, i;
+-
+-	np = 0;
+-        for (i=0; i < NR_CPUS; ++i) {
+-                if (paca[i].lppaca.dyn_proc_status < 2) {
+-			cpu_set(i, cpu_possible_map);
+-			cpu_set(i, cpu_present_map);
+-			cpu_set(i, cpu_sibling_map[i]);
+-                        ++np;
+-                }
+-        }
+-	return np;
+-}
+-
+-static int smp_iSeries_probe(void)
+-{
+-	unsigned i;
+-	unsigned np = 0;
+-
+-	for (i=0; i < NR_CPUS; ++i) {
+-		if (paca[i].lppaca.dyn_proc_status < 2) {
+-			/*paca[i].active = 1;*/
+-			++np;
+-		}
+-	}
+-
+-	return np;
+-}
+-
+-static void smp_iSeries_kick_cpu(int nr)
+-{
+-	BUG_ON(nr < 0 || nr >= NR_CPUS);
+-
+-	/* Verify that our partition has a processor nr */
+-	if (paca[nr].lppaca.dyn_proc_status >= 2)
+-		return;
+-
+-	/* The processor is currently spinning, waiting
+-	 * for the cpu_start field to become non-zero
+-	 * After we set cpu_start, the processor will
+-	 * continue on to secondary_start in iSeries_head.S
+-	 */
+-	paca[nr].cpu_start = 1;
+-}
+-
+-static void __devinit smp_iSeries_setup_cpu(int nr)
+-{
+-}
+-
+-static struct smp_ops_t iSeries_smp_ops = {
+-	.message_pass = smp_iSeries_message_pass,
+-	.probe        = smp_iSeries_probe,
+-	.kick_cpu     = smp_iSeries_kick_cpu,
+-	.setup_cpu    = smp_iSeries_setup_cpu,
+-};
+-
+-/* This is called very early. */
+-void __init smp_init_iSeries(void)
+-{
+-	smp_ops = &iSeries_smp_ops;
+-	systemcfg->processorCount	= smp_iSeries_numProcs();
+-}
+-
+diff --git a/arch/ppc64/kernel/iSeries_vio.c b/arch/ppc64/kernel/iSeries_vio.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/iSeries_vio.c
++++ /dev/null
+@@ -1,155 +0,0 @@
+-/*
+- * IBM PowerPC iSeries Virtual I/O Infrastructure Support.
+- *
+- *    Copyright (c) 2005 Stephen Rothwell, IBM Corp.
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the GNU General Public License
+- *      as published by the Free Software Foundation; either version
+- *      2 of the License, or (at your option) any later version.
+- */
+-#include <linux/types.h>
+-#include <linux/device.h>
+-#include <linux/init.h>
+-
+-#include <asm/vio.h>
+-#include <asm/iommu.h>
+-#include <asm/abs_addr.h>
+-#include <asm/page.h>
+-#include <asm/iSeries/vio.h>
+-#include <asm/iSeries/HvTypes.h>
+-#include <asm/iSeries/HvLpConfig.h>
+-#include <asm/iSeries/HvCallXm.h>
+-
+-struct device *iSeries_vio_dev = &vio_bus_device.dev;
+-EXPORT_SYMBOL(iSeries_vio_dev);
+-
+-static struct iommu_table veth_iommu_table;
+-static struct iommu_table vio_iommu_table;
+-
+-static void __init iommu_vio_init(void)
+-{
+-	struct iommu_table *t;
+-	struct iommu_table_cb cb;
+-	unsigned long cbp;
+-	unsigned long itc_entries;
+-
+-	cb.itc_busno = 255;    /* Bus 255 is the virtual bus */
+-	cb.itc_virtbus = 0xff; /* Ask for virtual bus */
+-
+-	cbp = virt_to_abs(&cb);
+-	HvCallXm_getTceTableParms(cbp);
+-
+-	itc_entries = cb.itc_size * PAGE_SIZE / sizeof(union tce_entry);
+-	veth_iommu_table.it_size        = itc_entries / 2;
+-	veth_iommu_table.it_busno       = cb.itc_busno;
+-	veth_iommu_table.it_offset      = cb.itc_offset;
+-	veth_iommu_table.it_index       = cb.itc_index;
+-	veth_iommu_table.it_type        = TCE_VB;
+-	veth_iommu_table.it_blocksize	= 1;
+-
+-	t = iommu_init_table(&veth_iommu_table);
+-
+-	if (!t)
+-		printk("Virtual Bus VETH TCE table failed.\n");
+-
+-	vio_iommu_table.it_size         = itc_entries - veth_iommu_table.it_size;
+-	vio_iommu_table.it_busno        = cb.itc_busno;
+-	vio_iommu_table.it_offset       = cb.itc_offset +
+-					  veth_iommu_table.it_size;
+-	vio_iommu_table.it_index        = cb.itc_index;
+-	vio_iommu_table.it_type         = TCE_VB;
+-	vio_iommu_table.it_blocksize	= 1;
+-
+-	t = iommu_init_table(&vio_iommu_table);
+-
+-	if (!t)
+-		printk("Virtual Bus VIO TCE table failed.\n");
+-}
+-
+-/**
+- * vio_register_device_iseries: - Register a new iSeries vio device.
+- * @voidev:	The device to register.
+- */
+-static struct vio_dev *__init vio_register_device_iseries(char *type,
+-		uint32_t unit_num)
+-{
+-	struct vio_dev *viodev;
+-
+-	/* allocate a vio_dev for this device */
+-	viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
+-	if (!viodev)
+-		return NULL;
+-	memset(viodev, 0, sizeof(struct vio_dev));
+-
+-	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num);
+-
+-	viodev->name = viodev->dev.bus_id;
+-	viodev->type = type;
+-	viodev->unit_address = unit_num;
+-	viodev->iommu_table = &vio_iommu_table;
+-	if (vio_register_device(viodev) == NULL) {
+-		kfree(viodev);
+-		return NULL;
+-	}
+-	return viodev;
+-}
+-
+-void __init probe_bus_iseries(void)
+-{
+-	HvLpIndexMap vlan_map;
+-	struct vio_dev *viodev;
+-	int i;
+-
+-	/* there is only one of each of these */
+-	vio_register_device_iseries("viocons", 0);
+-	vio_register_device_iseries("vscsi", 0);
+-
+-	vlan_map = HvLpConfig_getVirtualLanIndexMap();
+-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
+-		if ((vlan_map & (0x8000 >> i)) == 0)
+-			continue;
+-		viodev = vio_register_device_iseries("vlan", i);
+-		/* veth is special and has it own iommu_table */
+-		viodev->iommu_table = &veth_iommu_table;
+-	}
+-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
+-		vio_register_device_iseries("viodasd", i);
+-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
+-		vio_register_device_iseries("viocd", i);
+-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
+-		vio_register_device_iseries("viotape", i);
+-}
+-
+-/**
+- * vio_match_device_iseries: - Tell if a iSeries VIO device matches a
+- *	vio_device_id
+- */
+-static int vio_match_device_iseries(const struct vio_device_id *id,
+-		const struct vio_dev *dev)
+-{
+-	return strncmp(dev->type, id->type, strlen(id->type)) == 0;
+-}
+-
+-static struct vio_bus_ops vio_bus_ops_iseries = {
+-	.match = vio_match_device_iseries,
+-};
+-
+-/**
+- * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus
+- */
+-static int __init vio_bus_init_iseries(void)
+-{
+-	int err;
+-
+-	err = vio_bus_init(&vio_bus_ops_iseries);
+-	if (err == 0) {
+-		iommu_vio_init();
+-		vio_bus_device.iommu_table = &vio_iommu_table;
+-		iSeries_vio_dev = &vio_bus_device.dev;
+-		probe_bus_iseries();
+-	}
+-	return err;
+-}
+-
+-__initcall(vio_bus_init_iseries);
+diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
+--- a/arch/ppc64/kernel/idle.c
++++ b/arch/ppc64/kernel/idle.c
+@@ -31,7 +31,7 @@
+ 
+ extern void power4_idle(void);
+ 
+-int default_idle(void)
++void default_idle(void)
+ {
+ 	long oldval;
+ 	unsigned int cpu = smp_processor_id();
+@@ -64,11 +64,9 @@ int default_idle(void)
+ 		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
+ 			cpu_die();
+ 	}
+-
+-	return 0;
+ }
+ 
+-int native_idle(void)
++void native_idle(void)
+ {
+ 	while (1) {
+ 		ppc64_runlatch_off();
+@@ -85,8 +83,6 @@ int native_idle(void)
+ 		    system_state == SYSTEM_RUNNING)
+ 			cpu_die();
+ 	}
+-
+-	return 0;
+ }
+ 
+ void cpu_idle(void)
+diff --git a/arch/ppc64/kernel/idle_power4.S b/arch/ppc64/kernel/idle_power4.S
+deleted file mode 100644
+--- a/arch/ppc64/kernel/idle_power4.S
++++ /dev/null
+@@ -1,79 +0,0 @@
+-/*
+- *  This file contains the power_save function for 6xx & 7xxx CPUs
+- *  rewritten in assembler
+- *
+- *  Warning ! This code assumes that if your machine has a 750fx
+- *  it will have PLL 1 set to low speed mode (used during NAP/DOZE).
+- *  if this is not the case some additional changes will have to
+- *  be done to check a runtime var (a bit like powersave-nap)
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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/threads.h>
+-#include <asm/processor.h>
+-#include <asm/page.h>
+-#include <asm/cputable.h>
+-#include <asm/thread_info.h>
+-#include <asm/ppc_asm.h>
+-#include <asm/asm-offsets.h>
+-
+-#undef DEBUG
+-
+-	.text
+-
+-/*
+- * Here is the power_save_6xx function. This could eventually be
+- * split into several functions & changing the function pointer
+- * depending on the various features.
+- */
+-_GLOBAL(power4_idle)
+-BEGIN_FTR_SECTION
+-	blr
+-END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
+-	/* We must dynamically check for the NAP feature as it
+-	 * can be cleared by CPU init after the fixups are done
+-	 */
+-	LOADBASE(r3,cur_cpu_spec)
+-	ld	r4,cur_cpu_spec at l(r3)
+-	ld	r4,CPU_SPEC_FEATURES(r4)
+-	andi.	r0,r4,CPU_FTR_CAN_NAP
+-	beqlr
+-	/* Now check if user or arch enabled NAP mode */
+-	LOADBASE(r3,powersave_nap)
+-	lwz	r4,powersave_nap at l(r3)
+-	cmpwi	0,r4,0
+-	beqlr
+-
+-	/* Clear MSR:EE */
+-	mfmsr	r7
+-	li	r4,0
+-	ori	r4,r4,MSR_EE
+-	andc	r0,r7,r4
+-	mtmsrd	r0
+-
+-	/* Check current_thread_info()->flags */
+-	clrrdi	r4,r1,THREAD_SHIFT
+-	ld	r4,TI_FLAGS(r4)
+-	andi.	r0,r4,_TIF_NEED_RESCHED
+-	beq	1f
+-	mtmsrd	r7	/* out of line this ? */
+-	blr
+-1:	
+-	/* Go to NAP now */	
+-BEGIN_FTR_SECTION
+-	DSSALL
+-	sync
+-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+-	oris	r7,r7,MSR_POW at h
+-	sync
+-	isync
+-	mtmsrd	r7
+-	isync
+-	sync
+-	blr
+-	
+diff --git a/arch/ppc64/kernel/init_task.c b/arch/ppc64/kernel/init_task.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/init_task.c
++++ /dev/null
+@@ -1,36 +0,0 @@
+-#include <linux/mm.h>
+-#include <linux/module.h>
+-#include <linux/sched.h>
+-#include <linux/init.h>
+-#include <linux/init_task.h>
+-#include <linux/fs.h>
+-#include <linux/mqueue.h>
+-#include <asm/uaccess.h>
+-
+-static struct fs_struct init_fs = INIT_FS;
+-static struct files_struct init_files = INIT_FILES;
+-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+-struct mm_struct init_mm = INIT_MM(init_mm);
+-
+-EXPORT_SYMBOL(init_mm);
+-
+-/*
+- * Initial thread structure.
+- *
+- * We need to make sure that this is 16384-byte aligned due to the
+- * way process stacks are handled. This is done by having a special
+- * "init_task" linker map entry..
+- */
+-union thread_union init_thread_union 
+-	__attribute__((__section__(".data.init_task"))) =
+-		{ INIT_THREAD_INFO(init_task) };
+-
+-/*
+- * Initial task structure.
+- *
+- * All other task structs will be allocated on slabs in fork.c
+- */
+-struct task_struct init_task = INIT_TASK(init_task);
+-
+-EXPORT_SYMBOL(init_task);
+diff --git a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
+--- a/arch/ppc64/kernel/ioctl32.c
++++ b/arch/ppc64/kernel/ioctl32.c
+@@ -39,9 +39,7 @@ IOCTL_TABLE_START
+ #include <linux/compat_ioctl.h>
+ #define DECLARES
+ #include "compat_ioctl.c"
+-COMPATIBLE_IOCTL(TIOCSTART)
+-COMPATIBLE_IOCTL(TIOCSTOP)
+-COMPATIBLE_IOCTL(TIOCSLTC)
++
+ /* Little p (/dev/rtc, /dev/envctrl, etc.) */
+ COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
+ COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
+diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
+--- a/arch/ppc64/kernel/kprobes.c
++++ b/arch/ppc64/kernel/kprobes.c
+@@ -395,7 +395,6 @@ int __kprobes kprobe_exceptions_notify(s
+ 		if (post_kprobe_handler(args->regs))
+ 			ret = NOTIFY_STOP;
+ 		break;
+-	case DIE_GPF:
+ 	case DIE_PAGE_FAULT:
+ 		if (kprobe_running() &&
+ 		    kprobe_fault_handler(args->regs, args->trapnr))
+diff --git a/arch/ppc64/kernel/lmb.c b/arch/ppc64/kernel/lmb.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/lmb.c
++++ /dev/null
+@@ -1,299 +0,0 @@
+-/*
+- * Procedures for interfacing to Open Firmware.
+- *
+- * Peter Bergner, IBM Corp.	June 2001.
+- * Copyright (C) 2001 Peter Bergner.
+- * 
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/init.h>
+-#include <linux/bitops.h>
+-#include <asm/types.h>
+-#include <asm/page.h>
+-#include <asm/prom.h>
+-#include <asm/lmb.h>
+-#include <asm/abs_addr.h>
+-
+-struct lmb lmb;
+-
+-#undef DEBUG
+-
+-void lmb_dump_all(void)
+-{
+-#ifdef DEBUG
+-	unsigned long i;
+-
+-	udbg_printf("lmb_dump_all:\n");
+-	udbg_printf("    memory.cnt		  = 0x%lx\n",
+-		    lmb.memory.cnt);
+-	udbg_printf("    memory.size		  = 0x%lx\n",
+-		    lmb.memory.size);
+-	for (i=0; i < lmb.memory.cnt ;i++) {
+-		udbg_printf("    memory.region[0x%x].base       = 0x%lx\n",
+-			    i, lmb.memory.region[i].base);
+-		udbg_printf("		      .size     = 0x%lx\n",
+-			    lmb.memory.region[i].size);
+-	}
+-
+-	udbg_printf("\n    reserved.cnt	  = 0x%lx\n",
+-		    lmb.reserved.cnt);
+-	udbg_printf("    reserved.size	  = 0x%lx\n",
+-		    lmb.reserved.size);
+-	for (i=0; i < lmb.reserved.cnt ;i++) {
+-		udbg_printf("    reserved.region[0x%x].base       = 0x%lx\n",
+-			    i, lmb.reserved.region[i].base);
+-		udbg_printf("		      .size     = 0x%lx\n",
+-			    lmb.reserved.region[i].size);
+-	}
+-#endif /* DEBUG */
+-}
+-
+-static unsigned long __init
+-lmb_addrs_overlap(unsigned long base1, unsigned long size1,
+-                  unsigned long base2, unsigned long size2)
+-{
+-	return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
+-}
+-
+-static long __init
+-lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
+-		   unsigned long base2, unsigned long size2)
+-{
+-	if (base2 == base1 + size1)
+-		return 1;
+-	else if (base1 == base2 + size2)
+-		return -1;
+-
+-	return 0;
+-}
+-
+-static long __init
+-lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
+-{
+-	unsigned long base1 = rgn->region[r1].base;
+-	unsigned long size1 = rgn->region[r1].size;
+-	unsigned long base2 = rgn->region[r2].base;
+-	unsigned long size2 = rgn->region[r2].size;
+-
+-	return lmb_addrs_adjacent(base1, size1, base2, size2);
+-}
+-
+-/* Assumption: base addr of region 1 < base addr of region 2 */
+-static void __init
+-lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
+-{
+-	unsigned long i;
+-
+-	rgn->region[r1].size += rgn->region[r2].size;
+-	for (i=r2; i < rgn->cnt-1; i++) {
+-		rgn->region[i].base = rgn->region[i+1].base;
+-		rgn->region[i].size = rgn->region[i+1].size;
+-	}
+-	rgn->cnt--;
+-}
+-
+-/* This routine called with relocation disabled. */
+-void __init
+-lmb_init(void)
+-{
+-	/* Create a dummy zero size LMB which will get coalesced away later.
+-	 * This simplifies the lmb_add() code below...
+-	 */
+-	lmb.memory.region[0].base = 0;
+-	lmb.memory.region[0].size = 0;
+-	lmb.memory.cnt = 1;
+-
+-	/* Ditto. */
+-	lmb.reserved.region[0].base = 0;
+-	lmb.reserved.region[0].size = 0;
+-	lmb.reserved.cnt = 1;
+-}
+-
+-/* This routine called with relocation disabled. */
+-void __init
+-lmb_analyze(void)
+-{
+-	int i;
+-
+-	lmb.memory.size = 0;
+-
+-	for (i = 0; i < lmb.memory.cnt; i++)
+-		lmb.memory.size += lmb.memory.region[i].size;
+-}
+-
+-/* This routine called with relocation disabled. */
+-static long __init
+-lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
+-{
+-	unsigned long i, coalesced = 0;
+-	long adjacent;
+-
+-	/* First try and coalesce this LMB with another. */
+-	for (i=0; i < rgn->cnt; i++) {
+-		unsigned long rgnbase = rgn->region[i].base;
+-		unsigned long rgnsize = rgn->region[i].size;
+-
+-		adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
+-		if ( adjacent > 0 ) {
+-			rgn->region[i].base -= size;
+-			rgn->region[i].size += size;
+-			coalesced++;
+-			break;
+-		}
+-		else if ( adjacent < 0 ) {
+-			rgn->region[i].size += size;
+-			coalesced++;
+-			break;
+-		}
+-	}
+-
+-	if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
+-		lmb_coalesce_regions(rgn, i, i+1);
+-		coalesced++;
+-	}
+-
+-	if ( coalesced ) {
+-		return coalesced;
+-	} else if ( rgn->cnt >= MAX_LMB_REGIONS ) {
+-		return -1;
+-	}
+-
+-	/* Couldn't coalesce the LMB, so add it to the sorted table. */
+-	for (i=rgn->cnt-1; i >= 0; i--) {
+-		if (base < rgn->region[i].base) {
+-			rgn->region[i+1].base = rgn->region[i].base;
+-			rgn->region[i+1].size = rgn->region[i].size;
+-		}  else {
+-			rgn->region[i+1].base = base;
+-			rgn->region[i+1].size = size;
+-			break;
+-		}
+-	}
+-	rgn->cnt++;
+-
+-	return 0;
+-}
+-
+-/* This routine called with relocation disabled. */
+-long __init
+-lmb_add(unsigned long base, unsigned long size)
+-{
+-	struct lmb_region *_rgn = &(lmb.memory);
+-
+-	/* On pSeries LPAR systems, the first LMB is our RMO region. */
+-	if ( base == 0 )
+-		lmb.rmo_size = size;
+-
+-	return lmb_add_region(_rgn, base, size);
+-
+-}
+-
+-long __init
+-lmb_reserve(unsigned long base, unsigned long size)
+-{
+-	struct lmb_region *_rgn = &(lmb.reserved);
+-
+-	return lmb_add_region(_rgn, base, size);
+-}
+-
+-long __init
+-lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
+-{
+-	unsigned long i;
+-
+-	for (i=0; i < rgn->cnt; i++) {
+-		unsigned long rgnbase = rgn->region[i].base;
+-		unsigned long rgnsize = rgn->region[i].size;
+-		if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
+-			break;
+-		}
+-	}
+-
+-	return (i < rgn->cnt) ? i : -1;
+-}
+-
+-unsigned long __init
+-lmb_alloc(unsigned long size, unsigned long align)
+-{
+-	return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
+-}
+-
+-unsigned long __init
+-lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
+-{
+-	long i, j;
+-	unsigned long base = 0;
+-
+-	for (i=lmb.memory.cnt-1; i >= 0; i--) {
+-		unsigned long lmbbase = lmb.memory.region[i].base;
+-		unsigned long lmbsize = lmb.memory.region[i].size;
+-
+-		if ( max_addr == LMB_ALLOC_ANYWHERE )
+-			base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
+-		else if ( lmbbase < max_addr )
+-			base = _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size, align);
+-		else
+-			continue;
+-
+-		while ( (lmbbase <= base) &&
+-			((j = lmb_overlaps_region(&lmb.reserved,base,size)) >= 0) ) {
+-			base = _ALIGN_DOWN(lmb.reserved.region[j].base-size, align);
+-		}
+-
+-		if ( (base != 0) && (lmbbase <= base) )
+-			break;
+-	}
+-
+-	if ( i < 0 )
+-		return 0;
+-
+-	lmb_add_region(&lmb.reserved, base, size);
+-
+-	return base;
+-}
+-
+-/* You must call lmb_analyze() before this. */
+-unsigned long __init
+-lmb_phys_mem_size(void)
+-{
+-	return lmb.memory.size;
+-}
+-
+-unsigned long __init
+-lmb_end_of_DRAM(void)
+-{
+-	int idx = lmb.memory.cnt - 1;
+-
+-	return (lmb.memory.region[idx].base + lmb.memory.region[idx].size);
+-}
+-
+-/*
+- * Truncate the lmb list to memory_limit if it's set
+- * You must call lmb_analyze() after this.
+- */
+-void __init lmb_enforce_memory_limit(void)
+-{
+-	extern unsigned long memory_limit;
+-	unsigned long i, limit;
+-
+-	if (! memory_limit)
+-		return;
+-
+-	limit = memory_limit;
+-	for (i = 0; i < lmb.memory.cnt; i++) {
+-		if (limit > lmb.memory.region[i].size) {
+-			limit -= lmb.memory.region[i].size;
+-			continue;
+-		}
+-
+-		lmb.memory.region[i].size = limit;
+-		lmb.memory.cnt = i + 1;
+-		break;
+-	}
+-}
+diff --git a/arch/ppc64/kernel/lparmap.c b/arch/ppc64/kernel/lparmap.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/lparmap.c
++++ /dev/null
+@@ -1,31 +0,0 @@
+-/*
+- * Copyright (C) 2005  Stephen Rothwell  IBM Corp.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-#include <asm/mmu.h>
+-#include <asm/page.h>
+-#include <asm/iSeries/LparMap.h>
+-
+-const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
+-	.xNumberEsids = HvEsidsToMap,
+-	.xNumberRanges = HvRangesToMap,
+-	.xSegmentTableOffs = STAB0_PAGE,
+-
+-	.xEsids = {
+-		{ .xKernelEsid = GET_ESID(KERNELBASE),
+-		  .xKernelVsid = KERNEL_VSID(KERNELBASE), },
+-		{ .xKernelEsid = GET_ESID(VMALLOCBASE),
+-		  .xKernelVsid = KERNEL_VSID(VMALLOCBASE), },
+-	},
+-
+-	.xRanges = {
+-		{ .xPages = HvPagesToMap,
+-		  .xOffset = 0,
+-		  .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT),
+-		},
+-	},
+-};
+diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/maple_pci.c
++++ /dev/null
+@@ -1,521 +0,0 @@
+-/*
+- * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org),
+- *		      IBM Corp.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-#define DEBUG
+-
+-#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/sections.h>
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/machdep.h>
+-#include <asm/iommu.h>
+-
+-#include "pci.h"
+-
+-#ifdef DEBUG
+-#define DBG(x...) printk(x)
+-#else
+-#define DBG(x...)
+-#endif
+-
+-static struct pci_controller *u3_agp, *u3_ht;
+-
+-static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
+-{
+-	for (; node != 0;node = node->sibling) {
+-		int * bus_range;
+-		unsigned int *class_code;
+-		int len;
+-
+-		/* For PCI<->PCI bridges or CardBus bridges, we go down */
+-		class_code = (unsigned int *) get_property(node, "class-code", NULL);
+-		if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+-			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+-			continue;
+-		bus_range = (int *) get_property(node, "bus-range", &len);
+-		if (bus_range != NULL && len > 2 * sizeof(int)) {
+-			if (bus_range[1] > higher)
+-				higher = bus_range[1];
+-		}
+-		higher = fixup_one_level_bus_range(node->child, higher);
+-	}
+-	return higher;
+-}
+-
+-/* This routine fixes the "bus-range" property of all bridges in the
+- * system since they tend to have their "last" member wrong on macs
+- *
+- * Note that the bus numbers manipulated here are OF bus numbers, they
+- * are not Linux bus numbers.
+- */
+-static void __init fixup_bus_range(struct device_node *bridge)
+-{
+-	int * bus_range;
+-	int len;
+-
+-	/* Lookup the "bus-range" property for the hose */
+-	bus_range = (int *) get_property(bridge, "bus-range", &len);
+-	if (bus_range == NULL || len < 2 * sizeof(int)) {
+-		printk(KERN_WARNING "Can't get bus-range for %s\n",
+-			       bridge->full_name);
+-		return;
+-	}
+-	bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
+-}
+-
+-
+-#define U3_AGP_CFA0(devfn, off)	\
+-	((1 << (unsigned long)PCI_SLOT(dev_fn)) \
+-	| (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
+-	| (((unsigned long)(off)) & 0xFCUL))
+-
+-#define U3_AGP_CFA1(bus, devfn, off)	\
+-	((((unsigned long)(bus)) << 16) \
+-	|(((unsigned long)(devfn)) << 8) \
+-	|(((unsigned long)(off)) & 0xFCUL) \
+-	|1UL)
+-
+-static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
+-				       u8 bus, u8 dev_fn, u8 offset)
+-{
+-	unsigned int caddr;
+-
+-	if (bus == hose->first_busno) {
+-		if (dev_fn < (11 << 3))
+-			return 0;
+-		caddr = U3_AGP_CFA0(dev_fn, offset);
+-	} else
+-		caddr = U3_AGP_CFA1(bus, dev_fn, offset);
+-
+-	/* Uninorth will return garbage if we don't read back the value ! */
+-	do {
+-		out_le32(hose->cfg_addr, caddr);
+-	} while (in_le32(hose->cfg_addr) != caddr);
+-
+-	offset &= 0x07;
+-	return ((unsigned long)hose->cfg_data) + offset;
+-}
+-
+-static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
+-			      int offset, int len, u32 *val)
+-{
+-	struct pci_controller *hose;
+-	unsigned long addr;
+-
+-	hose = pci_bus_to_host(bus);
+-	if (hose == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	addr = u3_agp_cfg_access(hose, bus->number, devfn, offset);
+-	if (!addr)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	switch (len) {
+-	case 1:
+-		*val = in_8((u8 *)addr);
+-		break;
+-	case 2:
+-		*val = in_le16((u16 *)addr);
+-		break;
+-	default:
+-		*val = in_le32((u32 *)addr);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
+-			       int offset, int len, u32 val)
+-{
+-	struct pci_controller *hose;
+-	unsigned long addr;
+-
+-	hose = pci_bus_to_host(bus);
+-	if (hose == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	addr = u3_agp_cfg_access(hose, bus->number, devfn, offset);
+-	if (!addr)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	switch (len) {
+-	case 1:
+-		out_8((u8 *)addr, val);
+-		(void) in_8((u8 *)addr);
+-		break;
+-	case 2:
+-		out_le16((u16 *)addr, val);
+-		(void) in_le16((u16 *)addr);
+-		break;
+-	default:
+-		out_le32((u32 *)addr, val);
+-		(void) in_le32((u32 *)addr);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static struct pci_ops u3_agp_pci_ops =
+-{
+-	u3_agp_read_config,
+-	u3_agp_write_config
+-};
+-
+-
+-#define U3_HT_CFA0(devfn, off)		\
+-		((((unsigned long)devfn) << 8) | offset)
+-#define U3_HT_CFA1(bus, devfn, off)	\
+-		(U3_HT_CFA0(devfn, off) \
+-		+ (((unsigned long)bus) << 16) \
+-		+ 0x01000000UL)
+-
+-static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+-				      u8 bus, u8 devfn, u8 offset)
+-{
+-	if (bus == hose->first_busno) {
+-		if (PCI_SLOT(devfn) == 0)
+-			return 0;
+-		return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
+-	} else
+-		return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
+-}
+-
+-static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
+-			     int offset, int len, u32 *val)
+-{
+-	struct pci_controller *hose;
+-	unsigned long addr;
+-
+-	hose = pci_bus_to_host(bus);
+-	if (hose == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+-	if (!addr)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	switch (len) {
+-	case 1:
+-		*val = in_8((u8 *)addr);
+-		break;
+-	case 2:
+-		*val = in_le16((u16 *)addr);
+-		break;
+-	default:
+-		*val = in_le32((u32 *)addr);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
+-			      int offset, int len, u32 val)
+-{
+-	struct pci_controller *hose;
+-	unsigned long addr;
+-
+-	hose = pci_bus_to_host(bus);
+-	if (hose == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+-	if (!addr)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	switch (len) {
+-	case 1:
+-		out_8((u8 *)addr, val);
+-		(void) in_8((u8 *)addr);
+-		break;
+-	case 2:
+-		out_le16((u16 *)addr, val);
+-		(void) in_le16((u16 *)addr);
+-		break;
+-	default:
+-		out_le32((u32 *)addr, val);
+-		(void) in_le32((u32 *)addr);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static struct pci_ops u3_ht_pci_ops =
+-{
+-	u3_ht_read_config,
+-	u3_ht_write_config
+-};
+-
+-static void __init setup_u3_agp(struct pci_controller* hose)
+-{
+-	/* On G5, we move AGP up to high bus number so we don't need
+-	 * to reassign bus numbers for HT. If we ever have P2P bridges
+-	 * on AGP, we'll have to move pci_assign_all_busses to the
+-	 * pci_controller structure so we enable it for AGP and not for
+-	 * HT childs.
+-	 * We hard code the address because of the different size of
+-	 * the reg address cell, we shall fix that by killing struct
+-	 * reg_property and using some accessor functions instead
+-	 */
+-	hose->first_busno = 0xf0;
+-	hose->last_busno = 0xff;
+-	hose->ops = &u3_agp_pci_ops;
+-	hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
+-	hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
+-
+-	u3_agp = hose;
+-}
+-
+-static void __init setup_u3_ht(struct pci_controller* hose)
+-{
+-	hose->ops = &u3_ht_pci_ops;
+-
+-	/* We hard code the address because of the different size of
+-	 * the reg address cell, we shall fix that by killing struct
+-	 * reg_property and using some accessor functions instead
+-	 */
+-	hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+-
+-	hose->first_busno = 0;
+-	hose->last_busno = 0xef;
+-
+-	u3_ht = hose;
+-}
+-
+-static int __init add_bridge(struct device_node *dev)
+-{
+-	int len;
+-	struct pci_controller *hose;
+-	char* disp_name;
+-	int *bus_range;
+-	int primary = 1;
+-	struct property *of_prop;
+-
+-	DBG("Adding PCI host bridge %s\n", dev->full_name);
+-
+-	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 = alloc_bootmem(sizeof(struct pci_controller));
+-	if (hose == NULL)
+-		return -ENOMEM;
+-	pci_setup_pci_controller(hose);
+-
+-	hose->arch_data = dev;
+-	hose->first_busno = bus_range ? bus_range[0] : 0;
+-	hose->last_busno = bus_range ? bus_range[1] : 0xff;
+-
+-	of_prop = alloc_bootmem(sizeof(struct property) +
+-				sizeof(hose->global_number));
+-	if (of_prop) {
+-		memset(of_prop, 0, sizeof(struct property));
+-		of_prop->name = "linux,pci-domain";
+-		of_prop->length = sizeof(hose->global_number);
+-		of_prop->value = (unsigned char *)&of_prop[1];
+-		memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
+-		prom_add_property(dev, of_prop);
+-	}
+-
+-	disp_name = NULL;
+-	if (device_is_compatible(dev, "u3-agp")) {
+-		setup_u3_agp(hose);
+-		disp_name = "U3-AGP";
+-		primary = 0;
+-	} else if (device_is_compatible(dev, "u3-ht")) {
+-		setup_u3_ht(hose);
+-		disp_name = "U3-HT";
+-		primary = 1;
+-	}
+-	printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
+-		disp_name, 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);
+-	pci_setup_phb_io(hose, primary);
+-
+-	/* Fixup "bus-range" OF property */
+-	fixup_bus_range(dev);
+-
+-	return 0;
+-}
+-
+-
+-void __init maple_pcibios_fixup(void)
+-{
+-	struct pci_dev *dev = NULL;
+-
+-	DBG(" -> maple_pcibios_fixup\n");
+-
+-	for_each_pci_dev(dev)
+-		pci_read_irq_line(dev);
+-
+-	/* Do the mapping of the IO space */
+-	phbs_remap_io();
+-
+-	DBG(" <- maple_pcibios_fixup\n");
+-}
+-
+-static void __init maple_fixup_phb_resources(void)
+-{
+-	struct pci_controller *hose, *tmp;
+-	
+-	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+-		unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
+-		hose->io_resource.start += offset;
+-		hose->io_resource.end += offset;
+-		printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
+-		       hose->global_number,
+-		       hose->io_resource.start, hose->io_resource.end);
+-	}
+-}
+-
+-void __init maple_pci_init(void)
+-{
+-	struct device_node *np, *root;
+-	struct device_node *ht = NULL;
+-
+-	/* Probe root PCI hosts, that is on U3 the AGP host and the
+-	 * HyperTransport host. That one is actually "kept" around
+-	 * and actually added last as it's resource management relies
+-	 * on the AGP resources to have been setup first
+-	 */
+-	root = of_find_node_by_path("/");
+-	if (root == NULL) {
+-		printk(KERN_CRIT "maple_find_bridges: can't find root of device tree\n");
+-		return;
+-	}
+-	for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
+-		if (np->name == NULL)
+-			continue;
+-		if (strcmp(np->name, "pci") == 0) {
+-			if (add_bridge(np) == 0)
+-				of_node_get(np);
+-		}
+-		if (strcmp(np->name, "ht") == 0) {
+-			of_node_get(np);
+-			ht = np;
+-		}
+-	}
+-	of_node_put(root);
+-
+-	/* Now setup the HyperTransport host if we found any
+-	 */
+-	if (ht && add_bridge(ht) != 0)
+-		of_node_put(ht);
+-
+-	/* Fixup the IO resources on our host bridges as the common code
+-	 * does it only for childs of the host bridges
+-	 */
+-	maple_fixup_phb_resources();
+-
+-	/* Setup the linkage between OF nodes and PHBs */ 
+-	pci_devs_phb_init();
+-
+-	/* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
+-	 * assume there is no P2P bridge on the AGP bus, which should be a
+-	 * safe assumptions hopefully.
+-	 */
+-	if (u3_agp) {
+-		struct device_node *np = u3_agp->arch_data;
+-		PCI_DN(np)->busno = 0xf0;
+-		for (np = np->child; np; np = np->sibling)
+-			PCI_DN(np)->busno = 0xf0;
+-	}
+-
+-	/* Tell pci.c to use the common resource allocation mecanism */
+-	pci_probe_only = 0;
+-	
+-	/* Allow all IO */
+-	io_page_mask = -1;
+-}
+-
+-int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel)
+-{
+-	struct device_node *np;
+-	int irq = channel ? 15 : 14;
+-
+-	if (pdev->vendor != PCI_VENDOR_ID_AMD ||
+-	    pdev->device != PCI_DEVICE_ID_AMD_8111_IDE)
+-		return irq;
+-
+-	np = pci_device_to_OF_node(pdev);
+-	if (np == NULL)
+-		return irq;
+-	if (np->n_intrs < 2)
+-		return irq;
+-	return np->intrs[channel & 0x1].line;
+-}
+-
+-/* XXX: To remove once all firmwares are ok */
+-static void fixup_maple_ide(struct pci_dev* dev)
+-{
+-#if 0 /* Enable this to enable IDE port 0 */
+-	{
+-		u8 v;
+-
+-		pci_read_config_byte(dev, 0x40, &v);
+-		v |= 2;
+-		pci_write_config_byte(dev, 0x40, v);
+-	}
+-#endif
+-#if 0 /* fix bus master base */
+-	pci_write_config_dword(dev, 0x20, 0xcc01);
+-	printk("old ide resource: %lx -> %lx \n",
+-	       dev->resource[4].start, dev->resource[4].end);
+-	dev->resource[4].start = 0xcc00;
+-	dev->resource[4].end = 0xcc10;
+-#endif
+-#if 1 /* Enable this to fixup IDE sense/polarity of irqs in IO-APICs */
+-	{
+-		struct pci_dev *apicdev;
+-		u32 v;
+-
+-		apicdev = pci_get_slot (dev->bus, PCI_DEVFN(5,0));
+-		if (apicdev == NULL)
+-			printk("IDE Fixup IRQ: Can't find IO-APIC !\n");
+-		else {
+-			pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*14);
+-			pci_read_config_dword(apicdev, 0xf4, &v);
+-			v &= ~0x00000022;
+-			pci_write_config_dword(apicdev, 0xf4, v);
+-			pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*15);
+-			pci_read_config_dword(apicdev, 0xf4, &v);
+-			v &= ~0x00000022;
+-			pci_write_config_dword(apicdev, 0xf4, v);
+-			pci_dev_put(apicdev);
+-		}
+-	}
+-#endif
+-}
+-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE,
+-			 fixup_maple_ide);
+diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/maple_setup.c
++++ /dev/null
+@@ -1,300 +0,0 @@
+-/*
+- *  arch/ppc64/kernel/maple_setup.c
+- *
+- *  (c) Copyright 2004 Benjamin Herrenschmidt (benh at kernel.crashing.org),
+- *                     IBM Corp. 
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the GNU General Public License
+- *  as published by the Free Software Foundation; either version
+- *  2 of the License, or (at your option) any later version.
+- *
+- */
+-
+-#define DEBUG
+-
+-#include <linux/config.h>
+-#include <linux/init.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/mm.h>
+-#include <linux/stddef.h>
+-#include <linux/unistd.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/user.h>
+-#include <linux/a.out.h>
+-#include <linux/tty.h>
+-#include <linux/string.h>
+-#include <linux/delay.h>
+-#include <linux/ioport.h>
+-#include <linux/major.h>
+-#include <linux/initrd.h>
+-#include <linux/vt_kern.h>
+-#include <linux/console.h>
+-#include <linux/ide.h>
+-#include <linux/pci.h>
+-#include <linux/adb.h>
+-#include <linux/cuda.h>
+-#include <linux/pmu.h>
+-#include <linux/irq.h>
+-#include <linux/seq_file.h>
+-#include <linux/root_dev.h>
+-#include <linux/serial.h>
+-#include <linux/smp.h>
+-
+-#include <asm/processor.h>
+-#include <asm/sections.h>
+-#include <asm/prom.h>
+-#include <asm/system.h>
+-#include <asm/pgtable.h>
+-#include <asm/bitops.h>
+-#include <asm/io.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/iommu.h>
+-#include <asm/machdep.h>
+-#include <asm/dma.h>
+-#include <asm/cputable.h>
+-#include <asm/time.h>
+-#include <asm/of_device.h>
+-#include <asm/lmb.h>
+-
+-#include "mpic.h"
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) udbg_printf(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-extern int maple_set_rtc_time(struct rtc_time *tm);
+-extern void maple_get_rtc_time(struct rtc_time *tm);
+-extern void maple_get_boot_time(struct rtc_time *tm);
+-extern void maple_calibrate_decr(void);
+-extern void maple_pci_init(void);
+-extern void maple_pcibios_fixup(void);
+-extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
+-extern void generic_find_legacy_serial_ports(u64 *physport,
+-		unsigned int *default_speed);
+-
+-static void maple_restart(char *cmd)
+-{
+-	unsigned int maple_nvram_base;
+-	unsigned int maple_nvram_offset;
+-	unsigned int maple_nvram_command;
+-	struct device_node *rtcs;
+-
+-	/* find NVRAM device */
+-	rtcs = find_compatible_devices("nvram", "AMD8111");
+-	if (rtcs && rtcs->addrs) {
+-		maple_nvram_base = rtcs->addrs[0].address;
+-	} else {
+-		printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
+-		printk(KERN_EMERG "Maple: Manual Restart Required\n");
+-		return;
+-	}
+-
+-	/* find service processor device */
+-	rtcs = find_devices("service-processor");
+-	if (!rtcs) {
+-		printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
+-		printk(KERN_EMERG "Maple: Manual Restart Required\n");
+-		return;
+-	}
+-	maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+-			"restart-addr", NULL);
+-	maple_nvram_command = *(unsigned int*) get_property(rtcs,
+-			"restart-value", NULL);
+-
+-	/* send command */
+-	outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
+-	for (;;) ;
+-}
+-
+-static void maple_power_off(void)
+-{
+-	unsigned int maple_nvram_base;
+-	unsigned int maple_nvram_offset;
+-	unsigned int maple_nvram_command;
+-	struct device_node *rtcs;
+-
+-	/* find NVRAM device */
+-	rtcs = find_compatible_devices("nvram", "AMD8111");
+-	if (rtcs && rtcs->addrs) {
+-		maple_nvram_base = rtcs->addrs[0].address;
+-	} else {
+-		printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
+-		printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
+-		return;
+-	}
+-
+-	/* find service processor device */
+-	rtcs = find_devices("service-processor");
+-	if (!rtcs) {
+-		printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
+-		printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
+-		return;
+-	}
+-	maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+-			"power-off-addr", NULL);
+-	maple_nvram_command = *(unsigned int*) get_property(rtcs,
+-			"power-off-value", NULL);
+-
+-	/* send command */
+-	outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
+-	for (;;) ;
+-}
+-
+-static void maple_halt(void)
+-{
+-	maple_power_off();
+-}
+-
+-#ifdef CONFIG_SMP
+-struct smp_ops_t maple_smp_ops = {
+-	.probe		= smp_mpic_probe,
+-	.message_pass	= smp_mpic_message_pass,
+-	.kick_cpu	= smp_generic_kick_cpu,
+-	.setup_cpu	= smp_mpic_setup_cpu,
+-	.give_timebase	= smp_generic_give_timebase,
+-	.take_timebase	= smp_generic_take_timebase,
+-};
+-#endif /* CONFIG_SMP */
+-
+-void __init maple_setup_arch(void)
+-{
+-	/* init to some ~sane value until calibrate_delay() runs */
+-	loops_per_jiffy = 50000000;
+-
+-	/* Setup SMP callback */
+-#ifdef CONFIG_SMP
+-	smp_ops = &maple_smp_ops;
+-#endif
+-	/* Lookup PCI hosts */
+-       	maple_pci_init();
+-
+-#ifdef CONFIG_DUMMY_CONSOLE
+-	conswitchp = &dummy_con;
+-#endif
+-
+-	printk(KERN_INFO "Using native/NAP idle loop\n");
+-}
+-
+-/* 
+- * Early initialization.
+- */
+-static void __init maple_init_early(void)
+-{
+-	unsigned int default_speed;
+-	u64 physport;
+-
+-	DBG(" -> maple_init_early\n");
+-
+-	/* Initialize hash table, from now on, we can take hash faults
+-	 * and call ioremap
+-	 */
+-	hpte_init_native();
+-
+-	/* Find the serial port */
+-	generic_find_legacy_serial_ports(&physport, &default_speed);
+-
+-	DBG("phys port addr: %lx\n", (long)physport);
+-
+-	if (physport) {
+-		void *comport;
+-		/* Map the uart for udbg. */
+-		comport = (void *)ioremap(physport, 16);
+-		udbg_init_uart(comport, default_speed);
+-
+-		DBG("Hello World !\n");
+-	}
+-
+-	/* Setup interrupt mapping options */
+-	ppc64_interrupt_controller = IC_OPEN_PIC;
+-
+-	iommu_init_early_u3();
+-
+-	DBG(" <- maple_init_early\n");
+-}
+-
+-
+-static __init void maple_init_IRQ(void)
+-{
+-	struct device_node *root;
+-	unsigned int *opprop;
+-	unsigned long opic_addr;
+-	struct mpic *mpic;
+-	unsigned char senses[128];
+-	int n;
+-
+-	DBG(" -> maple_init_IRQ\n");
+-
+-	/* XXX: Non standard, replace that with a proper openpic/mpic node
+-	 * in the device-tree. Find the Open PIC if present */
+-	root = of_find_node_by_path("/");
+-	opprop = (unsigned int *) get_property(root,
+-				"platform-open-pic", NULL);
+-	if (opprop == 0)
+-		panic("OpenPIC not found !\n");
+-
+-	n = prom_n_addr_cells(root);
+-	for (opic_addr = 0; n > 0; --n)
+-		opic_addr = (opic_addr << 32) + *opprop++;
+-	of_node_put(root);
+-
+-	/* Obtain sense values from device-tree */
+-	prom_get_irq_senses(senses, 0, 128);
+-
+-	mpic = mpic_alloc(opic_addr,
+-			  MPIC_PRIMARY | MPIC_BIG_ENDIAN |
+-			  MPIC_BROKEN_U3 | MPIC_WANTS_RESET,
+-			  0, 0, 128, 128, senses, 128, "U3-MPIC");
+-	BUG_ON(mpic == NULL);
+-	mpic_init(mpic);
+-
+-	DBG(" <- maple_init_IRQ\n");
+-}
+-
+-static void __init maple_progress(char *s, unsigned short hex)
+-{
+-	printk("*** %04x : %s\n", hex, s ? s : "");
+-}
+-
+-
+-/*
+- * Called very early, MMU is off, device-tree isn't unflattened
+- */
+-static int __init maple_probe(int platform)
+-{
+-	if (platform != PLATFORM_MAPLE)
+-		return 0;
+-	/*
+-	 * On U3, the DART (iommu) must be allocated now since it
+-	 * has an impact on htab_initialize (due to the large page it
+-	 * occupies having to be broken up so the DART itself is not
+-	 * part of the cacheable linar mapping
+-	 */
+-	alloc_u3_dart_table();
+-
+-	return 1;
+-}
+-
+-struct machdep_calls __initdata maple_md = {
+-	.probe			= maple_probe,
+-	.setup_arch		= maple_setup_arch,
+-	.init_early		= maple_init_early,
+-	.init_IRQ		= maple_init_IRQ,
+-	.get_irq		= mpic_get_irq,
+-	.pcibios_fixup		= maple_pcibios_fixup,
+-	.pci_get_legacy_ide_irq	= maple_pci_get_legacy_ide_irq,
+-	.restart		= maple_restart,
+-	.power_off		= maple_power_off,
+-	.halt			= maple_halt,
+-       	.get_boot_time		= maple_get_boot_time,
+-       	.set_rtc_time		= maple_set_rtc_time,
+-       	.get_rtc_time		= maple_get_rtc_time,
+-      	.calibrate_decr		= generic_calibrate_decr,
+-	.progress		= maple_progress,
+-	.idle_loop		= native_idle,
+-};
+diff --git a/arch/ppc64/kernel/maple_time.c b/arch/ppc64/kernel/maple_time.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/maple_time.c
++++ /dev/null
+@@ -1,175 +0,0 @@
+-/*
+- *  arch/ppc64/kernel/maple_time.c
+- *
+- *  (c) Copyright 2004 Benjamin Herrenschmidt (benh at kernel.crashing.org),
+- *                     IBM Corp. 
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the GNU General Public License
+- *  as published by the Free Software Foundation; either version
+- *  2 of the License, or (at your option) any later version.
+- *
+- */
+-
+-#undef DEBUG
+-
+-#include <linux/config.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/param.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
+-#include <linux/init.h>
+-#include <linux/time.h>
+-#include <linux/adb.h>
+-#include <linux/pmu.h>
+-#include <linux/interrupt.h>
+-#include <linux/mc146818rtc.h>
+-#include <linux/bcd.h>
+-
+-#include <asm/sections.h>
+-#include <asm/prom.h>
+-#include <asm/system.h>
+-#include <asm/io.h>
+-#include <asm/pgtable.h>
+-#include <asm/machdep.h>
+-#include <asm/time.h>
+-
+-#ifdef DEBUG
+-#define DBG(x...) printk(x)
+-#else
+-#define DBG(x...)
+-#endif
+-
+-extern void GregorianDay(struct rtc_time * tm);
+-
+-static int maple_rtc_addr;
+-
+-static int maple_clock_read(int addr)
+-{
+-	outb_p(addr, maple_rtc_addr);
+-	return inb_p(maple_rtc_addr+1);
+-}
+-
+-static void maple_clock_write(unsigned long val, int addr)
+-{
+-	outb_p(addr, maple_rtc_addr);
+-	outb_p(val, maple_rtc_addr+1);
+-}
+-
+-void maple_get_rtc_time(struct rtc_time *tm)
+-{
+-	int uip, i;
+-
+-	/* The Linux interpretation of the CMOS clock register contents:
+-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+-	 * RTC registers show the second which has precisely just started.
+-	 * Let's hope other operating systems interpret the RTC the same way.
+-	 */
+-
+-	/* Since the UIP flag is set for about 2.2 ms and the clock
+-	 * is typically written with a precision of 1 jiffy, trying
+-	 * to obtain a precision better than a few milliseconds is
+-	 * an illusion. Only consistency is interesting, this also
+-	 * allows to use the routine for /dev/rtc without a potential
+-	 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
+-	 */
+-
+-	for (i = 0; i<1000000; i++) {
+-		uip = maple_clock_read(RTC_FREQ_SELECT);
+-		tm->tm_sec = maple_clock_read(RTC_SECONDS);
+-		tm->tm_min = maple_clock_read(RTC_MINUTES);
+-		tm->tm_hour = maple_clock_read(RTC_HOURS);
+-		tm->tm_mday = maple_clock_read(RTC_DAY_OF_MONTH);
+-		tm->tm_mon = maple_clock_read(RTC_MONTH);
+-		tm->tm_year = maple_clock_read(RTC_YEAR);
+-		uip |= maple_clock_read(RTC_FREQ_SELECT);
+-		if ((uip & RTC_UIP)==0)
+-			break;
+-	}
+-
+-	if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY)
+-	    || RTC_ALWAYS_BCD) {
+-		BCD_TO_BIN(tm->tm_sec);
+-		BCD_TO_BIN(tm->tm_min);
+-		BCD_TO_BIN(tm->tm_hour);
+-		BCD_TO_BIN(tm->tm_mday);
+-		BCD_TO_BIN(tm->tm_mon);
+-		BCD_TO_BIN(tm->tm_year);
+-	  }
+-	if ((tm->tm_year + 1900) < 1970)
+-		tm->tm_year += 100;
+-
+-	GregorianDay(tm);
+-}
+-
+-int maple_set_rtc_time(struct rtc_time *tm)
+-{
+-	unsigned char save_control, save_freq_select;
+-	int sec, min, hour, mon, mday, year;
+-
+-	spin_lock(&rtc_lock);
+-
+-	save_control = maple_clock_read(RTC_CONTROL); /* tell the clock it's being set */
+-
+-	maple_clock_write((save_control|RTC_SET), RTC_CONTROL);
+-
+-	save_freq_select = maple_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
+-
+-	maple_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+-
+-	sec = tm->tm_sec;
+-	min = tm->tm_min;
+-	hour = tm->tm_hour;
+-	mon = tm->tm_mon;
+-	mday = tm->tm_mday;
+-	year = tm->tm_year;
+-
+-	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+-		BIN_TO_BCD(sec);
+-		BIN_TO_BCD(min);
+-		BIN_TO_BCD(hour);
+-		BIN_TO_BCD(mon);
+-		BIN_TO_BCD(mday);
+-		BIN_TO_BCD(year);
+-	}
+-	maple_clock_write(sec, RTC_SECONDS);
+-	maple_clock_write(min, RTC_MINUTES);
+-	maple_clock_write(hour, RTC_HOURS);
+-	maple_clock_write(mon, RTC_MONTH);
+-	maple_clock_write(mday, RTC_DAY_OF_MONTH);
+-	maple_clock_write(year, RTC_YEAR);
+-
+-	/* The following flags have to be released exactly in this order,
+-	 * otherwise the DS12887 (popular MC146818A clone with integrated
+-	 * battery and quartz) will not reset the oscillator and will not
+-	 * update precisely 500 ms later. You won't find this mentioned in
+-	 * the Dallas Semiconductor data sheets, but who believes data
+-	 * sheets anyway ...                           -- Markus Kuhn
+-	 */
+-	maple_clock_write(save_control, RTC_CONTROL);
+-	maple_clock_write(save_freq_select, RTC_FREQ_SELECT);
+-
+-	spin_unlock(&rtc_lock);
+-
+-	return 0;
+-}
+-
+-void __init maple_get_boot_time(struct rtc_time *tm)
+-{
+-	struct device_node *rtcs;
+-
+-	rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
+-	if (rtcs && rtcs->addrs) {
+-		maple_rtc_addr = rtcs->addrs[0].address;
+-		printk(KERN_INFO "Maple: Found RTC at 0x%x\n", maple_rtc_addr);
+-	} else {
+-		maple_rtc_addr = RTC_PORT(0); /* legacy address */
+-		printk(KERN_INFO "Maple: No device node for RTC, assuming "
+-		       "legacy address (0x%x)\n", maple_rtc_addr);
+-	}
+-	
+-	maple_get_rtc_time(tm);
+-}
+-
+diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/mf.c
++++ /dev/null
+@@ -1,1281 +0,0 @@
+-/*
+-  * mf.c
+-  * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
+-  * Copyright (C) 2004-2005 Stephen Rothwell  IBM Corporation
+-  *
+-  * This modules exists as an interface between a Linux secondary partition
+-  * running on an iSeries and the primary partition's Virtual Service
+-  * Processor (VSP) object.  The VSP has final authority over powering on/off
+-  * all partitions in the iSeries.  It also provides miscellaneous low-level
+-  * machine facility type operations.
+-  *
+-  *
+-  * This program is free software; you can redistribute it and/or modify
+-  * it under the terms of the 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/errno.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/completion.h>
+-#include <linux/delay.h>
+-#include <linux/dma-mapping.h>
+-#include <linux/bcd.h>
+-
+-#include <asm/time.h>
+-#include <asm/uaccess.h>
+-#include <asm/paca.h>
+-#include <asm/iSeries/vio.h>
+-#include <asm/iSeries/mf.h>
+-#include <asm/iSeries/HvLpConfig.h>
+-#include <asm/iSeries/ItLpQueue.h>
+-
+-/*
+- * This is the structure layout for the Machine Facilites LPAR event
+- * flows.
+- */
+-struct vsp_cmd_data {
+-	u64 token;
+-	u16 cmd;
+-	HvLpIndex lp_index;
+-	u8 result_code;
+-	u32 reserved;
+-	union {
+-		u64 state;	/* GetStateOut */
+-		u64 ipl_type;	/* GetIplTypeOut, Function02SelectIplTypeIn */
+-		u64 ipl_mode;	/* GetIplModeOut, Function02SelectIplModeIn */
+-		u64 page[4];	/* GetSrcHistoryIn */
+-		u64 flag;	/* GetAutoIplWhenPrimaryIplsOut,
+-				   SetAutoIplWhenPrimaryIplsIn,
+-				   WhiteButtonPowerOffIn,
+-				   Function08FastPowerOffIn,
+-				   IsSpcnRackPowerIncompleteOut */
+-		struct {
+-			u64 token;
+-			u64 address_type;
+-			u64 side;
+-			u32 length;
+-			u32 offset;
+-		} kern;		/* SetKernelImageIn, GetKernelImageIn,
+-				   SetKernelCmdLineIn, GetKernelCmdLineIn */
+-		u32 length_out;	/* GetKernelImageOut, GetKernelCmdLineOut */
+-		u8 reserved[80];
+-	} sub_data;
+-};
+-
+-struct vsp_rsp_data {
+-	struct completion com;
+-	struct vsp_cmd_data *response;
+-};
+-
+-struct alloc_data {
+-	u16 size;
+-	u16 type;
+-	u32 count;
+-	u16 reserved1;
+-	u8 reserved2;
+-	HvLpIndex target_lp;
+-};
+-
+-struct ce_msg_data;
+-
+-typedef void (*ce_msg_comp_hdlr)(void *token, struct ce_msg_data *vsp_cmd_rsp);
+-
+-struct ce_msg_comp_data {
+-	ce_msg_comp_hdlr handler;
+-	void *token;
+-};
+-
+-struct ce_msg_data {
+-	u8 ce_msg[12];
+-	char reserved[4];
+-	struct ce_msg_comp_data *completion;
+-};
+-
+-struct io_mf_lp_event {
+-	struct HvLpEvent hp_lp_event;
+-	u16 subtype_result_code;
+-	u16 reserved1;
+-	u32 reserved2;
+-	union {
+-		struct alloc_data alloc;
+-		struct ce_msg_data ce_msg;
+-		struct vsp_cmd_data vsp_cmd;
+-	} data;
+-};
+-
+-#define subtype_data(a, b, c, d)	\
+-		(((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
+-
+-/*
+- * All outgoing event traffic is kept on a FIFO queue.  The first
+- * pointer points to the one that is outstanding, and all new
+- * requests get stuck on the end.  Also, we keep a certain number of
+- * preallocated pending events so that we can operate very early in
+- * the boot up sequence (before kmalloc is ready).
+- */
+-struct pending_event {
+-	struct pending_event *next;
+-	struct io_mf_lp_event event;
+-	MFCompleteHandler hdlr;
+-	char dma_data[72];
+-	unsigned dma_data_length;
+-	unsigned remote_address;
+-};
+-static spinlock_t pending_event_spinlock;
+-static struct pending_event *pending_event_head;
+-static struct pending_event *pending_event_tail;
+-static struct pending_event *pending_event_avail;
+-static struct pending_event pending_event_prealloc[16];
+-
+-/*
+- * Put a pending event onto the available queue, so it can get reused.
+- * Attention! You must have the pending_event_spinlock before calling!
+- */
+-static void free_pending_event(struct pending_event *ev)
+-{
+-	if (ev != NULL) {
+-		ev->next = pending_event_avail;
+-		pending_event_avail = ev;
+-	}
+-}
+-
+-/*
+- * Enqueue the outbound event onto the stack.  If the queue was
+- * empty to begin with, we must also issue it via the Hypervisor
+- * interface.  There is a section of code below that will touch
+- * the first stack pointer without the protection of the pending_event_spinlock.
+- * This is OK, because we know that nobody else will be modifying
+- * the first pointer when we do this.
+- */
+-static int signal_event(struct pending_event *ev)
+-{
+-	int rc = 0;
+-	unsigned long flags;
+-	int go = 1;
+-	struct pending_event *ev1;
+-	HvLpEvent_Rc hv_rc;
+-
+-	/* enqueue the event */
+-	if (ev != NULL) {
+-		ev->next = NULL;
+-		spin_lock_irqsave(&pending_event_spinlock, flags);
+-		if (pending_event_head == NULL)
+-			pending_event_head = ev;
+-		else {
+-			go = 0;
+-			pending_event_tail->next = ev;
+-		}
+-		pending_event_tail = ev;
+-		spin_unlock_irqrestore(&pending_event_spinlock, flags);
+-	}
+-
+-	/* send the event */
+-	while (go) {
+-		go = 0;
+-
+-		/* any DMA data to send beforehand? */
+-		if (pending_event_head->dma_data_length > 0)
+-			HvCallEvent_dmaToSp(pending_event_head->dma_data,
+-					pending_event_head->remote_address,
+-					pending_event_head->dma_data_length,
+-					HvLpDma_Direction_LocalToRemote);
+-
+-		hv_rc = HvCallEvent_signalLpEvent(
+-				&pending_event_head->event.hp_lp_event);
+-		if (hv_rc != HvLpEvent_Rc_Good) {
+-			printk(KERN_ERR "mf.c: HvCallEvent_signalLpEvent() "
+-					"failed with %d\n", (int)hv_rc);
+-
+-			spin_lock_irqsave(&pending_event_spinlock, flags);
+-			ev1 = pending_event_head;
+-			pending_event_head = pending_event_head->next;
+-			if (pending_event_head != NULL)
+-				go = 1;
+-			spin_unlock_irqrestore(&pending_event_spinlock, flags);
+-
+-			if (ev1 == ev)
+-				rc = -EIO;
+-			else if (ev1->hdlr != NULL)
+-				(*ev1->hdlr)((void *)ev1->event.hp_lp_event.xCorrelationToken, -EIO);
+-
+-			spin_lock_irqsave(&pending_event_spinlock, flags);
+-			free_pending_event(ev1);
+-			spin_unlock_irqrestore(&pending_event_spinlock, flags);
+-		}
+-	}
+-
+-	return rc;
+-}
+-
+-/*
+- * Allocate a new pending_event structure, and initialize it.
+- */
+-static struct pending_event *new_pending_event(void)
+-{
+-	struct pending_event *ev = NULL;
+-	HvLpIndex primary_lp = HvLpConfig_getPrimaryLpIndex();
+-	unsigned long flags;
+-	struct HvLpEvent *hev;
+-
+-	spin_lock_irqsave(&pending_event_spinlock, flags);
+-	if (pending_event_avail != NULL) {
+-		ev = pending_event_avail;
+-		pending_event_avail = pending_event_avail->next;
+-	}
+-	spin_unlock_irqrestore(&pending_event_spinlock, flags);
+-	if (ev == NULL) {
+-		ev = kmalloc(sizeof(struct pending_event), GFP_ATOMIC);
+-		if (ev == NULL) {
+-			printk(KERN_ERR "mf.c: unable to kmalloc %ld bytes\n",
+-					sizeof(struct pending_event));
+-			return NULL;
+-		}
+-	}
+-	memset(ev, 0, sizeof(struct pending_event));
+-	hev = &ev->event.hp_lp_event;
+-	hev->xFlags.xValid = 1;
+-	hev->xFlags.xAckType = HvLpEvent_AckType_ImmediateAck;
+-	hev->xFlags.xAckInd = HvLpEvent_AckInd_DoAck;
+-	hev->xFlags.xFunction = HvLpEvent_Function_Int;
+-	hev->xType = HvLpEvent_Type_MachineFac;
+-	hev->xSourceLp = HvLpConfig_getLpIndex();
+-	hev->xTargetLp = primary_lp;
+-	hev->xSizeMinus1 = sizeof(ev->event) - 1;
+-	hev->xRc = HvLpEvent_Rc_Good;
+-	hev->xSourceInstanceId = HvCallEvent_getSourceLpInstanceId(primary_lp,
+-			HvLpEvent_Type_MachineFac);
+-	hev->xTargetInstanceId = HvCallEvent_getTargetLpInstanceId(primary_lp,
+-			HvLpEvent_Type_MachineFac);
+-
+-	return ev;
+-}
+-
+-static int signal_vsp_instruction(struct vsp_cmd_data *vsp_cmd)
+-{
+-	struct pending_event *ev = new_pending_event();
+-	int rc;
+-	struct vsp_rsp_data response;
+-
+-	if (ev == NULL)
+-		return -ENOMEM;
+-
+-	init_completion(&response.com);
+-	response.response = vsp_cmd;
+-	ev->event.hp_lp_event.xSubtype = 6;
+-	ev->event.hp_lp_event.x.xSubtypeData =
+-		subtype_data('M', 'F',  'V',  'I');
+-	ev->event.data.vsp_cmd.token = (u64)&response;
+-	ev->event.data.vsp_cmd.cmd = vsp_cmd->cmd;
+-	ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex();
+-	ev->event.data.vsp_cmd.result_code = 0xFF;
+-	ev->event.data.vsp_cmd.reserved = 0;
+-	memcpy(&(ev->event.data.vsp_cmd.sub_data),
+-			&(vsp_cmd->sub_data), sizeof(vsp_cmd->sub_data));
+-	mb();
+-
+-	rc = signal_event(ev);
+-	if (rc == 0)
+-		wait_for_completion(&response.com);
+-	return rc;
+-}
+-
+-
+-/*
+- * Send a 12-byte CE message to the primary partition VSP object
+- */
+-static int signal_ce_msg(char *ce_msg, struct ce_msg_comp_data *completion)
+-{
+-	struct pending_event *ev = new_pending_event();
+-
+-	if (ev == NULL)
+-		return -ENOMEM;
+-
+-	ev->event.hp_lp_event.xSubtype = 0;
+-	ev->event.hp_lp_event.x.xSubtypeData =
+-		subtype_data('M',  'F',  'C',  'E');
+-	memcpy(ev->event.data.ce_msg.ce_msg, ce_msg, 12);
+-	ev->event.data.ce_msg.completion = completion;
+-	return signal_event(ev);
+-}
+-
+-/*
+- * Send a 12-byte CE message (with no data) to the primary partition VSP object
+- */
+-static int signal_ce_msg_simple(u8 ce_op, struct ce_msg_comp_data *completion)
+-{
+-	u8 ce_msg[12];
+-
+-	memset(ce_msg, 0, sizeof(ce_msg));
+-	ce_msg[3] = ce_op;
+-	return signal_ce_msg(ce_msg, completion);
+-}
+-
+-/*
+- * Send a 12-byte CE message and DMA data to the primary partition VSP object
+- */
+-static int dma_and_signal_ce_msg(char *ce_msg,
+-		struct ce_msg_comp_data *completion, void *dma_data,
+-		unsigned dma_data_length, unsigned remote_address)
+-{
+-	struct pending_event *ev = new_pending_event();
+-
+-	if (ev == NULL)
+-		return -ENOMEM;
+-
+-	ev->event.hp_lp_event.xSubtype = 0;
+-	ev->event.hp_lp_event.x.xSubtypeData =
+-		subtype_data('M', 'F', 'C', 'E');
+-	memcpy(ev->event.data.ce_msg.ce_msg, ce_msg, 12);
+-	ev->event.data.ce_msg.completion = completion;
+-	memcpy(ev->dma_data, dma_data, dma_data_length);
+-	ev->dma_data_length = dma_data_length;
+-	ev->remote_address = remote_address;
+-	return signal_event(ev);
+-}
+-
+-/*
+- * Initiate a nice (hopefully) shutdown of Linux.  We simply are
+- * going to try and send the init process a SIGINT signal.  If
+- * this fails (why?), we'll simply force it off in a not-so-nice
+- * manner.
+- */
+-static int shutdown(void)
+-{
+-	int rc = kill_proc(1, SIGINT, 1);
+-
+-	if (rc) {
+-		printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), "
+-				"hard shutdown commencing\n", rc);
+-		mf_power_off();
+-	} else
+-		printk(KERN_INFO "mf.c: init has been successfully notified "
+-				"to proceed with shutdown\n");
+-	return rc;
+-}
+-
+-/*
+- * The primary partition VSP object is sending us a new
+- * event flow.  Handle it...
+- */
+-static void handle_int(struct io_mf_lp_event *event)
+-{
+-	struct ce_msg_data *ce_msg_data;
+-	struct ce_msg_data *pce_msg_data;
+-	unsigned long flags;
+-	struct pending_event *pev;
+-
+-	/* ack the interrupt */
+-	event->hp_lp_event.xRc = HvLpEvent_Rc_Good;
+-	HvCallEvent_ackLpEvent(&event->hp_lp_event);
+-
+-	/* process interrupt */
+-	switch (event->hp_lp_event.xSubtype) {
+-	case 0:	/* CE message */
+-		ce_msg_data = &event->data.ce_msg;
+-		switch (ce_msg_data->ce_msg[3]) {
+-		case 0x5B:	/* power control notification */
+-			if ((ce_msg_data->ce_msg[5] & 0x20) != 0) {
+-				printk(KERN_INFO "mf.c: Commencing partition shutdown\n");
+-				if (shutdown() == 0)
+-					signal_ce_msg_simple(0xDB, NULL);
+-			}
+-			break;
+-		case 0xC0:	/* get time */
+-			spin_lock_irqsave(&pending_event_spinlock, flags);
+-			pev = pending_event_head;
+-			if (pev != NULL)
+-				pending_event_head = pending_event_head->next;
+-			spin_unlock_irqrestore(&pending_event_spinlock, flags);
+-			if (pev == NULL)
+-				break;
+-			pce_msg_data = &pev->event.data.ce_msg;
+-			if (pce_msg_data->ce_msg[3] != 0x40)
+-				break;
+-			if (pce_msg_data->completion != NULL) {
+-				ce_msg_comp_hdlr handler =
+-					pce_msg_data->completion->handler;
+-				void *token = pce_msg_data->completion->token;
+-
+-				if (handler != NULL)
+-					(*handler)(token, ce_msg_data);
+-			}
+-			spin_lock_irqsave(&pending_event_spinlock, flags);
+-			free_pending_event(pev);
+-			spin_unlock_irqrestore(&pending_event_spinlock, flags);
+-			/* send next waiting event */
+-			if (pending_event_head != NULL)
+-				signal_event(NULL);
+-			break;
+-		}
+-		break;
+-	case 1:	/* IT sys shutdown */
+-		printk(KERN_INFO "mf.c: Commencing system shutdown\n");
+-		shutdown();
+-		break;
+-	}
+-}
+-
+-/*
+- * The primary partition VSP object is acknowledging the receipt
+- * of a flow we sent to them.  If there are other flows queued
+- * up, we must send another one now...
+- */
+-static void handle_ack(struct io_mf_lp_event *event)
+-{
+-	unsigned long flags;
+-	struct pending_event *two = NULL;
+-	unsigned long free_it = 0;
+-	struct ce_msg_data *ce_msg_data;
+-	struct ce_msg_data *pce_msg_data;
+-	struct vsp_rsp_data *rsp;
+-
+-	/* handle current event */
+-	if (pending_event_head == NULL) {
+-		printk(KERN_ERR "mf.c: stack empty for receiving ack\n");
+-		return;
+-	}
+-
+-	switch (event->hp_lp_event.xSubtype) {
+-	case 0:     /* CE msg */
+-		ce_msg_data = &event->data.ce_msg;
+-		if (ce_msg_data->ce_msg[3] != 0x40) {
+-			free_it = 1;
+-			break;
+-		}
+-		if (ce_msg_data->ce_msg[2] == 0)
+-			break;
+-		free_it = 1;
+-		pce_msg_data = &pending_event_head->event.data.ce_msg;
+-		if (pce_msg_data->completion != NULL) {
+-			ce_msg_comp_hdlr handler =
+-				pce_msg_data->completion->handler;
+-			void *token = pce_msg_data->completion->token;
+-
+-			if (handler != NULL)
+-				(*handler)(token, ce_msg_data);
+-		}
+-		break;
+-	case 4:	/* allocate */
+-	case 5:	/* deallocate */
+-		if (pending_event_head->hdlr != NULL)
+-			(*pending_event_head->hdlr)((void *)event->hp_lp_event.xCorrelationToken, event->data.alloc.count);
+-		free_it = 1;
+-		break;
+-	case 6:
+-		free_it = 1;
+-		rsp = (struct vsp_rsp_data *)event->data.vsp_cmd.token;
+-		if (rsp == NULL) {
+-			printk(KERN_ERR "mf.c: no rsp\n");
+-			break;
+-		}
+-		if (rsp->response != NULL)
+-			memcpy(rsp->response, &event->data.vsp_cmd,
+-					sizeof(event->data.vsp_cmd));
+-		complete(&rsp->com);
+-		break;
+-	}
+-
+-	/* remove from queue */
+-	spin_lock_irqsave(&pending_event_spinlock, flags);
+-	if ((pending_event_head != NULL) && (free_it == 1)) {
+-		struct pending_event *oldHead = pending_event_head;
+-
+-		pending_event_head = pending_event_head->next;
+-		two = pending_event_head;
+-		free_pending_event(oldHead);
+-	}
+-	spin_unlock_irqrestore(&pending_event_spinlock, flags);
+-
+-	/* send next waiting event */
+-	if (two != NULL)
+-		signal_event(NULL);
+-}
+-
+-/*
+- * This is the generic event handler we are registering with
+- * the Hypervisor.  Ensure the flows are for us, and then
+- * parse it enough to know if it is an interrupt or an
+- * acknowledge.
+- */
+-static void hv_handler(struct HvLpEvent *event, struct pt_regs *regs)
+-{
+-	if ((event != NULL) && (event->xType == HvLpEvent_Type_MachineFac)) {
+-		switch(event->xFlags.xFunction) {
+-		case HvLpEvent_Function_Ack:
+-			handle_ack((struct io_mf_lp_event *)event);
+-			break;
+-		case HvLpEvent_Function_Int:
+-			handle_int((struct io_mf_lp_event *)event);
+-			break;
+-		default:
+-			printk(KERN_ERR "mf.c: non ack/int event received\n");
+-			break;
+-		}
+-	} else
+-		printk(KERN_ERR "mf.c: alien event received\n");
+-}
+-
+-/*
+- * Global kernel interface to allocate and seed events into the
+- * Hypervisor.
+- */
+-void mf_allocate_lp_events(HvLpIndex target_lp, HvLpEvent_Type type,
+-		unsigned size, unsigned count, MFCompleteHandler hdlr,
+-		void *user_token)
+-{
+-	struct pending_event *ev = new_pending_event();
+-	int rc;
+-
+-	if (ev == NULL) {
+-		rc = -ENOMEM;
+-	} else {
+-		ev->event.hp_lp_event.xSubtype = 4;
+-		ev->event.hp_lp_event.xCorrelationToken = (u64)user_token;
+-		ev->event.hp_lp_event.x.xSubtypeData =
+-			subtype_data('M', 'F', 'M', 'A');
+-		ev->event.data.alloc.target_lp = target_lp;
+-		ev->event.data.alloc.type = type;
+-		ev->event.data.alloc.size = size;
+-		ev->event.data.alloc.count = count;
+-		ev->hdlr = hdlr;
+-		rc = signal_event(ev);
+-	}
+-	if ((rc != 0) && (hdlr != NULL))
+-		(*hdlr)(user_token, rc);
+-}
+-EXPORT_SYMBOL(mf_allocate_lp_events);
+-
+-/*
+- * Global kernel interface to unseed and deallocate events already in
+- * Hypervisor.
+- */
+-void mf_deallocate_lp_events(HvLpIndex target_lp, HvLpEvent_Type type,
+-		unsigned count, MFCompleteHandler hdlr, void *user_token)
+-{
+-	struct pending_event *ev = new_pending_event();
+-	int rc;
+-
+-	if (ev == NULL)
+-		rc = -ENOMEM;
+-	else {
+-		ev->event.hp_lp_event.xSubtype = 5;
+-		ev->event.hp_lp_event.xCorrelationToken = (u64)user_token;
+-		ev->event.hp_lp_event.x.xSubtypeData =
+-			subtype_data('M', 'F', 'M', 'D');
+-		ev->event.data.alloc.target_lp = target_lp;
+-		ev->event.data.alloc.type = type;
+-		ev->event.data.alloc.count = count;
+-		ev->hdlr = hdlr;
+-		rc = signal_event(ev);
+-	}
+-	if ((rc != 0) && (hdlr != NULL))
+-		(*hdlr)(user_token, rc);
+-}
+-EXPORT_SYMBOL(mf_deallocate_lp_events);
+-
+-/*
+- * Global kernel interface to tell the VSP object in the primary
+- * partition to power this partition off.
+- */
+-void mf_power_off(void)
+-{
+-	printk(KERN_INFO "mf.c: Down it goes...\n");
+-	signal_ce_msg_simple(0x4d, NULL);
+-	for (;;)
+-		;
+-}
+-
+-/*
+- * Global kernel interface to tell the VSP object in the primary
+- * partition to reboot this partition.
+- */
+-void mf_reboot(void)
+-{
+-	printk(KERN_INFO "mf.c: Preparing to bounce...\n");
+-	signal_ce_msg_simple(0x4e, NULL);
+-	for (;;)
+-		;
+-}
+-
+-/*
+- * Display a single word SRC onto the VSP control panel.
+- */
+-void mf_display_src(u32 word)
+-{
+-	u8 ce[12];
+-
+-	memset(ce, 0, sizeof(ce));
+-	ce[3] = 0x4a;
+-	ce[7] = 0x01;
+-	ce[8] = word >> 24;
+-	ce[9] = word >> 16;
+-	ce[10] = word >> 8;
+-	ce[11] = word;
+-	signal_ce_msg(ce, NULL);
+-}
+-
+-/*
+- * Display a single word SRC of the form "PROGXXXX" on the VSP control panel.
+- */
+-void mf_display_progress(u16 value)
+-{
+-	u8 ce[12];
+-	u8 src[72];
+-
+-	memcpy(ce, "\x00\x00\x04\x4A\x00\x00\x00\x48\x00\x00\x00\x00", 12);
+-	memcpy(src, "\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
+-		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+-		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+-		"\x00\x00\x00\x00PROGxxxx                        ",
+-		72);
+-	src[6] = value >> 8;
+-	src[7] = value & 255;
+-	src[44] = "0123456789ABCDEF"[(value >> 12) & 15];
+-	src[45] = "0123456789ABCDEF"[(value >> 8) & 15];
+-	src[46] = "0123456789ABCDEF"[(value >> 4) & 15];
+-	src[47] = "0123456789ABCDEF"[value & 15];
+-	dma_and_signal_ce_msg(ce, NULL, src, sizeof(src), 9 * 64 * 1024);
+-}
+-
+-/*
+- * Clear the VSP control panel.  Used to "erase" an SRC that was
+- * previously displayed.
+- */
+-void mf_clear_src(void)
+-{
+-	signal_ce_msg_simple(0x4b, NULL);
+-}
+-
+-/*
+- * Initialization code here.
+- */
+-void mf_init(void)
+-{
+-	int i;
+-
+-	/* initialize */
+-	spin_lock_init(&pending_event_spinlock);
+-	for (i = 0;
+-	     i < sizeof(pending_event_prealloc) / sizeof(*pending_event_prealloc);
+-	     ++i)
+-		free_pending_event(&pending_event_prealloc[i]);
+-	HvLpEvent_registerHandler(HvLpEvent_Type_MachineFac, &hv_handler);
+-
+-	/* virtual continue ack */
+-	signal_ce_msg_simple(0x57, NULL);
+-
+-	/* initialization complete */
+-	printk(KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities "
+-			"initialized\n");
+-}
+-
+-struct rtc_time_data {
+-	struct completion com;
+-	struct ce_msg_data ce_msg;
+-	int rc;
+-};
+-
+-static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
+-{
+-	struct rtc_time_data *rtc = token;
+-
+-	memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
+-	rtc->rc = 0;
+-	complete(&rtc->com);
+-}
+-
+-static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
+-{
+-	tm->tm_wday = 0;
+-	tm->tm_yday = 0;
+-	tm->tm_isdst = 0;
+-	if (rc) {
+-		tm->tm_sec = 0;
+-		tm->tm_min = 0;
+-		tm->tm_hour = 0;
+-		tm->tm_mday = 15;
+-		tm->tm_mon = 5;
+-		tm->tm_year = 52;
+-		return rc;
+-	}
+-
+-	if ((ce_msg[2] == 0xa9) ||
+-	    (ce_msg[2] == 0xaf)) {
+-		/* TOD clock is not set */
+-		tm->tm_sec = 1;
+-		tm->tm_min = 1;
+-		tm->tm_hour = 1;
+-		tm->tm_mday = 10;
+-		tm->tm_mon = 8;
+-		tm->tm_year = 71;
+-		mf_set_rtc(tm);
+-	}
+-	{
+-		u8 year = ce_msg[5];
+-		u8 sec = ce_msg[6];
+-		u8 min = ce_msg[7];
+-		u8 hour = ce_msg[8];
+-		u8 day = ce_msg[10];
+-		u8 mon = ce_msg[11];
+-
+-		BCD_TO_BIN(sec);
+-		BCD_TO_BIN(min);
+-		BCD_TO_BIN(hour);
+-		BCD_TO_BIN(day);
+-		BCD_TO_BIN(mon);
+-		BCD_TO_BIN(year);
+-
+-		if (year <= 69)
+-			year += 100;
+-
+-		tm->tm_sec = sec;
+-		tm->tm_min = min;
+-		tm->tm_hour = hour;
+-		tm->tm_mday = day;
+-		tm->tm_mon = mon;
+-		tm->tm_year = year;
+-	}
+-
+-	return 0;
+-}
+-
+-int mf_get_rtc(struct rtc_time *tm)
+-{
+-	struct ce_msg_comp_data ce_complete;
+-	struct rtc_time_data rtc_data;
+-	int rc;
+-
+-	memset(&ce_complete, 0, sizeof(ce_complete));
+-	memset(&rtc_data, 0, sizeof(rtc_data));
+-	init_completion(&rtc_data.com);
+-	ce_complete.handler = &get_rtc_time_complete;
+-	ce_complete.token = &rtc_data;
+-	rc = signal_ce_msg_simple(0x40, &ce_complete);
+-	if (rc)
+-		return rc;
+-	wait_for_completion(&rtc_data.com);
+-	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+-}
+-
+-struct boot_rtc_time_data {
+-	int busy;
+-	struct ce_msg_data ce_msg;
+-	int rc;
+-};
+-
+-static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
+-{
+-	struct boot_rtc_time_data *rtc = token;
+-
+-	memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
+-	rtc->rc = 0;
+-	rtc->busy = 0;
+-}
+-
+-int mf_get_boot_rtc(struct rtc_time *tm)
+-{
+-	struct ce_msg_comp_data ce_complete;
+-	struct boot_rtc_time_data rtc_data;
+-	int rc;
+-
+-	memset(&ce_complete, 0, sizeof(ce_complete));
+-	memset(&rtc_data, 0, sizeof(rtc_data));
+-	rtc_data.busy = 1;
+-	ce_complete.handler = &get_boot_rtc_time_complete;
+-	ce_complete.token = &rtc_data;
+-	rc = signal_ce_msg_simple(0x40, &ce_complete);
+-	if (rc)
+-		return rc;
+-	/* We need to poll here as we are not yet taking interrupts */
+-	while (rtc_data.busy) {
+-		if (hvlpevent_is_pending())
+-			process_hvlpevents(NULL);
+-	}
+-	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+-}
+-
+-int mf_set_rtc(struct rtc_time *tm)
+-{
+-	char ce_time[12];
+-	u8 day, mon, hour, min, sec, y1, y2;
+-	unsigned year;
+-
+-	year = 1900 + tm->tm_year;
+-	y1 = year / 100;
+-	y2 = year % 100;
+-
+-	sec = tm->tm_sec;
+-	min = tm->tm_min;
+-	hour = tm->tm_hour;
+-	day = tm->tm_mday;
+-	mon = tm->tm_mon + 1;
+-
+-	BIN_TO_BCD(sec);
+-	BIN_TO_BCD(min);
+-	BIN_TO_BCD(hour);
+-	BIN_TO_BCD(mon);
+-	BIN_TO_BCD(day);
+-	BIN_TO_BCD(y1);
+-	BIN_TO_BCD(y2);
+-
+-	memset(ce_time, 0, sizeof(ce_time));
+-	ce_time[3] = 0x41;
+-	ce_time[4] = y1;
+-	ce_time[5] = y2;
+-	ce_time[6] = sec;
+-	ce_time[7] = min;
+-	ce_time[8] = hour;
+-	ce_time[10] = day;
+-	ce_time[11] = mon;
+-
+-	return signal_ce_msg(ce_time, NULL);
+-}
+-
+-#ifdef CONFIG_PROC_FS
+-
+-static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
+-		int count, int *eof, void *data)
+-{
+-	int len;
+-	char *p;
+-	struct vsp_cmd_data vsp_cmd;
+-	int rc;
+-	dma_addr_t dma_addr;
+-
+-	/* The HV appears to return no more than 256 bytes of command line */
+-	if (off >= 256)
+-		return 0;
+-	if ((off + count) > 256)
+-		count = 256 - off;
+-
+-	dma_addr = dma_map_single(iSeries_vio_dev, page, off + count,
+-			DMA_FROM_DEVICE);
+-	if (dma_mapping_error(dma_addr))
+-		return -ENOMEM;
+-	memset(page, 0, off + count);
+-	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
+-	vsp_cmd.cmd = 33;
+-	vsp_cmd.sub_data.kern.token = dma_addr;
+-	vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
+-	vsp_cmd.sub_data.kern.side = (u64)data;
+-	vsp_cmd.sub_data.kern.length = off + count;
+-	mb();
+-	rc = signal_vsp_instruction(&vsp_cmd);
+-	dma_unmap_single(iSeries_vio_dev, dma_addr, off + count,
+-			DMA_FROM_DEVICE);
+-	if (rc)
+-		return rc;
+-	if (vsp_cmd.result_code != 0)
+-		return -ENOMEM;
+-	p = page;
+-	len = 0;
+-	while (len < (off + count)) {
+-		if ((*p == '\0') || (*p == '\n')) {
+-			if (*p == '\0')
+-				*p = '\n';
+-			p++;
+-			len++;
+-			*eof = 1;
+-			break;
+-		}
+-		p++;
+-		len++;
+-	}
+-
+-	if (len < off) {
+-		*eof = 1;
+-		len = 0;
+-	}
+-	return len;
+-}
+-
+-#if 0
+-static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side)
+-{
+-	struct vsp_cmd_data vsp_cmd;
+-	int rc;
+-	int len = *size;
+-	dma_addr_t dma_addr;
+-
+-	dma_addr = dma_map_single(iSeries_vio_dev, buffer, len,
+-			DMA_FROM_DEVICE);
+-	memset(buffer, 0, len);
+-	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
+-	vsp_cmd.cmd = 32;
+-	vsp_cmd.sub_data.kern.token = dma_addr;
+-	vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
+-	vsp_cmd.sub_data.kern.side = side;
+-	vsp_cmd.sub_data.kern.offset = offset;
+-	vsp_cmd.sub_data.kern.length = len;
+-	mb();
+-	rc = signal_vsp_instruction(&vsp_cmd);
+-	if (rc == 0) {
+-		if (vsp_cmd.result_code == 0)
+-			*size = vsp_cmd.sub_data.length_out;
+-		else
+-			rc = -ENOMEM;
+-	}
+-
+-	dma_unmap_single(iSeries_vio_dev, dma_addr, len, DMA_FROM_DEVICE);
+-
+-	return rc;
+-}
+-
+-static int proc_mf_dump_vmlinux(char *page, char **start, off_t off,
+-		int count, int *eof, void *data)
+-{
+-	int sizeToGet = count;
+-
+-	if (!capable(CAP_SYS_ADMIN))
+-		return -EACCES;
+-
+-	if (mf_getVmlinuxChunk(page, &sizeToGet, off, (u64)data) == 0) {
+-		if (sizeToGet != 0) {
+-			*start = page + off;
+-			return sizeToGet;
+-		}
+-		*eof = 1;
+-		return 0;
+-	}
+-	*eof = 1;
+-	return 0;
+-}
+-#endif
+-
+-static int proc_mf_dump_side(char *page, char **start, off_t off,
+-		int count, int *eof, void *data)
+-{
+-	int len;
+-	char mf_current_side = ' ';
+-	struct vsp_cmd_data vsp_cmd;
+-
+-	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
+-	vsp_cmd.cmd = 2;
+-	vsp_cmd.sub_data.ipl_type = 0;
+-	mb();
+-
+-	if (signal_vsp_instruction(&vsp_cmd) == 0) {
+-		if (vsp_cmd.result_code == 0) {
+-			switch (vsp_cmd.sub_data.ipl_type) {
+-			case 0:	mf_current_side = 'A';
+-				break;
+-			case 1:	mf_current_side = 'B';
+-				break;
+-			case 2:	mf_current_side = 'C';
+-				break;
+-			default:	mf_current_side = 'D';
+-				break;
+-			}
+-		}
+-	}
+-
+-	len = sprintf(page, "%c\n", mf_current_side);
+-
+-	if (len <= (off + count))
+-		*eof = 1;
+-	*start = page + off;
+-	len -= off;
+-	if (len > count)
+-		len = count;
+-	if (len < 0)
+-		len = 0;
+-	return len;
+-}
+-
+-static int proc_mf_change_side(struct file *file, const char __user *buffer,
+-		unsigned long count, void *data)
+-{
+-	char side;
+-	u64 newSide;
+-	struct vsp_cmd_data vsp_cmd;
+-
+-	if (!capable(CAP_SYS_ADMIN))
+-		return -EACCES;
+-
+-	if (count == 0)
+-		return 0;
+-
+-	if (get_user(side, buffer))
+-		return -EFAULT;
+-
+-	switch (side) {
+-	case 'A':	newSide = 0;
+-			break;
+-	case 'B':	newSide = 1;
+-			break;
+-	case 'C':	newSide = 2;
+-			break;
+-	case 'D':	newSide = 3;
+-			break;
+-	default:
+-		printk(KERN_ERR "mf_proc.c: proc_mf_change_side: invalid side\n");
+-		return -EINVAL;
+-	}
+-
+-	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
+-	vsp_cmd.sub_data.ipl_type = newSide;
+-	vsp_cmd.cmd = 10;
+-
+-	(void)signal_vsp_instruction(&vsp_cmd);
+-
+-	return count;
+-}
+-
+-#if 0
+-static void mf_getSrcHistory(char *buffer, int size)
+-{
+-	struct IplTypeReturnStuff return_stuff;
+-	struct pending_event *ev = new_pending_event();
+-	int rc = 0;
+-	char *pages[4];
+-
+-	pages[0] = kmalloc(4096, GFP_ATOMIC);
+-	pages[1] = kmalloc(4096, GFP_ATOMIC);
+-	pages[2] = kmalloc(4096, GFP_ATOMIC);
+-	pages[3] = kmalloc(4096, GFP_ATOMIC);
+-	if ((ev == NULL) || (pages[0] == NULL) || (pages[1] == NULL)
+-			 || (pages[2] == NULL) || (pages[3] == NULL))
+-		return -ENOMEM;
+-
+-	return_stuff.xType = 0;
+-	return_stuff.xRc = 0;
+-	return_stuff.xDone = 0;
+-	ev->event.hp_lp_event.xSubtype = 6;
+-	ev->event.hp_lp_event.x.xSubtypeData =
+-		subtype_data('M', 'F', 'V', 'I');
+-	ev->event.data.vsp_cmd.xEvent = &return_stuff;
+-	ev->event.data.vsp_cmd.cmd = 4;
+-	ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex();
+-	ev->event.data.vsp_cmd.result_code = 0xFF;
+-	ev->event.data.vsp_cmd.reserved = 0;
+-	ev->event.data.vsp_cmd.sub_data.page[0] = ISERIES_HV_ADDR(pages[0]);
+-	ev->event.data.vsp_cmd.sub_data.page[1] = ISERIES_HV_ADDR(pages[1]);
+-	ev->event.data.vsp_cmd.sub_data.page[2] = ISERIES_HV_ADDR(pages[2]);
+-	ev->event.data.vsp_cmd.sub_data.page[3] = ISERIES_HV_ADDR(pages[3]);
+-	mb();
+-	if (signal_event(ev) != 0)
+-		return;
+-
+- 	while (return_stuff.xDone != 1)
+- 		udelay(10);
+- 	if (return_stuff.xRc == 0)
+- 		memcpy(buffer, pages[0], size);
+-	kfree(pages[0]);
+-	kfree(pages[1]);
+-	kfree(pages[2]);
+-	kfree(pages[3]);
+-}
+-#endif
+-
+-static int proc_mf_dump_src(char *page, char **start, off_t off,
+-		int count, int *eof, void *data)
+-{
+-#if 0
+-	int len;
+-
+-	mf_getSrcHistory(page, count);
+-	len = count;
+-	len -= off;
+-	if (len < count) {
+-		*eof = 1;
+-		if (len <= 0)
+-			return 0;
+-	} else
+-		len = count;
+-	*start = page + off;
+-	return len;
+-#else
+-	return 0;
+-#endif
+-}
+-
+-static int proc_mf_change_src(struct file *file, const char __user *buffer,
+-		unsigned long count, void *data)
+-{
+-	char stkbuf[10];
+-
+-	if (!capable(CAP_SYS_ADMIN))
+-		return -EACCES;
+-
+-	if ((count < 4) && (count != 1)) {
+-		printk(KERN_ERR "mf_proc: invalid src\n");
+-		return -EINVAL;
+-	}
+-
+-	if (count > (sizeof(stkbuf) - 1))
+-		count = sizeof(stkbuf) - 1;
+-	if (copy_from_user(stkbuf, buffer, count))
+-		return -EFAULT;
+-
+-	if ((count == 1) && (*stkbuf == '\0'))
+-		mf_clear_src();
+-	else
+-		mf_display_src(*(u32 *)stkbuf);
+-
+-	return count;
+-}
+-
+-static int proc_mf_change_cmdline(struct file *file, const char __user *buffer,
+-		unsigned long count, void *data)
+-{
+-	struct vsp_cmd_data vsp_cmd;
+-	dma_addr_t dma_addr;
+-	char *page;
+-	int ret = -EACCES;
+-
+-	if (!capable(CAP_SYS_ADMIN))
+-		goto out;
+-
+-	dma_addr = 0;
+-	page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr,
+-			GFP_ATOMIC);
+-	ret = -ENOMEM;
+-	if (page == NULL)
+-		goto out;
+-
+-	ret = -EFAULT;
+-	if (copy_from_user(page, buffer, count))
+-		goto out_free;
+-
+-	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
+-	vsp_cmd.cmd = 31;
+-	vsp_cmd.sub_data.kern.token = dma_addr;
+-	vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
+-	vsp_cmd.sub_data.kern.side = (u64)data;
+-	vsp_cmd.sub_data.kern.length = count;
+-	mb();
+-	(void)signal_vsp_instruction(&vsp_cmd);
+-	ret = count;
+-
+-out_free:
+-	dma_free_coherent(iSeries_vio_dev, count, page, dma_addr);
+-out:
+-	return ret;
+-}
+-
+-static ssize_t proc_mf_change_vmlinux(struct file *file,
+-				      const char __user *buf,
+-				      size_t count, loff_t *ppos)
+-{
+-	struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
+-	ssize_t rc;
+-	dma_addr_t dma_addr;
+-	char *page;
+-	struct vsp_cmd_data vsp_cmd;
+-
+-	rc = -EACCES;
+-	if (!capable(CAP_SYS_ADMIN))
+-		goto out;
+-
+-	dma_addr = 0;
+-	page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr,
+-			GFP_ATOMIC);
+-	rc = -ENOMEM;
+-	if (page == NULL) {
+-		printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n");
+-		goto out;
+-	}
+-	rc = -EFAULT;
+-	if (copy_from_user(page, buf, count))
+-		goto out_free;
+-
+-	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
+-	vsp_cmd.cmd = 30;
+-	vsp_cmd.sub_data.kern.token = dma_addr;
+-	vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
+-	vsp_cmd.sub_data.kern.side = (u64)dp->data;
+-	vsp_cmd.sub_data.kern.offset = *ppos;
+-	vsp_cmd.sub_data.kern.length = count;
+-	mb();
+-	rc = signal_vsp_instruction(&vsp_cmd);
+-	if (rc)
+-		goto out_free;
+-	rc = -ENOMEM;
+-	if (vsp_cmd.result_code != 0)
+-		goto out_free;
+-
+-	*ppos += count;
+-	rc = count;
+-out_free:
+-	dma_free_coherent(iSeries_vio_dev, count, page, dma_addr);
+-out:
+-	return rc;
+-}
+-
+-static struct file_operations proc_vmlinux_operations = {
+-	.write		= proc_mf_change_vmlinux,
+-};
+-
+-static int __init mf_proc_init(void)
+-{
+-	struct proc_dir_entry *mf_proc_root;
+-	struct proc_dir_entry *ent;
+-	struct proc_dir_entry *mf;
+-	char name[2];
+-	int i;
+-
+-	mf_proc_root = proc_mkdir("iSeries/mf", NULL);
+-	if (!mf_proc_root)
+-		return 1;
+-
+-	name[1] = '\0';
+-	for (i = 0; i < 4; i++) {
+-		name[0] = 'A' + i;
+-		mf = proc_mkdir(name, mf_proc_root);
+-		if (!mf)
+-			return 1;
+-
+-		ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf);
+-		if (!ent)
+-			return 1;
+-		ent->nlink = 1;
+-		ent->data = (void *)(long)i;
+-		ent->read_proc = proc_mf_dump_cmdline;
+-		ent->write_proc = proc_mf_change_cmdline;
+-
+-		if (i == 3)	/* no vmlinux entry for 'D' */
+-			continue;
+-
+-		ent = create_proc_entry("vmlinux", S_IFREG|S_IWUSR, mf);
+-		if (!ent)
+-			return 1;
+-		ent->nlink = 1;
+-		ent->data = (void *)(long)i;
+-		ent->proc_fops = &proc_vmlinux_operations;
+-	}
+-
+-	ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
+-	if (!ent)
+-		return 1;
+-	ent->nlink = 1;
+-	ent->data = (void *)0;
+-	ent->read_proc = proc_mf_dump_side;
+-	ent->write_proc = proc_mf_change_side;
+-
+-	ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
+-	if (!ent)
+-		return 1;
+-	ent->nlink = 1;
+-	ent->data = (void *)0;
+-	ent->read_proc = proc_mf_dump_src;
+-	ent->write_proc = proc_mf_change_src;
+-
+-	return 0;
+-}
+-
+-__initcall(mf_proc_init);
+-
+-#endif /* CONFIG_PROC_FS */
+diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
+--- a/arch/ppc64/kernel/misc.S
++++ b/arch/ppc64/kernel/misc.S
+@@ -28,6 +28,7 @@
+ #include <asm/ppc_asm.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/cputable.h>
++#include <asm/thread_info.h>
+ 
+ 	.text
+ 
+@@ -64,44 +65,6 @@ _GLOBAL(get_srr1)
+ _GLOBAL(get_sp)
+ 	mr	r3,r1
+ 	blr
+-		
+-#ifdef CONFIG_PPC_ISERIES
+-/* unsigned long local_save_flags(void) */
+-_GLOBAL(local_get_flags)
+-	lbz	r3,PACAPROCENABLED(r13)
+-	blr
+-
+-/* unsigned long local_irq_disable(void) */
+-_GLOBAL(local_irq_disable)
+-	lbz	r3,PACAPROCENABLED(r13)
+-	li	r4,0
+-	stb	r4,PACAPROCENABLED(r13)
+-	blr			/* Done */
+-
+-/* void local_irq_restore(unsigned long flags) */	
+-_GLOBAL(local_irq_restore)
+-	lbz	r5,PACAPROCENABLED(r13)
+-	 /* Check if things are setup the way we want _already_. */
+-	cmpw	0,r3,r5
+-	beqlr
+-	/* are we enabling interrupts? */
+-	cmpdi	0,r3,0
+-	stb	r3,PACAPROCENABLED(r13)
+-	beqlr
+-	/* Check pending interrupts */
+-	/*   A decrementer, IPI or PMC interrupt may have occurred
+-	 *   while we were in the hypervisor (which enables) */
+-	ld	r4,PACALPPACA+LPPACAANYINT(r13)
+-	cmpdi	r4,0
+-	beqlr
+-
+-	/*
+-	 * Handle pending interrupts in interrupt context
+-	 */
+-	li	r0,0x5555
+-	sc
+-	blr
+-#endif /* CONFIG_PPC_ISERIES */
+ 
+ #ifdef CONFIG_IRQSTACKS
+ _GLOBAL(call_do_softirq)
+@@ -329,7 +292,7 @@ _GLOBAL(__flush_dcache_icache)
+ 
+ /* Flush the dcache */
+  	ld	r7,PPC64_CACHES at toc(r2)
+-	clrrdi	r3,r3,12           	    /* Page align */
++	clrrdi	r3,r3,PAGE_SHIFT           	    /* Page align */
+ 	lwz	r4,DCACHEL1LINESPERPAGE(r7)	/* Get # dcache lines per page */
+ 	lwz	r5,DCACHEL1LINESIZE(r7)		/* Get dcache line size */
+ 	mr	r6,r3
+@@ -488,25 +451,6 @@ _GLOBAL(_outsl_ns)
+ 	sync
+ 	blr	
+ 
+-
+-_GLOBAL(cvt_fd)
+-	lfd	0,0(r5)		/* load up fpscr value */
+-	mtfsf	0xff,0
+-	lfs	0,0(r3)
+-	stfd	0,0(r4)
+-	mffs	0		/* save new fpscr value */
+-	stfd	0,0(r5)
+-	blr
+-
+-_GLOBAL(cvt_df)
+-	lfd	0,0(r5)		/* load up fpscr value */
+-	mtfsf	0xff,0
+-	lfd	0,0(r3)
+-	stfs	0,0(r4)
+-	mffs	0		/* save new fpscr value */
+-	stfd	0,0(r5)
+-	blr
+-
+ /*
+  * identify_cpu and calls setup_cpu
+  * In:	r3 = base of the cpu_specs array
+@@ -692,38 +636,6 @@ _GLOBAL(disable_kernel_fp)
+ 	isync
+ 	blr
+ 
+-/*
+- * giveup_fpu(tsk)
+- * Disable FP for the task given as the argument,
+- * and save the floating-point registers in its thread_struct.
+- * Enables the FPU for use in the kernel on return.
+- */
+-_GLOBAL(giveup_fpu)
+-	mfmsr	r5
+-	ori	r5,r5,MSR_FP
+-	mtmsrd	r5			/* enable use of fpu now */
+-	isync
+-	cmpdi	0,r3,0
+-	beqlr-				/* if no previous owner, done */
+-	addi	r3,r3,THREAD		/* want THREAD of task */
+-	ld	r5,PT_REGS(r3)
+-	cmpdi	0,r5,0
+-	SAVE_32FPRS(0, r3)
+-	mffs	fr0
+-	stfd	fr0,THREAD_FPSCR(r3)
+-	beq	1f
+-	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+-	li	r3,MSR_FP|MSR_FE0|MSR_FE1
+-	andc	r4,r4,r3		/* disable FP for previous task */
+-	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+-1:
+-#ifndef CONFIG_SMP
+-	li	r5,0
+-	ld	r4,last_task_used_math at got(r2)
+-	std	r5,0(r4)
+-#endif /* CONFIG_SMP */
+-	blr
+-
+ #ifdef CONFIG_ALTIVEC
+ 
+ #if 0 /* this has no callers for now */
+@@ -778,6 +690,13 @@ _GLOBAL(giveup_altivec)
+ _GLOBAL(__setup_cpu_power3)
+ 	blr
+ 
++_GLOBAL(execve)
++	li	r0,__NR_execve
++	sc
++	bnslr
++	neg	r3,r3
++	blr
++
+ /* kexec_wait(phys_cpu)
+  *
+  * wait for the flag to change, indicating this kernel is going away but
+@@ -948,566 +867,3 @@ _GLOBAL(kexec_sequence)
+ 	li	r5,0
+ 	blr	/* image->start(physid, image->start, 0); */
+ #endif /* CONFIG_KEXEC */
+-
+-/* Why isn't this a) automatic, b) written in 'C'? */	
+-	.balign 8
+-_GLOBAL(sys_call_table32)
+-	.llong .sys_restart_syscall	/* 0 */
+-	.llong .sys_exit
+-	.llong .ppc_fork
+-	.llong .sys_read
+-	.llong .sys_write
+-	.llong .compat_sys_open		/* 5 */
+-	.llong .sys_close
+-	.llong .sys32_waitpid
+-	.llong .sys32_creat
+-	.llong .sys_link
+-	.llong .sys_unlink      	/* 10 */
+-	.llong .sys32_execve
+-	.llong .sys_chdir
+-	.llong .compat_sys_time
+-	.llong .sys_mknod
+-	.llong .sys_chmod		/* 15 */
+-	.llong .sys_lchown
+-	.llong .sys_ni_syscall		/* old break syscall */
+-	.llong .sys_ni_syscall		/* old stat syscall */
+-	.llong .ppc32_lseek
+-	.llong .sys_getpid              /* 20 */
+-	.llong .compat_sys_mount
+-	.llong .sys_oldumount
+-	.llong .sys_setuid
+-	.llong .sys_getuid
+-	.llong .compat_sys_stime	/* 25 */
+-	.llong .sys32_ptrace
+-	.llong .sys_alarm
+-	.llong .sys_ni_syscall		/* old fstat syscall */
+-	.llong .sys32_pause
+-	.llong .compat_sys_utime		/* 30 */
+-	.llong .sys_ni_syscall		/* old stty syscall */
+-	.llong .sys_ni_syscall		/* old gtty syscall */
+-	.llong .sys32_access
+-	.llong .sys32_nice
+-	.llong .sys_ni_syscall		/* 35 - old ftime syscall */
+-	.llong .sys_sync
+-	.llong .sys32_kill
+-	.llong .sys_rename
+-	.llong .sys32_mkdir
+-	.llong .sys_rmdir		/* 40 */
+-	.llong .sys_dup
+-	.llong .sys_pipe
+-	.llong .compat_sys_times
+-	.llong .sys_ni_syscall		/* old prof syscall */
+-	.llong .sys_brk			/* 45 */
+-	.llong .sys_setgid
+-	.llong .sys_getgid
+-	.llong .sys_signal
+-	.llong .sys_geteuid
+-	.llong .sys_getegid		/* 50 */
+-	.llong .sys_acct
+-	.llong .sys_umount
+-	.llong .sys_ni_syscall		/* old lock syscall */
+-	.llong .compat_sys_ioctl
+-	.llong .compat_sys_fcntl		/* 55 */
+-	.llong .sys_ni_syscall		/* old mpx syscall */
+-	.llong .sys32_setpgid
+-	.llong .sys_ni_syscall		/* old ulimit syscall */
+-	.llong .sys32_olduname
+-	.llong .sys32_umask		/* 60 */
+-	.llong .sys_chroot
+-	.llong .sys_ustat
+-	.llong .sys_dup2
+-	.llong .sys_getppid
+-	.llong .sys_getpgrp	        /* 65 */
+-	.llong .sys_setsid
+-	.llong .sys32_sigaction
+-	.llong .sys_sgetmask
+-	.llong .sys32_ssetmask
+-	.llong .sys_setreuid	        /* 70 */
+-	.llong .sys_setregid
+-	.llong .ppc32_sigsuspend
+-	.llong .compat_sys_sigpending
+-	.llong .sys32_sethostname
+-	.llong .compat_sys_setrlimit	        /* 75 */
+-	.llong .compat_sys_old_getrlimit
+-	.llong .compat_sys_getrusage
+-	.llong .sys32_gettimeofday
+-	.llong .sys32_settimeofday
+-	.llong .sys32_getgroups	        /* 80 */
+-	.llong .sys32_setgroups
+-	.llong .sys_ni_syscall		/* old select syscall */
+-	.llong .sys_symlink
+-	.llong .sys_ni_syscall		/* old lstat syscall */
+-	.llong .sys32_readlink	        /* 85 */
+-	.llong .sys_uselib
+-	.llong .sys_swapon
+-	.llong .sys_reboot
+-	.llong .old32_readdir
+-	.llong .sys_mmap		/* 90 */
+-	.llong .sys_munmap
+-	.llong .sys_truncate
+-	.llong .sys_ftruncate
+-	.llong .sys_fchmod
+-	.llong .sys_fchown              /* 95 */
+-	.llong .sys32_getpriority
+-	.llong .sys32_setpriority
+-	.llong .sys_ni_syscall		/* old profil syscall */
+-	.llong .compat_sys_statfs
+-	.llong .compat_sys_fstatfs		/* 100 */
+-	.llong .sys_ni_syscall		/* old ioperm syscall */
+-	.llong .compat_sys_socketcall
+-	.llong .sys32_syslog
+-	.llong .compat_sys_setitimer
+-	.llong .compat_sys_getitimer		/* 105 */
+-	.llong .compat_sys_newstat
+-	.llong .compat_sys_newlstat
+-	.llong .compat_sys_newfstat
+-	.llong .sys32_uname
+-	.llong .sys_ni_syscall		/* 110 old iopl syscall */
+-	.llong .sys_vhangup
+-	.llong .sys_ni_syscall		/* old idle syscall */
+-	.llong .sys_ni_syscall		/* old vm86 syscall */
+-	.llong .compat_sys_wait4
+-	.llong .sys_swapoff		/* 115 */
+-	.llong .sys32_sysinfo
+-	.llong .sys32_ipc
+-	.llong .sys_fsync
+-	.llong .ppc32_sigreturn
+-	.llong .ppc_clone		/* 120 */
+-	.llong .sys32_setdomainname
+-	.llong .ppc64_newuname
+-	.llong .sys_ni_syscall		/* old modify_ldt syscall */
+-	.llong .sys32_adjtimex
+-	.llong .sys_mprotect		/* 125 */
+-	.llong .compat_sys_sigprocmask
+-	.llong .sys_ni_syscall		/* old create_module syscall */
+-	.llong .sys_init_module
+-	.llong .sys_delete_module
+-	.llong .sys_ni_syscall		/* 130 old get_kernel_syms syscall */
+-	.llong .sys_quotactl
+-	.llong .sys32_getpgid
+-	.llong .sys_fchdir
+-	.llong .sys_bdflush
+-	.llong .sys32_sysfs		/* 135 */
+-	.llong .ppc64_personality
+-	.llong .sys_ni_syscall	        /* for afs_syscall */
+-	.llong .sys_setfsuid
+-	.llong .sys_setfsgid
+-	.llong .sys_llseek	        /* 140 */
+-        .llong .sys32_getdents
+-	.llong .ppc32_select
+-	.llong .sys_flock
+-	.llong .sys_msync
+-	.llong .compat_sys_readv	/* 145 */
+-	.llong .compat_sys_writev
+-	.llong .sys32_getsid
+-	.llong .sys_fdatasync
+-	.llong .sys32_sysctl
+-	.llong .sys_mlock		/* 150 */
+-	.llong .sys_munlock
+-	.llong .sys_mlockall
+-	.llong .sys_munlockall
+-	.llong .sys32_sched_setparam
+-	.llong .sys32_sched_getparam	/* 155 */
+-	.llong .sys32_sched_setscheduler
+-	.llong .sys32_sched_getscheduler
+-	.llong .sys_sched_yield
+-	.llong .sys32_sched_get_priority_max
+-	.llong .sys32_sched_get_priority_min  /* 160 */
+-	.llong .sys32_sched_rr_get_interval
+-	.llong .compat_sys_nanosleep
+-	.llong .sys_mremap
+-	.llong .sys_setresuid
+-	.llong .sys_getresuid	        /* 165 */
+-	.llong .sys_ni_syscall		/* old query_module syscall */
+-	.llong .sys_poll
+-	.llong .compat_sys_nfsservctl
+-	.llong .sys_setresgid
+-	.llong .sys_getresgid	        /* 170 */
+-	.llong .sys32_prctl
+-	.llong .ppc32_rt_sigreturn
+-	.llong .sys32_rt_sigaction
+-	.llong .sys32_rt_sigprocmask
+-	.llong .sys32_rt_sigpending     /* 175 */
+-	.llong .compat_sys_rt_sigtimedwait
+-	.llong .sys32_rt_sigqueueinfo
+-	.llong .ppc32_rt_sigsuspend
+-	.llong .sys32_pread64
+-	.llong .sys32_pwrite64	        /* 180 */
+-	.llong .sys_chown
+-	.llong .sys_getcwd
+-	.llong .sys_capget
+-	.llong .sys_capset
+-	.llong .sys32_sigaltstack	/* 185 */
+-	.llong .sys32_sendfile
+-	.llong .sys_ni_syscall		/* reserved for streams1 */
+-	.llong .sys_ni_syscall		/* reserved for streams2 */
+-	.llong .ppc_vfork
+-	.llong .compat_sys_getrlimit	        /* 190 */
+-	.llong .sys32_readahead
+-	.llong .sys32_mmap2
+-	.llong .sys32_truncate64
+-	.llong .sys32_ftruncate64
+-	.llong .sys_stat64      	/* 195 */
+-	.llong .sys_lstat64
+-	.llong .sys_fstat64
+-	.llong .sys32_pciconfig_read
+-	.llong .sys32_pciconfig_write
+-	.llong .sys32_pciconfig_iobase	/* 200 - pciconfig_iobase */
+-	.llong .sys_ni_syscall		/* reserved for MacOnLinux */
+-	.llong .sys_getdents64
+-	.llong .sys_pivot_root
+-	.llong .compat_sys_fcntl64
+-	.llong .sys_madvise		/* 205 */
+-	.llong .sys_mincore
+-	.llong .sys_gettid
+-	.llong .sys_tkill
+-	.llong .sys_setxattr
+-	.llong .sys_lsetxattr		/* 210 */
+-	.llong .sys_fsetxattr
+-	.llong .sys_getxattr
+-	.llong .sys_lgetxattr
+-	.llong .sys_fgetxattr
+-	.llong .sys_listxattr		/* 215 */
+-	.llong .sys_llistxattr
+-	.llong .sys_flistxattr
+-	.llong .sys_removexattr
+-	.llong .sys_lremovexattr
+-	.llong .sys_fremovexattr	/* 220 */
+-	.llong .compat_sys_futex
+-	.llong .compat_sys_sched_setaffinity
+-	.llong .compat_sys_sched_getaffinity
+-	.llong .sys_ni_syscall
+-	.llong .sys_ni_syscall		/* 225 - reserved for tux */
+-	.llong .sys32_sendfile64
+-	.llong .compat_sys_io_setup
+-	.llong .sys_io_destroy
+-	.llong .compat_sys_io_getevents
+-	.llong .compat_sys_io_submit
+-	.llong .sys_io_cancel
+-	.llong .sys_set_tid_address
+-	.llong .ppc32_fadvise64
+-	.llong .sys_exit_group
+-	.llong .ppc32_lookup_dcookie	/* 235 */
+-	.llong .sys_epoll_create
+-	.llong .sys_epoll_ctl
+-	.llong .sys_epoll_wait
+-	.llong .sys_remap_file_pages
+-	.llong .ppc32_timer_create	/* 240 */
+-	.llong .compat_sys_timer_settime
+-	.llong .compat_sys_timer_gettime
+-	.llong .sys_timer_getoverrun
+-	.llong .sys_timer_delete
+-	.llong .compat_sys_clock_settime	/* 245 */
+-	.llong .compat_sys_clock_gettime
+-	.llong .compat_sys_clock_getres
+-	.llong .compat_sys_clock_nanosleep
+-	.llong .ppc32_swapcontext
+-	.llong .sys32_tgkill		/* 250 */
+-	.llong .sys32_utimes
+-	.llong .compat_sys_statfs64
+-	.llong .compat_sys_fstatfs64
+-	.llong .ppc32_fadvise64_64	/* 32bit only fadvise64_64 */
+-	.llong .ppc_rtas		/* 255 */
+-	.llong .sys_ni_syscall		/* 256 reserved for sys_debug_setcontext */
+-	.llong .sys_ni_syscall		/* 257 reserved for vserver */
+-	.llong .sys_ni_syscall		/* 258 reserved for new sys_remap_file_pages */
+-	.llong .compat_sys_mbind
+-	.llong .compat_sys_get_mempolicy	/* 260 */
+-	.llong .compat_sys_set_mempolicy
+-	.llong .compat_sys_mq_open
+-	.llong .sys_mq_unlink
+-	.llong .compat_sys_mq_timedsend
+-	.llong .compat_sys_mq_timedreceive /* 265 */
+-	.llong .compat_sys_mq_notify
+-	.llong .compat_sys_mq_getsetattr
+-	.llong .compat_sys_kexec_load
+-	.llong .sys32_add_key
+-	.llong .sys32_request_key	/* 270 */
+-	.llong .compat_sys_keyctl
+-	.llong .compat_sys_waitid
+-	.llong .sys32_ioprio_set
+-	.llong .sys32_ioprio_get
+-	.llong .sys_inotify_init	/* 275 */
+-	.llong .sys_inotify_add_watch
+-	.llong .sys_inotify_rm_watch
+-
+-	.balign 8
+-_GLOBAL(sys_call_table)
+-	.llong .sys_restart_syscall	/* 0 */
+-	.llong .sys_exit
+-	.llong .ppc_fork
+-	.llong .sys_read
+-	.llong .sys_write
+-	.llong .sys_open		/* 5 */
+-	.llong .sys_close
+-	.llong .sys_waitpid
+-	.llong .sys_creat
+-	.llong .sys_link
+-	.llong .sys_unlink		/* 10 */
+-	.llong .sys_execve
+-	.llong .sys_chdir
+-	.llong .sys64_time
+-	.llong .sys_mknod
+-	.llong .sys_chmod		/* 15 */
+-	.llong .sys_lchown
+-	.llong .sys_ni_syscall		/* old break syscall */
+-	.llong .sys_ni_syscall		/* old stat syscall */
+-	.llong .sys_lseek
+-	.llong .sys_getpid		/* 20 */
+-	.llong .sys_mount
+-	.llong .sys_ni_syscall		/* old umount syscall */
+-	.llong .sys_setuid
+-	.llong .sys_getuid
+-	.llong .sys_stime		/* 25 */
+-	.llong .sys_ptrace
+-	.llong .sys_alarm
+-	.llong .sys_ni_syscall		/* old fstat syscall */
+-	.llong .sys_pause
+-	.llong .sys_utime		/* 30 */
+-	.llong .sys_ni_syscall		/* old stty syscall */
+-	.llong .sys_ni_syscall		/* old gtty syscall */
+-	.llong .sys_access
+-	.llong .sys_nice
+-	.llong .sys_ni_syscall		/* 35 - old ftime syscall */
+-	.llong .sys_sync
+-	.llong .sys_kill
+-	.llong .sys_rename
+-	.llong .sys_mkdir
+-	.llong .sys_rmdir		/* 40 */
+-	.llong .sys_dup
+-	.llong .sys_pipe
+-	.llong .sys_times
+-	.llong .sys_ni_syscall		/* old prof syscall */
+-	.llong .sys_brk			/* 45 */
+-	.llong .sys_setgid
+-	.llong .sys_getgid
+-	.llong .sys_signal
+-	.llong .sys_geteuid
+-	.llong .sys_getegid		/* 50 */
+-	.llong .sys_acct
+-	.llong .sys_umount
+-	.llong .sys_ni_syscall		/* old lock syscall */
+-	.llong .sys_ioctl
+-	.llong .sys_fcntl		/* 55 */
+-	.llong .sys_ni_syscall		/* old mpx syscall */
+-	.llong .sys_setpgid
+-	.llong .sys_ni_syscall		/* old ulimit syscall */
+-	.llong .sys_ni_syscall		/* old uname syscall */
+-	.llong .sys_umask		/* 60 */
+-	.llong .sys_chroot
+-	.llong .sys_ustat
+-	.llong .sys_dup2
+-	.llong .sys_getppid
+-	.llong .sys_getpgrp		/* 65 */
+-	.llong .sys_setsid
+-	.llong .sys_ni_syscall
+-	.llong .sys_sgetmask
+-	.llong .sys_ssetmask
+-	.llong .sys_setreuid		/* 70 */
+-	.llong .sys_setregid
+-	.llong .sys_ni_syscall
+-	.llong .sys_ni_syscall
+-	.llong .sys_sethostname
+-	.llong .sys_setrlimit		/* 75 */
+-	.llong .sys_ni_syscall		/* old getrlimit syscall */
+-	.llong .sys_getrusage
+-	.llong .sys_gettimeofday
+-	.llong .sys_settimeofday
+-	.llong .sys_getgroups		/* 80 */
+-	.llong .sys_setgroups
+-	.llong .sys_ni_syscall		/* old select syscall */
+-	.llong .sys_symlink
+-	.llong .sys_ni_syscall		/* old lstat syscall */
+-	.llong .sys_readlink		/* 85 */
+-	.llong .sys_uselib
+-	.llong .sys_swapon
+-	.llong .sys_reboot
+-	.llong .sys_ni_syscall		/* old readdir syscall */
+-	.llong .sys_mmap		/* 90 */
+-	.llong .sys_munmap
+-	.llong .sys_truncate
+-	.llong .sys_ftruncate
+-	.llong .sys_fchmod
+-	.llong .sys_fchown		/* 95 */
+-	.llong .sys_getpriority
+-	.llong .sys_setpriority
+-	.llong .sys_ni_syscall		/* old profil syscall holder */
+-	.llong .sys_statfs
+-	.llong .sys_fstatfs		/* 100 */
+-	.llong .sys_ni_syscall		/* old ioperm syscall */
+-	.llong .sys_socketcall
+-	.llong .sys_syslog
+-	.llong .sys_setitimer
+-	.llong .sys_getitimer		/* 105 */
+-	.llong .sys_newstat
+-	.llong .sys_newlstat
+-	.llong .sys_newfstat
+-	.llong .sys_ni_syscall		/* old uname syscall */
+-	.llong .sys_ni_syscall		/* 110 old iopl syscall */
+-	.llong .sys_vhangup
+-	.llong .sys_ni_syscall		/* old idle syscall */
+-	.llong .sys_ni_syscall		/* old vm86 syscall */
+-	.llong .sys_wait4
+-	.llong .sys_swapoff		/* 115 */
+-	.llong .sys_sysinfo
+-	.llong .sys_ipc
+-	.llong .sys_fsync
+-	.llong .sys_ni_syscall
+-	.llong .ppc_clone		/* 120 */
+-	.llong .sys_setdomainname
+-	.llong .ppc64_newuname
+-	.llong .sys_ni_syscall		/* old modify_ldt syscall */
+-	.llong .sys_adjtimex
+-	.llong .sys_mprotect		/* 125 */
+-	.llong .sys_ni_syscall
+-	.llong .sys_ni_syscall		/* old create_module syscall */
+-	.llong .sys_init_module
+-	.llong .sys_delete_module
+-	.llong .sys_ni_syscall		/* 130 old get_kernel_syms syscall */
+-	.llong .sys_quotactl
+-	.llong .sys_getpgid
+-	.llong .sys_fchdir
+-	.llong .sys_bdflush
+-	.llong .sys_sysfs		/* 135 */
+-	.llong .ppc64_personality
+-	.llong .sys_ni_syscall	        /* for afs_syscall */
+-	.llong .sys_setfsuid
+-	.llong .sys_setfsgid
+-	.llong .sys_llseek	        /* 140 */
+-        .llong .sys_getdents
+-	.llong .sys_select
+-	.llong .sys_flock
+-	.llong .sys_msync
+-	.llong .sys_readv		/* 145 */
+-	.llong .sys_writev
+-	.llong .sys_getsid
+-	.llong .sys_fdatasync
+-	.llong .sys_sysctl
+-	.llong .sys_mlock		/* 150 */
+-	.llong .sys_munlock
+-	.llong .sys_mlockall
+-	.llong .sys_munlockall
+-	.llong .sys_sched_setparam
+-	.llong .sys_sched_getparam	/* 155 */
+-	.llong .sys_sched_setscheduler
+-	.llong .sys_sched_getscheduler
+-	.llong .sys_sched_yield
+-	.llong .sys_sched_get_priority_max
+-	.llong .sys_sched_get_priority_min  /* 160 */
+-	.llong .sys_sched_rr_get_interval
+-	.llong .sys_nanosleep
+-	.llong .sys_mremap
+-	.llong .sys_setresuid
+-	.llong .sys_getresuid	        /* 165 */
+-	.llong .sys_ni_syscall		/* old query_module syscall */
+-	.llong .sys_poll
+-	.llong .sys_nfsservctl
+-	.llong .sys_setresgid
+-	.llong .sys_getresgid	        /* 170 */
+-	.llong .sys_prctl
+-	.llong .ppc64_rt_sigreturn
+-	.llong .sys_rt_sigaction
+-	.llong .sys_rt_sigprocmask	
+-	.llong .sys_rt_sigpending	/* 175 */
+-	.llong .sys_rt_sigtimedwait
+-	.llong .sys_rt_sigqueueinfo
+-	.llong .ppc64_rt_sigsuspend
+-	.llong .sys_pread64
+-	.llong .sys_pwrite64	        /* 180 */
+-	.llong .sys_chown
+-	.llong .sys_getcwd
+-	.llong .sys_capget
+-	.llong .sys_capset
+-	.llong .sys_sigaltstack	        /* 185 */
+-	.llong .sys_sendfile64
+-	.llong .sys_ni_syscall		/* reserved for streams1 */
+-	.llong .sys_ni_syscall		/* reserved for streams2 */
+-	.llong .ppc_vfork
+-	.llong .sys_getrlimit	        /* 190 */
+-	.llong .sys_readahead
+-	.llong .sys_ni_syscall		/* 32bit only mmap2 */
+-	.llong .sys_ni_syscall		/* 32bit only truncate64 */
+-	.llong .sys_ni_syscall		/* 32bit only ftruncate64 */
+-	.llong .sys_ni_syscall		/* 195 - 32bit only stat64 */
+-	.llong .sys_ni_syscall		/* 32bit only lstat64 */
+-	.llong .sys_ni_syscall		/* 32bit only fstat64 */
+-	.llong .sys_pciconfig_read
+-	.llong .sys_pciconfig_write
+-	.llong .sys_pciconfig_iobase	/* 200 - pciconfig_iobase */
+-	.llong .sys_ni_syscall		/* reserved for MacOnLinux */
+-	.llong .sys_getdents64
+-	.llong .sys_pivot_root
+-	.llong .sys_ni_syscall		/* 32bit only fcntl64 */
+-	.llong .sys_madvise		/* 205 */
+-	.llong .sys_mincore
+-	.llong .sys_gettid
+-	.llong .sys_tkill
+-	.llong .sys_setxattr
+-	.llong .sys_lsetxattr		/* 210 */
+-	.llong .sys_fsetxattr
+-	.llong .sys_getxattr
+-	.llong .sys_lgetxattr
+-	.llong .sys_fgetxattr
+-	.llong .sys_listxattr		/* 215 */
+-	.llong .sys_llistxattr
+-	.llong .sys_flistxattr
+-	.llong .sys_removexattr
+-	.llong .sys_lremovexattr
+-	.llong .sys_fremovexattr	/* 220 */
+-	.llong .sys_futex
+-	.llong .sys_sched_setaffinity
+-	.llong .sys_sched_getaffinity
+-	.llong .sys_ni_syscall
+-	.llong .sys_ni_syscall		/* 225 - reserved for tux */
+-	.llong .sys_ni_syscall		/* 32bit only sendfile64 */
+-	.llong .sys_io_setup
+-	.llong .sys_io_destroy
+-	.llong .sys_io_getevents
+-	.llong .sys_io_submit		/* 230 */
+-	.llong .sys_io_cancel
+-	.llong .sys_set_tid_address
+-	.llong .sys_fadvise64
+-	.llong .sys_exit_group
+-	.llong .sys_lookup_dcookie	/* 235 */
+-	.llong .sys_epoll_create
+-	.llong .sys_epoll_ctl
+-	.llong .sys_epoll_wait
+-	.llong .sys_remap_file_pages
+-	.llong .sys_timer_create	/* 240 */
+-	.llong .sys_timer_settime
+-	.llong .sys_timer_gettime
+-	.llong .sys_timer_getoverrun
+-	.llong .sys_timer_delete
+-	.llong .sys_clock_settime	/* 245 */
+-	.llong .sys_clock_gettime
+-	.llong .sys_clock_getres
+-	.llong .sys_clock_nanosleep
+-	.llong .ppc64_swapcontext
+-	.llong .sys_tgkill		/* 250 */
+-	.llong .sys_utimes
+-	.llong .sys_statfs64
+-	.llong .sys_fstatfs64
+-	.llong .sys_ni_syscall		/* 32bit only fadvise64_64 */
+-	.llong .ppc_rtas		/* 255 */
+-	.llong .sys_ni_syscall		/* 256 reserved for sys_debug_setcontext */
+-	.llong .sys_ni_syscall		/* 257 reserved for vserver */
+-	.llong .sys_ni_syscall		/* 258 reserved for new sys_remap_file_pages */
+-	.llong .sys_mbind
+-	.llong .sys_get_mempolicy	/* 260 */
+-	.llong .sys_set_mempolicy
+-	.llong .sys_mq_open
+-	.llong .sys_mq_unlink
+-	.llong .sys_mq_timedsend
+-	.llong .sys_mq_timedreceive	/* 265 */
+-	.llong .sys_mq_notify
+-	.llong .sys_mq_getsetattr
+-	.llong .sys_kexec_load
+-	.llong .sys_add_key
+-	.llong .sys_request_key		/* 270 */
+-	.llong .sys_keyctl
+-	.llong .sys_waitid
+-	.llong .sys_ioprio_set
+-	.llong .sys_ioprio_get
+-	.llong .sys_inotify_init	/* 275 */
+-	.llong .sys_inotify_add_watch
+-	.llong .sys_inotify_rm_watch
+diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/mpic.c
++++ /dev/null
+@@ -1,888 +0,0 @@
+-/*
+- *  arch/ppc64/kernel/mpic.c
+- *
+- *  Driver for interrupt controllers following the OpenPIC standard, the
+- *  common implementation beeing IBM's MPIC. This driver also can deal
+- *  with various broken implementations of this HW.
+- *
+- *  Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
+- *
+- *  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/config.h>
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/irq.h>
+-#include <linux/smp.h>
+-#include <linux/interrupt.h>
+-#include <linux/bootmem.h>
+-#include <linux/spinlock.h>
+-#include <linux/pci.h>
+-
+-#include <asm/ptrace.h>
+-#include <asm/signal.h>
+-#include <asm/io.h>
+-#include <asm/pgtable.h>
+-#include <asm/irq.h>
+-#include <asm/machdep.h>
+-
+-#include "mpic.h"
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) printk(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-static struct mpic *mpics;
+-static struct mpic *mpic_primary;
+-static DEFINE_SPINLOCK(mpic_lock);
+-
+-
+-/*
+- * Register accessor functions
+- */
+-
+-
+-static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base,
+-			    unsigned int reg)
+-{
+-	if (be)
+-		return in_be32(base + (reg >> 2));
+-	else
+-		return in_le32(base + (reg >> 2));
+-}
+-
+-static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base,
+-			      unsigned int reg, u32 value)
+-{
+-	if (be)
+-		out_be32(base + (reg >> 2), value);
+-	else
+-		out_le32(base + (reg >> 2), value);
+-}
+-
+-static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
+-{
+-	unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
+-	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+-
+-	if (mpic->flags & MPIC_BROKEN_IPI)
+-		be = !be;
+-	return _mpic_read(be, mpic->gregs, offset);
+-}
+-
+-static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
+-{
+-	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+-
+-	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
+-}
+-
+-static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
+-{
+-	unsigned int cpu = 0;
+-
+-	if (mpic->flags & MPIC_PRIMARY)
+-		cpu = hard_smp_processor_id();
+-
+-	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg);
+-}
+-
+-static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value)
+-{
+-	unsigned int cpu = 0;
+-
+-	if (mpic->flags & MPIC_PRIMARY)
+-		cpu = hard_smp_processor_id();
+-
+-	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg, value);
+-}
+-
+-static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg)
+-{
+-	unsigned int	isu = src_no >> mpic->isu_shift;
+-	unsigned int	idx = src_no & mpic->isu_mask;
+-
+-	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
+-			  reg + (idx * MPIC_IRQ_STRIDE));
+-}
+-
+-static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
+-				   unsigned int reg, u32 value)
+-{
+-	unsigned int	isu = src_no >> mpic->isu_shift;
+-	unsigned int	idx = src_no & mpic->isu_mask;
+-
+-	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
+-		    reg + (idx * MPIC_IRQ_STRIDE), value);
+-}
+-
+-#define mpic_read(b,r)		_mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
+-#define mpic_write(b,r,v)	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN,(b),(r),(v))
+-#define mpic_ipi_read(i)	_mpic_ipi_read(mpic,(i))
+-#define mpic_ipi_write(i,v)	_mpic_ipi_write(mpic,(i),(v))
+-#define mpic_cpu_read(i)	_mpic_cpu_read(mpic,(i))
+-#define mpic_cpu_write(i,v)	_mpic_cpu_write(mpic,(i),(v))
+-#define mpic_irq_read(s,r)	_mpic_irq_read(mpic,(s),(r))
+-#define mpic_irq_write(s,r,v)	_mpic_irq_write(mpic,(s),(r),(v))
+-
+-
+-/*
+- * Low level utility functions
+- */
+-
+-
+-
+-/* Check if we have one of those nice broken MPICs with a flipped endian on
+- * reads from IPI registers
+- */
+-static void __init mpic_test_broken_ipi(struct mpic *mpic)
+-{
+-	u32 r;
+-
+-	mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK);
+-	r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0);
+-
+-	if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
+-		printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
+-		mpic->flags |= MPIC_BROKEN_IPI;
+-	}
+-}
+-
+-#ifdef CONFIG_MPIC_BROKEN_U3
+-
+-/* Test if an interrupt is sourced from HyperTransport (used on broken U3s)
+- * to force the edge setting on the MPIC and do the ack workaround.
+- */
+-static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source_no)
+-{
+-	if (source_no >= 128 || !mpic->fixups)
+-		return 0;
+-	return mpic->fixups[source_no].base != NULL;
+-}
+-
+-static inline void mpic_apic_end_irq(struct mpic *mpic, unsigned int source_no)
+-{
+-	struct mpic_irq_fixup *fixup = &mpic->fixups[source_no];
+-	u32 tmp;
+-
+-	spin_lock(&mpic->fixup_lock);
+-	writeb(0x11 + 2 * fixup->irq, fixup->base);
+-	tmp = readl(fixup->base + 2);
+-	writel(tmp | 0x80000000ul, fixup->base + 2);
+-	/* config writes shouldn't be posted but let's be safe ... */
+-	(void)readl(fixup->base + 2);
+-	spin_unlock(&mpic->fixup_lock);
+-}
+-
+-
+-static void __init mpic_amd8111_read_irq(struct mpic *mpic, u8 __iomem *devbase)
+-{
+-	int i, irq;
+-	u32 tmp;
+-
+-	printk(KERN_INFO "mpic:    - Workarounds on AMD 8111 @ %p\n", devbase);
+-
+-	for (i=0; i < 24; i++) {
+-		writeb(0x10 + 2*i, devbase + 0xf2);
+-		tmp = readl(devbase + 0xf4);
+-		if ((tmp & 0x1) || !(tmp & 0x20))
+-			continue;
+-		irq = (tmp >> 16) & 0xff;
+-		mpic->fixups[irq].irq = i;
+-		mpic->fixups[irq].base = devbase + 0xf2;
+-	}
+-}
+- 
+-static void __init mpic_amd8131_read_irq(struct mpic *mpic, u8 __iomem *devbase)
+-{
+-	int i, irq;
+-	u32 tmp;
+-
+-	printk(KERN_INFO "mpic:    - Workarounds on AMD 8131 @ %p\n", devbase);
+-
+-	for (i=0; i < 4; i++) {
+-		writeb(0x10 + 2*i, devbase + 0xba);
+-		tmp = readl(devbase + 0xbc);
+-		if ((tmp & 0x1) || !(tmp & 0x20))
+-			continue;
+-		irq = (tmp >> 16) & 0xff;
+-		mpic->fixups[irq].irq = i;
+-		mpic->fixups[irq].base = devbase + 0xba;
+-	}
+-}
+- 
+-static void __init mpic_scan_ioapics(struct mpic *mpic)
+-{
+-	unsigned int devfn;
+-	u8 __iomem *cfgspace;
+-
+-	printk(KERN_INFO "mpic: Setting up IO-APICs workarounds for U3\n");
+-
+-	/* Allocate fixups array */
+-	mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup));
+-	BUG_ON(mpic->fixups == NULL);
+-	memset(mpic->fixups, 0, 128 * sizeof(struct mpic_irq_fixup));
+-
+-	/* Init spinlock */
+-	spin_lock_init(&mpic->fixup_lock);
+-
+-	/* Map u3 config space. We assume all IO-APICs are on the primary bus
+-	 * and slot will never be above "0xf" so we only need to map 32k
+-	 */
+-	cfgspace = (unsigned char __iomem *)ioremap(0xf2000000, 0x8000);
+-	BUG_ON(cfgspace == NULL);
+-
+-	/* Now we scan all slots. We do a very quick scan, we read the header type,
+-	 * vendor ID and device ID only, that's plenty enough
+-	 */
+-	for (devfn = 0; devfn < PCI_DEVFN(0x10,0); devfn ++) {
+-		u8 __iomem *devbase = cfgspace + (devfn << 8);
+-		u8 hdr_type = readb(devbase + PCI_HEADER_TYPE);
+-		u32 l = readl(devbase + PCI_VENDOR_ID);
+-		u16 vendor_id, device_id;
+-		int multifunc = 0;
+-
+-		DBG("devfn %x, l: %x\n", devfn, l);
+-
+-		/* If no device, skip */
+-		if (l == 0xffffffff || l == 0x00000000 ||
+-		    l == 0x0000ffff || l == 0xffff0000)
+-			goto next;
+-
+-		/* Check if it's a multifunction device (only really used
+-		 * to function 0 though
+-		 */
+-		multifunc = !!(hdr_type & 0x80);
+-		vendor_id = l & 0xffff;
+-		device_id = (l >> 16) & 0xffff;
+-
+-		/* If a known device, go to fixup setup code */
+-		if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7460)
+-			mpic_amd8111_read_irq(mpic, devbase);
+-		if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7450)
+-			mpic_amd8131_read_irq(mpic, devbase);
+-	next:
+-		/* next device, if function 0 */
+-		if ((PCI_FUNC(devfn) == 0) && !multifunc)
+-			devfn += 7;
+-	}
+-}
+-
+-#endif /* CONFIG_MPIC_BROKEN_U3 */
+-
+-
+-/* Find an mpic associated with a given linux interrupt */
+-static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi)
+-{
+-	struct mpic *mpic = mpics;
+-
+-	while(mpic) {
+-		/* search IPIs first since they may override the main interrupts */
+-		if (irq >= mpic->ipi_offset && irq < (mpic->ipi_offset + 4)) {
+-			if (is_ipi)
+-				*is_ipi = 1;
+-			return mpic;
+-		}
+-		if (irq >= mpic->irq_offset &&
+-		    irq < (mpic->irq_offset + mpic->irq_count)) {
+-			if (is_ipi)
+-				*is_ipi = 0;
+-			return mpic;
+-		}
+-		mpic = mpic -> next;
+-	}
+-	return NULL;
+-}
+-
+-/* Convert a cpu mask from logical to physical cpu numbers. */
+-static inline u32 mpic_physmask(u32 cpumask)
+-{
+-	int i;
+-	u32 mask = 0;
+-
+-	for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1)
+-		mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
+-	return mask;
+-}
+-
+-#ifdef CONFIG_SMP
+-/* Get the mpic structure from the IPI number */
+-static inline struct mpic * mpic_from_ipi(unsigned int ipi)
+-{
+-	return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi);
+-}
+-#endif
+-
+-/* Get the mpic structure from the irq number */
+-static inline struct mpic * mpic_from_irq(unsigned int irq)
+-{
+-	return container_of(irq_desc[irq].handler, struct mpic, hc_irq);
+-}
+-
+-/* Send an EOI */
+-static inline void mpic_eoi(struct mpic *mpic)
+-{
+-	mpic_cpu_write(MPIC_CPU_EOI, 0);
+-	(void)mpic_cpu_read(MPIC_CPU_WHOAMI);
+-}
+-
+-#ifdef CONFIG_SMP
+-static irqreturn_t mpic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+-{
+-	struct mpic *mpic = dev_id;
+-
+-	smp_message_recv(irq - mpic->ipi_offset, regs);
+-	return IRQ_HANDLED;
+-}
+-#endif /* CONFIG_SMP */
+-
+-/*
+- * Linux descriptor level callbacks
+- */
+-
+-
+-static void mpic_enable_irq(unsigned int irq)
+-{
+-	unsigned int loops = 100000;
+-	struct mpic *mpic = mpic_from_irq(irq);
+-	unsigned int src = irq - mpic->irq_offset;
+-
+-	DBG("%s: enable_irq: %d (src %d)\n", mpic->name, irq, src);
+-
+-	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
+-		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK);
+-
+-	/* make sure mask gets to controller before we return to user */
+-	do {
+-		if (!loops--) {
+-			printk(KERN_ERR "mpic_enable_irq timeout\n");
+-			break;
+-		}
+-	} while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);	
+-}
+-
+-static void mpic_disable_irq(unsigned int irq)
+-{
+-	unsigned int loops = 100000;
+-	struct mpic *mpic = mpic_from_irq(irq);
+-	unsigned int src = irq - mpic->irq_offset;
+-
+-	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
+-
+-	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
+-		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK);
+-
+-	/* make sure mask gets to controller before we return to user */
+-	do {
+-		if (!loops--) {
+-			printk(KERN_ERR "mpic_enable_irq timeout\n");
+-			break;
+-		}
+-	} while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
+-}
+-
+-static void mpic_end_irq(unsigned int irq)
+-{
+-	struct mpic *mpic = mpic_from_irq(irq);
+-
+-	DBG("%s: end_irq: %d\n", mpic->name, irq);
+-
+-	/* We always EOI on end_irq() even for edge interrupts since that
+-	 * should only lower the priority, the MPIC should have properly
+-	 * latched another edge interrupt coming in anyway
+-	 */
+-
+-#ifdef CONFIG_MPIC_BROKEN_U3
+-	if (mpic->flags & MPIC_BROKEN_U3) {
+-		unsigned int src = irq - mpic->irq_offset;
+-		if (mpic_is_ht_interrupt(mpic, src))
+-			mpic_apic_end_irq(mpic, src);
+-	}
+-#endif /* CONFIG_MPIC_BROKEN_U3 */
+-
+-	mpic_eoi(mpic);
+-}
+-
+-#ifdef CONFIG_SMP
+-
+-static void mpic_enable_ipi(unsigned int irq)
+-{
+-	struct mpic *mpic = mpic_from_ipi(irq);
+-	unsigned int src = irq - mpic->ipi_offset;
+-
+-	DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src);
+-	mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
+-}
+-
+-static void mpic_disable_ipi(unsigned int irq)
+-{
+-	/* NEVER disable an IPI... that's just plain wrong! */
+-}
+-
+-static void mpic_end_ipi(unsigned int irq)
+-{
+-	struct mpic *mpic = mpic_from_ipi(irq);
+-
+-	/*
+-	 * IPIs are marked IRQ_PER_CPU. This has the side effect of
+-	 * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
+-	 * applying to them. We EOI them late to avoid re-entering.
+-	 * We mark IPI's with SA_INTERRUPT as they must run with
+-	 * irqs disabled.
+-	 */
+-	mpic_eoi(mpic);
+-}
+-
+-#endif /* CONFIG_SMP */
+-
+-static void mpic_set_affinity(unsigned int irq, cpumask_t cpumask)
+-{
+-	struct mpic *mpic = mpic_from_irq(irq);
+-
+-	cpumask_t tmp;
+-
+-	cpus_and(tmp, cpumask, cpu_online_map);
+-
+-	mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION,
+-		       mpic_physmask(cpus_addr(tmp)[0]));	
+-}
+-
+-
+-/*
+- * Exported functions
+- */
+-
+-
+-struct mpic * __init mpic_alloc(unsigned long phys_addr,
+-				unsigned int flags,
+-				unsigned int isu_size,
+-				unsigned int irq_offset,
+-				unsigned int irq_count,
+-				unsigned int ipi_offset,
+-				unsigned char *senses,
+-				unsigned int senses_count,
+-				const char *name)
+-{
+-	struct mpic	*mpic;
+-	u32		reg;
+-	const char	*vers;
+-	int		i;
+-
+-	mpic = alloc_bootmem(sizeof(struct mpic));
+-	if (mpic == NULL)
+-		return NULL;
+-	
+-	memset(mpic, 0, sizeof(struct mpic));
+-	mpic->name = name;
+-
+-	mpic->hc_irq.typename = name;
+-	mpic->hc_irq.enable = mpic_enable_irq;
+-	mpic->hc_irq.disable = mpic_disable_irq;
+-	mpic->hc_irq.end = mpic_end_irq;
+-	if (flags & MPIC_PRIMARY)
+-		mpic->hc_irq.set_affinity = mpic_set_affinity;
+-#ifdef CONFIG_SMP
+-	mpic->hc_ipi.typename = name;
+-	mpic->hc_ipi.enable = mpic_enable_ipi;
+-	mpic->hc_ipi.disable = mpic_disable_ipi;
+-	mpic->hc_ipi.end = mpic_end_ipi;
+-#endif /* CONFIG_SMP */
+-
+-	mpic->flags = flags;
+-	mpic->isu_size = isu_size;
+-	mpic->irq_offset = irq_offset;
+-	mpic->irq_count = irq_count;
+-	mpic->ipi_offset = ipi_offset;
+-	mpic->num_sources = 0; /* so far */
+-	mpic->senses = senses;
+-	mpic->senses_count = senses_count;
+-
+-	/* Map the global registers */
+-	mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x2000);
+-	mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
+-	BUG_ON(mpic->gregs == NULL);
+-
+-	/* Reset */
+-	if (flags & MPIC_WANTS_RESET) {
+-		mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
+-			   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+-			   | MPIC_GREG_GCONF_RESET);
+-		while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+-		       & MPIC_GREG_GCONF_RESET)
+-			mb();
+-	}
+-
+-	/* Read feature register, calculate num CPUs and, for non-ISU
+-	 * MPICs, num sources as well. On ISU MPICs, sources are counted
+-	 * as ISUs are added
+-	 */
+-	reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
+-	mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
+-			  >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
+-	if (isu_size == 0)
+-		mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK)
+-				     >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
+-
+-	/* Map the per-CPU registers */
+-	for (i = 0; i < mpic->num_cpus; i++) {
+-		mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
+-					   i * MPIC_CPU_STRIDE, 0x1000);
+-		BUG_ON(mpic->cpuregs[i] == NULL);
+-	}
+-
+-	/* Initialize main ISU if none provided */
+-	if (mpic->isu_size == 0) {
+-		mpic->isu_size = mpic->num_sources;
+-		mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
+-					MPIC_IRQ_STRIDE * mpic->isu_size);
+-		BUG_ON(mpic->isus[0] == NULL);
+-	}
+-	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
+-	mpic->isu_mask = (1 << mpic->isu_shift) - 1;
+-
+-	/* Display version */
+-	switch (reg & MPIC_GREG_FEATURE_VERSION_MASK) {
+-	case 1:
+-		vers = "1.0";
+-		break;
+-	case 2:
+-		vers = "1.2";
+-		break;
+-	case 3:
+-		vers = "1.3";
+-		break;
+-	default:
+-		vers = "<unknown>";
+-		break;
+-	}
+-	printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %lx, max %d CPUs\n",
+-	       name, vers, phys_addr, mpic->num_cpus);
+-	printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", mpic->isu_size,
+-	       mpic->isu_shift, mpic->isu_mask);
+-
+-	mpic->next = mpics;
+-	mpics = mpic;
+-
+-	if (flags & MPIC_PRIMARY)
+-		mpic_primary = mpic;
+-
+-	return mpic;
+-}
+-
+-void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
+-			    unsigned long phys_addr)
+-{
+-	unsigned int isu_first = isu_num * mpic->isu_size;
+-
+-	BUG_ON(isu_num >= MPIC_MAX_ISU);
+-
+-	mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size);
+-	if ((isu_first + mpic->isu_size) > mpic->num_sources)
+-		mpic->num_sources = isu_first + mpic->isu_size;
+-}
+-
+-void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler,
+-			       void *data)
+-{
+-	struct mpic *mpic = mpic_find(irq, NULL);
+-	unsigned long flags;
+-
+-	/* Synchronization here is a bit dodgy, so don't try to replace cascade
+-	 * interrupts on the fly too often ... but normally it's set up at boot.
+-	 */
+-	spin_lock_irqsave(&mpic_lock, flags);
+-	if (mpic->cascade)	       
+-		mpic_disable_irq(mpic->cascade_vec + mpic->irq_offset);
+-	mpic->cascade = NULL;
+-	wmb();
+-	mpic->cascade_vec = irq - mpic->irq_offset;
+-	mpic->cascade_data = data;
+-	wmb();
+-	mpic->cascade = handler;
+-	mpic_enable_irq(irq);
+-	spin_unlock_irqrestore(&mpic_lock, flags);
+-}
+-
+-void __init mpic_init(struct mpic *mpic)
+-{
+-	int i;
+-
+-	BUG_ON(mpic->num_sources == 0);
+-
+-	printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);
+-
+-	/* Set current processor priority to max */
+-	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+-
+-	/* Initialize timers: just disable them all */
+-	for (i = 0; i < 4; i++) {
+-		mpic_write(mpic->tmregs,
+-			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
+-		mpic_write(mpic->tmregs,
+-			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
+-			   MPIC_VECPRI_MASK |
+-			   (MPIC_VEC_TIMER_0 + i));
+-	}
+-
+-	/* Initialize IPIs to our reserved vectors and mark them disabled for now */
+-	mpic_test_broken_ipi(mpic);
+-	for (i = 0; i < 4; i++) {
+-		mpic_ipi_write(i,
+-			       MPIC_VECPRI_MASK |
+-			       (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
+-			       (MPIC_VEC_IPI_0 + i));
+-#ifdef CONFIG_SMP
+-		if (!(mpic->flags & MPIC_PRIMARY))
+-			continue;
+-		irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU;
+-		irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi;
+-		
+-#endif /* CONFIG_SMP */
+-	}
+-
+-	/* Initialize interrupt sources */
+-	if (mpic->irq_count == 0)
+-		mpic->irq_count = mpic->num_sources;
+-
+-#ifdef CONFIG_MPIC_BROKEN_U3
+-	/* Do the ioapic fixups on U3 broken mpic */
+-	DBG("MPIC flags: %x\n", mpic->flags);
+-	if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY))
+-		mpic_scan_ioapics(mpic);
+-#endif /* CONFIG_MPIC_BROKEN_U3 */
+-
+-	for (i = 0; i < mpic->num_sources; i++) {
+-		/* start with vector = source number, and masked */
+-		u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT);
+-		int level = 0;
+-		
+-		/* if it's an IPI, we skip it */
+-		if ((mpic->irq_offset + i) >= (mpic->ipi_offset + i) &&
+-		    (mpic->irq_offset + i) <  (mpic->ipi_offset + i + 4))
+-			continue;
+-
+-		/* do senses munging */
+-		if (mpic->senses && i < mpic->senses_count) {
+-			if (mpic->senses[i] & IRQ_SENSE_LEVEL)
+-				vecpri |= MPIC_VECPRI_SENSE_LEVEL;
+-			if (mpic->senses[i] & IRQ_POLARITY_POSITIVE)
+-				vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
+-		} else
+-			vecpri |= MPIC_VECPRI_SENSE_LEVEL;
+-
+-		/* remember if it was a level interrupts */
+-		level = (vecpri & MPIC_VECPRI_SENSE_LEVEL);
+-
+-		/* deal with broken U3 */
+-		if (mpic->flags & MPIC_BROKEN_U3) {
+-#ifdef CONFIG_MPIC_BROKEN_U3
+-			if (mpic_is_ht_interrupt(mpic, i)) {
+-				vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
+-					    MPIC_VECPRI_POLARITY_MASK);
+-				vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
+-			}
+-#else
+-			printk(KERN_ERR "mpic: BROKEN_U3 set, but CONFIG doesn't match\n");
+-#endif
+-		}
+-
+-		DBG("setup source %d, vecpri: %08x, level: %d\n", i, vecpri,
+-		    (level != 0));
+-
+-		/* init hw */
+-		mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
+-		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
+-			       1 << get_hard_smp_processor_id(boot_cpuid));
+-
+-		/* init linux descriptors */
+-		if (i < mpic->irq_count) {
+-			irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0;
+-			irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq;
+-		}
+-	}
+-	
+-	/* Init spurrious vector */
+-	mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS);
+-
+-	/* Disable 8259 passthrough */
+-	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
+-		   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+-		   | MPIC_GREG_GCONF_8259_PTHROU_DIS);
+-
+-	/* Set current processor priority to 0 */
+-	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+-}
+-
+-
+-
+-void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
+-{
+-	int is_ipi;
+-	struct mpic *mpic = mpic_find(irq, &is_ipi);
+-	unsigned long flags;
+-	u32 reg;
+-
+-	spin_lock_irqsave(&mpic_lock, flags);
+-	if (is_ipi) {
+-		reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK;
+-		mpic_ipi_write(irq - mpic->ipi_offset,
+-			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
+-	} else {
+-		reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI)
+-			& MPIC_VECPRI_PRIORITY_MASK;
+-		mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
+-			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
+-	}
+-	spin_unlock_irqrestore(&mpic_lock, flags);
+-}
+-
+-unsigned int mpic_irq_get_priority(unsigned int irq)
+-{
+-	int is_ipi;
+-	struct mpic *mpic = mpic_find(irq, &is_ipi);
+-	unsigned long flags;
+-	u32 reg;
+-
+-	spin_lock_irqsave(&mpic_lock, flags);
+-	if (is_ipi)
+-		reg = mpic_ipi_read(irq - mpic->ipi_offset);
+-	else
+-		reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI);
+-	spin_unlock_irqrestore(&mpic_lock, flags);
+-	return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT;
+-}
+-
+-void mpic_setup_this_cpu(void)
+-{
+-#ifdef CONFIG_SMP
+-	struct mpic *mpic = mpic_primary;
+-	unsigned long flags;
+-	u32 msk = 1 << hard_smp_processor_id();
+-	unsigned int i;
+-
+-	BUG_ON(mpic == NULL);
+-
+-	DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
+-
+-	spin_lock_irqsave(&mpic_lock, flags);
+-
+- 	/* let the mpic know we want intrs. default affinity is 0xffffffff
+-	 * until changed via /proc. That's how it's done on x86. If we want
+-	 * it differently, then we should make sure we also change the default
+-	 * values of irq_affinity in irq.c.
+- 	 */
+-	if (distribute_irqs) {
+-	 	for (i = 0; i < mpic->num_sources ; i++)
+-			mpic_irq_write(i, MPIC_IRQ_DESTINATION,
+-				mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
+-	}
+-
+-	/* Set current processor priority to 0 */
+-	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+-
+-	spin_unlock_irqrestore(&mpic_lock, flags);
+-#endif /* CONFIG_SMP */
+-}
+-
+-/*
+- * XXX: someone who knows mpic should check this.
+- * do we need to eoi the ipi including for kexec cpu here (see xics comments)?
+- * or can we reset the mpic in the new kernel?
+- */
+-void mpic_teardown_this_cpu(int secondary)
+-{
+-	struct mpic *mpic = mpic_primary;
+-	unsigned long flags;
+-	u32 msk = 1 << hard_smp_processor_id();
+-	unsigned int i;
+-
+-	BUG_ON(mpic == NULL);
+-
+-	DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
+-	spin_lock_irqsave(&mpic_lock, flags);
+-
+-	/* let the mpic know we don't want intrs.  */
+-	for (i = 0; i < mpic->num_sources ; i++)
+-		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
+-			mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
+-
+-	/* Set current processor priority to max */
+-	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+-
+-	spin_unlock_irqrestore(&mpic_lock, flags);
+-}
+-
+-
+-void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
+-{
+-	struct mpic *mpic = mpic_primary;
+-
+-	BUG_ON(mpic == NULL);
+-
+-	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
+-
+-	mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
+-		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
+-}
+-
+-int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
+-{
+-	u32 irq;
+-
+-	irq = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
+-	DBG("%s: get_one_irq(): %d\n", mpic->name, irq);
+-
+-	if (mpic->cascade && irq == mpic->cascade_vec) {
+-		DBG("%s: cascading ...\n", mpic->name);
+-		irq = mpic->cascade(regs, mpic->cascade_data);
+-		mpic_eoi(mpic);
+-		return irq;
+-	}
+-	if (unlikely(irq == MPIC_VEC_SPURRIOUS))
+-		return -1;
+-	if (irq < MPIC_VEC_IPI_0) 
+-		return irq + mpic->irq_offset;
+-       	DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
+-	return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset;
+-}
+-
+-int mpic_get_irq(struct pt_regs *regs)
+-{
+-	struct mpic *mpic = mpic_primary;
+-
+-	BUG_ON(mpic == NULL);
+-
+-	return mpic_get_one_irq(mpic, regs);
+-}
+-
+-
+-#ifdef CONFIG_SMP
+-void mpic_request_ipis(void)
+-{
+-	struct mpic *mpic = mpic_primary;
+-
+-	BUG_ON(mpic == NULL);
+-	
+-	printk("requesting IPIs ... \n");
+-
+-	/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
+-	request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT,
+-		    "IPI0 (call function)", mpic);
+-	request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT,
+-		   "IPI1 (reschedule)", mpic);
+-	request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT,
+-		   "IPI2 (unused)", mpic);
+-	request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT,
+-		   "IPI3 (debugger break)", mpic);
+-
+-	printk("IPIs requested... \n");
+-}
+-#endif /* CONFIG_SMP */
+diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h
+deleted file mode 100644
+--- a/arch/ppc64/kernel/mpic.h
++++ /dev/null
+@@ -1,273 +0,0 @@
+-#include <linux/irq.h>
+-
+-/*
+- * Global registers
+- */
+-
+-#define MPIC_GREG_BASE			0x01000
+-
+-#define MPIC_GREG_FEATURE_0		0x00000
+-#define		MPIC_GREG_FEATURE_LAST_SRC_MASK		0x07ff0000
+-#define		MPIC_GREG_FEATURE_LAST_SRC_SHIFT	16
+-#define		MPIC_GREG_FEATURE_LAST_CPU_MASK		0x00001f00
+-#define		MPIC_GREG_FEATURE_LAST_CPU_SHIFT	8
+-#define		MPIC_GREG_FEATURE_VERSION_MASK		0xff
+-#define MPIC_GREG_FEATURE_1		0x00010
+-#define MPIC_GREG_GLOBAL_CONF_0		0x00020
+-#define		MPIC_GREG_GCONF_RESET			0x80000000
+-#define		MPIC_GREG_GCONF_8259_PTHROU_DIS		0x20000000
+-#define		MPIC_GREG_GCONF_BASE_MASK		0x000fffff
+-#define MPIC_GREG_GLOBAL_CONF_1		0x00030
+-#define MPIC_GREG_VENDOR_0		0x00040
+-#define MPIC_GREG_VENDOR_1		0x00050
+-#define MPIC_GREG_VENDOR_2		0x00060
+-#define MPIC_GREG_VENDOR_3		0x00070
+-#define MPIC_GREG_VENDOR_ID		0x00080
+-#define 	MPIC_GREG_VENDOR_ID_STEPPING_MASK	0x00ff0000
+-#define 	MPIC_GREG_VENDOR_ID_STEPPING_SHIFT	16
+-#define 	MPIC_GREG_VENDOR_ID_DEVICE_ID_MASK	0x0000ff00
+-#define 	MPIC_GREG_VENDOR_ID_DEVICE_ID_SHIFT	8
+-#define 	MPIC_GREG_VENDOR_ID_VENDOR_ID_MASK	0x000000ff
+-#define MPIC_GREG_PROCESSOR_INIT	0x00090
+-#define MPIC_GREG_IPI_VECTOR_PRI_0	0x000a0
+-#define MPIC_GREG_IPI_VECTOR_PRI_1	0x000b0
+-#define MPIC_GREG_IPI_VECTOR_PRI_2	0x000c0
+-#define MPIC_GREG_IPI_VECTOR_PRI_3	0x000d0
+-#define MPIC_GREG_SPURIOUS		0x000e0
+-#define MPIC_GREG_TIMER_FREQ		0x000f0
+-
+-/*
+- *
+- * Timer registers
+- */
+-#define MPIC_TIMER_BASE			0x01100
+-#define MPIC_TIMER_STRIDE		0x40
+-
+-#define MPIC_TIMER_CURRENT_CNT		0x00000
+-#define MPIC_TIMER_BASE_CNT		0x00010
+-#define MPIC_TIMER_VECTOR_PRI		0x00020
+-#define MPIC_TIMER_DESTINATION		0x00030
+-
+-/*
+- * Per-Processor registers
+- */
+-
+-#define MPIC_CPU_THISBASE		0x00000
+-#define MPIC_CPU_BASE			0x20000
+-#define MPIC_CPU_STRIDE			0x01000
+-
+-#define MPIC_CPU_IPI_DISPATCH_0		0x00040
+-#define MPIC_CPU_IPI_DISPATCH_1		0x00050
+-#define MPIC_CPU_IPI_DISPATCH_2		0x00060
+-#define MPIC_CPU_IPI_DISPATCH_3		0x00070
+-#define MPIC_CPU_CURRENT_TASK_PRI	0x00080
+-#define 	MPIC_CPU_TASKPRI_MASK			0x0000000f
+-#define MPIC_CPU_WHOAMI			0x00090
+-#define 	MPIC_CPU_WHOAMI_MASK			0x0000001f
+-#define MPIC_CPU_INTACK			0x000a0
+-#define MPIC_CPU_EOI			0x000b0
+-
+-/*
+- * Per-source registers
+- */
+-
+-#define MPIC_IRQ_BASE			0x10000
+-#define MPIC_IRQ_STRIDE			0x00020
+-#define MPIC_IRQ_VECTOR_PRI		0x00000
+-#define 	MPIC_VECPRI_MASK			0x80000000
+-#define 	MPIC_VECPRI_ACTIVITY			0x40000000	/* Read Only */
+-#define 	MPIC_VECPRI_PRIORITY_MASK		0x000f0000
+-#define 	MPIC_VECPRI_PRIORITY_SHIFT		16
+-#define 	MPIC_VECPRI_VECTOR_MASK			0x000007ff
+-#define 	MPIC_VECPRI_POLARITY_POSITIVE		0x00800000
+-#define 	MPIC_VECPRI_POLARITY_NEGATIVE		0x00000000
+-#define 	MPIC_VECPRI_POLARITY_MASK		0x00800000
+-#define 	MPIC_VECPRI_SENSE_LEVEL			0x00400000
+-#define 	MPIC_VECPRI_SENSE_EDGE			0x00000000
+-#define 	MPIC_VECPRI_SENSE_MASK			0x00400000
+-#define MPIC_IRQ_DESTINATION		0x00010
+-
+-#define MPIC_MAX_IRQ_SOURCES	2048
+-#define MPIC_MAX_CPUS		32
+-#define MPIC_MAX_ISU		32
+-
+-/*
+- * Special vector numbers (internal use only)
+- */
+-#define MPIC_VEC_SPURRIOUS	255
+-#define MPIC_VEC_IPI_3		254
+-#define MPIC_VEC_IPI_2		253
+-#define MPIC_VEC_IPI_1		252
+-#define MPIC_VEC_IPI_0		251
+-
+-/* unused */
+-#define MPIC_VEC_TIMER_3	250
+-#define MPIC_VEC_TIMER_2	249
+-#define MPIC_VEC_TIMER_1	248
+-#define MPIC_VEC_TIMER_0	247
+-
+-/* Type definition of the cascade handler */
+-typedef int (*mpic_cascade_t)(struct pt_regs *regs, void *data);
+-
+-#ifdef CONFIG_MPIC_BROKEN_U3
+-/* Fixup table entry */
+-struct mpic_irq_fixup
+-{
+-	u8 __iomem	*base;
+-	unsigned int   irq;
+-};
+-#endif /* CONFIG_MPIC_BROKEN_U3 */
+-
+-
+-/* The instance data of a given MPIC */
+-struct mpic
+-{
+-	/* The "linux" controller struct */
+-	hw_irq_controller	hc_irq;
+-#ifdef CONFIG_SMP
+-	hw_irq_controller	hc_ipi;
+-#endif
+-	const char		*name;
+-	/* Flags */
+-	unsigned int		flags;
+-	/* How many irq sources in a given ISU */
+-	unsigned int		isu_size;
+-	unsigned int		isu_shift;
+-	unsigned int		isu_mask;
+-	/* Offset of irq vector numbers */
+-	unsigned int		irq_offset;	
+-	unsigned int		irq_count;
+-	/* Offset of ipi vector numbers */
+-	unsigned int		ipi_offset;
+-	/* Number of sources */
+-	unsigned int		num_sources;
+-	/* Number of CPUs */
+-	unsigned int		num_cpus;
+-	/* cascade handler */
+-	mpic_cascade_t		cascade;
+-	void			*cascade_data;
+-	unsigned int		cascade_vec;
+-	/* senses array */
+-	unsigned char		*senses;
+-	unsigned int		senses_count;
+-
+-#ifdef CONFIG_MPIC_BROKEN_U3
+-	/* The fixup table */
+-	struct mpic_irq_fixup	*fixups;
+-	spinlock_t		fixup_lock;
+-#endif
+-
+-	/* The various ioremap'ed bases */
+-	volatile u32 __iomem	*gregs;
+-	volatile u32 __iomem	*tmregs;
+-	volatile u32 __iomem	*cpuregs[MPIC_MAX_CPUS];
+-	volatile u32 __iomem	*isus[MPIC_MAX_ISU];
+-
+-	/* link */
+-	struct mpic		*next;
+-};
+-
+-/* This is the primary controller, only that one has IPIs and
+- * has afinity control. A non-primary MPIC always uses CPU0
+- * registers only
+- */
+-#define MPIC_PRIMARY			0x00000001
+-/* Set this for a big-endian MPIC */
+-#define MPIC_BIG_ENDIAN			0x00000002
+-/* Broken U3 MPIC */
+-#define MPIC_BROKEN_U3			0x00000004
+-/* Broken IPI registers (autodetected) */
+-#define MPIC_BROKEN_IPI			0x00000008
+-/* MPIC wants a reset */
+-#define MPIC_WANTS_RESET		0x00000010
+-
+-/* Allocate the controller structure and setup the linux irq descs
+- * for the range if interrupts passed in. No HW initialization is
+- * actually performed.
+- * 
+- * @phys_addr:	physial base address of the MPIC
+- * @flags:	flags, see constants above
+- * @isu_size:	number of interrupts in an ISU. Use 0 to use a
+- *              standard ISU-less setup (aka powermac)
+- * @irq_offset: first irq number to assign to this mpic
+- * @irq_count:  number of irqs to use with this mpic IRQ sources. Pass 0
+- *	        to match the number of sources
+- * @ipi_offset: first irq number to assign to this mpic IPI sources,
+- *		used only on primary mpic
+- * @senses:	array of sense values
+- * @senses_num: number of entries in the array
+- *
+- * Note about the sense array. If none is passed, all interrupts are
+- * setup to be level negative unless MPIC_BROKEN_U3 is set in which
+- * case they are edge positive (and the array is ignored anyway).
+- * The values in the array start at the first source of the MPIC,
+- * that is senses[0] correspond to linux irq "irq_offset".
+- */
+-extern struct mpic *mpic_alloc(unsigned long phys_addr,
+-			       unsigned int flags,
+-			       unsigned int isu_size,
+-			       unsigned int irq_offset,
+-			       unsigned int irq_count,
+-			       unsigned int ipi_offset,
+-			       unsigned char *senses,
+-			       unsigned int senses_num,
+-			       const char *name);
+-
+-/* Assign ISUs, to call before mpic_init()
+- *
+- * @mpic:	controller structure as returned by mpic_alloc()
+- * @isu_num:	ISU number
+- * @phys_addr:	physical address of the ISU
+- */
+-extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
+-			    unsigned long phys_addr);
+-
+-/* Initialize the controller. After this has been called, none of the above
+- * should be called again for this mpic
+- */
+-extern void mpic_init(struct mpic *mpic);
+-
+-/* Setup a cascade. Currently, only one cascade is supported this
+- * way, though you can always do a normal request_irq() and add
+- * other cascades this way. You should call this _after_ having
+- * added all the ISUs
+- *
+- * @irq_no:	"linux" irq number of the cascade (that is offset'ed vector)
+- * @handler:	cascade handler function
+- */
+-extern void mpic_setup_cascade(unsigned int irq_no, mpic_cascade_t hanlder,
+-			       void *data);
+-
+-/*
+- * All of the following functions must only be used after the
+- * ISUs have been assigned and the controller fully initialized
+- * with mpic_init()
+- */
+-
+-
+-/* Change/Read the priority of an interrupt. Default is 8 for irqs and
+- * 10 for IPIs. You can call this on both IPIs and IRQ numbers, but the
+- * IPI number is then the offset'ed (linux irq number mapped to the IPI)
+- */
+-extern void mpic_irq_set_priority(unsigned int irq, unsigned int pri);
+-extern unsigned int mpic_irq_get_priority(unsigned int irq);
+-
+-/* Setup a non-boot CPU */
+-extern void mpic_setup_this_cpu(void);
+-
+-/* Clean up for kexec (or cpu offline or ...) */
+-extern void mpic_teardown_this_cpu(int secondary);
+-
+-/* Request IPIs on primary mpic */
+-extern void mpic_request_ipis(void);
+-
+-/* Send an IPI (non offseted number 0..3) */
+-extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
+-
+-/* Fetch interrupt from a given mpic */
+-extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs);
+-/* This one gets to the primary mpic */
+-extern int mpic_get_irq(struct pt_regs *regs);
+-
+-/* global mpic for pSeries */
+-extern struct mpic *pSeries_mpic;
+diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/of_device.c
++++ /dev/null
+@@ -1,274 +0,0 @@
+-#include <linux/config.h>
+-#include <linux/string.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/mod_devicetable.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 &= 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;
+-}
+-
+-struct bus_type of_platform_bus_type = {
+-       .name	= "of_platform",
+-       .match	= of_platform_bus_match,
+-       .suspend	= of_device_suspend,
+-       .resume	= of_device_resume,
+-};
+-
+-static int __init of_bus_driver_init(void)
+-{
+-	return bus_register(&of_platform_bus_type);
+-}
+-
+-postcore_initcall(of_bus_driver_init);
+-
+-int of_register_driver(struct of_platform_driver *drv)
+-{
+-	int count = 0;
+-
+-	/* initialize common driver fields */
+-	drv->driver.name = drv->name;
+-	drv->driver.bus = &of_platform_bus_type;
+-	drv->driver.probe = of_device_probe;
+-	drv->driver.remove = of_device_remove;
+-
+-	/* register with core */
+-	count = driver_register(&drv->driver);
+-	return count ? count : 1;
+-}
+-
+-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;
+-	struct of_device **odprop;
+-
+-	BUG_ON(ofdev->node == NULL);
+-
+-	odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
+-	if (!odprop) {
+-		struct property *new_prop;
+-	
+-		new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *),
+-			GFP_KERNEL);
+-		if (new_prop == NULL)
+-			return -ENOMEM;
+-		new_prop->name = "linux,device";
+-		new_prop->length = sizeof(sizeof(struct of_device *));
+-		new_prop->value = (unsigned char *)&new_prop[1];
+-		odprop = (struct of_device **)new_prop->value;
+-		*odprop = NULL;
+-		prom_add_property(ofdev->node, new_prop);
+-	}
+-	*odprop = ofdev;
+-
+-	rc = device_register(&ofdev->dev);
+-	if (rc)
+-		return rc;
+-
+-	device_create_file(&ofdev->dev, &dev_attr_devspec);
+-
+-	return 0;
+-}
+-
+-void of_device_unregister(struct of_device *ofdev)
+-{
+-	struct of_device **odprop;
+-
+-	device_remove_file(&ofdev->dev, &dev_attr_devspec);
+-
+-	odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
+-	if (odprop)
+-		*odprop = NULL;
+-
+-	device_unregister(&ofdev->dev);
+-}
+-
+-struct of_device* of_platform_device_create(struct device_node *np,
+-					    const char *bus_id,
+-					    struct device *parent)
+-{
+-	struct of_device *dev;
+-
+-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+-	if (!dev)
+-		return NULL;
+-	memset(dev, 0, sizeof(*dev));
+-
+-	dev->node = np;
+-	dev->dma_mask = 0xffffffffUL;
+-	dev->dev.dma_mask = &dev->dma_mask;
+-	dev->dev.parent = parent;
+-	dev->dev.bus = &of_platform_bus_type;
+-	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_platform_bus_type);
+-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/ppc64/kernel/pSeries_hvCall.S b/arch/ppc64/kernel/pSeries_hvCall.S
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pSeries_hvCall.S
++++ /dev/null
+@@ -1,131 +0,0 @@
+-/*
+- * arch/ppc64/kernel/pSeries_hvCall.S
+- *
+- * This file contains the generic code to perform a call to the
+- * pSeries LPAR hypervisor.
+- * NOTE: this file will go away when we move to inline this work.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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/hvcall.h>
+-#include <asm/processor.h>
+-#include <asm/ppc_asm.h>
+-	
+-#define STK_PARM(i)     (48 + ((i)-3)*8)
+-
+-	.text
+-
+-/* long plpar_hcall(unsigned long opcode,		R3
+-			unsigned long arg1,		R4
+-			unsigned long arg2,		R5
+-			unsigned long arg3,		R6
+-			unsigned long arg4,		R7
+-			unsigned long *out1,		R8
+-			unsigned long *out2,		R9
+-			unsigned long *out3);		R10
+- */
+-_GLOBAL(plpar_hcall)
+-	HMT_MEDIUM
+-
+-	mfcr	r0
+-
+-	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
+-	std	r9,STK_PARM(r9)(r1)
+-	std	r10,STK_PARM(r10)(r1)
+-
+-	stw	r0,8(r1)
+-
+-	HVSC				/* invoke the hypervisor */
+-
+-	lwz	r0,8(r1)
+-
+-	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r6 ret args */
+-	ld	r9,STK_PARM(r9)(r1)
+-	ld	r10,STK_PARM(r10)(r1)
+-	std	r4,0(r8)
+-	std	r5,0(r9)
+-	std	r6,0(r10)
+-
+-	mtcrf	0xff,r0
+-	blr				/* return r3 = status */
+-
+-
+-/* Simple interface with no output values (other than status) */
+-_GLOBAL(plpar_hcall_norets)
+-	HMT_MEDIUM
+-
+-	mfcr	r0
+-	stw	r0,8(r1)
+-
+-	HVSC				/* invoke the hypervisor */
+-
+-	lwz	r0,8(r1)
+-	mtcrf	0xff,r0
+-	blr				/* return r3 = status */
+-
+-
+-/* long plpar_hcall_8arg_2ret(unsigned long opcode,	R3
+-			unsigned long arg1,		R4
+-			unsigned long arg2,		R5
+-			unsigned long arg3,		R6
+-			unsigned long arg4,		R7
+-			unsigned long arg5,		R8
+-			unsigned long arg6,		R9
+-			unsigned long arg7,		R10
+-			unsigned long arg8,		112(R1)
+-			unsigned long *out1);		120(R1)
+- */
+-_GLOBAL(plpar_hcall_8arg_2ret)
+-	HMT_MEDIUM
+-
+-	mfcr	r0
+-	ld	r11,STK_PARM(r11)(r1)	/* put arg8 in R11 */
+-	stw	r0,8(r1)
+-
+-	HVSC				/* invoke the hypervisor */
+-
+-	lwz	r0,8(r1)
+-	ld	r10,STK_PARM(r12)(r1)	/* Fetch r4 ret arg */
+-	std	r4,0(r10)
+-	mtcrf	0xff,r0
+-	blr				/* return r3 = status */
+-
+-
+-/* long plpar_hcall_4out(unsigned long opcode,		R3
+-		 	unsigned long arg1,		R4
+-		 	unsigned long arg2,		R5
+-		 	unsigned long arg3,		R6
+-		 	unsigned long arg4,		R7
+-		 	unsigned long *out1,		R8
+-		 	unsigned long *out2,		R9
+-		 	unsigned long *out3,		R10
+-		 	unsigned long *out4);		112(R1)
+- */
+-_GLOBAL(plpar_hcall_4out)
+-	HMT_MEDIUM
+-
+-	mfcr	r0
+-	stw	r0,8(r1)
+-
+-	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
+-	std	r9,STK_PARM(r9)(r1)
+-	std	r10,STK_PARM(r10)(r1)
+-
+-	HVSC				/* invoke the hypervisor */
+-
+-	lwz	r0,8(r1)
+-
+-	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r7 ret args */
+-	ld	r9,STK_PARM(r9)(r1)
+-	ld	r10,STK_PARM(r10)(r1)
+-	ld	r11,STK_PARM(r11)(r1)
+-	std	r4,0(r8)
+-	std	r5,0(r9)
+-	std	r6,0(r10)
+-	std	r7,0(r11)
+-
+-	mtcrf	0xff,r0
+-	blr				/* return r3 = status */
+diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pSeries_iommu.c
++++ /dev/null
+@@ -1,590 +0,0 @@
+-/*
+- * arch/ppc64/kernel/pSeries_iommu.c
+- *
+- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+- *
+- * Rewrite, cleanup: 
+- *
+- * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, IBM Corporation
+- *
+- * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR.
+- *
+- * 
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the 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/config.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/pci.h>
+-#include <linux/dma-mapping.h>
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/rtas.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/iommu.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/machdep.h>
+-#include <asm/abs_addr.h>
+-#include <asm/plpar_wrappers.h>
+-#include <asm/pSeries_reconfig.h>
+-#include <asm/systemcfg.h>
+-#include <asm/firmware.h>
+-#include "pci.h"
+-
+-#define DBG(fmt...)
+-
+-extern int is_python(struct device_node *);
+-
+-static void tce_build_pSeries(struct iommu_table *tbl, long index, 
+-			      long npages, unsigned long uaddr, 
+-			      enum dma_data_direction direction)
+-{
+-	union tce_entry t;
+-	union tce_entry *tp;
+-
+-	t.te_word = 0;
+-	t.te_rdwr = 1; // Read allowed 
+-
+-	if (direction != DMA_TO_DEVICE)
+-		t.te_pciwr = 1;
+-
+-	tp = ((union tce_entry *)tbl->it_base) + index;
+-
+-	while (npages--) {
+-		/* can't move this out since we might cross LMB boundary */
+-		t.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+-	
+-		tp->te_word = t.te_word;
+-
+-		uaddr += PAGE_SIZE;
+-		tp++;
+-	}
+-}
+-
+-
+-static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
+-{
+-	union tce_entry t;
+-	union tce_entry *tp;
+-
+-	t.te_word = 0;
+-	tp  = ((union tce_entry *)tbl->it_base) + index;
+-		
+-	while (npages--) {
+-		tp->te_word = t.te_word;
+-		
+-		tp++;
+-	}
+-}
+-
+-
+-static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
+-				long npages, unsigned long uaddr,
+-				enum dma_data_direction direction)
+-{
+-	u64 rc;
+-	union tce_entry tce;
+-
+-	tce.te_word = 0;
+-	tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+-	tce.te_rdwr = 1;
+-	if (direction != DMA_TO_DEVICE)
+-		tce.te_pciwr = 1;
+-
+-	while (npages--) {
+-		rc = plpar_tce_put((u64)tbl->it_index, 
+-				   (u64)tcenum << 12, 
+-				   tce.te_word );
+-		
+-		if (rc && printk_ratelimit()) {
+-			printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
+-			printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
+-			printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
+-			printk("\ttce val = 0x%lx\n", tce.te_word );
+-			show_stack(current, (unsigned long *)__get_SP());
+-		}
+-			
+-		tcenum++;
+-		tce.te_rpn++;
+-	}
+-}
+-
+-static DEFINE_PER_CPU(void *, tce_page) = NULL;
+-
+-static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
+-				     long npages, unsigned long uaddr,
+-				     enum dma_data_direction direction)
+-{
+-	u64 rc;
+-	union tce_entry tce, *tcep;
+-	long l, limit;
+-
+-	if (npages == 1)
+-		return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
+-					   direction);
+-
+-	tcep = __get_cpu_var(tce_page);
+-
+-	/* This is safe to do since interrupts are off when we're called
+-	 * from iommu_alloc{,_sg}()
+-	 */
+-	if (!tcep) {
+-		tcep = (void *)__get_free_page(GFP_ATOMIC);
+-		/* If allocation fails, fall back to the loop implementation */
+-		if (!tcep)
+-			return tce_build_pSeriesLP(tbl, tcenum, npages,
+-						   uaddr, direction);
+-		__get_cpu_var(tce_page) = tcep;
+-	}
+-
+-	tce.te_word = 0;
+-	tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+-	tce.te_rdwr = 1;
+-	if (direction != DMA_TO_DEVICE)
+-		tce.te_pciwr = 1;
+-
+-	/* We can map max one pageful of TCEs at a time */
+-	do {
+-		/*
+-		 * Set up the page with TCE data, looping through and setting
+-		 * the values.
+-		 */
+-		limit = min_t(long, npages, PAGE_SIZE/sizeof(union tce_entry));
+-
+-		for (l = 0; l < limit; l++) {
+-			tcep[l] = tce;
+-			tce.te_rpn++;
+-		}
+-
+-		rc = plpar_tce_put_indirect((u64)tbl->it_index,
+-					    (u64)tcenum << 12,
+-					    (u64)virt_to_abs(tcep),
+-					    limit);
+-
+-		npages -= limit;
+-		tcenum += limit;
+-	} while (npages > 0 && !rc);
+-
+-	if (rc && printk_ratelimit()) {
+-		printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
+-		printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
+-		printk("\tnpages  = 0x%lx\n", (u64)npages);
+-		printk("\ttce[0] val = 0x%lx\n", tcep[0].te_word);
+-		show_stack(current, (unsigned long *)__get_SP());
+-	}
+-}
+-
+-static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
+-{
+-	u64 rc;
+-	union tce_entry tce;
+-
+-	tce.te_word = 0;
+-
+-	while (npages--) {
+-		rc = plpar_tce_put((u64)tbl->it_index,
+-				   (u64)tcenum << 12,
+-				   tce.te_word);
+-
+-		if (rc && printk_ratelimit()) {
+-			printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
+-			printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
+-			printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
+-			printk("\ttce val = 0x%lx\n", tce.te_word );
+-			show_stack(current, (unsigned long *)__get_SP());
+-		}
+-
+-		tcenum++;
+-	}
+-}
+-
+-
+-static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
+-{
+-	u64 rc;
+-	union tce_entry tce;
+-
+-	tce.te_word = 0;
+-
+-	rc = plpar_tce_stuff((u64)tbl->it_index,
+-			   (u64)tcenum << 12,
+-			   tce.te_word,
+-			   npages);
+-
+-	if (rc && printk_ratelimit()) {
+-		printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n");
+-		printk("\trc      = %ld\n", rc);
+-		printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
+-		printk("\tnpages  = 0x%lx\n", (u64)npages);
+-		printk("\ttce val = 0x%lx\n", tce.te_word );
+-		show_stack(current, (unsigned long *)__get_SP());
+-	}
+-}
+-
+-static void iommu_table_setparms(struct pci_controller *phb,
+-				 struct device_node *dn,
+-				 struct iommu_table *tbl) 
+-{
+-	struct device_node *node;
+-	unsigned long *basep;
+-	unsigned int *sizep;
+-
+-	node = (struct device_node *)phb->arch_data;
+-
+-	basep = (unsigned long *)get_property(node, "linux,tce-base", NULL);
+-	sizep = (unsigned int *)get_property(node, "linux,tce-size", NULL);
+-	if (basep == NULL || sizep == NULL) {
+-		printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has "
+-				"missing tce entries !\n", dn->full_name);
+-		return;
+-	}
+-
+-	tbl->it_base = (unsigned long)__va(*basep);
+-	memset((void *)tbl->it_base, 0, *sizep);
+-
+-	tbl->it_busno = phb->bus->number;
+-	
+-	/* Units of tce entries */
+-	tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
+-	
+-	/* Test if we are going over 2GB of DMA space */
+-	if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
+-		udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
+-		panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 
+-	}
+-	
+-	phb->dma_window_base_cur += phb->dma_window_size;
+-
+-	/* Set the tce table size - measured in entries */
+-	tbl->it_size = phb->dma_window_size >> PAGE_SHIFT;
+-
+-	tbl->it_index = 0;
+-	tbl->it_blocksize = 16;
+-	tbl->it_type = TCE_PCI;
+-}
+-
+-/*
+- * iommu_table_setparms_lpar
+- *
+- * Function: On pSeries LPAR systems, return TCE table info, given a pci bus.
+- *
+- * ToDo: properly interpret the ibm,dma-window property.  The definition is:
+- *	logical-bus-number	(1 word)
+- *	phys-address		(#address-cells words)
+- *	size			(#cell-size words)
+- *
+- * Currently we hard code these sizes (more or less).
+- */
+-static void iommu_table_setparms_lpar(struct pci_controller *phb,
+-				      struct device_node *dn,
+-				      struct iommu_table *tbl,
+-				      unsigned int *dma_window)
+-{
+-	tbl->it_busno  = PCI_DN(dn)->bussubno;
+-
+-	/* TODO: Parse field size properties properly. */
+-	tbl->it_size   = (((unsigned long)dma_window[4] << 32) |
+-			   (unsigned long)dma_window[5]) >> PAGE_SHIFT;
+-	tbl->it_offset = (((unsigned long)dma_window[2] << 32) |
+-			   (unsigned long)dma_window[3]) >> PAGE_SHIFT;
+-	tbl->it_base   = 0;
+-	tbl->it_index  = dma_window[0];
+-	tbl->it_blocksize  = 16;
+-	tbl->it_type = TCE_PCI;
+-}
+-
+-static void iommu_bus_setup_pSeries(struct pci_bus *bus)
+-{
+-	struct device_node *dn;
+-	struct iommu_table *tbl;
+-	struct device_node *isa_dn, *isa_dn_orig;
+-	struct device_node *tmp;
+-	struct pci_dn *pci;
+-	int children;
+-
+-	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
+-
+-	dn = pci_bus_to_OF_node(bus);
+-	pci = PCI_DN(dn);
+-
+-	if (bus->self) {
+-		/* This is not a root bus, any setup will be done for the
+-		 * device-side of the bridge in iommu_dev_setup_pSeries().
+-		 */
+-		return;
+-	}
+-
+-	/* Check if the ISA bus on the system is under
+-	 * this PHB.
+-	 */
+-	isa_dn = isa_dn_orig = of_find_node_by_type(NULL, "isa");
+-
+-	while (isa_dn && isa_dn != dn)
+-		isa_dn = isa_dn->parent;
+-
+-	if (isa_dn_orig)
+-		of_node_put(isa_dn_orig);
+-
+-	/* Count number of direct PCI children of the PHB.
+-	 * All PCI device nodes have class-code property, so it's
+-	 * an easy way to find them.
+-	 */
+-	for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
+-		if (get_property(tmp, "class-code", NULL))
+-			children++;
+-
+-	DBG("Children: %d\n", children);
+-
+-	/* Calculate amount of DMA window per slot. Each window must be
+-	 * a power of two (due to pci_alloc_consistent requirements).
+-	 *
+-	 * Keep 256MB aside for PHBs with ISA.
+-	 */
+-
+-	if (!isa_dn) {
+-		/* No ISA/IDE - just set window size and return */
+-		pci->phb->dma_window_size = 0x80000000ul; /* To be divided */
+-
+-		while (pci->phb->dma_window_size * children > 0x80000000ul)
+-			pci->phb->dma_window_size >>= 1;
+-		DBG("No ISA/IDE, window size is 0x%lx\n",
+-			pci->phb->dma_window_size);
+-		pci->phb->dma_window_base_cur = 0;
+-
+-		return;
+-	}
+-
+-	/* If we have ISA, then we probably have an IDE
+-	 * controller too. Allocate a 128MB table but
+-	 * skip the first 128MB to avoid stepping on ISA
+-	 * space.
+-	 */
+-	pci->phb->dma_window_size = 0x8000000ul;
+-	pci->phb->dma_window_base_cur = 0x8000000ul;
+-
+-	tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+-
+-	iommu_table_setparms(pci->phb, dn, tbl);
+-	pci->iommu_table = iommu_init_table(tbl);
+-
+-	/* Divide the rest (1.75GB) among the children */
+-	pci->phb->dma_window_size = 0x80000000ul;
+-	while (pci->phb->dma_window_size * children > 0x70000000ul)
+-		pci->phb->dma_window_size >>= 1;
+-
+-	DBG("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);
+-
+-}
+-
+-
+-static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
+-{
+-	struct iommu_table *tbl;
+-	struct device_node *dn, *pdn;
+-	struct pci_dn *ppci;
+-	unsigned int *dma_window = NULL;
+-
+-	DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
+-
+-	dn = pci_bus_to_OF_node(bus);
+-
+-	/* Find nearest ibm,dma-window, walking up the device tree */
+-	for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
+-		dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
+-		if (dma_window != NULL)
+-			break;
+-	}
+-
+-	if (dma_window == NULL) {
+-		DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name);
+-		return;
+-	}
+-
+-	ppci = pdn->data;
+-	if (!ppci->iommu_table) {
+-		/* Bussubno hasn't been copied yet.
+-		 * Do it now because iommu_table_setparms_lpar needs it.
+-		 */
+-
+-		ppci->bussubno = bus->number;
+-
+-		tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
+-						    GFP_KERNEL);
+-	
+-		iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
+-
+-		ppci->iommu_table = iommu_init_table(tbl);
+-	}
+-
+-	if (pdn != dn)
+-		PCI_DN(dn)->iommu_table = ppci->iommu_table;
+-}
+-
+-
+-static void iommu_dev_setup_pSeries(struct pci_dev *dev)
+-{
+-	struct device_node *dn, *mydn;
+-	struct iommu_table *tbl;
+-
+-	DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev));
+-
+-	mydn = dn = pci_device_to_OF_node(dev);
+-
+-	/* If we're the direct child of a root bus, then we need to allocate
+-	 * an iommu table ourselves. The bus setup code should have setup
+-	 * the window sizes already.
+-	 */
+-	if (!dev->bus->self) {
+-		DBG(" --> first child, no bridge. Allocating iommu table.\n");
+-		tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+-		iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
+-		PCI_DN(mydn)->iommu_table = iommu_init_table(tbl);
+-
+-		return;
+-	}
+-
+-	/* If this device is further down the bus tree, search upwards until
+-	 * an already allocated iommu table is found and use that.
+-	 */
+-
+-	while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)
+-		dn = dn->parent;
+-
+-	if (dn && dn->data) {
+-		PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
+-	} else {
+-		DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev));
+-	}
+-}
+-
+-static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
+-{
+-	int err = NOTIFY_OK;
+-	struct device_node *np = node;
+-	struct pci_dn *pci = np->data;
+-
+-	switch (action) {
+-	case PSERIES_RECONFIG_REMOVE:
+-		if (pci->iommu_table &&
+-		    get_property(np, "ibm,dma-window", NULL))
+-			iommu_free_table(np);
+-		break;
+-	default:
+-		err = NOTIFY_DONE;
+-		break;
+-	}
+-	return err;
+-}
+-
+-static struct notifier_block iommu_reconfig_nb = {
+-	.notifier_call = iommu_reconfig_notifier,
+-};
+-
+-static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
+-{
+-	struct device_node *pdn, *dn;
+-	struct iommu_table *tbl;
+-	int *dma_window = NULL;
+-	struct pci_dn *pci;
+-
+-	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
+-
+-	/* dev setup for LPAR is a little tricky, since the device tree might
+-	 * contain the dma-window properties per-device and not neccesarily
+-	 * for the bus. So we need to search upwards in the tree until we
+-	 * either hit a dma-window property, OR find a parent with a table
+-	 * already allocated.
+-	 */
+-	dn = pci_device_to_OF_node(dev);
+-
+-	for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table;
+-	     pdn = pdn->parent) {
+-		dma_window = (unsigned int *)
+-			get_property(pdn, "ibm,dma-window", NULL);
+-		if (dma_window)
+-			break;
+-	}
+-
+-	/* Check for parent == NULL so we don't try to setup the empty EADS
+-	 * slots on POWER4 machines.
+-	 */
+-	if (dma_window == NULL || pdn->parent == NULL) {
+-		DBG("No dma window for device, linking to parent\n");
+-		PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table;
+-		return;
+-	} else {
+-		DBG("Found DMA window, allocating table\n");
+-	}
+-
+-	pci = pdn->data;
+-	if (!pci->iommu_table) {
+-		/* iommu_table_setparms_lpar needs bussubno. */
+-		pci->bussubno = pci->phb->bus->number;
+-
+-		tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
+-						    GFP_KERNEL);
+-
+-		iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
+-
+-		pci->iommu_table = iommu_init_table(tbl);
+-	}
+-
+-	if (pdn != dn)
+-		PCI_DN(dn)->iommu_table = pci->iommu_table;
+-}
+-
+-static void iommu_bus_setup_null(struct pci_bus *b) { }
+-static void iommu_dev_setup_null(struct pci_dev *d) { }
+-
+-/* These are called very early. */
+-void iommu_init_early_pSeries(void)
+-{
+-	if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) {
+-		/* Direct I/O, IOMMU off */
+-		ppc_md.iommu_dev_setup = iommu_dev_setup_null;
+-		ppc_md.iommu_bus_setup = iommu_bus_setup_null;
+-		pci_direct_iommu_init();
+-
+-		return;
+-	}
+-
+-	if (systemcfg->platform & PLATFORM_LPAR) {
+-		if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
+-			ppc_md.tce_build = tce_buildmulti_pSeriesLP;
+-			ppc_md.tce_free	 = tce_freemulti_pSeriesLP;
+-		} else {
+-			ppc_md.tce_build = tce_build_pSeriesLP;
+-			ppc_md.tce_free	 = tce_free_pSeriesLP;
+-		}
+-		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP;
+-		ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP;
+-	} else {
+-		ppc_md.tce_build = tce_build_pSeries;
+-		ppc_md.tce_free  = tce_free_pSeries;
+-		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries;
+-		ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries;
+-	}
+-
+-
+-	pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
+-
+-	pci_iommu_init();
+-}
+-
+diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pSeries_lpar.c
++++ /dev/null
+@@ -1,518 +0,0 @@
+-/*
+- * pSeries_lpar.c
+- * Copyright (C) 2001 Todd Inglett, IBM Corporation
+- *
+- * pSeries LPAR 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
+- */
+-
+-#define DEBUG
+-
+-#include <linux/config.h>
+-#include <linux/kernel.h>
+-#include <linux/dma-mapping.h>
+-#include <asm/processor.h>
+-#include <asm/mmu.h>
+-#include <asm/page.h>
+-#include <asm/pgtable.h>
+-#include <asm/machdep.h>
+-#include <asm/abs_addr.h>
+-#include <asm/mmu_context.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/iommu.h>
+-#include <asm/tlbflush.h>
+-#include <asm/tlb.h>
+-#include <asm/prom.h>
+-#include <asm/abs_addr.h>
+-#include <asm/cputable.h>
+-#include <asm/plpar_wrappers.h>
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) udbg_printf(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-/* in pSeries_hvCall.S */
+-EXPORT_SYMBOL(plpar_hcall);
+-EXPORT_SYMBOL(plpar_hcall_4out);
+-EXPORT_SYMBOL(plpar_hcall_norets);
+-EXPORT_SYMBOL(plpar_hcall_8arg_2ret);
+-
+-extern void pSeries_find_serial_port(void);
+-
+-
+-int vtermno;	/* virtual terminal# for udbg  */
+-
+-#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
+-static void udbg_hvsi_putc(unsigned char c)
+-{
+-	/* packet's seqno isn't used anyways */
+-	uint8_t packet[] __ALIGNED__ = { 0xff, 5, 0, 0, c };
+-	int rc;
+-
+-	if (c == '\n')
+-		udbg_hvsi_putc('\r');
+-
+-	do {
+-		rc = plpar_put_term_char(vtermno, sizeof(packet), packet);
+-	} while (rc == H_Busy);
+-}
+-
+-static long hvsi_udbg_buf_len;
+-static uint8_t hvsi_udbg_buf[256];
+-
+-static int udbg_hvsi_getc_poll(void)
+-{
+-	unsigned char ch;
+-	int rc, i;
+-
+-	if (hvsi_udbg_buf_len == 0) {
+-		rc = plpar_get_term_char(vtermno, &hvsi_udbg_buf_len, hvsi_udbg_buf);
+-		if (rc != H_Success || hvsi_udbg_buf[0] != 0xff) {
+-			/* bad read or non-data packet */
+-			hvsi_udbg_buf_len = 0;
+-		} else {
+-			/* remove the packet header */
+-			for (i = 4; i < hvsi_udbg_buf_len; i++)
+-				hvsi_udbg_buf[i-4] = hvsi_udbg_buf[i];
+-			hvsi_udbg_buf_len -= 4;
+-		}
+-	}
+-
+-	if (hvsi_udbg_buf_len <= 0 || hvsi_udbg_buf_len > 256) {
+-		/* no data ready */
+-		hvsi_udbg_buf_len = 0;
+-		return -1;
+-	}
+-
+-	ch = hvsi_udbg_buf[0];
+-	/* shift remaining data down */
+-	for (i = 1; i < hvsi_udbg_buf_len; i++) {
+-		hvsi_udbg_buf[i-1] = hvsi_udbg_buf[i];
+-	}
+-	hvsi_udbg_buf_len--;
+-
+-	return ch;
+-}
+-
+-static unsigned char udbg_hvsi_getc(void)
+-{
+-	int ch;
+-	for (;;) {
+-		ch = udbg_hvsi_getc_poll();
+-		if (ch == -1) {
+-			/* This shouldn't be needed...but... */
+-			volatile unsigned long delay;
+-			for (delay=0; delay < 2000000; delay++)
+-				;
+-		} else {
+-			return ch;
+-		}
+-	}
+-}
+-
+-static void udbg_putcLP(unsigned char c)
+-{
+-	char buf[16];
+-	unsigned long rc;
+-
+-	if (c == '\n')
+-		udbg_putcLP('\r');
+-
+-	buf[0] = c;
+-	do {
+-		rc = plpar_put_term_char(vtermno, 1, buf);
+-	} while(rc == H_Busy);
+-}
+-
+-/* Buffered chars getc */
+-static long inbuflen;
+-static long inbuf[2];	/* must be 2 longs */
+-
+-static int udbg_getc_pollLP(void)
+-{
+-	/* The interface is tricky because it may return up to 16 chars.
+-	 * We save them statically for future calls to udbg_getc().
+-	 */
+-	char ch, *buf = (char *)inbuf;
+-	int i;
+-	long rc;
+-	if (inbuflen == 0) {
+-		/* get some more chars. */
+-		inbuflen = 0;
+-		rc = plpar_get_term_char(vtermno, &inbuflen, buf);
+-		if (rc != H_Success)
+-			inbuflen = 0;	/* otherwise inbuflen is garbage */
+-	}
+-	if (inbuflen <= 0 || inbuflen > 16) {
+-		/* Catch error case as well as other oddities (corruption) */
+-		inbuflen = 0;
+-		return -1;
+-	}
+-	ch = buf[0];
+-	for (i = 1; i < inbuflen; i++)	/* shuffle them down. */
+-		buf[i-1] = buf[i];
+-	inbuflen--;
+-	return ch;
+-}
+-
+-static unsigned char udbg_getcLP(void)
+-{
+-	int ch;
+-	for (;;) {
+-		ch = udbg_getc_pollLP();
+-		if (ch == -1) {
+-			/* This shouldn't be needed...but... */
+-			volatile unsigned long delay;
+-			for (delay=0; delay < 2000000; delay++)
+-				;
+-		} else {
+-			return ch;
+-		}
+-	}
+-}
+-
+-/* call this from early_init() for a working debug console on
+- * vterm capable LPAR machines
+- */
+-void udbg_init_debug_lpar(void)
+-{
+-	vtermno = 0;
+-	udbg_putc = udbg_putcLP;
+-	udbg_getc = udbg_getcLP;
+-	udbg_getc_poll = udbg_getc_pollLP;
+-}
+-
+-/* returns 0 if couldn't find or use /chosen/stdout as console */
+-int find_udbg_vterm(void)
+-{
+-	struct device_node *stdout_node;
+-	u32 *termno;
+-	char *name;
+-	int found = 0;
+-
+-	/* find the boot console from /chosen/stdout */
+-	if (!of_chosen)
+-		return 0;
+-	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+-	if (name == NULL)
+-		return 0;
+-	stdout_node = of_find_node_by_path(name);
+-	if (!stdout_node)
+-		return 0;
+-
+-	/* now we have the stdout node; figure out what type of device it is. */
+-	name = (char *)get_property(stdout_node, "name", NULL);
+-	if (!name) {
+-		printk(KERN_WARNING "stdout node missing 'name' property!\n");
+-		goto out;
+-	}
+-
+-	if (strncmp(name, "vty", 3) == 0) {
+-		if (device_is_compatible(stdout_node, "hvterm1")) {
+-			termno = (u32 *)get_property(stdout_node, "reg", NULL);
+-			if (termno) {
+-				vtermno = termno[0];
+-				udbg_putc = udbg_putcLP;
+-				udbg_getc = udbg_getcLP;
+-				udbg_getc_poll = udbg_getc_pollLP;
+-				found = 1;
+-			}
+-		} else if (device_is_compatible(stdout_node, "hvterm-protocol")) {
+-			termno = (u32 *)get_property(stdout_node, "reg", NULL);
+-			if (termno) {
+-				vtermno = termno[0];
+-				udbg_putc = udbg_hvsi_putc;
+-				udbg_getc = udbg_hvsi_getc;
+-				udbg_getc_poll = udbg_hvsi_getc_poll;
+-				found = 1;
+-			}
+-		}
+-	} else if (strncmp(name, "serial", 6)) {
+-		/* XXX fix ISA serial console */
+-		printk(KERN_WARNING "serial stdout on LPAR ('%s')! "
+-				"can't print udbg messages\n",
+-		       stdout_node->full_name);
+-	} else {
+-		printk(KERN_WARNING "don't know how to print to stdout '%s'\n",
+-		       stdout_node->full_name);
+-	}
+-
+-out:
+-	of_node_put(stdout_node);
+-	return found;
+-}
+-
+-void vpa_init(int cpu)
+-{
+-	int hwcpu = get_hard_smp_processor_id(cpu);
+-	unsigned long vpa = (unsigned long)&(paca[cpu].lppaca);
+-	long ret;
+-	unsigned long flags;
+-
+-	/* Register the Virtual Processor Area (VPA) */
+-	flags = 1UL << (63 - 18);
+-
+-	if (cpu_has_feature(CPU_FTR_ALTIVEC))
+-		paca[cpu].lppaca.vmxregs_in_use = 1;
+-
+-	ret = register_vpa(flags, hwcpu, __pa(vpa));
+-
+-	if (ret)
+-		printk(KERN_ERR "WARNING: vpa_init: VPA registration for "
+-				"cpu %d (hw %d) of area %lx returns %ld\n",
+-				cpu, hwcpu, __pa(vpa), ret);
+-}
+-
+-long pSeries_lpar_hpte_insert(unsigned long hpte_group,
+-			      unsigned long va, unsigned long prpn,
+-			      unsigned long vflags, unsigned long rflags)
+-{
+-	unsigned long lpar_rc;
+-	unsigned long flags;
+-	unsigned long slot;
+-	unsigned long hpte_v, hpte_r;
+-	unsigned long dummy0, dummy1;
+-
+-	hpte_v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | vflags | HPTE_V_VALID;
+-	if (vflags & HPTE_V_LARGE)
+-		hpte_v &= ~(1UL << HPTE_V_AVPN_SHIFT);
+-
+-	hpte_r = (prpn << HPTE_R_RPN_SHIFT) | rflags;
+-
+-	/* Now fill in the actual HPTE */
+-	/* Set CEC cookie to 0         */
+-	/* Zero page = 0               */
+-	/* I-cache Invalidate = 0      */
+-	/* I-cache synchronize = 0     */
+-	/* Exact = 0                   */
+-	flags = 0;
+-
+-	/* XXX why is this here? - Anton */
+-	if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
+-		hpte_r &= ~_PAGE_COHERENT;
+-
+-	lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v,
+-			      hpte_r, &slot, &dummy0, &dummy1);
+-
+-	if (unlikely(lpar_rc == H_PTEG_Full))
+-		return -1;
+-
+-	/*
+-	 * Since we try and ioremap PHBs we don't own, the pte insert
+-	 * will fail. However we must catch the failure in hash_page
+-	 * or we will loop forever, so return -2 in this case.
+-	 */
+-	if (unlikely(lpar_rc != H_Success))
+-		return -2;
+-
+-	/* Because of iSeries, we have to pass down the secondary
+-	 * bucket bit here as well
+-	 */
+-	return (slot & 7) | (!!(vflags & HPTE_V_SECONDARY) << 3);
+-}
+-
+-static DEFINE_SPINLOCK(pSeries_lpar_tlbie_lock);
+-
+-static long pSeries_lpar_hpte_remove(unsigned long hpte_group)
+-{
+-	unsigned long slot_offset;
+-	unsigned long lpar_rc;
+-	int i;
+-	unsigned long dummy1, dummy2;
+-
+-	/* pick a random slot to start at */
+-	slot_offset = mftb() & 0x7;
+-
+-	for (i = 0; i < HPTES_PER_GROUP; i++) {
+-
+-		/* don't remove a bolted entry */
+-		lpar_rc = plpar_pte_remove(H_ANDCOND, hpte_group + slot_offset,
+-					   (0x1UL << 4), &dummy1, &dummy2);
+-
+-		if (lpar_rc == H_Success)
+-			return i;
+-
+-		BUG_ON(lpar_rc != H_Not_Found);
+-
+-		slot_offset++;
+-		slot_offset &= 0x7;
+-	}
+-
+-	return -1;
+-}
+-
+-static void pSeries_lpar_hptab_clear(void)
+-{
+-	unsigned long size_bytes = 1UL << ppc64_pft_size;
+-	unsigned long hpte_count = size_bytes >> 4;
+-	unsigned long dummy1, dummy2;
+-	int i;
+-
+-	/* TODO: Use bulk call */
+-	for (i = 0; i < hpte_count; i++)
+-		plpar_pte_remove(0, i, 0, &dummy1, &dummy2);
+-}
+-
+-/*
+- * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
+- * the low 3 bits of flags happen to line up.  So no transform is needed.
+- * We can probably optimize here and assume the high bits of newpp are
+- * already zero.  For now I am paranoid.
+- */
+-static long pSeries_lpar_hpte_updatepp(unsigned long slot, unsigned long newpp,
+-				       unsigned long va, int large, int local)
+-{
+-	unsigned long lpar_rc;
+-	unsigned long flags = (newpp & 7) | H_AVPN;
+-	unsigned long avpn = va >> 23;
+-
+-	if (large)
+-		avpn &= ~0x1UL;
+-
+-	lpar_rc = plpar_pte_protect(flags, slot, (avpn << 7));
+-
+-	if (lpar_rc == H_Not_Found)
+-		return -1;
+-
+-	BUG_ON(lpar_rc != H_Success);
+-
+-	return 0;
+-}
+-
+-static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot)
+-{
+-	unsigned long dword0;
+-	unsigned long lpar_rc;
+-	unsigned long dummy_word1;
+-	unsigned long flags;
+-
+-	/* Read 1 pte at a time                        */
+-	/* Do not need RPN to logical page translation */
+-	/* No cross CEC PFT access                     */
+-	flags = 0;
+-
+-	lpar_rc = plpar_pte_read(flags, slot, &dword0, &dummy_word1);
+-
+-	BUG_ON(lpar_rc != H_Success);
+-
+-	return dword0;
+-}
+-
+-static long pSeries_lpar_hpte_find(unsigned long vpn)
+-{
+-	unsigned long hash;
+-	unsigned long i, j;
+-	long slot;
+-	unsigned long hpte_v;
+-
+-	hash = hpt_hash(vpn, 0);
+-
+-	for (j = 0; j < 2; j++) {
+-		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+-		for (i = 0; i < HPTES_PER_GROUP; i++) {
+-			hpte_v = pSeries_lpar_hpte_getword0(slot);
+-
+-			if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
+-			    && (hpte_v & HPTE_V_VALID)
+-			    && (!!(hpte_v & HPTE_V_SECONDARY) == j)) {
+-				/* HPTE matches */
+-				if (j)
+-					slot = -slot;
+-				return slot;
+-			}
+-			++slot;
+-		}
+-		hash = ~hash;
+-	}
+-
+-	return -1;
+-} 
+-
+-static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
+-					     unsigned long ea)
+-{
+-	unsigned long lpar_rc;
+-	unsigned long vsid, va, vpn, flags;
+-	long slot;
+-
+-	vsid = get_kernel_vsid(ea);
+-	va = (vsid << 28) | (ea & 0x0fffffff);
+-	vpn = va >> PAGE_SHIFT;
+-
+-	slot = pSeries_lpar_hpte_find(vpn);
+-	BUG_ON(slot == -1);
+-
+-	flags = newpp & 7;
+-	lpar_rc = plpar_pte_protect(flags, slot, 0);
+-
+-	BUG_ON(lpar_rc != H_Success);
+-}
+-
+-static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
+-					 int large, int local)
+-{
+-	unsigned long avpn = va >> 23;
+-	unsigned long lpar_rc;
+-	unsigned long dummy1, dummy2;
+-
+-	if (large)
+-		avpn &= ~0x1UL;
+-
+-	lpar_rc = plpar_pte_remove(H_AVPN, slot, (avpn << 7), &dummy1,
+-				   &dummy2);
+-
+-	if (lpar_rc == H_Not_Found)
+-		return;
+-
+-	BUG_ON(lpar_rc != H_Success);
+-}
+-
+-/*
+- * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
+- * lock.
+- */
+-void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number,
+-				   int local)
+-{
+-	int i;
+-	unsigned long flags = 0;
+-	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
+-	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
+-
+-	if (lock_tlbie)
+-		spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
+-
+-	for (i = 0; i < number; i++)
+-		flush_hash_page(context, batch->addr[i], batch->pte[i], local);
+-
+-	if (lock_tlbie)
+-		spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
+-}
+-
+-void hpte_init_lpar(void)
+-{
+-	ppc_md.hpte_invalidate	= pSeries_lpar_hpte_invalidate;
+-	ppc_md.hpte_updatepp	= pSeries_lpar_hpte_updatepp;
+-	ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp;
+-	ppc_md.hpte_insert	= pSeries_lpar_hpte_insert;
+-	ppc_md.hpte_remove	= pSeries_lpar_hpte_remove;
+-	ppc_md.flush_hash_range	= pSeries_lpar_flush_hash_range;
+-	ppc_md.hpte_clear_all   = pSeries_lpar_hptab_clear;
+-
+-	htab_finish_init();
+-}
+diff --git a/arch/ppc64/kernel/pSeries_nvram.c b/arch/ppc64/kernel/pSeries_nvram.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pSeries_nvram.c
++++ /dev/null
+@@ -1,148 +0,0 @@
+-/*
+- *  c 2001 PPC 64 Team, IBM Corp
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the GNU General Public License
+- *      as published by the Free Software Foundation; either version
+- *      2 of the License, or (at your option) any later version.
+- *
+- * /dev/nvram driver for PPC64
+- *
+- * This perhaps should live in drivers/char
+- */
+-
+-
+-#include <linux/types.h>
+-#include <linux/errno.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <linux/spinlock.h>
+-#include <asm/uaccess.h>
+-#include <asm/nvram.h>
+-#include <asm/rtas.h>
+-#include <asm/prom.h>
+-#include <asm/machdep.h>
+-
+-static unsigned int nvram_size;
+-static int nvram_fetch, nvram_store;
+-static char nvram_buf[NVRW_CNT];	/* assume this is in the first 4GB */
+-static DEFINE_SPINLOCK(nvram_lock);
+-
+-
+-static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
+-{
+-	unsigned int i;
+-	unsigned long len;
+-	int done;
+-	unsigned long flags;
+-	char *p = buf;
+-
+-
+-	if (nvram_size == 0 || nvram_fetch == RTAS_UNKNOWN_SERVICE)
+-		return -ENODEV;
+-
+-	if (*index >= nvram_size)
+-		return 0;
+-
+-	i = *index;
+-	if (i + count > nvram_size)
+-		count = nvram_size - i;
+-
+-	spin_lock_irqsave(&nvram_lock, flags);
+-
+-	for (; count != 0; count -= len) {
+-		len = count;
+-		if (len > NVRW_CNT)
+-			len = NVRW_CNT;
+-		
+-		if ((rtas_call(nvram_fetch, 3, 2, &done, i, __pa(nvram_buf),
+-			       len) != 0) || len != done) {
+-			spin_unlock_irqrestore(&nvram_lock, flags);
+-			return -EIO;
+-		}
+-		
+-		memcpy(p, nvram_buf, len);
+-
+-		p += len;
+-		i += len;
+-	}
+-
+-	spin_unlock_irqrestore(&nvram_lock, flags);
+-	
+-	*index = i;
+-	return p - buf;
+-}
+-
+-static ssize_t pSeries_nvram_write(char *buf, size_t count, loff_t *index)
+-{
+-	unsigned int i;
+-	unsigned long len;
+-	int done;
+-	unsigned long flags;
+-	const char *p = buf;
+-
+-	if (nvram_size == 0 || nvram_store == RTAS_UNKNOWN_SERVICE)
+-		return -ENODEV;
+-
+-	if (*index >= nvram_size)
+-		return 0;
+-
+-	i = *index;
+-	if (i + count > nvram_size)
+-		count = nvram_size - i;
+-
+-	spin_lock_irqsave(&nvram_lock, flags);
+-
+-	for (; count != 0; count -= len) {
+-		len = count;
+-		if (len > NVRW_CNT)
+-			len = NVRW_CNT;
+-
+-		memcpy(nvram_buf, p, len);
+-
+-		if ((rtas_call(nvram_store, 3, 2, &done, i, __pa(nvram_buf),
+-			       len) != 0) || len != done) {
+-			spin_unlock_irqrestore(&nvram_lock, flags);
+-			return -EIO;
+-		}
+-		
+-		p += len;
+-		i += len;
+-	}
+-	spin_unlock_irqrestore(&nvram_lock, flags);
+-	
+-	*index = i;
+-	return p - buf;
+-}
+-
+-static ssize_t pSeries_nvram_get_size(void)
+-{
+-	return nvram_size ? nvram_size : -ENODEV;
+-}
+-
+-int __init pSeries_nvram_init(void)
+-{
+-	struct device_node *nvram;
+-	unsigned int *nbytes_p, proplen;
+-
+-	nvram = of_find_node_by_type(NULL, "nvram");
+-	if (nvram == NULL)
+-		return -ENODEV;
+-
+-	nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
+-	if (nbytes_p == NULL || proplen != sizeof(unsigned int))
+-		return -EIO;
+-
+-	nvram_size = *nbytes_p;
+-
+-	nvram_fetch = rtas_token("nvram-fetch");
+-	nvram_store = rtas_token("nvram-store");
+-	printk(KERN_INFO "PPC64 nvram contains %d bytes\n", nvram_size);
+-	of_node_put(nvram);
+-
+-	ppc_md.nvram_read	= pSeries_nvram_read;
+-	ppc_md.nvram_write	= pSeries_nvram_write;
+-	ppc_md.nvram_size	= pSeries_nvram_get_size;
+-
+-	return 0;
+-}
+diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pSeries_pci.c
++++ /dev/null
+@@ -1,143 +0,0 @@
+-/*
+- * arch/ppc64/kernel/pSeries_pci.c
+- *
+- * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
+- * Copyright (C) 2003 Anton Blanchard <anton at au.ibm.com>, IBM
+- *
+- * pSeries specific routines for PCI.
+- * 
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the 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/ioport.h>
+-#include <linux/kernel.h>
+-#include <linux/pci.h>
+-#include <linux/string.h>
+-
+-#include <asm/pci-bridge.h>
+-#include <asm/prom.h>
+-
+-#include "pci.h"
+-
+-static int __devinitdata s7a_workaround = -1;
+-
+-#if 0
+-void pcibios_name_device(struct pci_dev *dev)
+-{
+-	struct device_node *dn;
+-
+-	/*
+-	 * Add IBM loc code (slot) as a prefix to the device names for service
+-	 */
+-	dn = pci_device_to_OF_node(dev);
+-	if (dn) {
+-		char *loc_code = get_property(dn, "ibm,loc-code", 0);
+-		if (loc_code) {
+-			int loc_len = strlen(loc_code);
+-			if (loc_len < sizeof(dev->dev.name)) {
+-				memmove(dev->dev.name+loc_len+1, dev->dev.name,
+-					sizeof(dev->dev.name)-loc_len-1);
+-				memcpy(dev->dev.name, loc_code, loc_len);
+-				dev->dev.name[loc_len] = ' ';
+-				dev->dev.name[sizeof(dev->dev.name)-1] = '\0';
+-			}
+-		}
+-	}
+-}   
+-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
+-#endif
+-
+-static void __devinit check_s7a(void)
+-{
+-	struct device_node *root;
+-	char *model;
+-
+-	s7a_workaround = 0;
+-	root = of_find_node_by_path("/");
+-	if (root) {
+-		model = get_property(root, "model", NULL);
+-		if (model && !strcmp(model, "IBM,7013-S7A"))
+-			s7a_workaround = 1;
+-		of_node_put(root);
+-	}
+-}
+-
+-void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
+-{
+-	struct pci_dev *dev;
+-
+-	if (s7a_workaround < 0)
+-		check_s7a();
+-	list_for_each_entry(dev, &bus->devices, bus_list) {
+-		pci_read_irq_line(dev);
+-		if (s7a_workaround) {
+-			if (dev->irq > 16) {
+-				dev->irq -= 3;
+-				pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+-					dev->irq);
+-			}
+-		}
+-	}
+-}
+-
+-static void __init pSeries_request_regions(void)
+-{
+-	if (!isa_io_base)
+-		return;
+-
+-	request_region(0x20,0x20,"pic1");
+-	request_region(0xa0,0x20,"pic2");
+-	request_region(0x00,0x20,"dma1");
+-	request_region(0x40,0x20,"timer");
+-	request_region(0x80,0x10,"dma page reg");
+-	request_region(0xc0,0x20,"dma2");
+-}
+-
+-void __init pSeries_final_fixup(void)
+-{
+-	phbs_remap_io();
+-	pSeries_request_regions();
+-
+-	pci_addr_cache_build();
+-}
+-
+-/*
+- * Assume the winbond 82c105 is the IDE controller on a
+- * p610.  We should probably be more careful in case
+- * someone tries to plug in a similar adapter.
+- */
+-static void fixup_winbond_82c105(struct pci_dev* dev)
+-{
+-	int i;
+-	unsigned int reg;
+-
+-	if (!(systemcfg->platform & PLATFORM_PSERIES))
+-		return;
+-
+-	printk("Using INTC for W82c105 IDE controller.\n");
+-	pci_read_config_dword(dev, 0x40, &reg);
+-	/* Enable LEGIRQ to use INTC instead of ISA interrupts */
+-	pci_write_config_dword(dev, 0x40, reg | (1<<11));
+-
+-	for (i = 0; i < DEVICE_COUNT_RESOURCE; ++i) {
+-		/* zap the 2nd function of the winbond chip */
+-		if (dev->resource[i].flags & IORESOURCE_IO
+-		    && dev->bus->number == 0 && dev->devfn == 0x81)
+-			dev->resource[i].flags &= ~IORESOURCE_IO;
+-	}
+-}
+-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
+-			 fixup_winbond_82c105);
+diff --git a/arch/ppc64/kernel/pSeries_reconfig.c b/arch/ppc64/kernel/pSeries_reconfig.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pSeries_reconfig.c
++++ /dev/null
+@@ -1,426 +0,0 @@
+-/*
+- * pSeries_reconfig.c - support for dynamic reconfiguration (including PCI
+- * Hotplug and Dynamic Logical Partitioning on RPA platforms).
+- *
+- * Copyright (C) 2005 Nathan Lynch
+- * Copyright (C) 2005 IBM 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.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/kref.h>
+-#include <linux/notifier.h>
+-#include <linux/proc_fs.h>
+-
+-#include <asm/prom.h>
+-#include <asm/pSeries_reconfig.h>
+-#include <asm/uaccess.h>
+-
+-
+-
+-/*
+- * Routines for "runtime" addition and removal of device tree nodes.
+- */
+-#ifdef CONFIG_PROC_DEVICETREE
+-/*
+- * Add a node to /proc/device-tree.
+- */
+-static void add_node_proc_entries(struct device_node *np)
+-{
+-	struct proc_dir_entry *ent;
+-
+-	ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
+-	if (ent)
+-		proc_device_tree_add_node(np, ent);
+-}
+-
+-static void remove_node_proc_entries(struct device_node *np)
+-{
+-	struct property *pp = np->properties;
+-	struct device_node *parent = np->parent;
+-
+-	while (pp) {
+-		remove_proc_entry(pp->name, np->pde);
+-		pp = pp->next;
+-	}
+-	if (np->pde)
+-		remove_proc_entry(np->pde->name, parent->pde);
+-}
+-#else /* !CONFIG_PROC_DEVICETREE */
+-static void add_node_proc_entries(struct device_node *np)
+-{
+-	return;
+-}
+-
+-static void remove_node_proc_entries(struct device_node *np)
+-{
+-	return;
+-}
+-#endif /* CONFIG_PROC_DEVICETREE */
+-
+-/**
+- *	derive_parent - basically like dirname(1)
+- *	@path:  the full_name of a node to be added to the tree
+- *
+- *	Returns the node which should be the parent of the node
+- *	described by path.  E.g., for path = "/foo/bar", returns
+- *	the node with full_name = "/foo".
+- */
+-static struct device_node *derive_parent(const char *path)
+-{
+-	struct device_node *parent = NULL;
+-	char *parent_path = "/";
+-	size_t parent_path_len = strrchr(path, '/') - path + 1;
+-
+-	/* reject if path is "/" */
+-	if (!strcmp(path, "/"))
+-		return ERR_PTR(-EINVAL);
+-
+-	if (strrchr(path, '/') != path) {
+-		parent_path = kmalloc(parent_path_len, GFP_KERNEL);
+-		if (!parent_path)
+-			return ERR_PTR(-ENOMEM);
+-		strlcpy(parent_path, path, parent_path_len);
+-	}
+-	parent = of_find_node_by_path(parent_path);
+-	if (!parent)
+-		return ERR_PTR(-EINVAL);
+-	if (strcmp(parent_path, "/"))
+-		kfree(parent_path);
+-	return parent;
+-}
+-
+-static struct notifier_block *pSeries_reconfig_chain;
+-
+-int pSeries_reconfig_notifier_register(struct notifier_block *nb)
+-{
+-	return notifier_chain_register(&pSeries_reconfig_chain, nb);
+-}
+-
+-void pSeries_reconfig_notifier_unregister(struct notifier_block *nb)
+-{
+-	notifier_chain_unregister(&pSeries_reconfig_chain, nb);
+-}
+-
+-static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
+-{
+-	struct device_node *np;
+-	int err = -ENOMEM;
+-
+-	np = kzalloc(sizeof(*np), GFP_KERNEL);
+-	if (!np)
+-		goto out_err;
+-
+-	np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
+-	if (!np->full_name)
+-		goto out_err;
+-
+-	strcpy(np->full_name, path);
+-
+-	np->properties = proplist;
+-	OF_MARK_DYNAMIC(np);
+-	kref_init(&np->kref);
+-
+-	np->parent = derive_parent(path);
+-	if (IS_ERR(np->parent)) {
+-		err = PTR_ERR(np->parent);
+-		goto out_err;
+-	}
+-
+-	err = notifier_call_chain(&pSeries_reconfig_chain,
+-				  PSERIES_RECONFIG_ADD, np);
+-	if (err == NOTIFY_BAD) {
+-		printk(KERN_ERR "Failed to add device node %s\n", path);
+-		err = -ENOMEM; /* For now, safe to assume kmalloc failure */
+-		goto out_err;
+-	}
+-
+-	of_attach_node(np);
+-
+-	add_node_proc_entries(np);
+-
+-	of_node_put(np->parent);
+-
+-	return 0;
+-
+-out_err:
+-	if (np) {
+-		of_node_put(np->parent);
+-		kfree(np->full_name);
+-		kfree(np);
+-	}
+-	return err;
+-}
+-
+-static int pSeries_reconfig_remove_node(struct device_node *np)
+-{
+-	struct device_node *parent, *child;
+-
+-	parent = of_get_parent(np);
+-	if (!parent)
+-		return -EINVAL;
+-
+-	if ((child = of_get_next_child(np, NULL))) {
+-		of_node_put(child);
+-		return -EBUSY;
+-	}
+-
+-	remove_node_proc_entries(np);
+-
+-	notifier_call_chain(&pSeries_reconfig_chain,
+-			    PSERIES_RECONFIG_REMOVE, np);
+-	of_detach_node(np);
+-
+-	of_node_put(parent);
+-	of_node_put(np); /* Must decrement the refcount */
+-	return 0;
+-}
+-
+-/*
+- * /proc/ppc64/ofdt - yucky binary interface for adding and removing
+- * OF device nodes.  Should be deprecated as soon as we get an
+- * in-kernel wrapper for the RTAS ibm,configure-connector call.
+- */
+-
+-static void release_prop_list(const struct property *prop)
+-{
+-	struct property *next;
+-	for (; prop; prop = next) {
+-		next = prop->next;
+-		kfree(prop->name);
+-		kfree(prop->value);
+-		kfree(prop);
+-	}
+-
+-}
+-
+-/**
+- * parse_next_property - process the next property from raw input buffer
+- * @buf: input buffer, must be nul-terminated
+- * @end: end of the input buffer + 1, for validation
+- * @name: return value; set to property name in buf
+- * @length: return value; set to length of value
+- * @value: return value; set to the property value in buf
+- *
+- * Note that the caller must make copies of the name and value returned,
+- * this function does no allocation or copying of the data.  Return value
+- * is set to the next name in buf, or NULL on error.
+- */
+-static char * parse_next_property(char *buf, char *end, char **name, int *length,
+-				  unsigned char **value)
+-{
+-	char *tmp;
+-
+-	*name = buf;
+-
+-	tmp = strchr(buf, ' ');
+-	if (!tmp) {
+-		printk(KERN_ERR "property parse failed in %s at line %d\n",
+-		       __FUNCTION__, __LINE__);
+-		return NULL;
+-	}
+-	*tmp = '\0';
+-
+-	if (++tmp >= end) {
+-		printk(KERN_ERR "property parse failed in %s at line %d\n",
+-		       __FUNCTION__, __LINE__);
+-		return NULL;
+-	}
+-
+-	/* now we're on the length */
+-	*length = -1;
+-	*length = simple_strtoul(tmp, &tmp, 10);
+-	if (*length == -1) {
+-		printk(KERN_ERR "property parse failed in %s at line %d\n",
+-		       __FUNCTION__, __LINE__);
+-		return NULL;
+-	}
+-	if (*tmp != ' ' || ++tmp >= end) {
+-		printk(KERN_ERR "property parse failed in %s at line %d\n",
+-		       __FUNCTION__, __LINE__);
+-		return NULL;
+-	}
+-
+-	/* now we're on the value */
+-	*value = tmp;
+-	tmp += *length;
+-	if (tmp > end) {
+-		printk(KERN_ERR "property parse failed in %s at line %d\n",
+-		       __FUNCTION__, __LINE__);
+-		return NULL;
+-	}
+-	else if (tmp < end && *tmp != ' ' && *tmp != '\0') {
+-		printk(KERN_ERR "property parse failed in %s at line %d\n",
+-		       __FUNCTION__, __LINE__);
+-		return NULL;
+-	}
+-	tmp++;
+-
+-	/* and now we should be on the next name, or the end */
+-	return tmp;
+-}
+-
+-static struct property *new_property(const char *name, const int length,
+-				     const unsigned char *value, struct property *last)
+-{
+-	struct property *new = kmalloc(sizeof(*new), GFP_KERNEL);
+-
+-	if (!new)
+-		return NULL;
+-	memset(new, 0, sizeof(*new));
+-
+-	if (!(new->name = kmalloc(strlen(name) + 1, GFP_KERNEL)))
+-		goto cleanup;
+-	if (!(new->value = kmalloc(length + 1, GFP_KERNEL)))
+-		goto cleanup;
+-
+-	strcpy(new->name, name);
+-	memcpy(new->value, value, length);
+-	*(((char *)new->value) + length) = 0;
+-	new->length = length;
+-	new->next = last;
+-	return new;
+-
+-cleanup:
+-	if (new->name)
+-		kfree(new->name);
+-	if (new->value)
+-		kfree(new->value);
+-	kfree(new);
+-	return NULL;
+-}
+-
+-static int do_add_node(char *buf, size_t bufsize)
+-{
+-	char *path, *end, *name;
+-	struct device_node *np;
+-	struct property *prop = NULL;
+-	unsigned char* value;
+-	int length, rv = 0;
+-
+-	end = buf + bufsize;
+-	path = buf;
+-	buf = strchr(buf, ' ');
+-	if (!buf)
+-		return -EINVAL;
+-	*buf = '\0';
+-	buf++;
+-
+-	if ((np = of_find_node_by_path(path))) {
+-		of_node_put(np);
+-		return -EINVAL;
+-	}
+-
+-	/* rv = build_prop_list(tmp, bufsize - (tmp - buf), &proplist); */
+-	while (buf < end &&
+-	       (buf = parse_next_property(buf, end, &name, &length, &value))) {
+-		struct property *last = prop;
+-
+-		prop = new_property(name, length, value, last);
+-		if (!prop) {
+-			rv = -ENOMEM;
+-			prop = last;
+-			goto out;
+-		}
+-	}
+-	if (!buf) {
+-		rv = -EINVAL;
+-		goto out;
+-	}
+-
+-	rv = pSeries_reconfig_add_node(path, prop);
+-
+-out:
+-	if (rv)
+-		release_prop_list(prop);
+-	return rv;
+-}
+-
+-static int do_remove_node(char *buf)
+-{
+-	struct device_node *node;
+-	int rv = -ENODEV;
+-
+-	if ((node = of_find_node_by_path(buf)))
+-		rv = pSeries_reconfig_remove_node(node);
+-
+-	of_node_put(node);
+-	return rv;
+-}
+-
+-/**
+- * ofdt_write - perform operations on the Open Firmware device tree
+- *
+- * @file: not used
+- * @buf: command and arguments
+- * @count: size of the command buffer
+- * @off: not used
+- *
+- * Operations supported at this time are addition and removal of
+- * whole nodes along with their properties.  Operations on individual
+- * properties are not implemented (yet).
+- */
+-static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t count,
+-			  loff_t *off)
+-{
+-	int rv = 0;
+-	char *kbuf;
+-	char *tmp;
+-
+-	if (!(kbuf = kmalloc(count + 1, GFP_KERNEL))) {
+-		rv = -ENOMEM;
+-		goto out;
+-	}
+-	if (copy_from_user(kbuf, buf, count)) {
+-		rv = -EFAULT;
+-		goto out;
+-	}
+-
+-	kbuf[count] = '\0';
+-
+-	tmp = strchr(kbuf, ' ');
+-	if (!tmp) {
+-		rv = -EINVAL;
+-		goto out;
+-	}
+-	*tmp = '\0';
+-	tmp++;
+-
+-	if (!strcmp(kbuf, "add_node"))
+-		rv = do_add_node(tmp, count - (tmp - kbuf));
+-	else if (!strcmp(kbuf, "remove_node"))
+-		rv = do_remove_node(tmp);
+-	else
+-		rv = -EINVAL;
+-out:
+-	kfree(kbuf);
+-	return rv ? rv : count;
+-}
+-
+-static struct file_operations ofdt_fops = {
+-	.write = ofdt_write
+-};
+-
+-/* create /proc/ppc64/ofdt write-only by root */
+-static int proc_ppc64_create_ofdt(void)
+-{
+-	struct proc_dir_entry *ent;
+-
+-	if (!(systemcfg->platform & PLATFORM_PSERIES))
+-		return 0;
+-
+-	ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL);
+-	if (ent) {
+-		ent->nlink = 1;
+-		ent->data = NULL;
+-		ent->size = 0;
+-		ent->proc_fops = &ofdt_fops;
+-	}
+-
+-	return 0;
+-}
+-__initcall(proc_ppc64_create_ofdt);
+diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pSeries_setup.c
++++ /dev/null
+@@ -1,622 +0,0 @@
+-/*
+- *  linux/arch/ppc/kernel/setup.c
+- *
+- *  Copyright (C) 1995  Linus Torvalds
+- *  Adapted from 'alpha' version by Gary Thomas
+- *  Modified by Cort Dougan (cort at cs.nmt.edu)
+- *  Modified by PPC64 Team, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-/*
+- * bootup setup stuff..
+- */
+-
+-#undef DEBUG
+-
+-#include <linux/config.h>
+-#include <linux/cpu.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/mm.h>
+-#include <linux/stddef.h>
+-#include <linux/unistd.h>
+-#include <linux/slab.h>
+-#include <linux/user.h>
+-#include <linux/a.out.h>
+-#include <linux/tty.h>
+-#include <linux/major.h>
+-#include <linux/interrupt.h>
+-#include <linux/reboot.h>
+-#include <linux/init.h>
+-#include <linux/ioport.h>
+-#include <linux/console.h>
+-#include <linux/pci.h>
+-#include <linux/utsname.h>
+-#include <linux/adb.h>
+-#include <linux/module.h>
+-#include <linux/delay.h>
+-#include <linux/irq.h>
+-#include <linux/seq_file.h>
+-#include <linux/root_dev.h>
+-
+-#include <asm/mmu.h>
+-#include <asm/processor.h>
+-#include <asm/io.h>
+-#include <asm/pgtable.h>
+-#include <asm/prom.h>
+-#include <asm/rtas.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/iommu.h>
+-#include <asm/dma.h>
+-#include <asm/machdep.h>
+-#include <asm/irq.h>
+-#include <asm/time.h>
+-#include <asm/nvram.h>
+-#include <asm/plpar_wrappers.h>
+-#include <asm/xics.h>
+-#include <asm/firmware.h>
+-#include <asm/pmc.h>
+-
+-#include "i8259.h"
+-#include "mpic.h"
+-#include "pci.h"
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) udbg_printf(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-extern void find_udbg_vterm(void);
+-extern void system_reset_fwnmi(void);	/* from head.S */
+-extern void machine_check_fwnmi(void);	/* from head.S */
+-extern void generic_find_legacy_serial_ports(u64 *physport,
+-		unsigned int *default_speed);
+-
+-int fwnmi_active;  /* TRUE if an FWNMI handler is present */
+-
+-extern void pSeries_system_reset_exception(struct pt_regs *regs);
+-extern int pSeries_machine_check_exception(struct pt_regs *regs);
+-
+-static int pseries_shared_idle(void);
+-static int pseries_dedicated_idle(void);
+-
+-static volatile void __iomem * chrp_int_ack_special;
+-struct mpic *pSeries_mpic;
+-
+-void pSeries_get_cpuinfo(struct seq_file *m)
+-{
+-	struct device_node *root;
+-	const char *model = "";
+-
+-	root = of_find_node_by_path("/");
+-	if (root)
+-		model = get_property(root, "model", NULL);
+-	seq_printf(m, "machine\t\t: CHRP %s\n", model);
+-	of_node_put(root);
+-}
+-
+-/* Initialize firmware assisted non-maskable interrupts if
+- * the firmware supports this feature.
+- *
+- */
+-static void __init fwnmi_init(void)
+-{
+-	int ret;
+-	int ibm_nmi_register = rtas_token("ibm,nmi-register");
+-	if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
+-		return;
+-	ret = rtas_call(ibm_nmi_register, 2, 1, NULL,
+-			__pa((unsigned long)system_reset_fwnmi),
+-			__pa((unsigned long)machine_check_fwnmi));
+-	if (ret == 0)
+-		fwnmi_active = 1;
+-}
+-
+-static int pSeries_irq_cascade(struct pt_regs *regs, void *data)
+-{
+-	if (chrp_int_ack_special)
+-		return readb(chrp_int_ack_special);
+-	else
+-		return i8259_irq(smp_processor_id());
+-}
+-
+-static void __init pSeries_init_mpic(void)
+-{
+-        unsigned int *addrp;
+-	struct device_node *np;
+-        int i;
+-
+-	/* All ISUs are setup, complete initialization */
+-	mpic_init(pSeries_mpic);
+-
+-	/* Check what kind of cascade ACK we have */
+-        if (!(np = of_find_node_by_name(NULL, "pci"))
+-            || !(addrp = (unsigned int *)
+-                 get_property(np, "8259-interrupt-acknowledge", NULL)))
+-                printk(KERN_ERR "Cannot find pci to get ack address\n");
+-        else
+-		chrp_int_ack_special = ioremap(addrp[prom_n_addr_cells(np)-1], 1);
+-	of_node_put(np);
+-
+-	/* Setup the legacy interrupts & controller */
+-        for (i = 0; i < NUM_ISA_INTERRUPTS; i++)
+-                irq_desc[i].handler = &i8259_pic;
+-	i8259_init(0);
+-
+-	/* Hook cascade to mpic */
+-	mpic_setup_cascade(NUM_ISA_INTERRUPTS, pSeries_irq_cascade, NULL);
+-}
+-
+-static void __init pSeries_setup_mpic(void)
+-{
+-	unsigned int *opprop;
+-	unsigned long openpic_addr = 0;
+-        unsigned char senses[NR_IRQS - NUM_ISA_INTERRUPTS];
+-        struct device_node *root;
+-	int irq_count;
+-
+-	/* Find the Open PIC if present */
+-	root = of_find_node_by_path("/");
+-	opprop = (unsigned int *) get_property(root, "platform-open-pic", NULL);
+-	if (opprop != 0) {
+-		int n = prom_n_addr_cells(root);
+-
+-		for (openpic_addr = 0; n > 0; --n)
+-			openpic_addr = (openpic_addr << 32) + *opprop++;
+-		printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
+-	}
+-	of_node_put(root);
+-
+-	BUG_ON(openpic_addr == 0);
+-
+-	/* Get the sense values from OF */
+-	prom_get_irq_senses(senses, NUM_ISA_INTERRUPTS, NR_IRQS);
+-	
+-	/* Setup the openpic driver */
+-	irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
+-	pSeries_mpic = mpic_alloc(openpic_addr, MPIC_PRIMARY,
+-				  16, 16, irq_count, /* isu size, irq offset, irq count */ 
+-				  NR_IRQS - 4, /* ipi offset */
+-				  senses, irq_count, /* sense & sense size */
+-				  " MPIC     ");
+-}
+-
+-static void pseries_lpar_enable_pmcs(void)
+-{
+-	unsigned long set, reset;
+-
+-	power4_enable_pmcs();
+-
+-	set = 1UL << 63;
+-	reset = 0;
+-	plpar_hcall_norets(H_PERFMON, set, reset);
+-
+-	/* instruct hypervisor to maintain PMCs */
+-	if (firmware_has_feature(FW_FEATURE_SPLPAR))
+-		get_paca()->lppaca.pmcregs_in_use = 1;
+-}
+-
+-static void __init pSeries_setup_arch(void)
+-{
+-	/* Fixup ppc_md depending on the type of interrupt controller */
+-	if (ppc64_interrupt_controller == IC_OPEN_PIC) {
+-		ppc_md.init_IRQ       = pSeries_init_mpic;
+-		ppc_md.get_irq        = mpic_get_irq;
+-	 	ppc_md.cpu_irq_down   = mpic_teardown_this_cpu;
+-		/* Allocate the mpic now, so that find_and_init_phbs() can
+-		 * fill the ISUs */
+-		pSeries_setup_mpic();
+-	} else {
+-		ppc_md.init_IRQ       = xics_init_IRQ;
+-		ppc_md.get_irq        = xics_get_irq;
+-		ppc_md.cpu_irq_down   = xics_teardown_cpu;
+-	}
+-
+-#ifdef CONFIG_SMP
+-	smp_init_pSeries();
+-#endif
+-	/* openpic global configuration register (64-bit format). */
+-	/* openpic Interrupt Source Unit pointer (64-bit format). */
+-	/* python0 facility area (mmio) (64-bit format) REAL address. */
+-
+-	/* init to some ~sane value until calibrate_delay() runs */
+-	loops_per_jiffy = 50000000;
+-
+-	if (ROOT_DEV == 0) {
+-		printk("No ramdisk, default root is /dev/sda2\n");
+-		ROOT_DEV = Root_SDA2;
+-	}
+-
+-	fwnmi_init();
+-
+-	/* Find and initialize PCI host bridges */
+-	init_pci_config_tokens();
+-	find_and_init_phbs();
+-	eeh_init();
+-
+-#ifdef CONFIG_DUMMY_CONSOLE
+-	conswitchp = &dummy_con;
+-#endif
+-
+-	pSeries_nvram_init();
+-
+-	/* Choose an idle loop */
+-	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+-		vpa_init(boot_cpuid);
+-		if (get_paca()->lppaca.shared_proc) {
+-			printk(KERN_INFO "Using shared processor idle loop\n");
+-			ppc_md.idle_loop = pseries_shared_idle;
+-		} else {
+-			printk(KERN_INFO "Using dedicated idle loop\n");
+-			ppc_md.idle_loop = pseries_dedicated_idle;
+-		}
+-	} else {
+-		printk(KERN_INFO "Using default idle loop\n");
+-		ppc_md.idle_loop = default_idle;
+-	}
+-
+-	if (systemcfg->platform & PLATFORM_LPAR)
+-		ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
+-	else
+-		ppc_md.enable_pmcs = power4_enable_pmcs;
+-}
+-
+-static int __init pSeries_init_panel(void)
+-{
+-	/* Manually leave the kernel version on the panel. */
+-	ppc_md.progress("Linux ppc64\n", 0);
+-	ppc_md.progress(system_utsname.version, 0);
+-
+-	return 0;
+-}
+-arch_initcall(pSeries_init_panel);
+-
+-
+-/* Build up the ppc64_firmware_features bitmask field
+- * using contents of device-tree/ibm,hypertas-functions.
+- * Ultimately this functionality may be moved into prom.c prom_init().
+- */
+-static void __init fw_feature_init(void)
+-{
+-	struct device_node * dn;
+-	char * hypertas;
+-	unsigned int len;
+-
+-	DBG(" -> fw_feature_init()\n");
+-
+-	ppc64_firmware_features = 0;
+-	dn = of_find_node_by_path("/rtas");
+-	if (dn == NULL) {
+-		printk(KERN_ERR "WARNING ! Cannot find RTAS in device-tree !\n");
+-		goto no_rtas;
+-	}
+-
+-	hypertas = get_property(dn, "ibm,hypertas-functions", &len);
+-	if (hypertas) {
+-		while (len > 0){
+-			int i, hypertas_len;
+-			/* check value against table of strings */
+-			for(i=0; i < FIRMWARE_MAX_FEATURES ;i++) {
+-				if ((firmware_features_table[i].name) &&
+-				    (strcmp(firmware_features_table[i].name,hypertas))==0) {
+-					/* we have a match */
+-					ppc64_firmware_features |= 
+-						(firmware_features_table[i].val);
+-					break;
+-				} 
+-			}
+-			hypertas_len = strlen(hypertas);
+-			len -= hypertas_len +1;
+-			hypertas+= hypertas_len +1;
+-		}
+-	}
+-
+-	of_node_put(dn);
+- no_rtas:
+-	printk(KERN_INFO "firmware_features = 0x%lx\n", 
+-	       ppc64_firmware_features);
+-
+-	DBG(" <- fw_feature_init()\n");
+-}
+-
+-
+-static  void __init pSeries_discover_pic(void)
+-{
+-	struct device_node *np;
+-	char *typep;
+-
+-	/*
+-	 * Setup interrupt mapping options that are needed for finish_device_tree
+-	 * to properly parse the OF interrupt tree & do the virtual irq mapping
+-	 */
+-	__irq_offset_value = NUM_ISA_INTERRUPTS;
+-	ppc64_interrupt_controller = IC_INVALID;
+-	for (np = NULL; (np = of_find_node_by_name(np, "interrupt-controller"));) {
+-		typep = (char *)get_property(np, "compatible", NULL);
+-		if (strstr(typep, "open-pic"))
+-			ppc64_interrupt_controller = IC_OPEN_PIC;
+-		else if (strstr(typep, "ppc-xicp"))
+-			ppc64_interrupt_controller = IC_PPC_XIC;
+-		else
+-			printk("pSeries_discover_pic: failed to recognize"
+-			       " interrupt-controller\n");
+-		break;
+-	}
+-}
+-
+-static void pSeries_mach_cpu_die(void)
+-{
+-	local_irq_disable();
+-	idle_task_exit();
+-	/* Some hardware requires clearing the CPPR, while other hardware does not
+-	 * it is safe either way
+-	 */
+-	pSeriesLP_cppr_info(0, 0);
+-	rtas_stop_self();
+-	/* Should never get here... */
+-	BUG();
+-	for(;;);
+-}
+-
+-
+-/*
+- * Early initialization.  Relocation is on but do not reference unbolted pages
+- */
+-static void __init pSeries_init_early(void)
+-{
+-	void *comport;
+-	int iommu_off = 0;
+-	unsigned int default_speed;
+-	u64 physport;
+-
+-	DBG(" -> pSeries_init_early()\n");
+-
+-	fw_feature_init();
+-	
+-	if (systemcfg->platform & PLATFORM_LPAR)
+-		hpte_init_lpar();
+-	else {
+-		hpte_init_native();
+-		iommu_off = (of_chosen &&
+-			     get_property(of_chosen, "linux,iommu-off", NULL));
+-	}
+-
+-	generic_find_legacy_serial_ports(&physport, &default_speed);
+-
+-	if (systemcfg->platform & PLATFORM_LPAR)
+-		find_udbg_vterm();
+-	else if (physport) {
+-		/* Map the uart for udbg. */
+-		comport = (void *)ioremap(physport, 16);
+-		udbg_init_uart(comport, default_speed);
+-
+-		DBG("Hello World !\n");
+-	}
+-
+-
+-	iommu_init_early_pSeries();
+-
+-	pSeries_discover_pic();
+-
+-	DBG(" <- pSeries_init_early()\n");
+-}
+-
+-
+-static int pSeries_check_legacy_ioport(unsigned int baseport)
+-{
+-	struct device_node *np;
+-
+-#define I8042_DATA_REG	0x60
+-#define FDC_BASE	0x3f0
+-
+-
+-	switch(baseport) {
+-	case I8042_DATA_REG:
+-		np = of_find_node_by_type(NULL, "8042");
+-		if (np == NULL)
+-			return -ENODEV;
+-		of_node_put(np);
+-		break;
+-	case FDC_BASE:
+-		np = of_find_node_by_type(NULL, "fdc");
+-		if (np == NULL)
+-			return -ENODEV;
+-		of_node_put(np);
+-		break;
+-	}
+-	return 0;
+-}
+-
+-/*
+- * Called very early, MMU is off, device-tree isn't unflattened
+- */
+-extern struct machdep_calls pSeries_md;
+-
+-static int __init pSeries_probe(int platform)
+-{
+-	if (platform != PLATFORM_PSERIES &&
+-	    platform != PLATFORM_PSERIES_LPAR)
+-		return 0;
+-
+-	/* if we have some ppc_md fixups for LPAR to do, do
+-	 * it here ...
+-	 */
+-
+-	return 1;
+-}
+-
+-DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
+-
+-static inline void dedicated_idle_sleep(unsigned int cpu)
+-{
+-	struct paca_struct *ppaca = &paca[cpu ^ 1];
+-
+-	/* Only sleep if the other thread is not idle */
+-	if (!(ppaca->lppaca.idle)) {
+-		local_irq_disable();
+-
+-		/*
+-		 * We are about to sleep the thread and so wont be polling any
+-		 * more.
+-		 */
+-		clear_thread_flag(TIF_POLLING_NRFLAG);
+-
+-		/*
+-		 * SMT dynamic mode. Cede will result in this thread going
+-		 * dormant, if the partner thread is still doing work.  Thread
+-		 * wakes up if partner goes idle, an interrupt is presented, or
+-		 * a prod occurs.  Returning from the cede enables external
+-		 * interrupts.
+-		 */
+-		if (!need_resched())
+-			cede_processor();
+-		else
+-			local_irq_enable();
+-	} else {
+-		/*
+-		 * Give the HV an opportunity at the processor, since we are
+-		 * not doing any work.
+-		 */
+-		poll_pending();
+-	}
+-}
+-
+-static int pseries_dedicated_idle(void)
+-{
+-	long oldval;
+-	struct paca_struct *lpaca = get_paca();
+-	unsigned int cpu = smp_processor_id();
+-	unsigned long start_snooze;
+-	unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
+-
+-	while (1) {
+-		/*
+-		 * Indicate to the HV that we are idle. Now would be
+-		 * a good time to find other work to dispatch.
+-		 */
+-		lpaca->lppaca.idle = 1;
+-
+-		oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
+-		if (!oldval) {
+-			set_thread_flag(TIF_POLLING_NRFLAG);
+-
+-			start_snooze = __get_tb() +
+-				*smt_snooze_delay * tb_ticks_per_usec;
+-
+-			while (!need_resched() && !cpu_is_offline(cpu)) {
+-				ppc64_runlatch_off();
+-
+-				/*
+-				 * Go into low thread priority and possibly
+-				 * low power mode.
+-				 */
+-				HMT_low();
+-				HMT_very_low();
+-
+-				if (*smt_snooze_delay != 0 &&
+-				    __get_tb() > start_snooze) {
+-					HMT_medium();
+-					dedicated_idle_sleep(cpu);
+-				}
+-
+-			}
+-
+-			HMT_medium();
+-			clear_thread_flag(TIF_POLLING_NRFLAG);
+-		} else {
+-			set_need_resched();
+-		}
+-
+-		lpaca->lppaca.idle = 0;
+-		ppc64_runlatch_on();
+-
+-		schedule();
+-
+-		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
+-			cpu_die();
+-	}
+-}
+-
+-static int pseries_shared_idle(void)
+-{
+-	struct paca_struct *lpaca = get_paca();
+-	unsigned int cpu = smp_processor_id();
+-
+-	while (1) {
+-		/*
+-		 * Indicate to the HV that we are idle. Now would be
+-		 * a good time to find other work to dispatch.
+-		 */
+-		lpaca->lppaca.idle = 1;
+-
+-		while (!need_resched() && !cpu_is_offline(cpu)) {
+-			local_irq_disable();
+-			ppc64_runlatch_off();
+-
+-			/*
+-			 * Yield the processor to the hypervisor.  We return if
+-			 * an external interrupt occurs (which are driven prior
+-			 * to returning here) or if a prod occurs from another
+-			 * processor. When returning here, external interrupts
+-			 * are enabled.
+-			 *
+-			 * Check need_resched() again with interrupts disabled
+-			 * to avoid a race.
+-			 */
+-			if (!need_resched())
+-				cede_processor();
+-			else
+-				local_irq_enable();
+-
+-			HMT_medium();
+-		}
+-
+-		lpaca->lppaca.idle = 0;
+-		ppc64_runlatch_on();
+-
+-		schedule();
+-
+-		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
+-			cpu_die();
+-	}
+-
+-	return 0;
+-}
+-
+-static int pSeries_pci_probe_mode(struct pci_bus *bus)
+-{
+-	if (systemcfg->platform & PLATFORM_LPAR)
+-		return PCI_PROBE_DEVTREE;
+-	return PCI_PROBE_NORMAL;
+-}
+-
+-struct machdep_calls __initdata pSeries_md = {
+-	.probe			= pSeries_probe,
+-	.setup_arch		= pSeries_setup_arch,
+-	.init_early		= pSeries_init_early,
+-	.get_cpuinfo		= pSeries_get_cpuinfo,
+-	.log_error		= pSeries_log_error,
+-	.pcibios_fixup		= pSeries_final_fixup,
+-	.pci_probe_mode		= pSeries_pci_probe_mode,
+-	.irq_bus_setup		= pSeries_irq_bus_setup,
+-	.restart		= rtas_restart,
+-	.power_off		= rtas_power_off,
+-	.halt			= rtas_halt,
+-	.panic			= rtas_os_term,
+-	.cpu_die		= pSeries_mach_cpu_die,
+-	.get_boot_time		= rtas_get_boot_time,
+-	.get_rtc_time		= rtas_get_rtc_time,
+-	.set_rtc_time		= rtas_set_rtc_time,
+-	.calibrate_decr		= generic_calibrate_decr,
+-	.progress		= rtas_progress,
+-	.check_legacy_ioport	= pSeries_check_legacy_ioport,
+-	.system_reset_exception = pSeries_system_reset_exception,
+-	.machine_check_exception = pSeries_machine_check_exception,
+-};
+diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pSeries_smp.c
++++ /dev/null
+@@ -1,517 +0,0 @@
+-/*
+- * SMP support for pSeries and BPA machines.
+- *
+- * Dave Engebretsen, Peter Bergner, and
+- * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
+- *
+- * Plus various changes from other IBM teams...
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/config.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/sched.h>
+-#include <linux/smp.h>
+-#include <linux/interrupt.h>
+-#include <linux/delay.h>
+-#include <linux/init.h>
+-#include <linux/spinlock.h>
+-#include <linux/cache.h>
+-#include <linux/err.h>
+-#include <linux/sysdev.h>
+-#include <linux/cpu.h>
+-
+-#include <asm/ptrace.h>
+-#include <asm/atomic.h>
+-#include <asm/irq.h>
+-#include <asm/page.h>
+-#include <asm/pgtable.h>
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/smp.h>
+-#include <asm/paca.h>
+-#include <asm/time.h>
+-#include <asm/machdep.h>
+-#include <asm/xics.h>
+-#include <asm/cputable.h>
+-#include <asm/firmware.h>
+-#include <asm/system.h>
+-#include <asm/rtas.h>
+-#include <asm/plpar_wrappers.h>
+-#include <asm/pSeries_reconfig.h>
+-
+-#include "mpic.h"
+-#include "bpa_iic.h"
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) udbg_printf(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-/*
+- * The primary thread of each non-boot processor is recorded here before
+- * smp init.
+- */
+-static cpumask_t of_spin_map;
+-
+-extern void pSeries_secondary_smp_init(unsigned long);
+-
+-#ifdef CONFIG_HOTPLUG_CPU
+-
+-/* Get state of physical CPU.
+- * Return codes:
+- *	0	- The processor is in the RTAS stopped state
+- *	1	- stop-self is in progress
+- *	2	- The processor is not in the RTAS stopped state
+- *	-1	- Hardware Error
+- *	-2	- Hardware Busy, Try again later.
+- */
+-static int query_cpu_stopped(unsigned int pcpu)
+-{
+-	int cpu_status;
+-	int status, qcss_tok;
+-
+-	qcss_tok = rtas_token("query-cpu-stopped-state");
+-	if (qcss_tok == RTAS_UNKNOWN_SERVICE)
+-		return -1;
+-	status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu);
+-	if (status != 0) {
+-		printk(KERN_ERR
+-		       "RTAS query-cpu-stopped-state failed: %i\n", status);
+-		return status;
+-	}
+-
+-	return cpu_status;
+-}
+-
+-int pSeries_cpu_disable(void)
+-{
+-	int cpu = smp_processor_id();
+-
+-	cpu_clear(cpu, cpu_online_map);
+-	systemcfg->processorCount--;
+-
+-	/*fix boot_cpuid here*/
+-	if (cpu == boot_cpuid)
+-		boot_cpuid = any_online_cpu(cpu_online_map);
+-
+-	/* FIXME: abstract this to not be platform specific later on */
+-	xics_migrate_irqs_away();
+-	return 0;
+-}
+-
+-void pSeries_cpu_die(unsigned int cpu)
+-{
+-	int tries;
+-	int cpu_status;
+-	unsigned int pcpu = get_hard_smp_processor_id(cpu);
+-
+-	for (tries = 0; tries < 25; tries++) {
+-		cpu_status = query_cpu_stopped(pcpu);
+-		if (cpu_status == 0 || cpu_status == -1)
+-			break;
+-		msleep(200);
+-	}
+-	if (cpu_status != 0) {
+-		printk("Querying DEAD? cpu %i (%i) shows %i\n",
+-		       cpu, pcpu, cpu_status);
+-	}
+-
+-	/* Isolation and deallocation are definatly done by
+-	 * drslot_chrp_cpu.  If they were not they would be
+-	 * done here.  Change isolate state to Isolate and
+-	 * change allocation-state to Unusable.
+-	 */
+-	paca[cpu].cpu_start = 0;
+-}
+-
+-/*
+- * Update cpu_present_map and paca(s) for a new cpu node.  The wrinkle
+- * here is that a cpu device node may represent up to two logical cpus
+- * in the SMT case.  We must honor the assumption in other code that
+- * the logical ids for sibling SMT threads x and y are adjacent, such
+- * that x^1 == y and y^1 == x.
+- */
+-static int pSeries_add_processor(struct device_node *np)
+-{
+-	unsigned int cpu;
+-	cpumask_t candidate_map, tmp = CPU_MASK_NONE;
+-	int err = -ENOSPC, len, nthreads, i;
+-	u32 *intserv;
+-
+-	intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len);
+-	if (!intserv)
+-		return 0;
+-
+-	nthreads = len / sizeof(u32);
+-	for (i = 0; i < nthreads; i++)
+-		cpu_set(i, tmp);
+-
+-	lock_cpu_hotplug();
+-
+-	BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));
+-
+-	/* Get a bitmap of unoccupied slots. */
+-	cpus_xor(candidate_map, cpu_possible_map, cpu_present_map);
+-	if (cpus_empty(candidate_map)) {
+-		/* If we get here, it most likely means that NR_CPUS is
+-		 * less than the partition's max processors setting.
+-		 */
+-		printk(KERN_ERR "Cannot add cpu %s; this system configuration"
+-		       " supports %d logical cpus.\n", np->full_name,
+-		       cpus_weight(cpu_possible_map));
+-		goto out_unlock;
+-	}
+-
+-	while (!cpus_empty(tmp))
+-		if (cpus_subset(tmp, candidate_map))
+-			/* Found a range where we can insert the new cpu(s) */
+-			break;
+-		else
+-			cpus_shift_left(tmp, tmp, nthreads);
+-
+-	if (cpus_empty(tmp)) {
+-		printk(KERN_ERR "Unable to find space in cpu_present_map for"
+-		       " processor %s with %d thread(s)\n", np->name,
+-		       nthreads);
+-		goto out_unlock;
+-	}
+-
+-	for_each_cpu_mask(cpu, tmp) {
+-		BUG_ON(cpu_isset(cpu, cpu_present_map));
+-		cpu_set(cpu, cpu_present_map);
+-		set_hard_smp_processor_id(cpu, *intserv++);
+-	}
+-	err = 0;
+-out_unlock:
+-	unlock_cpu_hotplug();
+-	return err;
+-}
+-
+-/*
+- * Update the present map for a cpu node which is going away, and set
+- * the hard id in the paca(s) to -1 to be consistent with boot time
+- * convention for non-present cpus.
+- */
+-static void pSeries_remove_processor(struct device_node *np)
+-{
+-	unsigned int cpu;
+-	int len, nthreads, i;
+-	u32 *intserv;
+-
+-	intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len);
+-	if (!intserv)
+-		return;
+-
+-	nthreads = len / sizeof(u32);
+-
+-	lock_cpu_hotplug();
+-	for (i = 0; i < nthreads; i++) {
+-		for_each_present_cpu(cpu) {
+-			if (get_hard_smp_processor_id(cpu) != intserv[i])
+-				continue;
+-			BUG_ON(cpu_online(cpu));
+-			cpu_clear(cpu, cpu_present_map);
+-			set_hard_smp_processor_id(cpu, -1);
+-			break;
+-		}
+-		if (cpu == NR_CPUS)
+-			printk(KERN_WARNING "Could not find cpu to remove "
+-			       "with physical id 0x%x\n", intserv[i]);
+-	}
+-	unlock_cpu_hotplug();
+-}
+-
+-static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node)
+-{
+-	int err = NOTIFY_OK;
+-
+-	switch (action) {
+-	case PSERIES_RECONFIG_ADD:
+-		if (pSeries_add_processor(node))
+-			err = NOTIFY_BAD;
+-		break;
+-	case PSERIES_RECONFIG_REMOVE:
+-		pSeries_remove_processor(node);
+-		break;
+-	default:
+-		err = NOTIFY_DONE;
+-		break;
+-	}
+-	return err;
+-}
+-
+-static struct notifier_block pSeries_smp_nb = {
+-	.notifier_call = pSeries_smp_notifier,
+-};
+-
+-#endif /* CONFIG_HOTPLUG_CPU */
+-
+-/**
+- * smp_startup_cpu() - start the given cpu
+- *
+- * At boot time, there is nothing to do for primary threads which were
+- * started from Open Firmware.  For anything else, call RTAS with the
+- * appropriate start location.
+- *
+- * Returns:
+- *	0	- failure
+- *	1	- success
+- */
+-static inline int __devinit smp_startup_cpu(unsigned int lcpu)
+-{
+-	int status;
+-	unsigned long start_here = __pa((u32)*((unsigned long *)
+-					       pSeries_secondary_smp_init));
+-	unsigned int pcpu;
+-	int start_cpu;
+-
+-	if (cpu_isset(lcpu, of_spin_map))
+-		/* Already started by OF and sitting in spin loop */
+-		return 1;
+-
+-	pcpu = get_hard_smp_processor_id(lcpu);
+-
+-	/* Fixup atomic count: it exited inside IRQ handler. */
+-	paca[lcpu].__current->thread_info->preempt_count	= 0;
+-
+-	/* 
+-	 * If the RTAS start-cpu token does not exist then presume the
+-	 * cpu is already spinning.
+-	 */
+-	start_cpu = rtas_token("start-cpu");
+-	if (start_cpu == RTAS_UNKNOWN_SERVICE)
+-		return 1;
+-
+-	status = rtas_call(start_cpu, 3, 1, NULL, pcpu, start_here, lcpu);
+-	if (status != 0) {
+-		printk(KERN_ERR "start-cpu failed: %i\n", status);
+-		return 0;
+-	}
+-
+-	return 1;
+-}
+-
+-#ifdef CONFIG_XICS
+-static inline void smp_xics_do_message(int cpu, int msg)
+-{
+-	set_bit(msg, &xics_ipi_message[cpu].value);
+-	mb();
+-	xics_cause_IPI(cpu);
+-}
+-
+-static void smp_xics_message_pass(int target, int msg)
+-{
+-	unsigned int i;
+-
+-	if (target < NR_CPUS) {
+-		smp_xics_do_message(target, msg);
+-	} else {
+-		for_each_online_cpu(i) {
+-			if (target == MSG_ALL_BUT_SELF
+-			    && i == smp_processor_id())
+-				continue;
+-			smp_xics_do_message(i, msg);
+-		}
+-	}
+-}
+-
+-static int __init smp_xics_probe(void)
+-{
+-	xics_request_IPIs();
+-
+-	return cpus_weight(cpu_possible_map);
+-}
+-
+-static void __devinit smp_xics_setup_cpu(int cpu)
+-{
+-	if (cpu != boot_cpuid)
+-		xics_setup_cpu();
+-
+-	if (firmware_has_feature(FW_FEATURE_SPLPAR))
+-		vpa_init(cpu);
+-
+-	cpu_clear(cpu, of_spin_map);
+-
+-}
+-#endif /* CONFIG_XICS */
+-#ifdef CONFIG_BPA_IIC
+-static void smp_iic_message_pass(int target, int msg)
+-{
+-	unsigned int i;
+-
+-	if (target < NR_CPUS) {
+-		iic_cause_IPI(target, msg);
+-	} else {
+-		for_each_online_cpu(i) {
+-			if (target == MSG_ALL_BUT_SELF
+-			    && i == smp_processor_id())
+-				continue;
+-			iic_cause_IPI(i, msg);
+-		}
+-	}
+-}
+-
+-static int __init smp_iic_probe(void)
+-{
+-	iic_request_IPIs();
+-
+-	return cpus_weight(cpu_possible_map);
+-}
+-
+-static void __devinit smp_iic_setup_cpu(int cpu)
+-{
+-	if (cpu != boot_cpuid)
+-		iic_setup_cpu();
+-}
+-#endif /* CONFIG_BPA_IIC */
+-
+-static DEFINE_SPINLOCK(timebase_lock);
+-static unsigned long timebase = 0;
+-
+-static void __devinit pSeries_give_timebase(void)
+-{
+-	spin_lock(&timebase_lock);
+-	rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
+-	timebase = get_tb();
+-	spin_unlock(&timebase_lock);
+-
+-	while (timebase)
+-		barrier();
+-	rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
+-}
+-
+-static void __devinit pSeries_take_timebase(void)
+-{
+-	while (!timebase)
+-		barrier();
+-	spin_lock(&timebase_lock);
+-	set_tb(timebase >> 32, timebase & 0xffffffff);
+-	timebase = 0;
+-	spin_unlock(&timebase_lock);
+-}
+-
+-static void __devinit smp_pSeries_kick_cpu(int nr)
+-{
+-	BUG_ON(nr < 0 || nr >= NR_CPUS);
+-
+-	if (!smp_startup_cpu(nr))
+-		return;
+-
+-	/*
+-	 * The processor is currently spinning, waiting for the
+-	 * cpu_start field to become non-zero After we set cpu_start,
+-	 * the processor will continue on to secondary_start
+-	 */
+-	paca[nr].cpu_start = 1;
+-}
+-
+-static int smp_pSeries_cpu_bootable(unsigned int nr)
+-{
+-	/* Special case - we inhibit secondary thread startup
+-	 * during boot if the user requests it.  Odd-numbered
+-	 * cpus are assumed to be secondary threads.
+-	 */
+-	if (system_state < SYSTEM_RUNNING &&
+-	    cpu_has_feature(CPU_FTR_SMT) &&
+-	    !smt_enabled_at_boot && nr % 2 != 0)
+-		return 0;
+-
+-	return 1;
+-}
+-#ifdef CONFIG_MPIC
+-static struct smp_ops_t pSeries_mpic_smp_ops = {
+-	.message_pass	= smp_mpic_message_pass,
+-	.probe		= smp_mpic_probe,
+-	.kick_cpu	= smp_pSeries_kick_cpu,
+-	.setup_cpu	= smp_mpic_setup_cpu,
+-};
+-#endif
+-#ifdef CONFIG_XICS
+-static struct smp_ops_t pSeries_xics_smp_ops = {
+-	.message_pass	= smp_xics_message_pass,
+-	.probe		= smp_xics_probe,
+-	.kick_cpu	= smp_pSeries_kick_cpu,
+-	.setup_cpu	= smp_xics_setup_cpu,
+-	.cpu_bootable	= smp_pSeries_cpu_bootable,
+-};
+-#endif
+-#ifdef CONFIG_BPA_IIC
+-static struct smp_ops_t bpa_iic_smp_ops = {
+-	.message_pass	= smp_iic_message_pass,
+-	.probe		= smp_iic_probe,
+-	.kick_cpu	= smp_pSeries_kick_cpu,
+-	.setup_cpu	= smp_iic_setup_cpu,
+-	.cpu_bootable	= smp_pSeries_cpu_bootable,
+-};
+-#endif
+-
+-/* This is called very early */
+-void __init smp_init_pSeries(void)
+-{
+-	int i;
+-
+-	DBG(" -> smp_init_pSeries()\n");
+-
+-	switch (ppc64_interrupt_controller) {
+-#ifdef CONFIG_MPIC
+-	case IC_OPEN_PIC:
+-		smp_ops = &pSeries_mpic_smp_ops;
+-		break;
+-#endif
+-#ifdef CONFIG_XICS
+-	case IC_PPC_XIC:
+-		smp_ops = &pSeries_xics_smp_ops;
+-		break;
+-#endif
+-#ifdef CONFIG_BPA_IIC
+-	case IC_BPA_IIC:
+-		smp_ops = &bpa_iic_smp_ops;
+-		break;
+-#endif
+-	default:
+-		panic("Invalid interrupt controller");
+-	}
+-
+-#ifdef CONFIG_HOTPLUG_CPU
+-	smp_ops->cpu_disable = pSeries_cpu_disable;
+-	smp_ops->cpu_die = pSeries_cpu_die;
+-
+-	/* Processors can be added/removed only on LPAR */
+-	if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
+-		pSeries_reconfig_notifier_register(&pSeries_smp_nb);
+-#endif
+-
+-	/* Mark threads which are still spinning in hold loops. */
+-	if (cpu_has_feature(CPU_FTR_SMT)) {
+-		for_each_present_cpu(i) { 
+-			if (i % 2 == 0)
+-				/*
+-				 * Even-numbered logical cpus correspond to
+-				 * primary threads.
+-				 */
+-				cpu_set(i, of_spin_map);
+-		}
+-	} else {
+-		of_spin_map = cpu_present_map;
+-	}
+-
+-	cpu_clear(boot_cpuid, of_spin_map);
+-
+-	/* Non-lpar has additional take/give timebase */
+-	if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
+-		smp_ops->give_timebase = pSeries_give_timebase;
+-		smp_ops->take_timebase = pSeries_take_timebase;
+-	}
+-
+-	DBG(" <- smp_init_pSeries()\n");
+-}
+-
+diff --git a/arch/ppc64/kernel/pSeries_vio.c b/arch/ppc64/kernel/pSeries_vio.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pSeries_vio.c
++++ /dev/null
+@@ -1,273 +0,0 @@
+-/*
+- * IBM PowerPC pSeries Virtual I/O Infrastructure Support.
+- *
+- *    Copyright (c) 2003-2005 IBM Corp.
+- *     Dave Engebretsen engebret at us.ibm.com
+- *     Santiago Leon santil at us.ibm.com
+- *     Hollis Blanchard <hollisb at us.ibm.com>
+- *     Stephen Rothwell
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/module.h>
+-#include <linux/mm.h>
+-#include <linux/kobject.h>
+-#include <asm/iommu.h>
+-#include <asm/dma.h>
+-#include <asm/prom.h>
+-#include <asm/vio.h>
+-#include <asm/hvcall.h>
+-
+-extern struct subsystem devices_subsys; /* needed for vio_find_name() */
+-
+-static void probe_bus_pseries(void)
+-{
+-	struct device_node *node_vroot, *of_node;
+-
+-	node_vroot = find_devices("vdevice");
+-	if ((node_vroot == NULL) || (node_vroot->child == NULL))
+-		/* this machine doesn't do virtual IO, and that's ok */
+-		return;
+-
+-	/*
+-	 * Create struct vio_devices for each virtual device in the device tree.
+-	 * Drivers will associate with them later.
+-	 */
+-	for (of_node = node_vroot->child; of_node != NULL;
+-			of_node = of_node->sibling) {
+-		printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node);
+-		vio_register_device_node(of_node);
+-	}
+-}
+-
+-/**
+- * vio_match_device_pseries: - Tell if a pSeries VIO device matches a
+- *	vio_device_id
+- */
+-static int vio_match_device_pseries(const struct vio_device_id *id,
+-		const struct vio_dev *dev)
+-{
+-	return (strncmp(dev->type, id->type, strlen(id->type)) == 0) &&
+-			device_is_compatible(dev->dev.platform_data, id->compat);
+-}
+-
+-static void vio_release_device_pseries(struct device *dev)
+-{
+-	/* XXX free TCE table */
+-	of_node_put(dev->platform_data);
+-}
+-
+-static ssize_t viodev_show_devspec(struct device *dev,
+-		struct device_attribute *attr, char *buf)
+-{
+-	struct device_node *of_node = dev->platform_data;
+-
+-	return sprintf(buf, "%s\n", of_node->full_name);
+-}
+-DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
+-
+-static void vio_unregister_device_pseries(struct vio_dev *viodev)
+-{
+-	device_remove_file(&viodev->dev, &dev_attr_devspec);
+-}
+-
+-static struct vio_bus_ops vio_bus_ops_pseries = {
+-	.match = vio_match_device_pseries,
+-	.unregister_device = vio_unregister_device_pseries,
+-	.release_device = vio_release_device_pseries,
+-};
+-
+-/**
+- * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
+- */
+-static int __init vio_bus_init_pseries(void)
+-{
+-	int err;
+-
+-	err = vio_bus_init(&vio_bus_ops_pseries);
+-	if (err == 0)
+-		probe_bus_pseries();
+-	return err;
+-}
+-
+-__initcall(vio_bus_init_pseries);
+-
+-/**
+- * vio_build_iommu_table: - gets the dma information from OF and
+- *	builds the TCE tree.
+- * @dev: the virtual device.
+- *
+- * Returns a pointer to the built tce tree, or NULL if it can't
+- * find property.
+-*/
+-static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
+-{
+-	unsigned int *dma_window;
+-	struct iommu_table *newTceTable;
+-	unsigned long offset;
+-	int dma_window_property_size;
+-
+-	dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
+-	if(!dma_window) {
+-		return NULL;
+-	}
+-
+-	newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+-
+-	/*  There should be some code to extract the phys-encoded offset
+-		using prom_n_addr_cells(). However, according to a comment
+-		on earlier versions, it's always zero, so we don't bother */
+-	offset = dma_window[1] >>  PAGE_SHIFT;
+-
+-	/* TCE table size - measured in tce entries */
+-	newTceTable->it_size		= dma_window[4] >> PAGE_SHIFT;
+-	/* offset for VIO should always be 0 */
+-	newTceTable->it_offset		= offset;
+-	newTceTable->it_busno		= 0;
+-	newTceTable->it_index		= (unsigned long)dma_window[0];
+-	newTceTable->it_type		= TCE_VB;
+-
+-	return iommu_init_table(newTceTable);
+-}
+-
+-/**
+- * vio_register_device_node: - Register a new vio device.
+- * @of_node:	The OF node for this device.
+- *
+- * Creates and initializes a vio_dev structure from the data in
+- * of_node (dev.platform_data) and adds it to the list of virtual devices.
+- * Returns a pointer to the created vio_dev or NULL if node has
+- * NULL device_type or compatible fields.
+- */
+-struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
+-{
+-	struct vio_dev *viodev;
+-	unsigned int *unit_address;
+-	unsigned int *irq_p;
+-
+-	/* we need the 'device_type' property, in order to match with drivers */
+-	if ((NULL == of_node->type)) {
+-		printk(KERN_WARNING
+-			"%s: node %s missing 'device_type'\n", __FUNCTION__,
+-			of_node->name ? of_node->name : "<unknown>");
+-		return NULL;
+-	}
+-
+-	unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
+-	if (!unit_address) {
+-		printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__,
+-			of_node->name ? of_node->name : "<unknown>");
+-		return NULL;
+-	}
+-
+-	/* allocate a vio_dev for this node */
+-	viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
+-	if (!viodev) {
+-		return NULL;
+-	}
+-	memset(viodev, 0, sizeof(struct vio_dev));
+-
+-	viodev->dev.platform_data = of_node_get(of_node);
+-
+-	viodev->irq = NO_IRQ;
+-	irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
+-	if (irq_p) {
+-		int virq = virt_irq_create_mapping(*irq_p);
+-		if (virq == NO_IRQ) {
+-			printk(KERN_ERR "Unable to allocate interrupt "
+-			       "number for %s\n", of_node->full_name);
+-		} else
+-			viodev->irq = irq_offset_up(virq);
+-	}
+-
+-	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
+-	viodev->name = of_node->name;
+-	viodev->type = of_node->type;
+-	viodev->unit_address = *unit_address;
+-	viodev->iommu_table = vio_build_iommu_table(viodev);
+-
+-	/* register with generic device framework */
+-	if (vio_register_device(viodev) == NULL) {
+-		/* XXX free TCE table */
+-		kfree(viodev);
+-		return NULL;
+-	}
+-	device_create_file(&viodev->dev, &dev_attr_devspec);
+-
+-	return viodev;
+-}
+-EXPORT_SYMBOL(vio_register_device_node);
+-
+-/**
+- * vio_get_attribute: - get attribute for virtual device
+- * @vdev:	The vio device to get property.
+- * @which:	The property/attribute to be extracted.
+- * @length:	Pointer to length of returned data size (unused if NULL).
+- *
+- * Calls prom.c's get_property() to return the value of the
+- * attribute specified by the preprocessor constant @which
+-*/
+-const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
+-{
+-	return get_property(vdev->dev.platform_data, (char*)which, length);
+-}
+-EXPORT_SYMBOL(vio_get_attribute);
+-
+-/* vio_find_name() - internal because only vio.c knows how we formatted the
+- * kobject name
+- * XXX once vio_bus_type.devices is actually used as a kset in
+- * drivers/base/bus.c, this function should be removed in favor of
+- * "device_find(kobj_name, &vio_bus_type)"
+- */
+-static struct vio_dev *vio_find_name(const char *kobj_name)
+-{
+-	struct kobject *found;
+-
+-	found = kset_find_obj(&devices_subsys.kset, kobj_name);
+-	if (!found)
+-		return NULL;
+-
+-	return to_vio_dev(container_of(found, struct device, kobj));
+-}
+-
+-/**
+- * vio_find_node - find an already-registered vio_dev
+- * @vnode: device_node of the virtual device we're looking for
+- */
+-struct vio_dev *vio_find_node(struct device_node *vnode)
+-{
+-	uint32_t *unit_address;
+-	char kobj_name[BUS_ID_SIZE];
+-
+-	/* construct the kobject name from the device node */
+-	unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
+-	if (!unit_address)
+-		return NULL;
+-	snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
+-
+-	return vio_find_name(kobj_name);
+-}
+-EXPORT_SYMBOL(vio_find_node);
+-
+-int vio_enable_interrupts(struct vio_dev *dev)
+-{
+-	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
+-	if (rc != H_Success)
+-		printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
+-	return rc;
+-}
+-EXPORT_SYMBOL(vio_enable_interrupts);
+-
+-int vio_disable_interrupts(struct vio_dev *dev)
+-{
+-	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
+-	if (rc != H_Success)
+-		printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
+-	return rc;
+-}
+-EXPORT_SYMBOL(vio_disable_interrupts);
+diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
+--- a/arch/ppc64/kernel/pci.c
++++ b/arch/ppc64/kernel/pci.c
+@@ -31,8 +31,7 @@
+ #include <asm/irq.h>
+ #include <asm/machdep.h>
+ #include <asm/udbg.h>
+-
+-#include "pci.h"
++#include <asm/ppc-pci.h>
+ 
+ #ifdef DEBUG
+ #define DBG(fmt...) udbg_printf(fmt)
+@@ -727,16 +726,17 @@ static pgprot_t __pci_mmap_set_pgprot(st
+  * above routine
+  */
+ pgprot_t pci_phys_mem_access_prot(struct file *file,
+-				  unsigned long offset,
++				  unsigned long pfn,
+ 				  unsigned long size,
+ 				  pgprot_t protection)
+ {
+ 	struct pci_dev *pdev = NULL;
+ 	struct resource *found = NULL;
+ 	unsigned long prot = pgprot_val(protection);
++	unsigned long offset = pfn << PAGE_SHIFT;
+ 	int i;
+ 
+-	if (page_is_ram(offset >> PAGE_SHIFT))
++	if (page_is_ram(pfn))
+ 		return __pgprot(prot);
+ 
+ 	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+@@ -881,9 +881,9 @@ static void __devinit pci_process_ISA_OF
+ }
+ 
+ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+-					    struct device_node *dev)
++					    struct device_node *dev, int prim)
+ {
+-	unsigned int *ranges;
++	unsigned int *ranges, pci_space;
+ 	unsigned long size;
+ 	int rlen = 0;
+ 	int memno = 0;
+@@ -906,16 +906,39 @@ void __devinit pci_process_bridge_OF_ran
+ 	ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+ 	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+ 		res = NULL;
+-		pci_addr = (unsigned long)ranges[1] << 32 | ranges[2];
++		pci_space = ranges[0];
++		pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
+ 
+ 		cpu_phys_addr = ranges[3];
+-		if (na == 2)
+-			cpu_phys_addr = cpu_phys_addr << 32 | ranges[4];
++		if (na >= 2)
++			cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
+ 
+-		size = (unsigned long)ranges[na+3] << 32 | ranges[na+4];
++		size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
++		ranges += np;
+ 		if (size == 0)
+ 			continue;
+-		switch ((ranges[0] >> 24) & 0x3) {
++
++		/* Now consume following elements while they are contiguous */
++		while (rlen >= np * sizeof(unsigned int)) {
++			unsigned long addr, phys;
++
++			if (ranges[0] != pci_space)
++				break;
++			addr = ((unsigned long)ranges[1] << 32) | ranges[2];
++			phys = ranges[3];
++			if (na >= 2)
++				phys = (phys << 32) | ranges[4];
++			if (addr != pci_addr + size ||
++			    phys != cpu_phys_addr + size)
++				break;
++
++			size += ((unsigned long)ranges[na+3] << 32)
++				| ranges[na+4];
++			ranges += np;
++			rlen -= np * sizeof(unsigned int);
++		}
++
++		switch ((pci_space >> 24) & 0x3) {
+ 		case 1:		/* I/O space */
+ 			hose->io_base_phys = cpu_phys_addr;
+ 			hose->pci_io_size = size;
+@@ -949,7 +972,6 @@ void __devinit pci_process_bridge_OF_ran
+ 			res->sibling = NULL;
+ 			res->child = NULL;
+ 		}
+-		ranges += np;
+ 	}
+ }
+ 
+diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pci.h
++++ /dev/null
+@@ -1,54 +0,0 @@
+-/*
+- * c 2001 PPC 64 Team, IBM Corp
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the GNU General Public License
+- *      as published by the Free Software Foundation; either version
+- *      2 of the License, or (at your option) any later version.
+- */
+-#ifndef __PPC_KERNEL_PCI_H__
+-#define __PPC_KERNEL_PCI_H__
+-
+-#include <linux/pci.h>
+-#include <asm/pci-bridge.h>
+-
+-extern unsigned long isa_io_base;
+-
+-extern void pci_setup_pci_controller(struct pci_controller *hose);
+-extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
+-extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary);
+-
+-
+-extern struct list_head hose_list;
+-extern int global_phb_number;
+-
+-extern unsigned long find_and_init_phbs(void);
+-
+-extern struct pci_dev *ppc64_isabridge_dev;	/* may be NULL if no ISA bus */
+-
+-/* PCI device_node operations */
+-struct device_node;
+-typedef void *(*traverse_func)(struct device_node *me, void *data);
+-void *traverse_pci_devices(struct device_node *start, traverse_func pre,
+-		void *data);
+-
+-void pci_devs_phb_init(void);
+-void pci_devs_phb_init_dynamic(struct pci_controller *phb);
+-
+-/* PCI address cache management routines */
+-void pci_addr_cache_insert_device(struct pci_dev *dev);
+-void pci_addr_cache_remove_device(struct pci_dev *dev);
+-
+-/* From rtas_pci.h */
+-void init_pci_config_tokens (void);
+-unsigned long get_phb_buid (struct device_node *);
+-
+-/* From pSeries_pci.h */
+-extern void pSeries_final_fixup(void);
+-extern void pSeries_irq_bus_setup(struct pci_bus *bus);
+-
+-extern unsigned long pci_probe_only;
+-extern unsigned long pci_assign_all_buses;
+-extern int pci_read_irq_line(struct pci_dev *pci_dev);
+-
+-#endif /* __PPC_KERNEL_PCI_H__ */
+diff --git a/arch/ppc64/kernel/pci_direct_iommu.c b/arch/ppc64/kernel/pci_direct_iommu.c
+--- a/arch/ppc64/kernel/pci_direct_iommu.c
++++ b/arch/ppc64/kernel/pci_direct_iommu.c
+@@ -27,8 +27,7 @@
+ #include <asm/machdep.h>
+ #include <asm/pmac_feature.h>
+ #include <asm/abs_addr.h>
+-
+-#include "pci.h"
++#include <asm/ppc-pci.h>
+ 
+ static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
+ 				   dma_addr_t *dma_handle, gfp_t flag)
+diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
+--- a/arch/ppc64/kernel/pci_dn.c
++++ b/arch/ppc64/kernel/pci_dn.c
+@@ -30,8 +30,7 @@
+ #include <asm/prom.h>
+ #include <asm/pci-bridge.h>
+ #include <asm/pSeries_reconfig.h>
+-
+-#include "pci.h"
++#include <asm/ppc-pci.h>
+ 
+ /*
+  * Traverse_func that inits the PCI fields of the device node.
+diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c
+--- a/arch/ppc64/kernel/pci_iommu.c
++++ b/arch/ppc64/kernel/pci_iommu.c
+@@ -1,8 +1,8 @@
+ /*
+  * arch/ppc64/kernel/pci_iommu.c
+  * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+- * 
+- * Rewrite, cleanup, new allocation schemes: 
++ *
++ * Rewrite, cleanup, new allocation schemes:
+  * Copyright (C) 2004 Olof Johansson, IBM Corporation
+  *
+  * Dynamic DMA mapping support, platform-independent parts.
+@@ -11,19 +11,18 @@
+  * it under the terms of the 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/config.h>
+ #include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/slab.h>
+@@ -37,11 +36,7 @@
+ #include <asm/iommu.h>
+ #include <asm/pci-bridge.h>
+ #include <asm/machdep.h>
+-#include "pci.h"
+-
+-#ifdef CONFIG_PPC_ISERIES
+-#include <asm/iSeries/iSeries_pci.h>
+-#endif /* CONFIG_PPC_ISERIES */
++#include <asm/ppc-pci.h>
+ 
+ /*
+  * We can use ->sysdata directly and avoid the extra work in
+@@ -61,13 +56,7 @@ static inline struct iommu_table *devnod
+ 	} else
+ 		pdev = to_pci_dev(dev);
+ 
+-#ifdef CONFIG_PPC_ISERIES
+-	return ISERIES_DEVNODE(pdev)->iommu_table;
+-#endif /* CONFIG_PPC_ISERIES */
+-
+-#ifdef CONFIG_PPC_MULTIPLATFORM
+ 	return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
+-#endif /* CONFIG_PPC_MULTIPLATFORM */
+ }
+ 
+ 
+diff --git a/arch/ppc64/kernel/pmac.h b/arch/ppc64/kernel/pmac.h
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pmac.h
++++ /dev/null
+@@ -1,31 +0,0 @@
+-#ifndef __PMAC_H__
+-#define __PMAC_H__
+-
+-#include <linux/pci.h>
+-#include <linux/ide.h>
+-
+-/*
+- * Declaration for the various functions exported by the
+- * pmac_* files. Mostly for use by pmac_setup
+- */
+-
+-extern void pmac_get_boot_time(struct rtc_time *tm);
+-extern void pmac_get_rtc_time(struct rtc_time *tm);
+-extern int  pmac_set_rtc_time(struct rtc_time *tm);
+-extern void pmac_read_rtc_time(void);
+-extern void pmac_calibrate_decr(void);
+-
+-extern void pmac_pcibios_fixup(void);
+-extern void pmac_pci_init(void);
+-extern void pmac_setup_pci_dma(void);
+-extern void pmac_check_ht_link(void);
+-
+-extern void pmac_setup_smp(void);
+-
+-extern unsigned long pmac_ide_get_base(int index);
+-extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
+-	unsigned long data_port, unsigned long ctrl_port, int *irq);
+-
+-extern void pmac_nvram_init(void);
+-
+-#endif /* __PMAC_H__ */
+diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pmac_feature.c
++++ /dev/null
+@@ -1,767 +0,0 @@
+-/*
+- *  arch/ppc/platforms/pmac_feature.c
+- *
+- *  Copyright (C) 1996-2001 Paul Mackerras (paulus at cs.anu.edu.au)
+- *                          Ben. Herrenschmidt (benh at 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.
+- *
+- *  TODO:
+- *
+- *   - Replace mdelay with some schedule loop if possible
+- *   - Shorten some obfuscated delays on some routines (like modem
+- *     power)
+- *   - Refcount some clocks (see darwin)
+- *   - Split split split...
+- *
+- */
+-#include <linux/config.h>
+-#include <linux/types.h>
+-#include <linux/init.h>
+-#include <linux/delay.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/spinlock.h>
+-#include <linux/adb.h>
+-#include <linux/pmu.h>
+-#include <linux/ioport.h>
+-#include <linux/pci.h>
+-#include <asm/sections.h>
+-#include <asm/errno.h>
+-#include <asm/keylargo.h>
+-#include <asm/uninorth.h>
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/machdep.h>
+-#include <asm/pmac_feature.h>
+-#include <asm/dbdma.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/pmac_low_i2c.h>
+-
+-#undef DEBUG_FEATURE
+-
+-#ifdef DEBUG_FEATURE
+-#define DBG(fmt...) printk(KERN_DEBUG fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-/*
+- * We use a single global lock to protect accesses. Each driver has
+- * to take care of its own locking
+- */
+-static DEFINE_SPINLOCK(feature_lock  __pmacdata);
+-
+-#define LOCK(flags)	spin_lock_irqsave(&feature_lock, flags);
+-#define UNLOCK(flags)	spin_unlock_irqrestore(&feature_lock, flags);
+-
+-
+-/*
+- * Instance of some macio stuffs
+- */
+-struct macio_chip macio_chips[MAX_MACIO_CHIPS]  __pmacdata;
+-
+-struct macio_chip* __pmac macio_find(struct device_node* child, int type)
+-{
+-	while(child) {
+-		int	i;
+-
+-		for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
+-			if (child == macio_chips[i].of_node &&
+-			    (!type || macio_chips[i].type == type))
+-				return &macio_chips[i];
+-		child = child->parent;
+-	}
+-	return NULL;
+-}
+-EXPORT_SYMBOL_GPL(macio_find);
+-
+-static const char* macio_names[] __pmacdata =
+-{
+-	"Unknown",
+-	"Grand Central",
+-	"OHare",
+-	"OHareII",
+-	"Heathrow",
+-	"Gatwick",
+-	"Paddington",
+-	"Keylargo",
+-	"Pangea",
+-	"Intrepid",
+-	"K2"
+-};
+-
+-
+-
+-/*
+- * Uninorth reg. access. Note that Uni-N regs are big endian
+- */
+-
+-#define UN_REG(r)	(uninorth_base + ((r) >> 2))
+-#define UN_IN(r)	(in_be32(UN_REG(r)))
+-#define UN_OUT(r,v)	(out_be32(UN_REG(r), (v)))
+-#define UN_BIS(r,v)	(UN_OUT((r), UN_IN(r) | (v)))
+-#define UN_BIC(r,v)	(UN_OUT((r), UN_IN(r) & ~(v)))
+-
+-static struct device_node* uninorth_node __pmacdata;
+-static u32* uninorth_base __pmacdata;
+-static u32 uninorth_rev __pmacdata;
+-static void *u3_ht;
+-
+-extern struct device_node *k2_skiplist[2];
+-
+-/*
+- * For each motherboard family, we have a table of functions pointers
+- * that handle the various features.
+- */
+-
+-typedef long (*feature_call)(struct device_node* node, long param, long value);
+-
+-struct feature_table_entry {
+-	unsigned int	selector;
+-	feature_call	function;
+-};
+-
+-struct pmac_mb_def
+-{
+-	const char*			model_string;
+-	const char*			model_name;
+-	int				model_id;
+-	struct feature_table_entry* 	features;
+-	unsigned long			board_flags;
+-};
+-static struct pmac_mb_def pmac_mb __pmacdata;
+-
+-/*
+- * Here are the chip specific feature functions
+- */
+-
+-
+-static long __pmac g5_read_gpio(struct device_node* node, long param, long value)
+-{
+-	struct macio_chip* macio = &macio_chips[0];
+-
+-	return MACIO_IN8(param);
+-}
+-
+-
+-static long __pmac g5_write_gpio(struct device_node* node, long param, long value)
+-{
+-	struct macio_chip* macio = &macio_chips[0];
+-
+-	MACIO_OUT8(param, (u8)(value & 0xff));
+-	return 0;
+-}
+-
+-static long __pmac g5_gmac_enable(struct device_node* node, long param, long value)
+-{
+-	struct macio_chip* macio = &macio_chips[0];
+-	unsigned long flags;
+-
+-	if (node == NULL)
+-		return -ENODEV;
+-
+-	LOCK(flags);
+-	if (value) {
+-		MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
+-		mb();
+-		k2_skiplist[0] = NULL;
+-	} else {
+-		k2_skiplist[0] = node;
+-		mb();
+-		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
+-	}
+-	
+-	UNLOCK(flags);
+-	mdelay(1);
+-
+-	return 0;
+-}
+-
+-static long __pmac g5_fw_enable(struct device_node* node, long param, long value)
+-{
+-	struct macio_chip* macio = &macio_chips[0];
+-	unsigned long flags;
+-
+-	if (node == NULL)
+-		return -ENODEV;
+-
+-	LOCK(flags);
+-	if (value) {
+-		MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
+-		mb();
+-		k2_skiplist[1] = NULL;
+-	} else {
+-		k2_skiplist[1] = node;
+-		mb();
+-		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
+-	}
+-	
+-	UNLOCK(flags);
+-	mdelay(1);
+-
+-	return 0;
+-}
+-
+-static long __pmac g5_mpic_enable(struct device_node* node, long param, long value)
+-{
+-	unsigned long flags;
+-
+-	if (node->parent == NULL || strcmp(node->parent->name, "u3"))
+-		return 0;
+-
+-	LOCK(flags);
+-	UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
+-	UNLOCK(flags);
+-
+-	return 0;
+-}
+-
+-static long __pmac g5_eth_phy_reset(struct device_node* node, long param, long value)
+-{
+-	struct macio_chip* macio = &macio_chips[0];
+-	struct device_node *phy;
+-	int need_reset;
+-
+-	/*
+-	 * We must not reset the combo PHYs, only the BCM5221 found in
+-	 * the iMac G5.
+-	 */
+-	phy = of_get_next_child(node, NULL);
+-	if (!phy)
+-		return -ENODEV;
+-	need_reset = device_is_compatible(phy, "B5221");
+-	of_node_put(phy);
+-	if (!need_reset)
+-		return 0;
+-
+-	/* PHY reset is GPIO 29, not in device-tree unfortunately */
+-	MACIO_OUT8(K2_GPIO_EXTINT_0 + 29,
+-		   KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+-	/* Thankfully, this is now always called at a time when we can
+-	 * schedule by sungem.
+-	 */
+-	msleep(10);
+-	MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0);
+-
+-	return 0;
+-}
+-
+-static long __pmac g5_i2s_enable(struct device_node *node, long param, long value)
+-{
+-	/* Very crude implementation for now */
+-	struct macio_chip* macio = &macio_chips[0];
+-	unsigned long flags;
+-
+-	if (value == 0)
+-		return 0; /* don't disable yet */
+-
+-	LOCK(flags);
+-	MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE |
+-		  KL3_I2S0_CLK18_ENABLE);
+-	udelay(10);
+-	MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE |
+-		  K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE);
+-	udelay(10);
+-	MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET);
+-	UNLOCK(flags);
+-	udelay(10);
+-
+-	return 0;
+-}
+-
+-
+-#ifdef CONFIG_SMP
+-static long __pmac g5_reset_cpu(struct device_node* node, long param, long value)
+-{
+-	unsigned int reset_io = 0;
+-	unsigned long flags;
+-	struct macio_chip* macio;
+-	struct device_node* np;
+-
+-	macio = &macio_chips[0];
+-	if (macio->type != macio_keylargo2)
+-		return -ENODEV;
+-
+-	np = find_path_device("/cpus");
+-	if (np == NULL)
+-		return -ENODEV;
+-	for (np = np->child; np != NULL; np = np->sibling) {
+-		u32* num = (u32 *)get_property(np, "reg", NULL);
+-		u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
+-		if (num == NULL || rst == NULL)
+-			continue;
+-		if (param == *num) {
+-			reset_io = *rst;
+-			break;
+-		}
+-	}
+-	if (np == NULL || reset_io == 0)
+-		return -ENODEV;
+-
+-	LOCK(flags);
+-	MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
+-	(void)MACIO_IN8(reset_io);
+-	udelay(1);
+-	MACIO_OUT8(reset_io, 0);
+-	(void)MACIO_IN8(reset_io);
+-	UNLOCK(flags);
+-
+-	return 0;
+-}
+-#endif /* CONFIG_SMP */
+-
+-/*
+- * This can be called from pmac_smp so isn't static
+- *
+- * This takes the second CPU off the bus on dual CPU machines
+- * running UP
+- */
+-void __pmac g5_phy_disable_cpu1(void)
+-{
+-	UN_OUT(U3_API_PHY_CONFIG_1, 0);
+-}
+-
+-static long __pmac generic_get_mb_info(struct device_node* node, long param, long value)
+-{
+-	switch(param) {
+-		case PMAC_MB_INFO_MODEL:
+-			return pmac_mb.model_id;
+-		case PMAC_MB_INFO_FLAGS:
+-			return pmac_mb.board_flags;
+-		case PMAC_MB_INFO_NAME:			
+-			/* hack hack hack... but should work */
+-			*((const char **)value) = pmac_mb.model_name;
+-			return 0;
+-	}
+-	return -EINVAL;
+-}
+-
+-
+-/*
+- * Table definitions
+- */
+-
+-/* Used on any machine
+- */
+-static struct feature_table_entry any_features[]  __pmacdata = {
+-	{ PMAC_FTR_GET_MB_INFO,		generic_get_mb_info },
+-	{ 0, NULL }
+-};
+-
+-/* G5 features
+- */
+-static struct feature_table_entry g5_features[]  __pmacdata = {
+-	{ PMAC_FTR_GMAC_ENABLE,		g5_gmac_enable },
+-	{ PMAC_FTR_1394_ENABLE,		g5_fw_enable },
+-	{ PMAC_FTR_ENABLE_MPIC,		g5_mpic_enable },
+-	{ PMAC_FTR_READ_GPIO,		g5_read_gpio },
+-	{ PMAC_FTR_WRITE_GPIO,		g5_write_gpio },
+-	{ PMAC_FTR_GMAC_PHY_RESET,	g5_eth_phy_reset },
+-	{ PMAC_FTR_SOUND_CHIP_ENABLE,	g5_i2s_enable },
+-#ifdef CONFIG_SMP
+-	{ PMAC_FTR_RESET_CPU,		g5_reset_cpu },
+-#endif /* CONFIG_SMP */
+-	{ 0, NULL }
+-};
+-
+-static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
+-	{	"PowerMac7,2",			"PowerMac G5",
+-		PMAC_TYPE_POWERMAC_G5,		g5_features,
+-		0,
+-	},
+-	{	"PowerMac7,3",			"PowerMac G5",
+-		PMAC_TYPE_POWERMAC_G5,		g5_features,
+-		0,
+-	},
+-	{	"PowerMac8,1",			"iMac G5",
+-		PMAC_TYPE_IMAC_G5,		g5_features,
+-		0,
+-	},
+-	{	"PowerMac9,1",			"PowerMac G5",
+-		PMAC_TYPE_POWERMAC_G5_U3L,	g5_features,
+-		0,
+-	},
+-	{       "RackMac3,1",                   "XServe G5",
+-		PMAC_TYPE_XSERVE_G5,		g5_features,
+-		0,
+-	},
+-};
+-
+-/*
+- * The toplevel feature_call callback
+- */
+-long __pmac pmac_do_feature_call(unsigned int selector, ...)
+-{
+-	struct device_node* node;
+-	long param, value;
+-	int i;
+-	feature_call func = NULL;
+-	va_list args;
+-
+-	if (pmac_mb.features)
+-		for (i=0; pmac_mb.features[i].function; i++)
+-			if (pmac_mb.features[i].selector == selector) {
+-				func = pmac_mb.features[i].function;
+-				break;
+-			}
+-	if (!func)
+-		for (i=0; any_features[i].function; i++)
+-			if (any_features[i].selector == selector) {
+-				func = any_features[i].function;
+-				break;
+-			}
+-	if (!func)
+-		return -ENODEV;
+-
+-	va_start(args, selector);
+-	node = (struct device_node*)va_arg(args, void*);
+-	param = va_arg(args, long);
+-	value = va_arg(args, long);
+-	va_end(args);
+-
+-	return func(node, param, value);
+-}
+-
+-static int __init probe_motherboard(void)
+-{
+-	int i;
+-	struct macio_chip* macio = &macio_chips[0];
+-	const char* model = NULL;
+-	struct device_node *dt;
+-
+-	/* Lookup known motherboard type in device-tree. First try an
+-	 * exact match on the "model" property, then try a "compatible"
+-	 * match is none is found.
+-	 */
+-	dt = find_devices("device-tree");
+-	if (dt != NULL)
+-		model = (const char *) get_property(dt, "model", NULL);
+-	for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
+-	    if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
+-		pmac_mb = pmac_mb_defs[i];
+-		goto found;
+-	    }
+-	}
+-	for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
+-	    if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
+-		pmac_mb = pmac_mb_defs[i];
+-		goto found;
+-	    }
+-	}
+-
+-	/* Fallback to selection depending on mac-io chip type */
+-	switch(macio->type) {
+-	case macio_keylargo2:
+-		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
+-		pmac_mb.model_name = "Unknown K2-based";
+-	    	pmac_mb.features = g5_features;
+-		
+-	default:
+-	    	return -ENODEV;
+-	}
+-found:
+-	/* Check for "mobile" machine */
+-	if (model && (strncmp(model, "PowerBook", 9) == 0
+-		   || strncmp(model, "iBook", 5) == 0))
+-		pmac_mb.board_flags |= PMAC_MB_MOBILE;
+-
+-
+-	printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
+-	return 0;
+-}
+-
+-/* Initialize the Core99 UniNorth host bridge and memory controller
+- */
+-static void __init probe_uninorth(void)
+-{
+-	uninorth_node = of_find_node_by_name(NULL, "u3");
+-	if (uninorth_node && uninorth_node->n_addrs > 0) {
+-		/* Small hack until I figure out if parsing in prom.c is correct. I should
+-		 * get rid of those pre-parsed junk anyway
+-		 */
+-		unsigned long address = uninorth_node->addrs[0].address;
+-		uninorth_base = ioremap(address, 0x40000);
+-		uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
+-		u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
+-	} else
+-		uninorth_node = NULL;
+-
+-	if (!uninorth_node)
+-		return;
+-
+-	printk(KERN_INFO "Found U3 memory controller & host bridge, revision: %d\n",
+-	       uninorth_rev);
+-	printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
+-
+-}
+-
+-static void __init probe_one_macio(const char* name, const char* compat, int type)
+-{
+-	struct device_node*	node;
+-	int			i;
+-	volatile u32*		base;
+-	u32*			revp;
+-
+-	node = find_devices(name);
+-	if (!node || !node->n_addrs)
+-		return;
+-	if (compat)
+-		do {
+-			if (device_is_compatible(node, compat))
+-				break;
+-			node = node->next;
+-		} while (node);
+-	if (!node)
+-		return;
+-	for(i=0; i<MAX_MACIO_CHIPS; i++) {
+-		if (!macio_chips[i].of_node)
+-			break;
+-		if (macio_chips[i].of_node == node)
+-			return;
+-	}
+-	if (i >= MAX_MACIO_CHIPS) {
+-		printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
+-		printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
+-		return;
+-	}
+-	base = (volatile u32*)ioremap(node->addrs[0].address, node->addrs[0].size);
+-	if (!base) {
+-		printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
+-		return;
+-	}
+-	if (type == macio_keylargo) {
+-		u32* did = (u32 *)get_property(node, "device-id", NULL);
+-		if (*did == 0x00000025)
+-			type = macio_pangea;
+-		if (*did == 0x0000003e)
+-			type = macio_intrepid;
+-	}
+-	macio_chips[i].of_node	= node;
+-	macio_chips[i].type	= type;
+-	macio_chips[i].base	= base;
+-	macio_chips[i].flags	= MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
+-	macio_chips[i].name 	= macio_names[type];
+-	revp = (u32 *)get_property(node, "revision-id", NULL);
+-	if (revp)
+-		macio_chips[i].rev = *revp;
+-	printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
+-		macio_names[type], macio_chips[i].rev, macio_chips[i].base);
+-}
+-
+-static int __init
+-probe_macios(void)
+-{
+-	probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
+-
+-	macio_chips[0].lbus.index = 0;
+-	macio_chips[1].lbus.index = 1;
+-
+-	return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
+-}
+-
+-static void __init
+-set_initial_features(void)
+-{
+-	struct device_node *np;
+-
+-	if (macio_chips[0].type == macio_keylargo2) {
+-#ifndef CONFIG_SMP
+-		/* On SMP machines running UP, we have the second CPU eating
+-		 * bus cycles. We need to take it off the bus. This is done
+-		 * from pmac_smp for SMP kernels running on one CPU
+-		 */
+-		np = of_find_node_by_type(NULL, "cpu");
+-		if (np != NULL)
+-			np = of_find_node_by_type(np, "cpu");
+-		if (np != NULL) {
+-			g5_phy_disable_cpu1();
+-			of_node_put(np);
+-		}
+-#endif /* CONFIG_SMP */
+-		/* Enable GMAC for now for PCI probing. It will be disabled
+-		 * later on after PCI probe
+-		 */
+-		np = of_find_node_by_name(NULL, "ethernet");
+-		while(np) {
+-			if (device_is_compatible(np, "K2-GMAC"))
+-				g5_gmac_enable(np, 0, 1);
+-			np = of_find_node_by_name(np, "ethernet");
+-		}
+-
+-		/* Enable FW before PCI probe. Will be disabled later on
+-		 * Note: We should have a batter way to check that we are
+-		 * dealing with uninorth internal cell and not a PCI cell
+-		 * on the external PCI. The code below works though.
+-		 */
+-		np = of_find_node_by_name(NULL, "firewire");
+-		while(np) {
+-			if (device_is_compatible(np, "pci106b,5811")) {
+-				macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
+-				g5_fw_enable(np, 0, 1);
+-			}
+-			np = of_find_node_by_name(np, "firewire");
+-		}
+-	}
+-}
+-
+-void __init
+-pmac_feature_init(void)
+-{
+-	/* Detect the UniNorth memory controller */
+-	probe_uninorth();
+-
+-	/* Probe mac-io controllers */
+-	if (probe_macios()) {
+-		printk(KERN_WARNING "No mac-io chip found\n");
+-		return;
+-	}
+-
+-	/* Setup low-level i2c stuffs */
+-	pmac_init_low_i2c();
+-
+-	/* Probe machine type */
+-	if (probe_motherboard())
+-		printk(KERN_WARNING "Unknown PowerMac !\n");
+-
+-	/* Set some initial features (turn off some chips that will
+-	 * be later turned on)
+-	 */
+-	set_initial_features();
+-}
+-
+-int __init pmac_feature_late_init(void)
+-{
+-#if 0
+-	struct device_node* np;
+-
+-	/* Request some resources late */
+-	if (uninorth_node)
+-		request_OF_resource(uninorth_node, 0, NULL);
+-	np = find_devices("hammerhead");
+-	if (np)
+-		request_OF_resource(np, 0, NULL);
+-	np = find_devices("interrupt-controller");
+-	if (np)
+-		request_OF_resource(np, 0, NULL);
+-#endif
+-	return 0;
+-}
+-
+-device_initcall(pmac_feature_late_init);
+-
+-#if 0
+-static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
+-{
+-	int	freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
+-	int	bits[8] = { 8,16,0,32,2,4,0,0 };
+-	int	freq = (frq >> 8) & 0xf;
+-
+-	if (freqs[freq] == 0)
+-		printk("%s: Unknown HT link frequency %x\n", name, freq);
+-	else
+-		printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
+-		       name, freqs[freq],
+-		       bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
+-}
+-#endif
+-
+-void __init pmac_check_ht_link(void)
+-{
+-#if 0 /* Disabled for now */
+-	u32	ufreq, freq, ucfg, cfg;
+-	struct device_node *pcix_node;
+-	struct pci_dn *pdn;
+-	u8  	px_bus, px_devfn;
+-	struct pci_controller *px_hose;
+-
+-	(void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
+-	ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
+-	ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
+-	dump_HT_speeds("U3 HyperTransport", cfg, freq);
+-
+-	pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
+-	if (pcix_node == NULL) {
+-		printk("No PCI-X bridge found\n");
+-		return;
+-	}
+-	pdn = pcix_node->data;
+-	px_hose = pdn->phb;
+-	px_bus = pdn->busno;
+-	px_devfn = pdn->devfn;
+-	
+-	early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
+-	early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
+-	dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
+-	early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
+-	early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
+-	dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
+-#endif
+-}
+-
+-/*
+- * Early video resume hook
+- */
+-
+-static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
+-static void *pmac_early_vresume_data __pmacdata;
+-
+-void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
+-{
+-	if (_machine != _MACH_Pmac)
+-		return;
+-	preempt_disable();
+-	pmac_early_vresume_proc = proc;
+-	pmac_early_vresume_data = data;
+-	preempt_enable();
+-}
+-EXPORT_SYMBOL(pmac_set_early_video_resume);
+-
+-
+-/*
+- * AGP related suspend/resume code
+- */
+-
+-static struct pci_dev *pmac_agp_bridge __pmacdata;
+-static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
+-static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
+-
+-void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
+-				 int (*suspend)(struct pci_dev *bridge),
+-				 int (*resume)(struct pci_dev *bridge))
+-{
+-	if (suspend || resume) {
+-		pmac_agp_bridge = bridge;
+-		pmac_agp_suspend = suspend;
+-		pmac_agp_resume = resume;
+-		return;
+-	}
+-	if (bridge != pmac_agp_bridge)
+-		return;
+-	pmac_agp_suspend = pmac_agp_resume = NULL;
+-	return;
+-}
+-EXPORT_SYMBOL(pmac_register_agp_pm);
+-
+-void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
+-{
+-	if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
+-		return;
+-	if (pmac_agp_bridge->bus != dev->bus)
+-		return;
+-	pmac_agp_suspend(pmac_agp_bridge);
+-}
+-EXPORT_SYMBOL(pmac_suspend_agp_for_card);
+-
+-void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
+-{
+-	if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
+-		return;
+-	if (pmac_agp_bridge->bus != dev->bus)
+-		return;
+-	pmac_agp_resume(pmac_agp_bridge);
+-}
+-EXPORT_SYMBOL(pmac_resume_agp_for_card);
+diff --git a/arch/ppc64/kernel/pmac_low_i2c.c b/arch/ppc64/kernel/pmac_low_i2c.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pmac_low_i2c.c
++++ /dev/null
+@@ -1,523 +0,0 @@
+-/*
+- *  arch/ppc/platforms/pmac_low_i2c.c
+- *
+- *  Copyright (C) 2003 Ben. Herrenschmidt (benh at 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.
+- *
+- *  This file contains some low-level i2c access routines that
+- *  need to be used by various bits of the PowerMac platform code
+- *  at times where the real asynchronous & interrupt driven driver
+- *  cannot be used. The API borrows some semantics from the darwin
+- *  driver in order to ease the implementation of the platform
+- *  properties parser
+- */
+-
+-#undef DEBUG
+-
+-#include <linux/config.h>
+-#include <linux/types.h>
+-#include <linux/sched.h>
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/adb.h>
+-#include <linux/pmu.h>
+-#include <asm/keylargo.h>
+-#include <asm/uninorth.h>
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/machdep.h>
+-#include <asm/pmac_low_i2c.h>
+-
+-#define MAX_LOW_I2C_HOST	4
+-
+-#ifdef DEBUG
+-#define DBG(x...) do {\
+-		printk(KERN_DEBUG "KW:" x);	\
+-	} while(0)
+-#else
+-#define DBG(x...)
+-#endif
+-
+-struct low_i2c_host;
+-
+-typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len);
+-
+-struct low_i2c_host
+-{
+-	struct device_node	*np;		/* OF device node */
+-	struct semaphore	mutex;		/* Access mutex for use by i2c-keywest */
+-	low_i2c_func_t		func;		/* Access function */
+-	unsigned int		is_open : 1;	/* Poor man's access control */
+-	int			mode;		/* Current mode */
+-	int			channel;	/* Current channel */
+-	int			num_channels;	/* Number of channels */
+-	void __iomem		*base;		/* For keywest-i2c, base address */
+-	int			bsteps;		/* And register stepping */
+-	int			speed;		/* And speed */
+-};
+-
+-static struct low_i2c_host	low_i2c_hosts[MAX_LOW_I2C_HOST];
+-
+-/* No locking is necessary on allocation, we are running way before
+- * anything can race with us
+- */
+-static struct low_i2c_host *find_low_i2c_host(struct device_node *np)
+-{
+-	int i;
+-
+-	for (i = 0; i < MAX_LOW_I2C_HOST; i++)
+-		if (low_i2c_hosts[i].np == np)
+-			return &low_i2c_hosts[i];
+-	return NULL;
+-}
+-
+-/*
+- *
+- * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's)
+- *
+- */
+-
+-/*
+- * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h,
+- * should be moved somewhere in include/asm-ppc/
+- */
+-/* Register indices */
+-typedef enum {
+-	reg_mode = 0,
+-	reg_control,
+-	reg_status,
+-	reg_isr,
+-	reg_ier,
+-	reg_addr,
+-	reg_subaddr,
+-	reg_data
+-} reg_t;
+-
+-
+-/* Mode register */
+-#define KW_I2C_MODE_100KHZ	0x00
+-#define KW_I2C_MODE_50KHZ	0x01
+-#define KW_I2C_MODE_25KHZ	0x02
+-#define KW_I2C_MODE_DUMB	0x00
+-#define KW_I2C_MODE_STANDARD	0x04
+-#define KW_I2C_MODE_STANDARDSUB	0x08
+-#define KW_I2C_MODE_COMBINED	0x0C
+-#define KW_I2C_MODE_MODE_MASK	0x0C
+-#define KW_I2C_MODE_CHAN_MASK	0xF0
+-
+-/* Control register */
+-#define KW_I2C_CTL_AAK		0x01
+-#define KW_I2C_CTL_XADDR	0x02
+-#define KW_I2C_CTL_STOP		0x04
+-#define KW_I2C_CTL_START	0x08
+-
+-/* Status register */
+-#define KW_I2C_STAT_BUSY	0x01
+-#define KW_I2C_STAT_LAST_AAK	0x02
+-#define KW_I2C_STAT_LAST_RW	0x04
+-#define KW_I2C_STAT_SDA		0x08
+-#define KW_I2C_STAT_SCL		0x10
+-
+-/* IER & ISR registers */
+-#define KW_I2C_IRQ_DATA		0x01
+-#define KW_I2C_IRQ_ADDR		0x02
+-#define KW_I2C_IRQ_STOP		0x04
+-#define KW_I2C_IRQ_START	0x08
+-#define KW_I2C_IRQ_MASK		0x0F
+-
+-/* State machine states */
+-enum {
+-	state_idle,
+-	state_addr,
+-	state_read,
+-	state_write,
+-	state_stop,
+-	state_dead
+-};
+-
+-#define WRONG_STATE(name) do {\
+-		printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \
+-		       name, __kw_state_names[state], isr); \
+-	} while(0)
+-
+-static const char *__kw_state_names[] = {
+-	"state_idle",
+-	"state_addr",
+-	"state_read",
+-	"state_write",
+-	"state_stop",
+-	"state_dead"
+-};
+-
+-static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg)
+-{
+-	return readb(host->base + (((unsigned int)reg) << host->bsteps));
+-}
+-
+-static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val)
+-{
+-	writeb(val, host->base + (((unsigned)reg) << host->bsteps));
+-	(void)__kw_read_reg(host, reg_subaddr);
+-}
+-
+-#define kw_write_reg(reg, val)	__kw_write_reg(host, reg, val) 
+-#define kw_read_reg(reg)	__kw_read_reg(host, reg) 
+-
+-
+-/* Don't schedule, the g5 fan controller is too
+- * timing sensitive
+- */
+-static u8 kw_wait_interrupt(struct low_i2c_host* host)
+-{
+-	int i, j;
+-	u8 isr;
+-	
+-	for (i = 0; i < 100000; i++) {
+-		isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK;
+-		if (isr != 0)
+-			return isr;
+-
+-		/* This code is used with the timebase frozen, we cannot rely
+-		 * on udelay ! For now, just use a bogus loop
+-		 */
+-		for (j = 1; j < 10000; j++)
+-			mb();
+-	}
+-	return isr;
+-}
+-
+-static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr)
+-{
+-	u8 ack;
+-
+-	DBG("kw_handle_interrupt(%s, isr: %x)\n", __kw_state_names[state], isr);
+-
+-	if (isr == 0) {
+-		if (state != state_stop) {
+-			DBG("KW: Timeout !\n");
+-			*rc = -EIO;
+-			goto stop;
+-		}
+-		if (state == state_stop) {
+-			ack = kw_read_reg(reg_status);
+-			if (!(ack & KW_I2C_STAT_BUSY)) {
+-				state = state_idle;
+-				kw_write_reg(reg_ier, 0x00);
+-			}
+-		}
+-		return state;
+-	}
+-
+-	if (isr & KW_I2C_IRQ_ADDR) {
+-		ack = kw_read_reg(reg_status);
+-		if (state != state_addr) {
+-			kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
+-			WRONG_STATE("KW_I2C_IRQ_ADDR"); 
+-			*rc = -EIO;
+-			goto stop;
+-		}
+-		if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {			
+-			*rc = -ENODEV;
+-			DBG("KW: NAK on address\n");
+-			return state_stop;		     
+-		} else {
+-			if (rw) {
+-				state = state_read;
+-				if (*len > 1)
+-					kw_write_reg(reg_control, KW_I2C_CTL_AAK);
+-			} else {
+-				state = state_write;
+-				kw_write_reg(reg_data, **data);
+-				(*data)++; (*len)--;
+-			}
+-		}
+-		kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
+-	}
+-
+-	if (isr & KW_I2C_IRQ_DATA) {
+-		if (state == state_read) {
+-			**data = kw_read_reg(reg_data);
+-			(*data)++; (*len)--;
+-			kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
+-			if ((*len) == 0)
+-				state = state_stop;
+-			else if ((*len) == 1)
+-				kw_write_reg(reg_control, 0);
+-		} else if (state == state_write) {
+-			ack = kw_read_reg(reg_status);
+-			if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
+-				DBG("KW: nack on data write\n");
+-				*rc = -EIO;
+-				goto stop;
+-			} else if (*len) {
+-				kw_write_reg(reg_data, **data);
+-				(*data)++; (*len)--;
+-			} else {
+-				kw_write_reg(reg_control, KW_I2C_CTL_STOP);
+-				state = state_stop;
+-				*rc = 0;
+-			}
+-			kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
+-		} else {
+-			kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
+-			WRONG_STATE("KW_I2C_IRQ_DATA"); 
+-			if (state != state_stop) {
+-				*rc = -EIO;
+-				goto stop;
+-			}
+-		}
+-	}
+-
+-	if (isr & KW_I2C_IRQ_STOP) {
+-		kw_write_reg(reg_isr, KW_I2C_IRQ_STOP);
+-		if (state != state_stop) {
+-			WRONG_STATE("KW_I2C_IRQ_STOP");
+-			*rc = -EIO;
+-		}
+-		return state_idle;
+-	}
+-
+-	if (isr & KW_I2C_IRQ_START)
+-		kw_write_reg(reg_isr, KW_I2C_IRQ_START);
+-
+-	return state;
+-
+- stop:
+-	kw_write_reg(reg_control, KW_I2C_CTL_STOP);	
+-	return state_stop;
+-}
+-
+-static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len)
+-{
+-	u8 mode_reg = host->speed;
+-	int state = state_addr;
+-	int rc = 0;
+-
+-	/* Setup mode & subaddress if any */
+-	switch(host->mode) {
+-	case pmac_low_i2c_mode_dumb:
+-		printk(KERN_ERR "low_i2c: Dumb mode not supported !\n");
+-		return -EINVAL;
+-	case pmac_low_i2c_mode_std:
+-		mode_reg |= KW_I2C_MODE_STANDARD;
+-		break;
+-	case pmac_low_i2c_mode_stdsub:
+-		mode_reg |= KW_I2C_MODE_STANDARDSUB;
+-		break;
+-	case pmac_low_i2c_mode_combined:
+-		mode_reg |= KW_I2C_MODE_COMBINED;
+-		break;
+-	}
+-
+-	/* Setup channel & clear pending irqs */
+-	kw_write_reg(reg_isr, kw_read_reg(reg_isr));
+-	kw_write_reg(reg_mode, mode_reg | (host->channel << 4));
+-	kw_write_reg(reg_status, 0);
+-
+-	/* Set up address and r/w bit */
+-	kw_write_reg(reg_addr, addr);
+-
+-	/* Set up the sub address */
+-	if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB
+-	    || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED)
+-		kw_write_reg(reg_subaddr, subaddr);
+-
+-	/* Start sending address & disable interrupt*/
+-	kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/);
+-	kw_write_reg(reg_control, KW_I2C_CTL_XADDR);
+-
+-	/* State machine, to turn into an interrupt handler */
+-	while(state != state_idle) {
+-		u8 isr = kw_wait_interrupt(host);
+-		state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr);
+-	}
+-
+-	return rc;
+-}
+-
+-static void keywest_low_i2c_add(struct device_node *np)
+-{
+-	struct low_i2c_host	*host = find_low_i2c_host(NULL);
+-	u32			*psteps, *prate, steps, aoffset = 0;
+-	struct device_node	*parent;
+-
+-	if (host == NULL) {
+-		printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
+-		       np->full_name);
+-		return;
+-	}
+-	memset(host, 0, sizeof(*host));
+-
+-	init_MUTEX(&host->mutex);
+-	host->np = of_node_get(np);	
+-	psteps = (u32 *)get_property(np, "AAPL,address-step", NULL);
+-	steps = psteps ? (*psteps) : 0x10;
+-	for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
+-		steps >>= 1;
+-	parent = of_get_parent(np);
+-	host->num_channels = 1;
+-	if (parent && parent->name[0] == 'u') {
+-		host->num_channels = 2;
+-		aoffset = 3;
+-	}
+-	/* Select interface rate */
+-	host->speed = KW_I2C_MODE_100KHZ;
+-	prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL);
+-	if (prate) switch(*prate) {
+-	case 100:
+-		host->speed = KW_I2C_MODE_100KHZ;
+-		break;
+-	case 50:
+-		host->speed = KW_I2C_MODE_50KHZ;
+-		break;
+-	case 25:
+-		host->speed = KW_I2C_MODE_25KHZ;
+-		break;
+-	}	
+-
+-	host->mode = pmac_low_i2c_mode_std;
+-	host->base = ioremap(np->addrs[0].address + aoffset,
+-						np->addrs[0].size);
+-	host->func = keywest_low_i2c_func;
+-}
+-
+-/*
+- *
+- * PMU implementation
+- *
+- */
+-
+-
+-#ifdef CONFIG_ADB_PMU
+-
+-static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len)
+-{
+-	// TODO
+-	return -ENODEV;
+-}
+-
+-static void pmu_low_i2c_add(struct device_node *np)
+-{
+-	struct low_i2c_host	*host = find_low_i2c_host(NULL);
+-
+-	if (host == NULL) {
+-		printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
+-		       np->full_name);
+-		return;
+-	}
+-	memset(host, 0, sizeof(*host));
+-
+-	init_MUTEX(&host->mutex);
+-	host->np = of_node_get(np);	
+-	host->num_channels = 3;
+-	host->mode = pmac_low_i2c_mode_std;
+-	host->func = pmu_low_i2c_func;
+-}
+-
+-#endif /* CONFIG_ADB_PMU */
+-
+-void __init pmac_init_low_i2c(void)
+-{
+-	struct device_node *np;
+-
+-	/* Probe keywest-i2c busses */
+-	np = of_find_compatible_node(NULL, "i2c", "keywest-i2c");
+-	while(np) {
+-		keywest_low_i2c_add(np);
+-		np = of_find_compatible_node(np, "i2c", "keywest-i2c");
+-	}
+-
+-#ifdef CONFIG_ADB_PMU
+-	/* Probe PMU busses */
+-	np = of_find_node_by_name(NULL, "via-pmu");
+-	if (np)
+-		pmu_low_i2c_add(np);
+-#endif /* CONFIG_ADB_PMU */
+-
+-	/* TODO: Add CUDA support as well */
+-}
+-
+-int pmac_low_i2c_lock(struct device_node *np)
+-{
+-	struct low_i2c_host *host = find_low_i2c_host(np);
+-
+-	if (!host)
+-		return -ENODEV;
+-	down(&host->mutex);
+-	return 0;
+-}
+-EXPORT_SYMBOL(pmac_low_i2c_lock);
+-
+-int pmac_low_i2c_unlock(struct device_node *np)
+-{
+-	struct low_i2c_host *host = find_low_i2c_host(np);
+-
+-	if (!host)
+-		return -ENODEV;
+-	up(&host->mutex);
+-	return 0;
+-}
+-EXPORT_SYMBOL(pmac_low_i2c_unlock);
+-
+-
+-int pmac_low_i2c_open(struct device_node *np, int channel)
+-{
+-	struct low_i2c_host *host = find_low_i2c_host(np);
+-
+-	if (!host)
+-		return -ENODEV;
+-
+-	if (channel >= host->num_channels)
+-		return -EINVAL;
+-
+-	down(&host->mutex);
+-	host->is_open = 1;
+-	host->channel = channel;
+-
+-	return 0;
+-}
+-EXPORT_SYMBOL(pmac_low_i2c_open);
+-
+-int pmac_low_i2c_close(struct device_node *np)
+-{
+-	struct low_i2c_host *host = find_low_i2c_host(np);
+-
+-	if (!host)
+-		return -ENODEV;
+-
+-	host->is_open = 0;
+-	up(&host->mutex);
+-
+-	return 0;
+-}
+-EXPORT_SYMBOL(pmac_low_i2c_close);
+-
+-int pmac_low_i2c_setmode(struct device_node *np, int mode)
+-{
+-	struct low_i2c_host *host = find_low_i2c_host(np);
+-
+-	if (!host)
+-		return -ENODEV;
+-	WARN_ON(!host->is_open);
+-	host->mode = mode;
+-
+-	return 0;
+-}
+-EXPORT_SYMBOL(pmac_low_i2c_setmode);
+-
+-int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len)
+-{
+-	struct low_i2c_host *host = find_low_i2c_host(np);
+-
+-	if (!host)
+-		return -ENODEV;
+-	WARN_ON(!host->is_open);
+-
+-	return host->func(host, addrdir, subaddr, data, len);
+-}
+-EXPORT_SYMBOL(pmac_low_i2c_xfer);
+-
+diff --git a/arch/ppc64/kernel/pmac_nvram.c b/arch/ppc64/kernel/pmac_nvram.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pmac_nvram.c
++++ /dev/null
+@@ -1,495 +0,0 @@
+-/*
+- *  arch/ppc/platforms/pmac_nvram.c
+- *
+- *  Copyright (C) 2002 Benjamin Herrenschmidt (benh at 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.
+- *
+- *  Todo: - add support for the OF persistent properties
+- */
+-#include <linux/config.h>
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/stddef.h>
+-#include <linux/string.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <linux/delay.h>
+-#include <linux/errno.h>
+-#include <linux/bootmem.h>
+-#include <linux/completion.h>
+-#include <linux/spinlock.h>
+-#include <asm/sections.h>
+-#include <asm/io.h>
+-#include <asm/system.h>
+-#include <asm/prom.h>
+-#include <asm/machdep.h>
+-#include <asm/nvram.h>
+-
+-#define DEBUG
+-
+-#ifdef DEBUG
+-#define DBG(x...) printk(x)
+-#else
+-#define DBG(x...)
+-#endif
+-
+-#define NVRAM_SIZE		0x2000	/* 8kB of non-volatile RAM */
+-
+-#define CORE99_SIGNATURE	0x5a
+-#define CORE99_ADLER_START	0x14
+-
+-/* On Core99, nvram is either a sharp, a micron or an AMD flash */
+-#define SM_FLASH_STATUS_DONE	0x80
+-#define SM_FLASH_STATUS_ERR	0x38
+-
+-#define SM_FLASH_CMD_ERASE_CONFIRM	0xd0
+-#define SM_FLASH_CMD_ERASE_SETUP	0x20
+-#define SM_FLASH_CMD_RESET		0xff
+-#define SM_FLASH_CMD_WRITE_SETUP	0x40
+-#define SM_FLASH_CMD_CLEAR_STATUS	0x50
+-#define SM_FLASH_CMD_READ_STATUS	0x70
+-
+-/* CHRP NVRAM header */
+-struct chrp_header {
+-  u8		signature;
+-  u8		cksum;
+-  u16		len;
+-  char          name[12];
+-  u8		data[0];
+-};
+-
+-struct core99_header {
+-  struct chrp_header	hdr;
+-  u32			adler;
+-  u32			generation;
+-  u32			reserved[2];
+-};
+-
+-/*
+- * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
+- */
+-static volatile unsigned char *nvram_data;
+-static int core99_bank = 0;
+-// XXX Turn that into a sem
+-static DEFINE_SPINLOCK(nv_lock);
+-
+-extern int system_running;
+-
+-static int (*core99_write_bank)(int bank, u8* datas);
+-static int (*core99_erase_bank)(int bank);
+-
+-static char *nvram_image __pmacdata;
+-
+-
+-static ssize_t __pmac core99_nvram_read(char *buf, size_t count, loff_t *index)
+-{
+-	int i;
+-
+-	if (nvram_image == NULL)
+-		return -ENODEV;
+-	if (*index > NVRAM_SIZE)
+-		return 0;
+-
+-	i = *index;
+-	if (i + count > NVRAM_SIZE)
+-		count = NVRAM_SIZE - i;
+-
+-	memcpy(buf, &nvram_image[i], count);
+-	*index = i + count;
+-	return count;
+-}
+-
+-static ssize_t __pmac core99_nvram_write(char *buf, size_t count, loff_t *index)
+-{
+-	int i;
+-
+-	if (nvram_image == NULL)
+-		return -ENODEV;
+-	if (*index > NVRAM_SIZE)
+-		return 0;
+-
+-	i = *index;
+-	if (i + count > NVRAM_SIZE)
+-		count = NVRAM_SIZE - i;
+-
+-	memcpy(&nvram_image[i], buf, count);
+-	*index = i + count;
+-	return count;
+-}
+-
+-static ssize_t __pmac core99_nvram_size(void)
+-{
+-	if (nvram_image == NULL)
+-		return -ENODEV;
+-	return NVRAM_SIZE;
+-}
+-
+-static u8 __pmac chrp_checksum(struct chrp_header* hdr)
+-{
+-	u8 *ptr;
+-	u16 sum = hdr->signature;
+-	for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
+-		sum += *ptr;
+-	while (sum > 0xFF)
+-		sum = (sum & 0xFF) + (sum>>8);
+-	return sum;
+-}
+-
+-static u32 __pmac core99_calc_adler(u8 *buffer)
+-{
+-	int cnt;
+-	u32 low, high;
+-
+-   	buffer += CORE99_ADLER_START;
+-	low = 1;
+-	high = 0;
+-	for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
+-		if ((cnt % 5000) == 0) {
+-			high  %= 65521UL;
+-			high %= 65521UL;
+-		}
+-		low += buffer[cnt];
+-		high += low;
+-	}
+-	low  %= 65521UL;
+-	high %= 65521UL;
+-
+-	return (high << 16) | low;
+-}
+-
+-static u32 __pmac core99_check(u8* datas)
+-{
+-	struct core99_header* hdr99 = (struct core99_header*)datas;
+-
+-	if (hdr99->hdr.signature != CORE99_SIGNATURE) {
+-		DBG("Invalid signature\n");
+-		return 0;
+-	}
+-	if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
+-		DBG("Invalid checksum\n");
+-		return 0;
+-	}
+-	if (hdr99->adler != core99_calc_adler(datas)) {
+-		DBG("Invalid adler\n");
+-		return 0;
+-	}
+-	return hdr99->generation;
+-}
+-
+-static int __pmac sm_erase_bank(int bank)
+-{
+-	int stat, i;
+-	unsigned long timeout;
+-
+-	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
+-
+-       	DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
+-
+-	out_8(base, SM_FLASH_CMD_ERASE_SETUP);
+-	out_8(base, SM_FLASH_CMD_ERASE_CONFIRM);
+-	timeout = 0;
+-	do {
+-		if (++timeout > 1000000) {
+-			printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n");
+-			break;
+-		}
+-		out_8(base, SM_FLASH_CMD_READ_STATUS);
+-		stat = in_8(base);
+-	} while (!(stat & SM_FLASH_STATUS_DONE));
+-
+-	out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
+-	out_8(base, SM_FLASH_CMD_RESET);
+-
+-	for (i=0; i<NVRAM_SIZE; i++)
+-		if (base[i] != 0xff) {
+-			printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n");
+-			return -ENXIO;
+-		}
+-	return 0;
+-}
+-
+-static int __pmac sm_write_bank(int bank, u8* datas)
+-{
+-	int i, stat = 0;
+-	unsigned long timeout;
+-
+-	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
+-
+-       	DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
+-
+-	for (i=0; i<NVRAM_SIZE; i++) {
+-		out_8(base+i, SM_FLASH_CMD_WRITE_SETUP);
+-		udelay(1);
+-		out_8(base+i, datas[i]);
+-		timeout = 0;
+-		do {
+-			if (++timeout > 1000000) {
+-				printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n");
+-				break;
+-			}
+-			out_8(base, SM_FLASH_CMD_READ_STATUS);
+-			stat = in_8(base);
+-		} while (!(stat & SM_FLASH_STATUS_DONE));
+-		if (!(stat & SM_FLASH_STATUS_DONE))
+-			break;
+-	}
+-	out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
+-	out_8(base, SM_FLASH_CMD_RESET);
+-	for (i=0; i<NVRAM_SIZE; i++)
+-		if (base[i] != datas[i]) {
+-			printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n");
+-			return -ENXIO;
+-		}
+-	return 0;
+-}
+-
+-static int __pmac amd_erase_bank(int bank)
+-{
+-	int i, stat = 0;
+-	unsigned long timeout;
+-
+-	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
+-
+-       	DBG("nvram: AMD Erasing bank %d...\n", bank);
+-
+-	/* Unlock 1 */
+-	out_8(base+0x555, 0xaa);
+-	udelay(1);
+-	/* Unlock 2 */
+-	out_8(base+0x2aa, 0x55);
+-	udelay(1);
+-
+-	/* Sector-Erase */
+-	out_8(base+0x555, 0x80);
+-	udelay(1);
+-	out_8(base+0x555, 0xaa);
+-	udelay(1);
+-	out_8(base+0x2aa, 0x55);
+-	udelay(1);
+-	out_8(base, 0x30);
+-	udelay(1);
+-
+-	timeout = 0;
+-	do {
+-		if (++timeout > 1000000) {
+-			printk(KERN_ERR "nvram: AMD flash erase timeout !\n");
+-			break;
+-		}
+-		stat = in_8(base) ^ in_8(base);
+-	} while (stat != 0);
+-	
+-	/* Reset */
+-	out_8(base, 0xf0);
+-	udelay(1);
+-	
+-	for (i=0; i<NVRAM_SIZE; i++)
+-		if (base[i] != 0xff) {
+-			printk(KERN_ERR "nvram: AMD flash erase failed !\n");
+-			return -ENXIO;
+-		}
+-	return 0;
+-}
+-
+-static int __pmac amd_write_bank(int bank, u8* datas)
+-{
+-	int i, stat = 0;
+-	unsigned long timeout;
+-
+-	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
+-
+-       	DBG("nvram: AMD Writing bank %d...\n", bank);
+-
+-	for (i=0; i<NVRAM_SIZE; i++) {
+-		/* Unlock 1 */
+-		out_8(base+0x555, 0xaa);
+-		udelay(1);
+-		/* Unlock 2 */
+-		out_8(base+0x2aa, 0x55);
+-		udelay(1);
+-
+-		/* Write single word */
+-		out_8(base+0x555, 0xa0);
+-		udelay(1);
+-		out_8(base+i, datas[i]);
+-		
+-		timeout = 0;
+-		do {
+-			if (++timeout > 1000000) {
+-				printk(KERN_ERR "nvram: AMD flash write timeout !\n");
+-				break;
+-			}
+-			stat = in_8(base) ^ in_8(base);
+-		} while (stat != 0);
+-		if (stat != 0)
+-			break;
+-	}
+-
+-	/* Reset */
+-	out_8(base, 0xf0);
+-	udelay(1);
+-
+-	for (i=0; i<NVRAM_SIZE; i++)
+-		if (base[i] != datas[i]) {
+-			printk(KERN_ERR "nvram: AMD flash write failed !\n");
+-			return -ENXIO;
+-		}
+-	return 0;
+-}
+-
+-
+-static int __pmac core99_nvram_sync(void)
+-{
+-	struct core99_header* hdr99;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&nv_lock, flags);
+-	if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
+-		NVRAM_SIZE))
+-		goto bail;
+-
+-	DBG("Updating nvram...\n");
+-
+-	hdr99 = (struct core99_header*)nvram_image;
+-	hdr99->generation++;
+-	hdr99->hdr.signature = CORE99_SIGNATURE;
+-	hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
+-	hdr99->adler = core99_calc_adler(nvram_image);
+-	core99_bank = core99_bank ? 0 : 1;
+-	if (core99_erase_bank)
+-		if (core99_erase_bank(core99_bank)) {
+-			printk("nvram: Error erasing bank %d\n", core99_bank);
+-			goto bail;
+-		}
+-	if (core99_write_bank)
+-		if (core99_write_bank(core99_bank, nvram_image))
+-			printk("nvram: Error writing bank %d\n", core99_bank);
+- bail:
+-	spin_unlock_irqrestore(&nv_lock, flags);
+-
+-	return 0;
+-}
+-
+-int __init pmac_nvram_init(void)
+-{
+-	struct device_node *dp;
+-	u32 gen_bank0, gen_bank1;
+-	int i;
+-
+-	dp = find_devices("nvram");
+-	if (dp == NULL) {
+-		printk(KERN_ERR "Can't find NVRAM device\n");
+-		return -ENODEV;
+-	}
+-	if (!device_is_compatible(dp, "nvram,flash")) {
+-		printk(KERN_ERR "Incompatible type of NVRAM\n");
+-		return -ENXIO;
+-	}
+-
+-	nvram_image = alloc_bootmem(NVRAM_SIZE);
+-	if (nvram_image == NULL) {
+-		printk(KERN_ERR "nvram: can't allocate ram image\n");
+-		return -ENOMEM;
+-	}
+-	nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
+-	
+-	DBG("nvram: Checking bank 0...\n");
+-
+-	gen_bank0 = core99_check((u8 *)nvram_data);
+-	gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
+-	core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
+-
+-	DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
+-	DBG("nvram: Active bank is: %d\n", core99_bank);
+-
+-	for (i=0; i<NVRAM_SIZE; i++)
+-		nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
+-
+-	ppc_md.nvram_read	= core99_nvram_read;
+-	ppc_md.nvram_write	= core99_nvram_write;
+-	ppc_md.nvram_size	= core99_nvram_size;
+-	ppc_md.nvram_sync	= core99_nvram_sync;
+-	
+-	/* 
+-	 * Maybe we could be smarter here though making an exclusive list
+-	 * of known flash chips is a bit nasty as older OF didn't provide us
+-	 * with a useful "compatible" entry. A solution would be to really
+-	 * identify the chip using flash id commands and base ourselves on
+-	 * a list of known chips IDs
+-	 */
+-	if (device_is_compatible(dp, "amd-0137")) {
+-		core99_erase_bank = amd_erase_bank;
+-		core99_write_bank = amd_write_bank;
+-	} else {
+-		core99_erase_bank = sm_erase_bank;
+-		core99_write_bank = sm_write_bank;
+-	}
+-
+-	return 0;
+-}
+-
+-int __pmac pmac_get_partition(int partition)
+-{
+-	struct nvram_partition *part;
+-	const char *name;
+-	int sig;
+-
+-	switch(partition) {
+-	case pmac_nvram_OF:
+-		name = "common";
+-		sig = NVRAM_SIG_SYS;
+-		break;
+-	case pmac_nvram_XPRAM:
+-		name = "APL,MacOS75";
+-		sig = NVRAM_SIG_OS;
+-		break;
+-	case pmac_nvram_NR:
+-	default:
+-		/* Oldworld stuff */
+-		return -ENODEV;
+-	}
+-
+-	part = nvram_find_partition(sig, name);
+-	if (part == NULL)
+-		return 0;
+-
+-	return part->index;
+-}
+-
+-u8 __pmac pmac_xpram_read(int xpaddr)
+-{
+-	int offset = pmac_get_partition(pmac_nvram_XPRAM);
+-	loff_t index;
+-	u8 buf;
+-	ssize_t count;
+-
+-	if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
+-		return 0xff;
+-	index = offset + xpaddr;
+-
+-	count = ppc_md.nvram_read(&buf, 1, &index);
+-	if (count != 1)
+-		return 0xff;
+-	return buf;
+-}
+-
+-void __pmac pmac_xpram_write(int xpaddr, u8 data)
+-{
+-	int offset = pmac_get_partition(pmac_nvram_XPRAM);
+-	loff_t index;
+-	u8 buf;
+-
+-	if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
+-		return;
+-	index = offset + xpaddr;
+-	buf = data;
+-
+-	ppc_md.nvram_write(&buf, 1, &index);
+-}
+-
+-EXPORT_SYMBOL(pmac_get_partition);
+-EXPORT_SYMBOL(pmac_xpram_read);
+-EXPORT_SYMBOL(pmac_xpram_write);
+diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pmac_pci.c
++++ /dev/null
+@@ -1,793 +0,0 @@
+-/*
+- * Support for PCI bridges found on Power Macintoshes.
+- * At present the "bandit" and "chaos" bridges are supported.
+- * Fortunately you access configuration space in the same
+- * way with either bridge.
+- *
+- * Copyright (C) 2003 Benjamin Herrenschmuidt (benh at kernel.crashing.org)
+- * Copyright (C) 1997 Paul Mackerras (paulus at samba.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/pci.h>
+-#include <linux/delay.h>
+-#include <linux/string.h>
+-#include <linux/init.h>
+-#include <linux/bootmem.h>
+-
+-#include <asm/sections.h>
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/machdep.h>
+-#include <asm/pmac_feature.h>
+-#include <asm/iommu.h>
+-
+-#include "pci.h"
+-#include "pmac.h"
+-
+-#define DEBUG
+-
+-#ifdef DEBUG
+-#define DBG(x...) printk(x)
+-#else
+-#define DBG(x...)
+-#endif
+-
+-/* XXX Could be per-controller, but I don't think we risk anything by
+- * assuming we won't have both UniNorth and Bandit */
+-static int has_uninorth;
+-static struct pci_controller *u3_agp;
+-struct device_node *k2_skiplist[2];
+-
+-static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
+-{
+-	for (; node != 0;node = node->sibling) {
+-		int * bus_range;
+-		unsigned int *class_code;
+-		int len;
+-
+-		/* For PCI<->PCI bridges or CardBus bridges, we go down */
+-		class_code = (unsigned int *) get_property(node, "class-code", NULL);
+-		if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+-			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+-			continue;
+-		bus_range = (int *) get_property(node, "bus-range", &len);
+-		if (bus_range != NULL && len > 2 * sizeof(int)) {
+-			if (bus_range[1] > higher)
+-				higher = bus_range[1];
+-		}
+-		higher = fixup_one_level_bus_range(node->child, higher);
+-	}
+-	return higher;
+-}
+-
+-/* This routine fixes the "bus-range" property of all bridges in the
+- * system since they tend to have their "last" member wrong on macs
+- *
+- * Note that the bus numbers manipulated here are OF bus numbers, they
+- * are not Linux bus numbers.
+- */
+-static void __init fixup_bus_range(struct device_node *bridge)
+-{
+-	int * bus_range;
+-	int len;
+-
+-	/* Lookup the "bus-range" property for the hose */
+-	bus_range = (int *) get_property(bridge, "bus-range", &len);
+-	if (bus_range == NULL || len < 2 * sizeof(int)) {
+-		printk(KERN_WARNING "Can't get bus-range for %s\n",
+-			       bridge->full_name);
+-		return;
+-	}
+-	bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
+-}
+-
+-/*
+- * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
+- *
+- * The "Bandit" version is present in all early PCI PowerMacs,
+- * and up to the first ones using Grackle. Some machines may
+- * have 2 bandit controllers (2 PCI busses).
+- *
+- * "Chaos" is used in some "Bandit"-type machines as a bridge
+- * for the separate display bus. It is accessed the same
+- * way as bandit, but cannot be probed for devices. It therefore
+- * has its own config access functions.
+- *
+- * The "UniNorth" version is present in all Core99 machines
+- * (iBook, G4, new IMacs, and all the recent Apple machines).
+- * It contains 3 controllers in one ASIC.
+- *
+- * The U3 is the bridge used on G5 machines. It contains on
+- * AGP bus which is dealt with the old UniNorth access routines
+- * and an HyperTransport bus which uses its own set of access
+- * functions.
+- */
+-
+-#define MACRISC_CFA0(devfn, off)	\
+-	((1 << (unsigned long)PCI_SLOT(dev_fn)) \
+-	| (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
+-	| (((unsigned long)(off)) & 0xFCUL))
+-
+-#define MACRISC_CFA1(bus, devfn, off)	\
+-	((((unsigned long)(bus)) << 16) \
+-	|(((unsigned long)(devfn)) << 8) \
+-	|(((unsigned long)(off)) & 0xFCUL) \
+-	|1UL)
+-
+-static unsigned long __pmac macrisc_cfg_access(struct pci_controller* hose,
+-					       u8 bus, u8 dev_fn, u8 offset)
+-{
+-	unsigned int caddr;
+-
+-	if (bus == hose->first_busno) {
+-		if (dev_fn < (11 << 3))
+-			return 0;
+-		caddr = MACRISC_CFA0(dev_fn, offset);
+-	} else
+-		caddr = MACRISC_CFA1(bus, dev_fn, offset);
+-
+-	/* Uninorth will return garbage if we don't read back the value ! */
+-	do {
+-		out_le32(hose->cfg_addr, caddr);
+-	} while (in_le32(hose->cfg_addr) != caddr);
+-
+-	offset &= has_uninorth ? 0x07 : 0x03;
+-	return ((unsigned long)hose->cfg_data) + offset;
+-}
+-
+-static int __pmac macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
+-				      int offset, int len, u32 *val)
+-{
+-	struct pci_controller *hose;
+-	unsigned long addr;
+-
+-	hose = pci_bus_to_host(bus);
+-	if (hose == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
+-	if (!addr)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	switch (len) {
+-	case 1:
+-		*val = in_8((u8 *)addr);
+-		break;
+-	case 2:
+-		*val = in_le16((u16 *)addr);
+-		break;
+-	default:
+-		*val = in_le32((u32 *)addr);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static int __pmac macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
+-				       int offset, int len, u32 val)
+-{
+-	struct pci_controller *hose;
+-	unsigned long addr;
+-
+-	hose = pci_bus_to_host(bus);
+-	if (hose == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
+-	if (!addr)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	switch (len) {
+-	case 1:
+-		out_8((u8 *)addr, val);
+-		(void) in_8((u8 *)addr);
+-		break;
+-	case 2:
+-		out_le16((u16 *)addr, val);
+-		(void) in_le16((u16 *)addr);
+-		break;
+-	default:
+-		out_le32((u32 *)addr, val);
+-		(void) in_le32((u32 *)addr);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static struct pci_ops macrisc_pci_ops =
+-{
+-	macrisc_read_config,
+-	macrisc_write_config
+-};
+-
+-/*
+- * These versions of U3 HyperTransport config space access ops do not
+- * implement self-view of the HT host yet
+- */
+-
+-/*
+- * This function deals with some "special cases" devices.
+- *
+- *  0 -> No special case
+- *  1 -> Skip the device but act as if the access was successfull
+- *       (return 0xff's on reads, eventually, cache config space
+- *       accesses in a later version)
+- * -1 -> Hide the device (unsuccessful acess)
+- */
+-static int u3_ht_skip_device(struct pci_controller *hose,
+-			     struct pci_bus *bus, unsigned int devfn)
+-{
+-	struct device_node *busdn, *dn;
+-	int i;
+-
+-	/* We only allow config cycles to devices that are in OF device-tree
+-	 * as we are apparently having some weird things going on with some
+-	 * revs of K2 on recent G5s
+-	 */
+-	if (bus->self)
+-		busdn = pci_device_to_OF_node(bus->self);
+-	else
+-		busdn = hose->arch_data;
+-	for (dn = busdn->child; dn; dn = dn->sibling)
+-		if (dn->data && PCI_DN(dn)->devfn == devfn)
+-			break;
+-	if (dn == NULL)
+-		return -1;
+-
+-	/*
+-	 * When a device in K2 is powered down, we die on config
+-	 * cycle accesses. Fix that here.
+-	 */
+-	for (i=0; i<2; i++)
+-		if (k2_skiplist[i] == dn)
+-			return 1;
+-
+-	return 0;
+-}
+-
+-#define U3_HT_CFA0(devfn, off)		\
+-		((((unsigned long)devfn) << 8) | offset)
+-#define U3_HT_CFA1(bus, devfn, off)	\
+-		(U3_HT_CFA0(devfn, off) \
+-		+ (((unsigned long)bus) << 16) \
+-		+ 0x01000000UL)
+-
+-static unsigned long __pmac u3_ht_cfg_access(struct pci_controller* hose,
+-					     u8 bus, u8 devfn, u8 offset)
+-{
+-	if (bus == hose->first_busno) {
+-		/* For now, we don't self probe U3 HT bridge */
+-		if (PCI_SLOT(devfn) == 0)
+-			return 0;
+-		return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
+-	} else
+-		return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
+-}
+-
+-static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
+-				    int offset, int len, u32 *val)
+-{
+-	struct pci_controller *hose;
+-	unsigned long addr;
+-
+-
+-	hose = pci_bus_to_host(bus);      
+-	if (hose == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+-	if (!addr)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	switch (u3_ht_skip_device(hose, bus, devfn)) {
+-	case 0:
+-		break;
+-	case 1:
+-		switch (len) {
+-		case 1:
+-			*val = 0xff; break;
+-		case 2:
+-			*val = 0xffff; break;
+-		default:
+-			*val = 0xfffffffful; break;
+-		}
+-		return PCIBIOS_SUCCESSFUL;
+-	default:
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-	}
+-
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	switch (len) {
+-	case 1:
+-		*val = in_8((u8 *)addr);
+-		break;
+-	case 2:
+-		*val = in_le16((u16 *)addr);
+-		break;
+-	default:
+-		*val = in_le32((u32 *)addr);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static int __pmac u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
+-				     int offset, int len, u32 val)
+-{
+-	struct pci_controller *hose;
+-	unsigned long addr;
+-
+-	hose = pci_bus_to_host(bus);
+-	if (hose == NULL)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+-	if (!addr)
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-
+-	switch (u3_ht_skip_device(hose, bus, devfn)) {
+-	case 0:
+-		break;
+-	case 1:
+-		return PCIBIOS_SUCCESSFUL;
+-	default:
+-		return PCIBIOS_DEVICE_NOT_FOUND;
+-	}
+-
+-	/*
+-	 * Note: the caller has already checked that offset is
+-	 * suitably aligned and that len is 1, 2 or 4.
+-	 */
+-	switch (len) {
+-	case 1:
+-		out_8((u8 *)addr, val);
+-		(void) in_8((u8 *)addr);
+-		break;
+-	case 2:
+-		out_le16((u16 *)addr, val);
+-		(void) in_le16((u16 *)addr);
+-		break;
+-	default:
+-		out_le32((u32 *)addr, val);
+-		(void) in_le32((u32 *)addr);
+-		break;
+-	}
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-static struct pci_ops u3_ht_pci_ops =
+-{
+-	u3_ht_read_config,
+-	u3_ht_write_config
+-};
+-
+-static void __init setup_u3_agp(struct pci_controller* hose)
+-{
+-	/* On G5, we move AGP up to high bus number so we don't need
+-	 * to reassign bus numbers for HT. If we ever have P2P bridges
+-	 * on AGP, we'll have to move pci_assign_all_busses to the
+-	 * pci_controller structure so we enable it for AGP and not for
+-	 * HT childs.
+-	 * We hard code the address because of the different size of
+-	 * the reg address cell, we shall fix that by killing struct
+-	 * reg_property and using some accessor functions instead
+-	 */
+-	hose->first_busno = 0xf0;
+-	hose->last_busno = 0xff;
+-	has_uninorth = 1;
+-	hose->ops = &macrisc_pci_ops;
+-	hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
+-	hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
+-
+-	u3_agp = hose;
+-}
+-
+-static void __init setup_u3_ht(struct pci_controller* hose)
+-{
+-	struct device_node *np = (struct device_node *)hose->arch_data;
+-	int i, cur;
+-
+-	hose->ops = &u3_ht_pci_ops;
+-
+-	/* We hard code the address because of the different size of
+-	 * the reg address cell, we shall fix that by killing struct
+-	 * reg_property and using some accessor functions instead
+-	 */
+-	hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+-
+-	/*
+-	 * /ht node doesn't expose a "ranges" property, so we "remove" regions that
+-	 * have been allocated to AGP. So far, this version of the code doesn't assign
+-	 * any of the 0xfxxxxxxx "fine" memory regions to /ht.
+-	 * We need to fix that sooner or later by either parsing all child "ranges"
+-	 * properties or figuring out the U3 address space decoding logic and
+-	 * then read it's configuration register (if any).
+-	 */
+-	hose->io_base_phys = 0xf4000000;
+-	hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);
+-	isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt;
+-	hose->io_resource.name = np->full_name;
+-	hose->io_resource.start = 0;
+-	hose->io_resource.end = 0x003fffff;
+-	hose->io_resource.flags = IORESOURCE_IO;
+-	hose->pci_mem_offset = 0;
+-	hose->first_busno = 0;
+-	hose->last_busno = 0xef;
+-	hose->mem_resources[0].name = np->full_name;
+-	hose->mem_resources[0].start = 0x80000000;
+-	hose->mem_resources[0].end = 0xefffffff;
+-	hose->mem_resources[0].flags = IORESOURCE_MEM;
+-
+-	if (u3_agp == NULL) {
+-		DBG("U3 has no AGP, using full resource range\n");
+-		return;
+-	}
+-
+-	/* We "remove" the AGP resources from the resources allocated to HT, that
+-	 * is we create "holes". However, that code does assumptions that so far
+-	 * happen to be true (cross fingers...), typically that resources in the
+-	 * AGP node are properly ordered
+-	 */
+-	cur = 0;
+-	for (i=0; i<3; i++) {
+-		struct resource *res = &u3_agp->mem_resources[i];
+-		if (res->flags != IORESOURCE_MEM)
+-			continue;
+-		/* We don't care about "fine" resources */
+-		if (res->start >= 0xf0000000)
+-			continue;
+-		/* Check if it's just a matter of "shrinking" us in one direction */
+-		if (hose->mem_resources[cur].start == res->start) {
+-			DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
+-			    cur, hose->mem_resources[cur].start, res->end + 1);
+-			hose->mem_resources[cur].start = res->end + 1;
+-			continue;
+-		}
+-		if (hose->mem_resources[cur].end == res->end) {
+-			DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
+-			    cur, hose->mem_resources[cur].end, res->start - 1);
+-			hose->mem_resources[cur].end = res->start - 1;
+-			continue;
+-		}
+-		/* No, it's not the case, we need a hole */
+-		if (cur == 2) {
+-			/* not enough resources for a hole, we drop part of the range */
+-			printk(KERN_WARNING "Running out of resources for /ht host !\n");
+-			hose->mem_resources[cur].end = res->start - 1;
+-			continue;
+-		}		
+-		cur++;
+-		DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
+-		    cur-1, res->start - 1, cur, res->end + 1);
+-		hose->mem_resources[cur].name = np->full_name;
+-		hose->mem_resources[cur].flags = IORESOURCE_MEM;
+-		hose->mem_resources[cur].start = res->end + 1;
+-		hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
+-		hose->mem_resources[cur-1].end = res->start - 1;
+-	}
+-}
+-
+-static void __init pmac_process_bridge_OF_ranges(struct pci_controller *hose,
+-			   struct device_node *dev, int primary)
+-{
+-	static unsigned int static_lc_ranges[2024];
+-	unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;
+-	unsigned int size;
+-	int rlen = 0, orig_rlen;
+-	int memno = 0;
+-	struct resource *res;
+-	int np, na = prom_n_addr_cells(dev);
+-
+-	np = na + 5;
+-
+-	/* First we try to merge ranges to fix a problem with some pmacs
+-	 * that can have more than 3 ranges, fortunately using contiguous
+-	 * addresses -- BenH
+-	 */
+-	dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+-	if (!dt_ranges)
+-		return;
+-	/*	lc_ranges = alloc_bootmem(rlen);*/
+-	lc_ranges = static_lc_ranges;
+-	if (!lc_ranges)
+-		return; /* what can we do here ? */
+-	memcpy(lc_ranges, dt_ranges, rlen);
+-	orig_rlen = rlen;
+-
+-	/* Let's work on a copy of the "ranges" property instead of damaging
+-	 * the device-tree image in memory
+-	 */
+-	ranges = lc_ranges;
+-	prev = NULL;
+-	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+-		if (prev) {
+-			if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
+-				(prev[2] + prev[na+4]) == ranges[2] &&
+-				(prev[na+2] + prev[na+4]) == ranges[na+2]) {
+-				prev[na+4] += ranges[na+4];
+-				ranges[0] = 0;
+-				ranges += np;
+-				continue;
+-			}
+-		}
+-		prev = ranges;
+-		ranges += np;
+-	}
+-
+-	/*
+-	 * The ranges property is laid out as an array of elements,
+-	 * each of which comprises:
+-	 *   cells 0 - 2:	a PCI address
+-	 *   cells 3 or 3+4:	a CPU physical address
+-	 *			(size depending on dev->n_addr_cells)
+-	 *   cells 4+5 or 5+6:	the size of the range
+-	 */
+-	ranges = lc_ranges;
+-	rlen = orig_rlen;
+-	while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
+-		res = NULL;
+-		size = ranges[na+4];
+-		switch (ranges[0] >> 24) {
+-		case 1:		/* I/O space */
+-			if (ranges[2] != 0)
+-				break;
+-			hose->io_base_phys = ranges[na+2];
+-			/* limit I/O space to 16MB */
+-			if (size > 0x01000000)
+-				size = 0x01000000;
+-			hose->io_base_virt = ioremap(ranges[na+2], size);
+-			if (primary)
+-				isa_io_base = (unsigned long) hose->io_base_virt;
+-			res = &hose->io_resource;
+-			res->flags = IORESOURCE_IO;
+-			res->start = ranges[2];
+-			break;
+-		case 2:		/* memory space */
+-			memno = 0;
+-			if (ranges[1] == 0 && ranges[2] == 0
+-			    && ranges[na+4] <= (16 << 20)) {
+-				/* 1st 16MB, i.e. ISA memory area */
+-#if 0
+-				if (primary)
+-					isa_mem_base = ranges[na+2];
+-#endif
+-				memno = 1;
+-			}
+-			while (memno < 3 && hose->mem_resources[memno].flags)
+-				++memno;
+-			if (memno == 0)
+-				hose->pci_mem_offset = ranges[na+2] - ranges[2];
+-			if (memno < 3) {
+-				res = &hose->mem_resources[memno];
+-				res->flags = IORESOURCE_MEM;
+-				res->start = ranges[na+2];
+-			}
+-			break;
+-		}
+-		if (res != NULL) {
+-			res->name = dev->full_name;
+-			res->end = res->start + size - 1;
+-			res->parent = NULL;
+-			res->sibling = NULL;
+-			res->child = NULL;
+-		}
+-		ranges += np;
+-	}
+-}
+-
+-/*
+- * We assume that if we have a G3 powermac, we have one bridge called
+- * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
+- * if we have one or more bandit or chaos bridges, we don't have a MPC106.
+- */
+-static int __init add_bridge(struct device_node *dev)
+-{
+-	int len;
+-	struct pci_controller *hose;
+-	char* disp_name;
+-	int *bus_range;
+-	int primary = 1;
+-	struct property *of_prop;
+-
+-	DBG("Adding PCI host bridge %s\n", dev->full_name);
+-
+-	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 = alloc_bootmem(sizeof(struct pci_controller));
+-	if (hose == NULL)
+-		return -ENOMEM;
+-	pci_setup_pci_controller(hose);
+-
+-	hose->arch_data = dev;
+-	hose->first_busno = bus_range ? bus_range[0] : 0;
+-	hose->last_busno = bus_range ? bus_range[1] : 0xff;
+-
+-	of_prop = alloc_bootmem(sizeof(struct property) +
+-				sizeof(hose->global_number));
+-	if (of_prop) {
+-		memset(of_prop, 0, sizeof(struct property));
+-		of_prop->name = "linux,pci-domain";
+-		of_prop->length = sizeof(hose->global_number);
+-		of_prop->value = (unsigned char *)&of_prop[1];
+-		memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
+-		prom_add_property(dev, of_prop);
+-	}
+-
+-	disp_name = NULL;
+-	if (device_is_compatible(dev, "u3-agp")) {
+-		setup_u3_agp(hose);
+-		disp_name = "U3-AGP";
+-		primary = 0;
+-	} else if (device_is_compatible(dev, "u3-ht")) {
+-		setup_u3_ht(hose);
+-		disp_name = "U3-HT";
+-		primary = 1;
+-	}
+-	printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
+-		disp_name, hose->first_busno, hose->last_busno);
+-
+-	/* Interpret the "ranges" property */
+-	/* This also maps the I/O region and sets isa_io/mem_base */
+-	pmac_process_bridge_OF_ranges(hose, dev, primary);
+-
+-	/* Fixup "bus-range" OF property */
+-	fixup_bus_range(dev);
+-
+-	return 0;
+-}
+-
+-/*
+- * We use our own read_irq_line here because PCI_INTERRUPT_PIN is
+- * crap on some of Apple ASICs. We unconditionally use the Open Firmware
+- * interrupt number as this is always right.
+- */
+-static int pmac_pci_read_irq_line(struct pci_dev *pci_dev)
+-{
+-	struct device_node *node;
+-
+-	node = pci_device_to_OF_node(pci_dev);
+-	if (node == NULL)
+-		return -1;
+-	if (node->n_intrs == 0)
+-		return -1;
+-	pci_dev->irq = node->intrs[0].line;
+-	pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq);
+-
+-	return 0;
+-}
+-
+-void __init pmac_pcibios_fixup(void)
+-{
+-	struct pci_dev *dev = NULL;
+-
+-	for_each_pci_dev(dev)
+-		pmac_pci_read_irq_line(dev);
+-}
+-
+-static void __init pmac_fixup_phb_resources(void)
+-{
+-	struct pci_controller *hose, *tmp;
+-	
+-	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+-		unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
+-		hose->io_resource.start += offset;
+-		hose->io_resource.end += offset;
+-		printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
+-		       hose->global_number,
+-		       hose->io_resource.start, hose->io_resource.end);
+-	}
+-}
+-
+-void __init pmac_pci_init(void)
+-{
+-	struct device_node *np, *root;
+-	struct device_node *ht = NULL;
+-
+-	/* Probe root PCI hosts, that is on U3 the AGP host and the
+-	 * HyperTransport host. That one is actually "kept" around
+-	 * and actually added last as it's resource management relies
+-	 * on the AGP resources to have been setup first
+-	 */
+-	root = of_find_node_by_path("/");
+-	if (root == NULL) {
+-		printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n");
+-		return;
+-	}
+-	for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
+-		if (np->name == NULL)
+-			continue;
+-		if (strcmp(np->name, "pci") == 0) {
+-			if (add_bridge(np) == 0)
+-				of_node_get(np);
+-		}
+-		if (strcmp(np->name, "ht") == 0) {
+-			of_node_get(np);
+-			ht = np;
+-		}
+-	}
+-	of_node_put(root);
+-
+-	/* Now setup the HyperTransport host if we found any
+-	 */
+-	if (ht && add_bridge(ht) != 0)
+-		of_node_put(ht);
+-
+-	/* Fixup the IO resources on our host bridges as the common code
+-	 * does it only for childs of the host bridges
+-	 */
+-	pmac_fixup_phb_resources();
+-
+-	/* Setup the linkage between OF nodes and PHBs */ 
+-	pci_devs_phb_init();
+-
+-	/* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
+-	 * assume there is no P2P bridge on the AGP bus, which should be a
+-	 * safe assumptions hopefully.
+-	 */
+-	if (u3_agp) {
+-		struct device_node *np = u3_agp->arch_data;
+-		PCI_DN(np)->busno = 0xf0;
+-		for (np = np->child; np; np = np->sibling)
+-			PCI_DN(np)->busno = 0xf0;
+-	}
+-
+-	pmac_check_ht_link();
+-
+-	/* Tell pci.c to not use the common resource allocation mecanism */
+-	pci_probe_only = 1;
+-	
+-	/* Allow all IO */
+-	io_page_mask = -1;
+-}
+-
+-/*
+- * Disable second function on K2-SATA, it's broken
+- * and disable IO BARs on first one
+- */
+-static void fixup_k2_sata(struct pci_dev* dev)
+-{
+-	int i;
+-	u16 cmd;
+-
+-	if (PCI_FUNC(dev->devfn) > 0) {
+-		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+-		cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+-		pci_write_config_word(dev, PCI_COMMAND, cmd);
+-		for (i = 0; i < 6; i++) {
+-			dev->resource[i].start = dev->resource[i].end = 0;
+-			dev->resource[i].flags = 0;
+-			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
+-		}
+-	} else {
+-		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+-		cmd &= ~PCI_COMMAND_IO;
+-		pci_write_config_word(dev, PCI_COMMAND, cmd);
+-		for (i = 0; i < 5; i++) {
+-			dev->resource[i].start = dev->resource[i].end = 0;
+-			dev->resource[i].flags = 0;
+-			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
+-		}
+-	}
+-}
+-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);
+-
+diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pmac_setup.c
++++ /dev/null
+@@ -1,525 +0,0 @@
+-/*
+- *  arch/ppc/platforms/setup.c
+- *
+- *  PowerPC version
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- *  Adapted for Power Macintosh by Paul Mackerras
+- *    Copyright (C) 1996 Paul Mackerras (paulus at cs.anu.edu.au)
+- *
+- *  Derived from "arch/alpha/kernel/setup.c"
+- *    Copyright (C) 1995 Linus Torvalds
+- *
+- *  Maintained by Benjamin Herrenschmidt (benh at 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.
+- *
+- */
+-
+-/*
+- * bootup setup stuff..
+- */
+-
+-#undef DEBUG
+-
+-#include <linux/config.h>
+-#include <linux/init.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/mm.h>
+-#include <linux/stddef.h>
+-#include <linux/unistd.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/user.h>
+-#include <linux/a.out.h>
+-#include <linux/tty.h>
+-#include <linux/string.h>
+-#include <linux/delay.h>
+-#include <linux/ioport.h>
+-#include <linux/major.h>
+-#include <linux/initrd.h>
+-#include <linux/vt_kern.h>
+-#include <linux/console.h>
+-#include <linux/ide.h>
+-#include <linux/pci.h>
+-#include <linux/adb.h>
+-#include <linux/cuda.h>
+-#include <linux/pmu.h>
+-#include <linux/irq.h>
+-#include <linux/seq_file.h>
+-#include <linux/root_dev.h>
+-#include <linux/bitops.h>
+-
+-#include <asm/processor.h>
+-#include <asm/sections.h>
+-#include <asm/prom.h>
+-#include <asm/system.h>
+-#include <asm/io.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/iommu.h>
+-#include <asm/machdep.h>
+-#include <asm/dma.h>
+-#include <asm/btext.h>
+-#include <asm/cputable.h>
+-#include <asm/pmac_feature.h>
+-#include <asm/time.h>
+-#include <asm/of_device.h>
+-#include <asm/lmb.h>
+-#include <asm/smu.h>
+-#include <asm/pmc.h>
+-
+-#include "pmac.h"
+-#include "mpic.h"
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) udbg_printf(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-static int current_root_goodness = -1;
+-#define DEFAULT_ROOT_DEVICE Root_SDA1	/* sda1 - slightly silly choice */
+-
+-extern  int powersave_nap;
+-int sccdbg;
+-
+-sys_ctrler_t sys_ctrler;
+-EXPORT_SYMBOL(sys_ctrler);
+-
+-#ifdef CONFIG_PMAC_SMU
+-unsigned long smu_cmdbuf_abs;
+-EXPORT_SYMBOL(smu_cmdbuf_abs);
+-#endif
+-
+-extern void udbg_init_scc(struct device_node *np);
+-
+-static void __pmac pmac_show_cpuinfo(struct seq_file *m)
+-{
+-	struct device_node *np;
+-	char *pp;
+-	int plen;
+-	char* mbname;
+-	int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
+-					PMAC_MB_INFO_MODEL, 0);
+-	unsigned int mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
+-						 PMAC_MB_INFO_FLAGS, 0);
+-
+-	if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME,
+-			      (long)&mbname) != 0)
+-		mbname = "Unknown";
+-	
+-	/* find motherboard type */
+-	seq_printf(m, "machine\t\t: ");
+-	np = of_find_node_by_path("/");
+-	if (np != NULL) {
+-		pp = (char *) get_property(np, "model", NULL);
+-		if (pp != NULL)
+-			seq_printf(m, "%s\n", pp);
+-		else
+-			seq_printf(m, "PowerMac\n");
+-		pp = (char *) get_property(np, "compatible", &plen);
+-		if (pp != NULL) {
+-			seq_printf(m, "motherboard\t:");
+-			while (plen > 0) {
+-				int l = strlen(pp) + 1;
+-				seq_printf(m, " %s", pp);
+-				plen -= l;
+-				pp += l;
+-			}
+-			seq_printf(m, "\n");
+-		}
+-		of_node_put(np);
+-	} else
+-		seq_printf(m, "PowerMac\n");
+-
+-	/* print parsed model */
+-	seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
+-	seq_printf(m, "pmac flags\t: %08x\n", mbflags);
+-
+-	/* Indicate newworld */
+-	seq_printf(m, "pmac-generation\t: NewWorld\n");
+-}
+-
+-
+-static void __init pmac_setup_arch(void)
+-{
+-	/* init to some ~sane value until calibrate_delay() runs */
+-	loops_per_jiffy = 50000000;
+-
+-	/* Probe motherboard chipset */
+-	pmac_feature_init();
+-#if 0
+-	/* Lock-enable the SCC channel used for debug */
+-	if (sccdbg) {
+-		np = of_find_node_by_name(NULL, "escc");
+-		if (np)
+-			pmac_call_feature(PMAC_FTR_SCC_ENABLE, np,
+-					  PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
+-	}
+-#endif
+-	/* We can NAP */
+-	powersave_nap = 1;
+-
+-#ifdef CONFIG_ADB_PMU
+-	/* Initialize the PMU if any */
+-	find_via_pmu();
+-#endif
+-#ifdef CONFIG_PMAC_SMU
+-	/* Initialize the SMU if any */
+-	smu_init();
+-#endif
+-
+-	/* Init NVRAM access */
+-	pmac_nvram_init();
+-
+-	/* Setup SMP callback */
+-#ifdef CONFIG_SMP
+-	pmac_setup_smp();
+-#endif
+-
+-	/* Lookup PCI hosts */
+-       	pmac_pci_init();
+-
+-#ifdef CONFIG_DUMMY_CONSOLE
+-	conswitchp = &dummy_con;
+-#endif
+-
+-	printk(KERN_INFO "Using native/NAP idle loop\n");
+-}
+-
+-#ifdef CONFIG_SCSI
+-void note_scsi_host(struct device_node *node, void *host)
+-{
+-	/* Obsolete */
+-}
+-#endif
+-
+-
+-static int initializing = 1;
+-
+-static int pmac_late_init(void)
+-{
+-	initializing = 0;
+-	return 0;
+-}
+-
+-late_initcall(pmac_late_init);
+-
+-/* can't be __init - can be called whenever a disk is first accessed */
+-void __pmac note_bootable_part(dev_t dev, int part, int goodness)
+-{
+-	extern dev_t boot_dev;
+-	char *p;
+-
+-	if (!initializing)
+-		return;
+-	if ((goodness <= current_root_goodness) &&
+-	    ROOT_DEV != DEFAULT_ROOT_DEVICE)
+-		return;
+-	p = strstr(saved_command_line, "root=");
+-	if (p != NULL && (p == saved_command_line || p[-1] == ' '))
+-		return;
+-
+-	if (!boot_dev || dev == boot_dev) {
+-		ROOT_DEV = dev + part;
+-		boot_dev = 0;
+-		current_root_goodness = goodness;
+-	}
+-}
+-
+-static void __pmac pmac_restart(char *cmd)
+-{
+-	switch(sys_ctrler) {
+-#ifdef CONFIG_ADB_PMU
+-	case SYS_CTRLER_PMU:
+-		pmu_restart();
+-		break;
+-#endif
+-
+-#ifdef CONFIG_PMAC_SMU
+-	case SYS_CTRLER_SMU:
+-		smu_restart();
+-		break;
+-#endif
+-	default:
+-		;
+-	}
+-}
+-
+-static void __pmac pmac_power_off(void)
+-{
+-	switch(sys_ctrler) {
+-#ifdef CONFIG_ADB_PMU
+-	case SYS_CTRLER_PMU:
+-		pmu_shutdown();
+-		break;
+-#endif
+-#ifdef CONFIG_PMAC_SMU
+-	case SYS_CTRLER_SMU:
+-		smu_shutdown();
+-		break;
+-#endif
+-	default:
+-		;
+-	}
+-}
+-
+-static void __pmac pmac_halt(void)
+-{
+-	pmac_power_off();
+-}
+-
+-#ifdef CONFIG_BOOTX_TEXT
+-static void btext_putc(unsigned char c)
+-{
+-	btext_drawchar(c);
+-}
+-
+-static void __init init_boot_display(void)
+-{
+-	char *name;
+-	struct device_node *np = NULL; 
+-	int rc = -ENODEV;
+-
+-	printk("trying to initialize btext ...\n");
+-
+-	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+-	if (name != NULL) {
+-		np = of_find_node_by_path(name);
+-		if (np != NULL) {
+-			if (strcmp(np->type, "display") != 0) {
+-				printk("boot stdout isn't a display !\n");
+-				of_node_put(np);
+-				np = NULL;
+-			}
+-		}
+-	}
+-	if (np)
+-		rc = btext_initialize(np);
+-	if (rc == 0)
+-		return;
+-
+-	for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
+-		if (get_property(np, "linux,opened", NULL)) {
+-			printk("trying %s ...\n", np->full_name);
+-			rc = btext_initialize(np);
+-			printk("result: %d\n", rc);
+-		}
+-		if (rc == 0)
+-			return;
+-	}
+-}
+-#endif /* CONFIG_BOOTX_TEXT */
+-
+-/* 
+- * Early initialization.
+- */
+-static void __init pmac_init_early(void)
+-{
+-	DBG(" -> pmac_init_early\n");
+-
+-	/* Initialize hash table, from now on, we can take hash faults
+-	 * and call ioremap
+-	 */
+-	hpte_init_native();
+-
+-	/* Init SCC */
+-       	if (strstr(cmd_line, "sccdbg")) {
+-		sccdbg = 1;
+-       		udbg_init_scc(NULL);
+-       	}
+-#ifdef CONFIG_BOOTX_TEXT
+-	else {
+-		init_boot_display();
+-
+-		udbg_putc = btext_putc;
+-	}
+-#endif /* CONFIG_BOOTX_TEXT */
+-
+-	/* Setup interrupt mapping options */
+-	ppc64_interrupt_controller = IC_OPEN_PIC;
+-
+-	iommu_init_early_u3();
+-
+-	DBG(" <- pmac_init_early\n");
+-}
+-
+-static int pmac_u3_cascade(struct pt_regs *regs, void *data)
+-{
+-	return mpic_get_one_irq((struct mpic *)data, regs);
+-}
+-
+-static __init void pmac_init_IRQ(void)
+-{
+-        struct device_node *irqctrler  = NULL;
+-        struct device_node *irqctrler2 = NULL;
+-	struct device_node *np = NULL;
+-	struct mpic *mpic1, *mpic2;
+-
+-	/* We first try to detect Apple's new Core99 chipset, since mac-io
+-	 * is quite different on those machines and contains an IBM MPIC2.
+-	 */
+-	while ((np = of_find_node_by_type(np, "open-pic")) != NULL) {
+-		struct device_node *parent = of_get_parent(np);
+-		if (parent && !strcmp(parent->name, "u3"))
+-			irqctrler2 = of_node_get(np);
+-		else
+-			irqctrler = of_node_get(np);
+-		of_node_put(parent);
+-	}
+-	if (irqctrler != NULL && irqctrler->n_addrs > 0) {
+-		unsigned char senses[128];
+-
+-		printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
+-		       (unsigned int)irqctrler->addrs[0].address);
+-
+-		prom_get_irq_senses(senses, 0, 128);
+-		mpic1 = mpic_alloc(irqctrler->addrs[0].address,
+-				   MPIC_PRIMARY | MPIC_WANTS_RESET,
+-				   0, 0, 128, 256, senses, 128, " K2-MPIC  ");
+-		BUG_ON(mpic1 == NULL);
+-		mpic_init(mpic1);		
+-
+-		if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
+-		    irqctrler2->n_addrs > 0) {
+-			printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
+-			       (u32)irqctrler2->addrs[0].address,
+-			       irqctrler2->intrs[0].line);
+-
+-			pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
+-			prom_get_irq_senses(senses, 128, 128 + 128);
+-
+-			/* We don't need to set MPIC_BROKEN_U3 here since we don't have
+-			 * hypertransport interrupts routed to it
+-			 */
+-			mpic2 = mpic_alloc(irqctrler2->addrs[0].address,
+-					   MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
+-					   0, 128, 128, 0, senses, 128, " U3-MPIC  ");
+-			BUG_ON(mpic2 == NULL);
+-			mpic_init(mpic2);
+-			mpic_setup_cascade(irqctrler2->intrs[0].line,
+-					   pmac_u3_cascade, mpic2);
+-		}
+-	}
+-	of_node_put(irqctrler);
+-	of_node_put(irqctrler2);
+-}
+-
+-static void __init pmac_progress(char *s, unsigned short hex)
+-{
+-	if (sccdbg) {
+-		udbg_puts(s);
+-		udbg_puts("\n");
+-	}
+-#ifdef CONFIG_BOOTX_TEXT
+-	else if (boot_text_mapped) {
+-		btext_drawstring(s);
+-		btext_drawstring("\n");
+-	}
+-#endif /* CONFIG_BOOTX_TEXT */
+-}
+-
+-/*
+- * pmac has no legacy IO, anything calling this function has to
+- * fail or bad things will happen
+- */
+-static int pmac_check_legacy_ioport(unsigned int baseport)
+-{
+-	return -ENODEV;
+-}
+-
+-static int __init pmac_declare_of_platform_devices(void)
+-{
+-	struct device_node *np, *npp;
+-
+-	npp = of_find_node_by_name(NULL, "u3");
+-	if (npp) {
+-		for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
+-			if (strncmp(np->name, "i2c", 3) == 0) {
+-				of_platform_device_create(np, "u3-i2c", NULL);
+-				of_node_put(np);
+-				break;
+-			}
+-		}
+-		of_node_put(npp);
+-	}
+-        npp = of_find_node_by_type(NULL, "smu");
+-        if (npp) {
+-		of_platform_device_create(npp, "smu", NULL);
+-		of_node_put(npp);
+-	}
+-
+-	return 0;
+-}
+-
+-device_initcall(pmac_declare_of_platform_devices);
+-
+-/*
+- * Called very early, MMU is off, device-tree isn't unflattened
+- */
+-static int __init pmac_probe(int platform)
+-{
+-	if (platform != PLATFORM_POWERMAC)
+-		return 0;
+-	/*
+-	 * On U3, the DART (iommu) must be allocated now since it
+-	 * has an impact on htab_initialize (due to the large page it
+-	 * occupies having to be broken up so the DART itself is not
+-	 * part of the cacheable linar mapping
+-	 */
+-	alloc_u3_dart_table();
+-
+-#ifdef CONFIG_PMAC_SMU
+-	/*
+-	 * SMU based G5s need some memory below 2Gb, at least the current
+-	 * driver needs that. We have to allocate it now. We allocate 4k
+-	 * (1 small page) for now.
+-	 */
+-	smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL);
+-#endif /* CONFIG_PMAC_SMU */
+-
+-	return 1;
+-}
+-
+-static int pmac_probe_mode(struct pci_bus *bus)
+-{
+-	struct device_node *node = bus->sysdata;
+-
+-	/* We need to use normal PCI probing for the AGP bus,
+-	   since the device for the AGP bridge isn't in the tree. */
+-	if (bus->self == NULL && device_is_compatible(node, "u3-agp"))
+-		return PCI_PROBE_NORMAL;
+-
+-	return PCI_PROBE_DEVTREE;
+-}
+-
+-struct machdep_calls __initdata pmac_md = {
+-#ifdef CONFIG_HOTPLUG_CPU
+-	.cpu_die		= generic_mach_cpu_die,
+-#endif
+-	.probe			= pmac_probe,
+-	.setup_arch		= pmac_setup_arch,
+-	.init_early		= pmac_init_early,
+-       	.get_cpuinfo		= pmac_show_cpuinfo,
+-	.init_IRQ		= pmac_init_IRQ,
+-	.get_irq		= mpic_get_irq,
+-	.pcibios_fixup		= pmac_pcibios_fixup,
+-	.pci_probe_mode		= pmac_probe_mode,
+-	.restart		= pmac_restart,
+-	.power_off		= pmac_power_off,
+-	.halt			= pmac_halt,
+-       	.get_boot_time		= pmac_get_boot_time,
+-       	.set_rtc_time		= pmac_set_rtc_time,
+-       	.get_rtc_time		= pmac_get_rtc_time,
+-      	.calibrate_decr		= pmac_calibrate_decr,
+-	.feature_call		= pmac_do_feature_call,
+-	.progress		= pmac_progress,
+-	.check_legacy_ioport	= pmac_check_legacy_ioport,
+-	.idle_loop		= native_idle,
+-	.enable_pmcs		= power4_enable_pmcs,
+-};
+diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pmac_smp.c
++++ /dev/null
+@@ -1,330 +0,0 @@
+-/*
+- * SMP support for power macintosh.
+- *
+- * We support both the old "powersurge" SMP architecture
+- * and the current Core99 (G4 PowerMac) machines.
+- *
+- * Note that we don't support the very first rev. of
+- * Apple/DayStar 2 CPUs board, the one with the funky
+- * watchdog. Hopefully, none of these should be there except
+- * maybe internally to Apple. I should probably still add some
+- * code to detect this card though and disable SMP. --BenH.
+- *
+- * Support Macintosh G4 SMP by Troy Benjegerdes (hozer at drgw.net)
+- * and Ben Herrenschmidt <benh at kernel.crashing.org>.
+- *
+- * Support for DayStar quad CPU cards
+- * Copyright (C) XLR8, Inc. 1994-2000
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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/config.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/interrupt.h>
+-#include <linux/kernel_stat.h>
+-#include <linux/init.h>
+-#include <linux/spinlock.h>
+-#include <linux/errno.h>
+-#include <linux/irq.h>
+-
+-#include <asm/ptrace.h>
+-#include <asm/atomic.h>
+-#include <asm/irq.h>
+-#include <asm/page.h>
+-#include <asm/pgtable.h>
+-#include <asm/sections.h>
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/smp.h>
+-#include <asm/machdep.h>
+-#include <asm/pmac_feature.h>
+-#include <asm/time.h>
+-#include <asm/cacheflush.h>
+-#include <asm/keylargo.h>
+-#include <asm/pmac_low_i2c.h>
+-
+-#include "mpic.h"
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) udbg_printf(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-extern void pmac_secondary_start_1(void);
+-extern void pmac_secondary_start_2(void);
+-extern void pmac_secondary_start_3(void);
+-
+-extern struct smp_ops_t *smp_ops;
+-
+-static void (*pmac_tb_freeze)(int freeze);
+-static struct device_node *pmac_tb_clock_chip_host;
+-static u8 pmac_tb_pulsar_addr;
+-static DEFINE_SPINLOCK(timebase_lock);
+-static unsigned long timebase;
+-
+-static void smp_core99_cypress_tb_freeze(int freeze)
+-{
+-	u8 data;
+-	int rc;
+-
+-	/* Strangely, the device-tree says address is 0xd2, but darwin
+-	 * accesses 0xd0 ...
+-	 */
+-	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
+-	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+-			       0xd0 | pmac_low_i2c_read,
+-			       0x81, &data, 1);
+-	if (rc != 0)
+-		goto bail;
+-
+-	data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
+-
+-       	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
+-	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+-			       0xd0 | pmac_low_i2c_write,
+-			       0x81, &data, 1);
+-
+- bail:
+-	if (rc != 0) {
+-		printk("Cypress Timebase %s rc: %d\n",
+-		       freeze ? "freeze" : "unfreeze", rc);
+-		panic("Timebase freeze failed !\n");
+-	}
+-}
+-
+-static void smp_core99_pulsar_tb_freeze(int freeze)
+-{
+-	u8 data;
+-	int rc;
+-
+-	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
+-	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+-			       pmac_tb_pulsar_addr | pmac_low_i2c_read,
+-			       0x2e, &data, 1);
+-	if (rc != 0)
+-		goto bail;
+-
+-	data = (data & 0x88) | (freeze ? 0x11 : 0x22);
+-
+-	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
+-	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+-			       pmac_tb_pulsar_addr | pmac_low_i2c_write,
+-			       0x2e, &data, 1);
+- bail:
+-	if (rc != 0) {
+-		printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
+-		       freeze ? "freeze" : "unfreeze", rc);
+-		panic("Timebase freeze failed !\n");
+-	}
+-}
+-
+-
+-static void smp_core99_give_timebase(void)
+-{
+-	/* Open i2c bus for synchronous access */
+-	if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0))
+-		panic("Can't open i2c for TB sync !\n");
+-
+-	spin_lock(&timebase_lock);
+-	(*pmac_tb_freeze)(1);
+-	mb();
+-	timebase = get_tb();
+-	spin_unlock(&timebase_lock);
+-
+-	while (timebase)
+-		barrier();
+-
+-	spin_lock(&timebase_lock);
+-	(*pmac_tb_freeze)(0);
+-	spin_unlock(&timebase_lock);
+-
+-	/* Close i2c bus */
+-	pmac_low_i2c_close(pmac_tb_clock_chip_host);
+-}
+-
+-
+-static void __devinit smp_core99_take_timebase(void)
+-{
+-	while (!timebase)
+-		barrier();
+-	spin_lock(&timebase_lock);
+-	set_tb(timebase >> 32, timebase & 0xffffffff);
+-	timebase = 0;
+-	spin_unlock(&timebase_lock);
+-}
+-
+-
+-static int __init smp_core99_probe(void)
+-{
+-	struct device_node *cpus;	
+-	struct device_node *cc;	
+-	int ncpus = 0;
+-
+-	/* Maybe use systemconfiguration here ? */
+-	if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
+-
+-	/* Count CPUs in the device-tree */
+-       	for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;)
+-	       	++ncpus;
+-
+-	printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
+-
+-	/* Nothing more to do if less than 2 of them */
+-	if (ncpus <= 1)
+-		return 1;
+-
+-	/* HW sync only on these platforms */
+-	if (!machine_is_compatible("PowerMac7,2") &&
+-	    !machine_is_compatible("PowerMac7,3") &&
+-	    !machine_is_compatible("RackMac3,1"))
+-		goto nohwsync;
+-
+-	/* Look for the clock chip */
+-	for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
+-		struct device_node *p = of_get_parent(cc);
+-		u32 *reg;
+-		int ok;
+-		ok = p && device_is_compatible(p, "uni-n-i2c");
+-		if (!ok)
+-			goto next;
+-		reg = (u32 *)get_property(cc, "reg", NULL);
+-		if (reg == NULL)
+-			goto next;
+-		switch (*reg) {
+-		case 0xd2:
+-			if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
+-				pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+-				pmac_tb_pulsar_addr = 0xd2;
+-				printk(KERN_INFO "Timebase clock is Pulsar chip\n");
+-			} else if (device_is_compatible(cc, "cy28508")) {
+-				pmac_tb_freeze = smp_core99_cypress_tb_freeze;
+-				printk(KERN_INFO "Timebase clock is Cypress chip\n");
+-			}
+-			break;
+-		case 0xd4:
+-			pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+-			pmac_tb_pulsar_addr = 0xd4;
+-			printk(KERN_INFO "Timebase clock is Pulsar chip\n");
+-			break;
+-		}
+-		if (pmac_tb_freeze != NULL) {
+-			pmac_tb_clock_chip_host = p;
+-			smp_ops->give_timebase = smp_core99_give_timebase;
+-			smp_ops->take_timebase = smp_core99_take_timebase;
+-			of_node_put(cc);
+-			of_node_put(p);
+-			break;
+-		}
+-	next:
+-		of_node_put(p);
+-	}
+-
+- nohwsync:
+-	mpic_request_ipis();
+-
+-	return ncpus;
+-}
+-
+-static void __init smp_core99_kick_cpu(int nr)
+-{
+-	int save_vector, j;
+-	unsigned long new_vector;
+-	unsigned long flags;
+-	volatile unsigned int *vector
+-		 = ((volatile unsigned int *)(KERNELBASE+0x100));
+-
+-	if (nr < 1 || nr > 3)
+-		return;
+-	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
+-
+-	local_irq_save(flags);
+-	local_irq_disable();
+-
+-	/* Save reset vector */
+-	save_vector = *vector;
+-
+-	/* Setup fake reset vector that does	
+-	 *   b .pmac_secondary_start - KERNELBASE
+-	 */
+-	switch(nr) {
+-	case 1:
+-		new_vector = (unsigned long)pmac_secondary_start_1;
+-		break;
+-	case 2:
+-		new_vector = (unsigned long)pmac_secondary_start_2;
+-		break;			
+-	case 3:
+-	default:
+-		new_vector = (unsigned long)pmac_secondary_start_3;
+-		break;
+-	}
+-	*vector = 0x48000002 + (new_vector - KERNELBASE);
+-
+-	/* flush data cache and inval instruction cache */
+-	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+-
+-	/* Put some life in our friend */
+-	pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
+-	paca[nr].cpu_start = 1;
+-
+-	/* FIXME: We wait a bit for the CPU to take the exception, I should
+-	 * instead wait for the entry code to set something for me. Well,
+-	 * ideally, all that crap will be done in prom.c and the CPU left
+-	 * in a RAM-based wait loop like CHRP.
+-	 */
+-	for (j = 1; j < 1000000; j++)
+-		mb();
+-
+-	/* Restore our exception vector */
+-	*vector = save_vector;
+-	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+-
+-	local_irq_restore(flags);
+-	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
+-}
+-
+-static void __init smp_core99_setup_cpu(int cpu_nr)
+-{
+-	/* Setup MPIC */
+-	mpic_setup_this_cpu();
+-
+-	if (cpu_nr == 0) {
+-		extern void g5_phy_disable_cpu1(void);
+-
+-		/* If we didn't start the second CPU, we must take
+-		 * it off the bus
+-		 */
+-		if (num_online_cpus() < 2)		
+-			g5_phy_disable_cpu1();
+-		if (ppc_md.progress) ppc_md.progress("smp_core99_setup_cpu 0 done", 0x349);
+-	}
+-}
+-
+-struct smp_ops_t core99_smp_ops __pmacdata = {
+-	.message_pass	= smp_mpic_message_pass,
+-	.probe		= smp_core99_probe,
+-	.kick_cpu	= smp_core99_kick_cpu,
+-	.setup_cpu	= smp_core99_setup_cpu,
+-	.give_timebase	= smp_generic_give_timebase,
+-	.take_timebase	= smp_generic_take_timebase,
+-};
+-
+-void __init pmac_setup_smp(void)
+-{
+-	smp_ops = &core99_smp_ops;
+-#ifdef CONFIG_HOTPLUG_CPU
+-	smp_ops->cpu_enable = generic_cpu_enable;
+-	smp_ops->cpu_disable = generic_cpu_disable;
+-	smp_ops->cpu_die = generic_cpu_die;
+-#endif
+-}
+diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pmac_time.c
++++ /dev/null
+@@ -1,195 +0,0 @@
+-/*
+- * Support for periodic interrupts (100 per second) and for getting
+- * the current time from the RTC on Power Macintoshes.
+- *
+- * We use the decrementer register for our periodic interrupts.
+- *
+- * Paul Mackerras	August 1996.
+- * Copyright (C) 1996 Paul Mackerras.
+- * Copyright (C) 2003-2005 Benjamin Herrenschmidt.
+- *
+- */
+-#include <linux/config.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/param.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
+-#include <linux/init.h>
+-#include <linux/time.h>
+-#include <linux/adb.h>
+-#include <linux/pmu.h>
+-#include <linux/interrupt.h>
+-
+-#include <asm/sections.h>
+-#include <asm/prom.h>
+-#include <asm/system.h>
+-#include <asm/io.h>
+-#include <asm/pgtable.h>
+-#include <asm/machdep.h>
+-#include <asm/time.h>
+-#include <asm/nvram.h>
+-#include <asm/smu.h>
+-
+-#undef DEBUG
+-
+-#ifdef DEBUG
+-#define DBG(x...) printk(x)
+-#else
+-#define DBG(x...)
+-#endif
+-
+-/* Apparently the RTC stores seconds since 1 Jan 1904 */
+-#define RTC_OFFSET	2082844800
+-
+-/*
+- * Calibrate the decrementer frequency with the VIA timer 1.
+- */
+-#define VIA_TIMER_FREQ_6	4700000	/* time 1 frequency * 6 */
+-
+-extern struct timezone sys_tz;
+-extern void to_tm(int tim, struct rtc_time * tm);
+-
+-void __pmac pmac_get_rtc_time(struct rtc_time *tm)
+-{
+-	switch(sys_ctrler) {
+-#ifdef CONFIG_ADB_PMU
+-	case SYS_CTRLER_PMU: {
+-		/* TODO: Move that to a function in the PMU driver */
+-		struct adb_request req;
+-		unsigned int now;
+-
+-		if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
+-			return;
+-		pmu_wait_complete(&req);
+-		if (req.reply_len != 4)
+-			printk(KERN_ERR "pmac_get_rtc_time: PMU returned a %d"
+-			       " bytes reply\n", req.reply_len);
+-		now = (req.reply[0] << 24) + (req.reply[1] << 16)
+-			+ (req.reply[2] << 8) + req.reply[3];
+-		DBG("get: %u -> %u\n", (int)now, (int)(now - RTC_OFFSET));
+-		now -= RTC_OFFSET;
+-
+-		to_tm(now, tm);
+-		tm->tm_year -= 1900;
+-		tm->tm_mon -= 1;
+-	
+-		DBG("-> tm_mday: %d, tm_mon: %d, tm_year: %d, %d:%02d:%02d\n",
+-		    tm->tm_mday, tm->tm_mon, tm->tm_year,
+-		    tm->tm_hour, tm->tm_min, tm->tm_sec);
+-		break;
+-	}
+-#endif /* CONFIG_ADB_PMU */
+-
+-#ifdef CONFIG_PMAC_SMU
+-	case SYS_CTRLER_SMU:
+-		smu_get_rtc_time(tm, 1);
+-		break;
+-#endif /* CONFIG_PMAC_SMU */
+-	default:
+-		;
+-	}
+-}
+-
+-int __pmac pmac_set_rtc_time(struct rtc_time *tm)
+-{
+-	switch(sys_ctrler) {
+-#ifdef CONFIG_ADB_PMU
+-	case SYS_CTRLER_PMU: {
+-		/* TODO: Move that to a function in the PMU driver */
+-		struct adb_request req;
+-		unsigned int nowtime;
+-
+-		DBG("set: tm_mday: %d, tm_mon: %d, tm_year: %d,"
+-		    " %d:%02d:%02d\n",
+-		    tm->tm_mday, tm->tm_mon, tm->tm_year,
+-		    tm->tm_hour, tm->tm_min, tm->tm_sec);
+-
+-		nowtime = mktime(tm->tm_year + 1900, tm->tm_mon + 1,
+-				 tm->tm_mday, tm->tm_hour, tm->tm_min,
+-				 tm->tm_sec);
+-
+-		DBG("-> %u -> %u\n", (int)nowtime,
+-		    (int)(nowtime + RTC_OFFSET));
+-		nowtime += RTC_OFFSET;
+-
+-		if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
+-				nowtime >> 24, nowtime >> 16,
+-				nowtime >> 8, nowtime) < 0)
+-			return -ENXIO;
+-		pmu_wait_complete(&req);
+-		if (req.reply_len != 0)
+-			printk(KERN_ERR "pmac_set_rtc_time: PMU returned a %d"
+-			       " bytes reply\n", req.reply_len);
+-		return 0;
+-	}
+-#endif /* CONFIG_ADB_PMU */
+-
+-#ifdef CONFIG_PMAC_SMU
+-	case SYS_CTRLER_SMU:
+-		return smu_set_rtc_time(tm, 1);
+-#endif /* CONFIG_PMAC_SMU */
+-	default:
+-		return -ENODEV;
+-	}
+-}
+-
+-void __init pmac_get_boot_time(struct rtc_time *tm)
+-{
+-	pmac_get_rtc_time(tm);
+-
+-#ifdef disabled__CONFIG_NVRAM
+-	s32 delta = 0;
+-	int dst;
+-	
+-	delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
+-	delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
+-	delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
+-	if (delta & 0x00800000UL)
+-		delta |= 0xFF000000UL;
+-	dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
+-	printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
+-		dst ? "on" : "off");
+-#endif
+-}
+-
+-/*
+- * Query the OF and get the decr frequency.
+- * FIXME: merge this with generic_calibrate_decr
+- */
+-void __init pmac_calibrate_decr(void)
+-{
+-	struct device_node *cpu;
+-	unsigned int freq, *fp;
+-	struct div_result divres;
+-
+-	/*
+-	 * The cpu node should have a timebase-frequency property
+-	 * to tell us the rate at which the decrementer counts.
+-	 */
+-	cpu = find_type_devices("cpu");
+-	if (cpu == 0)
+-		panic("can't find cpu node in time_init");
+-	fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL);
+-	if (fp == 0)
+-		panic("can't get cpu timebase frequency");
+-	freq = *fp;
+-	printk("time_init: decrementer frequency = %u.%.6u MHz\n",
+-	       freq/1000000, freq%1000000);
+-	tb_ticks_per_jiffy = freq / HZ;
+-	tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
+-	tb_ticks_per_usec = freq / 1000000;
+-	tb_to_us = mulhwu_scale_factor(freq, 1000000);
+-	div128_by_32( 1024*1024, 0, tb_ticks_per_sec, &divres );
+-	tb_to_xs = divres.result_low;
+-	ppc_tb_freq = freq;
+-
+-	fp = (unsigned int *)get_property(cpu, "clock-frequency", NULL);
+-	if (fp == 0)
+-		panic("can't get cpu processor frequency");
+-	ppc_proc_freq = *fp;
+-
+-	setup_default_decr();
+-}
+-
+diff --git a/arch/ppc64/kernel/pmc.c b/arch/ppc64/kernel/pmc.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/pmc.c
++++ /dev/null
+@@ -1,88 +0,0 @@
+-/*
+- *  linux/arch/ppc64/kernel/pmc.c
+- *
+- *  Copyright (C) 2004 David Gibson, 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.
+- */
+-
+-#include <linux/config.h>
+-#include <linux/errno.h>
+-#include <linux/spinlock.h>
+-#include <linux/module.h>
+-
+-#include <asm/processor.h>
+-#include <asm/pmc.h>
+-
+-/* Ensure exceptions are disabled */
+-static void dummy_perf(struct pt_regs *regs)
+-{
+-	unsigned int mmcr0 = mfspr(SPRN_MMCR0);
+-
+-	mmcr0 &= ~(MMCR0_PMXE|MMCR0_PMAO);
+-	mtspr(SPRN_MMCR0, mmcr0);
+-}
+-
+-static DEFINE_SPINLOCK(pmc_owner_lock);
+-static void *pmc_owner_caller; /* mostly for debugging */
+-perf_irq_t perf_irq = dummy_perf;
+-
+-int reserve_pmc_hardware(perf_irq_t new_perf_irq)
+-{
+-	int err = 0;
+-
+-	spin_lock(&pmc_owner_lock);
+-
+-	if (pmc_owner_caller) {
+-		printk(KERN_WARNING "reserve_pmc_hardware: "
+-		       "PMC hardware busy (reserved by caller %p)\n",
+-		       pmc_owner_caller);
+-		err = -EBUSY;
+-		goto out;
+-	}
+-
+-	pmc_owner_caller = __builtin_return_address(0);
+-	perf_irq = new_perf_irq ? : dummy_perf;
+-
+- out:
+-	spin_unlock(&pmc_owner_lock);
+-	return err;
+-}
+-EXPORT_SYMBOL_GPL(reserve_pmc_hardware);
+-
+-void release_pmc_hardware(void)
+-{
+-	spin_lock(&pmc_owner_lock);
+-
+-	WARN_ON(! pmc_owner_caller);
+-
+-	pmc_owner_caller = NULL;
+-	perf_irq = dummy_perf;
+-
+-	spin_unlock(&pmc_owner_lock);
+-}
+-EXPORT_SYMBOL_GPL(release_pmc_hardware);
+-
+-void power4_enable_pmcs(void)
+-{
+-	unsigned long hid0;
+-
+-	hid0 = mfspr(HID0);
+-	hid0 |= 1UL << (63 - 20);
+-
+-	/* POWER4 requires the following sequence */
+-	asm volatile(
+-		"sync\n"
+-		"mtspr     %1, %0\n"
+-		"mfspr     %0, %1\n"
+-		"mfspr     %0, %1\n"
+-		"mfspr     %0, %1\n"
+-		"mfspr     %0, %1\n"
+-		"mfspr     %0, %1\n"
+-		"mfspr     %0, %1\n"
+-		"isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0):
+-		"memory");
+-}
+diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
+--- a/arch/ppc64/kernel/ppc_ksyms.c
++++ b/arch/ppc64/kernel/ppc_ksyms.c
+@@ -19,7 +19,6 @@
+ #include <asm/hw_irq.h>
+ #include <asm/abs_addr.h>
+ #include <asm/cacheflush.h>
+-#include <asm/iSeries/HvCallSc.h>
+ 
+ EXPORT_SYMBOL(strcpy);
+ EXPORT_SYMBOL(strncpy);
+@@ -46,17 +45,6 @@ EXPORT_SYMBOL(__strnlen_user);
+ 
+ EXPORT_SYMBOL(reloc_offset);
+ 
+-#ifdef CONFIG_PPC_ISERIES
+-EXPORT_SYMBOL(HvCall0);
+-EXPORT_SYMBOL(HvCall1);
+-EXPORT_SYMBOL(HvCall2);
+-EXPORT_SYMBOL(HvCall3);
+-EXPORT_SYMBOL(HvCall4);
+-EXPORT_SYMBOL(HvCall5);
+-EXPORT_SYMBOL(HvCall6);
+-EXPORT_SYMBOL(HvCall7);
+-#endif
+-
+ EXPORT_SYMBOL(_insb);
+ EXPORT_SYMBOL(_outsb);
+ EXPORT_SYMBOL(_insw);
+@@ -77,14 +65,6 @@ EXPORT_SYMBOL(giveup_altivec);
+ EXPORT_SYMBOL(__flush_icache_range);
+ EXPORT_SYMBOL(flush_dcache_range);
+ 
+-#ifdef CONFIG_SMP
+-#ifdef CONFIG_PPC_ISERIES
+-EXPORT_SYMBOL(local_get_flags);
+-EXPORT_SYMBOL(local_irq_disable);
+-EXPORT_SYMBOL(local_irq_restore);
+-#endif
+-#endif
+-
+ EXPORT_SYMBOL(memcpy);
+ EXPORT_SYMBOL(memset);
+ EXPORT_SYMBOL(memmove);
+diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/process.c
++++ /dev/null
+@@ -1,713 +0,0 @@
+-/*
+- *  linux/arch/ppc64/kernel/process.c
+- *
+- *  Derived from "arch/i386/kernel/process.c"
+- *    Copyright (C) 1995  Linus Torvalds
+- *
+- *  Updated and modified by Cort Dougan (cort at cs.nmt.edu) and
+- *  Paul Mackerras (paulus at cs.anu.edu.au)
+- *
+- *  PowerPC version 
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.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/config.h>
+-#include <linux/module.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/stddef.h>
+-#include <linux/unistd.h>
+-#include <linux/slab.h>
+-#include <linux/user.h>
+-#include <linux/elf.h>
+-#include <linux/init.h>
+-#include <linux/init_task.h>
+-#include <linux/prctl.h>
+-#include <linux/ptrace.h>
+-#include <linux/kallsyms.h>
+-#include <linux/interrupt.h>
+-#include <linux/utsname.h>
+-#include <linux/kprobes.h>
+-
+-#include <asm/pgtable.h>
+-#include <asm/uaccess.h>
+-#include <asm/system.h>
+-#include <asm/io.h>
+-#include <asm/processor.h>
+-#include <asm/mmu.h>
+-#include <asm/mmu_context.h>
+-#include <asm/prom.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/machdep.h>
+-#include <asm/iSeries/HvCallHpt.h>
+-#include <asm/cputable.h>
+-#include <asm/firmware.h>
+-#include <asm/sections.h>
+-#include <asm/tlbflush.h>
+-#include <asm/time.h>
+-#include <asm/plpar_wrappers.h>
+-
+-#ifndef CONFIG_SMP
+-struct task_struct *last_task_used_math = NULL;
+-struct task_struct *last_task_used_altivec = NULL;
+-#endif
+-
+-/*
+- * Make sure the floating-point register state in the
+- * the thread_struct is up to date for task tsk.
+- */
+-void flush_fp_to_thread(struct task_struct *tsk)
+-{
+-	if (tsk->thread.regs) {
+-		/*
+-		 * We need to disable preemption here because if we didn't,
+-		 * another process could get scheduled after the regs->msr
+-		 * test but before we have finished saving the FP registers
+-		 * to the thread_struct.  That process could take over the
+-		 * FPU, and then when we get scheduled again we would store
+-		 * bogus values for the remaining FP registers.
+-		 */
+-		preempt_disable();
+-		if (tsk->thread.regs->msr & MSR_FP) {
+-#ifdef CONFIG_SMP
+-			/*
+-			 * This should only ever be called for current or
+-			 * for a stopped child process.  Since we save away
+-			 * the FP register state on context switch on SMP,
+-			 * there is something wrong if a stopped child appears
+-			 * to still have its FP state in the CPU registers.
+-			 */
+-			BUG_ON(tsk != current);
+-#endif
+-			giveup_fpu(current);
+-		}
+-		preempt_enable();
+-	}
+-}
+-
+-void enable_kernel_fp(void)
+-{
+-	WARN_ON(preemptible());
+-
+-#ifdef CONFIG_SMP
+-	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
+-		giveup_fpu(current);
+-	else
+-		giveup_fpu(NULL);	/* just enables FP for kernel */
+-#else
+-	giveup_fpu(last_task_used_math);
+-#endif /* CONFIG_SMP */
+-}
+-EXPORT_SYMBOL(enable_kernel_fp);
+-
+-int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
+-{
+-	if (!tsk->thread.regs)
+-		return 0;
+-	flush_fp_to_thread(current);
+-
+-	memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
+-
+-	return 1;
+-}
+-
+-#ifdef CONFIG_ALTIVEC
+-
+-void enable_kernel_altivec(void)
+-{
+-	WARN_ON(preemptible());
+-
+-#ifdef CONFIG_SMP
+-	if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
+-		giveup_altivec(current);
+-	else
+-		giveup_altivec(NULL);	/* just enables FP for kernel */
+-#else
+-	giveup_altivec(last_task_used_altivec);
+-#endif /* CONFIG_SMP */
+-}
+-EXPORT_SYMBOL(enable_kernel_altivec);
+-
+-/*
+- * Make sure the VMX/Altivec register state in the
+- * the thread_struct is up to date for task tsk.
+- */
+-void flush_altivec_to_thread(struct task_struct *tsk)
+-{
+-	if (tsk->thread.regs) {
+-		preempt_disable();
+-		if (tsk->thread.regs->msr & MSR_VEC) {
+-#ifdef CONFIG_SMP
+-			BUG_ON(tsk != current);
+-#endif
+-			giveup_altivec(current);
+-		}
+-		preempt_enable();
+-	}
+-}
+-
+-int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
+-{
+-	flush_altivec_to_thread(current);
+-	memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
+-	return 1;
+-}
+-
+-#endif /* CONFIG_ALTIVEC */
+-
+-static void set_dabr_spr(unsigned long val)
+-{
+-	mtspr(SPRN_DABR, val);
+-}
+-
+-int set_dabr(unsigned long dabr)
+-{
+-	int ret = 0;
+-
+-	if (firmware_has_feature(FW_FEATURE_XDABR)) {
+-		/* We want to catch accesses from kernel and userspace */
+-		unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
+-		ret = plpar_set_xdabr(dabr, flags);
+-	} else if (firmware_has_feature(FW_FEATURE_DABR)) {
+-		ret = plpar_set_dabr(dabr);
+-	} else {
+-		set_dabr_spr(dabr);
+-	}
+-
+-	return ret;
+-}
+-
+-DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
+-static DEFINE_PER_CPU(unsigned long, current_dabr);
+-
+-struct task_struct *__switch_to(struct task_struct *prev,
+-				struct task_struct *new)
+-{
+-	struct thread_struct *new_thread, *old_thread;
+-	unsigned long flags;
+-	struct task_struct *last;
+-
+-#ifdef CONFIG_SMP
+-	/* avoid complexity of lazy save/restore of fpu
+-	 * by just saving it every time we switch out if
+-	 * this task used the fpu during the last quantum.
+-	 * 
+-	 * If it tries to use the fpu again, it'll trap and
+-	 * reload its fp regs.  So we don't have to do a restore
+-	 * every switch, just a save.
+-	 *  -- Cort
+-	 */
+-	if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
+-		giveup_fpu(prev);
+-#ifdef CONFIG_ALTIVEC
+-	if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
+-		giveup_altivec(prev);
+-#endif /* CONFIG_ALTIVEC */
+-#endif /* CONFIG_SMP */
+-
+-#if defined(CONFIG_ALTIVEC) && !defined(CONFIG_SMP)
+-	/* Avoid the trap.  On smp this this never happens since
+-	 * we don't set last_task_used_altivec -- Cort
+-	 */
+-	if (new->thread.regs && last_task_used_altivec == new)
+-		new->thread.regs->msr |= MSR_VEC;
+-#endif /* CONFIG_ALTIVEC */
+-
+-	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
+-		set_dabr(new->thread.dabr);
+-		__get_cpu_var(current_dabr) = new->thread.dabr;
+-	}
+-
+-	flush_tlb_pending();
+-
+-	new_thread = &new->thread;
+-	old_thread = &current->thread;
+-
+-	/* Collect purr utilization data per process and per processor
+-	 * wise purr is nothing but processor time base
+-	 */
+-	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+-		struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
+-		long unsigned start_tb, current_tb;
+-		start_tb = old_thread->start_tb;
+-		cu->current_tb = current_tb = mfspr(SPRN_PURR);
+-		old_thread->accum_tb += (current_tb - start_tb);
+-		new_thread->start_tb = current_tb;
+-	}
+-
+-	local_irq_save(flags);
+-	last = _switch(old_thread, new_thread);
+-
+-	local_irq_restore(flags);
+-
+-	return last;
+-}
+-
+-static int instructions_to_print = 16;
+-
+-static void show_instructions(struct pt_regs *regs)
+-{
+-	int i;
+-	unsigned long pc = regs->nip - (instructions_to_print * 3 / 4 *
+-			sizeof(int));
+-
+-	printk("Instruction dump:");
+-
+-	for (i = 0; i < instructions_to_print; i++) {
+-		int instr;
+-
+-		if (!(i % 8))
+-			printk("\n");
+-
+-		if (((REGION_ID(pc) != KERNEL_REGION_ID) &&
+-		     (REGION_ID(pc) != VMALLOC_REGION_ID)) ||
+-		     __get_user(instr, (unsigned int *)pc)) {
+-			printk("XXXXXXXX ");
+-		} else {
+-			if (regs->nip == pc)
+-				printk("<%08x> ", instr);
+-			else
+-				printk("%08x ", instr);
+-		}
+-
+-		pc += sizeof(int);
+-	}
+-
+-	printk("\n");
+-}
+-
+-void show_regs(struct pt_regs * regs)
+-{
+-	int i;
+-	unsigned long trap;
+-
+-	printk("NIP: %016lX XER: %08X LR: %016lX CTR: %016lX\n",
+-	       regs->nip, (unsigned int)regs->xer, regs->link, regs->ctr);
+-	printk("REGS: %p TRAP: %04lx   %s  (%s)\n",
+-	       regs, regs->trap, print_tainted(), system_utsname.release);
+-	printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x "
+-	       "IR/DR: %01x%01x CR: %08X\n",
+-	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
+-	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
+-	       regs->msr&MSR_IR ? 1 : 0,
+-	       regs->msr&MSR_DR ? 1 : 0,
+-	       (unsigned int)regs->ccr);
+-	trap = TRAP(regs);
+-	printk("DAR: %016lx DSISR: %016lx\n", regs->dar, regs->dsisr);
+-	printk("TASK: %p[%d] '%s' THREAD: %p",
+-	       current, current->pid, current->comm, current->thread_info);
+-
+-#ifdef CONFIG_SMP
+-	printk(" CPU: %d", smp_processor_id());
+-#endif /* CONFIG_SMP */
+-
+-	for (i = 0; i < 32; i++) {
+-		if ((i % 4) == 0) {
+-			printk("\n" KERN_INFO "GPR%02d: ", i);
+-		}
+-
+-		printk("%016lX ", regs->gpr[i]);
+-		if (i == 13 && !FULL_REGS(regs))
+-			break;
+-	}
+-	printk("\n");
+-	/*
+-	 * Lookup NIP late so we have the best change of getting the
+-	 * above info out without failing
+-	 */
+-	printk("NIP [%016lx] ", regs->nip);
+-	print_symbol("%s\n", regs->nip);
+-	printk("LR [%016lx] ", regs->link);
+-	print_symbol("%s\n", regs->link);
+-	show_stack(current, (unsigned long *)regs->gpr[1]);
+-	if (!user_mode(regs))
+-		show_instructions(regs);
+-}
+-
+-void exit_thread(void)
+-{
+-	kprobe_flush_task(current);
+-
+-#ifndef CONFIG_SMP
+-	if (last_task_used_math == current)
+-		last_task_used_math = NULL;
+-#ifdef CONFIG_ALTIVEC
+-	if (last_task_used_altivec == current)
+-		last_task_used_altivec = NULL;
+-#endif /* CONFIG_ALTIVEC */
+-#endif /* CONFIG_SMP */
+-}
+-
+-void flush_thread(void)
+-{
+-	struct thread_info *t = current_thread_info();
+-
+-	kprobe_flush_task(current);
+-	if (t->flags & _TIF_ABI_PENDING)
+-		t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
+-
+-#ifndef CONFIG_SMP
+-	if (last_task_used_math == current)
+-		last_task_used_math = NULL;
+-#ifdef CONFIG_ALTIVEC
+-	if (last_task_used_altivec == current)
+-		last_task_used_altivec = NULL;
+-#endif /* CONFIG_ALTIVEC */
+-#endif /* CONFIG_SMP */
+-
+-	if (current->thread.dabr) {
+-		current->thread.dabr = 0;
+-		set_dabr(0);
+-	}
+-}
+-
+-void
+-release_thread(struct task_struct *t)
+-{
+-}
+-
+-
+-/*
+- * This gets called before we allocate a new thread and copy
+- * the current task into it.
+- */
+-void prepare_to_copy(struct task_struct *tsk)
+-{
+-	flush_fp_to_thread(current);
+-	flush_altivec_to_thread(current);
+-}
+-
+-/*
+- * Copy a thread..
+- */
+-int
+-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+-	    unsigned long unused, struct task_struct *p, struct pt_regs *regs)
+-{
+-	struct pt_regs *childregs, *kregs;
+-	extern void ret_from_fork(void);
+-	unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
+-
+-	/* Copy registers */
+-	sp -= sizeof(struct pt_regs);
+-	childregs = (struct pt_regs *) sp;
+-	*childregs = *regs;
+-	if ((childregs->msr & MSR_PR) == 0) {
+-		/* for kernel thread, set stackptr in new task */
+-		childregs->gpr[1] = sp + sizeof(struct pt_regs);
+-		p->thread.regs = NULL;	/* no user register state */
+-		clear_ti_thread_flag(p->thread_info, TIF_32BIT);
+-	} else {
+-		childregs->gpr[1] = usp;
+-		p->thread.regs = childregs;
+-		if (clone_flags & CLONE_SETTLS) {
+-			if (test_thread_flag(TIF_32BIT))
+-				childregs->gpr[2] = childregs->gpr[6];
+-			else
+-				childregs->gpr[13] = childregs->gpr[6];
+-		}
+-	}
+-	childregs->gpr[3] = 0;  /* Result from fork() */
+-	sp -= STACK_FRAME_OVERHEAD;
+-
+-	/*
+-	 * The way this works is that at some point in the future
+-	 * some task will call _switch to switch to the new task.
+-	 * That will pop off the stack frame created below and start
+-	 * the new task running at ret_from_fork.  The new task will
+-	 * do some house keeping and then return from the fork or clone
+-	 * system call, using the stack frame created above.
+-	 */
+-	sp -= sizeof(struct pt_regs);
+-	kregs = (struct pt_regs *) sp;
+-	sp -= STACK_FRAME_OVERHEAD;
+-	p->thread.ksp = sp;
+-	if (cpu_has_feature(CPU_FTR_SLB)) {
+-		unsigned long sp_vsid = get_kernel_vsid(sp);
+-
+-		sp_vsid <<= SLB_VSID_SHIFT;
+-		sp_vsid |= SLB_VSID_KERNEL;
+-		if (cpu_has_feature(CPU_FTR_16M_PAGE))
+-			sp_vsid |= SLB_VSID_L;
+-
+-		p->thread.ksp_vsid = sp_vsid;
+-	}
+-
+-	/*
+-	 * The PPC64 ABI makes use of a TOC to contain function 
+-	 * pointers.  The function (ret_from_except) is actually a pointer
+-	 * to the TOC entry.  The first entry is a pointer to the actual
+-	 * function.
+- 	 */
+-	kregs->nip = *((unsigned long *)ret_from_fork);
+-
+-	return 0;
+-}
+-
+-/*
+- * Set up a thread for executing a new program
+- */
+-void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp)
+-{
+-	unsigned long entry, toc, load_addr = regs->gpr[2];
+-
+-	/* fdptr is a relocated pointer to the function descriptor for
+-         * the elf _start routine.  The first entry in the function
+-         * descriptor is the entry address of _start and the second
+-         * entry is the TOC value we need to use.
+-         */
+-	set_fs(USER_DS);
+-	__get_user(entry, (unsigned long __user *)fdptr);
+-	__get_user(toc, (unsigned long __user *)fdptr+1);
+-
+-	/* Check whether the e_entry function descriptor entries
+-	 * need to be relocated before we can use them.
+-	 */
+-	if (load_addr != 0) {
+-		entry += load_addr;
+-		toc   += load_addr;
+-	}
+-
+-	/*
+-	 * If we exec out of a kernel thread then thread.regs will not be
+-	 * set. Do it now.
+-	 */
+-	if (!current->thread.regs) {
+-		unsigned long childregs = (unsigned long)current->thread_info +
+-						THREAD_SIZE;
+-		childregs -= sizeof(struct pt_regs);
+-		current->thread.regs = (struct pt_regs *)childregs;
+-	}
+-
+-	regs->nip = entry;
+-	regs->gpr[1] = sp;
+-	regs->gpr[2] = toc;
+-	regs->msr = MSR_USER64;
+-#ifndef CONFIG_SMP
+-	if (last_task_used_math == current)
+-		last_task_used_math = 0;
+-#endif /* CONFIG_SMP */
+-	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
+-	current->thread.fpscr = 0;
+-#ifdef CONFIG_ALTIVEC
+-#ifndef CONFIG_SMP
+-	if (last_task_used_altivec == current)
+-		last_task_used_altivec = 0;
+-#endif /* CONFIG_SMP */
+-	memset(current->thread.vr, 0, sizeof(current->thread.vr));
+-	current->thread.vscr.u[0] = 0;
+-	current->thread.vscr.u[1] = 0;
+-	current->thread.vscr.u[2] = 0;
+-	current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
+-	current->thread.vrsave = 0;
+-	current->thread.used_vr = 0;
+-#endif /* CONFIG_ALTIVEC */
+-}
+-EXPORT_SYMBOL(start_thread);
+-
+-int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
+-{
+-	struct pt_regs *regs = tsk->thread.regs;
+-
+-	if (val > PR_FP_EXC_PRECISE)
+-		return -EINVAL;
+-	tsk->thread.fpexc_mode = __pack_fe01(val);
+-	if (regs != NULL && (regs->msr & MSR_FP) != 0)
+-		regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
+-			| tsk->thread.fpexc_mode;
+-	return 0;
+-}
+-
+-int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
+-{
+-	unsigned int val;
+-
+-	val = __unpack_fe01(tsk->thread.fpexc_mode);
+-	return put_user(val, (unsigned int __user *) adr);
+-}
+-
+-int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,
+-	      unsigned long p4, unsigned long p5, unsigned long p6,
+-	      struct pt_regs *regs)
+-{
+-	unsigned long parent_tidptr = 0;
+-	unsigned long child_tidptr = 0;
+-
+-	if (p2 == 0)
+-		p2 = regs->gpr[1];	/* stack pointer for child */
+-
+-	if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_SETTID |
+-			   CLONE_CHILD_CLEARTID)) {
+-		parent_tidptr = p3;
+-		child_tidptr = p5;
+-		if (test_thread_flag(TIF_32BIT)) {
+-			parent_tidptr &= 0xffffffff;
+-			child_tidptr &= 0xffffffff;
+-		}
+-	}
+-
+-	return do_fork(clone_flags, p2, regs, 0,
+-		    (int __user *)parent_tidptr, (int __user *)child_tidptr);
+-}
+-
+-int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
+-	     unsigned long p4, unsigned long p5, unsigned long p6,
+-	     struct pt_regs *regs)
+-{
+-	return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
+-}
+-
+-int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
+-	      unsigned long p4, unsigned long p5, unsigned long p6,
+-	      struct pt_regs *regs)
+-{
+-	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0,
+-	            NULL, NULL);
+-}
+-
+-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+-	       unsigned long a3, unsigned long a4, unsigned long a5,
+-	       struct pt_regs *regs)
+-{
+-	int error;
+-	char * filename;
+-	
+-	filename = getname((char __user *) a0);
+-	error = PTR_ERR(filename);
+-	if (IS_ERR(filename))
+-		goto out;
+-	flush_fp_to_thread(current);
+-	flush_altivec_to_thread(current);
+-	error = do_execve(filename, (char __user * __user *) a1,
+-				    (char __user * __user *) a2, regs);
+-  
+-	if (error == 0) {
+-		task_lock(current);
+-		current->ptrace &= ~PT_DTRACE;
+-		task_unlock(current);
+-	}
+-	putname(filename);
+-
+-out:
+-	return error;
+-}
+-
+-static int kstack_depth_to_print = 64;
+-
+-static int validate_sp(unsigned long sp, struct task_struct *p,
+-		       unsigned long nbytes)
+-{
+-	unsigned long stack_page = (unsigned long)p->thread_info;
+-
+-	if (sp >= stack_page + sizeof(struct thread_struct)
+-	    && sp <= stack_page + THREAD_SIZE - nbytes)
+-		return 1;
+-
+-#ifdef CONFIG_IRQSTACKS
+-	stack_page = (unsigned long) hardirq_ctx[task_cpu(p)];
+-	if (sp >= stack_page + sizeof(struct thread_struct)
+-	    && sp <= stack_page + THREAD_SIZE - nbytes)
+-		return 1;
+-
+-	stack_page = (unsigned long) softirq_ctx[task_cpu(p)];
+-	if (sp >= stack_page + sizeof(struct thread_struct)
+-	    && sp <= stack_page + THREAD_SIZE - nbytes)
+-		return 1;
+-#endif
+-
+-	return 0;
+-}
+-
+-unsigned long get_wchan(struct task_struct *p)
+-{
+-	unsigned long ip, sp;
+-	int count = 0;
+-
+-	if (!p || p == current || p->state == TASK_RUNNING)
+-		return 0;
+-
+-	sp = p->thread.ksp;
+-	if (!validate_sp(sp, p, 112))
+-		return 0;
+-
+-	do {
+-		sp = *(unsigned long *)sp;
+-		if (!validate_sp(sp, p, 112))
+-			return 0;
+-		if (count > 0) {
+-			ip = *(unsigned long *)(sp + 16);
+-			if (!in_sched_functions(ip))
+-				return ip;
+-		}
+-	} while (count++ < 16);
+-	return 0;
+-}
+-EXPORT_SYMBOL(get_wchan);
+-
+-void show_stack(struct task_struct *p, unsigned long *_sp)
+-{
+-	unsigned long ip, newsp, lr;
+-	int count = 0;
+-	unsigned long sp = (unsigned long)_sp;
+-	int firstframe = 1;
+-
+-	if (sp == 0) {
+-		if (p) {
+-			sp = p->thread.ksp;
+-		} else {
+-			sp = __get_SP();
+-			p = current;
+-		}
+-	}
+-
+-	lr = 0;
+-	printk("Call Trace:\n");
+-	do {
+-		if (!validate_sp(sp, p, 112))
+-			return;
+-
+-		_sp = (unsigned long *) sp;
+-		newsp = _sp[0];
+-		ip = _sp[2];
+-		if (!firstframe || ip != lr) {
+-			printk("[%016lx] [%016lx] ", sp, ip);
+-			print_symbol("%s", ip);
+-			if (firstframe)
+-				printk(" (unreliable)");
+-			printk("\n");
+-		}
+-		firstframe = 0;
+-
+-		/*
+-		 * See if this is an exception frame.
+-		 * We look for the "regshere" marker in the current frame.
+-		 */
+-		if (validate_sp(sp, p, sizeof(struct pt_regs) + 400)
+-		    && _sp[12] == 0x7265677368657265ul) {
+-			struct pt_regs *regs = (struct pt_regs *)
+-				(sp + STACK_FRAME_OVERHEAD);
+-			printk("--- Exception: %lx", regs->trap);
+-			print_symbol(" at %s\n", regs->nip);
+-			lr = regs->link;
+-			print_symbol("    LR = %s\n", lr);
+-			firstframe = 1;
+-		}
+-
+-		sp = newsp;
+-	} while (count++ < kstack_depth_to_print);
+-}
+-
+-void dump_stack(void)
+-{
+-	show_stack(current, (unsigned long *)__get_SP());
+-}
+-EXPORT_SYMBOL(dump_stack);
+diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
+--- a/arch/ppc64/kernel/prom.c
++++ b/arch/ppc64/kernel/prom.c
+@@ -46,7 +46,6 @@
+ #include <asm/pgtable.h>
+ #include <asm/pci.h>
+ #include <asm/iommu.h>
+-#include <asm/bootinfo.h>
+ #include <asm/ppcdebug.h>
+ #include <asm/btext.h>
+ #include <asm/sections.h>
+@@ -78,11 +77,14 @@ typedef int interpret_func(struct device
+ extern struct rtas_t rtas;
+ extern struct lmb lmb;
+ extern unsigned long klimit;
++extern unsigned long memory_limit;
+ 
+ static int __initdata dt_root_addr_cells;
+ static int __initdata dt_root_size_cells;
+ static int __initdata iommu_is_off;
+ int __initdata iommu_force_on;
++unsigned long tce_alloc_start, tce_alloc_end;
++
+ typedef u32 cell_t;
+ 
+ #if 0
+@@ -1063,7 +1065,6 @@ static int __init early_init_dt_scan_cho
+ {
+ 	u32 *prop;
+ 	u64 *prop64;
+-	extern unsigned long memory_limit, tce_alloc_start, tce_alloc_end;
+ 
+ 	DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+ 
+@@ -1237,7 +1238,7 @@ void __init early_init_devtree(void *par
+ 	lmb_init();
+ 	scan_flat_dt(early_init_dt_scan_root, NULL);
+ 	scan_flat_dt(early_init_dt_scan_memory, NULL);
+-	lmb_enforce_memory_limit();
++	lmb_enforce_memory_limit(memory_limit);
+ 	lmb_analyze();
+ 	systemcfg->physicalMemorySize = lmb_phys_mem_size();
+ 	lmb_reserve(0, __pa(klimit));
+diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
+--- a/arch/ppc64/kernel/prom_init.c
++++ b/arch/ppc64/kernel/prom_init.c
+@@ -44,7 +44,6 @@
+ #include <asm/pgtable.h>
+ #include <asm/pci.h>
+ #include <asm/iommu.h>
+-#include <asm/bootinfo.h>
+ #include <asm/ppcdebug.h>
+ #include <asm/btext.h>
+ #include <asm/sections.h>
+diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/ptrace.c
++++ /dev/null
+@@ -1,363 +0,0 @@
+-/*
+- *  linux/arch/ppc64/kernel/ptrace.c
+- *
+- *  PowerPC version
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- *  Derived from "arch/m68k/kernel/ptrace.c"
+- *  Copyright (C) 1994 by Hamish Macdonald
+- *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+- *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+- *
+- * Modified by Cort Dougan (cort at hq.fsmlabs.com)
+- * and Paul Mackerras (paulus at linuxcare.com.au).
+- *
+- * This file is subject to the terms and conditions of the GNU General
+- * Public License.  See the file README.legal in the main directory of
+- * this archive for more details.
+- */
+-
+-#include <linux/config.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/errno.h>
+-#include <linux/ptrace.h>
+-#include <linux/user.h>
+-#include <linux/security.h>
+-#include <linux/audit.h>
+-#include <linux/seccomp.h>
+-#include <linux/signal.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/page.h>
+-#include <asm/pgtable.h>
+-#include <asm/system.h>
+-#include <asm/ptrace-common.h>
+-
+-/*
+- * does not yet catch signals sent when the child dies.
+- * in exit.c or in signal.c.
+- */
+-
+-/*
+- * Called by kernel/ptrace.c when detaching..
+- *
+- * Make sure single step bits etc are not set.
+- */
+-void ptrace_disable(struct task_struct *child)
+-{
+-	/* make sure the single step bit is not set. */
+-	clear_single_step(child);
+-}
+-
+-int sys_ptrace(long request, long pid, long addr, long data)
+-{
+-	struct task_struct *child;
+-	int ret = -EPERM;
+-
+-	lock_kernel();
+-	if (request == PTRACE_TRACEME) {
+-		/* are we already being traced? */
+-		if (current->ptrace & PT_PTRACED)
+-			goto out;
+-		ret = security_ptrace(current->parent, current);
+-		if (ret)
+-			goto out;
+-		/* set the ptrace bit in the process flags. */
+-		current->ptrace |= PT_PTRACED;
+-		ret = 0;
+-		goto out;
+-	}
+-	ret = -ESRCH;
+-	read_lock(&tasklist_lock);
+-	child = find_task_by_pid(pid);
+-	if (child)
+-		get_task_struct(child);
+-	read_unlock(&tasklist_lock);
+-	if (!child)
+-		goto out;
+-
+-	ret = -EPERM;
+-	if (pid == 1)		/* you may not mess with init */
+-		goto out_tsk;
+-
+-	if (request == PTRACE_ATTACH) {
+-		ret = ptrace_attach(child);
+-		goto out_tsk;
+-	}
+-
+-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+-	if (ret < 0)
+-		goto out_tsk;
+-
+-	switch (request) {
+-	/* when I and D space are separate, these will need to be fixed. */
+-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+-	case PTRACE_PEEKDATA: {
+-		unsigned long tmp;
+-		int copied;
+-
+-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+-		ret = -EIO;
+-		if (copied != sizeof(tmp))
+-			break;
+-		ret = put_user(tmp,(unsigned long __user *) data);
+-		break;
+-	}
+-
+-	/* read the word at location addr in the USER area. */
+-	case PTRACE_PEEKUSR: {
+-		unsigned long index;
+-		unsigned long tmp;
+-
+-		ret = -EIO;
+-		/* convert to index and check */
+-		index = (unsigned long) addr >> 3;
+-		if ((addr & 7) || (index > PT_FPSCR))
+-			break;
+-
+-		if (index < PT_FPR0) {
+-			tmp = get_reg(child, (int)index);
+-		} else {
+-			flush_fp_to_thread(child);
+-			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
+-		}
+-		ret = put_user(tmp,(unsigned long __user *) data);
+-		break;
+-	}
+-
+-	/* If I and D space are separate, this will have to be fixed. */
+-	case PTRACE_POKETEXT: /* write the word at location addr. */
+-	case PTRACE_POKEDATA:
+-		ret = 0;
+-		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+-				== sizeof(data))
+-			break;
+-		ret = -EIO;
+-		break;
+-
+-	/* write the word at location addr in the USER area */
+-	case PTRACE_POKEUSR: {
+-		unsigned long index;
+-
+-		ret = -EIO;
+-		/* convert to index and check */
+-		index = (unsigned long) addr >> 3;
+-		if ((addr & 7) || (index > PT_FPSCR))
+-			break;
+-
+-		if (index == PT_ORIG_R3)
+-			break;
+-		if (index < PT_FPR0) {
+-			ret = put_reg(child, index, data);
+-		} else {
+-			flush_fp_to_thread(child);
+-			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
+-			ret = 0;
+-		}
+-		break;
+-	}
+-
+-	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+-	case PTRACE_CONT: { /* restart after signal. */
+-		ret = -EIO;
+-		if (!valid_signal(data))
+-			break;
+-		if (request == PTRACE_SYSCALL)
+-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		else
+-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		child->exit_code = data;
+-		/* make sure the single step bit is not set. */
+-		clear_single_step(child);
+-		wake_up_process(child);
+-		ret = 0;
+-		break;
+-	}
+-
+-	/*
+-	 * make the child exit.  Best I can do is send it a sigkill.
+-	 * perhaps it should be put in the status that it wants to
+-	 * exit.
+-	 */
+-	case PTRACE_KILL: {
+-		ret = 0;
+-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
+-			break;
+-		child->exit_code = SIGKILL;
+-		/* make sure the single step bit is not set. */
+-		clear_single_step(child);
+-		wake_up_process(child);
+-		break;
+-	}
+-
+-	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+-		ret = -EIO;
+-		if (!valid_signal(data))
+-			break;
+-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		set_single_step(child);
+-		child->exit_code = data;
+-		/* give it a chance to run. */
+-		wake_up_process(child);
+-		ret = 0;
+-		break;
+-	}
+-
+-	case PTRACE_GET_DEBUGREG: {
+-		ret = -EINVAL;
+-		/* We only support one DABR and no IABRS at the moment */
+-		if (addr > 0)
+-			break;
+-		ret = put_user(child->thread.dabr,
+-			       (unsigned long __user *)data);
+-		break;
+-	}
+-
+-	case PTRACE_SET_DEBUGREG:
+-		ret = ptrace_set_debugreg(child, addr, data);
+-		break;
+-
+-	case PTRACE_DETACH:
+-		ret = ptrace_detach(child, data);
+-		break;
+-
+-	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
+-		int i;
+-		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+-		unsigned long __user *tmp = (unsigned long __user *)addr;
+-
+-		for (i = 0; i < 32; i++) {
+-			ret = put_user(*reg, tmp);
+-			if (ret)
+-				break;
+-			reg++;
+-			tmp++;
+-		}
+-		break;
+-	}
+-
+-	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
+-		int i;
+-		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+-		unsigned long __user *tmp = (unsigned long __user *)addr;
+-
+-		for (i = 0; i < 32; i++) {
+-			ret = get_user(*reg, tmp);
+-			if (ret)
+-				break;
+-			reg++;
+-			tmp++;
+-		}
+-		break;
+-	}
+-
+-	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
+-		int i;
+-		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
+-		unsigned long __user *tmp = (unsigned long __user *)addr;
+-
+-		flush_fp_to_thread(child);
+-
+-		for (i = 0; i < 32; i++) {
+-			ret = put_user(*reg, tmp);
+-			if (ret)
+-				break;
+-			reg++;
+-			tmp++;
+-		}
+-		break;
+-	}
+-
+-	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
+-		int i;
+-		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
+-		unsigned long __user *tmp = (unsigned long __user *)addr;
+-
+-		flush_fp_to_thread(child);
+-
+-		for (i = 0; i < 32; i++) {
+-			ret = get_user(*reg, tmp);
+-			if (ret)
+-				break;
+-			reg++;
+-			tmp++;
+-		}
+-		break;
+-	}
+-
+-#ifdef CONFIG_ALTIVEC
+-	case PTRACE_GETVRREGS:
+-		/* Get the child altivec register state. */
+-		flush_altivec_to_thread(child);
+-		ret = get_vrregs((unsigned long __user *)data, child);
+-		break;
+-
+-	case PTRACE_SETVRREGS:
+-		/* Set the child altivec register state. */
+-		flush_altivec_to_thread(child);
+-		ret = set_vrregs(child, (unsigned long __user *)data);
+-		break;
+-#endif
+-
+-	default:
+-		ret = ptrace_request(child, request, addr, data);
+-		break;
+-	}
+-out_tsk:
+-	put_task_struct(child);
+-out:
+-	unlock_kernel();
+-	return ret;
+-}
+-
+-static void do_syscall_trace(void)
+-{
+-	/* the 0x80 provides a way for the tracing parent to distinguish
+-	   between a syscall stop and SIGTRAP delivery */
+-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+-				 ? 0x80 : 0));
+-
+-	/*
+-	 * this isn't the same as continuing with a signal, but it will do
+-	 * for normal use.  strace only continues with a signal if the
+-	 * stopping signal is not SIGTRAP.  -brl
+-	 */
+-	if (current->exit_code) {
+-		send_sig(current->exit_code, current, 1);
+-		current->exit_code = 0;
+-	}
+-}
+-
+-void do_syscall_trace_enter(struct pt_regs *regs)
+-{
+-	secure_computing(regs->gpr[0]);
+-
+-	if (test_thread_flag(TIF_SYSCALL_TRACE)
+-	    && (current->ptrace & PT_PTRACED))
+-		do_syscall_trace();
+-
+-	if (unlikely(current->audit_context))
+-		audit_syscall_entry(current,
+-				    test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
+-				    regs->gpr[0],
+-				    regs->gpr[3], regs->gpr[4],
+-				    regs->gpr[5], regs->gpr[6]);
+-
+-}
+-
+-void do_syscall_trace_leave(struct pt_regs *regs)
+-{
+-	if (unlikely(current->audit_context))
+-		audit_syscall_exit(current, 
+-				   (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+-				   regs->result);
+-
+-	if ((test_thread_flag(TIF_SYSCALL_TRACE)
+-	     || test_thread_flag(TIF_SINGLESTEP))
+-	    && (current->ptrace & PT_PTRACED))
+-		do_syscall_trace();
+-}
+diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/ptrace32.c
++++ /dev/null
+@@ -1,449 +0,0 @@
+-/*
+- *  linux/arch/ppc64/kernel/ptrace32.c
+- *
+- *  PowerPC version
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- *  Derived from "arch/m68k/kernel/ptrace.c"
+- *  Copyright (C) 1994 by Hamish Macdonald
+- *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+- *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+- *
+- * Modified by Cort Dougan (cort at hq.fsmlabs.com)
+- * and Paul Mackerras (paulus at linuxcare.com.au).
+- *
+- * This file is subject to the terms and conditions of the GNU General
+- * Public License.  See the file README.legal in the main directory of
+- * this archive for more details.
+- */
+-
+-#include <linux/config.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/errno.h>
+-#include <linux/ptrace.h>
+-#include <linux/user.h>
+-#include <linux/security.h>
+-#include <linux/signal.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/page.h>
+-#include <asm/pgtable.h>
+-#include <asm/system.h>
+-#include <asm/ptrace-common.h>
+-
+-/*
+- * does not yet catch signals sent when the child dies.
+- * in exit.c or in signal.c.
+- */
+-
+-int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
+-{
+-	struct task_struct *child;
+-	int ret = -EPERM;
+-
+-	lock_kernel();
+-	if (request == PTRACE_TRACEME) {
+-		/* are we already being traced? */
+-		if (current->ptrace & PT_PTRACED)
+-			goto out;
+-		ret = security_ptrace(current->parent, current);
+-		if (ret)
+-			goto out;
+-		/* set the ptrace bit in the process flags. */
+-		current->ptrace |= PT_PTRACED;
+-		ret = 0;
+-		goto out;
+-	}
+-	ret = -ESRCH;
+-	read_lock(&tasklist_lock);
+-	child = find_task_by_pid(pid);
+-	if (child)
+-		get_task_struct(child);
+-	read_unlock(&tasklist_lock);
+-	if (!child)
+-		goto out;
+-
+-	ret = -EPERM;
+-	if (pid == 1)		/* you may not mess with init */
+-		goto out_tsk;
+-
+-	if (request == PTRACE_ATTACH) {
+-		ret = ptrace_attach(child);
+-		goto out_tsk;
+-	}
+-
+-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+-	if (ret < 0)
+-		goto out_tsk;
+-
+-	switch (request) {
+-	/* when I and D space are separate, these will need to be fixed. */
+-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+-	case PTRACE_PEEKDATA: {
+-		unsigned int tmp;
+-		int copied;
+-
+-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+-		ret = -EIO;
+-		if (copied != sizeof(tmp))
+-			break;
+-		ret = put_user(tmp, (u32 __user *)data);
+-		break;
+-	}
+-
+-	/*
+-	 * Read 4 bytes of the other process' storage
+-	 *  data is a pointer specifying where the user wants the
+-	 *	4 bytes copied into
+-	 *  addr is a pointer in the user's storage that contains an 8 byte
+-	 *	address in the other process of the 4 bytes that is to be read
+-	 * (this is run in a 32-bit process looking at a 64-bit process)
+-	 * when I and D space are separate, these will need to be fixed.
+-	 */
+-	case PPC_PTRACE_PEEKTEXT_3264:
+-	case PPC_PTRACE_PEEKDATA_3264: {
+-		u32 tmp;
+-		int copied;
+-		u32 __user * addrOthers;
+-
+-		ret = -EIO;
+-
+-		/* Get the addr in the other process that we want to read */
+-		if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
+-			break;
+-
+-		copied = access_process_vm(child, (u64)addrOthers, &tmp,
+-				sizeof(tmp), 0);
+-		if (copied != sizeof(tmp))
+-			break;
+-		ret = put_user(tmp, (u32 __user *)data);
+-		break;
+-	}
+-
+-	/* Read a register (specified by ADDR) out of the "user area" */
+-	case PTRACE_PEEKUSR: {
+-		int index;
+-		unsigned long tmp;
+-
+-		ret = -EIO;
+-		/* convert to index and check */
+-		index = (unsigned long) addr >> 2;
+-		if ((addr & 3) || (index > PT_FPSCR32))
+-			break;
+-
+-		if (index < PT_FPR0) {
+-			tmp = get_reg(child, index);
+-		} else {
+-			flush_fp_to_thread(child);
+-			/*
+-			 * the user space code considers the floating point
+-			 * to be an array of unsigned int (32 bits) - the
+-			 * index passed in is based on this assumption.
+-			 */
+-			tmp = ((unsigned int *)child->thread.fpr)[index - PT_FPR0];
+-		}
+-		ret = put_user((unsigned int)tmp, (u32 __user *)data);
+-		break;
+-	}
+-  
+-	/*
+-	 * Read 4 bytes out of the other process' pt_regs area
+-	 *  data is a pointer specifying where the user wants the
+-	 *	4 bytes copied into
+-	 *  addr is the offset into the other process' pt_regs structure
+-	 *	that is to be read
+-	 * (this is run in a 32-bit process looking at a 64-bit process)
+-	 */
+-	case PPC_PTRACE_PEEKUSR_3264: {
+-		u32 index;
+-		u32 reg32bits;
+-		u64 tmp;
+-		u32 numReg;
+-		u32 part;
+-
+-		ret = -EIO;
+-		/* Determine which register the user wants */
+-		index = (u64)addr >> 2;
+-		numReg = index / 2;
+-		/* Determine which part of the register the user wants */
+-		if (index % 2)
+-			part = 1;  /* want the 2nd half of the register (right-most). */
+-		else
+-			part = 0;  /* want the 1st half of the register (left-most). */
+-
+-		/* Validate the input - check to see if address is on the wrong boundary or beyond the end of the user area */
+-		if ((addr & 3) || numReg > PT_FPSCR)
+-			break;
+-
+-		if (numReg >= PT_FPR0) {
+-			flush_fp_to_thread(child);
+-			tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
+-		} else { /* register within PT_REGS struct */
+-			tmp = get_reg(child, numReg);
+-		} 
+-		reg32bits = ((u32*)&tmp)[part];
+-		ret = put_user(reg32bits, (u32 __user *)data);
+-		break;
+-	}
+-
+-	/* If I and D space are separate, this will have to be fixed. */
+-	case PTRACE_POKETEXT: /* write the word at location addr. */
+-	case PTRACE_POKEDATA: {
+-		unsigned int tmp;
+-		tmp = data;
+-		ret = 0;
+-		if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1)
+-				== sizeof(tmp))
+-			break;
+-		ret = -EIO;
+-		break;
+-	}
+-
+-	/*
+-	 * Write 4 bytes into the other process' storage
+-	 *  data is the 4 bytes that the user wants written
+-	 *  addr is a pointer in the user's storage that contains an
+-	 *	8 byte address in the other process where the 4 bytes
+-	 *	that is to be written
+-	 * (this is run in a 32-bit process looking at a 64-bit process)
+-	 * when I and D space are separate, these will need to be fixed.
+-	 */
+-	case PPC_PTRACE_POKETEXT_3264:
+-	case PPC_PTRACE_POKEDATA_3264: {
+-		u32 tmp = data;
+-		u32 __user * addrOthers;
+-
+-		/* Get the addr in the other process that we want to write into */
+-		ret = -EIO;
+-		if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
+-			break;
+-		ret = 0;
+-		if (access_process_vm(child, (u64)addrOthers, &tmp,
+-					sizeof(tmp), 1) == sizeof(tmp))
+-			break;
+-		ret = -EIO;
+-		break;
+-	}
+-
+-	/* write the word at location addr in the USER area */
+-	case PTRACE_POKEUSR: {
+-		unsigned long index;
+-
+-		ret = -EIO;
+-		/* convert to index and check */
+-		index = (unsigned long) addr >> 2;
+-		if ((addr & 3) || (index > PT_FPSCR32))
+-			break;
+-
+-		if (index == PT_ORIG_R3)
+-			break;
+-		if (index < PT_FPR0) {
+-			ret = put_reg(child, index, data);
+-		} else {
+-			flush_fp_to_thread(child);
+-			/*
+-			 * the user space code considers the floating point
+-			 * to be an array of unsigned int (32 bits) - the
+-			 * index passed in is based on this assumption.
+-			 */
+-			((unsigned int *)child->thread.fpr)[index - PT_FPR0] = data;
+-			ret = 0;
+-		}
+-		break;
+-	}
+-
+-	/*
+-	 * Write 4 bytes into the other process' pt_regs area
+-	 *  data is the 4 bytes that the user wants written
+-	 *  addr is the offset into the other process' pt_regs structure
+-	 *	that is to be written into
+-	 * (this is run in a 32-bit process looking at a 64-bit process)
+-	 */
+-	case PPC_PTRACE_POKEUSR_3264: {
+-		u32 index;
+-		u32 numReg;
+-
+-		ret = -EIO;
+-		/* Determine which register the user wants */
+-		index = (u64)addr >> 2;
+-		numReg = index / 2;
+-		/*
+-		 * Validate the input - check to see if address is on the
+-		 * wrong boundary or beyond the end of the user area
+-		 */
+-		if ((addr & 3) || (numReg > PT_FPSCR))
+-			break;
+-		/* Insure it is a register we let them change */
+-		if ((numReg == PT_ORIG_R3)
+-				|| ((numReg > PT_CCR) && (numReg < PT_FPR0)))
+-			break;
+-		if (numReg >= PT_FPR0) {
+-			flush_fp_to_thread(child);
+-		}
+-		if (numReg == PT_MSR)
+-			data = (data & MSR_DEBUGCHANGE)
+-				| (child->thread.regs->msr & ~MSR_DEBUGCHANGE);
+-		((u32*)child->thread.regs)[index] = data;
+-		ret = 0;
+-		break;
+-	}
+-
+-	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+-	case PTRACE_CONT: { /* restart after signal. */
+-		ret = -EIO;
+-		if (!valid_signal(data))
+-			break;
+-		if (request == PTRACE_SYSCALL)
+-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		else
+-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		child->exit_code = data;
+-		/* make sure the single step bit is not set. */
+-		clear_single_step(child);
+-		wake_up_process(child);
+-		ret = 0;
+-		break;
+-	}
+-
+-	/*
+-	 * make the child exit.  Best I can do is send it a sigkill.
+-	 * perhaps it should be put in the status that it wants to
+-	 * exit.
+-	 */
+-	case PTRACE_KILL: {
+-		ret = 0;
+-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
+-			break;
+-		child->exit_code = SIGKILL;
+-		/* make sure the single step bit is not set. */
+-		clear_single_step(child);
+-		wake_up_process(child);
+-		break;
+-	}
+-
+-	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+-		ret = -EIO;
+-		if (!valid_signal(data))
+-			break;
+-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		set_single_step(child);
+-		child->exit_code = data;
+-		/* give it a chance to run. */
+-		wake_up_process(child);
+-		ret = 0;
+-		break;
+-	}
+-
+-	case PTRACE_GET_DEBUGREG: {
+-		ret = -EINVAL;
+-		/* We only support one DABR and no IABRS at the moment */
+-		if (addr > 0)
+-			break;
+-		ret = put_user(child->thread.dabr, (u32 __user *)data);
+-		break;
+-	}
+-
+-	case PTRACE_SET_DEBUGREG:
+-		ret = ptrace_set_debugreg(child, addr, data);
+-		break;
+-
+-	case PTRACE_DETACH:
+-		ret = ptrace_detach(child, data);
+-		break;
+-
+-	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
+-		int i;
+-		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+-		unsigned int __user *tmp = (unsigned int __user *)addr;
+-
+-		for (i = 0; i < 32; i++) {
+-			ret = put_user(*reg, tmp);
+-			if (ret)
+-				break;
+-			reg++;
+-			tmp++;
+-		}
+-		break;
+-	}
+-
+-	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
+-		int i;
+-		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+-		unsigned int __user *tmp = (unsigned int __user *)addr;
+-
+-		for (i = 0; i < 32; i++) {
+-			ret = get_user(*reg, tmp);
+-			if (ret)
+-				break;
+-			reg++;
+-			tmp++;
+-		}
+-		break;
+-	}
+-
+-	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
+-		int i;
+-		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
+-		unsigned int __user *tmp = (unsigned int __user *)addr;
+-
+-		flush_fp_to_thread(child);
+-
+-		for (i = 0; i < 32; i++) {
+-			ret = put_user(*reg, tmp);
+-			if (ret)
+-				break;
+-			reg++;
+-			tmp++;
+-		}
+-		break;
+-	}
+-
+-	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
+-		int i;
+-		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
+-		unsigned int __user *tmp = (unsigned int __user *)addr;
+-
+-		flush_fp_to_thread(child);
+-
+-		for (i = 0; i < 32; i++) {
+-			ret = get_user(*reg, tmp);
+-			if (ret)
+-				break;
+-			reg++;
+-			tmp++;
+-		}
+-		break;
+-	}
+-
+-	case PTRACE_GETEVENTMSG:
+-		ret = put_user(child->ptrace_message, (unsigned int __user *) data);
+-		break;
+-
+-#ifdef CONFIG_ALTIVEC
+-	case PTRACE_GETVRREGS:
+-		/* Get the child altivec register state. */
+-		flush_altivec_to_thread(child);
+-		ret = get_vrregs((unsigned long __user *)data, child);
+-		break;
+-
+-	case PTRACE_SETVRREGS:
+-		/* Set the child altivec register state. */
+-		flush_altivec_to_thread(child);
+-		ret = set_vrregs(child, (unsigned long __user *)data);
+-		break;
+-#endif
+-
+-	default:
+-		ret = ptrace_request(child, request, addr, data);
+-		break;
+-	}
+-out_tsk:
+-	put_task_struct(child);
+-out:
+-	unlock_kernel();
+-	return ret;
+-}
+diff --git a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/ras.c
++++ /dev/null
+@@ -1,353 +0,0 @@
+-/*
+- * ras.c
+- * Copyright (C) 2001 Dave Engebretsen 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
+- */
+-
+-/* Change Activity:
+- * 2001/09/21 : engebret : Created with minimal EPOW and HW exception support.
+- * End Change Activity 
+- */
+-
+-#include <linux/errno.h>
+-#include <linux/threads.h>
+-#include <linux/kernel_stat.h>
+-#include <linux/signal.h>
+-#include <linux/sched.h>
+-#include <linux/ioport.h>
+-#include <linux/interrupt.h>
+-#include <linux/timex.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <linux/pci.h>
+-#include <linux/delay.h>
+-#include <linux/irq.h>
+-#include <linux/random.h>
+-#include <linux/sysrq.h>
+-#include <linux/bitops.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/system.h>
+-#include <asm/io.h>
+-#include <asm/pgtable.h>
+-#include <asm/irq.h>
+-#include <asm/cache.h>
+-#include <asm/prom.h>
+-#include <asm/ptrace.h>
+-#include <asm/machdep.h>
+-#include <asm/rtas.h>
+-#include <asm/ppcdebug.h>
+-
+-static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
+-static DEFINE_SPINLOCK(ras_log_buf_lock);
+-
+-char mce_data_buf[RTAS_ERROR_LOG_MAX]
+-;
+-/* This is true if we are using the firmware NMI handler (typically LPAR) */
+-extern int fwnmi_active;
+-
+-static int ras_get_sensor_state_token;
+-static int ras_check_exception_token;
+-
+-#define EPOW_SENSOR_TOKEN	9
+-#define EPOW_SENSOR_INDEX	0
+-#define RAS_VECTOR_OFFSET	0x500
+-
+-static irqreturn_t ras_epow_interrupt(int irq, void *dev_id,
+-					struct pt_regs * regs);
+-static irqreturn_t ras_error_interrupt(int irq, void *dev_id,
+-					struct pt_regs * regs);
+-
+-/* #define DEBUG */
+-
+-static void request_ras_irqs(struct device_node *np, char *propname,
+-			irqreturn_t (*handler)(int, void *, struct pt_regs *),
+-			const char *name)
+-{
+-	unsigned int *ireg, len, i;
+-	int virq, n_intr;
+-
+-	ireg = (unsigned int *)get_property(np, propname, &len);
+-	if (ireg == NULL)
+-		return;
+-	n_intr = prom_n_intr_cells(np);
+-	len /= n_intr * sizeof(*ireg);
+-
+-	for (i = 0; i < len; i++) {
+-		virq = virt_irq_create_mapping(*ireg);
+-		if (virq == NO_IRQ) {
+-			printk(KERN_ERR "Unable to allocate interrupt "
+-			       "number for %s\n", np->full_name);
+-			return;
+-		}
+-		if (request_irq(irq_offset_up(virq), handler, 0, name, NULL)) {
+-			printk(KERN_ERR "Unable to request interrupt %d for "
+-			       "%s\n", irq_offset_up(virq), np->full_name);
+-			return;
+-		}
+-		ireg += n_intr;
+-	}
+-}
+-
+-/*
+- * Initialize handlers for the set of interrupts caused by hardware errors
+- * and power system events.
+- */
+-static int __init init_ras_IRQ(void)
+-{
+-	struct device_node *np;
+-
+-	ras_get_sensor_state_token = rtas_token("get-sensor-state");
+-	ras_check_exception_token = rtas_token("check-exception");
+-
+-	/* Internal Errors */
+-	np = of_find_node_by_path("/event-sources/internal-errors");
+-	if (np != NULL) {
+-		request_ras_irqs(np, "open-pic-interrupt", ras_error_interrupt,
+-				 "RAS_ERROR");
+-		request_ras_irqs(np, "interrupts", ras_error_interrupt,
+-				 "RAS_ERROR");
+-		of_node_put(np);
+-	}
+-
+-	/* EPOW Events */
+-	np = of_find_node_by_path("/event-sources/epow-events");
+-	if (np != NULL) {
+-		request_ras_irqs(np, "open-pic-interrupt", ras_epow_interrupt,
+-				 "RAS_EPOW");
+-		request_ras_irqs(np, "interrupts", ras_epow_interrupt,
+-				 "RAS_EPOW");
+-		of_node_put(np);
+-	}
+-
+-	return 1;
+-}
+-__initcall(init_ras_IRQ);
+-
+-/*
+- * Handle power subsystem events (EPOW).
+- *
+- * Presently we just log the event has occurred.  This should be fixed
+- * to examine the type of power failure and take appropriate action where
+- * the time horizon permits something useful to be done.
+- */
+-static irqreturn_t
+-ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+-{
+-	int status = 0xdeadbeef;
+-	int state = 0;
+-	int critical;
+-
+-	status = rtas_call(ras_get_sensor_state_token, 2, 2, &state,
+-			   EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX);
+-
+-	if (state > 3)
+-		critical = 1;  /* Time Critical */
+-	else
+-		critical = 0;
+-
+-	spin_lock(&ras_log_buf_lock);
+-
+-	status = rtas_call(ras_check_exception_token, 6, 1, NULL,
+-			   RAS_VECTOR_OFFSET,
+-			   virt_irq_to_real(irq_offset_down(irq)),
+-			   RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS,
+-			   critical, __pa(&ras_log_buf),
+-				rtas_get_error_log_max());
+-
+-	udbg_printf("EPOW <0x%lx 0x%x 0x%x>\n",
+-		    *((unsigned long *)&ras_log_buf), status, state);
+-	printk(KERN_WARNING "EPOW <0x%lx 0x%x 0x%x>\n",
+-	       *((unsigned long *)&ras_log_buf), status, state);
+-
+-	/* format and print the extended information */
+-	log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, 0);
+-
+-	spin_unlock(&ras_log_buf_lock);
+-	return IRQ_HANDLED;
+-}
+-
+-/*
+- * Handle hardware error interrupts.
+- *
+- * RTAS check-exception is called to collect data on the exception.  If
+- * the error is deemed recoverable, we log a warning and return.
+- * For nonrecoverable errors, an error is logged and we stop all processing
+- * as quickly as possible in order to prevent propagation of the failure.
+- */
+-static irqreturn_t
+-ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+-{
+-	struct rtas_error_log *rtas_elog;
+-	int status = 0xdeadbeef;
+-	int fatal;
+-
+-	spin_lock(&ras_log_buf_lock);
+-
+-	status = rtas_call(ras_check_exception_token, 6, 1, NULL,
+-			   RAS_VECTOR_OFFSET,
+-			   virt_irq_to_real(irq_offset_down(irq)),
+-			   RTAS_INTERNAL_ERROR, 1 /*Time Critical */,
+-			   __pa(&ras_log_buf),
+-				rtas_get_error_log_max());
+-
+-	rtas_elog = (struct rtas_error_log *)ras_log_buf;
+-
+-	if ((status == 0) && (rtas_elog->severity >= RTAS_SEVERITY_ERROR_SYNC))
+-		fatal = 1;
+-	else
+-		fatal = 0;
+-
+-	/* format and print the extended information */
+-	log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, fatal);
+-
+-	if (fatal) {
+-		udbg_printf("Fatal HW Error <0x%lx 0x%x>\n",
+-			    *((unsigned long *)&ras_log_buf), status);
+-		printk(KERN_EMERG "Error: Fatal hardware error <0x%lx 0x%x>\n",
+-		       *((unsigned long *)&ras_log_buf), status);
+-
+-#ifndef DEBUG
+-		/* Don't actually power off when debugging so we can test
+-		 * without actually failing while injecting errors.
+-		 * Error data will not be logged to syslog.
+-		 */
+-		ppc_md.power_off();
+-#endif
+-	} else {
+-		udbg_printf("Recoverable HW Error <0x%lx 0x%x>\n",
+-			    *((unsigned long *)&ras_log_buf), status);
+-		printk(KERN_WARNING
+-		       "Warning: Recoverable hardware error <0x%lx 0x%x>\n",
+-		       *((unsigned long *)&ras_log_buf), status);
+-	}
+-
+-	spin_unlock(&ras_log_buf_lock);
+-	return IRQ_HANDLED;
+-}
+-
+-/* Get the error information for errors coming through the
+- * FWNMI vectors.  The pt_regs' r3 will be updated to reflect
+- * the actual r3 if possible, and a ptr to the error log entry
+- * will be returned if found.
+- *
+- * The mce_data_buf does not have any locks or protection around it,
+- * if a second machine check comes in, or a system reset is done
+- * before we have logged the error, then we will get corruption in the
+- * error log.  This is preferable over holding off on calling
+- * ibm,nmi-interlock which would result in us checkstopping if a
+- * second machine check did come in.
+- */
+-static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
+-{
+-	unsigned long errdata = regs->gpr[3];
+-	struct rtas_error_log *errhdr = NULL;
+-	unsigned long *savep;
+-
+-	if ((errdata >= 0x7000 && errdata < 0x7fff0) ||
+-	    (errdata >= rtas.base && errdata < rtas.base + rtas.size - 16)) {
+-		savep = __va(errdata);
+-		regs->gpr[3] = savep[0];	/* restore original r3 */
+-		memset(mce_data_buf, 0, RTAS_ERROR_LOG_MAX);
+-		memcpy(mce_data_buf, (char *)(savep + 1), RTAS_ERROR_LOG_MAX);
+-		errhdr = (struct rtas_error_log *)mce_data_buf;
+-	} else {
+-		printk("FWNMI: corrupt r3\n");
+-	}
+-	return errhdr;
+-}
+-
+-/* Call this when done with the data returned by FWNMI_get_errinfo.
+- * It will release the saved data area for other CPUs in the
+- * partition to receive FWNMI errors.
+- */
+-static void fwnmi_release_errinfo(void)
+-{
+-	int ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL);
+-	if (ret != 0)
+-		printk("FWNMI: nmi-interlock failed: %d\n", ret);
+-}
+-
+-void pSeries_system_reset_exception(struct pt_regs *regs)
+-{
+-	if (fwnmi_active) {
+-		struct rtas_error_log *errhdr = fwnmi_get_errinfo(regs);
+-		if (errhdr) {
+-			/* XXX Should look at FWNMI information */
+-		}
+-		fwnmi_release_errinfo();
+-	}
+-}
+-
+-/*
+- * See if we can recover from a machine check exception.
+- * This is only called on power4 (or above) and only via
+- * the Firmware Non-Maskable Interrupts (fwnmi) handler
+- * which provides the error analysis for us.
+- *
+- * Return 1 if corrected (or delivered a signal).
+- * Return 0 if there is nothing we can do.
+- */
+-static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
+-{
+-	int nonfatal = 0;
+-
+-	if (err->disposition == RTAS_DISP_FULLY_RECOVERED) {
+-		/* Platform corrected itself */
+-		nonfatal = 1;
+-	} else if ((regs->msr & MSR_RI) &&
+-		   user_mode(regs) &&
+-		   err->severity == RTAS_SEVERITY_ERROR_SYNC &&
+-		   err->disposition == RTAS_DISP_NOT_RECOVERED &&
+-		   err->target == RTAS_TARGET_MEMORY &&
+-		   err->type == RTAS_TYPE_ECC_UNCORR &&
+-		   !(current->pid == 0 || current->pid == 1)) {
+-		/* Kill off a user process with an ECC error */
+-		printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
+-		       current->pid);
+-		/* XXX something better for ECC error? */
+-		_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
+-		nonfatal = 1;
+-	}
+-
+- 	log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal);
+-
+-	return nonfatal;
+-}
+-
+-/*
+- * Handle a machine check.
+- *
+- * Note that on Power 4 and beyond Firmware Non-Maskable Interrupts (fwnmi)
+- * should be present.  If so the handler which called us tells us if the
+- * error was recovered (never true if RI=0).
+- *
+- * On hardware prior to Power 4 these exceptions were asynchronous which
+- * means we can't tell exactly where it occurred and so we can't recover.
+- */
+-int pSeries_machine_check_exception(struct pt_regs *regs)
+-{
+-	struct rtas_error_log *errp;
+-
+-	if (fwnmi_active) {
+-		errp = fwnmi_get_errinfo(regs);
+-		fwnmi_release_errinfo();
+-		if (errp && recover_mce(regs, errp))
+-			return 1;
+-	}
+-
+-	return 0;
+-}
+diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
+--- a/arch/ppc64/kernel/rtas-proc.c
++++ b/arch/ppc64/kernel/rtas-proc.c
+@@ -23,6 +23,7 @@
+ #include <linux/init.h>
+ #include <linux/seq_file.h>
+ #include <linux/bitops.h>
++#include <linux/rtc.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/processor.h>
+diff --git a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/rtas.c
++++ /dev/null
+@@ -1,774 +0,0 @@
+-/*
+- *
+- * Procedures for interfacing to the RTAS on CHRP machines.
+- *
+- * Peter Bergner, IBM	March 2001.
+- * Copyright (C) 2001 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 <stdarg.h>
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-#include <linux/spinlock.h>
+-#include <linux/module.h>
+-#include <linux/init.h>
+-
+-#include <asm/prom.h>
+-#include <asm/rtas.h>
+-#include <asm/semaphore.h>
+-#include <asm/machdep.h>
+-#include <asm/page.h>
+-#include <asm/param.h>
+-#include <asm/system.h>
+-#include <asm/abs_addr.h>
+-#include <asm/udbg.h>
+-#include <asm/delay.h>
+-#include <asm/uaccess.h>
+-#include <asm/systemcfg.h>
+-
+-struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
+-
+-struct rtas_t rtas = { 
+-	.lock = SPIN_LOCK_UNLOCKED
+-};
+-
+-EXPORT_SYMBOL(rtas);
+-
+-char rtas_err_buf[RTAS_ERROR_LOG_MAX];
+-
+-DEFINE_SPINLOCK(rtas_data_buf_lock);
+-char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned;
+-unsigned long rtas_rmo_buf;
+-
+-void
+-call_rtas_display_status(unsigned char c)
+-{
+-	struct rtas_args *args = &rtas.args;
+-	unsigned long s;
+-
+-	if (!rtas.base)
+-		return;
+-	spin_lock_irqsave(&rtas.lock, s);
+-
+-	args->token = 10;
+-	args->nargs = 1;
+-	args->nret  = 1;
+-	args->rets  = (rtas_arg_t *)&(args->args[1]);
+-	args->args[0] = (int)c;
+-
+-	enter_rtas(__pa(args));
+-
+-	spin_unlock_irqrestore(&rtas.lock, s);
+-}
+-
+-void
+-call_rtas_display_status_delay(unsigned char c)
+-{
+-	static int pending_newline = 0;  /* did last write end with unprinted newline? */
+-	static int width = 16;
+-
+-	if (c == '\n') {	
+-		while (width-- > 0)
+-			call_rtas_display_status(' ');
+-		width = 16;
+-		udelay(500000);
+-		pending_newline = 1;
+-	} else {
+-		if (pending_newline) {
+-			call_rtas_display_status('\r');
+-			call_rtas_display_status('\n');
+-		} 
+-		pending_newline = 0;
+-		if (width--) {
+-			call_rtas_display_status(c);
+-			udelay(10000);
+-		}
+-	}
+-}
+-
+-void
+-rtas_progress(char *s, unsigned short hex)
+-{
+-	struct device_node *root;
+-	int width, *p;
+-	char *os;
+-	static int display_character, set_indicator;
+-	static int display_width, display_lines, *row_width, form_feed;
+-	static DEFINE_SPINLOCK(progress_lock);
+-	static int current_line;
+-	static int pending_newline = 0;  /* did last write end with unprinted newline? */
+-
+-	if (!rtas.base)
+-		return;
+-
+-	if (display_width == 0) {
+-		display_width = 0x10;
+-		if ((root = find_path_device("/rtas"))) {
+-			if ((p = (unsigned int *)get_property(root,
+-					"ibm,display-line-length", NULL)))
+-				display_width = *p;
+-			if ((p = (unsigned int *)get_property(root,
+-					"ibm,form-feed", NULL)))
+-				form_feed = *p;
+-			if ((p = (unsigned int *)get_property(root,
+-					"ibm,display-number-of-lines", NULL)))
+-				display_lines = *p;
+-			row_width = (unsigned int *)get_property(root,
+-					"ibm,display-truncation-length", NULL);
+-		}
+-		display_character = rtas_token("display-character");
+-		set_indicator = rtas_token("set-indicator");
+-	}
+-
+-	if (display_character == RTAS_UNKNOWN_SERVICE) {
+-		/* use hex display if available */
+-		if (set_indicator != RTAS_UNKNOWN_SERVICE)
+-			rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
+-		return;
+-	}
+-
+-	spin_lock(&progress_lock);
+-
+-	/*
+-	 * Last write ended with newline, but we didn't print it since
+-	 * it would just clear the bottom line of output. Print it now
+-	 * instead.
+-	 *
+-	 * If no newline is pending and form feed is supported, clear the
+-	 * display with a form feed; otherwise, print a CR to start output
+-	 * at the beginning of the line.
+-	 */
+-	if (pending_newline) {
+-		rtas_call(display_character, 1, 1, NULL, '\r');
+-		rtas_call(display_character, 1, 1, NULL, '\n');
+-		pending_newline = 0;
+-	} else {
+-		current_line = 0;
+-		if (form_feed)
+-			rtas_call(display_character, 1, 1, NULL,
+-				  (char)form_feed);
+-		else
+-			rtas_call(display_character, 1, 1, NULL, '\r');
+-	}
+- 
+-	if (row_width)
+-		width = row_width[current_line];
+-	else
+-		width = display_width;
+-	os = s;
+-	while (*os) {
+-		if (*os == '\n' || *os == '\r') {
+-			/* If newline is the last character, save it
+-			 * until next call to avoid bumping up the
+-			 * display output.
+-			 */
+-			if (*os == '\n' && !os[1]) {
+-				pending_newline = 1;
+-				current_line++;
+-				if (current_line > display_lines-1)
+-					current_line = display_lines-1;
+-				spin_unlock(&progress_lock);
+-				return;
+-			}
+- 
+-			/* RTAS wants CR-LF, not just LF */
+- 
+-			if (*os == '\n') {
+-				rtas_call(display_character, 1, 1, NULL, '\r');
+-				rtas_call(display_character, 1, 1, NULL, '\n');
+-			} else {
+-				/* CR might be used to re-draw a line, so we'll
+-				 * leave it alone and not add LF.
+-				 */
+-				rtas_call(display_character, 1, 1, NULL, *os);
+-			}
+- 
+-			if (row_width)
+-				width = row_width[current_line];
+-			else
+-				width = display_width;
+-		} else {
+-			width--;
+-			rtas_call(display_character, 1, 1, NULL, *os);
+-		}
+- 
+-		os++;
+- 
+-		/* if we overwrite the screen length */
+-		if (width <= 0)
+-			while ((*os != 0) && (*os != '\n') && (*os != '\r'))
+-				os++;
+-	}
+- 
+-	spin_unlock(&progress_lock);
+-}
+-
+-int
+-rtas_token(const char *service)
+-{
+-	int *tokp;
+-	if (rtas.dev == NULL) {
+-		PPCDBG(PPCDBG_RTAS,"\tNo rtas device in device-tree...\n");
+-		return RTAS_UNKNOWN_SERVICE;
+-	}
+-	tokp = (int *) get_property(rtas.dev, service, NULL);
+-	return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
+-}
+-
+-/*
+- * Return the firmware-specified size of the error log buffer
+- *  for all rtas calls that require an error buffer argument.
+- *  This includes 'check-exception' and 'rtas-last-error'.
+- */
+-int rtas_get_error_log_max(void)
+-{
+-	static int rtas_error_log_max;
+-	if (rtas_error_log_max)
+-		return rtas_error_log_max;
+-
+-	rtas_error_log_max = rtas_token ("rtas-error-log-max");
+-	if ((rtas_error_log_max == RTAS_UNKNOWN_SERVICE) ||
+-	    (rtas_error_log_max > RTAS_ERROR_LOG_MAX)) {
+-		printk (KERN_WARNING "RTAS: bad log buffer size %d\n", rtas_error_log_max);
+-		rtas_error_log_max = RTAS_ERROR_LOG_MAX;
+-	}
+-	return rtas_error_log_max;
+-}
+-
+-
+-/** Return a copy of the detailed error text associated with the
+- *  most recent failed call to rtas.  Because the error text
+- *  might go stale if there are any other intervening rtas calls,
+- *  this routine must be called atomically with whatever produced
+- *  the error (i.e. with rtas.lock still held from the previous call).
+- */
+-static int
+-__fetch_rtas_last_error(void)
+-{
+-	struct rtas_args err_args, save_args;
+-	u32 bufsz;
+-
+-	bufsz = rtas_get_error_log_max();
+-
+-	err_args.token = rtas_token("rtas-last-error");
+-	err_args.nargs = 2;
+-	err_args.nret = 1;
+-
+-	err_args.args[0] = (rtas_arg_t)__pa(rtas_err_buf);
+-	err_args.args[1] = bufsz;
+-	err_args.args[2] = 0;
+-
+-	save_args = rtas.args;
+-	rtas.args = err_args;
+-
+-	enter_rtas(__pa(&rtas.args));
+-
+-	err_args = rtas.args;
+-	rtas.args = save_args;
+-
+-	return err_args.args[2];
+-}
+-
+-int rtas_call(int token, int nargs, int nret, int *outputs, ...)
+-{
+-	va_list list;
+-	int i, logit = 0;
+-	unsigned long s;
+-	struct rtas_args *rtas_args;
+-	char * buff_copy = NULL;
+-	int ret;
+-
+-	PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n");
+-	PPCDBG(PPCDBG_RTAS, "\ttoken    = 0x%x\n", token);
+-	PPCDBG(PPCDBG_RTAS, "\tnargs    = %d\n", nargs);
+-	PPCDBG(PPCDBG_RTAS, "\tnret     = %d\n", nret);
+-	PPCDBG(PPCDBG_RTAS, "\t&outputs = 0x%lx\n", outputs);
+-	if (token == RTAS_UNKNOWN_SERVICE)
+-		return -1;
+-
+-	/* Gotta do something different here, use global lock for now... */
+-	spin_lock_irqsave(&rtas.lock, s);
+-	rtas_args = &rtas.args;
+-
+-	rtas_args->token = token;
+-	rtas_args->nargs = nargs;
+-	rtas_args->nret  = nret;
+-	rtas_args->rets  = (rtas_arg_t *)&(rtas_args->args[nargs]);
+-	va_start(list, outputs);
+-	for (i = 0; i < nargs; ++i) {
+-		rtas_args->args[i] = va_arg(list, rtas_arg_t);
+-		PPCDBG(PPCDBG_RTAS, "\tnarg[%d] = 0x%x\n", i, rtas_args->args[i]);
+-	}
+-	va_end(list);
+-
+-	for (i = 0; i < nret; ++i)
+-		rtas_args->rets[i] = 0;
+-
+-	PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n",
+-		__pa(rtas_args));
+-	enter_rtas(__pa(rtas_args));
+-	PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n");
+-
+-	/* A -1 return code indicates that the last command couldn't
+-	   be completed due to a hardware error. */
+-	if (rtas_args->rets[0] == -1)
+-		logit = (__fetch_rtas_last_error() == 0);
+-
+-	ifppcdebug(PPCDBG_RTAS) {
+-		for(i=0; i < nret ;i++)
+-			udbg_printf("\tnret[%d] = 0x%lx\n", i, (ulong)rtas_args->rets[i]);
+-	}
+-
+-	if (nret > 1 && outputs != NULL)
+-		for (i = 0; i < nret-1; ++i)
+-			outputs[i] = rtas_args->rets[i+1];
+-	ret = (nret > 0)? rtas_args->rets[0]: 0;
+-
+-	/* Log the error in the unlikely case that there was one. */
+-	if (unlikely(logit)) {
+-		buff_copy = rtas_err_buf;
+-		if (mem_init_done) {
+-			buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
+-			if (buff_copy)
+-				memcpy(buff_copy, rtas_err_buf,
+-				       RTAS_ERROR_LOG_MAX);
+-		}
+-	}
+-
+-	/* Gotta do something different here, use global lock for now... */
+-	spin_unlock_irqrestore(&rtas.lock, s);
+-
+-	if (buff_copy) {
+-		log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0);
+-		if (mem_init_done)
+-			kfree(buff_copy);
+-	}
+-	return ret;
+-}
+-
+-/* Given an RTAS status code of 990n compute the hinted delay of 10^n
+- * (last digit) milliseconds.  For now we bound at n=5 (100 sec).
+- */
+-unsigned int
+-rtas_extended_busy_delay_time(int status)
+-{
+-	int order = status - 9900;
+-	unsigned long ms;
+-
+-	if (order < 0)
+-		order = 0;	/* RTC depends on this for -2 clock busy */
+-	else if (order > 5)
+-		order = 5;	/* bound */
+-
+-	/* Use microseconds for reasonable accuracy */
+-	for (ms=1; order > 0; order--)
+-		ms *= 10;
+-
+-	return ms; 
+-}
+-
+-int rtas_error_rc(int rtas_rc)
+-{
+-	int rc;
+-
+-	switch (rtas_rc) {
+-		case -1: 		/* Hardware Error */
+-			rc = -EIO;
+-			break;
+-		case -3:		/* Bad indicator/domain/etc */
+-			rc = -EINVAL;
+-			break;
+-		case -9000:		/* Isolation error */
+-			rc = -EFAULT;
+-			break;
+-		case -9001:		/* Outstanding TCE/PTE */
+-			rc = -EEXIST;
+-			break;
+-		case -9002:		/* No usable slot */
+-			rc = -ENODEV;
+-			break;
+-		default:
+-			printk(KERN_ERR "%s: unexpected RTAS error %d\n",
+-					__FUNCTION__, rtas_rc);
+-			rc = -ERANGE;
+-			break;
+-	}
+-	return rc;
+-}
+-
+-int rtas_get_power_level(int powerdomain, int *level)
+-{
+-	int token = rtas_token("get-power-level");
+-	int rc;
+-
+-	if (token == RTAS_UNKNOWN_SERVICE)
+-		return -ENOENT;
+-
+-	while ((rc = rtas_call(token, 1, 2, level, powerdomain)) == RTAS_BUSY)
+-		udelay(1);
+-
+-	if (rc < 0)
+-		return rtas_error_rc(rc);
+-	return rc;
+-}
+-
+-int rtas_set_power_level(int powerdomain, int level, int *setlevel)
+-{
+-	int token = rtas_token("set-power-level");
+-	unsigned int wait_time;
+-	int rc;
+-
+-	if (token == RTAS_UNKNOWN_SERVICE)
+-		return -ENOENT;
+-
+-	while (1) {
+-		rc = rtas_call(token, 2, 2, setlevel, powerdomain, level);
+-		if (rc == RTAS_BUSY)
+-			udelay(1);
+-		else if (rtas_is_extended_busy(rc)) {
+-			wait_time = rtas_extended_busy_delay_time(rc);
+-			udelay(wait_time * 1000);
+-		} else
+-			break;
+-	}
+-
+-	if (rc < 0)
+-		return rtas_error_rc(rc);
+-	return rc;
+-}
+-
+-int rtas_get_sensor(int sensor, int index, int *state)
+-{
+-	int token = rtas_token("get-sensor-state");
+-	unsigned int wait_time;
+-	int rc;
+-
+-	if (token == RTAS_UNKNOWN_SERVICE)
+-		return -ENOENT;
+-
+-	while (1) {
+-		rc = rtas_call(token, 2, 2, state, sensor, index);
+-		if (rc == RTAS_BUSY)
+-			udelay(1);
+-		else if (rtas_is_extended_busy(rc)) {
+-			wait_time = rtas_extended_busy_delay_time(rc);
+-			udelay(wait_time * 1000);
+-		} else
+-			break;
+-	}
+-
+-	if (rc < 0)
+-		return rtas_error_rc(rc);
+-	return rc;
+-}
+-
+-int rtas_set_indicator(int indicator, int index, int new_value)
+-{
+-	int token = rtas_token("set-indicator");
+-	unsigned int wait_time;
+-	int rc;
+-
+-	if (token == RTAS_UNKNOWN_SERVICE)
+-		return -ENOENT;
+-
+-	while (1) {
+-		rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value);
+-		if (rc == RTAS_BUSY)
+-			udelay(1);
+-		else if (rtas_is_extended_busy(rc)) {
+-			wait_time = rtas_extended_busy_delay_time(rc);
+-			udelay(wait_time * 1000);
+-		}
+-		else
+-			break;
+-	}
+-
+-	if (rc < 0)
+-		return rtas_error_rc(rc);
+-	return rc;
+-}
+-
+-#define FLASH_BLOCK_LIST_VERSION (1UL)
+-static void
+-rtas_flash_firmware(void)
+-{
+-	unsigned long image_size;
+-	struct flash_block_list *f, *next, *flist;
+-	unsigned long rtas_block_list;
+-	int i, status, update_token;
+-
+-	update_token = rtas_token("ibm,update-flash-64-and-reboot");
+-	if (update_token == RTAS_UNKNOWN_SERVICE) {
+-		printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n");
+-		printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
+-		return;
+-	}
+-
+-	/* NOTE: the "first" block list is a global var with no data
+-	 * blocks in the kernel data segment.  We do this because
+-	 * we want to ensure this block_list addr is under 4GB.
+-	 */
+-	rtas_firmware_flash_list.num_blocks = 0;
+-	flist = (struct flash_block_list *)&rtas_firmware_flash_list;
+-	rtas_block_list = virt_to_abs(flist);
+-	if (rtas_block_list >= 4UL*1024*1024*1024) {
+-		printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
+-		return;
+-	}
+-
+-	printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
+-	/* Update the block_list in place. */
+-	image_size = 0;
+-	for (f = flist; f; f = next) {
+-		/* Translate data addrs to absolute */
+-		for (i = 0; i < f->num_blocks; i++) {
+-			f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
+-			image_size += f->blocks[i].length;
+-		}
+-		next = f->next;
+-		/* Don't translate NULL pointer for last entry */
+-		if (f->next)
+-			f->next = (struct flash_block_list *)virt_to_abs(f->next);
+-		else
+-			f->next = NULL;
+-		/* make num_blocks into the version/length field */
+-		f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
+-	}
+-
+-	printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
+-	printk(KERN_ALERT "FLASH: performing flash and reboot\n");
+-	rtas_progress("Flashing        \n", 0x0);
+-	rtas_progress("Please Wait...  ", 0x0);
+-	printk(KERN_ALERT "FLASH: this will take several minutes.  Do not power off!\n");
+-	status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
+-	switch (status) {	/* should only get "bad" status */
+-	    case 0:
+-		printk(KERN_ALERT "FLASH: success\n");
+-		break;
+-	    case -1:
+-		printk(KERN_ALERT "FLASH: hardware error.  Firmware may not be not flashed\n");
+-		break;
+-	    case -3:
+-		printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform.  Firmware not flashed\n");
+-		break;
+-	    case -4:
+-		printk(KERN_ALERT "FLASH: flash failed when partially complete.  System may not reboot\n");
+-		break;
+-	    default:
+-		printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
+-		break;
+-	}
+-}
+-
+-void rtas_flash_bypass_warning(void)
+-{
+-	printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
+-	printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
+-}
+-
+-
+-void
+-rtas_restart(char *cmd)
+-{
+-	if (rtas_firmware_flash_list.next)
+-		rtas_flash_firmware();
+-
+-	printk("RTAS system-reboot returned %d\n",
+-	       rtas_call(rtas_token("system-reboot"), 0, 1, NULL));
+-	for (;;);
+-}
+-
+-void
+-rtas_power_off(void)
+-{
+-	if (rtas_firmware_flash_list.next)
+-		rtas_flash_bypass_warning();
+-	/* allow power on only with power button press */
+-	printk("RTAS power-off returned %d\n",
+-	       rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
+-	for (;;);
+-}
+-
+-void
+-rtas_halt(void)
+-{
+-	if (rtas_firmware_flash_list.next)
+-		rtas_flash_bypass_warning();
+-	rtas_power_off();
+-}
+-
+-/* Must be in the RMO region, so we place it here */
+-static char rtas_os_term_buf[2048];
+-
+-void rtas_os_term(char *str)
+-{
+-	int status;
+-
+-	if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
+-		return;
+-
+-	snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
+-
+-	do {
+-		status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
+-				   __pa(rtas_os_term_buf));
+-
+-		if (status == RTAS_BUSY)
+-			udelay(1);
+-		else if (status != 0)
+-			printk(KERN_EMERG "ibm,os-term call failed %d\n",
+-			       status);
+-	} while (status == RTAS_BUSY);
+-}
+-
+-
+-asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
+-{
+-	struct rtas_args args;
+-	unsigned long flags;
+-	char * buff_copy;
+-	int nargs;
+-	int err_rc = 0;
+-
+-	if (!capable(CAP_SYS_ADMIN))
+-		return -EPERM;
+-
+-	if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
+-		return -EFAULT;
+-
+-	nargs = args.nargs;
+-	if (nargs > ARRAY_SIZE(args.args)
+-	    || args.nret > ARRAY_SIZE(args.args)
+-	    || nargs + args.nret > ARRAY_SIZE(args.args))
+-		return -EINVAL;
+-
+-	/* Copy in args. */
+-	if (copy_from_user(args.args, uargs->args,
+-			   nargs * sizeof(rtas_arg_t)) != 0)
+-		return -EFAULT;
+-
+-	buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_KERNEL);
+-
+-	spin_lock_irqsave(&rtas.lock, flags);
+-
+-	rtas.args = args;
+-	enter_rtas(__pa(&rtas.args));
+-	args = rtas.args;
+-
+-	args.rets = &args.args[nargs];
+-
+-	/* A -1 return code indicates that the last command couldn't
+-	   be completed due to a hardware error. */
+-	if (args.rets[0] == -1) {
+-		err_rc = __fetch_rtas_last_error();
+-		if ((err_rc == 0) && buff_copy) {
+-			memcpy(buff_copy, rtas_err_buf, RTAS_ERROR_LOG_MAX);
+-		}
+-	}
+-
+-	spin_unlock_irqrestore(&rtas.lock, flags);
+-
+-	if (buff_copy) {
+-		if ((args.rets[0] == -1) && (err_rc == 0)) {
+-			log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0);
+-		}
+-		kfree(buff_copy);
+-	}
+-
+-	/* Copy out args. */
+-	if (copy_to_user(uargs->args + nargs,
+-			 args.args + nargs,
+-			 args.nret * sizeof(rtas_arg_t)) != 0)
+-		return -EFAULT;
+-
+-	return 0;
+-}
+-
+-/* This version can't take the spinlock, because it never returns */
+-
+-struct rtas_args rtas_stop_self_args = {
+-	/* The token is initialized for real in setup_system() */
+-	.token = RTAS_UNKNOWN_SERVICE,
+-	.nargs = 0,
+-	.nret = 1,
+-	.rets = &rtas_stop_self_args.args[0],
+-};
+-
+-void rtas_stop_self(void)
+-{
+-	struct rtas_args *rtas_args = &rtas_stop_self_args;
+-
+-	local_irq_disable();
+-
+-	BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE);
+-
+-	printk("cpu %u (hwid %u) Ready to die...\n",
+-	       smp_processor_id(), hard_smp_processor_id());
+-	enter_rtas(__pa(rtas_args));
+-
+-	panic("Alas, I survived.\n");
+-}
+-
+-/*
+- * Call early during boot, before mem init or bootmem, to retreive the RTAS
+- * informations from the device-tree and allocate the RMO buffer for userland
+- * accesses.
+- */
+-void __init rtas_initialize(void)
+-{
+-	/* Get RTAS dev node and fill up our "rtas" structure with infos
+-	 * about it.
+-	 */
+-	rtas.dev = of_find_node_by_name(NULL, "rtas");
+-	if (rtas.dev) {
+-		u32 *basep, *entryp;
+-		u32 *sizep;
+-
+-		basep = (u32 *)get_property(rtas.dev, "linux,rtas-base", NULL);
+-		sizep = (u32 *)get_property(rtas.dev, "rtas-size", NULL);
+-		if (basep != NULL && sizep != NULL) {
+-			rtas.base = *basep;
+-			rtas.size = *sizep;
+-			entryp = (u32 *)get_property(rtas.dev, "linux,rtas-entry", NULL);
+-			if (entryp == NULL) /* Ugh */
+-				rtas.entry = rtas.base;
+-			else
+-				rtas.entry = *entryp;
+-		} else
+-			rtas.dev = NULL;
+-	}
+-	/* If RTAS was found, allocate the RMO buffer for it and look for
+-	 * the stop-self token if any
+-	 */
+-	if (rtas.dev) {
+-		unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
+-		if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
+-			rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
+-
+-		rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE,
+-							rtas_region);
+-
+-#ifdef CONFIG_HOTPLUG_CPU
+-		rtas_stop_self_args.token = rtas_token("stop-self");
+-#endif /* CONFIG_HOTPLUG_CPU */
+-	}
+-
+-}
+-
+-
+-EXPORT_SYMBOL(rtas_firmware_flash_list);
+-EXPORT_SYMBOL(rtas_token);
+-EXPORT_SYMBOL(rtas_call);
+-EXPORT_SYMBOL(rtas_data_buf);
+-EXPORT_SYMBOL(rtas_data_buf_lock);
+-EXPORT_SYMBOL(rtas_extended_busy_delay_time);
+-EXPORT_SYMBOL(rtas_get_sensor);
+-EXPORT_SYMBOL(rtas_get_power_level);
+-EXPORT_SYMBOL(rtas_set_power_level);
+-EXPORT_SYMBOL(rtas_set_indicator);
+-EXPORT_SYMBOL(rtas_get_error_log_max);
+diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
+--- a/arch/ppc64/kernel/rtas_pci.c
++++ b/arch/ppc64/kernel/rtas_pci.c
+@@ -38,9 +38,8 @@
+ #include <asm/pci-bridge.h>
+ #include <asm/iommu.h>
+ #include <asm/rtas.h>
+-
+-#include "mpic.h"
+-#include "pci.h"
++#include <asm/mpic.h>
++#include <asm/ppc-pci.h>
+ 
+ /* RTAS tokens */
+ static int read_pci_config;
+@@ -401,7 +400,7 @@ unsigned long __init find_and_init_phbs(
+ 		if (!phb)
+ 			continue;
+ 
+-		pci_process_bridge_OF_ranges(phb, node);
++		pci_process_bridge_OF_ranges(phb, node, 0);
+ 		pci_setup_phb_io(phb, index == 0);
+ #ifdef CONFIG_PPC_PSERIES
+ 		if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
+@@ -451,7 +450,7 @@ struct pci_controller * __devinit init_p
+ 	if (!phb)
+ 		return NULL;
+ 
+-	pci_process_bridge_OF_ranges(phb, dn);
++	pci_process_bridge_OF_ranges(phb, dn, primary);
+ 
+ 	pci_setup_phb_io_dynamic(phb, primary);
+ 	of_node_put(root);
+diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
+--- a/arch/ppc64/kernel/rtc.c
++++ b/arch/ppc64/kernel/rtc.c
+@@ -43,11 +43,8 @@
+ #include <asm/time.h>
+ #include <asm/rtas.h>
+ 
+-#include <asm/iSeries/mf.h>
+ #include <asm/machdep.h>
+ 
+-extern int piranha_simulator;
+-
+ /*
+  *	We sponge a minor off of the misc major. No need slurping
+  *	up another valuable major dev number for this. If you add
+@@ -265,44 +262,10 @@ static int rtc_read_proc(char *page, cha
+         return len;
+ }
+ 
+-#ifdef CONFIG_PPC_ISERIES
+-/*
+- * Get the RTC from the virtual service processor
+- * This requires flowing LpEvents to the primary partition
+- */
+-void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
+-{
+-	if (piranha_simulator)
+-		return;
+-
+-	mf_get_rtc(rtc_tm);
+-	rtc_tm->tm_mon--;
+-}
+-
+-/*
+- * Set the RTC in the virtual service processor
+- * This requires flowing LpEvents to the primary partition
+- */
+-int iSeries_set_rtc_time(struct rtc_time *tm)
+-{
+-	mf_set_rtc(tm);
+-	return 0;
+-}
+-
+-void iSeries_get_boot_time(struct rtc_time *tm)
+-{
+-	if ( piranha_simulator )
+-		return;
+-
+-	mf_get_boot_rtc(tm);
+-	tm->tm_mon  -= 1;
+-}
+-#endif
+-
+ #ifdef CONFIG_PPC_RTAS
+ #define MAX_RTC_WAIT 5000	/* 5 sec */
+ #define RTAS_CLOCK_BUSY (-2)
+-void rtas_get_boot_time(struct rtc_time *rtc_tm)
++unsigned long rtas_get_boot_time(void)
+ {
+ 	int ret[8];
+ 	int error, wait_time;
+@@ -322,15 +285,10 @@ void rtas_get_boot_time(struct rtc_time 
+ 	if (error != 0 && printk_ratelimit()) {
+ 		printk(KERN_WARNING "error: reading the clock failed (%d)\n",
+ 			error);
+-		return;
++		return 0;
+ 	}
+ 
+-	rtc_tm->tm_sec = ret[5];
+-	rtc_tm->tm_min = ret[4];
+-	rtc_tm->tm_hour = ret[3];
+-	rtc_tm->tm_mday = ret[2];
+-	rtc_tm->tm_mon = ret[1] - 1;
+-	rtc_tm->tm_year = ret[0] - 1900;
++	return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
+ }
+ 
+ /* NOTE: get_rtc_time will get an error if executed in interrupt context
+diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/setup.c
++++ /dev/null
+@@ -1,1316 +0,0 @@
+-/*
+- * 
+- * Common boot and setup code.
+- *
+- * Copyright (C) 2001 PPC64 Team, IBM Corp
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the GNU General Public License
+- *      as published by the Free Software Foundation; either version
+- *      2 of the License, or (at your option) any later version.
+- */
+-
+-#undef DEBUG
+-
+-#include <linux/config.h>
+-#include <linux/module.h>
+-#include <linux/string.h>
+-#include <linux/sched.h>
+-#include <linux/init.h>
+-#include <linux/kernel.h>
+-#include <linux/reboot.h>
+-#include <linux/delay.h>
+-#include <linux/initrd.h>
+-#include <linux/ide.h>
+-#include <linux/seq_file.h>
+-#include <linux/ioport.h>
+-#include <linux/console.h>
+-#include <linux/utsname.h>
+-#include <linux/tty.h>
+-#include <linux/root_dev.h>
+-#include <linux/notifier.h>
+-#include <linux/cpu.h>
+-#include <linux/unistd.h>
+-#include <linux/serial.h>
+-#include <linux/serial_8250.h>
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/processor.h>
+-#include <asm/pgtable.h>
+-#include <asm/bootinfo.h>
+-#include <asm/smp.h>
+-#include <asm/elf.h>
+-#include <asm/machdep.h>
+-#include <asm/paca.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/time.h>
+-#include <asm/cputable.h>
+-#include <asm/sections.h>
+-#include <asm/btext.h>
+-#include <asm/nvram.h>
+-#include <asm/setup.h>
+-#include <asm/system.h>
+-#include <asm/rtas.h>
+-#include <asm/iommu.h>
+-#include <asm/serial.h>
+-#include <asm/cache.h>
+-#include <asm/page.h>
+-#include <asm/mmu.h>
+-#include <asm/lmb.h>
+-#include <asm/iSeries/ItLpNaca.h>
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) udbg_printf(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-/*
+- * Here are some early debugging facilities. You can enable one
+- * but your kernel will not boot on anything else if you do so
+- */
+-
+-/* This one is for use on LPAR machines that support an HVC console
+- * on vterm 0
+- */
+-extern void udbg_init_debug_lpar(void);
+-/* This one is for use on Apple G5 machines
+- */
+-extern void udbg_init_pmac_realmode(void);
+-/* That's RTAS panel debug */
+-extern void call_rtas_display_status_delay(unsigned char c);
+-/* Here's maple real mode debug */
+-extern void udbg_init_maple_realmode(void);
+-
+-#define EARLY_DEBUG_INIT() do {} while(0)
+-
+-#if 0
+-#define EARLY_DEBUG_INIT() udbg_init_debug_lpar()
+-#define EARLY_DEBUG_INIT() udbg_init_maple_realmode()
+-#define EARLY_DEBUG_INIT() udbg_init_pmac_realmode()
+-#define EARLY_DEBUG_INIT()						\
+-	do { udbg_putc = call_rtas_display_status_delay; } while(0)
+-#endif
+-
+-/* extern void *stab; */
+-extern unsigned long klimit;
+-
+-extern void mm_init_ppc64(void);
+-extern void stab_initialize(unsigned long stab);
+-extern void htab_initialize(void);
+-extern void early_init_devtree(void *flat_dt);
+-extern void unflatten_device_tree(void);
+-
+-extern void smp_release_cpus(void);
+-
+-int have_of = 1;
+-int boot_cpuid = 0;
+-int boot_cpuid_phys = 0;
+-dev_t boot_dev;
+-u64 ppc64_pft_size;
+-
+-struct ppc64_caches ppc64_caches;
+-EXPORT_SYMBOL_GPL(ppc64_caches);
+-
+-/*
+- * These are used in binfmt_elf.c to put aux entries on the stack
+- * for each elf executable being started.
+- */
+-int dcache_bsize;
+-int icache_bsize;
+-int ucache_bsize;
+-
+-/* The main machine-dep calls structure
+- */
+-struct machdep_calls ppc_md;
+-EXPORT_SYMBOL(ppc_md);
+-
+-#ifdef CONFIG_MAGIC_SYSRQ
+-unsigned long SYSRQ_KEY;
+-#endif /* CONFIG_MAGIC_SYSRQ */
+-
+-
+-static int ppc64_panic_event(struct notifier_block *, unsigned long, void *);
+-static struct notifier_block ppc64_panic_block = {
+-	.notifier_call = ppc64_panic_event,
+-	.priority = INT_MIN /* may not return; must be done last */
+-};
+-
+-/*
+- * Perhaps we can put the pmac screen_info[] here
+- * on pmac as well so we don't need the ifdef's.
+- * Until we get multiple-console support in here
+- * that is.  -- Cort
+- * Maybe tie it to serial consoles, since this is really what
+- * these processors use on existing boards.  -- Dan
+- */ 
+-struct screen_info screen_info = {
+-	.orig_x = 0,
+-	.orig_y = 25,
+-	.orig_video_cols = 80,
+-	.orig_video_lines = 25,
+-	.orig_video_isVGA = 1,
+-	.orig_video_points = 16
+-};
+-
+-#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP)
+-
+-static int smt_enabled_cmdline;
+-
+-/* Look for ibm,smt-enabled OF option */
+-static void check_smt_enabled(void)
+-{
+-	struct device_node *dn;
+-	char *smt_option;
+-
+-	/* Allow the command line to overrule the OF option */
+-	if (smt_enabled_cmdline)
+-		return;
+-
+-	dn = of_find_node_by_path("/options");
+-
+-	if (dn) {
+-		smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL);
+-
+-                if (smt_option) {
+-			if (!strcmp(smt_option, "on"))
+-				smt_enabled_at_boot = 1;
+-			else if (!strcmp(smt_option, "off"))
+-				smt_enabled_at_boot = 0;
+-                }
+-        }
+-}
+-
+-/* Look for smt-enabled= cmdline option */
+-static int __init early_smt_enabled(char *p)
+-{
+-	smt_enabled_cmdline = 1;
+-
+-	if (!p)
+-		return 0;
+-
+-	if (!strcmp(p, "on") || !strcmp(p, "1"))
+-		smt_enabled_at_boot = 1;
+-	else if (!strcmp(p, "off") || !strcmp(p, "0"))
+-		smt_enabled_at_boot = 0;
+-
+-	return 0;
+-}
+-early_param("smt-enabled", early_smt_enabled);
+-
+-/**
+- * setup_cpu_maps - initialize the following cpu maps:
+- *                  cpu_possible_map
+- *                  cpu_present_map
+- *                  cpu_sibling_map
+- *
+- * Having the possible map set up early allows us to restrict allocations
+- * of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
+- *
+- * We do not initialize the online map here; cpus set their own bits in
+- * cpu_online_map as they come up.
+- *
+- * This function is valid only for Open Firmware systems.  finish_device_tree
+- * must be called before using this.
+- *
+- * While we're here, we may as well set the "physical" cpu ids in the paca.
+- */
+-static void __init setup_cpu_maps(void)
+-{
+-	struct device_node *dn = NULL;
+-	int cpu = 0;
+-	int swap_cpuid = 0;
+-
+-	check_smt_enabled();
+-
+-	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
+-		u32 *intserv;
+-		int j, len = sizeof(u32), nthreads;
+-
+-		intserv = (u32 *)get_property(dn, "ibm,ppc-interrupt-server#s",
+-					      &len);
+-		if (!intserv)
+-			intserv = (u32 *)get_property(dn, "reg", NULL);
+-
+-		nthreads = len / sizeof(u32);
+-
+-		for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
+-			cpu_set(cpu, cpu_present_map);
+-			set_hard_smp_processor_id(cpu, intserv[j]);
+-
+-			if (intserv[j] == boot_cpuid_phys)
+-				swap_cpuid = cpu;
+-			cpu_set(cpu, cpu_possible_map);
+-			cpu++;
+-		}
+-	}
+-
+-	/* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
+-	 * boot cpu is logical 0.
+-	 */
+-	if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
+-		u32 tmp;
+-		tmp = get_hard_smp_processor_id(0);
+-		set_hard_smp_processor_id(0, boot_cpuid_phys);
+-		set_hard_smp_processor_id(swap_cpuid, tmp);
+-	}
+-
+-	/*
+-	 * On pSeries LPAR, we need to know how many cpus
+-	 * could possibly be added to this partition.
+-	 */
+-	if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
+-				(dn = of_find_node_by_path("/rtas"))) {
+-		int num_addr_cell, num_size_cell, maxcpus;
+-		unsigned int *ireg;
+-
+-		num_addr_cell = prom_n_addr_cells(dn);
+-		num_size_cell = prom_n_size_cells(dn);
+-
+-		ireg = (unsigned int *)
+-			get_property(dn, "ibm,lrdr-capacity", NULL);
+-
+-		if (!ireg)
+-			goto out;
+-
+-		maxcpus = ireg[num_addr_cell + num_size_cell];
+-
+-		/* Double maxcpus for processors which have SMT capability */
+-		if (cpu_has_feature(CPU_FTR_SMT))
+-			maxcpus *= 2;
+-
+-		if (maxcpus > NR_CPUS) {
+-			printk(KERN_WARNING
+-			       "Partition configured for %d cpus, "
+-			       "operating system maximum is %d.\n",
+-			       maxcpus, NR_CPUS);
+-			maxcpus = NR_CPUS;
+-		} else
+-			printk(KERN_INFO "Partition configured for %d cpus.\n",
+-			       maxcpus);
+-
+-		for (cpu = 0; cpu < maxcpus; cpu++)
+-			cpu_set(cpu, cpu_possible_map);
+-	out:
+-		of_node_put(dn);
+-	}
+-
+-	/*
+-	 * Do the sibling map; assume only two threads per processor.
+-	 */
+-	for_each_cpu(cpu) {
+-		cpu_set(cpu, cpu_sibling_map[cpu]);
+-		if (cpu_has_feature(CPU_FTR_SMT))
+-			cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
+-	}
+-
+-	systemcfg->processorCount = num_present_cpus();
+-}
+-#endif /* defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP) */
+-
+-
+-#ifdef CONFIG_PPC_MULTIPLATFORM
+-
+-extern struct machdep_calls pSeries_md;
+-extern struct machdep_calls pmac_md;
+-extern struct machdep_calls maple_md;
+-extern struct machdep_calls bpa_md;
+-
+-/* Ultimately, stuff them in an elf section like initcalls... */
+-static struct machdep_calls __initdata *machines[] = {
+-#ifdef CONFIG_PPC_PSERIES
+-	&pSeries_md,
+-#endif /* CONFIG_PPC_PSERIES */
+-#ifdef CONFIG_PPC_PMAC
+-	&pmac_md,
+-#endif /* CONFIG_PPC_PMAC */
+-#ifdef CONFIG_PPC_MAPLE
+-	&maple_md,
+-#endif /* CONFIG_PPC_MAPLE */
+-#ifdef CONFIG_PPC_BPA
+-	&bpa_md,
+-#endif
+-	NULL
+-};
+-
+-/*
+- * Early initialization entry point. This is called by head.S
+- * with MMU translation disabled. We rely on the "feature" of
+- * the CPU that ignores the top 2 bits of the address in real
+- * mode so we can access kernel globals normally provided we
+- * only toy with things in the RMO region. From here, we do
+- * some early parsing of the device-tree to setup out LMB
+- * data structures, and allocate & initialize the hash table
+- * and segment tables so we can start running with translation
+- * enabled.
+- *
+- * It is this function which will call the probe() callback of
+- * the various platform types and copy the matching one to the
+- * global ppc_md structure. Your platform can eventually do
+- * some very early initializations from the probe() routine, but
+- * this is not recommended, be very careful as, for example, the
+- * device-tree is not accessible via normal means at this point.
+- */
+-
+-void __init early_setup(unsigned long dt_ptr)
+-{
+-	struct paca_struct *lpaca = get_paca();
+-	static struct machdep_calls **mach;
+-
+-	/*
+-	 * Enable early debugging if any specified (see top of
+-	 * this file)
+-	 */
+-	EARLY_DEBUG_INIT();
+-
+-	DBG(" -> early_setup()\n");
+-
+-	/*
+-	 * Fill the default DBG level (do we want to keep
+-	 * that old mecanism around forever ?)
+-	 */
+-	ppcdbg_initialize();
+-
+-	/*
+-	 * Do early initializations using the flattened device
+-	 * tree, like retreiving the physical memory map or
+-	 * calculating/retreiving the hash table size
+-	 */
+-	early_init_devtree(__va(dt_ptr));
+-
+-	/*
+-	 * Iterate all ppc_md structures until we find the proper
+-	 * one for the current machine type
+-	 */
+-	DBG("Probing machine type for platform %x...\n",
+-	    systemcfg->platform);
+-
+-	for (mach = machines; *mach; mach++) {
+-		if ((*mach)->probe(systemcfg->platform))
+-			break;
+-	}
+-	/* What can we do if we didn't find ? */
+-	if (*mach == NULL) {
+-		DBG("No suitable machine found !\n");
+-		for (;;);
+-	}
+-	ppc_md = **mach;
+-
+-	DBG("Found, Initializing memory management...\n");
+-
+-	/*
+-	 * Initialize stab / SLB management
+-	 */
+-	stab_initialize(lpaca->stab_real);
+-
+-	/*
+-	 * Initialize the MMU Hash table and create the linear mapping
+-	 * of memory
+-	 */
+-	htab_initialize();
+-
+-	DBG(" <- early_setup()\n");
+-}
+-
+-
+-/*
+- * Initialize some remaining members of the ppc64_caches and systemcfg structures
+- * (at least until we get rid of them completely). This is mostly some
+- * cache informations about the CPU that will be used by cache flush
+- * routines and/or provided to userland
+- */
+-static void __init initialize_cache_info(void)
+-{
+-	struct device_node *np;
+-	unsigned long num_cpus = 0;
+-
+-	DBG(" -> initialize_cache_info()\n");
+-
+-	for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) {
+-		num_cpus += 1;
+-
+-		/* We're assuming *all* of the CPUs have the same
+-		 * d-cache and i-cache sizes... -Peter
+-		 */
+-
+-		if ( num_cpus == 1 ) {
+-			u32 *sizep, *lsizep;
+-			u32 size, lsize;
+-			const char *dc, *ic;
+-
+-			/* Then read cache informations */
+-			if (systemcfg->platform == PLATFORM_POWERMAC) {
+-				dc = "d-cache-block-size";
+-				ic = "i-cache-block-size";
+-			} else {
+-				dc = "d-cache-line-size";
+-				ic = "i-cache-line-size";
+-			}
+-
+-			size = 0;
+-			lsize = cur_cpu_spec->dcache_bsize;
+-			sizep = (u32 *)get_property(np, "d-cache-size", NULL);
+-			if (sizep != NULL)
+-				size = *sizep;
+-			lsizep = (u32 *) get_property(np, dc, NULL);
+-			if (lsizep != NULL)
+-				lsize = *lsizep;
+-			if (sizep == 0 || lsizep == 0)
+-				DBG("Argh, can't find dcache properties ! "
+-				    "sizep: %p, lsizep: %p\n", sizep, lsizep);
+-
+-			systemcfg->dcache_size = ppc64_caches.dsize = size;
+-			systemcfg->dcache_line_size =
+-				ppc64_caches.dline_size = lsize;
+-			ppc64_caches.log_dline_size = __ilog2(lsize);
+-			ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
+-
+-			size = 0;
+-			lsize = cur_cpu_spec->icache_bsize;
+-			sizep = (u32 *)get_property(np, "i-cache-size", NULL);
+-			if (sizep != NULL)
+-				size = *sizep;
+-			lsizep = (u32 *)get_property(np, ic, NULL);
+-			if (lsizep != NULL)
+-				lsize = *lsizep;
+-			if (sizep == 0 || lsizep == 0)
+-				DBG("Argh, can't find icache properties ! "
+-				    "sizep: %p, lsizep: %p\n", sizep, lsizep);
+-
+-			systemcfg->icache_size = ppc64_caches.isize = size;
+-			systemcfg->icache_line_size =
+-				ppc64_caches.iline_size = lsize;
+-			ppc64_caches.log_iline_size = __ilog2(lsize);
+-			ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
+-		}
+-	}
+-
+-	/* Add an eye catcher and the systemcfg layout version number */
+-	strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
+-	systemcfg->version.major = SYSTEMCFG_MAJOR;
+-	systemcfg->version.minor = SYSTEMCFG_MINOR;
+-	systemcfg->processor = mfspr(SPRN_PVR);
+-
+-	DBG(" <- initialize_cache_info()\n");
+-}
+-
+-static void __init check_for_initrd(void)
+-{
+-#ifdef CONFIG_BLK_DEV_INITRD
+-	u64 *prop;
+-
+-	DBG(" -> check_for_initrd()\n");
+-
+-	if (of_chosen) {
+-		prop = (u64 *)get_property(of_chosen,
+-				"linux,initrd-start", NULL);
+-		if (prop != NULL) {
+-			initrd_start = (unsigned long)__va(*prop);
+-			prop = (u64 *)get_property(of_chosen,
+-					"linux,initrd-end", NULL);
+-			if (prop != NULL) {
+-				initrd_end = (unsigned long)__va(*prop);
+-				initrd_below_start_ok = 1;
+-			} else
+-				initrd_start = 0;
+-		}
+-	}
+-
+-	/* If we were passed an initrd, set the ROOT_DEV properly if the values
+-	 * look sensible. If not, clear initrd reference.
+-	 */
+-	if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
+-	    initrd_end > initrd_start)
+-		ROOT_DEV = Root_RAM0;
+-	else
+-		initrd_start = initrd_end = 0;
+-
+-	if (initrd_start)
+-		printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end);
+-
+-	DBG(" <- check_for_initrd()\n");
+-#endif /* CONFIG_BLK_DEV_INITRD */
+-}
+-
+-#endif /* CONFIG_PPC_MULTIPLATFORM */
+-
+-/*
+- * Do some initial setup of the system.  The parameters are those which 
+- * were passed in from the bootloader.
+- */
+-void __init setup_system(void)
+-{
+-	DBG(" -> setup_system()\n");
+-
+-#ifdef CONFIG_PPC_ISERIES
+-	/* pSeries systems are identified in prom.c via OF. */
+-	if (itLpNaca.xLparInstalled == 1)
+-		systemcfg->platform = PLATFORM_ISERIES_LPAR;
+-
+-	ppc_md.init_early();
+-#else /* CONFIG_PPC_ISERIES */
+-
+-	/*
+-	 * Unflatten the device-tree passed by prom_init or kexec
+-	 */
+-	unflatten_device_tree();
+-
+-	/*
+-	 * Fill the ppc64_caches & systemcfg structures with informations
+-	 * retreived from the device-tree. Need to be called before
+-	 * finish_device_tree() since the later requires some of the
+-	 * informations filled up here to properly parse the interrupt
+-	 * tree.
+-	 * It also sets up the cache line sizes which allows to call
+-	 * routines like flush_icache_range (used by the hash init
+-	 * later on).
+-	 */
+-	initialize_cache_info();
+-
+-#ifdef CONFIG_PPC_RTAS
+-	/*
+-	 * Initialize RTAS if available
+-	 */
+-	rtas_initialize();
+-#endif /* CONFIG_PPC_RTAS */
+-
+-	/*
+-	 * Check if we have an initrd provided via the device-tree
+-	 */
+-	check_for_initrd();
+-
+-	/*
+-	 * Do some platform specific early initializations, that includes
+-	 * setting up the hash table pointers. It also sets up some interrupt-mapping
+-	 * related options that will be used by finish_device_tree()
+-	 */
+-	ppc_md.init_early();
+-
+-	/*
+-	 * "Finish" the device-tree, that is do the actual parsing of
+-	 * some of the properties like the interrupt map
+-	 */
+-	finish_device_tree();
+-
+-	/*
+-	 * Initialize xmon
+-	 */
+-#ifdef CONFIG_XMON_DEFAULT
+-	xmon_init(1);
+-#endif
+-	/*
+-	 * Register early console
+-	 */
+-	register_early_udbg_console();
+-
+-	/* Save unparsed command line copy for /proc/cmdline */
+-	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
+-
+-	parse_early_param();
+-#endif /* !CONFIG_PPC_ISERIES */
+-
+-#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)
+-	/*
+-	 * iSeries has already initialized the cpu maps at this point.
+-	 */
+-	setup_cpu_maps();
+-
+-	/* Release secondary cpus out of their spinloops at 0x60 now that
+-	 * we can map physical -> logical CPU ids
+-	 */
+-	smp_release_cpus();
+-#endif /* defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) */
+-
+-	printk("Starting Linux PPC64 %s\n", system_utsname.version);
+-
+-	printk("-----------------------------------------------------\n");
+-	printk("ppc64_pft_size                = 0x%lx\n", ppc64_pft_size);
+-	printk("ppc64_debug_switch            = 0x%lx\n", ppc64_debug_switch);
+-	printk("ppc64_interrupt_controller    = 0x%ld\n", ppc64_interrupt_controller);
+-	printk("systemcfg                     = 0x%p\n", systemcfg);
+-	printk("systemcfg->platform           = 0x%x\n", systemcfg->platform);
+-	printk("systemcfg->processorCount     = 0x%lx\n", systemcfg->processorCount);
+-	printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
+-	printk("ppc64_caches.dcache_line_size = 0x%x\n",
+-			ppc64_caches.dline_size);
+-	printk("ppc64_caches.icache_line_size = 0x%x\n",
+-			ppc64_caches.iline_size);
+-	printk("htab_address                  = 0x%p\n", htab_address);
+-	printk("htab_hash_mask                = 0x%lx\n", htab_hash_mask);
+-	printk("-----------------------------------------------------\n");
+-
+-	mm_init_ppc64();
+-
+-	DBG(" <- setup_system()\n");
+-}
+-
+-/* also used by kexec */
+-void machine_shutdown(void)
+-{
+-	if (ppc_md.nvram_sync)
+-		ppc_md.nvram_sync();
+-}
+-
+-void machine_restart(char *cmd)
+-{
+-	machine_shutdown();
+-	ppc_md.restart(cmd);
+-#ifdef CONFIG_SMP
+-	smp_send_stop();
+-#endif
+-	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+-	local_irq_disable();
+-	while (1) ;
+-}
+-
+-void machine_power_off(void)
+-{
+-	machine_shutdown();
+-	ppc_md.power_off();
+-#ifdef CONFIG_SMP
+-	smp_send_stop();
+-#endif
+-	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+-	local_irq_disable();
+-	while (1) ;
+-}
+-/* Used by the G5 thermal driver */
+-EXPORT_SYMBOL_GPL(machine_power_off);
+-
+-void machine_halt(void)
+-{
+-	machine_shutdown();
+-	ppc_md.halt();
+-#ifdef CONFIG_SMP
+-	smp_send_stop();
+-#endif
+-	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+-	local_irq_disable();
+-	while (1) ;
+-}
+-
+-static int ppc64_panic_event(struct notifier_block *this,
+-                             unsigned long event, void *ptr)
+-{
+-	ppc_md.panic((char *)ptr);  /* May not return */
+-	return NOTIFY_DONE;
+-}
+-
+-
+-#ifdef CONFIG_SMP
+-DEFINE_PER_CPU(unsigned int, pvr);
+-#endif
+-
+-static int show_cpuinfo(struct seq_file *m, void *v)
+-{
+-	unsigned long cpu_id = (unsigned long)v - 1;
+-	unsigned int pvr;
+-	unsigned short maj;
+-	unsigned short min;
+-
+-	if (cpu_id == NR_CPUS) {
+-		seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
+-
+-		if (ppc_md.get_cpuinfo != NULL)
+-			ppc_md.get_cpuinfo(m);
+-
+-		return 0;
+-	}
+-
+-	/* We only show online cpus: disable preempt (overzealous, I
+-	 * knew) to prevent cpu going down. */
+-	preempt_disable();
+-	if (!cpu_online(cpu_id)) {
+-		preempt_enable();
+-		return 0;
+-	}
+-
+-#ifdef CONFIG_SMP
+-	pvr = per_cpu(pvr, cpu_id);
+-#else
+-	pvr = mfspr(SPRN_PVR);
+-#endif
+-	maj = (pvr >> 8) & 0xFF;
+-	min = pvr & 0xFF;
+-
+-	seq_printf(m, "processor\t: %lu\n", cpu_id);
+-	seq_printf(m, "cpu\t\t: ");
+-
+-	if (cur_cpu_spec->pvr_mask)
+-		seq_printf(m, "%s", cur_cpu_spec->cpu_name);
+-	else
+-		seq_printf(m, "unknown (%08x)", pvr);
+-
+-#ifdef CONFIG_ALTIVEC
+-	if (cpu_has_feature(CPU_FTR_ALTIVEC))
+-		seq_printf(m, ", altivec supported");
+-#endif /* CONFIG_ALTIVEC */
+-
+-	seq_printf(m, "\n");
+-
+-	/*
+-	 * Assume here that all clock rates are the same in a
+-	 * smp system.  -- Cort
+-	 */
+-	seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000,
+-		   ppc_proc_freq % 1000000);
+-
+-	seq_printf(m, "revision\t: %hd.%hd\n\n", maj, min);
+-
+-	preempt_enable();
+-	return 0;
+-}
+-
+-static void *c_start(struct seq_file *m, loff_t *pos)
+-{
+-	return *pos <= NR_CPUS ? (void *)((*pos)+1) : NULL;
+-}
+-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+-{
+-	++*pos;
+-	return c_start(m, pos);
+-}
+-static void c_stop(struct seq_file *m, void *v)
+-{
+-}
+-struct seq_operations cpuinfo_op = {
+-	.start =c_start,
+-	.next =	c_next,
+-	.stop =	c_stop,
+-	.show =	show_cpuinfo,
+-};
+-
+-/*
+- * These three variables are used to save values passed to us by prom_init()
+- * via the device tree. The TCE variables are needed because with a memory_limit
+- * in force we may need to explicitly map the TCE are at the top of RAM.
+- */
+-unsigned long memory_limit;
+-unsigned long tce_alloc_start;
+-unsigned long tce_alloc_end;
+-
+-#ifdef CONFIG_PPC_ISERIES
+-/*
+- * On iSeries we just parse the mem=X option from the command line.
+- * On pSeries it's a bit more complicated, see prom_init_mem()
+- */
+-static int __init early_parsemem(char *p)
+-{
+-	if (!p)
+-		return 0;
+-
+-	memory_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
+-
+-	return 0;
+-}
+-early_param("mem", early_parsemem);
+-#endif /* CONFIG_PPC_ISERIES */
+-
+-#ifdef CONFIG_PPC_MULTIPLATFORM
+-static int __init set_preferred_console(void)
+-{
+-	struct device_node *prom_stdout = NULL;
+-	char *name;
+-	u32 *spd;
+-	int offset = 0;
+-
+-	DBG(" -> set_preferred_console()\n");
+-
+-	/* The user has requested a console so this is already set up. */
+-	if (strstr(saved_command_line, "console=")) {
+-		DBG(" console was specified !\n");
+-		return -EBUSY;
+-	}
+-
+-	if (!of_chosen) {
+-		DBG(" of_chosen is NULL !\n");
+-		return -ENODEV;
+-	}
+-	/* We are getting a weird phandle from OF ... */
+-	/* ... So use the full path instead */
+-	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+-	if (name == NULL) {
+-		DBG(" no linux,stdout-path !\n");
+-		return -ENODEV;
+-	}
+-	prom_stdout = of_find_node_by_path(name);
+-	if (!prom_stdout) {
+-		DBG(" can't find stdout package %s !\n", name);
+-		return -ENODEV;
+-	}	
+-	DBG("stdout is %s\n", prom_stdout->full_name);
+-
+-	name = (char *)get_property(prom_stdout, "name", NULL);
+-	if (!name) {
+-		DBG(" stdout package has no name !\n");
+-		goto not_found;
+-	}
+-	spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
+-
+-	if (0)
+-		;
+-#ifdef CONFIG_SERIAL_8250_CONSOLE
+-	else if (strcmp(name, "serial") == 0) {
+-		int i;
+-		u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
+-		if (i > 8) {
+-			switch (reg[1]) {
+-				case 0x3f8:
+-					offset = 0;
+-					break;
+-				case 0x2f8:
+-					offset = 1;
+-					break;
+-				case 0x898:
+-					offset = 2;
+-					break;
+-				case 0x890:
+-					offset = 3;
+-					break;
+-				default:
+-					/* We dont recognise the serial port */
+-					goto not_found;
+-			}
+-		}
+-	}
+-#endif /* CONFIG_SERIAL_8250_CONSOLE */
+-#ifdef CONFIG_PPC_PSERIES
+-	else if (strcmp(name, "vty") == 0) {
+- 		u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
+- 		char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
+-
+- 		if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
+- 			/* Host Virtual Serial Interface */
+- 			int offset;
+- 			switch (reg[0]) {
+- 				case 0x30000000:
+- 					offset = 0;
+- 					break;
+- 				case 0x30000001:
+- 					offset = 1;
+- 					break;
+- 				default:
+-					goto not_found;
+- 			}
+-			of_node_put(prom_stdout);
+-			DBG("Found hvsi console at offset %d\n", offset);
+- 			return add_preferred_console("hvsi", offset, NULL);
+- 		} else {
+- 			/* pSeries LPAR virtual console */
+-			of_node_put(prom_stdout);
+-			DBG("Found hvc console\n");
+- 			return add_preferred_console("hvc", 0, NULL);
+- 		}
+-	}
+-#endif /* CONFIG_PPC_PSERIES */
+-#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
+-	else if (strcmp(name, "ch-a") == 0)
+-		offset = 0;
+-	else if (strcmp(name, "ch-b") == 0)
+-		offset = 1;
+-#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
+-	else
+-		goto not_found;
+-	of_node_put(prom_stdout);
+-
+-	DBG("Found serial console at ttyS%d\n", offset);
+-
+-	if (spd) {
+-		static char __initdata opt[16];
+-		sprintf(opt, "%d", *spd);
+-		return add_preferred_console("ttyS", offset, opt);
+-	} else
+-		return add_preferred_console("ttyS", offset, NULL);
+-
+- not_found:
+-	DBG("No preferred console found !\n");
+-	of_node_put(prom_stdout);
+-	return -ENODEV;
+-}
+-console_initcall(set_preferred_console);
+-#endif /* CONFIG_PPC_MULTIPLATFORM */
+-
+-#ifdef CONFIG_IRQSTACKS
+-static void __init irqstack_early_init(void)
+-{
+-	unsigned int i;
+-
+-	/*
+-	 * interrupt stacks must be under 256MB, we cannot afford to take
+-	 * SLB misses on them.
+-	 */
+-	for_each_cpu(i) {
+-		softirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
+-					THREAD_SIZE, 0x10000000));
+-		hardirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
+-					THREAD_SIZE, 0x10000000));
+-	}
+-}
+-#else
+-#define irqstack_early_init()
+-#endif
+-
+-/*
+- * Stack space used when we detect a bad kernel stack pointer, and
+- * early in SMP boots before relocation is enabled.
+- */
+-static void __init emergency_stack_init(void)
+-{
+-	unsigned long limit;
+-	unsigned int i;
+-
+-	/*
+-	 * Emergency stacks must be under 256MB, we cannot afford to take
+-	 * SLB misses on them. The ABI also requires them to be 128-byte
+-	 * aligned.
+-	 *
+-	 * Since we use these as temporary stacks during secondary CPU
+-	 * bringup, we need to get at them in real mode. This means they
+-	 * must also be within the RMO region.
+-	 */
+-	limit = min(0x10000000UL, lmb.rmo_size);
+-
+-	for_each_cpu(i)
+-		paca[i].emergency_sp = __va(lmb_alloc_base(PAGE_SIZE, 128,
+-						limit)) + PAGE_SIZE;
+-}
+-
+-/*
+- * Called from setup_arch to initialize the bitmap of available
+- * syscalls in the systemcfg page
+- */
+-void __init setup_syscall_map(void)
+-{
+-	unsigned int i, count64 = 0, count32 = 0;
+-	extern unsigned long *sys_call_table;
+-	extern unsigned long *sys_call_table32;
+-	extern unsigned long sys_ni_syscall;
+-
+-
+-	for (i = 0; i < __NR_syscalls; i++) {
+-		if (sys_call_table[i] == sys_ni_syscall)
+-			continue;
+-		count64++;
+-		systemcfg->syscall_map_64[i >> 5] |= 0x80000000UL >> (i & 0x1f);
+-	}
+-	for (i = 0; i < __NR_syscalls; i++) {
+-		if (sys_call_table32[i] == sys_ni_syscall)
+-			continue;
+-		count32++;
+-		systemcfg->syscall_map_32[i >> 5] |= 0x80000000UL >> (i & 0x1f);
+-	}
+-	printk(KERN_INFO "Syscall map setup, %d 32 bits and %d 64 bits syscalls\n",
+-	       count32, count64);
+-}
+-
+-/*
+- * Called into from start_kernel, after lock_kernel has been called.
+- * Initializes bootmem, which is unsed to manage page allocation until
+- * mem_init is called.
+- */
+-void __init setup_arch(char **cmdline_p)
+-{
+-	extern void do_init_bootmem(void);
+-
+-	ppc64_boot_msg(0x12, "Setup Arch");
+-
+-	*cmdline_p = cmd_line;
+-
+-	/*
+-	 * Set cache line size based on type of cpu as a default.
+-	 * Systems with OF can look in the properties on the cpu node(s)
+-	 * for a possibly more accurate value.
+-	 */
+-	dcache_bsize = ppc64_caches.dline_size;
+-	icache_bsize = ppc64_caches.iline_size;
+-
+-	/* reboot on panic */
+-	panic_timeout = 180;
+-
+-	if (ppc_md.panic)
+-		notifier_chain_register(&panic_notifier_list, &ppc64_panic_block);
+-
+-	init_mm.start_code = PAGE_OFFSET;
+-	init_mm.end_code = (unsigned long) _etext;
+-	init_mm.end_data = (unsigned long) _edata;
+-	init_mm.brk = klimit;
+-	
+-	irqstack_early_init();
+-	emergency_stack_init();
+-
+-	stabs_alloc();
+-
+-	/* set up the bootmem stuff with available memory */
+-	do_init_bootmem();
+-	sparse_init();
+-
+-	/* initialize the syscall map in systemcfg */
+-	setup_syscall_map();
+-
+-	ppc_md.setup_arch();
+-
+-	/* Use the default idle loop if the platform hasn't provided one. */
+-	if (NULL == ppc_md.idle_loop) {
+-		ppc_md.idle_loop = default_idle;
+-		printk(KERN_INFO "Using default idle loop\n");
+-	}
+-
+-	paging_init();
+-	ppc64_boot_msg(0x15, "Setup Done");
+-}
+-
+-
+-/* ToDo: do something useful if ppc_md is not yet setup. */
+-#define PPC64_LINUX_FUNCTION 0x0f000000
+-#define PPC64_IPL_MESSAGE 0xc0000000
+-#define PPC64_TERM_MESSAGE 0xb0000000
+-
+-static void ppc64_do_msg(unsigned int src, const char *msg)
+-{
+-	if (ppc_md.progress) {
+-		char buf[128];
+-
+-		sprintf(buf, "%08X\n", src);
+-		ppc_md.progress(buf, 0);
+-		snprintf(buf, 128, "%s", msg);
+-		ppc_md.progress(buf, 0);
+-	}
+-}
+-
+-/* Print a boot progress message. */
+-void ppc64_boot_msg(unsigned int src, const char *msg)
+-{
+-	ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg);
+-	printk("[boot]%04x %s\n", src, msg);
+-}
+-
+-/* Print a termination message (print only -- does not stop the kernel) */
+-void ppc64_terminate_msg(unsigned int src, const char *msg)
+-{
+-	ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg);
+-	printk("[terminate]%04x %s\n", src, msg);
+-}
+-
+-/* This should only be called on processor 0 during calibrate decr */
+-void __init setup_default_decr(void)
+-{
+-	struct paca_struct *lpaca = get_paca();
+-
+-	lpaca->default_decr = tb_ticks_per_jiffy;
+-	lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
+-}
+-
+-#ifndef CONFIG_PPC_ISERIES
+-/*
+- * This function can be used by platforms to "find" legacy serial ports.
+- * It works for "serial" nodes under an "isa" node, and will try to
+- * respect the "ibm,aix-loc" property if any. It works with up to 8
+- * ports.
+- */
+-
+-#define MAX_LEGACY_SERIAL_PORTS	8
+-static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
+-static unsigned int old_serial_count;
+-
+-void __init generic_find_legacy_serial_ports(u64 *physport,
+-		unsigned int *default_speed)
+-{
+-	struct device_node *np;
+-	u32 *sizeprop;
+-
+-	struct isa_reg_property {
+-		u32 space;
+-		u32 address;
+-		u32 size;
+-	};
+-	struct pci_reg_property {
+-		struct pci_address addr;
+-		u32 size_hi;
+-		u32 size_lo;
+-	};                                                                        
+-
+-	DBG(" -> generic_find_legacy_serial_port()\n");
+-
+-	*physport = 0;
+-	if (default_speed)
+-		*default_speed = 0;
+-
+-	np = of_find_node_by_path("/");
+-	if (!np)
+-		return;
+-
+-	/* First fill our array */
+-	for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
+-		struct device_node *isa, *pci;
+-		struct isa_reg_property *reg;
+-		unsigned long phys_size, addr_size, io_base;
+-		u32 *rangesp;
+-		u32 *interrupts, *clk, *spd;
+-		char *typep;
+-		int index, rlen, rentsize;
+-
+-		/* Ok, first check if it's under an "isa" parent */
+-		isa = of_get_parent(np);
+-		if (!isa || strcmp(isa->name, "isa")) {
+-			DBG("%s: no isa parent found\n", np->full_name);
+-			continue;
+-		}
+-		
+-		/* Now look for an "ibm,aix-loc" property that gives us ordering
+-		 * if any...
+-		 */
+-	 	typep = (char *)get_property(np, "ibm,aix-loc", NULL);
+-
+-		/* Get the ISA port number */
+-		reg = (struct isa_reg_property *)get_property(np, "reg", NULL);	
+-		if (reg == NULL)
+-			goto next_port;
+-		/* We assume the interrupt number isn't translated ... */
+-		interrupts = (u32 *)get_property(np, "interrupts", NULL);
+-		/* get clock freq. if present */
+-		clk = (u32 *)get_property(np, "clock-frequency", NULL);
+-		/* get default speed if present */
+-		spd = (u32 *)get_property(np, "current-speed", NULL);
+-		/* Default to locate at end of array */
+-		index = old_serial_count; /* end of the array by default */
+-
+-		/* If we have a location index, then use it */
+-		if (typep && *typep == 'S') {
+-			index = simple_strtol(typep+1, NULL, 0) - 1;
+-			/* if index is out of range, use end of array instead */
+-			if (index >= MAX_LEGACY_SERIAL_PORTS)
+-				index = old_serial_count;
+-			/* if our index is still out of range, that mean that
+-			 * array is full, we could scan for a free slot but that
+-			 * make little sense to bother, just skip the port
+-			 */
+-			if (index >= MAX_LEGACY_SERIAL_PORTS)
+-				goto next_port;
+-			if (index >= old_serial_count)
+-				old_serial_count = index + 1;
+-			/* Check if there is a port who already claimed our slot */
+-			if (serial_ports[index].iobase != 0) {
+-				/* if we still have some room, move it, else override */
+-				if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
+-					DBG("Moved legacy port %d -> %d\n", index,
+-					    old_serial_count);
+-					serial_ports[old_serial_count++] =
+-						serial_ports[index];
+-				} else {
+-					DBG("Replacing legacy port %d\n", index);
+-				}
+-			}
+-		}
+-		if (index >= MAX_LEGACY_SERIAL_PORTS)
+-			goto next_port;
+-		if (index >= old_serial_count)
+-			old_serial_count = index + 1;
+-
+-		/* Now fill the entry */
+-		memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port));
+-		serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16;
+-		serial_ports[index].iobase = reg->address;
+-		serial_ports[index].irq = interrupts ? interrupts[0] : 0;
+-		serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
+-
+-		DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
+-		    index,
+-		    serial_ports[index].iobase,
+-		    serial_ports[index].irq,
+-		    serial_ports[index].uartclk);
+-
+-		/* Get phys address of IO reg for port 1 */
+-		if (index != 0)
+-			goto next_port;
+-
+-		pci = of_get_parent(isa);
+-		if (!pci) {
+-			DBG("%s: no pci parent found\n", np->full_name);
+-			goto next_port;
+-		}
+-
+-		rangesp = (u32 *)get_property(pci, "ranges", &rlen);
+-		if (rangesp == NULL) {
+-			of_node_put(pci);
+-			goto next_port;
+-		}
+-		rlen /= 4;
+-
+-		/* we need the #size-cells of the PCI bridge node itself */
+-		phys_size = 1;
+-		sizeprop = (u32 *)get_property(pci, "#size-cells", NULL);
+-		if (sizeprop != NULL)
+-			phys_size = *sizeprop;
+-		/* we need the parent #addr-cells */
+-		addr_size = prom_n_addr_cells(pci);
+-		rentsize = 3 + addr_size + phys_size;
+-		io_base = 0;
+-		for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) {
+-			if (((rangesp[0] >> 24) & 0x3) != 1)
+-				continue; /* not IO space */
+-			io_base = rangesp[3];
+-			if (addr_size == 2)
+-				io_base = (io_base << 32) | rangesp[4];
+-		}
+-		if (io_base != 0) {
+-			*physport = io_base + reg->address;
+-			if (default_speed && spd)
+-				*default_speed = *spd;
+-		}
+-		of_node_put(pci);
+-	next_port:
+-		of_node_put(isa);
+-	}
+-
+-	DBG(" <- generic_find_legacy_serial_port()\n");
+-}
+-
+-static struct platform_device serial_device = {
+-	.name	= "serial8250",
+-	.id	= PLAT8250_DEV_PLATFORM,
+-	.dev	= {
+-		.platform_data = serial_ports,
+-	},
+-};
+-
+-static int __init serial_dev_init(void)
+-{
+-	return platform_device_register(&serial_device);
+-}
+-arch_initcall(serial_dev_init);
+-
+-#endif /* CONFIG_PPC_ISERIES */
+-
+-int check_legacy_ioport(unsigned long base_port)
+-{
+-	if (ppc_md.check_legacy_ioport == NULL)
+-		return 0;
+-	return ppc_md.check_legacy_ioport(base_port);
+-}
+-EXPORT_SYMBOL(check_legacy_ioport);
+-
+-#ifdef CONFIG_XMON
+-static int __init early_xmon(char *p)
+-{
+-	/* ensure xmon is enabled */
+-	if (p) {
+-		if (strncmp(p, "on", 2) == 0)
+-			xmon_init(1);
+-		if (strncmp(p, "off", 3) == 0)
+-			xmon_init(0);
+-		if (strncmp(p, "early", 5) != 0)
+-			return 0;
+-	}
+-	xmon_init(1);
+-	debugger(NULL);
+-
+-	return 0;
+-}
+-early_param("xmon", early_xmon);
+-#endif
+-
+-void cpu_die(void)
+-{
+-	if (ppc_md.cpu_die)
+-		ppc_md.cpu_die();
+-}
+diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
+--- a/arch/ppc64/kernel/signal.c
++++ b/arch/ppc64/kernel/signal.c
+@@ -133,7 +133,7 @@ static long setup_sigcontext(struct sigc
+ 	flush_fp_to_thread(current);
+ 
+ 	/* Make sure signal doesn't get spurrious FP exceptions */
+-	current->thread.fpscr = 0;
++	current->thread.fpscr.val = 0;
+ 
+ #ifdef CONFIG_ALTIVEC
+ 	err |= __put_user(v_regs, &sc->v_regs);
+diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/signal32.c
++++ /dev/null
+@@ -1,998 +0,0 @@
+-/*
+- * signal32.c: Support 32bit signal syscalls.
+- *
+- * Copyright (C) 2001 IBM
+- * Copyright (C) 1997,1998 Jakub Jelinek (jj at sunsite.mff.cuni.cz)
+- * Copyright (C) 1997 David S. Miller (davem at caip.rutgers.edu)
+- *
+- * These routines maintain argument size conversion between 32bit and 64bit
+- * environment.
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/sched.h>
+-#include <linux/mm.h> 
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/kernel.h>
+-#include <linux/signal.h>
+-#include <linux/syscalls.h>
+-#include <linux/errno.h>
+-#include <linux/elf.h>
+-#include <linux/compat.h>
+-#include <linux/ptrace.h>
+-#include <asm/ppc32.h>
+-#include <asm/uaccess.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/unistd.h>
+-#include <asm/cacheflush.h>
+-#include <asm/vdso.h>
+-
+-#define DEBUG_SIG 0
+-
+-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+-
+-#define GP_REGS_SIZE32	min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
+-
+-/*
+- * When we have signals to deliver, we set up on the
+- * user stack, going down from the original stack pointer:
+- *	a sigregs32 struct
+- *	a sigcontext32 struct
+- *	a gap of __SIGNAL_FRAMESIZE32 bytes
+- *
+- * Each of these things must be a multiple of 16 bytes in size.
+- *
+- */
+-struct sigregs32 {
+-	struct mcontext32	mctx;		/* all the register values */
+-	/*
+-	 * Programs using the rs6000/xcoff abi can save up to 19 gp
+-	 * regs and 18 fp regs below sp before decrementing it.
+-	 */
+-	int			abigap[56];
+-};
+-
+-/* We use the mc_pad field for the signal return trampoline. */
+-#define tramp	mc_pad
+-
+-/*
+- *  When we have rt signals to deliver, we set up on the
+- *  user stack, going down from the original stack pointer:
+- *	one rt_sigframe32 struct (siginfo + ucontext + ABI gap)
+- *	a gap of __SIGNAL_FRAMESIZE32+16 bytes
+- *  (the +16 is to get the siginfo and ucontext32 in the same
+- *  positions as in older kernels).
+- *
+- *  Each of these things must be a multiple of 16 bytes in size.
+- *
+- */
+-struct rt_sigframe32 {
+-	compat_siginfo_t	info;
+-	struct ucontext32	uc;
+-	/*
+-	 * Programs using the rs6000/xcoff abi can save up to 19 gp
+-	 * regs and 18 fp regs below sp before decrementing it.
+-	 */
+-	int			abigap[56];
+-};
+-
+-
+-/*
+- * Common utility functions used by signal and context support
+- *
+- */
+-
+-/*
+- * Restore the user process's signal mask
+- * (implemented in signal.c)
+- */
+-extern void restore_sigmask(sigset_t *set);
+-
+-/*
+- * Functions for flipping sigsets (thanks to brain dead generic
+- * implementation that makes things simple for little endian only
+- */
+-static inline void compat_from_sigset(compat_sigset_t *compat, sigset_t *set)
+-{
+-	switch (_NSIG_WORDS) {
+-	case 4: compat->sig[5] = set->sig[3] & 0xffffffffull ;
+-		compat->sig[7] = set->sig[3] >> 32; 
+-	case 3: compat->sig[4] = set->sig[2] & 0xffffffffull ;
+-		compat->sig[5] = set->sig[2] >> 32; 
+-	case 2: compat->sig[2] = set->sig[1] & 0xffffffffull ;
+-		compat->sig[3] = set->sig[1] >> 32; 
+-	case 1: compat->sig[0] = set->sig[0] & 0xffffffffull ;
+-		compat->sig[1] = set->sig[0] >> 32; 
+-	}
+-}
+-
+-static inline void sigset_from_compat(sigset_t *set, compat_sigset_t *compat)
+-{
+-	switch (_NSIG_WORDS) {
+-	case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32);
+-	case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32);
+-	case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32);
+-	case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32);
+-	}
+-}
+-
+-
+-/*
+- * Save the current user registers on the user stack.
+- * We only save the altivec registers if the process has used
+- * altivec instructions at some point.
+- */
+-static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, int sigret)
+-{
+-	elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
+-	int i, err = 0;
+-
+-	/* Make sure floating point registers are stored in regs */
+-	flush_fp_to_thread(current);
+-
+-	/* save general and floating-point registers */
+-	for (i = 0; i <= PT_RESULT; i ++)
+-		err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]);
+-	err |= __copy_to_user(&frame->mc_fregs, current->thread.fpr,
+-			      ELF_NFPREG * sizeof(double));
+-	if (err)
+-		return 1;
+-
+-	current->thread.fpscr = 0;	/* turn off all fp exceptions */
+-
+-#ifdef CONFIG_ALTIVEC
+-	/* save altivec registers */
+-	if (current->thread.used_vr) {
+-		flush_altivec_to_thread(current);
+-		if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
+-				   ELF_NVRREG32 * sizeof(vector128)))
+-			return 1;
+-		/* set MSR_VEC in the saved MSR value to indicate that
+-		   frame->mc_vregs contains valid data */
+-		if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
+-			return 1;
+-	}
+-	/* else assert((regs->msr & MSR_VEC) == 0) */
+-
+-	/* We always copy to/from vrsave, it's 0 if we don't have or don't
+-	 * use altivec. Since VSCR only contains 32 bits saved in the least
+-	 * significant bits of a vector, we "cheat" and stuff VRSAVE in the
+-	 * most significant bits of that same vector. --BenH
+-	 */
+-	if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
+-		return 1;
+-#endif /* CONFIG_ALTIVEC */
+-
+-	if (sigret) {
+-		/* Set up the sigreturn trampoline: li r0,sigret; sc */
+-		if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
+-		    || __put_user(0x44000002UL, &frame->tramp[1]))
+-			return 1;
+-		flush_icache_range((unsigned long) &frame->tramp[0],
+-				   (unsigned long) &frame->tramp[2]);
+-	}
+-
+-	return 0;
+-}
+-
+-/*
+- * Restore the current user register values from the user stack,
+- * (except for MSR).
+- */
+-static long restore_user_regs(struct pt_regs *regs,
+-			      struct mcontext32 __user *sr, int sig)
+-{
+-	elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
+-	int i;
+-	long err = 0;
+-	unsigned int save_r2 = 0;
+-#ifdef CONFIG_ALTIVEC
+-	unsigned long msr;
+-#endif
+-
+-	/*
+-	 * restore general registers but not including MSR or SOFTE. Also
+-	 * take care of keeping r2 (TLS) intact if not a signal
+-	 */
+-	if (!sig)
+-		save_r2 = (unsigned int)regs->gpr[2];
+-	for (i = 0; i <= PT_RESULT; i++) {
+-		if ((i == PT_MSR) || (i == PT_SOFTE))
+-			continue;
+-		err |= __get_user(gregs[i], &sr->mc_gregs[i]);
+-	}
+-	if (!sig)
+-		regs->gpr[2] = (unsigned long) save_r2;
+-	if (err)
+-		return 1;
+-
+-	/* force the process to reload the FP registers from
+-	   current->thread when it next does FP instructions */
+-	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
+-	if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
+-			     sizeof(sr->mc_fregs)))
+-		return 1;
+-
+-#ifdef CONFIG_ALTIVEC
+-	/* force the process to reload the altivec registers from
+-	   current->thread when it next does altivec instructions */
+-	regs->msr &= ~MSR_VEC;
+-	if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
+-		/* restore altivec registers from the stack */
+-		if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
+-				     sizeof(sr->mc_vregs)))
+-			return 1;
+-	} else if (current->thread.used_vr)
+-		memset(current->thread.vr, 0, ELF_NVRREG32 * sizeof(vector128));
+-
+-	/* Always get VRSAVE back */
+-	if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
+-		return 1;
+-#endif /* CONFIG_ALTIVEC */
+-
+-#ifndef CONFIG_SMP
+-	preempt_disable();
+-	if (last_task_used_math == current)
+-		last_task_used_math = NULL;
+-	if (last_task_used_altivec == current)
+-		last_task_used_altivec = NULL;
+-	preempt_enable();
+-#endif
+-	return 0;
+-}
+-
+-
+-/*
+- *  Start of nonRT signal support
+- *
+- *     sigset_t is 32 bits for non-rt signals
+- *
+- *  System Calls
+- *       sigaction                sys32_sigaction
+- *       sigreturn                sys32_sigreturn
+- *
+- *  Note sigsuspend has no special 32 bit routine - uses the 64 bit routine
+- *
+- *  Other routines
+- *        setup_frame32
+- */
+-
+-/*
+- * Atomically swap in the new signal mask, and wait for a signal.
+- */
+-long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
+-	       struct pt_regs *regs)
+-{
+-	sigset_t saveset;
+-
+-	mask &= _BLOCKABLE;
+-	spin_lock_irq(&current->sighand->siglock);
+-	saveset = current->blocked;
+-	siginitset(&current->blocked, mask);
+-	recalc_sigpending();
+-	spin_unlock_irq(&current->sighand->siglock);
+-
+-	regs->result = -EINTR;
+-	regs->gpr[3] = EINTR;
+-	regs->ccr |= 0x10000000;
+-	while (1) {
+-		current->state = TASK_INTERRUPTIBLE;
+-		schedule();
+-		if (do_signal32(&saveset, regs))
+-			/*
+-			 * Returning 0 means we return to userspace via
+-			 * ret_from_except and thus restore all user
+-			 * registers from *regs.  This is what we need
+-			 * to do when a signal has been delivered.
+-			 */
+-			return 0;
+-	}
+-}
+-
+-long sys32_sigaction(int sig, struct old_sigaction32 __user *act,
+-		struct old_sigaction32 __user *oact)
+-{
+-	struct k_sigaction new_ka, old_ka;
+-	int ret;
+-	
+-	if (sig < 0)
+-		sig = -sig;
+-
+-	if (act) {
+-		compat_old_sigset_t mask;
+-		compat_uptr_t handler, restorer;
+-
+-		if (get_user(handler, &act->sa_handler) ||
+-		    __get_user(restorer, &act->sa_restorer) ||
+-		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+-		    __get_user(mask, &act->sa_mask))
+-			return -EFAULT;
+-		new_ka.sa.sa_handler = compat_ptr(handler);
+-		new_ka.sa.sa_restorer = compat_ptr(restorer);
+-		siginitset(&new_ka.sa.sa_mask, mask);
+-	}
+-
+-	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+-	if (!ret && oact) {
+-		if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
+-		    __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+-		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+-		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
+-			return -EFAULT;
+-	}
+-
+-	return ret;
+-}
+-
+-
+-
+-/*
+- *  Start of RT signal support
+- *
+- *     sigset_t is 64 bits for rt signals
+- *
+- *  System Calls
+- *       sigaction                sys32_rt_sigaction
+- *       sigpending               sys32_rt_sigpending
+- *       sigprocmask              sys32_rt_sigprocmask
+- *       sigreturn                sys32_rt_sigreturn
+- *       sigqueueinfo             sys32_rt_sigqueueinfo
+- *       sigsuspend               sys32_rt_sigsuspend
+- *
+- *  Other routines
+- *        setup_rt_frame32
+- *        copy_siginfo_to_user32
+- *        siginfo32to64
+- */
+-
+-
+-long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
+-		struct sigaction32 __user *oact, size_t sigsetsize)
+-{
+-	struct k_sigaction new_ka, old_ka;
+-	int ret;
+-	compat_sigset_t set32;
+-
+-	/* XXX: Don't preclude handling different sized sigset_t's.  */
+-	if (sigsetsize != sizeof(compat_sigset_t))
+-		return -EINVAL;
+-
+-	if (act) {
+-		compat_uptr_t handler;
+-
+-		ret = get_user(handler, &act->sa_handler);
+-		new_ka.sa.sa_handler = compat_ptr(handler);
+-		ret |= __copy_from_user(&set32, &act->sa_mask,
+-					sizeof(compat_sigset_t));
+-		sigset_from_compat(&new_ka.sa.sa_mask, &set32);
+-		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+-		if (ret)
+-			return -EFAULT;
+-	}
+-
+-	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+-	if (!ret && oact) {
+-		compat_from_sigset(&set32, &old_ka.sa.sa_mask);
+-		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
+-		ret |= __copy_to_user(&oact->sa_mask, &set32,
+-				      sizeof(compat_sigset_t));
+-		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+-	}
+-	return ret;
+-}
+-
+-/*
+- * Note: it is necessary to treat how as an unsigned int, with the
+- * corresponding cast to a signed int to insure that the proper
+- * conversion (sign extension) between the register representation
+- * of a signed int (msr in 32-bit mode) and the register representation
+- * of a signed int (msr in 64-bit mode) is performed.
+- */
+-long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set,
+-		compat_sigset_t __user *oset, size_t sigsetsize)
+-{
+-	sigset_t s;
+-	sigset_t __user *up;
+-	compat_sigset_t s32;
+-	int ret;
+-	mm_segment_t old_fs = get_fs();
+-
+-	if (set) {
+-		if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
+-			return -EFAULT;    
+-		sigset_from_compat(&s, &s32);
+-	}
+-	
+-	set_fs(KERNEL_DS);
+-	/* This is valid because of the set_fs() */
+-	up = (sigset_t __user *) &s;
+-	ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL,
+-				 sigsetsize); 
+-	set_fs(old_fs);
+-	if (ret)
+-		return ret;
+-	if (oset) {
+-		compat_from_sigset(&s32, &s);
+-		if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
+-			return -EFAULT;
+-	}
+-	return 0;
+-}
+-
+-long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
+-{
+-	sigset_t s;
+-	compat_sigset_t s32;
+-	int ret;
+-	mm_segment_t old_fs = get_fs();
+-
+-	set_fs(KERNEL_DS);
+-	/* The __user pointer cast is valid because of the set_fs() */
+-	ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
+-	set_fs(old_fs);
+-	if (!ret) {
+-		compat_from_sigset(&s32, &s);
+-		if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
+-			return -EFAULT;
+-	}
+-	return ret;
+-}
+-
+-
+-int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
+-{
+-	int err;
+-
+-	if (!access_ok (VERIFY_WRITE, d, sizeof(*d)))
+-		return -EFAULT;
+-
+-	/* If you change siginfo_t structure, please be sure
+-	 * this code is fixed accordingly.
+-	 * It should never copy any pad contained in the structure
+-	 * to avoid security leaks, but must copy the generic
+-	 * 3 ints plus the relevant union member.
+-	 * This routine must convert siginfo from 64bit to 32bit as well
+-	 * at the same time.
+-	 */
+-	err = __put_user(s->si_signo, &d->si_signo);
+-	err |= __put_user(s->si_errno, &d->si_errno);
+-	err |= __put_user((short)s->si_code, &d->si_code);
+-	if (s->si_code < 0)
+-		err |= __copy_to_user(&d->_sifields._pad, &s->_sifields._pad,
+-				      SI_PAD_SIZE32);
+-	else switch(s->si_code >> 16) {
+-	case __SI_CHLD >> 16:
+-		err |= __put_user(s->si_pid, &d->si_pid);
+-		err |= __put_user(s->si_uid, &d->si_uid);
+-		err |= __put_user(s->si_utime, &d->si_utime);
+-		err |= __put_user(s->si_stime, &d->si_stime);
+-		err |= __put_user(s->si_status, &d->si_status);
+-		break;
+-	case __SI_FAULT >> 16:
+-		err |= __put_user((unsigned int)(unsigned long)s->si_addr,
+-				  &d->si_addr);
+-		break;
+-	case __SI_POLL >> 16:
+-		err |= __put_user(s->si_band, &d->si_band);
+-		err |= __put_user(s->si_fd, &d->si_fd);
+-		break;
+-	case __SI_TIMER >> 16:
+-		err |= __put_user(s->si_tid, &d->si_tid);
+-		err |= __put_user(s->si_overrun, &d->si_overrun);
+-		err |= __put_user(s->si_int, &d->si_int);
+-		break;
+-	case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
+-	case __SI_MESGQ >> 16:
+-		err |= __put_user(s->si_int, &d->si_int);
+-		/* fallthrough */
+-	case __SI_KILL >> 16:
+-	default:
+-		err |= __put_user(s->si_pid, &d->si_pid);
+-		err |= __put_user(s->si_uid, &d->si_uid);
+-		break;
+-	}
+-	return err;
+-}
+-
+-/*
+- * Note: it is necessary to treat pid and sig as unsigned ints, with the
+- * corresponding cast to a signed int to insure that the proper conversion
+- * (sign extension) between the register representation of a signed int
+- * (msr in 32-bit mode) and the register representation of a signed int
+- * (msr in 64-bit mode) is performed.
+- */
+-long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
+-{
+-	siginfo_t info;
+-	int ret;
+-	mm_segment_t old_fs = get_fs();
+-	
+-	if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
+-	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32))
+-		return -EFAULT;
+-	set_fs (KERNEL_DS);
+-	/* The __user pointer cast is valid becasuse of the set_fs() */
+-	ret = sys_rt_sigqueueinfo((int)pid, (int)sig, (siginfo_t __user *) &info);
+-	set_fs (old_fs);
+-	return ret;
+-}
+-
+-int sys32_rt_sigsuspend(compat_sigset_t __user * unewset, size_t sigsetsize, int p3,
+-		int p4, int p6, int p7, struct pt_regs *regs)
+-{
+-	sigset_t saveset, newset;
+-	compat_sigset_t s32;
+-
+-	/* XXX: Don't preclude handling different sized sigset_t's.  */
+-	if (sigsetsize != sizeof(sigset_t))
+-		return -EINVAL;
+-
+-	if (copy_from_user(&s32, unewset, sizeof(s32)))
+-		return -EFAULT;
+-
+-	/*
+-	 * Swap the 2 words of the 64-bit sigset_t (they are stored
+-	 * in the "wrong" endian in 32-bit user storage).
+-	 */
+-	sigset_from_compat(&newset, &s32);
+-
+-	sigdelsetmask(&newset, ~_BLOCKABLE);
+-	spin_lock_irq(&current->sighand->siglock);
+-	saveset = current->blocked;
+-	current->blocked = newset;
+-	recalc_sigpending();
+-	spin_unlock_irq(&current->sighand->siglock);
+-
+-	regs->result = -EINTR;
+-	regs->gpr[3] = EINTR;
+-	regs->ccr |= 0x10000000;
+-	while (1) {
+-		current->state = TASK_INTERRUPTIBLE;
+-		schedule();
+-		if (do_signal32(&saveset, regs))
+-			/*
+-			 * Returning 0 means we return to userspace via
+-			 * ret_from_except and thus restore all user
+-			 * registers from *regs.  This is what we need
+-			 * to do when a signal has been delivered.
+-			 */
+-			return 0;
+-	}
+-}
+-
+-/*
+- *  Start Alternate signal stack support
+- *
+- *  System Calls
+- *       sigaltatck               sys32_sigaltstack
+- */
+-
+-int sys32_sigaltstack(u32 __new, u32 __old, int r5,
+-		      int r6, int r7, int r8, struct pt_regs *regs)
+-{
+-	stack_32_t __user * newstack = (stack_32_t __user *)(long) __new;
+-	stack_32_t __user * oldstack = (stack_32_t __user *)(long) __old;
+-	stack_t uss, uoss;
+-	int ret;
+-	mm_segment_t old_fs;
+-	unsigned long sp;
+-	compat_uptr_t ss_sp;
+-
+-	/*
+-	 * set sp to the user stack on entry to the system call
+-	 * the system call router sets R9 to the saved registers
+-	 */
+-	sp = regs->gpr[1];
+-
+-	/* Put new stack info in local 64 bit stack struct */
+-	if (newstack) {
+-		if (get_user(ss_sp, &newstack->ss_sp) ||
+-		    __get_user(uss.ss_flags, &newstack->ss_flags) ||
+-		    __get_user(uss.ss_size, &newstack->ss_size))
+-			return -EFAULT;
+-		uss.ss_sp = compat_ptr(ss_sp);
+-	}
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	/* The __user pointer casts are valid because of the set_fs() */
+-	ret = do_sigaltstack(
+-		newstack ? (stack_t __user *) &uss : NULL,
+-		oldstack ? (stack_t __user *) &uoss : NULL,
+-		sp);
+-	set_fs(old_fs);
+-	/* Copy the stack information to the user output buffer */
+-	if (!ret && oldstack  &&
+-		(put_user((long)uoss.ss_sp, &oldstack->ss_sp) ||
+-		 __put_user(uoss.ss_flags, &oldstack->ss_flags) ||
+-		 __put_user(uoss.ss_size, &oldstack->ss_size)))
+-		return -EFAULT;
+-	return ret;
+-}
+-
+-
+-/*
+- * Set up a signal frame for a "real-time" signal handler
+- * (one which gets siginfo).
+- */
+-static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
+-			      siginfo_t *info, sigset_t *oldset,
+-			      struct pt_regs * regs, unsigned long newsp)
+-{
+-	struct rt_sigframe32 __user *rt_sf;
+-	struct mcontext32 __user *frame;
+-	unsigned long origsp = newsp;
+-	compat_sigset_t c_oldset;
+-
+-	/* Set up Signal Frame */
+-	/* Put a Real Time Context onto stack */
+-	newsp -= sizeof(*rt_sf);
+-	rt_sf = (struct rt_sigframe32 __user *)newsp;
+-
+-	/* create a stack frame for the caller of the handler */
+-	newsp -= __SIGNAL_FRAMESIZE32 + 16;
+-
+-	if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp))
+-		goto badframe;
+-
+-	compat_from_sigset(&c_oldset, oldset);
+-
+-	/* Put the siginfo & fill in most of the ucontext */
+-	if (copy_siginfo_to_user32(&rt_sf->info, info)
+-	    || __put_user(0, &rt_sf->uc.uc_flags)
+-	    || __put_user(0, &rt_sf->uc.uc_link)
+-	    || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
+-	    || __put_user(sas_ss_flags(regs->gpr[1]),
+-			  &rt_sf->uc.uc_stack.ss_flags)
+-	    || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
+-	    || __put_user((u32)(u64)&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
+-	    || __copy_to_user(&rt_sf->uc.uc_sigmask, &c_oldset, sizeof(c_oldset)))
+-		goto badframe;
+-
+-	/* Save user registers on the stack */
+-	frame = &rt_sf->uc.uc_mcontext;
+-	if (put_user(regs->gpr[1], (u32 __user *)newsp))
+-		goto badframe;
+-
+-	if (vdso32_rt_sigtramp && current->thread.vdso_base) {
+-		if (save_user_regs(regs, frame, 0))
+-			goto badframe;
+-		regs->link = current->thread.vdso_base + vdso32_rt_sigtramp;
+-	} else {
+-		if (save_user_regs(regs, frame, __NR_rt_sigreturn))
+-			goto badframe;
+-		regs->link = (unsigned long) frame->tramp;
+-	}
+-	regs->gpr[1] = (unsigned long) newsp;
+-	regs->gpr[3] = sig;
+-	regs->gpr[4] = (unsigned long) &rt_sf->info;
+-	regs->gpr[5] = (unsigned long) &rt_sf->uc;
+-	regs->gpr[6] = (unsigned long) rt_sf;
+-	regs->nip = (unsigned long) ka->sa.sa_handler;
+-	regs->trap = 0;
+-	regs->result = 0;
+-
+-	if (test_thread_flag(TIF_SINGLESTEP))
+-		ptrace_notify(SIGTRAP);
+-
+-	return 1;
+-
+-badframe:
+-#if DEBUG_SIG
+-	printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
+-	       regs, frame, newsp);
+-#endif
+-	force_sigsegv(sig, current);
+-	return 0;
+-}
+-
+-static long do_setcontext32(struct ucontext32 __user *ucp, struct pt_regs *regs, int sig)
+-{
+-	compat_sigset_t c_set;
+-	sigset_t set;
+-	u32 mcp;
+-
+-	if (__copy_from_user(&c_set, &ucp->uc_sigmask, sizeof(c_set))
+-	    || __get_user(mcp, &ucp->uc_regs))
+-		return -EFAULT;
+-	sigset_from_compat(&set, &c_set);
+-	restore_sigmask(&set);
+-	if (restore_user_regs(regs, (struct mcontext32 __user *)(u64)mcp, sig))
+-		return -EFAULT;
+-
+-	return 0;
+-}
+-
+-/*
+- * Handle {get,set,swap}_context operations for 32 bits processes
+- */
+-
+-long sys32_swapcontext(struct ucontext32 __user *old_ctx,
+-		       struct ucontext32 __user *new_ctx,
+-		       int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
+-{
+-	unsigned char tmp;
+-	compat_sigset_t c_set;
+-
+-	/* Context size is for future use. Right now, we only make sure
+-	 * we are passed something we understand
+-	 */
+-	if (ctx_size < sizeof(struct ucontext32))
+-		return -EINVAL;
+-
+-	if (old_ctx != NULL) {
+-		compat_from_sigset(&c_set, &current->blocked);
+-		if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
+-		    || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
+-		    || __copy_to_user(&old_ctx->uc_sigmask, &c_set, sizeof(c_set))
+-		    || __put_user((u32)(u64)&old_ctx->uc_mcontext, &old_ctx->uc_regs))
+-			return -EFAULT;
+-	}
+-	if (new_ctx == NULL)
+-		return 0;
+-	if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx))
+-	    || __get_user(tmp, (u8 __user *) new_ctx)
+-	    || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
+-		return -EFAULT;
+-
+-	/*
+-	 * If we get a fault copying the context into the kernel's
+-	 * image of the user's registers, we can't just return -EFAULT
+-	 * because the user's registers will be corrupted.  For instance
+-	 * the NIP value may have been updated but not some of the
+-	 * other registers.  Given that we have done the access_ok
+-	 * and successfully read the first and last bytes of the region
+-	 * above, this should only happen in an out-of-memory situation
+-	 * or if another thread unmaps the region containing the context.
+-	 * We kill the task with a SIGSEGV in this situation.
+-	 */
+-	if (do_setcontext32(new_ctx, regs, 0))
+-		do_exit(SIGSEGV);
+-
+-	return 0;
+-}
+-
+-long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+-		     struct pt_regs *regs)
+-{
+-	struct rt_sigframe32 __user *rt_sf;
+-	int ret;
+-
+-
+-	/* Always make any pending restarted system calls return -EINTR */
+-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+-
+-	rt_sf = (struct rt_sigframe32 __user *)
+-		(regs->gpr[1] + __SIGNAL_FRAMESIZE32 + 16);
+-	if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
+-		goto bad;
+-	if (do_setcontext32(&rt_sf->uc, regs, 1))
+-		goto bad;
+-
+-	/*
+-	 * It's not clear whether or why it is desirable to save the
+-	 * sigaltstack setting on signal delivery and restore it on
+-	 * signal return.  But other architectures do this and we have
+-	 * always done it up until now so it is probably better not to
+-	 * change it.  -- paulus
+-	 * We use the sys32_ version that does the 32/64 bits conversion
+-	 * and takes userland pointer directly. What about error checking ?
+-	 * nobody does any...
+-	 */
+-       	sys32_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
+-
+-	ret = regs->result;
+-
+-	return ret;
+-
+- bad:
+-	force_sig(SIGSEGV, current);
+-	return 0;
+-}
+-
+-
+-/*
+- * OK, we're invoking a handler
+- */
+-static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
+-			    siginfo_t *info, sigset_t *oldset,
+-			    struct pt_regs * regs, unsigned long newsp)
+-{
+-	struct sigcontext32 __user *sc;
+-	struct sigregs32 __user *frame;
+-	unsigned long origsp = newsp;
+-
+-	/* Set up Signal Frame */
+-	newsp -= sizeof(struct sigregs32);
+-	frame = (struct sigregs32 __user *) newsp;
+-
+-	/* Put a sigcontext on the stack */
+-	newsp -= sizeof(*sc);
+-	sc = (struct sigcontext32 __user *) newsp;
+-
+-	/* create a stack frame for the caller of the handler */
+-	newsp -= __SIGNAL_FRAMESIZE32;
+-
+-	if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
+-		goto badframe;
+-
+-#if _NSIG != 64
+-#error "Please adjust handle_signal32()"
+-#endif
+-	if (__put_user((u32)(u64)ka->sa.sa_handler, &sc->handler)
+-	    || __put_user(oldset->sig[0], &sc->oldmask)
+-	    || __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
+-	    || __put_user((u32)(u64)frame, &sc->regs)
+-	    || __put_user(sig, &sc->signal))
+-		goto badframe;
+-
+-	if (vdso32_sigtramp && current->thread.vdso_base) {
+-		if (save_user_regs(regs, &frame->mctx, 0))
+-			goto badframe;
+-		regs->link = current->thread.vdso_base + vdso32_sigtramp;
+-	} else {
+-		if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
+-			goto badframe;
+-		regs->link = (unsigned long) frame->mctx.tramp;
+-	}
+-
+-	if (put_user(regs->gpr[1], (u32 __user *)newsp))
+-		goto badframe;
+-	regs->gpr[1] = (unsigned long) newsp;
+-	regs->gpr[3] = sig;
+-	regs->gpr[4] = (unsigned long) sc;
+-	regs->nip = (unsigned long) ka->sa.sa_handler;
+-	regs->trap = 0;
+-	regs->result = 0;
+-
+-	if (test_thread_flag(TIF_SINGLESTEP))
+-		ptrace_notify(SIGTRAP);
+-
+-	return 1;
+-
+-badframe:
+-#if DEBUG_SIG
+-	printk("badframe in handle_signal, regs=%p frame=%x newsp=%x\n",
+-	       regs, frame, *newspp);
+-#endif
+-	force_sigsegv(sig, current);
+-	return 0;
+-}
+-
+-/*
+- * Do a signal return; undo the signal stack.
+- */
+-long sys32_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+-		       struct pt_regs *regs)
+-{
+-	struct sigcontext32 __user *sc;
+-	struct sigcontext32 sigctx;
+-	struct mcontext32 __user *sr;
+-	sigset_t set;
+-	int ret;
+-
+-	/* Always make any pending restarted system calls return -EINTR */
+-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+-
+-	sc = (struct sigcontext32 __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
+-	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+-		goto badframe;
+-
+-	/*
+-	 * Note that PPC32 puts the upper 32 bits of the sigmask in the
+-	 * unused part of the signal stackframe
+-	 */
+-	set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32);
+-	restore_sigmask(&set);
+-
+-	sr = (struct mcontext32 __user *)(u64)sigctx.regs;
+-	if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
+-	    || restore_user_regs(regs, sr, 1))
+-		goto badframe;
+-
+-	ret = regs->result;
+-	return ret;
+-
+-badframe:
+-	force_sig(SIGSEGV, current);
+-	return 0;
+-}
+-
+-
+-
+-/*
+- *  Start of do_signal32 routine
+- *
+- *   This routine gets control when a pending signal needs to be processed
+- *     in the 32 bit target thread -
+- *
+- *   It handles both rt and non-rt signals
+- */
+-
+-/*
+- * Note that 'init' is a special process: it doesn't get signals it doesn't
+- * want to handle. Thus you cannot kill init even with a SIGKILL even by
+- * mistake.
+- */
+-
+-int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+-{
+-	siginfo_t info;
+-	unsigned int frame, newsp;
+-	int signr, ret;
+-	struct k_sigaction ka;
+-
+-	if (!oldset)
+-		oldset = &current->blocked;
+-
+-	newsp = frame = 0;
+-
+-	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+-
+-	if (TRAP(regs) == 0x0C00		/* System Call! */
+-	    && regs->ccr & 0x10000000		/* error signalled */
+-	    && ((ret = regs->gpr[3]) == ERESTARTSYS
+-		|| ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
+-		|| ret == ERESTART_RESTARTBLOCK)) {
+-
+-		if (signr > 0
+-		    && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
+-			|| (ret == ERESTARTSYS
+-			    && !(ka.sa.sa_flags & SA_RESTART)))) {
+-			/* make the system call return an EINTR error */
+-			regs->result = -EINTR;
+-			regs->gpr[3] = EINTR;
+-			/* note that the cr0.SO bit is already set */
+-		} else {
+-			regs->nip -= 4;	/* Back up & retry system call */
+-			regs->result = 0;
+-			regs->trap = 0;
+-			if (ret == ERESTART_RESTARTBLOCK)
+-				regs->gpr[0] = __NR_restart_syscall;
+-			else
+-				regs->gpr[3] = regs->orig_gpr3;
+-		}
+-	}
+-
+-	if (signr == 0)
+-		return 0;		/* no signals delivered */
+-
+-	if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
+-	    && (!on_sig_stack(regs->gpr[1])))
+-		newsp = (current->sas_ss_sp + current->sas_ss_size);
+-	else
+-		newsp = regs->gpr[1];
+-	newsp &= ~0xfUL;
+-
+-	/*
+-	 * Reenable the DABR before delivering the signal to
+-	 * user space. The DABR will have been cleared if it
+-	 * triggered inside the kernel.
+-	 */
+-	if (current->thread.dabr)
+-		set_dabr(current->thread.dabr);
+-
+-	/* Whee!  Actually deliver the signal.  */
+-	if (ka.sa.sa_flags & SA_SIGINFO)
+-		ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp);
+-	else
+-		ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp);
+-
+-	if (ret) {
+-		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 ret;
+-}
+diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
+--- a/arch/ppc64/kernel/smp.c
++++ b/arch/ppc64/kernel/smp.c
+@@ -45,8 +45,7 @@
+ #include <asm/cputable.h>
+ #include <asm/system.h>
+ #include <asm/abs_addr.h>
+-
+-#include "mpic.h"
++#include <asm/mpic.h>
+ 
+ #ifdef DEBUG
+ #define DBG(fmt...) udbg_printf(fmt)
+@@ -70,28 +69,6 @@ void smp_call_function_interrupt(void);
+ int smt_enabled_at_boot = 1;
+ 
+ #ifdef CONFIG_MPIC
+-void smp_mpic_message_pass(int target, int msg)
+-{
+-	/* make sure we're sending something that translates to an IPI */
+-	if ( msg > 0x3 ){
+-		printk("SMP %d: smp_message_pass: unknown msg %d\n",
+-		       smp_processor_id(), msg);
+-		return;
+-	}
+-	switch ( target )
+-	{
+-	case MSG_ALL:
+-		mpic_send_ipi(msg, 0xffffffff);
+-		break;
+-	case MSG_ALL_BUT_SELF:
+-		mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id()));
+-		break;
+-	default:
+-		mpic_send_ipi(msg, 1 << target);
+-		break;
+-	}
+-}
+-
+ int __init smp_mpic_probe(void)
+ {
+ 	int nr_cpus;
+@@ -128,21 +105,6 @@ void __devinit smp_generic_kick_cpu(int 
+ 
+ #endif /* CONFIG_MPIC */
+ 
+-static void __init smp_space_timers(unsigned int max_cpus)
+-{
+-	int i;
+-	unsigned long offset = tb_ticks_per_jiffy / max_cpus;
+-	unsigned long previous_tb = paca[boot_cpuid].next_jiffy_update_tb;
+-
+-	for_each_cpu(i) {
+-		if (i != boot_cpuid) {
+-			paca[i].next_jiffy_update_tb =
+-				previous_tb + offset;
+-			previous_tb = paca[i].next_jiffy_update_tb;
+-		}
+-	}
+-}
+-
+ void smp_message_recv(int msg, struct pt_regs *regs)
+ {
+ 	switch(msg) {
+diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/sys_ppc32.c
++++ /dev/null
+@@ -1,1222 +0,0 @@
+-/*
+- * sys_ppc32.c: Conversion between 32bit and 64bit native syscalls.
+- *
+- * Copyright (C) 2001 IBM
+- * Copyright (C) 1997,1998 Jakub Jelinek (jj at sunsite.mff.cuni.cz)
+- * Copyright (C) 1997 David S. Miller (davem at caip.rutgers.edu)
+- *
+- * These routines maintain argument size conversion between 32bit and 64bit
+- * environment.
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/fs.h> 
+-#include <linux/mm.h> 
+-#include <linux/file.h> 
+-#include <linux/signal.h>
+-#include <linux/resource.h>
+-#include <linux/times.h>
+-#include <linux/utsname.h>
+-#include <linux/timex.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/sem.h>
+-#include <linux/msg.h>
+-#include <linux/shm.h>
+-#include <linux/poll.h>
+-#include <linux/personality.h>
+-#include <linux/stat.h>
+-#include <linux/mman.h>
+-#include <linux/in.h>
+-#include <linux/syscalls.h>
+-#include <linux/unistd.h>
+-#include <linux/sysctl.h>
+-#include <linux/binfmts.h>
+-#include <linux/security.h>
+-#include <linux/compat.h>
+-#include <linux/ptrace.h>
+-#include <linux/elf.h>
+-
+-#include <asm/ptrace.h>
+-#include <asm/types.h>
+-#include <asm/ipc.h>
+-#include <asm/uaccess.h>
+-#include <asm/unistd.h>
+-#include <asm/semaphore.h>
+-#include <asm/time.h>
+-#include <asm/mmu_context.h>
+-#include <asm/systemcfg.h>
+-
+-#include "pci.h"
+-
+-/* readdir & getdents */
+-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
+-#define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
+-
+-struct old_linux_dirent32 {
+-	u32		d_ino;
+-	u32		d_offset;
+-	unsigned short	d_namlen;
+-	char		d_name[1];
+-};
+-
+-struct readdir_callback32 {
+-	struct old_linux_dirent32 __user * dirent;
+-	int count;
+-};
+-
+-static int fillonedir(void * __buf, const char * name, int namlen,
+-		                  off_t offset, ino_t ino, unsigned int d_type)
+-{
+-	struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
+-	struct old_linux_dirent32 __user * dirent;
+-
+-	if (buf->count)
+-		return -EINVAL;
+-	buf->count++;
+-	dirent = buf->dirent;
+-	put_user(ino, &dirent->d_ino);
+-	put_user(offset, &dirent->d_offset);
+-	put_user(namlen, &dirent->d_namlen);
+-	copy_to_user(dirent->d_name, name, namlen);
+-	put_user(0, dirent->d_name + namlen);
+-	return 0;
+-}
+-
+-asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 __user *dirent, unsigned int count)
+-{
+-	int error = -EBADF;
+-	struct file * file;
+-	struct readdir_callback32 buf;
+-
+-	file = fget(fd);
+-	if (!file)
+-		goto out;
+-
+-	buf.count = 0;
+-	buf.dirent = dirent;
+-
+-	error = vfs_readdir(file, (filldir_t)fillonedir, &buf);
+-	if (error < 0)
+-		goto out_putf;
+-	error = buf.count;
+-
+-out_putf:
+-	fput(file);
+-out:
+-	return error;
+-}
+-
+-struct linux_dirent32 {
+-	u32		d_ino;
+-	u32		d_off;
+-	unsigned short	d_reclen;
+-	char		d_name[1];
+-};
+-
+-struct getdents_callback32 {
+-	struct linux_dirent32 __user * current_dir;
+-	struct linux_dirent32 __user * previous;
+-	int count;
+-	int error;
+-};
+-
+-static int filldir(void * __buf, const char * name, int namlen, off_t offset,
+-		   ino_t ino, unsigned int d_type)
+-{
+-	struct linux_dirent32 __user * dirent;
+-	struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
+-	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
+-
+-	buf->error = -EINVAL;	/* only used if we fail.. */
+-	if (reclen > buf->count)
+-		return -EINVAL;
+-	dirent = buf->previous;
+-	if (dirent) {
+-		if (__put_user(offset, &dirent->d_off))
+-			goto efault;
+-	}
+-	dirent = buf->current_dir;
+-	if (__put_user(ino, &dirent->d_ino))
+-		goto efault;
+-	if (__put_user(reclen, &dirent->d_reclen))
+-		goto efault;
+-	if (copy_to_user(dirent->d_name, name, namlen))
+-		goto efault;
+-	if (__put_user(0, dirent->d_name + namlen))
+-		goto efault;
+-	if (__put_user(d_type, (char __user *) dirent + reclen - 1))
+-		goto efault;
+-	buf->previous = dirent;
+-	dirent = (void __user *)dirent + reclen;
+-	buf->current_dir = dirent;
+-	buf->count -= reclen;
+-	return 0;
+-efault:
+-	buf->error = -EFAULT;
+-	return -EFAULT;
+-}
+-
+-asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 __user *dirent,
+-		    unsigned int count)
+-{
+-	struct file * file;
+-	struct linux_dirent32 __user * lastdirent;
+-	struct getdents_callback32 buf;
+-	int error;
+-
+-	error = -EFAULT;
+-	if (!access_ok(VERIFY_WRITE, dirent, count))
+-		goto out;
+-
+-	error = -EBADF;
+-	file = fget(fd);
+-	if (!file)
+-		goto out;
+-
+-	buf.current_dir = dirent;
+-	buf.previous = NULL;
+-	buf.count = count;
+-	buf.error = 0;
+-
+-	error = vfs_readdir(file, (filldir_t)filldir, &buf);
+-	if (error < 0)
+-		goto out_putf;
+-	error = buf.error;
+-	lastdirent = buf.previous;
+-	if (lastdirent) {
+-		if (put_user(file->f_pos, &lastdirent->d_off))
+-			error = -EFAULT;
+-		else
+-			error = count - buf.count;
+-	}
+-
+-out_putf:
+-	fput(file);
+-out:
+-	return error;
+-}
+-
+-asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
+-		compat_ulong_t __user *outp, compat_ulong_t __user *exp,
+-		compat_uptr_t tvp_x)
+-{
+-	/* sign extend n */
+-	return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x));
+-}
+-
+-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
+-{
+-	long err;
+-
+-	if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
+-	    !new_valid_dev(stat->rdev))
+-		return -EOVERFLOW;
+-
+-	err  = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT;
+-	err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
+-	err |= __put_user(stat->ino, &statbuf->st_ino);
+-	err |= __put_user(stat->mode, &statbuf->st_mode);
+-	err |= __put_user(stat->nlink, &statbuf->st_nlink);
+-	err |= __put_user(stat->uid, &statbuf->st_uid);
+-	err |= __put_user(stat->gid, &statbuf->st_gid);
+-	err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
+-	err |= __put_user(stat->size, &statbuf->st_size);
+-	err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime);
+-	err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+-	err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
+-	err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
+-	err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
+-	err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
+-	err |= __put_user(stat->blksize, &statbuf->st_blksize);
+-	err |= __put_user(stat->blocks, &statbuf->st_blocks);
+-	err |= __put_user(0, &statbuf->__unused4[0]);
+-	err |= __put_user(0, &statbuf->__unused4[1]);
+-
+-	return err;
+-}
+-
+-/* Note: it is necessary to treat option as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_sysfs(u32 option, u32 arg1, u32 arg2)
+-{
+-	return sys_sysfs((int)option, arg1, arg2);
+-}
+-
+-/* Handle adjtimex compatibility. */
+-struct timex32 {
+-	u32 modes;
+-	s32 offset, freq, maxerror, esterror;
+-	s32 status, constant, precision, tolerance;
+-	struct compat_timeval time;
+-	s32 tick;
+-	s32 ppsfreq, jitter, shift, stabil;
+-	s32 jitcnt, calcnt, errcnt, stbcnt;
+-	s32  :32; s32  :32; s32  :32; s32  :32;
+-	s32  :32; s32  :32; s32  :32; s32  :32;
+-	s32  :32; s32  :32; s32  :32; s32  :32;
+-};
+-
+-extern int do_adjtimex(struct timex *);
+-extern void ppc_adjtimex(void);
+-
+-asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
+-{
+-	struct timex txc;
+-	int ret;
+-	
+-	memset(&txc, 0, sizeof(struct timex));
+-
+-	if(get_user(txc.modes, &utp->modes) ||
+-	   __get_user(txc.offset, &utp->offset) ||
+-	   __get_user(txc.freq, &utp->freq) ||
+-	   __get_user(txc.maxerror, &utp->maxerror) ||
+-	   __get_user(txc.esterror, &utp->esterror) ||
+-	   __get_user(txc.status, &utp->status) ||
+-	   __get_user(txc.constant, &utp->constant) ||
+-	   __get_user(txc.precision, &utp->precision) ||
+-	   __get_user(txc.tolerance, &utp->tolerance) ||
+-	   __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
+-	   __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
+-	   __get_user(txc.tick, &utp->tick) ||
+-	   __get_user(txc.ppsfreq, &utp->ppsfreq) ||
+-	   __get_user(txc.jitter, &utp->jitter) ||
+-	   __get_user(txc.shift, &utp->shift) ||
+-	   __get_user(txc.stabil, &utp->stabil) ||
+-	   __get_user(txc.jitcnt, &utp->jitcnt) ||
+-	   __get_user(txc.calcnt, &utp->calcnt) ||
+-	   __get_user(txc.errcnt, &utp->errcnt) ||
+-	   __get_user(txc.stbcnt, &utp->stbcnt))
+-		return -EFAULT;
+-
+-	ret = do_adjtimex(&txc);
+-
+-	/* adjust the conversion of TB to time of day to track adjtimex */
+-	ppc_adjtimex();
+-
+-	if(put_user(txc.modes, &utp->modes) ||
+-	   __put_user(txc.offset, &utp->offset) ||
+-	   __put_user(txc.freq, &utp->freq) ||
+-	   __put_user(txc.maxerror, &utp->maxerror) ||
+-	   __put_user(txc.esterror, &utp->esterror) ||
+-	   __put_user(txc.status, &utp->status) ||
+-	   __put_user(txc.constant, &utp->constant) ||
+-	   __put_user(txc.precision, &utp->precision) ||
+-	   __put_user(txc.tolerance, &utp->tolerance) ||
+-	   __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
+-	   __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
+-	   __put_user(txc.tick, &utp->tick) ||
+-	   __put_user(txc.ppsfreq, &utp->ppsfreq) ||
+-	   __put_user(txc.jitter, &utp->jitter) ||
+-	   __put_user(txc.shift, &utp->shift) ||
+-	   __put_user(txc.stabil, &utp->stabil) ||
+-	   __put_user(txc.jitcnt, &utp->jitcnt) ||
+-	   __put_user(txc.calcnt, &utp->calcnt) ||
+-	   __put_user(txc.errcnt, &utp->errcnt) ||
+-	   __put_user(txc.stbcnt, &utp->stbcnt))
+-		ret = -EFAULT;
+-
+-	return ret;
+-}
+-
+-asmlinkage long sys32_pause(void)
+-{
+-	current->state = TASK_INTERRUPTIBLE;
+-	schedule();
+-	
+-	return -ERESTARTNOHAND;
+-}
+-
+-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
+-{
+-	long usec;
+-
+-	if (!access_ok(VERIFY_READ, i, sizeof(*i)))
+-		return -EFAULT;
+-	if (__get_user(o->tv_sec, &i->tv_sec))
+-		return -EFAULT;
+-	if (__get_user(usec, &i->tv_usec))
+-		return -EFAULT;
+-	o->tv_nsec = usec * 1000;
+-	return 0;
+-}
+-
+-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
+-{
+-	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
+-		(__put_user(i->tv_sec, &o->tv_sec) |
+-		 __put_user(i->tv_usec, &o->tv_usec)));
+-}
+-
+-struct sysinfo32 {
+-        s32 uptime;
+-        u32 loads[3];
+-        u32 totalram;
+-        u32 freeram;
+-        u32 sharedram;
+-        u32 bufferram;
+-        u32 totalswap;
+-        u32 freeswap;
+-        unsigned short procs;
+-	unsigned short pad;
+-	u32 totalhigh;
+-	u32 freehigh;
+-	u32 mem_unit;
+-	char _f[20-2*sizeof(int)-sizeof(int)];
+-};
+-
+-asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info)
+-{
+-	struct sysinfo s;
+-	int ret, err;
+-	int bitcount=0;
+-	mm_segment_t old_fs = get_fs ();
+-	
+-	/* The __user cast is valid due to set_fs() */
+-	set_fs (KERNEL_DS);
+-	ret = sys_sysinfo((struct sysinfo __user *)&s);
+-	set_fs (old_fs);
+-
+-	/* Check to see if any memory value is too large for 32-bit and
+-         * scale down if needed.
+-         */
+-	if ((s.totalram >> 32) || (s.totalswap >> 32)) {
+-	    while (s.mem_unit < PAGE_SIZE) {
+-		s.mem_unit <<= 1;
+-		bitcount++;
+-	    }
+-	    s.totalram >>=bitcount;
+-	    s.freeram >>= bitcount;
+-	    s.sharedram >>= bitcount;
+-	    s.bufferram >>= bitcount;
+-	    s.totalswap >>= bitcount;
+-	    s.freeswap >>= bitcount;
+-	    s.totalhigh >>= bitcount;
+-	    s.freehigh >>= bitcount;
+-	}
+-
+-	err = put_user (s.uptime, &info->uptime);
+-	err |= __put_user (s.loads[0], &info->loads[0]);
+-	err |= __put_user (s.loads[1], &info->loads[1]);
+-	err |= __put_user (s.loads[2], &info->loads[2]);
+-	err |= __put_user (s.totalram, &info->totalram);
+-	err |= __put_user (s.freeram, &info->freeram);
+-	err |= __put_user (s.sharedram, &info->sharedram);
+-	err |= __put_user (s.bufferram, &info->bufferram);
+-	err |= __put_user (s.totalswap, &info->totalswap);
+-	err |= __put_user (s.freeswap, &info->freeswap);
+-	err |= __put_user (s.procs, &info->procs);
+-	err |= __put_user (s.totalhigh, &info->totalhigh);
+-	err |= __put_user (s.freehigh, &info->freehigh);
+-	err |= __put_user (s.mem_unit, &info->mem_unit);
+-	if (err)
+-		return -EFAULT;
+-	
+-	return ret;
+-}
+-
+-
+-
+-
+-/* Translations due to time_t size differences.  Which affects all
+-   sorts of things, like timeval and itimerval.  */
+-extern struct timezone sys_tz;
+-
+-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
+-{
+-	if (tv) {
+-		struct timeval ktv;
+-		do_gettimeofday(&ktv);
+-		if (put_tv32(tv, &ktv))
+-			return -EFAULT;
+-	}
+-	if (tz) {
+-		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
+-			return -EFAULT;
+-	}
+-	
+-	return 0;
+-}
+-
+-
+-
+-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
+-{
+-	struct timespec kts;
+-	struct timezone ktz;
+-	
+- 	if (tv) {
+-		if (get_ts32(&kts, tv))
+-			return -EFAULT;
+-	}
+-	if (tz) {
+-		if (copy_from_user(&ktz, tz, sizeof(ktz)))
+-			return -EFAULT;
+-	}
+-
+-	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
+-}
+-
+-#ifdef CONFIG_SYSVIPC
+-long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
+-	       u32 fifth)
+-{
+-	int version;
+-
+-	version = call >> 16; /* hack for backward compatibility */
+-	call &= 0xffff;
+-
+-	switch (call) {
+-
+-	case SEMTIMEDOP:
+-		if (fifth)
+-			/* sign extend semid */
+-			return compat_sys_semtimedop((int)first,
+-						     compat_ptr(ptr), second,
+-						     compat_ptr(fifth));
+-		/* else fall through for normal semop() */
+-	case SEMOP:
+-		/* struct sembuf is the same on 32 and 64bit :)) */
+-		/* sign extend semid */
+-		return sys_semtimedop((int)first, compat_ptr(ptr), second,
+-				      NULL);
+-	case SEMGET:
+-		/* sign extend key, nsems */
+-		return sys_semget((int)first, (int)second, third);
+-	case SEMCTL:
+-		/* sign extend semid, semnum */
+-		return compat_sys_semctl((int)first, (int)second, third,
+-					 compat_ptr(ptr));
+-
+-	case MSGSND:
+-		/* sign extend msqid */
+-		return compat_sys_msgsnd((int)first, (int)second, third,
+-					 compat_ptr(ptr));
+-	case MSGRCV:
+-		/* sign extend msqid, msgtyp */
+-		return compat_sys_msgrcv((int)first, second, (int)fifth,
+-					 third, version, compat_ptr(ptr));
+-	case MSGGET:
+-		/* sign extend key */
+-		return sys_msgget((int)first, second);
+-	case MSGCTL:
+-		/* sign extend msqid */
+-		return compat_sys_msgctl((int)first, second, compat_ptr(ptr));
+-
+-	case SHMAT:
+-		/* sign extend shmid */
+-		return compat_sys_shmat((int)first, second, third, version,
+-					compat_ptr(ptr));
+-	case SHMDT:
+-		return sys_shmdt(compat_ptr(ptr));
+-	case SHMGET:
+-		/* sign extend key_t */
+-		return sys_shmget((int)first, second, third);
+-	case SHMCTL:
+-		/* sign extend shmid */
+-		return compat_sys_shmctl((int)first, second, compat_ptr(ptr));
+-
+-	default:
+-		return -ENOSYS;
+-	}
+-
+-	return -ENOSYS;
+-}
+-#endif
+-
+-/* Note: it is necessary to treat out_fd and in_fd as unsigned ints, 
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
+-{
+-	mm_segment_t old_fs = get_fs();
+-	int ret;
+-	off_t of;
+-	off_t __user *up;
+-
+-	if (offset && get_user(of, offset))
+-		return -EFAULT;
+-
+-	/* The __user pointer cast is valid because of the set_fs() */		
+-	set_fs(KERNEL_DS);
+-	up = offset ? (off_t __user *) &of : NULL;
+-	ret = sys_sendfile((int)out_fd, (int)in_fd, up, count);
+-	set_fs(old_fs);
+-	
+-	if (offset && put_user(of, offset))
+-		return -EFAULT;
+-		
+-	return ret;
+-}
+-
+-asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
+-{
+-	mm_segment_t old_fs = get_fs();
+-	int ret;
+-	loff_t lof;
+-	loff_t __user *up;
+-	
+-	if (offset && get_user(lof, offset))
+-		return -EFAULT;
+-		
+-	/* The __user pointer cast is valid because of the set_fs() */		
+-	set_fs(KERNEL_DS);
+-	up = offset ? (loff_t __user *) &lof : NULL;
+-	ret = sys_sendfile64(out_fd, in_fd, up, count);
+-	set_fs(old_fs);
+-	
+-	if (offset && put_user(lof, offset))
+-		return -EFAULT;
+-		
+-	return ret;
+-}
+-
+-long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+-		  unsigned long a3, unsigned long a4, unsigned long a5,
+-		  struct pt_regs *regs)
+-{
+-	int error;
+-	char * filename;
+-	
+-	filename = getname((char __user *) a0);
+-	error = PTR_ERR(filename);
+-	if (IS_ERR(filename))
+-		goto out;
+-	flush_fp_to_thread(current);
+-	flush_altivec_to_thread(current);
+-
+-	error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
+-
+-	if (error == 0) {
+-		task_lock(current);
+-		current->ptrace &= ~PT_DTRACE;
+-		task_unlock(current);
+-	}
+-	putname(filename);
+-
+-out:
+-	return error;
+-}
+-
+-/* Set up a thread for executing a new program. */
+-void start_thread32(struct pt_regs* regs, unsigned long nip, unsigned long sp)
+-{
+-	set_fs(USER_DS);
+-
+-	/*
+-	 * If we exec out of a kernel thread then thread.regs will not be
+-	 * set. Do it now.
+-	 */
+-	if (!current->thread.regs) {
+-		unsigned long childregs = (unsigned long)current->thread_info +
+-						THREAD_SIZE;
+-		childregs -= sizeof(struct pt_regs);
+-		current->thread.regs = (struct pt_regs *)childregs;
+-	}
+-
+-	/*
+-	 * ELF_PLAT_INIT already clears all registers but it also sets r2.
+-	 * So just clear r2 here.
+-	 */
+-	regs->gpr[2] = 0;
+-
+-	regs->nip = nip;
+-	regs->gpr[1] = sp;
+-	regs->msr = MSR_USER32;
+-#ifndef CONFIG_SMP
+-	if (last_task_used_math == current)
+-		last_task_used_math = 0;
+-#endif /* CONFIG_SMP */
+-	current->thread.fpscr = 0;
+-	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
+-#ifdef CONFIG_ALTIVEC
+-#ifndef CONFIG_SMP
+-	if (last_task_used_altivec == current)
+-		last_task_used_altivec = 0;
+-#endif /* CONFIG_SMP */
+-	memset(current->thread.vr, 0, sizeof(current->thread.vr));
+-	current->thread.vscr.u[0] = 0;
+-	current->thread.vscr.u[1] = 0;
+-	current->thread.vscr.u[2] = 0;
+-	current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
+-	current->thread.vrsave = 0;
+-	current->thread.used_vr = 0;
+-#endif /* CONFIG_ALTIVEC */
+-}
+-
+-/* Note: it is necessary to treat option as an unsigned int, 
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
+-{
+-	return sys_prctl((int)option,
+-			 (unsigned long) arg2,
+-			 (unsigned long) arg3,
+-			 (unsigned long) arg4,
+-			 (unsigned long) arg5);
+-}
+-
+-/* Note: it is necessary to treat pid as an unsigned int, 
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval)
+-{
+-	struct timespec t;
+-	int ret;
+-	mm_segment_t old_fs = get_fs ();
+-
+-	/* The __user pointer cast is valid because of the set_fs() */
+-	set_fs (KERNEL_DS);
+-	ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t);
+-	set_fs (old_fs);
+-	if (put_compat_timespec(&t, interval))
+-		return -EFAULT;
+-	return ret;
+-}
+-
+-asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
+-{
+-	return sys_pciconfig_read((unsigned long) bus,
+-				  (unsigned long) dfn,
+-				  (unsigned long) off,
+-				  (unsigned long) len,
+-				  compat_ptr(ubuf));
+-}
+-
+-asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
+-{
+-	return sys_pciconfig_write((unsigned long) bus,
+-				   (unsigned long) dfn,
+-				   (unsigned long) off,
+-				   (unsigned long) len,
+-				   compat_ptr(ubuf));
+-}
+-
+-asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
+-{
+-	return sys_pciconfig_iobase(which, in_bus, in_devfn);
+-}
+-
+-
+-/* Note: it is necessary to treat mode as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_access(const char __user * filename, u32 mode)
+-{
+-	return sys_access(filename, (int)mode);
+-}
+-
+-
+-/* Note: it is necessary to treat mode as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_creat(const char __user * pathname, u32 mode)
+-{
+-	return sys_creat(pathname, (int)mode);
+-}
+-
+-
+-/* Note: it is necessary to treat pid and options as unsigned ints,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options)
+-{
+-	return sys_waitpid((int)pid, stat_addr, (int)options);
+-}
+-
+-
+-/* Note: it is necessary to treat gidsetsize as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t __user *grouplist)
+-{
+-	return sys_getgroups((int)gidsetsize, grouplist);
+-}
+-
+-
+-/* Note: it is necessary to treat pid as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_getpgid(u32 pid)
+-{
+-	return sys_getpgid((int)pid);
+-}
+-
+-
+-
+-/* Note: it is necessary to treat pid as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_getsid(u32 pid)
+-{
+-	return sys_getsid((int)pid);
+-}
+-
+-
+-/* Note: it is necessary to treat pid and sig as unsigned ints,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_kill(u32 pid, u32 sig)
+-{
+-	return sys_kill((int)pid, (int)sig);
+-}
+-
+-
+-/* Note: it is necessary to treat mode as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_mkdir(const char __user * pathname, u32 mode)
+-{
+-	return sys_mkdir(pathname, (int)mode);
+-}
+-
+-long sys32_nice(u32 increment)
+-{
+-	/* sign extend increment */
+-	return sys_nice((int)increment);
+-}
+-
+-off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin)
+-{
+-	/* sign extend n */
+-	return sys_lseek(fd, (int)offset, origin);
+-}
+-
+-/* Note: it is necessary to treat bufsiz as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_readlink(const char __user * path, char __user * buf, u32 bufsiz)
+-{
+-	return sys_readlink(path, buf, (int)bufsiz);
+-}
+-
+-/* Note: it is necessary to treat option as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_sched_get_priority_max(u32 policy)
+-{
+-	return sys_sched_get_priority_max((int)policy);
+-}
+-
+-
+-/* Note: it is necessary to treat policy as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_sched_get_priority_min(u32 policy)
+-{
+-	return sys_sched_get_priority_min((int)policy);
+-}
+-
+-
+-/* Note: it is necessary to treat pid as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param __user *param)
+-{
+-	return sys_sched_getparam((int)pid, param);
+-}
+-
+-
+-/* Note: it is necessary to treat pid as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_sched_getscheduler(u32 pid)
+-{
+-	return sys_sched_getscheduler((int)pid);
+-}
+-
+-
+-/* Note: it is necessary to treat pid as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param __user *param)
+-{
+-	return sys_sched_setparam((int)pid, param);
+-}
+-
+-
+-/* Note: it is necessary to treat pid and policy as unsigned ints,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param)
+-{
+-	return sys_sched_setscheduler((int)pid, (int)policy, param);
+-}
+-
+-
+-/* Note: it is necessary to treat len as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_setdomainname(char __user *name, u32 len)
+-{
+-	return sys_setdomainname(name, (int)len);
+-}
+-
+-
+-/* Note: it is necessary to treat gidsetsize as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_setgroups(u32 gidsetsize, gid_t __user *grouplist)
+-{
+-	return sys_setgroups((int)gidsetsize, grouplist);
+-}
+-
+-
+-asmlinkage long sys32_sethostname(char __user *name, u32 len)
+-{
+-	/* sign extend len */
+-	return sys_sethostname(name, (int)len);
+-}
+-
+-
+-/* Note: it is necessary to treat pid and pgid as unsigned ints,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_setpgid(u32 pid, u32 pgid)
+-{
+-	return sys_setpgid((int)pid, (int)pgid);
+-}
+-
+-long sys32_getpriority(u32 which, u32 who)
+-{
+-	/* sign extend which and who */
+-	return sys_getpriority((int)which, (int)who);
+-}
+-
+-long sys32_setpriority(u32 which, u32 who, u32 niceval)
+-{
+-	/* sign extend which, who and niceval */
+-	return sys_setpriority((int)which, (int)who, (int)niceval);
+-}
+-
+-long sys32_ioprio_get(u32 which, u32 who)
+-{
+-	/* sign extend which and who */
+-	return sys_ioprio_get((int)which, (int)who);
+-}
+-
+-long sys32_ioprio_set(u32 which, u32 who, u32 ioprio)
+-{
+-	/* sign extend which, who and ioprio */
+-	return sys_ioprio_set((int)which, (int)who, (int)ioprio);
+-}
+-
+-/* Note: it is necessary to treat newmask as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_ssetmask(u32 newmask)
+-{
+-	return sys_ssetmask((int) newmask);
+-}
+-
+-asmlinkage long sys32_syslog(u32 type, char __user * buf, u32 len)
+-{
+-	/* sign extend len */
+-	return sys_syslog(type, buf, (int)len);
+-}
+-
+-
+-/* Note: it is necessary to treat mask as an unsigned int,
+- * with the corresponding cast to a signed int to insure that the 
+- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
+- * and the register representation of a signed int (msr in 64-bit mode) is performed.
+- */
+-asmlinkage long sys32_umask(u32 mask)
+-{
+-	return sys_umask((int)mask);
+-}
+-
+-#ifdef CONFIG_SYSCTL
+-struct __sysctl_args32 {
+-	u32 name;
+-	int nlen;
+-	u32 oldval;
+-	u32 oldlenp;
+-	u32 newval;
+-	u32 newlen;
+-	u32 __unused[4];
+-};
+-
+-asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
+-{
+-	struct __sysctl_args32 tmp;
+-	int error;
+-	size_t oldlen;
+-	size_t __user *oldlenp = NULL;
+-	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
+-
+-	if (copy_from_user(&tmp, args, sizeof(tmp)))
+-		return -EFAULT;
+-
+-	if (tmp.oldval && tmp.oldlenp) {
+-		/* Duh, this is ugly and might not work if sysctl_args
+-		   is in read-only memory, but do_sysctl does indirectly
+-		   a lot of uaccess in both directions and we'd have to
+-		   basically copy the whole sysctl.c here, and
+-		   glibc's __sysctl uses rw memory for the structure
+-		   anyway.  */
+-		oldlenp = (size_t __user *)addr;
+-		if (get_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) ||
+-		    put_user(oldlen, oldlenp))
+-			return -EFAULT;
+-	}
+-
+-	lock_kernel();
+-	error = do_sysctl(compat_ptr(tmp.name), tmp.nlen,
+-			  compat_ptr(tmp.oldval), oldlenp,
+-			  compat_ptr(tmp.newval), tmp.newlen);
+-	unlock_kernel();
+-	if (oldlenp) {
+-		if (!error) {
+-			if (get_user(oldlen, oldlenp) ||
+-			    put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)))
+-				error = -EFAULT;
+-		}
+-		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
+-	}
+-	return error;
+-}
+-#endif
+-
+-asmlinkage int sys32_uname(struct old_utsname __user * name)
+-{
+-	int err = 0;
+-	
+-	down_read(&uts_sem);
+-	if (copy_to_user(name, &system_utsname, sizeof(*name)))
+-		err = -EFAULT;
+-	up_read(&uts_sem);
+-	if (!err && personality(current->personality) == PER_LINUX32) {
+-		/* change "ppc64" to "ppc" */
+-		if (__put_user(0, name->machine + 3)
+-		    || __put_user(0, name->machine + 4))
+-			err = -EFAULT;
+-	}
+-	return err;
+-}
+-
+-asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
+-{
+-	int error;
+-
+-	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+-		return -EFAULT;
+-  
+-	down_read(&uts_sem);
+-	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
+-	error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
+-	error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+-	error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
+-	error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+-	error |= __put_user(0,name->release+__OLD_UTS_LEN);
+-	error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+-	error |= __put_user(0,name->version+__OLD_UTS_LEN);
+-	error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+-	error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+-	if (personality(current->personality) == PER_LINUX32) {
+-		/* change "ppc64" to "ppc" */
+-		error |= __put_user(0, name->machine + 3);
+-		error |= __put_user(0, name->machine + 4);
+-	}
+-	
+-	up_read(&uts_sem);
+-
+-	error = error ? -EFAULT : 0;
+-	
+-	return error;
+-}
+-
+-unsigned long sys32_mmap2(unsigned long addr, size_t len,
+-			  unsigned long prot, unsigned long flags,
+-			  unsigned long fd, unsigned long pgoff)
+-{
+-	/* This should remain 12 even if PAGE_SIZE changes */
+-	return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
+-}
+-
+-int get_compat_timeval(struct timeval *tv, struct compat_timeval __user *ctv)
+-{
+-	return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
+-		__get_user(tv->tv_sec, &ctv->tv_sec) ||
+-		__get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
+-}
+-
+-asmlinkage long sys32_utimes(char __user *filename, struct compat_timeval __user *tvs)
+-{
+-	struct timeval ktvs[2], *ptr;
+-
+-	ptr = NULL;
+-	if (tvs) {
+-		if (get_compat_timeval(&ktvs[0], &tvs[0]) ||
+-		    get_compat_timeval(&ktvs[1], &tvs[1]))
+-			return -EFAULT;
+-		ptr = ktvs;
+-	}
+-
+-	return do_utimes(filename, ptr);
+-}
+-
+-long sys32_tgkill(u32 tgid, u32 pid, int sig)
+-{
+-	/* sign extend tgid, pid */
+-	return sys_tgkill((int)tgid, (int)pid, sig);
+-}
+-
+-/* 
+- * long long munging:
+- * The 32 bit ABI passes long longs in an odd even register pair.
+- */
+-
+-compat_ssize_t sys32_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
+-			     u32 reg6, u32 poshi, u32 poslo)
+-{
+-	return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
+-}
+-
+-compat_ssize_t sys32_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count,
+-			      u32 reg6, u32 poshi, u32 poslo)
+-{
+-	return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
+-}
+-
+-compat_ssize_t sys32_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
+-{
+-	return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count);
+-}
+-
+-asmlinkage int sys32_truncate64(const char __user * path, u32 reg4,
+-				unsigned long high, unsigned long low)
+-{
+-	return sys_truncate(path, (high << 32) | low);
+-}
+-
+-asmlinkage int sys32_ftruncate64(unsigned int fd, u32 reg4, unsigned long high,
+-				 unsigned long low)
+-{
+-	return sys_ftruncate(fd, (high << 32) | low);
+-}
+-
+-long ppc32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf,
+-			  size_t len)
+-{
+-	return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
+-				  buf, len);
+-}
+-
+-long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low,
+-		     size_t len, int advice)
+-{
+-	return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, len,
+-			     advice);
+-}
+-
+-long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
+-			u32 len_high, u32 len_low)
+-{
+-	return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low,
+-			     (u64)len_high << 32 | len_low, advice);
+-}
+-
+-long ppc32_timer_create(clockid_t clock,
+-			struct compat_sigevent __user *ev32,
+-			timer_t __user *timer_id)
+-{
+-	sigevent_t event;
+-	timer_t t;
+-	long err;
+-	mm_segment_t savefs;
+-
+-	if (ev32 == NULL)
+-		return sys_timer_create(clock, NULL, timer_id);
+-
+-	if (get_compat_sigevent(&event, ev32))
+-		return -EFAULT;
+-
+-	if (!access_ok(VERIFY_WRITE, timer_id, sizeof(timer_t)))
+-		return -EFAULT;
+-
+-	savefs = get_fs();
+-	set_fs(KERNEL_DS);
+-	/* The __user pointer casts are valid due to the set_fs() */
+-	err = sys_timer_create(clock,
+-		(sigevent_t __user *) &event,
+-		(timer_t __user *) &t);
+-	set_fs(savefs);
+-
+-	if (err == 0)
+-		err = __put_user(t, timer_id);
+-
+-	return err;
+-}
+-
+-asmlinkage long sys32_add_key(const char __user *_type,
+-			      const char __user *_description,
+-			      const void __user *_payload,
+-			      u32 plen,
+-			      u32 ringid)
+-{
+-	return sys_add_key(_type, _description, _payload, plen, ringid);
+-}
+-
+-asmlinkage long sys32_request_key(const char __user *_type,
+-				  const char __user *_description,
+-				  const char __user *_callout_info,
+-				  u32 destringid)
+-{
+-	return sys_request_key(_type, _description, _callout_info, destringid);
+-}
+-
+diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/syscalls.c
++++ /dev/null
+@@ -1,263 +0,0 @@
+-/*
+- * linux/arch/ppc64/kernel/sys_ppc.c
+- *
+- *  PowerPC version 
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- * Derived from "arch/i386/kernel/sys_i386.c"
+- * Adapted from the i386 version by Gary Thomas
+- * Modified by Cort Dougan (cort at cs.nmt.edu)
+- * and Paul Mackerras (paulus at cs.anu.edu.au).
+- *
+- * This file contains various random system calls that
+- * have a non-standard calling sequence on the Linux/PPC
+- * platform.
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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/sched.h>
+-#include <linux/syscalls.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/smp_lock.h>
+-#include <linux/sem.h>
+-#include <linux/msg.h>
+-#include <linux/shm.h>
+-#include <linux/stat.h>
+-#include <linux/mman.h>
+-#include <linux/sys.h>
+-#include <linux/ipc.h>
+-#include <linux/utsname.h>
+-#include <linux/file.h>
+-#include <linux/init.h>
+-#include <linux/personality.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/ipc.h>
+-#include <asm/semaphore.h>
+-#include <asm/time.h>
+-#include <asm/unistd.h>
+-
+-extern unsigned long wall_jiffies;
+-
+-
+-/*
+- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+- *
+- * This is really horribly ugly.
+- */
+-asmlinkage int 
+-sys_ipc (uint call, int first, unsigned long second, long third,
+-	 void __user *ptr, long fifth)
+-{
+-	int version, ret;
+-
+-	version = call >> 16; /* hack for backward compatibility */
+-	call &= 0xffff;
+-
+-	ret = -ENOSYS;
+-	switch (call) {
+-	case SEMOP:
+-		ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
+-				      (unsigned)second, NULL);
+-		break;
+-	case SEMTIMEDOP:
+-		ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
+-				      (unsigned)second,
+-				      (const struct timespec __user *) fifth);
+-		break;
+-	case SEMGET:
+-		ret = sys_semget (first, (int)second, third);
+-		break;
+-	case SEMCTL: {
+-		union semun fourth;
+-
+-		ret = -EINVAL;
+-		if (!ptr)
+-			break;
+-		if ((ret = get_user(fourth.__pad, (void __user * __user *)ptr)))
+-			break;
+-		ret = sys_semctl(first, (int)second, third, fourth);
+-		break;
+-	}
+-	case MSGSND:
+-		ret = sys_msgsnd(first, (struct msgbuf __user *)ptr,
+-				  (size_t)second, third);
+-		break;
+-	case MSGRCV:
+-		switch (version) {
+-		case 0: {
+-			struct ipc_kludge tmp;
+-
+-			ret = -EINVAL;
+-			if (!ptr)
+-				break;
+-			if ((ret = copy_from_user(&tmp,
+-						(struct ipc_kludge __user *) ptr,
+-						sizeof (tmp)) ? -EFAULT : 0))
+-				break;
+-			ret = sys_msgrcv(first, tmp.msgp, (size_t) second,
+-					  tmp.msgtyp, third);
+-			break;
+-		}
+-		default:
+-			ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
+-					  (size_t)second, fifth, third);
+-			break;
+-		}
+-		break;
+-	case MSGGET:
+-		ret = sys_msgget ((key_t)first, (int)second);
+-		break;
+-	case MSGCTL:
+-		ret = sys_msgctl(first, (int)second,
+-				  (struct msqid_ds __user *)ptr);
+-		break;
+-	case SHMAT:
+-		switch (version) {
+-		default: {
+-			ulong raddr;
+-			ret = do_shmat(first, (char __user *) ptr,
+-					(int)second, &raddr);
+-			if (ret)
+-				break;
+-			ret = put_user (raddr, (ulong __user *) third);
+-			break;
+-		}
+-		case 1:	/* iBCS2 emulator entry point */
+-			ret = -EINVAL;
+-			if (!segment_eq(get_fs(), get_ds()))
+-				break;
+-			ret = do_shmat(first, (char __user *)ptr,
+-					(int)second, (ulong *)third);
+-			break;
+-		}
+-		break;
+-	case SHMDT: 
+-		ret = sys_shmdt ((char __user *)ptr);
+-		break;
+-	case SHMGET:
+-		ret = sys_shmget (first, (size_t)second, third);
+-		break;
+-	case SHMCTL:
+-		ret = sys_shmctl(first, (int)second,
+-				  (struct shmid_ds __user *)ptr);
+-		break;
+-	}
+-
+-	return ret;
+-}
+-
+-/*
+- * sys_pipe() is the normal C calling standard for creating
+- * a pipe. It's not the way unix traditionally does this, though.
+- */
+-asmlinkage int sys_pipe(int __user *fildes)
+-{
+-	int fd[2];
+-	int error;
+-	
+-	error = do_pipe(fd);
+-	if (!error) {
+-		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+-			error = -EFAULT;
+-	}
+-	
+-	return error;
+-}
+-
+-unsigned long sys_mmap(unsigned long addr, size_t len,
+-		       unsigned long prot, unsigned long flags,
+-		       unsigned long fd, off_t offset)
+-{
+-	struct file * file = NULL;
+-	unsigned long ret = -EBADF;
+-
+-	if (!(flags & MAP_ANONYMOUS)) {
+-		if (!(file = fget(fd)))
+-			goto out;
+-	}
+-
+-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-	down_write(&current->mm->mmap_sem);
+-	ret = do_mmap(file, addr, len, prot, flags, offset);
+-	up_write(&current->mm->mmap_sem);
+-	if (file)
+-		fput(file);
+-
+-out:
+-	return ret;
+-}
+-
+-long ppc64_personality(unsigned long personality)
+-{
+-	long ret;
+-
+-	if (personality(current->personality) == PER_LINUX32
+-	    && personality == PER_LINUX)
+-		personality = PER_LINUX32;
+-	ret = sys_personality(personality);
+-	if (ret == PER_LINUX32)
+-		ret = PER_LINUX;
+-	return ret;
+-}
+-
+-long ppc64_newuname(struct new_utsname __user * name)
+-{
+-	int err = 0;
+-
+-	down_read(&uts_sem);
+-	if (copy_to_user(name, &system_utsname, sizeof(*name)))
+-		err = -EFAULT;
+-	up_read(&uts_sem);
+-	if (!err && personality(current->personality) == PER_LINUX32) {
+-		/* change ppc64 to ppc */
+-		if (__put_user(0, name->machine + 3)
+-		    || __put_user(0, name->machine + 4))
+-			err = -EFAULT;
+-	}
+-	return err;
+-}
+-
+-asmlinkage time_t sys64_time(time_t __user * tloc)
+-{
+-	time_t secs;
+-	time_t usecs;
+-
+-	long tb_delta = tb_ticks_since(tb_last_stamp);
+-	tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
+-
+-	secs  = xtime.tv_sec;  
+-	usecs = (xtime.tv_nsec/1000) + tb_delta / tb_ticks_per_usec;
+-	while (usecs >= USEC_PER_SEC) {
+-		++secs;
+-		usecs -= USEC_PER_SEC;
+-	}
+-
+-	if (tloc) {
+-		if (put_user(secs,tloc))
+-			secs = -EFAULT;
+-	}
+-
+-	return secs;
+-}
+-
+-void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5,
+-		     unsigned long r6, unsigned long r7, unsigned long r8,
+-		     struct pt_regs *regs)
+-{
+-	printk("syscall %ld(%lx, %lx, %lx, %lx, %lx, %lx) regs=%p current=%p"
+-	       " cpu=%d\n", regs->gpr[0], r3, r4, r5, r6, r7, r8, regs,
+-	       current, smp_processor_id());
+-}
+-
+-void do_show_syscall_exit(unsigned long r3)
+-{
+-	printk(" -> %lx, current=%p cpu=%d\n", r3, current, smp_processor_id());
+-}
+diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/time.c
++++ /dev/null
+@@ -1,881 +0,0 @@
+-/*
+- * 
+- * Common time routines among all ppc machines.
+- *
+- * Written by Cort Dougan (cort at cs.nmt.edu) to merge
+- * Paul Mackerras' version and mine for PReP and Pmac.
+- * MPC8xx/MBX changes by Dan Malek (dmalek at jlc.net).
+- * Converted for 64-bit by Mike Corrigan (mikejc at us.ibm.com)
+- *
+- * First round of bugfixes by Gabriel Paubert (paubert at iram.es)
+- * to make clock more stable (2.4.0-test5). The only thing
+- * that this code assumes is that the timebases have been synchronized
+- * by firmware on SMP and are never stopped (never do sleep
+- * on SMP then, nap and doze are OK).
+- * 
+- * Speeded up do_gettimeofday by getting rid of references to
+- * xtime (which required locks for consistency). (mikejc at us.ibm.com)
+- *
+- * TODO (not necessarily in this file):
+- * - improve precision and reproducibility of timebase frequency
+- * measurement at boot time. (for iSeries, we calibrate the timebase
+- * against the Titan chip's clock.)
+- * - for astronomical applications: add a new function to get
+- * non ambiguous timestamps even around leap seconds. This needs
+- * a new timestamp format and a good name.
+- *
+- * 1997-09-10  Updated NTP code according to technical memorandum Jan '96
+- *             "A Kernel Model for Precision Timekeeping" by Dave Mills
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/errno.h>
+-#include <linux/module.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/param.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
+-#include <linux/interrupt.h>
+-#include <linux/timex.h>
+-#include <linux/kernel_stat.h>
+-#include <linux/mc146818rtc.h>
+-#include <linux/time.h>
+-#include <linux/init.h>
+-#include <linux/profile.h>
+-#include <linux/cpu.h>
+-#include <linux/security.h>
+-
+-#include <asm/io.h>
+-#include <asm/processor.h>
+-#include <asm/nvram.h>
+-#include <asm/cache.h>
+-#include <asm/machdep.h>
+-#ifdef CONFIG_PPC_ISERIES
+-#include <asm/iSeries/ItLpQueue.h>
+-#include <asm/iSeries/HvCallXm.h>
+-#endif
+-#include <asm/uaccess.h>
+-#include <asm/time.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/prom.h>
+-#include <asm/sections.h>
+-#include <asm/systemcfg.h>
+-#include <asm/firmware.h>
+-
+-u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+-/* keep track of when we need to update the rtc */
+-time_t last_rtc_update;
+-extern int piranha_simulator;
+-#ifdef CONFIG_PPC_ISERIES
+-unsigned long iSeries_recal_titan = 0;
+-unsigned long iSeries_recal_tb = 0; 
+-static unsigned long first_settimeofday = 1;
+-#endif
+-
+-#define XSEC_PER_SEC (1024*1024)
+-
+-unsigned long tb_ticks_per_jiffy;
+-unsigned long tb_ticks_per_usec = 100; /* sane default */
+-EXPORT_SYMBOL(tb_ticks_per_usec);
+-unsigned long tb_ticks_per_sec;
+-unsigned long tb_to_xs;
+-unsigned      tb_to_us;
+-unsigned long processor_freq;
+-DEFINE_SPINLOCK(rtc_lock);
+-EXPORT_SYMBOL_GPL(rtc_lock);
+-
+-unsigned long tb_to_ns_scale;
+-unsigned long tb_to_ns_shift;
+-
+-struct gettimeofday_struct do_gtod;
+-
+-extern unsigned long wall_jiffies;
+-extern int smp_tb_synchronized;
+-
+-extern struct timezone sys_tz;
+-
+-void ppc_adjtimex(void);
+-
+-static unsigned adjusting_time = 0;
+-
+-unsigned long ppc_proc_freq;
+-unsigned long ppc_tb_freq;
+-
+-static __inline__ void timer_check_rtc(void)
+-{
+-        /*
+-         * update the rtc when needed, this should be performed on the
+-         * right fraction of a second. Half or full second ?
+-         * Full second works on mk48t59 clocks, others need testing.
+-         * Note that this update is basically only used through 
+-         * the adjtimex system calls. Setting the HW clock in
+-         * any other way is a /dev/rtc and userland business.
+-         * This is still wrong by -0.5/+1.5 jiffies because of the
+-         * timer interrupt resolution and possible delay, but here we 
+-         * hit a quantization limit which can only be solved by higher
+-         * resolution timers and decoupling time management from timer
+-         * interrupts. This is also wrong on the clocks
+-         * which require being written at the half second boundary.
+-         * We should have an rtc call that only sets the minutes and
+-         * seconds like on Intel to avoid problems with non UTC clocks.
+-         */
+-        if (ntp_synced() &&
+-             xtime.tv_sec - last_rtc_update >= 659 &&
+-             abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ &&
+-             jiffies - wall_jiffies == 1) {
+-	    struct rtc_time tm;
+-	    to_tm(xtime.tv_sec+1, &tm);
+-	    tm.tm_year -= 1900;
+-	    tm.tm_mon -= 1;
+-            if (ppc_md.set_rtc_time(&tm) == 0)
+-                last_rtc_update = xtime.tv_sec+1;
+-            else
+-                /* Try again one minute later */
+-                last_rtc_update += 60;
+-        }
+-}
+-
+-/*
+- * This version of gettimeofday has microsecond resolution.
+- */
+-static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val)
+-{
+-	unsigned long sec, usec, tb_ticks;
+-	unsigned long xsec, tb_xsec;
+-	struct gettimeofday_vars * temp_varp;
+-	unsigned long temp_tb_to_xs, temp_stamp_xsec;
+-
+-	/*
+-	 * These calculations are faster (gets rid of divides)
+-	 * if done in units of 1/2^20 rather than microseconds.
+-	 * The conversion to microseconds at the end is done
+-	 * without a divide (and in fact, without a multiply)
+-	 */
+-	temp_varp = do_gtod.varp;
+-	tb_ticks = tb_val - temp_varp->tb_orig_stamp;
+-	temp_tb_to_xs = temp_varp->tb_to_xs;
+-	temp_stamp_xsec = temp_varp->stamp_xsec;
+-	tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs );
+-	xsec = temp_stamp_xsec + tb_xsec;
+-	sec = xsec / XSEC_PER_SEC;
+-	xsec -= sec * XSEC_PER_SEC;
+-	usec = (xsec * USEC_PER_SEC)/XSEC_PER_SEC;
+-
+-	tv->tv_sec = sec;
+-	tv->tv_usec = usec;
+-}
+-
+-void do_gettimeofday(struct timeval *tv)
+-{
+-	__do_gettimeofday(tv, get_tb());
+-}
+-
+-EXPORT_SYMBOL(do_gettimeofday);
+-
+-/* Synchronize xtime with do_gettimeofday */ 
+-
+-static inline void timer_sync_xtime(unsigned long cur_tb)
+-{
+-	struct timeval my_tv;
+-
+-	__do_gettimeofday(&my_tv, cur_tb);
+-
+-	if (xtime.tv_sec <= my_tv.tv_sec) {
+-		xtime.tv_sec = my_tv.tv_sec;
+-		xtime.tv_nsec = my_tv.tv_usec * 1000;
+-	}
+-}
+-
+-/*
+- * When the timebase - tb_orig_stamp gets too big, we do a manipulation
+- * between tb_orig_stamp and stamp_xsec. The goal here is to keep the
+- * difference tb - tb_orig_stamp small enough to always fit inside a
+- * 32 bits number. This is a requirement of our fast 32 bits userland
+- * implementation in the vdso. If we "miss" a call to this function
+- * (interrupt latency, CPU locked in a spinlock, ...) and we end up
+- * with a too big difference, then the vdso will fallback to calling
+- * the syscall
+- */
+-static __inline__ void timer_recalc_offset(unsigned long cur_tb)
+-{
+-	struct gettimeofday_vars * temp_varp;
+-	unsigned temp_idx;
+-	unsigned long offset, new_stamp_xsec, new_tb_orig_stamp;
+-
+-	if (((cur_tb - do_gtod.varp->tb_orig_stamp) & 0x80000000u) == 0)
+-		return;
+-
+-	temp_idx = (do_gtod.var_idx == 0);
+-	temp_varp = &do_gtod.vars[temp_idx];
+-
+-	new_tb_orig_stamp = cur_tb;
+-	offset = new_tb_orig_stamp - do_gtod.varp->tb_orig_stamp;
+-	new_stamp_xsec = do_gtod.varp->stamp_xsec + mulhdu(offset, do_gtod.varp->tb_to_xs);
+-
+-	temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs;
+-	temp_varp->tb_orig_stamp = new_tb_orig_stamp;
+-	temp_varp->stamp_xsec = new_stamp_xsec;
+-	smp_mb();
+-	do_gtod.varp = temp_varp;
+-	do_gtod.var_idx = temp_idx;
+-
+-	++(systemcfg->tb_update_count);
+-	smp_wmb();
+-	systemcfg->tb_orig_stamp = new_tb_orig_stamp;
+-	systemcfg->stamp_xsec = new_stamp_xsec;
+-	smp_wmb();
+-	++(systemcfg->tb_update_count);
+-}
+-
+-#ifdef CONFIG_SMP
+-unsigned long profile_pc(struct pt_regs *regs)
+-{
+-	unsigned long pc = instruction_pointer(regs);
+-
+-	if (in_lock_functions(pc))
+-		return regs->link;
+-
+-	return pc;
+-}
+-EXPORT_SYMBOL(profile_pc);
+-#endif
+-
+-#ifdef CONFIG_PPC_ISERIES
+-
+-/* 
+- * This function recalibrates the timebase based on the 49-bit time-of-day
+- * value in the Titan chip.  The Titan is much more accurate than the value
+- * returned by the service processor for the timebase frequency.  
+- */
+-
+-static void iSeries_tb_recal(void)
+-{
+-	struct div_result divres;
+-	unsigned long titan, tb;
+-	tb = get_tb();
+-	titan = HvCallXm_loadTod();
+-	if ( iSeries_recal_titan ) {
+-		unsigned long tb_ticks = tb - iSeries_recal_tb;
+-		unsigned long titan_usec = (titan - iSeries_recal_titan) >> 12;
+-		unsigned long new_tb_ticks_per_sec   = (tb_ticks * USEC_PER_SEC)/titan_usec;
+-		unsigned long new_tb_ticks_per_jiffy = (new_tb_ticks_per_sec+(HZ/2))/HZ;
+-		long tick_diff = new_tb_ticks_per_jiffy - tb_ticks_per_jiffy;
+-		char sign = '+';		
+-		/* make sure tb_ticks_per_sec and tb_ticks_per_jiffy are consistent */
+-		new_tb_ticks_per_sec = new_tb_ticks_per_jiffy * HZ;
+-
+-		if ( tick_diff < 0 ) {
+-			tick_diff = -tick_diff;
+-			sign = '-';
+-		}
+-		if ( tick_diff ) {
+-			if ( tick_diff < tb_ticks_per_jiffy/25 ) {
+-				printk( "Titan recalibrate: new tb_ticks_per_jiffy = %lu (%c%ld)\n",
+-						new_tb_ticks_per_jiffy, sign, tick_diff );
+-				tb_ticks_per_jiffy = new_tb_ticks_per_jiffy;
+-				tb_ticks_per_sec   = new_tb_ticks_per_sec;
+-				div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres );
+-				do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
+-				tb_to_xs = divres.result_low;
+-				do_gtod.varp->tb_to_xs = tb_to_xs;
+-				systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
+-				systemcfg->tb_to_xs = tb_to_xs;
+-			}
+-			else {
+-				printk( "Titan recalibrate: FAILED (difference > 4 percent)\n"
+-					"                   new tb_ticks_per_jiffy = %lu\n"
+-					"                   old tb_ticks_per_jiffy = %lu\n",
+-					new_tb_ticks_per_jiffy, tb_ticks_per_jiffy );
+-			}
+-		}
+-	}
+-	iSeries_recal_titan = titan;
+-	iSeries_recal_tb = tb;
+-}
+-#endif
+-
+-/*
+- * For iSeries shared processors, we have to let the hypervisor
+- * set the hardware decrementer.  We set a virtual decrementer
+- * in the lppaca and call the hypervisor if the virtual
+- * decrementer is less than the current value in the hardware
+- * decrementer. (almost always the new decrementer value will
+- * be greater than the current hardware decementer so the hypervisor
+- * call will not be needed)
+- */
+-
+-unsigned long tb_last_stamp __cacheline_aligned_in_smp;
+-
+-/*
+- * timer_interrupt - gets called when the decrementer overflows,
+- * with interrupts disabled.
+- */
+-int timer_interrupt(struct pt_regs * regs)
+-{
+-	int next_dec;
+-	unsigned long cur_tb;
+-	struct paca_struct *lpaca = get_paca();
+-	unsigned long cpu = smp_processor_id();
+-
+-	irq_enter();
+-
+-	profile_tick(CPU_PROFILING, regs);
+-
+-	lpaca->lppaca.int_dword.fields.decr_int = 0;
+-
+-	while (lpaca->next_jiffy_update_tb <= (cur_tb = get_tb())) {
+-		/*
+-		 * We cannot disable the decrementer, so in the period
+-		 * between this cpu's being marked offline in cpu_online_map
+-		 * and calling stop-self, it is taking timer interrupts.
+-		 * Avoid calling into the scheduler rebalancing code if this
+-		 * is the case.
+-		 */
+-		if (!cpu_is_offline(cpu))
+-			update_process_times(user_mode(regs));
+-		/*
+-		 * No need to check whether cpu is offline here; boot_cpuid
+-		 * should have been fixed up by now.
+-		 */
+-		if (cpu == boot_cpuid) {
+-			write_seqlock(&xtime_lock);
+-			tb_last_stamp = lpaca->next_jiffy_update_tb;
+-			timer_recalc_offset(lpaca->next_jiffy_update_tb);
+-			do_timer(regs);
+-			timer_sync_xtime(lpaca->next_jiffy_update_tb);
+-			timer_check_rtc();
+-			write_sequnlock(&xtime_lock);
+-			if ( adjusting_time && (time_adjust == 0) )
+-				ppc_adjtimex();
+-		}
+-		lpaca->next_jiffy_update_tb += tb_ticks_per_jiffy;
+-	}
+-	
+-	next_dec = lpaca->next_jiffy_update_tb - cur_tb;
+-	if (next_dec > lpaca->default_decr)
+-        	next_dec = lpaca->default_decr;
+-	set_dec(next_dec);
+-
+-#ifdef CONFIG_PPC_ISERIES
+-	if (hvlpevent_is_pending())
+-		process_hvlpevents(regs);
+-#endif
+-
+-	/* collect purr register values often, for accurate calculations */
+-	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+-		struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
+-		cu->current_tb = mfspr(SPRN_PURR);
+-	}
+-
+-	irq_exit();
+-
+-	return 1;
+-}
+-
+-/*
+- * Scheduler clock - returns current time in nanosec units.
+- *
+- * Note: mulhdu(a, b) (multiply high double unsigned) returns
+- * the high 64 bits of a * b, i.e. (a * b) >> 64, where a and b
+- * are 64-bit unsigned numbers.
+- */
+-unsigned long long sched_clock(void)
+-{
+-	return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift;
+-}
+-
+-int do_settimeofday(struct timespec *tv)
+-{
+-	time_t wtm_sec, new_sec = tv->tv_sec;
+-	long wtm_nsec, new_nsec = tv->tv_nsec;
+-	unsigned long flags;
+-	unsigned long delta_xsec;
+-	long int tb_delta;
+-	unsigned long new_xsec;
+-
+-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+-		return -EINVAL;
+-
+-	write_seqlock_irqsave(&xtime_lock, flags);
+-	/* Updating the RTC is not the job of this code. If the time is
+-	 * stepped under NTP, the RTC will be update after STA_UNSYNC
+-	 * is cleared. Tool like clock/hwclock either copy the RTC
+-	 * to the system time, in which case there is no point in writing
+-	 * to the RTC again, or write to the RTC but then they don't call
+-	 * settimeofday to perform this operation.
+-	 */
+-#ifdef CONFIG_PPC_ISERIES
+-	if ( first_settimeofday ) {
+-		iSeries_tb_recal();
+-		first_settimeofday = 0;
+-	}
+-#endif
+-	tb_delta = tb_ticks_since(tb_last_stamp);
+-	tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
+-
+-	new_nsec -= tb_delta / tb_ticks_per_usec / 1000;
+-
+-	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec);
+-	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec);
+-
+- 	set_normalized_timespec(&xtime, new_sec, new_nsec);
+-	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+-
+-	/* In case of a large backwards jump in time with NTP, we want the 
+-	 * clock to be updated as soon as the PLL is again in lock.
+-	 */
+-	last_rtc_update = new_sec - 658;
+-
+-	ntp_clear();
+-
+-	delta_xsec = mulhdu( (tb_last_stamp-do_gtod.varp->tb_orig_stamp),
+-			     do_gtod.varp->tb_to_xs );
+-
+-	new_xsec = (new_nsec * XSEC_PER_SEC) / NSEC_PER_SEC;
+-	new_xsec += new_sec * XSEC_PER_SEC;
+-	if ( new_xsec > delta_xsec ) {
+-		do_gtod.varp->stamp_xsec = new_xsec - delta_xsec;
+-		systemcfg->stamp_xsec = new_xsec - delta_xsec;
+-	}
+-	else {
+-		/* This is only for the case where the user is setting the time
+-		 * way back to a time such that the boot time would have been
+-		 * before 1970 ... eg. we booted ten days ago, and we are setting
+-		 * the time to Jan 5, 1970 */
+-		do_gtod.varp->stamp_xsec = new_xsec;
+-		do_gtod.varp->tb_orig_stamp = tb_last_stamp;
+-		systemcfg->stamp_xsec = new_xsec;
+-		systemcfg->tb_orig_stamp = tb_last_stamp;
+-	}
+-
+-	systemcfg->tz_minuteswest = sys_tz.tz_minuteswest;
+-	systemcfg->tz_dsttime = sys_tz.tz_dsttime;
+-
+-	write_sequnlock_irqrestore(&xtime_lock, flags);
+-	clock_was_set();
+-	return 0;
+-}
+-
+-EXPORT_SYMBOL(do_settimeofday);
+-
+-#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA)
+-void __init generic_calibrate_decr(void)
+-{
+-	struct device_node *cpu;
+-	struct div_result divres;
+-	unsigned int *fp;
+-	int node_found;
+-
+-	/*
+-	 * The cpu node should have a timebase-frequency property
+-	 * to tell us the rate at which the decrementer counts.
+-	 */
+-	cpu = of_find_node_by_type(NULL, "cpu");
+-
+-	ppc_tb_freq = DEFAULT_TB_FREQ;		/* hardcoded default */
+-	node_found = 0;
+-	if (cpu != 0) {
+-		fp = (unsigned int *)get_property(cpu, "timebase-frequency",
+-						  NULL);
+-		if (fp != 0) {
+-			node_found = 1;
+-			ppc_tb_freq = *fp;
+-		}
+-	}
+-	if (!node_found)
+-		printk(KERN_ERR "WARNING: Estimating decrementer frequency "
+-				"(not found)\n");
+-
+-	ppc_proc_freq = DEFAULT_PROC_FREQ;
+-	node_found = 0;
+-	if (cpu != 0) {
+-		fp = (unsigned int *)get_property(cpu, "clock-frequency",
+-						  NULL);
+-		if (fp != 0) {
+-			node_found = 1;
+-			ppc_proc_freq = *fp;
+-		}
+-	}
+-	if (!node_found)
+-		printk(KERN_ERR "WARNING: Estimating processor frequency "
+-				"(not found)\n");
+-
+-	of_node_put(cpu);
+-
+-	printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
+-	       ppc_tb_freq/1000000, ppc_tb_freq%1000000);
+-	printk(KERN_INFO "time_init: processor frequency   = %lu.%.6lu MHz\n",
+-	       ppc_proc_freq/1000000, ppc_proc_freq%1000000);
+-
+-	tb_ticks_per_jiffy = ppc_tb_freq / HZ;
+-	tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
+-	tb_ticks_per_usec = ppc_tb_freq / 1000000;
+-	tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
+-	div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
+-	tb_to_xs = divres.result_low;
+-
+-	setup_default_decr();
+-}
+-#endif
+-
+-void __init time_init(void)
+-{
+-	/* This function is only called on the boot processor */
+-	unsigned long flags;
+-	struct rtc_time tm;
+-	struct div_result res;
+-	unsigned long scale, shift;
+-
+-	ppc_md.calibrate_decr();
+-
+-	/*
+-	 * Compute scale factor for sched_clock.
+-	 * The calibrate_decr() function has set tb_ticks_per_sec,
+-	 * which is the timebase frequency.
+-	 * We compute 1e9 * 2^64 / tb_ticks_per_sec and interpret
+-	 * the 128-bit result as a 64.64 fixed-point number.
+-	 * We then shift that number right until it is less than 1.0,
+-	 * giving us the scale factor and shift count to use in
+-	 * sched_clock().
+-	 */
+-	div128_by_32(1000000000, 0, tb_ticks_per_sec, &res);
+-	scale = res.result_low;
+-	for (shift = 0; res.result_high != 0; ++shift) {
+-		scale = (scale >> 1) | (res.result_high << 63);
+-		res.result_high >>= 1;
+-	}
+-	tb_to_ns_scale = scale;
+-	tb_to_ns_shift = shift;
+-
+-#ifdef CONFIG_PPC_ISERIES
+-	if (!piranha_simulator)
+-#endif
+-		ppc_md.get_boot_time(&tm);
+-
+-	write_seqlock_irqsave(&xtime_lock, flags);
+-	xtime.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+-			      tm.tm_hour, tm.tm_min, tm.tm_sec);
+-	tb_last_stamp = get_tb();
+-	do_gtod.varp = &do_gtod.vars[0];
+-	do_gtod.var_idx = 0;
+-	do_gtod.varp->tb_orig_stamp = tb_last_stamp;
+-	get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
+-	do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
+-	do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
+-	do_gtod.varp->tb_to_xs = tb_to_xs;
+-	do_gtod.tb_to_us = tb_to_us;
+-	systemcfg->tb_orig_stamp = tb_last_stamp;
+-	systemcfg->tb_update_count = 0;
+-	systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
+-	systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
+-	systemcfg->tb_to_xs = tb_to_xs;
+-
+-	time_freq = 0;
+-
+-	xtime.tv_nsec = 0;
+-	last_rtc_update = xtime.tv_sec;
+-	set_normalized_timespec(&wall_to_monotonic,
+-	                        -xtime.tv_sec, -xtime.tv_nsec);
+-	write_sequnlock_irqrestore(&xtime_lock, flags);
+-
+-	/* Not exact, but the timer interrupt takes care of this */
+-	set_dec(tb_ticks_per_jiffy);
+-}
+-
+-/* 
+- * After adjtimex is called, adjust the conversion of tb ticks
+- * to microseconds to keep do_gettimeofday synchronized 
+- * with ntpd.
+- *
+- * Use the time_adjust, time_freq and time_offset computed by adjtimex to 
+- * adjust the frequency.
+- */
+-
+-/* #define DEBUG_PPC_ADJTIMEX 1 */
+-
+-void ppc_adjtimex(void)
+-{
+-	unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec, new_tb_to_xs, new_xsec, new_stamp_xsec;
+-	unsigned long tb_ticks_per_sec_delta;
+-	long delta_freq, ltemp;
+-	struct div_result divres; 
+-	unsigned long flags;
+-	struct gettimeofday_vars * temp_varp;
+-	unsigned temp_idx;
+-	long singleshot_ppm = 0;
+-
+-	/* Compute parts per million frequency adjustment to accomplish the time adjustment
+-	   implied by time_offset to be applied over the elapsed time indicated by time_constant.
+-	   Use SHIFT_USEC to get it into the same units as time_freq. */
+-	if ( time_offset < 0 ) {
+-		ltemp = -time_offset;
+-		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
+-		ltemp >>= SHIFT_KG + time_constant;
+-		ltemp = -ltemp;
+-	}
+-	else {
+-		ltemp = time_offset;
+-		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
+-		ltemp >>= SHIFT_KG + time_constant;
+-	}
+-	
+-	/* If there is a single shot time adjustment in progress */
+-	if ( time_adjust ) {
+-#ifdef DEBUG_PPC_ADJTIMEX
+-		printk("ppc_adjtimex: ");
+-		if ( adjusting_time == 0 )
+-			printk("starting ");
+-		printk("single shot time_adjust = %ld\n", time_adjust);
+-#endif	
+-	
+-		adjusting_time = 1;
+-		
+-		/* Compute parts per million frequency adjustment to match time_adjust */
+-		singleshot_ppm = tickadj * HZ;	
+-		/*
+-		 * The adjustment should be tickadj*HZ to match the code in
+-		 * linux/kernel/timer.c, but experiments show that this is too
+-		 * large. 3/4 of tickadj*HZ seems about right
+-		 */
+-		singleshot_ppm -= singleshot_ppm / 4;
+-		/* Use SHIFT_USEC to get it into the same units as time_freq */	
+-		singleshot_ppm <<= SHIFT_USEC;
+-		if ( time_adjust < 0 )
+-			singleshot_ppm = -singleshot_ppm;
+-	}
+-	else {
+-#ifdef DEBUG_PPC_ADJTIMEX
+-		if ( adjusting_time )
+-			printk("ppc_adjtimex: ending single shot time_adjust\n");
+-#endif
+-		adjusting_time = 0;
+-	}
+-	
+-	/* Add up all of the frequency adjustments */
+-	delta_freq = time_freq + ltemp + singleshot_ppm;
+-	
+-	/* Compute a new value for tb_ticks_per_sec based on the frequency adjustment */
+-	den = 1000000 * (1 << (SHIFT_USEC - 8));
+-	if ( delta_freq < 0 ) {
+-		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( (-delta_freq) >> (SHIFT_USEC - 8))) / den;
+-		new_tb_ticks_per_sec = tb_ticks_per_sec + tb_ticks_per_sec_delta;
+-	}
+-	else {
+-		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( delta_freq >> (SHIFT_USEC - 8))) / den;
+-		new_tb_ticks_per_sec = tb_ticks_per_sec - tb_ticks_per_sec_delta;
+-	}
+-	
+-#ifdef DEBUG_PPC_ADJTIMEX
+-	printk("ppc_adjtimex: ltemp = %ld, time_freq = %ld, singleshot_ppm = %ld\n", ltemp, time_freq, singleshot_ppm);
+-	printk("ppc_adjtimex: tb_ticks_per_sec - base = %ld  new = %ld\n", tb_ticks_per_sec, new_tb_ticks_per_sec);
+-#endif
+-				
+-	/* Compute a new value of tb_to_xs (used to convert tb to microseconds and a new value of 
+-	   stamp_xsec which is the time (in 1/2^20 second units) corresponding to tb_orig_stamp.  This 
+-	   new value of stamp_xsec compensates for the change in frequency (implied by the new tb_to_xs)
+-	   which guarantees that the current time remains the same */ 
+-	write_seqlock_irqsave( &xtime_lock, flags );
+-	tb_ticks = get_tb() - do_gtod.varp->tb_orig_stamp;
+-	div128_by_32( 1024*1024, 0, new_tb_ticks_per_sec, &divres );
+-	new_tb_to_xs = divres.result_low;
+-	new_xsec = mulhdu( tb_ticks, new_tb_to_xs );
+-
+-	old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs );
+-	new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec;
+-
+-	/* There are two copies of tb_to_xs and stamp_xsec so that no lock is needed to access and use these
+-	   values in do_gettimeofday.  We alternate the copies and as long as a reasonable time elapses between
+-	   changes, there will never be inconsistent values.  ntpd has a minimum of one minute between updates */
+-
+-	temp_idx = (do_gtod.var_idx == 0);
+-	temp_varp = &do_gtod.vars[temp_idx];
+-
+-	temp_varp->tb_to_xs = new_tb_to_xs;
+-	temp_varp->stamp_xsec = new_stamp_xsec;
+-	temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp;
+-	smp_mb();
+-	do_gtod.varp = temp_varp;
+-	do_gtod.var_idx = temp_idx;
+-
+-	/*
+-	 * tb_update_count is used to allow the problem state gettimeofday code
+-	 * to assure itself that it sees a consistent view of the tb_to_xs and
+-	 * stamp_xsec variables.  It reads the tb_update_count, then reads
+-	 * tb_to_xs and stamp_xsec and then reads tb_update_count again.  If
+-	 * the two values of tb_update_count match and are even then the
+-	 * tb_to_xs and stamp_xsec values are consistent.  If not, then it
+-	 * loops back and reads them again until this criteria is met.
+-	 */
+-	++(systemcfg->tb_update_count);
+-	smp_wmb();
+-	systemcfg->tb_to_xs = new_tb_to_xs;
+-	systemcfg->stamp_xsec = new_stamp_xsec;
+-	smp_wmb();
+-	++(systemcfg->tb_update_count);
+-
+-	write_sequnlock_irqrestore( &xtime_lock, flags );
+-
+-}
+-
+-
+-#define TICK_SIZE tick
+-#define FEBRUARY	2
+-#define	STARTOFTIME	1970
+-#define SECDAY		86400L
+-#define SECYR		(SECDAY * 365)
+-#define	leapyear(year)		((year) % 4 == 0)
+-#define	days_in_year(a) 	(leapyear(a) ? 366 : 365)
+-#define	days_in_month(a) 	(month_days[(a) - 1])
+-
+-static int month_days[12] = {
+-	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+-};
+-
+-/*
+- * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
+- */
+-void GregorianDay(struct rtc_time * tm)
+-{
+-	int leapsToDate;
+-	int lastYear;
+-	int day;
+-	int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+-
+-	lastYear=tm->tm_year-1;
+-
+-	/*
+-	 * Number of leap corrections to apply up to end of last year
+-	 */
+-	leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+-
+-	/*
+-	 * This year is a leap year if it is divisible by 4 except when it is
+-	 * divisible by 100 unless it is divisible by 400
+-	 *
+-	 * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+-	 */
+-	if((tm->tm_year%4==0) &&
+-	   ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
+-	   (tm->tm_mon>2))
+-	{
+-		/*
+-		 * We are past Feb. 29 in a leap year
+-		 */
+-		day=1;
+-	}
+-	else
+-	{
+-		day=0;
+-	}
+-
+-	day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
+-		   tm->tm_mday;
+-
+-	tm->tm_wday=day%7;
+-}
+-
+-void to_tm(int tim, struct rtc_time * tm)
+-{
+-	register int    i;
+-	register long   hms, day;
+-
+-	day = tim / SECDAY;
+-	hms = tim % SECDAY;
+-
+-	/* Hours, minutes, seconds are easy */
+-	tm->tm_hour = hms / 3600;
+-	tm->tm_min = (hms % 3600) / 60;
+-	tm->tm_sec = (hms % 3600) % 60;
+-
+-	/* Number of years in days */
+-	for (i = STARTOFTIME; day >= days_in_year(i); i++)
+-		day -= days_in_year(i);
+-	tm->tm_year = i;
+-
+-	/* Number of months in days left */
+-	if (leapyear(tm->tm_year))
+-		days_in_month(FEBRUARY) = 29;
+-	for (i = 1; day >= days_in_month(i); i++)
+-		day -= days_in_month(i);
+-	days_in_month(FEBRUARY) = 28;
+-	tm->tm_mon = i;
+-
+-	/* Days are what is left over (+1) from all that. */
+-	tm->tm_mday = day + 1;
+-
+-	/*
+-	 * Determine the day of week
+-	 */
+-	GregorianDay(tm);
+-}
+-
+-/* Auxiliary function to compute scaling factors */
+-/* Actually the choice of a timebase running at 1/4 the of the bus
+- * frequency giving resolution of a few tens of nanoseconds is quite nice.
+- * It makes this computation very precise (27-28 bits typically) which
+- * is optimistic considering the stability of most processor clock
+- * oscillators and the precision with which the timebase frequency
+- * is measured but does not harm.
+- */
+-unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) {
+-        unsigned mlt=0, tmp, err;
+-        /* No concern for performance, it's done once: use a stupid
+-         * but safe and compact method to find the multiplier.
+-         */
+-  
+-        for (tmp = 1U<<31; tmp != 0; tmp >>= 1) {
+-                if (mulhwu(inscale, mlt|tmp) < outscale) mlt|=tmp;
+-        }
+-  
+-        /* We might still be off by 1 for the best approximation.
+-         * A side effect of this is that if outscale is too large
+-         * the returned value will be zero.
+-         * Many corner cases have been checked and seem to work,
+-         * some might have been forgotten in the test however.
+-         */
+-  
+-        err = inscale*(mlt+1);
+-        if (err <= inscale/2) mlt++;
+-        return mlt;
+-  }
+-
+-/*
+- * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit
+- * result.
+- */
+-
+-void div128_by_32( unsigned long dividend_high, unsigned long dividend_low,
+-		   unsigned divisor, struct div_result *dr )
+-{
+-	unsigned long a,b,c,d, w,x,y,z, ra,rb,rc;
+-
+-	a = dividend_high >> 32;
+-	b = dividend_high & 0xffffffff;
+-	c = dividend_low >> 32;
+-	d = dividend_low & 0xffffffff;
+-
+-	w = a/divisor;
+-	ra = (a - (w * divisor)) << 32;
+-
+-	x = (ra + b)/divisor;
+-	rb = ((ra + b) - (x * divisor)) << 32;
+-
+-	y = (rb + c)/divisor;
+-	rc = ((rb + c) - (y * divisor)) << 32;
+-
+-	z = (rc + d)/divisor;
+-
+-	dr->result_high = (w << 32) + x;
+-	dr->result_low  = (y << 32) + z;
+-
+-}
+-
+diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/traps.c
++++ /dev/null
+@@ -1,568 +0,0 @@
+-/*
+- *  linux/arch/ppc64/kernel/traps.c
+- *
+- *  Copyright (C) 1995-1996  Gary Thomas (gdt at linuxppc.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.
+- *
+- *  Modified by Cort Dougan (cort at cs.nmt.edu)
+- *  and Paul Mackerras (paulus at cs.anu.edu.au)
+- */
+-
+-/*
+- * This file handles the architecture-dependent parts of hardware exceptions
+- */
+-
+-#include <linux/config.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/mm.h>
+-#include <linux/stddef.h>
+-#include <linux/unistd.h>
+-#include <linux/slab.h>
+-#include <linux/user.h>
+-#include <linux/a.out.h>
+-#include <linux/interrupt.h>
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/delay.h>
+-#include <linux/kprobes.h>
+-#include <asm/kdebug.h>
+-
+-#include <asm/pgtable.h>
+-#include <asm/uaccess.h>
+-#include <asm/system.h>
+-#include <asm/io.h>
+-#include <asm/processor.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/rtas.h>
+-#include <asm/systemcfg.h>
+-#include <asm/machdep.h>
+-#include <asm/pmc.h>
+-
+-#ifdef CONFIG_DEBUGGER
+-int (*__debugger)(struct pt_regs *regs);
+-int (*__debugger_ipi)(struct pt_regs *regs);
+-int (*__debugger_bpt)(struct pt_regs *regs);
+-int (*__debugger_sstep)(struct pt_regs *regs);
+-int (*__debugger_iabr_match)(struct pt_regs *regs);
+-int (*__debugger_dabr_match)(struct pt_regs *regs);
+-int (*__debugger_fault_handler)(struct pt_regs *regs);
+-
+-EXPORT_SYMBOL(__debugger);
+-EXPORT_SYMBOL(__debugger_ipi);
+-EXPORT_SYMBOL(__debugger_bpt);
+-EXPORT_SYMBOL(__debugger_sstep);
+-EXPORT_SYMBOL(__debugger_iabr_match);
+-EXPORT_SYMBOL(__debugger_dabr_match);
+-EXPORT_SYMBOL(__debugger_fault_handler);
+-#endif
+-
+-struct notifier_block *ppc64_die_chain;
+-static DEFINE_SPINLOCK(die_notifier_lock);
+-
+-int register_die_notifier(struct notifier_block *nb)
+-{
+-	int err = 0;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&die_notifier_lock, flags);
+-	err = notifier_chain_register(&ppc64_die_chain, nb);
+-	spin_unlock_irqrestore(&die_notifier_lock, flags);
+-	return err;
+-}
+-
+-/*
+- * Trap & Exception support
+- */
+-
+-static DEFINE_SPINLOCK(die_lock);
+-
+-int die(const char *str, struct pt_regs *regs, long err)
+-{
+-	static int die_counter;
+-	int nl = 0;
+-
+-	if (debugger(regs))
+-		return 1;
+-
+-	console_verbose();
+-	spin_lock_irq(&die_lock);
+-	bust_spinlocks(1);
+-	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
+-#ifdef CONFIG_PREEMPT
+-	printk("PREEMPT ");
+-	nl = 1;
+-#endif
+-#ifdef CONFIG_SMP
+-	printk("SMP NR_CPUS=%d ", NR_CPUS);
+-	nl = 1;
+-#endif
+-#ifdef CONFIG_DEBUG_PAGEALLOC
+-	printk("DEBUG_PAGEALLOC ");
+-	nl = 1;
+-#endif
+-#ifdef CONFIG_NUMA
+-	printk("NUMA ");
+-	nl = 1;
+-#endif
+-	switch(systemcfg->platform) {
+-		case PLATFORM_PSERIES:
+-			printk("PSERIES ");
+-			nl = 1;
+-			break;
+-		case PLATFORM_PSERIES_LPAR:
+-			printk("PSERIES LPAR ");
+-			nl = 1;
+-			break;
+-		case PLATFORM_ISERIES_LPAR:
+-			printk("ISERIES LPAR ");
+-			nl = 1;
+-			break;
+-		case PLATFORM_POWERMAC:
+-			printk("POWERMAC ");
+-			nl = 1;
+-			break;
+-		case PLATFORM_BPA:
+-			printk("BPA ");
+-			nl = 1;
+-			break;
+-	}
+-	if (nl)
+-		printk("\n");
+-	print_modules();
+-	show_regs(regs);
+-	bust_spinlocks(0);
+-	spin_unlock_irq(&die_lock);
+-
+-	if (in_interrupt())
+-		panic("Fatal exception in interrupt");
+-
+-	if (panic_on_oops) {
+-		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+-		ssleep(5);
+-		panic("Fatal exception");
+-	}
+-	do_exit(SIGSEGV);
+-
+-	return 0;
+-}
+-
+-void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+-{
+-	siginfo_t info;
+-
+-	if (!user_mode(regs)) {
+-		if (die("Exception in kernel mode", regs, signr))
+-			return;
+-	}
+-
+-	memset(&info, 0, sizeof(info));
+-	info.si_signo = signr;
+-	info.si_code = code;
+-	info.si_addr = (void __user *) addr;
+-	force_sig_info(signr, &info, current);
+-}
+-
+-void system_reset_exception(struct pt_regs *regs)
+-{
+-	/* See if any machine dependent calls */
+-	if (ppc_md.system_reset_exception)
+-		ppc_md.system_reset_exception(regs);
+-
+-	die("System Reset", regs, 0);
+-
+-	/* Must die if the interrupt is not recoverable */
+-	if (!(regs->msr & MSR_RI))
+-		panic("Unrecoverable System Reset");
+-
+-	/* What should we do here? We could issue a shutdown or hard reset. */
+-}
+-
+-void machine_check_exception(struct pt_regs *regs)
+-{
+-	int recover = 0;
+-
+-	/* See if any machine dependent calls */
+-	if (ppc_md.machine_check_exception)
+-		recover = ppc_md.machine_check_exception(regs);
+-
+-	if (recover)
+-		return;
+-
+-	if (debugger_fault_handler(regs))
+-		return;
+-	die("Machine check", regs, 0);
+-
+-	/* Must die if the interrupt is not recoverable */
+-	if (!(regs->msr & MSR_RI))
+-		panic("Unrecoverable Machine check");
+-}
+-
+-void unknown_exception(struct pt_regs *regs)
+-{
+-	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+-	       regs->nip, regs->msr, regs->trap);
+-
+-	_exception(SIGTRAP, regs, 0, 0);
+-}
+-
+-void instruction_breakpoint_exception(struct pt_regs *regs)
+-{
+-	if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
+-					5, SIGTRAP) == NOTIFY_STOP)
+-		return;
+-	if (debugger_iabr_match(regs))
+-		return;
+-	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+-}
+-
+-void __kprobes single_step_exception(struct pt_regs *regs)
+-{
+-	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
+-
+-	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
+-					5, SIGTRAP) == NOTIFY_STOP)
+-		return;
+-	if (debugger_sstep(regs))
+-		return;
+-
+-	_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
+-}
+-
+-/*
+- * After we have successfully emulated an instruction, we have to
+- * check if the instruction was being single-stepped, and if so,
+- * pretend we got a single-step exception.  This was pointed out
+- * by Kumar Gala.  -- paulus
+- */
+-static inline void emulate_single_step(struct pt_regs *regs)
+-{
+-	if (regs->msr & MSR_SE)
+-		single_step_exception(regs);
+-}
+-
+-static void parse_fpe(struct pt_regs *regs)
+-{
+-	int code = 0;
+-	unsigned long fpscr;
+-
+-	flush_fp_to_thread(current);
+-
+-	fpscr = current->thread.fpscr;
+-
+-	/* Invalid operation */
+-	if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
+-		code = FPE_FLTINV;
+-
+-	/* Overflow */
+-	else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
+-		code = FPE_FLTOVF;
+-
+-	/* Underflow */
+-	else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
+-		code = FPE_FLTUND;
+-
+-	/* Divide by zero */
+-	else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
+-		code = FPE_FLTDIV;
+-
+-	/* Inexact result */
+-	else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
+-		code = FPE_FLTRES;
+-
+-	_exception(SIGFPE, regs, code, regs->nip);
+-}
+-
+-/*
+- * Illegal instruction emulation support.  Return non-zero if we can't
+- * emulate, or -EFAULT if the associated memory access caused an access
+- * fault.  Return zero on success.
+- */
+-
+-#define INST_MFSPR_PVR		0x7c1f42a6
+-#define INST_MFSPR_PVR_MASK	0xfc1fffff
+-
+-#define INST_DCBA		0x7c0005ec
+-#define INST_DCBA_MASK		0x7c0007fe
+-
+-#define INST_MCRXR		0x7c000400
+-#define INST_MCRXR_MASK		0x7c0007fe
+-
+-static int emulate_instruction(struct pt_regs *regs)
+-{
+-	unsigned int instword;
+-
+-	if (!user_mode(regs))
+-		return -EINVAL;
+-
+-	CHECK_FULL_REGS(regs);
+-
+-	if (get_user(instword, (unsigned int __user *)(regs->nip)))
+-		return -EFAULT;
+-
+-	/* Emulate the mfspr rD, PVR. */
+-	if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
+-		unsigned int rd;
+-
+-		rd = (instword >> 21) & 0x1f;
+-		regs->gpr[rd] = mfspr(SPRN_PVR);
+-		return 0;
+-	}
+-
+-	/* Emulating the dcba insn is just a no-op.  */
+-	if ((instword & INST_DCBA_MASK) == INST_DCBA) {
+-		static int warned;
+-
+-		if (!warned) {
+-			printk(KERN_WARNING
+-			       "process %d (%s) uses obsolete 'dcba' insn\n",
+-			       current->pid, current->comm);
+-			warned = 1;
+-		}
+-		return 0;
+-	}
+-
+-	/* Emulate the mcrxr insn.  */
+-	if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
+-		static int warned;
+-		unsigned int shift;
+-
+-		if (!warned) {
+-			printk(KERN_WARNING
+-			       "process %d (%s) uses obsolete 'mcrxr' insn\n",
+-			       current->pid, current->comm);
+-			warned = 1;
+-		}
+-
+-		shift = (instword >> 21) & 0x1c;
+-		regs->ccr &= ~(0xf0000000 >> shift);
+-		regs->ccr |= (regs->xer & 0xf0000000) >> shift;
+-		regs->xer &= ~0xf0000000;
+-		return 0;
+-	}
+-
+-	return -EINVAL;
+-}
+-
+-/*
+- * Look through the list of trap instructions that are used for BUG(),
+- * BUG_ON() and WARN_ON() and see if we hit one.  At this point we know
+- * that the exception was caused by a trap instruction of some kind.
+- * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
+- * otherwise.
+- */
+-extern struct bug_entry __start___bug_table[], __stop___bug_table[];
+-
+-#ifndef CONFIG_MODULES
+-#define module_find_bug(x)	NULL
+-#endif
+-
+-struct bug_entry *find_bug(unsigned long bugaddr)
+-{
+-	struct bug_entry *bug;
+-
+-	for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
+-		if (bugaddr == bug->bug_addr)
+-			return bug;
+-	return module_find_bug(bugaddr);
+-}
+-
+-static int
+-check_bug_trap(struct pt_regs *regs)
+-{
+-	struct bug_entry *bug;
+-	unsigned long addr;
+-
+-	if (regs->msr & MSR_PR)
+-		return 0;	/* not in kernel */
+-	addr = regs->nip;	/* address of trap instruction */
+-	if (addr < PAGE_OFFSET)
+-		return 0;
+-	bug = find_bug(regs->nip);
+-	if (bug == NULL)
+-		return 0;
+-	if (bug->line & BUG_WARNING_TRAP) {
+-		/* this is a WARN_ON rather than BUG/BUG_ON */
+-		printk(KERN_ERR "Badness in %s at %s:%d\n",
+-		       bug->function, bug->file,
+-		      (unsigned int)bug->line & ~BUG_WARNING_TRAP);
+-		show_stack(current, (void *)regs->gpr[1]);
+-		return 1;
+-	}
+-	printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+-	       bug->function, bug->file, (unsigned int)bug->line);
+-	return 0;
+-}
+-
+-void __kprobes program_check_exception(struct pt_regs *regs)
+-{
+-	if (debugger_fault_handler(regs))
+-		return;
+-
+-	if (regs->msr & 0x100000) {
+-		/* IEEE FP exception */
+-		parse_fpe(regs);
+-	} else if (regs->msr & 0x20000) {
+-		/* trap exception */
+-
+-		if (notify_die(DIE_BPT, "breakpoint", regs, 5,
+-					5, SIGTRAP) == NOTIFY_STOP)
+-			return;
+-		if (debugger_bpt(regs))
+-			return;
+-
+-		if (check_bug_trap(regs)) {
+-			regs->nip += 4;
+-			return;
+-		}
+-		_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+-
+-	} else {
+-		/* Privileged or illegal instruction; try to emulate it. */
+-		switch (emulate_instruction(regs)) {
+-		case 0:
+-			regs->nip += 4;
+-			emulate_single_step(regs);
+-			break;
+-
+-		case -EFAULT:
+-			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
+-			break;
+-
+-		default:
+-			if (regs->msr & 0x40000)
+-				/* priveleged */
+-				_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+-			else
+-				/* illegal */
+-				_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+-			break;
+-		}
+-	}
+-}
+-
+-void kernel_fp_unavailable_exception(struct pt_regs *regs)
+-{
+-	printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
+-			  "%lx at %lx\n", regs->trap, regs->nip);
+-	die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
+-}
+-
+-void altivec_unavailable_exception(struct pt_regs *regs)
+-{
+-	if (user_mode(regs)) {
+-		/* A user program has executed an altivec instruction,
+-		   but this kernel doesn't support altivec. */
+-		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+-		return;
+-	}
+-	printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
+-			  "%lx at %lx\n", regs->trap, regs->nip);
+-	die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
+-}
+-
+-extern perf_irq_t perf_irq;
+-
+-void performance_monitor_exception(struct pt_regs *regs)
+-{
+-	perf_irq(regs);
+-}
+-
+-void alignment_exception(struct pt_regs *regs)
+-{
+-	int fixed;
+-
+-	fixed = fix_alignment(regs);
+-
+-	if (fixed == 1) {
+-		regs->nip += 4;	/* skip over emulated instruction */
+-		emulate_single_step(regs);
+-		return;
+-	}
+-
+-	/* Operand address was bad */	
+-	if (fixed == -EFAULT) {
+-		if (user_mode(regs)) {
+-			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->dar);
+-		} else {
+-			/* Search exception table */
+-			bad_page_fault(regs, regs->dar, SIGSEGV);
+-		}
+-
+-		return;
+-	}
+-
+-	_exception(SIGBUS, regs, BUS_ADRALN, regs->nip);
+-}
+-
+-#ifdef CONFIG_ALTIVEC
+-void altivec_assist_exception(struct pt_regs *regs)
+-{
+-	int err;
+-	siginfo_t info;
+-
+-	if (!user_mode(regs)) {
+-		printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
+-		       " at %lx\n", regs->nip);
+-		die("Kernel VMX/Altivec assist exception", regs, SIGILL);
+-	}
+-
+-	flush_altivec_to_thread(current);
+-
+-	err = emulate_altivec(regs);
+-	if (err == 0) {
+-		regs->nip += 4;		/* skip emulated instruction */
+-		emulate_single_step(regs);
+-		return;
+-	}
+-
+-	if (err == -EFAULT) {
+-		/* got an error reading the instruction */
+-		info.si_signo = SIGSEGV;
+-		info.si_errno = 0;
+-		info.si_code = SEGV_MAPERR;
+-		info.si_addr = (void __user *) regs->nip;
+-		force_sig_info(SIGSEGV, &info, current);
+-	} else {
+-		/* didn't recognize the instruction */
+-		/* XXX quick hack for now: set the non-Java bit in the VSCR */
+-		if (printk_ratelimit())
+-			printk(KERN_ERR "Unrecognized altivec instruction "
+-			       "in %s at %lx\n", current->comm, regs->nip);
+-		current->thread.vscr.u[3] |= 0x10000;
+-	}
+-}
+-#endif /* CONFIG_ALTIVEC */
+-
+-/*
+- * We enter here if we get an unrecoverable exception, that is, one
+- * that happened at a point where the RI (recoverable interrupt) bit
+- * in the MSR is 0.  This indicates that SRR0/1 are live, and that
+- * we therefore lost state by taking this exception.
+- */
+-void unrecoverable_exception(struct pt_regs *regs)
+-{
+-	printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
+-	       regs->trap, regs->nip);
+-	die("Unrecoverable exception", regs, SIGABRT);
+-}
+-
+-/*
+- * We enter here if we discover during exception entry that we are
+- * running in supervisor mode with a userspace value in the stack pointer.
+- */
+-void kernel_bad_stack(struct pt_regs *regs)
+-{
+-	printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
+-	       regs->gpr[1], regs->nip);
+-	die("Bad kernel stack pointer", regs, SIGABRT);
+-}
+-
+-void __init trap_init(void)
+-{
+-}
+diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/u3_iommu.c
++++ /dev/null
+@@ -1,349 +0,0 @@
+-/*
+- * arch/ppc64/kernel/u3_iommu.c
+- *
+- * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, IBM Corporation
+- *
+- * Based on pSeries_iommu.c:
+- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+- * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, IBM Corporation
+- *
+- * Dynamic DMA mapping support, Apple U3 & IBM CPC925 "DART" iommu.
+- *
+- * 
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the 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/config.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/pci.h>
+-#include <linux/dma-mapping.h>
+-#include <linux/vmalloc.h>
+-#include <asm/io.h>
+-#include <asm/prom.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/iommu.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/machdep.h>
+-#include <asm/abs_addr.h>
+-#include <asm/cacheflush.h>
+-#include <asm/lmb.h>
+-
+-#include "pci.h"
+-
+-extern int iommu_force_on;
+-
+-/* physical base of DART registers */
+-#define DART_BASE        0xf8033000UL
+-
+-/* Offset from base to control register */
+-#define DARTCNTL   0
+-/* Offset from base to exception register */
+-#define DARTEXCP   0x10
+-/* Offset from base to TLB tag registers */
+-#define DARTTAG    0x1000
+-
+-
+-/* Control Register fields */
+-
+-/* base address of table (pfn) */
+-#define DARTCNTL_BASE_MASK    0xfffff
+-#define DARTCNTL_BASE_SHIFT   12
+-
+-#define DARTCNTL_FLUSHTLB     0x400
+-#define DARTCNTL_ENABLE       0x200
+-
+-/* size of table in pages */
+-#define DARTCNTL_SIZE_MASK    0x1ff
+-#define DARTCNTL_SIZE_SHIFT   0
+-
+-/* DART table fields */
+-#define DARTMAP_VALID   0x80000000
+-#define DARTMAP_RPNMASK 0x00ffffff
+-
+-/* Physical base address and size of the DART table */
+-unsigned long dart_tablebase; /* exported to htab_initialize */
+-static unsigned long dart_tablesize;
+-
+-/* Virtual base address of the DART table */
+-static u32 *dart_vbase;
+-
+-/* Mapped base address for the dart */
+-static unsigned int *dart; 
+-
+-/* Dummy val that entries are set to when unused */
+-static unsigned int dart_emptyval;
+-
+-static struct iommu_table iommu_table_u3;
+-static int iommu_table_u3_inited;
+-static int dart_dirty;
+-
+-#define DBG(...)
+-
+-static inline void dart_tlb_invalidate_all(void)
+-{
+-	unsigned long l = 0;
+-	unsigned int reg;
+-	unsigned long limit;
+-
+-	DBG("dart: flush\n");
+-
+-	/* To invalidate the DART, set the DARTCNTL_FLUSHTLB bit in the
+-	 * control register and wait for it to clear.
+-	 *
+-	 * Gotcha: Sometimes, the DART won't detect that the bit gets
+-	 * set. If so, clear it and set it again.
+-	 */ 
+-
+-	limit = 0;
+-
+-retry:
+-	reg = in_be32((unsigned int *)dart+DARTCNTL);
+-	reg |= DARTCNTL_FLUSHTLB;
+-	out_be32((unsigned int *)dart+DARTCNTL, reg);
+-
+-	l = 0;
+-	while ((in_be32((unsigned int *)dart+DARTCNTL) & DARTCNTL_FLUSHTLB) &&
+-		l < (1L<<limit)) {
+-		l++;
+-	}
+-	if (l == (1L<<limit)) {
+-		if (limit < 4) {
+-			limit++;
+-		        reg = in_be32((unsigned int *)dart+DARTCNTL);
+-		        reg &= ~DARTCNTL_FLUSHTLB;
+-		        out_be32((unsigned int *)dart+DARTCNTL, reg);
+-			goto retry;
+-		} else
+-			panic("U3-DART: TLB did not flush after waiting a long "
+-			      "time. Buggy U3 ?");
+-	}
+-}
+-
+-static void dart_flush(struct iommu_table *tbl)
+-{
+-	if (dart_dirty)
+-		dart_tlb_invalidate_all();
+-	dart_dirty = 0;
+-}
+-
+-static void dart_build(struct iommu_table *tbl, long index, 
+-		       long npages, unsigned long uaddr,
+-		       enum dma_data_direction direction)
+-{
+-	unsigned int *dp;
+-	unsigned int rpn;
+-
+-	DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);
+-
+-	dp = ((unsigned int*)tbl->it_base) + index;
+-	
+-	/* On U3, all memory is contigous, so we can move this
+-	 * out of the loop.
+-	 */
+-	while (npages--) {
+-		rpn = virt_to_abs(uaddr) >> PAGE_SHIFT;
+-
+-		*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
+-
+-		rpn++;
+-		uaddr += PAGE_SIZE;
+-	}
+-
+-	dart_dirty = 1;
+-}
+-
+-
+-static void dart_free(struct iommu_table *tbl, long index, long npages)
+-{
+-	unsigned int *dp;
+-	
+-	/* We don't worry about flushing the TLB cache. The only drawback of
+-	 * not doing it is that we won't catch buggy device drivers doing
+-	 * bad DMAs, but then no 32-bit architecture ever does either.
+-	 */
+-
+-	DBG("dart: free at: %lx, %lx\n", index, npages);
+-
+-	dp  = ((unsigned int *)tbl->it_base) + index;
+-		
+-	while (npages--)
+-		*(dp++) = dart_emptyval;
+-}
+-
+-
+-static int dart_init(struct device_node *dart_node)
+-{
+-	unsigned int regword;
+-	unsigned int i;
+-	unsigned long tmp;
+-
+-	if (dart_tablebase == 0 || dart_tablesize == 0) {
+-		printk(KERN_INFO "U3-DART: table not allocated, using direct DMA\n");
+-		return -ENODEV;
+-	}
+-
+-	/* Make sure nothing from the DART range remains in the CPU cache
+-	 * from a previous mapping that existed before the kernel took
+-	 * over
+-	 */
+-	flush_dcache_phys_range(dart_tablebase, dart_tablebase + dart_tablesize);
+-
+-	/* Allocate a spare page to map all invalid DART pages. We need to do
+-	 * that to work around what looks like a problem with the HT bridge
+-	 * prefetching into invalid pages and corrupting data
+-	 */
+-	tmp = lmb_alloc(PAGE_SIZE, PAGE_SIZE);
+-	if (!tmp)
+-		panic("U3-DART: Cannot allocate spare page!");
+-	dart_emptyval = DARTMAP_VALID | ((tmp >> PAGE_SHIFT) & DARTMAP_RPNMASK);
+-
+-	/* Map in DART registers. FIXME: Use device node to get base address */
+-	dart = ioremap(DART_BASE, 0x7000);
+-	if (dart == NULL)
+-		panic("U3-DART: Cannot map registers!");
+-
+-	/* Set initial control register contents: table base, 
+-	 * table size and enable bit
+-	 */
+-	regword = DARTCNTL_ENABLE | 
+-		((dart_tablebase >> PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
+-		(((dart_tablesize >> PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
+-				 << DARTCNTL_SIZE_SHIFT);
+-	dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize);
+-
+-	/* Fill initial table */
+-	for (i = 0; i < dart_tablesize/4; i++)
+-		dart_vbase[i] = dart_emptyval;
+-
+-	/* Initialize DART with table base and enable it. */
+-	out_be32((unsigned int *)dart, regword);
+-
+-	/* Invalidate DART to get rid of possible stale TLBs */
+-	dart_tlb_invalidate_all();
+-
+-	printk(KERN_INFO "U3/CPC925 DART IOMMU initialized\n");
+-
+-	return 0;
+-}
+-
+-static void iommu_table_u3_setup(void)
+-{
+-	iommu_table_u3.it_busno = 0;
+-	iommu_table_u3.it_offset = 0;
+-	/* it_size is in number of entries */
+-	iommu_table_u3.it_size = dart_tablesize / sizeof(u32);
+-
+-	/* Initialize the common IOMMU code */
+-	iommu_table_u3.it_base = (unsigned long)dart_vbase;
+-	iommu_table_u3.it_index = 0;
+-	iommu_table_u3.it_blocksize = 1;
+-	iommu_init_table(&iommu_table_u3);
+-
+-	/* Reserve the last page of the DART to avoid possible prefetch
+-	 * past the DART mapped area
+-	 */
+-	set_bit(iommu_table_u3.it_size - 1, iommu_table_u3.it_map);
+-}
+-
+-static void iommu_dev_setup_u3(struct pci_dev *dev)
+-{
+-	struct device_node *dn;
+-
+-	/* We only have one iommu table on the mac for now, which makes
+-	 * things simple. Setup all PCI devices to point to this table
+-	 *
+-	 * We must use pci_device_to_OF_node() to make sure that
+-	 * we get the real "final" pointer to the device in the
+-	 * pci_dev sysdata and not the temporary PHB one
+-	 */
+-	dn = pci_device_to_OF_node(dev);
+-
+-	if (dn)
+-		PCI_DN(dn)->iommu_table = &iommu_table_u3;
+-}
+-
+-static void iommu_bus_setup_u3(struct pci_bus *bus)
+-{
+-	struct device_node *dn;
+-
+-	if (!iommu_table_u3_inited) {
+-		iommu_table_u3_inited = 1;
+-		iommu_table_u3_setup();
+-	}
+-
+-	dn = pci_bus_to_OF_node(bus);
+-
+-	if (dn)
+-		PCI_DN(dn)->iommu_table = &iommu_table_u3;
+-}
+-
+-static void iommu_dev_setup_null(struct pci_dev *dev) { }
+-static void iommu_bus_setup_null(struct pci_bus *bus) { }
+-
+-void iommu_init_early_u3(void)
+-{
+-	struct device_node *dn;
+-
+-	/* Find the DART in the device-tree */
+-	dn = of_find_compatible_node(NULL, "dart", "u3-dart");
+-	if (dn == NULL)
+-		return;
+-
+-	/* Setup low level TCE operations for the core IOMMU code */
+-	ppc_md.tce_build = dart_build;
+-	ppc_md.tce_free  = dart_free;
+-	ppc_md.tce_flush = dart_flush;
+-
+-	/* Initialize the DART HW */
+-	if (dart_init(dn)) {
+-		/* If init failed, use direct iommu and null setup functions */
+-		ppc_md.iommu_dev_setup = iommu_dev_setup_null;
+-		ppc_md.iommu_bus_setup = iommu_bus_setup_null;
+-
+-		/* Setup pci_dma ops */
+-		pci_direct_iommu_init();
+-	} else {
+-		ppc_md.iommu_dev_setup = iommu_dev_setup_u3;
+-		ppc_md.iommu_bus_setup = iommu_bus_setup_u3;
+-
+-		/* Setup pci_dma ops */
+-		pci_iommu_init();
+-	}
+-}
+-
+-
+-void __init alloc_u3_dart_table(void)
+-{
+-	/* Only reserve DART space if machine has more than 2GB of RAM
+-	 * or if requested with iommu=on on cmdline.
+-	 */
+-	if (lmb_end_of_DRAM() <= 0x80000000ull && !iommu_force_on)
+-		return;
+-
+-	/* 512 pages (2MB) is max DART tablesize. */
+-	dart_tablesize = 1UL << 21;
+-	/* 16MB (1 << 24) alignment. We allocate a full 16Mb chuck since we
+-	 * will blow up an entire large page anyway in the kernel mapping
+-	 */
+-	dart_tablebase = (unsigned long)
+-		abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
+-
+-	printk(KERN_INFO "U3-DART allocated at: %lx\n", dart_tablebase);
+-}
+diff --git a/arch/ppc64/kernel/vdso.c b/arch/ppc64/kernel/vdso.c
+--- a/arch/ppc64/kernel/vdso.c
++++ b/arch/ppc64/kernel/vdso.c
+@@ -176,13 +176,13 @@ static struct page * vdso_vma_nopage(str
+ 		return NOPAGE_SIGBUS;
+ 
+ 	/*
+-	 * Last page is systemcfg, special handling here, no get_page() a
+-	 * this is a reserved page
++	 * Last page is systemcfg.
+ 	 */
+ 	if ((vma->vm_end - address) <= PAGE_SIZE)
+-		return virt_to_page(systemcfg);
++		pg = virt_to_page(systemcfg);
++	else
++		pg = virt_to_page(vbase + offset);
+ 
+-	pg = virt_to_page(vbase + offset);
+ 	get_page(pg);
+ 	DBG(" ->page count: %d\n", page_count(pg));
+ 
+@@ -259,7 +259,7 @@ int arch_setup_additional_pages(struct l
+ 	 * gettimeofday will be totally dead. It's fine to use that for setting
+ 	 * breakpoints in the vDSO code pages though
+ 	 */
+-	vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
++	vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC | VM_RESERVED;
+ 	vma->vm_flags |= mm->def_flags;
+ 	vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
+ 	vma->vm_ops = &vdso_vmops;
+@@ -603,6 +603,8 @@ void __init vdso_init(void)
+ 		ClearPageReserved(pg);
+ 		get_page(pg);
+ 	}
++
++	get_page(virt_to_page(systemcfg));
+ }
+ 
+ int in_gate_area_no_task(unsigned long addr)
+diff --git a/arch/ppc64/kernel/vdso64/sigtramp.S b/arch/ppc64/kernel/vdso64/sigtramp.S
+--- a/arch/ppc64/kernel/vdso64/sigtramp.S
++++ b/arch/ppc64/kernel/vdso64/sigtramp.S
+@@ -15,6 +15,7 @@
+ #include <asm/ppc_asm.h>
+ #include <asm/unistd.h>
+ #include <asm/vdso.h>
++#include <asm/ptrace.h>		/* XXX for __SIGNAL_FRAMESIZE */
+ 
+ 	.text
+ 
+diff --git a/arch/ppc64/kernel/vecemu.c b/arch/ppc64/kernel/vecemu.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/vecemu.c
++++ /dev/null
+@@ -1,346 +0,0 @@
+-/*
+- * Routines to emulate some Altivec/VMX instructions, specifically
+- * those that can trap when given denormalized operands in Java mode.
+- */
+-#include <linux/kernel.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <asm/ptrace.h>
+-#include <asm/processor.h>
+-#include <asm/uaccess.h>
+-
+-/* Functions in vector.S */
+-extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b);
+-extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b);
+-extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
+-extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
+-extern void vrefp(vector128 *dst, vector128 *src);
+-extern void vrsqrtefp(vector128 *dst, vector128 *src);
+-extern void vexptep(vector128 *dst, vector128 *src);
+-
+-static unsigned int exp2s[8] = {
+-	0x800000,
+-	0x8b95c2,
+-	0x9837f0,
+-	0xa5fed7,
+-	0xb504f3,
+-	0xc5672a,
+-	0xd744fd,
+-	0xeac0c7
+-};
+-
+-/*
+- * Computes an estimate of 2^x.  The `s' argument is the 32-bit
+- * single-precision floating-point representation of x.
+- */
+-static unsigned int eexp2(unsigned int s)
+-{
+-	int exp, pwr;
+-	unsigned int mant, frac;
+-
+-	/* extract exponent field from input */
+-	exp = ((s >> 23) & 0xff) - 127;
+-	if (exp > 7) {
+-		/* check for NaN input */
+-		if (exp == 128 && (s & 0x7fffff) != 0)
+-			return s | 0x400000;	/* return QNaN */
+-		/* 2^-big = 0, 2^+big = +Inf */
+-		return (s & 0x80000000)? 0: 0x7f800000;	/* 0 or +Inf */
+-	}
+-	if (exp < -23)
+-		return 0x3f800000;	/* 1.0 */
+-
+-	/* convert to fixed point integer in 9.23 representation */
+-	pwr = (s & 0x7fffff) | 0x800000;
+-	if (exp > 0)
+-		pwr <<= exp;
+-	else
+-		pwr >>= -exp;
+-	if (s & 0x80000000)
+-		pwr = -pwr;
+-
+-	/* extract integer part, which becomes exponent part of result */
+-	exp = (pwr >> 23) + 126;
+-	if (exp >= 254)
+-		return 0x7f800000;
+-	if (exp < -23)
+-		return 0;
+-
+-	/* table lookup on top 3 bits of fraction to get mantissa */
+-	mant = exp2s[(pwr >> 20) & 7];
+-
+-	/* linear interpolation using remaining 20 bits of fraction */
+-	asm("mulhwu %0,%1,%2" : "=r" (frac)
+-	    : "r" (pwr << 12), "r" (0x172b83ff));
+-	asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant));
+-	mant += frac;
+-
+-	if (exp >= 0)
+-		return mant + (exp << 23);
+-
+-	/* denormalized result */
+-	exp = -exp;
+-	mant += 1 << (exp - 1);
+-	return mant >> exp;
+-}
+-
+-/*
+- * Computes an estimate of log_2(x).  The `s' argument is the 32-bit
+- * single-precision floating-point representation of x.
+- */
+-static unsigned int elog2(unsigned int s)
+-{
+-	int exp, mant, lz, frac;
+-
+-	exp = s & 0x7f800000;
+-	mant = s & 0x7fffff;
+-	if (exp == 0x7f800000) {	/* Inf or NaN */
+-		if (mant != 0)
+-			s |= 0x400000;	/* turn NaN into QNaN */
+-		return s;
+-	}
+-	if ((exp | mant) == 0)		/* +0 or -0 */
+-		return 0xff800000;	/* return -Inf */
+-
+-	if (exp == 0) {
+-		/* denormalized */
+-		asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant));
+-		mant <<= lz - 8;
+-		exp = (-118 - lz) << 23;
+-	} else {
+-		mant |= 0x800000;
+-		exp -= 127 << 23;
+-	}
+-
+-	if (mant >= 0xb504f3) {				/* 2^0.5 * 2^23 */
+-		exp |= 0x400000;			/* 0.5 * 2^23 */
+-		asm("mulhwu %0,%1,%2" : "=r" (mant)
+-		    : "r" (mant), "r" (0xb504f334));	/* 2^-0.5 * 2^32 */
+-	}
+-	if (mant >= 0x9837f0) {				/* 2^0.25 * 2^23 */
+-		exp |= 0x200000;			/* 0.25 * 2^23 */
+-		asm("mulhwu %0,%1,%2" : "=r" (mant)
+-		    : "r" (mant), "r" (0xd744fccb));	/* 2^-0.25 * 2^32 */
+-	}
+-	if (mant >= 0x8b95c2) {				/* 2^0.125 * 2^23 */
+-		exp |= 0x100000;			/* 0.125 * 2^23 */
+-		asm("mulhwu %0,%1,%2" : "=r" (mant)
+-		    : "r" (mant), "r" (0xeac0c6e8));	/* 2^-0.125 * 2^32 */
+-	}
+-	if (mant > 0x800000) {				/* 1.0 * 2^23 */
+-		/* calculate (mant - 1) * 1.381097463 */
+-		/* 1.381097463 == 0.125 / (2^0.125 - 1) */
+-		asm("mulhwu %0,%1,%2" : "=r" (frac)
+-		    : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a));
+-		exp += frac;
+-	}
+-	s = exp & 0x80000000;
+-	if (exp != 0) {
+-		if (s)
+-			exp = -exp;
+-		asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp));
+-		lz = 8 - lz;
+-		if (lz > 0)
+-			exp >>= lz;
+-		else if (lz < 0)
+-			exp <<= -lz;
+-		s += ((lz + 126) << 23) + exp;
+-	}
+-	return s;
+-}
+-
+-#define VSCR_SAT	1
+-
+-static int ctsxs(unsigned int x, int scale, unsigned int *vscrp)
+-{
+-	int exp, mant;
+-
+-	exp = (x >> 23) & 0xff;
+-	mant = x & 0x7fffff;
+-	if (exp == 255 && mant != 0)
+-		return 0;		/* NaN -> 0 */
+-	exp = exp - 127 + scale;
+-	if (exp < 0)
+-		return 0;		/* round towards zero */
+-	if (exp >= 31) {
+-		/* saturate, unless the result would be -2^31 */
+-		if (x + (scale << 23) != 0xcf000000)
+-			*vscrp |= VSCR_SAT;
+-		return (x & 0x80000000)? 0x80000000: 0x7fffffff;
+-	}
+-	mant |= 0x800000;
+-	mant = (mant << 7) >> (30 - exp);
+-	return (x & 0x80000000)? -mant: mant;
+-}
+-
+-static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp)
+-{
+-	int exp;
+-	unsigned int mant;
+-
+-	exp = (x >> 23) & 0xff;
+-	mant = x & 0x7fffff;
+-	if (exp == 255 && mant != 0)
+-		return 0;		/* NaN -> 0 */
+-	exp = exp - 127 + scale;
+-	if (exp < 0)
+-		return 0;		/* round towards zero */
+-	if (x & 0x80000000) {
+-		/* negative => saturate to 0 */
+-		*vscrp |= VSCR_SAT;
+-		return 0;
+-	}
+-	if (exp >= 32) {
+-		/* saturate */
+-		*vscrp |= VSCR_SAT;
+-		return 0xffffffff;
+-	}
+-	mant |= 0x800000;
+-	mant = (mant << 8) >> (31 - exp);
+-	return mant;
+-}
+-
+-/* Round to floating integer, towards 0 */
+-static unsigned int rfiz(unsigned int x)
+-{
+-	int exp;
+-
+-	exp = ((x >> 23) & 0xff) - 127;
+-	if (exp == 128 && (x & 0x7fffff) != 0)
+-		return x | 0x400000;	/* NaN -> make it a QNaN */
+-	if (exp >= 23)
+-		return x;		/* it's an integer already (or Inf) */
+-	if (exp < 0)
+-		return x & 0x80000000;	/* |x| < 1.0 rounds to 0 */
+-	return x & ~(0x7fffff >> exp);
+-}
+-
+-/* Round to floating integer, towards +/- Inf */
+-static unsigned int rfii(unsigned int x)
+-{
+-	int exp, mask;
+-
+-	exp = ((x >> 23) & 0xff) - 127;
+-	if (exp == 128 && (x & 0x7fffff) != 0)
+-		return x | 0x400000;	/* NaN -> make it a QNaN */
+-	if (exp >= 23)
+-		return x;		/* it's an integer already (or Inf) */
+-	if ((x & 0x7fffffff) == 0)
+-		return x;		/* +/-0 -> +/-0 */
+-	if (exp < 0)
+-		/* 0 < |x| < 1.0 rounds to +/- 1.0 */
+-		return (x & 0x80000000) | 0x3f800000;
+-	mask = 0x7fffff >> exp;
+-	/* mantissa overflows into exponent - that's OK,
+-	   it can't overflow into the sign bit */
+-	return (x + mask) & ~mask;
+-}
+-
+-/* Round to floating integer, to nearest */
+-static unsigned int rfin(unsigned int x)
+-{
+-	int exp, half;
+-
+-	exp = ((x >> 23) & 0xff) - 127;
+-	if (exp == 128 && (x & 0x7fffff) != 0)
+-		return x | 0x400000;	/* NaN -> make it a QNaN */
+-	if (exp >= 23)
+-		return x;		/* it's an integer already (or Inf) */
+-	if (exp < -1)
+-		return x & 0x80000000;	/* |x| < 0.5 -> +/-0 */
+-	if (exp == -1)
+-		/* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */
+-		return (x & 0x80000000) | 0x3f800000;
+-	half = 0x400000 >> exp;
+-	/* add 0.5 to the magnitude and chop off the fraction bits */
+-	return (x + half) & ~(0x7fffff >> exp);
+-}
+-
+-int
+-emulate_altivec(struct pt_regs *regs)
+-{
+-	unsigned int instr, i;
+-	unsigned int va, vb, vc, vd;
+-	vector128 *vrs;
+-
+-	if (get_user(instr, (unsigned int __user *) regs->nip))
+-		return -EFAULT;
+-	if ((instr >> 26) != 4)
+-		return -EINVAL;		/* not an altivec instruction */
+-	vd = (instr >> 21) & 0x1f;
+-	va = (instr >> 16) & 0x1f;
+-	vb = (instr >> 11) & 0x1f;
+-	vc = (instr >> 6) & 0x1f;
+-
+-	vrs = current->thread.vr;
+-	switch (instr & 0x3f) {
+-	case 10:
+-		switch (vc) {
+-		case 0:	/* vaddfp */
+-			vaddfp(&vrs[vd], &vrs[va], &vrs[vb]);
+-			break;
+-		case 1:	/* vsubfp */
+-			vsubfp(&vrs[vd], &vrs[va], &vrs[vb]);
+-			break;
+-		case 4:	/* vrefp */
+-			vrefp(&vrs[vd], &vrs[vb]);
+-			break;
+-		case 5:	/* vrsqrtefp */
+-			vrsqrtefp(&vrs[vd], &vrs[vb]);
+-			break;
+-		case 6:	/* vexptefp */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = eexp2(vrs[vb].u[i]);
+-			break;
+-		case 7:	/* vlogefp */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = elog2(vrs[vb].u[i]);
+-			break;
+-		case 8:		/* vrfin */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = rfin(vrs[vb].u[i]);
+-			break;
+-		case 9:		/* vrfiz */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = rfiz(vrs[vb].u[i]);
+-			break;
+-		case 10:	/* vrfip */
+-			for (i = 0; i < 4; ++i) {
+-				u32 x = vrs[vb].u[i];
+-				x = (x & 0x80000000)? rfiz(x): rfii(x);
+-				vrs[vd].u[i] = x;
+-			}
+-			break;
+-		case 11:	/* vrfim */
+-			for (i = 0; i < 4; ++i) {
+-				u32 x = vrs[vb].u[i];
+-				x = (x & 0x80000000)? rfii(x): rfiz(x);
+-				vrs[vd].u[i] = x;
+-			}
+-			break;
+-		case 14:	/* vctuxs */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
+-						&current->thread.vscr.u[3]);
+-			break;
+-		case 15:	/* vctsxs */
+-			for (i = 0; i < 4; ++i)
+-				vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
+-						&current->thread.vscr.u[3]);
+-			break;
+-		default:
+-			return -EINVAL;
+-		}
+-		break;
+-	case 46:	/* vmaddfp */
+-		vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
+-		break;
+-	case 47:	/* vnmsubfp */
+-		vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
+-		break;
+-	default:
+-		return -EINVAL;
+-	}
+-
+-	return 0;
+-}
+diff --git a/arch/ppc64/kernel/vector.S b/arch/ppc64/kernel/vector.S
+deleted file mode 100644
+--- a/arch/ppc64/kernel/vector.S
++++ /dev/null
+@@ -1,172 +0,0 @@
+-#include <asm/ppc_asm.h>
+-#include <asm/processor.h>
+-
+-/*
+- * The routines below are in assembler so we can closely control the
+- * usage of floating-point registers.  These routines must be called
+- * with preempt disabled.
+- */
+-	.section ".toc","aw"
+-fpzero:
+-	.tc	FD_0_0[TC],0
+-fpone:
+-	.tc	FD_3ff00000_0[TC],0x3ff0000000000000	/* 1.0 */
+-fphalf:
+-	.tc	FD_3fe00000_0[TC],0x3fe0000000000000	/* 0.5 */
+-
+-	.text
+-/*
+- * Internal routine to enable floating point and set FPSCR to 0.
+- * Don't call it from C; it doesn't use the normal calling convention.
+- */
+-fpenable:
+-	mfmsr	r10
+-	ori	r11,r10,MSR_FP
+-	mtmsr	r11
+-	isync
+-	stfd	fr31,-8(r1)
+-	stfd	fr0,-16(r1)
+-	stfd	fr1,-24(r1)
+-	mffs	fr31
+-	lfd	fr1,fpzero at toc(r2)
+-	mtfsf	0xff,fr1
+-	blr
+-
+-fpdisable:
+-	mtlr	r12
+-	mtfsf	0xff,fr31
+-	lfd	fr1,-24(r1)
+-	lfd	fr0,-16(r1)
+-	lfd	fr31,-8(r1)
+-	mtmsr	r10
+-	isync
+-	blr
+-
+-/*
+- * Vector add, floating point.
+- */
+-_GLOBAL(vaddfp)
+-	mflr	r12
+-	bl	fpenable
+-	li	r0,4
+-	mtctr	r0
+-	li	r6,0
+-1:	lfsx	fr0,r4,r6
+-	lfsx	fr1,r5,r6
+-	fadds	fr0,fr0,fr1
+-	stfsx	fr0,r3,r6
+-	addi	r6,r6,4
+-	bdnz	1b
+-	b	fpdisable
+-
+-/*
+- * Vector subtract, floating point.
+- */
+-_GLOBAL(vsubfp)
+-	mflr	r12
+-	bl	fpenable
+-	li	r0,4
+-	mtctr	r0
+-	li	r6,0
+-1:	lfsx	fr0,r4,r6
+-	lfsx	fr1,r5,r6
+-	fsubs	fr0,fr0,fr1
+-	stfsx	fr0,r3,r6
+-	addi	r6,r6,4
+-	bdnz	1b
+-	b	fpdisable
+-
+-/*
+- * Vector multiply and add, floating point.
+- */
+-_GLOBAL(vmaddfp)
+-	mflr	r12
+-	bl	fpenable
+-	stfd	fr2,-32(r1)
+-	li	r0,4
+-	mtctr	r0
+-	li	r7,0
+-1:	lfsx	fr0,r4,r7
+-	lfsx	fr1,r5,r7
+-	lfsx	fr2,r6,r7
+-	fmadds	fr0,fr0,fr2,fr1
+-	stfsx	fr0,r3,r7
+-	addi	r7,r7,4
+-	bdnz	1b
+-	lfd	fr2,-32(r1)
+-	b	fpdisable
+-
+-/*
+- * Vector negative multiply and subtract, floating point.
+- */
+-_GLOBAL(vnmsubfp)
+-	mflr	r12
+-	bl	fpenable
+-	stfd	fr2,-32(r1)
+-	li	r0,4
+-	mtctr	r0
+-	li	r7,0
+-1:	lfsx	fr0,r4,r7
+-	lfsx	fr1,r5,r7
+-	lfsx	fr2,r6,r7
+-	fnmsubs	fr0,fr0,fr2,fr1
+-	stfsx	fr0,r3,r7
+-	addi	r7,r7,4
+-	bdnz	1b
+-	lfd	fr2,-32(r1)
+-	b	fpdisable
+-
+-/*
+- * Vector reciprocal estimate.  We just compute 1.0/x.
+- * r3 -> destination, r4 -> source.
+- */
+-_GLOBAL(vrefp)
+-	mflr	r12
+-	bl	fpenable
+-	li	r0,4
+-	lfd	fr1,fpone at toc(r2)
+-	mtctr	r0
+-	li	r6,0
+-1:	lfsx	fr0,r4,r6
+-	fdivs	fr0,fr1,fr0
+-	stfsx	fr0,r3,r6
+-	addi	r6,r6,4
+-	bdnz	1b
+-	b	fpdisable
+-
+-/*
+- * Vector reciprocal square-root estimate, floating point.
+- * We use the frsqrte instruction for the initial estimate followed
+- * by 2 iterations of Newton-Raphson to get sufficient accuracy.
+- * r3 -> destination, r4 -> source.
+- */
+-_GLOBAL(vrsqrtefp)
+-	mflr	r12
+-	bl	fpenable
+-	stfd	fr2,-32(r1)
+-	stfd	fr3,-40(r1)
+-	stfd	fr4,-48(r1)
+-	stfd	fr5,-56(r1)
+-	li	r0,4
+-	lfd	fr4,fpone at toc(r2)
+-	lfd	fr5,fphalf at toc(r2)
+-	mtctr	r0
+-	li	r6,0
+-1:	lfsx	fr0,r4,r6
+-	frsqrte	fr1,fr0		/* r = frsqrte(s) */
+-	fmuls	fr3,fr1,fr0	/* r * s */
+-	fmuls	fr2,fr1,fr5	/* r * 0.5 */
+-	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
+-	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
+-	fmuls	fr3,fr1,fr0	/* r * s */
+-	fmuls	fr2,fr1,fr5	/* r * 0.5 */
+-	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
+-	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
+-	stfsx	fr1,r3,r6
+-	addi	r6,r6,4
+-	bdnz	1b
+-	lfd	fr5,-56(r1)
+-	lfd	fr4,-48(r1)
+-	lfd	fr3,-40(r1)
+-	lfd	fr2,-32(r1)
+-	b	fpdisable
+diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/vio.c
++++ /dev/null
+@@ -1,261 +0,0 @@
+-/*
+- * IBM PowerPC Virtual I/O Infrastructure Support.
+- *
+- *    Copyright (c) 2003-2005 IBM Corp.
+- *     Dave Engebretsen engebret at us.ibm.com
+- *     Santiago Leon santil at us.ibm.com
+- *     Hollis Blanchard <hollisb at us.ibm.com>
+- *     Stephen Rothwell
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/console.h>
+-#include <linux/module.h>
+-#include <linux/mm.h>
+-#include <linux/dma-mapping.h>
+-#include <asm/iommu.h>
+-#include <asm/dma.h>
+-#include <asm/vio.h>
+-
+-static const struct vio_device_id *vio_match_device(
+-		const struct vio_device_id *, const struct vio_dev *);
+-
+-struct vio_dev vio_bus_device  = { /* fake "parent" device */
+-	.name = vio_bus_device.dev.bus_id,
+-	.type = "",
+-	.dev.bus_id = "vio",
+-	.dev.bus = &vio_bus_type,
+-};
+-
+-static struct vio_bus_ops vio_bus_ops;
+-
+-/*
+- * Convert from struct device to struct vio_dev and pass to driver.
+- * dev->driver has already been set by generic code because vio_bus_match
+- * succeeded.
+- */
+-static int vio_bus_probe(struct device *dev)
+-{
+-	struct vio_dev *viodev = to_vio_dev(dev);
+-	struct vio_driver *viodrv = to_vio_driver(dev->driver);
+-	const struct vio_device_id *id;
+-	int error = -ENODEV;
+-
+-	if (!viodrv->probe)
+-		return error;
+-
+-	id = vio_match_device(viodrv->id_table, viodev);
+-	if (id)
+-		error = viodrv->probe(viodev, id);
+-
+-	return error;
+-}
+-
+-/* convert from struct device to struct vio_dev and pass to driver. */
+-static int vio_bus_remove(struct device *dev)
+-{
+-	struct vio_dev *viodev = to_vio_dev(dev);
+-	struct vio_driver *viodrv = to_vio_driver(dev->driver);
+-
+-	if (viodrv->remove)
+-		return viodrv->remove(viodev);
+-
+-	/* driver can't remove */
+-	return 1;
+-}
+-
+-/**
+- * vio_register_driver: - Register a new vio driver
+- * @drv:	The vio_driver structure to be registered.
+- */
+-int vio_register_driver(struct vio_driver *viodrv)
+-{
+-	printk(KERN_DEBUG "%s: driver %s registering\n", __FUNCTION__,
+-		viodrv->name);
+-
+-	/* fill in 'struct driver' fields */
+-	viodrv->driver.name = viodrv->name;
+-	viodrv->driver.bus = &vio_bus_type;
+-	viodrv->driver.probe = vio_bus_probe;
+-	viodrv->driver.remove = vio_bus_remove;
+-
+-	return driver_register(&viodrv->driver);
+-}
+-EXPORT_SYMBOL(vio_register_driver);
+-
+-/**
+- * vio_unregister_driver - Remove registration of vio driver.
+- * @driver:	The vio_driver struct to be removed form registration
+- */
+-void vio_unregister_driver(struct vio_driver *viodrv)
+-{
+-	driver_unregister(&viodrv->driver);
+-}
+-EXPORT_SYMBOL(vio_unregister_driver);
+-
+-/**
+- * vio_match_device: - Tell if a VIO device has a matching
+- *			VIO device id structure.
+- * @ids:	array of VIO device id structures to search in
+- * @dev:	the VIO device structure to match against
+- *
+- * Used by a driver to check whether a VIO device present in the
+- * system is in its list of supported devices. Returns the matching
+- * vio_device_id structure or NULL if there is no match.
+- */
+-static const struct vio_device_id *vio_match_device(
+-		const struct vio_device_id *ids, const struct vio_dev *dev)
+-{
+-	while (ids->type[0] != '\0') {
+-		if (vio_bus_ops.match(ids, dev))
+-			return ids;
+-		ids++;
+-	}
+-	return NULL;
+-}
+-
+-/**
+- * vio_bus_init: - Initialize the virtual IO bus
+- */
+-int __init vio_bus_init(struct vio_bus_ops *ops)
+-{
+-	int err;
+-
+-	vio_bus_ops = *ops;
+-
+-	err = bus_register(&vio_bus_type);
+-	if (err) {
+-		printk(KERN_ERR "failed to register VIO bus\n");
+-		return err;
+-	}
+-
+-	/*
+-	 * The fake parent of all vio devices, just to give us
+-	 * a nice directory
+-	 */
+-	err = device_register(&vio_bus_device.dev);
+-	if (err) {
+-		printk(KERN_WARNING "%s: device_register returned %i\n",
+-				__FUNCTION__, err);
+-		return err;
+-	}
+-
+-	return 0;
+-}
+-
+-/* vio_dev refcount hit 0 */
+-static void __devinit vio_dev_release(struct device *dev)
+-{
+-	if (vio_bus_ops.release_device)
+-		vio_bus_ops.release_device(dev);
+-	kfree(to_vio_dev(dev));
+-}
+-
+-static ssize_t viodev_show_name(struct device *dev,
+-		struct device_attribute *attr, char *buf)
+-{
+-	return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
+-}
+-DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL);
+-
+-struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev)
+-{
+-	/* init generic 'struct device' fields: */
+-	viodev->dev.parent = &vio_bus_device.dev;
+-	viodev->dev.bus = &vio_bus_type;
+-	viodev->dev.release = vio_dev_release;
+-
+-	/* register with generic device framework */
+-	if (device_register(&viodev->dev)) {
+-		printk(KERN_ERR "%s: failed to register device %s\n",
+-				__FUNCTION__, viodev->dev.bus_id);
+-		return NULL;
+-	}
+-	device_create_file(&viodev->dev, &dev_attr_name);
+-
+-	return viodev;
+-}
+-
+-void __devinit vio_unregister_device(struct vio_dev *viodev)
+-{
+-	if (vio_bus_ops.unregister_device)
+-		vio_bus_ops.unregister_device(viodev);
+-	device_remove_file(&viodev->dev, &dev_attr_name);
+-	device_unregister(&viodev->dev);
+-}
+-EXPORT_SYMBOL(vio_unregister_device);
+-
+-static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
+-			  size_t size, enum dma_data_direction direction)
+-{
+-	return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
+-			direction);
+-}
+-
+-static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
+-		      size_t size, enum dma_data_direction direction)
+-{
+-	iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size,
+-			direction);
+-}
+-
+-static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
+-		int nelems, enum dma_data_direction direction)
+-{
+-	return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
+-			nelems, direction);
+-}
+-
+-static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
+-		int nelems, enum dma_data_direction direction)
+-{
+-	iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction);
+-}
+-
+-static void *vio_alloc_coherent(struct device *dev, size_t size,
+-			   dma_addr_t *dma_handle, gfp_t flag)
+-{
+-	return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
+-			dma_handle, flag);
+-}
+-
+-static void vio_free_coherent(struct device *dev, size_t size,
+-			 void *vaddr, dma_addr_t dma_handle)
+-{
+-	iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr,
+-			dma_handle);
+-}
+-
+-static int vio_dma_supported(struct device *dev, u64 mask)
+-{
+-	return 1;
+-}
+-
+-struct dma_mapping_ops vio_dma_ops = {
+-	.alloc_coherent = vio_alloc_coherent,
+-	.free_coherent = vio_free_coherent,
+-	.map_single = vio_map_single,
+-	.unmap_single = vio_unmap_single,
+-	.map_sg = vio_map_sg,
+-	.unmap_sg = vio_unmap_sg,
+-	.dma_supported = vio_dma_supported,
+-};
+-
+-static int vio_bus_match(struct device *dev, struct device_driver *drv)
+-{
+-	const struct vio_dev *vio_dev = to_vio_dev(dev);
+-	struct vio_driver *vio_drv = to_vio_driver(drv);
+-	const struct vio_device_id *ids = vio_drv->id_table;
+-
+-	return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
+-}
+-
+-struct bus_type vio_bus_type = {
+-	.name = "vio",
+-	.match = vio_bus_match,
+-};
+diff --git a/arch/ppc64/kernel/viopath.c b/arch/ppc64/kernel/viopath.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/viopath.c
++++ /dev/null
+@@ -1,673 +0,0 @@
+-/* -*- linux-c -*-
+- *  arch/ppc64/kernel/viopath.c
+- *
+- *  iSeries Virtual I/O Message Path code
+- *
+- *  Authors: Dave Boutcher <boutcher at us.ibm.com>
+- *           Ryan Arnold <ryanarn at us.ibm.com>
+- *           Colin Devilbiss <devilbis at us.ibm.com>
+- *
+- * (C) Copyright 2000-2003 IBM Corporation
+- *
+- * This code is used by the iSeries virtual disk, cd,
+- * tape, and console to communicate with OS/400 in another
+- * partition.
+- *
+- * This program is free software;  you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License as
+- * published by the Free Software Foundation; either version 2 of the
+- * License, or (at your option) anyu 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/errno.h>
+-#include <linux/vmalloc.h>
+-#include <linux/string.h>
+-#include <linux/proc_fs.h>
+-#include <linux/dma-mapping.h>
+-#include <linux/wait.h>
+-#include <linux/seq_file.h>
+-#include <linux/smp_lock.h>
+-#include <linux/interrupt.h>
+-
+-#include <asm/system.h>
+-#include <asm/uaccess.h>
+-#include <asm/iSeries/HvTypes.h>
+-#include <asm/iSeries/ItExtVpdPanel.h>
+-#include <asm/iSeries/HvLpEvent.h>
+-#include <asm/iSeries/HvLpConfig.h>
+-#include <asm/iSeries/mf.h>
+-#include <asm/iSeries/vio.h>
+-
+-/* Status of the path to each other partition in the system.
+- * This is overkill, since we will only ever establish connections
+- * to our hosting partition and the primary partition on the system.
+- * But this allows for other support in the future.
+- */
+-static struct viopathStatus {
+-	int isOpen;		/* Did we open the path?            */
+-	int isActive;		/* Do we have a mon msg outstanding */
+-	int users[VIO_MAX_SUBTYPES];
+-	HvLpInstanceId mSourceInst;
+-	HvLpInstanceId mTargetInst;
+-	int numberAllocated;
+-} viopathStatus[HVMAXARCHITECTEDLPS];
+-
+-static DEFINE_SPINLOCK(statuslock);
+-
+-/*
+- * For each kind of event we allocate a buffer that is
+- * guaranteed not to cross a page boundary
+- */
+-static unsigned char event_buffer[VIO_MAX_SUBTYPES * 256] __page_aligned;
+-static atomic_t event_buffer_available[VIO_MAX_SUBTYPES];
+-static int event_buffer_initialised;
+-
+-static void handleMonitorEvent(struct HvLpEvent *event);
+-
+-/*
+- * We use this structure to handle asynchronous responses.  The caller
+- * blocks on the semaphore and the handler posts the semaphore.  However,
+- * if system_state is not SYSTEM_RUNNING, then wait_atomic is used ...
+- */
+-struct alloc_parms {
+-	struct semaphore sem;
+-	int number;
+-	atomic_t wait_atomic;
+-	int used_wait_atomic;
+-};
+-
+-/* Put a sequence number in each mon msg.  The value is not
+- * important.  Start at something other than 0 just for
+- * readability.  wrapping this is ok.
+- */
+-static u8 viomonseq = 22;
+-
+-/* Our hosting logical partition.  We get this at startup
+- * time, and different modules access this variable directly.
+- */
+-HvLpIndex viopath_hostLp = HvLpIndexInvalid;
+-EXPORT_SYMBOL(viopath_hostLp);
+-HvLpIndex viopath_ourLp = HvLpIndexInvalid;
+-EXPORT_SYMBOL(viopath_ourLp);
+-
+-/* For each kind of incoming event we set a pointer to a
+- * routine to call.
+- */
+-static vio_event_handler_t *vio_handler[VIO_MAX_SUBTYPES];
+-
+-#define VIOPATH_KERN_WARN	KERN_WARNING "viopath: "
+-#define VIOPATH_KERN_INFO	KERN_INFO "viopath: "
+-
+-static int proc_viopath_show(struct seq_file *m, void *v)
+-{
+-	char *buf;
+-	u16 vlanMap;
+-	dma_addr_t handle;
+-	HvLpEvent_Rc hvrc;
+-	DECLARE_MUTEX_LOCKED(Semaphore);
+-
+-	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+-	if (!buf)
+-		return 0;
+-	memset(buf, 0, PAGE_SIZE);
+-
+-	handle = dma_map_single(iSeries_vio_dev, buf, PAGE_SIZE,
+-				DMA_FROM_DEVICE);
+-
+-	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+-			HvLpEvent_Type_VirtualIo,
+-			viomajorsubtype_config | vioconfigget,
+-			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+-			viopath_sourceinst(viopath_hostLp),
+-			viopath_targetinst(viopath_hostLp),
+-			(u64)(unsigned long)&Semaphore, VIOVERSION << 16,
+-			((u64)handle) << 32, PAGE_SIZE, 0, 0);
+-
+-	if (hvrc != HvLpEvent_Rc_Good)
+-		printk(VIOPATH_KERN_WARN "hv error on op %d\n", (int)hvrc);
+-
+-	down(&Semaphore);
+-
+-	vlanMap = HvLpConfig_getVirtualLanIndexMap();
+-
+-	buf[PAGE_SIZE-1] = '\0';
+-	seq_printf(m, "%s", buf);
+-	seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
+-	seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n",
+-		   e2a(xItExtVpdPanel.mfgID[2]),
+-		   e2a(xItExtVpdPanel.mfgID[3]),
+-		   e2a(xItExtVpdPanel.systemSerial[1]),
+-		   e2a(xItExtVpdPanel.systemSerial[2]),
+-		   e2a(xItExtVpdPanel.systemSerial[3]),
+-		   e2a(xItExtVpdPanel.systemSerial[4]),
+-		   e2a(xItExtVpdPanel.systemSerial[5]));
+-
+-	dma_unmap_single(iSeries_vio_dev, handle, PAGE_SIZE, DMA_FROM_DEVICE);
+-	kfree(buf);
+-
+-	return 0;
+-}
+-
+-static int proc_viopath_open(struct inode *inode, struct file *file)
+-{
+-	return single_open(file, proc_viopath_show, NULL);
+-}
+-
+-static struct file_operations proc_viopath_operations = {
+-	.open		= proc_viopath_open,
+-	.read		= seq_read,
+-	.llseek		= seq_lseek,
+-	.release	= single_release,
+-};
+-
+-static int __init vio_proc_init(void)
+-{
+-	struct proc_dir_entry *e;
+-
+-	e = create_proc_entry("iSeries/config", 0, NULL);
+-	if (e)
+-		e->proc_fops = &proc_viopath_operations;
+-
+-        return 0;
+-}
+-__initcall(vio_proc_init);
+-
+-/* See if a given LP is active.  Allow for invalid lps to be passed in
+- * and just return invalid
+- */
+-int viopath_isactive(HvLpIndex lp)
+-{
+-	if (lp == HvLpIndexInvalid)
+-		return 0;
+-	if (lp < HVMAXARCHITECTEDLPS)
+-		return viopathStatus[lp].isActive;
+-	else
+-		return 0;
+-}
+-EXPORT_SYMBOL(viopath_isactive);
+-
+-/*
+- * We cache the source and target instance ids for each
+- * partition.
+- */
+-HvLpInstanceId viopath_sourceinst(HvLpIndex lp)
+-{
+-	return viopathStatus[lp].mSourceInst;
+-}
+-EXPORT_SYMBOL(viopath_sourceinst);
+-
+-HvLpInstanceId viopath_targetinst(HvLpIndex lp)
+-{
+-	return viopathStatus[lp].mTargetInst;
+-}
+-EXPORT_SYMBOL(viopath_targetinst);
+-
+-/*
+- * Send a monitor message.  This is a message with the acknowledge
+- * bit on that the other side will NOT explicitly acknowledge.  When
+- * the other side goes down, the hypervisor will acknowledge any
+- * outstanding messages....so we will know when the other side dies.
+- */
+-static void sendMonMsg(HvLpIndex remoteLp)
+-{
+-	HvLpEvent_Rc hvrc;
+-
+-	viopathStatus[remoteLp].mSourceInst =
+-		HvCallEvent_getSourceLpInstanceId(remoteLp,
+-				HvLpEvent_Type_VirtualIo);
+-	viopathStatus[remoteLp].mTargetInst =
+-		HvCallEvent_getTargetLpInstanceId(remoteLp,
+-				HvLpEvent_Type_VirtualIo);
+-
+-	/*
+-	 * Deliberately ignore the return code here.  if we call this
+-	 * more than once, we don't care.
+-	 */
+-	vio_setHandler(viomajorsubtype_monitor, handleMonitorEvent);
+-
+-	hvrc = HvCallEvent_signalLpEventFast(remoteLp, HvLpEvent_Type_VirtualIo,
+-			viomajorsubtype_monitor, HvLpEvent_AckInd_DoAck,
+-			HvLpEvent_AckType_DeferredAck,
+-			viopathStatus[remoteLp].mSourceInst,
+-			viopathStatus[remoteLp].mTargetInst,
+-			viomonseq++, 0, 0, 0, 0, 0);
+-
+-	if (hvrc == HvLpEvent_Rc_Good)
+-		viopathStatus[remoteLp].isActive = 1;
+-	else {
+-		printk(VIOPATH_KERN_WARN "could not connect to partition %d\n",
+-				remoteLp);
+-		viopathStatus[remoteLp].isActive = 0;
+-	}
+-}
+-
+-static void handleMonitorEvent(struct HvLpEvent *event)
+-{
+-	HvLpIndex remoteLp;
+-	int i;
+-
+-	/*
+-	 * This handler is _also_ called as part of the loop
+-	 * at the end of this routine, so it must be able to
+-	 * ignore NULL events...
+-	 */
+-	if (!event)
+-		return;
+-
+-	/*
+-	 * First see if this is just a normal monitor message from the
+-	 * other partition
+-	 */
+-	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+-		remoteLp = event->xSourceLp;
+-		if (!viopathStatus[remoteLp].isActive)
+-			sendMonMsg(remoteLp);
+-		return;
+-	}
+-
+-	/*
+-	 * This path is for an acknowledgement; the other partition
+-	 * died
+-	 */
+-	remoteLp = event->xTargetLp;
+-	if ((event->xSourceInstanceId != viopathStatus[remoteLp].mSourceInst) ||
+-	    (event->xTargetInstanceId != viopathStatus[remoteLp].mTargetInst)) {
+-		printk(VIOPATH_KERN_WARN "ignoring ack....mismatched instances\n");
+-		return;
+-	}
+-
+-	printk(VIOPATH_KERN_WARN "partition %d ended\n", remoteLp);
+-
+-	viopathStatus[remoteLp].isActive = 0;
+-
+-	/*
+-	 * For each active handler, pass them a NULL
+-	 * message to indicate that the other partition
+-	 * died
+-	 */
+-	for (i = 0; i < VIO_MAX_SUBTYPES; i++) {
+-		if (vio_handler[i] != NULL)
+-			(*vio_handler[i])(NULL);
+-	}
+-}
+-
+-int vio_setHandler(int subtype, vio_event_handler_t *beh)
+-{
+-	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+-	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+-		return -EINVAL;
+-	if (vio_handler[subtype] != NULL)
+-		return -EBUSY;
+-	vio_handler[subtype] = beh;
+-	return 0;
+-}
+-EXPORT_SYMBOL(vio_setHandler);
+-
+-int vio_clearHandler(int subtype)
+-{
+-	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+-	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+-		return -EINVAL;
+-	if (vio_handler[subtype] == NULL)
+-		return -EAGAIN;
+-	vio_handler[subtype] = NULL;
+-	return 0;
+-}
+-EXPORT_SYMBOL(vio_clearHandler);
+-
+-static void handleConfig(struct HvLpEvent *event)
+-{
+-	if (!event)
+-		return;
+-	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+-		printk(VIOPATH_KERN_WARN
+-		       "unexpected config request from partition %d",
+-		       event->xSourceLp);
+-
+-		if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
+-		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+-			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+-			HvCallEvent_ackLpEvent(event);
+-		}
+-		return;
+-	}
+-
+-	up((struct semaphore *)event->xCorrelationToken);
+-}
+-
+-/*
+- * Initialization of the hosting partition
+- */
+-void vio_set_hostlp(void)
+-{
+-	/*
+-	 * If this has already been set then we DON'T want to either change
+-	 * it or re-register the proc file system
+-	 */
+-	if (viopath_hostLp != HvLpIndexInvalid)
+-		return;
+-
+-	/*
+-	 * Figure out our hosting partition.  This isn't allowed to change
+-	 * while we're active
+-	 */
+-	viopath_ourLp = HvLpConfig_getLpIndex();
+-	viopath_hostLp = HvLpConfig_getHostingLpIndex(viopath_ourLp);
+-
+-	if (viopath_hostLp != HvLpIndexInvalid)
+-		vio_setHandler(viomajorsubtype_config, handleConfig);
+-}
+-EXPORT_SYMBOL(vio_set_hostlp);
+-
+-static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs)
+-{
+-	HvLpIndex remoteLp;
+-	int subtype = (event->xSubtype & VIOMAJOR_SUBTYPE_MASK)
+-		>> VIOMAJOR_SUBTYPE_SHIFT;
+-
+-	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+-		remoteLp = event->xSourceLp;
+-		/*
+-		 * The isActive is checked because if the hosting partition
+-		 * went down and came back up it would not be active but it
+-		 * would have different source and target instances, in which
+-		 * case we'd want to reset them.  This case really protects
+-		 * against an unauthorized active partition sending interrupts
+-		 * or acks to this linux partition.
+-		 */
+-		if (viopathStatus[remoteLp].isActive
+-		    && (event->xSourceInstanceId !=
+-			viopathStatus[remoteLp].mTargetInst)) {
+-			printk(VIOPATH_KERN_WARN
+-			       "message from invalid partition. "
+-			       "int msg rcvd, source inst (%d) doesnt match (%d)\n",
+-			       viopathStatus[remoteLp].mTargetInst,
+-			       event->xSourceInstanceId);
+-			return;
+-		}
+-
+-		if (viopathStatus[remoteLp].isActive
+-		    && (event->xTargetInstanceId !=
+-			viopathStatus[remoteLp].mSourceInst)) {
+-			printk(VIOPATH_KERN_WARN
+-			       "message from invalid partition. "
+-			       "int msg rcvd, target inst (%d) doesnt match (%d)\n",
+-			       viopathStatus[remoteLp].mSourceInst,
+-			       event->xTargetInstanceId);
+-			return;
+-		}
+-	} else {
+-		remoteLp = event->xTargetLp;
+-		if (event->xSourceInstanceId !=
+-		    viopathStatus[remoteLp].mSourceInst) {
+-			printk(VIOPATH_KERN_WARN
+-			       "message from invalid partition. "
+-			       "ack msg rcvd, source inst (%d) doesnt match (%d)\n",
+-			       viopathStatus[remoteLp].mSourceInst,
+-			       event->xSourceInstanceId);
+-			return;
+-		}
+-
+-		if (event->xTargetInstanceId !=
+-		    viopathStatus[remoteLp].mTargetInst) {
+-			printk(VIOPATH_KERN_WARN
+-			       "message from invalid partition. "
+-			       "viopath: ack msg rcvd, target inst (%d) doesnt match (%d)\n",
+-			       viopathStatus[remoteLp].mTargetInst,
+-			       event->xTargetInstanceId);
+-			return;
+-		}
+-	}
+-
+-	if (vio_handler[subtype] == NULL) {
+-		printk(VIOPATH_KERN_WARN
+-		       "unexpected virtual io event subtype %d from partition %d\n",
+-		       event->xSubtype, remoteLp);
+-		/* No handler.  Ack if necessary */
+-		if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
+-		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+-			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+-			HvCallEvent_ackLpEvent(event);
+-		}
+-		return;
+-	}
+-
+-	/* This innocuous little line is where all the real work happens */
+-	(*vio_handler[subtype])(event);
+-}
+-
+-static void viopath_donealloc(void *parm, int number)
+-{
+-	struct alloc_parms *parmsp = parm;
+-
+-	parmsp->number = number;
+-	if (parmsp->used_wait_atomic)
+-		atomic_set(&parmsp->wait_atomic, 0);
+-	else
+-		up(&parmsp->sem);
+-}
+-
+-static int allocateEvents(HvLpIndex remoteLp, int numEvents)
+-{
+-	struct alloc_parms parms;
+-
+-	if (system_state != SYSTEM_RUNNING) {
+-		parms.used_wait_atomic = 1;
+-		atomic_set(&parms.wait_atomic, 1);
+-	} else {
+-		parms.used_wait_atomic = 0;
+-		init_MUTEX_LOCKED(&parms.sem);
+-	}
+-	mf_allocate_lp_events(remoteLp, HvLpEvent_Type_VirtualIo, 250,	/* It would be nice to put a real number here! */
+-			    numEvents, &viopath_donealloc, &parms);
+-	if (system_state != SYSTEM_RUNNING) {
+-		while (atomic_read(&parms.wait_atomic))
+-			mb();
+-	} else
+-		down(&parms.sem);
+-	return parms.number;
+-}
+-
+-int viopath_open(HvLpIndex remoteLp, int subtype, int numReq)
+-{
+-	int i;
+-	unsigned long flags;
+-	int tempNumAllocated;
+-
+-	if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid))
+-		return -EINVAL;
+-
+-	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+-	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+-		return -EINVAL;
+-
+-	spin_lock_irqsave(&statuslock, flags);
+-
+-	if (!event_buffer_initialised) {
+-		for (i = 0; i < VIO_MAX_SUBTYPES; i++)
+-			atomic_set(&event_buffer_available[i], 1);
+-		event_buffer_initialised = 1;
+-	}
+-
+-	viopathStatus[remoteLp].users[subtype]++;
+-
+-	if (!viopathStatus[remoteLp].isOpen) {
+-		viopathStatus[remoteLp].isOpen = 1;
+-		HvCallEvent_openLpEventPath(remoteLp, HvLpEvent_Type_VirtualIo);
+-
+-		/*
+-		 * Don't hold the spinlock during an operation that
+-		 * can sleep.
+-		 */
+-		spin_unlock_irqrestore(&statuslock, flags);
+-		tempNumAllocated = allocateEvents(remoteLp, 1);
+-		spin_lock_irqsave(&statuslock, flags);
+-
+-		viopathStatus[remoteLp].numberAllocated += tempNumAllocated;
+-
+-		if (viopathStatus[remoteLp].numberAllocated == 0) {
+-			HvCallEvent_closeLpEventPath(remoteLp,
+-					HvLpEvent_Type_VirtualIo);
+-
+-			spin_unlock_irqrestore(&statuslock, flags);
+-			return -ENOMEM;
+-		}
+-
+-		viopathStatus[remoteLp].mSourceInst =
+-			HvCallEvent_getSourceLpInstanceId(remoteLp,
+-					HvLpEvent_Type_VirtualIo);
+-		viopathStatus[remoteLp].mTargetInst =
+-			HvCallEvent_getTargetLpInstanceId(remoteLp,
+-					HvLpEvent_Type_VirtualIo);
+-		HvLpEvent_registerHandler(HvLpEvent_Type_VirtualIo,
+-					  &vio_handleEvent);
+-		sendMonMsg(remoteLp);
+-		printk(VIOPATH_KERN_INFO "opening connection to partition %d, "
+-				"setting sinst %d, tinst %d\n",
+-				remoteLp, viopathStatus[remoteLp].mSourceInst,
+-				viopathStatus[remoteLp].mTargetInst);
+-	}
+-
+-	spin_unlock_irqrestore(&statuslock, flags);
+-	tempNumAllocated = allocateEvents(remoteLp, numReq);
+-	spin_lock_irqsave(&statuslock, flags);
+-	viopathStatus[remoteLp].numberAllocated += tempNumAllocated;
+-	spin_unlock_irqrestore(&statuslock, flags);
+-
+-	return 0;
+-}
+-EXPORT_SYMBOL(viopath_open);
+-
+-int viopath_close(HvLpIndex remoteLp, int subtype, int numReq)
+-{
+-	unsigned long flags;
+-	int i;
+-	int numOpen;
+-	struct alloc_parms parms;
+-
+-	if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid))
+-		return -EINVAL;
+-
+-	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+-	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+-		return -EINVAL;
+-
+-	spin_lock_irqsave(&statuslock, flags);
+-	/*
+-	 * If the viopath_close somehow gets called before a
+-	 * viopath_open it could decrement to -1 which is a non
+-	 * recoverable state so we'll prevent this from
+-	 * happening.
+-	 */
+-	if (viopathStatus[remoteLp].users[subtype] > 0)
+-		viopathStatus[remoteLp].users[subtype]--;
+-
+-	spin_unlock_irqrestore(&statuslock, flags);
+-
+-	parms.used_wait_atomic = 0;
+-	init_MUTEX_LOCKED(&parms.sem);
+-	mf_deallocate_lp_events(remoteLp, HvLpEvent_Type_VirtualIo,
+-			      numReq, &viopath_donealloc, &parms);
+-	down(&parms.sem);
+-
+-	spin_lock_irqsave(&statuslock, flags);
+-	for (i = 0, numOpen = 0; i < VIO_MAX_SUBTYPES; i++)
+-		numOpen += viopathStatus[remoteLp].users[i];
+-
+-	if ((viopathStatus[remoteLp].isOpen) && (numOpen == 0)) {
+-		printk(VIOPATH_KERN_INFO "closing connection to partition %d",
+-				remoteLp);
+-
+-		HvCallEvent_closeLpEventPath(remoteLp,
+-					     HvLpEvent_Type_VirtualIo);
+-		viopathStatus[remoteLp].isOpen = 0;
+-		viopathStatus[remoteLp].isActive = 0;
+-
+-		for (i = 0; i < VIO_MAX_SUBTYPES; i++)
+-			atomic_set(&event_buffer_available[i], 0);
+-		event_buffer_initialised = 0;
+-	}
+-	spin_unlock_irqrestore(&statuslock, flags);
+-	return 0;
+-}
+-EXPORT_SYMBOL(viopath_close);
+-
+-void *vio_get_event_buffer(int subtype)
+-{
+-	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+-	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+-		return NULL;
+-
+-	if (atomic_dec_if_positive(&event_buffer_available[subtype]) == 0)
+-		return &event_buffer[subtype * 256];
+-	else
+-		return NULL;
+-}
+-EXPORT_SYMBOL(vio_get_event_buffer);
+-
+-void vio_free_event_buffer(int subtype, void *buffer)
+-{
+-	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+-	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES)) {
+-		printk(VIOPATH_KERN_WARN
+-		       "unexpected subtype %d freeing event buffer\n", subtype);
+-		return;
+-	}
+-
+-	if (atomic_read(&event_buffer_available[subtype]) != 0) {
+-		printk(VIOPATH_KERN_WARN
+-		       "freeing unallocated event buffer, subtype %d\n",
+-		       subtype);
+-		return;
+-	}
+-
+-	if (buffer != &event_buffer[subtype * 256]) {
+-		printk(VIOPATH_KERN_WARN
+-		       "freeing invalid event buffer, subtype %d\n", subtype);
+-	}
+-
+-	atomic_set(&event_buffer_available[subtype], 1);
+-}
+-EXPORT_SYMBOL(vio_free_event_buffer);
+-
+-static const struct vio_error_entry vio_no_error =
+-    { 0, 0, "Non-VIO Error" };
+-static const struct vio_error_entry vio_unknown_error =
+-    { 0, EIO, "Unknown Error" };
+-
+-static const struct vio_error_entry vio_default_errors[] = {
+-	{0x0001, EIO, "No Connection"},
+-	{0x0002, EIO, "No Receiver"},
+-	{0x0003, EIO, "No Buffer Available"},
+-	{0x0004, EBADRQC, "Invalid Message Type"},
+-	{0x0000, 0, NULL},
+-};
+-
+-const struct vio_error_entry *vio_lookup_rc(
+-		const struct vio_error_entry *local_table, u16 rc)
+-{
+-	const struct vio_error_entry *cur;
+-
+-	if (!rc)
+-		return &vio_no_error;
+-	if (local_table)
+-		for (cur = local_table; cur->rc; ++cur)
+-			if (cur->rc == rc)
+-				return cur;
+-	for (cur = vio_default_errors; cur->rc; ++cur)
+-		if (cur->rc == rc)
+-			return cur;
+-	return &vio_unknown_error;
+-}
+-EXPORT_SYMBOL(vio_lookup_rc);
+diff --git a/arch/ppc64/kernel/vmlinux.lds.S b/arch/ppc64/kernel/vmlinux.lds.S
+--- a/arch/ppc64/kernel/vmlinux.lds.S
++++ b/arch/ppc64/kernel/vmlinux.lds.S
+@@ -1,3 +1,4 @@
++#include <asm/page.h>
+ #include <asm-generic/vmlinux.lds.h>
+ 
+ OUTPUT_ARCH(powerpc:common64)
+@@ -17,7 +18,7 @@ SECTIONS
+ 	LOCK_TEXT
+ 	KPROBES_TEXT
+ 	*(.fixup)
+-	. = ALIGN(4096);
++	. = ALIGN(PAGE_SIZE);
+ 	_etext = .;
+ 	}
+ 
+@@ -43,7 +44,7 @@ SECTIONS
+ 
+ 
+   /* will be freed after init */
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   __init_begin = .;
+ 
+   .init.text : {
+@@ -83,7 +84,7 @@ SECTIONS
+ 
+   SECURITY_INIT
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .init.ramfs : {
+ 	__initramfs_start = .;
+ 	*(.init.ramfs)
+@@ -96,18 +97,22 @@ SECTIONS
+ 	__per_cpu_end = .;
+ 	}
+ 
++  . = ALIGN(PAGE_SIZE);
+   . = ALIGN(16384);
+   __init_end = .;
+   /* freed after init ends here */
+ 
+ 
+   /* Read/write sections */
++  . = ALIGN(PAGE_SIZE);
+   . = ALIGN(16384);
++  _sdata = .;
+   /* The initial task and kernel stack */
+   .data.init_task : {
+ 	*(.data.init_task)
+ 	}
+ 
++  . = ALIGN(PAGE_SIZE);
+   .data.page_aligned : {
+ 	*(.data.page_aligned)
+ 	}
+@@ -129,18 +134,18 @@ SECTIONS
+ 	__toc_start = .;
+ 	*(.got)
+ 	*(.toc)
+-	. = ALIGN(4096);
++	. = ALIGN(PAGE_SIZE);
+ 	_edata = .;
+ 	}
+ 
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .bss : {
+ 	__bss_start = .;
+ 	*(.bss)
+ 	__bss_stop = .;
+ 	}
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   _end = . ;
+ }
+diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
+deleted file mode 100644
+--- a/arch/ppc64/kernel/xics.c
++++ /dev/null
+@@ -1,747 +0,0 @@
+-/* 
+- * arch/ppc64/kernel/xics.c
+- *
+- * Copyright 2000 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.
+- */
+-#include <linux/config.h>
+-#include <linux/types.h>
+-#include <linux/threads.h>
+-#include <linux/kernel.h>
+-#include <linux/irq.h>
+-#include <linux/smp.h>
+-#include <linux/interrupt.h>
+-#include <linux/signal.h>
+-#include <linux/init.h>
+-#include <linux/gfp.h>
+-#include <linux/radix-tree.h>
+-#include <linux/cpu.h>
+-#include <asm/prom.h>
+-#include <asm/io.h>
+-#include <asm/pgtable.h>
+-#include <asm/smp.h>
+-#include <asm/rtas.h>
+-#include <asm/xics.h>
+-#include <asm/hvcall.h>
+-#include <asm/machdep.h>
+-
+-#include "i8259.h"
+-
+-static unsigned int xics_startup(unsigned int irq);
+-static void xics_enable_irq(unsigned int irq);
+-static void xics_disable_irq(unsigned int irq);
+-static void xics_mask_and_ack_irq(unsigned int irq);
+-static void xics_end_irq(unsigned int irq);
+-static void xics_set_affinity(unsigned int irq_nr, cpumask_t cpumask);
+-
+-static struct hw_interrupt_type xics_pic = {
+-	.typename = " XICS     ",
+-	.startup = xics_startup,
+-	.enable = xics_enable_irq,
+-	.disable = xics_disable_irq,
+-	.ack = xics_mask_and_ack_irq,
+-	.end = xics_end_irq,
+-	.set_affinity = xics_set_affinity
+-};
+-
+-static struct hw_interrupt_type xics_8259_pic = {
+-	.typename = " XICS/8259",
+-	.ack = xics_mask_and_ack_irq,
+-};
+-
+-/* This is used to map real irq numbers to virtual */
+-static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC);
+-
+-#define XICS_IPI		2
+-#define XICS_IRQ_SPURIOUS	0
+-
+-/* Want a priority other than 0.  Various HW issues require this. */
+-#define	DEFAULT_PRIORITY	5
+-
+-/* 
+- * Mark IPIs as higher priority so we can take them inside interrupts that
+- * arent marked SA_INTERRUPT
+- */
+-#define IPI_PRIORITY		4
+-
+-struct xics_ipl {
+-	union {
+-		u32 word;
+-		u8 bytes[4];
+-	} xirr_poll;
+-	union {
+-		u32 word;
+-		u8 bytes[4];
+-	} xirr;
+-	u32 dummy;
+-	union {
+-		u32 word;
+-		u8 bytes[4];
+-	} qirr;
+-};
+-
+-static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS];
+-
+-static int xics_irq_8259_cascade = 0;
+-static int xics_irq_8259_cascade_real = 0;
+-static unsigned int default_server = 0xFF;
+-static unsigned int default_distrib_server = 0;
+-static unsigned int interrupt_server_size = 8;
+-
+-/*
+- * XICS only has a single IPI, so encode the messages per CPU
+- */
+-struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
+-
+-/* RTAS service tokens */
+-static int ibm_get_xive;
+-static int ibm_set_xive;
+-static int ibm_int_on;
+-static int ibm_int_off;
+-
+-typedef struct {
+-	int (*xirr_info_get)(int cpu);
+-	void (*xirr_info_set)(int cpu, int val);
+-	void (*cppr_info)(int cpu, u8 val);
+-	void (*qirr_info)(int cpu, u8 val);
+-} xics_ops;
+-
+-
+-/* SMP */
+-
+-static int pSeries_xirr_info_get(int n_cpu)
+-{
+-	return in_be32(&xics_per_cpu[n_cpu]->xirr.word);
+-}
+-
+-static void pSeries_xirr_info_set(int n_cpu, int value)
+-{
+-	out_be32(&xics_per_cpu[n_cpu]->xirr.word, value);
+-}
+-
+-static void pSeries_cppr_info(int n_cpu, u8 value)
+-{
+-	out_8(&xics_per_cpu[n_cpu]->xirr.bytes[0], value);
+-}
+-
+-static void pSeries_qirr_info(int n_cpu, u8 value)
+-{
+-	out_8(&xics_per_cpu[n_cpu]->qirr.bytes[0], value);
+-}
+-
+-static xics_ops pSeries_ops = {
+-	pSeries_xirr_info_get,
+-	pSeries_xirr_info_set,
+-	pSeries_cppr_info,
+-	pSeries_qirr_info
+-};
+-
+-static xics_ops *ops = &pSeries_ops;
+-
+-
+-/* LPAR */
+-
+-static inline long plpar_eoi(unsigned long xirr)
+-{
+-	return plpar_hcall_norets(H_EOI, xirr);
+-}
+-
+-static inline long plpar_cppr(unsigned long cppr)
+-{
+-	return plpar_hcall_norets(H_CPPR, cppr);
+-}
+-
+-static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
+-{
+-	return plpar_hcall_norets(H_IPI, servernum, mfrr);
+-}
+-
+-static inline long plpar_xirr(unsigned long *xirr_ret)
+-{
+-	unsigned long dummy;
+-	return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy);
+-}
+-
+-static int pSeriesLP_xirr_info_get(int n_cpu)
+-{
+-	unsigned long lpar_rc;
+-	unsigned long return_value; 
+-
+-	lpar_rc = plpar_xirr(&return_value);
+-	if (lpar_rc != H_Success)
+-		panic(" bad return code xirr - rc = %lx \n", lpar_rc); 
+-	return (int)return_value;
+-}
+-
+-static void pSeriesLP_xirr_info_set(int n_cpu, int value)
+-{
+-	unsigned long lpar_rc;
+-	unsigned long val64 = value & 0xffffffff;
+-
+-	lpar_rc = plpar_eoi(val64);
+-	if (lpar_rc != H_Success)
+-		panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc,
+-		      val64); 
+-}
+-
+-void pSeriesLP_cppr_info(int n_cpu, u8 value)
+-{
+-	unsigned long lpar_rc;
+-
+-	lpar_rc = plpar_cppr(value);
+-	if (lpar_rc != H_Success)
+-		panic("bad return code cppr - rc = %lx\n", lpar_rc); 
+-}
+-
+-static void pSeriesLP_qirr_info(int n_cpu , u8 value)
+-{
+-	unsigned long lpar_rc;
+-
+-	lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu), value);
+-	if (lpar_rc != H_Success)
+-		panic("bad return code qirr - rc = %lx\n", lpar_rc); 
+-}
+-
+-xics_ops pSeriesLP_ops = {
+-	pSeriesLP_xirr_info_get,
+-	pSeriesLP_xirr_info_set,
+-	pSeriesLP_cppr_info,
+-	pSeriesLP_qirr_info
+-};
+-
+-static unsigned int xics_startup(unsigned int virq)
+-{
+-	unsigned int irq;
+-
+-	irq = irq_offset_down(virq);
+-	if (radix_tree_insert(&irq_map, virt_irq_to_real(irq),
+-			      &virt_irq_to_real_map[irq]) == -ENOMEM)
+-		printk(KERN_CRIT "Out of memory creating real -> virtual"
+-		       " IRQ mapping for irq %u (real 0x%x)\n",
+-		       virq, virt_irq_to_real(irq));
+-	xics_enable_irq(virq);
+-	return 0;	/* return value is ignored */
+-}
+-
+-static unsigned int real_irq_to_virt(unsigned int real_irq)
+-{
+-	unsigned int *ptr;
+-
+-	ptr = radix_tree_lookup(&irq_map, real_irq);
+-	if (ptr == NULL)
+-		return NO_IRQ;
+-	return ptr - virt_irq_to_real_map;
+-}
+-
+-#ifdef CONFIG_SMP
+-static int get_irq_server(unsigned int irq)
+-{
+-	unsigned int server;
+-	/* For the moment only implement delivery to all cpus or one cpu */
+-	cpumask_t cpumask = irq_affinity[irq];
+-	cpumask_t tmp = CPU_MASK_NONE;
+-
+-	if (!distribute_irqs)
+-		return default_server;
+-
+-	if (cpus_equal(cpumask, CPU_MASK_ALL)) {
+-		server = default_distrib_server;
+-	} else {
+-		cpus_and(tmp, cpu_online_map, cpumask);
+-
+-		if (cpus_empty(tmp))
+-			server = default_distrib_server;
+-		else
+-			server = get_hard_smp_processor_id(first_cpu(tmp));
+-	}
+-
+-	return server;
+-
+-}
+-#else
+-static int get_irq_server(unsigned int irq)
+-{
+-	return default_server;
+-}
+-#endif
+-
+-static void xics_enable_irq(unsigned int virq)
+-{
+-	unsigned int irq;
+-	int call_status;
+-	unsigned int server;
+-
+-	irq = virt_irq_to_real(irq_offset_down(virq));
+-	if (irq == XICS_IPI)
+-		return;
+-
+-	server = get_irq_server(virq);
+-	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
+-				DEFAULT_PRIORITY);
+-	if (call_status != 0) {
+-		printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_set_xive "
+-		       "returned %d\n", irq, call_status);
+-		printk("set_xive %x, server %x\n", ibm_set_xive, server);
+-		return;
+-	}
+-
+-	/* Now unmask the interrupt (often a no-op) */
+-	call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
+-	if (call_status != 0) {
+-		printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_int_on "
+-		       "returned %d\n", irq, call_status);
+-		return;
+-	}
+-}
+-
+-static void xics_disable_real_irq(unsigned int irq)
+-{
+-	int call_status;
+-	unsigned int server;
+-
+-	if (irq == XICS_IPI)
+-		return;
+-
+-	call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
+-	if (call_status != 0) {
+-		printk(KERN_ERR "xics_disable_real_irq: irq=%u: "
+-		       "ibm_int_off returned %d\n", irq, call_status);
+-		return;
+-	}
+-
+-	server = get_irq_server(irq);
+-	/* Have to set XIVE to 0xff to be able to remove a slot */
+-	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 0xff);
+-	if (call_status != 0) {
+-		printk(KERN_ERR "xics_disable_irq: irq=%u: ibm_set_xive(0xff)"
+-		       " returned %d\n", irq, call_status);
+-		return;
+-	}
+-}
+-
+-static void xics_disable_irq(unsigned int virq)
+-{
+-	unsigned int irq;
+-
+-	irq = virt_irq_to_real(irq_offset_down(virq));
+-	xics_disable_real_irq(irq);
+-}
+-
+-static void xics_end_irq(unsigned int irq)
+-{
+-	int cpu = smp_processor_id();
+-
+-	iosync();
+-	ops->xirr_info_set(cpu, ((0xff << 24) |
+-				 (virt_irq_to_real(irq_offset_down(irq)))));
+-
+-}
+-
+-static void xics_mask_and_ack_irq(unsigned int irq)
+-{
+-	int cpu = smp_processor_id();
+-
+-	if (irq < irq_offset_value()) {
+-		i8259_pic.ack(irq);
+-		iosync();
+-		ops->xirr_info_set(cpu, ((0xff<<24) |
+-					 xics_irq_8259_cascade_real));
+-		iosync();
+-	}
+-}
+-
+-int xics_get_irq(struct pt_regs *regs)
+-{
+-	unsigned int cpu = smp_processor_id();
+-	unsigned int vec;
+-	int irq;
+-
+-	vec = ops->xirr_info_get(cpu);
+-	/*  (vec >> 24) == old priority */
+-	vec &= 0x00ffffff;
+-
+-	/* for sanity, this had better be < NR_IRQS - 16 */
+-	if (vec == xics_irq_8259_cascade_real) {
+-		irq = i8259_irq(cpu);
+-		if (irq == -1) {
+-			/* Spurious cascaded interrupt.  Still must ack xics */
+-			xics_end_irq(irq_offset_up(xics_irq_8259_cascade));
+-
+-			irq = -1;
+-		}
+-	} else if (vec == XICS_IRQ_SPURIOUS) {
+-		irq = -1;
+-	} else {
+-		irq = real_irq_to_virt(vec);
+-		if (irq == NO_IRQ)
+-			irq = real_irq_to_virt_slowpath(vec);
+-		if (irq == NO_IRQ) {
+-			printk(KERN_ERR "Interrupt %u (real) is invalid,"
+-			       " disabling it.\n", vec);
+-			xics_disable_real_irq(vec);
+-		} else
+-			irq = irq_offset_up(irq);
+-	}
+-	return irq;
+-}
+-
+-#ifdef CONFIG_SMP
+-
+-irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+-{
+-	int cpu = smp_processor_id();
+-
+-	ops->qirr_info(cpu, 0xff);
+-
+-	WARN_ON(cpu_is_offline(cpu));
+-
+-	while (xics_ipi_message[cpu].value) {
+-		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
+-				       &xics_ipi_message[cpu].value)) {
+-			mb();
+-			smp_message_recv(PPC_MSG_CALL_FUNCTION, regs);
+-		}
+-		if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
+-				       &xics_ipi_message[cpu].value)) {
+-			mb();
+-			smp_message_recv(PPC_MSG_RESCHEDULE, regs);
+-		}
+-#if 0
+-		if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK,
+-				       &xics_ipi_message[cpu].value)) {
+-			mb();
+-			smp_message_recv(PPC_MSG_MIGRATE_TASK, regs);
+-		}
+-#endif
+-#ifdef CONFIG_DEBUGGER
+-		if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
+-				       &xics_ipi_message[cpu].value)) {
+-			mb();
+-			smp_message_recv(PPC_MSG_DEBUGGER_BREAK, regs);
+-		}
+-#endif
+-	}
+-	return IRQ_HANDLED;
+-}
+-
+-void xics_cause_IPI(int cpu)
+-{
+-	ops->qirr_info(cpu, IPI_PRIORITY);
+-}
+-#endif /* CONFIG_SMP */
+-
+-void xics_setup_cpu(void)
+-{
+-	int cpu = smp_processor_id();
+-
+-	ops->cppr_info(cpu, 0xff);
+-	iosync();
+-
+-	/*
+-	 * Put the calling processor into the GIQ.  This is really only
+-	 * necessary from a secondary thread as the OF start-cpu interface
+-	 * performs this function for us on primary threads.
+-	 *
+-	 * XXX: undo of teardown on kexec needs this too, as may hotplug
+-	 */
+-	rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+-		(1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
+-}
+-
+-void xics_init_IRQ(void)
+-{
+-	int i;
+-	unsigned long intr_size = 0;
+-	struct device_node *np;
+-	uint *ireg, ilen, indx = 0;
+-	unsigned long intr_base = 0;
+-	struct xics_interrupt_node {
+-		unsigned long addr;
+-		unsigned long size;
+-	} intnodes[NR_CPUS]; 
+-
+-	ppc64_boot_msg(0x20, "XICS Init");
+-
+-	ibm_get_xive = rtas_token("ibm,get-xive");
+-	ibm_set_xive = rtas_token("ibm,set-xive");
+-	ibm_int_on  = rtas_token("ibm,int-on");
+-	ibm_int_off = rtas_token("ibm,int-off");
+-
+-	np = of_find_node_by_type(NULL, "PowerPC-External-Interrupt-Presentation");
+-	if (!np)
+-		panic("xics_init_IRQ: can't find interrupt presentation");
+-
+-nextnode:
+-	ireg = (uint *)get_property(np, "ibm,interrupt-server-ranges", NULL);
+-	if (ireg) {
+-		/*
+-		 * set node starting index for this node
+-		 */
+-		indx = *ireg;
+-	}
+-
+-	ireg = (uint *)get_property(np, "reg", &ilen);
+-	if (!ireg)
+-		panic("xics_init_IRQ: can't find interrupt reg property");
+-	
+-	while (ilen) {
+-		intnodes[indx].addr = (unsigned long)*ireg++ << 32;
+-		ilen -= sizeof(uint);
+-		intnodes[indx].addr |= *ireg++;
+-		ilen -= sizeof(uint);
+-		intnodes[indx].size = (unsigned long)*ireg++ << 32;
+-		ilen -= sizeof(uint);
+-		intnodes[indx].size |= *ireg++;
+-		ilen -= sizeof(uint);
+-		indx++;
+-		if (indx >= NR_CPUS) break;
+-	}
+-
+-	np = of_find_node_by_type(np, "PowerPC-External-Interrupt-Presentation");
+-	if ((indx < NR_CPUS) && np) goto nextnode;
+-
+-	/* Find the server numbers for the boot cpu. */
+-	for (np = of_find_node_by_type(NULL, "cpu");
+-	     np;
+-	     np = of_find_node_by_type(np, "cpu")) {
+-		ireg = (uint *)get_property(np, "reg", &ilen);
+-		if (ireg && ireg[0] == boot_cpuid_phys) {
+-			ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s",
+-						    &ilen);
+-			i = ilen / sizeof(int);
+-			if (ireg && i > 0) {
+-				default_server = ireg[0];
+-				default_distrib_server = ireg[i-1]; /* take last element */
+-			}
+-			ireg = (uint *)get_property(np,
+-					"ibm,interrupt-server#-size", NULL);
+-			if (ireg)
+-				interrupt_server_size = *ireg;
+-			break;
+-		}
+-	}
+-	of_node_put(np);
+-
+-	intr_base = intnodes[0].addr;
+-	intr_size = intnodes[0].size;
+-
+-	np = of_find_node_by_type(NULL, "interrupt-controller");
+-	if (!np) {
+-		printk(KERN_WARNING "xics: no ISA interrupt controller\n");
+-		xics_irq_8259_cascade_real = -1;
+-		xics_irq_8259_cascade = -1;
+-	} else {
+-		ireg = (uint *) get_property(np, "interrupts", NULL);
+-		if (!ireg)
+-			panic("xics_init_IRQ: can't find ISA interrupts property");
+-
+-		xics_irq_8259_cascade_real = *ireg;
+-		xics_irq_8259_cascade
+-			= virt_irq_create_mapping(xics_irq_8259_cascade_real);
+-		of_node_put(np);
+-	}
+-
+-	if (systemcfg->platform == PLATFORM_PSERIES) {
+-#ifdef CONFIG_SMP
+-		for_each_cpu(i) {
+-			int hard_id;
+-
+-			/* FIXME: Do this dynamically! --RR */
+-			if (!cpu_present(i))
+-				continue;
+-
+-			hard_id = get_hard_smp_processor_id(i);
+-			xics_per_cpu[i] = ioremap(intnodes[hard_id].addr, 
+-						  intnodes[hard_id].size);
+-		}
+-#else
+-		xics_per_cpu[0] = ioremap(intr_base, intr_size);
+-#endif /* CONFIG_SMP */
+-	} else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
+-		ops = &pSeriesLP_ops;
+-	}
+-
+-	xics_8259_pic.enable = i8259_pic.enable;
+-	xics_8259_pic.disable = i8259_pic.disable;
+-	for (i = 0; i < 16; ++i)
+-		get_irq_desc(i)->handler = &xics_8259_pic;
+-	for (; i < NR_IRQS; ++i)
+-		get_irq_desc(i)->handler = &xics_pic;
+-
+-	xics_setup_cpu();
+-
+-	ppc64_boot_msg(0x21, "XICS Done");
+-}
+-
+-/*
+- * We cant do this in init_IRQ because we need the memory subsystem up for
+- * request_irq()
+- */
+-static int __init xics_setup_i8259(void)
+-{
+-	if (ppc64_interrupt_controller == IC_PPC_XIC &&
+-	    xics_irq_8259_cascade != -1) {
+-		if (request_irq(irq_offset_up(xics_irq_8259_cascade),
+-				no_action, 0, "8259 cascade", NULL))
+-			printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 "
+-					"cascade\n");
+-		i8259_init(0);
+-	}
+-	return 0;
+-}
+-arch_initcall(xics_setup_i8259);
+-
+-#ifdef CONFIG_SMP
+-void xics_request_IPIs(void)
+-{
+-	virt_irq_to_real_map[XICS_IPI] = XICS_IPI;
+-
+-	/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
+-	request_irq(irq_offset_up(XICS_IPI), xics_ipi_action, SA_INTERRUPT,
+-		    "IPI", NULL);
+-	get_irq_desc(irq_offset_up(XICS_IPI))->status |= IRQ_PER_CPU;
+-}
+-#endif
+-
+-static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
+-{
+-	unsigned int irq;
+-	int status;
+-	int xics_status[2];
+-	unsigned long newmask;
+-	cpumask_t tmp = CPU_MASK_NONE;
+-
+-	irq = virt_irq_to_real(irq_offset_down(virq));
+-	if (irq == XICS_IPI || irq == NO_IRQ)
+-		return;
+-
+-	status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
+-
+-	if (status) {
+-		printk(KERN_ERR "xics_set_affinity: irq=%u ibm,get-xive "
+-		       "returns %d\n", irq, status);
+-		return;
+-	}
+-
+-	/* For the moment only implement delivery to all cpus or one cpu */
+-	if (cpus_equal(cpumask, CPU_MASK_ALL)) {
+-		newmask = default_distrib_server;
+-	} else {
+-		cpus_and(tmp, cpu_online_map, cpumask);
+-		if (cpus_empty(tmp))
+-			return;
+-		newmask = get_hard_smp_processor_id(first_cpu(tmp));
+-	}
+-
+-	status = rtas_call(ibm_set_xive, 3, 1, NULL,
+-				irq, newmask, xics_status[1]);
+-
+-	if (status) {
+-		printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive "
+-		       "returns %d\n", irq, status);
+-		return;
+-	}
+-}
+-
+-void xics_teardown_cpu(int secondary)
+-{
+-	int cpu = smp_processor_id();
+-
+-	ops->cppr_info(cpu, 0x00);
+-	iosync();
+-
+-	/*
+-	 * Some machines need to have at least one cpu in the GIQ,
+-	 * so leave the master cpu in the group.
+-	 */
+-	if (secondary) {
+-		/*
+-		 * we need to EOI the IPI if we got here from kexec down IPI
+-		 *
+-		 * probably need to check all the other interrupts too
+-		 * should we be flagging idle loop instead?
+-		 * or creating some task to be scheduled?
+-		 */
+-		ops->xirr_info_set(cpu, XICS_IPI);
+-		rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+-			(1UL << interrupt_server_size) - 1 -
+-			default_distrib_server, 0);
+-	}
+-}
+-
+-#ifdef CONFIG_HOTPLUG_CPU
+-
+-/* Interrupts are disabled. */
+-void xics_migrate_irqs_away(void)
+-{
+-	int status;
+-	unsigned int irq, virq, cpu = smp_processor_id();
+-
+-	/* Reject any interrupt that was queued to us... */
+-	ops->cppr_info(cpu, 0);
+-	iosync();
+-
+-	/* remove ourselves from the global interrupt queue */
+-	status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+-		(1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
+-	WARN_ON(status < 0);
+-
+-	/* Allow IPIs again... */
+-	ops->cppr_info(cpu, DEFAULT_PRIORITY);
+-	iosync();
+-
+-	for_each_irq(virq) {
+-		irq_desc_t *desc;
+-		int xics_status[2];
+-		unsigned long flags;
+-
+-		/* We cant set affinity on ISA interrupts */
+-		if (virq < irq_offset_value())
+-			continue;
+-
+-		desc = get_irq_desc(virq);
+-		irq = virt_irq_to_real(irq_offset_down(virq));
+-
+-		/* We need to get IPIs still. */
+-		if (irq == XICS_IPI || irq == NO_IRQ)
+-			continue;
+-
+-		/* We only need to migrate enabled IRQS */
+-		if (desc == NULL || desc->handler == NULL
+-		    || desc->action == NULL
+-		    || desc->handler->set_affinity == NULL)
+-			continue;
+-
+-		spin_lock_irqsave(&desc->lock, flags);
+-
+-		status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
+-		if (status) {
+-			printk(KERN_ERR "migrate_irqs_away: irq=%u "
+-					"ibm,get-xive returns %d\n",
+-					virq, status);
+-			goto unlock;
+-		}
+-
+-		/*
+-		 * We only support delivery to all cpus or to one cpu.
+-		 * The irq has to be migrated only in the single cpu
+-		 * case.
+-		 */
+-		if (xics_status[0] != get_hard_smp_processor_id(cpu))
+-			goto unlock;
+-
+-		printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
+-		       virq, cpu);
+-
+-		/* Reset affinity to all cpus */
+-		desc->handler->set_affinity(virq, CPU_MASK_ALL);
+-		irq_affinity[virq] = CPU_MASK_ALL;
+-unlock:
+-		spin_unlock_irqrestore(&desc->lock, flags);
+-	}
+-}
+-#endif
+diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile
+--- a/arch/ppc64/lib/Makefile
++++ b/arch/ppc64/lib/Makefile
+@@ -2,17 +2,4 @@
+ # Makefile for ppc64-specific library files..
+ #
+ 
+-lib-y := checksum.o string.o strcase.o
+-lib-y += copypage.o memcpy.o copyuser.o usercopy.o
+-
+-# Lock primitives are defined as no-ops in include/linux/spinlock.h
+-# for non-SMP configs. Don't build the real versions.
+-
+-lib-$(CONFIG_SMP) += locks.o
+-
+-# e2a provides EBCDIC to ASCII conversions.
+-ifdef CONFIG_PPC_ISERIES
+-obj-y += e2a.o
+-endif
+-
+-lib-$(CONFIG_DEBUG_KERNEL) += sstep.o
++lib-y := string.o
+diff --git a/arch/ppc64/lib/checksum.S b/arch/ppc64/lib/checksum.S
+deleted file mode 100644
+--- a/arch/ppc64/lib/checksum.S
++++ /dev/null
+@@ -1,229 +0,0 @@
+-/*
+- * This file contains assembly-language implementations
+- * of IP-style 1's complement checksum routines.
+- *	
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.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.
+- *
+- * Severely hacked about by Paul Mackerras (paulus at cs.anu.edu.au).
+- */
+-
+-#include <linux/sys.h>
+-#include <asm/processor.h>
+-#include <asm/errno.h>
+-#include <asm/ppc_asm.h>
+-
+-/*
+- * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header
+- * len is in words and is always >= 5.
+- *
+- * In practice len == 5, but this is not guaranteed.  So this code does not
+- * attempt to use doubleword instructions.
+- */
+-_GLOBAL(ip_fast_csum)
+-	lwz	r0,0(r3)
+-	lwzu	r5,4(r3)
+-	addic.	r4,r4,-2
+-	addc	r0,r0,r5
+-	mtctr	r4
+-	blelr-
+-1:	lwzu	r4,4(r3)
+-	adde	r0,r0,r4
+-	bdnz	1b
+-	addze	r0,r0		/* add in final carry */
+-        rldicl  r4,r0,32,0      /* fold two 32-bit halves together */
+-        add     r0,r0,r4
+-        srdi    r0,r0,32
+-	rlwinm	r3,r0,16,0,31	/* fold two halves together */
+-	add	r3,r0,r3
+-	not	r3,r3
+-	srwi	r3,r3,16
+-	blr
+-
+-/*
+- * Compute checksum of TCP or UDP pseudo-header:
+- *   csum_tcpudp_magic(r3=saddr, r4=daddr, r5=len, r6=proto, r7=sum)
+- * No real gain trying to do this specially for 64 bit, but
+- * the 32 bit addition may spill into the upper bits of
+- * the doubleword so we still must fold it down from 64.
+- */	
+-_GLOBAL(csum_tcpudp_magic)
+-	rlwimi	r5,r6,16,0,15	/* put proto in upper half of len */
+-	addc	r0,r3,r4	/* add 4 32-bit words together */
+-	adde	r0,r0,r5
+-	adde	r0,r0,r7
+-        rldicl  r4,r0,32,0      /* fold 64 bit value */
+-        add     r0,r4,r0
+-        srdi    r0,r0,32
+-	rlwinm	r3,r0,16,0,31	/* fold two halves together */
+-	add	r3,r0,r3
+-	not	r3,r3
+-	srwi	r3,r3,16
+-	blr
+-
+-/*
+- * Computes the checksum of a memory block at buff, length len,
+- * and adds in "sum" (32-bit).
+- *
+- * This code assumes at least halfword alignment, though the length
+- * can be any number of bytes.  The sum is accumulated in r5.
+- *
+- * csum_partial(r3=buff, r4=len, r5=sum)
+- */
+-_GLOBAL(csum_partial)
+-        subi	r3,r3,8		/* we'll offset by 8 for the loads */
+-        srdi.	r6,r4,3         /* divide by 8 for doubleword count */
+-        addic   r5,r5,0         /* clear carry */
+-        beq	3f              /* if we're doing < 8 bytes */
+-        andi.	r0,r3,2         /* aligned on a word boundary already? */
+-        beq+	1f
+-        lhz     r6,8(r3)        /* do 2 bytes to get aligned */
+-        addi    r3,r3,2
+-        subi    r4,r4,2
+-        addc    r5,r5,r6
+-        srdi.   r6,r4,3         /* recompute number of doublewords */
+-        beq     3f              /* any left? */
+-1:      mtctr   r6
+-2:      ldu     r6,8(r3)        /* main sum loop */
+-        adde    r5,r5,r6
+-        bdnz    2b
+-        andi.	r4,r4,7         /* compute bytes left to sum after doublewords */
+-3:	cmpwi	0,r4,4		/* is at least a full word left? */
+-	blt	4f
+-	lwz	r6,8(r3)	/* sum this word */
+-	addi	r3,r3,4
+-	subi	r4,r4,4
+-	adde	r5,r5,r6
+-4:	cmpwi	0,r4,2		/* is at least a halfword left? */
+-        blt+	5f
+-        lhz     r6,8(r3)        /* sum this halfword */
+-        addi    r3,r3,2
+-        subi    r4,r4,2
+-        adde    r5,r5,r6
+-5:	cmpwi	0,r4,1		/* is at least a byte left? */
+-        bne+    6f
+-        lbz     r6,8(r3)        /* sum this byte */
+-        slwi    r6,r6,8         /* this byte is assumed to be the upper byte of a halfword */
+-        adde    r5,r5,r6
+-6:      addze	r5,r5		/* add in final carry */
+-	rldicl  r4,r5,32,0      /* fold two 32-bit halves together */
+-        add     r3,r4,r5
+-        srdi    r3,r3,32
+-        blr
+-
+-/*
+- * Computes the checksum of a memory block at src, length len,
+- * and adds in "sum" (32-bit), while copying the block to dst.
+- * If an access exception occurs on src or dst, it stores -EFAULT
+- * to *src_err or *dst_err respectively, and (for an error on
+- * src) zeroes the rest of dst.
+- *
+- * This code needs to be reworked to take advantage of 64 bit sum+copy.
+- * However, due to tokenring halfword alignment problems this will be very
+- * tricky.  For now we'll leave it until we instrument it somehow.
+- *
+- * csum_partial_copy_generic(r3=src, r4=dst, r5=len, r6=sum, r7=src_err, r8=dst_err)
+- */
+-_GLOBAL(csum_partial_copy_generic)
+-	addic	r0,r6,0
+-	subi	r3,r3,4
+-	subi	r4,r4,4
+-	srwi.	r6,r5,2
+-	beq	3f		/* if we're doing < 4 bytes */
+-	andi.	r9,r4,2		/* Align dst to longword boundary */
+-	beq+	1f
+-81:	lhz	r6,4(r3)	/* do 2 bytes to get aligned */
+-	addi	r3,r3,2
+-	subi	r5,r5,2
+-91:	sth	r6,4(r4)
+-	addi	r4,r4,2
+-	addc	r0,r0,r6
+-	srwi.	r6,r5,2		/* # words to do */
+-	beq	3f
+-1:	mtctr	r6
+-82:	lwzu	r6,4(r3)	/* the bdnz has zero overhead, so it should */
+-92:	stwu	r6,4(r4)	/* be unnecessary to unroll this loop */
+-	adde	r0,r0,r6
+-	bdnz	82b
+-	andi.	r5,r5,3
+-3:	cmpwi	0,r5,2
+-	blt+	4f
+-83:	lhz	r6,4(r3)
+-	addi	r3,r3,2
+-	subi	r5,r5,2
+-93:	sth	r6,4(r4)
+-	addi	r4,r4,2
+-	adde	r0,r0,r6
+-4:	cmpwi	0,r5,1
+-	bne+	5f
+-84:	lbz	r6,4(r3)
+-94:	stb	r6,4(r4)
+-	slwi	r6,r6,8		/* Upper byte of word */
+-	adde	r0,r0,r6
+-5:	addze	r3,r0		/* add in final carry (unlikely with 64-bit regs) */
+-        rldicl  r4,r3,32,0      /* fold 64 bit value */
+-        add     r3,r4,r3
+-        srdi    r3,r3,32
+-	blr
+-
+-/* These shouldn't go in the fixup section, since that would
+-   cause the ex_table addresses to get out of order. */
+-
+-	.globl src_error_1
+-src_error_1:
+-	li	r6,0
+-	subi	r5,r5,2
+-95:	sth	r6,4(r4)
+-	addi	r4,r4,2
+-	srwi.	r6,r5,2
+-	beq	3f
+-	mtctr	r6
+-	.globl src_error_2
+-src_error_2:
+-	li	r6,0
+-96:	stwu	r6,4(r4)
+-	bdnz	96b
+-3:	andi.	r5,r5,3
+-	beq	src_error
+-	.globl src_error_3
+-src_error_3:
+-	li	r6,0
+-	mtctr	r5
+-	addi	r4,r4,3
+-97:	stbu	r6,1(r4)
+-	bdnz	97b
+-	.globl src_error
+-src_error:
+-	cmpdi	0,r7,0
+-	beq	1f
+-	li	r6,-EFAULT
+-	stw	r6,0(r7)
+-1:	addze	r3,r0
+-	blr
+-
+-	.globl dst_error
+-dst_error:
+-	cmpdi	0,r8,0
+-	beq	1f
+-	li	r6,-EFAULT
+-	stw	r6,0(r8)
+-1:	addze	r3,r0
+-	blr
+-
+-.section __ex_table,"a"
+-	.align  3
+-	.llong	81b,src_error_1
+-	.llong	91b,dst_error
+-	.llong	82b,src_error_2
+-	.llong	92b,dst_error
+-	.llong	83b,src_error_3
+-	.llong	93b,dst_error
+-	.llong	84b,src_error_3
+-	.llong	94b,dst_error
+-	.llong	95b,dst_error
+-	.llong	96b,dst_error
+-	.llong	97b,dst_error
+diff --git a/arch/ppc64/lib/copypage.S b/arch/ppc64/lib/copypage.S
+deleted file mode 100644
+--- a/arch/ppc64/lib/copypage.S
++++ /dev/null
+@@ -1,121 +0,0 @@
+-/*
+- * arch/ppc64/lib/copypage.S
+- *
+- * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-#include <asm/processor.h>
+-#include <asm/ppc_asm.h>
+-
+-_GLOBAL(copy_page)
+-	std	r31,-8(1)
+-	std	r30,-16(1)
+-	std	r29,-24(1)
+-	std	r28,-32(1)
+-	std	r27,-40(1)
+-	std	r26,-48(1)
+-	std	r25,-56(1)
+-	std	r24,-64(1)
+-	std	r23,-72(1)
+-	std	r22,-80(1)
+-	std	r21,-88(1)
+-	std	r20,-96(1)
+-	li	r5,4096/32 - 1
+-	addi	r3,r3,-8
+-	li	r12,5
+-0:	addi	r5,r5,-24
+-	mtctr	r12
+-	ld	r22,640(4)
+-	ld	r21,512(4)
+-	ld	r20,384(4)
+-	ld	r11,256(4)
+-	ld	r9,128(4)
+-	ld	r7,0(4)
+-	ld	r25,648(4)
+-	ld	r24,520(4)
+-	ld	r23,392(4)
+-	ld	r10,264(4)
+-	ld	r8,136(4)
+-	ldu	r6,8(4)
+-	cmpwi	r5,24
+-1:	std	r22,648(3)
+-	std	r21,520(3)
+-	std	r20,392(3)
+-	std	r11,264(3)
+-	std	r9,136(3)
+-	std	r7,8(3)
+-	ld	r28,648(4)
+-	ld	r27,520(4)
+-	ld	r26,392(4)
+-	ld	r31,264(4)
+-	ld	r30,136(4)
+-	ld	r29,8(4)
+-	std	r25,656(3)
+-	std	r24,528(3)
+-	std	r23,400(3)
+-	std	r10,272(3)
+-	std	r8,144(3)
+-	std	r6,16(3)
+-	ld	r22,656(4)
+-	ld	r21,528(4)
+-	ld	r20,400(4)
+-	ld	r11,272(4)
+-	ld	r9,144(4)
+-	ld	r7,16(4)
+-	std	r28,664(3)
+-	std	r27,536(3)
+-	std	r26,408(3)
+-	std	r31,280(3)
+-	std	r30,152(3)
+-	stdu	r29,24(3)
+-	ld	r25,664(4)
+-	ld	r24,536(4)
+-	ld	r23,408(4)
+-	ld	r10,280(4)
+-	ld	r8,152(4)
+-	ldu	r6,24(4)
+-	bdnz	1b
+-	std	r22,648(3)
+-	std	r21,520(3)
+-	std	r20,392(3)
+-	std	r11,264(3)
+-	std	r9,136(3)
+-	std	r7,8(3)
+-	addi	r4,r4,640
+-	addi	r3,r3,648
+-	bge	0b
+-	mtctr	r5
+-	ld	r7,0(4)
+-	ld	r8,8(4)
+-	ldu	r9,16(4)
+-3:	ld	r10,8(4)
+-	std	r7,8(3)
+-	ld	r7,16(4)
+-	std	r8,16(3)
+-	ld	r8,24(4)
+-	std	r9,24(3)
+-	ldu	r9,32(4)
+-	stdu	r10,32(3)
+-	bdnz	3b
+-4:	ld	r10,8(4)
+-	std	r7,8(3)
+-	std	r8,16(3)
+-	std	r9,24(3)
+-	std	r10,32(3)
+-9:	ld	r20,-96(1)
+-	ld	r21,-88(1)
+-	ld	r22,-80(1)
+-	ld	r23,-72(1)
+-	ld	r24,-64(1)
+-	ld	r25,-56(1)
+-	ld	r26,-48(1)
+-	ld	r27,-40(1)
+-	ld	r28,-32(1)
+-	ld	r29,-24(1)
+-	ld	r30,-16(1)
+-	ld	r31,-8(1)
+-	blr
+diff --git a/arch/ppc64/lib/copyuser.S b/arch/ppc64/lib/copyuser.S
+deleted file mode 100644
+--- a/arch/ppc64/lib/copyuser.S
++++ /dev/null
+@@ -1,576 +0,0 @@
+-/*
+- * arch/ppc64/lib/copyuser.S
+- *
+- * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-#include <asm/processor.h>
+-#include <asm/ppc_asm.h>
+-
+-	.align	7
+-_GLOBAL(__copy_tofrom_user)
+-	/* first check for a whole page copy on a page boundary */
+-	cmpldi	cr1,r5,16
+-	cmpdi	cr6,r5,4096
+-	or	r0,r3,r4
+-	neg	r6,r3		/* LS 3 bits = # bytes to 8-byte dest bdry */
+-	andi.	r0,r0,4095
+-	std	r3,-24(r1)
+-	crand	cr0*4+2,cr0*4+2,cr6*4+2
+-	std	r4,-16(r1)
+-	std	r5,-8(r1)
+-	dcbt	0,r4
+-	beq	.Lcopy_page
+-	andi.	r6,r6,7
+-	mtcrf	0x01,r5
+-	blt	cr1,.Lshort_copy
+-	bne	.Ldst_unaligned
+-.Ldst_aligned:
+-	andi.	r0,r4,7
+-	addi	r3,r3,-16
+-	bne	.Lsrc_unaligned
+-	srdi	r7,r5,4
+-20:	ld	r9,0(r4)
+-	addi	r4,r4,-8
+-	mtctr	r7
+-	andi.	r5,r5,7
+-	bf	cr7*4+0,22f
+-	addi	r3,r3,8
+-	addi	r4,r4,8
+-	mr	r8,r9
+-	blt	cr1,72f
+-21:	ld	r9,8(r4)
+-70:	std	r8,8(r3)
+-22:	ldu	r8,16(r4)
+-71:	stdu	r9,16(r3)
+-	bdnz	21b
+-72:	std	r8,8(r3)
+-	beq+	3f
+-	addi	r3,r3,16
+-23:	ld	r9,8(r4)
+-.Ldo_tail:
+-	bf	cr7*4+1,1f
+-	rotldi	r9,r9,32
+-73:	stw	r9,0(r3)
+-	addi	r3,r3,4
+-1:	bf	cr7*4+2,2f
+-	rotldi	r9,r9,16
+-74:	sth	r9,0(r3)
+-	addi	r3,r3,2
+-2:	bf	cr7*4+3,3f
+-	rotldi	r9,r9,8
+-75:	stb	r9,0(r3)
+-3:	li	r3,0
+-	blr
+-
+-.Lsrc_unaligned:
+-	srdi	r6,r5,3
+-	addi	r5,r5,-16
+-	subf	r4,r0,r4
+-	srdi	r7,r5,4
+-	sldi	r10,r0,3
+-	cmpldi	cr6,r6,3
+-	andi.	r5,r5,7
+-	mtctr	r7
+-	subfic	r11,r10,64
+-	add	r5,r5,r0
+-	bt	cr7*4+0,28f
+-
+-24:	ld	r9,0(r4)	/* 3+2n loads, 2+2n stores */
+-25:	ld	r0,8(r4)
+-	sld	r6,r9,r10
+-26:	ldu	r9,16(r4)
+-	srd	r7,r0,r11
+-	sld	r8,r0,r10
+-	or	r7,r7,r6
+-	blt	cr6,79f
+-27:	ld	r0,8(r4)
+-	b	2f
+-
+-28:	ld	r0,0(r4)	/* 4+2n loads, 3+2n stores */
+-29:	ldu	r9,8(r4)
+-	sld	r8,r0,r10
+-	addi	r3,r3,-8
+-	blt	cr6,5f
+-30:	ld	r0,8(r4)
+-	srd	r12,r9,r11
+-	sld	r6,r9,r10
+-31:	ldu	r9,16(r4)
+-	or	r12,r8,r12
+-	srd	r7,r0,r11
+-	sld	r8,r0,r10
+-	addi	r3,r3,16
+-	beq	cr6,78f
+-
+-1:	or	r7,r7,r6
+-32:	ld	r0,8(r4)
+-76:	std	r12,8(r3)
+-2:	srd	r12,r9,r11
+-	sld	r6,r9,r10
+-33:	ldu	r9,16(r4)
+-	or	r12,r8,r12
+-77:	stdu	r7,16(r3)
+-	srd	r7,r0,r11
+-	sld	r8,r0,r10
+-	bdnz	1b
+-
+-78:	std	r12,8(r3)
+-	or	r7,r7,r6
+-79:	std	r7,16(r3)
+-5:	srd	r12,r9,r11
+-	or	r12,r8,r12
+-80:	std	r12,24(r3)
+-	bne	6f
+-	li	r3,0
+-	blr
+-6:	cmpwi	cr1,r5,8
+-	addi	r3,r3,32
+-	sld	r9,r9,r10
+-	ble	cr1,.Ldo_tail
+-34:	ld	r0,8(r4)
+-	srd	r7,r0,r11
+-	or	r9,r7,r9
+-	b	.Ldo_tail
+-
+-.Ldst_unaligned:
+-	mtcrf	0x01,r6		/* put #bytes to 8B bdry into cr7 */
+-	subf	r5,r6,r5
+-	li	r7,0
+-	cmpldi	r1,r5,16
+-	bf	cr7*4+3,1f
+-35:	lbz	r0,0(r4)
+-81:	stb	r0,0(r3)
+-	addi	r7,r7,1
+-1:	bf	cr7*4+2,2f
+-36:	lhzx	r0,r7,r4
+-82:	sthx	r0,r7,r3
+-	addi	r7,r7,2
+-2:	bf	cr7*4+1,3f
+-37:	lwzx	r0,r7,r4
+-83:	stwx	r0,r7,r3
+-3:	mtcrf	0x01,r5
+-	add	r4,r6,r4
+-	add	r3,r6,r3
+-	b	.Ldst_aligned
+-
+-.Lshort_copy:
+-	bf	cr7*4+0,1f
+-38:	lwz	r0,0(r4)
+-39:	lwz	r9,4(r4)
+-	addi	r4,r4,8
+-84:	stw	r0,0(r3)
+-85:	stw	r9,4(r3)
+-	addi	r3,r3,8
+-1:	bf	cr7*4+1,2f
+-40:	lwz	r0,0(r4)
+-	addi	r4,r4,4
+-86:	stw	r0,0(r3)
+-	addi	r3,r3,4
+-2:	bf	cr7*4+2,3f
+-41:	lhz	r0,0(r4)
+-	addi	r4,r4,2
+-87:	sth	r0,0(r3)
+-	addi	r3,r3,2
+-3:	bf	cr7*4+3,4f
+-42:	lbz	r0,0(r4)
+-88:	stb	r0,0(r3)
+-4:	li	r3,0
+-	blr
+-
+-/*
+- * exception handlers follow
+- * we have to return the number of bytes not copied
+- * for an exception on a load, we set the rest of the destination to 0
+- */
+-
+-136:
+-137:
+-	add	r3,r3,r7
+-	b	1f
+-130:
+-131:
+-	addi	r3,r3,8
+-120:
+-122:
+-124:
+-125:
+-126:
+-127:
+-128:
+-129:
+-133:
+-	addi	r3,r3,8
+-121:
+-132:
+-	addi	r3,r3,8
+-123:
+-134:
+-135:
+-138:
+-139:
+-140:
+-141:
+-142:
+-
+-/*
+- * here we have had a fault on a load and r3 points to the first
+- * unmodified byte of the destination
+- */
+-1:	ld	r6,-24(r1)
+-	ld	r4,-16(r1)
+-	ld	r5,-8(r1)
+-	subf	r6,r6,r3
+-	add	r4,r4,r6
+-	subf	r5,r6,r5	/* #bytes left to go */
+-
+-/*
+- * first see if we can copy any more bytes before hitting another exception
+- */
+-	mtctr	r5
+-43:	lbz	r0,0(r4)
+-	addi	r4,r4,1
+-89:	stb	r0,0(r3)
+-	addi	r3,r3,1
+-	bdnz	43b
+-	li	r3,0		/* huh? all copied successfully this time? */
+-	blr
+-
+-/*
+- * here we have trapped again, need to clear ctr bytes starting at r3
+- */
+-143:	mfctr	r5
+-	li	r0,0
+-	mr	r4,r3
+-	mr	r3,r5		/* return the number of bytes not copied */
+-1:	andi.	r9,r4,7
+-	beq	3f
+-90:	stb	r0,0(r4)
+-	addic.	r5,r5,-1
+-	addi	r4,r4,1
+-	bne	1b
+-	blr
+-3:	cmpldi	cr1,r5,8
+-	srdi	r9,r5,3
+-	andi.	r5,r5,7
+-	blt	cr1,93f
+-	mtctr	r9
+-91:	std	r0,0(r4)
+-	addi	r4,r4,8
+-	bdnz	91b
+-93:	beqlr
+-	mtctr	r5	
+-92:	stb	r0,0(r4)
+-	addi	r4,r4,1
+-	bdnz	92b
+-	blr
+-
+-/*
+- * exception handlers for stores: we just need to work
+- * out how many bytes weren't copied
+- */
+-182:
+-183:
+-	add	r3,r3,r7
+-	b	1f
+-180:
+-	addi	r3,r3,8
+-171:
+-177:
+-	addi	r3,r3,8
+-170:
+-172:
+-176:
+-178:
+-	addi	r3,r3,4
+-185:
+-	addi	r3,r3,4
+-173:
+-174:
+-175:
+-179:
+-181:
+-184:
+-186:
+-187:
+-188:
+-189:	
+-1:
+-	ld	r6,-24(r1)
+-	ld	r5,-8(r1)
+-	add	r6,r6,r5
+-	subf	r3,r3,r6	/* #bytes not copied */
+-190:
+-191:
+-192:
+-	blr			/* #bytes not copied in r3 */
+-
+-	.section __ex_table,"a"
+-	.align	3
+-	.llong	20b,120b
+-	.llong	21b,121b
+-	.llong	70b,170b
+-	.llong	22b,122b
+-	.llong	71b,171b
+-	.llong	72b,172b
+-	.llong	23b,123b
+-	.llong	73b,173b
+-	.llong	74b,174b
+-	.llong	75b,175b
+-	.llong	24b,124b
+-	.llong	25b,125b
+-	.llong	26b,126b
+-	.llong	27b,127b
+-	.llong	28b,128b
+-	.llong	29b,129b
+-	.llong	30b,130b
+-	.llong	31b,131b
+-	.llong	32b,132b
+-	.llong	76b,176b
+-	.llong	33b,133b
+-	.llong	77b,177b
+-	.llong	78b,178b
+-	.llong	79b,179b
+-	.llong	80b,180b
+-	.llong	34b,134b
+-	.llong	35b,135b
+-	.llong	81b,181b
+-	.llong	36b,136b
+-	.llong	82b,182b
+-	.llong	37b,137b
+-	.llong	83b,183b
+-	.llong	38b,138b
+-	.llong	39b,139b
+-	.llong	84b,184b
+-	.llong	85b,185b
+-	.llong	40b,140b
+-	.llong	86b,186b
+-	.llong	41b,141b
+-	.llong	87b,187b
+-	.llong	42b,142b
+-	.llong	88b,188b
+-	.llong	43b,143b
+-	.llong	89b,189b
+-	.llong	90b,190b
+-	.llong	91b,191b
+-	.llong	92b,192b
+-	
+-	.text
+-
+-/*
+- * Routine to copy a whole page of data, optimized for POWER4.
+- * On POWER4 it is more than 50% faster than the simple loop
+- * above (following the .Ldst_aligned label) but it runs slightly
+- * slower on POWER3.
+- */
+-.Lcopy_page:
+-	std	r31,-32(1)
+-	std	r30,-40(1)
+-	std	r29,-48(1)
+-	std	r28,-56(1)
+-	std	r27,-64(1)
+-	std	r26,-72(1)
+-	std	r25,-80(1)
+-	std	r24,-88(1)
+-	std	r23,-96(1)
+-	std	r22,-104(1)
+-	std	r21,-112(1)
+-	std	r20,-120(1)
+-	li	r5,4096/32 - 1
+-	addi	r3,r3,-8
+-	li	r0,5
+-0:	addi	r5,r5,-24
+-	mtctr	r0
+-20:	ld	r22,640(4)
+-21:	ld	r21,512(4)
+-22:	ld	r20,384(4)
+-23:	ld	r11,256(4)
+-24:	ld	r9,128(4)
+-25:	ld	r7,0(4)
+-26:	ld	r25,648(4)
+-27:	ld	r24,520(4)
+-28:	ld	r23,392(4)
+-29:	ld	r10,264(4)
+-30:	ld	r8,136(4)
+-31:	ldu	r6,8(4)
+-	cmpwi	r5,24
+-1:
+-32:	std	r22,648(3)
+-33:	std	r21,520(3)
+-34:	std	r20,392(3)
+-35:	std	r11,264(3)
+-36:	std	r9,136(3)
+-37:	std	r7,8(3)
+-38:	ld	r28,648(4)
+-39:	ld	r27,520(4)
+-40:	ld	r26,392(4)
+-41:	ld	r31,264(4)
+-42:	ld	r30,136(4)
+-43:	ld	r29,8(4)
+-44:	std	r25,656(3)
+-45:	std	r24,528(3)
+-46:	std	r23,400(3)
+-47:	std	r10,272(3)
+-48:	std	r8,144(3)
+-49:	std	r6,16(3)
+-50:	ld	r22,656(4)
+-51:	ld	r21,528(4)
+-52:	ld	r20,400(4)
+-53:	ld	r11,272(4)
+-54:	ld	r9,144(4)
+-55:	ld	r7,16(4)
+-56:	std	r28,664(3)
+-57:	std	r27,536(3)
+-58:	std	r26,408(3)
+-59:	std	r31,280(3)
+-60:	std	r30,152(3)
+-61:	stdu	r29,24(3)
+-62:	ld	r25,664(4)
+-63:	ld	r24,536(4)
+-64:	ld	r23,408(4)
+-65:	ld	r10,280(4)
+-66:	ld	r8,152(4)
+-67:	ldu	r6,24(4)
+-	bdnz	1b
+-68:	std	r22,648(3)
+-69:	std	r21,520(3)
+-70:	std	r20,392(3)
+-71:	std	r11,264(3)
+-72:	std	r9,136(3)
+-73:	std	r7,8(3)
+-74:	addi	r4,r4,640
+-75:	addi	r3,r3,648
+-	bge	0b
+-	mtctr	r5
+-76:	ld	r7,0(4)
+-77:	ld	r8,8(4)
+-78:	ldu	r9,16(4)
+-3:
+-79:	ld	r10,8(4)
+-80:	std	r7,8(3)
+-81:	ld	r7,16(4)
+-82:	std	r8,16(3)
+-83:	ld	r8,24(4)
+-84:	std	r9,24(3)
+-85:	ldu	r9,32(4)
+-86:	stdu	r10,32(3)
+-	bdnz	3b
+-4:
+-87:	ld	r10,8(4)
+-88:	std	r7,8(3)
+-89:	std	r8,16(3)
+-90:	std	r9,24(3)
+-91:	std	r10,32(3)
+-9:	ld	r20,-120(1)
+-	ld	r21,-112(1)
+-	ld	r22,-104(1)
+-	ld	r23,-96(1)
+-	ld	r24,-88(1)
+-	ld	r25,-80(1)
+-	ld	r26,-72(1)
+-	ld	r27,-64(1)
+-	ld	r28,-56(1)
+-	ld	r29,-48(1)
+-	ld	r30,-40(1)
+-	ld	r31,-32(1)
+-	li	r3,0
+-	blr
+-
+-/*
+- * on an exception, reset to the beginning and jump back into the
+- * standard __copy_tofrom_user
+- */
+-100:	ld	r20,-120(1)
+-	ld	r21,-112(1)
+-	ld	r22,-104(1)
+-	ld	r23,-96(1)
+-	ld	r24,-88(1)
+-	ld	r25,-80(1)
+-	ld	r26,-72(1)
+-	ld	r27,-64(1)
+-	ld	r28,-56(1)
+-	ld	r29,-48(1)
+-	ld	r30,-40(1)
+-	ld	r31,-32(1)
+-	ld	r3,-24(r1)
+-	ld	r4,-16(r1)
+-	li	r5,4096
+-	b	.Ldst_aligned
+-
+-	.section __ex_table,"a"
+-	.align	3
+-	.llong	20b,100b
+-	.llong	21b,100b
+-	.llong	22b,100b
+-	.llong	23b,100b
+-	.llong	24b,100b
+-	.llong	25b,100b
+-	.llong	26b,100b
+-	.llong	27b,100b
+-	.llong	28b,100b
+-	.llong	29b,100b
+-	.llong	30b,100b
+-	.llong	31b,100b
+-	.llong	32b,100b
+-	.llong	33b,100b
+-	.llong	34b,100b
+-	.llong	35b,100b
+-	.llong	36b,100b
+-	.llong	37b,100b
+-	.llong	38b,100b
+-	.llong	39b,100b
+-	.llong	40b,100b
+-	.llong	41b,100b
+-	.llong	42b,100b
+-	.llong	43b,100b
+-	.llong	44b,100b
+-	.llong	45b,100b
+-	.llong	46b,100b
+-	.llong	47b,100b
+-	.llong	48b,100b
+-	.llong	49b,100b
+-	.llong	50b,100b
+-	.llong	51b,100b
+-	.llong	52b,100b
+-	.llong	53b,100b
+-	.llong	54b,100b
+-	.llong	55b,100b
+-	.llong	56b,100b
+-	.llong	57b,100b
+-	.llong	58b,100b
+-	.llong	59b,100b
+-	.llong	60b,100b
+-	.llong	61b,100b
+-	.llong	62b,100b
+-	.llong	63b,100b
+-	.llong	64b,100b
+-	.llong	65b,100b
+-	.llong	66b,100b
+-	.llong	67b,100b
+-	.llong	68b,100b
+-	.llong	69b,100b
+-	.llong	70b,100b
+-	.llong	71b,100b
+-	.llong	72b,100b
+-	.llong	73b,100b
+-	.llong	74b,100b
+-	.llong	75b,100b
+-	.llong	76b,100b
+-	.llong	77b,100b
+-	.llong	78b,100b
+-	.llong	79b,100b
+-	.llong	80b,100b
+-	.llong	81b,100b
+-	.llong	82b,100b
+-	.llong	83b,100b
+-	.llong	84b,100b
+-	.llong	85b,100b
+-	.llong	86b,100b
+-	.llong	87b,100b
+-	.llong	88b,100b
+-	.llong	89b,100b
+-	.llong	90b,100b
+-	.llong	91b,100b
+diff --git a/arch/ppc64/lib/e2a.c b/arch/ppc64/lib/e2a.c
+deleted file mode 100644
+--- a/arch/ppc64/lib/e2a.c
++++ /dev/null
+@@ -1,108 +0,0 @@
+-/*
+- *  arch/ppc64/lib/e2a.c
+- *
+- *  EBCDIC to ASCII conversion
+- *
+- * This function moved here from arch/ppc64/kernel/viopath.c
+- *
+- * (C) Copyright 2000-2004 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) anyu 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>
+-
+-unsigned char e2a(unsigned char x)
+-{
+-	switch (x) {
+-	case 0xF0:
+-		return '0';
+-	case 0xF1:
+-		return '1';
+-	case 0xF2:
+-		return '2';
+-	case 0xF3:
+-		return '3';
+-	case 0xF4:
+-		return '4';
+-	case 0xF5:
+-		return '5';
+-	case 0xF6:
+-		return '6';
+-	case 0xF7:
+-		return '7';
+-	case 0xF8:
+-		return '8';
+-	case 0xF9:
+-		return '9';
+-	case 0xC1:
+-		return 'A';
+-	case 0xC2:
+-		return 'B';
+-	case 0xC3:
+-		return 'C';
+-	case 0xC4:
+-		return 'D';
+-	case 0xC5:
+-		return 'E';
+-	case 0xC6:
+-		return 'F';
+-	case 0xC7:
+-		return 'G';
+-	case 0xC8:
+-		return 'H';
+-	case 0xC9:
+-		return 'I';
+-	case 0xD1:
+-		return 'J';
+-	case 0xD2:
+-		return 'K';
+-	case 0xD3:
+-		return 'L';
+-	case 0xD4:
+-		return 'M';
+-	case 0xD5:
+-		return 'N';
+-	case 0xD6:
+-		return 'O';
+-	case 0xD7:
+-		return 'P';
+-	case 0xD8:
+-		return 'Q';
+-	case 0xD9:
+-		return 'R';
+-	case 0xE2:
+-		return 'S';
+-	case 0xE3:
+-		return 'T';
+-	case 0xE4:
+-		return 'U';
+-	case 0xE5:
+-		return 'V';
+-	case 0xE6:
+-		return 'W';
+-	case 0xE7:
+-		return 'X';
+-	case 0xE8:
+-		return 'Y';
+-	case 0xE9:
+-		return 'Z';
+-	}
+-	return ' ';
+-}
+-EXPORT_SYMBOL(e2a);
+-
+-
+diff --git a/arch/ppc64/lib/locks.c b/arch/ppc64/lib/locks.c
+deleted file mode 100644
+--- a/arch/ppc64/lib/locks.c
++++ /dev/null
+@@ -1,95 +0,0 @@
+-/*
+- * Spin and read/write lock operations.
+- *
+- * Copyright (C) 2001-2004 Paul Mackerras <paulus at au.ibm.com>, IBM
+- * Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, IBM
+- * Copyright (C) 2002 Dave Engebretsen <engebret at us.ibm.com>, IBM
+- *   Rework to support virtual processors
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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/spinlock.h>
+-#include <linux/module.h>
+-#include <linux/stringify.h>
+-#include <asm/hvcall.h>
+-#include <asm/iSeries/HvCall.h>
+-
+-/* waiting for a spinlock... */
+-#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
+-
+-void __spin_yield(raw_spinlock_t *lock)
+-{
+-	unsigned int lock_value, holder_cpu, yield_count;
+-	struct paca_struct *holder_paca;
+-
+-	lock_value = lock->slock;
+-	if (lock_value == 0)
+-		return;
+-	holder_cpu = lock_value & 0xffff;
+-	BUG_ON(holder_cpu >= NR_CPUS);
+-	holder_paca = &paca[holder_cpu];
+-	yield_count = holder_paca->lppaca.yield_count;
+-	if ((yield_count & 1) == 0)
+-		return;		/* virtual cpu is currently running */
+-	rmb();
+-	if (lock->slock != lock_value)
+-		return;		/* something has changed */
+-#ifdef CONFIG_PPC_ISERIES
+-	HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
+-		((u64)holder_cpu << 32) | yield_count);
+-#else
+-	plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
+-			   yield_count);
+-#endif
+-}
+-
+-/*
+- * Waiting for a read lock or a write lock on a rwlock...
+- * This turns out to be the same for read and write locks, since
+- * we only know the holder if it is write-locked.
+- */
+-void __rw_yield(raw_rwlock_t *rw)
+-{
+-	int lock_value;
+-	unsigned int holder_cpu, yield_count;
+-	struct paca_struct *holder_paca;
+-
+-	lock_value = rw->lock;
+-	if (lock_value >= 0)
+-		return;		/* no write lock at present */
+-	holder_cpu = lock_value & 0xffff;
+-	BUG_ON(holder_cpu >= NR_CPUS);
+-	holder_paca = &paca[holder_cpu];
+-	yield_count = holder_paca->lppaca.yield_count;
+-	if ((yield_count & 1) == 0)
+-		return;		/* virtual cpu is currently running */
+-	rmb();
+-	if (rw->lock != lock_value)
+-		return;		/* something has changed */
+-#ifdef CONFIG_PPC_ISERIES
+-	HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
+-		((u64)holder_cpu << 32) | yield_count);
+-#else
+-	plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
+-			   yield_count);
+-#endif
+-}
+-#endif
+-
+-void __raw_spin_unlock_wait(raw_spinlock_t *lock)
+-{
+-	while (lock->slock) {
+-		HMT_low();
+-		if (SHARED_PROCESSOR)
+-			__spin_yield(lock);
+-	}
+-	HMT_medium();
+-}
+-
+-EXPORT_SYMBOL(__raw_spin_unlock_wait);
+diff --git a/arch/ppc64/lib/memcpy.S b/arch/ppc64/lib/memcpy.S
+deleted file mode 100644
+--- a/arch/ppc64/lib/memcpy.S
++++ /dev/null
+@@ -1,172 +0,0 @@
+-/*
+- * arch/ppc64/lib/memcpy.S
+- *
+- * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-#include <asm/processor.h>
+-#include <asm/ppc_asm.h>
+-
+-	.align	7
+-_GLOBAL(memcpy)
+-	mtcrf	0x01,r5
+-	cmpldi	cr1,r5,16
+-	neg	r6,r3		# LS 3 bits = # bytes to 8-byte dest bdry
+-	andi.	r6,r6,7
+-	dcbt	0,r4
+-	blt	cr1,.Lshort_copy
+-	bne	.Ldst_unaligned
+-.Ldst_aligned:
+-	andi.	r0,r4,7
+-	addi	r3,r3,-16
+-	bne	.Lsrc_unaligned
+-	srdi	r7,r5,4
+-	ld	r9,0(r4)
+-	addi	r4,r4,-8
+-	mtctr	r7
+-	andi.	r5,r5,7
+-	bf	cr7*4+0,2f
+-	addi	r3,r3,8
+-	addi	r4,r4,8
+-	mr	r8,r9
+-	blt	cr1,3f
+-1:	ld	r9,8(r4)
+-	std	r8,8(r3)
+-2:	ldu	r8,16(r4)
+-	stdu	r9,16(r3)
+-	bdnz	1b
+-3:	std	r8,8(r3)
+-	beqlr
+-	addi	r3,r3,16
+-	ld	r9,8(r4)
+-.Ldo_tail:
+-	bf	cr7*4+1,1f
+-	rotldi	r9,r9,32
+-	stw	r9,0(r3)
+-	addi	r3,r3,4
+-1:	bf	cr7*4+2,2f
+-	rotldi	r9,r9,16
+-	sth	r9,0(r3)
+-	addi	r3,r3,2
+-2:	bf	cr7*4+3,3f
+-	rotldi	r9,r9,8
+-	stb	r9,0(r3)
+-3:	blr
+-
+-.Lsrc_unaligned:
+-	srdi	r6,r5,3
+-	addi	r5,r5,-16
+-	subf	r4,r0,r4
+-	srdi	r7,r5,4
+-	sldi	r10,r0,3
+-	cmpdi	cr6,r6,3
+-	andi.	r5,r5,7
+-	mtctr	r7
+-	subfic	r11,r10,64
+-	add	r5,r5,r0
+-
+-	bt	cr7*4+0,0f
+-
+-	ld	r9,0(r4)	# 3+2n loads, 2+2n stores
+-	ld	r0,8(r4)
+-	sld	r6,r9,r10
+-	ldu	r9,16(r4)
+-	srd	r7,r0,r11
+-	sld	r8,r0,r10
+-	or	r7,r7,r6
+-	blt	cr6,4f
+-	ld	r0,8(r4)
+-	# s1<< in r8, d0=(s0<<|s1>>) in r7, s3 in r0, s2 in r9, nix in r6 & r12
+-	b	2f
+-
+-0:	ld	r0,0(r4)	# 4+2n loads, 3+2n stores
+-	ldu	r9,8(r4)
+-	sld	r8,r0,r10
+-	addi	r3,r3,-8
+-	blt	cr6,5f
+-	ld	r0,8(r4)
+-	srd	r12,r9,r11
+-	sld	r6,r9,r10
+-	ldu	r9,16(r4)
+-	or	r12,r8,r12
+-	srd	r7,r0,r11
+-	sld	r8,r0,r10
+-	addi	r3,r3,16
+-	beq	cr6,3f
+-
+-	# d0=(s0<<|s1>>) in r12, s1<< in r6, s2>> in r7, s2<< in r8, s3 in r9
+-1:	or	r7,r7,r6
+-	ld	r0,8(r4)
+-	std	r12,8(r3)
+-2:	srd	r12,r9,r11
+-	sld	r6,r9,r10
+-	ldu	r9,16(r4)
+-	or	r12,r8,r12
+-	stdu	r7,16(r3)
+-	srd	r7,r0,r11
+-	sld	r8,r0,r10
+-	bdnz	1b
+-
+-3:	std	r12,8(r3)
+-	or	r7,r7,r6
+-4:	std	r7,16(r3)
+-5:	srd	r12,r9,r11
+-	or	r12,r8,r12
+-	std	r12,24(r3)
+-	beqlr
+-	cmpwi	cr1,r5,8
+-	addi	r3,r3,32
+-	sld	r9,r9,r10
+-	ble	cr1,.Ldo_tail
+-	ld	r0,8(r4)
+-	srd	r7,r0,r11
+-	or	r9,r7,r9
+-	b	.Ldo_tail
+-
+-.Ldst_unaligned:
+-	mtcrf	0x01,r6		# put #bytes to 8B bdry into cr7
+-	subf	r5,r6,r5
+-	li	r7,0
+-	cmpldi	r1,r5,16
+-	bf	cr7*4+3,1f
+-	lbz	r0,0(r4)
+-	stb	r0,0(r3)
+-	addi	r7,r7,1
+-1:	bf	cr7*4+2,2f
+-	lhzx	r0,r7,r4
+-	sthx	r0,r7,r3
+-	addi	r7,r7,2
+-2:	bf	cr7*4+1,3f
+-	lwzx	r0,r7,r4
+-	stwx	r0,r7,r3
+-3:	mtcrf	0x01,r5
+-	add	r4,r6,r4
+-	add	r3,r6,r3
+-	b	.Ldst_aligned
+-
+-.Lshort_copy:
+-	bf	cr7*4+0,1f
+-	lwz	r0,0(r4)
+-	lwz	r9,4(r4)
+-	addi	r4,r4,8
+-	stw	r0,0(r3)
+-	stw	r9,4(r3)
+-	addi	r3,r3,8
+-1:	bf	cr7*4+1,2f
+-	lwz	r0,0(r4)
+-	addi	r4,r4,4
+-	stw	r0,0(r3)
+-	addi	r3,r3,4
+-2:	bf	cr7*4+2,3f
+-	lhz	r0,0(r4)
+-	addi	r4,r4,2
+-	sth	r0,0(r3)
+-	addi	r3,r3,2
+-3:	bf	cr7*4+3,4f
+-	lbz	r0,0(r4)
+-	stb	r0,0(r3)
+-4:	blr
+diff --git a/arch/ppc64/lib/sstep.c b/arch/ppc64/lib/sstep.c
+deleted file mode 100644
+--- a/arch/ppc64/lib/sstep.c
++++ /dev/null
+@@ -1,141 +0,0 @@
+-/*
+- * Single-step support.
+- *
+- * Copyright (C) 2004 Paul Mackerras <paulus at au.ibm.com>, 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/kernel.h>
+-#include <linux/ptrace.h>
+-#include <asm/sstep.h>
+-#include <asm/processor.h>
+-
+-extern char system_call_common[];
+-
+-/* Bits in SRR1 that are copied from MSR */
+-#define MSR_MASK	0xffffffff87c0ffff
+-
+-/*
+- * Determine whether a conditional branch instruction would branch.
+- */
+-static int branch_taken(unsigned int instr, struct pt_regs *regs)
+-{
+-	unsigned int bo = (instr >> 21) & 0x1f;
+-	unsigned int bi;
+-
+-	if ((bo & 4) == 0) {
+-		/* decrement counter */
+-		--regs->ctr;
+-		if (((bo >> 1) & 1) ^ (regs->ctr == 0))
+-			return 0;
+-	}
+-	if ((bo & 0x10) == 0) {
+-		/* check bit from CR */
+-		bi = (instr >> 16) & 0x1f;
+-		if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1))
+-			return 0;
+-	}
+-	return 1;
+-}
+-
+-/*
+- * Emulate instructions that cause a transfer of control.
+- * Returns 1 if the step was emulated, 0 if not,
+- * or -1 if the instruction is one that should not be stepped,
+- * such as an rfid, or a mtmsrd that would clear MSR_RI.
+- */
+-int emulate_step(struct pt_regs *regs, unsigned int instr)
+-{
+-	unsigned int opcode, rd;
+-	unsigned long int imm;
+-
+-	opcode = instr >> 26;
+-	switch (opcode) {
+-	case 16:	/* bc */
+-		imm = (signed short)(instr & 0xfffc);
+-		if ((instr & 2) == 0)
+-			imm += regs->nip;
+-		regs->nip += 4;
+-		if ((regs->msr & MSR_SF) == 0)
+-			regs->nip &= 0xffffffffUL;
+-		if (instr & 1)
+-			regs->link = regs->nip;
+-		if (branch_taken(instr, regs))
+-			regs->nip = imm;
+-		return 1;
+-	case 17:	/* sc */
+-		/*
+-		 * N.B. this uses knowledge about how the syscall
+-		 * entry code works.  If that is changed, this will
+-		 * need to be changed also.
+-		 */
+-		regs->gpr[9] = regs->gpr[13];
+-		regs->gpr[11] = regs->nip + 4;
+-		regs->gpr[12] = regs->msr & MSR_MASK;
+-		regs->gpr[13] = (unsigned long) get_paca();
+-		regs->nip = (unsigned long) &system_call_common;
+-		regs->msr = MSR_KERNEL;
+-		return 1;
+-	case 18:	/* b */
+-		imm = instr & 0x03fffffc;
+-		if (imm & 0x02000000)
+-			imm -= 0x04000000;
+-		if ((instr & 2) == 0)
+-			imm += regs->nip;
+-		if (instr & 1) {
+-			regs->link = regs->nip + 4;
+-			if ((regs->msr & MSR_SF) == 0)
+-				regs->link &= 0xffffffffUL;
+-		}
+-		if ((regs->msr & MSR_SF) == 0)
+-			imm &= 0xffffffffUL;
+-		regs->nip = imm;
+-		return 1;
+-	case 19:
+-		switch (instr & 0x7fe) {
+-		case 0x20:	/* bclr */
+-		case 0x420:	/* bcctr */
+-			imm = (instr & 0x400)? regs->ctr: regs->link;
+-			regs->nip += 4;
+-			if ((regs->msr & MSR_SF) == 0) {
+-				regs->nip &= 0xffffffffUL;
+-				imm &= 0xffffffffUL;
+-			}
+-			if (instr & 1)
+-				regs->link = regs->nip;
+-			if (branch_taken(instr, regs))
+-				regs->nip = imm;
+-			return 1;
+-		case 0x24:	/* rfid, scary */
+-			return -1;
+-		}
+-	case 31:
+-		rd = (instr >> 21) & 0x1f;
+-		switch (instr & 0x7fe) {
+-		case 0xa6:	/* mfmsr */
+-			regs->gpr[rd] = regs->msr & MSR_MASK;
+-			regs->nip += 4;
+-			if ((regs->msr & MSR_SF) == 0)
+-				regs->nip &= 0xffffffffUL;
+-			return 1;
+-		case 0x164:	/* mtmsrd */
+-			/* only MSR_EE and MSR_RI get changed if bit 15 set */
+-			/* mtmsrd doesn't change MSR_HV and MSR_ME */
+-			imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL;
+-			imm = (regs->msr & MSR_MASK & ~imm)
+-				| (regs->gpr[rd] & imm);
+-			if ((imm & MSR_RI) == 0)
+-				/* can't step mtmsrd that would clear MSR_RI */
+-				return -1;
+-			regs->msr = imm;
+-			regs->nip += 4;
+-			if ((imm & MSR_SF) == 0)
+-				regs->nip &= 0xffffffffUL;
+-			return 1;
+-		}
+-	}
+-	return 0;
+-}
+diff --git a/arch/ppc64/lib/strcase.c b/arch/ppc64/lib/strcase.c
+deleted file mode 100644
+--- a/arch/ppc64/lib/strcase.c
++++ /dev/null
+@@ -1,31 +0,0 @@
+-/*
+- * c 2001 PPC 64 Team, IBM Corp
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the GNU General Public License
+- *      as published by the Free Software Foundation; either version
+- *      2 of the License, or (at your option) any later version.
+- */
+-#include <linux/ctype.h>
+-
+-int strcasecmp(const char *s1, const char *s2)
+-{
+-	int c1, c2;
+-
+-	do {
+-		c1 = tolower(*s1++);
+-		c2 = tolower(*s2++);
+-	} while (c1 == c2 && c1 != 0);
+-	return c1 - c2;
+-}
+-
+-int strncasecmp(const char *s1, const char *s2, int n)
+-{
+-	int c1, c2;
+-
+-	do {
+-		c1 = tolower(*s1++);
+-		c2 = tolower(*s2++);
+-	} while ((--n > 0) && c1 == c2 && c1 != 0);
+-	return c1 - c2;
+-}
+diff --git a/arch/ppc64/lib/string.S b/arch/ppc64/lib/string.S
+--- a/arch/ppc64/lib/string.S
++++ b/arch/ppc64/lib/string.S
+@@ -65,112 +65,6 @@ _GLOBAL(strlen)
+ 	subf	r3,r3,r4
+ 	blr
+ 
+-_GLOBAL(memset)
+-	neg	r0,r3
+-	rlwimi	r4,r4,8,16,23
+-	andi.	r0,r0,7			/* # bytes to be 8-byte aligned */
+-	rlwimi	r4,r4,16,0,15
+-	cmplw	cr1,r5,r0		/* do we get that far? */
+-	rldimi	r4,r4,32,0
+-	mtcrf	1,r0
+-	mr	r6,r3
+-	blt	cr1,8f
+-	beq+	3f			/* if already 8-byte aligned */
+-	subf	r5,r0,r5
+-	bf	31,1f
+-	stb	r4,0(r6)
+-	addi	r6,r6,1
+-1:	bf	30,2f
+-	sth	r4,0(r6)
+-	addi	r6,r6,2
+-2:	bf	29,3f
+-	stw	r4,0(r6)
+-	addi	r6,r6,4
+-3:	srdi.	r0,r5,6
+-	clrldi	r5,r5,58
+-	mtctr	r0
+-	beq	5f
+-4:	std	r4,0(r6)
+-	std	r4,8(r6)
+-	std	r4,16(r6)
+-	std	r4,24(r6)
+-	std	r4,32(r6)
+-	std	r4,40(r6)
+-	std	r4,48(r6)
+-	std	r4,56(r6)
+-	addi	r6,r6,64
+-	bdnz	4b
+-5:	srwi.	r0,r5,3
+-	clrlwi	r5,r5,29
+-	mtcrf	1,r0
+-	beq	8f
+-	bf	29,6f
+-	std	r4,0(r6)
+-	std	r4,8(r6)
+-	std	r4,16(r6)
+-	std	r4,24(r6)
+-	addi	r6,r6,32
+-6:	bf	30,7f
+-	std	r4,0(r6)
+-	std	r4,8(r6)
+-	addi	r6,r6,16
+-7:	bf	31,8f
+-	std	r4,0(r6)
+-	addi	r6,r6,8
+-8:	cmpwi	r5,0
+-	mtcrf	1,r5
+-	beqlr+
+-	bf	29,9f
+-	stw	r4,0(r6)
+-	addi	r6,r6,4
+-9:	bf	30,10f
+-	sth	r4,0(r6)
+-	addi	r6,r6,2
+-10:	bflr	31
+-	stb	r4,0(r6)
+-	blr
+-
+-_GLOBAL(memmove)
+-	cmplw	0,r3,r4
+-	bgt	.backwards_memcpy
+-	b	.memcpy
+-
+-_GLOBAL(backwards_memcpy)
+-	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+-	add	r6,r3,r5
+-	add	r4,r4,r5
+-	beq	2f
+-	andi.	r0,r6,3
+-	mtctr	r7
+-	bne	5f
+-1:	lwz	r7,-4(r4)
+-	lwzu	r8,-8(r4)
+-	stw	r7,-4(r6)
+-	stwu	r8,-8(r6)
+-	bdnz	1b
+-	andi.	r5,r5,7
+-2:	cmplwi	0,r5,4
+-	blt	3f
+-	lwzu	r0,-4(r4)
+-	subi	r5,r5,4
+-	stwu	r0,-4(r6)
+-3:	cmpwi	0,r5,0
+-	beqlr
+-	mtctr	r5
+-4:	lbzu	r0,-1(r4)
+-	stbu	r0,-1(r6)
+-	bdnz	4b
+-	blr
+-5:	mtctr	r0
+-6:	lbzu	r7,-1(r4)
+-	stbu	r7,-1(r6)
+-	bdnz	6b
+-	subf	r5,r0,r5
+-	rlwinm.	r7,r5,32-3,3,31
+-	beq	2b
+-	mtctr	r7
+-	b	1b
+-	
+ _GLOBAL(memcmp)
+ 	cmpwi	0,r5,0
+ 	ble-	2f
+diff --git a/arch/ppc64/lib/usercopy.c b/arch/ppc64/lib/usercopy.c
+deleted file mode 100644
+--- a/arch/ppc64/lib/usercopy.c
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/*
+- * Functions which are too large to be inlined.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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/uaccess.h>
+-
+-unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
+-{
+-	if (likely(access_ok(VERIFY_READ, from, n)))
+-		n = __copy_from_user(to, from, n);
+-	else
+-		memset(to, 0, n);
+-	return n;
+-}
+-
+-unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
+-{
+-	if (likely(access_ok(VERIFY_WRITE, to, n)))
+-		n = __copy_to_user(to, from, n);
+-	return n;
+-}
+-
+-unsigned long copy_in_user(void __user *to, const void __user *from,
+-			   unsigned long n)
+-{
+-	might_sleep();
+-	if (likely(access_ok(VERIFY_READ, from, n) &&
+-	    access_ok(VERIFY_WRITE, to, n)))
+-		n =__copy_tofrom_user(to, from, n);
+-	return n;
+-}
+-
+-EXPORT_SYMBOL(copy_from_user);
+-EXPORT_SYMBOL(copy_to_user);
+-EXPORT_SYMBOL(copy_in_user);
+-
+diff --git a/arch/ppc64/mm/Makefile b/arch/ppc64/mm/Makefile
+deleted file mode 100644
+--- a/arch/ppc64/mm/Makefile
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#
+-# Makefile for the linux ppc-specific parts of the memory manager.
+-#
+-
+-EXTRA_CFLAGS += -mno-minimal-toc
+-
+-obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \
+-	slb_low.o slb.o stab.o mmap.o
+-obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
+-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+-obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o
+diff --git a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/fault.c
++++ /dev/null
+@@ -1,333 +0,0 @@
+-/*
+- *  arch/ppc/mm/fault.c
+- *
+- *  PowerPC version 
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- *  Derived from "arch/i386/mm/fault.c"
+- *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+- *
+- *  Modified by Cort Dougan and Paul Mackerras.
+- *
+- *  Modified for PPC64 by Dave Engebretsen (engebret at 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 <linux/config.h>
+-#include <linux/signal.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/errno.h>
+-#include <linux/string.h>
+-#include <linux/types.h>
+-#include <linux/mman.h>
+-#include <linux/mm.h>
+-#include <linux/interrupt.h>
+-#include <linux/smp_lock.h>
+-#include <linux/module.h>
+-#include <linux/kprobes.h>
+-
+-#include <asm/page.h>
+-#include <asm/pgtable.h>
+-#include <asm/mmu.h>
+-#include <asm/mmu_context.h>
+-#include <asm/system.h>
+-#include <asm/uaccess.h>
+-#include <asm/kdebug.h>
+-#include <asm/siginfo.h>
+-
+-/*
+- * Check whether the instruction at regs->nip is a store using
+- * an update addressing form which will update r1.
+- */
+-static int store_updates_sp(struct pt_regs *regs)
+-{
+-	unsigned int inst;
+-
+-	if (get_user(inst, (unsigned int __user *)regs->nip))
+-		return 0;
+-	/* check for 1 in the rA field */
+-	if (((inst >> 16) & 0x1f) != 1)
+-		return 0;
+-	/* check major opcode */
+-	switch (inst >> 26) {
+-	case 37:	/* stwu */
+-	case 39:	/* stbu */
+-	case 45:	/* sthu */
+-	case 53:	/* stfsu */
+-	case 55:	/* stfdu */
+-		return 1;
+-	case 62:	/* std or stdu */
+-		return (inst & 3) == 1;
+-	case 31:
+-		/* check minor opcode */
+-		switch ((inst >> 1) & 0x3ff) {
+-		case 181:	/* stdux */
+-		case 183:	/* stwux */
+-		case 247:	/* stbux */
+-		case 439:	/* sthux */
+-		case 695:	/* stfsux */
+-		case 759:	/* stfdux */
+-			return 1;
+-		}
+-	}
+-	return 0;
+-}
+-
+-static void do_dabr(struct pt_regs *regs, unsigned long error_code)
+-{
+-	siginfo_t info;
+-
+-	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
+-			11, SIGSEGV) == NOTIFY_STOP)
+-		return;
+-
+-	if (debugger_dabr_match(regs))
+-		return;
+-
+-	/* Clear the DABR */
+-	set_dabr(0);
+-
+-	/* Deliver the signal to userspace */
+-	info.si_signo = SIGTRAP;
+-	info.si_errno = 0;
+-	info.si_code = TRAP_HWBKPT;
+-	info.si_addr = (void __user *)regs->nip;
+-	force_sig_info(SIGTRAP, &info, current);
+-}
+-
+-/*
+- * The error_code parameter is
+- *  - DSISR for a non-SLB data access fault,
+- *  - SRR1 & 0x08000000 for a non-SLB instruction access fault
+- *  - 0 any SLB fault.
+- * The return value is 0 if the fault was handled, or the signal
+- * number if this is a kernel fault that can't be handled here.
+- */
+-int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
+-			    unsigned long error_code)
+-{
+-	struct vm_area_struct * vma;
+-	struct mm_struct *mm = current->mm;
+-	siginfo_t info;
+-	unsigned long code = SEGV_MAPERR;
+-	unsigned long is_write = error_code & DSISR_ISSTORE;
+-	unsigned long trap = TRAP(regs);
+- 	unsigned long is_exec = trap == 0x400;
+-
+-	BUG_ON((trap == 0x380) || (trap == 0x480));
+-
+-	if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code,
+-				11, SIGSEGV) == NOTIFY_STOP)
+-		return 0;
+-
+-	if (trap == 0x300) {
+-		if (debugger_fault_handler(regs))
+-			return 0;
+-	}
+-
+-	/* On a kernel SLB miss we can only check for a valid exception entry */
+-	if (!user_mode(regs) && (address >= TASK_SIZE))
+-		return SIGSEGV;
+-
+-  	if (error_code & DSISR_DABRMATCH) {
+-		do_dabr(regs, error_code);
+-		return 0;
+-	}
+-
+-	if (in_atomic() || mm == NULL) {
+-		if (!user_mode(regs))
+-			return SIGSEGV;
+-		/* in_atomic() in user mode is really bad,
+-		   as is current->mm == NULL. */
+-		printk(KERN_EMERG "Page fault in user mode with"
+-		       "in_atomic() = %d mm = %p\n", in_atomic(), mm);
+-		printk(KERN_EMERG "NIP = %lx  MSR = %lx\n",
+-		       regs->nip, regs->msr);
+-		die("Weird page fault", regs, SIGSEGV);
+-	}
+-
+-	/* When running in the kernel we expect faults to occur only to
+-	 * addresses in user space.  All other faults represent errors in the
+-	 * kernel and should generate an OOPS.  Unfortunatly, in the case of an
+-	 * erroneous fault occuring in a code path which already holds mmap_sem
+-	 * we will deadlock attempting to validate the fault against the
+-	 * address space.  Luckily the kernel only validly references user
+-	 * space from well defined areas of code, which are listed in the
+-	 * exceptions table.
+-	 *
+-	 * As the vast majority of faults will be valid we will only perform
+-	 * the source reference check when there is a possibilty of a deadlock.
+-	 * Attempt to lock the address space, if we cannot we then validate the
+-	 * source.  If this is invalid we can skip the address space check,
+-	 * thus avoiding the deadlock.
+-	 */
+-	if (!down_read_trylock(&mm->mmap_sem)) {
+-		if (!user_mode(regs) && !search_exception_tables(regs->nip))
+-			goto bad_area_nosemaphore;
+-
+-		down_read(&mm->mmap_sem);
+-	}
+-
+-	vma = find_vma(mm, address);
+-	if (!vma)
+-		goto bad_area;
+-
+-	if (vma->vm_start <= address) {
+-		goto good_area;
+-	}
+-	if (!(vma->vm_flags & VM_GROWSDOWN))
+-		goto bad_area;
+-
+-	/*
+-	 * N.B. The POWER/Open ABI allows programs to access up to
+-	 * 288 bytes below the stack pointer.
+-	 * The kernel signal delivery code writes up to about 1.5kB
+-	 * below the stack pointer (r1) before decrementing it.
+-	 * The exec code can write slightly over 640kB to the stack
+-	 * before setting the user r1.  Thus we allow the stack to
+-	 * expand to 1MB without further checks.
+-	 */
+-	if (address + 0x100000 < vma->vm_end) {
+-		/* get user regs even if this fault is in kernel mode */
+-		struct pt_regs *uregs = current->thread.regs;
+-		if (uregs == NULL)
+-			goto bad_area;
+-
+-		/*
+-		 * A user-mode access to an address a long way below
+-		 * the stack pointer is only valid if the instruction
+-		 * is one which would update the stack pointer to the
+-		 * address accessed if the instruction completed,
+-		 * i.e. either stwu rs,n(r1) or stwux rs,r1,rb
+-		 * (or the byte, halfword, float or double forms).
+-		 *
+-		 * If we don't check this then any write to the area
+-		 * between the last mapped region and the stack will
+-		 * expand the stack rather than segfaulting.
+-		 */
+-		if (address + 2048 < uregs->gpr[1]
+-		    && (!user_mode(regs) || !store_updates_sp(regs)))
+-			goto bad_area;
+-	}
+-
+-	if (expand_stack(vma, address))
+-		goto bad_area;
+-
+-good_area:
+-	code = SEGV_ACCERR;
+-
+-	if (is_exec) {
+-		/* protection fault */
+-		if (error_code & DSISR_PROTFAULT)
+-			goto bad_area;
+-		if (!(vma->vm_flags & VM_EXEC))
+-			goto bad_area;
+-	/* a write */
+-	} else if (is_write) {
+-		if (!(vma->vm_flags & VM_WRITE))
+-			goto bad_area;
+-	/* a read */
+-	} else {
+-		if (!(vma->vm_flags & VM_READ))
+-			goto bad_area;
+-	}
+-
+- survive:
+-	/*
+-	 * If for any reason at all we couldn't handle the fault,
+-	 * make sure we exit gracefully rather than endlessly redo
+-	 * the fault.
+-	 */
+-	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:
+-		goto do_sigbus;
+-	case VM_FAULT_OOM:
+-		goto out_of_memory;
+-	default:
+-		BUG();
+-	}
+-
+-	up_read(&mm->mmap_sem);
+-	return 0;
+-
+-bad_area:
+-	up_read(&mm->mmap_sem);
+-
+-bad_area_nosemaphore:
+-	/* User mode accesses cause a SIGSEGV */
+-	if (user_mode(regs)) {
+-		info.si_signo = SIGSEGV;
+-		info.si_errno = 0;
+-		info.si_code = code;
+-		info.si_addr = (void __user *) address;
+-		force_sig_info(SIGSEGV, &info, current);
+-		return 0;
+-	}
+-
+-	if (trap == 0x400 && (error_code & DSISR_PROTFAULT)
+-	    && printk_ratelimit())
+-		printk(KERN_CRIT "kernel tried to execute NX-protected"
+-		       " page (%lx) - exploit attempt? (uid: %d)\n",
+-		       address, current->uid);
+-
+-	return SIGSEGV;
+-
+-/*
+- * 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:
+-	up_read(&mm->mmap_sem);
+-	if (current->pid == 1) {
+-		yield();
+-		down_read(&mm->mmap_sem);
+-		goto survive;
+-	}
+-	printk("VM: killing process %s\n", current->comm);
+-	if (user_mode(regs))
+-		do_exit(SIGKILL);
+-	return SIGKILL;
+-
+-do_sigbus:
+-	up_read(&mm->mmap_sem);
+-	if (user_mode(regs)) {
+-		info.si_signo = SIGBUS;
+-		info.si_errno = 0;
+-		info.si_code = BUS_ADRERR;
+-		info.si_addr = (void __user *)address;
+-		force_sig_info(SIGBUS, &info, current);
+-		return 0;
+-	}
+-	return SIGBUS;
+-}
+-
+-/*
+- * bad_page_fault is called when we have a bad access from the kernel.
+- * It is called from do_page_fault above and from some of the procedures
+- * in traps.c.
+- */
+-void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
+-{
+-	const struct exception_table_entry *entry;
+-
+-	/* Are we prepared to handle this fault?  */
+-	if ((entry = search_exception_tables(regs->nip)) != NULL) {
+-		regs->nip = entry->fixup;
+-		return;
+-	}
+-
+-	/* kernel has accessed a bad area */
+-	die("Kernel access of bad area", regs, sig);
+-}
+diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S
+deleted file mode 100644
+--- a/arch/ppc64/mm/hash_low.S
++++ /dev/null
+@@ -1,288 +0,0 @@
+-/*
+- * ppc64 MMU hashtable management routines
+- *
+- * (c) Copyright IBM Corp. 2003
+- *
+- * Maintained by: Benjamin Herrenschmidt
+- *                <benh at kernel.crashing.org>
+- *
+- * This file is covered by the GNU Public Licence v2 as
+- * described in the kernel's COPYING file.
+- */
+-
+-#include <asm/processor.h>
+-#include <asm/pgtable.h>
+-#include <asm/mmu.h>
+-#include <asm/page.h>
+-#include <asm/types.h>
+-#include <asm/ppc_asm.h>
+-#include <asm/asm-offsets.h>
+-#include <asm/cputable.h>
+-
+-	.text
+-
+-/*
+- * Stackframe:
+- *		
+- *         +-> Back chain			(SP + 256)
+- *         |   General register save area	(SP + 112)
+- *         |   Parameter save area		(SP + 48)
+- *         |   TOC save area			(SP + 40)
+- *         |   link editor doubleword		(SP + 32)
+- *         |   compiler doubleword		(SP + 24)
+- *         |   LR save area			(SP + 16)
+- *         |   CR save area			(SP + 8)
+- * SP ---> +-- Back chain			(SP + 0)
+- */
+-#define STACKFRAMESIZE	256
+-
+-/* Save parameters offsets */
+-#define STK_PARM(i)	(STACKFRAMESIZE + 48 + ((i)-3)*8)
+-
+-/* Save non-volatile offsets */
+-#define STK_REG(i)	(112 + ((i)-14)*8)
+-
+-/*
+- * _hash_page(unsigned long ea, unsigned long access, unsigned long vsid,
+- *		pte_t *ptep, unsigned long trap, int local)
+- *
+- * Adds a page to the hash table. This is the non-LPAR version for now
+- */
+-
+-_GLOBAL(__hash_page)
+-	mflr	r0
+-	std	r0,16(r1)
+-	stdu	r1,-STACKFRAMESIZE(r1)
+-	/* Save all params that we need after a function call */
+-	std	r6,STK_PARM(r6)(r1)
+-	std	r8,STK_PARM(r8)(r1)
+-	
+-	/* Add _PAGE_PRESENT to access */
+-	ori	r4,r4,_PAGE_PRESENT
+-
+-	/* Save non-volatile registers.
+-	 * r31 will hold "old PTE"
+-	 * r30 is "new PTE"
+-	 * r29 is "va"
+-	 * r28 is a hash value
+-	 * r27 is hashtab mask (maybe dynamic patched instead ?)
+-	 */
+-	std	r27,STK_REG(r27)(r1)
+-	std	r28,STK_REG(r28)(r1)
+-	std	r29,STK_REG(r29)(r1)
+-	std	r30,STK_REG(r30)(r1)
+-	std	r31,STK_REG(r31)(r1)
+-	
+-	/* Step 1:
+-	 *
+-	 * Check permissions, atomically mark the linux PTE busy
+-	 * and hashed.
+-	 */ 
+-1:
+-	ldarx	r31,0,r6
+-	/* Check access rights (access & ~(pte_val(*ptep))) */
+-	andc.	r0,r4,r31
+-	bne-	htab_wrong_access
+-	/* Check if PTE is busy */
+-	andi.	r0,r31,_PAGE_BUSY
+-	/* If so, just bail out and refault if needed. Someone else
+-	 * is changing this PTE anyway and might hash it.
+-	 */
+-	bne-	bail_ok
+-	/* Prepare new PTE value (turn access RW into DIRTY, then
+-	 * add BUSY,HASHPTE and ACCESSED)
+-	 */
+-	rlwinm	r30,r4,32-9+7,31-7,31-7	/* _PAGE_RW -> _PAGE_DIRTY */
+-	or	r30,r30,r31
+-	ori	r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
+-	/* Write the linux PTE atomically (setting busy) */
+-	stdcx.	r30,0,r6
+-	bne-	1b
+-	isync
+-
+-	/* Step 2:
+-	 *
+-	 * Insert/Update the HPTE in the hash table. At this point,
+-	 * r4 (access) is re-useable, we use it for the new HPTE flags
+-	 */
+-
+-	/* Calc va and put it in r29 */
+-	rldicr	r29,r5,28,63-28
+-	rldicl	r3,r3,0,36
+-	or	r29,r3,r29
+-
+-	/* Calculate hash value for primary slot and store it in r28 */
+-	rldicl	r5,r5,0,25		/* vsid & 0x0000007fffffffff */
+-	rldicl	r0,r3,64-12,48		/* (ea >> 12) & 0xffff */
+-	xor	r28,r5,r0
+-
+-	/* Convert linux PTE bits into HW equivalents */
+-	andi.	r3,r30,0x1fe		/* Get basic set of flags */
+-	xori	r3,r3,HW_NO_EXEC	/* _PAGE_EXEC -> NOEXEC */
+-	rlwinm	r0,r30,32-9+1,30,30	/* _PAGE_RW -> _PAGE_USER (r0) */
+-	rlwinm	r4,r30,32-7+1,30,30	/* _PAGE_DIRTY -> _PAGE_USER (r4) */
+-	and	r0,r0,r4		/* _PAGE_RW & _PAGE_DIRTY -> r0 bit 30 */
+-	andc	r0,r30,r0		/* r0 = pte & ~r0 */
+-	rlwimi	r3,r0,32-1,31,31	/* Insert result into PP lsb */
+-
+-	/* We eventually do the icache sync here (maybe inline that
+-	 * code rather than call a C function...) 
+-	 */
+-BEGIN_FTR_SECTION
+-	mr	r4,r30
+-	mr	r5,r7
+-	bl	.hash_page_do_lazy_icache
+-END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
+-
+-	/* At this point, r3 contains new PP bits, save them in
+-	 * place of "access" in the param area (sic)
+-	 */
+-	std	r3,STK_PARM(r4)(r1)
+-
+-	/* Get htab_hash_mask */
+-	ld	r4,htab_hash_mask at got(2)
+-	ld	r27,0(r4)	/* htab_hash_mask -> r27 */
+-
+-	/* Check if we may already be in the hashtable, in this case, we
+-	 * go to out-of-line code to try to modify the HPTE
+-	 */
+-	andi.	r0,r31,_PAGE_HASHPTE
+-	bne	htab_modify_pte
+-
+-htab_insert_pte:
+-	/* Clear hpte bits in new pte (we also clear BUSY btw) and
+-	 * add _PAGE_HASHPTE
+-	 */
+-	lis	r0,_PAGE_HPTEFLAGS at h
+-	ori	r0,r0,_PAGE_HPTEFLAGS at l
+-	andc	r30,r30,r0
+-	ori	r30,r30,_PAGE_HASHPTE
+-
+-	/* page number in r5 */
+-	rldicl	r5,r31,64-PTE_SHIFT,PTE_SHIFT
+-
+-	/* Calculate primary group hash */
+-	and	r0,r28,r27
+-	rldicr	r3,r0,3,63-3	/* r0 = (hash & mask) << 3 */
+-
+-	/* Call ppc_md.hpte_insert */
+-	ld	r7,STK_PARM(r4)(r1)	/* Retreive new pp bits */
+-	mr	r4,r29			/* Retreive va */
+-	li	r6,0			/* no vflags */
+-_GLOBAL(htab_call_hpte_insert1)
+-	bl	.			/* Will be patched by htab_finish_init() */
+-	cmpdi	0,r3,0
+-	bge	htab_pte_insert_ok	/* Insertion successful */
+-	cmpdi	0,r3,-2			/* Critical failure */
+-	beq-	htab_pte_insert_failure
+-
+-	/* Now try secondary slot */
+-	
+-	/* page number in r5 */
+-	rldicl	r5,r31,64-PTE_SHIFT,PTE_SHIFT
+-
+-	/* Calculate secondary group hash */
+-	andc	r0,r27,r28
+-	rldicr	r3,r0,3,63-3	/* r0 = (~hash & mask) << 3 */
+-	
+-	/* Call ppc_md.hpte_insert */
+-	ld	r7,STK_PARM(r4)(r1)	/* Retreive new pp bits */
+-	mr	r4,r29			/* Retreive va */
+-	li	r6,HPTE_V_SECONDARY at l	/* secondary slot */
+-_GLOBAL(htab_call_hpte_insert2)
+-	bl	.			/* Will be patched by htab_finish_init() */
+-	cmpdi	0,r3,0
+-	bge+	htab_pte_insert_ok	/* Insertion successful */
+-	cmpdi	0,r3,-2			/* Critical failure */
+-	beq-	htab_pte_insert_failure
+-
+-	/* Both are full, we need to evict something */
+-	mftb	r0
+-	/* Pick a random group based on TB */
+-	andi.	r0,r0,1
+-	mr	r5,r28
+-	bne	2f
+-	not	r5,r5
+-2:	and	r0,r5,r27
+-	rldicr	r3,r0,3,63-3	/* r0 = (hash & mask) << 3 */	
+-	/* Call ppc_md.hpte_remove */
+-_GLOBAL(htab_call_hpte_remove)
+-	bl	.			/* Will be patched by htab_finish_init() */
+-
+-	/* Try all again */
+-	b	htab_insert_pte	
+-
+-bail_ok:
+-	li	r3,0
+-	b	bail
+-
+-htab_pte_insert_ok:
+-	/* Insert slot number & secondary bit in PTE */
+-	rldimi	r30,r3,12,63-15
+-		
+-	/* Write out the PTE with a normal write
+-	 * (maybe add eieio may be good still ?)
+-	 */
+-htab_write_out_pte:
+-	ld	r6,STK_PARM(r6)(r1)
+-	std	r30,0(r6)
+-	li	r3, 0
+-bail:
+-	ld	r27,STK_REG(r27)(r1)
+-	ld	r28,STK_REG(r28)(r1)
+-	ld	r29,STK_REG(r29)(r1)
+-	ld      r30,STK_REG(r30)(r1)
+-	ld      r31,STK_REG(r31)(r1)
+-	addi    r1,r1,STACKFRAMESIZE
+-	ld      r0,16(r1)
+-	mtlr    r0
+-	blr
+-
+-htab_modify_pte:
+-	/* Keep PP bits in r4 and slot idx from the PTE around in r3 */
+-	mr	r4,r3
+-	rlwinm	r3,r31,32-12,29,31
+-
+-	/* Secondary group ? if yes, get a inverted hash value */
+-	mr	r5,r28
+-	andi.	r0,r31,_PAGE_SECONDARY
+-	beq	1f
+-	not	r5,r5
+-1:
+-	/* Calculate proper slot value for ppc_md.hpte_updatepp */
+-	and	r0,r5,r27
+-	rldicr	r0,r0,3,63-3	/* r0 = (hash & mask) << 3 */
+-	add	r3,r0,r3	/* add slot idx */
+-
+-	/* Call ppc_md.hpte_updatepp */
+-	mr	r5,r29			/* va */
+-	li	r6,0			/* large is 0 */
+-	ld	r7,STK_PARM(r8)(r1)	/* get "local" param */
+-_GLOBAL(htab_call_hpte_updatepp)
+-	bl	.			/* Will be patched by htab_finish_init() */
+-
+-	/* if we failed because typically the HPTE wasn't really here
+-	 * we try an insertion. 
+-	 */
+-	cmpdi	0,r3,-1
+-	beq-	htab_insert_pte
+-
+-	/* Clear the BUSY bit and Write out the PTE */
+-	li	r0,_PAGE_BUSY
+-	andc	r30,r30,r0
+-	b	htab_write_out_pte
+-
+-htab_wrong_access:
+-	/* Bail out clearing reservation */
+-	stdcx.	r31,0,r6
+-	li	r3,1
+-	b	bail
+-
+-htab_pte_insert_failure:
+-	/* Bail out restoring old PTE */
+-	ld	r6,STK_PARM(r6)(r1)
+-	std	r31,0(r6)
+-	li	r3,-1
+-	b	bail
+-
+-
+diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/hash_native.c
++++ /dev/null
+@@ -1,453 +0,0 @@
+-/*
+- * native hashtable management.
+- *
+- * SMP scalability work:
+- *    Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, 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/spinlock.h>
+-#include <linux/bitops.h>
+-#include <linux/threads.h>
+-#include <linux/smp.h>
+-
+-#include <asm/abs_addr.h>
+-#include <asm/machdep.h>
+-#include <asm/mmu.h>
+-#include <asm/mmu_context.h>
+-#include <asm/pgtable.h>
+-#include <asm/tlbflush.h>
+-#include <asm/tlb.h>
+-#include <asm/cputable.h>
+-
+-#define HPTE_LOCK_BIT 3
+-
+-static DEFINE_SPINLOCK(native_tlbie_lock);
+-
+-static inline void native_lock_hpte(hpte_t *hptep)
+-{
+-	unsigned long *word = &hptep->v;
+-
+-	while (1) {
+-		if (!test_and_set_bit(HPTE_LOCK_BIT, word))
+-			break;
+-		while(test_bit(HPTE_LOCK_BIT, word))
+-			cpu_relax();
+-	}
+-}
+-
+-static inline void native_unlock_hpte(hpte_t *hptep)
+-{
+-	unsigned long *word = &hptep->v;
+-
+-	asm volatile("lwsync":::"memory");
+-	clear_bit(HPTE_LOCK_BIT, word);
+-}
+-
+-long native_hpte_insert(unsigned long hpte_group, unsigned long va,
+-			unsigned long prpn, unsigned long vflags,
+-			unsigned long rflags)
+-{
+-	hpte_t *hptep = htab_address + hpte_group;
+-	unsigned long hpte_v, hpte_r;
+-	int i;
+-
+-	for (i = 0; i < HPTES_PER_GROUP; i++) {
+-		if (! (hptep->v & HPTE_V_VALID)) {
+-			/* retry with lock held */
+-			native_lock_hpte(hptep);
+-			if (! (hptep->v & HPTE_V_VALID))
+-				break;
+-			native_unlock_hpte(hptep);
+-		}
+-
+-		hptep++;
+-	}
+-
+-	if (i == HPTES_PER_GROUP)
+-		return -1;
+-
+-	hpte_v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
+-	if (vflags & HPTE_V_LARGE)
+-		va &= ~(1UL << HPTE_V_AVPN_SHIFT);
+-	hpte_r = (prpn << HPTE_R_RPN_SHIFT) | rflags;
+-
+-	hptep->r = hpte_r;
+-	/* Guarantee the second dword is visible before the valid bit */
+-	__asm__ __volatile__ ("eieio" : : : "memory");
+-	/*
+-	 * Now set the first dword including the valid bit
+-	 * NOTE: this also unlocks the hpte
+-	 */
+-	hptep->v = hpte_v;
+-
+-	__asm__ __volatile__ ("ptesync" : : : "memory");
+-
+-	return i | (!!(vflags & HPTE_V_SECONDARY) << 3);
+-}
+-
+-static long native_hpte_remove(unsigned long hpte_group)
+-{
+-	hpte_t *hptep;
+-	int i;
+-	int slot_offset;
+-	unsigned long hpte_v;
+-
+-	/* pick a random entry to start at */
+-	slot_offset = mftb() & 0x7;
+-
+-	for (i = 0; i < HPTES_PER_GROUP; i++) {
+-		hptep = htab_address + hpte_group + slot_offset;
+-		hpte_v = hptep->v;
+-
+-		if ((hpte_v & HPTE_V_VALID) && !(hpte_v & HPTE_V_BOLTED)) {
+-			/* retry with lock held */
+-			native_lock_hpte(hptep);
+-			hpte_v = hptep->v;
+-			if ((hpte_v & HPTE_V_VALID)
+-			    && !(hpte_v & HPTE_V_BOLTED))
+-				break;
+-			native_unlock_hpte(hptep);
+-		}
+-
+-		slot_offset++;
+-		slot_offset &= 0x7;
+-	}
+-
+-	if (i == HPTES_PER_GROUP)
+-		return -1;
+-
+-	/* Invalidate the hpte. NOTE: this also unlocks it */
+-	hptep->v = 0;
+-
+-	return i;
+-}
+-
+-static inline void set_pp_bit(unsigned long pp, hpte_t *addr)
+-{
+-	unsigned long old;
+-	unsigned long *p = &addr->r;
+-
+-	__asm__ __volatile__(
+-	"1:	ldarx	%0,0,%3\n\
+-		rldimi	%0,%2,0,61\n\
+-		stdcx.	%0,0,%3\n\
+-		bne	1b"
+-	: "=&r" (old), "=m" (*p)
+-	: "r" (pp), "r" (p), "m" (*p)
+-	: "cc");
+-}
+-
+-/*
+- * Only works on small pages. Yes its ugly to have to check each slot in
+- * the group but we only use this during bootup.
+- */
+-static long native_hpte_find(unsigned long vpn)
+-{
+-	hpte_t *hptep;
+-	unsigned long hash;
+-	unsigned long i, j;
+-	long slot;
+-	unsigned long hpte_v;
+-
+-	hash = hpt_hash(vpn, 0);
+-
+-	for (j = 0; j < 2; j++) {
+-		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+-		for (i = 0; i < HPTES_PER_GROUP; i++) {
+-			hptep = htab_address + slot;
+-			hpte_v = hptep->v;
+-
+-			if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
+-			    && (hpte_v & HPTE_V_VALID)
+-			    && ( !!(hpte_v & HPTE_V_SECONDARY) == j)) {
+-				/* HPTE matches */
+-				if (j)
+-					slot = -slot;
+-				return slot;
+-			}
+-			++slot;
+-		}
+-		hash = ~hash;
+-	}
+-
+-	return -1;
+-}
+-
+-static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
+-				 unsigned long va, int large, int local)
+-{
+-	hpte_t *hptep = htab_address + slot;
+-	unsigned long hpte_v;
+-	unsigned long avpn = va >> 23;
+-	int ret = 0;
+-
+-	if (large)
+-		avpn &= ~1;
+-
+-	native_lock_hpte(hptep);
+-
+-	hpte_v = hptep->v;
+-
+-	/* Even if we miss, we need to invalidate the TLB */
+-	if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
+-	    || !(hpte_v & HPTE_V_VALID)) {
+-		native_unlock_hpte(hptep);
+-		ret = -1;
+-	} else {
+-		set_pp_bit(newpp, hptep);
+-		native_unlock_hpte(hptep);
+-	}
+-
+-	/* Ensure it is out of the tlb too */
+-	if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
+-		tlbiel(va);
+-	} else {
+-		int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
+-
+-		if (lock_tlbie)
+-			spin_lock(&native_tlbie_lock);
+-		tlbie(va, large);
+-		if (lock_tlbie)
+-			spin_unlock(&native_tlbie_lock);
+-	}
+-
+-	return ret;
+-}
+-
+-/*
+- * Update the page protection bits. Intended to be used to create
+- * guard pages for kernel data structures on pages which are bolted
+- * in the HPT. Assumes pages being operated on will not be stolen.
+- * Does not work on large pages.
+- *
+- * No need to lock here because we should be the only user.
+- */
+-static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
+-{
+-	unsigned long vsid, va, vpn, flags = 0;
+-	long slot;
+-	hpte_t *hptep;
+-	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
+-
+-	vsid = get_kernel_vsid(ea);
+-	va = (vsid << 28) | (ea & 0x0fffffff);
+-	vpn = va >> PAGE_SHIFT;
+-
+-	slot = native_hpte_find(vpn);
+-	if (slot == -1)
+-		panic("could not find page to bolt\n");
+-	hptep = htab_address + slot;
+-
+-	set_pp_bit(newpp, hptep);
+-
+-	/* Ensure it is out of the tlb too */
+-	if (lock_tlbie)
+-		spin_lock_irqsave(&native_tlbie_lock, flags);
+-	tlbie(va, 0);
+-	if (lock_tlbie)
+-		spin_unlock_irqrestore(&native_tlbie_lock, flags);
+-}
+-
+-static void native_hpte_invalidate(unsigned long slot, unsigned long va,
+-				    int large, int local)
+-{
+-	hpte_t *hptep = htab_address + slot;
+-	unsigned long hpte_v;
+-	unsigned long avpn = va >> 23;
+-	unsigned long flags;
+-	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
+-
+-	if (large)
+-		avpn &= ~1;
+-
+-	local_irq_save(flags);
+-	native_lock_hpte(hptep);
+-
+-	hpte_v = hptep->v;
+-
+-	/* Even if we miss, we need to invalidate the TLB */
+-	if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
+-	    || !(hpte_v & HPTE_V_VALID)) {
+-		native_unlock_hpte(hptep);
+-	} else {
+-		/* Invalidate the hpte. NOTE: this also unlocks it */
+-		hptep->v = 0;
+-	}
+-
+-	/* Invalidate the tlb */
+-	if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
+-		tlbiel(va);
+-	} else {
+-		if (lock_tlbie)
+-			spin_lock(&native_tlbie_lock);
+-		tlbie(va, large);
+-		if (lock_tlbie)
+-			spin_unlock(&native_tlbie_lock);
+-	}
+-	local_irq_restore(flags);
+-}
+-
+-/*
+- * clear all mappings on kexec.  All cpus are in real mode (or they will
+- * be when they isi), and we are the only one left.  We rely on our kernel
+- * mapping being 0xC0's and the hardware ignoring those two real bits.
+- *
+- * TODO: add batching support when enabled.  remember, no dynamic memory here,
+- * athough there is the control page available...
+- */
+-static void native_hpte_clear(void)
+-{
+-	unsigned long slot, slots, flags;
+-	hpte_t *hptep = htab_address;
+-	unsigned long hpte_v;
+-	unsigned long pteg_count;
+-
+-	pteg_count = htab_hash_mask + 1;
+-
+-	local_irq_save(flags);
+-
+-	/* we take the tlbie lock and hold it.  Some hardware will
+-	 * deadlock if we try to tlbie from two processors at once.
+-	 */
+-	spin_lock(&native_tlbie_lock);
+-
+-	slots = pteg_count * HPTES_PER_GROUP;
+-
+-	for (slot = 0; slot < slots; slot++, hptep++) {
+-		/*
+-		 * we could lock the pte here, but we are the only cpu
+-		 * running,  right?  and for crash dump, we probably
+-		 * don't want to wait for a maybe bad cpu.
+-		 */
+-		hpte_v = hptep->v;
+-
+-		if (hpte_v & HPTE_V_VALID) {
+-			hptep->v = 0;
+-			tlbie(slot2va(hpte_v, slot), hpte_v & HPTE_V_LARGE);
+-		}
+-	}
+-
+-	spin_unlock(&native_tlbie_lock);
+-	local_irq_restore(flags);
+-}
+-
+-static void native_flush_hash_range(unsigned long context,
+-				    unsigned long number, int local)
+-{
+-	unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn;
+-	int i, j;
+-	hpte_t *hptep;
+-	unsigned long hpte_v;
+-	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
+-	unsigned long large = batch->large;
+-
+-	local_irq_save(flags);
+-
+-	j = 0;
+-	for (i = 0; i < number; i++) {
+-		if (batch->addr[i] < KERNELBASE)
+-			vsid = get_vsid(context, batch->addr[i]);
+-		else
+-			vsid = get_kernel_vsid(batch->addr[i]);
+-
+-		va = (vsid << 28) | (batch->addr[i] & 0x0fffffff);
+-		batch->vaddr[j] = va;
+-		if (large)
+-			vpn = va >> HPAGE_SHIFT;
+-		else
+-			vpn = va >> PAGE_SHIFT;
+-		hash = hpt_hash(vpn, large);
+-		secondary = (pte_val(batch->pte[i]) & _PAGE_SECONDARY) >> 15;
+-		if (secondary)
+-			hash = ~hash;
+-		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+-		slot += (pte_val(batch->pte[i]) & _PAGE_GROUP_IX) >> 12;
+-
+-		hptep = htab_address + slot;
+-
+-		avpn = va >> 23;
+-		if (large)
+-			avpn &= ~0x1UL;
+-
+-		native_lock_hpte(hptep);
+-
+-		hpte_v = hptep->v;
+-
+-		/* Even if we miss, we need to invalidate the TLB */
+-		if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
+-		    || !(hpte_v & HPTE_V_VALID)) {
+-			native_unlock_hpte(hptep);
+-		} else {
+-			/* Invalidate the hpte. NOTE: this also unlocks it */
+-			hptep->v = 0;
+-		}
+-
+-		j++;
+-	}
+-
+-	if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
+-		asm volatile("ptesync":::"memory");
+-
+-		for (i = 0; i < j; i++)
+-			__tlbiel(batch->vaddr[i]);
+-
+-		asm volatile("ptesync":::"memory");
+-	} else {
+-		int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
+-
+-		if (lock_tlbie)
+-			spin_lock(&native_tlbie_lock);
+-
+-		asm volatile("ptesync":::"memory");
+-
+-		for (i = 0; i < j; i++)
+-			__tlbie(batch->vaddr[i], large);
+-
+-		asm volatile("eieio; tlbsync; ptesync":::"memory");
+-
+-		if (lock_tlbie)
+-			spin_unlock(&native_tlbie_lock);
+-	}
+-
+-	local_irq_restore(flags);
+-}
+-
+-#ifdef CONFIG_PPC_PSERIES
+-/* Disable TLB batching on nighthawk */
+-static inline int tlb_batching_enabled(void)
+-{
+-	struct device_node *root = of_find_node_by_path("/");
+-	int enabled = 1;
+-
+-	if (root) {
+-		const char *model = get_property(root, "model", NULL);
+-		if (model && !strcmp(model, "IBM,9076-N81"))
+-			enabled = 0;
+-		of_node_put(root);
+-	}
+-
+-	return enabled;
+-}
+-#else
+-static inline int tlb_batching_enabled(void)
+-{
+-	return 1;
+-}
+-#endif
+-
+-void hpte_init_native(void)
+-{
+-	ppc_md.hpte_invalidate	= native_hpte_invalidate;
+-	ppc_md.hpte_updatepp	= native_hpte_updatepp;
+-	ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp;
+-	ppc_md.hpte_insert	= native_hpte_insert;
+-	ppc_md.hpte_remove	= native_hpte_remove;
+-	ppc_md.hpte_clear_all	= native_hpte_clear;
+-	if (tlb_batching_enabled())
+-		ppc_md.flush_hash_range = native_flush_hash_range;
+-	htab_finish_init();
+-}
+diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/hash_utils.c
++++ /dev/null
+@@ -1,438 +0,0 @@
+-/*
+- * PowerPC64 port by Mike Corrigan and Dave Engebretsen
+- *   {mikejc|engebret}@us.ibm.com
+- *
+- *    Copyright (c) 2000 Mike Corrigan <mikejc at us.ibm.com>
+- *
+- * SMP scalability work:
+- *    Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, IBM
+- * 
+- *    Module name: htab.c
+- *
+- *    Description:
+- *      PowerPC Hashed Page Table 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.
+- */
+-
+-#undef DEBUG
+-
+-#include <linux/config.h>
+-#include <linux/spinlock.h>
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/proc_fs.h>
+-#include <linux/stat.h>
+-#include <linux/sysctl.h>
+-#include <linux/ctype.h>
+-#include <linux/cache.h>
+-#include <linux/init.h>
+-#include <linux/signal.h>
+-
+-#include <asm/ppcdebug.h>
+-#include <asm/processor.h>
+-#include <asm/pgtable.h>
+-#include <asm/mmu.h>
+-#include <asm/mmu_context.h>
+-#include <asm/page.h>
+-#include <asm/types.h>
+-#include <asm/system.h>
+-#include <asm/uaccess.h>
+-#include <asm/machdep.h>
+-#include <asm/lmb.h>
+-#include <asm/abs_addr.h>
+-#include <asm/tlbflush.h>
+-#include <asm/io.h>
+-#include <asm/eeh.h>
+-#include <asm/tlb.h>
+-#include <asm/cacheflush.h>
+-#include <asm/cputable.h>
+-#include <asm/abs_addr.h>
+-#include <asm/sections.h>
+-
+-#ifdef DEBUG
+-#define DBG(fmt...) udbg_printf(fmt)
+-#else
+-#define DBG(fmt...)
+-#endif
+-
+-/*
+- * Note:  pte   --> Linux PTE
+- *        HPTE  --> PowerPC Hashed Page Table Entry
+- *
+- * Execution context:
+- *   htab_initialize is called with the MMU off (of course), but
+- *   the kernel has been copied down to zero so it can directly
+- *   reference global data.  At this point it is very difficult
+- *   to print debug info.
+- *
+- */
+-
+-#ifdef CONFIG_U3_DART
+-extern unsigned long dart_tablebase;
+-#endif /* CONFIG_U3_DART */
+-
+-hpte_t *htab_address;
+-unsigned long htab_hash_mask;
+-
+-extern unsigned long _SDR1;
+-
+-#define KB (1024)
+-#define MB (1024*KB)
+-
+-static inline void loop_forever(void)
+-{
+-	volatile unsigned long x = 1;
+-	for(;x;x|=1)
+-		;
+-}
+-
+-#ifdef CONFIG_PPC_MULTIPLATFORM
+-static inline void create_pte_mapping(unsigned long start, unsigned long end,
+-				      unsigned long mode, int large)
+-{
+-	unsigned long addr;
+-	unsigned int step;
+-	unsigned long tmp_mode;
+-	unsigned long vflags;
+-
+-	if (large) {
+-		step = 16*MB;
+-		vflags = HPTE_V_BOLTED | HPTE_V_LARGE;
+-	} else {
+-		step = 4*KB;
+-		vflags = HPTE_V_BOLTED;
+-	}
+-
+-	for (addr = start; addr < end; addr += step) {
+-		unsigned long vpn, hash, hpteg;
+-		unsigned long vsid = get_kernel_vsid(addr);
+-		unsigned long va = (vsid << 28) | (addr & 0xfffffff);
+-		int ret;
+-
+-		if (large)
+-			vpn = va >> HPAGE_SHIFT;
+-		else
+-			vpn = va >> PAGE_SHIFT;
+-
+-
+-		tmp_mode = mode;
+-		
+-		/* Make non-kernel text non-executable */
+-		if (!in_kernel_text(addr))
+-			tmp_mode = mode | HW_NO_EXEC;
+-
+-		hash = hpt_hash(vpn, large);
+-
+-		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
+-
+-#ifdef CONFIG_PPC_PSERIES
+-		if (systemcfg->platform & PLATFORM_LPAR)
+-			ret = pSeries_lpar_hpte_insert(hpteg, va,
+-				virt_to_abs(addr) >> PAGE_SHIFT,
+-				vflags, tmp_mode);
+-		else
+-#endif /* CONFIG_PPC_PSERIES */
+-			ret = native_hpte_insert(hpteg, va,
+-				virt_to_abs(addr) >> PAGE_SHIFT,
+-				vflags, tmp_mode);
+-
+-		if (ret == -1) {
+-			ppc64_terminate_msg(0x20, "create_pte_mapping");
+-			loop_forever();
+-		}
+-	}
+-}
+-
+-void __init htab_initialize(void)
+-{
+-	unsigned long table, htab_size_bytes;
+-	unsigned long pteg_count;
+-	unsigned long mode_rw;
+-	int i, use_largepages = 0;
+-	unsigned long base = 0, size = 0;
+-	extern unsigned long tce_alloc_start, tce_alloc_end;
+-
+-	DBG(" -> htab_initialize()\n");
+-
+-	/*
+-	 * Calculate the required size of the htab.  We want the number of
+-	 * PTEGs to equal one half the number of real pages.
+-	 */ 
+-	htab_size_bytes = 1UL << ppc64_pft_size;
+-	pteg_count = htab_size_bytes >> 7;
+-
+-	/* For debug, make the HTAB 1/8 as big as it normally would be. */
+-	ifppcdebug(PPCDBG_HTABSIZE) {
+-		pteg_count >>= 3;
+-		htab_size_bytes = pteg_count << 7;
+-	}
+-
+-	htab_hash_mask = pteg_count - 1;
+-
+-	if (systemcfg->platform & PLATFORM_LPAR) {
+-		/* Using a hypervisor which owns the htab */
+-		htab_address = NULL;
+-		_SDR1 = 0; 
+-	} else {
+-		/* Find storage for the HPT.  Must be contiguous in
+-		 * the absolute address space.
+-		 */
+-		table = lmb_alloc(htab_size_bytes, htab_size_bytes);
+-
+-		DBG("Hash table allocated at %lx, size: %lx\n", table,
+-		    htab_size_bytes);
+-
+-		if ( !table ) {
+-			ppc64_terminate_msg(0x20, "hpt space");
+-			loop_forever();
+-		}
+-		htab_address = abs_to_virt(table);
+-
+-		/* htab absolute addr + encoded htabsize */
+-		_SDR1 = table + __ilog2(pteg_count) - 11;
+-
+-		/* Initialize the HPT with no entries */
+-		memset((void *)table, 0, htab_size_bytes);
+-	}
+-
+-	mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
+-
+-	/* On U3 based machines, we need to reserve the DART area and
+-	 * _NOT_ map it to avoid cache paradoxes as it's remapped non
+-	 * cacheable later on
+-	 */
+-	if (cpu_has_feature(CPU_FTR_16M_PAGE))
+-		use_largepages = 1;
+-
+-	/* create bolted the linear mapping in the hash table */
+-	for (i=0; i < lmb.memory.cnt; i++) {
+-		base = lmb.memory.region[i].base + KERNELBASE;
+-		size = lmb.memory.region[i].size;
+-
+-		DBG("creating mapping for region: %lx : %lx\n", base, size);
+-
+-#ifdef CONFIG_U3_DART
+-		/* Do not map the DART space. Fortunately, it will be aligned
+-		 * in such a way that it will not cross two lmb regions and will
+-		 * fit within a single 16Mb page.
+-		 * The DART space is assumed to be a full 16Mb region even if we
+-		 * only use 2Mb of that space. We will use more of it later for
+-		 * AGP GART. We have to use a full 16Mb large page.
+-		 */
+-		DBG("DART base: %lx\n", dart_tablebase);
+-
+-		if (dart_tablebase != 0 && dart_tablebase >= base
+-		    && dart_tablebase < (base + size)) {
+-			if (base != dart_tablebase)
+-				create_pte_mapping(base, dart_tablebase, mode_rw,
+-						   use_largepages);
+-			if ((base + size) > (dart_tablebase + 16*MB))
+-				create_pte_mapping(dart_tablebase + 16*MB, base + size,
+-						   mode_rw, use_largepages);
+-			continue;
+-		}
+-#endif /* CONFIG_U3_DART */
+-		create_pte_mapping(base, base + size, mode_rw, use_largepages);
+-	}
+-
+-	/*
+-	 * If we have a memory_limit and we've allocated TCEs then we need to
+-	 * explicitly map the TCE area at the top of RAM. We also cope with the
+-	 * case that the TCEs start below memory_limit.
+-	 * tce_alloc_start/end are 16MB aligned so the mapping should work
+-	 * for either 4K or 16MB pages.
+-	 */
+-	if (tce_alloc_start) {
+-		tce_alloc_start += KERNELBASE;
+-		tce_alloc_end += KERNELBASE;
+-
+-		if (base + size >= tce_alloc_start)
+-			tce_alloc_start = base + size + 1;
+-
+-		create_pte_mapping(tce_alloc_start, tce_alloc_end,
+-			mode_rw, use_largepages);
+-	}
+-
+-	DBG(" <- htab_initialize()\n");
+-}
+-#undef KB
+-#undef MB
+-#endif /* CONFIG_PPC_MULTIPLATFORM */
+-
+-/*
+- * Called by asm hashtable.S for doing lazy icache flush
+- */
+-unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
+-{
+-	struct page *page;
+-
+-	if (!pfn_valid(pte_pfn(pte)))
+-		return pp;
+-
+-	page = pte_page(pte);
+-
+-	/* page is dirty */
+-	if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
+-		if (trap == 0x400) {
+-			__flush_dcache_icache(page_address(page));
+-			set_bit(PG_arch_1, &page->flags);
+-		} else
+-			pp |= HW_NO_EXEC;
+-	}
+-	return pp;
+-}
+-
+-/* Result code is:
+- *  0 - handled
+- *  1 - normal page fault
+- * -1 - critical hash insertion error
+- */
+-int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
+-{
+-	void *pgdir;
+-	unsigned long vsid;
+-	struct mm_struct *mm;
+-	pte_t *ptep;
+-	int ret;
+-	int user_region = 0;
+-	int local = 0;
+-	cpumask_t tmp;
+-
+-	if ((ea & ~REGION_MASK) >= PGTABLE_RANGE)
+-		return 1;
+-
+- 	switch (REGION_ID(ea)) {
+-	case USER_REGION_ID:
+-		user_region = 1;
+-		mm = current->mm;
+-		if (! mm)
+-			return 1;
+-
+-		vsid = get_vsid(mm->context.id, ea);
+-		break;
+-	case VMALLOC_REGION_ID:
+-		mm = &init_mm;
+-		vsid = get_kernel_vsid(ea);
+-		break;
+-#if 0
+-	case KERNEL_REGION_ID:
+-		/*
+-		 * Should never get here - entire 0xC0... region is bolted.
+-		 * Send the problem up to do_page_fault 
+-		 */
+-#endif
+-	default:
+-		/* Not a valid range
+-		 * Send the problem up to do_page_fault 
+-		 */
+-		return 1;
+-		break;
+-	}
+-
+-	pgdir = mm->pgd;
+-
+-	if (pgdir == NULL)
+-		return 1;
+-
+-	tmp = cpumask_of_cpu(smp_processor_id());
+-	if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
+-		local = 1;
+-
+-	/* Is this a huge page ? */
+-	if (unlikely(in_hugepage_area(mm->context, ea)))
+-		ret = hash_huge_page(mm, access, ea, vsid, local);
+-	else {
+-		ptep = find_linux_pte(pgdir, ea);
+-		if (ptep == NULL)
+-			return 1;
+-		ret = __hash_page(ea, access, vsid, ptep, trap, local);
+-	}
+-
+-	return ret;
+-}
+-
+-void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
+-		     int local)
+-{
+-	unsigned long vsid, vpn, va, hash, secondary, slot;
+-	unsigned long huge = pte_huge(pte);
+-
+-	if (ea < KERNELBASE)
+-		vsid = get_vsid(context, ea);
+-	else
+-		vsid = get_kernel_vsid(ea);
+-
+-	va = (vsid << 28) | (ea & 0x0fffffff);
+-	if (huge)
+-		vpn = va >> HPAGE_SHIFT;
+-	else
+-		vpn = va >> PAGE_SHIFT;
+-	hash = hpt_hash(vpn, huge);
+-	secondary = (pte_val(pte) & _PAGE_SECONDARY) >> 15;
+-	if (secondary)
+-		hash = ~hash;
+-	slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+-	slot += (pte_val(pte) & _PAGE_GROUP_IX) >> 12;
+-
+-	ppc_md.hpte_invalidate(slot, va, huge, local);
+-}
+-
+-void flush_hash_range(unsigned long context, unsigned long number, int local)
+-{
+-	if (ppc_md.flush_hash_range) {
+-		ppc_md.flush_hash_range(context, number, local);
+-	} else {
+-		int i;
+-		struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
+-
+-		for (i = 0; i < number; i++)
+-			flush_hash_page(context, batch->addr[i], batch->pte[i],
+-					local);
+-	}
+-}
+-
+-static inline void make_bl(unsigned int *insn_addr, void *func)
+-{
+-	unsigned long funcp = *((unsigned long *)func);
+-	int offset = funcp - (unsigned long)insn_addr;
+-
+-	*insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
+-	flush_icache_range((unsigned long)insn_addr, 4+
+-			   (unsigned long)insn_addr);
+-}
+-
+-/*
+- * low_hash_fault is called when we the low level hash code failed
+- * to instert a PTE due to an hypervisor error
+- */
+-void low_hash_fault(struct pt_regs *regs, unsigned long address)
+-{
+-	if (user_mode(regs)) {
+-		siginfo_t info;
+-
+-		info.si_signo = SIGBUS;
+-		info.si_errno = 0;
+-		info.si_code = BUS_ADRERR;
+-		info.si_addr = (void __user *)address;
+-		force_sig_info(SIGBUS, &info, current);
+-		return;
+-	}
+-	bad_page_fault(regs, address, SIGBUS);
+-}
+-
+-void __init htab_finish_init(void)
+-{
+-	extern unsigned int *htab_call_hpte_insert1;
+-	extern unsigned int *htab_call_hpte_insert2;
+-	extern unsigned int *htab_call_hpte_remove;
+-	extern unsigned int *htab_call_hpte_updatepp;
+-
+-	make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
+-	make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
+-	make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
+-	make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
+-}
+diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/hugetlbpage.c
++++ /dev/null
+@@ -1,745 +0,0 @@
+-/*
+- * PPC64 (POWER4) Huge TLB Page Support for Kernel.
+- *
+- * Copyright (C) 2003 David Gibson, IBM Corporation.
+- *
+- * Based on the IA-32 version:
+- * Copyright (C) 2002, Rohit Seth <rohit.seth at intel.com>
+- */
+-
+-#include <linux/init.h>
+-#include <linux/fs.h>
+-#include <linux/mm.h>
+-#include <linux/hugetlb.h>
+-#include <linux/pagemap.h>
+-#include <linux/smp_lock.h>
+-#include <linux/slab.h>
+-#include <linux/err.h>
+-#include <linux/sysctl.h>
+-#include <asm/mman.h>
+-#include <asm/pgalloc.h>
+-#include <asm/tlb.h>
+-#include <asm/tlbflush.h>
+-#include <asm/mmu_context.h>
+-#include <asm/machdep.h>
+-#include <asm/cputable.h>
+-#include <asm/tlb.h>
+-
+-#include <linux/sysctl.h>
+-
+-#define NUM_LOW_AREAS	(0x100000000UL >> SID_SHIFT)
+-#define NUM_HIGH_AREAS	(PGTABLE_RANGE >> HTLB_AREA_SHIFT)
+-
+-/* Modelled after find_linux_pte() */
+-pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+-{
+-	pgd_t *pg;
+-	pud_t *pu;
+-	pmd_t *pm;
+-	pte_t *pt;
+-
+-	BUG_ON(! in_hugepage_area(mm->context, addr));
+-
+-	addr &= HPAGE_MASK;
+-
+-	pg = pgd_offset(mm, addr);
+-	if (!pgd_none(*pg)) {
+-		pu = pud_offset(pg, addr);
+-		if (!pud_none(*pu)) {
+-			pm = pmd_offset(pu, addr);
+-			pt = (pte_t *)pm;
+-			BUG_ON(!pmd_none(*pm)
+-			       && !(pte_present(*pt) && pte_huge(*pt)));
+-			return pt;
+-		}
+-	}
+-
+-	return NULL;
+-}
+-
+-pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
+-{
+-	pgd_t *pg;
+-	pud_t *pu;
+-	pmd_t *pm;
+-	pte_t *pt;
+-
+-	BUG_ON(! in_hugepage_area(mm->context, addr));
+-
+-	addr &= HPAGE_MASK;
+-
+-	pg = pgd_offset(mm, addr);
+-	pu = pud_alloc(mm, pg, addr);
+-
+-	if (pu) {
+-		pm = pmd_alloc(mm, pu, addr);
+-		if (pm) {
+-			pt = (pte_t *)pm;
+-			BUG_ON(!pmd_none(*pm)
+-			       && !(pte_present(*pt) && pte_huge(*pt)));
+-			return pt;
+-		}
+-	}
+-
+-	return NULL;
+-}
+-
+-#define HUGEPTE_BATCH_SIZE	(HPAGE_SIZE / PMD_SIZE)
+-
+-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+-		     pte_t *ptep, pte_t pte)
+-{
+-	int i;
+-
+-	if (pte_present(*ptep)) {
+-		pte_clear(mm, addr, ptep);
+-		flush_tlb_pending();
+-	}
+-
+-	for (i = 0; i < HUGEPTE_BATCH_SIZE; i++) {
+-		*ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+-		ptep++;
+-	}
+-}
+-
+-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+-			      pte_t *ptep)
+-{
+-	unsigned long old = pte_update(ptep, ~0UL);
+-	int i;
+-
+-	if (old & _PAGE_HASHPTE)
+-		hpte_update(mm, addr, old, 0);
+-
+-	for (i = 1; i < HUGEPTE_BATCH_SIZE; i++)
+-		ptep[i] = __pte(0);
+-
+-	return __pte(old);
+-}
+-
+-/*
+- * This function checks for proper alignment of input addr and len parameters.
+- */
+-int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
+-{
+-	if (len & ~HPAGE_MASK)
+-		return -EINVAL;
+-	if (addr & ~HPAGE_MASK)
+-		return -EINVAL;
+-	if (! (within_hugepage_low_range(addr, len)
+-	       || within_hugepage_high_range(addr, len)) )
+-		return -EINVAL;
+-	return 0;
+-}
+-
+-static void flush_low_segments(void *parm)
+-{
+-	u16 areas = (unsigned long) parm;
+-	unsigned long i;
+-
+-	asm volatile("isync" : : : "memory");
+-
+-	BUILD_BUG_ON((sizeof(areas)*8) != NUM_LOW_AREAS);
+-
+-	for (i = 0; i < NUM_LOW_AREAS; i++) {
+-		if (! (areas & (1U << i)))
+-			continue;
+-		asm volatile("slbie %0"
+-			     : : "r" ((i << SID_SHIFT) | SLBIE_C));
+-	}
+-
+-	asm volatile("isync" : : : "memory");
+-}
+-
+-static void flush_high_segments(void *parm)
+-{
+-	u16 areas = (unsigned long) parm;
+-	unsigned long i, j;
+-
+-	asm volatile("isync" : : : "memory");
+-
+-	BUILD_BUG_ON((sizeof(areas)*8) != NUM_HIGH_AREAS);
+-
+-	for (i = 0; i < NUM_HIGH_AREAS; i++) {
+-		if (! (areas & (1U << i)))
+-			continue;
+-		for (j = 0; j < (1UL << (HTLB_AREA_SHIFT-SID_SHIFT)); j++)
+-			asm volatile("slbie %0"
+-				     :: "r" (((i << HTLB_AREA_SHIFT)
+-					     + (j << SID_SHIFT)) | SLBIE_C));
+-	}
+-
+-	asm volatile("isync" : : : "memory");
+-}
+-
+-static int prepare_low_area_for_htlb(struct mm_struct *mm, unsigned long area)
+-{
+-	unsigned long start = area << SID_SHIFT;
+-	unsigned long end = (area+1) << SID_SHIFT;
+-	struct vm_area_struct *vma;
+-
+-	BUG_ON(area >= NUM_LOW_AREAS);
+-
+-	/* Check no VMAs are in the region */
+-	vma = find_vma(mm, start);
+-	if (vma && (vma->vm_start < end))
+-		return -EBUSY;
+-
+-	return 0;
+-}
+-
+-static int prepare_high_area_for_htlb(struct mm_struct *mm, unsigned long area)
+-{
+-	unsigned long start = area << HTLB_AREA_SHIFT;
+-	unsigned long end = (area+1) << HTLB_AREA_SHIFT;
+-	struct vm_area_struct *vma;
+-
+-	BUG_ON(area >= NUM_HIGH_AREAS);
+-
+-	/* Check no VMAs are in the region */
+-	vma = find_vma(mm, start);
+-	if (vma && (vma->vm_start < end))
+-		return -EBUSY;
+-
+-	return 0;
+-}
+-
+-static int open_low_hpage_areas(struct mm_struct *mm, u16 newareas)
+-{
+-	unsigned long i;
+-
+-	BUILD_BUG_ON((sizeof(newareas)*8) != NUM_LOW_AREAS);
+-	BUILD_BUG_ON((sizeof(mm->context.low_htlb_areas)*8) != NUM_LOW_AREAS);
+-
+-	newareas &= ~(mm->context.low_htlb_areas);
+-	if (! newareas)
+-		return 0; /* The segments we want are already open */
+-
+-	for (i = 0; i < NUM_LOW_AREAS; i++)
+-		if ((1 << i) & newareas)
+-			if (prepare_low_area_for_htlb(mm, i) != 0)
+-				return -EBUSY;
+-
+-	mm->context.low_htlb_areas |= newareas;
+-
+-	/* update the paca copy of the context struct */
+-	get_paca()->context = mm->context;
+-
+-	/* the context change must make it to memory before the flush,
+-	 * so that further SLB misses do the right thing. */
+-	mb();
+-	on_each_cpu(flush_low_segments, (void *)(unsigned long)newareas, 0, 1);
+-
+-	return 0;
+-}
+-
+-static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas)
+-{
+-	unsigned long i;
+-
+-	BUILD_BUG_ON((sizeof(newareas)*8) != NUM_HIGH_AREAS);
+-	BUILD_BUG_ON((sizeof(mm->context.high_htlb_areas)*8)
+-		     != NUM_HIGH_AREAS);
+-
+-	newareas &= ~(mm->context.high_htlb_areas);
+-	if (! newareas)
+-		return 0; /* The areas we want are already open */
+-
+-	for (i = 0; i < NUM_HIGH_AREAS; i++)
+-		if ((1 << i) & newareas)
+-			if (prepare_high_area_for_htlb(mm, i) != 0)
+-				return -EBUSY;
+-
+-	mm->context.high_htlb_areas |= newareas;
+-
+-	/* update the paca copy of the context struct */
+-	get_paca()->context = mm->context;
+-
+-	/* the context change must make it to memory before the flush,
+-	 * so that further SLB misses do the right thing. */
+-	mb();
+-	on_each_cpu(flush_high_segments, (void *)(unsigned long)newareas, 0, 1);
+-
+-	return 0;
+-}
+-
+-int prepare_hugepage_range(unsigned long addr, unsigned long len)
+-{
+-	int err;
+-
+-	if ( (addr+len) < addr )
+-		return -EINVAL;
+-
+-	if ((addr + len) < 0x100000000UL)
+-		err = open_low_hpage_areas(current->mm,
+-					  LOW_ESID_MASK(addr, len));
+-	else
+-		err = open_high_hpage_areas(current->mm,
+-					    HTLB_AREA_MASK(addr, len));
+-	if (err) {
+-		printk(KERN_DEBUG "prepare_hugepage_range(%lx, %lx)"
+-		       " failed (lowmask: 0x%04hx, highmask: 0x%04hx)\n",
+-		       addr, len,
+-		       LOW_ESID_MASK(addr, len), HTLB_AREA_MASK(addr, len));
+-		return err;
+-	}
+-
+-	return 0;
+-}
+-
+-struct page *
+-follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
+-{
+-	pte_t *ptep;
+-	struct page *page;
+-
+-	if (! in_hugepage_area(mm->context, address))
+-		return ERR_PTR(-EINVAL);
+-
+-	ptep = huge_pte_offset(mm, address);
+-	page = pte_page(*ptep);
+-	if (page)
+-		page += (address % HPAGE_SIZE) / PAGE_SIZE;
+-
+-	return page;
+-}
+-
+-int pmd_huge(pmd_t pmd)
+-{
+-	return 0;
+-}
+-
+-struct page *
+-follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+-		pmd_t *pmd, int write)
+-{
+-	BUG();
+-	return NULL;
+-}
+-
+-/* Because we have an exclusive hugepage region which lies within the
+- * normal user address space, we have to take special measures to make
+- * non-huge mmap()s evade the hugepage reserved regions. */
+-unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+-				     unsigned long len, unsigned long pgoff,
+-				     unsigned long flags)
+-{
+-	struct mm_struct *mm = current->mm;
+-	struct vm_area_struct *vma;
+-	unsigned long start_addr;
+-
+-	if (len > TASK_SIZE)
+-		return -ENOMEM;
+-
+-	if (addr) {
+-		addr = PAGE_ALIGN(addr);
+-		vma = find_vma(mm, addr);
+-		if (((TASK_SIZE - len) >= addr)
+-		    && (!vma || (addr+len) <= vma->vm_start)
+-		    && !is_hugepage_only_range(mm, addr,len))
+-			return addr;
+-	}
+-	if (len > mm->cached_hole_size) {
+-	        start_addr = addr = mm->free_area_cache;
+-	} else {
+-	        start_addr = addr = TASK_UNMAPPED_BASE;
+-	        mm->cached_hole_size = 0;
+-	}
+-
+-full_search:
+-	vma = find_vma(mm, addr);
+-	while (TASK_SIZE - len >= addr) {
+-		BUG_ON(vma && (addr >= vma->vm_end));
+-
+-		if (touches_hugepage_low_range(mm, addr, len)) {
+-			addr = ALIGN(addr+1, 1<<SID_SHIFT);
+-			vma = find_vma(mm, addr);
+-			continue;
+-		}
+-		if (touches_hugepage_high_range(mm, addr, len)) {
+-			addr = ALIGN(addr+1, 1UL<<HTLB_AREA_SHIFT);
+-			vma = find_vma(mm, addr);
+-			continue;
+-		}
+-		if (!vma || addr + len <= vma->vm_start) {
+-			/*
+-			 * Remember the place where we stopped the search:
+-			 */
+-			mm->free_area_cache = addr + len;
+-			return addr;
+-		}
+-		if (addr + mm->cached_hole_size < vma->vm_start)
+-		        mm->cached_hole_size = vma->vm_start - addr;
+-		addr = vma->vm_end;
+-		vma = vma->vm_next;
+-	}
+-
+-	/* Make sure we didn't miss any holes */
+-	if (start_addr != TASK_UNMAPPED_BASE) {
+-		start_addr = addr = TASK_UNMAPPED_BASE;
+-		mm->cached_hole_size = 0;
+-		goto full_search;
+-	}
+-	return -ENOMEM;
+-}
+-
+-/*
+- * This mmap-allocator allocates new areas top-down from below the
+- * stack's low limit (the base):
+- *
+- * Because we have an exclusive hugepage region which lies within the
+- * normal user address space, we have to take special measures to make
+- * non-huge mmap()s evade the hugepage reserved regions.
+- */
+-unsigned long
+-arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+-			  const unsigned long len, const unsigned long pgoff,
+-			  const unsigned long flags)
+-{
+-	struct vm_area_struct *vma, *prev_vma;
+-	struct mm_struct *mm = current->mm;
+-	unsigned long base = mm->mmap_base, addr = addr0;
+-	unsigned long largest_hole = mm->cached_hole_size;
+-	int first_time = 1;
+-
+-	/* requested length too big for entire address space */
+-	if (len > TASK_SIZE)
+-		return -ENOMEM;
+-
+-	/* dont allow allocations above current base */
+-	if (mm->free_area_cache > base)
+-		mm->free_area_cache = base;
+-
+-	/* requesting a specific address */
+-	if (addr) {
+-		addr = PAGE_ALIGN(addr);
+-		vma = find_vma(mm, addr);
+-		if (TASK_SIZE - len >= addr &&
+-				(!vma || addr + len <= vma->vm_start)
+-				&& !is_hugepage_only_range(mm, addr,len))
+-			return addr;
+-	}
+-
+-	if (len <= largest_hole) {
+-	        largest_hole = 0;
+-		mm->free_area_cache = base;
+-	}
+-try_again:
+-	/* make sure it can fit in the remaining address space */
+-	if (mm->free_area_cache < len)
+-		goto fail;
+-
+-	/* either no address requested or cant fit in requested address hole */
+-	addr = (mm->free_area_cache - len) & PAGE_MASK;
+-	do {
+-hugepage_recheck:
+-		if (touches_hugepage_low_range(mm, addr, len)) {
+-			addr = (addr & ((~0) << SID_SHIFT)) - len;
+-			goto hugepage_recheck;
+-		} else if (touches_hugepage_high_range(mm, addr, len)) {
+-			addr = (addr & ((~0UL) << HTLB_AREA_SHIFT)) - len;
+-			goto hugepage_recheck;
+-		}
+-
+-		/*
+-		 * Lookup failure means no vma is above this address,
+-		 * i.e. return with success:
+-		 */
+- 	 	if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
+-			return addr;
+-
+-		/*
+-		 * new region fits between prev_vma->vm_end and
+-		 * vma->vm_start, use it:
+-		 */
+-		if (addr+len <= vma->vm_start &&
+-		          (!prev_vma || (addr >= prev_vma->vm_end))) {
+-			/* remember the address as a hint for next time */
+-		        mm->cached_hole_size = largest_hole;
+-		        return (mm->free_area_cache = addr);
+-		} else {
+-			/* pull free_area_cache down to the first hole */
+-		        if (mm->free_area_cache == vma->vm_end) {
+-				mm->free_area_cache = vma->vm_start;
+-				mm->cached_hole_size = largest_hole;
+-			}
+-		}
+-
+-		/* remember the largest hole we saw so far */
+-		if (addr + largest_hole < vma->vm_start)
+-		        largest_hole = vma->vm_start - addr;
+-
+-		/* try just below the current vma->vm_start */
+-		addr = vma->vm_start-len;
+-	} while (len <= vma->vm_start);
+-
+-fail:
+-	/*
+-	 * if hint left us with no space for the requested
+-	 * mapping then try again:
+-	 */
+-	if (first_time) {
+-		mm->free_area_cache = base;
+-		largest_hole = 0;
+-		first_time = 0;
+-		goto try_again;
+-	}
+-	/*
+-	 * A failed mmap() very likely causes application failure,
+-	 * so fall back to the bottom-up function here. This scenario
+-	 * can happen with large stack limits and large mmap()
+-	 * allocations.
+-	 */
+-	mm->free_area_cache = TASK_UNMAPPED_BASE;
+-	mm->cached_hole_size = ~0UL;
+-	addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
+-	/*
+-	 * Restore the topdown base:
+-	 */
+-	mm->free_area_cache = base;
+-	mm->cached_hole_size = ~0UL;
+-
+-	return addr;
+-}
+-
+-static unsigned long htlb_get_low_area(unsigned long len, u16 segmask)
+-{
+-	unsigned long addr = 0;
+-	struct vm_area_struct *vma;
+-
+-	vma = find_vma(current->mm, addr);
+-	while (addr + len <= 0x100000000UL) {
+-		BUG_ON(vma && (addr >= vma->vm_end)); /* invariant */
+-
+-		if (! __within_hugepage_low_range(addr, len, segmask)) {
+-			addr = ALIGN(addr+1, 1<<SID_SHIFT);
+-			vma = find_vma(current->mm, addr);
+-			continue;
+-		}
+-
+-		if (!vma || (addr + len) <= vma->vm_start)
+-			return addr;
+-		addr = ALIGN(vma->vm_end, HPAGE_SIZE);
+-		/* Depending on segmask this might not be a confirmed
+-		 * hugepage region, so the ALIGN could have skipped
+-		 * some VMAs */
+-		vma = find_vma(current->mm, addr);
+-	}
+-
+-	return -ENOMEM;
+-}
+-
+-static unsigned long htlb_get_high_area(unsigned long len, u16 areamask)
+-{
+-	unsigned long addr = 0x100000000UL;
+-	struct vm_area_struct *vma;
+-
+-	vma = find_vma(current->mm, addr);
+-	while (addr + len <= TASK_SIZE_USER64) {
+-		BUG_ON(vma && (addr >= vma->vm_end)); /* invariant */
+-
+-		if (! __within_hugepage_high_range(addr, len, areamask)) {
+-			addr = ALIGN(addr+1, 1UL<<HTLB_AREA_SHIFT);
+-			vma = find_vma(current->mm, addr);
+-			continue;
+-		}
+-
+-		if (!vma || (addr + len) <= vma->vm_start)
+-			return addr;
+-		addr = ALIGN(vma->vm_end, HPAGE_SIZE);
+-		/* Depending on segmask this might not be a confirmed
+-		 * hugepage region, so the ALIGN could have skipped
+-		 * some VMAs */
+-		vma = find_vma(current->mm, addr);
+-	}
+-
+-	return -ENOMEM;
+-}
+-
+-unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+-					unsigned long len, unsigned long pgoff,
+-					unsigned long flags)
+-{
+-	int lastshift;
+-	u16 areamask, curareas;
+-
+-	if (len & ~HPAGE_MASK)
+-		return -EINVAL;
+-
+-	if (!cpu_has_feature(CPU_FTR_16M_PAGE))
+-		return -EINVAL;
+-
+-	if (test_thread_flag(TIF_32BIT)) {
+-		curareas = current->mm->context.low_htlb_areas;
+-
+-		/* First see if we can do the mapping in the existing
+-		 * low areas */
+-		addr = htlb_get_low_area(len, curareas);
+-		if (addr != -ENOMEM)
+-			return addr;
+-
+-		lastshift = 0;
+-		for (areamask = LOW_ESID_MASK(0x100000000UL-len, len);
+-		     ! lastshift; areamask >>=1) {
+-			if (areamask & 1)
+-				lastshift = 1;
+-
+-			addr = htlb_get_low_area(len, curareas | areamask);
+-			if ((addr != -ENOMEM)
+-			    && open_low_hpage_areas(current->mm, areamask) == 0)
+-				return addr;
+-		}
+-	} else {
+-		curareas = current->mm->context.high_htlb_areas;
+-
+-		/* First see if we can do the mapping in the existing
+-		 * high areas */
+-		addr = htlb_get_high_area(len, curareas);
+-		if (addr != -ENOMEM)
+-			return addr;
+-
+-		lastshift = 0;
+-		for (areamask = HTLB_AREA_MASK(TASK_SIZE_USER64-len, len);
+-		     ! lastshift; areamask >>=1) {
+-			if (areamask & 1)
+-				lastshift = 1;
+-
+-			addr = htlb_get_high_area(len, curareas | areamask);
+-			if ((addr != -ENOMEM)
+-			    && open_high_hpage_areas(current->mm, areamask) == 0)
+-				return addr;
+-		}
+-	}
+-	printk(KERN_DEBUG "hugetlb_get_unmapped_area() unable to open"
+-	       " enough areas\n");
+-	return -ENOMEM;
+-}
+-
+-int hash_huge_page(struct mm_struct *mm, unsigned long access,
+-		   unsigned long ea, unsigned long vsid, int local)
+-{
+-	pte_t *ptep;
+-	unsigned long va, vpn;
+-	pte_t old_pte, new_pte;
+-	unsigned long rflags, prpn;
+-	long slot;
+-	int err = 1;
+-
+-	spin_lock(&mm->page_table_lock);
+-
+-	ptep = huge_pte_offset(mm, ea);
+-
+-	/* Search the Linux page table for a match with va */
+-	va = (vsid << 28) | (ea & 0x0fffffff);
+-	vpn = va >> HPAGE_SHIFT;
+-
+-	/*
+-	 * If no pte found or not present, send the problem up to
+-	 * do_page_fault
+-	 */
+-	if (unlikely(!ptep || pte_none(*ptep)))
+-		goto out;
+-
+-/* 	BUG_ON(pte_bad(*ptep)); */
+-
+-	/* 
+-	 * Check the user's access rights to the page.  If access should be
+-	 * prevented then send the problem up to do_page_fault.
+-	 */
+-	if (unlikely(access & ~pte_val(*ptep)))
+-		goto out;
+-	/*
+-	 * At this point, we have a pte (old_pte) which can be used to build
+-	 * or update an HPTE. There are 2 cases:
+-	 *
+-	 * 1. There is a valid (present) pte with no associated HPTE (this is 
+-	 *	the most common case)
+-	 * 2. There is a valid (present) pte with an associated HPTE. The
+-	 *	current values of the pp bits in the HPTE prevent access
+-	 *	because we are doing software DIRTY bit management and the
+-	 *	page is currently not DIRTY. 
+-	 */
+-
+-
+-	old_pte = *ptep;
+-	new_pte = old_pte;
+-
+-	rflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW));
+- 	/* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */
+-	rflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC);
+-
+-	/* Check if pte already has an hpte (case 2) */
+-	if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) {
+-		/* There MIGHT be an HPTE for this pte */
+-		unsigned long hash, slot;
+-
+-		hash = hpt_hash(vpn, 1);
+-		if (pte_val(old_pte) & _PAGE_SECONDARY)
+-			hash = ~hash;
+-		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+-		slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12;
+-
+-		if (ppc_md.hpte_updatepp(slot, rflags, va, 1, local) == -1)
+-			pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;
+-	}
+-
+-	if (likely(!(pte_val(old_pte) & _PAGE_HASHPTE))) {
+-		unsigned long hash = hpt_hash(vpn, 1);
+-		unsigned long hpte_group;
+-
+-		prpn = pte_pfn(old_pte);
+-
+-repeat:
+-		hpte_group = ((hash & htab_hash_mask) *
+-			      HPTES_PER_GROUP) & ~0x7UL;
+-
+-		/* Update the linux pte with the HPTE slot */
+-		pte_val(new_pte) &= ~_PAGE_HPTEFLAGS;
+-		pte_val(new_pte) |= _PAGE_HASHPTE;
+-
+-		/* Add in WIMG bits */
+-		/* XXX We should store these in the pte */
+-		rflags |= _PAGE_COHERENT;
+-
+-		slot = ppc_md.hpte_insert(hpte_group, va, prpn,
+-					  HPTE_V_LARGE, rflags);
+-
+-		/* Primary is full, try the secondary */
+-		if (unlikely(slot == -1)) {
+-			pte_val(new_pte) |= _PAGE_SECONDARY;
+-			hpte_group = ((~hash & htab_hash_mask) *
+-				      HPTES_PER_GROUP) & ~0x7UL; 
+-			slot = ppc_md.hpte_insert(hpte_group, va, prpn,
+-						  HPTE_V_LARGE |
+-						  HPTE_V_SECONDARY,
+-						  rflags);
+-			if (slot == -1) {
+-				if (mftb() & 0x1)
+-					hpte_group = ((hash & htab_hash_mask) *
+-						      HPTES_PER_GROUP)&~0x7UL;
+-
+-				ppc_md.hpte_remove(hpte_group);
+-				goto repeat;
+-                        }
+-		}
+-
+-		if (unlikely(slot == -2))
+-			panic("hash_huge_page: pte_insert failed\n");
+-
+-		pte_val(new_pte) |= (slot<<12) & _PAGE_GROUP_IX;
+-
+-		/* 
+-		 * No need to use ldarx/stdcx here because all who
+-		 * might be updating the pte will hold the
+-		 * page_table_lock
+-		 */
+-		*ptep = new_pte;
+-	}
+-
+-	err = 0;
+-
+- out:
+-	spin_unlock(&mm->page_table_lock);
+-
+-	return err;
+-}
+diff --git a/arch/ppc64/mm/imalloc.c b/arch/ppc64/mm/imalloc.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/imalloc.c
++++ /dev/null
+@@ -1,317 +0,0 @@
+-/*
+- * c 2001 PPC 64 Team, IBM Corp
+- * 
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the GNU General Public License
+- *      as published by the Free Software Foundation; either version
+- *      2 of the License, or (at your option) any later version.
+- */
+-
+-#include <linux/slab.h>
+-#include <linux/vmalloc.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/pgalloc.h>
+-#include <asm/pgtable.h>
+-#include <asm/semaphore.h>
+-#include <asm/imalloc.h>
+-#include <asm/cacheflush.h>
+-
+-static DECLARE_MUTEX(imlist_sem);
+-struct vm_struct * imlist = NULL;
+-
+-static int get_free_im_addr(unsigned long size, unsigned long *im_addr)
+-{
+-	unsigned long addr;
+-	struct vm_struct **p, *tmp;
+-
+-	addr = ioremap_bot;
+-	for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
+-		if (size + addr < (unsigned long) tmp->addr)
+-			break;
+-		if ((unsigned long)tmp->addr >= ioremap_bot)
+-			addr = tmp->size + (unsigned long) tmp->addr;
+-		if (addr >= IMALLOC_END-size)
+-			return 1;
+-	}
+-	*im_addr = addr;
+-
+-	return 0;
+-}
+-
+-/* Return whether the region described by v_addr and size is a subset
+- * of the region described by parent
+- */
+-static inline int im_region_is_subset(unsigned long v_addr, unsigned long size,
+-			struct vm_struct *parent)
+-{
+-	return (int) (v_addr >= (unsigned long) parent->addr &&
+-	              v_addr < (unsigned long) parent->addr + parent->size &&
+-	    	      size < parent->size);
+-}
+-
+-/* Return whether the region described by v_addr and size is a superset
+- * of the region described by child
+- */
+-static int im_region_is_superset(unsigned long v_addr, unsigned long size,
+-		struct vm_struct *child)
+-{
+-	struct vm_struct parent;
+-
+-	parent.addr = (void *) v_addr;
+-	parent.size = size;
+-
+-	return im_region_is_subset((unsigned long) child->addr, child->size,
+-			&parent);
+-}
+-
+-/* Return whether the region described by v_addr and size overlaps
+- * the region described by vm.  Overlapping regions meet the
+- * following conditions:
+- * 1) The regions share some part of the address space
+- * 2) The regions aren't identical
+- * 3) Neither region is a subset of the other
+- */
+-static int im_region_overlaps(unsigned long v_addr, unsigned long size,
+-		     struct vm_struct *vm)
+-{
+-	if (im_region_is_superset(v_addr, size, vm))
+-		return 0;
+-
+-	return (v_addr + size > (unsigned long) vm->addr + vm->size &&
+-		v_addr < (unsigned long) vm->addr + vm->size) ||
+-	       (v_addr < (unsigned long) vm->addr &&
+-		v_addr + size > (unsigned long) vm->addr);
+-}
+-
+-/* Determine imalloc status of region described by v_addr and size.
+- * Can return one of the following:
+- * IM_REGION_UNUSED   -  Entire region is unallocated in imalloc space.
+- * IM_REGION_SUBSET -    Region is a subset of a region that is already
+- * 			 allocated in imalloc space.
+- * 		         vm will be assigned to a ptr to the parent region.
+- * IM_REGION_EXISTS -    Exact region already allocated in imalloc space.
+- *                       vm will be assigned to a ptr to the existing imlist
+- *                       member.
+- * IM_REGION_OVERLAPS -  Region overlaps an allocated region in imalloc space.
+- * IM_REGION_SUPERSET -  Region is a superset of a region that is already
+- *                       allocated in imalloc space.
+- */
+-static int im_region_status(unsigned long v_addr, unsigned long size,
+-		    struct vm_struct **vm)
+-{
+-	struct vm_struct *tmp;
+-
+-	for (tmp = imlist; tmp; tmp = tmp->next)
+-		if (v_addr < (unsigned long) tmp->addr + tmp->size)
+-			break;
+-
+-	if (tmp) {
+-		if (im_region_overlaps(v_addr, size, tmp))
+-			return IM_REGION_OVERLAP;
+-
+-		*vm = tmp;
+-		if (im_region_is_subset(v_addr, size, tmp)) {
+-			/* Return with tmp pointing to superset */
+-			return IM_REGION_SUBSET;
+-		}
+-		if (im_region_is_superset(v_addr, size, tmp)) {
+-			/* Return with tmp pointing to first subset */
+-			return IM_REGION_SUPERSET;
+-		}
+-		else if (v_addr == (unsigned long) tmp->addr &&
+-		 	 size == tmp->size) {
+-			/* Return with tmp pointing to exact region */
+-			return IM_REGION_EXISTS;
+-		}
+-	}
+-
+-	*vm = NULL;
+-	return IM_REGION_UNUSED;
+-}
+-
+-static struct vm_struct * split_im_region(unsigned long v_addr, 
+-		unsigned long size, struct vm_struct *parent)
+-{
+-	struct vm_struct *vm1 = NULL;
+-	struct vm_struct *vm2 = NULL;
+-	struct vm_struct *new_vm = NULL;
+-	
+-	vm1 = (struct vm_struct *) kmalloc(sizeof(*vm1), GFP_KERNEL);
+-	if (vm1	== NULL) {
+-		printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
+-		return NULL;
+-	}
+-
+-	if (v_addr == (unsigned long) parent->addr) {
+-	        /* Use existing parent vm_struct to represent child, allocate
+-		 * new one for the remainder of parent range
+-		 */
+-		vm1->size = parent->size - size;
+-		vm1->addr = (void *) (v_addr + size);
+-		vm1->next = parent->next;
+-
+-		parent->size = size;
+-		parent->next = vm1;
+-		new_vm = parent;
+-	} else if (v_addr + size == (unsigned long) parent->addr + 
+-			parent->size) {
+-		/* Allocate new vm_struct to represent child, use existing
+-		 * parent one for remainder of parent range
+-		 */
+-		vm1->size = size;
+-		vm1->addr = (void *) v_addr;
+-		vm1->next = parent->next;
+-		new_vm = vm1;
+-
+-		parent->size -= size;
+-		parent->next = vm1;
+-	} else {
+-	        /* Allocate two new vm_structs for the new child and 
+-		 * uppermost remainder, and use existing parent one for the
+-		 * lower remainder of parent range
+-		 */
+-		vm2 = (struct vm_struct *) kmalloc(sizeof(*vm2), GFP_KERNEL);
+-		if (vm2 == NULL) {
+-			printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
+-			kfree(vm1);
+-			return NULL;
+-		}
+-
+-		vm1->size = size;
+-		vm1->addr = (void *) v_addr;
+-		vm1->next = vm2;
+-		new_vm = vm1;
+-
+-		vm2->size = ((unsigned long) parent->addr + parent->size) - 
+-				(v_addr + size);
+-		vm2->addr = (void *) v_addr + size;
+-		vm2->next = parent->next;
+-
+-		parent->size = v_addr - (unsigned long) parent->addr;
+-		parent->next = vm1;
+-	}
+-
+-	return new_vm;
+-}
+-
+-static struct vm_struct * __add_new_im_area(unsigned long req_addr, 
+-					    unsigned long size)
+-{
+-	struct vm_struct **p, *tmp, *area;
+-		
+-	for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
+-		if (req_addr + size <= (unsigned long)tmp->addr)
+-			break;
+-	}
+-	
+-	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
+-	if (!area)
+-		return NULL;
+-	area->flags = 0;
+-	area->addr = (void *)req_addr;
+-	area->size = size;
+-	area->next = *p;
+-	*p = area;
+-
+-	return area;
+-}
+-
+-static struct vm_struct * __im_get_area(unsigned long req_addr, 
+-					unsigned long size,
+-					int criteria)
+-{
+-	struct vm_struct *tmp;
+-	int status;
+-
+-	status = im_region_status(req_addr, size, &tmp);
+-	if ((criteria & status) == 0) {
+-		return NULL;
+-	}
+-	
+-	switch (status) {
+-	case IM_REGION_UNUSED:
+-		tmp = __add_new_im_area(req_addr, size);
+-		break;
+-	case IM_REGION_SUBSET:
+-		tmp = split_im_region(req_addr, size, tmp);
+-		break;
+-	case IM_REGION_EXISTS:
+-		/* Return requested region */
+-		break;
+-	case IM_REGION_SUPERSET:
+-		/* Return first existing subset of requested region */
+-		break;
+-	default:
+-		printk(KERN_ERR "%s() unexpected imalloc region status\n",
+-				__FUNCTION__);
+-		tmp = NULL;
+-	}
+-
+-	return tmp;
+-}
+-
+-struct vm_struct * im_get_free_area(unsigned long size)
+-{
+-	struct vm_struct *area;
+-	unsigned long addr;
+-	
+-	down(&imlist_sem);
+-	if (get_free_im_addr(size, &addr)) {
+-		printk(KERN_ERR "%s() cannot obtain addr for size 0x%lx\n",
+-				__FUNCTION__, size);
+-		area = NULL;
+-		goto next_im_done;
+-	}
+-
+-	area = __im_get_area(addr, size, IM_REGION_UNUSED);
+-	if (area == NULL) {
+-		printk(KERN_ERR 
+-		       "%s() cannot obtain area for addr 0x%lx size 0x%lx\n",
+-			__FUNCTION__, addr, size);
+-	}
+-next_im_done:
+-	up(&imlist_sem);
+-	return area;
+-}
+-
+-struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
+-		int criteria)
+-{
+-	struct vm_struct *area;
+-
+-	down(&imlist_sem);
+-	area = __im_get_area(v_addr, size, criteria);
+-	up(&imlist_sem);
+-	return area;
+-}
+-
+-void im_free(void * addr)
+-{
+-	struct vm_struct **p, *tmp;
+-  
+-	if (!addr)
+-		return;
+-	if ((unsigned long) addr & ~PAGE_MASK) {
+-		printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__,			addr);
+-		return;
+-	}
+-	down(&imlist_sem);
+-	for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
+-		if (tmp->addr == addr) {
+-			*p = tmp->next;
+-
+-			/* XXX: do we need the lock? */
+-			spin_lock(&init_mm.page_table_lock);
+-			unmap_vm_area(tmp);
+-			spin_unlock(&init_mm.page_table_lock);
+-
+-			kfree(tmp);
+-			up(&imlist_sem);
+-			return;
+-		}
+-	}
+-	up(&imlist_sem);
+-	printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__,
+-			addr);
+-}
+diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/init.c
++++ /dev/null
+@@ -1,869 +0,0 @@
+-/*
+- *  PowerPC version 
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
+- *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
+- *    Copyright (C) 1996 Paul Mackerras
+- *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
+- *
+- *  Derived from "arch/i386/mm/init.c"
+- *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+- *
+- *  Dave Engebretsen <engebret at us.ibm.com>
+- *      Rework for PPC64 port.
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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/signal.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/errno.h>
+-#include <linux/string.h>
+-#include <linux/types.h>
+-#include <linux/mman.h>
+-#include <linux/mm.h>
+-#include <linux/swap.h>
+-#include <linux/stddef.h>
+-#include <linux/vmalloc.h>
+-#include <linux/init.h>
+-#include <linux/delay.h>
+-#include <linux/bootmem.h>
+-#include <linux/highmem.h>
+-#include <linux/idr.h>
+-#include <linux/nodemask.h>
+-#include <linux/module.h>
+-
+-#include <asm/pgalloc.h>
+-#include <asm/page.h>
+-#include <asm/prom.h>
+-#include <asm/lmb.h>
+-#include <asm/rtas.h>
+-#include <asm/io.h>
+-#include <asm/mmu_context.h>
+-#include <asm/pgtable.h>
+-#include <asm/mmu.h>
+-#include <asm/uaccess.h>
+-#include <asm/smp.h>
+-#include <asm/machdep.h>
+-#include <asm/tlb.h>
+-#include <asm/eeh.h>
+-#include <asm/processor.h>
+-#include <asm/mmzone.h>
+-#include <asm/cputable.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/sections.h>
+-#include <asm/system.h>
+-#include <asm/iommu.h>
+-#include <asm/abs_addr.h>
+-#include <asm/vdso.h>
+-#include <asm/imalloc.h>
+-
+-#if PGTABLE_RANGE > USER_VSID_RANGE
+-#warning Limited user VSID range means pagetable space is wasted
+-#endif
+-
+-#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE)
+-#warning TASK_SIZE is smaller than it needs to be.
+-#endif
+-
+-int mem_init_done;
+-unsigned long ioremap_bot = IMALLOC_BASE;
+-static unsigned long phbs_io_bot = PHBS_IO_BASE;
+-
+-extern pgd_t swapper_pg_dir[];
+-extern struct task_struct *current_set[NR_CPUS];
+-
+-unsigned long klimit = (unsigned long)_end;
+-
+-unsigned long _SDR1=0;
+-unsigned long _ASR=0;
+-
+-/* max amount of RAM to use */
+-unsigned long __max_memory;
+-
+-/* info on what we think the IO hole is */
+-unsigned long 	io_hole_start;
+-unsigned long	io_hole_size;
+-
+-void show_mem(void)
+-{
+-	unsigned long total = 0, reserved = 0;
+-	unsigned long shared = 0, cached = 0;
+-	struct page *page;
+-	pg_data_t *pgdat;
+-	unsigned long i;
+-
+-	printk("Mem-info:\n");
+-	show_free_areas();
+-	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+-	for_each_pgdat(pgdat) {
+-		for (i = 0; i < pgdat->node_spanned_pages; i++) {
+-			page = pgdat_page_nr(pgdat, i);
+-			total++;
+-			if (PageReserved(page))
+-				reserved++;
+-			else if (PageSwapCache(page))
+-				cached++;
+-			else if (page_count(page))
+-				shared += page_count(page) - 1;
+-		}
+-	}
+-	printk("%ld pages of RAM\n", total);
+-	printk("%ld reserved pages\n", reserved);
+-	printk("%ld pages shared\n", shared);
+-	printk("%ld pages swap cached\n", cached);
+-}
+-
+-#ifdef CONFIG_PPC_ISERIES
+-
+-void __iomem *ioremap(unsigned long addr, unsigned long size)
+-{
+-	return (void __iomem *)addr;
+-}
+-
+-extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
+-		       unsigned long flags)
+-{
+-	return (void __iomem *)addr;
+-}
+-
+-void iounmap(volatile void __iomem *addr)
+-{
+-	return;
+-}
+-
+-#else
+-
+-/*
+- * map_io_page currently only called by __ioremap
+- * map_io_page adds an entry to the ioremap page table
+- * and adds an entry to the HPT, possibly bolting it
+- */
+-static int map_io_page(unsigned long ea, unsigned long pa, int flags)
+-{
+-	pgd_t *pgdp;
+-	pud_t *pudp;
+-	pmd_t *pmdp;
+-	pte_t *ptep;
+-	unsigned long vsid;
+-
+-	if (mem_init_done) {
+-		spin_lock(&init_mm.page_table_lock);
+-		pgdp = pgd_offset_k(ea);
+-		pudp = pud_alloc(&init_mm, pgdp, ea);
+-		if (!pudp)
+-			return -ENOMEM;
+-		pmdp = pmd_alloc(&init_mm, pudp, ea);
+-		if (!pmdp)
+-			return -ENOMEM;
+-		ptep = pte_alloc_kernel(&init_mm, pmdp, ea);
+-		if (!ptep)
+-			return -ENOMEM;
+-		set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
+-							  __pgprot(flags)));
+-		spin_unlock(&init_mm.page_table_lock);
+-	} else {
+-		unsigned long va, vpn, hash, hpteg;
+-
+-		/*
+-		 * If the mm subsystem is not fully up, we cannot create a
+-		 * linux page table entry for this mapping.  Simply bolt an
+-		 * entry in the hardware page table.
+-		 */
+-		vsid = get_kernel_vsid(ea);
+-		va = (vsid << 28) | (ea & 0xFFFFFFF);
+-		vpn = va >> PAGE_SHIFT;
+-
+-		hash = hpt_hash(vpn, 0);
+-
+-		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
+-
+-		/* Panic if a pte grpup is full */
+-		if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT,
+-				       HPTE_V_BOLTED,
+-				       _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX)
+-		    == -1) {
+-			panic("map_io_page: could not insert mapping");
+-		}
+-	}
+-	return 0;
+-}
+-
+-
+-static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
+-			    unsigned long ea, unsigned long size,
+-			    unsigned long flags)
+-{
+-	unsigned long i;
+-
+-	if ((flags & _PAGE_PRESENT) == 0)
+-		flags |= pgprot_val(PAGE_KERNEL);
+-
+-	for (i = 0; i < size; i += PAGE_SIZE)
+-		if (map_io_page(ea+i, pa+i, flags))
+-			return NULL;
+-
+-	return (void __iomem *) (ea + (addr & ~PAGE_MASK));
+-}
+-
+-
+-void __iomem *
+-ioremap(unsigned long addr, unsigned long size)
+-{
+-	return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
+-}
+-
+-void __iomem * __ioremap(unsigned long addr, unsigned long size,
+-			 unsigned long flags)
+-{
+-	unsigned long pa, ea;
+-	void __iomem *ret;
+-
+-	/*
+-	 * Choose an address to map it to.
+-	 * Once the imalloc system is running, we use it.
+-	 * Before that, we map using addresses going
+-	 * up from ioremap_bot.  imalloc will use
+-	 * the addresses from ioremap_bot through
+-	 * IMALLOC_END
+-	 * 
+-	 */
+-	pa = addr & PAGE_MASK;
+-	size = PAGE_ALIGN(addr + size) - pa;
+-
+-	if (size == 0)
+-		return NULL;
+-
+-	if (mem_init_done) {
+-		struct vm_struct *area;
+-		area = im_get_free_area(size);
+-		if (area == NULL)
+-			return NULL;
+-		ea = (unsigned long)(area->addr);
+-		ret = __ioremap_com(addr, pa, ea, size, flags);
+-		if (!ret)
+-			im_free(area->addr);
+-	} else {
+-		ea = ioremap_bot;
+-		ret = __ioremap_com(addr, pa, ea, size, flags);
+-		if (ret)
+-			ioremap_bot += size;
+-	}
+-	return ret;
+-}
+-
+-#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
+-
+-int __ioremap_explicit(unsigned long pa, unsigned long ea,
+-		       unsigned long size, unsigned long flags)
+-{
+-	struct vm_struct *area;
+-	void __iomem *ret;
+-	
+-	/* For now, require page-aligned values for pa, ea, and size */
+-	if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
+-	    !IS_PAGE_ALIGNED(size)) {
+-		printk(KERN_ERR	"unaligned value in %s\n", __FUNCTION__);
+-		return 1;
+-	}
+-	
+-	if (!mem_init_done) {
+-		/* Two things to consider in this case:
+-		 * 1) No records will be kept (imalloc, etc) that the region
+-		 *    has been remapped
+-		 * 2) It won't be easy to iounmap() the region later (because
+-		 *    of 1)
+-		 */
+-		;
+-	} else {
+-		area = im_get_area(ea, size,
+-			IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS);
+-		if (area == NULL) {
+-			/* Expected when PHB-dlpar is in play */
+-			return 1;
+-		}
+-		if (ea != (unsigned long) area->addr) {
+-			printk(KERN_ERR "unexpected addr return from "
+-			       "im_get_area\n");
+-			return 1;
+-		}
+-	}
+-	
+-	ret = __ioremap_com(pa, pa, ea, size, flags);
+-	if (ret == NULL) {
+-		printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
+-		return 1;
+-	}
+-	if (ret != (void *) ea) {
+-		printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
+-		return 1;
+-	}
+-
+-	return 0;
+-}
+-
+-/*  
+- * Unmap an IO region and remove it from imalloc'd list.
+- * Access to IO memory should be serialized by driver.
+- * This code is modeled after vmalloc code - unmap_vm_area()
+- *
+- * XXX	what about calls before mem_init_done (ie python_countermeasures())
+- */
+-void iounmap(volatile void __iomem *token)
+-{
+-	void *addr;
+-
+-	if (!mem_init_done)
+-		return;
+-	
+-	addr = (void *) ((unsigned long __force) token & PAGE_MASK);
+-
+-	im_free(addr);
+-}
+-
+-static int iounmap_subset_regions(unsigned long addr, unsigned long size)
+-{
+-	struct vm_struct *area;
+-
+-	/* Check whether subsets of this region exist */
+-	area = im_get_area(addr, size, IM_REGION_SUPERSET);
+-	if (area == NULL)
+-		return 1;
+-
+-	while (area) {
+-		iounmap((void __iomem *) area->addr);
+-		area = im_get_area(addr, size,
+-				IM_REGION_SUPERSET);
+-	}
+-
+-	return 0;
+-}
+-
+-int iounmap_explicit(volatile void __iomem *start, unsigned long size)
+-{
+-	struct vm_struct *area;
+-	unsigned long addr;
+-	int rc;
+-	
+-	addr = (unsigned long __force) start & PAGE_MASK;
+-
+-	/* Verify that the region either exists or is a subset of an existing
+-	 * region.  In the latter case, split the parent region to create 
+-	 * the exact region 
+-	 */
+-	area = im_get_area(addr, size, 
+-			    IM_REGION_EXISTS | IM_REGION_SUBSET);
+-	if (area == NULL) {
+-		/* Determine whether subset regions exist.  If so, unmap */
+-		rc = iounmap_subset_regions(addr, size);
+-		if (rc) {
+-			printk(KERN_ERR
+-			       "%s() cannot unmap nonexistent range 0x%lx\n",
+- 				__FUNCTION__, addr);
+-			return 1;
+-		}
+-	} else {
+-		iounmap((void __iomem *) area->addr);
+-	}
+-	/*
+-	 * FIXME! This can't be right:
+-	iounmap(area->addr);
+-	 * Maybe it should be "iounmap(area);"
+-	 */
+-	return 0;
+-}
+-
+-#endif
+-
+-EXPORT_SYMBOL(ioremap);
+-EXPORT_SYMBOL(__ioremap);
+-EXPORT_SYMBOL(iounmap);
+-
+-void free_initmem(void)
+-{
+-	unsigned long addr;
+-
+-	addr = (unsigned long)__init_begin;
+-	for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
+-		memset((void *)addr, 0xcc, PAGE_SIZE);
+-		ClearPageReserved(virt_to_page(addr));
+-		set_page_count(virt_to_page(addr), 1);
+-		free_page(addr);
+-		totalram_pages++;
+-	}
+-	printk ("Freeing unused kernel memory: %luk freed\n",
+-		((unsigned long)__init_end - (unsigned long)__init_begin) >> 10);
+-}
+-
+-#ifdef CONFIG_BLK_DEV_INITRD
+-void free_initrd_mem(unsigned long start, unsigned long end)
+-{
+-	if (start < end)
+-		printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+-	for (; start < end; start += PAGE_SIZE) {
+-		ClearPageReserved(virt_to_page(start));
+-		set_page_count(virt_to_page(start), 1);
+-		free_page(start);
+-		totalram_pages++;
+-	}
+-}
+-#endif
+-
+-static DEFINE_SPINLOCK(mmu_context_lock);
+-static DEFINE_IDR(mmu_context_idr);
+-
+-int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+-{
+-	int index;
+-	int err;
+-
+-again:
+-	if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL))
+-		return -ENOMEM;
+-
+-	spin_lock(&mmu_context_lock);
+-	err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index);
+-	spin_unlock(&mmu_context_lock);
+-
+-	if (err == -EAGAIN)
+-		goto again;
+-	else if (err)
+-		return err;
+-
+-	if (index > MAX_CONTEXT) {
+-		idr_remove(&mmu_context_idr, index);
+-		return -ENOMEM;
+-	}
+-
+-	mm->context.id = index;
+-
+-	return 0;
+-}
+-
+-void destroy_context(struct mm_struct *mm)
+-{
+-	spin_lock(&mmu_context_lock);
+-	idr_remove(&mmu_context_idr, mm->context.id);
+-	spin_unlock(&mmu_context_lock);
+-
+-	mm->context.id = NO_CONTEXT;
+-}
+-
+-/*
+- * Do very early mm setup.
+- */
+-void __init mm_init_ppc64(void)
+-{
+-#ifndef CONFIG_PPC_ISERIES
+-	unsigned long i;
+-#endif
+-
+-	ppc64_boot_msg(0x100, "MM Init");
+-
+-	/* This is the story of the IO hole... please, keep seated,
+-	 * unfortunately, we are out of oxygen masks at the moment.
+-	 * So we need some rough way to tell where your big IO hole
+-	 * is. On pmac, it's between 2G and 4G, on POWER3, it's around
+-	 * that area as well, on POWER4 we don't have one, etc...
+-	 * We need that as a "hint" when sizing the TCE table on POWER3
+-	 * So far, the simplest way that seem work well enough for us it
+-	 * to just assume that the first discontinuity in our physical
+-	 * RAM layout is the IO hole. That may not be correct in the future
+-	 * (and isn't on iSeries but then we don't care ;)
+-	 */
+-
+-#ifndef CONFIG_PPC_ISERIES
+-	for (i = 1; i < lmb.memory.cnt; i++) {
+-		unsigned long base, prevbase, prevsize;
+-
+-		prevbase = lmb.memory.region[i-1].base;
+-		prevsize = lmb.memory.region[i-1].size;
+-		base = lmb.memory.region[i].base;
+-		if (base > (prevbase + prevsize)) {
+-			io_hole_start = prevbase + prevsize;
+-			io_hole_size = base  - (prevbase + prevsize);
+-			break;
+-		}
+-	}
+-#endif /* CONFIG_PPC_ISERIES */
+-	if (io_hole_start)
+-		printk("IO Hole assumed to be %lx -> %lx\n",
+-		       io_hole_start, io_hole_start + io_hole_size - 1);
+-
+-	ppc64_boot_msg(0x100, "MM Init Done");
+-}
+-
+-/*
+- * This is called by /dev/mem to know if a given address has to
+- * be mapped non-cacheable or not
+- */
+-int page_is_ram(unsigned long pfn)
+-{
+-	int i;
+-	unsigned long paddr = (pfn << PAGE_SHIFT);
+-
+-	for (i=0; i < lmb.memory.cnt; i++) {
+-		unsigned long base;
+-
+-		base = lmb.memory.region[i].base;
+-
+-		if ((paddr >= base) &&
+-			(paddr < (base + lmb.memory.region[i].size))) {
+-			return 1;
+-		}
+-	}
+-
+-	return 0;
+-}
+-EXPORT_SYMBOL(page_is_ram);
+-
+-/*
+- * Initialize the bootmem system and give it all the memory we
+- * have available.
+- */
+-#ifndef CONFIG_NEED_MULTIPLE_NODES
+-void __init do_init_bootmem(void)
+-{
+-	unsigned long i;
+-	unsigned long start, bootmap_pages;
+-	unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
+-	int boot_mapsize;
+-
+-	/*
+-	 * Find an area to use for the bootmem bitmap.  Calculate the size of
+-	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
+-	 * Add 1 additional page in case the address isn't page-aligned.
+-	 */
+-	bootmap_pages = bootmem_bootmap_pages(total_pages);
+-
+-	start = lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE);
+-	BUG_ON(!start);
+-
+-	boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
+-
+-	max_pfn = max_low_pfn;
+-
+-	/* Add all physical memory to the bootmem map, mark each area
+-	 * present.
+-	 */
+-	for (i=0; i < lmb.memory.cnt; i++)
+-		free_bootmem(lmb.memory.region[i].base,
+-			     lmb_size_bytes(&lmb.memory, i));
+-
+-	/* reserve the sections we're already using */
+-	for (i=0; i < lmb.reserved.cnt; i++)
+-		reserve_bootmem(lmb.reserved.region[i].base,
+-				lmb_size_bytes(&lmb.reserved, i));
+-
+-	for (i=0; i < lmb.memory.cnt; i++)
+-		memory_present(0, lmb_start_pfn(&lmb.memory, i),
+-			       lmb_end_pfn(&lmb.memory, i));
+-}
+-
+-/*
+- * paging_init() sets up the page tables - in fact we've already done this.
+- */
+-void __init paging_init(void)
+-{
+-	unsigned long zones_size[MAX_NR_ZONES];
+-	unsigned long zholes_size[MAX_NR_ZONES];
+-	unsigned long total_ram = lmb_phys_mem_size();
+-	unsigned long top_of_ram = lmb_end_of_DRAM();
+-
+-	printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
+-	       top_of_ram, total_ram);
+-	printk(KERN_INFO "Memory hole size: %ldMB\n",
+-	       (top_of_ram - total_ram) >> 20);
+-	/*
+-	 * All pages are DMA-able so we put them all in the DMA zone.
+-	 */
+-	memset(zones_size, 0, sizeof(zones_size));
+-	memset(zholes_size, 0, sizeof(zholes_size));
+-
+-	zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
+-	zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
+-
+-	free_area_init_node(0, NODE_DATA(0), zones_size,
+-			    __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
+-}
+-#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
+-
+-static struct kcore_list kcore_vmem;
+-
+-static int __init setup_kcore(void)
+-{
+-	int i;
+-
+-	for (i=0; i < lmb.memory.cnt; i++) {
+-		unsigned long base, size;
+-		struct kcore_list *kcore_mem;
+-
+-		base = lmb.memory.region[i].base;
+-		size = lmb.memory.region[i].size;
+-
+-		/* GFP_ATOMIC to avoid might_sleep warnings during boot */
+-		kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
+-		if (!kcore_mem)
+-			panic("mem_init: kmalloc failed\n");
+-
+-		kclist_add(kcore_mem, __va(base), size);
+-	}
+-
+-	kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
+-
+-	return 0;
+-}
+-module_init(setup_kcore);
+-
+-void __init mem_init(void)
+-{
+-#ifdef CONFIG_NEED_MULTIPLE_NODES
+-	int nid;
+-#endif
+-	pg_data_t *pgdat;
+-	unsigned long i;
+-	struct page *page;
+-	unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
+-
+-	num_physpages = max_low_pfn;	/* RAM is assumed contiguous */
+-	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+-
+-#ifdef CONFIG_NEED_MULTIPLE_NODES
+-        for_each_online_node(nid) {
+-		if (NODE_DATA(nid)->node_spanned_pages != 0) {
+-			printk("freeing bootmem node %x\n", nid);
+-			totalram_pages +=
+-				free_all_bootmem_node(NODE_DATA(nid));
+-		}
+-	}
+-#else
+-	max_mapnr = num_physpages;
+-	totalram_pages += free_all_bootmem();
+-#endif
+-
+-	for_each_pgdat(pgdat) {
+-		for (i = 0; i < pgdat->node_spanned_pages; i++) {
+-			page = pgdat_page_nr(pgdat, i);
+-			if (PageReserved(page))
+-				reservedpages++;
+-		}
+-	}
+-
+-	codesize = (unsigned long)&_etext - (unsigned long)&_stext;
+-	initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
+-	datasize = (unsigned long)&_edata - (unsigned long)&__init_end;
+-	bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
+-
+-	printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, "
+-	       "%luk reserved, %luk data, %luk bss, %luk init)\n",
+-		(unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
+-		num_physpages << (PAGE_SHIFT-10),
+-		codesize >> 10,
+-		reservedpages << (PAGE_SHIFT-10),
+-		datasize >> 10,
+-		bsssize >> 10,
+-		initsize >> 10);
+-
+-	mem_init_done = 1;
+-
+-	/* Initialize the vDSO */
+-	vdso_init();
+-}
+-
+-/*
+- * This is called when a page has been modified by the kernel.
+- * It just marks the page as not i-cache clean.  We do the i-cache
+- * flush later when the page is given to a user process, if necessary.
+- */
+-void flush_dcache_page(struct page *page)
+-{
+-	if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+-		return;
+-	/* avoid an atomic op if possible */
+-	if (test_bit(PG_arch_1, &page->flags))
+-		clear_bit(PG_arch_1, &page->flags);
+-}
+-EXPORT_SYMBOL(flush_dcache_page);
+-
+-void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
+-{
+-	clear_page(page);
+-
+-	if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+-		return;
+-	/*
+-	 * We shouldnt have to do this, but some versions of glibc
+-	 * require it (ld.so assumes zero filled pages are icache clean)
+-	 * - Anton
+-	 */
+-
+-	/* avoid an atomic op if possible */
+-	if (test_bit(PG_arch_1, &pg->flags))
+-		clear_bit(PG_arch_1, &pg->flags);
+-}
+-EXPORT_SYMBOL(clear_user_page);
+-
+-void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+-		    struct page *pg)
+-{
+-	copy_page(vto, vfrom);
+-
+-	/*
+-	 * We should be able to use the following optimisation, however
+-	 * there are two problems.
+-	 * Firstly a bug in some versions of binutils meant PLT sections
+-	 * were not marked executable.
+-	 * Secondly the first word in the GOT section is blrl, used
+-	 * to establish the GOT address. Until recently the GOT was
+-	 * not marked executable.
+-	 * - Anton
+-	 */
+-#if 0
+-	if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0))
+-		return;
+-#endif
+-
+-	if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+-		return;
+-
+-	/* avoid an atomic op if possible */
+-	if (test_bit(PG_arch_1, &pg->flags))
+-		clear_bit(PG_arch_1, &pg->flags);
+-}
+-
+-void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+-			     unsigned long addr, int len)
+-{
+-	unsigned long maddr;
+-
+-	maddr = (unsigned long)page_address(page) + (addr & ~PAGE_MASK);
+-	flush_icache_range(maddr, maddr + len);
+-}
+-EXPORT_SYMBOL(flush_icache_user_range);
+-
+-/*
+- * This is called at the end of handling a user page fault, when the
+- * fault has been handled by updating a PTE in the linux page tables.
+- * We use it to preload an HPTE into the hash table corresponding to
+- * the updated linux PTE.
+- * 
+- * This must always be called with the mm->page_table_lock held
+- */
+-void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea,
+-		      pte_t pte)
+-{
+-	unsigned long vsid;
+-	void *pgdir;
+-	pte_t *ptep;
+-	int local = 0;
+-	cpumask_t tmp;
+-	unsigned long flags;
+-
+-	/* handle i-cache coherency */
+-	if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
+-	    !cpu_has_feature(CPU_FTR_NOEXECUTE)) {
+-		unsigned long pfn = pte_pfn(pte);
+-		if (pfn_valid(pfn)) {
+-			struct page *page = pfn_to_page(pfn);
+-			if (!PageReserved(page)
+-			    && !test_bit(PG_arch_1, &page->flags)) {
+-				__flush_dcache_icache(page_address(page));
+-				set_bit(PG_arch_1, &page->flags);
+-			}
+-		}
+-	}
+-
+-	/* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
+-	if (!pte_young(pte))
+-		return;
+-
+-	pgdir = vma->vm_mm->pgd;
+-	if (pgdir == NULL)
+-		return;
+-
+-	ptep = find_linux_pte(pgdir, ea);
+-	if (!ptep)
+-		return;
+-
+-	vsid = get_vsid(vma->vm_mm->context.id, ea);
+-
+-	local_irq_save(flags);
+-	tmp = cpumask_of_cpu(smp_processor_id());
+-	if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
+-		local = 1;
+-
+-	__hash_page(ea, 0, vsid, ptep, 0x300, local);
+-	local_irq_restore(flags);
+-}
+-
+-void __iomem * reserve_phb_iospace(unsigned long size)
+-{
+-	void __iomem *virt_addr;
+-		
+-	if (phbs_io_bot >= IMALLOC_BASE) 
+-		panic("reserve_phb_iospace(): phb io space overflow\n");
+-			
+-	virt_addr = (void __iomem *) phbs_io_bot;
+-	phbs_io_bot += size;
+-
+-	return virt_addr;
+-}
+-
+-static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
+-{
+-	memset(addr, 0, kmem_cache_size(cache));
+-}
+-
+-static const int pgtable_cache_size[2] = {
+-	PTE_TABLE_SIZE, PMD_TABLE_SIZE
+-};
+-static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
+-	"pgd_pte_cache", "pud_pmd_cache",
+-};
+-
+-kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
+-
+-void pgtable_cache_init(void)
+-{
+-	int i;
+-
+-	BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]);
+-	BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]);
+-	BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]);
+-	BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]);
+-
+-	for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) {
+-		int size = pgtable_cache_size[i];
+-		const char *name = pgtable_cache_name[i];
+-
+-		pgtable_cache[i] = kmem_cache_create(name,
+-						     size, size,
+-						     SLAB_HWCACHE_ALIGN
+-						     | SLAB_MUST_HWCACHE_ALIGN,
+-						     zero_ctor,
+-						     NULL);
+-		if (! pgtable_cache[i])
+-			panic("pgtable_cache_init(): could not create %s!\n",
+-			      name);
+-	}
+-}
+-
+-pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
+-			      unsigned long size, pgprot_t vma_prot)
+-{
+-	if (ppc_md.phys_mem_access_prot)
+-		return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot);
+-
+-	if (!page_is_ram(addr >> PAGE_SHIFT))
+-		vma_prot = __pgprot(pgprot_val(vma_prot)
+-				    | _PAGE_GUARDED | _PAGE_NO_CACHE);
+-	return vma_prot;
+-}
+-EXPORT_SYMBOL(phys_mem_access_prot);
+diff --git a/arch/ppc64/mm/mmap.c b/arch/ppc64/mm/mmap.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/mmap.c
++++ /dev/null
+@@ -1,86 +0,0 @@
+-/*
+- *  linux/arch/ppc64/mm/mmap.c
+- *
+- *  flexible mmap layout support
+- *
+- * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+- * 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
+- *
+- *
+- * Started by Ingo Molnar <mingo at elte.hu>
+- */
+-
+-#include <linux/personality.h>
+-#include <linux/mm.h>
+-
+-/*
+- * Top of mmap area (just below the process stack).
+- *
+- * Leave an at least ~128 MB hole.
+- */
+-#define MIN_GAP (128*1024*1024)
+-#define MAX_GAP (TASK_SIZE/6*5)
+-
+-static inline unsigned long mmap_base(void)
+-{
+-	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+-
+-	if (gap < MIN_GAP)
+-		gap = MIN_GAP;
+-	else if (gap > MAX_GAP)
+-		gap = MAX_GAP;
+-
+-	return TASK_SIZE - (gap & PAGE_MASK);
+-}
+-
+-static inline int mmap_is_legacy(void)
+-{
+-	/*
+-	 * Force standard allocation for 64 bit programs.
+-	 */
+-	if (!test_thread_flag(TIF_32BIT))
+-		return 1;
+-
+-	if (current->personality & ADDR_COMPAT_LAYOUT)
+-		return 1;
+-
+-	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+-		return 1;
+-
+-	return sysctl_legacy_va_layout;
+-}
+-
+-/*
+- * This function, called very early during the creation of a new
+- * process VM image, sets up which VM layout function to use:
+- */
+-void arch_pick_mmap_layout(struct mm_struct *mm)
+-{
+-	/*
+-	 * Fall back to the standard layout if the personality
+-	 * bit is set, or if the expected stack growth is unlimited:
+-	 */
+-	if (mmap_is_legacy()) {
+-		mm->mmap_base = TASK_UNMAPPED_BASE;
+-		mm->get_unmapped_area = arch_get_unmapped_area;
+-		mm->unmap_area = arch_unmap_area;
+-	} else {
+-		mm->mmap_base = mmap_base();
+-		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+-		mm->unmap_area = arch_unmap_area_topdown;
+-	}
+-}
+diff --git a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/numa.c
++++ /dev/null
+@@ -1,779 +0,0 @@
+-/*
+- * pSeries NUMA support
+- *
+- * Copyright (C) 2002 Anton Blanchard <anton at au.ibm.com>, 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/threads.h>
+-#include <linux/bootmem.h>
+-#include <linux/init.h>
+-#include <linux/mm.h>
+-#include <linux/mmzone.h>
+-#include <linux/module.h>
+-#include <linux/nodemask.h>
+-#include <linux/cpu.h>
+-#include <linux/notifier.h>
+-#include <asm/lmb.h>
+-#include <asm/machdep.h>
+-#include <asm/abs_addr.h>
+-
+-static int numa_enabled = 1;
+-
+-static int numa_debug;
+-#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); }
+-
+-#ifdef DEBUG_NUMA
+-#define ARRAY_INITIALISER -1
+-#else
+-#define ARRAY_INITIALISER 0
+-#endif
+-
+-int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] =
+-	ARRAY_INITIALISER};
+-char *numa_memory_lookup_table;
+-cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
+-int nr_cpus_in_node[MAX_NUMNODES] = { [0 ... (MAX_NUMNODES -1)] = 0};
+-
+-struct pglist_data *node_data[MAX_NUMNODES];
+-bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
+-static int min_common_depth;
+-
+-/*
+- * We need somewhere to store start/span for each node until we have
+- * allocated the real node_data structures.
+- */
+-static struct {
+-	unsigned long node_start_pfn;
+-	unsigned long node_end_pfn;
+-	unsigned long node_present_pages;
+-} init_node_data[MAX_NUMNODES] __initdata;
+-
+-EXPORT_SYMBOL(node_data);
+-EXPORT_SYMBOL(numa_cpu_lookup_table);
+-EXPORT_SYMBOL(numa_memory_lookup_table);
+-EXPORT_SYMBOL(numa_cpumask_lookup_table);
+-EXPORT_SYMBOL(nr_cpus_in_node);
+-
+-static inline void map_cpu_to_node(int cpu, int node)
+-{
+-	numa_cpu_lookup_table[cpu] = node;
+-	if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node]))) {
+-		cpu_set(cpu, numa_cpumask_lookup_table[node]);
+-		nr_cpus_in_node[node]++;
+-	}
+-}
+-
+-#ifdef CONFIG_HOTPLUG_CPU
+-static void unmap_cpu_from_node(unsigned long cpu)
+-{
+-	int node = numa_cpu_lookup_table[cpu];
+-
+-	dbg("removing cpu %lu from node %d\n", cpu, node);
+-
+-	if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) {
+-		cpu_clear(cpu, numa_cpumask_lookup_table[node]);
+-		nr_cpus_in_node[node]--;
+-	} else {
+-		printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n",
+-		       cpu, node);
+-	}
+-}
+-#endif /* CONFIG_HOTPLUG_CPU */
+-
+-static struct device_node * __devinit find_cpu_node(unsigned int cpu)
+-{
+-	unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
+-	struct device_node *cpu_node = NULL;
+-	unsigned int *interrupt_server, *reg;
+-	int len;
+-
+-	while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
+-		/* Try interrupt server first */
+-		interrupt_server = (unsigned int *)get_property(cpu_node,
+-					"ibm,ppc-interrupt-server#s", &len);
+-
+-		len = len / sizeof(u32);
+-
+-		if (interrupt_server && (len > 0)) {
+-			while (len--) {
+-				if (interrupt_server[len] == hw_cpuid)
+-					return cpu_node;
+-			}
+-		} else {
+-			reg = (unsigned int *)get_property(cpu_node,
+-							   "reg", &len);
+-			if (reg && (len > 0) && (reg[0] == hw_cpuid))
+-				return cpu_node;
+-		}
+-	}
+-
+-	return NULL;
+-}
+-
+-/* must hold reference to node during call */
+-static int *of_get_associativity(struct device_node *dev)
+-{
+-	return (unsigned int *)get_property(dev, "ibm,associativity", NULL);
+-}
+-
+-static int of_node_numa_domain(struct device_node *device)
+-{
+-	int numa_domain;
+-	unsigned int *tmp;
+-
+-	if (min_common_depth == -1)
+-		return 0;
+-
+-	tmp = of_get_associativity(device);
+-	if (tmp && (tmp[0] >= min_common_depth)) {
+-		numa_domain = tmp[min_common_depth];
+-	} else {
+-		dbg("WARNING: no NUMA information for %s\n",
+-		    device->full_name);
+-		numa_domain = 0;
+-	}
+-	return numa_domain;
+-}
+-
+-/*
+- * In theory, the "ibm,associativity" property may contain multiple
+- * associativity lists because a resource may be multiply connected
+- * into the machine.  This resource then has different associativity
+- * characteristics relative to its multiple connections.  We ignore
+- * this for now.  We also assume that all cpu and memory sets have
+- * their distances represented at a common level.  This won't be
+- * true for heirarchical NUMA.
+- *
+- * In any case the ibm,associativity-reference-points should give
+- * the correct depth for a normal NUMA system.
+- *
+- * - Dave Hansen <haveblue at us.ibm.com>
+- */
+-static int __init find_min_common_depth(void)
+-{
+-	int depth;
+-	unsigned int *ref_points;
+-	struct device_node *rtas_root;
+-	unsigned int len;
+-
+-	rtas_root = of_find_node_by_path("/rtas");
+-
+-	if (!rtas_root)
+-		return -1;
+-
+-	/*
+-	 * this property is 2 32-bit integers, each representing a level of
+-	 * depth in the associativity nodes.  The first is for an SMP
+-	 * configuration (should be all 0's) and the second is for a normal
+-	 * NUMA configuration.
+-	 */
+-	ref_points = (unsigned int *)get_property(rtas_root,
+-			"ibm,associativity-reference-points", &len);
+-
+-	if ((len >= 1) && ref_points) {
+-		depth = ref_points[1];
+-	} else {
+-		dbg("WARNING: could not find NUMA "
+-		    "associativity reference point\n");
+-		depth = -1;
+-	}
+-	of_node_put(rtas_root);
+-
+-	return depth;
+-}
+-
+-static int __init get_mem_addr_cells(void)
+-{
+-	struct device_node *memory = NULL;
+-	int rc;
+-
+-	memory = of_find_node_by_type(memory, "memory");
+-	if (!memory)
+-		return 0; /* it won't matter */
+-
+-	rc = prom_n_addr_cells(memory);
+-	return rc;
+-}
+-
+-static int __init get_mem_size_cells(void)
+-{
+-	struct device_node *memory = NULL;
+-	int rc;
+-
+-	memory = of_find_node_by_type(memory, "memory");
+-	if (!memory)
+-		return 0; /* it won't matter */
+-	rc = prom_n_size_cells(memory);
+-	return rc;
+-}
+-
+-static unsigned long read_n_cells(int n, unsigned int **buf)
+-{
+-	unsigned long result = 0;
+-
+-	while (n--) {
+-		result = (result << 32) | **buf;
+-		(*buf)++;
+-	}
+-	return result;
+-}
+-
+-/*
+- * Figure out to which domain a cpu belongs and stick it there.
+- * Return the id of the domain used.
+- */
+-static int numa_setup_cpu(unsigned long lcpu)
+-{
+-	int numa_domain = 0;
+-	struct device_node *cpu = find_cpu_node(lcpu);
+-
+-	if (!cpu) {
+-		WARN_ON(1);
+-		goto out;
+-	}
+-
+-	numa_domain = of_node_numa_domain(cpu);
+-
+-	if (numa_domain >= num_online_nodes()) {
+-		/*
+-		 * POWER4 LPAR uses 0xffff as invalid node,
+-		 * dont warn in this case.
+-		 */
+-		if (numa_domain != 0xffff)
+-			printk(KERN_ERR "WARNING: cpu %ld "
+-			       "maps to invalid NUMA node %d\n",
+-			       lcpu, numa_domain);
+-		numa_domain = 0;
+-	}
+-out:
+-	node_set_online(numa_domain);
+-
+-	map_cpu_to_node(lcpu, numa_domain);
+-
+-	of_node_put(cpu);
+-
+-	return numa_domain;
+-}
+-
+-static int cpu_numa_callback(struct notifier_block *nfb,
+-			     unsigned long action,
+-			     void *hcpu)
+-{
+-	unsigned long lcpu = (unsigned long)hcpu;
+-	int ret = NOTIFY_DONE;
+-
+-	switch (action) {
+-	case CPU_UP_PREPARE:
+-		if (min_common_depth == -1 || !numa_enabled)
+-			map_cpu_to_node(lcpu, 0);
+-		else
+-			numa_setup_cpu(lcpu);
+-		ret = NOTIFY_OK;
+-		break;
+-#ifdef CONFIG_HOTPLUG_CPU
+-	case CPU_DEAD:
+-	case CPU_UP_CANCELED:
+-		unmap_cpu_from_node(lcpu);
+-		break;
+-		ret = NOTIFY_OK;
+-#endif
+-	}
+-	return ret;
+-}
+-
+-/*
+- * Check and possibly modify a memory region to enforce the memory limit.
+- *
+- * Returns the size the region should have to enforce the memory limit.
+- * This will either be the original value of size, a truncated value,
+- * or zero. If the returned value of size is 0 the region should be
+- * discarded as it lies wholy above the memory limit.
+- */
+-static unsigned long __init numa_enforce_memory_limit(unsigned long start, unsigned long size)
+-{
+-	/*
+-	 * We use lmb_end_of_DRAM() in here instead of memory_limit because
+-	 * we've already adjusted it for the limit and it takes care of
+-	 * having memory holes below the limit.
+-	 */
+-	extern unsigned long memory_limit;
+-
+-	if (! memory_limit)
+-		return size;
+-
+-	if (start + size <= lmb_end_of_DRAM())
+-		return size;
+-
+-	if (start >= lmb_end_of_DRAM())
+-		return 0;
+-
+-	return lmb_end_of_DRAM() - start;
+-}
+-
+-static int __init parse_numa_properties(void)
+-{
+-	struct device_node *cpu = NULL;
+-	struct device_node *memory = NULL;
+-	int addr_cells, size_cells;
+-	int max_domain = 0;
+-	long entries = lmb_end_of_DRAM() >> MEMORY_INCREMENT_SHIFT;
+-	unsigned long i;
+-
+-	if (numa_enabled == 0) {
+-		printk(KERN_WARNING "NUMA disabled by user\n");
+-		return -1;
+-	}
+-
+-	numa_memory_lookup_table =
+-		(char *)abs_to_virt(lmb_alloc(entries * sizeof(char), 1));
+-	memset(numa_memory_lookup_table, 0, entries * sizeof(char));
+-
+-	for (i = 0; i < entries ; i++)
+-		numa_memory_lookup_table[i] = ARRAY_INITIALISER;
+-
+-	min_common_depth = find_min_common_depth();
+-
+-	dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
+-	if (min_common_depth < 0)
+-		return min_common_depth;
+-
+-	max_domain = numa_setup_cpu(boot_cpuid);
+-
+-	/*
+-	 * Even though we connect cpus to numa domains later in SMP init,
+-	 * we need to know the maximum node id now. This is because each
+-	 * node id must have NODE_DATA etc backing it.
+-	 * As a result of hotplug we could still have cpus appear later on
+-	 * with larger node ids. In that case we force the cpu into node 0.
+-	 */
+-	for_each_cpu(i) {
+-		int numa_domain;
+-
+-		cpu = find_cpu_node(i);
+-
+-		if (cpu) {
+-			numa_domain = of_node_numa_domain(cpu);
+-			of_node_put(cpu);
+-
+-			if (numa_domain < MAX_NUMNODES &&
+-			    max_domain < numa_domain)
+-				max_domain = numa_domain;
+-		}
+-	}
+-
+-	addr_cells = get_mem_addr_cells();
+-	size_cells = get_mem_size_cells();
+-	memory = NULL;
+-	while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+-		unsigned long start;
+-		unsigned long size;
+-		int numa_domain;
+-		int ranges;
+-		unsigned int *memcell_buf;
+-		unsigned int len;
+-
+-		memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
+-		if (!memcell_buf || len <= 0)
+-			continue;
+-
+-		ranges = memory->n_addrs;
+-new_range:
+-		/* these are order-sensitive, and modify the buffer pointer */
+-		start = read_n_cells(addr_cells, &memcell_buf);
+-		size = read_n_cells(size_cells, &memcell_buf);
+-
+-		start = _ALIGN_DOWN(start, MEMORY_INCREMENT);
+-		size = _ALIGN_UP(size, MEMORY_INCREMENT);
+-
+-		numa_domain = of_node_numa_domain(memory);
+-
+-		if (numa_domain >= MAX_NUMNODES) {
+-			if (numa_domain != 0xffff)
+-				printk(KERN_ERR "WARNING: memory at %lx maps "
+-				       "to invalid NUMA node %d\n", start,
+-				       numa_domain);
+-			numa_domain = 0;
+-		}
+-
+-		if (max_domain < numa_domain)
+-			max_domain = numa_domain;
+-
+-		if (! (size = numa_enforce_memory_limit(start, size))) {
+-			if (--ranges)
+-				goto new_range;
+-			else
+-				continue;
+-		}
+-
+-		/*
+-		 * Initialize new node struct, or add to an existing one.
+-		 */
+-		if (init_node_data[numa_domain].node_end_pfn) {
+-			if ((start / PAGE_SIZE) <
+-			    init_node_data[numa_domain].node_start_pfn)
+-				init_node_data[numa_domain].node_start_pfn =
+-					start / PAGE_SIZE;
+-			if (((start / PAGE_SIZE) + (size / PAGE_SIZE)) >
+-			    init_node_data[numa_domain].node_end_pfn)
+-				init_node_data[numa_domain].node_end_pfn =
+-					(start / PAGE_SIZE) +
+-					(size / PAGE_SIZE);
+-
+-			init_node_data[numa_domain].node_present_pages +=
+-				size / PAGE_SIZE;
+-		} else {
+-			node_set_online(numa_domain);
+-
+-			init_node_data[numa_domain].node_start_pfn =
+-				start / PAGE_SIZE;
+-			init_node_data[numa_domain].node_end_pfn =
+-				init_node_data[numa_domain].node_start_pfn +
+-				size / PAGE_SIZE;
+-			init_node_data[numa_domain].node_present_pages =
+-				size / PAGE_SIZE;
+-		}
+-
+-		for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
+-			numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
+-				numa_domain;
+-
+-		if (--ranges)
+-			goto new_range;
+-	}
+-
+-	for (i = 0; i <= max_domain; i++)
+-		node_set_online(i);
+-
+-	return 0;
+-}
+-
+-static void __init setup_nonnuma(void)
+-{
+-	unsigned long top_of_ram = lmb_end_of_DRAM();
+-	unsigned long total_ram = lmb_phys_mem_size();
+-	unsigned long i;
+-
+-	printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
+-	       top_of_ram, total_ram);
+-	printk(KERN_INFO "Memory hole size: %ldMB\n",
+-	       (top_of_ram - total_ram) >> 20);
+-
+-	if (!numa_memory_lookup_table) {
+-		long entries = top_of_ram >> MEMORY_INCREMENT_SHIFT;
+-		numa_memory_lookup_table =
+-			(char *)abs_to_virt(lmb_alloc(entries * sizeof(char), 1));
+-		memset(numa_memory_lookup_table, 0, entries * sizeof(char));
+-		for (i = 0; i < entries ; i++)
+-			numa_memory_lookup_table[i] = ARRAY_INITIALISER;
+-	}
+-
+-	map_cpu_to_node(boot_cpuid, 0);
+-
+-	node_set_online(0);
+-
+-	init_node_data[0].node_start_pfn = 0;
+-	init_node_data[0].node_end_pfn = lmb_end_of_DRAM() / PAGE_SIZE;
+-	init_node_data[0].node_present_pages = total_ram / PAGE_SIZE;
+-
+-	for (i = 0 ; i < top_of_ram; i += MEMORY_INCREMENT)
+-		numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0;
+-}
+-
+-static void __init dump_numa_topology(void)
+-{
+-	unsigned int node;
+-	unsigned int count;
+-
+-	if (min_common_depth == -1 || !numa_enabled)
+-		return;
+-
+-	for_each_online_node(node) {
+-		unsigned long i;
+-
+-		printk(KERN_INFO "Node %d Memory:", node);
+-
+-		count = 0;
+-
+-		for (i = 0; i < lmb_end_of_DRAM(); i += MEMORY_INCREMENT) {
+-			if (numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] == node) {
+-				if (count == 0)
+-					printk(" 0x%lx", i);
+-				++count;
+-			} else {
+-				if (count > 0)
+-					printk("-0x%lx", i);
+-				count = 0;
+-			}
+-		}
+-
+-		if (count > 0)
+-			printk("-0x%lx", i);
+-		printk("\n");
+-	}
+-	return;
+-}
+-
+-/*
+- * Allocate some memory, satisfying the lmb or bootmem allocator where
+- * required. nid is the preferred node and end is the physical address of
+- * the highest address in the node.
+- *
+- * Returns the physical address of the memory.
+- */
+-static unsigned long careful_allocation(int nid, unsigned long size,
+-					unsigned long align, unsigned long end)
+-{
+-	unsigned long ret = lmb_alloc_base(size, align, end);
+-
+-	/* retry over all memory */
+-	if (!ret)
+-		ret = lmb_alloc_base(size, align, lmb_end_of_DRAM());
+-
+-	if (!ret)
+-		panic("numa.c: cannot allocate %lu bytes on node %d",
+-		      size, nid);
+-
+-	/*
+-	 * If the memory came from a previously allocated node, we must
+-	 * retry with the bootmem allocator.
+-	 */
+-	if (pa_to_nid(ret) < nid) {
+-		nid = pa_to_nid(ret);
+-		ret = (unsigned long)__alloc_bootmem_node(NODE_DATA(nid),
+-				size, align, 0);
+-
+-		if (!ret)
+-			panic("numa.c: cannot allocate %lu bytes on node %d",
+-			      size, nid);
+-
+-		ret = virt_to_abs(ret);
+-
+-		dbg("alloc_bootmem %lx %lx\n", ret, size);
+-	}
+-
+-	return ret;
+-}
+-
+-void __init do_init_bootmem(void)
+-{
+-	int nid;
+-	int addr_cells, size_cells;
+-	struct device_node *memory = NULL;
+-	static struct notifier_block ppc64_numa_nb = {
+-		.notifier_call = cpu_numa_callback,
+-		.priority = 1 /* Must run before sched domains notifier. */
+-	};
+-
+-	min_low_pfn = 0;
+-	max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
+-	max_pfn = max_low_pfn;
+-
+-	if (parse_numa_properties())
+-		setup_nonnuma();
+-	else
+-		dump_numa_topology();
+-
+-	register_cpu_notifier(&ppc64_numa_nb);
+-
+-	for_each_online_node(nid) {
+-		unsigned long start_paddr, end_paddr;
+-		int i;
+-		unsigned long bootmem_paddr;
+-		unsigned long bootmap_pages;
+-
+-		start_paddr = init_node_data[nid].node_start_pfn * PAGE_SIZE;
+-		end_paddr = init_node_data[nid].node_end_pfn * PAGE_SIZE;
+-
+-		/* Allocate the node structure node local if possible */
+-		NODE_DATA(nid) = (struct pglist_data *)careful_allocation(nid,
+-					sizeof(struct pglist_data),
+-					SMP_CACHE_BYTES, end_paddr);
+-		NODE_DATA(nid) = abs_to_virt(NODE_DATA(nid));
+-		memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
+-
+-  		dbg("node %d\n", nid);
+-		dbg("NODE_DATA() = %p\n", NODE_DATA(nid));
+-
+-		NODE_DATA(nid)->bdata = &plat_node_bdata[nid];
+-		NODE_DATA(nid)->node_start_pfn =
+-			init_node_data[nid].node_start_pfn;
+-		NODE_DATA(nid)->node_spanned_pages =
+-			end_paddr - start_paddr;
+-
+-		if (NODE_DATA(nid)->node_spanned_pages == 0)
+-  			continue;
+-
+-  		dbg("start_paddr = %lx\n", start_paddr);
+-  		dbg("end_paddr = %lx\n", end_paddr);
+-
+-		bootmap_pages = bootmem_bootmap_pages((end_paddr - start_paddr) >> PAGE_SHIFT);
+-
+-		bootmem_paddr = careful_allocation(nid,
+-				bootmap_pages << PAGE_SHIFT,
+-				PAGE_SIZE, end_paddr);
+-		memset(abs_to_virt(bootmem_paddr), 0,
+-		       bootmap_pages << PAGE_SHIFT);
+-		dbg("bootmap_paddr = %lx\n", bootmem_paddr);
+-
+-		init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
+-				  start_paddr >> PAGE_SHIFT,
+-				  end_paddr >> PAGE_SHIFT);
+-
+-		/*
+-		 * We need to do another scan of all memory sections to
+-		 * associate memory with the correct node.
+-		 */
+-		addr_cells = get_mem_addr_cells();
+-		size_cells = get_mem_size_cells();
+-		memory = NULL;
+-		while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+-			unsigned long mem_start, mem_size;
+-			int numa_domain, ranges;
+-			unsigned int *memcell_buf;
+-			unsigned int len;
+-
+-			memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
+-			if (!memcell_buf || len <= 0)
+-				continue;
+-
+-			ranges = memory->n_addrs;	/* ranges in cell */
+-new_range:
+-			mem_start = read_n_cells(addr_cells, &memcell_buf);
+-			mem_size = read_n_cells(size_cells, &memcell_buf);
+-			if (numa_enabled) {
+-				numa_domain = of_node_numa_domain(memory);
+-				if (numa_domain  >= MAX_NUMNODES)
+-					numa_domain = 0;
+-			} else
+-				numa_domain =  0;
+-
+-			if (numa_domain != nid)
+-				continue;
+-
+-			mem_size = numa_enforce_memory_limit(mem_start, mem_size);
+-  			if (mem_size) {
+-  				dbg("free_bootmem %lx %lx\n", mem_start, mem_size);
+-  				free_bootmem_node(NODE_DATA(nid), mem_start, mem_size);
+-			}
+-
+-			if (--ranges)		/* process all ranges in cell */
+-				goto new_range;
+-		}
+-
+-		/*
+-		 * Mark reserved regions on this node
+-		 */
+-		for (i = 0; i < lmb.reserved.cnt; i++) {
+-			unsigned long physbase = lmb.reserved.region[i].base;
+-			unsigned long size = lmb.reserved.region[i].size;
+-
+-			if (pa_to_nid(physbase) != nid &&
+-			    pa_to_nid(physbase+size-1) != nid)
+-				continue;
+-
+-			if (physbase < end_paddr &&
+-			    (physbase+size) > start_paddr) {
+-				/* overlaps */
+-				if (physbase < start_paddr) {
+-					size -= start_paddr - physbase;
+-					physbase = start_paddr;
+-				}
+-
+-				if (size > end_paddr - physbase)
+-					size = end_paddr - physbase;
+-
+-				dbg("reserve_bootmem %lx %lx\n", physbase,
+-				    size);
+-				reserve_bootmem_node(NODE_DATA(nid), physbase,
+-						     size);
+-			}
+-		}
+-		/*
+-		 * This loop may look famaliar, but we have to do it again
+-		 * after marking our reserved memory to mark memory present
+-		 * for sparsemem.
+-		 */
+-		addr_cells = get_mem_addr_cells();
+-		size_cells = get_mem_size_cells();
+-		memory = NULL;
+-		while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+-			unsigned long mem_start, mem_size;
+-			int numa_domain, ranges;
+-			unsigned int *memcell_buf;
+-			unsigned int len;
+-
+-			memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
+-			if (!memcell_buf || len <= 0)
+-				continue;
+-
+-			ranges = memory->n_addrs;	/* ranges in cell */
+-new_range2:
+-			mem_start = read_n_cells(addr_cells, &memcell_buf);
+-			mem_size = read_n_cells(size_cells, &memcell_buf);
+-			if (numa_enabled) {
+-				numa_domain = of_node_numa_domain(memory);
+-				if (numa_domain  >= MAX_NUMNODES)
+-					numa_domain = 0;
+-			} else
+-				numa_domain =  0;
+-
+-			if (numa_domain != nid)
+-				continue;
+-
+-			mem_size = numa_enforce_memory_limit(mem_start, mem_size);
+-			memory_present(numa_domain, mem_start >> PAGE_SHIFT,
+-				       (mem_start + mem_size) >> PAGE_SHIFT);
+-
+-			if (--ranges)		/* process all ranges in cell */
+-				goto new_range2;
+-		}
+-
+-	}
+-}
+-
+-void __init paging_init(void)
+-{
+-	unsigned long zones_size[MAX_NR_ZONES];
+-	unsigned long zholes_size[MAX_NR_ZONES];
+-	int nid;
+-
+-	memset(zones_size, 0, sizeof(zones_size));
+-	memset(zholes_size, 0, sizeof(zholes_size));
+-
+-	for_each_online_node(nid) {
+-		unsigned long start_pfn;
+-		unsigned long end_pfn;
+-
+-		start_pfn = init_node_data[nid].node_start_pfn;
+-		end_pfn = init_node_data[nid].node_end_pfn;
+-
+-		zones_size[ZONE_DMA] = end_pfn - start_pfn;
+-		zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] -
+-			init_node_data[nid].node_present_pages;
+-
+-		dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid,
+-		    zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]);
+-
+-		free_area_init_node(nid, NODE_DATA(nid), zones_size,
+-							start_pfn, zholes_size);
+-	}
+-}
+-
+-static int __init early_numa(char *p)
+-{
+-	if (!p)
+-		return 0;
+-
+-	if (strstr(p, "off"))
+-		numa_enabled = 0;
+-
+-	if (strstr(p, "debug"))
+-		numa_debug = 1;
+-
+-	return 0;
+-}
+-early_param("numa", early_numa);
+diff --git a/arch/ppc64/mm/slb.c b/arch/ppc64/mm/slb.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/slb.c
++++ /dev/null
+@@ -1,158 +0,0 @@
+-/*
+- * PowerPC64 SLB support.
+- *
+- * Copyright (C) 2004 David Gibson <dwg at au.ibm.com>, IBM
+- * Based on earlier code writteh by:
+- * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
+- *    Copyright (c) 2001 Dave Engebretsen
+- * Copyright (C) 2002 Anton Blanchard <anton at au.ibm.com>, 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/config.h>
+-#include <asm/pgtable.h>
+-#include <asm/mmu.h>
+-#include <asm/mmu_context.h>
+-#include <asm/paca.h>
+-#include <asm/cputable.h>
+-
+-extern void slb_allocate(unsigned long ea);
+-
+-static inline unsigned long mk_esid_data(unsigned long ea, unsigned long slot)
+-{
+-	return (ea & ESID_MASK) | SLB_ESID_V | slot;
+-}
+-
+-static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags)
+-{
+-	return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
+-}
+-
+-static inline void create_slbe(unsigned long ea, unsigned long flags,
+-			       unsigned long entry)
+-{
+-	asm volatile("slbmte  %0,%1" :
+-		     : "r" (mk_vsid_data(ea, flags)),
+-		       "r" (mk_esid_data(ea, entry))
+-		     : "memory" );
+-}
+-
+-static void slb_flush_and_rebolt(void)
+-{
+-	/* If you change this make sure you change SLB_NUM_BOLTED
+-	 * appropriately too. */
+-	unsigned long ksp_flags = SLB_VSID_KERNEL;
+-	unsigned long ksp_esid_data;
+-
+-	WARN_ON(!irqs_disabled());
+-
+-	if (cpu_has_feature(CPU_FTR_16M_PAGE))
+-		ksp_flags |= SLB_VSID_L;
+-
+-	ksp_esid_data = mk_esid_data(get_paca()->kstack, 2);
+-	if ((ksp_esid_data & ESID_MASK) == KERNELBASE)
+-		ksp_esid_data &= ~SLB_ESID_V;
+-
+-	/* We need to do this all in asm, so we're sure we don't touch
+-	 * the stack between the slbia and rebolting it. */
+-	asm volatile("isync\n"
+-		     "slbia\n"
+-		     /* Slot 1 - first VMALLOC segment */
+-		     "slbmte	%0,%1\n"
+-		     /* Slot 2 - kernel stack */
+-		     "slbmte	%2,%3\n"
+-		     "isync"
+-		     :: "r"(mk_vsid_data(VMALLOCBASE, SLB_VSID_KERNEL)),
+-		        "r"(mk_esid_data(VMALLOCBASE, 1)),
+-		        "r"(mk_vsid_data(ksp_esid_data, ksp_flags)),
+-		        "r"(ksp_esid_data)
+-		     : "memory");
+-}
+-
+-/* Flush all user entries from the segment table of the current processor. */
+-void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
+-{
+-	unsigned long offset = get_paca()->slb_cache_ptr;
+-	unsigned long esid_data = 0;
+-	unsigned long pc = KSTK_EIP(tsk);
+-	unsigned long stack = KSTK_ESP(tsk);
+-	unsigned long unmapped_base;
+-
+-	if (offset <= SLB_CACHE_ENTRIES) {
+-		int i;
+-		asm volatile("isync" : : : "memory");
+-		for (i = 0; i < offset; i++) {
+-			esid_data = ((unsigned long)get_paca()->slb_cache[i]
+-				<< SID_SHIFT) | SLBIE_C;
+-			asm volatile("slbie %0" : : "r" (esid_data));
+-		}
+-		asm volatile("isync" : : : "memory");
+-	} else {
+-		slb_flush_and_rebolt();
+-	}
+-
+-	/* Workaround POWER5 < DD2.1 issue */
+-	if (offset == 1 || offset > SLB_CACHE_ENTRIES)
+-		asm volatile("slbie %0" : : "r" (esid_data));
+-
+-	get_paca()->slb_cache_ptr = 0;
+-	get_paca()->context = mm->context;
+-
+-	/*
+-	 * preload some userspace segments into the SLB.
+-	 */
+-	if (test_tsk_thread_flag(tsk, TIF_32BIT))
+-		unmapped_base = TASK_UNMAPPED_BASE_USER32;
+-	else
+-		unmapped_base = TASK_UNMAPPED_BASE_USER64;
+-
+-	if (pc >= KERNELBASE)
+-		return;
+-	slb_allocate(pc);
+-
+-	if (GET_ESID(pc) == GET_ESID(stack))
+-		return;
+-
+-	if (stack >= KERNELBASE)
+-		return;
+-	slb_allocate(stack);
+-
+-	if ((GET_ESID(pc) == GET_ESID(unmapped_base))
+-	    || (GET_ESID(stack) == GET_ESID(unmapped_base)))
+-		return;
+-
+-	if (unmapped_base >= KERNELBASE)
+-		return;
+-	slb_allocate(unmapped_base);
+-}
+-
+-void slb_initialize(void)
+-{
+-	/* On iSeries the bolted entries have already been set up by
+-	 * the hypervisor from the lparMap data in head.S */
+-#ifndef CONFIG_PPC_ISERIES
+-	unsigned long flags = SLB_VSID_KERNEL;
+-
+- 	/* Invalidate the entire SLB (even slot 0) & all the ERATS */
+- 	if (cpu_has_feature(CPU_FTR_16M_PAGE))
+- 		flags |= SLB_VSID_L;
+-
+- 	asm volatile("isync":::"memory");
+- 	asm volatile("slbmte  %0,%0"::"r" (0) : "memory");
+-	asm volatile("isync; slbia; isync":::"memory");
+-	create_slbe(KERNELBASE, flags, 0);
+-	create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1);
+-	/* We don't bolt the stack for the time being - we're in boot,
+-	 * so the stack is in the bolted segment.  By the time it goes
+-	 * elsewhere, we'll call _switch() which will bolt in the new
+-	 * one. */
+-	asm volatile("isync":::"memory");
+-#endif
+-
+-	get_paca()->stab_rr = SLB_NUM_BOLTED;
+-}
+diff --git a/arch/ppc64/mm/slb_low.S b/arch/ppc64/mm/slb_low.S
+deleted file mode 100644
+--- a/arch/ppc64/mm/slb_low.S
++++ /dev/null
+@@ -1,151 +0,0 @@
+-/*
+- * arch/ppc64/mm/slb_low.S
+- *
+- * Low-level SLB routines
+- *
+- * Copyright (C) 2004 David Gibson <dwg at au.ibm.com>, IBM
+- *
+- * Based on earlier C version:
+- * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
+- *    Copyright (c) 2001 Dave Engebretsen
+- * Copyright (C) 2002 Anton Blanchard <anton at au.ibm.com>, 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/config.h>
+-#include <asm/processor.h>
+-#include <asm/page.h>
+-#include <asm/mmu.h>
+-#include <asm/ppc_asm.h>
+-#include <asm/asm-offsets.h>
+-#include <asm/cputable.h>
+-
+-/* void slb_allocate(unsigned long ea);
+- *
+- * Create an SLB entry for the given EA (user or kernel).
+- * 	r3 = faulting address, r13 = PACA
+- *	r9, r10, r11 are clobbered by this function
+- * No other registers are examined or changed.
+- */
+-_GLOBAL(slb_allocate)
+-	/*
+-	 * First find a slot, round robin. Previously we tried to find
+-	 * a free slot first but that took too long. Unfortunately we
+-	 * dont have any LRU information to help us choose a slot.
+-	 */
+-#ifdef CONFIG_PPC_ISERIES
+-	/*
+-	 * On iSeries, the "bolted" stack segment can be cast out on
+-	 * shared processor switch so we need to check for a miss on
+-	 * it and restore it to the right slot.
+-	 */
+-	ld	r9,PACAKSAVE(r13)
+-	clrrdi	r9,r9,28
+-	clrrdi	r11,r3,28
+-	li	r10,SLB_NUM_BOLTED-1	/* Stack goes in last bolted slot */
+-	cmpld	r9,r11
+-	beq	3f
+-#endif /* CONFIG_PPC_ISERIES */
+-
+-	ld	r10,PACASTABRR(r13)
+-	addi	r10,r10,1
+-	/* use a cpu feature mask if we ever change our slb size */
+-	cmpldi	r10,SLB_NUM_ENTRIES
+-
+-	blt+	4f
+-	li	r10,SLB_NUM_BOLTED
+-
+-4:
+-	std	r10,PACASTABRR(r13)
+-3:
+-	/* r3 = faulting address, r10 = entry */
+-
+-	srdi	r9,r3,60		/* get region */
+-	srdi	r3,r3,28		/* get esid */
+-	cmpldi	cr7,r9,0xc		/* cmp KERNELBASE for later use */
+-
+-	rldimi	r10,r3,28,0		/* r10= ESID<<28 | entry */
+-	oris	r10,r10,SLB_ESID_V at h	/* r10 |= SLB_ESID_V */
+-
+-	/* r3 = esid, r10 = esid_data, cr7 = <>KERNELBASE */
+-
+-	blt	cr7,0f			/* user or kernel? */
+-
+-	/* kernel address: proto-VSID = ESID */
+-	/* WARNING - MAGIC: we don't use the VSID 0xfffffffff, but
+-	 * this code will generate the protoVSID 0xfffffffff for the
+-	 * top segment.  That's ok, the scramble below will translate
+-	 * it to VSID 0, which is reserved as a bad VSID - one which
+-	 * will never have any pages in it.  */
+-	li	r11,SLB_VSID_KERNEL
+-BEGIN_FTR_SECTION
+-	bne	cr7,9f
+-	li	r11,(SLB_VSID_KERNEL|SLB_VSID_L)
+-END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
+-	b	9f
+-
+-0:	/* user address: proto-VSID = context<<15 | ESID */
+-	srdi.	r9,r3,USER_ESID_BITS
+-	bne-	8f			/* invalid ea bits set */
+-
+-#ifdef CONFIG_HUGETLB_PAGE
+-BEGIN_FTR_SECTION
+-	lhz	r9,PACAHIGHHTLBAREAS(r13)
+-	srdi	r11,r3,(HTLB_AREA_SHIFT-SID_SHIFT)
+-	srd	r9,r9,r11
+-	lhz	r11,PACALOWHTLBAREAS(r13)
+-	srd	r11,r11,r3
+-	or	r9,r9,r11
+-END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
+-#endif /* CONFIG_HUGETLB_PAGE */
+-
+-	li	r11,SLB_VSID_USER
+-
+-#ifdef CONFIG_HUGETLB_PAGE
+-BEGIN_FTR_SECTION
+-	rldimi	r11,r9,8,55		/* shift masked bit into SLB_VSID_L */
+-END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
+-#endif /* CONFIG_HUGETLB_PAGE */
+-
+-	ld	r9,PACACONTEXTID(r13)
+-	rldimi	r3,r9,USER_ESID_BITS,0
+-
+-9:	/* r3 = protovsid, r11 = flags, r10 = esid_data, cr7 = <>KERNELBASE */
+-	ASM_VSID_SCRAMBLE(r3,r9)
+-
+-	rldimi	r11,r3,SLB_VSID_SHIFT,16	/* combine VSID and flags */
+-
+-	/*
+-	 * No need for an isync before or after this slbmte. The exception
+-	 * we enter with and the rfid we exit with are context synchronizing.
+-	 */
+-	slbmte	r11,r10
+-
+-	bgelr	cr7			/* we're done for kernel addresses */
+-
+-	/* Update the slb cache */
+-	lhz	r3,PACASLBCACHEPTR(r13)	/* offset = paca->slb_cache_ptr */
+-	cmpldi	r3,SLB_CACHE_ENTRIES
+-	bge	1f
+-
+-	/* still room in the slb cache */
+-	sldi	r11,r3,1		/* r11 = offset * sizeof(u16) */
+-	rldicl	r10,r10,36,28		/* get low 16 bits of the ESID */
+-	add	r11,r11,r13		/* r11 = (u16 *)paca + offset */
+-	sth	r10,PACASLBCACHE(r11)	/* paca->slb_cache[offset] = esid */
+-	addi	r3,r3,1			/* offset++ */
+-	b	2f
+-1:					/* offset >= SLB_CACHE_ENTRIES */
+-	li	r3,SLB_CACHE_ENTRIES+1
+-2:
+-	sth	r3,PACASLBCACHEPTR(r13)	/* paca->slb_cache_ptr = offset */
+-	blr
+-
+-8:	/* invalid EA */
+-	li	r3,0			/* BAD_VSID */
+-	li	r11,SLB_VSID_USER	/* flags don't much matter */
+-	b	9b
+diff --git a/arch/ppc64/mm/stab.c b/arch/ppc64/mm/stab.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/stab.c
++++ /dev/null
+@@ -1,279 +0,0 @@
+-/*
+- * PowerPC64 Segment Translation Support.
+- *
+- * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
+- *    Copyright (c) 2001 Dave Engebretsen
+- *
+- * Copyright (C) 2002 Anton Blanchard <anton at au.ibm.com>, 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/config.h>
+-#include <asm/pgtable.h>
+-#include <asm/mmu.h>
+-#include <asm/mmu_context.h>
+-#include <asm/paca.h>
+-#include <asm/cputable.h>
+-#include <asm/lmb.h>
+-#include <asm/abs_addr.h>
+-
+-struct stab_entry {
+-	unsigned long esid_data;
+-	unsigned long vsid_data;
+-};
+-
+-/* Both the segment table and SLB code uses the following cache */
+-#define NR_STAB_CACHE_ENTRIES 8
+-DEFINE_PER_CPU(long, stab_cache_ptr);
+-DEFINE_PER_CPU(long, stab_cache[NR_STAB_CACHE_ENTRIES]);
+-
+-/*
+- * Create a segment table entry for the given esid/vsid pair.
+- */
+-static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
+-{
+-	unsigned long esid_data, vsid_data;
+-	unsigned long entry, group, old_esid, castout_entry, i;
+-	unsigned int global_entry;
+-	struct stab_entry *ste, *castout_ste;
+-	unsigned long kernel_segment = (esid << SID_SHIFT) >= KERNELBASE;
+-
+-	vsid_data = vsid << STE_VSID_SHIFT;
+-	esid_data = esid << SID_SHIFT | STE_ESID_KP | STE_ESID_V;
+-	if (! kernel_segment)
+-		esid_data |= STE_ESID_KS;
+-
+-	/* Search the primary group first. */
+-	global_entry = (esid & 0x1f) << 3;
+-	ste = (struct stab_entry *)(stab | ((esid & 0x1f) << 7));
+-
+-	/* Find an empty entry, if one exists. */
+-	for (group = 0; group < 2; group++) {
+-		for (entry = 0; entry < 8; entry++, ste++) {
+-			if (!(ste->esid_data & STE_ESID_V)) {
+-				ste->vsid_data = vsid_data;
+-				asm volatile("eieio":::"memory");
+-				ste->esid_data = esid_data;
+-				return (global_entry | entry);
+-			}
+-		}
+-		/* Now search the secondary group. */
+-		global_entry = ((~esid) & 0x1f) << 3;
+-		ste = (struct stab_entry *)(stab | (((~esid) & 0x1f) << 7));
+-	}
+-
+-	/*
+-	 * Could not find empty entry, pick one with a round robin selection.
+-	 * Search all entries in the two groups.
+-	 */
+-	castout_entry = get_paca()->stab_rr;
+-	for (i = 0; i < 16; i++) {
+-		if (castout_entry < 8) {
+-			global_entry = (esid & 0x1f) << 3;
+-			ste = (struct stab_entry *)(stab | ((esid & 0x1f) << 7));
+-			castout_ste = ste + castout_entry;
+-		} else {
+-			global_entry = ((~esid) & 0x1f) << 3;
+-			ste = (struct stab_entry *)(stab | (((~esid) & 0x1f) << 7));
+-			castout_ste = ste + (castout_entry - 8);
+-		}
+-
+-		/* Dont cast out the first kernel segment */
+-		if ((castout_ste->esid_data & ESID_MASK) != KERNELBASE)
+-			break;
+-
+-		castout_entry = (castout_entry + 1) & 0xf;
+-	}
+-
+-	get_paca()->stab_rr = (castout_entry + 1) & 0xf;
+-
+-	/* Modify the old entry to the new value. */
+-
+-	/* Force previous translations to complete. DRENG */
+-	asm volatile("isync" : : : "memory");
+-
+-	old_esid = castout_ste->esid_data >> SID_SHIFT;
+-	castout_ste->esid_data = 0;		/* Invalidate old entry */
+-
+-	asm volatile("sync" : : : "memory");    /* Order update */
+-
+-	castout_ste->vsid_data = vsid_data;
+-	asm volatile("eieio" : : : "memory");   /* Order update */
+-	castout_ste->esid_data = esid_data;
+-
+-	asm volatile("slbie  %0" : : "r" (old_esid << SID_SHIFT));
+-	/* Ensure completion of slbie */
+-	asm volatile("sync" : : : "memory");
+-
+-	return (global_entry | (castout_entry & 0x7));
+-}
+-
+-/*
+- * Allocate a segment table entry for the given ea and mm
+- */
+-static int __ste_allocate(unsigned long ea, struct mm_struct *mm)
+-{
+-	unsigned long vsid;
+-	unsigned char stab_entry;
+-	unsigned long offset;
+-
+-	/* Kernel or user address? */
+-	if (ea >= KERNELBASE) {
+-		vsid = get_kernel_vsid(ea);
+-	} else {
+-		if ((ea >= TASK_SIZE_USER64) || (! mm))
+-			return 1;
+-
+-		vsid = get_vsid(mm->context.id, ea);
+-	}
+-
+-	stab_entry = make_ste(get_paca()->stab_addr, GET_ESID(ea), vsid);
+-
+-	if (ea < KERNELBASE) {
+-		offset = __get_cpu_var(stab_cache_ptr);
+-		if (offset < NR_STAB_CACHE_ENTRIES)
+-			__get_cpu_var(stab_cache[offset++]) = stab_entry;
+-		else
+-			offset = NR_STAB_CACHE_ENTRIES+1;
+-		__get_cpu_var(stab_cache_ptr) = offset;
+-
+-		/* Order update */
+-		asm volatile("sync":::"memory");
+-	}
+-
+-	return 0;
+-}
+-
+-int ste_allocate(unsigned long ea)
+-{
+-	return __ste_allocate(ea, current->mm);
+-}
+-
+-/*
+- * Do the segment table work for a context switch: flush all user
+- * entries from the table, then preload some probably useful entries
+- * for the new task
+- */
+-void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
+-{
+-	struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr;
+-	struct stab_entry *ste;
+-	unsigned long offset = __get_cpu_var(stab_cache_ptr);
+-	unsigned long pc = KSTK_EIP(tsk);
+-	unsigned long stack = KSTK_ESP(tsk);
+-	unsigned long unmapped_base;
+-
+-	/* Force previous translations to complete. DRENG */
+-	asm volatile("isync" : : : "memory");
+-
+-	if (offset <= NR_STAB_CACHE_ENTRIES) {
+-		int i;
+-
+-		for (i = 0; i < offset; i++) {
+-			ste = stab + __get_cpu_var(stab_cache[i]);
+-			ste->esid_data = 0; /* invalidate entry */
+-		}
+-	} else {
+-		unsigned long entry;
+-
+-		/* Invalidate all entries. */
+-		ste = stab;
+-
+-		/* Never flush the first entry. */
+-		ste += 1;
+-		for (entry = 1;
+-		     entry < (PAGE_SIZE / sizeof(struct stab_entry));
+-		     entry++, ste++) {
+-			unsigned long ea;
+-			ea = ste->esid_data & ESID_MASK;
+-			if (ea < KERNELBASE) {
+-				ste->esid_data = 0;
+-			}
+-		}
+-	}
+-
+-	asm volatile("sync; slbia; sync":::"memory");
+-
+-	__get_cpu_var(stab_cache_ptr) = 0;
+-
+-	/* Now preload some entries for the new task */
+-	if (test_tsk_thread_flag(tsk, TIF_32BIT))
+-		unmapped_base = TASK_UNMAPPED_BASE_USER32;
+-	else
+-		unmapped_base = TASK_UNMAPPED_BASE_USER64;
+-
+-	__ste_allocate(pc, mm);
+-
+-	if (GET_ESID(pc) == GET_ESID(stack))
+-		return;
+-
+-	__ste_allocate(stack, mm);
+-
+-	if ((GET_ESID(pc) == GET_ESID(unmapped_base))
+-	    || (GET_ESID(stack) == GET_ESID(unmapped_base)))
+-		return;
+-
+-	__ste_allocate(unmapped_base, mm);
+-
+-	/* Order update */
+-	asm volatile("sync" : : : "memory");
+-}
+-
+-extern void slb_initialize(void);
+-
+-/*
+- * Allocate segment tables for secondary CPUs.  These must all go in
+- * the first (bolted) segment, so that do_stab_bolted won't get a
+- * recursive segment miss on the segment table itself.
+- */
+-void stabs_alloc(void)
+-{
+-	int cpu;
+-
+-	if (cpu_has_feature(CPU_FTR_SLB))
+-		return;
+-
+-	for_each_cpu(cpu) {
+-		unsigned long newstab;
+-
+-		if (cpu == 0)
+-			continue; /* stab for CPU 0 is statically allocated */
+-
+-		newstab = lmb_alloc_base(PAGE_SIZE, PAGE_SIZE, 1<<SID_SHIFT);
+-		if (! newstab)
+-			panic("Unable to allocate segment table for CPU %d.\n",
+-			      cpu);
+-
+-		newstab += KERNELBASE;
+-
+-		memset((void *)newstab, 0, PAGE_SIZE);
+-
+-		paca[cpu].stab_addr = newstab;
+-		paca[cpu].stab_real = virt_to_abs(newstab);
+-		printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx virtual, 0x%lx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
+-	}
+-}
+-
+-/*
+- * Build an entry for the base kernel segment and put it into
+- * the segment table or SLB.  All other segment table or SLB
+- * entries are faulted in.
+- */
+-void stab_initialize(unsigned long stab)
+-{
+-	unsigned long vsid = get_kernel_vsid(KERNELBASE);
+-
+-	if (cpu_has_feature(CPU_FTR_SLB)) {
+-		slb_initialize();
+-	} else {
+-		asm volatile("isync; slbia; isync":::"memory");
+-		make_ste(stab, GET_ESID(KERNELBASE), vsid);
+-
+-		/* Order update */
+-		asm volatile("sync":::"memory");
+-	}
+-}
+diff --git a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c
+deleted file mode 100644
+--- a/arch/ppc64/mm/tlb.c
++++ /dev/null
+@@ -1,197 +0,0 @@
+-/*
+- * This file contains the routines for flushing entries from the
+- * TLB and MMU hash table.
+- *
+- *  Derived from arch/ppc64/mm/init.c:
+- *    Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+- *
+- *  Modifications by Paul Mackerras (PowerMac) (paulus at cs.anu.edu.au)
+- *  and Cort Dougan (PReP) (cort at cs.nmt.edu)
+- *    Copyright (C) 1996 Paul Mackerras
+- *  Amiga/APUS changes by Jesper Skov (jskov at cygnus.co.uk).
+- *
+- *  Derived from "arch/i386/mm/init.c"
+- *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+- *
+- *  Dave Engebretsen <engebret at us.ibm.com>
+- *      Rework for PPC64 port.
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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/mm.h>
+-#include <linux/init.h>
+-#include <linux/percpu.h>
+-#include <linux/hardirq.h>
+-#include <asm/pgalloc.h>
+-#include <asm/tlbflush.h>
+-#include <asm/tlb.h>
+-#include <linux/highmem.h>
+-
+-DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
+-
+-/* This is declared as we are using the more or less generic
+- * include/asm-ppc64/tlb.h file -- tgall
+- */
+-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+-DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
+-unsigned long pte_freelist_forced_free;
+-
+-struct pte_freelist_batch
+-{
+-	struct rcu_head	rcu;
+-	unsigned int	index;
+-	pgtable_free_t	tables[0];
+-};
+-
+-DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
+-unsigned long pte_freelist_forced_free;
+-
+-#define PTE_FREELIST_SIZE \
+-	((PAGE_SIZE - sizeof(struct pte_freelist_batch)) \
+-	  / sizeof(pgtable_free_t))
+-
+-#ifdef CONFIG_SMP
+-static void pte_free_smp_sync(void *arg)
+-{
+-	/* Do nothing, just ensure we sync with all CPUs */
+-}
+-#endif
+-
+-/* This is only called when we are critically out of memory
+- * (and fail to get a page in pte_free_tlb).
+- */
+-static void pgtable_free_now(pgtable_free_t pgf)
+-{
+-	pte_freelist_forced_free++;
+-
+-	smp_call_function(pte_free_smp_sync, NULL, 0, 1);
+-
+-	pgtable_free(pgf);
+-}
+-
+-static void pte_free_rcu_callback(struct rcu_head *head)
+-{
+-	struct pte_freelist_batch *batch =
+-		container_of(head, struct pte_freelist_batch, rcu);
+-	unsigned int i;
+-
+-	for (i = 0; i < batch->index; i++)
+-		pgtable_free(batch->tables[i]);
+-
+-	free_page((unsigned long)batch);
+-}
+-
+-static void pte_free_submit(struct pte_freelist_batch *batch)
+-{
+-	INIT_RCU_HEAD(&batch->rcu);
+-	call_rcu(&batch->rcu, pte_free_rcu_callback);
+-}
+-
+-void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
+-{
+-	/* This is safe as we are holding page_table_lock */
+-        cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
+-	struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
+-
+-	if (atomic_read(&tlb->mm->mm_users) < 2 ||
+-	    cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
+-		pgtable_free(pgf);
+-		return;
+-	}
+-
+-	if (*batchp == NULL) {
+-		*batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
+-		if (*batchp == NULL) {
+-			pgtable_free_now(pgf);
+-			return;
+-		}
+-		(*batchp)->index = 0;
+-	}
+-	(*batchp)->tables[(*batchp)->index++] = pgf;
+-	if ((*batchp)->index == PTE_FREELIST_SIZE) {
+-		pte_free_submit(*batchp);
+-		*batchp = NULL;
+-	}
+-}
+-
+-/*
+- * Update the MMU hash table to correspond with a change to
+- * a Linux PTE.  If wrprot is true, it is permissible to
+- * change the existing HPTE to read-only rather than removing it
+- * (if we remove it we should clear the _PTE_HPTEFLAGS bits).
+- */
+-void hpte_update(struct mm_struct *mm, unsigned long addr,
+-		 unsigned long pte, int wrprot)
+-{
+-	int i;
+-	unsigned long context = 0;
+-	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
+-
+-	if (REGION_ID(addr) == USER_REGION_ID)
+-		context = mm->context.id;
+-	i = batch->index;
+-
+-	/*
+-	 * This can happen when we are in the middle of a TLB batch and
+-	 * we encounter memory pressure (eg copy_page_range when it tries
+-	 * to allocate a new pte). If we have to reclaim memory and end
+-	 * up scanning and resetting referenced bits then our batch context
+-	 * will change mid stream.
+-	 */
+-	if (i != 0 && (context != batch->context ||
+-		       batch->large != pte_huge(pte))) {
+-		flush_tlb_pending();
+-		i = 0;
+-	}
+-
+-	if (i == 0) {
+-		batch->context = context;
+-		batch->mm = mm;
+-		batch->large = pte_huge(pte);
+-	}
+-	batch->pte[i] = __pte(pte);
+-	batch->addr[i] = addr;
+-	batch->index = ++i;
+-	if (i >= PPC64_TLB_BATCH_NR)
+-		flush_tlb_pending();
+-}
+-
+-void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
+-{
+-	int i;
+-	int cpu;
+-	cpumask_t tmp;
+-	int local = 0;
+-
+-	BUG_ON(in_interrupt());
+-
+-	cpu = get_cpu();
+-	i = batch->index;
+-	tmp = cpumask_of_cpu(cpu);
+-	if (cpus_equal(batch->mm->cpu_vm_mask, tmp))
+-		local = 1;
+-
+-	if (i == 1)
+-		flush_hash_page(batch->context, batch->addr[0], batch->pte[0],
+-				local);
+-	else
+-		flush_hash_range(batch->context, i, local);
+-	batch->index = 0;
+-	put_cpu();
+-}
+-
+-void pte_free_finish(void)
+-{
+-	/* This is safe as we are holding page_table_lock */
+-	struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
+-
+-	if (*batchp == NULL)
+-		return;
+-	pte_free_submit(*batchp);
+-	*batchp = NULL;
+-}
+diff --git a/arch/ppc64/oprofile/Kconfig b/arch/ppc64/oprofile/Kconfig
+deleted file mode 100644
+--- a/arch/ppc64/oprofile/Kconfig
++++ /dev/null
+@@ -1,23 +0,0 @@
+-
+-menu "Profiling support"
+-	depends on EXPERIMENTAL
+-
+-config PROFILING
+-	bool "Profiling support (EXPERIMENTAL)"
+-	help
+-	  Say Y here to enable the extended profiling support mechanisms used
+-	  by profilers such as OProfile.
+-	  
+-
+-config OPROFILE
+-	tristate "OProfile system profiling (EXPERIMENTAL)"
+-	depends on PROFILING
+-	help
+-	  OProfile is a profiling system capable of profiling the
+-	  whole system, include the kernel, kernel modules, libraries,
+-	  and applications.
+-
+-	  If unsure, say N.
+-
+-endmenu
+-
+diff --git a/arch/ppc64/oprofile/Makefile b/arch/ppc64/oprofile/Makefile
+deleted file mode 100644
+--- a/arch/ppc64/oprofile/Makefile
++++ /dev/null
+@@ -1,9 +0,0 @@
+-obj-$(CONFIG_OPROFILE) += oprofile.o
+-
+-DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
+-		oprof.o cpu_buffer.o buffer_sync.o \
+-		event_buffer.o oprofile_files.o \
+-		oprofilefs.o oprofile_stats.o \
+-		timer_int.o )
+-
+-oprofile-y := $(DRIVER_OBJS) common.o op_model_rs64.o op_model_power4.o
+diff --git a/arch/ppc64/oprofile/common.c b/arch/ppc64/oprofile/common.c
+deleted file mode 100644
+--- a/arch/ppc64/oprofile/common.c
++++ /dev/null
+@@ -1,145 +0,0 @@
+-/*
+- * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, IBM
+- *
+- * Based on alpha version.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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/oprofile.h>
+-#include <linux/init.h>
+-#include <linux/smp.h>
+-#include <linux/errno.h>
+-#include <asm/ptrace.h>
+-#include <asm/system.h>
+-#include <asm/pmc.h>
+-#include <asm/cputable.h>
+-#include <asm/oprofile_impl.h>
+-
+-static struct op_ppc64_model *model;
+-
+-static struct op_counter_config ctr[OP_MAX_COUNTER];
+-static struct op_system_config sys;
+-
+-static void op_handle_interrupt(struct pt_regs *regs)
+-{
+-	model->handle_interrupt(regs, ctr);
+-}
+-
+-static int op_ppc64_setup(void)
+-{
+-	int err;
+-
+-	/* Grab the hardware */
+-	err = reserve_pmc_hardware(op_handle_interrupt);
+-	if (err)
+-		return err;
+-
+-	/* Pre-compute the values to stuff in the hardware registers.  */
+-	model->reg_setup(ctr, &sys, model->num_counters);
+-
+-	/* Configure the registers on all cpus.  */
+-	on_each_cpu(model->cpu_setup, NULL, 0, 1);
+-
+-	return 0;
+-}
+-
+-static void op_ppc64_shutdown(void)
+-{
+-	release_pmc_hardware();
+-}
+-
+-static void op_ppc64_cpu_start(void *dummy)
+-{
+-	model->start(ctr);
+-}
+-
+-static int op_ppc64_start(void)
+-{
+-	on_each_cpu(op_ppc64_cpu_start, NULL, 0, 1);
+-	return 0;
+-}
+-
+-static inline void op_ppc64_cpu_stop(void *dummy)
+-{
+-	model->stop();
+-}
+-
+-static void op_ppc64_stop(void)
+-{
+-	on_each_cpu(op_ppc64_cpu_stop, NULL, 0, 1);
+-}
+-
+-static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
+-{
+-	int i;
+-
+-	/*
+-	 * There is one mmcr0, mmcr1 and mmcra for setting the events for
+-	 * all of the counters.
+-	 */
+-	oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0);
+-	oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1);
+-	oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra);
+-
+-	for (i = 0; i < model->num_counters; ++i) {
+-		struct dentry *dir;
+-		char buf[3];
+-
+-		snprintf(buf, sizeof buf, "%d", i);
+-		dir = oprofilefs_mkdir(sb, root, buf);
+-
+-		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+-		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+-		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+-		/*
+-		 * We dont support per counter user/kernel selection, but
+-		 * we leave the entries because userspace expects them
+-		 */
+-		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+-		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+-		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+-	}
+-
+-	oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
+-	oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
+-	oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
+-				&sys.backtrace_spinlocks);
+-
+-	/* Default to tracing both kernel and user */
+-	sys.enable_kernel = 1;
+-	sys.enable_user = 1;
+-
+-	/* Turn on backtracing through spinlocks by default */
+-	sys.backtrace_spinlocks = 1;
+-
+-	return 0;
+-}
+-
+-int __init oprofile_arch_init(struct oprofile_operations *ops)
+-{
+-	if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type)
+-		return -ENODEV;
+-
+-	model = cur_cpu_spec->oprofile_model;
+-	model->num_counters = cur_cpu_spec->num_pmcs;
+-
+-	ops->cpu_type = cur_cpu_spec->oprofile_cpu_type;
+-	ops->create_files = op_ppc64_create_files;
+-	ops->setup = op_ppc64_setup;
+-	ops->shutdown = op_ppc64_shutdown;
+-	ops->start = op_ppc64_start;
+-	ops->stop = op_ppc64_stop;
+-
+-	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+-	       ops->cpu_type);
+-
+-	return 0;
+-}
+-
+-void oprofile_arch_exit(void)
+-{
+-}
+diff --git a/arch/ppc64/oprofile/op_model_power4.c b/arch/ppc64/oprofile/op_model_power4.c
+deleted file mode 100644
+--- a/arch/ppc64/oprofile/op_model_power4.c
++++ /dev/null
+@@ -1,309 +0,0 @@
+-/*
+- * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, 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/oprofile.h>
+-#include <linux/init.h>
+-#include <linux/smp.h>
+-#include <asm/ptrace.h>
+-#include <asm/system.h>
+-#include <asm/processor.h>
+-#include <asm/cputable.h>
+-#include <asm/systemcfg.h>
+-#include <asm/rtas.h>
+-#include <asm/oprofile_impl.h>
+-
+-#define dbg(args...)
+-
+-static unsigned long reset_value[OP_MAX_COUNTER];
+-
+-static int oprofile_running;
+-static int mmcra_has_sihv;
+-
+-/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
+-static u32 mmcr0_val;
+-static u64 mmcr1_val;
+-static u32 mmcra_val;
+-
+-/*
+- * Since we do not have an NMI, backtracing through spinlocks is
+- * only a best guess. In light of this, allow it to be disabled at
+- * runtime.
+- */
+-static int backtrace_spinlocks;
+-
+-static void power4_reg_setup(struct op_counter_config *ctr,
+-			     struct op_system_config *sys,
+-			     int num_ctrs)
+-{
+-	int i;
+-
+-	/*
+-	 * SIHV / SIPR bits are only implemented on POWER4+ (GQ) and above.
+-	 * However we disable it on all POWER4 until we verify it works
+-	 * (I was seeing some strange behaviour last time I tried).
+-	 *
+-	 * It has been verified to work on POWER5 so we enable it there.
+-	 */
+-	if (cpu_has_feature(CPU_FTR_MMCRA_SIHV))
+-		mmcra_has_sihv = 1;
+-
+-	/*
+-	 * The performance counter event settings are given in the mmcr0,
+-	 * mmcr1 and mmcra values passed from the user in the
+-	 * op_system_config structure (sys variable).
+-	 */
+-	mmcr0_val = sys->mmcr0;
+-	mmcr1_val = sys->mmcr1;
+-	mmcra_val = sys->mmcra;
+-
+-	backtrace_spinlocks = sys->backtrace_spinlocks;
+-
+-	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)
+-		reset_value[i] = 0x80000000UL - ctr[i].count;
+-
+-	/* setup user and kernel profiling */
+-	if (sys->enable_kernel)
+-		mmcr0_val &= ~MMCR0_KERNEL_DISABLE;
+-	else
+-		mmcr0_val |= MMCR0_KERNEL_DISABLE;
+-
+-	if (sys->enable_user)
+-		mmcr0_val &= ~MMCR0_PROBLEM_DISABLE;
+-	else
+-		mmcr0_val |= MMCR0_PROBLEM_DISABLE;
+-}
+-
+-extern void ppc64_enable_pmcs(void);
+-
+-static void power4_cpu_setup(void *unused)
+-{
+-	unsigned int mmcr0 = mmcr0_val;
+-	unsigned long mmcra = mmcra_val;
+-
+-	ppc64_enable_pmcs();
+-
+-	/* set the freeze bit */
+-	mmcr0 |= MMCR0_FC;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-
+-	mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE;
+-	mmcr0 |= MMCR0_PMC1CE|MMCR0_PMCjCE;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-
+-	mtspr(SPRN_MMCR1, mmcr1_val);
+-
+-	mmcra |= MMCRA_SAMPLE_ENABLE;
+-	mtspr(SPRN_MMCRA, mmcra);
+-
+-	dbg("setup on cpu %d, mmcr0 %lx\n", smp_processor_id(),
+-	    mfspr(SPRN_MMCR0));
+-	dbg("setup on cpu %d, mmcr1 %lx\n", smp_processor_id(),
+-	    mfspr(SPRN_MMCR1));
+-	dbg("setup on cpu %d, mmcra %lx\n", smp_processor_id(),
+-	    mfspr(SPRN_MMCRA));
+-}
+-
+-static void power4_start(struct op_counter_config *ctr)
+-{
+-	int i;
+-	unsigned int mmcr0;
+-
+-	/* set the PMM bit (see comment below) */
+-	mtmsrd(mfmsr() | MSR_PMM);
+-
+-	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
+-		if (ctr[i].enabled) {
+-			ctr_write(i, reset_value[i]);
+-		} else {
+-			ctr_write(i, 0);
+-		}
+-	}
+-
+-	mmcr0 = mfspr(SPRN_MMCR0);
+-
+-	/*
+-	 * We must clear the PMAO bit on some (GQ) chips. Just do it
+-	 * all the time
+-	 */
+-	mmcr0 &= ~MMCR0_PMAO;
+-
+-	/*
+-	 * now clear the freeze bit, counting will not start until we
+-	 * rfid from this excetion, because only at that point will
+-	 * the PMM bit be cleared
+-	 */
+-	mmcr0 &= ~MMCR0_FC;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-
+-	oprofile_running = 1;
+-
+-	dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
+-}
+-
+-static void power4_stop(void)
+-{
+-	unsigned int mmcr0;
+-
+-	/* freeze counters */
+-	mmcr0 = mfspr(SPRN_MMCR0);
+-	mmcr0 |= MMCR0_FC;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-
+-	oprofile_running = 0;
+-
+-	dbg("stop on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
+-
+-	mb();
+-}
+-
+-/* Fake functions used by canonicalize_pc */
+-static void __attribute_used__ hypervisor_bucket(void)
+-{
+-}
+-
+-static void __attribute_used__ rtas_bucket(void)
+-{
+-}
+-
+-static void __attribute_used__ kernel_unknown_bucket(void)
+-{
+-}
+-
+-static unsigned long check_spinlock_pc(struct pt_regs *regs,
+-				       unsigned long profile_pc)
+-{
+-	unsigned long pc = instruction_pointer(regs);
+-
+-	/*
+-	 * If both the SIAR (sampled instruction) and the perfmon exception
+-	 * occurred in a spinlock region then we account the sample to the
+-	 * calling function. This isnt 100% correct, we really need soft
+-	 * IRQ disable so we always get the perfmon exception at the
+-	 * point at which the SIAR is set.
+-	 */
+-	if (backtrace_spinlocks && in_lock_functions(pc) &&
+-			in_lock_functions(profile_pc))
+-		return regs->link;
+-	else
+-		return profile_pc;
+-}
+-
+-/*
+- * On GQ and newer the MMCRA stores the HV and PR bits at the time
+- * the SIAR was sampled. We use that to work out if the SIAR was sampled in
+- * the hypervisor, our exception vectors or RTAS.
+- */
+-static unsigned long get_pc(struct pt_regs *regs)
+-{
+-	unsigned long pc = mfspr(SPRN_SIAR);
+-	unsigned long mmcra;
+-
+-	/* Cant do much about it */
+-	if (!mmcra_has_sihv)
+-		return check_spinlock_pc(regs, pc);
+-
+-	mmcra = mfspr(SPRN_MMCRA);
+-
+-	/* Were we in the hypervisor? */
+-	if ((systemcfg->platform == PLATFORM_PSERIES_LPAR) &&
+-	    (mmcra & MMCRA_SIHV))
+-		/* function descriptor madness */
+-		return *((unsigned long *)hypervisor_bucket);
+-
+-	/* We were in userspace, nothing to do */
+-	if (mmcra & MMCRA_SIPR)
+-		return pc;
+-
+-#ifdef CONFIG_PPC_RTAS
+-	/* Were we in RTAS? */
+-	if (pc >= rtas.base && pc < (rtas.base + rtas.size))
+-		/* function descriptor madness */
+-		return *((unsigned long *)rtas_bucket);
+-#endif
+-
+-	/* Were we in our exception vectors or SLB real mode miss handler? */
+-	if (pc < 0x1000000UL)
+-		return (unsigned long)__va(pc);
+-
+-	/* Not sure where we were */
+-	if (pc < KERNELBASE)
+-		/* function descriptor madness */
+-		return *((unsigned long *)kernel_unknown_bucket);
+-
+-	return check_spinlock_pc(regs, pc);
+-}
+-
+-static int get_kernel(unsigned long pc)
+-{
+-	int is_kernel;
+-
+-	if (!mmcra_has_sihv) {
+-		is_kernel = (pc >= KERNELBASE);
+-	} else {
+-		unsigned long mmcra = mfspr(SPRN_MMCRA);
+-		is_kernel = ((mmcra & MMCRA_SIPR) == 0);
+-	}
+-
+-	return is_kernel;
+-}
+-
+-static void power4_handle_interrupt(struct pt_regs *regs,
+-				    struct op_counter_config *ctr)
+-{
+-	unsigned long pc;
+-	int is_kernel;
+-	int val;
+-	int i;
+-	unsigned int mmcr0;
+-
+-	pc = get_pc(regs);
+-	is_kernel = get_kernel(pc);
+-
+-	/* set the PMM bit (see comment below) */
+-	mtmsrd(mfmsr() | MSR_PMM);
+-
+-	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
+-		val = ctr_read(i);
+-		if (val < 0) {
+-			if (oprofile_running && ctr[i].enabled) {
+-				oprofile_add_pc(pc, is_kernel, i);
+-				ctr_write(i, reset_value[i]);
+-			} else {
+-				ctr_write(i, 0);
+-			}
+-		}
+-	}
+-
+-	mmcr0 = mfspr(SPRN_MMCR0);
+-
+-	/* reset the perfmon trigger */
+-	mmcr0 |= MMCR0_PMXE;
+-
+-	/*
+-	 * We must clear the PMAO bit on some (GQ) chips. Just do it
+-	 * all the time
+-	 */
+-	mmcr0 &= ~MMCR0_PMAO;
+-
+-	/*
+-	 * now clear the freeze bit, counting will not start until we
+-	 * rfid from this exception, because only at that point will
+-	 * the PMM bit be cleared
+-	 */
+-	mmcr0 &= ~MMCR0_FC;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-}
+-
+-struct op_ppc64_model op_model_power4 = {
+-	.reg_setup		= power4_reg_setup,
+-	.cpu_setup		= power4_cpu_setup,
+-	.start			= power4_start,
+-	.stop			= power4_stop,
+-	.handle_interrupt	= power4_handle_interrupt,
+-};
+diff --git a/arch/ppc64/oprofile/op_model_rs64.c b/arch/ppc64/oprofile/op_model_rs64.c
+deleted file mode 100644
+--- a/arch/ppc64/oprofile/op_model_rs64.c
++++ /dev/null
+@@ -1,218 +0,0 @@
+-/*
+- * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, 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/oprofile.h>
+-#include <linux/init.h>
+-#include <linux/smp.h>
+-#include <asm/ptrace.h>
+-#include <asm/system.h>
+-#include <asm/processor.h>
+-#include <asm/cputable.h>
+-#include <asm/oprofile_impl.h>
+-
+-#define dbg(args...)
+-
+-static void ctrl_write(unsigned int i, unsigned int val)
+-{
+-	unsigned int tmp = 0;
+-	unsigned long shift = 0, mask = 0;
+-
+-	dbg("ctrl_write %d %x\n", i, val);
+-
+-	switch(i) {
+-	case 0:
+-		tmp = mfspr(SPRN_MMCR0);
+-		shift = 6;
+-		mask = 0x7F;
+-		break;
+-	case 1:
+-		tmp = mfspr(SPRN_MMCR0);
+-		shift = 0;
+-		mask = 0x3F;
+-		break;
+-	case 2:
+-		tmp = mfspr(SPRN_MMCR1);
+-		shift = 31 - 4;
+-		mask = 0x1F;
+-		break;
+-	case 3:
+-		tmp = mfspr(SPRN_MMCR1);
+-		shift = 31 - 9;
+-		mask = 0x1F;
+-		break;
+-	case 4:
+-		tmp = mfspr(SPRN_MMCR1);
+-		shift = 31 - 14;
+-		mask = 0x1F;
+-		break;
+-	case 5:
+-		tmp = mfspr(SPRN_MMCR1);
+-		shift = 31 - 19;
+-		mask = 0x1F;
+-		break;
+-	case 6:
+-		tmp = mfspr(SPRN_MMCR1);
+-		shift = 31 - 24;
+-		mask = 0x1F;
+-		break;
+-	case 7:
+-		tmp = mfspr(SPRN_MMCR1);
+-		shift = 31 - 28;
+-		mask = 0xF;
+-		break;
+-	}
+-
+-	tmp = tmp & ~(mask << shift);
+-	tmp |= val << shift;
+-
+-	switch(i) {
+-		case 0:
+-		case 1:
+-			mtspr(SPRN_MMCR0, tmp);
+-			break;
+-		default:
+-			mtspr(SPRN_MMCR1, tmp);
+-	}
+-
+-	dbg("ctrl_write mmcr0 %lx mmcr1 %lx\n", mfspr(SPRN_MMCR0),
+-	       mfspr(SPRN_MMCR1));
+-}
+-
+-static unsigned long reset_value[OP_MAX_COUNTER];
+-
+-static int num_counters;
+-
+-static void rs64_reg_setup(struct op_counter_config *ctr,
+-			   struct op_system_config *sys,
+-			   int num_ctrs)
+-{
+-	int i;
+-
+-	num_counters = num_ctrs;
+-
+-	for (i = 0; i < num_counters; ++i)
+-		reset_value[i] = 0x80000000UL - ctr[i].count;
+-
+-	/* XXX setup user and kernel profiling */
+-}
+-
+-static void rs64_cpu_setup(void *unused)
+-{
+-	unsigned int mmcr0;
+-
+-	/* reset MMCR0 and set the freeze bit */
+-	mmcr0 = MMCR0_FC;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-
+-	/* reset MMCR1, MMCRA */
+-	mtspr(SPRN_MMCR1, 0);
+-
+-	if (cpu_has_feature(CPU_FTR_MMCRA))
+-		mtspr(SPRN_MMCRA, 0);
+-
+-	mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE;
+-	/* Only applies to POWER3, but should be safe on RS64 */
+-	mmcr0 |= MMCR0_PMC1CE|MMCR0_PMCjCE;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-
+-	dbg("setup on cpu %d, mmcr0 %lx\n", smp_processor_id(),
+-	    mfspr(SPRN_MMCR0));
+-	dbg("setup on cpu %d, mmcr1 %lx\n", smp_processor_id(),
+-	    mfspr(SPRN_MMCR1));
+-}
+-
+-static void rs64_start(struct op_counter_config *ctr)
+-{
+-	int i;
+-	unsigned int mmcr0;
+-
+-	/* set the PMM bit (see comment below) */
+-	mtmsrd(mfmsr() | MSR_PMM);
+-
+-	for (i = 0; i < num_counters; ++i) {
+-		if (ctr[i].enabled) {
+-			ctr_write(i, reset_value[i]);
+-			ctrl_write(i, ctr[i].event);
+-		} else {
+-			ctr_write(i, 0);
+-		}
+-	}
+-
+-	mmcr0 = mfspr(SPRN_MMCR0);
+-
+-	/*
+-	 * now clear the freeze bit, counting will not start until we
+-	 * rfid from this excetion, because only at that point will
+-	 * the PMM bit be cleared
+-	 */
+-	mmcr0 &= ~MMCR0_FC;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-
+-	dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
+-}
+-
+-static void rs64_stop(void)
+-{
+-	unsigned int mmcr0;
+-
+-	/* freeze counters */
+-	mmcr0 = mfspr(SPRN_MMCR0);
+-	mmcr0 |= MMCR0_FC;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-
+-	dbg("stop on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
+-
+-	mb();
+-}
+-
+-static void rs64_handle_interrupt(struct pt_regs *regs,
+-				  struct op_counter_config *ctr)
+-{
+-	unsigned int mmcr0;
+-	int val;
+-	int i;
+-	unsigned long pc = mfspr(SPRN_SIAR);
+-	int is_kernel = (pc >= KERNELBASE);
+-
+-	/* set the PMM bit (see comment below) */
+-	mtmsrd(mfmsr() | MSR_PMM);
+-
+-	for (i = 0; i < num_counters; ++i) {
+-		val = ctr_read(i);
+-		if (val < 0) {
+-			if (ctr[i].enabled) {
+-				oprofile_add_pc(pc, is_kernel, i);
+-				ctr_write(i, reset_value[i]);
+-			} else {
+-				ctr_write(i, 0);
+-			}
+-		}
+-	}
+-
+-	mmcr0 = mfspr(SPRN_MMCR0);
+-
+-	/* reset the perfmon trigger */
+-	mmcr0 |= MMCR0_PMXE;
+-
+-	/*
+-	 * now clear the freeze bit, counting will not start until we
+-	 * rfid from this exception, because only at that point will
+-	 * the PMM bit be cleared
+-	 */
+-	mmcr0 &= ~MMCR0_FC;
+-	mtspr(SPRN_MMCR0, mmcr0);
+-}
+-
+-struct op_ppc64_model op_model_rs64 = {
+-	.reg_setup		= rs64_reg_setup,
+-	.cpu_setup		= rs64_cpu_setup,
+-	.start			= rs64_start,
+-	.stop			= rs64_stop,
+-	.handle_interrupt	= rs64_handle_interrupt,
+-};
+diff --git a/arch/ppc64/xmon/Makefile b/arch/ppc64/xmon/Makefile
+deleted file mode 100644
+--- a/arch/ppc64/xmon/Makefile
++++ /dev/null
+@@ -1,5 +0,0 @@
+-# Makefile for xmon
+-
+-EXTRA_CFLAGS += -mno-minimal-toc
+-
+-obj-y := start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
+diff --git a/arch/ppc64/xmon/ansidecl.h b/arch/ppc64/xmon/ansidecl.h
+deleted file mode 100644
+--- a/arch/ppc64/xmon/ansidecl.h
++++ /dev/null
+@@ -1,141 +0,0 @@
+-/* ANSI and traditional C compatibility macros
+-   Copyright 1991, 1992 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-This program is free software; you can redistribute it and/or modify
+-it under the terms of the 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.  */
+-
+-/* ANSI and traditional C compatibility macros
+-
+-   ANSI C is assumed if __STDC__ is #defined.
+-
+-   Macro	ANSI C definition	Traditional C definition
+-   -----	---- - ----------	----------- - ----------
+-   PTR		`void *'		`char *'
+-   LONG_DOUBLE	`long double'		`double'
+-   VOLATILE	`volatile'		`'
+-   SIGNED	`signed'		`'
+-   PTRCONST	`void *const'		`char *'
+-   ANSI_PROTOTYPES  1			not defined
+-
+-   CONST is also defined, but is obsolete.  Just use const.
+-
+-   DEFUN (name, arglist, args)
+-
+-	Defines function NAME.
+-
+-	ARGLIST lists the arguments, separated by commas and enclosed in
+-	parentheses.  ARGLIST becomes the argument list in traditional C.
+-
+-	ARGS list the arguments with their types.  It becomes a prototype in
+-	ANSI C, and the type declarations in traditional C.  Arguments should
+-	be separated with `AND'.  For functions with a variable number of
+-	arguments, the last thing listed should be `DOTS'.
+-
+-   DEFUN_VOID (name)
+-
+-	Defines a function NAME, which takes no arguments.
+-
+-   obsolete --     EXFUN (name, (prototype))	-- obsolete.
+-
+-	Replaced by PARAMS.  Do not use; will disappear someday soon.
+-	Was used in external function declarations.
+-	In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
+-	parentheses).  In traditional C it is `NAME()'.
+-	For a function that takes no arguments, PROTOTYPE should be `(void)'.
+-
+-    PARAMS ((args))
+-
+-	We could use the EXFUN macro to handle prototype declarations, but
+-	the name is misleading and the result is ugly.  So we just define a
+-	simple macro to handle the parameter lists, as in:
+-
+-	      static int foo PARAMS ((int, char));
+-
+-	This produces:  `static int foo();' or `static int foo (int, char);'
+-
+-	EXFUN would have done it like this:
+-
+-	      static int EXFUN (foo, (int, char));
+-
+-	but the function is not external...and it's hard to visually parse
+-	the function name out of the mess.   EXFUN should be considered
+-	obsolete; new code should be written to use PARAMS.
+-
+-    For example:
+-	extern int printf PARAMS ((CONST char *format DOTS));
+-	int DEFUN(fprintf, (stream, format),
+-		  FILE *stream AND CONST char *format DOTS) { ... }
+-	void DEFUN_VOID(abort) { ... }
+-*/
+-
+-#ifndef	_ANSIDECL_H
+-
+-#define	_ANSIDECL_H	1
+-
+-
+-/* Every source file includes this file,
+-   so they will all get the switch for lint.  */
+-/* LINTLIBRARY */
+-
+-
+-#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32)
+-/* All known AIX compilers implement these things (but don't always
+-   define __STDC__).  The RISC/OS MIPS compiler defines these things
+-   in SVR4 mode, but does not define __STDC__.  */
+-
+-#define	PTR		void *
+-#define	PTRCONST	void *CONST
+-#define	LONG_DOUBLE	long double
+-
+-#define	AND		,
+-#define	NOARGS		void
+-#define	CONST		const
+-#define	VOLATILE	volatile
+-#define	SIGNED		signed
+-#define	DOTS		, ...
+-
+-#define	EXFUN(name, proto)		name proto
+-#define	DEFUN(name, arglist, args)	name(args)
+-#define	DEFUN_VOID(name)		name(void)
+-
+-#define PROTO(type, name, arglist)	type name arglist
+-#define PARAMS(paramlist)		paramlist
+-#define ANSI_PROTOTYPES			1
+-
+-#else	/* Not ANSI C.  */
+-
+-#define	PTR		char *
+-#define	PTRCONST	PTR
+-#define	LONG_DOUBLE	double
+-
+-#define	AND		;
+-#define	NOARGS
+-#define	CONST
+-#ifndef const /* some systems define it in header files for non-ansi mode */
+-#define	const
+-#endif
+-#define	VOLATILE
+-#define	SIGNED
+-#define	DOTS
+-
+-#define	EXFUN(name, proto)		name()
+-#define	DEFUN(name, arglist, args)	name arglist args;
+-#define	DEFUN_VOID(name)		name()
+-#define PROTO(type, name, arglist) type name ()
+-#define PARAMS(paramlist)		()
+-
+-#endif	/* ANSI C.  */
+-
+-#endif	/* ansidecl.h	*/
+diff --git a/arch/ppc64/xmon/nonstdio.h b/arch/ppc64/xmon/nonstdio.h
+deleted file mode 100644
+--- a/arch/ppc64/xmon/nonstdio.h
++++ /dev/null
+@@ -1,22 +0,0 @@
+-typedef int	FILE;
+-extern FILE *xmon_stdin, *xmon_stdout;
+-#define EOF	(-1)
+-#define stdin	xmon_stdin
+-#define stdout	xmon_stdout
+-#define printf	xmon_printf
+-#define fprintf	xmon_fprintf
+-#define fputs	xmon_fputs
+-#define fgets	xmon_fgets
+-#define putchar	xmon_putchar
+-#define getchar	xmon_getchar
+-#define putc	xmon_putc
+-#define getc	xmon_getc
+-#define fopen(n, m)	NULL
+-#define fflush(f)	do {} while (0)
+-#define fclose(f)	do {} while (0)
+-extern char *fgets(char *, int, void *);
+-extern void xmon_printf(const char *, ...);
+-extern void xmon_fprintf(void *, const char *, ...);
+-extern void xmon_sprintf(char *, const char *, ...);
+-
+-#define perror(s)	printf("%s: no files!\n", (s))
+diff --git a/arch/ppc64/xmon/ppc-dis.c b/arch/ppc64/xmon/ppc-dis.c
+deleted file mode 100644
+--- a/arch/ppc64/xmon/ppc-dis.c
++++ /dev/null
+@@ -1,184 +0,0 @@
+-/* ppc-dis.c -- Disassemble PowerPC instructions
+-   Copyright 1994 Free Software Foundation, Inc.
+-   Written by Ian Lance Taylor, Cygnus Support
+-
+-This file is part of GDB, GAS, and the GNU binutils.
+-
+-GDB, GAS, and the GNU binutils are free software; you can redistribute
+-them and/or modify them 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.
+-
+-GDB, GAS, and the GNU binutils are distributed in the hope that they
+-will be useful, but WITHOUT ANY WARRANTY; without even the implied
+-warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+-the GNU General Public License for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with this file; see the file COPYING.  If not, write to the Free
+-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+-
+-#include "nonstdio.h"
+-#include "ansidecl.h"
+-#include "ppc.h"
+-
+-extern void print_address (unsigned long memaddr);
+-
+-/* Print a PowerPC or POWER instruction.  */
+-
+-int
+-print_insn_powerpc (unsigned long insn, unsigned long memaddr, int dialect)
+-{
+-  const struct powerpc_opcode *opcode;
+-  const struct powerpc_opcode *opcode_end;
+-  unsigned long op;
+-
+-  if (dialect == 0)
+-    dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON
+-	      | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC;
+-
+-  /* Get the major opcode of the instruction.  */
+-  op = PPC_OP (insn);
+-
+-  /* Find the first match in the opcode table.  We could speed this up
+-     a bit by doing a binary search on the major opcode.  */
+-  opcode_end = powerpc_opcodes + powerpc_num_opcodes;
+- again:
+-  for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
+-    {
+-      unsigned long table_op;
+-      const unsigned char *opindex;
+-      const struct powerpc_operand *operand;
+-      int invalid;
+-      int need_comma;
+-      int need_paren;
+-
+-      table_op = PPC_OP (opcode->opcode);
+-      if (op < table_op)
+-	break;
+-      if (op > table_op)
+-	continue;
+-
+-      if ((insn & opcode->mask) != opcode->opcode
+-	  || (opcode->flags & dialect) == 0)
+-	continue;
+-
+-      /* Make two passes over the operands.  First see if any of them
+-	 have extraction functions, and, if they do, make sure the
+-	 instruction is valid.  */
+-      invalid = 0;
+-      for (opindex = opcode->operands; *opindex != 0; opindex++)
+-	{
+-	  operand = powerpc_operands + *opindex;
+-	  if (operand->extract)
+-	    (*operand->extract) (insn, dialect, &invalid);
+-	}
+-      if (invalid)
+-	continue;
+-
+-      /* The instruction is valid.  */
+-      printf("%s", opcode->name);
+-      if (opcode->operands[0] != 0)
+-	printf("\t");
+-
+-      /* Now extract and print the operands.  */
+-      need_comma = 0;
+-      need_paren = 0;
+-      for (opindex = opcode->operands; *opindex != 0; opindex++)
+-	{
+-	  long value;
+-
+-	  operand = powerpc_operands + *opindex;
+-
+-	  /* Operands that are marked FAKE are simply ignored.  We
+-	     already made sure that the extract function considered
+-	     the instruction to be valid.  */
+-	  if ((operand->flags & PPC_OPERAND_FAKE) != 0)
+-	    continue;
+-
+-	  /* Extract the value from the instruction.  */
+-	  if (operand->extract)
+-	    value = (*operand->extract) (insn, dialect, &invalid);
+-	  else
+-	    {
+-	      value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+-	      if ((operand->flags & PPC_OPERAND_SIGNED) != 0
+-		  && (value & (1 << (operand->bits - 1))) != 0)
+-		value -= 1 << operand->bits;
+-	    }
+-
+-	  /* If the operand is optional, and the value is zero, don't
+-	     print anything.  */
+-	  if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+-	      && (operand->flags & PPC_OPERAND_NEXT) == 0
+-	      && value == 0)
+-	    continue;
+-
+-	  if (need_comma)
+-	    {
+-	      printf(",");
+-	      need_comma = 0;
+-	    }
+-
+-	  /* Print the operand as directed by the flags.  */
+-	  if ((operand->flags & PPC_OPERAND_GPR) != 0)
+-	    printf("r%ld", value);
+-	  else if ((operand->flags & PPC_OPERAND_FPR) != 0)
+-	    printf("f%ld", value);
+-	  else if ((operand->flags & PPC_OPERAND_VR) != 0)
+-	    printf("v%ld", value);
+-	  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
+-	    print_address (memaddr + value);
+-	  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+-	    print_address (value & 0xffffffff);
+-	  else if ((operand->flags & PPC_OPERAND_CR) == 0
+-		   || (dialect & PPC_OPCODE_PPC) == 0)
+-	    printf("%ld", value);
+-	  else
+-	    {
+-	      if (operand->bits == 3)
+-		printf("cr%d", value);
+-	      else
+-		{
+-		  static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
+-		  int cr;
+-		  int cc;
+-
+-		  cr = value >> 2;
+-		  if (cr != 0)
+-		    printf("4*cr%d+", cr);
+-		  cc = value & 3;
+-		  printf("%s", cbnames[cc]);
+-		}
+-	    }
+-
+-	  if (need_paren)
+-	    {
+-	      printf(")");
+-	      need_paren = 0;
+-	    }
+-
+-	  if ((operand->flags & PPC_OPERAND_PARENS) == 0)
+-	    need_comma = 1;
+-	  else
+-	    {
+-	      printf("(");
+-	      need_paren = 1;
+-	    }
+-	}
+-
+-      /* We have found and printed an instruction; return.  */
+-      return 4;
+-    }
+-
+-  if ((dialect & PPC_OPCODE_ANY) != 0)
+-    {
+-      dialect = ~PPC_OPCODE_ANY;
+-      goto again;
+-    }
+-
+-  /* We could not find a match.  */
+-  printf(".long 0x%lx", insn);
+-
+-  return 4;
+-}
+diff --git a/arch/ppc64/xmon/ppc-opc.c b/arch/ppc64/xmon/ppc-opc.c
+deleted file mode 100644
+--- a/arch/ppc64/xmon/ppc-opc.c
++++ /dev/null
+@@ -1,4621 +0,0 @@
+-/* ppc-opc.c -- PowerPC opcode list
+-   Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
+-   Free Software Foundation, Inc.
+-   Written by Ian Lance Taylor, Cygnus Support
+-
+-   This file is part of GDB, GAS, and the GNU binutils.
+-
+-   GDB, GAS, and the GNU binutils are free software; you can redistribute
+-   them and/or modify them 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.
+-
+-   GDB, GAS, and the GNU binutils are distributed in the hope that they
+-   will be useful, but WITHOUT ANY WARRANTY; without even the implied
+-   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+-   the GNU General Public License for more details.
+-
+-   You should have received a copy of the GNU General Public License
+-   along with this file; see the file COPYING.  If not, write to the Free
+-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+-   02111-1307, USA.  */
+-
+-#include <linux/stddef.h>
+-#include "nonstdio.h"
+-#include "ppc.h"
+-
+-#define ATTRIBUTE_UNUSED
+-#define _(x)	x
+-
+-/* This file holds the PowerPC opcode table.  The opcode table
+-   includes almost all of the extended instruction mnemonics.  This
+-   permits the disassembler to use them, and simplifies the assembler
+-   logic, at the cost of increasing the table size.  The table is
+-   strictly constant data, so the compiler should be able to put it in
+-   the .text section.
+-
+-   This file also holds the operand table.  All knowledge about
+-   inserting operands into instructions and vice-versa is kept in this
+-   file.  */
+-
+-/* Local insertion and extraction functions.  */
+-
+-static unsigned long insert_bat (unsigned long, long, int, const char **);
+-static long extract_bat (unsigned long, int, int *);
+-static unsigned long insert_bba (unsigned long, long, int, const char **);
+-static long extract_bba (unsigned long, int, int *);
+-static unsigned long insert_bd (unsigned long, long, int, const char **);
+-static long extract_bd (unsigned long, int, int *);
+-static unsigned long insert_bdm (unsigned long, long, int, const char **);
+-static long extract_bdm (unsigned long, int, int *);
+-static unsigned long insert_bdp (unsigned long, long, int, const char **);
+-static long extract_bdp (unsigned long, int, int *);
+-static unsigned long insert_bo (unsigned long, long, int, const char **);
+-static long extract_bo (unsigned long, int, int *);
+-static unsigned long insert_boe (unsigned long, long, int, const char **);
+-static long extract_boe (unsigned long, int, int *);
+-static unsigned long insert_dq (unsigned long, long, int, const char **);
+-static long extract_dq (unsigned long, int, int *);
+-static unsigned long insert_ds (unsigned long, long, int, const char **);
+-static long extract_ds (unsigned long, int, int *);
+-static unsigned long insert_de (unsigned long, long, int, const char **);
+-static long extract_de (unsigned long, int, int *);
+-static unsigned long insert_des (unsigned long, long, int, const char **);
+-static long extract_des (unsigned long, int, int *);
+-static unsigned long insert_fxm (unsigned long, long, int, const char **);
+-static long extract_fxm (unsigned long, int, int *);
+-static unsigned long insert_li (unsigned long, long, int, const char **);
+-static long extract_li (unsigned long, int, int *);
+-static unsigned long insert_mbe (unsigned long, long, int, const char **);
+-static long extract_mbe (unsigned long, int, int *);
+-static unsigned long insert_mb6 (unsigned long, long, int, const char **);
+-static long extract_mb6 (unsigned long, int, int *);
+-static unsigned long insert_nb (unsigned long, long, int, const char **);
+-static long extract_nb (unsigned long, int, int *);
+-static unsigned long insert_nsi (unsigned long, long, int, const char **);
+-static long extract_nsi (unsigned long, int, int *);
+-static unsigned long insert_ral (unsigned long, long, int, const char **);
+-static unsigned long insert_ram (unsigned long, long, int, const char **);
+-static unsigned long insert_raq (unsigned long, long, int, const char **);
+-static unsigned long insert_ras (unsigned long, long, int, const char **);
+-static unsigned long insert_rbs (unsigned long, long, int, const char **);
+-static long extract_rbs (unsigned long, int, int *);
+-static unsigned long insert_rsq (unsigned long, long, int, const char **);
+-static unsigned long insert_rtq (unsigned long, long, int, const char **);
+-static unsigned long insert_sh6 (unsigned long, long, int, const char **);
+-static long extract_sh6 (unsigned long, int, int *);
+-static unsigned long insert_spr (unsigned long, long, int, const char **);
+-static long extract_spr (unsigned long, int, int *);
+-static unsigned long insert_tbr (unsigned long, long, int, const char **);
+-static long extract_tbr (unsigned long, int, int *);
+-static unsigned long insert_ev2 (unsigned long, long, int, const char **);
+-static long extract_ev2 (unsigned long, int, int *);
+-static unsigned long insert_ev4 (unsigned long, long, int, const char **);
+-static long extract_ev4 (unsigned long, int, int *);
+-static unsigned long insert_ev8 (unsigned long, long, int, const char **);
+-static long extract_ev8 (unsigned long, int, int *);
+-
+-/* The operands table.
+-
+-   The fields are bits, shift, insert, extract, flags.
+-
+-   We used to put parens around the various additions, like the one
+-   for BA just below.  However, that caused trouble with feeble
+-   compilers with a limit on depth of a parenthesized expression, like
+-   (reportedly) the compiler in Microsoft Developer Studio 5.  So we
+-   omit the parens, since the macros are never used in a context where
+-   the addition will be ambiguous.  */
+-
+-const struct powerpc_operand powerpc_operands[] =
+-{
+-  /* The zero index is used to indicate the end of the list of
+-     operands.  */
+-#define UNUSED 0
+-  { 0, 0, NULL, NULL, 0 },
+-
+-  /* The BA field in an XL form instruction.  */
+-#define BA UNUSED + 1
+-#define BA_MASK (0x1f << 16)
+-  { 5, 16, NULL, NULL, PPC_OPERAND_CR },
+-
+-  /* The BA field in an XL form instruction when it must be the same
+-     as the BT field in the same instruction.  */
+-#define BAT BA + 1
+-  { 5, 16, insert_bat, extract_bat, PPC_OPERAND_FAKE },
+-
+-  /* The BB field in an XL form instruction.  */
+-#define BB BAT + 1
+-#define BB_MASK (0x1f << 11)
+-  { 5, 11, NULL, NULL, PPC_OPERAND_CR },
+-
+-  /* The BB field in an XL form instruction when it must be the same
+-     as the BA field in the same instruction.  */
+-#define BBA BB + 1
+-  { 5, 11, insert_bba, extract_bba, PPC_OPERAND_FAKE },
+-
+-  /* The BD field in a B form instruction.  The lower two bits are
+-     forced to zero.  */
+-#define BD BBA + 1
+-  { 16, 0, insert_bd, extract_bd, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+-
+-  /* The BD field in a B form instruction when absolute addressing is
+-     used.  */
+-#define BDA BD + 1
+-  { 16, 0, insert_bd, extract_bd, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+-
+-  /* The BD field in a B form instruction when the - modifier is used.
+-     This sets the y bit of the BO field appropriately.  */
+-#define BDM BDA + 1
+-  { 16, 0, insert_bdm, extract_bdm,
+-      PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+-
+-  /* The BD field in a B form instruction when the - modifier is used
+-     and absolute address is used.  */
+-#define BDMA BDM + 1
+-  { 16, 0, insert_bdm, extract_bdm,
+-      PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+-
+-  /* The BD field in a B form instruction when the + modifier is used.
+-     This sets the y bit of the BO field appropriately.  */
+-#define BDP BDMA + 1
+-  { 16, 0, insert_bdp, extract_bdp,
+-      PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+-
+-  /* The BD field in a B form instruction when the + modifier is used
+-     and absolute addressing is used.  */
+-#define BDPA BDP + 1
+-  { 16, 0, insert_bdp, extract_bdp,
+-      PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+-
+-  /* The BF field in an X or XL form instruction.  */
+-#define BF BDPA + 1
+-  { 3, 23, NULL, NULL, PPC_OPERAND_CR },
+-
+-  /* An optional BF field.  This is used for comparison instructions,
+-     in which an omitted BF field is taken as zero.  */
+-#define OBF BF + 1
+-  { 3, 23, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+-
+-  /* The BFA field in an X or XL form instruction.  */
+-#define BFA OBF + 1
+-  { 3, 18, NULL, NULL, PPC_OPERAND_CR },
+-
+-  /* The BI field in a B form or XL form instruction.  */
+-#define BI BFA + 1
+-#define BI_MASK (0x1f << 16)
+-  { 5, 16, NULL, NULL, PPC_OPERAND_CR },
+-
+-  /* The BO field in a B form instruction.  Certain values are
+-     illegal.  */
+-#define BO BI + 1
+-#define BO_MASK (0x1f << 21)
+-  { 5, 21, insert_bo, extract_bo, 0 },
+-
+-  /* The BO field in a B form instruction when the + or - modifier is
+-     used.  This is like the BO field, but it must be even.  */
+-#define BOE BO + 1
+-  { 5, 21, insert_boe, extract_boe, 0 },
+-
+-  /* The BT field in an X or XL form instruction.  */
+-#define BT BOE + 1
+-  { 5, 21, NULL, NULL, PPC_OPERAND_CR },
+-
+-  /* The condition register number portion of the BI field in a B form
+-     or XL form instruction.  This is used for the extended
+-     conditional branch mnemonics, which set the lower two bits of the
+-     BI field.  This field is optional.  */
+-#define CR BT + 1
+-  { 3, 18, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+-
+-  /* The CRB field in an X form instruction.  */
+-#define CRB CR + 1
+-  { 5, 6, NULL, NULL, 0 },
+-
+-  /* The CRFD field in an X form instruction.  */
+-#define CRFD CRB + 1
+-  { 3, 23, NULL, NULL, PPC_OPERAND_CR },
+-
+-  /* The CRFS field in an X form instruction.  */
+-#define CRFS CRFD + 1
+-  { 3, 0, NULL, NULL, PPC_OPERAND_CR },
+-
+-  /* The CT field in an X form instruction.  */
+-#define CT CRFS + 1
+-  { 5, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
+-
+-  /* The D field in a D form instruction.  This is a displacement off
+-     a register, and implies that the next operand is a register in
+-     parentheses.  */
+-#define D CT + 1
+-  { 16, 0, NULL, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+-
+-  /* The DE field in a DE form instruction.  This is like D, but is 12
+-     bits only.  */
+-#define DE D + 1
+-  { 14, 0, insert_de, extract_de, PPC_OPERAND_PARENS },
+-
+-  /* The DES field in a DES form instruction.  This is like DS, but is 14
+-     bits only (12 stored.)  */
+-#define DES DE + 1
+-  { 14, 0, insert_des, extract_des, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+-
+-  /* The DQ field in a DQ form instruction.  This is like D, but the
+-     lower four bits are forced to zero. */
+-#define DQ DES + 1
+-  { 16, 0, insert_dq, extract_dq,
+-      PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DQ },
+-
+-  /* The DS field in a DS form instruction.  This is like D, but the
+-     lower two bits are forced to zero.  */
+-#define DS DQ + 1
+-  { 16, 0, insert_ds, extract_ds,
+-      PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS },
+-
+-  /* The E field in a wrteei instruction.  */
+-#define E DS + 1
+-  { 1, 15, NULL, NULL, 0 },
+-
+-  /* The FL1 field in a POWER SC form instruction.  */
+-#define FL1 E + 1
+-  { 4, 12, NULL, NULL, 0 },
+-
+-  /* The FL2 field in a POWER SC form instruction.  */
+-#define FL2 FL1 + 1
+-  { 3, 2, NULL, NULL, 0 },
+-
+-  /* The FLM field in an XFL form instruction.  */
+-#define FLM FL2 + 1
+-  { 8, 17, NULL, NULL, 0 },
+-
+-  /* The FRA field in an X or A form instruction.  */
+-#define FRA FLM + 1
+-#define FRA_MASK (0x1f << 16)
+-  { 5, 16, NULL, NULL, PPC_OPERAND_FPR },
+-
+-  /* The FRB field in an X or A form instruction.  */
+-#define FRB FRA + 1
+-#define FRB_MASK (0x1f << 11)
+-  { 5, 11, NULL, NULL, PPC_OPERAND_FPR },
+-
+-  /* The FRC field in an A form instruction.  */
+-#define FRC FRB + 1
+-#define FRC_MASK (0x1f << 6)
+-  { 5, 6, NULL, NULL, PPC_OPERAND_FPR },
+-
+-  /* The FRS field in an X form instruction or the FRT field in a D, X
+-     or A form instruction.  */
+-#define FRS FRC + 1
+-#define FRT FRS
+-  { 5, 21, NULL, NULL, PPC_OPERAND_FPR },
+-
+-  /* The FXM field in an XFX instruction.  */
+-#define FXM FRS + 1
+-#define FXM_MASK (0xff << 12)
+-  { 8, 12, insert_fxm, extract_fxm, 0 },
+-
+-  /* Power4 version for mfcr.  */
+-#define FXM4 FXM + 1
+-  { 8, 12, insert_fxm, extract_fxm, PPC_OPERAND_OPTIONAL },
+-
+-  /* The L field in a D or X form instruction.  */
+-#define L FXM4 + 1
+-  { 1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
+-
+-  /* The LEV field in a POWER SC form instruction.  */
+-#define LEV L + 1
+-  { 7, 5, NULL, NULL, 0 },
+-
+-  /* The LI field in an I form instruction.  The lower two bits are
+-     forced to zero.  */
+-#define LI LEV + 1
+-  { 26, 0, insert_li, extract_li, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+-
+-  /* The LI field in an I form instruction when used as an absolute
+-     address.  */
+-#define LIA LI + 1
+-  { 26, 0, insert_li, extract_li, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+-
+-  /* The LS field in an X (sync) form instruction.  */
+-#define LS LIA + 1
+-  { 2, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
+-
+-  /* The MB field in an M form instruction.  */
+-#define MB LS + 1
+-#define MB_MASK (0x1f << 6)
+-  { 5, 6, NULL, NULL, 0 },
+-
+-  /* The ME field in an M form instruction.  */
+-#define ME MB + 1
+-#define ME_MASK (0x1f << 1)
+-  { 5, 1, NULL, NULL, 0 },
+-
+-  /* The MB and ME fields in an M form instruction expressed a single
+-     operand which is a bitmask indicating which bits to select.  This
+-     is a two operand form using PPC_OPERAND_NEXT.  See the
+-     description in opcode/ppc.h for what this means.  */
+-#define MBE ME + 1
+-  { 5, 6, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT },
+-  { 32, 0, insert_mbe, extract_mbe, 0 },
+-
+-  /* The MB or ME field in an MD or MDS form instruction.  The high
+-     bit is wrapped to the low end.  */
+-#define MB6 MBE + 2
+-#define ME6 MB6
+-#define MB6_MASK (0x3f << 5)
+-  { 6, 5, insert_mb6, extract_mb6, 0 },
+-
+-  /* The MO field in an mbar instruction.  */
+-#define MO MB6 + 1
+-  { 5, 21, NULL, NULL, 0 },
+-
+-  /* The NB field in an X form instruction.  The value 32 is stored as
+-     0.  */
+-#define NB MO + 1
+-  { 6, 11, insert_nb, extract_nb, 0 },
+-
+-  /* The NSI field in a D form instruction.  This is the same as the
+-     SI field, only negated.  */
+-#define NSI NB + 1
+-  { 16, 0, insert_nsi, extract_nsi,
+-      PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
+-
+-  /* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction.  */
+-#define RA NSI + 1
+-#define RA_MASK (0x1f << 16)
+-  { 5, 16, NULL, NULL, PPC_OPERAND_GPR },
+-
+-  /* The RA field in the DQ form lq instruction, which has special
+-     value restrictions.  */
+-#define RAQ RA + 1
+-  { 5, 16, insert_raq, NULL, PPC_OPERAND_GPR },
+-
+-  /* The RA field in a D or X form instruction which is an updating
+-     load, which means that the RA field may not be zero and may not
+-     equal the RT field.  */
+-#define RAL RAQ + 1
+-  { 5, 16, insert_ral, NULL, PPC_OPERAND_GPR },
+-
+-  /* The RA field in an lmw instruction, which has special value
+-     restrictions.  */
+-#define RAM RAL + 1
+-  { 5, 16, insert_ram, NULL, PPC_OPERAND_GPR },
+-
+-  /* The RA field in a D or X form instruction which is an updating
+-     store or an updating floating point load, which means that the RA
+-     field may not be zero.  */
+-#define RAS RAM + 1
+-  { 5, 16, insert_ras, NULL, PPC_OPERAND_GPR },
+-
+-  /* The RB field in an X, XO, M, or MDS form instruction.  */
+-#define RB RAS + 1
+-#define RB_MASK (0x1f << 11)
+-  { 5, 11, NULL, NULL, PPC_OPERAND_GPR },
+-
+-  /* The RB field in an X form instruction when it must be the same as
+-     the RS field in the instruction.  This is used for extended
+-     mnemonics like mr.  */
+-#define RBS RB + 1
+-  { 5, 1, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
+-
+-  /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
+-     instruction or the RT field in a D, DS, X, XFX or XO form
+-     instruction.  */
+-#define RS RBS + 1
+-#define RT RS
+-#define RT_MASK (0x1f << 21)
+-  { 5, 21, NULL, NULL, PPC_OPERAND_GPR },
+-
+-  /* The RS field of the DS form stq instruction, which has special
+-     value restrictions.  */
+-#define RSQ RS + 1
+-  { 5, 21, insert_rsq, NULL, PPC_OPERAND_GPR },
+-
+-  /* The RT field of the DQ form lq instruction, which has special
+-     value restrictions.  */
+-#define RTQ RSQ + 1
+-  { 5, 21, insert_rtq, NULL, PPC_OPERAND_GPR },
+-
+-  /* The SH field in an X or M form instruction.  */
+-#define SH RTQ + 1
+-#define SH_MASK (0x1f << 11)
+-  { 5, 11, NULL, NULL, 0 },
+-
+-  /* The SH field in an MD form instruction.  This is split.  */
+-#define SH6 SH + 1
+-#define SH6_MASK ((0x1f << 11) | (1 << 1))
+-  { 6, 1, insert_sh6, extract_sh6, 0 },
+-
+-  /* The SI field in a D form instruction.  */
+-#define SI SH6 + 1
+-  { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED },
+-
+-  /* The SI field in a D form instruction when we accept a wide range
+-     of positive values.  */
+-#define SISIGNOPT SI + 1
+-  { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT },
+-
+-  /* The SPR field in an XFX form instruction.  This is flipped--the
+-     lower 5 bits are stored in the upper 5 and vice- versa.  */
+-#define SPR SISIGNOPT + 1
+-#define PMR SPR
+-#define SPR_MASK (0x3ff << 11)
+-  { 10, 11, insert_spr, extract_spr, 0 },
+-
+-  /* The BAT index number in an XFX form m[ft]ibat[lu] instruction.  */
+-#define SPRBAT SPR + 1
+-#define SPRBAT_MASK (0x3 << 17)
+-  { 2, 17, NULL, NULL, 0 },
+-
+-  /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
+-#define SPRG SPRBAT + 1
+-#define SPRG_MASK (0x3 << 16)
+-  { 2, 16, NULL, NULL, 0 },
+-
+-  /* The SR field in an X form instruction.  */
+-#define SR SPRG + 1
+-  { 4, 16, NULL, NULL, 0 },
+-
+-  /* The STRM field in an X AltiVec form instruction.  */
+-#define STRM SR + 1
+-#define STRM_MASK (0x3 << 21)
+-  { 2, 21, NULL, NULL, 0 },
+-
+-  /* The SV field in a POWER SC form instruction.  */
+-#define SV STRM + 1
+-  { 14, 2, NULL, NULL, 0 },
+-
+-  /* The TBR field in an XFX form instruction.  This is like the SPR
+-     field, but it is optional.  */
+-#define TBR SV + 1
+-  { 10, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
+-
+-  /* The TO field in a D or X form instruction.  */
+-#define TO TBR + 1
+-#define TO_MASK (0x1f << 21)
+-  { 5, 21, NULL, NULL, 0 },
+-
+-  /* The U field in an X form instruction.  */
+-#define U TO + 1
+-  { 4, 12, NULL, NULL, 0 },
+-
+-  /* The UI field in a D form instruction.  */
+-#define UI U + 1
+-  { 16, 0, NULL, NULL, 0 },
+-
+-  /* The VA field in a VA, VX or VXR form instruction.  */
+-#define VA UI + 1
+-#define VA_MASK	(0x1f << 16)
+-  { 5, 16, NULL, NULL, PPC_OPERAND_VR },
+-
+-  /* The VB field in a VA, VX or VXR form instruction.  */
+-#define VB VA + 1
+-#define VB_MASK (0x1f << 11)
+-  { 5, 11, NULL, NULL, PPC_OPERAND_VR },
+-
+-  /* The VC field in a VA form instruction.  */
+-#define VC VB + 1
+-#define VC_MASK (0x1f << 6)
+-  { 5, 6, NULL, NULL, PPC_OPERAND_VR },
+-
+-  /* The VD or VS field in a VA, VX, VXR or X form instruction.  */
+-#define VD VC + 1
+-#define VS VD
+-#define VD_MASK (0x1f << 21)
+-  { 5, 21, NULL, NULL, PPC_OPERAND_VR },
+-
+-  /* The SIMM field in a VX form instruction.  */
+-#define SIMM VD + 1
+-  { 5, 16, NULL, NULL, PPC_OPERAND_SIGNED},
+-
+-  /* The UIMM field in a VX form instruction.  */
+-#define UIMM SIMM + 1
+-  { 5, 16, NULL, NULL, 0 },
+-
+-  /* The SHB field in a VA form instruction.  */
+-#define SHB UIMM + 1
+-  { 4, 6, NULL, NULL, 0 },
+-
+-  /* The other UIMM field in a EVX form instruction.  */
+-#define EVUIMM SHB + 1
+-  { 5, 11, NULL, NULL, 0 },
+-
+-  /* The other UIMM field in a half word EVX form instruction.  */
+-#define EVUIMM_2 EVUIMM + 1
+-  { 32, 11, insert_ev2, extract_ev2, PPC_OPERAND_PARENS },
+-
+-  /* The other UIMM field in a word EVX form instruction.  */
+-#define EVUIMM_4 EVUIMM_2 + 1
+-  { 32, 11, insert_ev4, extract_ev4, PPC_OPERAND_PARENS },
+-
+-  /* The other UIMM field in a double EVX form instruction.  */
+-#define EVUIMM_8 EVUIMM_4 + 1
+-  { 32, 11, insert_ev8, extract_ev8, PPC_OPERAND_PARENS },
+-
+-  /* The WS field.  */
+-#define WS EVUIMM_8 + 1
+-#define WS_MASK (0x7 << 11)
+-  { 3, 11, NULL, NULL, 0 },
+-
+-  /* The L field in an mtmsrd instruction */
+-#define MTMSRD_L WS + 1
+-  { 1, 16, NULL, NULL, PPC_OPERAND_OPTIONAL },
+-
+-};
+-
+-/* The functions used to insert and extract complicated operands.  */
+-
+-/* The BA field in an XL form instruction when it must be the same as
+-   the BT field in the same instruction.  This operand is marked FAKE.
+-   The insertion function just copies the BT field into the BA field,
+-   and the extraction function just checks that the fields are the
+-   same.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_bat (unsigned long insn,
+-	    long value ATTRIBUTE_UNUSED,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  return insn | (((insn >> 21) & 0x1f) << 16);
+-}
+-
+-static long
+-extract_bat (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid)
+-{
+-  if (((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f))
+-    *invalid = 1;
+-  return 0;
+-}
+-
+-/* The BB field in an XL form instruction when it must be the same as
+-   the BA field in the same instruction.  This operand is marked FAKE.
+-   The insertion function just copies the BA field into the BB field,
+-   and the extraction function just checks that the fields are the
+-   same.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_bba (unsigned long insn,
+-	    long value ATTRIBUTE_UNUSED,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  return insn | (((insn >> 16) & 0x1f) << 11);
+-}
+-
+-static long
+-extract_bba (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid)
+-{
+-  if (((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f))
+-    *invalid = 1;
+-  return 0;
+-}
+-
+-/* The BD field in a B form instruction.  The lower two bits are
+-   forced to zero.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_bd (unsigned long insn,
+-	   long value,
+-	   int dialect ATTRIBUTE_UNUSED,
+-	   const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  return insn | (value & 0xfffc);
+-}
+-
+-/*ARGSUSED*/
+-static long
+-extract_bd (unsigned long insn,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
+-}
+-
+-/* The BD field in a B form instruction when the - modifier is used.
+-   This modifier means that the branch is not expected to be taken.
+-   For chips built to versions of the architecture prior to version 2
+-   (ie. not Power4 compatible), we set the y bit of the BO field to 1
+-   if the offset is negative.  When extracting, we require that the y
+-   bit be 1 and that the offset be positive, since if the y bit is 0
+-   we just want to print the normal form of the instruction.
+-   Power4 compatible targets use two bits, "a", and "t", instead of
+-   the "y" bit.  "at" == 00 => no hint, "at" == 01 => unpredictable,
+-   "at" == 10 => not taken, "at" == 11 => taken.  The "t" bit is 00001
+-   in BO field, the "a" bit is 00010 for branch on CR(BI) and 01000
+-   for branch on CTR.  We only handle the taken/not-taken hint here.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_bdm (unsigned long insn,
+-	    long value,
+-	    int dialect,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  if ((dialect & PPC_OPCODE_POWER4) == 0)
+-    {
+-      if ((value & 0x8000) != 0)
+-	insn |= 1 << 21;
+-    }
+-  else
+-    {
+-      if ((insn & (0x14 << 21)) == (0x04 << 21))
+-	insn |= 0x02 << 21;
+-      else if ((insn & (0x14 << 21)) == (0x10 << 21))
+-	insn |= 0x08 << 21;
+-    }
+-  return insn | (value & 0xfffc);
+-}
+-
+-static long
+-extract_bdm (unsigned long insn,
+-	     int dialect,
+-	     int *invalid)
+-{
+-  if ((dialect & PPC_OPCODE_POWER4) == 0)
+-    {
+-      if (((insn & (1 << 21)) == 0) != ((insn & (1 << 15)) == 0))
+-	*invalid = 1;
+-    }
+-  else
+-    {
+-      if ((insn & (0x17 << 21)) != (0x06 << 21)
+-	  && (insn & (0x1d << 21)) != (0x18 << 21))
+-	*invalid = 1;
+-    }
+-
+-  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
+-}
+-
+-/* The BD field in a B form instruction when the + modifier is used.
+-   This is like BDM, above, except that the branch is expected to be
+-   taken.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_bdp (unsigned long insn,
+-	    long value,
+-	    int dialect,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  if ((dialect & PPC_OPCODE_POWER4) == 0)
+-    {
+-      if ((value & 0x8000) == 0)
+-	insn |= 1 << 21;
+-    }
+-  else
+-    {
+-      if ((insn & (0x14 << 21)) == (0x04 << 21))
+-	insn |= 0x03 << 21;
+-      else if ((insn & (0x14 << 21)) == (0x10 << 21))
+-	insn |= 0x09 << 21;
+-    }
+-  return insn | (value & 0xfffc);
+-}
+-
+-static long
+-extract_bdp (unsigned long insn,
+-	     int dialect,
+-	     int *invalid)
+-{
+-  if ((dialect & PPC_OPCODE_POWER4) == 0)
+-    {
+-      if (((insn & (1 << 21)) == 0) == ((insn & (1 << 15)) == 0))
+-	*invalid = 1;
+-    }
+-  else
+-    {
+-      if ((insn & (0x17 << 21)) != (0x07 << 21)
+-	  && (insn & (0x1d << 21)) != (0x19 << 21))
+-	*invalid = 1;
+-    }
+-
+-  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
+-}
+-
+-/* Check for legal values of a BO field.  */
+-
+-static int
+-valid_bo (long value, int dialect)
+-{
+-  if ((dialect & PPC_OPCODE_POWER4) == 0)
+-    {
+-      /* Certain encodings have bits that are required to be zero.
+-	 These are (z must be zero, y may be anything):
+-	     001zy
+-	     011zy
+-	     1z00y
+-	     1z01y
+-	     1z1zz
+-      */
+-      switch (value & 0x14)
+-	{
+-	default:
+-	case 0:
+-	  return 1;
+-	case 0x4:
+-	  return (value & 0x2) == 0;
+-	case 0x10:
+-	  return (value & 0x8) == 0;
+-	case 0x14:
+-	  return value == 0x14;
+-	}
+-    }
+-  else
+-    {
+-      /* Certain encodings have bits that are required to be zero.
+-	 These are (z must be zero, a & t may be anything):
+-	     0000z
+-	     0001z
+-	     0100z
+-	     0101z
+-	     001at
+-	     011at
+-	     1a00t
+-	     1a01t
+-	     1z1zz
+-      */
+-      if ((value & 0x14) == 0)
+-	return (value & 0x1) == 0;
+-      else if ((value & 0x14) == 0x14)
+-	return value == 0x14;
+-      else
+-	return 1;
+-    }
+-}
+-
+-/* The BO field in a B form instruction.  Warn about attempts to set
+-   the field to an illegal value.  */
+-
+-static unsigned long
+-insert_bo (unsigned long insn,
+-	   long value,
+-	   int dialect,
+-	   const char **errmsg)
+-{
+-  if (!valid_bo (value, dialect))
+-    *errmsg = _("invalid conditional option");
+-  return insn | ((value & 0x1f) << 21);
+-}
+-
+-static long
+-extract_bo (unsigned long insn,
+-	    int dialect,
+-	    int *invalid)
+-{
+-  long value;
+-
+-  value = (insn >> 21) & 0x1f;
+-  if (!valid_bo (value, dialect))
+-    *invalid = 1;
+-  return value;
+-}
+-
+-/* The BO field in a B form instruction when the + or - modifier is
+-   used.  This is like the BO field, but it must be even.  When
+-   extracting it, we force it to be even.  */
+-
+-static unsigned long
+-insert_boe (unsigned long insn,
+-	    long value,
+-	    int dialect,
+-	    const char **errmsg)
+-{
+-  if (!valid_bo (value, dialect))
+-    *errmsg = _("invalid conditional option");
+-  else if ((value & 1) != 0)
+-    *errmsg = _("attempt to set y bit when using + or - modifier");
+-
+-  return insn | ((value & 0x1f) << 21);
+-}
+-
+-static long
+-extract_boe (unsigned long insn,
+-	     int dialect,
+-	     int *invalid)
+-{
+-  long value;
+-
+-  value = (insn >> 21) & 0x1f;
+-  if (!valid_bo (value, dialect))
+-    *invalid = 1;
+-  return value & 0x1e;
+-}
+-
+-/* The DQ field in a DQ form instruction.  This is like D, but the
+-   lower four bits are forced to zero. */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_dq (unsigned long insn,
+-	   long value,
+-	   int dialect ATTRIBUTE_UNUSED,
+-	   const char **errmsg)
+-{
+-  if ((value & 0xf) != 0)
+-    *errmsg = _("offset not a multiple of 16");
+-  return insn | (value & 0xfff0);
+-}
+-
+-/*ARGSUSED*/
+-static long
+-extract_dq (unsigned long insn,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return ((insn & 0xfff0) ^ 0x8000) - 0x8000;
+-}
+-
+-static unsigned long
+-insert_ev2 (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  if ((value & 1) != 0)
+-    *errmsg = _("offset not a multiple of 2");
+-  if ((value > 62) != 0)
+-    *errmsg = _("offset greater than 62");
+-  return insn | ((value & 0x3e) << 10);
+-}
+-
+-static long
+-extract_ev2 (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return (insn >> 10) & 0x3e;
+-}
+-
+-static unsigned long
+-insert_ev4 (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  if ((value & 3) != 0)
+-    *errmsg = _("offset not a multiple of 4");
+-  if ((value > 124) != 0)
+-    *errmsg = _("offset greater than 124");
+-  return insn | ((value & 0x7c) << 9);
+-}
+-
+-static long
+-extract_ev4 (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return (insn >> 9) & 0x7c;
+-}
+-
+-static unsigned long
+-insert_ev8 (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  if ((value & 7) != 0)
+-    *errmsg = _("offset not a multiple of 8");
+-  if ((value > 248) != 0)
+-    *errmsg = _("offset greater than 248");
+-  return insn | ((value & 0xf8) << 8);
+-}
+-
+-static long
+-extract_ev8 (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return (insn >> 8) & 0xf8;
+-}
+-
+-/* The DS field in a DS form instruction.  This is like D, but the
+-   lower two bits are forced to zero.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_ds (unsigned long insn,
+-	   long value,
+-	   int dialect ATTRIBUTE_UNUSED,
+-	   const char **errmsg)
+-{
+-  if ((value & 3) != 0)
+-    *errmsg = _("offset not a multiple of 4");
+-  return insn | (value & 0xfffc);
+-}
+-
+-/*ARGSUSED*/
+-static long
+-extract_ds (unsigned long insn,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
+-}
+-
+-/* The DE field in a DE form instruction.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_de (unsigned long insn,
+-	   long value,
+-	   int dialect ATTRIBUTE_UNUSED,
+-	   const char **errmsg)
+-{
+-  if (value > 2047 || value < -2048)
+-    *errmsg = _("offset not between -2048 and 2047");
+-  return insn | ((value << 4) & 0xfff0);
+-}
+-
+-/*ARGSUSED*/
+-static long
+-extract_de (unsigned long insn,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return (insn & 0xfff0) >> 4;
+-}
+-
+-/* The DES field in a DES form instruction.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_des (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  if (value > 8191 || value < -8192)
+-    *errmsg = _("offset not between -8192 and 8191");
+-  else if ((value & 3) != 0)
+-    *errmsg = _("offset not a multiple of 4");
+-  return insn | ((value << 2) & 0xfff0);
+-}
+-
+-/*ARGSUSED*/
+-static long
+-extract_des (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return (((insn >> 2) & 0x3ffc) ^ 0x2000) - 0x2000;
+-}
+-
+-/* FXM mask in mfcr and mtcrf instructions.  */
+-
+-static unsigned long
+-insert_fxm (unsigned long insn,
+-	    long value,
+-	    int dialect,
+-	    const char **errmsg)
+-{
+-  /* If the optional field on mfcr is missing that means we want to use
+-     the old form of the instruction that moves the whole cr.  In that
+-     case we'll have VALUE zero.  There doesn't seem to be a way to
+-     distinguish this from the case where someone writes mfcr %r3,0.  */
+-  if (value == 0)
+-    ;
+-
+-  /* If only one bit of the FXM field is set, we can use the new form
+-     of the instruction, which is faster.  Unlike the Power4 branch hint
+-     encoding, this is not backward compatible.  */
+-  else if ((dialect & PPC_OPCODE_POWER4) != 0 && (value & -value) == value)
+-    insn |= 1 << 20;
+-
+-  /* Any other value on mfcr is an error.  */
+-  else if ((insn & (0x3ff << 1)) == 19 << 1)
+-    {
+-      *errmsg = _("ignoring invalid mfcr mask");
+-      value = 0;
+-    }
+-
+-  return insn | ((value & 0xff) << 12);
+-}
+-
+-static long
+-extract_fxm (unsigned long insn,
+-	     int dialect,
+-	     int *invalid)
+-{
+-  long mask = (insn >> 12) & 0xff;
+-
+-  /* Is this a Power4 insn?  */
+-  if ((insn & (1 << 20)) != 0)
+-    {
+-      if ((dialect & PPC_OPCODE_POWER4) == 0)
+-	*invalid = 1;
+-      else
+-	{
+-	  /* Exactly one bit of MASK should be set.  */
+-	  if (mask == 0 || (mask & -mask) != mask)
+-	    *invalid = 1;
+-	}
+-    }
+-
+-  /* Check that non-power4 form of mfcr has a zero MASK.  */
+-  else if ((insn & (0x3ff << 1)) == 19 << 1)
+-    {
+-      if (mask != 0)
+-	*invalid = 1;
+-    }
+-
+-  return mask;
+-}
+-
+-/* The LI field in an I form instruction.  The lower two bits are
+-   forced to zero.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_li (unsigned long insn,
+-	   long value,
+-	   int dialect ATTRIBUTE_UNUSED,
+-	   const char **errmsg)
+-{
+-  if ((value & 3) != 0)
+-    *errmsg = _("ignoring least significant bits in branch offset");
+-  return insn | (value & 0x3fffffc);
+-}
+-
+-/*ARGSUSED*/
+-static long
+-extract_li (unsigned long insn,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return ((insn & 0x3fffffc) ^ 0x2000000) - 0x2000000;
+-}
+-
+-/* The MB and ME fields in an M form instruction expressed as a single
+-   operand which is itself a bitmask.  The extraction function always
+-   marks it as invalid, since we never want to recognize an
+-   instruction which uses a field of this type.  */
+-
+-static unsigned long
+-insert_mbe (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  unsigned long uval, mask;
+-  int mb, me, mx, count, last;
+-
+-  uval = value;
+-
+-  if (uval == 0)
+-    {
+-      *errmsg = _("illegal bitmask");
+-      return insn;
+-    }
+-
+-  mb = 0;
+-  me = 32;
+-  if ((uval & 1) != 0)
+-    last = 1;
+-  else
+-    last = 0;
+-  count = 0;
+-
+-  /* mb: location of last 0->1 transition */
+-  /* me: location of last 1->0 transition */
+-  /* count: # transitions */
+-
+-  for (mx = 0, mask = 1L << 31; mx < 32; ++mx, mask >>= 1)
+-    {
+-      if ((uval & mask) && !last)
+-	{
+-	  ++count;
+-	  mb = mx;
+-	  last = 1;
+-	}
+-      else if (!(uval & mask) && last)
+-	{
+-	  ++count;
+-	  me = mx;
+-	  last = 0;
+-	}
+-    }
+-  if (me == 0)
+-    me = 32;
+-
+-  if (count != 2 && (count != 0 || ! last))
+-    *errmsg = _("illegal bitmask");
+-
+-  return insn | (mb << 6) | ((me - 1) << 1);
+-}
+-
+-static long
+-extract_mbe (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid)
+-{
+-  long ret;
+-  int mb, me;
+-  int i;
+-
+-  *invalid = 1;
+-
+-  mb = (insn >> 6) & 0x1f;
+-  me = (insn >> 1) & 0x1f;
+-  if (mb < me + 1)
+-    {
+-      ret = 0;
+-      for (i = mb; i <= me; i++)
+-	ret |= 1L << (31 - i);
+-    }
+-  else if (mb == me + 1)
+-    ret = ~0;
+-  else /* (mb > me + 1) */
+-    {
+-      ret = ~0;
+-      for (i = me + 1; i < mb; i++)
+-	ret &= ~(1L << (31 - i));
+-    }
+-  return ret;
+-}
+-
+-/* The MB or ME field in an MD or MDS form instruction.  The high bit
+-   is wrapped to the low end.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_mb6 (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  return insn | ((value & 0x1f) << 6) | (value & 0x20);
+-}
+-
+-/*ARGSUSED*/
+-static long
+-extract_mb6 (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return ((insn >> 6) & 0x1f) | (insn & 0x20);
+-}
+-
+-/* The NB field in an X form instruction.  The value 32 is stored as
+-   0.  */
+-
+-static unsigned long
+-insert_nb (unsigned long insn,
+-	   long value,
+-	   int dialect ATTRIBUTE_UNUSED,
+-	   const char **errmsg)
+-{
+-  if (value < 0 || value > 32)
+-    *errmsg = _("value out of range");
+-  if (value == 32)
+-    value = 0;
+-  return insn | ((value & 0x1f) << 11);
+-}
+-
+-/*ARGSUSED*/
+-static long
+-extract_nb (unsigned long insn,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    int *invalid ATTRIBUTE_UNUSED)
+-{
+-  long ret;
+-
+-  ret = (insn >> 11) & 0x1f;
+-  if (ret == 0)
+-    ret = 32;
+-  return ret;
+-}
+-
+-/* The NSI field in a D form instruction.  This is the same as the SI
+-   field, only negated.  The extraction function always marks it as
+-   invalid, since we never want to recognize an instruction which uses
+-   a field of this type.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_nsi (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  return insn | (-value & 0xffff);
+-}
+-
+-static long
+-extract_nsi (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid)
+-{
+-  *invalid = 1;
+-  return -(((insn & 0xffff) ^ 0x8000) - 0x8000);
+-}
+-
+-/* The RA field in a D or X form instruction which is an updating
+-   load, which means that the RA field may not be zero and may not
+-   equal the RT field.  */
+-
+-static unsigned long
+-insert_ral (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  if (value == 0
+-      || (unsigned long) value == ((insn >> 21) & 0x1f))
+-    *errmsg = "invalid register operand when updating";
+-  return insn | ((value & 0x1f) << 16);
+-}
+-
+-/* The RA field in an lmw instruction, which has special value
+-   restrictions.  */
+-
+-static unsigned long
+-insert_ram (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  if ((unsigned long) value >= ((insn >> 21) & 0x1f))
+-    *errmsg = _("index register in load range");
+-  return insn | ((value & 0x1f) << 16);
+-}
+-
+-/* The RA field in the DQ form lq instruction, which has special
+-   value restrictions.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_raq (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  long rtvalue = (insn & RT_MASK) >> 21;
+-
+-  if (value == rtvalue)
+-    *errmsg = _("source and target register operands must be different");
+-  return insn | ((value & 0x1f) << 16);
+-}
+-
+-/* The RA field in a D or X form instruction which is an updating
+-   store or an updating floating point load, which means that the RA
+-   field may not be zero.  */
+-
+-static unsigned long
+-insert_ras (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  if (value == 0)
+-    *errmsg = _("invalid register operand when updating");
+-  return insn | ((value & 0x1f) << 16);
+-}
+-
+-/* The RB field in an X form instruction when it must be the same as
+-   the RS field in the instruction.  This is used for extended
+-   mnemonics like mr.  This operand is marked FAKE.  The insertion
+-   function just copies the BT field into the BA field, and the
+-   extraction function just checks that the fields are the same.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_rbs (unsigned long insn,
+-	    long value ATTRIBUTE_UNUSED,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  return insn | (((insn >> 21) & 0x1f) << 11);
+-}
+-
+-static long
+-extract_rbs (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid)
+-{
+-  if (((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f))
+-    *invalid = 1;
+-  return 0;
+-}
+-
+-/* The RT field of the DQ form lq instruction, which has special
+-   value restrictions.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_rtq (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  if ((value & 1) != 0)
+-    *errmsg = _("target register operand must be even");
+-  return insn | ((value & 0x1f) << 21);
+-}
+-
+-/* The RS field of the DS form stq instruction, which has special
+-   value restrictions.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_rsq (unsigned long insn,
+-	    long value ATTRIBUTE_UNUSED,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg)
+-{
+-  if ((value & 1) != 0)
+-    *errmsg = _("source register operand must be even");
+-  return insn | ((value & 0x1f) << 21);
+-}
+-
+-/* The SH field in an MD form instruction.  This is split.  */
+-
+-/*ARGSUSED*/
+-static unsigned long
+-insert_sh6 (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
+-}
+-
+-/*ARGSUSED*/
+-static long
+-extract_sh6 (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);
+-}
+-
+-/* The SPR field in an XFX form instruction.  This is flipped--the
+-   lower 5 bits are stored in the upper 5 and vice- versa.  */
+-
+-static unsigned long
+-insert_spr (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+-}
+-
+-static long
+-extract_spr (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid ATTRIBUTE_UNUSED)
+-{
+-  return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+-}
+-
+-/* The TBR field in an XFX instruction.  This is just like SPR, but it
+-   is optional.  When TBR is omitted, it must be inserted as 268 (the
+-   magic number of the TB register).  These functions treat 0
+-   (indicating an omitted optional operand) as 268.  This means that
+-   ``mftb 4,0'' is not handled correctly.  This does not matter very
+-   much, since the architecture manual does not define mftb as
+-   accepting any values other than 268 or 269.  */
+-
+-#define TB (268)
+-
+-static unsigned long
+-insert_tbr (unsigned long insn,
+-	    long value,
+-	    int dialect ATTRIBUTE_UNUSED,
+-	    const char **errmsg ATTRIBUTE_UNUSED)
+-{
+-  if (value == 0)
+-    value = TB;
+-  return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+-}
+-
+-static long
+-extract_tbr (unsigned long insn,
+-	     int dialect ATTRIBUTE_UNUSED,
+-	     int *invalid ATTRIBUTE_UNUSED)
+-{
+-  long ret;
+-
+-  ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+-  if (ret == TB)
+-    ret = 0;
+-  return ret;
+-}
+-
+-/* Macros used to form opcodes.  */
+-
+-/* The main opcode.  */
+-#define OP(x) ((((unsigned long)(x)) & 0x3f) << 26)
+-#define OP_MASK OP (0x3f)
+-
+-/* The main opcode combined with a trap code in the TO field of a D
+-   form instruction.  Used for extended mnemonics for the trap
+-   instructions.  */
+-#define OPTO(x,to) (OP (x) | ((((unsigned long)(to)) & 0x1f) << 21))
+-#define OPTO_MASK (OP_MASK | TO_MASK)
+-
+-/* The main opcode combined with a comparison size bit in the L field
+-   of a D form or X form instruction.  Used for extended mnemonics for
+-   the comparison instructions.  */
+-#define OPL(x,l) (OP (x) | ((((unsigned long)(l)) & 1) << 21))
+-#define OPL_MASK OPL (0x3f,1)
+-
+-/* An A form instruction.  */
+-#define A(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1) | (((unsigned long)(rc)) & 1))
+-#define A_MASK A (0x3f, 0x1f, 1)
+-
+-/* An A_MASK with the FRB field fixed.  */
+-#define AFRB_MASK (A_MASK | FRB_MASK)
+-
+-/* An A_MASK with the FRC field fixed.  */
+-#define AFRC_MASK (A_MASK | FRC_MASK)
+-
+-/* An A_MASK with the FRA and FRC fields fixed.  */
+-#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)
+-
+-/* A B form instruction.  */
+-#define B(op, aa, lk) (OP (op) | ((((unsigned long)(aa)) & 1) << 1) | ((lk) & 1))
+-#define B_MASK B (0x3f, 1, 1)
+-
+-/* A B form instruction setting the BO field.  */
+-#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21))
+-#define BBO_MASK BBO (0x3f, 0x1f, 1, 1)
+-
+-/* A BBO_MASK with the y bit of the BO field removed.  This permits
+-   matching a conditional branch regardless of the setting of the y
+-   bit.  Similarly for the 'at' bits used for power4 branch hints.  */
+-#define Y_MASK   (((unsigned long) 1) << 21)
+-#define AT1_MASK (((unsigned long) 3) << 21)
+-#define AT2_MASK (((unsigned long) 9) << 21)
+-#define BBOY_MASK  (BBO_MASK &~ Y_MASK)
+-#define BBOAT_MASK (BBO_MASK &~ AT1_MASK)
+-
+-/* A B form instruction setting the BO field and the condition bits of
+-   the BI field.  */
+-#define BBOCB(op, bo, cb, aa, lk) \
+-  (BBO ((op), (bo), (aa), (lk)) | ((((unsigned long)(cb)) & 0x3) << 16))
+-#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1)
+-
+-/* A BBOCB_MASK with the y bit of the BO field removed.  */
+-#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK)
+-#define BBOATCB_MASK (BBOCB_MASK &~ AT1_MASK)
+-#define BBOAT2CB_MASK (BBOCB_MASK &~ AT2_MASK)
+-
+-/* A BBOYCB_MASK in which the BI field is fixed.  */
+-#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK)
+-#define BBOATBI_MASK (BBOAT2CB_MASK | BI_MASK)
+-
+-/* An Context form instruction.  */
+-#define CTX(op, xop)   (OP (op) | (((unsigned long)(xop)) & 0x7))
+-#define CTX_MASK       CTX(0x3f, 0x7)
+-
+-/* An User Context form instruction.  */
+-#define UCTX(op, xop)  (OP (op) | (((unsigned long)(xop)) & 0x1f))
+-#define UCTX_MASK      UCTX(0x3f, 0x1f)
+-
+-/* The main opcode mask with the RA field clear.  */
+-#define DRA_MASK (OP_MASK | RA_MASK)
+-
+-/* A DS form instruction.  */
+-#define DSO(op, xop) (OP (op) | ((xop) & 0x3))
+-#define DS_MASK DSO (0x3f, 3)
+-
+-/* A DE form instruction.  */
+-#define DEO(op, xop) (OP (op) | ((xop) & 0xf))
+-#define DE_MASK DEO (0x3e, 0xf)
+-
+-/* An EVSEL form instruction.  */
+-#define EVSEL(op, xop) (OP (op) | (((unsigned long)(xop)) & 0xff) << 3)
+-#define EVSEL_MASK EVSEL(0x3f, 0xff)
+-
+-/* An M form instruction.  */
+-#define M(op, rc) (OP (op) | ((rc) & 1))
+-#define M_MASK M (0x3f, 1)
+-
+-/* An M form instruction with the ME field specified.  */
+-#define MME(op, me, rc) (M ((op), (rc)) | ((((unsigned long)(me)) & 0x1f) << 1))
+-
+-/* An M_MASK with the MB and ME fields fixed.  */
+-#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK)
+-
+-/* An M_MASK with the SH and ME fields fixed.  */
+-#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK)
+-
+-/* An MD form instruction.  */
+-#define MD(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x7) << 2) | ((rc) & 1))
+-#define MD_MASK MD (0x3f, 0x7, 1)
+-
+-/* An MD_MASK with the MB field fixed.  */
+-#define MDMB_MASK (MD_MASK | MB6_MASK)
+-
+-/* An MD_MASK with the SH field fixed.  */
+-#define MDSH_MASK (MD_MASK | SH6_MASK)
+-
+-/* An MDS form instruction.  */
+-#define MDS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0xf) << 1) | ((rc) & 1))
+-#define MDS_MASK MDS (0x3f, 0xf, 1)
+-
+-/* An MDS_MASK with the MB field fixed.  */
+-#define MDSMB_MASK (MDS_MASK | MB6_MASK)
+-
+-/* An SC form instruction.  */
+-#define SC(op, sa, lk) (OP (op) | ((((unsigned long)(sa)) & 1) << 1) | ((lk) & 1))
+-#define SC_MASK (OP_MASK | (((unsigned long)0x3ff) << 16) | (((unsigned long)1) << 1) | 1)
+-
+-/* An VX form instruction.  */
+-#define VX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7ff))
+-
+-/* The mask for an VX form instruction.  */
+-#define VX_MASK	VX(0x3f, 0x7ff)
+-
+-/* An VA form instruction.  */
+-#define VXA(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x03f))
+-
+-/* The mask for an VA form instruction.  */
+-#define VXA_MASK VXA(0x3f, 0x3f)
+-
+-/* An VXR form instruction.  */
+-#define VXR(op, xop, rc) (OP (op) | (((rc) & 1) << 10) | (((unsigned long)(xop)) & 0x3ff))
+-
+-/* The mask for a VXR form instruction.  */
+-#define VXR_MASK VXR(0x3f, 0x3ff, 1)
+-
+-/* An X form instruction.  */
+-#define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1))
+-
+-/* An X form instruction with the RC bit specified.  */
+-#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
+-
+-/* The mask for an X form instruction.  */
+-#define X_MASK XRC (0x3f, 0x3ff, 1)
+-
+-/* An X_MASK with the RA field fixed.  */
+-#define XRA_MASK (X_MASK | RA_MASK)
+-
+-/* An X_MASK with the RB field fixed.  */
+-#define XRB_MASK (X_MASK | RB_MASK)
+-
+-/* An X_MASK with the RT field fixed.  */
+-#define XRT_MASK (X_MASK | RT_MASK)
+-
+-/* An X_MASK with the RA and RB fields fixed.  */
+-#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
+-
+-/* An XRARB_MASK, but with the L bit clear.  */
+-#define XRLARB_MASK (XRARB_MASK & ~((unsigned long) 1 << 16))
+-
+-/* An X_MASK with the RT and RA fields fixed.  */
+-#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK)
+-
+-/* An XRTRA_MASK, but with L bit clear.  */
+-#define XRTLRA_MASK (XRTRA_MASK & ~((unsigned long) 1 << 21))
+-
+-/* An X form comparison instruction.  */
+-#define XCMPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21))
+-
+-/* The mask for an X form comparison instruction.  */
+-#define XCMP_MASK (X_MASK | (((unsigned long)1) << 22))
+-
+-/* The mask for an X form comparison instruction with the L field
+-   fixed.  */
+-#define XCMPL_MASK (XCMP_MASK | (((unsigned long)1) << 21))
+-
+-/* An X form trap instruction with the TO field specified.  */
+-#define XTO(op, xop, to) (X ((op), (xop)) | ((((unsigned long)(to)) & 0x1f) << 21))
+-#define XTO_MASK (X_MASK | TO_MASK)
+-
+-/* An X form tlb instruction with the SH field specified.  */
+-#define XTLB(op, xop, sh) (X ((op), (xop)) | ((((unsigned long)(sh)) & 0x1f) << 11))
+-#define XTLB_MASK (X_MASK | SH_MASK)
+-
+-/* An X form sync instruction.  */
+-#define XSYNC(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 3) << 21))
+-
+-/* An X form sync instruction with everything filled in except the LS field.  */
+-#define XSYNC_MASK (0xff9fffff)
+-
+-/* An X form AltiVec dss instruction.  */
+-#define XDSS(op, xop, a) (X ((op), (xop)) | ((((unsigned long)(a)) & 1) << 25))
+-#define XDSS_MASK XDSS(0x3f, 0x3ff, 1)
+-
+-/* An XFL form instruction.  */
+-#define XFL(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1) | (((unsigned long)(rc)) & 1))
+-#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (((unsigned long)1) << 25) | (((unsigned long)1) << 16))
+-
+-/* An X form isel instruction.  */
+-#define XISEL(op, xop)  (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1))
+-#define XISEL_MASK      XISEL(0x3f, 0x1f)
+-
+-/* An XL form instruction with the LK field set to 0.  */
+-#define XL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1))
+-
+-/* An XL form instruction which uses the LK field.  */
+-#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1))
+-
+-/* The mask for an XL form instruction.  */
+-#define XL_MASK XLLK (0x3f, 0x3ff, 1)
+-
+-/* An XL form instruction which explicitly sets the BO field.  */
+-#define XLO(op, bo, xop, lk) \
+-  (XLLK ((op), (xop), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21))
+-#define XLO_MASK (XL_MASK | BO_MASK)
+-
+-/* An XL form instruction which explicitly sets the y bit of the BO
+-   field.  */
+-#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | ((((unsigned long)(y)) & 1) << 21))
+-#define XLYLK_MASK (XL_MASK | Y_MASK)
+-
+-/* An XL form instruction which sets the BO field and the condition
+-   bits of the BI field.  */
+-#define XLOCB(op, bo, cb, xop, lk) \
+-  (XLO ((op), (bo), (xop), (lk)) | ((((unsigned long)(cb)) & 3) << 16))
+-#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1)
+-
+-/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed.  */
+-#define XLBB_MASK (XL_MASK | BB_MASK)
+-#define XLYBB_MASK (XLYLK_MASK | BB_MASK)
+-#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK)
+-
+-/* An XL_MASK with the BO and BB fields fixed.  */
+-#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK)
+-
+-/* An XL_MASK with the BO, BI and BB fields fixed.  */
+-#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK)
+-
+-/* An XO form instruction.  */
+-#define XO(op, xop, oe, rc) \
+-  (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1) | ((((unsigned long)(oe)) & 1) << 10) | (((unsigned long)(rc)) & 1))
+-#define XO_MASK XO (0x3f, 0x1ff, 1, 1)
+-
+-/* An XO_MASK with the RB field fixed.  */
+-#define XORB_MASK (XO_MASK | RB_MASK)
+-
+-/* An XS form instruction.  */
+-#define XS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 2) | (((unsigned long)(rc)) & 1))
+-#define XS_MASK XS (0x3f, 0x1ff, 1)
+-
+-/* A mask for the FXM version of an XFX form instruction.  */
+-#define XFXFXM_MASK (X_MASK | (1 << 11))
+-
+-/* An XFX form instruction with the FXM field filled in.  */
+-#define XFXM(op, xop, fxm) \
+-  (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12))
+-
+-/* An XFX form instruction with the SPR field filled in.  */
+-#define XSPR(op, xop, spr) \
+-  (X ((op), (xop)) | ((((unsigned long)(spr)) & 0x1f) << 16) | ((((unsigned long)(spr)) & 0x3e0) << 6))
+-#define XSPR_MASK (X_MASK | SPR_MASK)
+-
+-/* An XFX form instruction with the SPR field filled in except for the
+-   SPRBAT field.  */
+-#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK)
+-
+-/* An XFX form instruction with the SPR field filled in except for the
+-   SPRG field.  */
+-#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK)
+-
+-/* An X form instruction with everything filled in except the E field.  */
+-#define XE_MASK (0xffff7fff)
+-
+-/* An X form user context instruction.  */
+-#define XUC(op, xop)  (OP (op) | (((unsigned long)(xop)) & 0x1f))
+-#define XUC_MASK      XUC(0x3f, 0x1f)
+-
+-/* The BO encodings used in extended conditional branch mnemonics.  */
+-#define BODNZF	(0x0)
+-#define BODNZFP	(0x1)
+-#define BODZF	(0x2)
+-#define BODZFP	(0x3)
+-#define BODNZT	(0x8)
+-#define BODNZTP	(0x9)
+-#define BODZT	(0xa)
+-#define BODZTP	(0xb)
+-
+-#define BOF	(0x4)
+-#define BOFP	(0x5)
+-#define BOFM4	(0x6)
+-#define BOFP4	(0x7)
+-#define BOT	(0xc)
+-#define BOTP	(0xd)
+-#define BOTM4	(0xe)
+-#define BOTP4	(0xf)
+-
+-#define BODNZ	(0x10)
+-#define BODNZP	(0x11)
+-#define BODZ	(0x12)
+-#define BODZP	(0x13)
+-#define BODNZM4 (0x18)
+-#define BODNZP4 (0x19)
+-#define BODZM4	(0x1a)
+-#define BODZP4	(0x1b)
+-
+-#define BOU	(0x14)
+-
+-/* The BI condition bit encodings used in extended conditional branch
+-   mnemonics.  */
+-#define CBLT	(0)
+-#define CBGT	(1)
+-#define CBEQ	(2)
+-#define CBSO	(3)
+-
+-/* The TO encodings used in extended trap mnemonics.  */
+-#define TOLGT	(0x1)
+-#define TOLLT	(0x2)
+-#define TOEQ	(0x4)
+-#define TOLGE	(0x5)
+-#define TOLNL	(0x5)
+-#define TOLLE	(0x6)
+-#define TOLNG	(0x6)
+-#define TOGT	(0x8)
+-#define TOGE	(0xc)
+-#define TONL	(0xc)
+-#define TOLT	(0x10)
+-#define TOLE	(0x14)
+-#define TONG	(0x14)
+-#define TONE	(0x18)
+-#define TOU	(0x1f)
+-
+-/* Smaller names for the flags so each entry in the opcodes table will
+-   fit on a single line.  */
+-#undef	PPC
+-#define PPC     PPC_OPCODE_PPC
+-#define PPCCOM	PPC_OPCODE_PPC | PPC_OPCODE_COMMON
+-#define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM
+-#define POWER4	PPC_OPCODE_POWER4
+-#define PPC32   PPC_OPCODE_32 | PPC_OPCODE_PPC
+-#define PPC64   PPC_OPCODE_64 | PPC_OPCODE_PPC
+-#define PPC403	PPC_OPCODE_403
+-#define PPC405	PPC403
+-#define PPC440	PPC_OPCODE_440
+-#define PPC750	PPC
+-#define PPC860	PPC
+-#define PPCVEC	PPC_OPCODE_ALTIVEC | PPC_OPCODE_PPC
+-#define	POWER   PPC_OPCODE_POWER
+-#define	POWER2	PPC_OPCODE_POWER | PPC_OPCODE_POWER2
+-#define PPCPWR2	PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2
+-#define	POWER32	PPC_OPCODE_POWER | PPC_OPCODE_32
+-#define	COM     PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON
+-#define	COM32   PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_32
+-#define	M601    PPC_OPCODE_POWER | PPC_OPCODE_601
+-#define PWRCOM	PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON
+-#define	MFDEC1	PPC_OPCODE_POWER
+-#define	MFDEC2	PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_BOOKE
+-#define BOOKE	PPC_OPCODE_BOOKE
+-#define BOOKE64	PPC_OPCODE_BOOKE64
+-#define CLASSIC	PPC_OPCODE_CLASSIC
+-#define PPCSPE	PPC_OPCODE_SPE
+-#define PPCISEL	PPC_OPCODE_ISEL
+-#define PPCEFS	PPC_OPCODE_EFS
+-#define PPCBRLK	PPC_OPCODE_BRLOCK
+-#define PPCPMR	PPC_OPCODE_PMR
+-#define PPCCHLK	PPC_OPCODE_CACHELCK
+-#define PPCCHLK64	PPC_OPCODE_CACHELCK | PPC_OPCODE_BOOKE64
+-#define PPCRFMCI	PPC_OPCODE_RFMCI
+-
+-/* The opcode table.
+-
+-   The format of the opcode table is:
+-
+-   NAME	     OPCODE	MASK		FLAGS		{ OPERANDS }
+-
+-   NAME is the name of the instruction.
+-   OPCODE is the instruction opcode.
+-   MASK is the opcode mask; this is used to tell the disassembler
+-     which bits in the actual opcode must match OPCODE.
+-   FLAGS are flags indicated what processors support the instruction.
+-   OPERANDS is the list of operands.
+-
+-   The disassembler reads the table in order and prints the first
+-   instruction which matches, so this table is sorted to put more
+-   specific instructions before more general instructions.  It is also
+-   sorted by major opcode.  */
+-
+-const struct powerpc_opcode powerpc_opcodes[] = {
+-{ "attn",    X(0,256), X_MASK,		POWER4,		{ 0 } },
+-{ "tdlgti",  OPTO(2,TOLGT), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdllti",  OPTO(2,TOLLT), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdeqi",   OPTO(2,TOEQ), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdlgei",  OPTO(2,TOLGE), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdlnli",  OPTO(2,TOLNL), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdllei",  OPTO(2,TOLLE), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdlngi",  OPTO(2,TOLNG), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdgti",   OPTO(2,TOGT), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdgei",   OPTO(2,TOGE), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdnli",   OPTO(2,TONL), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdlti",   OPTO(2,TOLT), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdlei",   OPTO(2,TOLE), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdngi",   OPTO(2,TONG), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdnei",   OPTO(2,TONE), OPTO_MASK,	PPC64,		{ RA, SI } },
+-{ "tdi",     OP(2),	OP_MASK,	PPC64,		{ TO, RA, SI } },
+-
+-{ "twlgti",  OPTO(3,TOLGT), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tlgti",   OPTO(3,TOLGT), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twllti",  OPTO(3,TOLLT), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tllti",   OPTO(3,TOLLT), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "tweqi",   OPTO(3,TOEQ), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "teqi",    OPTO(3,TOEQ), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twlgei",  OPTO(3,TOLGE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tlgei",   OPTO(3,TOLGE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twlnli",  OPTO(3,TOLNL), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tlnli",   OPTO(3,TOLNL), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twllei",  OPTO(3,TOLLE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tllei",   OPTO(3,TOLLE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twlngi",  OPTO(3,TOLNG), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tlngi",   OPTO(3,TOLNG), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twgti",   OPTO(3,TOGT), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tgti",    OPTO(3,TOGT), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twgei",   OPTO(3,TOGE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tgei",    OPTO(3,TOGE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twnli",   OPTO(3,TONL), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tnli",    OPTO(3,TONL), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twlti",   OPTO(3,TOLT), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tlti",    OPTO(3,TOLT), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twlei",   OPTO(3,TOLE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tlei",    OPTO(3,TOLE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twngi",   OPTO(3,TONG), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tngi",    OPTO(3,TONG), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twnei",   OPTO(3,TONE), OPTO_MASK,	PPCCOM,		{ RA, SI } },
+-{ "tnei",    OPTO(3,TONE), OPTO_MASK,	PWRCOM,		{ RA, SI } },
+-{ "twi",     OP(3),	OP_MASK,	PPCCOM,		{ TO, RA, SI } },
+-{ "ti",      OP(3),	OP_MASK,	PWRCOM,		{ TO, RA, SI } },
+-
+-{ "macchw",	XO(4,172,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchw.",	XO(4,172,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwo",	XO(4,172,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwo.",	XO(4,172,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchws",	XO(4,236,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchws.",	XO(4,236,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwso",	XO(4,236,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwso.",	XO(4,236,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwsu",	XO(4,204,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwsu.",	XO(4,204,0,1), XO_MASK, PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwsuo",	XO(4,204,1,0), XO_MASK, PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwsuo.",	XO(4,204,1,1), XO_MASK, PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwu",	XO(4,140,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwu.",	XO(4,140,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwuo",	XO(4,140,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "macchwuo.",	XO(4,140,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhw",	XO(4,44,0,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhw.",	XO(4,44,0,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwo",	XO(4,44,1,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwo.",	XO(4,44,1,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhws",	XO(4,108,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhws.",	XO(4,108,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwso",	XO(4,108,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwso.",	XO(4,108,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwsu",	XO(4,76,0,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwsu.",	XO(4,76,0,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwsuo",	XO(4,76,1,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwsuo.",	XO(4,76,1,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwu",	XO(4,12,0,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwu.",	XO(4,12,0,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwuo",	XO(4,12,1,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "machhwuo.",	XO(4,12,1,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhw",	XO(4,428,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhw.",	XO(4,428,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwo",	XO(4,428,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwo.",	XO(4,428,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhws",	XO(4,492,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhws.",	XO(4,492,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwso",	XO(4,492,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwso.",	XO(4,492,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwsu",	XO(4,460,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwsu.",	XO(4,460,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwsuo",	XO(4,460,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwsuo.",	XO(4,460,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwu",	XO(4,396,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwu.",	XO(4,396,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwuo",	XO(4,396,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "maclhwuo.",	XO(4,396,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mulchw",	XRC(4,168,0),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mulchw.",	XRC(4,168,1),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mulchwu",	XRC(4,136,0),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mulchwu.",	XRC(4,136,1),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mulhhw",	XRC(4,40,0),   X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mulhhw.",	XRC(4,40,1),   X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mulhhwu",	XRC(4,8,0),    X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mulhhwu.",	XRC(4,8,1),    X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mullhw",	XRC(4,424,0),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mullhw.",	XRC(4,424,1),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mullhwu",	XRC(4,392,0),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mullhwu.",	XRC(4,392,1),  X_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmacchw",	XO(4,174,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmacchw.",	XO(4,174,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmacchwo",	XO(4,174,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmacchwo.",	XO(4,174,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmacchws",	XO(4,238,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmacchws.",	XO(4,238,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmacchwso",	XO(4,238,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmacchwso.",	XO(4,238,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmachhw",	XO(4,46,0,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmachhw.",	XO(4,46,0,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmachhwo",	XO(4,46,1,0),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmachhwo.",	XO(4,46,1,1),  XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmachhws",	XO(4,110,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmachhws.",	XO(4,110,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmachhwso",	XO(4,110,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmachhwso.",	XO(4,110,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmaclhw",	XO(4,430,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmaclhw.",	XO(4,430,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmaclhwo",	XO(4,430,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmaclhwo.",	XO(4,430,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmaclhws",	XO(4,494,0,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmaclhws.",	XO(4,494,0,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmaclhwso",	XO(4,494,1,0), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "nmaclhwso.",	XO(4,494,1,1), XO_MASK,	PPC405|PPC440,	{ RT, RA, RB } },
+-{ "mfvscr",  VX(4, 1540), VX_MASK,	PPCVEC,		{ VD } },
+-{ "mtvscr",  VX(4, 1604), VX_MASK,	PPCVEC,		{ VB } },
+-{ "vaddcuw", VX(4,  384), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vaddfp",  VX(4,   10), VX_MASK, 	PPCVEC,		{ VD, VA, VB } },
+-{ "vaddsbs", VX(4,  768), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vaddshs", VX(4,  832), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vaddsws", VX(4,  896), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vaddubm", VX(4,    0), VX_MASK, 	PPCVEC,		{ VD, VA, VB } },
+-{ "vaddubs", VX(4,  512), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vadduhm", VX(4,   64), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vadduhs", VX(4,  576), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vadduwm", VX(4,  128), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vadduws", VX(4,  640), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vand",    VX(4, 1028), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vandc",   VX(4, 1092), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vavgsb",  VX(4, 1282), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vavgsh",  VX(4, 1346), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vavgsw",  VX(4, 1410), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vavgub",  VX(4, 1026), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vavguh",  VX(4, 1090), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vavguw",  VX(4, 1154), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vcfsx",   VX(4,  842), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
+-{ "vcfux",   VX(4,  778), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
+-{ "vcmpbfp",   VXR(4, 966, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpbfp.",  VXR(4, 966, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpeqfp",  VXR(4, 198, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpeqfp.", VXR(4, 198, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpequb",  VXR(4,   6, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpequb.", VXR(4,   6, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpequh",  VXR(4,  70, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpequh.", VXR(4,  70, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpequw",  VXR(4, 134, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpequw.", VXR(4, 134, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgefp",  VXR(4, 454, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgefp.", VXR(4, 454, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtfp",  VXR(4, 710, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtfp.", VXR(4, 710, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtsb",  VXR(4, 774, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtsb.", VXR(4, 774, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtsh",  VXR(4, 838, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtsh.", VXR(4, 838, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtsw",  VXR(4, 902, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtsw.", VXR(4, 902, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtub",  VXR(4, 518, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtub.", VXR(4, 518, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtuh",  VXR(4, 582, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtuh.", VXR(4, 582, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtuw",  VXR(4, 646, 0), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vcmpgtuw.", VXR(4, 646, 1), VXR_MASK, PPCVEC,	{ VD, VA, VB } },
+-{ "vctsxs",    VX(4,  970), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
+-{ "vctuxs",    VX(4,  906), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
+-{ "vexptefp",  VX(4,  394), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vlogefp",   VX(4,  458), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vmaddfp",   VXA(4,  46), VXA_MASK,	PPCVEC,		{ VD, VA, VC, VB } },
+-{ "vmaxfp",    VX(4, 1034), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmaxsb",    VX(4,  258), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmaxsh",    VX(4,  322), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmaxsw",    VX(4,  386), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmaxub",    VX(4,    2), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmaxuh",    VX(4,   66), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmaxuw",    VX(4,  130), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmhaddshs", VXA(4,  32), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vmhraddshs", VXA(4, 33), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vminfp",    VX(4, 1098), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vminsb",    VX(4,  770), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vminsh",    VX(4,  834), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vminsw",    VX(4,  898), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vminub",    VX(4,  514), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vminuh",    VX(4,  578), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vminuw",    VX(4,  642), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmladduhm", VXA(4,  34), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vmrghb",    VX(4,   12), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmrghh",    VX(4,   76), VX_MASK,    PPCVEC,		{ VD, VA, VB } },
+-{ "vmrghw",    VX(4,  140), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmrglb",    VX(4,  268), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmrglh",    VX(4,  332), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmrglw",    VX(4,  396), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmsummbm",  VXA(4,  37), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vmsumshm",  VXA(4,  40), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vmsumshs",  VXA(4,  41), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vmsumubm",  VXA(4,  36), VXA_MASK,   PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vmsumuhm",  VXA(4,  38), VXA_MASK,   PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vmsumuhs",  VXA(4,  39), VXA_MASK,   PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vmulesb",   VX(4,  776), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmulesh",   VX(4,  840), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmuleub",   VX(4,  520), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmuleuh",   VX(4,  584), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmulosb",   VX(4,  264), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmulosh",   VX(4,  328), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmuloub",   VX(4,    8), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vmulouh",   VX(4,   72), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vnmsubfp",  VXA(4,  47), VXA_MASK,	PPCVEC,		{ VD, VA, VC, VB } },
+-{ "vnor",      VX(4, 1284), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vor",       VX(4, 1156), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vperm",     VXA(4,  43), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vpkpx",     VX(4,  782), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vpkshss",   VX(4,  398), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vpkshus",   VX(4,  270), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vpkswss",   VX(4,  462), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vpkswus",   VX(4,  334), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vpkuhum",   VX(4,   14), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vpkuhus",   VX(4,  142), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vpkuwum",   VX(4,   78), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vpkuwus",   VX(4,  206), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vrefp",     VX(4,  266), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vrfim",     VX(4,  714), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vrfin",     VX(4,  522), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vrfip",     VX(4,  650), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vrfiz",     VX(4,  586), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vrlb",      VX(4,    4), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vrlh",      VX(4,   68), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vrlw",      VX(4,  132), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vrsqrtefp", VX(4,  330), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vsel",      VXA(4,  42), VXA_MASK,	PPCVEC,		{ VD, VA, VB, VC } },
+-{ "vsl",       VX(4,  452), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vslb",      VX(4,  260), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsldoi",    VXA(4,  44), VXA_MASK,	PPCVEC,		{ VD, VA, VB, SHB } },
+-{ "vslh",      VX(4,  324), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vslo",      VX(4, 1036), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vslw",      VX(4,  388), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vspltb",    VX(4,  524), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
+-{ "vsplth",    VX(4,  588), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
+-{ "vspltisb",  VX(4,  780), VX_MASK,	PPCVEC,		{ VD, SIMM } },
+-{ "vspltish",  VX(4,  844), VX_MASK,	PPCVEC,		{ VD, SIMM } },
+-{ "vspltisw",  VX(4,  908), VX_MASK,	PPCVEC,		{ VD, SIMM } },
+-{ "vspltw",    VX(4,  652), VX_MASK,	PPCVEC,		{ VD, VB, UIMM } },
+-{ "vsr",       VX(4,  708), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsrab",     VX(4,  772), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsrah",     VX(4,  836), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsraw",     VX(4,  900), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsrb",      VX(4,  516), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsrh",      VX(4,  580), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsro",      VX(4, 1100), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsrw",      VX(4,  644), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsubcuw",   VX(4, 1408), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsubfp",    VX(4,   74), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsubsbs",   VX(4, 1792), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsubshs",   VX(4, 1856), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsubsws",   VX(4, 1920), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsububm",   VX(4, 1024), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsububs",   VX(4, 1536), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsubuhm",   VX(4, 1088), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsubuhs",   VX(4, 1600), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsubuwm",   VX(4, 1152), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsubuws",   VX(4, 1664), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsumsws",   VX(4, 1928), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsum2sws",  VX(4, 1672), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsum4sbs",  VX(4, 1800), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsum4shs",  VX(4, 1608), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vsum4ubs",  VX(4, 1544), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-{ "vupkhpx",   VX(4,  846), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vupkhsb",   VX(4,  526), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vupkhsh",   VX(4,  590), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vupklpx",   VX(4,  974), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vupklsb",   VX(4,  654), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vupklsh",   VX(4,  718), VX_MASK,	PPCVEC,		{ VD, VB } },
+-{ "vxor",      VX(4, 1220), VX_MASK,	PPCVEC,		{ VD, VA, VB } },
+-
+-{ "evaddw",    VX(4, 512), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evaddiw",   VX(4, 514), VX_MASK,	PPCSPE,		{ RS, RB, UIMM } },
+-{ "evsubfw",   VX(4, 516), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evsubw",    VX(4, 516), VX_MASK,	PPCSPE,		{ RS, RB, RA } },
+-{ "evsubifw",  VX(4, 518), VX_MASK,	PPCSPE,		{ RS, UIMM, RB } },
+-{ "evsubiw",   VX(4, 518), VX_MASK,	PPCSPE,		{ RS, RB, UIMM } },
+-{ "evabs",     VX(4, 520), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evneg",     VX(4, 521), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evextsb",   VX(4, 522), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evextsh",   VX(4, 523), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evrndw",    VX(4, 524), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evcntlzw",  VX(4, 525), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evcntlsw",  VX(4, 526), VX_MASK,	PPCSPE,		{ RS, RA } },
+-
+-{ "brinc",     VX(4, 527), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evand",     VX(4, 529), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evandc",    VX(4, 530), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmr",      VX(4, 535), VX_MASK,	PPCSPE,		{ RS, RA, BBA } },
+-{ "evor",      VX(4, 535), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evorc",     VX(4, 539), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evxor",     VX(4, 534), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "eveqv",     VX(4, 537), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evnand",    VX(4, 542), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evnot",     VX(4, 536), VX_MASK,	PPCSPE,		{ RS, RA, BBA } },
+-{ "evnor",     VX(4, 536), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evrlw",     VX(4, 552), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evrlwi",    VX(4, 554), VX_MASK,	PPCSPE,		{ RS, RA, EVUIMM } },
+-{ "evslw",     VX(4, 548), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evslwi",    VX(4, 550), VX_MASK,	PPCSPE,		{ RS, RA, EVUIMM } },
+-{ "evsrws",    VX(4, 545), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evsrwu",    VX(4, 544), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evsrwis",   VX(4, 547), VX_MASK,	PPCSPE,		{ RS, RA, EVUIMM } },
+-{ "evsrwiu",   VX(4, 546), VX_MASK,	PPCSPE,		{ RS, RA, EVUIMM } },
+-{ "evsplati",  VX(4, 553), VX_MASK,	PPCSPE,		{ RS, SIMM } },
+-{ "evsplatfi", VX(4, 555), VX_MASK,	PPCSPE,		{ RS, SIMM } },
+-{ "evmergehi", VX(4, 556), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmergelo", VX(4, 557), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmergehilo",VX(4,558), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmergelohi",VX(4,559), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evcmpgts",  VX(4, 561), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evcmpgtu",  VX(4, 560), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evcmplts",  VX(4, 563), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evcmpltu",  VX(4, 562), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evcmpeq",   VX(4, 564), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evsel",     EVSEL(4,79),EVSEL_MASK,	PPCSPE,		{ RS, RA, RB, CRFS } },
+-
+-{ "evldd",     VX(4, 769), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
+-{ "evlddx",    VX(4, 768), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evldw",     VX(4, 771), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
+-{ "evldwx",    VX(4, 770), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evldh",     VX(4, 773), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
+-{ "evldhx",    VX(4, 772), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evlwhe",    VX(4, 785), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
+-{ "evlwhex",   VX(4, 784), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evlwhou",   VX(4, 789), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
+-{ "evlwhoux",  VX(4, 788), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evlwhos",   VX(4, 791), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
+-{ "evlwhosx",  VX(4, 790), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evlwwsplat",VX(4, 793), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
+-{ "evlwwsplatx",VX(4, 792), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evlwhsplat",VX(4, 797), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
+-{ "evlwhsplatx",VX(4, 796), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evlhhesplat",VX(4, 777), VX_MASK,	PPCSPE,		{ RS, EVUIMM_2, RA } },
+-{ "evlhhesplatx",VX(4, 776), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evlhhousplat",VX(4, 781), VX_MASK,	PPCSPE,		{ RS, EVUIMM_2, RA } },
+-{ "evlhhousplatx",VX(4, 780), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evlhhossplat",VX(4, 783), VX_MASK,	PPCSPE,		{ RS, EVUIMM_2, RA } },
+-{ "evlhhossplatx",VX(4, 782), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evstdd",    VX(4, 801), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
+-{ "evstddx",   VX(4, 800), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evstdw",    VX(4, 803), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
+-{ "evstdwx",   VX(4, 802), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evstdh",    VX(4, 805), VX_MASK,	PPCSPE,		{ RS, EVUIMM_8, RA } },
+-{ "evstdhx",   VX(4, 804), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evstwwe",   VX(4, 825), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
+-{ "evstwwex",  VX(4, 824), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evstwwo",   VX(4, 829), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
+-{ "evstwwox",  VX(4, 828), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evstwhe",   VX(4, 817), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
+-{ "evstwhex",  VX(4, 816), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evstwho",   VX(4, 821), VX_MASK,	PPCSPE,		{ RS, EVUIMM_4, RA } },
+-{ "evstwhox",  VX(4, 820), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evfsabs",   VX(4, 644), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evfsnabs",  VX(4, 645), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evfsneg",   VX(4, 646), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evfsadd",   VX(4, 640), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evfssub",   VX(4, 641), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evfsmul",   VX(4, 648), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evfsdiv",   VX(4, 649), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evfscmpgt", VX(4, 652), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evfscmplt", VX(4, 653), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evfscmpeq", VX(4, 654), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evfststgt", VX(4, 668), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evfststlt", VX(4, 669), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evfststeq", VX(4, 670), VX_MASK,	PPCSPE,		{ CRFD, RA, RB } },
+-{ "evfscfui",  VX(4, 656), VX_MASK,	PPCSPE,		{ RS, RB } },
+-{ "evfsctuiz", VX(4, 664), VX_MASK,	PPCSPE,		{ RS, RB } },
+-{ "evfscfsi",  VX(4, 657), VX_MASK,	PPCSPE,		{ RS, RB } },
+-{ "evfscfuf",  VX(4, 658), VX_MASK,	PPCSPE,		{ RS, RB } },
+-{ "evfscfsf",  VX(4, 659), VX_MASK,	PPCSPE,		{ RS, RB } },
+-{ "evfsctui",  VX(4, 660), VX_MASK,	PPCSPE,		{ RS, RB } },
+-{ "evfsctsi",  VX(4, 661), VX_MASK,	PPCSPE,		{ RS, RB } },
+-{ "evfsctsiz", VX(4, 666), VX_MASK,	PPCSPE,		{ RS, RB } },
+-{ "evfsctuf",  VX(4, 662), VX_MASK,	PPCSPE,		{ RS, RB } },
+-{ "evfsctsf",  VX(4, 663), VX_MASK,	PPCSPE,		{ RS, RB } },
+-
+-{ "efsabs",   VX(4, 708), VX_MASK,	PPCEFS,		{ RS, RA } },
+-{ "efsnabs",  VX(4, 709), VX_MASK,	PPCEFS,		{ RS, RA } },
+-{ "efsneg",   VX(4, 710), VX_MASK,	PPCEFS,		{ RS, RA } },
+-{ "efsadd",   VX(4, 704), VX_MASK,	PPCEFS,		{ RS, RA, RB } },
+-{ "efssub",   VX(4, 705), VX_MASK,	PPCEFS,		{ RS, RA, RB } },
+-{ "efsmul",   VX(4, 712), VX_MASK,	PPCEFS,		{ RS, RA, RB } },
+-{ "efsdiv",   VX(4, 713), VX_MASK,	PPCEFS,		{ RS, RA, RB } },
+-{ "efscmpgt", VX(4, 716), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
+-{ "efscmplt", VX(4, 717), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
+-{ "efscmpeq", VX(4, 718), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
+-{ "efststgt", VX(4, 732), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
+-{ "efststlt", VX(4, 733), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
+-{ "efststeq", VX(4, 734), VX_MASK,	PPCEFS,		{ CRFD, RA, RB } },
+-{ "efscfui",  VX(4, 720), VX_MASK,	PPCEFS,		{ RS, RB } },
+-{ "efsctuiz", VX(4, 728), VX_MASK,	PPCEFS,		{ RS, RB } },
+-{ "efscfsi",  VX(4, 721), VX_MASK,	PPCEFS,		{ RS, RB } },
+-{ "efscfuf",  VX(4, 722), VX_MASK,	PPCEFS,		{ RS, RB } },
+-{ "efscfsf",  VX(4, 723), VX_MASK,	PPCEFS,		{ RS, RB } },
+-{ "efsctui",  VX(4, 724), VX_MASK,	PPCEFS,		{ RS, RB } },
+-{ "efsctsi",  VX(4, 725), VX_MASK,	PPCEFS,		{ RS, RB } },
+-{ "efsctsiz", VX(4, 730), VX_MASK,	PPCEFS,		{ RS, RB } },
+-{ "efsctuf",  VX(4, 726), VX_MASK,	PPCEFS,		{ RS, RB } },
+-{ "efsctsf",  VX(4, 727), VX_MASK,	PPCEFS,		{ RS, RB } },
+-
+-{ "evmhossf",  VX(4, 1031), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhossfa", VX(4, 1063), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhosmf",  VX(4, 1039), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhosmfa", VX(4, 1071), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhosmi",  VX(4, 1037), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhosmia", VX(4, 1069), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhoumi",  VX(4, 1036), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhoumia", VX(4, 1068), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhessf",  VX(4, 1027), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhessfa", VX(4, 1059), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhesmf",  VX(4, 1035), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhesmfa", VX(4, 1067), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhesmi",  VX(4, 1033), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhesmia", VX(4, 1065), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmheumi",  VX(4, 1032), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmheumia", VX(4, 1064), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmhossfaaw",VX(4, 1287), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhossiaaw",VX(4, 1285), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhosmfaaw",VX(4, 1295), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhosmiaaw",VX(4, 1293), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhousiaaw",VX(4, 1284), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhoumiaaw",VX(4, 1292), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhessfaaw",VX(4, 1283), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhessiaaw",VX(4, 1281), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhesmfaaw",VX(4, 1291), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhesmiaaw",VX(4, 1289), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmheusiaaw",VX(4, 1280), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmheumiaaw",VX(4, 1288), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmhossfanw",VX(4, 1415), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhossianw",VX(4, 1413), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhosmfanw",VX(4, 1423), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhosmianw",VX(4, 1421), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhousianw",VX(4, 1412), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhoumianw",VX(4, 1420), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhessfanw",VX(4, 1411), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhessianw",VX(4, 1409), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhesmfanw",VX(4, 1419), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhesmianw",VX(4, 1417), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmheusianw",VX(4, 1408), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmheumianw",VX(4, 1416), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmhogsmfaa",VX(4, 1327), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhogsmiaa",VX(4, 1325), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhogumiaa",VX(4, 1324), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhegsmfaa",VX(4, 1323), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhegsmiaa",VX(4, 1321), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhegumiaa",VX(4, 1320), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmhogsmfan",VX(4, 1455), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhogsmian",VX(4, 1453), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhogumian",VX(4, 1452), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhegsmfan",VX(4, 1451), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhegsmian",VX(4, 1449), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmhegumian",VX(4, 1448), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmwhssf",  VX(4, 1095), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwhssfa", VX(4, 1127), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwhsmf",  VX(4, 1103), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwhsmfa", VX(4, 1135), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwhsmi",  VX(4, 1101), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwhsmia", VX(4, 1133), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwhumi",  VX(4, 1100), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwhumia", VX(4, 1132), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmwlumi",  VX(4, 1096), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwlumia", VX(4, 1128), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmwlssiaaw",VX(4, 1345), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwlsmiaaw",VX(4, 1353), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwlusiaaw",VX(4, 1344), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwlumiaaw",VX(4, 1352), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmwlssianw",VX(4, 1473), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwlsmianw",VX(4, 1481), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwlusianw",VX(4, 1472), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwlumianw",VX(4, 1480), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmwssf",   VX(4, 1107), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwssfa",  VX(4, 1139), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwsmf",   VX(4, 1115), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwsmfa",  VX(4, 1147), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwsmi",   VX(4, 1113), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwsmia",  VX(4, 1145), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwumi",   VX(4, 1112), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwumia",  VX(4, 1144), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmwssfaa", VX(4, 1363), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwsmfaa", VX(4, 1371), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwsmiaa", VX(4, 1369), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwumiaa", VX(4, 1368), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evmwssfan", VX(4, 1491), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwsmfan", VX(4, 1499), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwsmian", VX(4, 1497), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evmwumian", VX(4, 1496), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "evaddssiaaw",VX(4, 1217), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evaddsmiaaw",VX(4, 1225), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evaddusiaaw",VX(4, 1216), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evaddumiaaw",VX(4, 1224), VX_MASK,	PPCSPE,		{ RS, RA } },
+-
+-{ "evsubfssiaaw",VX(4, 1219), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evsubfsmiaaw",VX(4, 1227), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evsubfusiaaw",VX(4, 1218), VX_MASK,	PPCSPE,		{ RS, RA } },
+-{ "evsubfumiaaw",VX(4, 1226), VX_MASK,	PPCSPE,		{ RS, RA } },
+-
+-{ "evmra",    VX(4, 1220), VX_MASK,	PPCSPE,		{ RS, RA } },
+-
+-{ "evdivws",  VX(4, 1222), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-{ "evdivwu",  VX(4, 1223), VX_MASK,	PPCSPE,		{ RS, RA, RB } },
+-
+-{ "mulli",   OP(7),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
+-{ "muli",    OP(7),	OP_MASK,	PWRCOM,		{ RT, RA, SI } },
+-
+-{ "subfic",  OP(8),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
+-{ "sfi",     OP(8),	OP_MASK,	PWRCOM,		{ RT, RA, SI } },
+-
+-{ "dozi",    OP(9),	OP_MASK,	M601,		{ RT, RA, SI } },
+-
+-{ "bce",     B(9,0,0),	B_MASK,		BOOKE64,	{ BO, BI, BD } },
+-{ "bcel",    B(9,0,1),	B_MASK,		BOOKE64,	{ BO, BI, BD } },
+-{ "bcea",    B(9,1,0),	B_MASK,		BOOKE64,	{ BO, BI, BDA } },
+-{ "bcela",   B(9,1,1),	B_MASK,		BOOKE64,	{ BO, BI, BDA } },
+-
+-{ "cmplwi",  OPL(10,0),	OPL_MASK,	PPCCOM,		{ OBF, RA, UI } },
+-{ "cmpldi",  OPL(10,1), OPL_MASK,	PPC64,		{ OBF, RA, UI } },
+-{ "cmpli",   OP(10),	OP_MASK,	PPC,		{ BF, L, RA, UI } },
+-{ "cmpli",   OP(10),	OP_MASK,	PWRCOM,		{ BF, RA, UI } },
+-
+-{ "cmpwi",   OPL(11,0),	OPL_MASK,	PPCCOM,		{ OBF, RA, SI } },
+-{ "cmpdi",   OPL(11,1),	OPL_MASK,	PPC64,		{ OBF, RA, SI } },
+-{ "cmpi",    OP(11),	OP_MASK,	PPC,		{ BF, L, RA, SI } },
+-{ "cmpi",    OP(11),	OP_MASK,	PWRCOM,		{ BF, RA, SI } },
+-
+-{ "addic",   OP(12),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
+-{ "ai",	     OP(12),	OP_MASK,	PWRCOM,		{ RT, RA, SI } },
+-{ "subic",   OP(12),	OP_MASK,	PPCCOM,		{ RT, RA, NSI } },
+-
+-{ "addic.",  OP(13),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
+-{ "ai.",     OP(13),	OP_MASK,	PWRCOM,		{ RT, RA, SI } },
+-{ "subic.",  OP(13),	OP_MASK,	PPCCOM,		{ RT, RA, NSI } },
+-
+-{ "li",	     OP(14),	DRA_MASK,	PPCCOM,		{ RT, SI } },
+-{ "lil",     OP(14),	DRA_MASK,	PWRCOM,		{ RT, SI } },
+-{ "addi",    OP(14),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
+-{ "cal",     OP(14),	OP_MASK,	PWRCOM,		{ RT, D, RA } },
+-{ "subi",    OP(14),	OP_MASK,	PPCCOM,		{ RT, RA, NSI } },
+-{ "la",	     OP(14),	OP_MASK,	PPCCOM,		{ RT, D, RA } },
+-
+-{ "lis",     OP(15),	DRA_MASK,	PPCCOM,		{ RT, SISIGNOPT } },
+-{ "liu",     OP(15),	DRA_MASK,	PWRCOM,		{ RT, SISIGNOPT } },
+-{ "addis",   OP(15),	OP_MASK,	PPCCOM,		{ RT,RA,SISIGNOPT } },
+-{ "cau",     OP(15),	OP_MASK,	PWRCOM,		{ RT,RA,SISIGNOPT } },
+-{ "subis",   OP(15),	OP_MASK,	PPCCOM,		{ RT, RA, NSI } },
+-
+-{ "bdnz-",   BBO(16,BODNZ,0,0),      BBOATBI_MASK, PPCCOM,	{ BDM } },
+-{ "bdnz+",   BBO(16,BODNZ,0,0),      BBOATBI_MASK, PPCCOM,	{ BDP } },
+-{ "bdnz",    BBO(16,BODNZ,0,0),      BBOATBI_MASK, PPCCOM,	{ BD } },
+-{ "bdn",     BBO(16,BODNZ,0,0),      BBOATBI_MASK, PWRCOM,	{ BD } },
+-{ "bdnzl-",  BBO(16,BODNZ,0,1),      BBOATBI_MASK, PPCCOM,	{ BDM } },
+-{ "bdnzl+",  BBO(16,BODNZ,0,1),      BBOATBI_MASK, PPCCOM,	{ BDP } },
+-{ "bdnzl",   BBO(16,BODNZ,0,1),      BBOATBI_MASK, PPCCOM,	{ BD } },
+-{ "bdnl",    BBO(16,BODNZ,0,1),      BBOATBI_MASK, PWRCOM,	{ BD } },
+-{ "bdnza-",  BBO(16,BODNZ,1,0),      BBOATBI_MASK, PPCCOM,	{ BDMA } },
+-{ "bdnza+",  BBO(16,BODNZ,1,0),      BBOATBI_MASK, PPCCOM,	{ BDPA } },
+-{ "bdnza",   BBO(16,BODNZ,1,0),      BBOATBI_MASK, PPCCOM,	{ BDA } },
+-{ "bdna",    BBO(16,BODNZ,1,0),      BBOATBI_MASK, PWRCOM,	{ BDA } },
+-{ "bdnzla-", BBO(16,BODNZ,1,1),      BBOATBI_MASK, PPCCOM,	{ BDMA } },
+-{ "bdnzla+", BBO(16,BODNZ,1,1),      BBOATBI_MASK, PPCCOM,	{ BDPA } },
+-{ "bdnzla",  BBO(16,BODNZ,1,1),      BBOATBI_MASK, PPCCOM,	{ BDA } },
+-{ "bdnla",   BBO(16,BODNZ,1,1),      BBOATBI_MASK, PWRCOM,	{ BDA } },
+-{ "bdz-",    BBO(16,BODZ,0,0),       BBOATBI_MASK, PPCCOM,	{ BDM } },
+-{ "bdz+",    BBO(16,BODZ,0,0),       BBOATBI_MASK, PPCCOM,	{ BDP } },
+-{ "bdz",     BBO(16,BODZ,0,0),       BBOATBI_MASK, COM,		{ BD } },
+-{ "bdzl-",   BBO(16,BODZ,0,1),       BBOATBI_MASK, PPCCOM,	{ BDM } },
+-{ "bdzl+",   BBO(16,BODZ,0,1),       BBOATBI_MASK, PPCCOM,	{ BDP } },
+-{ "bdzl",    BBO(16,BODZ,0,1),       BBOATBI_MASK, COM,		{ BD } },
+-{ "bdza-",   BBO(16,BODZ,1,0),       BBOATBI_MASK, PPCCOM,	{ BDMA } },
+-{ "bdza+",   BBO(16,BODZ,1,0),       BBOATBI_MASK, PPCCOM,	{ BDPA } },
+-{ "bdza",    BBO(16,BODZ,1,0),       BBOATBI_MASK, COM,		{ BDA } },
+-{ "bdzla-",  BBO(16,BODZ,1,1),       BBOATBI_MASK, PPCCOM,	{ BDMA } },
+-{ "bdzla+",  BBO(16,BODZ,1,1),       BBOATBI_MASK, PPCCOM,	{ BDPA } },
+-{ "bdzla",   BBO(16,BODZ,1,1),       BBOATBI_MASK, COM,		{ BDA } },
+-{ "blt-",    BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "blt+",    BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "blt",     BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bltl-",   BBOCB(16,BOT,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bltl+",   BBOCB(16,BOT,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bltl",    BBOCB(16,BOT,CBLT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "blta-",   BBOCB(16,BOT,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "blta+",   BBOCB(16,BOT,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "blta",    BBOCB(16,BOT,CBLT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bltla-",  BBOCB(16,BOT,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bltla+",  BBOCB(16,BOT,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bltla",   BBOCB(16,BOT,CBLT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bgt-",    BBOCB(16,BOT,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bgt+",    BBOCB(16,BOT,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bgt",     BBOCB(16,BOT,CBGT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bgtl-",   BBOCB(16,BOT,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bgtl+",   BBOCB(16,BOT,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bgtl",    BBOCB(16,BOT,CBGT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bgta-",   BBOCB(16,BOT,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bgta+",   BBOCB(16,BOT,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bgta",    BBOCB(16,BOT,CBGT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bgtla-",  BBOCB(16,BOT,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bgtla+",  BBOCB(16,BOT,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bgtla",   BBOCB(16,BOT,CBGT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "beq-",    BBOCB(16,BOT,CBEQ,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "beq+",    BBOCB(16,BOT,CBEQ,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "beq",     BBOCB(16,BOT,CBEQ,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "beql-",   BBOCB(16,BOT,CBEQ,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "beql+",   BBOCB(16,BOT,CBEQ,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "beql",    BBOCB(16,BOT,CBEQ,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "beqa-",   BBOCB(16,BOT,CBEQ,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "beqa+",   BBOCB(16,BOT,CBEQ,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "beqa",    BBOCB(16,BOT,CBEQ,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "beqla-",  BBOCB(16,BOT,CBEQ,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "beqla+",  BBOCB(16,BOT,CBEQ,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "beqla",   BBOCB(16,BOT,CBEQ,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bso-",    BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bso+",    BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bso",     BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bsol-",   BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bsol+",   BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bsol",    BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bsoa-",   BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bsoa+",   BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bsoa",    BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bsola-",  BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bsola+",  BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bsola",   BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bun-",    BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bun+",    BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bun",     BBOCB(16,BOT,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BD } },
+-{ "bunl-",   BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bunl+",   BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bunl",    BBOCB(16,BOT,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BD } },
+-{ "buna-",   BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "buna+",   BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "buna",    BBOCB(16,BOT,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDA } },
+-{ "bunla-",  BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bunla+",  BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bunla",   BBOCB(16,BOT,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDA } },
+-{ "bge-",    BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bge+",    BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bge",     BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bgel-",   BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bgel+",   BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bgel",    BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bgea-",   BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bgea+",   BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bgea",    BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bgela-",  BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bgela+",  BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bgela",   BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bnl-",    BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bnl+",    BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bnl",     BBOCB(16,BOF,CBLT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bnll-",   BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bnll+",   BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bnll",    BBOCB(16,BOF,CBLT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bnla-",   BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bnla+",   BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bnla",    BBOCB(16,BOF,CBLT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bnlla-",  BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bnlla+",  BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bnlla",   BBOCB(16,BOF,CBLT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "ble-",    BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "ble+",    BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "ble",     BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "blel-",   BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "blel+",   BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "blel",    BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "blea-",   BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "blea+",   BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "blea",    BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "blela-",  BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "blela+",  BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "blela",   BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bng-",    BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bng+",    BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bng",     BBOCB(16,BOF,CBGT,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bngl-",   BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bngl+",   BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bngl",    BBOCB(16,BOF,CBGT,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bnga-",   BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bnga+",   BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bnga",    BBOCB(16,BOF,CBGT,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bngla-",  BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bngla+",  BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bngla",   BBOCB(16,BOF,CBGT,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bne-",    BBOCB(16,BOF,CBEQ,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bne+",    BBOCB(16,BOF,CBEQ,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bne",     BBOCB(16,BOF,CBEQ,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bnel-",   BBOCB(16,BOF,CBEQ,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bnel+",   BBOCB(16,BOF,CBEQ,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bnel",    BBOCB(16,BOF,CBEQ,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bnea-",   BBOCB(16,BOF,CBEQ,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bnea+",   BBOCB(16,BOF,CBEQ,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bnea",    BBOCB(16,BOF,CBEQ,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bnela-",  BBOCB(16,BOF,CBEQ,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bnela+",  BBOCB(16,BOF,CBEQ,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bnela",   BBOCB(16,BOF,CBEQ,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bns-",    BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bns+",    BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bns",     BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bnsl-",   BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bnsl+",   BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bnsl",    BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, COM,		{ CR, BD } },
+-{ "bnsa-",   BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bnsa+",   BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bnsa",    BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bnsla-",  BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bnsla+",  BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bnsla",   BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, COM,		{ CR, BDA } },
+-{ "bnu-",    BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bnu+",    BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bnu",     BBOCB(16,BOF,CBSO,0,0), BBOATCB_MASK, PPCCOM,	{ CR, BD } },
+-{ "bnul-",   BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDM } },
+-{ "bnul+",   BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BDP } },
+-{ "bnul",    BBOCB(16,BOF,CBSO,0,1), BBOATCB_MASK, PPCCOM,	{ CR, BD } },
+-{ "bnua-",   BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bnua+",   BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bnua",    BBOCB(16,BOF,CBSO,1,0), BBOATCB_MASK, PPCCOM,	{ CR, BDA } },
+-{ "bnula-",  BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDMA } },
+-{ "bnula+",  BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDPA } },
+-{ "bnula",   BBOCB(16,BOF,CBSO,1,1), BBOATCB_MASK, PPCCOM,	{ CR, BDA } },
+-{ "bdnzt-",  BBO(16,BODNZT,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
+-{ "bdnzt+",  BBO(16,BODNZT,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
+-{ "bdnzt",   BBO(16,BODNZT,0,0), BBOY_MASK, PPCCOM,	{ BI, BD } },
+-{ "bdnztl-", BBO(16,BODNZT,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
+-{ "bdnztl+", BBO(16,BODNZT,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
+-{ "bdnztl",  BBO(16,BODNZT,0,1), BBOY_MASK, PPCCOM,	{ BI, BD } },
+-{ "bdnzta-", BBO(16,BODNZT,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
+-{ "bdnzta+", BBO(16,BODNZT,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
+-{ "bdnzta",  BBO(16,BODNZT,1,0), BBOY_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bdnztla-",BBO(16,BODNZT,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
+-{ "bdnztla+",BBO(16,BODNZT,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
+-{ "bdnztla", BBO(16,BODNZT,1,1), BBOY_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bdnzf-",  BBO(16,BODNZF,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
+-{ "bdnzf+",  BBO(16,BODNZF,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
+-{ "bdnzf",   BBO(16,BODNZF,0,0), BBOY_MASK, PPCCOM,	{ BI, BD } },
+-{ "bdnzfl-", BBO(16,BODNZF,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
+-{ "bdnzfl+", BBO(16,BODNZF,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
+-{ "bdnzfl",  BBO(16,BODNZF,0,1), BBOY_MASK, PPCCOM,	{ BI, BD } },
+-{ "bdnzfa-", BBO(16,BODNZF,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
+-{ "bdnzfa+", BBO(16,BODNZF,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
+-{ "bdnzfa",  BBO(16,BODNZF,1,0), BBOY_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bdnzfla-",BBO(16,BODNZF,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
+-{ "bdnzfla+",BBO(16,BODNZF,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
+-{ "bdnzfla", BBO(16,BODNZF,1,1), BBOY_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bt-",     BBO(16,BOT,0,0), BBOAT_MASK, PPCCOM,	{ BI, BDM } },
+-{ "bt+",     BBO(16,BOT,0,0), BBOAT_MASK, PPCCOM,	{ BI, BDP } },
+-{ "bt",	     BBO(16,BOT,0,0), BBOAT_MASK, PPCCOM,	{ BI, BD } },
+-{ "bbt",     BBO(16,BOT,0,0), BBOAT_MASK, PWRCOM,	{ BI, BD } },
+-{ "btl-",    BBO(16,BOT,0,1), BBOAT_MASK, PPCCOM,	{ BI, BDM } },
+-{ "btl+",    BBO(16,BOT,0,1), BBOAT_MASK, PPCCOM,	{ BI, BDP } },
+-{ "btl",     BBO(16,BOT,0,1), BBOAT_MASK, PPCCOM,	{ BI, BD } },
+-{ "bbtl",    BBO(16,BOT,0,1), BBOAT_MASK, PWRCOM,	{ BI, BD } },
+-{ "bta-",    BBO(16,BOT,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDMA } },
+-{ "bta+",    BBO(16,BOT,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDPA } },
+-{ "bta",     BBO(16,BOT,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bbta",    BBO(16,BOT,1,0), BBOAT_MASK, PWRCOM,	{ BI, BDA } },
+-{ "btla-",   BBO(16,BOT,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDMA } },
+-{ "btla+",   BBO(16,BOT,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDPA } },
+-{ "btla",    BBO(16,BOT,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bbtla",   BBO(16,BOT,1,1), BBOAT_MASK, PWRCOM,	{ BI, BDA } },
+-{ "bf-",     BBO(16,BOF,0,0), BBOAT_MASK, PPCCOM,	{ BI, BDM } },
+-{ "bf+",     BBO(16,BOF,0,0), BBOAT_MASK, PPCCOM,	{ BI, BDP } },
+-{ "bf",	     BBO(16,BOF,0,0), BBOAT_MASK, PPCCOM,	{ BI, BD } },
+-{ "bbf",     BBO(16,BOF,0,0), BBOAT_MASK, PWRCOM,	{ BI, BD } },
+-{ "bfl-",    BBO(16,BOF,0,1), BBOAT_MASK, PPCCOM,	{ BI, BDM } },
+-{ "bfl+",    BBO(16,BOF,0,1), BBOAT_MASK, PPCCOM,	{ BI, BDP } },
+-{ "bfl",     BBO(16,BOF,0,1), BBOAT_MASK, PPCCOM,	{ BI, BD } },
+-{ "bbfl",    BBO(16,BOF,0,1), BBOAT_MASK, PWRCOM,	{ BI, BD } },
+-{ "bfa-",    BBO(16,BOF,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDMA } },
+-{ "bfa+",    BBO(16,BOF,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDPA } },
+-{ "bfa",     BBO(16,BOF,1,0), BBOAT_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bbfa",    BBO(16,BOF,1,0), BBOAT_MASK, PWRCOM,	{ BI, BDA } },
+-{ "bfla-",   BBO(16,BOF,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDMA } },
+-{ "bfla+",   BBO(16,BOF,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDPA } },
+-{ "bfla",    BBO(16,BOF,1,1), BBOAT_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bbfla",   BBO(16,BOF,1,1), BBOAT_MASK, PWRCOM,	{ BI, BDA } },
+-{ "bdzt-",   BBO(16,BODZT,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
+-{ "bdzt+",   BBO(16,BODZT,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
+-{ "bdzt",    BBO(16,BODZT,0,0), BBOY_MASK, PPCCOM,	{ BI, BD } },
+-{ "bdztl-",  BBO(16,BODZT,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
+-{ "bdztl+",  BBO(16,BODZT,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
+-{ "bdztl",   BBO(16,BODZT,0,1), BBOY_MASK, PPCCOM,	{ BI, BD } },
+-{ "bdzta-",  BBO(16,BODZT,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
+-{ "bdzta+",  BBO(16,BODZT,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
+-{ "bdzta",   BBO(16,BODZT,1,0), BBOY_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bdztla-", BBO(16,BODZT,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
+-{ "bdztla+", BBO(16,BODZT,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
+-{ "bdztla",  BBO(16,BODZT,1,1), BBOY_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bdzf-",   BBO(16,BODZF,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
+-{ "bdzf+",   BBO(16,BODZF,0,0), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
+-{ "bdzf",    BBO(16,BODZF,0,0), BBOY_MASK, PPCCOM,	{ BI, BD } },
+-{ "bdzfl-",  BBO(16,BODZF,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDM } },
+-{ "bdzfl+",  BBO(16,BODZF,0,1), BBOY_MASK, NOPOWER4,	{ BI, BDP } },
+-{ "bdzfl",   BBO(16,BODZF,0,1), BBOY_MASK, PPCCOM,	{ BI, BD } },
+-{ "bdzfa-",  BBO(16,BODZF,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
+-{ "bdzfa+",  BBO(16,BODZF,1,0), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
+-{ "bdzfa",   BBO(16,BODZF,1,0), BBOY_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bdzfla-", BBO(16,BODZF,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDMA } },
+-{ "bdzfla+", BBO(16,BODZF,1,1), BBOY_MASK, NOPOWER4,	{ BI, BDPA } },
+-{ "bdzfla",  BBO(16,BODZF,1,1), BBOY_MASK, PPCCOM,	{ BI, BDA } },
+-{ "bc-",     B(16,0,0),	B_MASK,		PPCCOM,		{ BOE, BI, BDM } },
+-{ "bc+",     B(16,0,0),	B_MASK,		PPCCOM,		{ BOE, BI, BDP } },
+-{ "bc",	     B(16,0,0),	B_MASK,		COM,		{ BO, BI, BD } },
+-{ "bcl-",    B(16,0,1),	B_MASK,		PPCCOM,		{ BOE, BI, BDM } },
+-{ "bcl+",    B(16,0,1),	B_MASK,		PPCCOM,		{ BOE, BI, BDP } },
+-{ "bcl",     B(16,0,1),	B_MASK,		COM,		{ BO, BI, BD } },
+-{ "bca-",    B(16,1,0),	B_MASK,		PPCCOM,		{ BOE, BI, BDMA } },
+-{ "bca+",    B(16,1,0),	B_MASK,		PPCCOM,		{ BOE, BI, BDPA } },
+-{ "bca",     B(16,1,0),	B_MASK,		COM,		{ BO, BI, BDA } },
+-{ "bcla-",   B(16,1,1),	B_MASK,		PPCCOM,		{ BOE, BI, BDMA } },
+-{ "bcla+",   B(16,1,1),	B_MASK,		PPCCOM,		{ BOE, BI, BDPA } },
+-{ "bcla",    B(16,1,1),	B_MASK,		COM,		{ BO, BI, BDA } },
+-
+-{ "sc",      SC(17,1,0), 0xffffffff,	PPC,		{ 0 } },
+-{ "svc",     SC(17,0,0), SC_MASK,	POWER,		{ LEV, FL1, FL2 } },
+-{ "svcl",    SC(17,0,1), SC_MASK,	POWER,		{ LEV, FL1, FL2 } },
+-{ "svca",    SC(17,1,0), SC_MASK,	PWRCOM,		{ SV } },
+-{ "svcla",   SC(17,1,1), SC_MASK,	POWER,		{ SV } },
+-
+-{ "b",	     B(18,0,0),	B_MASK,		COM,		{ LI } },
+-{ "bl",      B(18,0,1),	B_MASK,		COM,		{ LI } },
+-{ "ba",      B(18,1,0),	B_MASK,		COM,		{ LIA } },
+-{ "bla",     B(18,1,1),	B_MASK,		COM,		{ LIA } },
+-
+-{ "mcrf",    XL(19,0),	XLBB_MASK|(3 << 21)|(3 << 16), COM,	{ BF, BFA } },
+-
+-{ "blr",     XLO(19,BOU,16,0), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
+-{ "br",      XLO(19,BOU,16,0), XLBOBIBB_MASK, PWRCOM,	{ 0 } },
+-{ "blrl",    XLO(19,BOU,16,1), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
+-{ "brl",     XLO(19,BOU,16,1), XLBOBIBB_MASK, PWRCOM,	{ 0 } },
+-{ "bdnzlr",  XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
+-{ "bdnzlr-", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
+-{ "bdnzlr-", XLO(19,BODNZM4,16,0), XLBOBIBB_MASK, POWER4,	{ 0 } },
+-{ "bdnzlr+", XLO(19,BODNZP,16,0), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
+-{ "bdnzlr+", XLO(19,BODNZP4,16,0), XLBOBIBB_MASK, POWER4,	{ 0 } },
+-{ "bdnzlrl", XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
+-{ "bdnzlrl-",XLO(19,BODNZ,16,1), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
+-{ "bdnzlrl-",XLO(19,BODNZM4,16,1), XLBOBIBB_MASK, POWER4,	{ 0 } },
+-{ "bdnzlrl+",XLO(19,BODNZP,16,1), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
+-{ "bdnzlrl+",XLO(19,BODNZP4,16,1), XLBOBIBB_MASK, POWER4,	{ 0 } },
+-{ "bdzlr",   XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
+-{ "bdzlr-",  XLO(19,BODZ,16,0), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
+-{ "bdzlr-",  XLO(19,BODZM4,16,0), XLBOBIBB_MASK, POWER4,	{ 0 } },
+-{ "bdzlr+",  XLO(19,BODZP,16,0), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
+-{ "bdzlr+",  XLO(19,BODZP4,16,0), XLBOBIBB_MASK, POWER4,	{ 0 } },
+-{ "bdzlrl",  XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPCCOM,	{ 0 } },
+-{ "bdzlrl-", XLO(19,BODZ,16,1), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
+-{ "bdzlrl-", XLO(19,BODZM4,16,1), XLBOBIBB_MASK, POWER4,	{ 0 } },
+-{ "bdzlrl+", XLO(19,BODZP,16,1), XLBOBIBB_MASK, NOPOWER4,	{ 0 } },
+-{ "bdzlrl+", XLO(19,BODZP4,16,1), XLBOBIBB_MASK, POWER4,	{ 0 } },
+-{ "bltlr",   XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bltlr-",  XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bltlr-",  XLOCB(19,BOTM4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bltlr+",  XLOCB(19,BOTP,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bltlr+",  XLOCB(19,BOTP4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bltr",    XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bltlrl",  XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bltlrl-", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bltlrl-", XLOCB(19,BOTM4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bltlrl+", XLOCB(19,BOTP,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bltlrl+", XLOCB(19,BOTP4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bltrl",   XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bgtlr",   XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bgtlr-",  XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgtlr-",  XLOCB(19,BOTM4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgtlr+",  XLOCB(19,BOTP,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgtlr+",  XLOCB(19,BOTP4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgtr",    XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bgtlrl",  XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bgtlrl-", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgtlrl-", XLOCB(19,BOTM4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgtlrl+", XLOCB(19,BOTP,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgtlrl+", XLOCB(19,BOTP4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgtrl",   XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "beqlr",   XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "beqlr-",  XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "beqlr-",  XLOCB(19,BOTM4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "beqlr+",  XLOCB(19,BOTP,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "beqlr+",  XLOCB(19,BOTP4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "beqr",    XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "beqlrl",  XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "beqlrl-", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "beqlrl-", XLOCB(19,BOTM4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "beqlrl+", XLOCB(19,BOTP,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "beqlrl+", XLOCB(19,BOTP4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "beqrl",   XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bsolr",   XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bsolr-",  XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bsolr-",  XLOCB(19,BOTM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bsolr+",  XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bsolr+",  XLOCB(19,BOTP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bsor",    XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bsolrl",  XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bsolrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bsolrl-", XLOCB(19,BOTM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bsolrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bsolrl+", XLOCB(19,BOTP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bsorl",   XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bunlr",   XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bunlr-",  XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bunlr-",  XLOCB(19,BOTM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bunlr+",  XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bunlr+",  XLOCB(19,BOTP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bunlrl",  XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bunlrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bunlrl-", XLOCB(19,BOTM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bunlrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bunlrl+", XLOCB(19,BOTP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgelr",   XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bgelr-",  XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgelr-",  XLOCB(19,BOFM4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgelr+",  XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgelr+",  XLOCB(19,BOFP4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bger",    XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bgelrl",  XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bgelrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgelrl-", XLOCB(19,BOFM4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgelrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgelrl+", XLOCB(19,BOFP4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgerl",   XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bnllr",   XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnllr-",  XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnllr-",  XLOCB(19,BOFM4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnllr+",  XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnllr+",  XLOCB(19,BOFP4,CBLT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnlr",    XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bnllrl",  XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnllrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnllrl-", XLOCB(19,BOFM4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnllrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnllrl+", XLOCB(19,BOFP4,CBLT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnlrl",   XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "blelr",   XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "blelr-",  XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "blelr-",  XLOCB(19,BOFM4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "blelr+",  XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "blelr+",  XLOCB(19,BOFP4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bler",    XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "blelrl",  XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "blelrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "blelrl-", XLOCB(19,BOFM4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "blelrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "blelrl+", XLOCB(19,BOFP4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "blerl",   XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bnglr",   XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnglr-",  XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnglr-",  XLOCB(19,BOFM4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnglr+",  XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnglr+",  XLOCB(19,BOFP4,CBGT,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bngr",    XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bnglrl",  XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnglrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnglrl-", XLOCB(19,BOFM4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnglrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnglrl+", XLOCB(19,BOFP4,CBGT,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bngrl",   XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bnelr",   XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnelr-",  XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnelr-",  XLOCB(19,BOFM4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnelr+",  XLOCB(19,BOFP,CBEQ,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnelr+",  XLOCB(19,BOFP4,CBEQ,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bner",    XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bnelrl",  XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnelrl-", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnelrl-", XLOCB(19,BOFM4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnelrl+", XLOCB(19,BOFP,CBEQ,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnelrl+", XLOCB(19,BOFP4,CBEQ,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnerl",   XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bnslr",   XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnslr-",  XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnslr-",  XLOCB(19,BOFM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnslr+",  XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnslr+",  XLOCB(19,BOFP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnsr",    XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bnslrl",  XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnslrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnslrl-", XLOCB(19,BOFM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnslrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnslrl+", XLOCB(19,BOFP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnsrl",   XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+-{ "bnulr",   XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnulr-",  XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnulr-",  XLOCB(19,BOFM4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnulr+",  XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnulr+",  XLOCB(19,BOFP4,CBSO,16,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnulrl",  XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+-{ "bnulrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnulrl-", XLOCB(19,BOFM4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnulrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnulrl+", XLOCB(19,BOFP4,CBSO,16,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "btlr",    XLO(19,BOT,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "btlr-",   XLO(19,BOT,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "btlr-",   XLO(19,BOTM4,16,0), XLBOBB_MASK, POWER4,	{ BI } },
+-{ "btlr+",   XLO(19,BOTP,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "btlr+",   XLO(19,BOTP4,16,0), XLBOBB_MASK, POWER4,	{ BI } },
+-{ "bbtr",    XLO(19,BOT,16,0), XLBOBB_MASK, PWRCOM,	{ BI } },
+-{ "btlrl",   XLO(19,BOT,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "btlrl-",  XLO(19,BOT,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "btlrl-",  XLO(19,BOTM4,16,1), XLBOBB_MASK, POWER4,	{ BI } },
+-{ "btlrl+",  XLO(19,BOTP,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "btlrl+",  XLO(19,BOTP4,16,1), XLBOBB_MASK, POWER4,	{ BI } },
+-{ "bbtrl",   XLO(19,BOT,16,1), XLBOBB_MASK, PWRCOM,	{ BI } },
+-{ "bflr",    XLO(19,BOF,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bflr-",   XLO(19,BOF,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "bflr-",   XLO(19,BOFM4,16,0), XLBOBB_MASK, POWER4,	{ BI } },
+-{ "bflr+",   XLO(19,BOFP,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "bflr+",   XLO(19,BOFP4,16,0), XLBOBB_MASK, POWER4,	{ BI } },
+-{ "bbfr",    XLO(19,BOF,16,0), XLBOBB_MASK, PWRCOM,	{ BI } },
+-{ "bflrl",   XLO(19,BOF,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bflrl-",  XLO(19,BOF,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "bflrl-",  XLO(19,BOFM4,16,1), XLBOBB_MASK, POWER4,	{ BI } },
+-{ "bflrl+",  XLO(19,BOFP,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "bflrl+",  XLO(19,BOFP4,16,1), XLBOBB_MASK, POWER4,	{ BI } },
+-{ "bbfrl",   XLO(19,BOF,16,1), XLBOBB_MASK, PWRCOM,	{ BI } },
+-{ "bdnztlr", XLO(19,BODNZT,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bdnztlr-",XLO(19,BODNZT,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdnztlr+",XLO(19,BODNZTP,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdnztlrl",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bdnztlrl-",XLO(19,BODNZT,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdnztlrl+",XLO(19,BODNZTP,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdnzflr", XLO(19,BODNZF,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bdnzflr-",XLO(19,BODNZF,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdnzflr+",XLO(19,BODNZFP,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdnzflrl",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bdnzflrl-",XLO(19,BODNZF,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdnzflrl+",XLO(19,BODNZFP,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdztlr",  XLO(19,BODZT,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bdztlr-", XLO(19,BODZT,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "bdztlr+", XLO(19,BODZTP,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdztlrl", XLO(19,BODZT,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bdztlrl-",XLO(19,BODZT,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "bdztlrl+",XLO(19,BODZTP,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdzflr",  XLO(19,BODZF,16,0), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bdzflr-", XLO(19,BODZF,16,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "bdzflr+", XLO(19,BODZFP,16,0), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bclr",    XLLK(19,16,0), XLYBB_MASK,	PPCCOM,		{ BO, BI } },
+-{ "bclrl",   XLLK(19,16,1), XLYBB_MASK,	PPCCOM,		{ BO, BI } },
+-{ "bclr+",   XLYLK(19,16,1,0), XLYBB_MASK, PPCCOM,	{ BOE, BI } },
+-{ "bclrl+",  XLYLK(19,16,1,1), XLYBB_MASK, PPCCOM,	{ BOE, BI } },
+-{ "bclr-",   XLYLK(19,16,0,0), XLYBB_MASK, PPCCOM,	{ BOE, BI } },
+-{ "bclrl-",  XLYLK(19,16,0,1), XLYBB_MASK, PPCCOM,	{ BOE, BI } },
+-{ "bcr",     XLLK(19,16,0), XLBB_MASK,	PWRCOM,		{ BO, BI } },
+-{ "bcrl",    XLLK(19,16,1), XLBB_MASK,	PWRCOM,		{ BO, BI } },
+-{ "bclre",   XLLK(19,17,0), XLBB_MASK,	BOOKE64,	{ BO, BI } },
+-{ "bclrel",  XLLK(19,17,1), XLBB_MASK,	BOOKE64,	{ BO, BI } },
+-
+-{ "rfid",    XL(19,18),	0xffffffff,	PPC64,		{ 0 } },
+-
+-{ "crnot",   XL(19,33), XL_MASK,	PPCCOM,		{ BT, BA, BBA } },
+-{ "crnor",   XL(19,33),	XL_MASK,	COM,		{ BT, BA, BB } },
+-{ "rfmci",    X(19,38), 0xffffffff,	PPCRFMCI,	{ 0 } },
+-
+-{ "rfi",     XL(19,50),	0xffffffff,	COM,		{ 0 } },
+-{ "rfci",    XL(19,51),	0xffffffff,	PPC403 | BOOKE,	{ 0 } },
+-
+-{ "rfsvc",   XL(19,82),	0xffffffff,	POWER,		{ 0 } },
+-
+-{ "crandc",  XL(19,129), XL_MASK,	COM,		{ BT, BA, BB } },
+-
+-{ "isync",   XL(19,150), 0xffffffff,	PPCCOM,		{ 0 } },
+-{ "ics",     XL(19,150), 0xffffffff,	PWRCOM,		{ 0 } },
+-
+-{ "crclr",   XL(19,193), XL_MASK,	PPCCOM,		{ BT, BAT, BBA } },
+-{ "crxor",   XL(19,193), XL_MASK,	COM,		{ BT, BA, BB } },
+-
+-{ "crnand",  XL(19,225), XL_MASK,	COM,		{ BT, BA, BB } },
+-
+-{ "crand",   XL(19,257), XL_MASK,	COM,		{ BT, BA, BB } },
+-
+-{ "crset",   XL(19,289), XL_MASK,	PPCCOM,		{ BT, BAT, BBA } },
+-{ "creqv",   XL(19,289), XL_MASK,	COM,		{ BT, BA, BB } },
+-
+-{ "crorc",   XL(19,417), XL_MASK,	COM,		{ BT, BA, BB } },
+-
+-{ "crmove",  XL(19,449), XL_MASK,	PPCCOM,		{ BT, BA, BBA } },
+-{ "cror",    XL(19,449), XL_MASK,	COM,		{ BT, BA, BB } },
+-
+-{ "bctr",    XLO(19,BOU,528,0), XLBOBIBB_MASK, COM,	{ 0 } },
+-{ "bctrl",   XLO(19,BOU,528,1), XLBOBIBB_MASK, COM,	{ 0 } },
+-{ "bltctr",  XLOCB(19,BOT,CBLT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bltctr-", XLOCB(19,BOT,CBLT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bltctr-", XLOCB(19,BOTM4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bltctr+", XLOCB(19,BOTP,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bltctr+", XLOCB(19,BOTP4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bltctrl", XLOCB(19,BOT,CBLT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bltctrl-",XLOCB(19,BOT,CBLT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bltctrl-",XLOCB(19,BOTM4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bltctrl+",XLOCB(19,BOTP,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bltctrl+",XLOCB(19,BOTP4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgtctr",  XLOCB(19,BOT,CBGT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bgtctr-", XLOCB(19,BOT,CBGT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgtctr-", XLOCB(19,BOTM4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgtctr+", XLOCB(19,BOTP,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgtctr+", XLOCB(19,BOTP4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgtctrl", XLOCB(19,BOT,CBGT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bgtctrl-",XLOCB(19,BOT,CBGT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgtctrl-",XLOCB(19,BOTM4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgtctrl+",XLOCB(19,BOTP,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgtctrl+",XLOCB(19,BOTP4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "beqctr",  XLOCB(19,BOT,CBEQ,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "beqctr-", XLOCB(19,BOT,CBEQ,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "beqctr-", XLOCB(19,BOTM4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "beqctr+", XLOCB(19,BOTP,CBEQ,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "beqctr+", XLOCB(19,BOTP4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "beqctrl", XLOCB(19,BOT,CBEQ,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "beqctrl-",XLOCB(19,BOT,CBEQ,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "beqctrl-",XLOCB(19,BOTM4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "beqctrl+",XLOCB(19,BOTP,CBEQ,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "beqctrl+",XLOCB(19,BOTP4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bsoctr",  XLOCB(19,BOT,CBSO,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bsoctr-", XLOCB(19,BOT,CBSO,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bsoctr-", XLOCB(19,BOTM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bsoctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bsoctr+", XLOCB(19,BOTP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bsoctrl", XLOCB(19,BOT,CBSO,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bsoctrl-",XLOCB(19,BOT,CBSO,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bsoctrl-",XLOCB(19,BOTM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bsoctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bsoctrl+",XLOCB(19,BOTP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bunctr",  XLOCB(19,BOT,CBSO,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bunctr-", XLOCB(19,BOT,CBSO,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bunctr-", XLOCB(19,BOTM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bunctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bunctr+", XLOCB(19,BOTP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bunctrl", XLOCB(19,BOT,CBSO,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bunctrl-",XLOCB(19,BOT,CBSO,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bunctrl-",XLOCB(19,BOTM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bunctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bunctrl+",XLOCB(19,BOTP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgectr",  XLOCB(19,BOF,CBLT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bgectr-", XLOCB(19,BOF,CBLT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgectr-", XLOCB(19,BOFM4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgectr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgectr+", XLOCB(19,BOFP4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgectrl", XLOCB(19,BOF,CBLT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bgectrl-",XLOCB(19,BOF,CBLT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgectrl-",XLOCB(19,BOFM4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bgectrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bgectrl+",XLOCB(19,BOFP4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnlctr",  XLOCB(19,BOF,CBLT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bnlctr-", XLOCB(19,BOF,CBLT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnlctr-", XLOCB(19,BOFM4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnlctr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnlctr+", XLOCB(19,BOFP4,CBLT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnlctrl", XLOCB(19,BOF,CBLT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bnlctrl-",XLOCB(19,BOF,CBLT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnlctrl-",XLOCB(19,BOFM4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnlctrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnlctrl+",XLOCB(19,BOFP4,CBLT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "blectr",  XLOCB(19,BOF,CBGT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "blectr-", XLOCB(19,BOF,CBGT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "blectr-", XLOCB(19,BOFM4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "blectr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "blectr+", XLOCB(19,BOFP4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "blectrl", XLOCB(19,BOF,CBGT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "blectrl-",XLOCB(19,BOF,CBGT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "blectrl-",XLOCB(19,BOFM4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "blectrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "blectrl+",XLOCB(19,BOFP4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bngctr",  XLOCB(19,BOF,CBGT,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bngctr-", XLOCB(19,BOF,CBGT,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bngctr-", XLOCB(19,BOFM4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bngctr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bngctr+", XLOCB(19,BOFP4,CBGT,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bngctrl", XLOCB(19,BOF,CBGT,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bngctrl-",XLOCB(19,BOF,CBGT,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bngctrl-",XLOCB(19,BOFM4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bngctrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bngctrl+",XLOCB(19,BOFP4,CBGT,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnectr",  XLOCB(19,BOF,CBEQ,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bnectr-", XLOCB(19,BOF,CBEQ,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnectr-", XLOCB(19,BOFM4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnectr+", XLOCB(19,BOFP,CBEQ,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnectr+", XLOCB(19,BOFP4,CBEQ,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnectrl", XLOCB(19,BOF,CBEQ,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bnectrl-",XLOCB(19,BOF,CBEQ,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnectrl-",XLOCB(19,BOFM4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnectrl+",XLOCB(19,BOFP,CBEQ,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnectrl+",XLOCB(19,BOFP4,CBEQ,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnsctr",  XLOCB(19,BOF,CBSO,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bnsctr-", XLOCB(19,BOF,CBSO,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnsctr-", XLOCB(19,BOFM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnsctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnsctr+", XLOCB(19,BOFP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnsctrl", XLOCB(19,BOF,CBSO,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bnsctrl-",XLOCB(19,BOF,CBSO,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnsctrl-",XLOCB(19,BOFM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnsctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnsctrl+",XLOCB(19,BOFP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnuctr",  XLOCB(19,BOF,CBSO,528,0),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bnuctr-", XLOCB(19,BOF,CBSO,528,0),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnuctr-", XLOCB(19,BOFM4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnuctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnuctr+", XLOCB(19,BOFP4,CBSO,528,0), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnuctrl", XLOCB(19,BOF,CBSO,528,1),  XLBOCBBB_MASK, PPCCOM,	{ CR } },
+-{ "bnuctrl-",XLOCB(19,BOF,CBSO,528,1),  XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnuctrl-",XLOCB(19,BOFM4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "bnuctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, NOPOWER4, { CR } },
+-{ "bnuctrl+",XLOCB(19,BOFP4,CBSO,528,1), XLBOCBBB_MASK, POWER4, { CR } },
+-{ "btctr",   XLO(19,BOT,528,0),  XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "btctr-",  XLO(19,BOT,528,0),  XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "btctr-",  XLO(19,BOTM4,528,0), XLBOBB_MASK, POWER4, { BI } },
+-{ "btctr+",  XLO(19,BOTP,528,0), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "btctr+",  XLO(19,BOTP4,528,0), XLBOBB_MASK, POWER4, { BI } },
+-{ "btctrl",  XLO(19,BOT,528,1),  XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "btctrl-", XLO(19,BOT,528,1),  XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "btctrl-", XLO(19,BOTM4,528,1), XLBOBB_MASK, POWER4, { BI } },
+-{ "btctrl+", XLO(19,BOTP,528,1), XLBOBB_MASK, NOPOWER4,	{ BI } },
+-{ "btctrl+", XLO(19,BOTP4,528,1), XLBOBB_MASK, POWER4, { BI } },
+-{ "bfctr",   XLO(19,BOF,528,0),  XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bfctr-",  XLO(19,BOF,528,0),  XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bfctr-",  XLO(19,BOFM4,528,0), XLBOBB_MASK, POWER4, { BI } },
+-{ "bfctr+",  XLO(19,BOFP,528,0), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bfctr+",  XLO(19,BOFP4,528,0), XLBOBB_MASK, POWER4, { BI } },
+-{ "bfctrl",  XLO(19,BOF,528,1),  XLBOBB_MASK, PPCCOM,	{ BI } },
+-{ "bfctrl-", XLO(19,BOF,528,1),  XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bfctrl-", XLO(19,BOFM4,528,1), XLBOBB_MASK, POWER4, { BI } },
+-{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, NOPOWER4, { BI } },
+-{ "bfctrl+", XLO(19,BOFP4,528,1), XLBOBB_MASK, POWER4, { BI } },
+-{ "bcctr",   XLLK(19,528,0),     XLYBB_MASK,  PPCCOM,	{ BO, BI } },
+-{ "bcctr-",  XLYLK(19,528,0,0),  XLYBB_MASK,  PPCCOM,	{ BOE, BI } },
+-{ "bcctr+",  XLYLK(19,528,1,0),  XLYBB_MASK,  PPCCOM,	{ BOE, BI } },
+-{ "bcctrl",  XLLK(19,528,1),     XLYBB_MASK,  PPCCOM,	{ BO, BI } },
+-{ "bcctrl-", XLYLK(19,528,0,1),  XLYBB_MASK,  PPCCOM,	{ BOE, BI } },
+-{ "bcctrl+", XLYLK(19,528,1,1),  XLYBB_MASK,  PPCCOM,	{ BOE, BI } },
+-{ "bcc",     XLLK(19,528,0),     XLBB_MASK,   PWRCOM,	{ BO, BI } },
+-{ "bccl",    XLLK(19,528,1),     XLBB_MASK,   PWRCOM,	{ BO, BI } },
+-{ "bcctre",  XLLK(19,529,0),     XLYBB_MASK,  BOOKE64,	{ BO, BI } },
+-{ "bcctrel", XLLK(19,529,1),     XLYBB_MASK,  BOOKE64,	{ BO, BI } },
+-
+-{ "rlwimi",  M(20,0),	M_MASK,		PPCCOM,		{ RA,RS,SH,MBE,ME } },
+-{ "rlimi",   M(20,0),	M_MASK,		PWRCOM,		{ RA,RS,SH,MBE,ME } },
+-
+-{ "rlwimi.", M(20,1),	M_MASK,		PPCCOM,		{ RA,RS,SH,MBE,ME } },
+-{ "rlimi.",  M(20,1),	M_MASK,		PWRCOM,		{ RA,RS,SH,MBE,ME } },
+-
+-{ "rotlwi",  MME(21,31,0), MMBME_MASK,	PPCCOM,		{ RA, RS, SH } },
+-{ "clrlwi",  MME(21,31,0), MSHME_MASK,	PPCCOM,		{ RA, RS, MB } },
+-{ "rlwinm",  M(21,0),	M_MASK,		PPCCOM,		{ RA,RS,SH,MBE,ME } },
+-{ "rlinm",   M(21,0),	M_MASK,		PWRCOM,		{ RA,RS,SH,MBE,ME } },
+-{ "rotlwi.", MME(21,31,1), MMBME_MASK,	PPCCOM,		{ RA,RS,SH } },
+-{ "clrlwi.", MME(21,31,1), MSHME_MASK,	PPCCOM,		{ RA, RS, MB } },
+-{ "rlwinm.", M(21,1),	M_MASK,		PPCCOM,		{ RA,RS,SH,MBE,ME } },
+-{ "rlinm.",  M(21,1),	M_MASK,		PWRCOM,		{ RA,RS,SH,MBE,ME } },
+-
+-{ "rlmi",    M(22,0),	M_MASK,		M601,		{ RA,RS,RB,MBE,ME } },
+-{ "rlmi.",   M(22,1),	M_MASK,		M601,		{ RA,RS,RB,MBE,ME } },
+-
+-{ "be",	     B(22,0,0),	B_MASK,		BOOKE64,	{ LI } },
+-{ "bel",     B(22,0,1),	B_MASK,		BOOKE64,	{ LI } },
+-{ "bea",     B(22,1,0),	B_MASK,		BOOKE64,	{ LIA } },
+-{ "bela",    B(22,1,1),	B_MASK,		BOOKE64,	{ LIA } },
+-
+-{ "rotlw",   MME(23,31,0), MMBME_MASK,	PPCCOM,		{ RA, RS, RB } },
+-{ "rlwnm",   M(23,0),	M_MASK,		PPCCOM,		{ RA,RS,RB,MBE,ME } },
+-{ "rlnm",    M(23,0),	M_MASK,		PWRCOM,		{ RA,RS,RB,MBE,ME } },
+-{ "rotlw.",  MME(23,31,1), MMBME_MASK,	PPCCOM,		{ RA, RS, RB } },
+-{ "rlwnm.",  M(23,1),	M_MASK,		PPCCOM,		{ RA,RS,RB,MBE,ME } },
+-{ "rlnm.",   M(23,1),	M_MASK,		PWRCOM,		{ RA,RS,RB,MBE,ME } },
+-
+-{ "nop",     OP(24),	0xffffffff,	PPCCOM,		{ 0 } },
+-{ "ori",     OP(24),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
+-{ "oril",    OP(24),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
+-
+-{ "oris",    OP(25),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
+-{ "oriu",    OP(25),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
+-
+-{ "xori",    OP(26),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
+-{ "xoril",   OP(26),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
+-
+-{ "xoris",   OP(27),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
+-{ "xoriu",   OP(27),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
+-
+-{ "andi.",   OP(28),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
+-{ "andil.",  OP(28),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
+-
+-{ "andis.",  OP(29),	OP_MASK,	PPCCOM,		{ RA, RS, UI } },
+-{ "andiu.",  OP(29),	OP_MASK,	PWRCOM,		{ RA, RS, UI } },
+-
+-{ "rotldi",  MD(30,0,0), MDMB_MASK,	PPC64,		{ RA, RS, SH6 } },
+-{ "clrldi",  MD(30,0,0), MDSH_MASK,	PPC64,		{ RA, RS, MB6 } },
+-{ "rldicl",  MD(30,0,0), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
+-{ "rotldi.", MD(30,0,1), MDMB_MASK,	PPC64,		{ RA, RS, SH6 } },
+-{ "clrldi.", MD(30,0,1), MDSH_MASK,	PPC64,		{ RA, RS, MB6 } },
+-{ "rldicl.", MD(30,0,1), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
+-
+-{ "rldicr",  MD(30,1,0), MD_MASK,	PPC64,		{ RA, RS, SH6, ME6 } },
+-{ "rldicr.", MD(30,1,1), MD_MASK,	PPC64,		{ RA, RS, SH6, ME6 } },
+-
+-{ "rldic",   MD(30,2,0), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
+-{ "rldic.",  MD(30,2,1), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
+-
+-{ "rldimi",  MD(30,3,0), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
+-{ "rldimi.", MD(30,3,1), MD_MASK,	PPC64,		{ RA, RS, SH6, MB6 } },
+-
+-{ "rotld",   MDS(30,8,0), MDSMB_MASK,	PPC64,		{ RA, RS, RB } },
+-{ "rldcl",   MDS(30,8,0), MDS_MASK,	PPC64,		{ RA, RS, RB, MB6 } },
+-{ "rotld.",  MDS(30,8,1), MDSMB_MASK,	PPC64,		{ RA, RS, RB } },
+-{ "rldcl.",  MDS(30,8,1), MDS_MASK,	PPC64,		{ RA, RS, RB, MB6 } },
+-
+-{ "rldcr",   MDS(30,9,0), MDS_MASK,	PPC64,		{ RA, RS, RB, ME6 } },
+-{ "rldcr.",  MDS(30,9,1), MDS_MASK,	PPC64,		{ RA, RS, RB, ME6 } },
+-
+-{ "cmpw",    XCMPL(31,0,0), XCMPL_MASK, PPCCOM,		{ OBF, RA, RB } },
+-{ "cmpd",    XCMPL(31,0,1), XCMPL_MASK, PPC64,		{ OBF, RA, RB } },
+-{ "cmp",     X(31,0),	XCMP_MASK,	PPC,		{ BF, L, RA, RB } },
+-{ "cmp",     X(31,0),	XCMPL_MASK,	PWRCOM,		{ BF, RA, RB } },
+-
+-{ "twlgt",   XTO(31,4,TOLGT), XTO_MASK, PPCCOM,		{ RA, RB } },
+-{ "tlgt",    XTO(31,4,TOLGT), XTO_MASK, PWRCOM,		{ RA, RB } },
+-{ "twllt",   XTO(31,4,TOLLT), XTO_MASK, PPCCOM,		{ RA, RB } },
+-{ "tllt",    XTO(31,4,TOLLT), XTO_MASK, PWRCOM,		{ RA, RB } },
+-{ "tweq",    XTO(31,4,TOEQ), XTO_MASK,	PPCCOM,		{ RA, RB } },
+-{ "teq",     XTO(31,4,TOEQ), XTO_MASK,	PWRCOM,		{ RA, RB } },
+-{ "twlge",   XTO(31,4,TOLGE), XTO_MASK, PPCCOM,		{ RA, RB } },
+-{ "tlge",    XTO(31,4,TOLGE), XTO_MASK, PWRCOM,		{ RA, RB } },
+-{ "twlnl",   XTO(31,4,TOLNL), XTO_MASK, PPCCOM,		{ RA, RB } },
+-{ "tlnl",    XTO(31,4,TOLNL), XTO_MASK, PWRCOM,		{ RA, RB } },
+-{ "twlle",   XTO(31,4,TOLLE), XTO_MASK, PPCCOM,		{ RA, RB } },
+-{ "tlle",    XTO(31,4,TOLLE), XTO_MASK, PWRCOM,		{ RA, RB } },
+-{ "twlng",   XTO(31,4,TOLNG), XTO_MASK, PPCCOM,		{ RA, RB } },
+-{ "tlng",    XTO(31,4,TOLNG), XTO_MASK, PWRCOM,		{ RA, RB } },
+-{ "twgt",    XTO(31,4,TOGT), XTO_MASK,	PPCCOM,		{ RA, RB } },
+-{ "tgt",     XTO(31,4,TOGT), XTO_MASK,	PWRCOM,		{ RA, RB } },
+-{ "twge",    XTO(31,4,TOGE), XTO_MASK,	PPCCOM,		{ RA, RB } },
+-{ "tge",     XTO(31,4,TOGE), XTO_MASK,	PWRCOM,		{ RA, RB } },
+-{ "twnl",    XTO(31,4,TONL), XTO_MASK,	PPCCOM,		{ RA, RB } },
+-{ "tnl",     XTO(31,4,TONL), XTO_MASK,	PWRCOM,		{ RA, RB } },
+-{ "twlt",    XTO(31,4,TOLT), XTO_MASK,	PPCCOM,		{ RA, RB } },
+-{ "tlt",     XTO(31,4,TOLT), XTO_MASK,	PWRCOM,		{ RA, RB } },
+-{ "twle",    XTO(31,4,TOLE), XTO_MASK,	PPCCOM,		{ RA, RB } },
+-{ "tle",     XTO(31,4,TOLE), XTO_MASK,	PWRCOM,		{ RA, RB } },
+-{ "twng",    XTO(31,4,TONG), XTO_MASK,	PPCCOM,		{ RA, RB } },
+-{ "tng",     XTO(31,4,TONG), XTO_MASK,	PWRCOM,		{ RA, RB } },
+-{ "twne",    XTO(31,4,TONE), XTO_MASK,	PPCCOM,		{ RA, RB } },
+-{ "tne",     XTO(31,4,TONE), XTO_MASK,	PWRCOM,		{ RA, RB } },
+-{ "trap",    XTO(31,4,TOU), 0xffffffff,	PPCCOM,		{ 0 } },
+-{ "tw",      X(31,4),	X_MASK,		PPCCOM,		{ TO, RA, RB } },
+-{ "t",       X(31,4),	X_MASK,		PWRCOM,		{ TO, RA, RB } },
+-
+-{ "subfc",   XO(31,8,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "sf",      XO(31,8,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "subc",    XO(31,8,0,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+-{ "subfc.",  XO(31,8,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "sf.",     XO(31,8,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "subc.",   XO(31,8,0,1), XO_MASK,	PPCCOM,		{ RT, RB, RA } },
+-{ "subfco",  XO(31,8,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "sfo",     XO(31,8,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "subco",   XO(31,8,1,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+-{ "subfco.", XO(31,8,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "sfo.",    XO(31,8,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "subco.",  XO(31,8,1,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+-
+-{ "mulhdu",  XO(31,9,0,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "mulhdu.", XO(31,9,0,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-
+-{ "addc",    XO(31,10,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "a",       XO(31,10,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "addc.",   XO(31,10,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "a.",      XO(31,10,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "addco",   XO(31,10,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "ao",      XO(31,10,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "addco.",  XO(31,10,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "ao.",     XO(31,10,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-
+-{ "mulhwu",  XO(31,11,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "mulhwu.", XO(31,11,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+-
+-{ "isellt",  X(31,15),      X_MASK,	PPCISEL,	{ RT, RA, RB } },
+-{ "iselgt",  X(31,47),      X_MASK,	PPCISEL,	{ RT, RA, RB } },
+-{ "iseleq",  X(31,79),      X_MASK,	PPCISEL,	{ RT, RA, RB } },
+-{ "isel",    XISEL(31,15),  XISEL_MASK,	PPCISEL,	{ RT, RA, RB, CRB } },
+-
+-{ "mfcr",    X(31,19),	XRARB_MASK,	NOPOWER4,	{ RT } },
+-{ "mfcr",    X(31,19),	XFXFXM_MASK,	POWER4,		{ RT, FXM4 } },
+-
+-{ "lwarx",   X(31,20),	X_MASK,		PPC,		{ RT, RA, RB } },
+-
+-{ "ldx",     X(31,21),	X_MASK,		PPC64,		{ RT, RA, RB } },
+-
+-{ "icbt",    X(31,22),	X_MASK,		BOOKE,		{ CT, RA, RB } },
+-{ "icbt",    X(31,262),	XRT_MASK,	PPC403,		{ RA, RB } },
+-
+-{ "lwzx",    X(31,23),	X_MASK,		PPCCOM,		{ RT, RA, RB } },
+-{ "lx",      X(31,23),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
+-
+-{ "slw",     XRC(31,24,0), X_MASK,	PPCCOM,		{ RA, RS, RB } },
+-{ "sl",      XRC(31,24,0), X_MASK,	PWRCOM,		{ RA, RS, RB } },
+-{ "slw.",    XRC(31,24,1), X_MASK,	PPCCOM,		{ RA, RS, RB } },
+-{ "sl.",     XRC(31,24,1), X_MASK,	PWRCOM,		{ RA, RS, RB } },
+-
+-{ "cntlzw",  XRC(31,26,0), XRB_MASK,	PPCCOM,		{ RA, RS } },
+-{ "cntlz",   XRC(31,26,0), XRB_MASK,	PWRCOM,		{ RA, RS } },
+-{ "cntlzw.", XRC(31,26,1), XRB_MASK,	PPCCOM,		{ RA, RS } },
+-{ "cntlz.",  XRC(31,26,1), XRB_MASK, 	PWRCOM,		{ RA, RS } },
+-
+-{ "sld",     XRC(31,27,0), X_MASK,	PPC64,		{ RA, RS, RB } },
+-{ "sld.",    XRC(31,27,1), X_MASK,	PPC64,		{ RA, RS, RB } },
+-
+-{ "and",     XRC(31,28,0), X_MASK,	COM,		{ RA, RS, RB } },
+-{ "and.",    XRC(31,28,1), X_MASK,	COM,		{ RA, RS, RB } },
+-
+-{ "maskg",   XRC(31,29,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "maskg.",  XRC(31,29,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "icbte",   X(31,30),	X_MASK,		BOOKE64,	{ CT, RA, RB } },
+-
+-{ "lwzxe",   X(31,31),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
+-
+-{ "cmplw",   XCMPL(31,32,0), XCMPL_MASK, PPCCOM,	{ OBF, RA, RB } },
+-{ "cmpld",   XCMPL(31,32,1), XCMPL_MASK, PPC64,		{ OBF, RA, RB } },
+-{ "cmpl",    X(31,32),	XCMP_MASK,	 PPC,		{ BF, L, RA, RB } },
+-{ "cmpl",    X(31,32),	XCMPL_MASK,	 PWRCOM,	{ BF, RA, RB } },
+-
+-{ "subf",    XO(31,40,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "sub",     XO(31,40,0,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+-{ "subf.",   XO(31,40,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "sub.",    XO(31,40,0,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+-{ "subfo",   XO(31,40,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "subo",    XO(31,40,1,0), XO_MASK,	PPC,		{ RT, RB, RA } },
+-{ "subfo.",  XO(31,40,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "subo.",   XO(31,40,1,1), XO_MASK,	PPC,		{ RT, RB, RA } },
+-
+-{ "ldux",    X(31,53),	X_MASK,		PPC64,		{ RT, RAL, RB } },
+-
+-{ "dcbst",   X(31,54),	XRT_MASK,	PPC,		{ RA, RB } },
+-
+-{ "lwzux",   X(31,55),	X_MASK,		PPCCOM,		{ RT, RAL, RB } },
+-{ "lux",     X(31,55),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
+-
+-{ "dcbste",  X(31,62),	XRT_MASK,	BOOKE64,	{ RA, RB } },
+-
+-{ "lwzuxe",  X(31,63),	X_MASK,		BOOKE64,	{ RT, RAL, RB } },
+-
+-{ "cntlzd",  XRC(31,58,0), XRB_MASK,	PPC64,		{ RA, RS } },
+-{ "cntlzd.", XRC(31,58,1), XRB_MASK,	PPC64,		{ RA, RS } },
+-
+-{ "andc",    XRC(31,60,0), X_MASK,	COM,		{ RA, RS, RB } },
+-{ "andc.",   XRC(31,60,1), X_MASK,	COM,		{ RA, RS, RB } },
+-
+-{ "tdlgt",   XTO(31,68,TOLGT), XTO_MASK, PPC64,		{ RA, RB } },
+-{ "tdllt",   XTO(31,68,TOLLT), XTO_MASK, PPC64,		{ RA, RB } },
+-{ "tdeq",    XTO(31,68,TOEQ), XTO_MASK,  PPC64,		{ RA, RB } },
+-{ "tdlge",   XTO(31,68,TOLGE), XTO_MASK, PPC64,		{ RA, RB } },
+-{ "tdlnl",   XTO(31,68,TOLNL), XTO_MASK, PPC64,		{ RA, RB } },
+-{ "tdlle",   XTO(31,68,TOLLE), XTO_MASK, PPC64,		{ RA, RB } },
+-{ "tdlng",   XTO(31,68,TOLNG), XTO_MASK, PPC64,		{ RA, RB } },
+-{ "tdgt",    XTO(31,68,TOGT), XTO_MASK,  PPC64,		{ RA, RB } },
+-{ "tdge",    XTO(31,68,TOGE), XTO_MASK,  PPC64,		{ RA, RB } },
+-{ "tdnl",    XTO(31,68,TONL), XTO_MASK,  PPC64,		{ RA, RB } },
+-{ "tdlt",    XTO(31,68,TOLT), XTO_MASK,  PPC64,		{ RA, RB } },
+-{ "tdle",    XTO(31,68,TOLE), XTO_MASK,  PPC64,		{ RA, RB } },
+-{ "tdng",    XTO(31,68,TONG), XTO_MASK,  PPC64,		{ RA, RB } },
+-{ "tdne",    XTO(31,68,TONE), XTO_MASK,  PPC64,		{ RA, RB } },
+-{ "td",	     X(31,68),	X_MASK,		 PPC64,		{ TO, RA, RB } },
+-
+-{ "mulhd",   XO(31,73,0,0), XO_MASK,	 PPC64,		{ RT, RA, RB } },
+-{ "mulhd.",  XO(31,73,0,1), XO_MASK,	 PPC64,		{ RT, RA, RB } },
+-
+-{ "mulhw",   XO(31,75,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "mulhw.",  XO(31,75,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+-
+-{ "dlmzb",   XRC(31,78,0),  X_MASK,	PPC403|PPC440,	{ RA, RS, RB } },
+-{ "dlmzb.",  XRC(31,78,1),  X_MASK,	PPC403|PPC440,	{ RA, RS, RB } },
+-
+-{ "mtsrd",   X(31,82),	XRB_MASK|(1<<20), PPC64,	{ SR, RS } },
+-
+-{ "mfmsr",   X(31,83),	XRARB_MASK,	COM,		{ RT } },
+-
+-{ "ldarx",   X(31,84),	X_MASK,		PPC64,		{ RT, RA, RB } },
+-
+-{ "dcbf",    X(31,86),	XRT_MASK,	PPC,		{ RA, RB } },
+-
+-{ "lbzx",    X(31,87),	X_MASK,		COM,		{ RT, RA, RB } },
+-
+-{ "dcbfe",   X(31,94),	XRT_MASK,	BOOKE64,	{ RA, RB } },
+-
+-{ "lbzxe",   X(31,95),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
+-
+-{ "neg",     XO(31,104,0,0), XORB_MASK,	COM,		{ RT, RA } },
+-{ "neg.",    XO(31,104,0,1), XORB_MASK,	COM,		{ RT, RA } },
+-{ "nego",    XO(31,104,1,0), XORB_MASK,	COM,		{ RT, RA } },
+-{ "nego.",   XO(31,104,1,1), XORB_MASK,	COM,		{ RT, RA } },
+-
+-{ "mul",     XO(31,107,0,0), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "mul.",    XO(31,107,0,1), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "mulo",    XO(31,107,1,0), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "mulo.",   XO(31,107,1,1), XO_MASK,	M601,		{ RT, RA, RB } },
+-
+-{ "mtsrdin", X(31,114),	XRA_MASK,	PPC64,		{ RS, RB } },
+-
+-{ "clf",     X(31,118), XTO_MASK,	POWER,		{ RA, RB } },
+-
+-{ "lbzux",   X(31,119),	X_MASK,		COM,		{ RT, RAL, RB } },
+-
+-{ "not",     XRC(31,124,0), X_MASK,	COM,		{ RA, RS, RBS } },
+-{ "nor",     XRC(31,124,0), X_MASK,	COM,		{ RA, RS, RB } },
+-{ "not.",    XRC(31,124,1), X_MASK,	COM,		{ RA, RS, RBS } },
+-{ "nor.",    XRC(31,124,1), X_MASK,	COM,		{ RA, RS, RB } },
+-
+-{ "lwarxe",  X(31,126),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
+-
+-{ "lbzuxe",  X(31,127),	X_MASK,		BOOKE64,	{ RT, RAL, RB } },
+-
+-{ "wrtee",   X(31,131),	XRARB_MASK,	PPC403 | BOOKE,	{ RS } },
+-
+-{ "dcbtstls",X(31,134),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
+-
+-{ "subfe",   XO(31,136,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "sfe",     XO(31,136,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "subfe.",  XO(31,136,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "sfe.",    XO(31,136,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "subfeo",  XO(31,136,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "sfeo",    XO(31,136,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "subfeo.", XO(31,136,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "sfeo.",   XO(31,136,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-
+-{ "adde",    XO(31,138,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "ae",      XO(31,138,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "adde.",   XO(31,138,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "ae.",     XO(31,138,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "addeo",   XO(31,138,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "aeo",     XO(31,138,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "addeo.",  XO(31,138,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "aeo.",    XO(31,138,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-
+-{ "dcbtstlse",X(31,142),X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
+-
+-{ "mtcr",    XFXM(31,144,0xff), XRARB_MASK, COM,	{ RS }},
+-{ "mtcrf",   X(31,144),	XFXFXM_MASK,	COM,		{ FXM, RS } },
+-
+-{ "mtmsr",   X(31,146),	XRARB_MASK,	COM,		{ RS } },
+-
+-{ "stdx",    X(31,149), X_MASK,		PPC64,		{ RS, RA, RB } },
+-
+-{ "stwcx.",  XRC(31,150,1), X_MASK,	PPC,		{ RS, RA, RB } },
+-
+-{ "stwx",    X(31,151), X_MASK,		PPCCOM,		{ RS, RA, RB } },
+-{ "stx",     X(31,151), X_MASK,		PWRCOM,		{ RS, RA, RB } },
+-
+-{ "stwcxe.", XRC(31,158,1), X_MASK,	BOOKE64,	{ RS, RA, RB } },
+-
+-{ "stwxe",   X(31,159), X_MASK,		BOOKE64,	{ RS, RA, RB } },
+-
+-{ "slq",     XRC(31,152,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "slq.",    XRC(31,152,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "sle",     XRC(31,153,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "sle.",    XRC(31,153,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "wrteei",  X(31,163),	XE_MASK,	PPC403 | BOOKE,	{ E } },
+-
+-{ "dcbtls",  X(31,166),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
+-{ "dcbtlse", X(31,174),	X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
+-
+-{ "mtmsrd",  X(31,178),	XRLARB_MASK,	PPC64,		{ RS, MTMSRD_L } },
+-
+-{ "stdux",   X(31,181),	X_MASK,		PPC64,		{ RS, RAS, RB } },
+-
+-{ "stwux",   X(31,183),	X_MASK,		PPCCOM,		{ RS, RAS, RB } },
+-{ "stux",    X(31,183),	X_MASK,		PWRCOM,		{ RS, RA, RB } },
+-
+-{ "sliq",    XRC(31,184,0), X_MASK,	M601,		{ RA, RS, SH } },
+-{ "sliq.",   XRC(31,184,1), X_MASK,	M601,		{ RA, RS, SH } },
+-
+-{ "stwuxe",  X(31,191),	X_MASK,		BOOKE64,	{ RS, RAS, RB } },
+-
+-{ "subfze",  XO(31,200,0,0), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "sfze",    XO(31,200,0,0), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "subfze.", XO(31,200,0,1), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "sfze.",   XO(31,200,0,1), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "subfzeo", XO(31,200,1,0), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "sfzeo",   XO(31,200,1,0), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "subfzeo.",XO(31,200,1,1), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "sfzeo.",  XO(31,200,1,1), XORB_MASK, PWRCOM,		{ RT, RA } },
+-
+-{ "addze",   XO(31,202,0,0), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "aze",     XO(31,202,0,0), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "addze.",  XO(31,202,0,1), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "aze.",    XO(31,202,0,1), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "addzeo",  XO(31,202,1,0), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "azeo",    XO(31,202,1,0), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "addzeo.", XO(31,202,1,1), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "azeo.",   XO(31,202,1,1), XORB_MASK, PWRCOM,		{ RT, RA } },
+-
+-{ "mtsr",    X(31,210),	XRB_MASK|(1<<20), COM32,	{ SR, RS } },
+-
+-{ "stdcx.",  XRC(31,214,1), X_MASK,	PPC64,		{ RS, RA, RB } },
+-
+-{ "stbx",    X(31,215),	X_MASK,		COM,		{ RS, RA, RB } },
+-
+-{ "sllq",    XRC(31,216,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "sllq.",   XRC(31,216,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "sleq",    XRC(31,217,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "sleq.",   XRC(31,217,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "stbxe",   X(31,223),	X_MASK,		BOOKE64,	{ RS, RA, RB } },
+-
+-{ "icblc",   X(31,230),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
+-
+-{ "subfme",  XO(31,232,0,0), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "sfme",    XO(31,232,0,0), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "subfme.", XO(31,232,0,1), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "sfme.",   XO(31,232,0,1), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "subfmeo", XO(31,232,1,0), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "sfmeo",   XO(31,232,1,0), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "subfmeo.",XO(31,232,1,1), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "sfmeo.",  XO(31,232,1,1), XORB_MASK, PWRCOM,		{ RT, RA } },
+-
+-{ "mulld",   XO(31,233,0,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "mulld.",  XO(31,233,0,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "mulldo",  XO(31,233,1,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "mulldo.", XO(31,233,1,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-
+-{ "addme",   XO(31,234,0,0), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "ame",     XO(31,234,0,0), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "addme.",  XO(31,234,0,1), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "ame.",    XO(31,234,0,1), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "addmeo",  XO(31,234,1,0), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "ameo",    XO(31,234,1,0), XORB_MASK, PWRCOM,		{ RT, RA } },
+-{ "addmeo.", XO(31,234,1,1), XORB_MASK, PPCCOM,		{ RT, RA } },
+-{ "ameo.",   XO(31,234,1,1), XORB_MASK, PWRCOM,		{ RT, RA } },
+-
+-{ "mullw",   XO(31,235,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "muls",    XO(31,235,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "mullw.",  XO(31,235,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "muls.",   XO(31,235,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "mullwo",  XO(31,235,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "mulso",   XO(31,235,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "mullwo.", XO(31,235,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "mulso.",  XO(31,235,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-
+-{ "icblce",  X(31,238),	X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
+-{ "mtsrin",  X(31,242),	XRA_MASK,	PPC32,		{ RS, RB } },
+-{ "mtsri",   X(31,242),	XRA_MASK,	POWER32,	{ RS, RB } },
+-
+-{ "dcbtst",  X(31,246),	XRT_MASK,	PPC,		{ CT, RA, RB } },
+-
+-{ "stbux",   X(31,247),	X_MASK,		COM,		{ RS, RAS, RB } },
+-
+-{ "slliq",   XRC(31,248,0), X_MASK,	M601,		{ RA, RS, SH } },
+-{ "slliq.",  XRC(31,248,1), X_MASK,	M601,		{ RA, RS, SH } },
+-
+-{ "dcbtste", X(31,253),	X_MASK,		BOOKE64,	{ CT, RA, RB } },
+-
+-{ "stbuxe",  X(31,255),	X_MASK,		BOOKE64,	{ RS, RAS, RB } },
+-
+-{ "mfdcrx",  X(31,259),	X_MASK,		BOOKE,		{ RS, RA } },
+-
+-{ "doz",     XO(31,264,0,0), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "doz.",    XO(31,264,0,1), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "dozo",    XO(31,264,1,0), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "dozo.",   XO(31,264,1,1), XO_MASK,	M601,		{ RT, RA, RB } },
+-
+-{ "add",     XO(31,266,0,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "cax",     XO(31,266,0,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "add.",    XO(31,266,0,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "cax.",    XO(31,266,0,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "addo",    XO(31,266,1,0), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "caxo",    XO(31,266,1,0), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-{ "addo.",   XO(31,266,1,1), XO_MASK,	PPCCOM,		{ RT, RA, RB } },
+-{ "caxo.",   XO(31,266,1,1), XO_MASK,	PWRCOM,		{ RT, RA, RB } },
+-
+-{ "tlbiel",  X(31,274), XRTRA_MASK,	POWER4,		{ RB } },
+-
+-{ "mfapidi", X(31,275), X_MASK,		BOOKE,		{ RT, RA } },
+-
+-{ "lscbx",   XRC(31,277,0), X_MASK,	M601,		{ RT, RA, RB } },
+-{ "lscbx.",  XRC(31,277,1), X_MASK,	M601,		{ RT, RA, RB } },
+-
+-{ "dcbt",    X(31,278),	XRT_MASK,	PPC,		{ CT, RA, RB } },
+-
+-{ "lhzx",    X(31,279),	X_MASK,		COM,		{ RT, RA, RB } },
+-
+-{ "eqv",     XRC(31,284,0), X_MASK,	COM,		{ RA, RS, RB } },
+-{ "eqv.",    XRC(31,284,1), X_MASK,	COM,		{ RA, RS, RB } },
+-
+-{ "dcbte",   X(31,286),	X_MASK,		BOOKE64,	{ CT, RA, RB } },
+-
+-{ "lhzxe",   X(31,287),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
+-
+-{ "tlbie",   X(31,306),	XRTLRA_MASK,	PPC,		{ RB, L } },
+-{ "tlbi",    X(31,306),	XRT_MASK,	POWER,		{ RA, RB } },
+-
+-{ "eciwx",   X(31,310), X_MASK,		PPC,		{ RT, RA, RB } },
+-
+-{ "lhzux",   X(31,311),	X_MASK,		COM,		{ RT, RAL, RB } },
+-
+-{ "xor",     XRC(31,316,0), X_MASK,	COM,		{ RA, RS, RB } },
+-{ "xor.",    XRC(31,316,1), X_MASK,	COM,		{ RA, RS, RB } },
+-
+-{ "lhzuxe",  X(31,319),	X_MASK,		BOOKE64,	{ RT, RAL, RB } },
+-
+-{ "mfexisr",  XSPR(31,323,64),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfexier",  XSPR(31,323,66),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbr0",    XSPR(31,323,128), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbr1",    XSPR(31,323,129), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbr2",    XSPR(31,323,130), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbr3",    XSPR(31,323,131), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbr4",    XSPR(31,323,132), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbr5",    XSPR(31,323,133), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbr6",    XSPR(31,323,134), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbr7",    XSPR(31,323,135), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbear",   XSPR(31,323,144), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfbesr",   XSPR(31,323,145), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfiocr",   XSPR(31,323,160), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmacr0", XSPR(31,323,192), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmact0", XSPR(31,323,193), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmada0", XSPR(31,323,194), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmasa0", XSPR(31,323,195), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmacc0", XSPR(31,323,196), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmacr1", XSPR(31,323,200), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmact1", XSPR(31,323,201), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmada1", XSPR(31,323,202), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmasa1", XSPR(31,323,203), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmacc1", XSPR(31,323,204), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmacr2", XSPR(31,323,208), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmact2", XSPR(31,323,209), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmada2", XSPR(31,323,210), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmasa2", XSPR(31,323,211), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmacc2", XSPR(31,323,212), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmacr3", XSPR(31,323,216), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmact3", XSPR(31,323,217), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmada3", XSPR(31,323,218), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmasa3", XSPR(31,323,219), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmacc3", XSPR(31,323,220), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdmasr",  XSPR(31,323,224), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdcr",    X(31,323),	X_MASK,	PPC403 | BOOKE,	{ RT, SPR } },
+-
+-{ "div",     XO(31,331,0,0), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "div.",    XO(31,331,0,1), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "divo",    XO(31,331,1,0), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "divo.",   XO(31,331,1,1), XO_MASK,	M601,		{ RT, RA, RB } },
+-
+-{ "mfpmr",   X(31,334),	X_MASK,		PPCPMR,		{ RT, PMR }},
+-
+-{ "mfmq",       XSPR(31,339,0),    XSPR_MASK, M601,	{ RT } },
+-{ "mfxer",      XSPR(31,339,1),    XSPR_MASK, COM,	{ RT } },
+-{ "mfrtcu",     XSPR(31,339,4),    XSPR_MASK, COM,	{ RT } },
+-{ "mfrtcl",     XSPR(31,339,5),    XSPR_MASK, COM,	{ RT } },
+-{ "mfdec",      XSPR(31,339,6),    XSPR_MASK, MFDEC1,	{ RT } },
+-{ "mfdec",      XSPR(31,339,22),   XSPR_MASK, MFDEC2,	{ RT } },
+-{ "mflr",       XSPR(31,339,8),    XSPR_MASK, COM,	{ RT } },
+-{ "mfctr",      XSPR(31,339,9),    XSPR_MASK, COM,	{ RT } },
+-{ "mftid",      XSPR(31,339,17),   XSPR_MASK, POWER,	{ RT } },
+-{ "mfdsisr",    XSPR(31,339,18),   XSPR_MASK, COM,	{ RT } },
+-{ "mfdar",      XSPR(31,339,19),   XSPR_MASK, COM,	{ RT } },
+-{ "mfsdr0",     XSPR(31,339,24),   XSPR_MASK, POWER,	{ RT } },
+-{ "mfsdr1",     XSPR(31,339,25),   XSPR_MASK, COM,	{ RT } },
+-{ "mfsrr0",     XSPR(31,339,26),   XSPR_MASK, COM,	{ RT } },
+-{ "mfsrr1",     XSPR(31,339,27),   XSPR_MASK, COM,	{ RT } },
+-{ "mfpid",      XSPR(31,339,48),   XSPR_MASK, BOOKE,    { RT } },
+-{ "mfpid",      XSPR(31,339,945),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfcsrr0",    XSPR(31,339,58),   XSPR_MASK, BOOKE,    { RT } },
+-{ "mfcsrr1",    XSPR(31,339,59),   XSPR_MASK, BOOKE,    { RT } },
+-{ "mfdear",     XSPR(31,339,61),   XSPR_MASK, BOOKE,    { RT } },
+-{ "mfdear",     XSPR(31,339,981),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfesr",      XSPR(31,339,62),   XSPR_MASK, BOOKE,    { RT } },
+-{ "mfesr",      XSPR(31,339,980),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfivpr",     XSPR(31,339,63),   XSPR_MASK, BOOKE,    { RT } },
+-{ "mfcmpa",     XSPR(31,339,144),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfcmpb",     XSPR(31,339,145),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfcmpc",     XSPR(31,339,146),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfcmpd",     XSPR(31,339,147),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mficr",      XSPR(31,339,148),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfder",      XSPR(31,339,149),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfcounta",   XSPR(31,339,150),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfcountb",   XSPR(31,339,151),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfcmpe",     XSPR(31,339,152),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfcmpf",     XSPR(31,339,153),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfcmpg",     XSPR(31,339,154),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfcmph",     XSPR(31,339,155),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mflctrl1",   XSPR(31,339,156),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mflctrl2",   XSPR(31,339,157),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfictrl",    XSPR(31,339,158),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,	{ RT } },
+-{ "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mftb",       X(31,371),	   X_MASK,    CLASSIC,	{ RT, TBR } },
+-{ "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mftbl",      XSPR(31,371,268),  XSPR_MASK, CLASSIC,	{ RT } },
+-{ "mftbl",      XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mftbu",      XSPR(31,371,269),  XSPR_MASK, CLASSIC,	{ RT } },
+-{ "mftbu",      XSPR(31,339,269),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfsprg",     XSPR(31,339,272),  XSPRG_MASK, PPC,	{ RT, SPRG } },
+-{ "mfsprg0",    XSPR(31,339,272),  XSPR_MASK, PPC,	{ RT } },
+-{ "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,	{ RT } },
+-{ "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,	{ RT } },
+-{ "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,	{ RT } },
+-{ "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,	{ RT } },
+-{ "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,	{ RT } },
+-{ "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfpvr",      XSPR(31,339,287),  XSPR_MASK, PPC,	{ RT } },
+-{ "mfdbsr",     XSPR(31,339,304),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfdbsr",     XSPR(31,339,1008), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdbcr0",    XSPR(31,339,308),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfdbcr0",    XSPR(31,339,1010), XSPR_MASK, PPC405,	{ RT } },
+-{ "mfdbcr1",    XSPR(31,339,309),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfdbcr1",    XSPR(31,339,957),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfdbcr2",    XSPR(31,339,310),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfiac1",     XSPR(31,339,312),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfiac1",     XSPR(31,339,1012), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfiac2",     XSPR(31,339,313),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfiac2",     XSPR(31,339,1013), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfiac3",     XSPR(31,339,314),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfiac3",     XSPR(31,339,948),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfiac4",     XSPR(31,339,315),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfiac4",     XSPR(31,339,949),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfdac1",     XSPR(31,339,316),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfdac1",     XSPR(31,339,1014), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdac2",     XSPR(31,339,317),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfdac2",     XSPR(31,339,1015), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfdvc1",     XSPR(31,339,318),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfdvc1",     XSPR(31,339,950),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfdvc2",     XSPR(31,339,319),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfdvc2",     XSPR(31,339,951),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mftsr",      XSPR(31,339,336),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mftsr",      XSPR(31,339,984),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mftcr",      XSPR(31,339,340),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mftcr",      XSPR(31,339,986),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfivor0",    XSPR(31,339,400),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor1",    XSPR(31,339,401),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor2",    XSPR(31,339,402),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor3",    XSPR(31,339,403),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor4",    XSPR(31,339,404),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor5",    XSPR(31,339,405),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor6",    XSPR(31,339,406),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor7",    XSPR(31,339,407),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor8",    XSPR(31,339,408),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor9",    XSPR(31,339,409),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor10",   XSPR(31,339,410),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor11",   XSPR(31,339,411),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor12",   XSPR(31,339,412),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor13",   XSPR(31,339,413),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor14",   XSPR(31,339,414),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfivor15",   XSPR(31,339,415),  XSPR_MASK, BOOKE,    { RT } },
+-{ "mfspefscr",  XSPR(31,339,512),  XSPR_MASK, PPCSPE,	{ RT } },
+-{ "mfbbear",    XSPR(31,339,513),  XSPR_MASK, PPCBRLK,  { RT } },
+-{ "mfbbtar",    XSPR(31,339,514),  XSPR_MASK, PPCBRLK,  { RT } },
+-{ "mfibatu",    XSPR(31,339,528),  XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+-{ "mfibatl",    XSPR(31,339,529),  XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+-{ "mfdbatu",    XSPR(31,339,536),  XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+-{ "mfdbatl",    XSPR(31,339,537),  XSPRBAT_MASK, PPC,	{ RT, SPRBAT } },
+-{ "mfic_cst",   XSPR(31,339,560),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfic_adr",   XSPR(31,339,561),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfic_dat",   XSPR(31,339,562),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfdc_cst",   XSPR(31,339,568),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfdc_adr",   XSPR(31,339,569),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfdc_dat",   XSPR(31,339,570),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmcsrr0",   XSPR(31,339,570),  XSPR_MASK, PPCRFMCI, { RT } },
+-{ "mfmcsrr1",   XSPR(31,339,571),  XSPR_MASK, PPCRFMCI, { RT } },
+-{ "mfmcsr",     XSPR(31,339,572),  XSPR_MASK, PPCRFMCI, { RT } },
+-{ "mfdpdr",     XSPR(31,339,630),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfdpir",     XSPR(31,339,631),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfimmr",     XSPR(31,339,638),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmi_ctr",   XSPR(31,339,784),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmi_ap",    XSPR(31,339,786),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmi_epn",   XSPR(31,339,787),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmi_twc",   XSPR(31,339,789),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmi_rpn",   XSPR(31,339,790),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmd_ctr",   XSPR(31,339,792),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfm_casid",  XSPR(31,339,793),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmd_ap",    XSPR(31,339,794),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmd_epn",   XSPR(31,339,795),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmd_twb",   XSPR(31,339,796),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmd_twc",   XSPR(31,339,797),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmd_rpn",   XSPR(31,339,798),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfm_tw",     XSPR(31,339,799),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmi_dbcam", XSPR(31,339,816),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmi_dbram0",XSPR(31,339,817),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmi_dbram1",XSPR(31,339,818),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmd_dbcam", XSPR(31,339,824),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmd_dbram0",XSPR(31,339,825),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfmd_dbram1",XSPR(31,339,826),  XSPR_MASK, PPC860,	{ RT } },
+-{ "mfummcr0",   XSPR(31,339,936),  XSPR_MASK, PPC750,   { RT } },
+-{ "mfupmc1",    XSPR(31,339,937),  XSPR_MASK, PPC750,   { RT } },
+-{ "mfupmc2",    XSPR(31,339,938),  XSPR_MASK, PPC750,   { RT } },
+-{ "mfusia",     XSPR(31,339,939),  XSPR_MASK, PPC750,   { RT } },
+-{ "mfummcr1",   XSPR(31,339,940),  XSPR_MASK, PPC750,   { RT } },
+-{ "mfupmc3",    XSPR(31,339,941),  XSPR_MASK, PPC750,   { RT } },
+-{ "mfupmc4",    XSPR(31,339,942),  XSPR_MASK, PPC750,   { RT } },
+-{ "mfzpr",   	XSPR(31,339,944),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfccr0",  	XSPR(31,339,947),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfmmcr0",	XSPR(31,339,952),  XSPR_MASK, PPC750,	{ RT } },
+-{ "mfpmc1",	XSPR(31,339,953),  XSPR_MASK, PPC750,	{ RT } },
+-{ "mfsgr",	XSPR(31,339,953),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfpmc2",	XSPR(31,339,954),  XSPR_MASK, PPC750,	{ RT } },
+-{ "mfdcwr", 	XSPR(31,339,954),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfsia",	XSPR(31,339,955),  XSPR_MASK, PPC750,	{ RT } },
+-{ "mfsler",	XSPR(31,339,955),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfmmcr1",	XSPR(31,339,956),  XSPR_MASK, PPC750,	{ RT } },
+-{ "mfsu0r",	XSPR(31,339,956),  XSPR_MASK, PPC405,	{ RT } },
+-{ "mfpmc3",	XSPR(31,339,957),  XSPR_MASK, PPC750,	{ RT } },
+-{ "mfpmc4",	XSPR(31,339,958),  XSPR_MASK, PPC750,	{ RT } },
+-{ "mficdbdr",   XSPR(31,339,979),  XSPR_MASK, PPC403,   { RT } },
+-{ "mfevpr",     XSPR(31,339,982),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfcdbcr",    XSPR(31,339,983),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfpit",      XSPR(31,339,987),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mftbhi",     XSPR(31,339,988),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mftblo",     XSPR(31,339,989),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfsrr2",     XSPR(31,339,990),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfsrr3",     XSPR(31,339,991),  XSPR_MASK, PPC403,	{ RT } },
+-{ "mfl2cr",     XSPR(31,339,1017), XSPR_MASK, PPC750,   { RT } },
+-{ "mfdccr",     XSPR(31,339,1018), XSPR_MASK, PPC403,	{ RT } },
+-{ "mficcr",     XSPR(31,339,1019), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfictc",     XSPR(31,339,1019), XSPR_MASK, PPC750,   { RT } },
+-{ "mfpbl1",     XSPR(31,339,1020), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfthrm1",    XSPR(31,339,1020), XSPR_MASK, PPC750,   { RT } },
+-{ "mfpbu1",     XSPR(31,339,1021), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfthrm2",    XSPR(31,339,1021), XSPR_MASK, PPC750,   { RT } },
+-{ "mfpbl2",     XSPR(31,339,1022), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfthrm3",    XSPR(31,339,1022), XSPR_MASK, PPC750,   { RT } },
+-{ "mfpbu2",     XSPR(31,339,1023), XSPR_MASK, PPC403,	{ RT } },
+-{ "mfspr",      X(31,339),	   X_MASK,    COM,	{ RT, SPR } },
+-
+-{ "lwax",    X(31,341),	X_MASK,		PPC64,		{ RT, RA, RB } },
+-
+-{ "dst",     XDSS(31,342,0), XDSS_MASK,	PPCVEC,		{ RA, RB, STRM } },
+-{ "dstt",    XDSS(31,342,1), XDSS_MASK,	PPCVEC,		{ RA, RB, STRM } },
+-
+-{ "lhax",    X(31,343),	X_MASK,		COM,		{ RT, RA, RB } },
+-
+-{ "lhaxe",   X(31,351),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
+-
+-{ "dstst",   XDSS(31,374,0), XDSS_MASK,	PPCVEC,		{ RA, RB, STRM } },
+-{ "dststt",  XDSS(31,374,1), XDSS_MASK,	PPCVEC,		{ RA, RB, STRM } },
+-
+-{ "dccci",   X(31,454),	XRT_MASK,	PPC403|PPC440,	{ RA, RB } },
+-
+-{ "abs",     XO(31,360,0,0), XORB_MASK, M601,		{ RT, RA } },
+-{ "abs.",    XO(31,360,0,1), XORB_MASK, M601,		{ RT, RA } },
+-{ "abso",    XO(31,360,1,0), XORB_MASK, M601,		{ RT, RA } },
+-{ "abso.",   XO(31,360,1,1), XORB_MASK, M601,		{ RT, RA } },
+-
+-{ "divs",    XO(31,363,0,0), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "divs.",   XO(31,363,0,1), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "divso",   XO(31,363,1,0), XO_MASK,	M601,		{ RT, RA, RB } },
+-{ "divso.",  XO(31,363,1,1), XO_MASK,	M601,		{ RT, RA, RB } },
+-
+-{ "tlbia",   X(31,370),	0xffffffff,	PPC,		{ 0 } },
+-
+-{ "lwaux",   X(31,373),	X_MASK,		PPC64,		{ RT, RAL, RB } },
+-
+-{ "lhaux",   X(31,375),	X_MASK,		COM,		{ RT, RAL, RB } },
+-
+-{ "lhauxe",  X(31,383),	X_MASK,		BOOKE64,	{ RT, RAL, RB } },
+-
+-{ "mtdcrx",  X(31,387),	X_MASK,		BOOKE,		{ RA, RS } },
+-
+-{ "dcblc",   X(31,390),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
+-
+-{ "subfe64", XO(31,392,0,0), XO_MASK,	BOOKE64,	{ RT, RA, RB } },
+-{ "subfe64o",XO(31,392,1,0), XO_MASK,	BOOKE64,	{ RT, RA, RB } },
+-
+-{ "adde64",  XO(31,394,0,0), XO_MASK,	BOOKE64,	{ RT, RA, RB } },
+-{ "adde64o", XO(31,394,1,0), XO_MASK,	BOOKE64,	{ RT, RA, RB } },
+-
+-{ "dcblce",  X(31,398),	X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
+-
+-{ "slbmte",  X(31,402), XRA_MASK,	PPC64,		{ RS, RB } },
+-
+-{ "sthx",    X(31,407),	X_MASK,		COM,		{ RS, RA, RB } },
+-
+-{ "lfqx",    X(31,791),	X_MASK,		POWER2,		{ FRT, RA, RB } },
+-
+-{ "lfqux",   X(31,823),	X_MASK,		POWER2,		{ FRT, RA, RB } },
+-
+-{ "stfqx",   X(31,919),	X_MASK,		POWER2,		{ FRS, RA, RB } },
+-
+-{ "stfqux",  X(31,951),	X_MASK,		POWER2,		{ FRS, RA, RB } },
+-
+-{ "orc",     XRC(31,412,0), X_MASK,	COM,		{ RA, RS, RB } },
+-{ "orc.",    XRC(31,412,1), X_MASK,	COM,		{ RA, RS, RB } },
+-
+-{ "sradi",   XS(31,413,0), XS_MASK,	PPC64,		{ RA, RS, SH6 } },
+-{ "sradi.",  XS(31,413,1), XS_MASK,	PPC64,		{ RA, RS, SH6 } },
+-
+-{ "sthxe",   X(31,415),	X_MASK,		BOOKE64,	{ RS, RA, RB } },
+-
+-{ "slbie",   X(31,434),	XRTRA_MASK,	PPC64,		{ RB } },
+-
+-{ "ecowx",   X(31,438),	X_MASK,		PPC,		{ RT, RA, RB } },
+-
+-{ "sthux",   X(31,439),	X_MASK,		COM,		{ RS, RAS, RB } },
+-
+-{ "sthuxe",  X(31,447),	X_MASK,		BOOKE64,	{ RS, RAS, RB } },
+-
+-{ "mr",	     XRC(31,444,0), X_MASK,	COM,		{ RA, RS, RBS } },
+-{ "or",      XRC(31,444,0), X_MASK,	COM,		{ RA, RS, RB } },
+-{ "mr.",     XRC(31,444,1), X_MASK,	COM,		{ RA, RS, RBS } },
+-{ "or.",     XRC(31,444,1), X_MASK,	COM,		{ RA, RS, RB } },
+-
+-{ "mtexisr",  XSPR(31,451,64),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtexier",  XSPR(31,451,66),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbr0",    XSPR(31,451,128), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbr1",    XSPR(31,451,129), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbr2",    XSPR(31,451,130), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbr3",    XSPR(31,451,131), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbr4",    XSPR(31,451,132), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbr5",    XSPR(31,451,133), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbr6",    XSPR(31,451,134), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbr7",    XSPR(31,451,135), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbear",   XSPR(31,451,144), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtbesr",   XSPR(31,451,145), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtiocr",   XSPR(31,451,160), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmacr0", XSPR(31,451,192), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmact0", XSPR(31,451,193), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmada0", XSPR(31,451,194), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmasa0", XSPR(31,451,195), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmacc0", XSPR(31,451,196), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmacr1", XSPR(31,451,200), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmact1", XSPR(31,451,201), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmada1", XSPR(31,451,202), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmasa1", XSPR(31,451,203), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmacc1", XSPR(31,451,204), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmacr2", XSPR(31,451,208), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmact2", XSPR(31,451,209), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmada2", XSPR(31,451,210), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmasa2", XSPR(31,451,211), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmacc2", XSPR(31,451,212), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmacr3", XSPR(31,451,216), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmact3", XSPR(31,451,217), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmada3", XSPR(31,451,218), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmasa3", XSPR(31,451,219), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmacc3", XSPR(31,451,220), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdmasr",  XSPR(31,451,224), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdcr",    X(31,451),	X_MASK,	PPC403 | BOOKE,	{ SPR, RS } },
+-
+-{ "subfze64",XO(31,456,0,0), XORB_MASK, BOOKE64,	{ RT, RA } },
+-{ "subfze64o",XO(31,456,1,0), XORB_MASK, BOOKE64,	{ RT, RA } },
+-
+-{ "divdu",   XO(31,457,0,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "divdu.",  XO(31,457,0,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "divduo",  XO(31,457,1,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "divduo.", XO(31,457,1,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-
+-{ "addze64", XO(31,458,0,0), XORB_MASK, BOOKE64,	{ RT, RA } },
+-{ "addze64o",XO(31,458,1,0), XORB_MASK, BOOKE64,	{ RT, RA } },
+-
+-{ "divwu",   XO(31,459,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "divwu.",  XO(31,459,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "divwuo",  XO(31,459,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "divwuo.", XO(31,459,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+-
+-{ "mtmq",      XSPR(31,467,0),    XSPR_MASK, M601,	{ RS } },
+-{ "mtxer",     XSPR(31,467,1),    XSPR_MASK, COM,	{ RS } },
+-{ "mtlr",      XSPR(31,467,8),    XSPR_MASK, COM,	{ RS } },
+-{ "mtctr",     XSPR(31,467,9),    XSPR_MASK, COM,	{ RS } },
+-{ "mttid",     XSPR(31,467,17),   XSPR_MASK, POWER,	{ RS } },
+-{ "mtdsisr",   XSPR(31,467,18),   XSPR_MASK, COM,	{ RS } },
+-{ "mtdar",     XSPR(31,467,19),   XSPR_MASK, COM,	{ RS } },
+-{ "mtrtcu",    XSPR(31,467,20),   XSPR_MASK, COM,	{ RS } },
+-{ "mtrtcl",    XSPR(31,467,21),   XSPR_MASK, COM,	{ RS } },
+-{ "mtdec",     XSPR(31,467,22),   XSPR_MASK, COM,	{ RS } },
+-{ "mtsdr0",    XSPR(31,467,24),   XSPR_MASK, POWER,	{ RS } },
+-{ "mtsdr1",    XSPR(31,467,25),   XSPR_MASK, COM,	{ RS } },
+-{ "mtsrr0",    XSPR(31,467,26),   XSPR_MASK, COM,	{ RS } },
+-{ "mtsrr1",    XSPR(31,467,27),   XSPR_MASK, COM,	{ RS } },
+-{ "mtpid",     XSPR(31,467,48),   XSPR_MASK, BOOKE,     { RS } },
+-{ "mtpid",     XSPR(31,467,945),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdecar",   XSPR(31,467,54),   XSPR_MASK, BOOKE,     { RS } },
+-{ "mtcsrr0",   XSPR(31,467,58),   XSPR_MASK, BOOKE,     { RS } },
+-{ "mtcsrr1",   XSPR(31,467,59),   XSPR_MASK, BOOKE,     { RS } },
+-{ "mtdear",    XSPR(31,467,61),   XSPR_MASK, BOOKE,     { RS } },
+-{ "mtdear",    XSPR(31,467,981),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtesr",     XSPR(31,467,62),   XSPR_MASK, BOOKE,     { RS } },
+-{ "mtesr",     XSPR(31,467,980),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtivpr",    XSPR(31,467,63),   XSPR_MASK, BOOKE,     { RS } },
+-{ "mtcmpa",    XSPR(31,467,144),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtcmpb",    XSPR(31,467,145),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtcmpc",    XSPR(31,467,146),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtcmpd",    XSPR(31,467,147),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mticr",     XSPR(31,467,148),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtder",     XSPR(31,467,149),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtcounta",  XSPR(31,467,150),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtcountb",  XSPR(31,467,151),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtcmpe",    XSPR(31,467,152),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtcmpf",    XSPR(31,467,153),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtcmpg",    XSPR(31,467,154),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtcmph",    XSPR(31,467,155),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtlctrl1",  XSPR(31,467,156),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtlctrl2",  XSPR(31,467,157),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtictrl",   XSPR(31,467,158),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtbar",     XSPR(31,467,159),  XSPR_MASK, PPC860,	{ RS } },
+-{ "mtvrsave",  XSPR(31,467,256),  XSPR_MASK, PPCVEC,	{ RS } },
+-{ "mtusprg0",  XSPR(31,467,256),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtsprg",    XSPR(31,467,272),  XSPRG_MASK,PPC,	{ SPRG, RS } },
+-{ "mtsprg0",   XSPR(31,467,272),  XSPR_MASK, PPC,	{ RS } },
+-{ "mtsprg1",   XSPR(31,467,273),  XSPR_MASK, PPC,	{ RS } },
+-{ "mtsprg2",   XSPR(31,467,274),  XSPR_MASK, PPC,	{ RS } },
+-{ "mtsprg3",   XSPR(31,467,275),  XSPR_MASK, PPC,	{ RS } },
+-{ "mtsprg4",   XSPR(31,467,276),  XSPR_MASK, PPC405 | BOOKE, { RS } },
+-{ "mtsprg5",   XSPR(31,467,277),  XSPR_MASK, PPC405 | BOOKE, { RS } },
+-{ "mtsprg6",   XSPR(31,467,278),  XSPR_MASK, PPC405 | BOOKE, { RS } },
+-{ "mtsprg7",   XSPR(31,467,279),  XSPR_MASK, PPC405 | BOOKE, { RS } },
+-{ "mtasr",     XSPR(31,467,280),  XSPR_MASK, PPC64,	{ RS } },
+-{ "mtear",     XSPR(31,467,282),  XSPR_MASK, PPC,	{ RS } },
+-{ "mttbl",     XSPR(31,467,284),  XSPR_MASK, PPC,	{ RS } },
+-{ "mttbu",     XSPR(31,467,285),  XSPR_MASK, PPC,	{ RS } },
+-{ "mtdbsr",    XSPR(31,467,304),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtdbsr",    XSPR(31,467,1008), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdbcr0",   XSPR(31,467,308),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtdbcr0",   XSPR(31,467,1010), XSPR_MASK, PPC405,	{ RS } },
+-{ "mtdbcr1",   XSPR(31,467,309),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtdbcr1",   XSPR(31,467,957),  XSPR_MASK, PPC405,	{ RS } },
+-{ "mtdbcr2",   XSPR(31,467,310),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtiac1",    XSPR(31,467,312),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtiac1",    XSPR(31,467,1012), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtiac2",    XSPR(31,467,313),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtiac2",    XSPR(31,467,1013), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtiac3",    XSPR(31,467,314),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtiac3",    XSPR(31,467,948),  XSPR_MASK, PPC405,	{ RS } },
+-{ "mtiac4",    XSPR(31,467,315),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtiac4",    XSPR(31,467,949),  XSPR_MASK, PPC405,	{ RS } },
+-{ "mtdac1",    XSPR(31,467,316),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtdac1",    XSPR(31,467,1014), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdac2",    XSPR(31,467,317),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtdac2",    XSPR(31,467,1015), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtdvc1",    XSPR(31,467,318),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtdvc1",    XSPR(31,467,950),  XSPR_MASK, PPC405,	{ RS } },
+-{ "mtdvc2",    XSPR(31,467,319),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtdvc2",    XSPR(31,467,951),  XSPR_MASK, PPC405,	{ RS } },
+-{ "mttsr",     XSPR(31,467,336),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mttsr",     XSPR(31,467,984),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mttcr",     XSPR(31,467,340),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mttcr",     XSPR(31,467,986),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtivor0",   XSPR(31,467,400),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor1",   XSPR(31,467,401),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor2",   XSPR(31,467,402),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor3",   XSPR(31,467,403),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor4",   XSPR(31,467,404),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor5",   XSPR(31,467,405),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor6",   XSPR(31,467,406),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor7",   XSPR(31,467,407),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor8",   XSPR(31,467,408),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor9",   XSPR(31,467,409),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor10",  XSPR(31,467,410),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor11",  XSPR(31,467,411),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor12",  XSPR(31,467,412),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor13",  XSPR(31,467,413),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor14",  XSPR(31,467,414),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtivor15",  XSPR(31,467,415),  XSPR_MASK, BOOKE,     { RS } },
+-{ "mtspefscr",  XSPR(31,467,512),  XSPR_MASK, PPCSPE,   { RS } },
+-{ "mtbbear",   XSPR(31,467,513),  XSPR_MASK, PPCBRLK,   { RS } },
+-{ "mtbbtar",   XSPR(31,467,514),  XSPR_MASK, PPCBRLK,  { RS } },
+-{ "mtibatu",   XSPR(31,467,528),  XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+-{ "mtibatl",   XSPR(31,467,529),  XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+-{ "mtdbatu",   XSPR(31,467,536),  XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+-{ "mtdbatl",   XSPR(31,467,537),  XSPRBAT_MASK, PPC,	{ SPRBAT, RS } },
+-{ "mtmcsrr0",  XSPR(31,467,570),  XSPR_MASK, PPCRFMCI,  { RS } },
+-{ "mtmcsrr1",  XSPR(31,467,571),  XSPR_MASK, PPCRFMCI,  { RS } },
+-{ "mtmcsr",    XSPR(31,467,572),  XSPR_MASK, PPCRFMCI,  { RS } },
+-{ "mtummcr0",  XSPR(31,467,936),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtupmc1",   XSPR(31,467,937),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtupmc2",   XSPR(31,467,938),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtusia",    XSPR(31,467,939),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtummcr1",  XSPR(31,467,940),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtupmc3",   XSPR(31,467,941),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtupmc4",   XSPR(31,467,942),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtzpr",     XSPR(31,467,944),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtccr0",    XSPR(31,467,947),  XSPR_MASK, PPC405,	{ RS } },
+-{ "mtmmcr0",   XSPR(31,467,952),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtsgr",     XSPR(31,467,953),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtpmc1",    XSPR(31,467,953),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtdcwr",    XSPR(31,467,954),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtpmc2",    XSPR(31,467,954),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtsler",    XSPR(31,467,955),  XSPR_MASK, PPC405,	{ RS } },
+-{ "mtsia",     XSPR(31,467,955),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtsu0r",    XSPR(31,467,956),  XSPR_MASK, PPC405,	{ RS } },
+-{ "mtmmcr1",   XSPR(31,467,956),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtpmc3",    XSPR(31,467,957),  XSPR_MASK, PPC750,    { RS } },
+-{ "mtpmc4",    XSPR(31,467,958),  XSPR_MASK, PPC750,    { RS } },
+-{ "mticdbdr",  XSPR(31,467,979),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtevpr",    XSPR(31,467,982),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtcdbcr",   XSPR(31,467,983),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtpit",     XSPR(31,467,987),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mttbhi",    XSPR(31,467,988),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mttblo",    XSPR(31,467,989),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtsrr2",    XSPR(31,467,990),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtsrr3",    XSPR(31,467,991),  XSPR_MASK, PPC403,	{ RS } },
+-{ "mtl2cr",    XSPR(31,467,1017), XSPR_MASK, PPC750,    { RS } },
+-{ "mtdccr",    XSPR(31,467,1018), XSPR_MASK, PPC403,	{ RS } },
+-{ "mticcr",    XSPR(31,467,1019), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtictc",    XSPR(31,467,1019), XSPR_MASK, PPC750,    { RS } },
+-{ "mtpbl1",    XSPR(31,467,1020), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtthrm1",   XSPR(31,467,1020), XSPR_MASK, PPC750,    { RS } },
+-{ "mtpbu1",    XSPR(31,467,1021), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtthrm2",   XSPR(31,467,1021), XSPR_MASK, PPC750,    { RS } },
+-{ "mtpbl2",    XSPR(31,467,1022), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtthrm3",   XSPR(31,467,1022), XSPR_MASK, PPC750,    { RS } },
+-{ "mtpbu2",    XSPR(31,467,1023), XSPR_MASK, PPC403,	{ RS } },
+-{ "mtspr",     X(31,467),	  X_MASK,    COM,	{ SPR, RS } },
+-
+-{ "dcbi",    X(31,470),	XRT_MASK,	PPC,		{ RA, RB } },
+-
+-{ "nand",    XRC(31,476,0), X_MASK,	COM,		{ RA, RS, RB } },
+-{ "nand.",   XRC(31,476,1), X_MASK,	COM,		{ RA, RS, RB } },
+-
+-{ "dcbie",   X(31,478),	XRT_MASK,	BOOKE64,	{ RA, RB } },
+-
+-{ "dcread",  X(31,486),	X_MASK,		PPC403|PPC440,	{ RT, RA, RB }},
+-
+-{ "mtpmr",   X(31,462),	X_MASK,		PPCPMR,		{ PMR, RS }},
+-
+-{ "icbtls",  X(31,486),	X_MASK,		PPCCHLK,	{ CT, RA, RB }},
+-
+-{ "nabs",    XO(31,488,0,0), XORB_MASK, M601,		{ RT, RA } },
+-{ "subfme64",XO(31,488,0,0), XORB_MASK, BOOKE64,	{ RT, RA } },
+-{ "nabs.",   XO(31,488,0,1), XORB_MASK, M601,		{ RT, RA } },
+-{ "nabso",   XO(31,488,1,0), XORB_MASK, M601,		{ RT, RA } },
+-{ "subfme64o",XO(31,488,1,0), XORB_MASK, BOOKE64,	{ RT, RA } },
+-{ "nabso.",  XO(31,488,1,1), XORB_MASK, M601,		{ RT, RA } },
+-
+-{ "divd",    XO(31,489,0,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "divd.",   XO(31,489,0,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "divdo",   XO(31,489,1,0), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-{ "divdo.",  XO(31,489,1,1), XO_MASK,	PPC64,		{ RT, RA, RB } },
+-
+-{ "addme64", XO(31,490,0,0), XORB_MASK, BOOKE64,	{ RT, RA } },
+-{ "addme64o",XO(31,490,1,0), XORB_MASK, BOOKE64,	{ RT, RA } },
+-
+-{ "divw",    XO(31,491,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "divw.",   XO(31,491,0,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "divwo",   XO(31,491,1,0), XO_MASK,	PPC,		{ RT, RA, RB } },
+-{ "divwo.",  XO(31,491,1,1), XO_MASK,	PPC,		{ RT, RA, RB } },
+-
+-{ "icbtlse", X(31,494),	X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
+-
+-{ "slbia",   X(31,498),	0xffffffff,	PPC64,		{ 0 } },
+-
+-{ "cli",     X(31,502), XRB_MASK,	POWER,		{ RT, RA } },
+-
+-{ "stdcxe.", XRC(31,511,1), X_MASK,	BOOKE64,	{ RS, RA, RB } },
+-
+-{ "mcrxr",   X(31,512),	XRARB_MASK|(3<<21), COM,	{ BF } },
+-
+-{ "bblels",  X(31,518),	X_MASK,		PPCBRLK,	{ 0 }},
+-{ "mcrxr64", X(31,544),	XRARB_MASK|(3<<21), BOOKE64,	{ BF } },
+-
+-{ "clcs",    X(31,531), XRB_MASK,	M601,		{ RT, RA } },
+-
+-{ "lswx",    X(31,533),	X_MASK,		PPCCOM,		{ RT, RA, RB } },
+-{ "lsx",     X(31,533),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
+-
+-{ "lwbrx",   X(31,534),	X_MASK,		PPCCOM,		{ RT, RA, RB } },
+-{ "lbrx",    X(31,534),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
+-
+-{ "lfsx",    X(31,535),	X_MASK,		COM,		{ FRT, RA, RB } },
+-
+-{ "srw",     XRC(31,536,0), X_MASK,	PPCCOM,		{ RA, RS, RB } },
+-{ "sr",      XRC(31,536,0), X_MASK,	PWRCOM,		{ RA, RS, RB } },
+-{ "srw.",    XRC(31,536,1), X_MASK,	PPCCOM,		{ RA, RS, RB } },
+-{ "sr.",     XRC(31,536,1), X_MASK,	PWRCOM,		{ RA, RS, RB } },
+-
+-{ "rrib",    XRC(31,537,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "rrib.",   XRC(31,537,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "srd",     XRC(31,539,0), X_MASK,	PPC64,		{ RA, RS, RB } },
+-{ "srd.",    XRC(31,539,1), X_MASK,	PPC64,		{ RA, RS, RB } },
+-
+-{ "maskir",  XRC(31,541,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "maskir.", XRC(31,541,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "lwbrxe",  X(31,542),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
+-
+-{ "lfsxe",   X(31,543),	X_MASK,		BOOKE64,	{ FRT, RA, RB } },
+-
+-{ "bbelr",   X(31,550),	X_MASK,		PPCBRLK,	{ 0 }},
+-{ "tlbsync", X(31,566),	0xffffffff,	PPC,		{ 0 } },
+-
+-{ "lfsux",   X(31,567),	X_MASK,		COM,		{ FRT, RAS, RB } },
+-
+-{ "lfsuxe",  X(31,575),	X_MASK,		BOOKE64,	{ FRT, RAS, RB } },
+-
+-{ "mfsr",    X(31,595),	XRB_MASK|(1<<20), COM32,	{ RT, SR } },
+-
+-{ "lswi",    X(31,597),	X_MASK,		PPCCOM,		{ RT, RA, NB } },
+-{ "lsi",     X(31,597),	X_MASK,		PWRCOM,		{ RT, RA, NB } },
+-
+-{ "lwsync",  XSYNC(31,598,1), 0xffffffff, PPC,		{ 0 } },
+-{ "ptesync", XSYNC(31,598,2), 0xffffffff, PPC64,	{ 0 } },
+-{ "msync",   X(31,598), 0xffffffff,	BOOKE,		{ 0 } },
+-{ "sync",    X(31,598), XSYNC_MASK,	PPCCOM,		{ LS } },
+-{ "dcs",     X(31,598), 0xffffffff,	PWRCOM,		{ 0 } },
+-
+-{ "lfdx",    X(31,599), X_MASK,		COM,		{ FRT, RA, RB } },
+-
+-{ "lfdxe",   X(31,607), X_MASK,		BOOKE64,	{ FRT, RA, RB } },
+-
+-{ "mfsri",   X(31,627), X_MASK,		PWRCOM,		{ RT, RA, RB } },
+-
+-{ "dclst",   X(31,630), XRB_MASK,	PWRCOM,		{ RS, RA } },
+-
+-{ "lfdux",   X(31,631), X_MASK,		COM,		{ FRT, RAS, RB } },
+-
+-{ "lfduxe",  X(31,639), X_MASK,		BOOKE64,	{ FRT, RAS, RB } },
+-
+-{ "mfsrin",  X(31,659), XRA_MASK,	PPC32,		{ RT, RB } },
+-
+-{ "stswx",   X(31,661), X_MASK,		PPCCOM,		{ RS, RA, RB } },
+-{ "stsx",    X(31,661), X_MASK,		PWRCOM,		{ RS, RA, RB } },
+-
+-{ "stwbrx",  X(31,662), X_MASK,		PPCCOM,		{ RS, RA, RB } },
+-{ "stbrx",   X(31,662), X_MASK,		PWRCOM,		{ RS, RA, RB } },
+-
+-{ "stfsx",   X(31,663), X_MASK,		COM,		{ FRS, RA, RB } },
+-
+-{ "srq",     XRC(31,664,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "srq.",    XRC(31,664,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "sre",     XRC(31,665,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "sre.",    XRC(31,665,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "stwbrxe", X(31,670), X_MASK,		BOOKE64,	{ RS, RA, RB } },
+-
+-{ "stfsxe",  X(31,671), X_MASK,		BOOKE64,	{ FRS, RA, RB } },
+-
+-{ "stfsux",  X(31,695),	X_MASK,		COM,		{ FRS, RAS, RB } },
+-
+-{ "sriq",    XRC(31,696,0), X_MASK,	M601,		{ RA, RS, SH } },
+-{ "sriq.",   XRC(31,696,1), X_MASK,	M601,		{ RA, RS, SH } },
+-
+-{ "stfsuxe", X(31,703),	X_MASK,		BOOKE64,	{ FRS, RAS, RB } },
+-
+-{ "stswi",   X(31,725),	X_MASK,		PPCCOM,		{ RS, RA, NB } },
+-{ "stsi",    X(31,725),	X_MASK,		PWRCOM,		{ RS, RA, NB } },
+-
+-{ "stfdx",   X(31,727),	X_MASK,		COM,		{ FRS, RA, RB } },
+-
+-{ "srlq",    XRC(31,728,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "srlq.",   XRC(31,728,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "sreq",    XRC(31,729,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "sreq.",   XRC(31,729,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "stfdxe",  X(31,735),	X_MASK,		BOOKE64,	{ FRS, RA, RB } },
+-
+-{ "dcba",    X(31,758),	XRT_MASK,	PPC405 | BOOKE,	{ RA, RB } },
+-
+-{ "stfdux",  X(31,759),	X_MASK,		COM,		{ FRS, RAS, RB } },
+-
+-{ "srliq",   XRC(31,760,0), X_MASK,	M601,		{ RA, RS, SH } },
+-{ "srliq.",  XRC(31,760,1), X_MASK,	M601,		{ RA, RS, SH } },
+-
+-{ "dcbae",   X(31,766),	XRT_MASK,	BOOKE64,	{ RA, RB } },
+-
+-{ "stfduxe", X(31,767),	X_MASK,		BOOKE64,	{ FRS, RAS, RB } },
+-
+-{ "tlbivax", X(31,786),	XRT_MASK,	BOOKE,		{ RA, RB } },
+-{ "tlbivaxe",X(31,787),	XRT_MASK,	BOOKE64,	{ RA, RB } },
+-
+-{ "lhbrx",   X(31,790),	X_MASK,		COM,		{ RT, RA, RB } },
+-
+-{ "sraw",    XRC(31,792,0), X_MASK,	PPCCOM,		{ RA, RS, RB } },
+-{ "sra",     XRC(31,792,0), X_MASK,	PWRCOM,		{ RA, RS, RB } },
+-{ "sraw.",   XRC(31,792,1), X_MASK,	PPCCOM,		{ RA, RS, RB } },
+-{ "sra.",    XRC(31,792,1), X_MASK,	PWRCOM,		{ RA, RS, RB } },
+-
+-{ "srad",    XRC(31,794,0), X_MASK,	PPC64,		{ RA, RS, RB } },
+-{ "srad.",   XRC(31,794,1), X_MASK,	PPC64,		{ RA, RS, RB } },
+-
+-{ "lhbrxe",  X(31,798),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
+-
+-{ "ldxe",    X(31,799),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
+-{ "lduxe",   X(31,831),	X_MASK,		BOOKE64,	{ RT, RA, RB } },
+-
+-{ "rac",     X(31,818),	X_MASK,		PWRCOM,		{ RT, RA, RB } },
+-
+-{ "dss",     XDSS(31,822,0), XDSS_MASK,	PPCVEC,		{ STRM } },
+-{ "dssall",  XDSS(31,822,1), XDSS_MASK,	PPCVEC,		{ 0 } },
+-
+-{ "srawi",   XRC(31,824,0), X_MASK,	PPCCOM,		{ RA, RS, SH } },
+-{ "srai",    XRC(31,824,0), X_MASK,	PWRCOM,		{ RA, RS, SH } },
+-{ "srawi.",  XRC(31,824,1), X_MASK,	PPCCOM,		{ RA, RS, SH } },
+-{ "srai.",   XRC(31,824,1), X_MASK,	PWRCOM,		{ RA, RS, SH } },
+-
+-{ "slbmfev", X(31,851), XRA_MASK,	PPC64,		{ RT, RB } },
+-
+-{ "mbar",    X(31,854),	X_MASK,		BOOKE,		{ MO } },
+-{ "eieio",   X(31,854),	0xffffffff,	PPC,		{ 0 } },
+-
+-{ "tlbsx",   XRC(31,914,0), X_MASK,	BOOKE,		{ RA, RB } },
+-{ "tlbsx",   XRC(31,914,0), X_MASK, 	PPC403,		{ RT, RA, RB } },
+-{ "tlbsx.",  XRC(31,914,1), X_MASK,	BOOKE,		{ RA, RB } },
+-{ "tlbsx.",  XRC(31,914,1), X_MASK, 	PPC403,		{ RT, RA, RB } },
+-{ "tlbsxe",  XRC(31,915,0), X_MASK,	BOOKE64,	{ RA, RB } },
+-{ "tlbsxe.", XRC(31,915,1), X_MASK,	BOOKE64,	{ RA, RB } },
+-
+-{ "slbmfee", X(31,915), XRA_MASK,	PPC64,		{ RT, RB } },
+-
+-{ "sthbrx",  X(31,918),	X_MASK,		COM,		{ RS, RA, RB } },
+-
+-{ "sraq",    XRC(31,920,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "sraq.",   XRC(31,920,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "srea",    XRC(31,921,0), X_MASK,	M601,		{ RA, RS, RB } },
+-{ "srea.",   XRC(31,921,1), X_MASK,	M601,		{ RA, RS, RB } },
+-
+-{ "extsh",   XRC(31,922,0), XRB_MASK,	PPCCOM,		{ RA, RS } },
+-{ "exts",    XRC(31,922,0), XRB_MASK,	PWRCOM,		{ RA, RS } },
+-{ "extsh.",  XRC(31,922,1), XRB_MASK,	PPCCOM,		{ RA, RS } },
+-{ "exts.",   XRC(31,922,1), XRB_MASK,	PWRCOM,		{ RA, RS } },
+-
+-{ "sthbrxe", X(31,926),	X_MASK,		BOOKE64,	{ RS, RA, RB } },
+-
+-{ "stdxe",   X(31,927), X_MASK,		BOOKE64,	{ RS, RA, RB } },
+-
+-{ "tlbrehi", XTLB(31,946,0), XTLB_MASK,	PPC403,		{ RT, RA } },
+-{ "tlbrelo", XTLB(31,946,1), XTLB_MASK,	PPC403,		{ RT, RA } },
+-{ "tlbre",   X(31,946),	X_MASK,		BOOKE,		{ 0 } },
+-{ "tlbre",   X(31,946),	X_MASK,		PPC403,		{ RS, RA, SH } },
+-
+-{ "sraiq",   XRC(31,952,0), X_MASK,	M601,		{ RA, RS, SH } },
+-{ "sraiq.",  XRC(31,952,1), X_MASK,	M601,		{ RA, RS, SH } },
+-
+-{ "extsb",   XRC(31,954,0), XRB_MASK,	PPC,		{ RA, RS} },
+-{ "extsb.",  XRC(31,954,1), XRB_MASK,	PPC,		{ RA, RS} },
+-
+-{ "stduxe",  X(31,959),	X_MASK,		BOOKE64,	{ RS, RAS, RB } },
+-
+-{ "iccci",   X(31,966),	XRT_MASK,	PPC403|PPC440,	{ RA, RB } },
+-
+-{ "tlbwehi", XTLB(31,978,0), XTLB_MASK,	PPC403,		{ RT, RA } },
+-{ "tlbwelo", XTLB(31,978,1), XTLB_MASK,	PPC403,		{ RT, RA } },
+-{ "tlbwe",   X(31,978),	X_MASK,		BOOKE,		{ 0 } },
+-{ "tlbwe",   X(31,978),	X_MASK,		PPC403,		{ RS, RA, SH } },
+-{ "tlbld",   X(31,978),	XRTRA_MASK,	PPC,		{ RB } },
+-
+-{ "icbi",    X(31,982),	XRT_MASK,	PPC,		{ RA, RB } },
+-
+-{ "stfiwx",  X(31,983),	X_MASK,		PPC,		{ FRS, RA, RB } },
+-
+-{ "extsw",   XRC(31,986,0), XRB_MASK,	PPC64 | BOOKE64,{ RA, RS } },
+-{ "extsw.",  XRC(31,986,1), XRB_MASK,	PPC64,		{ RA, RS } },
+-
+-{ "icread",  X(31,998),	XRT_MASK,	PPC403|PPC440,	{ RA, RB } },
+-
+-{ "icbie",   X(31,990),	XRT_MASK,	BOOKE64,	{ RA, RB } },
+-{ "stfiwxe", X(31,991),	X_MASK,		BOOKE64,	{ FRS, RA, RB } },
+-
+-{ "tlbli",   X(31,1010), XRTRA_MASK,	PPC,		{ RB } },
+-
+-{ "dcbz",    X(31,1014), XRT_MASK,	PPC,		{ RA, RB } },
+-{ "dclz",    X(31,1014), XRT_MASK,	PPC,		{ RA, RB } },
+-
+-{ "dcbze",   X(31,1022), XRT_MASK,	BOOKE64,	{ RA, RB } },
+-
+-{ "lvebx",   X(31,   7), X_MASK,	PPCVEC,		{ VD, RA, RB } },
+-{ "lvehx",   X(31,  39), X_MASK,	PPCVEC,		{ VD, RA, RB } },
+-{ "lvewx",   X(31,  71), X_MASK,	PPCVEC,		{ VD, RA, RB } },
+-{ "lvsl",    X(31,   6), X_MASK,	PPCVEC,		{ VD, RA, RB } },
+-{ "lvsr",    X(31,  38), X_MASK,	PPCVEC,		{ VD, RA, RB } },
+-{ "lvx",     X(31, 103), X_MASK,	PPCVEC,		{ VD, RA, RB } },
+-{ "lvxl",    X(31, 359), X_MASK,	PPCVEC,		{ VD, RA, RB } },
+-{ "stvebx",  X(31, 135), X_MASK,	PPCVEC,		{ VS, RA, RB } },
+-{ "stvehx",  X(31, 167), X_MASK,	PPCVEC,		{ VS, RA, RB } },
+-{ "stvewx",  X(31, 199), X_MASK,	PPCVEC,		{ VS, RA, RB } },
+-{ "stvx",    X(31, 231), X_MASK,	PPCVEC,		{ VS, RA, RB } },
+-{ "stvxl",   X(31, 487), X_MASK,	PPCVEC,		{ VS, RA, RB } },
+-
+-{ "lwz",     OP(32),	OP_MASK,	PPCCOM,		{ RT, D, RA } },
+-{ "l",	     OP(32),	OP_MASK,	PWRCOM,		{ RT, D, RA } },
+-
+-{ "lwzu",    OP(33),	OP_MASK,	PPCCOM,		{ RT, D, RAL } },
+-{ "lu",      OP(33),	OP_MASK,	PWRCOM,		{ RT, D, RA } },
+-
+-{ "lbz",     OP(34),	OP_MASK,	COM,		{ RT, D, RA } },
+-
+-{ "lbzu",    OP(35),	OP_MASK,	COM,		{ RT, D, RAL } },
+-
+-{ "stw",     OP(36),	OP_MASK,	PPCCOM,		{ RS, D, RA } },
+-{ "st",      OP(36),	OP_MASK,	PWRCOM,		{ RS, D, RA } },
+-
+-{ "stwu",    OP(37),	OP_MASK,	PPCCOM,		{ RS, D, RAS } },
+-{ "stu",     OP(37),	OP_MASK,	PWRCOM,		{ RS, D, RA } },
+-
+-{ "stb",     OP(38),	OP_MASK,	COM,		{ RS, D, RA } },
+-
+-{ "stbu",    OP(39),	OP_MASK,	COM,		{ RS, D, RAS } },
+-
+-{ "lhz",     OP(40),	OP_MASK,	COM,		{ RT, D, RA } },
+-
+-{ "lhzu",    OP(41),	OP_MASK,	COM,		{ RT, D, RAL } },
+-
+-{ "lha",     OP(42),	OP_MASK,	COM,		{ RT, D, RA } },
+-
+-{ "lhau",    OP(43),	OP_MASK,	COM,		{ RT, D, RAL } },
+-
+-{ "sth",     OP(44),	OP_MASK,	COM,		{ RS, D, RA } },
+-
+-{ "sthu",    OP(45),	OP_MASK,	COM,		{ RS, D, RAS } },
+-
+-{ "lmw",     OP(46),	OP_MASK,	PPCCOM,		{ RT, D, RAM } },
+-{ "lm",      OP(46),	OP_MASK,	PWRCOM,		{ RT, D, RA } },
+-
+-{ "stmw",    OP(47),	OP_MASK,	PPCCOM,		{ RS, D, RA } },
+-{ "stm",     OP(47),	OP_MASK,	PWRCOM,		{ RS, D, RA } },
+-
+-{ "lfs",     OP(48),	OP_MASK,	COM,		{ FRT, D, RA } },
+-
+-{ "lfsu",    OP(49),	OP_MASK,	COM,		{ FRT, D, RAS } },
+-
+-{ "lfd",     OP(50),	OP_MASK,	COM,		{ FRT, D, RA } },
+-
+-{ "lfdu",    OP(51),	OP_MASK,	COM,		{ FRT, D, RAS } },
+-
+-{ "stfs",    OP(52),	OP_MASK,	COM,		{ FRS, D, RA } },
+-
+-{ "stfsu",   OP(53),	OP_MASK,	COM,		{ FRS, D, RAS } },
+-
+-{ "stfd",    OP(54),	OP_MASK,	COM,		{ FRS, D, RA } },
+-
+-{ "stfdu",   OP(55),	OP_MASK,	COM,		{ FRS, D, RAS } },
+-
+-{ "lq",      OP(56),	OP_MASK,	POWER4,		{ RTQ, DQ, RAQ } },
+-
+-{ "lfq",     OP(56),	OP_MASK,	POWER2,		{ FRT, D, RA } },
+-
+-{ "lfqu",    OP(57),	OP_MASK,	POWER2,		{ FRT, D, RA } },
+-
+-{ "lbze",    DEO(58,0), DE_MASK,	BOOKE64,	{ RT, DE, RA } },
+-{ "lbzue",   DEO(58,1), DE_MASK,	BOOKE64,	{ RT, DE, RAL } },
+-{ "lhze",    DEO(58,2), DE_MASK,	BOOKE64,	{ RT, DE, RA } },
+-{ "lhzue",   DEO(58,3), DE_MASK,	BOOKE64,	{ RT, DE, RAL } },
+-{ "lhae",    DEO(58,4), DE_MASK,	BOOKE64,	{ RT, DE, RA } },
+-{ "lhaue",   DEO(58,5), DE_MASK,	BOOKE64,	{ RT, DE, RAL } },
+-{ "lwze",    DEO(58,6), DE_MASK,	BOOKE64,	{ RT, DE, RA } },
+-{ "lwzue",   DEO(58,7), DE_MASK,	BOOKE64,	{ RT, DE, RAL } },
+-{ "stbe",    DEO(58,8), DE_MASK,	BOOKE64,	{ RS, DE, RA } },
+-{ "stbue",   DEO(58,9), DE_MASK,	BOOKE64,	{ RS, DE, RAS } },
+-{ "sthe",    DEO(58,10), DE_MASK,	BOOKE64,	{ RS, DE, RA } },
+-{ "sthue",   DEO(58,11), DE_MASK,	BOOKE64,	{ RS, DE, RAS } },
+-{ "stwe",    DEO(58,14), DE_MASK,	BOOKE64,	{ RS, DE, RA } },
+-{ "stwue",   DEO(58,15), DE_MASK,	BOOKE64,	{ RS, DE, RAS } },
+-
+-{ "ld",      DSO(58,0),	DS_MASK,	PPC64,		{ RT, DS, RA } },
+-
+-{ "ldu",     DSO(58,1), DS_MASK,	PPC64,		{ RT, DS, RAL } },
+-
+-{ "lwa",     DSO(58,2), DS_MASK,	PPC64,		{ RT, DS, RA } },
+-
+-{ "fdivs",   A(59,18,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+-{ "fdivs.",  A(59,18,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+-
+-{ "fsubs",   A(59,20,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+-{ "fsubs.",  A(59,20,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+-
+-{ "fadds",   A(59,21,0), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+-{ "fadds.",  A(59,21,1), AFRC_MASK,	PPC,		{ FRT, FRA, FRB } },
+-
+-{ "fsqrts",  A(59,22,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+-{ "fsqrts.", A(59,22,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+-
+-{ "fres",    A(59,24,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+-{ "fres.",   A(59,24,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+-
+-{ "fmuls",   A(59,25,0), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+-{ "fmuls.",  A(59,25,1), AFRB_MASK,	PPC,		{ FRT, FRA, FRC } },
+-
+-{ "fmsubs",  A(59,28,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-{ "fmsubs.", A(59,28,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-
+-{ "fmadds",  A(59,29,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-{ "fmadds.", A(59,29,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-
+-{ "fnmsubs", A(59,30,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-{ "fnmsubs.",A(59,30,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-
+-{ "fnmadds", A(59,31,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-{ "fnmadds.",A(59,31,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-
+-{ "stfq",    OP(60),	OP_MASK,	POWER2,		{ FRS, D, RA } },
+-
+-{ "stfqu",   OP(61),	OP_MASK,	POWER2,		{ FRS, D, RA } },
+-
+-{ "lde",     DEO(62,0), DE_MASK,	BOOKE64,	{ RT, DES, RA } },
+-{ "ldue",    DEO(62,1), DE_MASK,	BOOKE64,	{ RT, DES, RA } },
+-{ "lfse",    DEO(62,4), DE_MASK,	BOOKE64,	{ FRT, DES, RA } },
+-{ "lfsue",   DEO(62,5), DE_MASK,	BOOKE64,	{ FRT, DES, RAS } },
+-{ "lfde",    DEO(62,6), DE_MASK,	BOOKE64,	{ FRT, DES, RA } },
+-{ "lfdue",   DEO(62,7), DE_MASK,	BOOKE64,	{ FRT, DES, RAS } },
+-{ "stde",    DEO(62,8), DE_MASK,	BOOKE64,	{ RS, DES, RA } },
+-{ "stdue",   DEO(62,9), DE_MASK,	BOOKE64,	{ RS, DES, RAS } },
+-{ "stfse",   DEO(62,12), DE_MASK,	BOOKE64,	{ FRS, DES, RA } },
+-{ "stfsue",  DEO(62,13), DE_MASK,	BOOKE64,	{ FRS, DES, RAS } },
+-{ "stfde",   DEO(62,14), DE_MASK,	BOOKE64,	{ FRS, DES, RA } },
+-{ "stfdue",  DEO(62,15), DE_MASK,	BOOKE64,	{ FRS, DES, RAS } },
+-
+-{ "std",     DSO(62,0),	DS_MASK,	PPC64,		{ RS, DS, RA } },
+-
+-{ "stdu",    DSO(62,1),	DS_MASK,	PPC64,		{ RS, DS, RAS } },
+-
+-{ "stq",     DSO(62,2),	DS_MASK,	POWER4,		{ RSQ, DS, RA } },
+-
+-{ "fcmpu",   X(63,0),	X_MASK|(3<<21),	COM,		{ BF, FRA, FRB } },
+-
+-{ "frsp",    XRC(63,12,0), XRA_MASK,	COM,		{ FRT, FRB } },
+-{ "frsp.",   XRC(63,12,1), XRA_MASK,	COM,		{ FRT, FRB } },
+-
+-{ "fctiw",   XRC(63,14,0), XRA_MASK,	PPCCOM,		{ FRT, FRB } },
+-{ "fcir",    XRC(63,14,0), XRA_MASK,	POWER2,		{ FRT, FRB } },
+-{ "fctiw.",  XRC(63,14,1), XRA_MASK,	PPCCOM,		{ FRT, FRB } },
+-{ "fcir.",   XRC(63,14,1), XRA_MASK,	POWER2,		{ FRT, FRB } },
+-
+-{ "fctiwz",  XRC(63,15,0), XRA_MASK,	PPCCOM,		{ FRT, FRB } },
+-{ "fcirz",   XRC(63,15,0), XRA_MASK,	POWER2,		{ FRT, FRB } },
+-{ "fctiwz.", XRC(63,15,1), XRA_MASK,	PPCCOM,		{ FRT, FRB } },
+-{ "fcirz.",  XRC(63,15,1), XRA_MASK,	POWER2,		{ FRT, FRB } },
+-
+-{ "fdiv",    A(63,18,0), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
+-{ "fd",      A(63,18,0), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
+-{ "fdiv.",   A(63,18,1), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
+-{ "fd.",     A(63,18,1), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
+-
+-{ "fsub",    A(63,20,0), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
+-{ "fs",      A(63,20,0), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
+-{ "fsub.",   A(63,20,1), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
+-{ "fs.",     A(63,20,1), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
+-
+-{ "fadd",    A(63,21,0), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
+-{ "fa",      A(63,21,0), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
+-{ "fadd.",   A(63,21,1), AFRC_MASK,	PPCCOM,		{ FRT, FRA, FRB } },
+-{ "fa.",     A(63,21,1), AFRC_MASK,	PWRCOM,		{ FRT, FRA, FRB } },
+-
+-{ "fsqrt",   A(63,22,0), AFRAFRC_MASK,	PPCPWR2,	{ FRT, FRB } },
+-{ "fsqrt.",  A(63,22,1), AFRAFRC_MASK,	PPCPWR2,	{ FRT, FRB } },
+-
+-{ "fsel",    A(63,23,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-{ "fsel.",   A(63,23,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
+-
+-{ "fmul",    A(63,25,0), AFRB_MASK,	PPCCOM,		{ FRT, FRA, FRC } },
+-{ "fm",      A(63,25,0), AFRB_MASK,	PWRCOM,		{ FRT, FRA, FRC } },
+-{ "fmul.",   A(63,25,1), AFRB_MASK,	PPCCOM,		{ FRT, FRA, FRC } },
+-{ "fm.",     A(63,25,1), AFRB_MASK,	PWRCOM,		{ FRT, FRA, FRC } },
+-
+-{ "frsqrte", A(63,26,0), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+-{ "frsqrte.",A(63,26,1), AFRAFRC_MASK,	PPC,		{ FRT, FRB } },
+-
+-{ "fmsub",   A(63,28,0), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fms",     A(63,28,0), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fmsub.",  A(63,28,1), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fms.",    A(63,28,1), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
+-
+-{ "fmadd",   A(63,29,0), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fma",     A(63,29,0), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fmadd.",  A(63,29,1), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fma.",    A(63,29,1), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
+-
+-{ "fnmsub",  A(63,30,0), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fnms",    A(63,30,0), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fnmsub.", A(63,30,1), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fnms.",   A(63,30,1), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
+-
+-{ "fnmadd",  A(63,31,0), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fnma",    A(63,31,0), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fnmadd.", A(63,31,1), A_MASK,	PPCCOM,		{ FRT,FRA,FRC,FRB } },
+-{ "fnma.",   A(63,31,1), A_MASK,	PWRCOM,		{ FRT,FRA,FRC,FRB } },
+-
+-{ "fcmpo",   X(63,32),	X_MASK|(3<<21),	COM,		{ BF, FRA, FRB } },
+-
+-{ "mtfsb1",  XRC(63,38,0), XRARB_MASK,	COM,		{ BT } },
+-{ "mtfsb1.", XRC(63,38,1), XRARB_MASK,	COM,		{ BT } },
+-
+-{ "fneg",    XRC(63,40,0), XRA_MASK,	COM,		{ FRT, FRB } },
+-{ "fneg.",   XRC(63,40,1), XRA_MASK,	COM,		{ FRT, FRB } },
+-
+-{ "mcrfs",   X(63,64),	XRB_MASK|(3<<21)|(3<<16), COM,	{ BF, BFA } },
+-
+-{ "mtfsb0",  XRC(63,70,0), XRARB_MASK,	COM,		{ BT } },
+-{ "mtfsb0.", XRC(63,70,1), XRARB_MASK,	COM,		{ BT } },
+-
+-{ "fmr",     XRC(63,72,0), XRA_MASK,	COM,		{ FRT, FRB } },
+-{ "fmr.",    XRC(63,72,1), XRA_MASK,	COM,		{ FRT, FRB } },
+-
+-{ "mtfsfi",  XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
+-{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
+-
+-{ "fnabs",   XRC(63,136,0), XRA_MASK,	COM,		{ FRT, FRB } },
+-{ "fnabs.",  XRC(63,136,1), XRA_MASK,	COM,		{ FRT, FRB } },
+-
+-{ "fabs",    XRC(63,264,0), XRA_MASK,	COM,		{ FRT, FRB } },
+-{ "fabs.",   XRC(63,264,1), XRA_MASK,	COM,		{ FRT, FRB } },
+-
+-{ "mffs",    XRC(63,583,0), XRARB_MASK,	COM,		{ FRT } },
+-{ "mffs.",   XRC(63,583,1), XRARB_MASK,	COM,		{ FRT } },
+-
+-{ "mtfsf",   XFL(63,711,0), XFL_MASK,	COM,		{ FLM, FRB } },
+-{ "mtfsf.",  XFL(63,711,1), XFL_MASK,	COM,		{ FLM, FRB } },
+-
+-{ "fctid",   XRC(63,814,0), XRA_MASK,	PPC64,		{ FRT, FRB } },
+-{ "fctid.",  XRC(63,814,1), XRA_MASK,	PPC64,		{ FRT, FRB } },
+-
+-{ "fctidz",  XRC(63,815,0), XRA_MASK,	PPC64,		{ FRT, FRB } },
+-{ "fctidz.", XRC(63,815,1), XRA_MASK,	PPC64,		{ FRT, FRB } },
+-
+-{ "fcfid",   XRC(63,846,0), XRA_MASK,	PPC64,		{ FRT, FRB } },
+-{ "fcfid.",  XRC(63,846,1), XRA_MASK,	PPC64,		{ FRT, FRB } },
+-
+-};
+-
+-const int powerpc_num_opcodes =
+-  sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
+-
+-/* The macro table.  This is only used by the assembler.  */
+-
+-/* The expressions of the form (-x ! 31) & (x | 31) have the value 0
+-   when x=0; 32-x when x is between 1 and 31; are negative if x is
+-   negative; and are 32 or more otherwise.  This is what you want
+-   when, for instance, you are emulating a right shift by a
+-   rotate-left-and-mask, because the underlying instructions support
+-   shifts of size 0 but not shifts of size 32.  By comparison, when
+-   extracting x bits from some word you want to use just 32-x, because
+-   the underlying instructions don't support extracting 0 bits but do
+-   support extracting the whole word (32 bits in this case).  */
+-
+-const struct powerpc_macro powerpc_macros[] = {
+-{ "extldi",  4,   PPC64,	"rldicr %0,%1,%3,(%2)-1" },
+-{ "extldi.", 4,   PPC64,	"rldicr. %0,%1,%3,(%2)-1" },
+-{ "extrdi",  4,   PPC64,	"rldicl %0,%1,(%2)+(%3),64-(%2)" },
+-{ "extrdi.", 4,   PPC64,	"rldicl. %0,%1,(%2)+(%3),64-(%2)" },
+-{ "insrdi",  4,   PPC64,	"rldimi %0,%1,64-((%2)+(%3)),%3" },
+-{ "insrdi.", 4,   PPC64,	"rldimi. %0,%1,64-((%2)+(%3)),%3" },
+-{ "rotrdi",  3,   PPC64,	"rldicl %0,%1,(-(%2)!63)&((%2)|63),0" },
+-{ "rotrdi.", 3,   PPC64,	"rldicl. %0,%1,(-(%2)!63)&((%2)|63),0" },
+-{ "sldi",    3,   PPC64,	"rldicr %0,%1,%2,63-(%2)" },
+-{ "sldi.",   3,   PPC64,	"rldicr. %0,%1,%2,63-(%2)" },
+-{ "srdi",    3,   PPC64,	"rldicl %0,%1,(-(%2)!63)&((%2)|63),%2" },
+-{ "srdi.",   3,   PPC64,	"rldicl. %0,%1,(-(%2)!63)&((%2)|63),%2" },
+-{ "clrrdi",  3,   PPC64,	"rldicr %0,%1,0,63-(%2)" },
+-{ "clrrdi.", 3,   PPC64,	"rldicr. %0,%1,0,63-(%2)" },
+-{ "clrlsldi",4,   PPC64,	"rldic %0,%1,%3,(%2)-(%3)" },
+-{ "clrlsldi.",4,  PPC64,	"rldic. %0,%1,%3,(%2)-(%3)" },
+-
+-{ "extlwi",  4,   PPCCOM,	"rlwinm %0,%1,%3,0,(%2)-1" },
+-{ "extlwi.", 4,   PPCCOM,	"rlwinm. %0,%1,%3,0,(%2)-1" },
+-{ "extrwi",  4,   PPCCOM,	"rlwinm %0,%1,((%2)+(%3))&((%2)+(%3)<>32),32-(%2),31" },
+-{ "extrwi.", 4,   PPCCOM,	"rlwinm. %0,%1,((%2)+(%3))&((%2)+(%3)<>32),32-(%2),31" },
+-{ "inslwi",  4,   PPCCOM,	"rlwimi %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1" },
+-{ "inslwi.", 4,   PPCCOM,	"rlwimi. %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1"},
+-{ "insrwi",  4,   PPCCOM,	"rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" },
+-{ "insrwi.", 4,   PPCCOM,	"rlwimi. %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1"},
+-{ "rotrwi",  3,   PPCCOM,	"rlwinm %0,%1,(-(%2)!31)&((%2)|31),0,31" },
+-{ "rotrwi.", 3,   PPCCOM,	"rlwinm. %0,%1,(-(%2)!31)&((%2)|31),0,31" },
+-{ "slwi",    3,   PPCCOM,	"rlwinm %0,%1,%2,0,31-(%2)" },
+-{ "sli",     3,   PWRCOM,	"rlinm %0,%1,%2,0,31-(%2)" },
+-{ "slwi.",   3,   PPCCOM,	"rlwinm. %0,%1,%2,0,31-(%2)" },
+-{ "sli.",    3,   PWRCOM,	"rlinm. %0,%1,%2,0,31-(%2)" },
+-{ "srwi",    3,   PPCCOM,	"rlwinm %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
+-{ "sri",     3,   PWRCOM,	"rlinm %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
+-{ "srwi.",   3,   PPCCOM,	"rlwinm. %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
+-{ "sri.",    3,   PWRCOM,	"rlinm. %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
+-{ "clrrwi",  3,   PPCCOM,	"rlwinm %0,%1,0,0,31-(%2)" },
+-{ "clrrwi.", 3,   PPCCOM,	"rlwinm. %0,%1,0,0,31-(%2)" },
+-{ "clrlslwi",4,   PPCCOM,	"rlwinm %0,%1,%3,(%2)-(%3),31-(%3)" },
+-{ "clrlslwi.",4,  PPCCOM,	"rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" },
+-};
+-
+-const int powerpc_num_macros =
+-  sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
+diff --git a/arch/ppc64/xmon/ppc.h b/arch/ppc64/xmon/ppc.h
+deleted file mode 100644
+--- a/arch/ppc64/xmon/ppc.h
++++ /dev/null
+@@ -1,307 +0,0 @@
+-/* ppc.h -- Header file for PowerPC opcode table
+-   Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003
+-   Free Software Foundation, Inc.
+-   Written by Ian Lance Taylor, Cygnus Support
+-
+-This file is part of GDB, GAS, and the GNU binutils.
+-
+-GDB, GAS, and the GNU binutils are free software; you can redistribute
+-them and/or modify them under the terms of the GNU General Public
+-License as published by the Free Software Foundation; either version
+-1, or (at your option) any later version.
+-
+-GDB, GAS, and the GNU binutils are distributed in the hope that they
+-will be useful, but WITHOUT ANY WARRANTY; without even the implied
+-warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+-the GNU General Public License for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with this file; see the file COPYING.  If not, write to the Free
+-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+-
+-#ifndef PPC_H
+-#define PPC_H
+-
+-/* The opcode table is an array of struct powerpc_opcode.  */
+-
+-struct powerpc_opcode
+-{
+-  /* The opcode name.  */
+-  const char *name;
+-
+-  /* The opcode itself.  Those bits which will be filled in with
+-     operands are zeroes.  */
+-  unsigned long opcode;
+-
+-  /* The opcode mask.  This is used by the disassembler.  This is a
+-     mask containing ones indicating those bits which must match the
+-     opcode field, and zeroes indicating those bits which need not
+-     match (and are presumably filled in by operands).  */
+-  unsigned long mask;
+-
+-  /* One bit flags for the opcode.  These are used to indicate which
+-     specific processors support the instructions.  The defined values
+-     are listed below.  */
+-  unsigned long flags;
+-
+-  /* An array of operand codes.  Each code is an index into the
+-     operand table.  They appear in the order which the operands must
+-     appear in assembly code, and are terminated by a zero.  */
+-  unsigned char operands[8];
+-};
+-
+-/* The table itself is sorted by major opcode number, and is otherwise
+-   in the order in which the disassembler should consider
+-   instructions.  */
+-extern const struct powerpc_opcode powerpc_opcodes[];
+-extern const int powerpc_num_opcodes;
+-
+-/* Values defined for the flags field of a struct powerpc_opcode.  */
+-
+-/* Opcode is defined for the PowerPC architecture.  */
+-#define PPC_OPCODE_PPC			 1
+-
+-/* Opcode is defined for the POWER (RS/6000) architecture.  */
+-#define PPC_OPCODE_POWER		 2
+-
+-/* Opcode is defined for the POWER2 (Rios 2) architecture.  */
+-#define PPC_OPCODE_POWER2		 4
+-
+-/* Opcode is only defined on 32 bit architectures.  */
+-#define PPC_OPCODE_32			 8
+-
+-/* Opcode is only defined on 64 bit architectures.  */
+-#define PPC_OPCODE_64		      0x10
+-
+-/* Opcode is supported by the Motorola PowerPC 601 processor.  The 601
+-   is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
+-   but it also supports many additional POWER instructions.  */
+-#define PPC_OPCODE_601		      0x20
+-
+-/* Opcode is supported in both the Power and PowerPC architectures
+-   (ie, compiler's -mcpu=common or assembler's -mcom).  */
+-#define PPC_OPCODE_COMMON	      0x40
+-
+-/* Opcode is supported for any Power or PowerPC platform (this is
+-   for the assembler's -many option, and it eliminates duplicates).  */
+-#define PPC_OPCODE_ANY		      0x80
+-
+-/* Opcode is supported as part of the 64-bit bridge.  */
+-#define PPC_OPCODE_64_BRIDGE	     0x100
+-
+-/* Opcode is supported by Altivec Vector Unit */
+-#define PPC_OPCODE_ALTIVEC	     0x200
+-
+-/* Opcode is supported by PowerPC 403 processor.  */
+-#define PPC_OPCODE_403		     0x400
+-
+-/* Opcode is supported by PowerPC BookE processor.  */
+-#define PPC_OPCODE_BOOKE	     0x800
+-
+-/* Opcode is only supported by 64-bit PowerPC BookE processor.  */
+-#define PPC_OPCODE_BOOKE64	    0x1000
+-
+-/* Opcode is supported by PowerPC 440 processor.  */
+-#define PPC_OPCODE_440		    0x2000
+-
+-/* Opcode is only supported by Power4 architecture.  */
+-#define PPC_OPCODE_POWER4	    0x4000
+-
+-/* Opcode isn't supported by Power4 architecture.  */
+-#define PPC_OPCODE_NOPOWER4	    0x8000
+-
+-/* Opcode is only supported by POWERPC Classic architecture.  */
+-#define PPC_OPCODE_CLASSIC	   0x10000
+-
+-/* Opcode is only supported by e500x2 Core.  */
+-#define PPC_OPCODE_SPE		   0x20000
+-
+-/* Opcode is supported by e500x2 Integer select APU.  */
+-#define PPC_OPCODE_ISEL		   0x40000
+-
+-/* Opcode is an e500 SPE floating point instruction.  */
+-#define PPC_OPCODE_EFS		   0x80000
+-
+-/* Opcode is supported by branch locking APU.  */
+-#define PPC_OPCODE_BRLOCK	  0x100000
+-
+-/* Opcode is supported by performance monitor APU.  */
+-#define PPC_OPCODE_PMR		  0x200000
+-
+-/* Opcode is supported by cache locking APU.  */
+-#define PPC_OPCODE_CACHELCK	  0x400000
+-
+-/* Opcode is supported by machine check APU.  */
+-#define PPC_OPCODE_RFMCI	  0x800000
+-
+-/* A macro to extract the major opcode from an instruction.  */
+-#define PPC_OP(i) (((i) >> 26) & 0x3f)
+-
+-/* The operands table is an array of struct powerpc_operand.  */
+-
+-struct powerpc_operand
+-{
+-  /* The number of bits in the operand.  */
+-  int bits;
+-
+-  /* How far the operand is left shifted in the instruction.  */
+-  int shift;
+-
+-  /* Insertion function.  This is used by the assembler.  To insert an
+-     operand value into an instruction, check this field.
+-
+-     If it is NULL, execute
+-         i |= (op & ((1 << o->bits) - 1)) << o->shift;
+-     (i is the instruction which we are filling in, o is a pointer to
+-     this structure, and op is the opcode value; this assumes twos
+-     complement arithmetic).
+-
+-     If this field is not NULL, then simply call it with the
+-     instruction and the operand value.  It will return the new value
+-     of the instruction.  If the ERRMSG argument is not NULL, then if
+-     the operand value is illegal, *ERRMSG will be set to a warning
+-     string (the operand will be inserted in any case).  If the
+-     operand value is legal, *ERRMSG will be unchanged (most operands
+-     can accept any value).  */
+-  unsigned long (*insert)
+-    (unsigned long instruction, long op, int dialect, const char **errmsg);
+-
+-  /* Extraction function.  This is used by the disassembler.  To
+-     extract this operand type from an instruction, check this field.
+-
+-     If it is NULL, compute
+-         op = ((i) >> o->shift) & ((1 << o->bits) - 1);
+-	 if ((o->flags & PPC_OPERAND_SIGNED) != 0
+-	     && (op & (1 << (o->bits - 1))) != 0)
+-	   op -= 1 << o->bits;
+-     (i is the instruction, o is a pointer to this structure, and op
+-     is the result; this assumes twos complement arithmetic).
+-
+-     If this field is not NULL, then simply call it with the
+-     instruction value.  It will return the value of the operand.  If
+-     the INVALID argument is not NULL, *INVALID will be set to
+-     non-zero if this operand type can not actually be extracted from
+-     this operand (i.e., the instruction does not match).  If the
+-     operand is valid, *INVALID will not be changed.  */
+-  long (*extract) (unsigned long instruction, int dialect, int *invalid);
+-
+-  /* One bit syntax flags.  */
+-  unsigned long flags;
+-};
+-
+-/* Elements in the table are retrieved by indexing with values from
+-   the operands field of the powerpc_opcodes table.  */
+-
+-extern const struct powerpc_operand powerpc_operands[];
+-
+-/* Values defined for the flags field of a struct powerpc_operand.  */
+-
+-/* This operand takes signed values.  */
+-#define PPC_OPERAND_SIGNED (01)
+-
+-/* This operand takes signed values, but also accepts a full positive
+-   range of values when running in 32 bit mode.  That is, if bits is
+-   16, it takes any value from -0x8000 to 0xffff.  In 64 bit mode,
+-   this flag is ignored.  */
+-#define PPC_OPERAND_SIGNOPT (02)
+-
+-/* This operand does not actually exist in the assembler input.  This
+-   is used to support extended mnemonics such as mr, for which two
+-   operands fields are identical.  The assembler should call the
+-   insert function with any op value.  The disassembler should call
+-   the extract function, ignore the return value, and check the value
+-   placed in the valid argument.  */
+-#define PPC_OPERAND_FAKE (04)
+-
+-/* The next operand should be wrapped in parentheses rather than
+-   separated from this one by a comma.  This is used for the load and
+-   store instructions which want their operands to look like
+-       reg,displacement(reg)
+-   */
+-#define PPC_OPERAND_PARENS (010)
+-
+-/* This operand may use the symbolic names for the CR fields, which
+-   are
+-       lt  0	gt  1	eq  2	so  3	un  3
+-       cr0 0	cr1 1	cr2 2	cr3 3
+-       cr4 4	cr5 5	cr6 6	cr7 7
+-   These may be combined arithmetically, as in cr2*4+gt.  These are
+-   only supported on the PowerPC, not the POWER.  */
+-#define PPC_OPERAND_CR (020)
+-
+-/* This operand names a register.  The disassembler uses this to print
+-   register names with a leading 'r'.  */
+-#define PPC_OPERAND_GPR (040)
+-
+-/* This operand names a floating point register.  The disassembler
+-   prints these with a leading 'f'.  */
+-#define PPC_OPERAND_FPR (0100)
+-
+-/* This operand is a relative branch displacement.  The disassembler
+-   prints these symbolically if possible.  */
+-#define PPC_OPERAND_RELATIVE (0200)
+-
+-/* This operand is an absolute branch address.  The disassembler
+-   prints these symbolically if possible.  */
+-#define PPC_OPERAND_ABSOLUTE (0400)
+-
+-/* This operand is optional, and is zero if omitted.  This is used for
+-   the optional BF and L fields in the comparison instructions.  The
+-   assembler must count the number of operands remaining on the line,
+-   and the number of operands remaining for the opcode, and decide
+-   whether this operand is present or not.  The disassembler should
+-   print this operand out only if it is not zero.  */
+-#define PPC_OPERAND_OPTIONAL (01000)
+-
+-/* This flag is only used with PPC_OPERAND_OPTIONAL.  If this operand
+-   is omitted, then for the next operand use this operand value plus
+-   1, ignoring the next operand field for the opcode.  This wretched
+-   hack is needed because the Power rotate instructions can take
+-   either 4 or 5 operands.  The disassembler should print this operand
+-   out regardless of the PPC_OPERAND_OPTIONAL field.  */
+-#define PPC_OPERAND_NEXT (02000)
+-
+-/* This operand should be regarded as a negative number for the
+-   purposes of overflow checking (i.e., the normal most negative
+-   number is disallowed and one more than the normal most positive
+-   number is allowed).  This flag will only be set for a signed
+-   operand.  */
+-#define PPC_OPERAND_NEGATIVE (04000)
+-
+-/* This operand names a vector unit register.  The disassembler
+-   prints these with a leading 'v'.  */
+-#define PPC_OPERAND_VR (010000)
+-
+-/* This operand is for the DS field in a DS form instruction.  */
+-#define PPC_OPERAND_DS (020000)
+-
+-/* This operand is for the DQ field in a DQ form instruction.  */
+-#define PPC_OPERAND_DQ (040000)
+-
+-/* The POWER and PowerPC assemblers use a few macros.  We keep them
+-   with the operands table for simplicity.  The macro table is an
+-   array of struct powerpc_macro.  */
+-
+-struct powerpc_macro
+-{
+-  /* The macro name.  */
+-  const char *name;
+-
+-  /* The number of operands the macro takes.  */
+-  unsigned int operands;
+-
+-  /* One bit flags for the opcode.  These are used to indicate which
+-     specific processors support the instructions.  The values are the
+-     same as those for the struct powerpc_opcode flags field.  */
+-  unsigned long flags;
+-
+-  /* A format string to turn the macro into a normal instruction.
+-     Each %N in the string is replaced with operand number N (zero
+-     based).  */
+-  const char *format;
+-};
+-
+-extern const struct powerpc_macro powerpc_macros[];
+-extern const int powerpc_num_macros;
+-
+-#endif /* PPC_H */
+diff --git a/arch/ppc64/xmon/setjmp.S b/arch/ppc64/xmon/setjmp.S
+deleted file mode 100644
+--- a/arch/ppc64/xmon/setjmp.S
++++ /dev/null
+@@ -1,73 +0,0 @@
+-/*
+- * Copyright (C) 1996 Paul Mackerras.
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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: assert(sizeof(buf) > 184)
+- */
+-#include <asm/processor.h>
+-#include <asm/ppc_asm.h>
+-
+-_GLOBAL(xmon_setjmp)
+-	mflr    r0
+-	std     r0,0(r3)
+-	std     r1,8(r3)
+-	std     r2,16(r3)
+-	mfcr    r0
+-	std     r0,24(r3)
+-	std     r13,32(r3)
+-	std     r14,40(r3)
+-	std     r15,48(r3)
+-	std     r16,56(r3)
+-	std     r17,64(r3)
+-	std     r18,72(r3)
+-	std     r19,80(r3)
+-	std     r20,88(r3)
+-	std     r21,96(r3)
+-	std     r22,104(r3)
+-	std     r23,112(r3)
+-	std     r24,120(r3)
+-	std     r25,128(r3)
+-	std     r26,136(r3)
+-	std     r27,144(r3)
+-	std     r28,152(r3)
+-	std     r29,160(r3)
+-	std     r30,168(r3)
+-	std     r31,176(r3)
+-	li      r3,0
+-	blr
+-
+-_GLOBAL(xmon_longjmp)
+-	cmpdi   r4,0
+-	bne     1f
+-	li      r4,1
+-1:	ld      r13,32(r3)
+-	ld      r14,40(r3)
+-	ld      r15,48(r3)
+-	ld      r16,56(r3)
+-	ld      r17,64(r3)
+-	ld      r18,72(r3)
+-	ld      r19,80(r3)
+-	ld      r20,88(r3)
+-	ld      r21,96(r3)
+-	ld      r22,104(r3)
+-	ld      r23,112(r3)
+-	ld      r24,120(r3)
+-	ld      r25,128(r3)
+-	ld      r26,136(r3)
+-	ld      r27,144(r3)
+-	ld      r28,152(r3)
+-	ld      r29,160(r3)
+-	ld      r30,168(r3)
+-	ld      r31,176(r3)
+-	ld      r0,24(r3)
+-	mtcrf   56,r0
+-	ld      r0,0(r3)
+-	ld      r1,8(r3)
+-	ld      r2,16(r3)
+-	mtlr    r0
+-	mr      r3,r4
+-	blr
+diff --git a/arch/ppc64/xmon/start.c b/arch/ppc64/xmon/start.c
+deleted file mode 100644
+--- a/arch/ppc64/xmon/start.c
++++ /dev/null
+@@ -1,187 +0,0 @@
+-/*
+- * Copyright (C) 1996 Paul Mackerras.
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/string.h>
+-#include <linux/kernel.h>
+-#include <linux/errno.h>
+-#include <linux/sysrq.h>
+-#include <linux/init.h>
+-#include <asm/machdep.h>
+-#include <asm/io.h>
+-#include <asm/page.h>
+-#include <asm/prom.h>
+-#include <asm/processor.h>
+-#include <asm/udbg.h>
+-#include <asm/system.h>
+-#include "nonstdio.h"
+-
+-#ifdef CONFIG_MAGIC_SYSRQ
+-
+-static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
+-			      struct tty_struct *tty) 
+-{
+-	/* ensure xmon is enabled */
+-	xmon_init(1);
+-	debugger(pt_regs);
+-}
+-
+-static struct sysrq_key_op sysrq_xmon_op = 
+-{
+-	.handler =	sysrq_handle_xmon,
+-	.help_msg =	"Xmon",
+-	.action_msg =	"Entering xmon",
+-};
+-
+-static int __init setup_xmon_sysrq(void)
+-{
+-	register_sysrq_key('x', &sysrq_xmon_op);
+-	return 0;
+-}
+-__initcall(setup_xmon_sysrq);
+-#endif /* CONFIG_MAGIC_SYSRQ */
+-
+-int
+-xmon_write(void *handle, void *ptr, int nb)
+-{
+-	return udbg_write(ptr, nb);
+-}
+-
+-int
+-xmon_read(void *handle, void *ptr, int nb)
+-{
+-	return udbg_read(ptr, nb);
+-}
+-
+-int
+-xmon_read_poll(void)
+-{
+-	if (udbg_getc_poll)
+-		return udbg_getc_poll();
+-	return -1;
+-}
+- 
+-FILE *xmon_stdin;
+-FILE *xmon_stdout;
+-
+-int
+-xmon_putc(int c, void *f)
+-{
+-	char ch = c;
+-
+-	if (c == '\n')
+-		xmon_putc('\r', f);
+-	return xmon_write(f, &ch, 1) == 1? c: -1;
+-}
+-
+-int
+-xmon_putchar(int c)
+-{
+-	return xmon_putc(c, xmon_stdout);
+-}
+-
+-int
+-xmon_fputs(char *str, void *f)
+-{
+-	int n = strlen(str);
+-
+-	return xmon_write(f, str, n) == n? 0: -1;
+-}
+-
+-int
+-xmon_readchar(void)
+-{
+-	char ch;
+-
+-	for (;;) {
+-		switch (xmon_read(xmon_stdin, &ch, 1)) {
+-		case 1:
+-			return ch;
+-		case -1:
+-			xmon_printf("read(stdin) returned -1\r\n", 0, 0);
+-			return -1;
+-		}
+-	}
+-}
+-
+-static char line[256];
+-static char *lineptr;
+-static int lineleft;
+-
+-int
+-xmon_getchar(void)
+-{
+-	int c;
+-
+-	if (lineleft == 0) {
+-		lineptr = line;
+-		for (;;) {
+-			c = xmon_readchar();
+-			if (c == -1 || c == 4)
+-				break;
+-			if (c == '\r' || c == '\n') {
+-				*lineptr++ = '\n';
+-				xmon_putchar('\n');
+-				break;
+-			}
+-			switch (c) {
+-			case 0177:
+-			case '\b':
+-				if (lineptr > line) {
+-					xmon_putchar('\b');
+-					xmon_putchar(' ');
+-					xmon_putchar('\b');
+-					--lineptr;
+-				}
+-				break;
+-			case 'U' & 0x1F:
+-				while (lineptr > line) {
+-					xmon_putchar('\b');
+-					xmon_putchar(' ');
+-					xmon_putchar('\b');
+-					--lineptr;
+-				}
+-				break;
+-			default:
+-				if (lineptr >= &line[sizeof(line) - 1])
+-					xmon_putchar('\a');
+-				else {
+-					xmon_putchar(c);
+-					*lineptr++ = c;
+-				}
+-			}
+-		}
+-		lineleft = lineptr - line;
+-		lineptr = line;
+-	}
+-	if (lineleft == 0)
+-		return -1;
+-	--lineleft;
+-	return *lineptr++;
+-}
+-
+-char *
+-xmon_fgets(char *str, int nb, void *f)
+-{
+-	char *p;
+-	int c;
+-
+-	for (p = str; p < str + nb - 1; ) {
+-		c = xmon_getchar();
+-		if (c == -1) {
+-			if (p == str)
+-				return NULL;
+-			break;
+-		}
+-		*p++ = c;
+-		if (c == '\n')
+-			break;
+-	}
+-	*p = 0;
+-	return str;
+-}
+diff --git a/arch/ppc64/xmon/subr_prf.c b/arch/ppc64/xmon/subr_prf.c
+deleted file mode 100644
+--- a/arch/ppc64/xmon/subr_prf.c
++++ /dev/null
+@@ -1,55 +0,0 @@
+-/*
+- * Written by Cort Dougan to replace the version originally used
+- * by Paul Mackerras, which came from NetBSD and thus had copyright
+- * conflicts with Linux.
+- *
+- * This file makes liberal use of the standard linux utility
+- * routines to reduce the size of the binary.  We assume we can
+- * trust some parts of Linux inside the debugger.
+- *   -- Cort (cort at cs.nmt.edu)
+- *
+- * Copyright (C) 1999 Cort Dougan.
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/string.h>
+-#include <stdarg.h>
+-#include "nonstdio.h"
+-
+-extern int xmon_write(void *, void *, int);
+-
+-void
+-xmon_vfprintf(void *f, const char *fmt, va_list ap)
+-{
+-	static char xmon_buf[2048];
+-	int n;
+-
+-	n = vsprintf(xmon_buf, fmt, ap);
+-	xmon_write(f, xmon_buf, n);
+-}
+-
+-void
+-xmon_printf(const char *fmt, ...)
+-{
+-	va_list ap;
+-
+-	va_start(ap, fmt);
+-	xmon_vfprintf(stdout, fmt, ap);
+-	va_end(ap);
+-}
+-
+-void
+-xmon_fprintf(void *f, const char *fmt, ...)
+-{
+-	va_list ap;
+-
+-	va_start(ap, fmt);
+-	xmon_vfprintf(f, fmt, ap);
+-	va_end(ap);
+-}
+-
+diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c
+deleted file mode 100644
+--- a/arch/ppc64/xmon/xmon.c
++++ /dev/null
+@@ -1,2514 +0,0 @@
+-/*
+- * Routines providing a simple monitor for use on the PowerMac.
+- *
+- * Copyright (C) 1996 Paul Mackerras.
+- *
+- *      This program is free software; you can redistribute it and/or
+- *      modify it under the terms of the 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/errno.h>
+-#include <linux/sched.h>
+-#include <linux/smp.h>
+-#include <linux/mm.h>
+-#include <linux/reboot.h>
+-#include <linux/delay.h>
+-#include <linux/kallsyms.h>
+-#include <linux/cpumask.h>
+-
+-#include <asm/ptrace.h>
+-#include <asm/string.h>
+-#include <asm/prom.h>
+-#include <asm/machdep.h>
+-#include <asm/processor.h>
+-#include <asm/pgtable.h>
+-#include <asm/mmu.h>
+-#include <asm/mmu_context.h>
+-#include <asm/paca.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/cputable.h>
+-#include <asm/rtas.h>
+-#include <asm/sstep.h>
+-#include <asm/bug.h>
+-#include <asm/hvcall.h>
+-
+-#include "nonstdio.h"
+-#include "privinst.h"
+-
+-#define scanhex	xmon_scanhex
+-#define skipbl	xmon_skipbl
+-
+-#ifdef CONFIG_SMP
+-cpumask_t cpus_in_xmon = CPU_MASK_NONE;
+-static unsigned long xmon_taken = 1;
+-static int xmon_owner;
+-static int xmon_gate;
+-#endif /* CONFIG_SMP */
+-
+-static unsigned long in_xmon = 0;
+-
+-static unsigned long adrs;
+-static int size = 1;
+-#define MAX_DUMP (128 * 1024)
+-static unsigned long ndump = 64;
+-static unsigned long nidump = 16;
+-static unsigned long ncsum = 4096;
+-static int termch;
+-static char tmpstr[128];
+-
+-#define JMP_BUF_LEN	(184/sizeof(long))
+-static long bus_error_jmp[JMP_BUF_LEN];
+-static int catch_memory_errors;
+-static long *xmon_fault_jmp[NR_CPUS];
+-#define setjmp xmon_setjmp
+-#define longjmp xmon_longjmp
+-
+-/* Breakpoint stuff */
+-struct bpt {
+-	unsigned long	address;
+-	unsigned int	instr[2];
+-	atomic_t	ref_count;
+-	int		enabled;
+-	unsigned long	pad;
+-};
+-
+-/* Bits in bpt.enabled */
+-#define BP_IABR_TE	1		/* IABR translation enabled */
+-#define BP_IABR		2
+-#define BP_TRAP		8
+-#define BP_DABR		0x10
+-
+-#define NBPTS	256
+-static struct bpt bpts[NBPTS];
+-static struct bpt dabr;
+-static struct bpt *iabr;
+-static unsigned bpinstr = 0x7fe00008;	/* trap */
+-
+-#define BP_NUM(bp)	((bp) - bpts + 1)
+-
+-/* Prototypes */
+-static int cmds(struct pt_regs *);
+-static int mread(unsigned long, void *, int);
+-static int mwrite(unsigned long, void *, int);
+-static int handle_fault(struct pt_regs *);
+-static void byterev(unsigned char *, int);
+-static void memex(void);
+-static int bsesc(void);
+-static void dump(void);
+-static void prdump(unsigned long, long);
+-static int ppc_inst_dump(unsigned long, long, int);
+-void print_address(unsigned long);
+-static void backtrace(struct pt_regs *);
+-static void excprint(struct pt_regs *);
+-static void prregs(struct pt_regs *);
+-static void memops(int);
+-static void memlocate(void);
+-static void memzcan(void);
+-static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
+-int skipbl(void);
+-int scanhex(unsigned long *valp);
+-static void scannl(void);
+-static int hexdigit(int);
+-void getstring(char *, int);
+-static void flush_input(void);
+-static int inchar(void);
+-static void take_input(char *);
+-static unsigned long read_spr(int);
+-static void write_spr(int, unsigned long);
+-static void super_regs(void);
+-static void remove_bpts(void);
+-static void insert_bpts(void);
+-static void remove_cpu_bpts(void);
+-static void insert_cpu_bpts(void);
+-static struct bpt *at_breakpoint(unsigned long pc);
+-static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
+-static int  do_step(struct pt_regs *);
+-static void bpt_cmds(void);
+-static void cacheflush(void);
+-static int  cpu_cmd(void);
+-static void csum(void);
+-static void bootcmds(void);
+-void dump_segments(void);
+-static void symbol_lookup(void);
+-static void xmon_print_symbol(unsigned long address, const char *mid,
+-			      const char *after);
+-static const char *getvecname(unsigned long vec);
+-
+-static void debug_trace(void);
+-
+-extern int print_insn_powerpc(unsigned long, unsigned long, int);
+-extern void printf(const char *fmt, ...);
+-extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
+-extern int xmon_putc(int c, void *f);
+-extern int putchar(int ch);
+-extern int xmon_read_poll(void);
+-extern int setjmp(long *);
+-extern void longjmp(long *, int);
+-extern unsigned long _ASR;
+-
+-#define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
+-
+-#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
+-			 || ('a' <= (c) && (c) <= 'f') \
+-			 || ('A' <= (c) && (c) <= 'F'))
+-#define isalnum(c)	(('0' <= (c) && (c) <= '9') \
+-			 || ('a' <= (c) && (c) <= 'z') \
+-			 || ('A' <= (c) && (c) <= 'Z'))
+-#define isspace(c)	(c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
+-
+-static char *help_string = "\
+-Commands:\n\
+-  b	show breakpoints\n\
+-  bd	set data breakpoint\n\
+-  bi	set instruction breakpoint\n\
+-  bc	clear breakpoint\n"
+-#ifdef CONFIG_SMP
+-  "\
+-  c	print cpus stopped in xmon\n\
+-  c#	try to switch to cpu number h (in hex)\n"
+-#endif
+-  "\
+-  C	checksum\n\
+-  d	dump bytes\n\
+-  di	dump instructions\n\
+-  df	dump float values\n\
+-  dd	dump double values\n\
+-  e	print exception information\n\
+-  f	flush cache\n\
+-  la	lookup symbol+offset of specified address\n\
+-  ls	lookup address of specified symbol\n\
+-  m	examine/change memory\n\
+-  mm	move a block of memory\n\
+-  ms	set a block of memory\n\
+-  md	compare two blocks of memory\n\
+-  ml	locate a block of memory\n\
+-  mz	zero a block of memory\n\
+-  mi	show information about memory allocation\n\
+-  p 	show the task list\n\
+-  r	print registers\n\
+-  s	single step\n\
+-  S	print special registers\n\
+-  t	print backtrace\n\
+-  T	Enable/Disable PPCDBG flags\n\
+-  x	exit monitor and recover\n\
+-  X	exit monitor and dont recover\n\
+-  u	dump segment table or SLB\n\
+-  ?	help\n"
+-  "\
+-  zr	reboot\n\
+-  zh	halt\n"
+-;
+-
+-static struct pt_regs *xmon_regs;
+-
+-extern inline void sync(void)
+-{
+-	asm volatile("sync; isync");
+-}
+-
+-/* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
+- A PPC stack frame looks like this:
+-
+- High Address
+-    Back Chain
+-    FP reg save area
+-    GP reg save area
+-    Local var space
+-    Parameter save area		(SP+48)
+-    TOC save area		(SP+40)
+-    link editor doubleword	(SP+32)
+-    compiler doubleword		(SP+24)
+-    LR save			(SP+16)
+-    CR save			(SP+8)
+-    Back Chain			(SP+0)
+-
+- Note that the LR (ret addr) may not be saved in the current frame if
+- no functions have been called from the current function.
+- */
+-
+-/*
+- * Disable surveillance (the service processor watchdog function)
+- * while we are in xmon.
+- * XXX we should re-enable it when we leave. :)
+- */
+-#define SURVEILLANCE_TOKEN	9000
+-
+-static inline void disable_surveillance(void)
+-{
+-#ifdef CONFIG_PPC_PSERIES
+-	/* Since this can't be a module, args should end up below 4GB. */
+-	static struct rtas_args args;
+-
+-	/*
+-	 * At this point we have got all the cpus we can into
+-	 * xmon, so there is hopefully no other cpu calling RTAS
+-	 * at the moment, even though we don't take rtas.lock.
+-	 * If we did try to take rtas.lock there would be a
+-	 * real possibility of deadlock.
+-	 */
+-	args.token = rtas_token("set-indicator");
+-	if (args.token == RTAS_UNKNOWN_SERVICE)
+-		return;
+-	args.nargs = 3;
+-	args.nret = 1;
+-	args.rets = &args.args[3];
+-	args.args[0] = SURVEILLANCE_TOKEN;
+-	args.args[1] = 0;
+-	args.args[2] = 0;
+-	enter_rtas(__pa(&args));
+-#endif /* CONFIG_PPC_PSERIES */
+-}
+-
+-#ifdef CONFIG_SMP
+-static int xmon_speaker;
+-
+-static void get_output_lock(void)
+-{
+-	int me = smp_processor_id() + 0x100;
+-	int last_speaker = 0, prev;
+-	long timeout;
+-
+-	if (xmon_speaker == me)
+-		return;
+-	for (;;) {
+-		if (xmon_speaker == 0) {
+-			last_speaker = cmpxchg(&xmon_speaker, 0, me);
+-			if (last_speaker == 0)
+-				return;
+-		}
+-		timeout = 10000000;
+-		while (xmon_speaker == last_speaker) {
+-			if (--timeout > 0)
+-				continue;
+-			/* hostile takeover */
+-			prev = cmpxchg(&xmon_speaker, last_speaker, me);
+-			if (prev == last_speaker)
+-				return;
+-			break;
+-		}
+-	}
+-}
+-
+-static void release_output_lock(void)
+-{
+-	xmon_speaker = 0;
+-}
+-#endif
+-
+-int xmon_core(struct pt_regs *regs, int fromipi)
+-{
+-	int cmd = 0;
+-	unsigned long msr;
+-	struct bpt *bp;
+-	long recurse_jmp[JMP_BUF_LEN];
+-	unsigned long offset;
+-#ifdef CONFIG_SMP
+-	int cpu;
+-	int secondary;
+-	unsigned long timeout;
+-#endif
+-
+-	msr = get_msr();
+-	set_msrd(msr & ~MSR_EE);	/* disable interrupts */
+-
+-	bp = in_breakpoint_table(regs->nip, &offset);
+-	if (bp != NULL) {
+-		regs->nip = bp->address + offset;
+-		atomic_dec(&bp->ref_count);
+-	}
+-
+-	remove_cpu_bpts();
+-
+-#ifdef CONFIG_SMP
+-	cpu = smp_processor_id();
+-	if (cpu_isset(cpu, cpus_in_xmon)) {
+-		get_output_lock();
+-		excprint(regs);
+-		printf("cpu 0x%x: Exception %lx %s in xmon, "
+-		       "returning to main loop\n",
+-		       cpu, regs->trap, getvecname(TRAP(regs)));
+-		release_output_lock();
+-		longjmp(xmon_fault_jmp[cpu], 1);
+-	}
+-
+-	if (setjmp(recurse_jmp) != 0) {
+-		if (!in_xmon || !xmon_gate) {
+-			get_output_lock();
+-			printf("xmon: WARNING: bad recursive fault "
+-			       "on cpu 0x%x\n", cpu);
+-			release_output_lock();
+-			goto waiting;
+-		}
+-		secondary = !(xmon_taken && cpu == xmon_owner);
+-		goto cmdloop;
+-	}
+-
+-	xmon_fault_jmp[cpu] = recurse_jmp;
+-	cpu_set(cpu, cpus_in_xmon);
+-
+-	bp = NULL;
+-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
+-		bp = at_breakpoint(regs->nip);
+-	if (bp || (regs->msr & MSR_RI) == 0)
+-		fromipi = 0;
+-
+-	if (!fromipi) {
+-		get_output_lock();
+-		excprint(regs);
+-		if (bp) {
+-			printf("cpu 0x%x stopped at breakpoint 0x%x (",
+-			       cpu, BP_NUM(bp));
+-			xmon_print_symbol(regs->nip, " ", ")\n");
+-		}
+-		if ((regs->msr & MSR_RI) == 0)
+-			printf("WARNING: exception is not recoverable, "
+-			       "can't continue\n");
+-		release_output_lock();
+-	}
+-
+- waiting:
+-	secondary = 1;
+-	while (secondary && !xmon_gate) {
+-		if (in_xmon == 0) {
+-			if (fromipi)
+-				goto leave;
+-			secondary = test_and_set_bit(0, &in_xmon);
+-		}
+-		barrier();
+-	}
+-
+-	if (!secondary && !xmon_gate) {
+-		/* we are the first cpu to come in */
+-		/* interrupt other cpu(s) */
+-		int ncpus = num_online_cpus();
+-
+-		xmon_owner = cpu;
+-		mb();
+-		if (ncpus > 1) {
+-			smp_send_debugger_break(MSG_ALL_BUT_SELF);
+-			/* wait for other cpus to come in */
+-			for (timeout = 100000000; timeout != 0; --timeout) {
+-				if (cpus_weight(cpus_in_xmon) >= ncpus)
+-					break;
+-				barrier();
+-			}
+-		}
+-		remove_bpts();
+-		disable_surveillance();
+-		/* for breakpoint or single step, print the current instr. */
+-		if (bp || TRAP(regs) == 0xd00)
+-			ppc_inst_dump(regs->nip, 1, 0);
+-		printf("enter ? for help\n");
+-		mb();
+-		xmon_gate = 1;
+-		barrier();
+-	}
+-
+- cmdloop:
+-	while (in_xmon) {
+-		if (secondary) {
+-			if (cpu == xmon_owner) {
+-				if (!test_and_set_bit(0, &xmon_taken)) {
+-					secondary = 0;
+-					continue;
+-				}
+-				/* missed it */
+-				while (cpu == xmon_owner)
+-					barrier();
+-			}
+-			barrier();
+-		} else {
+-			cmd = cmds(regs);
+-			if (cmd != 0) {
+-				/* exiting xmon */
+-				insert_bpts();
+-				xmon_gate = 0;
+-				wmb();
+-				in_xmon = 0;
+-				break;
+-			}
+-			/* have switched to some other cpu */
+-			secondary = 1;
+-		}
+-	}
+- leave:
+-	cpu_clear(cpu, cpus_in_xmon);
+-	xmon_fault_jmp[cpu] = NULL;
+-
+-#else
+-	/* UP is simple... */
+-	if (in_xmon) {
+-		printf("Exception %lx %s in xmon, returning to main loop\n",
+-		       regs->trap, getvecname(TRAP(regs)));
+-		longjmp(xmon_fault_jmp[0], 1);
+-	}
+-	if (setjmp(recurse_jmp) == 0) {
+-		xmon_fault_jmp[0] = recurse_jmp;
+-		in_xmon = 1;
+-
+-		excprint(regs);
+-		bp = at_breakpoint(regs->nip);
+-		if (bp) {
+-			printf("Stopped at breakpoint %x (", BP_NUM(bp));
+-			xmon_print_symbol(regs->nip, " ", ")\n");
+-		}
+-		if ((regs->msr & MSR_RI) == 0)
+-			printf("WARNING: exception is not recoverable, "
+-			       "can't continue\n");
+-		remove_bpts();
+-		disable_surveillance();
+-		/* for breakpoint or single step, print the current instr. */
+-		if (bp || TRAP(regs) == 0xd00)
+-			ppc_inst_dump(regs->nip, 1, 0);
+-		printf("enter ? for help\n");
+-	}
+-
+-	cmd = cmds(regs);
+-
+-	insert_bpts();
+-	in_xmon = 0;
+-#endif
+-
+-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
+-		bp = at_breakpoint(regs->nip);
+-		if (bp != NULL) {
+-			int stepped = emulate_step(regs, bp->instr[0]);
+-			if (stepped == 0) {
+-				regs->nip = (unsigned long) &bp->instr[0];
+-				atomic_inc(&bp->ref_count);
+-			} else if (stepped < 0) {
+-				printf("Couldn't single-step %s instruction\n",
+-				    (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
+-			}
+-		}
+-	}
+-
+-	insert_cpu_bpts();
+-
+-	set_msrd(msr);		/* restore interrupt enable */
+-
+-	return cmd != 'X';
+-}
+-
+-int xmon(struct pt_regs *excp)
+-{
+-	struct pt_regs regs;
+-
+-	if (excp == NULL) {
+-		/* Ok, grab regs as they are now.
+-		 This won't do a particularily good job because the
+-		 prologue has already been executed.
+-		 ToDo: We could reach back into the callers save
+-		 area to do a better job of representing the
+-		 caller's state.
+-		 */
+-		asm volatile ("std	0,0(%0)\n\
+-			std	1,8(%0)\n\
+-			std	2,16(%0)\n\
+-			std	3,24(%0)\n\
+-			std	4,32(%0)\n\
+-			std	5,40(%0)\n\
+-			std	6,48(%0)\n\
+-			std	7,56(%0)\n\
+-			std	8,64(%0)\n\
+-			std	9,72(%0)\n\
+-			std	10,80(%0)\n\
+-			std	11,88(%0)\n\
+-			std	12,96(%0)\n\
+-			std	13,104(%0)\n\
+-			std	14,112(%0)\n\
+-			std	15,120(%0)\n\
+-			std	16,128(%0)\n\
+-			std	17,136(%0)\n\
+-			std	18,144(%0)\n\
+-			std	19,152(%0)\n\
+-			std	20,160(%0)\n\
+-			std	21,168(%0)\n\
+-			std	22,176(%0)\n\
+-			std	23,184(%0)\n\
+-			std	24,192(%0)\n\
+-			std	25,200(%0)\n\
+-			std	26,208(%0)\n\
+-			std	27,216(%0)\n\
+-			std	28,224(%0)\n\
+-			std	29,232(%0)\n\
+-			std	30,240(%0)\n\
+-			std	31,248(%0)" : : "b" (&regs));
+-
+-		regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
+-		regs.msr = get_msr();
+-		regs.ctr = get_ctr();
+-		regs.xer = get_xer();
+-		regs.ccr = get_cr();
+-		regs.trap = 0;
+-		excp = &regs;
+-	}
+-	return xmon_core(excp, 0);
+-}
+-
+-int xmon_bpt(struct pt_regs *regs)
+-{
+-	struct bpt *bp;
+-	unsigned long offset;
+-
+-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
+-		return 0;
+-
+-	/* Are we at the trap at bp->instr[1] for some bp? */
+-	bp = in_breakpoint_table(regs->nip, &offset);
+-	if (bp != NULL && offset == 4) {
+-		regs->nip = bp->address + 4;
+-		atomic_dec(&bp->ref_count);
+-		return 1;
+-	}
+-
+-	/* Are we at a breakpoint? */
+-	bp = at_breakpoint(regs->nip);
+-	if (!bp)
+-		return 0;
+-
+-	xmon_core(regs, 0);
+-
+-	return 1;
+-}
+-
+-int xmon_sstep(struct pt_regs *regs)
+-{
+-	if (user_mode(regs))
+-		return 0;
+-	xmon_core(regs, 0);
+-	return 1;
+-}
+-
+-int xmon_dabr_match(struct pt_regs *regs)
+-{
+-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
+-		return 0;
+-	if (dabr.enabled == 0)
+-		return 0;
+-	xmon_core(regs, 0);
+-	return 1;
+-}
+-
+-int xmon_iabr_match(struct pt_regs *regs)
+-{
+-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
+-		return 0;
+-	if (iabr == 0)
+-		return 0;
+-	xmon_core(regs, 0);
+-	return 1;
+-}
+-
+-int xmon_ipi(struct pt_regs *regs)
+-{
+-#ifdef CONFIG_SMP
+-	if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
+-		xmon_core(regs, 1);
+-#endif
+-	return 0;
+-}
+-
+-int xmon_fault_handler(struct pt_regs *regs)
+-{
+-	struct bpt *bp;
+-	unsigned long offset;
+-
+-	if (in_xmon && catch_memory_errors)
+-		handle_fault(regs);	/* doesn't return */
+-
+-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
+-		bp = in_breakpoint_table(regs->nip, &offset);
+-		if (bp != NULL) {
+-			regs->nip = bp->address + offset;
+-			atomic_dec(&bp->ref_count);
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static struct bpt *at_breakpoint(unsigned long pc)
+-{
+-	int i;
+-	struct bpt *bp;
+-
+-	bp = bpts;
+-	for (i = 0; i < NBPTS; ++i, ++bp)
+-		if (bp->enabled && pc == bp->address)
+-			return bp;
+-	return NULL;
+-}
+-
+-static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
+-{
+-	unsigned long off;
+-
+-	off = nip - (unsigned long) bpts;
+-	if (off >= sizeof(bpts))
+-		return NULL;
+-	off %= sizeof(struct bpt);
+-	if (off != offsetof(struct bpt, instr[0])
+-	    && off != offsetof(struct bpt, instr[1]))
+-		return NULL;
+-	*offp = off - offsetof(struct bpt, instr[0]);
+-	return (struct bpt *) (nip - off);
+-}
+-
+-static struct bpt *new_breakpoint(unsigned long a)
+-{
+-	struct bpt *bp;
+-
+-	a &= ~3UL;
+-	bp = at_breakpoint(a);
+-	if (bp)
+-		return bp;
+-
+-	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
+-		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
+-			bp->address = a;
+-			bp->instr[1] = bpinstr;
+-			store_inst(&bp->instr[1]);
+-			return bp;
+-		}
+-	}
+-
+-	printf("Sorry, no free breakpoints.  Please clear one first.\n");
+-	return NULL;
+-}
+-
+-static void insert_bpts(void)
+-{
+-	int i;
+-	struct bpt *bp;
+-
+-	bp = bpts;
+-	for (i = 0; i < NBPTS; ++i, ++bp) {
+-		if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
+-			continue;
+-		if (mread(bp->address, &bp->instr[0], 4) != 4) {
+-			printf("Couldn't read instruction at %lx, "
+-			       "disabling breakpoint there\n", bp->address);
+-			bp->enabled = 0;
+-			continue;
+-		}
+-		if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
+-			printf("Breakpoint at %lx is on an mtmsrd or rfid "
+-			       "instruction, disabling it\n", bp->address);
+-			bp->enabled = 0;
+-			continue;
+-		}
+-		store_inst(&bp->instr[0]);
+-		if (bp->enabled & BP_IABR)
+-			continue;
+-		if (mwrite(bp->address, &bpinstr, 4) != 4) {
+-			printf("Couldn't write instruction at %lx, "
+-			       "disabling breakpoint there\n", bp->address);
+-			bp->enabled &= ~BP_TRAP;
+-			continue;
+-		}
+-		store_inst((void *)bp->address);
+-	}
+-}
+-
+-static void insert_cpu_bpts(void)
+-{
+-	if (dabr.enabled)
+-		set_dabr(dabr.address | (dabr.enabled & 7));
+-	if (iabr && cpu_has_feature(CPU_FTR_IABR))
+-		set_iabr(iabr->address
+-			 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
+-}
+-
+-static void remove_bpts(void)
+-{
+-	int i;
+-	struct bpt *bp;
+-	unsigned instr;
+-
+-	bp = bpts;
+-	for (i = 0; i < NBPTS; ++i, ++bp) {
+-		if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
+-			continue;
+-		if (mread(bp->address, &instr, 4) == 4
+-		    && instr == bpinstr
+-		    && mwrite(bp->address, &bp->instr, 4) != 4)
+-			printf("Couldn't remove breakpoint at %lx\n",
+-			       bp->address);
+-		else
+-			store_inst((void *)bp->address);
+-	}
+-}
+-
+-static void remove_cpu_bpts(void)
+-{
+-	set_dabr(0);
+-	if (cpu_has_feature(CPU_FTR_IABR))
+-		set_iabr(0);
+-}
+-
+-/* Command interpreting routine */
+-static char *last_cmd;
+-
+-static int
+-cmds(struct pt_regs *excp)
+-{
+-	int cmd = 0;
+-
+-	last_cmd = NULL;
+-	xmon_regs = excp;
+-	for(;;) {
+-#ifdef CONFIG_SMP
+-		printf("%x:", smp_processor_id());
+-#endif /* CONFIG_SMP */
+-		printf("mon> ");
+-		fflush(stdout);
+-		flush_input();
+-		termch = 0;
+-		cmd = skipbl();
+-		if( cmd == '\n' ) {
+-			if (last_cmd == NULL)
+-				continue;
+-			take_input(last_cmd);
+-			last_cmd = NULL;
+-			cmd = inchar();
+-		}
+-		switch (cmd) {
+-		case 'm':
+-			cmd = inchar();
+-			switch (cmd) {
+-			case 'm':
+-			case 's':
+-			case 'd':
+-				memops(cmd);
+-				break;
+-			case 'l':
+-				memlocate();
+-				break;
+-			case 'z':
+-				memzcan();
+-				break;
+-			case 'i':
+-				show_mem();
+-				break;
+-			default:
+-				termch = cmd;
+-				memex();
+-			}
+-			break;
+-		case 'd':
+-			dump();
+-			break;
+-		case 'l':
+-			symbol_lookup();
+-			break;
+-		case 'r':
+-			prregs(excp);	/* print regs */
+-			break;
+-		case 'e':
+-			excprint(excp);
+-			break;
+-		case 'S':
+-			super_regs();
+-			break;
+-		case 't':
+-			backtrace(excp);
+-			break;
+-		case 'f':
+-			cacheflush();
+-			break;
+-		case 's':
+-			if (do_step(excp))
+-				return cmd;
+-			break;
+-		case 'x':
+-		case 'X':
+-		case EOF:
+-			return cmd;
+-		case '?':
+-			printf(help_string);
+-			break;
+-		case 'p':
+-			show_state();
+-			break;
+-		case 'b':
+-			bpt_cmds();
+-			break;
+-		case 'C':
+-			csum();
+-			break;
+-		case 'c':
+-			if (cpu_cmd())
+-				return 0;
+-			break;
+-		case 'z':
+-			bootcmds();
+-			break;
+-		case 'T':
+-			debug_trace();
+-			break;
+-		case 'u':
+-			dump_segments();
+-			break;
+-		default:
+-			printf("Unrecognized command: ");
+-		        do {
+-				if (' ' < cmd && cmd <= '~')
+-					putchar(cmd);
+-				else
+-					printf("\\x%x", cmd);
+-				cmd = inchar();
+-		        } while (cmd != '\n'); 
+-			printf(" (type ? for help)\n");
+-			break;
+-		}
+-	}
+-}
+-
+-/*
+- * Step a single instruction.
+- * Some instructions we emulate, others we execute with MSR_SE set.
+- */
+-static int do_step(struct pt_regs *regs)
+-{
+-	unsigned int instr;
+-	int stepped;
+-
+-	/* check we are in 64-bit kernel mode, translation enabled */
+-	if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
+-		if (mread(regs->nip, &instr, 4) == 4) {
+-			stepped = emulate_step(regs, instr);
+-			if (stepped < 0) {
+-				printf("Couldn't single-step %s instruction\n",
+-				       (IS_RFID(instr)? "rfid": "mtmsrd"));
+-				return 0;
+-			}
+-			if (stepped > 0) {
+-				regs->trap = 0xd00 | (regs->trap & 1);
+-				printf("stepped to ");
+-				xmon_print_symbol(regs->nip, " ", "\n");
+-				ppc_inst_dump(regs->nip, 1, 0);
+-				return 0;
+-			}
+-		}
+-	}
+-	regs->msr |= MSR_SE;
+-	return 1;
+-}
+-
+-static void bootcmds(void)
+-{
+-	int cmd;
+-
+-	cmd = inchar();
+-	if (cmd == 'r')
+-		ppc_md.restart(NULL);
+-	else if (cmd == 'h')
+-		ppc_md.halt();
+-	else if (cmd == 'p')
+-		ppc_md.power_off();
+-}
+-
+-static int cpu_cmd(void)
+-{
+-#ifdef CONFIG_SMP
+-	unsigned long cpu;
+-	int timeout;
+-	int count;
+-
+-	if (!scanhex(&cpu)) {
+-		/* print cpus waiting or in xmon */
+-		printf("cpus stopped:");
+-		count = 0;
+-		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+-			if (cpu_isset(cpu, cpus_in_xmon)) {
+-				if (count == 0)
+-					printf(" %x", cpu);
+-				++count;
+-			} else {
+-				if (count > 1)
+-					printf("-%x", cpu - 1);
+-				count = 0;
+-			}
+-		}
+-		if (count > 1)
+-			printf("-%x", NR_CPUS - 1);
+-		printf("\n");
+-		return 0;
+-	}
+-	/* try to switch to cpu specified */
+-	if (!cpu_isset(cpu, cpus_in_xmon)) {
+-		printf("cpu 0x%x isn't in xmon\n", cpu);
+-		return 0;
+-	}
+-	xmon_taken = 0;
+-	mb();
+-	xmon_owner = cpu;
+-	timeout = 10000000;
+-	while (!xmon_taken) {
+-		if (--timeout == 0) {
+-			if (test_and_set_bit(0, &xmon_taken))
+-				break;
+-			/* take control back */
+-			mb();
+-			xmon_owner = smp_processor_id();
+-			printf("cpu %u didn't take control\n", cpu);
+-			return 0;
+-		}
+-		barrier();
+-	}
+-	return 1;
+-#else
+-	return 0;
+-#endif /* CONFIG_SMP */
+-}
+-
+-static unsigned short fcstab[256] = {
+-	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+-	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+-	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+-	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+-	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+-	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+-	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+-	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+-	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+-	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+-	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+-	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+-	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+-	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+-	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+-	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+-	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+-	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+-	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+-	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+-	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+-	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+-	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+-	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+-	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+-	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+-	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+-	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+-	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+-	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+-	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+-	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+-};
+-
+-#define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
+-
+-static void
+-csum(void)
+-{
+-	unsigned int i;
+-	unsigned short fcs;
+-	unsigned char v;
+-
+-	if (!scanhex(&adrs))
+-		return;
+-	if (!scanhex(&ncsum))
+-		return;
+-	fcs = 0xffff;
+-	for (i = 0; i < ncsum; ++i) {
+-		if (mread(adrs+i, &v, 1) == 0) {
+-			printf("csum stopped at %x\n", adrs+i);
+-			break;
+-		}
+-		fcs = FCS(fcs, v);
+-	}
+-	printf("%x\n", fcs);
+-}
+-
+-/*
+- * Check if this is a suitable place to put a breakpoint.
+- */
+-static long check_bp_loc(unsigned long addr)
+-{
+-	unsigned int instr;
+-
+-	addr &= ~3;
+-	if (addr < KERNELBASE) {
+-		printf("Breakpoints may only be placed at kernel addresses\n");
+-		return 0;
+-	}
+-	if (!mread(addr, &instr, sizeof(instr))) {
+-		printf("Can't read instruction at address %lx\n", addr);
+-		return 0;
+-	}
+-	if (IS_MTMSRD(instr) || IS_RFID(instr)) {
+-		printf("Breakpoints may not be placed on mtmsrd or rfid "
+-		       "instructions\n");
+-		return 0;
+-	}
+-	return 1;
+-}
+-
+-static char *breakpoint_help_string = 
+-    "Breakpoint command usage:\n"
+-    "b                show breakpoints\n"
+-    "b <addr> [cnt]   set breakpoint at given instr addr\n"
+-    "bc               clear all breakpoints\n"
+-    "bc <n/addr>      clear breakpoint number n or at addr\n"
+-    "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
+-    "bd <addr> [cnt]  set hardware data breakpoint\n"
+-    "";
+-
+-static void
+-bpt_cmds(void)
+-{
+-	int cmd;
+-	unsigned long a;
+-	int mode, i;
+-	struct bpt *bp;
+-	const char badaddr[] = "Only kernel addresses are permitted "
+-		"for breakpoints\n";
+-
+-	cmd = inchar();
+-	switch (cmd) {
+-	case 'd':	/* bd - hardware data breakpoint */
+-		mode = 7;
+-		cmd = inchar();
+-		if (cmd == 'r')
+-			mode = 5;
+-		else if (cmd == 'w')
+-			mode = 6;
+-		else
+-			termch = cmd;
+-		dabr.address = 0;
+-		dabr.enabled = 0;
+-		if (scanhex(&dabr.address)) {
+-			if (dabr.address < KERNELBASE) {
+-				printf(badaddr);
+-				break;
+-			}
+-			dabr.address &= ~7;
+-			dabr.enabled = mode | BP_DABR;
+-		}
+-		break;
+-
+-	case 'i':	/* bi - hardware instr breakpoint */
+-		if (!cpu_has_feature(CPU_FTR_IABR)) {
+-			printf("Hardware instruction breakpoint "
+-			       "not supported on this cpu\n");
+-			break;
+-		}
+-		if (iabr) {
+-			iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
+-			iabr = NULL;
+-		}
+-		if (!scanhex(&a))
+-			break;
+-		if (!check_bp_loc(a))
+-			break;
+-		bp = new_breakpoint(a);
+-		if (bp != NULL) {
+-			bp->enabled |= BP_IABR | BP_IABR_TE;
+-			iabr = bp;
+-		}
+-		break;
+-
+-	case 'c':
+-		if (!scanhex(&a)) {
+-			/* clear all breakpoints */
+-			for (i = 0; i < NBPTS; ++i)
+-				bpts[i].enabled = 0;
+-			iabr = NULL;
+-			dabr.enabled = 0;
+-			printf("All breakpoints cleared\n");
+-			break;
+-		}
+-
+-		if (a <= NBPTS && a >= 1) {
+-			/* assume a breakpoint number */
+-			bp = &bpts[a-1];	/* bp nums are 1 based */
+-		} else {
+-			/* assume a breakpoint address */
+-			bp = at_breakpoint(a);
+-			if (bp == 0) {
+-				printf("No breakpoint at %x\n", a);
+-				break;
+-			}
+-		}
+-
+-		printf("Cleared breakpoint %x (", BP_NUM(bp));
+-		xmon_print_symbol(bp->address, " ", ")\n");
+-		bp->enabled = 0;
+-		break;
+-
+-	default:
+-		termch = cmd;
+-	        cmd = skipbl();
+-		if (cmd == '?') {
+-			printf(breakpoint_help_string);
+-			break;
+-		}
+-		termch = cmd;
+-		if (!scanhex(&a)) {
+-			/* print all breakpoints */
+-			printf("   type            address\n");
+-			if (dabr.enabled) {
+-				printf("   data   %.16lx  [", dabr.address);
+-				if (dabr.enabled & 1)
+-					printf("r");
+-				if (dabr.enabled & 2)
+-					printf("w");
+-				printf("]\n");
+-			}
+-			for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
+-				if (!bp->enabled)
+-					continue;
+-				printf("%2x %s   ", BP_NUM(bp),
+-				    (bp->enabled & BP_IABR)? "inst": "trap");
+-				xmon_print_symbol(bp->address, "  ", "\n");
+-			}
+-			break;
+-		}
+-
+-		if (!check_bp_loc(a))
+-			break;
+-		bp = new_breakpoint(a);
+-		if (bp != NULL)
+-			bp->enabled |= BP_TRAP;
+-		break;
+-	}
+-}
+-
+-/* Very cheap human name for vector lookup. */
+-static
+-const char *getvecname(unsigned long vec)
+-{
+-	char *ret;
+-
+-	switch (vec) {
+-	case 0x100:	ret = "(System Reset)"; break;
+-	case 0x200:	ret = "(Machine Check)"; break;
+-	case 0x300:	ret = "(Data Access)"; break;
+-	case 0x380:	ret = "(Data SLB Access)"; break;
+-	case 0x400:	ret = "(Instruction Access)"; break;
+-	case 0x480:	ret = "(Instruction SLB Access)"; break;
+-	case 0x500:	ret = "(Hardware Interrupt)"; break;
+-	case 0x600:	ret = "(Alignment)"; break;
+-	case 0x700:	ret = "(Program Check)"; break;
+-	case 0x800:	ret = "(FPU Unavailable)"; break;
+-	case 0x900:	ret = "(Decrementer)"; break;
+-	case 0xc00:	ret = "(System Call)"; break;
+-	case 0xd00:	ret = "(Single Step)"; break;
+-	case 0xf00:	ret = "(Performance Monitor)"; break;
+-	case 0xf20:	ret = "(Altivec Unavailable)"; break;
+-	case 0x1300:	ret = "(Instruction Breakpoint)"; break;
+-	default: ret = "";
+-	}
+-	return ret;
+-}
+-
+-static void get_function_bounds(unsigned long pc, unsigned long *startp,
+-				unsigned long *endp)
+-{
+-	unsigned long size, offset;
+-	const char *name;
+-	char *modname;
+-
+-	*startp = *endp = 0;
+-	if (pc == 0)
+-		return;
+-	if (setjmp(bus_error_jmp) == 0) {
+-		catch_memory_errors = 1;
+-		sync();
+-		name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
+-		if (name != NULL) {
+-			*startp = pc - offset;
+-			*endp = pc - offset + size;
+-		}
+-		sync();
+-	}
+-	catch_memory_errors = 0;
+-}
+-
+-static int xmon_depth_to_print = 64;
+-
+-static void xmon_show_stack(unsigned long sp, unsigned long lr,
+-			    unsigned long pc)
+-{
+-	unsigned long ip;
+-	unsigned long newsp;
+-	unsigned long marker;
+-	int count = 0;
+-	struct pt_regs regs;
+-
+-	do {
+-		if (sp < PAGE_OFFSET) {
+-			if (sp != 0)
+-				printf("SP (%lx) is in userspace\n", sp);
+-			break;
+-		}
+-
+-		if (!mread(sp + 16, &ip, sizeof(unsigned long))
+-		    || !mread(sp, &newsp, sizeof(unsigned long))) {
+-			printf("Couldn't read stack frame at %lx\n", sp);
+-			break;
+-		}
+-
+-		/*
+-		 * For the first stack frame, try to work out if
+-		 * LR and/or the saved LR value in the bottommost
+-		 * stack frame are valid.
+-		 */
+-		if ((pc | lr) != 0) {
+-			unsigned long fnstart, fnend;
+-			unsigned long nextip;
+-			int printip = 1;
+-
+-			get_function_bounds(pc, &fnstart, &fnend);
+-			nextip = 0;
+-			if (newsp > sp)
+-				mread(newsp + 16, &nextip,
+-				      sizeof(unsigned long));
+-			if (lr == ip) {
+-				if (lr < PAGE_OFFSET
+-				    || (fnstart <= lr && lr < fnend))
+-					printip = 0;
+-			} else if (lr == nextip) {
+-				printip = 0;
+-			} else if (lr >= PAGE_OFFSET
+-				   && !(fnstart <= lr && lr < fnend)) {
+-				printf("[link register   ] ");
+-				xmon_print_symbol(lr, " ", "\n");
+-			}
+-			if (printip) {
+-				printf("[%.16lx] ", sp);
+-				xmon_print_symbol(ip, " ", " (unreliable)\n");
+-			}
+-			pc = lr = 0;
+-
+-		} else {
+-			printf("[%.16lx] ", sp);
+-			xmon_print_symbol(ip, " ", "\n");
+-		}
+-
+-		/* Look for "regshere" marker to see if this is
+-		   an exception frame. */
+-		if (mread(sp + 0x60, &marker, sizeof(unsigned long))
+-		    && marker == 0x7265677368657265ul) {
+-			if (mread(sp + 0x70, &regs, sizeof(regs))
+-			    != sizeof(regs)) {
+-				printf("Couldn't read registers at %lx\n",
+-				       sp + 0x70);
+-				break;
+-			}
+-                        printf("--- Exception: %lx %s at ", regs.trap,
+-			       getvecname(TRAP(&regs)));
+-			pc = regs.nip;
+-			lr = regs.link;
+-			xmon_print_symbol(pc, " ", "\n");
+-		}
+-
+-		if (newsp == 0)
+-			break;
+-
+-		sp = newsp;
+-	} while (count++ < xmon_depth_to_print);
+-}
+-
+-static void backtrace(struct pt_regs *excp)
+-{
+-	unsigned long sp;
+-
+-	if (scanhex(&sp))
+-		xmon_show_stack(sp, 0, 0);
+-	else
+-		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
+-	scannl();
+-}
+-
+-static void print_bug_trap(struct pt_regs *regs)
+-{
+-	struct bug_entry *bug;
+-	unsigned long addr;
+-
+-	if (regs->msr & MSR_PR)
+-		return;		/* not in kernel */
+-	addr = regs->nip;	/* address of trap instruction */
+-	if (addr < PAGE_OFFSET)
+-		return;
+-	bug = find_bug(regs->nip);
+-	if (bug == NULL)
+-		return;
+-	if (bug->line & BUG_WARNING_TRAP)
+-		return;
+-
+-	printf("kernel BUG in %s at %s:%d!\n",
+-	       bug->function, bug->file, (unsigned int)bug->line);
+-}
+-
+-void excprint(struct pt_regs *fp)
+-{
+-	unsigned long trap;
+-
+-#ifdef CONFIG_SMP
+-	printf("cpu 0x%x: ", smp_processor_id());
+-#endif /* CONFIG_SMP */
+-
+-	trap = TRAP(fp);
+-	printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
+-	printf("    pc: ");
+-	xmon_print_symbol(fp->nip, ": ", "\n");
+-
+-	printf("    lr: ", fp->link);
+-	xmon_print_symbol(fp->link, ": ", "\n");
+-
+-	printf("    sp: %lx\n", fp->gpr[1]);
+-	printf("   msr: %lx\n", fp->msr);
+-
+-	if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
+-		printf("   dar: %lx\n", fp->dar);
+-		if (trap != 0x380)
+-			printf(" dsisr: %lx\n", fp->dsisr);
+-	}
+-
+-	printf("  current = 0x%lx\n", current);
+-	printf("  paca    = 0x%lx\n", get_paca());
+-	if (current) {
+-		printf("    pid   = %ld, comm = %s\n",
+-		       current->pid, current->comm);
+-	}
+-
+-	if (trap == 0x700)
+-		print_bug_trap(fp);
+-}
+-
+-void prregs(struct pt_regs *fp)
+-{
+-	int n;
+-	unsigned long base;
+-	struct pt_regs regs;
+-
+-	if (scanhex(&base)) {
+-		if (setjmp(bus_error_jmp) == 0) {
+-			catch_memory_errors = 1;
+-			sync();
+-			regs = *(struct pt_regs *)base;
+-			sync();
+-			__delay(200);
+-		} else {
+-			catch_memory_errors = 0;
+-			printf("*** Error reading registers from %.16lx\n",
+-			       base);
+-			return;
+-		}
+-		catch_memory_errors = 0;
+-		fp = &regs;
+-	}
+-
+-	if (FULL_REGS(fp)) {
+-		for (n = 0; n < 16; ++n)
+-			printf("R%.2ld = %.16lx   R%.2ld = %.16lx\n",
+-			       n, fp->gpr[n], n+16, fp->gpr[n+16]);
+-	} else {
+-		for (n = 0; n < 7; ++n)
+-			printf("R%.2ld = %.16lx   R%.2ld = %.16lx\n",
+-			       n, fp->gpr[n], n+7, fp->gpr[n+7]);
+-	}
+-	printf("pc  = ");
+-	xmon_print_symbol(fp->nip, " ", "\n");
+-	printf("lr  = ");
+-	xmon_print_symbol(fp->link, " ", "\n");
+-	printf("msr = %.16lx   cr  = %.8lx\n", fp->msr, fp->ccr);
+-	printf("ctr = %.16lx   xer = %.16lx   trap = %8lx\n",
+-	       fp->ctr, fp->xer, fp->trap);
+-}
+-
+-void cacheflush(void)
+-{
+-	int cmd;
+-	unsigned long nflush;
+-
+-	cmd = inchar();
+-	if (cmd != 'i')
+-		termch = cmd;
+-	scanhex((void *)&adrs);
+-	if (termch != '\n')
+-		termch = 0;
+-	nflush = 1;
+-	scanhex(&nflush);
+-	nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
+-	if (setjmp(bus_error_jmp) == 0) {
+-		catch_memory_errors = 1;
+-		sync();
+-
+-		if (cmd != 'i') {
+-			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
+-				cflush((void *) adrs);
+-		} else {
+-			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
+-				cinval((void *) adrs);
+-		}
+-		sync();
+-		/* wait a little while to see if we get a machine check */
+-		__delay(200);
+-	}
+-	catch_memory_errors = 0;
+-}
+-
+-unsigned long
+-read_spr(int n)
+-{
+-	unsigned int instrs[2];
+-	unsigned long (*code)(void);
+-	unsigned long opd[3];
+-	unsigned long ret = -1UL;
+-
+-	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
+-	instrs[1] = 0x4e800020;
+-	opd[0] = (unsigned long)instrs;
+-	opd[1] = 0;
+-	opd[2] = 0;
+-	store_inst(instrs);
+-	store_inst(instrs+1);
+-	code = (unsigned long (*)(void)) opd;
+-
+-	if (setjmp(bus_error_jmp) == 0) {
+-		catch_memory_errors = 1;
+-		sync();
+-
+-		ret = code();
+-
+-		sync();
+-		/* wait a little while to see if we get a machine check */
+-		__delay(200);
+-		n = size;
+-	}
+-
+-	return ret;
+-}
+-
+-void
+-write_spr(int n, unsigned long val)
+-{
+-	unsigned int instrs[2];
+-	unsigned long (*code)(unsigned long);
+-	unsigned long opd[3];
+-
+-	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
+-	instrs[1] = 0x4e800020;
+-	opd[0] = (unsigned long)instrs;
+-	opd[1] = 0;
+-	opd[2] = 0;
+-	store_inst(instrs);
+-	store_inst(instrs+1);
+-	code = (unsigned long (*)(unsigned long)) opd;
+-
+-	if (setjmp(bus_error_jmp) == 0) {
+-		catch_memory_errors = 1;
+-		sync();
+-
+-		code(val);
+-
+-		sync();
+-		/* wait a little while to see if we get a machine check */
+-		__delay(200);
+-		n = size;
+-	}
+-}
+-
+-static unsigned long regno;
+-extern char exc_prolog;
+-extern char dec_exc;
+-
+-void
+-super_regs(void)
+-{
+-	int cmd;
+-	unsigned long val;
+-#ifdef CONFIG_PPC_ISERIES
+-	struct paca_struct *ptrPaca = NULL;
+-	struct lppaca *ptrLpPaca = NULL;
+-	struct ItLpRegSave *ptrLpRegSave = NULL;
+-#endif
+-
+-	cmd = skipbl();
+-	if (cmd == '\n') {
+-	        unsigned long sp, toc;
+-		asm("mr %0,1" : "=r" (sp) :);
+-		asm("mr %0,2" : "=r" (toc) :);
+-
+-		printf("msr  = %.16lx  sprg0= %.16lx\n", get_msr(), get_sprg0());
+-		printf("pvr  = %.16lx  sprg1= %.16lx\n", get_pvr(), get_sprg1()); 
+-		printf("dec  = %.16lx  sprg2= %.16lx\n", get_dec(), get_sprg2());
+-		printf("sp   = %.16lx  sprg3= %.16lx\n", sp, get_sprg3());
+-		printf("toc  = %.16lx  dar  = %.16lx\n", toc, get_dar());
+-		printf("srr0 = %.16lx  srr1 = %.16lx\n", get_srr0(), get_srr1());
+-#ifdef CONFIG_PPC_ISERIES
+-		// Dump out relevant Paca data areas.
+-		printf("Paca: \n");
+-		ptrPaca = get_paca();
+-    
+-		printf("  Local Processor Control Area (LpPaca): \n");
+-		ptrLpPaca = ptrPaca->lppaca_ptr;
+-		printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",
+-		       ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
+-		printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
+-		       ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
+-		printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
+-    
+-		printf("  Local Processor Register Save Area (LpRegSave): \n");
+-		ptrLpRegSave = ptrPaca->reg_save_ptr;
+-		printf("    Saved Sprg0=%.16lx  Saved Sprg1=%.16lx \n",
+-		       ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
+-		printf("    Saved Sprg2=%.16lx  Saved Sprg3=%.16lx \n",
+-		       ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
+-		printf("    Saved Msr  =%.16lx  Saved Nia  =%.16lx \n",
+-		       ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
+-#endif
+-
+-		return;
+-	}
+-
+-	scanhex(&regno);
+-	switch (cmd) {
+-	case 'w':
+-		val = read_spr(regno);
+-		scanhex(&val);
+-		write_spr(regno, val);
+-		/* fall through */
+-	case 'r':
+-		printf("spr %lx = %lx\n", regno, read_spr(regno));
+-		break;
+-	case 'm':
+-		val = get_msr();
+-		scanhex(&val);
+-		set_msrd(val);
+-		break;
+-	}
+-	scannl();
+-}
+-
+-/*
+- * Stuff for reading and writing memory safely
+- */
+-int
+-mread(unsigned long adrs, void *buf, int size)
+-{
+-	volatile int n;
+-	char *p, *q;
+-
+-	n = 0;
+-	if (setjmp(bus_error_jmp) == 0) {
+-		catch_memory_errors = 1;
+-		sync();
+-		p = (char *)adrs;
+-		q = (char *)buf;
+-		switch (size) {
+-		case 2:
+-			*(short *)q = *(short *)p;
+-			break;
+-		case 4:
+-			*(int *)q = *(int *)p;
+-			break;
+-		case 8:
+-			*(long *)q = *(long *)p;
+-			break;
+-		default:
+-			for( ; n < size; ++n) {
+-				*q++ = *p++;
+-				sync();
+-			}
+-		}
+-		sync();
+-		/* wait a little while to see if we get a machine check */
+-		__delay(200);
+-		n = size;
+-	}
+-	catch_memory_errors = 0;
+-	return n;
+-}
+-
+-int
+-mwrite(unsigned long adrs, void *buf, int size)
+-{
+-	volatile int n;
+-	char *p, *q;
+-
+-	n = 0;
+-	if (setjmp(bus_error_jmp) == 0) {
+-		catch_memory_errors = 1;
+-		sync();
+-		p = (char *) adrs;
+-		q = (char *) buf;
+-		switch (size) {
+-		case 2:
+-			*(short *)p = *(short *)q;
+-			break;
+-		case 4:
+-			*(int *)p = *(int *)q;
+-			break;
+-		case 8:
+-			*(long *)p = *(long *)q;
+-			break;
+-		default:
+-			for ( ; n < size; ++n) {
+-				*p++ = *q++;
+-				sync();
+-			}
+-		}
+-		sync();
+-		/* wait a little while to see if we get a machine check */
+-		__delay(200);
+-		n = size;
+-	} else {
+-		printf("*** Error writing address %x\n", adrs + n);
+-	}
+-	catch_memory_errors = 0;
+-	return n;
+-}
+-
+-static int fault_type;
+-static char *fault_chars[] = { "--", "**", "##" };
+-
+-static int
+-handle_fault(struct pt_regs *regs)
+-{
+-	switch (TRAP(regs)) {
+-	case 0x200:
+-		fault_type = 0;
+-		break;
+-	case 0x300:
+-	case 0x380:
+-		fault_type = 1;
+-		break;
+-	default:
+-		fault_type = 2;
+-	}
+-
+-	longjmp(bus_error_jmp, 1);
+-
+-	return 0;
+-}
+-
+-#define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
+-
+-void
+-byterev(unsigned char *val, int size)
+-{
+-	int t;
+-	
+-	switch (size) {
+-	case 2:
+-		SWAP(val[0], val[1], t);
+-		break;
+-	case 4:
+-		SWAP(val[0], val[3], t);
+-		SWAP(val[1], val[2], t);
+-		break;
+-	case 8: /* is there really any use for this? */
+-		SWAP(val[0], val[7], t);
+-		SWAP(val[1], val[6], t);
+-		SWAP(val[2], val[5], t);
+-		SWAP(val[3], val[4], t);
+-		break;
+-	}
+-}
+-
+-static int brev;
+-static int mnoread;
+-
+-static char *memex_help_string = 
+-    "Memory examine command usage:\n"
+-    "m [addr] [flags] examine/change memory\n"
+-    "  addr is optional.  will start where left off.\n"
+-    "  flags may include chars from this set:\n"
+-    "    b   modify by bytes (default)\n"
+-    "    w   modify by words (2 byte)\n"
+-    "    l   modify by longs (4 byte)\n"
+-    "    d   modify by doubleword (8 byte)\n"
+-    "    r   toggle reverse byte order mode\n"
+-    "    n   do not read memory (for i/o spaces)\n"
+-    "    .   ok to read (default)\n"
+-    "NOTE: flags are saved as defaults\n"
+-    "";
+-
+-static char *memex_subcmd_help_string = 
+-    "Memory examine subcommands:\n"
+-    "  hexval   write this val to current location\n"
+-    "  'string' write chars from string to this location\n"
+-    "  '        increment address\n"
+-    "  ^        decrement address\n"
+-    "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
+-    "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
+-    "  `        clear no-read flag\n"
+-    "  ;        stay at this addr\n"
+-    "  v        change to byte mode\n"
+-    "  w        change to word (2 byte) mode\n"
+-    "  l        change to long (4 byte) mode\n"
+-    "  u        change to doubleword (8 byte) mode\n"
+-    "  m addr   change current addr\n"
+-    "  n        toggle no-read flag\n"
+-    "  r        toggle byte reverse flag\n"
+-    "  < count  back up count bytes\n"
+-    "  > count  skip forward count bytes\n"
+-    "  x        exit this mode\n"
+-    "";
+-
+-void
+-memex(void)
+-{
+-	int cmd, inc, i, nslash;
+-	unsigned long n;
+-	unsigned char val[16];
+-
+-	scanhex((void *)&adrs);
+-	cmd = skipbl();
+-	if (cmd == '?') {
+-		printf(memex_help_string);
+-		return;
+-	} else {
+-		termch = cmd;
+-	}
+-	last_cmd = "m\n";
+-	while ((cmd = skipbl()) != '\n') {
+-		switch( cmd ){
+-		case 'b':	size = 1;	break;
+-		case 'w':	size = 2;	break;
+-		case 'l':	size = 4;	break;
+-		case 'd':	size = 8;	break;
+-		case 'r': 	brev = !brev;	break;
+-		case 'n':	mnoread = 1;	break;
+-		case '.':	mnoread = 0;	break;
+-		}
+-	}
+-	if( size <= 0 )
+-		size = 1;
+-	else if( size > 8 )
+-		size = 8;
+-	for(;;){
+-		if (!mnoread)
+-			n = mread(adrs, val, size);
+-		printf("%.16x%c", adrs, brev? 'r': ' ');
+-		if (!mnoread) {
+-			if (brev)
+-				byterev(val, size);
+-			putchar(' ');
+-			for (i = 0; i < n; ++i)
+-				printf("%.2x", val[i]);
+-			for (; i < size; ++i)
+-				printf("%s", fault_chars[fault_type]);
+-		}
+-		putchar(' ');
+-		inc = size;
+-		nslash = 0;
+-		for(;;){
+-			if( scanhex(&n) ){
+-				for (i = 0; i < size; ++i)
+-					val[i] = n >> (i * 8);
+-				if (!brev)
+-					byterev(val, size);
+-				mwrite(adrs, val, size);
+-				inc = size;
+-			}
+-			cmd = skipbl();
+-			if (cmd == '\n')
+-				break;
+-			inc = 0;
+-			switch (cmd) {
+-			case '\'':
+-				for(;;){
+-					n = inchar();
+-					if( n == '\\' )
+-						n = bsesc();
+-					else if( n == '\'' )
+-						break;
+-					for (i = 0; i < size; ++i)
+-						val[i] = n >> (i * 8);
+-					if (!brev)
+-						byterev(val, size);
+-					mwrite(adrs, val, size);
+-					adrs += size;
+-				}
+-				adrs -= size;
+-				inc = size;
+-				break;
+-			case ',':
+-				adrs += size;
+-				break;
+-			case '.':
+-				mnoread = 0;
+-				break;
+-			case ';':
+-				break;
+-			case 'x':
+-			case EOF:
+-				scannl();
+-				return;
+-			case 'b':
+-			case 'v':
+-				size = 1;
+-				break;
+-			case 'w':
+-				size = 2;
+-				break;
+-			case 'l':
+-				size = 4;
+-				break;
+-			case 'u':
+-				size = 8;
+-				break;
+-			case '^':
+-				adrs -= size;
+-				break;
+-				break;
+-			case '/':
+-				if (nslash > 0)
+-					adrs -= 1 << nslash;
+-				else
+-					nslash = 0;
+-				nslash += 4;
+-				adrs += 1 << nslash;
+-				break;
+-			case '\\':
+-				if (nslash < 0)
+-					adrs += 1 << -nslash;
+-				else
+-					nslash = 0;
+-				nslash -= 4;
+-				adrs -= 1 << -nslash;
+-				break;
+-			case 'm':
+-				scanhex((void *)&adrs);
+-				break;
+-			case 'n':
+-				mnoread = 1;
+-				break;
+-			case 'r':
+-				brev = !brev;
+-				break;
+-			case '<':
+-				n = size;
+-				scanhex(&n);
+-				adrs -= n;
+-				break;
+-			case '>':
+-				n = size;
+-				scanhex(&n);
+-				adrs += n;
+-				break;
+-			case '?':
+-				printf(memex_subcmd_help_string);
+-				break;
+-			}
+-		}
+-		adrs += inc;
+-	}
+-}
+-
+-int
+-bsesc(void)
+-{
+-	int c;
+-
+-	c = inchar();
+-	switch( c ){
+-	case 'n':	c = '\n';	break;
+-	case 'r':	c = '\r';	break;
+-	case 'b':	c = '\b';	break;
+-	case 't':	c = '\t';	break;
+-	}
+-	return c;
+-}
+-
+-#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
+-			 || ('a' <= (c) && (c) <= 'f') \
+-			 || ('A' <= (c) && (c) <= 'F'))
+-void
+-dump(void)
+-{
+-	int c;
+-
+-	c = inchar();
+-	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
+-		termch = c;
+-	scanhex((void *)&adrs);
+-	if (termch != '\n')
+-		termch = 0;
+-	if (c == 'i') {
+-		scanhex(&nidump);
+-		if (nidump == 0)
+-			nidump = 16;
+-		else if (nidump > MAX_DUMP)
+-			nidump = MAX_DUMP;
+-		adrs += ppc_inst_dump(adrs, nidump, 1);
+-		last_cmd = "di\n";
+-	} else {
+-		scanhex(&ndump);
+-		if (ndump == 0)
+-			ndump = 64;
+-		else if (ndump > MAX_DUMP)
+-			ndump = MAX_DUMP;
+-		prdump(adrs, ndump);
+-		adrs += ndump;
+-		last_cmd = "d\n";
+-	}
+-}
+-
+-void
+-prdump(unsigned long adrs, long ndump)
+-{
+-	long n, m, c, r, nr;
+-	unsigned char temp[16];
+-
+-	for (n = ndump; n > 0;) {
+-		printf("%.16lx", adrs);
+-		putchar(' ');
+-		r = n < 16? n: 16;
+-		nr = mread(adrs, temp, r);
+-		adrs += nr;
+-		for (m = 0; m < r; ++m) {
+-		        if ((m & 7) == 0 && m > 0)
+-			    putchar(' ');
+-			if (m < nr)
+-				printf("%.2x", temp[m]);
+-			else
+-				printf("%s", fault_chars[fault_type]);
+-		}
+-		if (m <= 8)
+-			printf(" ");
+-		for (; m < 16; ++m)
+-			printf("  ");
+-		printf("  |");
+-		for (m = 0; m < r; ++m) {
+-			if (m < nr) {
+-				c = temp[m];
+-				putchar(' ' <= c && c <= '~'? c: '.');
+-			} else
+-				putchar(' ');
+-		}
+-		n -= r;
+-		for (; m < 16; ++m)
+-			putchar(' ');
+-		printf("|\n");
+-		if (nr < r)
+-			break;
+-	}
+-}
+-
+-int
+-ppc_inst_dump(unsigned long adr, long count, int praddr)
+-{
+-	int nr, dotted;
+-	unsigned long first_adr;
+-	unsigned long inst, last_inst = 0;
+-	unsigned char val[4];
+-
+-	dotted = 0;
+-	for (first_adr = adr; count > 0; --count, adr += 4) {
+-		nr = mread(adr, val, 4);
+-		if (nr == 0) {
+-			if (praddr) {
+-				const char *x = fault_chars[fault_type];
+-				printf("%.16lx  %s%s%s%s\n", adr, x, x, x, x);
+-			}
+-			break;
+-		}
+-		inst = GETWORD(val);
+-		if (adr > first_adr && inst == last_inst) {
+-			if (!dotted) {
+-				printf(" ...\n");
+-				dotted = 1;
+-			}
+-			continue;
+-		}
+-		dotted = 0;
+-		last_inst = inst;
+-		if (praddr)
+-			printf("%.16lx  %.8x", adr, inst);
+-		printf("\t");
+-		print_insn_powerpc(inst, adr, 0);	/* always returns 4 */
+-		printf("\n");
+-	}
+-	return adr - first_adr;
+-}
+-
+-void
+-print_address(unsigned long addr)
+-{
+-	xmon_print_symbol(addr, "\t# ", "");
+-}
+-
+-
+-/*
+- * Memory operations - move, set, print differences
+- */
+-static unsigned long mdest;		/* destination address */
+-static unsigned long msrc;		/* source address */
+-static unsigned long mval;		/* byte value to set memory to */
+-static unsigned long mcount;		/* # bytes to affect */
+-static unsigned long mdiffs;		/* max # differences to print */
+-
+-void
+-memops(int cmd)
+-{
+-	scanhex((void *)&mdest);
+-	if( termch != '\n' )
+-		termch = 0;
+-	scanhex((void *)(cmd == 's'? &mval: &msrc));
+-	if( termch != '\n' )
+-		termch = 0;
+-	scanhex((void *)&mcount);
+-	switch( cmd ){
+-	case 'm':
+-		memmove((void *)mdest, (void *)msrc, mcount);
+-		break;
+-	case 's':
+-		memset((void *)mdest, mval, mcount);
+-		break;
+-	case 'd':
+-		if( termch != '\n' )
+-			termch = 0;
+-		scanhex((void *)&mdiffs);
+-		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
+-		break;
+-	}
+-}
+-
+-void
+-memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
+-{
+-	unsigned n, prt;
+-
+-	prt = 0;
+-	for( n = nb; n > 0; --n )
+-		if( *p1++ != *p2++ )
+-			if( ++prt <= maxpr )
+-				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
+-					p1[-1], p2 - 1, p2[-1]);
+-	if( prt > maxpr )
+-		printf("Total of %d differences\n", prt);
+-}
+-
+-static unsigned mend;
+-static unsigned mask;
+-
+-void
+-memlocate(void)
+-{
+-	unsigned a, n;
+-	unsigned char val[4];
+-
+-	last_cmd = "ml";
+-	scanhex((void *)&mdest);
+-	if (termch != '\n') {
+-		termch = 0;
+-		scanhex((void *)&mend);
+-		if (termch != '\n') {
+-			termch = 0;
+-			scanhex((void *)&mval);
+-			mask = ~0;
+-			if (termch != '\n') termch = 0;
+-			scanhex((void *)&mask);
+-		}
+-	}
+-	n = 0;
+-	for (a = mdest; a < mend; a += 4) {
+-		if (mread(a, val, 4) == 4
+-			&& ((GETWORD(val) ^ mval) & mask) == 0) {
+-			printf("%.16x:  %.16x\n", a, GETWORD(val));
+-			if (++n >= 10)
+-				break;
+-		}
+-	}
+-}
+-
+-static unsigned long mskip = 0x1000;
+-static unsigned long mlim = 0xffffffff;
+-
+-void
+-memzcan(void)
+-{
+-	unsigned char v;
+-	unsigned a;
+-	int ok, ook;
+-
+-	scanhex(&mdest);
+-	if (termch != '\n') termch = 0;
+-	scanhex(&mskip);
+-	if (termch != '\n') termch = 0;
+-	scanhex(&mlim);
+-	ook = 0;
+-	for (a = mdest; a < mlim; a += mskip) {
+-		ok = mread(a, &v, 1);
+-		if (ok && !ook) {
+-			printf("%.8x .. ", a);
+-			fflush(stdout);
+-		} else if (!ok && ook)
+-			printf("%.8x\n", a - mskip);
+-		ook = ok;
+-		if (a + mskip < a)
+-			break;
+-	}
+-	if (ook)
+-		printf("%.8x\n", a - mskip);
+-}
+-
+-/* Input scanning routines */
+-int
+-skipbl(void)
+-{
+-	int c;
+-
+-	if( termch != 0 ){
+-		c = termch;
+-		termch = 0;
+-	} else
+-		c = inchar();
+-	while( c == ' ' || c == '\t' )
+-		c = inchar();
+-	return c;
+-}
+-
+-#define N_PTREGS	44
+-static char *regnames[N_PTREGS] = {
+-	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+-	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+-	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+-	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+-	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
+-	"trap", "dar", "dsisr", "res"
+-};
+-
+-int
+-scanhex(unsigned long *vp)
+-{
+-	int c, d;
+-	unsigned long v;
+-
+-	c = skipbl();
+-	if (c == '%') {
+-		/* parse register name */
+-		char regname[8];
+-		int i;
+-
+-		for (i = 0; i < sizeof(regname) - 1; ++i) {
+-			c = inchar();
+-			if (!isalnum(c)) {
+-				termch = c;
+-				break;
+-			}
+-			regname[i] = c;
+-		}
+-		regname[i] = 0;
+-		for (i = 0; i < N_PTREGS; ++i) {
+-			if (strcmp(regnames[i], regname) == 0) {
+-				if (xmon_regs == NULL) {
+-					printf("regs not available\n");
+-					return 0;
+-				}
+-				*vp = ((unsigned long *)xmon_regs)[i];
+-				return 1;
+-			}
+-		}
+-		printf("invalid register name '%%%s'\n", regname);
+-		return 0;
+-	}
+-
+-	/* skip leading "0x" if any */
+-
+-	if (c == '0') {
+-		c = inchar();
+-		if (c == 'x') {
+-			c = inchar();
+-		} else {
+-			d = hexdigit(c);
+-			if (d == EOF) {
+-				termch = c;
+-				*vp = 0;
+-				return 1;
+-			}
+-		}
+-	} else if (c == '$') {
+-		int i;
+-		for (i=0; i<63; i++) {
+-			c = inchar();
+-			if (isspace(c)) {
+-				termch = c;
+-				break;
+-			}
+-			tmpstr[i] = c;
+-		}
+-		tmpstr[i++] = 0;
+-		*vp = 0;
+-		if (setjmp(bus_error_jmp) == 0) {
+-			catch_memory_errors = 1;
+-			sync();
+-			*vp = kallsyms_lookup_name(tmpstr);
+-			sync();
+-		}
+-		catch_memory_errors = 0;
+-		if (!(*vp)) {
+-			printf("unknown symbol '%s'\n", tmpstr);
+-			return 0;
+-		}
+-		return 1;
+-	}
+-
+-	d = hexdigit(c);
+-	if (d == EOF) {
+-		termch = c;
+-		return 0;
+-	}
+-	v = 0;
+-	do {
+-		v = (v << 4) + d;
+-		c = inchar();
+-		d = hexdigit(c);
+-	} while (d != EOF);
+-	termch = c;
+-	*vp = v;
+-	return 1;
+-}
+-
+-void
+-scannl(void)
+-{
+-	int c;
+-
+-	c = termch;
+-	termch = 0;
+-	while( c != '\n' )
+-		c = inchar();
+-}
+-
+-int
+-hexdigit(int c)
+-{
+-	if( '0' <= c && c <= '9' )
+-		return c - '0';
+-	if( 'A' <= c && c <= 'F' )
+-		return c - ('A' - 10);
+-	if( 'a' <= c && c <= 'f' )
+-		return c - ('a' - 10);
+-	return EOF;
+-}
+-
+-void
+-getstring(char *s, int size)
+-{
+-	int c;
+-
+-	c = skipbl();
+-	do {
+-		if( size > 1 ){
+-			*s++ = c;
+-			--size;
+-		}
+-		c = inchar();
+-	} while( c != ' ' && c != '\t' && c != '\n' );
+-	termch = c;
+-	*s = 0;
+-}
+-
+-static char line[256];
+-static char *lineptr;
+-
+-void
+-flush_input(void)
+-{
+-	lineptr = NULL;
+-}
+-
+-int
+-inchar(void)
+-{
+-	if (lineptr == NULL || *lineptr == 0) {
+-		if (fgets(line, sizeof(line), stdin) == NULL) {
+-			lineptr = NULL;
+-			return EOF;
+-		}
+-		lineptr = line;
+-	}
+-	return *lineptr++;
+-}
+-
+-void
+-take_input(char *str)
+-{
+-	lineptr = str;
+-}
+-
+-
+-static void
+-symbol_lookup(void)
+-{
+-	int type = inchar();
+-	unsigned long addr;
+-	static char tmp[64];
+-
+-	switch (type) {
+-	case 'a':
+-		if (scanhex(&addr))
+-			xmon_print_symbol(addr, ": ", "\n");
+-		termch = 0;
+-		break;
+-	case 's':
+-		getstring(tmp, 64);
+-		if (setjmp(bus_error_jmp) == 0) {
+-			catch_memory_errors = 1;
+-			sync();
+-			addr = kallsyms_lookup_name(tmp);
+-			if (addr)
+-				printf("%s: %lx\n", tmp, addr);
+-			else
+-				printf("Symbol '%s' not found.\n", tmp);
+-			sync();
+-		}
+-		catch_memory_errors = 0;
+-		termch = 0;
+-		break;
+-	}
+-}
+-
+-
+-/* Print an address in numeric and symbolic form (if possible) */
+-static void xmon_print_symbol(unsigned long address, const char *mid,
+-			      const char *after)
+-{
+-	char *modname;
+-	const char *name = NULL;
+-	unsigned long offset, size;
+-
+-	printf("%.16lx", address);
+-	if (setjmp(bus_error_jmp) == 0) {
+-		catch_memory_errors = 1;
+-		sync();
+-		name = kallsyms_lookup(address, &size, &offset, &modname,
+-				       tmpstr);
+-		sync();
+-		/* wait a little while to see if we get a machine check */
+-		__delay(200);
+-	}
+-
+-	catch_memory_errors = 0;
+-
+-	if (name) {
+-		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
+-		if (modname)
+-			printf(" [%s]", modname);
+-	}
+-	printf("%s", after);
+-}
+-
+-static void debug_trace(void)
+-{
+-        unsigned long val, cmd, on;
+-
+-	cmd = skipbl();
+-	if (cmd == '\n') {
+-		/* show current state */
+-		unsigned long i;
+-		printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
+-		for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
+-			on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
+-			printf("%02x %s %12s   ", i, on ? "on " : "off",  trace_names[i] ? trace_names[i] : "");
+-			if (((i+1) % 3) == 0)
+-				printf("\n");
+-		}
+-		printf("\n");
+-		return;
+-	}
+-	while (cmd != '\n') {
+-		on = 1;	/* default if no sign given */
+-		while (cmd == '+' || cmd == '-') {
+-			on = (cmd == '+');
+-			cmd = inchar();
+-			if (cmd == ' ' || cmd == '\n') {  /* Turn on or off based on + or - */
+-				ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
+-				printf("Setting all values to %s...\n", on ? "on" : "off");
+-				if (cmd == '\n') return;
+-				else cmd = skipbl(); 
+-			}
+-			else
+-				termch = cmd;
+-		}
+-		termch = cmd;	/* not +/- ... let scanhex see it */
+-		scanhex((void *)&val);
+-		if (val >= 64) {
+-			printf("Value %x out of range:\n", val);
+-			return;
+-		}
+-		if (on) {
+-			ppc64_debug_switch |= PPCDBG_BITVAL(val);
+-			printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
+-		} else {
+-			ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
+-			printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
+-		}
+-		cmd = skipbl();
+-	}
+-}
+-
+-static void dump_slb(void)
+-{
+-	int i;
+-	unsigned long tmp;
+-
+-	printf("SLB contents of cpu %x\n", smp_processor_id());
+-
+-	for (i = 0; i < SLB_NUM_ENTRIES; i++) {
+-		asm volatile("slbmfee  %0,%1" : "=r" (tmp) : "r" (i));
+-		printf("%02d %016lx ", i, tmp);
+-
+-		asm volatile("slbmfev  %0,%1" : "=r" (tmp) : "r" (i));
+-		printf("%016lx\n", tmp);
+-	}
+-}
+-
+-static void dump_stab(void)
+-{
+-	int i;
+-	unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
+-
+-	printf("Segment table contents of cpu %x\n", smp_processor_id());
+-
+-	for (i = 0; i < PAGE_SIZE/16; i++) {
+-		unsigned long a, b;
+-
+-		a = *tmp++;
+-		b = *tmp++;
+-
+-		if (a || b) {
+-			printf("%03d %016lx ", i, a);
+-			printf("%016lx\n", b);
+-		}
+-	}
+-}
+-
+-void xmon_init(int enable)
+-{
+-	if (enable) {
+-		__debugger = xmon;
+-		__debugger_ipi = xmon_ipi;
+-		__debugger_bpt = xmon_bpt;
+-		__debugger_sstep = xmon_sstep;
+-		__debugger_iabr_match = xmon_iabr_match;
+-		__debugger_dabr_match = xmon_dabr_match;
+-		__debugger_fault_handler = xmon_fault_handler;
+-	} else {
+-		__debugger = NULL;
+-		__debugger_ipi = NULL;
+-		__debugger_bpt = NULL;
+-		__debugger_sstep = NULL;
+-		__debugger_iabr_match = NULL;
+-		__debugger_dabr_match = NULL;
+-		__debugger_fault_handler = NULL;
+-	}
+-}
+-
+-void dump_segments(void)
+-{
+-	if (cpu_has_feature(CPU_FTR_SLB))
+-		dump_slb();
+-	else
+-		dump_stab();
+-}
+diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c
+--- a/arch/s390/kernel/compat_ioctl.c
++++ b/arch/s390/kernel/compat_ioctl.c
+@@ -18,6 +18,8 @@
+ #include <asm/dasd.h>
+ #include <asm/cmb.h>
+ #include <asm/tape390.h>
++#include <asm/ccwdev.h>
++#include "../../../drivers/s390/char/raw3270.h"
+ 
+ static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
+ 				unsigned long arg, struct file *f)
+@@ -62,6 +64,13 @@ COMPATIBLE_IOCTL(BIODASDCMFENABLE)
+ COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
+ COMPATIBLE_IOCTL(BIODASDREADALLCMB)
+ 
++COMPATIBLE_IOCTL(TUBICMD)
++COMPATIBLE_IOCTL(TUBOCMD)
++COMPATIBLE_IOCTL(TUBGETI)
++COMPATIBLE_IOCTL(TUBGETO)
++COMPATIBLE_IOCTL(TUBSETMOD)
++COMPATIBLE_IOCTL(TUBGETMOD)
++
+ COMPATIBLE_IOCTL(TAPE390_DISPLAY)
+ 
+ /* s390 doesn't need handlers here */
+diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
+--- a/arch/s390/kernel/head.S
++++ b/arch/s390/kernel/head.S
+@@ -485,7 +485,9 @@ start:
+ #
+         .org  0x10000
+ startup:basr  %r13,0                     # get base
+-.LPG1:  lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
++.LPG1:	l     %r1, .Lget_ipl_device_addr-.LPG1(%r13)
++	basr  %r14, %r1
++	lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
+ 	la    %r12,_pstart-.LPG1(%r13)   # pointer to parameter area
+ 					 # move IPL device to lowcore
+         mvc   __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
+@@ -560,6 +562,9 @@ startup:basr  %r13,0                    
+ 	mr    %r2,%r1			# mem size in bytes in %r3
+ 	b     .Lfchunk-.LPG1(%r13)
+ 
++	.align 4
++.Lget_ipl_device_addr:
++	.long .Lget_ipl_device
+ .Lpmask:
+ 	.byte 0
+ .align 8
+@@ -755,6 +760,63 @@ _pstart:	
+ 	.global _pend
+ _pend:	
+ 
++.Lget_ipl_device:
++	basr  %r12,0
++.LPG2:	l     %r1,0xb8			# get sid
++	sll   %r1,15			# test if subchannel is enabled
++	srl   %r1,31
++	ltr   %r1,%r1
++	bz    0(%r14)			# subchannel disabled
++	l     %r1,0xb8
++	la    %r5,.Lipl_schib-.LPG2(%r12)
++	stsch 0(%r5)		        # get schib of subchannel
++	bnz   0(%r14)			# schib not available
++	tm    5(%r5),0x01		# devno valid?
++	bno   0(%r14)
++	la    %r6,ipl_parameter_flags-.LPG2(%r12)
++	oi    3(%r6),0x01		# set flag
++	la    %r2,ipl_devno-.LPG2(%r12)
++	mvc   0(2,%r2),6(%r5)		# store devno
++	tm    4(%r5),0x80		# qdio capable device?
++	bno   0(%r14)
++	oi    3(%r6),0x02		# set flag
++
++	# copy ipl parameters
++
++	lhi   %r0,4096
++	l     %r2,20(%r0)		# get address of parameter list
++	lhi   %r3,IPL_PARMBLOCK_ORIGIN
++	st    %r3,20(%r0)
++	lhi   %r4,1
++	cr    %r2,%r3			# start parameters < destination ?
++	jl    0f
++	lhi   %r1,1			# copy direction is upwards
++	j     1f
++0:	lhi   %r1,-1			# copy direction is downwards
++	ar    %r2,%r0
++	ar    %r3,%r0
++	ar    %r2,%r1
++	ar    %r3,%r1
++1:	mvc   0(1,%r3),0(%r2)		# finally copy ipl parameters
++	ar    %r3,%r1
++	ar    %r2,%r1
++	sr    %r0,%r4
++	jne   1b
++	b     0(%r14)
++
++	.align 4
++.Lipl_schib:
++	.rept 13
++	.long 0
++	.endr
++
++	.globl ipl_parameter_flags
++ipl_parameter_flags:
++	.long 0
++	.globl ipl_devno
++ipl_devno:
++	.word 0
++
+ #ifdef CONFIG_SHARED_KERNEL
+ 	.org   0x100000
+ #endif
+@@ -764,11 +826,11 @@ _pend:	
+ #
+         .globl _stext
+ _stext:	basr  %r13,0                    # get base
+-.LPG2:
++.LPG3:
+ #
+ # Setup stack
+ #
+-        l     %r15,.Linittu-.LPG2(%r13)
++        l     %r15,.Linittu-.LPG3(%r13)
+ 	mvc   __LC_CURRENT(4),__TI_task(%r15)
+         ahi   %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
+         st    %r15,__LC_KERNEL_STACK    # set end of kernel stack
+@@ -782,8 +844,8 @@ _stext:	basr  %r13,0                    
+         lctl   %c0,%c15,0(%r15)
+ 
+ #
+-        lam    0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess
+-        l      %r14,.Lstart-.LPG2(%r13)
++        lam    0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
++        l      %r14,.Lstart-.LPG3(%r13)
+         basr   %r14,%r14                # call start_kernel
+ #
+ # We returned from start_kernel ?!? PANIK
+diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
+--- a/arch/s390/kernel/head64.S
++++ b/arch/s390/kernel/head64.S
+@@ -484,6 +484,8 @@ start:
+ startup:basr  %r13,0                     # get base
+ .LPG1:  sll   %r13,1                     # remove high order bit
+         srl   %r13,1
++	l     %r1,.Lget_ipl_device_addr-.LPG1(%r13)
++	basr  %r14,%r1
+         lhi   %r1,1                      # mode 1 = esame
+         slr   %r0,%r0                    # set cpuid to zero
+         sigp  %r1,%r0,0x12               # switch to esame mode
+@@ -556,6 +558,9 @@ startup:basr  %r13,0                    
+ 	mlgr  %r2,%r1			# mem size in bytes in %r3
+ 	b     .Lfchunk-.LPG1(%r13)
+ 
++	.align 4
++.Lget_ipl_device_addr:
++	.long .Lget_ipl_device
+ .Lpmask:
+ 	.byte 0
+ 	.align 8
+@@ -746,6 +751,63 @@ _pstart:
+ 	.global _pend
+ _pend:	
+ 
++.Lget_ipl_device:
++	basr  %r12,0
++.LPG2:	l     %r1,0xb8			# get sid
++	sll   %r1,15			# test if subchannel is enabled
++	srl   %r1,31
++	ltr   %r1,%r1
++	bz    0(%r14)			# subchannel disabled
++	l     %r1,0xb8
++	la    %r5,.Lipl_schib-.LPG2(%r12)
++	stsch 0(%r5)		        # get schib of subchannel
++	bnz   0(%r14)			# schib not available
++	tm    5(%r5),0x01		# devno valid?
++	bno   0(%r14)
++	la    %r6,ipl_parameter_flags-.LPG2(%r12)
++	oi    3(%r6),0x01		# set flag
++	la    %r2,ipl_devno-.LPG2(%r12)
++	mvc   0(2,%r2),6(%r5)		# store devno
++	tm    4(%r5),0x80		# qdio capable device?
++	bno   0(%r14)
++	oi    3(%r6),0x02		# set flag
++
++	# copy ipl parameters
++
++	lhi   %r0,4096
++	l     %r2,20(%r0)		# get address of parameter list
++	lhi   %r3,IPL_PARMBLOCK_ORIGIN
++	st    %r3,20(%r0)
++	lhi   %r4,1
++	cr    %r2,%r3			# start parameters < destination ?
++	jl    0f
++	lhi   %r1,1			# copy direction is upwards
++	j     1f
++0:	lhi   %r1,-1			# copy direction is downwards
++	ar    %r2,%r0
++	ar    %r3,%r0
++	ar    %r2,%r1
++	ar    %r3,%r1
++1:	mvc   0(1,%r3),0(%r2)		# finally copy ipl parameters
++	ar    %r3,%r1
++	ar    %r2,%r1
++	sr    %r0,%r4
++	jne   1b
++	b     0(%r14)
++
++	.align 4
++.Lipl_schib:
++	.rept 13
++	.long 0
++	.endr
++
++	.globl ipl_parameter_flags
++ipl_parameter_flags:
++	.long 0
++	.globl ipl_devno
++ipl_devno:
++	.word 0
++
+ #ifdef CONFIG_SHARED_KERNEL
+ 	.org   0x100000
+ #endif
+@@ -755,7 +817,7 @@ _pend:	
+ #
+         .globl _stext
+ _stext:	basr  %r13,0                    # get base
+-.LPG2:
++.LPG3:
+ #
+ # Setup stack
+ #
+@@ -774,7 +836,7 @@ _stext:	basr  %r13,0                    
+         lctlg  %c0,%c15,0(%r15)
+ 
+ #
+-        lam    0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess
++        lam    0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
+         brasl  %r14,start_kernel        # go to C code
+ #
+ # We returned from start_kernel ?!? PANIK
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -36,6 +36,7 @@
+ #include <linux/console.h>
+ #include <linux/seq_file.h>
+ #include <linux/kernel_stat.h>
++#include <linux/device.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+@@ -685,3 +686,188 @@ struct seq_operations cpuinfo_op = {
+ 	.show	= show_cpuinfo,
+ };
+ 
++#define DEFINE_IPL_ATTR(_name, _format, _value)			\
++static ssize_t ipl_##_name##_show(struct subsystem *subsys,	\
++		char *page)					\
++{								\
++	return sprintf(page, _format, _value);			\
++}								\
++static struct subsys_attribute ipl_##_name##_attr =		\
++	__ATTR(_name, S_IRUGO, ipl_##_name##_show, NULL);
++
++DEFINE_IPL_ATTR(wwpn, "0x%016llx\n", (unsigned long long)
++		IPL_PARMBLOCK_START->fcp.wwpn);
++DEFINE_IPL_ATTR(lun, "0x%016llx\n", (unsigned long long)
++		IPL_PARMBLOCK_START->fcp.lun);
++DEFINE_IPL_ATTR(bootprog, "%lld\n", (unsigned long long)
++		IPL_PARMBLOCK_START->fcp.bootprog);
++DEFINE_IPL_ATTR(br_lba, "%lld\n", (unsigned long long)
++		IPL_PARMBLOCK_START->fcp.br_lba);
++
++enum ipl_type_type {
++	ipl_type_unknown,
++	ipl_type_ccw,
++	ipl_type_fcp,
++};
++
++static enum ipl_type_type
++get_ipl_type(void)
++{
++	struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
++
++	if (!IPL_DEVNO_VALID)
++		return ipl_type_unknown;
++	if (!IPL_PARMBLOCK_VALID)
++		return ipl_type_ccw;
++	if (ipl->hdr.header.version > IPL_MAX_SUPPORTED_VERSION)
++		return ipl_type_unknown;
++	if (ipl->fcp.pbt != IPL_TYPE_FCP)
++		return ipl_type_unknown;
++	return ipl_type_fcp;
++}
++
++static ssize_t
++ipl_type_show(struct subsystem *subsys, char *page)
++{
++	switch (get_ipl_type()) {
++	case ipl_type_ccw:
++		return sprintf(page, "ccw\n");
++	case ipl_type_fcp:
++		return sprintf(page, "fcp\n");
++	default:
++		return sprintf(page, "unknown\n");
++	}
++}
++
++static struct subsys_attribute ipl_type_attr = __ATTR_RO(ipl_type);
++
++static ssize_t
++ipl_device_show(struct subsystem *subsys, char *page)
++{
++	struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
++
++	switch (get_ipl_type()) {
++	case ipl_type_ccw:
++		return sprintf(page, "0.0.%04x\n", ipl_devno);
++	case ipl_type_fcp:
++		return sprintf(page, "0.0.%04x\n", ipl->fcp.devno);
++	default:
++		return 0;
++	}
++}
++
++static struct subsys_attribute ipl_device_attr =
++	__ATTR(device, S_IRUGO, ipl_device_show, NULL);
++
++static struct attribute *ipl_fcp_attrs[] = {
++	&ipl_type_attr.attr,
++	&ipl_device_attr.attr,
++	&ipl_wwpn_attr.attr,
++	&ipl_lun_attr.attr,
++	&ipl_bootprog_attr.attr,
++	&ipl_br_lba_attr.attr,
++	NULL,
++};
++
++static struct attribute_group ipl_fcp_attr_group = {
++	.attrs = ipl_fcp_attrs,
++};
++
++static struct attribute *ipl_ccw_attrs[] = {
++	&ipl_type_attr.attr,
++	&ipl_device_attr.attr,
++	NULL,
++};
++
++static struct attribute_group ipl_ccw_attr_group = {
++	.attrs = ipl_ccw_attrs,
++};
++
++static struct attribute *ipl_unknown_attrs[] = {
++	&ipl_type_attr.attr,
++	NULL,
++};
++
++static struct attribute_group ipl_unknown_attr_group = {
++	.attrs = ipl_unknown_attrs,
++};
++
++static ssize_t
++ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
++{
++	unsigned int size = IPL_PARMBLOCK_SIZE;
++
++	if (off > size)
++		return 0;
++	if (off + count > size)
++		count = size - off;
++
++	memcpy(buf, (void *) IPL_PARMBLOCK_START + off, count);
++	return count;
++}
++
++static struct bin_attribute ipl_parameter_attr = {
++	.attr = {
++		.name = "binary_parameter",
++		.mode = S_IRUGO,
++		.owner = THIS_MODULE,
++	},
++	.size = PAGE_SIZE,
++	.read = &ipl_parameter_read,
++};
++
++static ssize_t
++ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
++{
++	unsigned int size =  IPL_PARMBLOCK_START->fcp.scp_data_len;
++	void *scp_data = &IPL_PARMBLOCK_START->fcp.scp_data;
++
++	if (off > size)
++		return 0;
++	if (off + count > size)
++		count = size - off;
++
++	memcpy(buf, scp_data + off, count);
++	return count;
++}
++
++static struct bin_attribute ipl_scp_data_attr = {
++	.attr = {
++		.name = "scp_data",
++		.mode = S_IRUGO,
++		.owner = THIS_MODULE,
++	},
++	.size = PAGE_SIZE,
++	.read = &ipl_scp_data_read,
++};
++
++static decl_subsys(ipl, NULL, NULL);
++
++static int __init
++ipl_device_sysfs_register(void) {
++	int rc;
++
++	rc = firmware_register(&ipl_subsys);
++	if (rc)
++		return rc;
++
++	switch (get_ipl_type()) {
++	case ipl_type_ccw:
++		sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group);
++		break;
++	case ipl_type_fcp:
++		sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
++		sysfs_create_bin_file(&ipl_subsys.kset.kobj,
++				      &ipl_parameter_attr);
++		sysfs_create_bin_file(&ipl_subsys.kset.kobj,
++				      &ipl_scp_data_attr);
++		break;
++	default:
++		sysfs_create_group(&ipl_subsys.kset.kobj,
++				   &ipl_unknown_attr_group);
++		break;
++	}
++	return 0;
++}
++
++__initcall(ipl_device_sysfs_register);
+diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
+--- a/arch/s390/kernel/time.c
++++ b/arch/s390/kernel/time.c
+@@ -49,10 +49,6 @@
+ 
+ #define TICK_SIZE tick
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ static ext_int_info_t ext_int_info_cc;
+ static u64 init_timer_cc;
+ static u64 jiffies_timer_cc;
+diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
+--- a/arch/s390/kernel/vtime.c
++++ b/arch/s390/kernel/vtime.c
+@@ -24,7 +24,6 @@
+ #include <asm/s390_ext.h>
+ #include <asm/timer.h>
+ 
+-#define VTIMER_MAGIC (TIMER_MAGIC + 1)
+ static ext_int_info_t ext_int_info_timer;
+ DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
+ 
+@@ -277,20 +276,12 @@ static void do_cpu_timer_interrupt(struc
+ 
+ void init_virt_timer(struct vtimer_list *timer)
+ {
+-	timer->magic = VTIMER_MAGIC;
+ 	timer->function = NULL;
+ 	INIT_LIST_HEAD(&timer->entry);
+ 	spin_lock_init(&timer->lock);
+ }
+ EXPORT_SYMBOL(init_virt_timer);
+ 
+-static inline int check_vtimer(struct vtimer_list *timer)
+-{
+-	if (timer->magic != VTIMER_MAGIC)
+-		return -EINVAL;
+-	return 0;
+-}
+-
+ static inline int vtimer_pending(struct vtimer_list *timer)
+ {
+ 	return (!list_empty(&timer->entry));
+@@ -346,7 +337,7 @@ static void internal_add_vtimer(struct v
+ 
+ static inline int prepare_vtimer(struct vtimer_list *timer)
+ {
+-	if (check_vtimer(timer) || !timer->function) {
++	if (!timer->function) {
+ 		printk("add_virt_timer: uninitialized timer\n");
+ 		return -EINVAL;
+ 	}
+@@ -414,7 +405,7 @@ int mod_virt_timer(struct vtimer_list *t
+ 	unsigned long flags;
+ 	int cpu;
+ 
+-	if (check_vtimer(timer) || !timer->function) {
++	if (!timer->function) {
+ 		printk("mod_virt_timer: uninitialized timer\n");
+ 		return	-EINVAL;
+ 	}
+@@ -481,11 +472,6 @@ int del_virt_timer(struct vtimer_list *t
+ 	unsigned long flags;
+ 	struct vtimer_queue *vt_list;
+ 
+-	if (check_vtimer(timer)) {
+-		printk("del_virt_timer: timer not initialized\n");
+-		return -EINVAL;
+-	}
+-
+ 	/* check if timer is pending */
+ 	if (!vtimer_pending(timer))
+ 		return 0;
+diff --git a/arch/s390/mm/ioremap.c b/arch/s390/mm/ioremap.c
+--- a/arch/s390/mm/ioremap.c
++++ b/arch/s390/mm/ioremap.c
+@@ -58,7 +58,7 @@ static inline int remap_area_pmd(pmd_t *
+ 	if (address >= end)
+ 		BUG();
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+@@ -80,7 +80,6 @@ static int remap_area_pages(unsigned lon
+ 	flush_cache_all();
+ 	if (address >= end)
+ 		BUG();
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		pmd_t *pmd;
+ 		pmd = pmd_alloc(&init_mm, dir, address);
+@@ -94,7 +93,6 @@ static int remap_area_pages(unsigned lon
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_tlb_all();
+ 	return 0;
+ }
+diff --git a/arch/sh/boards/renesas/rts7751r2d/mach.c b/arch/sh/boards/renesas/rts7751r2d/mach.c
+--- a/arch/sh/boards/renesas/rts7751r2d/mach.c
++++ b/arch/sh/boards/renesas/rts7751r2d/mach.c
+@@ -23,7 +23,7 @@ extern void init_rts7751r2d_IRQ(void);
+ extern void *rts7751r2d_ioremap(unsigned long, unsigned long);
+ extern int rts7751r2d_irq_demux(int irq);
+ 
+-extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, int);
++extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
+ extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
+ 
+ /*
+diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c
+--- a/arch/sh/boards/superh/microdev/setup.c
++++ b/arch/sh/boards/superh/microdev/setup.c
+@@ -13,7 +13,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/ioport.h>
+ #include <asm/io.h>
+ #include <asm/mach/irq.h>
+diff --git a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c
+--- a/arch/sh/cchips/voyagergx/consistent.c
++++ b/arch/sh/cchips/voyagergx/consistent.c
+@@ -31,7 +31,7 @@ static LIST_HEAD(voya_alloc_list);
+ #define OHCI_SRAM_SIZE	0x10000
+ 
+ void *voyagergx_consistent_alloc(struct device *dev, size_t size,
+-				 dma_addr_t *handle, int flag)
++				 dma_addr_t *handle, gfp_t flag)
+ {
+ 	struct list_head *list = &voya_alloc_list;
+ 	struct voya_alloc_entry *entry;
+diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
+--- a/arch/sh/drivers/dma/dma-sysfs.c
++++ b/arch/sh/drivers/dma/dma-sysfs.c
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/sysdev.h>
+ #include <linux/module.h>
++#include <linux/string.h>
+ #include <asm/dma.h>
+ 
+ static struct sysdev_class dma_sysclass = {
+diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
+--- a/arch/sh/drivers/pci/dma-dreamcast.c
++++ b/arch/sh/drivers/pci/dma-dreamcast.c
+@@ -33,7 +33,7 @@
+ static int gapspci_dma_used = 0;
+ 
+ void *dreamcast_consistent_alloc(struct device *dev, size_t size,
+-				 dma_addr_t *dma_handle, int flag)
++				 dma_addr_t *dma_handle, gfp_t flag)
+ {
+ 	unsigned long buf;
+ 
+diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
+--- a/arch/sh/kernel/cpufreq.c
++++ b/arch/sh/kernel/cpufreq.c
+@@ -20,6 +20,7 @@
+ #include <linux/delay.h>
+ #include <linux/cpumask.h>
+ #include <linux/smp.h>
++#include <linux/sched.h>	/* set_cpus_allowed() */
+ 
+ #include <asm/processor.h>
+ #include <asm/watchdog.h>
+diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
+--- a/arch/sh/kernel/ptrace.c
++++ b/arch/sh/kernel/ptrace.c
+@@ -80,7 +80,7 @@ void ptrace_disable(struct task_struct *
+ 	/* nothing to do.. */
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	struct user * dummy = NULL;
+diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
+--- a/arch/sh/kernel/time.c
++++ b/arch/sh/kernel/time.c
+@@ -56,10 +56,6 @@ extern unsigned long wall_jiffies;
+ #define TICK_SIZE (tick_nsec / 1000)
+ DEFINE_SPINLOCK(tmu0_lock);
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ /* XXX: Can we initialize this in a routine somewhere?  Dreamcast doesn't want
+  * these routines anywhere... */
+ #ifdef CONFIG_SH_RTC
+diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
+--- a/arch/sh/mm/consistent.c
++++ b/arch/sh/mm/consistent.c
+@@ -11,7 +11,7 @@
+ #include <linux/dma-mapping.h>
+ #include <asm/io.h>
+ 
+-void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle)
++void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
+ {
+ 	struct page *page, *end, *free;
+ 	void *ret;
+diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
+--- a/arch/sh/mm/fault.c
++++ b/arch/sh/mm/fault.c
+@@ -194,10 +194,13 @@ asmlinkage int __do_page_fault(struct pt
+ 			       unsigned long address)
+ {
+ 	unsigned long addrmax = P4SEG;
+-	pgd_t *dir;
++	pgd_t *pgd;
+ 	pmd_t *pmd;
+ 	pte_t *pte;
+ 	pte_t entry;
++	struct mm_struct *mm;
++	spinlock_t *ptl;
++	int ret = 1;
+ 
+ #ifdef CONFIG_SH_KGDB
+ 	if (kgdb_nofault && kgdb_bus_err_hook)
+@@ -208,28 +211,28 @@ asmlinkage int __do_page_fault(struct pt
+ 	addrmax = P4SEG_STORE_QUE + 0x04000000;
+ #endif
+ 
+-	if (address >= P3SEG && address < addrmax)
+-		dir = pgd_offset_k(address);
+-	else if (address >= TASK_SIZE)
++	if (address >= P3SEG && address < addrmax) {
++		pgd = pgd_offset_k(address);
++		mm = NULL;
++	} else if (address >= TASK_SIZE)
+ 		return 1;
+-	else if (!current->mm)
++	else if (!(mm = current->mm))
+ 		return 1;
+ 	else
+-		dir = pgd_offset(current->mm, address);
++		pgd = pgd_offset(mm, address);
+ 
+-	pmd = pmd_offset(dir, address);
+-	if (pmd_none(*pmd))
++	pmd = pmd_offset(pgd, address);
++	if (pmd_none_or_clear_bad(pmd))
+ 		return 1;
+-	if (pmd_bad(*pmd)) {
+-		pmd_ERROR(*pmd);
+-		pmd_clear(pmd);
+-		return 1;
+-	}
+-	pte = pte_offset_kernel(pmd, address);
++	if (mm)
++		pte = pte_offset_map_lock(mm, pmd, address, &ptl);
++	else
++		pte = pte_offset_kernel(pmd, address);
++
+ 	entry = *pte;
+ 	if (pte_none(entry) || pte_not_present(entry)
+ 	    || (writeaccess && !pte_write(entry)))
+-		return 1;
++		goto unlock;
+ 
+ 	if (writeaccess)
+ 		entry = pte_mkdirty(entry);
+@@ -251,8 +254,11 @@ asmlinkage int __do_page_fault(struct pt
+ 
+ 	set_pte(pte, entry);
+ 	update_mmu_cache(NULL, address, entry);
+-
+-	return 0;
++	ret = 0;
++unlock:
++	if (mm)
++		pte_unmap_unlock(pte, ptl);
++	return ret;
+ }
+ 
+ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
+--- a/arch/sh/mm/hugetlbpage.c
++++ b/arch/sh/mm/hugetlbpage.c
+@@ -54,8 +54,6 @@ pte_t *huge_pte_offset(struct mm_struct 
+ 	return pte;
+ }
+ 
+-#define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
+-
+ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ 		     pte_t *ptep, pte_t entry)
+ {
+diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
+--- a/arch/sh/mm/ioremap.c
++++ b/arch/sh/mm/ioremap.c
+@@ -57,7 +57,7 @@ static inline int remap_area_pmd(pmd_t *
+ 	if (address >= end)
+ 		BUG();
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+@@ -79,7 +79,6 @@ int remap_area_pages(unsigned long addre
+ 	flush_cache_all();
+ 	if (address >= end)
+ 		BUG();
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		pmd_t *pmd;
+ 		pmd = pmd_alloc(&init_mm, dir, address);
+@@ -93,7 +92,6 @@ int remap_area_pages(unsigned long addre
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_tlb_all();
+ 	return error;
+ }
+diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
+--- a/arch/sh64/kernel/ptrace.c
++++ b/arch/sh64/kernel/ptrace.c
+@@ -121,7 +121,7 @@ put_fpu_long(struct task_struct *task, u
+ 	return 0;
+ }
+ 
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
+diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c
+--- a/arch/sh64/kernel/time.c
++++ b/arch/sh64/kernel/time.c
+@@ -116,8 +116,6 @@
+ 
+ extern unsigned long wall_jiffies;
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+ static unsigned long tmu_base, rtc_base;
+ unsigned long cprc_base;
+ 
+@@ -253,6 +251,7 @@ int do_settimeofday(struct timespec *tv)
+ 
+ 	return 0;
+ }
++EXPORT_SYMBOL(do_settimeofday);
+ 
+ static int set_rtc_time(unsigned long nowtime)
+ {
+diff --git a/arch/sh64/mm/cache.c b/arch/sh64/mm/cache.c
+--- a/arch/sh64/mm/cache.c
++++ b/arch/sh64/mm/cache.c
+@@ -584,32 +584,36 @@ static void sh64_dcache_purge_phy_page(u
+ 	}
+ }
+ 
+-static void sh64_dcache_purge_user_page(struct mm_struct *mm, unsigned long eaddr)
++static void sh64_dcache_purge_user_pages(struct mm_struct *mm,
++				unsigned long addr, unsigned long end)
+ {
+ 	pgd_t *pgd;
+ 	pmd_t *pmd;
+ 	pte_t *pte;
+ 	pte_t entry;
++	spinlock_t *ptl;
+ 	unsigned long paddr;
+ 
+-	/* NOTE : all the callers of this have mm->page_table_lock held, so the
+-	   following page table traversal is safe even on SMP/pre-emptible. */
+-
+-	if (!mm) return; /* No way to find physical address of page */
+-	pgd = pgd_offset(mm, eaddr);
+-	if (pgd_bad(*pgd)) return;
+-
+-	pmd = pmd_offset(pgd, eaddr);
+-	if (pmd_none(*pmd) || pmd_bad(*pmd)) return;
+-
+-	pte = pte_offset_kernel(pmd, eaddr);
+-	entry = *pte;
+-	if (pte_none(entry) || !pte_present(entry)) return;
+-
+-	paddr = pte_val(entry) & PAGE_MASK;
+-
+-	sh64_dcache_purge_coloured_phy_page(paddr, eaddr);
++	if (!mm)
++		return; /* No way to find physical address of page */
+ 
++	pgd = pgd_offset(mm, addr);
++	if (pgd_bad(*pgd))
++		return;
++
++	pmd = pmd_offset(pgd, addr);
++	if (pmd_none(*pmd) || pmd_bad(*pmd))
++		return;
++
++	pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
++	do {
++		entry = *pte;
++		if (pte_none(entry) || !pte_present(entry))
++			continue;
++		paddr = pte_val(entry) & PAGE_MASK;
++		sh64_dcache_purge_coloured_phy_page(paddr, addr);
++	} while (pte++, addr += PAGE_SIZE, addr != end);
++	pte_unmap_unlock(pte - 1, ptl);
+ }
+ /****************************************************************************/
+ 
+@@ -668,7 +672,7 @@ static void sh64_dcache_purge_user_range
+ 	int n_pages;
+ 
+ 	n_pages = ((end - start) >> PAGE_SHIFT);
+-	if (n_pages >= 64) {
++	if (n_pages >= 64 || ((start ^ (end - 1)) & PMD_MASK)) {
+ #if 1
+ 		sh64_dcache_purge_all();
+ #else
+@@ -707,20 +711,10 @@ static void sh64_dcache_purge_user_range
+ 		}
+ #endif
+ 	} else {
+-		/* 'Small' range */
+-		unsigned long aligned_start;
+-		unsigned long eaddr;
+-		unsigned long last_page_start;
+-
+-		aligned_start = start & PAGE_MASK;
+-		/* 'end' is 1 byte beyond the end of the range */
+-		last_page_start = (end - 1) & PAGE_MASK;
+-
+-		eaddr = aligned_start;
+-		while (eaddr <= last_page_start) {
+-			sh64_dcache_purge_user_page(mm, eaddr);
+-			eaddr += PAGE_SIZE;
+-		}
++		/* Small range, covered by a single page table page */
++		start &= PAGE_MASK;	/* should already be so */
++		end = PAGE_ALIGN(end);	/* should already be so */
++		sh64_dcache_purge_user_pages(mm, start, end);
+ 	}
+ 	return;
+ }
+@@ -880,9 +874,7 @@ void flush_cache_range(struct vm_area_st
+ 	   addresses from the user address space specified by mm, after writing
+ 	   back any dirty data.
+ 
+-	   Note(1), 'end' is 1 byte beyond the end of the range to flush.
+-
+-	   Note(2), this is called with mm->page_table_lock held.*/
++	   Note, 'end' is 1 byte beyond the end of the range to flush. */
+ 
+ 	sh64_dcache_purge_user_range(mm, start, end);
+ 	sh64_icache_inv_user_page_range(mm, start, end);
+@@ -898,7 +890,7 @@ void flush_cache_page(struct vm_area_str
+ 	   the I-cache must be searched too in case the page in question is
+ 	   both writable and being executed from (e.g. stack trampolines.)
+ 
+-	   Note(1), this is called with mm->page_table_lock held.
++	   Note, this is called with pte lock held.
+ 	   */
+ 
+ 	sh64_dcache_purge_phy_page(pfn << PAGE_SHIFT);
+diff --git a/arch/sh64/mm/hugetlbpage.c b/arch/sh64/mm/hugetlbpage.c
+--- a/arch/sh64/mm/hugetlbpage.c
++++ b/arch/sh64/mm/hugetlbpage.c
+@@ -54,41 +54,31 @@ pte_t *huge_pte_offset(struct mm_struct 
+ 	return pte;
+ }
+ 
+-#define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
+-
+-static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma,
+-			 struct page *page, pte_t * page_table, int write_access)
++void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
++		     pte_t *ptep, pte_t entry)
+ {
+-	unsigned long i;
+-	pte_t entry;
+-
+-	add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
+-
+-	if (write_access)
+-		entry = pte_mkwrite(pte_mkdirty(mk_pte(page,
+-						       vma->vm_page_prot)));
+-	else
+-		entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
+-	entry = pte_mkyoung(entry);
+-	mk_pte_huge(entry);
++	int i;
+ 
+ 	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+-		set_pte(page_table, entry);
+-		page_table++;
+-
++		set_pte_at(mm, addr, ptep, entry);
++		ptep++;
++		addr += PAGE_SIZE;
+ 		pte_val(entry) += PAGE_SIZE;
+ 	}
+ }
+ 
+-pte_t huge_ptep_get_and_clear(pte_t *ptep)
++pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
++			      pte_t *ptep)
+ {
+ 	pte_t entry;
++	int i;
+ 
+ 	entry = *ptep;
+ 
+ 	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+-		pte_clear(pte);
+-		pte++;
++		pte_clear(mm, addr, ptep);
++		addr += PAGE_SIZE;
++		ptep++;
+ 	}
+ 
+ 	return entry;
+@@ -106,79 +96,6 @@ int is_aligned_hugepage_range(unsigned l
+ 	return 0;
+ }
+ 
+-int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
+-			    struct vm_area_struct *vma)
+-{
+-	pte_t *src_pte, *dst_pte, entry;
+-	struct page *ptepage;
+-	unsigned long addr = vma->vm_start;
+-	unsigned long end = vma->vm_end;
+-	int i;
+-
+-	while (addr < end) {
+-		dst_pte = huge_pte_alloc(dst, addr);
+-		if (!dst_pte)
+-			goto nomem;
+-		src_pte = huge_pte_offset(src, addr);
+-		BUG_ON(!src_pte || pte_none(*src_pte));
+-		entry = *src_pte;
+-		ptepage = pte_page(entry);
+-		get_page(ptepage);
+-		for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+-			set_pte(dst_pte, entry);
+-			pte_val(entry) += PAGE_SIZE;
+-			dst_pte++;
+-		}
+-		add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
+-		addr += HPAGE_SIZE;
+-	}
+-	return 0;
+-
+-nomem:
+-	return -ENOMEM;
+-}
+-
+-int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
+-			struct page **pages, struct vm_area_struct **vmas,
+-			unsigned long *position, int *length, int i)
+-{
+-	unsigned long vaddr = *position;
+-	int remainder = *length;
+-
+-	WARN_ON(!is_vm_hugetlb_page(vma));
+-
+-	while (vaddr < vma->vm_end && remainder) {
+-		if (pages) {
+-			pte_t *pte;
+-			struct page *page;
+-
+-			pte = huge_pte_offset(mm, vaddr);
+-
+-			/* hugetlb should be locked, and hence, prefaulted */
+-			BUG_ON(!pte || pte_none(*pte));
+-
+-			page = pte_page(*pte);
+-
+-			WARN_ON(!PageCompound(page));
+-
+-			get_page(page);
+-			pages[i] = page;
+-		}
+-
+-		if (vmas)
+-			vmas[i] = vma;
+-
+-		vaddr += PAGE_SIZE;
+-		--remainder;
+-		++i;
+-	}
+-
+-	*length = remainder;
+-	*position = vaddr;
+-
+-	return i;
+-}
+-
+ struct page *follow_huge_addr(struct mm_struct *mm,
+ 			      unsigned long address, int write)
+ {
+@@ -195,84 +112,3 @@ struct page *follow_huge_pmd(struct mm_s
+ {
+ 	return NULL;
+ }
+-
+-void unmap_hugepage_range(struct vm_area_struct *vma,
+-			  unsigned long start, unsigned long end)
+-{
+-	struct mm_struct *mm = vma->vm_mm;
+-	unsigned long address;
+-	pte_t *pte;
+-	struct page *page;
+-	int i;
+-
+-	BUG_ON(start & (HPAGE_SIZE - 1));
+-	BUG_ON(end & (HPAGE_SIZE - 1));
+-
+-	for (address = start; address < end; address += HPAGE_SIZE) {
+-		pte = huge_pte_offset(mm, address);
+-		BUG_ON(!pte);
+-		if (pte_none(*pte))
+-			continue;
+-		page = pte_page(*pte);
+-		put_page(page);
+-		for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+-			pte_clear(mm, address+(i*PAGE_SIZE), pte);
+-			pte++;
+-		}
+-	}
+-	add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT));
+-	flush_tlb_range(vma, start, end);
+-}
+-
+-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
+-{
+-	struct mm_struct *mm = current->mm;
+-	unsigned long addr;
+-	int ret = 0;
+-
+-	BUG_ON(vma->vm_start & ~HPAGE_MASK);
+-	BUG_ON(vma->vm_end & ~HPAGE_MASK);
+-
+-	spin_lock(&mm->page_table_lock);
+-	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
+-		unsigned long idx;
+-		pte_t *pte = huge_pte_alloc(mm, addr);
+-		struct page *page;
+-
+-		if (!pte) {
+-			ret = -ENOMEM;
+-			goto out;
+-		}
+-		if (!pte_none(*pte))
+-			continue;
+-
+-		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
+-			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+-		page = find_get_page(mapping, idx);
+-		if (!page) {
+-			/* charge the fs quota first */
+-			if (hugetlb_get_quota(mapping)) {
+-				ret = -ENOMEM;
+-				goto out;
+-			}
+-			page = alloc_huge_page();
+-			if (!page) {
+-				hugetlb_put_quota(mapping);
+-				ret = -ENOMEM;
+-				goto out;
+-			}
+-			ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
+-			if (! ret) {
+-				unlock_page(page);
+-			} else {
+-				hugetlb_put_quota(mapping);
+-				free_huge_page(page);
+-				goto out;
+-			}
+-		}
+-		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
+-	}
+-out:
+-	spin_unlock(&mm->page_table_lock);
+-	return ret;
+-}
+diff --git a/arch/sh64/mm/ioremap.c b/arch/sh64/mm/ioremap.c
+--- a/arch/sh64/mm/ioremap.c
++++ b/arch/sh64/mm/ioremap.c
+@@ -79,7 +79,7 @@ static inline int remap_area_pmd(pmd_t *
+ 		BUG();
+ 
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+@@ -101,7 +101,6 @@ static int remap_area_pages(unsigned lon
+ 	flush_cache_all();
+ 	if (address >= end)
+ 		BUG();
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
+ 		error = -ENOMEM;
+@@ -115,7 +114,6 @@ static int remap_area_pages(unsigned lon
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_tlb_all();
+ 	return 0;
+ }
+diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
+--- a/arch/sparc/kernel/pcic.c
++++ b/arch/sparc/kernel/pcic.c
+@@ -497,8 +497,8 @@ static void pcic_map_pci_device(struct l
+ 				 * CheerIO makes a similar conversion.
+ 				 * See ebus.c for details.
+ 				 *
+-				 * Note that check_region()/request_region()
+-				 * work for these devices.
++				 * Note that request_region()
++				 * works for these devices.
+ 				 *
+ 				 * XXX Neat trick, but it's a *bad* idea
+ 				 * to shit into regions like that.
+diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
+--- a/arch/sparc/kernel/time.c
++++ b/arch/sparc/kernel/time.c
+@@ -45,10 +45,6 @@
+ 
+ extern unsigned long wall_jiffies;
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ DEFINE_SPINLOCK(rtc_lock);
+ enum sparc_clock_type sp_clock_typ;
+ DEFINE_SPINLOCK(mostek_lock);
+diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c
+--- a/arch/sparc/mm/generic.c
++++ b/arch/sparc/mm/generic.c
+@@ -73,14 +73,16 @@ int io_remap_pfn_range(struct vm_area_st
+ 	int space = GET_IOSPACE(pfn);
+ 	unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+ 
++	/* See comment in mm/memory.c remap_pfn_range */
++	vma->vm_flags |= VM_IO | VM_RESERVED;
++
+ 	prot = __pgprot(pg_iobits);
+ 	offset -= from;
+ 	dir = pgd_offset(mm, from);
+ 	flush_cache_range(vma, beg, end);
+ 
+-	spin_lock(&mm->page_table_lock);
+ 	while (from < end) {
+-		pmd_t *pmd = pmd_alloc(current->mm, dir, from);
++		pmd_t *pmd = pmd_alloc(mm, dir, from);
+ 		error = -ENOMEM;
+ 		if (!pmd)
+ 			break;
+@@ -90,7 +92,6 @@ int io_remap_pfn_range(struct vm_area_st
+ 		from = (from + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	}
+-	spin_unlock(&mm->page_table_lock);
+ 
+ 	flush_tlb_range(vma, beg, end);
+ 	return error;
+diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
+--- a/arch/sparc64/kernel/binfmt_aout32.c
++++ b/arch/sparc64/kernel/binfmt_aout32.c
+@@ -241,7 +241,6 @@ static int load_aout32_binary(struct lin
+ 	current->mm->brk = ex.a_bss +
+ 		(current->mm->start_brk = N_BSSADDR(ex));
+ 
+-	set_mm_counter(current->mm, rss, 0);
+ 	current->mm->mmap = NULL;
+ 	compute_creds(bprm);
+  	current->flags &= ~PF_FORKNOEXEC;
+diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
+--- a/arch/sparc64/kernel/ioctl32.c
++++ b/arch/sparc64/kernel/ioctl32.c
+@@ -475,9 +475,6 @@ IOCTL_TABLE_START
+ #include <linux/compat_ioctl.h>
+ #define DECLARES
+ #include "compat_ioctl.c"
+-COMPATIBLE_IOCTL(TIOCSTART)
+-COMPATIBLE_IOCTL(TIOCSTOP)
+-COMPATIBLE_IOCTL(TIOCSLTC)
+ COMPATIBLE_IOCTL(FBIOGTYPE)
+ COMPATIBLE_IOCTL(FBIOSATTR)
+ COMPATIBLE_IOCTL(FBIOGATTR)
+diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
+--- a/arch/sparc64/kernel/time.c
++++ b/arch/sparc64/kernel/time.c
+@@ -55,10 +55,6 @@ unsigned long ds1287_regs = 0UL;
+ 
+ extern unsigned long wall_jiffies;
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ static void __iomem *mstk48t08_regs;
+ static void __iomem *mstk48t59_regs;
+ 
+diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c
+--- a/arch/sparc64/mm/generic.c
++++ b/arch/sparc64/mm/generic.c
+@@ -127,14 +127,16 @@ int io_remap_pfn_range(struct vm_area_st
+ 	int space = GET_IOSPACE(pfn);
+ 	unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+ 
++	/* See comment in mm/memory.c remap_pfn_range */
++	vma->vm_flags |= VM_IO | VM_RESERVED;
++
+ 	prot = __pgprot(pg_iobits);
+ 	offset -= from;
+ 	dir = pgd_offset(mm, from);
+ 	flush_cache_range(vma, beg, end);
+ 
+-	spin_lock(&mm->page_table_lock);
+ 	while (from < end) {
+-		pud_t *pud = pud_alloc(current->mm, dir, from);
++		pud_t *pud = pud_alloc(mm, dir, from);
+ 		error = -ENOMEM;
+ 		if (!pud)
+ 			break;
+@@ -144,8 +146,7 @@ int io_remap_pfn_range(struct vm_area_st
+ 		from = (from + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	}
+-	flush_tlb_range(vma, beg, end);
+-	spin_unlock(&mm->page_table_lock);
+ 
++	flush_tlb_range(vma, beg, end);
+ 	return error;
+ }
+diff --git a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c
+--- a/arch/sparc64/mm/tlb.c
++++ b/arch/sparc64/mm/tlb.c
+@@ -18,8 +18,7 @@
+ 
+ /* Heavily inspired by the ppc64 code.  */
+ 
+-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) =
+-	{ NULL, 0, 0, 0, 0, 0, { 0 }, { NULL }, };
++DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) = { 0, };
+ 
+ void flush_tlb_pending(void)
+ {
+@@ -72,7 +71,7 @@ void tlb_batch_add(struct mm_struct *mm,
+ 
+ no_cache_flush:
+ 
+-	if (mp->tlb_frozen)
++	if (mp->fullmm)
+ 		return;
+ 
+ 	nr = mp->tlb_nr;
+@@ -97,7 +96,7 @@ void flush_tlb_pgtables(struct mm_struct
+ 	unsigned long nr = mp->tlb_nr;
+ 	long s = start, e = end, vpte_base;
+ 
+-	if (mp->tlb_frozen)
++	if (mp->fullmm)
+ 		return;
+ 
+ 	/* If start is greater than end, that is a real problem.  */
+diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
+--- a/arch/sparc64/solaris/socksys.c
++++ b/arch/sparc64/solaris/socksys.c
+@@ -49,7 +49,7 @@ IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, I
+ 
+ #else
+ 
+-extern void * mykmalloc(size_t s, int gfp);
++extern void * mykmalloc(size_t s, gfp_t gfp);
+ extern void mykfree(void *);
+ 
+ #endif
+diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
+--- a/arch/sparc64/solaris/timod.c
++++ b/arch/sparc64/solaris/timod.c
+@@ -39,7 +39,7 @@ static char * page = NULL ;
+ 
+ #else
+ 
+-void * mykmalloc(size_t s, int gfp)
++void * mykmalloc(size_t s, gfp_t gfp)
+ {
+ 	static char * page;
+ 	static size_t free;
+diff --git a/arch/um/Kconfig b/arch/um/Kconfig
+--- a/arch/um/Kconfig
++++ b/arch/um/Kconfig
+@@ -27,10 +27,6 @@ config UID16
+ 	bool
+ 	default y
+ 
+-config RWSEM_GENERIC_SPINLOCK
+-	bool
+-	default y
+-
+ config GENERIC_CALIBRATE_DELAY
+ 	bool
+ 	default y
+@@ -40,6 +36,12 @@ config IRQ_RELEASE_METHOD
+ 	bool
+ 	default y
+ 
++menu "Host processor type and features"
++
++source "arch/i386/Kconfig.cpu"
++
++endmenu
++
+ menu "UML-specific options"
+ 
+ config MODE_TT
+diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64
+--- a/arch/um/Kconfig.x86_64
++++ b/arch/um/Kconfig.x86_64
+@@ -6,6 +6,11 @@ config 64BIT
+ 	bool
+ 	default y
+ 
++#XXX: this is so in the underlying arch, but it's wrong!!!
++config RWSEM_GENERIC_SPINLOCK
++	bool
++	default y
++
+ config SEMAPHORE_SLEEPERS
+ 	bool
+ 	default y
+diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
+--- a/arch/um/Makefile-i386
++++ b/arch/um/Makefile-i386
+@@ -29,6 +29,12 @@ endif
+ 
+ CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
+ 
+-ifneq ($(CONFIG_GPROF),y)
+-ARCH_CFLAGS += -DUM_FASTCALL
+-endif
++# First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
++include $(srctree)/arch/i386/Makefile.cpu
++
++# prevent gcc from keeping the stack 16 byte aligned. Taken from i386.
++cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
++
++CFLAGS += $(cflags-y)
++USER_CFLAGS += $(cflags-y)
++
+diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
+--- a/arch/um/drivers/net_kern.c
++++ b/arch/um/drivers/net_kern.c
+@@ -20,6 +20,7 @@
+ #include "linux/ctype.h"
+ #include "linux/bootmem.h"
+ #include "linux/ethtool.h"
++#include "linux/platform_device.h"
+ #include "asm/uaccess.h"
+ #include "user_util.h"
+ #include "kern_util.h"
+diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
+--- a/arch/um/drivers/ubd_kern.c
++++ b/arch/um/drivers/ubd_kern.c
+@@ -35,6 +35,7 @@
+ #include "linux/blkpg.h"
+ #include "linux/genhd.h"
+ #include "linux/spinlock.h"
++#include "linux/platform_device.h"
+ #include "asm/segment.h"
+ #include "asm/uaccess.h"
+ #include "asm/irq.h"
+diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
+--- a/arch/um/include/net_kern.h
++++ b/arch/um/include/net_kern.h
+@@ -6,10 +6,11 @@
+ #ifndef __UM_NET_KERN_H
+ #define __UM_NET_KERN_H
+ 
+-#include "linux/netdevice.h"
+-#include "linux/skbuff.h"
+-#include "linux/socket.h"
+-#include "linux/list.h"
++#include <linux/netdevice.h>
++#include <linux/platform_device.h>
++#include <linux/skbuff.h>
++#include <linux/socket.h>
++#include <linux/list.h>
+ 
+ struct uml_net {
+ 	struct list_head list;
+diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
+--- a/arch/um/include/sysdep-i386/syscalls.h
++++ b/arch/um/include/sysdep-i386/syscalls.h
+@@ -11,7 +11,6 @@ typedef long syscall_handler_t(struct pt
+ /* Not declared on x86, incompatible declarations on x86_64, so these have
+  * to go here rather than in sys_call_table.c
+  */
+-extern syscall_handler_t sys_ptrace;
+ extern syscall_handler_t sys_rt_sigaction;
+ 
+ extern syscall_handler_t old_mmap_i386;
+diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h
+--- a/arch/um/include/tlb.h
++++ b/arch/um/include/tlb.h
+@@ -34,7 +34,6 @@ struct host_vm_op {
+ 	} u;
+ };
+ 
+-extern void mprotect_kernel_vm(int w);
+ extern void force_flush_all(void);
+ extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
+                              unsigned long end_addr, int force,
+diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
+--- a/arch/um/kernel/mem.c
++++ b/arch/um/kernel/mem.c
+@@ -252,7 +252,7 @@ void paging_init(void)
+ #endif
+ }
+ 
+-struct page *arch_validate(struct page *page, int mask, int order)
++struct page *arch_validate(struct page *page, gfp_t mask, int order)
+ {
+ 	unsigned long addr, zero = 0;
+ 	int i;
+diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
+--- a/arch/um/kernel/process_kern.c
++++ b/arch/um/kernel/process_kern.c
+@@ -80,7 +80,7 @@ void free_stack(unsigned long stack, int
+ unsigned long alloc_stack(int order, int atomic)
+ {
+ 	unsigned long page;
+-	int flags = GFP_KERNEL;
++	gfp_t flags = GFP_KERNEL;
+ 
+ 	if (atomic)
+ 		flags = GFP_ATOMIC;
+@@ -222,6 +222,7 @@ void *um_virt_to_phys(struct task_struct
+ 	pud_t *pud;
+ 	pmd_t *pmd;
+ 	pte_t *pte;
++	pte_t ptent;
+ 
+ 	if(task->mm == NULL) 
+ 		return(ERR_PTR(-EINVAL));
+@@ -238,12 +239,13 @@ void *um_virt_to_phys(struct task_struct
+ 		return(ERR_PTR(-EINVAL));
+ 
+ 	pte = pte_offset_kernel(pmd, addr);
+-	if(!pte_present(*pte)) 
++	ptent = *pte;
++	if(!pte_present(ptent))
+ 		return(ERR_PTR(-EINVAL));
+ 
+ 	if(pte_out != NULL)
+-		*pte_out = *pte;
+-	return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
++		*pte_out = ptent;
++	return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK));
+ }
+ 
+ char *current_cmd(void)
+diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
+--- a/arch/um/kernel/skas/mmu.c
++++ b/arch/um/kernel/skas/mmu.c
+@@ -28,7 +28,6 @@ static int init_stub_pte(struct mm_struc
+ 	pmd_t *pmd;
+ 	pte_t *pte;
+ 
+-	spin_lock(&mm->page_table_lock);
+ 	pgd = pgd_offset(mm, proc);
+ 	pud = pud_alloc(mm, pgd, proc);
+ 	if (!pud)
+@@ -63,7 +62,6 @@ static int init_stub_pte(struct mm_struc
+ 	*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
+ 	*pte = pte_mkexec(*pte);
+ 	*pte = pte_wrprotect(*pte);
+-	spin_unlock(&mm->page_table_lock);
+ 	return(0);
+ 
+  out_pmd:
+@@ -71,7 +69,6 @@ static int init_stub_pte(struct mm_struc
+  out_pte:
+ 	pmd_free(pmd);
+  out:
+-	spin_unlock(&mm->page_table_lock);
+ 	return(-ENOMEM);
+ }
+ 
+@@ -147,6 +144,7 @@ void destroy_context_skas(struct mm_stru
+ 
+ 	if(!proc_mm || !ptrace_faultinfo){
+ 		free_page(mmu->id.stack);
++		pte_lock_deinit(virt_to_page(mmu->last_page_table));
+ 		pte_free_kernel((pte_t *) mmu->last_page_table);
+                 dec_page_state(nr_page_table_pages);
+ #ifdef CONFIG_3_LEVEL_PGTABLES
+diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
+--- a/arch/um/kernel/time_kern.c
++++ b/arch/um/kernel/time_kern.c
+@@ -22,10 +22,6 @@
+ #include "mode.h"
+ #include "os.h"
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ int hz(void)
+ {
+ 	return(HZ);
+diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
+--- a/arch/um/kernel/tt/tlb.c
++++ b/arch/um/kernel/tt/tlb.c
+@@ -74,42 +74,6 @@ void flush_tlb_kernel_range_tt(unsigned 
+                 atomic_inc(&vmchange_seq);
+ }
+ 
+-static void protect_vm_page(unsigned long addr, int w, int must_succeed)
+-{
+-	int err;
+-
+-	err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
+-	if(err == 0) return;
+-	else if((err == -EFAULT) || (err == -ENOMEM)){
+-		flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+-		protect_vm_page(addr, w, 1);
+-	}
+-	else panic("protect_vm_page : protect failed, errno = %d\n", err);
+-}
+-
+-void mprotect_kernel_vm(int w)
+-{
+-	struct mm_struct *mm;
+-	pgd_t *pgd;
+-	pud_t *pud;
+-	pmd_t *pmd;
+-	pte_t *pte;
+-	unsigned long addr;
+-	
+-	mm = &init_mm;
+-	for(addr = start_vm; addr < end_vm;){
+-		pgd = pgd_offset(mm, addr);
+-		pud = pud_offset(pgd, addr);
+-		pmd = pmd_offset(pud, addr);
+-		if(pmd_present(*pmd)){
+-			pte = pte_offset_kernel(pmd, addr);
+-			if(pte_present(*pte)) protect_vm_page(addr, w, 0);
+-			addr += PAGE_SIZE;
+-		}
+-		else addr += PMD_SIZE;
+-	}
+-}
+-
+ void flush_tlb_kernel_vm_tt(void)
+ {
+         flush_tlb_kernel_range(start_vm, end_vm);
+diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
+--- a/arch/v850/kernel/ptrace.c
++++ b/arch/v850/kernel/ptrace.c
+@@ -113,7 +113,7 @@ static int set_single_step (struct task_
+ 	return 1;
+ }
+ 
+-int sys_ptrace(long request, long pid, long addr, long data)
++long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	int rval;
+diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
+--- a/arch/v850/kernel/time.c
++++ b/arch/v850/kernel/time.c
+@@ -26,10 +26,6 @@
+ 
+ #include "mach.h"
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ #define TICK_SIZE	(tick_nsec / 1000)
+ 
+ /*
+diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
+--- a/arch/x86_64/ia32/ia32_aout.c
++++ b/arch/x86_64/ia32/ia32_aout.c
+@@ -314,7 +314,6 @@ static int load_aout_binary(struct linux
+ 	current->mm->free_area_cache = TASK_UNMAPPED_BASE;
+ 	current->mm->cached_hole_size = 0;
+ 
+-	set_mm_counter(current->mm, rss, 0);
+ 	current->mm->mmap = NULL;
+ 	compute_creds(bprm);
+  	current->flags &= ~PF_FORKNOEXEC;
+diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
+--- a/arch/x86_64/ia32/ia32_ioctl.c
++++ b/arch/x86_64/ia32/ia32_ioctl.c
+@@ -12,40 +12,11 @@
+ #define INCLUDES
+ #include <linux/syscalls.h>
+ #include "compat_ioctl.c"
+-#include <asm/mtrr.h>
+ #include <asm/ia32.h>
+ 
+ #define CODE
+ #include "compat_ioctl.c"
+   
+-#ifndef TIOCGDEV
+-#define TIOCGDEV       _IOR('T',0x32, unsigned int)
+-#endif
+-static int tiocgdev(unsigned fd, unsigned cmd,  unsigned int __user *ptr) 
+-{ 
+-
+-	struct file *file;
+-	struct tty_struct *real_tty;
+-	int fput_needed, ret;
+-
+-	file = fget_light(fd, &fput_needed);
+-	if (!file)
+-		return -EBADF;
+-
+-	ret = -EINVAL;
+-	if (file->f_op->ioctl != tty_ioctl)
+-		goto out;
+-	real_tty = (struct tty_struct *)file->private_data;
+-	if (!real_tty) 	
+-		goto out;
+-
+-	ret = put_user(new_encode_dev(tty_devnum(real_tty)), ptr); 
+-
+-out:
+-	fput_light(file, fput_needed);
+-	return ret;
+-} 
+-
+ #define RTC_IRQP_READ32	_IOR('p', 0x0b, unsigned int)	 /* Read IRQ rate   */
+ #define RTC_IRQP_SET32	_IOW('p', 0x0c, unsigned int)	 /* Set IRQ rate    */
+ #define RTC_EPOCH_READ32	_IOR('p', 0x0d, unsigned)	 /* Read epoch      */
+@@ -85,90 +56,6 @@ static int rtc32_ioctl(unsigned fd, unsi
+ 	return sys_ioctl(fd,cmd,arg); 
+ } 
+ 
+-/* /proc/mtrr ioctls */
+-
+-
+-struct mtrr_sentry32
+-{
+-    compat_ulong_t base;    /*  Base address     */
+-    compat_uint_t size;    /*  Size of region   */
+-    compat_uint_t type;     /*  Type of region   */
+-};
+-
+-struct mtrr_gentry32
+-{
+-    compat_ulong_t regnum;   /*  Register number  */
+-    compat_uint_t base;    /*  Base address     */
+-    compat_uint_t size;    /*  Size of region   */
+-    compat_uint_t type;     /*  Type of region   */
+-};
+-
+-#define	MTRR_IOCTL_BASE	'M'
+-
+-#define MTRRIOC32_ADD_ENTRY        _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry32)
+-#define MTRRIOC32_SET_ENTRY        _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry32)
+-#define MTRRIOC32_DEL_ENTRY        _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry32)
+-#define MTRRIOC32_GET_ENTRY        _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
+-#define MTRRIOC32_KILL_ENTRY       _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry32)
+-#define MTRRIOC32_ADD_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry32)
+-#define MTRRIOC32_SET_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry32)
+-#define MTRRIOC32_DEL_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry32)
+-#define MTRRIOC32_GET_PAGE_ENTRY   _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
+-#define MTRRIOC32_KILL_PAGE_ENTRY  _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry32)
+-
+-
+-static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{ 
+-	struct mtrr_gentry g;
+-	struct mtrr_sentry s;
+-	int get = 0, err = 0; 
+-	struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)arg; 
+-	mm_segment_t oldfs = get_fs(); 
+-
+-	switch (cmd) { 
+-#define SET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; break 
+-#define GET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; get=1; break
+-		SET(ADD);
+-		SET(SET); 
+-		SET(DEL);
+-		GET(GET); 
+-		SET(KILL);
+-		SET(ADD_PAGE); 
+-		SET(SET_PAGE); 
+-		SET(DEL_PAGE); 
+-		GET(GET_PAGE); 
+-		SET(KILL_PAGE); 
+-	} 
+-	
+-	if (get) { 
+-		err = get_user(g.regnum, &g32->regnum);
+-		err |= get_user(g.base, &g32->base);
+-		err |= get_user(g.size, &g32->size);
+-		err |= get_user(g.type, &g32->type); 
+-
+-		arg = (unsigned long)&g; 
+-	} else { 
+-		struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)arg;
+-		err = get_user(s.base, &s32->base);
+-		err |= get_user(s.size, &s32->size);
+-		err |= get_user(s.type, &s32->type);
+-
+-		arg = (unsigned long)&s; 
+-	} 
+-	if (err) return err;
+-	
+-	set_fs(KERNEL_DS); 
+-	err = sys_ioctl(fd, cmd, arg); 
+-	set_fs(oldfs); 
+-		
+-	if (!err && get) { 
+-		err = put_user(g.base, &g32->base);
+-		err |= put_user(g.size, &g32->size);
+-		err |= put_user(g.regnum, &g32->regnum);
+-		err |= put_user(g.type, &g32->type); 
+-	} 
+-	return err;
+-} 
+ 
+ #define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) }, 
+ #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
+@@ -185,7 +72,6 @@ COMPATIBLE_IOCTL(0x4B51)   /* KDSHWCLK -
+ COMPATIBLE_IOCTL(FIOQSIZE)
+ 
+ /* And these ioctls need translation */
+-HANDLE_IOCTL(TIOCGDEV, tiocgdev)
+ /* realtime device */
+ HANDLE_IOCTL(RTC_IRQP_READ,  rtc32_ioctl)
+ HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
+@@ -193,17 +79,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl
+ HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
+ HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
+ /* take care of sizeof(sizeof()) breakage */
+-/* mtrr */
+-HANDLE_IOCTL(MTRRIOC32_ADD_ENTRY, mtrr_ioctl32)
+-HANDLE_IOCTL(MTRRIOC32_SET_ENTRY, mtrr_ioctl32)
+-HANDLE_IOCTL(MTRRIOC32_DEL_ENTRY, mtrr_ioctl32)
+-HANDLE_IOCTL(MTRRIOC32_GET_ENTRY, mtrr_ioctl32)
+-HANDLE_IOCTL(MTRRIOC32_KILL_ENTRY, mtrr_ioctl32)
+-HANDLE_IOCTL(MTRRIOC32_ADD_PAGE_ENTRY, mtrr_ioctl32)
+-HANDLE_IOCTL(MTRRIOC32_SET_PAGE_ENTRY, mtrr_ioctl32)
+-HANDLE_IOCTL(MTRRIOC32_DEL_PAGE_ENTRY, mtrr_ioctl32)
+-HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32)
+-HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32)
+ }; 
+ 
+ int ioctl_table_size = ARRAY_SIZE(ioctl_start);
+diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
+--- a/arch/x86_64/kernel/i8259.c
++++ b/arch/x86_64/kernel/i8259.c
+@@ -494,7 +494,7 @@ void invalidate_interrupt7(void);
+ void thermal_interrupt(void);
+ void i8254_timer_resume(void);
+ 
+-static void setup_timer(void)
++static void setup_timer_hardware(void)
+ {
+ 	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
+ 	udelay(10);
+@@ -505,13 +505,13 @@ static void setup_timer(void)
+ 
+ static int timer_resume(struct sys_device *dev)
+ {
+-	setup_timer();
++	setup_timer_hardware();
+ 	return 0;
+ }
+ 
+ void i8254_timer_resume(void)
+ {
+-	setup_timer();
++	setup_timer_hardware();
+ }
+ 
+ static struct sysdev_class timer_sysclass = {
+@@ -594,7 +594,7 @@ void __init init_IRQ(void)
+ 	 * Set the clock to HZ Hz, we already have a valid
+ 	 * vector now:
+ 	 */
+-	setup_timer();
++	setup_timer_hardware();
+ 
+ 	if (!acpi_ioapic)
+ 		setup_irq(2, &irq2);
+diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
+--- a/arch/x86_64/kernel/pci-gart.c
++++ b/arch/x86_64/kernel/pci-gart.c
+@@ -187,7 +187,7 @@ static void flush_gart(struct device *de
+ 
+ /* Allocate DMA memory on node near device */
+ noinline
+-static void *dma_alloc_pages(struct device *dev, unsigned gfp, unsigned order)
++static void *dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order)
+ {
+ 	struct page *page;
+ 	int node;
+@@ -204,7 +204,7 @@ static void *dma_alloc_pages(struct devi
+  */
+ void *
+ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+-		   unsigned gfp)
++		   gfp_t gfp)
+ {
+ 	void *memory;
+ 	unsigned long dma_mask = 0;
+diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c
+--- a/arch/x86_64/kernel/pci-nommu.c
++++ b/arch/x86_64/kernel/pci-nommu.c
+@@ -24,7 +24,7 @@ EXPORT_SYMBOL(iommu_sac_force);
+  */
+ 
+ void *dma_alloc_coherent(struct device *hwdev, size_t size,
+-			 dma_addr_t *dma_handle, unsigned gfp)
++			 dma_addr_t *dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 	u64 mask;
+diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
+--- a/arch/x86_64/kernel/setup.c
++++ b/arch/x86_64/kernel/setup.c
+@@ -1213,7 +1213,7 @@ static int show_cpuinfo(struct seq_file 
+ 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ 
+ 		/* Intel-defined (#2) */
+-		"pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
++		"pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
+ 		"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
+ 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
+--- a/arch/x86_64/kernel/suspend.c
++++ b/arch/x86_64/kernel/suspend.c
+@@ -63,13 +63,12 @@ void save_processor_state(void)
+ 	__save_processor_state(&saved_context);
+ }
+ 
+-static void
+-do_fpu_end(void)
++static void do_fpu_end(void)
+ {
+-        /* restore FPU regs if necessary */
+-	/* Do it out of line so that gcc does not move cr0 load to some stupid place */
+-        kernel_fpu_end();
+-	mxcsr_feature_mask_init();
++	/*
++	 * Restore FPU regs if necessary
++	 */
++	kernel_fpu_end();
+ }
+ 
+ void __restore_processor_state(struct saved_context *ctxt)
+@@ -148,57 +147,7 @@ extern int restore_image(void);
+ 
+ pgd_t *temp_level4_pgt;
+ 
+-static void **pages;
+-
+-static inline void *__add_page(void)
+-{
+-	void **c;
+-
+-	c = (void **)get_usable_page(GFP_ATOMIC);
+-	if (c) {
+-		*c = pages;
+-		pages = c;
+-	}
+-	return c;
+-}
+-
+-static inline void *__next_page(void)
+-{
+-	void **c;
+-
+-	c = pages;
+-	if (c) {
+-		pages = *c;
+-		*c = NULL;
+-	}
+-	return c;
+-}
+-
+-/*
+- * Try to allocate as many usable pages as needed and daisy chain them.
+- * If one allocation fails, free the pages allocated so far
+- */
+-static int alloc_usable_pages(unsigned long n)
+-{
+-	void *p;
+-
+-	pages = NULL;
+-	do
+-		if (!__add_page())
+-			break;
+-	while (--n);
+-	if (n) {
+-		p = __next_page();
+-		while (p) {
+-			free_page((unsigned long)p);
+-			p = __next_page();
+-		}
+-		return -ENOMEM;
+-	}
+-	return 0;
+-}
+-
+-static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
++static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
+ {
+ 	long i, j;
+ 
+@@ -212,7 +161,9 @@ static void res_phys_pud_init(pud_t *pud
+ 		if (paddr >= end)
+ 			break;
+ 
+-		pmd = (pmd_t *)__next_page();
++		pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
++		if (!pmd)
++			return -ENOMEM;
+ 		set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
+ 		for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) {
+ 			unsigned long pe;
+@@ -224,13 +175,17 @@ static void res_phys_pud_init(pud_t *pud
+ 			set_pmd(pmd, __pmd(pe));
+ 		}
+ 	}
++	return 0;
+ }
+ 
+-static void set_up_temporary_mappings(void)
++static int set_up_temporary_mappings(void)
+ {
+ 	unsigned long start, end, next;
++	int error;
+ 
+-	temp_level4_pgt = (pgd_t *)__next_page();
++	temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC);
++	if (!temp_level4_pgt)
++		return -ENOMEM;
+ 
+ 	/* It is safe to reuse the original kernel mapping */
+ 	set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
+@@ -241,29 +196,27 @@ static void set_up_temporary_mappings(vo
+ 	end = (unsigned long)pfn_to_kaddr(end_pfn);
+ 
+ 	for (; start < end; start = next) {
+-		pud_t *pud = (pud_t *)__next_page();
++		pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC);
++		if (!pud)
++			return -ENOMEM;
+ 		next = start + PGDIR_SIZE;
+ 		if (next > end)
+ 			next = end;
+-		res_phys_pud_init(pud, __pa(start), __pa(next));
++		if ((error = res_phys_pud_init(pud, __pa(start), __pa(next))))
++			return error;
+ 		set_pgd(temp_level4_pgt + pgd_index(start),
+ 			mk_kernel_pgd(__pa(pud)));
+ 	}
++	return 0;
+ }
+ 
+ int swsusp_arch_resume(void)
+ {
+-	unsigned long n;
++	int error;
+ 
+-	n = ((end_pfn << PAGE_SHIFT) + PUD_SIZE - 1) >> PUD_SHIFT;
+-	n += (n + PTRS_PER_PUD - 1) / PTRS_PER_PUD + 1;
+-	pr_debug("swsusp_arch_resume(): pages needed = %lu\n", n);
+-	if (alloc_usable_pages(n)) {
+-		free_eaten_memory();
+-		return -ENOMEM;
+-	}
+ 	/* We have got enough memory and from now on we cannot recover */
+-	set_up_temporary_mappings();
++	if ((error = set_up_temporary_mappings()))
++		return error;
+ 	restore_image();
+ 	return 0;
+ }
+diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
+--- a/arch/x86_64/kernel/time.c
++++ b/arch/x86_64/kernel/time.c
+@@ -42,10 +42,6 @@
+ #include <asm/apic.h>
+ #endif
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-
+-EXPORT_SYMBOL(jiffies_64);
+-
+ #ifdef CONFIG_CPU_FREQ
+ static void cpufreq_delayed_get(void);
+ #endif
+@@ -481,9 +477,9 @@ static irqreturn_t timer_interrupt(int i
+ static unsigned int cyc2ns_scale;
+ #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
+ 
+-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
++static inline void set_cyc2ns_scale(unsigned long cpu_khz)
+ {
+-	cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
++	cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
+ }
+ 
+ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
+@@ -655,7 +651,7 @@ static int time_cpufreq_notifier(struct 
+ 			vxtime.tsc_quot = (1000L << 32) / cpu_khz;
+ 	}
+ 	
+-	set_cyc2ns_scale(cpu_khz_ref / 1000);
++	set_cyc2ns_scale(cpu_khz_ref);
+ 
+ 	return 0;
+ }
+@@ -939,7 +935,7 @@ void __init time_init(void)
+ 	rdtscll_sync(&vxtime.last_tsc);
+ 	setup_irq(0, &irq0);
+ 
+-	set_cyc2ns_scale(cpu_khz / 1000);
++	set_cyc2ns_scale(cpu_khz);
+ 
+ #ifndef CONFIG_SMP
+ 	time_init_gtod();
+@@ -1093,6 +1089,7 @@ static unsigned long PIE_freq = DEFAULT_
+ static unsigned long PIE_count;
+ 
+ static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
++static unsigned int hpet_t1_cmp; /* cached comparator register */
+ 
+ int is_hpet_enabled(void)
+ {
+@@ -1129,10 +1126,12 @@ int hpet_rtc_timer_init(void)
+ 	cnt = hpet_readl(HPET_COUNTER);
+ 	cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
+ 	hpet_writel(cnt, HPET_T1_CMP);
++	hpet_t1_cmp = cnt;
+ 	local_irq_restore(flags);
+ 
+ 	cfg = hpet_readl(HPET_T1_CFG);
+-	cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
++	cfg &= ~HPET_TN_PERIODIC;
++	cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
+ 	hpet_writel(cfg, HPET_T1_CFG);
+ 
+ 	return 1;
+@@ -1142,8 +1141,12 @@ static void hpet_rtc_timer_reinit(void)
+ {
+ 	unsigned int cfg, cnt;
+ 
+-	if (!(PIE_on | AIE_on | UIE_on))
++	if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
++		cfg = hpet_readl(HPET_T1_CFG);
++		cfg &= ~HPET_TN_ENABLE;
++		hpet_writel(cfg, HPET_T1_CFG);
+ 		return;
++	}
+ 
+ 	if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
+ 		hpet_rtc_int_freq = PIE_freq;
+@@ -1151,15 +1154,10 @@ static void hpet_rtc_timer_reinit(void)
+ 		hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
+ 
+ 	/* It is more accurate to use the comparator value than current count.*/
+-	cnt = hpet_readl(HPET_T1_CMP);
++	cnt = hpet_t1_cmp;
+ 	cnt += hpet_tick*HZ/hpet_rtc_int_freq;
+ 	hpet_writel(cnt, HPET_T1_CMP);
+-
+-	cfg = hpet_readl(HPET_T1_CFG);
+-	cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+-	hpet_writel(cfg, HPET_T1_CFG);
+-
+-	return;
++	hpet_t1_cmp = cnt;
+ }
+ 
+ /*
+diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
+--- a/arch/x86_64/mm/ioremap.c
++++ b/arch/x86_64/mm/ioremap.c
+@@ -60,7 +60,7 @@ static inline int remap_area_pmd(pmd_t *
+ 	if (address >= end)
+ 		BUG();
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
++		pte_t * pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+ 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+@@ -105,7 +105,6 @@ static int remap_area_pages(unsigned lon
+ 	flush_cache_all();
+ 	if (address >= end)
+ 		BUG();
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		pud_t *pud;
+ 		pud = pud_alloc(&init_mm, pgd, address);
+@@ -119,7 +118,6 @@ static int remap_area_pages(unsigned lon
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		pgd++;
+ 	} while (address && (address < end));
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_tlb_all();
+ 	return error;
+ }
+diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
+--- a/arch/xtensa/kernel/pci-dma.c
++++ b/arch/xtensa/kernel/pci-dma.c
+@@ -29,7 +29,7 @@
+  */
+ 
+ void *
+-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
++dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 
+diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
+--- a/arch/xtensa/kernel/platform.c
++++ b/arch/xtensa/kernel/platform.c
+@@ -18,6 +18,7 @@
+ #include <linux/time.h>
+ #include <asm/platform.h>
+ #include <asm/timex.h>
++#include <asm/param.h>		/* HZ */
+ 
+ #define _F(r,f,a,b)							\
+ 	r __platform_##f a b;                                   	\
+diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
+--- a/arch/xtensa/kernel/ptrace.c
++++ b/arch/xtensa/kernel/ptrace.c
+@@ -45,7 +45,7 @@ void ptrace_disable(struct task_struct *
+ 	/* Nothing to do.. */
+ }
+ 
+-int sys_ptrace(long request, long pid, long addr, long data)
++long sys_ptrace(long request, long pid, long addr, long data)
+ {
+ 	struct task_struct *child;
+ 	int ret = -EPERM;
+diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
+--- a/arch/xtensa/kernel/time.c
++++ b/arch/xtensa/kernel/time.c
+@@ -29,9 +29,6 @@
+ 
+ extern volatile unsigned long wall_jiffies;
+ 
+-u64 jiffies_64 = INITIAL_JIFFIES;
+-EXPORT_SYMBOL(jiffies_64);
+-
+ spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+ EXPORT_SYMBOL(rtc_lock);
+ 
+diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
+--- a/arch/xtensa/platform-iss/network.c
++++ b/arch/xtensa/platform-iss/network.c
+@@ -33,6 +33,7 @@
+ #include <linux/ethtool.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/timer.h>
++#include <linux/platform_device.h>
+ 
+ #include <xtensa/simcall.h>
+ 
+diff --git a/crypto/api.c b/crypto/api.c
+--- a/crypto/api.c
++++ b/crypto/api.c
+@@ -215,7 +215,10 @@ int crypto_register_alg(struct crypto_al
+ 	if (alg->cra_alignmask & (alg->cra_alignmask + 1))
+ 		return -EINVAL;
+ 
+-	if (alg->cra_alignmask > PAGE_SIZE)
++	if (alg->cra_alignmask & alg->cra_blocksize)
++		return -EINVAL;
++
++	if (alg->cra_blocksize > PAGE_SIZE)
+ 		return -EINVAL;
+ 	
+ 	down_write(&crypto_alg_sem);
+diff --git a/crypto/hmac.c b/crypto/hmac.c
+--- a/crypto/hmac.c
++++ b/crypto/hmac.c
+@@ -18,18 +18,15 @@
+ #include <linux/mm.h>
+ #include <linux/highmem.h>
+ #include <linux/slab.h>
+-#include <asm/scatterlist.h>
++#include <linux/scatterlist.h>
+ #include "internal.h"
+ 
+ static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
+ {
+ 	struct scatterlist tmp;
+ 	
+-	tmp.page = virt_to_page(key);
+-	tmp.offset = offset_in_page(key);
+-	tmp.length = keylen;
++	sg_set_buf(&tmp, key, keylen);
+ 	crypto_digest_digest(tfm, &tmp, 1, key);
+-		
+ }
+ 
+ int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
+@@ -69,9 +66,7 @@ void crypto_hmac_init(struct crypto_tfm 
+ 	for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
+ 		ipad[i] ^= 0x36;
+ 
+-	tmp.page = virt_to_page(ipad);
+-	tmp.offset = offset_in_page(ipad);
+-	tmp.length = crypto_tfm_alg_blocksize(tfm);
++	sg_set_buf(&tmp, ipad, crypto_tfm_alg_blocksize(tfm));
+ 	
+ 	crypto_digest_init(tfm);
+ 	crypto_digest_update(tfm, &tmp, 1);
+@@ -103,16 +98,12 @@ void crypto_hmac_final(struct crypto_tfm
+ 	for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
+ 		opad[i] ^= 0x5c;
+ 
+-	tmp.page = virt_to_page(opad);
+-	tmp.offset = offset_in_page(opad);
+-	tmp.length = crypto_tfm_alg_blocksize(tfm);
++	sg_set_buf(&tmp, opad, crypto_tfm_alg_blocksize(tfm));
+ 
+ 	crypto_digest_init(tfm);
+ 	crypto_digest_update(tfm, &tmp, 1);
+ 	
+-	tmp.page = virt_to_page(out);
+-	tmp.offset = offset_in_page(out);
+-	tmp.length = crypto_tfm_alg_digestsize(tfm);
++	sg_set_buf(&tmp, out, crypto_tfm_alg_digestsize(tfm));
+ 	
+ 	crypto_digest_update(tfm, &tmp, 1);
+ 	crypto_digest_final(tfm, out);
+diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
+--- a/crypto/tcrypt.c
++++ b/crypto/tcrypt.c
+@@ -21,7 +21,7 @@
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+-#include <asm/scatterlist.h>
++#include <linux/scatterlist.h>
+ #include <linux/string.h>
+ #include <linux/crypto.h>
+ #include <linux/highmem.h>
+@@ -86,7 +86,6 @@ static void hexdump(unsigned char *buf, 
+ static void test_hash(char *algo, struct hash_testvec *template,
+ 		      unsigned int tcount)
+ {
+-	char *p;
+ 	unsigned int i, j, k, temp;
+ 	struct scatterlist sg[8];
+ 	char result[64];
+@@ -116,10 +115,7 @@ static void test_hash(char *algo, struct
+ 		printk("test %u:\n", i + 1);
+ 		memset(result, 0, 64);
+ 
+-		p = hash_tv[i].plaintext;
+-		sg[0].page = virt_to_page(p);
+-		sg[0].offset = offset_in_page(p);
+-		sg[0].length = hash_tv[i].psize;
++		sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize);
+ 
+ 		crypto_digest_init(tfm);
+ 		if (tfm->crt_u.digest.dit_setkey) {
+@@ -154,10 +150,8 @@ static void test_hash(char *algo, struct
+ 				       hash_tv[i].plaintext + temp,
+ 				       hash_tv[i].tap[k]);
+ 				temp += hash_tv[i].tap[k];
+-				p = &xbuf[IDX[k]];
+-				sg[k].page = virt_to_page(p);
+-				sg[k].offset = offset_in_page(p);
+-				sg[k].length = hash_tv[i].tap[k];
++				sg_set_buf(&sg[k], &xbuf[IDX[k]],
++					    hash_tv[i].tap[k]);
+ 			}
+ 
+ 			crypto_digest_digest(tfm, sg, hash_tv[i].np, result);
+@@ -179,7 +173,6 @@ static void test_hash(char *algo, struct
+ static void test_hmac(char *algo, struct hmac_testvec *template,
+ 		      unsigned int tcount)
+ {
+-	char *p;
+ 	unsigned int i, j, k, temp;
+ 	struct scatterlist sg[8];
+ 	char result[64];
+@@ -210,11 +203,8 @@ static void test_hmac(char *algo, struct
+ 		printk("test %u:\n", i + 1);
+ 		memset(result, 0, sizeof (result));
+ 
+-		p = hmac_tv[i].plaintext;
+ 		klen = hmac_tv[i].ksize;
+-		sg[0].page = virt_to_page(p);
+-		sg[0].offset = offset_in_page(p);
+-		sg[0].length = hmac_tv[i].psize;
++		sg_set_buf(&sg[0], hmac_tv[i].plaintext, hmac_tv[i].psize);
+ 
+ 		crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result);
+ 
+@@ -243,10 +233,8 @@ static void test_hmac(char *algo, struct
+ 				       hmac_tv[i].plaintext + temp,
+ 				       hmac_tv[i].tap[k]);
+ 				temp += hmac_tv[i].tap[k];
+-				p = &xbuf[IDX[k]];
+-				sg[k].page = virt_to_page(p);
+-				sg[k].offset = offset_in_page(p);
+-				sg[k].length = hmac_tv[i].tap[k];
++				sg_set_buf(&sg[k], &xbuf[IDX[k]],
++					    hmac_tv[i].tap[k]);
+ 			}
+ 
+ 			crypto_hmac(tfm, hmac_tv[i].key, &klen, sg,
+@@ -270,7 +258,7 @@ static void test_cipher(char *algo, int 
+ {
+ 	unsigned int ret, i, j, k, temp;
+ 	unsigned int tsize;
+-	char *p, *q;
++	char *q;
+ 	struct crypto_tfm *tfm;
+ 	char *key;
+ 	struct cipher_testvec *cipher_tv;
+@@ -330,10 +318,8 @@ static void test_cipher(char *algo, int 
+ 					goto out;
+ 			}
+ 
+-			p = cipher_tv[i].input;
+-			sg[0].page = virt_to_page(p);
+-			sg[0].offset = offset_in_page(p);
+-			sg[0].length = cipher_tv[i].ilen;
++			sg_set_buf(&sg[0], cipher_tv[i].input,
++				   cipher_tv[i].ilen);
+ 
+ 			if (!mode) {
+ 				crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
+@@ -389,10 +375,8 @@ static void test_cipher(char *algo, int 
+ 				       cipher_tv[i].input + temp,
+ 				       cipher_tv[i].tap[k]);
+ 				temp += cipher_tv[i].tap[k];
+-				p = &xbuf[IDX[k]];
+-				sg[k].page = virt_to_page(p);
+-				sg[k].offset = offset_in_page(p);
+-				sg[k].length = cipher_tv[i].tap[k];
++				sg_set_buf(&sg[k], &xbuf[IDX[k]],
++					   cipher_tv[i].tap[k]);
+ 			}
+ 
+ 			if (!mode) {
+@@ -431,14 +415,12 @@ out:
+ static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
+ 			       int blen, int sec)
+ {
+-	struct scatterlist sg[8];
++	struct scatterlist sg[1];
+ 	unsigned long start, end;
+ 	int bcount;
+ 	int ret;
+ 
+-	sg[0].page = virt_to_page(p);
+-	sg[0].offset = offset_in_page(p);
+-	sg[0].length = blen;
++	sg_set_buf(sg, p, blen);
+ 
+ 	for (start = jiffies, end = start + sec * HZ, bcount = 0;
+ 	     time_before(jiffies, end); bcount++) {
+@@ -459,14 +441,12 @@ static int test_cipher_jiffies(struct cr
+ static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p,
+ 			      int blen)
+ {
+-	struct scatterlist sg[8];
++	struct scatterlist sg[1];
+ 	unsigned long cycles = 0;
+ 	int ret = 0;
+ 	int i;
+ 
+-	sg[0].page = virt_to_page(p);
+-	sg[0].offset = offset_in_page(p);
+-	sg[0].length = blen;
++	sg_set_buf(sg, p, blen);
+ 
+ 	local_bh_disable();
+ 	local_irq_disable();
+@@ -709,9 +689,7 @@ static void test_crc32c(void)
+ 	for (i = 0; i < NUMVEC; i++) {
+ 		for (j = 0; j < VECSIZE; j++)
+ 			test_vec[i][j] = ++b;
+-		sg[i].page = virt_to_page(test_vec[i]);
+-		sg[i].offset = offset_in_page(test_vec[i]);
+-		sg[i].length = VECSIZE;
++		sg_set_buf(&sg[i], test_vec[i], VECSIZE);
+ 	}
+ 
+ 	seed = SEEDTESTVAL;
+diff --git a/drivers/Makefile b/drivers/Makefile
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -5,7 +5,7 @@
+ # Rewritten to use lists instead of if-statements.
+ #
+ 
+-obj-$(CONFIG_PCI)		+= pci/
++obj-$(CONFIG_PCI)		+= pci/ usb/
+ obj-$(CONFIG_PARISC)		+= parisc/
+ obj-y				+= video/
+ obj-$(CONFIG_ACPI)		+= acpi/
+diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
+--- a/drivers/acorn/char/pcf8583.c
++++ b/drivers/acorn/char/pcf8583.c
+@@ -9,6 +9,7 @@
+  *
+  *  Driver for PCF8583 RTC & RAM chip
+  */
++#include <linux/module.h>
+ #include <linux/i2c.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
+@@ -32,7 +33,8 @@ static struct i2c_client_address_data ad
+ 	.forces			= forces,
+ };
+ 
+-#define DAT(x) ((unsigned int)(x->dev.driver_data))
++#define set_ctrl(x, v) i2c_set_clientdata(x, (void *)(unsigned int)(v))
++#define get_ctrl(x)    ((unsigned int)i2c_get_clientdata(x))
+ 
+ static int
+ pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
+@@ -40,8 +42,17 @@ pcf8583_attach(struct i2c_adapter *adap,
+ 	struct i2c_client *c;
+ 	unsigned char buf[1], ad[1] = { 0 };
+ 	struct i2c_msg msgs[2] = {
+-		{ addr, 0,        1, ad  },
+-		{ addr, I2C_M_RD, 1, buf }
++		{
++			.addr = addr,
++			.flags = 0,
++			.len = 1,
++			.buf = ad,
++		}, {
++			.addr = addr,
++			.flags = I2C_M_RD,
++			.len = 1,
++			.buf = buf,
++		}
+ 	};
+ 
+ 	c = kmalloc(sizeof(*c), GFP_KERNEL);
+@@ -54,7 +65,7 @@ pcf8583_attach(struct i2c_adapter *adap,
+ 	c->driver	= &pcf8583_driver;
+ 
+ 	if (i2c_transfer(c->adapter, msgs, 2) == 2)
+-		DAT(c) = buf[0];
++		set_ctrl(c, buf[0]);
+ 
+ 	return i2c_attach_client(c);
+ }
+@@ -78,8 +89,17 @@ pcf8583_get_datetime(struct i2c_client *
+ {
+ 	unsigned char buf[8], addr[1] = { 1 };
+ 	struct i2c_msg msgs[2] = {
+-		{ client->addr, 0,        1, addr },
+-		{ client->addr, I2C_M_RD, 6, buf  }
++		{
++			.addr = client->addr,
++			.flags = 0,
++			.len = 1,
++			.buf = addr,
++		}, {
++			.addr = client->addr,
++			.flags = I2C_M_RD,
++			.len = 6,
++			.buf = buf,
++		}
+ 	};
+ 	int ret = -EIO;
+ 
+@@ -113,7 +133,7 @@ pcf8583_set_datetime(struct i2c_client *
+ 	int ret, len = 6;
+ 
+ 	buf[0] = 0;
+-	buf[1] = DAT(client) | 0x80;
++	buf[1] = get_ctrl(client) | 0x80;
+ 	buf[2] = BIN_TO_BCD(dt->cs);
+ 	buf[3] = BIN_TO_BCD(dt->secs);
+ 	buf[4] = BIN_TO_BCD(dt->mins);
+@@ -129,7 +149,7 @@ pcf8583_set_datetime(struct i2c_client *
+ 	if (ret == len)
+ 		ret = 0;
+ 
+-	buf[1] = DAT(client);
++	buf[1] = get_ctrl(client);
+ 	i2c_master_send(client, (char *)buf, 2);
+ 
+ 	return ret;
+@@ -138,7 +158,7 @@ pcf8583_set_datetime(struct i2c_client *
+ static int
+ pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
+ {
+-	*ctrl = DAT(client);
++	*ctrl = get_ctrl(client);
+ 	return 0;
+ }
+ 
+@@ -149,7 +169,7 @@ pcf8583_set_ctrl(struct i2c_client *clie
+ 
+ 	buf[0] = 0;
+ 	buf[1] = *ctrl;
+-	DAT(client) = *ctrl;
++	set_ctrl(client, *ctrl);
+ 
+ 	return i2c_master_send(client, (char *)buf, 2);
+ }
+@@ -159,15 +179,23 @@ pcf8583_read_mem(struct i2c_client *clie
+ {
+ 	unsigned char addr[1];
+ 	struct i2c_msg msgs[2] = {
+-		{ client->addr, 0,        1, addr },
+-		{ client->addr, I2C_M_RD, 0, mem->data }
++		{
++			.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;
+-	msgs[1].len = mem->nr;
+ 
+ 	return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
+ }
+@@ -177,15 +205,23 @@ pcf8583_write_mem(struct i2c_client *cli
+ {
+ 	unsigned char addr[1];
+ 	struct i2c_msg msgs[2] = {
+-		{ client->addr, 0, 1, addr },
+-		{ client->addr, 0, 0, mem->data }
++		{
++			.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;
+-	msgs[1].len = mem->nr;
+ 
+ 	return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
+ }
+@@ -234,4 +270,14 @@ static __init int pcf8583_init(void)
+ 	return i2c_add_driver(&pcf8583_driver);
+ }
+ 
+-__initcall(pcf8583_init);
++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/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
+--- a/drivers/acpi/acpi_memhotplug.c
++++ b/drivers/acpi/acpi_memhotplug.c
+@@ -200,8 +200,7 @@ static int acpi_memory_enable_device(str
+ 	 * Note: Assume that this function returns zero on success
+ 	 */
+ 	result = add_memory(mem_device->start_addr,
+-			    (mem_device->end_addr - mem_device->start_addr) + 1,
+-			    mem_device->read_write_attribute);
++			    (mem_device->end_addr - mem_device->start_addr) + 1);
+ 	if (result) {
+ 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "\nadd_memory failed\n"));
+ 		mem_device->state = MEMORY_INVALID_STATE;
+@@ -259,7 +258,7 @@ static int acpi_memory_disable_device(st
+ 	 * Ask the VM to offline this memory range.
+ 	 * Note: Assume that this function returns zero on success
+ 	 */
+-	result = remove_memory(start, len, attr);
++	result = remove_memory(start, len);
+ 	if (result) {
+ 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Hot-Remove failed.\n"));
+ 		return_VALUE(result);
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -37,6 +37,7 @@
+ #include <linux/acpi.h>
+ #include <linux/dmi.h>
+ #include <linux/moduleparam.h>
++#include <linux/sched.h>	/* need_resched() */
+ 
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
+--- a/drivers/acpi/sleep/main.c
++++ b/drivers/acpi/sleep/main.c
+@@ -158,7 +158,15 @@ int acpi_suspend(u32 acpi_state)
+ 	return -EINVAL;
+ }
+ 
++static int acpi_pm_state_valid(suspend_state_t pm_state)
++{
++	u32 acpi_state = acpi_suspend_states[pm_state];
++
++	return sleep_states[acpi_state];
++}
++
+ static struct pm_ops acpi_pm_ops = {
++	.valid = acpi_pm_state_valid,
+ 	.prepare = acpi_pm_prepare,
+ 	.enter = acpi_pm_enter,
+ 	.finish = acpi_pm_finish,
+diff --git a/drivers/base/Makefile b/drivers/base/Makefile
+--- a/drivers/base/Makefile
++++ b/drivers/base/Makefile
+@@ -7,6 +7,7 @@ obj-y			:= core.o sys.o bus.o dd.o \
+ obj-y			+= power/
+ obj-$(CONFIG_FW_LOADER)	+= firmware_class.o
+ obj-$(CONFIG_NUMA)	+= node.o
++obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o
+ 
+ ifeq ($(CONFIG_DEBUG_DRIVER),y)
+ EXTRA_CFLAGS += -DDEBUG
+diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
+--- a/drivers/base/attribute_container.c
++++ b/drivers/base/attribute_container.c
+@@ -19,6 +19,8 @@
+ #include <linux/list.h>
+ #include <linux/module.h>
+ 
++#include "base.h"
++
+ /* This is a private structure used to tie the classdev and the
+  * container .. it should never be visible outside this file */
+ struct internal_container {
+diff --git a/drivers/base/base.h b/drivers/base/base.h
+--- a/drivers/base/base.h
++++ b/drivers/base/base.h
+@@ -1,3 +1,15 @@
++
++/* initialisation functions */
++
++extern int devices_init(void);
++extern int buses_init(void);
++extern int classes_init(void);
++extern int firmware_init(void);
++extern int platform_bus_init(void);
++extern int system_bus_init(void);
++extern int cpu_dev_init(void);
++extern int attribute_container_init(void);
++
+ extern int bus_add_device(struct device * dev);
+ extern void bus_remove_device(struct device * dev);
+ 
+diff --git a/drivers/base/class.c b/drivers/base/class.c
+--- a/drivers/base/class.c
++++ b/drivers/base/class.c
+@@ -17,6 +17,7 @@
+ #include <linux/string.h>
+ #include <linux/kdev_t.h>
+ #include <linux/err.h>
++#include <linux/slab.h>
+ #include "base.h"
+ 
+ #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
+@@ -99,7 +100,8 @@ struct class * class_get(struct class * 
+ 
+ void class_put(struct class * cls)
+ {
+-	subsys_put(&cls->subsys);
++	if (cls)
++		subsys_put(&cls->subsys);
+ }
+ 
+ 
+@@ -165,14 +167,25 @@ void class_unregister(struct class * cls
+ 
+ static void class_create_release(struct class *cls)
+ {
++	pr_debug("%s called for %s\n", __FUNCTION__, cls->name);
+ 	kfree(cls);
+ }
+ 
+ static void class_device_create_release(struct class_device *class_dev)
+ {
++	pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
+ 	kfree(class_dev);
+ }
+ 
++/* needed to allow these devices to have parent class devices */
++static int class_device_create_hotplug(struct class_device *class_dev,
++				       char **envp, int num_envp,
++				       char *buffer, int buffer_size)
++{
++	pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
++	return 0;
++}
++
+ /**
+  * class_create - create a struct class structure
+  * @owner: pointer to the module that is to "own" this struct class
+@@ -301,10 +314,12 @@ static void class_dev_release(struct kob
+ 	kfree(cd->devt_attr);
+ 	cd->devt_attr = NULL;
+ 
+-	if (cls->release)
++	if (cd->release)
++		cd->release(cd);
++	else if (cls->release)
+ 		cls->release(cd);
+ 	else {
+-		printk(KERN_ERR "Device class '%s' does not have a release() function, "
++		printk(KERN_ERR "Class Device '%s' does not have a release() function, "
+ 			"it is broken and must be fixed.\n",
+ 			cd->class_id);
+ 		WARN_ON(1);
+@@ -382,14 +397,18 @@ static int class_hotplug(struct kset *ks
+ 	buffer = &buffer[length];
+ 	buffer_size -= length;
+ 
+-	if (class_dev->class->hotplug) {
+-		/* have the bus specific function add its stuff */
+-		retval = class_dev->class->hotplug (class_dev, envp, num_envp,
+-						    buffer, buffer_size);
+-			if (retval) {
+-			pr_debug ("%s - hotplug() returned %d\n",
+-				  __FUNCTION__, retval);
+-		}
++	if (class_dev->hotplug) {
++		/* have the class device specific function add its stuff */
++		retval = class_dev->hotplug(class_dev, envp, num_envp,
++					    buffer, buffer_size);
++		if (retval)
++			pr_debug("class_dev->hotplug() returned %d\n", retval);
++	} else if (class_dev->class->hotplug) {
++		/* have the class specific function add its stuff */
++		retval = class_dev->class->hotplug(class_dev, envp, num_envp,
++						   buffer, buffer_size);
++		if (retval)
++			pr_debug("class->hotplug() returned %d\n", retval);
+ 	}
+ 
+ 	return retval;
+@@ -442,6 +461,13 @@ static ssize_t show_dev(struct class_dev
+ 	return print_dev_t(buf, class_dev->devt);
+ }
+ 
++static ssize_t store_uevent(struct class_device *class_dev,
++			    const char *buf, size_t count)
++{
++	kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
++	return count;
++}
++
+ void class_device_initialize(struct class_device *class_dev)
+ {
+ 	kobj_set_kset_s(class_dev, class_obj_subsys);
+@@ -469,34 +495,45 @@ static char *make_class_name(struct clas
+ 
+ int class_device_add(struct class_device *class_dev)
+ {
+-	struct class * parent = NULL;
+-	struct class_interface * class_intf;
++	struct class *parent_class = NULL;
++	struct class_device *parent_class_dev = NULL;
++	struct class_interface *class_intf;
+ 	char *class_name = NULL;
+-	int error;
++	int error = -EINVAL;
+ 
+ 	class_dev = class_device_get(class_dev);
+ 	if (!class_dev)
+ 		return -EINVAL;
+ 
+-	if (!strlen(class_dev->class_id)) {
+-		error = -EINVAL;
++	if (!strlen(class_dev->class_id))
+ 		goto register_done;
+-	}
+ 
+-	parent = class_get(class_dev->class);
++	parent_class = class_get(class_dev->class);
++	if (!parent_class)
++		goto register_done;
++	parent_class_dev = class_device_get(class_dev->parent);
+ 
+ 	pr_debug("CLASS: registering class device: ID = '%s'\n",
+ 		 class_dev->class_id);
+ 
+ 	/* first, register with generic layer. */
+ 	kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
+-	if (parent)
+-		class_dev->kobj.parent = &parent->subsys.kset.kobj;
++	if (parent_class_dev)
++		class_dev->kobj.parent = &parent_class_dev->kobj;
++	else
++		class_dev->kobj.parent = &parent_class->subsys.kset.kobj;
+ 
+-	if ((error = kobject_add(&class_dev->kobj)))
++	error = kobject_add(&class_dev->kobj);
++	if (error)
+ 		goto register_done;
+ 
+ 	/* add the needed attributes to this device */
++	class_dev->uevent_attr.attr.name = "uevent";
++	class_dev->uevent_attr.attr.mode = S_IWUSR;
++	class_dev->uevent_attr.attr.owner = parent_class->owner;
++	class_dev->uevent_attr.store = store_uevent;
++	class_device_create_file(class_dev, &class_dev->uevent_attr);
++
+ 	if (MAJOR(class_dev->devt)) {
+ 		struct class_device_attribute *attr;
+ 		attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+@@ -505,12 +542,10 @@ int class_device_add(struct class_device
+ 			kobject_del(&class_dev->kobj);
+ 			goto register_done;
+ 		}
+-
+ 		attr->attr.name = "dev";
+ 		attr->attr.mode = S_IRUGO;
+-		attr->attr.owner = parent->owner;
++		attr->attr.owner = parent_class->owner;
+ 		attr->show = show_dev;
+-		attr->store = NULL;
+ 		class_device_create_file(class_dev, attr);
+ 		class_dev->devt_attr = attr;
+ 	}
+@@ -524,20 +559,23 @@ int class_device_add(struct class_device
+ 				  class_name);
+ 	}
+ 
++	kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
++
+ 	/* notify any interfaces this device is now here */
+-	if (parent) {
+-		down(&parent->sem);
+-		list_add_tail(&class_dev->node, &parent->children);
+-		list_for_each_entry(class_intf, &parent->interfaces, node)
++	if (parent_class) {
++		down(&parent_class->sem);
++		list_add_tail(&class_dev->node, &parent_class->children);
++		list_for_each_entry(class_intf, &parent_class->interfaces, node)
+ 			if (class_intf->add)
+-				class_intf->add(class_dev);
+-		up(&parent->sem);
++				class_intf->add(class_dev, class_intf);
++		up(&parent_class->sem);
+ 	}
+-	kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+ 
+  register_done:
+-	if (error && parent)
+-		class_put(parent);
++	if (error) {
++		class_put(parent_class);
++		class_device_put(parent_class_dev);
++	}
+ 	class_device_put(class_dev);
+ 	kfree(class_name);
+ 	return error;
+@@ -552,21 +590,28 @@ int class_device_register(struct class_d
+ /**
+  * class_device_create - creates a class device and registers it with sysfs
+  * @cs: pointer to the struct class that this device should be registered to.
++ * @parent: pointer to the parent struct class_device of this new device, if any.
+  * @dev: the dev_t for the char device to be added.
+  * @device: a pointer to a struct device that is assiociated with this class device.
+  * @fmt: string for the class device's name
+  *
+  * This function can be used by char device classes.  A struct
+  * class_device will be created in sysfs, registered to the specified
+- * class.  A "dev" file will be created, showing the dev_t for the
+- * device.  The pointer to the struct class_device will be returned from
+- * the call.  Any further sysfs files that might be required can be
+- * created using this pointer.
++ * class.
++ * A "dev" file will be created, showing the dev_t for the device, if
++ * the dev_t is not 0,0.
++ * If a pointer to a parent struct class_device is passed in, the newly
++ * created struct class_device will be a child of that device in sysfs.
++ * The pointer to the struct class_device will be returned from the
++ * call.  Any further sysfs files that might be required can be created
++ * using this pointer.
+  *
+  * Note: the struct class passed to this function must have previously
+  * been created with a call to class_create().
+  */
+-struct class_device *class_device_create(struct class *cls, dev_t devt,
++struct class_device *class_device_create(struct class *cls,
++					 struct class_device *parent,
++					 dev_t devt,
+ 					 struct device *device, char *fmt, ...)
+ {
+ 	va_list args;
+@@ -585,6 +630,9 @@ struct class_device *class_device_create
+ 	class_dev->devt = devt;
+ 	class_dev->dev = device;
+ 	class_dev->class = cls;
++	class_dev->parent = parent;
++	class_dev->release = class_device_create_release;
++	class_dev->hotplug = class_device_create_hotplug;
+ 
+ 	va_start(args, fmt);
+ 	vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
+@@ -602,17 +650,18 @@ error:
+ 
+ void class_device_del(struct class_device *class_dev)
+ {
+-	struct class * parent = class_dev->class;
+-	struct class_interface * class_intf;
++	struct class *parent_class = class_dev->class;
++	struct class_device *parent_device = class_dev->parent;
++	struct class_interface *class_intf;
+ 	char *class_name = NULL;
+ 
+-	if (parent) {
+-		down(&parent->sem);
++	if (parent_class) {
++		down(&parent_class->sem);
+ 		list_del_init(&class_dev->node);
+-		list_for_each_entry(class_intf, &parent->interfaces, node)
++		list_for_each_entry(class_intf, &parent_class->interfaces, node)
+ 			if (class_intf->remove)
+-				class_intf->remove(class_dev);
+-		up(&parent->sem);
++				class_intf->remove(class_dev, class_intf);
++		up(&parent_class->sem);
+ 	}
+ 
+ 	if (class_dev->dev) {
+@@ -620,6 +669,7 @@ void class_device_del(struct class_devic
+ 		sysfs_remove_link(&class_dev->kobj, "device");
+ 		sysfs_remove_link(&class_dev->dev->kobj, class_name);
+ 	}
++	class_device_remove_file(class_dev, &class_dev->uevent_attr);
+ 	if (class_dev->devt_attr)
+ 		class_device_remove_file(class_dev, class_dev->devt_attr);
+ 	class_device_remove_attrs(class_dev);
+@@ -627,8 +677,8 @@ void class_device_del(struct class_devic
+ 	kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
+ 	kobject_del(&class_dev->kobj);
+ 
+-	if (parent)
+-		class_put(parent);
++	class_device_put(parent_device);
++	class_put(parent_class);
+ 	kfree(class_name);
+ }
+ 
+@@ -708,7 +758,8 @@ struct class_device * class_device_get(s
+ 
+ void class_device_put(struct class_device *class_dev)
+ {
+-	kobject_put(&class_dev->kobj);
++	if (class_dev)
++		kobject_put(&class_dev->kobj);
+ }
+ 
+ 
+@@ -728,7 +779,7 @@ int class_interface_register(struct clas
+ 	list_add_tail(&class_intf->node, &parent->interfaces);
+ 	if (class_intf->add) {
+ 		list_for_each_entry(class_dev, &parent->children, node)
+-			class_intf->add(class_dev);
++			class_intf->add(class_dev, class_intf);
+ 	}
+ 	up(&parent->sem);
+ 
+@@ -747,7 +798,7 @@ void class_interface_unregister(struct c
+ 	list_del_init(&class_intf->node);
+ 	if (class_intf->remove) {
+ 		list_for_each_entry(class_dev, &parent->children, node)
+-			class_intf->remove(class_dev);
++			class_intf->remove(class_dev, class_intf);
+ 	}
+ 	up(&parent->sem);
+ 
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -154,6 +154,13 @@ static struct kset_hotplug_ops device_ho
+ 	.hotplug =	dev_hotplug,
+ };
+ 
++static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
++			    const char *buf, size_t count)
++{
++	kobject_hotplug(&dev->kobj, KOBJ_ADD);
++	return count;
++}
++
+ /**
+  *	device_subsys - structure to be registered with kobject core.
+  */
+@@ -225,6 +232,7 @@ void device_initialize(struct device *de
+ 		   klist_children_put);
+ 	INIT_LIST_HEAD(&dev->dma_pools);
+ 	init_MUTEX(&dev->sem);
++	device_init_wakeup(dev, 0);
+ }
+ 
+ /**
+@@ -258,6 +266,14 @@ int device_add(struct device *dev)
+ 
+ 	if ((error = kobject_add(&dev->kobj)))
+ 		goto Error;
++
++	dev->uevent_attr.attr.name = "uevent";
++	dev->uevent_attr.attr.mode = S_IWUSR;
++	if (dev->driver)
++		dev->uevent_attr.attr.owner = dev->driver->owner;
++	dev->uevent_attr.store = store_uevent;
++	device_create_file(dev, &dev->uevent_attr);
++
+ 	kobject_hotplug(&dev->kobj, KOBJ_ADD);
+ 	if ((error = device_pm_add(dev)))
+ 		goto PMError;
+@@ -349,6 +365,7 @@ void device_del(struct device * dev)
+ 
+ 	if (parent)
+ 		klist_del(&dev->knode_parent);
++	device_remove_file(dev, &dev->uevent_attr);
+ 
+ 	/* Notify the platform of the removal, in case they
+ 	 * need to do anything...
+@@ -390,11 +407,11 @@ static struct device * next_device(struc
+ 
+ /**
+  *	device_for_each_child - device child iterator.
+- *	@dev:	parent struct device.
++ *	@parent: parent struct device.
+  *	@data:	data for the callback.
+  *	@fn:	function to be called for each device.
+  *
+- *	Iterate over @dev's child devices, and call @fn for each,
++ *	Iterate over @parent's child devices, and call @fn for each,
+  *	passing it @data.
+  *
+  *	We check the return of @fn each time. If it returns anything
+diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -9,12 +9,15 @@
+ #include <linux/topology.h>
+ #include <linux/device.h>
+ 
++#include "base.h"
+ 
+ struct sysdev_class cpu_sysdev_class = {
+ 	set_kset_name("cpu"),
+ };
+ EXPORT_SYMBOL(cpu_sysdev_class);
+ 
++static struct sys_device *cpu_sys_devices[NR_CPUS];
++
+ #ifdef CONFIG_HOTPLUG_CPU
+ int __attribute__((weak)) smp_prepare_cpu (int cpu)
+ {
+@@ -63,6 +66,7 @@ static void __devinit register_cpu_contr
+ }
+ void unregister_cpu(struct cpu *cpu, struct node *root)
+ {
++	int logical_cpu = cpu->sysdev.id;
+ 
+ 	if (root)
+ 		sysfs_remove_link(&root->sysdev.kobj,
+@@ -70,7 +74,7 @@ void unregister_cpu(struct cpu *cpu, str
+ 	sysdev_remove_file(&cpu->sysdev, &attr_online);
+ 
+ 	sysdev_unregister(&cpu->sysdev);
+-
++	cpu_sys_devices[logical_cpu] = NULL;
+ 	return;
+ }
+ #else /* ... !CONFIG_HOTPLUG_CPU */
+@@ -102,10 +106,19 @@ int __devinit register_cpu(struct cpu *c
+ 					  kobject_name(&cpu->sysdev.kobj));
+ 	if (!error && !cpu->no_control)
+ 		register_cpu_control(cpu);
++	if (!error)
++		cpu_sys_devices[num] = &cpu->sysdev;
+ 	return error;
+ }
+ 
+-
++struct sys_device *get_cpu_sysdev(int cpu)
++{
++	if (cpu < NR_CPUS)
++		return cpu_sys_devices[cpu];
++	else
++		return NULL;
++}
++EXPORT_SYMBOL_GPL(get_cpu_sysdev);
+ 
+ int __init cpu_dev_init(void)
+ {
+diff --git a/drivers/base/driver.c b/drivers/base/driver.c
+--- a/drivers/base/driver.c
++++ b/drivers/base/driver.c
+@@ -28,6 +28,7 @@ static struct device * next_device(struc
+ /**
+  *	driver_for_each_device - Iterator for devices bound to a driver.
+  *	@drv:	Driver we're iterating.
++ *	@start: Device to begin with
+  *	@data:	Data to pass to the callback.
+  *	@fn:	Function to call for each device.
+  *
+@@ -57,7 +58,7 @@ EXPORT_SYMBOL_GPL(driver_for_each_device
+ 
+ /**
+  * driver_find_device - device iterator for locating a particular device.
+- * @driver: The device's driver
++ * @drv: The device's driver
+  * @start: Device to begin with
+  * @data: Data to pass to match function
+  * @match: Callback function to check device
+diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c
+--- a/drivers/base/firmware.c
++++ b/drivers/base/firmware.c
+@@ -11,6 +11,9 @@
+ #include <linux/kobject.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/device.h>
++
++#include "base.h"
+ 
+ static decl_subsys(firmware, NULL, NULL);
+ 
+diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
+--- a/drivers/base/firmware_class.c
++++ b/drivers/base/firmware_class.c
+@@ -62,14 +62,16 @@ firmware_timeout_show(struct class *clas
+ }
+ 
+ /**
+- * firmware_timeout_store:
+- * Description:
++ * firmware_timeout_store - set number of seconds to wait for firmware
++ * @class: device class pointer
++ * @buf: buffer to scan for timeout value
++ * @count: number of bytes in @buf
++ *
+  *	Sets the number of seconds to wait for the firmware.  Once
+- *	this expires an error will be return to the driver and no
++ *	this expires an error will be returned to the driver and no
+  *	firmware will be provided.
+  *
+- *	Note: zero means 'wait for ever'
+- *
++ *	Note: zero means 'wait forever'.
+  **/
+ static ssize_t
+ firmware_timeout_store(struct class *class, const char *buf, size_t count)
+@@ -123,12 +125,15 @@ firmware_loading_show(struct class_devic
+ }
+ 
+ /**
+- * firmware_loading_store: - loading control file
+- * Description:
++ * firmware_loading_store - set value in the 'loading' control file
++ * @class_dev: class_device pointer
++ * @buf: buffer to scan for loading control value
++ * @count: number of bytes in @buf
++ *
+  *	The relevant values are:
+  *
+  *	 1: Start a load, discarding any previous partial load.
+- *	 0: Conclude the load and handle the data to the driver code.
++ *	 0: Conclude the load and hand the data to the driver code.
+  *	-1: Conclude the load with an error and discard any written data.
+  **/
+ static ssize_t
+@@ -201,6 +206,7 @@ out:
+ 	up(&fw_lock);
+ 	return ret_count;
+ }
++
+ static int
+ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
+ {
+@@ -227,11 +233,13 @@ fw_realloc_buffer(struct firmware_priv *
+ }
+ 
+ /**
+- * firmware_data_write:
++ * firmware_data_write - write method for firmware
++ * @kobj: kobject for the class_device
++ * @buffer: buffer being written
++ * @offset: buffer offset for write in total data store area
++ * @count: buffer size
+  *
+- * Description:
+- *
+- *	Data written to the 'data' attribute will be later handled to
++ *	Data written to the 'data' attribute will be later handed to
+  *	the driver as a firmware image.
+  **/
+ static ssize_t
+@@ -264,6 +272,7 @@ out:
+ 	up(&fw_lock);
+ 	return retval;
+ }
++
+ static struct bin_attribute firmware_attr_data_tmpl = {
+ 	.attr = {.name = "data", .mode = 0644, .owner = THIS_MODULE},
+ 	.size = 0,
+@@ -448,13 +457,16 @@ out:
+ 
+ /**
+  * request_firmware: - request firmware to hotplug and wait for it
+- * Description:
+- *      @firmware will be used to return a firmware image by the name
++ * @firmware_p: pointer to firmware image
++ * @name: name of firmware file
++ * @device: device for which firmware is being loaded
++ *
++ *      @firmware_p will be used to return a firmware image by the name
+  *      of @name for device @device.
+  *
+  *      Should be called from user context where sleeping is allowed.
+  *
+- *      @name will be use as $FIRMWARE in the hotplug environment and
++ *      @name will be used as $FIRMWARE in the hotplug environment and
+  *      should be distinctive enough not to be confused with any other
+  *      firmware image for this or any other device.
+  **/
+@@ -468,6 +480,7 @@ request_firmware(const struct firmware *
+ 
+ /**
+  * release_firmware: - release the resource associated with a firmware image
++ * @fw: firmware resource to release
+  **/
+ void
+ release_firmware(const struct firmware *fw)
+@@ -480,8 +493,10 @@ release_firmware(const struct firmware *
+ 
+ /**
+  * register_firmware: - provide a firmware image for later usage
++ * @name: name of firmware image file
++ * @data: buffer pointer for the firmware image
++ * @size: size of the data buffer area
+  *
+- * Description:
+  *	Make sure that @data will be available by requesting firmware @name.
+  *
+  *	Note: This will not be possible until some kind of persistence
+@@ -526,21 +541,19 @@ request_firmware_work_func(void *arg)
+ }
+ 
+ /**
+- * request_firmware_nowait:
++ * request_firmware_nowait: asynchronous version of request_firmware
++ * @module: module requesting the firmware
++ * @hotplug: invokes hotplug event to copy the firmware image if this flag
++ *	is non-zero else the firmware copy must be done manually.
++ * @name: name of firmware file
++ * @device: device for which firmware is being loaded
++ * @context: will be passed over to @cont, and
++ *	@fw may be %NULL if firmware request fails.
++ * @cont: function will be called asynchronously when the firmware
++ *	request is over.
+  *
+- * Description:
+  *	Asynchronous variant of request_firmware() for contexts where
+  *	it is not possible to sleep.
+- *
+- *      @hotplug invokes hotplug event to copy the firmware image if this flag
+- *      is non-zero else the firmware copy must be done manually.
+- *
+- *	@cont will be called asynchronously when the firmware request is over.
+- *
+- *	@context will be passed over to @cont.
+- *
+- *	@fw may be %NULL if firmware request fails.
+- *
+  **/
+ int
+ request_firmware_nowait(
+diff --git a/drivers/base/init.c b/drivers/base/init.c
+--- a/drivers/base/init.c
++++ b/drivers/base/init.c
+@@ -9,15 +9,10 @@
+ 
+ #include <linux/device.h>
+ #include <linux/init.h>
++#include <linux/memory.h>
++
++#include "base.h"
+ 
+-extern int devices_init(void);
+-extern int buses_init(void);
+-extern int classes_init(void);
+-extern int firmware_init(void);
+-extern int platform_bus_init(void);
+-extern int system_bus_init(void);
+-extern int cpu_dev_init(void);
+-extern int attribute_container_init(void);
+ /**
+  *	driver_init - initialize driver model.
+  *
+@@ -39,5 +34,6 @@ void __init driver_init(void)
+ 	platform_bus_init();
+ 	system_bus_init();
+ 	cpu_dev_init();
++	memory_dev_init();
+ 	attribute_container_init();
+ }
+diff --git a/drivers/base/memory.c b/drivers/base/memory.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/base/memory.c
+@@ -0,0 +1,452 @@
++/*
++ * drivers/base/memory.c - basic Memory class support
++ *
++ * Written by Matt Tolentino <matthew.e.tolentino at intel.com>
++ *            Dave Hansen <haveblue at us.ibm.com>
++ *
++ * This file provides the necessary infrastructure to represent
++ * a SPARSEMEM-memory-model system's physical memory in /sysfs.
++ * All arch-independent code that assumes MEMORY_HOTPLUG requires
++ * SPARSEMEM should be contained here, or in mm/memory_hotplug.c.
++ */
++
++#include <linux/sysdev.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/sched.h>	/* capable() */
++#include <linux/topology.h>
++#include <linux/device.h>
++#include <linux/memory.h>
++#include <linux/kobject.h>
++#include <linux/memory_hotplug.h>
++#include <linux/mm.h>
++#include <asm/atomic.h>
++#include <asm/uaccess.h>
++
++#define MEMORY_CLASS_NAME	"memory"
++
++static struct sysdev_class memory_sysdev_class = {
++	set_kset_name(MEMORY_CLASS_NAME),
++};
++EXPORT_SYMBOL(memory_sysdev_class);
++
++static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj)
++{
++	return MEMORY_CLASS_NAME;
++}
++
++static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
++			int num_envp, char *buffer, int buffer_size)
++{
++	int retval = 0;
++
++	return retval;
++}
++
++static struct kset_hotplug_ops memory_hotplug_ops = {
++	.name		= memory_hotplug_name,
++	.hotplug	= memory_hotplug,
++};
++
++static struct notifier_block *memory_chain;
++
++static int register_memory_notifier(struct notifier_block *nb)
++{
++        return notifier_chain_register(&memory_chain, nb);
++}
++
++static void unregister_memory_notifier(struct notifier_block *nb)
++{
++        notifier_chain_unregister(&memory_chain, nb);
++}
++
++/*
++ * register_memory - Setup a sysfs device for a memory block
++ */
++static int
++register_memory(struct memory_block *memory, struct mem_section *section,
++		struct node *root)
++{
++	int error;
++
++	memory->sysdev.cls = &memory_sysdev_class;
++	memory->sysdev.id = __section_nr(section);
++
++	error = sysdev_register(&memory->sysdev);
++
++	if (root && !error)
++		error = sysfs_create_link(&root->sysdev.kobj,
++					  &memory->sysdev.kobj,
++					  kobject_name(&memory->sysdev.kobj));
++
++	return error;
++}
++
++static void
++unregister_memory(struct memory_block *memory, struct mem_section *section,
++		struct node *root)
++{
++	BUG_ON(memory->sysdev.cls != &memory_sysdev_class);
++	BUG_ON(memory->sysdev.id != __section_nr(section));
++
++	sysdev_unregister(&memory->sysdev);
++	if (root)
++		sysfs_remove_link(&root->sysdev.kobj,
++				  kobject_name(&memory->sysdev.kobj));
++}
++
++/*
++ * use this as the physical section index that this memsection
++ * uses.
++ */
++
++static ssize_t show_mem_phys_index(struct sys_device *dev, char *buf)
++{
++	struct memory_block *mem =
++		container_of(dev, struct memory_block, sysdev);
++	return sprintf(buf, "%08lx\n", mem->phys_index);
++}
++
++/*
++ * online, offline, going offline, etc.
++ */
++static ssize_t show_mem_state(struct sys_device *dev, char *buf)
++{
++	struct memory_block *mem =
++		container_of(dev, struct memory_block, sysdev);
++	ssize_t len = 0;
++
++	/*
++	 * We can probably put these states in a nice little array
++	 * so that they're not open-coded
++	 */
++	switch (mem->state) {
++		case MEM_ONLINE:
++			len = sprintf(buf, "online\n");
++			break;
++		case MEM_OFFLINE:
++			len = sprintf(buf, "offline\n");
++			break;
++		case MEM_GOING_OFFLINE:
++			len = sprintf(buf, "going-offline\n");
++			break;
++		default:
++			len = sprintf(buf, "ERROR-UNKNOWN-%ld\n",
++					mem->state);
++			WARN_ON(1);
++			break;
++	}
++
++	return len;
++}
++
++static inline int memory_notify(unsigned long val, void *v)
++{
++	return notifier_call_chain(&memory_chain, val, v);
++}
++
++/*
++ * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
++ * OK to have direct references to sparsemem variables in here.
++ */
++static int
++memory_block_action(struct memory_block *mem, unsigned long action)
++{
++	int i;
++	unsigned long psection;
++	unsigned long start_pfn, start_paddr;
++	struct page *first_page;
++	int ret;
++	int old_state = mem->state;
++
++	psection = mem->phys_index;
++	first_page = pfn_to_page(psection << PFN_SECTION_SHIFT);
++
++	/*
++	 * The probe routines leave the pages reserved, just
++	 * as the bootmem code does.  Make sure they're still
++	 * that way.
++	 */
++	if (action == MEM_ONLINE) {
++		for (i = 0; i < PAGES_PER_SECTION; i++) {
++			if (PageReserved(first_page+i))
++				continue;
++
++			printk(KERN_WARNING "section number %ld page number %d "
++				"not reserved, was it already online? \n",
++				psection, i);
++			return -EBUSY;
++		}
++	}
++
++	switch (action) {
++		case MEM_ONLINE:
++			start_pfn = page_to_pfn(first_page);
++			ret = online_pages(start_pfn, PAGES_PER_SECTION);
++			break;
++		case MEM_OFFLINE:
++			mem->state = MEM_GOING_OFFLINE;
++			memory_notify(MEM_GOING_OFFLINE, NULL);
++			start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
++			ret = remove_memory(start_paddr,
++					    PAGES_PER_SECTION << PAGE_SHIFT);
++			if (ret) {
++				mem->state = old_state;
++				break;
++			}
++			memory_notify(MEM_MAPPING_INVALID, NULL);
++			break;
++		default:
++			printk(KERN_WARNING "%s(%p, %ld) unknown action: %ld\n",
++					__FUNCTION__, mem, action, action);
++			WARN_ON(1);
++			ret = -EINVAL;
++	}
++	/*
++	 * For now, only notify on successful memory operations
++	 */
++	if (!ret)
++		memory_notify(action, NULL);
++
++	return ret;
++}
++
++static int memory_block_change_state(struct memory_block *mem,
++		unsigned long to_state, unsigned long from_state_req)
++{
++	int ret = 0;
++	down(&mem->state_sem);
++
++	if (mem->state != from_state_req) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	ret = memory_block_action(mem, to_state);
++	if (!ret)
++		mem->state = to_state;
++
++out:
++	up(&mem->state_sem);
++	return ret;
++}
++
++static ssize_t
++store_mem_state(struct sys_device *dev, const char *buf, size_t count)
++{
++	struct memory_block *mem;
++	unsigned int phys_section_nr;
++	int ret = -EINVAL;
++
++	mem = container_of(dev, struct memory_block, sysdev);
++	phys_section_nr = mem->phys_index;
++
++	if (!valid_section_nr(phys_section_nr))
++		goto out;
++
++	if (!strncmp(buf, "online", min((int)count, 6)))
++		ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
++	else if(!strncmp(buf, "offline", min((int)count, 7)))
++		ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
++out:
++	if (ret)
++		return ret;
++	return count;
++}
++
++/*
++ * phys_device is a bad name for this.  What I really want
++ * is a way to differentiate between memory ranges that
++ * are part of physical devices that constitute
++ * a complete removable unit or fru.
++ * i.e. do these ranges belong to the same physical device,
++ * s.t. if I offline all of these sections I can then
++ * remove the physical device?
++ */
++static ssize_t show_phys_device(struct sys_device *dev, char *buf)
++{
++	struct memory_block *mem =
++		container_of(dev, struct memory_block, sysdev);
++	return sprintf(buf, "%d\n", mem->phys_device);
++}
++
++static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL);
++static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state);
++static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL);
++
++#define mem_create_simple_file(mem, attr_name)	\
++	sysdev_create_file(&mem->sysdev, &attr_##attr_name)
++#define mem_remove_simple_file(mem, attr_name)	\
++	sysdev_remove_file(&mem->sysdev, &attr_##attr_name)
++
++/*
++ * Block size attribute stuff
++ */
++static ssize_t
++print_block_size(struct class *class, char *buf)
++{
++	return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
++}
++
++static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
++
++static int block_size_init(void)
++{
++	sysfs_create_file(&memory_sysdev_class.kset.kobj,
++		&class_attr_block_size_bytes.attr);
++	return 0;
++}
++
++/*
++ * Some architectures will have custom drivers to do this, and
++ * will not need to do it from userspace.  The fake hot-add code
++ * as well as ppc64 will do all of their discovery in userspace
++ * and will require this interface.
++ */
++#ifdef CONFIG_ARCH_MEMORY_PROBE
++static ssize_t
++memory_probe_store(struct class *class, const char __user *buf, size_t count)
++{
++	u64 phys_addr;
++	int ret;
++
++	phys_addr = simple_strtoull(buf, NULL, 0);
++
++	ret = add_memory(phys_addr, PAGES_PER_SECTION << PAGE_SHIFT);
++
++	if (ret)
++		count = ret;
++
++	return count;
++}
++static CLASS_ATTR(probe, 0700, NULL, memory_probe_store);
++
++static int memory_probe_init(void)
++{
++	sysfs_create_file(&memory_sysdev_class.kset.kobj,
++		&class_attr_probe.attr);
++	return 0;
++}
++#else
++#define memory_probe_init(...)	do {} while (0)
++#endif
++
++/*
++ * Note that phys_device is optional.  It is here to allow for
++ * differentiation between which *physical* devices each
++ * section belongs to...
++ */
++
++static int add_memory_block(unsigned long node_id, struct mem_section *section,
++		     unsigned long state, int phys_device)
++{
++	struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
++	int ret = 0;
++
++	if (!mem)
++		return -ENOMEM;
++
++	mem->phys_index = __section_nr(section);
++	mem->state = state;
++	init_MUTEX(&mem->state_sem);
++	mem->phys_device = phys_device;
++
++	ret = register_memory(mem, section, NULL);
++	if (!ret)
++		ret = mem_create_simple_file(mem, phys_index);
++	if (!ret)
++		ret = mem_create_simple_file(mem, state);
++	if (!ret)
++		ret = mem_create_simple_file(mem, phys_device);
++
++	return ret;
++}
++
++/*
++ * For now, we have a linear search to go find the appropriate
++ * memory_block corresponding to a particular phys_index. If
++ * this gets to be a real problem, we can always use a radix
++ * tree or something here.
++ *
++ * This could be made generic for all sysdev classes.
++ */
++static struct memory_block *find_memory_block(struct mem_section *section)
++{
++	struct kobject *kobj;
++	struct sys_device *sysdev;
++	struct memory_block *mem;
++	char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
++
++	/*
++	 * This only works because we know that section == sysdev->id
++	 * slightly redundant with sysdev_register()
++	 */
++	sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section));
++
++	kobj = kset_find_obj(&memory_sysdev_class.kset, name);
++	if (!kobj)
++		return NULL;
++
++	sysdev = container_of(kobj, struct sys_device, kobj);
++	mem = container_of(sysdev, struct memory_block, sysdev);
++
++	return mem;
++}
++
++int remove_memory_block(unsigned long node_id, struct mem_section *section,
++		int phys_device)
++{
++	struct memory_block *mem;
++
++	mem = find_memory_block(section);
++	mem_remove_simple_file(mem, phys_index);
++	mem_remove_simple_file(mem, state);
++	mem_remove_simple_file(mem, phys_device);
++	unregister_memory(mem, section, NULL);
++
++	return 0;
++}
++
++/*
++ * need an interface for the VM to add new memory regions,
++ * but without onlining it.
++ */
++int register_new_memory(struct mem_section *section)
++{
++	return add_memory_block(0, section, MEM_OFFLINE, 0);
++}
++
++int unregister_memory_section(struct mem_section *section)
++{
++	if (!valid_section(section))
++		return -EINVAL;
++
++	return remove_memory_block(0, section, 0);
++}
++
++/*
++ * Initialize the sysfs support for memory devices...
++ */
++int __init memory_dev_init(void)
++{
++	unsigned int i;
++	int ret;
++
++	memory_sysdev_class.kset.hotplug_ops = &memory_hotplug_ops;
++	ret = sysdev_class_register(&memory_sysdev_class);
++
++	/*
++	 * Create entries for memory sections that were found
++	 * during boot and have been initialized
++	 */
++	for (i = 0; i < NR_MEM_SECTIONS; i++) {
++		if (!valid_section_nr(i))
++			continue;
++		add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0);
++	}
++
++	memory_probe_init();
++	block_size_init();
++
++	return ret;
++}
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -10,12 +10,15 @@
+  * information.
+  */
+ 
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/bootmem.h>
+ #include <linux/err.h>
++#include <linux/slab.h>
++
++#include "base.h"
+ 
+ struct device platform_bus = {
+ 	.bus_id		= "platform",
+@@ -279,13 +282,9 @@ static int platform_suspend(struct devic
+ {
+ 	int ret = 0;
+ 
+-	if (dev->driver && dev->driver->suspend) {
+-		ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE);
+-		if (ret == 0)
+-			ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE);
+-		if (ret == 0)
+-			ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
+-	}
++	if (dev->driver && dev->driver->suspend)
++		ret = dev->driver->suspend(dev, state);
++
+ 	return ret;
+ }
+ 
+@@ -293,13 +292,9 @@ static int platform_resume(struct device
+ {
+ 	int ret = 0;
+ 
+-	if (dev->driver && dev->driver->resume) {
+-		ret = dev->driver->resume(dev, RESUME_POWER_ON);
+-		if (ret == 0)
+-			ret = dev->driver->resume(dev, RESUME_RESTORE_STATE);
+-		if (ret == 0)
+-			ret = dev->driver->resume(dev, RESUME_ENABLE);
+-	}
++	if (dev->driver && dev->driver->resume)
++		ret = dev->driver->resume(dev);
++
+ 	return ret;
+ }
+ 
+diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
+--- a/drivers/base/power/main.c
++++ b/drivers/base/power/main.c
+@@ -30,23 +30,6 @@ LIST_HEAD(dpm_off_irq);
+ DECLARE_MUTEX(dpm_sem);
+ DECLARE_MUTEX(dpm_list_sem);
+ 
+-/*
+- * PM Reference Counting.
+- */
+-
+-static inline void device_pm_hold(struct device * dev)
+-{
+-	if (dev)
+-		atomic_inc(&dev->power.pm_users);
+-}
+-
+-static inline void device_pm_release(struct device * dev)
+-{
+-	if (dev)
+-		atomic_dec(&dev->power.pm_users);
+-}
+-
+-
+ /**
+  *	device_pm_set_parent - Specify power dependency.
+  *	@dev:		Device who needs power.
+@@ -62,10 +45,8 @@ static inline void device_pm_release(str
+ 
+ void device_pm_set_parent(struct device * dev, struct device * parent)
+ {
+-	struct device * old_parent = dev->power.pm_parent;
+-	device_pm_release(old_parent);
+-	dev->power.pm_parent = parent;
+-	device_pm_hold(parent);
++	put_device(dev->power.pm_parent);
++	dev->power.pm_parent = get_device(parent);
+ }
+ EXPORT_SYMBOL_GPL(device_pm_set_parent);
+ 
+@@ -75,7 +56,6 @@ int device_pm_add(struct device * dev)
+ 
+ 	pr_debug("PM: Adding info for %s:%s\n",
+ 		 dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
+-	atomic_set(&dev->power.pm_users, 0);
+ 	down(&dpm_list_sem);
+ 	list_add_tail(&dev->power.entry, &dpm_active);
+ 	device_pm_set_parent(dev, dev->parent);
+@@ -91,7 +71,7 @@ void device_pm_remove(struct device * de
+ 		 dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
+ 	down(&dpm_list_sem);
+ 	dpm_sysfs_remove(dev);
+-	device_pm_release(dev->power.pm_parent);
++	put_device(dev->power.pm_parent);
+ 	list_del_init(&dev->power.entry);
+ 	up(&dpm_list_sem);
+ }
+diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
+--- a/drivers/base/power/power.h
++++ b/drivers/base/power/power.h
+@@ -67,9 +67,6 @@ extern int suspend_device(struct device 
+  * runtime.c
+  */
+ 
+-extern int dpm_runtime_suspend(struct device *, pm_message_t);
+-extern void dpm_runtime_resume(struct device *);
+-
+ #else /* CONFIG_PM */
+ 
+ 
+@@ -82,14 +79,4 @@ static inline void device_pm_remove(stru
+ 
+ }
+ 
+-static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state)
+-{
+-	return 0;
+-}
+-
+-static inline void dpm_runtime_resume(struct device * dev)
+-{
+-
+-}
+-
+ #endif
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -36,6 +36,7 @@ void dpm_runtime_resume(struct device * 
+ 	runtime_resume(dev);
+ 	up(&dpm_sem);
+ }
++EXPORT_SYMBOL(dpm_runtime_resume);
+ 
+ 
+ /**
+diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
+--- a/drivers/base/power/sysfs.c
++++ b/drivers/base/power/sysfs.c
+@@ -48,8 +48,81 @@ static ssize_t state_store(struct device
+ static DEVICE_ATTR(state, 0644, state_show, state_store);
+ 
+ 
++/*
++ *	wakeup - Report/change current wakeup option for device
++ *
++ *	Some devices support "wakeup" events, which are hardware signals
++ *	used to activate devices from suspended or low power states.  Such
++ *	devices have one of three values for the sysfs power/wakeup file:
++ *
++ *	 + "enabled\n" to issue the events;
++ *	 + "disabled\n" not to do so; or
++ *	 + "\n" for temporary or permanent inability to issue wakeup.
++ *
++ *	(For example, unconfigured USB devices can't issue wakeups.)
++ *
++ *	Familiar examples of devices that can issue wakeup events include
++ *	keyboards and mice (both PS2 and USB styles), power buttons, modems,
++ *	"Wake-On-LAN" Ethernet links, GPIO lines, and more.  Some events
++ *	will wake the entire system from a suspend state; others may just
++ *	wake up the device (if the system as a whole is already active).
++ *	Some wakeup events use normal IRQ lines; other use special out
++ *	of band signaling.
++ *
++ *	It is the responsibility of device drivers to enable (or disable)
++ *	wakeup signaling as part of changing device power states, respecting
++ *	the policy choices provided through the driver model.
++ *
++ *	Devices may not be able to generate wakeup events from all power
++ *	states.  Also, the events may be ignored in some configurations;
++ *	for example, they might need help from other devices that aren't
++ *	active, or which may have wakeup disabled.  Some drivers rely on
++ *	wakeup events internally (unless they are disabled), keeping
++ *	their hardware in low power modes whenever they're unused.  This
++ *	saves runtime power, without requiring system-wide sleep states.
++ */
++
++static const char enabled[] = "enabled";
++static const char disabled[] = "disabled";
++
++static ssize_t
++wake_show(struct device * dev, struct device_attribute *attr, char * buf)
++{
++	return sprintf(buf, "%s\n", device_can_wakeup(dev)
++		? (device_may_wakeup(dev) ? enabled : disabled)
++		: "");
++}
++
++static ssize_t
++wake_store(struct device * dev, struct device_attribute *attr,
++	const char * buf, size_t n)
++{
++	char *cp;
++	int len = n;
++
++	if (!device_can_wakeup(dev))
++		return -EINVAL;
++
++	cp = memchr(buf, '\n', n);
++	if (cp)
++		len = cp - buf;
++	if (len == sizeof enabled - 1
++			&& strncmp(buf, enabled, sizeof enabled - 1) == 0)
++		device_set_wakeup_enable(dev, 1);
++	else if (len == sizeof disabled - 1
++			&& strncmp(buf, disabled, sizeof disabled - 1) == 0)
++		device_set_wakeup_enable(dev, 0);
++	else
++		return -EINVAL;
++	return n;
++}
++
++static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
++
++
+ static struct attribute * power_attrs[] = {
+ 	&dev_attr_state.attr,
++	&dev_attr_wakeup.attr,
+ 	NULL,
+ };
+ static struct attribute_group pm_attr_group = {
+diff --git a/drivers/base/sys.c b/drivers/base/sys.c
+--- a/drivers/base/sys.c
++++ b/drivers/base/sys.c
+@@ -21,6 +21,7 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/pm.h>
++#include <asm/semaphore.h>
+ 
+ extern struct subsystem devices_subsys;
+ 
+diff --git a/drivers/block/Kconfig.iosched b/drivers/block/Kconfig.iosched
+--- a/drivers/block/Kconfig.iosched
++++ b/drivers/block/Kconfig.iosched
+@@ -38,4 +38,32 @@ config IOSCHED_CFQ
+ 	  among all processes in the system. It should provide a fair
+ 	  working environment, suitable for desktop systems.
+ 
++choice
++	prompt "Default I/O scheduler"
++	default DEFAULT_AS
++	help
++	  Select the I/O scheduler which will be used by default for all
++	  block devices.
++
++	config DEFAULT_AS
++		bool "Anticipatory" if IOSCHED_AS
++
++	config DEFAULT_DEADLINE
++		bool "Deadline" if IOSCHED_DEADLINE
++
++	config DEFAULT_CFQ
++		bool "CFQ" if IOSCHED_CFQ
++
++	config DEFAULT_NOOP
++		bool "No-op"
++
++endchoice
++
++config DEFAULT_IOSCHED
++	string
++	default "anticipatory" if DEFAULT_AS
++	default "deadline" if DEFAULT_DEADLINE
++	default "cfq" if DEFAULT_CFQ
++	default "noop" if DEFAULT_NOOP
++
+ endmenu
+diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
+--- a/drivers/block/aoe/aoe.h
++++ b/drivers/block/aoe/aoe.h
+@@ -1,5 +1,5 @@
+ /* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+-#define VERSION "12"
++#define VERSION "14"
+ #define AOE_MAJOR 152
+ #define DEVICE_NAME "aoe"
+ 
+diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
+--- a/drivers/block/aoe/aoechr.c
++++ b/drivers/block/aoe/aoechr.c
+@@ -224,7 +224,7 @@ aoechr_init(void)
+ 		return PTR_ERR(aoe_class);
+ 	}
+ 	for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
+-		class_device_create(aoe_class,
++		class_device_create(aoe_class, NULL,
+ 					MKDEV(AOE_MAJOR, chardevs[i].minor),
+ 					NULL, chardevs[i].name);
+ 
+diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
+--- a/drivers/block/aoe/aoecmd.c
++++ b/drivers/block/aoe/aoecmd.c
+@@ -8,6 +8,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/skbuff.h>
+ #include <linux/netdevice.h>
++#include <asm/unaligned.h>
+ #include "aoe.h"
+ 
+ #define TIMERTICK (HZ / 10)
+@@ -311,16 +312,16 @@ ataid_complete(struct aoedev *d, unsigne
+ 	u16 n;
+ 
+ 	/* word 83: command set supported */
+-	n = le16_to_cpup((__le16 *) &id[83<<1]);
++	n = le16_to_cpu(get_unaligned((__le16 *) &id[83<<1]));
+ 
+ 	/* word 86: command set/feature enabled */
+-	n |= le16_to_cpup((__le16 *) &id[86<<1]);
++	n |= le16_to_cpu(get_unaligned((__le16 *) &id[86<<1]));
+ 
+ 	if (n & (1<<10)) {	/* bit 10: LBA 48 */
+ 		d->flags |= DEVFL_EXT;
+ 
+ 		/* word 100: number lba48 sectors */
+-		ssize = le64_to_cpup((__le64 *) &id[100<<1]);
++		ssize = le64_to_cpu(get_unaligned((__le64 *) &id[100<<1]));
+ 
+ 		/* set as in ide-disk.c:init_idedisk_capacity */
+ 		d->geo.cylinders = ssize;
+@@ -331,12 +332,12 @@ ataid_complete(struct aoedev *d, unsigne
+ 		d->flags &= ~DEVFL_EXT;
+ 
+ 		/* number lba28 sectors */
+-		ssize = le32_to_cpup((__le32 *) &id[60<<1]);
++		ssize = le32_to_cpu(get_unaligned((__le32 *) &id[60<<1]));
+ 
+ 		/* NOTE: obsolete in ATA 6 */
+-		d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]);
+-		d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]);
+-		d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]);
++		d->geo.cylinders = le16_to_cpu(get_unaligned((__le16 *) &id[54<<1]));
++		d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1]));
++		d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1]));
+ 	}
+ 	d->ssize = ssize;
+ 	d->geo.start = 0;
+diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
+--- a/drivers/block/as-iosched.c
++++ b/drivers/block/as-iosched.c
+@@ -98,7 +98,6 @@ struct as_data {
+ 
+ 	struct as_rq *next_arq[2];	/* next in sort order */
+ 	sector_t last_sector[2];	/* last REQ_SYNC & REQ_ASYNC sectors */
+-	struct list_head *dispatch;	/* driver dispatch queue */
+ 	struct list_head *hash;		/* request hash */
+ 
+ 	unsigned long exit_prob;	/* probability a task will exit while
+@@ -239,6 +238,25 @@ static struct io_context *as_get_io_cont
+ 	return ioc;
+ }
+ 
++static void as_put_io_context(struct as_rq *arq)
++{
++	struct as_io_context *aic;
++
++	if (unlikely(!arq->io_context))
++		return;
++
++	aic = arq->io_context->aic;
++
++	if (arq->is_sync == REQ_SYNC && aic) {
++		spin_lock(&aic->lock);
++		set_bit(AS_TASK_IORUNNING, &aic->state);
++		aic->last_end_request = jiffies;
++		spin_unlock(&aic->lock);
++	}
++
++	put_io_context(arq->io_context);
++}
++
+ /*
+  * the back merge hash support functions
+  */
+@@ -261,14 +279,6 @@ static inline void as_del_arq_hash(struc
+ 		__as_del_arq_hash(arq);
+ }
+ 
+-static void as_remove_merge_hints(request_queue_t *q, struct as_rq *arq)
+-{
+-	as_del_arq_hash(arq);
+-
+-	if (q->last_merge == arq->request)
+-		q->last_merge = NULL;
+-}
+-
+ static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq)
+ {
+ 	struct request *rq = arq->request;
+@@ -312,7 +322,7 @@ static struct request *as_find_arq_hash(
+ 		BUG_ON(!arq->on_hash);
+ 
+ 		if (!rq_mergeable(__rq)) {
+-			as_remove_merge_hints(ad->q, arq);
++			as_del_arq_hash(arq);
+ 			continue;
+ 		}
+ 
+@@ -950,23 +960,12 @@ static void as_completed_request(request
+ 
+ 	WARN_ON(!list_empty(&rq->queuelist));
+ 
+-	if (arq->state == AS_RQ_PRESCHED) {
+-		WARN_ON(arq->io_context);
+-		goto out;
+-	}
+-
+-	if (arq->state == AS_RQ_MERGED)
+-		goto out_ioc;
+-
+ 	if (arq->state != AS_RQ_REMOVED) {
+ 		printk("arq->state %d\n", arq->state);
+ 		WARN_ON(1);
+ 		goto out;
+ 	}
+ 
+-	if (!blk_fs_request(rq))
+-		goto out;
+-
+ 	if (ad->changed_batch && ad->nr_dispatched == 1) {
+ 		kblockd_schedule_work(&ad->antic_work);
+ 		ad->changed_batch = 0;
+@@ -1001,21 +1000,7 @@ static void as_completed_request(request
+ 		}
+ 	}
+ 
+-out_ioc:
+-	if (!arq->io_context)
+-		goto out;
+-
+-	if (arq->is_sync == REQ_SYNC) {
+-		struct as_io_context *aic = arq->io_context->aic;
+-		if (aic) {
+-			spin_lock(&aic->lock);
+-			set_bit(AS_TASK_IORUNNING, &aic->state);
+-			aic->last_end_request = jiffies;
+-			spin_unlock(&aic->lock);
+-		}
+-	}
+-
+-	put_io_context(arq->io_context);
++	as_put_io_context(arq);
+ out:
+ 	arq->state = AS_RQ_POSTSCHED;
+ }
+@@ -1047,73 +1032,11 @@ static void as_remove_queued_request(req
+ 		ad->next_arq[data_dir] = as_find_next_arq(ad, arq);
+ 
+ 	list_del_init(&arq->fifo);
+-	as_remove_merge_hints(q, arq);
++	as_del_arq_hash(arq);
+ 	as_del_arq_rb(ad, arq);
+ }
+ 
+ /*
+- * as_remove_dispatched_request is called to remove a request which has gone
+- * to the dispatch list.
+- */
+-static void as_remove_dispatched_request(request_queue_t *q, struct request *rq)
+-{
+-	struct as_rq *arq = RQ_DATA(rq);
+-	struct as_io_context *aic;
+-
+-	if (!arq) {
+-		WARN_ON(1);
+-		return;
+-	}
+-
+-	WARN_ON(arq->state != AS_RQ_DISPATCHED);
+-	WARN_ON(ON_RB(&arq->rb_node));
+-	if (arq->io_context && arq->io_context->aic) {
+-		aic = arq->io_context->aic;
+-		if (aic) {
+-			WARN_ON(!atomic_read(&aic->nr_dispatched));
+-			atomic_dec(&aic->nr_dispatched);
+-		}
+-	}
+-}
+-
+-/*
+- * as_remove_request is called when a driver has finished with a request.
+- * This should be only called for dispatched requests, but for some reason
+- * a POWER4 box running hwscan it does not.
+- */
+-static void as_remove_request(request_queue_t *q, struct request *rq)
+-{
+-	struct as_rq *arq = RQ_DATA(rq);
+-
+-	if (unlikely(arq->state == AS_RQ_NEW))
+-		goto out;
+-
+-	if (ON_RB(&arq->rb_node)) {
+-		if (arq->state != AS_RQ_QUEUED) {
+-			printk("arq->state %d\n", arq->state);
+-			WARN_ON(1);
+-			goto out;
+-		}
+-		/*
+-		 * We'll lose the aliased request(s) here. I don't think this
+-		 * will ever happen, but if it does, hopefully someone will
+-		 * report it.
+-		 */
+-		WARN_ON(!list_empty(&rq->queuelist));
+-		as_remove_queued_request(q, rq);
+-	} else {
+-		if (arq->state != AS_RQ_DISPATCHED) {
+-			printk("arq->state %d\n", arq->state);
+-			WARN_ON(1);
+-			goto out;
+-		}
+-		as_remove_dispatched_request(q, rq);
+-	}
+-out:
+-	arq->state = AS_RQ_REMOVED;
+-}
+-
+-/*
+  * as_fifo_expired returns 0 if there are no expired reads on the fifo,
+  * 1 otherwise.  It is ratelimited so that we only perform the check once per
+  * `fifo_expire' interval.  Otherwise a large number of expired requests
+@@ -1165,7 +1088,6 @@ static inline int as_batch_expired(struc
+ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
+ {
+ 	struct request *rq = arq->request;
+-	struct list_head *insert;
+ 	const int data_dir = arq->is_sync;
+ 
+ 	BUG_ON(!ON_RB(&arq->rb_node));
+@@ -1198,13 +1120,13 @@ static void as_move_to_dispatch(struct a
+ 	/*
+ 	 * take it off the sort and fifo list, add to dispatch queue
+ 	 */
+-	insert = ad->dispatch->prev;
+-
+ 	while (!list_empty(&rq->queuelist)) {
+ 		struct request *__rq = list_entry_rq(rq->queuelist.next);
+ 		struct as_rq *__arq = RQ_DATA(__rq);
+ 
+-		list_move_tail(&__rq->queuelist, ad->dispatch);
++		list_del(&__rq->queuelist);
++
++		elv_dispatch_add_tail(ad->q, __rq);
+ 
+ 		if (__arq->io_context && __arq->io_context->aic)
+ 			atomic_inc(&__arq->io_context->aic->nr_dispatched);
+@@ -1218,7 +1140,8 @@ static void as_move_to_dispatch(struct a
+ 	as_remove_queued_request(ad->q, rq);
+ 	WARN_ON(arq->state != AS_RQ_QUEUED);
+ 
+-	list_add(&rq->queuelist, insert);
++	elv_dispatch_sort(ad->q, rq);
++
+ 	arq->state = AS_RQ_DISPATCHED;
+ 	if (arq->io_context && arq->io_context->aic)
+ 		atomic_inc(&arq->io_context->aic->nr_dispatched);
+@@ -1230,12 +1153,42 @@ static void as_move_to_dispatch(struct a
+  * read/write expire, batch expire, etc, and moves it to the dispatch
+  * queue. Returns 1 if a request was found, 0 otherwise.
+  */
+-static int as_dispatch_request(struct as_data *ad)
++static int as_dispatch_request(request_queue_t *q, int force)
+ {
++	struct as_data *ad = q->elevator->elevator_data;
+ 	struct as_rq *arq;
+ 	const int reads = !list_empty(&ad->fifo_list[REQ_SYNC]);
+ 	const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]);
+ 
++	if (unlikely(force)) {
++		/*
++		 * Forced dispatch, accounting is useless.  Reset
++		 * accounting states and dump fifo_lists.  Note that
++		 * batch_data_dir is reset to REQ_SYNC to avoid
++		 * screwing write batch accounting as write batch
++		 * accounting occurs on W->R transition.
++		 */
++		int dispatched = 0;
++
++		ad->batch_data_dir = REQ_SYNC;
++		ad->changed_batch = 0;
++		ad->new_batch = 0;
++
++		while (ad->next_arq[REQ_SYNC]) {
++			as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
++			dispatched++;
++		}
++		ad->last_check_fifo[REQ_SYNC] = jiffies;
++
++		while (ad->next_arq[REQ_ASYNC]) {
++			as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
++			dispatched++;
++		}
++		ad->last_check_fifo[REQ_ASYNC] = jiffies;
++
++		return dispatched;
++	}
++
+ 	/* Signal that the write batch was uncontended, so we can't time it */
+ 	if (ad->batch_data_dir == REQ_ASYNC && !reads) {
+ 		if (ad->current_write_count == 0 || !writes)
+@@ -1359,20 +1312,6 @@ fifo_expired:
+ 	return 1;
+ }
+ 
+-static struct request *as_next_request(request_queue_t *q)
+-{
+-	struct as_data *ad = q->elevator->elevator_data;
+-	struct request *rq = NULL;
+-
+-	/*
+-	 * if there are still requests on the dispatch queue, grab the first
+-	 */
+-	if (!list_empty(ad->dispatch) || as_dispatch_request(ad))
+-		rq = list_entry_rq(ad->dispatch->next);
+-
+-	return rq;
+-}
+-
+ /*
+  * Add arq to a list behind alias
+  */
+@@ -1404,17 +1343,26 @@ as_add_aliased_request(struct as_data *a
+ 	/*
+ 	 * Don't want to have to handle merges.
+ 	 */
+-	as_remove_merge_hints(ad->q, arq);
++	as_del_arq_hash(arq);
++	arq->request->flags |= REQ_NOMERGE;
+ }
+ 
+ /*
+  * add arq to rbtree and fifo
+  */
+-static void as_add_request(struct as_data *ad, struct as_rq *arq)
++static void as_add_request(request_queue_t *q, struct request *rq)
+ {
++	struct as_data *ad = q->elevator->elevator_data;
++	struct as_rq *arq = RQ_DATA(rq);
+ 	struct as_rq *alias;
+ 	int data_dir;
+ 
++	if (arq->state != AS_RQ_PRESCHED) {
++		printk("arq->state: %d\n", arq->state);
++		WARN_ON(1);
++	}
++	arq->state = AS_RQ_NEW;
++
+ 	if (rq_data_dir(arq->request) == READ
+ 			|| current->flags&PF_SYNCWRITE)
+ 		arq->is_sync = 1;
+@@ -1437,12 +1385,8 @@ static void as_add_request(struct as_dat
+ 		arq->expires = jiffies + ad->fifo_expire[data_dir];
+ 		list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
+ 
+-		if (rq_mergeable(arq->request)) {
++		if (rq_mergeable(arq->request))
+ 			as_add_arq_hash(ad, arq);
+-
+-			if (!ad->q->last_merge)
+-				ad->q->last_merge = arq->request;
+-		}
+ 		as_update_arq(ad, arq); /* keep state machine up to date */
+ 
+ 	} else {
+@@ -1463,96 +1407,24 @@ static void as_add_request(struct as_dat
+ 	arq->state = AS_RQ_QUEUED;
+ }
+ 
+-static void as_deactivate_request(request_queue_t *q, struct request *rq)
++static void as_activate_request(request_queue_t *q, struct request *rq)
+ {
+-	struct as_data *ad = q->elevator->elevator_data;
+ 	struct as_rq *arq = RQ_DATA(rq);
+ 
+-	if (arq) {
+-		if (arq->state == AS_RQ_REMOVED) {
+-			arq->state = AS_RQ_DISPATCHED;
+-			if (arq->io_context && arq->io_context->aic)
+-				atomic_inc(&arq->io_context->aic->nr_dispatched);
+-		}
+-	} else
+-		WARN_ON(blk_fs_request(rq)
+-			&& (!(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) );
+-
+-	/* Stop anticipating - let this request get through */
+-	as_antic_stop(ad);
+-}
+-
+-/*
+- * requeue the request. The request has not been completed, nor is it a
+- * new request, so don't touch accounting.
+- */
+-static void as_requeue_request(request_queue_t *q, struct request *rq)
+-{
+-	as_deactivate_request(q, rq);
+-	list_add(&rq->queuelist, &q->queue_head);
+-}
+-
+-/*
+- * Account a request that is inserted directly onto the dispatch queue.
+- * arq->io_context->aic->nr_dispatched should not need to be incremented
+- * because only new requests should come through here: requeues go through
+- * our explicit requeue handler.
+- */
+-static void as_account_queued_request(struct as_data *ad, struct request *rq)
+-{
+-	if (blk_fs_request(rq)) {
+-		struct as_rq *arq = RQ_DATA(rq);
+-		arq->state = AS_RQ_DISPATCHED;
+-		ad->nr_dispatched++;
+-	}
++	WARN_ON(arq->state != AS_RQ_DISPATCHED);
++	arq->state = AS_RQ_REMOVED;
++	if (arq->io_context && arq->io_context->aic)
++		atomic_dec(&arq->io_context->aic->nr_dispatched);
+ }
+ 
+-static void
+-as_insert_request(request_queue_t *q, struct request *rq, int where)
++static void as_deactivate_request(request_queue_t *q, struct request *rq)
+ {
+-	struct as_data *ad = q->elevator->elevator_data;
+ 	struct as_rq *arq = RQ_DATA(rq);
+ 
+-	if (arq) {
+-		if (arq->state != AS_RQ_PRESCHED) {
+-			printk("arq->state: %d\n", arq->state);
+-			WARN_ON(1);
+-		}
+-		arq->state = AS_RQ_NEW;
+-	}
+-
+-	/* barriers must flush the reorder queue */
+-	if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
+-			&& where == ELEVATOR_INSERT_SORT)) {
+-		WARN_ON(1);
+-		where = ELEVATOR_INSERT_BACK;
+-	}
+-
+-	switch (where) {
+-		case ELEVATOR_INSERT_BACK:
+-			while (ad->next_arq[REQ_SYNC])
+-				as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
+-
+-			while (ad->next_arq[REQ_ASYNC])
+-				as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
+-
+-			list_add_tail(&rq->queuelist, ad->dispatch);
+-			as_account_queued_request(ad, rq);
+-			as_antic_stop(ad);
+-			break;
+-		case ELEVATOR_INSERT_FRONT:
+-			list_add(&rq->queuelist, ad->dispatch);
+-			as_account_queued_request(ad, rq);
+-			as_antic_stop(ad);
+-			break;
+-		case ELEVATOR_INSERT_SORT:
+-			BUG_ON(!blk_fs_request(rq));
+-			as_add_request(ad, arq);
+-			break;
+-		default:
+-			BUG();
+-			return;
+-	}
++	WARN_ON(arq->state != AS_RQ_REMOVED);
++	arq->state = AS_RQ_DISPATCHED;
++	if (arq->io_context && arq->io_context->aic)
++		atomic_inc(&arq->io_context->aic->nr_dispatched);
+ }
+ 
+ /*
+@@ -1565,12 +1437,8 @@ static int as_queue_empty(request_queue_
+ {
+ 	struct as_data *ad = q->elevator->elevator_data;
+ 
+-	if (!list_empty(&ad->fifo_list[REQ_ASYNC])
+-		|| !list_empty(&ad->fifo_list[REQ_SYNC])
+-		|| !list_empty(ad->dispatch))
+-			return 0;
+-
+-	return 1;
++	return list_empty(&ad->fifo_list[REQ_ASYNC])
++		&& list_empty(&ad->fifo_list[REQ_SYNC]);
+ }
+ 
+ static struct request *
+@@ -1608,15 +1476,6 @@ as_merge(request_queue_t *q, struct requ
+ 	int ret;
+ 
+ 	/*
+-	 * try last_merge to avoid going to hash
+-	 */
+-	ret = elv_try_last_merge(q, bio);
+-	if (ret != ELEVATOR_NO_MERGE) {
+-		__rq = q->last_merge;
+-		goto out_insert;
+-	}
+-
+-	/*
+ 	 * see if the merge hash can satisfy a back merge
+ 	 */
+ 	__rq = as_find_arq_hash(ad, bio->bi_sector);
+@@ -1644,9 +1503,6 @@ as_merge(request_queue_t *q, struct requ
+ 
+ 	return ELEVATOR_NO_MERGE;
+ out:
+-	if (rq_mergeable(__rq))
+-		q->last_merge = __rq;
+-out_insert:
+ 	if (ret) {
+ 		if (rq_mergeable(__rq))
+ 			as_hot_arq_hash(ad, RQ_DATA(__rq));
+@@ -1693,9 +1549,6 @@ static void as_merged_request(request_qu
+ 		 * behind the disk head. We currently don't bother adjusting.
+ 		 */
+ 	}
+-
+-	if (arq->on_hash)
+-		q->last_merge = req;
+ }
+ 
+ static void
+@@ -1763,6 +1616,7 @@ as_merged_requests(request_queue_t *q, s
+ 	 * kill knowledge of next, this one is a goner
+ 	 */
+ 	as_remove_queued_request(q, next);
++	as_put_io_context(anext);
+ 
+ 	anext->state = AS_RQ_MERGED;
+ }
+@@ -1782,7 +1636,7 @@ static void as_work_handler(void *data)
+ 	unsigned long flags;
+ 
+ 	spin_lock_irqsave(q->queue_lock, flags);
+-	if (as_next_request(q))
++	if (!as_queue_empty(q))
+ 		q->request_fn(q);
+ 	spin_unlock_irqrestore(q->queue_lock, flags);
+ }
+@@ -1797,7 +1651,9 @@ static void as_put_request(request_queue
+ 		return;
+ 	}
+ 
+-	if (arq->state != AS_RQ_POSTSCHED && arq->state != AS_RQ_PRESCHED) {
++	if (unlikely(arq->state != AS_RQ_POSTSCHED &&
++		     arq->state != AS_RQ_PRESCHED &&
++		     arq->state != AS_RQ_MERGED)) {
+ 		printk("arq->state %d\n", arq->state);
+ 		WARN_ON(1);
+ 	}
+@@ -1807,7 +1663,7 @@ static void as_put_request(request_queue
+ }
+ 
+ static int as_set_request(request_queue_t *q, struct request *rq,
+-			  struct bio *bio, int gfp_mask)
++			  struct bio *bio, gfp_t gfp_mask)
+ {
+ 	struct as_data *ad = q->elevator->elevator_data;
+ 	struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
+@@ -1907,7 +1763,6 @@ static int as_init_queue(request_queue_t
+ 	INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]);
+ 	ad->sort_list[REQ_SYNC] = RB_ROOT;
+ 	ad->sort_list[REQ_ASYNC] = RB_ROOT;
+-	ad->dispatch = &q->queue_head;
+ 	ad->fifo_expire[REQ_SYNC] = default_read_expire;
+ 	ad->fifo_expire[REQ_ASYNC] = default_write_expire;
+ 	ad->antic_expire = default_antic_expire;
+@@ -2072,10 +1927,9 @@ static struct elevator_type iosched_as =
+ 		.elevator_merge_fn = 		as_merge,
+ 		.elevator_merged_fn =		as_merged_request,
+ 		.elevator_merge_req_fn =	as_merged_requests,
+-		.elevator_next_req_fn =		as_next_request,
+-		.elevator_add_req_fn =		as_insert_request,
+-		.elevator_remove_req_fn =	as_remove_request,
+-		.elevator_requeue_req_fn = 	as_requeue_request,
++		.elevator_dispatch_fn =		as_dispatch_request,
++		.elevator_add_req_fn =		as_add_request,
++		.elevator_activate_req_fn =	as_activate_request,
+ 		.elevator_deactivate_req_fn = 	as_deactivate_request,
+ 		.elevator_queue_empty_fn =	as_queue_empty,
+ 		.elevator_completed_req_fn =	as_completed_request,
+@@ -2119,8 +1973,8 @@ static int __init as_init(void)
+ 
+ static void __exit as_exit(void)
+ {
+-	kmem_cache_destroy(arq_pool);
+ 	elv_unregister(&iosched_as);
++	kmem_cache_destroy(arq_pool);
+ }
+ 
+ module_init(as_init);
+diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
+--- a/drivers/block/cciss_scsi.c
++++ b/drivers/block/cciss_scsi.c
+@@ -28,13 +28,17 @@
+    through the array controller.  Note in particular, neither 
+    physical nor logical disks are presented through the scsi layer. */
+ 
++#include <linux/timer.h>
++#include <linux/completion.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++
++#include <asm/atomic.h>
++
+ #include <scsi/scsi.h> 
+ #include <scsi/scsi_cmnd.h>
+ #include <scsi/scsi_device.h>
+ #include <scsi/scsi_host.h> 
+-#include <asm/atomic.h>
+-#include <linux/timer.h>
+-#include <linux/completion.h>
+ 
+ #include "cciss_scsi.h"
+ 
+diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
+--- a/drivers/block/cfq-iosched.c
++++ b/drivers/block/cfq-iosched.c
+@@ -84,7 +84,6 @@ static int cfq_max_depth = 2;
+ 	(node)->rb_left = NULL;		\
+ } while (0)
+ #define RB_CLEAR_ROOT(root)	((root)->rb_node = NULL)
+-#define ON_RB(node)		((node)->rb_color != RB_NONE)
+ #define rb_entry_crq(node)	rb_entry((node), struct cfq_rq, rb_node)
+ #define rq_rb_key(rq)		(rq)->sector
+ 
+@@ -271,10 +270,7 @@ CFQ_CFQQ_FNS(expired);
+ #undef CFQ_CFQQ_FNS
+ 
+ enum cfq_rq_state_flags {
+-	CFQ_CRQ_FLAG_in_flight = 0,
+-	CFQ_CRQ_FLAG_in_driver,
+-	CFQ_CRQ_FLAG_is_sync,
+-	CFQ_CRQ_FLAG_requeued,
++	CFQ_CRQ_FLAG_is_sync = 0,
+ };
+ 
+ #define CFQ_CRQ_FNS(name)						\
+@@ -291,14 +287,11 @@ static inline int cfq_crq_##name(const s
+ 	return (crq->crq_flags & (1 << CFQ_CRQ_FLAG_##name)) != 0;	\
+ }
+ 
+-CFQ_CRQ_FNS(in_flight);
+-CFQ_CRQ_FNS(in_driver);
+ CFQ_CRQ_FNS(is_sync);
+-CFQ_CRQ_FNS(requeued);
+ #undef CFQ_CRQ_FNS
+ 
+ static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned int, unsigned short);
+-static void cfq_dispatch_sort(request_queue_t *, struct cfq_rq *);
++static void cfq_dispatch_insert(request_queue_t *, struct cfq_rq *);
+ static void cfq_put_cfqd(struct cfq_data *cfqd);
+ 
+ #define process_sync(tsk)	((tsk)->flags & PF_SYNCWRITE)
+@@ -311,14 +304,6 @@ static inline void cfq_del_crq_hash(stru
+ 	hlist_del_init(&crq->hash);
+ }
+ 
+-static void cfq_remove_merge_hints(request_queue_t *q, struct cfq_rq *crq)
+-{
+-	cfq_del_crq_hash(crq);
+-
+-	if (q->last_merge == crq->request)
+-		q->last_merge = NULL;
+-}
+-
+ static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
+ {
+ 	const int hash_idx = CFQ_MHASH_FN(rq_hash_key(crq->request));
+@@ -347,18 +332,13 @@ static struct request *cfq_find_rq_hash(
+ 	return NULL;
+ }
+ 
+-static inline int cfq_pending_requests(struct cfq_data *cfqd)
+-{
+-	return !list_empty(&cfqd->queue->queue_head) || cfqd->busy_queues;
+-}
+-
+ /*
+  * scheduler run of queue, if there are requests pending and no one in the
+  * driver that will restart queueing
+  */
+ static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
+ {
+-	if (!cfqd->rq_in_driver && cfq_pending_requests(cfqd))
++	if (!cfqd->rq_in_driver && cfqd->busy_queues)
+ 		kblockd_schedule_work(&cfqd->unplug_work);
+ }
+ 
+@@ -366,7 +346,7 @@ static int cfq_queue_empty(request_queue
+ {
+ 	struct cfq_data *cfqd = q->elevator->elevator_data;
+ 
+-	return !cfq_pending_requests(cfqd);
++	return !cfqd->busy_queues;
+ }
+ 
+ /*
+@@ -386,11 +366,6 @@ cfq_choose_req(struct cfq_data *cfqd, st
+ 	if (crq2 == NULL)
+ 		return crq1;
+ 
+-	if (cfq_crq_requeued(crq1) && !cfq_crq_requeued(crq2))
+-		return crq1;
+-	else if (cfq_crq_requeued(crq2) && !cfq_crq_requeued(crq1))
+-		return crq2;
+-
+ 	if (cfq_crq_is_sync(crq1) && !cfq_crq_is_sync(crq2))
+ 		return crq1;
+ 	else if (cfq_crq_is_sync(crq2) && !cfq_crq_is_sync(crq1))
+@@ -461,10 +436,7 @@ cfq_find_next_crq(struct cfq_data *cfqd,
+ 	struct cfq_rq *crq_next = NULL, *crq_prev = NULL;
+ 	struct rb_node *rbnext, *rbprev;
+ 
+-	rbnext = NULL;
+-	if (ON_RB(&last->rb_node))
+-		rbnext = rb_next(&last->rb_node);
+-	if (!rbnext) {
++	if (!(rbnext = rb_next(&last->rb_node))) {
+ 		rbnext = rb_first(&cfqq->sort_list);
+ 		if (rbnext == &last->rb_node)
+ 			rbnext = NULL;
+@@ -545,13 +517,13 @@ static void cfq_resort_rr_list(struct cf
+  * the pending list according to last request service
+  */
+ static inline void
+-cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq, int requeue)
++cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+ {
+ 	BUG_ON(cfq_cfqq_on_rr(cfqq));
+ 	cfq_mark_cfqq_on_rr(cfqq);
+ 	cfqd->busy_queues++;
+ 
+-	cfq_resort_rr_list(cfqq, requeue);
++	cfq_resort_rr_list(cfqq, 0);
+ }
+ 
+ static inline void
+@@ -571,22 +543,19 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, s
+ static inline void cfq_del_crq_rb(struct cfq_rq *crq)
+ {
+ 	struct cfq_queue *cfqq = crq->cfq_queue;
++	struct cfq_data *cfqd = cfqq->cfqd;
++	const int sync = cfq_crq_is_sync(crq);
+ 
+-	if (ON_RB(&crq->rb_node)) {
+-		struct cfq_data *cfqd = cfqq->cfqd;
+-		const int sync = cfq_crq_is_sync(crq);
+-
+-		BUG_ON(!cfqq->queued[sync]);
+-		cfqq->queued[sync]--;
++	BUG_ON(!cfqq->queued[sync]);
++	cfqq->queued[sync]--;
+ 
+-		cfq_update_next_crq(crq);
++	cfq_update_next_crq(crq);
+ 
+-		rb_erase(&crq->rb_node, &cfqq->sort_list);
+-		RB_CLEAR_COLOR(&crq->rb_node);
++	rb_erase(&crq->rb_node, &cfqq->sort_list);
++	RB_CLEAR_COLOR(&crq->rb_node);
+ 
+-		if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
+-			cfq_del_cfqq_rr(cfqd, cfqq);
+-	}
++	if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
++		cfq_del_cfqq_rr(cfqd, cfqq);
+ }
+ 
+ static struct cfq_rq *
+@@ -627,12 +596,12 @@ static void cfq_add_crq_rb(struct cfq_rq
+ 	 * if that happens, put the alias on the dispatch list
+ 	 */
+ 	while ((__alias = __cfq_add_crq_rb(crq)) != NULL)
+-		cfq_dispatch_sort(cfqd->queue, __alias);
++		cfq_dispatch_insert(cfqd->queue, __alias);
+ 
+ 	rb_insert_color(&crq->rb_node, &cfqq->sort_list);
+ 
+ 	if (!cfq_cfqq_on_rr(cfqq))
+-		cfq_add_cfqq_rr(cfqd, cfqq, cfq_crq_requeued(crq));
++		cfq_add_cfqq_rr(cfqd, cfqq);
+ 
+ 	/*
+ 	 * check if this request is a better next-serve candidate
+@@ -643,10 +612,8 @@ static void cfq_add_crq_rb(struct cfq_rq
+ static inline void
+ cfq_reposition_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
+ {
+-	if (ON_RB(&crq->rb_node)) {
+-		rb_erase(&crq->rb_node, &cfqq->sort_list);
+-		cfqq->queued[cfq_crq_is_sync(crq)]--;
+-	}
++	rb_erase(&crq->rb_node, &cfqq->sort_list);
++	cfqq->queued[cfq_crq_is_sync(crq)]--;
+ 
+ 	cfq_add_crq_rb(crq);
+ }
+@@ -676,49 +643,28 @@ out:
+ 	return NULL;
+ }
+ 
+-static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
++static void cfq_activate_request(request_queue_t *q, struct request *rq)
+ {
+ 	struct cfq_data *cfqd = q->elevator->elevator_data;
+-	struct cfq_rq *crq = RQ_DATA(rq);
+ 
+-	if (crq) {
+-		struct cfq_queue *cfqq = crq->cfq_queue;
+-
+-		if (cfq_crq_in_driver(crq)) {
+-			cfq_clear_crq_in_driver(crq);
+-			WARN_ON(!cfqd->rq_in_driver);
+-			cfqd->rq_in_driver--;
+-		}
+-		if (cfq_crq_in_flight(crq)) {
+-			const int sync = cfq_crq_is_sync(crq);
+-
+-			cfq_clear_crq_in_flight(crq);
+-			WARN_ON(!cfqq->on_dispatch[sync]);
+-			cfqq->on_dispatch[sync]--;
+-		}
+-		cfq_mark_crq_requeued(crq);
+-	}
++	cfqd->rq_in_driver++;
+ }
+ 
+-/*
+- * make sure the service time gets corrected on reissue of this request
+- */
+-static void cfq_requeue_request(request_queue_t *q, struct request *rq)
++static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
+ {
+-	cfq_deactivate_request(q, rq);
+-	list_add(&rq->queuelist, &q->queue_head);
++	struct cfq_data *cfqd = q->elevator->elevator_data;
++
++	WARN_ON(!cfqd->rq_in_driver);
++	cfqd->rq_in_driver--;
+ }
+ 
+-static void cfq_remove_request(request_queue_t *q, struct request *rq)
++static void cfq_remove_request(struct request *rq)
+ {
+ 	struct cfq_rq *crq = RQ_DATA(rq);
+ 
+-	if (crq) {
+-		list_del_init(&rq->queuelist);
+-		cfq_del_crq_rb(crq);
+-		cfq_remove_merge_hints(q, crq);
+-
+-	}
++	list_del_init(&rq->queuelist);
++	cfq_del_crq_rb(crq);
++	cfq_del_crq_hash(crq);
+ }
+ 
+ static int
+@@ -728,12 +674,6 @@ cfq_merge(request_queue_t *q, struct req
+ 	struct request *__rq;
+ 	int ret;
+ 
+-	ret = elv_try_last_merge(q, bio);
+-	if (ret != ELEVATOR_NO_MERGE) {
+-		__rq = q->last_merge;
+-		goto out_insert;
+-	}
+-
+ 	__rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
+ 	if (__rq && elv_rq_merge_ok(__rq, bio)) {
+ 		ret = ELEVATOR_BACK_MERGE;
+@@ -748,8 +688,6 @@ cfq_merge(request_queue_t *q, struct req
+ 
+ 	return ELEVATOR_NO_MERGE;
+ out:
+-	q->last_merge = __rq;
+-out_insert:
+ 	*req = __rq;
+ 	return ret;
+ }
+@@ -762,14 +700,12 @@ static void cfq_merged_request(request_q
+ 	cfq_del_crq_hash(crq);
+ 	cfq_add_crq_hash(cfqd, crq);
+ 
+-	if (ON_RB(&crq->rb_node) && (rq_rb_key(req) != crq->rb_key)) {
++	if (rq_rb_key(req) != crq->rb_key) {
+ 		struct cfq_queue *cfqq = crq->cfq_queue;
+ 
+ 		cfq_update_next_crq(crq);
+ 		cfq_reposition_crq_rb(cfqq, crq);
+ 	}
+-
+-	q->last_merge = req;
+ }
+ 
+ static void
+@@ -785,7 +721,7 @@ cfq_merged_requests(request_queue_t *q, 
+ 	    time_before(next->start_time, rq->start_time))
+ 		list_move(&rq->queuelist, &next->queuelist);
+ 
+-	cfq_remove_request(q, next);
++	cfq_remove_request(next);
+ }
+ 
+ static inline void
+@@ -992,53 +928,15 @@ static int cfq_arm_slice_timer(struct cf
+ 	return 1;
+ }
+ 
+-/*
+- * we dispatch cfqd->cfq_quantum requests in total from the rr_list queues,
+- * this function sector sorts the selected request to minimize seeks. we start
+- * at cfqd->last_sector, not 0.
+- */
+-static void cfq_dispatch_sort(request_queue_t *q, struct cfq_rq *crq)
++static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq)
+ {
+ 	struct cfq_data *cfqd = q->elevator->elevator_data;
+ 	struct cfq_queue *cfqq = crq->cfq_queue;
+-	struct list_head *head = &q->queue_head, *entry = head;
+-	struct request *__rq;
+-	sector_t last;
+-
+-	list_del(&crq->request->queuelist);
+-
+-	last = cfqd->last_sector;
+-	list_for_each_entry_reverse(__rq, head, queuelist) {
+-		struct cfq_rq *__crq = RQ_DATA(__rq);
+-
+-		if (blk_barrier_rq(__rq))
+-			break;
+-		if (!blk_fs_request(__rq))
+-			break;
+-		if (cfq_crq_requeued(__crq))
+-			break;
+-
+-		if (__rq->sector <= crq->request->sector)
+-			break;
+-		if (__rq->sector > last && crq->request->sector < last) {
+-			last = crq->request->sector + crq->request->nr_sectors;
+-			break;
+-		}
+-		entry = &__rq->queuelist;
+-	}
+-
+-	cfqd->last_sector = last;
+ 
+ 	cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq);
+-
+-	cfq_del_crq_rb(crq);
+-	cfq_remove_merge_hints(q, crq);
+-
+-	cfq_mark_crq_in_flight(crq);
+-	cfq_clear_crq_requeued(crq);
+-
++	cfq_remove_request(crq->request);
+ 	cfqq->on_dispatch[cfq_crq_is_sync(crq)]++;
+-	list_add_tail(&crq->request->queuelist, entry);
++	elv_dispatch_sort(q, crq->request);
+ }
+ 
+ /*
+@@ -1159,7 +1057,7 @@ __cfq_dispatch_requests(struct cfq_data 
+ 		/*
+ 		 * finally, insert request into driver dispatch list
+ 		 */
+-		cfq_dispatch_sort(cfqd->queue, crq);
++		cfq_dispatch_insert(cfqd->queue, crq);
+ 
+ 		cfqd->dispatch_slice++;
+ 		dispatched++;
+@@ -1194,7 +1092,7 @@ __cfq_dispatch_requests(struct cfq_data 
+ }
+ 
+ static int
+-cfq_dispatch_requests(request_queue_t *q, int max_dispatch, int force)
++cfq_dispatch_requests(request_queue_t *q, int force)
+ {
+ 	struct cfq_data *cfqd = q->elevator->elevator_data;
+ 	struct cfq_queue *cfqq;
+@@ -1204,12 +1102,25 @@ cfq_dispatch_requests(request_queue_t *q
+ 
+ 	cfqq = cfq_select_queue(cfqd, force);
+ 	if (cfqq) {
++		int max_dispatch;
++
++		/*
++		 * if idle window is disabled, allow queue buildup
++		 */
++		if (!cfq_cfqq_idle_window(cfqq) &&
++		    cfqd->rq_in_driver >= cfqd->cfq_max_depth)
++			return 0;
++
+ 		cfq_clear_cfqq_must_dispatch(cfqq);
+ 		cfq_clear_cfqq_wait_request(cfqq);
+ 		del_timer(&cfqd->idle_slice_timer);
+ 
+-		if (cfq_class_idle(cfqq))
+-			max_dispatch = 1;
++		if (!force) {
++			max_dispatch = cfqd->cfq_quantum;
++			if (cfq_class_idle(cfqq))
++				max_dispatch = 1;
++		} else
++			max_dispatch = INT_MAX;
+ 
+ 		return __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
+ 	}
+@@ -1217,93 +1128,6 @@ cfq_dispatch_requests(request_queue_t *q
+ 	return 0;
+ }
+ 
+-static inline void cfq_account_dispatch(struct cfq_rq *crq)
+-{
+-	struct cfq_queue *cfqq = crq->cfq_queue;
+-	struct cfq_data *cfqd = cfqq->cfqd;
+-
+-	if (unlikely(!blk_fs_request(crq->request)))
+-		return;
+-
+-	/*
+-	 * accounted bit is necessary since some drivers will call
+-	 * elv_next_request() many times for the same request (eg ide)
+-	 */
+-	if (cfq_crq_in_driver(crq))
+-		return;
+-
+-	cfq_mark_crq_in_driver(crq);
+-	cfqd->rq_in_driver++;
+-}
+-
+-static inline void
+-cfq_account_completion(struct cfq_queue *cfqq, struct cfq_rq *crq)
+-{
+-	struct cfq_data *cfqd = cfqq->cfqd;
+-	unsigned long now;
+-
+-	if (!cfq_crq_in_driver(crq))
+-		return;
+-
+-	now = jiffies;
+-
+-	WARN_ON(!cfqd->rq_in_driver);
+-	cfqd->rq_in_driver--;
+-
+-	if (!cfq_class_idle(cfqq))
+-		cfqd->last_end_request = now;
+-
+-	if (!cfq_cfqq_dispatched(cfqq)) {
+-		if (cfq_cfqq_on_rr(cfqq)) {
+-			cfqq->service_last = now;
+-			cfq_resort_rr_list(cfqq, 0);
+-		}
+-		if (cfq_cfqq_expired(cfqq)) {
+-			__cfq_slice_expired(cfqd, cfqq, 0);
+-			cfq_schedule_dispatch(cfqd);
+-		}
+-	}
+-
+-	if (cfq_crq_is_sync(crq))
+-		crq->io_context->last_end_request = now;
+-}
+-
+-static struct request *cfq_next_request(request_queue_t *q)
+-{
+-	struct cfq_data *cfqd = q->elevator->elevator_data;
+-	struct request *rq;
+-
+-	if (!list_empty(&q->queue_head)) {
+-		struct cfq_rq *crq;
+-dispatch:
+-		rq = list_entry_rq(q->queue_head.next);
+-
+-		crq = RQ_DATA(rq);
+-		if (crq) {
+-			struct cfq_queue *cfqq = crq->cfq_queue;
+-
+-			/*
+-			 * if idle window is disabled, allow queue buildup
+-			 */
+-			if (!cfq_crq_in_driver(crq) &&
+-			    !cfq_cfqq_idle_window(cfqq) &&
+-			    !blk_barrier_rq(rq) &&
+-			    cfqd->rq_in_driver >= cfqd->cfq_max_depth)
+-				return NULL;
+-
+-			cfq_remove_merge_hints(q, crq);
+-			cfq_account_dispatch(crq);
+-		}
+-
+-		return rq;
+-	}
+-
+-	if (cfq_dispatch_requests(q, cfqd->cfq_quantum, 0))
+-		goto dispatch;
+-
+-	return NULL;
+-}
+-
+ /*
+  * task holds one reference to the queue, dropped when task exits. each crq
+  * in-flight on this queue also holds a reference, dropped when crq is freed.
+@@ -1422,7 +1246,7 @@ static void cfq_exit_io_context(struct c
+ }
+ 
+ static struct cfq_io_context *
+-cfq_alloc_io_context(struct cfq_data *cfqd, int gfp_mask)
++cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
+ {
+ 	struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask);
+ 
+@@ -1517,7 +1341,7 @@ static int cfq_ioc_set_ioprio(struct io_
+ 
+ static struct cfq_queue *
+ cfq_get_queue(struct cfq_data *cfqd, unsigned int key, unsigned short ioprio,
+-	      int gfp_mask)
++	      gfp_t gfp_mask)
+ {
+ 	const int hashval = hash_long(key, CFQ_QHASH_SHIFT);
+ 	struct cfq_queue *cfqq, *new_cfqq = NULL;
+@@ -1578,7 +1402,7 @@ out:
+  * cfqq, so we don't need to worry about it disappearing
+  */
+ static struct cfq_io_context *
+-cfq_get_io_context(struct cfq_data *cfqd, pid_t pid, int gfp_mask)
++cfq_get_io_context(struct cfq_data *cfqd, pid_t pid, gfp_t gfp_mask)
+ {
+ 	struct io_context *ioc = NULL;
+ 	struct cfq_io_context *cic;
+@@ -1816,8 +1640,9 @@ cfq_crq_enqueued(struct cfq_data *cfqd, 
+ 	}
+ }
+ 
+-static void cfq_enqueue(struct cfq_data *cfqd, struct request *rq)
++static void cfq_insert_request(request_queue_t *q, struct request *rq)
+ {
++	struct cfq_data *cfqd = q->elevator->elevator_data;
+ 	struct cfq_rq *crq = RQ_DATA(rq);
+ 	struct cfq_queue *cfqq = crq->cfq_queue;
+ 
+@@ -1827,66 +1652,43 @@ static void cfq_enqueue(struct cfq_data 
+ 
+ 	list_add_tail(&rq->queuelist, &cfqq->fifo);
+ 
+-	if (rq_mergeable(rq)) {
++	if (rq_mergeable(rq))
+ 		cfq_add_crq_hash(cfqd, crq);
+ 
+-		if (!cfqd->queue->last_merge)
+-			cfqd->queue->last_merge = rq;
+-	}
+-
+ 	cfq_crq_enqueued(cfqd, cfqq, crq);
+ }
+ 
+-static void
+-cfq_insert_request(request_queue_t *q, struct request *rq, int where)
+-{
+-	struct cfq_data *cfqd = q->elevator->elevator_data;
+-
+-	switch (where) {
+-		case ELEVATOR_INSERT_BACK:
+-			while (cfq_dispatch_requests(q, INT_MAX, 1))
+-				;
+-			list_add_tail(&rq->queuelist, &q->queue_head);
+-			/*
+-			 * If we were idling with pending requests on
+-			 * inactive cfqqs, force dispatching will
+-			 * remove the idle timer and the queue won't
+-			 * be kicked by __make_request() afterward.
+-			 * Kick it here.
+-			 */
+-			cfq_schedule_dispatch(cfqd);
+-			break;
+-		case ELEVATOR_INSERT_FRONT:
+-			list_add(&rq->queuelist, &q->queue_head);
+-			break;
+-		case ELEVATOR_INSERT_SORT:
+-			BUG_ON(!blk_fs_request(rq));
+-			cfq_enqueue(cfqd, rq);
+-			break;
+-		default:
+-			printk("%s: bad insert point %d\n", __FUNCTION__,where);
+-			return;
+-	}
+-}
+-
+ static void cfq_completed_request(request_queue_t *q, struct request *rq)
+ {
+ 	struct cfq_rq *crq = RQ_DATA(rq);
+-	struct cfq_queue *cfqq;
++	struct cfq_queue *cfqq = crq->cfq_queue;
++	struct cfq_data *cfqd = cfqq->cfqd;
++	const int sync = cfq_crq_is_sync(crq);
++	unsigned long now;
+ 
+-	if (unlikely(!blk_fs_request(rq)))
+-		return;
++	now = jiffies;
+ 
+-	cfqq = crq->cfq_queue;
++	WARN_ON(!cfqd->rq_in_driver);
++	WARN_ON(!cfqq->on_dispatch[sync]);
++	cfqd->rq_in_driver--;
++	cfqq->on_dispatch[sync]--;
+ 
+-	if (cfq_crq_in_flight(crq)) {
+-		const int sync = cfq_crq_is_sync(crq);
++	if (!cfq_class_idle(cfqq))
++		cfqd->last_end_request = now;
+ 
+-		WARN_ON(!cfqq->on_dispatch[sync]);
+-		cfqq->on_dispatch[sync]--;
++	if (!cfq_cfqq_dispatched(cfqq)) {
++		if (cfq_cfqq_on_rr(cfqq)) {
++			cfqq->service_last = now;
++			cfq_resort_rr_list(cfqq, 0);
++		}
++		if (cfq_cfqq_expired(cfqq)) {
++			__cfq_slice_expired(cfqd, cfqq, 0);
++			cfq_schedule_dispatch(cfqd);
++		}
+ 	}
+ 
+-	cfq_account_completion(cfqq, crq);
++	if (cfq_crq_is_sync(crq))
++		crq->io_context->last_end_request = now;
+ }
+ 
+ static struct request *
+@@ -2075,7 +1877,7 @@ static void cfq_put_request(request_queu
+  */
+ static int
+ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
+-		int gfp_mask)
++		gfp_t gfp_mask)
+ {
+ 	struct cfq_data *cfqd = q->elevator->elevator_data;
+ 	struct task_struct *tsk = current;
+@@ -2118,9 +1920,6 @@ cfq_set_request(request_queue_t *q, stru
+ 		INIT_HLIST_NODE(&crq->hash);
+ 		crq->cfq_queue = cfqq;
+ 		crq->io_context = cic;
+-		cfq_clear_crq_in_flight(crq);
+-		cfq_clear_crq_in_driver(crq);
+-		cfq_clear_crq_requeued(crq);
+ 
+ 		if (rw == READ || process_sync(tsk))
+ 			cfq_mark_crq_is_sync(crq);
+@@ -2201,7 +2000,7 @@ static void cfq_idle_slice_timer(unsigne
+ 		 * only expire and reinvoke request handler, if there are
+ 		 * other queues with pending requests
+ 		 */
+-		if (!cfq_pending_requests(cfqd)) {
++		if (!cfqd->busy_queues) {
+ 			cfqd->idle_slice_timer.expires = min(now + cfqd->cfq_slice_idle, cfqq->slice_end);
+ 			add_timer(&cfqd->idle_slice_timer);
+ 			goto out_cont;
+@@ -2260,10 +2059,8 @@ static void cfq_put_cfqd(struct cfq_data
+ 	if (!atomic_dec_and_test(&cfqd->ref))
+ 		return;
+ 
+-	blk_put_queue(q);
+-
+ 	cfq_shutdown_timer_wq(cfqd);
+-	q->elevator->elevator_data = NULL;
++	blk_put_queue(q);
+ 
+ 	mempool_destroy(cfqd->crq_pool);
+ 	kfree(cfqd->crq_hash);
+@@ -2576,10 +2373,9 @@ static struct elevator_type iosched_cfq 
+ 		.elevator_merge_fn = 		cfq_merge,
+ 		.elevator_merged_fn =		cfq_merged_request,
+ 		.elevator_merge_req_fn =	cfq_merged_requests,
+-		.elevator_next_req_fn =		cfq_next_request,
++		.elevator_dispatch_fn =		cfq_dispatch_requests,
+ 		.elevator_add_req_fn =		cfq_insert_request,
+-		.elevator_remove_req_fn =	cfq_remove_request,
+-		.elevator_requeue_req_fn =	cfq_requeue_request,
++		.elevator_activate_req_fn =	cfq_activate_request,
+ 		.elevator_deactivate_req_fn =	cfq_deactivate_request,
+ 		.elevator_queue_empty_fn =	cfq_queue_empty,
+ 		.elevator_completed_req_fn =	cfq_completed_request,
+@@ -2620,28 +2416,8 @@ static int __init cfq_init(void)
+ 
+ static void __exit cfq_exit(void)
+ {
+-	struct task_struct *g, *p;
+-	unsigned long flags;
+-
+-	read_lock_irqsave(&tasklist_lock, flags);
+-
+-	/*
+-	 * iterate each process in the system, removing our io_context
+-	 */
+-	do_each_thread(g, p) {
+-		struct io_context *ioc = p->io_context;
+-
+-		if (ioc && ioc->cic) {
+-			ioc->cic->exit(ioc->cic);
+-			cfq_free_io_context(ioc->cic);
+-			ioc->cic = NULL;
+-		}
+-	} while_each_thread(g, p);
+-
+-	read_unlock_irqrestore(&tasklist_lock, flags);
+-
+-	cfq_slab_kill();
+ 	elv_unregister(&iosched_cfq);
++	cfq_slab_kill();
+ }
+ 
+ module_init(cfq_init);
+diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
+--- a/drivers/block/deadline-iosched.c
++++ b/drivers/block/deadline-iosched.c
+@@ -50,7 +50,6 @@ struct deadline_data {
+ 	 * next in sort order. read, write or both are NULL
+ 	 */
+ 	struct deadline_rq *next_drq[2];
+-	struct list_head *dispatch;	/* driver dispatch queue */
+ 	struct list_head *hash;		/* request hash */
+ 	unsigned int batching;		/* number of sequential requests made */
+ 	sector_t last_sector;		/* head position */
+@@ -113,15 +112,6 @@ static inline void deadline_del_drq_hash
+ 		__deadline_del_drq_hash(drq);
+ }
+ 
+-static void
+-deadline_remove_merge_hints(request_queue_t *q, struct deadline_rq *drq)
+-{
+-	deadline_del_drq_hash(drq);
+-
+-	if (q->last_merge == drq->request)
+-		q->last_merge = NULL;
+-}
+-
+ static inline void
+ deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
+ {
+@@ -239,10 +229,9 @@ deadline_del_drq_rb(struct deadline_data
+ 			dd->next_drq[data_dir] = rb_entry_drq(rbnext);
+ 	}
+ 
+-	if (ON_RB(&drq->rb_node)) {
+-		rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
+-		RB_CLEAR(&drq->rb_node);
+-	}
++	BUG_ON(!ON_RB(&drq->rb_node));
++	rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
++	RB_CLEAR(&drq->rb_node);
+ }
+ 
+ static struct request *
+@@ -286,7 +275,7 @@ deadline_find_first_drq(struct deadline_
+ /*
+  * add drq to rbtree and fifo
+  */
+-static inline void
++static void
+ deadline_add_request(struct request_queue *q, struct request *rq)
+ {
+ 	struct deadline_data *dd = q->elevator->elevator_data;
+@@ -301,12 +290,8 @@ deadline_add_request(struct request_queu
+ 	drq->expires = jiffies + dd->fifo_expire[data_dir];
+ 	list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]);
+ 
+-	if (rq_mergeable(rq)) {
++	if (rq_mergeable(rq))
+ 		deadline_add_drq_hash(dd, drq);
+-
+-		if (!q->last_merge)
+-			q->last_merge = rq;
+-	}
+ }
+ 
+ /*
+@@ -315,14 +300,11 @@ deadline_add_request(struct request_queu
+ static void deadline_remove_request(request_queue_t *q, struct request *rq)
+ {
+ 	struct deadline_rq *drq = RQ_DATA(rq);
++	struct deadline_data *dd = q->elevator->elevator_data;
+ 
+-	if (drq) {
+-		struct deadline_data *dd = q->elevator->elevator_data;
+-
+-		list_del_init(&drq->fifo);
+-		deadline_remove_merge_hints(q, drq);
+-		deadline_del_drq_rb(dd, drq);
+-	}
++	list_del_init(&drq->fifo);
++	deadline_del_drq_rb(dd, drq);
++	deadline_del_drq_hash(drq);
+ }
+ 
+ static int
+@@ -333,15 +315,6 @@ deadline_merge(request_queue_t *q, struc
+ 	int ret;
+ 
+ 	/*
+-	 * try last_merge to avoid going to hash
+-	 */
+-	ret = elv_try_last_merge(q, bio);
+-	if (ret != ELEVATOR_NO_MERGE) {
+-		__rq = q->last_merge;
+-		goto out_insert;
+-	}
+-
+-	/*
+ 	 * see if the merge hash can satisfy a back merge
+ 	 */
+ 	__rq = deadline_find_drq_hash(dd, bio->bi_sector);
+@@ -373,8 +346,6 @@ deadline_merge(request_queue_t *q, struc
+ 
+ 	return ELEVATOR_NO_MERGE;
+ out:
+-	q->last_merge = __rq;
+-out_insert:
+ 	if (ret)
+ 		deadline_hot_drq_hash(dd, RQ_DATA(__rq));
+ 	*req = __rq;
+@@ -399,8 +370,6 @@ static void deadline_merged_request(requ
+ 		deadline_del_drq_rb(dd, drq);
+ 		deadline_add_drq_rb(dd, drq);
+ 	}
+-
+-	q->last_merge = req;
+ }
+ 
+ static void
+@@ -452,7 +421,7 @@ deadline_move_to_dispatch(struct deadlin
+ 	request_queue_t *q = drq->request->q;
+ 
+ 	deadline_remove_request(q, drq->request);
+-	list_add_tail(&drq->request->queuelist, dd->dispatch);
++	elv_dispatch_add_tail(q, drq->request);
+ }
+ 
+ /*
+@@ -502,8 +471,9 @@ static inline int deadline_check_fifo(st
+  * deadline_dispatch_requests selects the best request according to
+  * read/write expire, fifo_batch, etc
+  */
+-static int deadline_dispatch_requests(struct deadline_data *dd)
++static int deadline_dispatch_requests(request_queue_t *q, int force)
+ {
++	struct deadline_data *dd = q->elevator->elevator_data;
+ 	const int reads = !list_empty(&dd->fifo_list[READ]);
+ 	const int writes = !list_empty(&dd->fifo_list[WRITE]);
+ 	struct deadline_rq *drq;
+@@ -597,65 +567,12 @@ dispatch_request:
+ 	return 1;
+ }
+ 
+-static struct request *deadline_next_request(request_queue_t *q)
+-{
+-	struct deadline_data *dd = q->elevator->elevator_data;
+-	struct request *rq;
+-
+-	/*
+-	 * if there are still requests on the dispatch queue, grab the first one
+-	 */
+-	if (!list_empty(dd->dispatch)) {
+-dispatch:
+-		rq = list_entry_rq(dd->dispatch->next);
+-		return rq;
+-	}
+-
+-	if (deadline_dispatch_requests(dd))
+-		goto dispatch;
+-
+-	return NULL;
+-}
+-
+-static void
+-deadline_insert_request(request_queue_t *q, struct request *rq, int where)
+-{
+-	struct deadline_data *dd = q->elevator->elevator_data;
+-
+-	/* barriers must flush the reorder queue */
+-	if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
+-			&& where == ELEVATOR_INSERT_SORT))
+-		where = ELEVATOR_INSERT_BACK;
+-
+-	switch (where) {
+-		case ELEVATOR_INSERT_BACK:
+-			while (deadline_dispatch_requests(dd))
+-				;
+-			list_add_tail(&rq->queuelist, dd->dispatch);
+-			break;
+-		case ELEVATOR_INSERT_FRONT:
+-			list_add(&rq->queuelist, dd->dispatch);
+-			break;
+-		case ELEVATOR_INSERT_SORT:
+-			BUG_ON(!blk_fs_request(rq));
+-			deadline_add_request(q, rq);
+-			break;
+-		default:
+-			printk("%s: bad insert point %d\n", __FUNCTION__,where);
+-			return;
+-	}
+-}
+-
+ static int deadline_queue_empty(request_queue_t *q)
+ {
+ 	struct deadline_data *dd = q->elevator->elevator_data;
+ 
+-	if (!list_empty(&dd->fifo_list[WRITE])
+-	    || !list_empty(&dd->fifo_list[READ])
+-	    || !list_empty(dd->dispatch))
+-		return 0;
+-
+-	return 1;
++	return list_empty(&dd->fifo_list[WRITE])
++		&& list_empty(&dd->fifo_list[READ]);
+ }
+ 
+ static struct request *
+@@ -733,7 +650,6 @@ static int deadline_init_queue(request_q
+ 	INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
+ 	dd->sort_list[READ] = RB_ROOT;
+ 	dd->sort_list[WRITE] = RB_ROOT;
+-	dd->dispatch = &q->queue_head;
+ 	dd->fifo_expire[READ] = read_expire;
+ 	dd->fifo_expire[WRITE] = write_expire;
+ 	dd->writes_starved = writes_starved;
+@@ -748,15 +664,13 @@ static void deadline_put_request(request
+ 	struct deadline_data *dd = q->elevator->elevator_data;
+ 	struct deadline_rq *drq = RQ_DATA(rq);
+ 
+-	if (drq) {
+-		mempool_free(drq, dd->drq_pool);
+-		rq->elevator_private = NULL;
+-	}
++	mempool_free(drq, dd->drq_pool);
++	rq->elevator_private = NULL;
+ }
+ 
+ static int
+ deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
+-		     int gfp_mask)
++		     gfp_t gfp_mask)
+ {
+ 	struct deadline_data *dd = q->elevator->elevator_data;
+ 	struct deadline_rq *drq;
+@@ -917,9 +831,8 @@ static struct elevator_type iosched_dead
+ 		.elevator_merge_fn = 		deadline_merge,
+ 		.elevator_merged_fn =		deadline_merged_request,
+ 		.elevator_merge_req_fn =	deadline_merged_requests,
+-		.elevator_next_req_fn =		deadline_next_request,
+-		.elevator_add_req_fn =		deadline_insert_request,
+-		.elevator_remove_req_fn =	deadline_remove_request,
++		.elevator_dispatch_fn =		deadline_dispatch_requests,
++		.elevator_add_req_fn =		deadline_add_request,
+ 		.elevator_queue_empty_fn =	deadline_queue_empty,
+ 		.elevator_former_req_fn =	deadline_former_request,
+ 		.elevator_latter_req_fn =	deadline_latter_request,
+diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
+--- a/drivers/block/elevator.c
++++ b/drivers/block/elevator.c
+@@ -34,6 +34,7 @@
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/compiler.h>
++#include <linux/delay.h>
+ 
+ #include <asm/uaccess.h>
+ 
+@@ -83,21 +84,11 @@ inline int elv_try_merge(struct request 
+ }
+ EXPORT_SYMBOL(elv_try_merge);
+ 
+-inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
+-{
+-	if (q->last_merge)
+-		return elv_try_merge(q->last_merge, bio);
+-
+-	return ELEVATOR_NO_MERGE;
+-}
+-EXPORT_SYMBOL(elv_try_last_merge);
+-
+ static struct elevator_type *elevator_find(const char *name)
+ {
+ 	struct elevator_type *e = NULL;
+ 	struct list_head *entry;
+ 
+-	spin_lock_irq(&elv_list_lock);
+ 	list_for_each(entry, &elv_list) {
+ 		struct elevator_type *__e;
+ 
+@@ -108,7 +99,6 @@ static struct elevator_type *elevator_fi
+ 			break;
+ 		}
+ 	}
+-	spin_unlock_irq(&elv_list_lock);
+ 
+ 	return e;
+ }
+@@ -120,12 +110,15 @@ static void elevator_put(struct elevator
+ 
+ static struct elevator_type *elevator_get(const char *name)
+ {
+-	struct elevator_type *e = elevator_find(name);
++	struct elevator_type *e;
+ 
+-	if (!e)
+-		return NULL;
+-	if (!try_module_get(e->elevator_owner))
+-		return NULL;
++	spin_lock_irq(&elv_list_lock);
++
++	e = elevator_find(name);
++	if (e && !try_module_get(e->elevator_owner))
++		e = NULL;
++
++	spin_unlock_irq(&elv_list_lock);
+ 
+ 	return e;
+ }
+@@ -139,8 +132,6 @@ static int elevator_attach(request_queue
+ 	eq->ops = &e->ops;
+ 	eq->elevator_type = e;
+ 
+-	INIT_LIST_HEAD(&q->queue_head);
+-	q->last_merge = NULL;
+ 	q->elevator = eq;
+ 
+ 	if (eq->ops->elevator_init_fn)
+@@ -153,23 +144,20 @@ static char chosen_elevator[16];
+ 
+ static void elevator_setup_default(void)
+ {
++	struct elevator_type *e;
++
+ 	/*
+-	 * check if default is set and exists
++	 * If default has not been set, use the compiled-in selection.
+ 	 */
+-	if (chosen_elevator[0] && elevator_find(chosen_elevator))
+-		return;
++	if (!chosen_elevator[0])
++		strcpy(chosen_elevator, CONFIG_DEFAULT_IOSCHED);
+ 
+-#if defined(CONFIG_IOSCHED_AS)
+-	strcpy(chosen_elevator, "anticipatory");
+-#elif defined(CONFIG_IOSCHED_DEADLINE)
+-	strcpy(chosen_elevator, "deadline");
+-#elif defined(CONFIG_IOSCHED_CFQ)
+-	strcpy(chosen_elevator, "cfq");
+-#elif defined(CONFIG_IOSCHED_NOOP)
+-	strcpy(chosen_elevator, "noop");
+-#else
+-#error "You must build at least 1 IO scheduler into the kernel"
+-#endif
++ 	/*
++ 	 * If the given scheduler is not available, fall back to no-op.
++ 	 */
++ 	if (!(e = elevator_find(chosen_elevator)))
++ 		strcpy(chosen_elevator, "noop");
++	elevator_put(e);
+ }
+ 
+ static int __init elevator_setup(char *str)
+@@ -186,6 +174,11 @@ int elevator_init(request_queue_t *q, ch
+ 	struct elevator_queue *eq;
+ 	int ret = 0;
+ 
++	INIT_LIST_HEAD(&q->queue_head);
++	q->last_merge = NULL;
++	q->end_sector = 0;
++	q->boundary_rq = NULL;
++
+ 	elevator_setup_default();
+ 
+ 	if (!name)
+@@ -220,9 +213,52 @@ void elevator_exit(elevator_t *e)
+ 	kfree(e);
+ }
+ 
++/*
++ * Insert rq into dispatch queue of q.  Queue lock must be held on
++ * entry.  If sort != 0, rq is sort-inserted; otherwise, rq will be
++ * appended to the dispatch queue.  To be used by specific elevators.
++ */
++void elv_dispatch_sort(request_queue_t *q, struct request *rq)
++{
++	sector_t boundary;
++	struct list_head *entry;
++
++	if (q->last_merge == rq)
++		q->last_merge = NULL;
++
++	boundary = q->end_sector;
++
++	list_for_each_prev(entry, &q->queue_head) {
++		struct request *pos = list_entry_rq(entry);
++
++		if (pos->flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED))
++			break;
++		if (rq->sector >= boundary) {
++			if (pos->sector < boundary)
++				continue;
++		} else {
++			if (pos->sector >= boundary)
++				break;
++		}
++		if (rq->sector >= pos->sector)
++			break;
++	}
++
++	list_add(&rq->queuelist, entry);
++}
++
+ int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
+ {
+ 	elevator_t *e = q->elevator;
++	int ret;
++
++	if (q->last_merge) {
++		ret = elv_try_merge(q->last_merge, bio);
++		if (ret != ELEVATOR_NO_MERGE) {
++			*req = q->last_merge;
++			return ret;
++		}
++	}
+ 
+ 	if (e->ops->elevator_merge_fn)
+ 		return e->ops->elevator_merge_fn(q, req, bio);
+@@ -236,6 +272,8 @@ void elv_merged_request(request_queue_t 
+ 
+ 	if (e->ops->elevator_merged_fn)
+ 		e->ops->elevator_merged_fn(q, rq);
++
++	q->last_merge = rq;
+ }
+ 
+ void elv_merge_requests(request_queue_t *q, struct request *rq,
+@@ -243,20 +281,13 @@ void elv_merge_requests(request_queue_t 
+ {
+ 	elevator_t *e = q->elevator;
+ 
+-	if (q->last_merge == next)
+-		q->last_merge = NULL;
+-
+ 	if (e->ops->elevator_merge_req_fn)
+ 		e->ops->elevator_merge_req_fn(q, rq, next);
++
++	q->last_merge = rq;
+ }
+ 
+-/*
+- * For careful internal use by the block layer. Essentially the same as
+- * a requeue in that it tells the io scheduler that this request is not
+- * active in the driver or hardware anymore, but we don't want the request
+- * added back to the scheduler. Function is not exported.
+- */
+-void elv_deactivate_request(request_queue_t *q, struct request *rq)
++void elv_requeue_request(request_queue_t *q, struct request *rq)
+ {
+ 	elevator_t *e = q->elevator;
+ 
+@@ -264,19 +295,14 @@ void elv_deactivate_request(request_queu
+ 	 * it already went through dequeue, we need to decrement the
+ 	 * in_flight count again
+ 	 */
+-	if (blk_account_rq(rq))
++	if (blk_account_rq(rq)) {
+ 		q->in_flight--;
++		if (blk_sorted_rq(rq) && e->ops->elevator_deactivate_req_fn)
++			e->ops->elevator_deactivate_req_fn(q, rq);
++	}
+ 
+ 	rq->flags &= ~REQ_STARTED;
+ 
+-	if (e->ops->elevator_deactivate_req_fn)
+-		e->ops->elevator_deactivate_req_fn(q, rq);
+-}
+-
+-void elv_requeue_request(request_queue_t *q, struct request *rq)
+-{
+-	elv_deactivate_request(q, rq);
+-
+ 	/*
+ 	 * if this is the flush, requeue the original instead and drop the flush
+ 	 */
+@@ -285,31 +311,27 @@ void elv_requeue_request(request_queue_t
+ 		rq = rq->end_io_data;
+ 	}
+ 
+-	/*
+-	 * the request is prepped and may have some resources allocated.
+-	 * allowing unprepped requests to pass this one may cause resource
+-	 * deadlock.  turn on softbarrier.
+-	 */
+-	rq->flags |= REQ_SOFTBARRIER;
+-
+-	/*
+-	 * if iosched has an explicit requeue hook, then use that. otherwise
+-	 * just put the request at the front of the queue
+-	 */
+-	if (q->elevator->ops->elevator_requeue_req_fn)
+-		q->elevator->ops->elevator_requeue_req_fn(q, rq);
+-	else
+-		__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
++	__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+ }
+ 
+ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
+ 		       int plug)
+ {
+-	/*
+-	 * barriers implicitly indicate back insertion
+-	 */
+-	if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER) &&
+-	    where == ELEVATOR_INSERT_SORT)
++	if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
++		/*
++		 * barriers implicitly indicate back insertion
++		 */
++		if (where == ELEVATOR_INSERT_SORT)
++			where = ELEVATOR_INSERT_BACK;
++
++		/*
++		 * this request is scheduling boundary, update end_sector
++		 */
++		if (blk_fs_request(rq)) {
++			q->end_sector = rq_end_sector(rq);
++			q->boundary_rq = rq;
++		}
++	} else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
+ 		where = ELEVATOR_INSERT_BACK;
+ 
+ 	if (plug)
+@@ -317,23 +339,59 @@ void __elv_add_request(request_queue_t *
+ 
+ 	rq->q = q;
+ 
+-	if (!test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)) {
+-		q->elevator->ops->elevator_add_req_fn(q, rq, where);
+-
+-		if (blk_queue_plugged(q)) {
+-			int nrq = q->rq.count[READ] + q->rq.count[WRITE]
+-				  - q->in_flight;
+-
+-			if (nrq >= q->unplug_thresh)
+-				__generic_unplug_device(q);
+-		}
+-	} else
++	switch (where) {
++	case ELEVATOR_INSERT_FRONT:
++		rq->flags |= REQ_SOFTBARRIER;
++
++		list_add(&rq->queuelist, &q->queue_head);
++		break;
++
++	case ELEVATOR_INSERT_BACK:
++		rq->flags |= REQ_SOFTBARRIER;
++
++		while (q->elevator->ops->elevator_dispatch_fn(q, 1))
++			;
++		list_add_tail(&rq->queuelist, &q->queue_head);
++		/*
++		 * We kick the queue here for the following reasons.
++		 * - The elevator might have returned NULL previously
++		 *   to delay requests and returned them now.  As the
++		 *   queue wasn't empty before this request, ll_rw_blk
++		 *   won't run the queue on return, resulting in hang.
++		 * - Usually, back inserted requests won't be merged
++		 *   with anything.  There's no point in delaying queue
++		 *   processing.
++		 */
++		blk_remove_plug(q);
++		q->request_fn(q);
++		break;
++
++	case ELEVATOR_INSERT_SORT:
++		BUG_ON(!blk_fs_request(rq));
++		rq->flags |= REQ_SORTED;
++		if (q->last_merge == NULL && rq_mergeable(rq))
++			q->last_merge = rq;
+ 		/*
+-		 * if drain is set, store the request "locally". when the drain
+-		 * is finished, the requests will be handed ordered to the io
+-		 * scheduler
++		 * Some ioscheds (cfq) run q->request_fn directly, so
++		 * rq cannot be accessed after calling
++		 * elevator_add_req_fn.
+ 		 */
+-		list_add_tail(&rq->queuelist, &q->drain_list);
++		q->elevator->ops->elevator_add_req_fn(q, rq);
++		break;
++
++	default:
++		printk(KERN_ERR "%s: bad insertion point %d\n",
++		       __FUNCTION__, where);
++		BUG();
++	}
++
++	if (blk_queue_plugged(q)) {
++		int nrq = q->rq.count[READ] + q->rq.count[WRITE]
++			- q->in_flight;
++
++		if (nrq >= q->unplug_thresh)
++			__generic_unplug_device(q);
++	}
+ }
+ 
+ void elv_add_request(request_queue_t *q, struct request *rq, int where,
+@@ -348,13 +406,19 @@ void elv_add_request(request_queue_t *q,
+ 
+ static inline struct request *__elv_next_request(request_queue_t *q)
+ {
+-	struct request *rq = q->elevator->ops->elevator_next_req_fn(q);
++	struct request *rq;
++
++	if (unlikely(list_empty(&q->queue_head) &&
++		     !q->elevator->ops->elevator_dispatch_fn(q, 0)))
++		return NULL;
++
++	rq = list_entry_rq(q->queue_head.next);
+ 
+ 	/*
+ 	 * if this is a barrier write and the device has to issue a
+ 	 * flush sequence to support it, check how far we are
+ 	 */
+-	if (rq && blk_fs_request(rq) && blk_barrier_rq(rq)) {
++	if (blk_fs_request(rq) && blk_barrier_rq(rq)) {
+ 		BUG_ON(q->ordered == QUEUE_ORDERED_NONE);
+ 
+ 		if (q->ordered == QUEUE_ORDERED_FLUSH &&
+@@ -371,15 +435,30 @@ struct request *elv_next_request(request
+ 	int ret;
+ 
+ 	while ((rq = __elv_next_request(q)) != NULL) {
+-		/*
+-		 * just mark as started even if we don't start it, a request
+-		 * that has been delayed should not be passed by new incoming
+-		 * requests
+-		 */
+-		rq->flags |= REQ_STARTED;
++		if (!(rq->flags & REQ_STARTED)) {
++			elevator_t *e = q->elevator;
+ 
+-		if (rq == q->last_merge)
+-			q->last_merge = NULL;
++			/*
++			 * This is the first time the device driver
++			 * sees this request (possibly after
++			 * requeueing).  Notify IO scheduler.
++			 */
++			if (blk_sorted_rq(rq) &&
++			    e->ops->elevator_activate_req_fn)
++				e->ops->elevator_activate_req_fn(q, rq);
++
++			/*
++			 * just mark as started even if we don't start
++			 * it, a request that has been delayed should
++			 * not be passed by new incoming requests
++			 */
++			rq->flags |= REQ_STARTED;
++		}
++
++		if (!q->boundary_rq || q->boundary_rq == rq) {
++			q->end_sector = rq_end_sector(rq);
++			q->boundary_rq = NULL;
++		}
+ 
+ 		if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn)
+ 			break;
+@@ -391,9 +470,9 @@ struct request *elv_next_request(request
+ 			/*
+ 			 * the request may have been (partially) prepped.
+ 			 * we need to keep this request in the front to
+-			 * avoid resource deadlock.  turn on softbarrier.
++			 * avoid resource deadlock.  REQ_STARTED will
++			 * prevent other fs requests from passing this one.
+ 			 */
+-			rq->flags |= REQ_SOFTBARRIER;
+ 			rq = NULL;
+ 			break;
+ 		} else if (ret == BLKPREP_KILL) {
+@@ -416,42 +495,32 @@ struct request *elv_next_request(request
+ 	return rq;
+ }
+ 
+-void elv_remove_request(request_queue_t *q, struct request *rq)
++void elv_dequeue_request(request_queue_t *q, struct request *rq)
+ {
+-	elevator_t *e = q->elevator;
++	BUG_ON(list_empty(&rq->queuelist));
++
++	list_del_init(&rq->queuelist);
+ 
+ 	/*
+ 	 * the time frame between a request being removed from the lists
+ 	 * and to it is freed is accounted as io that is in progress at
+-	 * the driver side. note that we only account requests that the
+-	 * driver has seen (REQ_STARTED set), to avoid false accounting
+-	 * for request-request merges
++	 * the driver side.
+ 	 */
+ 	if (blk_account_rq(rq))
+ 		q->in_flight++;
+-
+-	/*
+-	 * the main clearing point for q->last_merge is on retrieval of
+-	 * request by driver (it calls elv_next_request()), but it _can_
+-	 * also happen here if a request is added to the queue but later
+-	 * deleted without ever being given to driver (merged with another
+-	 * request).
+-	 */
+-	if (rq == q->last_merge)
+-		q->last_merge = NULL;
+-
+-	if (e->ops->elevator_remove_req_fn)
+-		e->ops->elevator_remove_req_fn(q, rq);
+ }
+ 
+ int elv_queue_empty(request_queue_t *q)
+ {
+ 	elevator_t *e = q->elevator;
+ 
++	if (!list_empty(&q->queue_head))
++		return 0;
++
+ 	if (e->ops->elevator_queue_empty_fn)
+ 		return e->ops->elevator_queue_empty_fn(q);
+ 
+-	return list_empty(&q->queue_head);
++	return 1;
+ }
+ 
+ struct request *elv_latter_request(request_queue_t *q, struct request *rq)
+@@ -487,7 +556,7 @@ struct request *elv_former_request(reque
+ }
+ 
+ int elv_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
+-		    int gfp_mask)
++		    gfp_t gfp_mask)
+ {
+ 	elevator_t *e = q->elevator;
+ 
+@@ -523,11 +592,11 @@ void elv_completed_request(request_queue
+ 	/*
+ 	 * request is released from the driver, io must be done
+ 	 */
+-	if (blk_account_rq(rq))
++	if (blk_account_rq(rq)) {
+ 		q->in_flight--;
+-
+-	if (e->ops->elevator_completed_req_fn)
+-		e->ops->elevator_completed_req_fn(q, rq);
++		if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn)
++			e->ops->elevator_completed_req_fn(q, rq);
++	}
+ }
+ 
+ int elv_register_queue(struct request_queue *q)
+@@ -555,10 +624,9 @@ void elv_unregister_queue(struct request
+ 
+ int elv_register(struct elevator_type *e)
+ {
++	spin_lock_irq(&elv_list_lock);
+ 	if (elevator_find(e->elevator_name))
+ 		BUG();
+-
+-	spin_lock_irq(&elv_list_lock);
+ 	list_add_tail(&e->list, &elv_list);
+ 	spin_unlock_irq(&elv_list_lock);
+ 
+@@ -572,6 +640,27 @@ EXPORT_SYMBOL_GPL(elv_register);
+ 
+ void elv_unregister(struct elevator_type *e)
+ {
++	struct task_struct *g, *p;
++
++	/*
++	 * Iterate every thread in the process to remove the io contexts.
++	 */
++	read_lock(&tasklist_lock);
++	do_each_thread(g, p) {
++		struct io_context *ioc = p->io_context;
++		if (ioc && ioc->cic) {
++			ioc->cic->exit(ioc->cic);
++			ioc->cic->dtor(ioc->cic);
++			ioc->cic = NULL;
++		}
++		if (ioc && ioc->aic) {
++			ioc->aic->exit(ioc->aic);
++			ioc->aic->dtor(ioc->aic);
++			ioc->aic = NULL;
++		}
++	} while_each_thread(g, p);
++	read_unlock(&tasklist_lock);
++
+ 	spin_lock_irq(&elv_list_lock);
+ 	list_del_init(&e->list);
+ 	spin_unlock_irq(&elv_list_lock);
+@@ -582,25 +671,36 @@ EXPORT_SYMBOL_GPL(elv_unregister);
+  * switch to new_e io scheduler. be careful not to introduce deadlocks -
+  * we don't free the old io scheduler, before we have allocated what we
+  * need for the new one. this way we have a chance of going back to the old
+- * one, if the new one fails init for some reason. we also do an intermediate
+- * switch to noop to ensure safety with stack-allocated requests, since they
+- * don't originate from the block layer allocator. noop is safe here, because
+- * it never needs to touch the elevator itself for completion events. DRAIN
+- * flags will make sure we don't touch it for additions either.
++ * one, if the new one fails init for some reason.
+  */
+ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
+ {
+-	elevator_t *e = kmalloc(sizeof(elevator_t), GFP_KERNEL);
+-	struct elevator_type *noop_elevator = NULL;
+-	elevator_t *old_elevator;
++	elevator_t *old_elevator, *e;
+ 
++	/*
++	 * Allocate new elevator
++	 */
++	e = kmalloc(sizeof(elevator_t), GFP_KERNEL);
+ 	if (!e)
+ 		goto error;
+ 
+ 	/*
+-	 * first step, drain requests from the block freelist
++	 * Turn on BYPASS and drain all requests w/ elevator private data
+ 	 */
+-	blk_wait_queue_drained(q, 0);
++	spin_lock_irq(q->queue_lock);
++
++	set_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
++
++	while (q->elevator->ops->elevator_dispatch_fn(q, 1))
++		;
++
++	while (q->rq.elvpriv) {
++		spin_unlock_irq(q->queue_lock);
++		msleep(10);
++		spin_lock_irq(q->queue_lock);
++	}
++
++	spin_unlock_irq(q->queue_lock);
+ 
+ 	/*
+ 	 * unregister old elevator data
+@@ -609,18 +709,6 @@ static void elevator_switch(request_queu
+ 	old_elevator = q->elevator;
+ 
+ 	/*
+- 	 * next step, switch to noop since it uses no private rq structures
+-	 * and doesn't allocate any memory for anything. then wait for any
+-	 * non-fs requests in-flight
+- 	 */
+-	noop_elevator = elevator_get("noop");
+-	spin_lock_irq(q->queue_lock);
+-	elevator_attach(q, noop_elevator, e);
+-	spin_unlock_irq(q->queue_lock);
+-
+-	blk_wait_queue_drained(q, 1);
+-
+-	/*
+ 	 * attach and start new elevator
+ 	 */
+ 	if (elevator_attach(q, new_e, e))
+@@ -630,11 +718,10 @@ static void elevator_switch(request_queu
+ 		goto fail_register;
+ 
+ 	/*
+-	 * finally exit old elevator and start queue again
++	 * finally exit old elevator and turn off BYPASS.
+ 	 */
+ 	elevator_exit(old_elevator);
+-	blk_finish_queue_drain(q);
+-	elevator_put(noop_elevator);
++	clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
+ 	return;
+ 
+ fail_register:
+@@ -643,13 +730,13 @@ fail_register:
+ 	 * one again (along with re-adding the sysfs dir)
+ 	 */
+ 	elevator_exit(e);
++	e = NULL;
+ fail:
+ 	q->elevator = old_elevator;
+ 	elv_register_queue(q);
+-	blk_finish_queue_drain(q);
++	clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
++	kfree(e);
+ error:
+-	if (noop_elevator)
+-		elevator_put(noop_elevator);
+ 	elevator_put(new_e);
+ 	printk(KERN_ERR "elevator: switch to %s failed\n",new_e->elevator_name);
+ }
+@@ -671,8 +758,10 @@ ssize_t elv_iosched_store(request_queue_
+ 		return -EINVAL;
+ 	}
+ 
+-	if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name))
++	if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
++		elevator_put(e);
+ 		return count;
++	}
+ 
+ 	elevator_switch(q, e);
+ 	return count;
+@@ -701,11 +790,12 @@ ssize_t elv_iosched_show(request_queue_t
+ 	return len;
+ }
+ 
++EXPORT_SYMBOL(elv_dispatch_sort);
+ EXPORT_SYMBOL(elv_add_request);
+ EXPORT_SYMBOL(__elv_add_request);
+ EXPORT_SYMBOL(elv_requeue_request);
+ EXPORT_SYMBOL(elv_next_request);
+-EXPORT_SYMBOL(elv_remove_request);
++EXPORT_SYMBOL(elv_dequeue_request);
+ EXPORT_SYMBOL(elv_queue_empty);
+ EXPORT_SYMBOL(elv_completed_request);
+ EXPORT_SYMBOL(elevator_exit);
+diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
+--- a/drivers/block/floppy.c
++++ b/drivers/block/floppy.c
+@@ -177,7 +177,7 @@ static int print_unex = 1;
+ #include <linux/interrupt.h>
+ #include <linux/init.h>
+ #include <linux/devfs_fs_kernel.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/buffer_head.h>	/* for invalidate_buffers() */
+ 
+ /*
+diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
+--- a/drivers/block/genhd.c
++++ b/drivers/block/genhd.c
+@@ -337,10 +337,30 @@ static ssize_t disk_attr_show(struct kob
+ 	return ret;
+ }
+ 
++static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr,
++			       const char *page, size_t count)
++{
++	struct gendisk *disk = to_disk(kobj);
++	struct disk_attribute *disk_attr =
++		container_of(attr,struct disk_attribute,attr);
++	ssize_t ret = 0;
++
++	if (disk_attr->store)
++		ret = disk_attr->store(disk, page, count);
++	return ret;
++}
++
+ static struct sysfs_ops disk_sysfs_ops = {
+ 	.show	= &disk_attr_show,
++	.store	= &disk_attr_store,
+ };
+ 
++static ssize_t disk_uevent_store(struct gendisk * disk,
++				 const char *buf, size_t count)
++{
++	kobject_hotplug(&disk->kobj, KOBJ_ADD);
++	return count;
++}
+ static ssize_t disk_dev_read(struct gendisk * disk, char *page)
+ {
+ 	dev_t base = MKDEV(disk->major, disk->first_minor); 
+@@ -382,6 +402,10 @@ static ssize_t disk_stats_read(struct ge
+ 		jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
+ 		jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
+ }
++static struct disk_attribute disk_attr_uevent = {
++	.attr = {.name = "uevent", .mode = S_IWUSR },
++	.store	= disk_uevent_store
++};
+ static struct disk_attribute disk_attr_dev = {
+ 	.attr = {.name = "dev", .mode = S_IRUGO },
+ 	.show	= disk_dev_read
+@@ -404,6 +428,7 @@ static struct disk_attribute disk_attr_s
+ };
+ 
+ static struct attribute * default_attrs[] = {
++	&disk_attr_uevent.attr,
+ 	&disk_attr_dev.attr,
+ 	&disk_attr_range.attr,
+ 	&disk_attr_removable.attr,
+diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
+--- a/drivers/block/ll_rw_blk.c
++++ b/drivers/block/ll_rw_blk.c
+@@ -263,8 +263,6 @@ void blk_queue_make_request(request_queu
+ 	blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
+ 
+ 	blk_queue_activity_fn(q, NULL, NULL);
+-
+-	INIT_LIST_HEAD(&q->drain_list);
+ }
+ 
+ EXPORT_SYMBOL(blk_queue_make_request);
+@@ -353,6 +351,8 @@ static void blk_pre_flush_end_io(struct 
+ 	struct request *rq = flush_rq->end_io_data;
+ 	request_queue_t *q = rq->q;
+ 
++	elv_completed_request(q, flush_rq);
++
+ 	rq->flags |= REQ_BAR_PREFLUSH;
+ 
+ 	if (!flush_rq->errors)
+@@ -369,6 +369,8 @@ static void blk_post_flush_end_io(struct
+ 	struct request *rq = flush_rq->end_io_data;
+ 	request_queue_t *q = rq->q;
+ 
++	elv_completed_request(q, flush_rq);
++
+ 	rq->flags |= REQ_BAR_POSTFLUSH;
+ 
+ 	q->end_flush_fn(q, flush_rq);
+@@ -408,8 +410,6 @@ struct request *blk_start_pre_flush(requ
+ 	if (!list_empty(&rq->queuelist))
+ 		blkdev_dequeue_request(rq);
+ 
+-	elv_deactivate_request(q, rq);
+-
+ 	flush_rq->end_io_data = rq;
+ 	flush_rq->end_io = blk_pre_flush_end_io;
+ 
+@@ -1040,6 +1040,7 @@ EXPORT_SYMBOL(blk_queue_invalidate_tags)
+ static char *rq_flags[] = {
+ 	"REQ_RW",
+ 	"REQ_FAILFAST",
++	"REQ_SORTED",
+ 	"REQ_SOFTBARRIER",
+ 	"REQ_HARDBARRIER",
+ 	"REQ_CMD",
+@@ -1047,6 +1048,7 @@ static char *rq_flags[] = {
+ 	"REQ_STARTED",
+ 	"REQ_DONTPREP",
+ 	"REQ_QUEUED",
++	"REQ_ELVPRIV",
+ 	"REQ_PC",
+ 	"REQ_BLOCK_PC",
+ 	"REQ_SENSE",
+@@ -1637,9 +1639,9 @@ static int blk_init_free_list(request_qu
+ 
+ 	rl->count[READ] = rl->count[WRITE] = 0;
+ 	rl->starved[READ] = rl->starved[WRITE] = 0;
++	rl->elvpriv = 0;
+ 	init_waitqueue_head(&rl->wait[READ]);
+ 	init_waitqueue_head(&rl->wait[WRITE]);
+-	init_waitqueue_head(&rl->drain);
+ 
+ 	rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
+ 				mempool_free_slab, request_cachep, q->node);
+@@ -1652,13 +1654,13 @@ static int blk_init_free_list(request_qu
+ 
+ static int __make_request(request_queue_t *, struct bio *);
+ 
+-request_queue_t *blk_alloc_queue(int gfp_mask)
++request_queue_t *blk_alloc_queue(gfp_t gfp_mask)
+ {
+ 	return blk_alloc_queue_node(gfp_mask, -1);
+ }
+ EXPORT_SYMBOL(blk_alloc_queue);
+ 
+-request_queue_t *blk_alloc_queue_node(int gfp_mask, int node_id)
++request_queue_t *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
+ {
+ 	request_queue_t *q;
+ 
+@@ -1782,12 +1784,14 @@ EXPORT_SYMBOL(blk_get_queue);
+ 
+ static inline void blk_free_request(request_queue_t *q, struct request *rq)
+ {
+-	elv_put_request(q, rq);
++	if (rq->flags & REQ_ELVPRIV)
++		elv_put_request(q, rq);
+ 	mempool_free(rq, q->rq.rq_pool);
+ }
+ 
+ static inline struct request *
+-blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, int gfp_mask)
++blk_alloc_request(request_queue_t *q, int rw, struct bio *bio,
++		  int priv, gfp_t gfp_mask)
+ {
+ 	struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
+ 
+@@ -1800,11 +1804,15 @@ blk_alloc_request(request_queue_t *q, in
+ 	 */
+ 	rq->flags = rw;
+ 
+-	if (!elv_set_request(q, rq, bio, gfp_mask))
+-		return rq;
++	if (priv) {
++		if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) {
++			mempool_free(rq, q->rq.rq_pool);
++			return NULL;
++		}
++		rq->flags |= REQ_ELVPRIV;
++	}
+ 
+-	mempool_free(rq, q->rq.rq_pool);
+-	return NULL;
++	return rq;
+ }
+ 
+ /*
+@@ -1860,22 +1868,18 @@ static void __freed_request(request_queu
+  * A request has just been released.  Account for it, update the full and
+  * congestion status, wake up any waiters.   Called under q->queue_lock.
+  */
+-static void freed_request(request_queue_t *q, int rw)
++static void freed_request(request_queue_t *q, int rw, int priv)
+ {
+ 	struct request_list *rl = &q->rq;
+ 
+ 	rl->count[rw]--;
++	if (priv)
++		rl->elvpriv--;
+ 
+ 	__freed_request(q, rw);
+ 
+ 	if (unlikely(rl->starved[rw ^ 1]))
+ 		__freed_request(q, rw ^ 1);
+-
+-	if (!rl->count[READ] && !rl->count[WRITE]) {
+-		smp_mb();
+-		if (unlikely(waitqueue_active(&rl->drain)))
+-			wake_up(&rl->drain);
+-	}
+ }
+ 
+ #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
+@@ -1885,14 +1889,12 @@ static void freed_request(request_queue_
+  * Returns !NULL on success, with queue_lock *not held*.
+  */
+ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
+-				   int gfp_mask)
++				   gfp_t gfp_mask)
+ {
+ 	struct request *rq = NULL;
+ 	struct request_list *rl = &q->rq;
+ 	struct io_context *ioc = current_io_context(GFP_ATOMIC);
+-
+-	if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)))
+-		goto out;
++	int priv;
+ 
+ 	if (rl->count[rw]+1 >= q->nr_requests) {
+ 		/*
+@@ -1937,9 +1939,14 @@ get_rq:
+ 	rl->starved[rw] = 0;
+ 	if (rl->count[rw] >= queue_congestion_on_threshold(q))
+ 		set_queue_congested(q, rw);
++
++	priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
++	if (priv)
++		rl->elvpriv++;
++
+ 	spin_unlock_irq(q->queue_lock);
+ 
+-	rq = blk_alloc_request(q, rw, bio, gfp_mask);
++	rq = blk_alloc_request(q, rw, bio, priv, gfp_mask);
+ 	if (!rq) {
+ 		/*
+ 		 * Allocation failed presumably due to memory. Undo anything
+@@ -1949,7 +1956,7 @@ get_rq:
+ 		 * wait queue, but this is pretty rare.
+ 		 */
+ 		spin_lock_irq(q->queue_lock);
+-		freed_request(q, rw);
++		freed_request(q, rw, priv);
+ 
+ 		/*
+ 		 * in the very unlikely event that allocation failed and no
+@@ -2019,7 +2026,7 @@ static struct request *get_request_wait(
+ 	return rq;
+ }
+ 
+-struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
++struct request *blk_get_request(request_queue_t *q, int rw, gfp_t gfp_mask)
+ {
+ 	struct request *rq;
+ 
+@@ -2251,7 +2258,7 @@ EXPORT_SYMBOL(blk_rq_unmap_user);
+  * @gfp_mask:	memory allocation flags
+  */
+ int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
+-		    unsigned int len, unsigned int gfp_mask)
++		    unsigned int len, gfp_t gfp_mask)
+ {
+ 	struct bio *bio;
+ 
+@@ -2433,13 +2440,15 @@ void disk_round_stats(struct gendisk *di
+ {
+ 	unsigned long now = jiffies;
+ 
+-	__disk_stat_add(disk, time_in_queue,
+-			disk->in_flight * (now - disk->stamp));
+-	disk->stamp = now;
++	if (now == disk->stamp)
++		return;
+ 
+-	if (disk->in_flight)
+-		__disk_stat_add(disk, io_ticks, (now - disk->stamp_idle));
+-	disk->stamp_idle = now;
++	if (disk->in_flight) {
++		__disk_stat_add(disk, time_in_queue,
++				disk->in_flight * (now - disk->stamp));
++		__disk_stat_add(disk, io_ticks, (now - disk->stamp));
++	}
++	disk->stamp = now;
+ }
+ 
+ /*
+@@ -2454,6 +2463,8 @@ static void __blk_put_request(request_qu
+ 	if (unlikely(--req->ref_count))
+ 		return;
+ 
++	elv_completed_request(q, req);
++
+ 	req->rq_status = RQ_INACTIVE;
+ 	req->rl = NULL;
+ 
+@@ -2463,26 +2474,25 @@ static void __blk_put_request(request_qu
+ 	 */
+ 	if (rl) {
+ 		int rw = rq_data_dir(req);
+-
+-		elv_completed_request(q, req);
++		int priv = req->flags & REQ_ELVPRIV;
+ 
+ 		BUG_ON(!list_empty(&req->queuelist));
+ 
+ 		blk_free_request(q, req);
+-		freed_request(q, rw);
++		freed_request(q, rw, priv);
+ 	}
+ }
+ 
+ void blk_put_request(struct request *req)
+ {
++	unsigned long flags;
++	request_queue_t *q = req->q;
++
+ 	/*
+-	 * if req->rl isn't set, this request didnt originate from the
+-	 * block layer, so it's safe to just disregard it
++	 * Gee, IDE calls in w/ NULL q.  Fix IDE and remove the
++	 * following if (q) test.
+ 	 */
+-	if (req->rl) {
+-		unsigned long flags;
+-		request_queue_t *q = req->q;
+-
++	if (q) {
+ 		spin_lock_irqsave(q->queue_lock, flags);
+ 		__blk_put_request(q, req);
+ 		spin_unlock_irqrestore(q->queue_lock, flags);
+@@ -2797,97 +2807,6 @@ static inline void blk_partition_remap(s
+ 	}
+ }
+ 
+-void blk_finish_queue_drain(request_queue_t *q)
+-{
+-	struct request_list *rl = &q->rq;
+-	struct request *rq;
+-	int requeued = 0;
+-
+-	spin_lock_irq(q->queue_lock);
+-	clear_bit(QUEUE_FLAG_DRAIN, &q->queue_flags);
+-
+-	while (!list_empty(&q->drain_list)) {
+-		rq = list_entry_rq(q->drain_list.next);
+-
+-		list_del_init(&rq->queuelist);
+-		elv_requeue_request(q, rq);
+-		requeued++;
+-	}
+-
+-	if (requeued)
+-		q->request_fn(q);
+-
+-	spin_unlock_irq(q->queue_lock);
+-
+-	wake_up(&rl->wait[0]);
+-	wake_up(&rl->wait[1]);
+-	wake_up(&rl->drain);
+-}
+-
+-static int wait_drain(request_queue_t *q, struct request_list *rl, int dispatch)
+-{
+-	int wait = rl->count[READ] + rl->count[WRITE];
+-
+-	if (dispatch)
+-		wait += !list_empty(&q->queue_head);
+-
+-	return wait;
+-}
+-
+-/*
+- * We rely on the fact that only requests allocated through blk_alloc_request()
+- * have io scheduler private data structures associated with them. Any other
+- * type of request (allocated on stack or through kmalloc()) should not go
+- * to the io scheduler core, but be attached to the queue head instead.
+- */
+-void blk_wait_queue_drained(request_queue_t *q, int wait_dispatch)
+-{
+-	struct request_list *rl = &q->rq;
+-	DEFINE_WAIT(wait);
+-
+-	spin_lock_irq(q->queue_lock);
+-	set_bit(QUEUE_FLAG_DRAIN, &q->queue_flags);
+-
+-	while (wait_drain(q, rl, wait_dispatch)) {
+-		prepare_to_wait(&rl->drain, &wait, TASK_UNINTERRUPTIBLE);
+-
+-		if (wait_drain(q, rl, wait_dispatch)) {
+-			__generic_unplug_device(q);
+-			spin_unlock_irq(q->queue_lock);
+-			io_schedule();
+-			spin_lock_irq(q->queue_lock);
+-		}
+-
+-		finish_wait(&rl->drain, &wait);
+-	}
+-
+-	spin_unlock_irq(q->queue_lock);
+-}
+-
+-/*
+- * block waiting for the io scheduler being started again.
+- */
+-static inline void block_wait_queue_running(request_queue_t *q)
+-{
+-	DEFINE_WAIT(wait);
+-
+-	while (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) {
+-		struct request_list *rl = &q->rq;
+-
+-		prepare_to_wait_exclusive(&rl->drain, &wait,
+-				TASK_UNINTERRUPTIBLE);
+-
+-		/*
+-		 * re-check the condition. avoids using prepare_to_wait()
+-		 * in the fast path (queue is running)
+-		 */
+-		if (test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))
+-			io_schedule();
+-
+-		finish_wait(&rl->drain, &wait);
+-	}
+-}
+-
+ static void handle_bad_sector(struct bio *bio)
+ {
+ 	char b[BDEVNAME_SIZE];
+@@ -2983,8 +2902,6 @@ end_io:
+ 		if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
+ 			goto end_io;
+ 
+-		block_wait_queue_running(q);
+-
+ 		/*
+ 		 * If this device has partitions, remap block n
+ 		 * of partition p to block n+start(p) of the disk.
+@@ -3393,7 +3310,7 @@ void exit_io_context(void)
+  * but since the current task itself holds a reference, the context can be
+  * used in general code, so long as it stays within `current` context.
+  */
+-struct io_context *current_io_context(int gfp_flags)
++struct io_context *current_io_context(gfp_t gfp_flags)
+ {
+ 	struct task_struct *tsk = current;
+ 	struct io_context *ret;
+@@ -3424,7 +3341,7 @@ EXPORT_SYMBOL(current_io_context);
+  *
+  * This is always called in the context of the task which submitted the I/O.
+  */
+-struct io_context *get_io_context(int gfp_flags)
++struct io_context *get_io_context(gfp_t gfp_flags)
+ {
+ 	struct io_context *ret;
+ 	ret = current_io_context(gfp_flags);
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -881,7 +881,7 @@ loop_init_xfer(struct loop_device *lo, s
+ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
+ {
+ 	struct file *filp = lo->lo_backing_file;
+-	int gfp = lo->old_gfp_mask;
++	gfp_t gfp = lo->old_gfp_mask;
+ 
+ 	if (lo->lo_state != Lo_bound)
+ 		return -ENXIO;
+diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
+--- a/drivers/block/noop-iosched.c
++++ b/drivers/block/noop-iosched.c
+@@ -7,57 +7,20 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ 
+-/*
+- * See if we can find a request that this buffer can be coalesced with.
+- */
+-static int elevator_noop_merge(request_queue_t *q, struct request **req,
+-			       struct bio *bio)
++static void elevator_noop_add_request(request_queue_t *q, struct request *rq)
+ {
+-	int ret;
+-
+-	ret = elv_try_last_merge(q, bio);
+-	if (ret != ELEVATOR_NO_MERGE)
+-		*req = q->last_merge;
+-
+-	return ret;
+-}
+-
+-static void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
+-					 struct request *next)
+-{
+-	list_del_init(&next->queuelist);
++	rq->flags |= REQ_NOMERGE;
++	elv_dispatch_add_tail(q, rq);
+ }
+ 
+-static void elevator_noop_add_request(request_queue_t *q, struct request *rq,
+-				      int where)
++static int elevator_noop_dispatch(request_queue_t *q, int force)
+ {
+-	if (where == ELEVATOR_INSERT_FRONT)
+-		list_add(&rq->queuelist, &q->queue_head);
+-	else
+-		list_add_tail(&rq->queuelist, &q->queue_head);
+-
+-	/*
+-	 * new merges must not precede this barrier
+-	 */
+-	if (rq->flags & REQ_HARDBARRIER)
+-		q->last_merge = NULL;
+-	else if (!q->last_merge)
+-		q->last_merge = rq;
+-}
+-
+-static struct request *elevator_noop_next_request(request_queue_t *q)
+-{
+-	if (!list_empty(&q->queue_head))
+-		return list_entry_rq(q->queue_head.next);
+-
+-	return NULL;
++	return 0;
+ }
+ 
+ static struct elevator_type elevator_noop = {
+ 	.ops = {
+-		.elevator_merge_fn		= elevator_noop_merge,
+-		.elevator_merge_req_fn		= elevator_noop_merge_requests,
+-		.elevator_next_req_fn		= elevator_noop_next_request,
++		.elevator_dispatch_fn		= elevator_noop_dispatch,
+ 		.elevator_add_req_fn		= elevator_noop_add_request,
+ 	},
+ 	.elevator_name = "noop",
+diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
+--- a/drivers/block/paride/paride.c
++++ b/drivers/block/paride/paride.c
+@@ -29,6 +29,7 @@
+ #include <linux/string.h>
+ #include <linux/spinlock.h>
+ #include <linux/wait.h>
++#include <linux/sched.h>	/* TASK_* */
+ 
+ #ifdef CONFIG_PARPORT_MODULE
+ #define CONFIG_PARPORT
+diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
+--- a/drivers/block/paride/pf.c
++++ b/drivers/block/paride/pf.c
+@@ -807,10 +807,6 @@ static int pf_next_buf(void)
+ 		return 1;
+ 	spin_lock_irqsave(&pf_spin_lock, saved_flags);
+ 	pf_end_request(1);
+-	if (pf_req) {
+-		pf_count = pf_req->current_nr_sectors;
+-		pf_buf = pf_req->buffer;
+-	}
+ 	spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
+ 	return 1;
+ }
+diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
+--- a/drivers/block/paride/pg.c
++++ b/drivers/block/paride/pg.c
+@@ -162,6 +162,8 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV,
+ #include <linux/mtio.h>
+ #include <linux/pg.h>
+ #include <linux/device.h>
++#include <linux/sched.h>	/* current, TASK_* */
++#include <linux/jiffies.h>
+ 
+ #include <asm/uaccess.h>
+ 
+@@ -674,7 +676,7 @@ static int __init pg_init(void)
+ 	for (unit = 0; unit < PG_UNITS; unit++) {
+ 		struct pg *dev = &devices[unit];
+ 		if (dev->present) {
+-			class_device_create(pg_class, MKDEV(major, unit),
++			class_device_create(pg_class, NULL, MKDEV(major, unit),
+ 					NULL, "pg%u", unit);
+ 			err = devfs_mk_cdev(MKDEV(major, unit),
+ 				      S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
+diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
+--- a/drivers/block/paride/pt.c
++++ b/drivers/block/paride/pt.c
+@@ -146,6 +146,7 @@ static int (*drives[4])[6] = {&drive0, &
+ #include <linux/slab.h>
+ #include <linux/mtio.h>
+ #include <linux/device.h>
++#include <linux/sched.h>	/* current, TASK_*, schedule_timeout() */
+ 
+ #include <asm/uaccess.h>
+ 
+@@ -971,7 +972,7 @@ static int __init pt_init(void)
+ 	devfs_mk_dir("pt");
+ 	for (unit = 0; unit < PT_UNITS; unit++)
+ 		if (pt[unit].present) {
+-			class_device_create(pt_class, MKDEV(major, unit),
++			class_device_create(pt_class, NULL, MKDEV(major, unit),
+ 					NULL, "pt%d", unit);
+ 			err = devfs_mk_cdev(MKDEV(major, unit),
+ 				      S_IFCHR | S_IRUSR | S_IWUSR,
+@@ -980,7 +981,7 @@ static int __init pt_init(void)
+ 				class_device_destroy(pt_class, MKDEV(major, unit));
+ 				goto out_class;
+ 			}
+-			class_device_create(pt_class, MKDEV(major, unit + 128),
++			class_device_create(pt_class, NULL, MKDEV(major, unit + 128),
+ 					NULL, "pt%dn", unit);
+ 			err = devfs_mk_cdev(MKDEV(major, unit + 128),
+ 				      S_IFCHR | S_IRUSR | S_IWUSR,
+diff --git a/drivers/block/rd.c b/drivers/block/rd.c
+--- a/drivers/block/rd.c
++++ b/drivers/block/rd.c
+@@ -348,7 +348,7 @@ static int rd_open(struct inode *inode, 
+ 		struct block_device *bdev = inode->i_bdev;
+ 		struct address_space *mapping;
+ 		unsigned bsize;
+-		int gfp_mask;
++		gfp_t gfp_mask;
+ 
+ 		inode = igrab(bdev->bd_inode);
+ 		rd_bdev[unit] = bdev;
+diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
+--- a/drivers/block/sx8.c
++++ b/drivers/block/sx8.c
+@@ -1,7 +1,7 @@
+ /*
+  *  sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware
+  *
+- *  Copyright 2004 Red Hat, Inc.
++ *  Copyright 2004-2005 Red Hat, Inc.
+  *
+  *  Author/maintainer:  Jeff Garzik <jgarzik at pobox.com>
+  *
+@@ -31,10 +31,6 @@
+ #include <asm/semaphore.h>
+ #include <asm/uaccess.h>
+ 
+-MODULE_AUTHOR("Jeff Garzik");
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("Promise SATA SX8 block driver");
+-
+ #if 0
+ #define CARM_DEBUG
+ #define CARM_VERBOSE_DEBUG
+@@ -45,9 +41,35 @@ MODULE_DESCRIPTION("Promise SATA SX8 blo
+ #undef CARM_NDEBUG
+ 
+ #define DRV_NAME "sx8"
+-#define DRV_VERSION "0.8"
++#define DRV_VERSION "1.0"
+ #define PFX DRV_NAME ": "
+ 
++MODULE_AUTHOR("Jeff Garzik");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Promise SATA SX8 block driver");
++MODULE_VERSION(DRV_VERSION);
++
++/*
++ * SX8 hardware has a single message queue for all ATA ports.
++ * When this driver was written, the hardware (firmware?) would
++ * corrupt data eventually, if more than one request was outstanding.
++ * As one can imagine, having 8 ports bottlenecking on a single
++ * command hurts performance.
++ *
++ * Based on user reports, later versions of the hardware (firmware?)
++ * seem to be able to survive with more than one command queued.
++ *
++ * Therefore, we default to the safe option -- 1 command -- but
++ * allow the user to increase this.
++ *
++ * SX8 should be able to support up to ~60 queued commands (CARM_MAX_REQ),
++ * but problems seem to occur when you exceed ~30, even on newer hardware.
++ */
++static int max_queue = 1;
++module_param(max_queue, int, 0444);
++MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30, safe==1)");
++
++
+ #define NEXT_RESP(idx)	((idx + 1) % RMSG_Q_LEN)
+ 
+ /* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */
+@@ -90,12 +112,10 @@ enum {
+ 
+ 	/* command message queue limits */
+ 	CARM_MAX_REQ		= 64,	       /* max command msgs per host */
+-	CARM_MAX_Q		= 1,		   /* one command at a time */
+ 	CARM_MSG_LOW_WATER	= (CARM_MAX_REQ / 4),	     /* refill mark */
+ 
+ 	/* S/G limits, host-wide and per-request */
+ 	CARM_MAX_REQ_SG		= 32,	     /* max s/g entries per request */
+-	CARM_SG_BOUNDARY	= 0xffffUL,	    /* s/g segment boundary */
+ 	CARM_MAX_HOST_SG	= 600,		/* max s/g entries per host */
+ 	CARM_SG_LOW_WATER	= (CARM_MAX_HOST_SG / 4),   /* re-fill mark */
+ 
+@@ -181,6 +201,10 @@ enum {
+ 	FL_DYN_MAJOR		= (1 << 17),
+ };
+ 
++enum {
++	CARM_SG_BOUNDARY	= 0xffffUL,	    /* s/g segment boundary */
++};
++
+ enum scatter_gather_types {
+ 	SGT_32BIT		= 0,
+ 	SGT_64BIT		= 1,
+@@ -218,7 +242,6 @@ static const char *state_name[] = {
+ 
+ struct carm_port {
+ 	unsigned int			port_no;
+-	unsigned int			n_queued;
+ 	struct gendisk			*disk;
+ 	struct carm_host		*host;
+ 
+@@ -448,7 +471,7 @@ static inline int carm_lookup_bucket(u32
+ 	for (i = 0; i < ARRAY_SIZE(msg_sizes); i++)
+ 		if (msg_size <= msg_sizes[i])
+ 			return i;
+-	
++
+ 	return -ENOENT;
+ }
+ 
+@@ -509,7 +532,7 @@ static struct carm_request *carm_get_req
+ 	if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG))
+ 		return NULL;
+ 
+-	for (i = 0; i < CARM_MAX_Q; i++)
++	for (i = 0; i < max_queue; i++)
+ 		if ((host->msg_alloc & (1ULL << i)) == 0) {
+ 			struct carm_request *crq = &host->req[i];
+ 			crq->port = NULL;
+@@ -521,14 +544,14 @@ static struct carm_request *carm_get_req
+ 			assert(host->n_msgs <= CARM_MAX_REQ);
+ 			return crq;
+ 		}
+-	
++
+ 	DPRINTK("no request available, returning NULL\n");
+ 	return NULL;
+ }
+ 
+ static int carm_put_request(struct carm_host *host, struct carm_request *crq)
+ {
+-	assert(crq->tag < CARM_MAX_Q);
++	assert(crq->tag < max_queue);
+ 
+ 	if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0))
+ 		return -EINVAL; /* tried to clear a tag that was not active */
+@@ -791,7 +814,7 @@ static inline void carm_end_rq(struct ca
+ 			int is_ok)
+ {
+ 	carm_end_request_queued(host, crq, is_ok);
+-	if (CARM_MAX_Q == 1)
++	if (max_queue == 1)
+ 		carm_round_robin(host);
+ 	else if ((host->n_msgs <= CARM_MSG_LOW_WATER) &&
+ 		 (host->hw_sg_used <= CARM_SG_LOW_WATER)) {
+diff --git a/drivers/block/ub.c b/drivers/block/ub.c
+--- a/drivers/block/ub.c
++++ b/drivers/block/ub.c
+@@ -1512,7 +1512,7 @@ static void ub_state_sense(struct ub_dev
+ 	scmd->nsg = 1;
+ 	sg = &scmd->sgv[0];
+ 	sg->page = virt_to_page(sc->top_sense);
+-	sg->offset = (unsigned int)sc->top_sense & (PAGE_SIZE-1);
++	sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
+ 	sg->length = UB_SENSE_SIZE;
+ 	scmd->len = UB_SENSE_SIZE;
+ 	scmd->lun = cmd->lun;
+@@ -1891,7 +1891,7 @@ static int ub_sync_read_cap(struct ub_de
+ 	cmd->nsg = 1;
+ 	sg = &cmd->sgv[0];
+ 	sg->page = virt_to_page(p);
+-	sg->offset = (unsigned int)p & (PAGE_SIZE-1);
++	sg->offset = (unsigned long)p & (PAGE_SIZE-1);
+ 	sg->length = 8;
+ 	cmd->len = 8;
+ 	cmd->lun = lun;
+diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
+--- a/drivers/block/viodasd.c
++++ b/drivers/block/viodasd.c
+@@ -778,13 +778,16 @@ static struct vio_device_id viodasd_devi
+ 	{ "viodasd", "" },
+ 	{ "", "" }
+ };
+-
+ MODULE_DEVICE_TABLE(vio, viodasd_device_table);
++
+ static struct vio_driver viodasd_driver = {
+-	.name = "viodasd",
+ 	.id_table = viodasd_device_table,
+ 	.probe = viodasd_probe,
+-	.remove = viodasd_remove
++	.remove = viodasd_remove,
++	.driver = {
++		.name = "viodasd",
++		.owner = THIS_MODULE,
++	}
+ };
+ 
+ /*
+diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
+--- a/drivers/bluetooth/Kconfig
++++ b/drivers/bluetooth/Kconfig
+@@ -55,14 +55,6 @@ config BT_HCIUART_BCSP
+ 
+ 	  Say Y here to compile support for HCI BCSP protocol.
+ 
+-config BT_HCIUART_BCSP_TXCRC
+-	bool "Transmit CRC with every BCSP packet"
+-	depends on BT_HCIUART_BCSP
+-	help
+-	  If you say Y here, a 16-bit CRC checksum will be transmitted along with
+-	  every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
+-	  This increases reliability, but slightly reduces efficiency.
+-
+ config BT_HCIBCM203X
+ 	tristate "HCI BCM203x USB driver"
+ 	depends on USB
+diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
+--- a/drivers/bluetooth/bpa10x.c
++++ b/drivers/bluetooth/bpa10x.c
+@@ -550,6 +550,9 @@ static int bpa10x_probe(struct usb_inter
+ 	if (ignore)
+ 		return -ENODEV;
+ 
++	if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
++		return -ENODEV;
++
+ 	data = kmalloc(sizeof(*data), GFP_KERNEL);
+ 	if (!data) {
+ 		BT_ERR("Can't allocate data structure");
+diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
+--- a/drivers/bluetooth/hci_bcsp.c
++++ b/drivers/bluetooth/hci_bcsp.c
+@@ -1,35 +1,27 @@
+-/* 
+-   BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
+-   Copyright 2002 by Fabrizio Gennari <fabrizio.gennari at philips.com>
+-
+-   Based on
+-       hci_h4.c  by Maxim Krasnyansky <maxk at qualcomm.com>
+-       ABCSP     by Carl Orsborn <cjo at csr.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;
+-
+-   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 OF THIRD PARTY RIGHTS.
+-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+-   SOFTWARE IS DISCLAIMED.
+-*/
+-
+ /*
+- * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $
++ *
++ *  Bluetooth HCI UART driver
++ *
++ *  Copyright (C) 2002-2003  Fabrizio Gennari <fabrizio.gennari at philips.com>
++ *  Copyright (C) 2004-2005  Marcel Holtmann <marcel at holtmann.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
+  */
+ 
+-#define VERSION "0.2"
+-
+ #include <linux/config.h>
+ #include <linux/module.h>
+ 
+@@ -52,16 +44,56 @@
+ 
+ #include <net/bluetooth/bluetooth.h>
+ #include <net/bluetooth/hci_core.h>
++
+ #include "hci_uart.h"
+-#include "hci_bcsp.h"
+ 
+ #ifndef CONFIG_BT_HCIUART_DEBUG
+ #undef  BT_DBG
+ #define BT_DBG( A... )
+ #endif
+ 
++#define VERSION "0.3"
++
++static int txcrc = 1;
+ static int hciextn = 1;
+ 
++#define BCSP_TXWINSIZE	4
++
++#define BCSP_ACK_PKT	0x05
++#define BCSP_LE_PKT	0x06
++
++struct bcsp_struct {
++	struct sk_buff_head unack;	/* Unack'ed packets queue */
++	struct sk_buff_head rel;	/* Reliable packets queue */
++	struct sk_buff_head unrel;	/* Unreliable packets queue */
++
++	unsigned long rx_count;
++	struct	sk_buff *rx_skb;
++	u8	rxseq_txack;		/* rxseq == txack. */
++	u8	rxack;			/* Last packet sent by us that the peer ack'ed */
++	struct	timer_list tbcsp;
++
++	enum {
++		BCSP_W4_PKT_DELIMITER,
++		BCSP_W4_PKT_START,
++		BCSP_W4_BCSP_HDR,
++		BCSP_W4_DATA,
++		BCSP_W4_CRC
++	} rx_state;
++
++	enum {
++		BCSP_ESCSTATE_NOESC,
++		BCSP_ESCSTATE_ESC
++	} rx_esc_state;
++
++	u8	use_crc;
++	u16	message_crc;
++	u8	txack_req;		/* Do we need to send ack's to the peer? */
++
++	/* Reliable packet sequence number - used to assign seq to each rel pkt. */
++	u8	msgq_txseq;
++};
++
+ /* ---- BCSP CRC calculation ---- */
+ 
+ /* Table for calculating CRC for polynomial 0x1021, LSB processed first,
+@@ -111,6 +143,7 @@ static u16 bcsp_crc_reverse(u16 crc)
+ 		rev |= (crc & 1);
+ 		crc = crc >> 1;
+ 	}
++
+ 	return (rev);
+ }
+ 
+@@ -119,6 +152,7 @@ static u16 bcsp_crc_reverse(u16 crc)
+ static void bcsp_slip_msgdelim(struct sk_buff *skb)
+ {
+ 	const char pkt_delim = 0xc0;
++
+ 	memcpy(skb_put(skb, 1), &pkt_delim, 1);
+ }
+ 
+@@ -173,11 +207,8 @@ static struct sk_buff *bcsp_prepare_pkt(
+ {
+ 	struct sk_buff *nskb;
+ 	u8 hdr[4], chan;
+-	int rel, i;
+-
+-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
+ 	u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
+-#endif
++	int rel, i;
+ 
+ 	switch (pkt_type) {
+ 	case HCI_ACLDATA_PKT:
+@@ -240,9 +271,9 @@ static struct sk_buff *bcsp_prepare_pkt(
+ 		BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
+ 		bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
+ 	}
+-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
+-	hdr[0] |= 0x40;
+-#endif
++
++	if (bcsp->use_crc)
++		hdr[0] |= 0x40;
+ 
+ 	hdr[1] = ((len << 4) & 0xff) | chan;
+ 	hdr[2] = len >> 4;
+@@ -251,25 +282,25 @@ static struct sk_buff *bcsp_prepare_pkt(
+ 	/* Put BCSP header */
+ 	for (i = 0; i < 4; i++) {
+ 		bcsp_slip_one_byte(nskb, hdr[i]);
+-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
+-		bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
+-#endif
++
++		if (bcsp->use_crc)
++			bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
+ 	}
+ 
+ 	/* Put payload */
+ 	for (i = 0; i < len; i++) {
+ 		bcsp_slip_one_byte(nskb, data[i]);
+-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
+-		bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
+-#endif
++
++		if (bcsp->use_crc)
++			bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
+ 	}
+ 
+-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
+ 	/* Put CRC */
+-	bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
+-	bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
+-	bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
+-#endif
++	if (bcsp->use_crc) {
++		bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
++		bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
++		bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
++	}
+ 
+ 	bcsp_slip_msgdelim(nskb);
+ 	return nskb;
+@@ -317,7 +348,6 @@ static struct sk_buff *bcsp_dequeue(stru
+ 
+ 	spin_unlock_irqrestore(&bcsp->unack.lock, flags);
+ 
+-
+ 	/* We could not send a reliable packet, either because there are
+ 	   none or because there are too many unack'ed pkts. Did we receive
+ 	   any packets we have not acknowledged yet ? */
+@@ -363,7 +393,7 @@ static void bcsp_pkt_cull(struct bcsp_st
+ 		BT_ERR("Peer acked invalid packet");
+ 
+ 	BT_DBG("Removing %u pkts out of %u, up to seqno %u",
+-	       pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
++		pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
+ 
+ 	for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
+ 			&& skb != (struct sk_buff *) &bcsp->unack; i++) {
+@@ -374,8 +404,10 @@ static void bcsp_pkt_cull(struct bcsp_st
+ 		kfree_skb(skb);
+ 		skb = nskb;
+ 	}
++
+ 	if (bcsp->unack.qlen == 0)
+ 		del_timer(&bcsp->tbcsp);
++
+ 	spin_unlock_irqrestore(&bcsp->unack.lock, flags);
+ 
+ 	if (i != pkts_to_be_removed)
+@@ -530,6 +562,7 @@ static inline void bcsp_complete_rx_pkt(
+ 
+ 		hci_recv_frame(bcsp->rx_skb);
+ 	}
++
+ 	bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
+ 	bcsp->rx_skb = NULL;
+ }
+@@ -598,8 +631,8 @@ static int bcsp_recv(struct hci_uart *hu
+ 
+ 				BT_ERR ("Checksum failed: computed %04x received %04x",
+ 					bcsp_crc_reverse(bcsp->message_crc),
+-				     	(bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
+-				     	bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
++					(bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
++					bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
+ 
+ 				kfree_skb(bcsp->rx_skb);
+ 				bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
+@@ -633,7 +666,7 @@ static int bcsp_recv(struct hci_uart *hu
+ 				bcsp->rx_count = 4;
+ 				bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
+ 				BCSP_CRC_INIT(bcsp->message_crc);
+-				
++
+ 				/* Do not increment ptr or decrement count
+ 				 * Allocate packet. Max len of a BCSP pkt= 
+ 				 * 0xFFF (payload) +4 (header) +2 (crc) */
+@@ -698,6 +731,9 @@ static int bcsp_open(struct hci_uart *hu
+ 
+ 	bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
+ 
++	if (txcrc)
++		bcsp->use_crc = 1;
++
+ 	return 0;
+ }
+ 
+@@ -718,18 +754,19 @@ static int bcsp_close(struct hci_uart *h
+ }
+ 
+ static struct hci_uart_proto bcsp = {
+-	.id      = HCI_UART_BCSP,
+-	.open    = bcsp_open,
+-	.close   = bcsp_close,
+-	.enqueue = bcsp_enqueue,
+-	.dequeue = bcsp_dequeue,
+-	.recv    = bcsp_recv,
+-	.flush   = bcsp_flush
++	.id		= HCI_UART_BCSP,
++	.open		= bcsp_open,
++	.close		= bcsp_close,
++	.enqueue	= bcsp_enqueue,
++	.dequeue	= bcsp_dequeue,
++	.recv		= bcsp_recv,
++	.flush		= bcsp_flush
+ };
+ 
+ int bcsp_init(void)
+ {
+ 	int err = hci_uart_register_proto(&bcsp);
++
+ 	if (!err)
+ 		BT_INFO("HCI BCSP protocol initialized");
+ 	else
+@@ -743,5 +780,8 @@ int bcsp_deinit(void)
+ 	return hci_uart_unregister_proto(&bcsp);
+ }
+ 
++module_param(txcrc, bool, 0644);
++MODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet");
++
+ module_param(hciextn, bool, 0644);
+ MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");
+diff --git a/drivers/bluetooth/hci_bcsp.h b/drivers/bluetooth/hci_bcsp.h
+deleted file mode 100644
+--- a/drivers/bluetooth/hci_bcsp.h
++++ /dev/null
+@@ -1,70 +0,0 @@
+-/* 
+-   BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
+-   Copyright 2002 by Fabrizio Gennari <fabrizio.gennari at philips.com>
+-
+-   Based on
+-       hci_h4.c  by Maxim Krasnyansky <maxk at qualcomm.com>
+-       ABCSP     by Carl Orsborn <cjo at csr.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;
+-
+-   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 OF THIRD PARTY RIGHTS.
+-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+-   SOFTWARE IS DISCLAIMED.
+-*/
+-
+-/* 
+- * $Id: hci_bcsp.h,v 1.2 2002/09/26 05:05:14 maxk Exp $
+- */
+-
+-#ifndef __HCI_BCSP_H__
+-#define __HCI_BCSP_H__
+-
+-#define BCSP_TXWINSIZE  4
+-
+-#define BCSP_ACK_PKT    0x05
+-#define BCSP_LE_PKT     0x06
+-
+-struct bcsp_struct {
+-	struct sk_buff_head unack;	/* Unack'ed packets queue */
+-	struct sk_buff_head rel;	/* Reliable packets queue */
+-	struct sk_buff_head unrel;	/* Unreliable packets queue */
+-
+-	unsigned long rx_count;
+-	struct  sk_buff *rx_skb;
+-	u8      rxseq_txack;		/* rxseq == txack. */
+-	u8      rxack;			/* Last packet sent by us that the peer ack'ed */
+-	struct  timer_list tbcsp;
+-	
+-	enum {
+-		BCSP_W4_PKT_DELIMITER,
+-		BCSP_W4_PKT_START,
+-		BCSP_W4_BCSP_HDR,
+-		BCSP_W4_DATA,
+-		BCSP_W4_CRC
+-	} rx_state;
+-
+-	enum {
+-		BCSP_ESCSTATE_NOESC,
+-		BCSP_ESCSTATE_ESC
+-	} rx_esc_state;
+-
+-	u16     message_crc;
+-	u8      txack_req;		/* Do we need to send ack's to the peer? */
+-
+-	/* Reliable packet sequence number - used to assign seq to each rel pkt. */
+-	u8      msgq_txseq;
+-};
+-
+-#endif	/* __HCI_BCSP_H__ */
+diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
+--- a/drivers/bluetooth/hci_h4.c
++++ b/drivers/bluetooth/hci_h4.c
+@@ -1,33 +1,27 @@
+-/* 
+-   BlueZ - Bluetooth protocol stack for Linux
+-   Copyright (C) 2000-2001 Qualcomm Incorporated
+-
+-   Written 2000,2001 by Maxim Krasnyansky <maxk at qualcomm.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;
+-
+-   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 OF THIRD PARTY RIGHTS.
+-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+-   SOFTWARE IS DISCLAIMED.
+-*/
+-
+ /*
+- * Bluetooth HCI UART(H4) protocol.
+  *
+- * $Id: hci_h4.c,v 1.3 2002/09/09 01:17:32 maxk Exp $    
++ *  Bluetooth HCI UART driver
++ *
++ *  Copyright (C) 2000-2001  Qualcomm Incorporated
++ *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk at qualcomm.com>
++ *  Copyright (C) 2004-2005  Marcel Holtmann <marcel at holtmann.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
+  */
+-#define VERSION "1.2"
+ 
+ #include <linux/config.h>
+ #include <linux/module.h>
+@@ -51,24 +45,41 @@
+ 
+ #include <net/bluetooth/bluetooth.h>
+ #include <net/bluetooth/hci_core.h>
++
+ #include "hci_uart.h"
+-#include "hci_h4.h"
+ 
+ #ifndef CONFIG_BT_HCIUART_DEBUG
+ #undef  BT_DBG
+ #define BT_DBG( A... )
+ #endif
+ 
++#define VERSION "1.2"
++
++struct h4_struct {
++	unsigned long rx_state;
++	unsigned long rx_count;
++	struct sk_buff *rx_skb;
++	struct sk_buff_head txq;
++};
++
++/* H4 receiver States */
++#define H4_W4_PACKET_TYPE	0
++#define H4_W4_EVENT_HDR		1
++#define H4_W4_ACL_HDR		2
++#define H4_W4_SCO_HDR		3
++#define H4_W4_DATA		4
++
+ /* Initialize protocol */
+ static int h4_open(struct hci_uart *hu)
+ {
+ 	struct h4_struct *h4;
+-	
++
+ 	BT_DBG("hu %p", hu);
+-	
++
+ 	h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
+ 	if (!h4)
+ 		return -ENOMEM;
++
+ 	memset(h4, 0, sizeof(*h4));
+ 
+ 	skb_queue_head_init(&h4->txq);
+@@ -83,7 +94,9 @@ static int h4_flush(struct hci_uart *hu)
+ 	struct h4_struct *h4 = hu->priv;
+ 
+ 	BT_DBG("hu %p", hu);
++
+ 	skb_queue_purge(&h4->txq);
++
+ 	return 0;
+ }
+ 
+@@ -91,16 +104,19 @@ static int h4_flush(struct hci_uart *hu)
+ static int h4_close(struct hci_uart *hu)
+ {
+ 	struct h4_struct *h4 = hu->priv;
++
+ 	hu->priv = NULL;
+ 
+ 	BT_DBG("hu %p", hu);
+ 
+ 	skb_queue_purge(&h4->txq);
++
+ 	if (h4->rx_skb)
+ 		kfree_skb(h4->rx_skb);
+ 
+ 	hu->priv = NULL;
+ 	kfree(h4);
++
+ 	return 0;
+ }
+ 
+@@ -114,6 +130,7 @@ static int h4_enqueue(struct hci_uart *h
+ 	/* Prepend skb with frame type */
+ 	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+ 	skb_queue_tail(&h4->txq, skb);
++
+ 	return 0;
+ }
+ 
+@@ -122,6 +139,7 @@ static inline int h4_check_data_len(stru
+ 	register int room = skb_tailroom(h4->rx_skb);
+ 
+ 	BT_DBG("len %d room %d", len, room);
++
+ 	if (!len) {
+ 		hci_recv_frame(h4->rx_skb);
+ 	} else if (len > room) {
+@@ -136,6 +154,7 @@ static inline int h4_check_data_len(stru
+ 	h4->rx_state = H4_W4_PACKET_TYPE;
+ 	h4->rx_skb   = NULL;
+ 	h4->rx_count = 0;
++
+ 	return 0;
+ }
+ 
+@@ -228,6 +247,7 @@ static int h4_recv(struct hci_uart *hu, 
+ 			ptr++; count--;
+ 			continue;
+ 		};
++
+ 		ptr++; count--;
+ 
+ 		/* Allocate packet */
+@@ -238,9 +258,11 @@ static int h4_recv(struct hci_uart *hu, 
+ 			h4->rx_count = 0;
+ 			return 0;
+ 		}
++
+ 		h4->rx_skb->dev = (void *) hu->hdev;
+ 		bt_cb(h4->rx_skb)->pkt_type = type;
+ 	}
++
+ 	return count;
+ }
+ 
+@@ -251,23 +273,24 @@ static struct sk_buff *h4_dequeue(struct
+ }
+ 
+ static struct hci_uart_proto h4p = {
+-	.id      = HCI_UART_H4,
+-	.open    = h4_open,
+-	.close   = h4_close,
+-	.recv    = h4_recv,
+-	.enqueue = h4_enqueue,
+-	.dequeue = h4_dequeue,
+-	.flush   = h4_flush,
++	.id		= HCI_UART_H4,
++	.open		= h4_open,
++	.close		= h4_close,
++	.recv		= h4_recv,
++	.enqueue	= h4_enqueue,
++	.dequeue	= h4_dequeue,
++	.flush		= h4_flush,
+ };
+-	      
++
+ int h4_init(void)
+ {
+ 	int err = hci_uart_register_proto(&h4p);
++
+ 	if (!err)
+ 		BT_INFO("HCI H4 protocol initialized");
+ 	else
+ 		BT_ERR("HCI H4 protocol registration failed");
+-	
++
+ 	return err;
+ }
+ 
+diff --git a/drivers/bluetooth/hci_h4.h b/drivers/bluetooth/hci_h4.h
+deleted file mode 100644
+--- a/drivers/bluetooth/hci_h4.h
++++ /dev/null
+@@ -1,44 +0,0 @@
+-/* 
+-   BlueZ - Bluetooth protocol stack for Linux
+-   Copyright (C) 2000-2001 Qualcomm Incorporated
+-
+-   Written 2000,2001 by Maxim Krasnyansky <maxk at qualcomm.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;
+-
+-   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 OF THIRD PARTY RIGHTS.
+-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+-   SOFTWARE IS DISCLAIMED.
+-*/
+-
+-/*
+- * $Id: hci_h4.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
+- */
+-
+-#ifdef __KERNEL__
+-struct h4_struct {
+-	unsigned long rx_state;
+-	unsigned long rx_count;
+-	struct sk_buff *rx_skb;
+-	struct sk_buff_head txq;
+-};
+-
+-/* H4 receiver States */
+-#define H4_W4_PACKET_TYPE 0
+-#define H4_W4_EVENT_HDR	  1
+-#define H4_W4_ACL_HDR     2
+-#define H4_W4_SCO_HDR     3
+-#define H4_W4_DATA        4
+-
+-#endif /* __KERNEL__ */
+diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
+--- a/drivers/bluetooth/hci_ldisc.c
++++ b/drivers/bluetooth/hci_ldisc.c
+@@ -1,33 +1,27 @@
+-/* 
+-   BlueZ - Bluetooth protocol stack for Linux
+-   Copyright (C) 2000-2001 Qualcomm Incorporated
+-
+-   Written 2000,2001 by Maxim Krasnyansky <maxk at qualcomm.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;
+-
+-   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 OF THIRD PARTY RIGHTS.
+-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+-   SOFTWARE IS DISCLAIMED.
+-*/
+-
+ /*
+- * Bluetooth HCI UART driver.
+  *
+- * $Id: hci_ldisc.c,v 1.5 2002/10/02 18:37:20 maxk Exp $    
++ *  Bluetooth HCI UART driver
++ *
++ *  Copyright (C) 2000-2001  Qualcomm Incorporated
++ *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk at qualcomm.com>
++ *  Copyright (C) 2004-2005  Marcel Holtmann <marcel at holtmann.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
+  */
+-#define VERSION "2.1"
+ 
+ #include <linux/config.h>
+ #include <linux/module.h>
+@@ -59,6 +53,8 @@
+ #define BT_DBG( A... )
+ #endif
+ 
++#define VERSION "2.2"
++
+ static int reset = 0;
+ 
+ static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
+@@ -72,6 +68,7 @@ int hci_uart_register_proto(struct hci_u
+ 		return -EEXIST;
+ 
+ 	hup[p->id] = p;
++
+ 	return 0;
+ }
+ 
+@@ -84,6 +81,7 @@ int hci_uart_unregister_proto(struct hci
+ 		return -EINVAL;
+ 
+ 	hup[p->id] = NULL;
++
+ 	return 0;
+ }
+ 
+@@ -91,13 +89,14 @@ static struct hci_uart_proto *hci_uart_g
+ {
+ 	if (id >= HCI_UART_MAX_PROTO)
+ 		return NULL;
++
+ 	return hup[id];
+ }
+ 
+ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
+ {
+ 	struct hci_dev *hdev = hu->hdev;
+-	
++
+ 	/* Update HCI stat counters */
+ 	switch (pkt_type) {
+ 	case HCI_COMMAND_PKT:
+@@ -117,10 +116,12 @@ static inline void hci_uart_tx_complete(
+ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
+ {
+ 	struct sk_buff *skb = hu->tx_skb;
++
+ 	if (!skb)
+ 		skb = hu->proto->dequeue(hu);
+ 	else
+ 		hu->tx_skb = NULL;
++
+ 	return skb;
+ }
+ 
+@@ -129,7 +130,7 @@ int hci_uart_tx_wakeup(struct hci_uart *
+ 	struct tty_struct *tty = hu->tty;
+ 	struct hci_dev *hdev = hu->hdev;
+ 	struct sk_buff *skb;
+-	
++
+ 	if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
+ 		set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
+ 		return 0;
+@@ -142,7 +143,7 @@ restart:
+ 
+ 	while ((skb = hci_uart_dequeue(hu))) {
+ 		int len;
+-	
++
+ 		set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+ 		len = tty->driver->write(tty, skb->data, skb->len);
+ 		hdev->stat.byte_tx += len;
+@@ -152,11 +153,11 @@ restart:
+ 			hu->tx_skb = skb;
+ 			break;
+ 		}
+-	
++
+ 		hci_uart_tx_complete(hu, bt_cb(skb)->pkt_type);
+ 		kfree_skb(skb);
+-	} 
+-	
++	}
++
+ 	if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
+ 		goto restart;
+ 
+@@ -173,6 +174,7 @@ static int hci_uart_open(struct hci_dev 
+ 	/* Nothing to do for UART driver */
+ 
+ 	set_bit(HCI_RUNNING, &hdev->flags);
++
+ 	return 0;
+ }
+ 
+@@ -234,6 +236,7 @@ static int hci_uart_send_frame(struct sk
+ 	hu->proto->enqueue(hu, skb);
+ 
+ 	hci_uart_tx_wakeup(hu);
++
+ 	return 0;
+ }
+ 
+@@ -241,7 +244,8 @@ static void hci_uart_destruct(struct hci
+ {
+ 	struct hci_uart *hu;
+ 
+-	if (!hdev) return;
++	if (!hdev)
++		return;
+ 
+ 	BT_DBG("%s", hdev->name);
+ 
+@@ -272,6 +276,7 @@ static int hci_uart_tty_open(struct tty_
+ 		BT_ERR("Can't allocate controll structure");
+ 		return -ENFILE;
+ 	}
++
+ 	memset(hu, 0, sizeof(struct hci_uart));
+ 
+ 	tty->disc_data = hu;
+@@ -280,8 +285,10 @@ static int hci_uart_tty_open(struct tty_
+ 	spin_lock_init(&hu->rx_lock);
+ 
+ 	/* Flush any pending characters in the driver and line discipline. */
++
+ 	/* FIXME: why is this needed. Note don't use ldisc_ref here as the
+ 	   open path is before the ldisc is referencable */
++
+ 	if (tty->ldisc.flush_buffer)
+ 		tty->ldisc.flush_buffer(tty);
+ 
+@@ -372,13 +379,13 @@ static int hci_uart_tty_room (struct tty
+ static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
+ {
+ 	struct hci_uart *hu = (void *)tty->disc_data;
+-	
++
+ 	if (!hu || tty != hu->tty)
+ 		return;
+ 
+ 	if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
+ 		return;
+-	
++
+ 	spin_lock(&hu->rx_lock);
+ 	hu->proto->recv(hu, (void *) data, count);
+ 	hu->hdev->stat.byte_rx += count;
+@@ -429,8 +436,8 @@ static int hci_uart_register_dev(struct 
+ static int hci_uart_set_proto(struct hci_uart *hu, int id)
+ {
+ 	struct hci_uart_proto *p;
+-	int err;	
+-	
++	int err;
++
+ 	p = hci_uart_get_proto(id);
+ 	if (!p)
+ 		return -EPROTONOSUPPORT;
+@@ -446,6 +453,7 @@ static int hci_uart_set_proto(struct hci
+ 		p->close(hu);
+ 		return err;
+ 	}
++
+ 	return 0;
+ }
+ 
+@@ -463,7 +471,7 @@ static int hci_uart_set_proto(struct hci
+  * Return Value:    Command dependent
+  */
+ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
+-                            unsigned int cmd, unsigned long arg)
++					unsigned int cmd, unsigned long arg)
+ {
+ 	struct hci_uart *hu = (void *)tty->disc_data;
+ 	int err = 0;
+@@ -483,14 +491,14 @@ static int hci_uart_tty_ioctl(struct tty
+ 				return err;
+ 			}
+ 			tty->low_latency = 1;
+-		} else	
++		} else
+ 			return -EBUSY;
+ 
+ 	case HCIUARTGETPROTO:
+ 		if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
+ 			return hu->proto->id;
+ 		return -EUNATCH;
+-		
++
+ 	default:
+ 		err = n_tty_ioctl(tty, file, cmd, arg);
+ 		break;
+@@ -502,28 +510,24 @@ static int hci_uart_tty_ioctl(struct tty
+ /*
+  * We don't provide read/write/poll interface for user space.
+  */
+-static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr)
++static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file,
++					unsigned char __user *buf, size_t nr)
+ {
+ 	return 0;
+ }
+-static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
++
++static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file,
++					const unsigned char *data, size_t count)
+ {
+ 	return 0;
+ }
+-static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
++
++static unsigned int hci_uart_tty_poll(struct tty_struct *tty,
++					struct file *filp, poll_table *wait)
+ {
+ 	return 0;
+ }
+ 
+-#ifdef CONFIG_BT_HCIUART_H4
+-int h4_init(void);
+-int h4_deinit(void);
+-#endif
+-#ifdef CONFIG_BT_HCIUART_BCSP
+-int bcsp_init(void);
+-int bcsp_deinit(void);
+-#endif
+-
+ static int __init hci_uart_init(void)
+ {
+ 	static struct tty_ldisc hci_uart_ldisc;
+@@ -534,18 +538,18 @@ static int __init hci_uart_init(void)
+ 	/* Register the tty discipline */
+ 
+ 	memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
+-	hci_uart_ldisc.magic       = TTY_LDISC_MAGIC;
+-	hci_uart_ldisc.name        = "n_hci";
+-	hci_uart_ldisc.open        = hci_uart_tty_open;
+-	hci_uart_ldisc.close       = hci_uart_tty_close;
+-	hci_uart_ldisc.read        = hci_uart_tty_read;
+-	hci_uart_ldisc.write       = hci_uart_tty_write;
+-	hci_uart_ldisc.ioctl       = hci_uart_tty_ioctl;
+-	hci_uart_ldisc.poll        = hci_uart_tty_poll;
+-	hci_uart_ldisc.receive_room= hci_uart_tty_room;
+-	hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
+-	hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
+-	hci_uart_ldisc.owner       = THIS_MODULE;
++	hci_uart_ldisc.magic		= TTY_LDISC_MAGIC;
++	hci_uart_ldisc.name		= "n_hci";
++	hci_uart_ldisc.open		= hci_uart_tty_open;
++	hci_uart_ldisc.close		= hci_uart_tty_close;
++	hci_uart_ldisc.read		= hci_uart_tty_read;
++	hci_uart_ldisc.write		= hci_uart_tty_write;
++	hci_uart_ldisc.ioctl		= hci_uart_tty_ioctl;
++	hci_uart_ldisc.poll		= hci_uart_tty_poll;
++	hci_uart_ldisc.receive_room	= hci_uart_tty_room;
++	hci_uart_ldisc.receive_buf	= hci_uart_tty_receive;
++	hci_uart_ldisc.write_wakeup	= hci_uart_tty_wakeup;
++	hci_uart_ldisc.owner		= THIS_MODULE;
+ 
+ 	if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
+ 		BT_ERR("HCI line discipline registration failed. (%d)", err);
+diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
+--- a/drivers/bluetooth/hci_uart.h
++++ b/drivers/bluetooth/hci_uart.h
+@@ -1,32 +1,29 @@
+-/* 
+-   BlueZ - Bluetooth protocol stack for Linux
+-   Copyright (C) 2000-2001 Qualcomm Incorporated
+-
+-   Written 2000,2001 by Maxim Krasnyansky <maxk at qualcomm.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;
+-
+-   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 OF THIRD PARTY RIGHTS.
+-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+-   SOFTWARE IS DISCLAIMED.
+-*/
+-
+ /*
+- * $Id: hci_uart.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
++ *
++ *  Bluetooth HCI UART driver
++ *
++ *  Copyright (C) 2000-2001  Qualcomm Incorporated
++ *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk at qualcomm.com>
++ *  Copyright (C) 2004-2005  Marcel Holtmann <marcel at holtmann.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
+  */
+ 
+-#ifndef N_HCI 
++#ifndef N_HCI
+ #define N_HCI	15
+ #endif
+ 
+@@ -42,7 +39,6 @@
+ #define HCI_UART_3WIRE	2
+ #define HCI_UART_H4DS	3
+ 
+-#ifdef __KERNEL__
+ struct hci_uart;
+ 
+ struct hci_uart_proto {
+@@ -56,27 +52,35 @@ struct hci_uart_proto {
+ };
+ 
+ struct hci_uart {
+-	struct tty_struct  *tty;
+-	struct hci_dev     *hdev;
+-	unsigned long      flags;
+-
+-	struct hci_uart_proto *proto;
+-	void               *priv;
+-	
+-	struct sk_buff     *tx_skb;
+-	unsigned long      tx_state;
+-	spinlock_t         rx_lock;
++	struct tty_struct	*tty;
++	struct hci_dev		*hdev;
++	unsigned long		flags;
++
++	struct hci_uart_proto	*proto;
++	void			*priv;
++
++	struct sk_buff		*tx_skb;
++	unsigned long		tx_state;
++	spinlock_t		rx_lock;
+ };
+ 
+ /* HCI_UART flag bits */
+-#define HCI_UART_PROTO_SET		0
++#define HCI_UART_PROTO_SET	0
+ 
+ /* TX states  */
+-#define HCI_UART_SENDING		1
+-#define HCI_UART_TX_WAKEUP		2
++#define HCI_UART_SENDING	1
++#define HCI_UART_TX_WAKEUP	2
+ 
+ int hci_uart_register_proto(struct hci_uart_proto *p);
+ int hci_uart_unregister_proto(struct hci_uart_proto *p);
+ int hci_uart_tx_wakeup(struct hci_uart *hu);
+ 
+-#endif /* __KERNEL__ */
++#ifdef CONFIG_BT_HCIUART_H4
++int h4_init(void);
++int h4_deinit(void);
++#endif
++
++#ifdef CONFIG_BT_HCIUART_BCSP
++int bcsp_init(void);
++int bcsp_deinit(void);
++#endif
+diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
+--- a/drivers/cdrom/viocd.c
++++ b/drivers/cdrom/viocd.c
+@@ -736,13 +736,16 @@ static struct vio_device_id viocd_device
+ 	{ "viocd", "" },
+ 	{ "", "" }
+ };
+-
+ MODULE_DEVICE_TABLE(vio, viocd_device_table);
++
+ static struct vio_driver viocd_driver = {
+-	.name = "viocd",
+ 	.id_table = viocd_device_table,
+ 	.probe = viocd_probe,
+-	.remove = viocd_remove
++	.remove = viocd_remove,
++	.driver = {
++		.name = "viocd",
++		.owner = THIS_MODULE,
++	}
+ };
+ 
+ static int __init viocd_init(void)
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
+--- a/drivers/char/Kconfig
++++ b/drivers/char/Kconfig
+@@ -661,7 +661,7 @@ config HW_RANDOM
+ 
+ config NVRAM
+ 	tristate "/dev/nvram support"
+-	depends on ATARI || X86 || X86_64 || ARM || GENERIC_NVRAM
++	depends on ATARI || X86 || ARM || GENERIC_NVRAM
+ 	---help---
+ 	  If you say Y here and create a character special file /dev/nvram
+ 	  with major number 10 and minor number 144 using mknod ("man mknod"),
+@@ -985,7 +985,7 @@ config MAX_RAW_DEVS
+ 
+ config HANGCHECK_TIMER
+ 	tristate "Hangcheck timer"
+-	depends on X86_64 || X86 || IA64 || PPC64 || ARCH_S390
++	depends on X86 || IA64 || PPC64 || ARCH_S390
+ 	help
+ 	  The hangcheck-timer module detects when the system has gone
+ 	  out to lunch past a certain margin.  It can reboot the system
+@@ -1001,5 +1001,17 @@ config MMTIMER
+ 
+ source "drivers/char/tpm/Kconfig"
+ 
++config TELCLOCK
++	tristate "Telecom clock driver for MPBL0010 ATCA SBC"
++	depends on EXPERIMENTAL
++	default n
++	help
++	  The telecom clock device is specific to the MPBL0010 ATCA computer and
++	  allows direct userspace access to the configuration of the telecom clock
++	  configuration settings.  This device is used for hardware synchronization
++	  across the ATCA backplane fabric.  Upon loading, the driver exports a
++	  sysfs directory, /sys/devices/platform/telco_clock, with a number of
++	  files for controlling the behavior of this hardware.
++
+ endmenu
+ 
+diff --git a/drivers/char/Makefile b/drivers/char/Makefile
+--- a/drivers/char/Makefile
++++ b/drivers/char/Makefile
+@@ -82,6 +82,7 @@ obj-$(CONFIG_NWFLASH) += nwflash.o
+ obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
+ obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
+ obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
++obj-$(CONFIG_TELCLOCK) += tlclk.o
+ 
+ obj-$(CONFIG_WATCHDOG)	+= watchdog/
+ obj-$(CONFIG_MWAVE) += mwave/
+diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
+--- a/drivers/char/agp/Kconfig
++++ b/drivers/char/agp/Kconfig
+@@ -27,7 +27,7 @@ config AGP
+ 
+ config AGP_ALI
+ 	tristate "ALI chipset support"
+-	depends on AGP && X86 && !X86_64
++	depends on AGP && X86_32
+ 	---help---
+ 	  This option gives you AGP support for the GLX component of
+ 	  XFree86 4.x on the following ALi chipsets.  The supported chipsets
+@@ -45,7 +45,7 @@ config AGP_ALI
+ 
+ config AGP_ATI
+ 	tristate "ATI chipset support"
+-	depends on AGP && X86 && !X86_64
++	depends on AGP && X86_32
+ 	---help---
+       This option gives you AGP support for the GLX component of
+       XFree86 4.x on the ATI RadeonIGP family of chipsets.
+@@ -55,7 +55,7 @@ config AGP_ATI
+ 
+ config AGP_AMD
+ 	tristate "AMD Irongate, 761, and 762 chipset support"
+-	depends on AGP && X86 && !X86_64
++	depends on AGP && X86_32
+ 	help
+ 	  This option gives you AGP support for the GLX component of
+ 	  XFree86 4.x on AMD Irongate, 761, and 762 chipsets.
+@@ -91,7 +91,7 @@ config AGP_INTEL
+ 
+ config AGP_NVIDIA
+ 	tristate "NVIDIA nForce/nForce2 chipset support"
+-	depends on AGP && X86 && !X86_64
++	depends on AGP && X86_32
+ 	help
+ 	  This option gives you AGP support for the GLX component of
+ 	  XFree86 4.x on the following NVIDIA chipsets.  The supported chipsets
+@@ -99,7 +99,7 @@ config AGP_NVIDIA
+ 
+ config AGP_SIS
+ 	tristate "SiS chipset support"
+-	depends on AGP && X86 && !X86_64
++	depends on AGP && X86_32
+ 	help
+ 	  This option gives you AGP support for the GLX component of
+ 	  XFree86 4.x on Silicon Integrated Systems [SiS] chipsets.
+@@ -111,14 +111,14 @@ config AGP_SIS
+ 
+ config AGP_SWORKS
+ 	tristate "Serverworks LE/HE chipset support"
+-	depends on AGP && X86 && !X86_64
++	depends on AGP && X86_32
+ 	help
+ 	  Say Y here to support the Serverworks AGP card.  See 
+ 	  <http://www.serverworks.com/> for product descriptions and images.
+ 
+ config AGP_VIA
+ 	tristate "VIA chipset support"
+-	depends on AGP && X86 && !X86_64
++	depends on AGP && X86_32
+ 	help
+ 	  This option gives you AGP support for the GLX component of
+ 	  XFree86 4.x on VIA MVP3/Apollo Pro chipsets.
+@@ -154,7 +154,7 @@ config AGP_UNINORTH
+ 
+ config AGP_EFFICEON
+ 	tristate "Transmeta Efficeon support"
+-	depends on AGP && X86 && !X86_64
++	depends on AGP && X86_32
+ 	help
+ 	  This option gives you AGP support for the Transmeta Efficeon
+ 	  series processors with integrated northbridges.
+diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
+--- a/drivers/char/agp/ali-agp.c
++++ b/drivers/char/agp/ali-agp.c
+@@ -7,6 +7,7 @@
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/agp_backend.h>
++#include <asm/page.h>		/* PAGE_SIZE */
+ #include "agp.h"
+ 
+ #define ALI_AGPCTRL	0xb8
+diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
+--- a/drivers/char/agp/amd64-agp.c
++++ b/drivers/char/agp/amd64-agp.c
+@@ -13,6 +13,7 @@
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/agp_backend.h>
++#include <asm/page.h>		/* PAGE_SIZE */
+ #include "agp.h"
+ 
+ /* Will need to be increased if AMD64 ever goes >8-way. */
+diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
+--- a/drivers/char/agp/ati-agp.c
++++ b/drivers/char/agp/ati-agp.c
+@@ -6,6 +6,8 @@
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include <linux/agp_backend.h>
+ #include <asm/agp.h>
+ #include "agp.h"
+diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
+--- a/drivers/char/agp/i460-agp.c
++++ b/drivers/char/agp/i460-agp.c
+@@ -10,6 +10,8 @@
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include <linux/agp_backend.h>
+ 
+ #include "agp.h"
+diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c
+--- a/drivers/char/agp/isoch.c
++++ b/drivers/char/agp/isoch.c
+@@ -6,6 +6,7 @@
+ #include <linux/pci.h>
+ #include <linux/agp_backend.h>
+ #include <linux/module.h>
++#include <linux/slab.h>
+ 
+ #include "agp.h"
+ 
+diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
+--- a/drivers/char/agp/sgi-agp.c
++++ b/drivers/char/agp/sgi-agp.c
+@@ -17,6 +17,7 @@
+ #include <linux/init.h>
+ #include <linux/agp_backend.h>
+ #include <asm/sn/addrs.h>
++#include <asm/sn/io.h>
+ #include <asm/sn/pcidev.h>
+ #include <asm/sn/pcibus_provider_defs.h>
+ #include <asm/sn/tioca_provider.h>
+diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
+--- a/drivers/char/agp/sworks-agp.c
++++ b/drivers/char/agp/sworks-agp.c
+@@ -5,6 +5,8 @@
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include <linux/agp_backend.h>
+ #include "agp.h"
+ 
+diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
+--- a/drivers/char/cyclades.c
++++ b/drivers/char/cyclades.c
+@@ -281,7 +281,7 @@ static char rcsid[] =
+  * make sure "cyc" appears in all kernel messages; all soft interrupts
+  * handled by same routine; recognize out-of-band reception; comment
+  * out some diagnostic messages; leave RTS/CTS flow control to hardware;
+- * fix race condition in -Z buffer management; only -Y needs to explictly
++ * fix race condition in -Z buffer management; only -Y needs to explicitly
+  * flush chars; tidy up some startup messages;
+  *
+  * Revision 1.36.4.18  1996/07/25 18:57:31  bentson
+diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
+--- a/drivers/char/drm/ati_pcigart.c
++++ b/drivers/char/drm/ati_pcigart.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file ati_pcigart.h 
++ * \file ati_pcigart.c
+  * ATI PCI GART support
+  *
+  * \author Gareth Hughes <gareth at valinux.com>
+@@ -52,85 +52,91 @@
+ # define ATI_MAX_PCIGART_PAGES		8192	/**< 32 MB aperture, 4K pages */
+ # define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */
+ 
+-static unsigned long drm_ati_alloc_pcigart_table( void )
++static unsigned long drm_ati_alloc_pcigart_table(void)
+ {
+ 	unsigned long address;
+ 	struct page *page;
+ 	int i;
+-	DRM_DEBUG( "%s\n", __FUNCTION__ );
++	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+-	address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER );
+-	if ( address == 0UL ) {
++	address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER);
++	if (address == 0UL) {
+ 		return 0;
+ 	}
+ 
+-	page = virt_to_page( address );
++	page = virt_to_page(address);
+ 
+-	for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
++	for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
+ 		get_page(page);
+-		SetPageReserved( page );
++		SetPageReserved(page);
+ 	}
+ 
+-	DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address );
++	DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
+ 	return address;
+ }
+ 
+-static void drm_ati_free_pcigart_table( unsigned long address )
++static void drm_ati_free_pcigart_table(unsigned long address)
+ {
+ 	struct page *page;
+ 	int i;
+-	DRM_DEBUG( "%s\n", __FUNCTION__ );
++	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+-	page = virt_to_page( address );
++	page = virt_to_page(address);
+ 
+-	for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
++	for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
+ 		__put_page(page);
+-		ClearPageReserved( page );
++		ClearPageReserved(page);
+ 	}
+ 
+-	free_pages( address, ATI_PCIGART_TABLE_ORDER );
++	free_pages(address, ATI_PCIGART_TABLE_ORDER);
+ }
+ 
+-int drm_ati_pcigart_cleanup( drm_device_t *dev,
+-			      unsigned long addr,
+-			      dma_addr_t bus_addr)
++int drm_ati_pcigart_cleanup(drm_device_t * dev,
++			    drm_ati_pcigart_info * gart_info)
+ {
+ 	drm_sg_mem_t *entry = dev->sg;
+ 	unsigned long pages;
+ 	int i;
+ 
+ 	/* we need to support large memory configurations */
+-	if ( !entry ) {
+-		DRM_ERROR( "no scatter/gather memory!\n" );
++	if (!entry) {
++		DRM_ERROR("no scatter/gather memory!\n");
+ 		return 0;
+ 	}
+ 
+-	if ( bus_addr ) {
+-		pci_unmap_single(dev->pdev, bus_addr,
+-				 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+-				 PCI_DMA_TODEVICE);
++	if (gart_info->bus_addr) {
++		if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
++			pci_unmap_single(dev->pdev, gart_info->bus_addr,
++					 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
++					 PCI_DMA_TODEVICE);
++		}
+ 
+-		pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
+-		        ? entry->pages : ATI_MAX_PCIGART_PAGES;
++		pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
++		    ? entry->pages : ATI_MAX_PCIGART_PAGES;
+ 
+-		for ( i = 0 ; i < pages ; i++ ) {
+-			if ( !entry->busaddr[i] ) break;
++		for (i = 0; i < pages; i++) {
++			if (!entry->busaddr[i])
++				break;
+ 			pci_unmap_single(dev->pdev, entry->busaddr[i],
+ 					 PAGE_SIZE, PCI_DMA_TODEVICE);
+ 		}
++
++		if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
++			gart_info->bus_addr = 0;
+ 	}
+ 
+-	if ( addr ) {
+-		drm_ati_free_pcigart_table( addr );
++	if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
++	    && gart_info->addr) {
++		drm_ati_free_pcigart_table(gart_info->addr);
++		gart_info->addr = 0;
+ 	}
+ 
+ 	return 1;
+ }
++
+ EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
+ 
+-int drm_ati_pcigart_init( drm_device_t *dev,
+-			   unsigned long *addr,
+-			   dma_addr_t *bus_addr)
++int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
+ {
+ 	drm_sg_mem_t *entry = dev->sg;
+ 	unsigned long address = 0;
+@@ -138,48 +144,57 @@ int drm_ati_pcigart_init( drm_device_t *
+ 	u32 *pci_gart, page_base, bus_address = 0;
+ 	int i, j, ret = 0;
+ 
+-	if ( !entry ) {
+-		DRM_ERROR( "no scatter/gather memory!\n" );
++	if (!entry) {
++		DRM_ERROR("no scatter/gather memory!\n");
+ 		goto done;
+ 	}
+ 
+-	address = drm_ati_alloc_pcigart_table();
+-	if ( !address ) {
+-		DRM_ERROR( "cannot allocate PCI GART page!\n" );
+-		goto done;
+-	}
++	if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
++		DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
+ 
+-	if ( !dev->pdev ) {
+-		DRM_ERROR( "PCI device unknown!\n" );
+-		goto done;
+-	}
++		address = drm_ati_alloc_pcigart_table();
++		if (!address) {
++			DRM_ERROR("cannot allocate PCI GART page!\n");
++			goto done;
++		}
+ 
+-	bus_address = pci_map_single(dev->pdev, (void *)address,
+-				  ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+-				  PCI_DMA_TODEVICE);
+-	if (bus_address == 0) {
+-		DRM_ERROR( "unable to map PCIGART pages!\n" );
+-		drm_ati_free_pcigart_table( address );
+-		address = 0;
+-		goto done;
++		if (!dev->pdev) {
++			DRM_ERROR("PCI device unknown!\n");
++			goto done;
++		}
++
++		bus_address = pci_map_single(dev->pdev, (void *)address,
++					     ATI_PCIGART_TABLE_PAGES *
++					     PAGE_SIZE, PCI_DMA_TODEVICE);
++		if (bus_address == 0) {
++			DRM_ERROR("unable to map PCIGART pages!\n");
++			drm_ati_free_pcigart_table(address);
++			address = 0;
++			goto done;
++		}
++	} else {
++		address = gart_info->addr;
++		bus_address = gart_info->bus_addr;
++		DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
++			  bus_address, address);
+ 	}
+ 
+-	pci_gart = (u32 *)address;
++	pci_gart = (u32 *) address;
+ 
+-	pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
+-		? entry->pages : ATI_MAX_PCIGART_PAGES;
++	pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
++	    ? entry->pages : ATI_MAX_PCIGART_PAGES;
+ 
+-	memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
++	memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32));
+ 
+-	for ( i = 0 ; i < pages ; i++ ) {
++	for (i = 0; i < pages; i++) {
+ 		/* we need to support large memory configurations */
+ 		entry->busaddr[i] = pci_map_single(dev->pdev,
+-					   page_address( entry->pagelist[i] ),
+-					   PAGE_SIZE,
+-					   PCI_DMA_TODEVICE);
++						   page_address(entry->
++								pagelist[i]),
++						   PAGE_SIZE, PCI_DMA_TODEVICE);
+ 		if (entry->busaddr[i] == 0) {
+-			DRM_ERROR( "unable to map PCIGART pages!\n" );
+-			drm_ati_pcigart_cleanup( dev, address, bus_address );
++			DRM_ERROR("unable to map PCIGART pages!\n");
++			drm_ati_pcigart_cleanup(dev, gart_info);
+ 			address = 0;
+ 			bus_address = 0;
+ 			goto done;
+@@ -187,7 +202,11 @@ int drm_ati_pcigart_init( drm_device_t *
+ 		page_base = (u32) entry->busaddr[i];
+ 
+ 		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+-			*pci_gart++ = cpu_to_le32( page_base );
++			if (gart_info->is_pcie)
++				*pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc;
++			else
++				*pci_gart = cpu_to_le32(page_base);
++			*pci_gart++;
+ 			page_base += ATI_PCIGART_PAGE_SIZE;
+ 		}
+ 	}
+@@ -200,9 +219,10 @@ int drm_ati_pcigart_init( drm_device_t *
+ 	mb();
+ #endif
+ 
+-done:
+-	*addr = address;
+-	*bus_addr = bus_address;
++      done:
++	gart_info->addr = address;
++	gart_info->bus_addr = bus_address;
+ 	return ret;
+ }
++
+ EXPORT_SYMBOL(drm_ati_pcigart_init);
+diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
+--- a/drivers/char/drm/drm.h
++++ b/drivers/char/drm/drm.h
+@@ -1,7 +1,7 @@
+ /**
+- * \file drm.h 
++ * \file drm.h
+  * Header for the Direct Rendering Manager
+- * 
++ *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  *
+  * \par Acknowledgments:
+@@ -33,7 +33,6 @@
+  * OTHER DEALINGS IN THE SOFTWARE.
+  */
+ 
+-
+ #ifndef _DRM_H_
+ #define _DRM_H_
+ 
+@@ -56,7 +55,7 @@
+ #define ioctl(a,b,c)		xf86ioctl(a,b,c)
+ #else
+ #include <sys/ioccom.h>
+-#endif /* __FreeBSD__ && xf86ioctl */
++#endif				/* __FreeBSD__ && xf86ioctl */
+ #define DRM_IOCTL_NR(n)		((n) & 0xff)
+ #define DRM_IOC_VOID		IOC_VOID
+ #define DRM_IOC_READ		IOC_OUT
+@@ -97,16 +96,14 @@
+ #define _DRM_LOCK_IS_CONT(lock)	   ((lock) & _DRM_LOCK_CONT)
+ #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
+ 
+-
+-typedef unsigned int  drm_handle_t;
+-typedef unsigned int  drm_context_t;
+-typedef unsigned int  drm_drawable_t;
+-typedef unsigned int  drm_magic_t;
+-
++typedef unsigned int drm_handle_t;
++typedef unsigned int drm_context_t;
++typedef unsigned int drm_drawable_t;
++typedef unsigned int drm_magic_t;
+ 
+ /**
+  * Cliprect.
+- * 
++ *
+  * \warning: If you change this structure, make sure you change
+  * XF86DRIClipRectRec in the server as well
+  *
+@@ -114,22 +111,21 @@ typedef unsigned int  drm_magic_t;
+  * backwards-compatibility reasons.
+  */
+ typedef struct drm_clip_rect {
+-	unsigned short	x1;
+-	unsigned short	y1;
+-	unsigned short	x2;
+-	unsigned short	y2;
++	unsigned short x1;
++	unsigned short y1;
++	unsigned short x2;
++	unsigned short y2;
+ } drm_clip_rect_t;
+ 
+-
+ /**
+  * Texture region,
+  */
+ typedef struct drm_tex_region {
+-	unsigned char	next;
+-	unsigned char	prev;
+-	unsigned char	in_use;
+-	unsigned char	padding;
+-	unsigned int	age;
++	unsigned char next;
++	unsigned char prev;
++	unsigned char in_use;
++	unsigned char padding;
++	unsigned int age;
+ } drm_tex_region_t;
+ 
+ /**
+@@ -141,28 +137,26 @@ typedef struct drm_tex_region {
+  */
+ typedef struct drm_hw_lock {
+ 	__volatile__ unsigned int lock;		/**< lock variable */
+-	char			  padding[60];	/**< Pad to cache line */
++	char padding[60];			/**< Pad to cache line */
+ } drm_hw_lock_t;
+ 
+-
+ /**
+  * DRM_IOCTL_VERSION ioctl argument type.
+- * 
++ *
+  * \sa drmGetVersion().
+  */
+ typedef struct drm_version {
+-	int    version_major;	  /**< Major version */
+-	int    version_minor;	  /**< Minor version */
+-	int    version_patchlevel;/**< Patch level */
++	int version_major;	  /**< Major version */
++	int version_minor;	  /**< Minor version */
++	int version_patchlevel;	  /**< Patch level */
+ 	size_t name_len;	  /**< Length of name buffer */
+-	char   __user *name;	  /**< Name of driver */
++	char __user *name;	  /**< Name of driver */
+ 	size_t date_len;	  /**< Length of date buffer */
+-	char   __user *date;	  /**< User-space buffer to hold date */
++	char __user *date;	  /**< User-space buffer to hold date */
+ 	size_t desc_len;	  /**< Length of desc buffer */
+-	char   __user *desc;	  /**< User-space buffer to hold desc */
++	char __user *desc;	  /**< User-space buffer to hold desc */
+ } drm_version_t;
+ 
+-
+ /**
+  * DRM_IOCTL_GET_UNIQUE ioctl argument type.
+  *
+@@ -170,21 +164,18 @@ typedef struct drm_version {
+  */
+ typedef struct drm_unique {
+ 	size_t unique_len;	  /**< Length of unique */
+-	char   __user *unique;	  /**< Unique name for driver instantiation */
++	char __user *unique;	  /**< Unique name for driver instantiation */
+ } drm_unique_t;
+ 
+-
+ typedef struct drm_list {
+-	int		 count;	  /**< Length of user-space structures */
+-	drm_version_t	 __user *version;
++	int count;		  /**< Length of user-space structures */
++	drm_version_t __user *version;
+ } drm_list_t;
+ 
+-
+ typedef struct drm_block {
+-	int		 unused;
++	int unused;
+ } drm_block_t;
+ 
+-
+ /**
+  * DRM_IOCTL_CONTROL ioctl argument type.
+  *
+@@ -196,44 +187,40 @@ typedef struct drm_control {
+ 		DRM_RM_COMMAND,
+ 		DRM_INST_HANDLER,
+ 		DRM_UNINST_HANDLER
+-	}		 func;
+-	int		 irq;
++	} func;
++	int irq;
+ } drm_control_t;
+ 
+-
+ /**
+  * Type of memory to map.
+  */
+ typedef enum drm_map_type {
+-	_DRM_FRAME_BUFFER   = 0,  /**< WC (no caching), no core dump */
+-	_DRM_REGISTERS	    = 1,  /**< no caching, no core dump */
+-	_DRM_SHM	    = 2,  /**< shared, cached */
+-	_DRM_AGP            = 3,  /**< AGP/GART */
++	_DRM_FRAME_BUFFER = 0,	  /**< WC (no caching), no core dump */
++	_DRM_REGISTERS = 1,	  /**< no caching, no core dump */
++	_DRM_SHM = 2,		  /**< shared, cached */
++	_DRM_AGP = 3,		  /**< AGP/GART */
+ 	_DRM_SCATTER_GATHER = 4,  /**< Scatter/gather memory for PCI DMA */
+-	_DRM_CONSISTENT     = 5,  /**< Consistent memory for PCI DMA */
++	_DRM_CONSISTENT = 5,	  /**< Consistent memory for PCI DMA */
+ } drm_map_type_t;
+ 
+-
+ /**
+  * Memory mapping flags.
+  */
+ typedef enum drm_map_flags {
+-	_DRM_RESTRICTED	     = 0x01, /**< Cannot be mapped to user-virtual */
+-	_DRM_READ_ONLY	     = 0x02,
+-	_DRM_LOCKED	     = 0x04, /**< shared, cached, locked */
+-	_DRM_KERNEL	     = 0x08, /**< kernel requires access */
++	_DRM_RESTRICTED = 0x01,	     /**< Cannot be mapped to user-virtual */
++	_DRM_READ_ONLY = 0x02,
++	_DRM_LOCKED = 0x04,	     /**< shared, cached, locked */
++	_DRM_KERNEL = 0x08,	     /**< kernel requires access */
+ 	_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
+-	_DRM_CONTAINS_LOCK   = 0x20, /**< SHM page that contains lock */
+-	_DRM_REMOVABLE	     = 0x40  /**< Removable mapping */
++	_DRM_CONTAINS_LOCK = 0x20,   /**< SHM page that contains lock */
++	_DRM_REMOVABLE = 0x40	     /**< Removable mapping */
+ } drm_map_flags_t;
+ 
+-
+ typedef struct drm_ctx_priv_map {
+-	unsigned int	ctx_id;  /**< Context requesting private mapping */
+-	void		*handle; /**< Handle of map */
++	unsigned int ctx_id;	 /**< Context requesting private mapping */
++	void *handle;		 /**< Handle of map */
+ } drm_ctx_priv_map_t;
+ 
+-
+ /**
+  * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
+  * argument type.
+@@ -241,30 +228,28 @@ typedef struct drm_ctx_priv_map {
+  * \sa drmAddMap().
+  */
+ typedef struct drm_map {
+-	unsigned long	offset;	 /**< Requested physical address (0 for SAREA)*/
+-	unsigned long	size;	 /**< Requested physical size (bytes) */
+-	drm_map_type_t	type;	 /**< Type of memory to map */
++	unsigned long offset;	 /**< Requested physical address (0 for SAREA)*/
++	unsigned long size;	 /**< Requested physical size (bytes) */
++	drm_map_type_t type;	 /**< Type of memory to map */
+ 	drm_map_flags_t flags;	 /**< Flags */
+-	void		*handle; /**< User-space: "Handle" to pass to mmap() */
++	void *handle;		 /**< User-space: "Handle" to pass to mmap() */
+ 				 /**< Kernel-space: kernel-virtual address */
+-	int		mtrr;	 /**< MTRR slot used */
+-				 /*   Private data */
++	int mtrr;		 /**< MTRR slot used */
++	/*   Private data */
+ } drm_map_t;
+ 
+-
+ /**
+  * DRM_IOCTL_GET_CLIENT ioctl argument type.
+  */
+ typedef struct drm_client {
+-	int		idx;	/**< Which client desired? */
+-	int		auth;	/**< Is client authenticated? */
+-	unsigned long	pid;	/**< Process ID */
+-	unsigned long	uid;	/**< User ID */
+-	unsigned long	magic;	/**< Magic */
+-	unsigned long	iocs;	/**< Ioctl count */
++	int idx;		/**< Which client desired? */
++	int auth;		/**< Is client authenticated? */
++	unsigned long pid;	/**< Process ID */
++	unsigned long uid;	/**< User ID */
++	unsigned long magic;	/**< Magic */
++	unsigned long iocs;	/**< Ioctl count */
+ } drm_client_t;
+ 
+-
+ typedef enum {
+ 	_DRM_STAT_LOCK,
+ 	_DRM_STAT_OPENS,
+@@ -282,63 +267,58 @@ typedef enum {
+ 	_DRM_STAT_DMA,		/**< DMA */
+ 	_DRM_STAT_SPECIAL,	/**< Special DMA (e.g., priority or polled) */
+ 	_DRM_STAT_MISSED	/**< Missed DMA opportunity */
+-
+-				/* Add to the *END* of the list */
++	    /* Add to the *END* of the list */
+ } drm_stat_type_t;
+ 
+-
+ /**
+  * DRM_IOCTL_GET_STATS ioctl argument type.
+  */
+ typedef struct drm_stats {
+ 	unsigned long count;
+ 	struct {
+-		unsigned long   value;
++		unsigned long value;
+ 		drm_stat_type_t type;
+ 	} data[15];
+ } drm_stats_t;
+ 
+-
+ /**
+  * Hardware locking flags.
+  */
+ typedef enum drm_lock_flags {
+-	_DRM_LOCK_READY	     = 0x01, /**< Wait until hardware is ready for DMA */
+-	_DRM_LOCK_QUIESCENT  = 0x02, /**< Wait until hardware quiescent */
+-	_DRM_LOCK_FLUSH	     = 0x04, /**< Flush this context's DMA queue first */
+-	_DRM_LOCK_FLUSH_ALL  = 0x08, /**< Flush all DMA queues first */
+-				/* These *HALT* flags aren't supported yet
+-				   -- they will be used to support the
+-				   full-screen DGA-like mode. */
++	_DRM_LOCK_READY = 0x01,	     /**< Wait until hardware is ready for DMA */
++	_DRM_LOCK_QUIESCENT = 0x02,  /**< Wait until hardware quiescent */
++	_DRM_LOCK_FLUSH = 0x04,	     /**< Flush this context's DMA queue first */
++	_DRM_LOCK_FLUSH_ALL = 0x08,  /**< Flush all DMA queues first */
++	/* These *HALT* flags aren't supported yet
++	   -- they will be used to support the
++	   full-screen DGA-like mode. */
+ 	_DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
+ 	_DRM_HALT_CUR_QUEUES = 0x20  /**< Halt all current queues */
+ } drm_lock_flags_t;
+ 
+-
+ /**
+  * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
+- * 
++ *
+  * \sa drmGetLock() and drmUnlock().
+  */
+ typedef struct drm_lock {
+-	int		 context;
++	int context;
+ 	drm_lock_flags_t flags;
+ } drm_lock_t;
+ 
+-
+ /**
+  * DMA flags
+  *
+- * \warning 
++ * \warning
+  * These values \e must match xf86drm.h.
+  *
+  * \sa drm_dma.
+  */
+-typedef enum drm_dma_flags {	      
+-				      /* Flags for DMA buffer dispatch */
+-	_DRM_DMA_BLOCK	      = 0x01, /**<
++typedef enum drm_dma_flags {
++	/* Flags for DMA buffer dispatch */
++	_DRM_DMA_BLOCK = 0x01,	      /**<
+ 				       * Block until buffer dispatched.
+-				       * 
++				       *
+ 				       * \note The buffer may not yet have
+ 				       * been processed by the hardware --
+ 				       * getting a hardware lock with the
+@@ -347,79 +327,73 @@ typedef enum drm_dma_flags {	      
+ 				       * processed.
+ 				       */
+ 	_DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
+-	_DRM_DMA_PRIORITY     = 0x04, /**< High priority dispatch */
++	_DRM_DMA_PRIORITY = 0x04,     /**< High priority dispatch */
+ 
+-				      /* Flags for DMA buffer request */
+-	_DRM_DMA_WAIT	      = 0x10, /**< Wait for free buffers */
+-	_DRM_DMA_SMALLER_OK   = 0x20, /**< Smaller-than-requested buffers OK */
+-	_DRM_DMA_LARGER_OK    = 0x40  /**< Larger-than-requested buffers OK */
++	/* Flags for DMA buffer request */
++	_DRM_DMA_WAIT = 0x10,	      /**< Wait for free buffers */
++	_DRM_DMA_SMALLER_OK = 0x20,   /**< Smaller-than-requested buffers OK */
++	_DRM_DMA_LARGER_OK = 0x40     /**< Larger-than-requested buffers OK */
+ } drm_dma_flags_t;
+ 
+-
+ /**
+  * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
+  *
+  * \sa drmAddBufs().
+  */
+ typedef struct drm_buf_desc {
+-	int	      count;	 /**< Number of buffers of this size */
+-	int	      size;	 /**< Size in bytes */
+-	int	      low_mark;	 /**< Low water mark */
+-	int	      high_mark; /**< High water mark */
++	int count;		 /**< Number of buffers of this size */
++	int size;		 /**< Size in bytes */
++	int low_mark;		 /**< Low water mark */
++	int high_mark;		 /**< High water mark */
+ 	enum {
+-		_DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
+-		_DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
+-		_DRM_SG_BUFFER  = 0x04, /**< Scatter/gather memory buffer */
+-		_DRM_FB_BUFFER  = 0x08  /**< Buffer is in frame buffer */
+-	}	      flags;
+-	unsigned long agp_start; /**< 
++		_DRM_PAGE_ALIGN = 0x01,	/**< Align on page boundaries for DMA */
++		_DRM_AGP_BUFFER = 0x02,	/**< Buffer is in AGP space */
++		_DRM_SG_BUFFER = 0x04,	/**< Scatter/gather memory buffer */
++		_DRM_FB_BUFFER = 0x08	/**< Buffer is in frame buffer */
++	} flags;
++	unsigned long agp_start; /**<
+ 				  * Start address of where the AGP buffers are
+ 				  * in the AGP aperture
+ 				  */
+ } drm_buf_desc_t;
+ 
+-
+ /**
+  * DRM_IOCTL_INFO_BUFS ioctl argument type.
+  */
+ typedef struct drm_buf_info {
+-	int	       count;	/**< Entries in list */
++	int count;		/**< Entries in list */
+ 	drm_buf_desc_t __user *list;
+ } drm_buf_info_t;
+ 
+-
+ /**
+  * DRM_IOCTL_FREE_BUFS ioctl argument type.
+  */
+ typedef struct drm_buf_free {
+-	int	       count;
+-	int	       __user *list;
++	int count;
++	int __user *list;
+ } drm_buf_free_t;
+ 
+-
+ /**
+  * Buffer information
+  *
+  * \sa drm_buf_map.
+  */
+ typedef struct drm_buf_pub {
+-	int		  idx;	       /**< Index into the master buffer list */
+-	int		  total;       /**< Buffer size */
+-	int		  used;	       /**< Amount of buffer in use (for DMA) */
+-	void	  __user *address;     /**< Address of buffer */
++	int idx;		       /**< Index into the master buffer list */
++	int total;		       /**< Buffer size */
++	int used;		       /**< Amount of buffer in use (for DMA) */
++	void __user *address;	       /**< Address of buffer */
+ } drm_buf_pub_t;
+ 
+-
+ /**
+  * DRM_IOCTL_MAP_BUFS ioctl argument type.
+  */
+ typedef struct drm_buf_map {
+-	int	      count;	/**< Length of the buffer list */
+-	void	      __user *virtual;	/**< Mmap'd area in user-virtual */
++	int count;		/**< Length of the buffer list */
++	void __user *virtual;		/**< Mmap'd area in user-virtual */
+ 	drm_buf_pub_t __user *list;	/**< Buffer information */
+ } drm_buf_map_t;
+ 
+-
+ /**
+  * DRM_IOCTL_DMA ioctl argument type.
+  *
+@@ -428,61 +402,55 @@ typedef struct drm_buf_map {
+  * \sa drmDMA().
+  */
+ typedef struct drm_dma {
+-	int		context;	  /**< Context handle */
+-	int		send_count;	  /**< Number of buffers to send */
+-	int	__user *send_indices;	  /**< List of handles to buffers */
+-	int	__user *send_sizes;	  /**< Lengths of data to send */
++	int context;			  /**< Context handle */
++	int send_count;			  /**< Number of buffers to send */
++	int __user *send_indices;	  /**< List of handles to buffers */
++	int __user *send_sizes;		  /**< Lengths of data to send */
+ 	drm_dma_flags_t flags;		  /**< Flags */
+-	int		request_count;	  /**< Number of buffers requested */
+-	int		request_size;	  /**< Desired size for buffers */
+-	int	__user *request_indices;  /**< Buffer information */
+-	int	__user *request_sizes;
+-	int		granted_count;	  /**< Number of buffers granted */
++	int request_count;		  /**< Number of buffers requested */
++	int request_size;		  /**< Desired size for buffers */
++	int __user *request_indices;	  /**< Buffer information */
++	int __user *request_sizes;
++	int granted_count;		  /**< Number of buffers granted */
+ } drm_dma_t;
+ 
+-
+ typedef enum {
+ 	_DRM_CONTEXT_PRESERVED = 0x01,
+-	_DRM_CONTEXT_2DONLY    = 0x02
++	_DRM_CONTEXT_2DONLY = 0x02
+ } drm_ctx_flags_t;
+ 
+-
+ /**
+  * DRM_IOCTL_ADD_CTX ioctl argument type.
+  *
+  * \sa drmCreateContext() and drmDestroyContext().
+  */
+ typedef struct drm_ctx {
+-	drm_context_t	handle;
++	drm_context_t handle;
+ 	drm_ctx_flags_t flags;
+ } drm_ctx_t;
+ 
+-
+ /**
+  * DRM_IOCTL_RES_CTX ioctl argument type.
+  */
+ typedef struct drm_ctx_res {
+-	int		count;
+-	drm_ctx_t	__user *contexts;
++	int count;
++	drm_ctx_t __user *contexts;
+ } drm_ctx_res_t;
+ 
+-
+ /**
+  * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
+  */
+ typedef struct drm_draw {
+-	drm_drawable_t	handle;
++	drm_drawable_t handle;
+ } drm_draw_t;
+ 
+-
+ /**
+  * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
+  */
+ typedef struct drm_auth {
+-	drm_magic_t	magic;
++	drm_magic_t magic;
+ } drm_auth_t;
+ 
+-
+ /**
+  * DRM_IOCTL_IRQ_BUSID ioctl argument type.
+  *
+@@ -495,24 +463,20 @@ typedef struct drm_irq_busid {
+ 	int funcnum;	/**< function number */
+ } drm_irq_busid_t;
+ 
+-
+ typedef enum {
+-    _DRM_VBLANK_ABSOLUTE = 0x0,		/**< Wait for specific vblank sequence number */
+-    _DRM_VBLANK_RELATIVE = 0x1,		/**< Wait for given number of vblanks */
+-    _DRM_VBLANK_SIGNAL   = 0x40000000	/**< Send signal instead of blocking */
++	_DRM_VBLANK_ABSOLUTE = 0x0,	/**< Wait for specific vblank sequence number */
++	_DRM_VBLANK_RELATIVE = 0x1,	/**< Wait for given number of vblanks */
++	_DRM_VBLANK_SIGNAL = 0x40000000	/**< Send signal instead of blocking */
+ } drm_vblank_seq_type_t;
+ 
+-
+ #define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
+ 
+-
+ struct drm_wait_vblank_request {
+ 	drm_vblank_seq_type_t type;
+ 	unsigned int sequence;
+ 	unsigned long signal;
+ };
+ 
+-
+ struct drm_wait_vblank_reply {
+ 	drm_vblank_seq_type_t type;
+ 	unsigned int sequence;
+@@ -520,7 +484,6 @@ struct drm_wait_vblank_reply {
+ 	long tval_usec;
+ };
+ 
+-
+ /**
+  * DRM_IOCTL_WAIT_VBLANK ioctl argument type.
+  *
+@@ -531,7 +494,6 @@ typedef union drm_wait_vblank {
+ 	struct drm_wait_vblank_reply reply;
+ } drm_wait_vblank_t;
+ 
+-
+ /**
+  * DRM_IOCTL_AGP_ENABLE ioctl argument type.
+  *
+@@ -541,7 +503,6 @@ typedef struct drm_agp_mode {
+ 	unsigned long mode;	/**< AGP mode */
+ } drm_agp_mode_t;
+ 
+-
+ /**
+  * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
+  *
+@@ -550,22 +511,20 @@ typedef struct drm_agp_mode {
+ typedef struct drm_agp_buffer {
+ 	unsigned long size;	/**< In bytes -- will round to page boundary */
+ 	unsigned long handle;	/**< Used for binding / unbinding */
+-	unsigned long type;     /**< Type of memory to allocate */
+-        unsigned long physical; /**< Physical used by i810 */
++	unsigned long type;	/**< Type of memory to allocate */
++	unsigned long physical;	/**< Physical used by i810 */
+ } drm_agp_buffer_t;
+ 
+-
+ /**
+  * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
+  *
+  * \sa drmAgpBind() and drmAgpUnbind().
+  */
+ typedef struct drm_agp_binding {
+-	unsigned long handle;   /**< From drm_agp_buffer */
++	unsigned long handle;	/**< From drm_agp_buffer */
+ 	unsigned long offset;	/**< In bytes -- will round to page boundary */
+ } drm_agp_binding_t;
+ 
+-
+ /**
+  * DRM_IOCTL_AGP_INFO ioctl argument type.
+  *
+@@ -574,20 +533,19 @@ typedef struct drm_agp_binding {
+  * drmAgpVendorId() and drmAgpDeviceId().
+  */
+ typedef struct drm_agp_info {
+-	int            agp_version_major;
+-	int            agp_version_minor;
+-	unsigned long  mode;
+-	unsigned long  aperture_base;  /* physical address */
+-	unsigned long  aperture_size;  /* bytes */
+-	unsigned long  memory_allowed; /* bytes */
+-	unsigned long  memory_used;
++	int agp_version_major;
++	int agp_version_minor;
++	unsigned long mode;
++	unsigned long aperture_base;	/* physical address */
++	unsigned long aperture_size;	/* bytes */
++	unsigned long memory_allowed;	/* bytes */
++	unsigned long memory_used;
+ 
+-				/* PCI information */
++	/* PCI information */
+ 	unsigned short id_vendor;
+ 	unsigned short id_device;
+ } drm_agp_info_t;
+ 
+-
+ /**
+  * DRM_IOCTL_SG_ALLOC ioctl argument type.
+  */
+@@ -606,7 +564,6 @@ typedef struct drm_set_version {
+ 	int drm_dd_minor;
+ } drm_set_version_t;
+ 
+-
+ #define DRM_IOCTL_BASE			'd'
+ #define DRM_IO(nr)			_IO(DRM_IOCTL_BASE,nr)
+ #define DRM_IOR(nr,type)		_IOR(DRM_IOCTL_BASE,nr,type)
+diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
+--- a/drivers/char/drm/drmP.h
++++ b/drivers/char/drm/drmP.h
+@@ -1,7 +1,7 @@
+ /**
+- * \file drmP.h 
++ * \file drmP.h
+  * Private header for Direct Rendering Manager
+- * 
++ *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Gareth Hughes <gareth at valinux.com>
+  */
+@@ -43,7 +43,7 @@
+  * before static inline funcs in wait.h. Doing this so we
+  * can build the DRM (part of PI DRI). 4/21/2000 S + B */
+ #include <asm/current.h>
+-#endif /* __alpha__ */
++#endif				/* __alpha__ */
+ #include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -58,7 +58,7 @@
+ #include <linux/mm.h>
+ #include <linux/cdev.h>
+ #if defined(__alpha__) || defined(__powerpc__)
+-#include <asm/pgtable.h> /* For pte_wrprotect */
++#include <asm/pgtable.h>	/* For pte_wrprotect */
+ #endif
+ #include <asm/io.h>
+ #include <asm/mman.h>
+@@ -108,7 +108,6 @@
+ #define DRM_KERNEL_CONTEXT    0	 /**< Change drm_resctx if changed */
+ #define DRM_RESERVED_CONTEXTS 1	 /**< Change drm_resctx if changed */
+ #define DRM_LOOPING_LIMIT     5000000
+-#define DRM_BSZ		      1024 /**< Buffer size for /dev/drm? output */
+ #define DRM_TIME_SLICE	      (HZ/20)  /**< Time slice for GLXContexts */
+ #define DRM_LOCK_SLICE	      1	/**< Time slice for lock, in jiffies */
+ 
+@@ -138,16 +137,15 @@
+ #define DRM_MEM_CTXLIST  21
+ 
+ #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
+-	
+-/*@}*/
+ 
++/*@}*/
+ 
+ /***********************************************************************/
+ /** \name Backward compatibility section */
+ /*@{*/
+ 
+ #ifndef MODULE_LICENSE
+-#define MODULE_LICENSE(x) 
++#define MODULE_LICENSE(x)
+ #endif
+ 
+ #ifndef preempt_disable
+@@ -155,7 +153,7 @@
+ #define preempt_enable()
+ #endif
+ 
+-#ifndef pte_offset_map 
++#ifndef pte_offset_map
+ #define pte_offset_map pte_offset
+ #define pte_unmap(pte)
+ #endif
+@@ -166,7 +164,6 @@
+ 
+ /*@}*/
+ 
+-
+ /***********************************************************************/
+ /** \name Macros to make printk easier */
+ /*@{*/
+@@ -195,7 +192,7 @@
+ 
+ /**
+  * Debug output.
+- * 
++ *
+  * \param fmt printf() like format string.
+  * \param arg arguments
+  */
+@@ -223,14 +220,13 @@
+ 
+ /*@}*/
+ 
+-
+ /***********************************************************************/
+ /** \name Internal types and structures */
+ /*@{*/
+ 
+-#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+-#define DRM_MIN(a,b) ((a)<(b)?(a):(b))
+-#define DRM_MAX(a,b) ((a)>(b)?(a):(b))
++#define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x)
++#define DRM_MIN(a,b) min(a,b)
++#define DRM_MAX(a,b) max(a,b)
+ 
+ #define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
+ #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
+@@ -275,7 +271,7 @@ do {									\
+ 		if ( copy_to_user( name, value, len ) )			\
+ 			return -EFAULT;					\
+ 	}
+-	
++
+ /**
+  * Ioctl function type.
+  *
+@@ -284,25 +280,25 @@ do {									\
+  * \param cmd command.
+  * \param arg argument.
+  */
+-typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
+-			 unsigned int cmd, unsigned long arg );
++typedef int drm_ioctl_t(struct inode *inode, struct file *filp,
++			unsigned int cmd, unsigned long arg);
+ 
+ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
+ 			       unsigned long arg);
+ 
+ typedef struct drm_ioctl_desc {
+-	drm_ioctl_t	     *func;
+-	int		     auth_needed;
+-	int		     root_only;
++	drm_ioctl_t *func;
++	int auth_needed;
++	int root_only;
+ } drm_ioctl_desc_t;
+ 
+ typedef struct drm_devstate {
+-	pid_t		  owner;	/**< X server pid holding x_lock */
++	pid_t owner;			/**< X server pid holding x_lock */
+ } drm_devstate_t;
+ 
+ typedef struct drm_magic_entry {
+-	drm_magic_t	       magic;
+-	struct drm_file	       *priv;
++	drm_magic_t magic;
++	struct drm_file *priv;
+ 	struct drm_magic_entry *next;
+ } drm_magic_entry_t;
+ 
+@@ -313,111 +309,110 @@ typedef struct drm_magic_head {
+ 
+ typedef struct drm_vma_entry {
+ 	struct vm_area_struct *vma;
+-	struct drm_vma_entry  *next;
+-	pid_t		      pid;
++	struct drm_vma_entry *next;
++	pid_t pid;
+ } drm_vma_entry_t;
+ 
+ /**
+  * DMA buffer.
+  */
+ typedef struct drm_buf {
+-	int		  idx;	       /**< Index into master buflist */
+-	int		  total;       /**< Buffer size */
+-	int		  order;       /**< log-base-2(total) */
+-	int		  used;	       /**< Amount of buffer in use (for DMA) */
+-	unsigned long	  offset;      /**< Byte offset (used internally) */
+-	void		  *address;    /**< Address of buffer */
+-	unsigned long	  bus_address; /**< Bus address of buffer */
+-	struct drm_buf	  *next;       /**< Kernel-only: used for free list */
+-	__volatile__ int  waiting;     /**< On kernel DMA queue */
+-	__volatile__ int  pending;     /**< On hardware DMA queue */
++	int idx;		       /**< Index into master buflist */
++	int total;		       /**< Buffer size */
++	int order;		       /**< log-base-2(total) */
++	int used;		       /**< Amount of buffer in use (for DMA) */
++	unsigned long offset;	       /**< Byte offset (used internally) */
++	void *address;		       /**< Address of buffer */
++	unsigned long bus_address;     /**< Bus address of buffer */
++	struct drm_buf *next;	       /**< Kernel-only: used for free list */
++	__volatile__ int waiting;      /**< On kernel DMA queue */
++	__volatile__ int pending;      /**< On hardware DMA queue */
+ 	wait_queue_head_t dma_wait;    /**< Processes waiting */
+-	struct file       *filp;       /**< Pointer to holding file descr */
+-	int		  context;     /**< Kernel queue for this buffer */
+-	int		  while_locked;/**< Dispatch this buffer while locked */
++	struct file *filp;	       /**< Pointer to holding file descr */
++	int context;		       /**< Kernel queue for this buffer */
++	int while_locked;	       /**< Dispatch this buffer while locked */
+ 	enum {
+-		DRM_LIST_NONE	 = 0,
+-		DRM_LIST_FREE	 = 1,
+-		DRM_LIST_WAIT	 = 2,
+-		DRM_LIST_PEND	 = 3,
+-		DRM_LIST_PRIO	 = 4,
++		DRM_LIST_NONE = 0,
++		DRM_LIST_FREE = 1,
++		DRM_LIST_WAIT = 2,
++		DRM_LIST_PEND = 3,
++		DRM_LIST_PRIO = 4,
+ 		DRM_LIST_RECLAIM = 5
+-	}		  list;	       /**< Which list we're on */
++	} list;			       /**< Which list we're on */
+ 
+-	int		  dev_priv_size; /**< Size of buffer private storage */
+-	void		  *dev_private;  /**< Per-buffer private storage */
++	int dev_priv_size;		 /**< Size of buffer private storage */
++	void *dev_private;		 /**< Per-buffer private storage */
+ } drm_buf_t;
+ 
+-
+ /** bufs is one longer than it has to be */
+ typedef struct drm_waitlist {
+-	int		  count;	/**< Number of possible buffers */
+-	drm_buf_t	  **bufs;	/**< List of pointers to buffers */
+-	drm_buf_t	  **rp;		/**< Read pointer */
+-	drm_buf_t	  **wp;		/**< Write pointer */
+-	drm_buf_t	  **end;	/**< End pointer */
+-	spinlock_t	  read_lock;
+-	spinlock_t	  write_lock;
++	int count;			/**< Number of possible buffers */
++	drm_buf_t **bufs;		/**< List of pointers to buffers */
++	drm_buf_t **rp;			/**< Read pointer */
++	drm_buf_t **wp;			/**< Write pointer */
++	drm_buf_t **end;		/**< End pointer */
++	spinlock_t read_lock;
++	spinlock_t write_lock;
+ } drm_waitlist_t;
+ 
+ typedef struct drm_freelist {
+-	int		  initialized; /**< Freelist in use */
+-	atomic_t	  count;       /**< Number of free buffers */
+-	drm_buf_t	  *next;       /**< End pointer */
++	int initialized;	       /**< Freelist in use */
++	atomic_t count;		       /**< Number of free buffers */
++	drm_buf_t *next;	       /**< End pointer */
+ 
+ 	wait_queue_head_t waiting;     /**< Processes waiting on free bufs */
+-	int		  low_mark;    /**< Low water mark */
+-	int		  high_mark;   /**< High water mark */
+-	atomic_t	  wfh;	       /**< If waiting for high mark */
+-	spinlock_t        lock;
++	int low_mark;		       /**< Low water mark */
++	int high_mark;		       /**< High water mark */
++	atomic_t wfh;		       /**< If waiting for high mark */
++	spinlock_t lock;
+ } drm_freelist_t;
+ 
+ /**
+  * Buffer entry.  There is one of this for each buffer size order.
+  */
+ typedef struct drm_buf_entry {
+-	int		  buf_size;	/**< size */
+-	int		  buf_count;	/**< number of buffers */
+-	drm_buf_t	  *buflist;	/**< buffer list */
+-	int		  seg_count;
+-	int		  page_order;
+-	unsigned long	  *seglist;
++	int buf_size;			/**< size */
++	int buf_count;			/**< number of buffers */
++	drm_buf_t *buflist;		/**< buffer list */
++	int seg_count;
++	int page_order;
++	unsigned long *seglist;
+ 
+-	drm_freelist_t	  freelist;
++	drm_freelist_t freelist;
+ } drm_buf_entry_t;
+ 
+ /** File private data */
+ typedef struct drm_file {
+-	int		  authenticated;
+-	int		  minor;
+-	pid_t		  pid;
+-	uid_t		  uid;
+-	drm_magic_t	  magic;
+-	unsigned long	  ioctl_count;
+-	struct drm_file	  *next;
+-	struct drm_file	  *prev;
+-	struct drm_head   *head;
+-	int 		  remove_auth_on_close;
+-	unsigned long     lock_count;
+-	void              *driver_priv;
++	int authenticated;
++	int minor;
++	pid_t pid;
++	uid_t uid;
++	drm_magic_t magic;
++	unsigned long ioctl_count;
++	struct drm_file *next;
++	struct drm_file *prev;
++	struct drm_head *head;
++	int remove_auth_on_close;
++	unsigned long lock_count;
++	void *driver_priv;
+ } drm_file_t;
+ 
+ /** Wait queue */
+ typedef struct drm_queue {
+-	atomic_t	  use_count;	/**< Outstanding uses (+1) */
+-	atomic_t	  finalization;	/**< Finalization in progress */
+-	atomic_t	  block_count;	/**< Count of processes waiting */
+-	atomic_t	  block_read;	/**< Queue blocked for reads */
++	atomic_t use_count;		/**< Outstanding uses (+1) */
++	atomic_t finalization;		/**< Finalization in progress */
++	atomic_t block_count;		/**< Count of processes waiting */
++	atomic_t block_read;		/**< Queue blocked for reads */
+ 	wait_queue_head_t read_queue;	/**< Processes waiting on block_read */
+-	atomic_t	  block_write;	/**< Queue blocked for writes */
++	atomic_t block_write;		/**< Queue blocked for writes */
+ 	wait_queue_head_t write_queue;	/**< Processes waiting on block_write */
+ #if 1
+-	atomic_t	  total_queued;	/**< Total queued statistic */
+-	atomic_t	  total_flushed;/**< Total flushes statistic */
+-	atomic_t	  total_locks;	/**< Total locks statistics */
++	atomic_t total_queued;		/**< Total queued statistic */
++	atomic_t total_flushed;		/**< Total flushes statistic */
++	atomic_t total_locks;		/**< Total locks statistics */
+ #endif
+-	drm_ctx_flags_t	  flags;	/**< Context preserving and 2D-only */
+-	drm_waitlist_t	  waitlist;	/**< Pending buffers */
++	drm_ctx_flags_t flags;		/**< Context preserving and 2D-only */
++	drm_waitlist_t waitlist;	/**< Pending buffers */
+ 	wait_queue_head_t flush_queue;	/**< Processes waiting until flush */
+ } drm_queue_t;
+ 
+@@ -425,10 +420,10 @@ typedef struct drm_queue {
+  * Lock data.
+  */
+ typedef struct drm_lock_data {
+-	drm_hw_lock_t	  *hw_lock;	/**< Hardware lock */
+-	struct file       *filp;	/**< File descr of lock holder (0=kernel) */
++	drm_hw_lock_t *hw_lock;		/**< Hardware lock */
++	struct file *filp;		/**< File descr of lock holder (0=kernel) */
+ 	wait_queue_head_t lock_queue;	/**< Queue of blocked processes */
+-	unsigned long	  lock_time;	/**< Time of last lock in jiffies */
++	unsigned long lock_time;	/**< Time of last lock in jiffies */
+ } drm_lock_data_t;
+ 
+ /**
+@@ -436,29 +431,29 @@ typedef struct drm_lock_data {
+  */
+ typedef struct drm_device_dma {
+ 
+-	drm_buf_entry_t	  bufs[DRM_MAX_ORDER+1];	/**< buffers, grouped by their size order */
+-	int		  buf_count;	/**< total number of buffers */
+-	drm_buf_t	  **buflist;	/**< Vector of pointers into drm_device_dma::bufs */
+-	int		  seg_count;
+-	int		  page_count;	/**< number of pages */
+-	unsigned long	  *pagelist;	/**< page list */
+-	unsigned long	  byte_count;
++	drm_buf_entry_t bufs[DRM_MAX_ORDER + 1];	/**< buffers, grouped by their size order */
++	int buf_count;			/**< total number of buffers */
++	drm_buf_t **buflist;		/**< Vector of pointers into drm_device_dma::bufs */
++	int seg_count;
++	int page_count;			/**< number of pages */
++	unsigned long *pagelist;	/**< page list */
++	unsigned long byte_count;
+ 	enum {
+ 		_DRM_DMA_USE_AGP = 0x01,
+-		_DRM_DMA_USE_SG  = 0x02,
+-		_DRM_DMA_USE_FB  = 0x04
++		_DRM_DMA_USE_SG = 0x02,
++		_DRM_DMA_USE_FB = 0x04
+ 	} flags;
+ 
+ } drm_device_dma_t;
+ 
+-/** 
++/**
+  * AGP memory entry.  Stored as a doubly linked list.
+  */
+ typedef struct drm_agp_mem {
+-	unsigned long      handle;	/**< handle */
+-	DRM_AGP_MEM        *memory;	
+-	unsigned long      bound;	/**< address */
+-	int                pages;
++	unsigned long handle;		/**< handle */
++	DRM_AGP_MEM *memory;
++	unsigned long bound;		/**< address */
++	int pages;
+ 	struct drm_agp_mem *prev;	/**< previous entry */
+ 	struct drm_agp_mem *next;	/**< next entry */
+ } drm_agp_mem_t;
+@@ -469,31 +464,31 @@ typedef struct drm_agp_mem {
+  * \sa drm_agp_init() and drm_device::agp.
+  */
+ typedef struct drm_agp_head {
+-	DRM_AGP_KERN       agp_info;	/**< AGP device information */
+-	drm_agp_mem_t      *memory;	/**< memory entries */
+-	unsigned long      mode;	/**< AGP mode */
+-	struct agp_bridge_data  *bridge;
+-	int                enabled;	/**< whether the AGP bus as been enabled */
+-	int                acquired;	/**< whether the AGP device has been acquired */
+-	unsigned long      base;
+-   	int 		   agp_mtrr;
+-	int		   cant_use_aperture;
+-	unsigned long	   page_mask;
++	DRM_AGP_KERN agp_info;		/**< AGP device information */
++	drm_agp_mem_t *memory;		/**< memory entries */
++	unsigned long mode;		/**< AGP mode */
++	struct agp_bridge_data *bridge;
++	int enabled;			/**< whether the AGP bus as been enabled */
++	int acquired;			/**< whether the AGP device has been acquired */
++	unsigned long base;
++	int agp_mtrr;
++	int cant_use_aperture;
++	unsigned long page_mask;
+ } drm_agp_head_t;
+ 
+ /**
+  * Scatter-gather memory.
+  */
+ typedef struct drm_sg_mem {
+-	unsigned long   handle;
+-	void            *virtual;
+-	int             pages;
+-	struct page     **pagelist;
+-	dma_addr_t	*busaddr;
++	unsigned long handle;
++	void *virtual;
++	int pages;
++	struct page **pagelist;
++	dma_addr_t *busaddr;
+ } drm_sg_mem_t;
+ 
+ typedef struct drm_sigdata {
+-	int           context;
++	int context;
+ 	drm_hw_lock_t *lock;
+ } drm_sigdata_t;
+ 
+@@ -507,8 +502,8 @@ typedef struct drm_dma_handle {
+  * Mappings list
+  */
+ typedef struct drm_map_list {
+-	struct list_head	head;	/**< list head */
+-	drm_map_t		*map;	/**< mapping */
++	struct list_head head;		/**< list head */
++	drm_map_t *map;			/**< mapping */
+ 	unsigned int user_token;
+ } drm_map_list_t;
+ 
+@@ -518,19 +513,28 @@ typedef drm_map_t drm_local_map_t;
+  * Context handle list
+  */
+ typedef struct drm_ctx_list {
+-	struct list_head	head;   /**< list head */
+-	drm_context_t		handle; /**< context handle */
+-	drm_file_t		*tag;   /**< associated fd private data */
++	struct list_head head;		/**< list head */
++	drm_context_t handle;		/**< context handle */
++	drm_file_t *tag;		/**< associated fd private data */
+ } drm_ctx_list_t;
+ 
+-
+ typedef struct drm_vbl_sig {
+-	struct list_head	head;
+-	unsigned int		sequence;
+-	struct siginfo		info;
+-	struct task_struct	*task;
++	struct list_head head;
++	unsigned int sequence;
++	struct siginfo info;
++	struct task_struct *task;
+ } drm_vbl_sig_t;
+ 
++/* location of GART table */
++#define DRM_ATI_GART_MAIN 1
++#define DRM_ATI_GART_FB   2
++
++typedef struct ati_pcigart_info {
++	int gart_table_location;
++	int is_pcie;
++	unsigned long addr;
++	dma_addr_t bus_addr;
++} drm_ati_pcigart_info;
+ 
+ /**
+  * DRM driver structure. This structure represent the common code for
+@@ -540,24 +544,26 @@ typedef struct drm_vbl_sig {
+ struct drm_device;
+ 
+ struct drm_driver {
+-	int (*preinit)(struct drm_device *, unsigned long flags);
+-	void (*prerelease)(struct drm_device *, struct file *filp);
+-	void (*pretakedown)(struct drm_device *);
+-	int (*postcleanup)(struct drm_device *);
+-	int (*presetup)(struct drm_device *);
+-	int (*postsetup)(struct drm_device *);
+- 	int (*dma_ioctl)( DRM_IOCTL_ARGS );
+-	int (*open_helper)(struct drm_device *, drm_file_t *);
+-	void (*free_filp_priv)(struct drm_device *, drm_file_t *);
+-	void (*release)(struct drm_device *, struct file *filp);
+-	void (*dma_ready)(struct drm_device *);
+-	int (*dma_quiescent)(struct drm_device *);
+-	int (*context_ctor)(struct drm_device *dev, int context);
+- 	int (*context_dtor)(struct drm_device *dev, int context);
+- 	int (*kernel_context_switch)(struct drm_device *dev, int old, int new);
+-	void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock);
+-	int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence);
+-	
++	int (*preinit) (struct drm_device *, unsigned long flags);
++	void (*prerelease) (struct drm_device *, struct file * filp);
++	void (*pretakedown) (struct drm_device *);
++	int (*postcleanup) (struct drm_device *);
++	int (*presetup) (struct drm_device *);
++	int (*postsetup) (struct drm_device *);
++	int (*dma_ioctl) (DRM_IOCTL_ARGS);
++	int (*open_helper) (struct drm_device *, drm_file_t *);
++	void (*free_filp_priv) (struct drm_device *, drm_file_t *);
++	void (*release) (struct drm_device *, struct file * filp);
++	void (*dma_ready) (struct drm_device *);
++	int (*dma_quiescent) (struct drm_device *);
++	int (*context_ctor) (struct drm_device * dev, int context);
++	int (*context_dtor) (struct drm_device * dev, int context);
++	int (*kernel_context_switch) (struct drm_device * dev, int old,
++				      int new);
++	void (*kernel_context_switch_unlock) (struct drm_device * dev,
++					      drm_lock_t * lock);
++	int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
++
+ 	/**
+ 	 * Called by \c drm_device_is_agp.  Typically used to determine if a
+ 	 * card is really attached to AGP or not.
+@@ -572,17 +578,17 @@ struct drm_driver {
+ 	int (*device_is_agp) (struct drm_device * dev);
+ 
+ 	/* these have to be filled in */
+-  
+- 	int (*postinit)(struct drm_device *, unsigned long flags);
+-	irqreturn_t (*irq_handler)( DRM_IRQ_ARGS );
+- 	void (*irq_preinstall)(struct drm_device *dev);
+- 	void (*irq_postinstall)(struct drm_device *dev);
+- 	void (*irq_uninstall)(struct drm_device *dev);
+-	void (*reclaim_buffers)(struct drm_device *dev, struct file *filp);
+-	unsigned long (*get_map_ofs)(drm_map_t *map);
+-	unsigned long (*get_reg_ofs)(struct drm_device *dev);
+-	void (*set_version)(struct drm_device *dev, drm_set_version_t *sv);
+- 	int (*version)(drm_version_t *version);
++
++	int (*postinit) (struct drm_device *, unsigned long flags);
++	 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
++	void (*irq_preinstall) (struct drm_device * dev);
++	void (*irq_postinstall) (struct drm_device * dev);
++	void (*irq_uninstall) (struct drm_device * dev);
++	void (*reclaim_buffers) (struct drm_device * dev, struct file * filp);
++	unsigned long (*get_map_ofs) (drm_map_t * map);
++	unsigned long (*get_reg_ofs) (struct drm_device * dev);
++	void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
++	int (*version) (drm_version_t * version);
+ 	u32 driver_features;
+ 	int dev_priv_size;
+ 	drm_ioctl_desc_t *ioctls;
+@@ -609,128 +615,125 @@ typedef struct drm_head {
+  * may contain multiple heads.
+  */
+ typedef struct drm_device {
+-	char		  *unique;	/**< Unique identifier: e.g., busid */
+-	int		  unique_len;	/**< Length of unique field */
+-	char		  *devname;	/**< For /proc/interrupts */
+-	int		  if_version;	/**< Highest interface version set */
++	char *unique;			/**< Unique identifier: e.g., busid */
++	int unique_len;			/**< Length of unique field */
++	char *devname;			/**< For /proc/interrupts */
++	int if_version;			/**< Highest interface version set */
+ 
+-	int		  blocked;	/**< Blocked due to VC switch? */
++	int blocked;			/**< Blocked due to VC switch? */
+ 
+ 	/** \name Locks */
+-	/*@{*/
+-	spinlock_t	  count_lock;	/**< For inuse, drm_device::open_count, drm_device::buf_use */
+-	struct semaphore  struct_sem;	/**< For others */
+-	/*@}*/
++	/*@{ */
++	spinlock_t count_lock;		/**< For inuse, drm_device::open_count, drm_device::buf_use */
++	struct semaphore struct_sem;	/**< For others */
++	/*@} */
+ 
+ 	/** \name Usage Counters */
+-	/*@{*/
+-	int		  open_count;	/**< Outstanding files open */
+-	atomic_t	  ioctl_count;	/**< Outstanding IOCTLs pending */
+-	atomic_t	  vma_count;	/**< Outstanding vma areas open */
+-	int		  buf_use;	/**< Buffers in use -- cannot alloc */
+-	atomic_t	  buf_alloc;	/**< Buffer allocation in progress */
+-	/*@}*/
++	/*@{ */
++	int open_count;			/**< Outstanding files open */
++	atomic_t ioctl_count;		/**< Outstanding IOCTLs pending */
++	atomic_t vma_count;		/**< Outstanding vma areas open */
++	int buf_use;			/**< Buffers in use -- cannot alloc */
++	atomic_t buf_alloc;		/**< Buffer allocation in progress */
++	/*@} */
+ 
+ 	/** \name Performance counters */
+-	/*@{*/
+-	unsigned long     counters;
+-	drm_stat_type_t   types[15];
+-	atomic_t          counts[15];
+-	/*@}*/
++	/*@{ */
++	unsigned long counters;
++	drm_stat_type_t types[15];
++	atomic_t counts[15];
++	/*@} */
+ 
+ 	/** \name Authentication */
+-	/*@{*/
+-	drm_file_t	  *file_first;	/**< file list head */
+-	drm_file_t	  *file_last;	/**< file list tail */
+-	drm_magic_head_t  magiclist[DRM_HASH_SIZE];	/**< magic hash table */
+-	/*@}*/
++	/*@{ */
++	drm_file_t *file_first;		/**< file list head */
++	drm_file_t *file_last;		/**< file list tail */
++	drm_magic_head_t magiclist[DRM_HASH_SIZE];	/**< magic hash table */
++	/*@} */
+ 
+ 	/** \name Memory management */
+-	/*@{*/
+-	drm_map_list_t	  *maplist;	/**< Linked list of regions */
+-	int		  map_count;	/**< Number of mappable regions */
++	/*@{ */
++	drm_map_list_t *maplist;	/**< Linked list of regions */
++	int map_count;			/**< Number of mappable regions */
+ 
+ 	/** \name Context handle management */
+-	/*@{*/
+-	drm_ctx_list_t	  *ctxlist;	/**< Linked list of context handles */
+-	int		  ctx_count;	/**< Number of context handles */
+-	struct semaphore  ctxlist_sem;	/**< For ctxlist */
+-
+-	drm_map_t	  **context_sareas; /**< per-context SAREA's */
+-	int		  max_context;
+-
+-	drm_vma_entry_t	  *vmalist;	/**< List of vmas (for debugging) */
+-	drm_lock_data_t	  lock;		/**< Information on hardware lock */
+-	/*@}*/
++	/*@{ */
++	drm_ctx_list_t *ctxlist;	/**< Linked list of context handles */
++	int ctx_count;			/**< Number of context handles */
++	struct semaphore ctxlist_sem;	/**< For ctxlist */
++
++	drm_map_t **context_sareas;	    /**< per-context SAREA's */
++	int max_context;
++
++	drm_vma_entry_t *vmalist;	/**< List of vmas (for debugging) */
++	drm_lock_data_t lock;		/**< Information on hardware lock */
++	/*@} */
+ 
+ 	/** \name DMA queues (contexts) */
+-	/*@{*/
+-	int		  queue_count;	/**< Number of active DMA queues */
+-	int		  queue_reserved; /**< Number of reserved DMA queues */
+-	int		  queue_slots;	/**< Actual length of queuelist */
+-	drm_queue_t	  **queuelist;	/**< Vector of pointers to DMA queues */
+-	drm_device_dma_t  *dma;		/**< Optional pointer for DMA support */
+-	/*@}*/
++	/*@{ */
++	int queue_count;		/**< Number of active DMA queues */
++	int queue_reserved;		  /**< Number of reserved DMA queues */
++	int queue_slots;		/**< Actual length of queuelist */
++	drm_queue_t **queuelist;	/**< Vector of pointers to DMA queues */
++	drm_device_dma_t *dma;		/**< Optional pointer for DMA support */
++	/*@} */
+ 
+ 	/** \name Context support */
+-	/*@{*/
+-	int		  irq;		/**< Interrupt used by board */
+-	int		  irq_enabled;	/**< True if irq handler is enabled */
++	/*@{ */
++	int irq;			/**< Interrupt used by board */
++	int irq_enabled;		/**< True if irq handler is enabled */
+ 	__volatile__ long context_flag;	/**< Context swapping flag */
+ 	__volatile__ long interrupt_flag; /**< Interruption handler flag */
+ 	__volatile__ long dma_flag;	/**< DMA dispatch flag */
+ 	struct timer_list timer;	/**< Timer for delaying ctx switch */
+-	wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */
+-	int		  last_checked;	/**< Last context checked for DMA */
+-	int		  last_context;	/**< Last current context */
+-	unsigned long	  last_switch;	/**< jiffies at last context switch */
+-	/*@}*/
+-	
+-	struct work_struct	work;
++	wait_queue_head_t context_wait;	/**< Processes waiting on ctx switch */
++	int last_checked;		/**< Last context checked for DMA */
++	int last_context;		/**< Last current context */
++	unsigned long last_switch;	/**< jiffies at last context switch */
++	/*@} */
++
++	struct work_struct work;
+ 	/** \name VBLANK IRQ support */
+-	/*@{*/
++	/*@{ */
++
++	wait_queue_head_t vbl_queue;	/**< VBLANK wait queue */
++	atomic_t vbl_received;
++	spinlock_t vbl_lock;
++	drm_vbl_sig_t vbl_sigs;		/**< signal list to send on VBLANK */
++	unsigned int vbl_pending;
++
++	/*@} */
++	cycles_t ctx_start;
++	cycles_t lck_start;
+ 
+-   	wait_queue_head_t vbl_queue;	/**< VBLANK wait queue */
+-   	atomic_t          vbl_received;
+-	spinlock_t        vbl_lock;
+-	drm_vbl_sig_t     vbl_sigs;	/**< signal list to send on VBLANK */
+-	unsigned int      vbl_pending;
+-
+-	/*@}*/
+-	cycles_t	  ctx_start;
+-	cycles_t	  lck_start;
+-
+-	char		  buf[DRM_BSZ]; /**< Output buffer */
+-	char		  *buf_rp;	/**< Read pointer */
+-	char		  *buf_wp;	/**< Write pointer */
+-	char		  *buf_end;	/**< End pointer */
+ 	struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */
+ 	wait_queue_head_t buf_readers;	/**< Processes waiting to read */
+ 	wait_queue_head_t buf_writers;	/**< Processes waiting to ctx switch */
+ 
+-	drm_agp_head_t    *agp;	/**< AGP data */
++	drm_agp_head_t *agp;	/**< AGP data */
+ 
+-	struct pci_dev    *pdev;	/**< PCI device structure */
+-	int               pci_domain;	/**< PCI bus domain number */
+-	int               pci_bus;	/**< PCI bus number */
+-	int               pci_slot;	/**< PCI slot number */
+-	int               pci_func;	/**< PCI function number */
++	struct pci_dev *pdev;		/**< PCI device structure */
++	int pci_domain;			/**< PCI bus domain number */
++	int pci_bus;			/**< PCI bus number */
++	int pci_slot;			/**< PCI slot number */
++	int pci_func;			/**< PCI function number */
+ #ifdef __alpha__
+ 	struct pci_controller *hose;
+ #endif
+-	drm_sg_mem_t      *sg;  /**< Scatter gather memory */
+-	unsigned long     *ctx_bitmap;	/**< context bitmap */
+-	void		  *dev_private; /**< device private data */
+-	drm_sigdata_t     sigdata; /**< For block_all_signals */
+-	sigset_t          sigmask;
++	drm_sg_mem_t *sg;	/**< Scatter gather memory */
++	unsigned long *ctx_bitmap;	/**< context bitmap */
++	void *dev_private;		/**< device private data */
++	drm_sigdata_t sigdata;	   /**< For block_all_signals */
++	sigset_t sigmask;
+ 
+-	struct            drm_driver *driver;
+-	drm_local_map_t   *agp_buffer_map;
++	struct drm_driver *driver;
++	drm_local_map_t *agp_buffer_map;
+ 	unsigned int agp_buffer_token;
+ 	drm_head_t primary;		/**< primary screen head */
+ } drm_device_t;
+ 
+-static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature)
++static __inline__ int drm_core_check_feature(struct drm_device *dev,
++					     int feature)
+ {
+ 	return ((dev->driver->driver_features & feature) ? 1 : 0);
+ }
+@@ -738,7 +741,7 @@ static __inline__ int drm_core_check_fea
+ #if __OS_HAS_AGP
+ static inline int drm_core_has_AGP(struct drm_device *dev)
+ {
+-  return drm_core_check_feature(dev, DRIVER_USE_AGP);
++	return drm_core_check_feature(dev, DRIVER_USE_AGP);
+ }
+ #else
+ #define drm_core_has_AGP(dev) (0)
+@@ -747,7 +750,7 @@ static inline int drm_core_has_AGP(struc
+ #if __OS_HAS_MTRR
+ static inline int drm_core_has_MTRR(struct drm_device *dev)
+ {
+-  return drm_core_check_feature(dev, DRIVER_USE_MTRR);
++	return drm_core_check_feature(dev, DRIVER_USE_MTRR);
+ }
+ #else
+ #define drm_core_has_MTRR(dev) (0)
+@@ -758,234 +761,229 @@ static inline int drm_core_has_MTRR(stru
+ /*@{*/
+ 
+ 				/* Misc. support (drm_init.h) */
+-extern int	     drm_flags;
+-extern void	     drm_parse_options( char *s );
+-extern int           drm_cpu_valid( void );
++extern int drm_flags;
++extern void drm_parse_options(char *s);
++extern int drm_cpu_valid(void);
+ 
+ 				/* Driver support (drm_drv.h) */
+-extern int           drm_init(struct drm_driver *driver);
+-extern void          drm_exit(struct drm_driver *driver);
+-extern int           drm_ioctl(struct inode *inode, struct file *filp,
+-				unsigned int cmd, unsigned long arg);
+-extern long	     drm_compat_ioctl(struct file *filp,
+-				unsigned int cmd, unsigned long arg);
+-extern int           drm_takedown(drm_device_t * dev);
++extern int drm_init(struct drm_driver *driver);
++extern void drm_exit(struct drm_driver *driver);
++extern int drm_ioctl(struct inode *inode, struct file *filp,
++		     unsigned int cmd, unsigned long arg);
++extern long drm_compat_ioctl(struct file *filp,
++			     unsigned int cmd, unsigned long arg);
++extern int drm_takedown(drm_device_t * dev);
+ 
+ 				/* Device support (drm_fops.h) */
+-extern int           drm_open(struct inode *inode, struct file *filp);
+-extern int           drm_stub_open(struct inode *inode, struct file *filp);
+-extern int	     drm_flush(struct file *filp);
+-extern int	     drm_fasync(int fd, struct file *filp, int on);
+-extern int           drm_release(struct inode *inode, struct file *filp);
++extern int drm_open(struct inode *inode, struct file *filp);
++extern int drm_stub_open(struct inode *inode, struct file *filp);
++extern int drm_flush(struct file *filp);
++extern int drm_fasync(int fd, struct file *filp, int on);
++extern int drm_release(struct inode *inode, struct file *filp);
+ 
+ 				/* Mapping support (drm_vm.h) */
+-extern int	     drm_mmap(struct file *filp, struct vm_area_struct *vma);
+-extern unsigned int  drm_poll(struct file *filp, struct poll_table_struct *wait);
++extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
++extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
+ 
+ 				/* Memory management support (drm_memory.h) */
+ #include "drm_memory.h"
+-extern void	     drm_mem_init(void);
+-extern int	     drm_mem_info(char *buf, char **start, off_t offset,
+-				   int request, int *eof, void *data);
+-extern void	     *drm_realloc(void *oldpt, size_t oldsize, size_t size,
+-				   int area);
++extern void drm_mem_init(void);
++extern int drm_mem_info(char *buf, char **start, off_t offset,
++			int request, int *eof, void *data);
++extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
+ extern unsigned long drm_alloc_pages(int order, int area);
+-extern void	     drm_free_pages(unsigned long address, int order,
+-				     int area);
+-extern void	     *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev);
+-extern void	     *drm_ioremap_nocache(unsigned long offset, unsigned long size,
+-					   drm_device_t *dev);
+-extern void	     drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev);
+-
+-extern DRM_AGP_MEM   *drm_alloc_agp(drm_device_t *dev, int pages, u32 type);
+-extern int           drm_free_agp(DRM_AGP_MEM *handle, int pages);
+-extern int           drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start);
+-extern int           drm_unbind_agp(DRM_AGP_MEM *handle);
++extern void drm_free_pages(unsigned long address, int order, int area);
++extern void *drm_ioremap(unsigned long offset, unsigned long size,
++			 drm_device_t * dev);
++extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
++				 drm_device_t * dev);
++extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev);
++
++extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type);
++extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
++extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
++extern int drm_unbind_agp(DRM_AGP_MEM * handle);
+ 
+ 				/* Misc. IOCTL support (drm_ioctl.h) */
+-extern int	     drm_irq_by_busid(struct inode *inode, struct file *filp,
+-				       unsigned int cmd, unsigned long arg);
+-extern int	     drm_getunique(struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg);
+-extern int	     drm_setunique(struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg);
+-extern int	     drm_getmap(struct inode *inode, struct file *filp,
+-				 unsigned int cmd, unsigned long arg);
+-extern int	     drm_getclient(struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg);
+-extern int	     drm_getstats(struct inode *inode, struct file *filp,
+-				   unsigned int cmd, unsigned long arg);
+-extern int	     drm_setversion(struct inode *inode, struct file *filp,
+-				     unsigned int cmd, unsigned long arg);
++extern int drm_irq_by_busid(struct inode *inode, struct file *filp,
++			    unsigned int cmd, unsigned long arg);
++extern int drm_getunique(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg);
++extern int drm_setunique(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg);
++extern int drm_getmap(struct inode *inode, struct file *filp,
++		      unsigned int cmd, unsigned long arg);
++extern int drm_getclient(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg);
++extern int drm_getstats(struct inode *inode, struct file *filp,
++			unsigned int cmd, unsigned long arg);
++extern int drm_setversion(struct inode *inode, struct file *filp,
++			  unsigned int cmd, unsigned long arg);
+ 
+ 				/* Context IOCTL support (drm_context.h) */
+-extern int	     drm_resctx( struct inode *inode, struct file *filp,
+-				  unsigned int cmd, unsigned long arg );
+-extern int	     drm_addctx( struct inode *inode, struct file *filp,
+-				  unsigned int cmd, unsigned long arg );
+-extern int	     drm_modctx( struct inode *inode, struct file *filp,
+-				  unsigned int cmd, unsigned long arg );
+-extern int	     drm_getctx( struct inode *inode, struct file *filp,
+-				  unsigned int cmd, unsigned long arg );
+-extern int	     drm_switchctx( struct inode *inode, struct file *filp,
+-				     unsigned int cmd, unsigned long arg );
+-extern int	     drm_newctx( struct inode *inode, struct file *filp,
+-				  unsigned int cmd, unsigned long arg );
+-extern int	     drm_rmctx( struct inode *inode, struct file *filp,
+-				 unsigned int cmd, unsigned long arg );
+-
+-extern int	     drm_ctxbitmap_init( drm_device_t *dev );
+-extern void	     drm_ctxbitmap_cleanup( drm_device_t *dev );
+-extern void          drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle );
+-
+-extern int	     drm_setsareactx( struct inode *inode, struct file *filp,
+-				       unsigned int cmd, unsigned long arg );
+-extern int	     drm_getsareactx( struct inode *inode, struct file *filp,
+-				       unsigned int cmd, unsigned long arg );
++extern int drm_resctx(struct inode *inode, struct file *filp,
++		      unsigned int cmd, unsigned long arg);
++extern int drm_addctx(struct inode *inode, struct file *filp,
++		      unsigned int cmd, unsigned long arg);
++extern int drm_modctx(struct inode *inode, struct file *filp,
++		      unsigned int cmd, unsigned long arg);
++extern int drm_getctx(struct inode *inode, struct file *filp,
++		      unsigned int cmd, unsigned long arg);
++extern int drm_switchctx(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg);
++extern int drm_newctx(struct inode *inode, struct file *filp,
++		      unsigned int cmd, unsigned long arg);
++extern int drm_rmctx(struct inode *inode, struct file *filp,
++		     unsigned int cmd, unsigned long arg);
++
++extern int drm_ctxbitmap_init(drm_device_t * dev);
++extern void drm_ctxbitmap_cleanup(drm_device_t * dev);
++extern void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle);
+ 
+-				/* Drawable IOCTL support (drm_drawable.h) */
+-extern int	     drm_adddraw(struct inode *inode, struct file *filp,
+-				  unsigned int cmd, unsigned long arg);
+-extern int	     drm_rmdraw(struct inode *inode, struct file *filp,
+-				 unsigned int cmd, unsigned long arg);
++extern int drm_setsareactx(struct inode *inode, struct file *filp,
++			   unsigned int cmd, unsigned long arg);
++extern int drm_getsareactx(struct inode *inode, struct file *filp,
++			   unsigned int cmd, unsigned long arg);
+ 
++				/* Drawable IOCTL support (drm_drawable.h) */
++extern int drm_adddraw(struct inode *inode, struct file *filp,
++		       unsigned int cmd, unsigned long arg);
++extern int drm_rmdraw(struct inode *inode, struct file *filp,
++		      unsigned int cmd, unsigned long arg);
+ 
+ 				/* Authentication IOCTL support (drm_auth.h) */
+-extern int	     drm_getmagic(struct inode *inode, struct file *filp,
+-				   unsigned int cmd, unsigned long arg);
+-extern int	     drm_authmagic(struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg);
+-
+-                                /* Placeholder for ioctls past */
+-extern int	     drm_noop(struct inode *inode, struct file *filp,
+-				  unsigned int cmd, unsigned long arg);
++extern int drm_getmagic(struct inode *inode, struct file *filp,
++			unsigned int cmd, unsigned long arg);
++extern int drm_authmagic(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg);
++
++				/* Placeholder for ioctls past */
++extern int drm_noop(struct inode *inode, struct file *filp,
++		    unsigned int cmd, unsigned long arg);
+ 
+ 				/* Locking IOCTL support (drm_lock.h) */
+-extern int           drm_lock(struct inode *inode, struct file *filp,
+-			       unsigned int cmd, unsigned long arg);
+-extern int           drm_unlock(struct inode *inode, struct file *filp,
+-				 unsigned int cmd, unsigned long arg);
+-extern int	     drm_lock_take(__volatile__ unsigned int *lock,
+-				    unsigned int context);
+-extern int	     drm_lock_free(drm_device_t *dev,
+-				    __volatile__ unsigned int *lock,
+-				    unsigned int context);
++extern int drm_lock(struct inode *inode, struct file *filp,
++		    unsigned int cmd, unsigned long arg);
++extern int drm_unlock(struct inode *inode, struct file *filp,
++		      unsigned int cmd, unsigned long arg);
++extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context);
++extern int drm_lock_free(drm_device_t * dev,
++			 __volatile__ unsigned int *lock, unsigned int context);
+ 
+ 				/* Buffer management support (drm_bufs.h) */
+-extern int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request);
+-extern int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request);
+-extern int drm_addmap(drm_device_t *dev, unsigned int offset,
++extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
++extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
++extern int drm_addmap(drm_device_t * dev, unsigned int offset,
+ 		      unsigned int size, drm_map_type_t type,
+-		      drm_map_flags_t flags, drm_local_map_t **map_ptr);
++		      drm_map_flags_t flags, drm_local_map_t ** map_ptr);
+ extern int drm_addmap_ioctl(struct inode *inode, struct file *filp,
+ 			    unsigned int cmd, unsigned long arg);
+-extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map);
+-extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map);
++extern int drm_rmmap(drm_device_t * dev, drm_local_map_t * map);
++extern int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map);
+ extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
+ 			   unsigned int cmd, unsigned long arg);
+ 
+-extern int	     drm_order( unsigned long size );
+-extern int	     drm_addbufs( struct inode *inode, struct file *filp,
+-				   unsigned int cmd, unsigned long arg );
+-extern int	     drm_infobufs( struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg );
+-extern int	     drm_markbufs( struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg );
+-extern int	     drm_freebufs( struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg );
+-extern int	     drm_mapbufs( struct inode *inode, struct file *filp,
+-				   unsigned int cmd, unsigned long arg );
+-extern unsigned long drm_get_resource_start(drm_device_t *dev,
++extern int drm_order(unsigned long size);
++extern int drm_addbufs(struct inode *inode, struct file *filp,
++		       unsigned int cmd, unsigned long arg);
++extern int drm_infobufs(struct inode *inode, struct file *filp,
++			unsigned int cmd, unsigned long arg);
++extern int drm_markbufs(struct inode *inode, struct file *filp,
++			unsigned int cmd, unsigned long arg);
++extern int drm_freebufs(struct inode *inode, struct file *filp,
++			unsigned int cmd, unsigned long arg);
++extern int drm_mapbufs(struct inode *inode, struct file *filp,
++		       unsigned int cmd, unsigned long arg);
++extern unsigned long drm_get_resource_start(drm_device_t * dev,
+ 					    unsigned int resource);
+-extern unsigned long drm_get_resource_len(drm_device_t *dev,
++extern unsigned long drm_get_resource_len(drm_device_t * dev,
+ 					  unsigned int resource);
+ 
+ 				/* DMA support (drm_dma.h) */
+-extern int	     drm_dma_setup(drm_device_t *dev);
+-extern void	     drm_dma_takedown(drm_device_t *dev);
+-extern void	     drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
+-extern void	     drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp);
++extern int drm_dma_setup(drm_device_t * dev);
++extern void drm_dma_takedown(drm_device_t * dev);
++extern void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf);
++extern void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp);
+ 
+ 				/* IRQ support (drm_irq.h) */
+-extern int           drm_control( struct inode *inode, struct file *filp,
+-				   unsigned int cmd, unsigned long arg );
+-extern int           drm_irq_uninstall( drm_device_t *dev );
+-extern irqreturn_t   drm_irq_handler( DRM_IRQ_ARGS );
+-extern void          drm_driver_irq_preinstall( drm_device_t *dev );
+-extern void          drm_driver_irq_postinstall( drm_device_t *dev );
+-extern void          drm_driver_irq_uninstall( drm_device_t *dev );
+-
+-extern int           drm_wait_vblank(struct inode *inode, struct file *filp,
+-				      unsigned int cmd, unsigned long arg);
+-extern int           drm_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq);
+-extern void          drm_vbl_send_signals( drm_device_t *dev );
++extern int drm_control(struct inode *inode, struct file *filp,
++		       unsigned int cmd, unsigned long arg);
++extern int drm_irq_uninstall(drm_device_t * dev);
++extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
++extern void drm_driver_irq_preinstall(drm_device_t * dev);
++extern void drm_driver_irq_postinstall(drm_device_t * dev);
++extern void drm_driver_irq_uninstall(drm_device_t * dev);
++
++extern int drm_wait_vblank(struct inode *inode, struct file *filp,
++			   unsigned int cmd, unsigned long arg);
++extern int drm_vblank_wait(drm_device_t * dev, unsigned int *vbl_seq);
++extern void drm_vbl_send_signals(drm_device_t * dev);
+ 
+ 				/* AGP/GART support (drm_agpsupport.h) */
+-extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
++extern drm_agp_head_t *drm_agp_init(drm_device_t * dev);
+ extern int drm_agp_acquire(drm_device_t * dev);
+ extern int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
+-			   unsigned int cmd, unsigned long arg);
+-extern int drm_agp_release(drm_device_t *dev);
++				 unsigned int cmd, unsigned long arg);
++extern int drm_agp_release(drm_device_t * dev);
+ extern int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
+-			   unsigned int cmd, unsigned long arg);
+-extern int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode);
++				 unsigned int cmd, unsigned long arg);
++extern int drm_agp_enable(drm_device_t * dev, drm_agp_mode_t mode);
+ extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
+-			  unsigned int cmd, unsigned long arg);
+-extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info);
++				unsigned int cmd, unsigned long arg);
++extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info);
+ extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
++			      unsigned int cmd, unsigned long arg);
++extern int drm_agp_alloc(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg);
++extern int drm_agp_free(struct inode *inode, struct file *filp,
+ 			unsigned int cmd, unsigned long arg);
+-extern int            drm_agp_alloc(struct inode *inode, struct file *filp,
+-				     unsigned int cmd, unsigned long arg);
+-extern int            drm_agp_free(struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg);
+-extern int            drm_agp_unbind(struct inode *inode, struct file *filp,
+-				      unsigned int cmd, unsigned long arg);
+-extern int            drm_agp_bind(struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg);
+-extern DRM_AGP_MEM    *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type);
+-extern int            drm_agp_free_memory(DRM_AGP_MEM *handle);
+-extern int            drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start);
+-extern int            drm_agp_unbind_memory(DRM_AGP_MEM *handle);
++extern int drm_agp_unbind(struct inode *inode, struct file *filp,
++			  unsigned int cmd, unsigned long arg);
++extern int drm_agp_bind(struct inode *inode, struct file *filp,
++			unsigned int cmd, unsigned long arg);
++extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge,
++					    size_t pages, u32 type);
++extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
++extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
++extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
+ 
+ 				/* Stub support (drm_stub.h) */
+ extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+-		     struct drm_driver *driver);
++		       struct drm_driver *driver);
+ extern int drm_put_dev(drm_device_t * dev);
+ extern int drm_put_head(drm_head_t * head);
+-extern unsigned int   drm_debug;
+-extern unsigned int   drm_cards_limit;
++extern unsigned int drm_debug;
++extern unsigned int drm_cards_limit;
+ extern drm_head_t **drm_heads;
+ extern struct drm_sysfs_class *drm_class;
+ extern struct proc_dir_entry *drm_proc_root;
+ 
+ 				/* Proc support (drm_proc.h) */
+-extern int            drm_proc_init(drm_device_t *dev,
+-					     int minor,
+-					     struct proc_dir_entry *root,
+-					     struct proc_dir_entry **dev_root);
+-extern int            drm_proc_cleanup(int minor,
+-					struct proc_dir_entry *root,
+-					struct proc_dir_entry *dev_root);
++extern int drm_proc_init(drm_device_t * dev,
++			 int minor,
++			 struct proc_dir_entry *root,
++			 struct proc_dir_entry **dev_root);
++extern int drm_proc_cleanup(int minor,
++			    struct proc_dir_entry *root,
++			    struct proc_dir_entry *dev_root);
+ 
+ 				/* Scatter Gather Support (drm_scatter.h) */
+-extern void           drm_sg_cleanup(drm_sg_mem_t *entry);
+-extern int            drm_sg_alloc(struct inode *inode, struct file *filp,
+-				    unsigned int cmd, unsigned long arg);
+-extern int            drm_sg_free(struct inode *inode, struct file *filp,
+-				   unsigned int cmd, unsigned long arg);
+-
+-                               /* ATI PCIGART support (ati_pcigart.h) */
+-extern int            drm_ati_pcigart_init(drm_device_t *dev,
+-					    unsigned long *addr,
+-					    dma_addr_t *bus_addr);
+-extern int            drm_ati_pcigart_cleanup(drm_device_t *dev,
+-					       unsigned long addr,
+-					       dma_addr_t bus_addr);
++extern void drm_sg_cleanup(drm_sg_mem_t * entry);
++extern int drm_sg_alloc(struct inode *inode, struct file *filp,
++			unsigned int cmd, unsigned long arg);
++extern int drm_sg_free(struct inode *inode, struct file *filp,
++		       unsigned int cmd, unsigned long arg);
+ 
+-extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size,
++			       /* ATI PCIGART support (ati_pcigart.h) */
++extern int drm_ati_pcigart_init(drm_device_t * dev,
++				drm_ati_pcigart_info * gart_info);
++extern int drm_ati_pcigart_cleanup(drm_device_t * dev,
++				   drm_ati_pcigart_info * gart_info);
++
++extern drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size,
+ 				       size_t align, dma_addr_t maxaddr);
+-extern void __drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
+-extern void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
++extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah);
++extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah);
+ 
+ 			       /* sysfs support (drm_sysfs.c) */
+ struct drm_sysfs_class;
+@@ -998,38 +996,41 @@ extern struct class_device *drm_sysfs_de
+ 						 const char *fmt, ...);
+ extern void drm_sysfs_device_remove(dev_t dev);
+ 
+-
+ /* Inline replacements for DRM_IOREMAP macros */
+-static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
++static __inline__ void drm_core_ioremap(struct drm_map *map,
++					struct drm_device *dev)
+ {
+-	map->handle = drm_ioremap( map->offset, map->size, dev );
++	map->handle = drm_ioremap(map->offset, map->size, dev);
+ }
+ 
+-static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, struct drm_device *dev)
++static __inline__ void drm_core_ioremap_nocache(struct drm_map *map,
++						struct drm_device *dev)
+ {
+ 	map->handle = drm_ioremap_nocache(map->offset, map->size, dev);
+ }
+ 
+-static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
++static __inline__ void drm_core_ioremapfree(struct drm_map *map,
++					    struct drm_device *dev)
+ {
+-	if ( map->handle && map->size )
+-		drm_ioremapfree( map->handle, map->size, dev );
++	if (map->handle && map->size)
++		drm_ioremapfree(map->handle, map->size, dev);
+ }
+ 
+-static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned int token)
++static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev,
++						   unsigned int token)
+ {
+ 	drm_map_list_t *_entry;
+ 	list_for_each_entry(_entry, &dev->maplist->head, head)
+-		if (_entry->user_token == token)
+-			return _entry->map;
++	    if (_entry->user_token == token)
++		return _entry->map;
+ 	return NULL;
+ }
+ 
+-static __inline__ int drm_device_is_agp(drm_device_t *dev)
++static __inline__ int drm_device_is_agp(drm_device_t * dev)
+ {
+-	if ( dev->driver->device_is_agp != NULL ) {
+-		int err = (*dev->driver->device_is_agp)( dev );
+-	
++	if (dev->driver->device_is_agp != NULL) {
++		int err = (*dev->driver->device_is_agp) (dev);
++
+ 		if (err != 2) {
+ 			return err;
+ 		}
+@@ -1038,6 +1039,11 @@ static __inline__ int drm_device_is_agp(
+ 	return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
+ }
+ 
++static __inline__ int drm_device_is_pcie(drm_device_t * dev)
++{
++	return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
++}
++
+ static __inline__ void drm_core_dropmap(struct drm_map *map)
+ {
+ }
+@@ -1068,12 +1074,12 @@ extern void *drm_calloc(size_t nmemb, si
+ 
+ /*@}*/
+ 
+-extern unsigned long drm_core_get_map_ofs(drm_map_t *map);
++extern unsigned long drm_core_get_map_ofs(drm_map_t * map);
+ extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
+ 
+ #ifndef pci_pretty_name
+ #define pci_pretty_name(dev) ""
+ #endif
+ 
+-#endif /* __KERNEL__ */
++#endif				/* __KERNEL__ */
+ #endif
+diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
+--- a/drivers/char/drm/drm_agpsupport.c
++++ b/drivers/char/drm/drm_agpsupport.c
+@@ -1,7 +1,7 @@
+ /**
+- * \file drm_agpsupport.h 
++ * \file drm_agpsupport.h
+  * DRM support for AGP/GART backend
+- *    
++ *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Gareth Hughes <gareth at valinux.com>
+  */
+@@ -48,30 +48,31 @@
+  * Verifies the AGP device has been initialized and acquired and fills in the
+  * drm_agp_info structure with the information in drm_agp_head::agp_info.
+  */
+-int drm_agp_info(drm_device_t *dev, drm_agp_info_t *info)
++int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info)
+ {
+-	DRM_AGP_KERN     *kern;
++	DRM_AGP_KERN *kern;
+ 
+ 	if (!dev->agp || !dev->agp->acquired)
+ 		return -EINVAL;
+ 
+-	kern                   = &dev->agp->agp_info;
++	kern = &dev->agp->agp_info;
+ 	info->agp_version_major = kern->version.major;
+ 	info->agp_version_minor = kern->version.minor;
+-	info->mode              = kern->mode;
+-	info->aperture_base     = kern->aper_base;
+-	info->aperture_size     = kern->aper_size * 1024 * 1024;
+-	info->memory_allowed    = kern->max_memory << PAGE_SHIFT;
+-	info->memory_used       = kern->current_memory << PAGE_SHIFT;
+-	info->id_vendor         = kern->device->vendor;
+-	info->id_device         = kern->device->device;
++	info->mode = kern->mode;
++	info->aperture_base = kern->aper_base;
++	info->aperture_size = kern->aper_size * 1024 * 1024;
++	info->memory_allowed = kern->max_memory << PAGE_SHIFT;
++	info->memory_used = kern->current_memory << PAGE_SHIFT;
++	info->id_vendor = kern->device->vendor;
++	info->id_device = kern->device->device;
+ 
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_agp_info);
+ 
+ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg)
++		       unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -81,7 +82,7 @@ int drm_agp_info_ioctl(struct inode *ino
+ 	err = drm_agp_info(dev, &info);
+ 	if (err)
+ 		return err;
+-	
++
+ 	if (copy_to_user((drm_agp_info_t __user *) arg, &info, sizeof(info)))
+ 		return -EFAULT;
+ 	return 0;
+@@ -91,12 +92,12 @@ int drm_agp_info_ioctl(struct inode *ino
+  * Acquire the AGP device.
+  *
+  * \param dev DRM device that is to acquire AGP
+- * \return zero on success or a negative number on failure. 
++ * \return zero on success or a negative number on failure.
+  *
+  * Verifies the AGP device hasn't been acquired before and calls
+  * \c agp_backend_acquire.
+  */
+-int drm_agp_acquire(drm_device_t *dev)
++int drm_agp_acquire(drm_device_t * dev)
+ {
+ 	if (!dev->agp)
+ 		return -ENODEV;
+@@ -107,6 +108,7 @@ int drm_agp_acquire(drm_device_t *dev)
+ 	dev->agp->acquired = 1;
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_agp_acquire);
+ 
+ /**
+@@ -125,8 +127,8 @@ int drm_agp_acquire_ioctl(struct inode *
+ 			  unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+-	
+-	return drm_agp_acquire( (drm_device_t *) priv->head->dev );
++
++	return drm_agp_acquire((drm_device_t *) priv->head->dev);
+ }
+ 
+ /**
+@@ -137,7 +139,7 @@ int drm_agp_acquire_ioctl(struct inode *
+  *
+  * Verifies the AGP device has been acquired and calls \c agp_backend_release.
+  */
+-int drm_agp_release(drm_device_t *dev)
++int drm_agp_release(drm_device_t * dev)
+ {
+ 	if (!dev->agp || !dev->agp->acquired)
+ 		return -EINVAL;
+@@ -145,6 +147,7 @@ int drm_agp_release(drm_device_t *dev)
+ 	dev->agp->acquired = 0;
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_agp_release);
+ 
+ int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
+@@ -152,13 +155,13 @@ int drm_agp_release_ioctl(struct inode *
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+-	
++
+ 	return drm_agp_release(dev);
+ }
+ 
+ /**
+  * Enable the AGP bus.
+- * 
++ *
+  * \param dev DRM device that has previously acquired AGP.
+  * \param mode Requested AGP mode.
+  * \return zero on success or a negative number on failure.
+@@ -166,27 +169,27 @@ int drm_agp_release_ioctl(struct inode *
+  * Verifies the AGP device has been acquired but not enabled, and calls
+  * \c agp_enable.
+  */
+-int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
++int drm_agp_enable(drm_device_t * dev, drm_agp_mode_t mode)
+ {
+ 	if (!dev->agp || !dev->agp->acquired)
+ 		return -EINVAL;
+ 
+-	dev->agp->mode    = mode.mode;
++	dev->agp->mode = mode.mode;
+ 	agp_enable(dev->agp->bridge, mode.mode);
+-	dev->agp->base    = dev->agp->agp_info.aper_base;
++	dev->agp->base = dev->agp->agp_info.aper_base;
+ 	dev->agp->enabled = 1;
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_agp_enable);
+ 
+ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg)
++			 unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_agp_mode_t mode;
+ 
+-
+ 	if (copy_from_user(&mode, (drm_agp_mode_t __user *) arg, sizeof(mode)))
+ 		return -EFAULT;
+ 
+@@ -201,20 +204,20 @@ int drm_agp_enable_ioctl(struct inode *i
+  * \param cmd command.
+  * \param arg pointer to a drm_agp_buffer structure.
+  * \return zero on success or a negative number on failure.
+- * 
++ *
+  * Verifies the AGP device is present and has been acquired, allocates the
+  * memory via alloc_agp() and creates a drm_agp_mem entry for it.
+  */
+ int drm_agp_alloc(struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg)
++		  unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	 *priv	 = filp->private_data;
+-	drm_device_t	 *dev	 = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_agp_buffer_t request;
+-	drm_agp_mem_t    *entry;
+-	DRM_AGP_MEM      *memory;
+-	unsigned long    pages;
+-	u32 		 type;
++	drm_agp_mem_t *entry;
++	DRM_AGP_MEM *memory;
++	unsigned long pages;
++	u32 type;
+ 	drm_agp_buffer_t __user *argp = (void __user *)arg;
+ 
+ 	if (!dev->agp || !dev->agp->acquired)
+@@ -224,7 +227,7 @@ int drm_agp_alloc(struct inode *inode, s
+ 	if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
+ 		return -ENOMEM;
+ 
+-   	memset(entry, 0, sizeof(*entry));
++	memset(entry, 0, sizeof(*entry));
+ 
+ 	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+ 	type = (u32) request.type;
+@@ -234,21 +237,21 @@ int drm_agp_alloc(struct inode *inode, s
+ 		return -ENOMEM;
+ 	}
+ 
+-	entry->handle    = (unsigned long)memory->key + 1;
+-	entry->memory    = memory;
+-	entry->bound     = 0;
+-	entry->pages     = pages;
+-	entry->prev      = NULL;
+-	entry->next      = dev->agp->memory;
++	entry->handle = (unsigned long)memory->key + 1;
++	entry->memory = memory;
++	entry->bound = 0;
++	entry->pages = pages;
++	entry->prev = NULL;
++	entry->next = dev->agp->memory;
+ 	if (dev->agp->memory)
+ 		dev->agp->memory->prev = entry;
+ 	dev->agp->memory = entry;
+ 
+-	request.handle   = entry->handle;
++	request.handle = entry->handle;
+ 	request.physical = memory->physical;
+ 
+ 	if (copy_to_user(argp, &request, sizeof(request))) {
+-		dev->agp->memory       = entry->next;
++		dev->agp->memory = entry->next;
+ 		dev->agp->memory->prev = NULL;
+ 		drm_free_agp(memory, pages);
+ 		drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+@@ -263,11 +266,11 @@ int drm_agp_alloc(struct inode *inode, s
+  * \param dev DRM device structure.
+  * \param handle AGP memory handle.
+  * \return pointer to the drm_agp_mem structure associated with \p handle.
+- * 
++ *
+  * Walks through drm_agp_head::memory until finding a matching handle.
+  */
+-static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
+-					    unsigned long handle)
++static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev,
++					   unsigned long handle)
+ {
+ 	drm_agp_mem_t *entry;
+ 
+@@ -291,17 +294,18 @@ static drm_agp_mem_t *drm_agp_lookup_ent
+  * entry and passes it to the unbind_agp() function.
+  */
+ int drm_agp_unbind(struct inode *inode, struct file *filp,
+-		    unsigned int cmd, unsigned long arg)
++		   unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	  *priv	 = filp->private_data;
+-	drm_device_t	  *dev	 = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_agp_binding_t request;
+-	drm_agp_mem_t     *entry;
++	drm_agp_mem_t *entry;
+ 	int ret;
+ 
+ 	if (!dev->agp || !dev->agp->acquired)
+ 		return -EINVAL;
+-	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
++	if (copy_from_user
++	    (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
+ 		return -EFAULT;
+ 	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+ 		return -EINVAL;
+@@ -309,7 +313,7 @@ int drm_agp_unbind(struct inode *inode, 
+ 		return -EINVAL;
+ 	ret = drm_unbind_agp(entry->memory);
+ 	if (ret == 0)
+-	    entry->bound = 0;
++		entry->bound = 0;
+ 	return ret;
+ }
+ 
+@@ -327,18 +331,19 @@ int drm_agp_unbind(struct inode *inode, 
+  * it to bind_agp() function.
+  */
+ int drm_agp_bind(struct inode *inode, struct file *filp,
+-		  unsigned int cmd, unsigned long arg)
++		 unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	  *priv	 = filp->private_data;
+-	drm_device_t	  *dev	 = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_agp_binding_t request;
+-	drm_agp_mem_t     *entry;
+-	int               retcode;
+-	int               page;
++	drm_agp_mem_t *entry;
++	int retcode;
++	int page;
+ 
+ 	if (!dev->agp || !dev->agp->acquired)
+ 		return -EINVAL;
+-	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
++	if (copy_from_user
++	    (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
+ 		return -EFAULT;
+ 	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+ 		return -EINVAL;
+@@ -368,16 +373,17 @@ int drm_agp_bind(struct inode *inode, st
+  * and unlinks from the doubly linked list it's inserted in.
+  */
+ int drm_agp_free(struct inode *inode, struct file *filp,
+-		  unsigned int cmd, unsigned long arg)
++		 unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	 *priv	 = filp->private_data;
+-	drm_device_t	 *dev	 = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_agp_buffer_t request;
+-	drm_agp_mem_t    *entry;
++	drm_agp_mem_t *entry;
+ 
+ 	if (!dev->agp || !dev->agp->acquired)
+ 		return -EINVAL;
+-	if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request)))
++	if (copy_from_user
++	    (&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
+ 		return -EFAULT;
+ 	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+ 		return -EINVAL;
+@@ -403,9 +409,9 @@ int drm_agp_free(struct inode *inode, st
+  * \return pointer to a drm_agp_head structure.
+  *
+  */
+-drm_agp_head_t *drm_agp_init(drm_device_t *dev)
++drm_agp_head_t *drm_agp_init(drm_device_t * dev)
+ {
+-	drm_agp_head_t *head         = NULL;
++	drm_agp_head_t *head = NULL;
+ 
+ 	if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
+ 		return NULL;
+@@ -433,13 +439,14 @@ drm_agp_head_t *drm_agp_init(drm_device_
+ }
+ 
+ /** Calls agp_allocate_memory() */
+-DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type)
++DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data * bridge,
++				     size_t pages, u32 type)
+ {
+ 	return agp_allocate_memory(bridge, pages, type);
+ }
+ 
+ /** Calls agp_free_memory() */
+-int drm_agp_free_memory(DRM_AGP_MEM *handle)
++int drm_agp_free_memory(DRM_AGP_MEM * handle)
+ {
+ 	if (!handle)
+ 		return 0;
+@@ -448,20 +455,21 @@ int drm_agp_free_memory(DRM_AGP_MEM *han
+ }
+ 
+ /** Calls agp_bind_memory() */
+-int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start)
++int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start)
+ {
+ 	if (!handle)
+ 		return -EINVAL;
+ 	return agp_bind_memory(handle, start);
+ }
++
+ EXPORT_SYMBOL(drm_agp_bind_memory);
+ 
+ /** Calls agp_unbind_memory() */
+-int drm_agp_unbind_memory(DRM_AGP_MEM *handle)
++int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
+ {
+ 	if (!handle)
+ 		return -EINVAL;
+ 	return agp_unbind_memory(handle);
+ }
+ 
+-#endif /* __OS_HAS_AGP */
++#endif				/* __OS_HAS_AGP */
+diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c
+--- a/drivers/char/drm/drm_auth.c
++++ b/drivers/char/drm/drm_auth.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_auth.h 
++ * \file drm_auth.c
+  * IOCTLs for authentication
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+@@ -46,7 +46,7 @@
+  */
+ static int drm_hash_magic(drm_magic_t magic)
+ {
+-	return magic & (DRM_HASH_SIZE-1);
++	return magic & (DRM_HASH_SIZE - 1);
+ }
+ 
+ /**
+@@ -59,11 +59,11 @@ static int drm_hash_magic(drm_magic_t ma
+  * the one with matching magic number, while holding the drm_device::struct_sem
+  * lock.
+  */
+-static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
++static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
+ {
+-	drm_file_t	  *retval = NULL;
++	drm_file_t *retval = NULL;
+ 	drm_magic_entry_t *pt;
+-	int		  hash	  = drm_hash_magic(magic);
++	int hash = drm_hash_magic(magic);
+ 
+ 	down(&dev->struct_sem);
+ 	for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
+@@ -78,7 +78,7 @@ static drm_file_t *drm_find_file(drm_dev
+ 
+ /**
+  * Adds a magic number.
+- * 
++ *
+  * \param dev DRM device.
+  * \param priv file private data.
+  * \param magic magic number.
+@@ -87,28 +87,30 @@ static drm_file_t *drm_find_file(drm_dev
+  * associated the magic number hash key in drm_device::magiclist, while holding
+  * the drm_device::struct_sem lock.
+  */
+-static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
++static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
++			 drm_magic_t magic)
+ {
+-	int		  hash;
++	int hash;
+ 	drm_magic_entry_t *entry;
+ 
+ 	DRM_DEBUG("%d\n", magic);
+ 
+-	hash	     = drm_hash_magic(magic);
+-	entry	     = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
+-	if (!entry) return -ENOMEM;
++	hash = drm_hash_magic(magic);
++	entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
++	if (!entry)
++		return -ENOMEM;
+ 	memset(entry, 0, sizeof(*entry));
+ 	entry->magic = magic;
+-	entry->priv  = priv;
+-	entry->next  = NULL;
++	entry->priv = priv;
++	entry->next = NULL;
+ 
+ 	down(&dev->struct_sem);
+ 	if (dev->magiclist[hash].tail) {
+ 		dev->magiclist[hash].tail->next = entry;
+-		dev->magiclist[hash].tail	= entry;
++		dev->magiclist[hash].tail = entry;
+ 	} else {
+-		dev->magiclist[hash].head	= entry;
+-		dev->magiclist[hash].tail	= entry;
++		dev->magiclist[hash].head = entry;
++		dev->magiclist[hash].tail = entry;
+ 	}
+ 	up(&dev->struct_sem);
+ 
+@@ -117,19 +119,18 @@ static int drm_add_magic(drm_device_t *d
+ 
+ /**
+  * Remove a magic number.
+- * 
++ *
+  * \param dev DRM device.
+  * \param magic magic number.
+  *
+  * Searches and unlinks the entry in drm_device::magiclist with the magic
+  * number hash key, while holding the drm_device::struct_sem lock.
+  */
+-static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
++static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
+ {
+ 	drm_magic_entry_t *prev = NULL;
+ 	drm_magic_entry_t *pt;
+-	int		  hash;
+-
++	int hash;
+ 
+ 	DRM_DEBUG("%d\n", magic);
+ 	hash = drm_hash_magic(magic);
+@@ -171,21 +172,22 @@ static int drm_remove_magic(drm_device_t
+  * filp.
+  */
+ int drm_getmagic(struct inode *inode, struct file *filp,
+-		  unsigned int cmd, unsigned long arg)
++		 unsigned int cmd, unsigned long arg)
+ {
+ 	static drm_magic_t sequence = 0;
+ 	static DEFINE_SPINLOCK(lock);
+-	drm_file_t	   *priv    = filp->private_data;
+-	drm_device_t	   *dev	    = priv->head->dev;
+-	drm_auth_t	   auth;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_auth_t auth;
+ 
+-				/* Find unique magic */
++	/* Find unique magic */
+ 	if (priv->magic) {
+ 		auth.magic = priv->magic;
+ 	} else {
+ 		do {
+ 			spin_lock(&lock);
+-			if (!sequence) ++sequence; /* reserve 0 */
++			if (!sequence)
++				++sequence;	/* reserve 0 */
+ 			auth.magic = sequence++;
+ 			spin_unlock(&lock);
+ 		} while (drm_find_file(dev, auth.magic));
+@@ -194,7 +196,7 @@ int drm_getmagic(struct inode *inode, st
+ 	}
+ 
+ 	DRM_DEBUG("%u\n", auth.magic);
+-	if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
++	if (copy_to_user((drm_auth_t __user *) arg, &auth, sizeof(auth)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+@@ -211,14 +213,14 @@ int drm_getmagic(struct inode *inode, st
+  * Checks if \p filp is associated with the magic number passed in \arg.
+  */
+ int drm_authmagic(struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg)
++		  unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	   *priv    = filp->private_data;
+-	drm_device_t	   *dev	    = priv->head->dev;
+-	drm_auth_t	   auth;
+-	drm_file_t	   *file;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_auth_t auth;
++	drm_file_t *file;
+ 
+-	if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
++	if (copy_from_user(&auth, (drm_auth_t __user *) arg, sizeof(auth)))
+ 		return -EFAULT;
+ 	DRM_DEBUG("%u\n", auth.magic);
+ 	if ((file = drm_find_file(dev, auth.magic))) {
+diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
+--- a/drivers/char/drm/drm_bufs.c
++++ b/drivers/char/drm/drm_bufs.c
+@@ -1,7 +1,7 @@
+ /**
+- * \file drm_bufs.h 
++ * \file drm_bufs.c
+  * Generic buffer template
+- * 
++ *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Gareth Hughes <gareth at valinux.com>
+  */
+@@ -36,20 +36,22 @@
+ #include <linux/vmalloc.h>
+ #include "drmP.h"
+ 
+-unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
++unsigned long drm_get_resource_start(drm_device_t * dev, unsigned int resource)
+ {
+ 	return pci_resource_start(dev->pdev, resource);
+ }
++
+ EXPORT_SYMBOL(drm_get_resource_start);
+ 
+-unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
++unsigned long drm_get_resource_len(drm_device_t * dev, unsigned int resource)
+ {
+ 	return pci_resource_len(dev->pdev, resource);
+ }
++
+ EXPORT_SYMBOL(drm_get_resource_len);
+ 
+-static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
+-					     drm_local_map_t *map)
++static drm_map_list_t *drm_find_matching_map(drm_device_t * dev,
++					     drm_local_map_t * map)
+ {
+ 	struct list_head *list;
+ 
+@@ -71,7 +73,8 @@ static drm_map_list_t *drm_find_matching
+ #define END_RANGE 0x40000000
+ 
+ #ifdef _LP64
+-static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev) 
++static __inline__ unsigned int HandleID(unsigned long lhandle,
++					drm_device_t * dev)
+ {
+ 	static unsigned int map32_handle = START_RANGE;
+ 	unsigned int hash;
+@@ -81,12 +84,12 @@ static __inline__ unsigned int HandleID(
+ 		map32_handle += PAGE_SIZE;
+ 		if (map32_handle > END_RANGE)
+ 			map32_handle = START_RANGE;
+-	} else 
++	} else
+ 		hash = lhandle;
+ 
+ 	while (1) {
+ 		drm_map_list_t *_entry;
+-		list_for_each_entry(_entry, &dev->maplist->head,head) {
++		list_for_each_entry(_entry, &dev->maplist->head, head) {
+ 			if (_entry->user_token == hash)
+ 				break;
+ 		}
+@@ -114,16 +117,16 @@ static __inline__ unsigned int HandleID(
+  * type.  Adds the map to the map list drm_device::maplist. Adds MTRR's where
+  * applicable and if supported by the kernel.
+  */
+-int drm_addmap_core(drm_device_t * dev, unsigned int offset,
+-		    unsigned int size, drm_map_type_t type,
+-		    drm_map_flags_t flags, drm_map_list_t **maplist)
++static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
++			   unsigned int size, drm_map_type_t type,
++			   drm_map_flags_t flags, drm_map_list_t ** maplist)
+ {
+ 	drm_map_t *map;
+ 	drm_map_list_t *list;
+ 	drm_dma_handle_t *dmah;
+ 
+-	map = drm_alloc( sizeof(*map), DRM_MEM_MAPS );
+-	if ( !map )
++	map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
++	if (!map)
+ 		return -ENOMEM;
+ 
+ 	map->offset = offset;
+@@ -135,26 +138,26 @@ int drm_addmap_core(drm_device_t * dev, 
+ 	 * book keeping information about shared memory to allow for removal
+ 	 * when processes fork.
+ 	 */
+-	if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) {
+-		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
++	if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) {
++		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ 		return -EINVAL;
+ 	}
+-	DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n",
+-		   map->offset, map->size, map->type );
+-	if ( (map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK)) ) {
+-		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
++	DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n",
++		  map->offset, map->size, map->type);
++	if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
++		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ 		return -EINVAL;
+ 	}
+-	map->mtrr   = -1;
++	map->mtrr = -1;
+ 	map->handle = NULL;
+ 
+-	switch ( map->type ) {
++	switch (map->type) {
+ 	case _DRM_REGISTERS:
+ 	case _DRM_FRAME_BUFFER:
+ #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__)
+-		if ( map->offset + map->size < map->offset ||
+-		     map->offset < virt_to_phys(high_memory) ) {
+-			drm_free( map, sizeof(*map), DRM_MEM_MAPS );
++		if (map->offset + map->size < map->offset ||
++		    map->offset < virt_to_phys(high_memory)) {
++			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ 			return -EINVAL;
+ 		}
+ #endif
+@@ -169,8 +172,9 @@ int drm_addmap_core(drm_device_t * dev, 
+ 		if (list != NULL) {
+ 			if (list->map->size != map->size) {
+ 				DRM_DEBUG("Matching maps of type %d with "
+-				   "mismatched sizes, (%ld vs %ld)\n",
+-				    map->type, map->size, list->map->size);
++					  "mismatched sizes, (%ld vs %ld)\n",
++					  map->type, map->size,
++					  list->map->size);
+ 				list->map->size = map->size;
+ 			}
+ 
+@@ -180,35 +184,33 @@ int drm_addmap_core(drm_device_t * dev, 
+ 		}
+ 
+ 		if (drm_core_has_MTRR(dev)) {
+-			if ( map->type == _DRM_FRAME_BUFFER ||
+-			     (map->flags & _DRM_WRITE_COMBINING) ) {
+-				map->mtrr = mtrr_add( map->offset, map->size,
+-						      MTRR_TYPE_WRCOMB, 1 );
++			if (map->type == _DRM_FRAME_BUFFER ||
++			    (map->flags & _DRM_WRITE_COMBINING)) {
++				map->mtrr = mtrr_add(map->offset, map->size,
++						     MTRR_TYPE_WRCOMB, 1);
+ 			}
+ 		}
+ 		if (map->type == _DRM_REGISTERS)
+-			map->handle = drm_ioremap( map->offset, map->size,
+-						    dev );
++			map->handle = drm_ioremap(map->offset, map->size, dev);
+ 		break;
+ 
+ 	case _DRM_SHM:
+ 		map->handle = vmalloc_32(map->size);
+-		DRM_DEBUG( "%lu %d %p\n",
+-			   map->size, drm_order( map->size ), map->handle );
+-		if ( !map->handle ) {
+-			drm_free( map, sizeof(*map), DRM_MEM_MAPS );
++		DRM_DEBUG("%lu %d %p\n",
++			  map->size, drm_order(map->size), map->handle);
++		if (!map->handle) {
++			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ 			return -ENOMEM;
+ 		}
+ 		map->offset = (unsigned long)map->handle;
+-		if ( map->flags & _DRM_CONTAINS_LOCK ) {
++		if (map->flags & _DRM_CONTAINS_LOCK) {
+ 			/* Prevent a 2nd X Server from creating a 2nd lock */
+ 			if (dev->lock.hw_lock != NULL) {
+-				vfree( map->handle );
+-				drm_free( map, sizeof(*map), DRM_MEM_MAPS );
++				vfree(map->handle);
++				drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ 				return -EBUSY;
+ 			}
+-			dev->sigdata.lock =
+-			dev->lock.hw_lock = map->handle; /* Pointer to lock */
++			dev->sigdata.lock = dev->lock.hw_lock = map->handle;	/* Pointer to lock */
+ 		}
+ 		break;
+ 	case _DRM_AGP:
+@@ -217,7 +219,7 @@ int drm_addmap_core(drm_device_t * dev, 
+ 			map->offset += dev->hose->mem_space->start;
+ #endif
+ 			map->offset += dev->agp->base;
+-			map->mtrr   = dev->agp->agp_mtrr; /* for getmap */
++			map->mtrr = dev->agp->agp_mtrr;	/* for getmap */
+ 		}
+ 		break;
+ 	case _DRM_SCATTER_GATHER:
+@@ -227,7 +229,7 @@ int drm_addmap_core(drm_device_t * dev, 
+ 		}
+ 		map->offset += (unsigned long)dev->sg->virtual;
+ 		break;
+-	case _DRM_CONSISTENT: 
++	case _DRM_CONSISTENT:
+ 		/* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
+ 		 * As we're limiting the address to 2^32-1 (or less),
+ 		 * casting it down to 32 bits is no problem, but we
+@@ -242,12 +244,12 @@ int drm_addmap_core(drm_device_t * dev, 
+ 		kfree(dmah);
+ 		break;
+ 	default:
+-		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
++		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ 		return -EINVAL;
+ 	}
+ 
+ 	list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
+-	if(!list) {
++	if (!list) {
+ 		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ 		return -EINVAL;
+ 	}
+@@ -258,18 +260,18 @@ int drm_addmap_core(drm_device_t * dev, 
+ 	list_add(&list->head, &dev->maplist->head);
+ 	/* Assign a 32-bit handle */
+ 	/* We do it here so that dev->struct_sem protects the increment */
+-	list->user_token = HandleID(map->type==_DRM_SHM
++	list->user_token = HandleID(map->type == _DRM_SHM
+ 				    ? (unsigned long)map->handle
+ 				    : map->offset, dev);
+- 	up(&dev->struct_sem);
++	up(&dev->struct_sem);
+ 
+ 	*maplist = list;
+ 	return 0;
+ }
+ 
+-int drm_addmap(drm_device_t *dev, unsigned int offset,
++int drm_addmap(drm_device_t * dev, unsigned int offset,
+ 	       unsigned int size, drm_map_type_t type,
+-	       drm_map_flags_t flags, drm_local_map_t **map_ptr)
++	       drm_map_flags_t flags, drm_local_map_t ** map_ptr)
+ {
+ 	drm_map_list_t *list;
+ 	int rc;
+@@ -279,6 +281,7 @@ int drm_addmap(drm_device_t *dev, unsign
+ 		*map_ptr = list->map;
+ 	return rc;
+ }
++
+ EXPORT_SYMBOL(drm_addmap);
+ 
+ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
+@@ -294,24 +297,25 @@ int drm_addmap_ioctl(struct inode *inode
+ 	if (!(filp->f_mode & 3))
+ 		return -EACCES;	/* Require read/write */
+ 
+-	if (copy_from_user(& map, argp, sizeof(map))) {
++	if (copy_from_user(&map, argp, sizeof(map))) {
+ 		return -EFAULT;
+ 	}
+ 
+ 	err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
+ 			      &maplist);
+ 
+-	if (err) 
++	if (err)
+ 		return err;
+ 
+ 	if (copy_to_user(argp, maplist->map, sizeof(drm_map_t)))
+ 		return -EFAULT;
+-	if (put_user(maplist->user_token, &argp->handle))
++
++	/* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */
++	if (put_user((void *)(unsigned long)maplist->user_token, &argp->handle))
+ 		return -EFAULT;
+ 	return 0;
+ }
+ 
+-
+ /**
+  * Remove a map private from list and deallocate resources if the mapping
+  * isn't in use.
+@@ -328,7 +332,7 @@ int drm_addmap_ioctl(struct inode *inode
+  *
+  * \sa drm_addmap
+  */
+-int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
++int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map)
+ {
+ 	struct list_head *list;
+ 	drm_map_list_t *r_list = NULL;
+@@ -359,9 +363,8 @@ int drm_rmmap_locked(drm_device_t *dev, 
+ 	case _DRM_FRAME_BUFFER:
+ 		if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
+ 			int retcode;
+-			retcode = mtrr_del(map->mtrr, map->offset,
+-					   map->size);
+-			DRM_DEBUG ("mtrr_del=%d\n", retcode);
++			retcode = mtrr_del(map->mtrr, map->offset, map->size);
++			DRM_DEBUG("mtrr_del=%d\n", retcode);
+ 		}
+ 		break;
+ 	case _DRM_SHM:
+@@ -381,9 +384,10 @@ int drm_rmmap_locked(drm_device_t *dev, 
+ 
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_rmmap_locked);
+ 
+-int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
++int drm_rmmap(drm_device_t * dev, drm_local_map_t * map)
+ {
+ 	int ret;
+ 
+@@ -393,6 +397,7 @@ int drm_rmmap(drm_device_t *dev, drm_loc
+ 
+ 	return ret;
+ }
++
+ EXPORT_SYMBOL(drm_rmmap);
+ 
+ /* The rmmap ioctl appears to be unnecessary.  All mappings are torn down on
+@@ -414,7 +419,7 @@ int drm_rmmap_ioctl(struct inode *inode,
+ 	struct list_head *list;
+ 	int ret;
+ 
+-	if (copy_from_user(&request, (drm_map_t __user *)arg, sizeof(request))) {
++	if (copy_from_user(&request, (drm_map_t __user *) arg, sizeof(request))) {
+ 		return -EFAULT;
+ 	}
+ 
+@@ -423,7 +428,7 @@ int drm_rmmap_ioctl(struct inode *inode,
+ 		drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
+ 
+ 		if (r_list->map &&
+-		    r_list->user_token == (unsigned long) request.handle &&
++		    r_list->user_token == (unsigned long)request.handle &&
+ 		    r_list->map->flags & _DRM_REMOVABLE) {
+ 			map = r_list->map;
+ 			break;
+@@ -462,7 +467,7 @@ int drm_rmmap_ioctl(struct inode *inode,
+  *
+  * Frees any pages and buffers associated with the given entry.
+  */
+-static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry)
++static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry)
+ {
+ 	int i;
+ 
+@@ -470,30 +475,27 @@ static void drm_cleanup_buf_error(drm_de
+ 		for (i = 0; i < entry->seg_count; i++) {
+ 			if (entry->seglist[i]) {
+ 				drm_free_pages(entry->seglist[i],
+-					        entry->page_order,
+-					        DRM_MEM_DMA);
++					       entry->page_order, DRM_MEM_DMA);
+ 			}
+ 		}
+ 		drm_free(entry->seglist,
+-			  entry->seg_count *
+-			  sizeof(*entry->seglist),
+-			  DRM_MEM_SEGS);
++			 entry->seg_count *
++			 sizeof(*entry->seglist), DRM_MEM_SEGS);
+ 
+ 		entry->seg_count = 0;
+ 	}
+ 
+-   	if (entry->buf_count) {
+-	   	for (i = 0; i < entry->buf_count; i++) {
++	if (entry->buf_count) {
++		for (i = 0; i < entry->buf_count; i++) {
+ 			if (entry->buflist[i].dev_private) {
+ 				drm_free(entry->buflist[i].dev_private,
+-					  entry->buflist[i].dev_priv_size,
+-					  DRM_MEM_BUFS);
++					 entry->buflist[i].dev_priv_size,
++					 DRM_MEM_BUFS);
+ 			}
+ 		}
+ 		drm_free(entry->buflist,
+-			  entry->buf_count *
+-			  sizeof(*entry->buflist),
+-			  DRM_MEM_BUFS);
++			 entry->buf_count *
++			 sizeof(*entry->buflist), DRM_MEM_BUFS);
+ 
+ 		entry->buf_count = 0;
+ 	}
+@@ -506,12 +508,12 @@ static void drm_cleanup_buf_error(drm_de
+  * \param dev drm_device_t to which the buffers are to be added.
+  * \param request pointer to a drm_buf_desc_t describing the request.
+  * \return zero on success or a negative number on failure.
+- * 
++ *
+  * After some sanity checks creates a drm_buf structure for each buffer and
+  * reallocates the buffer list of the same size order to accommodate the new
+  * buffers.
+  */
+-int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
++int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_buf_entry_t *entry;
+@@ -528,144 +530,145 @@ int drm_addbufs_agp(drm_device_t *dev, d
+ 	int i;
+ 	drm_buf_t **temp_buflist;
+ 
+-	if ( !dma ) return -EINVAL;
++	if (!dma)
++		return -EINVAL;
+ 
+ 	count = request->count;
+ 	order = drm_order(request->size);
+ 	size = 1 << order;
+ 
+-	alignment  = (request->flags & _DRM_PAGE_ALIGN)
+-		? PAGE_ALIGN(size) : size;
++	alignment = (request->flags & _DRM_PAGE_ALIGN)
++	    ? PAGE_ALIGN(size) : size;
+ 	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ 	total = PAGE_SIZE << page_order;
+ 
+ 	byte_count = 0;
+ 	agp_offset = dev->agp->base + request->agp_start;
+ 
+-	DRM_DEBUG( "count:      %d\n",  count );
+-	DRM_DEBUG( "order:      %d\n",  order );
+-	DRM_DEBUG( "size:       %d\n",  size );
+-	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
+-	DRM_DEBUG( "alignment:  %d\n",  alignment );
+-	DRM_DEBUG( "page_order: %d\n",  page_order );
+-	DRM_DEBUG( "total:      %d\n",  total );
+-
+-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+-	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+-
+-	spin_lock( &dev->count_lock );
+-	if ( dev->buf_use ) {
+-		spin_unlock( &dev->count_lock );
++	DRM_DEBUG("count:      %d\n", count);
++	DRM_DEBUG("order:      %d\n", order);
++	DRM_DEBUG("size:       %d\n", size);
++	DRM_DEBUG("agp_offset: %lu\n", agp_offset);
++	DRM_DEBUG("alignment:  %d\n", alignment);
++	DRM_DEBUG("page_order: %d\n", page_order);
++	DRM_DEBUG("total:      %d\n", total);
++
++	if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
++		return -EINVAL;
++	if (dev->queue_count)
++		return -EBUSY;	/* Not while in use */
++
++	spin_lock(&dev->count_lock);
++	if (dev->buf_use) {
++		spin_unlock(&dev->count_lock);
+ 		return -EBUSY;
+ 	}
+-	atomic_inc( &dev->buf_alloc );
+-	spin_unlock( &dev->count_lock );
++	atomic_inc(&dev->buf_alloc);
++	spin_unlock(&dev->count_lock);
+ 
+-	down( &dev->struct_sem );
++	down(&dev->struct_sem);
+ 	entry = &dma->bufs[order];
+-	if ( entry->buf_count ) {
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
+-		return -ENOMEM; /* May only call once for each order */
++	if (entry->buf_count) {
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
++		return -ENOMEM;	/* May only call once for each order */
+ 	}
+ 
+ 	if (count < 0 || count > 4096) {
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -EINVAL;
+ 	}
+ 
+-	entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
+-				    DRM_MEM_BUFS );
+-	if ( !entry->buflist ) {
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++	entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
++				   DRM_MEM_BUFS);
++	if (!entry->buflist) {
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -ENOMEM;
+ 	}
+-	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
++	memset(entry->buflist, 0, count * sizeof(*entry->buflist));
+ 
+ 	entry->buf_size = size;
+ 	entry->page_order = page_order;
+ 
+ 	offset = 0;
+ 
+-	while ( entry->buf_count < count ) {
+-		buf          = &entry->buflist[entry->buf_count];
+-		buf->idx     = dma->buf_count + entry->buf_count;
+-		buf->total   = alignment;
+-		buf->order   = order;
+-		buf->used    = 0;
++	while (entry->buf_count < count) {
++		buf = &entry->buflist[entry->buf_count];
++		buf->idx = dma->buf_count + entry->buf_count;
++		buf->total = alignment;
++		buf->order = order;
++		buf->used = 0;
+ 
+-		buf->offset  = (dma->byte_count + offset);
++		buf->offset = (dma->byte_count + offset);
+ 		buf->bus_address = agp_offset + offset;
+ 		buf->address = (void *)(agp_offset + offset);
+-		buf->next    = NULL;
++		buf->next = NULL;
+ 		buf->waiting = 0;
+ 		buf->pending = 0;
+-		init_waitqueue_head( &buf->dma_wait );
+-		buf->filp    = NULL;
++		init_waitqueue_head(&buf->dma_wait);
++		buf->filp = NULL;
+ 
+ 		buf->dev_priv_size = dev->driver->dev_priv_size;
+-		buf->dev_private = drm_alloc( buf->dev_priv_size,
+-					       DRM_MEM_BUFS );
+-		if(!buf->dev_private) {
++		buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
++		if (!buf->dev_private) {
+ 			/* Set count correctly so we free the proper amount. */
+ 			entry->buf_count = count;
+-			drm_cleanup_buf_error(dev,entry);
+-			up( &dev->struct_sem );
+-			atomic_dec( &dev->buf_alloc );
++			drm_cleanup_buf_error(dev, entry);
++			up(&dev->struct_sem);
++			atomic_dec(&dev->buf_alloc);
+ 			return -ENOMEM;
+ 		}
+-		memset( buf->dev_private, 0, buf->dev_priv_size );
++		memset(buf->dev_private, 0, buf->dev_priv_size);
+ 
+-		DRM_DEBUG( "buffer %d @ %p\n",
+-			   entry->buf_count, buf->address );
++		DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
+ 
+ 		offset += alignment;
+ 		entry->buf_count++;
+ 		byte_count += PAGE_SIZE << page_order;
+ 	}
+ 
+-	DRM_DEBUG( "byte_count: %d\n", byte_count );
++	DRM_DEBUG("byte_count: %d\n", byte_count);
+ 
+-	temp_buflist = drm_realloc( dma->buflist,
+-				     dma->buf_count * sizeof(*dma->buflist),
+-				     (dma->buf_count + entry->buf_count)
+-				     * sizeof(*dma->buflist),
+-				     DRM_MEM_BUFS );
+-	if(!temp_buflist) {
++	temp_buflist = drm_realloc(dma->buflist,
++				   dma->buf_count * sizeof(*dma->buflist),
++				   (dma->buf_count + entry->buf_count)
++				   * sizeof(*dma->buflist), DRM_MEM_BUFS);
++	if (!temp_buflist) {
+ 		/* Free the entry because it isn't valid */
+-		drm_cleanup_buf_error(dev,entry);
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++		drm_cleanup_buf_error(dev, entry);
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -ENOMEM;
+ 	}
+ 	dma->buflist = temp_buflist;
+ 
+-	for ( i = 0 ; i < entry->buf_count ; i++ ) {
++	for (i = 0; i < entry->buf_count; i++) {
+ 		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+ 	}
+ 
+ 	dma->buf_count += entry->buf_count;
+ 	dma->byte_count += byte_count;
+ 
+-	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
+-	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
++	DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
++	DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
+ 
+-	up( &dev->struct_sem );
++	up(&dev->struct_sem);
+ 
+ 	request->count = entry->buf_count;
+ 	request->size = size;
+ 
+ 	dma->flags = _DRM_DMA_USE_AGP;
+ 
+-	atomic_dec( &dev->buf_alloc );
++	atomic_dec(&dev->buf_alloc);
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_addbufs_agp);
+-#endif /* __OS_HAS_AGP */
++#endif				/* __OS_HAS_AGP */
+ 
+-int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
++int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	int count;
+@@ -684,178 +687,174 @@ int drm_addbufs_pci(drm_device_t *dev, d
+ 	unsigned long *temp_pagelist;
+ 	drm_buf_t **temp_buflist;
+ 
+-	if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL;
+-	if ( !dma ) return -EINVAL;
++	if (!drm_core_check_feature(dev, DRIVER_PCI_DMA))
++		return -EINVAL;
++	if (!dma)
++		return -EINVAL;
+ 
+ 	count = request->count;
+ 	order = drm_order(request->size);
+ 	size = 1 << order;
+ 
+-	DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n",
+-		   request->count, request->size, size,
+-		   order, dev->queue_count );
++	DRM_DEBUG("count=%d, size=%d (%d), order=%d, queue_count=%d\n",
++		  request->count, request->size, size, order, dev->queue_count);
+ 
+-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+-	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
++	if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
++		return -EINVAL;
++	if (dev->queue_count)
++		return -EBUSY;	/* Not while in use */
+ 
+ 	alignment = (request->flags & _DRM_PAGE_ALIGN)
+-		? PAGE_ALIGN(size) : size;
++	    ? PAGE_ALIGN(size) : size;
+ 	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ 	total = PAGE_SIZE << page_order;
+ 
+-	spin_lock( &dev->count_lock );
+-	if ( dev->buf_use ) {
+-		spin_unlock( &dev->count_lock );
++	spin_lock(&dev->count_lock);
++	if (dev->buf_use) {
++		spin_unlock(&dev->count_lock);
+ 		return -EBUSY;
+ 	}
+-	atomic_inc( &dev->buf_alloc );
+-	spin_unlock( &dev->count_lock );
++	atomic_inc(&dev->buf_alloc);
++	spin_unlock(&dev->count_lock);
+ 
+-	down( &dev->struct_sem );
++	down(&dev->struct_sem);
+ 	entry = &dma->bufs[order];
+-	if ( entry->buf_count ) {
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++	if (entry->buf_count) {
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -ENOMEM;	/* May only call once for each order */
+ 	}
+ 
+ 	if (count < 0 || count > 4096) {
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -EINVAL;
+ 	}
+ 
+-	entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
+-				    DRM_MEM_BUFS );
+-	if ( !entry->buflist ) {
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++	entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
++				   DRM_MEM_BUFS);
++	if (!entry->buflist) {
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -ENOMEM;
+ 	}
+-	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
++	memset(entry->buflist, 0, count * sizeof(*entry->buflist));
+ 
+-	entry->seglist = drm_alloc( count * sizeof(*entry->seglist),
+-				    DRM_MEM_SEGS );
+-	if ( !entry->seglist ) {
+-		drm_free( entry->buflist,
+-			  count * sizeof(*entry->buflist),
+-			  DRM_MEM_BUFS );
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++	entry->seglist = drm_alloc(count * sizeof(*entry->seglist),
++				   DRM_MEM_SEGS);
++	if (!entry->seglist) {
++		drm_free(entry->buflist,
++			 count * sizeof(*entry->buflist), DRM_MEM_BUFS);
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -ENOMEM;
+ 	}
+-	memset( entry->seglist, 0, count * sizeof(*entry->seglist) );
++	memset(entry->seglist, 0, count * sizeof(*entry->seglist));
+ 
+ 	/* Keep the original pagelist until we know all the allocations
+ 	 * have succeeded
+ 	 */
+-	temp_pagelist = drm_alloc( (dma->page_count + (count << page_order))
+-				    * sizeof(*dma->pagelist),
+-				    DRM_MEM_PAGES );
++	temp_pagelist = drm_alloc((dma->page_count + (count << page_order))
++				  * sizeof(*dma->pagelist), DRM_MEM_PAGES);
+ 	if (!temp_pagelist) {
+-		drm_free( entry->buflist,
+-			   count * sizeof(*entry->buflist),
+-			   DRM_MEM_BUFS );
+-		drm_free( entry->seglist,
+-			   count * sizeof(*entry->seglist),
+-			   DRM_MEM_SEGS );
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++		drm_free(entry->buflist,
++			 count * sizeof(*entry->buflist), DRM_MEM_BUFS);
++		drm_free(entry->seglist,
++			 count * sizeof(*entry->seglist), DRM_MEM_SEGS);
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -ENOMEM;
+ 	}
+ 	memcpy(temp_pagelist,
+-	       dma->pagelist,
+-	       dma->page_count * sizeof(*dma->pagelist));
+-	DRM_DEBUG( "pagelist: %d entries\n",
+-		   dma->page_count + (count << page_order) );
++	       dma->pagelist, dma->page_count * sizeof(*dma->pagelist));
++	DRM_DEBUG("pagelist: %d entries\n",
++		  dma->page_count + (count << page_order));
+ 
+-	entry->buf_size	= size;
++	entry->buf_size = size;
+ 	entry->page_order = page_order;
+ 	byte_count = 0;
+ 	page_count = 0;
+ 
+-	while ( entry->buf_count < count ) {
+-		page = drm_alloc_pages( page_order, DRM_MEM_DMA );
+-		if ( !page ) {
++	while (entry->buf_count < count) {
++		page = drm_alloc_pages(page_order, DRM_MEM_DMA);
++		if (!page) {
+ 			/* Set count correctly so we free the proper amount. */
+ 			entry->buf_count = count;
+ 			entry->seg_count = count;
+ 			drm_cleanup_buf_error(dev, entry);
+-			drm_free( temp_pagelist,
+-				   (dma->page_count + (count << page_order))
+-				   * sizeof(*dma->pagelist),
+-				   DRM_MEM_PAGES );
+-			up( &dev->struct_sem );
+-			atomic_dec( &dev->buf_alloc );
++			drm_free(temp_pagelist,
++				 (dma->page_count + (count << page_order))
++				 * sizeof(*dma->pagelist), DRM_MEM_PAGES);
++			up(&dev->struct_sem);
++			atomic_dec(&dev->buf_alloc);
+ 			return -ENOMEM;
+ 		}
+ 		entry->seglist[entry->seg_count++] = page;
+-		for ( i = 0 ; i < (1 << page_order) ; i++ ) {
+-			DRM_DEBUG( "page %d @ 0x%08lx\n",
+-				   dma->page_count + page_count,
+-				   page + PAGE_SIZE * i );
++		for (i = 0; i < (1 << page_order); i++) {
++			DRM_DEBUG("page %d @ 0x%08lx\n",
++				  dma->page_count + page_count,
++				  page + PAGE_SIZE * i);
+ 			temp_pagelist[dma->page_count + page_count++]
+-				= page + PAGE_SIZE * i;
++			    = page + PAGE_SIZE * i;
+ 		}
+-		for ( offset = 0 ;
+-		      offset + size <= total && entry->buf_count < count ;
+-		      offset += alignment, ++entry->buf_count ) {
+-			buf	     = &entry->buflist[entry->buf_count];
+-			buf->idx     = dma->buf_count + entry->buf_count;
+-			buf->total   = alignment;
+-			buf->order   = order;
+-			buf->used    = 0;
+-			buf->offset  = (dma->byte_count + byte_count + offset);
++		for (offset = 0;
++		     offset + size <= total && entry->buf_count < count;
++		     offset += alignment, ++entry->buf_count) {
++			buf = &entry->buflist[entry->buf_count];
++			buf->idx = dma->buf_count + entry->buf_count;
++			buf->total = alignment;
++			buf->order = order;
++			buf->used = 0;
++			buf->offset = (dma->byte_count + byte_count + offset);
+ 			buf->address = (void *)(page + offset);
+-			buf->next    = NULL;
++			buf->next = NULL;
+ 			buf->waiting = 0;
+ 			buf->pending = 0;
+-			init_waitqueue_head( &buf->dma_wait );
+-			buf->filp    = NULL;
++			init_waitqueue_head(&buf->dma_wait);
++			buf->filp = NULL;
+ 
+ 			buf->dev_priv_size = dev->driver->dev_priv_size;
+-			buf->dev_private = drm_alloc( buf->dev_priv_size,
+-						       DRM_MEM_BUFS );
+-			if(!buf->dev_private) {
++			buf->dev_private = drm_alloc(buf->dev_priv_size,
++						     DRM_MEM_BUFS);
++			if (!buf->dev_private) {
+ 				/* Set count correctly so we free the proper amount. */
+ 				entry->buf_count = count;
+ 				entry->seg_count = count;
+-				drm_cleanup_buf_error(dev,entry);
+-				drm_free( temp_pagelist,
+-					   (dma->page_count + (count << page_order))
+-					   * sizeof(*dma->pagelist),
+-					   DRM_MEM_PAGES );
+-				up( &dev->struct_sem );
+-				atomic_dec( &dev->buf_alloc );
++				drm_cleanup_buf_error(dev, entry);
++				drm_free(temp_pagelist,
++					 (dma->page_count +
++					  (count << page_order))
++					 * sizeof(*dma->pagelist),
++					 DRM_MEM_PAGES);
++				up(&dev->struct_sem);
++				atomic_dec(&dev->buf_alloc);
+ 				return -ENOMEM;
+ 			}
+-			memset( buf->dev_private, 0, buf->dev_priv_size );
++			memset(buf->dev_private, 0, buf->dev_priv_size);
+ 
+-			DRM_DEBUG( "buffer %d @ %p\n",
+-				   entry->buf_count, buf->address );
++			DRM_DEBUG("buffer %d @ %p\n",
++				  entry->buf_count, buf->address);
+ 		}
+ 		byte_count += PAGE_SIZE << page_order;
+ 	}
+ 
+-	temp_buflist = drm_realloc( dma->buflist,
+-				     dma->buf_count * sizeof(*dma->buflist),
+-				     (dma->buf_count + entry->buf_count)
+-				     * sizeof(*dma->buflist),
+-				     DRM_MEM_BUFS );
++	temp_buflist = drm_realloc(dma->buflist,
++				   dma->buf_count * sizeof(*dma->buflist),
++				   (dma->buf_count + entry->buf_count)
++				   * sizeof(*dma->buflist), DRM_MEM_BUFS);
+ 	if (!temp_buflist) {
+ 		/* Free the entry because it isn't valid */
+-		drm_cleanup_buf_error(dev,entry);
+-		drm_free( temp_pagelist,
+-			   (dma->page_count + (count << page_order))
+-			   * sizeof(*dma->pagelist),
+-			   DRM_MEM_PAGES );
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++		drm_cleanup_buf_error(dev, entry);
++		drm_free(temp_pagelist,
++			 (dma->page_count + (count << page_order))
++			 * sizeof(*dma->pagelist), DRM_MEM_PAGES);
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -ENOMEM;
+ 	}
+ 	dma->buflist = temp_buflist;
+ 
+-	for ( i = 0 ; i < entry->buf_count ; i++ ) {
++	for (i = 0; i < entry->buf_count; i++) {
+ 		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+ 	}
+ 
+@@ -864,8 +863,8 @@ int drm_addbufs_pci(drm_device_t *dev, d
+ 	 */
+ 	if (dma->page_count) {
+ 		drm_free(dma->pagelist,
+-			  dma->page_count * sizeof(*dma->pagelist),
+-			  DRM_MEM_PAGES);
++			 dma->page_count * sizeof(*dma->pagelist),
++			 DRM_MEM_PAGES);
+ 	}
+ 	dma->pagelist = temp_pagelist;
+ 
+@@ -874,18 +873,19 @@ int drm_addbufs_pci(drm_device_t *dev, d
+ 	dma->page_count += entry->seg_count << page_order;
+ 	dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
+ 
+-	up( &dev->struct_sem );
++	up(&dev->struct_sem);
+ 
+ 	request->count = entry->buf_count;
+ 	request->size = size;
+ 
+-	atomic_dec( &dev->buf_alloc );
++	atomic_dec(&dev->buf_alloc);
+ 	return 0;
+ 
+ }
++
+ EXPORT_SYMBOL(drm_addbufs_pci);
+ 
+-static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
++static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_buf_entry_t *entry;
+@@ -902,146 +902,147 @@ static int drm_addbufs_sg(drm_device_t *
+ 	int i;
+ 	drm_buf_t **temp_buflist;
+ 
+-	if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL;
+-	
+-	if ( !dma ) return -EINVAL;
++	if (!drm_core_check_feature(dev, DRIVER_SG))
++		return -EINVAL;
++
++	if (!dma)
++		return -EINVAL;
+ 
+ 	count = request->count;
+ 	order = drm_order(request->size);
+ 	size = 1 << order;
+ 
+-	alignment  = (request->flags & _DRM_PAGE_ALIGN)
+-			? PAGE_ALIGN(size) : size;
++	alignment = (request->flags & _DRM_PAGE_ALIGN)
++	    ? PAGE_ALIGN(size) : size;
+ 	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ 	total = PAGE_SIZE << page_order;
+ 
+ 	byte_count = 0;
+ 	agp_offset = request->agp_start;
+ 
+-	DRM_DEBUG( "count:      %d\n",  count );
+-	DRM_DEBUG( "order:      %d\n",  order );
+-	DRM_DEBUG( "size:       %d\n",  size );
+-	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
+-	DRM_DEBUG( "alignment:  %d\n",  alignment );
+-	DRM_DEBUG( "page_order: %d\n",  page_order );
+-	DRM_DEBUG( "total:      %d\n",  total );
+-
+-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+-	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+-
+-	spin_lock( &dev->count_lock );
+-	if ( dev->buf_use ) {
+-		spin_unlock( &dev->count_lock );
++	DRM_DEBUG("count:      %d\n", count);
++	DRM_DEBUG("order:      %d\n", order);
++	DRM_DEBUG("size:       %d\n", size);
++	DRM_DEBUG("agp_offset: %lu\n", agp_offset);
++	DRM_DEBUG("alignment:  %d\n", alignment);
++	DRM_DEBUG("page_order: %d\n", page_order);
++	DRM_DEBUG("total:      %d\n", total);
++
++	if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
++		return -EINVAL;
++	if (dev->queue_count)
++		return -EBUSY;	/* Not while in use */
++
++	spin_lock(&dev->count_lock);
++	if (dev->buf_use) {
++		spin_unlock(&dev->count_lock);
+ 		return -EBUSY;
+ 	}
+-	atomic_inc( &dev->buf_alloc );
+-	spin_unlock( &dev->count_lock );
++	atomic_inc(&dev->buf_alloc);
++	spin_unlock(&dev->count_lock);
+ 
+-	down( &dev->struct_sem );
++	down(&dev->struct_sem);
+ 	entry = &dma->bufs[order];
+-	if ( entry->buf_count ) {
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
+-		return -ENOMEM; /* May only call once for each order */
++	if (entry->buf_count) {
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
++		return -ENOMEM;	/* May only call once for each order */
+ 	}
+ 
+ 	if (count < 0 || count > 4096) {
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -EINVAL;
+ 	}
+ 
+-	entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
+-				     DRM_MEM_BUFS );
+-	if ( !entry->buflist ) {
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++	entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
++				   DRM_MEM_BUFS);
++	if (!entry->buflist) {
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -ENOMEM;
+ 	}
+-	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
++	memset(entry->buflist, 0, count * sizeof(*entry->buflist));
+ 
+ 	entry->buf_size = size;
+ 	entry->page_order = page_order;
+ 
+ 	offset = 0;
+ 
+-	while ( entry->buf_count < count ) {
+-		buf          = &entry->buflist[entry->buf_count];
+-		buf->idx     = dma->buf_count + entry->buf_count;
+-		buf->total   = alignment;
+-		buf->order   = order;
+-		buf->used    = 0;
++	while (entry->buf_count < count) {
++		buf = &entry->buflist[entry->buf_count];
++		buf->idx = dma->buf_count + entry->buf_count;
++		buf->total = alignment;
++		buf->order = order;
++		buf->used = 0;
+ 
+-		buf->offset  = (dma->byte_count + offset);
++		buf->offset = (dma->byte_count + offset);
+ 		buf->bus_address = agp_offset + offset;
+-		buf->address = (void *)(agp_offset + offset 
++		buf->address = (void *)(agp_offset + offset
+ 					+ (unsigned long)dev->sg->virtual);
+-		buf->next    = NULL;
++		buf->next = NULL;
+ 		buf->waiting = 0;
+ 		buf->pending = 0;
+-		init_waitqueue_head( &buf->dma_wait );
+-		buf->filp    = NULL;
++		init_waitqueue_head(&buf->dma_wait);
++		buf->filp = NULL;
+ 
+ 		buf->dev_priv_size = dev->driver->dev_priv_size;
+-		buf->dev_private = drm_alloc( buf->dev_priv_size,
+-					       DRM_MEM_BUFS );
+-		if(!buf->dev_private) {
++		buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
++		if (!buf->dev_private) {
+ 			/* Set count correctly so we free the proper amount. */
+ 			entry->buf_count = count;
+-			drm_cleanup_buf_error(dev,entry);
+-			up( &dev->struct_sem );
+-			atomic_dec( &dev->buf_alloc );
++			drm_cleanup_buf_error(dev, entry);
++			up(&dev->struct_sem);
++			atomic_dec(&dev->buf_alloc);
+ 			return -ENOMEM;
+ 		}
+ 
+-		memset( buf->dev_private, 0, buf->dev_priv_size );
++		memset(buf->dev_private, 0, buf->dev_priv_size);
+ 
+-		DRM_DEBUG( "buffer %d @ %p\n",
+-			   entry->buf_count, buf->address );
++		DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
+ 
+ 		offset += alignment;
+ 		entry->buf_count++;
+ 		byte_count += PAGE_SIZE << page_order;
+ 	}
+ 
+-	DRM_DEBUG( "byte_count: %d\n", byte_count );
++	DRM_DEBUG("byte_count: %d\n", byte_count);
+ 
+-	temp_buflist = drm_realloc( dma->buflist,
+-				     dma->buf_count * sizeof(*dma->buflist),
+-				     (dma->buf_count + entry->buf_count)
+-				     * sizeof(*dma->buflist),
+-				     DRM_MEM_BUFS );
+-	if(!temp_buflist) {
++	temp_buflist = drm_realloc(dma->buflist,
++				   dma->buf_count * sizeof(*dma->buflist),
++				   (dma->buf_count + entry->buf_count)
++				   * sizeof(*dma->buflist), DRM_MEM_BUFS);
++	if (!temp_buflist) {
+ 		/* Free the entry because it isn't valid */
+-		drm_cleanup_buf_error(dev,entry);
+-		up( &dev->struct_sem );
+-		atomic_dec( &dev->buf_alloc );
++		drm_cleanup_buf_error(dev, entry);
++		up(&dev->struct_sem);
++		atomic_dec(&dev->buf_alloc);
+ 		return -ENOMEM;
+ 	}
+ 	dma->buflist = temp_buflist;
+ 
+-	for ( i = 0 ; i < entry->buf_count ; i++ ) {
++	for (i = 0; i < entry->buf_count; i++) {
+ 		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+ 	}
+ 
+ 	dma->buf_count += entry->buf_count;
+ 	dma->byte_count += byte_count;
+ 
+-	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
+-	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
++	DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
++	DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
+ 
+-	up( &dev->struct_sem );
++	up(&dev->struct_sem);
+ 
+ 	request->count = entry->buf_count;
+ 	request->size = size;
+ 
+ 	dma->flags = _DRM_DMA_USE_SG;
+ 
+-	atomic_dec( &dev->buf_alloc );
++	atomic_dec(&dev->buf_alloc);
+ 	return 0;
+ }
+ 
+-static int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request)
++static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_buf_entry_t *entry;
+@@ -1060,7 +1061,7 @@ static int drm_addbufs_fb(drm_device_t *
+ 
+ 	if (!drm_core_check_feature(dev, DRIVER_FB_DMA))
+ 		return -EINVAL;
+-    
++
+ 	if (!dma)
+ 		return -EINVAL;
+ 
+@@ -1210,43 +1211,41 @@ static int drm_addbufs_fb(drm_device_t *
+  * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
+  * PCI memory respectively.
+  */
+-int drm_addbufs( struct inode *inode, struct file *filp,
+-		  unsigned int cmd, unsigned long arg )
++int drm_addbufs(struct inode *inode, struct file *filp,
++		unsigned int cmd, unsigned long arg)
+ {
+ 	drm_buf_desc_t request;
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	int ret;
+-	
++
+ 	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+ 		return -EINVAL;
+ 
+-	if ( copy_from_user( &request, (drm_buf_desc_t __user *)arg,
+-			     sizeof(request) ) )
++	if (copy_from_user(&request, (drm_buf_desc_t __user *) arg,
++			   sizeof(request)))
+ 		return -EFAULT;
+ 
+ #if __OS_HAS_AGP
+-	if ( request.flags & _DRM_AGP_BUFFER )
+-		ret=drm_addbufs_agp(dev, &request);
++	if (request.flags & _DRM_AGP_BUFFER)
++		ret = drm_addbufs_agp(dev, &request);
+ 	else
+ #endif
+-	if ( request.flags & _DRM_SG_BUFFER )
+-		ret=drm_addbufs_sg(dev, &request);
+-	else if ( request.flags & _DRM_FB_BUFFER)
+-		ret=drm_addbufs_fb(dev, &request);
++	if (request.flags & _DRM_SG_BUFFER)
++		ret = drm_addbufs_sg(dev, &request);
++	else if (request.flags & _DRM_FB_BUFFER)
++		ret = drm_addbufs_fb(dev, &request);
+ 	else
+-		ret=drm_addbufs_pci(dev, &request);
++		ret = drm_addbufs_pci(dev, &request);
+ 
+-	if (ret==0) {
+-		if (copy_to_user((void __user *)arg, &request,
+-				 sizeof(request))) {
++	if (ret == 0) {
++		if (copy_to_user((void __user *)arg, &request, sizeof(request))) {
+ 			ret = -EFAULT;
+ 		}
+ 	}
+ 	return ret;
+ }
+ 
+-
+ /**
+  * Get information about the buffer mappings.
+  *
+@@ -1264,8 +1263,8 @@ int drm_addbufs( struct inode *inode, st
+  * lock, preventing of allocating more buffers after this call. Information
+  * about each requested buffer is then copied into user space.
+  */
+-int drm_infobufs( struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg )
++int drm_infobufs(struct inode *inode, struct file *filp,
++		 unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -1278,58 +1277,61 @@ int drm_infobufs( struct inode *inode, s
+ 	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+ 		return -EINVAL;
+ 
+-	if ( !dma ) return -EINVAL;
++	if (!dma)
++		return -EINVAL;
+ 
+-	spin_lock( &dev->count_lock );
+-	if ( atomic_read( &dev->buf_alloc ) ) {
+-		spin_unlock( &dev->count_lock );
++	spin_lock(&dev->count_lock);
++	if (atomic_read(&dev->buf_alloc)) {
++		spin_unlock(&dev->count_lock);
+ 		return -EBUSY;
+ 	}
+ 	++dev->buf_use;		/* Can't allocate more after this call */
+-	spin_unlock( &dev->count_lock );
++	spin_unlock(&dev->count_lock);
+ 
+-	if ( copy_from_user( &request, argp, sizeof(request) ) )
++	if (copy_from_user(&request, argp, sizeof(request)))
+ 		return -EFAULT;
+ 
+-	for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
+-		if ( dma->bufs[i].buf_count ) ++count;
++	for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
++		if (dma->bufs[i].buf_count)
++			++count;
+ 	}
+ 
+-	DRM_DEBUG( "count = %d\n", count );
+-
+-	if ( request.count >= count ) {
+-		for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
+-			if ( dma->bufs[i].buf_count ) {
+-				drm_buf_desc_t __user *to = &request.list[count];
++	DRM_DEBUG("count = %d\n", count);
++
++	if (request.count >= count) {
++		for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
++			if (dma->bufs[i].buf_count) {
++				drm_buf_desc_t __user *to =
++				    &request.list[count];
+ 				drm_buf_entry_t *from = &dma->bufs[i];
+ 				drm_freelist_t *list = &dma->bufs[i].freelist;
+-				if ( copy_to_user( &to->count,
+-						   &from->buf_count,
+-						   sizeof(from->buf_count) ) ||
+-				     copy_to_user( &to->size,
+-						   &from->buf_size,
+-						   sizeof(from->buf_size) ) ||
+-				     copy_to_user( &to->low_mark,
+-						   &list->low_mark,
+-						   sizeof(list->low_mark) ) ||
+-				     copy_to_user( &to->high_mark,
+-						   &list->high_mark,
+-						   sizeof(list->high_mark) ) )
++				if (copy_to_user(&to->count,
++						 &from->buf_count,
++						 sizeof(from->buf_count)) ||
++				    copy_to_user(&to->size,
++						 &from->buf_size,
++						 sizeof(from->buf_size)) ||
++				    copy_to_user(&to->low_mark,
++						 &list->low_mark,
++						 sizeof(list->low_mark)) ||
++				    copy_to_user(&to->high_mark,
++						 &list->high_mark,
++						 sizeof(list->high_mark)))
+ 					return -EFAULT;
+ 
+-				DRM_DEBUG( "%d %d %d %d %d\n",
+-					   i,
+-					   dma->bufs[i].buf_count,
+-					   dma->bufs[i].buf_size,
+-					   dma->bufs[i].freelist.low_mark,
+-					   dma->bufs[i].freelist.high_mark );
++				DRM_DEBUG("%d %d %d %d %d\n",
++					  i,
++					  dma->bufs[i].buf_count,
++					  dma->bufs[i].buf_size,
++					  dma->bufs[i].freelist.low_mark,
++					  dma->bufs[i].freelist.high_mark);
+ 				++count;
+ 			}
+ 		}
+ 	}
+ 	request.count = count;
+ 
+-	if ( copy_to_user( argp, &request, sizeof(request) ) )
++	if (copy_to_user(argp, &request, sizeof(request)))
+ 		return -EFAULT;
+ 
+ 	return 0;
+@@ -1349,8 +1351,8 @@ int drm_infobufs( struct inode *inode, s
+  *
+  * \note This ioctl is deprecated and mostly never used.
+  */
+-int drm_markbufs( struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg )
++int drm_markbufs(struct inode *inode, struct file *filp,
++		 unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -1362,44 +1364,45 @@ int drm_markbufs( struct inode *inode, s
+ 	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+ 		return -EINVAL;
+ 
+-	if ( !dma ) return -EINVAL;
++	if (!dma)
++		return -EINVAL;
+ 
+-	if ( copy_from_user( &request,
+-			     (drm_buf_desc_t __user *)arg,
+-			     sizeof(request) ) )
++	if (copy_from_user(&request,
++			   (drm_buf_desc_t __user *) arg, sizeof(request)))
+ 		return -EFAULT;
+ 
+-	DRM_DEBUG( "%d, %d, %d\n",
+-		   request.size, request.low_mark, request.high_mark );
+-	order = drm_order( request.size );
+-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
++	DRM_DEBUG("%d, %d, %d\n",
++		  request.size, request.low_mark, request.high_mark);
++	order = drm_order(request.size);
++	if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
++		return -EINVAL;
+ 	entry = &dma->bufs[order];
+ 
+-	if ( request.low_mark < 0 || request.low_mark > entry->buf_count )
++	if (request.low_mark < 0 || request.low_mark > entry->buf_count)
+ 		return -EINVAL;
+-	if ( request.high_mark < 0 || request.high_mark > entry->buf_count )
++	if (request.high_mark < 0 || request.high_mark > entry->buf_count)
+ 		return -EINVAL;
+ 
+-	entry->freelist.low_mark  = request.low_mark;
++	entry->freelist.low_mark = request.low_mark;
+ 	entry->freelist.high_mark = request.high_mark;
+ 
+ 	return 0;
+ }
+ 
+ /**
+- * Unreserve the buffers in list, previously reserved using drmDMA. 
++ * Unreserve the buffers in list, previously reserved using drmDMA.
+  *
+  * \param inode device inode.
+  * \param filp file pointer.
+  * \param cmd command.
+  * \param arg pointer to a drm_buf_free structure.
+  * \return zero on success or a negative number on failure.
+- * 
++ *
+  * Calls free_buffer() for each used buffer.
+  * This function is primarily used for debugging.
+  */
+-int drm_freebufs( struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg )
++int drm_freebufs(struct inode *inode, struct file *filp,
++		 unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -1412,31 +1415,29 @@ int drm_freebufs( struct inode *inode, s
+ 	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+ 		return -EINVAL;
+ 
+-	if ( !dma ) return -EINVAL;
++	if (!dma)
++		return -EINVAL;
+ 
+-	if ( copy_from_user( &request,
+-			     (drm_buf_free_t __user *)arg,
+-			     sizeof(request) ) )
++	if (copy_from_user(&request,
++			   (drm_buf_free_t __user *) arg, sizeof(request)))
+ 		return -EFAULT;
+ 
+-	DRM_DEBUG( "%d\n", request.count );
+-	for ( i = 0 ; i < request.count ; i++ ) {
+-		if ( copy_from_user( &idx,
+-				     &request.list[i],
+-				     sizeof(idx) ) )
++	DRM_DEBUG("%d\n", request.count);
++	for (i = 0; i < request.count; i++) {
++		if (copy_from_user(&idx, &request.list[i], sizeof(idx)))
+ 			return -EFAULT;
+-		if ( idx < 0 || idx >= dma->buf_count ) {
+-			DRM_ERROR( "Index %d (of %d max)\n",
+-				   idx, dma->buf_count - 1 );
++		if (idx < 0 || idx >= dma->buf_count) {
++			DRM_ERROR("Index %d (of %d max)\n",
++				  idx, dma->buf_count - 1);
+ 			return -EINVAL;
+ 		}
+ 		buf = dma->buflist[idx];
+-		if ( buf->filp != filp ) {
+-			DRM_ERROR( "Process %d freeing buffer not owned\n",
+-				   current->pid );
++		if (buf->filp != filp) {
++			DRM_ERROR("Process %d freeing buffer not owned\n",
++				  current->pid);
+ 			return -EINVAL;
+ 		}
+-		drm_free_buffer( dev, buf );
++		drm_free_buffer(dev, buf);
+ 	}
+ 
+ 	return 0;
+@@ -1455,8 +1456,8 @@ int drm_freebufs( struct inode *inode, s
+  * about each buffer into user space. The PCI buffers are already mapped on the
+  * addbufs_pci() call.
+  */
+-int drm_mapbufs( struct inode *inode, struct file *filp,
+-		  unsigned int cmd, unsigned long arg )
++int drm_mapbufs(struct inode *inode, struct file *filp,
++		unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -1472,86 +1473,84 @@ int drm_mapbufs( struct inode *inode, st
+ 	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+ 		return -EINVAL;
+ 
+-	if ( !dma ) return -EINVAL;
++	if (!dma)
++		return -EINVAL;
+ 
+-	spin_lock( &dev->count_lock );
+-	if ( atomic_read( &dev->buf_alloc ) ) {
+-		spin_unlock( &dev->count_lock );
++	spin_lock(&dev->count_lock);
++	if (atomic_read(&dev->buf_alloc)) {
++		spin_unlock(&dev->count_lock);
+ 		return -EBUSY;
+ 	}
+ 	dev->buf_use++;		/* Can't allocate more after this call */
+-	spin_unlock( &dev->count_lock );
++	spin_unlock(&dev->count_lock);
+ 
+-	if ( copy_from_user( &request, argp, sizeof(request) ) )
++	if (copy_from_user(&request, argp, sizeof(request)))
+ 		return -EFAULT;
+ 
+-	if ( request.count >= dma->buf_count ) {
++	if (request.count >= dma->buf_count) {
+ 		if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP))
+-		    || (drm_core_check_feature(dev, DRIVER_SG) 
++		    || (drm_core_check_feature(dev, DRIVER_SG)
+ 			&& (dma->flags & _DRM_DMA_USE_SG))
+ 		    || (drm_core_check_feature(dev, DRIVER_FB_DMA)
+ 			&& (dma->flags & _DRM_DMA_USE_FB))) {
+ 			drm_map_t *map = dev->agp_buffer_map;
+ 			unsigned long token = dev->agp_buffer_token;
+ 
+-			if ( !map ) {
++			if (!map) {
+ 				retcode = -EINVAL;
+ 				goto done;
+ 			}
+ 
+-			down_write( &current->mm->mmap_sem );
+-			virtual = do_mmap( filp, 0, map->size,
+-					   PROT_READ | PROT_WRITE,
+-					   MAP_SHARED,
+-					   token );
+-			up_write( &current->mm->mmap_sem );
++			down_write(&current->mm->mmap_sem);
++			virtual = do_mmap(filp, 0, map->size,
++					  PROT_READ | PROT_WRITE,
++					  MAP_SHARED, token);
++			up_write(&current->mm->mmap_sem);
+ 		} else {
+-			down_write( &current->mm->mmap_sem );
+-			virtual = do_mmap( filp, 0, dma->byte_count,
+-					   PROT_READ | PROT_WRITE,
+-					   MAP_SHARED, 0 );
+-			up_write( &current->mm->mmap_sem );
++			down_write(&current->mm->mmap_sem);
++			virtual = do_mmap(filp, 0, dma->byte_count,
++					  PROT_READ | PROT_WRITE,
++					  MAP_SHARED, 0);
++			up_write(&current->mm->mmap_sem);
+ 		}
+-		if ( virtual > -1024UL ) {
++		if (virtual > -1024UL) {
+ 			/* Real error */
+ 			retcode = (signed long)virtual;
+ 			goto done;
+ 		}
+ 		request.virtual = (void __user *)virtual;
+ 
+-		for ( i = 0 ; i < dma->buf_count ; i++ ) {
+-			if ( copy_to_user( &request.list[i].idx,
+-					   &dma->buflist[i]->idx,
+-					   sizeof(request.list[0].idx) ) ) {
++		for (i = 0; i < dma->buf_count; i++) {
++			if (copy_to_user(&request.list[i].idx,
++					 &dma->buflist[i]->idx,
++					 sizeof(request.list[0].idx))) {
+ 				retcode = -EFAULT;
+ 				goto done;
+ 			}
+-			if ( copy_to_user( &request.list[i].total,
+-					   &dma->buflist[i]->total,
+-					   sizeof(request.list[0].total) ) ) {
++			if (copy_to_user(&request.list[i].total,
++					 &dma->buflist[i]->total,
++					 sizeof(request.list[0].total))) {
+ 				retcode = -EFAULT;
+ 				goto done;
+ 			}
+-			if ( copy_to_user( &request.list[i].used,
+-					   &zero,
+-					   sizeof(zero) ) ) {
++			if (copy_to_user(&request.list[i].used,
++					 &zero, sizeof(zero))) {
+ 				retcode = -EFAULT;
+ 				goto done;
+ 			}
+-			address = virtual + dma->buflist[i]->offset; /* *** */
+-			if ( copy_to_user( &request.list[i].address,
+-					   &address,
+-					   sizeof(address) ) ) {
++			address = virtual + dma->buflist[i]->offset;	/* *** */
++			if (copy_to_user(&request.list[i].address,
++					 &address, sizeof(address))) {
+ 				retcode = -EFAULT;
+ 				goto done;
+ 			}
+ 		}
+ 	}
+- done:
++      done:
+ 	request.count = dma->buf_count;
+-	DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode );
++	DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
+ 
+-	if ( copy_to_user( argp, &request, sizeof(request) ) )
++	if (copy_to_user(argp, &request, sizeof(request)))
+ 		return -EFAULT;
+ 
+ 	return retcode;
+@@ -1560,23 +1559,23 @@ int drm_mapbufs( struct inode *inode, st
+ /**
+  * Compute size order.  Returns the exponent of the smaller power of two which
+  * is greater or equal to given number.
+- * 
++ *
+  * \param size size.
+  * \return order.
+  *
+  * \todo Can be made faster.
+  */
+-int drm_order( unsigned long size )
++int drm_order(unsigned long size)
+ {
+ 	int order;
+ 	unsigned long tmp;
+ 
+-	for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++)
+-		;
++	for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) ;
+ 
+ 	if (size & (size - 1))
+ 		++order;
+ 
+ 	return order;
+ }
++
+ EXPORT_SYMBOL(drm_order);
+diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
+--- a/drivers/char/drm/drm_context.c
++++ b/drivers/char/drm/drm_context.c
+@@ -1,7 +1,7 @@
+ /**
+- * \file drm_context.h 
++ * \file drm_context.c
+  * IOCTLs for generic contexts
+- * 
++ *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Gareth Hughes <gareth at valinux.com>
+  */
+@@ -56,25 +56,26 @@
+  * in drm_device::context_sareas, while holding the drm_device::struct_sem
+  * lock.
+  */
+-void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle )
++void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle)
+ {
+-	if ( ctx_handle < 0 ) goto failed;
+-	if ( !dev->ctx_bitmap ) goto failed;
++	if (ctx_handle < 0)
++		goto failed;
++	if (!dev->ctx_bitmap)
++		goto failed;
+ 
+-	if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
++	if (ctx_handle < DRM_MAX_CTXBITMAP) {
+ 		down(&dev->struct_sem);
+-		clear_bit( ctx_handle, dev->ctx_bitmap );
++		clear_bit(ctx_handle, dev->ctx_bitmap);
+ 		dev->context_sareas[ctx_handle] = NULL;
+ 		up(&dev->struct_sem);
+ 		return;
+ 	}
+-failed:
+-       	DRM_ERROR( "Attempt to free invalid context handle: %d\n",
+-		   ctx_handle );
+-       	return;
++      failed:
++	DRM_ERROR("Attempt to free invalid context handle: %d\n", ctx_handle);
++	return;
+ }
+ 
+-/** 
++/**
+  * Context bitmap allocation.
+  *
+  * \param dev DRM device.
+@@ -84,29 +85,33 @@ failed:
+  * drm_device::context_sareas to accommodate the new entry while holding the
+  * drm_device::struct_sem lock.
+  */
+-static int drm_ctxbitmap_next( drm_device_t *dev )
++static int drm_ctxbitmap_next(drm_device_t * dev)
+ {
+ 	int bit;
+ 
+-	if(!dev->ctx_bitmap) return -1;
++	if (!dev->ctx_bitmap)
++		return -1;
+ 
+ 	down(&dev->struct_sem);
+-	bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
+-	if ( bit < DRM_MAX_CTXBITMAP ) {
+-		set_bit( bit, dev->ctx_bitmap );
+-	   	DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
+-		if((bit+1) > dev->max_context) {
+-			dev->max_context = (bit+1);
+-			if(dev->context_sareas) {
++	bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP);
++	if (bit < DRM_MAX_CTXBITMAP) {
++		set_bit(bit, dev->ctx_bitmap);
++		DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit);
++		if ((bit + 1) > dev->max_context) {
++			dev->max_context = (bit + 1);
++			if (dev->context_sareas) {
+ 				drm_map_t **ctx_sareas;
+ 
+ 				ctx_sareas = drm_realloc(dev->context_sareas,
+-						(dev->max_context - 1) * 
+-						sizeof(*dev->context_sareas),
+-						dev->max_context * 
+-						sizeof(*dev->context_sareas),
+-						DRM_MEM_MAPS);
+-				if(!ctx_sareas) {
++							 (dev->max_context -
++							  1) *
++							 sizeof(*dev->
++								context_sareas),
++							 dev->max_context *
++							 sizeof(*dev->
++								context_sareas),
++							 DRM_MEM_MAPS);
++				if (!ctx_sareas) {
+ 					clear_bit(bit, dev->ctx_bitmap);
+ 					up(&dev->struct_sem);
+ 					return -1;
+@@ -115,11 +120,11 @@ static int drm_ctxbitmap_next( drm_devic
+ 				dev->context_sareas[bit] = NULL;
+ 			} else {
+ 				/* max_context == 1 at this point */
+-				dev->context_sareas = drm_alloc(
+-						dev->max_context * 
+-						sizeof(*dev->context_sareas),
+-						DRM_MEM_MAPS);
+-				if(!dev->context_sareas) {
++				dev->context_sareas =
++				    drm_alloc(dev->max_context *
++					      sizeof(*dev->context_sareas),
++					      DRM_MEM_MAPS);
++				if (!dev->context_sareas) {
+ 					clear_bit(bit, dev->ctx_bitmap);
+ 					up(&dev->struct_sem);
+ 					return -1;
+@@ -142,26 +147,26 @@ static int drm_ctxbitmap_next( drm_devic
+  * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
+  * the drm_device::struct_sem lock.
+  */
+-int drm_ctxbitmap_init( drm_device_t *dev )
++int drm_ctxbitmap_init(drm_device_t * dev)
+ {
+ 	int i;
+-   	int temp;
++	int temp;
+ 
+ 	down(&dev->struct_sem);
+-	dev->ctx_bitmap = (unsigned long *) drm_alloc( PAGE_SIZE,
+-							DRM_MEM_CTXBITMAP );
+-	if ( dev->ctx_bitmap == NULL ) {
++	dev->ctx_bitmap = (unsigned long *)drm_alloc(PAGE_SIZE,
++						     DRM_MEM_CTXBITMAP);
++	if (dev->ctx_bitmap == NULL) {
+ 		up(&dev->struct_sem);
+ 		return -ENOMEM;
+ 	}
+-	memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
++	memset((void *)dev->ctx_bitmap, 0, PAGE_SIZE);
+ 	dev->context_sareas = NULL;
+ 	dev->max_context = -1;
+ 	up(&dev->struct_sem);
+ 
+-	for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
+-		temp = drm_ctxbitmap_next( dev );
+-	   	DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
++	for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
++		temp = drm_ctxbitmap_next(dev);
++		DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp);
+ 	}
+ 
+ 	return 0;
+@@ -175,14 +180,14 @@ int drm_ctxbitmap_init( drm_device_t *de
+  * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
+  * the drm_device::struct_sem lock.
+  */
+-void drm_ctxbitmap_cleanup( drm_device_t *dev )
++void drm_ctxbitmap_cleanup(drm_device_t * dev)
+ {
+ 	down(&dev->struct_sem);
+-	if( dev->context_sareas ) drm_free( dev->context_sareas,
+-					     sizeof(*dev->context_sareas) * 
+-					     dev->max_context,
+-					     DRM_MEM_MAPS );
+-	drm_free( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
++	if (dev->context_sareas)
++		drm_free(dev->context_sareas,
++			 sizeof(*dev->context_sareas) *
++			 dev->max_context, DRM_MEM_MAPS);
++	drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP);
+ 	up(&dev->struct_sem);
+ }
+ 
+@@ -194,7 +199,7 @@ void drm_ctxbitmap_cleanup( drm_device_t
+ 
+ /**
+  * Get per-context SAREA.
+- * 
++ *
+  * \param inode device inode.
+  * \param filp file pointer.
+  * \param cmd command.
+@@ -205,10 +210,10 @@ void drm_ctxbitmap_cleanup( drm_device_t
+  * returns its handle.
+  */
+ int drm_getsareactx(struct inode *inode, struct file *filp,
+-		     unsigned int cmd, unsigned long arg)
++		    unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	*priv	= filp->private_data;
+-	drm_device_t	*dev	= priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_ctx_priv_map_t __user *argp = (void __user *)arg;
+ 	drm_ctx_priv_map_t request;
+ 	drm_map_t *map;
+@@ -218,7 +223,8 @@ int drm_getsareactx(struct inode *inode,
+ 		return -EFAULT;
+ 
+ 	down(&dev->struct_sem);
+-	if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
++	if (dev->max_context < 0
++	    || request.ctx_id >= (unsigned)dev->max_context) {
+ 		up(&dev->struct_sem);
+ 		return -EINVAL;
+ 	}
+@@ -226,17 +232,17 @@ int drm_getsareactx(struct inode *inode,
+ 	map = dev->context_sareas[request.ctx_id];
+ 	up(&dev->struct_sem);
+ 
+-	request.handle = 0;
+-	list_for_each_entry(_entry, &dev->maplist->head,head) {
++	request.handle = NULL;
++	list_for_each_entry(_entry, &dev->maplist->head, head) {
+ 		if (_entry->map == map) {
+-			request.handle = (void *)(unsigned long)_entry->user_token;
++			request.handle =
++			    (void *)(unsigned long)_entry->user_token;
+ 			break;
+ 		}
+ 	}
+-	if (request.handle == 0)
++	if (request.handle == NULL)
+ 		return -EINVAL;
+ 
+-
+ 	if (copy_to_user(argp, &request, sizeof(request)))
+ 		return -EFAULT;
+ 	return 0;
+@@ -244,7 +250,7 @@ int drm_getsareactx(struct inode *inode,
+ 
+ /**
+  * Set per-context SAREA.
+- * 
++ *
+  * \param inode device inode.
+  * \param filp file pointer.
+  * \param cmd command.
+@@ -255,37 +261,37 @@ int drm_getsareactx(struct inode *inode,
+  * drm_device::context_sareas with it.
+  */
+ int drm_setsareactx(struct inode *inode, struct file *filp,
+-		     unsigned int cmd, unsigned long arg)
++		    unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	*priv	= filp->private_data;
+-	drm_device_t	*dev	= priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_ctx_priv_map_t request;
+ 	drm_map_t *map = NULL;
+ 	drm_map_list_t *r_list = NULL;
+ 	struct list_head *list;
+ 
+ 	if (copy_from_user(&request,
+-			   (drm_ctx_priv_map_t __user *)arg,
+-			   sizeof(request)))
++			   (drm_ctx_priv_map_t __user *) arg, sizeof(request)))
+ 		return -EFAULT;
+ 
+ 	down(&dev->struct_sem);
+ 	list_for_each(list, &dev->maplist->head) {
+ 		r_list = list_entry(list, drm_map_list_t, head);
+ 		if (r_list->map
+-		    && r_list->user_token == (unsigned long) request.handle)
++		    && r_list->user_token == (unsigned long)request.handle)
+ 			goto found;
+ 	}
+-bad:
++      bad:
+ 	up(&dev->struct_sem);
+ 	return -EINVAL;
+ 
+-found:
++      found:
+ 	map = r_list->map;
+-	if (!map) goto bad;
++	if (!map)
++		goto bad;
+ 	if (dev->max_context < 0)
+ 		goto bad;
+-	if (request.ctx_id >= (unsigned) dev->max_context)
++	if (request.ctx_id >= (unsigned)dev->max_context)
+ 		goto bad;
+ 	dev->context_sareas[request.ctx_id] = map;
+ 	up(&dev->struct_sem);
+@@ -308,22 +314,21 @@ found:
+  *
+  * Attempt to set drm_device::context_flag.
+  */
+-static int drm_context_switch( drm_device_t *dev, int old, int new )
++static int drm_context_switch(drm_device_t * dev, int old, int new)
+ {
+-        if ( test_and_set_bit( 0, &dev->context_flag ) ) {
+-                DRM_ERROR( "Reentering -- FIXME\n" );
+-                return -EBUSY;
+-        }
+-
++	if (test_and_set_bit(0, &dev->context_flag)) {
++		DRM_ERROR("Reentering -- FIXME\n");
++		return -EBUSY;
++	}
+ 
+-        DRM_DEBUG( "Context switch from %d to %d\n", old, new );
++	DRM_DEBUG("Context switch from %d to %d\n", old, new);
+ 
+-        if ( new == dev->last_context ) {
+-                clear_bit( 0, &dev->context_flag );
+-                return 0;
+-        }
++	if (new == dev->last_context) {
++		clear_bit(0, &dev->context_flag);
++		return 0;
++	}
+ 
+-        return 0;
++	return 0;
+ }
+ 
+ /**
+@@ -337,22 +342,22 @@ static int drm_context_switch( drm_devic
+  * hardware lock is held, clears the drm_device::context_flag and wakes up
+  * drm_device::context_wait.
+  */
+-static int drm_context_switch_complete( drm_device_t *dev, int new )
++static int drm_context_switch_complete(drm_device_t * dev, int new)
+ {
+-        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
+-        dev->last_switch  = jiffies;
++	dev->last_context = new;	/* PRE/POST: This is the _only_ writer. */
++	dev->last_switch = jiffies;
+ 
+-        if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
+-                DRM_ERROR( "Lock isn't held after context switch\n" );
+-        }
+-
+-				/* If a context switch is ever initiated
+-                                   when the kernel holds the lock, release
+-                                   that lock here. */
+-        clear_bit( 0, &dev->context_flag );
+-        wake_up( &dev->context_wait );
++	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
++		DRM_ERROR("Lock isn't held after context switch\n");
++	}
++
++	/* If a context switch is ever initiated
++	   when the kernel holds the lock, release
++	   that lock here. */
++	clear_bit(0, &dev->context_flag);
++	wake_up(&dev->context_wait);
+ 
+-        return 0;
++	return 0;
+ }
+ 
+ /**
+@@ -364,29 +369,28 @@ static int drm_context_switch_complete( 
+  * \param arg user argument pointing to a drm_ctx_res structure.
+  * \return zero on success or a negative number on failure.
+  */
+-int drm_resctx( struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg )
++int drm_resctx(struct inode *inode, struct file *filp,
++	       unsigned int cmd, unsigned long arg)
+ {
+ 	drm_ctx_res_t res;
+ 	drm_ctx_t __user *argp = (void __user *)arg;
+ 	drm_ctx_t ctx;
+ 	int i;
+ 
+-	if ( copy_from_user( &res, argp, sizeof(res) ) )
++	if (copy_from_user(&res, argp, sizeof(res)))
+ 		return -EFAULT;
+ 
+-	if ( res.count >= DRM_RESERVED_CONTEXTS ) {
+-		memset( &ctx, 0, sizeof(ctx) );
+-		for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
++	if (res.count >= DRM_RESERVED_CONTEXTS) {
++		memset(&ctx, 0, sizeof(ctx));
++		for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ 			ctx.handle = i;
+-			if ( copy_to_user( &res.contexts[i],
+-					   &ctx, sizeof(ctx) ) )
++			if (copy_to_user(&res.contexts[i], &ctx, sizeof(ctx)))
+ 				return -EFAULT;
+ 		}
+ 	}
+ 	res.count = DRM_RESERVED_CONTEXTS;
+ 
+-	if ( copy_to_user( argp, &res, sizeof(res) ) )
++	if (copy_to_user(argp, &res, sizeof(res)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+@@ -402,58 +406,57 @@ int drm_resctx( struct inode *inode, str
+  *
+  * Get a new handle for the context and copy to userspace.
+  */
+-int drm_addctx( struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg )
++int drm_addctx(struct inode *inode, struct file *filp,
++	       unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+-	drm_ctx_list_t * ctx_entry;
++	drm_ctx_list_t *ctx_entry;
+ 	drm_ctx_t __user *argp = (void __user *)arg;
+ 	drm_ctx_t ctx;
+ 
+-	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
++	if (copy_from_user(&ctx, argp, sizeof(ctx)))
+ 		return -EFAULT;
+ 
+-	ctx.handle = drm_ctxbitmap_next( dev );
+-	if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
+-				/* Skip kernel's context and get a new one. */
+-		ctx.handle = drm_ctxbitmap_next( dev );
+-	}
+-	DRM_DEBUG( "%d\n", ctx.handle );
+-	if ( ctx.handle == -1 ) {
+-		DRM_DEBUG( "Not enough free contexts.\n" );
+-				/* Should this return -EBUSY instead? */
++	ctx.handle = drm_ctxbitmap_next(dev);
++	if (ctx.handle == DRM_KERNEL_CONTEXT) {
++		/* Skip kernel's context and get a new one. */
++		ctx.handle = drm_ctxbitmap_next(dev);
++	}
++	DRM_DEBUG("%d\n", ctx.handle);
++	if (ctx.handle == -1) {
++		DRM_DEBUG("Not enough free contexts.\n");
++		/* Should this return -EBUSY instead? */
+ 		return -ENOMEM;
+ 	}
+ 
+-	if ( ctx.handle != DRM_KERNEL_CONTEXT )
+-	{
++	if (ctx.handle != DRM_KERNEL_CONTEXT) {
+ 		if (dev->driver->context_ctor)
+ 			dev->driver->context_ctor(dev, ctx.handle);
+ 	}
+ 
+-	ctx_entry = drm_alloc( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
+-	if ( !ctx_entry ) {
++	ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST);
++	if (!ctx_entry) {
+ 		DRM_DEBUG("out of memory\n");
+ 		return -ENOMEM;
+ 	}
+ 
+-	INIT_LIST_HEAD( &ctx_entry->head );
++	INIT_LIST_HEAD(&ctx_entry->head);
+ 	ctx_entry->handle = ctx.handle;
+ 	ctx_entry->tag = priv;
+ 
+-	down( &dev->ctxlist_sem );
+-	list_add( &ctx_entry->head, &dev->ctxlist->head );
++	down(&dev->ctxlist_sem);
++	list_add(&ctx_entry->head, &dev->ctxlist->head);
+ 	++dev->ctx_count;
+-	up( &dev->ctxlist_sem );
++	up(&dev->ctxlist_sem);
+ 
+-	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
++	if (copy_to_user(argp, &ctx, sizeof(ctx)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+ 
+-int drm_modctx( struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg )
++int drm_modctx(struct inode *inode, struct file *filp,
++	       unsigned int cmd, unsigned long arg)
+ {
+ 	/* This does nothing */
+ 	return 0;
+@@ -468,19 +471,19 @@ int drm_modctx( struct inode *inode, str
+  * \param arg user argument pointing to a drm_ctx structure.
+  * \return zero on success or a negative number on failure.
+  */
+-int drm_getctx( struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg )
++int drm_getctx(struct inode *inode, struct file *filp,
++	       unsigned int cmd, unsigned long arg)
+ {
+ 	drm_ctx_t __user *argp = (void __user *)arg;
+ 	drm_ctx_t ctx;
+ 
+-	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
++	if (copy_from_user(&ctx, argp, sizeof(ctx)))
+ 		return -EFAULT;
+ 
+ 	/* This is 0, because we don't handle any context flags */
+ 	ctx.flags = 0;
+ 
+-	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
++	if (copy_to_user(argp, &ctx, sizeof(ctx)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+@@ -496,18 +499,18 @@ int drm_getctx( struct inode *inode, str
+  *
+  * Calls context_switch().
+  */
+-int drm_switchctx( struct inode *inode, struct file *filp,
+-		    unsigned int cmd, unsigned long arg )
++int drm_switchctx(struct inode *inode, struct file *filp,
++		  unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_ctx_t ctx;
+ 
+-	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
++	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
+ 		return -EFAULT;
+ 
+-	DRM_DEBUG( "%d\n", ctx.handle );
+-	return drm_context_switch( dev, dev->last_context, ctx.handle );
++	DRM_DEBUG("%d\n", ctx.handle);
++	return drm_context_switch(dev, dev->last_context, ctx.handle);
+ }
+ 
+ /**
+@@ -521,18 +524,18 @@ int drm_switchctx( struct inode *inode, 
+  *
+  * Calls context_switch_complete().
+  */
+-int drm_newctx( struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg )
++int drm_newctx(struct inode *inode, struct file *filp,
++	       unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_ctx_t ctx;
+ 
+-	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
++	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
+ 		return -EFAULT;
+ 
+-	DRM_DEBUG( "%d\n", ctx.handle );
+-	drm_context_switch_complete( dev, ctx.handle );
++	DRM_DEBUG("%d\n", ctx.handle);
++	drm_context_switch_complete(dev, ctx.handle);
+ 
+ 	return 0;
+ }
+@@ -548,42 +551,41 @@ int drm_newctx( struct inode *inode, str
+  *
+  * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
+  */
+-int drm_rmctx( struct inode *inode, struct file *filp,
+-		unsigned int cmd, unsigned long arg )
++int drm_rmctx(struct inode *inode, struct file *filp,
++	      unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_ctx_t ctx;
+ 
+-	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
++	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
+ 		return -EFAULT;
+ 
+-	DRM_DEBUG( "%d\n", ctx.handle );
+-	if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) {
++	DRM_DEBUG("%d\n", ctx.handle);
++	if (ctx.handle == DRM_KERNEL_CONTEXT + 1) {
+ 		priv->remove_auth_on_close = 1;
+ 	}
+-	if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
++	if (ctx.handle != DRM_KERNEL_CONTEXT) {
+ 		if (dev->driver->context_dtor)
+ 			dev->driver->context_dtor(dev, ctx.handle);
+-		drm_ctxbitmap_free( dev, ctx.handle );
++		drm_ctxbitmap_free(dev, ctx.handle);
+ 	}
+ 
+-	down( &dev->ctxlist_sem );
+-	if ( !list_empty( &dev->ctxlist->head ) ) {
++	down(&dev->ctxlist_sem);
++	if (!list_empty(&dev->ctxlist->head)) {
+ 		drm_ctx_list_t *pos, *n;
+ 
+-		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+-			if ( pos->handle == ctx.handle ) {
+-				list_del( &pos->head );
+-				drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
++		list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) {
++			if (pos->handle == ctx.handle) {
++				list_del(&pos->head);
++				drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
+ 				--dev->ctx_count;
+ 			}
+ 		}
+ 	}
+-	up( &dev->ctxlist_sem );
++	up(&dev->ctxlist_sem);
+ 
+ 	return 0;
+ }
+ 
+ /*@}*/
+-
+diff --git a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c
+--- a/drivers/char/drm/drm_dma.c
++++ b/drivers/char/drm/drm_dma.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_dma.h 
++ * \file drm_dma.c
+  * DMA IOCTL and function support
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+@@ -37,23 +37,23 @@
+ 
+ /**
+  * Initialize the DMA data.
+- * 
++ *
+  * \param dev DRM device.
+  * \return zero on success or a negative value on failure.
+  *
+  * Allocate and initialize a drm_device_dma structure.
+  */
+-int drm_dma_setup( drm_device_t *dev )
++int drm_dma_setup(drm_device_t * dev)
+ {
+ 	int i;
+ 
+-	dev->dma = drm_alloc( sizeof(*dev->dma), DRM_MEM_DRIVER );
+-	if ( !dev->dma )
++	dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER);
++	if (!dev->dma)
+ 		return -ENOMEM;
+ 
+-	memset( dev->dma, 0, sizeof(*dev->dma) );
++	memset(dev->dma, 0, sizeof(*dev->dma));
+ 
+-	for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
++	for (i = 0; i <= DRM_MAX_ORDER; i++)
+ 		memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
+ 
+ 	return 0;
+@@ -67,14 +67,15 @@ int drm_dma_setup( drm_device_t *dev )
+  * Free all pages associated with DMA buffers, the buffers and pages lists, and
+  * finally the the drm_device::dma structure itself.
+  */
+-void drm_dma_takedown(drm_device_t *dev)
++void drm_dma_takedown(drm_device_t * dev)
+ {
+-	drm_device_dma_t  *dma = dev->dma;
+-	int		  i, j;
++	drm_device_dma_t *dma = dev->dma;
++	int i, j;
+ 
+-	if (!dma) return;
++	if (!dma)
++		return;
+ 
+-				/* Clear dma buffers */
++	/* Clear dma buffers */
+ 	for (i = 0; i <= DRM_MAX_ORDER; i++) {
+ 		if (dma->bufs[i].seg_count) {
+ 			DRM_DEBUG("order %d: buf_count = %d,"
+@@ -85,64 +86,63 @@ void drm_dma_takedown(drm_device_t *dev)
+ 			for (j = 0; j < dma->bufs[i].seg_count; j++) {
+ 				if (dma->bufs[i].seglist[j]) {
+ 					drm_free_pages(dma->bufs[i].seglist[j],
+-							dma->bufs[i].page_order,
+-							DRM_MEM_DMA);
++						       dma->bufs[i].page_order,
++						       DRM_MEM_DMA);
+ 				}
+ 			}
+ 			drm_free(dma->bufs[i].seglist,
+-				  dma->bufs[i].seg_count
+-				  * sizeof(*dma->bufs[0].seglist),
+-				  DRM_MEM_SEGS);
++				 dma->bufs[i].seg_count
++				 * sizeof(*dma->bufs[0].seglist), DRM_MEM_SEGS);
+ 		}
+-	   	if (dma->bufs[i].buf_count) {
+-		   	for (j = 0; j < dma->bufs[i].buf_count; j++) {
++		if (dma->bufs[i].buf_count) {
++			for (j = 0; j < dma->bufs[i].buf_count; j++) {
+ 				if (dma->bufs[i].buflist[j].dev_private) {
+-					drm_free(dma->bufs[i].buflist[j].dev_private,
+-						  dma->bufs[i].buflist[j].dev_priv_size,
+-						  DRM_MEM_BUFS);
++					drm_free(dma->bufs[i].buflist[j].
++						 dev_private,
++						 dma->bufs[i].buflist[j].
++						 dev_priv_size, DRM_MEM_BUFS);
+ 				}
+ 			}
+-		   	drm_free(dma->bufs[i].buflist,
+-				  dma->bufs[i].buf_count *
+-				  sizeof(*dma->bufs[0].buflist),
+-				  DRM_MEM_BUFS);
++			drm_free(dma->bufs[i].buflist,
++				 dma->bufs[i].buf_count *
++				 sizeof(*dma->bufs[0].buflist), DRM_MEM_BUFS);
+ 		}
+ 	}
+ 
+ 	if (dma->buflist) {
+ 		drm_free(dma->buflist,
+-			  dma->buf_count * sizeof(*dma->buflist),
+-			  DRM_MEM_BUFS);
++			 dma->buf_count * sizeof(*dma->buflist), DRM_MEM_BUFS);
+ 	}
+ 
+ 	if (dma->pagelist) {
+ 		drm_free(dma->pagelist,
+-			  dma->page_count * sizeof(*dma->pagelist),
+-			  DRM_MEM_PAGES);
++			 dma->page_count * sizeof(*dma->pagelist),
++			 DRM_MEM_PAGES);
+ 	}
+ 	drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
+ 	dev->dma = NULL;
+ }
+ 
+-
+ /**
+  * Free a buffer.
+  *
+  * \param dev DRM device.
+  * \param buf buffer to free.
+- * 
++ *
+  * Resets the fields of \p buf.
+  */
+-void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
++void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf)
+ {
+-	if (!buf) return;
++	if (!buf)
++		return;
+ 
+-	buf->waiting  = 0;
+-	buf->pending  = 0;
+-	buf->filp     = NULL;
+-	buf->used     = 0;
++	buf->waiting = 0;
++	buf->pending = 0;
++	buf->filp = NULL;
++	buf->used = 0;
+ 
+-	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) {
++	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)
++	    && waitqueue_active(&buf->dma_wait)) {
+ 		wake_up_interruptible(&buf->dma_wait);
+ 	}
+ }
+@@ -154,12 +154,13 @@ void drm_free_buffer(drm_device_t *dev, 
+  *
+  * Frees each buffer associated with \p filp not already on the hardware.
+  */
+-void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp)
++void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+-	int		 i;
++	int i;
+ 
+-	if (!dma) return;
++	if (!dma)
++		return;
+ 	for (i = 0; i < dma->buf_count; i++) {
+ 		if (dma->buflist[i]->filp == filp) {
+ 			switch (dma->buflist[i]->list) {
+@@ -176,5 +177,5 @@ void drm_core_reclaim_buffers(drm_device
+ 		}
+ 	}
+ }
+-EXPORT_SYMBOL(drm_core_reclaim_buffers);
+ 
++EXPORT_SYMBOL(drm_core_reclaim_buffers);
+diff --git a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c
+--- a/drivers/char/drm/drm_drawable.c
++++ b/drivers/char/drm/drm_drawable.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_drawable.h 
++ * \file drm_drawable.c
+  * IOCTLs for drawables
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+@@ -37,20 +37,20 @@
+ 
+ /** No-op. */
+ int drm_adddraw(struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg)
++		unsigned int cmd, unsigned long arg)
+ {
+ 	drm_draw_t draw;
+ 
+ 	draw.handle = 0;	/* NOOP */
+ 	DRM_DEBUG("%d\n", draw.handle);
+-	if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw)))
++	if (copy_to_user((drm_draw_t __user *) arg, &draw, sizeof(draw)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+ 
+ /** No-op. */
+ int drm_rmdraw(struct inode *inode, struct file *filp,
+-		unsigned int cmd, unsigned long arg)
++	       unsigned int cmd, unsigned long arg)
+ {
+ 	return 0;		/* NOOP */
+ }
+diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
+--- a/drivers/char/drm/drm_drv.c
++++ b/drivers/char/drm/drm_drv.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_drv.h 
++ * \file drm_drv.c
+  * Generic driver template
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+@@ -55,67 +55,67 @@ static int drm_version(struct inode *ino
+ 		       unsigned int cmd, unsigned long arg);
+ 
+ /** Ioctl table */
+-static drm_ioctl_desc_t		  drm_ioctls[] = {
+-	[DRM_IOCTL_NR(DRM_IOCTL_VERSION)]       = { drm_version,     0, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]    = { drm_getunique,   0, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]     = { drm_getmagic,    0, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]     = { drm_irq_by_busid, 0, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)]       = { drm_getmap,      0, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)]    = { drm_getclient,   0, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)]     = { drm_getstats,    0, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)]   = { drm_setversion,  0, 1 },
+-
+-	[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]    = { drm_setunique,   1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]         = { drm_noop,        1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]       = { drm_noop,        1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]    = { drm_authmagic,   1, 1 },
+-
+-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]       = { drm_addmap_ioctl,1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)]        = { drm_rmmap_ioctl, 1, 0 },
+-
+-	[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 },
+-
+-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]       = { drm_addctx,      1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]        = { drm_rmctx,       1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]       = { drm_modctx,      1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]       = { drm_getctx,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]    = { drm_switchctx,   1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]       = { drm_newctx,      1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]       = { drm_resctx,      1, 0 },
+-
+-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]      = { drm_adddraw,     1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]       = { drm_rmdraw,      1, 1 },
+-
+-	[DRM_IOCTL_NR(DRM_IOCTL_LOCK)]	        = { drm_lock,        1, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]        = { drm_unlock,      1, 0 },
+-
+-	[DRM_IOCTL_NR(DRM_IOCTL_FINISH)]        = { drm_noop,      1, 0 },
+-
+-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]      = { drm_addbufs,     1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]     = { drm_markbufs,    1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]     = { drm_infobufs,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]      = { drm_mapbufs,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]     = { drm_freebufs,    1, 0 },
++static drm_ioctl_desc_t drm_ioctls[] = {
++	[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, 0, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, 0, 1},
++
++	[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, 1, 1},
++
++	[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, 1, 0},
++
++	[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, 1, 0},
++
++	[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, 1, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, 1, 0},
++
++	[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, 1, 1},
++
++	[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, 1, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, 1, 0},
++
++	[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, 1, 0},
++
++	[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, 1, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, 1, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, 1, 0},
+ 	/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
+ 
+-	[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]       = { drm_control,     1, 1 },
++	[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, 1, 1},
+ 
+ #if __OS_HAS_AGP
+-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]   = { drm_agp_acquire_ioctl, 1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = { drm_agp_release_ioctl, 1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = { drm_agp_enable_ioctl, 1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = { drm_agp_info_ioctl, 1, 0 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { drm_agp_alloc,   1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { drm_agp_free,    1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { drm_agp_bind,    1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { drm_agp_unbind,  1, 1 },
++	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0},
++	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1},
+ #endif
+ 
+-	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)]      = { drm_sg_alloc,    1, 1 },
+-	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)]       = { drm_sg_free,     1, 1 },
++	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1},
++	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, 1, 1},
+ 
+-	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)]   = { drm_wait_vblank, 0, 0 },
++	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0, 0},
+ };
+ 
+ #define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( drm_ioctls )
+@@ -129,17 +129,17 @@ static drm_ioctl_desc_t		  drm_ioctls[] 
+  *
+  * \sa drm_device
+  */
+-int drm_takedown( drm_device_t *dev )
++int drm_takedown(drm_device_t * dev)
+ {
+ 	drm_magic_entry_t *pt, *next;
+ 	drm_map_list_t *r_list;
+ 	drm_vma_entry_t *vma, *vma_next;
+ 	int i;
+ 
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	if (dev->driver->pretakedown)
+-	  dev->driver->pretakedown(dev);
++		dev->driver->pretakedown(dev);
+ 	DRM_DEBUG("driver pretakedown completed\n");
+ 
+ 	if (dev->unique) {
+@@ -148,95 +148,95 @@ int drm_takedown( drm_device_t *dev )
+ 		dev->unique_len = 0;
+ 	}
+ 
+-	if ( dev->irq_enabled ) drm_irq_uninstall( dev );
++	if (dev->irq_enabled)
++		drm_irq_uninstall(dev);
+ 
+-	down( &dev->struct_sem );
+-	del_timer( &dev->timer );
++	down(&dev->struct_sem);
++	del_timer(&dev->timer);
+ 
+-				/* Clear pid list */
+-	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+-		for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {
++	/* Clear pid list */
++	for (i = 0; i < DRM_HASH_SIZE; i++) {
++		for (pt = dev->magiclist[i].head; pt; pt = next) {
+ 			next = pt->next;
+-			drm_free( pt, sizeof(*pt), DRM_MEM_MAGIC );
++			drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+ 		}
+ 		dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+ 	}
+ 
+-				/* Clear AGP information */
++	/* Clear AGP information */
+ 	if (drm_core_has_AGP(dev) && dev->agp) {
+ 		drm_agp_mem_t *entry;
+ 		drm_agp_mem_t *nexte;
+ 
+-				/* Remove AGP resources, but leave dev->agp
+-                                   intact until drv_cleanup is called. */
+-		for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
++		/* Remove AGP resources, but leave dev->agp
++		   intact until drv_cleanup is called. */
++		for (entry = dev->agp->memory; entry; entry = nexte) {
+ 			nexte = entry->next;
+-			if ( entry->bound ) drm_unbind_agp( entry->memory );
+-			drm_free_agp( entry->memory, entry->pages );
+-			drm_free( entry, sizeof(*entry), DRM_MEM_AGPLISTS );
++			if (entry->bound)
++				drm_unbind_agp(entry->memory);
++			drm_free_agp(entry->memory, entry->pages);
++			drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+ 		}
+ 		dev->agp->memory = NULL;
+ 
+ 		if (dev->agp->acquired)
+-		  drm_agp_release(dev);
++			drm_agp_release(dev);
+ 
+ 		dev->agp->acquired = 0;
+-		dev->agp->enabled  = 0;
++		dev->agp->enabled = 0;
+ 	}
+ 	if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
+ 		drm_sg_cleanup(dev->sg);
+ 		dev->sg = NULL;
+ 	}
+ 
+-				/* Clear vma list (only built for debugging) */
+-	if ( dev->vmalist ) {
+-		for ( vma = dev->vmalist ; vma ; vma = vma_next ) {
++	/* Clear vma list (only built for debugging) */
++	if (dev->vmalist) {
++		for (vma = dev->vmalist; vma; vma = vma_next) {
+ 			vma_next = vma->next;
+-			drm_free( vma, sizeof(*vma), DRM_MEM_VMAS );
++			drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
+ 		}
+ 		dev->vmalist = NULL;
+ 	}
+ 
+-	if( dev->maplist ) {
++	if (dev->maplist) {
+ 		while (!list_empty(&dev->maplist->head)) {
+ 			struct list_head *list = dev->maplist->head.next;
+ 			r_list = list_entry(list, drm_map_list_t, head);
+ 			drm_rmmap_locked(dev, r_list->map);
+ 		}
+- 	}
++	}
+ 
+-	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
+-		for ( i = 0 ; i < dev->queue_count ; i++ ) {
+-			if ( dev->queuelist[i] ) {
+-				drm_free( dev->queuelist[i],
+-					  sizeof(*dev->queuelist[0]),
+-					  DRM_MEM_QUEUES );
++	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) {
++		for (i = 0; i < dev->queue_count; i++) {
++			if (dev->queuelist[i]) {
++				drm_free(dev->queuelist[i],
++					 sizeof(*dev->queuelist[0]),
++					 DRM_MEM_QUEUES);
+ 				dev->queuelist[i] = NULL;
+ 			}
+ 		}
+-		drm_free( dev->queuelist,
+-			  dev->queue_slots * sizeof(*dev->queuelist),
+-			  DRM_MEM_QUEUES );
++		drm_free(dev->queuelist,
++			 dev->queue_slots * sizeof(*dev->queuelist),
++			 DRM_MEM_QUEUES);
+ 		dev->queuelist = NULL;
+ 	}
+ 	dev->queue_count = 0;
+ 
+ 	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+-		drm_dma_takedown( dev );
++		drm_dma_takedown(dev);
+ 
+-	if ( dev->lock.hw_lock ) {
+-		dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
++	if (dev->lock.hw_lock) {
++		dev->sigdata.lock = dev->lock.hw_lock = NULL;	/* SHM removed */
+ 		dev->lock.filp = NULL;
+-		wake_up_interruptible( &dev->lock.lock_queue );
++		wake_up_interruptible(&dev->lock.lock_queue);
+ 	}
+-	up( &dev->struct_sem );
++	up(&dev->struct_sem);
+ 
+ 	DRM_DEBUG("takedown completed\n");
+ 	return 0;
+ }
+ 
+-
+-
+ /**
+  * Module initialization. Called via init_module at module load time, or via
+  * linux/init/main.c (this is not currently supported).
+@@ -246,26 +246,28 @@ int drm_takedown( drm_device_t *dev )
+  * Initializes an array of drm_device structures, and attempts to
+  * initialize all available devices, using consecutive minors, registering the
+  * stubs and initializing the AGP device.
+- * 
++ *
+  * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
+  * after the initialization for driver customization.
+  */
+-int drm_init( struct drm_driver *driver )
++int drm_init(struct drm_driver *driver)
+ {
+ 	struct pci_dev *pdev = NULL;
+ 	struct pci_device_id *pid;
+ 	int i;
+ 
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	drm_mem_init();
+ 
+-	for (i=0; driver->pci_driver.id_table[i].vendor != 0; i++) {
++	for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
+ 		pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
+-		
+-		pdev=NULL;
+-		/* pass back in pdev to account for multiple identical cards */		
+-		while ((pdev = pci_get_subsys(pid->vendor, pid->device, pid->subvendor, pid->subdevice, pdev)) != NULL) {
++
++		pdev = NULL;
++		/* pass back in pdev to account for multiple identical cards */
++		while ((pdev =
++			pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
++				       pid->subdevice, pdev)) != NULL) {
+ 			/* stealth mode requires a manual probe */
+ 			pci_dev_get(pdev);
+ 			drm_get_dev(pdev, pid, driver);
+@@ -273,62 +275,63 @@ int drm_init( struct drm_driver *driver 
+ 	}
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_init);
+ 
+ /**
+  * Called via cleanup_module() at module unload time.
+  *
+  * Cleans up all DRM device, calling takedown().
+- * 
++ *
+  * \sa drm_init
+  */
+-static void drm_cleanup( drm_device_t *dev )
++static void drm_cleanup(drm_device_t * dev)
+ {
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	if (!dev) {
+ 		DRM_ERROR("cleanup called no dev\n");
+ 		return;
+ 	}
+ 
+-	drm_takedown( dev );	
++	drm_takedown(dev);
+ 
+ 	if (dev->maplist) {
+ 		drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
+ 		dev->maplist = NULL;
+ 	}
+ 
+-	drm_ctxbitmap_cleanup( dev );
+-	
++	drm_ctxbitmap_cleanup(dev);
++
+ 	if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
+ 	    dev->agp && dev->agp->agp_mtrr >= 0) {
+ 		int retval;
+-		retval = mtrr_del( dev->agp->agp_mtrr,
+-				   dev->agp->agp_info.aper_base,
+-				   dev->agp->agp_info.aper_size*1024*1024 );
+-		DRM_DEBUG( "mtrr_del=%d\n", retval );
+-	}
+-	
+-	if (drm_core_has_AGP(dev) && dev->agp ) {
+-		drm_free( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
++		retval = mtrr_del(dev->agp->agp_mtrr,
++				  dev->agp->agp_info.aper_base,
++				  dev->agp->agp_info.aper_size * 1024 * 1024);
++		DRM_DEBUG("mtrr_del=%d\n", retval);
++	}
++
++	if (drm_core_has_AGP(dev) && dev->agp) {
++		drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
+ 		dev->agp = NULL;
+ 	}
+ 
+ 	if (dev->driver->postcleanup)
+ 		dev->driver->postcleanup(dev);
+-	
++
+ 	drm_put_head(&dev->primary);
+-	if ( drm_put_dev(dev) )
+-		DRM_ERROR( "Cannot unload module\n" );
++	if (drm_put_dev(dev))
++		DRM_ERROR("Cannot unload module\n");
+ }
+ 
+-void drm_exit (struct drm_driver *driver)
++void drm_exit(struct drm_driver *driver)
+ {
+ 	int i;
+ 	drm_device_t *dev = NULL;
+ 	drm_head_t *head;
+-	
+-	DRM_DEBUG( "\n" );
++
++	DRM_DEBUG("\n");
+ 
+ 	for (i = 0; i < drm_cards_limit; i++) {
+ 		head = drm_heads[i];
+@@ -336,9 +339,9 @@ void drm_exit (struct drm_driver *driver
+ 			continue;
+ 		if (!head->dev)
+ 			continue;
+-		if (head->dev->driver!=driver)
++		if (head->dev->driver != driver)
+ 			continue;
+-		dev=head->dev;
++		dev = head->dev;
+ 	}
+ 	if (dev) {
+ 		/* release the pci driver */
+@@ -346,32 +349,35 @@ void drm_exit (struct drm_driver *driver
+ 			pci_dev_put(dev->pdev);
+ 		drm_cleanup(dev);
+ 	}
+-	DRM_INFO( "Module unloaded\n" );
++	DRM_INFO("Module unloaded\n");
+ }
++
+ EXPORT_SYMBOL(drm_exit);
+ 
+ /** File operations structure */
+ static struct file_operations drm_stub_fops = {
+ 	.owner = THIS_MODULE,
+-	.open  = drm_stub_open
++	.open = drm_stub_open
+ };
+ 
+ static int __init drm_core_init(void)
+ {
+ 	int ret = -ENOMEM;
+-	
+-	drm_cards_limit = (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
+-	drm_heads = drm_calloc(drm_cards_limit,
+-				sizeof(*drm_heads), DRM_MEM_STUB);
+-	if(!drm_heads) 
++
++	drm_cards_limit =
++	    (drm_cards_limit <
++	     DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
++	drm_heads =
++	    drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB);
++	if (!drm_heads)
+ 		goto err_p1;
+-	
++
+ 	if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
+ 		goto err_p1;
+-	
++
+ 	drm_class = drm_sysfs_create(THIS_MODULE, "drm");
+ 	if (IS_ERR(drm_class)) {
+-		printk (KERN_ERR "DRM: Error creating drm class.\n");
++		printk(KERN_ERR "DRM: Error creating drm class.\n");
+ 		ret = PTR_ERR(drm_class);
+ 		goto err_p2;
+ 	}
+@@ -382,35 +388,31 @@ static int __init drm_core_init(void)
+ 		ret = -1;
+ 		goto err_p3;
+ 	}
+-		
+-	DRM_INFO( "Initialized %s %d.%d.%d %s\n",
+-		CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL,
+-		CORE_DATE);
++
++	DRM_INFO("Initialized %s %d.%d.%d %s\n",
++		 CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
+ 	return 0;
+-err_p3:
++      err_p3:
+ 	drm_sysfs_destroy(drm_class);
+-err_p2:
++      err_p2:
+ 	unregister_chrdev(DRM_MAJOR, "drm");
+ 	drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
+-err_p1:	
++      err_p1:
+ 	return ret;
+ }
+ 
+-static void __exit drm_core_exit (void)
++static void __exit drm_core_exit(void)
+ {
+ 	remove_proc_entry("dri", NULL);
+ 	drm_sysfs_destroy(drm_class);
+ 
+ 	unregister_chrdev(DRM_MAJOR, "drm");
+ 
+-	drm_free(drm_heads, sizeof(*drm_heads) *
+-				drm_cards_limit, DRM_MEM_STUB);
++	drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
+ }
+ 
+-
+-module_init( drm_core_init );
+-module_exit( drm_core_exit );
+-
++module_init(drm_core_init);
++module_exit(drm_core_exit);
+ 
+ /**
+  * Get version information
+@@ -423,8 +425,8 @@ module_exit( drm_core_exit );
+  *
+  * Fills in the version information in \p arg.
+  */
+-static int drm_version( struct inode *inode, struct file *filp,
+-			unsigned int cmd, unsigned long arg )
++static int drm_version(struct inode *inode, struct file *filp,
++		       unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -432,21 +434,19 @@ static int drm_version( struct inode *in
+ 	drm_version_t version;
+ 	int ret;
+ 
+-	if ( copy_from_user( &version, argp, sizeof(version) ) )
++	if (copy_from_user(&version, argp, sizeof(version)))
+ 		return -EFAULT;
+ 
+ 	/* version is a required function to return the personality module version */
+ 	if ((ret = dev->driver->version(&version)))
+ 		return ret;
+-		
+-	if ( copy_to_user( argp, &version, sizeof(version) ) )
++
++	if (copy_to_user(argp, &version, sizeof(version)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+ 
+-
+-
+-/** 
++/**
+  * Called whenever a process performs an ioctl on /dev/drm.
+  *
+  * \param inode device inode.
+@@ -458,8 +458,8 @@ static int drm_version( struct inode *in
+  * Looks up the ioctl function in the ::ioctls table, checking for root
+  * previleges if so required, and dispatches to the respective function.
+  */
+-int drm_ioctl( struct inode *inode, struct file *filp,
+-		unsigned int cmd, unsigned long arg )
++int drm_ioctl(struct inode *inode, struct file *filp,
++	      unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -468,40 +468,43 @@ int drm_ioctl( struct inode *inode, stru
+ 	unsigned int nr = DRM_IOCTL_NR(cmd);
+ 	int retcode = -EINVAL;
+ 
+-	atomic_inc( &dev->ioctl_count );
+-	atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
++	atomic_inc(&dev->ioctl_count);
++	atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
+ 	++priv->ioctl_count;
+ 
+-	DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
+-		   current->pid, cmd, nr, (long)old_encode_dev(priv->head->device), 
+-		   priv->authenticated );
+-	
++	DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
++		  current->pid, cmd, nr,
++		  (long)old_encode_dev(priv->head->device),
++		  priv->authenticated);
++
+ 	if (nr < DRIVER_IOCTL_COUNT)
+ 		ioctl = &drm_ioctls[nr];
+-	else if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
++	else if ((nr >= DRM_COMMAND_BASE)
++		 && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
+ 		ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
+ 	else
+ 		goto err_i1;
+-	
++
+ 	func = ioctl->func;
+ 	/* is there a local override? */
+ 	if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl)
+ 		func = dev->driver->dma_ioctl;
+-	
+-	if ( !func ) {
+-		DRM_DEBUG( "no function\n" );
++
++	if (!func) {
++		DRM_DEBUG("no function\n");
+ 		retcode = -EINVAL;
+-	} else if ( ( ioctl->root_only && !capable( CAP_SYS_ADMIN ) )||
+-		    ( ioctl->auth_needed && !priv->authenticated ) ) {
++	} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) ||
++		   (ioctl->auth_needed && !priv->authenticated)) {
+ 		retcode = -EACCES;
+ 	} else {
+-		retcode = func( inode, filp, cmd, arg );
++		retcode = func(inode, filp, cmd, arg);
+ 	}
+-	
+-err_i1:
+-	atomic_dec( &dev->ioctl_count );
+-	if (retcode) DRM_DEBUG( "ret = %x\n", retcode);
++
++      err_i1:
++	atomic_dec(&dev->ioctl_count);
++	if (retcode)
++		DRM_DEBUG("ret = %x\n", retcode);
+ 	return retcode;
+ }
+-EXPORT_SYMBOL(drm_ioctl);
+ 
++EXPORT_SYMBOL(drm_ioctl);
+diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
+--- a/drivers/char/drm/drm_fops.c
++++ b/drivers/char/drm/drm_fops.c
+@@ -1,7 +1,7 @@
+ /**
+- * \file drm_fops.h 
++ * \file drm_fops.c
+  * File operations for DRM
+- * 
++ *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Daryll Strauss <daryll at valinux.com>
+  * \author Gareth Hughes <gareth at valinux.com>
+@@ -37,49 +37,48 @@
+ #include "drmP.h"
+ #include <linux/poll.h>
+ 
+-static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev);
++static int drm_open_helper(struct inode *inode, struct file *filp,
++			   drm_device_t * dev);
+ 
+-static int drm_setup( drm_device_t *dev )
++static int drm_setup(drm_device_t * dev)
+ {
+ 	int i;
+ 	int ret;
+ 
+-	if (dev->driver->presetup)
+-	{
+-		ret=dev->driver->presetup(dev);
+-		if (ret!=0) 
++	if (dev->driver->presetup) {
++		ret = dev->driver->presetup(dev);
++		if (ret != 0)
+ 			return ret;
+ 	}
+ 
+-	atomic_set( &dev->ioctl_count, 0 );
+-	atomic_set( &dev->vma_count, 0 );
++	atomic_set(&dev->ioctl_count, 0);
++	atomic_set(&dev->vma_count, 0);
+ 	dev->buf_use = 0;
+-	atomic_set( &dev->buf_alloc, 0 );
++	atomic_set(&dev->buf_alloc, 0);
+ 
+-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+-	{
+-		i = drm_dma_setup( dev );
+-		if ( i < 0 )
++	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) {
++		i = drm_dma_setup(dev);
++		if (i < 0)
+ 			return i;
+ 	}
+ 
+-	for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
+-		atomic_set( &dev->counts[i], 0 );
++	for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++)
++		atomic_set(&dev->counts[i], 0);
+ 
+-	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
++	for (i = 0; i < DRM_HASH_SIZE; i++) {
+ 		dev->magiclist[i].head = NULL;
+ 		dev->magiclist[i].tail = NULL;
+ 	}
+ 
+-	dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
+-				  DRM_MEM_CTXLIST);
+-	if(dev->ctxlist == NULL) return -ENOMEM;
++	dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST);
++	if (dev->ctxlist == NULL)
++		return -ENOMEM;
+ 	memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
+ 	INIT_LIST_HEAD(&dev->ctxlist->head);
+ 
+ 	dev->vmalist = NULL;
+ 	dev->sigdata.lock = dev->lock.hw_lock = NULL;
+-	init_waitqueue_head( &dev->lock.lock_queue );
++	init_waitqueue_head(&dev->lock.lock_queue);
+ 	dev->queue_count = 0;
+ 	dev->queue_reserved = 0;
+ 	dev->queue_slots = 0;
+@@ -91,24 +90,21 @@ static int drm_setup( drm_device_t *dev 
+ 	dev->last_context = 0;
+ 	dev->last_switch = 0;
+ 	dev->last_checked = 0;
+-	init_waitqueue_head( &dev->context_wait );
++	init_waitqueue_head(&dev->context_wait);
+ 	dev->if_version = 0;
+ 
+ 	dev->ctx_start = 0;
+ 	dev->lck_start = 0;
+ 
+-	dev->buf_rp = dev->buf;
+-	dev->buf_wp = dev->buf;
+-	dev->buf_end = dev->buf + DRM_BSZ;
+ 	dev->buf_async = NULL;
+-	init_waitqueue_head( &dev->buf_readers );
+-	init_waitqueue_head( &dev->buf_writers );
++	init_waitqueue_head(&dev->buf_readers);
++	init_waitqueue_head(&dev->buf_writers);
+ 
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	/*
+ 	 * The kernel's context could be created here, but is now created
+-	 * in drm_dma_enqueue.	This is more resource-efficient for
++	 * in drm_dma_enqueue.  This is more resource-efficient for
+ 	 * hardware that does not do DMA, but may mean that
+ 	 * drm_select_queue fails between the time the interrupt is
+ 	 * initialized and the time the queues are initialized.
+@@ -121,7 +117,7 @@ static int drm_setup( drm_device_t *dev 
+ 
+ /**
+  * Open file.
+- * 
++ *
+  * \param inode device inode
+  * \param filp file pointer.
+  * \return zero on success or a negative number on failure.
+@@ -130,7 +126,7 @@ static int drm_setup( drm_device_t *dev 
+  * increments the device open count. If the open count was previous at zero,
+  * i.e., it's the first that the device is open, then calls setup().
+  */
+-int drm_open( struct inode *inode, struct file *filp )
++int drm_open(struct inode *inode, struct file *filp)
+ {
+ 	drm_device_t *dev = NULL;
+ 	int minor = iminor(inode);
+@@ -138,26 +134,27 @@ int drm_open( struct inode *inode, struc
+ 
+ 	if (!((minor >= 0) && (minor < drm_cards_limit)))
+ 		return -ENODEV;
+-		
++
+ 	if (!drm_heads[minor])
+ 		return -ENODEV;
+ 
+ 	if (!(dev = drm_heads[minor]->dev))
+ 		return -ENODEV;
+-	
+-	retcode = drm_open_helper( inode, filp, dev );
+-	if ( !retcode ) {
+-		atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
+-		spin_lock( &dev->count_lock );
+-		if ( !dev->open_count++ ) {
+-			spin_unlock( &dev->count_lock );
+-			return drm_setup( dev );
++
++	retcode = drm_open_helper(inode, filp, dev);
++	if (!retcode) {
++		atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
++		spin_lock(&dev->count_lock);
++		if (!dev->open_count++) {
++			spin_unlock(&dev->count_lock);
++			return drm_setup(dev);
+ 		}
+-		spin_unlock( &dev->count_lock );
++		spin_unlock(&dev->count_lock);
+ 	}
+ 
+ 	return retcode;
+ }
++
+ EXPORT_SYMBOL(drm_open);
+ 
+ /**
+@@ -172,7 +169,7 @@ EXPORT_SYMBOL(drm_open);
+  * data from its list and free it. Decreases the open count and if it reaches
+  * zero calls takedown().
+  */
+-int drm_release( struct inode *inode, struct file *filp )
++int drm_release(struct inode *inode, struct file *filp)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev;
+@@ -181,7 +178,7 @@ int drm_release( struct inode *inode, st
+ 	lock_kernel();
+ 	dev = priv->head->dev;
+ 
+-	DRM_DEBUG( "open_count = %d\n", dev->open_count );
++	DRM_DEBUG("open_count = %d\n", dev->open_count);
+ 
+ 	if (dev->driver->prerelease)
+ 		dev->driver->prerelease(dev, filp);
+@@ -190,194 +187,199 @@ int drm_release( struct inode *inode, st
+ 	 * Begin inline drm_release
+ 	 */
+ 
+-	DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
+-		   current->pid, (long)old_encode_dev(priv->head->device), dev->open_count );
++	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
++		  current->pid, (long)old_encode_dev(priv->head->device),
++		  dev->open_count);
++
++	if (priv->lock_count && dev->lock.hw_lock &&
++	    _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
++	    dev->lock.filp == filp) {
++		DRM_DEBUG("File %p released, freeing lock for context %d\n",
++			  filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ 
+-	if ( priv->lock_count && dev->lock.hw_lock &&
+-	     _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+-	     dev->lock.filp == filp ) {
+-		DRM_DEBUG( "File %p released, freeing lock for context %d\n",
+-			filp,
+-			_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+-		
+ 		if (dev->driver->release)
+ 			dev->driver->release(dev, filp);
+ 
+-		drm_lock_free( dev, &dev->lock.hw_lock->lock,
+-				_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
++		drm_lock_free(dev, &dev->lock.hw_lock->lock,
++			      _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ 
+-				/* FIXME: may require heavy-handed reset of
+-                                   hardware at this point, possibly
+-                                   processed via a callback to the X
+-                                   server. */
+-	}
+-	else if ( dev->driver->release && priv->lock_count && dev->lock.hw_lock ) {
++		/* FIXME: may require heavy-handed reset of
++		   hardware at this point, possibly
++		   processed via a callback to the X
++		   server. */
++	} else if (dev->driver->release && priv->lock_count
++		   && dev->lock.hw_lock) {
+ 		/* The lock is required to reclaim buffers */
+-		DECLARE_WAITQUEUE( entry, current );
++		DECLARE_WAITQUEUE(entry, current);
+ 
+-		add_wait_queue( &dev->lock.lock_queue, &entry );
++		add_wait_queue(&dev->lock.lock_queue, &entry);
+ 		for (;;) {
+ 			__set_current_state(TASK_INTERRUPTIBLE);
+-			if ( !dev->lock.hw_lock ) {
++			if (!dev->lock.hw_lock) {
+ 				/* Device has been unregistered */
+ 				retcode = -EINTR;
+ 				break;
+ 			}
+-			if ( drm_lock_take( &dev->lock.hw_lock->lock,
+-					     DRM_KERNEL_CONTEXT ) ) {
+-				dev->lock.filp	    = filp;
++			if (drm_lock_take(&dev->lock.hw_lock->lock,
++					  DRM_KERNEL_CONTEXT)) {
++				dev->lock.filp = filp;
+ 				dev->lock.lock_time = jiffies;
+-                                atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
++				atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
+ 				break;	/* Got lock */
+ 			}
+-				/* Contention */
++			/* Contention */
+ 			schedule();
+-			if ( signal_pending( current ) ) {
++			if (signal_pending(current)) {
+ 				retcode = -ERESTARTSYS;
+ 				break;
+ 			}
+ 		}
+ 		__set_current_state(TASK_RUNNING);
+-		remove_wait_queue( &dev->lock.lock_queue, &entry );
+-		if( !retcode ) {
++		remove_wait_queue(&dev->lock.lock_queue, &entry);
++		if (!retcode) {
+ 			if (dev->driver->release)
+ 				dev->driver->release(dev, filp);
+-			drm_lock_free( dev, &dev->lock.hw_lock->lock,
+-					DRM_KERNEL_CONTEXT );
++			drm_lock_free(dev, &dev->lock.hw_lock->lock,
++				      DRM_KERNEL_CONTEXT);
+ 		}
+ 	}
+-	
+-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !dev->driver->release)
+-	{
++
++	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)
++	    && !dev->driver->release) {
+ 		dev->driver->reclaim_buffers(dev, filp);
+ 	}
+ 
+-	drm_fasync( -1, filp, 0 );
++	drm_fasync(-1, filp, 0);
+ 
+-	down( &dev->ctxlist_sem );
+-	if ( dev->ctxlist && (!list_empty(&dev->ctxlist->head))) {
++	down(&dev->ctxlist_sem);
++	if (dev->ctxlist && (!list_empty(&dev->ctxlist->head))) {
+ 		drm_ctx_list_t *pos, *n;
+ 
+-		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+-			if ( pos->tag == priv &&
+-			     pos->handle != DRM_KERNEL_CONTEXT ) {
++		list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) {
++			if (pos->tag == priv &&
++			    pos->handle != DRM_KERNEL_CONTEXT) {
+ 				if (dev->driver->context_dtor)
+-					dev->driver->context_dtor(dev, pos->handle);
++					dev->driver->context_dtor(dev,
++								  pos->handle);
+ 
+-				drm_ctxbitmap_free( dev, pos->handle );
++				drm_ctxbitmap_free(dev, pos->handle);
+ 
+-				list_del( &pos->head );
+-				drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
++				list_del(&pos->head);
++				drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
+ 				--dev->ctx_count;
+ 			}
+ 		}
+ 	}
+-	up( &dev->ctxlist_sem );
++	up(&dev->ctxlist_sem);
+ 
+-	down( &dev->struct_sem );
+-	if ( priv->remove_auth_on_close == 1 ) {
++	down(&dev->struct_sem);
++	if (priv->remove_auth_on_close == 1) {
+ 		drm_file_t *temp = dev->file_first;
+-		while ( temp ) {
++		while (temp) {
+ 			temp->authenticated = 0;
+ 			temp = temp->next;
+ 		}
+ 	}
+-	if ( priv->prev ) {
++	if (priv->prev) {
+ 		priv->prev->next = priv->next;
+ 	} else {
+-		dev->file_first	 = priv->next;
++		dev->file_first = priv->next;
+ 	}
+-	if ( priv->next ) {
++	if (priv->next) {
+ 		priv->next->prev = priv->prev;
+ 	} else {
+-		dev->file_last	 = priv->prev;
++		dev->file_last = priv->prev;
+ 	}
+-	up( &dev->struct_sem );
+-	
++	up(&dev->struct_sem);
++
+ 	if (dev->driver->free_filp_priv)
+ 		dev->driver->free_filp_priv(dev, priv);
+ 
+-	drm_free( priv, sizeof(*priv), DRM_MEM_FILES );
++	drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+ 
+ 	/* ========================================================
+ 	 * End inline drm_release
+ 	 */
+ 
+-	atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
+-	spin_lock( &dev->count_lock );
+-	if ( !--dev->open_count ) {
+-		if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
+-			DRM_ERROR( "Device busy: %d %d\n",
+-				   atomic_read( &dev->ioctl_count ),
+-				   dev->blocked );
+-			spin_unlock( &dev->count_lock );
++	atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
++	spin_lock(&dev->count_lock);
++	if (!--dev->open_count) {
++		if (atomic_read(&dev->ioctl_count) || dev->blocked) {
++			DRM_ERROR("Device busy: %d %d\n",
++				  atomic_read(&dev->ioctl_count), dev->blocked);
++			spin_unlock(&dev->count_lock);
+ 			unlock_kernel();
+ 			return -EBUSY;
+ 		}
+-		spin_unlock( &dev->count_lock );
++		spin_unlock(&dev->count_lock);
+ 		unlock_kernel();
+-		return drm_takedown( dev );
++		return drm_takedown(dev);
+ 	}
+-	spin_unlock( &dev->count_lock );
++	spin_unlock(&dev->count_lock);
+ 
+ 	unlock_kernel();
+ 
+ 	return retcode;
+ }
++
+ EXPORT_SYMBOL(drm_release);
+ 
+ /**
+- * Called whenever a process opens /dev/drm. 
++ * Called whenever a process opens /dev/drm.
+  *
+  * \param inode device inode.
+  * \param filp file pointer.
+  * \param dev device.
+  * \return zero on success or a negative number on failure.
+- * 
++ *
+  * Creates and initializes a drm_file structure for the file private data in \p
+  * filp and add it into the double linked list in \p dev.
+  */
+-static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
++static int drm_open_helper(struct inode *inode, struct file *filp,
++			   drm_device_t * dev)
+ {
+-	int	     minor = iminor(inode);
+-	drm_file_t   *priv;
++	int minor = iminor(inode);
++	drm_file_t *priv;
+ 	int ret;
+ 
+-	if (filp->f_flags & O_EXCL)   return -EBUSY; /* No exclusive opens */
+-	if (!drm_cpu_valid())        return -EINVAL;
++	if (filp->f_flags & O_EXCL)
++		return -EBUSY;	/* No exclusive opens */
++	if (!drm_cpu_valid())
++		return -EINVAL;
+ 
+ 	DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+ 
+-	priv		    = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+-	if(!priv) return -ENOMEM;
++	priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
++	if (!priv)
++		return -ENOMEM;
+ 
+ 	memset(priv, 0, sizeof(*priv));
+-	filp->private_data  = priv;
+-	priv->uid	    = current->euid;
+-	priv->pid	    = current->pid;
+-	priv->minor	    = minor;
+-	priv->head          = drm_heads[minor];
+-	priv->ioctl_count   = 0;
++	filp->private_data = priv;
++	priv->uid = current->euid;
++	priv->pid = current->pid;
++	priv->minor = minor;
++	priv->head = drm_heads[minor];
++	priv->ioctl_count = 0;
+ 	priv->authenticated = capable(CAP_SYS_ADMIN);
+-	priv->lock_count    = 0;
++	priv->lock_count = 0;
+ 
+ 	if (dev->driver->open_helper) {
+-		ret=dev->driver->open_helper(dev, priv);
++		ret = dev->driver->open_helper(dev, priv);
+ 		if (ret < 0)
+ 			goto out_free;
+ 	}
+ 
+ 	down(&dev->struct_sem);
+ 	if (!dev->file_last) {
+-		priv->next	= NULL;
+-		priv->prev	= NULL;
++		priv->next = NULL;
++		priv->prev = NULL;
+ 		dev->file_first = priv;
+-		dev->file_last	= priv;
++		dev->file_last = priv;
+ 	} else {
+-		priv->next	     = NULL;
+-		priv->prev	     = dev->file_last;
++		priv->next = NULL;
++		priv->prev = dev->file_last;
+ 		dev->file_last->next = priv;
+-		dev->file_last	     = priv;
++		dev->file_last = priv;
+ 	}
+ 	up(&dev->struct_sem);
+ 
+@@ -394,42 +396,48 @@ static int drm_open_helper(struct inode 
+ 		}
+ 		if (!dev->hose) {
+ 			struct pci_bus *b = pci_bus_b(pci_root_buses.next);
+-			if (b) dev->hose = b->sysdata;
++			if (b)
++				dev->hose = b->sysdata;
+ 		}
+ 	}
+ #endif
+ 
+ 	return 0;
+-out_free:
++      out_free:
+ 	drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+-	filp->private_data=NULL;
++	filp->private_data = NULL;
+ 	return ret;
+ }
+ 
+ /** No-op. */
+ int drm_flush(struct file *filp)
+ {
+-	drm_file_t    *priv   = filp->private_data;
+-	drm_device_t  *dev    = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 
+ 	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
+-		  current->pid, (long)old_encode_dev(priv->head->device), dev->open_count);
++		  current->pid, (long)old_encode_dev(priv->head->device),
++		  dev->open_count);
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_flush);
+ 
+ /** No-op. */
+ int drm_fasync(int fd, struct file *filp, int on)
+ {
+-	drm_file_t    *priv   = filp->private_data;
+-	drm_device_t  *dev    = priv->head->dev;
+-	int	      retcode;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	int retcode;
+ 
+-	DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(priv->head->device));
++	DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
++		  (long)old_encode_dev(priv->head->device));
+ 	retcode = fasync_helper(fd, filp, on, &dev->buf_async);
+-	if (retcode < 0) return retcode;
++	if (retcode < 0)
++		return retcode;
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_fasync);
+ 
+ /** No-op. */
+@@ -437,5 +445,5 @@ unsigned int drm_poll(struct file *filp,
+ {
+ 	return 0;
+ }
+-EXPORT_SYMBOL(drm_poll);
+ 
++EXPORT_SYMBOL(drm_poll);
+diff --git a/drivers/char/drm/drm_init.c b/drivers/char/drm/drm_init.c
+--- a/drivers/char/drm/drm_init.c
++++ b/drivers/char/drm/drm_init.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_init.h 
++ * \file drm_init.c
+  * Setup/Cleanup for DRM
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+@@ -43,10 +43,11 @@
+ int drm_cpu_valid(void)
+ {
+ #if defined(__i386__)
+-	if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
++	if (boot_cpu_data.x86 == 3)
++		return 0;	/* No cmpxchg on a 386 */
+ #endif
+ #if defined(__sparc__) && !defined(__sparc_v9__)
+-	return 0; /* No cmpxchg before v9 sparc. */
++	return 0;		/* No cmpxchg before v9 sparc. */
+ #endif
+ 	return 1;
+ }
+diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c
+--- a/drivers/char/drm/drm_ioc32.c
++++ b/drivers/char/drm/drm_ioc32.c
+@@ -68,15 +68,15 @@
+ #define DRM_IOCTL_WAIT_VBLANK32		DRM_IOWR(0x3a, drm_wait_vblank32_t)
+ 
+ typedef struct drm_version_32 {
+-	int	version_major;	  /**< Major version */
+-	int	version_minor;	  /**< Minor version */
+-	int	version_patchlevel;/**< Patch level */
+-	u32	name_len;	  /**< Length of name buffer */
+-	u32	name;		  /**< Name of driver */
+-	u32	date_len;	  /**< Length of date buffer */
+-	u32	date;		  /**< User-space buffer to hold date */
+-	u32	desc_len;	  /**< Length of desc buffer */
+-	u32	desc;		  /**< User-space buffer to hold desc */
++	int version_major;	  /**< Major version */
++	int version_minor;	  /**< Minor version */
++	int version_patchlevel;	   /**< Patch level */
++	u32 name_len;		  /**< Length of name buffer */
++	u32 name;		  /**< Name of driver */
++	u32 date_len;		  /**< Length of date buffer */
++	u32 date;		  /**< User-space buffer to hold date */
++	u32 desc_len;		  /**< Length of desc buffer */
++	u32 desc;		  /**< User-space buffer to hold desc */
+ } drm_version32_t;
+ 
+ static int compat_drm_version(struct file *file, unsigned int cmd,
+@@ -86,7 +86,7 @@ static int compat_drm_version(struct fil
+ 	drm_version_t __user *version;
+ 	int err;
+ 
+-	if (copy_from_user(&v32, (void __user *) arg, sizeof(v32)))
++	if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
+ 		return -EFAULT;
+ 
+ 	version = compat_alloc_user_space(sizeof(*version));
+@@ -104,7 +104,7 @@ static int compat_drm_version(struct fil
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_VERSION, (unsigned long) version);
++			DRM_IOCTL_VERSION, (unsigned long)version);
+ 	if (err)
+ 		return err;
+ 
+@@ -116,7 +116,7 @@ static int compat_drm_version(struct fil
+ 	    || __get_user(v32.desc_len, &version->desc_len))
+ 		return -EFAULT;
+ 
+-	if (copy_to_user((void __user *) arg, &v32, sizeof(v32)))
++	if (copy_to_user((void __user *)arg, &v32, sizeof(v32)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+@@ -133,25 +133,25 @@ static int compat_drm_getunique(struct f
+ 	drm_unique_t __user *u;
+ 	int err;
+ 
+-	if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
++	if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
+ 		return -EFAULT;
+ 
+ 	u = compat_alloc_user_space(sizeof(*u));
+ 	if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
+ 		return -EFAULT;
+ 	if (__put_user(uq32.unique_len, &u->unique_len)
+-	    || __put_user((void __user *)(unsigned long) uq32.unique,
++	    || __put_user((void __user *)(unsigned long)uq32.unique,
+ 			  &u->unique))
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_GET_UNIQUE, (unsigned long) u);
++			DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
+ 	if (err)
+ 		return err;
+ 
+ 	if (__get_user(uq32.unique_len, &u->unique_len))
+ 		return -EFAULT;
+-	if (copy_to_user((void __user *) arg, &uq32, sizeof(uq32)))
++	if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+@@ -162,28 +162,28 @@ static int compat_drm_setunique(struct f
+ 	drm_unique32_t uq32;
+ 	drm_unique_t __user *u;
+ 
+-	if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
++	if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
+ 		return -EFAULT;
+ 
+ 	u = compat_alloc_user_space(sizeof(*u));
+ 	if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
+ 		return -EFAULT;
+ 	if (__put_user(uq32.unique_len, &u->unique_len)
+-	    || __put_user((void __user *)(unsigned long) uq32.unique,
++	    || __put_user((void __user *)(unsigned long)uq32.unique,
+ 			  &u->unique))
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_SET_UNIQUE, (unsigned long) u);
++			 DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
+ }
+ 
+ typedef struct drm_map32 {
+-	u32	offset;	 	/**< Requested physical address (0 for SAREA)*/
+-	u32	size;	 	/**< Requested physical size (bytes) */
+-	drm_map_type_t	type;	/**< Type of memory to map */
++	u32 offset;		/**< Requested physical address (0 for SAREA)*/
++	u32 size;		/**< Requested physical size (bytes) */
++	drm_map_type_t type;	/**< Type of memory to map */
+ 	drm_map_flags_t flags;	/**< Flags */
+-	u32	handle;		/**< User-space: "Handle" to pass to mmap() */
+-	int	mtrr;		/**< MTRR slot used */
++	u32 handle;		/**< User-space: "Handle" to pass to mmap() */
++	int mtrr;		/**< MTRR slot used */
+ } drm_map32_t;
+ 
+ static int compat_drm_getmap(struct file *file, unsigned int cmd,
+@@ -205,7 +205,7 @@ static int compat_drm_getmap(struct file
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_GET_MAP, (unsigned long) map);
++			DRM_IOCTL_GET_MAP, (unsigned long)map);
+ 	if (err)
+ 		return err;
+ 
+@@ -217,7 +217,7 @@ static int compat_drm_getmap(struct file
+ 	    || __get_user(m32.mtrr, &map->mtrr))
+ 		return -EFAULT;
+ 
+-	m32.handle = (unsigned long) handle;
++	m32.handle = (unsigned long)handle;
+ 	if (copy_to_user(argp, &m32, sizeof(m32)))
+ 		return -EFAULT;
+ 	return 0;
+@@ -246,7 +246,7 @@ static int compat_drm_addmap(struct file
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_ADD_MAP, (unsigned long) map);
++			DRM_IOCTL_ADD_MAP, (unsigned long)map);
+ 	if (err)
+ 		return err;
+ 
+@@ -255,8 +255,8 @@ static int compat_drm_addmap(struct file
+ 	    || __get_user(handle, &map->handle))
+ 		return -EFAULT;
+ 
+-	m32.handle = (unsigned long) handle;
+-	if (m32.handle != (unsigned long) handle && printk_ratelimit())
++	m32.handle = (unsigned long)handle;
++	if (m32.handle != (unsigned long)handle && printk_ratelimit())
+ 		printk(KERN_ERR "compat_drm_addmap truncated handle"
+ 		       " %p for type %d offset %x\n",
+ 		       handle, m32.type, m32.offset);
+@@ -280,20 +280,20 @@ static int compat_drm_rmmap(struct file 
+ 	map = compat_alloc_user_space(sizeof(*map));
+ 	if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
+ 		return -EFAULT;
+-	if (__put_user((void *)(unsigned long) handle, &map->handle))
++	if (__put_user((void *)(unsigned long)handle, &map->handle))
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RM_MAP, (unsigned long) map);
++			 DRM_IOCTL_RM_MAP, (unsigned long)map);
+ }
+ 
+ typedef struct drm_client32 {
+-	int	idx;	/**< Which client desired? */
+-	int	auth;	/**< Is client authenticated? */
+-	u32	pid;	/**< Process ID */
+-	u32	uid;	/**< User ID */
+-	u32	magic;	/**< Magic */
+-	u32	iocs;	/**< Ioctl count */
++	int idx;	/**< Which client desired? */
++	int auth;	/**< Is client authenticated? */
++	u32 pid;	/**< Process ID */
++	u32 uid;	/**< User ID */
++	u32 magic;	/**< Magic */
++	u32 iocs;	/**< Ioctl count */
+ } drm_client32_t;
+ 
+ static int compat_drm_getclient(struct file *file, unsigned int cmd,
+@@ -314,7 +314,7 @@ static int compat_drm_getclient(struct f
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_GET_CLIENT, (unsigned long) client);
++			DRM_IOCTL_GET_CLIENT, (unsigned long)client);
+ 	if (err)
+ 		return err;
+ 
+@@ -351,7 +351,7 @@ static int compat_drm_getstats(struct fi
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_GET_STATS, (unsigned long) stats);
++			DRM_IOCTL_GET_STATS, (unsigned long)stats);
+ 	if (err)
+ 		return err;
+ 
+@@ -368,12 +368,12 @@ static int compat_drm_getstats(struct fi
+ }
+ 
+ typedef struct drm_buf_desc32 {
+-	int	      count;	 /**< Number of buffers of this size */
+-	int	      size;	 /**< Size in bytes */
+-	int	      low_mark;	 /**< Low water mark */
+-	int	      high_mark; /**< High water mark */
+-	int	      flags;
+-	u32	      agp_start; /**< Start address in the AGP aperture */
++	int count;		 /**< Number of buffers of this size */
++	int size;		 /**< Size in bytes */
++	int low_mark;		 /**< Low water mark */
++	int high_mark;		 /**< High water mark */
++	int flags;
++	u32 agp_start;		 /**< Start address in the AGP aperture */
+ } drm_buf_desc32_t;
+ 
+ static int compat_drm_addbufs(struct file *file, unsigned int cmd,
+@@ -395,7 +395,7 @@ static int compat_drm_addbufs(struct fil
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_ADD_BUFS, (unsigned long) buf);
++			DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
+ 	if (err)
+ 		return err;
+ 
+@@ -427,12 +427,12 @@ static int compat_drm_markbufs(struct fi
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_MARK_BUFS, (unsigned long) buf);
++			 DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
+ }
+ 
+ typedef struct drm_buf_info32 {
+-	int	       count;	/**< Entries in list */
+-	u32	       list;
++	int count;		/**< Entries in list */
++	u32 list;
+ } drm_buf_info32_t;
+ 
+ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
+@@ -451,7 +451,7 @@ static int compat_drm_infobufs(struct fi
+ 		return -EFAULT;
+ 
+ 	count = req32.count;
+-	to = (drm_buf_desc32_t __user *)(unsigned long) req32.list;
++	to = (drm_buf_desc32_t __user *) (unsigned long)req32.list;
+ 	if (count < 0)
+ 		count = 0;
+ 	if (count > 0
+@@ -469,7 +469,7 @@ static int compat_drm_infobufs(struct fi
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_INFO_BUFS, (unsigned long) request);
++			DRM_IOCTL_INFO_BUFS, (unsigned long)request);
+ 	if (err)
+ 		return err;
+ 
+@@ -488,16 +488,16 @@ static int compat_drm_infobufs(struct fi
+ }
+ 
+ typedef struct drm_buf_pub32 {
+-	int	idx;		/**< Index into the master buffer list */
+-	int	total;		/**< Buffer size */
+-	int	used;		/**< Amount of buffer in use (for DMA) */
+-	u32	address;	/**< Address of buffer */
++	int idx;		/**< Index into the master buffer list */
++	int total;		/**< Buffer size */
++	int used;		/**< Amount of buffer in use (for DMA) */
++	u32 address;		/**< Address of buffer */
+ } drm_buf_pub32_t;
+ 
+ typedef struct drm_buf_map32 {
+-	int	count;		/**< Length of the buffer list */
+-	u32	virtual;	/**< Mmap'd area in user-virtual */
+-	u32	list;		/**< Buffer information */
++	int count;		/**< Length of the buffer list */
++	u32 virtual;		/**< Mmap'd area in user-virtual */
++	u32 list;		/**< Buffer information */
+ } drm_buf_map32_t;
+ 
+ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
+@@ -531,7 +531,7 @@ static int compat_drm_mapbufs(struct fil
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_MAP_BUFS, (unsigned long) request);
++			DRM_IOCTL_MAP_BUFS, (unsigned long)request);
+ 	if (err)
+ 		return err;
+ 
+@@ -542,21 +542,21 @@ static int compat_drm_mapbufs(struct fil
+ 			if (__copy_in_user(&list32[i], &list[i],
+ 					   offsetof(drm_buf_pub_t, address))
+ 			    || __get_user(addr, &list[i].address)
+-			    || __put_user((unsigned long) addr,
++			    || __put_user((unsigned long)addr,
+ 					  &list32[i].address))
+ 				return -EFAULT;
+ 
+ 	if (__put_user(actual, &argp->count)
+ 	    || __get_user(addr, &request->virtual)
+-	    || __put_user((unsigned long) addr, &argp->virtual))
++	    || __put_user((unsigned long)addr, &argp->virtual))
+ 		return -EFAULT;
+ 
+ 	return 0;
+ }
+ 
+ typedef struct drm_buf_free32 {
+-	int	count;
+-	u32	list;
++	int count;
++	u32 list;
+ } drm_buf_free32_t;
+ 
+ static int compat_drm_freebufs(struct file *file, unsigned int cmd,
+@@ -573,17 +573,17 @@ static int compat_drm_freebufs(struct fi
+ 	if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
+ 		return -EFAULT;
+ 	if (__put_user(req32.count, &request->count)
+-	    || __put_user((int __user *)(unsigned long) req32.list,
++	    || __put_user((int __user *)(unsigned long)req32.list,
+ 			  &request->list))
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_FREE_BUFS, (unsigned long) request);
++			 DRM_IOCTL_FREE_BUFS, (unsigned long)request);
+ }
+ 
+ typedef struct drm_ctx_priv_map32 {
+-	unsigned int	ctx_id;  /**< Context requesting private mapping */
+-	u32		handle; /**< Handle of map */
++	unsigned int ctx_id;	 /**< Context requesting private mapping */
++	u32 handle;		/**< Handle of map */
+ } drm_ctx_priv_map32_t;
+ 
+ static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
+@@ -600,12 +600,12 @@ static int compat_drm_setsareactx(struct
+ 	if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
+ 		return -EFAULT;
+ 	if (__put_user(req32.ctx_id, &request->ctx_id)
+-	    || __put_user((void *)(unsigned long) req32.handle,
++	    || __put_user((void *)(unsigned long)req32.handle,
+ 			  &request->handle))
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_SET_SAREA_CTX, (unsigned long) request);
++			 DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
+ }
+ 
+ static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
+@@ -628,20 +628,20 @@ static int compat_drm_getsareactx(struct
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_GET_SAREA_CTX, (unsigned long) request);
++			DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
+ 	if (err)
+ 		return err;
+ 
+ 	if (__get_user(handle, &request->handle)
+-	    || __put_user((unsigned long) handle, &argp->handle))
++	    || __put_user((unsigned long)handle, &argp->handle))
+ 		return -EFAULT;
+ 
+ 	return 0;
+ }
+ 
+ typedef struct drm_ctx_res32 {
+-	int	count;
+-	u32	contexts;
++	int count;
++	u32 contexts;
+ } drm_ctx_res32_t;
+ 
+ static int compat_drm_resctx(struct file *file, unsigned int cmd,
+@@ -659,12 +659,12 @@ static int compat_drm_resctx(struct file
+ 	if (!access_ok(VERIFY_WRITE, res, sizeof(*res)))
+ 		return -EFAULT;
+ 	if (__put_user(res32.count, &res->count)
+-	    || __put_user((drm_ctx_t __user *)(unsigned long) res32.contexts,
++	    || __put_user((drm_ctx_t __user *) (unsigned long)res32.contexts,
+ 			  &res->contexts))
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_RES_CTX, (unsigned long) res);
++			DRM_IOCTL_RES_CTX, (unsigned long)res);
+ 	if (err)
+ 		return err;
+ 
+@@ -676,23 +676,23 @@ static int compat_drm_resctx(struct file
+ }
+ 
+ typedef struct drm_dma32 {
+-	int	context;	  /**< Context handle */
+-	int	send_count;	  /**< Number of buffers to send */
+-	u32	send_indices;	  /**< List of handles to buffers */
+-	u32	send_sizes;	  /**< Lengths of data to send */
++	int context;		  /**< Context handle */
++	int send_count;		  /**< Number of buffers to send */
++	u32 send_indices;	  /**< List of handles to buffers */
++	u32 send_sizes;		  /**< Lengths of data to send */
+ 	drm_dma_flags_t flags;		  /**< Flags */
+-	int	request_count;	  /**< Number of buffers requested */
+-	int	request_size;	  /**< Desired size for buffers */
+-	u32	request_indices;  /**< Buffer information */
+-	u32	request_sizes;
+-	int	granted_count;	  /**< Number of buffers granted */
++	int request_count;	  /**< Number of buffers requested */
++	int request_size;	  /**< Desired size for buffers */
++	u32 request_indices;	  /**< Buffer information */
++	u32 request_sizes;
++	int granted_count;	  /**< Number of buffers granted */
+ } drm_dma32_t;
+ 
+ static int compat_drm_dma(struct file *file, unsigned int cmd,
+ 			  unsigned long arg)
+ {
+ 	drm_dma32_t d32;
+-	drm_dma32_t __user *argp = (void __user *) arg;
++	drm_dma32_t __user *argp = (void __user *)arg;
+ 	drm_dma_t __user *d;
+ 	int err;
+ 
+@@ -705,20 +705,20 @@ static int compat_drm_dma(struct file *f
+ 
+ 	if (__put_user(d32.context, &d->context)
+ 	    || __put_user(d32.send_count, &d->send_count)
+-	    || __put_user((int __user *)(unsigned long) d32.send_indices,
++	    || __put_user((int __user *)(unsigned long)d32.send_indices,
+ 			  &d->send_indices)
+-	    || __put_user((int __user *)(unsigned long) d32.send_sizes,
++	    || __put_user((int __user *)(unsigned long)d32.send_sizes,
+ 			  &d->send_sizes)
+ 	    || __put_user(d32.flags, &d->flags)
+ 	    || __put_user(d32.request_count, &d->request_count)
+-	    || __put_user((int __user *)(unsigned long) d32.request_indices,
++	    || __put_user((int __user *)(unsigned long)d32.request_indices,
+ 			  &d->request_indices)
+-	    || __put_user((int __user *)(unsigned long) d32.request_sizes,
++	    || __put_user((int __user *)(unsigned long)d32.request_sizes,
+ 			  &d->request_sizes))
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_DMA, (unsigned long) d);
++			DRM_IOCTL_DMA, (unsigned long)d);
+ 	if (err)
+ 		return err;
+ 
+@@ -751,19 +751,19 @@ static int compat_drm_agp_enable(struct 
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_AGP_ENABLE, (unsigned long) mode);
++			 DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
+ }
+ 
+ typedef struct drm_agp_info32 {
+-	int       agp_version_major;
+-	int       agp_version_minor;
+-	u32	  mode;
+-	u32	  aperture_base;  /* physical address */
+-	u32	  aperture_size;  /* bytes */
+-	u32	  memory_allowed; /* bytes */
+-	u32	  memory_used;
++	int agp_version_major;
++	int agp_version_minor;
++	u32 mode;
++	u32 aperture_base;	/* physical address */
++	u32 aperture_size;	/* bytes */
++	u32 memory_allowed;	/* bytes */
++	u32 memory_used;
+ 
+-				/* PCI information */
++	/* PCI information */
+ 	unsigned short id_vendor;
+ 	unsigned short id_device;
+ } drm_agp_info32_t;
+@@ -781,7 +781,7 @@ static int compat_drm_agp_info(struct fi
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_AGP_INFO, (unsigned long) info);
++			DRM_IOCTL_AGP_INFO, (unsigned long)info);
+ 	if (err)
+ 		return err;
+ 
+@@ -806,7 +806,7 @@ typedef struct drm_agp_buffer32 {
+ 	u32 size;	/**< In bytes -- will round to page boundary */
+ 	u32 handle;	/**< Used for binding / unbinding */
+ 	u32 type;	/**< Type of memory to allocate */
+-        u32 physical;	/**< Physical used by i810 */
++	u32 physical;	/**< Physical used by i810 */
+ } drm_agp_buffer32_t;
+ 
+ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
+@@ -827,7 +827,7 @@ static int compat_drm_agp_alloc(struct f
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_AGP_ALLOC, (unsigned long) request);
++			DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
+ 	if (err)
+ 		return err;
+ 
+@@ -835,7 +835,7 @@ static int compat_drm_agp_alloc(struct f
+ 	    || __get_user(req32.physical, &request->physical)
+ 	    || copy_to_user(argp, &req32, sizeof(req32))) {
+ 		drm_ioctl(file->f_dentry->d_inode, file,
+-			  DRM_IOCTL_AGP_FREE, (unsigned long) request);
++			  DRM_IOCTL_AGP_FREE, (unsigned long)request);
+ 		return -EFAULT;
+ 	}
+ 
+@@ -856,7 +856,7 @@ static int compat_drm_agp_free(struct fi
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_AGP_FREE, (unsigned long) request);
++			 DRM_IOCTL_AGP_FREE, (unsigned long)request);
+ }
+ 
+ typedef struct drm_agp_binding32 {
+@@ -881,7 +881,7 @@ static int compat_drm_agp_bind(struct fi
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_AGP_BIND, (unsigned long) request);
++			 DRM_IOCTL_AGP_BIND, (unsigned long)request);
+ }
+ 
+ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
+@@ -898,9 +898,9 @@ static int compat_drm_agp_unbind(struct 
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_AGP_UNBIND, (unsigned long) request);
++			 DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
+ }
+-#endif /* __OS_HAS_AGP */
++#endif				/* __OS_HAS_AGP */
+ 
+ typedef struct drm_scatter_gather32 {
+ 	u32 size;	/**< In bytes -- will round to page boundary */
+@@ -923,7 +923,7 @@ static int compat_drm_sg_alloc(struct fi
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_SG_ALLOC, (unsigned long) request);
++			DRM_IOCTL_SG_ALLOC, (unsigned long)request);
+ 	if (err)
+ 		return err;
+ 
+@@ -950,7 +950,7 @@ static int compat_drm_sg_free(struct fil
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_SG_FREE, (unsigned long) request);
++			 DRM_IOCTL_SG_FREE, (unsigned long)request);
+ }
+ 
+ struct drm_wait_vblank_request32 {
+@@ -990,7 +990,7 @@ static int compat_drm_wait_vblank(struct
+ 		return -EFAULT;
+ 
+ 	err = drm_ioctl(file->f_dentry->d_inode, file,
+-			DRM_IOCTL_WAIT_VBLANK, (unsigned long) request);
++			DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
+ 	if (err)
+ 		return err;
+ 
+@@ -1059,11 +1059,12 @@ long drm_compat_ioctl(struct file *filp,
+ 
+ 	lock_kernel();		/* XXX for now */
+ 	if (fn != NULL)
+-		ret = (*fn)(filp, cmd, arg);
++		ret = (*fn) (filp, cmd, arg);
+ 	else
+ 		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+ 	unlock_kernel();
+ 
+ 	return ret;
+ }
++
+ EXPORT_SYMBOL(drm_compat_ioctl);
+diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
+--- a/drivers/char/drm/drm_ioctl.c
++++ b/drivers/char/drm/drm_ioctl.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_ioctl.h 
++ * \file drm_ioctl.c
+  * IOCTL processing for DRM
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+@@ -40,7 +40,7 @@
+ 
+ /**
+  * Get the bus id.
+- * 
++ *
+  * \param inode device inode.
+  * \param filp file pointer.
+  * \param cmd command.
+@@ -50,12 +50,12 @@
+  * Copies the bus id from drm_device::unique into user space.
+  */
+ int drm_getunique(struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg)
++		  unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	 *priv	 = filp->private_data;
+-	drm_device_t	 *dev	 = priv->head->dev;
+-	drm_unique_t	 __user *argp = (void __user *)arg;
+-	drm_unique_t	 u;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_unique_t __user *argp = (void __user *)arg;
++	drm_unique_t u;
+ 
+ 	if (copy_from_user(&u, argp, sizeof(u)))
+ 		return -EFAULT;
+@@ -71,7 +71,7 @@ int drm_getunique(struct inode *inode, s
+ 
+ /**
+  * Set the bus id.
+- * 
++ *
+  * \param inode device inode.
+  * \param filp file pointer.
+  * \param cmd command.
+@@ -84,34 +84,39 @@ int drm_getunique(struct inode *inode, s
+  * version 1.1 or greater.
+  */
+ int drm_setunique(struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg)
++		  unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	 *priv	 = filp->private_data;
+-	drm_device_t	 *dev	 = priv->head->dev;
+-	drm_unique_t	 u;
+-	int		 domain, bus, slot, func, ret;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_unique_t u;
++	int domain, bus, slot, func, ret;
+ 
+-	if (dev->unique_len || dev->unique) return -EBUSY;
++	if (dev->unique_len || dev->unique)
++		return -EBUSY;
+ 
+-	if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u)))
++	if (copy_from_user(&u, (drm_unique_t __user *) arg, sizeof(u)))
+ 		return -EFAULT;
+ 
+-	if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
++	if (!u.unique_len || u.unique_len > 1024)
++		return -EINVAL;
+ 
+ 	dev->unique_len = u.unique_len;
+-	dev->unique	= drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
+-	if(!dev->unique) return -ENOMEM;
++	dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
++	if (!dev->unique)
++		return -ENOMEM;
+ 	if (copy_from_user(dev->unique, u.unique, dev->unique_len))
+ 		return -EFAULT;
+ 
+ 	dev->unique[dev->unique_len] = '\0';
+ 
+-	dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2,
+-				  DRM_MEM_DRIVER);
++	dev->devname =
++	    drm_alloc(strlen(dev->driver->pci_driver.name) +
++		      strlen(dev->unique) + 2, DRM_MEM_DRIVER);
+ 	if (!dev->devname)
+ 		return -ENOMEM;
+ 
+-	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
++	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
++		dev->unique);
+ 
+ 	/* Return error if the busid submitted doesn't match the device's actual
+ 	 * busid.
+@@ -121,18 +126,16 @@ int drm_setunique(struct inode *inode, s
+ 		return DRM_ERR(EINVAL);
+ 	domain = bus >> 8;
+ 	bus &= 0xff;
+-	
++
+ 	if ((domain != dev->pci_domain) ||
+ 	    (bus != dev->pci_bus) ||
+-	    (slot != dev->pci_slot) ||
+-	    (func != dev->pci_func))
++	    (slot != dev->pci_slot) || (func != dev->pci_func))
+ 		return -EINVAL;
+ 
+ 	return 0;
+ }
+ 
+-static int
+-drm_set_busid(drm_device_t *dev)
++static int drm_set_busid(drm_device_t * dev)
+ {
+ 	if (dev->unique != NULL)
+ 		return EBUSY;
+@@ -143,19 +146,20 @@ drm_set_busid(drm_device_t *dev)
+ 		return ENOMEM;
+ 
+ 	snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
+-		dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
++		 dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
+ 
+-	dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2,
+-				DRM_MEM_DRIVER);
++	dev->devname =
++	    drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
++		      2, DRM_MEM_DRIVER);
+ 	if (dev->devname == NULL)
+ 		return ENOMEM;
+ 
+-	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
++	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
++		dev->unique);
+ 
+ 	return 0;
+ }
+ 
+-
+ /**
+  * Get a mapping information.
+  *
+@@ -163,23 +167,23 @@ drm_set_busid(drm_device_t *dev)
+  * \param filp file pointer.
+  * \param cmd command.
+  * \param arg user argument, pointing to a drm_map structure.
+- * 
++ *
+  * \return zero on success or a negative number on failure.
+  *
+  * Searches for the mapping with the specified offset and copies its information
+  * into userspace
+  */
+-int drm_getmap( struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg )
++int drm_getmap(struct inode *inode, struct file *filp,
++	       unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t   *priv = filp->private_data;
+-	drm_device_t *dev  = priv->head->dev;
+-	drm_map_t    __user *argp = (void __user *)arg;
+-	drm_map_t    map;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_map_t __user *argp = (void __user *)arg;
++	drm_map_t map;
+ 	drm_map_list_t *r_list = NULL;
+ 	struct list_head *list;
+-	int          idx;
+-	int	     i;
++	int idx;
++	int i;
+ 
+ 	if (copy_from_user(&map, argp, sizeof(map)))
+ 		return -EFAULT;
+@@ -193,26 +197,27 @@ int drm_getmap( struct inode *inode, str
+ 
+ 	i = 0;
+ 	list_for_each(list, &dev->maplist->head) {
+-		if(i == idx) {
++		if (i == idx) {
+ 			r_list = list_entry(list, drm_map_list_t, head);
+ 			break;
+ 		}
+ 		i++;
+ 	}
+-	if(!r_list || !r_list->map) {
++	if (!r_list || !r_list->map) {
+ 		up(&dev->struct_sem);
+ 		return -EINVAL;
+ 	}
+ 
+ 	map.offset = r_list->map->offset;
+-	map.size   = r_list->map->size;
+-	map.type   = r_list->map->type;
+-	map.flags  = r_list->map->flags;
+-	map.handle = (void *)(unsigned long) r_list->user_token;
+-	map.mtrr   = r_list->map->mtrr;
++	map.size = r_list->map->size;
++	map.type = r_list->map->type;
++	map.flags = r_list->map->flags;
++	map.handle = (void *)(unsigned long)r_list->user_token;
++	map.mtrr = r_list->map->mtrr;
+ 	up(&dev->struct_sem);
+ 
+-	if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT;
++	if (copy_to_user(argp, &map, sizeof(map)))
++		return -EFAULT;
+ 	return 0;
+ }
+ 
+@@ -223,83 +228,81 @@ int drm_getmap( struct inode *inode, str
+  * \param filp file pointer.
+  * \param cmd command.
+  * \param arg user argument, pointing to a drm_client structure.
+- * 
++ *
+  * \return zero on success or a negative number on failure.
+  *
+  * Searches for the client with the specified index and copies its information
+  * into userspace
+  */
+-int drm_getclient( struct inode *inode, struct file *filp,
+-		    unsigned int cmd, unsigned long arg )
++int drm_getclient(struct inode *inode, struct file *filp,
++		  unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t   *priv = filp->private_data;
+-	drm_device_t *dev  = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_client_t __user *argp = (void __user *)arg;
+ 	drm_client_t client;
+-	drm_file_t   *pt;
+-	int          idx;
+-	int          i;
++	drm_file_t *pt;
++	int idx;
++	int i;
+ 
+ 	if (copy_from_user(&client, argp, sizeof(client)))
+ 		return -EFAULT;
+ 	idx = client.idx;
+ 	down(&dev->struct_sem);
+-	for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
+-		;
++	for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) ;
+ 
+ 	if (!pt) {
+ 		up(&dev->struct_sem);
+ 		return -EINVAL;
+ 	}
+-	client.auth  = pt->authenticated;
+-	client.pid   = pt->pid;
+-	client.uid   = pt->uid;
++	client.auth = pt->authenticated;
++	client.pid = pt->pid;
++	client.uid = pt->uid;
+ 	client.magic = pt->magic;
+-	client.iocs  = pt->ioctl_count;
++	client.iocs = pt->ioctl_count;
+ 	up(&dev->struct_sem);
+ 
+-	if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client)))
++	if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+ 
+-/** 
+- * Get statistics information. 
+- * 
++/**
++ * Get statistics information.
++ *
+  * \param inode device inode.
+  * \param filp file pointer.
+  * \param cmd command.
+  * \param arg user argument, pointing to a drm_stats structure.
+- * 
++ *
+  * \return zero on success or a negative number on failure.
+  */
+-int drm_getstats( struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg )
++int drm_getstats(struct inode *inode, struct file *filp,
++		 unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t   *priv = filp->private_data;
+-	drm_device_t *dev  = priv->head->dev;
+-	drm_stats_t  stats;
+-	int          i;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_stats_t stats;
++	int i;
+ 
+ 	memset(&stats, 0, sizeof(stats));
+-	
++
+ 	down(&dev->struct_sem);
+ 
+ 	for (i = 0; i < dev->counters; i++) {
+ 		if (dev->types[i] == _DRM_STAT_LOCK)
+ 			stats.data[i].value
+-				= (dev->lock.hw_lock
+-				   ? dev->lock.hw_lock->lock : 0);
+-		else 
++			    = (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
++		else
+ 			stats.data[i].value = atomic_read(&dev->counts[i]);
+-		stats.data[i].type  = dev->types[i];
++		stats.data[i].type = dev->types[i];
+ 	}
+-	
++
+ 	stats.count = dev->counters;
+ 
+ 	up(&dev->struct_sem);
+ 
+-	if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats)))
++	if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+@@ -352,7 +355,8 @@ int drm_setversion(DRM_IOCTL_ARGS)
+ 
+ 	if (sv.drm_dd_major != -1) {
+ 		if (sv.drm_dd_major != version.version_major ||
+-		    sv.drm_dd_minor < 0 || sv.drm_dd_minor > version.version_minor)
++		    sv.drm_dd_minor < 0
++		    || sv.drm_dd_minor > version.version_minor)
+ 			return EINVAL;
+ 
+ 		if (dev->driver->set_version)
+@@ -363,7 +367,7 @@ int drm_setversion(DRM_IOCTL_ARGS)
+ 
+ /** No-op ioctl. */
+ int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
+-	       unsigned long arg)
++	     unsigned long arg)
+ {
+ 	DRM_DEBUG("\n");
+ 	return 0;
+diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
+--- a/drivers/char/drm/drm_irq.c
++++ b/drivers/char/drm/drm_irq.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_irq.h 
++ * \file drm_irq.c
+  * IRQ support
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+@@ -39,19 +39,19 @@
+ 
+ /**
+  * Get interrupt from bus id.
+- * 
++ *
+  * \param inode device inode.
+  * \param filp file pointer.
+  * \param cmd command.
+  * \param arg user argument, pointing to a drm_irq_busid structure.
+  * \return zero on success or a negative number on failure.
+- * 
++ *
+  * Finds the PCI device with the specified bus id and gets its IRQ number.
+  * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
+  * to that of the device that this DRM instance attached to.
+  */
+ int drm_irq_by_busid(struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg)
++		     unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -66,14 +66,12 @@ int drm_irq_by_busid(struct inode *inode
+ 
+ 	if ((p.busnum >> 8) != dev->pci_domain ||
+ 	    (p.busnum & 0xff) != dev->pci_bus ||
+-	    p.devnum != dev->pci_slot ||
+-	    p.funcnum != dev->pci_func)
++	    p.devnum != dev->pci_slot || p.funcnum != dev->pci_func)
+ 		return -EINVAL;
+ 
+ 	p.irq = dev->irq;
+ 
+-	DRM_DEBUG("%d:%d:%d => IRQ %d\n",
+-		  p.busnum, p.devnum, p.funcnum, p.irq);
++	DRM_DEBUG("%d:%d:%d => IRQ %d\n", p.busnum, p.devnum, p.funcnum, p.irq);
+ 	if (copy_to_user(argp, &p, sizeof(p)))
+ 		return -EFAULT;
+ 	return 0;
+@@ -89,61 +87,61 @@ int drm_irq_by_busid(struct inode *inode
+  * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
+  * before and after the installation.
+  */
+-static int drm_irq_install( drm_device_t *dev )
++static int drm_irq_install(drm_device_t * dev)
+ {
+ 	int ret;
+-	unsigned long sh_flags=0;
++	unsigned long sh_flags = 0;
+ 
+ 	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+ 		return -EINVAL;
+ 
+-	if ( dev->irq == 0 )
++	if (dev->irq == 0)
+ 		return -EINVAL;
+ 
+-	down( &dev->struct_sem );
++	down(&dev->struct_sem);
+ 
+ 	/* Driver must have been initialized */
+-	if ( !dev->dev_private ) {
+-		up( &dev->struct_sem );
++	if (!dev->dev_private) {
++		up(&dev->struct_sem);
+ 		return -EINVAL;
+ 	}
+ 
+-	if ( dev->irq_enabled ) {
+-		up( &dev->struct_sem );
++	if (dev->irq_enabled) {
++		up(&dev->struct_sem);
+ 		return -EBUSY;
+ 	}
+ 	dev->irq_enabled = 1;
+-	up( &dev->struct_sem );
++	up(&dev->struct_sem);
+ 
+-	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
++	DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq);
+ 
+ 	if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
+ 		init_waitqueue_head(&dev->vbl_queue);
+-		
+-		spin_lock_init( &dev->vbl_lock );
+-		
+-		INIT_LIST_HEAD( &dev->vbl_sigs.head );
+-		
++
++		spin_lock_init(&dev->vbl_lock);
++
++		INIT_LIST_HEAD(&dev->vbl_sigs.head);
++
+ 		dev->vbl_pending = 0;
+ 	}
+ 
+-				/* Before installing handler */
++	/* Before installing handler */
+ 	dev->driver->irq_preinstall(dev);
+ 
+-				/* Install handler */
++	/* Install handler */
+ 	if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
+ 		sh_flags = SA_SHIRQ;
+-	
+-	ret = request_irq( dev->irq, dev->driver->irq_handler,
+-			   sh_flags, dev->devname, dev );
+-	if ( ret < 0 ) {
+-		down( &dev->struct_sem );
++
++	ret = request_irq(dev->irq, dev->driver->irq_handler,
++			  sh_flags, dev->devname, dev);
++	if (ret < 0) {
++		down(&dev->struct_sem);
+ 		dev->irq_enabled = 0;
+-		up( &dev->struct_sem );
++		up(&dev->struct_sem);
+ 		return ret;
+ 	}
+ 
+-				/* After installing handler */
++	/* After installing handler */
+ 	dev->driver->irq_postinstall(dev);
+ 
+ 	return 0;
+@@ -156,29 +154,30 @@ static int drm_irq_install( drm_device_t
+  *
+  * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
+  */
+-int drm_irq_uninstall( drm_device_t *dev )
++int drm_irq_uninstall(drm_device_t * dev)
+ {
+ 	int irq_enabled;
+ 
+ 	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+ 		return -EINVAL;
+ 
+-	down( &dev->struct_sem );
++	down(&dev->struct_sem);
+ 	irq_enabled = dev->irq_enabled;
+ 	dev->irq_enabled = 0;
+-	up( &dev->struct_sem );
++	up(&dev->struct_sem);
+ 
+-	if ( !irq_enabled )
++	if (!irq_enabled)
+ 		return -EINVAL;
+ 
+-	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
++	DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq);
+ 
+ 	dev->driver->irq_uninstall(dev);
+ 
+-	free_irq( dev->irq, dev );
++	free_irq(dev->irq, dev);
+ 
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_irq_uninstall);
+ 
+ /**
+@@ -192,30 +191,30 @@ EXPORT_SYMBOL(drm_irq_uninstall);
+  *
+  * Calls irq_install() or irq_uninstall() according to \p arg.
+  */
+-int drm_control( struct inode *inode, struct file *filp,
+-		  unsigned int cmd, unsigned long arg )
++int drm_control(struct inode *inode, struct file *filp,
++		unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_control_t ctl;
+-	
++
+ 	/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
+ 
+-	if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) )
++	if (copy_from_user(&ctl, (drm_control_t __user *) arg, sizeof(ctl)))
+ 		return -EFAULT;
+ 
+-	switch ( ctl.func ) {
++	switch (ctl.func) {
+ 	case DRM_INST_HANDLER:
+ 		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+ 			return 0;
+ 		if (dev->if_version < DRM_IF_VERSION(1, 2) &&
+ 		    ctl.irq != dev->irq)
+ 			return -EINVAL;
+-		return drm_irq_install( dev );
++		return drm_irq_install(dev);
+ 	case DRM_UNINST_HANDLER:
+ 		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+ 			return 0;
+-		return drm_irq_uninstall( dev );
++		return drm_irq_uninstall(dev);
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -230,7 +229,7 @@ int drm_control( struct inode *inode, st
+  * \param data user argument, pointing to a drm_wait_vblank structure.
+  * \return zero on success or a negative number on failure.
+  *
+- * Verifies the IRQ is installed. 
++ * Verifies the IRQ is installed.
+  *
+  * If a signal is requested checks if this task has already scheduled the same signal
+  * for the same vblank sequence number - nothing to be done in
+@@ -240,7 +239,7 @@ int drm_control( struct inode *inode, st
+  *
+  * If a signal is not requested, then calls vblank_wait().
+  */
+-int drm_wait_vblank( DRM_IOCTL_ARGS )
++int drm_wait_vblank(DRM_IOCTL_ARGS)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -256,11 +255,11 @@ int drm_wait_vblank( DRM_IOCTL_ARGS )
+ 	if (!dev->irq)
+ 		return -EINVAL;
+ 
+-	DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) );
++	DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait));
+ 
+-	switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
++	switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) {
+ 	case _DRM_VBLANK_RELATIVE:
+-		vblwait.request.sequence += atomic_read( &dev->vbl_received );
++		vblwait.request.sequence += atomic_read(&dev->vbl_received);
+ 		vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
+ 	case _DRM_VBLANK_ABSOLUTE:
+ 		break;
+@@ -269,64 +268,68 @@ int drm_wait_vblank( DRM_IOCTL_ARGS )
+ 	}
+ 
+ 	flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
+-	
+-	if ( flags & _DRM_VBLANK_SIGNAL ) {
++
++	if (flags & _DRM_VBLANK_SIGNAL) {
+ 		unsigned long irqflags;
+ 		drm_vbl_sig_t *vbl_sig;
+-		
+-		vblwait.reply.sequence = atomic_read( &dev->vbl_received );
+ 
+-		spin_lock_irqsave( &dev->vbl_lock, irqflags );
++		vblwait.reply.sequence = atomic_read(&dev->vbl_received);
++
++		spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ 
+ 		/* Check if this task has already scheduled the same signal
+ 		 * for the same vblank sequence number; nothing to be done in
+ 		 * that case
+ 		 */
+-		list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) {
++		list_for_each_entry(vbl_sig, &dev->vbl_sigs.head, head) {
+ 			if (vbl_sig->sequence == vblwait.request.sequence
+ 			    && vbl_sig->info.si_signo == vblwait.request.signal
+-			    && vbl_sig->task == current)
+-			{
+-				spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
++			    && vbl_sig->task == current) {
++				spin_unlock_irqrestore(&dev->vbl_lock,
++						       irqflags);
+ 				goto done;
+ 			}
+ 		}
+ 
+-		if ( dev->vbl_pending >= 100 ) {
+-			spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
++		if (dev->vbl_pending >= 100) {
++			spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+ 			return -EBUSY;
+ 		}
+ 
+ 		dev->vbl_pending++;
+ 
+-		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
++		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+ 
+-		if ( !( vbl_sig = drm_alloc( sizeof( drm_vbl_sig_t ), DRM_MEM_DRIVER ) ) ) {
++		if (!
++		    (vbl_sig =
++		     drm_alloc(sizeof(drm_vbl_sig_t), DRM_MEM_DRIVER))) {
+ 			return -ENOMEM;
+ 		}
+ 
+-		memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
++		memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
+ 
+ 		vbl_sig->sequence = vblwait.request.sequence;
+ 		vbl_sig->info.si_signo = vblwait.request.signal;
+ 		vbl_sig->task = current;
+ 
+-		spin_lock_irqsave( &dev->vbl_lock, irqflags );
++		spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ 
+-		list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
++		list_add_tail((struct list_head *)vbl_sig, &dev->vbl_sigs.head);
+ 
+-		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
++		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+ 	} else {
+ 		if (dev->driver->vblank_wait)
+-			ret = dev->driver->vblank_wait( dev, &vblwait.request.sequence );
++			ret =
++			    dev->driver->vblank_wait(dev,
++						     &vblwait.request.sequence);
+ 
+-		do_gettimeofday( &now );
++		do_gettimeofday(&now);
+ 		vblwait.reply.tval_sec = now.tv_sec;
+ 		vblwait.reply.tval_usec = now.tv_usec;
+ 	}
+ 
+-done:
+-	DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) );
++      done:
++	DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait));
+ 
+ 	return ret;
+ }
+@@ -340,31 +343,31 @@ done:
+  *
+  * If a signal is not requested, then calls vblank_wait().
+  */
+-void drm_vbl_send_signals( drm_device_t *dev )
++void drm_vbl_send_signals(drm_device_t * dev)
+ {
+ 	struct list_head *list, *tmp;
+ 	drm_vbl_sig_t *vbl_sig;
+-	unsigned int vbl_seq = atomic_read( &dev->vbl_received );
++	unsigned int vbl_seq = atomic_read(&dev->vbl_received);
+ 	unsigned long flags;
+ 
+-	spin_lock_irqsave( &dev->vbl_lock, flags );
++	spin_lock_irqsave(&dev->vbl_lock, flags);
+ 
+-	list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) {
+-		vbl_sig = list_entry( list, drm_vbl_sig_t, head );
+-		if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
++	list_for_each_safe(list, tmp, &dev->vbl_sigs.head) {
++		vbl_sig = list_entry(list, drm_vbl_sig_t, head);
++		if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
+ 			vbl_sig->info.si_code = vbl_seq;
+-			send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
++			send_sig_info(vbl_sig->info.si_signo, &vbl_sig->info,
++				      vbl_sig->task);
+ 
+-			list_del( list );
++			list_del(list);
+ 
+-			drm_free( vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER );
++			drm_free(vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER);
+ 
+ 			dev->vbl_pending--;
+ 		}
+ 	}
+ 
+-	spin_unlock_irqrestore( &dev->vbl_lock, flags );
++	spin_unlock_irqrestore(&dev->vbl_lock, flags);
+ }
+-EXPORT_SYMBOL(drm_vbl_send_signals);
+-
+ 
++EXPORT_SYMBOL(drm_vbl_send_signals);
+diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
+--- a/drivers/char/drm/drm_lock.c
++++ b/drivers/char/drm/drm_lock.c
+@@ -1,7 +1,7 @@
+ /**
+- * \file drm_lock.h 
++ * \file drm_lock.c
+  * IOCTLs for locking
+- * 
++ *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Gareth Hughes <gareth at valinux.com>
+  */
+@@ -35,12 +35,12 @@
+ 
+ #include "drmP.h"
+ 
+-static int drm_lock_transfer(drm_device_t *dev,
++static int drm_lock_transfer(drm_device_t * dev,
+ 			     __volatile__ unsigned int *lock,
+ 			     unsigned int context);
+ static int drm_notifier(void *priv);
+ 
+-/** 
++/**
+  * Lock ioctl.
+  *
+  * \param inode device inode.
+@@ -51,91 +51,89 @@ static int drm_notifier(void *priv);
+  *
+  * Add the current task to the lock wait queue, and attempt to take to lock.
+  */
+-int drm_lock( struct inode *inode, struct file *filp,
+-	       unsigned int cmd, unsigned long arg )
++int drm_lock(struct inode *inode, struct file *filp,
++	     unsigned int cmd, unsigned long arg)
+ {
+-        drm_file_t *priv = filp->private_data;
+-        drm_device_t *dev = priv->head->dev;
+-        DECLARE_WAITQUEUE( entry, current );
+-        drm_lock_t lock;
+-        int ret = 0;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	DECLARE_WAITQUEUE(entry, current);
++	drm_lock_t lock;
++	int ret = 0;
+ 
+ 	++priv->lock_count;
+ 
+-        if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
++	if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
+ 		return -EFAULT;
+ 
+-        if ( lock.context == DRM_KERNEL_CONTEXT ) {
+-                DRM_ERROR( "Process %d using kernel context %d\n",
+-			   current->pid, lock.context );
+-                return -EINVAL;
+-        }
+-
+-        DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+-		   lock.context, current->pid,
+-		   dev->lock.hw_lock->lock, lock.flags );
++	if (lock.context == DRM_KERNEL_CONTEXT) {
++		DRM_ERROR("Process %d using kernel context %d\n",
++			  current->pid, lock.context);
++		return -EINVAL;
++	}
++
++	DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
++		  lock.context, current->pid,
++		  dev->lock.hw_lock->lock, lock.flags);
+ 
+ 	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
+-		if ( lock.context < 0 )
++		if (lock.context < 0)
+ 			return -EINVAL;
+ 
+-	add_wait_queue( &dev->lock.lock_queue, &entry );
++	add_wait_queue(&dev->lock.lock_queue, &entry);
+ 	for (;;) {
+ 		__set_current_state(TASK_INTERRUPTIBLE);
+-		if ( !dev->lock.hw_lock ) {
++		if (!dev->lock.hw_lock) {
+ 			/* Device has been unregistered */
+ 			ret = -EINTR;
+ 			break;
+ 		}
+-		if ( drm_lock_take( &dev->lock.hw_lock->lock,
+-				     lock.context ) ) {
+-			dev->lock.filp      = filp;
++		if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) {
++			dev->lock.filp = filp;
+ 			dev->lock.lock_time = jiffies;
+-			atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+-			break;  /* Got lock */
++			atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
++			break;	/* Got lock */
+ 		}
+-		
++
+ 		/* Contention */
+ 		schedule();
+-		if ( signal_pending( current ) ) {
++		if (signal_pending(current)) {
+ 			ret = -ERESTARTSYS;
+ 			break;
+ 		}
+ 	}
+ 	__set_current_state(TASK_RUNNING);
+-	remove_wait_queue( &dev->lock.lock_queue, &entry );
++	remove_wait_queue(&dev->lock.lock_queue, &entry);
+ 
+-	sigemptyset( &dev->sigmask );
+-	sigaddset( &dev->sigmask, SIGSTOP );
+-	sigaddset( &dev->sigmask, SIGTSTP );
+-	sigaddset( &dev->sigmask, SIGTTIN );
+-	sigaddset( &dev->sigmask, SIGTTOU );
++	sigemptyset(&dev->sigmask);
++	sigaddset(&dev->sigmask, SIGSTOP);
++	sigaddset(&dev->sigmask, SIGTSTP);
++	sigaddset(&dev->sigmask, SIGTTIN);
++	sigaddset(&dev->sigmask, SIGTTOU);
+ 	dev->sigdata.context = lock.context;
+-	dev->sigdata.lock    = dev->lock.hw_lock;
+-	block_all_signals( drm_notifier,
+-			   &dev->sigdata, &dev->sigmask );
+-	
++	dev->sigdata.lock = dev->lock.hw_lock;
++	block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
++
+ 	if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
+ 		dev->driver->dma_ready(dev);
+-	
+-	if ( dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
++
++	if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT))
+ 		return dev->driver->dma_quiescent(dev);
+-	
+-	/* dev->driver->kernel_context_switch isn't used by any of the x86 
++
++	/* dev->driver->kernel_context_switch isn't used by any of the x86
+ 	 *  drivers but is used by the Sparc driver.
+ 	 */
+-	
+-	if (dev->driver->kernel_context_switch && 
++
++	if (dev->driver->kernel_context_switch &&
+ 	    dev->last_context != lock.context) {
+-	  dev->driver->kernel_context_switch(dev, dev->last_context, 
+-					    lock.context);
++		dev->driver->kernel_context_switch(dev, dev->last_context,
++						   lock.context);
+ 	}
+-        DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
++	DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+ 
+-        return ret;
++	return ret;
+ }
+ 
+-/** 
++/**
+  * Unlock ioctl.
+  *
+  * \param inode device inode.
+@@ -146,23 +144,23 @@ int drm_lock( struct inode *inode, struc
+  *
+  * Transfer and free the lock.
+  */
+-int drm_unlock( struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg )
++int drm_unlock(struct inode *inode, struct file *filp,
++	       unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_lock_t lock;
+ 
+-	if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
++	if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
+ 		return -EFAULT;
+ 
+-	if ( lock.context == DRM_KERNEL_CONTEXT ) {
+-		DRM_ERROR( "Process %d using kernel context %d\n",
+-			   current->pid, lock.context );
++	if (lock.context == DRM_KERNEL_CONTEXT) {
++		DRM_ERROR("Process %d using kernel context %d\n",
++			  current->pid, lock.context);
+ 		return -EINVAL;
+ 	}
+ 
+-	atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
++	atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
+ 
+ 	/* kernel_context_switch isn't used by any of the x86 drm
+ 	 * modules but is required by the Sparc driver.
+@@ -170,12 +168,12 @@ int drm_unlock( struct inode *inode, str
+ 	if (dev->driver->kernel_context_switch_unlock)
+ 		dev->driver->kernel_context_switch_unlock(dev, &lock);
+ 	else {
+-		drm_lock_transfer( dev, &dev->lock.hw_lock->lock, 
+-				    DRM_KERNEL_CONTEXT );
+-		
+-		if ( drm_lock_free( dev, &dev->lock.hw_lock->lock,
+-				     DRM_KERNEL_CONTEXT ) ) {
+-			DRM_ERROR( "\n" );
++		drm_lock_transfer(dev, &dev->lock.hw_lock->lock,
++				  DRM_KERNEL_CONTEXT);
++
++		if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
++				  DRM_KERNEL_CONTEXT)) {
++			DRM_ERROR("\n");
+ 		}
+ 	}
+ 
+@@ -198,8 +196,10 @@ int drm_lock_take(__volatile__ unsigned 
+ 
+ 	do {
+ 		old = *lock;
+-		if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
+-		else			  new = context | _DRM_LOCK_HELD;
++		if (old & _DRM_LOCK_HELD)
++			new = old | _DRM_LOCK_CONT;
++		else
++			new = context | _DRM_LOCK_HELD;
+ 		prev = cmpxchg(lock, old, new);
+ 	} while (prev != old);
+ 	if (_DRM_LOCKING_CONTEXT(old) == context) {
+@@ -212,7 +212,7 @@ int drm_lock_take(__volatile__ unsigned 
+ 		}
+ 	}
+ 	if (new == (context | _DRM_LOCK_HELD)) {
+-				/* Have lock */
++		/* Have lock */
+ 		return 1;
+ 	}
+ 	return 0;
+@@ -220,8 +220,8 @@ int drm_lock_take(__volatile__ unsigned 
+ 
+ /**
+  * This takes a lock forcibly and hands it to context.	Should ONLY be used
+- * inside *_unlock to give lock to kernel before calling *_dma_schedule. 
+- * 
++ * inside *_unlock to give lock to kernel before calling *_dma_schedule.
++ *
+  * \param dev DRM device.
+  * \param lock lock pointer.
+  * \param context locking context.
+@@ -230,7 +230,7 @@ int drm_lock_take(__volatile__ unsigned 
+  * Resets the lock file pointer.
+  * Marks the lock as held by the given context, via the \p cmpxchg instruction.
+  */
+-static int drm_lock_transfer(drm_device_t *dev,
++static int drm_lock_transfer(drm_device_t * dev,
+ 			     __volatile__ unsigned int *lock,
+ 			     unsigned int context)
+ {
+@@ -238,8 +238,8 @@ static int drm_lock_transfer(drm_device_
+ 
+ 	dev->lock.filp = NULL;
+ 	do {
+-		old  = *lock;
+-		new  = context | _DRM_LOCK_HELD;
++		old = *lock;
++		new = context | _DRM_LOCK_HELD;
+ 		prev = cmpxchg(lock, old, new);
+ 	} while (prev != old);
+ 	return 1;
+@@ -247,30 +247,29 @@ static int drm_lock_transfer(drm_device_
+ 
+ /**
+  * Free lock.
+- * 
++ *
+  * \param dev DRM device.
+  * \param lock lock.
+  * \param context context.
+- * 
++ *
+  * Resets the lock file pointer.
+  * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
+  * waiting on the lock queue.
+  */
+-int drm_lock_free(drm_device_t *dev,
+-		   __volatile__ unsigned int *lock, unsigned int context)
++int drm_lock_free(drm_device_t * dev,
++		  __volatile__ unsigned int *lock, unsigned int context)
+ {
+ 	unsigned int old, new, prev;
+ 
+ 	dev->lock.filp = NULL;
+ 	do {
+-		old  = *lock;
+-		new  = 0;
++		old = *lock;
++		new = 0;
+ 		prev = cmpxchg(lock, old, new);
+ 	} while (prev != old);
+ 	if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
+ 		DRM_ERROR("%d freed heavyweight lock held by %d\n",
+-			  context,
+-			  _DRM_LOCKING_CONTEXT(old));
++			  context, _DRM_LOCKING_CONTEXT(old));
+ 		return 1;
+ 	}
+ 	wake_up_interruptible(&dev->lock.lock_queue);
+@@ -290,19 +289,19 @@ int drm_lock_free(drm_device_t *dev,
+  */
+ static int drm_notifier(void *priv)
+ {
+-	drm_sigdata_t *s = (drm_sigdata_t *)priv;
+-	unsigned int  old, new, prev;
+-
++	drm_sigdata_t *s = (drm_sigdata_t *) priv;
++	unsigned int old, new, prev;
+ 
+-				/* Allow signal delivery if lock isn't held */
++	/* Allow signal delivery if lock isn't held */
+ 	if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
+-	    || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
++	    || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context)
++		return 1;
+ 
+-				/* Otherwise, set flag to force call to
+-                                   drmUnlock */
++	/* Otherwise, set flag to force call to
++	   drmUnlock */
+ 	do {
+-		old  = s->lock->lock;
+-		new  = old | _DRM_LOCK_CONT;
++		old = s->lock->lock;
++		new = old | _DRM_LOCK_CONT;
+ 		prev = cmpxchg(&s->lock->lock, old, new);
+ 	} while (prev != old);
+ 	return 0;
+diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
+--- a/drivers/char/drm/drm_memory.c
++++ b/drivers/char/drm/drm_memory.c
+@@ -1,12 +1,12 @@
+-/** 
+- * \file drm_memory.h 
++/**
++ * \file drm_memory.c
+  * Memory management wrappers for DRM
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Gareth Hughes <gareth at valinux.com>
+  */
+ 
+-/* 
++/*
+  * Created: Thu Feb  4 14:00:34 1999 by faith at valinux.com
+  *
+  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+@@ -48,7 +48,7 @@ void drm_mem_init(void)
+ 
+ /**
+  * Called when "/proc/dri/%dev%/mem" is read.
+- * 
++ *
+  * \param buf output buffer.
+  * \param start start of output data.
+  * \param offset requested start offset.
+@@ -57,10 +57,10 @@ void drm_mem_init(void)
+  * \param data private data.
+  * \return number of written bytes.
+  *
+- * No-op. 
++ * No-op.
+  */
+ int drm_mem_info(char *buf, char **start, off_t offset,
+-		  int len, int *eof, void *data)
++		 int len, int *eof, void *data)
+ {
+ 	return 0;
+ }
+@@ -70,7 +70,8 @@ void *drm_realloc(void *oldpt, size_t ol
+ {
+ 	void *pt;
+ 
+-	if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL;
++	if (!(pt = kmalloc(size, GFP_KERNEL)))
++		return NULL;
+ 	if (oldpt && oldsize) {
+ 		memcpy(pt, oldpt, oldsize);
+ 		kfree(oldpt);
+@@ -90,21 +91,20 @@ void *drm_realloc(void *oldpt, size_t ol
+ unsigned long drm_alloc_pages(int order, int area)
+ {
+ 	unsigned long address;
+-	unsigned long bytes	  = PAGE_SIZE << order;
++	unsigned long bytes = PAGE_SIZE << order;
+ 	unsigned long addr;
+-	unsigned int  sz;
++	unsigned int sz;
+ 
+ 	address = __get_free_pages(GFP_KERNEL, order);
+-	if (!address) 
++	if (!address)
+ 		return 0;
+ 
+-				/* Zero */
++	/* Zero */
+ 	memset((void *)address, 0, bytes);
+ 
+-				/* Reserve */
++	/* Reserve */
+ 	for (addr = address, sz = bytes;
+-	     sz > 0;
+-	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
++	     sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ 		SetPageReserved(virt_to_page(addr));
+ 	}
+ 
+@@ -113,7 +113,7 @@ unsigned long drm_alloc_pages(int order,
+ 
+ /**
+  * Free pages.
+- * 
++ *
+  * \param address address of the pages to free.
+  * \param order size order.
+  * \param area memory area. (Not used.)
+@@ -124,49 +124,51 @@ void drm_free_pages(unsigned long addres
+ {
+ 	unsigned long bytes = PAGE_SIZE << order;
+ 	unsigned long addr;
+-	unsigned int  sz;
++	unsigned int sz;
+ 
+-	if (!address) 
++	if (!address)
+ 		return;
+ 
+ 	/* Unreserve */
+ 	for (addr = address, sz = bytes;
+-	     sz > 0;
+-	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
++	     sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ 		ClearPageReserved(virt_to_page(addr));
+ 	}
+ 
+ 	free_pages(address, order);
+ }
+ 
+-
+ #if __OS_HAS_AGP
+ /** Wrapper around agp_allocate_memory() */
+-DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type)
++DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type)
+ {
+ 	return drm_agp_allocate_memory(dev->agp->bridge, pages, type);
+ }
++
+ EXPORT_SYMBOL(drm_alloc_agp);
+ 
+ /** Wrapper around agp_free_memory() */
+-int drm_free_agp(DRM_AGP_MEM *handle, int pages)
++int drm_free_agp(DRM_AGP_MEM * handle, int pages)
+ {
+ 	return drm_agp_free_memory(handle) ? 0 : -EINVAL;
+ }
++
+ EXPORT_SYMBOL(drm_free_agp);
+ 
+ /** Wrapper around agp_bind_memory() */
+-int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start)
++int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
+ {
+ 	return drm_agp_bind_memory(handle, start);
+ }
++
+ EXPORT_SYMBOL(drm_bind_agp);
+ 
+ /** Wrapper around agp_unbind_memory() */
+-int drm_unbind_agp(DRM_AGP_MEM *handle)
++int drm_unbind_agp(DRM_AGP_MEM * handle)
+ {
+ 	return drm_agp_unbind_memory(handle);
+ }
++
+ EXPORT_SYMBOL(drm_unbind_agp);
+-#endif /* agp */
+-#endif /* debug_memory */
++#endif				/* agp */
++#endif				/* debug_memory */
+diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
+--- a/drivers/char/drm/drm_memory.h
++++ b/drivers/char/drm/drm_memory.h
+@@ -1,12 +1,12 @@
+-/** 
+- * \file drm_memory.h 
++/**
++ * \file drm_memory.h
+  * Memory management wrappers for DRM
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Gareth Hughes <gareth at valinux.com>
+  */
+ 
+-/* 
++/*
+  * Created: Thu Feb  4 14:00:34 1999 by faith at valinux.com
+  *
+  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+@@ -40,7 +40,7 @@
+ 
+ /**
+  * Cut down version of drm_memory_debug.h, which used to be called
+- * drm_memory.h.  
++ * drm_memory.h.
+  */
+ 
+ #if __OS_HAS_AGP
+@@ -60,8 +60,8 @@
+ /*
+  * Find the drm_map that covers the range [offset, offset+size).
+  */
+-static inline drm_map_t *
+-drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev)
++static inline drm_map_t *drm_lookup_map(unsigned long offset,
++					unsigned long size, drm_device_t * dev)
+ {
+ 	struct list_head *list;
+ 	drm_map_list_t *r_list;
+@@ -72,16 +72,18 @@ drm_lookup_map (unsigned long offset, un
+ 		map = r_list->map;
+ 		if (!map)
+ 			continue;
+-		if (map->offset <= offset && (offset + size) <= (map->offset + map->size))
++		if (map->offset <= offset
++		    && (offset + size) <= (map->offset + map->size))
+ 			return map;
+ 	}
+ 	return NULL;
+ }
+ 
+-static inline void *
+-agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
++static inline void *agp_remap(unsigned long offset, unsigned long size,
++			      drm_device_t * dev)
+ {
+-	unsigned long *phys_addr_map, i, num_pages = PAGE_ALIGN(size) / PAGE_SIZE;
++	unsigned long *phys_addr_map, i, num_pages =
++	    PAGE_ALIGN(size) / PAGE_SIZE;
+ 	struct drm_agp_mem *agpmem;
+ 	struct page **page_map;
+ 	void *addr;
+@@ -94,7 +96,8 @@ agp_remap (unsigned long offset, unsigne
+ 
+ 	for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next)
+ 		if (agpmem->bound <= offset
+-		    && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= (offset + size))
++		    && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
++		    (offset + size))
+ 			break;
+ 	if (!agpmem)
+ 		return NULL;
+@@ -109,7 +112,8 @@ agp_remap (unsigned long offset, unsigne
+ 	if (!page_map)
+ 		return NULL;
+ 
+-	phys_addr_map = agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
++	phys_addr_map =
++	    agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
+ 	for (i = 0; i < num_pages; ++i)
+ 		page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
+ 	addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
+@@ -118,36 +122,38 @@ agp_remap (unsigned long offset, unsigne
+ 	return addr;
+ }
+ 
+-static inline unsigned long
+-drm_follow_page (void *vaddr)
++static inline unsigned long drm_follow_page(void *vaddr)
+ {
+-	pgd_t *pgd = pgd_offset_k((unsigned long) vaddr);
+-	pud_t *pud = pud_offset(pgd, (unsigned long) vaddr);
+-	pmd_t *pmd = pmd_offset(pud, (unsigned long) vaddr);
+-	pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr);
++	pgd_t *pgd = pgd_offset_k((unsigned long)vaddr);
++	pud_t *pud = pud_offset(pgd, (unsigned long)vaddr);
++	pmd_t *pmd = pmd_offset(pud, (unsigned long)vaddr);
++	pte_t *ptep = pte_offset_kernel(pmd, (unsigned long)vaddr);
+ 	return pte_pfn(*ptep) << PAGE_SHIFT;
+ }
+ 
+-#else /* __OS_HAS_AGP */
++#else				/* __OS_HAS_AGP */
+ 
+-static inline drm_map_t *drm_lookup_map(unsigned long offset, unsigned long size, drm_device_t *dev)
++static inline drm_map_t *drm_lookup_map(unsigned long offset,
++					unsigned long size, drm_device_t * dev)
+ {
+-  return NULL;
++	return NULL;
+ }
+ 
+-static inline void *agp_remap(unsigned long offset, unsigned long size, drm_device_t *dev)
++static inline void *agp_remap(unsigned long offset, unsigned long size,
++			      drm_device_t * dev)
+ {
+-  return NULL;
++	return NULL;
+ }
+ 
+-static inline unsigned long drm_follow_page (void *vaddr)
++static inline unsigned long drm_follow_page(void *vaddr)
+ {
+-  return 0;
++	return 0;
+ }
+ 
+ #endif
+ 
+-static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev)
++static inline void *drm_ioremap(unsigned long offset, unsigned long size,
++				drm_device_t * dev)
+ {
+ 	if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
+ 		drm_map_t *map = drm_lookup_map(offset, size, dev);
+@@ -158,8 +164,8 @@ static inline void *drm_ioremap(unsigned
+ 	return ioremap(offset, size);
+ }
+ 
+-static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
+-					drm_device_t *dev)
++static inline void *drm_ioremap_nocache(unsigned long offset,
++					unsigned long size, drm_device_t * dev)
+ {
+ 	if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
+ 		drm_map_t *map = drm_lookup_map(offset, size, dev);
+@@ -170,7 +176,8 @@ static inline void *drm_ioremap_nocache(
+ 	return ioremap_nocache(offset, size);
+ }
+ 
+-static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev)
++static inline void drm_ioremapfree(void *pt, unsigned long size,
++				   drm_device_t * dev)
+ {
+ 	/*
+ 	 * This is a bit ugly.  It would be much cleaner if the DRM API would use separate
+@@ -178,12 +185,12 @@ static inline void drm_ioremapfree(void 
+ 	 * a future revision of the interface...
+ 	 */
+ 	if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
+-	    && ((unsigned long) pt >= VMALLOC_START && (unsigned long) pt < VMALLOC_END))
+-	{
++	    && ((unsigned long)pt >= VMALLOC_START
++		&& (unsigned long)pt < VMALLOC_END)) {
+ 		unsigned long offset;
+ 		drm_map_t *map;
+ 
+-		offset = drm_follow_page(pt) | ((unsigned long) pt & ~PAGE_MASK);
++		offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
+ 		map = drm_lookup_map(offset, size, dev);
+ 		if (map && map->type == _DRM_AGP) {
+ 			vunmap(pt);
+@@ -193,5 +200,3 @@ static inline void drm_ioremapfree(void 
+ 
+ 	iounmap(pt);
+ }
+-
+-
+diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
+--- a/drivers/char/drm/drm_memory_debug.h
++++ b/drivers/char/drm/drm_memory_debug.h
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_memory.h 
++ * \file drm_memory.h
+  * Memory management wrappers for DRM.
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+@@ -35,75 +35,75 @@
+ #include "drmP.h"
+ 
+ typedef struct drm_mem_stats {
+-	const char	  *name;
+-	int		  succeed_count;
+-	int		  free_count;
+-	int		  fail_count;
+-	unsigned long	  bytes_allocated;
+-	unsigned long	  bytes_freed;
++	const char *name;
++	int succeed_count;
++	int free_count;
++	int fail_count;
++	unsigned long bytes_allocated;
++	unsigned long bytes_freed;
+ } drm_mem_stats_t;
+ 
+ static DEFINE_SPINLOCK(DRM(mem_lock));
+-static unsigned long	  DRM(ram_available) = 0; /* In pages */
+-static unsigned long	  DRM(ram_used)      = 0;
+-static drm_mem_stats_t	  DRM(mem_stats)[]   = {
+-	[DRM_MEM_DMA]	    = { "dmabufs"  },
+-	[DRM_MEM_SAREA]	    = { "sareas"   },
+-	[DRM_MEM_DRIVER]    = { "driver"   },
+-	[DRM_MEM_MAGIC]	    = { "magic"	   },
+-	[DRM_MEM_IOCTLS]    = { "ioctltab" },
+-	[DRM_MEM_MAPS]	    = { "maplist"  },
+-	[DRM_MEM_VMAS]	    = { "vmalist"  },
+-	[DRM_MEM_BUFS]	    = { "buflist"  },
+-	[DRM_MEM_SEGS]	    = { "seglist"  },
+-	[DRM_MEM_PAGES]	    = { "pagelist" },
+-	[DRM_MEM_FILES]	    = { "files"	   },
+-	[DRM_MEM_QUEUES]    = { "queues"   },
+-	[DRM_MEM_CMDS]	    = { "commands" },
+-	[DRM_MEM_MAPPINGS]  = { "mappings" },
+-	[DRM_MEM_BUFLISTS]  = { "buflists" },
+-	[DRM_MEM_AGPLISTS]  = { "agplist"  },
+-	[DRM_MEM_SGLISTS]   = { "sglist"   },
+-	[DRM_MEM_TOTALAGP]  = { "totalagp" },
+-	[DRM_MEM_BOUNDAGP]  = { "boundagp" },
+-	[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
+-	[DRM_MEM_CTXLIST]   = { "ctxlist"  },
+-	[DRM_MEM_STUB]      = { "stub"     },
+-	{ NULL, 0, }		/* Last entry must be null */
++static unsigned long DRM(ram_available) = 0;	/* In pages */
++static unsigned long DRM(ram_used) = 0;
++static drm_mem_stats_t DRM(mem_stats)[] =
++{
++	[DRM_MEM_DMA] = {
++	"dmabufs"},[DRM_MEM_SAREA] = {
++	"sareas"},[DRM_MEM_DRIVER] = {
++	"driver"},[DRM_MEM_MAGIC] = {
++	"magic"},[DRM_MEM_IOCTLS] = {
++	"ioctltab"},[DRM_MEM_MAPS] = {
++	"maplist"},[DRM_MEM_VMAS] = {
++	"vmalist"},[DRM_MEM_BUFS] = {
++	"buflist"},[DRM_MEM_SEGS] = {
++	"seglist"},[DRM_MEM_PAGES] = {
++	"pagelist"},[DRM_MEM_FILES] = {
++	"files"},[DRM_MEM_QUEUES] = {
++	"queues"},[DRM_MEM_CMDS] = {
++	"commands"},[DRM_MEM_MAPPINGS] = {
++	"mappings"},[DRM_MEM_BUFLISTS] = {
++	"buflists"},[DRM_MEM_AGPLISTS] = {
++	"agplist"},[DRM_MEM_SGLISTS] = {
++	"sglist"},[DRM_MEM_TOTALAGP] = {
++	"totalagp"},[DRM_MEM_BOUNDAGP] = {
++	"boundagp"},[DRM_MEM_CTXBITMAP] = {
++	"ctxbitmap"},[DRM_MEM_CTXLIST] = {
++	"ctxlist"},[DRM_MEM_STUB] = {
++	"stub"}, {
++	NULL, 0,}		/* Last entry must be null */
+ };
+ 
+-void DRM(mem_init)(void)
+-{
++void DRM(mem_init) (void) {
+ 	drm_mem_stats_t *mem;
+-	struct sysinfo	si;
++	struct sysinfo si;
+ 
+ 	for (mem = DRM(mem_stats); mem->name; ++mem) {
+-		mem->succeed_count   = 0;
+-		mem->free_count	     = 0;
+-		mem->fail_count	     = 0;
++		mem->succeed_count = 0;
++		mem->free_count = 0;
++		mem->fail_count = 0;
+ 		mem->bytes_allocated = 0;
+-		mem->bytes_freed     = 0;
++		mem->bytes_freed = 0;
+ 	}
+ 
+ 	si_meminfo(&si);
+ 	DRM(ram_available) = si.totalram;
+-	DRM(ram_used)	   = 0;
++	DRM(ram_used) = 0;
+ }
+ 
+ /* drm_mem_info is called whenever a process reads /dev/drm/mem. */
+ 
+-static int DRM(_mem_info)(char *buf, char **start, off_t offset,
+-			  int request, int *eof, void *data)
+-{
++static int DRM(_mem_info) (char *buf, char **start, off_t offset,
++			   int request, int *eof, void *data) {
+ 	drm_mem_stats_t *pt;
+-	int             len = 0;
++	int len = 0;
+ 
+ 	if (offset > DRM_PROC_LIMIT) {
+ 		*eof = 1;
+ 		return 0;
+ 	}
+ 
+-	*eof   = 0;
++	*eof = 0;
+ 	*start = &buf[offset];
+ 
+ 	DRM_PROC_PRINT("		  total counts			"
+@@ -129,24 +129,23 @@ static int DRM(_mem_info)(char *buf, cha
+ 			       - (long)pt->bytes_freed);
+ 	}
+ 
+-	if (len > request + offset) return request;
++	if (len > request + offset)
++		return request;
+ 	*eof = 1;
+ 	return len - offset;
+ }
+ 
+-int DRM(mem_info)(char *buf, char **start, off_t offset,
+-		  int len, int *eof, void *data)
+-{
++int DRM(mem_info) (char *buf, char **start, off_t offset,
++		   int len, int *eof, void *data) {
+ 	int ret;
+ 
+ 	spin_lock(&DRM(mem_lock));
+-	ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
++	ret = DRM(_mem_info) (buf, start, offset, len, eof, data);
+ 	spin_unlock(&DRM(mem_lock));
+ 	return ret;
+ }
+ 
+-void *DRM(alloc)(size_t size, int area)
+-{
++void *DRM(alloc) (size_t size, int area) {
+ 	void *pt;
+ 
+ 	if (!size) {
+@@ -167,40 +166,40 @@ void *DRM(alloc)(size_t size, int area)
+ 	return pt;
+ }
+ 
+-void *DRM(calloc)(size_t nmemb, size_t size, int area)
+-{
++void *DRM(calloc) (size_t nmemb, size_t size, int area) {
+ 	void *addr;
+ 
+-	addr = DRM(alloc)(nmemb * size, area);
++	addr = DRM(alloc) (nmemb * size, area);
+ 	if (addr != NULL)
+ 		memset((void *)addr, 0, size * nmemb);
+ 
+ 	return addr;
+ }
+ 
+-void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
+-{
++void *DRM(realloc) (void *oldpt, size_t oldsize, size_t size, int area) {
+ 	void *pt;
+ 
+-	if (!(pt = DRM(alloc)(size, area))) return NULL;
++	if (!(pt = DRM(alloc) (size, area)))
++		return NULL;
+ 	if (oldpt && oldsize) {
+ 		memcpy(pt, oldpt, oldsize);
+-		DRM(free)(oldpt, oldsize, area);
++		DRM(free) (oldpt, oldsize, area);
+ 	}
+ 	return pt;
+ }
+ 
+-void DRM(free)(void *pt, size_t size, int area)
+-{
++void DRM(free) (void *pt, size_t size, int area) {
+ 	int alloc_count;
+ 	int free_count;
+ 
+-	if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
+-	else	 kfree(pt);
++	if (!pt)
++		DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
++	else
++		kfree(pt);
+ 	spin_lock(&DRM(mem_lock));
+ 	DRM(mem_stats)[area].bytes_freed += size;
+-	free_count  = ++DRM(mem_stats)[area].free_count;
+-	alloc_count =	DRM(mem_stats)[area].succeed_count;
++	free_count = ++DRM(mem_stats)[area].free_count;
++	alloc_count = DRM(mem_stats)[area].succeed_count;
+ 	spin_unlock(&DRM(mem_lock));
+ 	if (free_count > alloc_count) {
+ 		DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
+@@ -208,12 +207,11 @@ void DRM(free)(void *pt, size_t size, in
+ 	}
+ }
+ 
+-unsigned long DRM(alloc_pages)(int order, int area)
+-{
++unsigned long DRM(alloc_pages) (int order, int area) {
+ 	unsigned long address;
+-	unsigned long bytes	  = PAGE_SIZE << order;
++	unsigned long bytes = PAGE_SIZE << order;
+ 	unsigned long addr;
+-	unsigned int  sz;
++	unsigned int sz;
+ 
+ 	spin_lock(&DRM(mem_lock));
+ 	if ((DRM(ram_used) >> PAGE_SHIFT)
+@@ -233,48 +231,44 @@ unsigned long DRM(alloc_pages)(int order
+ 	spin_lock(&DRM(mem_lock));
+ 	++DRM(mem_stats)[area].succeed_count;
+ 	DRM(mem_stats)[area].bytes_allocated += bytes;
+-	DRM(ram_used)		             += bytes;
++	DRM(ram_used) += bytes;
+ 	spin_unlock(&DRM(mem_lock));
+ 
+-
+-				/* Zero outside the lock */
++	/* Zero outside the lock */
+ 	memset((void *)address, 0, bytes);
+ 
+-				/* Reserve */
++	/* Reserve */
+ 	for (addr = address, sz = bytes;
+-	     sz > 0;
+-	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
++	     sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ 		SetPageReserved(virt_to_page(addr));
+ 	}
+ 
+ 	return address;
+ }
+ 
+-void DRM(free_pages)(unsigned long address, int order, int area)
+-{
++void DRM(free_pages) (unsigned long address, int order, int area) {
+ 	unsigned long bytes = PAGE_SIZE << order;
+-	int		  alloc_count;
+-	int		  free_count;
++	int alloc_count;
++	int free_count;
+ 	unsigned long addr;
+-	unsigned int  sz;
++	unsigned int sz;
+ 
+ 	if (!address) {
+ 		DRM_MEM_ERROR(area, "Attempt to free address 0\n");
+ 	} else {
+-				/* Unreserve */
++		/* Unreserve */
+ 		for (addr = address, sz = bytes;
+-		     sz > 0;
+-		     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
++		     sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ 			ClearPageReserved(virt_to_page(addr));
+ 		}
+ 		free_pages(address, order);
+ 	}
+ 
+ 	spin_lock(&DRM(mem_lock));
+-	free_count  = ++DRM(mem_stats)[area].free_count;
+-	alloc_count =	DRM(mem_stats)[area].succeed_count;
++	free_count = ++DRM(mem_stats)[area].free_count;
++	alloc_count = DRM(mem_stats)[area].succeed_count;
+ 	DRM(mem_stats)[area].bytes_freed += bytes;
+-	DRM(ram_used)			 -= bytes;
++	DRM(ram_used) -= bytes;
+ 	spin_unlock(&DRM(mem_lock));
+ 	if (free_count > alloc_count) {
+ 		DRM_MEM_ERROR(area,
+@@ -283,8 +277,8 @@ void DRM(free_pages)(unsigned long addre
+ 	}
+ }
+ 
+-void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
+-{
++void *DRM(ioremap) (unsigned long offset, unsigned long size,
++		    drm_device_t * dev) {
+ 	void *pt;
+ 
+ 	if (!size) {
+@@ -306,8 +300,8 @@ void *DRM(ioremap)(unsigned long offset,
+ 	return pt;
+ }
+ 
+-void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
+-{
++void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size,
++			    drm_device_t * dev) {
+ 	void *pt;
+ 
+ 	if (!size) {
+@@ -329,8 +323,7 @@ void *DRM(ioremap_nocache)(unsigned long
+ 	return pt;
+ }
+ 
+-void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
+-{
++void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) {
+ 	int alloc_count;
+ 	int free_count;
+ 
+@@ -342,8 +335,8 @@ void DRM(ioremapfree)(void *pt, unsigned
+ 
+ 	spin_lock(&DRM(mem_lock));
+ 	DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
+-	free_count  = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
+-	alloc_count =	DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
++	free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
++	alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ 	spin_unlock(&DRM(mem_lock));
+ 	if (free_count > alloc_count) {
+ 		DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+@@ -354,8 +347,7 @@ void DRM(ioremapfree)(void *pt, unsigned
+ 
+ #if __OS_HAS_AGP
+ 
+-DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
+-{
++DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) {
+ 	DRM_AGP_MEM *handle;
+ 
+ 	if (!pages) {
+@@ -363,11 +355,11 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u
+ 		return NULL;
+ 	}
+ 
+-	if ((handle = DRM(agp_allocate_memory)(pages, type))) {
++	if ((handle = DRM(agp_allocate_memory) (pages, type))) {
+ 		spin_lock(&DRM(mem_lock));
+ 		++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
+ 		DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
+-			+= pages << PAGE_SHIFT;
++		    += pages << PAGE_SHIFT;
+ 		spin_unlock(&DRM(mem_lock));
+ 		return handle;
+ 	}
+@@ -377,11 +369,10 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u
+ 	return NULL;
+ }
+ 
+-int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
+-{
+-	int           alloc_count;
+-	int           free_count;
+-	int           retval = -EINVAL;
++int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) {
++	int alloc_count;
++	int free_count;
++	int retval = -EINVAL;
+ 
+ 	if (!handle) {
+ 		DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+@@ -389,12 +380,12 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, i
+ 		return retval;
+ 	}
+ 
+-	if (DRM(agp_free_memory)(handle)) {
++	if (DRM(agp_free_memory) (handle)) {
+ 		spin_lock(&DRM(mem_lock));
+-		free_count  = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
+-		alloc_count =   DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
++		free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
++		alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
+ 		DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
+-			+= pages << PAGE_SHIFT;
++		    += pages << PAGE_SHIFT;
+ 		spin_unlock(&DRM(mem_lock));
+ 		if (free_count > alloc_count) {
+ 			DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+@@ -406,8 +397,7 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, i
+ 	return retval;
+ }
+ 
+-int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
+-{
++int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) {
+ 	int retcode = -EINVAL;
+ 
+ 	if (!handle) {
+@@ -416,11 +406,11 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, u
+ 		return retcode;
+ 	}
+ 
+-	if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
++	if (!(retcode = DRM(agp_bind_memory) (handle, start))) {
+ 		spin_lock(&DRM(mem_lock));
+ 		++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
+ 		DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
+-			+= handle->page_count << PAGE_SHIFT;
++		    += handle->page_count << PAGE_SHIFT;
+ 		spin_unlock(&DRM(mem_lock));
+ 		return retcode;
+ 	}
+@@ -430,8 +420,7 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, u
+ 	return retcode;
+ }
+ 
+-int DRM(unbind_agp)(DRM_AGP_MEM *handle)
+-{
++int DRM(unbind_agp) (DRM_AGP_MEM * handle) {
+ 	int alloc_count;
+ 	int free_count;
+ 	int retcode = -EINVAL;
+@@ -442,12 +431,13 @@ int DRM(unbind_agp)(DRM_AGP_MEM *handle)
+ 		return retcode;
+ 	}
+ 
+-	if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode;
++	if ((retcode = DRM(agp_unbind_memory) (handle)))
++		return retcode;
+ 	spin_lock(&DRM(mem_lock));
+-	free_count  = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
++	free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
+ 	alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
+ 	DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
+-		+= handle->page_count << PAGE_SHIFT;
++	    += handle->page_count << PAGE_SHIFT;
+ 	spin_unlock(&DRM(mem_lock));
+ 	if (free_count > alloc_count) {
+ 		DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
+--- a/drivers/char/drm/drm_os_linux.h
++++ b/drivers/char/drm/drm_os_linux.h
+@@ -3,7 +3,6 @@
+  * OS abstraction macros.
+  */
+ 
+-
+ #include <linux/interrupt.h>	/* For task queue support */
+ #include <linux/delay.h>
+ 
+@@ -47,25 +46,25 @@
+ #else
+ /* define some dummy types for non AGP supporting kernels */
+ struct no_agp_kern {
+-  unsigned long aper_base;
+-  unsigned long aper_size;
++	unsigned long aper_base;
++	unsigned long aper_size;
+ };
+ #define DRM_AGP_MEM             int
+ #define DRM_AGP_KERN            struct no_agp_kern
+ #endif
+ 
+ #if !(__OS_HAS_MTRR)
+-static __inline__ int mtrr_add (unsigned long base, unsigned long size,
+-                                unsigned int type, char increment)
++static __inline__ int mtrr_add(unsigned long base, unsigned long size,
++			       unsigned int type, char increment)
+ {
+ 	return -ENODEV;
+ }
+ 
+-static __inline__ int mtrr_del (int reg, unsigned long base,
+-                                unsigned long size)
++static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
+ {
+ 	return -ENODEV;
+ }
++
+ #define MTRR_TYPE_WRCOMB     1
+ 
+ #endif
+@@ -99,7 +98,7 @@ static __inline__ int mtrr_del (int reg,
+ 
+ #define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data
+ 
+-/** 
++/**
+  * Get the pointer to the SAREA.
+  *
+  * Searches the SAREA on the mapping lists and points drm_device::sarea to it.
+@@ -143,7 +142,5 @@ do {								\
+ 	remove_wait_queue(&(queue), &entry);			\
+ } while (0)
+ 
+-
+ #define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
+ #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
+- 
+diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
+--- a/drivers/char/drm/drm_pci.c
++++ b/drivers/char/drm/drm_pci.c
+@@ -77,7 +77,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_devi
+ 	dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
+ 	if (!dmah)
+ 		return NULL;
+-	
++
+ 	dmah->size = size;
+ 	dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr);
+ 
+@@ -106,6 +106,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_devi
+ 
+ 	return dmah;
+ }
++
+ EXPORT_SYMBOL(drm_pci_alloc);
+ 
+ /**
+@@ -113,8 +114,7 @@ EXPORT_SYMBOL(drm_pci_alloc);
+  *
+  * This function is for internal use in the Linux-specific DRM core code.
+  */
+-void
+-__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
++void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
+ {
+ #ifdef DRM_DEBUG_MEMORY
+ 	int area = DRM_MEM_DMA;
+@@ -150,12 +150,12 @@ __drm_pci_free(drm_device_t * dev, drm_d
+ /**
+  * \brief Free a PCI consistent memory block
+  */
+-void
+-drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
++void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
+ {
+ 	__drm_pci_free(dev, dmah);
+ 	kfree(dmah);
+ }
++
+ EXPORT_SYMBOL(drm_pci_free);
+ 
+ /*@}*/
+diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
+--- a/drivers/char/drm/drm_pciids.h
++++ b/drivers/char/drm/drm_pciids.h
+@@ -234,4 +234,3 @@
+ 	{0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ 	{0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ 	{0, 0, 0}
+-
+diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
+--- a/drivers/char/drm/drm_proc.c
++++ b/drivers/char/drm/drm_proc.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_proc.h 
++ * \file drm_proc.c
+  * /proc support for DRM
+  *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+@@ -39,19 +39,19 @@
+ 
+ #include "drmP.h"
+ 
+-static int	   drm_name_info(char *buf, char **start, off_t offset,
+-				  int request, int *eof, void *data);
+-static int	   drm_vm_info(char *buf, char **start, off_t offset,
+-				int request, int *eof, void *data);
+-static int	   drm_clients_info(char *buf, char **start, off_t offset,
+-				     int request, int *eof, void *data);
+-static int	   drm_queues_info(char *buf, char **start, off_t offset,
+-				    int request, int *eof, void *data);
+-static int	   drm_bufs_info(char *buf, char **start, off_t offset,
+-				  int request, int *eof, void *data);
++static int drm_name_info(char *buf, char **start, off_t offset,
++			 int request, int *eof, void *data);
++static int drm_vm_info(char *buf, char **start, off_t offset,
++		       int request, int *eof, void *data);
++static int drm_clients_info(char *buf, char **start, off_t offset,
++			    int request, int *eof, void *data);
++static int drm_queues_info(char *buf, char **start, off_t offset,
++			   int request, int *eof, void *data);
++static int drm_bufs_info(char *buf, char **start, off_t offset,
++			 int request, int *eof, void *data);
+ #if DRM_DEBUG_CODE
+-static int	   drm_vma_info(char *buf, char **start, off_t offset,
+-				 int request, int *eof, void *data);
++static int drm_vma_info(char *buf, char **start, off_t offset,
++			int request, int *eof, void *data);
+ #endif
+ 
+ /**
+@@ -59,18 +59,21 @@ static int	   drm_vma_info(char *buf, ch
+  */
+ static struct drm_proc_list {
+ 	const char *name;	/**< file name */
+-	int	   (*f)(char *, char **, off_t, int, int *, void *);	/**< proc callback*/
++	int (*f) (char *, char **, off_t, int, int *, void *);		/**< proc callback*/
+ } drm_proc_list[] = {
+-	{ "name",    drm_name_info    },
+-	{ "mem",     drm_mem_info     },
+-	{ "vm",	     drm_vm_info      },
+-	{ "clients", drm_clients_info },
+-	{ "queues",  drm_queues_info  },
+-	{ "bufs",    drm_bufs_info    },
++	{
++	"name", drm_name_info}, {
++	"mem", drm_mem_info}, {
++	"vm", drm_vm_info}, {
++	"clients", drm_clients_info}, {
++	"queues", drm_queues_info}, {
++	"bufs", drm_bufs_info},
+ #if DRM_DEBUG_CODE
+-	{ "vma",     drm_vma_info     },
++	{
++	"vma", drm_vma_info},
+ #endif
+ };
++
+ #define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
+ 
+ /**
+@@ -81,18 +84,17 @@ static struct drm_proc_list {
+  * \param root DRI proc dir entry.
+  * \param dev_root resulting DRI device proc dir entry.
+  * \return root entry pointer on success, or NULL on failure.
+- * 
++ *
+  * Create the DRI proc root entry "/proc/dri", the device proc root entry
+  * "/proc/dri/%minor%/", and each entry in proc_list as
+  * "/proc/dri/%minor%/%name%".
+  */
+-int drm_proc_init(drm_device_t *dev, int minor,
+-		    struct proc_dir_entry *root,
+-		    struct proc_dir_entry **dev_root)
++int drm_proc_init(drm_device_t * dev, int minor,
++		  struct proc_dir_entry *root, struct proc_dir_entry **dev_root)
+ {
+ 	struct proc_dir_entry *ent;
+-	int		      i, j;
+-	char                  name[64];
++	int i, j;
++	char name[64];
+ 
+ 	sprintf(name, "%d", minor);
+ 	*dev_root = proc_mkdir(name, root);
+@@ -103,7 +105,7 @@ int drm_proc_init(drm_device_t *dev, int
+ 
+ 	for (i = 0; i < DRM_PROC_ENTRIES; i++) {
+ 		ent = create_proc_entry(drm_proc_list[i].name,
+-					S_IFREG|S_IRUGO, *dev_root);
++					S_IFREG | S_IRUGO, *dev_root);
+ 		if (!ent) {
+ 			DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
+ 				  name, drm_proc_list[i].name);
+@@ -114,13 +116,12 @@ int drm_proc_init(drm_device_t *dev, int
+ 			return -1;
+ 		}
+ 		ent->read_proc = drm_proc_list[i].f;
+-		ent->data      = dev;
++		ent->data = dev;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-
+ /**
+  * Cleanup the proc filesystem resources.
+  *
+@@ -132,12 +133,13 @@ int drm_proc_init(drm_device_t *dev, int
+  * Remove all proc entries created by proc_init().
+  */
+ int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
+-		      struct proc_dir_entry *dev_root)
++		     struct proc_dir_entry *dev_root)
+ {
+-	int  i;
++	int i;
+ 	char name[64];
+ 
+-	if (!root || !dev_root) return 0;
++	if (!root || !dev_root)
++		return 0;
+ 
+ 	for (i = 0; i < DRM_PROC_ENTRIES; i++)
+ 		remove_proc_entry(drm_proc_list[i].name, dev_root);
+@@ -149,7 +151,7 @@ int drm_proc_cleanup(int minor, struct p
+ 
+ /**
+  * Called when "/proc/dri/.../name" is read.
+- * 
++ *
+  * \param buf output buffer.
+  * \param start start of output data.
+  * \param offset requested start offset.
+@@ -157,14 +159,14 @@ int drm_proc_cleanup(int minor, struct p
+  * \param eof whether there is no more data to return.
+  * \param data private data.
+  * \return number of written bytes.
+- * 
++ *
+  * Prints the device name together with the bus id if available.
+  */
+ static int drm_name_info(char *buf, char **start, off_t offset, int request,
+-			  int *eof, void *data)
++			 int *eof, void *data)
+ {
+-	drm_device_t *dev = (drm_device_t *)data;
+-	int          len  = 0;
++	drm_device_t *dev = (drm_device_t *) data;
++	int len = 0;
+ 
+ 	if (offset > DRM_PROC_LIMIT) {
+ 		*eof = 1;
+@@ -172,23 +174,26 @@ static int drm_name_info(char *buf, char
+ 	}
+ 
+ 	*start = &buf[offset];
+-	*eof   = 0;
++	*eof = 0;
+ 
+ 	if (dev->unique) {
+ 		DRM_PROC_PRINT("%s %s %s\n",
+-			       dev->driver->pci_driver.name, pci_name(dev->pdev), dev->unique);
++			       dev->driver->pci_driver.name,
++			       pci_name(dev->pdev), dev->unique);
+ 	} else {
+-		DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name, pci_name(dev->pdev));
++		DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name,
++			       pci_name(dev->pdev));
+ 	}
+ 
+-	if (len > request + offset) return request;
++	if (len > request + offset)
++		return request;
+ 	*eof = 1;
+ 	return len - offset;
+ }
+ 
+ /**
+  * Called when "/proc/dri/.../vm" is read.
+- * 
++ *
+  * \param buf output buffer.
+  * \param start start of output data.
+  * \param offset requested start offset.
+@@ -196,24 +201,24 @@ static int drm_name_info(char *buf, char
+  * \param eof whether there is no more data to return.
+  * \param data private data.
+  * \return number of written bytes.
+- * 
++ *
+  * Prints information about all mappings in drm_device::maplist.
+  */
+ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
+-			 int *eof, void *data)
++			int *eof, void *data)
+ {
+-	drm_device_t *dev = (drm_device_t *)data;
+-	int          len  = 0;
+-	drm_map_t    *map;
++	drm_device_t *dev = (drm_device_t *) data;
++	int len = 0;
++	drm_map_t *map;
+ 	drm_map_list_t *r_list;
+ 	struct list_head *list;
+ 
+-				/* Hardcoded from _DRM_FRAME_BUFFER,
+-                                   _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
+-                                   _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
+-	const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
+-	const char   *type;
+-	int	     i;
++	/* Hardcoded from _DRM_FRAME_BUFFER,
++	   _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
++	   _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
++	const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
++	const char *type;
++	int i;
+ 
+ 	if (offset > DRM_PROC_LIMIT) {
+ 		*eof = 1;
+@@ -221,36 +226,35 @@ static int drm__vm_info(char *buf, char 
+ 	}
+ 
+ 	*start = &buf[offset];
+-	*eof   = 0;
++	*eof = 0;
+ 
+ 	DRM_PROC_PRINT("slot	 offset	      size type flags	 "
+ 		       "address mtrr\n\n");
+ 	i = 0;
+-	if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
++	if (dev->maplist != NULL)
++		list_for_each(list, &dev->maplist->head) {
+ 		r_list = list_entry(list, drm_map_list_t, head);
+ 		map = r_list->map;
+-		if(!map)
++		if (!map)
+ 			continue;
+ 		if (map->type < 0 || map->type > 5)
+ 			type = "??";
+-		else	
++		else
+ 			type = types[map->type];
+ 		DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08x ",
+ 			       i,
+ 			       map->offset,
+-			       map->size,
+-			       type,
+-			       map->flags,
+-			       r_list->user_token);
++			       map->size, type, map->flags, r_list->user_token);
+ 		if (map->mtrr < 0) {
+ 			DRM_PROC_PRINT("none\n");
+ 		} else {
+ 			DRM_PROC_PRINT("%4d\n", map->mtrr);
+ 		}
+ 		i++;
+-	}
++		}
+ 
+-	if (len > request + offset) return request;
++	if (len > request + offset)
++		return request;
+ 	*eof = 1;
+ 	return len - offset;
+ }
+@@ -259,10 +263,10 @@ static int drm__vm_info(char *buf, char 
+  * Simply calls _vm_info() while holding the drm_device::struct_sem lock.
+  */
+ static int drm_vm_info(char *buf, char **start, off_t offset, int request,
+-			int *eof, void *data)
++		       int *eof, void *data)
+ {
+-	drm_device_t *dev = (drm_device_t *)data;
+-	int	     ret;
++	drm_device_t *dev = (drm_device_t *) data;
++	int ret;
+ 
+ 	down(&dev->struct_sem);
+ 	ret = drm__vm_info(buf, start, offset, request, eof, data);
+@@ -272,7 +276,7 @@ static int drm_vm_info(char *buf, char *
+ 
+ /**
+  * Called when "/proc/dri/.../queues" is read.
+- * 
++ *
+  * \param buf output buffer.
+  * \param start start of output data.
+  * \param offset requested start offset.
+@@ -282,12 +286,12 @@ static int drm_vm_info(char *buf, char *
+  * \return number of written bytes.
+  */
+ static int drm__queues_info(char *buf, char **start, off_t offset,
+-			     int request, int *eof, void *data)
++			    int request, int *eof, void *data)
+ {
+-	drm_device_t *dev = (drm_device_t *)data;
+-	int          len  = 0;
+-	int	     i;
+-	drm_queue_t  *q;
++	drm_device_t *dev = (drm_device_t *) data;
++	int len = 0;
++	int i;
++	drm_queue_t *q;
+ 
+ 	if (offset > DRM_PROC_LIMIT) {
+ 		*eof = 1;
+@@ -295,7 +299,7 @@ static int drm__queues_info(char *buf, c
+ 	}
+ 
+ 	*start = &buf[offset];
+-	*eof   = 0;
++	*eof = 0;
+ 
+ 	DRM_PROC_PRINT("  ctx/flags   use   fin"
+ 		       "   blk/rw/rwf  wait    flushed	   queued"
+@@ -313,14 +317,17 @@ static int drm__queues_info(char *buf, c
+ 				   atomic_read(&q->block_count),
+ 				   atomic_read(&q->block_read) ? 'r' : '-',
+ 				   atomic_read(&q->block_write) ? 'w' : '-',
+-				   waitqueue_active(&q->read_queue) ? 'r':'-',
+-				   waitqueue_active(&q->write_queue) ? 'w':'-',
+-				   waitqueue_active(&q->flush_queue) ? 'f':'-',
++				   waitqueue_active(&q->read_queue) ? 'r' : '-',
++				   waitqueue_active(&q->
++						    write_queue) ? 'w' : '-',
++				   waitqueue_active(&q->
++						    flush_queue) ? 'f' : '-',
+ 				   DRM_BUFCOUNT(&q->waitlist));
+ 		atomic_dec(&q->use_count);
+ 	}
+ 
+-	if (len > request + offset) return request;
++	if (len > request + offset)
++		return request;
+ 	*eof = 1;
+ 	return len - offset;
+ }
+@@ -329,10 +336,10 @@ static int drm__queues_info(char *buf, c
+  * Simply calls _queues_info() while holding the drm_device::struct_sem lock.
+  */
+ static int drm_queues_info(char *buf, char **start, off_t offset, int request,
+-			    int *eof, void *data)
++			   int *eof, void *data)
+ {
+-	drm_device_t *dev = (drm_device_t *)data;
+-	int	     ret;
++	drm_device_t *dev = (drm_device_t *) data;
++	int ret;
+ 
+ 	down(&dev->struct_sem);
+ 	ret = drm__queues_info(buf, start, offset, request, eof, data);
+@@ -342,7 +349,7 @@ static int drm_queues_info(char *buf, ch
+ 
+ /**
+  * Called when "/proc/dri/.../bufs" is read.
+- * 
++ *
+  * \param buf output buffer.
+  * \param start start of output data.
+  * \param offset requested start offset.
+@@ -352,12 +359,12 @@ static int drm_queues_info(char *buf, ch
+  * \return number of written bytes.
+  */
+ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
+-			   int *eof, void *data)
++			  int *eof, void *data)
+ {
+-	drm_device_t	 *dev = (drm_device_t *)data;
+-	int              len  = 0;
++	drm_device_t *dev = (drm_device_t *) data;
++	int len = 0;
+ 	drm_device_dma_t *dma = dev->dma;
+-	int		 i;
++	int i;
+ 
+ 	if (!dma || offset > DRM_PROC_LIMIT) {
+ 		*eof = 1;
+@@ -365,7 +372,7 @@ static int drm__bufs_info(char *buf, cha
+ 	}
+ 
+ 	*start = &buf[offset];
+-	*eof   = 0;
++	*eof = 0;
+ 
+ 	DRM_PROC_PRINT(" o     size count  free	 segs pages    kB\n\n");
+ 	for (i = 0; i <= DRM_MAX_ORDER; i++) {
+@@ -378,19 +385,21 @@ static int drm__bufs_info(char *buf, cha
+ 						   .freelist.count),
+ 				       dma->bufs[i].seg_count,
+ 				       dma->bufs[i].seg_count
+-				       *(1 << dma->bufs[i].page_order),
++				       * (1 << dma->bufs[i].page_order),
+ 				       (dma->bufs[i].seg_count
+ 					* (1 << dma->bufs[i].page_order))
+ 				       * PAGE_SIZE / 1024);
+ 	}
+ 	DRM_PROC_PRINT("\n");
+ 	for (i = 0; i < dma->buf_count; i++) {
+-		if (i && !(i%32)) DRM_PROC_PRINT("\n");
++		if (i && !(i % 32))
++			DRM_PROC_PRINT("\n");
+ 		DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
+ 	}
+ 	DRM_PROC_PRINT("\n");
+ 
+-	if (len > request + offset) return request;
++	if (len > request + offset)
++		return request;
+ 	*eof = 1;
+ 	return len - offset;
+ }
+@@ -399,10 +408,10 @@ static int drm__bufs_info(char *buf, cha
+  * Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
+  */
+ static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
+-			  int *eof, void *data)
++			 int *eof, void *data)
+ {
+-	drm_device_t *dev = (drm_device_t *)data;
+-	int	     ret;
++	drm_device_t *dev = (drm_device_t *) data;
++	int ret;
+ 
+ 	down(&dev->struct_sem);
+ 	ret = drm__bufs_info(buf, start, offset, request, eof, data);
+@@ -412,7 +421,7 @@ static int drm_bufs_info(char *buf, char
+ 
+ /**
+  * Called when "/proc/dri/.../clients" is read.
+- * 
++ *
+  * \param buf output buffer.
+  * \param start start of output data.
+  * \param offset requested start offset.
+@@ -422,11 +431,11 @@ static int drm_bufs_info(char *buf, char
+  * \return number of written bytes.
+  */
+ static int drm__clients_info(char *buf, char **start, off_t offset,
+-			      int request, int *eof, void *data)
++			     int request, int *eof, void *data)
+ {
+-	drm_device_t *dev = (drm_device_t *)data;
+-	int          len  = 0;
+-	drm_file_t   *priv;
++	drm_device_t *dev = (drm_device_t *) data;
++	int len = 0;
++	drm_file_t *priv;
+ 
+ 	if (offset > DRM_PROC_LIMIT) {
+ 		*eof = 1;
+@@ -434,7 +443,7 @@ static int drm__clients_info(char *buf, 
+ 	}
+ 
+ 	*start = &buf[offset];
+-	*eof   = 0;
++	*eof = 0;
+ 
+ 	DRM_PROC_PRINT("a dev	pid    uid	magic	  ioctls\n\n");
+ 	for (priv = dev->file_first; priv; priv = priv->next) {
+@@ -442,12 +451,11 @@ static int drm__clients_info(char *buf, 
+ 			       priv->authenticated ? 'y' : 'n',
+ 			       priv->minor,
+ 			       priv->pid,
+-			       priv->uid,
+-			       priv->magic,
+-			       priv->ioctl_count);
++			       priv->uid, priv->magic, priv->ioctl_count);
+ 	}
+ 
+-	if (len > request + offset) return request;
++	if (len > request + offset)
++		return request;
+ 	*eof = 1;
+ 	return len - offset;
+ }
+@@ -456,10 +464,10 @@ static int drm__clients_info(char *buf, 
+  * Simply calls _clients_info() while holding the drm_device::struct_sem lock.
+  */
+ static int drm_clients_info(char *buf, char **start, off_t offset,
+-			     int request, int *eof, void *data)
++			    int request, int *eof, void *data)
+ {
+-	drm_device_t *dev = (drm_device_t *)data;
+-	int	     ret;
++	drm_device_t *dev = (drm_device_t *) data;
++	int ret;
+ 
+ 	down(&dev->struct_sem);
+ 	ret = drm__clients_info(buf, start, offset, request, eof, data);
+@@ -470,14 +478,14 @@ static int drm_clients_info(char *buf, c
+ #if DRM_DEBUG_CODE
+ 
+ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
+-			  int *eof, void *data)
++			 int *eof, void *data)
+ {
+-	drm_device_t	      *dev = (drm_device_t *)data;
+-	int                   len  = 0;
+-	drm_vma_entry_t	      *pt;
++	drm_device_t *dev = (drm_device_t *) data;
++	int len = 0;
++	drm_vma_entry_t *pt;
+ 	struct vm_area_struct *vma;
+ #if defined(__i386__)
+-	unsigned int	      pgprot;
++	unsigned int pgprot;
+ #endif
+ 
+ 	if (offset > DRM_PROC_LIMIT) {
+@@ -486,51 +494,53 @@ static int drm__vma_info(char *buf, char
+ 	}
+ 
+ 	*start = &buf[offset];
+-	*eof   = 0;
++	*eof = 0;
+ 
+ 	DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
+ 		       atomic_read(&dev->vma_count),
+ 		       high_memory, virt_to_phys(high_memory));
+ 	for (pt = dev->vmalist; pt; pt = pt->next) {
+-		if (!(vma = pt->vma)) continue;
++		if (!(vma = pt->vma))
++			continue;
+ 		DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
+ 			       pt->pid,
+ 			       vma->vm_start,
+ 			       vma->vm_end,
+-			       vma->vm_flags & VM_READ	   ? 'r' : '-',
+-			       vma->vm_flags & VM_WRITE	   ? 'w' : '-',
+-			       vma->vm_flags & VM_EXEC	   ? 'x' : '-',
++			       vma->vm_flags & VM_READ ? 'r' : '-',
++			       vma->vm_flags & VM_WRITE ? 'w' : '-',
++			       vma->vm_flags & VM_EXEC ? 'x' : '-',
+ 			       vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+-			       vma->vm_flags & VM_LOCKED   ? 'l' : '-',
+-			       vma->vm_flags & VM_IO	   ? 'i' : '-',
++			       vma->vm_flags & VM_LOCKED ? 'l' : '-',
++			       vma->vm_flags & VM_IO ? 'i' : '-',
+ 			       VM_OFFSET(vma));
+ 
+ #if defined(__i386__)
+ 		pgprot = pgprot_val(vma->vm_page_prot);
+ 		DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
+-			       pgprot & _PAGE_PRESENT  ? 'p' : '-',
+-			       pgprot & _PAGE_RW       ? 'w' : 'r',
+-			       pgprot & _PAGE_USER     ? 'u' : 's',
+-			       pgprot & _PAGE_PWT      ? 't' : 'b',
+-			       pgprot & _PAGE_PCD      ? 'u' : 'c',
++			       pgprot & _PAGE_PRESENT ? 'p' : '-',
++			       pgprot & _PAGE_RW ? 'w' : 'r',
++			       pgprot & _PAGE_USER ? 'u' : 's',
++			       pgprot & _PAGE_PWT ? 't' : 'b',
++			       pgprot & _PAGE_PCD ? 'u' : 'c',
+ 			       pgprot & _PAGE_ACCESSED ? 'a' : '-',
+-			       pgprot & _PAGE_DIRTY    ? 'd' : '-',
+-			       pgprot & _PAGE_PSE      ? 'm' : 'k',
+-			       pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
++			       pgprot & _PAGE_DIRTY ? 'd' : '-',
++			       pgprot & _PAGE_PSE ? 'm' : 'k',
++			       pgprot & _PAGE_GLOBAL ? 'g' : 'l');
+ #endif
+ 		DRM_PROC_PRINT("\n");
+ 	}
+ 
+-	if (len > request + offset) return request;
++	if (len > request + offset)
++		return request;
+ 	*eof = 1;
+ 	return len - offset;
+ }
+ 
+ static int drm_vma_info(char *buf, char **start, off_t offset, int request,
+-			 int *eof, void *data)
++			int *eof, void *data)
+ {
+-	drm_device_t *dev = (drm_device_t *)data;
+-	int	     ret;
++	drm_device_t *dev = (drm_device_t *) data;
++	int ret;
+ 
+ 	down(&dev->struct_sem);
+ 	ret = drm__vma_info(buf, start, offset, request, eof, data);
+@@ -538,5 +548,3 @@ static int drm_vma_info(char *buf, char 
+ 	return ret;
+ }
+ #endif
+-
+-
+diff --git a/drivers/char/drm/drm_sarea.h b/drivers/char/drm/drm_sarea.h
+--- a/drivers/char/drm/drm_sarea.h
++++ b/drivers/char/drm/drm_sarea.h
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_sarea.h 
++ * \file drm_sarea.h
+  * \brief SAREA definitions
+  *
+  * \author Michel Dänzer <michel at daenzer.net>
+@@ -38,7 +38,7 @@
+ #if defined(__alpha__)
+ #define SAREA_MAX                       0x2000
+ #elif defined(__ia64__)
+-#define SAREA_MAX                       0x10000         /* 64kB */
++#define SAREA_MAX                       0x10000	/* 64kB */
+ #else
+ /* Intel 830M driver needs at least 8k SAREA */
+ #define SAREA_MAX                       0x2000
+@@ -51,28 +51,28 @@
+ 
+ /** SAREA drawable */
+ typedef struct drm_sarea_drawable {
+-    unsigned int	stamp;
+-    unsigned int	flags;
++	unsigned int stamp;
++	unsigned int flags;
+ } drm_sarea_drawable_t;
+ 
+ /** SAREA frame */
+ typedef struct drm_sarea_frame {
+-    unsigned int        x;
+-    unsigned int        y;
+-    unsigned int        width;
+-    unsigned int        height;
+-    unsigned int        fullscreen;
++	unsigned int x;
++	unsigned int y;
++	unsigned int width;
++	unsigned int height;
++	unsigned int fullscreen;
+ } drm_sarea_frame_t;
+ 
+ /** SAREA */
+ typedef struct drm_sarea {
+     /** first thing is always the DRM locking structure */
+-    drm_hw_lock_t		lock;
++	drm_hw_lock_t lock;
+     /** \todo Use readers/writer lock for drm_sarea::drawable_lock */
+-    drm_hw_lock_t		drawable_lock;
+-    drm_sarea_drawable_t	drawableTable[SAREA_MAX_DRAWABLES];	/**< drawables */
+-    drm_sarea_frame_t		frame;	/**< frame */
+-    drm_context_t		dummy_context;
++	drm_hw_lock_t drawable_lock;
++	drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES];	/**< drawables */
++	drm_sarea_frame_t frame;	/**< frame */
++	drm_context_t dummy_context;
+ } drm_sarea_t;
+ 
+-#endif	/* _DRM_SAREA_H_ */
++#endif				/* _DRM_SAREA_H_ */
+diff --git a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c
+--- a/drivers/char/drm/drm_scatter.c
++++ b/drivers/char/drm/drm_scatter.c
+@@ -1,5 +1,5 @@
+ /**
+- * \file drm_scatter.h 
++ * \file drm_scatter.c
+  * IOCTLs to manage scatter/gather memory
+  *
+  * \author Gareth Hughes <gareth at valinux.com>
+@@ -37,28 +37,24 @@
+ 
+ #define DEBUG_SCATTER 0
+ 
+-void drm_sg_cleanup( drm_sg_mem_t *entry )
++void drm_sg_cleanup(drm_sg_mem_t * entry)
+ {
+ 	struct page *page;
+ 	int i;
+ 
+-	for ( i = 0 ; i < entry->pages ; i++ ) {
++	for (i = 0; i < entry->pages; i++) {
+ 		page = entry->pagelist[i];
+-		if ( page )
+-			ClearPageReserved( page );
++		if (page)
++			ClearPageReserved(page);
+ 	}
+ 
+-	vfree( entry->virtual );
++	vfree(entry->virtual);
+ 
+-	drm_free( entry->busaddr,
+-		   entry->pages * sizeof(*entry->busaddr),
+-		   DRM_MEM_PAGES );
+-	drm_free( entry->pagelist,
+-		   entry->pages * sizeof(*entry->pagelist),
+-		   DRM_MEM_PAGES );
+-	drm_free( entry,
+-		   sizeof(*entry),
+-		   DRM_MEM_SGLISTS );
++	drm_free(entry->busaddr,
++		 entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
++	drm_free(entry->pagelist,
++		 entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES);
++	drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
+ }
+ 
+ #ifdef _LP64
+@@ -67,8 +63,8 @@ void drm_sg_cleanup( drm_sg_mem_t *entry
+ # define ScatterHandle(x) (unsigned int)(x)
+ #endif
+ 
+-int drm_sg_alloc( struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg )
++int drm_sg_alloc(struct inode *inode, struct file *filp,
++		 unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -77,75 +73,70 @@ int drm_sg_alloc( struct inode *inode, s
+ 	drm_sg_mem_t *entry;
+ 	unsigned long pages, i, j;
+ 
+-	DRM_DEBUG( "%s\n", __FUNCTION__ );
++	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+ 	if (!drm_core_check_feature(dev, DRIVER_SG))
+ 		return -EINVAL;
+ 
+-	if ( dev->sg )
++	if (dev->sg)
+ 		return -EINVAL;
+ 
+-	if ( copy_from_user( &request, argp, sizeof(request) ) )
++	if (copy_from_user(&request, argp, sizeof(request)))
+ 		return -EFAULT;
+ 
+-	entry = drm_alloc( sizeof(*entry), DRM_MEM_SGLISTS );
+-	if ( !entry )
++	entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS);
++	if (!entry)
+ 		return -ENOMEM;
+ 
+-   	memset( entry, 0, sizeof(*entry) );
++	memset(entry, 0, sizeof(*entry));
+ 
+ 	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+-	DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
++	DRM_DEBUG("sg size=%ld pages=%ld\n", request.size, pages);
+ 
+ 	entry->pages = pages;
+-	entry->pagelist = drm_alloc( pages * sizeof(*entry->pagelist),
+-				     DRM_MEM_PAGES );
+-	if ( !entry->pagelist ) {
+-		drm_free( entry, sizeof(*entry), DRM_MEM_SGLISTS );
++	entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist),
++				    DRM_MEM_PAGES);
++	if (!entry->pagelist) {
++		drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
+ 		return -ENOMEM;
+ 	}
+ 
+ 	memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
+ 
+-	entry->busaddr = drm_alloc( pages * sizeof(*entry->busaddr),
+-				     DRM_MEM_PAGES );
+-	if ( !entry->busaddr ) {
+-		drm_free( entry->pagelist,
+-			   entry->pages * sizeof(*entry->pagelist),
+-			   DRM_MEM_PAGES );
+-		drm_free( entry,
+-			   sizeof(*entry),
+-			   DRM_MEM_SGLISTS );
++	entry->busaddr = drm_alloc(pages * sizeof(*entry->busaddr),
++				   DRM_MEM_PAGES);
++	if (!entry->busaddr) {
++		drm_free(entry->pagelist,
++			 entry->pages * sizeof(*entry->pagelist),
++			 DRM_MEM_PAGES);
++		drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
+ 		return -ENOMEM;
+ 	}
+-	memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
++	memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr));
+ 
+-	entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
+-	if ( !entry->virtual ) {
+-		drm_free( entry->busaddr,
+-			   entry->pages * sizeof(*entry->busaddr),
+-			   DRM_MEM_PAGES );
+-		drm_free( entry->pagelist,
+-			   entry->pages * sizeof(*entry->pagelist),
+-			   DRM_MEM_PAGES );
+-		drm_free( entry,
+-			   sizeof(*entry),
+-			   DRM_MEM_SGLISTS );
++	entry->virtual = vmalloc_32(pages << PAGE_SHIFT);
++	if (!entry->virtual) {
++		drm_free(entry->busaddr,
++			 entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
++		drm_free(entry->pagelist,
++			 entry->pages * sizeof(*entry->pagelist),
++			 DRM_MEM_PAGES);
++		drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
+ 		return -ENOMEM;
+ 	}
+ 
+ 	/* This also forces the mapping of COW pages, so our page list
+ 	 * will be valid.  Please don't remove it...
+ 	 */
+-	memset( entry->virtual, 0, pages << PAGE_SHIFT );
++	memset(entry->virtual, 0, pages << PAGE_SHIFT);
+ 
+ 	entry->handle = ScatterHandle((unsigned long)entry->virtual);
+ 
+-	DRM_DEBUG( "sg alloc handle  = %08lx\n", entry->handle );
+-	DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
++	DRM_DEBUG("sg alloc handle  = %08lx\n", entry->handle);
++	DRM_DEBUG("sg alloc virtual = %p\n", entry->virtual);
+ 
+-	for (i = (unsigned long)entry->virtual, j = 0; j < pages; 
+-		i += PAGE_SIZE, j++) {
++	for (i = (unsigned long)entry->virtual, j = 0; j < pages;
++	     i += PAGE_SIZE, j++) {
+ 		entry->pagelist[j] = vmalloc_to_page((void *)i);
+ 		if (!entry->pagelist[j])
+ 			goto failed;
+@@ -154,8 +145,8 @@ int drm_sg_alloc( struct inode *inode, s
+ 
+ 	request.handle = entry->handle;
+ 
+-	if ( copy_to_user( argp, &request, sizeof(request) ) ) {
+-		drm_sg_cleanup( entry );
++	if (copy_to_user(argp, &request, sizeof(request))) {
++		drm_sg_cleanup(entry);
+ 		return -EFAULT;
+ 	}
+ 
+@@ -166,50 +157,50 @@ int drm_sg_alloc( struct inode *inode, s
+ 	 * versa.
+ 	 */
+ 	{
+-	int error = 0;
++		int error = 0;
+ 
+-	for ( i = 0 ; i < pages ; i++ ) {
+-		unsigned long *tmp;
++		for (i = 0; i < pages; i++) {
++			unsigned long *tmp;
+ 
+-		tmp = page_address( entry->pagelist[i] );
+-		for ( j = 0 ;
+-		      j < PAGE_SIZE / sizeof(unsigned long) ;
+-		      j++, tmp++ ) {
+-			*tmp = 0xcafebabe;
+-		}
+-		tmp = (unsigned long *)((u8 *)entry->virtual +
+-					(PAGE_SIZE * i));
+-		for( j = 0 ;
+-		     j < PAGE_SIZE / sizeof(unsigned long) ;
+-		     j++, tmp++ ) {
+-			if ( *tmp != 0xcafebabe && error == 0 ) {
+-				error = 1;
+-				DRM_ERROR( "Scatter allocation error, "
+-					   "pagelist does not match "
+-					   "virtual mapping\n" );
++			tmp = page_address(entry->pagelist[i]);
++			for (j = 0;
++			     j < PAGE_SIZE / sizeof(unsigned long);
++			     j++, tmp++) {
++				*tmp = 0xcafebabe;
++			}
++			tmp = (unsigned long *)((u8 *) entry->virtual +
++						(PAGE_SIZE * i));
++			for (j = 0;
++			     j < PAGE_SIZE / sizeof(unsigned long);
++			     j++, tmp++) {
++				if (*tmp != 0xcafebabe && error == 0) {
++					error = 1;
++					DRM_ERROR("Scatter allocation error, "
++						  "pagelist does not match "
++						  "virtual mapping\n");
++				}
++			}
++			tmp = page_address(entry->pagelist[i]);
++			for (j = 0;
++			     j < PAGE_SIZE / sizeof(unsigned long);
++			     j++, tmp++) {
++				*tmp = 0;
+ 			}
+ 		}
+-		tmp = page_address( entry->pagelist[i] );
+-		for(j = 0 ;
+-		    j < PAGE_SIZE / sizeof(unsigned long) ;
+-		    j++, tmp++) {
+-			*tmp = 0;
+-		}
+-	}
+-	if (error == 0)
+-		DRM_ERROR( "Scatter allocation matches pagelist\n" );
++		if (error == 0)
++			DRM_ERROR("Scatter allocation matches pagelist\n");
+ 	}
+ #endif
+ 
+ 	return 0;
+ 
+- failed:
+-	drm_sg_cleanup( entry );
++      failed:
++	drm_sg_cleanup(entry);
+ 	return -ENOMEM;
+ }
+ 
+-int drm_sg_free( struct inode *inode, struct file *filp,
+-		 unsigned int cmd, unsigned long arg )
++int drm_sg_free(struct inode *inode, struct file *filp,
++		unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -219,20 +210,20 @@ int drm_sg_free( struct inode *inode, st
+ 	if (!drm_core_check_feature(dev, DRIVER_SG))
+ 		return -EINVAL;
+ 
+-	if ( copy_from_user( &request,
+-			     (drm_scatter_gather_t __user *)arg,
+-			     sizeof(request) ) )
++	if (copy_from_user(&request,
++			   (drm_scatter_gather_t __user *) arg,
++			   sizeof(request)))
+ 		return -EFAULT;
+ 
+ 	entry = dev->sg;
+ 	dev->sg = NULL;
+ 
+-	if ( !entry || entry->handle != request.handle )
++	if (!entry || entry->handle != request.handle)
+ 		return -EINVAL;
+ 
+-	DRM_DEBUG( "sg free virtual  = %p\n", entry->virtual );
++	DRM_DEBUG("sg free virtual  = %p\n", entry->virtual);
+ 
+-	drm_sg_cleanup( entry );
++	drm_sg_cleanup(entry);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
+--- a/drivers/char/drm/drm_stub.c
++++ b/drivers/char/drm/drm_stub.c
+@@ -37,11 +37,11 @@
+ #include "drm_core.h"
+ 
+ unsigned int drm_cards_limit = 16;	/* Enough for one machine */
+-unsigned int drm_debug = 0;		/* 1 to enable debug output */
++unsigned int drm_debug = 0;	/* 1 to enable debug output */
+ EXPORT_SYMBOL(drm_debug);
+ 
+-MODULE_AUTHOR( CORE_AUTHOR );
+-MODULE_DESCRIPTION( CORE_DESC );
++MODULE_AUTHOR(CORE_AUTHOR);
++MODULE_DESCRIPTION(CORE_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+ MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards");
+ MODULE_PARM_DESC(debug, "Enable debug output");
+@@ -53,19 +53,21 @@ drm_head_t **drm_heads;
+ struct drm_sysfs_class *drm_class;
+ struct proc_dir_entry *drm_proc_root;
+ 
+-static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver)
++static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
++			   const struct pci_device_id *ent,
++			   struct drm_driver *driver)
+ {
+ 	int retcode;
+ 
+ 	spin_lock_init(&dev->count_lock);
+-	init_timer( &dev->timer );
+-	sema_init( &dev->struct_sem, 1 );
+-	sema_init( &dev->ctxlist_sem, 1 );
++	init_timer(&dev->timer);
++	sema_init(&dev->struct_sem, 1);
++	sema_init(&dev->ctxlist_sem, 1);
+ 
+-	dev->pdev   = pdev;
++	dev->pdev = pdev;
+ 
+ #ifdef __alpha__
+-	dev->hose   = pdev->sysdata;
++	dev->hose = pdev->sysdata;
+ 	dev->pci_domain = dev->hose->bus->number;
+ #else
+ 	dev->pci_domain = 0;
+@@ -82,15 +84,15 @@ static int drm_fill_in_dev(drm_device_t 
+ 
+ 	/* the DRM has 6 basic counters */
+ 	dev->counters = 6;
+-	dev->types[0]  = _DRM_STAT_LOCK;
+-	dev->types[1]  = _DRM_STAT_OPENS;
+-	dev->types[2]  = _DRM_STAT_CLOSES;
+-	dev->types[3]  = _DRM_STAT_IOCTLS;
+-	dev->types[4]  = _DRM_STAT_LOCKS;
+-	dev->types[5]  = _DRM_STAT_UNLOCKS;
++	dev->types[0] = _DRM_STAT_LOCK;
++	dev->types[1] = _DRM_STAT_OPENS;
++	dev->types[2] = _DRM_STAT_CLOSES;
++	dev->types[3] = _DRM_STAT_IOCTLS;
++	dev->types[4] = _DRM_STAT_LOCKS;
++	dev->types[5] = _DRM_STAT_UNLOCKS;
+ 
+ 	dev->driver = driver;
+-	
++
+ 	if (dev->driver->preinit)
+ 		if ((retcode = dev->driver->preinit(dev, ent->driver_data)))
+ 			goto error_out_unreg;
+@@ -98,29 +100,30 @@ static int drm_fill_in_dev(drm_device_t 
+ 	if (drm_core_has_AGP(dev)) {
+ 		if (drm_device_is_agp(dev))
+ 			dev->agp = drm_agp_init(dev);
+-		if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
+-			DRM_ERROR( "Cannot initialize the agpgart module.\n" );
++		if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP)
++		    && (dev->agp == NULL)) {
++			DRM_ERROR("Cannot initialize the agpgart module.\n");
+ 			retcode = -EINVAL;
+ 			goto error_out_unreg;
+ 		}
+ 		if (drm_core_has_MTRR(dev)) {
+ 			if (dev->agp)
+-				dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
+-							       dev->agp->agp_info.aper_size*1024*1024,
+-							       MTRR_TYPE_WRCOMB,
+-							       1 );
++				dev->agp->agp_mtrr =
++				    mtrr_add(dev->agp->agp_info.aper_base,
++					     dev->agp->agp_info.aper_size *
++					     1024 * 1024, MTRR_TYPE_WRCOMB, 1);
+ 		}
+ 	}
+ 
+-	retcode = drm_ctxbitmap_init( dev );
+-	if( retcode ) {
+-		DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
++	retcode = drm_ctxbitmap_init(dev);
++	if (retcode) {
++		DRM_ERROR("Cannot allocate memory for context bitmap.\n");
+ 		goto error_out_unreg;
+ 	}
+ 
+ 	return 0;
+-	
+-error_out_unreg:
++
++      error_out_unreg:
+ 	drm_takedown(dev);
+ 	return retcode;
+ }
+@@ -140,7 +143,7 @@ int drm_stub_open(struct inode *inode, s
+ 	int minor = iminor(inode);
+ 	int err = -ENODEV;
+ 	struct file_operations *old_fops;
+-	
++
+ 	DRM_DEBUG("\n");
+ 
+ 	if (!((minor >= 0) && (minor < drm_cards_limit)))
+@@ -148,7 +151,7 @@ int drm_stub_open(struct inode *inode, s
+ 
+ 	if (!drm_heads[minor])
+ 		return -ENODEV;
+-	
++
+ 	if (!(dev = drm_heads[minor]->dev))
+ 		return -ENODEV;
+ 
+@@ -174,7 +177,7 @@ int drm_stub_open(struct inode *inode, s
+  * create the proc init entry via proc_init(). This routines assigns
+  * minor numbers to secondary heads of multi-headed cards
+  */
+-static int drm_get_head(drm_device_t *dev, drm_head_t *head)
++static int drm_get_head(drm_device_t * dev, drm_head_t * head)
+ {
+ 	drm_head_t **heads = drm_heads;
+ 	int ret;
+@@ -184,26 +187,27 @@ static int drm_get_head(drm_device_t *de
+ 
+ 	for (minor = 0; minor < drm_cards_limit; minor++, heads++) {
+ 		if (!*heads) {
+-			
++
+ 			*head = (drm_head_t) {
+-				.dev = dev,
+-				.device = MKDEV(DRM_MAJOR, minor),
+-				.minor = minor,
+-			};
+-			
+-			if ((ret = drm_proc_init(dev, minor, drm_proc_root, &head->dev_root))) {
+-				printk (KERN_ERR "DRM: Failed to initialize /proc/dri.\n");
++			.dev = dev,.device =
++				    MKDEV(DRM_MAJOR, minor),.minor = minor,};
++
++			if ((ret =
++			     drm_proc_init(dev, minor, drm_proc_root,
++					   &head->dev_root))) {
++				printk(KERN_ERR
++				       "DRM: Failed to initialize /proc/dri.\n");
+ 				goto err_g1;
+ 			}
+ 
+-			
+ 			head->dev_class = drm_sysfs_device_add(drm_class,
+ 							       MKDEV(DRM_MAJOR,
+ 								     minor),
+ 							       &dev->pdev->dev,
+ 							       "card%d", minor);
+ 			if (IS_ERR(head->dev_class)) {
+-				printk(KERN_ERR "DRM: Error sysfs_device_add.\n");
++				printk(KERN_ERR
++				       "DRM: Error sysfs_device_add.\n");
+ 				ret = PTR_ERR(head->dev_class);
+ 				goto err_g2;
+ 			}
+@@ -215,13 +219,14 @@ static int drm_get_head(drm_device_t *de
+ 	}
+ 	DRM_ERROR("out of minors\n");
+ 	return -ENOMEM;
+-err_g2:
++      err_g2:
+ 	drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
+-err_g1:
+-	*head = (drm_head_t) {.dev = NULL};
++      err_g1:
++	*head = (drm_head_t) {
++	.dev = NULL};
+ 	return ret;
+ }
+-		
++
+ /**
+  * Register.
+  *
+@@ -234,7 +239,7 @@ err_g1:
+  * Try and register, if we fail to register, backout previous work.
+  */
+ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+-	      struct drm_driver *driver)
++		struct drm_driver *driver)
+ {
+ 	drm_device_t *dev;
+ 	int ret;
+@@ -261,10 +266,11 @@ int drm_get_dev(struct pci_dev *pdev, co
+ 
+ 	return 0;
+ 
+-err_g1:
++      err_g1:
+ 	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+ 	return ret;
+ }
++
+ EXPORT_SYMBOL(drm_get_dev);
+ 
+ /**
+@@ -305,19 +311,19 @@ int drm_put_dev(drm_device_t * dev)
+  * last minor released.
+  *
+  */
+-int drm_put_head(drm_head_t *head)
++int drm_put_head(drm_head_t * head)
+ {
+ 	int minor = head->minor;
+-	
++
+ 	DRM_DEBUG("release secondary minor %d\n", minor);
+-	
++
+ 	drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
+ 	drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor));
+-	
+-	*head = (drm_head_t){.dev = NULL};
++
++	*head = (drm_head_t) {
++	.dev = NULL};
+ 
+ 	drm_heads[minor] = NULL;
+-	
++
+ 	return 0;
+ }
+-
+diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
+--- a/drivers/char/drm/drm_sysfs.c
++++ b/drivers/char/drm/drm_sysfs.c
+@@ -15,6 +15,8 @@
+ #include <linux/device.h>
+ #include <linux/kdev_t.h>
+ #include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/string.h>
+ 
+ #include "drm_core.h"
+ #include "drmP.h"
+diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
+--- a/drivers/char/drm/drm_vm.c
++++ b/drivers/char/drm/drm_vm.c
+@@ -1,7 +1,7 @@
+ /**
+- * \file drm_vm.h
++ * \file drm_vm.c
+  * Memory mapping for DRM
+- * 
++ *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Gareth Hughes <gareth at valinux.com>
+  */
+@@ -47,32 +47,34 @@ static void drm_vm_close(struct vm_area_
+  * \param vma virtual memory area.
+  * \param address access address.
+  * \return pointer to the page structure.
+- * 
++ *
+  * Find the right map and if it's AGP memory find the real physical page to
+  * map, get the page, increment the use count and return it.
+  */
+ #if __OS_HAS_AGP
+ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+-						 unsigned long address)
++						unsigned long address)
+ {
+-	drm_file_t *priv  = vma->vm_file->private_data;
++	drm_file_t *priv = vma->vm_file->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+-	drm_map_t *map    = NULL;
+-	drm_map_list_t  *r_list;
++	drm_map_t *map = NULL;
++	drm_map_list_t *r_list;
+ 	struct list_head *list;
+ 
+ 	/*
+-         * Find the right map
+-         */
++	 * Find the right map
++	 */
+ 	if (!drm_core_has_AGP(dev))
+ 		goto vm_nopage_error;
+ 
+-	if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
++	if (!dev->agp || !dev->agp->cant_use_aperture)
++		goto vm_nopage_error;
+ 
+ 	list_for_each(list, &dev->maplist->head) {
+ 		r_list = list_entry(list, drm_map_list_t, head);
+ 		map = r_list->map;
+-		if (!map) continue;
++		if (!map)
++			continue;
+ 		if (r_list->user_token == VM_OFFSET(vma))
+ 			break;
+ 	}
+@@ -85,45 +87,47 @@ static __inline__ struct page *drm_do_vm
+ 
+ #ifdef __alpha__
+ 		/*
+-                 * Adjust to a bus-relative address
+-                 */
++		 * Adjust to a bus-relative address
++		 */
+ 		baddr -= dev->hose->mem_space->start;
+ #endif
+ 
+ 		/*
+-                 * It's AGP memory - find the real physical page to map
+-                 */
+-		for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
++		 * It's AGP memory - find the real physical page to map
++		 */
++		for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
+ 			if (agpmem->bound <= baddr &&
+-			    agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) 
++			    agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
+ 				break;
+ 		}
+ 
+-		if (!agpmem) goto vm_nopage_error;
++		if (!agpmem)
++			goto vm_nopage_error;
+ 
+ 		/*
+-                 * Get the page, inc the use count, and return it
+-                 */
++		 * Get the page, inc the use count, and return it
++		 */
+ 		offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
+ 		page = virt_to_page(__va(agpmem->memory->memory[offset]));
+ 		get_page(page);
+ 
+-		DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
+-			  baddr, __va(agpmem->memory->memory[offset]), offset,
+-			  page_count(page));
++		DRM_DEBUG
++		    ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
++		     baddr, __va(agpmem->memory->memory[offset]), offset,
++		     page_count(page));
+ 
+ 		return page;
+-        }
+-vm_nopage_error:
+-	return NOPAGE_SIGBUS;		/* Disallow mremap */
++	}
++      vm_nopage_error:
++	return NOPAGE_SIGBUS;	/* Disallow mremap */
+ }
+-#else /* __OS_HAS_AGP */
++#else				/* __OS_HAS_AGP */
+ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+-						 unsigned long address)
++						unsigned long address)
+ {
+ 	return NOPAGE_SIGBUS;
+ }
+-#endif /* __OS_HAS_AGP */
++#endif				/* __OS_HAS_AGP */
+ 
+ /**
+  * \c nopage method for shared virtual memory.
+@@ -131,22 +135,24 @@ static __inline__ struct page *drm_do_vm
+  * \param vma virtual memory area.
+  * \param address access address.
+  * \return pointer to the page structure.
+- * 
++ *
+  * Get the the mapping, find the real physical page to map, get the page, and
+  * return it.
+  */
+ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
+-						     unsigned long address)
++						    unsigned long address)
+ {
+-	drm_map_t	 *map	 = (drm_map_t *)vma->vm_private_data;
+-	unsigned long	 offset;
+-	unsigned long	 i;
+-	struct page	 *page;
++	drm_map_t *map = (drm_map_t *) vma->vm_private_data;
++	unsigned long offset;
++	unsigned long i;
++	struct page *page;
+ 
+-	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+-	if (!map)    		   return NOPAGE_OOM;  /* Nothing allocated */
++	if (address > vma->vm_end)
++		return NOPAGE_SIGBUS;	/* Disallow mremap */
++	if (!map)
++		return NOPAGE_OOM;	/* Nothing allocated */
+ 
+-	offset	 = address - vma->vm_start;
++	offset = address - vma->vm_start;
+ 	i = (unsigned long)map->handle + offset;
+ 	page = (map->type == _DRM_CONSISTENT) ?
+ 		virt_to_page((void *)i) : vmalloc_to_page((void *)i);
+@@ -158,19 +164,18 @@ static __inline__ struct page *drm_do_vm
+ 	return page;
+ }
+ 
+-
+ /**
+  * \c close method for shared virtual memory.
+- * 
++ *
+  * \param vma virtual memory area.
+- * 
++ *
+  * Deletes map information if we are the last
+  * person to close a mapping and it's not in the global maplist.
+  */
+ static void drm_vm_shm_close(struct vm_area_struct *vma)
+ {
+-	drm_file_t	*priv	= vma->vm_file->private_data;
+-	drm_device_t	*dev	= priv->head->dev;
++	drm_file_t *priv = vma->vm_file->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_vma_entry_t *pt, *prev, *next;
+ 	drm_map_t *map;
+ 	drm_map_list_t *r_list;
+@@ -186,7 +191,8 @@ static void drm_vm_shm_close(struct vm_a
+ 	down(&dev->struct_sem);
+ 	for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
+ 		next = pt->next;
+-		if (pt->vma->vm_private_data == map) found_maps++;
++		if (pt->vma->vm_private_data == map)
++			found_maps++;
+ 		if (pt->vma == vma) {
+ 			if (prev) {
+ 				prev->next = pt->next;
+@@ -199,8 +205,7 @@ static void drm_vm_shm_close(struct vm_a
+ 		}
+ 	}
+ 	/* We were the only map that was found */
+-	if(found_maps == 1 &&
+-	   map->flags & _DRM_REMOVABLE) {
++	if (found_maps == 1 && map->flags & _DRM_REMOVABLE) {
+ 		/* Check to see if we are in the maplist, if we are not, then
+ 		 * we delete this mappings information.
+ 		 */
+@@ -208,10 +213,11 @@ static void drm_vm_shm_close(struct vm_a
+ 		list = &dev->maplist->head;
+ 		list_for_each(list, &dev->maplist->head) {
+ 			r_list = list_entry(list, drm_map_list_t, head);
+-			if (r_list->map == map) found_maps++;
++			if (r_list->map == map)
++				found_maps++;
+ 		}
+ 
+-		if(!found_maps) {
++		if (!found_maps) {
+ 			drm_dma_handle_t dmah;
+ 
+ 			switch (map->type) {
+@@ -251,27 +257,29 @@ static void drm_vm_shm_close(struct vm_a
+  * \param vma virtual memory area.
+  * \param address access address.
+  * \return pointer to the page structure.
+- * 
++ *
+  * Determine the page number from the page offset and get it from drm_device_dma::pagelist.
+  */
+ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
+-						     unsigned long address)
++						    unsigned long address)
+ {
+-	drm_file_t	 *priv	 = vma->vm_file->private_data;
+-	drm_device_t	 *dev	 = priv->head->dev;
+-	drm_device_dma_t *dma	 = dev->dma;
+-	unsigned long	 offset;
+-	unsigned long	 page_nr;
+-	struct page	 *page;
+-
+-	if (!dma)		   return NOPAGE_SIGBUS; /* Error */
+-	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+-	if (!dma->pagelist)	   return NOPAGE_OOM ; /* Nothing allocated */
+-
+-	offset	 = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
+-	page_nr  = offset >> PAGE_SHIFT;
+-	page = virt_to_page((dma->pagelist[page_nr] + 
+-			     (offset & (~PAGE_MASK))));
++	drm_file_t *priv = vma->vm_file->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_device_dma_t *dma = dev->dma;
++	unsigned long offset;
++	unsigned long page_nr;
++	struct page *page;
++
++	if (!dma)
++		return NOPAGE_SIGBUS;	/* Error */
++	if (address > vma->vm_end)
++		return NOPAGE_SIGBUS;	/* Disallow mremap */
++	if (!dma->pagelist)
++		return NOPAGE_OOM;	/* Nothing allocated */
++
++	offset = address - vma->vm_start;	/* vm_[pg]off[set] should be 0 */
++	page_nr = offset >> PAGE_SHIFT;
++	page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));
+ 
+ 	get_page(page);
+ 
+@@ -285,13 +293,13 @@ static __inline__ struct page *drm_do_vm
+  * \param vma virtual memory area.
+  * \param address access address.
+  * \return pointer to the page structure.
+- * 
++ *
+  * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
+  */
+ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
+-						    unsigned long address)
++						   unsigned long address)
+ {
+-	drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
++	drm_map_t *map = (drm_map_t *) vma->vm_private_data;
+ 	drm_file_t *priv = vma->vm_file->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_sg_mem_t *entry = dev->sg;
+@@ -300,10 +308,12 @@ static __inline__ struct page *drm_do_vm
+ 	unsigned long page_offset;
+ 	struct page *page;
+ 
+-	if (!entry)                return NOPAGE_SIGBUS; /* Error */
+-	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+-	if (!entry->pagelist)      return NOPAGE_OOM ;  /* Nothing allocated */
+-
++	if (!entry)
++		return NOPAGE_SIGBUS;	/* Error */
++	if (address > vma->vm_end)
++		return NOPAGE_SIGBUS;	/* Disallow mremap */
++	if (!entry->pagelist)
++		return NOPAGE_OOM;	/* Nothing allocated */
+ 
+ 	offset = address - vma->vm_start;
+ 	map_offset = map->offset - (unsigned long)dev->sg->virtual;
+@@ -314,76 +324,78 @@ static __inline__ struct page *drm_do_vm
+ 	return page;
+ }
+ 
+-
+ static struct page *drm_vm_nopage(struct vm_area_struct *vma,
+-				   unsigned long address,
+-				   int *type) {
+-	if (type) *type = VM_FAULT_MINOR;
++				  unsigned long address, int *type)
++{
++	if (type)
++		*type = VM_FAULT_MINOR;
+ 	return drm_do_vm_nopage(vma, address);
+ }
+ 
+ static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
+-				       unsigned long address,
+-				       int *type) {
+-	if (type) *type = VM_FAULT_MINOR;
++				      unsigned long address, int *type)
++{
++	if (type)
++		*type = VM_FAULT_MINOR;
+ 	return drm_do_vm_shm_nopage(vma, address);
+ }
+ 
+ static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
+-				       unsigned long address,
+-				       int *type) {
+-	if (type) *type = VM_FAULT_MINOR;
++				      unsigned long address, int *type)
++{
++	if (type)
++		*type = VM_FAULT_MINOR;
+ 	return drm_do_vm_dma_nopage(vma, address);
+ }
+ 
+ static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
+-				      unsigned long address,
+-				      int *type) {
+-	if (type) *type = VM_FAULT_MINOR;
++				     unsigned long address, int *type)
++{
++	if (type)
++		*type = VM_FAULT_MINOR;
+ 	return drm_do_vm_sg_nopage(vma, address);
+ }
+ 
+ /** AGP virtual memory operations */
+-static struct vm_operations_struct   drm_vm_ops = {
++static struct vm_operations_struct drm_vm_ops = {
+ 	.nopage = drm_vm_nopage,
+-	.open	= drm_vm_open,
+-	.close	= drm_vm_close,
++	.open = drm_vm_open,
++	.close = drm_vm_close,
+ };
+ 
+ /** Shared virtual memory operations */
+-static struct vm_operations_struct   drm_vm_shm_ops = {
++static struct vm_operations_struct drm_vm_shm_ops = {
+ 	.nopage = drm_vm_shm_nopage,
+-	.open	= drm_vm_open,
+-	.close	= drm_vm_shm_close,
++	.open = drm_vm_open,
++	.close = drm_vm_shm_close,
+ };
+ 
+ /** DMA virtual memory operations */
+-static struct vm_operations_struct   drm_vm_dma_ops = {
++static struct vm_operations_struct drm_vm_dma_ops = {
+ 	.nopage = drm_vm_dma_nopage,
+-	.open	= drm_vm_open,
+-	.close	= drm_vm_close,
++	.open = drm_vm_open,
++	.close = drm_vm_close,
+ };
+ 
+ /** Scatter-gather virtual memory operations */
+-static struct vm_operations_struct   drm_vm_sg_ops = {
++static struct vm_operations_struct drm_vm_sg_ops = {
+ 	.nopage = drm_vm_sg_nopage,
+-	.open   = drm_vm_open,
+-	.close  = drm_vm_close,
++	.open = drm_vm_open,
++	.close = drm_vm_close,
+ };
+ 
+-
+ /**
+  * \c open method for shared virtual memory.
+- * 
++ *
+  * \param vma virtual memory area.
+- * 
++ *
+  * Create a new drm_vma_entry structure as the \p vma private data entry and
+  * add it to drm_device::vmalist.
+  */
+ static void drm_vm_open(struct vm_area_struct *vma)
+ {
+-	drm_file_t	*priv	= vma->vm_file->private_data;
+-	drm_device_t	*dev	= priv->head->dev;
++	drm_file_t *priv = vma->vm_file->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_vma_entry_t *vma_entry;
+ 
+ 	DRM_DEBUG("0x%08lx,0x%08lx\n",
+@@ -393,26 +405,26 @@ static void drm_vm_open(struct vm_area_s
+ 	vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
+ 	if (vma_entry) {
+ 		down(&dev->struct_sem);
+-		vma_entry->vma	= vma;
++		vma_entry->vma = vma;
+ 		vma_entry->next = dev->vmalist;
+-		vma_entry->pid	= current->pid;
+-		dev->vmalist	= vma_entry;
++		vma_entry->pid = current->pid;
++		dev->vmalist = vma_entry;
+ 		up(&dev->struct_sem);
+ 	}
+ }
+ 
+ /**
+  * \c close method for all virtual memory types.
+- * 
++ *
+  * \param vma virtual memory area.
+- * 
++ *
+  * Search the \p vma private data entry in drm_device::vmalist, unlink it, and
+  * free it.
+  */
+ static void drm_vm_close(struct vm_area_struct *vma)
+ {
+-	drm_file_t	*priv	= vma->vm_file->private_data;
+-	drm_device_t	*dev	= priv->head->dev;
++	drm_file_t *priv = vma->vm_file->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_vma_entry_t *pt, *prev;
+ 
+ 	DRM_DEBUG("0x%08lx,0x%08lx\n",
+@@ -440,43 +452,44 @@ static void drm_vm_close(struct vm_area_
+  * \param filp file pointer.
+  * \param vma virtual memory area.
+  * \return zero on success or a negative number on failure.
+- * 
++ *
+  * Sets the virtual memory area operations structure to vm_dma_ops, the file
+  * pointer, and calls vm_open().
+  */
+ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
+ {
+-	drm_file_t	 *priv	 = filp->private_data;
+-	drm_device_t	 *dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev;
+ 	drm_device_dma_t *dma;
+-	unsigned long	 length	 = vma->vm_end - vma->vm_start;
++	unsigned long length = vma->vm_end - vma->vm_start;
+ 
+ 	lock_kernel();
+-	dev	 = priv->head->dev;
+-	dma	 = dev->dma;
++	dev = priv->head->dev;
++	dma = dev->dma;
+ 	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+ 		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+ 
+-				/* Length must match exact page count */
++	/* Length must match exact page count */
+ 	if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
+ 		unlock_kernel();
+ 		return -EINVAL;
+ 	}
+ 	unlock_kernel();
+ 
+-	vma->vm_ops   = &drm_vm_dma_ops;
++	vma->vm_ops = &drm_vm_dma_ops;
+ 
+-	vma->vm_flags |= VM_RESERVED; /* Don't swap */
++	vma->vm_flags |= VM_RESERVED;	/* Don't swap */
+ 
+-	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
++	vma->vm_file = filp;	/* Needed for drm_vm_open() */
+ 	drm_vm_open(vma);
+ 	return 0;
+ }
+ 
+-unsigned long drm_core_get_map_ofs(drm_map_t *map)
++unsigned long drm_core_get_map_ofs(drm_map_t * map)
+ {
+ 	return map->offset;
+ }
++
+ EXPORT_SYMBOL(drm_core_get_map_ofs);
+ 
+ unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
+@@ -487,6 +500,7 @@ unsigned long drm_core_get_reg_ofs(struc
+ 	return 0;
+ #endif
+ }
++
+ EXPORT_SYMBOL(drm_core_get_reg_ofs);
+ 
+ /**
+@@ -495,7 +509,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
+  * \param filp file pointer.
+  * \param vma virtual memory area.
+  * \return zero on success or a negative number on failure.
+- * 
++ *
+  * If the virtual memory area has no offset associated with it then it's a DMA
+  * area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
+  * checks that the restricted flag is not set, sets the virtual memory operations
+@@ -504,17 +518,18 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
+  */
+ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
+ {
+-	drm_file_t	*priv	= filp->private_data;
+-	drm_device_t	*dev	= priv->head->dev;
+-	drm_map_t	*map	= NULL;
+-	drm_map_list_t  *r_list;
+-	unsigned long   offset  = 0;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_map_t *map = NULL;
++	drm_map_list_t *r_list;
++	unsigned long offset = 0;
+ 	struct list_head *list;
+ 
+ 	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+ 		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+ 
+-	if ( !priv->authenticated ) return -EACCES;
++	if (!priv->authenticated)
++		return -EACCES;
+ 
+ 	/* We check for "dma". On Apple's UniNorth, it's valid to have
+ 	 * the AGP mapped at physical address 0
+@@ -522,61 +537,66 @@ int drm_mmap(struct file *filp, struct v
+ 	 */
+ 	if (!VM_OFFSET(vma)
+ #if __OS_HAS_AGP
+-	    && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
++	    && (!dev->agp
++		|| dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
+ #endif
+ 	    )
+ 		return drm_mmap_dma(filp, vma);
+ 
+-				/* A sequential search of a linked list is
+-				   fine here because: 1) there will only be
+-				   about 5-10 entries in the list and, 2) a
+-				   DRI client only has to do this mapping
+-				   once, so it doesn't have to be optimized
+-				   for performance, even if the list was a
+-				   bit longer. */
++	/* A sequential search of a linked list is
++	   fine here because: 1) there will only be
++	   about 5-10 entries in the list and, 2) a
++	   DRI client only has to do this mapping
++	   once, so it doesn't have to be optimized
++	   for performance, even if the list was a
++	   bit longer. */
+ 	list_for_each(list, &dev->maplist->head) {
+ 
+ 		r_list = list_entry(list, drm_map_list_t, head);
+ 		map = r_list->map;
+-		if (!map) continue;
++		if (!map)
++			continue;
+ 		if (r_list->user_token == VM_OFFSET(vma))
+ 			break;
+ 	}
+ 
+-	if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
++	if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
+ 		return -EPERM;
+ 
+-				/* Check for valid size. */
+-	if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
++	/* Check for valid size. */
++	if (map->size != vma->vm_end - vma->vm_start)
++		return -EINVAL;
+ 
+ 	if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
+ 		vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
+ #if defined(__i386__) || defined(__x86_64__)
+ 		pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+ #else
+-				/* Ye gads this is ugly.  With more thought
+-                                   we could move this up higher and use
+-                                   `protection_map' instead.  */
+-		vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
+-			__pte(pgprot_val(vma->vm_page_prot)))));
++		/* Ye gads this is ugly.  With more thought
++		   we could move this up higher and use
++		   `protection_map' instead.  */
++		vma->vm_page_prot =
++		    __pgprot(pte_val
++			     (pte_wrprotect
++			      (__pte(pgprot_val(vma->vm_page_prot)))));
+ #endif
+ 	}
+ 
+ 	switch (map->type) {
+-        case _DRM_AGP:
+-	  if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
+-                /*
+-                 * On some platforms we can't talk to bus dma address from the CPU, so for
+-                 * memory of type DRM_AGP, we'll deal with sorting out the real physical
+-                 * pages and mappings in nopage()
+-                 */
++	case _DRM_AGP:
++		if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
++			/*
++			 * On some platforms we can't talk to bus dma address from the CPU, so for
++			 * memory of type DRM_AGP, we'll deal with sorting out the real physical
++			 * pages and mappings in nopage()
++			 */
+ #if defined(__powerpc__)
+-		pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
++			pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
+ #endif
+-                vma->vm_ops = &drm_vm_ops;
+-                break;
+-	  }
+-                /* fall through to _DRM_FRAME_BUFFER... */        
++			vma->vm_ops = &drm_vm_ops;
++			break;
++		}
++		/* fall through to _DRM_FRAME_BUFFER... */
+ 	case _DRM_FRAME_BUFFER:
+ 	case _DRM_REGISTERS:
+ #if defined(__i386__) || defined(__x86_64__)
+@@ -591,27 +611,25 @@ int drm_mmap(struct file *filp, struct v
+ #endif
+ 		vma->vm_flags |= VM_IO;	/* not in core dump */
+ #if defined(__ia64__)
+-		if (efi_range_is_wc(vma->vm_start, vma->vm_end -
+-				    vma->vm_start))
++		if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
+ 			vma->vm_page_prot =
+-				pgprot_writecombine(vma->vm_page_prot);
++			    pgprot_writecombine(vma->vm_page_prot);
+ 		else
+-			vma->vm_page_prot =
+-				pgprot_noncached(vma->vm_page_prot);
++			vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ #endif
+ 		offset = dev->driver->get_reg_ofs(dev);
+ #ifdef __sparc__
+ 		if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
+-					(map->offset + offset) >> PAGE_SHIFT,
+-					vma->vm_end - vma->vm_start,
+-					vma->vm_page_prot))
++				       (map->offset + offset) >> PAGE_SHIFT,
++				       vma->vm_end - vma->vm_start,
++				       vma->vm_page_prot))
+ #else
+ 		if (io_remap_pfn_range(vma, vma->vm_start,
+-				     (map->offset + offset) >> PAGE_SHIFT,
+-				     vma->vm_end - vma->vm_start,
+-				     vma->vm_page_prot))
++				       (map->offset + offset) >> PAGE_SHIFT,
++				       vma->vm_end - vma->vm_start,
++				       vma->vm_page_prot))
+ #endif
+-				return -EAGAIN;
++			return -EAGAIN;
+ 		DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
+ 			  " offset = 0x%lx\n",
+ 			  map->type,
+@@ -624,22 +642,23 @@ int drm_mmap(struct file *filp, struct v
+ 		 * allocate in a different way */
+ 		vma->vm_ops = &drm_vm_shm_ops;
+ 		vma->vm_private_data = (void *)map;
+-				/* Don't let this area swap.  Change when
+-				   DRM_KERNEL advisory is supported. */
++		/* Don't let this area swap.  Change when
++		   DRM_KERNEL advisory is supported. */
+ 		vma->vm_flags |= VM_RESERVED;
+ 		break;
+ 	case _DRM_SCATTER_GATHER:
+ 		vma->vm_ops = &drm_vm_sg_ops;
+ 		vma->vm_private_data = (void *)map;
+ 		vma->vm_flags |= VM_RESERVED;
+-                break;
++		break;
+ 	default:
+ 		return -EINVAL;	/* This should never happen. */
+ 	}
+-	vma->vm_flags |= VM_RESERVED; /* Don't swap */
++	vma->vm_flags |= VM_RESERVED;	/* Don't swap */
+ 
+-	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
++	vma->vm_file = filp;	/* Needed for drm_vm_open() */
+ 	drm_vm_open(vma);
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(drm_mmap);
+diff --git a/drivers/char/drm/ffb_context.c b/drivers/char/drm/ffb_context.c
+--- a/drivers/char/drm/ffb_context.c
++++ b/drivers/char/drm/ffb_context.c
+@@ -15,8 +15,7 @@
+ 
+ #include "ffb_drv.h"
+ 
+-static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only)
+-{
++static int DRM(alloc_queue) (drm_device_t * dev, int is_2d_only) {
+ 	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ 	int i;
+ 
+@@ -37,7 +36,7 @@ static int DRM(alloc_queue)(drm_device_t
+ 	return i + 1;
+ }
+ 
+-static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
++static void ffb_save_context(ffb_dev_priv_t * fpriv, int idx)
+ {
+ 	ffb_fbcPtr ffb = fpriv->regs;
+ 	struct ffb_hw_context *ctx;
+@@ -94,36 +93,36 @@ static void ffb_save_context(ffb_dev_pri
+ 
+ 	/* Capture rendering attributes. */
+ 
+-	ctx->ppc = upa_readl(&ffb->ppc);		/* Pixel Processor Control */
+-	ctx->wid = upa_readl(&ffb->wid);		/* Current WID */
+-	ctx->fg = upa_readl(&ffb->fg);			/* Constant FG color */
+-	ctx->bg = upa_readl(&ffb->bg);			/* Constant BG color */
+-	ctx->consty = upa_readl(&ffb->consty);		/* Constant Y */
+-	ctx->constz = upa_readl(&ffb->constz);		/* Constant Z */
+-	ctx->xclip = upa_readl(&ffb->xclip);		/* X plane clip */
+-	ctx->dcss = upa_readl(&ffb->dcss);		/* Depth Cue Scale Slope */
++	ctx->ppc = upa_readl(&ffb->ppc);	/* Pixel Processor Control */
++	ctx->wid = upa_readl(&ffb->wid);	/* Current WID */
++	ctx->fg = upa_readl(&ffb->fg);	/* Constant FG color */
++	ctx->bg = upa_readl(&ffb->bg);	/* Constant BG color */
++	ctx->consty = upa_readl(&ffb->consty);	/* Constant Y */
++	ctx->constz = upa_readl(&ffb->constz);	/* Constant Z */
++	ctx->xclip = upa_readl(&ffb->xclip);	/* X plane clip */
++	ctx->dcss = upa_readl(&ffb->dcss);	/* Depth Cue Scale Slope */
+ 	ctx->vclipmin = upa_readl(&ffb->vclipmin);	/* Primary XY clip, minimum */
+ 	ctx->vclipmax = upa_readl(&ffb->vclipmax);	/* Primary XY clip, maximum */
+ 	ctx->vclipzmin = upa_readl(&ffb->vclipzmin);	/* Primary Z clip, minimum */
+ 	ctx->vclipzmax = upa_readl(&ffb->vclipzmax);	/* Primary Z clip, maximum */
+-	ctx->dcsf = upa_readl(&ffb->dcsf);		/* Depth Cue Scale Front Bound */
+-	ctx->dcsb = upa_readl(&ffb->dcsb);		/* Depth Cue Scale Back Bound */
+-	ctx->dczf = upa_readl(&ffb->dczf);		/* Depth Cue Scale Z Front */
+-	ctx->dczb = upa_readl(&ffb->dczb);		/* Depth Cue Scale Z Back */
+-	ctx->blendc = upa_readl(&ffb->blendc);		/* Alpha Blend Control */
++	ctx->dcsf = upa_readl(&ffb->dcsf);	/* Depth Cue Scale Front Bound */
++	ctx->dcsb = upa_readl(&ffb->dcsb);	/* Depth Cue Scale Back Bound */
++	ctx->dczf = upa_readl(&ffb->dczf);	/* Depth Cue Scale Z Front */
++	ctx->dczb = upa_readl(&ffb->dczb);	/* Depth Cue Scale Z Back */
++	ctx->blendc = upa_readl(&ffb->blendc);	/* Alpha Blend Control */
+ 	ctx->blendc1 = upa_readl(&ffb->blendc1);	/* Alpha Blend Color 1 */
+ 	ctx->blendc2 = upa_readl(&ffb->blendc2);	/* Alpha Blend Color 2 */
+-	ctx->fbc = upa_readl(&ffb->fbc);		/* Frame Buffer Control */
+-	ctx->rop = upa_readl(&ffb->rop);		/* Raster Operation */
+-	ctx->cmp = upa_readl(&ffb->cmp);		/* Compare Controls */
++	ctx->fbc = upa_readl(&ffb->fbc);	/* Frame Buffer Control */
++	ctx->rop = upa_readl(&ffb->rop);	/* Raster Operation */
++	ctx->cmp = upa_readl(&ffb->cmp);	/* Compare Controls */
+ 	ctx->matchab = upa_readl(&ffb->matchab);	/* Buffer A/B Match Ops */
+-	ctx->matchc = upa_readl(&ffb->matchc);		/* Buffer C Match Ops */
+-	ctx->magnab = upa_readl(&ffb->magnab);		/* Buffer A/B Magnitude Ops */
+-	ctx->magnc = upa_readl(&ffb->magnc);		/* Buffer C Magnitude Ops */
+-	ctx->pmask = upa_readl(&ffb->pmask);		/* RGB Plane Mask */
+-	ctx->xpmask = upa_readl(&ffb->xpmask);		/* X Plane Mask */
+-	ctx->ypmask = upa_readl(&ffb->ypmask);		/* Y Plane Mask */
+-	ctx->zpmask = upa_readl(&ffb->zpmask);		/* Z Plane Mask */
++	ctx->matchc = upa_readl(&ffb->matchc);	/* Buffer C Match Ops */
++	ctx->magnab = upa_readl(&ffb->magnab);	/* Buffer A/B Magnitude Ops */
++	ctx->magnc = upa_readl(&ffb->magnc);	/* Buffer C Magnitude Ops */
++	ctx->pmask = upa_readl(&ffb->pmask);	/* RGB Plane Mask */
++	ctx->xpmask = upa_readl(&ffb->xpmask);	/* X Plane Mask */
++	ctx->ypmask = upa_readl(&ffb->ypmask);	/* Y Plane Mask */
++	ctx->zpmask = upa_readl(&ffb->zpmask);	/* Z Plane Mask */
+ 
+ 	/* Auxiliary Clips. */
+ 	ctx->auxclip0min = upa_readl(&ffb->auxclip[0].min);
+@@ -135,9 +134,9 @@ static void ffb_save_context(ffb_dev_pri
+ 	ctx->auxclip3min = upa_readl(&ffb->auxclip[3].min);
+ 	ctx->auxclip3max = upa_readl(&ffb->auxclip[3].max);
+ 
+-	ctx->lpat = upa_readl(&ffb->lpat);		/* Line Pattern */
+-	ctx->fontxy = upa_readl(&ffb->fontxy);		/* XY Font Coordinate */
+-	ctx->fontw = upa_readl(&ffb->fontw);		/* Font Width */
++	ctx->lpat = upa_readl(&ffb->lpat);	/* Line Pattern */
++	ctx->fontxy = upa_readl(&ffb->fontxy);	/* XY Font Coordinate */
++	ctx->fontw = upa_readl(&ffb->fontw);	/* Font Width */
+ 	ctx->fontinc = upa_readl(&ffb->fontinc);	/* Font X/Y Increment */
+ 
+ 	/* These registers/features only exist on FFB2 and later chips. */
+@@ -145,12 +144,12 @@ static void ffb_save_context(ffb_dev_pri
+ 		ctx->dcss1 = upa_readl(&ffb->dcss1);	/* Depth Cue Scale Slope 1 */
+ 		ctx->dcss2 = upa_readl(&ffb->dcss2);	/* Depth Cue Scale Slope 2 */
+ 		ctx->dcss2 = upa_readl(&ffb->dcss3);	/* Depth Cue Scale Slope 3 */
+-		ctx->dcs2  = upa_readl(&ffb->dcs2);	/* Depth Cue Scale 2 */
+-		ctx->dcs3  = upa_readl(&ffb->dcs3);	/* Depth Cue Scale 3 */
+-		ctx->dcs4  = upa_readl(&ffb->dcs4);	/* Depth Cue Scale 4 */
+-		ctx->dcd2  = upa_readl(&ffb->dcd2);	/* Depth Cue Depth 2 */
+-		ctx->dcd3  = upa_readl(&ffb->dcd3);	/* Depth Cue Depth 3 */
+-		ctx->dcd4  = upa_readl(&ffb->dcd4);	/* Depth Cue Depth 4 */
++		ctx->dcs2 = upa_readl(&ffb->dcs2);	/* Depth Cue Scale 2 */
++		ctx->dcs3 = upa_readl(&ffb->dcs3);	/* Depth Cue Scale 3 */
++		ctx->dcs4 = upa_readl(&ffb->dcs4);	/* Depth Cue Scale 4 */
++		ctx->dcd2 = upa_readl(&ffb->dcd2);	/* Depth Cue Depth 2 */
++		ctx->dcd3 = upa_readl(&ffb->dcd3);	/* Depth Cue Depth 3 */
++		ctx->dcd4 = upa_readl(&ffb->dcd4);	/* Depth Cue Depth 4 */
+ 
+ 		/* And stencil/stencilctl only exists on FFB2+ and later
+ 		 * due to the introduction of 3DRAM-III.
+@@ -170,7 +169,7 @@ static void ffb_save_context(ffb_dev_pri
+ 	ctx->ucsr = upa_readl(&ffb->ucsr);
+ }
+ 
+-static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
++static void ffb_restore_context(ffb_dev_priv_t * fpriv, int old, int idx)
+ {
+ 	ffb_fbcPtr ffb = fpriv->regs;
+ 	struct ffb_hw_context *ctx;
+@@ -193,7 +192,7 @@ static void ffb_restore_context(ffb_dev_
+ 
+ 		upa_writel(ctx->ppc, &ffb->ppc);
+ 		upa_writel(ctx->wid, &ffb->wid);
+-		upa_writel(ctx->fg,  &ffb->fg);
++		upa_writel(ctx->fg, &ffb->fg);
+ 		upa_writel(ctx->bg, &ffb->bg);
+ 		upa_writel(ctx->xclip, &ffb->xclip);
+ 		upa_writel(ctx->fbc, &ffb->fbc);
+@@ -237,36 +236,36 @@ static void ffb_restore_context(ffb_dev_
+ 
+ 	/* Restore rendering attributes. */
+ 
+-	upa_writel(ctx->ppc, &ffb->ppc);		/* Pixel Processor Control */
+-	upa_writel(ctx->wid, &ffb->wid);		/* Current WID */
+-	upa_writel(ctx->fg, &ffb->fg);			/* Constant FG color */
+-	upa_writel(ctx->bg, &ffb->bg);			/* Constant BG color */
+-	upa_writel(ctx->consty, &ffb->consty);		/* Constant Y */
+-	upa_writel(ctx->constz, &ffb->constz);		/* Constant Z */
+-	upa_writel(ctx->xclip, &ffb->xclip);		/* X plane clip */
+-	upa_writel(ctx->dcss, &ffb->dcss);		/* Depth Cue Scale Slope */
++	upa_writel(ctx->ppc, &ffb->ppc);	/* Pixel Processor Control */
++	upa_writel(ctx->wid, &ffb->wid);	/* Current WID */
++	upa_writel(ctx->fg, &ffb->fg);	/* Constant FG color */
++	upa_writel(ctx->bg, &ffb->bg);	/* Constant BG color */
++	upa_writel(ctx->consty, &ffb->consty);	/* Constant Y */
++	upa_writel(ctx->constz, &ffb->constz);	/* Constant Z */
++	upa_writel(ctx->xclip, &ffb->xclip);	/* X plane clip */
++	upa_writel(ctx->dcss, &ffb->dcss);	/* Depth Cue Scale Slope */
+ 	upa_writel(ctx->vclipmin, &ffb->vclipmin);	/* Primary XY clip, minimum */
+ 	upa_writel(ctx->vclipmax, &ffb->vclipmax);	/* Primary XY clip, maximum */
+ 	upa_writel(ctx->vclipzmin, &ffb->vclipzmin);	/* Primary Z clip, minimum */
+ 	upa_writel(ctx->vclipzmax, &ffb->vclipzmax);	/* Primary Z clip, maximum */
+-	upa_writel(ctx->dcsf, &ffb->dcsf);		/* Depth Cue Scale Front Bound */
+-	upa_writel(ctx->dcsb, &ffb->dcsb);		/* Depth Cue Scale Back Bound */
+-	upa_writel(ctx->dczf, &ffb->dczf);		/* Depth Cue Scale Z Front */
+-	upa_writel(ctx->dczb, &ffb->dczb);		/* Depth Cue Scale Z Back */
+-	upa_writel(ctx->blendc, &ffb->blendc);		/* Alpha Blend Control */
++	upa_writel(ctx->dcsf, &ffb->dcsf);	/* Depth Cue Scale Front Bound */
++	upa_writel(ctx->dcsb, &ffb->dcsb);	/* Depth Cue Scale Back Bound */
++	upa_writel(ctx->dczf, &ffb->dczf);	/* Depth Cue Scale Z Front */
++	upa_writel(ctx->dczb, &ffb->dczb);	/* Depth Cue Scale Z Back */
++	upa_writel(ctx->blendc, &ffb->blendc);	/* Alpha Blend Control */
+ 	upa_writel(ctx->blendc1, &ffb->blendc1);	/* Alpha Blend Color 1 */
+ 	upa_writel(ctx->blendc2, &ffb->blendc2);	/* Alpha Blend Color 2 */
+-	upa_writel(ctx->fbc, &ffb->fbc);		/* Frame Buffer Control */
+-	upa_writel(ctx->rop, &ffb->rop);		/* Raster Operation */
+-	upa_writel(ctx->cmp, &ffb->cmp);		/* Compare Controls */
++	upa_writel(ctx->fbc, &ffb->fbc);	/* Frame Buffer Control */
++	upa_writel(ctx->rop, &ffb->rop);	/* Raster Operation */
++	upa_writel(ctx->cmp, &ffb->cmp);	/* Compare Controls */
+ 	upa_writel(ctx->matchab, &ffb->matchab);	/* Buffer A/B Match Ops */
+-	upa_writel(ctx->matchc, &ffb->matchc);		/* Buffer C Match Ops */
+-	upa_writel(ctx->magnab, &ffb->magnab);		/* Buffer A/B Magnitude Ops */
+-	upa_writel(ctx->magnc, &ffb->magnc);		/* Buffer C Magnitude Ops */
+-	upa_writel(ctx->pmask, &ffb->pmask);		/* RGB Plane Mask */
+-	upa_writel(ctx->xpmask, &ffb->xpmask);		/* X Plane Mask */
+-	upa_writel(ctx->ypmask, &ffb->ypmask);		/* Y Plane Mask */
+-	upa_writel(ctx->zpmask, &ffb->zpmask);		/* Z Plane Mask */
++	upa_writel(ctx->matchc, &ffb->matchc);	/* Buffer C Match Ops */
++	upa_writel(ctx->magnab, &ffb->magnab);	/* Buffer A/B Magnitude Ops */
++	upa_writel(ctx->magnc, &ffb->magnc);	/* Buffer C Magnitude Ops */
++	upa_writel(ctx->pmask, &ffb->pmask);	/* RGB Plane Mask */
++	upa_writel(ctx->xpmask, &ffb->xpmask);	/* X Plane Mask */
++	upa_writel(ctx->ypmask, &ffb->ypmask);	/* Y Plane Mask */
++	upa_writel(ctx->zpmask, &ffb->zpmask);	/* Z Plane Mask */
+ 
+ 	/* Auxiliary Clips. */
+ 	upa_writel(ctx->auxclip0min, &ffb->auxclip[0].min);
+@@ -278,9 +277,9 @@ static void ffb_restore_context(ffb_dev_
+ 	upa_writel(ctx->auxclip3min, &ffb->auxclip[3].min);
+ 	upa_writel(ctx->auxclip3max, &ffb->auxclip[3].max);
+ 
+-	upa_writel(ctx->lpat, &ffb->lpat);		/* Line Pattern */
+-	upa_writel(ctx->fontxy, &ffb->fontxy);		/* XY Font Coordinate */
+-	upa_writel(ctx->fontw, &ffb->fontw);		/* Font Width */
++	upa_writel(ctx->lpat, &ffb->lpat);	/* Line Pattern */
++	upa_writel(ctx->fontxy, &ffb->fontxy);	/* XY Font Coordinate */
++	upa_writel(ctx->fontw, &ffb->fontw);	/* Font Width */
+ 	upa_writel(ctx->fontinc, &ffb->fontinc);	/* Font X/Y Increment */
+ 
+ 	/* These registers/features only exist on FFB2 and later chips. */
+@@ -354,91 +353,87 @@ static void FFBWait(ffb_fbcPtr ffb)
+ 	} while (--limit);
+ }
+ 
+-int ffb_driver_context_switch(drm_device_t *dev, int old, int new)
++int ffb_driver_context_switch(drm_device_t * dev, int old, int new)
+ {
+ 	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ 
+ #ifdef DRM_DMA_HISTOGRAM
+-        dev->ctx_start = get_cycles();
++	dev->ctx_start = get_cycles();
+ #endif
+-        
+-        DRM_DEBUG("Context switch from %d to %d\n", old, new);
+ 
+-        if (new == dev->last_context ||
+-	    dev->last_context == 0) {
++	DRM_DEBUG("Context switch from %d to %d\n", old, new);
++
++	if (new == dev->last_context || dev->last_context == 0) {
+ 		dev->last_context = new;
+-                return 0;
++		return 0;
+ 	}
+-        
++
+ 	FFBWait(fpriv->regs);
+ 	ffb_save_context(fpriv, old);
+ 	ffb_restore_context(fpriv, old, new);
+ 	FFBWait(fpriv->regs);
+-        
++
+ 	dev->last_context = new;
+ 
+-        return 0;
++	return 0;
+ }
+ 
+ int ffb_driver_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
+-		unsigned long arg)
++		      unsigned long arg)
+ {
+-	drm_ctx_res_t	res;
+-	drm_ctx_t	ctx;
+-	int		i;
++	drm_ctx_res_t res;
++	drm_ctx_t ctx;
++	int i;
+ 
+ 	DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
+-	if (copy_from_user(&res, (drm_ctx_res_t __user *)arg, sizeof(res)))
++	if (copy_from_user(&res, (drm_ctx_res_t __user *) arg, sizeof(res)))
+ 		return -EFAULT;
+ 	if (res.count >= DRM_RESERVED_CONTEXTS) {
+ 		memset(&ctx, 0, sizeof(ctx));
+ 		for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ 			ctx.handle = i;
+-			if (copy_to_user(&res.contexts[i],
+-					 &i,
+-					 sizeof(i)))
++			if (copy_to_user(&res.contexts[i], &i, sizeof(i)))
+ 				return -EFAULT;
+ 		}
+ 	}
+ 	res.count = DRM_RESERVED_CONTEXTS;
+-	if (copy_to_user((drm_ctx_res_t __user *)arg, &res, sizeof(res)))
++	if (copy_to_user((drm_ctx_res_t __user *) arg, &res, sizeof(res)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+ 
+-
+ int ffb_driver_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
+-		unsigned long arg)
++		      unsigned long arg)
+ {
+-	drm_file_t	*priv	= filp->private_data;
+-	drm_device_t	*dev	= priv->dev;
+-	drm_ctx_t	ctx;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->dev;
++	drm_ctx_t ctx;
+ 	int idx;
+ 
+-	if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
++	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
+ 		return -EFAULT;
+-	idx = DRM(alloc_queue)(dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
++	idx = DRM(alloc_queue) (dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
+ 	if (idx < 0)
+ 		return -ENFILE;
+ 
+ 	DRM_DEBUG("%d\n", ctx.handle);
+ 	ctx.handle = idx;
+-	if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx)))
++	if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+ 
+ int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
+-		unsigned long arg)
++		      unsigned long arg)
+ {
+-	drm_file_t	*priv	= filp->private_data;
+-	drm_device_t	*dev	= priv->dev;
+-	ffb_dev_priv_t	*fpriv	= (ffb_dev_priv_t *) dev->dev_private;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->dev;
++	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ 	struct ffb_hw_context *hwctx;
+ 	drm_ctx_t ctx;
+ 	int idx;
+ 
+-	if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
++	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
+ 		return -EFAULT;
+ 
+ 	idx = ctx.handle;
+@@ -458,16 +453,16 @@ int ffb_driver_modctx(struct inode *inod
+ }
+ 
+ int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
+-		unsigned long arg)
++		      unsigned long arg)
+ {
+-	drm_file_t	*priv	= filp->private_data;
+-	drm_device_t	*dev	= priv->dev;
+-	ffb_dev_priv_t	*fpriv	= (ffb_dev_priv_t *) dev->dev_private;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->dev;
++	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ 	struct ffb_hw_context *hwctx;
+ 	drm_ctx_t ctx;
+ 	int idx;
+ 
+-	if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
++	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
+ 		return -EFAULT;
+ 
+ 	idx = ctx.handle;
+@@ -483,31 +478,31 @@ int ffb_driver_getctx(struct inode *inod
+ 	else
+ 		ctx.flags = 0;
+ 
+-	if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx)))
++	if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
+ 		return -EFAULT;
+ 
+ 	return 0;
+ }
+ 
+-int ffb_driver_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
+-		   unsigned long arg)
++int ffb_driver_switchctx(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	*priv	= filp->private_data;
+-	drm_device_t	*dev	= priv->dev;
+-	drm_ctx_t	ctx;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->dev;
++	drm_ctx_t ctx;
+ 
+-	if (copy_from_user(&ctx, (drm_ctx_t  __user *)arg, sizeof(ctx)))
++	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
+ 		return -EFAULT;
+ 	DRM_DEBUG("%d\n", ctx.handle);
+ 	return ffb_driver_context_switch(dev, dev->last_context, ctx.handle);
+ }
+ 
+ int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
+-		unsigned long arg)
++		      unsigned long arg)
+ {
+-	drm_ctx_t	ctx;
++	drm_ctx_t ctx;
+ 
+-	if (copy_from_user(&ctx, (drm_ctx_t  __user *)arg, sizeof(ctx)))
++	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
+ 		return -EFAULT;
+ 	DRM_DEBUG("%d\n", ctx.handle);
+ 
+@@ -515,15 +510,15 @@ int ffb_driver_newctx(struct inode *inod
+ }
+ 
+ int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
+-	       unsigned long arg)
++		     unsigned long arg)
+ {
+-	drm_ctx_t	ctx;
+-	drm_file_t	*priv	= filp->private_data;
+-	drm_device_t	*dev	= priv->dev;
+-	ffb_dev_priv_t	*fpriv	= (ffb_dev_priv_t *) dev->dev_private;
++	drm_ctx_t ctx;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->dev;
++	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ 	int idx;
+ 
+-	if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
++	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
+ 		return -EFAULT;
+ 	DRM_DEBUG("%d\n", ctx.handle);
+ 
+@@ -544,7 +539,8 @@ void ffb_set_context_ioctls(void)
+ 	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)].func = ffb_driver_rmctx;
+ 	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)].func = ffb_driver_modctx;
+ 	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)].func = ffb_driver_getctx;
+-	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func = ffb_driver_switchctx;
++	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func =
++	    ffb_driver_switchctx;
+ 	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)].func = ffb_driver_newctx;
+ 	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)].func = ffb_driver_resctx;
+ 
+diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
+--- a/drivers/char/drm/ffb_drv.c
++++ b/drivers/char/drm/ffb_drv.c
+@@ -33,13 +33,13 @@ typedef struct _ffb_position_t {
+ 
+ static ffb_position_t *ffb_position;
+ 
+-static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
++static void get_ffb_type(ffb_dev_priv_t * ffb_priv, int instance)
+ {
+ 	volatile unsigned char *strap_bits;
+ 	unsigned char val;
+ 
+ 	strap_bits = (volatile unsigned char *)
+-		(ffb_priv->card_phys_base + 0x00200000UL);
++	    (ffb_priv->card_phys_base + 0x00200000UL);
+ 
+ 	/* Don't ask, you have to read the value twice for whatever
+ 	 * reason to get correct contents.
+@@ -61,7 +61,8 @@ static void get_ffb_type(ffb_dev_priv_t 
+ 		break;
+ 	case (0x1 << 5) | (0x0 << 3):
+ 		ffb_priv->ffb_type = ffb2_prototype;
+-		printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n", instance);
++		printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n",
++		       instance);
+ 		break;
+ 	case (0x1 << 5) | (0x1 << 3):
+ 		ffb_priv->ffb_type = ffb2_vertical;
+@@ -81,12 +82,13 @@ static void get_ffb_type(ffb_dev_priv_t 
+ 		break;
+ 	default:
+ 		ffb_priv->ffb_type = ffb2_vertical;
+-		printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n", instance, val);
++		printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n",
++		       instance, val);
+ 		break;
+ 	};
+ }
+ 
+-static void ffb_apply_upa_parent_ranges(int parent, 
++static void ffb_apply_upa_parent_ranges(int parent,
+ 					struct linux_prom64_registers *regs)
+ {
+ 	struct linux_prom64_ranges ranges[PROMREG_MAX];
+@@ -97,7 +99,8 @@ static void ffb_apply_upa_parent_ranges(
+ 	if (strcmp(name, "upa") != 0)
+ 		return;
+ 
+-	len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
++	len =
++	    prom_getproperty(parent, "ranges", (void *)ranges, sizeof(ranges));
+ 	if (len <= 0)
+ 		return;
+ 
+@@ -117,11 +120,11 @@ static void ffb_apply_upa_parent_ranges(
+ 	return;
+ }
+ 
+-static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node,
++static int ffb_init_one(drm_device_t * dev, int prom_node, int parent_node,
+ 			int instance)
+ {
+-	struct linux_prom64_registers regs[2*PROMREG_MAX];
+-	ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
++	struct linux_prom64_registers regs[2 * PROMREG_MAX];
++	ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
+ 	int i;
+ 
+ 	ffb_priv->prom_node = prom_node;
+@@ -132,27 +135,27 @@ static int ffb_init_one(drm_device_t *de
+ 	ffb_apply_upa_parent_ranges(parent_node, &regs[0]);
+ 	ffb_priv->card_phys_base = regs[0].phys_addr;
+ 	ffb_priv->regs = (ffb_fbcPtr)
+-		(regs[0].phys_addr + 0x00600000UL);
++	    (regs[0].phys_addr + 0x00600000UL);
+ 	get_ffb_type(ffb_priv, instance);
+ 	for (i = 0; i < FFB_MAX_CTXS; i++)
+ 		ffb_priv->hw_state[i] = NULL;
+-	
++
+ 	return 0;
+ }
+ 
+ static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
+ {
+-	drm_file_t	*priv	= filp->private_data;
+-	drm_device_t	*dev;
+-	drm_map_list_t  *r_list;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev;
++	drm_map_list_t *r_list;
+ 	struct list_head *list;
+-	drm_map_t	*map;
++	drm_map_t *map;
+ 
+ 	if (!priv || (dev = priv->dev) == NULL)
+ 		return NULL;
+ 
+ 	list_for_each(list, &dev->maplist->head) {
+-		r_list = (drm_map_list_t *)list;
++		r_list = (drm_map_list_t *) list;
+ 		map = r_list->map;
+ 		if (!map)
+ 			continue;
+@@ -166,8 +169,7 @@ static drm_map_t *ffb_find_map(struct fi
+ unsigned long ffb_get_unmapped_area(struct file *filp,
+ 				    unsigned long hint,
+ 				    unsigned long len,
+-				    unsigned long pgoff,
+-				    unsigned long flags)
++				    unsigned long pgoff, unsigned long flags)
+ {
+ 	drm_map_t *map = ffb_find_map(filp, pgoff << PAGE_SHIFT);
+ 	unsigned long addr = -ENOMEM;
+@@ -175,8 +177,7 @@ unsigned long ffb_get_unmapped_area(stru
+ 	if (!map)
+ 		return get_unmapped_area(NULL, hint, len, pgoff, flags);
+ 
+-	if (map->type == _DRM_FRAME_BUFFER ||
+-	    map->type == _DRM_REGISTERS) {
++	if (map->type == _DRM_FRAME_BUFFER || map->type == _DRM_REGISTERS) {
+ #ifdef HAVE_ARCH_FB_UNMAPPED_AREA
+ 		addr = get_fb_unmapped_area(filp, hint, len, pgoff, flags);
+ #else
+@@ -187,7 +188,7 @@ unsigned long ffb_get_unmapped_area(stru
+ 
+ 		addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags);
+ 		if (!(addr & ~PAGE_MASK)) {
+-			unsigned long kvirt = (unsigned long) map->handle;
++			unsigned long kvirt = (unsigned long)map->handle;
+ 
+ 			if ((kvirt & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
+ 				unsigned long koff, aoff;
+@@ -207,9 +208,9 @@ unsigned long ffb_get_unmapped_area(stru
+ 	return addr;
+ }
+ 
+-static int ffb_presetup(drm_device_t *dev)
++static int ffb_presetup(drm_device_t * dev)
+ {
+-	ffb_dev_priv_t	*ffb_priv;
++	ffb_dev_priv_t *ffb_priv;
+ 	int ret = 0;
+ 	int i = 0;
+ 
+@@ -224,14 +225,11 @@ static int ffb_presetup(drm_device_t *de
+ 	memset(ffb_priv, 0, sizeof(*ffb_priv));
+ 	dev->dev_private = ffb_priv;
+ 
+-	ret = ffb_init_one(dev,
+-			   ffb_position[i].node,
+-			   ffb_position[i].root,
+-			   i);
++	ret = ffb_init_one(dev, ffb_position[i].node, ffb_position[i].root, i);
+ 	return ret;
+ }
+ 
+-static void ffb_driver_release(drm_device_t *dev, struct file *filp)
++static void ffb_driver_release(drm_device_t * dev, struct file *filp)
+ {
+ 	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ 	int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);
+@@ -239,84 +237,82 @@ static void ffb_driver_release(drm_devic
+ 
+ 	idx = context - 1;
+ 	if (fpriv &&
+-	    context != DRM_KERNEL_CONTEXT &&
+-	    fpriv->hw_state[idx] != NULL) {
++	    context != DRM_KERNEL_CONTEXT && fpriv->hw_state[idx] != NULL) {
+ 		kfree(fpriv->hw_state[idx]);
+ 		fpriv->hw_state[idx] = NULL;
+-	}	
++	}
+ }
+ 
+-static void ffb_driver_pretakedown(drm_device_t *dev)
++static void ffb_driver_pretakedown(drm_device_t * dev)
+ {
+-	if (dev->dev_private) kfree(dev->dev_private);
++	if (dev->dev_private)
++		kfree(dev->dev_private);
+ }
+ 
+-static int ffb_driver_postcleanup(drm_device_t *dev)
++static int ffb_driver_postcleanup(drm_device_t * dev)
+ {
+-	if (ffb_position != NULL) kfree(ffb_position);
++	if (ffb_position != NULL)
++		kfree(ffb_position);
+ 	return 0;
+ }
+ 
+-static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev, drm_lock_t *lock)
++static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev,
++						    drm_lock_t * lock)
+ {
+ 	dev->lock.filp = 0;
+ 	{
+ 		__volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
+ 		unsigned int old, new, prev, ctx;
+-		
++
+ 		ctx = lock->context;
+ 		do {
+-			old  = *plock;
+-			new  = ctx;
++			old = *plock;
++			new = ctx;
+ 			prev = cmpxchg(plock, old, new);
+ 		} while (prev != old);
+ 	}
+ 	wake_up_interruptible(&dev->lock.lock_queue);
+ }
+ 
+-static unsigned long ffb_driver_get_map_ofs(drm_map_t *map)
++static unsigned long ffb_driver_get_map_ofs(drm_map_t * map)
+ {
+ 	return (map->offset & 0xffffffff);
+ }
+ 
+-static unsigned long ffb_driver_get_reg_ofs(drm_device_t *dev)
++static unsigned long ffb_driver_get_reg_ofs(drm_device_t * dev)
++{
++	ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
++
++	if (ffb_priv)
++		return ffb_priv->card_phys_base;
++
++	return 0;
++}
++
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+-       ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
+-       
+-       if (ffb_priv)
+-               return ffb_priv->card_phys_base;
+-       
+-       return 0;
+-}
+-
+-static int postinit( struct drm_device *dev, unsigned long flags ) 
+-{
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->minor
+-		);
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_DATE, dev->minor);
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+ static drm_ioctl_desc_t ioctls[] = {
+-	
++
+ };
+ 
+ static struct drm_driver driver = {
+@@ -335,14 +331,15 @@ static struct drm_driver driver = {
+ 	.ioctls = ioctls,
+ 	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
+-	},
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
++		 }
++	,
+ };
+ 
+ static int __init ffb_init(void)
+@@ -357,6 +354,6 @@ static void __exit ffb_exit(void)
+ module_init(ffb_init);
+ module_exit(ffb_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+diff --git a/drivers/char/drm/ffb_drv.h b/drivers/char/drm/ffb_drv.h
+--- a/drivers/char/drm/ffb_drv.h
++++ b/drivers/char/drm/ffb_drv.h
+@@ -5,7 +5,7 @@
+  */
+ 
+ /* Auxilliary clips. */
+-typedef struct  {
++typedef struct {
+ 	volatile unsigned int min;
+ 	volatile unsigned int max;
+ } ffb_auxclip, *ffb_auxclipPtr;
+@@ -15,172 +15,265 @@ typedef struct _ffb_fbc {
+ 	/* Next vertex registers, on the right we list which drawops
+ 	 * use said register and the logical name the register has in
+ 	 * that context.
+-	 */					/* DESCRIPTION		DRAWOP(NAME)	*/
+-/*0x00*/unsigned int		pad1[3];	/* Reserved				*/
+-/*0x0c*/volatile unsigned int	alpha;		/* ALPHA Transparency			*/
+-/*0x10*/volatile unsigned int	red;		/* RED					*/
+-/*0x14*/volatile unsigned int	green;		/* GREEN				*/
+-/*0x18*/volatile unsigned int	blue;		/* BLUE					*/
+-/*0x1c*/volatile unsigned int	z;		/* DEPTH				*/
+-/*0x20*/volatile unsigned int	y;		/* Y			triangle(DOYF)	*/
+-						/*                      aadot(DYF)	*/
+-						/*                      ddline(DYF)	*/
+-						/*                      aaline(DYF)	*/
+-/*0x24*/volatile unsigned int	x;		/* X			triangle(DOXF)	*/
+-						/*                      aadot(DXF)	*/
+-						/*                      ddline(DXF)	*/
+-						/*                      aaline(DXF)	*/
+-/*0x28*/unsigned int		pad2[2];	/* Reserved				*/
+-/*0x30*/volatile unsigned int	ryf;		/* Y (alias to DOYF)	ddline(RYF)	*/
+-						/*			aaline(RYF)	*/
+-						/*			triangle(RYF)	*/
+-/*0x34*/volatile unsigned int	rxf;		/* X			ddline(RXF)	*/
+-						/*			aaline(RXF)	*/
+-						/*			triangle(RXF)	*/
+-/*0x38*/unsigned int		pad3[2];	/* Reserved				*/
+-/*0x40*/volatile unsigned int	dmyf;		/* Y (alias to DOYF)	triangle(DMYF)	*/
+-/*0x44*/volatile unsigned int	dmxf;		/* X			triangle(DMXF)	*/
+-/*0x48*/unsigned int		pad4[2];	/* Reserved				*/
+-/*0x50*/volatile unsigned int	ebyi;		/* Y (alias to RYI)	polygon(EBYI)	*/
+-/*0x54*/volatile unsigned int	ebxi;		/* X			polygon(EBXI)	*/
+-/*0x58*/unsigned int		pad5[2];	/* Reserved				*/
+-/*0x60*/volatile unsigned int	by;		/* Y			brline(RYI)	*/
+-						/*			fastfill(OP)	*/
+-						/*			polygon(YI)	*/
+-						/*			rectangle(YI)	*/
+-						/*			bcopy(SRCY)	*/
+-						/*			vscroll(SRCY)	*/
+-/*0x64*/volatile unsigned int	bx;		/* X			brline(RXI)	*/
+-						/*			polygon(XI)	*/
+-						/*			rectangle(XI)	*/
+-						/*			bcopy(SRCX)	*/
+-						/*			vscroll(SRCX)	*/
+-						/*			fastfill(GO)	*/
+-/*0x68*/volatile unsigned int	dy;		/* destination Y	fastfill(DSTY)	*/
+-						/*			bcopy(DSRY)	*/
+-						/*			vscroll(DSRY)	*/
+-/*0x6c*/volatile unsigned int	dx;		/* destination X	fastfill(DSTX)	*/
+-						/*			bcopy(DSTX)	*/
+-						/*			vscroll(DSTX)	*/
+-/*0x70*/volatile unsigned int	bh;		/* Y (alias to RYI)	brline(DYI)	*/
+-						/*			dot(DYI)	*/
+-						/*			polygon(ETYI)	*/
+-						/* Height		fastfill(H)	*/
+-						/*			bcopy(H)	*/
+-						/*			vscroll(H)	*/
+-						/* Y count		fastfill(NY)	*/
+-/*0x74*/volatile unsigned int	bw;		/* X			dot(DXI)	*/
+-						/*			brline(DXI)	*/
+-						/*			polygon(ETXI)	*/
+-						/*			fastfill(W)	*/
+-						/*			bcopy(W)	*/
+-						/*			vscroll(W)	*/
+-						/*			fastfill(NX)	*/
+-/*0x78*/unsigned int		pad6[2];	/* Reserved				*/
+-/*0x80*/unsigned int		pad7[32];	/* Reserved				*/
+-	
++	 *//* DESCRIPTION          DRAWOP(NAME)    */
++					/*0x00*/ unsigned int pad1[3];
++					/* Reserved                             */
++						/*0x0c*/ volatile unsigned int alpha;
++						/* ALPHA Transparency                   */
++						/*0x10*/ volatile unsigned int red;
++						/* RED                                  */
++						/*0x14*/ volatile unsigned int green;
++						/* GREEN                                */
++						/*0x18*/ volatile unsigned int blue;
++						/* BLUE                                 */
++						/*0x1c*/ volatile unsigned int z;
++						/* DEPTH                                */
++						/*0x20*/ volatile unsigned int y;
++						/* Y                    triangle(DOYF)  */
++	/*                      aadot(DYF)      */
++	/*                      ddline(DYF)     */
++	/*                      aaline(DYF)     */
++						/*0x24*/ volatile unsigned int x;
++						/* X                    triangle(DOXF)  */
++	/*                      aadot(DXF)      */
++	/*                      ddline(DXF)     */
++	/*                      aaline(DXF)     */
++					/*0x28*/ unsigned int pad2[2];
++					/* Reserved                             */
++						/*0x30*/ volatile unsigned int ryf;
++						/* Y (alias to DOYF)    ddline(RYF)     */
++	/*                      aaline(RYF)     */
++	/*                      triangle(RYF)   */
++						/*0x34*/ volatile unsigned int rxf;
++						/* X                    ddline(RXF)     */
++	/*                      aaline(RXF)     */
++	/*                      triangle(RXF)   */
++					/*0x38*/ unsigned int pad3[2];
++					/* Reserved                             */
++						/*0x40*/ volatile unsigned int dmyf;
++						/* Y (alias to DOYF)    triangle(DMYF)  */
++						/*0x44*/ volatile unsigned int dmxf;
++						/* X                    triangle(DMXF)  */
++					/*0x48*/ unsigned int pad4[2];
++					/* Reserved                             */
++						/*0x50*/ volatile unsigned int ebyi;
++						/* Y (alias to RYI)     polygon(EBYI)   */
++						/*0x54*/ volatile unsigned int ebxi;
++						/* X                    polygon(EBXI)   */
++					/*0x58*/ unsigned int pad5[2];
++					/* Reserved                             */
++						/*0x60*/ volatile unsigned int by;
++						/* Y                    brline(RYI)     */
++	/*                      fastfill(OP)    */
++	/*                      polygon(YI)     */
++	/*                      rectangle(YI)   */
++	/*                      bcopy(SRCY)     */
++	/*                      vscroll(SRCY)   */
++						/*0x64*/ volatile unsigned int bx;
++						/* X                    brline(RXI)     */
++	/*                      polygon(XI)     */
++	/*                      rectangle(XI)   */
++	/*                      bcopy(SRCX)     */
++	/*                      vscroll(SRCX)   */
++	/*                      fastfill(GO)    */
++						/*0x68*/ volatile unsigned int dy;
++						/* destination Y        fastfill(DSTY)  */
++	/*                      bcopy(DSRY)     */
++	/*                      vscroll(DSRY)   */
++						/*0x6c*/ volatile unsigned int dx;
++						/* destination X        fastfill(DSTX)  */
++	/*                      bcopy(DSTX)     */
++	/*                      vscroll(DSTX)   */
++						/*0x70*/ volatile unsigned int bh;
++						/* Y (alias to RYI)     brline(DYI)     */
++	/*                      dot(DYI)        */
++	/*                      polygon(ETYI)   */
++	/* Height               fastfill(H)     */
++	/*                      bcopy(H)        */
++	/*                      vscroll(H)      */
++	/* Y count              fastfill(NY)    */
++						/*0x74*/ volatile unsigned int bw;
++						/* X                    dot(DXI)        */
++	/*                      brline(DXI)     */
++	/*                      polygon(ETXI)   */
++	/*                      fastfill(W)     */
++	/*                      bcopy(W)        */
++	/*                      vscroll(W)      */
++	/*                      fastfill(NX)    */
++					/*0x78*/ unsigned int pad6[2];
++					/* Reserved                             */
++					/*0x80*/ unsigned int pad7[32];
++					/* Reserved                             */
++
+ 	/* Setup Unit's vertex state register */
+-/*100*/	volatile unsigned int	suvtx;
+-/*104*/	unsigned int		pad8[63];	/* Reserved				*/
+-	
++/*100*/ volatile unsigned int suvtx;
++					/*104*/ unsigned int pad8[63];
++					/* Reserved                             */
++
+ 	/* Frame Buffer Control Registers */
+-/*200*/	volatile unsigned int	ppc;		/* Pixel Processor Control		*/
+-/*204*/	volatile unsigned int	wid;		/* Current WID				*/
+-/*208*/	volatile unsigned int	fg;		/* FG data				*/
+-/*20c*/	volatile unsigned int	bg;		/* BG data				*/
+-/*210*/	volatile unsigned int	consty;		/* Constant Y				*/
+-/*214*/	volatile unsigned int	constz;		/* Constant Z				*/
+-/*218*/	volatile unsigned int	xclip;		/* X Clip				*/
+-/*21c*/	volatile unsigned int	dcss;		/* Depth Cue Scale Slope		*/
+-/*220*/	volatile unsigned int	vclipmin;	/* Viewclip XY Min Bounds		*/
+-/*224*/	volatile unsigned int	vclipmax;	/* Viewclip XY Max Bounds		*/
+-/*228*/	volatile unsigned int	vclipzmin;	/* Viewclip Z Min Bounds		*/
+-/*22c*/	volatile unsigned int	vclipzmax;	/* Viewclip Z Max Bounds		*/
+-/*230*/	volatile unsigned int	dcsf;		/* Depth Cue Scale Front Bound		*/
+-/*234*/	volatile unsigned int	dcsb;		/* Depth Cue Scale Back Bound		*/
+-/*238*/	volatile unsigned int	dczf;		/* Depth Cue Z Front			*/
+-/*23c*/	volatile unsigned int	dczb;		/* Depth Cue Z Back			*/
+-/*240*/	unsigned int		pad9;		/* Reserved				*/
+-/*244*/	volatile unsigned int	blendc;		/* Alpha Blend Control			*/
+-/*248*/	volatile unsigned int	blendc1;	/* Alpha Blend Color 1			*/
+-/*24c*/	volatile unsigned int	blendc2;	/* Alpha Blend Color 2			*/
+-/*250*/	volatile unsigned int	fbramitc;	/* FB RAM Interleave Test Control	*/
+-/*254*/	volatile unsigned int	fbc;		/* Frame Buffer Control			*/
+-/*258*/	volatile unsigned int	rop;		/* Raster OPeration			*/
+-/*25c*/	volatile unsigned int	cmp;		/* Frame Buffer Compare			*/
+-/*260*/	volatile unsigned int	matchab;	/* Buffer AB Match Mask			*/
+-/*264*/	volatile unsigned int	matchc;		/* Buffer C(YZ) Match Mask		*/
+-/*268*/	volatile unsigned int	magnab;		/* Buffer AB Magnitude Mask		*/
+-/*26c*/	volatile unsigned int	magnc;		/* Buffer C(YZ) Magnitude Mask		*/
+-/*270*/	volatile unsigned int	fbcfg0;		/* Frame Buffer Config 0		*/
+-/*274*/	volatile unsigned int	fbcfg1;		/* Frame Buffer Config 1		*/
+-/*278*/	volatile unsigned int	fbcfg2;		/* Frame Buffer Config 2		*/
+-/*27c*/	volatile unsigned int	fbcfg3;		/* Frame Buffer Config 3		*/
+-/*280*/	volatile unsigned int	ppcfg;		/* Pixel Processor Config		*/
+-/*284*/	volatile unsigned int	pick;		/* Picking Control			*/
+-/*288*/	volatile unsigned int	fillmode;	/* FillMode				*/
+-/*28c*/	volatile unsigned int	fbramwac;	/* FB RAM Write Address Control		*/
+-/*290*/	volatile unsigned int	pmask;		/* RGB PlaneMask			*/
+-/*294*/	volatile unsigned int	xpmask;		/* X PlaneMask				*/
+-/*298*/	volatile unsigned int	ypmask;		/* Y PlaneMask				*/
+-/*29c*/	volatile unsigned int	zpmask;		/* Z PlaneMask				*/
+-/*2a0*/	ffb_auxclip		auxclip[4]; 	/* Auxilliary Viewport Clip		*/
+-	
++						/*200*/ volatile unsigned int ppc;
++						/* Pixel Processor Control              */
++						/*204*/ volatile unsigned int wid;
++						/* Current WID                          */
++						/*208*/ volatile unsigned int fg;
++						/* FG data                              */
++						/*20c*/ volatile unsigned int bg;
++						/* BG data                              */
++						/*210*/ volatile unsigned int consty;
++						/* Constant Y                           */
++						/*214*/ volatile unsigned int constz;
++						/* Constant Z                           */
++						/*218*/ volatile unsigned int xclip;
++						/* X Clip                               */
++						/*21c*/ volatile unsigned int dcss;
++						/* Depth Cue Scale Slope                */
++						/*220*/ volatile unsigned int vclipmin;
++						/* Viewclip XY Min Bounds               */
++						/*224*/ volatile unsigned int vclipmax;
++						/* Viewclip XY Max Bounds               */
++							/*228*/ volatile unsigned int vclipzmin;
++							/* Viewclip Z Min Bounds                */
++							/*22c*/ volatile unsigned int vclipzmax;
++							/* Viewclip Z Max Bounds                */
++						/*230*/ volatile unsigned int dcsf;
++						/* Depth Cue Scale Front Bound          */
++						/*234*/ volatile unsigned int dcsb;
++						/* Depth Cue Scale Back Bound           */
++						/*238*/ volatile unsigned int dczf;
++						/* Depth Cue Z Front                    */
++						/*23c*/ volatile unsigned int dczb;
++						/* Depth Cue Z Back                     */
++					/*240*/ unsigned int pad9;
++					/* Reserved                             */
++						/*244*/ volatile unsigned int blendc;
++						/* Alpha Blend Control                  */
++						/*248*/ volatile unsigned int blendc1;
++						/* Alpha Blend Color 1                  */
++						/*24c*/ volatile unsigned int blendc2;
++						/* Alpha Blend Color 2                  */
++						/*250*/ volatile unsigned int fbramitc;
++						/* FB RAM Interleave Test Control       */
++						/*254*/ volatile unsigned int fbc;
++						/* Frame Buffer Control                 */
++						/*258*/ volatile unsigned int rop;
++						/* Raster OPeration                     */
++						/*25c*/ volatile unsigned int cmp;
++						/* Frame Buffer Compare                 */
++						/*260*/ volatile unsigned int matchab;
++						/* Buffer AB Match Mask                 */
++						/*264*/ volatile unsigned int matchc;
++						/* Buffer C(YZ) Match Mask              */
++						/*268*/ volatile unsigned int magnab;
++						/* Buffer AB Magnitude Mask             */
++						/*26c*/ volatile unsigned int magnc;
++						/* Buffer C(YZ) Magnitude Mask          */
++						/*270*/ volatile unsigned int fbcfg0;
++						/* Frame Buffer Config 0                */
++						/*274*/ volatile unsigned int fbcfg1;
++						/* Frame Buffer Config 1                */
++						/*278*/ volatile unsigned int fbcfg2;
++						/* Frame Buffer Config 2                */
++						/*27c*/ volatile unsigned int fbcfg3;
++						/* Frame Buffer Config 3                */
++						/*280*/ volatile unsigned int ppcfg;
++						/* Pixel Processor Config               */
++						/*284*/ volatile unsigned int pick;
++						/* Picking Control                      */
++						/*288*/ volatile unsigned int fillmode;
++						/* FillMode                             */
++						/*28c*/ volatile unsigned int fbramwac;
++						/* FB RAM Write Address Control         */
++						/*290*/ volatile unsigned int pmask;
++						/* RGB PlaneMask                        */
++						/*294*/ volatile unsigned int xpmask;
++						/* X PlaneMask                          */
++						/*298*/ volatile unsigned int ypmask;
++						/* Y PlaneMask                          */
++						/*29c*/ volatile unsigned int zpmask;
++						/* Z PlaneMask                          */
++					/*2a0*/ ffb_auxclip auxclip[4];
++					/* Auxilliary Viewport Clip             */
++
+ 	/* New 3dRAM III support regs */
+-/*2c0*/	volatile unsigned int	rawblend2;
+-/*2c4*/	volatile unsigned int	rawpreblend;
+-/*2c8*/	volatile unsigned int	rawstencil;
+-/*2cc*/	volatile unsigned int	rawstencilctl;
+-/*2d0*/	volatile unsigned int	threedram1;
+-/*2d4*/	volatile unsigned int	threedram2;
+-/*2d8*/	volatile unsigned int	passin;
+-/*2dc*/	volatile unsigned int	rawclrdepth;
+-/*2e0*/	volatile unsigned int	rawpmask;
+-/*2e4*/	volatile unsigned int	rawcsrc;
+-/*2e8*/	volatile unsigned int	rawmatch;
+-/*2ec*/	volatile unsigned int	rawmagn;
+-/*2f0*/	volatile unsigned int	rawropblend;
+-/*2f4*/	volatile unsigned int	rawcmp;
+-/*2f8*/	volatile unsigned int	rawwac;
+-/*2fc*/	volatile unsigned int	fbramid;
+-	
+-/*300*/	volatile unsigned int	drawop;		/* Draw OPeration			*/
+-/*304*/	unsigned int		pad10[2];	/* Reserved				*/
+-/*30c*/	volatile unsigned int	lpat;		/* Line Pattern control			*/
+-/*310*/	unsigned int		pad11;		/* Reserved				*/
+-/*314*/	volatile unsigned int	fontxy;		/* XY Font coordinate			*/
+-/*318*/	volatile unsigned int	fontw;		/* Font Width				*/
+-/*31c*/	volatile unsigned int	fontinc;	/* Font Increment			*/
+-/*320*/	volatile unsigned int	font;		/* Font bits				*/
+-/*324*/	unsigned int		pad12[3];	/* Reserved				*/
+-/*330*/	volatile unsigned int	blend2;
+-/*334*/	volatile unsigned int	preblend;
+-/*338*/	volatile unsigned int	stencil;
+-/*33c*/	volatile unsigned int	stencilctl;
+-
+-/*340*/	unsigned int		pad13[4];	/* Reserved				*/
+-/*350*/	volatile unsigned int	dcss1;		/* Depth Cue Scale Slope 1		*/
+-/*354*/	volatile unsigned int	dcss2;		/* Depth Cue Scale Slope 2		*/
+-/*358*/	volatile unsigned int	dcss3;		/* Depth Cue Scale Slope 3		*/
+-/*35c*/	volatile unsigned int	widpmask;
+-/*360*/	volatile unsigned int	dcs2;
+-/*364*/	volatile unsigned int	dcs3;
+-/*368*/	volatile unsigned int	dcs4;
+-/*36c*/	unsigned int		pad14;		/* Reserved				*/
+-/*370*/	volatile unsigned int	dcd2;
+-/*374*/	volatile unsigned int	dcd3;
+-/*378*/	volatile unsigned int	dcd4;
+-/*37c*/	unsigned int		pad15;		/* Reserved				*/
+-/*380*/	volatile unsigned int	pattern[32];	/* area Pattern				*/
+-/*400*/	unsigned int		pad16[8];	/* Reserved				*/
+-/*420*/	volatile unsigned int	reset;		/* chip RESET				*/
+-/*424*/	unsigned int		pad17[247];	/* Reserved				*/
+-/*800*/	volatile unsigned int	devid;		/* Device ID				*/
+-/*804*/	unsigned int		pad18[63];	/* Reserved				*/
+-/*900*/	volatile unsigned int	ucsr;		/* User Control & Status Register	*/
+-/*904*/	unsigned int		pad19[31];	/* Reserved				*/
+-/*980*/	volatile unsigned int	mer;		/* Mode Enable Register			*/
+-/*984*/	unsigned int		pad20[1439];	/* Reserved				*/
++/*2c0*/ volatile unsigned int rawblend2;
++/*2c4*/ volatile unsigned int rawpreblend;
++/*2c8*/ volatile unsigned int rawstencil;
++/*2cc*/ volatile unsigned int rawstencilctl;
++/*2d0*/ volatile unsigned int threedram1;
++/*2d4*/ volatile unsigned int threedram2;
++/*2d8*/ volatile unsigned int passin;
++/*2dc*/ volatile unsigned int rawclrdepth;
++/*2e0*/ volatile unsigned int rawpmask;
++/*2e4*/ volatile unsigned int rawcsrc;
++/*2e8*/ volatile unsigned int rawmatch;
++/*2ec*/ volatile unsigned int rawmagn;
++/*2f0*/ volatile unsigned int rawropblend;
++/*2f4*/ volatile unsigned int rawcmp;
++/*2f8*/ volatile unsigned int rawwac;
++/*2fc*/ volatile unsigned int fbramid;
++
++						/*300*/ volatile unsigned int drawop;
++						/* Draw OPeration                       */
++					/*304*/ unsigned int pad10[2];
++					/* Reserved                             */
++						/*30c*/ volatile unsigned int lpat;
++						/* Line Pattern control                 */
++					/*310*/ unsigned int pad11;
++					/* Reserved                             */
++						/*314*/ volatile unsigned int fontxy;
++						/* XY Font coordinate                   */
++						/*318*/ volatile unsigned int fontw;
++						/* Font Width                           */
++						/*31c*/ volatile unsigned int fontinc;
++						/* Font Increment                       */
++						/*320*/ volatile unsigned int font;
++						/* Font bits                            */
++					/*324*/ unsigned int pad12[3];
++					/* Reserved                             */
++/*330*/ volatile unsigned int blend2;
++/*334*/ volatile unsigned int preblend;
++/*338*/ volatile unsigned int stencil;
++/*33c*/ volatile unsigned int stencilctl;
++
++					/*340*/ unsigned int pad13[4];
++					/* Reserved                             */
++						/*350*/ volatile unsigned int dcss1;
++						/* Depth Cue Scale Slope 1              */
++						/*354*/ volatile unsigned int dcss2;
++						/* Depth Cue Scale Slope 2              */
++						/*358*/ volatile unsigned int dcss3;
++						/* Depth Cue Scale Slope 3              */
++/*35c*/ volatile unsigned int widpmask;
++/*360*/ volatile unsigned int dcs2;
++/*364*/ volatile unsigned int dcs3;
++/*368*/ volatile unsigned int dcs4;
++					/*36c*/ unsigned int pad14;
++					/* Reserved                             */
++/*370*/ volatile unsigned int dcd2;
++/*374*/ volatile unsigned int dcd3;
++/*378*/ volatile unsigned int dcd4;
++					/*37c*/ unsigned int pad15;
++					/* Reserved                             */
++							/*380*/ volatile unsigned int pattern[32];
++							/* area Pattern                         */
++					/*400*/ unsigned int pad16[8];
++					/* Reserved                             */
++						/*420*/ volatile unsigned int reset;
++						/* chip RESET                           */
++						/*424*/ unsigned int pad17[247];
++						/* Reserved                             */
++						/*800*/ volatile unsigned int devid;
++						/* Device ID                            */
++					/*804*/ unsigned int pad18[63];
++					/* Reserved                             */
++						/*900*/ volatile unsigned int ucsr;
++						/* User Control & Status Register       */
++					/*904*/ unsigned int pad19[31];
++					/* Reserved                             */
++						/*980*/ volatile unsigned int mer;
++						/* Mode Enable Register                 */
++						/*984*/ unsigned int pad20[1439];
++						/* Reserved                             */
+ } ffb_fbc, *ffb_fbcPtr;
+ 
+ struct ffb_hw_context {
+@@ -263,16 +356,16 @@ enum ffb_chip_type {
+ 
+ typedef struct ffb_dev_priv {
+ 	/* Misc software state. */
+-	int			prom_node;
+-	enum ffb_chip_type	ffb_type;
+-	u64			card_phys_base;
+-	struct miscdevice 	miscdev;
++	int prom_node;
++	enum ffb_chip_type ffb_type;
++	u64 card_phys_base;
++	struct miscdevice miscdev;
+ 
+ 	/* Controller registers. */
+-	ffb_fbcPtr		regs;
++	ffb_fbcPtr regs;
+ 
+ 	/* Context table. */
+-	struct ffb_hw_context	*hw_state[FFB_MAX_CTXS];
++	struct ffb_hw_context *hw_state[FFB_MAX_CTXS];
+ } ffb_dev_priv_t;
+ 
+ extern unsigned long ffb_get_unmapped_area(struct file *filp,
+@@ -283,4 +376,4 @@ extern unsigned long ffb_get_unmapped_ar
+ extern void ffb_set_context_ioctls(void);
+ extern drm_ioctl_desc_t DRM(ioctls)[];
+ 
+-extern int ffb_driver_context_switch(drm_device_t *dev, int old, int new);
++extern int ffb_driver_context_switch(drm_device_t * dev, int old, int new);
+diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
+--- a/drivers/char/drm/i810_dma.c
++++ b/drivers/char/drm/i810_dma.c
+@@ -45,102 +45,101 @@
+ #define I810_BUF_UNMAPPED 0
+ #define I810_BUF_MAPPED   1
+ 
+-static drm_buf_t *i810_freelist_get(drm_device_t *dev)
++static drm_buf_t *i810_freelist_get(drm_device_t * dev)
+ {
+-   	drm_device_dma_t *dma = dev->dma;
+-	int		 i;
+-   	int 		 used;
++	drm_device_dma_t *dma = dev->dma;
++	int i;
++	int used;
+ 
+ 	/* Linear search might not be the best solution */
+ 
+-   	for (i = 0; i < dma->buf_count; i++) {
+-	   	drm_buf_t *buf = dma->buflist[ i ];
+-	   	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
++	for (i = 0; i < dma->buf_count; i++) {
++		drm_buf_t *buf = dma->buflist[i];
++		drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ 		/* In use is already a pointer */
+-	   	used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
++		used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
+ 			       I810_BUF_CLIENT);
+ 		if (used == I810_BUF_FREE) {
+ 			return buf;
+ 		}
+ 	}
+-   	return NULL;
++	return NULL;
+ }
+ 
+ /* This should only be called if the buffer is not sent to the hardware
+  * yet, the hardware updates in use for us once its on the ring buffer.
+  */
+ 
+-static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf)
++static int i810_freelist_put(drm_device_t * dev, drm_buf_t * buf)
+ {
+-   	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+-   	int used;
++	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
++	int used;
+ 
+-   	/* In use is already a pointer */
+-   	used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE);
++	/* In use is already a pointer */
++	used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE);
+ 	if (used != I810_BUF_CLIENT) {
+-	   	DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
+-	   	return -EINVAL;
++		DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
++		return -EINVAL;
+ 	}
+ 
+-   	return 0;
++	return 0;
+ }
+ 
+ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
+ {
+-	drm_file_t	    *priv	  = filp->private_data;
+-	drm_device_t	    *dev;
+-	drm_i810_private_t  *dev_priv;
+-	drm_buf_t           *buf;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev;
++	drm_i810_private_t *dev_priv;
++	drm_buf_t *buf;
+ 	drm_i810_buf_priv_t *buf_priv;
+ 
+ 	lock_kernel();
+-	dev	 = priv->head->dev;
++	dev = priv->head->dev;
+ 	dev_priv = dev->dev_private;
+-	buf      = dev_priv->mmap_buffer;
++	buf = dev_priv->mmap_buffer;
+ 	buf_priv = buf->dev_private;
+ 
+ 	vma->vm_flags |= (VM_IO | VM_DONTCOPY);
+ 	vma->vm_file = filp;
+ 
+-   	buf_priv->currently_mapped = I810_BUF_MAPPED;
++	buf_priv->currently_mapped = I810_BUF_MAPPED;
+ 	unlock_kernel();
+ 
+ 	if (io_remap_pfn_range(vma, vma->vm_start,
+-			     VM_OFFSET(vma) >> PAGE_SHIFT,
+-			     vma->vm_end - vma->vm_start,
+-			     vma->vm_page_prot)) return -EAGAIN;
++			       VM_OFFSET(vma) >> PAGE_SHIFT,
++			       vma->vm_end - vma->vm_start, vma->vm_page_prot))
++		return -EAGAIN;
+ 	return 0;
+ }
+ 
+ static struct file_operations i810_buffer_fops = {
+-	.open	 = drm_open,
+-	.flush	 = drm_flush,
++	.open = drm_open,
++	.flush = drm_flush,
+ 	.release = drm_release,
+-	.ioctl	 = drm_ioctl,
+-	.mmap	 = i810_mmap_buffers,
+-	.fasync  = drm_fasync,
++	.ioctl = drm_ioctl,
++	.mmap = i810_mmap_buffers,
++	.fasync = drm_fasync,
+ };
+ 
+-static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
++static int i810_map_buffer(drm_buf_t * buf, struct file *filp)
+ {
+-	drm_file_t	  *priv	  = filp->private_data;
+-	drm_device_t	  *dev	  = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+-      	drm_i810_private_t *dev_priv = dev->dev_private;
+-   	struct file_operations *old_fops;
++	drm_i810_private_t *dev_priv = dev->dev_private;
++	struct file_operations *old_fops;
+ 	int retcode = 0;
+ 
+-	if (buf_priv->currently_mapped == I810_BUF_MAPPED) 
++	if (buf_priv->currently_mapped == I810_BUF_MAPPED)
+ 		return -EINVAL;
+ 
+-	down_write( &current->mm->mmap_sem );
++	down_write(&current->mm->mmap_sem);
+ 	old_fops = filp->f_op;
+ 	filp->f_op = &i810_buffer_fops;
+ 	dev_priv->mmap_buffer = buf;
+ 	buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
+-					    PROT_READ|PROT_WRITE,
+-					    MAP_SHARED,
+-					    buf->bus_address);
++					    PROT_READ | PROT_WRITE,
++					    MAP_SHARED, buf->bus_address);
+ 	dev_priv->mmap_buffer = NULL;
+ 	filp->f_op = old_fops;
+ 	if ((unsigned long)buf_priv->virtual > -1024UL) {
+@@ -149,12 +148,12 @@ static int i810_map_buffer(drm_buf_t *bu
+ 		retcode = (signed int)buf_priv->virtual;
+ 		buf_priv->virtual = NULL;
+ 	}
+-	up_write( &current->mm->mmap_sem );
++	up_write(&current->mm->mmap_sem);
+ 
+ 	return retcode;
+ }
+ 
+-static int i810_unmap_buffer(drm_buf_t *buf)
++static int i810_unmap_buffer(drm_buf_t * buf)
+ {
+ 	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ 	int retcode = 0;
+@@ -168,43 +167,43 @@ static int i810_unmap_buffer(drm_buf_t *
+ 			    (size_t) buf->total);
+ 	up_write(&current->mm->mmap_sem);
+ 
+-   	buf_priv->currently_mapped = I810_BUF_UNMAPPED;
+-   	buf_priv->virtual = NULL;
++	buf_priv->currently_mapped = I810_BUF_UNMAPPED;
++	buf_priv->virtual = NULL;
+ 
+ 	return retcode;
+ }
+ 
+-static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
++static int i810_dma_get_buffer(drm_device_t * dev, drm_i810_dma_t * d,
+ 			       struct file *filp)
+ {
+-	drm_buf_t	  *buf;
++	drm_buf_t *buf;
+ 	drm_i810_buf_priv_t *buf_priv;
+ 	int retcode = 0;
+ 
+ 	buf = i810_freelist_get(dev);
+ 	if (!buf) {
+ 		retcode = -ENOMEM;
+-	   	DRM_DEBUG("retcode=%d\n", retcode);
++		DRM_DEBUG("retcode=%d\n", retcode);
+ 		return retcode;
+ 	}
+ 
+ 	retcode = i810_map_buffer(buf, filp);
+ 	if (retcode) {
+ 		i810_freelist_put(dev, buf);
+-	   	DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
++		DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
+ 		return retcode;
+ 	}
+ 	buf->filp = filp;
+ 	buf_priv = buf->dev_private;
+ 	d->granted = 1;
+-   	d->request_idx = buf->idx;
+-   	d->request_size = buf->total;
+-   	d->virtual = buf_priv->virtual;
++	d->request_idx = buf->idx;
++	d->request_size = buf->total;
++	d->virtual = buf_priv->virtual;
+ 
+ 	return retcode;
+ }
+ 
+-static int i810_dma_cleanup(drm_device_t *dev)
++static int i810_dma_cleanup(drm_device_t * dev)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 
+@@ -217,165 +216,167 @@ static int i810_dma_cleanup(drm_device_t
+ 
+ 	if (dev->dev_private) {
+ 		int i;
+-	   	drm_i810_private_t *dev_priv =
+-	     		(drm_i810_private_t *) dev->dev_private;
++		drm_i810_private_t *dev_priv =
++		    (drm_i810_private_t *) dev->dev_private;
+ 
+ 		if (dev_priv->ring.virtual_start) {
+-		   	drm_ioremapfree((void *) dev_priv->ring.virtual_start,
+-					 dev_priv->ring.Size, dev);
++			drm_ioremapfree((void *)dev_priv->ring.virtual_start,
++					dev_priv->ring.Size, dev);
+ 		}
+-	   	if (dev_priv->hw_status_page) {
+-		   	pci_free_consistent(dev->pdev, PAGE_SIZE,
++		if (dev_priv->hw_status_page) {
++			pci_free_consistent(dev->pdev, PAGE_SIZE,
+ 					    dev_priv->hw_status_page,
+ 					    dev_priv->dma_status_page);
+-		   	/* Need to rewrite hardware status page */
+-		   	I810_WRITE(0x02080, 0x1ffff000);
++			/* Need to rewrite hardware status page */
++			I810_WRITE(0x02080, 0x1ffff000);
+ 		}
+-	   	drm_free(dev->dev_private, sizeof(drm_i810_private_t),
++		drm_free(dev->dev_private, sizeof(drm_i810_private_t),
+ 			 DRM_MEM_DRIVER);
+-	   	dev->dev_private = NULL;
++		dev->dev_private = NULL;
+ 
+ 		for (i = 0; i < dma->buf_count; i++) {
+-			drm_buf_t *buf = dma->buflist[ i ];
++			drm_buf_t *buf = dma->buflist[i];
+ 			drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+-			if ( buf_priv->kernel_virtual && buf->total )
+-				drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev);
++			if (buf_priv->kernel_virtual && buf->total)
++				drm_ioremapfree(buf_priv->kernel_virtual,
++						buf->total, dev);
+ 		}
+ 	}
+-   	return 0;
++	return 0;
+ }
+ 
+-static int i810_wait_ring(drm_device_t *dev, int n)
++static int i810_wait_ring(drm_device_t * dev, int n)
+ {
+-   	drm_i810_private_t *dev_priv = dev->dev_private;
+-   	drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
+-   	int iters = 0;
+-   	unsigned long end;
++	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
++	int iters = 0;
++	unsigned long end;
+ 	unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ 
+-	end = jiffies + (HZ*3);
+-   	while (ring->space < n) {
+-	   	ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+-	   	ring->space = ring->head - (ring->tail+8);
+-		if (ring->space < 0) ring->space += ring->Size;
+-	   
++	end = jiffies + (HZ * 3);
++	while (ring->space < n) {
++		ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
++		ring->space = ring->head - (ring->tail + 8);
++		if (ring->space < 0)
++			ring->space += ring->Size;
++
+ 		if (ring->head != last_head) {
+-			end = jiffies + (HZ*3);
++			end = jiffies + (HZ * 3);
+ 			last_head = ring->head;
+ 		}
+-	  
+-	   	iters++;
++
++		iters++;
+ 		if (time_before(end, jiffies)) {
+-		   	DRM_ERROR("space: %d wanted %d\n", ring->space, n);
+-		   	DRM_ERROR("lockup\n");
+-		   	goto out_wait_ring;
++			DRM_ERROR("space: %d wanted %d\n", ring->space, n);
++			DRM_ERROR("lockup\n");
++			goto out_wait_ring;
+ 		}
+ 		udelay(1);
+ 	}
+ 
+-out_wait_ring:
+-   	return iters;
++      out_wait_ring:
++	return iters;
+ }
+ 
+-static void i810_kernel_lost_context(drm_device_t *dev)
++static void i810_kernel_lost_context(drm_device_t * dev)
+ {
+-      	drm_i810_private_t *dev_priv = dev->dev_private;
+-   	drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
++	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
+ 
+-   	ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+-     	ring->tail = I810_READ(LP_RING + RING_TAIL);
+-     	ring->space = ring->head - (ring->tail+8);
+-     	if (ring->space < 0) ring->space += ring->Size;
++	ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
++	ring->tail = I810_READ(LP_RING + RING_TAIL);
++	ring->space = ring->head - (ring->tail + 8);
++	if (ring->space < 0)
++		ring->space += ring->Size;
+ }
+ 
+-static int i810_freelist_init(drm_device_t *dev, drm_i810_private_t *dev_priv)
++static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv)
+ {
+-      	drm_device_dma_t *dma = dev->dma;
+-   	int my_idx = 24;
+-   	u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx);
+-   	int i;
++	drm_device_dma_t *dma = dev->dma;
++	int my_idx = 24;
++	u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx);
++	int i;
+ 
+ 	if (dma->buf_count > 1019) {
+-	   	/* Not enough space in the status page for the freelist */
+-	   	return -EINVAL;
++		/* Not enough space in the status page for the freelist */
++		return -EINVAL;
+ 	}
+ 
+-   	for (i = 0; i < dma->buf_count; i++) {
+-	   	drm_buf_t *buf = dma->buflist[ i ];
+-	   	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
++	for (i = 0; i < dma->buf_count; i++) {
++		drm_buf_t *buf = dma->buflist[i];
++		drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ 
+-	   	buf_priv->in_use = hw_status++;
+-	   	buf_priv->my_use_idx = my_idx;
+-	   	my_idx += 4;
++		buf_priv->in_use = hw_status++;
++		buf_priv->my_use_idx = my_idx;
++		my_idx += 4;
+ 
+-	   	*buf_priv->in_use = I810_BUF_FREE;
++		*buf_priv->in_use = I810_BUF_FREE;
+ 
+ 		buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
+-							buf->total, dev);
++						       buf->total, dev);
+ 	}
+ 	return 0;
+ }
+ 
+-static int i810_dma_initialize(drm_device_t *dev,
+-			       drm_i810_private_t *dev_priv,
+-			       drm_i810_init_t *init)
++static int i810_dma_initialize(drm_device_t * dev,
++			       drm_i810_private_t * dev_priv,
++			       drm_i810_init_t * init)
+ {
+ 	struct list_head *list;
+ 
+-   	memset(dev_priv, 0, sizeof(drm_i810_private_t));
++	memset(dev_priv, 0, sizeof(drm_i810_private_t));
+ 
+ 	list_for_each(list, &dev->maplist->head) {
+ 		drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
+ 		if (r_list->map &&
+ 		    r_list->map->type == _DRM_SHM &&
+-		    r_list->map->flags & _DRM_CONTAINS_LOCK ) {
++		    r_list->map->flags & _DRM_CONTAINS_LOCK) {
+ 			dev_priv->sarea_map = r_list->map;
+- 			break;
+- 		}
+- 	}
++			break;
++		}
++	}
+ 	if (!dev_priv->sarea_map) {
+ 		dev->dev_private = (void *)dev_priv;
+-	   	i810_dma_cleanup(dev);
+-	   	DRM_ERROR("can not find sarea!\n");
+-	   	return -EINVAL;
++		i810_dma_cleanup(dev);
++		DRM_ERROR("can not find sarea!\n");
++		return -EINVAL;
+ 	}
+ 	dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
+ 	if (!dev_priv->mmio_map) {
+ 		dev->dev_private = (void *)dev_priv;
+-	   	i810_dma_cleanup(dev);
+-	   	DRM_ERROR("can not find mmio map!\n");
+-	   	return -EINVAL;
++		i810_dma_cleanup(dev);
++		DRM_ERROR("can not find mmio map!\n");
++		return -EINVAL;
+ 	}
+ 	dev->agp_buffer_token = init->buffers_offset;
+ 	dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+ 	if (!dev->agp_buffer_map) {
+ 		dev->dev_private = (void *)dev_priv;
+-	   	i810_dma_cleanup(dev);
+-	   	DRM_ERROR("can not find dma buffer map!\n");
+-	   	return -EINVAL;
++		i810_dma_cleanup(dev);
++		DRM_ERROR("can not find dma buffer map!\n");
++		return -EINVAL;
+ 	}
+ 
+ 	dev_priv->sarea_priv = (drm_i810_sarea_t *)
+-		((u8 *)dev_priv->sarea_map->handle +
+-		 init->sarea_priv_offset);
++	    ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset);
++
++	dev_priv->ring.Start = init->ring_start;
++	dev_priv->ring.End = init->ring_end;
++	dev_priv->ring.Size = init->ring_size;
++
++	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
++						   init->ring_start,
++						   init->ring_size, dev);
+ 
+-   	dev_priv->ring.Start = init->ring_start;
+-   	dev_priv->ring.End = init->ring_end;
+-   	dev_priv->ring.Size = init->ring_size;
+-
+-   	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
+-						    init->ring_start,
+-						    init->ring_size, dev);
+-
+-   	if (dev_priv->ring.virtual_start == NULL) {
+-		dev->dev_private = (void *) dev_priv;
+-	   	i810_dma_cleanup(dev);
+-	   	DRM_ERROR("can not ioremap virtual address for"
++	if (dev_priv->ring.virtual_start == NULL) {
++		dev->dev_private = (void *)dev_priv;
++		i810_dma_cleanup(dev);
++		DRM_ERROR("can not ioremap virtual address for"
+ 			  " ring buffer\n");
+-	   	return -ENOMEM;
++		return -ENOMEM;
+ 	}
+ 
+-   	dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
++	dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+ 
+ 	dev_priv->w = init->w;
+ 	dev_priv->h = init->h;
+@@ -391,33 +392,33 @@ static int i810_dma_initialize(drm_devic
+ 	dev_priv->back_di1 = init->back_offset | init->pitch_bits;
+ 	dev_priv->zi1 = init->depth_offset | init->pitch_bits;
+ 
+-   	/* Program Hardware Status Page */
+-   	dev_priv->hw_status_page =
+-		pci_alloc_consistent(dev->pdev, PAGE_SIZE,
+-						&dev_priv->dma_status_page);
+-   	if (!dev_priv->hw_status_page) {
++	/* Program Hardware Status Page */
++	dev_priv->hw_status_page =
++	    pci_alloc_consistent(dev->pdev, PAGE_SIZE,
++				 &dev_priv->dma_status_page);
++	if (!dev_priv->hw_status_page) {
+ 		dev->dev_private = (void *)dev_priv;
+ 		i810_dma_cleanup(dev);
+ 		DRM_ERROR("Can not allocate hardware status page\n");
+ 		return -ENOMEM;
+ 	}
+-   	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+-   	DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
++	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
++	DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
+ 
+ 	I810_WRITE(0x02080, dev_priv->dma_status_page);
+-   	DRM_DEBUG("Enabled hardware status page\n");
++	DRM_DEBUG("Enabled hardware status page\n");
+ 
+-   	/* Now we need to init our freelist */
++	/* Now we need to init our freelist */
+ 	if (i810_freelist_init(dev, dev_priv) != 0) {
+ 		dev->dev_private = (void *)dev_priv;
+-	   	i810_dma_cleanup(dev);
+-	   	DRM_ERROR("Not enough space in the status page for"
++		i810_dma_cleanup(dev);
++		DRM_ERROR("Not enough space in the status page for"
+ 			  " the freelist\n");
+-	   	return -ENOMEM;
++		return -ENOMEM;
+ 	}
+ 	dev->dev_private = (void *)dev_priv;
+ 
+-   	return 0;
++	return 0;
+ }
+ 
+ /* i810 DRM version 1.1 used a smaller init structure with different
+@@ -431,12 +432,12 @@ static int i810_dma_initialize(drm_devic
+  *    If it isn't then we have a v1.1 client. Fix up params.
+  *    If it is, then we have a 1.2 client... get the rest of the data.
+  */
+-static int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg)
++static int i810_dma_init_compat(drm_i810_init_t * init, unsigned long arg)
+ {
+ 
+ 	/* Get v1.1 init data */
+-	if (copy_from_user(init, (drm_i810_pre12_init_t __user *)arg,
+-			  sizeof(drm_i810_pre12_init_t))) {
++	if (copy_from_user(init, (drm_i810_pre12_init_t __user *) arg,
++			   sizeof(drm_i810_pre12_init_t))) {
+ 		return -EFAULT;
+ 	}
+ 
+@@ -444,7 +445,7 @@ static int i810_dma_init_compat(drm_i810
+ 
+ 		/* This is a v1.2 client, just get the v1.2 init data */
+ 		DRM_INFO("Using POST v1.2 init.\n");
+-		if (copy_from_user(init, (drm_i810_init_t __user *)arg,
++		if (copy_from_user(init, (drm_i810_init_t __user *) arg,
+ 				   sizeof(drm_i810_init_t))) {
+ 			return -EFAULT;
+ 		}
+@@ -452,246 +453,239 @@ static int i810_dma_init_compat(drm_i810
+ 
+ 		/* This is a v1.1 client, fix the params */
+ 		DRM_INFO("Using PRE v1.2 init.\n");
+-	 	init->pitch_bits = init->h;
+-	 	init->pitch = init->w;
+-	 	init->h = init->overlay_physical;
+-	 	init->w = init->overlay_offset;
+-	 	init->overlay_physical = 0;
+-	 	init->overlay_offset = 0;
++		init->pitch_bits = init->h;
++		init->pitch = init->w;
++		init->h = init->overlay_physical;
++		init->w = init->overlay_offset;
++		init->overlay_physical = 0;
++		init->overlay_offset = 0;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static int i810_dma_init(struct inode *inode, struct file *filp,
+-		  unsigned int cmd, unsigned long arg)
++			 unsigned int cmd, unsigned long arg)
+ {
+-   	drm_file_t *priv = filp->private_data;
+-   	drm_device_t *dev = priv->head->dev;
+-   	drm_i810_private_t *dev_priv;
+-   	drm_i810_init_t init;
+-   	int retcode = 0;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_i810_private_t *dev_priv;
++	drm_i810_init_t init;
++	int retcode = 0;
+ 
+ 	/* Get only the init func */
+-	if (copy_from_user(&init, (void __user *)arg, sizeof(drm_i810_init_func_t))) 
++	if (copy_from_user
++	    (&init, (void __user *)arg, sizeof(drm_i810_init_func_t)))
+ 		return -EFAULT;
+ 
+-   	switch(init.func) {
+-	 	case I810_INIT_DMA:
+-	 	       	/* This case is for backward compatibility. It
+-			 * handles XFree 4.1.0 and 4.2.0, and has to
+-			 * do some parameter checking as described below.
+-			 * It will someday go away.
+-			 */
+-			retcode = i810_dma_init_compat(&init, arg);
+-			if (retcode)
+-				return retcode;
+-
+-	   		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
+-					     DRM_MEM_DRIVER);
+-	   		if (dev_priv == NULL)
+-				return -ENOMEM;
+-	   		retcode = i810_dma_initialize(dev, dev_priv, &init);
+-			break;
+-
+-		default:
+-	 	case I810_INIT_DMA_1_4:
+-			DRM_INFO("Using v1.4 init.\n");
+-  			if (copy_from_user(&init, (drm_i810_init_t __user *)arg,
+-					  sizeof(drm_i810_init_t))) {
+-				return -EFAULT;
+-			}
+-	   		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
+-					     DRM_MEM_DRIVER);
+-			if (dev_priv == NULL) 
+-				return -ENOMEM;
+-	   		retcode = i810_dma_initialize(dev, dev_priv, &init);
+-			break;
+-
+-	 	case I810_CLEANUP_DMA:
+-		        DRM_INFO("DMA Cleanup\n");
+-	   		retcode = i810_dma_cleanup(dev);
+-              	   	break;
++	switch (init.func) {
++	case I810_INIT_DMA:
++		/* This case is for backward compatibility. It
++		 * handles XFree 4.1.0 and 4.2.0, and has to
++		 * do some parameter checking as described below.
++		 * It will someday go away.
++		 */
++		retcode = i810_dma_init_compat(&init, arg);
++		if (retcode)
++			return retcode;
++
++		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
++				     DRM_MEM_DRIVER);
++		if (dev_priv == NULL)
++			return -ENOMEM;
++		retcode = i810_dma_initialize(dev, dev_priv, &init);
++		break;
++
++	default:
++	case I810_INIT_DMA_1_4:
++		DRM_INFO("Using v1.4 init.\n");
++		if (copy_from_user(&init, (drm_i810_init_t __user *) arg,
++				   sizeof(drm_i810_init_t))) {
++			return -EFAULT;
++		}
++		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
++				     DRM_MEM_DRIVER);
++		if (dev_priv == NULL)
++			return -ENOMEM;
++		retcode = i810_dma_initialize(dev, dev_priv, &init);
++		break;
++
++	case I810_CLEANUP_DMA:
++		DRM_INFO("DMA Cleanup\n");
++		retcode = i810_dma_cleanup(dev);
++		break;
+ 	}
+ 
+-   	return retcode;
++	return retcode;
+ }
+ 
+-
+-
+ /* Most efficient way to verify state for the i810 is as it is
+  * emitted.  Non-conformant state is silently dropped.
+  *
+  * Use 'volatile' & local var tmp to force the emitted values to be
+  * identical to the verified ones.
+  */
+-static void i810EmitContextVerified( drm_device_t *dev,
+-				     volatile unsigned int *code )
++static void i810EmitContextVerified(drm_device_t * dev,
++				    volatile unsigned int *code)
+ {
+-   	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_private_t *dev_priv = dev->dev_private;
+ 	int i, j = 0;
+ 	unsigned int tmp;
+ 	RING_LOCALS;
+ 
+-	BEGIN_LP_RING( I810_CTX_SETUP_SIZE );
++	BEGIN_LP_RING(I810_CTX_SETUP_SIZE);
+ 
+-	OUT_RING( GFX_OP_COLOR_FACTOR );
+-	OUT_RING( code[I810_CTXREG_CF1] );
++	OUT_RING(GFX_OP_COLOR_FACTOR);
++	OUT_RING(code[I810_CTXREG_CF1]);
+ 
+-	OUT_RING( GFX_OP_STIPPLE );
+-	OUT_RING( code[I810_CTXREG_ST1] );
++	OUT_RING(GFX_OP_STIPPLE);
++	OUT_RING(code[I810_CTXREG_ST1]);
+ 
+-	for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) {
++	for (i = 4; i < I810_CTX_SETUP_SIZE; i++) {
+ 		tmp = code[i];
+ 
+-		if ((tmp & (7<<29)) == (3<<29) &&
+-		    (tmp & (0x1f<<24)) < (0x1d<<24))
+-		{
+-			OUT_RING( tmp );
++		if ((tmp & (7 << 29)) == (3 << 29) &&
++		    (tmp & (0x1f << 24)) < (0x1d << 24)) {
++			OUT_RING(tmp);
+ 			j++;
+-		}
+-		else printk("constext state dropped!!!\n");
++		} else
++			printk("constext state dropped!!!\n");
+ 	}
+ 
+ 	if (j & 1)
+-		OUT_RING( 0 );
++		OUT_RING(0);
+ 
+ 	ADVANCE_LP_RING();
+ }
+ 
+-static void i810EmitTexVerified( drm_device_t *dev,
+-				 volatile unsigned int *code )
++static void i810EmitTexVerified(drm_device_t * dev, volatile unsigned int *code)
+ {
+-   	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_private_t *dev_priv = dev->dev_private;
+ 	int i, j = 0;
+ 	unsigned int tmp;
+ 	RING_LOCALS;
+ 
+-	BEGIN_LP_RING( I810_TEX_SETUP_SIZE );
++	BEGIN_LP_RING(I810_TEX_SETUP_SIZE);
+ 
+-	OUT_RING( GFX_OP_MAP_INFO );
+-	OUT_RING( code[I810_TEXREG_MI1] );
+-	OUT_RING( code[I810_TEXREG_MI2] );
+-	OUT_RING( code[I810_TEXREG_MI3] );
++	OUT_RING(GFX_OP_MAP_INFO);
++	OUT_RING(code[I810_TEXREG_MI1]);
++	OUT_RING(code[I810_TEXREG_MI2]);
++	OUT_RING(code[I810_TEXREG_MI3]);
+ 
+-	for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) {
++	for (i = 4; i < I810_TEX_SETUP_SIZE; i++) {
+ 		tmp = code[i];
+ 
+-		if ((tmp & (7<<29)) == (3<<29) &&
+-		    (tmp & (0x1f<<24)) < (0x1d<<24))
+-		{
+-			OUT_RING( tmp );
++		if ((tmp & (7 << 29)) == (3 << 29) &&
++		    (tmp & (0x1f << 24)) < (0x1d << 24)) {
++			OUT_RING(tmp);
+ 			j++;
+-		}
+-		else printk("texture state dropped!!!\n");
++		} else
++			printk("texture state dropped!!!\n");
+ 	}
+ 
+ 	if (j & 1)
+-		OUT_RING( 0 );
++		OUT_RING(0);
+ 
+ 	ADVANCE_LP_RING();
+ }
+ 
+-
+ /* Need to do some additional checking when setting the dest buffer.
+  */
+-static void i810EmitDestVerified( drm_device_t *dev,
+-				  volatile unsigned int *code )
++static void i810EmitDestVerified(drm_device_t * dev,
++				 volatile unsigned int *code)
+ {
+-   	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_private_t *dev_priv = dev->dev_private;
+ 	unsigned int tmp;
+ 	RING_LOCALS;
+ 
+-	BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 );
++	BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2);
+ 
+ 	tmp = code[I810_DESTREG_DI1];
+ 	if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
+-		OUT_RING( CMD_OP_DESTBUFFER_INFO );
+-		OUT_RING( tmp );
++		OUT_RING(CMD_OP_DESTBUFFER_INFO);
++		OUT_RING(tmp);
+ 	} else
+-	   DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
+-		     tmp, dev_priv->front_di1, dev_priv->back_di1);
++		DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
++			  tmp, dev_priv->front_di1, dev_priv->back_di1);
+ 
+ 	/* invarient:
+ 	 */
+-	OUT_RING( CMD_OP_Z_BUFFER_INFO );
+-	OUT_RING( dev_priv->zi1 );
++	OUT_RING(CMD_OP_Z_BUFFER_INFO);
++	OUT_RING(dev_priv->zi1);
+ 
+-	OUT_RING( GFX_OP_DESTBUFFER_VARS );
+-	OUT_RING( code[I810_DESTREG_DV1] );
++	OUT_RING(GFX_OP_DESTBUFFER_VARS);
++	OUT_RING(code[I810_DESTREG_DV1]);
+ 
+-	OUT_RING( GFX_OP_DRAWRECT_INFO );
+-	OUT_RING( code[I810_DESTREG_DR1] );
+-	OUT_RING( code[I810_DESTREG_DR2] );
+-	OUT_RING( code[I810_DESTREG_DR3] );
+-	OUT_RING( code[I810_DESTREG_DR4] );
+-	OUT_RING( 0 );
++	OUT_RING(GFX_OP_DRAWRECT_INFO);
++	OUT_RING(code[I810_DESTREG_DR1]);
++	OUT_RING(code[I810_DESTREG_DR2]);
++	OUT_RING(code[I810_DESTREG_DR3]);
++	OUT_RING(code[I810_DESTREG_DR4]);
++	OUT_RING(0);
+ 
+ 	ADVANCE_LP_RING();
+ }
+ 
+-
+-
+-static void i810EmitState( drm_device_t *dev )
++static void i810EmitState(drm_device_t * dev)
+ {
+-   	drm_i810_private_t *dev_priv = dev->dev_private;
+-      	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
++	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	unsigned int dirty = sarea_priv->dirty;
+-	
++
+ 	DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);
+ 
+ 	if (dirty & I810_UPLOAD_BUFFERS) {
+-		i810EmitDestVerified( dev, sarea_priv->BufferState );
++		i810EmitDestVerified(dev, sarea_priv->BufferState);
+ 		sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
+ 	}
+ 
+ 	if (dirty & I810_UPLOAD_CTX) {
+-		i810EmitContextVerified( dev, sarea_priv->ContextState );
++		i810EmitContextVerified(dev, sarea_priv->ContextState);
+ 		sarea_priv->dirty &= ~I810_UPLOAD_CTX;
+ 	}
+ 
+ 	if (dirty & I810_UPLOAD_TEX0) {
+-		i810EmitTexVerified( dev, sarea_priv->TexState[0] );
++		i810EmitTexVerified(dev, sarea_priv->TexState[0]);
+ 		sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
+ 	}
+ 
+ 	if (dirty & I810_UPLOAD_TEX1) {
+-		i810EmitTexVerified( dev, sarea_priv->TexState[1] );
++		i810EmitTexVerified(dev, sarea_priv->TexState[1]);
+ 		sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
+ 	}
+ }
+ 
+-
+-
+ /* need to verify
+  */
+-static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
+-				     unsigned int clear_color,
+-				     unsigned int clear_zval )
++static void i810_dma_dispatch_clear(drm_device_t * dev, int flags,
++				    unsigned int clear_color,
++				    unsigned int clear_zval)
+ {
+-   	drm_i810_private_t *dev_priv = dev->dev_private;
+-      	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
++	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	int nbox = sarea_priv->nbox;
+ 	drm_clip_rect_t *pbox = sarea_priv->boxes;
+ 	int pitch = dev_priv->pitch;
+ 	int cpp = 2;
+ 	int i;
+ 	RING_LOCALS;
+-	
+-	if ( dev_priv->current_page == 1 ) {
+-	        unsigned int tmp = flags;
+-	       
++
++	if (dev_priv->current_page == 1) {
++		unsigned int tmp = flags;
++
+ 		flags &= ~(I810_FRONT | I810_BACK);
+-		if (tmp & I810_FRONT) flags |= I810_BACK;
+-		if (tmp & I810_BACK) flags |= I810_FRONT;
++		if (tmp & I810_FRONT)
++			flags |= I810_BACK;
++		if (tmp & I810_BACK)
++			flags |= I810_FRONT;
+ 	}
+ 
+-  	i810_kernel_lost_context(dev);
++	i810_kernel_lost_context(dev);
+ 
+-      	if (nbox > I810_NR_SAREA_CLIPRECTS)
+-     		nbox = I810_NR_SAREA_CLIPRECTS;
++	if (nbox > I810_NR_SAREA_CLIPRECTS)
++		nbox = I810_NR_SAREA_CLIPRECTS;
+ 
+-	for (i = 0 ; i < nbox ; i++, pbox++) {
++	for (i = 0; i < nbox; i++, pbox++) {
+ 		unsigned int x = pbox->x1;
+ 		unsigned int y = pbox->y1;
+ 		unsigned int width = (pbox->x2 - x) * cpp;
+@@ -700,52 +694,48 @@ static void i810_dma_dispatch_clear( drm
+ 
+ 		if (pbox->x1 > pbox->x2 ||
+ 		    pbox->y1 > pbox->y2 ||
+-		    pbox->x2 > dev_priv->w ||
+-		    pbox->y2 > dev_priv->h)
++		    pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
+ 			continue;
+ 
+-	   	if ( flags & I810_FRONT ) {
+-			BEGIN_LP_RING( 6 );
+-			OUT_RING( BR00_BITBLT_CLIENT |
+-				  BR00_OP_COLOR_BLT | 0x3 );
+-			OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
+-			OUT_RING( (height << 16) | width );
+-			OUT_RING( start );
+-			OUT_RING( clear_color );
+-			OUT_RING( 0 );
++		if (flags & I810_FRONT) {
++			BEGIN_LP_RING(6);
++			OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
++			OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
++			OUT_RING((height << 16) | width);
++			OUT_RING(start);
++			OUT_RING(clear_color);
++			OUT_RING(0);
+ 			ADVANCE_LP_RING();
+ 		}
+ 
+-		if ( flags & I810_BACK ) {
+-			BEGIN_LP_RING( 6 );
+-			OUT_RING( BR00_BITBLT_CLIENT |
+-				  BR00_OP_COLOR_BLT | 0x3 );
+-			OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
+-			OUT_RING( (height << 16) | width );
+-			OUT_RING( dev_priv->back_offset + start );
+-			OUT_RING( clear_color );
+-			OUT_RING( 0 );
++		if (flags & I810_BACK) {
++			BEGIN_LP_RING(6);
++			OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
++			OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
++			OUT_RING((height << 16) | width);
++			OUT_RING(dev_priv->back_offset + start);
++			OUT_RING(clear_color);
++			OUT_RING(0);
+ 			ADVANCE_LP_RING();
+ 		}
+ 
+-		if ( flags & I810_DEPTH ) {
+-			BEGIN_LP_RING( 6 );
+-			OUT_RING( BR00_BITBLT_CLIENT |
+-				  BR00_OP_COLOR_BLT | 0x3 );
+-			OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
+-			OUT_RING( (height << 16) | width );
+-			OUT_RING( dev_priv->depth_offset + start );
+-			OUT_RING( clear_zval );
+-			OUT_RING( 0 );
++		if (flags & I810_DEPTH) {
++			BEGIN_LP_RING(6);
++			OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
++			OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
++			OUT_RING((height << 16) | width);
++			OUT_RING(dev_priv->depth_offset + start);
++			OUT_RING(clear_zval);
++			OUT_RING(0);
+ 			ADVANCE_LP_RING();
+ 		}
+ 	}
+ }
+ 
+-static void i810_dma_dispatch_swap( drm_device_t *dev )
++static void i810_dma_dispatch_swap(drm_device_t * dev)
+ {
+-   	drm_i810_private_t *dev_priv = dev->dev_private;
+-      	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
++	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	int nbox = sarea_priv->nbox;
+ 	drm_clip_rect_t *pbox = sarea_priv->boxes;
+ 	int pitch = dev_priv->pitch;
+@@ -755,75 +745,71 @@ static void i810_dma_dispatch_swap( drm_
+ 
+ 	DRM_DEBUG("swapbuffers\n");
+ 
+-  	i810_kernel_lost_context(dev);
++	i810_kernel_lost_context(dev);
+ 
+-      	if (nbox > I810_NR_SAREA_CLIPRECTS)
+-     		nbox = I810_NR_SAREA_CLIPRECTS;
++	if (nbox > I810_NR_SAREA_CLIPRECTS)
++		nbox = I810_NR_SAREA_CLIPRECTS;
+ 
+-	for (i = 0 ; i < nbox; i++, pbox++)
+-	{
++	for (i = 0; i < nbox; i++, pbox++) {
+ 		unsigned int w = pbox->x2 - pbox->x1;
+ 		unsigned int h = pbox->y2 - pbox->y1;
+-		unsigned int dst = pbox->x1*cpp + pbox->y1*pitch;
++		unsigned int dst = pbox->x1 * cpp + pbox->y1 * pitch;
+ 		unsigned int start = dst;
+ 
+ 		if (pbox->x1 > pbox->x2 ||
+ 		    pbox->y1 > pbox->y2 ||
+-		    pbox->x2 > dev_priv->w ||
+-		    pbox->y2 > dev_priv->h)
++		    pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
+ 			continue;
+ 
+-		BEGIN_LP_RING( 6 );
+-		OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
+-		OUT_RING( pitch | (0xCC << 16));
+-		OUT_RING( (h << 16) | (w * cpp));
++		BEGIN_LP_RING(6);
++		OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4);
++		OUT_RING(pitch | (0xCC << 16));
++		OUT_RING((h << 16) | (w * cpp));
+ 		if (dev_priv->current_page == 0)
+-		  OUT_RING(dev_priv->front_offset + start);
++			OUT_RING(dev_priv->front_offset + start);
+ 		else
+-		  OUT_RING(dev_priv->back_offset + start);
+-		OUT_RING( pitch );
++			OUT_RING(dev_priv->back_offset + start);
++		OUT_RING(pitch);
+ 		if (dev_priv->current_page == 0)
+-		  OUT_RING(dev_priv->back_offset + start);
++			OUT_RING(dev_priv->back_offset + start);
+ 		else
+-		  OUT_RING(dev_priv->front_offset + start);
++			OUT_RING(dev_priv->front_offset + start);
+ 		ADVANCE_LP_RING();
+ 	}
+ }
+ 
+-
+-static void i810_dma_dispatch_vertex(drm_device_t *dev,
+-				     drm_buf_t *buf,
+-				     int discard,
+-				     int used)
++static void i810_dma_dispatch_vertex(drm_device_t * dev,
++				     drm_buf_t * buf, int discard, int used)
+ {
+-   	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_private_t *dev_priv = dev->dev_private;
+ 	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+-   	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+-   	drm_clip_rect_t *box = sarea_priv->boxes;
+-   	int nbox = sarea_priv->nbox;
++	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
++	drm_clip_rect_t *box = sarea_priv->boxes;
++	int nbox = sarea_priv->nbox;
+ 	unsigned long address = (unsigned long)buf->bus_address;
+ 	unsigned long start = address - dev->agp->base;
+ 	int i = 0;
+-   	RING_LOCALS;
++	RING_LOCALS;
+ 
+-   	i810_kernel_lost_context(dev);
++	i810_kernel_lost_context(dev);
+ 
+-   	if (nbox > I810_NR_SAREA_CLIPRECTS)
++	if (nbox > I810_NR_SAREA_CLIPRECTS)
+ 		nbox = I810_NR_SAREA_CLIPRECTS;
+ 
+-	if (used > 4*1024)
++	if (used > 4 * 1024)
+ 		used = 0;
+ 
+ 	if (sarea_priv->dirty)
+-	   i810EmitState( dev );
++		i810EmitState(dev);
+ 
+ 	if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
+ 		unsigned int prim = (sarea_priv->vertex_prim & PR_MASK);
+ 
+-		*(u32 *)buf_priv->kernel_virtual = ((GFX_OP_PRIMITIVE | prim | ((used/4)-2)));
++		*(u32 *) buf_priv->kernel_virtual =
++		    ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2)));
+ 
+ 		if (used & 4) {
+-			*(u32 *)((u32)buf_priv->kernel_virtual + used) = 0;
++			*(u32 *) ((u32) buf_priv->kernel_virtual + used) = 0;
+ 			used += 4;
+ 		}
+ 
+@@ -834,19 +820,20 @@ static void i810_dma_dispatch_vertex(drm
+ 		do {
+ 			if (i < nbox) {
+ 				BEGIN_LP_RING(4);
+-				OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
+-					  SC_ENABLE );
+-				OUT_RING( GFX_OP_SCISSOR_INFO );
+-				OUT_RING( box[i].x1 | (box[i].y1<<16) );
+-				OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) );
++				OUT_RING(GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
++					 SC_ENABLE);
++				OUT_RING(GFX_OP_SCISSOR_INFO);
++				OUT_RING(box[i].x1 | (box[i].y1 << 16));
++				OUT_RING((box[i].x2 -
++					  1) | ((box[i].y2 - 1) << 16));
+ 				ADVANCE_LP_RING();
+ 			}
+ 
+ 			BEGIN_LP_RING(4);
+-			OUT_RING( CMD_OP_BATCH_BUFFER );
+-			OUT_RING( start | BB1_PROTECTED );
+-			OUT_RING( start + used - 4 );
+-			OUT_RING( 0 );
++			OUT_RING(CMD_OP_BATCH_BUFFER);
++			OUT_RING(start | BB1_PROTECTED);
++			OUT_RING(start + used - 4);
++			OUT_RING(0);
+ 			ADVANCE_LP_RING();
+ 
+ 		} while (++i < nbox);
+@@ -855,59 +842,59 @@ static void i810_dma_dispatch_vertex(drm
+ 	if (discard) {
+ 		dev_priv->counter++;
+ 
+-		(void) cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
+-			       I810_BUF_HARDWARE);
++		(void)cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
++			      I810_BUF_HARDWARE);
+ 
+ 		BEGIN_LP_RING(8);
+-		OUT_RING( CMD_STORE_DWORD_IDX );
+-		OUT_RING( 20 );
+-		OUT_RING( dev_priv->counter );
+-		OUT_RING( CMD_STORE_DWORD_IDX );
+-		OUT_RING( buf_priv->my_use_idx );
+-		OUT_RING( I810_BUF_FREE );
+-		OUT_RING( CMD_REPORT_HEAD );
+-		OUT_RING( 0 );
++		OUT_RING(CMD_STORE_DWORD_IDX);
++		OUT_RING(20);
++		OUT_RING(dev_priv->counter);
++		OUT_RING(CMD_STORE_DWORD_IDX);
++		OUT_RING(buf_priv->my_use_idx);
++		OUT_RING(I810_BUF_FREE);
++		OUT_RING(CMD_REPORT_HEAD);
++		OUT_RING(0);
+ 		ADVANCE_LP_RING();
+ 	}
+ }
+ 
+-static void i810_dma_dispatch_flip( drm_device_t *dev )
++static void i810_dma_dispatch_flip(drm_device_t * dev)
+ {
+-        drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_private_t *dev_priv = dev->dev_private;
+ 	int pitch = dev_priv->pitch;
+ 	RING_LOCALS;
+ 
+-	DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", 
+-		__FUNCTION__, 
+-		dev_priv->current_page,
+-		dev_priv->sarea_priv->pf_current_page);
+-	
+-        i810_kernel_lost_context(dev);
+-
+-	BEGIN_LP_RING( 2 );
+-   	OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); 
+-	OUT_RING( 0 );
++	DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
++		  __FUNCTION__,
++		  dev_priv->current_page,
++		  dev_priv->sarea_priv->pf_current_page);
++
++	i810_kernel_lost_context(dev);
++
++	BEGIN_LP_RING(2);
++	OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
++	OUT_RING(0);
+ 	ADVANCE_LP_RING();
+ 
+-	BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 );
++	BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2);
+ 	/* On i815 at least ASYNC is buggy */
+ 	/* pitch<<5 is from 11.2.8 p158,
+ 	   its the pitch / 8 then left shifted 8,
+ 	   so (pitch >> 3) << 8 */
+-	OUT_RING( CMD_OP_FRONTBUFFER_INFO | (pitch<<5) /*| ASYNC_FLIP */ );
+-	if ( dev_priv->current_page == 0 ) {
+-		OUT_RING( dev_priv->back_offset );
++	OUT_RING(CMD_OP_FRONTBUFFER_INFO | (pitch << 5) /*| ASYNC_FLIP */ );
++	if (dev_priv->current_page == 0) {
++		OUT_RING(dev_priv->back_offset);
+ 		dev_priv->current_page = 1;
+ 	} else {
+-		OUT_RING( dev_priv->front_offset );
++		OUT_RING(dev_priv->front_offset);
+ 		dev_priv->current_page = 0;
+ 	}
+ 	OUT_RING(0);
+ 	ADVANCE_LP_RING();
+ 
+ 	BEGIN_LP_RING(2);
+-	OUT_RING( CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP );
+-	OUT_RING( 0 );
++	OUT_RING(CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP);
++	OUT_RING(0);
+ 	ADVANCE_LP_RING();
+ 
+ 	/* Increment the frame counter.  The client-side 3D driver must
+@@ -918,46 +905,46 @@ static void i810_dma_dispatch_flip( drm_
+ 
+ }
+ 
+-static void i810_dma_quiescent(drm_device_t *dev)
++static void i810_dma_quiescent(drm_device_t * dev)
+ {
+-      	drm_i810_private_t *dev_priv = dev->dev_private;
+-   	RING_LOCALS;
++	drm_i810_private_t *dev_priv = dev->dev_private;
++	RING_LOCALS;
+ 
+ /*  	printk("%s\n", __FUNCTION__); */
+ 
+-  	i810_kernel_lost_context(dev);
++	i810_kernel_lost_context(dev);
+ 
+-   	BEGIN_LP_RING(4);
+-   	OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
+-   	OUT_RING( CMD_REPORT_HEAD );
+-      	OUT_RING( 0 );
+-      	OUT_RING( 0 );
+-   	ADVANCE_LP_RING();
++	BEGIN_LP_RING(4);
++	OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
++	OUT_RING(CMD_REPORT_HEAD);
++	OUT_RING(0);
++	OUT_RING(0);
++	ADVANCE_LP_RING();
+ 
+-	i810_wait_ring( dev, dev_priv->ring.Size - 8 );
++	i810_wait_ring(dev, dev_priv->ring.Size - 8);
+ }
+ 
+-static int i810_flush_queue(drm_device_t *dev)
++static int i810_flush_queue(drm_device_t * dev)
+ {
+-   	drm_i810_private_t *dev_priv = dev->dev_private;
++	drm_i810_private_t *dev_priv = dev->dev_private;
+ 	drm_device_dma_t *dma = dev->dma;
+-   	int i, ret = 0;
+-   	RING_LOCALS;
+-	
++	int i, ret = 0;
++	RING_LOCALS;
++
+ /*  	printk("%s\n", __FUNCTION__); */
+ 
+-   	i810_kernel_lost_context(dev);
++	i810_kernel_lost_context(dev);
++
++	BEGIN_LP_RING(2);
++	OUT_RING(CMD_REPORT_HEAD);
++	OUT_RING(0);
++	ADVANCE_LP_RING();
++
++	i810_wait_ring(dev, dev_priv->ring.Size - 8);
+ 
+-   	BEGIN_LP_RING(2);
+-      	OUT_RING( CMD_REPORT_HEAD );
+-      	OUT_RING( 0 );
+-      	ADVANCE_LP_RING();
+-
+-	i810_wait_ring( dev, dev_priv->ring.Size - 8 );
+-
+-   	for (i = 0; i < dma->buf_count; i++) {
+-	   	drm_buf_t *buf = dma->buflist[ i ];
+-	   	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
++	for (i = 0; i < dma->buf_count; i++) {
++		drm_buf_t *buf = dma->buflist[i];
++		drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ 
+ 		int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE,
+ 				   I810_BUF_FREE);
+@@ -968,24 +955,27 @@ static int i810_flush_queue(drm_device_t
+ 			DRM_DEBUG("still on client\n");
+ 	}
+ 
+-   	return ret;
++	return ret;
+ }
+ 
+ /* Must be called with the lock held */
+-void i810_reclaim_buffers(drm_device_t *dev, struct file *filp)
++void i810_reclaim_buffers(drm_device_t * dev, struct file *filp)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+-	int		 i;
++	int i;
+ 
+-	if (!dma) return;
+-      	if (!dev->dev_private) return;
+-	if (!dma->buflist) return;
++	if (!dma)
++		return;
++	if (!dev->dev_private)
++		return;
++	if (!dma->buflist)
++		return;
+ 
+-        i810_flush_queue(dev);
++	i810_flush_queue(dev);
+ 
+ 	for (i = 0; i < dma->buf_count; i++) {
+-	   	drm_buf_t *buf = dma->buflist[ i ];
+-	   	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
++		drm_buf_t *buf = dma->buflist[i];
++		drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ 
+ 		if (buf->filp == filp && buf_priv) {
+ 			int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
+@@ -994,7 +984,7 @@ void i810_reclaim_buffers(drm_device_t *
+ 			if (used == I810_BUF_CLIENT)
+ 				DRM_DEBUG("reclaimed from client\n");
+ 			if (buf_priv->currently_mapped == I810_BUF_MAPPED)
+-		     		buf_priv->currently_mapped = I810_BUF_UNMAPPED;
++				buf_priv->currently_mapped = I810_BUF_UNMAPPED;
+ 		}
+ 	}
+ }
+@@ -1002,29 +992,29 @@ void i810_reclaim_buffers(drm_device_t *
+ static int i810_flush_ioctl(struct inode *inode, struct file *filp,
+ 			    unsigned int cmd, unsigned long arg)
+ {
+-   	drm_file_t	  *priv	  = filp->private_data;
+-   	drm_device_t	  *dev	  = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-   	i810_flush_queue(dev);
+-   	return 0;
++	i810_flush_queue(dev);
++	return 0;
+ }
+ 
+-
+ static int i810_dma_vertex(struct inode *inode, struct file *filp,
+-	       unsigned int cmd, unsigned long arg)
++			   unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_device_dma_t *dma = dev->dma;
+-   	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+-      	u32 *hw_status = dev_priv->hw_status_page;
+-   	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+-     					dev_priv->sarea_priv;
++	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
++	u32 *hw_status = dev_priv->hw_status_page;
++	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
++	    dev_priv->sarea_priv;
+ 	drm_i810_vertex_t vertex;
+ 
+-	if (copy_from_user(&vertex, (drm_i810_vertex_t __user *)arg, sizeof(vertex)))
++	if (copy_from_user
++	    (&vertex, (drm_i810_vertex_t __user *) arg, sizeof(vertex)))
+ 		return -EFAULT;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+@@ -1032,48 +1022,46 @@ static int i810_dma_vertex(struct inode 
+ 	DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
+ 		  vertex.idx, vertex.used, vertex.discard);
+ 
+-	if (vertex.idx < 0 || vertex.idx > dma->buf_count) 
++	if (vertex.idx < 0 || vertex.idx > dma->buf_count)
+ 		return -EINVAL;
+ 
+-	i810_dma_dispatch_vertex( dev,
+-				  dma->buflist[ vertex.idx ],
+-				  vertex.discard, vertex.used );
++	i810_dma_dispatch_vertex(dev,
++				 dma->buflist[vertex.idx],
++				 vertex.discard, vertex.used);
+ 
+-   	atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
++	atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
+ 	atomic_inc(&dev->counts[_DRM_STAT_DMA]);
+-	sarea_priv->last_enqueue = dev_priv->counter-1;
+-   	sarea_priv->last_dispatch = (int) hw_status[5];
++	sarea_priv->last_enqueue = dev_priv->counter - 1;
++	sarea_priv->last_dispatch = (int)hw_status[5];
+ 
+ 	return 0;
+ }
+ 
+-
+-
+ static int i810_clear_bufs(struct inode *inode, struct file *filp,
+-		   unsigned int cmd, unsigned long arg)
++			   unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_i810_clear_t clear;
+ 
+-   	if (copy_from_user(&clear, (drm_i810_clear_t __user *)arg, sizeof(clear)))
++	if (copy_from_user
++	    (&clear, (drm_i810_clear_t __user *) arg, sizeof(clear)))
+ 		return -EFAULT;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+- 	/* GH: Someone's doing nasty things... */
+- 	if (!dev->dev_private) {
+- 		return -EINVAL;
+- 	}
+-
+-	i810_dma_dispatch_clear( dev, clear.flags,
+-				 clear.clear_color,
+-				 clear.clear_depth );
+-   	return 0;
++	/* GH: Someone's doing nasty things... */
++	if (!dev->dev_private) {
++		return -EINVAL;
++	}
++
++	i810_dma_dispatch_clear(dev, clear.flags,
++				clear.clear_color, clear.clear_depth);
++	return 0;
+ }
+ 
+ static int i810_swap_bufs(struct inode *inode, struct file *filp,
+-		  unsigned int cmd, unsigned long arg)
++			  unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -1082,37 +1070,37 @@ static int i810_swap_bufs(struct inode *
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	i810_dma_dispatch_swap( dev );
+-   	return 0;
++	i810_dma_dispatch_swap(dev);
++	return 0;
+ }
+ 
+ static int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
+-		unsigned long arg)
++		       unsigned long arg)
+ {
+-   	drm_file_t	  *priv	    = filp->private_data;
+-	drm_device_t	  *dev	    = priv->head->dev;
+-   	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+-      	u32 *hw_status = dev_priv->hw_status_page;
+-   	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+-     					dev_priv->sarea_priv;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
++	u32 *hw_status = dev_priv->hw_status_page;
++	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
++	    dev_priv->sarea_priv;
+ 
+-      	sarea_priv->last_dispatch = (int) hw_status[5];
++	sarea_priv->last_dispatch = (int)hw_status[5];
+ 	return 0;
+ }
+ 
+ static int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
+-		unsigned long arg)
++		       unsigned long arg)
+ {
+-	drm_file_t	  *priv	    = filp->private_data;
+-	drm_device_t	  *dev	    = priv->head->dev;
+-	int		  retcode   = 0;
+-	drm_i810_dma_t	  d;
+-   	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+-   	u32 *hw_status = dev_priv->hw_status_page;
+-   	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+-     					dev_priv->sarea_priv;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	int retcode = 0;
++	drm_i810_dma_t d;
++	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
++	u32 *hw_status = dev_priv->hw_status_page;
++	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
++	    dev_priv->sarea_priv;
+ 
+-   	if (copy_from_user(&d, (drm_i810_dma_t __user *)arg, sizeof(d)))
++	if (copy_from_user(&d, (drm_i810_dma_t __user *) arg, sizeof(d)))
+ 		return -EFAULT;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+@@ -1124,29 +1112,29 @@ static int i810_getbuf(struct inode *ino
+ 	DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
+ 		  current->pid, retcode, d.granted);
+ 
+-	if (copy_to_user((drm_dma_t __user *)arg, &d, sizeof(d)))
++	if (copy_to_user((drm_dma_t __user *) arg, &d, sizeof(d)))
+ 		return -EFAULT;
+-   	sarea_priv->last_dispatch = (int) hw_status[5];
++	sarea_priv->last_dispatch = (int)hw_status[5];
+ 
+ 	return retcode;
+ }
+ 
+ static int i810_copybuf(struct inode *inode,
+-			 struct file *filp, unsigned int cmd, unsigned long arg)
++			struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ 	/* Never copy - 2.4.x doesn't need it */
+ 	return 0;
+ }
+ 
+ static int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
+-			unsigned long arg)
++		       unsigned long arg)
+ {
+ 	/* Never copy - 2.4.x doesn't need it */
+ 	return 0;
+ }
+ 
+-static void i810_dma_dispatch_mc(drm_device_t *dev, drm_buf_t *buf, int used,
+-		unsigned int last_render)
++static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used,
++				 unsigned int last_render)
+ {
+ 	drm_i810_private_t *dev_priv = dev->dev_private;
+ 	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+@@ -1158,19 +1146,17 @@ static void i810_dma_dispatch_mc(drm_dev
+ 
+ 	i810_kernel_lost_context(dev);
+ 
+-	u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
+-		I810_BUF_HARDWARE);
++	u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE);
+ 	if (u != I810_BUF_CLIENT) {
+ 		DRM_DEBUG("MC found buffer that isn't mine!\n");
+ 	}
+ 
+-	if (used > 4*1024)
++	if (used > 4 * 1024)
+ 		used = 0;
+ 
+ 	sarea_priv->dirty = 0x7f;
+ 
+-	DRM_DEBUG("dispatch mc addr 0x%lx, used 0x%x\n",
+-		address, used);
++	DRM_DEBUG("dispatch mc addr 0x%lx, used 0x%x\n", address, used);
+ 
+ 	dev_priv->counter++;
+ 	DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter);
+@@ -1181,46 +1167,45 @@ static void i810_dma_dispatch_mc(drm_dev
+ 
+ 	if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
+ 		if (used & 4) {
+-			*(u32 *)((u32)buf_priv->virtual + used) = 0;
++			*(u32 *) ((u32) buf_priv->virtual + used) = 0;
+ 			used += 4;
+ 		}
+ 
+ 		i810_unmap_buffer(buf);
+ 	}
+ 	BEGIN_LP_RING(4);
+-	OUT_RING( CMD_OP_BATCH_BUFFER );
+-	OUT_RING( start | BB1_PROTECTED );
+-	OUT_RING( start + used - 4 );
+-	OUT_RING( 0 );
++	OUT_RING(CMD_OP_BATCH_BUFFER);
++	OUT_RING(start | BB1_PROTECTED);
++	OUT_RING(start + used - 4);
++	OUT_RING(0);
+ 	ADVANCE_LP_RING();
+ 
+-
+ 	BEGIN_LP_RING(8);
+-	OUT_RING( CMD_STORE_DWORD_IDX );
+-	OUT_RING( buf_priv->my_use_idx );
+-	OUT_RING( I810_BUF_FREE );
+-	OUT_RING( 0 );
+-
+-	OUT_RING( CMD_STORE_DWORD_IDX );
+-	OUT_RING( 16 );
+-	OUT_RING( last_render );
+-	OUT_RING( 0 );
++	OUT_RING(CMD_STORE_DWORD_IDX);
++	OUT_RING(buf_priv->my_use_idx);
++	OUT_RING(I810_BUF_FREE);
++	OUT_RING(0);
++
++	OUT_RING(CMD_STORE_DWORD_IDX);
++	OUT_RING(16);
++	OUT_RING(last_render);
++	OUT_RING(0);
+ 	ADVANCE_LP_RING();
+ }
+ 
+ static int i810_dma_mc(struct inode *inode, struct file *filp,
+-	unsigned int cmd, unsigned long arg)
++		       unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_device_dma_t *dma = dev->dma;
+-	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
++	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+ 	u32 *hw_status = dev_priv->hw_status_page;
+ 	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+-		dev_priv->sarea_priv;
++	    dev_priv->sarea_priv;
+ 	drm_i810_mc_t mc;
+ 
+-	if (copy_from_user(&mc, (drm_i810_mc_t __user *)arg, sizeof(mc)))
++	if (copy_from_user(&mc, (drm_i810_mc_t __user *) arg, sizeof(mc)))
+ 		return -EFAULT;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+@@ -1229,12 +1214,12 @@ static int i810_dma_mc(struct inode *ino
+ 		return -EINVAL;
+ 
+ 	i810_dma_dispatch_mc(dev, dma->buflist[mc.idx], mc.used,
+-		mc.last_render );
++			     mc.last_render);
+ 
+ 	atomic_add(mc.used, &dev->counts[_DRM_STAT_SECONDARY]);
+ 	atomic_inc(&dev->counts[_DRM_STAT_DMA]);
+-	sarea_priv->last_enqueue = dev_priv->counter-1;
+-	sarea_priv->last_dispatch = (int) hw_status[5];
++	sarea_priv->last_enqueue = dev_priv->counter - 1;
++	sarea_priv->last_dispatch = (int)hw_status[5];
+ 
+ 	return 0;
+ }
+@@ -1244,22 +1229,23 @@ static int i810_rstatus(struct inode *in
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+-	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
++	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+ 
+-	return (int)(((u32 *)(dev_priv->hw_status_page))[4]);
++	return (int)(((u32 *) (dev_priv->hw_status_page))[4]);
+ }
+ 
+ static int i810_ov0_info(struct inode *inode, struct file *filp,
+-			unsigned int cmd, unsigned long arg)
++			 unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+-	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
++	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+ 	drm_i810_overlay_t data;
+ 
+ 	data.offset = dev_priv->overlay_offset;
+ 	data.physical = dev_priv->overlay_physical;
+-	if (copy_to_user((drm_i810_overlay_t __user *)arg,&data,sizeof(data)))
++	if (copy_to_user
++	    ((drm_i810_overlay_t __user *) arg, &data, sizeof(data)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+@@ -1269,7 +1255,7 @@ static int i810_fstatus(struct inode *in
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+-	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
++	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+@@ -1277,47 +1263,46 @@ static int i810_fstatus(struct inode *in
+ }
+ 
+ static int i810_ov0_flip(struct inode *inode, struct file *filp,
+-			unsigned int cmd, unsigned long arg)
++			 unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+-	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
++	drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+ 	//Tell the overlay to update
+-	I810_WRITE(0x30000,dev_priv->overlay_physical | 0x80000000);
++	I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000);
+ 
+ 	return 0;
+ }
+ 
+-
+ /* Not sure why this isn't set all the time:
+- */ 
+-static void i810_do_init_pageflip( drm_device_t *dev )
++ */
++static void i810_do_init_pageflip(drm_device_t * dev)
+ {
+ 	drm_i810_private_t *dev_priv = dev->dev_private;
+-	
++
+ 	DRM_DEBUG("%s\n", __FUNCTION__);
+ 	dev_priv->page_flipping = 1;
+ 	dev_priv->current_page = 0;
+ 	dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
+ }
+ 
+-static int i810_do_cleanup_pageflip( drm_device_t *dev )
++static int i810_do_cleanup_pageflip(drm_device_t * dev)
+ {
+ 	drm_i810_private_t *dev_priv = dev->dev_private;
+ 
+ 	DRM_DEBUG("%s\n", __FUNCTION__);
+ 	if (dev_priv->current_page != 0)
+-		i810_dma_dispatch_flip( dev );
++		i810_dma_dispatch_flip(dev);
+ 
+ 	dev_priv->page_flipping = 0;
+ 	return 0;
+ }
+ 
+ static int i810_flip_bufs(struct inode *inode, struct file *filp,
+-			unsigned int cmd, unsigned long arg)
++			  unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -1327,19 +1312,19 @@ static int i810_flip_bufs(struct inode *
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if (!dev_priv->page_flipping) 
+-		i810_do_init_pageflip( dev );
++	if (!dev_priv->page_flipping)
++		i810_do_init_pageflip(dev);
+ 
+-	i810_dma_dispatch_flip( dev );
+-   	return 0;
++	i810_dma_dispatch_flip(dev);
++	return 0;
+ }
+ 
+-void i810_driver_pretakedown(drm_device_t *dev)
++void i810_driver_pretakedown(drm_device_t * dev)
+ {
+-	i810_dma_cleanup( dev );
++	i810_dma_cleanup(dev);
+ }
+ 
+-void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp)
++void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+ {
+ 	if (dev->dev_private) {
+ 		drm_i810_private_t *dev_priv = dev->dev_private;
+@@ -1349,33 +1334,33 @@ void i810_driver_prerelease(drm_device_t
+ 	}
+ }
+ 
+-void i810_driver_release(drm_device_t *dev, struct file *filp)
++void i810_driver_release(drm_device_t * dev, struct file *filp)
+ {
+ 	i810_reclaim_buffers(dev, filp);
+ }
+ 
+-int i810_driver_dma_quiescent(drm_device_t *dev)
++int i810_driver_dma_quiescent(drm_device_t * dev)
+ {
+-	i810_dma_quiescent( dev );
++	i810_dma_quiescent(dev);
+ 	return 0;
+ }
+ 
+ drm_ioctl_desc_t i810_ioctls[] = {
+-	[DRM_IOCTL_NR(DRM_I810_INIT)]    = { i810_dma_init,    1, 1 },
+-	[DRM_IOCTL_NR(DRM_I810_VERTEX)]  = { i810_dma_vertex,  1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_CLEAR)]   = { i810_clear_bufs,  1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_FLUSH)]   = { i810_flush_ioctl, 1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_GETAGE)]  = { i810_getage,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_GETBUF)]  = { i810_getbuf,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_SWAP)]    = { i810_swap_bufs,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_COPY)]    = { i810_copybuf,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_DOCOPY)]  = { i810_docopy,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_OV0INFO)] = { i810_ov0_info,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_FSTATUS)] = { i810_fstatus,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = { i810_ov0_flip,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_MC)]      = { i810_dma_mc,      1, 1 },
+-	[DRM_IOCTL_NR(DRM_I810_RSTATUS)] = { i810_rstatus,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_I810_FLIP)]    = { i810_flip_bufs,   1, 0 }
++	[DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1},
++	[DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1},
++	[DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0},
++	[DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, 1, 0}
+ };
+ 
+ int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
+diff --git a/drivers/char/drm/i810_drm.h b/drivers/char/drm/i810_drm.h
+--- a/drivers/char/drm/i810_drm.h
++++ b/drivers/char/drm/i810_drm.h
+@@ -19,21 +19,20 @@
+ #define I810_LOG_MIN_TEX_REGION_SIZE 16
+ #endif
+ 
+-#define I810_UPLOAD_TEX0IMAGE  0x1 /* handled clientside */
+-#define I810_UPLOAD_TEX1IMAGE  0x2 /* handled clientside */
++#define I810_UPLOAD_TEX0IMAGE  0x1	/* handled clientside */
++#define I810_UPLOAD_TEX1IMAGE  0x2	/* handled clientside */
+ #define I810_UPLOAD_CTX        0x4
+ #define I810_UPLOAD_BUFFERS    0x8
+ #define I810_UPLOAD_TEX0       0x10
+ #define I810_UPLOAD_TEX1       0x20
+ #define I810_UPLOAD_CLIPRECTS  0x40
+ 
+-
+ /* Indices into buf.Setup where various bits of state are mirrored per
+  * context and per buffer.  These can be fired at the card as a unit,
+  * or in a piecewise fashion as required.
+  */
+ 
+-/* Destbuffer state 
++/* Destbuffer state
+  *    - backbuffer linear offset and pitch -- invarient in the current dri
+  *    - zbuffer linear offset and pitch -- also invarient
+  *    - drawing origin in back and depth buffers.
+@@ -55,13 +54,13 @@
+ /* Context state
+  */
+ #define I810_CTXREG_CF0   0	/* GFX_OP_COLOR_FACTOR */
+-#define I810_CTXREG_CF1   1	
+-#define I810_CTXREG_ST0   2     /* GFX_OP_STIPPLE */
++#define I810_CTXREG_CF1   1
++#define I810_CTXREG_ST0   2	/* GFX_OP_STIPPLE */
+ #define I810_CTXREG_ST1   3
+ #define I810_CTXREG_VF    4	/* GFX_OP_VERTEX_FMT */
+ #define I810_CTXREG_MT    5	/* GFX_OP_MAP_TEXELS */
+ #define I810_CTXREG_MC0   6	/* GFX_OP_MAP_COLOR_STAGES - stage 0 */
+-#define I810_CTXREG_MC1   7     /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
++#define I810_CTXREG_MC1   7	/* GFX_OP_MAP_COLOR_STAGES - stage 1 */
+ #define I810_CTXREG_MC2   8	/* GFX_OP_MAP_COLOR_STAGES - stage 2 */
+ #define I810_CTXREG_MA0   9	/* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
+ #define I810_CTXREG_MA1   10	/* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
+@@ -74,14 +73,14 @@
+ #define I810_CTXREG_PV    17	/* GFX_OP_PV_RULE -- Invarient! */
+ #define I810_CTXREG_ZA    18	/* GFX_OP_ZBIAS_ALPHAFUNC */
+ #define I810_CTXREG_AA    19	/* GFX_OP_ANTIALIAS */
+-#define I810_CTX_SETUP_SIZE 20 
++#define I810_CTX_SETUP_SIZE 20
+ 
+ /* Texture state (per tex unit)
+  */
+ #define I810_TEXREG_MI0  0	/* GFX_OP_MAP_INFO (4 dwords) */
+-#define I810_TEXREG_MI1  1	
+-#define I810_TEXREG_MI2  2	
+-#define I810_TEXREG_MI3  3	
++#define I810_TEXREG_MI1  1
++#define I810_TEXREG_MI2  2
++#define I810_TEXREG_MI3  3
+ #define I810_TEXREG_MF   4	/* GFX_OP_MAP_FILTER */
+ #define I810_TEXREG_MLC  5	/* GFX_OP_MAP_LOD_CTL */
+ #define I810_TEXREG_MLL  6	/* GFX_OP_MAP_LOD_LIMITS */
+@@ -98,7 +97,7 @@ typedef enum _drm_i810_init_func {
+ 	I810_INIT_DMA = 0x01,
+ 	I810_CLEANUP_DMA = 0x02,
+ 	I810_INIT_DMA_1_4 = 0x03
+- } drm_i810_init_func_t;
++} drm_i810_init_func_t;
+ 
+ /* This is the init structure after v1.2 */
+ typedef struct _drm_i810_init {
+@@ -122,7 +121,7 @@ typedef struct _drm_i810_init {
+ 	unsigned int w;
+ 	unsigned int h;
+ 	unsigned int pitch;
+-	unsigned int pitch_bits; 
++	unsigned int pitch_bits;
+ } drm_i810_init_t;
+ 
+ /* This is the init structure prior to v1.2 */
+@@ -140,23 +139,23 @@ typedef struct _drm_i810_pre12_init {
+ 	unsigned int w;
+ 	unsigned int h;
+ 	unsigned int pitch;
+-	unsigned int pitch_bits; 
++	unsigned int pitch_bits;
+ } drm_i810_pre12_init_t;
+ 
+ /* Warning: If you change the SAREA structure you must change the Xserver
+  * structure as well */
+ 
+ typedef struct _drm_i810_tex_region {
+-	unsigned char next, prev; /* indices to form a circular LRU  */
++	unsigned char next, prev;	/* indices to form a circular LRU  */
+ 	unsigned char in_use;	/* owned by a client, or free? */
+ 	int age;		/* tracked by clients to update local LRU's */
+ } drm_i810_tex_region_t;
+ 
+ typedef struct _drm_i810_sarea {
+-   	unsigned int ContextState[I810_CTX_SETUP_SIZE];
+-   	unsigned int BufferState[I810_DEST_SETUP_SIZE];
+-   	unsigned int TexState[2][I810_TEX_SETUP_SIZE];
+-   	unsigned int dirty;
++	unsigned int ContextState[I810_CTX_SETUP_SIZE];
++	unsigned int BufferState[I810_DEST_SETUP_SIZE];
++	unsigned int TexState[2][I810_TEX_SETUP_SIZE];
++	unsigned int dirty;
+ 
+ 	unsigned int nbox;
+ 	drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
+@@ -174,22 +173,22 @@ typedef struct _drm_i810_sarea {
+ 	 * texture space, and can make informed decisions as to which
+ 	 * areas to kick out.  There is no need to choose whether to
+ 	 * kick out your own texture or someone else's - simply eject
+-	 * them all in LRU order.  
++	 * them all in LRU order.
+ 	 */
+-   
+-	drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1]; 
+-				/* Last elt is sentinal */
+-        int texAge;		/* last time texture was uploaded */
+-        int last_enqueue;	/* last time a buffer was enqueued */
++
++	drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS + 1];
++	/* Last elt is sentinal */
++	int texAge;		/* last time texture was uploaded */
++	int last_enqueue;	/* last time a buffer was enqueued */
+ 	int last_dispatch;	/* age of the most recently dispatched buffer */
+-	int last_quiescent;     /*  */
++	int last_quiescent;	/*  */
+ 	int ctxOwner;		/* last context to upload state */
+ 
+ 	int vertex_prim;
+ 
+-	int pf_enabled;               /* is pageflipping allowed? */
++	int pf_enabled;		/* is pageflipping allowed? */
+ 	int pf_active;
+-	int pf_current_page;	    /* which buffer is being displayed? */
++	int pf_current_page;	/* which buffer is being displayed? */
+ } drm_i810_sarea_t;
+ 
+ /* WARNING: If you change any of these defines, make sure to change the
+@@ -243,13 +242,13 @@ typedef struct _drm_i810_clear {
+  * new set of cliprects.
+  */
+ typedef struct _drm_i810_vertex {
+-   	int idx;		/* buffer index */
++	int idx;		/* buffer index */
+ 	int used;		/* nr bytes in use */
+ 	int discard;		/* client is finished with the buffer? */
+ } drm_i810_vertex_t;
+ 
+ typedef struct _drm_i810_copy_t {
+-   	int idx;		/* buffer index */
++	int idx;		/* buffer index */
+ 	int used;		/* nr bytes in use */
+ 	void *address;		/* Address to copy from */
+ } drm_i810_copy_t;
+@@ -264,7 +263,6 @@ typedef struct _drm_i810_copy_t {
+ #define PR_RECTS             (0x7<<18)
+ #define PR_MASK              (0x7<<18)
+ 
+-
+ typedef struct drm_i810_dma {
+ 	void *virtual;
+ 	int request_idx;
+@@ -273,17 +271,16 @@ typedef struct drm_i810_dma {
+ } drm_i810_dma_t;
+ 
+ typedef struct _drm_i810_overlay_t {
+-	unsigned int offset;    /* Address of the Overlay Regs */
++	unsigned int offset;	/* Address of the Overlay Regs */
+ 	unsigned int physical;
+ } drm_i810_overlay_t;
+ 
+ typedef struct _drm_i810_mc {
+-	int idx;                /* buffer index */
+-	int used;               /* nr bytes in use */
+-	int num_blocks;         /* number of GFXBlocks */
+-	int *length;            /* List of lengths for GFXBlocks (FUTURE)*/
+-	unsigned int last_render; /* Last Render Request */
++	int idx;		/* buffer index */
++	int used;		/* nr bytes in use */
++	int num_blocks;		/* number of GFXBlocks */
++	int *length;		/* List of lengths for GFXBlocks (FUTURE) */
++	unsigned int last_render;	/* Last Render Request */
+ } drm_i810_mc_t;
+ 
+-
+-#endif /* _I810_DRM_H_ */
++#endif				/* _I810_DRM_H_ */
+diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
+--- a/drivers/char/drm/i810_drv.c
++++ b/drivers/char/drm/i810_drv.c
+@@ -38,7 +38,7 @@
+ 
+ #include "drm_pciids.h"
+ 
+-static int postinit( struct drm_device *dev, unsigned long flags )
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+ 	/* i810 has 4 more counters */
+ 	dev->counters += 4;
+@@ -46,29 +46,27 @@ static int postinit( struct drm_device *
+ 	dev->types[7] = _DRM_STAT_PRIMARY;
+ 	dev->types[8] = _DRM_STAT_SECONDARY;
+ 	dev->types[9] = _DRM_STAT_DMA;
+-	
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->primary.minor,
+-		pci_pretty_name(dev->pdev)
+-		);
++
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR,
++		 DRIVER_PATCHLEVEL,
++		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
++	    );
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+@@ -76,11 +74,10 @@ static struct pci_device_id pciidlist[] 
+ 	i810_PCI_IDS
+ };
+ 
+-extern drm_ioctl_desc_t i810_ioctls[];
+-extern int i810_max_ioctl;
+-
+ static struct drm_driver driver = {
+-	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
++	.driver_features =
++	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
++	    DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
+ 	.dev_priv_size = sizeof(drm_i810_buf_priv_t),
+ 	.pretakedown = i810_driver_pretakedown,
+ 	.prerelease = i810_driver_prerelease,
+@@ -94,18 +91,20 @@ static struct drm_driver driver = {
+ 	.version = version,
+ 	.ioctls = i810_ioctls,
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
+-	},
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
++		 }
++	,
+ 	.pci_driver = {
+-		.name          = DRIVER_NAME,
+-		.id_table      = pciidlist,
+-	},
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
++	,
+ };
+ 
+ static int __init i810_init(void)
+@@ -122,6 +121,6 @@ static void __exit i810_exit(void)
+ module_init(i810_init);
+ module_exit(i810_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
+--- a/drivers/char/drm/i810_drv.h
++++ b/drivers/char/drm/i810_drv.h
+@@ -56,14 +56,14 @@
+ #define DRIVER_PATCHLEVEL	0
+ 
+ typedef struct drm_i810_buf_priv {
+-   	u32 *in_use;
+-   	int my_use_idx;
++	u32 *in_use;
++	int my_use_idx;
+ 	int currently_mapped;
+ 	void *virtual;
+ 	void *kernel_virtual;
+ } drm_i810_buf_priv_t;
+ 
+-typedef struct _drm_i810_ring_buffer{
++typedef struct _drm_i810_ring_buffer {
+ 	int tail_mask;
+ 	unsigned long Start;
+ 	unsigned long End;
+@@ -79,16 +79,15 @@ typedef struct drm_i810_private {
+ 	drm_map_t *mmio_map;
+ 
+ 	drm_i810_sarea_t *sarea_priv;
+-   	drm_i810_ring_buffer_t ring;
++	drm_i810_ring_buffer_t ring;
+ 
+-      	void *hw_status_page;
+-   	unsigned long counter;
++	void *hw_status_page;
++	unsigned long counter;
+ 
+ 	dma_addr_t dma_status_page;
+ 
+ 	drm_buf_t *mmap_buffer;
+ 
+-
+ 	u32 front_di1, back_di1, zi1;
+ 
+ 	int back_offset;
+@@ -97,7 +96,7 @@ typedef struct drm_i810_private {
+ 	int overlay_physical;
+ 	int w, h;
+ 	int pitch;
+-  	int back_pitch;
++	int back_pitch;
+ 	int depth_pitch;
+ 
+ 	int do_boxes;
+@@ -107,21 +106,24 @@ typedef struct drm_i810_private {
+ 	int page_flipping;
+ 
+ 	wait_queue_head_t irq_queue;
+-   	atomic_t irq_received;
+-   	atomic_t irq_emitted;
+-  
+-        int front_offset;
++	atomic_t irq_received;
++	atomic_t irq_emitted;
++
++	int front_offset;
+ } drm_i810_private_t;
+ 
+ 				/* i810_dma.c */
+-extern void i810_reclaim_buffers(drm_device_t *dev, struct file *filp);
++extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp);
+ 
+-extern int i810_driver_dma_quiescent(drm_device_t *dev);
+-extern void i810_driver_release(drm_device_t *dev, struct file *filp);
+-extern void i810_driver_pretakedown(drm_device_t *dev);
+-extern void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp);
++extern int i810_driver_dma_quiescent(drm_device_t * dev);
++extern void i810_driver_release(drm_device_t * dev, struct file *filp);
++extern void i810_driver_pretakedown(drm_device_t * dev);
++extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+ extern int i810_driver_device_is_agp(drm_device_t * dev);
+ 
++extern drm_ioctl_desc_t i810_ioctls[];
++extern int i810_max_ioctl;
++
+ #define I810_BASE(reg)		((unsigned long) \
+ 				dev_priv->mmio_map->handle)
+ #define I810_ADDR(reg)		(I810_BASE(reg) + reg)
+@@ -170,7 +172,6 @@ extern int i810_driver_device_is_agp(drm
+ #define INST_OP_FLUSH        0x02000000
+ #define INST_FLUSH_MAP_CACHE 0x00000001
+ 
+-
+ #define BB1_START_ADDR_MASK   (~0x7)
+ #define BB1_PROTECTED         (1<<0)
+ #define BB1_UNPROTECTED       (0<<0)
+@@ -229,8 +230,8 @@ extern int i810_driver_device_is_agp(drm
+ #define BR00_OP_SRC_COPY_BLT 0x10C00000
+ #define BR13_SOLID_PATTERN   0x80000000
+ 
+-#define WAIT_FOR_PLANE_A_SCANLINES (1<<1) 
+-#define WAIT_FOR_PLANE_A_FLIP      (1<<2) 
++#define WAIT_FOR_PLANE_A_SCANLINES (1<<1)
++#define WAIT_FOR_PLANE_A_FLIP      (1<<2)
+ #define WAIT_FOR_VBLANK (1<<3)
+ 
+ #endif
+diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
+--- a/drivers/char/drm/i830_dma.c
++++ b/drivers/char/drm/i830_dma.c
+@@ -11,11 +11,11 @@
+  * 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 (including the next
+  * paragraph) 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
+@@ -47,103 +47,104 @@
+ #define I830_BUF_UNMAPPED 0
+ #define I830_BUF_MAPPED   1
+ 
+-static drm_buf_t *i830_freelist_get(drm_device_t *dev)
++static drm_buf_t *i830_freelist_get(drm_device_t * dev)
+ {
+-   	drm_device_dma_t *dma = dev->dma;
+-	int		 i;
+-   	int 		 used;
+-   
++	drm_device_dma_t *dma = dev->dma;
++	int i;
++	int used;
++
+ 	/* Linear search might not be the best solution */
+ 
+-   	for (i = 0; i < dma->buf_count; i++) {
+-	   	drm_buf_t *buf = dma->buflist[ i ];
+-	   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
++	for (i = 0; i < dma->buf_count; i++) {
++		drm_buf_t *buf = dma->buflist[i];
++		drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+ 		/* In use is already a pointer */
+-	   	used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, 
++		used = cmpxchg(buf_priv->in_use, I830_BUF_FREE,
+ 			       I830_BUF_CLIENT);
+-	   	if(used == I830_BUF_FREE) {
++		if (used == I830_BUF_FREE) {
+ 			return buf;
+ 		}
+ 	}
+-   	return NULL;
++	return NULL;
+ }
+ 
+ /* This should only be called if the buffer is not sent to the hardware
+  * yet, the hardware updates in use for us once its on the ring buffer.
+  */
+ 
+-static int i830_freelist_put(drm_device_t *dev, drm_buf_t *buf)
++static int i830_freelist_put(drm_device_t * dev, drm_buf_t * buf)
+ {
+-   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+-   	int used;
+-   
+-   	/* In use is already a pointer */
+-   	used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE);
+-   	if(used != I830_BUF_CLIENT) {
+-	   	DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
+-	   	return -EINVAL;
++	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
++	int used;
++
++	/* In use is already a pointer */
++	used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE);
++	if (used != I830_BUF_CLIENT) {
++		DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
++		return -EINVAL;
+ 	}
+-   
+-   	return 0;
++
++	return 0;
+ }
+ 
+ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
+ {
+-	drm_file_t	    *priv	  = filp->private_data;
+-	drm_device_t	    *dev;
+-	drm_i830_private_t  *dev_priv;
+-	drm_buf_t           *buf;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev;
++	drm_i830_private_t *dev_priv;
++	drm_buf_t *buf;
+ 	drm_i830_buf_priv_t *buf_priv;
+ 
+ 	lock_kernel();
+-	dev	 = priv->head->dev;
++	dev = priv->head->dev;
+ 	dev_priv = dev->dev_private;
+-	buf      = dev_priv->mmap_buffer;
++	buf = dev_priv->mmap_buffer;
+ 	buf_priv = buf->dev_private;
+-   
++
+ 	vma->vm_flags |= (VM_IO | VM_DONTCOPY);
+ 	vma->vm_file = filp;
+-   
+-   	buf_priv->currently_mapped = I830_BUF_MAPPED;
++
++	buf_priv->currently_mapped = I830_BUF_MAPPED;
+ 	unlock_kernel();
+ 
+ 	if (io_remap_pfn_range(vma, vma->vm_start,
+-			     VM_OFFSET(vma) >> PAGE_SHIFT,
+-			     vma->vm_end - vma->vm_start,
+-			     vma->vm_page_prot)) return -EAGAIN;
++			       VM_OFFSET(vma) >> PAGE_SHIFT,
++			       vma->vm_end - vma->vm_start, vma->vm_page_prot))
++		return -EAGAIN;
+ 	return 0;
+ }
+ 
+ static struct file_operations i830_buffer_fops = {
+-	.open	 = drm_open,
+-	.flush	 = drm_flush,
++	.open = drm_open,
++	.flush = drm_flush,
+ 	.release = drm_release,
+-	.ioctl	 = drm_ioctl,
+-	.mmap	 = i830_mmap_buffers,
+-	.fasync  = drm_fasync,
++	.ioctl = drm_ioctl,
++	.mmap = i830_mmap_buffers,
++	.fasync = drm_fasync,
+ };
+ 
+-static int i830_map_buffer(drm_buf_t *buf, struct file *filp)
++static int i830_map_buffer(drm_buf_t * buf, struct file *filp)
+ {
+-	drm_file_t	  *priv	  = filp->private_data;
+-	drm_device_t	  *dev	  = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+-      	drm_i830_private_t *dev_priv = dev->dev_private;
+-   	struct file_operations *old_fops;
++	drm_i830_private_t *dev_priv = dev->dev_private;
++	struct file_operations *old_fops;
+ 	unsigned long virtual;
+ 	int retcode = 0;
+ 
+-	if(buf_priv->currently_mapped == I830_BUF_MAPPED) return -EINVAL;
++	if (buf_priv->currently_mapped == I830_BUF_MAPPED)
++		return -EINVAL;
+ 
+-	down_write( &current->mm->mmap_sem );
++	down_write(&current->mm->mmap_sem);
+ 	old_fops = filp->f_op;
+ 	filp->f_op = &i830_buffer_fops;
+ 	dev_priv->mmap_buffer = buf;
+-	virtual = do_mmap(filp, 0, buf->total, PROT_READ|PROT_WRITE,
+-			    MAP_SHARED, buf->bus_address);
++	virtual = do_mmap(filp, 0, buf->total, PROT_READ | PROT_WRITE,
++			  MAP_SHARED, buf->bus_address);
+ 	dev_priv->mmap_buffer = NULL;
+ 	filp->f_op = old_fops;
+-	if (IS_ERR((void *)virtual)) {		/* ugh */
++	if (IS_ERR((void *)virtual)) {	/* ugh */
+ 		/* Real error */
+ 		DRM_ERROR("mmap error\n");
+ 		retcode = virtual;
+@@ -151,17 +152,17 @@ static int i830_map_buffer(drm_buf_t *bu
+ 	} else {
+ 		buf_priv->virtual = (void __user *)virtual;
+ 	}
+-	up_write( &current->mm->mmap_sem );
++	up_write(&current->mm->mmap_sem);
+ 
+ 	return retcode;
+ }
+ 
+-static int i830_unmap_buffer(drm_buf_t *buf)
++static int i830_unmap_buffer(drm_buf_t * buf)
+ {
+ 	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+ 	int retcode = 0;
+ 
+-	if(buf_priv->currently_mapped != I830_BUF_MAPPED) 
++	if (buf_priv->currently_mapped != I830_BUF_MAPPED)
+ 		return -EINVAL;
+ 
+ 	down_write(&current->mm->mmap_sem);
+@@ -170,43 +171,43 @@ static int i830_unmap_buffer(drm_buf_t *
+ 			    (size_t) buf->total);
+ 	up_write(&current->mm->mmap_sem);
+ 
+-   	buf_priv->currently_mapped = I830_BUF_UNMAPPED;
+-   	buf_priv->virtual = NULL;
++	buf_priv->currently_mapped = I830_BUF_UNMAPPED;
++	buf_priv->virtual = NULL;
+ 
+ 	return retcode;
+ }
+ 
+-static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, 
++static int i830_dma_get_buffer(drm_device_t * dev, drm_i830_dma_t * d,
+ 			       struct file *filp)
+ {
+-	drm_buf_t	  *buf;
++	drm_buf_t *buf;
+ 	drm_i830_buf_priv_t *buf_priv;
+ 	int retcode = 0;
+ 
+ 	buf = i830_freelist_get(dev);
+ 	if (!buf) {
+ 		retcode = -ENOMEM;
+-	   	DRM_DEBUG("retcode=%d\n", retcode);
++		DRM_DEBUG("retcode=%d\n", retcode);
+ 		return retcode;
+ 	}
+-   
++
+ 	retcode = i830_map_buffer(buf, filp);
+-	if(retcode) {
++	if (retcode) {
+ 		i830_freelist_put(dev, buf);
+-	   	DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
++		DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
+ 		return retcode;
+ 	}
+ 	buf->filp = filp;
+-	buf_priv = buf->dev_private;	
++	buf_priv = buf->dev_private;
+ 	d->granted = 1;
+-   	d->request_idx = buf->idx;
+-   	d->request_size = buf->total;
+-   	d->virtual = buf_priv->virtual;
++	d->request_idx = buf->idx;
++	d->request_size = buf->total;
++	d->virtual = buf_priv->virtual;
+ 
+ 	return retcode;
+ }
+ 
+-static int i830_dma_cleanup(drm_device_t *dev)
++static int i830_dma_cleanup(drm_device_t * dev)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 
+@@ -214,140 +215,144 @@ static int i830_dma_cleanup(drm_device_t
+ 	 * may not have been called from userspace and after dev_private
+ 	 * is freed, it's too late.
+ 	 */
+-	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
++	if (dev->irq_enabled)
++		drm_irq_uninstall(dev);
+ 
+ 	if (dev->dev_private) {
+ 		int i;
+-	   	drm_i830_private_t *dev_priv = 
+-	     		(drm_i830_private_t *) dev->dev_private;
+-	   
+-	   	if (dev_priv->ring.virtual_start) {
+-		   	drm_ioremapfree((void *) dev_priv->ring.virtual_start,
+-					 dev_priv->ring.Size, dev);
++		drm_i830_private_t *dev_priv =
++		    (drm_i830_private_t *) dev->dev_private;
++
++		if (dev_priv->ring.virtual_start) {
++			drm_ioremapfree((void *)dev_priv->ring.virtual_start,
++					dev_priv->ring.Size, dev);
+ 		}
+-	   	if (dev_priv->hw_status_page) {
++		if (dev_priv->hw_status_page) {
+ 			pci_free_consistent(dev->pdev, PAGE_SIZE,
+ 					    dev_priv->hw_status_page,
+ 					    dev_priv->dma_status_page);
+-		   	/* Need to rewrite hardware status page */
+-		   	I830_WRITE(0x02080, 0x1ffff000);
++			/* Need to rewrite hardware status page */
++			I830_WRITE(0x02080, 0x1ffff000);
+ 		}
+ 
+-	   	drm_free(dev->dev_private, sizeof(drm_i830_private_t), 
++		drm_free(dev->dev_private, sizeof(drm_i830_private_t),
+ 			 DRM_MEM_DRIVER);
+-	   	dev->dev_private = NULL;
++		dev->dev_private = NULL;
+ 
+ 		for (i = 0; i < dma->buf_count; i++) {
+-			drm_buf_t *buf = dma->buflist[ i ];
++			drm_buf_t *buf = dma->buflist[i];
+ 			drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+-			if ( buf_priv->kernel_virtual && buf->total )
+-				drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev);
++			if (buf_priv->kernel_virtual && buf->total)
++				drm_ioremapfree(buf_priv->kernel_virtual,
++						buf->total, dev);
+ 		}
+ 	}
+-   	return 0;
++	return 0;
+ }
+ 
+-int i830_wait_ring(drm_device_t *dev, int n, const char *caller)
++int i830_wait_ring(drm_device_t * dev, int n, const char *caller)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
+-   	drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
+-   	int iters = 0;
+-   	unsigned long end;
++	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
++	int iters = 0;
++	unsigned long end;
+ 	unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ 
+-	end = jiffies + (HZ*3);
+-   	while (ring->space < n) {	
+-	   	ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+-	   	ring->space = ring->head - (ring->tail+8);
+-		if (ring->space < 0) ring->space += ring->Size;
+-	   
++	end = jiffies + (HZ * 3);
++	while (ring->space < n) {
++		ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
++		ring->space = ring->head - (ring->tail + 8);
++		if (ring->space < 0)
++			ring->space += ring->Size;
++
+ 		if (ring->head != last_head) {
+-			end = jiffies + (HZ*3);
++			end = jiffies + (HZ * 3);
+ 			last_head = ring->head;
+ 		}
+-	  
+-	   	iters++;
+-		if(time_before(end, jiffies)) {
+-		   	DRM_ERROR("space: %d wanted %d\n", ring->space, n);
+-		   	DRM_ERROR("lockup\n");
+-		   	goto out_wait_ring;
++
++		iters++;
++		if (time_before(end, jiffies)) {
++			DRM_ERROR("space: %d wanted %d\n", ring->space, n);
++			DRM_ERROR("lockup\n");
++			goto out_wait_ring;
+ 		}
+ 		udelay(1);
+ 		dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
+ 	}
+ 
+-out_wait_ring:   
+-   	return iters;
++      out_wait_ring:
++	return iters;
+ }
+ 
+-static void i830_kernel_lost_context(drm_device_t *dev)
++static void i830_kernel_lost_context(drm_device_t * dev)
+ {
+-      	drm_i830_private_t *dev_priv = dev->dev_private;
+-   	drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
+-      
+-   	ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+-     	ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
+-     	ring->space = ring->head - (ring->tail+8);
+-     	if (ring->space < 0) ring->space += ring->Size;
++	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
++
++	ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
++	ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
++	ring->space = ring->head - (ring->tail + 8);
++	if (ring->space < 0)
++		ring->space += ring->Size;
+ 
+ 	if (ring->head == ring->tail)
+ 		dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY;
+ }
+ 
+-static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv)
++static int i830_freelist_init(drm_device_t * dev, drm_i830_private_t * dev_priv)
+ {
+-      	drm_device_dma_t *dma = dev->dma;
+-   	int my_idx = 36;
+-   	u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx);
+-   	int i;
++	drm_device_dma_t *dma = dev->dma;
++	int my_idx = 36;
++	u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx);
++	int i;
+ 
+-   	if(dma->buf_count > 1019) {
+-	   	/* Not enough space in the status page for the freelist */
+-	   	return -EINVAL;
++	if (dma->buf_count > 1019) {
++		/* Not enough space in the status page for the freelist */
++		return -EINVAL;
+ 	}
+ 
+-   	for (i = 0; i < dma->buf_count; i++) {
+-	   	drm_buf_t *buf = dma->buflist[ i ];
+-	   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
++	for (i = 0; i < dma->buf_count; i++) {
++		drm_buf_t *buf = dma->buflist[i];
++		drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+ 
+-	   	buf_priv->in_use = hw_status++;
+-	   	buf_priv->my_use_idx = my_idx;
+-	   	my_idx += 4;
++		buf_priv->in_use = hw_status++;
++		buf_priv->my_use_idx = my_idx;
++		my_idx += 4;
+ 
+-	   	*buf_priv->in_use = I830_BUF_FREE;
++		*buf_priv->in_use = I830_BUF_FREE;
+ 
+-		buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, 
+-							buf->total, dev);
++		buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
++						       buf->total, dev);
+ 	}
+ 	return 0;
+ }
+ 
+-static int i830_dma_initialize(drm_device_t *dev, 
+-			       drm_i830_private_t *dev_priv,
+-			       drm_i830_init_t *init)
++static int i830_dma_initialize(drm_device_t * dev,
++			       drm_i830_private_t * dev_priv,
++			       drm_i830_init_t * init)
+ {
+ 	struct list_head *list;
+ 
+-   	memset(dev_priv, 0, sizeof(drm_i830_private_t));
++	memset(dev_priv, 0, sizeof(drm_i830_private_t));
+ 
+ 	list_for_each(list, &dev->maplist->head) {
+ 		drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
+-		if( r_list->map &&
++		if (r_list->map &&
+ 		    r_list->map->type == _DRM_SHM &&
+-		    r_list->map->flags & _DRM_CONTAINS_LOCK ) {
++		    r_list->map->flags & _DRM_CONTAINS_LOCK) {
+ 			dev_priv->sarea_map = r_list->map;
+- 			break;
+- 		}
+- 	}
++			break;
++		}
++	}
+ 
+-	if(!dev_priv->sarea_map) {
++	if (!dev_priv->sarea_map) {
+ 		dev->dev_private = (void *)dev_priv;
+ 		i830_dma_cleanup(dev);
+ 		DRM_ERROR("can not find sarea!\n");
+ 		return -EINVAL;
+ 	}
+ 	dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
+-	if(!dev_priv->mmio_map) {
++	if (!dev_priv->mmio_map) {
+ 		dev->dev_private = (void *)dev_priv;
+ 		i830_dma_cleanup(dev);
+ 		DRM_ERROR("can not find mmio map!\n");
+@@ -355,7 +360,7 @@ static int i830_dma_initialize(drm_devic
+ 	}
+ 	dev->agp_buffer_token = init->buffers_offset;
+ 	dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+-	if(!dev->agp_buffer_map) {
++	if (!dev->agp_buffer_map) {
+ 		dev->dev_private = (void *)dev_priv;
+ 		i830_dma_cleanup(dev);
+ 		DRM_ERROR("can not find dma buffer map!\n");
+@@ -363,27 +368,26 @@ static int i830_dma_initialize(drm_devic
+ 	}
+ 
+ 	dev_priv->sarea_priv = (drm_i830_sarea_t *)
+-		((u8 *)dev_priv->sarea_map->handle +
+-		 init->sarea_priv_offset);
++	    ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset);
+ 
+-   	dev_priv->ring.Start = init->ring_start;
+-   	dev_priv->ring.End = init->ring_end;
+-   	dev_priv->ring.Size = init->ring_size;
+-
+-   	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + 
+-						    init->ring_start, 
+-						    init->ring_size, dev);
+-
+-   	if (dev_priv->ring.virtual_start == NULL) {
+-		dev->dev_private = (void *) dev_priv;
+-	   	i830_dma_cleanup(dev);
+-	   	DRM_ERROR("can not ioremap virtual address for"
++	dev_priv->ring.Start = init->ring_start;
++	dev_priv->ring.End = init->ring_end;
++	dev_priv->ring.Size = init->ring_size;
++
++	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
++						   init->ring_start,
++						   init->ring_size, dev);
++
++	if (dev_priv->ring.virtual_start == NULL) {
++		dev->dev_private = (void *)dev_priv;
++		i830_dma_cleanup(dev);
++		DRM_ERROR("can not ioremap virtual address for"
+ 			  " ring buffer\n");
+-	   	return -ENOMEM;
++		return -ENOMEM;
+ 	}
+ 
+-   	dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+-   
++	dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
++
+ 	dev_priv->w = init->w;
+ 	dev_priv->h = init->h;
+ 	dev_priv->pitch = init->pitch;
+@@ -395,10 +399,10 @@ static int i830_dma_initialize(drm_devic
+ 	dev_priv->back_di1 = init->back_offset | init->pitch_bits;
+ 	dev_priv->zi1 = init->depth_offset | init->pitch_bits;
+ 
+-	DRM_DEBUG("front_di1 %x\n",    dev_priv->front_di1);
++	DRM_DEBUG("front_di1 %x\n", dev_priv->front_di1);
+ 	DRM_DEBUG("back_offset %x\n", dev_priv->back_offset);
+-	DRM_DEBUG("back_di1 %x\n",    dev_priv->back_di1);
+-	DRM_DEBUG("pitch_bits %x\n",    init->pitch_bits);
++	DRM_DEBUG("back_di1 %x\n", dev_priv->back_di1);
++	DRM_DEBUG("pitch_bits %x\n", init->pitch_bits);
+ 
+ 	dev_priv->cpp = init->cpp;
+ 	/* We are using separate values as placeholders for mechanisms for
+@@ -410,63 +414,64 @@ static int i830_dma_initialize(drm_devic
+ 	dev_priv->do_boxes = 0;
+ 	dev_priv->use_mi_batchbuffer_start = 0;
+ 
+-   	/* Program Hardware Status Page */
+-   	dev_priv->hw_status_page =
+-		pci_alloc_consistent(dev->pdev, PAGE_SIZE,
+-						&dev_priv->dma_status_page);
+-   	if (!dev_priv->hw_status_page) {
++	/* Program Hardware Status Page */
++	dev_priv->hw_status_page =
++	    pci_alloc_consistent(dev->pdev, PAGE_SIZE,
++				 &dev_priv->dma_status_page);
++	if (!dev_priv->hw_status_page) {
+ 		dev->dev_private = (void *)dev_priv;
+ 		i830_dma_cleanup(dev);
+ 		DRM_ERROR("Can not allocate hardware status page\n");
+ 		return -ENOMEM;
+ 	}
+-   	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
++	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+ 	DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
+-   
+-   	I830_WRITE(0x02080, dev_priv->dma_status_page);
++
++	I830_WRITE(0x02080, dev_priv->dma_status_page);
+ 	DRM_DEBUG("Enabled hardware status page\n");
+-   
+-   	/* Now we need to init our freelist */
+-   	if(i830_freelist_init(dev, dev_priv) != 0) {
++
++	/* Now we need to init our freelist */
++	if (i830_freelist_init(dev, dev_priv) != 0) {
+ 		dev->dev_private = (void *)dev_priv;
+-	   	i830_dma_cleanup(dev);
+-	   	DRM_ERROR("Not enough space in the status page for"
++		i830_dma_cleanup(dev);
++		DRM_ERROR("Not enough space in the status page for"
+ 			  " the freelist\n");
+-	   	return -ENOMEM;
++		return -ENOMEM;
+ 	}
+ 	dev->dev_private = (void *)dev_priv;
+ 
+-   	return 0;
++	return 0;
+ }
+ 
+ static int i830_dma_init(struct inode *inode, struct file *filp,
+-		  unsigned int cmd, unsigned long arg)
++			 unsigned int cmd, unsigned long arg)
+ {
+-   	drm_file_t *priv = filp->private_data;
+-   	drm_device_t *dev = priv->head->dev;
+-   	drm_i830_private_t *dev_priv;
+-   	drm_i830_init_t init;
+-   	int retcode = 0;
+-	
+-  	if (copy_from_user(&init, (void * __user) arg, sizeof(init)))
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_i830_private_t *dev_priv;
++	drm_i830_init_t init;
++	int retcode = 0;
++
++	if (copy_from_user(&init, (void *__user)arg, sizeof(init)))
+ 		return -EFAULT;
+-	
+-   	switch(init.func) {
+-	 	case I830_INIT_DMA:
+-			dev_priv = drm_alloc(sizeof(drm_i830_private_t), 
+-					      DRM_MEM_DRIVER);
+-	   		if(dev_priv == NULL) return -ENOMEM;
+-	   		retcode = i830_dma_initialize(dev, dev_priv, &init);
+-	   	break;
+-	 	case I830_CLEANUP_DMA:
+-	   		retcode = i830_dma_cleanup(dev);
+-	   	break;
+-	 	default:
+-	   		retcode = -EINVAL;
+-	   	break;
++
++	switch (init.func) {
++	case I830_INIT_DMA:
++		dev_priv = drm_alloc(sizeof(drm_i830_private_t),
++				     DRM_MEM_DRIVER);
++		if (dev_priv == NULL)
++			return -ENOMEM;
++		retcode = i830_dma_initialize(dev, dev_priv, &init);
++		break;
++	case I830_CLEANUP_DMA:
++		retcode = i830_dma_cleanup(dev);
++		break;
++	default:
++		retcode = -EINVAL;
++		break;
+ 	}
+-   
+-   	return retcode;
++
++	return retcode;
+ }
+ 
+ #define GFX_OP_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+@@ -476,92 +481,89 @@ static int i830_dma_init(struct inode *i
+ /* Most efficient way to verify state for the i830 is as it is
+  * emitted.  Non-conformant state is silently dropped.
+  */
+-static void i830EmitContextVerified( drm_device_t *dev,
+-				     unsigned int *code )
++static void i830EmitContextVerified(drm_device_t * dev, unsigned int *code)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	int i, j = 0;
+ 	unsigned int tmp;
+ 	RING_LOCALS;
+ 
+-	BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 );
++	BEGIN_LP_RING(I830_CTX_SETUP_SIZE + 4);
+ 
+-	for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) {
++	for (i = 0; i < I830_CTXREG_BLENDCOLR0; i++) {
+ 		tmp = code[i];
+-		if ((tmp & (7<<29)) == CMD_3D &&
+-		    (tmp & (0x1f<<24)) < (0x1d<<24)) {
+-			OUT_RING( tmp ); 
++		if ((tmp & (7 << 29)) == CMD_3D &&
++		    (tmp & (0x1f << 24)) < (0x1d << 24)) {
++			OUT_RING(tmp);
+ 			j++;
+ 		} else {
+ 			DRM_ERROR("Skipping %d\n", i);
+ 		}
+ 	}
+ 
+-	OUT_RING( STATE3D_CONST_BLEND_COLOR_CMD ); 
+-	OUT_RING( code[I830_CTXREG_BLENDCOLR] ); 
++	OUT_RING(STATE3D_CONST_BLEND_COLOR_CMD);
++	OUT_RING(code[I830_CTXREG_BLENDCOLR]);
+ 	j += 2;
+ 
+-	for ( i = I830_CTXREG_VF ; i < I830_CTXREG_MCSB0 ; i++ ) {
++	for (i = I830_CTXREG_VF; i < I830_CTXREG_MCSB0; i++) {
+ 		tmp = code[i];
+-		if ((tmp & (7<<29)) == CMD_3D &&
+-		    (tmp & (0x1f<<24)) < (0x1d<<24)) {
+-			OUT_RING( tmp ); 
++		if ((tmp & (7 << 29)) == CMD_3D &&
++		    (tmp & (0x1f << 24)) < (0x1d << 24)) {
++			OUT_RING(tmp);
+ 			j++;
+ 		} else {
+ 			DRM_ERROR("Skipping %d\n", i);
+ 		}
+ 	}
+ 
+-	OUT_RING( STATE3D_MAP_COORD_SETBIND_CMD ); 
+-	OUT_RING( code[I830_CTXREG_MCSB1] ); 
++	OUT_RING(STATE3D_MAP_COORD_SETBIND_CMD);
++	OUT_RING(code[I830_CTXREG_MCSB1]);
+ 	j += 2;
+ 
+-	if (j & 1) 
+-		OUT_RING( 0 ); 
++	if (j & 1)
++		OUT_RING(0);
+ 
+ 	ADVANCE_LP_RING();
+ }
+ 
+-static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code ) 
++static void i830EmitTexVerified(drm_device_t * dev, unsigned int *code)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	int i, j = 0;
+ 	unsigned int tmp;
+ 	RING_LOCALS;
+ 
+ 	if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO ||
+-	    (code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) == 
+-	    (STATE3D_LOAD_STATE_IMMEDIATE_2|4)) {
++	    (code[I830_TEXREG_MI0] & ~(0xf * LOAD_TEXTURE_MAP0)) ==
++	    (STATE3D_LOAD_STATE_IMMEDIATE_2 | 4)) {
+ 
+-		BEGIN_LP_RING( I830_TEX_SETUP_SIZE );
++		BEGIN_LP_RING(I830_TEX_SETUP_SIZE);
+ 
+-		OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */
+-		OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */
+-		OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */
+-		OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */
+-		OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */
+-		OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */
+-		
+-		for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {
++		OUT_RING(code[I830_TEXREG_MI0]);	/* TM0LI */
++		OUT_RING(code[I830_TEXREG_MI1]);	/* TM0S0 */
++		OUT_RING(code[I830_TEXREG_MI2]);	/* TM0S1 */
++		OUT_RING(code[I830_TEXREG_MI3]);	/* TM0S2 */
++		OUT_RING(code[I830_TEXREG_MI4]);	/* TM0S3 */
++		OUT_RING(code[I830_TEXREG_MI5]);	/* TM0S4 */
++
++		for (i = 6; i < I830_TEX_SETUP_SIZE; i++) {
+ 			tmp = code[i];
+-			OUT_RING( tmp ); 
++			OUT_RING(tmp);
+ 			j++;
+-		} 
++		}
+ 
+-		if (j & 1) 
+-			OUT_RING( 0 ); 
++		if (j & 1)
++			OUT_RING(0);
+ 
+ 		ADVANCE_LP_RING();
+-	}
+-	else
++	} else
+ 		printk("rejected packet %x\n", code[0]);
+ }
+ 
+-static void i830EmitTexBlendVerified( drm_device_t *dev, 
+-				      unsigned int *code,
+-				      unsigned int num)
++static void i830EmitTexBlendVerified(drm_device_t * dev,
++				     unsigned int *code, unsigned int num)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	int i, j = 0;
+ 	unsigned int tmp;
+ 	RING_LOCALS;
+@@ -569,59 +571,54 @@ static void i830EmitTexBlendVerified( dr
+ 	if (!num)
+ 		return;
+ 
+-	BEGIN_LP_RING( num + 1 );
++	BEGIN_LP_RING(num + 1);
+ 
+-	for ( i = 0 ; i < num ; i++ ) {
++	for (i = 0; i < num; i++) {
+ 		tmp = code[i];
+-		OUT_RING( tmp );
++		OUT_RING(tmp);
+ 		j++;
+ 	}
+ 
+-	if (j & 1) 
+-		OUT_RING( 0 ); 
++	if (j & 1)
++		OUT_RING(0);
+ 
+ 	ADVANCE_LP_RING();
+ }
+ 
+-static void i830EmitTexPalette( drm_device_t *dev,
+-			        unsigned int *palette,
+-			        int number,
+-			        int is_shared )
++static void i830EmitTexPalette(drm_device_t * dev,
++			       unsigned int *palette, int number, int is_shared)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	int i;
+ 	RING_LOCALS;
+ 
+ 	return;
+ 
+-	BEGIN_LP_RING( 258 );
++	BEGIN_LP_RING(258);
+ 
+-	if(is_shared == 1) {
++	if (is_shared == 1) {
+ 		OUT_RING(CMD_OP_MAP_PALETTE_LOAD |
+-			 MAP_PALETTE_NUM(0) |
+-			 MAP_PALETTE_BOTH);
++			 MAP_PALETTE_NUM(0) | MAP_PALETTE_BOTH);
+ 	} else {
+ 		OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number));
+ 	}
+-	for(i = 0; i < 256; i++) {
++	for (i = 0; i < 256; i++) {
+ 		OUT_RING(palette[i]);
+ 	}
+ 	OUT_RING(0);
+-	/* KW:  WHERE IS THE ADVANCE_LP_RING?  This is effectively a noop! 
++	/* KW:  WHERE IS THE ADVANCE_LP_RING?  This is effectively a noop!
+ 	 */
+ }
+ 
+ /* Need to do some additional checking when setting the dest buffer.
+  */
+-static void i830EmitDestVerified( drm_device_t *dev, 
+-				  unsigned int *code ) 
+-{	
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++static void i830EmitDestVerified(drm_device_t * dev, unsigned int *code)
++{
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	unsigned int tmp;
+ 	RING_LOCALS;
+ 
+-	BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 );
+-
++	BEGIN_LP_RING(I830_DEST_SETUP_SIZE + 10);
+ 
+ 	tmp = code[I830_DESTREG_CBUFADDR];
+ 	if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
+@@ -630,18 +627,18 @@ static void i830EmitDestVerified( drm_de
+ 			OUT_RING(0);
+ 		}
+ 
+-		OUT_RING( CMD_OP_DESTBUFFER_INFO );
+-		OUT_RING( BUF_3D_ID_COLOR_BACK | 
+-			  BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
+-			  BUF_3D_USE_FENCE);
+-		OUT_RING( tmp );
+-		OUT_RING( 0 );
+-
+-		OUT_RING( CMD_OP_DESTBUFFER_INFO );
+-		OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | 
+-			  BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
+-		OUT_RING( dev_priv->zi1 );
+-		OUT_RING( 0 );
++		OUT_RING(CMD_OP_DESTBUFFER_INFO);
++		OUT_RING(BUF_3D_ID_COLOR_BACK |
++			 BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
++			 BUF_3D_USE_FENCE);
++		OUT_RING(tmp);
++		OUT_RING(0);
++
++		OUT_RING(CMD_OP_DESTBUFFER_INFO);
++		OUT_RING(BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE |
++			 BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
++		OUT_RING(dev_priv->zi1);
++		OUT_RING(0);
+ 	} else {
+ 		DRM_ERROR("bad di1 %x (allow %x or %x)\n",
+ 			  tmp, dev_priv->front_di1, dev_priv->back_di1);
+@@ -650,83 +647,80 @@ static void i830EmitDestVerified( drm_de
+ 	/* invarient:
+ 	 */
+ 
++	OUT_RING(GFX_OP_DESTBUFFER_VARS);
++	OUT_RING(code[I830_DESTREG_DV1]);
+ 
+-	OUT_RING( GFX_OP_DESTBUFFER_VARS );
+-	OUT_RING( code[I830_DESTREG_DV1] );
+-
+-	OUT_RING( GFX_OP_DRAWRECT_INFO );
+-	OUT_RING( code[I830_DESTREG_DR1] );
+-	OUT_RING( code[I830_DESTREG_DR2] );
+-	OUT_RING( code[I830_DESTREG_DR3] );
+-	OUT_RING( code[I830_DESTREG_DR4] );
++	OUT_RING(GFX_OP_DRAWRECT_INFO);
++	OUT_RING(code[I830_DESTREG_DR1]);
++	OUT_RING(code[I830_DESTREG_DR2]);
++	OUT_RING(code[I830_DESTREG_DR3]);
++	OUT_RING(code[I830_DESTREG_DR4]);
+ 
+ 	/* Need to verify this */
+ 	tmp = code[I830_DESTREG_SENABLE];
+-	if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) {
+-		OUT_RING( tmp );
++	if ((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) {
++		OUT_RING(tmp);
+ 	} else {
+ 		DRM_ERROR("bad scissor enable\n");
+-		OUT_RING( 0 );
++		OUT_RING(0);
+ 	}
+ 
+-	OUT_RING( GFX_OP_SCISSOR_RECT );
+-	OUT_RING( code[I830_DESTREG_SR1] );
+-	OUT_RING( code[I830_DESTREG_SR2] );
+-	OUT_RING( 0 );
++	OUT_RING(GFX_OP_SCISSOR_RECT);
++	OUT_RING(code[I830_DESTREG_SR1]);
++	OUT_RING(code[I830_DESTREG_SR2]);
++	OUT_RING(0);
+ 
+ 	ADVANCE_LP_RING();
+ }
+ 
+-static void i830EmitStippleVerified( drm_device_t *dev, 
+-				     unsigned int *code ) 
++static void i830EmitStippleVerified(drm_device_t * dev, unsigned int *code)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	RING_LOCALS;
+ 
+-	BEGIN_LP_RING( 2 );
+-	OUT_RING( GFX_OP_STIPPLE );
+-	OUT_RING( code[1] );
+-	ADVANCE_LP_RING();	
++	BEGIN_LP_RING(2);
++	OUT_RING(GFX_OP_STIPPLE);
++	OUT_RING(code[1]);
++	ADVANCE_LP_RING();
+ }
+ 
+-
+-static void i830EmitState( drm_device_t *dev )
++static void i830EmitState(drm_device_t * dev)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
+-      	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
++	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	unsigned int dirty = sarea_priv->dirty;
+ 
+ 	DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);
+ 
+ 	if (dirty & I830_UPLOAD_BUFFERS) {
+-		i830EmitDestVerified( dev, sarea_priv->BufferState );
++		i830EmitDestVerified(dev, sarea_priv->BufferState);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS;
+ 	}
+ 
+ 	if (dirty & I830_UPLOAD_CTX) {
+-		i830EmitContextVerified( dev, sarea_priv->ContextState );
++		i830EmitContextVerified(dev, sarea_priv->ContextState);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_CTX;
+ 	}
+ 
+ 	if (dirty & I830_UPLOAD_TEX0) {
+-		i830EmitTexVerified( dev, sarea_priv->TexState[0] );
++		i830EmitTexVerified(dev, sarea_priv->TexState[0]);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_TEX0;
+ 	}
+ 
+ 	if (dirty & I830_UPLOAD_TEX1) {
+-		i830EmitTexVerified( dev, sarea_priv->TexState[1] );
++		i830EmitTexVerified(dev, sarea_priv->TexState[1]);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_TEX1;
+ 	}
+ 
+ 	if (dirty & I830_UPLOAD_TEXBLEND0) {
+-		i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[0],
+-				sarea_priv->TexBlendStateWordsUsed[0]);
++		i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[0],
++					 sarea_priv->TexBlendStateWordsUsed[0]);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0;
+ 	}
+ 
+ 	if (dirty & I830_UPLOAD_TEXBLEND1) {
+-		i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[1],
+-				sarea_priv->TexBlendStateWordsUsed[1]);
++		i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[1],
++					 sarea_priv->TexBlendStateWordsUsed[1]);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1;
+ 	}
+ 
+@@ -759,36 +753,32 @@ static void i830EmitState( drm_device_t 
+ 	/* 1.3:
+ 	 */
+ 	if (dirty & I830_UPLOAD_STIPPLE) {
+-		i830EmitStippleVerified( dev, 
+-					 sarea_priv->StippleState);
++		i830EmitStippleVerified(dev, sarea_priv->StippleState);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE;
+ 	}
+ 
+ 	if (dirty & I830_UPLOAD_TEX2) {
+-		i830EmitTexVerified( dev, sarea_priv->TexState2 );
++		i830EmitTexVerified(dev, sarea_priv->TexState2);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_TEX2;
+ 	}
+ 
+ 	if (dirty & I830_UPLOAD_TEX3) {
+-		i830EmitTexVerified( dev, sarea_priv->TexState3 );
++		i830EmitTexVerified(dev, sarea_priv->TexState3);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_TEX3;
+ 	}
+ 
+-
+ 	if (dirty & I830_UPLOAD_TEXBLEND2) {
+-		i830EmitTexBlendVerified( 
+-			dev, 
+-			sarea_priv->TexBlendState2,
+-			sarea_priv->TexBlendStateWordsUsed2);
++		i830EmitTexBlendVerified(dev,
++					 sarea_priv->TexBlendState2,
++					 sarea_priv->TexBlendStateWordsUsed2);
+ 
+ 		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2;
+ 	}
+ 
+ 	if (dirty & I830_UPLOAD_TEXBLEND3) {
+-		i830EmitTexBlendVerified( 
+-			dev, 
+-			sarea_priv->TexBlendState3,
+-			sarea_priv->TexBlendStateWordsUsed3);
++		i830EmitTexBlendVerified(dev,
++					 sarea_priv->TexBlendState3,
++					 sarea_priv->TexBlendStateWordsUsed3);
+ 		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3;
+ 	}
+ }
+@@ -797,97 +787,96 @@ static void i830EmitState( drm_device_t 
+  * Performance monitoring functions
+  */
+ 
+-static void i830_fill_box( drm_device_t *dev,
+-			   int x, int y, int w, int h,
+-			   int r, int g, int b )
++static void i830_fill_box(drm_device_t * dev,
++			  int x, int y, int w, int h, int r, int g, int b)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	u32 color;
+ 	unsigned int BR13, CMD;
+ 	RING_LOCALS;
+ 
+-	BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24);
++	BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1 << 24);
+ 	CMD = XY_COLOR_BLT_CMD;
+ 	x += dev_priv->sarea_priv->boxes[0].x1;
+ 	y += dev_priv->sarea_priv->boxes[0].y1;
+ 
+ 	if (dev_priv->cpp == 4) {
+-		BR13 |= (1<<25);
++		BR13 |= (1 << 25);
+ 		CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
+-		color = (((0xff) << 24) | (r << 16) | (g <<  8) | b);	
++		color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
+ 	} else {
+ 		color = (((r & 0xf8) << 8) |
+-			 ((g & 0xfc) << 3) |
+-			 ((b & 0xf8) >> 3));
++			 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
+ 	}
+ 
+-	BEGIN_LP_RING( 6 );	    
+-	OUT_RING( CMD );
+-	OUT_RING( BR13 );
+-	OUT_RING( (y << 16) | x );
+-	OUT_RING( ((y+h) << 16) | (x+w) );
+-
+- 	if ( dev_priv->current_page == 1 ) { 
+-		OUT_RING( dev_priv->front_offset );
+- 	} else {	 
+-		OUT_RING( dev_priv->back_offset );
+- 	} 
++	BEGIN_LP_RING(6);
++	OUT_RING(CMD);
++	OUT_RING(BR13);
++	OUT_RING((y << 16) | x);
++	OUT_RING(((y + h) << 16) | (x + w));
+ 
+-	OUT_RING( color );
++	if (dev_priv->current_page == 1) {
++		OUT_RING(dev_priv->front_offset);
++	} else {
++		OUT_RING(dev_priv->back_offset);
++	}
++
++	OUT_RING(color);
+ 	ADVANCE_LP_RING();
+ }
+ 
+-static void i830_cp_performance_boxes( drm_device_t *dev )
++static void i830_cp_performance_boxes(drm_device_t * dev)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 
+ 	/* Purple box for page flipping
+ 	 */
+-	if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP ) 
+-		i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 );
++	if (dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP)
++		i830_fill_box(dev, 4, 4, 8, 8, 255, 0, 255);
+ 
+ 	/* Red box if we have to wait for idle at any point
+ 	 */
+-	if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT ) 
+-		i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 );
++	if (dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT)
++		i830_fill_box(dev, 16, 4, 8, 8, 255, 0, 0);
+ 
+ 	/* Blue box: lost context?
+ 	 */
+-	if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT ) 
+-		i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 );
++	if (dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT)
++		i830_fill_box(dev, 28, 4, 8, 8, 0, 0, 255);
+ 
+ 	/* Yellow box for texture swaps
+ 	 */
+-	if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD ) 
+-		i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 );
++	if (dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD)
++		i830_fill_box(dev, 40, 4, 8, 8, 255, 255, 0);
+ 
+ 	/* Green box if hardware never idles (as far as we can tell)
+ 	 */
+-	if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) ) 
+-		i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 );
+-
++	if (!(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY))
++		i830_fill_box(dev, 64, 4, 8, 8, 0, 255, 0);
+ 
+-	/* Draw bars indicating number of buffers allocated 
++	/* Draw bars indicating number of buffers allocated
+ 	 * (not a great measure, easily confused)
+ 	 */
+ 	if (dev_priv->dma_used) {
+ 		int bar = dev_priv->dma_used / 10240;
+-		if (bar > 100) bar = 100;
+-		if (bar < 1) bar = 1;
+-		i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 );
++		if (bar > 100)
++			bar = 100;
++		if (bar < 1)
++			bar = 1;
++		i830_fill_box(dev, 4, 16, bar, 4, 196, 128, 128);
+ 		dev_priv->dma_used = 0;
+ 	}
+ 
+ 	dev_priv->sarea_priv->perf_boxes = 0;
+ }
+ 
+-static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, 
++static void i830_dma_dispatch_clear(drm_device_t * dev, int flags,
+ 				    unsigned int clear_color,
+ 				    unsigned int clear_zval,
+ 				    unsigned int clear_depthmask)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
+-      	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
++	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	int nbox = sarea_priv->nbox;
+ 	drm_clip_rect_t *pbox = sarea_priv->boxes;
+ 	int pitch = dev_priv->pitch;
+@@ -896,90 +885,90 @@ static void i830_dma_dispatch_clear( drm
+ 	unsigned int BR13, CMD, D_CMD;
+ 	RING_LOCALS;
+ 
+-
+-	if ( dev_priv->current_page == 1 ) {
++	if (dev_priv->current_page == 1) {
+ 		unsigned int tmp = flags;
+ 
+ 		flags &= ~(I830_FRONT | I830_BACK);
+-		if ( tmp & I830_FRONT ) flags |= I830_BACK;
+-		if ( tmp & I830_BACK )  flags |= I830_FRONT;
++		if (tmp & I830_FRONT)
++			flags |= I830_BACK;
++		if (tmp & I830_BACK)
++			flags |= I830_FRONT;
+ 	}
+ 
+-  	i830_kernel_lost_context(dev);
++	i830_kernel_lost_context(dev);
+ 
+-	switch(cpp) {
+-	case 2: 
+-		BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
++	switch (cpp) {
++	case 2:
++		BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24);
+ 		D_CMD = CMD = XY_COLOR_BLT_CMD;
+ 		break;
+ 	case 4:
+-		BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);
+-		CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | 
++		BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24) | (1 << 25);
++		CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
+ 		       XY_COLOR_BLT_WRITE_RGB);
+ 		D_CMD = XY_COLOR_BLT_CMD;
+-		if(clear_depthmask & 0x00ffffff)
++		if (clear_depthmask & 0x00ffffff)
+ 			D_CMD |= XY_COLOR_BLT_WRITE_RGB;
+-		if(clear_depthmask & 0xff000000)
++		if (clear_depthmask & 0xff000000)
+ 			D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
+ 		break;
+ 	default:
+-		BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
++		BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24);
+ 		D_CMD = CMD = XY_COLOR_BLT_CMD;
+ 		break;
+ 	}
+ 
+-      	if (nbox > I830_NR_SAREA_CLIPRECTS)
+-     		nbox = I830_NR_SAREA_CLIPRECTS;
++	if (nbox > I830_NR_SAREA_CLIPRECTS)
++		nbox = I830_NR_SAREA_CLIPRECTS;
+ 
+-	for (i = 0 ; i < nbox ; i++, pbox++) {
++	for (i = 0; i < nbox; i++, pbox++) {
+ 		if (pbox->x1 > pbox->x2 ||
+ 		    pbox->y1 > pbox->y2 ||
+-		    pbox->x2 > dev_priv->w ||
+-		    pbox->y2 > dev_priv->h)
++		    pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
+ 			continue;
+ 
+-	   	if ( flags & I830_FRONT ) {	    
+-		   	DRM_DEBUG("clear front\n");
+-			BEGIN_LP_RING( 6 );	    
+-			OUT_RING( CMD );
+-			OUT_RING( BR13 );
+-			OUT_RING( (pbox->y1 << 16) | pbox->x1 );
+-			OUT_RING( (pbox->y2 << 16) | pbox->x2 );
+-			OUT_RING( dev_priv->front_offset );
+-			OUT_RING( clear_color );
++		if (flags & I830_FRONT) {
++			DRM_DEBUG("clear front\n");
++			BEGIN_LP_RING(6);
++			OUT_RING(CMD);
++			OUT_RING(BR13);
++			OUT_RING((pbox->y1 << 16) | pbox->x1);
++			OUT_RING((pbox->y2 << 16) | pbox->x2);
++			OUT_RING(dev_priv->front_offset);
++			OUT_RING(clear_color);
+ 			ADVANCE_LP_RING();
+ 		}
+ 
+-		if ( flags & I830_BACK ) {
++		if (flags & I830_BACK) {
+ 			DRM_DEBUG("clear back\n");
+-			BEGIN_LP_RING( 6 );	    
+-			OUT_RING( CMD );
+-			OUT_RING( BR13 );
+-			OUT_RING( (pbox->y1 << 16) | pbox->x1 );
+-			OUT_RING( (pbox->y2 << 16) | pbox->x2 );
+-			OUT_RING( dev_priv->back_offset );
+-			OUT_RING( clear_color );
++			BEGIN_LP_RING(6);
++			OUT_RING(CMD);
++			OUT_RING(BR13);
++			OUT_RING((pbox->y1 << 16) | pbox->x1);
++			OUT_RING((pbox->y2 << 16) | pbox->x2);
++			OUT_RING(dev_priv->back_offset);
++			OUT_RING(clear_color);
+ 			ADVANCE_LP_RING();
+ 		}
+ 
+-		if ( flags & I830_DEPTH ) {
++		if (flags & I830_DEPTH) {
+ 			DRM_DEBUG("clear depth\n");
+-			BEGIN_LP_RING( 6 );
+-			OUT_RING( D_CMD );
+-			OUT_RING( BR13 );
+-			OUT_RING( (pbox->y1 << 16) | pbox->x1 );
+-			OUT_RING( (pbox->y2 << 16) | pbox->x2 );
+-			OUT_RING( dev_priv->depth_offset );
+-			OUT_RING( clear_zval );
++			BEGIN_LP_RING(6);
++			OUT_RING(D_CMD);
++			OUT_RING(BR13);
++			OUT_RING((pbox->y1 << 16) | pbox->x1);
++			OUT_RING((pbox->y2 << 16) | pbox->x2);
++			OUT_RING(dev_priv->depth_offset);
++			OUT_RING(clear_zval);
+ 			ADVANCE_LP_RING();
+ 		}
+ 	}
+ }
+ 
+-static void i830_dma_dispatch_swap( drm_device_t *dev )
++static void i830_dma_dispatch_swap(drm_device_t * dev)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
+-      	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
++	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	int nbox = sarea_priv->nbox;
+ 	drm_clip_rect_t *pbox = sarea_priv->boxes;
+ 	int pitch = dev_priv->pitch;
+@@ -990,202 +979,192 @@ static void i830_dma_dispatch_swap( drm_
+ 
+ 	DRM_DEBUG("swapbuffers\n");
+ 
+-  	i830_kernel_lost_context(dev);
++	i830_kernel_lost_context(dev);
+ 
+ 	if (dev_priv->do_boxes)
+-		i830_cp_performance_boxes( dev );
++		i830_cp_performance_boxes(dev);
+ 
+-	switch(cpp) {
+-	case 2: 
+-		BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
++	switch (cpp) {
++	case 2:
++		BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
+ 		CMD = XY_SRC_COPY_BLT_CMD;
+ 		break;
+ 	case 4:
+-		BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25);
++		BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
+ 		CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+ 		       XY_SRC_COPY_BLT_WRITE_RGB);
+ 		break;
+ 	default:
+-		BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
++		BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
+ 		CMD = XY_SRC_COPY_BLT_CMD;
+ 		break;
+ 	}
+ 
++	if (nbox > I830_NR_SAREA_CLIPRECTS)
++		nbox = I830_NR_SAREA_CLIPRECTS;
+ 
+-      	if (nbox > I830_NR_SAREA_CLIPRECTS)
+-     		nbox = I830_NR_SAREA_CLIPRECTS;
+-
+-	for (i = 0 ; i < nbox; i++, pbox++) 
+-	{
++	for (i = 0; i < nbox; i++, pbox++) {
+ 		if (pbox->x1 > pbox->x2 ||
+ 		    pbox->y1 > pbox->y2 ||
+-		    pbox->x2 > dev_priv->w ||
+-		    pbox->y2 > dev_priv->h)
++		    pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
+ 			continue;
+- 
++
+ 		DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
+-			  pbox->x1, pbox->y1,
+-			  pbox->x2, pbox->y2);
++			  pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+ 
+-		BEGIN_LP_RING( 8 );
+-		OUT_RING( CMD );
+-		OUT_RING( BR13 );
+-		OUT_RING( (pbox->y1 << 16) | pbox->x1 );
+-		OUT_RING( (pbox->y2 << 16) | pbox->x2 );
++		BEGIN_LP_RING(8);
++		OUT_RING(CMD);
++		OUT_RING(BR13);
++		OUT_RING((pbox->y1 << 16) | pbox->x1);
++		OUT_RING((pbox->y2 << 16) | pbox->x2);
+ 
+-		if (dev_priv->current_page == 0) 
+-			OUT_RING( dev_priv->front_offset );
++		if (dev_priv->current_page == 0)
++			OUT_RING(dev_priv->front_offset);
+ 		else
+-			OUT_RING( dev_priv->back_offset );			
++			OUT_RING(dev_priv->back_offset);
+ 
+-		OUT_RING( (pbox->y1 << 16) | pbox->x1 );
+-		OUT_RING( BR13 & 0xffff );
++		OUT_RING((pbox->y1 << 16) | pbox->x1);
++		OUT_RING(BR13 & 0xffff);
+ 
+-		if (dev_priv->current_page == 0) 
+-			OUT_RING( dev_priv->back_offset );			
++		if (dev_priv->current_page == 0)
++			OUT_RING(dev_priv->back_offset);
+ 		else
+-			OUT_RING( dev_priv->front_offset );
++			OUT_RING(dev_priv->front_offset);
+ 
+ 		ADVANCE_LP_RING();
+ 	}
+ }
+ 
+-static void i830_dma_dispatch_flip( drm_device_t *dev )
++static void i830_dma_dispatch_flip(drm_device_t * dev)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	RING_LOCALS;
+ 
+-	DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", 
+-		   __FUNCTION__, 
+-		   dev_priv->current_page,
+-		   dev_priv->sarea_priv->pf_current_page);
++	DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
++		  __FUNCTION__,
++		  dev_priv->current_page,
++		  dev_priv->sarea_priv->pf_current_page);
+ 
+-  	i830_kernel_lost_context(dev);
++	i830_kernel_lost_context(dev);
+ 
+ 	if (dev_priv->do_boxes) {
+ 		dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP;
+-		i830_cp_performance_boxes( dev );
++		i830_cp_performance_boxes(dev);
+ 	}
+ 
+-
+-	BEGIN_LP_RING( 2 );
+-    	OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); 
+-	OUT_RING( 0 );
++	BEGIN_LP_RING(2);
++	OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
++	OUT_RING(0);
+ 	ADVANCE_LP_RING();
+ 
+-	BEGIN_LP_RING( 6 );
+-	OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP );	
+-	OUT_RING( 0 );
+-	if ( dev_priv->current_page == 0 ) {
+-		OUT_RING( dev_priv->back_offset );
++	BEGIN_LP_RING(6);
++	OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
++	OUT_RING(0);
++	if (dev_priv->current_page == 0) {
++		OUT_RING(dev_priv->back_offset);
+ 		dev_priv->current_page = 1;
+ 	} else {
+-		OUT_RING( dev_priv->front_offset );
++		OUT_RING(dev_priv->front_offset);
+ 		dev_priv->current_page = 0;
+ 	}
+ 	OUT_RING(0);
+ 	ADVANCE_LP_RING();
+ 
+-
+-	BEGIN_LP_RING( 2 );
+-	OUT_RING( MI_WAIT_FOR_EVENT |
+-		  MI_WAIT_FOR_PLANE_A_FLIP );
+-	OUT_RING( 0 );
++	BEGIN_LP_RING(2);
++	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
++	OUT_RING(0);
+ 	ADVANCE_LP_RING();
+-	
+ 
+ 	dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
+ }
+ 
+-static void i830_dma_dispatch_vertex(drm_device_t *dev, 
+-				     drm_buf_t *buf,
+-				     int discard,
+-				     int used)
++static void i830_dma_dispatch_vertex(drm_device_t * dev,
++				     drm_buf_t * buf, int discard, int used)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+-   	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+-   	drm_clip_rect_t *box = sarea_priv->boxes;
+-   	int nbox = sarea_priv->nbox;
++	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
++	drm_clip_rect_t *box = sarea_priv->boxes;
++	int nbox = sarea_priv->nbox;
+ 	unsigned long address = (unsigned long)buf->bus_address;
+-	unsigned long start = address - dev->agp->base;     
++	unsigned long start = address - dev->agp->base;
+ 	int i = 0, u;
+-   	RING_LOCALS;
++	RING_LOCALS;
+ 
+-   	i830_kernel_lost_context(dev);
++	i830_kernel_lost_context(dev);
+ 
+-   	if (nbox > I830_NR_SAREA_CLIPRECTS) 
++	if (nbox > I830_NR_SAREA_CLIPRECTS)
+ 		nbox = I830_NR_SAREA_CLIPRECTS;
+ 
+ 	if (discard) {
+-		u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, 
++		u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
+ 			    I830_BUF_HARDWARE);
+-		if(u != I830_BUF_CLIENT) {
++		if (u != I830_BUF_CLIENT) {
+ 			DRM_DEBUG("xxxx 2\n");
+ 		}
+ 	}
+ 
+-	if (used > 4*1023) 
++	if (used > 4 * 1023)
+ 		used = 0;
+ 
+ 	if (sarea_priv->dirty)
+-	   i830EmitState( dev );
++		i830EmitState(dev);
+ 
+-  	DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", 
++	DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
+ 		  address, used, nbox);
+ 
+-   	dev_priv->counter++;
+-   	DRM_DEBUG(  "dispatch counter : %ld\n", dev_priv->counter);
+-   	DRM_DEBUG(  "i830_dma_dispatch\n");
+-   	DRM_DEBUG(  "start : %lx\n", start);
+-	DRM_DEBUG(  "used : %d\n", used);
+-   	DRM_DEBUG(  "start + used - 4 : %ld\n", start + used - 4);
++	dev_priv->counter++;
++	DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter);
++	DRM_DEBUG("i830_dma_dispatch\n");
++	DRM_DEBUG("start : %lx\n", start);
++	DRM_DEBUG("used : %d\n", used);
++	DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4);
+ 
+ 	if (buf_priv->currently_mapped == I830_BUF_MAPPED) {
+ 		u32 *vp = buf_priv->kernel_virtual;
+ 
+ 		vp[0] = (GFX_OP_PRIMITIVE |
+-			sarea_priv->vertex_prim |
+-			((used/4)-2));
++			 sarea_priv->vertex_prim | ((used / 4) - 2));
+ 
+ 		if (dev_priv->use_mi_batchbuffer_start) {
+-			vp[used/4] = MI_BATCH_BUFFER_END;
+-			used += 4; 
++			vp[used / 4] = MI_BATCH_BUFFER_END;
++			used += 4;
+ 		}
+-		
++
+ 		if (used & 4) {
+-			vp[used/4] = 0;
++			vp[used / 4] = 0;
+ 			used += 4;
+ 		}
+ 
+ 		i830_unmap_buffer(buf);
+ 	}
+-		   
++
+ 	if (used) {
+ 		do {
+ 			if (i < nbox) {
+ 				BEGIN_LP_RING(6);
+-				OUT_RING( GFX_OP_DRAWRECT_INFO );
+-				OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR1] );
+-				OUT_RING( box[i].x1 | (box[i].y1<<16) );
+-				OUT_RING( box[i].x2 | (box[i].y2<<16) );
+-				OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR4] );
+-				OUT_RING( 0 );
++				OUT_RING(GFX_OP_DRAWRECT_INFO);
++				OUT_RING(sarea_priv->
++					 BufferState[I830_DESTREG_DR1]);
++				OUT_RING(box[i].x1 | (box[i].y1 << 16));
++				OUT_RING(box[i].x2 | (box[i].y2 << 16));
++				OUT_RING(sarea_priv->
++					 BufferState[I830_DESTREG_DR4]);
++				OUT_RING(0);
+ 				ADVANCE_LP_RING();
+ 			}
+ 
+ 			if (dev_priv->use_mi_batchbuffer_start) {
+ 				BEGIN_LP_RING(2);
+-				OUT_RING( MI_BATCH_BUFFER_START | (2<<6) );
+-				OUT_RING( start | MI_BATCH_NON_SECURE );
++				OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
++				OUT_RING(start | MI_BATCH_NON_SECURE);
+ 				ADVANCE_LP_RING();
+-			} 
+-			else {
++			} else {
+ 				BEGIN_LP_RING(4);
+-				OUT_RING( MI_BATCH_BUFFER );
+-				OUT_RING( start | MI_BATCH_NON_SECURE );
+-				OUT_RING( start + used - 4 );
+-				OUT_RING( 0 );
++				OUT_RING(MI_BATCH_BUFFER);
++				OUT_RING(start | MI_BATCH_NON_SECURE);
++				OUT_RING(start + used - 4);
++				OUT_RING(0);
+ 				ADVANCE_LP_RING();
+ 			}
+ 
+@@ -1195,61 +1174,60 @@ static void i830_dma_dispatch_vertex(drm
+ 	if (discard) {
+ 		dev_priv->counter++;
+ 
+-		(void) cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
+-			       I830_BUF_HARDWARE);
++		(void)cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
++			      I830_BUF_HARDWARE);
+ 
+ 		BEGIN_LP_RING(8);
+-		OUT_RING( CMD_STORE_DWORD_IDX );
+-		OUT_RING( 20 );
+-		OUT_RING( dev_priv->counter );
+-		OUT_RING( CMD_STORE_DWORD_IDX );
+-		OUT_RING( buf_priv->my_use_idx );
+-		OUT_RING( I830_BUF_FREE );
+-		OUT_RING( CMD_REPORT_HEAD );
+-		OUT_RING( 0 );
++		OUT_RING(CMD_STORE_DWORD_IDX);
++		OUT_RING(20);
++		OUT_RING(dev_priv->counter);
++		OUT_RING(CMD_STORE_DWORD_IDX);
++		OUT_RING(buf_priv->my_use_idx);
++		OUT_RING(I830_BUF_FREE);
++		OUT_RING(CMD_REPORT_HEAD);
++		OUT_RING(0);
+ 		ADVANCE_LP_RING();
+ 	}
+ }
+ 
+-
+-static void i830_dma_quiescent(drm_device_t *dev)
++static void i830_dma_quiescent(drm_device_t * dev)
+ {
+-      	drm_i830_private_t *dev_priv = dev->dev_private;
+-   	RING_LOCALS;
++	drm_i830_private_t *dev_priv = dev->dev_private;
++	RING_LOCALS;
+ 
+-  	i830_kernel_lost_context(dev);
++	i830_kernel_lost_context(dev);
+ 
+-   	BEGIN_LP_RING(4);
+-   	OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
+-   	OUT_RING( CMD_REPORT_HEAD );
+-      	OUT_RING( 0 );
+-      	OUT_RING( 0 );
+-   	ADVANCE_LP_RING();
++	BEGIN_LP_RING(4);
++	OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
++	OUT_RING(CMD_REPORT_HEAD);
++	OUT_RING(0);
++	OUT_RING(0);
++	ADVANCE_LP_RING();
+ 
+-	i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
++	i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
+ }
+ 
+-static int i830_flush_queue(drm_device_t *dev)
++static int i830_flush_queue(drm_device_t * dev)
+ {
+-   	drm_i830_private_t *dev_priv = dev->dev_private;
++	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	drm_device_dma_t *dma = dev->dma;
+-   	int i, ret = 0;
+-   	RING_LOCALS;
+-	
+-   	i830_kernel_lost_context(dev);
+-
+-   	BEGIN_LP_RING(2);
+-      	OUT_RING( CMD_REPORT_HEAD );
+-      	OUT_RING( 0 );
+-      	ADVANCE_LP_RING();
+-
+-	i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
+-
+-   	for (i = 0; i < dma->buf_count; i++) {
+-	   	drm_buf_t *buf = dma->buflist[ i ];
+-	   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+-	   
+-		int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE, 
++	int i, ret = 0;
++	RING_LOCALS;
++
++	i830_kernel_lost_context(dev);
++
++	BEGIN_LP_RING(2);
++	OUT_RING(CMD_REPORT_HEAD);
++	OUT_RING(0);
++	ADVANCE_LP_RING();
++
++	i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
++
++	for (i = 0; i < dma->buf_count; i++) {
++		drm_buf_t *buf = dma->buflist[i];
++		drm_i830_buf_priv_t *buf_priv = buf->dev_private;
++
++		int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE,
+ 				   I830_BUF_FREE);
+ 
+ 		if (used == I830_BUF_HARDWARE)
+@@ -1258,62 +1236,66 @@ static int i830_flush_queue(drm_device_t
+ 			DRM_DEBUG("still on client\n");
+ 	}
+ 
+-   	return ret;
++	return ret;
+ }
+ 
+ /* Must be called with the lock held */
+-void i830_reclaim_buffers(drm_device_t *dev, struct file *filp)
++void i830_reclaim_buffers(drm_device_t * dev, struct file *filp)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+-	int		 i;
++	int i;
+ 
+-	if (!dma) return;
+-      	if (!dev->dev_private) return;
+-	if (!dma->buflist) return;
++	if (!dma)
++		return;
++	if (!dev->dev_private)
++		return;
++	if (!dma->buflist)
++		return;
+ 
+-        i830_flush_queue(dev);
++	i830_flush_queue(dev);
+ 
+ 	for (i = 0; i < dma->buf_count; i++) {
+-	   	drm_buf_t *buf = dma->buflist[ i ];
+-	   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+-	   
++		drm_buf_t *buf = dma->buflist[i];
++		drm_i830_buf_priv_t *buf_priv = buf->dev_private;
++
+ 		if (buf->filp == filp && buf_priv) {
+-			int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, 
++			int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
+ 					   I830_BUF_FREE);
+ 
+ 			if (used == I830_BUF_CLIENT)
+ 				DRM_DEBUG("reclaimed from client\n");
+-		   	if(buf_priv->currently_mapped == I830_BUF_MAPPED)
+-		     		buf_priv->currently_mapped = I830_BUF_UNMAPPED;
++			if (buf_priv->currently_mapped == I830_BUF_MAPPED)
++				buf_priv->currently_mapped = I830_BUF_UNMAPPED;
+ 		}
+ 	}
+ }
+ 
+-static int i830_flush_ioctl(struct inode *inode, struct file *filp, 
+-			     unsigned int cmd, unsigned long arg)
++static int i830_flush_ioctl(struct inode *inode, struct file *filp,
++			    unsigned int cmd, unsigned long arg)
+ {
+-   	drm_file_t	  *priv	  = filp->private_data;
+-   	drm_device_t	  *dev	  = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-   	i830_flush_queue(dev);
+-   	return 0;
++	i830_flush_queue(dev);
++	return 0;
+ }
+ 
+ static int i830_dma_vertex(struct inode *inode, struct file *filp,
+-		       unsigned int cmd, unsigned long arg)
++			   unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_device_dma_t *dma = dev->dma;
+-   	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+-      	u32 *hw_status = dev_priv->hw_status_page;
+-   	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) 
+-     					dev_priv->sarea_priv; 
++	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
++	u32 *hw_status = dev_priv->hw_status_page;
++	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
++	    dev_priv->sarea_priv;
+ 	drm_i830_vertex_t vertex;
+ 
+-	if (copy_from_user(&vertex, (drm_i830_vertex_t __user *)arg, sizeof(vertex)))
++	if (copy_from_user
++	    (&vertex, (drm_i830_vertex_t __user *) arg, sizeof(vertex)))
+ 		return -EFAULT;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+@@ -1321,15 +1303,16 @@ static int i830_dma_vertex(struct inode 
+ 	DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n",
+ 		  vertex.idx, vertex.used, vertex.discard);
+ 
+-	if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
++	if (vertex.idx < 0 || vertex.idx > dma->buf_count)
++		return -EINVAL;
++
++	i830_dma_dispatch_vertex(dev,
++				 dma->buflist[vertex.idx],
++				 vertex.discard, vertex.used);
++
++	sarea_priv->last_enqueue = dev_priv->counter - 1;
++	sarea_priv->last_dispatch = (int)hw_status[5];
+ 
+-	i830_dma_dispatch_vertex( dev, 
+-				  dma->buflist[ vertex.idx ], 
+-				  vertex.discard, vertex.used );
+-
+-	sarea_priv->last_enqueue = dev_priv->counter-1;
+-   	sarea_priv->last_dispatch = (int) hw_status[5];
+-   
+ 	return 0;
+ }
+ 
+@@ -1340,9 +1323,10 @@ static int i830_clear_bufs(struct inode 
+ 	drm_device_t *dev = priv->head->dev;
+ 	drm_i830_clear_t clear;
+ 
+-   	if (copy_from_user(&clear, (drm_i830_clear_t __user *)arg, sizeof(clear)))
++	if (copy_from_user
++	    (&clear, (drm_i830_clear_t __user *) arg, sizeof(clear)))
+ 		return -EFAULT;
+-   
++
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+ 	/* GH: Someone's doing nasty things... */
+@@ -1350,11 +1334,10 @@ static int i830_clear_bufs(struct inode 
+ 		return -EINVAL;
+ 	}
+ 
+-	i830_dma_dispatch_clear( dev, clear.flags, 
+-				 clear.clear_color, 
+-				 clear.clear_depth,
+-			         clear.clear_depthmask);
+-   	return 0;
++	i830_dma_dispatch_clear(dev, clear.flags,
++				clear.clear_color,
++				clear.clear_depth, clear.clear_depthmask);
++	return 0;
+ }
+ 
+ static int i830_swap_bufs(struct inode *inode, struct file *filp,
+@@ -1362,20 +1345,18 @@ static int i830_swap_bufs(struct inode *
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+-   
++
+ 	DRM_DEBUG("i830_swap_bufs\n");
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	i830_dma_dispatch_swap( dev );
+-   	return 0;
++	i830_dma_dispatch_swap(dev);
++	return 0;
+ }
+ 
+-
+-
+ /* Not sure why this isn't set all the time:
+- */ 
+-static void i830_do_init_pageflip( drm_device_t *dev )
++ */
++static void i830_do_init_pageflip(drm_device_t * dev)
+ {
+ 	drm_i830_private_t *dev_priv = dev->dev_private;
+ 
+@@ -1385,20 +1366,20 @@ static void i830_do_init_pageflip( drm_d
+ 	dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
+ }
+ 
+-static int i830_do_cleanup_pageflip( drm_device_t *dev )
++static int i830_do_cleanup_pageflip(drm_device_t * dev)
+ {
+ 	drm_i830_private_t *dev_priv = dev->dev_private;
+ 
+ 	DRM_DEBUG("%s\n", __FUNCTION__);
+ 	if (dev_priv->current_page != 0)
+-		i830_dma_dispatch_flip( dev );
++		i830_dma_dispatch_flip(dev);
+ 
+ 	dev_priv->page_flipping = 0;
+ 	return 0;
+ }
+ 
+ static int i830_flip_bufs(struct inode *inode, struct file *filp,
+-			   unsigned int cmd, unsigned long arg)
++			  unsigned int cmd, unsigned long arg)
+ {
+ 	drm_file_t *priv = filp->private_data;
+ 	drm_device_t *dev = priv->head->dev;
+@@ -1408,45 +1389,45 @@ static int i830_flip_bufs(struct inode *
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if (!dev_priv->page_flipping) 
+-		i830_do_init_pageflip( dev );
++	if (!dev_priv->page_flipping)
++		i830_do_init_pageflip(dev);
+ 
+-	i830_dma_dispatch_flip( dev );
+-   	return 0;
++	i830_dma_dispatch_flip(dev);
++	return 0;
+ }
+ 
+ static int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
+-			unsigned long arg)
++		       unsigned long arg)
+ {
+-   	drm_file_t	  *priv	    = filp->private_data;
+-	drm_device_t	  *dev	    = priv->head->dev;
+-   	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+-      	u32 *hw_status = dev_priv->hw_status_page;
+-   	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) 
+-     					dev_priv->sarea_priv; 
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
++	u32 *hw_status = dev_priv->hw_status_page;
++	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
++	    dev_priv->sarea_priv;
+ 
+-      	sarea_priv->last_dispatch = (int) hw_status[5];
++	sarea_priv->last_dispatch = (int)hw_status[5];
+ 	return 0;
+ }
+ 
+ static int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
+-			unsigned long arg)
++		       unsigned long arg)
+ {
+-	drm_file_t	  *priv	    = filp->private_data;
+-	drm_device_t	  *dev	    = priv->head->dev;
+-	int		  retcode   = 0;
+-	drm_i830_dma_t	  d;
+-   	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+-   	u32 *hw_status = dev_priv->hw_status_page;
+-   	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) 
+-     					dev_priv->sarea_priv; 
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
++	int retcode = 0;
++	drm_i830_dma_t d;
++	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
++	u32 *hw_status = dev_priv->hw_status_page;
++	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
++	    dev_priv->sarea_priv;
+ 
+ 	DRM_DEBUG("getbuf\n");
+-   	if (copy_from_user(&d, (drm_i830_dma_t __user *)arg, sizeof(d)))
++	if (copy_from_user(&d, (drm_i830_dma_t __user *) arg, sizeof(d)))
+ 		return -EFAULT;
+-   
++
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+-	
++
+ 	d.granted = 0;
+ 
+ 	retcode = i830_dma_get_buffer(dev, &d, filp);
+@@ -1454,46 +1435,45 @@ static int i830_getbuf(struct inode *ino
+ 	DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",
+ 		  current->pid, retcode, d.granted);
+ 
+-	if (copy_to_user((drm_dma_t __user *)arg, &d, sizeof(d)))
++	if (copy_to_user((drm_dma_t __user *) arg, &d, sizeof(d)))
+ 		return -EFAULT;
+-   	sarea_priv->last_dispatch = (int) hw_status[5];
++	sarea_priv->last_dispatch = (int)hw_status[5];
+ 
+ 	return retcode;
+ }
+ 
+ static int i830_copybuf(struct inode *inode,
+-			 struct file *filp, unsigned int cmd, unsigned long arg)
++			struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ 	/* Never copy - 2.4.x doesn't need it */
+ 	return 0;
+ }
+ 
+ static int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
+-			unsigned long arg)
++		       unsigned long arg)
+ {
+ 	return 0;
+ }
+ 
+-
+-
+-static int i830_getparam( struct inode *inode, struct file *filp, 
+-			unsigned int cmd, unsigned long arg )
++static int i830_getparam(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	  *priv	    = filp->private_data;
+-	drm_device_t	  *dev	    = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	drm_i830_getparam_t param;
+ 	int value;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return -EINVAL;
+ 	}
+ 
+-	if (copy_from_user(&param, (drm_i830_getparam_t __user *)arg, sizeof(param) ))
++	if (copy_from_user
++	    (&param, (drm_i830_getparam_t __user *) arg, sizeof(param)))
+ 		return -EFAULT;
+ 
+-	switch( param.param ) {
++	switch (param.param) {
+ 	case I830_PARAM_IRQ_ACTIVE:
+ 		value = dev->irq_enabled;
+ 		break;
+@@ -1501,32 +1481,32 @@ static int i830_getparam( struct inode *
+ 		return -EINVAL;
+ 	}
+ 
+-	if ( copy_to_user( param.value, &value, sizeof(int) ) ) {
+-		DRM_ERROR( "copy_to_user\n" );
++	if (copy_to_user(param.value, &value, sizeof(int))) {
++		DRM_ERROR("copy_to_user\n");
+ 		return -EFAULT;
+ 	}
+-	
++
+ 	return 0;
+ }
+ 
+-
+-static int i830_setparam( struct inode *inode, struct file *filp,
+-			unsigned int cmd, unsigned long arg )
++static int i830_setparam(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg)
+ {
+-	drm_file_t	  *priv	    = filp->private_data;
+-	drm_device_t	  *dev	    = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	drm_i830_setparam_t param;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return -EINVAL;
+ 	}
+ 
+-	if (copy_from_user(&param, (drm_i830_setparam_t __user *)arg, sizeof(param) ))
++	if (copy_from_user
++	    (&param, (drm_i830_setparam_t __user *) arg, sizeof(param)))
+ 		return -EFAULT;
+ 
+-	switch( param.param ) {
++	switch (param.param) {
+ 	case I830_SETPARAM_USE_MI_BATCHBUFFER_START:
+ 		dev_priv->use_mi_batchbuffer_start = param.value;
+ 		break;
+@@ -1537,13 +1517,12 @@ static int i830_setparam( struct inode *
+ 	return 0;
+ }
+ 
+-
+-void i830_driver_pretakedown(drm_device_t *dev)
++void i830_driver_pretakedown(drm_device_t * dev)
+ {
+-	i830_dma_cleanup( dev );
++	i830_dma_cleanup(dev);
+ }
+ 
+-void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp)
++void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+ {
+ 	if (dev->dev_private) {
+ 		drm_i830_private_t *dev_priv = dev->dev_private;
+@@ -1553,32 +1532,32 @@ void i830_driver_prerelease(drm_device_t
+ 	}
+ }
+ 
+-void i830_driver_release(drm_device_t *dev, struct file *filp)
++void i830_driver_release(drm_device_t * dev, struct file *filp)
+ {
+ 	i830_reclaim_buffers(dev, filp);
+ }
+ 
+-int i830_driver_dma_quiescent(drm_device_t *dev)
++int i830_driver_dma_quiescent(drm_device_t * dev)
+ {
+-	i830_dma_quiescent( dev );
++	i830_dma_quiescent(dev);
+ 	return 0;
+ }
+ 
+ drm_ioctl_desc_t i830_ioctls[] = {
+-	[DRM_IOCTL_NR(DRM_I830_INIT)]     = { i830_dma_init,    1, 1 },
+-	[DRM_IOCTL_NR(DRM_I830_VERTEX)]   = { i830_dma_vertex,  1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_CLEAR)]    = { i830_clear_bufs,  1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_FLUSH)]    = { i830_flush_ioctl, 1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_GETAGE)]   = { i830_getage,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_GETBUF)]   = { i830_getbuf,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_SWAP)]     = { i830_swap_bufs,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_COPY)]     = { i830_copybuf,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_DOCOPY)]   = { i830_docopy,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_FLIP)]     = { i830_flip_bufs,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = { i830_irq_emit,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = { i830_irq_wait,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_GETPARAM)] = { i830_getparam,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_I830_SETPARAM)] = { i830_setparam,    1, 0 } 
++	[DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1},
++	[DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0},
++	[DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, 1, 0}
+ };
+ 
+ int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
+diff --git a/drivers/char/drm/i830_drm.h b/drivers/char/drm/i830_drm.h
+--- a/drivers/char/drm/i830_drm.h
++++ b/drivers/char/drm/i830_drm.h
+@@ -33,14 +33,14 @@
+ #define I830_UPLOAD_CTX			0x1
+ #define I830_UPLOAD_BUFFERS		0x2
+ #define I830_UPLOAD_CLIPRECTS		0x4
+-#define I830_UPLOAD_TEX0_IMAGE		0x100 /* handled clientside */
+-#define I830_UPLOAD_TEX0_CUBE		0x200 /* handled clientside */
+-#define I830_UPLOAD_TEX1_IMAGE		0x400 /* handled clientside */
+-#define I830_UPLOAD_TEX1_CUBE		0x800 /* handled clientside */
+-#define I830_UPLOAD_TEX2_IMAGE		0x1000 /* handled clientside */
+-#define I830_UPLOAD_TEX2_CUBE		0x2000 /* handled clientside */
+-#define I830_UPLOAD_TEX3_IMAGE		0x4000 /* handled clientside */
+-#define I830_UPLOAD_TEX3_CUBE		0x8000 /* handled clientside */
++#define I830_UPLOAD_TEX0_IMAGE		0x100	/* handled clientside */
++#define I830_UPLOAD_TEX0_CUBE		0x200	/* handled clientside */
++#define I830_UPLOAD_TEX1_IMAGE		0x400	/* handled clientside */
++#define I830_UPLOAD_TEX1_CUBE		0x800	/* handled clientside */
++#define I830_UPLOAD_TEX2_IMAGE		0x1000	/* handled clientside */
++#define I830_UPLOAD_TEX2_CUBE		0x2000	/* handled clientside */
++#define I830_UPLOAD_TEX3_IMAGE		0x4000	/* handled clientside */
++#define I830_UPLOAD_TEX3_CUBE		0x8000	/* handled clientside */
+ #define I830_UPLOAD_TEX_N_IMAGE(n)	(0x100 << (n * 2))
+ #define I830_UPLOAD_TEX_N_CUBE(n)	(0x200 << (n * 2))
+ #define I830_UPLOAD_TEXIMAGE_MASK	0xff00
+@@ -65,7 +65,7 @@
+  * or in a piecewise fashion as required.
+  */
+ 
+-/* Destbuffer state 
++/* Destbuffer state
+  *    - backbuffer linear offset and pitch -- invarient in the current dri
+  *    - zbuffer linear offset and pitch -- also invarient
+  *    - drawing origin in back and depth buffers.
+@@ -103,7 +103,7 @@
+ #define I830_CTXREG_AA			9
+ #define I830_CTXREG_FOGCOLOR		10
+ #define I830_CTXREG_BLENDCOLR0		11
+-#define I830_CTXREG_BLENDCOLR		12 /* Dword 1 of 2 dword command */
++#define I830_CTXREG_BLENDCOLR		12	/* Dword 1 of 2 dword command */
+ #define I830_CTXREG_VF			13
+ #define I830_CTXREG_VF2			14
+ #define I830_CTXREG_MCSB0		15
+@@ -111,12 +111,11 @@
+ #define I830_CTX_SETUP_SIZE		17
+ 
+ /* 1.3: Stipple state
+- */ 
++ */
+ #define I830_STPREG_ST0 0
+ #define I830_STPREG_ST1 1
+ #define I830_STP_SETUP_SIZE 2
+ 
+-
+ /* Texture state (per tex unit)
+  */
+ 
+@@ -132,23 +131,23 @@
+ #define I830_TEXREG_MCS	9	/* GFX_OP_MAP_COORD_SETS */
+ #define I830_TEX_SETUP_SIZE 10
+ 
+-#define I830_TEXREG_TM0LI      0 /* load immediate 2 texture map n */
++#define I830_TEXREG_TM0LI      0	/* load immediate 2 texture map n */
+ #define I830_TEXREG_TM0S0      1
+ #define I830_TEXREG_TM0S1      2
+ #define I830_TEXREG_TM0S2      3
+ #define I830_TEXREG_TM0S3      4
+ #define I830_TEXREG_TM0S4      5
+-#define I830_TEXREG_NOP0       6       /* noop */
+-#define I830_TEXREG_NOP1       7       /* noop */
+-#define I830_TEXREG_NOP2       8       /* noop */
+-#define __I830_TEXREG_MCS      9       /* GFX_OP_MAP_COORD_SETS -- shared */
++#define I830_TEXREG_NOP0       6	/* noop */
++#define I830_TEXREG_NOP1       7	/* noop */
++#define I830_TEXREG_NOP2       8	/* noop */
++#define __I830_TEXREG_MCS      9	/* GFX_OP_MAP_COORD_SETS -- shared */
+ #define __I830_TEX_SETUP_SIZE   10
+ 
+ #define I830_FRONT   0x1
+ #define I830_BACK    0x2
+ #define I830_DEPTH   0x4
+ 
+-#endif /* _I830_DEFINES_ */
++#endif				/* _I830_DEFINES_ */
+ 
+ typedef struct _drm_i830_init {
+ 	enum {
+@@ -177,19 +176,19 @@ typedef struct _drm_i830_init {
+  * structure as well */
+ 
+ typedef struct _drm_i830_tex_region {
+-	unsigned char next, prev; /* indices to form a circular LRU  */
++	unsigned char next, prev;	/* indices to form a circular LRU  */
+ 	unsigned char in_use;	/* owned by a client, or free? */
+ 	int age;		/* tracked by clients to update local LRU's */
+ } drm_i830_tex_region_t;
+ 
+ typedef struct _drm_i830_sarea {
+ 	unsigned int ContextState[I830_CTX_SETUP_SIZE];
+-   	unsigned int BufferState[I830_DEST_SETUP_SIZE];
++	unsigned int BufferState[I830_DEST_SETUP_SIZE];
+ 	unsigned int TexState[I830_TEXTURE_COUNT][I830_TEX_SETUP_SIZE];
+ 	unsigned int TexBlendState[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE];
+ 	unsigned int TexBlendStateWordsUsed[I830_TEXBLEND_COUNT];
+ 	unsigned int Palette[2][256];
+-   	unsigned int dirty;
++	unsigned int dirty;
+ 
+ 	unsigned int nbox;
+ 	drm_clip_rect_t boxes[I830_NR_SAREA_CLIPRECTS];
+@@ -207,26 +206,26 @@ typedef struct _drm_i830_sarea {
+ 	 * texture space, and can make informed decisions as to which
+ 	 * areas to kick out.  There is no need to choose whether to
+ 	 * kick out your own texture or someone else's - simply eject
+-	 * them all in LRU order.  
++	 * them all in LRU order.
+ 	 */
+ 
+-	drm_i830_tex_region_t texList[I830_NR_TEX_REGIONS+1]; 
+-				/* Last elt is sentinal */
+-        int texAge;		/* last time texture was uploaded */
+-        int last_enqueue;	/* last time a buffer was enqueued */
++	drm_i830_tex_region_t texList[I830_NR_TEX_REGIONS + 1];
++	/* Last elt is sentinal */
++	int texAge;		/* last time texture was uploaded */
++	int last_enqueue;	/* last time a buffer was enqueued */
+ 	int last_dispatch;	/* age of the most recently dispatched buffer */
+-	int last_quiescent;     /*  */
++	int last_quiescent;	/*  */
+ 	int ctxOwner;		/* last context to upload state */
+ 
+ 	int vertex_prim;
+ 
+-        int pf_enabled;               /* is pageflipping allowed? */
+-        int pf_active;               
+-        int pf_current_page;	    /* which buffer is being displayed? */
+-
+-        int perf_boxes;             /* performance boxes to be displayed */
+-   
+-        /* Here's the state for texunits 2,3:
++	int pf_enabled;		/* is pageflipping allowed? */
++	int pf_active;
++	int pf_current_page;	/* which buffer is being displayed? */
++
++	int perf_boxes;		/* performance boxes to be displayed */
++
++	/* Here's the state for texunits 2,3:
+ 	 */
+ 	unsigned int TexState2[I830_TEX_SETUP_SIZE];
+ 	unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
+@@ -241,12 +240,11 @@ typedef struct _drm_i830_sarea {
+ 
+ /* Flags for perf_boxes
+  */
+-#define I830_BOX_RING_EMPTY    0x1 /* populated by kernel */
+-#define I830_BOX_FLIP          0x2 /* populated by kernel */
+-#define I830_BOX_WAIT          0x4 /* populated by kernel & client */
+-#define I830_BOX_TEXTURE_LOAD  0x8 /* populated by kernel */
+-#define I830_BOX_LOST_CONTEXT  0x10 /* populated by client */
+-
++#define I830_BOX_RING_EMPTY    0x1	/* populated by kernel */
++#define I830_BOX_FLIP          0x2	/* populated by kernel */
++#define I830_BOX_WAIT          0x4	/* populated by kernel & client */
++#define I830_BOX_TEXTURE_LOAD  0x8	/* populated by kernel */
++#define I830_BOX_LOST_CONTEXT  0x10	/* populated by client */
+ 
+ /* I830 specific ioctls
+  * The device specific ioctl range is 0x40 to 0x79.
+@@ -289,23 +287,21 @@ typedef struct _drm_i830_clear {
+ 	unsigned int clear_depthmask;
+ } drm_i830_clear_t;
+ 
+-
+-
+ /* These may be placeholders if we have more cliprects than
+  * I830_NR_SAREA_CLIPRECTS.  In that case, the client sets discard to
+  * false, indicating that the buffer will be dispatched again with a
+  * new set of cliprects.
+  */
+ typedef struct _drm_i830_vertex {
+-   	int idx;		/* buffer index */
++	int idx;		/* buffer index */
+ 	int used;		/* nr bytes in use */
+ 	int discard;		/* client is finished with the buffer? */
+ } drm_i830_vertex_t;
+ 
+ typedef struct _drm_i830_copy_t {
+-   	int idx;		/* buffer index */
++	int idx;		/* buffer index */
+ 	int used;		/* nr bytes in use */
+-	void __user *address;		/* Address to copy from */
++	void __user *address;	/* Address to copy from */
+ } drm_i830_copy_t;
+ 
+ typedef struct drm_i830_dma {
+@@ -315,7 +311,6 @@ typedef struct drm_i830_dma {
+ 	int granted;
+ } drm_i830_dma_t;
+ 
+-
+ /* 1.3: Userspace can request & wait on irq's:
+  */
+ typedef struct drm_i830_irq_emit {
+@@ -326,7 +321,6 @@ typedef struct drm_i830_irq_wait {
+ 	int irq_seq;
+ } drm_i830_irq_wait_t;
+ 
+-
+ /* 1.3: New ioctl to query kernel params:
+  */
+ #define I830_PARAM_IRQ_ACTIVE            1
+@@ -336,7 +330,6 @@ typedef struct drm_i830_getparam {
+ 	int __user *value;
+ } drm_i830_getparam_t;
+ 
+-
+ /* 1.3: New ioctl to set kernel params:
+  */
+ #define I830_SETPARAM_USE_MI_BATCHBUFFER_START            1
+@@ -346,5 +339,4 @@ typedef struct drm_i830_setparam {
+ 	int value;
+ } drm_i830_setparam_t;
+ 
+-
+-#endif /* _I830_DRM_H_ */
++#endif				/* _I830_DRM_H_ */
+diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
+--- a/drivers/char/drm/i830_drv.c
++++ b/drivers/char/drm/i830_drv.c
+@@ -40,36 +40,34 @@
+ 
+ #include "drm_pciids.h"
+ 
+-static int postinit( struct drm_device *dev, unsigned long flags )
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+ 	dev->counters += 4;
+ 	dev->types[6] = _DRM_STAT_IRQ;
+ 	dev->types[7] = _DRM_STAT_PRIMARY;
+ 	dev->types[8] = _DRM_STAT_SECONDARY;
+ 	dev->types[9] = _DRM_STAT_DMA;
+-	
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->primary.minor,
+-		pci_pretty_name(dev->pdev)
+-		);
++
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR,
++		 DRIVER_PATCHLEVEL,
++		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
++	    );
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+@@ -77,11 +75,10 @@ static struct pci_device_id pciidlist[] 
+ 	i830_PCI_IDS
+ };
+ 
+-extern drm_ioctl_desc_t i830_ioctls[];
+-extern int i830_max_ioctl;
+-
+ static struct drm_driver driver = {
+-	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
++	.driver_features =
++	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
++	    DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
+ #if USE_IRQS
+ 	.driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ,
+ #endif
+@@ -104,18 +101,19 @@ static struct drm_driver driver = {
+ 	.version = version,
+ 	.ioctls = i830_ioctls,
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
+-	},
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
++		 }
++	,
+ 	.pci_driver = {
+-		.name          = DRIVER_NAME,
+-		.id_table      = pciidlist,
+-	}
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
+ 
+ };
+ 
+@@ -133,6 +131,6 @@ static void __exit i830_exit(void)
+ module_init(i830_init);
+ module_exit(i830_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
+--- a/drivers/char/drm/i830_drv.h
++++ b/drivers/char/drm/i830_drv.h
+@@ -11,11 +11,11 @@
+  * 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 (including the next
+  * paragraph) 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
+@@ -63,14 +63,14 @@
+ #define USE_IRQS 0
+ 
+ typedef struct drm_i830_buf_priv {
+-   	u32 *in_use;
+-   	int my_use_idx;
++	u32 *in_use;
++	int my_use_idx;
+ 	int currently_mapped;
+ 	void __user *virtual;
+ 	void *kernel_virtual;
+ } drm_i830_buf_priv_t;
+ 
+-typedef struct _drm_i830_ring_buffer{
++typedef struct _drm_i830_ring_buffer {
+ 	int tail_mask;
+ 	unsigned long Start;
+ 	unsigned long End;
+@@ -86,17 +86,17 @@ typedef struct drm_i830_private {
+ 	drm_map_t *mmio_map;
+ 
+ 	drm_i830_sarea_t *sarea_priv;
+-   	drm_i830_ring_buffer_t ring;
++	drm_i830_ring_buffer_t ring;
+ 
+-      	void * hw_status_page;
+-   	unsigned long counter;
++	void *hw_status_page;
++	unsigned long counter;
+ 
+ 	dma_addr_t dma_status_page;
+ 
+ 	drm_buf_t *mmap_buffer;
+-	
++
+ 	u32 front_di1, back_di1, zi1;
+-	
++
+ 	int back_offset;
+ 	int depth_offset;
+ 	int front_offset;
+@@ -113,43 +113,39 @@ typedef struct drm_i830_private {
+ 	int page_flipping;
+ 
+ 	wait_queue_head_t irq_queue;
+-   	atomic_t irq_received;
+-   	atomic_t irq_emitted;
++	atomic_t irq_received;
++	atomic_t irq_emitted;
+ 
+ 	int use_mi_batchbuffer_start;
+ 
+ } drm_i830_private_t;
+ 
++extern drm_ioctl_desc_t i830_ioctls[];
++extern int i830_max_ioctl;
++
+ /* i830_dma.c */
+-extern void i830_reclaim_buffers(drm_device_t *dev, struct file *filp);
++extern void i830_reclaim_buffers(drm_device_t * dev, struct file *filp);
+ 
+ /* i830_irq.c */
+-extern int i830_irq_emit( struct inode *inode, struct file *filp, 
+-			  unsigned int cmd, unsigned long arg );
+-extern int i830_irq_wait( struct inode *inode, struct file *filp,
+-			  unsigned int cmd, unsigned long arg );
+-
+-extern irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS );
+-extern void i830_driver_irq_preinstall( drm_device_t *dev );
+-extern void i830_driver_irq_postinstall( drm_device_t *dev );
+-extern void i830_driver_irq_uninstall( drm_device_t *dev );
+-extern void i830_driver_pretakedown(drm_device_t *dev);
+-extern void i830_driver_release(drm_device_t *dev, struct file *filp);
+-extern int i830_driver_dma_quiescent(drm_device_t *dev);
+-extern void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp);
++extern int i830_irq_emit(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg);
++extern int i830_irq_wait(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg);
++
++extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS);
++extern void i830_driver_irq_preinstall(drm_device_t * dev);
++extern void i830_driver_irq_postinstall(drm_device_t * dev);
++extern void i830_driver_irq_uninstall(drm_device_t * dev);
++extern void i830_driver_pretakedown(drm_device_t * dev);
++extern void i830_driver_release(drm_device_t * dev, struct file *filp);
++extern int i830_driver_dma_quiescent(drm_device_t * dev);
++extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+ extern int i830_driver_device_is_agp(drm_device_t * dev);
+ 
+-#define I830_BASE(reg)		((unsigned long) \
+-				dev_priv->mmio_map->handle)
+-#define I830_ADDR(reg)		(I830_BASE(reg) + reg)
+-#define I830_DEREF(reg)		*(__volatile__ unsigned int *)I830_ADDR(reg)
+-#define I830_READ(reg)		readl((volatile u32 *)I830_ADDR(reg))
+-#define I830_WRITE(reg,val) 	writel(val, (volatile u32 *)I830_ADDR(reg))
+-#define I830_DEREF16(reg)	*(__volatile__ u16 *)I830_ADDR(reg)
+-#define I830_READ16(reg) 	I830_DEREF16(reg)
+-#define I830_WRITE16(reg,val)	do { I830_DEREF16(reg) = val; } while (0)
+-
+-
++#define I830_READ(reg)          DRM_READ32(dev_priv->mmio_map, reg)
++#define I830_WRITE(reg,val)     DRM_WRITE32(dev_priv->mmio_map, reg, val)
++#define I830_READ16(reg)        DRM_READ16(dev_priv->mmio_map, reg)
++#define I830_WRITE16(reg,val)   DRM_WRITE16(dev_priv->mmio_map, reg, val)
+ 
+ #define I830_VERBOSE 0
+ 
+@@ -168,7 +164,6 @@ extern int i830_driver_device_is_agp(drm
+ 	virt = dev_priv->ring.virtual_start;		\
+ } while (0)
+ 
+-
+ #define OUT_RING(n) do {					\
+ 	if (I830_VERBOSE) printk("   OUT_RING %x\n", (int)(n));	\
+ 	*(volatile unsigned int *)(virt + outring) = n;		\
+@@ -184,8 +179,7 @@ extern int i830_driver_device_is_agp(drm
+ 	I830_WRITE(LP_RING + RING_TAIL, outring);			\
+ } while(0)
+ 
+-extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
+-
++extern int i830_wait_ring(drm_device_t * dev, int n, const char *caller);
+ 
+ #define GFX_OP_USER_INTERRUPT 		((0<<29)|(2<<23))
+ #define GFX_OP_BREAKPOINT_INTERRUPT	((0<<29)|(1<<23))
+@@ -200,7 +194,6 @@ extern int i830_wait_ring(drm_device_t *
+ #define INST_OP_FLUSH        0x02000000
+ #define INST_FLUSH_MAP_CACHE 0x00000001
+ 
+-
+ #define BB1_START_ADDR_MASK   (~0x7)
+ #define BB1_PROTECTED         (1<<0)
+ #define BB1_UNPROTECTED       (0<<0)
+@@ -213,7 +206,6 @@ extern int i830_wait_ring(drm_device_t *
+ 
+ #define I830_IRQ_RESERVED ((1<<13)|(3<<2))
+ 
+-
+ #define LP_RING     		0x2030
+ #define HP_RING     		0x2040
+ #define RING_TAIL      		0x00
+@@ -225,7 +217,7 @@ extern int i830_wait_ring(drm_device_t *
+ #define RING_START     		0x08
+ #define START_ADDR          	0x0xFFFFF000
+ #define RING_LEN       		0x0C
+-#define RING_NR_PAGES       	0x001FF000 
++#define RING_NR_PAGES       	0x001FF000
+ #define RING_REPORT_MASK    	0x00000006
+ #define RING_REPORT_64K     	0x00000002
+ #define RING_REPORT_128K    	0x00000004
+@@ -291,10 +283,9 @@ extern int i830_wait_ring(drm_device_t *
+ #define MI_BATCH_NON_SECURE	(1)
+ 
+ #define MI_WAIT_FOR_EVENT       ((0x3<<23))
+-#define MI_WAIT_FOR_PLANE_A_FLIP      (1<<2) 
+-#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) 
++#define MI_WAIT_FOR_PLANE_A_FLIP      (1<<2)
++#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
+ 
+ #define MI_LOAD_SCAN_LINES_INCL  ((0x12<<23))
+ 
+ #endif
+-
+diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c
+--- a/drivers/char/drm/i830_irq.c
++++ b/drivers/char/drm/i830_irq.c
+@@ -9,11 +9,11 @@
+  * 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 (including the next
+  * paragraph) 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
+@@ -33,28 +33,27 @@
+ #include <linux/interrupt.h>	/* For task queue support */
+ #include <linux/delay.h>
+ 
+-
+-irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS )
++irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS)
+ {
+-	drm_device_t	 *dev = (drm_device_t *)arg;
+-      	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+-   	u16 temp;
++	drm_device_t *dev = (drm_device_t *) arg;
++	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
++	u16 temp;
+ 
+-      	temp = I830_READ16(I830REG_INT_IDENTITY_R);
++	temp = I830_READ16(I830REG_INT_IDENTITY_R);
+ 	DRM_DEBUG("%x\n", temp);
+ 
+-   	if ( !( temp & 2 ) ) 
++	if (!(temp & 2))
+ 		return IRQ_NONE;
+ 
+-	I830_WRITE16(I830REG_INT_IDENTITY_R, temp); 
++	I830_WRITE16(I830REG_INT_IDENTITY_R, temp);
+ 
+ 	atomic_inc(&dev_priv->irq_received);
+-	wake_up_interruptible(&dev_priv->irq_queue); 
++	wake_up_interruptible(&dev_priv->irq_queue);
+ 
+ 	return IRQ_HANDLED;
+ }
+ 
+-static int i830_emit_irq(drm_device_t *dev)
++static int i830_emit_irq(drm_device_t * dev)
+ {
+ 	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	RING_LOCALS;
+@@ -63,27 +62,25 @@ static int i830_emit_irq(drm_device_t *d
+ 
+ 	atomic_inc(&dev_priv->irq_emitted);
+ 
+-   	BEGIN_LP_RING(2);
+-      	OUT_RING( 0 );
+-      	OUT_RING( GFX_OP_USER_INTERRUPT );
+-      	ADVANCE_LP_RING();
++	BEGIN_LP_RING(2);
++	OUT_RING(0);
++	OUT_RING(GFX_OP_USER_INTERRUPT);
++	ADVANCE_LP_RING();
+ 
+ 	return atomic_read(&dev_priv->irq_emitted);
+ }
+ 
+-
+-static int i830_wait_irq(drm_device_t *dev, int irq_nr)
++static int i830_wait_irq(drm_device_t * dev, int irq_nr)
+ {
+-  	drm_i830_private_t *dev_priv = 
+-	   (drm_i830_private_t *)dev->dev_private;
++	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
+ 	DECLARE_WAITQUEUE(entry, current);
+-	unsigned long end = jiffies + HZ*3;
++	unsigned long end = jiffies + HZ * 3;
+ 	int ret = 0;
+ 
+ 	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+- 	if (atomic_read(&dev_priv->irq_received) >= irq_nr)  
+- 		return 0; 
++	if (atomic_read(&dev_priv->irq_received) >= irq_nr)
++		return 0;
+ 
+ 	dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
+ 
+@@ -91,21 +88,21 @@ static int i830_wait_irq(drm_device_t *d
+ 
+ 	for (;;) {
+ 		__set_current_state(TASK_INTERRUPTIBLE);
+-	   	if (atomic_read(&dev_priv->irq_received) >= irq_nr) 
+-		   break;
+-		if((signed)(end - jiffies) <= 0) {
++		if (atomic_read(&dev_priv->irq_received) >= irq_nr)
++			break;
++		if ((signed)(end - jiffies) <= 0) {
+ 			DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n",
+-				  I830_READ16( I830REG_INT_IDENTITY_R ),
+-				  I830_READ16( I830REG_INT_MASK_R ),
+-				  I830_READ16( I830REG_INT_ENABLE_R ),
+-				  I830_READ16( I830REG_HWSTAM ));
++				  I830_READ16(I830REG_INT_IDENTITY_R),
++				  I830_READ16(I830REG_INT_MASK_R),
++				  I830_READ16(I830REG_INT_ENABLE_R),
++				  I830_READ16(I830REG_HWSTAM));
+ 
+-		   	ret = -EBUSY;	/* Lockup?  Missed irq? */
++			ret = -EBUSY;	/* Lockup?  Missed irq? */
+ 			break;
+ 		}
+-	      	schedule_timeout(HZ*3);
+-	      	if (signal_pending(current)) {
+-		   	ret = -EINTR;
++		schedule_timeout(HZ * 3);
++		if (signal_pending(current)) {
++			ret = -EINTR;
+ 			break;
+ 		}
+ 	}
+@@ -115,89 +112,87 @@ static int i830_wait_irq(drm_device_t *d
+ 	return ret;
+ }
+ 
+-
+ /* Needs the lock as it touches the ring.
+  */
+-int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd,
+-		   unsigned long arg )
++int i830_irq_emit(struct inode *inode, struct file *filp, unsigned int cmd,
++		  unsigned long arg)
+ {
+-	drm_file_t	  *priv	    = filp->private_data;
+-	drm_device_t	  *dev	    = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	drm_i830_irq_emit_t emit;
+ 	int result;
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return -EINVAL;
+ 	}
+ 
+-	if (copy_from_user( &emit, (drm_i830_irq_emit_t __user *)arg, sizeof(emit) ))
++	if (copy_from_user
++	    (&emit, (drm_i830_irq_emit_t __user *) arg, sizeof(emit)))
+ 		return -EFAULT;
+ 
+-	result = i830_emit_irq( dev );
++	result = i830_emit_irq(dev);
+ 
+-	if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) {
+-		DRM_ERROR( "copy_to_user\n" );
++	if (copy_to_user(emit.irq_seq, &result, sizeof(int))) {
++		DRM_ERROR("copy_to_user\n");
+ 		return -EFAULT;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-
+ /* Doesn't need the hardware lock.
+  */
+-int i830_irq_wait( struct inode *inode, struct file *filp, unsigned int cmd,
+-		   unsigned long arg )
++int i830_irq_wait(struct inode *inode, struct file *filp, unsigned int cmd,
++		  unsigned long arg)
+ {
+-	drm_file_t	  *priv	    = filp->private_data;
+-	drm_device_t	  *dev	    = priv->head->dev;
++	drm_file_t *priv = filp->private_data;
++	drm_device_t *dev = priv->head->dev;
+ 	drm_i830_private_t *dev_priv = dev->dev_private;
+ 	drm_i830_irq_wait_t irqwait;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return -EINVAL;
+ 	}
+ 
+-	if (copy_from_user( &irqwait, (drm_i830_irq_wait_t __user *)arg, 
+-			    sizeof(irqwait) ))
++	if (copy_from_user(&irqwait, (drm_i830_irq_wait_t __user *) arg,
++			   sizeof(irqwait)))
+ 		return -EFAULT;
+ 
+-	return i830_wait_irq( dev, irqwait.irq_seq );
++	return i830_wait_irq(dev, irqwait.irq_seq);
+ }
+ 
+-
+ /* drm_dma.h hooks
+ */
+-void i830_driver_irq_preinstall( drm_device_t *dev ) {
+-	drm_i830_private_t *dev_priv =
+-		(drm_i830_private_t *)dev->dev_private;
+-
+-	I830_WRITE16( I830REG_HWSTAM, 0xffff );
+-	I830_WRITE16( I830REG_INT_MASK_R, 0x0 );
+-	I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
++void i830_driver_irq_preinstall(drm_device_t * dev)
++{
++	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
++
++	I830_WRITE16(I830REG_HWSTAM, 0xffff);
++	I830_WRITE16(I830REG_INT_MASK_R, 0x0);
++	I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
+ 	atomic_set(&dev_priv->irq_received, 0);
+ 	atomic_set(&dev_priv->irq_emitted, 0);
+ 	init_waitqueue_head(&dev_priv->irq_queue);
+ }
+ 
+-void i830_driver_irq_postinstall( drm_device_t *dev ) {
+-	drm_i830_private_t *dev_priv =
+-		(drm_i830_private_t *)dev->dev_private;
++void i830_driver_irq_postinstall(drm_device_t * dev)
++{
++	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
+ 
+-	I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 );
++	I830_WRITE16(I830REG_INT_ENABLE_R, 0x2);
+ }
+ 
+-void i830_driver_irq_uninstall( drm_device_t *dev ) {
+-	drm_i830_private_t *dev_priv =
+-		(drm_i830_private_t *)dev->dev_private;
++void i830_driver_irq_uninstall(drm_device_t * dev)
++{
++	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
+ 	if (!dev_priv)
+ 		return;
+ 
+-	I830_WRITE16( I830REG_INT_MASK_R, 0xffff );
+-	I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
++	I830_WRITE16(I830REG_INT_MASK_R, 0xffff);
++	I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
+ }
+diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
+--- a/drivers/char/drm/i915_dma.c
++++ b/drivers/char/drm/i915_dma.c
+@@ -85,14 +85,14 @@ static int i915_dma_cleanup(drm_device_t
+ 	 * is freed, it's too late.
+ 	 */
+ 	if (dev->irq)
+-		drm_irq_uninstall (dev);
++		drm_irq_uninstall(dev);
+ 
+ 	if (dev->dev_private) {
+ 		drm_i915_private_t *dev_priv =
+ 		    (drm_i915_private_t *) dev->dev_private;
+ 
+ 		if (dev_priv->ring.virtual_start) {
+-			drm_core_ioremapfree( &dev_priv->ring.map, dev);
++			drm_core_ioremapfree(&dev_priv->ring.map, dev);
+ 		}
+ 
+ 		if (dev_priv->status_page_dmah) {
+@@ -101,8 +101,8 @@ static int i915_dma_cleanup(drm_device_t
+ 			I915_WRITE(0x02080, 0x1ffff000);
+ 		}
+ 
+-		drm_free (dev->dev_private, sizeof(drm_i915_private_t),
+-			   DRM_MEM_DRIVER);
++		drm_free(dev->dev_private, sizeof(drm_i915_private_t),
++			 DRM_MEM_DRIVER);
+ 
+ 		dev->dev_private = NULL;
+ 	}
+@@ -146,7 +146,7 @@ static int i915_initialize(drm_device_t 
+ 	dev_priv->ring.map.flags = 0;
+ 	dev_priv->ring.map.mtrr = 0;
+ 
+-	drm_core_ioremap( &dev_priv->ring.map, dev );
++	drm_core_ioremap(&dev_priv->ring.map, dev);
+ 
+ 	if (dev_priv->ring.map.handle == NULL) {
+ 		dev->dev_private = (void *)dev_priv;
+@@ -243,8 +243,8 @@ static int i915_dma_init(DRM_IOCTL_ARGS)
+ 
+ 	switch (init.func) {
+ 	case I915_INIT_DMA:
+-		dev_priv = drm_alloc (sizeof(drm_i915_private_t),
+-				       DRM_MEM_DRIVER);
++		dev_priv = drm_alloc(sizeof(drm_i915_private_t),
++				     DRM_MEM_DRIVER);
+ 		if (dev_priv == NULL)
+ 			return DRM_ERR(ENOMEM);
+ 		retcode = i915_initialize(dev, dev_priv, &init);
+@@ -297,7 +297,7 @@ static int do_validate_cmd(int cmd)
+ 		case 0x1c:
+ 			return 1;
+ 		case 0x1d:
+-			switch ((cmd>>16)&0xff) {
++			switch ((cmd >> 16) & 0xff) {
+ 			case 0x3:
+ 				return (cmd & 0x1f) + 2;
+ 			case 0x4:
+@@ -699,20 +699,20 @@ static int i915_setparam(DRM_IOCTL_ARGS)
+ 	return 0;
+ }
+ 
+-void i915_driver_pretakedown(drm_device_t *dev)
++void i915_driver_pretakedown(drm_device_t * dev)
+ {
+-	if ( dev->dev_private ) {
++	if (dev->dev_private) {
+ 		drm_i915_private_t *dev_priv = dev->dev_private;
+-	        i915_mem_takedown( &(dev_priv->agp_heap) );
+- 	}
+-	i915_dma_cleanup( dev );
++		i915_mem_takedown(&(dev_priv->agp_heap));
++	}
++	i915_dma_cleanup(dev);
+ }
+ 
+-void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp)
++void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+ {
+-	if ( dev->dev_private ) {
++	if (dev->dev_private) {
+ 		drm_i915_private_t *dev_priv = dev->dev_private;
+-                i915_mem_release( dev, filp, dev_priv->agp_heap );
++		i915_mem_release(dev, filp, dev_priv->agp_heap);
+ 	}
+ }
+ 
+diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
+--- a/drivers/char/drm/i915_drv.c
++++ b/drivers/char/drm/i915_drv.c
+@@ -34,36 +34,34 @@
+ 
+ #include "drm_pciids.h"
+ 
+-static int postinit( struct drm_device *dev, unsigned long flags )
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+ 	dev->counters += 4;
+ 	dev->types[6] = _DRM_STAT_IRQ;
+ 	dev->types[7] = _DRM_STAT_PRIMARY;
+ 	dev->types[8] = _DRM_STAT_SECONDARY;
+ 	dev->types[9] = _DRM_STAT_DMA;
+-	
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->primary.minor,
+-		pci_pretty_name(dev->pdev)
+-		);
++
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR,
++		 DRIVER_PATCHLEVEL,
++		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
++	    );
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+@@ -71,12 +69,10 @@ static struct pci_device_id pciidlist[] 
+ 	i915_PCI_IDS
+ };
+ 
+-extern drm_ioctl_desc_t i915_ioctls[];
+-extern int i915_max_ioctl;
+-
+ static struct drm_driver driver = {
+-	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
+-				DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
++	.driver_features =
++	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
++	    DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
+ 	.pretakedown = i915_driver_pretakedown,
+ 	.prerelease = i915_driver_prerelease,
+ 	.device_is_agp = i915_driver_device_is_agp,
+@@ -91,21 +87,21 @@ static struct drm_driver driver = {
+ 	.version = version,
+ 	.ioctls = i915_ioctls,
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
+ #ifdef CONFIG_COMPAT
+-		.compat_ioctl = i915_compat_ioctl,
++		 .compat_ioctl = i915_compat_ioctl,
+ #endif
+-	},
++		 },
+ 	.pci_driver = {
+-		.name          = DRIVER_NAME,
+-		.id_table      = pciidlist,
+-	}
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
+ };
+ 
+ static int __init i915_init(void)
+@@ -122,6 +118,6 @@ static void __exit i915_exit(void)
+ module_init(i915_init);
+ module_exit(i915_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
+--- a/drivers/char/drm/i915_drv.h
++++ b/drivers/char/drm/i915_drv.h
+@@ -99,20 +99,23 @@ typedef struct drm_i915_private {
+ 	struct mem_block *agp_heap;
+ } drm_i915_private_t;
+ 
++extern drm_ioctl_desc_t i915_ioctls[];
++extern int i915_max_ioctl;
++
+ 				/* i915_dma.c */
+ extern void i915_kernel_lost_context(drm_device_t * dev);
+-extern void i915_driver_pretakedown(drm_device_t *dev);
+-extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+-extern int i915_driver_device_is_agp(drm_device_t *dev);
++extern void i915_driver_pretakedown(drm_device_t * dev);
++extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp);
++extern int i915_driver_device_is_agp(drm_device_t * dev);
+ 
+ /* i915_irq.c */
+ extern int i915_irq_emit(DRM_IOCTL_ARGS);
+ extern int i915_irq_wait(DRM_IOCTL_ARGS);
+ 
+ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
+-extern void i915_driver_irq_preinstall(drm_device_t *dev);
+-extern void i915_driver_irq_postinstall(drm_device_t *dev);
+-extern void i915_driver_irq_uninstall(drm_device_t *dev);
++extern void i915_driver_irq_preinstall(drm_device_t * dev);
++extern void i915_driver_irq_postinstall(drm_device_t * dev);
++extern void i915_driver_irq_uninstall(drm_device_t * dev);
+ 
+ /* i915_mem.c */
+ extern int i915_mem_alloc(DRM_IOCTL_ARGS);
+@@ -125,7 +128,6 @@ extern void i915_mem_release(drm_device_
+ extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
+ 			      unsigned long arg);
+ 
+-
+ #define I915_READ(reg)          DRM_READ32(dev_priv->mmio_map, reg)
+ #define I915_WRITE(reg,val)     DRM_WRITE32(dev_priv->mmio_map, reg, val)
+ #define I915_READ16(reg) 	DRM_READ16(dev_priv->mmio_map, reg)
+diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c
+--- a/drivers/char/drm/i915_ioc32.c
++++ b/drivers/char/drm/i915_ioc32.c
+@@ -3,7 +3,7 @@
+  *
+  * 32-bit ioctl compatibility routines for the i915 DRM.
+  *
+- * \author Alan Hourihane <alanh at fairlite.demon.co.uk> 
++ * \author Alan Hourihane <alanh at fairlite.demon.co.uk>
+  *
+  *
+  * Copyright (C) Paul Mackerras 2005
+@@ -42,51 +42,55 @@ typedef struct _drm_i915_batchbuffer32 {
+ 	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */
+ 	int DR4;		/* window origin for GFX_OP_DRAWRECT_INFO */
+ 	int num_cliprects;	/* mulitpass with multiple cliprects? */
+-	u32 cliprects;	/* pointer to userspace cliprects */
++	u32 cliprects;		/* pointer to userspace cliprects */
+ } drm_i915_batchbuffer32_t;
+ 
+ static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,
+-			   unsigned long arg)
++				   unsigned long arg)
+ {
+ 	drm_i915_batchbuffer32_t batchbuffer32;
+ 	drm_i915_batchbuffer_t __user *batchbuffer;
+-	
+-	if (copy_from_user(&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
++
++	if (copy_from_user
++	    (&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
+ 		return -EFAULT;
+-	
++
+ 	batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer));
+ 	if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer))
+ 	    || __put_user(batchbuffer32.start, &batchbuffer->start)
+ 	    || __put_user(batchbuffer32.used, &batchbuffer->used)
+ 	    || __put_user(batchbuffer32.DR1, &batchbuffer->DR1)
+ 	    || __put_user(batchbuffer32.DR4, &batchbuffer->DR4)
+-	    || __put_user(batchbuffer32.num_cliprects, &batchbuffer->num_cliprects)
++	    || __put_user(batchbuffer32.num_cliprects,
++			  &batchbuffer->num_cliprects)
+ 	    || __put_user((int __user *)(unsigned long)batchbuffer32.cliprects,
+ 			  &batchbuffer->cliprects))
+ 		return -EFAULT;
+-	
++
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_I915_BATCHBUFFER, (unsigned long) batchbuffer);
++			 DRM_IOCTL_I915_BATCHBUFFER,
++			 (unsigned long)batchbuffer);
+ }
+ 
+ typedef struct _drm_i915_cmdbuffer32 {
+-	u32 buf;	/* pointer to userspace command buffer */
++	u32 buf;		/* pointer to userspace command buffer */
+ 	int sz;			/* nr bytes in buf */
+ 	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */
+ 	int DR4;		/* window origin for GFX_OP_DRAWRECT_INFO */
+ 	int num_cliprects;	/* mulitpass with multiple cliprects? */
+-	u32 cliprects;	/* pointer to userspace cliprects */
++	u32 cliprects;		/* pointer to userspace cliprects */
+ } drm_i915_cmdbuffer32_t;
+ 
+ static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
+-			   unsigned long arg)
++				 unsigned long arg)
+ {
+ 	drm_i915_cmdbuffer32_t cmdbuffer32;
+ 	drm_i915_cmdbuffer_t __user *cmdbuffer;
+-	
+-	if (copy_from_user(&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
++
++	if (copy_from_user
++	    (&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
+ 		return -EFAULT;
+-	
++
+ 	cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer));
+ 	if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer))
+ 	    || __put_user((int __user *)(unsigned long)cmdbuffer32.buf,
+@@ -98,9 +102,9 @@ static int compat_i915_cmdbuffer(struct 
+ 	    || __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects,
+ 			  &cmdbuffer->cliprects))
+ 		return -EFAULT;
+-	
++
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_I915_CMDBUFFER, (unsigned long) cmdbuffer);
++			 DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer);
+ }
+ 
+ typedef struct drm_i915_irq_emit32 {
+@@ -108,12 +112,12 @@ typedef struct drm_i915_irq_emit32 {
+ } drm_i915_irq_emit32_t;
+ 
+ static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
+-				  unsigned long arg)
++				unsigned long arg)
+ {
+ 	drm_i915_irq_emit32_t req32;
+ 	drm_i915_irq_emit_t __user *request;
+ 
+-	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
++	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+ 		return -EFAULT;
+ 
+ 	request = compat_alloc_user_space(sizeof(*request));
+@@ -123,7 +127,7 @@ static int compat_i915_irq_emit(struct f
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_I915_IRQ_EMIT, (unsigned long) request);
++			 DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request);
+ }
+ typedef struct drm_i915_getparam32 {
+ 	int param;
+@@ -131,12 +135,12 @@ typedef struct drm_i915_getparam32 {
+ } drm_i915_getparam32_t;
+ 
+ static int compat_i915_getparam(struct file *file, unsigned int cmd,
+-				     unsigned long arg)
++				unsigned long arg)
+ {
+ 	drm_i915_getparam32_t req32;
+ 	drm_i915_getparam_t __user *request;
+ 
+-	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
++	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+ 		return -EFAULT;
+ 
+ 	request = compat_alloc_user_space(sizeof(*request));
+@@ -147,7 +151,7 @@ static int compat_i915_getparam(struct f
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_I915_GETPARAM, (unsigned long) request);
++			 DRM_IOCTL_I915_GETPARAM, (unsigned long)request);
+ }
+ 
+ typedef struct drm_i915_mem_alloc32 {
+@@ -158,12 +162,12 @@ typedef struct drm_i915_mem_alloc32 {
+ } drm_i915_mem_alloc32_t;
+ 
+ static int compat_i915_alloc(struct file *file, unsigned int cmd,
+-				     unsigned long arg)
++			     unsigned long arg)
+ {
+ 	drm_i915_mem_alloc32_t req32;
+ 	drm_i915_mem_alloc_t __user *request;
+ 
+-	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
++	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+ 		return -EFAULT;
+ 
+ 	request = compat_alloc_user_space(sizeof(*request));
+@@ -176,10 +180,9 @@ static int compat_i915_alloc(struct file
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_I915_ALLOC, (unsigned long) request);
++			 DRM_IOCTL_I915_ALLOC, (unsigned long)request);
+ }
+ 
+-
+ drm_ioctl_compat_t *i915_compat_ioctls[] = {
+ 	[DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer,
+ 	[DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer,
+@@ -197,8 +200,7 @@ drm_ioctl_compat_t *i915_compat_ioctls[]
+  * \param arg user argument.
+  * \return zero on success or negative number on failure.
+  */
+-long i915_compat_ioctl(struct file *filp, unsigned int cmd,
+-			 unsigned long arg)
++long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ 	unsigned int nr = DRM_IOCTL_NR(cmd);
+ 	drm_ioctl_compat_t *fn = NULL;
+@@ -206,13 +208,13 @@ long i915_compat_ioctl(struct file *filp
+ 
+ 	if (nr < DRM_COMMAND_BASE)
+ 		return drm_compat_ioctl(filp, cmd, arg);
+-	
++
+ 	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
+ 		fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
+ 
+ 	lock_kernel();		/* XXX for now */
+ 	if (fn != NULL)
+-		ret = (*fn)(filp, cmd, arg);
++		ret = (*fn) (filp, cmd, arg);
+ 	else
+ 		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+ 	unlock_kernel();
+diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
+--- a/drivers/char/drm/i915_mem.c
++++ b/drivers/char/drm/i915_mem.c
+@@ -86,7 +86,7 @@ static void mark_block(drm_device_t * de
+ }
+ 
+ /* Very simple allocator for agp memory, working on a static range
+- * already mapped into each client's address space.  
++ * already mapped into each client's address space.
+  */
+ 
+ static struct mem_block *split_block(struct mem_block *p, int start, int size,
+@@ -94,7 +94,8 @@ static struct mem_block *split_block(str
+ {
+ 	/* Maybe cut off the start of an existing block */
+ 	if (start > p->start) {
+-		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
++		struct mem_block *newblock =
++		    drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
+ 		if (!newblock)
+ 			goto out;
+ 		newblock->start = start;
+@@ -110,7 +111,8 @@ static struct mem_block *split_block(str
+ 
+ 	/* Maybe cut off the end of an existing block */
+ 	if (size < p->size) {
+-		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
++		struct mem_block *newblock =
++		    drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
+ 		if (!newblock)
+ 			goto out;
+ 		newblock->start = start + size;
+diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
+--- a/drivers/char/drm/mga_dma.c
++++ b/drivers/char/drm/mga_dma.c
+@@ -28,7 +28,7 @@
+ /**
+  * \file mga_dma.c
+  * DMA support for MGA G200 / G400.
+- * 
++ *
+  * \author Rickard E. (Rik) Faith <faith at valinux.com>
+  * \author Jeff Hartmann <jhartmann at valinux.com>
+  * \author Keith Whitwell <keith at tungstengraphics.com>
+@@ -44,40 +44,40 @@
+ #define MGA_DEFAULT_USEC_TIMEOUT	10000
+ #define MGA_FREELIST_DEBUG		0
+ 
+-static int mga_do_cleanup_dma( drm_device_t *dev );
++static int mga_do_cleanup_dma(drm_device_t * dev);
+ 
+ /* ================================================================
+  * Engine control
+  */
+ 
+-int mga_do_wait_for_idle( drm_mga_private_t *dev_priv )
++int mga_do_wait_for_idle(drm_mga_private_t * dev_priv)
+ {
+ 	u32 status = 0;
+ 	int i;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
+-		if ( status == MGA_ENDPRDMASTS ) {
+-			MGA_WRITE8( MGA_CRTC_INDEX, 0 );
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
++		if (status == MGA_ENDPRDMASTS) {
++			MGA_WRITE8(MGA_CRTC_INDEX, 0);
+ 			return 0;
+ 		}
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+ #if MGA_DMA_DEBUG
+-	DRM_ERROR( "failed!\n" );
+-	DRM_INFO( "   status=0x%08x\n", status );
++	DRM_ERROR("failed!\n");
++	DRM_INFO("   status=0x%08x\n", status);
+ #endif
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-static int mga_do_dma_reset( drm_mga_private_t *dev_priv )
++static int mga_do_dma_reset(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
+ 
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	/* The primary DMA stream should look like new right about now.
+ 	 */
+@@ -100,24 +100,25 @@ static int mga_do_dma_reset( drm_mga_pri
+  * Primary DMA stream
+  */
+ 
+-void mga_do_dma_flush( drm_mga_private_t *dev_priv )
++void mga_do_dma_flush(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
+ 	u32 head, tail;
+ 	u32 status = 0;
+ 	int i;
+- 	DMA_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DMA_LOCALS;
++	DRM_DEBUG("\n");
+ 
+-        /* We need to wait so that we can do an safe flush */
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
+-		if ( status == MGA_ENDPRDMASTS ) break;
+-		DRM_UDELAY( 1 );
++	/* We need to wait so that we can do an safe flush */
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
++		if (status == MGA_ENDPRDMASTS)
++			break;
++		DRM_UDELAY(1);
+ 	}
+ 
+-	if ( primary->tail == primary->last_flush ) {
+-		DRM_DEBUG( "   bailing out...\n" );
++	if (primary->tail == primary->last_flush) {
++		DRM_DEBUG("   bailing out...\n");
+ 		return;
+ 	}
+ 
+@@ -127,48 +128,46 @@ void mga_do_dma_flush( drm_mga_private_t
+ 	 * actually (partially?) reads the first of these commands.
+ 	 * See page 4-16 in the G400 manual, middle of the page or so.
+ 	 */
+-	BEGIN_DMA( 1 );
++	BEGIN_DMA(1);
+ 
+-	DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+-		   MGA_DMAPAD,  0x00000000,
+-		   MGA_DMAPAD,  0x00000000,
+-		   MGA_DMAPAD,	0x00000000 );
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
+ 
+ 	ADVANCE_DMA();
+ 
+ 	primary->last_flush = primary->tail;
+ 
+-	head = MGA_READ( MGA_PRIMADDRESS );
++	head = MGA_READ(MGA_PRIMADDRESS);
+ 
+-	if ( head <= tail ) {
++	if (head <= tail) {
+ 		primary->space = primary->size - primary->tail;
+ 	} else {
+ 		primary->space = head - tail;
+ 	}
+ 
+-	DRM_DEBUG( "   head = 0x%06lx\n", head - dev_priv->primary->offset );
+-	DRM_DEBUG( "   tail = 0x%06lx\n", tail - dev_priv->primary->offset );
+-	DRM_DEBUG( "  space = 0x%06x\n", primary->space );
++	DRM_DEBUG("   head = 0x%06lx\n", head - dev_priv->primary->offset);
++	DRM_DEBUG("   tail = 0x%06lx\n", tail - dev_priv->primary->offset);
++	DRM_DEBUG("  space = 0x%06x\n", primary->space);
+ 
+ 	mga_flush_write_combine();
+ 	MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);
+ 
+-	DRM_DEBUG( "done.\n" );
++	DRM_DEBUG("done.\n");
+ }
+ 
+-void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
++void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
+ 	u32 head, tail;
+ 	DMA_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	BEGIN_DMA_WRAP();
+ 
+-	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000 );
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
+ 
+ 	ADVANCE_DMA();
+ 
+@@ -178,45 +177,43 @@ void mga_do_dma_wrap_start( drm_mga_priv
+ 	primary->last_flush = 0;
+ 	primary->last_wrap++;
+ 
+-	head = MGA_READ( MGA_PRIMADDRESS );
++	head = MGA_READ(MGA_PRIMADDRESS);
+ 
+-	if ( head == dev_priv->primary->offset ) {
++	if (head == dev_priv->primary->offset) {
+ 		primary->space = primary->size;
+ 	} else {
+ 		primary->space = head - dev_priv->primary->offset;
+ 	}
+ 
+-	DRM_DEBUG( "   head = 0x%06lx\n",
+-		  head - dev_priv->primary->offset );
+-	DRM_DEBUG( "   tail = 0x%06x\n", primary->tail );
+-	DRM_DEBUG( "   wrap = %d\n", primary->last_wrap );
+-	DRM_DEBUG( "  space = 0x%06x\n", primary->space );
++	DRM_DEBUG("   head = 0x%06lx\n", head - dev_priv->primary->offset);
++	DRM_DEBUG("   tail = 0x%06x\n", primary->tail);
++	DRM_DEBUG("   wrap = %d\n", primary->last_wrap);
++	DRM_DEBUG("  space = 0x%06x\n", primary->space);
+ 
+ 	mga_flush_write_combine();
+ 	MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);
+ 
+-	set_bit( 0, &primary->wrapped );
+-	DRM_DEBUG( "done.\n" );
++	set_bit(0, &primary->wrapped);
++	DRM_DEBUG("done.\n");
+ }
+ 
+-void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv )
++void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	u32 head = dev_priv->primary->offset;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	sarea_priv->last_wrap++;
+-	DRM_DEBUG( "   wrap = %d\n", sarea_priv->last_wrap );
++	DRM_DEBUG("   wrap = %d\n", sarea_priv->last_wrap);
+ 
+ 	mga_flush_write_combine();
+-	MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL );
++	MGA_WRITE(MGA_PRIMADDRESS, head | MGA_DMA_GENERAL);
+ 
+-	clear_bit( 0, &primary->wrapped );
+-	DRM_DEBUG( "done.\n" );
++	clear_bit(0, &primary->wrapped);
++	DRM_DEBUG("done.\n");
+ }
+ 
+-
+ /* ================================================================
+  * Freelist management
+  */
+@@ -225,63 +222,61 @@ void mga_do_dma_wrap_end( drm_mga_privat
+ #define MGA_BUFFER_FREE		0
+ 
+ #if MGA_FREELIST_DEBUG
+-static void mga_freelist_print( drm_device_t *dev )
++static void mga_freelist_print(drm_device_t * dev)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_freelist_t *entry;
+ 
+-	DRM_INFO( "\n" );
+-	DRM_INFO( "current dispatch: last=0x%x done=0x%x\n",
+-		  dev_priv->sarea_priv->last_dispatch,
+-		  (unsigned int)(MGA_READ( MGA_PRIMADDRESS ) -
+-				 dev_priv->primary->offset) );
+-	DRM_INFO( "current freelist:\n" );
+-
+-	for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) {
+-		DRM_INFO( "   %p   idx=%2d  age=0x%x 0x%06lx\n",
+-			  entry, entry->buf->idx, entry->age.head,
+-			  entry->age.head - dev_priv->primary->offset );
++	DRM_INFO("\n");
++	DRM_INFO("current dispatch: last=0x%x done=0x%x\n",
++		 dev_priv->sarea_priv->last_dispatch,
++		 (unsigned int)(MGA_READ(MGA_PRIMADDRESS) -
++				dev_priv->primary->offset));
++	DRM_INFO("current freelist:\n");
++
++	for (entry = dev_priv->head->next; entry; entry = entry->next) {
++		DRM_INFO("   %p   idx=%2d  age=0x%x 0x%06lx\n",
++			 entry, entry->buf->idx, entry->age.head,
++			 entry->age.head - dev_priv->primary->offset);
+ 	}
+-	DRM_INFO( "\n" );
++	DRM_INFO("\n");
+ }
+ #endif
+ 
+-static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv )
++static int mga_freelist_init(drm_device_t * dev, drm_mga_private_t * dev_priv)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_buf_t *buf;
+ 	drm_mga_buf_priv_t *buf_priv;
+ 	drm_mga_freelist_t *entry;
+ 	int i;
+-	DRM_DEBUG( "count=%d\n", dma->buf_count );
++	DRM_DEBUG("count=%d\n", dma->buf_count);
+ 
+-	dev_priv->head = drm_alloc( sizeof(drm_mga_freelist_t),
+-				     DRM_MEM_DRIVER );
+-	if ( dev_priv->head == NULL )
++	dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
++	if (dev_priv->head == NULL)
+ 		return DRM_ERR(ENOMEM);
+ 
+-	memset( dev_priv->head, 0, sizeof(drm_mga_freelist_t) );
+-	SET_AGE( &dev_priv->head->age, MGA_BUFFER_USED, 0 );
++	memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
++	SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0);
+ 
+-	for ( i = 0 ; i < dma->buf_count ; i++ ) {
++	for (i = 0; i < dma->buf_count; i++) {
+ 		buf = dma->buflist[i];
+-	        buf_priv = buf->dev_private;
++		buf_priv = buf->dev_private;
+ 
+-		entry = drm_alloc( sizeof(drm_mga_freelist_t),
+-				    DRM_MEM_DRIVER );
+-		if ( entry == NULL )
++		entry = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
++		if (entry == NULL)
+ 			return DRM_ERR(ENOMEM);
+ 
+-		memset( entry, 0, sizeof(drm_mga_freelist_t) );
++		memset(entry, 0, sizeof(drm_mga_freelist_t));
+ 
+ 		entry->next = dev_priv->head->next;
+ 		entry->prev = dev_priv->head;
+-		SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 );
++		SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
+ 		entry->buf = buf;
+ 
+-		if ( dev_priv->head->next != NULL )
++		if (dev_priv->head->next != NULL)
+ 			dev_priv->head->next->prev = entry;
+-		if ( entry->next == NULL )
++		if (entry->next == NULL)
+ 			dev_priv->tail = entry;
+ 
+ 		buf_priv->list_entry = entry;
+@@ -294,17 +289,17 @@ static int mga_freelist_init( drm_device
+ 	return 0;
+ }
+ 
+-static void mga_freelist_cleanup( drm_device_t *dev )
++static void mga_freelist_cleanup(drm_device_t * dev)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_freelist_t *entry;
+ 	drm_mga_freelist_t *next;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	entry = dev_priv->head;
+-	while ( entry ) {
++	while (entry) {
+ 		next = entry->next;
+-		drm_free( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER );
++		drm_free(entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
+ 		entry = next;
+ 	}
+ 
+@@ -314,71 +309,69 @@ static void mga_freelist_cleanup( drm_de
+ #if 0
+ /* FIXME: Still needed?
+  */
+-static void mga_freelist_reset( drm_device_t *dev )
++static void mga_freelist_reset(drm_device_t * dev)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_buf_t *buf;
+ 	drm_mga_buf_priv_t *buf_priv;
+ 	int i;
+ 
+-	for ( i = 0 ; i < dma->buf_count ; i++ ) {
++	for (i = 0; i < dma->buf_count; i++) {
+ 		buf = dma->buflist[i];
+-	        buf_priv = buf->dev_private;
+-		SET_AGE( &buf_priv->list_entry->age,
+-			 MGA_BUFFER_FREE, 0 );
++		buf_priv = buf->dev_private;
++		SET_AGE(&buf_priv->list_entry->age, MGA_BUFFER_FREE, 0);
+ 	}
+ }
+ #endif
+ 
+-static drm_buf_t *mga_freelist_get( drm_device_t *dev )
++static drm_buf_t *mga_freelist_get(drm_device_t * dev)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_freelist_t *next;
+ 	drm_mga_freelist_t *prev;
+ 	drm_mga_freelist_t *tail = dev_priv->tail;
+ 	u32 head, wrap;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	head = MGA_READ( MGA_PRIMADDRESS );
++	head = MGA_READ(MGA_PRIMADDRESS);
+ 	wrap = dev_priv->sarea_priv->last_wrap;
+ 
+-	DRM_DEBUG( "   tail=0x%06lx %d\n",
+-		   tail->age.head ?
+-		   tail->age.head - dev_priv->primary->offset : 0,
+-		   tail->age.wrap );
+-	DRM_DEBUG( "   head=0x%06lx %d\n",
+-		   head - dev_priv->primary->offset, wrap );
++	DRM_DEBUG("   tail=0x%06lx %d\n",
++		  tail->age.head ?
++		  tail->age.head - dev_priv->primary->offset : 0,
++		  tail->age.wrap);
++	DRM_DEBUG("   head=0x%06lx %d\n",
++		  head - dev_priv->primary->offset, wrap);
+ 
+-	if ( TEST_AGE( &tail->age, head, wrap ) ) {
++	if (TEST_AGE(&tail->age, head, wrap)) {
+ 		prev = dev_priv->tail->prev;
+ 		next = dev_priv->tail;
+ 		prev->next = NULL;
+ 		next->prev = next->next = NULL;
+ 		dev_priv->tail = prev;
+-		SET_AGE( &next->age, MGA_BUFFER_USED, 0 );
++		SET_AGE(&next->age, MGA_BUFFER_USED, 0);
+ 		return next->buf;
+ 	}
+ 
+-	DRM_DEBUG( "returning NULL!\n" );
++	DRM_DEBUG("returning NULL!\n");
+ 	return NULL;
+ }
+ 
+-int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
++int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
+ 	drm_mga_freelist_t *head, *entry, *prev;
+ 
+-	DRM_DEBUG( "age=0x%06lx wrap=%d\n",
+-		   buf_priv->list_entry->age.head -
+-		   dev_priv->primary->offset,
+-		   buf_priv->list_entry->age.wrap );
++	DRM_DEBUG("age=0x%06lx wrap=%d\n",
++		  buf_priv->list_entry->age.head -
++		  dev_priv->primary->offset, buf_priv->list_entry->age.wrap);
+ 
+ 	entry = buf_priv->list_entry;
+ 	head = dev_priv->head;
+ 
+-	if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) {
+-		SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 );
++	if (buf_priv->list_entry->age.head == MGA_BUFFER_USED) {
++		SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
+ 		prev = dev_priv->tail;
+ 		prev->next = entry;
+ 		entry->prev = prev;
+@@ -394,15 +387,13 @@ int mga_freelist_put( drm_device_t *dev,
+ 	return 0;
+ }
+ 
+-
+ /* ================================================================
+  * DMA initialization, cleanup
+  */
+ 
+-
+-int mga_driver_preinit(drm_device_t *dev, unsigned long flags)
++int mga_driver_preinit(drm_device_t * dev, unsigned long flags)
+ {
+-	drm_mga_private_t * dev_priv;
++	drm_mga_private_t *dev_priv;
+ 
+ 	dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
+ 	if (!dev_priv)
+@@ -420,7 +411,7 @@ int mga_driver_preinit(drm_device_t *dev
+ #if __OS_HAS_AGP
+ /**
+  * Bootstrap the driver for AGP DMA.
+- * 
++ *
+  * \todo
+  * Investigate whether there is any benifit to storing the WARP microcode in
+  * AGP memory.  If not, the microcode may as well always be put in PCI
+@@ -436,18 +427,18 @@ int mga_driver_preinit(drm_device_t *dev
+ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
+ 				    drm_mga_dma_bootstrap_t * dma_bs)
+ {
+-	drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
++	drm_mga_private_t *const dev_priv =
++	    (drm_mga_private_t *) dev->dev_private;
+ 	unsigned int warp_size = mga_warp_microcode_size(dev_priv);
+ 	int err;
+-	unsigned  offset;
++	unsigned offset;
+ 	const unsigned secondary_size = dma_bs->secondary_bin_count
+-		* dma_bs->secondary_bin_size;
++	    * dma_bs->secondary_bin_size;
+ 	const unsigned agp_size = (dma_bs->agp_size << 20);
+ 	drm_buf_desc_t req;
+ 	drm_agp_mode_t mode;
+ 	drm_agp_info_t info;
+ 
+-	
+ 	/* Acquire AGP. */
+ 	err = drm_agp_acquire(dev);
+ 	if (err) {
+@@ -468,7 +459,6 @@ static int mga_do_agp_dma_bootstrap(drm_
+ 		return err;
+ 	}
+ 
+-
+ 	/* In addition to the usual AGP mode configuration, the G200 AGP cards
+ 	 * need to have the AGP mode "manually" set.
+ 	 */
+@@ -476,24 +466,22 @@ static int mga_do_agp_dma_bootstrap(drm_
+ 	if (dev_priv->chipset == MGA_CARD_TYPE_G200) {
+ 		if (mode.mode & 0x02) {
+ 			MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE);
+-		}
+-		else {
++		} else {
+ 			MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE);
+ 		}
+ 	}
+ 
+-
+ 	/* Allocate and bind AGP memory. */
+ 	dev_priv->agp_pages = agp_size / PAGE_SIZE;
+-	dev_priv->agp_mem = drm_alloc_agp( dev, dev_priv->agp_pages, 0 );
++	dev_priv->agp_mem = drm_alloc_agp(dev, dev_priv->agp_pages, 0);
+ 	if (dev_priv->agp_mem == NULL) {
+ 		dev_priv->agp_pages = 0;
+ 		DRM_ERROR("Unable to allocate %uMB AGP memory\n",
+ 			  dma_bs->agp_size);
+ 		return DRM_ERR(ENOMEM);
+ 	}
+-		
+-	err = drm_bind_agp( dev_priv->agp_mem, 0 );
++
++	err = drm_bind_agp(dev_priv->agp_mem, 0);
+ 	if (err) {
+ 		DRM_ERROR("Unable to bind AGP memory\n");
+ 		return err;
+@@ -506,44 +494,44 @@ static int mga_do_agp_dma_bootstrap(drm_
+ 		warp_size = PAGE_SIZE;
+ 
+ 	offset = 0;
+-	err = drm_addmap( dev, offset, warp_size,
+-			  _DRM_AGP, _DRM_READ_ONLY, & dev_priv->warp );
++	err = drm_addmap(dev, offset, warp_size,
++			 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp);
+ 	if (err) {
+ 		DRM_ERROR("Unable to map WARP microcode\n");
+ 		return err;
+ 	}
+ 
+ 	offset += warp_size;
+-	err = drm_addmap( dev, offset, dma_bs->primary_size,
+-			  _DRM_AGP, _DRM_READ_ONLY, & dev_priv->primary );
++	err = drm_addmap(dev, offset, dma_bs->primary_size,
++			 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary);
+ 	if (err) {
+ 		DRM_ERROR("Unable to map primary DMA region\n");
+ 		return err;
+ 	}
+ 
+ 	offset += dma_bs->primary_size;
+-	err = drm_addmap( dev, offset, secondary_size,
+-			  _DRM_AGP, 0, & dev->agp_buffer_map );
++	err = drm_addmap(dev, offset, secondary_size,
++			 _DRM_AGP, 0, &dev->agp_buffer_map);
+ 	if (err) {
+ 		DRM_ERROR("Unable to map secondary DMA region\n");
+ 		return err;
+ 	}
+ 
+-	(void) memset( &req, 0, sizeof(req) );
++	(void)memset(&req, 0, sizeof(req));
+ 	req.count = dma_bs->secondary_bin_count;
+ 	req.size = dma_bs->secondary_bin_size;
+ 	req.flags = _DRM_AGP_BUFFER;
+ 	req.agp_start = offset;
+ 
+-	err = drm_addbufs_agp( dev, & req );
++	err = drm_addbufs_agp(dev, &req);
+ 	if (err) {
+ 		DRM_ERROR("Unable to add secondary DMA buffers\n");
+ 		return err;
+ 	}
+ 
+ 	offset += secondary_size;
+-	err = drm_addmap( dev, offset, agp_size - offset,
+-			  _DRM_AGP, 0, & dev_priv->agp_textures );
++	err = drm_addmap(dev, offset, agp_size - offset,
++			 _DRM_AGP, 0, &dev_priv->agp_textures);
+ 	if (err) {
+ 		DRM_ERROR("Unable to map AGP texture region\n");
+ 		return err;
+@@ -577,7 +565,7 @@ static int mga_do_agp_dma_bootstrap(drm_
+ 
+ /**
+  * Bootstrap the driver for PCI DMA.
+- * 
++ *
+  * \todo
+  * The algorithm for decreasing the size of the primary DMA buffer could be
+  * better.  The size should be rounded up to the nearest page size, then
+@@ -586,20 +574,20 @@ static int mga_do_agp_dma_bootstrap(drm_
+  * \todo
+  * Determine whether the maximum address passed to drm_pci_alloc is correct.
+  * The same goes for drm_addbufs_pci.
+- * 
++ *
+  * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap
+  */
+ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
+ 				    drm_mga_dma_bootstrap_t * dma_bs)
+ {
+-	drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
++	drm_mga_private_t *const dev_priv =
++	    (drm_mga_private_t *) dev->dev_private;
+ 	unsigned int warp_size = mga_warp_microcode_size(dev_priv);
+ 	unsigned int primary_size;
+ 	unsigned int bin_count;
+ 	int err;
+ 	drm_buf_desc_t req;
+ 
+-	
+ 	if (dev->dma == NULL) {
+ 		DRM_ERROR("dev->dma is NULL\n");
+ 		return DRM_ERR(EFAULT);
+@@ -624,9 +612,8 @@ static int mga_do_pci_dma_bootstrap(drm_
+ 	 * alignment of the primary or secondary DMA buffers.
+ 	 */
+ 
+-	for ( primary_size = dma_bs->primary_size
+-	      ; primary_size != 0
+-	      ; primary_size >>= 1 ) {
++	for (primary_size = dma_bs->primary_size; primary_size != 0;
++	     primary_size >>= 1) {
+ 		/* The proper alignment for this mapping is 0x04 */
+ 		err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT,
+ 				 _DRM_READ_ONLY, &dev_priv->primary);
+@@ -641,24 +628,23 @@ static int mga_do_pci_dma_bootstrap(drm_
+ 
+ 	if (dev_priv->primary->size != dma_bs->primary_size) {
+ 		DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n",
+-			 dma_bs->primary_size, 
+-			 (unsigned) dev_priv->primary->size);
++			 dma_bs->primary_size,
++			 (unsigned)dev_priv->primary->size);
+ 		dma_bs->primary_size = dev_priv->primary->size;
+ 	}
+ 
+-	for ( bin_count = dma_bs->secondary_bin_count
+-	      ; bin_count > 0 
+-	      ; bin_count-- ) {
+-		(void) memset( &req, 0, sizeof(req) );
++	for (bin_count = dma_bs->secondary_bin_count; bin_count > 0;
++	     bin_count--) {
++		(void)memset(&req, 0, sizeof(req));
+ 		req.count = bin_count;
+ 		req.size = dma_bs->secondary_bin_size;
+ 
+-		err = drm_addbufs_pci( dev, & req );
++		err = drm_addbufs_pci(dev, &req);
+ 		if (!err) {
+ 			break;
+ 		}
+ 	}
+-	
++
+ 	if (bin_count == 0) {
+ 		DRM_ERROR("Unable to add secondary DMA buffers\n");
+ 		return err;
+@@ -680,38 +666,34 @@ static int mga_do_pci_dma_bootstrap(drm_
+ 	return 0;
+ }
+ 
+-
+ static int mga_do_dma_bootstrap(drm_device_t * dev,
+ 				drm_mga_dma_bootstrap_t * dma_bs)
+ {
+ 	const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev);
+ 	int err;
+-	drm_mga_private_t * const dev_priv =
+-		(drm_mga_private_t *) dev->dev_private;
+-
++	drm_mga_private_t *const dev_priv =
++	    (drm_mga_private_t *) dev->dev_private;
+ 
+ 	dev_priv->used_new_dma_init = 1;
+ 
+ 	/* The first steps are the same for both PCI and AGP based DMA.  Map
+ 	 * the cards MMIO registers and map a status page.
+ 	 */
+-	err = drm_addmap( dev, dev_priv->mmio_base, dev_priv->mmio_size,
+-			  _DRM_REGISTERS, _DRM_READ_ONLY, & dev_priv->mmio );
++	err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size,
++			 _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
+ 	if (err) {
+ 		DRM_ERROR("Unable to map MMIO region\n");
+ 		return err;
+ 	}
+ 
+-
+-	err = drm_addmap( dev, 0, SAREA_MAX, _DRM_SHM,
+-			  _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
+-			  & dev_priv->status );
++	err = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
++			 _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
++			 &dev_priv->status);
+ 	if (err) {
+ 		DRM_ERROR("Unable to map status region\n");
+ 		return err;
+ 	}
+ 
+-
+ 	/* The DMA initialization procedure is slightly different for PCI and
+ 	 * AGP cards.  AGP cards just allocate a large block of AGP memory and
+ 	 * carve off portions of it for internal uses.  The remaining memory
+@@ -720,7 +702,7 @@ static int mga_do_dma_bootstrap(drm_devi
+ 	if (is_agp) {
+ 		err = mga_do_agp_dma_bootstrap(dev, dma_bs);
+ 	}
+-	
++
+ 	/* If we attempted to initialize the card for AGP DMA but failed,
+ 	 * clean-up any mess that may have been created.
+ 	 */
+@@ -729,7 +711,6 @@ static int mga_do_dma_bootstrap(drm_devi
+ 		mga_do_cleanup_dma(dev);
+ 	}
+ 
+-
+ 	/* Not only do we want to try and initialized PCI cards for PCI DMA,
+ 	 * but we also try to initialized AGP cards that could not be
+ 	 * initialized for AGP DMA.  This covers the case where we have an AGP
+@@ -742,7 +723,6 @@ static int mga_do_dma_bootstrap(drm_devi
+ 		err = mga_do_pci_dma_bootstrap(dev, dma_bs);
+ 	}
+ 
+-
+ 	return err;
+ }
+ 
+@@ -752,45 +732,42 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS)
+ 	drm_mga_dma_bootstrap_t bootstrap;
+ 	int err;
+ 
+-
+ 	DRM_COPY_FROM_USER_IOCTL(bootstrap,
+ 				 (drm_mga_dma_bootstrap_t __user *) data,
+ 				 sizeof(bootstrap));
+ 
+-	err = mga_do_dma_bootstrap(dev, & bootstrap);
+-	if (! err) {
++	err = mga_do_dma_bootstrap(dev, &bootstrap);
++	if (!err) {
+ 		static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
+-		const drm_mga_private_t * const dev_priv = 
+-			(drm_mga_private_t *) dev->dev_private;
++		const drm_mga_private_t *const dev_priv =
++		    (drm_mga_private_t *) dev->dev_private;
+ 
+ 		if (dev_priv->agp_textures != NULL) {
+-			bootstrap.texture_handle = dev_priv->agp_textures->offset;
++			bootstrap.texture_handle =
++			    dev_priv->agp_textures->offset;
+ 			bootstrap.texture_size = dev_priv->agp_textures->size;
+-		}
+-		else {
++		} else {
+ 			bootstrap.texture_handle = 0;
+ 			bootstrap.texture_size = 0;
+ 		}
+ 
+-		bootstrap.agp_mode = modes[ bootstrap.agp_mode & 0x07 ];
+-		if (DRM_COPY_TO_USER( (void __user *) data, & bootstrap,
++		bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07];
++		if (DRM_COPY_TO_USER((void __user *)data, &bootstrap,
+ 				     sizeof(bootstrap))) {
+ 			err = DRM_ERR(EFAULT);
+ 		}
+-	}
+-	else {
++	} else {
+ 		mga_do_cleanup_dma(dev);
+ 	}
+ 
+ 	return err;
+ }
+ 
+-static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
++static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
+ {
+ 	drm_mga_private_t *dev_priv;
+ 	int ret;
+-	DRM_DEBUG( "\n" );
+-
++	DRM_DEBUG("\n");
+ 
+ 	dev_priv = dev->dev_private;
+ 
+@@ -799,17 +776,17 @@ static int mga_do_init_dma( drm_device_t
+ 	} else {
+ 		dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;
+ 	}
+-	dev_priv->maccess	= init->maccess;
++	dev_priv->maccess = init->maccess;
+ 
+-	dev_priv->fb_cpp	= init->fb_cpp;
+-	dev_priv->front_offset	= init->front_offset;
+-	dev_priv->front_pitch	= init->front_pitch;
+-	dev_priv->back_offset	= init->back_offset;
+-	dev_priv->back_pitch	= init->back_pitch;
+-
+-	dev_priv->depth_cpp	= init->depth_cpp;
+-	dev_priv->depth_offset	= init->depth_offset;
+-	dev_priv->depth_pitch	= init->depth_pitch;
++	dev_priv->fb_cpp = init->fb_cpp;
++	dev_priv->front_offset = init->front_offset;
++	dev_priv->front_pitch = init->front_pitch;
++	dev_priv->back_offset = init->back_offset;
++	dev_priv->back_pitch = init->back_pitch;
++
++	dev_priv->depth_cpp = init->depth_cpp;
++	dev_priv->depth_offset = init->depth_offset;
++	dev_priv->depth_pitch = init->depth_pitch;
+ 
+ 	/* FIXME: Need to support AGP textures...
+ 	 */
+@@ -823,7 +800,7 @@ static int mga_do_init_dma( drm_device_t
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if (! dev_priv->used_new_dma_init) {
++	if (!dev_priv->used_new_dma_init) {
+ 
+ 		dev_priv->dma_access = MGA_PAGPXFER;
+ 		dev_priv->wagp_enable = MGA_WAGP_ENABLE;
+@@ -849,7 +826,8 @@ static int mga_do_init_dma( drm_device_t
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		dev->agp_buffer_token = init->buffers_offset;
+-		dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
++		dev->agp_buffer_map =
++		    drm_core_findmap(dev, init->buffers_offset);
+ 		if (!dev->agp_buffer_map) {
+ 			DRM_ERROR("failed to find dma buffer region!\n");
+ 			return DRM_ERR(EINVAL);
+@@ -861,8 +839,8 @@ static int mga_do_init_dma( drm_device_t
+ 	}
+ 
+ 	dev_priv->sarea_priv =
+-		(drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle +
+-				    init->sarea_priv_offset);
++	    (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle +
++				 init->sarea_priv_offset);
+ 
+ 	if (!dev_priv->warp->handle ||
+ 	    !dev_priv->primary->handle ||
+@@ -885,23 +863,20 @@ static int mga_do_init_dma( drm_device_t
+ 		return ret;
+ 	}
+ 
+-	dev_priv->prim.status = (u32 *)dev_priv->status->handle;
++	dev_priv->prim.status = (u32 *) dev_priv->status->handle;
+ 
+-	mga_do_wait_for_idle( dev_priv );
++	mga_do_wait_for_idle(dev_priv);
+ 
+ 	/* Init the primary DMA registers.
+ 	 */
+-	MGA_WRITE( MGA_PRIMADDRESS,
+-		   dev_priv->primary->offset | MGA_DMA_GENERAL );
++	MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL);
+ #if 0
+-	MGA_WRITE( MGA_PRIMPTR,
+-		   virt_to_bus((void *)dev_priv->prim.status) |
+-		   MGA_PRIMPTREN0 |	/* Soft trap, SECEND, SETUPEND */
+-		   MGA_PRIMPTREN1 );	/* DWGSYNC */
++	MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 |	/* Soft trap, SECEND, SETUPEND */
++		  MGA_PRIMPTREN1);	/* DWGSYNC */
+ #endif
+ 
+-	dev_priv->prim.start = (u8 *)dev_priv->primary->handle;
+-	dev_priv->prim.end = ((u8 *)dev_priv->primary->handle
++	dev_priv->prim.start = (u8 *) dev_priv->primary->handle;
++	dev_priv->prim.end = ((u8 *) dev_priv->primary->handle
+ 			      + dev_priv->primary->size);
+ 	dev_priv->prim.size = dev_priv->primary->size;
+ 
+@@ -929,7 +904,7 @@ static int mga_do_init_dma( drm_device_t
+ 	return 0;
+ }
+ 
+-static int mga_do_cleanup_dma( drm_device_t *dev )
++static int mga_do_cleanup_dma(drm_device_t * dev)
+ {
+ 	int err = 0;
+ 	DRM_DEBUG("\n");
+@@ -938,16 +913,17 @@ static int mga_do_cleanup_dma( drm_devic
+ 	 * may not have been called from userspace and after dev_private
+ 	 * is freed, it's too late.
+ 	 */
+-	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
++	if (dev->irq_enabled)
++		drm_irq_uninstall(dev);
+ 
+-	if ( dev->dev_private ) {
++	if (dev->dev_private) {
+ 		drm_mga_private_t *dev_priv = dev->dev_private;
+ 
+-		if ((dev_priv->warp != NULL) 
++		if ((dev_priv->warp != NULL)
+ 		    && (dev_priv->warp->type != _DRM_CONSISTENT))
+ 			drm_core_ioremapfree(dev_priv->warp, dev);
+ 
+-		if ((dev_priv->primary != NULL) 
++		if ((dev_priv->primary != NULL)
+ 		    && (dev_priv->primary->type != _DRM_CONSISTENT))
+ 			drm_core_ioremapfree(dev_priv->primary, dev);
+ 
+@@ -960,7 +936,8 @@ static int mga_do_cleanup_dma( drm_devic
+ 				dev_priv->agp_textures = NULL;
+ 				drm_unbind_agp(dev_priv->agp_mem);
+ 
+-				drm_free_agp(dev_priv->agp_mem, dev_priv->agp_pages);
++				drm_free_agp(dev_priv->agp_mem,
++					     dev_priv->agp_pages);
+ 				dev_priv->agp_pages = 0;
+ 				dev_priv->agp_mem = NULL;
+ 			}
+@@ -982,7 +959,8 @@ static int mga_do_cleanup_dma( drm_devic
+ 
+ 		memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
+ 		dev_priv->warp_pipe = 0;
+-		memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
++		memset(dev_priv->warp_pipe_phys, 0,
++		       sizeof(dev_priv->warp_pipe_phys));
+ 
+ 		if (dev_priv->head != NULL) {
+ 			mga_freelist_cleanup(dev);
+@@ -992,103 +970,102 @@ static int mga_do_cleanup_dma( drm_devic
+ 	return err;
+ }
+ 
+-int mga_dma_init( DRM_IOCTL_ARGS )
++int mga_dma_init(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_mga_init_t init;
+ 	int err;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+ 	DRM_COPY_FROM_USER_IOCTL(init, (drm_mga_init_t __user *) data,
+ 				 sizeof(init));
+ 
+-	switch ( init.func ) {
++	switch (init.func) {
+ 	case MGA_INIT_DMA:
+ 		err = mga_do_init_dma(dev, &init);
+ 		if (err) {
+-			(void) mga_do_cleanup_dma(dev);
++			(void)mga_do_cleanup_dma(dev);
+ 		}
+ 		return err;
+ 	case MGA_CLEANUP_DMA:
+-		return mga_do_cleanup_dma( dev );
++		return mga_do_cleanup_dma(dev);
+ 	}
+ 
+ 	return DRM_ERR(EINVAL);
+ }
+ 
+-
+ /* ================================================================
+  * Primary DMA stream management
+  */
+ 
+-int mga_dma_flush( DRM_IOCTL_ARGS )
++int mga_dma_flush(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+-	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
++	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ 	drm_lock_t lock;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t __user *)data, sizeof(lock) );
++	DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t __user *) data,
++				 sizeof(lock));
+ 
+-	DRM_DEBUG( "%s%s%s\n",
+-		   (lock.flags & _DRM_LOCK_FLUSH) ?	"flush, " : "",
+-		   (lock.flags & _DRM_LOCK_FLUSH_ALL) ?	"flush all, " : "",
+-		   (lock.flags & _DRM_LOCK_QUIESCENT) ?	"idle, " : "" );
++	DRM_DEBUG("%s%s%s\n",
++		  (lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "",
++		  (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "",
++		  (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "");
+ 
+-	WRAP_WAIT_WITH_RETURN( dev_priv );
++	WRAP_WAIT_WITH_RETURN(dev_priv);
+ 
+-	if ( lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL) ) {
+-		mga_do_dma_flush( dev_priv );
++	if (lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) {
++		mga_do_dma_flush(dev_priv);
+ 	}
+ 
+-	if ( lock.flags & _DRM_LOCK_QUIESCENT ) {
++	if (lock.flags & _DRM_LOCK_QUIESCENT) {
+ #if MGA_DMA_DEBUG
+-		int ret = mga_do_wait_for_idle( dev_priv );
+-		if ( ret < 0 )
+-			DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ );
++		int ret = mga_do_wait_for_idle(dev_priv);
++		if (ret < 0)
++			DRM_INFO("%s: -EBUSY\n", __FUNCTION__);
+ 		return ret;
+ #else
+-		return mga_do_wait_for_idle( dev_priv );
++		return mga_do_wait_for_idle(dev_priv);
+ #endif
+ 	} else {
+ 		return 0;
+ 	}
+ }
+ 
+-int mga_dma_reset( DRM_IOCTL_ARGS )
++int mga_dma_reset(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+-	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
++	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	return mga_do_dma_reset( dev_priv );
++	return mga_do_dma_reset(dev_priv);
+ }
+ 
+-
+ /* ================================================================
+  * DMA buffer management
+  */
+ 
+-static int mga_dma_get_buffers( DRMFILE filp,
+-				drm_device_t *dev, drm_dma_t *d )
++static int mga_dma_get_buffers(DRMFILE filp, drm_device_t * dev, drm_dma_t * d)
+ {
+ 	drm_buf_t *buf;
+ 	int i;
+ 
+-	for ( i = d->granted_count ; i < d->request_count ; i++ ) {
+-		buf = mga_freelist_get( dev );
+-		if ( !buf ) return DRM_ERR(EAGAIN);
++	for (i = d->granted_count; i < d->request_count; i++) {
++		buf = mga_freelist_get(dev);
++		if (!buf)
++			return DRM_ERR(EAGAIN);
+ 
+ 		buf->filp = filp;
+ 
+-		if ( DRM_COPY_TO_USER( &d->request_indices[i],
+-				   &buf->idx, sizeof(buf->idx) ) )
++		if (DRM_COPY_TO_USER(&d->request_indices[i],
++				     &buf->idx, sizeof(buf->idx)))
+ 			return DRM_ERR(EFAULT);
+-		if ( DRM_COPY_TO_USER( &d->request_sizes[i],
+-				   &buf->total, sizeof(buf->total) ) )
++		if (DRM_COPY_TO_USER(&d->request_sizes[i],
++				     &buf->total, sizeof(buf->total)))
+ 			return DRM_ERR(EFAULT);
+ 
+ 		d->granted_count++;
+@@ -1096,44 +1073,44 @@ static int mga_dma_get_buffers( DRMFILE 
+ 	return 0;
+ }
+ 
+-int mga_dma_buffers( DRM_IOCTL_ARGS )
++int mga_dma_buffers(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_device_dma_t *dma = dev->dma;
+-	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
++	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ 	drm_dma_t __user *argp = (void __user *)data;
+ 	drm_dma_t d;
+ 	int ret = 0;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) );
++	DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d));
+ 
+ 	/* Please don't send us buffers.
+ 	 */
+-	if ( d.send_count != 0 ) {
+-		DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
+-			   DRM_CURRENTPID, d.send_count );
++	if (d.send_count != 0) {
++		DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
++			  DRM_CURRENTPID, d.send_count);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	/* We'll send you buffers.
+ 	 */
+-	if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
+-		DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
+-			   DRM_CURRENTPID, d.request_count, dma->buf_count );
++	if (d.request_count < 0 || d.request_count > dma->buf_count) {
++		DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
++			  DRM_CURRENTPID, d.request_count, dma->buf_count);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	WRAP_TEST_WITH_RETURN( dev_priv );
++	WRAP_TEST_WITH_RETURN(dev_priv);
+ 
+ 	d.granted_count = 0;
+ 
+-	if ( d.request_count ) {
+-		ret = mga_dma_get_buffers( filp, dev, &d );
++	if (d.request_count) {
++		ret = mga_dma_get_buffers(filp, dev, &d);
+ 	}
+ 
+-	DRM_COPY_TO_USER_IOCTL( argp, d, sizeof(d) );
++	DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d));
+ 
+ 	return ret;
+ }
+@@ -1154,11 +1131,11 @@ int mga_driver_postcleanup(drm_device_t 
+  */
+ void mga_driver_pretakedown(drm_device_t * dev)
+ {
+-	mga_do_cleanup_dma( dev );
++	mga_do_cleanup_dma(dev);
+ }
+ 
+-int mga_driver_dma_quiescent(drm_device_t *dev)
++int mga_driver_dma_quiescent(drm_device_t * dev)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+-	return mga_do_wait_for_idle( dev_priv );
++	return mga_do_wait_for_idle(dev_priv);
+ }
+diff --git a/drivers/char/drm/mga_drm.h b/drivers/char/drm/mga_drm.h
+--- a/drivers/char/drm/mga_drm.h
++++ b/drivers/char/drm/mga_drm.h
+@@ -44,10 +44,10 @@
+ 
+ /* WARP pipe flags
+  */
+-#define MGA_F			0x1		/* fog */
+-#define MGA_A			0x2		/* alpha */
+-#define MGA_S			0x4		/* specular */
+-#define MGA_T2			0x8		/* multitexture */
++#define MGA_F			0x1	/* fog */
++#define MGA_A			0x2	/* alpha */
++#define MGA_S			0x4	/* specular */
++#define MGA_T2			0x8	/* multitexture */
+ 
+ #define MGA_WARP_TGZ		0
+ #define MGA_WARP_TGZF		(MGA_F)
+@@ -66,14 +66,14 @@
+ #define MGA_WARP_T2GZSA		(MGA_T2|MGA_S|MGA_A)
+ #define MGA_WARP_T2GZSAF	(MGA_T2|MGA_S|MGA_F|MGA_A)
+ 
+-#define MGA_MAX_G200_PIPES	8		/* no multitex */
++#define MGA_MAX_G200_PIPES	8	/* no multitex */
+ #define MGA_MAX_G400_PIPES	16
+ #define MGA_MAX_WARP_PIPES	MGA_MAX_G400_PIPES
+-#define MGA_WARP_UCODE_SIZE	32768		/* in bytes */
++#define MGA_WARP_UCODE_SIZE	32768	/* in bytes */
+ 
+ #define MGA_CARD_TYPE_G200	1
+ #define MGA_CARD_TYPE_G400	2
+-#define MGA_CARD_TYPE_G450	3       /* not currently used */
++#define MGA_CARD_TYPE_G450	3	/* not currently used */
+ #define MGA_CARD_TYPE_G550	4
+ 
+ #define MGA_FRONT		0x1
+@@ -86,14 +86,14 @@
+ #define MGA_UPLOAD_TEX0		0x2
+ #define MGA_UPLOAD_TEX1		0x4
+ #define MGA_UPLOAD_PIPE		0x8
+-#define MGA_UPLOAD_TEX0IMAGE	0x10 /* handled client-side */
+-#define MGA_UPLOAD_TEX1IMAGE	0x20 /* handled client-side */
++#define MGA_UPLOAD_TEX0IMAGE	0x10	/* handled client-side */
++#define MGA_UPLOAD_TEX1IMAGE	0x20	/* handled client-side */
+ #define MGA_UPLOAD_2D		0x40
+-#define MGA_WAIT_AGE		0x80 /* handled client-side */
+-#define MGA_UPLOAD_CLIPRECTS	0x100 /* handled client-side */
++#define MGA_WAIT_AGE		0x80	/* handled client-side */
++#define MGA_UPLOAD_CLIPRECTS	0x100	/* handled client-side */
+ #if 0
+-#define MGA_DMA_FLUSH		0x200 /* set when someone gets the lock
+-					 quiescent */
++#define MGA_DMA_FLUSH		0x200	/* set when someone gets the lock
++					   quiescent */
+ #endif
+ 
+ /* 32 buffers of 64k each, total 2 meg.
+@@ -120,8 +120,7 @@
+ 
+ #define  DRM_MGA_IDLE_RETRY          2048
+ 
+-#endif /* __MGA_SAREA_DEFINES__ */
+-
++#endif				/* __MGA_SAREA_DEFINES__ */
+ 
+ /* Setup registers for 3D context
+  */
+@@ -165,25 +164,25 @@ typedef struct {
+ /* General aging mechanism
+  */
+ typedef struct {
+-	unsigned int head;		/* Position of head pointer          */
+-	unsigned int wrap;		/* Primary DMA wrap count            */
++	unsigned int head;	/* Position of head pointer          */
++	unsigned int wrap;	/* Primary DMA wrap count            */
+ } drm_mga_age_t;
+ 
+ typedef struct _drm_mga_sarea {
+ 	/* The channel for communication of state information to the kernel
+ 	 * on firing a vertex dma buffer.
+ 	 */
+-   	drm_mga_context_regs_t context_state;
+-   	drm_mga_server_regs_t server_state;
+-   	drm_mga_texture_regs_t tex_state[2];
+-   	unsigned int warp_pipe;
+-   	unsigned int dirty;
+-   	unsigned int vertsize;
++	drm_mga_context_regs_t context_state;
++	drm_mga_server_regs_t server_state;
++	drm_mga_texture_regs_t tex_state[2];
++	unsigned int warp_pipe;
++	unsigned int dirty;
++	unsigned int vertsize;
+ 
+ 	/* The current cliprects, or a subset thereof.
+ 	 */
+-   	drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS];
+-   	unsigned int nbox;
++	drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS];
++	unsigned int nbox;
+ 
+ 	/* Information about the most recently used 3d drawable.  The
+ 	 * client fills in the req_* fields, the server fills in the
+@@ -192,18 +191,18 @@ typedef struct _drm_mga_sarea {
+ 	 * The client clears the exported_drawable field before
+ 	 * clobbering the boxes data.
+ 	 */
+-        unsigned int req_drawable;	 /* the X drawable id */
+-	unsigned int req_draw_buffer;	 /* MGA_FRONT or MGA_BACK */
++	unsigned int req_drawable;	/* the X drawable id */
++	unsigned int req_draw_buffer;	/* MGA_FRONT or MGA_BACK */
+ 
+-        unsigned int exported_drawable;
++	unsigned int exported_drawable;
+ 	unsigned int exported_index;
+-        unsigned int exported_stamp;
+-        unsigned int exported_buffers;
+-        unsigned int exported_nfront;
+-        unsigned int exported_nback;
++	unsigned int exported_stamp;
++	unsigned int exported_buffers;
++	unsigned int exported_nfront;
++	unsigned int exported_nback;
+ 	int exported_back_x, exported_front_x, exported_w;
+ 	int exported_back_y, exported_front_y, exported_h;
+-   	drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS];
++	drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS];
+ 
+ 	/* Counters for aging textures and for client-side throttling.
+ 	 */
+@@ -211,21 +210,20 @@ typedef struct _drm_mga_sarea {
+ 	unsigned int last_wrap;
+ 
+ 	drm_mga_age_t last_frame;
+-        unsigned int last_enqueue;	/* last time a buffer was enqueued */
++	unsigned int last_enqueue;	/* last time a buffer was enqueued */
+ 	unsigned int last_dispatch;	/* age of the most recently dispatched buffer */
+-	unsigned int last_quiescent;     /*  */
++	unsigned int last_quiescent;	/*  */
+ 
+ 	/* LRU lists for texture memory in agp space and on the card.
+ 	 */
+-	drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
++	drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1];
+ 	unsigned int texAge[MGA_NR_TEX_HEAPS];
+ 
+ 	/* Mechanism to validate card state.
+ 	 */
+-   	int ctxOwner;
++	int ctxOwner;
+ } drm_mga_sarea_t;
+ 
+-
+ /* MGA specific ioctls
+  * The device specific ioctl range is 0x40 to 0x79.
+  */
+@@ -247,7 +245,6 @@ typedef struct _drm_mga_sarea {
+ #define DRM_MGA_WAIT_FENCE     0x0b
+ #define DRM_MGA_DMA_BOOTSTRAP  0x0c
+ 
+-
+ #define DRM_IOCTL_MGA_INIT     DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
+ #define DRM_IOCTL_MGA_FLUSH    DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t)
+ #define DRM_IOCTL_MGA_RESET    DRM_IO(  DRM_COMMAND_BASE + DRM_MGA_RESET)
+@@ -263,33 +260,33 @@ typedef struct _drm_mga_sarea {
+ #define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t)
+ 
+ typedef struct _drm_mga_warp_index {
+-   	int installed;
+-   	unsigned long phys_addr;
+-   	int size;
++	int installed;
++	unsigned long phys_addr;
++	int size;
+ } drm_mga_warp_index_t;
+ 
+ typedef struct drm_mga_init {
+-   	enum {
+-	   	MGA_INIT_DMA    = 0x01,
+-	       	MGA_CLEANUP_DMA = 0x02
++	enum {
++		MGA_INIT_DMA = 0x01,
++		MGA_CLEANUP_DMA = 0x02
+ 	} func;
+ 
+-   	unsigned long sarea_priv_offset;
++	unsigned long sarea_priv_offset;
+ 
+ 	int chipset;
+-   	int sgram;
++	int sgram;
+ 
+ 	unsigned int maccess;
+ 
+-   	unsigned int fb_cpp;
++	unsigned int fb_cpp;
+ 	unsigned int front_offset, front_pitch;
+-   	unsigned int back_offset, back_pitch;
++	unsigned int back_offset, back_pitch;
+ 
+-   	unsigned int depth_cpp;
+-   	unsigned int depth_offset, depth_pitch;
++	unsigned int depth_cpp;
++	unsigned int depth_offset, depth_pitch;
+ 
+-   	unsigned int texture_offset[MGA_NR_TEX_HEAPS];
+-   	unsigned int texture_size[MGA_NR_TEX_HEAPS];
++	unsigned int texture_offset[MGA_NR_TEX_HEAPS];
++	unsigned int texture_size[MGA_NR_TEX_HEAPS];
+ 
+ 	unsigned long fb_offset;
+ 	unsigned long mmio_offset;
+@@ -302,64 +299,59 @@ typedef struct drm_mga_init {
+ typedef struct drm_mga_dma_bootstrap {
+ 	/**
+ 	 * \name AGP texture region
+-	 * 
++	 *
+ 	 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, these fields will
+ 	 * be filled in with the actual AGP texture settings.
+-	 * 
++	 *
+ 	 * \warning
+ 	 * If these fields are non-zero, but dma_mga_dma_bootstrap::agp_mode
+ 	 * is zero, it means that PCI memory (most likely through the use of
+ 	 * an IOMMU) is being used for "AGP" textures.
+ 	 */
+-	/*@{*/
++	/*@{ */
+ 	unsigned long texture_handle; /**< Handle used to map AGP textures. */
+-	uint32_t     texture_size;    /**< Size of the AGP texture region. */
+-	/*@}*/
+-
++	uint32_t texture_size;	      /**< Size of the AGP texture region. */
++	/*@} */
+ 
+ 	/**
+ 	 * Requested size of the primary DMA region.
+-	 * 
++	 *
+ 	 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
+ 	 * filled in with the actual AGP mode.  If AGP was not available
+ 	 */
+ 	uint32_t primary_size;
+ 
+-
+ 	/**
+ 	 * Requested number of secondary DMA buffers.
+-	 * 
++	 *
+ 	 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
+ 	 * filled in with the actual number of secondary DMA buffers
+ 	 * allocated.  Particularly when PCI DMA is used, this may be
+ 	 * (subtantially) less than the number requested.
+ 	 */
+ 	uint32_t secondary_bin_count;
+-	
+-	
++
+ 	/**
+ 	 * Requested size of each secondary DMA buffer.
+-	 * 
++	 *
+ 	 * While the kernel \b is free to reduce
+ 	 * dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed
+ 	 * to reduce dma_mga_dma_bootstrap::secondary_bin_size.
+ 	 */
+ 	uint32_t secondary_bin_size;
+ 
+-
+ 	/**
+ 	 * Bit-wise mask of AGPSTAT2_* values.  Currently only \c AGPSTAT2_1X,
+ 	 * \c AGPSTAT2_2X, and \c AGPSTAT2_4X are supported.  If this value is
+ 	 * zero, it means that PCI DMA should be used, even if AGP is
+ 	 * possible.
+-	 * 
++	 *
+ 	 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
+ 	 * filled in with the actual AGP mode.  If AGP was not available
+ 	 * (i.e., PCI DMA was used), this value will be zero.
+ 	 */
+ 	uint32_t agp_mode;
+ 
+-
+ 	/**
+ 	 * Desired AGP GART size, measured in megabytes.
+ 	 */
+@@ -375,16 +367,16 @@ typedef struct drm_mga_clear {
+ } drm_mga_clear_t;
+ 
+ typedef struct drm_mga_vertex {
+-   	int idx;			/* buffer to queue */
+-	int used;			/* bytes in use */
+-	int discard;			/* client finished with buffer?  */
++	int idx;		/* buffer to queue */
++	int used;		/* bytes in use */
++	int discard;		/* client finished with buffer?  */
+ } drm_mga_vertex_t;
+ 
+ typedef struct drm_mga_indices {
+-   	int idx;			/* buffer to queue */
++	int idx;		/* buffer to queue */
+ 	unsigned int start;
+ 	unsigned int end;
+-	int discard;			/* client finished with buffer?  */
++	int discard;		/* client finished with buffer?  */
+ } drm_mga_indices_t;
+ 
+ typedef struct drm_mga_iload {
+@@ -400,12 +392,12 @@ typedef struct _drm_mga_blit {
+ 	int src_pitch, dst_pitch;
+ 	int delta_sx, delta_sy;
+ 	int delta_dx, delta_dy;
+-	int height, ydir;		/* flip image vertically */
++	int height, ydir;	/* flip image vertically */
+ 	int source_pitch, dest_pitch;
+ } drm_mga_blit_t;
+ 
+ /* 3.1: An ioctl to get parameters that aren't available to the 3d
+- * client any other way.  
++ * client any other way.
+  */
+ #define MGA_PARAM_IRQ_NR            1
+ 
+diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
+--- a/drivers/char/drm/mga_drv.c
++++ b/drivers/char/drm/mga_drv.c
+@@ -35,14 +35,13 @@
+ #include "mga_drm.h"
+ #include "mga_drv.h"
+ 
+-  
+ #include "drm_pciids.h"
+ 
+ static int mga_driver_device_is_agp(drm_device_t * dev);
+-static int postinit( struct drm_device *dev, unsigned long flags )
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+-	drm_mga_private_t * const dev_priv =
+-		(drm_mga_private_t *) dev->dev_private;
++	drm_mga_private_t *const dev_priv =
++	    (drm_mga_private_t *) dev->dev_private;
+ 
+ 	dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
+ 	dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
+@@ -52,28 +51,26 @@ static int postinit( struct drm_device *
+ 	dev->types[7] = _DRM_STAT_PRIMARY;
+ 	dev->types[8] = _DRM_STAT_SECONDARY;
+ 
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->primary.minor,
+-		pci_pretty_name(dev->pdev)
+-		);
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR,
++		 DRIVER_PATCHLEVEL,
++		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
++	    );
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+@@ -81,11 +78,11 @@ static struct pci_device_id pciidlist[] 
+ 	mga_PCI_IDS
+ };
+ 
+-extern drm_ioctl_desc_t mga_ioctls[];
+-extern int mga_max_ioctl;
+-
+ static struct drm_driver driver = {
+-	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
++	.driver_features =
++	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
++	    DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
++	    DRIVER_IRQ_VBL,
+ 	.preinit = mga_driver_preinit,
+ 	.postcleanup = mga_driver_postcleanup,
+ 	.pretakedown = mga_driver_pretakedown,
+@@ -104,21 +101,21 @@ static struct drm_driver driver = {
+ 	.ioctls = mga_ioctls,
+ 	.dma_ioctl = mga_dma_buffers,
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
+ #ifdef CONFIG_COMPAT
+-		.compat_ioctl = mga_compat_ioctl,
++		 .compat_ioctl = mga_compat_ioctl,
+ #endif
+-	},
++		 },
+ 	.pci_driver = {
+-		.name = DRIVER_NAME,
+-		.id_table = pciidlist,
+-	}
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
+ };
+ 
+ static int __init mga_init(void)
+@@ -135,8 +132,8 @@ static void __exit mga_exit(void)
+ module_init(mga_init);
+ module_exit(mga_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+ 
+ /**
+@@ -151,10 +148,9 @@ MODULE_LICENSE("GPL and additional right
+  * \returns
+  * If the device is a PCI G450, zero is returned.  Otherwise 2 is returned.
+  */
+-int mga_driver_device_is_agp(drm_device_t * dev)
++static int mga_driver_device_is_agp(drm_device_t * dev)
+ {
+-	const struct pci_dev * const pdev = dev->pdev;
+-
++	const struct pci_dev *const pdev = dev->pdev;
+ 
+ 	/* There are PCI versions of the G450.  These cards have the
+ 	 * same PCI ID as the AGP G450, but have an additional PCI-to-PCI
+@@ -164,10 +160,10 @@ int mga_driver_device_is_agp(drm_device_
+ 	 * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
+ 	 * device.
+ 	 */
+-	
+-	if ( (pdev->device == 0x0525)
+-	     && (pdev->bus->self->vendor == 0x3388)
+-	     && (pdev->bus->self->device == 0x0021) ) {
++
++	if ((pdev->device == 0x0525)
++	    && (pdev->bus->self->vendor == 0x3388)
++	    && (pdev->bus->self->device == 0x0021)) {
+ 		return 0;
+ 	}
+ 
+diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
+--- a/drivers/char/drm/mga_drv.h
++++ b/drivers/char/drm/mga_drv.h
+@@ -62,14 +62,14 @@ typedef struct drm_mga_primary_buffer {
+ } drm_mga_primary_buffer_t;
+ 
+ typedef struct drm_mga_freelist {
+-   	struct drm_mga_freelist *next;
+-   	struct drm_mga_freelist *prev;
++	struct drm_mga_freelist *next;
++	struct drm_mga_freelist *prev;
+ 	drm_mga_age_t age;
+-   	drm_buf_t *buf;
++	drm_buf_t *buf;
+ } drm_mga_freelist_t;
+ 
+ typedef struct {
+-   	drm_mga_freelist_t *list_entry;
++	drm_mga_freelist_t *list_entry;
+ 	int discard;
+ 	int dispatched;
+ } drm_mga_buf_priv_t;
+@@ -78,8 +78,8 @@ typedef struct drm_mga_private {
+ 	drm_mga_primary_buffer_t prim;
+ 	drm_mga_sarea_t *sarea_priv;
+ 
+-   	drm_mga_freelist_t *head;
+-   	drm_mga_freelist_t *tail;
++	drm_mga_freelist_t *head;
++	drm_mga_freelist_t *tail;
+ 
+ 	unsigned int warp_pipe;
+ 	unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES];
+@@ -109,13 +109,13 @@ typedef struct drm_mga_private {
+ 
+ 	/**
+ 	 * \name MMIO region parameters.
+-	 * 
++	 *
+ 	 * \sa drm_mga_private_t::mmio
+ 	 */
+-	/*@{*/
+-	u32 mmio_base;             /**< Bus address of base of MMIO. */
+-	u32 mmio_size;             /**< Size of the MMIO region. */
+-	/*@}*/
++	/*@{ */
++	u32 mmio_base;		   /**< Bus address of base of MMIO. */
++	u32 mmio_size;		   /**< Size of the MMIO region. */
++	/*@} */
+ 
+ 	u32 clear_cmd;
+ 	u32 maccess;
+@@ -143,11 +143,14 @@ typedef struct drm_mga_private {
+ 	drm_local_map_t *warp;
+ 	drm_local_map_t *primary;
+ 	drm_local_map_t *agp_textures;
+-	
++
+ 	DRM_AGP_MEM *agp_mem;
+ 	unsigned int agp_pages;
+ } drm_mga_private_t;
+ 
++extern drm_ioctl_desc_t mga_ioctls[];
++extern int mga_max_ioctl;
++
+ 				/* mga_dma.c */
+ extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags);
+ extern int mga_dma_bootstrap(DRM_IOCTL_ARGS);
+@@ -165,7 +168,7 @@ extern void mga_do_dma_flush(drm_mga_pri
+ extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv);
+ extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv);
+ 
+-extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf );
++extern int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf);
+ 
+ 				/* mga_warp.c */
+ extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv);
+@@ -196,7 +199,7 @@ extern long mga_compat_ioctl(struct file
+ #define MGA_WRITE( reg, val )	do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
+ #define MGA_WRITE8( reg, val )  do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
+ 
+-static inline u32 _MGA_READ(u32 *addr)
++static inline u32 _MGA_READ(u32 * addr)
+ {
+ 	DRM_MEMORYBARRIER();
+ 	return *(volatile u32 *)addr;
+@@ -218,8 +221,6 @@ static inline u32 _MGA_READ(u32 *addr)
+ #define DMAREG1(r)	(u8)(((r - DWGREG1) >> 2) | 0x80)
+ #define DMAREG(r)	(ISREG0(r) ? DMAREG0(r) : DMAREG1(r))
+ 
+-
+-
+ /* ================================================================
+  * Helper macross...
+  */
+@@ -261,7 +262,6 @@ do {									\
+ 	}								\
+ } while (0)
+ 
+-
+ /* ================================================================
+  * Primary DMA command stream
+  */
+@@ -346,7 +346,6 @@ do {									\
+ 	write += DMA_BLOCK_SIZE;					\
+ } while (0)
+ 
+-
+ /* Buffer aging via primary DMA stream head pointer.
+  */
+ 
+@@ -373,7 +372,6 @@ do {									\
+ 	}								\
+ } while (0)
+ 
+-
+ #define MGA_ENGINE_IDLE_MASK		(MGA_SOFTRAPEN |		\
+ 					 MGA_DWGENGSTS |		\
+ 					 MGA_ENDPRDMASTS)
+@@ -382,8 +380,6 @@ do {									\
+ 
+ #define MGA_DMA_DEBUG			0
+ 
+-
+-
+ /* A reduced set of the mga registers.
+  */
+ #define MGA_CRTC_INDEX			0x1fd4
+@@ -644,7 +640,6 @@ do {									\
+ #	define MGA_G400_WR_MAGIC		(1 << 6)
+ #	define MGA_G400_WR56_MAGIC		0x46480000	/* 12800.0f */
+ 
+-
+ #define MGA_ILOAD_ALIGN		64
+ #define MGA_ILOAD_MASK		(MGA_ILOAD_ALIGN - 1)
+ 
+@@ -679,10 +674,10 @@ do {									\
+ 
+ /* Simple idle test.
+  */
+-static __inline__ int mga_is_idle( drm_mga_private_t *dev_priv )
++static __inline__ int mga_is_idle(drm_mga_private_t * dev_priv)
+ {
+-	u32 status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
+-	return ( status == MGA_ENDPRDMASTS );
++	u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
++	return (status == MGA_ENDPRDMASTS);
+ }
+ 
+ #endif
+diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c
+--- a/drivers/char/drm/mga_ioc32.c
++++ b/drivers/char/drm/mga_ioc32.c
+@@ -39,17 +39,17 @@
+ 
+ typedef struct drm32_mga_init {
+ 	int func;
+-   	u32 sarea_priv_offset;
++	u32 sarea_priv_offset;
+ 	int chipset;
+-   	int sgram;
++	int sgram;
+ 	unsigned int maccess;
+-   	unsigned int fb_cpp;
++	unsigned int fb_cpp;
+ 	unsigned int front_offset, front_pitch;
+-   	unsigned int back_offset, back_pitch;
+-   	unsigned int depth_cpp;
+-   	unsigned int depth_offset, depth_pitch;
+-   	unsigned int texture_offset[MGA_NR_TEX_HEAPS];
+-   	unsigned int texture_size[MGA_NR_TEX_HEAPS];
++	unsigned int back_offset, back_pitch;
++	unsigned int depth_cpp;
++	unsigned int depth_offset, depth_pitch;
++	unsigned int texture_offset[MGA_NR_TEX_HEAPS];
++	unsigned int texture_size[MGA_NR_TEX_HEAPS];
+ 	u32 fb_offset;
+ 	u32 mmio_offset;
+ 	u32 status_offset;
+@@ -64,10 +64,10 @@ static int compat_mga_init(struct file *
+ 	drm_mga_init32_t init32;
+ 	drm_mga_init_t __user *init;
+ 	int err = 0, i;
+-	
++
+ 	if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
+ 		return -EFAULT;
+-	
++
+ 	init = compat_alloc_user_space(sizeof(*init));
+ 	if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
+ 	    || __put_user(init32.func, &init->func)
+@@ -90,42 +90,43 @@ static int compat_mga_init(struct file *
+ 	    || __put_user(init32.primary_offset, &init->primary_offset)
+ 	    || __put_user(init32.buffers_offset, &init->buffers_offset))
+ 		return -EFAULT;
+-	
+-	for (i=0; i<MGA_NR_TEX_HEAPS; i++)
+-	{
+-		err |= __put_user(init32.texture_offset[i], &init->texture_offset[i]);
+-		err |= __put_user(init32.texture_size[i], &init->texture_size[i]);
++
++	for (i = 0; i < MGA_NR_TEX_HEAPS; i++) {
++		err |=
++		    __put_user(init32.texture_offset[i],
++			       &init->texture_offset[i]);
++		err |=
++		    __put_user(init32.texture_size[i], &init->texture_size[i]);
+ 	}
+ 	if (err)
+ 		return -EFAULT;
+-	
++
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_MGA_INIT, (unsigned long) init);
++			 DRM_IOCTL_MGA_INIT, (unsigned long)init);
+ }
+ 
+-
+ typedef struct drm_mga_getparam32 {
+ 	int param;
+ 	u32 value;
+ } drm_mga_getparam32_t;
+ 
+-
+ static int compat_mga_getparam(struct file *file, unsigned int cmd,
+ 			       unsigned long arg)
+ {
+ 	drm_mga_getparam32_t getparam32;
+ 	drm_mga_getparam_t __user *getparam;
+-	
++
+ 	if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
+ 		return -EFAULT;
+ 
+ 	getparam = compat_alloc_user_space(sizeof(*getparam));
+ 	if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
+ 	    || __put_user(getparam32.param, &getparam->param)
+-	    || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
++	    || __put_user((void __user *)(unsigned long)getparam32.value,
++			  &getparam->value))
+ 		return -EFAULT;
+ 
+-	return drm_ioctl(file->f_dentry->d_inode, file, 
++	return drm_ioctl(file->f_dentry->d_inode, file,
+ 			 DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
+ }
+ 
+@@ -182,14 +183,12 @@ static int compat_mga_dma_bootstrap(stru
+ 			  &dma_bootstrap->secondary_bin_count)
+ 	    || __get_user(dma_bootstrap32.secondary_bin_size,
+ 			  &dma_bootstrap->secondary_bin_size)
+-	    || __get_user(dma_bootstrap32.agp_mode,
+-			  &dma_bootstrap->agp_mode)
+-	    || __get_user(dma_bootstrap32.agp_size,
+-			  &dma_bootstrap->agp_size))
++	    || __get_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
++	    || __get_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
+ 		return -EFAULT;
+ 
+ 	if (copy_to_user((void __user *)arg, &dma_bootstrap32,
+-	    		 sizeof(dma_bootstrap32)))
++			 sizeof(dma_bootstrap32)))
+ 		return -EFAULT;
+ 
+ 	return 0;
+@@ -210,8 +209,7 @@ drm_ioctl_compat_t *mga_compat_ioctls[] 
+  * \param arg user argument.
+  * \return zero on success or negative number on failure.
+  */
+-long mga_compat_ioctl(struct file *filp, unsigned int cmd,
+-			 unsigned long arg)
++long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ 	unsigned int nr = DRM_IOCTL_NR(cmd);
+ 	drm_ioctl_compat_t *fn = NULL;
+@@ -219,13 +217,13 @@ long mga_compat_ioctl(struct file *filp,
+ 
+ 	if (nr < DRM_COMMAND_BASE)
+ 		return drm_compat_ioctl(filp, cmd, arg);
+-	
++
+ 	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
+ 		fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
+ 
+ 	lock_kernel();		/* XXX for now */
+ 	if (fn != NULL)
+-		ret = (*fn)(filp, cmd, arg);
++		ret = (*fn) (filp, cmd, arg);
+ 	else
+ 		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+ 	unlock_kernel();
+diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c
+--- a/drivers/char/drm/mga_irq.c
++++ b/drivers/char/drm/mga_irq.c
+@@ -1,7 +1,7 @@
+ /* mga_irq.c -- IRQ handling for radeon -*- linux-c -*-
+  *
+  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+- * 
++ *
+  * The Weather Channel (TM) funded Tungsten Graphics to develop the
+  * initial release of the Radeon 8500 driver under the XFree86 license.
+  * This notice must be preserved.
+@@ -35,19 +35,18 @@
+ #include "mga_drm.h"
+ #include "mga_drv.h"
+ 
+-irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS )
++irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
+ {
+ 	drm_device_t *dev = (drm_device_t *) arg;
+-	drm_mga_private_t *dev_priv = 
+-	   (drm_mga_private_t *)dev->dev_private;
++	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ 	int status;
+ 	int handled = 0;
+ 
+ 	status = MGA_READ(MGA_STATUS);
+ 
+ 	/* VBLANK interrupt */
+-	if ( status & MGA_VLINEPEN ) {
+-		MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR );
++	if (status & MGA_VLINEPEN) {
++		MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
+ 		atomic_inc(&dev->vbl_received);
+ 		DRM_WAKEUP(&dev->vbl_queue);
+ 		drm_vbl_send_signals(dev);
+@@ -57,15 +56,14 @@ irqreturn_t mga_driver_irq_handler( DRM_
+ 	/* SOFTRAP interrupt */
+ 	if (status & MGA_SOFTRAPEN) {
+ 		const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
+-		const u32 prim_end   = MGA_READ(MGA_PRIMEND);
+-
++		const u32 prim_end = MGA_READ(MGA_PRIMEND);
+ 
+ 		MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);
+ 
+ 		/* In addition to clearing the interrupt-pending bit, we
+ 		 * have to write to MGA_PRIMEND to re-start the DMA operation.
+ 		 */
+-		if ( (prim_start & ~0x03) != (prim_end & ~0x03) ) {
++		if ((prim_start & ~0x03) != (prim_end & ~0x03)) {
+ 			MGA_WRITE(MGA_PRIMEND, prim_end);
+ 		}
+ 
+@@ -74,24 +72,24 @@ irqreturn_t mga_driver_irq_handler( DRM_
+ 		handled = 1;
+ 	}
+ 
+-	if ( handled ) {
++	if (handled) {
+ 		return IRQ_HANDLED;
+ 	}
+ 	return IRQ_NONE;
+ }
+ 
+-int mga_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
++int mga_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
+ {
+ 	unsigned int cur_vblank;
+ 	int ret = 0;
+ 
+ 	/* Assume that the user has missed the current sequence number
+ 	 * by about a day rather than she wants to wait for years
+-	 * using vertical blanks... 
++	 * using vertical blanks...
+ 	 */
+-	DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, 
+-		     ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
+-			 - *sequence ) <= (1<<23) ) );
++	DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
++		    (((cur_vblank = atomic_read(&dev->vbl_received))
++		      - *sequence) <= (1 << 23)));
+ 
+ 	*sequence = cur_vblank;
+ 
+@@ -122,29 +120,29 @@ void mga_driver_irq_preinstall(drm_devic
+ 	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ 
+ 	/* Disable *all* interrupts */
+-      	MGA_WRITE( MGA_IEN, 0 );
++	MGA_WRITE(MGA_IEN, 0);
+ 	/* Clear bits if they're already high */
+-   	MGA_WRITE( MGA_ICLEAR, ~0 );
++	MGA_WRITE(MGA_ICLEAR, ~0);
+ }
+ 
+ void mga_driver_irq_postinstall(drm_device_t * dev)
+ {
+ 	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ 
+-	DRM_INIT_WAITQUEUE( &dev_priv->fence_queue );
++	DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
+ 
+ 	/* Turn on vertical blank interrupt and soft trap interrupt. */
+ 	MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
+ }
+ 
+-void mga_driver_irq_uninstall( drm_device_t *dev ) {
+-  	drm_mga_private_t *dev_priv = 
+-	   (drm_mga_private_t *)dev->dev_private;
++void mga_driver_irq_uninstall(drm_device_t * dev)
++{
++	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ 	if (!dev_priv)
+ 		return;
+ 
+ 	/* Disable *all* interrupts */
+ 	MGA_WRITE(MGA_IEN, 0);
+-	
++
+ 	dev->irq_enabled = 0;
+ }
+diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
+--- a/drivers/char/drm/mga_state.c
++++ b/drivers/char/drm/mga_state.c
+@@ -41,15 +41,15 @@
+  * DMA hardware state programming functions
+  */
+ 
+-static void mga_emit_clip_rect( drm_mga_private_t *dev_priv,
+-				drm_clip_rect_t *box )
++static void mga_emit_clip_rect(drm_mga_private_t * dev_priv,
++			       drm_clip_rect_t * box)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+ 	unsigned int pitch = dev_priv->front_pitch;
+ 	DMA_LOCALS;
+ 
+-	BEGIN_DMA( 2 );
++	BEGIN_DMA(2);
+ 
+ 	/* Force reset of DWGCTL on G400 (eliminates clip disable bit).
+ 	 */
+@@ -61,101 +61,90 @@ static void mga_emit_clip_rect( drm_mga_
+ 	}
+ 	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ 		  MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1,
+-		  MGA_YTOP, box->y1 * pitch,
+-		  MGA_YBOT, (box->y2 - 1) * pitch);
++		  MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch);
+ 
+ 	ADVANCE_DMA();
+ }
+ 
+-static __inline__ void mga_g200_emit_context( drm_mga_private_t *dev_priv )
++static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+ 	DMA_LOCALS;
+ 
+-	BEGIN_DMA( 3 );
++	BEGIN_DMA(3);
+ 
+-	DMA_BLOCK( MGA_DSTORG,		ctx->dstorg,
+-		   MGA_MACCESS,		ctx->maccess,
+-		   MGA_PLNWT,		ctx->plnwt,
+-		   MGA_DWGCTL,		ctx->dwgctl );
+-
+-	DMA_BLOCK( MGA_ALPHACTRL,	ctx->alphactrl,
+-		   MGA_FOGCOL,		ctx->fogcolor,
+-		   MGA_WFLAG,		ctx->wflag,
+-		   MGA_ZORG,		dev_priv->depth_offset );
+-
+-	DMA_BLOCK( MGA_FCOL,		ctx->fcol,
+-		   MGA_DMAPAD,		0x00000000,
+-		   MGA_DMAPAD,		0x00000000,
+-		   MGA_DMAPAD,		0x00000000 );
++	DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
++		  MGA_MACCESS, ctx->maccess,
++		  MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
++
++	DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
++		  MGA_FOGCOL, ctx->fogcolor,
++		  MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
++
++	DMA_BLOCK(MGA_FCOL, ctx->fcol,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
+ 
+ 	ADVANCE_DMA();
+ }
+ 
+-static __inline__ void mga_g400_emit_context( drm_mga_private_t *dev_priv )
++static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+ 	DMA_LOCALS;
+ 
+-	BEGIN_DMA( 4 );
++	BEGIN_DMA(4);
+ 
+-	DMA_BLOCK( MGA_DSTORG,		ctx->dstorg,
+-		   MGA_MACCESS,		ctx->maccess,
+-		   MGA_PLNWT,		ctx->plnwt,
+-		   MGA_DWGCTL,		ctx->dwgctl );
+-
+-	DMA_BLOCK( MGA_ALPHACTRL,	ctx->alphactrl,
+-		   MGA_FOGCOL,		ctx->fogcolor,
+-		   MGA_WFLAG,		ctx->wflag,
+-		   MGA_ZORG,		dev_priv->depth_offset );
+-
+-	DMA_BLOCK( MGA_WFLAG1,		ctx->wflag,
+-		   MGA_TDUALSTAGE0,	ctx->tdualstage0,
+-		   MGA_TDUALSTAGE1,	ctx->tdualstage1,
+-		   MGA_FCOL,		ctx->fcol );
+-
+-	DMA_BLOCK( MGA_STENCIL,		ctx->stencil,
+-		   MGA_STENCILCTL,	ctx->stencilctl,
+-		   MGA_DMAPAD,		0x00000000,
+-		   MGA_DMAPAD,		0x00000000 );
++	DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
++		  MGA_MACCESS, ctx->maccess,
++		  MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
++
++	DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
++		  MGA_FOGCOL, ctx->fogcolor,
++		  MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
++
++	DMA_BLOCK(MGA_WFLAG1, ctx->wflag,
++		  MGA_TDUALSTAGE0, ctx->tdualstage0,
++		  MGA_TDUALSTAGE1, ctx->tdualstage1, MGA_FCOL, ctx->fcol);
++
++	DMA_BLOCK(MGA_STENCIL, ctx->stencil,
++		  MGA_STENCILCTL, ctx->stencilctl,
++		  MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
+ 
+ 	ADVANCE_DMA();
+ }
+ 
+-static __inline__ void mga_g200_emit_tex0( drm_mga_private_t *dev_priv )
++static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
+ 	DMA_LOCALS;
+ 
+-	BEGIN_DMA( 4 );
++	BEGIN_DMA(4);
+ 
+-	DMA_BLOCK( MGA_TEXCTL2,		tex->texctl2,
+-		   MGA_TEXCTL,		tex->texctl,
+-		   MGA_TEXFILTER,	tex->texfilter,
+-		   MGA_TEXBORDERCOL,	tex->texbordercol );
+-
+-	DMA_BLOCK( MGA_TEXORG,		tex->texorg,
+-		   MGA_TEXORG1,		tex->texorg1,
+-		   MGA_TEXORG2,		tex->texorg2,
+-		   MGA_TEXORG3,		tex->texorg3 );
+-
+-	DMA_BLOCK( MGA_TEXORG4,		tex->texorg4,
+-		   MGA_TEXWIDTH,	tex->texwidth,
+-		   MGA_TEXHEIGHT,	tex->texheight,
+-		   MGA_WR24,		tex->texwidth );
+-
+-	DMA_BLOCK( MGA_WR34,		tex->texheight,
+-		   MGA_TEXTRANS,	0x0000ffff,
+-		   MGA_TEXTRANSHIGH,	0x0000ffff,
+-		   MGA_DMAPAD,		0x00000000 );
++	DMA_BLOCK(MGA_TEXCTL2, tex->texctl2,
++		  MGA_TEXCTL, tex->texctl,
++		  MGA_TEXFILTER, tex->texfilter,
++		  MGA_TEXBORDERCOL, tex->texbordercol);
++
++	DMA_BLOCK(MGA_TEXORG, tex->texorg,
++		  MGA_TEXORG1, tex->texorg1,
++		  MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
++
++	DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
++		  MGA_TEXWIDTH, tex->texwidth,
++		  MGA_TEXHEIGHT, tex->texheight, MGA_WR24, tex->texwidth);
++
++	DMA_BLOCK(MGA_WR34, tex->texheight,
++		  MGA_TEXTRANS, 0x0000ffff,
++		  MGA_TEXTRANSHIGH, 0x0000ffff, MGA_DMAPAD, 0x00000000);
+ 
+ 	ADVANCE_DMA();
+ }
+ 
+-static __inline__ void mga_g400_emit_tex0( drm_mga_private_t *dev_priv )
++static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
+@@ -164,42 +153,38 @@ static __inline__ void mga_g400_emit_tex
+ /*  	printk("mga_g400_emit_tex0 %x %x %x\n", tex->texorg, */
+ /*  	       tex->texctl, tex->texctl2); */
+ 
+-	BEGIN_DMA( 6 );
++	BEGIN_DMA(6);
+ 
+-	DMA_BLOCK( MGA_TEXCTL2,		tex->texctl2 | MGA_G400_TC2_MAGIC,
+-		   MGA_TEXCTL,		tex->texctl,
+-		   MGA_TEXFILTER,	tex->texfilter,
+-		   MGA_TEXBORDERCOL,	tex->texbordercol );
+-
+-	DMA_BLOCK( MGA_TEXORG,		tex->texorg,
+-		   MGA_TEXORG1,		tex->texorg1,
+-		   MGA_TEXORG2,		tex->texorg2,
+-		   MGA_TEXORG3,		tex->texorg3 );
+-
+-	DMA_BLOCK( MGA_TEXORG4,		tex->texorg4,
+-		   MGA_TEXWIDTH,	tex->texwidth,
+-		   MGA_TEXHEIGHT,	tex->texheight,
+-		   MGA_WR49,		0x00000000 );
+-
+-	DMA_BLOCK( MGA_WR57,		0x00000000,
+-		   MGA_WR53,		0x00000000,
+-		   MGA_WR61,		0x00000000,
+-		   MGA_WR52,		MGA_G400_WR_MAGIC );
+-
+-	DMA_BLOCK( MGA_WR60,		MGA_G400_WR_MAGIC,
+-		   MGA_WR54,		tex->texwidth | MGA_G400_WR_MAGIC,
+-		   MGA_WR62,		tex->texheight | MGA_G400_WR_MAGIC,
+-		   MGA_DMAPAD,		0x00000000 );
+-
+-	DMA_BLOCK( MGA_DMAPAD,		0x00000000,
+-		   MGA_DMAPAD,		0x00000000,
+-		   MGA_TEXTRANS,	0x0000ffff,
+-		   MGA_TEXTRANSHIGH,	0x0000ffff );
++	DMA_BLOCK(MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC,
++		  MGA_TEXCTL, tex->texctl,
++		  MGA_TEXFILTER, tex->texfilter,
++		  MGA_TEXBORDERCOL, tex->texbordercol);
++
++	DMA_BLOCK(MGA_TEXORG, tex->texorg,
++		  MGA_TEXORG1, tex->texorg1,
++		  MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
++
++	DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
++		  MGA_TEXWIDTH, tex->texwidth,
++		  MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000);
++
++	DMA_BLOCK(MGA_WR57, 0x00000000,
++		  MGA_WR53, 0x00000000,
++		  MGA_WR61, 0x00000000, MGA_WR52, MGA_G400_WR_MAGIC);
++
++	DMA_BLOCK(MGA_WR60, MGA_G400_WR_MAGIC,
++		  MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC,
++		  MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC,
++		  MGA_DMAPAD, 0x00000000);
++
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_TEXTRANS, 0x0000ffff, MGA_TEXTRANSHIGH, 0x0000ffff);
+ 
+ 	ADVANCE_DMA();
+ }
+ 
+-static __inline__ void mga_g400_emit_tex1( drm_mga_private_t *dev_priv )
++static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1];
+@@ -208,55 +193,51 @@ static __inline__ void mga_g400_emit_tex
+ /*  	printk("mga_g400_emit_tex1 %x %x %x\n", tex->texorg,  */
+ /*  	       tex->texctl, tex->texctl2); */
+ 
+-	BEGIN_DMA( 5 );
++	BEGIN_DMA(5);
+ 
+-	DMA_BLOCK( MGA_TEXCTL2,		(tex->texctl2 |
+-					 MGA_MAP1_ENABLE |
+-					 MGA_G400_TC2_MAGIC),
+-		   MGA_TEXCTL,		tex->texctl,
+-		   MGA_TEXFILTER,	tex->texfilter,
+-		   MGA_TEXBORDERCOL,	tex->texbordercol );
+-
+-	DMA_BLOCK( MGA_TEXORG,		tex->texorg,
+-		   MGA_TEXORG1,		tex->texorg1,
+-		   MGA_TEXORG2,		tex->texorg2,
+-		   MGA_TEXORG3,		tex->texorg3 );
+-
+-	DMA_BLOCK( MGA_TEXORG4,		tex->texorg4,
+-		   MGA_TEXWIDTH,	tex->texwidth,
+-		   MGA_TEXHEIGHT,	tex->texheight,
+-		   MGA_WR49,		0x00000000 );
+-
+-	DMA_BLOCK( MGA_WR57,		0x00000000,
+-		   MGA_WR53,		0x00000000,
+-		   MGA_WR61,		0x00000000,
+-		   MGA_WR52,		tex->texwidth | MGA_G400_WR_MAGIC );
+-
+-	DMA_BLOCK( MGA_WR60,		tex->texheight | MGA_G400_WR_MAGIC,
+-		   MGA_TEXTRANS,	0x0000ffff,
+-		   MGA_TEXTRANSHIGH,	0x0000ffff,
+-		   MGA_TEXCTL2,		tex->texctl2 | MGA_G400_TC2_MAGIC );
++	DMA_BLOCK(MGA_TEXCTL2, (tex->texctl2 |
++				MGA_MAP1_ENABLE |
++				MGA_G400_TC2_MAGIC),
++		  MGA_TEXCTL, tex->texctl,
++		  MGA_TEXFILTER, tex->texfilter,
++		  MGA_TEXBORDERCOL, tex->texbordercol);
++
++	DMA_BLOCK(MGA_TEXORG, tex->texorg,
++		  MGA_TEXORG1, tex->texorg1,
++		  MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
++
++	DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
++		  MGA_TEXWIDTH, tex->texwidth,
++		  MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000);
++
++	DMA_BLOCK(MGA_WR57, 0x00000000,
++		  MGA_WR53, 0x00000000,
++		  MGA_WR61, 0x00000000,
++		  MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC);
++
++	DMA_BLOCK(MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC,
++		  MGA_TEXTRANS, 0x0000ffff,
++		  MGA_TEXTRANSHIGH, 0x0000ffff,
++		  MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC);
+ 
+ 	ADVANCE_DMA();
+ }
+ 
+-static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv )
++static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	unsigned int pipe = sarea_priv->warp_pipe;
+ 	DMA_LOCALS;
+ 
+-	BEGIN_DMA( 3 );
++	BEGIN_DMA(3);
+ 
+-	DMA_BLOCK( MGA_WIADDR,	MGA_WMODE_SUSPEND,
+-		   MGA_WVRTXSZ,	0x00000007,
+-		   MGA_WFLAG,	0x00000000,
+-		   MGA_WR24,	0x00000000 );
+-
+-	DMA_BLOCK( MGA_WR25,	0x00000100,
+-		   MGA_WR34,	0x00000000,
+-		   MGA_WR42,	0x0000ffff,
+-		   MGA_WR60,	0x0000ffff );
++	DMA_BLOCK(MGA_WIADDR, MGA_WMODE_SUSPEND,
++		  MGA_WVRTXSZ, 0x00000007,
++		  MGA_WFLAG, 0x00000000, MGA_WR24, 0x00000000);
++
++	DMA_BLOCK(MGA_WR25, 0x00000100,
++		  MGA_WR34, 0x00000000,
++		  MGA_WR42, 0x0000ffff, MGA_WR60, 0x0000ffff);
+ 
+ 	/* Padding required to to hardware bug.
+ 	 */
+@@ -269,7 +250,7 @@ static __inline__ void mga_g200_emit_pip
+ 	ADVANCE_DMA();
+ }
+ 
+-static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv )
++static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	unsigned int pipe = sarea_priv->warp_pipe;
+@@ -277,68 +258,64 @@ static __inline__ void mga_g400_emit_pip
+ 
+ /*  	printk("mga_g400_emit_pipe %x\n", pipe); */
+ 
+-	BEGIN_DMA( 10 );
++	BEGIN_DMA(10);
+ 
+-	DMA_BLOCK( MGA_WIADDR2,	MGA_WMODE_SUSPEND,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000 );
+-
+-	if ( pipe & MGA_T2 ) {
+-		DMA_BLOCK( MGA_WVRTXSZ,		0x00001e09,
+-			   MGA_DMAPAD,		0x00000000,
+-			   MGA_DMAPAD,		0x00000000,
+-			   MGA_DMAPAD,		0x00000000 );
+-
+-		DMA_BLOCK( MGA_WACCEPTSEQ,	0x00000000,
+-			   MGA_WACCEPTSEQ,	0x00000000,
+-			   MGA_WACCEPTSEQ,	0x00000000,
+-			   MGA_WACCEPTSEQ,	0x1e000000 );
++	DMA_BLOCK(MGA_WIADDR2, MGA_WMODE_SUSPEND,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
++
++	if (pipe & MGA_T2) {
++		DMA_BLOCK(MGA_WVRTXSZ, 0x00001e09,
++			  MGA_DMAPAD, 0x00000000,
++			  MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
++
++		DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000,
++			  MGA_WACCEPTSEQ, 0x00000000,
++			  MGA_WACCEPTSEQ, 0x00000000,
++			  MGA_WACCEPTSEQ, 0x1e000000);
+ 	} else {
+-		if ( dev_priv->warp_pipe & MGA_T2 ) {
++		if (dev_priv->warp_pipe & MGA_T2) {
+ 			/* Flush the WARP pipe */
+-			DMA_BLOCK( MGA_YDST,		0x00000000,
+-				   MGA_FXLEFT,		0x00000000,
+-				   MGA_FXRIGHT,		0x00000001,
+-				   MGA_DWGCTL,		MGA_DWGCTL_FLUSH );
+-
+-			DMA_BLOCK( MGA_LEN + MGA_EXEC,	0x00000001,
+-				   MGA_DWGSYNC,		0x00007000,
+-				   MGA_TEXCTL2,		MGA_G400_TC2_MAGIC,
+-				   MGA_LEN + MGA_EXEC,	0x00000000 );
+-
+-			DMA_BLOCK( MGA_TEXCTL2,		(MGA_DUALTEX |
+-							 MGA_G400_TC2_MAGIC),
+-				   MGA_LEN + MGA_EXEC,	0x00000000,
+-				   MGA_TEXCTL2,		MGA_G400_TC2_MAGIC,
+-				   MGA_DMAPAD,		0x00000000 );
++			DMA_BLOCK(MGA_YDST, 0x00000000,
++				  MGA_FXLEFT, 0x00000000,
++				  MGA_FXRIGHT, 0x00000001,
++				  MGA_DWGCTL, MGA_DWGCTL_FLUSH);
++
++			DMA_BLOCK(MGA_LEN + MGA_EXEC, 0x00000001,
++				  MGA_DWGSYNC, 0x00007000,
++				  MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
++				  MGA_LEN + MGA_EXEC, 0x00000000);
++
++			DMA_BLOCK(MGA_TEXCTL2, (MGA_DUALTEX |
++						MGA_G400_TC2_MAGIC),
++				  MGA_LEN + MGA_EXEC, 0x00000000,
++				  MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
++				  MGA_DMAPAD, 0x00000000);
+ 		}
+ 
+-		DMA_BLOCK( MGA_WVRTXSZ,		0x00001807,
+-			   MGA_DMAPAD,		0x00000000,
+-			   MGA_DMAPAD,		0x00000000,
+-			   MGA_DMAPAD,		0x00000000 );
+-
+-		DMA_BLOCK( MGA_WACCEPTSEQ,	0x00000000,
+-			   MGA_WACCEPTSEQ,	0x00000000,
+-			   MGA_WACCEPTSEQ,	0x00000000,
+-			   MGA_WACCEPTSEQ,	0x18000000 );
+-	}
+-
+-	DMA_BLOCK( MGA_WFLAG,	0x00000000,
+-		   MGA_WFLAG1,	0x00000000,
+-		   MGA_WR56,	MGA_G400_WR56_MAGIC,
+-		   MGA_DMAPAD,	0x00000000 );
+-
+-	DMA_BLOCK( MGA_WR49,	0x00000000,		/* tex0              */
+-		   MGA_WR57,	0x00000000,		/* tex0              */
+-		   MGA_WR53,	0x00000000,		/* tex1              */
+-		   MGA_WR61,	0x00000000 );		/* tex1              */
+-
+-	DMA_BLOCK( MGA_WR54,	MGA_G400_WR_MAGIC,	/* tex0 width        */
+-		   MGA_WR62,	MGA_G400_WR_MAGIC,	/* tex0 height       */
+-		   MGA_WR52,	MGA_G400_WR_MAGIC,	/* tex1 width        */
+-		   MGA_WR60,	MGA_G400_WR_MAGIC );	/* tex1 height       */
++		DMA_BLOCK(MGA_WVRTXSZ, 0x00001807,
++			  MGA_DMAPAD, 0x00000000,
++			  MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
++
++		DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000,
++			  MGA_WACCEPTSEQ, 0x00000000,
++			  MGA_WACCEPTSEQ, 0x00000000,
++			  MGA_WACCEPTSEQ, 0x18000000);
++	}
++
++	DMA_BLOCK(MGA_WFLAG, 0x00000000,
++		  MGA_WFLAG1, 0x00000000,
++		  MGA_WR56, MGA_G400_WR56_MAGIC, MGA_DMAPAD, 0x00000000);
++
++	DMA_BLOCK(MGA_WR49, 0x00000000,	/* tex0              */
++		  MGA_WR57, 0x00000000,	/* tex0              */
++		  MGA_WR53, 0x00000000,	/* tex1              */
++		  MGA_WR61, 0x00000000);	/* tex1              */
++
++	DMA_BLOCK(MGA_WR54, MGA_G400_WR_MAGIC,	/* tex0 width        */
++		  MGA_WR62, MGA_G400_WR_MAGIC,	/* tex0 height       */
++		  MGA_WR52, MGA_G400_WR_MAGIC,	/* tex1 width        */
++		  MGA_WR60, MGA_G400_WR_MAGIC);	/* tex1 height       */
+ 
+ 	/* Padding required to to hardware bug */
+ 	DMA_BLOCK(MGA_DMAPAD, 0xffffffff,
+@@ -350,71 +327,70 @@ static __inline__ void mga_g400_emit_pip
+ 	ADVANCE_DMA();
+ }
+ 
+-static void mga_g200_emit_state( drm_mga_private_t *dev_priv )
++static void mga_g200_emit_state(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	unsigned int dirty = sarea_priv->dirty;
+ 
+-	if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) {
+-		mga_g200_emit_pipe( dev_priv );
++	if (sarea_priv->warp_pipe != dev_priv->warp_pipe) {
++		mga_g200_emit_pipe(dev_priv);
+ 		dev_priv->warp_pipe = sarea_priv->warp_pipe;
+ 	}
+ 
+-	if ( dirty & MGA_UPLOAD_CONTEXT ) {
+-		mga_g200_emit_context( dev_priv );
++	if (dirty & MGA_UPLOAD_CONTEXT) {
++		mga_g200_emit_context(dev_priv);
+ 		sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
+ 	}
+ 
+-	if ( dirty & MGA_UPLOAD_TEX0 ) {
+-		mga_g200_emit_tex0( dev_priv );
++	if (dirty & MGA_UPLOAD_TEX0) {
++		mga_g200_emit_tex0(dev_priv);
+ 		sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
+ 	}
+ }
+ 
+-static void mga_g400_emit_state( drm_mga_private_t *dev_priv )
++static void mga_g400_emit_state(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	unsigned int dirty = sarea_priv->dirty;
+ 	int multitex = sarea_priv->warp_pipe & MGA_T2;
+ 
+-	if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) {
+-		mga_g400_emit_pipe( dev_priv );
++	if (sarea_priv->warp_pipe != dev_priv->warp_pipe) {
++		mga_g400_emit_pipe(dev_priv);
+ 		dev_priv->warp_pipe = sarea_priv->warp_pipe;
+ 	}
+ 
+-	if ( dirty & MGA_UPLOAD_CONTEXT ) {
+-		mga_g400_emit_context( dev_priv );
++	if (dirty & MGA_UPLOAD_CONTEXT) {
++		mga_g400_emit_context(dev_priv);
+ 		sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
+ 	}
+ 
+-	if ( dirty & MGA_UPLOAD_TEX0 ) {
+-		mga_g400_emit_tex0( dev_priv );
++	if (dirty & MGA_UPLOAD_TEX0) {
++		mga_g400_emit_tex0(dev_priv);
+ 		sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
+ 	}
+ 
+-	if ( (dirty & MGA_UPLOAD_TEX1) && multitex ) {
+-		mga_g400_emit_tex1( dev_priv );
++	if ((dirty & MGA_UPLOAD_TEX1) && multitex) {
++		mga_g400_emit_tex1(dev_priv);
+ 		sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
+ 	}
+ }
+ 
+-
+ /* ================================================================
+  * SAREA state verification
+  */
+ 
+ /* Disallow all write destinations except the front and backbuffer.
+  */
+-static int mga_verify_context( drm_mga_private_t *dev_priv )
++static int mga_verify_context(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+ 
+-	if ( ctx->dstorg != dev_priv->front_offset &&
+-	     ctx->dstorg != dev_priv->back_offset ) {
+-		DRM_ERROR( "*** bad DSTORG: %x (front %x, back %x)\n\n",
+-			   ctx->dstorg, dev_priv->front_offset,
+-			   dev_priv->back_offset );
++	if (ctx->dstorg != dev_priv->front_offset &&
++	    ctx->dstorg != dev_priv->back_offset) {
++		DRM_ERROR("*** bad DSTORG: %x (front %x, back %x)\n\n",
++			  ctx->dstorg, dev_priv->front_offset,
++			  dev_priv->back_offset);
+ 		ctx->dstorg = 0;
+ 		return DRM_ERR(EINVAL);
+ 	}
+@@ -424,7 +400,7 @@ static int mga_verify_context( drm_mga_p
+ 
+ /* Disallow texture reads from PCI space.
+  */
+-static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit )
++static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit];
+@@ -432,9 +408,8 @@ static int mga_verify_tex( drm_mga_priva
+ 
+ 	org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK);
+ 
+-	if ( org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI) ) {
+-		DRM_ERROR( "*** bad TEXORG: 0x%x, unit %d\n",
+-			   tex->texorg, unit );
++	if (org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI)) {
++		DRM_ERROR("*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit);
+ 		tex->texorg = 0;
+ 		return DRM_ERR(EINVAL);
+ 	}
+@@ -442,73 +417,70 @@ static int mga_verify_tex( drm_mga_priva
+ 	return 0;
+ }
+ 
+-static int mga_verify_state( drm_mga_private_t *dev_priv )
++static int mga_verify_state(drm_mga_private_t * dev_priv)
+ {
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	unsigned int dirty = sarea_priv->dirty;
+ 	int ret = 0;
+ 
+-	if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
++	if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+ 		sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
+ 
+-	if ( dirty & MGA_UPLOAD_CONTEXT )
+-		ret |= mga_verify_context( dev_priv );
++	if (dirty & MGA_UPLOAD_CONTEXT)
++		ret |= mga_verify_context(dev_priv);
+ 
+-	if ( dirty & MGA_UPLOAD_TEX0 )
+-		ret |= mga_verify_tex( dev_priv, 0 );
++	if (dirty & MGA_UPLOAD_TEX0)
++		ret |= mga_verify_tex(dev_priv, 0);
+ 
+ 	if (dev_priv->chipset >= MGA_CARD_TYPE_G400) {
+ 		if (dirty & MGA_UPLOAD_TEX1)
+ 			ret |= mga_verify_tex(dev_priv, 1);
+ 
+-		if ( dirty & MGA_UPLOAD_PIPE )
+-			ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES );
++		if (dirty & MGA_UPLOAD_PIPE)
++			ret |= (sarea_priv->warp_pipe > MGA_MAX_G400_PIPES);
+ 	} else {
+-		if ( dirty & MGA_UPLOAD_PIPE )
+-			ret |= ( sarea_priv->warp_pipe > MGA_MAX_G200_PIPES );
++		if (dirty & MGA_UPLOAD_PIPE)
++			ret |= (sarea_priv->warp_pipe > MGA_MAX_G200_PIPES);
+ 	}
+ 
+-	return ( ret == 0 );
++	return (ret == 0);
+ }
+ 
+-static int mga_verify_iload( drm_mga_private_t *dev_priv,
+-			     unsigned int dstorg, unsigned int length )
++static int mga_verify_iload(drm_mga_private_t * dev_priv,
++			    unsigned int dstorg, unsigned int length)
+ {
+-	if ( dstorg < dev_priv->texture_offset ||
+-	     dstorg + length > (dev_priv->texture_offset +
+-				dev_priv->texture_size) ) {
+-		DRM_ERROR( "*** bad iload DSTORG: 0x%x\n", dstorg );
++	if (dstorg < dev_priv->texture_offset ||
++	    dstorg + length > (dev_priv->texture_offset +
++			       dev_priv->texture_size)) {
++		DRM_ERROR("*** bad iload DSTORG: 0x%x\n", dstorg);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( length & MGA_ILOAD_MASK ) {
+-		DRM_ERROR( "*** bad iload length: 0x%x\n",
+-			   length & MGA_ILOAD_MASK );
++	if (length & MGA_ILOAD_MASK) {
++		DRM_ERROR("*** bad iload length: 0x%x\n",
++			  length & MGA_ILOAD_MASK);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-static int mga_verify_blit( drm_mga_private_t *dev_priv,
+-			    unsigned int srcorg, unsigned int dstorg )
++static int mga_verify_blit(drm_mga_private_t * dev_priv,
++			   unsigned int srcorg, unsigned int dstorg)
+ {
+-	if ( (srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ||
+-	     (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ) {
+-		DRM_ERROR( "*** bad blit: src=0x%x dst=0x%x\n",
+-			   srcorg, dstorg );
++	if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ||
++	    (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM)) {
++		DRM_ERROR("*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 	return 0;
+ }
+ 
+-
+ /* ================================================================
+  *
+  */
+ 
+-static void mga_dma_dispatch_clear( drm_device_t *dev,
+-				    drm_mga_clear_t *clear )
++static void mga_dma_dispatch_clear(drm_device_t * dev, drm_mga_clear_t * clear)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+@@ -517,92 +489,86 @@ static void mga_dma_dispatch_clear( drm_
+ 	int nbox = sarea_priv->nbox;
+ 	int i;
+ 	DMA_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	BEGIN_DMA( 1 );
++	BEGIN_DMA(1);
+ 
+-	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_DWGSYNC,	0x00007100,
+-		   MGA_DWGSYNC,	0x00007000 );
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
+ 
+ 	ADVANCE_DMA();
+ 
+-	for ( i = 0 ; i < nbox ; i++ ) {
++	for (i = 0; i < nbox; i++) {
+ 		drm_clip_rect_t *box = &pbox[i];
+ 		u32 height = box->y2 - box->y1;
+ 
+-		DRM_DEBUG( "   from=%d,%d to=%d,%d\n",
+-			   box->x1, box->y1, box->x2, box->y2 );
++		DRM_DEBUG("   from=%d,%d to=%d,%d\n",
++			  box->x1, box->y1, box->x2, box->y2);
+ 
+-		if ( clear->flags & MGA_FRONT ) {
+-			BEGIN_DMA( 2 );
++		if (clear->flags & MGA_FRONT) {
++			BEGIN_DMA(2);
+ 
+-			DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-				   MGA_PLNWT,	clear->color_mask,
+-				   MGA_YDSTLEN, (box->y1 << 16) | height,
+-				   MGA_FXBNDRY, (box->x2 << 16) | box->x1 );
+-
+-			DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-				   MGA_FCOL,	clear->clear_color,
+-				   MGA_DSTORG,	dev_priv->front_offset,
+-				   MGA_DWGCTL + MGA_EXEC,
+-						dev_priv->clear_cmd );
++			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++				  MGA_PLNWT, clear->color_mask,
++				  MGA_YDSTLEN, (box->y1 << 16) | height,
++				  MGA_FXBNDRY, (box->x2 << 16) | box->x1);
++
++			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++				  MGA_FCOL, clear->clear_color,
++				  MGA_DSTORG, dev_priv->front_offset,
++				  MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
+ 
+ 			ADVANCE_DMA();
+ 		}
+ 
++		if (clear->flags & MGA_BACK) {
++			BEGIN_DMA(2);
+ 
+-		if ( clear->flags & MGA_BACK ) {
+-			BEGIN_DMA( 2 );
++			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++				  MGA_PLNWT, clear->color_mask,
++				  MGA_YDSTLEN, (box->y1 << 16) | height,
++				  MGA_FXBNDRY, (box->x2 << 16) | box->x1);
+ 
+-			DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-				   MGA_PLNWT,	clear->color_mask,
+-				   MGA_YDSTLEN, (box->y1 << 16) | height,
+-				   MGA_FXBNDRY, (box->x2 << 16) | box->x1 );
+-
+-			DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-				   MGA_FCOL,	clear->clear_color,
+-				   MGA_DSTORG,	dev_priv->back_offset,
+-				   MGA_DWGCTL + MGA_EXEC,
+-						dev_priv->clear_cmd );
++			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++				  MGA_FCOL, clear->clear_color,
++				  MGA_DSTORG, dev_priv->back_offset,
++				  MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
+ 
+ 			ADVANCE_DMA();
+ 		}
+ 
+-		if ( clear->flags & MGA_DEPTH ) {
+-			BEGIN_DMA( 2 );
++		if (clear->flags & MGA_DEPTH) {
++			BEGIN_DMA(2);
++
++			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++				  MGA_PLNWT, clear->depth_mask,
++				  MGA_YDSTLEN, (box->y1 << 16) | height,
++				  MGA_FXBNDRY, (box->x2 << 16) | box->x1);
+ 
+-			DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-				   MGA_PLNWT,	clear->depth_mask,
+-				   MGA_YDSTLEN, (box->y1 << 16) | height,
+-				   MGA_FXBNDRY, (box->x2 << 16) | box->x1 );
+-
+-			DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-				   MGA_FCOL,	clear->clear_depth,
+-				   MGA_DSTORG,	dev_priv->depth_offset,
+-				   MGA_DWGCTL + MGA_EXEC,
+-						dev_priv->clear_cmd );
++			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++				  MGA_FCOL, clear->clear_depth,
++				  MGA_DSTORG, dev_priv->depth_offset,
++				  MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
+ 
+ 			ADVANCE_DMA();
+ 		}
+ 
+ 	}
+ 
+-	BEGIN_DMA( 1 );
++	BEGIN_DMA(1);
+ 
+ 	/* Force reset of DWGCTL */
+-	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_PLNWT,	ctx->plnwt,
+-		   MGA_DWGCTL,	ctx->dwgctl );
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
+ 
+ 	ADVANCE_DMA();
+ 
+ 	FLUSH_DMA();
+ }
+ 
+-static void mga_dma_dispatch_swap( drm_device_t *dev )
++static void mga_dma_dispatch_swap(drm_device_t * dev)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+@@ -611,56 +577,52 @@ static void mga_dma_dispatch_swap( drm_d
+ 	int nbox = sarea_priv->nbox;
+ 	int i;
+ 	DMA_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	sarea_priv->last_frame.head = dev_priv->prim.tail;
+ 	sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
+ 
+-	BEGIN_DMA( 4 + nbox );
++	BEGIN_DMA(4 + nbox);
++
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
+ 
+-	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_DWGSYNC,	0x00007100,
+-		   MGA_DWGSYNC,	0x00007000 );
+-
+-	DMA_BLOCK( MGA_DSTORG,	dev_priv->front_offset,
+-		   MGA_MACCESS,	dev_priv->maccess,
+-		   MGA_SRCORG,	dev_priv->back_offset,
+-		   MGA_AR5,	dev_priv->front_pitch );
+-
+-	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_PLNWT,	0xffffffff,
+-		   MGA_DWGCTL,	MGA_DWGCTL_COPY );
++	DMA_BLOCK(MGA_DSTORG, dev_priv->front_offset,
++		  MGA_MACCESS, dev_priv->maccess,
++		  MGA_SRCORG, dev_priv->back_offset,
++		  MGA_AR5, dev_priv->front_pitch);
+ 
+-	for ( i = 0 ; i < nbox ; i++ ) {
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_PLNWT, 0xffffffff, MGA_DWGCTL, MGA_DWGCTL_COPY);
++
++	for (i = 0; i < nbox; i++) {
+ 		drm_clip_rect_t *box = &pbox[i];
+ 		u32 height = box->y2 - box->y1;
+ 		u32 start = box->y1 * dev_priv->front_pitch;
+ 
+-		DRM_DEBUG( "   from=%d,%d to=%d,%d\n",
+-			   box->x1, box->y1, box->x2, box->y2 );
++		DRM_DEBUG("   from=%d,%d to=%d,%d\n",
++			  box->x1, box->y1, box->x2, box->y2);
+ 
+-		DMA_BLOCK( MGA_AR0,	start + box->x2 - 1,
+-			   MGA_AR3,	start + box->x1,
+-			   MGA_FXBNDRY,	((box->x2 - 1) << 16) | box->x1,
+-			   MGA_YDSTLEN + MGA_EXEC,
+-					(box->y1 << 16) | height );
++		DMA_BLOCK(MGA_AR0, start + box->x2 - 1,
++			  MGA_AR3, start + box->x1,
++			  MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1,
++			  MGA_YDSTLEN + MGA_EXEC, (box->y1 << 16) | height);
+ 	}
+ 
+-	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-		   MGA_PLNWT,	ctx->plnwt,
+-		   MGA_SRCORG,	dev_priv->front_offset,
+-		   MGA_DWGCTL,	ctx->dwgctl );
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_PLNWT, ctx->plnwt,
++		  MGA_SRCORG, dev_priv->front_offset, MGA_DWGCTL, ctx->dwgctl);
+ 
+ 	ADVANCE_DMA();
+ 
+ 	FLUSH_DMA();
+ 
+-	DRM_DEBUG( "%s... done.\n", __FUNCTION__ );
++	DRM_DEBUG("%s... done.\n", __FUNCTION__);
+ }
+ 
+-static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
++static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
+@@ -669,20 +631,20 @@ static void mga_dma_dispatch_vertex( drm
+ 	u32 length = (u32) buf->used;
+ 	int i = 0;
+ 	DMA_LOCALS;
+-	DRM_DEBUG( "vertex: buf=%d used=%d\n", buf->idx, buf->used );
++	DRM_DEBUG("vertex: buf=%d used=%d\n", buf->idx, buf->used);
+ 
+-	if ( buf->used ) {
++	if (buf->used) {
+ 		buf_priv->dispatched = 1;
+ 
+-		MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );
++		MGA_EMIT_STATE(dev_priv, sarea_priv->dirty);
+ 
+ 		do {
+-			if ( i < sarea_priv->nbox ) {
+-				mga_emit_clip_rect( dev_priv,
+-						    &sarea_priv->boxes[i] );
++			if (i < sarea_priv->nbox) {
++				mga_emit_clip_rect(dev_priv,
++						   &sarea_priv->boxes[i]);
+ 			}
+ 
+-			BEGIN_DMA( 1 );
++			BEGIN_DMA(1);
+ 
+ 			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ 				  MGA_DMAPAD, 0x00000000,
+@@ -692,23 +654,23 @@ static void mga_dma_dispatch_vertex( drm
+ 					       dev_priv->dma_access));
+ 
+ 			ADVANCE_DMA();
+-		} while ( ++i < sarea_priv->nbox );
++		} while (++i < sarea_priv->nbox);
+ 	}
+ 
+-	if ( buf_priv->discard ) {
+-		AGE_BUFFER( buf_priv );
++	if (buf_priv->discard) {
++		AGE_BUFFER(buf_priv);
+ 		buf->pending = 0;
+ 		buf->used = 0;
+ 		buf_priv->dispatched = 0;
+ 
+-		mga_freelist_put( dev, buf );
++		mga_freelist_put(dev, buf);
+ 	}
+ 
+ 	FLUSH_DMA();
+ }
+ 
+-static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf,
+-				      unsigned int start, unsigned int end )
++static void mga_dma_dispatch_indices(drm_device_t * dev, drm_buf_t * buf,
++				     unsigned int start, unsigned int end)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
+@@ -716,20 +678,20 @@ static void mga_dma_dispatch_indices( dr
+ 	u32 address = (u32) buf->bus_address;
+ 	int i = 0;
+ 	DMA_LOCALS;
+-	DRM_DEBUG( "indices: buf=%d start=%d end=%d\n", buf->idx, start, end );
++	DRM_DEBUG("indices: buf=%d start=%d end=%d\n", buf->idx, start, end);
+ 
+-	if ( start != end ) {
++	if (start != end) {
+ 		buf_priv->dispatched = 1;
+ 
+-		MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );
++		MGA_EMIT_STATE(dev_priv, sarea_priv->dirty);
+ 
+ 		do {
+-			if ( i < sarea_priv->nbox ) {
+-				mga_emit_clip_rect( dev_priv,
+-						    &sarea_priv->boxes[i] );
++			if (i < sarea_priv->nbox) {
++				mga_emit_clip_rect(dev_priv,
++						   &sarea_priv->boxes[i]);
+ 			}
+ 
+-			BEGIN_DMA( 1 );
++			BEGIN_DMA(1);
+ 
+ 			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ 				  MGA_DMAPAD, 0x00000000,
+@@ -738,16 +700,16 @@ static void mga_dma_dispatch_indices( dr
+ 						 dev_priv->dma_access));
+ 
+ 			ADVANCE_DMA();
+-		} while ( ++i < sarea_priv->nbox );
++		} while (++i < sarea_priv->nbox);
+ 	}
+ 
+-	if ( buf_priv->discard ) {
+-		AGE_BUFFER( buf_priv );
++	if (buf_priv->discard) {
++		AGE_BUFFER(buf_priv);
+ 		buf->pending = 0;
+ 		buf->used = 0;
+ 		buf_priv->dispatched = 0;
+ 
+-		mga_freelist_put( dev, buf );
++		mga_freelist_put(dev, buf);
+ 	}
+ 
+ 	FLUSH_DMA();
+@@ -756,61 +718,55 @@ static void mga_dma_dispatch_indices( dr
+ /* This copies a 64 byte aligned agp region to the frambuffer with a
+  * standard blit, the ioctl needs to do checking.
+  */
+-static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf,
+-				    unsigned int dstorg, unsigned int length )
++static void mga_dma_dispatch_iload(drm_device_t * dev, drm_buf_t * buf,
++				   unsigned int dstorg, unsigned int length)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
+ 	drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state;
+-	u32 srcorg = buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM;
++	u32 srcorg =
++	    buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM;
+ 	u32 y2;
+ 	DMA_LOCALS;
+-	DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used );
++	DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
+ 
+ 	y2 = length / 64;
+ 
+-	BEGIN_DMA( 5 );
++	BEGIN_DMA(5);
+ 
+-	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_DWGSYNC,	0x00007100,
+-		   MGA_DWGSYNC,	0x00007000 );
+-
+-	DMA_BLOCK( MGA_DSTORG,	dstorg,
+-		   MGA_MACCESS,	0x00000000,
+-		   MGA_SRCORG,	srcorg,
+-		   MGA_AR5,	64 );
+-
+-	DMA_BLOCK( MGA_PITCH,	64,
+-		   MGA_PLNWT,	0xffffffff,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_DWGCTL,	MGA_DWGCTL_COPY );
+-
+-	DMA_BLOCK( MGA_AR0,	63,
+-		   MGA_AR3,	0,
+-		   MGA_FXBNDRY,	(63 << 16) | 0,
+-		   MGA_YDSTLEN + MGA_EXEC, y2 );
+-
+-	DMA_BLOCK( MGA_PLNWT,	ctx->plnwt,
+-		   MGA_SRCORG,	dev_priv->front_offset,
+-		   MGA_PITCH,	dev_priv->front_pitch,
+-		   MGA_DWGSYNC,	0x00007000 );
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
++
++	DMA_BLOCK(MGA_DSTORG, dstorg,
++		  MGA_MACCESS, 0x00000000, MGA_SRCORG, srcorg, MGA_AR5, 64);
++
++	DMA_BLOCK(MGA_PITCH, 64,
++		  MGA_PLNWT, 0xffffffff,
++		  MGA_DMAPAD, 0x00000000, MGA_DWGCTL, MGA_DWGCTL_COPY);
++
++	DMA_BLOCK(MGA_AR0, 63,
++		  MGA_AR3, 0,
++		  MGA_FXBNDRY, (63 << 16) | 0, MGA_YDSTLEN + MGA_EXEC, y2);
++
++	DMA_BLOCK(MGA_PLNWT, ctx->plnwt,
++		  MGA_SRCORG, dev_priv->front_offset,
++		  MGA_PITCH, dev_priv->front_pitch, MGA_DWGSYNC, 0x00007000);
+ 
+ 	ADVANCE_DMA();
+ 
+-	AGE_BUFFER( buf_priv );
++	AGE_BUFFER(buf_priv);
+ 
+ 	buf->pending = 0;
+ 	buf->used = 0;
+ 	buf_priv->dispatched = 0;
+ 
+-	mga_freelist_put( dev, buf );
++	mga_freelist_put(dev, buf);
+ 
+ 	FLUSH_DMA();
+ }
+ 
+-static void mga_dma_dispatch_blit( drm_device_t *dev,
+-				   drm_mga_blit_t *blit )
++static void mga_dma_dispatch_blit(drm_device_t * dev, drm_mga_blit_t * blit)
+ {
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+@@ -819,26 +775,24 @@ static void mga_dma_dispatch_blit( drm_d
+ 	int nbox = sarea_priv->nbox;
+ 	u32 scandir = 0, i;
+ 	DMA_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	BEGIN_DMA( 4 + nbox );
++	BEGIN_DMA(4 + nbox);
++
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_DMAPAD, 0x00000000,
++		  MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
+ 
+-	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-		   MGA_DMAPAD,	0x00000000,
+-		   MGA_DWGSYNC,	0x00007100,
+-		   MGA_DWGSYNC,	0x00007000 );
+-
+-	DMA_BLOCK( MGA_DWGCTL,	MGA_DWGCTL_COPY,
+-		   MGA_PLNWT,	blit->planemask,
+-		   MGA_SRCORG,	blit->srcorg,
+-		   MGA_DSTORG,	blit->dstorg );
+-
+-	DMA_BLOCK( MGA_SGN,	scandir,
+-		   MGA_MACCESS,	dev_priv->maccess,
+-		   MGA_AR5,	blit->ydir * blit->src_pitch,
+-		   MGA_PITCH,	blit->dst_pitch );
++	DMA_BLOCK(MGA_DWGCTL, MGA_DWGCTL_COPY,
++		  MGA_PLNWT, blit->planemask,
++		  MGA_SRCORG, blit->srcorg, MGA_DSTORG, blit->dstorg);
++
++	DMA_BLOCK(MGA_SGN, scandir,
++		  MGA_MACCESS, dev_priv->maccess,
++		  MGA_AR5, blit->ydir * blit->src_pitch,
++		  MGA_PITCH, blit->dst_pitch);
+ 
+-	for ( i = 0 ; i < nbox ; i++ ) {
++	for (i = 0; i < nbox; i++) {
+ 		int srcx = pbox[i].x1 + blit->delta_sx;
+ 		int srcy = pbox[i].y1 + blit->delta_sy;
+ 		int dstx = pbox[i].x1 + blit->delta_dx;
+@@ -847,52 +801,51 @@ static void mga_dma_dispatch_blit( drm_d
+ 		int w = pbox[i].x2 - pbox[i].x1 - 1;
+ 		int start;
+ 
+-		if ( blit->ydir == -1 ) {
++		if (blit->ydir == -1) {
+ 			srcy = blit->height - srcy - 1;
+ 		}
+ 
+ 		start = srcy * blit->src_pitch + srcx;
+ 
+-		DMA_BLOCK( MGA_AR0,	start + w,
+-			   MGA_AR3,	start,
+-			   MGA_FXBNDRY,	((dstx + w) << 16) | (dstx & 0xffff),
+-			   MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h );
++		DMA_BLOCK(MGA_AR0, start + w,
++			  MGA_AR3, start,
++			  MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff),
++			  MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h);
+ 	}
+ 
+ 	/* Do something to flush AGP?
+ 	 */
+ 
+ 	/* Force reset of DWGCTL */
+-	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
+-		   MGA_PLNWT,	ctx->plnwt,
+-		   MGA_PITCH,	dev_priv->front_pitch,
+-		   MGA_DWGCTL,	ctx->dwgctl );
++	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
++		  MGA_PLNWT, ctx->plnwt,
++		  MGA_PITCH, dev_priv->front_pitch, MGA_DWGCTL, ctx->dwgctl);
+ 
+ 	ADVANCE_DMA();
+ }
+ 
+-
+ /* ================================================================
+  *
+  */
+ 
+-static int mga_dma_clear( DRM_IOCTL_ARGS )
++static int mga_dma_clear(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_clear_t clear;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( clear, (drm_mga_clear_t __user *)data, sizeof(clear) );
++	DRM_COPY_FROM_USER_IOCTL(clear, (drm_mga_clear_t __user *) data,
++				 sizeof(clear));
+ 
+-	if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
++	if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+ 		sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
+ 
+-	WRAP_TEST_WITH_RETURN( dev_priv );
++	WRAP_TEST_WITH_RETURN(dev_priv);
+ 
+-	mga_dma_dispatch_clear( dev, &clear );
++	mga_dma_dispatch_clear(dev, &clear);
+ 
+ 	/* Make sure we restore the 3D state next time.
+ 	 */
+@@ -901,20 +854,20 @@ static int mga_dma_clear( DRM_IOCTL_ARGS
+ 	return 0;
+ }
+ 
+-static int mga_dma_swap( DRM_IOCTL_ARGS )
++static int mga_dma_swap(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
++	if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+ 		sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
+ 
+-	WRAP_TEST_WITH_RETURN( dev_priv );
++	WRAP_TEST_WITH_RETURN(dev_priv);
+ 
+-	mga_dma_dispatch_swap( dev );
++	mga_dma_dispatch_swap(dev);
+ 
+ 	/* Make sure we restore the 3D state next time.
+ 	 */
+@@ -923,7 +876,7 @@ static int mga_dma_swap( DRM_IOCTL_ARGS 
+ 	return 0;
+ }
+ 
+-static int mga_dma_vertex( DRM_IOCTL_ARGS )
++static int mga_dma_vertex(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+@@ -932,37 +885,38 @@ static int mga_dma_vertex( DRM_IOCTL_ARG
+ 	drm_mga_buf_priv_t *buf_priv;
+ 	drm_mga_vertex_t vertex;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( vertex,
+-			     (drm_mga_vertex_t __user *)data,
+-			     sizeof(vertex) );
++	DRM_COPY_FROM_USER_IOCTL(vertex,
++				 (drm_mga_vertex_t __user *) data,
++				 sizeof(vertex));
+ 
+-        if(vertex.idx < 0 || vertex.idx > dma->buf_count) return DRM_ERR(EINVAL);
++	if (vertex.idx < 0 || vertex.idx > dma->buf_count)
++		return DRM_ERR(EINVAL);
+ 	buf = dma->buflist[vertex.idx];
+ 	buf_priv = buf->dev_private;
+ 
+ 	buf->used = vertex.used;
+ 	buf_priv->discard = vertex.discard;
+ 
+-	if ( !mga_verify_state( dev_priv ) ) {
+-		if ( vertex.discard ) {
+-			if ( buf_priv->dispatched == 1 )
+-				AGE_BUFFER( buf_priv );
++	if (!mga_verify_state(dev_priv)) {
++		if (vertex.discard) {
++			if (buf_priv->dispatched == 1)
++				AGE_BUFFER(buf_priv);
+ 			buf_priv->dispatched = 0;
+-			mga_freelist_put( dev, buf );
++			mga_freelist_put(dev, buf);
+ 		}
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	WRAP_TEST_WITH_RETURN( dev_priv );
++	WRAP_TEST_WITH_RETURN(dev_priv);
+ 
+-	mga_dma_dispatch_vertex( dev, buf );
++	mga_dma_dispatch_vertex(dev, buf);
+ 
+ 	return 0;
+ }
+ 
+-static int mga_dma_indices( DRM_IOCTL_ARGS )
++static int mga_dma_indices(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+@@ -971,37 +925,38 @@ static int mga_dma_indices( DRM_IOCTL_AR
+ 	drm_mga_buf_priv_t *buf_priv;
+ 	drm_mga_indices_t indices;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( indices,
+-			     (drm_mga_indices_t __user *)data,
+-			     sizeof(indices) );
++	DRM_COPY_FROM_USER_IOCTL(indices,
++				 (drm_mga_indices_t __user *) data,
++				 sizeof(indices));
+ 
+-        if(indices.idx < 0 || indices.idx > dma->buf_count) return DRM_ERR(EINVAL);
++	if (indices.idx < 0 || indices.idx > dma->buf_count)
++		return DRM_ERR(EINVAL);
+ 
+ 	buf = dma->buflist[indices.idx];
+ 	buf_priv = buf->dev_private;
+ 
+ 	buf_priv->discard = indices.discard;
+ 
+-	if ( !mga_verify_state( dev_priv ) ) {
+-		if ( indices.discard ) {
+-			if ( buf_priv->dispatched == 1 )
+-				AGE_BUFFER( buf_priv );
++	if (!mga_verify_state(dev_priv)) {
++		if (indices.discard) {
++			if (buf_priv->dispatched == 1)
++				AGE_BUFFER(buf_priv);
+ 			buf_priv->dispatched = 0;
+-			mga_freelist_put( dev, buf );
++			mga_freelist_put(dev, buf);
+ 		}
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	WRAP_TEST_WITH_RETURN( dev_priv );
++	WRAP_TEST_WITH_RETURN(dev_priv);
+ 
+-	mga_dma_dispatch_indices( dev, buf, indices.start, indices.end );
++	mga_dma_dispatch_indices(dev, buf, indices.start, indices.end);
+ 
+ 	return 0;
+ }
+ 
+-static int mga_dma_iload( DRM_IOCTL_ARGS )
++static int mga_dma_iload(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_device_dma_t *dma = dev->dma;
+@@ -1009,32 +964,34 @@ static int mga_dma_iload( DRM_IOCTL_ARGS
+ 	drm_buf_t *buf;
+ 	drm_mga_buf_priv_t *buf_priv;
+ 	drm_mga_iload_t iload;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( iload, (drm_mga_iload_t __user *)data, sizeof(iload) );
++	DRM_COPY_FROM_USER_IOCTL(iload, (drm_mga_iload_t __user *) data,
++				 sizeof(iload));
+ 
+ #if 0
+-	if ( mga_do_wait_for_idle( dev_priv ) < 0 ) {
+-		if ( MGA_DMA_DEBUG )
+-			DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ );
++	if (mga_do_wait_for_idle(dev_priv) < 0) {
++		if (MGA_DMA_DEBUG)
++			DRM_INFO("%s: -EBUSY\n", __FUNCTION__);
+ 		return DRM_ERR(EBUSY);
+ 	}
+ #endif
+-        if(iload.idx < 0 || iload.idx > dma->buf_count) return DRM_ERR(EINVAL);
++	if (iload.idx < 0 || iload.idx > dma->buf_count)
++		return DRM_ERR(EINVAL);
+ 
+ 	buf = dma->buflist[iload.idx];
+ 	buf_priv = buf->dev_private;
+ 
+-	if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) {
+-		mga_freelist_put( dev, buf );
++	if (mga_verify_iload(dev_priv, iload.dstorg, iload.length)) {
++		mga_freelist_put(dev, buf);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	WRAP_TEST_WITH_RETURN( dev_priv );
++	WRAP_TEST_WITH_RETURN(dev_priv);
+ 
+-	mga_dma_dispatch_iload( dev, buf, iload.dstorg, iload.length );
++	mga_dma_dispatch_iload(dev, buf, iload.dstorg, iload.length);
+ 
+ 	/* Make sure we restore the 3D state next time.
+ 	 */
+@@ -1043,27 +1000,28 @@ static int mga_dma_iload( DRM_IOCTL_ARGS
+ 	return 0;
+ }
+ 
+-static int mga_dma_blit( DRM_IOCTL_ARGS )
++static int mga_dma_blit(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_mga_blit_t blit;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( blit, (drm_mga_blit_t __user *)data, sizeof(blit) );
++	DRM_COPY_FROM_USER_IOCTL(blit, (drm_mga_blit_t __user *) data,
++				 sizeof(blit));
+ 
+-	if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
++	if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+ 		sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
+ 
+-	if ( mga_verify_blit( dev_priv, blit.srcorg, blit.dstorg ) )
++	if (mga_verify_blit(dev_priv, blit.srcorg, blit.dstorg))
+ 		return DRM_ERR(EINVAL);
+ 
+-	WRAP_TEST_WITH_RETURN( dev_priv );
++	WRAP_TEST_WITH_RETURN(dev_priv);
+ 
+-	mga_dma_dispatch_blit( dev, &blit );
++	mga_dma_dispatch_blit(dev, &blit);
+ 
+ 	/* Make sure we restore the 3D state next time.
+ 	 */
+@@ -1072,24 +1030,24 @@ static int mga_dma_blit( DRM_IOCTL_ARGS 
+ 	return 0;
+ }
+ 
+-static int mga_getparam( DRM_IOCTL_ARGS )
++static int mga_getparam(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_mga_private_t *dev_priv = dev->dev_private;
+ 	drm_mga_getparam_t param;
+ 	int value;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( param, (drm_mga_getparam_t __user *)data,
+-			     sizeof(param) );
++	DRM_COPY_FROM_USER_IOCTL(param, (drm_mga_getparam_t __user *) data,
++				 sizeof(param));
+ 
+-	DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
++	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
+ 
+-	switch( param.param ) {
++	switch (param.param) {
+ 	case MGA_PARAM_IRQ_NR:
+ 		value = dev->irq;
+ 		break;
+@@ -1100,11 +1058,11 @@ static int mga_getparam( DRM_IOCTL_ARGS 
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
+-		DRM_ERROR( "copy_to_user\n" );
++	if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) {
++		DRM_ERROR("copy_to_user\n");
+ 		return DRM_ERR(EFAULT);
+ 	}
+-	
++
+ 	return 0;
+ }
+ 
+@@ -1132,11 +1090,10 @@ static int mga_set_fence(DRM_IOCTL_ARGS)
+ 	BEGIN_DMA(1);
+ 	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ 		  MGA_DMAPAD, 0x00000000,
+-		  MGA_DMAPAD, 0x00000000,
+-		  MGA_SOFTRAP, 0x00000000);
++		  MGA_DMAPAD, 0x00000000, MGA_SOFTRAP, 0x00000000);
+ 	ADVANCE_DMA();
+ 
+-	if (DRM_COPY_TO_USER( (u32 __user *) data, & temp, sizeof(u32))) {
++	if (DRM_COPY_TO_USER((u32 __user *) data, &temp, sizeof(u32))) {
+ 		DRM_ERROR("copy_to_user\n");
+ 		return DRM_ERR(EFAULT);
+ 	}
+@@ -1159,9 +1116,9 @@ static int mga_wait_fence(DRM_IOCTL_ARGS
+ 
+ 	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
+ 
+-	mga_driver_fence_wait(dev, & fence);
++	mga_driver_fence_wait(dev, &fence);
+ 
+-	if (DRM_COPY_TO_USER( (u32 __user *) data, & fence, sizeof(u32))) {
++	if (DRM_COPY_TO_USER((u32 __user *) data, &fence, sizeof(u32))) {
+ 		DRM_ERROR("copy_to_user\n");
+ 		return DRM_ERR(EFAULT);
+ 	}
+@@ -1183,7 +1140,6 @@ drm_ioctl_desc_t mga_ioctls[] = {
+ 	[DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0},
+ 	[DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0},
+ 	[DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1},
+-
+ };
+ 
+ int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls);
+diff --git a/drivers/char/drm/mga_ucode.h b/drivers/char/drm/mga_ucode.h
+--- a/drivers/char/drm/mga_ucode.h
++++ b/drivers/char/drm/mga_ucode.h
+@@ -40,11606 +40,11606 @@
+ 
+ static unsigned char warp_g200_tgz[] = {
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x98, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x98, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x81, 0x04,
+-0x89, 0x04,
+-0x01, 0x04,
+-0x09, 0x04,
++	0x81, 0x04,
++	0x89, 0x04,
++	0x01, 0x04,
++	0x09, 0x04,
+ 
+-0xC9, 0x41, 0xC0, 0xEC,
+-0x11, 0x04,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC0, 0xEC,
++	0x11, 0x04,
++	0x00, 0xE0,
+ 
+-0x41, 0xCC, 0x41, 0xCD,
+-0x49, 0xCC, 0x49, 0xCD,
++	0x41, 0xCC, 0x41, 0xCD,
++	0x49, 0xCC, 0x49, 0xCD,
+ 
+-0xD1, 0x41, 0xC0, 0xEC,
+-0x51, 0xCC, 0x51, 0xCD,
++	0xD1, 0x41, 0xC0, 0xEC,
++	0x51, 0xCC, 0x51, 0xCD,
+ 
+-0x80, 0x04,
+-0x10, 0x04,
+-0x08, 0x04,
+-0x00, 0xE0,
++	0x80, 0x04,
++	0x10, 0x04,
++	0x08, 0x04,
++	0x00, 0xE0,
+ 
+-0x00, 0xCC, 0xC0, 0xCD,
+-0xD1, 0x49, 0xC0, 0xEC,
++	0x00, 0xCC, 0xC0, 0xCD,
++	0xD1, 0x49, 0xC0, 0xEC,
+ 
+-0x8A, 0x1F, 0x20, 0xE9,
+-0x8B, 0x3F, 0x20, 0xE9,
++	0x8A, 0x1F, 0x20, 0xE9,
++	0x8B, 0x3F, 0x20, 0xE9,
+ 
+-0x41, 0x3C, 0x41, 0xAD,
+-0x49, 0x3C, 0x49, 0xAD,
++	0x41, 0x3C, 0x41, 0xAD,
++	0x49, 0x3C, 0x49, 0xAD,
+ 
+-0x10, 0xCC, 0x10, 0xCD,
+-0x08, 0xCC, 0x08, 0xCD,
++	0x10, 0xCC, 0x10, 0xCD,
++	0x08, 0xCC, 0x08, 0xCD,
+ 
+-0xB9, 0x41, 0x49, 0xBB,
+-0x1F, 0xF0, 0x41, 0xCD,
++	0xB9, 0x41, 0x49, 0xBB,
++	0x1F, 0xF0, 0x41, 0xCD,
+ 
+-0x51, 0x3C, 0x51, 0xAD,
+-0x00, 0x98, 0x80, 0xE9,
++	0x51, 0x3C, 0x51, 0xAD,
++	0x00, 0x98, 0x80, 0xE9,
+ 
+-0x72, 0x80, 0x07, 0xEA,
+-0x24, 0x1F, 0x20, 0xE9,
++	0x72, 0x80, 0x07, 0xEA,
++	0x24, 0x1F, 0x20, 0xE9,
+ 
+-0x15, 0x41, 0x49, 0xBD,
+-0x1D, 0x41, 0x51, 0xBD,
++	0x15, 0x41, 0x49, 0xBD,
++	0x1D, 0x41, 0x51, 0xBD,
+ 
+-0x2E, 0x41, 0x2A, 0xB8,
+-0x34, 0x53, 0xA0, 0xE8,
++	0x2E, 0x41, 0x2A, 0xB8,
++	0x34, 0x53, 0xA0, 0xE8,
+ 
+-0x15, 0x30,
+-0x1D, 0x30,
+-0x58, 0xE3,
+-0x00, 0xE0,
++	0x15, 0x30,
++	0x1D, 0x30,
++	0x58, 0xE3,
++	0x00, 0xE0,
+ 
+-0xB5, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0xB5, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x24, 0x43, 0xA0, 0xE8,
+-0x2C, 0x4B, 0xA0, 0xE8,
++	0x24, 0x43, 0xA0, 0xE8,
++	0x2C, 0x4B, 0xA0, 0xE8,
+ 
+-0x15, 0x72,
+-0x09, 0xE3,
+-0x00, 0xE0,
+-0x1D, 0x72,
++	0x15, 0x72,
++	0x09, 0xE3,
++	0x00, 0xE0,
++	0x1D, 0x72,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0x97, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x97, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6C, 0x64, 0xC8, 0xEC,
+-0x98, 0xE1,
+-0xB5, 0x05,
++	0x6C, 0x64, 0xC8, 0xEC,
++	0x98, 0xE1,
++	0xB5, 0x05,
+ 
+-0xBD, 0x05,
+-0x2E, 0x30,
+-0x32, 0xC0, 0xA0, 0xE8,
++	0xBD, 0x05,
++	0x2E, 0x30,
++	0x32, 0xC0, 0xA0, 0xE8,
+ 
+-0x33, 0xC0, 0xA0, 0xE8,
+-0x74, 0x64, 0xC8, 0xEC,
++	0x33, 0xC0, 0xA0, 0xE8,
++	0x74, 0x64, 0xC8, 0xEC,
+ 
+-0x40, 0x3C, 0x40, 0xAD,
+-0x32, 0x6A,
+-0x2A, 0x30,
++	0x40, 0x3C, 0x40, 0xAD,
++	0x32, 0x6A,
++	0x2A, 0x30,
+ 
+-0x20, 0x73,
+-0x33, 0x6A,
+-0x00, 0xE0,
+-0x28, 0x73,
++	0x20, 0x73,
++	0x33, 0x6A,
++	0x00, 0xE0,
++	0x28, 0x73,
+ 
+-0x1C, 0x72,
+-0x83, 0xE2,
+-0x60, 0x80, 0x15, 0xEA,
++	0x1C, 0x72,
++	0x83, 0xE2,
++	0x60, 0x80, 0x15, 0xEA,
+ 
+-0xB8, 0x3D, 0x28, 0xDF,
+-0x30, 0x35, 0x20, 0xDF,
++	0xB8, 0x3D, 0x28, 0xDF,
++	0x30, 0x35, 0x20, 0xDF,
+ 
+-0x40, 0x30,
+-0x00, 0xE0,
+-0xCC, 0xE2,
+-0x64, 0x72,
++	0x40, 0x30,
++	0x00, 0xE0,
++	0xCC, 0xE2,
++	0x64, 0x72,
+ 
+-0x25, 0x42, 0x52, 0xBF,
+-0x2D, 0x42, 0x4A, 0xBF,
++	0x25, 0x42, 0x52, 0xBF,
++	0x2D, 0x42, 0x4A, 0xBF,
+ 
+-0x30, 0x2E, 0x30, 0xDF,
+-0x38, 0x2E, 0x38, 0xDF,
++	0x30, 0x2E, 0x30, 0xDF,
++	0x38, 0x2E, 0x38, 0xDF,
+ 
+-0x18, 0x1D, 0x45, 0xE9,
+-0x1E, 0x15, 0x45, 0xE9,
++	0x18, 0x1D, 0x45, 0xE9,
++	0x1E, 0x15, 0x45, 0xE9,
+ 
+-0x2B, 0x49, 0x51, 0xBD,
+-0x00, 0xE0,
+-0x1F, 0x73,
++	0x2B, 0x49, 0x51, 0xBD,
++	0x00, 0xE0,
++	0x1F, 0x73,
+ 
+-0x38, 0x38, 0x40, 0xAF,
+-0x30, 0x30, 0x40, 0xAF,
++	0x38, 0x38, 0x40, 0xAF,
++	0x30, 0x30, 0x40, 0xAF,
+ 
+-0x24, 0x1F, 0x24, 0xDF,
+-0x1D, 0x32, 0x20, 0xE9,
++	0x24, 0x1F, 0x24, 0xDF,
++	0x1D, 0x32, 0x20, 0xE9,
+ 
+-0x2C, 0x1F, 0x2C, 0xDF,
+-0x1A, 0x33, 0x20, 0xE9,
++	0x2C, 0x1F, 0x2C, 0xDF,
++	0x1A, 0x33, 0x20, 0xE9,
+ 
+-0xB0, 0x10,
+-0x08, 0xE3,
+-0x40, 0x10,
+-0xB8, 0x10,
++	0xB0, 0x10,
++	0x08, 0xE3,
++	0x40, 0x10,
++	0xB8, 0x10,
+ 
+-0x26, 0xF0, 0x30, 0xCD,
+-0x2F, 0xF0, 0x38, 0xCD,
++	0x26, 0xF0, 0x30, 0xCD,
++	0x2F, 0xF0, 0x38, 0xCD,
+ 
+-0x2B, 0x80, 0x20, 0xE9,
+-0x2A, 0x80, 0x20, 0xE9,
++	0x2B, 0x80, 0x20, 0xE9,
++	0x2A, 0x80, 0x20, 0xE9,
+ 
+-0xA6, 0x20,
+-0x88, 0xE2,
+-0x00, 0xE0,
+-0xAF, 0x20,
++	0xA6, 0x20,
++	0x88, 0xE2,
++	0x00, 0xE0,
++	0xAF, 0x20,
+ 
+-0x28, 0x2A, 0x26, 0xAF,
+-0x20, 0x2A, 0xC0, 0xAF,
++	0x28, 0x2A, 0x26, 0xAF,
++	0x20, 0x2A, 0xC0, 0xAF,
+ 
+-0x34, 0x1F, 0x34, 0xDF,
+-0x46, 0x24, 0x46, 0xDF,
++	0x34, 0x1F, 0x34, 0xDF,
++	0x46, 0x24, 0x46, 0xDF,
+ 
+-0x28, 0x30, 0x80, 0xBF,
+-0x20, 0x38, 0x80, 0xBF,
++	0x28, 0x30, 0x80, 0xBF,
++	0x20, 0x38, 0x80, 0xBF,
+ 
+-0x47, 0x24, 0x47, 0xDF,
+-0x4E, 0x2C, 0x4E, 0xDF,
++	0x47, 0x24, 0x47, 0xDF,
++	0x4E, 0x2C, 0x4E, 0xDF,
+ 
+-0x4F, 0x2C, 0x4F, 0xDF,
+-0x56, 0x34, 0x56, 0xDF,
++	0x4F, 0x2C, 0x4F, 0xDF,
++	0x56, 0x34, 0x56, 0xDF,
+ 
+-0x28, 0x15, 0x28, 0xDF,
+-0x20, 0x1D, 0x20, 0xDF,
++	0x28, 0x15, 0x28, 0xDF,
++	0x20, 0x1D, 0x20, 0xDF,
+ 
+-0x57, 0x34, 0x57, 0xDF,
+-0x00, 0xE0,
+-0x1D, 0x05,
++	0x57, 0x34, 0x57, 0xDF,
++	0x00, 0xE0,
++	0x1D, 0x05,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x89, 0xE2,
+-0x2B, 0x30,
++	0x04, 0x80, 0x10, 0xEA,
++	0x89, 0xE2,
++	0x2B, 0x30,
+ 
+-0x3F, 0xC1, 0x1D, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0xC1, 0x1D, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x68,
+-0xBF, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x68,
++	0xBF, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x20, 0xC0, 0x20, 0xAF,
+-0x28, 0x05,
+-0x97, 0x74,
++	0x20, 0xC0, 0x20, 0xAF,
++	0x28, 0x05,
++	0x97, 0x74,
+ 
+-0x00, 0xE0,
+-0x2A, 0x10,
+-0x16, 0xC0, 0x20, 0xE9,
++	0x00, 0xE0,
++	0x2A, 0x10,
++	0x16, 0xC0, 0x20, 0xE9,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x8C, 0xE2,
+-0x95, 0x05,
++	0x04, 0x80, 0x10, 0xEA,
++	0x8C, 0xE2,
++	0x95, 0x05,
+ 
+-0x28, 0xC1, 0x28, 0xAD,
+-0x1F, 0xC1, 0x15, 0xBD,
++	0x28, 0xC1, 0x28, 0xAD,
++	0x1F, 0xC1, 0x15, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA8, 0x67,
+-0x9F, 0x6B,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA8, 0x67,
++	0x9F, 0x6B,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x28, 0xC0, 0x28, 0xAD,
+-0x1D, 0x25,
+-0x20, 0x05,
++	0x28, 0xC0, 0x28, 0xAD,
++	0x1D, 0x25,
++	0x20, 0x05,
+ 
+-0x28, 0x32, 0x80, 0xAD,
+-0x40, 0x2A, 0x40, 0xBD,
++	0x28, 0x32, 0x80, 0xAD,
++	0x40, 0x2A, 0x40, 0xBD,
+ 
+-0x1C, 0x80, 0x20, 0xE9,
+-0x20, 0x33, 0x20, 0xAD,
++	0x1C, 0x80, 0x20, 0xE9,
++	0x20, 0x33, 0x20, 0xAD,
+ 
+-0x20, 0x73,
+-0x00, 0xE0,
+-0xB6, 0x49, 0x51, 0xBB,
++	0x20, 0x73,
++	0x00, 0xE0,
++	0xB6, 0x49, 0x51, 0xBB,
+ 
+-0x26, 0x2F, 0xB0, 0xE8,
+-0x19, 0x20, 0x20, 0xE9,
++	0x26, 0x2F, 0xB0, 0xE8,
++	0x19, 0x20, 0x20, 0xE9,
+ 
+-0x35, 0x20, 0x35, 0xDF,
+-0x3D, 0x20, 0x3D, 0xDF,
++	0x35, 0x20, 0x35, 0xDF,
++	0x3D, 0x20, 0x3D, 0xDF,
+ 
+-0x15, 0x20, 0x15, 0xDF,
+-0x1D, 0x20, 0x1D, 0xDF,
++	0x15, 0x20, 0x15, 0xDF,
++	0x1D, 0x20, 0x1D, 0xDF,
+ 
+-0x26, 0xD0, 0x26, 0xCD,
+-0x29, 0x49, 0x2A, 0xB8,
++	0x26, 0xD0, 0x26, 0xCD,
++	0x29, 0x49, 0x2A, 0xB8,
+ 
+-0x26, 0x40, 0x80, 0xBD,
+-0x3B, 0x48, 0x50, 0xBD,
++	0x26, 0x40, 0x80, 0xBD,
++	0x3B, 0x48, 0x50, 0xBD,
+ 
+-0x3E, 0x54, 0x57, 0x9F,
+-0x00, 0xE0,
+-0x82, 0xE1,
++	0x3E, 0x54, 0x57, 0x9F,
++	0x00, 0xE0,
++	0x82, 0xE1,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x26, 0x30,
+-0x29, 0x30,
+-0x48, 0x3C, 0x48, 0xAD,
++	0x26, 0x30,
++	0x29, 0x30,
++	0x48, 0x3C, 0x48, 0xAD,
+ 
+-0x2B, 0x72,
+-0xC2, 0xE1,
+-0x2C, 0xC0, 0x44, 0xC2,
++	0x2B, 0x72,
++	0xC2, 0xE1,
++	0x2C, 0xC0, 0x44, 0xC2,
+ 
+-0x05, 0x24, 0x34, 0xBF,
+-0x0D, 0x24, 0x2C, 0xBF,
++	0x05, 0x24, 0x34, 0xBF,
++	0x0D, 0x24, 0x2C, 0xBF,
+ 
+-0x2D, 0x46, 0x4E, 0xBF,
+-0x25, 0x46, 0x56, 0xBF,
++	0x2D, 0x46, 0x4E, 0xBF,
++	0x25, 0x46, 0x56, 0xBF,
+ 
+-0x20, 0x1D, 0x6F, 0x8F,
+-0x32, 0x3E, 0x5F, 0xE9,
++	0x20, 0x1D, 0x6F, 0x8F,
++	0x32, 0x3E, 0x5F, 0xE9,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x30,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x30,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x33, 0x1E, 0x5F, 0xE9,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x33, 0x1E, 0x5F, 0xE9,
+ 
+-0x05, 0x44, 0x54, 0xB2,
+-0x0D, 0x44, 0x4C, 0xB2,
++	0x05, 0x44, 0x54, 0xB2,
++	0x0D, 0x44, 0x4C, 0xB2,
+ 
+-0x19, 0xC0, 0xB0, 0xE8,
+-0x34, 0xC0, 0x44, 0xC4,
++	0x19, 0xC0, 0xB0, 0xE8,
++	0x34, 0xC0, 0x44, 0xC4,
+ 
+-0x33, 0x73,
+-0x00, 0xE0,
+-0x3E, 0x62, 0x57, 0x9F,
++	0x33, 0x73,
++	0x00, 0xE0,
++	0x3E, 0x62, 0x57, 0x9F,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0xE0,
+-0x0D, 0x20,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0xE0,
++	0x0D, 0x20,
+ 
+-0x84, 0x3E, 0x58, 0xE9,
+-0x28, 0x1D, 0x6F, 0x8F,
++	0x84, 0x3E, 0x58, 0xE9,
++	0x28, 0x1D, 0x6F, 0x8F,
+ 
+-0x05, 0x20,
+-0x00, 0xE0,
+-0x85, 0x1E, 0x58, 0xE9,
++	0x05, 0x20,
++	0x00, 0xE0,
++	0x85, 0x1E, 0x58, 0xE9,
+ 
+-0x9B, 0x3B, 0x33, 0xDF,
+-0x20, 0x20, 0x42, 0xAF,
++	0x9B, 0x3B, 0x33, 0xDF,
++	0x20, 0x20, 0x42, 0xAF,
+ 
+-0x30, 0x42, 0x56, 0x9F,
+-0x80, 0x3E, 0x57, 0xE9,
++	0x30, 0x42, 0x56, 0x9F,
++	0x80, 0x3E, 0x57, 0xE9,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x30, 0x80, 0x5F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x30, 0x80, 0x5F, 0xE9,
+ 
+-0x28, 0x28, 0x24, 0xAF,
+-0x81, 0x1E, 0x57, 0xE9,
++	0x28, 0x28, 0x24, 0xAF,
++	0x81, 0x1E, 0x57, 0xE9,
+ 
+-0x05, 0x47, 0x57, 0xBF,
+-0x0D, 0x47, 0x4F, 0xBF,
++	0x05, 0x47, 0x57, 0xBF,
++	0x0D, 0x47, 0x4F, 0xBF,
+ 
+-0x88, 0x80, 0x58, 0xE9,
+-0x1B, 0x29, 0x1B, 0xDF,
++	0x88, 0x80, 0x58, 0xE9,
++	0x1B, 0x29, 0x1B, 0xDF,
+ 
+-0x30, 0x1D, 0x6F, 0x8F,
+-0x3A, 0x30, 0x4F, 0xE9,
++	0x30, 0x1D, 0x6F, 0x8F,
++	0x3A, 0x30, 0x4F, 0xE9,
+ 
+-0x1C, 0x30, 0x26, 0xDF,
+-0x09, 0xE3,
+-0x3B, 0x05,
++	0x1C, 0x30, 0x26, 0xDF,
++	0x09, 0xE3,
++	0x3B, 0x05,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x3B, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x3B, 0x3F, 0x4F, 0xE9,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x00, 0xE0,
+-0xAC, 0x20,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x00, 0xE0,
++	0xAC, 0x20,
+ 
+-0x2D, 0x44, 0x4C, 0xB4,
+-0x2C, 0x1C, 0xC0, 0xAF,
++	0x2D, 0x44, 0x4C, 0xB4,
++	0x2C, 0x1C, 0xC0, 0xAF,
+ 
+-0x25, 0x44, 0x54, 0xB4,
+-0x00, 0xE0,
+-0xC8, 0x30,
++	0x25, 0x44, 0x54, 0xB4,
++	0x00, 0xE0,
++	0xC8, 0x30,
+ 
+-0x30, 0x46, 0x30, 0xAF,
+-0x1B, 0x1B, 0x48, 0xAF,
++	0x30, 0x46, 0x30, 0xAF,
++	0x1B, 0x1B, 0x48, 0xAF,
+ 
+-0x00, 0xE0,
+-0x25, 0x20,
+-0x38, 0x2C, 0x4F, 0xE9,
++	0x00, 0xE0,
++	0x25, 0x20,
++	0x38, 0x2C, 0x4F, 0xE9,
+ 
+-0x86, 0x80, 0x57, 0xE9,
+-0x38, 0x1D, 0x6F, 0x8F,
++	0x86, 0x80, 0x57, 0xE9,
++	0x38, 0x1D, 0x6F, 0x8F,
+ 
+-0x28, 0x74,
+-0x00, 0xE0,
+-0x0D, 0x44, 0x4C, 0xB0,
++	0x28, 0x74,
++	0x00, 0xE0,
++	0x0D, 0x44, 0x4C, 0xB0,
+ 
+-0x05, 0x44, 0x54, 0xB0,
+-0x2D, 0x20,
+-0x9B, 0x10,
++	0x05, 0x44, 0x54, 0xB0,
++	0x2D, 0x20,
++	0x9B, 0x10,
+ 
+-0x82, 0x3E, 0x57, 0xE9,
+-0x32, 0xF0, 0x1B, 0xCD,
++	0x82, 0x3E, 0x57, 0xE9,
++	0x32, 0xF0, 0x1B, 0xCD,
+ 
+-0x1E, 0xBD, 0x59, 0x9F,
+-0x83, 0x1E, 0x57, 0xE9,
++	0x1E, 0xBD, 0x59, 0x9F,
++	0x83, 0x1E, 0x57, 0xE9,
+ 
+-0x38, 0x47, 0x38, 0xAF,
+-0x34, 0x20,
+-0x2A, 0x30,
++	0x38, 0x47, 0x38, 0xAF,
++	0x34, 0x20,
++	0x2A, 0x30,
+ 
+-0x00, 0xE0,
+-0x0D, 0x20,
+-0x32, 0x20,
+-0x05, 0x20,
++	0x00, 0xE0,
++	0x0D, 0x20,
++	0x32, 0x20,
++	0x05, 0x20,
+ 
+-0x87, 0x80, 0x57, 0xE9,
+-0x1F, 0x54, 0x57, 0x9F,
++	0x87, 0x80, 0x57, 0xE9,
++	0x1F, 0x54, 0x57, 0x9F,
+ 
+-0x17, 0x42, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x6A,
++	0x17, 0x42, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x6A,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x37, 0x1E, 0x4F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x37, 0x1E, 0x4F, 0xE9,
+ 
+-0x37, 0x32, 0x2A, 0xAF,
+-0x00, 0xE0,
+-0x32, 0x00,
++	0x37, 0x32, 0x2A, 0xAF,
++	0x00, 0xE0,
++	0x32, 0x00,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x27, 0xC0, 0x44, 0xC0,
++	0x00, 0x80, 0x00, 0xE8,
++	0x27, 0xC0, 0x44, 0xC0,
+ 
+-0x36, 0x1F, 0x4F, 0xE9,
+-0x1F, 0x1F, 0x26, 0xDF,
++	0x36, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x1F, 0x26, 0xDF,
+ 
+-0x37, 0x1B, 0x37, 0xBF,
+-0x17, 0x26, 0x17, 0xDF,
++	0x37, 0x1B, 0x37, 0xBF,
++	0x17, 0x26, 0x17, 0xDF,
+ 
+-0x3E, 0x17, 0x4F, 0xE9,
+-0x3F, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x17, 0x4F, 0xE9,
++	0x3F, 0x3F, 0x4F, 0xE9,
+ 
+-0x34, 0x1F, 0x34, 0xAF,
+-0x2B, 0x05,
+-0xA7, 0x20,
++	0x34, 0x1F, 0x34, 0xAF,
++	0x2B, 0x05,
++	0xA7, 0x20,
+ 
+-0x33, 0x2B, 0x37, 0xDF,
+-0x27, 0x17, 0xC0, 0xAF,
++	0x33, 0x2B, 0x37, 0xDF,
++	0x27, 0x17, 0xC0, 0xAF,
+ 
+-0x34, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x34, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x03, 0x80, 0x0A, 0xEA,
+-0x17, 0xC1, 0x2B, 0xBD,
++	0x03, 0x80, 0x0A, 0xEA,
++	0x17, 0xC1, 0x2B, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xB3, 0x68,
+-0x97, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x68,
++	0x97, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0xC0, 0x33, 0xAF,
+-0x3C, 0x27, 0x4F, 0xE9,
++	0x33, 0xC0, 0x33, 0xAF,
++	0x3C, 0x27, 0x4F, 0xE9,
+ 
+-0x57, 0x39, 0x20, 0xE9,
+-0x28, 0x19, 0x60, 0xEC,
++	0x57, 0x39, 0x20, 0xE9,
++	0x28, 0x19, 0x60, 0xEC,
+ 
+-0x2B, 0x32, 0x20, 0xE9,
+-0x1D, 0x3B, 0x20, 0xE9,
++	0x2B, 0x32, 0x20, 0xE9,
++	0x1D, 0x3B, 0x20, 0xE9,
+ 
+-0xB3, 0x05,
+-0x00, 0xE0,
+-0x16, 0x28, 0x20, 0xE9,
++	0xB3, 0x05,
++	0x00, 0xE0,
++	0x16, 0x28, 0x20, 0xE9,
+ 
+-0x23, 0x3B, 0x33, 0xAD,
+-0x1E, 0x2B, 0x20, 0xE9,
++	0x23, 0x3B, 0x33, 0xAD,
++	0x1E, 0x2B, 0x20, 0xE9,
+ 
+-0x1C, 0x80, 0x20, 0xE9,
+-0x57, 0x36, 0x20, 0xE9,
++	0x1C, 0x80, 0x20, 0xE9,
++	0x57, 0x36, 0x20, 0xE9,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x90, 0xE2,
+-0x00, 0xE0,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x90, 0xE2,
++	0x00, 0xE0,
+ 
+-0x85, 0xFF, 0x20, 0xEA,
+-0x19, 0xC8, 0xC1, 0xCD,
++	0x85, 0xFF, 0x20, 0xEA,
++	0x19, 0xC8, 0xC1, 0xCD,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x9F, 0x41, 0x49, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9F, 0x41, 0x49, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x41, 0x49, 0xBD,
+-0x2D, 0x41, 0x51, 0xBD,
++	0x25, 0x41, 0x49, 0xBD,
++	0x2D, 0x41, 0x51, 0xBD,
+ 
+-0x0D, 0x80, 0x07, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x0D, 0x80, 0x07, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x35, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0x35, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x25, 0x30,
+-0x2D, 0x30,
++	0x00, 0x80, 0x00, 0xE8,
++	0x25, 0x30,
++	0x2D, 0x30,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0xA7, 0x5B, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0xA7, 0x5B, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x84, 0xFF, 0x0A, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x84, 0xFF, 0x0A, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC9, 0x41, 0xC8, 0xEC,
+-0x42, 0xE1,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC8, 0xEC,
++	0x42, 0xE1,
++	0x00, 0xE0,
+ 
+-0x82, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x82, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC8, 0x40, 0xC0, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC8, 0x40, 0xC0, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x7F, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x7F, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+ };
+ 
+ static unsigned char warp_g200_tgza[] = {
+ 
+-0x00, 0x98, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x98, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x81, 0x04,
+-0x89, 0x04,
+-0x01, 0x04,
+-0x09, 0x04,
++	0x81, 0x04,
++	0x89, 0x04,
++	0x01, 0x04,
++	0x09, 0x04,
+ 
+-0xC9, 0x41, 0xC0, 0xEC,
+-0x11, 0x04,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC0, 0xEC,
++	0x11, 0x04,
++	0x00, 0xE0,
+ 
+-0x41, 0xCC, 0x41, 0xCD,
+-0x49, 0xCC, 0x49, 0xCD,
++	0x41, 0xCC, 0x41, 0xCD,
++	0x49, 0xCC, 0x49, 0xCD,
+ 
+-0xD1, 0x41, 0xC0, 0xEC,
+-0x51, 0xCC, 0x51, 0xCD,
++	0xD1, 0x41, 0xC0, 0xEC,
++	0x51, 0xCC, 0x51, 0xCD,
+ 
+-0x80, 0x04,
+-0x10, 0x04,
+-0x08, 0x04,
+-0x00, 0xE0,
++	0x80, 0x04,
++	0x10, 0x04,
++	0x08, 0x04,
++	0x00, 0xE0,
+ 
+-0x00, 0xCC, 0xC0, 0xCD,
+-0xD1, 0x49, 0xC0, 0xEC,
++	0x00, 0xCC, 0xC0, 0xCD,
++	0xD1, 0x49, 0xC0, 0xEC,
+ 
+-0x8A, 0x1F, 0x20, 0xE9,
+-0x8B, 0x3F, 0x20, 0xE9,
++	0x8A, 0x1F, 0x20, 0xE9,
++	0x8B, 0x3F, 0x20, 0xE9,
+ 
+-0x41, 0x3C, 0x41, 0xAD,
+-0x49, 0x3C, 0x49, 0xAD,
++	0x41, 0x3C, 0x41, 0xAD,
++	0x49, 0x3C, 0x49, 0xAD,
+ 
+-0x10, 0xCC, 0x10, 0xCD,
+-0x08, 0xCC, 0x08, 0xCD,
++	0x10, 0xCC, 0x10, 0xCD,
++	0x08, 0xCC, 0x08, 0xCD,
+ 
+-0xB9, 0x41, 0x49, 0xBB,
+-0x1F, 0xF0, 0x41, 0xCD,
++	0xB9, 0x41, 0x49, 0xBB,
++	0x1F, 0xF0, 0x41, 0xCD,
+ 
+-0x51, 0x3C, 0x51, 0xAD,
+-0x00, 0x98, 0x80, 0xE9,
++	0x51, 0x3C, 0x51, 0xAD,
++	0x00, 0x98, 0x80, 0xE9,
+ 
+-0x7D, 0x80, 0x07, 0xEA,
+-0x24, 0x1F, 0x20, 0xE9,
++	0x7D, 0x80, 0x07, 0xEA,
++	0x24, 0x1F, 0x20, 0xE9,
+ 
+-0x15, 0x41, 0x49, 0xBD,
+-0x1D, 0x41, 0x51, 0xBD,
++	0x15, 0x41, 0x49, 0xBD,
++	0x1D, 0x41, 0x51, 0xBD,
+ 
+-0x2E, 0x41, 0x2A, 0xB8,
+-0x34, 0x53, 0xA0, 0xE8,
++	0x2E, 0x41, 0x2A, 0xB8,
++	0x34, 0x53, 0xA0, 0xE8,
+ 
+-0x15, 0x30,
+-0x1D, 0x30,
+-0x58, 0xE3,
+-0x00, 0xE0,
++	0x15, 0x30,
++	0x1D, 0x30,
++	0x58, 0xE3,
++	0x00, 0xE0,
+ 
+-0xB5, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0xB5, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x24, 0x43, 0xA0, 0xE8,
+-0x2C, 0x4B, 0xA0, 0xE8,
++	0x24, 0x43, 0xA0, 0xE8,
++	0x2C, 0x4B, 0xA0, 0xE8,
+ 
+-0x15, 0x72,
+-0x09, 0xE3,
+-0x00, 0xE0,
+-0x1D, 0x72,
++	0x15, 0x72,
++	0x09, 0xE3,
++	0x00, 0xE0,
++	0x1D, 0x72,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0x97, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x97, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6C, 0x64, 0xC8, 0xEC,
+-0x98, 0xE1,
+-0xB5, 0x05,
++	0x6C, 0x64, 0xC8, 0xEC,
++	0x98, 0xE1,
++	0xB5, 0x05,
+ 
+-0xBD, 0x05,
+-0x2E, 0x30,
+-0x32, 0xC0, 0xA0, 0xE8,
++	0xBD, 0x05,
++	0x2E, 0x30,
++	0x32, 0xC0, 0xA0, 0xE8,
+ 
+-0x33, 0xC0, 0xA0, 0xE8,
+-0x74, 0x64, 0xC8, 0xEC,
++	0x33, 0xC0, 0xA0, 0xE8,
++	0x74, 0x64, 0xC8, 0xEC,
+ 
+-0x40, 0x3C, 0x40, 0xAD,
+-0x32, 0x6A,
+-0x2A, 0x30,
++	0x40, 0x3C, 0x40, 0xAD,
++	0x32, 0x6A,
++	0x2A, 0x30,
+ 
+-0x20, 0x73,
+-0x33, 0x6A,
+-0x00, 0xE0,
+-0x28, 0x73,
++	0x20, 0x73,
++	0x33, 0x6A,
++	0x00, 0xE0,
++	0x28, 0x73,
+ 
+-0x1C, 0x72,
+-0x83, 0xE2,
+-0x6B, 0x80, 0x15, 0xEA,
++	0x1C, 0x72,
++	0x83, 0xE2,
++	0x6B, 0x80, 0x15, 0xEA,
+ 
+-0xB8, 0x3D, 0x28, 0xDF,
+-0x30, 0x35, 0x20, 0xDF,
++	0xB8, 0x3D, 0x28, 0xDF,
++	0x30, 0x35, 0x20, 0xDF,
+ 
+-0x40, 0x30,
+-0x00, 0xE0,
+-0xCC, 0xE2,
+-0x64, 0x72,
++	0x40, 0x30,
++	0x00, 0xE0,
++	0xCC, 0xE2,
++	0x64, 0x72,
+ 
+-0x25, 0x42, 0x52, 0xBF,
+-0x2D, 0x42, 0x4A, 0xBF,
++	0x25, 0x42, 0x52, 0xBF,
++	0x2D, 0x42, 0x4A, 0xBF,
+ 
+-0x30, 0x2E, 0x30, 0xDF,
+-0x38, 0x2E, 0x38, 0xDF,
++	0x30, 0x2E, 0x30, 0xDF,
++	0x38, 0x2E, 0x38, 0xDF,
+ 
+-0x18, 0x1D, 0x45, 0xE9,
+-0x1E, 0x15, 0x45, 0xE9,
++	0x18, 0x1D, 0x45, 0xE9,
++	0x1E, 0x15, 0x45, 0xE9,
+ 
+-0x2B, 0x49, 0x51, 0xBD,
+-0x00, 0xE0,
+-0x1F, 0x73,
++	0x2B, 0x49, 0x51, 0xBD,
++	0x00, 0xE0,
++	0x1F, 0x73,
+ 
+-0x38, 0x38, 0x40, 0xAF,
+-0x30, 0x30, 0x40, 0xAF,
++	0x38, 0x38, 0x40, 0xAF,
++	0x30, 0x30, 0x40, 0xAF,
+ 
+-0x24, 0x1F, 0x24, 0xDF,
+-0x1D, 0x32, 0x20, 0xE9,
++	0x24, 0x1F, 0x24, 0xDF,
++	0x1D, 0x32, 0x20, 0xE9,
+ 
+-0x2C, 0x1F, 0x2C, 0xDF,
+-0x1A, 0x33, 0x20, 0xE9,
++	0x2C, 0x1F, 0x2C, 0xDF,
++	0x1A, 0x33, 0x20, 0xE9,
+ 
+-0xB0, 0x10,
+-0x08, 0xE3,
+-0x40, 0x10,
+-0xB8, 0x10,
++	0xB0, 0x10,
++	0x08, 0xE3,
++	0x40, 0x10,
++	0xB8, 0x10,
+ 
+-0x26, 0xF0, 0x30, 0xCD,
+-0x2F, 0xF0, 0x38, 0xCD,
++	0x26, 0xF0, 0x30, 0xCD,
++	0x2F, 0xF0, 0x38, 0xCD,
+ 
+-0x2B, 0x80, 0x20, 0xE9,
+-0x2A, 0x80, 0x20, 0xE9,
++	0x2B, 0x80, 0x20, 0xE9,
++	0x2A, 0x80, 0x20, 0xE9,
+ 
+-0xA6, 0x20,
+-0x88, 0xE2,
+-0x00, 0xE0,
+-0xAF, 0x20,
++	0xA6, 0x20,
++	0x88, 0xE2,
++	0x00, 0xE0,
++	0xAF, 0x20,
+ 
+-0x28, 0x2A, 0x26, 0xAF,
+-0x20, 0x2A, 0xC0, 0xAF,
++	0x28, 0x2A, 0x26, 0xAF,
++	0x20, 0x2A, 0xC0, 0xAF,
+ 
+-0x34, 0x1F, 0x34, 0xDF,
+-0x46, 0x24, 0x46, 0xDF,
++	0x34, 0x1F, 0x34, 0xDF,
++	0x46, 0x24, 0x46, 0xDF,
+ 
+-0x28, 0x30, 0x80, 0xBF,
+-0x20, 0x38, 0x80, 0xBF,
++	0x28, 0x30, 0x80, 0xBF,
++	0x20, 0x38, 0x80, 0xBF,
+ 
+-0x47, 0x24, 0x47, 0xDF,
+-0x4E, 0x2C, 0x4E, 0xDF,
++	0x47, 0x24, 0x47, 0xDF,
++	0x4E, 0x2C, 0x4E, 0xDF,
+ 
+-0x4F, 0x2C, 0x4F, 0xDF,
+-0x56, 0x34, 0x56, 0xDF,
++	0x4F, 0x2C, 0x4F, 0xDF,
++	0x56, 0x34, 0x56, 0xDF,
+ 
+-0x28, 0x15, 0x28, 0xDF,
+-0x20, 0x1D, 0x20, 0xDF,
++	0x28, 0x15, 0x28, 0xDF,
++	0x20, 0x1D, 0x20, 0xDF,
+ 
+-0x57, 0x34, 0x57, 0xDF,
+-0x00, 0xE0,
+-0x1D, 0x05,
++	0x57, 0x34, 0x57, 0xDF,
++	0x00, 0xE0,
++	0x1D, 0x05,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x89, 0xE2,
+-0x2B, 0x30,
++	0x04, 0x80, 0x10, 0xEA,
++	0x89, 0xE2,
++	0x2B, 0x30,
+ 
+-0x3F, 0xC1, 0x1D, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0xC1, 0x1D, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x68,
+-0xBF, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x68,
++	0xBF, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x20, 0xC0, 0x20, 0xAF,
+-0x28, 0x05,
+-0x97, 0x74,
++	0x20, 0xC0, 0x20, 0xAF,
++	0x28, 0x05,
++	0x97, 0x74,
+ 
+-0x00, 0xE0,
+-0x2A, 0x10,
+-0x16, 0xC0, 0x20, 0xE9,
++	0x00, 0xE0,
++	0x2A, 0x10,
++	0x16, 0xC0, 0x20, 0xE9,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x8C, 0xE2,
+-0x95, 0x05,
++	0x04, 0x80, 0x10, 0xEA,
++	0x8C, 0xE2,
++	0x95, 0x05,
+ 
+-0x28, 0xC1, 0x28, 0xAD,
+-0x1F, 0xC1, 0x15, 0xBD,
++	0x28, 0xC1, 0x28, 0xAD,
++	0x1F, 0xC1, 0x15, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA8, 0x67,
+-0x9F, 0x6B,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA8, 0x67,
++	0x9F, 0x6B,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x28, 0xC0, 0x28, 0xAD,
+-0x1D, 0x25,
+-0x20, 0x05,
++	0x28, 0xC0, 0x28, 0xAD,
++	0x1D, 0x25,
++	0x20, 0x05,
+ 
+-0x28, 0x32, 0x80, 0xAD,
+-0x40, 0x2A, 0x40, 0xBD,
++	0x28, 0x32, 0x80, 0xAD,
++	0x40, 0x2A, 0x40, 0xBD,
+ 
+-0x1C, 0x80, 0x20, 0xE9,
+-0x20, 0x33, 0x20, 0xAD,
++	0x1C, 0x80, 0x20, 0xE9,
++	0x20, 0x33, 0x20, 0xAD,
+ 
+-0x20, 0x73,
+-0x00, 0xE0,
+-0xB6, 0x49, 0x51, 0xBB,
++	0x20, 0x73,
++	0x00, 0xE0,
++	0xB6, 0x49, 0x51, 0xBB,
+ 
+-0x26, 0x2F, 0xB0, 0xE8,
+-0x19, 0x20, 0x20, 0xE9,
++	0x26, 0x2F, 0xB0, 0xE8,
++	0x19, 0x20, 0x20, 0xE9,
+ 
+-0x35, 0x20, 0x35, 0xDF,
+-0x3D, 0x20, 0x3D, 0xDF,
++	0x35, 0x20, 0x35, 0xDF,
++	0x3D, 0x20, 0x3D, 0xDF,
+ 
+-0x15, 0x20, 0x15, 0xDF,
+-0x1D, 0x20, 0x1D, 0xDF,
++	0x15, 0x20, 0x15, 0xDF,
++	0x1D, 0x20, 0x1D, 0xDF,
+ 
+-0x26, 0xD0, 0x26, 0xCD,
+-0x29, 0x49, 0x2A, 0xB8,
++	0x26, 0xD0, 0x26, 0xCD,
++	0x29, 0x49, 0x2A, 0xB8,
+ 
+-0x26, 0x40, 0x80, 0xBD,
+-0x3B, 0x48, 0x50, 0xBD,
++	0x26, 0x40, 0x80, 0xBD,
++	0x3B, 0x48, 0x50, 0xBD,
+ 
+-0x3E, 0x54, 0x57, 0x9F,
+-0x00, 0xE0,
+-0x82, 0xE1,
++	0x3E, 0x54, 0x57, 0x9F,
++	0x00, 0xE0,
++	0x82, 0xE1,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x26, 0x30,
+-0x29, 0x30,
+-0x48, 0x3C, 0x48, 0xAD,
++	0x26, 0x30,
++	0x29, 0x30,
++	0x48, 0x3C, 0x48, 0xAD,
+ 
+-0x2B, 0x72,
+-0xC2, 0xE1,
+-0x2C, 0xC0, 0x44, 0xC2,
++	0x2B, 0x72,
++	0xC2, 0xE1,
++	0x2C, 0xC0, 0x44, 0xC2,
+ 
+-0x05, 0x24, 0x34, 0xBF,
+-0x0D, 0x24, 0x2C, 0xBF,
++	0x05, 0x24, 0x34, 0xBF,
++	0x0D, 0x24, 0x2C, 0xBF,
+ 
+-0x2D, 0x46, 0x4E, 0xBF,
+-0x25, 0x46, 0x56, 0xBF,
++	0x2D, 0x46, 0x4E, 0xBF,
++	0x25, 0x46, 0x56, 0xBF,
+ 
+-0x20, 0x1D, 0x6F, 0x8F,
+-0x32, 0x3E, 0x5F, 0xE9,
++	0x20, 0x1D, 0x6F, 0x8F,
++	0x32, 0x3E, 0x5F, 0xE9,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x30,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x30,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x33, 0x1E, 0x5F, 0xE9,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x33, 0x1E, 0x5F, 0xE9,
+ 
+-0x05, 0x44, 0x54, 0xB2,
+-0x0D, 0x44, 0x4C, 0xB2,
++	0x05, 0x44, 0x54, 0xB2,
++	0x0D, 0x44, 0x4C, 0xB2,
+ 
+-0x19, 0xC0, 0xB0, 0xE8,
+-0x34, 0xC0, 0x44, 0xC4,
++	0x19, 0xC0, 0xB0, 0xE8,
++	0x34, 0xC0, 0x44, 0xC4,
+ 
+-0x33, 0x73,
+-0x00, 0xE0,
+-0x3E, 0x62, 0x57, 0x9F,
++	0x33, 0x73,
++	0x00, 0xE0,
++	0x3E, 0x62, 0x57, 0x9F,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0xE0,
+-0x0D, 0x20,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0xE0,
++	0x0D, 0x20,
+ 
+-0x84, 0x3E, 0x58, 0xE9,
+-0x28, 0x1D, 0x6F, 0x8F,
++	0x84, 0x3E, 0x58, 0xE9,
++	0x28, 0x1D, 0x6F, 0x8F,
+ 
+-0x05, 0x20,
+-0x00, 0xE0,
+-0x85, 0x1E, 0x58, 0xE9,
++	0x05, 0x20,
++	0x00, 0xE0,
++	0x85, 0x1E, 0x58, 0xE9,
+ 
+-0x9B, 0x3B, 0x33, 0xDF,
+-0x20, 0x20, 0x42, 0xAF,
++	0x9B, 0x3B, 0x33, 0xDF,
++	0x20, 0x20, 0x42, 0xAF,
+ 
+-0x30, 0x42, 0x56, 0x9F,
+-0x80, 0x3E, 0x57, 0xE9,
++	0x30, 0x42, 0x56, 0x9F,
++	0x80, 0x3E, 0x57, 0xE9,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x30, 0x80, 0x5F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x30, 0x80, 0x5F, 0xE9,
+ 
+-0x28, 0x28, 0x24, 0xAF,
+-0x81, 0x1E, 0x57, 0xE9,
++	0x28, 0x28, 0x24, 0xAF,
++	0x81, 0x1E, 0x57, 0xE9,
+ 
+-0x05, 0x47, 0x57, 0xBF,
+-0x0D, 0x47, 0x4F, 0xBF,
++	0x05, 0x47, 0x57, 0xBF,
++	0x0D, 0x47, 0x4F, 0xBF,
+ 
+-0x88, 0x80, 0x58, 0xE9,
+-0x1B, 0x29, 0x1B, 0xDF,
++	0x88, 0x80, 0x58, 0xE9,
++	0x1B, 0x29, 0x1B, 0xDF,
+ 
+-0x30, 0x1D, 0x6F, 0x8F,
+-0x3A, 0x30, 0x4F, 0xE9,
++	0x30, 0x1D, 0x6F, 0x8F,
++	0x3A, 0x30, 0x4F, 0xE9,
+ 
+-0x1C, 0x30, 0x26, 0xDF,
+-0x09, 0xE3,
+-0x3B, 0x05,
++	0x1C, 0x30, 0x26, 0xDF,
++	0x09, 0xE3,
++	0x3B, 0x05,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x3B, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x3B, 0x3F, 0x4F, 0xE9,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x00, 0xE0,
+-0xAC, 0x20,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x00, 0xE0,
++	0xAC, 0x20,
+ 
+-0x2D, 0x44, 0x4C, 0xB4,
+-0x2C, 0x1C, 0xC0, 0xAF,
++	0x2D, 0x44, 0x4C, 0xB4,
++	0x2C, 0x1C, 0xC0, 0xAF,
+ 
+-0x25, 0x44, 0x54, 0xB4,
+-0x00, 0xE0,
+-0xC8, 0x30,
++	0x25, 0x44, 0x54, 0xB4,
++	0x00, 0xE0,
++	0xC8, 0x30,
+ 
+-0x30, 0x46, 0x30, 0xAF,
+-0x1B, 0x1B, 0x48, 0xAF,
++	0x30, 0x46, 0x30, 0xAF,
++	0x1B, 0x1B, 0x48, 0xAF,
+ 
+-0x00, 0xE0,
+-0x25, 0x20,
+-0x38, 0x2C, 0x4F, 0xE9,
++	0x00, 0xE0,
++	0x25, 0x20,
++	0x38, 0x2C, 0x4F, 0xE9,
+ 
+-0x86, 0x80, 0x57, 0xE9,
+-0x38, 0x1D, 0x6F, 0x8F,
++	0x86, 0x80, 0x57, 0xE9,
++	0x38, 0x1D, 0x6F, 0x8F,
+ 
+-0x28, 0x74,
+-0x00, 0xE0,
+-0x0D, 0x44, 0x4C, 0xB0,
++	0x28, 0x74,
++	0x00, 0xE0,
++	0x0D, 0x44, 0x4C, 0xB0,
+ 
+-0x05, 0x44, 0x54, 0xB0,
+-0x2D, 0x20,
+-0x9B, 0x10,
++	0x05, 0x44, 0x54, 0xB0,
++	0x2D, 0x20,
++	0x9B, 0x10,
+ 
+-0x82, 0x3E, 0x57, 0xE9,
+-0x32, 0xF0, 0x1B, 0xCD,
++	0x82, 0x3E, 0x57, 0xE9,
++	0x32, 0xF0, 0x1B, 0xCD,
+ 
+-0x1E, 0xBD, 0x59, 0x9F,
+-0x83, 0x1E, 0x57, 0xE9,
++	0x1E, 0xBD, 0x59, 0x9F,
++	0x83, 0x1E, 0x57, 0xE9,
+ 
+-0x38, 0x47, 0x38, 0xAF,
+-0x34, 0x20,
+-0x2A, 0x30,
++	0x38, 0x47, 0x38, 0xAF,
++	0x34, 0x20,
++	0x2A, 0x30,
+ 
+-0x00, 0xE0,
+-0x0D, 0x20,
+-0x32, 0x20,
+-0x05, 0x20,
++	0x00, 0xE0,
++	0x0D, 0x20,
++	0x32, 0x20,
++	0x05, 0x20,
+ 
+-0x87, 0x80, 0x57, 0xE9,
+-0x1F, 0x54, 0x57, 0x9F,
++	0x87, 0x80, 0x57, 0xE9,
++	0x1F, 0x54, 0x57, 0x9F,
+ 
+-0x17, 0x42, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x6A,
++	0x17, 0x42, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x6A,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x37, 0x1E, 0x4F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x37, 0x1E, 0x4F, 0xE9,
+ 
+-0x37, 0x32, 0x2A, 0xAF,
+-0x00, 0xE0,
+-0x32, 0x00,
++	0x37, 0x32, 0x2A, 0xAF,
++	0x00, 0xE0,
++	0x32, 0x00,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x27, 0xC0, 0x44, 0xC0,
++	0x00, 0x80, 0x00, 0xE8,
++	0x27, 0xC0, 0x44, 0xC0,
+ 
+-0x36, 0x1F, 0x4F, 0xE9,
+-0x1F, 0x1F, 0x26, 0xDF,
++	0x36, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x1F, 0x26, 0xDF,
+ 
+-0x37, 0x1B, 0x37, 0xBF,
+-0x17, 0x26, 0x17, 0xDF,
++	0x37, 0x1B, 0x37, 0xBF,
++	0x17, 0x26, 0x17, 0xDF,
+ 
+-0x3E, 0x17, 0x4F, 0xE9,
+-0x3F, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x17, 0x4F, 0xE9,
++	0x3F, 0x3F, 0x4F, 0xE9,
+ 
+-0x34, 0x1F, 0x34, 0xAF,
+-0x2B, 0x05,
+-0xA7, 0x20,
++	0x34, 0x1F, 0x34, 0xAF,
++	0x2B, 0x05,
++	0xA7, 0x20,
+ 
+-0x33, 0x2B, 0x37, 0xDF,
+-0x27, 0x17, 0xC0, 0xAF,
++	0x33, 0x2B, 0x37, 0xDF,
++	0x27, 0x17, 0xC0, 0xAF,
+ 
+-0x34, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x34, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x2D, 0x44, 0x4C, 0xB6,
+-0x25, 0x44, 0x54, 0xB6,
++	0x2D, 0x44, 0x4C, 0xB6,
++	0x25, 0x44, 0x54, 0xB6,
+ 
+-0x03, 0x80, 0x2A, 0xEA,
+-0x17, 0xC1, 0x2B, 0xBD,
++	0x03, 0x80, 0x2A, 0xEA,
++	0x17, 0xC1, 0x2B, 0xBD,
+ 
+-0x2D, 0x20,
+-0x25, 0x20,
+-0x07, 0xC0, 0x44, 0xC6,
++	0x2D, 0x20,
++	0x25, 0x20,
++	0x07, 0xC0, 0x44, 0xC6,
+ 
+-0xB3, 0x68,
+-0x97, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x68,
++	0x97, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0xC0, 0x33, 0xAF,
+-0x3C, 0x27, 0x4F, 0xE9,
++	0x33, 0xC0, 0x33, 0xAF,
++	0x3C, 0x27, 0x4F, 0xE9,
+ 
+-0x1F, 0x62, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x62, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x3F, 0x3D, 0x5D, 0x9F,
+-0x00, 0xE0,
+-0x07, 0x20,
++	0x3F, 0x3D, 0x5D, 0x9F,
++	0x00, 0xE0,
++	0x07, 0x20,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x28, 0x19, 0x60, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
++	0x28, 0x19, 0x60, 0xEC,
+ 
+-0xB3, 0x05,
+-0x00, 0xE0,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x05,
++	0x00, 0xE0,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x23, 0x3B, 0x33, 0xAD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x23, 0x3B, 0x33, 0xAD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1F, 0x26, 0x1F, 0xDF,
+-0x9D, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x26, 0x1F, 0xDF,
++	0x9D, 0x1F, 0x4F, 0xE9,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x9E, 0x3F, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x9E, 0x3F, 0x4F, 0xE9,
+ 
+-0x07, 0x07, 0x1F, 0xAF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x07, 0x07, 0x1F, 0xAF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x9C, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x57, 0x39, 0x20, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x57, 0x39, 0x20, 0xE9,
+ 
+-0x16, 0x28, 0x20, 0xE9,
+-0x1D, 0x3B, 0x20, 0xE9,
++	0x16, 0x28, 0x20, 0xE9,
++	0x1D, 0x3B, 0x20, 0xE9,
+ 
+-0x1E, 0x2B, 0x20, 0xE9,
+-0x2B, 0x32, 0x20, 0xE9,
++	0x1E, 0x2B, 0x20, 0xE9,
++	0x2B, 0x32, 0x20, 0xE9,
+ 
+-0x1C, 0x23, 0x20, 0xE9,
+-0x57, 0x36, 0x20, 0xE9,
++	0x1C, 0x23, 0x20, 0xE9,
++	0x57, 0x36, 0x20, 0xE9,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x90, 0xE2,
+-0x00, 0xE0,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x90, 0xE2,
++	0x00, 0xE0,
+ 
+-0x7A, 0xFF, 0x20, 0xEA,
+-0x19, 0xC8, 0xC1, 0xCD,
++	0x7A, 0xFF, 0x20, 0xEA,
++	0x19, 0xC8, 0xC1, 0xCD,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x9F, 0x41, 0x49, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9F, 0x41, 0x49, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x41, 0x49, 0xBD,
+-0x2D, 0x41, 0x51, 0xBD,
++	0x25, 0x41, 0x49, 0xBD,
++	0x2D, 0x41, 0x51, 0xBD,
+ 
+-0x0D, 0x80, 0x07, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x0D, 0x80, 0x07, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x35, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0x35, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x25, 0x30,
+-0x2D, 0x30,
++	0x00, 0x80, 0x00, 0xE8,
++	0x25, 0x30,
++	0x2D, 0x30,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0xA7, 0x5B, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0xA7, 0x5B, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x79, 0xFF, 0x0A, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x79, 0xFF, 0x0A, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC9, 0x41, 0xC8, 0xEC,
+-0x42, 0xE1,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC8, 0xEC,
++	0x42, 0xE1,
++	0x00, 0xE0,
+ 
+-0x77, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x77, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC8, 0x40, 0xC0, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC8, 0x40, 0xC0, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x74, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x74, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+ };
+ 
+ static unsigned char warp_g200_tgzaf[] = {
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x98, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x98, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x81, 0x04,
+-0x89, 0x04,
+-0x01, 0x04,
+-0x09, 0x04,
++	0x81, 0x04,
++	0x89, 0x04,
++	0x01, 0x04,
++	0x09, 0x04,
+ 
+-0xC9, 0x41, 0xC0, 0xEC,
+-0x11, 0x04,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC0, 0xEC,
++	0x11, 0x04,
++	0x00, 0xE0,
+ 
+-0x41, 0xCC, 0x41, 0xCD,
+-0x49, 0xCC, 0x49, 0xCD,
++	0x41, 0xCC, 0x41, 0xCD,
++	0x49, 0xCC, 0x49, 0xCD,
+ 
+-0xD1, 0x41, 0xC0, 0xEC,
+-0x51, 0xCC, 0x51, 0xCD,
++	0xD1, 0x41, 0xC0, 0xEC,
++	0x51, 0xCC, 0x51, 0xCD,
+ 
+-0x80, 0x04,
+-0x10, 0x04,
+-0x08, 0x04,
+-0x00, 0xE0,
++	0x80, 0x04,
++	0x10, 0x04,
++	0x08, 0x04,
++	0x00, 0xE0,
+ 
+-0x00, 0xCC, 0xC0, 0xCD,
+-0xD1, 0x49, 0xC0, 0xEC,
++	0x00, 0xCC, 0xC0, 0xCD,
++	0xD1, 0x49, 0xC0, 0xEC,
+ 
+-0x8A, 0x1F, 0x20, 0xE9,
+-0x8B, 0x3F, 0x20, 0xE9,
++	0x8A, 0x1F, 0x20, 0xE9,
++	0x8B, 0x3F, 0x20, 0xE9,
+ 
+-0x41, 0x3C, 0x41, 0xAD,
+-0x49, 0x3C, 0x49, 0xAD,
++	0x41, 0x3C, 0x41, 0xAD,
++	0x49, 0x3C, 0x49, 0xAD,
+ 
+-0x10, 0xCC, 0x10, 0xCD,
+-0x08, 0xCC, 0x08, 0xCD,
++	0x10, 0xCC, 0x10, 0xCD,
++	0x08, 0xCC, 0x08, 0xCD,
+ 
+-0xB9, 0x41, 0x49, 0xBB,
+-0x1F, 0xF0, 0x41, 0xCD,
++	0xB9, 0x41, 0x49, 0xBB,
++	0x1F, 0xF0, 0x41, 0xCD,
+ 
+-0x51, 0x3C, 0x51, 0xAD,
+-0x00, 0x98, 0x80, 0xE9,
++	0x51, 0x3C, 0x51, 0xAD,
++	0x00, 0x98, 0x80, 0xE9,
+ 
+-0x83, 0x80, 0x07, 0xEA,
+-0x24, 0x1F, 0x20, 0xE9,
++	0x83, 0x80, 0x07, 0xEA,
++	0x24, 0x1F, 0x20, 0xE9,
+ 
+-0x21, 0x45, 0x80, 0xE8,
+-0x1A, 0x4D, 0x80, 0xE8,
++	0x21, 0x45, 0x80, 0xE8,
++	0x1A, 0x4D, 0x80, 0xE8,
+ 
+-0x31, 0x55, 0x80, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x55, 0x80, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0x41, 0x49, 0xBD,
+-0x1D, 0x41, 0x51, 0xBD,
++	0x15, 0x41, 0x49, 0xBD,
++	0x1D, 0x41, 0x51, 0xBD,
+ 
+-0x2E, 0x41, 0x2A, 0xB8,
+-0x34, 0x53, 0xA0, 0xE8,
++	0x2E, 0x41, 0x2A, 0xB8,
++	0x34, 0x53, 0xA0, 0xE8,
+ 
+-0x15, 0x30,
+-0x1D, 0x30,
+-0x58, 0xE3,
+-0x00, 0xE0,
++	0x15, 0x30,
++	0x1D, 0x30,
++	0x58, 0xE3,
++	0x00, 0xE0,
+ 
+-0xB5, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0xB5, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x24, 0x43, 0xA0, 0xE8,
+-0x2C, 0x4B, 0xA0, 0xE8,
++	0x24, 0x43, 0xA0, 0xE8,
++	0x2C, 0x4B, 0xA0, 0xE8,
+ 
+-0x15, 0x72,
+-0x09, 0xE3,
+-0x00, 0xE0,
+-0x1D, 0x72,
++	0x15, 0x72,
++	0x09, 0xE3,
++	0x00, 0xE0,
++	0x1D, 0x72,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0x97, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x97, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6C, 0x64, 0xC8, 0xEC,
+-0x98, 0xE1,
+-0xB5, 0x05,
++	0x6C, 0x64, 0xC8, 0xEC,
++	0x98, 0xE1,
++	0xB5, 0x05,
+ 
+-0xBD, 0x05,
+-0x2E, 0x30,
+-0x32, 0xC0, 0xA0, 0xE8,
++	0xBD, 0x05,
++	0x2E, 0x30,
++	0x32, 0xC0, 0xA0, 0xE8,
+ 
+-0x33, 0xC0, 0xA0, 0xE8,
+-0x74, 0x64, 0xC8, 0xEC,
++	0x33, 0xC0, 0xA0, 0xE8,
++	0x74, 0x64, 0xC8, 0xEC,
+ 
+-0x40, 0x3C, 0x40, 0xAD,
+-0x32, 0x6A,
+-0x2A, 0x30,
++	0x40, 0x3C, 0x40, 0xAD,
++	0x32, 0x6A,
++	0x2A, 0x30,
+ 
+-0x20, 0x73,
+-0x33, 0x6A,
+-0x00, 0xE0,
+-0x28, 0x73,
++	0x20, 0x73,
++	0x33, 0x6A,
++	0x00, 0xE0,
++	0x28, 0x73,
+ 
+-0x1C, 0x72,
+-0x83, 0xE2,
+-0x6F, 0x80, 0x15, 0xEA,
++	0x1C, 0x72,
++	0x83, 0xE2,
++	0x6F, 0x80, 0x15, 0xEA,
+ 
+-0xB8, 0x3D, 0x28, 0xDF,
+-0x30, 0x35, 0x20, 0xDF,
++	0xB8, 0x3D, 0x28, 0xDF,
++	0x30, 0x35, 0x20, 0xDF,
+ 
+-0x40, 0x30,
+-0x00, 0xE0,
+-0xCC, 0xE2,
+-0x64, 0x72,
++	0x40, 0x30,
++	0x00, 0xE0,
++	0xCC, 0xE2,
++	0x64, 0x72,
+ 
+-0x25, 0x42, 0x52, 0xBF,
+-0x2D, 0x42, 0x4A, 0xBF,
++	0x25, 0x42, 0x52, 0xBF,
++	0x2D, 0x42, 0x4A, 0xBF,
+ 
+-0x30, 0x2E, 0x30, 0xDF,
+-0x38, 0x2E, 0x38, 0xDF,
++	0x30, 0x2E, 0x30, 0xDF,
++	0x38, 0x2E, 0x38, 0xDF,
+ 
+-0x18, 0x1D, 0x45, 0xE9,
+-0x1E, 0x15, 0x45, 0xE9,
++	0x18, 0x1D, 0x45, 0xE9,
++	0x1E, 0x15, 0x45, 0xE9,
+ 
+-0x2B, 0x49, 0x51, 0xBD,
+-0x00, 0xE0,
+-0x1F, 0x73,
++	0x2B, 0x49, 0x51, 0xBD,
++	0x00, 0xE0,
++	0x1F, 0x73,
+ 
+-0x38, 0x38, 0x40, 0xAF,
+-0x30, 0x30, 0x40, 0xAF,
++	0x38, 0x38, 0x40, 0xAF,
++	0x30, 0x30, 0x40, 0xAF,
+ 
+-0x24, 0x1F, 0x24, 0xDF,
+-0x1D, 0x32, 0x20, 0xE9,
++	0x24, 0x1F, 0x24, 0xDF,
++	0x1D, 0x32, 0x20, 0xE9,
+ 
+-0x2C, 0x1F, 0x2C, 0xDF,
+-0x1A, 0x33, 0x20, 0xE9,
++	0x2C, 0x1F, 0x2C, 0xDF,
++	0x1A, 0x33, 0x20, 0xE9,
+ 
+-0xB0, 0x10,
+-0x08, 0xE3,
+-0x40, 0x10,
+-0xB8, 0x10,
++	0xB0, 0x10,
++	0x08, 0xE3,
++	0x40, 0x10,
++	0xB8, 0x10,
+ 
+-0x26, 0xF0, 0x30, 0xCD,
+-0x2F, 0xF0, 0x38, 0xCD,
++	0x26, 0xF0, 0x30, 0xCD,
++	0x2F, 0xF0, 0x38, 0xCD,
+ 
+-0x2B, 0x80, 0x20, 0xE9,
+-0x2A, 0x80, 0x20, 0xE9,
++	0x2B, 0x80, 0x20, 0xE9,
++	0x2A, 0x80, 0x20, 0xE9,
+ 
+-0xA6, 0x20,
+-0x88, 0xE2,
+-0x00, 0xE0,
+-0xAF, 0x20,
++	0xA6, 0x20,
++	0x88, 0xE2,
++	0x00, 0xE0,
++	0xAF, 0x20,
+ 
+-0x28, 0x2A, 0x26, 0xAF,
+-0x20, 0x2A, 0xC0, 0xAF,
++	0x28, 0x2A, 0x26, 0xAF,
++	0x20, 0x2A, 0xC0, 0xAF,
+ 
+-0x34, 0x1F, 0x34, 0xDF,
+-0x46, 0x24, 0x46, 0xDF,
++	0x34, 0x1F, 0x34, 0xDF,
++	0x46, 0x24, 0x46, 0xDF,
+ 
+-0x28, 0x30, 0x80, 0xBF,
+-0x20, 0x38, 0x80, 0xBF,
++	0x28, 0x30, 0x80, 0xBF,
++	0x20, 0x38, 0x80, 0xBF,
+ 
+-0x47, 0x24, 0x47, 0xDF,
+-0x4E, 0x2C, 0x4E, 0xDF,
++	0x47, 0x24, 0x47, 0xDF,
++	0x4E, 0x2C, 0x4E, 0xDF,
+ 
+-0x4F, 0x2C, 0x4F, 0xDF,
+-0x56, 0x34, 0x56, 0xDF,
++	0x4F, 0x2C, 0x4F, 0xDF,
++	0x56, 0x34, 0x56, 0xDF,
+ 
+-0x28, 0x15, 0x28, 0xDF,
+-0x20, 0x1D, 0x20, 0xDF,
++	0x28, 0x15, 0x28, 0xDF,
++	0x20, 0x1D, 0x20, 0xDF,
+ 
+-0x57, 0x34, 0x57, 0xDF,
+-0x00, 0xE0,
+-0x1D, 0x05,
++	0x57, 0x34, 0x57, 0xDF,
++	0x00, 0xE0,
++	0x1D, 0x05,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x89, 0xE2,
+-0x2B, 0x30,
++	0x04, 0x80, 0x10, 0xEA,
++	0x89, 0xE2,
++	0x2B, 0x30,
+ 
+-0x3F, 0xC1, 0x1D, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0xC1, 0x1D, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x68,
+-0xBF, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x68,
++	0xBF, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x20, 0xC0, 0x20, 0xAF,
+-0x28, 0x05,
+-0x97, 0x74,
++	0x20, 0xC0, 0x20, 0xAF,
++	0x28, 0x05,
++	0x97, 0x74,
+ 
+-0x00, 0xE0,
+-0x2A, 0x10,
+-0x16, 0xC0, 0x20, 0xE9,
++	0x00, 0xE0,
++	0x2A, 0x10,
++	0x16, 0xC0, 0x20, 0xE9,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x8C, 0xE2,
+-0x95, 0x05,
++	0x04, 0x80, 0x10, 0xEA,
++	0x8C, 0xE2,
++	0x95, 0x05,
+ 
+-0x28, 0xC1, 0x28, 0xAD,
+-0x1F, 0xC1, 0x15, 0xBD,
++	0x28, 0xC1, 0x28, 0xAD,
++	0x1F, 0xC1, 0x15, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA8, 0x67,
+-0x9F, 0x6B,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA8, 0x67,
++	0x9F, 0x6B,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x28, 0xC0, 0x28, 0xAD,
+-0x1D, 0x25,
+-0x20, 0x05,
++	0x28, 0xC0, 0x28, 0xAD,
++	0x1D, 0x25,
++	0x20, 0x05,
+ 
+-0x28, 0x32, 0x80, 0xAD,
+-0x40, 0x2A, 0x40, 0xBD,
++	0x28, 0x32, 0x80, 0xAD,
++	0x40, 0x2A, 0x40, 0xBD,
+ 
+-0x1C, 0x80, 0x20, 0xE9,
+-0x20, 0x33, 0x20, 0xAD,
++	0x1C, 0x80, 0x20, 0xE9,
++	0x20, 0x33, 0x20, 0xAD,
+ 
+-0x20, 0x73,
+-0x00, 0xE0,
+-0xB6, 0x49, 0x51, 0xBB,
++	0x20, 0x73,
++	0x00, 0xE0,
++	0xB6, 0x49, 0x51, 0xBB,
+ 
+-0x26, 0x2F, 0xB0, 0xE8,
+-0x19, 0x20, 0x20, 0xE9,
++	0x26, 0x2F, 0xB0, 0xE8,
++	0x19, 0x20, 0x20, 0xE9,
+ 
+-0x35, 0x20, 0x35, 0xDF,
+-0x3D, 0x20, 0x3D, 0xDF,
++	0x35, 0x20, 0x35, 0xDF,
++	0x3D, 0x20, 0x3D, 0xDF,
+ 
+-0x15, 0x20, 0x15, 0xDF,
+-0x1D, 0x20, 0x1D, 0xDF,
++	0x15, 0x20, 0x15, 0xDF,
++	0x1D, 0x20, 0x1D, 0xDF,
+ 
+-0x26, 0xD0, 0x26, 0xCD,
+-0x29, 0x49, 0x2A, 0xB8,
++	0x26, 0xD0, 0x26, 0xCD,
++	0x29, 0x49, 0x2A, 0xB8,
+ 
+-0x26, 0x40, 0x80, 0xBD,
+-0x3B, 0x48, 0x50, 0xBD,
++	0x26, 0x40, 0x80, 0xBD,
++	0x3B, 0x48, 0x50, 0xBD,
+ 
+-0x3E, 0x54, 0x57, 0x9F,
+-0x00, 0xE0,
+-0x82, 0xE1,
++	0x3E, 0x54, 0x57, 0x9F,
++	0x00, 0xE0,
++	0x82, 0xE1,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x26, 0x30,
+-0x29, 0x30,
+-0x48, 0x3C, 0x48, 0xAD,
++	0x26, 0x30,
++	0x29, 0x30,
++	0x48, 0x3C, 0x48, 0xAD,
+ 
+-0x2B, 0x72,
+-0xC2, 0xE1,
+-0x2C, 0xC0, 0x44, 0xC2,
++	0x2B, 0x72,
++	0xC2, 0xE1,
++	0x2C, 0xC0, 0x44, 0xC2,
+ 
+-0x05, 0x24, 0x34, 0xBF,
+-0x0D, 0x24, 0x2C, 0xBF,
++	0x05, 0x24, 0x34, 0xBF,
++	0x0D, 0x24, 0x2C, 0xBF,
+ 
+-0x2D, 0x46, 0x4E, 0xBF,
+-0x25, 0x46, 0x56, 0xBF,
++	0x2D, 0x46, 0x4E, 0xBF,
++	0x25, 0x46, 0x56, 0xBF,
+ 
+-0x20, 0x1D, 0x6F, 0x8F,
+-0x32, 0x3E, 0x5F, 0xE9,
++	0x20, 0x1D, 0x6F, 0x8F,
++	0x32, 0x3E, 0x5F, 0xE9,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x30,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x30,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x33, 0x1E, 0x5F, 0xE9,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x33, 0x1E, 0x5F, 0xE9,
+ 
+-0x05, 0x44, 0x54, 0xB2,
+-0x0D, 0x44, 0x4C, 0xB2,
++	0x05, 0x44, 0x54, 0xB2,
++	0x0D, 0x44, 0x4C, 0xB2,
+ 
+-0x19, 0xC0, 0xB0, 0xE8,
+-0x34, 0xC0, 0x44, 0xC4,
++	0x19, 0xC0, 0xB0, 0xE8,
++	0x34, 0xC0, 0x44, 0xC4,
+ 
+-0x33, 0x73,
+-0x00, 0xE0,
+-0x3E, 0x62, 0x57, 0x9F,
++	0x33, 0x73,
++	0x00, 0xE0,
++	0x3E, 0x62, 0x57, 0x9F,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0xE0,
+-0x0D, 0x20,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0xE0,
++	0x0D, 0x20,
+ 
+-0x84, 0x3E, 0x58, 0xE9,
+-0x28, 0x1D, 0x6F, 0x8F,
++	0x84, 0x3E, 0x58, 0xE9,
++	0x28, 0x1D, 0x6F, 0x8F,
+ 
+-0x05, 0x20,
+-0x00, 0xE0,
+-0x85, 0x1E, 0x58, 0xE9,
++	0x05, 0x20,
++	0x00, 0xE0,
++	0x85, 0x1E, 0x58, 0xE9,
+ 
+-0x9B, 0x3B, 0x33, 0xDF,
+-0x20, 0x20, 0x42, 0xAF,
++	0x9B, 0x3B, 0x33, 0xDF,
++	0x20, 0x20, 0x42, 0xAF,
+ 
+-0x30, 0x42, 0x56, 0x9F,
+-0x80, 0x3E, 0x57, 0xE9,
++	0x30, 0x42, 0x56, 0x9F,
++	0x80, 0x3E, 0x57, 0xE9,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x30, 0x80, 0x5F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x30, 0x80, 0x5F, 0xE9,
+ 
+-0x28, 0x28, 0x24, 0xAF,
+-0x81, 0x1E, 0x57, 0xE9,
++	0x28, 0x28, 0x24, 0xAF,
++	0x81, 0x1E, 0x57, 0xE9,
+ 
+-0x05, 0x47, 0x57, 0xBF,
+-0x0D, 0x47, 0x4F, 0xBF,
++	0x05, 0x47, 0x57, 0xBF,
++	0x0D, 0x47, 0x4F, 0xBF,
+ 
+-0x88, 0x80, 0x58, 0xE9,
+-0x1B, 0x29, 0x1B, 0xDF,
++	0x88, 0x80, 0x58, 0xE9,
++	0x1B, 0x29, 0x1B, 0xDF,
+ 
+-0x30, 0x1D, 0x6F, 0x8F,
+-0x3A, 0x30, 0x4F, 0xE9,
++	0x30, 0x1D, 0x6F, 0x8F,
++	0x3A, 0x30, 0x4F, 0xE9,
+ 
+-0x1C, 0x30, 0x26, 0xDF,
+-0x09, 0xE3,
+-0x3B, 0x05,
++	0x1C, 0x30, 0x26, 0xDF,
++	0x09, 0xE3,
++	0x3B, 0x05,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x3B, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x3B, 0x3F, 0x4F, 0xE9,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x00, 0xE0,
+-0xAC, 0x20,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x00, 0xE0,
++	0xAC, 0x20,
+ 
+-0x2D, 0x44, 0x4C, 0xB4,
+-0x2C, 0x1C, 0xC0, 0xAF,
++	0x2D, 0x44, 0x4C, 0xB4,
++	0x2C, 0x1C, 0xC0, 0xAF,
+ 
+-0x25, 0x44, 0x54, 0xB4,
+-0x00, 0xE0,
+-0xC8, 0x30,
++	0x25, 0x44, 0x54, 0xB4,
++	0x00, 0xE0,
++	0xC8, 0x30,
+ 
+-0x30, 0x46, 0x30, 0xAF,
+-0x1B, 0x1B, 0x48, 0xAF,
++	0x30, 0x46, 0x30, 0xAF,
++	0x1B, 0x1B, 0x48, 0xAF,
+ 
+-0x00, 0xE0,
+-0x25, 0x20,
+-0x38, 0x2C, 0x4F, 0xE9,
++	0x00, 0xE0,
++	0x25, 0x20,
++	0x38, 0x2C, 0x4F, 0xE9,
+ 
+-0x86, 0x80, 0x57, 0xE9,
+-0x38, 0x1D, 0x6F, 0x8F,
++	0x86, 0x80, 0x57, 0xE9,
++	0x38, 0x1D, 0x6F, 0x8F,
+ 
+-0x28, 0x74,
+-0x00, 0xE0,
+-0x0D, 0x44, 0x4C, 0xB0,
++	0x28, 0x74,
++	0x00, 0xE0,
++	0x0D, 0x44, 0x4C, 0xB0,
+ 
+-0x05, 0x44, 0x54, 0xB0,
+-0x2D, 0x20,
+-0x9B, 0x10,
++	0x05, 0x44, 0x54, 0xB0,
++	0x2D, 0x20,
++	0x9B, 0x10,
+ 
+-0x82, 0x3E, 0x57, 0xE9,
+-0x32, 0xF0, 0x1B, 0xCD,
++	0x82, 0x3E, 0x57, 0xE9,
++	0x32, 0xF0, 0x1B, 0xCD,
+ 
+-0x1E, 0xBD, 0x59, 0x9F,
+-0x83, 0x1E, 0x57, 0xE9,
++	0x1E, 0xBD, 0x59, 0x9F,
++	0x83, 0x1E, 0x57, 0xE9,
+ 
+-0x38, 0x47, 0x38, 0xAF,
+-0x34, 0x20,
+-0x2A, 0x30,
++	0x38, 0x47, 0x38, 0xAF,
++	0x34, 0x20,
++	0x2A, 0x30,
+ 
+-0x00, 0xE0,
+-0x0D, 0x20,
+-0x32, 0x20,
+-0x05, 0x20,
++	0x00, 0xE0,
++	0x0D, 0x20,
++	0x32, 0x20,
++	0x05, 0x20,
+ 
+-0x87, 0x80, 0x57, 0xE9,
+-0x1F, 0x54, 0x57, 0x9F,
++	0x87, 0x80, 0x57, 0xE9,
++	0x1F, 0x54, 0x57, 0x9F,
+ 
+-0x17, 0x42, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x6A,
++	0x17, 0x42, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x6A,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x37, 0x1E, 0x4F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x37, 0x1E, 0x4F, 0xE9,
+ 
+-0x37, 0x32, 0x2A, 0xAF,
+-0x00, 0xE0,
+-0x32, 0x00,
++	0x37, 0x32, 0x2A, 0xAF,
++	0x00, 0xE0,
++	0x32, 0x00,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x27, 0xC0, 0x44, 0xC0,
++	0x00, 0x80, 0x00, 0xE8,
++	0x27, 0xC0, 0x44, 0xC0,
+ 
+-0x36, 0x1F, 0x4F, 0xE9,
+-0x1F, 0x1F, 0x26, 0xDF,
++	0x36, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x1F, 0x26, 0xDF,
+ 
+-0x37, 0x1B, 0x37, 0xBF,
+-0x17, 0x26, 0x17, 0xDF,
++	0x37, 0x1B, 0x37, 0xBF,
++	0x17, 0x26, 0x17, 0xDF,
+ 
+-0x3E, 0x17, 0x4F, 0xE9,
+-0x3F, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x17, 0x4F, 0xE9,
++	0x3F, 0x3F, 0x4F, 0xE9,
+ 
+-0x34, 0x1F, 0x34, 0xAF,
+-0x2B, 0x05,
+-0xA7, 0x20,
++	0x34, 0x1F, 0x34, 0xAF,
++	0x2B, 0x05,
++	0xA7, 0x20,
+ 
+-0x33, 0x2B, 0x37, 0xDF,
+-0x27, 0x17, 0xC0, 0xAF,
++	0x33, 0x2B, 0x37, 0xDF,
++	0x27, 0x17, 0xC0, 0xAF,
+ 
+-0x34, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x34, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0D, 0x21, 0x1A, 0xB6,
+-0x05, 0x21, 0x31, 0xB6,
++	0x0D, 0x21, 0x1A, 0xB6,
++	0x05, 0x21, 0x31, 0xB6,
+ 
+-0x2D, 0x44, 0x4C, 0xB6,
+-0x25, 0x44, 0x54, 0xB6,
++	0x2D, 0x44, 0x4C, 0xB6,
++	0x25, 0x44, 0x54, 0xB6,
+ 
+-0x03, 0x80, 0x2A, 0xEA,
+-0x17, 0xC1, 0x2B, 0xBD,
++	0x03, 0x80, 0x2A, 0xEA,
++	0x17, 0xC1, 0x2B, 0xBD,
+ 
+-0x0D, 0x20,
+-0x05, 0x20,
+-0x2F, 0xC0, 0x21, 0xC6,
++	0x0D, 0x20,
++	0x05, 0x20,
++	0x2F, 0xC0, 0x21, 0xC6,
+ 
+-0xB3, 0x68,
+-0x97, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x68,
++	0x97, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0xC0, 0x33, 0xAF,
+-0x3C, 0x27, 0x4F, 0xE9,
++	0x33, 0xC0, 0x33, 0xAF,
++	0x3C, 0x27, 0x4F, 0xE9,
+ 
+-0x00, 0xE0,
+-0x25, 0x20,
+-0x07, 0xC0, 0x44, 0xC6,
++	0x00, 0xE0,
++	0x25, 0x20,
++	0x07, 0xC0, 0x44, 0xC6,
+ 
+-0x17, 0x50, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x2D, 0x20,
++	0x17, 0x50, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x2D, 0x20,
+ 
+-0x37, 0x0F, 0x5C, 0x9F,
+-0x00, 0xE0,
+-0x2F, 0x20,
++	0x37, 0x0F, 0x5C, 0x9F,
++	0x00, 0xE0,
++	0x2F, 0x20,
+ 
+-0x1F, 0x62, 0x57, 0x9F,
+-0x00, 0xE0,
+-0x07, 0x20,
++	0x1F, 0x62, 0x57, 0x9F,
++	0x00, 0xE0,
++	0x07, 0x20,
+ 
+-0x3F, 0x3D, 0x5D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0x3D, 0x5D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x28, 0x19, 0x60, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
++	0x28, 0x19, 0x60, 0xEC,
+ 
+-0xB3, 0x05,
+-0x00, 0xE0,
+-0x17, 0x26, 0x17, 0xDF,
++	0xB3, 0x05,
++	0x00, 0xE0,
++	0x17, 0x26, 0x17, 0xDF,
+ 
+-0x23, 0x3B, 0x33, 0xAD,
+-0x35, 0x17, 0x4F, 0xE9,
++	0x23, 0x3B, 0x33, 0xAD,
++	0x35, 0x17, 0x4F, 0xE9,
+ 
+-0x1F, 0x26, 0x1F, 0xDF,
+-0x9D, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x26, 0x1F, 0xDF,
++	0x9D, 0x1F, 0x4F, 0xE9,
+ 
+-0x9E, 0x3F, 0x4F, 0xE9,
+-0x39, 0x37, 0x4F, 0xE9,
++	0x9E, 0x3F, 0x4F, 0xE9,
++	0x39, 0x37, 0x4F, 0xE9,
+ 
+-0x2F, 0x2F, 0x17, 0xAF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x2F, 0x2F, 0x17, 0xAF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x07, 0x07, 0x1F, 0xAF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x07, 0x07, 0x1F, 0xAF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x31, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x9C, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x57, 0x39, 0x20, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x57, 0x39, 0x20, 0xE9,
+ 
+-0x16, 0x28, 0x20, 0xE9,
+-0x1D, 0x3B, 0x20, 0xE9,
++	0x16, 0x28, 0x20, 0xE9,
++	0x1D, 0x3B, 0x20, 0xE9,
+ 
+-0x1E, 0x2B, 0x20, 0xE9,
+-0x2B, 0x32, 0x20, 0xE9,
++	0x1E, 0x2B, 0x20, 0xE9,
++	0x2B, 0x32, 0x20, 0xE9,
+ 
+-0x1C, 0x23, 0x20, 0xE9,
+-0x57, 0x36, 0x20, 0xE9,
++	0x1C, 0x23, 0x20, 0xE9,
++	0x57, 0x36, 0x20, 0xE9,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x90, 0xE2,
+-0x00, 0xE0,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x90, 0xE2,
++	0x00, 0xE0,
+ 
+-0x74, 0xFF, 0x20, 0xEA,
+-0x19, 0xC8, 0xC1, 0xCD,
++	0x74, 0xFF, 0x20, 0xEA,
++	0x19, 0xC8, 0xC1, 0xCD,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x9F, 0x41, 0x49, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9F, 0x41, 0x49, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x41, 0x49, 0xBD,
+-0x2D, 0x41, 0x51, 0xBD,
++	0x25, 0x41, 0x49, 0xBD,
++	0x2D, 0x41, 0x51, 0xBD,
+ 
+-0x0D, 0x80, 0x07, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x0D, 0x80, 0x07, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x35, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0x35, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x25, 0x30,
+-0x2D, 0x30,
++	0x00, 0x80, 0x00, 0xE8,
++	0x25, 0x30,
++	0x2D, 0x30,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0xA7, 0x5B, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0xA7, 0x5B, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x73, 0xFF, 0x0A, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x73, 0xFF, 0x0A, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC9, 0x41, 0xC8, 0xEC,
+-0x42, 0xE1,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC8, 0xEC,
++	0x42, 0xE1,
++	0x00, 0xE0,
+ 
+-0x71, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x71, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC8, 0x40, 0xC0, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC8, 0x40, 0xC0, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6E, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x6E, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+ };
+ 
+ static unsigned char warp_g200_tgzf[] = {
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x98, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x98, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x81, 0x04,
+-0x89, 0x04,
+-0x01, 0x04,
+-0x09, 0x04,
++	0x81, 0x04,
++	0x89, 0x04,
++	0x01, 0x04,
++	0x09, 0x04,
+ 
+-0xC9, 0x41, 0xC0, 0xEC,
+-0x11, 0x04,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC0, 0xEC,
++	0x11, 0x04,
++	0x00, 0xE0,
+ 
+-0x41, 0xCC, 0x41, 0xCD,
+-0x49, 0xCC, 0x49, 0xCD,
++	0x41, 0xCC, 0x41, 0xCD,
++	0x49, 0xCC, 0x49, 0xCD,
+ 
+-0xD1, 0x41, 0xC0, 0xEC,
+-0x51, 0xCC, 0x51, 0xCD,
++	0xD1, 0x41, 0xC0, 0xEC,
++	0x51, 0xCC, 0x51, 0xCD,
+ 
+-0x80, 0x04,
+-0x10, 0x04,
+-0x08, 0x04,
+-0x00, 0xE0,
++	0x80, 0x04,
++	0x10, 0x04,
++	0x08, 0x04,
++	0x00, 0xE0,
+ 
+-0x00, 0xCC, 0xC0, 0xCD,
+-0xD1, 0x49, 0xC0, 0xEC,
++	0x00, 0xCC, 0xC0, 0xCD,
++	0xD1, 0x49, 0xC0, 0xEC,
+ 
+-0x8A, 0x1F, 0x20, 0xE9,
+-0x8B, 0x3F, 0x20, 0xE9,
++	0x8A, 0x1F, 0x20, 0xE9,
++	0x8B, 0x3F, 0x20, 0xE9,
+ 
+-0x41, 0x3C, 0x41, 0xAD,
+-0x49, 0x3C, 0x49, 0xAD,
++	0x41, 0x3C, 0x41, 0xAD,
++	0x49, 0x3C, 0x49, 0xAD,
+ 
+-0x10, 0xCC, 0x10, 0xCD,
+-0x08, 0xCC, 0x08, 0xCD,
++	0x10, 0xCC, 0x10, 0xCD,
++	0x08, 0xCC, 0x08, 0xCD,
+ 
+-0xB9, 0x41, 0x49, 0xBB,
+-0x1F, 0xF0, 0x41, 0xCD,
++	0xB9, 0x41, 0x49, 0xBB,
++	0x1F, 0xF0, 0x41, 0xCD,
+ 
+-0x51, 0x3C, 0x51, 0xAD,
+-0x00, 0x98, 0x80, 0xE9,
++	0x51, 0x3C, 0x51, 0xAD,
++	0x00, 0x98, 0x80, 0xE9,
+ 
+-0x7F, 0x80, 0x07, 0xEA,
+-0x24, 0x1F, 0x20, 0xE9,
++	0x7F, 0x80, 0x07, 0xEA,
++	0x24, 0x1F, 0x20, 0xE9,
+ 
+-0x21, 0x45, 0x80, 0xE8,
+-0x1A, 0x4D, 0x80, 0xE8,
++	0x21, 0x45, 0x80, 0xE8,
++	0x1A, 0x4D, 0x80, 0xE8,
+ 
+-0x31, 0x55, 0x80, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x55, 0x80, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0x41, 0x49, 0xBD,
+-0x1D, 0x41, 0x51, 0xBD,
++	0x15, 0x41, 0x49, 0xBD,
++	0x1D, 0x41, 0x51, 0xBD,
+ 
+-0x2E, 0x41, 0x2A, 0xB8,
+-0x34, 0x53, 0xA0, 0xE8,
++	0x2E, 0x41, 0x2A, 0xB8,
++	0x34, 0x53, 0xA0, 0xE8,
+ 
+-0x15, 0x30,
+-0x1D, 0x30,
+-0x58, 0xE3,
+-0x00, 0xE0,
++	0x15, 0x30,
++	0x1D, 0x30,
++	0x58, 0xE3,
++	0x00, 0xE0,
+ 
+-0xB5, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0xB5, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x24, 0x43, 0xA0, 0xE8,
+-0x2C, 0x4B, 0xA0, 0xE8,
++	0x24, 0x43, 0xA0, 0xE8,
++	0x2C, 0x4B, 0xA0, 0xE8,
+ 
+-0x15, 0x72,
+-0x09, 0xE3,
+-0x00, 0xE0,
+-0x1D, 0x72,
++	0x15, 0x72,
++	0x09, 0xE3,
++	0x00, 0xE0,
++	0x1D, 0x72,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0x97, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x97, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6C, 0x64, 0xC8, 0xEC,
+-0x98, 0xE1,
+-0xB5, 0x05,
++	0x6C, 0x64, 0xC8, 0xEC,
++	0x98, 0xE1,
++	0xB5, 0x05,
+ 
+-0xBD, 0x05,
+-0x2E, 0x30,
+-0x32, 0xC0, 0xA0, 0xE8,
++	0xBD, 0x05,
++	0x2E, 0x30,
++	0x32, 0xC0, 0xA0, 0xE8,
+ 
+-0x33, 0xC0, 0xA0, 0xE8,
+-0x74, 0x64, 0xC8, 0xEC,
++	0x33, 0xC0, 0xA0, 0xE8,
++	0x74, 0x64, 0xC8, 0xEC,
+ 
+-0x40, 0x3C, 0x40, 0xAD,
+-0x32, 0x6A,
+-0x2A, 0x30,
++	0x40, 0x3C, 0x40, 0xAD,
++	0x32, 0x6A,
++	0x2A, 0x30,
+ 
+-0x20, 0x73,
+-0x33, 0x6A,
+-0x00, 0xE0,
+-0x28, 0x73,
++	0x20, 0x73,
++	0x33, 0x6A,
++	0x00, 0xE0,
++	0x28, 0x73,
+ 
+-0x1C, 0x72,
+-0x83, 0xE2,
+-0x6B, 0x80, 0x15, 0xEA,
++	0x1C, 0x72,
++	0x83, 0xE2,
++	0x6B, 0x80, 0x15, 0xEA,
+ 
+-0xB8, 0x3D, 0x28, 0xDF,
+-0x30, 0x35, 0x20, 0xDF,
++	0xB8, 0x3D, 0x28, 0xDF,
++	0x30, 0x35, 0x20, 0xDF,
+ 
+-0x40, 0x30,
+-0x00, 0xE0,
+-0xCC, 0xE2,
+-0x64, 0x72,
++	0x40, 0x30,
++	0x00, 0xE0,
++	0xCC, 0xE2,
++	0x64, 0x72,
+ 
+-0x25, 0x42, 0x52, 0xBF,
+-0x2D, 0x42, 0x4A, 0xBF,
++	0x25, 0x42, 0x52, 0xBF,
++	0x2D, 0x42, 0x4A, 0xBF,
+ 
+-0x30, 0x2E, 0x30, 0xDF,
+-0x38, 0x2E, 0x38, 0xDF,
++	0x30, 0x2E, 0x30, 0xDF,
++	0x38, 0x2E, 0x38, 0xDF,
+ 
+-0x18, 0x1D, 0x45, 0xE9,
+-0x1E, 0x15, 0x45, 0xE9,
++	0x18, 0x1D, 0x45, 0xE9,
++	0x1E, 0x15, 0x45, 0xE9,
+ 
+-0x2B, 0x49, 0x51, 0xBD,
+-0x00, 0xE0,
+-0x1F, 0x73,
++	0x2B, 0x49, 0x51, 0xBD,
++	0x00, 0xE0,
++	0x1F, 0x73,
+ 
+-0x38, 0x38, 0x40, 0xAF,
+-0x30, 0x30, 0x40, 0xAF,
++	0x38, 0x38, 0x40, 0xAF,
++	0x30, 0x30, 0x40, 0xAF,
+ 
+-0x24, 0x1F, 0x24, 0xDF,
+-0x1D, 0x32, 0x20, 0xE9,
++	0x24, 0x1F, 0x24, 0xDF,
++	0x1D, 0x32, 0x20, 0xE9,
+ 
+-0x2C, 0x1F, 0x2C, 0xDF,
+-0x1A, 0x33, 0x20, 0xE9,
++	0x2C, 0x1F, 0x2C, 0xDF,
++	0x1A, 0x33, 0x20, 0xE9,
+ 
+-0xB0, 0x10,
+-0x08, 0xE3,
+-0x40, 0x10,
+-0xB8, 0x10,
++	0xB0, 0x10,
++	0x08, 0xE3,
++	0x40, 0x10,
++	0xB8, 0x10,
+ 
+-0x26, 0xF0, 0x30, 0xCD,
+-0x2F, 0xF0, 0x38, 0xCD,
++	0x26, 0xF0, 0x30, 0xCD,
++	0x2F, 0xF0, 0x38, 0xCD,
+ 
+-0x2B, 0x80, 0x20, 0xE9,
+-0x2A, 0x80, 0x20, 0xE9,
++	0x2B, 0x80, 0x20, 0xE9,
++	0x2A, 0x80, 0x20, 0xE9,
+ 
+-0xA6, 0x20,
+-0x88, 0xE2,
+-0x00, 0xE0,
+-0xAF, 0x20,
++	0xA6, 0x20,
++	0x88, 0xE2,
++	0x00, 0xE0,
++	0xAF, 0x20,
+ 
+-0x28, 0x2A, 0x26, 0xAF,
+-0x20, 0x2A, 0xC0, 0xAF,
++	0x28, 0x2A, 0x26, 0xAF,
++	0x20, 0x2A, 0xC0, 0xAF,
+ 
+-0x34, 0x1F, 0x34, 0xDF,
+-0x46, 0x24, 0x46, 0xDF,
++	0x34, 0x1F, 0x34, 0xDF,
++	0x46, 0x24, 0x46, 0xDF,
+ 
+-0x28, 0x30, 0x80, 0xBF,
+-0x20, 0x38, 0x80, 0xBF,
++	0x28, 0x30, 0x80, 0xBF,
++	0x20, 0x38, 0x80, 0xBF,
+ 
+-0x47, 0x24, 0x47, 0xDF,
+-0x4E, 0x2C, 0x4E, 0xDF,
++	0x47, 0x24, 0x47, 0xDF,
++	0x4E, 0x2C, 0x4E, 0xDF,
+ 
+-0x4F, 0x2C, 0x4F, 0xDF,
+-0x56, 0x34, 0x56, 0xDF,
++	0x4F, 0x2C, 0x4F, 0xDF,
++	0x56, 0x34, 0x56, 0xDF,
+ 
+-0x28, 0x15, 0x28, 0xDF,
+-0x20, 0x1D, 0x20, 0xDF,
++	0x28, 0x15, 0x28, 0xDF,
++	0x20, 0x1D, 0x20, 0xDF,
+ 
+-0x57, 0x34, 0x57, 0xDF,
+-0x00, 0xE0,
+-0x1D, 0x05,
++	0x57, 0x34, 0x57, 0xDF,
++	0x00, 0xE0,
++	0x1D, 0x05,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x89, 0xE2,
+-0x2B, 0x30,
++	0x04, 0x80, 0x10, 0xEA,
++	0x89, 0xE2,
++	0x2B, 0x30,
+ 
+-0x3F, 0xC1, 0x1D, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0xC1, 0x1D, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x68,
+-0xBF, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x68,
++	0xBF, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x20, 0xC0, 0x20, 0xAF,
+-0x28, 0x05,
+-0x97, 0x74,
++	0x20, 0xC0, 0x20, 0xAF,
++	0x28, 0x05,
++	0x97, 0x74,
+ 
+-0x00, 0xE0,
+-0x2A, 0x10,
+-0x16, 0xC0, 0x20, 0xE9,
++	0x00, 0xE0,
++	0x2A, 0x10,
++	0x16, 0xC0, 0x20, 0xE9,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x8C, 0xE2,
+-0x95, 0x05,
++	0x04, 0x80, 0x10, 0xEA,
++	0x8C, 0xE2,
++	0x95, 0x05,
+ 
+-0x28, 0xC1, 0x28, 0xAD,
+-0x1F, 0xC1, 0x15, 0xBD,
++	0x28, 0xC1, 0x28, 0xAD,
++	0x1F, 0xC1, 0x15, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA8, 0x67,
+-0x9F, 0x6B,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA8, 0x67,
++	0x9F, 0x6B,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x28, 0xC0, 0x28, 0xAD,
+-0x1D, 0x25,
+-0x20, 0x05,
++	0x28, 0xC0, 0x28, 0xAD,
++	0x1D, 0x25,
++	0x20, 0x05,
+ 
+-0x28, 0x32, 0x80, 0xAD,
+-0x40, 0x2A, 0x40, 0xBD,
++	0x28, 0x32, 0x80, 0xAD,
++	0x40, 0x2A, 0x40, 0xBD,
+ 
+-0x1C, 0x80, 0x20, 0xE9,
+-0x20, 0x33, 0x20, 0xAD,
++	0x1C, 0x80, 0x20, 0xE9,
++	0x20, 0x33, 0x20, 0xAD,
+ 
+-0x20, 0x73,
+-0x00, 0xE0,
+-0xB6, 0x49, 0x51, 0xBB,
++	0x20, 0x73,
++	0x00, 0xE0,
++	0xB6, 0x49, 0x51, 0xBB,
+ 
+-0x26, 0x2F, 0xB0, 0xE8,
+-0x19, 0x20, 0x20, 0xE9,
++	0x26, 0x2F, 0xB0, 0xE8,
++	0x19, 0x20, 0x20, 0xE9,
+ 
+-0x35, 0x20, 0x35, 0xDF,
+-0x3D, 0x20, 0x3D, 0xDF,
++	0x35, 0x20, 0x35, 0xDF,
++	0x3D, 0x20, 0x3D, 0xDF,
+ 
+-0x15, 0x20, 0x15, 0xDF,
+-0x1D, 0x20, 0x1D, 0xDF,
++	0x15, 0x20, 0x15, 0xDF,
++	0x1D, 0x20, 0x1D, 0xDF,
+ 
+-0x26, 0xD0, 0x26, 0xCD,
+-0x29, 0x49, 0x2A, 0xB8,
++	0x26, 0xD0, 0x26, 0xCD,
++	0x29, 0x49, 0x2A, 0xB8,
+ 
+-0x26, 0x40, 0x80, 0xBD,
+-0x3B, 0x48, 0x50, 0xBD,
++	0x26, 0x40, 0x80, 0xBD,
++	0x3B, 0x48, 0x50, 0xBD,
+ 
+-0x3E, 0x54, 0x57, 0x9F,
+-0x00, 0xE0,
+-0x82, 0xE1,
++	0x3E, 0x54, 0x57, 0x9F,
++	0x00, 0xE0,
++	0x82, 0xE1,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x26, 0x30,
+-0x29, 0x30,
+-0x48, 0x3C, 0x48, 0xAD,
++	0x26, 0x30,
++	0x29, 0x30,
++	0x48, 0x3C, 0x48, 0xAD,
+ 
+-0x2B, 0x72,
+-0xC2, 0xE1,
+-0x2C, 0xC0, 0x44, 0xC2,
++	0x2B, 0x72,
++	0xC2, 0xE1,
++	0x2C, 0xC0, 0x44, 0xC2,
+ 
+-0x05, 0x24, 0x34, 0xBF,
+-0x0D, 0x24, 0x2C, 0xBF,
++	0x05, 0x24, 0x34, 0xBF,
++	0x0D, 0x24, 0x2C, 0xBF,
+ 
+-0x2D, 0x46, 0x4E, 0xBF,
+-0x25, 0x46, 0x56, 0xBF,
++	0x2D, 0x46, 0x4E, 0xBF,
++	0x25, 0x46, 0x56, 0xBF,
+ 
+-0x20, 0x1D, 0x6F, 0x8F,
+-0x32, 0x3E, 0x5F, 0xE9,
++	0x20, 0x1D, 0x6F, 0x8F,
++	0x32, 0x3E, 0x5F, 0xE9,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x30,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x30,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x33, 0x1E, 0x5F, 0xE9,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x33, 0x1E, 0x5F, 0xE9,
+ 
+-0x05, 0x44, 0x54, 0xB2,
+-0x0D, 0x44, 0x4C, 0xB2,
++	0x05, 0x44, 0x54, 0xB2,
++	0x0D, 0x44, 0x4C, 0xB2,
+ 
+-0x19, 0xC0, 0xB0, 0xE8,
+-0x34, 0xC0, 0x44, 0xC4,
++	0x19, 0xC0, 0xB0, 0xE8,
++	0x34, 0xC0, 0x44, 0xC4,
+ 
+-0x33, 0x73,
+-0x00, 0xE0,
+-0x3E, 0x62, 0x57, 0x9F,
++	0x33, 0x73,
++	0x00, 0xE0,
++	0x3E, 0x62, 0x57, 0x9F,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0xE0,
+-0x0D, 0x20,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0xE0,
++	0x0D, 0x20,
+ 
+-0x84, 0x3E, 0x58, 0xE9,
+-0x28, 0x1D, 0x6F, 0x8F,
++	0x84, 0x3E, 0x58, 0xE9,
++	0x28, 0x1D, 0x6F, 0x8F,
+ 
+-0x05, 0x20,
+-0x00, 0xE0,
+-0x85, 0x1E, 0x58, 0xE9,
++	0x05, 0x20,
++	0x00, 0xE0,
++	0x85, 0x1E, 0x58, 0xE9,
+ 
+-0x9B, 0x3B, 0x33, 0xDF,
+-0x20, 0x20, 0x42, 0xAF,
++	0x9B, 0x3B, 0x33, 0xDF,
++	0x20, 0x20, 0x42, 0xAF,
+ 
+-0x30, 0x42, 0x56, 0x9F,
+-0x80, 0x3E, 0x57, 0xE9,
++	0x30, 0x42, 0x56, 0x9F,
++	0x80, 0x3E, 0x57, 0xE9,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x30, 0x80, 0x5F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x30, 0x80, 0x5F, 0xE9,
+ 
+-0x28, 0x28, 0x24, 0xAF,
+-0x81, 0x1E, 0x57, 0xE9,
++	0x28, 0x28, 0x24, 0xAF,
++	0x81, 0x1E, 0x57, 0xE9,
+ 
+-0x05, 0x47, 0x57, 0xBF,
+-0x0D, 0x47, 0x4F, 0xBF,
++	0x05, 0x47, 0x57, 0xBF,
++	0x0D, 0x47, 0x4F, 0xBF,
+ 
+-0x88, 0x80, 0x58, 0xE9,
+-0x1B, 0x29, 0x1B, 0xDF,
++	0x88, 0x80, 0x58, 0xE9,
++	0x1B, 0x29, 0x1B, 0xDF,
+ 
+-0x30, 0x1D, 0x6F, 0x8F,
+-0x3A, 0x30, 0x4F, 0xE9,
++	0x30, 0x1D, 0x6F, 0x8F,
++	0x3A, 0x30, 0x4F, 0xE9,
+ 
+-0x1C, 0x30, 0x26, 0xDF,
+-0x09, 0xE3,
+-0x3B, 0x05,
++	0x1C, 0x30, 0x26, 0xDF,
++	0x09, 0xE3,
++	0x3B, 0x05,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x3B, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x3B, 0x3F, 0x4F, 0xE9,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x00, 0xE0,
+-0xAC, 0x20,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x00, 0xE0,
++	0xAC, 0x20,
+ 
+-0x2D, 0x44, 0x4C, 0xB4,
+-0x2C, 0x1C, 0xC0, 0xAF,
++	0x2D, 0x44, 0x4C, 0xB4,
++	0x2C, 0x1C, 0xC0, 0xAF,
+ 
+-0x25, 0x44, 0x54, 0xB4,
+-0x00, 0xE0,
+-0xC8, 0x30,
++	0x25, 0x44, 0x54, 0xB4,
++	0x00, 0xE0,
++	0xC8, 0x30,
+ 
+-0x30, 0x46, 0x30, 0xAF,
+-0x1B, 0x1B, 0x48, 0xAF,
++	0x30, 0x46, 0x30, 0xAF,
++	0x1B, 0x1B, 0x48, 0xAF,
+ 
+-0x00, 0xE0,
+-0x25, 0x20,
+-0x38, 0x2C, 0x4F, 0xE9,
++	0x00, 0xE0,
++	0x25, 0x20,
++	0x38, 0x2C, 0x4F, 0xE9,
+ 
+-0x86, 0x80, 0x57, 0xE9,
+-0x38, 0x1D, 0x6F, 0x8F,
++	0x86, 0x80, 0x57, 0xE9,
++	0x38, 0x1D, 0x6F, 0x8F,
+ 
+-0x28, 0x74,
+-0x00, 0xE0,
+-0x0D, 0x44, 0x4C, 0xB0,
++	0x28, 0x74,
++	0x00, 0xE0,
++	0x0D, 0x44, 0x4C, 0xB0,
+ 
+-0x05, 0x44, 0x54, 0xB0,
+-0x2D, 0x20,
+-0x9B, 0x10,
++	0x05, 0x44, 0x54, 0xB0,
++	0x2D, 0x20,
++	0x9B, 0x10,
+ 
+-0x82, 0x3E, 0x57, 0xE9,
+-0x32, 0xF0, 0x1B, 0xCD,
++	0x82, 0x3E, 0x57, 0xE9,
++	0x32, 0xF0, 0x1B, 0xCD,
+ 
+-0x1E, 0xBD, 0x59, 0x9F,
+-0x83, 0x1E, 0x57, 0xE9,
++	0x1E, 0xBD, 0x59, 0x9F,
++	0x83, 0x1E, 0x57, 0xE9,
+ 
+-0x38, 0x47, 0x38, 0xAF,
+-0x34, 0x20,
+-0x2A, 0x30,
++	0x38, 0x47, 0x38, 0xAF,
++	0x34, 0x20,
++	0x2A, 0x30,
+ 
+-0x00, 0xE0,
+-0x0D, 0x20,
+-0x32, 0x20,
+-0x05, 0x20,
++	0x00, 0xE0,
++	0x0D, 0x20,
++	0x32, 0x20,
++	0x05, 0x20,
+ 
+-0x87, 0x80, 0x57, 0xE9,
+-0x1F, 0x54, 0x57, 0x9F,
++	0x87, 0x80, 0x57, 0xE9,
++	0x1F, 0x54, 0x57, 0x9F,
+ 
+-0x17, 0x42, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x6A,
++	0x17, 0x42, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x6A,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x37, 0x1E, 0x4F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x37, 0x1E, 0x4F, 0xE9,
+ 
+-0x37, 0x32, 0x2A, 0xAF,
+-0x00, 0xE0,
+-0x32, 0x00,
++	0x37, 0x32, 0x2A, 0xAF,
++	0x00, 0xE0,
++	0x32, 0x00,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x27, 0xC0, 0x44, 0xC0,
++	0x00, 0x80, 0x00, 0xE8,
++	0x27, 0xC0, 0x44, 0xC0,
+ 
+-0x36, 0x1F, 0x4F, 0xE9,
+-0x1F, 0x1F, 0x26, 0xDF,
++	0x36, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x1F, 0x26, 0xDF,
+ 
+-0x37, 0x1B, 0x37, 0xBF,
+-0x17, 0x26, 0x17, 0xDF,
++	0x37, 0x1B, 0x37, 0xBF,
++	0x17, 0x26, 0x17, 0xDF,
+ 
+-0x3E, 0x17, 0x4F, 0xE9,
+-0x3F, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x17, 0x4F, 0xE9,
++	0x3F, 0x3F, 0x4F, 0xE9,
+ 
+-0x34, 0x1F, 0x34, 0xAF,
+-0x2B, 0x05,
+-0xA7, 0x20,
++	0x34, 0x1F, 0x34, 0xAF,
++	0x2B, 0x05,
++	0xA7, 0x20,
+ 
+-0x33, 0x2B, 0x37, 0xDF,
+-0x27, 0x17, 0xC0, 0xAF,
++	0x33, 0x2B, 0x37, 0xDF,
++	0x27, 0x17, 0xC0, 0xAF,
+ 
+-0x34, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x34, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0D, 0x21, 0x1A, 0xB6,
+-0x05, 0x21, 0x31, 0xB6,
++	0x0D, 0x21, 0x1A, 0xB6,
++	0x05, 0x21, 0x31, 0xB6,
+ 
+-0x03, 0x80, 0x2A, 0xEA,
+-0x17, 0xC1, 0x2B, 0xBD,
++	0x03, 0x80, 0x2A, 0xEA,
++	0x17, 0xC1, 0x2B, 0xBD,
+ 
+-0x0D, 0x20,
+-0x05, 0x20,
+-0x2F, 0xC0, 0x21, 0xC6,
++	0x0D, 0x20,
++	0x05, 0x20,
++	0x2F, 0xC0, 0x21, 0xC6,
+ 
+-0xB3, 0x68,
+-0x97, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x68,
++	0x97, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0xC0, 0x33, 0xAF,
+-0x3C, 0x27, 0x4F, 0xE9,
++	0x33, 0xC0, 0x33, 0xAF,
++	0x3C, 0x27, 0x4F, 0xE9,
+ 
+-0x17, 0x50, 0x56, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x17, 0x50, 0x56, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x37, 0x0F, 0x5C, 0x9F,
+-0x00, 0xE0,
+-0x2F, 0x20,
++	0x37, 0x0F, 0x5C, 0x9F,
++	0x00, 0xE0,
++	0x2F, 0x20,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x28, 0x19, 0x60, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
++	0x28, 0x19, 0x60, 0xEC,
+ 
+-0xB3, 0x05,
+-0x00, 0xE0,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x05,
++	0x00, 0xE0,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x23, 0x3B, 0x33, 0xAD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x23, 0x3B, 0x33, 0xAD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x17, 0x26, 0x17, 0xDF,
+-0x35, 0x17, 0x4F, 0xE9,
++	0x17, 0x26, 0x17, 0xDF,
++	0x35, 0x17, 0x4F, 0xE9,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x39, 0x37, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x39, 0x37, 0x4F, 0xE9,
+ 
+-0x2F, 0x2F, 0x17, 0xAF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x2F, 0x2F, 0x17, 0xAF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x31, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x57, 0x39, 0x20, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x57, 0x39, 0x20, 0xE9,
+ 
+-0x16, 0x28, 0x20, 0xE9,
+-0x1D, 0x3B, 0x20, 0xE9,
++	0x16, 0x28, 0x20, 0xE9,
++	0x1D, 0x3B, 0x20, 0xE9,
+ 
+-0x1E, 0x2B, 0x20, 0xE9,
+-0x2B, 0x32, 0x20, 0xE9,
++	0x1E, 0x2B, 0x20, 0xE9,
++	0x2B, 0x32, 0x20, 0xE9,
+ 
+-0x1C, 0x23, 0x20, 0xE9,
+-0x57, 0x36, 0x20, 0xE9,
++	0x1C, 0x23, 0x20, 0xE9,
++	0x57, 0x36, 0x20, 0xE9,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x90, 0xE2,
+-0x00, 0xE0,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x90, 0xE2,
++	0x00, 0xE0,
+ 
+-0x78, 0xFF, 0x20, 0xEA,
+-0x19, 0xC8, 0xC1, 0xCD,
++	0x78, 0xFF, 0x20, 0xEA,
++	0x19, 0xC8, 0xC1, 0xCD,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x9F, 0x41, 0x49, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9F, 0x41, 0x49, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x41, 0x49, 0xBD,
+-0x2D, 0x41, 0x51, 0xBD,
++	0x25, 0x41, 0x49, 0xBD,
++	0x2D, 0x41, 0x51, 0xBD,
+ 
+-0x0D, 0x80, 0x07, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x0D, 0x80, 0x07, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x35, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0x35, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x25, 0x30,
+-0x2D, 0x30,
++	0x00, 0x80, 0x00, 0xE8,
++	0x25, 0x30,
++	0x2D, 0x30,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0xA7, 0x5B, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0xA7, 0x5B, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x77, 0xFF, 0x0A, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x77, 0xFF, 0x0A, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC9, 0x41, 0xC8, 0xEC,
+-0x42, 0xE1,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC8, 0xEC,
++	0x42, 0xE1,
++	0x00, 0xE0,
+ 
+-0x75, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x75, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC8, 0x40, 0xC0, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC8, 0x40, 0xC0, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x72, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x72, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+ };
+ 
+ static unsigned char warp_g200_tgzs[] = {
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x98, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x98, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x81, 0x04,
+-0x89, 0x04,
+-0x01, 0x04,
+-0x09, 0x04,
++	0x81, 0x04,
++	0x89, 0x04,
++	0x01, 0x04,
++	0x09, 0x04,
+ 
+-0xC9, 0x41, 0xC0, 0xEC,
+-0x11, 0x04,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC0, 0xEC,
++	0x11, 0x04,
++	0x00, 0xE0,
+ 
+-0x41, 0xCC, 0x41, 0xCD,
+-0x49, 0xCC, 0x49, 0xCD,
++	0x41, 0xCC, 0x41, 0xCD,
++	0x49, 0xCC, 0x49, 0xCD,
+ 
+-0xD1, 0x41, 0xC0, 0xEC,
+-0x51, 0xCC, 0x51, 0xCD,
++	0xD1, 0x41, 0xC0, 0xEC,
++	0x51, 0xCC, 0x51, 0xCD,
+ 
+-0x80, 0x04,
+-0x10, 0x04,
+-0x08, 0x04,
+-0x00, 0xE0,
++	0x80, 0x04,
++	0x10, 0x04,
++	0x08, 0x04,
++	0x00, 0xE0,
+ 
+-0x00, 0xCC, 0xC0, 0xCD,
+-0xD1, 0x49, 0xC0, 0xEC,
++	0x00, 0xCC, 0xC0, 0xCD,
++	0xD1, 0x49, 0xC0, 0xEC,
+ 
+-0x8A, 0x1F, 0x20, 0xE9,
+-0x8B, 0x3F, 0x20, 0xE9,
++	0x8A, 0x1F, 0x20, 0xE9,
++	0x8B, 0x3F, 0x20, 0xE9,
+ 
+-0x41, 0x3C, 0x41, 0xAD,
+-0x49, 0x3C, 0x49, 0xAD,
++	0x41, 0x3C, 0x41, 0xAD,
++	0x49, 0x3C, 0x49, 0xAD,
+ 
+-0x10, 0xCC, 0x10, 0xCD,
+-0x08, 0xCC, 0x08, 0xCD,
++	0x10, 0xCC, 0x10, 0xCD,
++	0x08, 0xCC, 0x08, 0xCD,
+ 
+-0xB9, 0x41, 0x49, 0xBB,
+-0x1F, 0xF0, 0x41, 0xCD,
++	0xB9, 0x41, 0x49, 0xBB,
++	0x1F, 0xF0, 0x41, 0xCD,
+ 
+-0x51, 0x3C, 0x51, 0xAD,
+-0x00, 0x98, 0x80, 0xE9,
++	0x51, 0x3C, 0x51, 0xAD,
++	0x00, 0x98, 0x80, 0xE9,
+ 
+-0x8B, 0x80, 0x07, 0xEA,
+-0x24, 0x1F, 0x20, 0xE9,
++	0x8B, 0x80, 0x07, 0xEA,
++	0x24, 0x1F, 0x20, 0xE9,
+ 
+-0x21, 0x45, 0x80, 0xE8,
+-0x1A, 0x4D, 0x80, 0xE8,
++	0x21, 0x45, 0x80, 0xE8,
++	0x1A, 0x4D, 0x80, 0xE8,
+ 
+-0x31, 0x55, 0x80, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x55, 0x80, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0x41, 0x49, 0xBD,
+-0x1D, 0x41, 0x51, 0xBD,
++	0x15, 0x41, 0x49, 0xBD,
++	0x1D, 0x41, 0x51, 0xBD,
+ 
+-0x2E, 0x41, 0x2A, 0xB8,
+-0x34, 0x53, 0xA0, 0xE8,
++	0x2E, 0x41, 0x2A, 0xB8,
++	0x34, 0x53, 0xA0, 0xE8,
+ 
+-0x15, 0x30,
+-0x1D, 0x30,
+-0x58, 0xE3,
+-0x00, 0xE0,
++	0x15, 0x30,
++	0x1D, 0x30,
++	0x58, 0xE3,
++	0x00, 0xE0,
+ 
+-0xB5, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0xB5, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x24, 0x43, 0xA0, 0xE8,
+-0x2C, 0x4B, 0xA0, 0xE8,
++	0x24, 0x43, 0xA0, 0xE8,
++	0x2C, 0x4B, 0xA0, 0xE8,
+ 
+-0x15, 0x72,
+-0x09, 0xE3,
+-0x00, 0xE0,
+-0x1D, 0x72,
++	0x15, 0x72,
++	0x09, 0xE3,
++	0x00, 0xE0,
++	0x1D, 0x72,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0x97, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x97, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6C, 0x64, 0xC8, 0xEC,
+-0x98, 0xE1,
+-0xB5, 0x05,
++	0x6C, 0x64, 0xC8, 0xEC,
++	0x98, 0xE1,
++	0xB5, 0x05,
+ 
+-0xBD, 0x05,
+-0x2E, 0x30,
+-0x32, 0xC0, 0xA0, 0xE8,
++	0xBD, 0x05,
++	0x2E, 0x30,
++	0x32, 0xC0, 0xA0, 0xE8,
+ 
+-0x33, 0xC0, 0xA0, 0xE8,
+-0x74, 0x64, 0xC8, 0xEC,
++	0x33, 0xC0, 0xA0, 0xE8,
++	0x74, 0x64, 0xC8, 0xEC,
+ 
+-0x40, 0x3C, 0x40, 0xAD,
+-0x32, 0x6A,
+-0x2A, 0x30,
++	0x40, 0x3C, 0x40, 0xAD,
++	0x32, 0x6A,
++	0x2A, 0x30,
+ 
+-0x20, 0x73,
+-0x33, 0x6A,
+-0x00, 0xE0,
+-0x28, 0x73,
++	0x20, 0x73,
++	0x33, 0x6A,
++	0x00, 0xE0,
++	0x28, 0x73,
+ 
+-0x1C, 0x72,
+-0x83, 0xE2,
+-0x77, 0x80, 0x15, 0xEA,
++	0x1C, 0x72,
++	0x83, 0xE2,
++	0x77, 0x80, 0x15, 0xEA,
+ 
+-0xB8, 0x3D, 0x28, 0xDF,
+-0x30, 0x35, 0x20, 0xDF,
++	0xB8, 0x3D, 0x28, 0xDF,
++	0x30, 0x35, 0x20, 0xDF,
+ 
+-0x40, 0x30,
+-0x00, 0xE0,
+-0xCC, 0xE2,
+-0x64, 0x72,
++	0x40, 0x30,
++	0x00, 0xE0,
++	0xCC, 0xE2,
++	0x64, 0x72,
+ 
+-0x25, 0x42, 0x52, 0xBF,
+-0x2D, 0x42, 0x4A, 0xBF,
++	0x25, 0x42, 0x52, 0xBF,
++	0x2D, 0x42, 0x4A, 0xBF,
+ 
+-0x30, 0x2E, 0x30, 0xDF,
+-0x38, 0x2E, 0x38, 0xDF,
++	0x30, 0x2E, 0x30, 0xDF,
++	0x38, 0x2E, 0x38, 0xDF,
+ 
+-0x18, 0x1D, 0x45, 0xE9,
+-0x1E, 0x15, 0x45, 0xE9,
++	0x18, 0x1D, 0x45, 0xE9,
++	0x1E, 0x15, 0x45, 0xE9,
+ 
+-0x2B, 0x49, 0x51, 0xBD,
+-0x00, 0xE0,
+-0x1F, 0x73,
++	0x2B, 0x49, 0x51, 0xBD,
++	0x00, 0xE0,
++	0x1F, 0x73,
+ 
+-0x38, 0x38, 0x40, 0xAF,
+-0x30, 0x30, 0x40, 0xAF,
++	0x38, 0x38, 0x40, 0xAF,
++	0x30, 0x30, 0x40, 0xAF,
+ 
+-0x24, 0x1F, 0x24, 0xDF,
+-0x1D, 0x32, 0x20, 0xE9,
++	0x24, 0x1F, 0x24, 0xDF,
++	0x1D, 0x32, 0x20, 0xE9,
+ 
+-0x2C, 0x1F, 0x2C, 0xDF,
+-0x1A, 0x33, 0x20, 0xE9,
++	0x2C, 0x1F, 0x2C, 0xDF,
++	0x1A, 0x33, 0x20, 0xE9,
+ 
+-0xB0, 0x10,
+-0x08, 0xE3,
+-0x40, 0x10,
+-0xB8, 0x10,
++	0xB0, 0x10,
++	0x08, 0xE3,
++	0x40, 0x10,
++	0xB8, 0x10,
+ 
+-0x26, 0xF0, 0x30, 0xCD,
+-0x2F, 0xF0, 0x38, 0xCD,
++	0x26, 0xF0, 0x30, 0xCD,
++	0x2F, 0xF0, 0x38, 0xCD,
+ 
+-0x2B, 0x80, 0x20, 0xE9,
+-0x2A, 0x80, 0x20, 0xE9,
++	0x2B, 0x80, 0x20, 0xE9,
++	0x2A, 0x80, 0x20, 0xE9,
+ 
+-0xA6, 0x20,
+-0x88, 0xE2,
+-0x00, 0xE0,
+-0xAF, 0x20,
++	0xA6, 0x20,
++	0x88, 0xE2,
++	0x00, 0xE0,
++	0xAF, 0x20,
+ 
+-0x28, 0x2A, 0x26, 0xAF,
+-0x20, 0x2A, 0xC0, 0xAF,
++	0x28, 0x2A, 0x26, 0xAF,
++	0x20, 0x2A, 0xC0, 0xAF,
+ 
+-0x34, 0x1F, 0x34, 0xDF,
+-0x46, 0x24, 0x46, 0xDF,
++	0x34, 0x1F, 0x34, 0xDF,
++	0x46, 0x24, 0x46, 0xDF,
+ 
+-0x28, 0x30, 0x80, 0xBF,
+-0x20, 0x38, 0x80, 0xBF,
++	0x28, 0x30, 0x80, 0xBF,
++	0x20, 0x38, 0x80, 0xBF,
+ 
+-0x47, 0x24, 0x47, 0xDF,
+-0x4E, 0x2C, 0x4E, 0xDF,
++	0x47, 0x24, 0x47, 0xDF,
++	0x4E, 0x2C, 0x4E, 0xDF,
+ 
+-0x4F, 0x2C, 0x4F, 0xDF,
+-0x56, 0x34, 0x56, 0xDF,
++	0x4F, 0x2C, 0x4F, 0xDF,
++	0x56, 0x34, 0x56, 0xDF,
+ 
+-0x28, 0x15, 0x28, 0xDF,
+-0x20, 0x1D, 0x20, 0xDF,
++	0x28, 0x15, 0x28, 0xDF,
++	0x20, 0x1D, 0x20, 0xDF,
+ 
+-0x57, 0x34, 0x57, 0xDF,
+-0x00, 0xE0,
+-0x1D, 0x05,
++	0x57, 0x34, 0x57, 0xDF,
++	0x00, 0xE0,
++	0x1D, 0x05,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x89, 0xE2,
+-0x2B, 0x30,
++	0x04, 0x80, 0x10, 0xEA,
++	0x89, 0xE2,
++	0x2B, 0x30,
+ 
+-0x3F, 0xC1, 0x1D, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0xC1, 0x1D, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x68,
+-0xBF, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x68,
++	0xBF, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x20, 0xC0, 0x20, 0xAF,
+-0x28, 0x05,
+-0x97, 0x74,
++	0x20, 0xC0, 0x20, 0xAF,
++	0x28, 0x05,
++	0x97, 0x74,
+ 
+-0x00, 0xE0,
+-0x2A, 0x10,
+-0x16, 0xC0, 0x20, 0xE9,
++	0x00, 0xE0,
++	0x2A, 0x10,
++	0x16, 0xC0, 0x20, 0xE9,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x8C, 0xE2,
+-0x95, 0x05,
++	0x04, 0x80, 0x10, 0xEA,
++	0x8C, 0xE2,
++	0x95, 0x05,
+ 
+-0x28, 0xC1, 0x28, 0xAD,
+-0x1F, 0xC1, 0x15, 0xBD,
++	0x28, 0xC1, 0x28, 0xAD,
++	0x1F, 0xC1, 0x15, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA8, 0x67,
+-0x9F, 0x6B,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA8, 0x67,
++	0x9F, 0x6B,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x28, 0xC0, 0x28, 0xAD,
+-0x1D, 0x25,
+-0x20, 0x05,
++	0x28, 0xC0, 0x28, 0xAD,
++	0x1D, 0x25,
++	0x20, 0x05,
+ 
+-0x28, 0x32, 0x80, 0xAD,
+-0x40, 0x2A, 0x40, 0xBD,
++	0x28, 0x32, 0x80, 0xAD,
++	0x40, 0x2A, 0x40, 0xBD,
+ 
+-0x1C, 0x80, 0x20, 0xE9,
+-0x20, 0x33, 0x20, 0xAD,
++	0x1C, 0x80, 0x20, 0xE9,
++	0x20, 0x33, 0x20, 0xAD,
+ 
+-0x20, 0x73,
+-0x00, 0xE0,
+-0xB6, 0x49, 0x51, 0xBB,
++	0x20, 0x73,
++	0x00, 0xE0,
++	0xB6, 0x49, 0x51, 0xBB,
+ 
+-0x26, 0x2F, 0xB0, 0xE8,
+-0x19, 0x20, 0x20, 0xE9,
++	0x26, 0x2F, 0xB0, 0xE8,
++	0x19, 0x20, 0x20, 0xE9,
+ 
+-0x35, 0x20, 0x35, 0xDF,
+-0x3D, 0x20, 0x3D, 0xDF,
++	0x35, 0x20, 0x35, 0xDF,
++	0x3D, 0x20, 0x3D, 0xDF,
+ 
+-0x15, 0x20, 0x15, 0xDF,
+-0x1D, 0x20, 0x1D, 0xDF,
++	0x15, 0x20, 0x15, 0xDF,
++	0x1D, 0x20, 0x1D, 0xDF,
+ 
+-0x26, 0xD0, 0x26, 0xCD,
+-0x29, 0x49, 0x2A, 0xB8,
++	0x26, 0xD0, 0x26, 0xCD,
++	0x29, 0x49, 0x2A, 0xB8,
+ 
+-0x26, 0x40, 0x80, 0xBD,
+-0x3B, 0x48, 0x50, 0xBD,
++	0x26, 0x40, 0x80, 0xBD,
++	0x3B, 0x48, 0x50, 0xBD,
+ 
+-0x3E, 0x54, 0x57, 0x9F,
+-0x00, 0xE0,
+-0x82, 0xE1,
++	0x3E, 0x54, 0x57, 0x9F,
++	0x00, 0xE0,
++	0x82, 0xE1,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x26, 0x30,
+-0x29, 0x30,
+-0x48, 0x3C, 0x48, 0xAD,
++	0x26, 0x30,
++	0x29, 0x30,
++	0x48, 0x3C, 0x48, 0xAD,
+ 
+-0x2B, 0x72,
+-0xC2, 0xE1,
+-0x2C, 0xC0, 0x44, 0xC2,
++	0x2B, 0x72,
++	0xC2, 0xE1,
++	0x2C, 0xC0, 0x44, 0xC2,
+ 
+-0x05, 0x24, 0x34, 0xBF,
+-0x0D, 0x24, 0x2C, 0xBF,
++	0x05, 0x24, 0x34, 0xBF,
++	0x0D, 0x24, 0x2C, 0xBF,
+ 
+-0x2D, 0x46, 0x4E, 0xBF,
+-0x25, 0x46, 0x56, 0xBF,
++	0x2D, 0x46, 0x4E, 0xBF,
++	0x25, 0x46, 0x56, 0xBF,
+ 
+-0x20, 0x1D, 0x6F, 0x8F,
+-0x32, 0x3E, 0x5F, 0xE9,
++	0x20, 0x1D, 0x6F, 0x8F,
++	0x32, 0x3E, 0x5F, 0xE9,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x30,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x30,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x33, 0x1E, 0x5F, 0xE9,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x33, 0x1E, 0x5F, 0xE9,
+ 
+-0x05, 0x44, 0x54, 0xB2,
+-0x0D, 0x44, 0x4C, 0xB2,
++	0x05, 0x44, 0x54, 0xB2,
++	0x0D, 0x44, 0x4C, 0xB2,
+ 
+-0x19, 0xC0, 0xB0, 0xE8,
+-0x34, 0xC0, 0x44, 0xC4,
++	0x19, 0xC0, 0xB0, 0xE8,
++	0x34, 0xC0, 0x44, 0xC4,
+ 
+-0x33, 0x73,
+-0x00, 0xE0,
+-0x3E, 0x62, 0x57, 0x9F,
++	0x33, 0x73,
++	0x00, 0xE0,
++	0x3E, 0x62, 0x57, 0x9F,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0xE0,
+-0x0D, 0x20,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0xE0,
++	0x0D, 0x20,
+ 
+-0x84, 0x3E, 0x58, 0xE9,
+-0x28, 0x1D, 0x6F, 0x8F,
++	0x84, 0x3E, 0x58, 0xE9,
++	0x28, 0x1D, 0x6F, 0x8F,
+ 
+-0x05, 0x20,
+-0x00, 0xE0,
+-0x85, 0x1E, 0x58, 0xE9,
++	0x05, 0x20,
++	0x00, 0xE0,
++	0x85, 0x1E, 0x58, 0xE9,
+ 
+-0x9B, 0x3B, 0x33, 0xDF,
+-0x20, 0x20, 0x42, 0xAF,
++	0x9B, 0x3B, 0x33, 0xDF,
++	0x20, 0x20, 0x42, 0xAF,
+ 
+-0x30, 0x42, 0x56, 0x9F,
+-0x80, 0x3E, 0x57, 0xE9,
++	0x30, 0x42, 0x56, 0x9F,
++	0x80, 0x3E, 0x57, 0xE9,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x30, 0x80, 0x5F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x30, 0x80, 0x5F, 0xE9,
+ 
+-0x28, 0x28, 0x24, 0xAF,
+-0x81, 0x1E, 0x57, 0xE9,
++	0x28, 0x28, 0x24, 0xAF,
++	0x81, 0x1E, 0x57, 0xE9,
+ 
+-0x05, 0x47, 0x57, 0xBF,
+-0x0D, 0x47, 0x4F, 0xBF,
++	0x05, 0x47, 0x57, 0xBF,
++	0x0D, 0x47, 0x4F, 0xBF,
+ 
+-0x88, 0x80, 0x58, 0xE9,
+-0x1B, 0x29, 0x1B, 0xDF,
++	0x88, 0x80, 0x58, 0xE9,
++	0x1B, 0x29, 0x1B, 0xDF,
+ 
+-0x30, 0x1D, 0x6F, 0x8F,
+-0x3A, 0x30, 0x4F, 0xE9,
++	0x30, 0x1D, 0x6F, 0x8F,
++	0x3A, 0x30, 0x4F, 0xE9,
+ 
+-0x1C, 0x30, 0x26, 0xDF,
+-0x09, 0xE3,
+-0x3B, 0x05,
++	0x1C, 0x30, 0x26, 0xDF,
++	0x09, 0xE3,
++	0x3B, 0x05,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x3B, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x3B, 0x3F, 0x4F, 0xE9,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x00, 0xE0,
+-0xAC, 0x20,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x00, 0xE0,
++	0xAC, 0x20,
+ 
+-0x2D, 0x44, 0x4C, 0xB4,
+-0x2C, 0x1C, 0xC0, 0xAF,
++	0x2D, 0x44, 0x4C, 0xB4,
++	0x2C, 0x1C, 0xC0, 0xAF,
+ 
+-0x25, 0x44, 0x54, 0xB4,
+-0x00, 0xE0,
+-0xC8, 0x30,
++	0x25, 0x44, 0x54, 0xB4,
++	0x00, 0xE0,
++	0xC8, 0x30,
+ 
+-0x30, 0x46, 0x30, 0xAF,
+-0x1B, 0x1B, 0x48, 0xAF,
++	0x30, 0x46, 0x30, 0xAF,
++	0x1B, 0x1B, 0x48, 0xAF,
+ 
+-0x00, 0xE0,
+-0x25, 0x20,
+-0x38, 0x2C, 0x4F, 0xE9,
++	0x00, 0xE0,
++	0x25, 0x20,
++	0x38, 0x2C, 0x4F, 0xE9,
+ 
+-0x86, 0x80, 0x57, 0xE9,
+-0x38, 0x1D, 0x6F, 0x8F,
++	0x86, 0x80, 0x57, 0xE9,
++	0x38, 0x1D, 0x6F, 0x8F,
+ 
+-0x28, 0x74,
+-0x00, 0xE0,
+-0x0D, 0x44, 0x4C, 0xB0,
++	0x28, 0x74,
++	0x00, 0xE0,
++	0x0D, 0x44, 0x4C, 0xB0,
+ 
+-0x05, 0x44, 0x54, 0xB0,
+-0x2D, 0x20,
+-0x9B, 0x10,
++	0x05, 0x44, 0x54, 0xB0,
++	0x2D, 0x20,
++	0x9B, 0x10,
+ 
+-0x82, 0x3E, 0x57, 0xE9,
+-0x32, 0xF0, 0x1B, 0xCD,
++	0x82, 0x3E, 0x57, 0xE9,
++	0x32, 0xF0, 0x1B, 0xCD,
+ 
+-0x1E, 0xBD, 0x59, 0x9F,
+-0x83, 0x1E, 0x57, 0xE9,
++	0x1E, 0xBD, 0x59, 0x9F,
++	0x83, 0x1E, 0x57, 0xE9,
+ 
+-0x38, 0x47, 0x38, 0xAF,
+-0x34, 0x20,
+-0x2A, 0x30,
++	0x38, 0x47, 0x38, 0xAF,
++	0x34, 0x20,
++	0x2A, 0x30,
+ 
+-0x00, 0xE0,
+-0x0D, 0x20,
+-0x32, 0x20,
+-0x05, 0x20,
++	0x00, 0xE0,
++	0x0D, 0x20,
++	0x32, 0x20,
++	0x05, 0x20,
+ 
+-0x87, 0x80, 0x57, 0xE9,
+-0x1F, 0x54, 0x57, 0x9F,
++	0x87, 0x80, 0x57, 0xE9,
++	0x1F, 0x54, 0x57, 0x9F,
+ 
+-0x17, 0x42, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x6A,
++	0x17, 0x42, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x6A,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x37, 0x1E, 0x4F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x37, 0x1E, 0x4F, 0xE9,
+ 
+-0x37, 0x32, 0x2A, 0xAF,
+-0x00, 0xE0,
+-0x32, 0x00,
++	0x37, 0x32, 0x2A, 0xAF,
++	0x00, 0xE0,
++	0x32, 0x00,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x27, 0xC0, 0x44, 0xC0,
++	0x00, 0x80, 0x00, 0xE8,
++	0x27, 0xC0, 0x44, 0xC0,
+ 
+-0x36, 0x1F, 0x4F, 0xE9,
+-0x1F, 0x1F, 0x26, 0xDF,
++	0x36, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x1F, 0x26, 0xDF,
+ 
+-0x37, 0x1B, 0x37, 0xBF,
+-0x17, 0x26, 0x17, 0xDF,
++	0x37, 0x1B, 0x37, 0xBF,
++	0x17, 0x26, 0x17, 0xDF,
+ 
+-0x3E, 0x17, 0x4F, 0xE9,
+-0x3F, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x17, 0x4F, 0xE9,
++	0x3F, 0x3F, 0x4F, 0xE9,
+ 
+-0x34, 0x1F, 0x34, 0xAF,
+-0x2B, 0x05,
+-0xA7, 0x20,
++	0x34, 0x1F, 0x34, 0xAF,
++	0x2B, 0x05,
++	0xA7, 0x20,
+ 
+-0x33, 0x2B, 0x37, 0xDF,
+-0x27, 0x17, 0xC0, 0xAF,
++	0x33, 0x2B, 0x37, 0xDF,
++	0x27, 0x17, 0xC0, 0xAF,
+ 
+-0x34, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x34, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x2D, 0x21, 0x1A, 0xB0,
+-0x25, 0x21, 0x31, 0xB0,
++	0x2D, 0x21, 0x1A, 0xB0,
++	0x25, 0x21, 0x31, 0xB0,
+ 
+-0x0D, 0x21, 0x1A, 0xB2,
+-0x05, 0x21, 0x31, 0xB2,
++	0x0D, 0x21, 0x1A, 0xB2,
++	0x05, 0x21, 0x31, 0xB2,
+ 
+-0x03, 0x80, 0x2A, 0xEA,
+-0x17, 0xC1, 0x2B, 0xBD,
++	0x03, 0x80, 0x2A, 0xEA,
++	0x17, 0xC1, 0x2B, 0xBD,
+ 
+-0x2D, 0x20,
+-0x25, 0x20,
+-0x05, 0x20,
+-0x0D, 0x20,
++	0x2D, 0x20,
++	0x25, 0x20,
++	0x05, 0x20,
++	0x0D, 0x20,
+ 
+-0xB3, 0x68,
+-0x97, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x68,
++	0x97, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0xC0, 0x33, 0xAF,
+-0x2F, 0xC0, 0x21, 0xC0,
++	0x33, 0xC0, 0x33, 0xAF,
++	0x2F, 0xC0, 0x21, 0xC0,
+ 
+-0x16, 0x42, 0x56, 0x9F,
+-0x3C, 0x27, 0x4F, 0xE9,
++	0x16, 0x42, 0x56, 0x9F,
++	0x3C, 0x27, 0x4F, 0xE9,
+ 
+-0x1E, 0x62, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0x62, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x21, 0x31, 0xB4,
+-0x2D, 0x21, 0x1A, 0xB4,
++	0x25, 0x21, 0x31, 0xB4,
++	0x2D, 0x21, 0x1A, 0xB4,
+ 
+-0x3F, 0x2F, 0x5D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0x2F, 0x5D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0x05,
+-0x00, 0xE0,
+-0x28, 0x19, 0x60, 0xEC,
++	0x33, 0x05,
++	0x00, 0xE0,
++	0x28, 0x19, 0x60, 0xEC,
+ 
+-0x37, 0x0F, 0x5C, 0x9F,
+-0x00, 0xE0,
+-0x2F, 0x20,
++	0x37, 0x0F, 0x5C, 0x9F,
++	0x00, 0xE0,
++	0x2F, 0x20,
+ 
+-0x23, 0x3B, 0x33, 0xAD,
+-0x1E, 0x26, 0x1E, 0xDF,
++	0x23, 0x3B, 0x33, 0xAD,
++	0x1E, 0x26, 0x1E, 0xDF,
+ 
+-0xA7, 0x1E, 0x4F, 0xE9,
+-0x17, 0x26, 0x16, 0xDF,
++	0xA7, 0x1E, 0x4F, 0xE9,
++	0x17, 0x26, 0x16, 0xDF,
+ 
+-0x2D, 0x20,
+-0x00, 0xE0,
+-0xA8, 0x3F, 0x4F, 0xE9,
++	0x2D, 0x20,
++	0x00, 0xE0,
++	0xA8, 0x3F, 0x4F, 0xE9,
+ 
+-0x2F, 0x2F, 0x1E, 0xAF,
+-0x25, 0x20,
+-0x00, 0xE0,
++	0x2F, 0x2F, 0x1E, 0xAF,
++	0x25, 0x20,
++	0x00, 0xE0,
+ 
+-0xA4, 0x16, 0x4F, 0xE9,
+-0x0F, 0xC0, 0x21, 0xC2,
++	0xA4, 0x16, 0x4F, 0xE9,
++	0x0F, 0xC0, 0x21, 0xC2,
+ 
+-0xA6, 0x80, 0x4F, 0xE9,
+-0x1F, 0x62, 0x57, 0x9F,
++	0xA6, 0x80, 0x4F, 0xE9,
++	0x1F, 0x62, 0x57, 0x9F,
+ 
+-0x3F, 0x2F, 0x5D, 0x9F,
+-0x00, 0xE0,
+-0x8F, 0x20,
++	0x3F, 0x2F, 0x5D, 0x9F,
++	0x00, 0xE0,
++	0x8F, 0x20,
+ 
+-0xA5, 0x37, 0x4F, 0xE9,
+-0x0F, 0x17, 0x0F, 0xAF,
++	0xA5, 0x37, 0x4F, 0xE9,
++	0x0F, 0x17, 0x0F, 0xAF,
+ 
+-0x06, 0xC0, 0x21, 0xC4,
+-0x00, 0x80, 0x00, 0xE8,
++	0x06, 0xC0, 0x21, 0xC4,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0xA3, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0xA3, 0x80, 0x4F, 0xE9,
+ 
+-0x06, 0x20,
+-0x00, 0xE0,
+-0x1F, 0x26, 0x1F, 0xDF,
++	0x06, 0x20,
++	0x00, 0xE0,
++	0x1F, 0x26, 0x1F, 0xDF,
+ 
+-0xA1, 0x1F, 0x4F, 0xE9,
+-0xA2, 0x3F, 0x4F, 0xE9,
++	0xA1, 0x1F, 0x4F, 0xE9,
++	0xA2, 0x3F, 0x4F, 0xE9,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x06, 0x06, 0x1F, 0xAF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x06, 0x06, 0x1F, 0xAF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x57, 0x39, 0x20, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x57, 0x39, 0x20, 0xE9,
+ 
+-0x16, 0x28, 0x20, 0xE9,
+-0x1D, 0x3B, 0x20, 0xE9,
++	0x16, 0x28, 0x20, 0xE9,
++	0x1D, 0x3B, 0x20, 0xE9,
+ 
+-0x1E, 0x2B, 0x20, 0xE9,
+-0x2B, 0x32, 0x20, 0xE9,
++	0x1E, 0x2B, 0x20, 0xE9,
++	0x2B, 0x32, 0x20, 0xE9,
+ 
+-0x1C, 0x23, 0x20, 0xE9,
+-0x57, 0x36, 0x20, 0xE9,
++	0x1C, 0x23, 0x20, 0xE9,
++	0x57, 0x36, 0x20, 0xE9,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x90, 0xE2,
+-0x00, 0xE0,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x90, 0xE2,
++	0x00, 0xE0,
+ 
+-0x6C, 0xFF, 0x20, 0xEA,
+-0x19, 0xC8, 0xC1, 0xCD,
++	0x6C, 0xFF, 0x20, 0xEA,
++	0x19, 0xC8, 0xC1, 0xCD,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x9F, 0x41, 0x49, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9F, 0x41, 0x49, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x41, 0x49, 0xBD,
+-0x2D, 0x41, 0x51, 0xBD,
++	0x25, 0x41, 0x49, 0xBD,
++	0x2D, 0x41, 0x51, 0xBD,
+ 
+-0x0D, 0x80, 0x07, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x0D, 0x80, 0x07, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x35, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0x35, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x25, 0x30,
+-0x2D, 0x30,
++	0x00, 0x80, 0x00, 0xE8,
++	0x25, 0x30,
++	0x2D, 0x30,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0xA7, 0x5B, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0xA7, 0x5B, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6B, 0xFF, 0x0A, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x6B, 0xFF, 0x0A, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC9, 0x41, 0xC8, 0xEC,
+-0x42, 0xE1,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC8, 0xEC,
++	0x42, 0xE1,
++	0x00, 0xE0,
+ 
+-0x69, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x69, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC8, 0x40, 0xC0, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC8, 0x40, 0xC0, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x66, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x66, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+ };
+ 
+ static unsigned char warp_g200_tgzsa[] = {
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x98, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x98, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x81, 0x04,
+-0x89, 0x04,
+-0x01, 0x04,
+-0x09, 0x04,
++	0x81, 0x04,
++	0x89, 0x04,
++	0x01, 0x04,
++	0x09, 0x04,
+ 
+-0xC9, 0x41, 0xC0, 0xEC,
+-0x11, 0x04,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC0, 0xEC,
++	0x11, 0x04,
++	0x00, 0xE0,
+ 
+-0x41, 0xCC, 0x41, 0xCD,
+-0x49, 0xCC, 0x49, 0xCD,
++	0x41, 0xCC, 0x41, 0xCD,
++	0x49, 0xCC, 0x49, 0xCD,
+ 
+-0xD1, 0x41, 0xC0, 0xEC,
+-0x51, 0xCC, 0x51, 0xCD,
++	0xD1, 0x41, 0xC0, 0xEC,
++	0x51, 0xCC, 0x51, 0xCD,
+ 
+-0x80, 0x04,
+-0x10, 0x04,
+-0x08, 0x04,
+-0x00, 0xE0,
++	0x80, 0x04,
++	0x10, 0x04,
++	0x08, 0x04,
++	0x00, 0xE0,
+ 
+-0x00, 0xCC, 0xC0, 0xCD,
+-0xD1, 0x49, 0xC0, 0xEC,
++	0x00, 0xCC, 0xC0, 0xCD,
++	0xD1, 0x49, 0xC0, 0xEC,
+ 
+-0x8A, 0x1F, 0x20, 0xE9,
+-0x8B, 0x3F, 0x20, 0xE9,
++	0x8A, 0x1F, 0x20, 0xE9,
++	0x8B, 0x3F, 0x20, 0xE9,
+ 
+-0x41, 0x3C, 0x41, 0xAD,
+-0x49, 0x3C, 0x49, 0xAD,
++	0x41, 0x3C, 0x41, 0xAD,
++	0x49, 0x3C, 0x49, 0xAD,
+ 
+-0x10, 0xCC, 0x10, 0xCD,
+-0x08, 0xCC, 0x08, 0xCD,
++	0x10, 0xCC, 0x10, 0xCD,
++	0x08, 0xCC, 0x08, 0xCD,
+ 
+-0xB9, 0x41, 0x49, 0xBB,
+-0x1F, 0xF0, 0x41, 0xCD,
++	0xB9, 0x41, 0x49, 0xBB,
++	0x1F, 0xF0, 0x41, 0xCD,
+ 
+-0x51, 0x3C, 0x51, 0xAD,
+-0x00, 0x98, 0x80, 0xE9,
++	0x51, 0x3C, 0x51, 0xAD,
++	0x00, 0x98, 0x80, 0xE9,
+ 
+-0x8F, 0x80, 0x07, 0xEA,
+-0x24, 0x1F, 0x20, 0xE9,
++	0x8F, 0x80, 0x07, 0xEA,
++	0x24, 0x1F, 0x20, 0xE9,
+ 
+-0x21, 0x45, 0x80, 0xE8,
+-0x1A, 0x4D, 0x80, 0xE8,
++	0x21, 0x45, 0x80, 0xE8,
++	0x1A, 0x4D, 0x80, 0xE8,
+ 
+-0x31, 0x55, 0x80, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x55, 0x80, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0x41, 0x49, 0xBD,
+-0x1D, 0x41, 0x51, 0xBD,
++	0x15, 0x41, 0x49, 0xBD,
++	0x1D, 0x41, 0x51, 0xBD,
+ 
+-0x2E, 0x41, 0x2A, 0xB8,
+-0x34, 0x53, 0xA0, 0xE8,
++	0x2E, 0x41, 0x2A, 0xB8,
++	0x34, 0x53, 0xA0, 0xE8,
+ 
+-0x15, 0x30,
+-0x1D, 0x30,
+-0x58, 0xE3,
+-0x00, 0xE0,
++	0x15, 0x30,
++	0x1D, 0x30,
++	0x58, 0xE3,
++	0x00, 0xE0,
+ 
+-0xB5, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0xB5, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x24, 0x43, 0xA0, 0xE8,
+-0x2C, 0x4B, 0xA0, 0xE8,
++	0x24, 0x43, 0xA0, 0xE8,
++	0x2C, 0x4B, 0xA0, 0xE8,
+ 
+-0x15, 0x72,
+-0x09, 0xE3,
+-0x00, 0xE0,
+-0x1D, 0x72,
++	0x15, 0x72,
++	0x09, 0xE3,
++	0x00, 0xE0,
++	0x1D, 0x72,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0x97, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x97, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6C, 0x64, 0xC8, 0xEC,
+-0x98, 0xE1,
+-0xB5, 0x05,
++	0x6C, 0x64, 0xC8, 0xEC,
++	0x98, 0xE1,
++	0xB5, 0x05,
+ 
+-0xBD, 0x05,
+-0x2E, 0x30,
+-0x32, 0xC0, 0xA0, 0xE8,
++	0xBD, 0x05,
++	0x2E, 0x30,
++	0x32, 0xC0, 0xA0, 0xE8,
+ 
+-0x33, 0xC0, 0xA0, 0xE8,
+-0x74, 0x64, 0xC8, 0xEC,
++	0x33, 0xC0, 0xA0, 0xE8,
++	0x74, 0x64, 0xC8, 0xEC,
+ 
+-0x40, 0x3C, 0x40, 0xAD,
+-0x32, 0x6A,
+-0x2A, 0x30,
++	0x40, 0x3C, 0x40, 0xAD,
++	0x32, 0x6A,
++	0x2A, 0x30,
+ 
+-0x20, 0x73,
+-0x33, 0x6A,
+-0x00, 0xE0,
+-0x28, 0x73,
++	0x20, 0x73,
++	0x33, 0x6A,
++	0x00, 0xE0,
++	0x28, 0x73,
+ 
+-0x1C, 0x72,
+-0x83, 0xE2,
+-0x7B, 0x80, 0x15, 0xEA,
++	0x1C, 0x72,
++	0x83, 0xE2,
++	0x7B, 0x80, 0x15, 0xEA,
+ 
+-0xB8, 0x3D, 0x28, 0xDF,
+-0x30, 0x35, 0x20, 0xDF,
++	0xB8, 0x3D, 0x28, 0xDF,
++	0x30, 0x35, 0x20, 0xDF,
+ 
+-0x40, 0x30,
+-0x00, 0xE0,
+-0xCC, 0xE2,
+-0x64, 0x72,
++	0x40, 0x30,
++	0x00, 0xE0,
++	0xCC, 0xE2,
++	0x64, 0x72,
+ 
+-0x25, 0x42, 0x52, 0xBF,
+-0x2D, 0x42, 0x4A, 0xBF,
++	0x25, 0x42, 0x52, 0xBF,
++	0x2D, 0x42, 0x4A, 0xBF,
+ 
+-0x30, 0x2E, 0x30, 0xDF,
+-0x38, 0x2E, 0x38, 0xDF,
++	0x30, 0x2E, 0x30, 0xDF,
++	0x38, 0x2E, 0x38, 0xDF,
+ 
+-0x18, 0x1D, 0x45, 0xE9,
+-0x1E, 0x15, 0x45, 0xE9,
++	0x18, 0x1D, 0x45, 0xE9,
++	0x1E, 0x15, 0x45, 0xE9,
+ 
+-0x2B, 0x49, 0x51, 0xBD,
+-0x00, 0xE0,
+-0x1F, 0x73,
++	0x2B, 0x49, 0x51, 0xBD,
++	0x00, 0xE0,
++	0x1F, 0x73,
+ 
+-0x38, 0x38, 0x40, 0xAF,
+-0x30, 0x30, 0x40, 0xAF,
++	0x38, 0x38, 0x40, 0xAF,
++	0x30, 0x30, 0x40, 0xAF,
+ 
+-0x24, 0x1F, 0x24, 0xDF,
+-0x1D, 0x32, 0x20, 0xE9,
++	0x24, 0x1F, 0x24, 0xDF,
++	0x1D, 0x32, 0x20, 0xE9,
+ 
+-0x2C, 0x1F, 0x2C, 0xDF,
+-0x1A, 0x33, 0x20, 0xE9,
++	0x2C, 0x1F, 0x2C, 0xDF,
++	0x1A, 0x33, 0x20, 0xE9,
+ 
+-0xB0, 0x10,
+-0x08, 0xE3,
+-0x40, 0x10,
+-0xB8, 0x10,
++	0xB0, 0x10,
++	0x08, 0xE3,
++	0x40, 0x10,
++	0xB8, 0x10,
+ 
+-0x26, 0xF0, 0x30, 0xCD,
+-0x2F, 0xF0, 0x38, 0xCD,
++	0x26, 0xF0, 0x30, 0xCD,
++	0x2F, 0xF0, 0x38, 0xCD,
+ 
+-0x2B, 0x80, 0x20, 0xE9,
+-0x2A, 0x80, 0x20, 0xE9,
++	0x2B, 0x80, 0x20, 0xE9,
++	0x2A, 0x80, 0x20, 0xE9,
+ 
+-0xA6, 0x20,
+-0x88, 0xE2,
+-0x00, 0xE0,
+-0xAF, 0x20,
++	0xA6, 0x20,
++	0x88, 0xE2,
++	0x00, 0xE0,
++	0xAF, 0x20,
+ 
+-0x28, 0x2A, 0x26, 0xAF,
+-0x20, 0x2A, 0xC0, 0xAF,
++	0x28, 0x2A, 0x26, 0xAF,
++	0x20, 0x2A, 0xC0, 0xAF,
+ 
+-0x34, 0x1F, 0x34, 0xDF,
+-0x46, 0x24, 0x46, 0xDF,
++	0x34, 0x1F, 0x34, 0xDF,
++	0x46, 0x24, 0x46, 0xDF,
+ 
+-0x28, 0x30, 0x80, 0xBF,
+-0x20, 0x38, 0x80, 0xBF,
++	0x28, 0x30, 0x80, 0xBF,
++	0x20, 0x38, 0x80, 0xBF,
+ 
+-0x47, 0x24, 0x47, 0xDF,
+-0x4E, 0x2C, 0x4E, 0xDF,
++	0x47, 0x24, 0x47, 0xDF,
++	0x4E, 0x2C, 0x4E, 0xDF,
+ 
+-0x4F, 0x2C, 0x4F, 0xDF,
+-0x56, 0x34, 0x56, 0xDF,
++	0x4F, 0x2C, 0x4F, 0xDF,
++	0x56, 0x34, 0x56, 0xDF,
+ 
+-0x28, 0x15, 0x28, 0xDF,
+-0x20, 0x1D, 0x20, 0xDF,
++	0x28, 0x15, 0x28, 0xDF,
++	0x20, 0x1D, 0x20, 0xDF,
+ 
+-0x57, 0x34, 0x57, 0xDF,
+-0x00, 0xE0,
+-0x1D, 0x05,
++	0x57, 0x34, 0x57, 0xDF,
++	0x00, 0xE0,
++	0x1D, 0x05,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x89, 0xE2,
+-0x2B, 0x30,
++	0x04, 0x80, 0x10, 0xEA,
++	0x89, 0xE2,
++	0x2B, 0x30,
+ 
+-0x3F, 0xC1, 0x1D, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0xC1, 0x1D, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x68,
+-0xBF, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x68,
++	0xBF, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x20, 0xC0, 0x20, 0xAF,
+-0x28, 0x05,
+-0x97, 0x74,
++	0x20, 0xC0, 0x20, 0xAF,
++	0x28, 0x05,
++	0x97, 0x74,
+ 
+-0x00, 0xE0,
+-0x2A, 0x10,
+-0x16, 0xC0, 0x20, 0xE9,
++	0x00, 0xE0,
++	0x2A, 0x10,
++	0x16, 0xC0, 0x20, 0xE9,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x8C, 0xE2,
+-0x95, 0x05,
++	0x04, 0x80, 0x10, 0xEA,
++	0x8C, 0xE2,
++	0x95, 0x05,
+ 
+-0x28, 0xC1, 0x28, 0xAD,
+-0x1F, 0xC1, 0x15, 0xBD,
++	0x28, 0xC1, 0x28, 0xAD,
++	0x1F, 0xC1, 0x15, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA8, 0x67,
+-0x9F, 0x6B,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA8, 0x67,
++	0x9F, 0x6B,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x28, 0xC0, 0x28, 0xAD,
+-0x1D, 0x25,
+-0x20, 0x05,
++	0x28, 0xC0, 0x28, 0xAD,
++	0x1D, 0x25,
++	0x20, 0x05,
+ 
+-0x28, 0x32, 0x80, 0xAD,
+-0x40, 0x2A, 0x40, 0xBD,
++	0x28, 0x32, 0x80, 0xAD,
++	0x40, 0x2A, 0x40, 0xBD,
+ 
+-0x1C, 0x80, 0x20, 0xE9,
+-0x20, 0x33, 0x20, 0xAD,
++	0x1C, 0x80, 0x20, 0xE9,
++	0x20, 0x33, 0x20, 0xAD,
+ 
+-0x20, 0x73,
+-0x00, 0xE0,
+-0xB6, 0x49, 0x51, 0xBB,
++	0x20, 0x73,
++	0x00, 0xE0,
++	0xB6, 0x49, 0x51, 0xBB,
+ 
+-0x26, 0x2F, 0xB0, 0xE8,
+-0x19, 0x20, 0x20, 0xE9,
++	0x26, 0x2F, 0xB0, 0xE8,
++	0x19, 0x20, 0x20, 0xE9,
+ 
+-0x35, 0x20, 0x35, 0xDF,
+-0x3D, 0x20, 0x3D, 0xDF,
++	0x35, 0x20, 0x35, 0xDF,
++	0x3D, 0x20, 0x3D, 0xDF,
+ 
+-0x15, 0x20, 0x15, 0xDF,
+-0x1D, 0x20, 0x1D, 0xDF,
++	0x15, 0x20, 0x15, 0xDF,
++	0x1D, 0x20, 0x1D, 0xDF,
+ 
+-0x26, 0xD0, 0x26, 0xCD,
+-0x29, 0x49, 0x2A, 0xB8,
++	0x26, 0xD0, 0x26, 0xCD,
++	0x29, 0x49, 0x2A, 0xB8,
+ 
+-0x26, 0x40, 0x80, 0xBD,
+-0x3B, 0x48, 0x50, 0xBD,
++	0x26, 0x40, 0x80, 0xBD,
++	0x3B, 0x48, 0x50, 0xBD,
+ 
+-0x3E, 0x54, 0x57, 0x9F,
+-0x00, 0xE0,
+-0x82, 0xE1,
++	0x3E, 0x54, 0x57, 0x9F,
++	0x00, 0xE0,
++	0x82, 0xE1,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x26, 0x30,
+-0x29, 0x30,
+-0x48, 0x3C, 0x48, 0xAD,
++	0x26, 0x30,
++	0x29, 0x30,
++	0x48, 0x3C, 0x48, 0xAD,
+ 
+-0x2B, 0x72,
+-0xC2, 0xE1,
+-0x2C, 0xC0, 0x44, 0xC2,
++	0x2B, 0x72,
++	0xC2, 0xE1,
++	0x2C, 0xC0, 0x44, 0xC2,
+ 
+-0x05, 0x24, 0x34, 0xBF,
+-0x0D, 0x24, 0x2C, 0xBF,
++	0x05, 0x24, 0x34, 0xBF,
++	0x0D, 0x24, 0x2C, 0xBF,
+ 
+-0x2D, 0x46, 0x4E, 0xBF,
+-0x25, 0x46, 0x56, 0xBF,
++	0x2D, 0x46, 0x4E, 0xBF,
++	0x25, 0x46, 0x56, 0xBF,
+ 
+-0x20, 0x1D, 0x6F, 0x8F,
+-0x32, 0x3E, 0x5F, 0xE9,
++	0x20, 0x1D, 0x6F, 0x8F,
++	0x32, 0x3E, 0x5F, 0xE9,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x30,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x30,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x33, 0x1E, 0x5F, 0xE9,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x33, 0x1E, 0x5F, 0xE9,
+ 
+-0x05, 0x44, 0x54, 0xB2,
+-0x0D, 0x44, 0x4C, 0xB2,
++	0x05, 0x44, 0x54, 0xB2,
++	0x0D, 0x44, 0x4C, 0xB2,
+ 
+-0x19, 0xC0, 0xB0, 0xE8,
+-0x34, 0xC0, 0x44, 0xC4,
++	0x19, 0xC0, 0xB0, 0xE8,
++	0x34, 0xC0, 0x44, 0xC4,
+ 
+-0x33, 0x73,
+-0x00, 0xE0,
+-0x3E, 0x62, 0x57, 0x9F,
++	0x33, 0x73,
++	0x00, 0xE0,
++	0x3E, 0x62, 0x57, 0x9F,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0xE0,
+-0x0D, 0x20,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0xE0,
++	0x0D, 0x20,
+ 
+-0x84, 0x3E, 0x58, 0xE9,
+-0x28, 0x1D, 0x6F, 0x8F,
++	0x84, 0x3E, 0x58, 0xE9,
++	0x28, 0x1D, 0x6F, 0x8F,
+ 
+-0x05, 0x20,
+-0x00, 0xE0,
+-0x85, 0x1E, 0x58, 0xE9,
++	0x05, 0x20,
++	0x00, 0xE0,
++	0x85, 0x1E, 0x58, 0xE9,
+ 
+-0x9B, 0x3B, 0x33, 0xDF,
+-0x20, 0x20, 0x42, 0xAF,
++	0x9B, 0x3B, 0x33, 0xDF,
++	0x20, 0x20, 0x42, 0xAF,
+ 
+-0x30, 0x42, 0x56, 0x9F,
+-0x80, 0x3E, 0x57, 0xE9,
++	0x30, 0x42, 0x56, 0x9F,
++	0x80, 0x3E, 0x57, 0xE9,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x30, 0x80, 0x5F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x30, 0x80, 0x5F, 0xE9,
+ 
+-0x28, 0x28, 0x24, 0xAF,
+-0x81, 0x1E, 0x57, 0xE9,
++	0x28, 0x28, 0x24, 0xAF,
++	0x81, 0x1E, 0x57, 0xE9,
+ 
+-0x05, 0x47, 0x57, 0xBF,
+-0x0D, 0x47, 0x4F, 0xBF,
++	0x05, 0x47, 0x57, 0xBF,
++	0x0D, 0x47, 0x4F, 0xBF,
+ 
+-0x88, 0x80, 0x58, 0xE9,
+-0x1B, 0x29, 0x1B, 0xDF,
++	0x88, 0x80, 0x58, 0xE9,
++	0x1B, 0x29, 0x1B, 0xDF,
+ 
+-0x30, 0x1D, 0x6F, 0x8F,
+-0x3A, 0x30, 0x4F, 0xE9,
++	0x30, 0x1D, 0x6F, 0x8F,
++	0x3A, 0x30, 0x4F, 0xE9,
+ 
+-0x1C, 0x30, 0x26, 0xDF,
+-0x09, 0xE3,
+-0x3B, 0x05,
++	0x1C, 0x30, 0x26, 0xDF,
++	0x09, 0xE3,
++	0x3B, 0x05,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x3B, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x3B, 0x3F, 0x4F, 0xE9,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x00, 0xE0,
+-0xAC, 0x20,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x00, 0xE0,
++	0xAC, 0x20,
+ 
+-0x2D, 0x44, 0x4C, 0xB4,
+-0x2C, 0x1C, 0xC0, 0xAF,
++	0x2D, 0x44, 0x4C, 0xB4,
++	0x2C, 0x1C, 0xC0, 0xAF,
+ 
+-0x25, 0x44, 0x54, 0xB4,
+-0x00, 0xE0,
+-0xC8, 0x30,
++	0x25, 0x44, 0x54, 0xB4,
++	0x00, 0xE0,
++	0xC8, 0x30,
+ 
+-0x30, 0x46, 0x30, 0xAF,
+-0x1B, 0x1B, 0x48, 0xAF,
++	0x30, 0x46, 0x30, 0xAF,
++	0x1B, 0x1B, 0x48, 0xAF,
+ 
+-0x00, 0xE0,
+-0x25, 0x20,
+-0x38, 0x2C, 0x4F, 0xE9,
++	0x00, 0xE0,
++	0x25, 0x20,
++	0x38, 0x2C, 0x4F, 0xE9,
+ 
+-0x86, 0x80, 0x57, 0xE9,
+-0x38, 0x1D, 0x6F, 0x8F,
++	0x86, 0x80, 0x57, 0xE9,
++	0x38, 0x1D, 0x6F, 0x8F,
+ 
+-0x28, 0x74,
+-0x00, 0xE0,
+-0x0D, 0x44, 0x4C, 0xB0,
++	0x28, 0x74,
++	0x00, 0xE0,
++	0x0D, 0x44, 0x4C, 0xB0,
+ 
+-0x05, 0x44, 0x54, 0xB0,
+-0x2D, 0x20,
+-0x9B, 0x10,
++	0x05, 0x44, 0x54, 0xB0,
++	0x2D, 0x20,
++	0x9B, 0x10,
+ 
+-0x82, 0x3E, 0x57, 0xE9,
+-0x32, 0xF0, 0x1B, 0xCD,
++	0x82, 0x3E, 0x57, 0xE9,
++	0x32, 0xF0, 0x1B, 0xCD,
+ 
+-0x1E, 0xBD, 0x59, 0x9F,
+-0x83, 0x1E, 0x57, 0xE9,
++	0x1E, 0xBD, 0x59, 0x9F,
++	0x83, 0x1E, 0x57, 0xE9,
+ 
+-0x38, 0x47, 0x38, 0xAF,
+-0x34, 0x20,
+-0x2A, 0x30,
++	0x38, 0x47, 0x38, 0xAF,
++	0x34, 0x20,
++	0x2A, 0x30,
+ 
+-0x00, 0xE0,
+-0x0D, 0x20,
+-0x32, 0x20,
+-0x05, 0x20,
++	0x00, 0xE0,
++	0x0D, 0x20,
++	0x32, 0x20,
++	0x05, 0x20,
+ 
+-0x87, 0x80, 0x57, 0xE9,
+-0x1F, 0x54, 0x57, 0x9F,
++	0x87, 0x80, 0x57, 0xE9,
++	0x1F, 0x54, 0x57, 0x9F,
+ 
+-0x17, 0x42, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x6A,
++	0x17, 0x42, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x6A,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x37, 0x1E, 0x4F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x37, 0x1E, 0x4F, 0xE9,
+ 
+-0x37, 0x32, 0x2A, 0xAF,
+-0x00, 0xE0,
+-0x32, 0x00,
++	0x37, 0x32, 0x2A, 0xAF,
++	0x00, 0xE0,
++	0x32, 0x00,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x27, 0xC0, 0x44, 0xC0,
++	0x00, 0x80, 0x00, 0xE8,
++	0x27, 0xC0, 0x44, 0xC0,
+ 
+-0x36, 0x1F, 0x4F, 0xE9,
+-0x1F, 0x1F, 0x26, 0xDF,
++	0x36, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x1F, 0x26, 0xDF,
+ 
+-0x37, 0x1B, 0x37, 0xBF,
+-0x17, 0x26, 0x17, 0xDF,
++	0x37, 0x1B, 0x37, 0xBF,
++	0x17, 0x26, 0x17, 0xDF,
+ 
+-0x3E, 0x17, 0x4F, 0xE9,
+-0x3F, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x17, 0x4F, 0xE9,
++	0x3F, 0x3F, 0x4F, 0xE9,
+ 
+-0x34, 0x1F, 0x34, 0xAF,
+-0x2B, 0x05,
+-0xA7, 0x20,
++	0x34, 0x1F, 0x34, 0xAF,
++	0x2B, 0x05,
++	0xA7, 0x20,
+ 
+-0x33, 0x2B, 0x37, 0xDF,
+-0x27, 0x17, 0xC0, 0xAF,
++	0x33, 0x2B, 0x37, 0xDF,
++	0x27, 0x17, 0xC0, 0xAF,
+ 
+-0x34, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x34, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x2D, 0x21, 0x1A, 0xB0,
+-0x25, 0x21, 0x31, 0xB0,
++	0x2D, 0x21, 0x1A, 0xB0,
++	0x25, 0x21, 0x31, 0xB0,
+ 
+-0x0D, 0x21, 0x1A, 0xB2,
+-0x05, 0x21, 0x31, 0xB2,
++	0x0D, 0x21, 0x1A, 0xB2,
++	0x05, 0x21, 0x31, 0xB2,
+ 
+-0x03, 0x80, 0x2A, 0xEA,
+-0x17, 0xC1, 0x2B, 0xBD,
++	0x03, 0x80, 0x2A, 0xEA,
++	0x17, 0xC1, 0x2B, 0xBD,
+ 
+-0x2D, 0x20,
+-0x25, 0x20,
+-0x05, 0x20,
+-0x0D, 0x20,
++	0x2D, 0x20,
++	0x25, 0x20,
++	0x05, 0x20,
++	0x0D, 0x20,
+ 
+-0xB3, 0x68,
+-0x97, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x68,
++	0x97, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0xC0, 0x33, 0xAF,
+-0x2F, 0xC0, 0x21, 0xC0,
++	0x33, 0xC0, 0x33, 0xAF,
++	0x2F, 0xC0, 0x21, 0xC0,
+ 
+-0x16, 0x42, 0x56, 0x9F,
+-0x3C, 0x27, 0x4F, 0xE9,
++	0x16, 0x42, 0x56, 0x9F,
++	0x3C, 0x27, 0x4F, 0xE9,
+ 
+-0x1E, 0x62, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0x62, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x21, 0x31, 0xB4,
+-0x2D, 0x21, 0x1A, 0xB4,
++	0x25, 0x21, 0x31, 0xB4,
++	0x2D, 0x21, 0x1A, 0xB4,
+ 
+-0x3F, 0x2F, 0x5D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0x2F, 0x5D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0x05,
+-0x00, 0xE0,
+-0x28, 0x19, 0x60, 0xEC,
++	0x33, 0x05,
++	0x00, 0xE0,
++	0x28, 0x19, 0x60, 0xEC,
+ 
+-0x0D, 0x44, 0x4C, 0xB6,
+-0x05, 0x44, 0x54, 0xB6,
++	0x0D, 0x44, 0x4C, 0xB6,
++	0x05, 0x44, 0x54, 0xB6,
+ 
+-0x37, 0x0F, 0x5C, 0x9F,
+-0x00, 0xE0,
+-0x2F, 0x20,
++	0x37, 0x0F, 0x5C, 0x9F,
++	0x00, 0xE0,
++	0x2F, 0x20,
+ 
+-0x23, 0x3B, 0x33, 0xAD,
+-0x1E, 0x26, 0x1E, 0xDF,
++	0x23, 0x3B, 0x33, 0xAD,
++	0x1E, 0x26, 0x1E, 0xDF,
+ 
+-0xA7, 0x1E, 0x4F, 0xE9,
+-0x17, 0x26, 0x16, 0xDF,
++	0xA7, 0x1E, 0x4F, 0xE9,
++	0x17, 0x26, 0x16, 0xDF,
+ 
+-0x2D, 0x20,
+-0x00, 0xE0,
+-0xA8, 0x3F, 0x4F, 0xE9,
++	0x2D, 0x20,
++	0x00, 0xE0,
++	0xA8, 0x3F, 0x4F, 0xE9,
+ 
+-0x2F, 0x2F, 0x1E, 0xAF,
+-0x25, 0x20,
+-0x00, 0xE0,
++	0x2F, 0x2F, 0x1E, 0xAF,
++	0x25, 0x20,
++	0x00, 0xE0,
+ 
+-0xA4, 0x16, 0x4F, 0xE9,
+-0x0F, 0xC0, 0x21, 0xC2,
++	0xA4, 0x16, 0x4F, 0xE9,
++	0x0F, 0xC0, 0x21, 0xC2,
+ 
+-0xA6, 0x80, 0x4F, 0xE9,
+-0x1F, 0x62, 0x57, 0x9F,
++	0xA6, 0x80, 0x4F, 0xE9,
++	0x1F, 0x62, 0x57, 0x9F,
+ 
+-0x0D, 0x20,
+-0x05, 0x20,
+-0x00, 0x80, 0x00, 0xE8,
++	0x0D, 0x20,
++	0x05, 0x20,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x3F, 0x2F, 0x5D, 0x9F,
+-0x00, 0xE0,
+-0x0F, 0x20,
++	0x3F, 0x2F, 0x5D, 0x9F,
++	0x00, 0xE0,
++	0x0F, 0x20,
+ 
+-0x17, 0x50, 0x56, 0x9F,
+-0xA5, 0x37, 0x4F, 0xE9,
++	0x17, 0x50, 0x56, 0x9F,
++	0xA5, 0x37, 0x4F, 0xE9,
+ 
+-0x06, 0xC0, 0x21, 0xC4,
+-0x0F, 0x17, 0x0F, 0xAF,
++	0x06, 0xC0, 0x21, 0xC4,
++	0x0F, 0x17, 0x0F, 0xAF,
+ 
+-0x37, 0x0F, 0x5C, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x37, 0x0F, 0x5C, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x2F, 0xC0, 0x44, 0xC6,
+-0xA3, 0x80, 0x4F, 0xE9,
++	0x2F, 0xC0, 0x44, 0xC6,
++	0xA3, 0x80, 0x4F, 0xE9,
+ 
+-0x06, 0x20,
+-0x00, 0xE0,
+-0x1F, 0x26, 0x1F, 0xDF,
++	0x06, 0x20,
++	0x00, 0xE0,
++	0x1F, 0x26, 0x1F, 0xDF,
+ 
+-0x17, 0x26, 0x17, 0xDF,
+-0x9D, 0x17, 0x4F, 0xE9,
++	0x17, 0x26, 0x17, 0xDF,
++	0x9D, 0x17, 0x4F, 0xE9,
+ 
+-0xA1, 0x1F, 0x4F, 0xE9,
+-0xA2, 0x3F, 0x4F, 0xE9,
++	0xA1, 0x1F, 0x4F, 0xE9,
++	0xA2, 0x3F, 0x4F, 0xE9,
+ 
+-0x06, 0x06, 0x1F, 0xAF,
+-0x00, 0xE0,
+-0xAF, 0x20,
++	0x06, 0x06, 0x1F, 0xAF,
++	0x00, 0xE0,
++	0xAF, 0x20,
+ 
+-0x9E, 0x37, 0x4F, 0xE9,
+-0x2F, 0x17, 0x2F, 0xAF,
++	0x9E, 0x37, 0x4F, 0xE9,
++	0x2F, 0x17, 0x2F, 0xAF,
+ 
+-0xA0, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x9C, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x80, 0x4F, 0xE9,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x57, 0x39, 0x20, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x57, 0x39, 0x20, 0xE9,
+ 
+-0x16, 0x28, 0x20, 0xE9,
+-0x1D, 0x3B, 0x20, 0xE9,
++	0x16, 0x28, 0x20, 0xE9,
++	0x1D, 0x3B, 0x20, 0xE9,
+ 
+-0x1E, 0x2B, 0x20, 0xE9,
+-0x2B, 0x32, 0x20, 0xE9,
++	0x1E, 0x2B, 0x20, 0xE9,
++	0x2B, 0x32, 0x20, 0xE9,
+ 
+-0x1C, 0x23, 0x20, 0xE9,
+-0x57, 0x36, 0x20, 0xE9,
++	0x1C, 0x23, 0x20, 0xE9,
++	0x57, 0x36, 0x20, 0xE9,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x90, 0xE2,
+-0x00, 0xE0,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x90, 0xE2,
++	0x00, 0xE0,
+ 
+-0x68, 0xFF, 0x20, 0xEA,
+-0x19, 0xC8, 0xC1, 0xCD,
++	0x68, 0xFF, 0x20, 0xEA,
++	0x19, 0xC8, 0xC1, 0xCD,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x9F, 0x41, 0x49, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9F, 0x41, 0x49, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x41, 0x49, 0xBD,
+-0x2D, 0x41, 0x51, 0xBD,
++	0x25, 0x41, 0x49, 0xBD,
++	0x2D, 0x41, 0x51, 0xBD,
+ 
+-0x0D, 0x80, 0x07, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x0D, 0x80, 0x07, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x35, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0x35, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x25, 0x30,
+-0x2D, 0x30,
++	0x00, 0x80, 0x00, 0xE8,
++	0x25, 0x30,
++	0x2D, 0x30,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0xA7, 0x5B, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0xA7, 0x5B, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x67, 0xFF, 0x0A, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x67, 0xFF, 0x0A, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC9, 0x41, 0xC8, 0xEC,
+-0x42, 0xE1,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC8, 0xEC,
++	0x42, 0xE1,
++	0x00, 0xE0,
+ 
+-0x65, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x65, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC8, 0x40, 0xC0, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC8, 0x40, 0xC0, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x62, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x62, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+ };
+ 
+ static unsigned char warp_g200_tgzsaf[] = {
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x98, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x98, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x81, 0x04,
+-0x89, 0x04,
+-0x01, 0x04,
+-0x09, 0x04,
++	0x81, 0x04,
++	0x89, 0x04,
++	0x01, 0x04,
++	0x09, 0x04,
+ 
+-0xC9, 0x41, 0xC0, 0xEC,
+-0x11, 0x04,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC0, 0xEC,
++	0x11, 0x04,
++	0x00, 0xE0,
+ 
+-0x41, 0xCC, 0x41, 0xCD,
+-0x49, 0xCC, 0x49, 0xCD,
++	0x41, 0xCC, 0x41, 0xCD,
++	0x49, 0xCC, 0x49, 0xCD,
+ 
+-0xD1, 0x41, 0xC0, 0xEC,
+-0x51, 0xCC, 0x51, 0xCD,
++	0xD1, 0x41, 0xC0, 0xEC,
++	0x51, 0xCC, 0x51, 0xCD,
+ 
+-0x80, 0x04,
+-0x10, 0x04,
+-0x08, 0x04,
+-0x00, 0xE0,
++	0x80, 0x04,
++	0x10, 0x04,
++	0x08, 0x04,
++	0x00, 0xE0,
+ 
+-0x00, 0xCC, 0xC0, 0xCD,
+-0xD1, 0x49, 0xC0, 0xEC,
++	0x00, 0xCC, 0xC0, 0xCD,
++	0xD1, 0x49, 0xC0, 0xEC,
+ 
+-0x8A, 0x1F, 0x20, 0xE9,
+-0x8B, 0x3F, 0x20, 0xE9,
++	0x8A, 0x1F, 0x20, 0xE9,
++	0x8B, 0x3F, 0x20, 0xE9,
+ 
+-0x41, 0x3C, 0x41, 0xAD,
+-0x49, 0x3C, 0x49, 0xAD,
++	0x41, 0x3C, 0x41, 0xAD,
++	0x49, 0x3C, 0x49, 0xAD,
+ 
+-0x10, 0xCC, 0x10, 0xCD,
+-0x08, 0xCC, 0x08, 0xCD,
++	0x10, 0xCC, 0x10, 0xCD,
++	0x08, 0xCC, 0x08, 0xCD,
+ 
+-0xB9, 0x41, 0x49, 0xBB,
+-0x1F, 0xF0, 0x41, 0xCD,
++	0xB9, 0x41, 0x49, 0xBB,
++	0x1F, 0xF0, 0x41, 0xCD,
+ 
+-0x51, 0x3C, 0x51, 0xAD,
+-0x00, 0x98, 0x80, 0xE9,
++	0x51, 0x3C, 0x51, 0xAD,
++	0x00, 0x98, 0x80, 0xE9,
+ 
+-0x94, 0x80, 0x07, 0xEA,
+-0x24, 0x1F, 0x20, 0xE9,
++	0x94, 0x80, 0x07, 0xEA,
++	0x24, 0x1F, 0x20, 0xE9,
+ 
+-0x21, 0x45, 0x80, 0xE8,
+-0x1A, 0x4D, 0x80, 0xE8,
++	0x21, 0x45, 0x80, 0xE8,
++	0x1A, 0x4D, 0x80, 0xE8,
+ 
+-0x31, 0x55, 0x80, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x55, 0x80, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0x41, 0x49, 0xBD,
+-0x1D, 0x41, 0x51, 0xBD,
++	0x15, 0x41, 0x49, 0xBD,
++	0x1D, 0x41, 0x51, 0xBD,
+ 
+-0x2E, 0x41, 0x2A, 0xB8,
+-0x34, 0x53, 0xA0, 0xE8,
++	0x2E, 0x41, 0x2A, 0xB8,
++	0x34, 0x53, 0xA0, 0xE8,
+ 
+-0x15, 0x30,
+-0x1D, 0x30,
+-0x58, 0xE3,
+-0x00, 0xE0,
++	0x15, 0x30,
++	0x1D, 0x30,
++	0x58, 0xE3,
++	0x00, 0xE0,
+ 
+-0xB5, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0xB5, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x24, 0x43, 0xA0, 0xE8,
+-0x2C, 0x4B, 0xA0, 0xE8,
++	0x24, 0x43, 0xA0, 0xE8,
++	0x2C, 0x4B, 0xA0, 0xE8,
+ 
+-0x15, 0x72,
+-0x09, 0xE3,
+-0x00, 0xE0,
+-0x1D, 0x72,
++	0x15, 0x72,
++	0x09, 0xE3,
++	0x00, 0xE0,
++	0x1D, 0x72,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0x97, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x97, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6C, 0x64, 0xC8, 0xEC,
+-0x98, 0xE1,
+-0xB5, 0x05,
++	0x6C, 0x64, 0xC8, 0xEC,
++	0x98, 0xE1,
++	0xB5, 0x05,
+ 
+-0xBD, 0x05,
+-0x2E, 0x30,
+-0x32, 0xC0, 0xA0, 0xE8,
++	0xBD, 0x05,
++	0x2E, 0x30,
++	0x32, 0xC0, 0xA0, 0xE8,
+ 
+-0x33, 0xC0, 0xA0, 0xE8,
+-0x74, 0x64, 0xC8, 0xEC,
++	0x33, 0xC0, 0xA0, 0xE8,
++	0x74, 0x64, 0xC8, 0xEC,
+ 
+-0x40, 0x3C, 0x40, 0xAD,
+-0x32, 0x6A,
+-0x2A, 0x30,
++	0x40, 0x3C, 0x40, 0xAD,
++	0x32, 0x6A,
++	0x2A, 0x30,
+ 
+-0x20, 0x73,
+-0x33, 0x6A,
+-0x00, 0xE0,
+-0x28, 0x73,
++	0x20, 0x73,
++	0x33, 0x6A,
++	0x00, 0xE0,
++	0x28, 0x73,
+ 
+-0x1C, 0x72,
+-0x83, 0xE2,
+-0x80, 0x80, 0x15, 0xEA,
++	0x1C, 0x72,
++	0x83, 0xE2,
++	0x80, 0x80, 0x15, 0xEA,
+ 
+-0xB8, 0x3D, 0x28, 0xDF,
+-0x30, 0x35, 0x20, 0xDF,
++	0xB8, 0x3D, 0x28, 0xDF,
++	0x30, 0x35, 0x20, 0xDF,
+ 
+-0x40, 0x30,
+-0x00, 0xE0,
+-0xCC, 0xE2,
+-0x64, 0x72,
++	0x40, 0x30,
++	0x00, 0xE0,
++	0xCC, 0xE2,
++	0x64, 0x72,
+ 
+-0x25, 0x42, 0x52, 0xBF,
+-0x2D, 0x42, 0x4A, 0xBF,
++	0x25, 0x42, 0x52, 0xBF,
++	0x2D, 0x42, 0x4A, 0xBF,
+ 
+-0x30, 0x2E, 0x30, 0xDF,
+-0x38, 0x2E, 0x38, 0xDF,
++	0x30, 0x2E, 0x30, 0xDF,
++	0x38, 0x2E, 0x38, 0xDF,
+ 
+-0x18, 0x1D, 0x45, 0xE9,
+-0x1E, 0x15, 0x45, 0xE9,
++	0x18, 0x1D, 0x45, 0xE9,
++	0x1E, 0x15, 0x45, 0xE9,
+ 
+-0x2B, 0x49, 0x51, 0xBD,
+-0x00, 0xE0,
+-0x1F, 0x73,
++	0x2B, 0x49, 0x51, 0xBD,
++	0x00, 0xE0,
++	0x1F, 0x73,
+ 
+-0x38, 0x38, 0x40, 0xAF,
+-0x30, 0x30, 0x40, 0xAF,
++	0x38, 0x38, 0x40, 0xAF,
++	0x30, 0x30, 0x40, 0xAF,
+ 
+-0x24, 0x1F, 0x24, 0xDF,
+-0x1D, 0x32, 0x20, 0xE9,
++	0x24, 0x1F, 0x24, 0xDF,
++	0x1D, 0x32, 0x20, 0xE9,
+ 
+-0x2C, 0x1F, 0x2C, 0xDF,
+-0x1A, 0x33, 0x20, 0xE9,
++	0x2C, 0x1F, 0x2C, 0xDF,
++	0x1A, 0x33, 0x20, 0xE9,
+ 
+-0xB0, 0x10,
+-0x08, 0xE3,
+-0x40, 0x10,
+-0xB8, 0x10,
++	0xB0, 0x10,
++	0x08, 0xE3,
++	0x40, 0x10,
++	0xB8, 0x10,
+ 
+-0x26, 0xF0, 0x30, 0xCD,
+-0x2F, 0xF0, 0x38, 0xCD,
++	0x26, 0xF0, 0x30, 0xCD,
++	0x2F, 0xF0, 0x38, 0xCD,
+ 
+-0x2B, 0x80, 0x20, 0xE9,
+-0x2A, 0x80, 0x20, 0xE9,
++	0x2B, 0x80, 0x20, 0xE9,
++	0x2A, 0x80, 0x20, 0xE9,
+ 
+-0xA6, 0x20,
+-0x88, 0xE2,
+-0x00, 0xE0,
+-0xAF, 0x20,
++	0xA6, 0x20,
++	0x88, 0xE2,
++	0x00, 0xE0,
++	0xAF, 0x20,
+ 
+-0x28, 0x2A, 0x26, 0xAF,
+-0x20, 0x2A, 0xC0, 0xAF,
++	0x28, 0x2A, 0x26, 0xAF,
++	0x20, 0x2A, 0xC0, 0xAF,
+ 
+-0x34, 0x1F, 0x34, 0xDF,
+-0x46, 0x24, 0x46, 0xDF,
++	0x34, 0x1F, 0x34, 0xDF,
++	0x46, 0x24, 0x46, 0xDF,
+ 
+-0x28, 0x30, 0x80, 0xBF,
+-0x20, 0x38, 0x80, 0xBF,
++	0x28, 0x30, 0x80, 0xBF,
++	0x20, 0x38, 0x80, 0xBF,
+ 
+-0x47, 0x24, 0x47, 0xDF,
+-0x4E, 0x2C, 0x4E, 0xDF,
++	0x47, 0x24, 0x47, 0xDF,
++	0x4E, 0x2C, 0x4E, 0xDF,
+ 
+-0x4F, 0x2C, 0x4F, 0xDF,
+-0x56, 0x34, 0x56, 0xDF,
++	0x4F, 0x2C, 0x4F, 0xDF,
++	0x56, 0x34, 0x56, 0xDF,
+ 
+-0x28, 0x15, 0x28, 0xDF,
+-0x20, 0x1D, 0x20, 0xDF,
++	0x28, 0x15, 0x28, 0xDF,
++	0x20, 0x1D, 0x20, 0xDF,
+ 
+-0x57, 0x34, 0x57, 0xDF,
+-0x00, 0xE0,
+-0x1D, 0x05,
++	0x57, 0x34, 0x57, 0xDF,
++	0x00, 0xE0,
++	0x1D, 0x05,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x89, 0xE2,
+-0x2B, 0x30,
++	0x04, 0x80, 0x10, 0xEA,
++	0x89, 0xE2,
++	0x2B, 0x30,
+ 
+-0x3F, 0xC1, 0x1D, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0xC1, 0x1D, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x68,
+-0xBF, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x68,
++	0xBF, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x20, 0xC0, 0x20, 0xAF,
+-0x28, 0x05,
+-0x97, 0x74,
++	0x20, 0xC0, 0x20, 0xAF,
++	0x28, 0x05,
++	0x97, 0x74,
+ 
+-0x00, 0xE0,
+-0x2A, 0x10,
+-0x16, 0xC0, 0x20, 0xE9,
++	0x00, 0xE0,
++	0x2A, 0x10,
++	0x16, 0xC0, 0x20, 0xE9,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x8C, 0xE2,
+-0x95, 0x05,
++	0x04, 0x80, 0x10, 0xEA,
++	0x8C, 0xE2,
++	0x95, 0x05,
+ 
+-0x28, 0xC1, 0x28, 0xAD,
+-0x1F, 0xC1, 0x15, 0xBD,
++	0x28, 0xC1, 0x28, 0xAD,
++	0x1F, 0xC1, 0x15, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA8, 0x67,
+-0x9F, 0x6B,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA8, 0x67,
++	0x9F, 0x6B,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x28, 0xC0, 0x28, 0xAD,
+-0x1D, 0x25,
+-0x20, 0x05,
++	0x28, 0xC0, 0x28, 0xAD,
++	0x1D, 0x25,
++	0x20, 0x05,
+ 
+-0x28, 0x32, 0x80, 0xAD,
+-0x40, 0x2A, 0x40, 0xBD,
++	0x28, 0x32, 0x80, 0xAD,
++	0x40, 0x2A, 0x40, 0xBD,
+ 
+-0x1C, 0x80, 0x20, 0xE9,
+-0x20, 0x33, 0x20, 0xAD,
++	0x1C, 0x80, 0x20, 0xE9,
++	0x20, 0x33, 0x20, 0xAD,
+ 
+-0x20, 0x73,
+-0x00, 0xE0,
+-0xB6, 0x49, 0x51, 0xBB,
++	0x20, 0x73,
++	0x00, 0xE0,
++	0xB6, 0x49, 0x51, 0xBB,
+ 
+-0x26, 0x2F, 0xB0, 0xE8,
+-0x19, 0x20, 0x20, 0xE9,
++	0x26, 0x2F, 0xB0, 0xE8,
++	0x19, 0x20, 0x20, 0xE9,
+ 
+-0x35, 0x20, 0x35, 0xDF,
+-0x3D, 0x20, 0x3D, 0xDF,
++	0x35, 0x20, 0x35, 0xDF,
++	0x3D, 0x20, 0x3D, 0xDF,
+ 
+-0x15, 0x20, 0x15, 0xDF,
+-0x1D, 0x20, 0x1D, 0xDF,
++	0x15, 0x20, 0x15, 0xDF,
++	0x1D, 0x20, 0x1D, 0xDF,
+ 
+-0x26, 0xD0, 0x26, 0xCD,
+-0x29, 0x49, 0x2A, 0xB8,
++	0x26, 0xD0, 0x26, 0xCD,
++	0x29, 0x49, 0x2A, 0xB8,
+ 
+-0x26, 0x40, 0x80, 0xBD,
+-0x3B, 0x48, 0x50, 0xBD,
++	0x26, 0x40, 0x80, 0xBD,
++	0x3B, 0x48, 0x50, 0xBD,
+ 
+-0x3E, 0x54, 0x57, 0x9F,
+-0x00, 0xE0,
+-0x82, 0xE1,
++	0x3E, 0x54, 0x57, 0x9F,
++	0x00, 0xE0,
++	0x82, 0xE1,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x26, 0x30,
+-0x29, 0x30,
+-0x48, 0x3C, 0x48, 0xAD,
++	0x26, 0x30,
++	0x29, 0x30,
++	0x48, 0x3C, 0x48, 0xAD,
+ 
+-0x2B, 0x72,
+-0xC2, 0xE1,
+-0x2C, 0xC0, 0x44, 0xC2,
++	0x2B, 0x72,
++	0xC2, 0xE1,
++	0x2C, 0xC0, 0x44, 0xC2,
+ 
+-0x05, 0x24, 0x34, 0xBF,
+-0x0D, 0x24, 0x2C, 0xBF,
++	0x05, 0x24, 0x34, 0xBF,
++	0x0D, 0x24, 0x2C, 0xBF,
+ 
+-0x2D, 0x46, 0x4E, 0xBF,
+-0x25, 0x46, 0x56, 0xBF,
++	0x2D, 0x46, 0x4E, 0xBF,
++	0x25, 0x46, 0x56, 0xBF,
+ 
+-0x20, 0x1D, 0x6F, 0x8F,
+-0x32, 0x3E, 0x5F, 0xE9,
++	0x20, 0x1D, 0x6F, 0x8F,
++	0x32, 0x3E, 0x5F, 0xE9,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x30,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x30,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x33, 0x1E, 0x5F, 0xE9,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x33, 0x1E, 0x5F, 0xE9,
+ 
+-0x05, 0x44, 0x54, 0xB2,
+-0x0D, 0x44, 0x4C, 0xB2,
++	0x05, 0x44, 0x54, 0xB2,
++	0x0D, 0x44, 0x4C, 0xB2,
+ 
+-0x19, 0xC0, 0xB0, 0xE8,
+-0x34, 0xC0, 0x44, 0xC4,
++	0x19, 0xC0, 0xB0, 0xE8,
++	0x34, 0xC0, 0x44, 0xC4,
+ 
+-0x33, 0x73,
+-0x00, 0xE0,
+-0x3E, 0x62, 0x57, 0x9F,
++	0x33, 0x73,
++	0x00, 0xE0,
++	0x3E, 0x62, 0x57, 0x9F,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0xE0,
+-0x0D, 0x20,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0xE0,
++	0x0D, 0x20,
+ 
+-0x84, 0x3E, 0x58, 0xE9,
+-0x28, 0x1D, 0x6F, 0x8F,
++	0x84, 0x3E, 0x58, 0xE9,
++	0x28, 0x1D, 0x6F, 0x8F,
+ 
+-0x05, 0x20,
+-0x00, 0xE0,
+-0x85, 0x1E, 0x58, 0xE9,
++	0x05, 0x20,
++	0x00, 0xE0,
++	0x85, 0x1E, 0x58, 0xE9,
+ 
+-0x9B, 0x3B, 0x33, 0xDF,
+-0x20, 0x20, 0x42, 0xAF,
++	0x9B, 0x3B, 0x33, 0xDF,
++	0x20, 0x20, 0x42, 0xAF,
+ 
+-0x30, 0x42, 0x56, 0x9F,
+-0x80, 0x3E, 0x57, 0xE9,
++	0x30, 0x42, 0x56, 0x9F,
++	0x80, 0x3E, 0x57, 0xE9,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x30, 0x80, 0x5F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x30, 0x80, 0x5F, 0xE9,
+ 
+-0x28, 0x28, 0x24, 0xAF,
+-0x81, 0x1E, 0x57, 0xE9,
++	0x28, 0x28, 0x24, 0xAF,
++	0x81, 0x1E, 0x57, 0xE9,
+ 
+-0x05, 0x47, 0x57, 0xBF,
+-0x0D, 0x47, 0x4F, 0xBF,
++	0x05, 0x47, 0x57, 0xBF,
++	0x0D, 0x47, 0x4F, 0xBF,
+ 
+-0x88, 0x80, 0x58, 0xE9,
+-0x1B, 0x29, 0x1B, 0xDF,
++	0x88, 0x80, 0x58, 0xE9,
++	0x1B, 0x29, 0x1B, 0xDF,
+ 
+-0x30, 0x1D, 0x6F, 0x8F,
+-0x3A, 0x30, 0x4F, 0xE9,
++	0x30, 0x1D, 0x6F, 0x8F,
++	0x3A, 0x30, 0x4F, 0xE9,
+ 
+-0x1C, 0x30, 0x26, 0xDF,
+-0x09, 0xE3,
+-0x3B, 0x05,
++	0x1C, 0x30, 0x26, 0xDF,
++	0x09, 0xE3,
++	0x3B, 0x05,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x3B, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x3B, 0x3F, 0x4F, 0xE9,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x00, 0xE0,
+-0xAC, 0x20,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x00, 0xE0,
++	0xAC, 0x20,
+ 
+-0x2D, 0x44, 0x4C, 0xB4,
+-0x2C, 0x1C, 0xC0, 0xAF,
++	0x2D, 0x44, 0x4C, 0xB4,
++	0x2C, 0x1C, 0xC0, 0xAF,
+ 
+-0x25, 0x44, 0x54, 0xB4,
+-0x00, 0xE0,
+-0xC8, 0x30,
++	0x25, 0x44, 0x54, 0xB4,
++	0x00, 0xE0,
++	0xC8, 0x30,
+ 
+-0x30, 0x46, 0x30, 0xAF,
+-0x1B, 0x1B, 0x48, 0xAF,
++	0x30, 0x46, 0x30, 0xAF,
++	0x1B, 0x1B, 0x48, 0xAF,
+ 
+-0x00, 0xE0,
+-0x25, 0x20,
+-0x38, 0x2C, 0x4F, 0xE9,
++	0x00, 0xE0,
++	0x25, 0x20,
++	0x38, 0x2C, 0x4F, 0xE9,
+ 
+-0x86, 0x80, 0x57, 0xE9,
+-0x38, 0x1D, 0x6F, 0x8F,
++	0x86, 0x80, 0x57, 0xE9,
++	0x38, 0x1D, 0x6F, 0x8F,
+ 
+-0x28, 0x74,
+-0x00, 0xE0,
+-0x0D, 0x44, 0x4C, 0xB0,
++	0x28, 0x74,
++	0x00, 0xE0,
++	0x0D, 0x44, 0x4C, 0xB0,
+ 
+-0x05, 0x44, 0x54, 0xB0,
+-0x2D, 0x20,
+-0x9B, 0x10,
++	0x05, 0x44, 0x54, 0xB0,
++	0x2D, 0x20,
++	0x9B, 0x10,
+ 
+-0x82, 0x3E, 0x57, 0xE9,
+-0x32, 0xF0, 0x1B, 0xCD,
++	0x82, 0x3E, 0x57, 0xE9,
++	0x32, 0xF0, 0x1B, 0xCD,
+ 
+-0x1E, 0xBD, 0x59, 0x9F,
+-0x83, 0x1E, 0x57, 0xE9,
++	0x1E, 0xBD, 0x59, 0x9F,
++	0x83, 0x1E, 0x57, 0xE9,
+ 
+-0x38, 0x47, 0x38, 0xAF,
+-0x34, 0x20,
+-0x2A, 0x30,
++	0x38, 0x47, 0x38, 0xAF,
++	0x34, 0x20,
++	0x2A, 0x30,
+ 
+-0x00, 0xE0,
+-0x0D, 0x20,
+-0x32, 0x20,
+-0x05, 0x20,
++	0x00, 0xE0,
++	0x0D, 0x20,
++	0x32, 0x20,
++	0x05, 0x20,
+ 
+-0x87, 0x80, 0x57, 0xE9,
+-0x1F, 0x54, 0x57, 0x9F,
++	0x87, 0x80, 0x57, 0xE9,
++	0x1F, 0x54, 0x57, 0x9F,
+ 
+-0x17, 0x42, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x6A,
++	0x17, 0x42, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x6A,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x37, 0x1E, 0x4F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x37, 0x1E, 0x4F, 0xE9,
+ 
+-0x37, 0x32, 0x2A, 0xAF,
+-0x00, 0xE0,
+-0x32, 0x00,
++	0x37, 0x32, 0x2A, 0xAF,
++	0x00, 0xE0,
++	0x32, 0x00,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x27, 0xC0, 0x44, 0xC0,
++	0x00, 0x80, 0x00, 0xE8,
++	0x27, 0xC0, 0x44, 0xC0,
+ 
+-0x36, 0x1F, 0x4F, 0xE9,
+-0x1F, 0x1F, 0x26, 0xDF,
++	0x36, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x1F, 0x26, 0xDF,
+ 
+-0x37, 0x1B, 0x37, 0xBF,
+-0x17, 0x26, 0x17, 0xDF,
++	0x37, 0x1B, 0x37, 0xBF,
++	0x17, 0x26, 0x17, 0xDF,
+ 
+-0x3E, 0x17, 0x4F, 0xE9,
+-0x3F, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x17, 0x4F, 0xE9,
++	0x3F, 0x3F, 0x4F, 0xE9,
+ 
+-0x34, 0x1F, 0x34, 0xAF,
+-0x2B, 0x05,
+-0xA7, 0x20,
++	0x34, 0x1F, 0x34, 0xAF,
++	0x2B, 0x05,
++	0xA7, 0x20,
+ 
+-0x33, 0x2B, 0x37, 0xDF,
+-0x27, 0x17, 0xC0, 0xAF,
++	0x33, 0x2B, 0x37, 0xDF,
++	0x27, 0x17, 0xC0, 0xAF,
+ 
+-0x34, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x34, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x2D, 0x21, 0x1A, 0xB0,
+-0x25, 0x21, 0x31, 0xB0,
++	0x2D, 0x21, 0x1A, 0xB0,
++	0x25, 0x21, 0x31, 0xB0,
+ 
+-0x0D, 0x21, 0x1A, 0xB2,
+-0x05, 0x21, 0x31, 0xB2,
++	0x0D, 0x21, 0x1A, 0xB2,
++	0x05, 0x21, 0x31, 0xB2,
+ 
+-0x03, 0x80, 0x2A, 0xEA,
+-0x17, 0xC1, 0x2B, 0xBD,
++	0x03, 0x80, 0x2A, 0xEA,
++	0x17, 0xC1, 0x2B, 0xBD,
+ 
+-0x2D, 0x20,
+-0x25, 0x20,
+-0x05, 0x20,
+-0x0D, 0x20,
++	0x2D, 0x20,
++	0x25, 0x20,
++	0x05, 0x20,
++	0x0D, 0x20,
+ 
+-0xB3, 0x68,
+-0x97, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x68,
++	0x97, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0xC0, 0x33, 0xAF,
+-0x2F, 0xC0, 0x21, 0xC0,
++	0x33, 0xC0, 0x33, 0xAF,
++	0x2F, 0xC0, 0x21, 0xC0,
+ 
+-0x16, 0x42, 0x56, 0x9F,
+-0x3C, 0x27, 0x4F, 0xE9,
++	0x16, 0x42, 0x56, 0x9F,
++	0x3C, 0x27, 0x4F, 0xE9,
+ 
+-0x1E, 0x62, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0x62, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x21, 0x31, 0xB4,
+-0x2D, 0x21, 0x1A, 0xB4,
++	0x25, 0x21, 0x31, 0xB4,
++	0x2D, 0x21, 0x1A, 0xB4,
+ 
+-0x3F, 0x2F, 0x5D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0x2F, 0x5D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0x05,
+-0x00, 0xE0,
+-0x28, 0x19, 0x60, 0xEC,
++	0x33, 0x05,
++	0x00, 0xE0,
++	0x28, 0x19, 0x60, 0xEC,
+ 
+-0x0D, 0x21, 0x1A, 0xB6,
+-0x05, 0x21, 0x31, 0xB6,
++	0x0D, 0x21, 0x1A, 0xB6,
++	0x05, 0x21, 0x31, 0xB6,
+ 
+-0x37, 0x0F, 0x5C, 0x9F,
+-0x00, 0xE0,
+-0x2F, 0x20,
++	0x37, 0x0F, 0x5C, 0x9F,
++	0x00, 0xE0,
++	0x2F, 0x20,
+ 
+-0x23, 0x3B, 0x33, 0xAD,
+-0x1E, 0x26, 0x1E, 0xDF,
++	0x23, 0x3B, 0x33, 0xAD,
++	0x1E, 0x26, 0x1E, 0xDF,
+ 
+-0xA7, 0x1E, 0x4F, 0xE9,
+-0x17, 0x26, 0x16, 0xDF,
++	0xA7, 0x1E, 0x4F, 0xE9,
++	0x17, 0x26, 0x16, 0xDF,
+ 
+-0x2D, 0x20,
+-0x00, 0xE0,
+-0xA8, 0x3F, 0x4F, 0xE9,
++	0x2D, 0x20,
++	0x00, 0xE0,
++	0xA8, 0x3F, 0x4F, 0xE9,
+ 
+-0x2F, 0x2F, 0x1E, 0xAF,
+-0x25, 0x20,
+-0x00, 0xE0,
++	0x2F, 0x2F, 0x1E, 0xAF,
++	0x25, 0x20,
++	0x00, 0xE0,
+ 
+-0xA4, 0x16, 0x4F, 0xE9,
+-0x0F, 0xC0, 0x21, 0xC2,
++	0xA4, 0x16, 0x4F, 0xE9,
++	0x0F, 0xC0, 0x21, 0xC2,
+ 
+-0xA6, 0x80, 0x4F, 0xE9,
+-0x1F, 0x62, 0x57, 0x9F,
++	0xA6, 0x80, 0x4F, 0xE9,
++	0x1F, 0x62, 0x57, 0x9F,
+ 
+-0x0D, 0x20,
+-0x05, 0x20,
+-0x2F, 0xC0, 0x21, 0xC6,
++	0x0D, 0x20,
++	0x05, 0x20,
++	0x2F, 0xC0, 0x21, 0xC6,
+ 
+-0x2D, 0x44, 0x4C, 0xB6,
+-0x25, 0x44, 0x54, 0xB6,
++	0x2D, 0x44, 0x4C, 0xB6,
++	0x25, 0x44, 0x54, 0xB6,
+ 
+-0x3F, 0x2F, 0x5D, 0x9F,
+-0x00, 0xE0,
+-0x0F, 0x20,
++	0x3F, 0x2F, 0x5D, 0x9F,
++	0x00, 0xE0,
++	0x0F, 0x20,
+ 
+-0x2D, 0x20,
+-0x25, 0x20,
+-0x07, 0xC0, 0x44, 0xC6,
++	0x2D, 0x20,
++	0x25, 0x20,
++	0x07, 0xC0, 0x44, 0xC6,
+ 
+-0x17, 0x50, 0x56, 0x9F,
+-0xA5, 0x37, 0x4F, 0xE9,
++	0x17, 0x50, 0x56, 0x9F,
++	0xA5, 0x37, 0x4F, 0xE9,
+ 
+-0x06, 0xC0, 0x21, 0xC4,
+-0x0F, 0x17, 0x0F, 0xAF,
++	0x06, 0xC0, 0x21, 0xC4,
++	0x0F, 0x17, 0x0F, 0xAF,
+ 
+-0x37, 0x0F, 0x5C, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x37, 0x0F, 0x5C, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1E, 0x62, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0x62, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x3E, 0x3D, 0x5D, 0x9F,
+-0x00, 0xE0,
+-0x07, 0x20,
++	0x3E, 0x3D, 0x5D, 0x9F,
++	0x00, 0xE0,
++	0x07, 0x20,
+ 
+-0x2F, 0x20,
+-0x00, 0xE0,
+-0xA3, 0x0F, 0x4F, 0xE9,
++	0x2F, 0x20,
++	0x00, 0xE0,
++	0xA3, 0x0F, 0x4F, 0xE9,
+ 
+-0x06, 0x20,
+-0x00, 0xE0,
+-0x1F, 0x26, 0x1F, 0xDF,
++	0x06, 0x20,
++	0x00, 0xE0,
++	0x1F, 0x26, 0x1F, 0xDF,
+ 
+-0x17, 0x26, 0x17, 0xDF,
+-0xA1, 0x1F, 0x4F, 0xE9,
++	0x17, 0x26, 0x17, 0xDF,
++	0xA1, 0x1F, 0x4F, 0xE9,
+ 
+-0x1E, 0x26, 0x1E, 0xDF,
+-0x9D, 0x1E, 0x4F, 0xE9,
++	0x1E, 0x26, 0x1E, 0xDF,
++	0x9D, 0x1E, 0x4F, 0xE9,
+ 
+-0x35, 0x17, 0x4F, 0xE9,
+-0xA2, 0x3F, 0x4F, 0xE9,
++	0x35, 0x17, 0x4F, 0xE9,
++	0xA2, 0x3F, 0x4F, 0xE9,
+ 
+-0x06, 0x06, 0x1F, 0xAF,
+-0x39, 0x37, 0x4F, 0xE9,
++	0x06, 0x06, 0x1F, 0xAF,
++	0x39, 0x37, 0x4F, 0xE9,
+ 
+-0x2F, 0x2F, 0x17, 0xAF,
+-0x07, 0x07, 0x1E, 0xAF,
++	0x2F, 0x2F, 0x17, 0xAF,
++	0x07, 0x07, 0x1E, 0xAF,
+ 
+-0xA0, 0x80, 0x4F, 0xE9,
+-0x9E, 0x3E, 0x4F, 0xE9,
++	0xA0, 0x80, 0x4F, 0xE9,
++	0x9E, 0x3E, 0x4F, 0xE9,
+ 
+-0x31, 0x80, 0x4F, 0xE9,
+-0x9C, 0x80, 0x4F, 0xE9,
++	0x31, 0x80, 0x4F, 0xE9,
++	0x9C, 0x80, 0x4F, 0xE9,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x57, 0x39, 0x20, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x57, 0x39, 0x20, 0xE9,
+ 
+-0x16, 0x28, 0x20, 0xE9,
+-0x1D, 0x3B, 0x20, 0xE9,
++	0x16, 0x28, 0x20, 0xE9,
++	0x1D, 0x3B, 0x20, 0xE9,
+ 
+-0x1E, 0x2B, 0x20, 0xE9,
+-0x2B, 0x32, 0x20, 0xE9,
++	0x1E, 0x2B, 0x20, 0xE9,
++	0x2B, 0x32, 0x20, 0xE9,
+ 
+-0x1C, 0x23, 0x20, 0xE9,
+-0x57, 0x36, 0x20, 0xE9,
++	0x1C, 0x23, 0x20, 0xE9,
++	0x57, 0x36, 0x20, 0xE9,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x90, 0xE2,
+-0x00, 0xE0,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x90, 0xE2,
++	0x00, 0xE0,
+ 
+-0x63, 0xFF, 0x20, 0xEA,
+-0x19, 0xC8, 0xC1, 0xCD,
++	0x63, 0xFF, 0x20, 0xEA,
++	0x19, 0xC8, 0xC1, 0xCD,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x9F, 0x41, 0x49, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9F, 0x41, 0x49, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x41, 0x49, 0xBD,
+-0x2D, 0x41, 0x51, 0xBD,
++	0x25, 0x41, 0x49, 0xBD,
++	0x2D, 0x41, 0x51, 0xBD,
+ 
+-0x0D, 0x80, 0x07, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x0D, 0x80, 0x07, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x35, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0x35, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x25, 0x30,
+-0x2D, 0x30,
++	0x00, 0x80, 0x00, 0xE8,
++	0x25, 0x30,
++	0x2D, 0x30,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0xA7, 0x5B, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0xA7, 0x5B, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x62, 0xFF, 0x0A, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x62, 0xFF, 0x0A, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC9, 0x41, 0xC8, 0xEC,
+-0x42, 0xE1,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC8, 0xEC,
++	0x42, 0xE1,
++	0x00, 0xE0,
+ 
+-0x60, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x60, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC8, 0x40, 0xC0, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC8, 0x40, 0xC0, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x5D, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x5D, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+ };
+ 
+ static unsigned char warp_g200_tgzsf[] = {
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x98, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x98, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x81, 0x04,
+-0x89, 0x04,
+-0x01, 0x04,
+-0x09, 0x04,
++	0x81, 0x04,
++	0x89, 0x04,
++	0x01, 0x04,
++	0x09, 0x04,
+ 
+-0xC9, 0x41, 0xC0, 0xEC,
+-0x11, 0x04,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC0, 0xEC,
++	0x11, 0x04,
++	0x00, 0xE0,
+ 
+-0x41, 0xCC, 0x41, 0xCD,
+-0x49, 0xCC, 0x49, 0xCD,
++	0x41, 0xCC, 0x41, 0xCD,
++	0x49, 0xCC, 0x49, 0xCD,
+ 
+-0xD1, 0x41, 0xC0, 0xEC,
+-0x51, 0xCC, 0x51, 0xCD,
++	0xD1, 0x41, 0xC0, 0xEC,
++	0x51, 0xCC, 0x51, 0xCD,
+ 
+-0x80, 0x04,
+-0x10, 0x04,
+-0x08, 0x04,
+-0x00, 0xE0,
++	0x80, 0x04,
++	0x10, 0x04,
++	0x08, 0x04,
++	0x00, 0xE0,
+ 
+-0x00, 0xCC, 0xC0, 0xCD,
+-0xD1, 0x49, 0xC0, 0xEC,
++	0x00, 0xCC, 0xC0, 0xCD,
++	0xD1, 0x49, 0xC0, 0xEC,
+ 
+-0x8A, 0x1F, 0x20, 0xE9,
+-0x8B, 0x3F, 0x20, 0xE9,
++	0x8A, 0x1F, 0x20, 0xE9,
++	0x8B, 0x3F, 0x20, 0xE9,
+ 
+-0x41, 0x3C, 0x41, 0xAD,
+-0x49, 0x3C, 0x49, 0xAD,
++	0x41, 0x3C, 0x41, 0xAD,
++	0x49, 0x3C, 0x49, 0xAD,
+ 
+-0x10, 0xCC, 0x10, 0xCD,
+-0x08, 0xCC, 0x08, 0xCD,
++	0x10, 0xCC, 0x10, 0xCD,
++	0x08, 0xCC, 0x08, 0xCD,
+ 
+-0xB9, 0x41, 0x49, 0xBB,
+-0x1F, 0xF0, 0x41, 0xCD,
++	0xB9, 0x41, 0x49, 0xBB,
++	0x1F, 0xF0, 0x41, 0xCD,
+ 
+-0x51, 0x3C, 0x51, 0xAD,
+-0x00, 0x98, 0x80, 0xE9,
++	0x51, 0x3C, 0x51, 0xAD,
++	0x00, 0x98, 0x80, 0xE9,
+ 
+-0x8F, 0x80, 0x07, 0xEA,
+-0x24, 0x1F, 0x20, 0xE9,
++	0x8F, 0x80, 0x07, 0xEA,
++	0x24, 0x1F, 0x20, 0xE9,
+ 
+-0x21, 0x45, 0x80, 0xE8,
+-0x1A, 0x4D, 0x80, 0xE8,
++	0x21, 0x45, 0x80, 0xE8,
++	0x1A, 0x4D, 0x80, 0xE8,
+ 
+-0x31, 0x55, 0x80, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x55, 0x80, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0x41, 0x49, 0xBD,
+-0x1D, 0x41, 0x51, 0xBD,
++	0x15, 0x41, 0x49, 0xBD,
++	0x1D, 0x41, 0x51, 0xBD,
+ 
+-0x2E, 0x41, 0x2A, 0xB8,
+-0x34, 0x53, 0xA0, 0xE8,
++	0x2E, 0x41, 0x2A, 0xB8,
++	0x34, 0x53, 0xA0, 0xE8,
+ 
+-0x15, 0x30,
+-0x1D, 0x30,
+-0x58, 0xE3,
+-0x00, 0xE0,
++	0x15, 0x30,
++	0x1D, 0x30,
++	0x58, 0xE3,
++	0x00, 0xE0,
+ 
+-0xB5, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0xB5, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x24, 0x43, 0xA0, 0xE8,
+-0x2C, 0x4B, 0xA0, 0xE8,
++	0x24, 0x43, 0xA0, 0xE8,
++	0x2C, 0x4B, 0xA0, 0xE8,
+ 
+-0x15, 0x72,
+-0x09, 0xE3,
+-0x00, 0xE0,
+-0x1D, 0x72,
++	0x15, 0x72,
++	0x09, 0xE3,
++	0x00, 0xE0,
++	0x1D, 0x72,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0x97, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0x97, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x6C, 0x64, 0xC8, 0xEC,
+-0x98, 0xE1,
+-0xB5, 0x05,
++	0x6C, 0x64, 0xC8, 0xEC,
++	0x98, 0xE1,
++	0xB5, 0x05,
+ 
+-0xBD, 0x05,
+-0x2E, 0x30,
+-0x32, 0xC0, 0xA0, 0xE8,
++	0xBD, 0x05,
++	0x2E, 0x30,
++	0x32, 0xC0, 0xA0, 0xE8,
+ 
+-0x33, 0xC0, 0xA0, 0xE8,
+-0x74, 0x64, 0xC8, 0xEC,
++	0x33, 0xC0, 0xA0, 0xE8,
++	0x74, 0x64, 0xC8, 0xEC,
+ 
+-0x40, 0x3C, 0x40, 0xAD,
+-0x32, 0x6A,
+-0x2A, 0x30,
++	0x40, 0x3C, 0x40, 0xAD,
++	0x32, 0x6A,
++	0x2A, 0x30,
+ 
+-0x20, 0x73,
+-0x33, 0x6A,
+-0x00, 0xE0,
+-0x28, 0x73,
++	0x20, 0x73,
++	0x33, 0x6A,
++	0x00, 0xE0,
++	0x28, 0x73,
+ 
+-0x1C, 0x72,
+-0x83, 0xE2,
+-0x7B, 0x80, 0x15, 0xEA,
++	0x1C, 0x72,
++	0x83, 0xE2,
++	0x7B, 0x80, 0x15, 0xEA,
+ 
+-0xB8, 0x3D, 0x28, 0xDF,
+-0x30, 0x35, 0x20, 0xDF,
++	0xB8, 0x3D, 0x28, 0xDF,
++	0x30, 0x35, 0x20, 0xDF,
+ 
+-0x40, 0x30,
+-0x00, 0xE0,
+-0xCC, 0xE2,
+-0x64, 0x72,
++	0x40, 0x30,
++	0x00, 0xE0,
++	0xCC, 0xE2,
++	0x64, 0x72,
+ 
+-0x25, 0x42, 0x52, 0xBF,
+-0x2D, 0x42, 0x4A, 0xBF,
++	0x25, 0x42, 0x52, 0xBF,
++	0x2D, 0x42, 0x4A, 0xBF,
+ 
+-0x30, 0x2E, 0x30, 0xDF,
+-0x38, 0x2E, 0x38, 0xDF,
++	0x30, 0x2E, 0x30, 0xDF,
++	0x38, 0x2E, 0x38, 0xDF,
+ 
+-0x18, 0x1D, 0x45, 0xE9,
+-0x1E, 0x15, 0x45, 0xE9,
++	0x18, 0x1D, 0x45, 0xE9,
++	0x1E, 0x15, 0x45, 0xE9,
+ 
+-0x2B, 0x49, 0x51, 0xBD,
+-0x00, 0xE0,
+-0x1F, 0x73,
++	0x2B, 0x49, 0x51, 0xBD,
++	0x00, 0xE0,
++	0x1F, 0x73,
+ 
+-0x38, 0x38, 0x40, 0xAF,
+-0x30, 0x30, 0x40, 0xAF,
++	0x38, 0x38, 0x40, 0xAF,
++	0x30, 0x30, 0x40, 0xAF,
+ 
+-0x24, 0x1F, 0x24, 0xDF,
+-0x1D, 0x32, 0x20, 0xE9,
++	0x24, 0x1F, 0x24, 0xDF,
++	0x1D, 0x32, 0x20, 0xE9,
+ 
+-0x2C, 0x1F, 0x2C, 0xDF,
+-0x1A, 0x33, 0x20, 0xE9,
++	0x2C, 0x1F, 0x2C, 0xDF,
++	0x1A, 0x33, 0x20, 0xE9,
+ 
+-0xB0, 0x10,
+-0x08, 0xE3,
+-0x40, 0x10,
+-0xB8, 0x10,
++	0xB0, 0x10,
++	0x08, 0xE3,
++	0x40, 0x10,
++	0xB8, 0x10,
+ 
+-0x26, 0xF0, 0x30, 0xCD,
+-0x2F, 0xF0, 0x38, 0xCD,
++	0x26, 0xF0, 0x30, 0xCD,
++	0x2F, 0xF0, 0x38, 0xCD,
+ 
+-0x2B, 0x80, 0x20, 0xE9,
+-0x2A, 0x80, 0x20, 0xE9,
++	0x2B, 0x80, 0x20, 0xE9,
++	0x2A, 0x80, 0x20, 0xE9,
+ 
+-0xA6, 0x20,
+-0x88, 0xE2,
+-0x00, 0xE0,
+-0xAF, 0x20,
++	0xA6, 0x20,
++	0x88, 0xE2,
++	0x00, 0xE0,
++	0xAF, 0x20,
+ 
+-0x28, 0x2A, 0x26, 0xAF,
+-0x20, 0x2A, 0xC0, 0xAF,
++	0x28, 0x2A, 0x26, 0xAF,
++	0x20, 0x2A, 0xC0, 0xAF,
+ 
+-0x34, 0x1F, 0x34, 0xDF,
+-0x46, 0x24, 0x46, 0xDF,
++	0x34, 0x1F, 0x34, 0xDF,
++	0x46, 0x24, 0x46, 0xDF,
+ 
+-0x28, 0x30, 0x80, 0xBF,
+-0x20, 0x38, 0x80, 0xBF,
++	0x28, 0x30, 0x80, 0xBF,
++	0x20, 0x38, 0x80, 0xBF,
+ 
+-0x47, 0x24, 0x47, 0xDF,
+-0x4E, 0x2C, 0x4E, 0xDF,
++	0x47, 0x24, 0x47, 0xDF,
++	0x4E, 0x2C, 0x4E, 0xDF,
+ 
+-0x4F, 0x2C, 0x4F, 0xDF,
+-0x56, 0x34, 0x56, 0xDF,
++	0x4F, 0x2C, 0x4F, 0xDF,
++	0x56, 0x34, 0x56, 0xDF,
+ 
+-0x28, 0x15, 0x28, 0xDF,
+-0x20, 0x1D, 0x20, 0xDF,
++	0x28, 0x15, 0x28, 0xDF,
++	0x20, 0x1D, 0x20, 0xDF,
+ 
+-0x57, 0x34, 0x57, 0xDF,
+-0x00, 0xE0,
+-0x1D, 0x05,
++	0x57, 0x34, 0x57, 0xDF,
++	0x00, 0xE0,
++	0x1D, 0x05,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x89, 0xE2,
+-0x2B, 0x30,
++	0x04, 0x80, 0x10, 0xEA,
++	0x89, 0xE2,
++	0x2B, 0x30,
+ 
+-0x3F, 0xC1, 0x1D, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0xC1, 0x1D, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x68,
+-0xBF, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x68,
++	0xBF, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x20, 0xC0, 0x20, 0xAF,
+-0x28, 0x05,
+-0x97, 0x74,
++	0x20, 0xC0, 0x20, 0xAF,
++	0x28, 0x05,
++	0x97, 0x74,
+ 
+-0x00, 0xE0,
+-0x2A, 0x10,
+-0x16, 0xC0, 0x20, 0xE9,
++	0x00, 0xE0,
++	0x2A, 0x10,
++	0x16, 0xC0, 0x20, 0xE9,
+ 
+-0x04, 0x80, 0x10, 0xEA,
+-0x8C, 0xE2,
+-0x95, 0x05,
++	0x04, 0x80, 0x10, 0xEA,
++	0x8C, 0xE2,
++	0x95, 0x05,
+ 
+-0x28, 0xC1, 0x28, 0xAD,
+-0x1F, 0xC1, 0x15, 0xBD,
++	0x28, 0xC1, 0x28, 0xAD,
++	0x1F, 0xC1, 0x15, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA8, 0x67,
+-0x9F, 0x6B,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA8, 0x67,
++	0x9F, 0x6B,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x28, 0xC0, 0x28, 0xAD,
+-0x1D, 0x25,
+-0x20, 0x05,
++	0x28, 0xC0, 0x28, 0xAD,
++	0x1D, 0x25,
++	0x20, 0x05,
+ 
+-0x28, 0x32, 0x80, 0xAD,
+-0x40, 0x2A, 0x40, 0xBD,
++	0x28, 0x32, 0x80, 0xAD,
++	0x40, 0x2A, 0x40, 0xBD,
+ 
+-0x1C, 0x80, 0x20, 0xE9,
+-0x20, 0x33, 0x20, 0xAD,
++	0x1C, 0x80, 0x20, 0xE9,
++	0x20, 0x33, 0x20, 0xAD,
+ 
+-0x20, 0x73,
+-0x00, 0xE0,
+-0xB6, 0x49, 0x51, 0xBB,
++	0x20, 0x73,
++	0x00, 0xE0,
++	0xB6, 0x49, 0x51, 0xBB,
+ 
+-0x26, 0x2F, 0xB0, 0xE8,
+-0x19, 0x20, 0x20, 0xE9,
++	0x26, 0x2F, 0xB0, 0xE8,
++	0x19, 0x20, 0x20, 0xE9,
+ 
+-0x35, 0x20, 0x35, 0xDF,
+-0x3D, 0x20, 0x3D, 0xDF,
++	0x35, 0x20, 0x35, 0xDF,
++	0x3D, 0x20, 0x3D, 0xDF,
+ 
+-0x15, 0x20, 0x15, 0xDF,
+-0x1D, 0x20, 0x1D, 0xDF,
++	0x15, 0x20, 0x15, 0xDF,
++	0x1D, 0x20, 0x1D, 0xDF,
+ 
+-0x26, 0xD0, 0x26, 0xCD,
+-0x29, 0x49, 0x2A, 0xB8,
++	0x26, 0xD0, 0x26, 0xCD,
++	0x29, 0x49, 0x2A, 0xB8,
+ 
+-0x26, 0x40, 0x80, 0xBD,
+-0x3B, 0x48, 0x50, 0xBD,
++	0x26, 0x40, 0x80, 0xBD,
++	0x3B, 0x48, 0x50, 0xBD,
+ 
+-0x3E, 0x54, 0x57, 0x9F,
+-0x00, 0xE0,
+-0x82, 0xE1,
++	0x3E, 0x54, 0x57, 0x9F,
++	0x00, 0xE0,
++	0x82, 0xE1,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x26, 0x30,
+-0x29, 0x30,
+-0x48, 0x3C, 0x48, 0xAD,
++	0x26, 0x30,
++	0x29, 0x30,
++	0x48, 0x3C, 0x48, 0xAD,
+ 
+-0x2B, 0x72,
+-0xC2, 0xE1,
+-0x2C, 0xC0, 0x44, 0xC2,
++	0x2B, 0x72,
++	0xC2, 0xE1,
++	0x2C, 0xC0, 0x44, 0xC2,
+ 
+-0x05, 0x24, 0x34, 0xBF,
+-0x0D, 0x24, 0x2C, 0xBF,
++	0x05, 0x24, 0x34, 0xBF,
++	0x0D, 0x24, 0x2C, 0xBF,
+ 
+-0x2D, 0x46, 0x4E, 0xBF,
+-0x25, 0x46, 0x56, 0xBF,
++	0x2D, 0x46, 0x4E, 0xBF,
++	0x25, 0x46, 0x56, 0xBF,
+ 
+-0x20, 0x1D, 0x6F, 0x8F,
+-0x32, 0x3E, 0x5F, 0xE9,
++	0x20, 0x1D, 0x6F, 0x8F,
++	0x32, 0x3E, 0x5F, 0xE9,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x30,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x30,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x33, 0x1E, 0x5F, 0xE9,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x33, 0x1E, 0x5F, 0xE9,
+ 
+-0x05, 0x44, 0x54, 0xB2,
+-0x0D, 0x44, 0x4C, 0xB2,
++	0x05, 0x44, 0x54, 0xB2,
++	0x0D, 0x44, 0x4C, 0xB2,
+ 
+-0x19, 0xC0, 0xB0, 0xE8,
+-0x34, 0xC0, 0x44, 0xC4,
++	0x19, 0xC0, 0xB0, 0xE8,
++	0x34, 0xC0, 0x44, 0xC4,
+ 
+-0x33, 0x73,
+-0x00, 0xE0,
+-0x3E, 0x62, 0x57, 0x9F,
++	0x33, 0x73,
++	0x00, 0xE0,
++	0x3E, 0x62, 0x57, 0x9F,
+ 
+-0x1E, 0xAF, 0x59, 0x9F,
+-0x00, 0xE0,
+-0x0D, 0x20,
++	0x1E, 0xAF, 0x59, 0x9F,
++	0x00, 0xE0,
++	0x0D, 0x20,
+ 
+-0x84, 0x3E, 0x58, 0xE9,
+-0x28, 0x1D, 0x6F, 0x8F,
++	0x84, 0x3E, 0x58, 0xE9,
++	0x28, 0x1D, 0x6F, 0x8F,
+ 
+-0x05, 0x20,
+-0x00, 0xE0,
+-0x85, 0x1E, 0x58, 0xE9,
++	0x05, 0x20,
++	0x00, 0xE0,
++	0x85, 0x1E, 0x58, 0xE9,
+ 
+-0x9B, 0x3B, 0x33, 0xDF,
+-0x20, 0x20, 0x42, 0xAF,
++	0x9B, 0x3B, 0x33, 0xDF,
++	0x20, 0x20, 0x42, 0xAF,
+ 
+-0x30, 0x42, 0x56, 0x9F,
+-0x80, 0x3E, 0x57, 0xE9,
++	0x30, 0x42, 0x56, 0x9F,
++	0x80, 0x3E, 0x57, 0xE9,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x30, 0x80, 0x5F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x30, 0x80, 0x5F, 0xE9,
+ 
+-0x28, 0x28, 0x24, 0xAF,
+-0x81, 0x1E, 0x57, 0xE9,
++	0x28, 0x28, 0x24, 0xAF,
++	0x81, 0x1E, 0x57, 0xE9,
+ 
+-0x05, 0x47, 0x57, 0xBF,
+-0x0D, 0x47, 0x4F, 0xBF,
++	0x05, 0x47, 0x57, 0xBF,
++	0x0D, 0x47, 0x4F, 0xBF,
+ 
+-0x88, 0x80, 0x58, 0xE9,
+-0x1B, 0x29, 0x1B, 0xDF,
++	0x88, 0x80, 0x58, 0xE9,
++	0x1B, 0x29, 0x1B, 0xDF,
+ 
+-0x30, 0x1D, 0x6F, 0x8F,
+-0x3A, 0x30, 0x4F, 0xE9,
++	0x30, 0x1D, 0x6F, 0x8F,
++	0x3A, 0x30, 0x4F, 0xE9,
+ 
+-0x1C, 0x30, 0x26, 0xDF,
+-0x09, 0xE3,
+-0x3B, 0x05,
++	0x1C, 0x30, 0x26, 0xDF,
++	0x09, 0xE3,
++	0x3B, 0x05,
+ 
+-0x3E, 0x50, 0x56, 0x9F,
+-0x3B, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x50, 0x56, 0x9F,
++	0x3B, 0x3F, 0x4F, 0xE9,
+ 
+-0x1E, 0x8F, 0x51, 0x9F,
+-0x00, 0xE0,
+-0xAC, 0x20,
++	0x1E, 0x8F, 0x51, 0x9F,
++	0x00, 0xE0,
++	0xAC, 0x20,
+ 
+-0x2D, 0x44, 0x4C, 0xB4,
+-0x2C, 0x1C, 0xC0, 0xAF,
++	0x2D, 0x44, 0x4C, 0xB4,
++	0x2C, 0x1C, 0xC0, 0xAF,
+ 
+-0x25, 0x44, 0x54, 0xB4,
+-0x00, 0xE0,
+-0xC8, 0x30,
++	0x25, 0x44, 0x54, 0xB4,
++	0x00, 0xE0,
++	0xC8, 0x30,
+ 
+-0x30, 0x46, 0x30, 0xAF,
+-0x1B, 0x1B, 0x48, 0xAF,
++	0x30, 0x46, 0x30, 0xAF,
++	0x1B, 0x1B, 0x48, 0xAF,
+ 
+-0x00, 0xE0,
+-0x25, 0x20,
+-0x38, 0x2C, 0x4F, 0xE9,
++	0x00, 0xE0,
++	0x25, 0x20,
++	0x38, 0x2C, 0x4F, 0xE9,
+ 
+-0x86, 0x80, 0x57, 0xE9,
+-0x38, 0x1D, 0x6F, 0x8F,
++	0x86, 0x80, 0x57, 0xE9,
++	0x38, 0x1D, 0x6F, 0x8F,
+ 
+-0x28, 0x74,
+-0x00, 0xE0,
+-0x0D, 0x44, 0x4C, 0xB0,
++	0x28, 0x74,
++	0x00, 0xE0,
++	0x0D, 0x44, 0x4C, 0xB0,
+ 
+-0x05, 0x44, 0x54, 0xB0,
+-0x2D, 0x20,
+-0x9B, 0x10,
++	0x05, 0x44, 0x54, 0xB0,
++	0x2D, 0x20,
++	0x9B, 0x10,
+ 
+-0x82, 0x3E, 0x57, 0xE9,
+-0x32, 0xF0, 0x1B, 0xCD,
++	0x82, 0x3E, 0x57, 0xE9,
++	0x32, 0xF0, 0x1B, 0xCD,
+ 
+-0x1E, 0xBD, 0x59, 0x9F,
+-0x83, 0x1E, 0x57, 0xE9,
++	0x1E, 0xBD, 0x59, 0x9F,
++	0x83, 0x1E, 0x57, 0xE9,
+ 
+-0x38, 0x47, 0x38, 0xAF,
+-0x34, 0x20,
+-0x2A, 0x30,
++	0x38, 0x47, 0x38, 0xAF,
++	0x34, 0x20,
++	0x2A, 0x30,
+ 
+-0x00, 0xE0,
+-0x0D, 0x20,
+-0x32, 0x20,
+-0x05, 0x20,
++	0x00, 0xE0,
++	0x0D, 0x20,
++	0x32, 0x20,
++	0x05, 0x20,
+ 
+-0x87, 0x80, 0x57, 0xE9,
+-0x1F, 0x54, 0x57, 0x9F,
++	0x87, 0x80, 0x57, 0xE9,
++	0x1F, 0x54, 0x57, 0x9F,
+ 
+-0x17, 0x42, 0x56, 0x9F,
+-0x00, 0xE0,
+-0x3B, 0x6A,
++	0x17, 0x42, 0x56, 0x9F,
++	0x00, 0xE0,
++	0x3B, 0x6A,
+ 
+-0x3F, 0x8F, 0x51, 0x9F,
+-0x37, 0x1E, 0x4F, 0xE9,
++	0x3F, 0x8F, 0x51, 0x9F,
++	0x37, 0x1E, 0x4F, 0xE9,
+ 
+-0x37, 0x32, 0x2A, 0xAF,
+-0x00, 0xE0,
+-0x32, 0x00,
++	0x37, 0x32, 0x2A, 0xAF,
++	0x00, 0xE0,
++	0x32, 0x00,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x27, 0xC0, 0x44, 0xC0,
++	0x00, 0x80, 0x00, 0xE8,
++	0x27, 0xC0, 0x44, 0xC0,
+ 
+-0x36, 0x1F, 0x4F, 0xE9,
+-0x1F, 0x1F, 0x26, 0xDF,
++	0x36, 0x1F, 0x4F, 0xE9,
++	0x1F, 0x1F, 0x26, 0xDF,
+ 
+-0x37, 0x1B, 0x37, 0xBF,
+-0x17, 0x26, 0x17, 0xDF,
++	0x37, 0x1B, 0x37, 0xBF,
++	0x17, 0x26, 0x17, 0xDF,
+ 
+-0x3E, 0x17, 0x4F, 0xE9,
+-0x3F, 0x3F, 0x4F, 0xE9,
++	0x3E, 0x17, 0x4F, 0xE9,
++	0x3F, 0x3F, 0x4F, 0xE9,
+ 
+-0x34, 0x1F, 0x34, 0xAF,
+-0x2B, 0x05,
+-0xA7, 0x20,
++	0x34, 0x1F, 0x34, 0xAF,
++	0x2B, 0x05,
++	0xA7, 0x20,
+ 
+-0x33, 0x2B, 0x37, 0xDF,
+-0x27, 0x17, 0xC0, 0xAF,
++	0x33, 0x2B, 0x37, 0xDF,
++	0x27, 0x17, 0xC0, 0xAF,
+ 
+-0x34, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x34, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x2D, 0x21, 0x1A, 0xB0,
+-0x25, 0x21, 0x31, 0xB0,
++	0x2D, 0x21, 0x1A, 0xB0,
++	0x25, 0x21, 0x31, 0xB0,
+ 
+-0x0D, 0x21, 0x1A, 0xB2,
+-0x05, 0x21, 0x31, 0xB2,
++	0x0D, 0x21, 0x1A, 0xB2,
++	0x05, 0x21, 0x31, 0xB2,
+ 
+-0x03, 0x80, 0x2A, 0xEA,
+-0x17, 0xC1, 0x2B, 0xBD,
++	0x03, 0x80, 0x2A, 0xEA,
++	0x17, 0xC1, 0x2B, 0xBD,
+ 
+-0x2D, 0x20,
+-0x25, 0x20,
+-0x05, 0x20,
+-0x0D, 0x20,
++	0x2D, 0x20,
++	0x25, 0x20,
++	0x05, 0x20,
++	0x0D, 0x20,
+ 
+-0xB3, 0x68,
+-0x97, 0x25,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0x68,
++	0x97, 0x25,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0xC0, 0x33, 0xAF,
+-0x2F, 0xC0, 0x21, 0xC0,
++	0x33, 0xC0, 0x33, 0xAF,
++	0x2F, 0xC0, 0x21, 0xC0,
+ 
+-0x16, 0x42, 0x56, 0x9F,
+-0x3C, 0x27, 0x4F, 0xE9,
++	0x16, 0x42, 0x56, 0x9F,
++	0x3C, 0x27, 0x4F, 0xE9,
+ 
+-0x1E, 0x62, 0x57, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1E, 0x62, 0x57, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x21, 0x31, 0xB4,
+-0x2D, 0x21, 0x1A, 0xB4,
++	0x25, 0x21, 0x31, 0xB4,
++	0x2D, 0x21, 0x1A, 0xB4,
+ 
+-0x3F, 0x2F, 0x5D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3F, 0x2F, 0x5D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x33, 0x05,
+-0x00, 0xE0,
+-0x28, 0x19, 0x60, 0xEC,
++	0x33, 0x05,
++	0x00, 0xE0,
++	0x28, 0x19, 0x60, 0xEC,
+ 
+-0x0D, 0x21, 0x1A, 0xB6,
+-0x05, 0x21, 0x31, 0xB6,
++	0x0D, 0x21, 0x1A, 0xB6,
++	0x05, 0x21, 0x31, 0xB6,
+ 
+-0x37, 0x0F, 0x5C, 0x9F,
+-0x00, 0xE0,
+-0x2F, 0x20,
++	0x37, 0x0F, 0x5C, 0x9F,
++	0x00, 0xE0,
++	0x2F, 0x20,
+ 
+-0x23, 0x3B, 0x33, 0xAD,
+-0x1E, 0x26, 0x1E, 0xDF,
++	0x23, 0x3B, 0x33, 0xAD,
++	0x1E, 0x26, 0x1E, 0xDF,
+ 
+-0xA7, 0x1E, 0x4F, 0xE9,
+-0x17, 0x26, 0x16, 0xDF,
++	0xA7, 0x1E, 0x4F, 0xE9,
++	0x17, 0x26, 0x16, 0xDF,
+ 
+-0x2D, 0x20,
+-0x00, 0xE0,
+-0xA8, 0x3F, 0x4F, 0xE9,
++	0x2D, 0x20,
++	0x00, 0xE0,
++	0xA8, 0x3F, 0x4F, 0xE9,
+ 
+-0x2F, 0x2F, 0x1E, 0xAF,
+-0x25, 0x20,
+-0x00, 0xE0,
++	0x2F, 0x2F, 0x1E, 0xAF,
++	0x25, 0x20,
++	0x00, 0xE0,
+ 
+-0xA4, 0x16, 0x4F, 0xE9,
+-0x0F, 0xC0, 0x21, 0xC2,
++	0xA4, 0x16, 0x4F, 0xE9,
++	0x0F, 0xC0, 0x21, 0xC2,
+ 
+-0xA6, 0x80, 0x4F, 0xE9,
+-0x1F, 0x62, 0x57, 0x9F,
++	0xA6, 0x80, 0x4F, 0xE9,
++	0x1F, 0x62, 0x57, 0x9F,
+ 
+-0x0D, 0x20,
+-0x05, 0x20,
+-0x2F, 0xC0, 0x21, 0xC6,
++	0x0D, 0x20,
++	0x05, 0x20,
++	0x2F, 0xC0, 0x21, 0xC6,
+ 
+-0x3F, 0x2F, 0x5D, 0x9F,
+-0x00, 0xE0,
+-0x0F, 0x20,
++	0x3F, 0x2F, 0x5D, 0x9F,
++	0x00, 0xE0,
++	0x0F, 0x20,
+ 
+-0x17, 0x50, 0x56, 0x9F,
+-0xA5, 0x37, 0x4F, 0xE9,
++	0x17, 0x50, 0x56, 0x9F,
++	0xA5, 0x37, 0x4F, 0xE9,
+ 
+-0x06, 0xC0, 0x21, 0xC4,
+-0x0F, 0x17, 0x0F, 0xAF,
++	0x06, 0xC0, 0x21, 0xC4,
++	0x0F, 0x17, 0x0F, 0xAF,
+ 
+-0x37, 0x0F, 0x5C, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x37, 0x0F, 0x5C, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x2F, 0x20,
+-0x00, 0xE0,
+-0xA3, 0x80, 0x4F, 0xE9,
++	0x2F, 0x20,
++	0x00, 0xE0,
++	0xA3, 0x80, 0x4F, 0xE9,
+ 
+-0x06, 0x20,
+-0x00, 0xE0,
+-0x1F, 0x26, 0x1F, 0xDF,
++	0x06, 0x20,
++	0x00, 0xE0,
++	0x1F, 0x26, 0x1F, 0xDF,
+ 
+-0x17, 0x26, 0x17, 0xDF,
+-0x35, 0x17, 0x4F, 0xE9,
++	0x17, 0x26, 0x17, 0xDF,
++	0x35, 0x17, 0x4F, 0xE9,
+ 
+-0xA1, 0x1F, 0x4F, 0xE9,
+-0xA2, 0x3F, 0x4F, 0xE9,
++	0xA1, 0x1F, 0x4F, 0xE9,
++	0xA2, 0x3F, 0x4F, 0xE9,
+ 
+-0x06, 0x06, 0x1F, 0xAF,
+-0x39, 0x37, 0x4F, 0xE9,
++	0x06, 0x06, 0x1F, 0xAF,
++	0x39, 0x37, 0x4F, 0xE9,
+ 
+-0x2F, 0x2F, 0x17, 0xAF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x2F, 0x2F, 0x17, 0xAF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xA0, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA0, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x31, 0x80, 0x4F, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x80, 0x4F, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x57, 0x39, 0x20, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
++	0x57, 0x39, 0x20, 0xE9,
+ 
+-0x16, 0x28, 0x20, 0xE9,
+-0x1D, 0x3B, 0x20, 0xE9,
++	0x16, 0x28, 0x20, 0xE9,
++	0x1D, 0x3B, 0x20, 0xE9,
+ 
+-0x1E, 0x2B, 0x20, 0xE9,
+-0x2B, 0x32, 0x20, 0xE9,
++	0x1E, 0x2B, 0x20, 0xE9,
++	0x2B, 0x32, 0x20, 0xE9,
+ 
+-0x1C, 0x23, 0x20, 0xE9,
+-0x57, 0x36, 0x20, 0xE9,
++	0x1C, 0x23, 0x20, 0xE9,
++	0x57, 0x36, 0x20, 0xE9,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x40, 0x40, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x40, 0x40, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x90, 0xE2,
+-0x00, 0xE0,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x90, 0xE2,
++	0x00, 0xE0,
+ 
+-0x68, 0xFF, 0x20, 0xEA,
+-0x19, 0xC8, 0xC1, 0xCD,
++	0x68, 0xFF, 0x20, 0xEA,
++	0x19, 0xC8, 0xC1, 0xCD,
+ 
+-0x1F, 0xD7, 0x18, 0xBD,
+-0x3F, 0xD7, 0x22, 0xBD,
++	0x1F, 0xD7, 0x18, 0xBD,
++	0x3F, 0xD7, 0x22, 0xBD,
+ 
+-0x9F, 0x41, 0x49, 0xBD,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9F, 0x41, 0x49, 0xBD,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x25, 0x41, 0x49, 0xBD,
+-0x2D, 0x41, 0x51, 0xBD,
++	0x25, 0x41, 0x49, 0xBD,
++	0x2D, 0x41, 0x51, 0xBD,
+ 
+-0x0D, 0x80, 0x07, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x0D, 0x80, 0x07, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x35, 0x40, 0x48, 0xBD,
+-0x3D, 0x40, 0x50, 0xBD,
++	0x35, 0x40, 0x48, 0xBD,
++	0x3D, 0x40, 0x50, 0xBD,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x25, 0x30,
+-0x2D, 0x30,
++	0x00, 0x80, 0x00, 0xE8,
++	0x25, 0x30,
++	0x2D, 0x30,
+ 
+-0x35, 0x30,
+-0xB5, 0x30,
+-0xBD, 0x30,
+-0x3D, 0x30,
++	0x35, 0x30,
++	0xB5, 0x30,
++	0xBD, 0x30,
++	0x3D, 0x30,
+ 
+-0x9C, 0xA7, 0x5B, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x9C, 0xA7, 0x5B, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x67, 0xFF, 0x0A, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x67, 0xFF, 0x0A, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC9, 0x41, 0xC8, 0xEC,
+-0x42, 0xE1,
+-0x00, 0xE0,
++	0xC9, 0x41, 0xC8, 0xEC,
++	0x42, 0xE1,
++	0x00, 0xE0,
+ 
+-0x65, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x65, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xC8, 0x40, 0xC0, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC8, 0x40, 0xC0, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x62, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0x62, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+ };
+ 
+ static unsigned char warp_g400_t2gz[] = {
+ 
+-0x00, 0x8A, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x8A, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0A, 0x40, 0x50, 0xBF,
+-0x2A, 0x40, 0x60, 0xBF,
++	0x0A, 0x40, 0x50, 0xBF,
++	0x2A, 0x40, 0x60, 0xBF,
+ 
+-0x32, 0x41, 0x51, 0xBF,
+-0x3A, 0x41, 0x61, 0xBF,
++	0x32, 0x41, 0x51, 0xBF,
++	0x3A, 0x41, 0x61, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xD3, 0x6B,
+-0x00, 0x8A, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xD3, 0x6B,
++	0x00, 0x8A, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x23, 0x9F,
+-0x00, 0xE0,
+-0x51, 0x04,
++	0xAD, 0xEE, 0x23, 0x9F,
++	0x00, 0xE0,
++	0x51, 0x04,
+ 
+-0x90, 0xE2,
+-0x61, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x61, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x51, 0x41, 0xE0, 0xEC,
+-0x39, 0x67, 0xB1, 0xE8,
++	0x51, 0x41, 0xE0, 0xEC,
++	0x39, 0x67, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x63, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x63, 0xA0, 0xE8,
+ 
+-0x61, 0x41, 0xE0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x61, 0x41, 0xE0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x78, 0x80, 0x15, 0xEA,
+-0x10, 0x04,
+-0x20, 0x04,
++	0x78, 0x80, 0x15, 0xEA,
++	0x10, 0x04,
++	0x20, 0x04,
+ 
+-0x61, 0x51, 0xE0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x61, 0x51, 0xE0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x52, 0xBF,
+-0x0F, 0x52, 0xA0, 0xE8,
++	0x2A, 0x42, 0x52, 0xBF,
++	0x0F, 0x52, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x62, 0xBF,
+-0x1E, 0x51, 0x60, 0xEA,
++	0x1A, 0x42, 0x62, 0xBF,
++	0x1E, 0x51, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x0E, 0x61, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x0E, 0x61, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x50, 0xBD,
+-0x22, 0x40, 0x60, 0xBD,
++	0x32, 0x40, 0x50, 0xBD,
++	0x22, 0x40, 0x60, 0xBD,
+ 
+-0x12, 0x41, 0x51, 0xBD,
+-0x3A, 0x41, 0x61, 0xBD,
++	0x12, 0x41, 0x51, 0xBD,
++	0x3A, 0x41, 0x61, 0xBD,
+ 
+-0xBF, 0x2F, 0x0E, 0xBD,
+-0x97, 0xE2,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x0E, 0xBD,
++	0x97, 0xE2,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x35, 0x48, 0xB1, 0xE8,
+-0x3D, 0x59, 0xB1, 0xE8,
++	0x35, 0x48, 0xB1, 0xE8,
++	0x3D, 0x59, 0xB1, 0xE8,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x56, 0x31, 0x56, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x66, 0x31, 0x66, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x66, 0x31, 0x66, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x57, 0x39, 0x57, 0xBF,
+-0x67, 0x39, 0x67, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
++	0x67, 0x39, 0x67, 0xBF,
+ 
+-0x69, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x69, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x35, 0x00,
+-0x3D, 0x00,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x35, 0x00,
++	0x3D, 0x00,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0x8D, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0x8D, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x75, 0xF8, 0xEC,
+-0x35, 0x20,
+-0x3D, 0x20,
++	0x43, 0x75, 0xF8, 0xEC,
++	0x35, 0x20,
++	0x3D, 0x20,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x53, 0x53, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x53, 0x53, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x0E, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x0E, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x48, 0x35, 0x48, 0xBF,
+-0x58, 0x35, 0x58, 0xBF,
++	0x48, 0x35, 0x48, 0xBF,
++	0x58, 0x35, 0x58, 0xBF,
+ 
+-0x68, 0x35, 0x68, 0xBF,
+-0x49, 0x3D, 0x49, 0xBF,
++	0x68, 0x35, 0x68, 0xBF,
++	0x49, 0x3D, 0x49, 0xBF,
+ 
+-0x59, 0x3D, 0x59, 0xBF,
+-0x69, 0x3D, 0x69, 0xBF,
++	0x59, 0x3D, 0x59, 0xBF,
++	0x69, 0x3D, 0x69, 0xBF,
+ 
+-0x63, 0x63, 0x2D, 0xDF,
+-0x4D, 0x7D, 0xF8, 0xEC,
++	0x63, 0x63, 0x2D, 0xDF,
++	0x4D, 0x7D, 0xF8, 0xEC,
+ 
+-0x59, 0xE3,
+-0x00, 0xE0,
+-0xB8, 0x38, 0x33, 0xBF,
++	0x59, 0xE3,
++	0x00, 0xE0,
++	0xB8, 0x38, 0x33, 0xBF,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x18, 0x3A, 0x41, 0xE9,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x18, 0x3A, 0x41, 0xE9,
+ 
+-0x3F, 0x53, 0xA0, 0xE8,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x3F, 0x53, 0xA0, 0xE8,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x63, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x63, 0xA0, 0xE8,
+ 
+-0x50, 0x70, 0xF8, 0xEC,
+-0x2B, 0x50, 0x3C, 0xE9,
++	0x50, 0x70, 0xF8, 0xEC,
++	0x2B, 0x50, 0x3C, 0xE9,
+ 
+-0x1F, 0x0F, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x0F, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x59, 0x78, 0xF8, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0x59, 0x78, 0xF8, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x56, 0x3F, 0x56, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x56, 0x3F, 0x56, 0xDF,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x66, 0x3D, 0x66, 0xDF,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x66, 0x3D, 0x66, 0xDF,
+ 
+-0x1D, 0x32, 0x41, 0xE9,
+-0x67, 0x3D, 0x67, 0xDF,
++	0x1D, 0x32, 0x41, 0xE9,
++	0x67, 0x3D, 0x67, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3F, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3F, 0x57, 0xDF,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x59, 0x3F, 0x59, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x59, 0x3F, 0x59, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x69, 0x3D, 0x69, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x69, 0x3D, 0x69, 0xDF,
+ 
+-0x48, 0x37, 0x48, 0xDF,
+-0x58, 0x3F, 0x58, 0xDF,
++	0x48, 0x37, 0x48, 0xDF,
++	0x58, 0x3F, 0x58, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x68, 0x3D, 0x68, 0xDF,
+-0x49, 0x37, 0x49, 0xDF,
++	0x68, 0x3D, 0x68, 0xDF,
++	0x49, 0x37, 0x49, 0xDF,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x34, 0x80, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x34, 0x80, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x54, 0xB0,
+-0x02, 0x44, 0x64, 0xB0,
++	0x0A, 0x44, 0x54, 0xB0,
++	0x02, 0x44, 0x64, 0xB0,
+ 
+-0x2A, 0x44, 0x54, 0xB2,
+-0x1A, 0x44, 0x64, 0xB2,
++	0x2A, 0x44, 0x54, 0xB2,
++	0x1A, 0x44, 0x64, 0xB2,
+ 
+-0x25, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x25, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x3D, 0xCF, 0x74, 0xC2,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x3D, 0xCF, 0x74, 0xC2,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x2A, 0x44, 0x54, 0xB4,
+-0x1A, 0x44, 0x64, 0xB4,
++	0x2A, 0x44, 0x54, 0xB4,
++	0x1A, 0x44, 0x64, 0xB4,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x38, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x38, 0x3D, 0x20, 0xE9,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x2A, 0x46, 0x56, 0xBF,
+-0x1A, 0x46, 0x66, 0xBF,
++	0x2A, 0x46, 0x56, 0xBF,
++	0x1A, 0x46, 0x66, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x0A, 0x47, 0x57, 0xBF,
+-0x02, 0x47, 0x67, 0xBF,
++	0x0A, 0x47, 0x57, 0xBF,
++	0x02, 0x47, 0x67, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x53, 0xBF,
+-0x1A, 0x43, 0x63, 0xBF,
++	0x2A, 0x43, 0x53, 0xBF,
++	0x1A, 0x43, 0x63, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x48, 0x58, 0xBF,
+-0x02, 0x48, 0x68, 0xBF,
++	0x0A, 0x48, 0x58, 0xBF,
++	0x02, 0x48, 0x68, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x2A, 0x49, 0x59, 0xBF,
+-0x1A, 0x49, 0x69, 0xBF,
++	0x2A, 0x49, 0x59, 0xBF,
++	0x1A, 0x49, 0x69, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x82, 0x30, 0x57, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x82, 0x30, 0x57, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x83, 0x38, 0x57, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x83, 0x38, 0x57, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x84, 0x31, 0x5E, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x84, 0x31, 0x5E, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x85, 0x39, 0x5E, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x85, 0x39, 0x5E, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x87, 0x77, 0x57, 0xE9,
+-0x8B, 0x3E, 0xBF, 0xEA,
++	0x87, 0x77, 0x57, 0xE9,
++	0x8B, 0x3E, 0xBF, 0xEA,
+ 
+-0x80, 0x30, 0x57, 0xE9,
+-0x81, 0x38, 0x57, 0xE9,
++	0x80, 0x30, 0x57, 0xE9,
++	0x81, 0x38, 0x57, 0xE9,
+ 
+-0x82, 0x31, 0x57, 0xE9,
+-0x86, 0x78, 0x57, 0xE9,
++	0x82, 0x31, 0x57, 0xE9,
++	0x86, 0x78, 0x57, 0xE9,
+ 
+-0x83, 0x39, 0x57, 0xE9,
+-0x87, 0x79, 0x57, 0xE9,
++	0x83, 0x39, 0x57, 0xE9,
++	0x87, 0x79, 0x57, 0xE9,
+ 
+-0x30, 0x1F, 0x5F, 0xE9,
+-0x8A, 0x34, 0x20, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
++	0x8A, 0x34, 0x20, 0xE9,
+ 
+-0x8B, 0x3C, 0x20, 0xE9,
+-0x37, 0x50, 0x60, 0xBD,
++	0x8B, 0x3C, 0x20, 0xE9,
++	0x37, 0x50, 0x60, 0xBD,
+ 
+-0x57, 0x0D, 0x20, 0xE9,
+-0x35, 0x51, 0x61, 0xBD,
++	0x57, 0x0D, 0x20, 0xE9,
++	0x35, 0x51, 0x61, 0xBD,
+ 
+-0x2B, 0x50, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x50, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x0E, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x0E, 0x77,
+ 
+-0x24, 0x51, 0x20, 0xE9,
+-0x9F, 0xFF, 0x20, 0xEA,
++	0x24, 0x51, 0x20, 0xE9,
++	0x9F, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x0E, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x0E, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x0B, 0x46, 0xA0, 0xE8,
+-0x1B, 0x56, 0xA0, 0xE8,
++	0x0B, 0x46, 0xA0, 0xE8,
++	0x1B, 0x56, 0xA0, 0xE8,
+ 
+-0x2B, 0x66, 0xA0, 0xE8,
+-0x0C, 0x47, 0xA0, 0xE8,
++	0x2B, 0x66, 0xA0, 0xE8,
++	0x0C, 0x47, 0xA0, 0xE8,
+ 
+-0x1C, 0x57, 0xA0, 0xE8,
+-0x2C, 0x67, 0xA0, 0xE8,
++	0x1C, 0x57, 0xA0, 0xE8,
++	0x2C, 0x67, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x57, 0x80, 0x57, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x57, 0x80, 0x57, 0xCF,
+ 
+-0x66, 0x33, 0x66, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x66, 0x33, 0x66, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x67, 0x3B, 0x67, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x67, 0x3B, 0x67, 0xCF,
+ 
+-0x0B, 0x48, 0xA0, 0xE8,
+-0x1B, 0x58, 0xA0, 0xE8,
++	0x0B, 0x48, 0xA0, 0xE8,
++	0x1B, 0x58, 0xA0, 0xE8,
+ 
+-0x2B, 0x68, 0xA0, 0xE8,
+-0x0C, 0x49, 0xA0, 0xE8,
++	0x2B, 0x68, 0xA0, 0xE8,
++	0x0C, 0x49, 0xA0, 0xE8,
+ 
+-0x1C, 0x59, 0xA0, 0xE8,
+-0x2C, 0x69, 0xA0, 0xE8,
++	0x1C, 0x59, 0xA0, 0xE8,
++	0x2C, 0x69, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x34, 0xD7, 0x34, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x34, 0xD7, 0x34, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3C, 0xD7, 0x3C, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3C, 0xD7, 0x3C, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x34, 0x80, 0x34, 0xBD,
+-0x3C, 0x80, 0x3C, 0xBD,
++	0x34, 0x80, 0x34, 0xBD,
++	0x3C, 0x80, 0x3C, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x48, 0x80, 0x48, 0xCF,
+-0x59, 0x80, 0x59, 0xCF,
++	0x48, 0x80, 0x48, 0xCF,
++	0x59, 0x80, 0x59, 0xCF,
+ 
+-0x68, 0x33, 0x68, 0xCF,
+-0x49, 0x3B, 0x49, 0xCF,
++	0x68, 0x33, 0x68, 0xCF,
++	0x49, 0x3B, 0x49, 0xCF,
+ 
+-0xBE, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xBE, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x58, 0x33, 0x58, 0xCF,
+-0x69, 0x3B, 0x69, 0xCF,
++	0x58, 0x33, 0x58, 0xCF,
++	0x69, 0x3B, 0x69, 0xCF,
+ 
+-0x7D, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x7D, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_t2gza[] = {
+ 
+-0x00, 0x8A, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x8A, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0A, 0x40, 0x50, 0xBF,
+-0x2A, 0x40, 0x60, 0xBF,
++	0x0A, 0x40, 0x50, 0xBF,
++	0x2A, 0x40, 0x60, 0xBF,
+ 
+-0x32, 0x41, 0x51, 0xBF,
+-0x3A, 0x41, 0x61, 0xBF,
++	0x32, 0x41, 0x51, 0xBF,
++	0x3A, 0x41, 0x61, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xD3, 0x6B,
+-0x00, 0x8A, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xD3, 0x6B,
++	0x00, 0x8A, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x23, 0x9F,
+-0x00, 0xE0,
+-0x51, 0x04,
++	0xAD, 0xEE, 0x23, 0x9F,
++	0x00, 0xE0,
++	0x51, 0x04,
+ 
+-0x90, 0xE2,
+-0x61, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x61, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x51, 0x41, 0xE0, 0xEC,
+-0x39, 0x67, 0xB1, 0xE8,
++	0x51, 0x41, 0xE0, 0xEC,
++	0x39, 0x67, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x63, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x63, 0xA0, 0xE8,
+ 
+-0x61, 0x41, 0xE0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x61, 0x41, 0xE0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x7C, 0x80, 0x15, 0xEA,
+-0x10, 0x04,
+-0x20, 0x04,
++	0x7C, 0x80, 0x15, 0xEA,
++	0x10, 0x04,
++	0x20, 0x04,
+ 
+-0x61, 0x51, 0xE0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x61, 0x51, 0xE0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x52, 0xBF,
+-0x0F, 0x52, 0xA0, 0xE8,
++	0x2A, 0x42, 0x52, 0xBF,
++	0x0F, 0x52, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x62, 0xBF,
+-0x1E, 0x51, 0x60, 0xEA,
++	0x1A, 0x42, 0x62, 0xBF,
++	0x1E, 0x51, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x0E, 0x61, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x0E, 0x61, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x50, 0xBD,
+-0x22, 0x40, 0x60, 0xBD,
++	0x32, 0x40, 0x50, 0xBD,
++	0x22, 0x40, 0x60, 0xBD,
+ 
+-0x12, 0x41, 0x51, 0xBD,
+-0x3A, 0x41, 0x61, 0xBD,
++	0x12, 0x41, 0x51, 0xBD,
++	0x3A, 0x41, 0x61, 0xBD,
+ 
+-0xBF, 0x2F, 0x0E, 0xBD,
+-0x97, 0xE2,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x0E, 0xBD,
++	0x97, 0xE2,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x35, 0x48, 0xB1, 0xE8,
+-0x3D, 0x59, 0xB1, 0xE8,
++	0x35, 0x48, 0xB1, 0xE8,
++	0x3D, 0x59, 0xB1, 0xE8,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x56, 0x31, 0x56, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x66, 0x31, 0x66, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x66, 0x31, 0x66, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x57, 0x39, 0x57, 0xBF,
+-0x67, 0x39, 0x67, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
++	0x67, 0x39, 0x67, 0xBF,
+ 
+-0x6D, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x6D, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x35, 0x00,
+-0x3D, 0x00,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x35, 0x00,
++	0x3D, 0x00,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0x8D, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0x8D, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x75, 0xF8, 0xEC,
+-0x35, 0x20,
+-0x3D, 0x20,
++	0x43, 0x75, 0xF8, 0xEC,
++	0x35, 0x20,
++	0x3D, 0x20,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x53, 0x53, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x53, 0x53, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x0E, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x0E, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x48, 0x35, 0x48, 0xBF,
+-0x58, 0x35, 0x58, 0xBF,
++	0x48, 0x35, 0x48, 0xBF,
++	0x58, 0x35, 0x58, 0xBF,
+ 
+-0x68, 0x35, 0x68, 0xBF,
+-0x49, 0x3D, 0x49, 0xBF,
++	0x68, 0x35, 0x68, 0xBF,
++	0x49, 0x3D, 0x49, 0xBF,
+ 
+-0x59, 0x3D, 0x59, 0xBF,
+-0x69, 0x3D, 0x69, 0xBF,
++	0x59, 0x3D, 0x59, 0xBF,
++	0x69, 0x3D, 0x69, 0xBF,
+ 
+-0x63, 0x63, 0x2D, 0xDF,
+-0x4D, 0x7D, 0xF8, 0xEC,
++	0x63, 0x63, 0x2D, 0xDF,
++	0x4D, 0x7D, 0xF8, 0xEC,
+ 
+-0x59, 0xE3,
+-0x00, 0xE0,
+-0xB8, 0x38, 0x33, 0xBF,
++	0x59, 0xE3,
++	0x00, 0xE0,
++	0xB8, 0x38, 0x33, 0xBF,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x18, 0x3A, 0x41, 0xE9,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x18, 0x3A, 0x41, 0xE9,
+ 
+-0x3F, 0x53, 0xA0, 0xE8,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x3F, 0x53, 0xA0, 0xE8,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x63, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x63, 0xA0, 0xE8,
+ 
+-0x50, 0x70, 0xF8, 0xEC,
+-0x2B, 0x50, 0x3C, 0xE9,
++	0x50, 0x70, 0xF8, 0xEC,
++	0x2B, 0x50, 0x3C, 0xE9,
+ 
+-0x1F, 0x0F, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x0F, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x59, 0x78, 0xF8, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0x59, 0x78, 0xF8, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x56, 0x3F, 0x56, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x56, 0x3F, 0x56, 0xDF,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x66, 0x3D, 0x66, 0xDF,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x66, 0x3D, 0x66, 0xDF,
+ 
+-0x1D, 0x32, 0x41, 0xE9,
+-0x67, 0x3D, 0x67, 0xDF,
++	0x1D, 0x32, 0x41, 0xE9,
++	0x67, 0x3D, 0x67, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3F, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3F, 0x57, 0xDF,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x59, 0x3F, 0x59, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x59, 0x3F, 0x59, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x69, 0x3D, 0x69, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x69, 0x3D, 0x69, 0xDF,
+ 
+-0x48, 0x37, 0x48, 0xDF,
+-0x58, 0x3F, 0x58, 0xDF,
++	0x48, 0x37, 0x48, 0xDF,
++	0x58, 0x3F, 0x58, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x68, 0x3D, 0x68, 0xDF,
+-0x49, 0x37, 0x49, 0xDF,
++	0x68, 0x3D, 0x68, 0xDF,
++	0x49, 0x37, 0x49, 0xDF,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x34, 0x80, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x34, 0x80, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x54, 0xB0,
+-0x02, 0x44, 0x64, 0xB0,
++	0x0A, 0x44, 0x54, 0xB0,
++	0x02, 0x44, 0x64, 0xB0,
+ 
+-0x2A, 0x44, 0x54, 0xB2,
+-0x1A, 0x44, 0x64, 0xB2,
++	0x2A, 0x44, 0x54, 0xB2,
++	0x1A, 0x44, 0x64, 0xB2,
+ 
+-0x29, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x29, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x0F, 0xCF, 0x74, 0xC6,
+-0x3D, 0xCF, 0x74, 0xC2,
++	0x0F, 0xCF, 0x74, 0xC6,
++	0x3D, 0xCF, 0x74, 0xC2,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9C, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9C, 0x0F, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x54, 0xB4,
+-0x02, 0x44, 0x64, 0xB4,
++	0x0A, 0x44, 0x54, 0xB4,
++	0x02, 0x44, 0x64, 0xB4,
+ 
+-0x2A, 0x44, 0x54, 0xB6,
+-0x1A, 0x44, 0x64, 0xB6,
++	0x2A, 0x44, 0x54, 0xB6,
++	0x1A, 0x44, 0x64, 0xB6,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x38, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x38, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x20,
+-0x02, 0x20,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0A, 0x20,
++	0x02, 0x20,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x0A, 0x47, 0x57, 0xBF,
+-0x02, 0x47, 0x67, 0xBF,
++	0x0A, 0x47, 0x57, 0xBF,
++	0x02, 0x47, 0x67, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x46, 0x56, 0xBF,
+-0x1A, 0x46, 0x66, 0xBF,
++	0x2A, 0x46, 0x56, 0xBF,
++	0x1A, 0x46, 0x66, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x36, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x36, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x37, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x37, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x53, 0xBF,
+-0x1A, 0x43, 0x63, 0xBF,
++	0x2A, 0x43, 0x53, 0xBF,
++	0x1A, 0x43, 0x63, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x9D, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x9D, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x9E, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x9E, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x48, 0x58, 0xBF,
+-0x02, 0x48, 0x68, 0xBF,
++	0x0A, 0x48, 0x58, 0xBF,
++	0x02, 0x48, 0x68, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x2A, 0x49, 0x59, 0xBF,
+-0x1A, 0x49, 0x69, 0xBF,
++	0x2A, 0x49, 0x59, 0xBF,
++	0x1A, 0x49, 0x69, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x82, 0x30, 0x57, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x82, 0x30, 0x57, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x83, 0x38, 0x57, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x83, 0x38, 0x57, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x84, 0x31, 0x5E, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x84, 0x31, 0x5E, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x85, 0x39, 0x5E, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x85, 0x39, 0x5E, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x87, 0x77, 0x57, 0xE9,
+-0x8B, 0x3E, 0xBF, 0xEA,
++	0x87, 0x77, 0x57, 0xE9,
++	0x8B, 0x3E, 0xBF, 0xEA,
+ 
+-0x80, 0x30, 0x57, 0xE9,
+-0x81, 0x38, 0x57, 0xE9,
++	0x80, 0x30, 0x57, 0xE9,
++	0x81, 0x38, 0x57, 0xE9,
+ 
+-0x82, 0x31, 0x57, 0xE9,
+-0x86, 0x78, 0x57, 0xE9,
++	0x82, 0x31, 0x57, 0xE9,
++	0x86, 0x78, 0x57, 0xE9,
+ 
+-0x83, 0x39, 0x57, 0xE9,
+-0x87, 0x79, 0x57, 0xE9,
++	0x83, 0x39, 0x57, 0xE9,
++	0x87, 0x79, 0x57, 0xE9,
+ 
+-0x30, 0x1F, 0x5F, 0xE9,
+-0x8A, 0x34, 0x20, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
++	0x8A, 0x34, 0x20, 0xE9,
+ 
+-0x8B, 0x3C, 0x20, 0xE9,
+-0x37, 0x50, 0x60, 0xBD,
++	0x8B, 0x3C, 0x20, 0xE9,
++	0x37, 0x50, 0x60, 0xBD,
+ 
+-0x57, 0x0D, 0x20, 0xE9,
+-0x35, 0x51, 0x61, 0xBD,
++	0x57, 0x0D, 0x20, 0xE9,
++	0x35, 0x51, 0x61, 0xBD,
+ 
+-0x2B, 0x50, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x50, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x0E, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x0E, 0x77,
+ 
+-0x24, 0x51, 0x20, 0xE9,
+-0x9B, 0xFF, 0x20, 0xEA,
++	0x24, 0x51, 0x20, 0xE9,
++	0x9B, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x0E, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x0E, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x0B, 0x46, 0xA0, 0xE8,
+-0x1B, 0x56, 0xA0, 0xE8,
++	0x0B, 0x46, 0xA0, 0xE8,
++	0x1B, 0x56, 0xA0, 0xE8,
+ 
+-0x2B, 0x66, 0xA0, 0xE8,
+-0x0C, 0x47, 0xA0, 0xE8,
++	0x2B, 0x66, 0xA0, 0xE8,
++	0x0C, 0x47, 0xA0, 0xE8,
+ 
+-0x1C, 0x57, 0xA0, 0xE8,
+-0x2C, 0x67, 0xA0, 0xE8,
++	0x1C, 0x57, 0xA0, 0xE8,
++	0x2C, 0x67, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x57, 0x80, 0x57, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x57, 0x80, 0x57, 0xCF,
+ 
+-0x66, 0x33, 0x66, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x66, 0x33, 0x66, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x67, 0x3B, 0x67, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x67, 0x3B, 0x67, 0xCF,
+ 
+-0x0B, 0x48, 0xA0, 0xE8,
+-0x1B, 0x58, 0xA0, 0xE8,
++	0x0B, 0x48, 0xA0, 0xE8,
++	0x1B, 0x58, 0xA0, 0xE8,
+ 
+-0x2B, 0x68, 0xA0, 0xE8,
+-0x0C, 0x49, 0xA0, 0xE8,
++	0x2B, 0x68, 0xA0, 0xE8,
++	0x0C, 0x49, 0xA0, 0xE8,
+ 
+-0x1C, 0x59, 0xA0, 0xE8,
+-0x2C, 0x69, 0xA0, 0xE8,
++	0x1C, 0x59, 0xA0, 0xE8,
++	0x2C, 0x69, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x34, 0xD7, 0x34, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x34, 0xD7, 0x34, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3C, 0xD7, 0x3C, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3C, 0xD7, 0x3C, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x34, 0x80, 0x34, 0xBD,
+-0x3C, 0x80, 0x3C, 0xBD,
++	0x34, 0x80, 0x34, 0xBD,
++	0x3C, 0x80, 0x3C, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x48, 0x80, 0x48, 0xCF,
+-0x59, 0x80, 0x59, 0xCF,
++	0x48, 0x80, 0x48, 0xCF,
++	0x59, 0x80, 0x59, 0xCF,
+ 
+-0x68, 0x33, 0x68, 0xCF,
+-0x49, 0x3B, 0x49, 0xCF,
++	0x68, 0x33, 0x68, 0xCF,
++	0x49, 0x3B, 0x49, 0xCF,
+ 
+-0xBA, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xBA, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x58, 0x33, 0x58, 0xCF,
+-0x69, 0x3B, 0x69, 0xCF,
++	0x58, 0x33, 0x58, 0xCF,
++	0x69, 0x3B, 0x69, 0xCF,
+ 
+-0x79, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x79, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_t2gzaf[] = {
+ 
+-0x00, 0x8A, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x8A, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0A, 0x40, 0x50, 0xBF,
+-0x2A, 0x40, 0x60, 0xBF,
++	0x0A, 0x40, 0x50, 0xBF,
++	0x2A, 0x40, 0x60, 0xBF,
+ 
+-0x32, 0x41, 0x51, 0xBF,
+-0x3A, 0x41, 0x61, 0xBF,
++	0x32, 0x41, 0x51, 0xBF,
++	0x3A, 0x41, 0x61, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xD3, 0x6B,
+-0x00, 0x8A, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xD3, 0x6B,
++	0x00, 0x8A, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x23, 0x9F,
+-0x00, 0xE0,
+-0x51, 0x04,
++	0xAD, 0xEE, 0x23, 0x9F,
++	0x00, 0xE0,
++	0x51, 0x04,
+ 
+-0x90, 0xE2,
+-0x61, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x61, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x51, 0x41, 0xE0, 0xEC,
+-0x39, 0x67, 0xB1, 0xE8,
++	0x51, 0x41, 0xE0, 0xEC,
++	0x39, 0x67, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x63, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x63, 0xA0, 0xE8,
+ 
+-0x61, 0x41, 0xE0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x61, 0x41, 0xE0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x81, 0x80, 0x15, 0xEA,
+-0x10, 0x04,
+-0x20, 0x04,
++	0x81, 0x80, 0x15, 0xEA,
++	0x10, 0x04,
++	0x20, 0x04,
+ 
+-0x61, 0x51, 0xE0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x61, 0x51, 0xE0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x52, 0xBF,
+-0x0F, 0x52, 0xA0, 0xE8,
++	0x2A, 0x42, 0x52, 0xBF,
++	0x0F, 0x52, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x62, 0xBF,
+-0x1E, 0x51, 0x60, 0xEA,
++	0x1A, 0x42, 0x62, 0xBF,
++	0x1E, 0x51, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x0E, 0x61, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x0E, 0x61, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x50, 0xBD,
+-0x22, 0x40, 0x60, 0xBD,
++	0x32, 0x40, 0x50, 0xBD,
++	0x22, 0x40, 0x60, 0xBD,
+ 
+-0x12, 0x41, 0x51, 0xBD,
+-0x3A, 0x41, 0x61, 0xBD,
++	0x12, 0x41, 0x51, 0xBD,
++	0x3A, 0x41, 0x61, 0xBD,
+ 
+-0xBF, 0x2F, 0x0E, 0xBD,
+-0x97, 0xE2,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x0E, 0xBD,
++	0x97, 0xE2,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x35, 0x48, 0xB1, 0xE8,
+-0x3D, 0x59, 0xB1, 0xE8,
++	0x35, 0x48, 0xB1, 0xE8,
++	0x3D, 0x59, 0xB1, 0xE8,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x56, 0x31, 0x56, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x66, 0x31, 0x66, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x66, 0x31, 0x66, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x57, 0x39, 0x57, 0xBF,
+-0x67, 0x39, 0x67, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
++	0x67, 0x39, 0x67, 0xBF,
+ 
+-0x72, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x72, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x35, 0x00,
+-0x3D, 0x00,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x35, 0x00,
++	0x3D, 0x00,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0x8D, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0x8D, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x75, 0xF8, 0xEC,
+-0x35, 0x20,
+-0x3D, 0x20,
++	0x43, 0x75, 0xF8, 0xEC,
++	0x35, 0x20,
++	0x3D, 0x20,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x53, 0x53, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x53, 0x53, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x0E, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x0E, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x48, 0x35, 0x48, 0xBF,
+-0x58, 0x35, 0x58, 0xBF,
++	0x48, 0x35, 0x48, 0xBF,
++	0x58, 0x35, 0x58, 0xBF,
+ 
+-0x68, 0x35, 0x68, 0xBF,
+-0x49, 0x3D, 0x49, 0xBF,
++	0x68, 0x35, 0x68, 0xBF,
++	0x49, 0x3D, 0x49, 0xBF,
+ 
+-0x59, 0x3D, 0x59, 0xBF,
+-0x69, 0x3D, 0x69, 0xBF,
++	0x59, 0x3D, 0x59, 0xBF,
++	0x69, 0x3D, 0x69, 0xBF,
+ 
+-0x63, 0x63, 0x2D, 0xDF,
+-0x4D, 0x7D, 0xF8, 0xEC,
++	0x63, 0x63, 0x2D, 0xDF,
++	0x4D, 0x7D, 0xF8, 0xEC,
+ 
+-0x59, 0xE3,
+-0x00, 0xE0,
+-0xB8, 0x38, 0x33, 0xBF,
++	0x59, 0xE3,
++	0x00, 0xE0,
++	0xB8, 0x38, 0x33, 0xBF,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x18, 0x3A, 0x41, 0xE9,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x18, 0x3A, 0x41, 0xE9,
+ 
+-0x3F, 0x53, 0xA0, 0xE8,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x3F, 0x53, 0xA0, 0xE8,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x63, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x63, 0xA0, 0xE8,
+ 
+-0x50, 0x70, 0xF8, 0xEC,
+-0x2B, 0x50, 0x3C, 0xE9,
++	0x50, 0x70, 0xF8, 0xEC,
++	0x2B, 0x50, 0x3C, 0xE9,
+ 
+-0x1F, 0x0F, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x0F, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x59, 0x78, 0xF8, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0x59, 0x78, 0xF8, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x56, 0x3F, 0x56, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x56, 0x3F, 0x56, 0xDF,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x66, 0x3D, 0x66, 0xDF,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x66, 0x3D, 0x66, 0xDF,
+ 
+-0x1D, 0x32, 0x41, 0xE9,
+-0x67, 0x3D, 0x67, 0xDF,
++	0x1D, 0x32, 0x41, 0xE9,
++	0x67, 0x3D, 0x67, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3F, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3F, 0x57, 0xDF,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x59, 0x3F, 0x59, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x59, 0x3F, 0x59, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x69, 0x3D, 0x69, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x69, 0x3D, 0x69, 0xDF,
+ 
+-0x48, 0x37, 0x48, 0xDF,
+-0x58, 0x3F, 0x58, 0xDF,
++	0x48, 0x37, 0x48, 0xDF,
++	0x58, 0x3F, 0x58, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x68, 0x3D, 0x68, 0xDF,
+-0x49, 0x37, 0x49, 0xDF,
++	0x68, 0x3D, 0x68, 0xDF,
++	0x49, 0x37, 0x49, 0xDF,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x54, 0xB0,
+-0x02, 0x44, 0x64, 0xB0,
++	0x0A, 0x44, 0x54, 0xB0,
++	0x02, 0x44, 0x64, 0xB0,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x34, 0x37, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB2,
+-0x1A, 0x44, 0x64, 0xB2,
++	0x2A, 0x44, 0x54, 0xB2,
++	0x1A, 0x44, 0x64, 0xB2,
+ 
+-0x2E, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x2E, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x3D, 0xCF, 0x74, 0xC2,
+-0x0F, 0xCF, 0x74, 0xC6,
++	0x3D, 0xCF, 0x74, 0xC2,
++	0x0F, 0xCF, 0x74, 0xC6,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9C, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9C, 0x0F, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x54, 0xB4,
+-0x02, 0x44, 0x64, 0xB4,
++	0x0A, 0x44, 0x54, 0xB4,
++	0x02, 0x44, 0x64, 0xB4,
+ 
+-0x2A, 0x44, 0x54, 0xB6,
+-0x1A, 0x44, 0x64, 0xB6,
++	0x2A, 0x44, 0x54, 0xB6,
++	0x1A, 0x44, 0x64, 0xB6,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x38, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x38, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x20,
+-0x02, 0x20,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0A, 0x20,
++	0x02, 0x20,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x3D, 0xCF, 0x75, 0xC6,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3D, 0xCF, 0x75, 0xC6,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x0A, 0x45, 0x55, 0xB6,
+-0x02, 0x45, 0x65, 0xB6,
++	0x0A, 0x45, 0x55, 0xB6,
++	0x02, 0x45, 0x65, 0xB6,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x3D, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x31, 0x3D, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x2A, 0x46, 0x56, 0xBF,
+-0x1A, 0x46, 0x66, 0xBF,
++	0x2A, 0x46, 0x56, 0xBF,
++	0x1A, 0x46, 0x66, 0xBF,
+ 
+-0x0A, 0x47, 0x57, 0xBF,
+-0x02, 0x47, 0x67, 0xBF,
++	0x0A, 0x47, 0x57, 0xBF,
++	0x02, 0x47, 0x67, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x38, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9D, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9D, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x9E, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x9E, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x53, 0xBF,
+-0x1A, 0x43, 0x63, 0xBF,
++	0x2A, 0x43, 0x53, 0xBF,
++	0x1A, 0x43, 0x63, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x35, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x35, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x39, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x39, 0x38, 0x4F, 0xE9,
+ 
+-0x0A, 0x48, 0x58, 0xBF,
+-0x02, 0x48, 0x68, 0xBF,
++	0x0A, 0x48, 0x58, 0xBF,
++	0x02, 0x48, 0x68, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x2A, 0x49, 0x59, 0xBF,
+-0x1A, 0x49, 0x69, 0xBF,
++	0x2A, 0x49, 0x59, 0xBF,
++	0x1A, 0x49, 0x69, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x82, 0x30, 0x57, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x82, 0x30, 0x57, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x83, 0x38, 0x57, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x83, 0x38, 0x57, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x84, 0x31, 0x5E, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x84, 0x31, 0x5E, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x85, 0x39, 0x5E, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x85, 0x39, 0x5E, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x87, 0x77, 0x57, 0xE9,
+-0x8B, 0x3E, 0xBF, 0xEA,
++	0x87, 0x77, 0x57, 0xE9,
++	0x8B, 0x3E, 0xBF, 0xEA,
+ 
+-0x80, 0x30, 0x57, 0xE9,
+-0x81, 0x38, 0x57, 0xE9,
++	0x80, 0x30, 0x57, 0xE9,
++	0x81, 0x38, 0x57, 0xE9,
+ 
+-0x82, 0x31, 0x57, 0xE9,
+-0x86, 0x78, 0x57, 0xE9,
++	0x82, 0x31, 0x57, 0xE9,
++	0x86, 0x78, 0x57, 0xE9,
+ 
+-0x83, 0x39, 0x57, 0xE9,
+-0x87, 0x79, 0x57, 0xE9,
++	0x83, 0x39, 0x57, 0xE9,
++	0x87, 0x79, 0x57, 0xE9,
+ 
+-0x30, 0x1F, 0x5F, 0xE9,
+-0x8A, 0x34, 0x20, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
++	0x8A, 0x34, 0x20, 0xE9,
+ 
+-0x8B, 0x3C, 0x20, 0xE9,
+-0x37, 0x50, 0x60, 0xBD,
++	0x8B, 0x3C, 0x20, 0xE9,
++	0x37, 0x50, 0x60, 0xBD,
+ 
+-0x57, 0x0D, 0x20, 0xE9,
+-0x35, 0x51, 0x61, 0xBD,
++	0x57, 0x0D, 0x20, 0xE9,
++	0x35, 0x51, 0x61, 0xBD,
+ 
+-0x2B, 0x50, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x50, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x0E, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x0E, 0x77,
+ 
+-0x24, 0x51, 0x20, 0xE9,
+-0x96, 0xFF, 0x20, 0xEA,
++	0x24, 0x51, 0x20, 0xE9,
++	0x96, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x0E, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x0E, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x0B, 0x46, 0xA0, 0xE8,
+-0x1B, 0x56, 0xA0, 0xE8,
++	0x0B, 0x46, 0xA0, 0xE8,
++	0x1B, 0x56, 0xA0, 0xE8,
+ 
+-0x2B, 0x66, 0xA0, 0xE8,
+-0x0C, 0x47, 0xA0, 0xE8,
++	0x2B, 0x66, 0xA0, 0xE8,
++	0x0C, 0x47, 0xA0, 0xE8,
+ 
+-0x1C, 0x57, 0xA0, 0xE8,
+-0x2C, 0x67, 0xA0, 0xE8,
++	0x1C, 0x57, 0xA0, 0xE8,
++	0x2C, 0x67, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x57, 0x80, 0x57, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x57, 0x80, 0x57, 0xCF,
+ 
+-0x66, 0x33, 0x66, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x66, 0x33, 0x66, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x67, 0x3B, 0x67, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x67, 0x3B, 0x67, 0xCF,
+ 
+-0x0B, 0x48, 0xA0, 0xE8,
+-0x1B, 0x58, 0xA0, 0xE8,
++	0x0B, 0x48, 0xA0, 0xE8,
++	0x1B, 0x58, 0xA0, 0xE8,
+ 
+-0x2B, 0x68, 0xA0, 0xE8,
+-0x0C, 0x49, 0xA0, 0xE8,
++	0x2B, 0x68, 0xA0, 0xE8,
++	0x0C, 0x49, 0xA0, 0xE8,
+ 
+-0x1C, 0x59, 0xA0, 0xE8,
+-0x2C, 0x69, 0xA0, 0xE8,
++	0x1C, 0x59, 0xA0, 0xE8,
++	0x2C, 0x69, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x34, 0xD7, 0x34, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x34, 0xD7, 0x34, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3C, 0xD7, 0x3C, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3C, 0xD7, 0x3C, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x34, 0x80, 0x34, 0xBD,
+-0x3C, 0x80, 0x3C, 0xBD,
++	0x34, 0x80, 0x34, 0xBD,
++	0x3C, 0x80, 0x3C, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x48, 0x80, 0x48, 0xCF,
+-0x59, 0x80, 0x59, 0xCF,
++	0x48, 0x80, 0x48, 0xCF,
++	0x59, 0x80, 0x59, 0xCF,
+ 
+-0x68, 0x33, 0x68, 0xCF,
+-0x49, 0x3B, 0x49, 0xCF,
++	0x68, 0x33, 0x68, 0xCF,
++	0x49, 0x3B, 0x49, 0xCF,
+ 
+-0xB5, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB5, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x58, 0x33, 0x58, 0xCF,
+-0x69, 0x3B, 0x69, 0xCF,
++	0x58, 0x33, 0x58, 0xCF,
++	0x69, 0x3B, 0x69, 0xCF,
+ 
+-0x74, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x74, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_t2gzf[] = {
+ 
+-0x00, 0x8A, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x8A, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0A, 0x40, 0x50, 0xBF,
+-0x2A, 0x40, 0x60, 0xBF,
++	0x0A, 0x40, 0x50, 0xBF,
++	0x2A, 0x40, 0x60, 0xBF,
+ 
+-0x32, 0x41, 0x51, 0xBF,
+-0x3A, 0x41, 0x61, 0xBF,
++	0x32, 0x41, 0x51, 0xBF,
++	0x3A, 0x41, 0x61, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xD3, 0x6B,
+-0x00, 0x8A, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xD3, 0x6B,
++	0x00, 0x8A, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x23, 0x9F,
+-0x00, 0xE0,
+-0x51, 0x04,
++	0xAD, 0xEE, 0x23, 0x9F,
++	0x00, 0xE0,
++	0x51, 0x04,
+ 
+-0x90, 0xE2,
+-0x61, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x61, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x51, 0x41, 0xE0, 0xEC,
+-0x39, 0x67, 0xB1, 0xE8,
++	0x51, 0x41, 0xE0, 0xEC,
++	0x39, 0x67, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x63, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x63, 0xA0, 0xE8,
+ 
+-0x61, 0x41, 0xE0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x61, 0x41, 0xE0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x7D, 0x80, 0x15, 0xEA,
+-0x10, 0x04,
+-0x20, 0x04,
++	0x7D, 0x80, 0x15, 0xEA,
++	0x10, 0x04,
++	0x20, 0x04,
+ 
+-0x61, 0x51, 0xE0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x61, 0x51, 0xE0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x52, 0xBF,
+-0x0F, 0x52, 0xA0, 0xE8,
++	0x2A, 0x42, 0x52, 0xBF,
++	0x0F, 0x52, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x62, 0xBF,
+-0x1E, 0x51, 0x60, 0xEA,
++	0x1A, 0x42, 0x62, 0xBF,
++	0x1E, 0x51, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x0E, 0x61, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x0E, 0x61, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x50, 0xBD,
+-0x22, 0x40, 0x60, 0xBD,
++	0x32, 0x40, 0x50, 0xBD,
++	0x22, 0x40, 0x60, 0xBD,
+ 
+-0x12, 0x41, 0x51, 0xBD,
+-0x3A, 0x41, 0x61, 0xBD,
++	0x12, 0x41, 0x51, 0xBD,
++	0x3A, 0x41, 0x61, 0xBD,
+ 
+-0xBF, 0x2F, 0x0E, 0xBD,
+-0x97, 0xE2,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x0E, 0xBD,
++	0x97, 0xE2,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x35, 0x48, 0xB1, 0xE8,
+-0x3D, 0x59, 0xB1, 0xE8,
++	0x35, 0x48, 0xB1, 0xE8,
++	0x3D, 0x59, 0xB1, 0xE8,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x56, 0x31, 0x56, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x66, 0x31, 0x66, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x66, 0x31, 0x66, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x57, 0x39, 0x57, 0xBF,
+-0x67, 0x39, 0x67, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
++	0x67, 0x39, 0x67, 0xBF,
+ 
+-0x6E, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x6E, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x35, 0x00,
+-0x3D, 0x00,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x35, 0x00,
++	0x3D, 0x00,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0x8D, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0x8D, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x75, 0xF8, 0xEC,
+-0x35, 0x20,
+-0x3D, 0x20,
++	0x43, 0x75, 0xF8, 0xEC,
++	0x35, 0x20,
++	0x3D, 0x20,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x53, 0x53, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x53, 0x53, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x0E, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x0E, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x48, 0x35, 0x48, 0xBF,
+-0x58, 0x35, 0x58, 0xBF,
++	0x48, 0x35, 0x48, 0xBF,
++	0x58, 0x35, 0x58, 0xBF,
+ 
+-0x68, 0x35, 0x68, 0xBF,
+-0x49, 0x3D, 0x49, 0xBF,
++	0x68, 0x35, 0x68, 0xBF,
++	0x49, 0x3D, 0x49, 0xBF,
+ 
+-0x59, 0x3D, 0x59, 0xBF,
+-0x69, 0x3D, 0x69, 0xBF,
++	0x59, 0x3D, 0x59, 0xBF,
++	0x69, 0x3D, 0x69, 0xBF,
+ 
+-0x63, 0x63, 0x2D, 0xDF,
+-0x4D, 0x7D, 0xF8, 0xEC,
++	0x63, 0x63, 0x2D, 0xDF,
++	0x4D, 0x7D, 0xF8, 0xEC,
+ 
+-0x59, 0xE3,
+-0x00, 0xE0,
+-0xB8, 0x38, 0x33, 0xBF,
++	0x59, 0xE3,
++	0x00, 0xE0,
++	0xB8, 0x38, 0x33, 0xBF,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x18, 0x3A, 0x41, 0xE9,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x18, 0x3A, 0x41, 0xE9,
+ 
+-0x3F, 0x53, 0xA0, 0xE8,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x3F, 0x53, 0xA0, 0xE8,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x63, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x63, 0xA0, 0xE8,
+ 
+-0x50, 0x70, 0xF8, 0xEC,
+-0x2B, 0x50, 0x3C, 0xE9,
++	0x50, 0x70, 0xF8, 0xEC,
++	0x2B, 0x50, 0x3C, 0xE9,
+ 
+-0x1F, 0x0F, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x0F, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x59, 0x78, 0xF8, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0x59, 0x78, 0xF8, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x56, 0x3F, 0x56, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x56, 0x3F, 0x56, 0xDF,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x66, 0x3D, 0x66, 0xDF,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x66, 0x3D, 0x66, 0xDF,
+ 
+-0x1D, 0x32, 0x41, 0xE9,
+-0x67, 0x3D, 0x67, 0xDF,
++	0x1D, 0x32, 0x41, 0xE9,
++	0x67, 0x3D, 0x67, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3F, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3F, 0x57, 0xDF,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x59, 0x3F, 0x59, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x59, 0x3F, 0x59, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x69, 0x3D, 0x69, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x69, 0x3D, 0x69, 0xDF,
+ 
+-0x48, 0x37, 0x48, 0xDF,
+-0x58, 0x3F, 0x58, 0xDF,
++	0x48, 0x37, 0x48, 0xDF,
++	0x58, 0x3F, 0x58, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x68, 0x3D, 0x68, 0xDF,
+-0x49, 0x37, 0x49, 0xDF,
++	0x68, 0x3D, 0x68, 0xDF,
++	0x49, 0x37, 0x49, 0xDF,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x34, 0x80, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x34, 0x80, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0F, 0xCF, 0x75, 0xC6,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x0F, 0xCF, 0x75, 0xC6,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x54, 0xB0,
+-0x02, 0x44, 0x64, 0xB0,
++	0x0A, 0x44, 0x54, 0xB0,
++	0x02, 0x44, 0x64, 0xB0,
+ 
+-0x2A, 0x44, 0x54, 0xB2,
+-0x1A, 0x44, 0x64, 0xB2,
++	0x2A, 0x44, 0x54, 0xB2,
++	0x1A, 0x44, 0x64, 0xB2,
+ 
+-0x28, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x28, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x3D, 0xCF, 0x74, 0xC2,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x3D, 0xCF, 0x74, 0xC2,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x31, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x31, 0x0F, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x54, 0xB4,
+-0x02, 0x44, 0x64, 0xB4,
++	0x0A, 0x44, 0x54, 0xB4,
++	0x02, 0x44, 0x64, 0xB4,
+ 
+-0x2A, 0x45, 0x55, 0xB6,
+-0x1A, 0x45, 0x65, 0xB6,
++	0x2A, 0x45, 0x55, 0xB6,
++	0x1A, 0x45, 0x65, 0xB6,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x38, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x38, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x20,
+-0x02, 0x20,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0A, 0x20,
++	0x02, 0x20,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x0A, 0x47, 0x57, 0xBF,
+-0x02, 0x47, 0x67, 0xBF,
++	0x0A, 0x47, 0x57, 0xBF,
++	0x02, 0x47, 0x67, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x46, 0x56, 0xBF,
+-0x1A, 0x46, 0x66, 0xBF,
++	0x2A, 0x46, 0x56, 0xBF,
++	0x1A, 0x46, 0x66, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x36, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x36, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x37, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x37, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x53, 0xBF,
+-0x1A, 0x43, 0x63, 0xBF,
++	0x2A, 0x43, 0x53, 0xBF,
++	0x1A, 0x43, 0x63, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x35, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x35, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x39, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x39, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x48, 0x58, 0xBF,
+-0x02, 0x48, 0x68, 0xBF,
++	0x0A, 0x48, 0x58, 0xBF,
++	0x02, 0x48, 0x68, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x2A, 0x49, 0x59, 0xBF,
+-0x1A, 0x49, 0x69, 0xBF,
++	0x2A, 0x49, 0x59, 0xBF,
++	0x1A, 0x49, 0x69, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x82, 0x30, 0x57, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x82, 0x30, 0x57, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x83, 0x38, 0x57, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x83, 0x38, 0x57, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x84, 0x31, 0x5E, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x84, 0x31, 0x5E, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x85, 0x39, 0x5E, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x85, 0x39, 0x5E, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x87, 0x77, 0x57, 0xE9,
+-0x8B, 0x3E, 0xBF, 0xEA,
++	0x87, 0x77, 0x57, 0xE9,
++	0x8B, 0x3E, 0xBF, 0xEA,
+ 
+-0x80, 0x30, 0x57, 0xE9,
+-0x81, 0x38, 0x57, 0xE9,
++	0x80, 0x30, 0x57, 0xE9,
++	0x81, 0x38, 0x57, 0xE9,
+ 
+-0x82, 0x31, 0x57, 0xE9,
+-0x86, 0x78, 0x57, 0xE9,
++	0x82, 0x31, 0x57, 0xE9,
++	0x86, 0x78, 0x57, 0xE9,
+ 
+-0x83, 0x39, 0x57, 0xE9,
+-0x87, 0x79, 0x57, 0xE9,
++	0x83, 0x39, 0x57, 0xE9,
++	0x87, 0x79, 0x57, 0xE9,
+ 
+-0x30, 0x1F, 0x5F, 0xE9,
+-0x8A, 0x34, 0x20, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
++	0x8A, 0x34, 0x20, 0xE9,
+ 
+-0x8B, 0x3C, 0x20, 0xE9,
+-0x37, 0x50, 0x60, 0xBD,
++	0x8B, 0x3C, 0x20, 0xE9,
++	0x37, 0x50, 0x60, 0xBD,
+ 
+-0x57, 0x0D, 0x20, 0xE9,
+-0x35, 0x51, 0x61, 0xBD,
++	0x57, 0x0D, 0x20, 0xE9,
++	0x35, 0x51, 0x61, 0xBD,
+ 
+-0x2B, 0x50, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x50, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x0E, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x0E, 0x77,
+ 
+-0x24, 0x51, 0x20, 0xE9,
+-0x9A, 0xFF, 0x20, 0xEA,
++	0x24, 0x51, 0x20, 0xE9,
++	0x9A, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x0E, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x0E, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x0B, 0x46, 0xA0, 0xE8,
+-0x1B, 0x56, 0xA0, 0xE8,
++	0x0B, 0x46, 0xA0, 0xE8,
++	0x1B, 0x56, 0xA0, 0xE8,
+ 
+-0x2B, 0x66, 0xA0, 0xE8,
+-0x0C, 0x47, 0xA0, 0xE8,
++	0x2B, 0x66, 0xA0, 0xE8,
++	0x0C, 0x47, 0xA0, 0xE8,
+ 
+-0x1C, 0x57, 0xA0, 0xE8,
+-0x2C, 0x67, 0xA0, 0xE8,
++	0x1C, 0x57, 0xA0, 0xE8,
++	0x2C, 0x67, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x57, 0x80, 0x57, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x57, 0x80, 0x57, 0xCF,
+ 
+-0x66, 0x33, 0x66, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x66, 0x33, 0x66, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x67, 0x3B, 0x67, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x67, 0x3B, 0x67, 0xCF,
+ 
+-0x0B, 0x48, 0xA0, 0xE8,
+-0x1B, 0x58, 0xA0, 0xE8,
++	0x0B, 0x48, 0xA0, 0xE8,
++	0x1B, 0x58, 0xA0, 0xE8,
+ 
+-0x2B, 0x68, 0xA0, 0xE8,
+-0x0C, 0x49, 0xA0, 0xE8,
++	0x2B, 0x68, 0xA0, 0xE8,
++	0x0C, 0x49, 0xA0, 0xE8,
+ 
+-0x1C, 0x59, 0xA0, 0xE8,
+-0x2C, 0x69, 0xA0, 0xE8,
++	0x1C, 0x59, 0xA0, 0xE8,
++	0x2C, 0x69, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x34, 0xD7, 0x34, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x34, 0xD7, 0x34, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3C, 0xD7, 0x3C, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3C, 0xD7, 0x3C, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x34, 0x80, 0x34, 0xBD,
+-0x3C, 0x80, 0x3C, 0xBD,
++	0x34, 0x80, 0x34, 0xBD,
++	0x3C, 0x80, 0x3C, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x48, 0x80, 0x48, 0xCF,
+-0x59, 0x80, 0x59, 0xCF,
++	0x48, 0x80, 0x48, 0xCF,
++	0x59, 0x80, 0x59, 0xCF,
+ 
+-0x68, 0x33, 0x68, 0xCF,
+-0x49, 0x3B, 0x49, 0xCF,
++	0x68, 0x33, 0x68, 0xCF,
++	0x49, 0x3B, 0x49, 0xCF,
+ 
+-0xBB, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xBB, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x58, 0x33, 0x58, 0xCF,
+-0x69, 0x3B, 0x69, 0xCF,
++	0x58, 0x33, 0x58, 0xCF,
++	0x69, 0x3B, 0x69, 0xCF,
+ 
+-0x78, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x78, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_t2gzs[] = {
+ 
+-0x00, 0x8A, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x8A, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0A, 0x40, 0x50, 0xBF,
+-0x2A, 0x40, 0x60, 0xBF,
++	0x0A, 0x40, 0x50, 0xBF,
++	0x2A, 0x40, 0x60, 0xBF,
+ 
+-0x32, 0x41, 0x51, 0xBF,
+-0x3A, 0x41, 0x61, 0xBF,
++	0x32, 0x41, 0x51, 0xBF,
++	0x3A, 0x41, 0x61, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xD3, 0x6B,
+-0x00, 0x8A, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xD3, 0x6B,
++	0x00, 0x8A, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x23, 0x9F,
+-0x00, 0xE0,
+-0x51, 0x04,
++	0xAD, 0xEE, 0x23, 0x9F,
++	0x00, 0xE0,
++	0x51, 0x04,
+ 
+-0x90, 0xE2,
+-0x61, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x61, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x51, 0x41, 0xE0, 0xEC,
+-0x39, 0x67, 0xB1, 0xE8,
++	0x51, 0x41, 0xE0, 0xEC,
++	0x39, 0x67, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x63, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x63, 0xA0, 0xE8,
+ 
+-0x61, 0x41, 0xE0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x61, 0x41, 0xE0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x85, 0x80, 0x15, 0xEA,
+-0x10, 0x04,
+-0x20, 0x04,
++	0x85, 0x80, 0x15, 0xEA,
++	0x10, 0x04,
++	0x20, 0x04,
+ 
+-0x61, 0x51, 0xE0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x61, 0x51, 0xE0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x52, 0xBF,
+-0x0F, 0x52, 0xA0, 0xE8,
++	0x2A, 0x42, 0x52, 0xBF,
++	0x0F, 0x52, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x62, 0xBF,
+-0x1E, 0x51, 0x60, 0xEA,
++	0x1A, 0x42, 0x62, 0xBF,
++	0x1E, 0x51, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x0E, 0x61, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x0E, 0x61, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x50, 0xBD,
+-0x22, 0x40, 0x60, 0xBD,
++	0x32, 0x40, 0x50, 0xBD,
++	0x22, 0x40, 0x60, 0xBD,
+ 
+-0x12, 0x41, 0x51, 0xBD,
+-0x3A, 0x41, 0x61, 0xBD,
++	0x12, 0x41, 0x51, 0xBD,
++	0x3A, 0x41, 0x61, 0xBD,
+ 
+-0xBF, 0x2F, 0x0E, 0xBD,
+-0x97, 0xE2,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x0E, 0xBD,
++	0x97, 0xE2,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x35, 0x48, 0xB1, 0xE8,
+-0x3D, 0x59, 0xB1, 0xE8,
++	0x35, 0x48, 0xB1, 0xE8,
++	0x3D, 0x59, 0xB1, 0xE8,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x56, 0x31, 0x56, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x66, 0x31, 0x66, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x66, 0x31, 0x66, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x57, 0x39, 0x57, 0xBF,
+-0x67, 0x39, 0x67, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
++	0x67, 0x39, 0x67, 0xBF,
+ 
+-0x76, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x76, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x35, 0x00,
+-0x3D, 0x00,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x35, 0x00,
++	0x3D, 0x00,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0x8D, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0x8D, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x75, 0xF8, 0xEC,
+-0x35, 0x20,
+-0x3D, 0x20,
++	0x43, 0x75, 0xF8, 0xEC,
++	0x35, 0x20,
++	0x3D, 0x20,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x53, 0x53, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x53, 0x53, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x0E, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x0E, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x48, 0x35, 0x48, 0xBF,
+-0x58, 0x35, 0x58, 0xBF,
++	0x48, 0x35, 0x48, 0xBF,
++	0x58, 0x35, 0x58, 0xBF,
+ 
+-0x68, 0x35, 0x68, 0xBF,
+-0x49, 0x3D, 0x49, 0xBF,
++	0x68, 0x35, 0x68, 0xBF,
++	0x49, 0x3D, 0x49, 0xBF,
+ 
+-0x59, 0x3D, 0x59, 0xBF,
+-0x69, 0x3D, 0x69, 0xBF,
++	0x59, 0x3D, 0x59, 0xBF,
++	0x69, 0x3D, 0x69, 0xBF,
+ 
+-0x63, 0x63, 0x2D, 0xDF,
+-0x4D, 0x7D, 0xF8, 0xEC,
++	0x63, 0x63, 0x2D, 0xDF,
++	0x4D, 0x7D, 0xF8, 0xEC,
+ 
+-0x59, 0xE3,
+-0x00, 0xE0,
+-0xB8, 0x38, 0x33, 0xBF,
++	0x59, 0xE3,
++	0x00, 0xE0,
++	0xB8, 0x38, 0x33, 0xBF,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x18, 0x3A, 0x41, 0xE9,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x18, 0x3A, 0x41, 0xE9,
+ 
+-0x3F, 0x53, 0xA0, 0xE8,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x3F, 0x53, 0xA0, 0xE8,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x63, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x63, 0xA0, 0xE8,
+ 
+-0x50, 0x70, 0xF8, 0xEC,
+-0x2B, 0x50, 0x3C, 0xE9,
++	0x50, 0x70, 0xF8, 0xEC,
++	0x2B, 0x50, 0x3C, 0xE9,
+ 
+-0x1F, 0x0F, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x0F, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x59, 0x78, 0xF8, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0x59, 0x78, 0xF8, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x56, 0x3F, 0x56, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x56, 0x3F, 0x56, 0xDF,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x66, 0x3D, 0x66, 0xDF,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x66, 0x3D, 0x66, 0xDF,
+ 
+-0x1D, 0x32, 0x41, 0xE9,
+-0x67, 0x3D, 0x67, 0xDF,
++	0x1D, 0x32, 0x41, 0xE9,
++	0x67, 0x3D, 0x67, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3F, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3F, 0x57, 0xDF,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x59, 0x3F, 0x59, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x59, 0x3F, 0x59, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x69, 0x3D, 0x69, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x69, 0x3D, 0x69, 0xDF,
+ 
+-0x48, 0x37, 0x48, 0xDF,
+-0x58, 0x3F, 0x58, 0xDF,
++	0x48, 0x37, 0x48, 0xDF,
++	0x58, 0x3F, 0x58, 0xDF,
+ 
+-0x68, 0x3D, 0x68, 0xDF,
+-0x49, 0x37, 0x49, 0xDF,
++	0x68, 0x3D, 0x68, 0xDF,
++	0x49, 0x37, 0x49, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x0F, 0xCF, 0x74, 0xC2,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x0F, 0xCF, 0x74, 0xC2,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x54, 0xB0,
+-0x02, 0x44, 0x64, 0xB0,
++	0x0A, 0x44, 0x54, 0xB0,
++	0x02, 0x44, 0x64, 0xB0,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x34, 0x37, 0x20, 0xE9,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x38, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x38, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB2,
+-0x1A, 0x44, 0x64, 0xB2,
++	0x2A, 0x44, 0x54, 0xB2,
++	0x1A, 0x44, 0x64, 0xB2,
+ 
+-0x31, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x31, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x0F, 0xCF, 0x75, 0xC0,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0F, 0xCF, 0x75, 0xC0,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x3D, 0xCF, 0x75, 0xC2,
+-0x37, 0xCF, 0x75, 0xC4,
++	0x3D, 0xCF, 0x75, 0xC2,
++	0x37, 0xCF, 0x75, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA6, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA6, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA3, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA3, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB4,
+-0x1A, 0x44, 0x64, 0xB4,
++	0x2A, 0x44, 0x54, 0xB4,
++	0x1A, 0x44, 0x64, 0xB4,
+ 
+-0x0A, 0x45, 0x55, 0xB0,
+-0x02, 0x45, 0x65, 0xB0,
++	0x0A, 0x45, 0x55, 0xB0,
++	0x02, 0x45, 0x65, 0xB0,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA0, 0x37, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA0, 0x37, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x55, 0xB2,
+-0x1A, 0x45, 0x65, 0xB2,
++	0x2A, 0x45, 0x55, 0xB2,
++	0x1A, 0x45, 0x65, 0xB2,
+ 
+-0x0A, 0x45, 0x55, 0xB4,
+-0x02, 0x45, 0x65, 0xB4,
++	0x0A, 0x45, 0x55, 0xB4,
++	0x02, 0x45, 0x65, 0xB4,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x20,
+-0x1A, 0x20,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x2A, 0x20,
++	0x1A, 0x20,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x2A, 0x46, 0x56, 0xBF,
+-0x1A, 0x46, 0x66, 0xBF,
++	0x2A, 0x46, 0x56, 0xBF,
++	0x1A, 0x46, 0x66, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0xA7, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0xA7, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0xA8, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0xA8, 0x38, 0x4F, 0xE9,
+ 
+-0x0A, 0x47, 0x57, 0xBF,
+-0x02, 0x47, 0x67, 0xBF,
++	0x0A, 0x47, 0x57, 0xBF,
++	0x02, 0x47, 0x67, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA4, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA4, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA5, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA5, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x53, 0xBF,
+-0x1A, 0x43, 0x63, 0xBF,
++	0x2A, 0x43, 0x53, 0xBF,
++	0x1A, 0x43, 0x63, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0xA1, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0xA1, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0xA2, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0xA2, 0x38, 0x4F, 0xE9,
+ 
+-0x0A, 0x48, 0x58, 0xBF,
+-0x02, 0x48, 0x68, 0xBF,
++	0x0A, 0x48, 0x58, 0xBF,
++	0x02, 0x48, 0x68, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x2A, 0x49, 0x59, 0xBF,
+-0x1A, 0x49, 0x69, 0xBF,
++	0x2A, 0x49, 0x59, 0xBF,
++	0x1A, 0x49, 0x69, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x82, 0x30, 0x57, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x82, 0x30, 0x57, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x83, 0x38, 0x57, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x83, 0x38, 0x57, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x84, 0x31, 0x5E, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x84, 0x31, 0x5E, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x85, 0x39, 0x5E, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x85, 0x39, 0x5E, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x87, 0x77, 0x57, 0xE9,
+-0x8B, 0x3E, 0xBF, 0xEA,
++	0x87, 0x77, 0x57, 0xE9,
++	0x8B, 0x3E, 0xBF, 0xEA,
+ 
+-0x80, 0x30, 0x57, 0xE9,
+-0x81, 0x38, 0x57, 0xE9,
++	0x80, 0x30, 0x57, 0xE9,
++	0x81, 0x38, 0x57, 0xE9,
+ 
+-0x82, 0x31, 0x57, 0xE9,
+-0x86, 0x78, 0x57, 0xE9,
++	0x82, 0x31, 0x57, 0xE9,
++	0x86, 0x78, 0x57, 0xE9,
+ 
+-0x83, 0x39, 0x57, 0xE9,
+-0x87, 0x79, 0x57, 0xE9,
++	0x83, 0x39, 0x57, 0xE9,
++	0x87, 0x79, 0x57, 0xE9,
+ 
+-0x30, 0x1F, 0x5F, 0xE9,
+-0x8A, 0x34, 0x20, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
++	0x8A, 0x34, 0x20, 0xE9,
+ 
+-0x8B, 0x3C, 0x20, 0xE9,
+-0x37, 0x50, 0x60, 0xBD,
++	0x8B, 0x3C, 0x20, 0xE9,
++	0x37, 0x50, 0x60, 0xBD,
+ 
+-0x57, 0x0D, 0x20, 0xE9,
+-0x35, 0x51, 0x61, 0xBD,
++	0x57, 0x0D, 0x20, 0xE9,
++	0x35, 0x51, 0x61, 0xBD,
+ 
+-0x2B, 0x50, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x50, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x0E, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x0E, 0x77,
+ 
+-0x24, 0x51, 0x20, 0xE9,
+-0x92, 0xFF, 0x20, 0xEA,
++	0x24, 0x51, 0x20, 0xE9,
++	0x92, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x0E, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x0E, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x0B, 0x46, 0xA0, 0xE8,
+-0x1B, 0x56, 0xA0, 0xE8,
++	0x0B, 0x46, 0xA0, 0xE8,
++	0x1B, 0x56, 0xA0, 0xE8,
+ 
+-0x2B, 0x66, 0xA0, 0xE8,
+-0x0C, 0x47, 0xA0, 0xE8,
++	0x2B, 0x66, 0xA0, 0xE8,
++	0x0C, 0x47, 0xA0, 0xE8,
+ 
+-0x1C, 0x57, 0xA0, 0xE8,
+-0x2C, 0x67, 0xA0, 0xE8,
++	0x1C, 0x57, 0xA0, 0xE8,
++	0x2C, 0x67, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x57, 0x80, 0x57, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x57, 0x80, 0x57, 0xCF,
+ 
+-0x66, 0x33, 0x66, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x66, 0x33, 0x66, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x67, 0x3B, 0x67, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x67, 0x3B, 0x67, 0xCF,
+ 
+-0x0B, 0x48, 0xA0, 0xE8,
+-0x1B, 0x58, 0xA0, 0xE8,
++	0x0B, 0x48, 0xA0, 0xE8,
++	0x1B, 0x58, 0xA0, 0xE8,
+ 
+-0x2B, 0x68, 0xA0, 0xE8,
+-0x0C, 0x49, 0xA0, 0xE8,
++	0x2B, 0x68, 0xA0, 0xE8,
++	0x0C, 0x49, 0xA0, 0xE8,
+ 
+-0x1C, 0x59, 0xA0, 0xE8,
+-0x2C, 0x69, 0xA0, 0xE8,
++	0x1C, 0x59, 0xA0, 0xE8,
++	0x2C, 0x69, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x34, 0xD7, 0x34, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x34, 0xD7, 0x34, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3C, 0xD7, 0x3C, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3C, 0xD7, 0x3C, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x34, 0x80, 0x34, 0xBD,
+-0x3C, 0x80, 0x3C, 0xBD,
++	0x34, 0x80, 0x34, 0xBD,
++	0x3C, 0x80, 0x3C, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x48, 0x80, 0x48, 0xCF,
+-0x59, 0x80, 0x59, 0xCF,
++	0x48, 0x80, 0x48, 0xCF,
++	0x59, 0x80, 0x59, 0xCF,
+ 
+-0x68, 0x33, 0x68, 0xCF,
+-0x49, 0x3B, 0x49, 0xCF,
++	0x68, 0x33, 0x68, 0xCF,
++	0x49, 0x3B, 0x49, 0xCF,
+ 
+-0xB2, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB2, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x58, 0x33, 0x58, 0xCF,
+-0x69, 0x3B, 0x69, 0xCF,
++	0x58, 0x33, 0x58, 0xCF,
++	0x69, 0x3B, 0x69, 0xCF,
+ 
+-0x70, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x70, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_t2gzsa[] = {
+ 
+-0x00, 0x8A, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x8A, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0A, 0x40, 0x50, 0xBF,
+-0x2A, 0x40, 0x60, 0xBF,
++	0x0A, 0x40, 0x50, 0xBF,
++	0x2A, 0x40, 0x60, 0xBF,
+ 
+-0x32, 0x41, 0x51, 0xBF,
+-0x3A, 0x41, 0x61, 0xBF,
++	0x32, 0x41, 0x51, 0xBF,
++	0x3A, 0x41, 0x61, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xD3, 0x6B,
+-0x00, 0x8A, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xD3, 0x6B,
++	0x00, 0x8A, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x23, 0x9F,
+-0x00, 0xE0,
+-0x51, 0x04,
++	0xAD, 0xEE, 0x23, 0x9F,
++	0x00, 0xE0,
++	0x51, 0x04,
+ 
+-0x90, 0xE2,
+-0x61, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x61, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x51, 0x41, 0xE0, 0xEC,
+-0x39, 0x67, 0xB1, 0xE8,
++	0x51, 0x41, 0xE0, 0xEC,
++	0x39, 0x67, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x63, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x63, 0xA0, 0xE8,
+ 
+-0x61, 0x41, 0xE0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x61, 0x41, 0xE0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x8A, 0x80, 0x15, 0xEA,
+-0x10, 0x04,
+-0x20, 0x04,
++	0x8A, 0x80, 0x15, 0xEA,
++	0x10, 0x04,
++	0x20, 0x04,
+ 
+-0x61, 0x51, 0xE0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x61, 0x51, 0xE0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x52, 0xBF,
+-0x0F, 0x52, 0xA0, 0xE8,
++	0x2A, 0x42, 0x52, 0xBF,
++	0x0F, 0x52, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x62, 0xBF,
+-0x1E, 0x51, 0x60, 0xEA,
++	0x1A, 0x42, 0x62, 0xBF,
++	0x1E, 0x51, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x0E, 0x61, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x0E, 0x61, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x50, 0xBD,
+-0x22, 0x40, 0x60, 0xBD,
++	0x32, 0x40, 0x50, 0xBD,
++	0x22, 0x40, 0x60, 0xBD,
+ 
+-0x12, 0x41, 0x51, 0xBD,
+-0x3A, 0x41, 0x61, 0xBD,
++	0x12, 0x41, 0x51, 0xBD,
++	0x3A, 0x41, 0x61, 0xBD,
+ 
+-0xBF, 0x2F, 0x0E, 0xBD,
+-0x97, 0xE2,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x0E, 0xBD,
++	0x97, 0xE2,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x35, 0x48, 0xB1, 0xE8,
+-0x3D, 0x59, 0xB1, 0xE8,
++	0x35, 0x48, 0xB1, 0xE8,
++	0x3D, 0x59, 0xB1, 0xE8,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x56, 0x31, 0x56, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x66, 0x31, 0x66, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x66, 0x31, 0x66, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x57, 0x39, 0x57, 0xBF,
+-0x67, 0x39, 0x67, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
++	0x67, 0x39, 0x67, 0xBF,
+ 
+-0x7B, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x7B, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x35, 0x00,
+-0x3D, 0x00,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x35, 0x00,
++	0x3D, 0x00,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0x8D, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0x8D, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x75, 0xF8, 0xEC,
+-0x35, 0x20,
+-0x3D, 0x20,
++	0x43, 0x75, 0xF8, 0xEC,
++	0x35, 0x20,
++	0x3D, 0x20,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x53, 0x53, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x53, 0x53, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x0E, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x0E, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x48, 0x35, 0x48, 0xBF,
+-0x58, 0x35, 0x58, 0xBF,
++	0x48, 0x35, 0x48, 0xBF,
++	0x58, 0x35, 0x58, 0xBF,
+ 
+-0x68, 0x35, 0x68, 0xBF,
+-0x49, 0x3D, 0x49, 0xBF,
++	0x68, 0x35, 0x68, 0xBF,
++	0x49, 0x3D, 0x49, 0xBF,
+ 
+-0x59, 0x3D, 0x59, 0xBF,
+-0x69, 0x3D, 0x69, 0xBF,
++	0x59, 0x3D, 0x59, 0xBF,
++	0x69, 0x3D, 0x69, 0xBF,
+ 
+-0x63, 0x63, 0x2D, 0xDF,
+-0x4D, 0x7D, 0xF8, 0xEC,
++	0x63, 0x63, 0x2D, 0xDF,
++	0x4D, 0x7D, 0xF8, 0xEC,
+ 
+-0x59, 0xE3,
+-0x00, 0xE0,
+-0xB8, 0x38, 0x33, 0xBF,
++	0x59, 0xE3,
++	0x00, 0xE0,
++	0xB8, 0x38, 0x33, 0xBF,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x18, 0x3A, 0x41, 0xE9,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x18, 0x3A, 0x41, 0xE9,
+ 
+-0x3F, 0x53, 0xA0, 0xE8,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x3F, 0x53, 0xA0, 0xE8,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x63, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x63, 0xA0, 0xE8,
+ 
+-0x50, 0x70, 0xF8, 0xEC,
+-0x2B, 0x50, 0x3C, 0xE9,
++	0x50, 0x70, 0xF8, 0xEC,
++	0x2B, 0x50, 0x3C, 0xE9,
+ 
+-0x1F, 0x0F, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x0F, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x59, 0x78, 0xF8, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0x59, 0x78, 0xF8, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x56, 0x3F, 0x56, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x56, 0x3F, 0x56, 0xDF,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x66, 0x3D, 0x66, 0xDF,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x66, 0x3D, 0x66, 0xDF,
+ 
+-0x1D, 0x32, 0x41, 0xE9,
+-0x67, 0x3D, 0x67, 0xDF,
++	0x1D, 0x32, 0x41, 0xE9,
++	0x67, 0x3D, 0x67, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3F, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3F, 0x57, 0xDF,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x59, 0x3F, 0x59, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x59, 0x3F, 0x59, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x69, 0x3D, 0x69, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x69, 0x3D, 0x69, 0xDF,
+ 
+-0x48, 0x37, 0x48, 0xDF,
+-0x58, 0x3F, 0x58, 0xDF,
++	0x48, 0x37, 0x48, 0xDF,
++	0x58, 0x3F, 0x58, 0xDF,
+ 
+-0x68, 0x3D, 0x68, 0xDF,
+-0x49, 0x37, 0x49, 0xDF,
++	0x68, 0x3D, 0x68, 0xDF,
++	0x49, 0x37, 0x49, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x0F, 0xCF, 0x74, 0xC2,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x0F, 0xCF, 0x74, 0xC2,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x54, 0xB0,
+-0x02, 0x44, 0x64, 0xB0,
++	0x0A, 0x44, 0x54, 0xB0,
++	0x02, 0x44, 0x64, 0xB0,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x34, 0x37, 0x20, 0xE9,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x38, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x38, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB2,
+-0x1A, 0x44, 0x64, 0xB2,
++	0x2A, 0x44, 0x54, 0xB2,
++	0x1A, 0x44, 0x64, 0xB2,
+ 
+-0x36, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x36, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x0F, 0xCF, 0x75, 0xC0,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0F, 0xCF, 0x75, 0xC0,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x3D, 0xCF, 0x75, 0xC2,
+-0x37, 0xCF, 0x75, 0xC4,
++	0x3D, 0xCF, 0x75, 0xC2,
++	0x37, 0xCF, 0x75, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA6, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA6, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA3, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA3, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB4,
+-0x1A, 0x44, 0x64, 0xB4,
++	0x2A, 0x44, 0x54, 0xB4,
++	0x1A, 0x44, 0x64, 0xB4,
+ 
+-0x0A, 0x45, 0x55, 0xB0,
+-0x02, 0x45, 0x65, 0xB0,
++	0x0A, 0x45, 0x55, 0xB0,
++	0x02, 0x45, 0x65, 0xB0,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA0, 0x37, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA0, 0x37, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x55, 0xB2,
+-0x1A, 0x45, 0x65, 0xB2,
++	0x2A, 0x45, 0x55, 0xB2,
++	0x1A, 0x45, 0x65, 0xB2,
+ 
+-0x0A, 0x45, 0x55, 0xB4,
+-0x02, 0x45, 0x65, 0xB4,
++	0x0A, 0x45, 0x55, 0xB4,
++	0x02, 0x45, 0x65, 0xB4,
+ 
+-0x0F, 0xCF, 0x74, 0xC6,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0F, 0xCF, 0x74, 0xC6,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA7, 0x30, 0x4F, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA7, 0x30, 0x4F, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9C, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9C, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA8, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA8, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB6,
+-0x1A, 0x44, 0x64, 0xB6,
++	0x2A, 0x44, 0x54, 0xB6,
++	0x1A, 0x44, 0x64, 0xB6,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x00, 0x80, 0x00, 0xE8,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x2A, 0x46, 0x56, 0xBF,
+-0x1A, 0x46, 0x66, 0xBF,
++	0x2A, 0x46, 0x56, 0xBF,
++	0x1A, 0x46, 0x66, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA4, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA4, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA5, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA5, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x47, 0x57, 0xBF,
+-0x02, 0x47, 0x67, 0xBF,
++	0x0A, 0x47, 0x57, 0xBF,
++	0x02, 0x47, 0x67, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA1, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA1, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA2, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA2, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x53, 0xBF,
+-0x1A, 0x43, 0x63, 0xBF,
++	0x2A, 0x43, 0x53, 0xBF,
++	0x1A, 0x43, 0x63, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x9D, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x9D, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x9E, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x9E, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x48, 0x58, 0xBF,
+-0x02, 0x48, 0x68, 0xBF,
++	0x0A, 0x48, 0x58, 0xBF,
++	0x02, 0x48, 0x68, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x2A, 0x49, 0x59, 0xBF,
+-0x1A, 0x49, 0x69, 0xBF,
++	0x2A, 0x49, 0x59, 0xBF,
++	0x1A, 0x49, 0x69, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x82, 0x30, 0x57, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x82, 0x30, 0x57, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x83, 0x38, 0x57, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x83, 0x38, 0x57, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x84, 0x31, 0x5E, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x84, 0x31, 0x5E, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x85, 0x39, 0x5E, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x85, 0x39, 0x5E, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x87, 0x77, 0x57, 0xE9,
+-0x8B, 0x3E, 0xBF, 0xEA,
++	0x87, 0x77, 0x57, 0xE9,
++	0x8B, 0x3E, 0xBF, 0xEA,
+ 
+-0x80, 0x30, 0x57, 0xE9,
+-0x81, 0x38, 0x57, 0xE9,
++	0x80, 0x30, 0x57, 0xE9,
++	0x81, 0x38, 0x57, 0xE9,
+ 
+-0x82, 0x31, 0x57, 0xE9,
+-0x86, 0x78, 0x57, 0xE9,
++	0x82, 0x31, 0x57, 0xE9,
++	0x86, 0x78, 0x57, 0xE9,
+ 
+-0x83, 0x39, 0x57, 0xE9,
+-0x87, 0x79, 0x57, 0xE9,
++	0x83, 0x39, 0x57, 0xE9,
++	0x87, 0x79, 0x57, 0xE9,
+ 
+-0x30, 0x1F, 0x5F, 0xE9,
+-0x8A, 0x34, 0x20, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
++	0x8A, 0x34, 0x20, 0xE9,
+ 
+-0x8B, 0x3C, 0x20, 0xE9,
+-0x37, 0x50, 0x60, 0xBD,
++	0x8B, 0x3C, 0x20, 0xE9,
++	0x37, 0x50, 0x60, 0xBD,
+ 
+-0x57, 0x0D, 0x20, 0xE9,
+-0x35, 0x51, 0x61, 0xBD,
++	0x57, 0x0D, 0x20, 0xE9,
++	0x35, 0x51, 0x61, 0xBD,
+ 
+-0x2B, 0x50, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x50, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x0E, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x0E, 0x77,
+ 
+-0x24, 0x51, 0x20, 0xE9,
+-0x8D, 0xFF, 0x20, 0xEA,
++	0x24, 0x51, 0x20, 0xE9,
++	0x8D, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x0E, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x0E, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x0B, 0x46, 0xA0, 0xE8,
+-0x1B, 0x56, 0xA0, 0xE8,
++	0x0B, 0x46, 0xA0, 0xE8,
++	0x1B, 0x56, 0xA0, 0xE8,
+ 
+-0x2B, 0x66, 0xA0, 0xE8,
+-0x0C, 0x47, 0xA0, 0xE8,
++	0x2B, 0x66, 0xA0, 0xE8,
++	0x0C, 0x47, 0xA0, 0xE8,
+ 
+-0x1C, 0x57, 0xA0, 0xE8,
+-0x2C, 0x67, 0xA0, 0xE8,
++	0x1C, 0x57, 0xA0, 0xE8,
++	0x2C, 0x67, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x57, 0x80, 0x57, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x57, 0x80, 0x57, 0xCF,
+ 
+-0x66, 0x33, 0x66, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x66, 0x33, 0x66, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x67, 0x3B, 0x67, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x67, 0x3B, 0x67, 0xCF,
+ 
+-0x0B, 0x48, 0xA0, 0xE8,
+-0x1B, 0x58, 0xA0, 0xE8,
++	0x0B, 0x48, 0xA0, 0xE8,
++	0x1B, 0x58, 0xA0, 0xE8,
+ 
+-0x2B, 0x68, 0xA0, 0xE8,
+-0x0C, 0x49, 0xA0, 0xE8,
++	0x2B, 0x68, 0xA0, 0xE8,
++	0x0C, 0x49, 0xA0, 0xE8,
+ 
+-0x1C, 0x59, 0xA0, 0xE8,
+-0x2C, 0x69, 0xA0, 0xE8,
++	0x1C, 0x59, 0xA0, 0xE8,
++	0x2C, 0x69, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x34, 0xD7, 0x34, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x34, 0xD7, 0x34, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3C, 0xD7, 0x3C, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3C, 0xD7, 0x3C, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x34, 0x80, 0x34, 0xBD,
+-0x3C, 0x80, 0x3C, 0xBD,
++	0x34, 0x80, 0x34, 0xBD,
++	0x3C, 0x80, 0x3C, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x48, 0x80, 0x48, 0xCF,
+-0x59, 0x80, 0x59, 0xCF,
++	0x48, 0x80, 0x48, 0xCF,
++	0x59, 0x80, 0x59, 0xCF,
+ 
+-0x68, 0x33, 0x68, 0xCF,
+-0x49, 0x3B, 0x49, 0xCF,
++	0x68, 0x33, 0x68, 0xCF,
++	0x49, 0x3B, 0x49, 0xCF,
+ 
+-0xAD, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xAD, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x58, 0x33, 0x58, 0xCF,
+-0x69, 0x3B, 0x69, 0xCF,
++	0x58, 0x33, 0x58, 0xCF,
++	0x69, 0x3B, 0x69, 0xCF,
+ 
+-0x6B, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x6B, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_t2gzsaf[] = {
+ 
+-0x00, 0x8A, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x8A, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0A, 0x40, 0x50, 0xBF,
+-0x2A, 0x40, 0x60, 0xBF,
++	0x0A, 0x40, 0x50, 0xBF,
++	0x2A, 0x40, 0x60, 0xBF,
+ 
+-0x32, 0x41, 0x51, 0xBF,
+-0x3A, 0x41, 0x61, 0xBF,
++	0x32, 0x41, 0x51, 0xBF,
++	0x3A, 0x41, 0x61, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xD3, 0x6B,
+-0x00, 0x8A, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xD3, 0x6B,
++	0x00, 0x8A, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x23, 0x9F,
+-0x00, 0xE0,
+-0x51, 0x04,
++	0xAD, 0xEE, 0x23, 0x9F,
++	0x00, 0xE0,
++	0x51, 0x04,
+ 
+-0x90, 0xE2,
+-0x61, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x61, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x51, 0x41, 0xE0, 0xEC,
+-0x39, 0x67, 0xB1, 0xE8,
++	0x51, 0x41, 0xE0, 0xEC,
++	0x39, 0x67, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x63, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x63, 0xA0, 0xE8,
+ 
+-0x61, 0x41, 0xE0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x61, 0x41, 0xE0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x8E, 0x80, 0x15, 0xEA,
+-0x10, 0x04,
+-0x20, 0x04,
++	0x8E, 0x80, 0x15, 0xEA,
++	0x10, 0x04,
++	0x20, 0x04,
+ 
+-0x61, 0x51, 0xE0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x61, 0x51, 0xE0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x52, 0xBF,
+-0x0F, 0x52, 0xA0, 0xE8,
++	0x2A, 0x42, 0x52, 0xBF,
++	0x0F, 0x52, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x62, 0xBF,
+-0x1E, 0x51, 0x60, 0xEA,
++	0x1A, 0x42, 0x62, 0xBF,
++	0x1E, 0x51, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x0E, 0x61, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x0E, 0x61, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x50, 0xBD,
+-0x22, 0x40, 0x60, 0xBD,
++	0x32, 0x40, 0x50, 0xBD,
++	0x22, 0x40, 0x60, 0xBD,
+ 
+-0x12, 0x41, 0x51, 0xBD,
+-0x3A, 0x41, 0x61, 0xBD,
++	0x12, 0x41, 0x51, 0xBD,
++	0x3A, 0x41, 0x61, 0xBD,
+ 
+-0xBF, 0x2F, 0x0E, 0xBD,
+-0x97, 0xE2,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x0E, 0xBD,
++	0x97, 0xE2,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x35, 0x48, 0xB1, 0xE8,
+-0x3D, 0x59, 0xB1, 0xE8,
++	0x35, 0x48, 0xB1, 0xE8,
++	0x3D, 0x59, 0xB1, 0xE8,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x56, 0x31, 0x56, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x66, 0x31, 0x66, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x66, 0x31, 0x66, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x57, 0x39, 0x57, 0xBF,
+-0x67, 0x39, 0x67, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
++	0x67, 0x39, 0x67, 0xBF,
+ 
+-0x7F, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x7F, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x35, 0x00,
+-0x3D, 0x00,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x35, 0x00,
++	0x3D, 0x00,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0x8D, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0x8D, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x75, 0xF8, 0xEC,
+-0x35, 0x20,
+-0x3D, 0x20,
++	0x43, 0x75, 0xF8, 0xEC,
++	0x35, 0x20,
++	0x3D, 0x20,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x53, 0x53, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x53, 0x53, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x0E, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x0E, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x48, 0x35, 0x48, 0xBF,
+-0x58, 0x35, 0x58, 0xBF,
++	0x48, 0x35, 0x48, 0xBF,
++	0x58, 0x35, 0x58, 0xBF,
+ 
+-0x68, 0x35, 0x68, 0xBF,
+-0x49, 0x3D, 0x49, 0xBF,
++	0x68, 0x35, 0x68, 0xBF,
++	0x49, 0x3D, 0x49, 0xBF,
+ 
+-0x59, 0x3D, 0x59, 0xBF,
+-0x69, 0x3D, 0x69, 0xBF,
++	0x59, 0x3D, 0x59, 0xBF,
++	0x69, 0x3D, 0x69, 0xBF,
+ 
+-0x63, 0x63, 0x2D, 0xDF,
+-0x4D, 0x7D, 0xF8, 0xEC,
++	0x63, 0x63, 0x2D, 0xDF,
++	0x4D, 0x7D, 0xF8, 0xEC,
+ 
+-0x59, 0xE3,
+-0x00, 0xE0,
+-0xB8, 0x38, 0x33, 0xBF,
++	0x59, 0xE3,
++	0x00, 0xE0,
++	0xB8, 0x38, 0x33, 0xBF,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x18, 0x3A, 0x41, 0xE9,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x18, 0x3A, 0x41, 0xE9,
+ 
+-0x3F, 0x53, 0xA0, 0xE8,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x3F, 0x53, 0xA0, 0xE8,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x63, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x63, 0xA0, 0xE8,
+ 
+-0x50, 0x70, 0xF8, 0xEC,
+-0x2B, 0x50, 0x3C, 0xE9,
++	0x50, 0x70, 0xF8, 0xEC,
++	0x2B, 0x50, 0x3C, 0xE9,
+ 
+-0x1F, 0x0F, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x0F, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x59, 0x78, 0xF8, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0x59, 0x78, 0xF8, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x56, 0x3F, 0x56, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x56, 0x3F, 0x56, 0xDF,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x66, 0x3D, 0x66, 0xDF,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x66, 0x3D, 0x66, 0xDF,
+ 
+-0x1D, 0x32, 0x41, 0xE9,
+-0x67, 0x3D, 0x67, 0xDF,
++	0x1D, 0x32, 0x41, 0xE9,
++	0x67, 0x3D, 0x67, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3F, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3F, 0x57, 0xDF,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x59, 0x3F, 0x59, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x59, 0x3F, 0x59, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x69, 0x3D, 0x69, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x69, 0x3D, 0x69, 0xDF,
+ 
+-0x48, 0x37, 0x48, 0xDF,
+-0x58, 0x3F, 0x58, 0xDF,
++	0x48, 0x37, 0x48, 0xDF,
++	0x58, 0x3F, 0x58, 0xDF,
+ 
+-0x68, 0x3D, 0x68, 0xDF,
+-0x49, 0x37, 0x49, 0xDF,
++	0x68, 0x3D, 0x68, 0xDF,
++	0x49, 0x37, 0x49, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x0F, 0xCF, 0x74, 0xC2,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x0F, 0xCF, 0x74, 0xC2,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x54, 0xB0,
+-0x02, 0x44, 0x64, 0xB0,
++	0x0A, 0x44, 0x54, 0xB0,
++	0x02, 0x44, 0x64, 0xB0,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x34, 0x37, 0x20, 0xE9,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x38, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x38, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB2,
+-0x1A, 0x44, 0x64, 0xB2,
++	0x2A, 0x44, 0x54, 0xB2,
++	0x1A, 0x44, 0x64, 0xB2,
+ 
+-0x3A, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x3A, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x0F, 0xCF, 0x75, 0xC0,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0F, 0xCF, 0x75, 0xC0,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x3D, 0xCF, 0x75, 0xC2,
+-0x37, 0xCF, 0x75, 0xC4,
++	0x3D, 0xCF, 0x75, 0xC2,
++	0x37, 0xCF, 0x75, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA6, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA6, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA3, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA3, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB4,
+-0x1A, 0x44, 0x64, 0xB4,
++	0x2A, 0x44, 0x54, 0xB4,
++	0x1A, 0x44, 0x64, 0xB4,
+ 
+-0x0A, 0x45, 0x55, 0xB0,
+-0x02, 0x45, 0x65, 0xB0,
++	0x0A, 0x45, 0x55, 0xB0,
++	0x02, 0x45, 0x65, 0xB0,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA0, 0x37, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA0, 0x37, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x55, 0xB2,
+-0x1A, 0x45, 0x65, 0xB2,
++	0x2A, 0x45, 0x55, 0xB2,
++	0x1A, 0x45, 0x65, 0xB2,
+ 
+-0x0A, 0x45, 0x55, 0xB4,
+-0x02, 0x45, 0x65, 0xB4,
++	0x0A, 0x45, 0x55, 0xB4,
++	0x02, 0x45, 0x65, 0xB4,
+ 
+-0x0F, 0xCF, 0x74, 0xC6,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0F, 0xCF, 0x74, 0xC6,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA7, 0x30, 0x4F, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA7, 0x30, 0x4F, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9C, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9C, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA8, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA8, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB6,
+-0x1A, 0x44, 0x64, 0xB6,
++	0x2A, 0x44, 0x54, 0xB6,
++	0x1A, 0x44, 0x64, 0xB6,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x45, 0x55, 0xB6,
+-0x02, 0x45, 0x65, 0xB6,
++	0x0A, 0x45, 0x55, 0xB6,
++	0x02, 0x45, 0x65, 0xB6,
+ 
+-0x3D, 0xCF, 0x75, 0xC6,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x3D, 0xCF, 0x75, 0xC6,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x2A, 0x46, 0x56, 0xBF,
+-0x1A, 0x46, 0x66, 0xBF,
++	0x2A, 0x46, 0x56, 0xBF,
++	0x1A, 0x46, 0x66, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA4, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA4, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA5, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA5, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x3D, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x31, 0x3D, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x0A, 0x47, 0x57, 0xBF,
+-0x02, 0x47, 0x67, 0xBF,
++	0x0A, 0x47, 0x57, 0xBF,
++	0x02, 0x47, 0x67, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0xA1, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0xA1, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0xA2, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0xA2, 0x38, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9D, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9D, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x9E, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x9E, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x53, 0xBF,
+-0x1A, 0x43, 0x63, 0xBF,
++	0x2A, 0x43, 0x53, 0xBF,
++	0x1A, 0x43, 0x63, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x35, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x35, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x39, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x39, 0x38, 0x4F, 0xE9,
+ 
+-0x0A, 0x48, 0x58, 0xBF,
+-0x02, 0x48, 0x68, 0xBF,
++	0x0A, 0x48, 0x58, 0xBF,
++	0x02, 0x48, 0x68, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x2A, 0x49, 0x59, 0xBF,
+-0x1A, 0x49, 0x69, 0xBF,
++	0x2A, 0x49, 0x59, 0xBF,
++	0x1A, 0x49, 0x69, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x82, 0x30, 0x57, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x82, 0x30, 0x57, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x83, 0x38, 0x57, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x83, 0x38, 0x57, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x84, 0x31, 0x5E, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x84, 0x31, 0x5E, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x85, 0x39, 0x5E, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x85, 0x39, 0x5E, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x87, 0x77, 0x57, 0xE9,
+-0x8B, 0x3E, 0xBF, 0xEA,
++	0x87, 0x77, 0x57, 0xE9,
++	0x8B, 0x3E, 0xBF, 0xEA,
+ 
+-0x80, 0x30, 0x57, 0xE9,
+-0x81, 0x38, 0x57, 0xE9,
++	0x80, 0x30, 0x57, 0xE9,
++	0x81, 0x38, 0x57, 0xE9,
+ 
+-0x82, 0x31, 0x57, 0xE9,
+-0x86, 0x78, 0x57, 0xE9,
++	0x82, 0x31, 0x57, 0xE9,
++	0x86, 0x78, 0x57, 0xE9,
+ 
+-0x83, 0x39, 0x57, 0xE9,
+-0x87, 0x79, 0x57, 0xE9,
++	0x83, 0x39, 0x57, 0xE9,
++	0x87, 0x79, 0x57, 0xE9,
+ 
+-0x30, 0x1F, 0x5F, 0xE9,
+-0x8A, 0x34, 0x20, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
++	0x8A, 0x34, 0x20, 0xE9,
+ 
+-0x8B, 0x3C, 0x20, 0xE9,
+-0x37, 0x50, 0x60, 0xBD,
++	0x8B, 0x3C, 0x20, 0xE9,
++	0x37, 0x50, 0x60, 0xBD,
+ 
+-0x57, 0x0D, 0x20, 0xE9,
+-0x35, 0x51, 0x61, 0xBD,
++	0x57, 0x0D, 0x20, 0xE9,
++	0x35, 0x51, 0x61, 0xBD,
+ 
+-0x2B, 0x50, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x50, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x0E, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x0E, 0x77,
+ 
+-0x24, 0x51, 0x20, 0xE9,
+-0x89, 0xFF, 0x20, 0xEA,
++	0x24, 0x51, 0x20, 0xE9,
++	0x89, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x0E, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x0E, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x0B, 0x46, 0xA0, 0xE8,
+-0x1B, 0x56, 0xA0, 0xE8,
++	0x0B, 0x46, 0xA0, 0xE8,
++	0x1B, 0x56, 0xA0, 0xE8,
+ 
+-0x2B, 0x66, 0xA0, 0xE8,
+-0x0C, 0x47, 0xA0, 0xE8,
++	0x2B, 0x66, 0xA0, 0xE8,
++	0x0C, 0x47, 0xA0, 0xE8,
+ 
+-0x1C, 0x57, 0xA0, 0xE8,
+-0x2C, 0x67, 0xA0, 0xE8,
++	0x1C, 0x57, 0xA0, 0xE8,
++	0x2C, 0x67, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x57, 0x80, 0x57, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x57, 0x80, 0x57, 0xCF,
+ 
+-0x66, 0x33, 0x66, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x66, 0x33, 0x66, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x67, 0x3B, 0x67, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x67, 0x3B, 0x67, 0xCF,
+ 
+-0x0B, 0x48, 0xA0, 0xE8,
+-0x1B, 0x58, 0xA0, 0xE8,
++	0x0B, 0x48, 0xA0, 0xE8,
++	0x1B, 0x58, 0xA0, 0xE8,
+ 
+-0x2B, 0x68, 0xA0, 0xE8,
+-0x0C, 0x49, 0xA0, 0xE8,
++	0x2B, 0x68, 0xA0, 0xE8,
++	0x0C, 0x49, 0xA0, 0xE8,
+ 
+-0x1C, 0x59, 0xA0, 0xE8,
+-0x2C, 0x69, 0xA0, 0xE8,
++	0x1C, 0x59, 0xA0, 0xE8,
++	0x2C, 0x69, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x34, 0xD7, 0x34, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x34, 0xD7, 0x34, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3C, 0xD7, 0x3C, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3C, 0xD7, 0x3C, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x34, 0x80, 0x34, 0xBD,
+-0x3C, 0x80, 0x3C, 0xBD,
++	0x34, 0x80, 0x34, 0xBD,
++	0x3C, 0x80, 0x3C, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x48, 0x80, 0x48, 0xCF,
+-0x59, 0x80, 0x59, 0xCF,
++	0x48, 0x80, 0x48, 0xCF,
++	0x59, 0x80, 0x59, 0xCF,
+ 
+-0x68, 0x33, 0x68, 0xCF,
+-0x49, 0x3B, 0x49, 0xCF,
++	0x68, 0x33, 0x68, 0xCF,
++	0x49, 0x3B, 0x49, 0xCF,
+ 
+-0xA9, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xA9, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x58, 0x33, 0x58, 0xCF,
+-0x69, 0x3B, 0x69, 0xCF,
++	0x58, 0x33, 0x58, 0xCF,
++	0x69, 0x3B, 0x69, 0xCF,
+ 
+-0x67, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x67, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_t2gzsf[] = {
+ 
+-0x00, 0x8A, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x8A, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x0A, 0x40, 0x50, 0xBF,
+-0x2A, 0x40, 0x60, 0xBF,
++	0x0A, 0x40, 0x50, 0xBF,
++	0x2A, 0x40, 0x60, 0xBF,
+ 
+-0x32, 0x41, 0x51, 0xBF,
+-0x3A, 0x41, 0x61, 0xBF,
++	0x32, 0x41, 0x51, 0xBF,
++	0x3A, 0x41, 0x61, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xD3, 0x6B,
+-0x00, 0x8A, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xD3, 0x6B,
++	0x00, 0x8A, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x23, 0x9F,
+-0x00, 0xE0,
+-0x51, 0x04,
++	0xAD, 0xEE, 0x23, 0x9F,
++	0x00, 0xE0,
++	0x51, 0x04,
+ 
+-0x90, 0xE2,
+-0x61, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x61, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x51, 0x41, 0xE0, 0xEC,
+-0x39, 0x67, 0xB1, 0xE8,
++	0x51, 0x41, 0xE0, 0xEC,
++	0x39, 0x67, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x63, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x63, 0xA0, 0xE8,
+ 
+-0x61, 0x41, 0xE0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x61, 0x41, 0xE0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x8A, 0x80, 0x15, 0xEA,
+-0x10, 0x04,
+-0x20, 0x04,
++	0x8A, 0x80, 0x15, 0xEA,
++	0x10, 0x04,
++	0x20, 0x04,
+ 
+-0x61, 0x51, 0xE0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x61, 0x51, 0xE0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x52, 0xBF,
+-0x0F, 0x52, 0xA0, 0xE8,
++	0x2A, 0x42, 0x52, 0xBF,
++	0x0F, 0x52, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x62, 0xBF,
+-0x1E, 0x51, 0x60, 0xEA,
++	0x1A, 0x42, 0x62, 0xBF,
++	0x1E, 0x51, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x0E, 0x61, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x0E, 0x61, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x50, 0xBD,
+-0x22, 0x40, 0x60, 0xBD,
++	0x32, 0x40, 0x50, 0xBD,
++	0x22, 0x40, 0x60, 0xBD,
+ 
+-0x12, 0x41, 0x51, 0xBD,
+-0x3A, 0x41, 0x61, 0xBD,
++	0x12, 0x41, 0x51, 0xBD,
++	0x3A, 0x41, 0x61, 0xBD,
+ 
+-0xBF, 0x2F, 0x0E, 0xBD,
+-0x97, 0xE2,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x0E, 0xBD,
++	0x97, 0xE2,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x35, 0x48, 0xB1, 0xE8,
+-0x3D, 0x59, 0xB1, 0xE8,
++	0x35, 0x48, 0xB1, 0xE8,
++	0x3D, 0x59, 0xB1, 0xE8,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x56, 0x31, 0x56, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x66, 0x31, 0x66, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x66, 0x31, 0x66, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x57, 0x39, 0x57, 0xBF,
+-0x67, 0x39, 0x67, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
++	0x67, 0x39, 0x67, 0xBF,
+ 
+-0x7B, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x7B, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x35, 0x00,
+-0x3D, 0x00,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x35, 0x00,
++	0x3D, 0x00,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0x8D, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0x8D, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x75, 0xF8, 0xEC,
+-0x35, 0x20,
+-0x3D, 0x20,
++	0x43, 0x75, 0xF8, 0xEC,
++	0x35, 0x20,
++	0x3D, 0x20,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x53, 0x53, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x53, 0x53, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x0E, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x0E, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x48, 0x35, 0x48, 0xBF,
+-0x58, 0x35, 0x58, 0xBF,
++	0x48, 0x35, 0x48, 0xBF,
++	0x58, 0x35, 0x58, 0xBF,
+ 
+-0x68, 0x35, 0x68, 0xBF,
+-0x49, 0x3D, 0x49, 0xBF,
++	0x68, 0x35, 0x68, 0xBF,
++	0x49, 0x3D, 0x49, 0xBF,
+ 
+-0x59, 0x3D, 0x59, 0xBF,
+-0x69, 0x3D, 0x69, 0xBF,
++	0x59, 0x3D, 0x59, 0xBF,
++	0x69, 0x3D, 0x69, 0xBF,
+ 
+-0x63, 0x63, 0x2D, 0xDF,
+-0x4D, 0x7D, 0xF8, 0xEC,
++	0x63, 0x63, 0x2D, 0xDF,
++	0x4D, 0x7D, 0xF8, 0xEC,
+ 
+-0x59, 0xE3,
+-0x00, 0xE0,
+-0xB8, 0x38, 0x33, 0xBF,
++	0x59, 0xE3,
++	0x00, 0xE0,
++	0xB8, 0x38, 0x33, 0xBF,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x18, 0x3A, 0x41, 0xE9,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x18, 0x3A, 0x41, 0xE9,
+ 
+-0x3F, 0x53, 0xA0, 0xE8,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x3F, 0x53, 0xA0, 0xE8,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x63, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x63, 0xA0, 0xE8,
+ 
+-0x50, 0x70, 0xF8, 0xEC,
+-0x2B, 0x50, 0x3C, 0xE9,
++	0x50, 0x70, 0xF8, 0xEC,
++	0x2B, 0x50, 0x3C, 0xE9,
+ 
+-0x1F, 0x0F, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x0F, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x59, 0x78, 0xF8, 0xEC,
+-0x00, 0x80, 0x00, 0xE8,
++	0x59, 0x78, 0xF8, 0xEC,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x56, 0x3F, 0x56, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x56, 0x3F, 0x56, 0xDF,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x66, 0x3D, 0x66, 0xDF,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x66, 0x3D, 0x66, 0xDF,
+ 
+-0x1D, 0x32, 0x41, 0xE9,
+-0x67, 0x3D, 0x67, 0xDF,
++	0x1D, 0x32, 0x41, 0xE9,
++	0x67, 0x3D, 0x67, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3F, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3F, 0x57, 0xDF,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x59, 0x3F, 0x59, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x59, 0x3F, 0x59, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x69, 0x3D, 0x69, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x69, 0x3D, 0x69, 0xDF,
+ 
+-0x48, 0x37, 0x48, 0xDF,
+-0x58, 0x3F, 0x58, 0xDF,
++	0x48, 0x37, 0x48, 0xDF,
++	0x58, 0x3F, 0x58, 0xDF,
+ 
+-0x68, 0x3D, 0x68, 0xDF,
+-0x49, 0x37, 0x49, 0xDF,
++	0x68, 0x3D, 0x68, 0xDF,
++	0x49, 0x37, 0x49, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x0F, 0xCF, 0x74, 0xC2,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x0F, 0xCF, 0x74, 0xC2,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x54, 0xB0,
+-0x02, 0x44, 0x64, 0xB0,
++	0x0A, 0x44, 0x54, 0xB0,
++	0x02, 0x44, 0x64, 0xB0,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x34, 0x37, 0x20, 0xE9,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x38, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x38, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB2,
+-0x1A, 0x44, 0x64, 0xB2,
++	0x2A, 0x44, 0x54, 0xB2,
++	0x1A, 0x44, 0x64, 0xB2,
+ 
+-0x36, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x36, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x0F, 0xCF, 0x75, 0xC0,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0F, 0xCF, 0x75, 0xC0,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x3D, 0xCF, 0x75, 0xC2,
+-0x37, 0xCF, 0x75, 0xC4,
++	0x3D, 0xCF, 0x75, 0xC2,
++	0x37, 0xCF, 0x75, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA6, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA6, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA3, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA3, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x54, 0xB4,
+-0x1A, 0x44, 0x64, 0xB4,
++	0x2A, 0x44, 0x54, 0xB4,
++	0x1A, 0x44, 0x64, 0xB4,
+ 
+-0x0A, 0x45, 0x55, 0xB0,
+-0x02, 0x45, 0x65, 0xB0,
++	0x0A, 0x45, 0x55, 0xB0,
++	0x02, 0x45, 0x65, 0xB0,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA0, 0x37, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA0, 0x37, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x55, 0xB2,
+-0x1A, 0x45, 0x65, 0xB2,
++	0x2A, 0x45, 0x55, 0xB2,
++	0x1A, 0x45, 0x65, 0xB2,
+ 
+-0x0A, 0x45, 0x55, 0xB4,
+-0x02, 0x45, 0x65, 0xB4,
++	0x0A, 0x45, 0x55, 0xB4,
++	0x02, 0x45, 0x65, 0xB4,
+ 
+-0x0F, 0xCF, 0x75, 0xC6,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0F, 0xCF, 0x75, 0xC6,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA7, 0x30, 0x4F, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA7, 0x30, 0x4F, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x31, 0x0F, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x31, 0x0F, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA8, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA8, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x55, 0xB6,
+-0x1A, 0x45, 0x65, 0xB6,
++	0x2A, 0x45, 0x55, 0xB6,
++	0x1A, 0x45, 0x65, 0xB6,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x00, 0x80, 0x00, 0xE8,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x2A, 0x46, 0x56, 0xBF,
+-0x1A, 0x46, 0x66, 0xBF,
++	0x2A, 0x46, 0x56, 0xBF,
++	0x1A, 0x46, 0x66, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA4, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA4, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA5, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA5, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x47, 0x57, 0xBF,
+-0x02, 0x47, 0x67, 0xBF,
++	0x0A, 0x47, 0x57, 0xBF,
++	0x02, 0x47, 0x67, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA1, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA1, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA2, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA2, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x53, 0xBF,
+-0x1A, 0x43, 0x63, 0xBF,
++	0x2A, 0x43, 0x53, 0xBF,
++	0x1A, 0x43, 0x63, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x35, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x35, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x39, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x39, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x48, 0x58, 0xBF,
+-0x02, 0x48, 0x68, 0xBF,
++	0x0A, 0x48, 0x58, 0xBF,
++	0x02, 0x48, 0x68, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x2A, 0x49, 0x59, 0xBF,
+-0x1A, 0x49, 0x69, 0xBF,
++	0x2A, 0x49, 0x59, 0xBF,
++	0x1A, 0x49, 0x69, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x82, 0x30, 0x57, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x82, 0x30, 0x57, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x83, 0x38, 0x57, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x83, 0x38, 0x57, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x84, 0x31, 0x5E, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x84, 0x31, 0x5E, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x85, 0x39, 0x5E, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x85, 0x39, 0x5E, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x87, 0x77, 0x57, 0xE9,
+-0x8B, 0x3E, 0xBF, 0xEA,
++	0x87, 0x77, 0x57, 0xE9,
++	0x8B, 0x3E, 0xBF, 0xEA,
+ 
+-0x80, 0x30, 0x57, 0xE9,
+-0x81, 0x38, 0x57, 0xE9,
++	0x80, 0x30, 0x57, 0xE9,
++	0x81, 0x38, 0x57, 0xE9,
+ 
+-0x82, 0x31, 0x57, 0xE9,
+-0x86, 0x78, 0x57, 0xE9,
++	0x82, 0x31, 0x57, 0xE9,
++	0x86, 0x78, 0x57, 0xE9,
+ 
+-0x83, 0x39, 0x57, 0xE9,
+-0x87, 0x79, 0x57, 0xE9,
++	0x83, 0x39, 0x57, 0xE9,
++	0x87, 0x79, 0x57, 0xE9,
+ 
+-0x30, 0x1F, 0x5F, 0xE9,
+-0x8A, 0x34, 0x20, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
++	0x8A, 0x34, 0x20, 0xE9,
+ 
+-0x8B, 0x3C, 0x20, 0xE9,
+-0x37, 0x50, 0x60, 0xBD,
++	0x8B, 0x3C, 0x20, 0xE9,
++	0x37, 0x50, 0x60, 0xBD,
+ 
+-0x57, 0x0D, 0x20, 0xE9,
+-0x35, 0x51, 0x61, 0xBD,
++	0x57, 0x0D, 0x20, 0xE9,
++	0x35, 0x51, 0x61, 0xBD,
+ 
+-0x2B, 0x50, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x50, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x0E, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x0E, 0x77,
+ 
+-0x24, 0x51, 0x20, 0xE9,
+-0x8D, 0xFF, 0x20, 0xEA,
++	0x24, 0x51, 0x20, 0xE9,
++	0x8D, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x0E, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x0E, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x0B, 0x46, 0xA0, 0xE8,
+-0x1B, 0x56, 0xA0, 0xE8,
++	0x0B, 0x46, 0xA0, 0xE8,
++	0x1B, 0x56, 0xA0, 0xE8,
+ 
+-0x2B, 0x66, 0xA0, 0xE8,
+-0x0C, 0x47, 0xA0, 0xE8,
++	0x2B, 0x66, 0xA0, 0xE8,
++	0x0C, 0x47, 0xA0, 0xE8,
+ 
+-0x1C, 0x57, 0xA0, 0xE8,
+-0x2C, 0x67, 0xA0, 0xE8,
++	0x1C, 0x57, 0xA0, 0xE8,
++	0x2C, 0x67, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x57, 0x80, 0x57, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x57, 0x80, 0x57, 0xCF,
+ 
+-0x66, 0x33, 0x66, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x66, 0x33, 0x66, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x67, 0x3B, 0x67, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x67, 0x3B, 0x67, 0xCF,
+ 
+-0x0B, 0x48, 0xA0, 0xE8,
+-0x1B, 0x58, 0xA0, 0xE8,
++	0x0B, 0x48, 0xA0, 0xE8,
++	0x1B, 0x58, 0xA0, 0xE8,
+ 
+-0x2B, 0x68, 0xA0, 0xE8,
+-0x0C, 0x49, 0xA0, 0xE8,
++	0x2B, 0x68, 0xA0, 0xE8,
++	0x0C, 0x49, 0xA0, 0xE8,
+ 
+-0x1C, 0x59, 0xA0, 0xE8,
+-0x2C, 0x69, 0xA0, 0xE8,
++	0x1C, 0x59, 0xA0, 0xE8,
++	0x2C, 0x69, 0xA0, 0xE8,
+ 
+-0x0B, 0x00,
+-0x1B, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x0B, 0x00,
++	0x1B, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x0C, 0x00,
+-0x1C, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x0C, 0x00,
++	0x1C, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x0B, 0x65,
+-0x1B, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x0B, 0x65,
++	0x1B, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x0C, 0x65,
+-0x1C, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x0C, 0x65,
++	0x1C, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x0B, 0x1B, 0x60, 0xEC,
+-0x34, 0xD7, 0x34, 0xAD,
++	0x0B, 0x1B, 0x60, 0xEC,
++	0x34, 0xD7, 0x34, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x0C, 0x1C, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x0C, 0x1C, 0x60, 0xEC,
+ 
+-0x3C, 0xD7, 0x3C, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3C, 0xD7, 0x3C, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x0B, 0x2B, 0xDE, 0xE8,
+-0x1B, 0x80, 0xDE, 0xE8,
++	0x0B, 0x2B, 0xDE, 0xE8,
++	0x1B, 0x80, 0xDE, 0xE8,
+ 
+-0x34, 0x80, 0x34, 0xBD,
+-0x3C, 0x80, 0x3C, 0xBD,
++	0x34, 0x80, 0x34, 0xBD,
++	0x3C, 0x80, 0x3C, 0xBD,
+ 
+-0x33, 0xD7, 0x0B, 0xBD,
+-0x3B, 0xD7, 0x1B, 0xBD,
++	0x33, 0xD7, 0x0B, 0xBD,
++	0x3B, 0xD7, 0x1B, 0xBD,
+ 
+-0x48, 0x80, 0x48, 0xCF,
+-0x59, 0x80, 0x59, 0xCF,
++	0x48, 0x80, 0x48, 0xCF,
++	0x59, 0x80, 0x59, 0xCF,
+ 
+-0x68, 0x33, 0x68, 0xCF,
+-0x49, 0x3B, 0x49, 0xCF,
++	0x68, 0x33, 0x68, 0xCF,
++	0x49, 0x3B, 0x49, 0xCF,
+ 
+-0xAD, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xAD, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x58, 0x33, 0x58, 0xCF,
+-0x69, 0x3B, 0x69, 0xCF,
++	0x58, 0x33, 0x58, 0xCF,
++	0x69, 0x3B, 0x69, 0xCF,
+ 
+-0x6B, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x6B, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_tgz[] = {
+ 
+-0x00, 0x88, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x88, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x22, 0x40, 0x48, 0xBF,
+-0x2A, 0x40, 0x50, 0xBF,
++	0x22, 0x40, 0x48, 0xBF,
++	0x2A, 0x40, 0x50, 0xBF,
+ 
+-0x32, 0x41, 0x49, 0xBF,
+-0x3A, 0x41, 0x51, 0xBF,
++	0x32, 0x41, 0x49, 0xBF,
++	0x3A, 0x41, 0x51, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xCB, 0x6B,
+-0x00, 0x88, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xCB, 0x6B,
++	0x00, 0x88, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x4B, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x4B, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x29, 0x9F,
+-0x00, 0xE0,
+-0x49, 0x04,
++	0xAD, 0xEE, 0x29, 0x9F,
++	0x00, 0xE0,
++	0x49, 0x04,
+ 
+-0x90, 0xE2,
+-0x51, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x51, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x49, 0x41, 0xC0, 0xEC,
+-0x39, 0x57, 0xB1, 0xE8,
++	0x49, 0x41, 0xC0, 0xEC,
++	0x39, 0x57, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0x51, 0x41, 0xC0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x51, 0x41, 0xC0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x58, 0x80, 0x15, 0xEA,
+-0x08, 0x04,
+-0x10, 0x04,
++	0x58, 0x80, 0x15, 0xEA,
++	0x08, 0x04,
++	0x10, 0x04,
+ 
+-0x51, 0x49, 0xC0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x51, 0x49, 0xC0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x4A, 0xBF,
+-0x27, 0x4A, 0xA0, 0xE8,
++	0x2A, 0x42, 0x4A, 0xBF,
++	0x27, 0x4A, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x52, 0xBF,
+-0x1E, 0x49, 0x60, 0xEA,
++	0x1A, 0x42, 0x52, 0xBF,
++	0x1E, 0x49, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x26, 0x51, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x26, 0x51, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x48, 0xBD,
+-0x22, 0x40, 0x50, 0xBD,
++	0x32, 0x40, 0x48, 0xBD,
++	0x22, 0x40, 0x50, 0xBD,
+ 
+-0x12, 0x41, 0x49, 0xBD,
+-0x3A, 0x41, 0x51, 0xBD,
++	0x12, 0x41, 0x49, 0xBD,
++	0x3A, 0x41, 0x51, 0xBD,
+ 
+-0xBF, 0x2F, 0x26, 0xBD,
+-0x00, 0xE0,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x26, 0xBD,
++	0x00, 0xE0,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x4E, 0x31, 0x4E, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x4E, 0x31, 0x4E, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x56, 0x31, 0x56, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x4F, 0x39, 0x4F, 0xBF,
+-0x57, 0x39, 0x57, 0xBF,
++	0x4F, 0x39, 0x4F, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
+ 
+-0x4A, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x4A, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x42, 0x73, 0xF8, 0xEC,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x42, 0x73, 0xF8, 0xEC,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0xA5, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0xA5, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x4B, 0x4B, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x4B, 0x4B, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x26, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x26, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x53, 0x53, 0x2D, 0xDF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x53, 0x53, 0x2D, 0xDF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xB8, 0x38, 0x33, 0xBF,
+-0x00, 0xE0,
+-0x59, 0xE3,
++	0xB8, 0x38, 0x33, 0xBF,
++	0x00, 0xE0,
++	0x59, 0xE3,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x3F, 0x4B, 0xA0, 0xE8,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x3F, 0x4B, 0xA0, 0xE8,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x53, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x53, 0xA0, 0xE8,
+ 
+-0x48, 0x70, 0xF8, 0xEC,
+-0x2B, 0x48, 0x3C, 0xE9,
++	0x48, 0x70, 0xF8, 0xEC,
++	0x2B, 0x48, 0x3C, 0xE9,
+ 
+-0x1F, 0x27, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x27, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x18, 0x3A, 0x41, 0xE9,
+-0x1D, 0x32, 0x41, 0xE9,
++	0x18, 0x3A, 0x41, 0xE9,
++	0x1D, 0x32, 0x41, 0xE9,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x56, 0x3D, 0x56, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x56, 0x3D, 0x56, 0xDF,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x4E, 0x3F, 0x4E, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x4E, 0x3F, 0x4E, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x4F, 0x3F, 0x4F, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x4F, 0x3F, 0x4F, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3D, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3D, 0x57, 0xDF,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x34, 0x80, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x34, 0x80, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x4C, 0xB0,
+-0x02, 0x44, 0x54, 0xB0,
++	0x0A, 0x44, 0x4C, 0xB0,
++	0x02, 0x44, 0x54, 0xB0,
+ 
+-0x2A, 0x44, 0x4C, 0xB2,
+-0x1A, 0x44, 0x54, 0xB2,
++	0x2A, 0x44, 0x4C, 0xB2,
++	0x1A, 0x44, 0x54, 0xB2,
+ 
+-0x1D, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x1D, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x3D, 0xCF, 0x74, 0xC2,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x3D, 0xCF, 0x74, 0xC2,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x2A, 0x44, 0x4C, 0xB4,
+-0x1A, 0x44, 0x54, 0xB4,
++	0x2A, 0x44, 0x4C, 0xB4,
++	0x1A, 0x44, 0x54, 0xB4,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x38, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x38, 0x3D, 0x20, 0xE9,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x2A, 0x46, 0x4E, 0xBF,
+-0x1A, 0x46, 0x56, 0xBF,
++	0x2A, 0x46, 0x4E, 0xBF,
++	0x1A, 0x46, 0x56, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x0A, 0x47, 0x4F, 0xBF,
+-0x02, 0x47, 0x57, 0xBF,
++	0x0A, 0x47, 0x4F, 0xBF,
++	0x02, 0x47, 0x57, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x4B, 0xBF,
+-0x1A, 0x43, 0x53, 0xBF,
++	0x2A, 0x43, 0x4B, 0xBF,
++	0x1A, 0x43, 0x53, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x37, 0x48, 0x50, 0xBD,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x37, 0x48, 0x50, 0xBD,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8B, 0x3E, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8B, 0x3E, 0x20, 0xE9,
+ 
+-0x82, 0x30, 0x57, 0xE9,
+-0x87, 0x77, 0x57, 0xE9,
++	0x82, 0x30, 0x57, 0xE9,
++	0x87, 0x77, 0x57, 0xE9,
+ 
+-0x83, 0x38, 0x57, 0xE9,
+-0x35, 0x49, 0x51, 0xBD,
++	0x83, 0x38, 0x57, 0xE9,
++	0x35, 0x49, 0x51, 0xBD,
+ 
+-0x84, 0x31, 0x5E, 0xE9,
+-0x30, 0x1F, 0x5F, 0xE9,
++	0x84, 0x31, 0x5E, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
+ 
+-0x85, 0x39, 0x5E, 0xE9,
+-0x57, 0x25, 0x20, 0xE9,
++	0x85, 0x39, 0x5E, 0xE9,
++	0x57, 0x25, 0x20, 0xE9,
+ 
+-0x2B, 0x48, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x48, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x26, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x26, 0x77,
+ 
+-0x24, 0x49, 0x20, 0xE9,
+-0xAF, 0xFF, 0x20, 0xEA,
++	0x24, 0x49, 0x20, 0xE9,
++	0xAF, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x26, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x26, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x1C, 0x46, 0xA0, 0xE8,
+-0x23, 0x4E, 0xA0, 0xE8,
++	0x1C, 0x46, 0xA0, 0xE8,
++	0x23, 0x4E, 0xA0, 0xE8,
+ 
+-0x2B, 0x56, 0xA0, 0xE8,
+-0x1D, 0x47, 0xA0, 0xE8,
++	0x2B, 0x56, 0xA0, 0xE8,
++	0x1D, 0x47, 0xA0, 0xE8,
+ 
+-0x24, 0x4F, 0xA0, 0xE8,
+-0x2C, 0x57, 0xA0, 0xE8,
++	0x24, 0x4F, 0xA0, 0xE8,
++	0x2C, 0x57, 0xA0, 0xE8,
+ 
+-0x1C, 0x00,
+-0x23, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x1C, 0x00,
++	0x23, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x1D, 0x00,
+-0x24, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x1D, 0x00,
++	0x24, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x1C, 0x65,
+-0x23, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x1C, 0x65,
++	0x23, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x1D, 0x65,
+-0x24, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x1D, 0x65,
++	0x24, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x1C, 0x23, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x1C, 0x23, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x1D, 0x24, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x1D, 0x24, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x1C, 0x2B, 0xDE, 0xE8,
+-0x23, 0x80, 0xDE, 0xE8,
++	0x1C, 0x2B, 0xDE, 0xE8,
++	0x23, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x1C, 0xBD,
+-0x3B, 0xD7, 0x23, 0xBD,
++	0x33, 0xD7, 0x1C, 0xBD,
++	0x3B, 0xD7, 0x23, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x4F, 0x80, 0x4F, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x4F, 0x80, 0x4F, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0xD6, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xD6, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x4E, 0x33, 0x4E, 0xCF,
+-0x57, 0x3B, 0x57, 0xCF,
++	0x4E, 0x33, 0x4E, 0xCF,
++	0x57, 0x3B, 0x57, 0xCF,
+ 
+-0x9D, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x9D, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_tgza[] = {
+ 
+-0x00, 0x88, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x88, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x22, 0x40, 0x48, 0xBF,
+-0x2A, 0x40, 0x50, 0xBF,
++	0x22, 0x40, 0x48, 0xBF,
++	0x2A, 0x40, 0x50, 0xBF,
+ 
+-0x32, 0x41, 0x49, 0xBF,
+-0x3A, 0x41, 0x51, 0xBF,
++	0x32, 0x41, 0x49, 0xBF,
++	0x3A, 0x41, 0x51, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xCB, 0x6B,
+-0x00, 0x88, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xCB, 0x6B,
++	0x00, 0x88, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x4B, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x4B, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x29, 0x9F,
+-0x00, 0xE0,
+-0x49, 0x04,
++	0xAD, 0xEE, 0x29, 0x9F,
++	0x00, 0xE0,
++	0x49, 0x04,
+ 
+-0x90, 0xE2,
+-0x51, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x51, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x49, 0x41, 0xC0, 0xEC,
+-0x39, 0x57, 0xB1, 0xE8,
++	0x49, 0x41, 0xC0, 0xEC,
++	0x39, 0x57, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0x51, 0x41, 0xC0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x51, 0x41, 0xC0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x5C, 0x80, 0x15, 0xEA,
+-0x08, 0x04,
+-0x10, 0x04,
++	0x5C, 0x80, 0x15, 0xEA,
++	0x08, 0x04,
++	0x10, 0x04,
+ 
+-0x51, 0x49, 0xC0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x51, 0x49, 0xC0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x4A, 0xBF,
+-0x27, 0x4A, 0xA0, 0xE8,
++	0x2A, 0x42, 0x4A, 0xBF,
++	0x27, 0x4A, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x52, 0xBF,
+-0x1E, 0x49, 0x60, 0xEA,
++	0x1A, 0x42, 0x52, 0xBF,
++	0x1E, 0x49, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x26, 0x51, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x26, 0x51, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x48, 0xBD,
+-0x22, 0x40, 0x50, 0xBD,
++	0x32, 0x40, 0x48, 0xBD,
++	0x22, 0x40, 0x50, 0xBD,
+ 
+-0x12, 0x41, 0x49, 0xBD,
+-0x3A, 0x41, 0x51, 0xBD,
++	0x12, 0x41, 0x49, 0xBD,
++	0x3A, 0x41, 0x51, 0xBD,
+ 
+-0xBF, 0x2F, 0x26, 0xBD,
+-0x00, 0xE0,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x26, 0xBD,
++	0x00, 0xE0,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x4E, 0x31, 0x4E, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x4E, 0x31, 0x4E, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x56, 0x31, 0x56, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x4F, 0x39, 0x4F, 0xBF,
+-0x57, 0x39, 0x57, 0xBF,
++	0x4F, 0x39, 0x4F, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
+ 
+-0x4E, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x4E, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x42, 0x73, 0xF8, 0xEC,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x42, 0x73, 0xF8, 0xEC,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0xA5, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0xA5, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x4B, 0x4B, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x4B, 0x4B, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x26, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x26, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x53, 0x53, 0x2D, 0xDF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x53, 0x53, 0x2D, 0xDF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xB8, 0x38, 0x33, 0xBF,
+-0x00, 0xE0,
+-0x59, 0xE3,
++	0xB8, 0x38, 0x33, 0xBF,
++	0x00, 0xE0,
++	0x59, 0xE3,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x3F, 0x4B, 0xA0, 0xE8,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x3F, 0x4B, 0xA0, 0xE8,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x53, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x53, 0xA0, 0xE8,
+ 
+-0x48, 0x70, 0xF8, 0xEC,
+-0x2B, 0x48, 0x3C, 0xE9,
++	0x48, 0x70, 0xF8, 0xEC,
++	0x2B, 0x48, 0x3C, 0xE9,
+ 
+-0x1F, 0x27, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x27, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x18, 0x3A, 0x41, 0xE9,
+-0x1D, 0x32, 0x41, 0xE9,
++	0x18, 0x3A, 0x41, 0xE9,
++	0x1D, 0x32, 0x41, 0xE9,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x56, 0x3D, 0x56, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x56, 0x3D, 0x56, 0xDF,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x4E, 0x3F, 0x4E, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x4E, 0x3F, 0x4E, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x4F, 0x3F, 0x4F, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x4F, 0x3F, 0x4F, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3D, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3D, 0x57, 0xDF,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x34, 0x80, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x34, 0x80, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x27, 0xCF, 0x74, 0xC6,
+-0x3D, 0xCF, 0x74, 0xC2,
++	0x27, 0xCF, 0x74, 0xC6,
++	0x3D, 0xCF, 0x74, 0xC2,
+ 
+-0x0A, 0x44, 0x4C, 0xB0,
+-0x02, 0x44, 0x54, 0xB0,
++	0x0A, 0x44, 0x4C, 0xB0,
++	0x02, 0x44, 0x54, 0xB0,
+ 
+-0x2A, 0x44, 0x4C, 0xB2,
+-0x1A, 0x44, 0x54, 0xB2,
++	0x2A, 0x44, 0x4C, 0xB2,
++	0x1A, 0x44, 0x54, 0xB2,
+ 
+-0x20, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x20, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9C, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9C, 0x27, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x4C, 0xB4,
+-0x02, 0x44, 0x54, 0xB4,
++	0x0A, 0x44, 0x4C, 0xB4,
++	0x02, 0x44, 0x54, 0xB4,
+ 
+-0x2A, 0x44, 0x4C, 0xB6,
+-0x1A, 0x44, 0x54, 0xB6,
++	0x2A, 0x44, 0x4C, 0xB6,
++	0x1A, 0x44, 0x54, 0xB6,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x38, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x38, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x20,
+-0x02, 0x20,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0A, 0x20,
++	0x02, 0x20,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x0A, 0x47, 0x4F, 0xBF,
+-0x02, 0x47, 0x57, 0xBF,
++	0x0A, 0x47, 0x4F, 0xBF,
++	0x02, 0x47, 0x57, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x46, 0x4E, 0xBF,
+-0x1A, 0x46, 0x56, 0xBF,
++	0x2A, 0x46, 0x4E, 0xBF,
++	0x1A, 0x46, 0x56, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x36, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x36, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x37, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x37, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x4B, 0xBF,
+-0x1A, 0x43, 0x53, 0xBF,
++	0x2A, 0x43, 0x4B, 0xBF,
++	0x1A, 0x43, 0x53, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x9D, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x9D, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x9E, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x9E, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x37, 0x48, 0x50, 0xBD,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x37, 0x48, 0x50, 0xBD,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8B, 0x3E, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8B, 0x3E, 0x20, 0xE9,
+ 
+-0x82, 0x30, 0x57, 0xE9,
+-0x87, 0x77, 0x57, 0xE9,
++	0x82, 0x30, 0x57, 0xE9,
++	0x87, 0x77, 0x57, 0xE9,
+ 
+-0x83, 0x38, 0x57, 0xE9,
+-0x35, 0x49, 0x51, 0xBD,
++	0x83, 0x38, 0x57, 0xE9,
++	0x35, 0x49, 0x51, 0xBD,
+ 
+-0x84, 0x31, 0x5E, 0xE9,
+-0x30, 0x1F, 0x5F, 0xE9,
++	0x84, 0x31, 0x5E, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
+ 
+-0x85, 0x39, 0x5E, 0xE9,
+-0x57, 0x25, 0x20, 0xE9,
++	0x85, 0x39, 0x5E, 0xE9,
++	0x57, 0x25, 0x20, 0xE9,
+ 
+-0x2B, 0x48, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x48, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x26, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x26, 0x77,
+ 
+-0x24, 0x49, 0x20, 0xE9,
+-0xAB, 0xFF, 0x20, 0xEA,
++	0x24, 0x49, 0x20, 0xE9,
++	0xAB, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x26, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x26, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x1C, 0x46, 0xA0, 0xE8,
+-0x23, 0x4E, 0xA0, 0xE8,
++	0x1C, 0x46, 0xA0, 0xE8,
++	0x23, 0x4E, 0xA0, 0xE8,
+ 
+-0x2B, 0x56, 0xA0, 0xE8,
+-0x1D, 0x47, 0xA0, 0xE8,
++	0x2B, 0x56, 0xA0, 0xE8,
++	0x1D, 0x47, 0xA0, 0xE8,
+ 
+-0x24, 0x4F, 0xA0, 0xE8,
+-0x2C, 0x57, 0xA0, 0xE8,
++	0x24, 0x4F, 0xA0, 0xE8,
++	0x2C, 0x57, 0xA0, 0xE8,
+ 
+-0x1C, 0x00,
+-0x23, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x1C, 0x00,
++	0x23, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x1D, 0x00,
+-0x24, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x1D, 0x00,
++	0x24, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x1C, 0x65,
+-0x23, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x1C, 0x65,
++	0x23, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x1D, 0x65,
+-0x24, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x1D, 0x65,
++	0x24, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x1C, 0x23, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x1C, 0x23, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x1D, 0x24, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x1D, 0x24, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x1C, 0x2B, 0xDE, 0xE8,
+-0x23, 0x80, 0xDE, 0xE8,
++	0x1C, 0x2B, 0xDE, 0xE8,
++	0x23, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x1C, 0xBD,
+-0x3B, 0xD7, 0x23, 0xBD,
++	0x33, 0xD7, 0x1C, 0xBD,
++	0x3B, 0xD7, 0x23, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x4F, 0x80, 0x4F, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x4F, 0x80, 0x4F, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0xD3, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xD3, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x4E, 0x33, 0x4E, 0xCF,
+-0x57, 0x3B, 0x57, 0xCF,
++	0x4E, 0x33, 0x4E, 0xCF,
++	0x57, 0x3B, 0x57, 0xCF,
+ 
+-0x99, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x99, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_tgzaf[] = {
+ 
+-0x00, 0x88, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x88, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x22, 0x40, 0x48, 0xBF,
+-0x2A, 0x40, 0x50, 0xBF,
++	0x22, 0x40, 0x48, 0xBF,
++	0x2A, 0x40, 0x50, 0xBF,
+ 
+-0x32, 0x41, 0x49, 0xBF,
+-0x3A, 0x41, 0x51, 0xBF,
++	0x32, 0x41, 0x49, 0xBF,
++	0x3A, 0x41, 0x51, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xCB, 0x6B,
+-0x00, 0x88, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xCB, 0x6B,
++	0x00, 0x88, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x4B, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x4B, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x29, 0x9F,
+-0x00, 0xE0,
+-0x49, 0x04,
++	0xAD, 0xEE, 0x29, 0x9F,
++	0x00, 0xE0,
++	0x49, 0x04,
+ 
+-0x90, 0xE2,
+-0x51, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x51, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x49, 0x41, 0xC0, 0xEC,
+-0x39, 0x57, 0xB1, 0xE8,
++	0x49, 0x41, 0xC0, 0xEC,
++	0x39, 0x57, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0x51, 0x41, 0xC0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x51, 0x41, 0xC0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x61, 0x80, 0x15, 0xEA,
+-0x08, 0x04,
+-0x10, 0x04,
++	0x61, 0x80, 0x15, 0xEA,
++	0x08, 0x04,
++	0x10, 0x04,
+ 
+-0x51, 0x49, 0xC0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x51, 0x49, 0xC0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x4A, 0xBF,
+-0x27, 0x4A, 0xA0, 0xE8,
++	0x2A, 0x42, 0x4A, 0xBF,
++	0x27, 0x4A, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x52, 0xBF,
+-0x1E, 0x49, 0x60, 0xEA,
++	0x1A, 0x42, 0x52, 0xBF,
++	0x1E, 0x49, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x26, 0x51, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x26, 0x51, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x48, 0xBD,
+-0x22, 0x40, 0x50, 0xBD,
++	0x32, 0x40, 0x48, 0xBD,
++	0x22, 0x40, 0x50, 0xBD,
+ 
+-0x12, 0x41, 0x49, 0xBD,
+-0x3A, 0x41, 0x51, 0xBD,
++	0x12, 0x41, 0x49, 0xBD,
++	0x3A, 0x41, 0x51, 0xBD,
+ 
+-0xBF, 0x2F, 0x26, 0xBD,
+-0x00, 0xE0,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x26, 0xBD,
++	0x00, 0xE0,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x4E, 0x31, 0x4E, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x4E, 0x31, 0x4E, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x56, 0x31, 0x56, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x4F, 0x39, 0x4F, 0xBF,
+-0x57, 0x39, 0x57, 0xBF,
++	0x4F, 0x39, 0x4F, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
+ 
+-0x53, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x53, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x42, 0x73, 0xF8, 0xEC,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x42, 0x73, 0xF8, 0xEC,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0xA5, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0xA5, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x4B, 0x4B, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x4B, 0x4B, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x26, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x26, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x53, 0x53, 0x2D, 0xDF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x53, 0x53, 0x2D, 0xDF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xB8, 0x38, 0x33, 0xBF,
+-0x00, 0xE0,
+-0x59, 0xE3,
++	0xB8, 0x38, 0x33, 0xBF,
++	0x00, 0xE0,
++	0x59, 0xE3,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x3F, 0x4B, 0xA0, 0xE8,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x3F, 0x4B, 0xA0, 0xE8,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x53, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x53, 0xA0, 0xE8,
+ 
+-0x48, 0x70, 0xF8, 0xEC,
+-0x2B, 0x48, 0x3C, 0xE9,
++	0x48, 0x70, 0xF8, 0xEC,
++	0x2B, 0x48, 0x3C, 0xE9,
+ 
+-0x1F, 0x27, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x27, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x18, 0x3A, 0x41, 0xE9,
+-0x1D, 0x32, 0x41, 0xE9,
++	0x18, 0x3A, 0x41, 0xE9,
++	0x1D, 0x32, 0x41, 0xE9,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x56, 0x3D, 0x56, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x56, 0x3D, 0x56, 0xDF,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x4E, 0x3F, 0x4E, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x4E, 0x3F, 0x4E, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x4F, 0x3F, 0x4F, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x4F, 0x3F, 0x4F, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3D, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3D, 0x57, 0xDF,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x4C, 0xB0,
+-0x02, 0x44, 0x54, 0xB0,
++	0x0A, 0x44, 0x4C, 0xB0,
++	0x02, 0x44, 0x54, 0xB0,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x34, 0x37, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB2,
+-0x1A, 0x44, 0x54, 0xB2,
++	0x2A, 0x44, 0x4C, 0xB2,
++	0x1A, 0x44, 0x54, 0xB2,
+ 
+-0x26, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x26, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x3D, 0xCF, 0x74, 0xC2,
+-0x27, 0xCF, 0x74, 0xC6,
++	0x3D, 0xCF, 0x74, 0xC2,
++	0x27, 0xCF, 0x74, 0xC6,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9C, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9C, 0x27, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x4C, 0xB4,
+-0x02, 0x44, 0x54, 0xB4,
++	0x0A, 0x44, 0x4C, 0xB4,
++	0x02, 0x44, 0x54, 0xB4,
+ 
+-0x2A, 0x44, 0x4C, 0xB6,
+-0x1A, 0x44, 0x54, 0xB6,
++	0x2A, 0x44, 0x4C, 0xB6,
++	0x1A, 0x44, 0x54, 0xB6,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x38, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x38, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x20,
+-0x02, 0x20,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0A, 0x20,
++	0x02, 0x20,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x3D, 0xCF, 0x75, 0xC6,
+-0x00, 0x80, 0x00, 0xE8,
++	0x3D, 0xCF, 0x75, 0xC6,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x0A, 0x45, 0x4D, 0xB6,
+-0x02, 0x45, 0x55, 0xB6,
++	0x0A, 0x45, 0x4D, 0xB6,
++	0x02, 0x45, 0x55, 0xB6,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x3D, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x31, 0x3D, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x2A, 0x46, 0x4E, 0xBF,
+-0x1A, 0x46, 0x56, 0xBF,
++	0x2A, 0x46, 0x4E, 0xBF,
++	0x1A, 0x46, 0x56, 0xBF,
+ 
+-0x0A, 0x47, 0x4F, 0xBF,
+-0x02, 0x47, 0x57, 0xBF,
++	0x0A, 0x47, 0x4F, 0xBF,
++	0x02, 0x47, 0x57, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x38, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9D, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9D, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x9E, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x9E, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x4B, 0xBF,
+-0x1A, 0x43, 0x53, 0xBF,
++	0x2A, 0x43, 0x4B, 0xBF,
++	0x1A, 0x43, 0x53, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x35, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x35, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x39, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x39, 0x38, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x37, 0x48, 0x50, 0xBD,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x37, 0x48, 0x50, 0xBD,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8B, 0x3E, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8B, 0x3E, 0x20, 0xE9,
+ 
+-0x82, 0x30, 0x57, 0xE9,
+-0x87, 0x77, 0x57, 0xE9,
++	0x82, 0x30, 0x57, 0xE9,
++	0x87, 0x77, 0x57, 0xE9,
+ 
+-0x83, 0x38, 0x57, 0xE9,
+-0x35, 0x49, 0x51, 0xBD,
++	0x83, 0x38, 0x57, 0xE9,
++	0x35, 0x49, 0x51, 0xBD,
+ 
+-0x84, 0x31, 0x5E, 0xE9,
+-0x30, 0x1F, 0x5F, 0xE9,
++	0x84, 0x31, 0x5E, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
+ 
+-0x85, 0x39, 0x5E, 0xE9,
+-0x57, 0x25, 0x20, 0xE9,
++	0x85, 0x39, 0x5E, 0xE9,
++	0x57, 0x25, 0x20, 0xE9,
+ 
+-0x2B, 0x48, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x48, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x26, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x26, 0x77,
+ 
+-0x24, 0x49, 0x20, 0xE9,
+-0xA6, 0xFF, 0x20, 0xEA,
++	0x24, 0x49, 0x20, 0xE9,
++	0xA6, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x26, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x26, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x1C, 0x46, 0xA0, 0xE8,
+-0x23, 0x4E, 0xA0, 0xE8,
++	0x1C, 0x46, 0xA0, 0xE8,
++	0x23, 0x4E, 0xA0, 0xE8,
+ 
+-0x2B, 0x56, 0xA0, 0xE8,
+-0x1D, 0x47, 0xA0, 0xE8,
++	0x2B, 0x56, 0xA0, 0xE8,
++	0x1D, 0x47, 0xA0, 0xE8,
+ 
+-0x24, 0x4F, 0xA0, 0xE8,
+-0x2C, 0x57, 0xA0, 0xE8,
++	0x24, 0x4F, 0xA0, 0xE8,
++	0x2C, 0x57, 0xA0, 0xE8,
+ 
+-0x1C, 0x00,
+-0x23, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x1C, 0x00,
++	0x23, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x1D, 0x00,
+-0x24, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x1D, 0x00,
++	0x24, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x1C, 0x65,
+-0x23, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x1C, 0x65,
++	0x23, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x1D, 0x65,
+-0x24, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x1D, 0x65,
++	0x24, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x1C, 0x23, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x1C, 0x23, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x1D, 0x24, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x1D, 0x24, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x1C, 0x2B, 0xDE, 0xE8,
+-0x23, 0x80, 0xDE, 0xE8,
++	0x1C, 0x2B, 0xDE, 0xE8,
++	0x23, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x1C, 0xBD,
+-0x3B, 0xD7, 0x23, 0xBD,
++	0x33, 0xD7, 0x1C, 0xBD,
++	0x3B, 0xD7, 0x23, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x4F, 0x80, 0x4F, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x4F, 0x80, 0x4F, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0xCD, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xCD, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x4E, 0x33, 0x4E, 0xCF,
+-0x57, 0x3B, 0x57, 0xCF,
++	0x4E, 0x33, 0x4E, 0xCF,
++	0x57, 0x3B, 0x57, 0xCF,
+ 
+-0x94, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x94, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_tgzf[] = {
+ 
+-0x00, 0x88, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x88, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x22, 0x40, 0x48, 0xBF,
+-0x2A, 0x40, 0x50, 0xBF,
++	0x22, 0x40, 0x48, 0xBF,
++	0x2A, 0x40, 0x50, 0xBF,
+ 
+-0x32, 0x41, 0x49, 0xBF,
+-0x3A, 0x41, 0x51, 0xBF,
++	0x32, 0x41, 0x49, 0xBF,
++	0x3A, 0x41, 0x51, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xCB, 0x6B,
+-0x00, 0x88, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xCB, 0x6B,
++	0x00, 0x88, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x4B, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x4B, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x29, 0x9F,
+-0x00, 0xE0,
+-0x49, 0x04,
++	0xAD, 0xEE, 0x29, 0x9F,
++	0x00, 0xE0,
++	0x49, 0x04,
+ 
+-0x90, 0xE2,
+-0x51, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x51, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x49, 0x41, 0xC0, 0xEC,
+-0x39, 0x57, 0xB1, 0xE8,
++	0x49, 0x41, 0xC0, 0xEC,
++	0x39, 0x57, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0x51, 0x41, 0xC0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x51, 0x41, 0xC0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x5D, 0x80, 0x15, 0xEA,
+-0x08, 0x04,
+-0x10, 0x04,
++	0x5D, 0x80, 0x15, 0xEA,
++	0x08, 0x04,
++	0x10, 0x04,
+ 
+-0x51, 0x49, 0xC0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x51, 0x49, 0xC0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x4A, 0xBF,
+-0x27, 0x4A, 0xA0, 0xE8,
++	0x2A, 0x42, 0x4A, 0xBF,
++	0x27, 0x4A, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x52, 0xBF,
+-0x1E, 0x49, 0x60, 0xEA,
++	0x1A, 0x42, 0x52, 0xBF,
++	0x1E, 0x49, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x26, 0x51, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x26, 0x51, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x48, 0xBD,
+-0x22, 0x40, 0x50, 0xBD,
++	0x32, 0x40, 0x48, 0xBD,
++	0x22, 0x40, 0x50, 0xBD,
+ 
+-0x12, 0x41, 0x49, 0xBD,
+-0x3A, 0x41, 0x51, 0xBD,
++	0x12, 0x41, 0x49, 0xBD,
++	0x3A, 0x41, 0x51, 0xBD,
+ 
+-0xBF, 0x2F, 0x26, 0xBD,
+-0x00, 0xE0,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x26, 0xBD,
++	0x00, 0xE0,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x4E, 0x31, 0x4E, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x4E, 0x31, 0x4E, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x56, 0x31, 0x56, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x4F, 0x39, 0x4F, 0xBF,
+-0x57, 0x39, 0x57, 0xBF,
++	0x4F, 0x39, 0x4F, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
+ 
+-0x4F, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x4F, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x42, 0x73, 0xF8, 0xEC,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x42, 0x73, 0xF8, 0xEC,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0xA5, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0xA5, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x4B, 0x4B, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x4B, 0x4B, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x26, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x26, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x53, 0x53, 0x2D, 0xDF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x53, 0x53, 0x2D, 0xDF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xB8, 0x38, 0x33, 0xBF,
+-0x00, 0xE0,
+-0x59, 0xE3,
++	0xB8, 0x38, 0x33, 0xBF,
++	0x00, 0xE0,
++	0x59, 0xE3,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x3F, 0x4B, 0xA0, 0xE8,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x3F, 0x4B, 0xA0, 0xE8,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x53, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x53, 0xA0, 0xE8,
+ 
+-0x48, 0x70, 0xF8, 0xEC,
+-0x2B, 0x48, 0x3C, 0xE9,
++	0x48, 0x70, 0xF8, 0xEC,
++	0x2B, 0x48, 0x3C, 0xE9,
+ 
+-0x1F, 0x27, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x27, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x18, 0x3A, 0x41, 0xE9,
+-0x1D, 0x32, 0x41, 0xE9,
++	0x18, 0x3A, 0x41, 0xE9,
++	0x1D, 0x32, 0x41, 0xE9,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x56, 0x3D, 0x56, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x56, 0x3D, 0x56, 0xDF,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x4E, 0x3F, 0x4E, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x4E, 0x3F, 0x4E, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x4F, 0x3F, 0x4F, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x4F, 0x3F, 0x4F, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3D, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3D, 0x57, 0xDF,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x34, 0x80, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x34, 0x80, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x27, 0xCF, 0x75, 0xC6,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x27, 0xCF, 0x75, 0xC6,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x4C, 0xB0,
+-0x02, 0x44, 0x54, 0xB0,
++	0x0A, 0x44, 0x4C, 0xB0,
++	0x02, 0x44, 0x54, 0xB0,
+ 
+-0x2A, 0x44, 0x4C, 0xB2,
+-0x1A, 0x44, 0x54, 0xB2,
++	0x2A, 0x44, 0x4C, 0xB2,
++	0x1A, 0x44, 0x54, 0xB2,
+ 
+-0x20, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x20, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x3D, 0xCF, 0x74, 0xC2,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x3D, 0xCF, 0x74, 0xC2,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x31, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x31, 0x27, 0x20, 0xE9,
+ 
+-0x0A, 0x44, 0x4C, 0xB4,
+-0x02, 0x44, 0x54, 0xB4,
++	0x0A, 0x44, 0x4C, 0xB4,
++	0x02, 0x44, 0x54, 0xB4,
+ 
+-0x2A, 0x45, 0x4D, 0xB6,
+-0x1A, 0x45, 0x55, 0xB6,
++	0x2A, 0x45, 0x4D, 0xB6,
++	0x1A, 0x45, 0x55, 0xB6,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x38, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x38, 0x3D, 0x20, 0xE9,
+ 
+-0x0A, 0x20,
+-0x02, 0x20,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0A, 0x20,
++	0x02, 0x20,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x0A, 0x47, 0x4F, 0xBF,
+-0x02, 0x47, 0x57, 0xBF,
++	0x0A, 0x47, 0x4F, 0xBF,
++	0x02, 0x47, 0x57, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x46, 0x4E, 0xBF,
+-0x1A, 0x46, 0x56, 0xBF,
++	0x2A, 0x46, 0x4E, 0xBF,
++	0x1A, 0x46, 0x56, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x36, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x36, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x37, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x37, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x4B, 0xBF,
+-0x1A, 0x43, 0x53, 0xBF,
++	0x2A, 0x43, 0x4B, 0xBF,
++	0x1A, 0x43, 0x53, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x35, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x35, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x39, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x39, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x37, 0x48, 0x50, 0xBD,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x37, 0x48, 0x50, 0xBD,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8B, 0x3E, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8B, 0x3E, 0x20, 0xE9,
+ 
+-0x82, 0x30, 0x57, 0xE9,
+-0x87, 0x77, 0x57, 0xE9,
++	0x82, 0x30, 0x57, 0xE9,
++	0x87, 0x77, 0x57, 0xE9,
+ 
+-0x83, 0x38, 0x57, 0xE9,
+-0x35, 0x49, 0x51, 0xBD,
++	0x83, 0x38, 0x57, 0xE9,
++	0x35, 0x49, 0x51, 0xBD,
+ 
+-0x84, 0x31, 0x5E, 0xE9,
+-0x30, 0x1F, 0x5F, 0xE9,
++	0x84, 0x31, 0x5E, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
+ 
+-0x85, 0x39, 0x5E, 0xE9,
+-0x57, 0x25, 0x20, 0xE9,
++	0x85, 0x39, 0x5E, 0xE9,
++	0x57, 0x25, 0x20, 0xE9,
+ 
+-0x2B, 0x48, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x48, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x26, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x26, 0x77,
+ 
+-0x24, 0x49, 0x20, 0xE9,
+-0xAA, 0xFF, 0x20, 0xEA,
++	0x24, 0x49, 0x20, 0xE9,
++	0xAA, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x26, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x26, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x1C, 0x46, 0xA0, 0xE8,
+-0x23, 0x4E, 0xA0, 0xE8,
++	0x1C, 0x46, 0xA0, 0xE8,
++	0x23, 0x4E, 0xA0, 0xE8,
+ 
+-0x2B, 0x56, 0xA0, 0xE8,
+-0x1D, 0x47, 0xA0, 0xE8,
++	0x2B, 0x56, 0xA0, 0xE8,
++	0x1D, 0x47, 0xA0, 0xE8,
+ 
+-0x24, 0x4F, 0xA0, 0xE8,
+-0x2C, 0x57, 0xA0, 0xE8,
++	0x24, 0x4F, 0xA0, 0xE8,
++	0x2C, 0x57, 0xA0, 0xE8,
+ 
+-0x1C, 0x00,
+-0x23, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x1C, 0x00,
++	0x23, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x1D, 0x00,
+-0x24, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x1D, 0x00,
++	0x24, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x1C, 0x65,
+-0x23, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x1C, 0x65,
++	0x23, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x1D, 0x65,
+-0x24, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x1D, 0x65,
++	0x24, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x1C, 0x23, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x1C, 0x23, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x1D, 0x24, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x1D, 0x24, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x1C, 0x2B, 0xDE, 0xE8,
+-0x23, 0x80, 0xDE, 0xE8,
++	0x1C, 0x2B, 0xDE, 0xE8,
++	0x23, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x1C, 0xBD,
+-0x3B, 0xD7, 0x23, 0xBD,
++	0x33, 0xD7, 0x1C, 0xBD,
++	0x3B, 0xD7, 0x23, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x4F, 0x80, 0x4F, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x4F, 0x80, 0x4F, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0xD3, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xD3, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x4E, 0x33, 0x4E, 0xCF,
+-0x57, 0x3B, 0x57, 0xCF,
++	0x4E, 0x33, 0x4E, 0xCF,
++	0x57, 0x3B, 0x57, 0xCF,
+ 
+-0x98, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x98, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_tgzs[] = {
+ 
+-0x00, 0x88, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x88, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x22, 0x40, 0x48, 0xBF,
+-0x2A, 0x40, 0x50, 0xBF,
++	0x22, 0x40, 0x48, 0xBF,
++	0x2A, 0x40, 0x50, 0xBF,
+ 
+-0x32, 0x41, 0x49, 0xBF,
+-0x3A, 0x41, 0x51, 0xBF,
++	0x32, 0x41, 0x49, 0xBF,
++	0x3A, 0x41, 0x51, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xCB, 0x6B,
+-0x00, 0x88, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xCB, 0x6B,
++	0x00, 0x88, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x4B, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x4B, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x29, 0x9F,
+-0x00, 0xE0,
+-0x49, 0x04,
++	0xAD, 0xEE, 0x29, 0x9F,
++	0x00, 0xE0,
++	0x49, 0x04,
+ 
+-0x90, 0xE2,
+-0x51, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x51, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x49, 0x41, 0xC0, 0xEC,
+-0x39, 0x57, 0xB1, 0xE8,
++	0x49, 0x41, 0xC0, 0xEC,
++	0x39, 0x57, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0x51, 0x41, 0xC0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x51, 0x41, 0xC0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x65, 0x80, 0x15, 0xEA,
+-0x08, 0x04,
+-0x10, 0x04,
++	0x65, 0x80, 0x15, 0xEA,
++	0x08, 0x04,
++	0x10, 0x04,
+ 
+-0x51, 0x49, 0xC0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x51, 0x49, 0xC0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x4A, 0xBF,
+-0x27, 0x4A, 0xA0, 0xE8,
++	0x2A, 0x42, 0x4A, 0xBF,
++	0x27, 0x4A, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x52, 0xBF,
+-0x1E, 0x49, 0x60, 0xEA,
++	0x1A, 0x42, 0x52, 0xBF,
++	0x1E, 0x49, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x26, 0x51, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x26, 0x51, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x48, 0xBD,
+-0x22, 0x40, 0x50, 0xBD,
++	0x32, 0x40, 0x48, 0xBD,
++	0x22, 0x40, 0x50, 0xBD,
+ 
+-0x12, 0x41, 0x49, 0xBD,
+-0x3A, 0x41, 0x51, 0xBD,
++	0x12, 0x41, 0x49, 0xBD,
++	0x3A, 0x41, 0x51, 0xBD,
+ 
+-0xBF, 0x2F, 0x26, 0xBD,
+-0x00, 0xE0,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x26, 0xBD,
++	0x00, 0xE0,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x4E, 0x31, 0x4E, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x4E, 0x31, 0x4E, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x56, 0x31, 0x56, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x4F, 0x39, 0x4F, 0xBF,
+-0x57, 0x39, 0x57, 0xBF,
++	0x4F, 0x39, 0x4F, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
+ 
+-0x57, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x57, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x42, 0x73, 0xF8, 0xEC,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x42, 0x73, 0xF8, 0xEC,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0xA5, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0xA5, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x4B, 0x4B, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x4B, 0x4B, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x26, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x26, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x53, 0x53, 0x2D, 0xDF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x53, 0x53, 0x2D, 0xDF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xB8, 0x38, 0x33, 0xBF,
+-0x00, 0xE0,
+-0x59, 0xE3,
++	0xB8, 0x38, 0x33, 0xBF,
++	0x00, 0xE0,
++	0x59, 0xE3,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x3F, 0x4B, 0xA0, 0xE8,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x3F, 0x4B, 0xA0, 0xE8,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x53, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x53, 0xA0, 0xE8,
+ 
+-0x48, 0x70, 0xF8, 0xEC,
+-0x2B, 0x48, 0x3C, 0xE9,
++	0x48, 0x70, 0xF8, 0xEC,
++	0x2B, 0x48, 0x3C, 0xE9,
+ 
+-0x1F, 0x27, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x27, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x18, 0x3A, 0x41, 0xE9,
+-0x1D, 0x32, 0x41, 0xE9,
++	0x18, 0x3A, 0x41, 0xE9,
++	0x1D, 0x32, 0x41, 0xE9,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x56, 0x3D, 0x56, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x56, 0x3D, 0x56, 0xDF,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x4E, 0x3F, 0x4E, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x4E, 0x3F, 0x4E, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x4F, 0x3F, 0x4F, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x4F, 0x3F, 0x4F, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3D, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3D, 0x57, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x27, 0xCF, 0x74, 0xC2,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x27, 0xCF, 0x74, 0xC2,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x4C, 0xB0,
+-0x02, 0x44, 0x54, 0xB0,
++	0x0A, 0x44, 0x4C, 0xB0,
++	0x02, 0x44, 0x54, 0xB0,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x34, 0x37, 0x20, 0xE9,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x38, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x38, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB2,
+-0x1A, 0x44, 0x54, 0xB2,
++	0x2A, 0x44, 0x4C, 0xB2,
++	0x1A, 0x44, 0x54, 0xB2,
+ 
+-0x29, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x29, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x27, 0xCF, 0x75, 0xC0,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x27, 0xCF, 0x75, 0xC0,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x3D, 0xCF, 0x75, 0xC2,
+-0x37, 0xCF, 0x75, 0xC4,
++	0x3D, 0xCF, 0x75, 0xC2,
++	0x37, 0xCF, 0x75, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA6, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA6, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA3, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA3, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB4,
+-0x1A, 0x44, 0x54, 0xB4,
++	0x2A, 0x44, 0x4C, 0xB4,
++	0x1A, 0x44, 0x54, 0xB4,
+ 
+-0x0A, 0x45, 0x4D, 0xB0,
+-0x02, 0x45, 0x55, 0xB0,
++	0x0A, 0x45, 0x4D, 0xB0,
++	0x02, 0x45, 0x55, 0xB0,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA0, 0x37, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA0, 0x37, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x4D, 0xB2,
+-0x1A, 0x45, 0x55, 0xB2,
++	0x2A, 0x45, 0x4D, 0xB2,
++	0x1A, 0x45, 0x55, 0xB2,
+ 
+-0x0A, 0x45, 0x4D, 0xB4,
+-0x02, 0x45, 0x55, 0xB4,
++	0x0A, 0x45, 0x4D, 0xB4,
++	0x02, 0x45, 0x55, 0xB4,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x20,
+-0x02, 0x20,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x0A, 0x20,
++	0x02, 0x20,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x2A, 0x46, 0x4E, 0xBF,
+-0x1A, 0x46, 0x56, 0xBF,
++	0x2A, 0x46, 0x4E, 0xBF,
++	0x1A, 0x46, 0x56, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0xA7, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0xA7, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0xA8, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0xA8, 0x38, 0x4F, 0xE9,
+ 
+-0x0A, 0x47, 0x4F, 0xBF,
+-0x02, 0x47, 0x57, 0xBF,
++	0x0A, 0x47, 0x4F, 0xBF,
++	0x02, 0x47, 0x57, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA4, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA4, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA5, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA5, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x4B, 0xBF,
+-0x1A, 0x43, 0x53, 0xBF,
++	0x2A, 0x43, 0x4B, 0xBF,
++	0x1A, 0x43, 0x53, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0xA1, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0xA1, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0xA2, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0xA2, 0x38, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x37, 0x48, 0x50, 0xBD,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x37, 0x48, 0x50, 0xBD,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8B, 0x3E, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8B, 0x3E, 0x20, 0xE9,
+ 
+-0x82, 0x30, 0x57, 0xE9,
+-0x87, 0x77, 0x57, 0xE9,
++	0x82, 0x30, 0x57, 0xE9,
++	0x87, 0x77, 0x57, 0xE9,
+ 
+-0x83, 0x38, 0x57, 0xE9,
+-0x35, 0x49, 0x51, 0xBD,
++	0x83, 0x38, 0x57, 0xE9,
++	0x35, 0x49, 0x51, 0xBD,
+ 
+-0x84, 0x31, 0x5E, 0xE9,
+-0x30, 0x1F, 0x5F, 0xE9,
++	0x84, 0x31, 0x5E, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
+ 
+-0x85, 0x39, 0x5E, 0xE9,
+-0x57, 0x25, 0x20, 0xE9,
++	0x85, 0x39, 0x5E, 0xE9,
++	0x57, 0x25, 0x20, 0xE9,
+ 
+-0x2B, 0x48, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x48, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x26, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x26, 0x77,
+ 
+-0x24, 0x49, 0x20, 0xE9,
+-0xA2, 0xFF, 0x20, 0xEA,
++	0x24, 0x49, 0x20, 0xE9,
++	0xA2, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x26, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x26, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x1C, 0x46, 0xA0, 0xE8,
+-0x23, 0x4E, 0xA0, 0xE8,
++	0x1C, 0x46, 0xA0, 0xE8,
++	0x23, 0x4E, 0xA0, 0xE8,
+ 
+-0x2B, 0x56, 0xA0, 0xE8,
+-0x1D, 0x47, 0xA0, 0xE8,
++	0x2B, 0x56, 0xA0, 0xE8,
++	0x1D, 0x47, 0xA0, 0xE8,
+ 
+-0x24, 0x4F, 0xA0, 0xE8,
+-0x2C, 0x57, 0xA0, 0xE8,
++	0x24, 0x4F, 0xA0, 0xE8,
++	0x2C, 0x57, 0xA0, 0xE8,
+ 
+-0x1C, 0x00,
+-0x23, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x1C, 0x00,
++	0x23, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x1D, 0x00,
+-0x24, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x1D, 0x00,
++	0x24, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x1C, 0x65,
+-0x23, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x1C, 0x65,
++	0x23, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x1D, 0x65,
+-0x24, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x1D, 0x65,
++	0x24, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x1C, 0x23, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x1C, 0x23, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x1D, 0x24, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x1D, 0x24, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x1C, 0x2B, 0xDE, 0xE8,
+-0x23, 0x80, 0xDE, 0xE8,
++	0x1C, 0x2B, 0xDE, 0xE8,
++	0x23, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x1C, 0xBD,
+-0x3B, 0xD7, 0x23, 0xBD,
++	0x33, 0xD7, 0x1C, 0xBD,
++	0x3B, 0xD7, 0x23, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x4F, 0x80, 0x4F, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x4F, 0x80, 0x4F, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0xCA, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xCA, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x4E, 0x33, 0x4E, 0xCF,
+-0x57, 0x3B, 0x57, 0xCF,
++	0x4E, 0x33, 0x4E, 0xCF,
++	0x57, 0x3B, 0x57, 0xCF,
+ 
+-0x90, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x90, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_tgzsa[] = {
+ 
+-0x00, 0x88, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x88, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x22, 0x40, 0x48, 0xBF,
+-0x2A, 0x40, 0x50, 0xBF,
++	0x22, 0x40, 0x48, 0xBF,
++	0x2A, 0x40, 0x50, 0xBF,
+ 
+-0x32, 0x41, 0x49, 0xBF,
+-0x3A, 0x41, 0x51, 0xBF,
++	0x32, 0x41, 0x49, 0xBF,
++	0x3A, 0x41, 0x51, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xCB, 0x6B,
+-0x00, 0x88, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xCB, 0x6B,
++	0x00, 0x88, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x4B, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x4B, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x29, 0x9F,
+-0x00, 0xE0,
+-0x49, 0x04,
++	0xAD, 0xEE, 0x29, 0x9F,
++	0x00, 0xE0,
++	0x49, 0x04,
+ 
+-0x90, 0xE2,
+-0x51, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x51, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x49, 0x41, 0xC0, 0xEC,
+-0x39, 0x57, 0xB1, 0xE8,
++	0x49, 0x41, 0xC0, 0xEC,
++	0x39, 0x57, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0x51, 0x41, 0xC0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x51, 0x41, 0xC0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x6A, 0x80, 0x15, 0xEA,
+-0x08, 0x04,
+-0x10, 0x04,
++	0x6A, 0x80, 0x15, 0xEA,
++	0x08, 0x04,
++	0x10, 0x04,
+ 
+-0x51, 0x49, 0xC0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x51, 0x49, 0xC0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x4A, 0xBF,
+-0x27, 0x4A, 0xA0, 0xE8,
++	0x2A, 0x42, 0x4A, 0xBF,
++	0x27, 0x4A, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x52, 0xBF,
+-0x1E, 0x49, 0x60, 0xEA,
++	0x1A, 0x42, 0x52, 0xBF,
++	0x1E, 0x49, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x26, 0x51, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x26, 0x51, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x48, 0xBD,
+-0x22, 0x40, 0x50, 0xBD,
++	0x32, 0x40, 0x48, 0xBD,
++	0x22, 0x40, 0x50, 0xBD,
+ 
+-0x12, 0x41, 0x49, 0xBD,
+-0x3A, 0x41, 0x51, 0xBD,
++	0x12, 0x41, 0x49, 0xBD,
++	0x3A, 0x41, 0x51, 0xBD,
+ 
+-0xBF, 0x2F, 0x26, 0xBD,
+-0x00, 0xE0,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x26, 0xBD,
++	0x00, 0xE0,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x4E, 0x31, 0x4E, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x4E, 0x31, 0x4E, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x56, 0x31, 0x56, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x4F, 0x39, 0x4F, 0xBF,
+-0x57, 0x39, 0x57, 0xBF,
++	0x4F, 0x39, 0x4F, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
+ 
+-0x5C, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x5C, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x42, 0x73, 0xF8, 0xEC,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x42, 0x73, 0xF8, 0xEC,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0xA5, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0xA5, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x4B, 0x4B, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x4B, 0x4B, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x26, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x26, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x53, 0x53, 0x2D, 0xDF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x53, 0x53, 0x2D, 0xDF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xB8, 0x38, 0x33, 0xBF,
+-0x00, 0xE0,
+-0x59, 0xE3,
++	0xB8, 0x38, 0x33, 0xBF,
++	0x00, 0xE0,
++	0x59, 0xE3,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x3F, 0x4B, 0xA0, 0xE8,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x3F, 0x4B, 0xA0, 0xE8,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x53, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x53, 0xA0, 0xE8,
+ 
+-0x48, 0x70, 0xF8, 0xEC,
+-0x2B, 0x48, 0x3C, 0xE9,
++	0x48, 0x70, 0xF8, 0xEC,
++	0x2B, 0x48, 0x3C, 0xE9,
+ 
+-0x1F, 0x27, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x27, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x18, 0x3A, 0x41, 0xE9,
+-0x1D, 0x32, 0x41, 0xE9,
++	0x18, 0x3A, 0x41, 0xE9,
++	0x1D, 0x32, 0x41, 0xE9,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x56, 0x3D, 0x56, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x56, 0x3D, 0x56, 0xDF,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x4E, 0x3F, 0x4E, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x4E, 0x3F, 0x4E, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x4F, 0x3F, 0x4F, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x4F, 0x3F, 0x4F, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3D, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3D, 0x57, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x27, 0xCF, 0x74, 0xC2,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x27, 0xCF, 0x74, 0xC2,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x4C, 0xB0,
+-0x02, 0x44, 0x54, 0xB0,
++	0x0A, 0x44, 0x4C, 0xB0,
++	0x02, 0x44, 0x54, 0xB0,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x34, 0x37, 0x20, 0xE9,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x38, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x38, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB2,
+-0x1A, 0x44, 0x54, 0xB2,
++	0x2A, 0x44, 0x4C, 0xB2,
++	0x1A, 0x44, 0x54, 0xB2,
+ 
+-0x2E, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x2E, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x27, 0xCF, 0x75, 0xC0,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x27, 0xCF, 0x75, 0xC0,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x3D, 0xCF, 0x75, 0xC2,
+-0x37, 0xCF, 0x75, 0xC4,
++	0x3D, 0xCF, 0x75, 0xC2,
++	0x37, 0xCF, 0x75, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA6, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA6, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA3, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA3, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB4,
+-0x1A, 0x44, 0x54, 0xB4,
++	0x2A, 0x44, 0x4C, 0xB4,
++	0x1A, 0x44, 0x54, 0xB4,
+ 
+-0x0A, 0x45, 0x4D, 0xB0,
+-0x02, 0x45, 0x55, 0xB0,
++	0x0A, 0x45, 0x4D, 0xB0,
++	0x02, 0x45, 0x55, 0xB0,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA0, 0x37, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA0, 0x37, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x4D, 0xB2,
+-0x1A, 0x45, 0x55, 0xB2,
++	0x2A, 0x45, 0x4D, 0xB2,
++	0x1A, 0x45, 0x55, 0xB2,
+ 
+-0x0A, 0x45, 0x4D, 0xB4,
+-0x02, 0x45, 0x55, 0xB4,
++	0x0A, 0x45, 0x4D, 0xB4,
++	0x02, 0x45, 0x55, 0xB4,
+ 
+-0x27, 0xCF, 0x74, 0xC6,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x27, 0xCF, 0x74, 0xC6,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA7, 0x30, 0x4F, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA7, 0x30, 0x4F, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9C, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9C, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA8, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA8, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB6,
+-0x1A, 0x44, 0x54, 0xB6,
++	0x2A, 0x44, 0x4C, 0xB6,
++	0x1A, 0x44, 0x54, 0xB6,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x00, 0x80, 0x00, 0xE8,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x2A, 0x46, 0x4E, 0xBF,
+-0x1A, 0x46, 0x56, 0xBF,
++	0x2A, 0x46, 0x4E, 0xBF,
++	0x1A, 0x46, 0x56, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA4, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA4, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA5, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA5, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x47, 0x4F, 0xBF,
+-0x02, 0x47, 0x57, 0xBF,
++	0x0A, 0x47, 0x4F, 0xBF,
++	0x02, 0x47, 0x57, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA1, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA1, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA2, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA2, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x4B, 0xBF,
+-0x1A, 0x43, 0x53, 0xBF,
++	0x2A, 0x43, 0x4B, 0xBF,
++	0x1A, 0x43, 0x53, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x9D, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x9D, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x9E, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x9E, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x37, 0x48, 0x50, 0xBD,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x37, 0x48, 0x50, 0xBD,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8B, 0x3E, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8B, 0x3E, 0x20, 0xE9,
+ 
+-0x82, 0x30, 0x57, 0xE9,
+-0x87, 0x77, 0x57, 0xE9,
++	0x82, 0x30, 0x57, 0xE9,
++	0x87, 0x77, 0x57, 0xE9,
+ 
+-0x83, 0x38, 0x57, 0xE9,
+-0x35, 0x49, 0x51, 0xBD,
++	0x83, 0x38, 0x57, 0xE9,
++	0x35, 0x49, 0x51, 0xBD,
+ 
+-0x84, 0x31, 0x5E, 0xE9,
+-0x30, 0x1F, 0x5F, 0xE9,
++	0x84, 0x31, 0x5E, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
+ 
+-0x85, 0x39, 0x5E, 0xE9,
+-0x57, 0x25, 0x20, 0xE9,
++	0x85, 0x39, 0x5E, 0xE9,
++	0x57, 0x25, 0x20, 0xE9,
+ 
+-0x2B, 0x48, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x48, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x26, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x26, 0x77,
+ 
+-0x24, 0x49, 0x20, 0xE9,
+-0x9D, 0xFF, 0x20, 0xEA,
++	0x24, 0x49, 0x20, 0xE9,
++	0x9D, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x26, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x26, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x1C, 0x46, 0xA0, 0xE8,
+-0x23, 0x4E, 0xA0, 0xE8,
++	0x1C, 0x46, 0xA0, 0xE8,
++	0x23, 0x4E, 0xA0, 0xE8,
+ 
+-0x2B, 0x56, 0xA0, 0xE8,
+-0x1D, 0x47, 0xA0, 0xE8,
++	0x2B, 0x56, 0xA0, 0xE8,
++	0x1D, 0x47, 0xA0, 0xE8,
+ 
+-0x24, 0x4F, 0xA0, 0xE8,
+-0x2C, 0x57, 0xA0, 0xE8,
++	0x24, 0x4F, 0xA0, 0xE8,
++	0x2C, 0x57, 0xA0, 0xE8,
+ 
+-0x1C, 0x00,
+-0x23, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x1C, 0x00,
++	0x23, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x1D, 0x00,
+-0x24, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x1D, 0x00,
++	0x24, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x1C, 0x65,
+-0x23, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x1C, 0x65,
++	0x23, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x1D, 0x65,
+-0x24, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x1D, 0x65,
++	0x24, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x1C, 0x23, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x1C, 0x23, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x1D, 0x24, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x1D, 0x24, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x1C, 0x2B, 0xDE, 0xE8,
+-0x23, 0x80, 0xDE, 0xE8,
++	0x1C, 0x2B, 0xDE, 0xE8,
++	0x23, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x1C, 0xBD,
+-0x3B, 0xD7, 0x23, 0xBD,
++	0x33, 0xD7, 0x1C, 0xBD,
++	0x3B, 0xD7, 0x23, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x4F, 0x80, 0x4F, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x4F, 0x80, 0x4F, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0xC5, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC5, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x4E, 0x33, 0x4E, 0xCF,
+-0x57, 0x3B, 0x57, 0xCF,
++	0x4E, 0x33, 0x4E, 0xCF,
++	0x57, 0x3B, 0x57, 0xCF,
+ 
+-0x8B, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x8B, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_tgzsaf[] = {
+ 
+-0x00, 0x88, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x88, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x22, 0x40, 0x48, 0xBF,
+-0x2A, 0x40, 0x50, 0xBF,
++	0x22, 0x40, 0x48, 0xBF,
++	0x2A, 0x40, 0x50, 0xBF,
+ 
+-0x32, 0x41, 0x49, 0xBF,
+-0x3A, 0x41, 0x51, 0xBF,
++	0x32, 0x41, 0x49, 0xBF,
++	0x3A, 0x41, 0x51, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xCB, 0x6B,
+-0x00, 0x88, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xCB, 0x6B,
++	0x00, 0x88, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x4B, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x4B, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x29, 0x9F,
+-0x00, 0xE0,
+-0x49, 0x04,
++	0xAD, 0xEE, 0x29, 0x9F,
++	0x00, 0xE0,
++	0x49, 0x04,
+ 
+-0x90, 0xE2,
+-0x51, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x51, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x49, 0x41, 0xC0, 0xEC,
+-0x39, 0x57, 0xB1, 0xE8,
++	0x49, 0x41, 0xC0, 0xEC,
++	0x39, 0x57, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0x51, 0x41, 0xC0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x51, 0x41, 0xC0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x6E, 0x80, 0x15, 0xEA,
+-0x08, 0x04,
+-0x10, 0x04,
++	0x6E, 0x80, 0x15, 0xEA,
++	0x08, 0x04,
++	0x10, 0x04,
+ 
+-0x51, 0x49, 0xC0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x51, 0x49, 0xC0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x4A, 0xBF,
+-0x27, 0x4A, 0xA0, 0xE8,
++	0x2A, 0x42, 0x4A, 0xBF,
++	0x27, 0x4A, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x52, 0xBF,
+-0x1E, 0x49, 0x60, 0xEA,
++	0x1A, 0x42, 0x52, 0xBF,
++	0x1E, 0x49, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x26, 0x51, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x26, 0x51, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x48, 0xBD,
+-0x22, 0x40, 0x50, 0xBD,
++	0x32, 0x40, 0x48, 0xBD,
++	0x22, 0x40, 0x50, 0xBD,
+ 
+-0x12, 0x41, 0x49, 0xBD,
+-0x3A, 0x41, 0x51, 0xBD,
++	0x12, 0x41, 0x49, 0xBD,
++	0x3A, 0x41, 0x51, 0xBD,
+ 
+-0xBF, 0x2F, 0x26, 0xBD,
+-0x00, 0xE0,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x26, 0xBD,
++	0x00, 0xE0,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x4E, 0x31, 0x4E, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x4E, 0x31, 0x4E, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x56, 0x31, 0x56, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x4F, 0x39, 0x4F, 0xBF,
+-0x57, 0x39, 0x57, 0xBF,
++	0x4F, 0x39, 0x4F, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
+ 
+-0x60, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x60, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x42, 0x73, 0xF8, 0xEC,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x42, 0x73, 0xF8, 0xEC,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0xA5, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0xA5, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x4B, 0x4B, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x4B, 0x4B, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x26, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x26, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x53, 0x53, 0x2D, 0xDF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x53, 0x53, 0x2D, 0xDF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xB8, 0x38, 0x33, 0xBF,
+-0x00, 0xE0,
+-0x59, 0xE3,
++	0xB8, 0x38, 0x33, 0xBF,
++	0x00, 0xE0,
++	0x59, 0xE3,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x3F, 0x4B, 0xA0, 0xE8,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x3F, 0x4B, 0xA0, 0xE8,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x53, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x53, 0xA0, 0xE8,
+ 
+-0x48, 0x70, 0xF8, 0xEC,
+-0x2B, 0x48, 0x3C, 0xE9,
++	0x48, 0x70, 0xF8, 0xEC,
++	0x2B, 0x48, 0x3C, 0xE9,
+ 
+-0x1F, 0x27, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x27, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x18, 0x3A, 0x41, 0xE9,
+-0x1D, 0x32, 0x41, 0xE9,
++	0x18, 0x3A, 0x41, 0xE9,
++	0x1D, 0x32, 0x41, 0xE9,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x56, 0x3D, 0x56, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x56, 0x3D, 0x56, 0xDF,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x4E, 0x3F, 0x4E, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x4E, 0x3F, 0x4E, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x4F, 0x3F, 0x4F, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x4F, 0x3F, 0x4F, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3D, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3D, 0x57, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x27, 0xCF, 0x74, 0xC2,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x27, 0xCF, 0x74, 0xC2,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x4C, 0xB0,
+-0x02, 0x44, 0x54, 0xB0,
++	0x0A, 0x44, 0x4C, 0xB0,
++	0x02, 0x44, 0x54, 0xB0,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x34, 0x37, 0x20, 0xE9,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x38, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x38, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB2,
+-0x1A, 0x44, 0x54, 0xB2,
++	0x2A, 0x44, 0x4C, 0xB2,
++	0x1A, 0x44, 0x54, 0xB2,
+ 
+-0x32, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x32, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x27, 0xCF, 0x75, 0xC0,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x27, 0xCF, 0x75, 0xC0,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x3D, 0xCF, 0x75, 0xC2,
+-0x37, 0xCF, 0x75, 0xC4,
++	0x3D, 0xCF, 0x75, 0xC2,
++	0x37, 0xCF, 0x75, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA6, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA6, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA3, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA3, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB4,
+-0x1A, 0x44, 0x54, 0xB4,
++	0x2A, 0x44, 0x4C, 0xB4,
++	0x1A, 0x44, 0x54, 0xB4,
+ 
+-0x0A, 0x45, 0x4D, 0xB0,
+-0x02, 0x45, 0x55, 0xB0,
++	0x0A, 0x45, 0x4D, 0xB0,
++	0x02, 0x45, 0x55, 0xB0,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA0, 0x37, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA0, 0x37, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x4D, 0xB2,
+-0x1A, 0x45, 0x55, 0xB2,
++	0x2A, 0x45, 0x4D, 0xB2,
++	0x1A, 0x45, 0x55, 0xB2,
+ 
+-0x0A, 0x45, 0x4D, 0xB4,
+-0x02, 0x45, 0x55, 0xB4,
++	0x0A, 0x45, 0x4D, 0xB4,
++	0x02, 0x45, 0x55, 0xB4,
+ 
+-0x27, 0xCF, 0x74, 0xC6,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x27, 0xCF, 0x74, 0xC6,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA7, 0x30, 0x4F, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA7, 0x30, 0x4F, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9C, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9C, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA8, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA8, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB6,
+-0x1A, 0x44, 0x54, 0xB6,
++	0x2A, 0x44, 0x4C, 0xB6,
++	0x1A, 0x44, 0x54, 0xB6,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x45, 0x4D, 0xB6,
+-0x02, 0x45, 0x55, 0xB6,
++	0x0A, 0x45, 0x4D, 0xB6,
++	0x02, 0x45, 0x55, 0xB6,
+ 
+-0x3D, 0xCF, 0x75, 0xC6,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x3D, 0xCF, 0x75, 0xC6,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x2A, 0x46, 0x4E, 0xBF,
+-0x1A, 0x46, 0x56, 0xBF,
++	0x2A, 0x46, 0x4E, 0xBF,
++	0x1A, 0x46, 0x56, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA4, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA4, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA5, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA5, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x3D, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x31, 0x3D, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x0A, 0x47, 0x4F, 0xBF,
+-0x02, 0x47, 0x57, 0xBF,
++	0x0A, 0x47, 0x4F, 0xBF,
++	0x02, 0x47, 0x57, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0xA1, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0xA1, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0xA2, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0xA2, 0x38, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x9D, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x9D, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x9E, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x9E, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x4B, 0xBF,
+-0x1A, 0x43, 0x53, 0xBF,
++	0x2A, 0x43, 0x4B, 0xBF,
++	0x1A, 0x43, 0x53, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x35, 0x30, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x35, 0x30, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x39, 0x38, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x39, 0x38, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x37, 0x48, 0x50, 0xBD,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x37, 0x48, 0x50, 0xBD,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8B, 0x3E, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8B, 0x3E, 0x20, 0xE9,
+ 
+-0x82, 0x30, 0x57, 0xE9,
+-0x87, 0x77, 0x57, 0xE9,
++	0x82, 0x30, 0x57, 0xE9,
++	0x87, 0x77, 0x57, 0xE9,
+ 
+-0x83, 0x38, 0x57, 0xE9,
+-0x35, 0x49, 0x51, 0xBD,
++	0x83, 0x38, 0x57, 0xE9,
++	0x35, 0x49, 0x51, 0xBD,
+ 
+-0x84, 0x31, 0x5E, 0xE9,
+-0x30, 0x1F, 0x5F, 0xE9,
++	0x84, 0x31, 0x5E, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
+ 
+-0x85, 0x39, 0x5E, 0xE9,
+-0x57, 0x25, 0x20, 0xE9,
++	0x85, 0x39, 0x5E, 0xE9,
++	0x57, 0x25, 0x20, 0xE9,
+ 
+-0x2B, 0x48, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x48, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x26, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x26, 0x77,
+ 
+-0x24, 0x49, 0x20, 0xE9,
+-0x99, 0xFF, 0x20, 0xEA,
++	0x24, 0x49, 0x20, 0xE9,
++	0x99, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x26, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x26, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x1C, 0x46, 0xA0, 0xE8,
+-0x23, 0x4E, 0xA0, 0xE8,
++	0x1C, 0x46, 0xA0, 0xE8,
++	0x23, 0x4E, 0xA0, 0xE8,
+ 
+-0x2B, 0x56, 0xA0, 0xE8,
+-0x1D, 0x47, 0xA0, 0xE8,
++	0x2B, 0x56, 0xA0, 0xE8,
++	0x1D, 0x47, 0xA0, 0xE8,
+ 
+-0x24, 0x4F, 0xA0, 0xE8,
+-0x2C, 0x57, 0xA0, 0xE8,
++	0x24, 0x4F, 0xA0, 0xE8,
++	0x2C, 0x57, 0xA0, 0xE8,
+ 
+-0x1C, 0x00,
+-0x23, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x1C, 0x00,
++	0x23, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x1D, 0x00,
+-0x24, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x1D, 0x00,
++	0x24, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x1C, 0x65,
+-0x23, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x1C, 0x65,
++	0x23, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x1D, 0x65,
+-0x24, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x1D, 0x65,
++	0x24, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x1C, 0x23, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x1C, 0x23, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x1D, 0x24, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x1D, 0x24, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x1C, 0x2B, 0xDE, 0xE8,
+-0x23, 0x80, 0xDE, 0xE8,
++	0x1C, 0x2B, 0xDE, 0xE8,
++	0x23, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x1C, 0xBD,
+-0x3B, 0xD7, 0x23, 0xBD,
++	0x33, 0xD7, 0x1C, 0xBD,
++	0x3B, 0xD7, 0x23, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x4F, 0x80, 0x4F, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x4F, 0x80, 0x4F, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0xC1, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC1, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x4E, 0x33, 0x4E, 0xCF,
+-0x57, 0x3B, 0x57, 0xCF,
++	0x4E, 0x33, 0x4E, 0xCF,
++	0x57, 0x3B, 0x57, 0xCF,
+ 
+-0x87, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x87, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+ 
+ static unsigned char warp_g400_tgzsf[] = {
+ 
+-0x00, 0x88, 0x98, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x88, 0x98, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+-0xFF, 0x80, 0xC0, 0xE9,
+-0x00, 0x80, 0x00, 0xE8,
++	0xFF, 0x80, 0xC0, 0xE9,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x22, 0x40, 0x48, 0xBF,
+-0x2A, 0x40, 0x50, 0xBF,
++	0x22, 0x40, 0x48, 0xBF,
++	0x2A, 0x40, 0x50, 0xBF,
+ 
+-0x32, 0x41, 0x49, 0xBF,
+-0x3A, 0x41, 0x51, 0xBF,
++	0x32, 0x41, 0x49, 0xBF,
++	0x3A, 0x41, 0x51, 0xBF,
+ 
+-0xC3, 0x6B,
+-0xCB, 0x6B,
+-0x00, 0x88, 0x98, 0xE9,
++	0xC3, 0x6B,
++	0xCB, 0x6B,
++	0x00, 0x88, 0x98, 0xE9,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x96, 0xE2,
+-0x41, 0x04,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x96, 0xE2,
++	0x41, 0x04,
+ 
+-0x7B, 0x43, 0xA0, 0xE8,
+-0x73, 0x4B, 0xA0, 0xE8,
++	0x7B, 0x43, 0xA0, 0xE8,
++	0x73, 0x4B, 0xA0, 0xE8,
+ 
+-0xAD, 0xEE, 0x29, 0x9F,
+-0x00, 0xE0,
+-0x49, 0x04,
++	0xAD, 0xEE, 0x29, 0x9F,
++	0x00, 0xE0,
++	0x49, 0x04,
+ 
+-0x90, 0xE2,
+-0x51, 0x04,
+-0x31, 0x46, 0xB1, 0xE8,
++	0x90, 0xE2,
++	0x51, 0x04,
++	0x31, 0x46, 0xB1, 0xE8,
+ 
+-0x49, 0x41, 0xC0, 0xEC,
+-0x39, 0x57, 0xB1, 0xE8,
++	0x49, 0x41, 0xC0, 0xEC,
++	0x39, 0x57, 0xB1, 0xE8,
+ 
+-0x00, 0x04,
+-0x46, 0xE2,
+-0x73, 0x53, 0xA0, 0xE8,
++	0x00, 0x04,
++	0x46, 0xE2,
++	0x73, 0x53, 0xA0, 0xE8,
+ 
+-0x51, 0x41, 0xC0, 0xEC,
+-0x31, 0x00,
+-0x39, 0x00,
++	0x51, 0x41, 0xC0, 0xEC,
++	0x31, 0x00,
++	0x39, 0x00,
+ 
+-0x6A, 0x80, 0x15, 0xEA,
+-0x08, 0x04,
+-0x10, 0x04,
++	0x6A, 0x80, 0x15, 0xEA,
++	0x08, 0x04,
++	0x10, 0x04,
+ 
+-0x51, 0x49, 0xC0, 0xEC,
+-0x2F, 0x41, 0x60, 0xEA,
++	0x51, 0x49, 0xC0, 0xEC,
++	0x2F, 0x41, 0x60, 0xEA,
+ 
+-0x31, 0x20,
+-0x39, 0x20,
+-0x1F, 0x42, 0xA0, 0xE8,
++	0x31, 0x20,
++	0x39, 0x20,
++	0x1F, 0x42, 0xA0, 0xE8,
+ 
+-0x2A, 0x42, 0x4A, 0xBF,
+-0x27, 0x4A, 0xA0, 0xE8,
++	0x2A, 0x42, 0x4A, 0xBF,
++	0x27, 0x4A, 0xA0, 0xE8,
+ 
+-0x1A, 0x42, 0x52, 0xBF,
+-0x1E, 0x49, 0x60, 0xEA,
++	0x1A, 0x42, 0x52, 0xBF,
++	0x1E, 0x49, 0x60, 0xEA,
+ 
+-0x73, 0x7B, 0xC8, 0xEC,
+-0x26, 0x51, 0x60, 0xEA,
++	0x73, 0x7B, 0xC8, 0xEC,
++	0x26, 0x51, 0x60, 0xEA,
+ 
+-0x32, 0x40, 0x48, 0xBD,
+-0x22, 0x40, 0x50, 0xBD,
++	0x32, 0x40, 0x48, 0xBD,
++	0x22, 0x40, 0x50, 0xBD,
+ 
+-0x12, 0x41, 0x49, 0xBD,
+-0x3A, 0x41, 0x51, 0xBD,
++	0x12, 0x41, 0x49, 0xBD,
++	0x3A, 0x41, 0x51, 0xBD,
+ 
+-0xBF, 0x2F, 0x26, 0xBD,
+-0x00, 0xE0,
+-0x7B, 0x72,
++	0xBF, 0x2F, 0x26, 0xBD,
++	0x00, 0xE0,
++	0x7B, 0x72,
+ 
+-0x32, 0x20,
+-0x22, 0x20,
+-0x12, 0x20,
+-0x3A, 0x20,
++	0x32, 0x20,
++	0x22, 0x20,
++	0x12, 0x20,
++	0x3A, 0x20,
+ 
+-0x46, 0x31, 0x46, 0xBF,
+-0x4E, 0x31, 0x4E, 0xBF,
++	0x46, 0x31, 0x46, 0xBF,
++	0x4E, 0x31, 0x4E, 0xBF,
+ 
+-0xB3, 0xE2, 0x2D, 0x9F,
+-0x00, 0x80, 0x00, 0xE8,
++	0xB3, 0xE2, 0x2D, 0x9F,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x56, 0x31, 0x56, 0xBF,
+-0x47, 0x39, 0x47, 0xBF,
++	0x56, 0x31, 0x56, 0xBF,
++	0x47, 0x39, 0x47, 0xBF,
+ 
+-0x4F, 0x39, 0x4F, 0xBF,
+-0x57, 0x39, 0x57, 0xBF,
++	0x4F, 0x39, 0x4F, 0xBF,
++	0x57, 0x39, 0x57, 0xBF,
+ 
+-0x5C, 0x80, 0x07, 0xEA,
+-0x24, 0x41, 0x20, 0xE9,
++	0x5C, 0x80, 0x07, 0xEA,
++	0x24, 0x41, 0x20, 0xE9,
+ 
+-0x42, 0x73, 0xF8, 0xEC,
+-0x00, 0xE0,
+-0x2D, 0x73,
++	0x42, 0x73, 0xF8, 0xEC,
++	0x00, 0xE0,
++	0x2D, 0x73,
+ 
+-0x33, 0x72,
+-0x0C, 0xE3,
+-0xA5, 0x2F, 0x1E, 0xBD,
++	0x33, 0x72,
++	0x0C, 0xE3,
++	0xA5, 0x2F, 0x1E, 0xBD,
+ 
+-0x43, 0x43, 0x2D, 0xDF,
+-0x4B, 0x4B, 0x2D, 0xDF,
++	0x43, 0x43, 0x2D, 0xDF,
++	0x4B, 0x4B, 0x2D, 0xDF,
+ 
+-0xAE, 0x1E, 0x26, 0xBD,
+-0x58, 0xE3,
+-0x33, 0x66,
++	0xAE, 0x1E, 0x26, 0xBD,
++	0x58, 0xE3,
++	0x33, 0x66,
+ 
+-0x53, 0x53, 0x2D, 0xDF,
+-0x00, 0x80, 0x00, 0xE8,
++	0x53, 0x53, 0x2D, 0xDF,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0xB8, 0x38, 0x33, 0xBF,
+-0x00, 0xE0,
+-0x59, 0xE3,
++	0xB8, 0x38, 0x33, 0xBF,
++	0x00, 0xE0,
++	0x59, 0xE3,
+ 
+-0x1E, 0x12, 0x41, 0xE9,
+-0x1A, 0x22, 0x41, 0xE9,
++	0x1E, 0x12, 0x41, 0xE9,
++	0x1A, 0x22, 0x41, 0xE9,
+ 
+-0x2B, 0x40, 0x3D, 0xE9,
+-0x3F, 0x4B, 0xA0, 0xE8,
++	0x2B, 0x40, 0x3D, 0xE9,
++	0x3F, 0x4B, 0xA0, 0xE8,
+ 
+-0x2D, 0x73,
+-0x30, 0x76,
+-0x05, 0x80, 0x3D, 0xEA,
++	0x2D, 0x73,
++	0x30, 0x76,
++	0x05, 0x80, 0x3D, 0xEA,
+ 
+-0x37, 0x43, 0xA0, 0xE8,
+-0x3D, 0x53, 0xA0, 0xE8,
++	0x37, 0x43, 0xA0, 0xE8,
++	0x3D, 0x53, 0xA0, 0xE8,
+ 
+-0x48, 0x70, 0xF8, 0xEC,
+-0x2B, 0x48, 0x3C, 0xE9,
++	0x48, 0x70, 0xF8, 0xEC,
++	0x2B, 0x48, 0x3C, 0xE9,
+ 
+-0x1F, 0x27, 0xBC, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x1F, 0x27, 0xBC, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x15, 0xC0, 0x20, 0xE9,
+-0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
++	0x15, 0xC0, 0x20, 0xE9,
+ 
+-0x18, 0x3A, 0x41, 0xE9,
+-0x1D, 0x32, 0x41, 0xE9,
++	0x18, 0x3A, 0x41, 0xE9,
++	0x1D, 0x32, 0x41, 0xE9,
+ 
+-0x2A, 0x40, 0x20, 0xE9,
+-0x56, 0x3D, 0x56, 0xDF,
++	0x2A, 0x40, 0x20, 0xE9,
++	0x56, 0x3D, 0x56, 0xDF,
+ 
+-0x46, 0x37, 0x46, 0xDF,
+-0x4E, 0x3F, 0x4E, 0xDF,
++	0x46, 0x37, 0x46, 0xDF,
++	0x4E, 0x3F, 0x4E, 0xDF,
+ 
+-0x16, 0x30, 0x20, 0xE9,
+-0x4F, 0x3F, 0x4F, 0xDF,
++	0x16, 0x30, 0x20, 0xE9,
++	0x4F, 0x3F, 0x4F, 0xDF,
+ 
+-0x47, 0x37, 0x47, 0xDF,
+-0x57, 0x3D, 0x57, 0xDF,
++	0x47, 0x37, 0x47, 0xDF,
++	0x57, 0x3D, 0x57, 0xDF,
+ 
+-0x32, 0x32, 0x2D, 0xDF,
+-0x22, 0x22, 0x2D, 0xDF,
++	0x32, 0x32, 0x2D, 0xDF,
++	0x22, 0x22, 0x2D, 0xDF,
+ 
+-0x12, 0x12, 0x2D, 0xDF,
+-0x3A, 0x3A, 0x2D, 0xDF,
++	0x12, 0x12, 0x2D, 0xDF,
++	0x3A, 0x3A, 0x2D, 0xDF,
+ 
+-0x27, 0xCF, 0x74, 0xC2,
+-0x37, 0xCF, 0x74, 0xC4,
++	0x27, 0xCF, 0x74, 0xC2,
++	0x37, 0xCF, 0x74, 0xC4,
+ 
+-0x0A, 0x44, 0x4C, 0xB0,
+-0x02, 0x44, 0x54, 0xB0,
++	0x0A, 0x44, 0x4C, 0xB0,
++	0x02, 0x44, 0x54, 0xB0,
+ 
+-0x3D, 0xCF, 0x74, 0xC0,
+-0x34, 0x37, 0x20, 0xE9,
++	0x3D, 0xCF, 0x74, 0xC0,
++	0x34, 0x37, 0x20, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x38, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x38, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3C, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3C, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB2,
+-0x1A, 0x44, 0x54, 0xB2,
++	0x2A, 0x44, 0x4C, 0xB2,
++	0x1A, 0x44, 0x54, 0xB2,
+ 
+-0x2E, 0x80, 0x3A, 0xEA,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0x2E, 0x80, 0x3A, 0xEA,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x27, 0xCF, 0x75, 0xC0,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x27, 0xCF, 0x75, 0xC0,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x32, 0x31, 0x5F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x32, 0x31, 0x5F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x33, 0x39, 0x5F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x33, 0x39, 0x5F, 0xE9,
+ 
+-0x3D, 0xCF, 0x75, 0xC2,
+-0x37, 0xCF, 0x75, 0xC4,
++	0x3D, 0xCF, 0x75, 0xC2,
++	0x37, 0xCF, 0x75, 0xC4,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA6, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA6, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA3, 0x3D, 0x20, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA3, 0x3D, 0x20, 0xE9,
+ 
+-0x2A, 0x44, 0x4C, 0xB4,
+-0x1A, 0x44, 0x54, 0xB4,
++	0x2A, 0x44, 0x4C, 0xB4,
++	0x1A, 0x44, 0x54, 0xB4,
+ 
+-0x0A, 0x45, 0x4D, 0xB0,
+-0x02, 0x45, 0x55, 0xB0,
++	0x0A, 0x45, 0x4D, 0xB0,
++	0x02, 0x45, 0x55, 0xB0,
+ 
+-0x88, 0x73, 0x5E, 0xE9,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x88, 0x73, 0x5E, 0xE9,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA0, 0x37, 0x20, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA0, 0x37, 0x20, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x3E, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x3E, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x3F, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x3F, 0x38, 0x4F, 0xE9,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x3A, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x3A, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x3B, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x3B, 0x39, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x4D, 0xB2,
+-0x1A, 0x45, 0x55, 0xB2,
++	0x2A, 0x45, 0x4D, 0xB2,
++	0x1A, 0x45, 0x55, 0xB2,
+ 
+-0x0A, 0x45, 0x4D, 0xB4,
+-0x02, 0x45, 0x55, 0xB4,
++	0x0A, 0x45, 0x4D, 0xB4,
++	0x02, 0x45, 0x55, 0xB4,
+ 
+-0x27, 0xCF, 0x75, 0xC6,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x27, 0xCF, 0x75, 0xC6,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0xA7, 0x30, 0x4F, 0xE9,
+-0x0A, 0x20,
+-0x02, 0x20,
++	0xA7, 0x30, 0x4F, 0xE9,
++	0x0A, 0x20,
++	0x02, 0x20,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x31, 0x27, 0x20, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x31, 0x27, 0x20, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA8, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA8, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x45, 0x4D, 0xB6,
+-0x1A, 0x45, 0x55, 0xB6,
++	0x2A, 0x45, 0x4D, 0xB6,
++	0x1A, 0x45, 0x55, 0xB6,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x36, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x36, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x37, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x37, 0x39, 0x4F, 0xE9,
+ 
+-0x00, 0x80, 0x00, 0xE8,
+-0x2A, 0x20,
+-0x1A, 0x20,
++	0x00, 0x80, 0x00, 0xE8,
++	0x2A, 0x20,
++	0x1A, 0x20,
+ 
+-0x2A, 0x46, 0x4E, 0xBF,
+-0x1A, 0x46, 0x56, 0xBF,
++	0x2A, 0x46, 0x4E, 0xBF,
++	0x1A, 0x46, 0x56, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA4, 0x31, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA4, 0x31, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA5, 0x39, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA5, 0x39, 0x4F, 0xE9,
+ 
+-0x0A, 0x47, 0x4F, 0xBF,
+-0x02, 0x47, 0x57, 0xBF,
++	0x0A, 0x47, 0x4F, 0xBF,
++	0x02, 0x47, 0x57, 0xBF,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0xA1, 0x30, 0x4F, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0xA1, 0x30, 0x4F, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0xA2, 0x38, 0x4F, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0xA2, 0x38, 0x4F, 0xE9,
+ 
+-0x2A, 0x43, 0x4B, 0xBF,
+-0x1A, 0x43, 0x53, 0xBF,
++	0x2A, 0x43, 0x4B, 0xBF,
++	0x1A, 0x43, 0x53, 0xBF,
+ 
+-0x30, 0x50, 0x2E, 0x9F,
+-0x35, 0x31, 0x4F, 0xE9,
++	0x30, 0x50, 0x2E, 0x9F,
++	0x35, 0x31, 0x4F, 0xE9,
+ 
+-0x38, 0x21, 0x2C, 0x9F,
+-0x39, 0x39, 0x4F, 0xE9,
++	0x38, 0x21, 0x2C, 0x9F,
++	0x39, 0x39, 0x4F, 0xE9,
+ 
+-0x31, 0x53, 0x2F, 0x9F,
+-0x80, 0x31, 0x57, 0xE9,
++	0x31, 0x53, 0x2F, 0x9F,
++	0x80, 0x31, 0x57, 0xE9,
+ 
+-0x39, 0xE5, 0x2C, 0x9F,
+-0x81, 0x39, 0x57, 0xE9,
++	0x39, 0xE5, 0x2C, 0x9F,
++	0x81, 0x39, 0x57, 0xE9,
+ 
+-0x37, 0x48, 0x50, 0xBD,
+-0x8A, 0x36, 0x20, 0xE9,
++	0x37, 0x48, 0x50, 0xBD,
++	0x8A, 0x36, 0x20, 0xE9,
+ 
+-0x86, 0x76, 0x57, 0xE9,
+-0x8B, 0x3E, 0x20, 0xE9,
++	0x86, 0x76, 0x57, 0xE9,
++	0x8B, 0x3E, 0x20, 0xE9,
+ 
+-0x82, 0x30, 0x57, 0xE9,
+-0x87, 0x77, 0x57, 0xE9,
++	0x82, 0x30, 0x57, 0xE9,
++	0x87, 0x77, 0x57, 0xE9,
+ 
+-0x83, 0x38, 0x57, 0xE9,
+-0x35, 0x49, 0x51, 0xBD,
++	0x83, 0x38, 0x57, 0xE9,
++	0x35, 0x49, 0x51, 0xBD,
+ 
+-0x84, 0x31, 0x5E, 0xE9,
+-0x30, 0x1F, 0x5F, 0xE9,
++	0x84, 0x31, 0x5E, 0xE9,
++	0x30, 0x1F, 0x5F, 0xE9,
+ 
+-0x85, 0x39, 0x5E, 0xE9,
+-0x57, 0x25, 0x20, 0xE9,
++	0x85, 0x39, 0x5E, 0xE9,
++	0x57, 0x25, 0x20, 0xE9,
+ 
+-0x2B, 0x48, 0x20, 0xE9,
+-0x1D, 0x37, 0xE1, 0xEA,
++	0x2B, 0x48, 0x20, 0xE9,
++	0x1D, 0x37, 0xE1, 0xEA,
+ 
+-0x1E, 0x35, 0xE1, 0xEA,
+-0x00, 0xE0,
+-0x26, 0x77,
++	0x1E, 0x35, 0xE1, 0xEA,
++	0x00, 0xE0,
++	0x26, 0x77,
+ 
+-0x24, 0x49, 0x20, 0xE9,
+-0x9D, 0xFF, 0x20, 0xEA,
++	0x24, 0x49, 0x20, 0xE9,
++	0x9D, 0xFF, 0x20, 0xEA,
+ 
+-0x16, 0x26, 0x20, 0xE9,
+-0x57, 0x2E, 0xBF, 0xEA,
++	0x16, 0x26, 0x20, 0xE9,
++	0x57, 0x2E, 0xBF, 0xEA,
+ 
+-0x1C, 0x46, 0xA0, 0xE8,
+-0x23, 0x4E, 0xA0, 0xE8,
++	0x1C, 0x46, 0xA0, 0xE8,
++	0x23, 0x4E, 0xA0, 0xE8,
+ 
+-0x2B, 0x56, 0xA0, 0xE8,
+-0x1D, 0x47, 0xA0, 0xE8,
++	0x2B, 0x56, 0xA0, 0xE8,
++	0x1D, 0x47, 0xA0, 0xE8,
+ 
+-0x24, 0x4F, 0xA0, 0xE8,
+-0x2C, 0x57, 0xA0, 0xE8,
++	0x24, 0x4F, 0xA0, 0xE8,
++	0x2C, 0x57, 0xA0, 0xE8,
+ 
+-0x1C, 0x00,
+-0x23, 0x00,
+-0x2B, 0x00,
+-0x00, 0xE0,
++	0x1C, 0x00,
++	0x23, 0x00,
++	0x2B, 0x00,
++	0x00, 0xE0,
+ 
+-0x1D, 0x00,
+-0x24, 0x00,
+-0x2C, 0x00,
+-0x00, 0xE0,
++	0x1D, 0x00,
++	0x24, 0x00,
++	0x2C, 0x00,
++	0x00, 0xE0,
+ 
+-0x1C, 0x65,
+-0x23, 0x65,
+-0x2B, 0x65,
+-0x00, 0xE0,
++	0x1C, 0x65,
++	0x23, 0x65,
++	0x2B, 0x65,
++	0x00, 0xE0,
+ 
+-0x1D, 0x65,
+-0x24, 0x65,
+-0x2C, 0x65,
+-0x00, 0xE0,
++	0x1D, 0x65,
++	0x24, 0x65,
++	0x2C, 0x65,
++	0x00, 0xE0,
+ 
+-0x1C, 0x23, 0x60, 0xEC,
+-0x36, 0xD7, 0x36, 0xAD,
++	0x1C, 0x23, 0x60, 0xEC,
++	0x36, 0xD7, 0x36, 0xAD,
+ 
+-0x2B, 0x80, 0x60, 0xEC,
+-0x1D, 0x24, 0x60, 0xEC,
++	0x2B, 0x80, 0x60, 0xEC,
++	0x1D, 0x24, 0x60, 0xEC,
+ 
+-0x3E, 0xD7, 0x3E, 0xAD,
+-0x2C, 0x80, 0x60, 0xEC,
++	0x3E, 0xD7, 0x3E, 0xAD,
++	0x2C, 0x80, 0x60, 0xEC,
+ 
+-0x1C, 0x2B, 0xDE, 0xE8,
+-0x23, 0x80, 0xDE, 0xE8,
++	0x1C, 0x2B, 0xDE, 0xE8,
++	0x23, 0x80, 0xDE, 0xE8,
+ 
+-0x36, 0x80, 0x36, 0xBD,
+-0x3E, 0x80, 0x3E, 0xBD,
++	0x36, 0x80, 0x36, 0xBD,
++	0x3E, 0x80, 0x3E, 0xBD,
+ 
+-0x33, 0xD7, 0x1C, 0xBD,
+-0x3B, 0xD7, 0x23, 0xBD,
++	0x33, 0xD7, 0x1C, 0xBD,
++	0x3B, 0xD7, 0x23, 0xBD,
+ 
+-0x46, 0x80, 0x46, 0xCF,
+-0x4F, 0x80, 0x4F, 0xCF,
++	0x46, 0x80, 0x46, 0xCF,
++	0x4F, 0x80, 0x4F, 0xCF,
+ 
+-0x56, 0x33, 0x56, 0xCF,
+-0x47, 0x3B, 0x47, 0xCF,
++	0x56, 0x33, 0x56, 0xCF,
++	0x47, 0x3B, 0x47, 0xCF,
+ 
+-0xC5, 0xFF, 0x20, 0xEA,
+-0x00, 0x80, 0x00, 0xE8,
++	0xC5, 0xFF, 0x20, 0xEA,
++	0x00, 0x80, 0x00, 0xE8,
+ 
+-0x4E, 0x33, 0x4E, 0xCF,
+-0x57, 0x3B, 0x57, 0xCF,
++	0x4E, 0x33, 0x4E, 0xCF,
++	0x57, 0x3B, 0x57, 0xCF,
+ 
+-0x8B, 0xFF, 0x20, 0xEA,
+-0x57, 0xC0, 0xBF, 0xEA,
++	0x8B, 0xFF, 0x20, 0xEA,
++	0x57, 0xC0, 0xBF, 0xEA,
+ 
+-0x00, 0x80, 0xA0, 0xE9,
+-0x00, 0x00, 0xD8, 0xEC,
++	0x00, 0x80, 0xA0, 0xE9,
++	0x00, 0x00, 0xD8, 0xEC,
+ 
+ };
+diff --git a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c
+--- a/drivers/char/drm/mga_warp.c
++++ b/drivers/char/drm/mga_warp.c
+@@ -33,8 +33,7 @@
+ #include "mga_drv.h"
+ #include "mga_ucode.h"
+ 
+-
+-#define MGA_WARP_CODE_ALIGN		256		/* in bytes */
++#define MGA_WARP_CODE_ALIGN		256	/* in bytes */
+ 
+ #define WARP_UCODE_SIZE( which )					\
+ 	((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN)
+@@ -49,33 +48,30 @@ do {									\
+ } while (0)
+ 
+ static const unsigned int mga_warp_g400_microcode_size =
+-	       (WARP_UCODE_SIZE(warp_g400_tgz) +
+-		WARP_UCODE_SIZE(warp_g400_tgza) +
+-		WARP_UCODE_SIZE(warp_g400_tgzaf) +
+-		WARP_UCODE_SIZE(warp_g400_tgzf) +
+-		WARP_UCODE_SIZE(warp_g400_tgzs) +
+-		WARP_UCODE_SIZE(warp_g400_tgzsa) +
+-		WARP_UCODE_SIZE(warp_g400_tgzsaf) +
+-		WARP_UCODE_SIZE(warp_g400_tgzsf) +
+-		WARP_UCODE_SIZE(warp_g400_t2gz) +
+-		WARP_UCODE_SIZE(warp_g400_t2gza) +
+-		WARP_UCODE_SIZE(warp_g400_t2gzaf) +
+-		WARP_UCODE_SIZE(warp_g400_t2gzf) +
+-		WARP_UCODE_SIZE(warp_g400_t2gzs) +
+-		WARP_UCODE_SIZE(warp_g400_t2gzsa) +
+-		WARP_UCODE_SIZE(warp_g400_t2gzsaf) +
+-		WARP_UCODE_SIZE(warp_g400_t2gzsf));
++    (WARP_UCODE_SIZE(warp_g400_tgz) +
++     WARP_UCODE_SIZE(warp_g400_tgza) +
++     WARP_UCODE_SIZE(warp_g400_tgzaf) +
++     WARP_UCODE_SIZE(warp_g400_tgzf) +
++     WARP_UCODE_SIZE(warp_g400_tgzs) +
++     WARP_UCODE_SIZE(warp_g400_tgzsa) +
++     WARP_UCODE_SIZE(warp_g400_tgzsaf) +
++     WARP_UCODE_SIZE(warp_g400_tgzsf) +
++     WARP_UCODE_SIZE(warp_g400_t2gz) +
++     WARP_UCODE_SIZE(warp_g400_t2gza) +
++     WARP_UCODE_SIZE(warp_g400_t2gzaf) +
++     WARP_UCODE_SIZE(warp_g400_t2gzf) +
++     WARP_UCODE_SIZE(warp_g400_t2gzs) +
++     WARP_UCODE_SIZE(warp_g400_t2gzsa) +
++     WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf));
+ 
+ static const unsigned int mga_warp_g200_microcode_size =
+-	       (WARP_UCODE_SIZE(warp_g200_tgz) +
+-		WARP_UCODE_SIZE(warp_g200_tgza) +
+-		WARP_UCODE_SIZE(warp_g200_tgzaf) +
+-		WARP_UCODE_SIZE(warp_g200_tgzf) +
+-		WARP_UCODE_SIZE(warp_g200_tgzs) +
+-		WARP_UCODE_SIZE(warp_g200_tgzsa) +
+-		WARP_UCODE_SIZE(warp_g200_tgzsaf) +
+-		WARP_UCODE_SIZE(warp_g200_tgzsf));
+-
++    (WARP_UCODE_SIZE(warp_g200_tgz) +
++     WARP_UCODE_SIZE(warp_g200_tgza) +
++     WARP_UCODE_SIZE(warp_g200_tgzaf) +
++     WARP_UCODE_SIZE(warp_g200_tgzf) +
++     WARP_UCODE_SIZE(warp_g200_tgzs) +
++     WARP_UCODE_SIZE(warp_g200_tgzsa) +
++     WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf));
+ 
+ unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
+ {
+@@ -90,36 +86,35 @@ unsigned int mga_warp_microcode_size(con
+ 	}
+ }
+ 
+-static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv )
++static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv)
+ {
+ 	unsigned char *vcbase = dev_priv->warp->handle;
+ 	unsigned long pcbase = dev_priv->warp->offset;
+ 
+-	memset( dev_priv->warp_pipe_phys, 0,
+-		sizeof(dev_priv->warp_pipe_phys) );
++	memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
+ 
+-	WARP_UCODE_INSTALL( warp_g400_tgz,	MGA_WARP_TGZ );
+-	WARP_UCODE_INSTALL( warp_g400_tgzf,	MGA_WARP_TGZF );
+-	WARP_UCODE_INSTALL( warp_g400_tgza,	MGA_WARP_TGZA );
+-	WARP_UCODE_INSTALL( warp_g400_tgzaf,	MGA_WARP_TGZAF );
+-	WARP_UCODE_INSTALL( warp_g400_tgzs,	MGA_WARP_TGZS );
+-	WARP_UCODE_INSTALL( warp_g400_tgzsf,	MGA_WARP_TGZSF );
+-	WARP_UCODE_INSTALL( warp_g400_tgzsa,	MGA_WARP_TGZSA );
+-	WARP_UCODE_INSTALL( warp_g400_tgzsaf,	MGA_WARP_TGZSAF );
+-
+-	WARP_UCODE_INSTALL( warp_g400_t2gz,	MGA_WARP_T2GZ );
+-	WARP_UCODE_INSTALL( warp_g400_t2gzf,	MGA_WARP_T2GZF );
+-	WARP_UCODE_INSTALL( warp_g400_t2gza,	MGA_WARP_T2GZA );
+-	WARP_UCODE_INSTALL( warp_g400_t2gzaf,	MGA_WARP_T2GZAF );
+-	WARP_UCODE_INSTALL( warp_g400_t2gzs,	MGA_WARP_T2GZS );
+-	WARP_UCODE_INSTALL( warp_g400_t2gzsf,	MGA_WARP_T2GZSF );
+-	WARP_UCODE_INSTALL( warp_g400_t2gzsa,	MGA_WARP_T2GZSA );
+-	WARP_UCODE_INSTALL( warp_g400_t2gzsaf,	MGA_WARP_T2GZSAF );
++	WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ);
++	WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF);
++	WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA);
++	WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF);
++	WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS);
++	WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF);
++	WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA);
++	WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF);
++
++	WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ);
++	WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF);
++	WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA);
++	WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF);
++	WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS);
++	WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF);
++	WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA);
++	WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF);
+ 
+ 	return 0;
+ }
+ 
+-static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv )
++static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv)
+ {
+ 	unsigned char *vcbase = dev_priv->warp->handle;
+ 	unsigned long pcbase = dev_priv->warp->offset;
+@@ -138,7 +133,7 @@ static int mga_warp_install_g200_microco
+ 	return 0;
+ }
+ 
+-int mga_warp_install_microcode(	drm_mga_private_t *dev_priv )
++int mga_warp_install_microcode(drm_mga_private_t * dev_priv)
+ {
+ 	const unsigned int size = mga_warp_microcode_size(dev_priv);
+ 
+@@ -154,7 +149,7 @@ int mga_warp_install_microcode(	drm_mga_
+ 	case MGA_CARD_TYPE_G550:
+ 		return mga_warp_install_g400_microcode(dev_priv);
+ 	case MGA_CARD_TYPE_G200:
+-		return mga_warp_install_g200_microcode( dev_priv );
++		return mga_warp_install_g200_microcode(dev_priv);
+ 	default:
+ 		return DRM_ERR(EINVAL);
+ 	}
+@@ -162,13 +157,13 @@ int mga_warp_install_microcode(	drm_mga_
+ 
+ #define WMISC_EXPECTED		(MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
+ 
+-int mga_warp_init( drm_mga_private_t *dev_priv )
++int mga_warp_init(drm_mga_private_t * dev_priv)
+ {
+ 	u32 wmisc;
+ 
+ 	/* FIXME: Get rid of these damned magic numbers...
+ 	 */
+-	switch ( dev_priv->chipset ) {
++	switch (dev_priv->chipset) {
+ 	case MGA_CARD_TYPE_G400:
+ 	case MGA_CARD_TYPE_G550:
+ 		MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND);
+@@ -177,21 +172,20 @@ int mga_warp_init( drm_mga_private_t *de
+ 		MGA_WRITE(MGA_WACCEPTSEQ, 0x18000000);
+ 		break;
+ 	case MGA_CARD_TYPE_G200:
+-		MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND );
+-		MGA_WRITE( MGA_WGETMSB, 0x1606 );
+-		MGA_WRITE( MGA_WVRTXSZ, 7 );
++		MGA_WRITE(MGA_WIADDR, MGA_WMODE_SUSPEND);
++		MGA_WRITE(MGA_WGETMSB, 0x1606);
++		MGA_WRITE(MGA_WVRTXSZ, 7);
+ 		break;
+ 	default:
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
+-			       MGA_WMASTER_ENABLE |
+-			       MGA_WCACHEFLUSH_ENABLE) );
+-	wmisc = MGA_READ( MGA_WMISC );
+-	if ( wmisc != WMISC_EXPECTED ) {
+-		DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n",
+-			   wmisc, WMISC_EXPECTED );
++	MGA_WRITE(MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
++			      MGA_WMASTER_ENABLE | MGA_WCACHEFLUSH_ENABLE));
++	wmisc = MGA_READ(MGA_WMISC);
++	if (wmisc != WMISC_EXPECTED) {
++		DRM_ERROR("WARP engine config failed! 0x%x != 0x%x\n",
++			  wmisc, WMISC_EXPECTED);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
+--- a/drivers/char/drm/r128_cce.c
++++ b/drivers/char/drm/r128_cce.c
+@@ -80,7 +80,7 @@ static u32 r128_cce_microcode[] = {
+ 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ 
+-static int R128_READ_PLL(drm_device_t *dev, int addr)
++static int R128_READ_PLL(drm_device_t * dev, int addr)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 
+@@ -89,106 +89,105 @@ static int R128_READ_PLL(drm_device_t *d
+ }
+ 
+ #if R128_FIFO_DEBUG
+-static void r128_status( drm_r128_private_t *dev_priv )
++static void r128_status(drm_r128_private_t * dev_priv)
+ {
+-	printk( "GUI_STAT           = 0x%08x\n",
+-		(unsigned int)R128_READ( R128_GUI_STAT ) );
+-	printk( "PM4_STAT           = 0x%08x\n",
+-		(unsigned int)R128_READ( R128_PM4_STAT ) );
+-	printk( "PM4_BUFFER_DL_WPTR = 0x%08x\n",
+-		(unsigned int)R128_READ( R128_PM4_BUFFER_DL_WPTR ) );
+-	printk( "PM4_BUFFER_DL_RPTR = 0x%08x\n",
+-		(unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR ) );
+-	printk( "PM4_MICRO_CNTL     = 0x%08x\n",
+-		(unsigned int)R128_READ( R128_PM4_MICRO_CNTL ) );
+-	printk( "PM4_BUFFER_CNTL    = 0x%08x\n",
+-		(unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) );
++	printk("GUI_STAT           = 0x%08x\n",
++	       (unsigned int)R128_READ(R128_GUI_STAT));
++	printk("PM4_STAT           = 0x%08x\n",
++	       (unsigned int)R128_READ(R128_PM4_STAT));
++	printk("PM4_BUFFER_DL_WPTR = 0x%08x\n",
++	       (unsigned int)R128_READ(R128_PM4_BUFFER_DL_WPTR));
++	printk("PM4_BUFFER_DL_RPTR = 0x%08x\n",
++	       (unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR));
++	printk("PM4_MICRO_CNTL     = 0x%08x\n",
++	       (unsigned int)R128_READ(R128_PM4_MICRO_CNTL));
++	printk("PM4_BUFFER_CNTL    = 0x%08x\n",
++	       (unsigned int)R128_READ(R128_PM4_BUFFER_CNTL));
+ }
+ #endif
+ 
+-
+ /* ================================================================
+  * Engine, FIFO control
+  */
+ 
+-static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv )
++static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv)
+ {
+ 	u32 tmp;
+ 	int i;
+ 
+-	tmp = R128_READ( R128_PC_NGUI_CTLSTAT ) | R128_PC_FLUSH_ALL;
+-	R128_WRITE( R128_PC_NGUI_CTLSTAT, tmp );
++	tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL;
++	R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp);
+ 
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		if ( !(R128_READ( R128_PC_NGUI_CTLSTAT ) & R128_PC_BUSY) ) {
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) {
+ 			return 0;
+ 		}
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+ #if R128_FIFO_DEBUG
+-	DRM_ERROR( "failed!\n" );
++	DRM_ERROR("failed!\n");
+ #endif
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
++static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries)
+ {
+ 	int i;
+ 
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		int slots = R128_READ( R128_GUI_STAT ) & R128_GUI_FIFOCNT_MASK;
+-		if ( slots >= entries ) return 0;
+-		DRM_UDELAY( 1 );
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;
++		if (slots >= entries)
++			return 0;
++		DRM_UDELAY(1);
+ 	}
+ 
+ #if R128_FIFO_DEBUG
+-	DRM_ERROR( "failed!\n" );
++	DRM_ERROR("failed!\n");
+ #endif
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
++static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv)
+ {
+ 	int i, ret;
+ 
+-	ret = r128_do_wait_for_fifo( dev_priv, 64 );
+-	if ( ret ) return ret;
+-
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) {
+-			r128_do_pixcache_flush( dev_priv );
++	ret = r128_do_wait_for_fifo(dev_priv, 64);
++	if (ret)
++		return ret;
++
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) {
++			r128_do_pixcache_flush(dev_priv);
+ 			return 0;
+ 		}
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+ #if R128_FIFO_DEBUG
+-	DRM_ERROR( "failed!\n" );
++	DRM_ERROR("failed!\n");
+ #endif
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-
+ /* ================================================================
+  * CCE control, initialization
+  */
+ 
+ /* Load the microcode for the CCE */
+-static void r128_cce_load_microcode( drm_r128_private_t *dev_priv )
++static void r128_cce_load_microcode(drm_r128_private_t * dev_priv)
+ {
+ 	int i;
+ 
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	r128_do_wait_for_idle( dev_priv );
++	r128_do_wait_for_idle(dev_priv);
+ 
+-	R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 );
+-	for ( i = 0 ; i < 256 ; i++ ) {
+-		R128_WRITE( R128_PM4_MICROCODE_DATAH,
+-			    r128_cce_microcode[i * 2] );
+-		R128_WRITE( R128_PM4_MICROCODE_DATAL,
+-			    r128_cce_microcode[i * 2 + 1] );
++	R128_WRITE(R128_PM4_MICROCODE_ADDR, 0);
++	for (i = 0; i < 256; i++) {
++		R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]);
++		R128_WRITE(R128_PM4_MICROCODE_DATAL,
++			   r128_cce_microcode[i * 2 + 1]);
+ 	}
+ }
+ 
+@@ -196,51 +195,51 @@ static void r128_cce_load_microcode( drm
+  * prior to a wait for idle, as it informs the engine that the command
+  * stream is ending.
+  */
+-static void r128_do_cce_flush( drm_r128_private_t *dev_priv )
++static void r128_do_cce_flush(drm_r128_private_t * dev_priv)
+ {
+ 	u32 tmp;
+ 
+-	tmp = R128_READ( R128_PM4_BUFFER_DL_WPTR ) | R128_PM4_BUFFER_DL_DONE;
+-	R128_WRITE( R128_PM4_BUFFER_DL_WPTR, tmp );
++	tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR) | R128_PM4_BUFFER_DL_DONE;
++	R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp);
+ }
+ 
+ /* Wait for the CCE to go idle.
+  */
+-int r128_do_cce_idle( drm_r128_private_t *dev_priv )
++int r128_do_cce_idle(drm_r128_private_t * dev_priv)
+ {
+ 	int i;
+ 
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		if ( GET_RING_HEAD( dev_priv ) == dev_priv->ring.tail ) {
+-			int pm4stat = R128_READ( R128_PM4_STAT );
+-			if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
+-			       dev_priv->cce_fifo_size ) &&
+-			     !(pm4stat & (R128_PM4_BUSY |
+-					  R128_PM4_GUI_ACTIVE)) ) {
+-				return r128_do_pixcache_flush( dev_priv );
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		if (GET_RING_HEAD(dev_priv) == dev_priv->ring.tail) {
++			int pm4stat = R128_READ(R128_PM4_STAT);
++			if (((pm4stat & R128_PM4_FIFOCNT_MASK) >=
++			     dev_priv->cce_fifo_size) &&
++			    !(pm4stat & (R128_PM4_BUSY |
++					 R128_PM4_GUI_ACTIVE))) {
++				return r128_do_pixcache_flush(dev_priv);
+ 			}
+ 		}
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+ #if R128_FIFO_DEBUG
+-	DRM_ERROR( "failed!\n" );
+-	r128_status( dev_priv );
++	DRM_ERROR("failed!\n");
++	r128_status(dev_priv);
+ #endif
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+ /* Start the Concurrent Command Engine.
+  */
+-static void r128_do_cce_start( drm_r128_private_t *dev_priv )
++static void r128_do_cce_start(drm_r128_private_t * dev_priv)
+ {
+-	r128_do_wait_for_idle( dev_priv );
++	r128_do_wait_for_idle(dev_priv);
+ 
+-	R128_WRITE( R128_PM4_BUFFER_CNTL,
+-		    dev_priv->cce_mode | dev_priv->ring.size_l2qw
+-		    | R128_PM4_BUFFER_CNTL_NOUPDATE );
+-	R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */
+-	R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN );
++	R128_WRITE(R128_PM4_BUFFER_CNTL,
++		   dev_priv->cce_mode | dev_priv->ring.size_l2qw
++		   | R128_PM4_BUFFER_CNTL_NOUPDATE);
++	R128_READ(R128_PM4_BUFFER_ADDR);	/* as per the sample code */
++	R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
+ 
+ 	dev_priv->cce_running = 1;
+ }
+@@ -249,10 +248,10 @@ static void r128_do_cce_start( drm_r128_
+  * commands, so you must wait for the CCE command stream to complete
+  * before calling this routine.
+  */
+-static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
++static void r128_do_cce_reset(drm_r128_private_t * dev_priv)
+ {
+-	R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
+-	R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
++	R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
++	R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
+ 	dev_priv->ring.tail = 0;
+ }
+ 
+@@ -260,122 +259,120 @@ static void r128_do_cce_reset( drm_r128_
+  * commands, so you must flush the command stream and wait for the CCE
+  * to go idle before calling this routine.
+  */
+-static void r128_do_cce_stop( drm_r128_private_t *dev_priv )
++static void r128_do_cce_stop(drm_r128_private_t * dev_priv)
+ {
+-	R128_WRITE( R128_PM4_MICRO_CNTL, 0 );
+-	R128_WRITE( R128_PM4_BUFFER_CNTL,
+-		    R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE );
++	R128_WRITE(R128_PM4_MICRO_CNTL, 0);
++	R128_WRITE(R128_PM4_BUFFER_CNTL,
++		   R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE);
+ 
+ 	dev_priv->cce_running = 0;
+ }
+ 
+ /* Reset the engine.  This will stop the CCE if it is running.
+  */
+-static int r128_do_engine_reset( drm_device_t *dev )
++static int r128_do_engine_reset(drm_device_t * dev)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	u32 clock_cntl_index, mclk_cntl, gen_reset_cntl;
+ 
+-	r128_do_pixcache_flush( dev_priv );
++	r128_do_pixcache_flush(dev_priv);
+ 
+-	clock_cntl_index = R128_READ( R128_CLOCK_CNTL_INDEX );
+-	mclk_cntl = R128_READ_PLL( dev, R128_MCLK_CNTL );
++	clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX);
++	mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL);
+ 
+-	R128_WRITE_PLL( R128_MCLK_CNTL,
+-			mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP );
++	R128_WRITE_PLL(R128_MCLK_CNTL,
++		       mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP);
+ 
+-	gen_reset_cntl = R128_READ( R128_GEN_RESET_CNTL );
++	gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL);
+ 
+ 	/* Taken from the sample code - do not change */
+-	R128_WRITE( R128_GEN_RESET_CNTL,
+-		    gen_reset_cntl | R128_SOFT_RESET_GUI );
+-	R128_READ( R128_GEN_RESET_CNTL );
+-	R128_WRITE( R128_GEN_RESET_CNTL,
+-		    gen_reset_cntl & ~R128_SOFT_RESET_GUI );
+-	R128_READ( R128_GEN_RESET_CNTL );
+-
+-	R128_WRITE_PLL( R128_MCLK_CNTL, mclk_cntl );
+-	R128_WRITE( R128_CLOCK_CNTL_INDEX, clock_cntl_index );
+-	R128_WRITE( R128_GEN_RESET_CNTL, gen_reset_cntl );
++	R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
++	R128_READ(R128_GEN_RESET_CNTL);
++	R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI);
++	R128_READ(R128_GEN_RESET_CNTL);
++
++	R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl);
++	R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
++	R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl);
+ 
+ 	/* Reset the CCE ring */
+-	r128_do_cce_reset( dev_priv );
++	r128_do_cce_reset(dev_priv);
+ 
+ 	/* The CCE is no longer running after an engine reset */
+ 	dev_priv->cce_running = 0;
+ 
+ 	/* Reset any pending vertex, indirect buffers */
+-	r128_freelist_reset( dev );
++	r128_freelist_reset(dev);
+ 
+ 	return 0;
+ }
+ 
+-static void r128_cce_init_ring_buffer( drm_device_t *dev,
+-				       drm_r128_private_t *dev_priv )
++static void r128_cce_init_ring_buffer(drm_device_t * dev,
++				      drm_r128_private_t * dev_priv)
+ {
+ 	u32 ring_start;
+ 	u32 tmp;
+ 
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	/* The manual (p. 2) says this address is in "VM space".  This
+ 	 * means it's an offset from the start of AGP space.
+ 	 */
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci )
++	if (!dev_priv->is_pci)
+ 		ring_start = dev_priv->cce_ring->offset - dev->agp->base;
+ 	else
+ #endif
+-		ring_start = dev_priv->cce_ring->offset - 
+-				(unsigned long)dev->sg->virtual;
++		ring_start = dev_priv->cce_ring->offset -
++		    (unsigned long)dev->sg->virtual;
+ 
+-	R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET );
++	R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET);
+ 
+-	R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
+-	R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
++	R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
++	R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
+ 
+ 	/* Set watermark control */
+-	R128_WRITE( R128_PM4_BUFFER_WM_CNTL,
+-		    ((R128_WATERMARK_L/4) << R128_WMA_SHIFT)
+-		    | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT)
+-		    | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT)
+-		    | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT) );
++	R128_WRITE(R128_PM4_BUFFER_WM_CNTL,
++		   ((R128_WATERMARK_L / 4) << R128_WMA_SHIFT)
++		   | ((R128_WATERMARK_M / 4) << R128_WMB_SHIFT)
++		   | ((R128_WATERMARK_N / 4) << R128_WMC_SHIFT)
++		   | ((R128_WATERMARK_K / 64) << R128_WB_WM_SHIFT));
+ 
+ 	/* Force read.  Why?  Because it's in the examples... */
+-	R128_READ( R128_PM4_BUFFER_ADDR );
++	R128_READ(R128_PM4_BUFFER_ADDR);
+ 
+ 	/* Turn on bus mastering */
+-	tmp = R128_READ( R128_BUS_CNTL ) & ~R128_BUS_MASTER_DIS;
+-	R128_WRITE( R128_BUS_CNTL, tmp );
++	tmp = R128_READ(R128_BUS_CNTL) & ~R128_BUS_MASTER_DIS;
++	R128_WRITE(R128_BUS_CNTL, tmp);
+ }
+ 
+-static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
++static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init)
+ {
+ 	drm_r128_private_t *dev_priv;
+ 
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	dev_priv = drm_alloc( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
+-	if ( dev_priv == NULL )
++	dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER);
++	if (dev_priv == NULL)
+ 		return DRM_ERR(ENOMEM);
+ 
+-	memset( dev_priv, 0, sizeof(drm_r128_private_t) );
++	memset(dev_priv, 0, sizeof(drm_r128_private_t));
+ 
+ 	dev_priv->is_pci = init->is_pci;
+ 
+-	if ( dev_priv->is_pci && !dev->sg ) {
+-		DRM_ERROR( "PCI GART memory not allocated!\n" );
++	if (dev_priv->is_pci && !dev->sg) {
++		DRM_ERROR("PCI GART memory not allocated!\n");
+ 		dev->dev_private = (void *)dev_priv;
+-		r128_do_cleanup_cce( dev );
++		r128_do_cleanup_cce(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	dev_priv->usec_timeout = init->usec_timeout;
+-	if ( dev_priv->usec_timeout < 1 ||
+-	     dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT ) {
+-		DRM_DEBUG( "TIMEOUT problem!\n" );
++	if (dev_priv->usec_timeout < 1 ||
++	    dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) {
++		DRM_DEBUG("TIMEOUT problem!\n");
+ 		dev->dev_private = (void *)dev_priv;
+-		r128_do_cleanup_cce( dev );
++		r128_do_cleanup_cce(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -383,23 +380,23 @@ static int r128_do_init_cce( drm_device_
+ 
+ 	/* GH: Simple idle check.
+ 	 */
+-	atomic_set( &dev_priv->idle_count, 0 );
++	atomic_set(&dev_priv->idle_count, 0);
+ 
+ 	/* We don't support anything other than bus-mastering ring mode,
+ 	 * but the ring can be in either AGP or PCI space for the ring
+ 	 * read pointer.
+ 	 */
+-	if ( ( init->cce_mode != R128_PM4_192BM ) &&
+-	     ( init->cce_mode != R128_PM4_128BM_64INDBM ) &&
+-	     ( init->cce_mode != R128_PM4_64BM_128INDBM ) &&
+-	     ( init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM ) ) {
+-		DRM_DEBUG( "Bad cce_mode!\n" );
++	if ((init->cce_mode != R128_PM4_192BM) &&
++	    (init->cce_mode != R128_PM4_128BM_64INDBM) &&
++	    (init->cce_mode != R128_PM4_64BM_128INDBM) &&
++	    (init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM)) {
++		DRM_DEBUG("Bad cce_mode!\n");
+ 		dev->dev_private = (void *)dev_priv;
+-		r128_do_cleanup_cce( dev );
++		r128_do_cleanup_cce(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	switch ( init->cce_mode ) {
++	switch (init->cce_mode) {
+ 	case R128_PM4_NONPM4:
+ 		dev_priv->cce_fifo_size = 0;
+ 		break;
+@@ -420,7 +417,7 @@ static int r128_do_init_cce( drm_device_
+ 		break;
+ 	}
+ 
+-	switch ( init->fb_bpp ) {
++	switch (init->fb_bpp) {
+ 	case 16:
+ 		dev_priv->color_fmt = R128_DATATYPE_RGB565;
+ 		break;
+@@ -429,12 +426,12 @@ static int r128_do_init_cce( drm_device_
+ 		dev_priv->color_fmt = R128_DATATYPE_ARGB8888;
+ 		break;
+ 	}
+-	dev_priv->front_offset	= init->front_offset;
+-	dev_priv->front_pitch	= init->front_pitch;
+-	dev_priv->back_offset	= init->back_offset;
+-	dev_priv->back_pitch	= init->back_pitch;
++	dev_priv->front_offset = init->front_offset;
++	dev_priv->front_pitch = init->front_pitch;
++	dev_priv->back_offset = init->back_offset;
++	dev_priv->back_pitch = init->back_pitch;
+ 
+-	switch ( init->depth_bpp ) {
++	switch (init->depth_bpp) {
+ 	case 16:
+ 		dev_priv->depth_fmt = R128_DATATYPE_RGB565;
+ 		break;
+@@ -444,218 +441,223 @@ static int r128_do_init_cce( drm_device_
+ 		dev_priv->depth_fmt = R128_DATATYPE_ARGB8888;
+ 		break;
+ 	}
+-	dev_priv->depth_offset	= init->depth_offset;
+-	dev_priv->depth_pitch	= init->depth_pitch;
+-	dev_priv->span_offset	= init->span_offset;
++	dev_priv->depth_offset = init->depth_offset;
++	dev_priv->depth_pitch = init->depth_pitch;
++	dev_priv->span_offset = init->span_offset;
+ 
+-	dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch/8) << 21) |
++	dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch / 8) << 21) |
+ 					  (dev_priv->front_offset >> 5));
+-	dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch/8) << 21) |
++	dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch / 8) << 21) |
+ 					 (dev_priv->back_offset >> 5));
+-	dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
++	dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) |
+ 					  (dev_priv->depth_offset >> 5) |
+ 					  R128_DST_TILE);
+-	dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
++	dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) |
+ 					 (dev_priv->span_offset >> 5));
+ 
+ 	DRM_GETSAREA();
+-	
+-	if(!dev_priv->sarea) {
++
++	if (!dev_priv->sarea) {
+ 		DRM_ERROR("could not find sarea!\n");
+ 		dev->dev_private = (void *)dev_priv;
+-		r128_do_cleanup_cce( dev );
++		r128_do_cleanup_cce(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
+-	if(!dev_priv->mmio) {
++	if (!dev_priv->mmio) {
+ 		DRM_ERROR("could not find mmio region!\n");
+ 		dev->dev_private = (void *)dev_priv;
+-		r128_do_cleanup_cce( dev );
++		r128_do_cleanup_cce(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 	dev_priv->cce_ring = drm_core_findmap(dev, init->ring_offset);
+-	if(!dev_priv->cce_ring) {
++	if (!dev_priv->cce_ring) {
+ 		DRM_ERROR("could not find cce ring region!\n");
+ 		dev->dev_private = (void *)dev_priv;
+-		r128_do_cleanup_cce( dev );
++		r128_do_cleanup_cce(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 	dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
+-	if(!dev_priv->ring_rptr) {
++	if (!dev_priv->ring_rptr) {
+ 		DRM_ERROR("could not find ring read pointer!\n");
+ 		dev->dev_private = (void *)dev_priv;
+-		r128_do_cleanup_cce( dev );
++		r128_do_cleanup_cce(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 	dev->agp_buffer_token = init->buffers_offset;
+ 	dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+-	if(!dev->agp_buffer_map) {
++	if (!dev->agp_buffer_map) {
+ 		DRM_ERROR("could not find dma buffer region!\n");
+ 		dev->dev_private = (void *)dev_priv;
+-		r128_do_cleanup_cce( dev );
++		r128_do_cleanup_cce(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( !dev_priv->is_pci ) {
+-		dev_priv->agp_textures = drm_core_findmap(dev, init->agp_textures_offset);
+-		if(!dev_priv->agp_textures) {
++	if (!dev_priv->is_pci) {
++		dev_priv->agp_textures =
++		    drm_core_findmap(dev, init->agp_textures_offset);
++		if (!dev_priv->agp_textures) {
+ 			DRM_ERROR("could not find agp texture region!\n");
+ 			dev->dev_private = (void *)dev_priv;
+-			r128_do_cleanup_cce( dev );
++			r128_do_cleanup_cce(dev);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 	}
+ 
+ 	dev_priv->sarea_priv =
+-		(drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
+-				     init->sarea_priv_offset);
++	    (drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->handle +
++				  init->sarea_priv_offset);
+ 
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci ) {
+-		drm_core_ioremap( dev_priv->cce_ring, dev );
+-		drm_core_ioremap( dev_priv->ring_rptr, dev );
+-		drm_core_ioremap( dev->agp_buffer_map, dev );
+-		if(!dev_priv->cce_ring->handle ||
+-		   !dev_priv->ring_rptr->handle ||
+-		   !dev->agp_buffer_map->handle) {
++	if (!dev_priv->is_pci) {
++		drm_core_ioremap(dev_priv->cce_ring, dev);
++		drm_core_ioremap(dev_priv->ring_rptr, dev);
++		drm_core_ioremap(dev->agp_buffer_map, dev);
++		if (!dev_priv->cce_ring->handle ||
++		    !dev_priv->ring_rptr->handle ||
++		    !dev->agp_buffer_map->handle) {
+ 			DRM_ERROR("Could not ioremap agp regions!\n");
+ 			dev->dev_private = (void *)dev_priv;
+-			r128_do_cleanup_cce( dev );
++			r128_do_cleanup_cce(dev);
+ 			return DRM_ERR(ENOMEM);
+ 		}
+ 	} else
+ #endif
+ 	{
+-		dev_priv->cce_ring->handle =
+-			(void *)dev_priv->cce_ring->offset;
++		dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset;
+ 		dev_priv->ring_rptr->handle =
+-			(void *)dev_priv->ring_rptr->offset;
+-		dev->agp_buffer_map->handle = (void *)dev->agp_buffer_map->offset;
++		    (void *)dev_priv->ring_rptr->offset;
++		dev->agp_buffer_map->handle =
++		    (void *)dev->agp_buffer_map->offset;
+ 	}
+ 
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci )
++	if (!dev_priv->is_pci)
+ 		dev_priv->cce_buffers_offset = dev->agp->base;
+ 	else
+ #endif
+ 		dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual;
+ 
+-	dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle;
+-	dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
++	dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle;
++	dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle
+ 			      + init->ring_size / sizeof(u32));
+ 	dev_priv->ring.size = init->ring_size;
+-	dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
++	dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
+ 
+-	dev_priv->ring.tail_mask =
+-		(dev_priv->ring.size / sizeof(u32)) - 1;
++	dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
+ 
+ 	dev_priv->ring.high_mark = 128;
+ 
+ 	dev_priv->sarea_priv->last_frame = 0;
+-	R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
++	R128_WRITE(R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
+ 
+ 	dev_priv->sarea_priv->last_dispatch = 0;
+-	R128_WRITE( R128_LAST_DISPATCH_REG,
+-		    dev_priv->sarea_priv->last_dispatch );
++	R128_WRITE(R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch);
+ 
+ #if __OS_HAS_AGP
+-	if ( dev_priv->is_pci ) {
++	if (dev_priv->is_pci) {
+ #endif
+-		if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart,
+-     					    &dev_priv->bus_pci_gart) ) {
+-			DRM_ERROR( "failed to init PCI GART!\n" );
++		dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
++		dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0;
++		dev_priv->gart_info.is_pcie = 0;
++		if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
++			DRM_ERROR("failed to init PCI GART!\n");
+ 			dev->dev_private = (void *)dev_priv;
+-			r128_do_cleanup_cce( dev );
++			r128_do_cleanup_cce(dev);
+ 			return DRM_ERR(ENOMEM);
+ 		}
+-		R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart );
++		R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr);
+ #if __OS_HAS_AGP
+ 	}
+ #endif
+ 
+-	r128_cce_init_ring_buffer( dev, dev_priv );
+-	r128_cce_load_microcode( dev_priv );
++	r128_cce_init_ring_buffer(dev, dev_priv);
++	r128_cce_load_microcode(dev_priv);
+ 
+ 	dev->dev_private = (void *)dev_priv;
+ 
+-	r128_do_engine_reset( dev );
++	r128_do_engine_reset(dev);
+ 
+ 	return 0;
+ }
+ 
+-int r128_do_cleanup_cce( drm_device_t *dev )
++int r128_do_cleanup_cce(drm_device_t * dev)
+ {
+ 
+ 	/* Make sure interrupts are disabled here because the uninstall ioctl
+ 	 * may not have been called from userspace and after dev_private
+ 	 * is freed, it's too late.
+ 	 */
+-	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
++	if (dev->irq_enabled)
++		drm_irq_uninstall(dev);
+ 
+-	if ( dev->dev_private ) {
++	if (dev->dev_private) {
+ 		drm_r128_private_t *dev_priv = dev->dev_private;
+ 
+ #if __OS_HAS_AGP
+-		if ( !dev_priv->is_pci ) {
+-			if ( dev_priv->cce_ring != NULL )
+-				drm_core_ioremapfree( dev_priv->cce_ring, dev );
+-			if ( dev_priv->ring_rptr != NULL )
+-				drm_core_ioremapfree( dev_priv->ring_rptr, dev );
+-			if ( dev->agp_buffer_map != NULL )
+-				drm_core_ioremapfree( dev->agp_buffer_map, dev );
++		if (!dev_priv->is_pci) {
++			if (dev_priv->cce_ring != NULL)
++				drm_core_ioremapfree(dev_priv->cce_ring, dev);
++			if (dev_priv->ring_rptr != NULL)
++				drm_core_ioremapfree(dev_priv->ring_rptr, dev);
++			if (dev->agp_buffer_map != NULL)
++				drm_core_ioremapfree(dev->agp_buffer_map, dev);
+ 		} else
+ #endif
+ 		{
+-			if (!drm_ati_pcigart_cleanup( dev,
+-						dev_priv->phys_pci_gart,
+-						dev_priv->bus_pci_gart ))
+-				DRM_ERROR( "failed to cleanup PCI GART!\n" );
++			if (dev_priv->gart_info.bus_addr)
++				if (!drm_ati_pcigart_cleanup(dev,
++							     &dev_priv->
++							     gart_info))
++					DRM_ERROR
++					    ("failed to cleanup PCI GART!\n");
+ 		}
+ 
+-		drm_free( dev->dev_private, sizeof(drm_r128_private_t),
+-			   DRM_MEM_DRIVER );
++		drm_free(dev->dev_private, sizeof(drm_r128_private_t),
++			 DRM_MEM_DRIVER);
+ 		dev->dev_private = NULL;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-int r128_cce_init( DRM_IOCTL_ARGS )
++int r128_cce_init(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_init_t init;
+ 
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( init, (drm_r128_init_t __user *)data, sizeof(init) );
++	DRM_COPY_FROM_USER_IOCTL(init, (drm_r128_init_t __user *) data,
++				 sizeof(init));
+ 
+-	switch ( init.func ) {
++	switch (init.func) {
+ 	case R128_INIT_CCE:
+-		return r128_do_init_cce( dev, &init );
++		return r128_do_init_cce(dev, &init);
+ 	case R128_CLEANUP_CCE:
+-		return r128_do_cleanup_cce( dev );
++		return r128_do_cleanup_cce(dev);
+ 	}
+ 
+ 	return DRM_ERR(EINVAL);
+ }
+ 
+-int r128_cce_start( DRM_IOCTL_ARGS )
++int r128_cce_start(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) {
+-		DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ );
++	if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
++		DRM_DEBUG("%s while CCE running\n", __FUNCTION__);
+ 		return 0;
+ 	}
+ 
+-	r128_do_cce_start( dev_priv );
++	r128_do_cce_start(dev_priv);
+ 
+ 	return 0;
+ }
+@@ -663,61 +665,63 @@ int r128_cce_start( DRM_IOCTL_ARGS )
+ /* Stop the CCE.  The engine must have been idled before calling this
+  * routine.
+  */
+-int r128_cce_stop( DRM_IOCTL_ARGS )
++int r128_cce_stop(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_cce_stop_t stop;
+ 	int ret;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t __user *)data, sizeof(stop) );
++	DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t __user *) data,
++				 sizeof(stop));
+ 
+ 	/* Flush any pending CCE commands.  This ensures any outstanding
+ 	 * commands are exectuted by the engine before we turn it off.
+ 	 */
+-	if ( stop.flush ) {
+-		r128_do_cce_flush( dev_priv );
++	if (stop.flush) {
++		r128_do_cce_flush(dev_priv);
+ 	}
+ 
+ 	/* If we fail to make the engine go idle, we return an error
+ 	 * code so that the DRM ioctl wrapper can try again.
+ 	 */
+-	if ( stop.idle ) {
+-		ret = r128_do_cce_idle( dev_priv );
+-		if ( ret ) return ret;
++	if (stop.idle) {
++		ret = r128_do_cce_idle(dev_priv);
++		if (ret)
++			return ret;
+ 	}
+ 
+ 	/* Finally, we can turn off the CCE.  If the engine isn't idle,
+ 	 * we will get some dropped triangles as they won't be fully
+ 	 * rendered before the CCE is shut down.
+ 	 */
+-	r128_do_cce_stop( dev_priv );
++	r128_do_cce_stop(dev_priv);
+ 
+ 	/* Reset the engine */
+-	r128_do_engine_reset( dev );
++	r128_do_engine_reset(dev);
+ 
+ 	return 0;
+ }
+ 
+ /* Just reset the CCE ring.  Called as part of an X Server engine reset.
+  */
+-int r128_cce_reset( DRM_IOCTL_ARGS )
++int r128_cce_reset(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_DEBUG("%s called before init done\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	r128_do_cce_reset( dev_priv );
++	r128_do_cce_reset(dev_priv);
+ 
+ 	/* The CCE is no longer running after an engine reset */
+ 	dev_priv->cce_running = 0;
+@@ -725,37 +729,36 @@ int r128_cce_reset( DRM_IOCTL_ARGS )
+ 	return 0;
+ }
+ 
+-int r128_cce_idle( DRM_IOCTL_ARGS )
++int r128_cce_idle(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( dev_priv->cce_running ) {
+-		r128_do_cce_flush( dev_priv );
++	if (dev_priv->cce_running) {
++		r128_do_cce_flush(dev_priv);
+ 	}
+ 
+-	return r128_do_cce_idle( dev_priv );
++	return r128_do_cce_idle(dev_priv);
+ }
+ 
+-int r128_engine_reset( DRM_IOCTL_ARGS )
++int r128_engine_reset(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	return r128_do_engine_reset( dev );
++	return r128_do_engine_reset(dev);
+ }
+ 
+-int r128_fullscreen( DRM_IOCTL_ARGS )
++int r128_fullscreen(DRM_IOCTL_ARGS)
+ {
+ 	return DRM_ERR(EINVAL);
+ }
+ 
+-
+ /* ================================================================
+  * Freelist management
+  */
+@@ -763,7 +766,7 @@ int r128_fullscreen( DRM_IOCTL_ARGS )
+ #define R128_BUFFER_FREE	0
+ 
+ #if 0
+-static int r128_freelist_init( drm_device_t *dev )
++static int r128_freelist_init(drm_device_t * dev)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+@@ -772,27 +775,26 @@ static int r128_freelist_init( drm_devic
+ 	drm_r128_freelist_t *entry;
+ 	int i;
+ 
+-	dev_priv->head = drm_alloc( sizeof(drm_r128_freelist_t),
+-				     DRM_MEM_DRIVER );
+-	if ( dev_priv->head == NULL )
++	dev_priv->head = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER);
++	if (dev_priv->head == NULL)
+ 		return DRM_ERR(ENOMEM);
+ 
+-	memset( dev_priv->head, 0, sizeof(drm_r128_freelist_t) );
++	memset(dev_priv->head, 0, sizeof(drm_r128_freelist_t));
+ 	dev_priv->head->age = R128_BUFFER_USED;
+ 
+-	for ( i = 0 ; i < dma->buf_count ; i++ ) {
++	for (i = 0; i < dma->buf_count; i++) {
+ 		buf = dma->buflist[i];
+ 		buf_priv = buf->dev_private;
+ 
+-		entry = drm_alloc( sizeof(drm_r128_freelist_t),
+-				    DRM_MEM_DRIVER );
+-		if ( !entry ) return DRM_ERR(ENOMEM);
++		entry = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER);
++		if (!entry)
++			return DRM_ERR(ENOMEM);
+ 
+ 		entry->age = R128_BUFFER_FREE;
+ 		entry->buf = buf;
+ 		entry->prev = dev_priv->head;
+ 		entry->next = dev_priv->head->next;
+-		if ( !entry->next )
++		if (!entry->next)
+ 			dev_priv->tail = entry;
+ 
+ 		buf_priv->discard = 0;
+@@ -801,7 +803,7 @@ static int r128_freelist_init( drm_devic
+ 
+ 		dev_priv->head->next = entry;
+ 
+-		if ( dev_priv->head->next )
++		if (dev_priv->head->next)
+ 			dev_priv->head->next->prev = entry;
+ 	}
+ 
+@@ -810,7 +812,7 @@ static int r128_freelist_init( drm_devic
+ }
+ #endif
+ 
+-static drm_buf_t *r128_freelist_get( drm_device_t *dev )
++static drm_buf_t *r128_freelist_get(drm_device_t * dev)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+@@ -820,20 +822,20 @@ static drm_buf_t *r128_freelist_get( drm
+ 
+ 	/* FIXME: Optimize -- use freelist code */
+ 
+-	for ( i = 0 ; i < dma->buf_count ; i++ ) {
++	for (i = 0; i < dma->buf_count; i++) {
+ 		buf = dma->buflist[i];
+ 		buf_priv = buf->dev_private;
+-		if ( buf->filp == 0 )
++		if (buf->filp == 0)
+ 			return buf;
+ 	}
+ 
+-	for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
+-		u32 done_age = R128_READ( R128_LAST_DISPATCH_REG );
++	for (t = 0; t < dev_priv->usec_timeout; t++) {
++		u32 done_age = R128_READ(R128_LAST_DISPATCH_REG);
+ 
+-		for ( i = 0 ; i < dma->buf_count ; i++ ) {
++		for (i = 0; i < dma->buf_count; i++) {
+ 			buf = dma->buflist[i];
+ 			buf_priv = buf->dev_private;
+-			if ( buf->pending && buf_priv->age <= done_age ) {
++			if (buf->pending && buf_priv->age <= done_age) {
+ 				/* The buffer has been processed, so it
+ 				 * can now be used.
+ 				 */
+@@ -841,63 +843,63 @@ static drm_buf_t *r128_freelist_get( drm
+ 				return buf;
+ 			}
+ 		}
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+-	DRM_DEBUG( "returning NULL!\n" );
++	DRM_DEBUG("returning NULL!\n");
+ 	return NULL;
+ }
+ 
+-void r128_freelist_reset( drm_device_t *dev )
++void r128_freelist_reset(drm_device_t * dev)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	int i;
+ 
+-	for ( i = 0 ; i < dma->buf_count ; i++ ) {
++	for (i = 0; i < dma->buf_count; i++) {
+ 		drm_buf_t *buf = dma->buflist[i];
+ 		drm_r128_buf_priv_t *buf_priv = buf->dev_private;
+ 		buf_priv->age = 0;
+ 	}
+ }
+ 
+-
+ /* ================================================================
+  * CCE command submission
+  */
+ 
+-int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
++int r128_wait_ring(drm_r128_private_t * dev_priv, int n)
+ {
+ 	drm_r128_ring_buffer_t *ring = &dev_priv->ring;
+ 	int i;
+ 
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		r128_update_ring_snapshot( dev_priv );
+-		if ( ring->space >= n )
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		r128_update_ring_snapshot(dev_priv);
++		if (ring->space >= n)
+ 			return 0;
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+ 	/* FIXME: This is being ignored... */
+-	DRM_ERROR( "failed!\n" );
++	DRM_ERROR("failed!\n");
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-static int r128_cce_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d )
++static int r128_cce_get_buffers(DRMFILE filp, drm_device_t * dev, drm_dma_t * d)
+ {
+ 	int i;
+ 	drm_buf_t *buf;
+ 
+-	for ( i = d->granted_count ; i < d->request_count ; i++ ) {
+-		buf = r128_freelist_get( dev );
+-		if ( !buf ) return DRM_ERR(EAGAIN);
++	for (i = d->granted_count; i < d->request_count; i++) {
++		buf = r128_freelist_get(dev);
++		if (!buf)
++			return DRM_ERR(EAGAIN);
+ 
+ 		buf->filp = filp;
+ 
+-		if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx,
+-				   sizeof(buf->idx) ) )
++		if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
++				     sizeof(buf->idx)))
+ 			return DRM_ERR(EFAULT);
+-		if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total,
+-				   sizeof(buf->total) ) )
++		if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
++				     sizeof(buf->total)))
+ 			return DRM_ERR(EFAULT);
+ 
+ 		d->granted_count++;
+@@ -905,7 +907,7 @@ static int r128_cce_get_buffers( DRMFILE
+ 	return 0;
+ }
+ 
+-int r128_cce_buffers( DRM_IOCTL_ARGS )
++int r128_cce_buffers(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_device_dma_t *dma = dev->dma;
+@@ -913,33 +915,33 @@ int r128_cce_buffers( DRM_IOCTL_ARGS )
+ 	drm_dma_t __user *argp = (void __user *)data;
+ 	drm_dma_t d;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) );
++	DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d));
+ 
+ 	/* Please don't send us buffers.
+ 	 */
+-	if ( d.send_count != 0 ) {
+-		DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
+-			   DRM_CURRENTPID, d.send_count );
++	if (d.send_count != 0) {
++		DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
++			  DRM_CURRENTPID, d.send_count);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	/* We'll send you buffers.
+ 	 */
+-	if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
+-		DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
+-			   DRM_CURRENTPID, d.request_count, dma->buf_count );
++	if (d.request_count < 0 || d.request_count > dma->buf_count) {
++		DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
++			  DRM_CURRENTPID, d.request_count, dma->buf_count);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	d.granted_count = 0;
+ 
+-	if ( d.request_count ) {
+-		ret = r128_cce_get_buffers( filp, dev, &d );
++	if (d.request_count) {
++		ret = r128_cce_get_buffers(filp, dev, &d);
+ 	}
+ 
+-	DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d) );
++	DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d));
+ 
+ 	return ret;
+ }
+diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h
+--- a/drivers/char/drm/r128_drm.h
++++ b/drivers/char/drm/r128_drm.h
+@@ -93,7 +93,7 @@
+ #define R128_MAX_TEXTURE_LEVELS		11
+ #define R128_MAX_TEXTURE_UNITS		2
+ 
+-#endif /* __R128_SAREA_DEFINES__ */
++#endif				/* __R128_SAREA_DEFINES__ */
+ 
+ typedef struct {
+ 	/* Context state - can be written in one large chunk */
+@@ -140,7 +140,6 @@ typedef struct {
+ 	unsigned int tex_border_color;
+ } drm_r128_texture_regs_t;
+ 
+-
+ typedef struct drm_r128_sarea {
+ 	/* The channel for communication of state information to the kernel
+ 	 * on firing a vertex buffer.
+@@ -161,14 +160,13 @@ typedef struct drm_r128_sarea {
+ 	unsigned int last_frame;
+ 	unsigned int last_dispatch;
+ 
+-	drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
++	drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1];
+ 	unsigned int tex_age[R128_NR_TEX_HEAPS];
+ 	int ctx_owner;
+-	int pfAllowPageFlip;        /* number of 3d windows (0,1,2 or more) */
+-	int pfCurrentPage;	    /* which buffer is being displayed? */
++	int pfAllowPageFlip;	/* number of 3d windows (0,1,2 or more) */
++	int pfCurrentPage;	/* which buffer is being displayed? */
+ } drm_r128_sarea_t;
+ 
+-
+ /* WARNING: If you change any of these defines, make sure to change the
+  * defines in the Xserver file (xf86drmR128.h)
+  */
+@@ -220,7 +218,7 @@ typedef struct drm_r128_sarea {
+ 
+ typedef struct drm_r128_init {
+ 	enum {
+-		R128_INIT_CCE    = 0x01,
++		R128_INIT_CCE = 0x01,
+ 		R128_CLEANUP_CCE = 0x02
+ 	} func;
+ #if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
+@@ -278,9 +276,9 @@ typedef struct drm_r128_clear {
+ 
+ typedef struct drm_r128_vertex {
+ 	int prim;
+-	int idx;			/* Index of vertex buffer */
+-	int count;			/* Number of vertices in buffer */
+-	int discard;			/* Client finished with buffer? */
++	int idx;		/* Index of vertex buffer */
++	int count;		/* Number of vertices in buffer */
++	int discard;		/* Client finished with buffer? */
+ } drm_r128_vertex_t;
+ 
+ typedef struct drm_r128_indices {
+@@ -288,7 +286,7 @@ typedef struct drm_r128_indices {
+ 	int idx;
+ 	int start;
+ 	int end;
+-	int discard;			/* Client finished with buffer? */
++	int discard;		/* Client finished with buffer? */
+ } drm_r128_indices_t;
+ 
+ typedef struct drm_r128_blit {
+@@ -302,10 +300,10 @@ typedef struct drm_r128_blit {
+ 
+ typedef struct drm_r128_depth {
+ 	enum {
+-		R128_WRITE_SPAN		= 0x01,
+-		R128_WRITE_PIXELS	= 0x02,
+-		R128_READ_SPAN		= 0x03,
+-		R128_READ_PIXELS	= 0x04
++		R128_WRITE_SPAN = 0x01,
++		R128_WRITE_PIXELS = 0x02,
++		R128_READ_SPAN = 0x03,
++		R128_READ_PIXELS = 0x04
+ 	} func;
+ 	int n;
+ 	int __user *x;
+@@ -327,13 +325,13 @@ typedef struct drm_r128_indirect {
+ 
+ typedef struct drm_r128_fullscreen {
+ 	enum {
+-		R128_INIT_FULLSCREEN    = 0x01,
++		R128_INIT_FULLSCREEN = 0x01,
+ 		R128_CLEANUP_FULLSCREEN = 0x02
+ 	} func;
+ } drm_r128_fullscreen_t;
+ 
+ /* 2.3: An ioctl to get parameters that aren't available to the 3d
+- * client any other way.  
++ * client any other way.
+  */
+ #define R128_PARAM_IRQ_NR            1
+ 
+diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
+--- a/drivers/char/drm/r128_drv.c
++++ b/drivers/char/drm/r128_drv.c
+@@ -37,30 +37,28 @@
+ 
+ #include "drm_pciids.h"
+ 
+-static int postinit( struct drm_device *dev, unsigned long flags )
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->primary.minor,
+-		pci_pretty_name(dev->pdev)
+-		);
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR,
++		 DRIVER_PATCHLEVEL,
++		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
++	    );
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+@@ -68,11 +66,11 @@ static struct pci_device_id pciidlist[] 
+ 	r128_PCI_IDS
+ };
+ 
+-extern drm_ioctl_desc_t r128_ioctls[];
+-extern int r128_max_ioctl;
+-
+ static struct drm_driver driver = {
+-	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
++	.driver_features =
++	    DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
++	    DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
++	    DRIVER_IRQ_VBL,
+ 	.dev_priv_size = sizeof(drm_r128_buf_priv_t),
+ 	.prerelease = r128_driver_prerelease,
+ 	.pretakedown = r128_driver_pretakedown,
+@@ -89,21 +87,22 @@ static struct drm_driver driver = {
+ 	.ioctls = r128_ioctls,
+ 	.dma_ioctl = r128_cce_buffers,
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
+ #ifdef CONFIG_COMPAT
+-		.compat_ioctl = r128_compat_ioctl,
++		 .compat_ioctl = r128_compat_ioctl,
+ #endif
+-	},
++		 }
++	,
+ 	.pci_driver = {
+-		.name          = DRIVER_NAME,
+-		.id_table      = pciidlist,
+-	}
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
+ };
+ 
+ static int __init r128_init(void)
+@@ -120,6 +119,6 @@ static void __exit r128_exit(void)
+ module_init(r128_init);
+ module_exit(r128_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
+--- a/drivers/char/drm/r128_drv.h
++++ b/drivers/char/drm/r128_drv.h
+@@ -52,14 +52,13 @@
+ #define DRIVER_MINOR		5
+ #define DRIVER_PATCHLEVEL	0
+ 
+-
+ #define GET_RING_HEAD(dev_priv)		R128_READ( R128_PM4_BUFFER_DL_RPTR )
+ 
+ typedef struct drm_r128_freelist {
+-   	unsigned int age;
+-   	drm_buf_t *buf;
+-   	struct drm_r128_freelist *next;
+-   	struct drm_r128_freelist *prev;
++	unsigned int age;
++	drm_buf_t *buf;
++	struct drm_r128_freelist *next;
++	struct drm_r128_freelist *prev;
+ } drm_r128_freelist_t;
+ 
+ typedef struct drm_r128_ring_buffer {
+@@ -83,13 +82,11 @@ typedef struct drm_r128_private {
+ 	int cce_fifo_size;
+ 	int cce_running;
+ 
+-   	drm_r128_freelist_t *head;
+-   	drm_r128_freelist_t *tail;
++	drm_r128_freelist_t *head;
++	drm_r128_freelist_t *tail;
+ 
+ 	int usec_timeout;
+ 	int is_pci;
+-	unsigned long phys_pci_gart;
+-	dma_addr_t bus_pci_gart;
+ 	unsigned long cce_buffers_offset;
+ 
+ 	atomic_t idle_count;
+@@ -120,6 +117,7 @@ typedef struct drm_r128_private {
+ 	drm_local_map_t *cce_ring;
+ 	drm_local_map_t *ring_rptr;
+ 	drm_local_map_t *agp_textures;
++	drm_ati_pcigart_info gart_info;
+ } drm_r128_private_t;
+ 
+ typedef struct drm_r128_buf_priv {
+@@ -127,34 +125,37 @@ typedef struct drm_r128_buf_priv {
+ 	int prim;
+ 	int discard;
+ 	int dispatched;
+-   	drm_r128_freelist_t *list_entry;
++	drm_r128_freelist_t *list_entry;
+ } drm_r128_buf_priv_t;
+ 
++extern drm_ioctl_desc_t r128_ioctls[];
++extern int r128_max_ioctl;
++
+ 				/* r128_cce.c */
+-extern int r128_cce_init( DRM_IOCTL_ARGS );
+-extern int r128_cce_start( DRM_IOCTL_ARGS );
+-extern int r128_cce_stop( DRM_IOCTL_ARGS );
+-extern int r128_cce_reset( DRM_IOCTL_ARGS );
+-extern int r128_cce_idle( DRM_IOCTL_ARGS );
+-extern int r128_engine_reset( DRM_IOCTL_ARGS );
+-extern int r128_fullscreen( DRM_IOCTL_ARGS );
+-extern int r128_cce_buffers( DRM_IOCTL_ARGS );
+-
+-extern void r128_freelist_reset( drm_device_t *dev );
+-
+-extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
+-
+-extern int r128_do_cce_idle( drm_r128_private_t *dev_priv );
+-extern int r128_do_cleanup_cce( drm_device_t *dev );
+-
+-extern int r128_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
+-
+-extern irqreturn_t r128_driver_irq_handler( DRM_IRQ_ARGS );
+-extern void r128_driver_irq_preinstall( drm_device_t *dev );
+-extern void r128_driver_irq_postinstall( drm_device_t *dev );
+-extern void r128_driver_irq_uninstall( drm_device_t *dev );
+-extern void r128_driver_pretakedown(drm_device_t *dev);
+-extern void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp);
++extern int r128_cce_init(DRM_IOCTL_ARGS);
++extern int r128_cce_start(DRM_IOCTL_ARGS);
++extern int r128_cce_stop(DRM_IOCTL_ARGS);
++extern int r128_cce_reset(DRM_IOCTL_ARGS);
++extern int r128_cce_idle(DRM_IOCTL_ARGS);
++extern int r128_engine_reset(DRM_IOCTL_ARGS);
++extern int r128_fullscreen(DRM_IOCTL_ARGS);
++extern int r128_cce_buffers(DRM_IOCTL_ARGS);
++
++extern void r128_freelist_reset(drm_device_t * dev);
++
++extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
++
++extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
++extern int r128_do_cleanup_cce(drm_device_t * dev);
++
++extern int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
++
++extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
++extern void r128_driver_irq_preinstall(drm_device_t * dev);
++extern void r128_driver_irq_postinstall(drm_device_t * dev);
++extern void r128_driver_irq_uninstall(drm_device_t * dev);
++extern void r128_driver_pretakedown(drm_device_t * dev);
++extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+ 
+ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
+ 			      unsigned long arg);
+@@ -266,7 +267,6 @@ extern long r128_compat_ioctl(struct fil
+ #	define R128_EVENT_CRTC_OFFSET		(1 << 0)
+ #define R128_WINDOW_XY_OFFSET		0x1bcc
+ 
+-
+ /* CCE registers
+  */
+ #define R128_PM4_BUFFER_OFFSET		0x0700
+@@ -317,7 +317,6 @@ extern long r128_compat_ioctl(struct fil
+ #define R128_PM4_FIFO_DATA_EVEN		0x1000
+ #define R128_PM4_FIFO_DATA_ODD		0x1004
+ 
+-
+ /* CCE command packets
+  */
+ #define R128_CCE_PACKET0		0x00000000
+@@ -395,7 +394,6 @@ do {									\
+ 	R128_WRITE(R128_CLOCK_CNTL_DATA, (val));			\
+ } while (0)
+ 
+-
+ #define CCE_PACKET0( reg, n )		(R128_CCE_PACKET0 |		\
+ 					 ((n) << 16) | ((reg) >> 2))
+ #define CCE_PACKET1( reg0, reg1 )	(R128_CCE_PACKET1 |		\
+@@ -404,13 +402,11 @@ do {									\
+ #define CCE_PACKET3( pkt, n )		(R128_CCE_PACKET3 |		\
+ 					 (pkt) | ((n) << 16))
+ 
+-
+-static __inline__ void
+-r128_update_ring_snapshot( drm_r128_private_t *dev_priv )
++static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv)
+ {
+ 	drm_r128_ring_buffer_t *ring = &dev_priv->ring;
+-	ring->space = (GET_RING_HEAD( dev_priv ) - ring->tail) * sizeof(u32);
+-	if ( ring->space <= 0 )
++	ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32);
++	if (ring->space <= 0)
+ 		ring->space += ring->size;
+ }
+ 
+@@ -451,7 +447,6 @@ do {									\
+ 	OUT_RING( R128_EVENT_CRTC_OFFSET );				\
+ } while (0)
+ 
+-
+ /* ================================================================
+  * Ring control
+  */
+@@ -521,4 +516,4 @@ do {									\
+ 	write &= tail_mask;						\
+ } while (0)
+ 
+-#endif /* __R128_DRV_H__ */
++#endif				/* __R128_DRV_H__ */
+diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c
+--- a/drivers/char/drm/r128_ioc32.c
++++ b/drivers/char/drm/r128_ioc32.c
+@@ -65,10 +65,10 @@ static int compat_r128_init(struct file 
+ {
+ 	drm_r128_init32_t init32;
+ 	drm_r128_init_t __user *init;
+-	
++
+ 	if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
+ 		return -EFAULT;
+-	
++
+ 	init = compat_alloc_user_space(sizeof(*init));
+ 	if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
+ 	    || __put_user(init32.func, &init->func)
+@@ -92,14 +92,14 @@ static int compat_r128_init(struct file 
+ 	    || __put_user(init32.ring_offset, &init->ring_offset)
+ 	    || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
+ 	    || __put_user(init32.buffers_offset, &init->buffers_offset)
+-	    || __put_user(init32.agp_textures_offset, &init->agp_textures_offset))
++	    || __put_user(init32.agp_textures_offset,
++			  &init->agp_textures_offset))
+ 		return -EFAULT;
+-	
++
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+ 			 DRM_IOCTL_R128_INIT, (unsigned long)init);
+ }
+ 
+-
+ typedef struct drm_r128_depth32 {
+ 	int func;
+ 	int n;
+@@ -124,13 +124,15 @@ static int compat_r128_depth(struct file
+ 	    || __put_user(depth32.n, &depth->n)
+ 	    || __put_user((int __user *)(unsigned long)depth32.x, &depth->x)
+ 	    || __put_user((int __user *)(unsigned long)depth32.y, &depth->y)
+-	    || __put_user((unsigned int __user *)(unsigned long)depth32.buffer, &depth->buffer)
+-	    || __put_user((unsigned char __user *)(unsigned long)depth32.mask, &depth->mask))
++	    || __put_user((unsigned int __user *)(unsigned long)depth32.buffer,
++			  &depth->buffer)
++	    || __put_user((unsigned char __user *)(unsigned long)depth32.mask,
++			  &depth->mask))
+ 		return -EFAULT;
+-	
++
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_R128_DEPTH, (unsigned long)depth);	
+-	
++			 DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
++
+ }
+ 
+ typedef struct drm_r128_stipple32 {
+@@ -148,7 +150,8 @@ static int compat_r128_stipple(struct fi
+ 
+ 	stipple = compat_alloc_user_space(sizeof(*stipple));
+ 	if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple))
+-	    || __put_user((unsigned int __user *)(unsigned long)stipple32.mask, &stipple->mask))
++	    || __put_user((unsigned int __user *)(unsigned long)stipple32.mask,
++			  &stipple->mask))
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+@@ -172,9 +175,10 @@ static int compat_r128_getparam(struct f
+ 	getparam = compat_alloc_user_space(sizeof(*getparam));
+ 	if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
+ 	    || __put_user(getparam32.param, &getparam->param)
+-	    || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
++	    || __put_user((void __user *)(unsigned long)getparam32.value,
++			  &getparam->value))
+ 		return -EFAULT;
+-	
++
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+ 			 DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
+ }
+@@ -195,8 +199,7 @@ drm_ioctl_compat_t *r128_compat_ioctls[]
+  * \param arg user argument.
+  * \return zero on success or negative number on failure.
+  */
+-long r128_compat_ioctl(struct file *filp, unsigned int cmd,
+-			 unsigned long arg)
++long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ 	unsigned int nr = DRM_IOCTL_NR(cmd);
+ 	drm_ioctl_compat_t *fn = NULL;
+@@ -210,7 +213,7 @@ long r128_compat_ioctl(struct file *filp
+ 
+ 	lock_kernel();		/* XXX for now */
+ 	if (fn != NULL)
+-		ret = (*fn)(filp, cmd, arg);
++		ret = (*fn) (filp, cmd, arg);
+ 	else
+ 		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+ 	unlock_kernel();
+diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c
+--- a/drivers/char/drm/r128_irq.c
++++ b/drivers/char/drm/r128_irq.c
+@@ -1,7 +1,7 @@
+ /* r128_irq.c -- IRQ handling for radeon -*- linux-c -*-
+  *
+  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+- * 
++ *
+  * The Weather Channel (TM) funded Tungsten Graphics to develop the
+  * initial release of the Radeon 8500 driver under the XFree86 license.
+  * This notice must be preserved.
+@@ -35,68 +35,67 @@
+ #include "r128_drm.h"
+ #include "r128_drv.h"
+ 
+-irqreturn_t r128_driver_irq_handler( DRM_IRQ_ARGS )
++irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
+ {
+ 	drm_device_t *dev = (drm_device_t *) arg;
+-	drm_r128_private_t *dev_priv = 
+-	   (drm_r128_private_t *)dev->dev_private;
++	drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
+ 	int status;
+ 
+-	status = R128_READ( R128_GEN_INT_STATUS );
+-	
++	status = R128_READ(R128_GEN_INT_STATUS);
++
+ 	/* VBLANK interrupt */
+-	if ( status & R128_CRTC_VBLANK_INT ) {
+-		R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
++	if (status & R128_CRTC_VBLANK_INT) {
++		R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
+ 		atomic_inc(&dev->vbl_received);
+ 		DRM_WAKEUP(&dev->vbl_queue);
+-		drm_vbl_send_signals( dev );
++		drm_vbl_send_signals(dev);
+ 		return IRQ_HANDLED;
+ 	}
+ 	return IRQ_NONE;
+ }
+ 
+-int r128_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
++int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
+ {
+ 	unsigned int cur_vblank;
+ 	int ret = 0;
+ 
+ 	/* Assume that the user has missed the current sequence number
+ 	 * by about a day rather than she wants to wait for years
+-	 * using vertical blanks... 
++	 * using vertical blanks...
+ 	 */
+-	DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, 
+-		     ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
+-			 - *sequence ) <= (1<<23) ) );
++	DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
++		    (((cur_vblank = atomic_read(&dev->vbl_received))
++		      - *sequence) <= (1 << 23)));
+ 
+ 	*sequence = cur_vblank;
+ 
+ 	return ret;
+ }
+ 
+-void r128_driver_irq_preinstall( drm_device_t *dev ) {
+-  	drm_r128_private_t *dev_priv = 
+-	   (drm_r128_private_t *)dev->dev_private;
++void r128_driver_irq_preinstall(drm_device_t * dev)
++{
++	drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
+ 
+ 	/* Disable *all* interrupts */
+-      	R128_WRITE( R128_GEN_INT_CNTL, 0 );
++	R128_WRITE(R128_GEN_INT_CNTL, 0);
+ 	/* Clear vblank bit if it's already high */
+-   	R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
++	R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
+ }
+ 
+-void r128_driver_irq_postinstall( drm_device_t *dev ) {
+-  	drm_r128_private_t *dev_priv = 
+-	   (drm_r128_private_t *)dev->dev_private;
++void r128_driver_irq_postinstall(drm_device_t * dev)
++{
++	drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
+ 
+ 	/* Turn on VBL interrupt */
+-   	R128_WRITE( R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN );
++	R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
+ }
+ 
+-void r128_driver_irq_uninstall( drm_device_t *dev ) {
+-  	drm_r128_private_t *dev_priv = 
+-	   (drm_r128_private_t *)dev->dev_private;
++void r128_driver_irq_uninstall(drm_device_t * dev)
++{
++	drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
+ 	if (!dev_priv)
+ 		return;
+ 
+ 	/* Disable *all* interrupts */
+-	R128_WRITE( R128_GEN_INT_CNTL, 0 );
++	R128_WRITE(R128_GEN_INT_CNTL, 0);
+ }
+diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
+--- a/drivers/char/drm/r128_state.c
++++ b/drivers/char/drm/r128_state.c
+@@ -32,235 +32,233 @@
+ #include "r128_drm.h"
+ #include "r128_drv.h"
+ 
+-
+ /* ================================================================
+  * CCE hardware state programming functions
+  */
+ 
+-static void r128_emit_clip_rects( drm_r128_private_t *dev_priv,
+-				  drm_clip_rect_t *boxes, int count )
++static void r128_emit_clip_rects(drm_r128_private_t * dev_priv,
++				 drm_clip_rect_t * boxes, int count)
+ {
+ 	u32 aux_sc_cntl = 0x00000000;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
++	DRM_DEBUG("    %s\n", __FUNCTION__);
+ 
+-	BEGIN_RING( (count < 3? count: 3) * 5 + 2 );
++	BEGIN_RING((count < 3 ? count : 3) * 5 + 2);
+ 
+-	if ( count >= 1 ) {
+-		OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) );
+-		OUT_RING( boxes[0].x1 );
+-		OUT_RING( boxes[0].x2 - 1 );
+-		OUT_RING( boxes[0].y1 );
+-		OUT_RING( boxes[0].y2 - 1 );
++	if (count >= 1) {
++		OUT_RING(CCE_PACKET0(R128_AUX1_SC_LEFT, 3));
++		OUT_RING(boxes[0].x1);
++		OUT_RING(boxes[0].x2 - 1);
++		OUT_RING(boxes[0].y1);
++		OUT_RING(boxes[0].y2 - 1);
+ 
+ 		aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR);
+ 	}
+-	if ( count >= 2 ) {
+-		OUT_RING( CCE_PACKET0( R128_AUX2_SC_LEFT, 3 ) );
+-		OUT_RING( boxes[1].x1 );
+-		OUT_RING( boxes[1].x2 - 1 );
+-		OUT_RING( boxes[1].y1 );
+-		OUT_RING( boxes[1].y2 - 1 );
++	if (count >= 2) {
++		OUT_RING(CCE_PACKET0(R128_AUX2_SC_LEFT, 3));
++		OUT_RING(boxes[1].x1);
++		OUT_RING(boxes[1].x2 - 1);
++		OUT_RING(boxes[1].y1);
++		OUT_RING(boxes[1].y2 - 1);
+ 
+ 		aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR);
+ 	}
+-	if ( count >= 3 ) {
+-		OUT_RING( CCE_PACKET0( R128_AUX3_SC_LEFT, 3 ) );
+-		OUT_RING( boxes[2].x1 );
+-		OUT_RING( boxes[2].x2 - 1 );
+-		OUT_RING( boxes[2].y1 );
+-		OUT_RING( boxes[2].y2 - 1 );
++	if (count >= 3) {
++		OUT_RING(CCE_PACKET0(R128_AUX3_SC_LEFT, 3));
++		OUT_RING(boxes[2].x1);
++		OUT_RING(boxes[2].x2 - 1);
++		OUT_RING(boxes[2].y1);
++		OUT_RING(boxes[2].y2 - 1);
+ 
+ 		aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR);
+ 	}
+ 
+-	OUT_RING( CCE_PACKET0( R128_AUX_SC_CNTL, 0 ) );
+-	OUT_RING( aux_sc_cntl );
++	OUT_RING(CCE_PACKET0(R128_AUX_SC_CNTL, 0));
++	OUT_RING(aux_sc_cntl);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static __inline__ void r128_emit_core( drm_r128_private_t *dev_priv )
++static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv)
+ {
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
++	DRM_DEBUG("    %s\n", __FUNCTION__);
+ 
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 
+-	OUT_RING( CCE_PACKET0( R128_SCALE_3D_CNTL, 0 ) );
+-	OUT_RING( ctx->scale_3d_cntl );
++	OUT_RING(CCE_PACKET0(R128_SCALE_3D_CNTL, 0));
++	OUT_RING(ctx->scale_3d_cntl);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static __inline__ void r128_emit_context( drm_r128_private_t *dev_priv )
++static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv)
+ {
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
++	DRM_DEBUG("    %s\n", __FUNCTION__);
+ 
+-	BEGIN_RING( 13 );
++	BEGIN_RING(13);
+ 
+-	OUT_RING( CCE_PACKET0( R128_DST_PITCH_OFFSET_C, 11 ) );
+-	OUT_RING( ctx->dst_pitch_offset_c );
+-	OUT_RING( ctx->dp_gui_master_cntl_c );
+-	OUT_RING( ctx->sc_top_left_c );
+-	OUT_RING( ctx->sc_bottom_right_c );
+-	OUT_RING( ctx->z_offset_c );
+-	OUT_RING( ctx->z_pitch_c );
+-	OUT_RING( ctx->z_sten_cntl_c );
+-	OUT_RING( ctx->tex_cntl_c );
+-	OUT_RING( ctx->misc_3d_state_cntl_reg );
+-	OUT_RING( ctx->texture_clr_cmp_clr_c );
+-	OUT_RING( ctx->texture_clr_cmp_msk_c );
+-	OUT_RING( ctx->fog_color_c );
++	OUT_RING(CCE_PACKET0(R128_DST_PITCH_OFFSET_C, 11));
++	OUT_RING(ctx->dst_pitch_offset_c);
++	OUT_RING(ctx->dp_gui_master_cntl_c);
++	OUT_RING(ctx->sc_top_left_c);
++	OUT_RING(ctx->sc_bottom_right_c);
++	OUT_RING(ctx->z_offset_c);
++	OUT_RING(ctx->z_pitch_c);
++	OUT_RING(ctx->z_sten_cntl_c);
++	OUT_RING(ctx->tex_cntl_c);
++	OUT_RING(ctx->misc_3d_state_cntl_reg);
++	OUT_RING(ctx->texture_clr_cmp_clr_c);
++	OUT_RING(ctx->texture_clr_cmp_msk_c);
++	OUT_RING(ctx->fog_color_c);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static __inline__ void r128_emit_setup( drm_r128_private_t *dev_priv )
++static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv)
+ {
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
++	DRM_DEBUG("    %s\n", __FUNCTION__);
+ 
+-	BEGIN_RING( 3 );
++	BEGIN_RING(3);
+ 
+-	OUT_RING( CCE_PACKET1( R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP ) );
+-	OUT_RING( ctx->setup_cntl );
+-	OUT_RING( ctx->pm4_vc_fpu_setup );
++	OUT_RING(CCE_PACKET1(R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP));
++	OUT_RING(ctx->setup_cntl);
++	OUT_RING(ctx->pm4_vc_fpu_setup);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static __inline__ void r128_emit_masks( drm_r128_private_t *dev_priv )
++static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv)
+ {
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
++	DRM_DEBUG("    %s\n", __FUNCTION__);
+ 
+-	BEGIN_RING( 5 );
++	BEGIN_RING(5);
+ 
+-	OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
+-	OUT_RING( ctx->dp_write_mask );
++	OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0));
++	OUT_RING(ctx->dp_write_mask);
+ 
+-	OUT_RING( CCE_PACKET0( R128_STEN_REF_MASK_C, 1 ) );
+-	OUT_RING( ctx->sten_ref_mask_c );
+-	OUT_RING( ctx->plane_3d_mask_c );
++	OUT_RING(CCE_PACKET0(R128_STEN_REF_MASK_C, 1));
++	OUT_RING(ctx->sten_ref_mask_c);
++	OUT_RING(ctx->plane_3d_mask_c);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static __inline__ void r128_emit_window( drm_r128_private_t *dev_priv )
++static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv)
+ {
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
++	DRM_DEBUG("    %s\n", __FUNCTION__);
+ 
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 
+-	OUT_RING( CCE_PACKET0( R128_WINDOW_XY_OFFSET, 0 ) );
+-	OUT_RING( ctx->window_xy_offset );
++	OUT_RING(CCE_PACKET0(R128_WINDOW_XY_OFFSET, 0));
++	OUT_RING(ctx->window_xy_offset);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static __inline__ void r128_emit_tex0( drm_r128_private_t *dev_priv )
++static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv)
+ {
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
+ 	drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
+ 	int i;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
++	DRM_DEBUG("    %s\n", __FUNCTION__);
+ 
+-	BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS );
++	BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS);
+ 
+-	OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
+-			       2 + R128_MAX_TEXTURE_LEVELS ) );
+-	OUT_RING( tex->tex_cntl );
+-	OUT_RING( tex->tex_combine_cntl );
+-	OUT_RING( ctx->tex_size_pitch_c );
+-	for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
+-		OUT_RING( tex->tex_offset[i] );
+-	}
+-
+-	OUT_RING( CCE_PACKET0( R128_CONSTANT_COLOR_C, 1 ) );
+-	OUT_RING( ctx->constant_color_c );
+-	OUT_RING( tex->tex_border_color );
++	OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C,
++			     2 + R128_MAX_TEXTURE_LEVELS));
++	OUT_RING(tex->tex_cntl);
++	OUT_RING(tex->tex_combine_cntl);
++	OUT_RING(ctx->tex_size_pitch_c);
++	for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) {
++		OUT_RING(tex->tex_offset[i]);
++	}
++
++	OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1));
++	OUT_RING(ctx->constant_color_c);
++	OUT_RING(tex->tex_border_color);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static __inline__ void r128_emit_tex1( drm_r128_private_t *dev_priv )
++static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv)
+ {
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
+ 	int i;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
++	DRM_DEBUG("    %s\n", __FUNCTION__);
+ 
+-	BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS );
++	BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS);
+ 
+-	OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
+-			       1 + R128_MAX_TEXTURE_LEVELS ) );
+-	OUT_RING( tex->tex_cntl );
+-	OUT_RING( tex->tex_combine_cntl );
+-	for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
+-		OUT_RING( tex->tex_offset[i] );
++	OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS));
++	OUT_RING(tex->tex_cntl);
++	OUT_RING(tex->tex_combine_cntl);
++	for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) {
++		OUT_RING(tex->tex_offset[i]);
+ 	}
+ 
+-	OUT_RING( CCE_PACKET0( R128_SEC_TEXTURE_BORDER_COLOR_C, 0 ) );
+-	OUT_RING( tex->tex_border_color );
++	OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0));
++	OUT_RING(tex->tex_border_color);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv )
++static __inline__ void r128_emit_state(drm_r128_private_t * dev_priv)
+ {
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	unsigned int dirty = sarea_priv->dirty;
+ 
+-	DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty );
++	DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty);
+ 
+-	if ( dirty & R128_UPLOAD_CORE ) {
+-		r128_emit_core( dev_priv );
++	if (dirty & R128_UPLOAD_CORE) {
++		r128_emit_core(dev_priv);
+ 		sarea_priv->dirty &= ~R128_UPLOAD_CORE;
+ 	}
+ 
+-	if ( dirty & R128_UPLOAD_CONTEXT ) {
+-		r128_emit_context( dev_priv );
++	if (dirty & R128_UPLOAD_CONTEXT) {
++		r128_emit_context(dev_priv);
+ 		sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT;
+ 	}
+ 
+-	if ( dirty & R128_UPLOAD_SETUP ) {
+-		r128_emit_setup( dev_priv );
++	if (dirty & R128_UPLOAD_SETUP) {
++		r128_emit_setup(dev_priv);
+ 		sarea_priv->dirty &= ~R128_UPLOAD_SETUP;
+ 	}
+ 
+-	if ( dirty & R128_UPLOAD_MASKS ) {
+-		r128_emit_masks( dev_priv );
++	if (dirty & R128_UPLOAD_MASKS) {
++		r128_emit_masks(dev_priv);
+ 		sarea_priv->dirty &= ~R128_UPLOAD_MASKS;
+ 	}
+ 
+-	if ( dirty & R128_UPLOAD_WINDOW ) {
+-		r128_emit_window( dev_priv );
++	if (dirty & R128_UPLOAD_WINDOW) {
++		r128_emit_window(dev_priv);
+ 		sarea_priv->dirty &= ~R128_UPLOAD_WINDOW;
+ 	}
+ 
+-	if ( dirty & R128_UPLOAD_TEX0 ) {
+-		r128_emit_tex0( dev_priv );
++	if (dirty & R128_UPLOAD_TEX0) {
++		r128_emit_tex0(dev_priv);
+ 		sarea_priv->dirty &= ~R128_UPLOAD_TEX0;
+ 	}
+ 
+-	if ( dirty & R128_UPLOAD_TEX1 ) {
+-		r128_emit_tex1( dev_priv );
++	if (dirty & R128_UPLOAD_TEX1) {
++		r128_emit_tex1(dev_priv);
+ 		sarea_priv->dirty &= ~R128_UPLOAD_TEX1;
+ 	}
+ 
+@@ -270,26 +268,23 @@ static __inline__ void r128_emit_state( 
+ 	sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE;
+ }
+ 
+-
+ #if R128_PERFORMANCE_BOXES
+ /* ================================================================
+  * Performance monitoring functions
+  */
+ 
+-static void r128_clear_box( drm_r128_private_t *dev_priv,
+-			    int x, int y, int w, int h,
+-			    int r, int g, int b )
++static void r128_clear_box(drm_r128_private_t * dev_priv,
++			   int x, int y, int w, int h, int r, int g, int b)
+ {
+ 	u32 pitch, offset;
+ 	u32 fb_bpp, color;
+ 	RING_LOCALS;
+ 
+-	switch ( dev_priv->fb_bpp ) {
++	switch (dev_priv->fb_bpp) {
+ 	case 16:
+ 		fb_bpp = R128_GMC_DST_16BPP;
+ 		color = (((r & 0xf8) << 8) |
+-			 ((g & 0xfc) << 3) |
+-			 ((b & 0xf8) >> 3));
++			 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
+ 		break;
+ 	case 24:
+ 		fb_bpp = R128_GMC_DST_24BPP;
+@@ -297,7 +292,7 @@ static void r128_clear_box( drm_r128_pri
+ 		break;
+ 	case 32:
+ 		fb_bpp = R128_GMC_DST_32BPP;
+-		color = (((0xff) << 24) | (r << 16) | (g <<  8) | b);
++		color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
+ 		break;
+ 	default:
+ 		return;
+@@ -306,60 +301,58 @@ static void r128_clear_box( drm_r128_pri
+ 	offset = dev_priv->back_offset;
+ 	pitch = dev_priv->back_pitch >> 3;
+ 
+-	BEGIN_RING( 6 );
++	BEGIN_RING(6);
+ 
+-	OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+-	OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+-		  R128_GMC_BRUSH_SOLID_COLOR |
+-		  fb_bpp |
+-		  R128_GMC_SRC_DATATYPE_COLOR |
+-		  R128_ROP3_P |
+-		  R128_GMC_CLR_CMP_CNTL_DIS |
+-		  R128_GMC_AUX_CLIP_DIS );
++	OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
++	OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
++		 R128_GMC_BRUSH_SOLID_COLOR |
++		 fb_bpp |
++		 R128_GMC_SRC_DATATYPE_COLOR |
++		 R128_ROP3_P |
++		 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS);
+ 
+-	OUT_RING( (pitch << 21) | (offset >> 5) );
+-	OUT_RING( color );
++	OUT_RING((pitch << 21) | (offset >> 5));
++	OUT_RING(color);
+ 
+-	OUT_RING( (x << 16) | y );
+-	OUT_RING( (w << 16) | h );
++	OUT_RING((x << 16) | y);
++	OUT_RING((w << 16) | h);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static void r128_cce_performance_boxes( drm_r128_private_t *dev_priv )
++static void r128_cce_performance_boxes(drm_r128_private_t * dev_priv)
+ {
+-	if ( atomic_read( &dev_priv->idle_count ) == 0 ) {
+-		r128_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
++	if (atomic_read(&dev_priv->idle_count) == 0) {
++		r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
+ 	} else {
+-		atomic_set( &dev_priv->idle_count, 0 );
++		atomic_set(&dev_priv->idle_count, 0);
+ 	}
+ }
+ 
+ #endif
+ 
+-
+ /* ================================================================
+  * CCE command dispatch functions
+  */
+ 
+-static void r128_print_dirty( const char *msg, unsigned int flags )
++static void r128_print_dirty(const char *msg, unsigned int flags)
+ {
+-	DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
+-		  msg,
+-		  flags,
+-		  (flags & R128_UPLOAD_CORE)        ? "core, " : "",
+-		  (flags & R128_UPLOAD_CONTEXT)     ? "context, " : "",
+-		  (flags & R128_UPLOAD_SETUP)       ? "setup, " : "",
+-		  (flags & R128_UPLOAD_TEX0)        ? "tex0, " : "",
+-		  (flags & R128_UPLOAD_TEX1)        ? "tex1, " : "",
+-		  (flags & R128_UPLOAD_MASKS)       ? "masks, " : "",
+-		  (flags & R128_UPLOAD_WINDOW)      ? "window, " : "",
+-		  (flags & R128_UPLOAD_CLIPRECTS)   ? "cliprects, " : "",
+-		  (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
++	DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
++		 msg,
++		 flags,
++		 (flags & R128_UPLOAD_CORE) ? "core, " : "",
++		 (flags & R128_UPLOAD_CONTEXT) ? "context, " : "",
++		 (flags & R128_UPLOAD_SETUP) ? "setup, " : "",
++		 (flags & R128_UPLOAD_TEX0) ? "tex0, " : "",
++		 (flags & R128_UPLOAD_TEX1) ? "tex1, " : "",
++		 (flags & R128_UPLOAD_MASKS) ? "masks, " : "",
++		 (flags & R128_UPLOAD_WINDOW) ? "window, " : "",
++		 (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
++		 (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "");
+ }
+ 
+-static void r128_cce_dispatch_clear( drm_device_t *dev,
+-				     drm_r128_clear_t *clear )
++static void r128_cce_dispatch_clear(drm_device_t * dev,
++				    drm_r128_clear_t * clear)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+@@ -368,102 +361,103 @@ static void r128_cce_dispatch_clear( drm
+ 	unsigned int flags = clear->flags;
+ 	int i;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "%s\n", __FUNCTION__ );
++	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+-	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
++	if (dev_priv->page_flipping && dev_priv->current_page == 1) {
+ 		unsigned int tmp = flags;
+ 
+ 		flags &= ~(R128_FRONT | R128_BACK);
+-		if ( tmp & R128_FRONT ) flags |= R128_BACK;
+-		if ( tmp & R128_BACK )  flags |= R128_FRONT;
++		if (tmp & R128_FRONT)
++			flags |= R128_BACK;
++		if (tmp & R128_BACK)
++			flags |= R128_FRONT;
+ 	}
+ 
+-	for ( i = 0 ; i < nbox ; i++ ) {
++	for (i = 0; i < nbox; i++) {
+ 		int x = pbox[i].x1;
+ 		int y = pbox[i].y1;
+ 		int w = pbox[i].x2 - x;
+ 		int h = pbox[i].y2 - y;
+ 
+-		DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
+-			   pbox[i].x1, pbox[i].y1, pbox[i].x2,
+-			   pbox[i].y2, flags );
++		DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
++			  pbox[i].x1, pbox[i].y1, pbox[i].x2,
++			  pbox[i].y2, flags);
+ 
+-		if ( flags & (R128_FRONT | R128_BACK) ) {
+-			BEGIN_RING( 2 );
++		if (flags & (R128_FRONT | R128_BACK)) {
++			BEGIN_RING(2);
+ 
+-			OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
+-			OUT_RING( clear->color_mask );
++			OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0));
++			OUT_RING(clear->color_mask);
+ 
+ 			ADVANCE_RING();
+ 		}
+ 
+-		if ( flags & R128_FRONT ) {
+-			BEGIN_RING( 6 );
++		if (flags & R128_FRONT) {
++			BEGIN_RING(6);
+ 
+-			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+-				  R128_GMC_BRUSH_SOLID_COLOR |
+-				  (dev_priv->color_fmt << 8) |
+-				  R128_GMC_SRC_DATATYPE_COLOR |
+-				  R128_ROP3_P |
+-				  R128_GMC_CLR_CMP_CNTL_DIS |
+-				  R128_GMC_AUX_CLIP_DIS );
++			OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
++			OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
++				 R128_GMC_BRUSH_SOLID_COLOR |
++				 (dev_priv->color_fmt << 8) |
++				 R128_GMC_SRC_DATATYPE_COLOR |
++				 R128_ROP3_P |
++				 R128_GMC_CLR_CMP_CNTL_DIS |
++				 R128_GMC_AUX_CLIP_DIS);
+ 
+-			OUT_RING( dev_priv->front_pitch_offset_c );
+-			OUT_RING( clear->clear_color );
++			OUT_RING(dev_priv->front_pitch_offset_c);
++			OUT_RING(clear->clear_color);
+ 
+-			OUT_RING( (x << 16) | y );
+-			OUT_RING( (w << 16) | h );
++			OUT_RING((x << 16) | y);
++			OUT_RING((w << 16) | h);
+ 
+ 			ADVANCE_RING();
+ 		}
+ 
+-		if ( flags & R128_BACK ) {
+-			BEGIN_RING( 6 );
++		if (flags & R128_BACK) {
++			BEGIN_RING(6);
+ 
+-			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+-				  R128_GMC_BRUSH_SOLID_COLOR |
+-				  (dev_priv->color_fmt << 8) |
+-				  R128_GMC_SRC_DATATYPE_COLOR |
+-				  R128_ROP3_P |
+-				  R128_GMC_CLR_CMP_CNTL_DIS |
+-				  R128_GMC_AUX_CLIP_DIS );
++			OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
++			OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
++				 R128_GMC_BRUSH_SOLID_COLOR |
++				 (dev_priv->color_fmt << 8) |
++				 R128_GMC_SRC_DATATYPE_COLOR |
++				 R128_ROP3_P |
++				 R128_GMC_CLR_CMP_CNTL_DIS |
++				 R128_GMC_AUX_CLIP_DIS);
+ 
+-			OUT_RING( dev_priv->back_pitch_offset_c );
+-			OUT_RING( clear->clear_color );
++			OUT_RING(dev_priv->back_pitch_offset_c);
++			OUT_RING(clear->clear_color);
+ 
+-			OUT_RING( (x << 16) | y );
+-			OUT_RING( (w << 16) | h );
++			OUT_RING((x << 16) | y);
++			OUT_RING((w << 16) | h);
+ 
+ 			ADVANCE_RING();
+ 		}
+ 
+-		if ( flags & R128_DEPTH ) {
+-			BEGIN_RING( 6 );
++		if (flags & R128_DEPTH) {
++			BEGIN_RING(6);
+ 
+-			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+-				  R128_GMC_BRUSH_SOLID_COLOR |
+-				  (dev_priv->depth_fmt << 8) |
+-				  R128_GMC_SRC_DATATYPE_COLOR |
+-				  R128_ROP3_P |
+-				  R128_GMC_CLR_CMP_CNTL_DIS |
+-				  R128_GMC_AUX_CLIP_DIS |
+-				  R128_GMC_WR_MSK_DIS );
++			OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
++			OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
++				 R128_GMC_BRUSH_SOLID_COLOR |
++				 (dev_priv->depth_fmt << 8) |
++				 R128_GMC_SRC_DATATYPE_COLOR |
++				 R128_ROP3_P |
++				 R128_GMC_CLR_CMP_CNTL_DIS |
++				 R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS);
+ 
+-			OUT_RING( dev_priv->depth_pitch_offset_c );
+-			OUT_RING( clear->clear_depth );
++			OUT_RING(dev_priv->depth_pitch_offset_c);
++			OUT_RING(clear->clear_depth);
+ 
+-			OUT_RING( (x << 16) | y );
+-			OUT_RING( (w << 16) | h );
++			OUT_RING((x << 16) | y);
++			OUT_RING((w << 16) | h);
+ 
+ 			ADVANCE_RING();
+ 		}
+ 	}
+ }
+ 
+-static void r128_cce_dispatch_swap( drm_device_t *dev )
++static void r128_cce_dispatch_swap(drm_device_t * dev)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+@@ -471,48 +465,46 @@ static void r128_cce_dispatch_swap( drm_
+ 	drm_clip_rect_t *pbox = sarea_priv->boxes;
+ 	int i;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "%s\n", __FUNCTION__ );
++	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+ #if R128_PERFORMANCE_BOXES
+ 	/* Do some trivial performance monitoring...
+ 	 */
+-	r128_cce_performance_boxes( dev_priv );
++	r128_cce_performance_boxes(dev_priv);
+ #endif
+ 
+-	for ( i = 0 ; i < nbox ; i++ ) {
++	for (i = 0; i < nbox; i++) {
+ 		int x = pbox[i].x1;
+ 		int y = pbox[i].y1;
+ 		int w = pbox[i].x2 - x;
+ 		int h = pbox[i].y2 - y;
+ 
+-		BEGIN_RING( 7 );
++		BEGIN_RING(7);
+ 
+-		OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
+-		OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+-			  R128_GMC_DST_PITCH_OFFSET_CNTL |
+-			  R128_GMC_BRUSH_NONE |
+-			  (dev_priv->color_fmt << 8) |
+-			  R128_GMC_SRC_DATATYPE_COLOR |
+-			  R128_ROP3_S |
+-			  R128_DP_SRC_SOURCE_MEMORY |
+-			  R128_GMC_CLR_CMP_CNTL_DIS |
+-			  R128_GMC_AUX_CLIP_DIS |
+-			  R128_GMC_WR_MSK_DIS );
++		OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
++		OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
++			 R128_GMC_DST_PITCH_OFFSET_CNTL |
++			 R128_GMC_BRUSH_NONE |
++			 (dev_priv->color_fmt << 8) |
++			 R128_GMC_SRC_DATATYPE_COLOR |
++			 R128_ROP3_S |
++			 R128_DP_SRC_SOURCE_MEMORY |
++			 R128_GMC_CLR_CMP_CNTL_DIS |
++			 R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS);
+ 
+ 		/* Make this work even if front & back are flipped:
+ 		 */
+ 		if (dev_priv->current_page == 0) {
+-			OUT_RING( dev_priv->back_pitch_offset_c );
+-			OUT_RING( dev_priv->front_pitch_offset_c );
+-		} 
+-		else {
+-			OUT_RING( dev_priv->front_pitch_offset_c );
+-			OUT_RING( dev_priv->back_pitch_offset_c );
++			OUT_RING(dev_priv->back_pitch_offset_c);
++			OUT_RING(dev_priv->front_pitch_offset_c);
++		} else {
++			OUT_RING(dev_priv->front_pitch_offset_c);
++			OUT_RING(dev_priv->back_pitch_offset_c);
+ 		}
+ 
+-		OUT_RING( (x << 16) | y );
+-		OUT_RING( (x << 16) | y );
+-		OUT_RING( (w << 16) | h );
++		OUT_RING((x << 16) | y);
++		OUT_RING((x << 16) | y);
++		OUT_RING((w << 16) | h);
+ 
+ 		ADVANCE_RING();
+ 	}
+@@ -523,38 +515,37 @@ static void r128_cce_dispatch_swap( drm_
+ 	 */
+ 	dev_priv->sarea_priv->last_frame++;
+ 
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 
+-	OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
+-	OUT_RING( dev_priv->sarea_priv->last_frame );
++	OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0));
++	OUT_RING(dev_priv->sarea_priv->last_frame);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static void r128_cce_dispatch_flip( drm_device_t *dev )
++static void r128_cce_dispatch_flip(drm_device_t * dev)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	RING_LOCALS;
+-	DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 
+-		__FUNCTION__,
+-		dev_priv->current_page,
+-		dev_priv->sarea_priv->pfCurrentPage);
++	DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
++		  __FUNCTION__,
++		  dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
+ 
+ #if R128_PERFORMANCE_BOXES
+ 	/* Do some trivial performance monitoring...
+ 	 */
+-	r128_cce_performance_boxes( dev_priv );
++	r128_cce_performance_boxes(dev_priv);
+ #endif
+ 
+-	BEGIN_RING( 4 );
++	BEGIN_RING(4);
+ 
+ 	R128_WAIT_UNTIL_PAGE_FLIPPED();
+-	OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) );
++	OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0));
+ 
+-	if ( dev_priv->current_page == 0 ) {
+-		OUT_RING( dev_priv->back_offset );
++	if (dev_priv->current_page == 0) {
++		OUT_RING(dev_priv->back_offset);
+ 	} else {
+-		OUT_RING( dev_priv->front_offset );
++		OUT_RING(dev_priv->front_offset);
+ 	}
+ 
+ 	ADVANCE_RING();
+@@ -565,18 +556,17 @@ static void r128_cce_dispatch_flip( drm_
+ 	 */
+ 	dev_priv->sarea_priv->last_frame++;
+ 	dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
+-					      1 - dev_priv->current_page;
++	    1 - dev_priv->current_page;
+ 
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 
+-	OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
+-	OUT_RING( dev_priv->sarea_priv->last_frame );
++	OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0));
++	OUT_RING(dev_priv->sarea_priv->last_frame);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static void r128_cce_dispatch_vertex( drm_device_t *dev,
+-				      drm_buf_t *buf )
++static void r128_cce_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_buf_priv_t *buf_priv = buf->dev_private;
+@@ -587,50 +577,50 @@ static void r128_cce_dispatch_vertex( dr
+ 	int prim = buf_priv->prim;
+ 	int i = 0;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox );
++	DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox);
+ 
+-	if ( 0 )
+-		r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
++	if (0)
++		r128_print_dirty("dispatch_vertex", sarea_priv->dirty);
+ 
+-	if ( buf->used ) {
++	if (buf->used) {
+ 		buf_priv->dispatched = 1;
+ 
+-		if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
+-			r128_emit_state( dev_priv );
++		if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {
++			r128_emit_state(dev_priv);
+ 		}
+ 
+ 		do {
+ 			/* Emit the next set of up to three cliprects */
+-			if ( i < sarea_priv->nbox ) {
+-				r128_emit_clip_rects( dev_priv,
+-						      &sarea_priv->boxes[i],
+-						      sarea_priv->nbox - i );
++			if (i < sarea_priv->nbox) {
++				r128_emit_clip_rects(dev_priv,
++						     &sarea_priv->boxes[i],
++						     sarea_priv->nbox - i);
+ 			}
+ 
+ 			/* Emit the vertex buffer rendering commands */
+-			BEGIN_RING( 5 );
++			BEGIN_RING(5);
+ 
+-			OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 3 ) );
+-			OUT_RING( offset );
+-			OUT_RING( size );
+-			OUT_RING( format );
+-			OUT_RING( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
+-				  (size << R128_CCE_VC_CNTL_NUM_SHIFT) );
++			OUT_RING(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 3));
++			OUT_RING(offset);
++			OUT_RING(size);
++			OUT_RING(format);
++			OUT_RING(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
++				 (size << R128_CCE_VC_CNTL_NUM_SHIFT));
+ 
+ 			ADVANCE_RING();
+ 
+ 			i += 3;
+-		} while ( i < sarea_priv->nbox );
++		} while (i < sarea_priv->nbox);
+ 	}
+ 
+-	if ( buf_priv->discard ) {
++	if (buf_priv->discard) {
+ 		buf_priv->age = dev_priv->sarea_priv->last_dispatch;
+ 
+ 		/* Emit the vertex buffer age */
+-		BEGIN_RING( 2 );
++		BEGIN_RING(2);
+ 
+-		OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
+-		OUT_RING( buf_priv->age );
++		OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
++		OUT_RING(buf_priv->age);
+ 
+ 		ADVANCE_RING();
+ 
+@@ -646,17 +636,15 @@ static void r128_cce_dispatch_vertex( dr
+ 	sarea_priv->nbox = 0;
+ }
+ 
+-static void r128_cce_dispatch_indirect( drm_device_t *dev,
+-					drm_buf_t *buf,
+-					int start, int end )
++static void r128_cce_dispatch_indirect(drm_device_t * dev,
++				       drm_buf_t * buf, int start, int end)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_buf_priv_t *buf_priv = buf->dev_private;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
+-		   buf->idx, start, end );
++	DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
+ 
+-	if ( start != end ) {
++	if (start != end) {
+ 		int offset = buf->bus_address + start;
+ 		int dwords = (end - start + 3) / sizeof(u32);
+ 
+@@ -664,33 +652,33 @@ static void r128_cce_dispatch_indirect( 
+ 		 * dwords, so if we've been given an odd number we must
+ 		 * pad the data with a Type-2 CCE packet.
+ 		 */
+-		if ( dwords & 1 ) {
++		if (dwords & 1) {
+ 			u32 *data = (u32 *)
+-				((char *)dev->agp_buffer_map->handle
+-				 + buf->offset + start);
+-			data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
++			    ((char *)dev->agp_buffer_map->handle
++			     + buf->offset + start);
++			data[dwords++] = cpu_to_le32(R128_CCE_PACKET2);
+ 		}
+ 
+ 		buf_priv->dispatched = 1;
+ 
+ 		/* Fire off the indirect buffer */
+-		BEGIN_RING( 3 );
++		BEGIN_RING(3);
+ 
+-		OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) );
+-		OUT_RING( offset );
+-		OUT_RING( dwords );
++		OUT_RING(CCE_PACKET0(R128_PM4_IW_INDOFF, 1));
++		OUT_RING(offset);
++		OUT_RING(dwords);
+ 
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( buf_priv->discard ) {
++	if (buf_priv->discard) {
+ 		buf_priv->age = dev_priv->sarea_priv->last_dispatch;
+ 
+ 		/* Emit the indirect buffer age */
+-		BEGIN_RING( 2 );
++		BEGIN_RING(2);
+ 
+-		OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
+-		OUT_RING( buf_priv->age );
++		OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
++		OUT_RING(buf_priv->age);
+ 
+ 		ADVANCE_RING();
+ 
+@@ -703,10 +691,9 @@ static void r128_cce_dispatch_indirect( 
+ 	dev_priv->sarea_priv->last_dispatch++;
+ }
+ 
+-static void r128_cce_dispatch_indices( drm_device_t *dev,
+-				       drm_buf_t *buf,
+-				       int start, int end,
+-				       int count )
++static void r128_cce_dispatch_indices(drm_device_t * dev,
++				      drm_buf_t * buf,
++				      int start, int end, int count)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_buf_priv_t *buf_priv = buf->dev_private;
+@@ -718,62 +705,62 @@ static void r128_cce_dispatch_indices( d
+ 	int dwords;
+ 	int i = 0;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
++	DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count);
+ 
+-	if ( 0 )
+-		r128_print_dirty( "dispatch_indices", sarea_priv->dirty );
++	if (0)
++		r128_print_dirty("dispatch_indices", sarea_priv->dirty);
+ 
+-	if ( start != end ) {
++	if (start != end) {
+ 		buf_priv->dispatched = 1;
+ 
+-		if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
+-			r128_emit_state( dev_priv );
++		if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {
++			r128_emit_state(dev_priv);
+ 		}
+ 
+ 		dwords = (end - start + 3) / sizeof(u32);
+ 
+-		data = (u32 *)((char *)dev->agp_buffer_map->handle
+-			       + buf->offset + start);
++		data = (u32 *) ((char *)dev->agp_buffer_map->handle
++				+ buf->offset + start);
+ 
+-		data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
+-						    dwords-2 ) );
++		data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM,
++						  dwords - 2));
+ 
+-		data[1] = cpu_to_le32( offset );
+-		data[2] = cpu_to_le32( R128_MAX_VB_VERTS );
+-		data[3] = cpu_to_le32( format );
+-		data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
+-					(count << 16)) );
++		data[1] = cpu_to_le32(offset);
++		data[2] = cpu_to_le32(R128_MAX_VB_VERTS);
++		data[3] = cpu_to_le32(format);
++		data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
++				       (count << 16)));
+ 
+-		if ( count & 0x1 ) {
++		if (count & 0x1) {
+ #ifdef __LITTLE_ENDIAN
+-			data[dwords-1] &= 0x0000ffff;
++			data[dwords - 1] &= 0x0000ffff;
+ #else
+-			data[dwords-1] &= 0xffff0000;
++			data[dwords - 1] &= 0xffff0000;
+ #endif
+ 		}
+ 
+ 		do {
+ 			/* Emit the next set of up to three cliprects */
+-			if ( i < sarea_priv->nbox ) {
+-				r128_emit_clip_rects( dev_priv,
+-						      &sarea_priv->boxes[i],
+-						      sarea_priv->nbox - i );
++			if (i < sarea_priv->nbox) {
++				r128_emit_clip_rects(dev_priv,
++						     &sarea_priv->boxes[i],
++						     sarea_priv->nbox - i);
+ 			}
+ 
+-			r128_cce_dispatch_indirect( dev, buf, start, end );
++			r128_cce_dispatch_indirect(dev, buf, start, end);
+ 
+ 			i += 3;
+-		} while ( i < sarea_priv->nbox );
++		} while (i < sarea_priv->nbox);
+ 	}
+ 
+-	if ( buf_priv->discard ) {
++	if (buf_priv->discard) {
+ 		buf_priv->age = dev_priv->sarea_priv->last_dispatch;
+ 
+ 		/* Emit the vertex buffer age */
+-		BEGIN_RING( 2 );
++		BEGIN_RING(2);
+ 
+-		OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
+-		OUT_RING( buf_priv->age );
++		OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
++		OUT_RING(buf_priv->age);
+ 
+ 		ADVANCE_RING();
+ 
+@@ -788,9 +775,8 @@ static void r128_cce_dispatch_indices( d
+ 	sarea_priv->nbox = 0;
+ }
+ 
+-static int r128_cce_dispatch_blit( DRMFILE filp,
+-				   drm_device_t *dev,
+-				   drm_r128_blit_t *blit )
++static int r128_cce_dispatch_blit(DRMFILE filp,
++				  drm_device_t * dev, drm_r128_blit_t * blit)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_device_dma_t *dma = dev->dma;
+@@ -799,13 +785,13 @@ static int r128_cce_dispatch_blit( DRMFI
+ 	u32 *data;
+ 	int dword_shift, dwords;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	/* The compiler won't optimize away a division by a variable,
+ 	 * even if the only legal values are powers of two.  Thus, we'll
+ 	 * use a shift instead.
+ 	 */
+-	switch ( blit->format ) {
++	switch (blit->format) {
+ 	case R128_DATATYPE_ARGB8888:
+ 		dword_shift = 0;
+ 		break;
+@@ -821,7 +807,7 @@ static int r128_cce_dispatch_blit( DRMFI
+ 		dword_shift = 2;
+ 		break;
+ 	default:
+-		DRM_ERROR( "invalid blit format %d\n", blit->format );
++		DRM_ERROR("invalid blit format %d\n", blit->format);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -830,10 +816,10 @@ static int r128_cce_dispatch_blit( DRMFI
+ 	 * data from the host data blit, otherwise part of the texture
+ 	 * image may be corrupted.
+ 	 */
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 
+-	OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
+-	OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI );
++	OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));
++	OUT_RING(R128_PC_RI_GUI | R128_PC_FLUSH_GUI);
+ 
+ 	ADVANCE_RING();
+ 
+@@ -842,13 +828,13 @@ static int r128_cce_dispatch_blit( DRMFI
+ 	buf = dma->buflist[blit->idx];
+ 	buf_priv = buf->dev_private;
+ 
+-	if ( buf->filp != filp ) {
+-		DRM_ERROR( "process %d using buffer owned by %p\n",
+-			   DRM_CURRENTPID, buf->filp );
++	if (buf->filp != filp) {
++		DRM_ERROR("process %d using buffer owned by %p\n",
++			  DRM_CURRENTPID, buf->filp);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( buf->pending ) {
+-		DRM_ERROR( "sending pending buffer %d\n", blit->idx );
++	if (buf->pending) {
++		DRM_ERROR("sending pending buffer %d\n", blit->idx);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -856,45 +842,43 @@ static int r128_cce_dispatch_blit( DRMFI
+ 
+ 	dwords = (blit->width * blit->height) >> dword_shift;
+ 
+-	data = (u32 *)((char *)dev->agp_buffer_map->handle + buf->offset);
++	data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
+ 
+-	data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) );
+-	data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL |
+-				R128_GMC_BRUSH_NONE |
+-				(blit->format << 8) |
+-				R128_GMC_SRC_DATATYPE_COLOR |
+-				R128_ROP3_S |
+-				R128_DP_SRC_SOURCE_HOST_DATA |
+-				R128_GMC_CLR_CMP_CNTL_DIS |
+-				R128_GMC_AUX_CLIP_DIS |
+-				R128_GMC_WR_MSK_DIS) );
+-
+-	data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) );
+-	data[3] = cpu_to_le32( 0xffffffff );
+-	data[4] = cpu_to_le32( 0xffffffff );
+-	data[5] = cpu_to_le32( (blit->y << 16) | blit->x );
+-	data[6] = cpu_to_le32( (blit->height << 16) | blit->width );
+-	data[7] = cpu_to_le32( dwords );
++	data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6));
++	data[1] = cpu_to_le32((R128_GMC_DST_PITCH_OFFSET_CNTL |
++			       R128_GMC_BRUSH_NONE |
++			       (blit->format << 8) |
++			       R128_GMC_SRC_DATATYPE_COLOR |
++			       R128_ROP3_S |
++			       R128_DP_SRC_SOURCE_HOST_DATA |
++			       R128_GMC_CLR_CMP_CNTL_DIS |
++			       R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS));
++
++	data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5));
++	data[3] = cpu_to_le32(0xffffffff);
++	data[4] = cpu_to_le32(0xffffffff);
++	data[5] = cpu_to_le32((blit->y << 16) | blit->x);
++	data[6] = cpu_to_le32((blit->height << 16) | blit->width);
++	data[7] = cpu_to_le32(dwords);
+ 
+ 	buf->used = (dwords + 8) * sizeof(u32);
+ 
+-	r128_cce_dispatch_indirect( dev, buf, 0, buf->used );
++	r128_cce_dispatch_indirect(dev, buf, 0, buf->used);
+ 
+ 	/* Flush the pixel cache after the blit completes.  This ensures
+ 	 * the texture data is written out to memory before rendering
+ 	 * continues.
+ 	 */
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 
+-	OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
+-	OUT_RING( R128_PC_FLUSH_GUI );
++	OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));
++	OUT_RING(R128_PC_FLUSH_GUI);
+ 
+ 	ADVANCE_RING();
+ 
+ 	return 0;
+ }
+ 
+-
+ /* ================================================================
+  * Tiled depth buffer management
+  *
+@@ -902,8 +886,8 @@ static int r128_cce_dispatch_blit( DRMFI
+  * have hardware stencil support.
+  */
+ 
+-static int r128_cce_dispatch_write_span( drm_device_t *dev,
+-					 drm_r128_depth_t *depth )
++static int r128_cce_dispatch_write_span(drm_device_t * dev,
++					drm_r128_depth_t * depth)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	int count, x, y;
+@@ -911,95 +895,95 @@ static int r128_cce_dispatch_write_span(
+ 	u8 *mask;
+ 	int i, buffer_size, mask_size;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	count = depth->n;
+ 	if (count > 4096 || count <= 0)
+ 		return DRM_ERR(EMSGSIZE);
+ 
+-	if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
++	if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {
+ 		return DRM_ERR(EFAULT);
+ 	}
+-	if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
++	if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {
+ 		return DRM_ERR(EFAULT);
+ 	}
+ 
+ 	buffer_size = depth->n * sizeof(u32);
+-	buffer = drm_alloc( buffer_size, DRM_MEM_BUFS );
+-	if ( buffer == NULL )
++	buffer = drm_alloc(buffer_size, DRM_MEM_BUFS);
++	if (buffer == NULL)
+ 		return DRM_ERR(ENOMEM);
+-	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
+-		drm_free( buffer, buffer_size, DRM_MEM_BUFS);
++	if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {
++		drm_free(buffer, buffer_size, DRM_MEM_BUFS);
+ 		return DRM_ERR(EFAULT);
+ 	}
+ 
+ 	mask_size = depth->n * sizeof(u8);
+-	if ( depth->mask ) {
+-		mask = drm_alloc( mask_size, DRM_MEM_BUFS );
+-		if ( mask == NULL ) {
+-			drm_free( buffer, buffer_size, DRM_MEM_BUFS );
++	if (depth->mask) {
++		mask = drm_alloc(mask_size, DRM_MEM_BUFS);
++		if (mask == NULL) {
++			drm_free(buffer, buffer_size, DRM_MEM_BUFS);
+ 			return DRM_ERR(ENOMEM);
+ 		}
+-		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
+-			drm_free( buffer, buffer_size, DRM_MEM_BUFS );
+-			drm_free( mask, mask_size, DRM_MEM_BUFS );
++		if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {
++			drm_free(buffer, buffer_size, DRM_MEM_BUFS);
++			drm_free(mask, mask_size, DRM_MEM_BUFS);
+ 			return DRM_ERR(EFAULT);
+ 		}
+ 
+-		for ( i = 0 ; i < count ; i++, x++ ) {
+-			if ( mask[i] ) {
+-				BEGIN_RING( 6 );
+-
+-				OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+-				OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+-					  R128_GMC_BRUSH_SOLID_COLOR |
+-					  (dev_priv->depth_fmt << 8) |
+-					  R128_GMC_SRC_DATATYPE_COLOR |
+-					  R128_ROP3_P |
+-					  R128_GMC_CLR_CMP_CNTL_DIS |
+-					  R128_GMC_WR_MSK_DIS );
++		for (i = 0; i < count; i++, x++) {
++			if (mask[i]) {
++				BEGIN_RING(6);
++
++				OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
++				OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
++					 R128_GMC_BRUSH_SOLID_COLOR |
++					 (dev_priv->depth_fmt << 8) |
++					 R128_GMC_SRC_DATATYPE_COLOR |
++					 R128_ROP3_P |
++					 R128_GMC_CLR_CMP_CNTL_DIS |
++					 R128_GMC_WR_MSK_DIS);
+ 
+-				OUT_RING( dev_priv->depth_pitch_offset_c );
+-				OUT_RING( buffer[i] );
++				OUT_RING(dev_priv->depth_pitch_offset_c);
++				OUT_RING(buffer[i]);
+ 
+-				OUT_RING( (x << 16) | y );
+-				OUT_RING( (1 << 16) | 1 );
++				OUT_RING((x << 16) | y);
++				OUT_RING((1 << 16) | 1);
+ 
+ 				ADVANCE_RING();
+ 			}
+ 		}
+ 
+-		drm_free( mask, mask_size, DRM_MEM_BUFS );
++		drm_free(mask, mask_size, DRM_MEM_BUFS);
+ 	} else {
+-		for ( i = 0 ; i < count ; i++, x++ ) {
+-			BEGIN_RING( 6 );
++		for (i = 0; i < count; i++, x++) {
++			BEGIN_RING(6);
+ 
+-			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+-				  R128_GMC_BRUSH_SOLID_COLOR |
+-				  (dev_priv->depth_fmt << 8) |
+-				  R128_GMC_SRC_DATATYPE_COLOR |
+-				  R128_ROP3_P |
+-				  R128_GMC_CLR_CMP_CNTL_DIS |
+-				  R128_GMC_WR_MSK_DIS );
++			OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
++			OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
++				 R128_GMC_BRUSH_SOLID_COLOR |
++				 (dev_priv->depth_fmt << 8) |
++				 R128_GMC_SRC_DATATYPE_COLOR |
++				 R128_ROP3_P |
++				 R128_GMC_CLR_CMP_CNTL_DIS |
++				 R128_GMC_WR_MSK_DIS);
+ 
+-			OUT_RING( dev_priv->depth_pitch_offset_c );
+-			OUT_RING( buffer[i] );
++			OUT_RING(dev_priv->depth_pitch_offset_c);
++			OUT_RING(buffer[i]);
+ 
+-			OUT_RING( (x << 16) | y );
+-			OUT_RING( (1 << 16) | 1 );
++			OUT_RING((x << 16) | y);
++			OUT_RING((1 << 16) | 1);
+ 
+ 			ADVANCE_RING();
+ 		}
+ 	}
+ 
+-	drm_free( buffer, buffer_size, DRM_MEM_BUFS );
++	drm_free(buffer, buffer_size, DRM_MEM_BUFS);
+ 
+ 	return 0;
+ }
+ 
+-static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
+-					   drm_r128_depth_t *depth )
++static int r128_cce_dispatch_write_pixels(drm_device_t * dev,
++					  drm_r128_depth_t * depth)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	int count, *x, *y;
+@@ -1007,7 +991,7 @@ static int r128_cce_dispatch_write_pixel
+ 	u8 *mask;
+ 	int i, xbuf_size, ybuf_size, buffer_size, mask_size;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	count = depth->n;
+ 	if (count > 4096 || count <= 0)
+@@ -1015,270 +999,266 @@ static int r128_cce_dispatch_write_pixel
+ 
+ 	xbuf_size = count * sizeof(*x);
+ 	ybuf_size = count * sizeof(*y);
+-	x = drm_alloc( xbuf_size, DRM_MEM_BUFS );
+-	if ( x == NULL ) {
++	x = drm_alloc(xbuf_size, DRM_MEM_BUFS);
++	if (x == NULL) {
+ 		return DRM_ERR(ENOMEM);
+ 	}
+-	y = drm_alloc( ybuf_size, DRM_MEM_BUFS );
+-	if ( y == NULL ) {
+-		drm_free( x, xbuf_size, DRM_MEM_BUFS );
++	y = drm_alloc(ybuf_size, DRM_MEM_BUFS);
++	if (y == NULL) {
++		drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ 		return DRM_ERR(ENOMEM);
+ 	}
+-	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
+-		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+-		drm_free( y, ybuf_size, DRM_MEM_BUFS );
++	if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) {
++		drm_free(x, xbuf_size, DRM_MEM_BUFS);
++		drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ 		return DRM_ERR(EFAULT);
+ 	}
+-	if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
+-		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+-		drm_free( y, ybuf_size, DRM_MEM_BUFS );
++	if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) {
++		drm_free(x, xbuf_size, DRM_MEM_BUFS);
++		drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ 		return DRM_ERR(EFAULT);
+ 	}
+ 
+ 	buffer_size = depth->n * sizeof(u32);
+-	buffer = drm_alloc( buffer_size, DRM_MEM_BUFS );
+-	if ( buffer == NULL ) {
+-		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+-		drm_free( y, ybuf_size, DRM_MEM_BUFS );
++	buffer = drm_alloc(buffer_size, DRM_MEM_BUFS);
++	if (buffer == NULL) {
++		drm_free(x, xbuf_size, DRM_MEM_BUFS);
++		drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ 		return DRM_ERR(ENOMEM);
+ 	}
+-	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
+-		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+-		drm_free( y, ybuf_size, DRM_MEM_BUFS );
+-		drm_free( buffer, buffer_size, DRM_MEM_BUFS );
++	if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {
++		drm_free(x, xbuf_size, DRM_MEM_BUFS);
++		drm_free(y, ybuf_size, DRM_MEM_BUFS);
++		drm_free(buffer, buffer_size, DRM_MEM_BUFS);
+ 		return DRM_ERR(EFAULT);
+ 	}
+ 
+-	if ( depth->mask ) {
++	if (depth->mask) {
+ 		mask_size = depth->n * sizeof(u8);
+-		mask = drm_alloc( mask_size, DRM_MEM_BUFS );
+-		if ( mask == NULL ) {
+-			drm_free( x, xbuf_size, DRM_MEM_BUFS );
+-			drm_free( y, ybuf_size, DRM_MEM_BUFS );
+-			drm_free( buffer, buffer_size, DRM_MEM_BUFS );
++		mask = drm_alloc(mask_size, DRM_MEM_BUFS);
++		if (mask == NULL) {
++			drm_free(x, xbuf_size, DRM_MEM_BUFS);
++			drm_free(y, ybuf_size, DRM_MEM_BUFS);
++			drm_free(buffer, buffer_size, DRM_MEM_BUFS);
+ 			return DRM_ERR(ENOMEM);
+ 		}
+-		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
+-			drm_free( x, xbuf_size, DRM_MEM_BUFS  );
+-			drm_free( y, ybuf_size, DRM_MEM_BUFS  );
+-			drm_free( buffer, buffer_size, DRM_MEM_BUFS  );
+-			drm_free( mask, mask_size, DRM_MEM_BUFS  );
++		if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {
++			drm_free(x, xbuf_size, DRM_MEM_BUFS);
++			drm_free(y, ybuf_size, DRM_MEM_BUFS);
++			drm_free(buffer, buffer_size, DRM_MEM_BUFS);
++			drm_free(mask, mask_size, DRM_MEM_BUFS);
+ 			return DRM_ERR(EFAULT);
+ 		}
+ 
+-		for ( i = 0 ; i < count ; i++ ) {
+-			if ( mask[i] ) {
+-				BEGIN_RING( 6 );
+-
+-				OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+-				OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+-					  R128_GMC_BRUSH_SOLID_COLOR |
+-					  (dev_priv->depth_fmt << 8) |
+-					  R128_GMC_SRC_DATATYPE_COLOR |
+-					  R128_ROP3_P |
+-					  R128_GMC_CLR_CMP_CNTL_DIS |
+-					  R128_GMC_WR_MSK_DIS );
++		for (i = 0; i < count; i++) {
++			if (mask[i]) {
++				BEGIN_RING(6);
++
++				OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
++				OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
++					 R128_GMC_BRUSH_SOLID_COLOR |
++					 (dev_priv->depth_fmt << 8) |
++					 R128_GMC_SRC_DATATYPE_COLOR |
++					 R128_ROP3_P |
++					 R128_GMC_CLR_CMP_CNTL_DIS |
++					 R128_GMC_WR_MSK_DIS);
+ 
+-				OUT_RING( dev_priv->depth_pitch_offset_c );
+-				OUT_RING( buffer[i] );
++				OUT_RING(dev_priv->depth_pitch_offset_c);
++				OUT_RING(buffer[i]);
+ 
+-				OUT_RING( (x[i] << 16) | y[i] );
+-				OUT_RING( (1 << 16) | 1 );
++				OUT_RING((x[i] << 16) | y[i]);
++				OUT_RING((1 << 16) | 1);
+ 
+ 				ADVANCE_RING();
+ 			}
+ 		}
+ 
+-		drm_free( mask, mask_size, DRM_MEM_BUFS );
++		drm_free(mask, mask_size, DRM_MEM_BUFS);
+ 	} else {
+-		for ( i = 0 ; i < count ; i++ ) {
+-			BEGIN_RING( 6 );
++		for (i = 0; i < count; i++) {
++			BEGIN_RING(6);
+ 
+-			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+-				  R128_GMC_BRUSH_SOLID_COLOR |
+-				  (dev_priv->depth_fmt << 8) |
+-				  R128_GMC_SRC_DATATYPE_COLOR |
+-				  R128_ROP3_P |
+-				  R128_GMC_CLR_CMP_CNTL_DIS |
+-				  R128_GMC_WR_MSK_DIS );
++			OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
++			OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
++				 R128_GMC_BRUSH_SOLID_COLOR |
++				 (dev_priv->depth_fmt << 8) |
++				 R128_GMC_SRC_DATATYPE_COLOR |
++				 R128_ROP3_P |
++				 R128_GMC_CLR_CMP_CNTL_DIS |
++				 R128_GMC_WR_MSK_DIS);
+ 
+-			OUT_RING( dev_priv->depth_pitch_offset_c );
+-			OUT_RING( buffer[i] );
++			OUT_RING(dev_priv->depth_pitch_offset_c);
++			OUT_RING(buffer[i]);
+ 
+-			OUT_RING( (x[i] << 16) | y[i] );
+-			OUT_RING( (1 << 16) | 1 );
++			OUT_RING((x[i] << 16) | y[i]);
++			OUT_RING((1 << 16) | 1);
+ 
+ 			ADVANCE_RING();
+ 		}
+ 	}
+ 
+-	drm_free( x, xbuf_size, DRM_MEM_BUFS );
+-	drm_free( y, ybuf_size, DRM_MEM_BUFS );
+-	drm_free( buffer, buffer_size, DRM_MEM_BUFS );
++	drm_free(x, xbuf_size, DRM_MEM_BUFS);
++	drm_free(y, ybuf_size, DRM_MEM_BUFS);
++	drm_free(buffer, buffer_size, DRM_MEM_BUFS);
+ 
+ 	return 0;
+ }
+ 
+-static int r128_cce_dispatch_read_span( drm_device_t *dev,
+-					drm_r128_depth_t *depth )
++static int r128_cce_dispatch_read_span(drm_device_t * dev,
++				       drm_r128_depth_t * depth)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	int count, x, y;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	count = depth->n;
+ 	if (count > 4096 || count <= 0)
+ 		return DRM_ERR(EMSGSIZE);
+ 
+-	if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
++	if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {
+ 		return DRM_ERR(EFAULT);
+ 	}
+-	if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
++	if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {
+ 		return DRM_ERR(EFAULT);
+ 	}
+ 
+-	BEGIN_RING( 7 );
++	BEGIN_RING(7);
+ 
+-	OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
+-	OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+-		  R128_GMC_DST_PITCH_OFFSET_CNTL |
+-		  R128_GMC_BRUSH_NONE |
+-		  (dev_priv->depth_fmt << 8) |
+-		  R128_GMC_SRC_DATATYPE_COLOR |
+-		  R128_ROP3_S |
+-		  R128_DP_SRC_SOURCE_MEMORY |
+-		  R128_GMC_CLR_CMP_CNTL_DIS |
+-		  R128_GMC_WR_MSK_DIS );
+-
+-	OUT_RING( dev_priv->depth_pitch_offset_c );
+-	OUT_RING( dev_priv->span_pitch_offset_c );
+-
+-	OUT_RING( (x << 16) | y );
+-	OUT_RING( (0 << 16) | 0 );
+-	OUT_RING( (count << 16) | 1 );
++	OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
++	OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
++		 R128_GMC_DST_PITCH_OFFSET_CNTL |
++		 R128_GMC_BRUSH_NONE |
++		 (dev_priv->depth_fmt << 8) |
++		 R128_GMC_SRC_DATATYPE_COLOR |
++		 R128_ROP3_S |
++		 R128_DP_SRC_SOURCE_MEMORY |
++		 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS);
++
++	OUT_RING(dev_priv->depth_pitch_offset_c);
++	OUT_RING(dev_priv->span_pitch_offset_c);
++
++	OUT_RING((x << 16) | y);
++	OUT_RING((0 << 16) | 0);
++	OUT_RING((count << 16) | 1);
+ 
+ 	ADVANCE_RING();
+ 
+ 	return 0;
+ }
+ 
+-static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
+-					  drm_r128_depth_t *depth )
++static int r128_cce_dispatch_read_pixels(drm_device_t * dev,
++					 drm_r128_depth_t * depth)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	int count, *x, *y;
+ 	int i, xbuf_size, ybuf_size;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "%s\n", __FUNCTION__ );
++	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+ 	count = depth->n;
+ 	if (count > 4096 || count <= 0)
+ 		return DRM_ERR(EMSGSIZE);
+ 
+-	if ( count > dev_priv->depth_pitch ) {
++	if (count > dev_priv->depth_pitch) {
+ 		count = dev_priv->depth_pitch;
+ 	}
+ 
+ 	xbuf_size = count * sizeof(*x);
+ 	ybuf_size = count * sizeof(*y);
+-	x = drm_alloc( xbuf_size, DRM_MEM_BUFS );
+-	if ( x == NULL ) {
++	x = drm_alloc(xbuf_size, DRM_MEM_BUFS);
++	if (x == NULL) {
+ 		return DRM_ERR(ENOMEM);
+ 	}
+-	y = drm_alloc( ybuf_size, DRM_MEM_BUFS );
+-	if ( y == NULL ) {
+-		drm_free( x, xbuf_size, DRM_MEM_BUFS );
++	y = drm_alloc(ybuf_size, DRM_MEM_BUFS);
++	if (y == NULL) {
++		drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ 		return DRM_ERR(ENOMEM);
+ 	}
+-	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
+-		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+-		drm_free( y, ybuf_size, DRM_MEM_BUFS );
++	if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) {
++		drm_free(x, xbuf_size, DRM_MEM_BUFS);
++		drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ 		return DRM_ERR(EFAULT);
+ 	}
+-	if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
+-		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+-		drm_free( y, ybuf_size, DRM_MEM_BUFS );
++	if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) {
++		drm_free(x, xbuf_size, DRM_MEM_BUFS);
++		drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ 		return DRM_ERR(EFAULT);
+ 	}
+ 
+-	for ( i = 0 ; i < count ; i++ ) {
+-		BEGIN_RING( 7 );
++	for (i = 0; i < count; i++) {
++		BEGIN_RING(7);
+ 
+-		OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
+-		OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+-			  R128_GMC_DST_PITCH_OFFSET_CNTL |
+-			  R128_GMC_BRUSH_NONE |
+-			  (dev_priv->depth_fmt << 8) |
+-			  R128_GMC_SRC_DATATYPE_COLOR |
+-			  R128_ROP3_S |
+-			  R128_DP_SRC_SOURCE_MEMORY |
+-			  R128_GMC_CLR_CMP_CNTL_DIS |
+-			  R128_GMC_WR_MSK_DIS );
+-
+-		OUT_RING( dev_priv->depth_pitch_offset_c );
+-		OUT_RING( dev_priv->span_pitch_offset_c );
+-
+-		OUT_RING( (x[i] << 16) | y[i] );
+-		OUT_RING( (i << 16) | 0 );
+-		OUT_RING( (1 << 16) | 1 );
++		OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
++		OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
++			 R128_GMC_DST_PITCH_OFFSET_CNTL |
++			 R128_GMC_BRUSH_NONE |
++			 (dev_priv->depth_fmt << 8) |
++			 R128_GMC_SRC_DATATYPE_COLOR |
++			 R128_ROP3_S |
++			 R128_DP_SRC_SOURCE_MEMORY |
++			 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS);
++
++		OUT_RING(dev_priv->depth_pitch_offset_c);
++		OUT_RING(dev_priv->span_pitch_offset_c);
++
++		OUT_RING((x[i] << 16) | y[i]);
++		OUT_RING((i << 16) | 0);
++		OUT_RING((1 << 16) | 1);
+ 
+ 		ADVANCE_RING();
+ 	}
+ 
+-	drm_free( x, xbuf_size, DRM_MEM_BUFS );
+-	drm_free( y, ybuf_size, DRM_MEM_BUFS );
++	drm_free(x, xbuf_size, DRM_MEM_BUFS);
++	drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ 
+ 	return 0;
+ }
+ 
+-
+ /* ================================================================
+  * Polygon stipple
+  */
+ 
+-static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple )
++static void r128_cce_dispatch_stipple(drm_device_t * dev, u32 * stipple)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	int i;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "%s\n", __FUNCTION__ );
++	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+-	BEGIN_RING( 33 );
++	BEGIN_RING(33);
+ 
+-	OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
+-	for ( i = 0 ; i < 32 ; i++ ) {
+-		OUT_RING( stipple[i] );
++	OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31));
++	for (i = 0; i < 32; i++) {
++		OUT_RING(stipple[i]);
+ 	}
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-
+ /* ================================================================
+  * IOCTL functions
+  */
+ 
+-static int r128_cce_clear( DRM_IOCTL_ARGS )
++static int r128_cce_clear(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_r128_clear_t clear;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t __user *) data,
+-			     sizeof(clear) );
++	DRM_COPY_FROM_USER_IOCTL(clear, (drm_r128_clear_t __user *) data,
++				 sizeof(clear));
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+-	if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
++	if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
+ 		sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
+ 
+-	r128_cce_dispatch_clear( dev, &clear );
++	r128_cce_dispatch_clear(dev, &clear);
+ 	COMMIT_RING();
+ 
+ 	/* Make sure we restore the 3D state next time.
+@@ -1288,17 +1268,17 @@ static int r128_cce_clear( DRM_IOCTL_ARG
+ 	return 0;
+ }
+ 
+-static int r128_do_init_pageflip( drm_device_t *dev )
++static int r128_do_init_pageflip(drm_device_t * dev)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	dev_priv->crtc_offset =      R128_READ( R128_CRTC_OFFSET );
+-	dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
++	dev_priv->crtc_offset = R128_READ(R128_CRTC_OFFSET);
++	dev_priv->crtc_offset_cntl = R128_READ(R128_CRTC_OFFSET_CNTL);
+ 
+-	R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
+-	R128_WRITE( R128_CRTC_OFFSET_CNTL,
+-		    dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
++	R128_WRITE(R128_CRTC_OFFSET, dev_priv->front_offset);
++	R128_WRITE(R128_CRTC_OFFSET_CNTL,
++		   dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL);
+ 
+ 	dev_priv->page_flipping = 1;
+ 	dev_priv->current_page = 0;
+@@ -1307,16 +1287,16 @@ static int r128_do_init_pageflip( drm_de
+ 	return 0;
+ }
+ 
+-static int r128_do_cleanup_pageflip( drm_device_t *dev )
++static int r128_do_cleanup_pageflip(drm_device_t * dev)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	R128_WRITE( R128_CRTC_OFFSET,      dev_priv->crtc_offset );
+-	R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
++	R128_WRITE(R128_CRTC_OFFSET, dev_priv->crtc_offset);
++	R128_WRITE(R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl);
+ 
+ 	if (dev_priv->current_page != 0) {
+-		r128_cce_dispatch_flip( dev );
++		r128_cce_dispatch_flip(dev);
+ 		COMMIT_RING();
+ 	}
+ 
+@@ -1325,43 +1305,43 @@ static int r128_do_cleanup_pageflip( drm
+ }
+ 
+ /* Swapping and flipping are different operations, need different ioctls.
+- * They can & should be intermixed to support multiple 3d windows.  
++ * They can & should be intermixed to support multiple 3d windows.
+  */
+ 
+-static int r128_cce_flip( DRM_IOCTL_ARGS )
++static int r128_cce_flip(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "%s\n", __FUNCTION__ );
++	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+-	if (!dev_priv->page_flipping) 
+-		r128_do_init_pageflip( dev );
++	if (!dev_priv->page_flipping)
++		r128_do_init_pageflip(dev);
+ 
+-	r128_cce_dispatch_flip( dev );
++	r128_cce_dispatch_flip(dev);
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int r128_cce_swap( DRM_IOCTL_ARGS )
++static int r128_cce_swap(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+-	DRM_DEBUG( "%s\n", __FUNCTION__ );
++	DRM_DEBUG("%s\n", __FUNCTION__);
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+-	if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
++	if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
+ 		sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
+ 
+-	r128_cce_dispatch_swap( dev );
++	r128_cce_dispatch_swap(dev);
+ 	dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
+ 					R128_UPLOAD_MASKS);
+ 
+@@ -1369,7 +1349,7 @@ static int r128_cce_swap( DRM_IOCTL_ARGS
+ 	return 0;
+ }
+ 
+-static int r128_cce_vertex( DRM_IOCTL_ARGS )
++static int r128_cce_vertex(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+@@ -1378,44 +1358,43 @@ static int r128_cce_vertex( DRM_IOCTL_AR
+ 	drm_r128_buf_priv_t *buf_priv;
+ 	drm_r128_vertex_t vertex;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( vertex, (drm_r128_vertex_t __user *) data,
+-			     sizeof(vertex) );
++	DRM_COPY_FROM_USER_IOCTL(vertex, (drm_r128_vertex_t __user *) data,
++				 sizeof(vertex));
+ 
+-	DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
+-		   DRM_CURRENTPID,
+-		   vertex.idx, vertex.count, vertex.discard );
++	DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
++		  DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard);
+ 
+-	if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
+-		DRM_ERROR( "buffer index %d (of %d max)\n",
+-			   vertex.idx, dma->buf_count - 1 );
++	if (vertex.idx < 0 || vertex.idx >= dma->buf_count) {
++		DRM_ERROR("buffer index %d (of %d max)\n",
++			  vertex.idx, dma->buf_count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( vertex.prim < 0 ||
+-	     vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
+-		DRM_ERROR( "buffer prim %d\n", vertex.prim );
++	if (vertex.prim < 0 ||
++	    vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) {
++		DRM_ERROR("buffer prim %d\n", vertex.prim);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	buf = dma->buflist[vertex.idx];
+ 	buf_priv = buf->dev_private;
+ 
+-	if ( buf->filp != filp ) {
+-		DRM_ERROR( "process %d using buffer owned by %p\n",
+-			   DRM_CURRENTPID, buf->filp );
++	if (buf->filp != filp) {
++		DRM_ERROR("process %d using buffer owned by %p\n",
++			  DRM_CURRENTPID, buf->filp);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( buf->pending ) {
+-		DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
++	if (buf->pending) {
++		DRM_ERROR("sending pending buffer %d\n", vertex.idx);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -1423,13 +1402,13 @@ static int r128_cce_vertex( DRM_IOCTL_AR
+ 	buf_priv->prim = vertex.prim;
+ 	buf_priv->discard = vertex.discard;
+ 
+-	r128_cce_dispatch_vertex( dev, buf );
++	r128_cce_dispatch_vertex(dev, buf);
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int r128_cce_indices( DRM_IOCTL_ARGS )
++static int r128_cce_indices(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+@@ -1439,55 +1418,54 @@ static int r128_cce_indices( DRM_IOCTL_A
+ 	drm_r128_indices_t elts;
+ 	int count;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( elts, (drm_r128_indices_t __user *) data,
+-			     sizeof(elts) );
++	DRM_COPY_FROM_USER_IOCTL(elts, (drm_r128_indices_t __user *) data,
++				 sizeof(elts));
+ 
+-	DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
+-		   elts.idx, elts.start, elts.end, elts.discard );
++	DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
++		  elts.idx, elts.start, elts.end, elts.discard);
+ 
+-	if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
+-		DRM_ERROR( "buffer index %d (of %d max)\n",
+-			   elts.idx, dma->buf_count - 1 );
++	if (elts.idx < 0 || elts.idx >= dma->buf_count) {
++		DRM_ERROR("buffer index %d (of %d max)\n",
++			  elts.idx, dma->buf_count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( elts.prim < 0 ||
+-	     elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
+-		DRM_ERROR( "buffer prim %d\n", elts.prim );
++	if (elts.prim < 0 || elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) {
++		DRM_ERROR("buffer prim %d\n", elts.prim);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	buf = dma->buflist[elts.idx];
+ 	buf_priv = buf->dev_private;
+ 
+-	if ( buf->filp != filp ) {
+-		DRM_ERROR( "process %d using buffer owned by %p\n",
+-			   DRM_CURRENTPID, buf->filp );
++	if (buf->filp != filp) {
++		DRM_ERROR("process %d using buffer owned by %p\n",
++			  DRM_CURRENTPID, buf->filp);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( buf->pending ) {
+-		DRM_ERROR( "sending pending buffer %d\n", elts.idx );
++	if (buf->pending) {
++		DRM_ERROR("sending pending buffer %d\n", elts.idx);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	count = (elts.end - elts.start) / sizeof(u16);
+ 	elts.start -= R128_INDEX_PRIM_OFFSET;
+ 
+-	if ( elts.start & 0x7 ) {
+-		DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
++	if (elts.start & 0x7) {
++		DRM_ERROR("misaligned buffer 0x%x\n", elts.start);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( elts.start < buf->used ) {
+-		DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
++	if (elts.start < buf->used) {
++		DRM_ERROR("no header 0x%x - 0x%x\n", elts.start, buf->used);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -1495,13 +1473,13 @@ static int r128_cce_indices( DRM_IOCTL_A
+ 	buf_priv->prim = elts.prim;
+ 	buf_priv->discard = elts.discard;
+ 
+-	r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count );
++	r128_cce_dispatch_indices(dev, buf, elts.start, elts.end, count);
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int r128_cce_blit( DRM_IOCTL_ARGS )
++static int r128_cce_blit(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_device_dma_t *dma = dev->dma;
+@@ -1509,55 +1487,55 @@ static int r128_cce_blit( DRM_IOCTL_ARGS
+ 	drm_r128_blit_t blit;
+ 	int ret;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t __user *) data,
+-			     sizeof(blit) );
++	DRM_COPY_FROM_USER_IOCTL(blit, (drm_r128_blit_t __user *) data,
++				 sizeof(blit));
+ 
+-	DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID, blit.idx );
++	DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit.idx);
+ 
+-	if ( blit.idx < 0 || blit.idx >= dma->buf_count ) {
+-		DRM_ERROR( "buffer index %d (of %d max)\n",
+-			   blit.idx, dma->buf_count - 1 );
++	if (blit.idx < 0 || blit.idx >= dma->buf_count) {
++		DRM_ERROR("buffer index %d (of %d max)\n",
++			  blit.idx, dma->buf_count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+-	ret = r128_cce_dispatch_blit( filp, dev, &blit );
++	ret = r128_cce_dispatch_blit(filp, dev, &blit);
+ 
+ 	COMMIT_RING();
+ 	return ret;
+ }
+ 
+-static int r128_cce_depth( DRM_IOCTL_ARGS )
++static int r128_cce_depth(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_depth_t depth;
+ 	int ret;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t __user *) data,
+-			     sizeof(depth) );
++	DRM_COPY_FROM_USER_IOCTL(depth, (drm_r128_depth_t __user *) data,
++				 sizeof(depth));
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	ret = DRM_ERR(EINVAL);
+-	switch ( depth.func ) {
++	switch (depth.func) {
+ 	case R128_WRITE_SPAN:
+-		ret = r128_cce_dispatch_write_span( dev, &depth );
++		ret = r128_cce_dispatch_write_span(dev, &depth);
+ 		break;
+ 	case R128_WRITE_PIXELS:
+-		ret = r128_cce_dispatch_write_pixels( dev, &depth );
++		ret = r128_cce_dispatch_write_pixels(dev, &depth);
+ 		break;
+ 	case R128_READ_SPAN:
+-		ret = r128_cce_dispatch_read_span( dev, &depth );
++		ret = r128_cce_dispatch_read_span(dev, &depth);
+ 		break;
+ 	case R128_READ_PIXELS:
+-		ret = r128_cce_dispatch_read_pixels( dev, &depth );
++		ret = r128_cce_dispatch_read_pixels(dev, &depth);
+ 		break;
+ 	}
+ 
+@@ -1565,31 +1543,30 @@ static int r128_cce_depth( DRM_IOCTL_ARG
+ 	return ret;
+ }
+ 
+-static int r128_cce_stipple( DRM_IOCTL_ARGS )
++static int r128_cce_stipple(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_stipple_t stipple;
+ 	u32 mask[32];
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t __user *) data,
+-			     sizeof(stipple) );
++	DRM_COPY_FROM_USER_IOCTL(stipple, (drm_r128_stipple_t __user *) data,
++				 sizeof(stipple));
+ 
+-	if ( DRM_COPY_FROM_USER( &mask, stipple.mask,
+-			     32 * sizeof(u32) ) )
+-		return DRM_ERR( EFAULT );
++	if (DRM_COPY_FROM_USER(&mask, stipple.mask, 32 * sizeof(u32)))
++		return DRM_ERR(EFAULT);
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+-	r128_cce_dispatch_stipple( dev, mask );
++	r128_cce_dispatch_stipple(dev, mask);
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int r128_cce_indirect( DRM_IOCTL_ARGS )
++static int r128_cce_indirect(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+@@ -1601,47 +1578,46 @@ static int r128_cce_indirect( DRM_IOCTL_
+ 	RING_LOCALS;
+ #endif
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( indirect, (drm_r128_indirect_t __user *) data,
+-			     sizeof(indirect) );
++	DRM_COPY_FROM_USER_IOCTL(indirect, (drm_r128_indirect_t __user *) data,
++				 sizeof(indirect));
+ 
+-	DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
+-		   indirect.idx, indirect.start,
+-		   indirect.end, indirect.discard );
++	DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
++		  indirect.idx, indirect.start, indirect.end, indirect.discard);
+ 
+-	if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
+-		DRM_ERROR( "buffer index %d (of %d max)\n",
+-			   indirect.idx, dma->buf_count - 1 );
++	if (indirect.idx < 0 || indirect.idx >= dma->buf_count) {
++		DRM_ERROR("buffer index %d (of %d max)\n",
++			  indirect.idx, dma->buf_count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	buf = dma->buflist[indirect.idx];
+ 	buf_priv = buf->dev_private;
+ 
+-	if ( buf->filp != filp ) {
+-		DRM_ERROR( "process %d using buffer owned by %p\n",
+-			   DRM_CURRENTPID, buf->filp );
++	if (buf->filp != filp) {
++		DRM_ERROR("process %d using buffer owned by %p\n",
++			  DRM_CURRENTPID, buf->filp);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( buf->pending ) {
+-		DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
++	if (buf->pending) {
++		DRM_ERROR("sending pending buffer %d\n", indirect.idx);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( indirect.start < buf->used ) {
+-		DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
+-			   indirect.start, buf->used );
++	if (indirect.start < buf->used) {
++		DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
++			  indirect.start, buf->used);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	buf->used = indirect.end;
+ 	buf_priv->discard = indirect.discard;
+@@ -1650,7 +1626,7 @@ static int r128_cce_indirect( DRM_IOCTL_
+ 	/* Wait for the 3D stream to idle before the indirect buffer
+ 	 * containing 2D acceleration commands is processed.
+ 	 */
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 	RADEON_WAIT_UNTIL_3D_IDLE();
+ 	ADVANCE_RING();
+ #endif
+@@ -1659,30 +1635,30 @@ static int r128_cce_indirect( DRM_IOCTL_
+ 	 * X server.  This is insecure and is thus only available to
+ 	 * privileged clients.
+ 	 */
+-	r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end );
++	r128_cce_dispatch_indirect(dev, buf, indirect.start, indirect.end);
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int r128_getparam( DRM_IOCTL_ARGS )
++static int r128_getparam(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+ 	drm_r128_getparam_t param;
+ 	int value;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( param, (drm_r128_getparam_t __user *)data,
+-			     sizeof(param) );
++	DRM_COPY_FROM_USER_IOCTL(param, (drm_r128_getparam_t __user *) data,
++				 sizeof(param));
+ 
+-	DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
++	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
+ 
+-	switch( param.param ) {
++	switch (param.param) {
+ 	case R128_PARAM_IRQ_NR:
+ 		value = dev->irq;
+ 		break;
+@@ -1690,47 +1666,47 @@ static int r128_getparam( DRM_IOCTL_ARGS
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
+-		DRM_ERROR( "copy_to_user\n" );
++	if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) {
++		DRM_ERROR("copy_to_user\n");
+ 		return DRM_ERR(EFAULT);
+ 	}
+-	
++
+ 	return 0;
+ }
+ 
+-void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp)
++void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+ {
+-	if ( dev->dev_private ) {
++	if (dev->dev_private) {
+ 		drm_r128_private_t *dev_priv = dev->dev_private;
+-		if ( dev_priv->page_flipping ) {
+-			r128_do_cleanup_pageflip( dev );
++		if (dev_priv->page_flipping) {
++			r128_do_cleanup_pageflip(dev);
+ 		}
+-	}			
++	}
+ }
+ 
+-void r128_driver_pretakedown(drm_device_t *dev)
++void r128_driver_pretakedown(drm_device_t * dev)
+ {
+-	r128_do_cleanup_cce( dev );
++	r128_do_cleanup_cce(dev);
+ }
+ 
+ drm_ioctl_desc_t r128_ioctls[] = {
+-	[DRM_IOCTL_NR(DRM_R128_INIT)]       = { r128_cce_init,     1, 1 },
+-	[DRM_IOCTL_NR(DRM_R128_CCE_START)]  = { r128_cce_start,    1, 1 },
+-	[DRM_IOCTL_NR(DRM_R128_CCE_STOP)]   = { r128_cce_stop,     1, 1 },
+-	[DRM_IOCTL_NR(DRM_R128_CCE_RESET)]  = { r128_cce_reset,    1, 1 },
+-	[DRM_IOCTL_NR(DRM_R128_CCE_IDLE)]   = { r128_cce_idle,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_RESET)]      = { r128_engine_reset, 1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = { r128_fullscreen,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_SWAP)]       = { r128_cce_swap,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_FLIP)]       = { r128_cce_flip,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_CLEAR)]      = { r128_cce_clear,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_VERTEX)]     = { r128_cce_vertex,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_INDICES)]    = { r128_cce_indices,  1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_BLIT)]       = { r128_cce_blit,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_DEPTH)]      = { r128_cce_depth,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_STIPPLE)]    = { r128_cce_stipple,  1, 0 },
+-	[DRM_IOCTL_NR(DRM_R128_INDIRECT)]   = { r128_cce_indirect, 1, 1 },
+-	[DRM_IOCTL_NR(DRM_R128_GETPARAM)]   = { r128_getparam, 1, 0 },
++	[DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, 1, 1},
++	[DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, 1, 1},
++	[DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, 1, 1},
++	[DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, 1, 1},
++	[DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, 1, 0},
++	[DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, 1, 1},
++	[DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, 1, 0},
+ };
+ 
+ int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls);
+diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
+--- a/drivers/char/drm/r300_cmdbuf.c
++++ b/drivers/char/drm/r300_cmdbuf.c
+@@ -37,7 +37,6 @@
+ #include "radeon_drv.h"
+ #include "r300_reg.h"
+ 
+-
+ #define R300_SIMULTANEOUS_CLIPRECTS		4
+ 
+ /* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects
+@@ -49,14 +48,12 @@ static const int r300_cliprect_cntl[4] =
+ 	0xFFFE
+ };
+ 
+-
+ /**
+  * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command
+  * buffer, starting with index n.
+  */
+-static int r300_emit_cliprects(drm_radeon_private_t* dev_priv,
+-			       drm_radeon_cmd_buffer_t* cmdbuf,
+-			       int n)
++static int r300_emit_cliprects(drm_radeon_private_t * dev_priv,
++			       drm_radeon_kcmd_buffer_t * cmdbuf, int n)
+ {
+ 	drm_clip_rect_t box;
+ 	int nr;
+@@ -70,38 +67,47 @@ static int r300_emit_cliprects(drm_radeo
+ 	DRM_DEBUG("%i cliprects\n", nr);
+ 
+ 	if (nr) {
+-		BEGIN_RING(6 + nr*2);
+-		OUT_RING( CP_PACKET0( R300_RE_CLIPRECT_TL_0, nr*2 - 1 ) );
++		BEGIN_RING(6 + nr * 2);
++		OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1));
+ 
+-		for(i = 0; i < nr; ++i) {
+-			if (DRM_COPY_FROM_USER_UNCHECKED(&box, &cmdbuf->boxes[n+i], sizeof(box))) {
++		for (i = 0; i < nr; ++i) {
++			if (DRM_COPY_FROM_USER_UNCHECKED
++			    (&box, &cmdbuf->boxes[n + i], sizeof(box))) {
+ 				DRM_ERROR("copy cliprect faulted\n");
+ 				return DRM_ERR(EFAULT);
+ 			}
+ 
+-			box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+-			box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+-			box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+-			box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
++			box.x1 =
++			    (box.x1 +
++			     R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
++			box.y1 =
++			    (box.y1 +
++			     R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
++			box.x2 =
++			    (box.x2 +
++			     R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
++			box.y2 =
++			    (box.y2 +
++			     R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+ 
+ 			OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) |
+-					(box.y1 << R300_CLIPRECT_Y_SHIFT));
++				 (box.y1 << R300_CLIPRECT_Y_SHIFT));
+ 			OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) |
+-					(box.y2 << R300_CLIPRECT_Y_SHIFT));
++				 (box.y2 << R300_CLIPRECT_Y_SHIFT));
+ 		}
+ 
+-		OUT_RING_REG( R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr-1] );
++		OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]);
+ 
+ 		/* TODO/SECURITY: Force scissors to a safe value, otherwise the
+-		* client might be able to trample over memory.
+-		* The impact should be very limited, but I'd rather be safe than
+-		* sorry.
+-		*/
+-		OUT_RING( CP_PACKET0( R300_RE_SCISSORS_TL, 1 ) );
+-		OUT_RING( 0 );
+-		OUT_RING( R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK );
++		 * client might be able to trample over memory.
++		 * The impact should be very limited, but I'd rather be safe than
++		 * sorry.
++		 */
++		OUT_RING(CP_PACKET0(R300_RE_SCISSORS_TL, 1));
++		OUT_RING(0);
++		OUT_RING(R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK);
+ 		ADVANCE_RING();
+-		} else {
++	} else {
+ 		/* Why we allow zero cliprect rendering:
+ 		 * There are some commands in a command buffer that must be submitted
+ 		 * even when there are no cliprects, e.g. DMA buffer discard
+@@ -118,28 +124,27 @@ static int r300_emit_cliprects(drm_radeo
+ 		 * can't produce any fragments.
+ 		 */
+ 		BEGIN_RING(2);
+-		OUT_RING_REG( R300_RE_CLIPRECT_CNTL, 0 );
++		OUT_RING_REG(R300_RE_CLIPRECT_CNTL, 0);
+ 		ADVANCE_RING();
+-		}
++	}
+ 
+ 	return 0;
+ }
+ 
+-u8  r300_reg_flags[0x10000>>2];
+-
++static u8 r300_reg_flags[0x10000 >> 2];
+ 
+ void r300_init_reg_flags(void)
+ {
+ 	int i;
+-	memset(r300_reg_flags, 0, 0x10000>>2);
+-	#define ADD_RANGE_MARK(reg, count,mark) \
++	memset(r300_reg_flags, 0, 0x10000 >> 2);
++#define ADD_RANGE_MARK(reg, count,mark) \
+ 		for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
+ 			r300_reg_flags[i]|=(mark);
+-	
+-	#define MARK_SAFE		1
+-	#define MARK_CHECK_OFFSET	2
+-	
+-	#define ADD_RANGE(reg, count)	ADD_RANGE_MARK(reg, count, MARK_SAFE)
++
++#define MARK_SAFE		1
++#define MARK_CHECK_OFFSET	2
++
++#define ADD_RANGE(reg, count)	ADD_RANGE_MARK(reg, count, MARK_SAFE)
+ 
+ 	/* these match cmducs() command in r300_driver/r300/r300_cmdbuf.c */
+ 	ADD_RANGE(R300_SE_VPORT_XSCALE, 6);
+@@ -193,15 +198,15 @@ void r300_init_reg_flags(void)
+ 	ADD_RANGE(R300_RB3D_CBLEND, 2);
+ 	ADD_RANGE(R300_RB3D_COLORMASK, 1);
+ 	ADD_RANGE(0x4E10, 3);
+-	ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */
++	ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET);	/* check offset */
+ 	ADD_RANGE(R300_RB3D_COLORPITCH0, 1);
+ 	ADD_RANGE(0x4E50, 9);
+ 	ADD_RANGE(0x4E88, 1);
+ 	ADD_RANGE(0x4EA0, 2);
+ 	ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3);
+ 	ADD_RANGE(0x4F10, 4);
+-	ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
+-	ADD_RANGE(R300_RB3D_DEPTHPITCH, 1); 
++	ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET);	/* check offset */
++	ADD_RANGE(R300_RB3D_DEPTHPITCH, 1);
+ 	ADD_RANGE(0x4F28, 1);
+ 	ADD_RANGE(0x4F30, 2);
+ 	ADD_RANGE(0x4F44, 1);
+@@ -211,7 +216,7 @@ void r300_init_reg_flags(void)
+ 	ADD_RANGE(R300_TX_UNK1_0, 16);
+ 	ADD_RANGE(R300_TX_SIZE_0, 16);
+ 	ADD_RANGE(R300_TX_FORMAT_0, 16);
+-		/* Texture offset is dangerous and needs more checking */
++	/* Texture offset is dangerous and needs more checking */
+ 	ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
+ 	ADD_RANGE(R300_TX_UNK4_0, 16);
+ 	ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
+@@ -224,33 +229,41 @@ void r300_init_reg_flags(void)
+ 
+ }
+ 
+-static __inline__ int r300_check_range(unsigned  reg, int count)
++static __inline__ int r300_check_range(unsigned reg, int count)
+ {
+ 	int i;
+-	if(reg & ~0xffff)return -1;
+-	for(i=(reg>>2);i<(reg>>2)+count;i++)
+-		if(r300_reg_flags[i]!=MARK_SAFE)return 1;
++	if (reg & ~0xffff)
++		return -1;
++	for (i = (reg >> 2); i < (reg >> 2) + count; i++)
++		if (r300_reg_flags[i] != MARK_SAFE)
++			return 1;
+ 	return 0;
+ }
+ 
+   /* we expect offsets passed to the framebuffer to be either within video memory or
+-      within AGP space */
+-static __inline__ int r300_check_offset(drm_radeon_private_t* dev_priv, u32 offset)
++     within AGP space */
++static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv,
++					u32 offset)
+ {
+ 	/* we realy want to check against end of video aperture
+-		but this value is not being kept. 
+-		This code is correct for now (does the same thing as the
+-		code that sets MC_FB_LOCATION) in radeon_cp.c */
+-	if((offset>=dev_priv->fb_location) && 
+-		(offset<dev_priv->gart_vm_start))return 0;
+-	if((offset>=dev_priv->gart_vm_start) &&
+-		 (offset<dev_priv->gart_vm_start+dev_priv->gart_size))return 0;
++	   but this value is not being kept.
++	   This code is correct for now (does the same thing as the
++	   code that sets MC_FB_LOCATION) in radeon_cp.c */
++	if ((offset >= dev_priv->fb_location) &&
++	    (offset < dev_priv->gart_vm_start))
++		return 0;
++	if ((offset >= dev_priv->gart_vm_start) &&
++	    (offset < dev_priv->gart_vm_start + dev_priv->gart_size))
++		return 0;
+ 	return 1;
+ }
+ 
+-static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t* dev_priv,
+-						drm_radeon_cmd_buffer_t* cmdbuf,
+-						drm_r300_cmd_header_t header)
++static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
++							  dev_priv,
++							  drm_radeon_kcmd_buffer_t
++							  * cmdbuf,
++							  drm_r300_cmd_header_t
++							  header)
+ {
+ 	int reg;
+ 	int sz;
+@@ -260,35 +273,40 @@ static __inline__ int r300_emit_carefull
+ 
+ 	sz = header.packet0.count;
+ 	reg = (header.packet0.reghi << 8) | header.packet0.reglo;
+-	
+-	if((sz>64)||(sz<0)){
+-		DRM_ERROR("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n", reg, sz);
++
++	if ((sz > 64) || (sz < 0)) {
++		DRM_ERROR
++		    ("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n",
++		     reg, sz);
+ 		return DRM_ERR(EINVAL);
+-		}
+-	for(i=0;i<sz;i++){
+-		values[i]=((int __user*)cmdbuf->buf)[i];
+-		switch(r300_reg_flags[(reg>>2)+i]){
++	}
++	for (i = 0; i < sz; i++) {
++		values[i] = ((int *)cmdbuf->buf)[i];
++		switch (r300_reg_flags[(reg >> 2) + i]) {
+ 		case MARK_SAFE:
+ 			break;
+ 		case MARK_CHECK_OFFSET:
+-			if(r300_check_offset(dev_priv, (u32)values[i])){
+-				DRM_ERROR("Offset failed range check (reg=%04x sz=%d)\n", reg, sz);
++			if (r300_check_offset(dev_priv, (u32) values[i])) {
++				DRM_ERROR
++				    ("Offset failed range check (reg=%04x sz=%d)\n",
++				     reg, sz);
+ 				return DRM_ERR(EINVAL);
+-				}
++			}
+ 			break;
+ 		default:
+-			DRM_ERROR("Register %04x failed check as flag=%02x\n", reg+i*4, r300_reg_flags[(reg>>2)+i]);
++			DRM_ERROR("Register %04x failed check as flag=%02x\n",
++				  reg + i * 4, r300_reg_flags[(reg >> 2) + i]);
+ 			return DRM_ERR(EINVAL);
+-			}
+ 		}
+-		
+-	BEGIN_RING(1+sz);
+-	OUT_RING( CP_PACKET0( reg, sz-1 ) );
+-	OUT_RING_TABLE( values, sz );
++	}
++
++	BEGIN_RING(1 + sz);
++	OUT_RING(CP_PACKET0(reg, sz - 1));
++	OUT_RING_TABLE(values, sz);
+ 	ADVANCE_RING();
+ 
+-	cmdbuf->buf += sz*4;
+-	cmdbuf->bufsz -= sz*4;
++	cmdbuf->buf += sz * 4;
++	cmdbuf->bufsz -= sz * 4;
+ 
+ 	return 0;
+ }
+@@ -299,9 +317,9 @@ static __inline__ int r300_emit_carefull
+  *
+  * Note that checks are performed on contents and addresses of the registers
+  */
+-static __inline__ int r300_emit_packet0(drm_radeon_private_t* dev_priv,
+-						drm_radeon_cmd_buffer_t* cmdbuf,
+-						drm_r300_cmd_header_t header)
++static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv,
++					drm_radeon_kcmd_buffer_t * cmdbuf,
++					drm_r300_cmd_header_t header)
+ {
+ 	int reg;
+ 	int sz;
+@@ -313,39 +331,40 @@ static __inline__ int r300_emit_packet0(
+ 	if (!sz)
+ 		return 0;
+ 
+-	if (sz*4 > cmdbuf->bufsz)
++	if (sz * 4 > cmdbuf->bufsz)
+ 		return DRM_ERR(EINVAL);
+-		
+-	if (reg+sz*4 >= 0x10000){
+-		DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg, sz);
++
++	if (reg + sz * 4 >= 0x10000) {
++		DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg,
++			  sz);
+ 		return DRM_ERR(EINVAL);
+-		}
++	}
+ 
+-	if(r300_check_range(reg, sz)){
++	if (r300_check_range(reg, sz)) {
+ 		/* go and check everything */
+-		return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf, header);
+-		}
++		return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf,
++							   header);
++	}
+ 	/* the rest of the data is safe to emit, whatever the values the user passed */
+ 
+-	BEGIN_RING(1+sz);
+-	OUT_RING( CP_PACKET0( reg, sz-1 ) );
+-	OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz );
++	BEGIN_RING(1 + sz);
++	OUT_RING(CP_PACKET0(reg, sz - 1));
++	OUT_RING_TABLE((int *)cmdbuf->buf, sz);
+ 	ADVANCE_RING();
+ 
+-	cmdbuf->buf += sz*4;
+-	cmdbuf->bufsz -= sz*4;
++	cmdbuf->buf += sz * 4;
++	cmdbuf->bufsz -= sz * 4;
+ 
+ 	return 0;
+ }
+ 
+-
+ /**
+  * Uploads user-supplied vertex program instructions or parameters onto
+  * the graphics card.
+  * Called by r300_do_cp_cmdbuf.
+  */
+-static __inline__ int r300_emit_vpu(drm_radeon_private_t* dev_priv,
+-				    drm_radeon_cmd_buffer_t* cmdbuf,
++static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv,
++				    drm_radeon_kcmd_buffer_t * cmdbuf,
+ 				    drm_r300_cmd_header_t header)
+ {
+ 	int sz;
+@@ -357,114 +376,121 @@ static __inline__ int r300_emit_vpu(drm_
+ 
+ 	if (!sz)
+ 		return 0;
+-	if (sz*16 > cmdbuf->bufsz)
++	if (sz * 16 > cmdbuf->bufsz)
+ 		return DRM_ERR(EINVAL);
+ 
+-	BEGIN_RING(5+sz*4);
++	BEGIN_RING(5 + sz * 4);
+ 	/* Wait for VAP to come to senses.. */
+ 	/* there is no need to emit it multiple times, (only once before VAP is programmed,
+ 	   but this optimization is for later */
+-	OUT_RING_REG( R300_VAP_PVS_WAITIDLE, 0 );
+-	OUT_RING_REG( R300_VAP_PVS_UPLOAD_ADDRESS, addr );
+-	OUT_RING( CP_PACKET0_TABLE( R300_VAP_PVS_UPLOAD_DATA, sz*4 - 1 ) );
+-	OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz*4 );
++	OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0);
++	OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
++	OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
++	OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
+ 
+ 	ADVANCE_RING();
+ 
+-	cmdbuf->buf += sz*16;
+-	cmdbuf->bufsz -= sz*16;
++	cmdbuf->buf += sz * 16;
++	cmdbuf->bufsz -= sz * 16;
+ 
+ 	return 0;
+ }
+ 
+-
+ /**
+  * Emit a clear packet from userspace.
+  * Called by r300_emit_packet3.
+  */
+-static __inline__ int r300_emit_clear(drm_radeon_private_t* dev_priv,
+-				      drm_radeon_cmd_buffer_t* cmdbuf)
++static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv,
++				      drm_radeon_kcmd_buffer_t * cmdbuf)
+ {
+ 	RING_LOCALS;
+ 
+-	if (8*4 > cmdbuf->bufsz)
++	if (8 * 4 > cmdbuf->bufsz)
+ 		return DRM_ERR(EINVAL);
+ 
+ 	BEGIN_RING(10);
+-	OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 8 ) );
+-	OUT_RING( R300_PRIM_TYPE_POINT|R300_PRIM_WALK_RING|
+-	          (1<<R300_PRIM_NUM_VERTICES_SHIFT) );
+-	OUT_RING_TABLE( (int __user*)cmdbuf->buf, 8 );
++	OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
++	OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
++		 (1 << R300_PRIM_NUM_VERTICES_SHIFT));
++	OUT_RING_TABLE((int *)cmdbuf->buf, 8);
+ 	ADVANCE_RING();
+ 
+-	cmdbuf->buf += 8*4;
+-	cmdbuf->bufsz -= 8*4;
++	cmdbuf->buf += 8 * 4;
++	cmdbuf->bufsz -= 8 * 4;
+ 
+ 	return 0;
+ }
+ 
+-static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t* dev_priv,
+-				      drm_radeon_cmd_buffer_t* cmdbuf,
+-				      u32 header)
++static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv,
++					       drm_radeon_kcmd_buffer_t * cmdbuf,
++					       u32 header)
+ {
+-	int count, i,k;
+-	#define MAX_ARRAY_PACKET  64
++	int count, i, k;
++#define MAX_ARRAY_PACKET  64
+ 	u32 payload[MAX_ARRAY_PACKET];
+ 	u32 narrays;
+ 	RING_LOCALS;
+ 
+-	count=(header>>16) & 0x3fff;
+-	
+-	if((count+1)>MAX_ARRAY_PACKET){
+-		DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", count);
++	count = (header >> 16) & 0x3fff;
++
++	if ((count + 1) > MAX_ARRAY_PACKET) {
++		DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
++			  count);
+ 		return DRM_ERR(EINVAL);
+-		}
+-	memset(payload, 0, MAX_ARRAY_PACKET*4);
+-	memcpy(payload, cmdbuf->buf+4, (count+1)*4);	
+-	
++	}
++	memset(payload, 0, MAX_ARRAY_PACKET * 4);
++	memcpy(payload, cmdbuf->buf + 4, (count + 1) * 4);
++
+ 	/* carefully check packet contents */
+-	
+-	narrays=payload[0];
+-	k=0;
+-	i=1;
+-	while((k<narrays) && (i<(count+1))){
+-		i++; /* skip attribute field */
+-		if(r300_check_offset(dev_priv, payload[i])){
+-			DRM_ERROR("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i);
++
++	narrays = payload[0];
++	k = 0;
++	i = 1;
++	while ((k < narrays) && (i < (count + 1))) {
++		i++;		/* skip attribute field */
++		if (r300_check_offset(dev_priv, payload[i])) {
++			DRM_ERROR
++			    ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
++			     k, i);
+ 			return DRM_ERR(EINVAL);
+-			}
++		}
+ 		k++;
+ 		i++;
+-		if(k==narrays)break;
++		if (k == narrays)
++			break;
+ 		/* have one more to process, they come in pairs */
+-		if(r300_check_offset(dev_priv, payload[i])){
+-			DRM_ERROR("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i);
++		if (r300_check_offset(dev_priv, payload[i])) {
++			DRM_ERROR
++			    ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
++			     k, i);
+ 			return DRM_ERR(EINVAL);
+-			}
+-		k++;
+-		i++;			
+ 		}
++		k++;
++		i++;
++	}
+ 	/* do the counts match what we expect ? */
+-	if((k!=narrays) || (i!=(count+1))){
+-		DRM_ERROR("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", k, i, narrays, count+1);
++	if ((k != narrays) || (i != (count + 1))) {
++		DRM_ERROR
++		    ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
++		     k, i, narrays, count + 1);
+ 		return DRM_ERR(EINVAL);
+-		}
++	}
+ 
+ 	/* all clear, output packet */
+ 
+-	BEGIN_RING(count+2);
++	BEGIN_RING(count + 2);
+ 	OUT_RING(header);
+-	OUT_RING_TABLE(payload, count+1);
++	OUT_RING_TABLE(payload, count + 1);
+ 	ADVANCE_RING();
+ 
+-	cmdbuf->buf += (count+2)*4;
+-	cmdbuf->bufsz -= (count+2)*4;
++	cmdbuf->buf += (count + 2) * 4;
++	cmdbuf->bufsz -= (count + 2) * 4;
+ 
+ 	return 0;
+ }
+ 
+-static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv,
+-				      drm_radeon_cmd_buffer_t* cmdbuf)
++static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv,
++					    drm_radeon_kcmd_buffer_t * cmdbuf)
+ {
+ 	u32 header;
+ 	int count;
+@@ -473,36 +499,37 @@ static __inline__ int r300_emit_raw_pack
+ 	if (4 > cmdbuf->bufsz)
+ 		return DRM_ERR(EINVAL);
+ 
+-        /* Fixme !! This simply emits a packet without much checking.
++	/* Fixme !! This simply emits a packet without much checking.
+ 	   We need to be smarter. */
+ 
+ 	/* obtain first word - actual packet3 header */
+-	header = *(u32 __user*)cmdbuf->buf;
++	header = *(u32 *) cmdbuf->buf;
+ 
+ 	/* Is it packet 3 ? */
+-	if( (header>>30)!=0x3 ) {
++	if ((header >> 30) != 0x3) {
+ 		DRM_ERROR("Not a packet3 header (0x%08x)\n", header);
+ 		return DRM_ERR(EINVAL);
+-		}
++	}
+ 
+-	count=(header>>16) & 0x3fff;
++	count = (header >> 16) & 0x3fff;
+ 
+ 	/* Check again now that we know how much data to expect */
+-	if ((count+2)*4 > cmdbuf->bufsz){
+-		DRM_ERROR("Expected packet3 of length %d but have only %d bytes left\n",
+-			(count+2)*4, cmdbuf->bufsz);
++	if ((count + 2) * 4 > cmdbuf->bufsz) {
++		DRM_ERROR
++		    ("Expected packet3 of length %d but have only %d bytes left\n",
++		     (count + 2) * 4, cmdbuf->bufsz);
+ 		return DRM_ERR(EINVAL);
+-		}
++	}
+ 
+ 	/* Is it a packet type we know about ? */
+-	switch(header & 0xff00){
+-	case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */
++	switch (header & 0xff00) {
++	case RADEON_3D_LOAD_VBPNTR:	/* load vertex array pointers */
+ 		return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header);
+ 
+-	case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
+-	case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
+-	case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
+-	case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
++	case RADEON_CP_3D_DRAW_IMMD_2:	/* triggers drawing using in-packet vertex data */
++	case RADEON_CP_3D_DRAW_VBUF_2:	/* triggers drawing of vertex buffers setup elsewhere */
++	case RADEON_CP_3D_DRAW_INDX_2:	/* triggers drawing using indices to vertex buffer */
++	case RADEON_CP_INDX_BUFFER:	/* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
+ 	case RADEON_WAIT_FOR_IDLE:
+ 	case RADEON_CP_NOP:
+ 		/* these packets are safe */
+@@ -510,32 +537,30 @@ static __inline__ int r300_emit_raw_pack
+ 	default:
+ 		DRM_ERROR("Unknown packet3 header (0x%08x)\n", header);
+ 		return DRM_ERR(EINVAL);
+-		}
+-
++	}
+ 
+-	BEGIN_RING(count+2);
++	BEGIN_RING(count + 2);
+ 	OUT_RING(header);
+-	OUT_RING_TABLE( (int __user*)(cmdbuf->buf+4), count+1);
++	OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
+ 	ADVANCE_RING();
+ 
+-	cmdbuf->buf += (count+2)*4;
+-	cmdbuf->bufsz -= (count+2)*4;
++	cmdbuf->buf += (count + 2) * 4;
++	cmdbuf->bufsz -= (count + 2) * 4;
+ 
+ 	return 0;
+ }
+ 
+-
+ /**
+  * Emit a rendering packet3 from userspace.
+  * Called by r300_do_cp_cmdbuf.
+  */
+-static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
+-					drm_radeon_cmd_buffer_t* cmdbuf,
++static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv,
++					drm_radeon_kcmd_buffer_t * cmdbuf,
+ 					drm_r300_cmd_header_t header)
+ {
+ 	int n;
+ 	int ret;
+-	char __user* orig_buf = cmdbuf->buf;
++	char *orig_buf = cmdbuf->buf;
+ 	int orig_bufsz = cmdbuf->bufsz;
+ 
+ 	/* This is a do-while-loop so that we run the interior at least once,
+@@ -550,16 +575,16 @@ static __inline__ int r300_emit_packet3(
+ 
+ 			cmdbuf->buf = orig_buf;
+ 			cmdbuf->bufsz = orig_bufsz;
+-			}
++		}
+ 
+-		switch(header.packet3.packet) {
++		switch (header.packet3.packet) {
+ 		case R300_CMD_PACKET3_CLEAR:
+ 			DRM_DEBUG("R300_CMD_PACKET3_CLEAR\n");
+ 			ret = r300_emit_clear(dev_priv, cmdbuf);
+ 			if (ret) {
+ 				DRM_ERROR("r300_emit_clear failed\n");
+ 				return ret;
+-				}
++			}
+ 			break;
+ 
+ 		case R300_CMD_PACKET3_RAW:
+@@ -568,18 +593,18 @@ static __inline__ int r300_emit_packet3(
+ 			if (ret) {
+ 				DRM_ERROR("r300_emit_raw_packet3 failed\n");
+ 				return ret;
+-				}
++			}
+ 			break;
+ 
+ 		default:
+ 			DRM_ERROR("bad packet3 type %i at %p\n",
+-				header.packet3.packet,
+-				cmdbuf->buf - sizeof(header));
++				  header.packet3.packet,
++				  cmdbuf->buf - sizeof(header));
+ 			return DRM_ERR(EINVAL);
+-			}
++		}
+ 
+ 		n += R300_SIMULTANEOUS_CLIPRECTS;
+-	} while(n < cmdbuf->nbox);
++	} while (n < cmdbuf->nbox);
+ 
+ 	return 0;
+ }
+@@ -598,21 +623,20 @@ static __inline__ int r300_emit_packet3(
+ /**
+  * Emit the sequence to pacify R300.
+  */
+-static __inline__ void r300_pacify(drm_radeon_private_t* dev_priv)
++static __inline__ void r300_pacify(drm_radeon_private_t * dev_priv)
+ {
+ 	RING_LOCALS;
+ 
+ 	BEGIN_RING(6);
+-	OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) );
+-	OUT_RING( 0xa );
+-	OUT_RING( CP_PACKET0( 0x4f18, 0 ) );
+-	OUT_RING( 0x3 );
+-	OUT_RING( CP_PACKET3( RADEON_CP_NOP, 0 ) );
+-	OUT_RING( 0x0 );
++	OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
++	OUT_RING(0xa);
++	OUT_RING(CP_PACKET0(0x4f18, 0));
++	OUT_RING(0x3);
++	OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0));
++	OUT_RING(0x0);
+ 	ADVANCE_RING();
+ }
+ 
+-
+ /**
+  * Called by r300_do_cp_cmdbuf to update the internal buffer age and state.
+  * The actual age emit is done by r300_do_cp_cmdbuf, which is why you must
+@@ -628,20 +652,18 @@ static void r300_discard_buffer(drm_devi
+ 	buf->used = 0;
+ }
+ 
+-
+ /**
+  * Parses and validates a user-supplied command buffer and emits appropriate
+  * commands on the DMA ring buffer.
+  * Called by the ioctl handler function radeon_cp_cmdbuf.
+  */
+-int r300_do_cp_cmdbuf(drm_device_t* dev,
+-			  DRMFILE filp,
+-		      drm_file_t* filp_priv,
+-		      drm_radeon_cmd_buffer_t* cmdbuf)
++int r300_do_cp_cmdbuf(drm_device_t * dev,
++		      DRMFILE filp,
++		      drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t * cmdbuf)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+-        drm_device_dma_t *dma = dev->dma;
+-        drm_buf_t *buf = NULL;
++	drm_device_dma_t *dma = dev->dma;
++	drm_buf_t *buf = NULL;
+ 	int emit_dispatch_age = 0;
+ 	int ret = 0;
+ 
+@@ -655,9 +677,9 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
+ 		ret = r300_emit_cliprects(dev_priv, cmdbuf, 0);
+ 		if (ret)
+ 			goto cleanup;
+-		}
++	}
+ 
+-	while(cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
++	while (cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
+ 		int idx;
+ 		drm_r300_cmd_header_t header;
+ 
+@@ -666,14 +688,14 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
+ 		cmdbuf->buf += sizeof(header);
+ 		cmdbuf->bufsz -= sizeof(header);
+ 
+-		switch(header.header.cmd_type) {
+-		case R300_CMD_PACKET0: 
++		switch (header.header.cmd_type) {
++		case R300_CMD_PACKET0:
+ 			DRM_DEBUG("R300_CMD_PACKET0\n");
+ 			ret = r300_emit_packet0(dev_priv, cmdbuf, header);
+ 			if (ret) {
+ 				DRM_ERROR("r300_emit_packet0 failed\n");
+ 				goto cleanup;
+-				}
++			}
+ 			break;
+ 
+ 		case R300_CMD_VPU:
+@@ -682,7 +704,7 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
+ 			if (ret) {
+ 				DRM_ERROR("r300_emit_vpu failed\n");
+ 				goto cleanup;
+-				}
++			}
+ 			break;
+ 
+ 		case R300_CMD_PACKET3:
+@@ -691,26 +713,26 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
+ 			if (ret) {
+ 				DRM_ERROR("r300_emit_packet3 failed\n");
+ 				goto cleanup;
+-				}
++			}
+ 			break;
+ 
+ 		case R300_CMD_END3D:
+ 			DRM_DEBUG("R300_CMD_END3D\n");
+-			/* TODO: 
+-				Ideally userspace driver should not need to issue this call, 
+-				i.e. the drm driver should issue it automatically and prevent
+-				lockups.
+-				
+-				In practice, we do not understand why this call is needed and what
+-				it does (except for some vague guesses that it has to do with cache
+-				coherence) and so the user space driver does it. 
+-				
+-				Once we are sure which uses prevent lockups the code could be moved
+-				into the kernel and the userspace driver will not
+-				need to use this command.
++			/* TODO:
++			   Ideally userspace driver should not need to issue this call,
++			   i.e. the drm driver should issue it automatically and prevent
++			   lockups.
++
++			   In practice, we do not understand why this call is needed and what
++			   it does (except for some vague guesses that it has to do with cache
++			   coherence) and so the user space driver does it.
++
++			   Once we are sure which uses prevent lockups the code could be moved
++			   into the kernel and the userspace driver will not
++			   need to use this command.
+ 
+-				Note that issuing this command does not hurt anything
+-				except, possibly, performance */
++			   Note that issuing this command does not hurt anything
++			   except, possibly, performance */
+ 			r300_pacify(dev_priv);
+ 			break;
+ 
+@@ -722,7 +744,7 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
+ 				RING_LOCALS;
+ 
+ 				BEGIN_RING(header.delay.count);
+-				for(i=0;i<header.delay.count;i++)
++				for (i = 0; i < header.delay.count; i++)
+ 					OUT_RING(RADEON_CP_PACKET2);
+ 				ADVANCE_RING();
+ 			}
+@@ -730,53 +752,54 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
+ 
+ 		case R300_CMD_DMA_DISCARD:
+ 			DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
+-            		idx = header.dma.buf_idx;
+-            		if (idx < 0 || idx >= dma->buf_count) {
+-                		DRM_ERROR("buffer index %d (of %d max)\n",
+-                      			idx, dma->buf_count - 1);
++			idx = header.dma.buf_idx;
++			if (idx < 0 || idx >= dma->buf_count) {
++				DRM_ERROR("buffer index %d (of %d max)\n",
++					  idx, dma->buf_count - 1);
+ 				ret = DRM_ERR(EINVAL);
+-                		goto cleanup;
+-            			}
++				goto cleanup;
++			}
+ 
+-	                buf = dma->buflist[idx];
+-            		if (buf->filp != filp || buf->pending) {
+-                		DRM_ERROR("bad buffer %p %p %d\n",
+-                      		buf->filp, filp, buf->pending);
+-                		ret = DRM_ERR(EINVAL);
++			buf = dma->buflist[idx];
++			if (buf->filp != filp || buf->pending) {
++				DRM_ERROR("bad buffer %p %p %d\n",
++					  buf->filp, filp, buf->pending);
++				ret = DRM_ERR(EINVAL);
+ 				goto cleanup;
+-            			}
++			}
+ 
+ 			emit_dispatch_age = 1;
+ 			r300_discard_buffer(dev, buf);
+-            		break;
++			break;
+ 
+ 		case R300_CMD_WAIT:
+ 			/* simple enough, we can do it here */
+ 			DRM_DEBUG("R300_CMD_WAIT\n");
+-			if(header.wait.flags==0)break; /* nothing to do */
++			if (header.wait.flags == 0)
++				break;	/* nothing to do */
+ 
+ 			{
+ 				RING_LOCALS;
+ 
+ 				BEGIN_RING(2);
+-				OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );
+-				OUT_RING( (header.wait.flags & 0xf)<<14 );
++				OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
++				OUT_RING((header.wait.flags & 0xf) << 14);
+ 				ADVANCE_RING();
+ 			}
+ 			break;
+ 
+ 		default:
+ 			DRM_ERROR("bad cmd_type %i at %p\n",
+-			          header.header.cmd_type,
++				  header.header.cmd_type,
+ 				  cmdbuf->buf - sizeof(header));
+ 			ret = DRM_ERR(EINVAL);
+ 			goto cleanup;
+-			}
++		}
+ 	}
+ 
+ 	DRM_DEBUG("END\n");
+ 
+-cleanup:
++      cleanup:
+ 	r300_pacify(dev_priv);
+ 
+ 	/* We emit the vertex buffer age here, outside the pacifier "brackets"
+@@ -792,10 +815,9 @@ cleanup:
+ 		BEGIN_RING(2);
+ 		RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch);
+ 		ADVANCE_RING();
+-		}
++	}
+ 
+ 	COMMIT_RING();
+ 
+ 	return ret;
+ }
+-
+diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h
+--- a/drivers/char/drm/r300_reg.h
++++ b/drivers/char/drm/r300_reg.h
+@@ -36,7 +36,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
+ #	define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT	24
+ #	define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT	28
+ 
+-
+ #define R300_MC_INIT_GFX_LAT_TIMER	0x154
+ #	define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT	0
+ #	define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT	4
+@@ -62,7 +61,6 @@ I am fairly certain that they are correc
+ #define R300_SE_VPORT_ZSCALE                0x1DA8
+ #define R300_SE_VPORT_ZOFFSET               0x1DAC
+ 
+-
+ /* This register is written directly and also starts data section in many 3d CP_PACKET3's */
+ #define R300_VAP_VF_CNTL	0x2084
+ 
+@@ -93,17 +91,17 @@ I am fairly certain that they are correc
+ 
+ 		/* index size - when not set the indices are assumed to be 16 bit */
+ #	define	R300_VAP_VF_CNTL__INDEX_SIZE_32bit                      (1<<11)
+-                /* number of vertices */
++		/* number of vertices */
+ #	define	R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT                    16
+ 
+ /* BEGIN: Wild guesses */
+ #define R300_VAP_OUTPUT_VTX_FMT_0           0x2090
+ #       define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT     (1<<0)
+ #       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT   (1<<1)
+-#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */
+-#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */
+-#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */
+-#       define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
++#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2)	/* GUESS */
++#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3)	/* GUESS */
++#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4)	/* GUESS */
++#       define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16)	/* GUESS */
+ 
+ #define R300_VAP_OUTPUT_VTX_FMT_1           0x2094
+ #       define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
+@@ -159,14 +157,14 @@ I am fairly certain that they are correc
+ #       define R300_INPUT_ROUTE_COMPONENTS_2     (1 << 0)
+ #       define R300_INPUT_ROUTE_COMPONENTS_3     (2 << 0)
+ #       define R300_INPUT_ROUTE_COMPONENTS_4     (3 << 0)
+-#       define R300_INPUT_ROUTE_COMPONENTS_RGBA  (4 << 0) /* GUESS */
++#       define R300_INPUT_ROUTE_COMPONENTS_RGBA  (4 << 0)	/* GUESS */
+ #       define R300_VAP_INPUT_ROUTE_IDX_SHIFT    8
+-#       define R300_VAP_INPUT_ROUTE_IDX_MASK     (31 << 8) /* GUESS */
++#       define R300_VAP_INPUT_ROUTE_IDX_MASK     (31 << 8)	/* GUESS */
+ #       define R300_VAP_INPUT_ROUTE_END          (1 << 13)
+-#       define R300_INPUT_ROUTE_IMMEDIATE_MODE   (0 << 14) /* GUESS */
+-#       define R300_INPUT_ROUTE_FLOAT            (1 << 14) /* GUESS */
+-#       define R300_INPUT_ROUTE_UNSIGNED_BYTE    (2 << 14) /* GUESS */
+-#       define R300_INPUT_ROUTE_FLOAT_COLOR      (3 << 14) /* GUESS */
++#       define R300_INPUT_ROUTE_IMMEDIATE_MODE   (0 << 14)	/* GUESS */
++#       define R300_INPUT_ROUTE_FLOAT            (1 << 14)	/* GUESS */
++#       define R300_INPUT_ROUTE_UNSIGNED_BYTE    (2 << 14)	/* GUESS */
++#       define R300_INPUT_ROUTE_FLOAT_COLOR      (3 << 14)	/* GUESS */
+ #define R300_VAP_INPUT_ROUTE_0_1            0x2154
+ #define R300_VAP_INPUT_ROUTE_0_2            0x2158
+ #define R300_VAP_INPUT_ROUTE_0_3            0x215C
+@@ -188,12 +186,12 @@ I am fairly certain that they are correc
+ #       define R300_INPUT_CNTL_COLOR             0x00000004
+ #       define R300_INPUT_CNTL_TC0               0x00000400
+ #       define R300_INPUT_CNTL_TC1               0x00000800
+-#       define R300_INPUT_CNTL_TC2               0x00001000 /* GUESS */
+-#       define R300_INPUT_CNTL_TC3               0x00002000 /* GUESS */
+-#       define R300_INPUT_CNTL_TC4               0x00004000 /* GUESS */
+-#       define R300_INPUT_CNTL_TC5               0x00008000 /* GUESS */
+-#       define R300_INPUT_CNTL_TC6               0x00010000 /* GUESS */
+-#       define R300_INPUT_CNTL_TC7               0x00020000 /* GUESS */
++#       define R300_INPUT_CNTL_TC2               0x00001000	/* GUESS */
++#       define R300_INPUT_CNTL_TC3               0x00002000	/* GUESS */
++#       define R300_INPUT_CNTL_TC4               0x00004000	/* GUESS */
++#       define R300_INPUT_CNTL_TC5               0x00008000	/* GUESS */
++#       define R300_INPUT_CNTL_TC6               0x00010000	/* GUESS */
++#       define R300_INPUT_CNTL_TC7               0x00020000	/* GUESS */
+ 
+ /* gap */
+ /* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0
+@@ -270,12 +268,12 @@ I am fairly certain that they are correc
+ // rendering commands and overwriting vertex program parameters.
+ // Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
+ // avoids bugs caused by still running shaders reading bad data from memory. */
+-#define R300_VAP_PVS_WAITIDLE               0x2284 /* GUESS */
++#define R300_VAP_PVS_WAITIDLE               0x2284	/* GUESS */
+ 
+ /* Absolutely no clue what this register is about. */
+ #define R300_VAP_UNKNOWN_2288               0x2288
+-#       define R300_2288_R300                    0x00750000 /* -- nh */
+-#       define R300_2288_RV350                   0x0000FFFF /* -- Vladimir */
++#       define R300_2288_R300                    0x00750000	/* -- nh */
++#       define R300_2288_RV350                   0x0000FFFF	/* -- Vladimir */
+ 
+ /* gap */
+ /* Addresses are relative to the vertex program instruction area of the
+@@ -286,10 +284,10 @@ I am fairly certain that they are correc
+ // experiments so far have shown that both *must* point to an instruction
+ // inside the vertex program, otherwise the GPU locks up.
+ // fglrx usually sets CNTL_3_UNKNOWN to the end of the program and
+-// CNTL_1_UNKNOWN points to instruction where last write to position takes place. 
++// CNTL_1_UNKNOWN points to instruction where last write to position takes place.
+ // Most likely this is used to ignore rest of the program in cases where group of verts arent visible.
+ // For some reason this "section" is sometimes accepted other instruction that have
+-// no relationship with position calculations. 
++// no relationship with position calculations.
+ */
+ #define R300_VAP_PVS_CNTL_1                 0x22D0
+ #       define R300_PVS_CNTL_1_PROGRAM_START_SHIFT   0
+@@ -308,13 +306,13 @@ I am fairly certain that they are correc
+ #define R300_VAP_VTX_COLOR_R                0x2464
+ #define R300_VAP_VTX_COLOR_G                0x2468
+ #define R300_VAP_VTX_COLOR_B                0x246C
+-#define R300_VAP_VTX_POS_0_X_1              0x2490 /* used for glVertex2*() */
++#define R300_VAP_VTX_POS_0_X_1              0x2490	/* used for glVertex2*() */
+ #define R300_VAP_VTX_POS_0_Y_1              0x2494
+-#define R300_VAP_VTX_COLOR_PKD              0x249C /* RGBA */
+-#define R300_VAP_VTX_POS_0_X_2              0x24A0 /* used for glVertex3*() */
++#define R300_VAP_VTX_COLOR_PKD              0x249C	/* RGBA */
++#define R300_VAP_VTX_POS_0_X_2              0x24A0	/* used for glVertex3*() */
+ #define R300_VAP_VTX_POS_0_Y_2              0x24A4
+ #define R300_VAP_VTX_POS_0_Z_2              0x24A8
+-#define R300_VAP_VTX_END_OF_PKT             0x24AC /* write 0 to indicate end of packet? */
++#define R300_VAP_VTX_END_OF_PKT             0x24AC	/* write 0 to indicate end of packet? */
+ 
+ /* gap */
+ 
+@@ -385,7 +383,6 @@ I am fairly certain that they are correc
+ #	define R300_GB_MSPOS1__MS_Y5_SHIFT	20
+ #	define R300_GB_MSPOS1__MSBD1		24
+ 
+-
+ #define R300_GB_TILE_CONFIG	0x4018
+ #	define R300_GB_TILE_ENABLE	(1<<0)
+ #	define R300_GB_TILE_PIPE_COUNT_RV300	0
+@@ -478,9 +475,9 @@ I am fairly certain that they are correc
+ // framebuffer. */
+ #define R300_RE_POINTSIZE                   0x421C
+ #       define R300_POINTSIZE_Y_SHIFT            0
+-#       define R300_POINTSIZE_Y_MASK             (0xFFFF << 0) /* GUESS */
++#       define R300_POINTSIZE_Y_MASK             (0xFFFF << 0)	/* GUESS */
+ #       define R300_POINTSIZE_X_SHIFT            16
+-#       define R300_POINTSIZE_X_MASK             (0xFFFF << 16) /* GUESS */
++#       define R300_POINTSIZE_X_MASK             (0xFFFF << 16)	/* GUESS */
+ #       define R300_POINTSIZE_MAX             (R300_POINTSIZE_Y_MASK / 6)
+ 
+ /* The line width is given in multiples of 6.
+@@ -491,7 +488,7 @@ I am fairly certain that they are correc
+ */
+ #define R300_RE_LINE_CNT                      0x4234
+ #       define R300_LINESIZE_SHIFT            0
+-#       define R300_LINESIZE_MASK             (0xFFFF << 0) /* GUESS */
++#       define R300_LINESIZE_MASK             (0xFFFF << 0)	/* GUESS */
+ #       define R300_LINESIZE_MAX             (R300_LINESIZE_MASK / 6)
+ #       define R300_LINE_CNT_HO               (1 << 16)
+ #       define R300_LINE_CNT_VE               (1 << 17)
+@@ -513,8 +510,8 @@ I am fairly certain that they are correc
+ #	define R300_PM_BACK_LINE              (1 << 7)
+ #	define R300_PM_BACK_FILL              (1 << 8)
+ 
+-/* Not sure why there are duplicate of factor and constant values. 
+-   My best guess so far is that there are seperate zbiases for test and write. 
++/* Not sure why there are duplicate of factor and constant values.
++   My best guess so far is that there are seperate zbiases for test and write.
+    Ordering might be wrong.
+    Some of the tests indicate that fgl has a fallback implementation of zbias
+    via pixel shaders. */
+@@ -540,7 +537,6 @@ I am fairly certain that they are correc
+ #       define R300_FRONT_FACE_CCW               (0 << 2)
+ #       define R300_FRONT_FACE_CW                (1 << 2)
+ 
+-
+ /* BEGIN: Rasterization / Interpolators - many guesses
+ // 0_UNKNOWN_18 has always been set except for clear operations.
+ // TC_CNT is the number of incoming texture coordinate sets (i.e. it depends
+@@ -548,7 +544,7 @@ I am fairly certain that they are correc
+ #define R300_RS_CNTL_0                      0x4300
+ #       define R300_RS_CNTL_TC_CNT_SHIFT         2
+ #       define R300_RS_CNTL_TC_CNT_MASK          (7 << 2)
+-#		define R300_RS_CNTL_CI_CNT_SHIFT         7 /* number of color interpolators used */
++#		define R300_RS_CNTL_CI_CNT_SHIFT         7	/* number of color interpolators used */
+ #       define R300_RS_CNTL_0_UNKNOWN_18         (1 << 18)
+ /* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register. */
+ #define R300_RS_CNTL_1                      0x4304
+@@ -585,29 +581,29 @@ I am fairly certain that they are correc
+ #define R300_RS_ROUTE_0                     0x4330
+ #define R300_RS_ROUTE_1                     0x4334
+ #define R300_RS_ROUTE_2                     0x4338
+-#define R300_RS_ROUTE_3                     0x433C /* GUESS */
+-#define R300_RS_ROUTE_4                     0x4340 /* GUESS */
+-#define R300_RS_ROUTE_5                     0x4344 /* GUESS */
+-#define R300_RS_ROUTE_6                     0x4348 /* GUESS */
+-#define R300_RS_ROUTE_7                     0x434C /* GUESS */
++#define R300_RS_ROUTE_3                     0x433C	/* GUESS */
++#define R300_RS_ROUTE_4                     0x4340	/* GUESS */
++#define R300_RS_ROUTE_5                     0x4344	/* GUESS */
++#define R300_RS_ROUTE_6                     0x4348	/* GUESS */
++#define R300_RS_ROUTE_7                     0x434C	/* GUESS */
+ #       define R300_RS_ROUTE_SOURCE_INTERP_0     0
+ #       define R300_RS_ROUTE_SOURCE_INTERP_1     1
+ #       define R300_RS_ROUTE_SOURCE_INTERP_2     2
+ #       define R300_RS_ROUTE_SOURCE_INTERP_3     3
+ #       define R300_RS_ROUTE_SOURCE_INTERP_4     4
+-#       define R300_RS_ROUTE_SOURCE_INTERP_5     5 /* GUESS */
+-#       define R300_RS_ROUTE_SOURCE_INTERP_6     6 /* GUESS */
+-#       define R300_RS_ROUTE_SOURCE_INTERP_7     7 /* GUESS */
+-#       define R300_RS_ROUTE_ENABLE              (1 << 3) /* GUESS */
++#       define R300_RS_ROUTE_SOURCE_INTERP_5     5	/* GUESS */
++#       define R300_RS_ROUTE_SOURCE_INTERP_6     6	/* GUESS */
++#       define R300_RS_ROUTE_SOURCE_INTERP_7     7	/* GUESS */
++#       define R300_RS_ROUTE_ENABLE              (1 << 3)	/* GUESS */
+ #       define R300_RS_ROUTE_DEST_SHIFT          6
+-#       define R300_RS_ROUTE_DEST_MASK           (31 << 6) /* GUESS */
++#       define R300_RS_ROUTE_DEST_MASK           (31 << 6)	/* GUESS */
+ 
+ /* Special handling for color: When the fragment program uses color,
+ // the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
+ // color register index. */
+ #       define R300_RS_ROUTE_0_COLOR             (1 << 14)
+ #       define R300_RS_ROUTE_0_COLOR_DEST_SHIFT  17
+-#       define R300_RS_ROUTE_0_COLOR_DEST_MASK   (31 << 17) /* GUESS */
++#       define R300_RS_ROUTE_0_COLOR_DEST_MASK   (31 << 17)	/* GUESS */
+ /* As above, but for secondary color */
+ #		define R300_RS_ROUTE_1_COLOR1            (1 << 14)
+ #		define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17
+@@ -721,7 +717,7 @@ I am fairly certain that they are correc
+ #       define R300_TX_HEIGHTMASK_SHIFT          11
+ #       define R300_TX_HEIGHTMASK_MASK           (2047 << 11)
+ #       define R300_TX_UNK23                     (1 << 23)
+-#       define R300_TX_SIZE_SHIFT                26 /* largest of width, height */
++#       define R300_TX_SIZE_SHIFT                26	/* largest of width, height */
+ #       define R300_TX_SIZE_MASK                 (15 << 26)
+ #define R300_TX_FORMAT_0                    0x44C0
+ 	/* The interpretation of the format word by Wladimir van der Laan */
+@@ -746,12 +742,12 @@ I am fairly certain that they are correc
+ #	define R300_TX_FORMAT_DXT1	    	    0xF
+ #	define R300_TX_FORMAT_DXT3	    	    0x10
+ #	define R300_TX_FORMAT_DXT5	    	    0x11
+-#	define R300_TX_FORMAT_D3DMFT_CxV8U8	    0x12     /* no swizzle */
+-#	define R300_TX_FORMAT_A8R8G8B8	    	    0x13     /* no swizzle */
+-#	define R300_TX_FORMAT_B8G8_B8G8	    	    0x14     /* no swizzle */
+-#	define R300_TX_FORMAT_G8R8_G8B8	    	    0x15     /* no swizzle */
++#	define R300_TX_FORMAT_D3DMFT_CxV8U8	    0x12	/* no swizzle */
++#	define R300_TX_FORMAT_A8R8G8B8	    	    0x13	/* no swizzle */
++#	define R300_TX_FORMAT_B8G8_B8G8	    	    0x14	/* no swizzle */
++#	define R300_TX_FORMAT_G8R8_G8B8	    	    0x15	/* no swizzle */
+ 						  /* 0x16 - some 16 bit green format.. ?? */
+-#	define R300_TX_FORMAT_UNK25		   (1 << 25) /* no swizzle */
++#	define R300_TX_FORMAT_UNK25		   (1 << 25)	/* no swizzle */
+ 
+ 	/* gap */
+ 	/* Floating point formats */
+@@ -777,8 +773,8 @@ I am fairly certain that they are correc
+ #	define R300_TX_FORMAT_W		3
+ #	define R300_TX_FORMAT_ZERO	4
+ #	define R300_TX_FORMAT_ONE	5
+-#	define R300_TX_FORMAT_CUT_Z	6		/* 2.0*Z, everything above 1.0 is set to 0.0 */
+-#	define R300_TX_FORMAT_CUT_W	7		/* 2.0*W, everything above 1.0 is set to 0.0 */
++#	define R300_TX_FORMAT_CUT_Z	6	/* 2.0*Z, everything above 1.0 is set to 0.0 */
++#	define R300_TX_FORMAT_CUT_W	7	/* 2.0*W, everything above 1.0 is set to 0.0 */
+ 
+ #	define R300_TX_FORMAT_B_SHIFT	18
+ #	define R300_TX_FORMAT_G_SHIFT	15
+@@ -811,7 +807,7 @@ I am fairly certain that they are correc
+ #       define R300_TXO_OFFSET_SHIFT             5
+ /* END */
+ #define R300_TX_UNK4_0                      0x4580
+-#define R300_TX_BORDER_COLOR_0              0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 }
++#define R300_TX_BORDER_COLOR_0              0x45C0	//ff00ff00 == { 0, 1.0, 0, 1.0 }
+ 
+ /* END */
+ 
+@@ -844,9 +840,9 @@ I am fairly certain that they are correc
+ #       define R300_PFS_CNTL_ALU_END_SHIFT       6
+ #       define R300_PFS_CNTL_ALU_END_MASK        (63 << 0)
+ #       define R300_PFS_CNTL_TEX_OFFSET_SHIFT    12
+-#       define R300_PFS_CNTL_TEX_OFFSET_MASK     (31 << 12) /* GUESS */
++#       define R300_PFS_CNTL_TEX_OFFSET_MASK     (31 << 12)	/* GUESS */
+ #       define R300_PFS_CNTL_TEX_END_SHIFT       18
+-#       define R300_PFS_CNTL_TEX_END_MASK        (31 << 18) /* GUESS */
++#       define R300_PFS_CNTL_TEX_END_MASK        (31 << 18)	/* GUESS */
+ 
+ /* gap */
+ /* Nodes are stored backwards. The last active node is always stored in
+@@ -877,11 +873,11 @@ I am fairly certain that they are correc
+ #define R300_PFS_TEXI_0                     0x4620
+ #       define R300_FPITX_SRC_SHIFT              0
+ #       define R300_FPITX_SRC_MASK               (31 << 0)
+-#       define R300_FPITX_SRC_CONST              (1 << 5) /* GUESS */
++#       define R300_FPITX_SRC_CONST              (1 << 5)	/* GUESS */
+ #       define R300_FPITX_DST_SHIFT              6
+ #       define R300_FPITX_DST_MASK               (31 << 6)
+ #       define R300_FPITX_IMAGE_SHIFT            11
+-#       define R300_FPITX_IMAGE_MASK             (15 << 11) /* GUESS based on layout and native limits */
++#       define R300_FPITX_IMAGE_MASK             (15 << 11)	/* GUESS based on layout and native limits */
+ /* Unsure if these are opcodes, or some kind of bitfield, but this is how
+  * they were set when I checked
+  */
+@@ -1003,7 +999,7 @@ I am fairly certain that they are correc
+ #       define R300_FPI0_ARGC_SRC1C_LRP          15
+ #       define R300_FPI0_ARGC_ZERO               20
+ #       define R300_FPI0_ARGC_ONE                21
+-#       define R300_FPI0_ARGC_HALF               22 /* GUESS */
++#       define R300_FPI0_ARGC_HALF               22	/* GUESS */
+ #       define R300_FPI0_ARGC_SRC0C_YZX          23
+ #       define R300_FPI0_ARGC_SRC1C_YZX          24
+ #       define R300_FPI0_ARGC_SRC2C_YZX          25
+@@ -1054,20 +1050,20 @@ I am fairly certain that they are correc
+ #       define R300_FPI2_ARGA_SRC1A_LRP          15
+ #       define R300_FPI2_ARGA_ZERO               16
+ #       define R300_FPI2_ARGA_ONE                17
+-#       define R300_FPI2_ARGA_HALF               18 /* GUESS */
++#       define R300_FPI2_ARGA_HALF               18	/* GUESS */
+ 
+ #       define R300_FPI2_ARG0A_SHIFT             0
+ #       define R300_FPI2_ARG0A_MASK              (31 << 0)
+ #       define R300_FPI2_ARG0A_NEG               (1 << 5)
+-#		define R300_FPI2_ARG0A_ABS				 (1 << 6) /* GUESS */
++#		define R300_FPI2_ARG0A_ABS				 (1 << 6)	/* GUESS */
+ #       define R300_FPI2_ARG1A_SHIFT             7
+ #       define R300_FPI2_ARG1A_MASK              (31 << 7)
+ #       define R300_FPI2_ARG1A_NEG               (1 << 12)
+-#		define R300_FPI2_ARG1A_ABS				 (1 << 13) /* GUESS */
++#		define R300_FPI2_ARG1A_ABS				 (1 << 13)	/* GUESS */
+ #       define R300_FPI2_ARG2A_SHIFT             14
+ #       define R300_FPI2_ARG2A_MASK              (31 << 14)
+ #       define R300_FPI2_ARG2A_NEG               (1 << 19)
+-#		define R300_FPI2_ARG2A_ABS				 (1 << 20) /* GUESS */
++#		define R300_FPI2_ARG2A_ABS				 (1 << 20)	/* GUESS */
+ #       define R300_FPI2_SPECIAL_LRP             (1 << 21)
+ #       define R300_FPI2_OUTA_MAD                (0 << 23)
+ #       define R300_FPI2_OUTA_DP4                (1 << 23)
+@@ -1157,26 +1153,26 @@ I am fairly certain that they are correc
+ 
+ /* gap */
+ #define R300_RB3D_COLOROFFSET0              0x4E28
+-#       define R300_COLOROFFSET_MASK             0xFFFFFFF0 /* GUESS */
+-#define R300_RB3D_COLOROFFSET1              0x4E2C /* GUESS */
+-#define R300_RB3D_COLOROFFSET2              0x4E30 /* GUESS */
+-#define R300_RB3D_COLOROFFSET3              0x4E34 /* GUESS */
++#       define R300_COLOROFFSET_MASK             0xFFFFFFF0	/* GUESS */
++#define R300_RB3D_COLOROFFSET1              0x4E2C	/* GUESS */
++#define R300_RB3D_COLOROFFSET2              0x4E30	/* GUESS */
++#define R300_RB3D_COLOROFFSET3              0x4E34	/* GUESS */
+ /* gap */
+ /* Bit 16: Larger tiles
+ // Bit 17: 4x2 tiles
+ // Bit 18: Extremely weird tile like, but some pixels duplicated? */
+ #define R300_RB3D_COLORPITCH0               0x4E38
+-#       define R300_COLORPITCH_MASK              0x00001FF8 /* GUESS */
+-#       define R300_COLOR_TILE_ENABLE            (1 << 16) /* GUESS */
+-#       define R300_COLOR_MICROTILE_ENABLE       (1 << 17) /* GUESS */
+-#       define R300_COLOR_ENDIAN_NO_SWAP         (0 << 18) /* GUESS */
+-#       define R300_COLOR_ENDIAN_WORD_SWAP       (1 << 18) /* GUESS */
+-#       define R300_COLOR_ENDIAN_DWORD_SWAP      (2 << 18) /* GUESS */
++#       define R300_COLORPITCH_MASK              0x00001FF8	/* GUESS */
++#       define R300_COLOR_TILE_ENABLE            (1 << 16)	/* GUESS */
++#       define R300_COLOR_MICROTILE_ENABLE       (1 << 17)	/* GUESS */
++#       define R300_COLOR_ENDIAN_NO_SWAP         (0 << 18)	/* GUESS */
++#       define R300_COLOR_ENDIAN_WORD_SWAP       (1 << 18)	/* GUESS */
++#       define R300_COLOR_ENDIAN_DWORD_SWAP      (2 << 18)	/* GUESS */
+ #       define R300_COLOR_FORMAT_RGB565          (2 << 22)
+ #       define R300_COLOR_FORMAT_ARGB8888        (3 << 22)
+-#define R300_RB3D_COLORPITCH1               0x4E3C /* GUESS */
+-#define R300_RB3D_COLORPITCH2               0x4E40 /* GUESS */
+-#define R300_RB3D_COLORPITCH3               0x4E44 /* GUESS */
++#define R300_RB3D_COLORPITCH1               0x4E3C	/* GUESS */
++#define R300_RB3D_COLORPITCH2               0x4E40	/* GUESS */
++#define R300_RB3D_COLORPITCH3               0x4E44	/* GUESS */
+ 
+ /* gap */
+ /* Guess by Vladimir.
+@@ -1189,8 +1185,8 @@ I am fairly certain that they are correc
+ /* There seems to be no "write only" setting, so use Z-test = ALWAYS for this. */
+ /* Bit (1<<8) is the "test" bit. so plain write is 6  - vd */
+ #define R300_RB3D_ZSTENCIL_CNTL_0                   0x4F00
+-#       define R300_RB3D_Z_DISABLED_1            0x00000010 /* GUESS */
+-#       define R300_RB3D_Z_DISABLED_2            0x00000014 /* GUESS */
++#       define R300_RB3D_Z_DISABLED_1            0x00000010	/* GUESS */
++#       define R300_RB3D_Z_DISABLED_2            0x00000014	/* GUESS */
+ #       define R300_RB3D_Z_TEST                  0x00000012
+ #       define R300_RB3D_Z_TEST_AND_WRITE        0x00000016
+ #       define R300_RB3D_Z_WRITE_ONLY        	 0x00000006
+@@ -1233,8 +1229,6 @@ I am fairly certain that they are correc
+ #	define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT       21
+ #	define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT       24
+ 
+-
+-
+ #define R300_RB3D_ZSTENCIL_CNTL_2                   0x4F08
+ #	define R300_RB3D_ZS2_STENCIL_REF_SHIFT		0
+ #	define R300_RB3D_ZS2_STENCIL_MASK		0xFF
+@@ -1250,12 +1244,12 @@ I am fairly certain that they are correc
+ /* gap */
+ #define R300_RB3D_DEPTHOFFSET               0x4F20
+ #define R300_RB3D_DEPTHPITCH                0x4F24
+-#       define R300_DEPTHPITCH_MASK              0x00001FF8 /* GUESS */
+-#       define R300_DEPTH_TILE_ENABLE            (1 << 16) /* GUESS */
+-#       define R300_DEPTH_MICROTILE_ENABLE       (1 << 17) /* GUESS */
+-#       define R300_DEPTH_ENDIAN_NO_SWAP         (0 << 18) /* GUESS */
+-#       define R300_DEPTH_ENDIAN_WORD_SWAP       (1 << 18) /* GUESS */
+-#       define R300_DEPTH_ENDIAN_DWORD_SWAP      (2 << 18) /* GUESS */
++#       define R300_DEPTHPITCH_MASK              0x00001FF8	/* GUESS */
++#       define R300_DEPTH_TILE_ENABLE            (1 << 16)	/* GUESS */
++#       define R300_DEPTH_MICROTILE_ENABLE       (1 << 17)	/* GUESS */
++#       define R300_DEPTH_ENDIAN_NO_SWAP         (0 << 18)	/* GUESS */
++#       define R300_DEPTH_ENDIAN_WORD_SWAP       (1 << 18)	/* GUESS */
++#       define R300_DEPTH_ENDIAN_DWORD_SWAP      (2 << 18)	/* GUESS */
+ 
+ /* BEGIN: Vertex program instruction set
+ // Every instruction is four dwords long:
+@@ -1295,26 +1289,26 @@ I am fairly certain that they are correc
+ #define R300_VPI_OUT_OP_MIN                     (8 << 0)
+ #define R300_VPI_OUT_OP_SGE                     (9 << 0)
+ #define R300_VPI_OUT_OP_SLT                     (10 << 0)
+-#define R300_VPI_OUT_OP_UNK12                   (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */
++#define R300_VPI_OUT_OP_UNK12                   (12 << 0)	/* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */
+ #define R300_VPI_OUT_OP_EXP                     (65 << 0)
+ #define R300_VPI_OUT_OP_LOG                     (66 << 0)
+-#define R300_VPI_OUT_OP_UNK67                   (67 << 0) /* Used in fog computations, scalar(scalar) */
++#define R300_VPI_OUT_OP_UNK67                   (67 << 0)	/* Used in fog computations, scalar(scalar) */
+ #define R300_VPI_OUT_OP_LIT                     (68 << 0)
+ #define R300_VPI_OUT_OP_POW                     (69 << 0)
+ #define R300_VPI_OUT_OP_RCP                     (70 << 0)
+ #define R300_VPI_OUT_OP_RSQ                     (72 << 0)
+-#define R300_VPI_OUT_OP_UNK73                   (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */
++#define R300_VPI_OUT_OP_UNK73                   (73 << 0)	/* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */
+ #define R300_VPI_OUT_OP_EX2                     (75 << 0)
+ #define R300_VPI_OUT_OP_LG2                     (76 << 0)
+ #define R300_VPI_OUT_OP_MAD_2                   (128 << 0)
+-#define R300_VPI_OUT_OP_UNK129                  (129 << 0) /* all temps, vector(scalar, vector, vector) */
++#define R300_VPI_OUT_OP_UNK129                  (129 << 0)	/* all temps, vector(scalar, vector, vector) */
+ 
+ #define R300_VPI_OUT_REG_CLASS_TEMPORARY        (0 << 8)
+ #define R300_VPI_OUT_REG_CLASS_RESULT           (2 << 8)
+ #define R300_VPI_OUT_REG_CLASS_MASK             (31 << 8)
+ 
+ #define R300_VPI_OUT_REG_INDEX_SHIFT            13
+-#define R300_VPI_OUT_REG_INDEX_MASK             (31 << 13) /* GUESS based on fglrx native limits */
++#define R300_VPI_OUT_REG_INDEX_MASK             (31 << 13)	/* GUESS based on fglrx native limits */
+ 
+ #define R300_VPI_OUT_WRITE_X                    (1 << 20)
+ #define R300_VPI_OUT_WRITE_Y                    (1 << 21)
+@@ -1325,10 +1319,10 @@ I am fairly certain that they are correc
+ #define R300_VPI_IN_REG_CLASS_ATTRIBUTE         (1 << 0)
+ #define R300_VPI_IN_REG_CLASS_PARAMETER         (2 << 0)
+ #define R300_VPI_IN_REG_CLASS_NONE              (9 << 0)
+-#define R300_VPI_IN_REG_CLASS_MASK              (31 << 0) /* GUESS */
++#define R300_VPI_IN_REG_CLASS_MASK              (31 << 0)	/* GUESS */
+ 
+ #define R300_VPI_IN_REG_INDEX_SHIFT             5
+-#define R300_VPI_IN_REG_INDEX_MASK              (255 << 5) /* GUESS based on fglrx native limits */
++#define R300_VPI_IN_REG_INDEX_MASK              (255 << 5)	/* GUESS based on fglrx native limits */
+ 
+ /* The R300 can select components from the input register arbitrarily.
+ // Use the following constants, shifted by the component shift you
+@@ -1366,7 +1360,7 @@ I am fairly certain that they are correc
+ #define R300_PRIM_TYPE_RECT_LIST                (8 << 0)
+ #define R300_PRIM_TYPE_3VRT_POINT_LIST          (9 << 0)
+ #define R300_PRIM_TYPE_3VRT_LINE_LIST           (10 << 0)
+-#define R300_PRIM_TYPE_POINT_SPRITES            (11 << 0) // GUESS (based on r200)
++#define R300_PRIM_TYPE_POINT_SPRITES            (11 << 0)	// GUESS (based on r200)
+ #define R300_PRIM_TYPE_LINE_LOOP                (12 << 0)
+ #define R300_PRIM_TYPE_QUADS                    (13 << 0)
+ #define R300_PRIM_TYPE_QUAD_STRIP               (14 << 0)
+@@ -1376,8 +1370,8 @@ I am fairly certain that they are correc
+ #define R300_PRIM_WALK_LIST                     (2 << 4)
+ #define R300_PRIM_WALK_RING                     (3 << 4)
+ #define R300_PRIM_WALK_MASK                     (3 << 4)
+-#define R300_PRIM_COLOR_ORDER_BGRA              (0 << 6) // GUESS (based on r200)
+-#define R300_PRIM_COLOR_ORDER_RGBA              (1 << 6) // GUESS
++#define R300_PRIM_COLOR_ORDER_BGRA              (0 << 6)	// GUESS (based on r200)
++#define R300_PRIM_COLOR_ORDER_RGBA              (1 << 6)	// GUESS
+ #define R300_PRIM_NUM_VERTICES_SHIFT            16
+ 
+ // Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR.
+@@ -1409,4 +1403,4 @@ I am fairly certain that they are correc
+ 
+ //END
+ 
+-#endif /* _R300_REG_H */
++#endif				/* _R300_REG_H */
+diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
+--- a/drivers/char/drm/radeon_cp.c
++++ b/drivers/char/drm/radeon_cp.c
+@@ -36,788 +36,787 @@
+ 
+ #define RADEON_FIFO_DEBUG	0
+ 
+-static int radeon_do_cleanup_cp( drm_device_t *dev );
++static int radeon_do_cleanup_cp(drm_device_t * dev);
+ 
+ /* CP microcode (from ATI) */
+ static u32 R200_cp_microcode[][2] = {
+-	{ 0x21007000, 0000000000 },        
+-	{ 0x20007000, 0000000000 }, 
+-	{ 0x000000ab, 0x00000004 },
+-	{ 0x000000af, 0x00000004 },
+-	{ 0x66544a49, 0000000000 },
+-	{ 0x49494174, 0000000000 },
+-	{ 0x54517d83, 0000000000 },
+-	{ 0x498d8b64, 0000000000 },
+-	{ 0x49494949, 0000000000 },
+-	{ 0x49da493c, 0000000000 },
+-	{ 0x49989898, 0000000000 },
+-	{ 0xd34949d5, 0000000000 },
+-	{ 0x9dc90e11, 0000000000 },
+-	{ 0xce9b9b9b, 0000000000 },
+-	{ 0x000f0000, 0x00000016 },
+-	{ 0x352e232c, 0000000000 },
+-	{ 0x00000013, 0x00000004 },
+-	{ 0x000f0000, 0x00000016 },
+-	{ 0x352e272c, 0000000000 },
+-	{ 0x000f0001, 0x00000016 },
+-	{ 0x3239362f, 0000000000 },
+-	{ 0x000077ef, 0x00000002 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x00000020, 0x0000001a },
+-	{ 0x00004000, 0x0000001e },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x00000020, 0x0000001a },
+-	{ 0x00004000, 0x0000001e },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x00000020, 0x0000001a },
+-	{ 0x00004000, 0x0000001e },
+-	{ 0x00000016, 0x00000004 },
+-	{ 0x0003802a, 0x00000002 },
+-	{ 0x040067e0, 0x00000002 },
+-	{ 0x00000016, 0x00000004 },
+-	{ 0x000077e0, 0x00000002 },
+-	{ 0x00065000, 0x00000002 },
+-	{ 0x000037e1, 0x00000002 },
+-	{ 0x040067e1, 0x00000006 },
+-	{ 0x000077e0, 0x00000002 },
+-	{ 0x000077e1, 0x00000002 },
+-	{ 0x000077e1, 0x00000006 },
+-	{ 0xffffffff, 0000000000 },
+-	{ 0x10000000, 0000000000 },
+-	{ 0x0003802a, 0x00000002 },
+-	{ 0x040067e0, 0x00000006 },
+-	{ 0x00007675, 0x00000002 },
+-	{ 0x00007676, 0x00000002 },
+-	{ 0x00007677, 0x00000002 },
+-	{ 0x00007678, 0x00000006 },
+-	{ 0x0003802b, 0x00000002 },
+-	{ 0x04002676, 0x00000002 },
+-	{ 0x00007677, 0x00000002 },
+-	{ 0x00007678, 0x00000006 },
+-	{ 0x0000002e, 0x00000018 },
+-	{ 0x0000002e, 0x00000018 },
+-	{ 0000000000, 0x00000006 },
+-	{ 0x0000002f, 0x00000018 },
+-	{ 0x0000002f, 0x00000018 },
+-	{ 0000000000, 0x00000006 },
+-	{ 0x01605000, 0x00000002 },
+-	{ 0x00065000, 0x00000002 },
+-	{ 0x00098000, 0x00000002 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x64c0603d, 0x00000004 },
+-	{ 0x00080000, 0x00000016 },
+-	{ 0000000000, 0000000000 },
+-	{ 0x0400251d, 0x00000002 },
+-	{ 0x00007580, 0x00000002 },
+-	{ 0x00067581, 0x00000002 },
+-	{ 0x04002580, 0x00000002 },
+-	{ 0x00067581, 0x00000002 },
+-	{ 0x00000046, 0x00000004 },
+-	{ 0x00005000, 0000000000 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x0000750e, 0x00000002 },
+-	{ 0x00019000, 0x00000002 },
+-	{ 0x00011055, 0x00000014 },
+-	{ 0x00000055, 0x00000012 },
+-	{ 0x0400250f, 0x00000002 },
+-	{ 0x0000504a, 0x00000004 },
+-	{ 0x00007565, 0x00000002 },
+-	{ 0x00007566, 0x00000002 },
+-	{ 0x00000051, 0x00000004 },
+-	{ 0x01e655b4, 0x00000002 },
+-	{ 0x4401b0dc, 0x00000002 },
+-	{ 0x01c110dc, 0x00000002 },
+-	{ 0x2666705d, 0x00000018 },
+-	{ 0x040c2565, 0x00000002 },
+-	{ 0x0000005d, 0x00000018 },
+-	{ 0x04002564, 0x00000002 },
+-	{ 0x00007566, 0x00000002 },
+-	{ 0x00000054, 0x00000004 },
+-	{ 0x00401060, 0x00000008 },
+-	{ 0x00101000, 0x00000002 },
+-	{ 0x000d80ff, 0x00000002 },
+-	{ 0x00800063, 0x00000008 },
+-	{ 0x000f9000, 0x00000002 },
+-	{ 0x000e00ff, 0x00000002 },
+-	{ 0000000000, 0x00000006 },
+-	{ 0x00000080, 0x00000018 },
+-	{ 0x00000054, 0x00000004 },
+-	{ 0x00007576, 0x00000002 },
+-	{ 0x00065000, 0x00000002 },
+-	{ 0x00009000, 0x00000002 },
+-	{ 0x00041000, 0x00000002 },
+-	{ 0x0c00350e, 0x00000002 },
+-	{ 0x00049000, 0x00000002 },
+-	{ 0x00051000, 0x00000002 },
+-	{ 0x01e785f8, 0x00000002 },
+-	{ 0x00200000, 0x00000002 },
+-	{ 0x00600073, 0x0000000c },
+-	{ 0x00007563, 0x00000002 },
+-	{ 0x006075f0, 0x00000021 },
+-	{ 0x20007068, 0x00000004 },
+-	{ 0x00005068, 0x00000004 },
+-	{ 0x00007576, 0x00000002 },
+-	{ 0x00007577, 0x00000002 },
+-	{ 0x0000750e, 0x00000002 },
+-	{ 0x0000750f, 0x00000002 },
+-	{ 0x00a05000, 0x00000002 },
+-	{ 0x00600076, 0x0000000c },
+-	{ 0x006075f0, 0x00000021 },
+-	{ 0x000075f8, 0x00000002 },
+-	{ 0x00000076, 0x00000004 },
+-	{ 0x000a750e, 0x00000002 },
+-	{ 0x0020750f, 0x00000002 },
+-	{ 0x00600079, 0x00000004 },
+-	{ 0x00007570, 0x00000002 },
+-	{ 0x00007571, 0x00000002 },
+-	{ 0x00007572, 0x00000006 },
+-	{ 0x00005000, 0x00000002 },
+-	{ 0x00a05000, 0x00000002 },
+-	{ 0x00007568, 0x00000002 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x00000084, 0x0000000c },
+-	{ 0x00058000, 0x00000002 },
+-	{ 0x0c607562, 0x00000002 },
+-	{ 0x00000086, 0x00000004 },
+-	{ 0x00600085, 0x00000004 },
+-	{ 0x400070dd, 0000000000 },
+-	{ 0x000380dd, 0x00000002 },
+-	{ 0x00000093, 0x0000001c },
+-	{ 0x00065095, 0x00000018 },
+-	{ 0x040025bb, 0x00000002 },
+-	{ 0x00061096, 0x00000018 },
+-	{ 0x040075bc, 0000000000 },
+-	{ 0x000075bb, 0x00000002 },
+-	{ 0x000075bc, 0000000000 },
+-	{ 0x00090000, 0x00000006 },
+-	{ 0x00090000, 0x00000002 },
+-	{ 0x000d8002, 0x00000006 },
+-	{ 0x00005000, 0x00000002 },
+-	{ 0x00007821, 0x00000002 },
+-	{ 0x00007800, 0000000000 },
+-	{ 0x00007821, 0x00000002 },
+-	{ 0x00007800, 0000000000 },
+-	{ 0x01665000, 0x00000002 },
+-	{ 0x000a0000, 0x00000002 },
+-	{ 0x000671cc, 0x00000002 },
+-	{ 0x0286f1cd, 0x00000002 },
+-	{ 0x000000a3, 0x00000010 },
+-	{ 0x21007000, 0000000000 },
+-	{ 0x000000aa, 0x0000001c },
+-	{ 0x00065000, 0x00000002 },
+-	{ 0x000a0000, 0x00000002 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x000b0000, 0x00000002 },
+-	{ 0x38067000, 0x00000002 },
+-	{ 0x000a00a6, 0x00000004 },
+-	{ 0x20007000, 0000000000 },
+-	{ 0x01200000, 0x00000002 },
+-	{ 0x20077000, 0x00000002 },
+-	{ 0x01200000, 0x00000002 },
+-	{ 0x20007000, 0000000000 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x0120751b, 0x00000002 },
+-	{ 0x8040750a, 0x00000002 },
+-	{ 0x8040750b, 0x00000002 },
+-	{ 0x00110000, 0x00000002 },
+-	{ 0x000380dd, 0x00000002 },
+-	{ 0x000000bd, 0x0000001c },
+-	{ 0x00061096, 0x00000018 },
+-	{ 0x844075bd, 0x00000002 },
+-	{ 0x00061095, 0x00000018 },
+-	{ 0x840075bb, 0x00000002 },
+-	{ 0x00061096, 0x00000018 },
+-	{ 0x844075bc, 0x00000002 },
+-	{ 0x000000c0, 0x00000004 },
+-	{ 0x804075bd, 0x00000002 },
+-	{ 0x800075bb, 0x00000002 },
+-	{ 0x804075bc, 0x00000002 },
+-	{ 0x00108000, 0x00000002 },
+-	{ 0x01400000, 0x00000002 },
+-	{ 0x006000c4, 0x0000000c },
+-	{ 0x20c07000, 0x00000020 },
+-	{ 0x000000c6, 0x00000012 },
+-	{ 0x00800000, 0x00000006 },
+-	{ 0x0080751d, 0x00000006 },
+-	{ 0x000025bb, 0x00000002 },
+-	{ 0x000040c0, 0x00000004 },
+-	{ 0x0000775c, 0x00000002 },
+-	{ 0x00a05000, 0x00000002 },
+-	{ 0x00661000, 0x00000002 },
+-	{ 0x0460275d, 0x00000020 },
+-	{ 0x00004000, 0000000000 },
+-	{ 0x00007999, 0x00000002 },
+-	{ 0x00a05000, 0x00000002 },
+-	{ 0x00661000, 0x00000002 },
+-	{ 0x0460299b, 0x00000020 },
+-	{ 0x00004000, 0000000000 },
+-	{ 0x01e00830, 0x00000002 },
+-	{ 0x21007000, 0000000000 },
+-	{ 0x00005000, 0x00000002 },
+-	{ 0x00038042, 0x00000002 },
+-	{ 0x040025e0, 0x00000002 },
+-	{ 0x000075e1, 0000000000 },
+-	{ 0x00000001, 0000000000 },
+-	{ 0x000380d9, 0x00000002 },
+-	{ 0x04007394, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
++	{0x21007000, 0000000000},
++	{0x20007000, 0000000000},
++	{0x000000ab, 0x00000004},
++	{0x000000af, 0x00000004},
++	{0x66544a49, 0000000000},
++	{0x49494174, 0000000000},
++	{0x54517d83, 0000000000},
++	{0x498d8b64, 0000000000},
++	{0x49494949, 0000000000},
++	{0x49da493c, 0000000000},
++	{0x49989898, 0000000000},
++	{0xd34949d5, 0000000000},
++	{0x9dc90e11, 0000000000},
++	{0xce9b9b9b, 0000000000},
++	{0x000f0000, 0x00000016},
++	{0x352e232c, 0000000000},
++	{0x00000013, 0x00000004},
++	{0x000f0000, 0x00000016},
++	{0x352e272c, 0000000000},
++	{0x000f0001, 0x00000016},
++	{0x3239362f, 0000000000},
++	{0x000077ef, 0x00000002},
++	{0x00061000, 0x00000002},
++	{0x00000020, 0x0000001a},
++	{0x00004000, 0x0000001e},
++	{0x00061000, 0x00000002},
++	{0x00000020, 0x0000001a},
++	{0x00004000, 0x0000001e},
++	{0x00061000, 0x00000002},
++	{0x00000020, 0x0000001a},
++	{0x00004000, 0x0000001e},
++	{0x00000016, 0x00000004},
++	{0x0003802a, 0x00000002},
++	{0x040067e0, 0x00000002},
++	{0x00000016, 0x00000004},
++	{0x000077e0, 0x00000002},
++	{0x00065000, 0x00000002},
++	{0x000037e1, 0x00000002},
++	{0x040067e1, 0x00000006},
++	{0x000077e0, 0x00000002},
++	{0x000077e1, 0x00000002},
++	{0x000077e1, 0x00000006},
++	{0xffffffff, 0000000000},
++	{0x10000000, 0000000000},
++	{0x0003802a, 0x00000002},
++	{0x040067e0, 0x00000006},
++	{0x00007675, 0x00000002},
++	{0x00007676, 0x00000002},
++	{0x00007677, 0x00000002},
++	{0x00007678, 0x00000006},
++	{0x0003802b, 0x00000002},
++	{0x04002676, 0x00000002},
++	{0x00007677, 0x00000002},
++	{0x00007678, 0x00000006},
++	{0x0000002e, 0x00000018},
++	{0x0000002e, 0x00000018},
++	{0000000000, 0x00000006},
++	{0x0000002f, 0x00000018},
++	{0x0000002f, 0x00000018},
++	{0000000000, 0x00000006},
++	{0x01605000, 0x00000002},
++	{0x00065000, 0x00000002},
++	{0x00098000, 0x00000002},
++	{0x00061000, 0x00000002},
++	{0x64c0603d, 0x00000004},
++	{0x00080000, 0x00000016},
++	{0000000000, 0000000000},
++	{0x0400251d, 0x00000002},
++	{0x00007580, 0x00000002},
++	{0x00067581, 0x00000002},
++	{0x04002580, 0x00000002},
++	{0x00067581, 0x00000002},
++	{0x00000046, 0x00000004},
++	{0x00005000, 0000000000},
++	{0x00061000, 0x00000002},
++	{0x0000750e, 0x00000002},
++	{0x00019000, 0x00000002},
++	{0x00011055, 0x00000014},
++	{0x00000055, 0x00000012},
++	{0x0400250f, 0x00000002},
++	{0x0000504a, 0x00000004},
++	{0x00007565, 0x00000002},
++	{0x00007566, 0x00000002},
++	{0x00000051, 0x00000004},
++	{0x01e655b4, 0x00000002},
++	{0x4401b0dc, 0x00000002},
++	{0x01c110dc, 0x00000002},
++	{0x2666705d, 0x00000018},
++	{0x040c2565, 0x00000002},
++	{0x0000005d, 0x00000018},
++	{0x04002564, 0x00000002},
++	{0x00007566, 0x00000002},
++	{0x00000054, 0x00000004},
++	{0x00401060, 0x00000008},
++	{0x00101000, 0x00000002},
++	{0x000d80ff, 0x00000002},
++	{0x00800063, 0x00000008},
++	{0x000f9000, 0x00000002},
++	{0x000e00ff, 0x00000002},
++	{0000000000, 0x00000006},
++	{0x00000080, 0x00000018},
++	{0x00000054, 0x00000004},
++	{0x00007576, 0x00000002},
++	{0x00065000, 0x00000002},
++	{0x00009000, 0x00000002},
++	{0x00041000, 0x00000002},
++	{0x0c00350e, 0x00000002},
++	{0x00049000, 0x00000002},
++	{0x00051000, 0x00000002},
++	{0x01e785f8, 0x00000002},
++	{0x00200000, 0x00000002},
++	{0x00600073, 0x0000000c},
++	{0x00007563, 0x00000002},
++	{0x006075f0, 0x00000021},
++	{0x20007068, 0x00000004},
++	{0x00005068, 0x00000004},
++	{0x00007576, 0x00000002},
++	{0x00007577, 0x00000002},
++	{0x0000750e, 0x00000002},
++	{0x0000750f, 0x00000002},
++	{0x00a05000, 0x00000002},
++	{0x00600076, 0x0000000c},
++	{0x006075f0, 0x00000021},
++	{0x000075f8, 0x00000002},
++	{0x00000076, 0x00000004},
++	{0x000a750e, 0x00000002},
++	{0x0020750f, 0x00000002},
++	{0x00600079, 0x00000004},
++	{0x00007570, 0x00000002},
++	{0x00007571, 0x00000002},
++	{0x00007572, 0x00000006},
++	{0x00005000, 0x00000002},
++	{0x00a05000, 0x00000002},
++	{0x00007568, 0x00000002},
++	{0x00061000, 0x00000002},
++	{0x00000084, 0x0000000c},
++	{0x00058000, 0x00000002},
++	{0x0c607562, 0x00000002},
++	{0x00000086, 0x00000004},
++	{0x00600085, 0x00000004},
++	{0x400070dd, 0000000000},
++	{0x000380dd, 0x00000002},
++	{0x00000093, 0x0000001c},
++	{0x00065095, 0x00000018},
++	{0x040025bb, 0x00000002},
++	{0x00061096, 0x00000018},
++	{0x040075bc, 0000000000},
++	{0x000075bb, 0x00000002},
++	{0x000075bc, 0000000000},
++	{0x00090000, 0x00000006},
++	{0x00090000, 0x00000002},
++	{0x000d8002, 0x00000006},
++	{0x00005000, 0x00000002},
++	{0x00007821, 0x00000002},
++	{0x00007800, 0000000000},
++	{0x00007821, 0x00000002},
++	{0x00007800, 0000000000},
++	{0x01665000, 0x00000002},
++	{0x000a0000, 0x00000002},
++	{0x000671cc, 0x00000002},
++	{0x0286f1cd, 0x00000002},
++	{0x000000a3, 0x00000010},
++	{0x21007000, 0000000000},
++	{0x000000aa, 0x0000001c},
++	{0x00065000, 0x00000002},
++	{0x000a0000, 0x00000002},
++	{0x00061000, 0x00000002},
++	{0x000b0000, 0x00000002},
++	{0x38067000, 0x00000002},
++	{0x000a00a6, 0x00000004},
++	{0x20007000, 0000000000},
++	{0x01200000, 0x00000002},
++	{0x20077000, 0x00000002},
++	{0x01200000, 0x00000002},
++	{0x20007000, 0000000000},
++	{0x00061000, 0x00000002},
++	{0x0120751b, 0x00000002},
++	{0x8040750a, 0x00000002},
++	{0x8040750b, 0x00000002},
++	{0x00110000, 0x00000002},
++	{0x000380dd, 0x00000002},
++	{0x000000bd, 0x0000001c},
++	{0x00061096, 0x00000018},
++	{0x844075bd, 0x00000002},
++	{0x00061095, 0x00000018},
++	{0x840075bb, 0x00000002},
++	{0x00061096, 0x00000018},
++	{0x844075bc, 0x00000002},
++	{0x000000c0, 0x00000004},
++	{0x804075bd, 0x00000002},
++	{0x800075bb, 0x00000002},
++	{0x804075bc, 0x00000002},
++	{0x00108000, 0x00000002},
++	{0x01400000, 0x00000002},
++	{0x006000c4, 0x0000000c},
++	{0x20c07000, 0x00000020},
++	{0x000000c6, 0x00000012},
++	{0x00800000, 0x00000006},
++	{0x0080751d, 0x00000006},
++	{0x000025bb, 0x00000002},
++	{0x000040c0, 0x00000004},
++	{0x0000775c, 0x00000002},
++	{0x00a05000, 0x00000002},
++	{0x00661000, 0x00000002},
++	{0x0460275d, 0x00000020},
++	{0x00004000, 0000000000},
++	{0x00007999, 0x00000002},
++	{0x00a05000, 0x00000002},
++	{0x00661000, 0x00000002},
++	{0x0460299b, 0x00000020},
++	{0x00004000, 0000000000},
++	{0x01e00830, 0x00000002},
++	{0x21007000, 0000000000},
++	{0x00005000, 0x00000002},
++	{0x00038042, 0x00000002},
++	{0x040025e0, 0x00000002},
++	{0x000075e1, 0000000000},
++	{0x00000001, 0000000000},
++	{0x000380d9, 0x00000002},
++	{0x04007394, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
+ };
+ 
+-
+ static u32 radeon_cp_microcode[][2] = {
+-	{ 0x21007000, 0000000000 },
+-	{ 0x20007000, 0000000000 },
+-	{ 0x000000b4, 0x00000004 },
+-	{ 0x000000b8, 0x00000004 },
+-	{ 0x6f5b4d4c, 0000000000 },
+-	{ 0x4c4c427f, 0000000000 },
+-	{ 0x5b568a92, 0000000000 },
+-	{ 0x4ca09c6d, 0000000000 },
+-	{ 0xad4c4c4c, 0000000000 },
+-	{ 0x4ce1af3d, 0000000000 },
+-	{ 0xd8afafaf, 0000000000 },
+-	{ 0xd64c4cdc, 0000000000 },
+-	{ 0x4cd10d10, 0000000000 },
+-	{ 0x000f0000, 0x00000016 },
+-	{ 0x362f242d, 0000000000 },
+-	{ 0x00000012, 0x00000004 },
+-	{ 0x000f0000, 0x00000016 },
+-	{ 0x362f282d, 0000000000 },
+-	{ 0x000380e7, 0x00000002 },
+-	{ 0x04002c97, 0x00000002 },
+-	{ 0x000f0001, 0x00000016 },
+-	{ 0x333a3730, 0000000000 },
+-	{ 0x000077ef, 0x00000002 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x00000021, 0x0000001a },
+-	{ 0x00004000, 0x0000001e },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x00000021, 0x0000001a },
+-	{ 0x00004000, 0x0000001e },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x00000021, 0x0000001a },
+-	{ 0x00004000, 0x0000001e },
+-	{ 0x00000017, 0x00000004 },
+-	{ 0x0003802b, 0x00000002 },
+-	{ 0x040067e0, 0x00000002 },
+-	{ 0x00000017, 0x00000004 },
+-	{ 0x000077e0, 0x00000002 },
+-	{ 0x00065000, 0x00000002 },
+-	{ 0x000037e1, 0x00000002 },
+-	{ 0x040067e1, 0x00000006 },
+-	{ 0x000077e0, 0x00000002 },
+-	{ 0x000077e1, 0x00000002 },
+-	{ 0x000077e1, 0x00000006 },
+-	{ 0xffffffff, 0000000000 },
+-	{ 0x10000000, 0000000000 },
+-	{ 0x0003802b, 0x00000002 },
+-	{ 0x040067e0, 0x00000006 },
+-	{ 0x00007675, 0x00000002 },
+-	{ 0x00007676, 0x00000002 },
+-	{ 0x00007677, 0x00000002 },
+-	{ 0x00007678, 0x00000006 },
+-	{ 0x0003802c, 0x00000002 },
+-	{ 0x04002676, 0x00000002 },
+-	{ 0x00007677, 0x00000002 },
+-	{ 0x00007678, 0x00000006 },
+-	{ 0x0000002f, 0x00000018 },
+-	{ 0x0000002f, 0x00000018 },
+-	{ 0000000000, 0x00000006 },
+-	{ 0x00000030, 0x00000018 },
+-	{ 0x00000030, 0x00000018 },
+-	{ 0000000000, 0x00000006 },
+-	{ 0x01605000, 0x00000002 },
+-	{ 0x00065000, 0x00000002 },
+-	{ 0x00098000, 0x00000002 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x64c0603e, 0x00000004 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x00080000, 0x00000016 },
+-	{ 0000000000, 0000000000 },
+-	{ 0x0400251d, 0x00000002 },
+-	{ 0x00007580, 0x00000002 },
+-	{ 0x00067581, 0x00000002 },
+-	{ 0x04002580, 0x00000002 },
+-	{ 0x00067581, 0x00000002 },
+-	{ 0x00000049, 0x00000004 },
+-	{ 0x00005000, 0000000000 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x0000750e, 0x00000002 },
+-	{ 0x00019000, 0x00000002 },
+-	{ 0x00011055, 0x00000014 },
+-	{ 0x00000055, 0x00000012 },
+-	{ 0x0400250f, 0x00000002 },
+-	{ 0x0000504f, 0x00000004 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x00007565, 0x00000002 },
+-	{ 0x00007566, 0x00000002 },
+-	{ 0x00000058, 0x00000004 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x01e655b4, 0x00000002 },
+-	{ 0x4401b0e4, 0x00000002 },
+-	{ 0x01c110e4, 0x00000002 },
+-	{ 0x26667066, 0x00000018 },
+-	{ 0x040c2565, 0x00000002 },
+-	{ 0x00000066, 0x00000018 },
+-	{ 0x04002564, 0x00000002 },
+-	{ 0x00007566, 0x00000002 },
+-	{ 0x0000005d, 0x00000004 },
+-	{ 0x00401069, 0x00000008 },
+-	{ 0x00101000, 0x00000002 },
+-	{ 0x000d80ff, 0x00000002 },
+-	{ 0x0080006c, 0x00000008 },
+-	{ 0x000f9000, 0x00000002 },
+-	{ 0x000e00ff, 0x00000002 },
+-	{ 0000000000, 0x00000006 },
+-	{ 0x0000008f, 0x00000018 },
+-	{ 0x0000005b, 0x00000004 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x00007576, 0x00000002 },
+-	{ 0x00065000, 0x00000002 },
+-	{ 0x00009000, 0x00000002 },
+-	{ 0x00041000, 0x00000002 },
+-	{ 0x0c00350e, 0x00000002 },
+-	{ 0x00049000, 0x00000002 },
+-	{ 0x00051000, 0x00000002 },
+-	{ 0x01e785f8, 0x00000002 },
+-	{ 0x00200000, 0x00000002 },
+-	{ 0x0060007e, 0x0000000c },
+-	{ 0x00007563, 0x00000002 },
+-	{ 0x006075f0, 0x00000021 },
+-	{ 0x20007073, 0x00000004 },
+-	{ 0x00005073, 0x00000004 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x00007576, 0x00000002 },
+-	{ 0x00007577, 0x00000002 },
+-	{ 0x0000750e, 0x00000002 },
+-	{ 0x0000750f, 0x00000002 },
+-	{ 0x00a05000, 0x00000002 },
+-	{ 0x00600083, 0x0000000c },
+-	{ 0x006075f0, 0x00000021 },
+-	{ 0x000075f8, 0x00000002 },
+-	{ 0x00000083, 0x00000004 },
+-	{ 0x000a750e, 0x00000002 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x0020750f, 0x00000002 },
+-	{ 0x00600086, 0x00000004 },
+-	{ 0x00007570, 0x00000002 },
+-	{ 0x00007571, 0x00000002 },
+-	{ 0x00007572, 0x00000006 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x00005000, 0x00000002 },
+-	{ 0x00a05000, 0x00000002 },
+-	{ 0x00007568, 0x00000002 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x00000095, 0x0000000c },
+-	{ 0x00058000, 0x00000002 },
+-	{ 0x0c607562, 0x00000002 },
+-	{ 0x00000097, 0x00000004 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x00600096, 0x00000004 },
+-	{ 0x400070e5, 0000000000 },
+-	{ 0x000380e6, 0x00000002 },
+-	{ 0x040025c5, 0x00000002 },
+-	{ 0x000380e5, 0x00000002 },
+-	{ 0x000000a8, 0x0000001c },
+-	{ 0x000650aa, 0x00000018 },
+-	{ 0x040025bb, 0x00000002 },
+-	{ 0x000610ab, 0x00000018 },
+-	{ 0x040075bc, 0000000000 },
+-	{ 0x000075bb, 0x00000002 },
+-	{ 0x000075bc, 0000000000 },
+-	{ 0x00090000, 0x00000006 },
+-	{ 0x00090000, 0x00000002 },
+-	{ 0x000d8002, 0x00000006 },
+-	{ 0x00007832, 0x00000002 },
+-	{ 0x00005000, 0x00000002 },
+-	{ 0x000380e7, 0x00000002 },
+-	{ 0x04002c97, 0x00000002 },
+-	{ 0x00007820, 0x00000002 },
+-	{ 0x00007821, 0x00000002 },
+-	{ 0x00007800, 0000000000 },
+-	{ 0x01200000, 0x00000002 },
+-	{ 0x20077000, 0x00000002 },
+-	{ 0x01200000, 0x00000002 },
+-	{ 0x20007000, 0x00000002 },
+-	{ 0x00061000, 0x00000002 },
+-	{ 0x0120751b, 0x00000002 },
+-	{ 0x8040750a, 0x00000002 },
+-	{ 0x8040750b, 0x00000002 },
+-	{ 0x00110000, 0x00000002 },
+-	{ 0x000380e5, 0x00000002 },
+-	{ 0x000000c6, 0x0000001c },
+-	{ 0x000610ab, 0x00000018 },
+-	{ 0x844075bd, 0x00000002 },
+-	{ 0x000610aa, 0x00000018 },
+-	{ 0x840075bb, 0x00000002 },
+-	{ 0x000610ab, 0x00000018 },
+-	{ 0x844075bc, 0x00000002 },
+-	{ 0x000000c9, 0x00000004 },
+-	{ 0x804075bd, 0x00000002 },
+-	{ 0x800075bb, 0x00000002 },
+-	{ 0x804075bc, 0x00000002 },
+-	{ 0x00108000, 0x00000002 },
+-	{ 0x01400000, 0x00000002 },
+-	{ 0x006000cd, 0x0000000c },
+-	{ 0x20c07000, 0x00000020 },
+-	{ 0x000000cf, 0x00000012 },
+-	{ 0x00800000, 0x00000006 },
+-	{ 0x0080751d, 0x00000006 },
+-	{ 0000000000, 0000000000 },
+-	{ 0x0000775c, 0x00000002 },
+-	{ 0x00a05000, 0x00000002 },
+-	{ 0x00661000, 0x00000002 },
+-	{ 0x0460275d, 0x00000020 },
+-	{ 0x00004000, 0000000000 },
+-	{ 0x01e00830, 0x00000002 },
+-	{ 0x21007000, 0000000000 },
+-	{ 0x6464614d, 0000000000 },
+-	{ 0x69687420, 0000000000 },
+-	{ 0x00000073, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0x00005000, 0x00000002 },
+-	{ 0x000380d0, 0x00000002 },
+-	{ 0x040025e0, 0x00000002 },
+-	{ 0x000075e1, 0000000000 },
+-	{ 0x00000001, 0000000000 },
+-	{ 0x000380e0, 0x00000002 },
+-	{ 0x04002394, 0x00000002 },
+-	{ 0x00005000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0x00000008, 0000000000 },
+-	{ 0x00000004, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
++	{0x21007000, 0000000000},
++	{0x20007000, 0000000000},
++	{0x000000b4, 0x00000004},
++	{0x000000b8, 0x00000004},
++	{0x6f5b4d4c, 0000000000},
++	{0x4c4c427f, 0000000000},
++	{0x5b568a92, 0000000000},
++	{0x4ca09c6d, 0000000000},
++	{0xad4c4c4c, 0000000000},
++	{0x4ce1af3d, 0000000000},
++	{0xd8afafaf, 0000000000},
++	{0xd64c4cdc, 0000000000},
++	{0x4cd10d10, 0000000000},
++	{0x000f0000, 0x00000016},
++	{0x362f242d, 0000000000},
++	{0x00000012, 0x00000004},
++	{0x000f0000, 0x00000016},
++	{0x362f282d, 0000000000},
++	{0x000380e7, 0x00000002},
++	{0x04002c97, 0x00000002},
++	{0x000f0001, 0x00000016},
++	{0x333a3730, 0000000000},
++	{0x000077ef, 0x00000002},
++	{0x00061000, 0x00000002},
++	{0x00000021, 0x0000001a},
++	{0x00004000, 0x0000001e},
++	{0x00061000, 0x00000002},
++	{0x00000021, 0x0000001a},
++	{0x00004000, 0x0000001e},
++	{0x00061000, 0x00000002},
++	{0x00000021, 0x0000001a},
++	{0x00004000, 0x0000001e},
++	{0x00000017, 0x00000004},
++	{0x0003802b, 0x00000002},
++	{0x040067e0, 0x00000002},
++	{0x00000017, 0x00000004},
++	{0x000077e0, 0x00000002},
++	{0x00065000, 0x00000002},
++	{0x000037e1, 0x00000002},
++	{0x040067e1, 0x00000006},
++	{0x000077e0, 0x00000002},
++	{0x000077e1, 0x00000002},
++	{0x000077e1, 0x00000006},
++	{0xffffffff, 0000000000},
++	{0x10000000, 0000000000},
++	{0x0003802b, 0x00000002},
++	{0x040067e0, 0x00000006},
++	{0x00007675, 0x00000002},
++	{0x00007676, 0x00000002},
++	{0x00007677, 0x00000002},
++	{0x00007678, 0x00000006},
++	{0x0003802c, 0x00000002},
++	{0x04002676, 0x00000002},
++	{0x00007677, 0x00000002},
++	{0x00007678, 0x00000006},
++	{0x0000002f, 0x00000018},
++	{0x0000002f, 0x00000018},
++	{0000000000, 0x00000006},
++	{0x00000030, 0x00000018},
++	{0x00000030, 0x00000018},
++	{0000000000, 0x00000006},
++	{0x01605000, 0x00000002},
++	{0x00065000, 0x00000002},
++	{0x00098000, 0x00000002},
++	{0x00061000, 0x00000002},
++	{0x64c0603e, 0x00000004},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x00080000, 0x00000016},
++	{0000000000, 0000000000},
++	{0x0400251d, 0x00000002},
++	{0x00007580, 0x00000002},
++	{0x00067581, 0x00000002},
++	{0x04002580, 0x00000002},
++	{0x00067581, 0x00000002},
++	{0x00000049, 0x00000004},
++	{0x00005000, 0000000000},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x00061000, 0x00000002},
++	{0x0000750e, 0x00000002},
++	{0x00019000, 0x00000002},
++	{0x00011055, 0x00000014},
++	{0x00000055, 0x00000012},
++	{0x0400250f, 0x00000002},
++	{0x0000504f, 0x00000004},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x00007565, 0x00000002},
++	{0x00007566, 0x00000002},
++	{0x00000058, 0x00000004},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x01e655b4, 0x00000002},
++	{0x4401b0e4, 0x00000002},
++	{0x01c110e4, 0x00000002},
++	{0x26667066, 0x00000018},
++	{0x040c2565, 0x00000002},
++	{0x00000066, 0x00000018},
++	{0x04002564, 0x00000002},
++	{0x00007566, 0x00000002},
++	{0x0000005d, 0x00000004},
++	{0x00401069, 0x00000008},
++	{0x00101000, 0x00000002},
++	{0x000d80ff, 0x00000002},
++	{0x0080006c, 0x00000008},
++	{0x000f9000, 0x00000002},
++	{0x000e00ff, 0x00000002},
++	{0000000000, 0x00000006},
++	{0x0000008f, 0x00000018},
++	{0x0000005b, 0x00000004},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x00007576, 0x00000002},
++	{0x00065000, 0x00000002},
++	{0x00009000, 0x00000002},
++	{0x00041000, 0x00000002},
++	{0x0c00350e, 0x00000002},
++	{0x00049000, 0x00000002},
++	{0x00051000, 0x00000002},
++	{0x01e785f8, 0x00000002},
++	{0x00200000, 0x00000002},
++	{0x0060007e, 0x0000000c},
++	{0x00007563, 0x00000002},
++	{0x006075f0, 0x00000021},
++	{0x20007073, 0x00000004},
++	{0x00005073, 0x00000004},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x00007576, 0x00000002},
++	{0x00007577, 0x00000002},
++	{0x0000750e, 0x00000002},
++	{0x0000750f, 0x00000002},
++	{0x00a05000, 0x00000002},
++	{0x00600083, 0x0000000c},
++	{0x006075f0, 0x00000021},
++	{0x000075f8, 0x00000002},
++	{0x00000083, 0x00000004},
++	{0x000a750e, 0x00000002},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x0020750f, 0x00000002},
++	{0x00600086, 0x00000004},
++	{0x00007570, 0x00000002},
++	{0x00007571, 0x00000002},
++	{0x00007572, 0x00000006},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x00005000, 0x00000002},
++	{0x00a05000, 0x00000002},
++	{0x00007568, 0x00000002},
++	{0x00061000, 0x00000002},
++	{0x00000095, 0x0000000c},
++	{0x00058000, 0x00000002},
++	{0x0c607562, 0x00000002},
++	{0x00000097, 0x00000004},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x00600096, 0x00000004},
++	{0x400070e5, 0000000000},
++	{0x000380e6, 0x00000002},
++	{0x040025c5, 0x00000002},
++	{0x000380e5, 0x00000002},
++	{0x000000a8, 0x0000001c},
++	{0x000650aa, 0x00000018},
++	{0x040025bb, 0x00000002},
++	{0x000610ab, 0x00000018},
++	{0x040075bc, 0000000000},
++	{0x000075bb, 0x00000002},
++	{0x000075bc, 0000000000},
++	{0x00090000, 0x00000006},
++	{0x00090000, 0x00000002},
++	{0x000d8002, 0x00000006},
++	{0x00007832, 0x00000002},
++	{0x00005000, 0x00000002},
++	{0x000380e7, 0x00000002},
++	{0x04002c97, 0x00000002},
++	{0x00007820, 0x00000002},
++	{0x00007821, 0x00000002},
++	{0x00007800, 0000000000},
++	{0x01200000, 0x00000002},
++	{0x20077000, 0x00000002},
++	{0x01200000, 0x00000002},
++	{0x20007000, 0x00000002},
++	{0x00061000, 0x00000002},
++	{0x0120751b, 0x00000002},
++	{0x8040750a, 0x00000002},
++	{0x8040750b, 0x00000002},
++	{0x00110000, 0x00000002},
++	{0x000380e5, 0x00000002},
++	{0x000000c6, 0x0000001c},
++	{0x000610ab, 0x00000018},
++	{0x844075bd, 0x00000002},
++	{0x000610aa, 0x00000018},
++	{0x840075bb, 0x00000002},
++	{0x000610ab, 0x00000018},
++	{0x844075bc, 0x00000002},
++	{0x000000c9, 0x00000004},
++	{0x804075bd, 0x00000002},
++	{0x800075bb, 0x00000002},
++	{0x804075bc, 0x00000002},
++	{0x00108000, 0x00000002},
++	{0x01400000, 0x00000002},
++	{0x006000cd, 0x0000000c},
++	{0x20c07000, 0x00000020},
++	{0x000000cf, 0x00000012},
++	{0x00800000, 0x00000006},
++	{0x0080751d, 0x00000006},
++	{0000000000, 0000000000},
++	{0x0000775c, 0x00000002},
++	{0x00a05000, 0x00000002},
++	{0x00661000, 0x00000002},
++	{0x0460275d, 0x00000020},
++	{0x00004000, 0000000000},
++	{0x01e00830, 0x00000002},
++	{0x21007000, 0000000000},
++	{0x6464614d, 0000000000},
++	{0x69687420, 0000000000},
++	{0x00000073, 0000000000},
++	{0000000000, 0000000000},
++	{0x00005000, 0x00000002},
++	{0x000380d0, 0x00000002},
++	{0x040025e0, 0x00000002},
++	{0x000075e1, 0000000000},
++	{0x00000001, 0000000000},
++	{0x000380e0, 0x00000002},
++	{0x04002394, 0x00000002},
++	{0x00005000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0x00000008, 0000000000},
++	{0x00000004, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
+ };
+ 
+ static u32 R300_cp_microcode[][2] = {
+-	{ 0x4200e000, 0000000000 },
+-	{ 0x4000e000, 0000000000 },
+-	{ 0x000000af, 0x00000008 },
+-	{ 0x000000b3, 0x00000008 },
+-	{ 0x6c5a504f, 0000000000 },
+-	{ 0x4f4f497a, 0000000000 },
+-	{ 0x5a578288, 0000000000 },
+-	{ 0x4f91906a, 0000000000 },
+-	{ 0x4f4f4f4f, 0000000000 },
+-	{ 0x4fe24f44, 0000000000 },
+-	{ 0x4f9c9c9c, 0000000000 },
+-	{ 0xdc4f4fde, 0000000000 },
+-	{ 0xa1cd4f4f, 0000000000 },
+-	{ 0xd29d9d9d, 0000000000 },
+-	{ 0x4f0f9fd7, 0000000000 },
+-	{ 0x000ca000, 0x00000004 },
+-	{ 0x000d0012, 0x00000038 },
+-	{ 0x0000e8b4, 0x00000004 },
+-	{ 0x000d0014, 0x00000038 },
+-	{ 0x0000e8b6, 0x00000004 },
+-	{ 0x000d0016, 0x00000038 },
+-	{ 0x0000e854, 0x00000004 },
+-	{ 0x000d0018, 0x00000038 },
+-	{ 0x0000e855, 0x00000004 },
+-	{ 0x000d001a, 0x00000038 },
+-	{ 0x0000e856, 0x00000004 },
+-	{ 0x000d001c, 0x00000038 },
+-	{ 0x0000e857, 0x00000004 },
+-	{ 0x000d001e, 0x00000038 },
+-	{ 0x0000e824, 0x00000004 },
+-	{ 0x000d0020, 0x00000038 },
+-	{ 0x0000e825, 0x00000004 },
+-	{ 0x000d0022, 0x00000038 },
+-	{ 0x0000e830, 0x00000004 },
+-	{ 0x000d0024, 0x00000038 },
+-	{ 0x0000f0c0, 0x00000004 },
+-	{ 0x000d0026, 0x00000038 },
+-	{ 0x0000f0c1, 0x00000004 },
+-	{ 0x000d0028, 0x00000038 },
+-	{ 0x0000f041, 0x00000004 },
+-	{ 0x000d002a, 0x00000038 },
+-	{ 0x0000f184, 0x00000004 },
+-	{ 0x000d002c, 0x00000038 },
+-	{ 0x0000f185, 0x00000004 },
+-	{ 0x000d002e, 0x00000038 },
+-	{ 0x0000f186, 0x00000004 },
+-	{ 0x000d0030, 0x00000038 },
+-	{ 0x0000f187, 0x00000004 },
+-	{ 0x000d0032, 0x00000038 },
+-	{ 0x0000f180, 0x00000004 },
+-	{ 0x000d0034, 0x00000038 },
+-	{ 0x0000f393, 0x00000004 },
+-	{ 0x000d0036, 0x00000038 },
+-	{ 0x0000f38a, 0x00000004 },
+-	{ 0x000d0038, 0x00000038 },
+-	{ 0x0000f38e, 0x00000004 },
+-	{ 0x0000e821, 0x00000004 },
+-	{ 0x0140a000, 0x00000004 },
+-	{ 0x00000043, 0x00000018 },
+-	{ 0x00cce800, 0x00000004 },
+-	{ 0x001b0001, 0x00000004 },
+-	{ 0x08004800, 0x00000004 },
+-	{ 0x001b0001, 0x00000004 },
+-	{ 0x08004800, 0x00000004 },
+-	{ 0x001b0001, 0x00000004 },
+-	{ 0x08004800, 0x00000004 },
+-	{ 0x0000003a, 0x00000008 },
+-	{ 0x0000a000, 0000000000 },
+-	{ 0x02c0a000, 0x00000004 },
+-	{ 0x000ca000, 0x00000004 },
+-	{ 0x00130000, 0x00000004 },
+-	{ 0x000c2000, 0x00000004 },
+-	{ 0xc980c045, 0x00000008 },
+-	{ 0x2000451d, 0x00000004 },
+-	{ 0x0000e580, 0x00000004 },
+-	{ 0x000ce581, 0x00000004 },
+-	{ 0x08004580, 0x00000004 },
+-	{ 0x000ce581, 0x00000004 },
+-	{ 0x0000004c, 0x00000008 },
+-	{ 0x0000a000, 0000000000 },
+-	{ 0x000c2000, 0x00000004 },
+-	{ 0x0000e50e, 0x00000004 },
+-	{ 0x00032000, 0x00000004 },
+-	{ 0x00022056, 0x00000028 },
+-	{ 0x00000056, 0x00000024 },
+-	{ 0x0800450f, 0x00000004 },
+-	{ 0x0000a050, 0x00000008 },
+-	{ 0x0000e565, 0x00000004 },
+-	{ 0x0000e566, 0x00000004 },
+-	{ 0x00000057, 0x00000008 },
+-	{ 0x03cca5b4, 0x00000004 },
+-	{ 0x05432000, 0x00000004 },
+-	{ 0x00022000, 0x00000004 },
+-	{ 0x4ccce063, 0x00000030 },
+-	{ 0x08274565, 0x00000004 },
+-	{ 0x00000063, 0x00000030 },
+-	{ 0x08004564, 0x00000004 },
+-	{ 0x0000e566, 0x00000004 },
+-	{ 0x0000005a, 0x00000008 },
+-	{ 0x00802066, 0x00000010 },
+-	{ 0x00202000, 0x00000004 },
+-	{ 0x001b00ff, 0x00000004 },
+-	{ 0x01000069, 0x00000010 },
+-	{ 0x001f2000, 0x00000004 },
+-	{ 0x001c00ff, 0x00000004 },
+-	{ 0000000000, 0x0000000c },
+-	{ 0x00000085, 0x00000030 },
+-	{ 0x0000005a, 0x00000008 },
+-	{ 0x0000e576, 0x00000004 },
+-	{ 0x000ca000, 0x00000004 },
+-	{ 0x00012000, 0x00000004 },
+-	{ 0x00082000, 0x00000004 },
+-	{ 0x1800650e, 0x00000004 },
+-	{ 0x00092000, 0x00000004 },
+-	{ 0x000a2000, 0x00000004 },
+-	{ 0x000f0000, 0x00000004 },
+-	{ 0x00400000, 0x00000004 },
+-	{ 0x00000079, 0x00000018 },
+-	{ 0x0000e563, 0x00000004 },
+-	{ 0x00c0e5f9, 0x000000c2 },
+-	{ 0x0000006e, 0x00000008 },
+-	{ 0x0000a06e, 0x00000008 },
+-	{ 0x0000e576, 0x00000004 },
+-	{ 0x0000e577, 0x00000004 },
+-	{ 0x0000e50e, 0x00000004 },
+-	{ 0x0000e50f, 0x00000004 },
+-	{ 0x0140a000, 0x00000004 },
+-	{ 0x0000007c, 0x00000018 },
+-	{ 0x00c0e5f9, 0x000000c2 },
+-	{ 0x0000007c, 0x00000008 },
+-	{ 0x0014e50e, 0x00000004 },
+-	{ 0x0040e50f, 0x00000004 },
+-	{ 0x00c0007f, 0x00000008 },
+-	{ 0x0000e570, 0x00000004 },
+-	{ 0x0000e571, 0x00000004 },
+-	{ 0x0000e572, 0x0000000c },
+-	{ 0x0000a000, 0x00000004 },
+-	{ 0x0140a000, 0x00000004 },
+-	{ 0x0000e568, 0x00000004 },
+-	{ 0x000c2000, 0x00000004 },
+-	{ 0x00000089, 0x00000018 },
+-	{ 0x000b0000, 0x00000004 },
+-	{ 0x18c0e562, 0x00000004 },
+-	{ 0x0000008b, 0x00000008 },
+-	{ 0x00c0008a, 0x00000008 },
+-	{ 0x000700e4, 0x00000004 },
+-	{ 0x00000097, 0x00000038 },
+-	{ 0x000ca099, 0x00000030 },
+-	{ 0x080045bb, 0x00000004 },
+-	{ 0x000c209a, 0x00000030 },
+-	{ 0x0800e5bc, 0000000000 },
+-	{ 0x0000e5bb, 0x00000004 },
+-	{ 0x0000e5bc, 0000000000 },
+-	{ 0x00120000, 0x0000000c },
+-	{ 0x00120000, 0x00000004 },
+-	{ 0x001b0002, 0x0000000c },
+-	{ 0x0000a000, 0x00000004 },
+-	{ 0x0000e821, 0x00000004 },
+-	{ 0x0000e800, 0000000000 },
+-	{ 0x0000e821, 0x00000004 },
+-	{ 0x0000e82e, 0000000000 },
+-	{ 0x02cca000, 0x00000004 },
+-	{ 0x00140000, 0x00000004 },
+-	{ 0x000ce1cc, 0x00000004 },
+-	{ 0x050de1cd, 0x00000004 },
+-	{ 0x000000a7, 0x00000020 },
+-	{ 0x4200e000, 0000000000 },
+-	{ 0x000000ae, 0x00000038 },
+-	{ 0x000ca000, 0x00000004 },
+-	{ 0x00140000, 0x00000004 },
+-	{ 0x000c2000, 0x00000004 },
+-	{ 0x00160000, 0x00000004 },
+-	{ 0x700ce000, 0x00000004 },
+-	{ 0x001400aa, 0x00000008 },
+-	{ 0x4000e000, 0000000000 },
+-	{ 0x02400000, 0x00000004 },
+-	{ 0x400ee000, 0x00000004 },
+-	{ 0x02400000, 0x00000004 },
+-	{ 0x4000e000, 0000000000 },
+-	{ 0x000c2000, 0x00000004 },
+-	{ 0x0240e51b, 0x00000004 },
+-	{ 0x0080e50a, 0x00000005 },
+-	{ 0x0080e50b, 0x00000005 },
+-	{ 0x00220000, 0x00000004 },
+-	{ 0x000700e4, 0x00000004 },
+-	{ 0x000000c1, 0x00000038 },
+-	{ 0x000c209a, 0x00000030 },
+-	{ 0x0880e5bd, 0x00000005 },
+-	{ 0x000c2099, 0x00000030 },
+-	{ 0x0800e5bb, 0x00000005 },
+-	{ 0x000c209a, 0x00000030 },
+-	{ 0x0880e5bc, 0x00000005 },
+-	{ 0x000000c4, 0x00000008 },
+-	{ 0x0080e5bd, 0x00000005 },
+-	{ 0x0000e5bb, 0x00000005 },
+-	{ 0x0080e5bc, 0x00000005 },
+-	{ 0x00210000, 0x00000004 },
+-	{ 0x02800000, 0x00000004 },
+-	{ 0x00c000c8, 0x00000018 },
+-	{ 0x4180e000, 0x00000040 },
+-	{ 0x000000ca, 0x00000024 },
+-	{ 0x01000000, 0x0000000c },
+-	{ 0x0100e51d, 0x0000000c },
+-	{ 0x000045bb, 0x00000004 },
+-	{ 0x000080c4, 0x00000008 },
+-	{ 0x0000f3ce, 0x00000004 },
+-	{ 0x0140a000, 0x00000004 },
+-	{ 0x00cc2000, 0x00000004 },
+-	{ 0x08c053cf, 0x00000040 },
+-	{ 0x00008000, 0000000000 },
+-	{ 0x0000f3d2, 0x00000004 },
+-	{ 0x0140a000, 0x00000004 },
+-	{ 0x00cc2000, 0x00000004 },
+-	{ 0x08c053d3, 0x00000040 },
+-	{ 0x00008000, 0000000000 },
+-	{ 0x0000f39d, 0x00000004 },
+-	{ 0x0140a000, 0x00000004 },
+-	{ 0x00cc2000, 0x00000004 },
+-	{ 0x08c0539e, 0x00000040 },
+-	{ 0x00008000, 0000000000 },
+-	{ 0x03c00830, 0x00000004 },
+-	{ 0x4200e000, 0000000000 },
+-	{ 0x0000a000, 0x00000004 },
+-	{ 0x200045e0, 0x00000004 },
+-	{ 0x0000e5e1, 0000000000 },
+-	{ 0x00000001, 0000000000 },
+-	{ 0x000700e1, 0x00000004 },
+-	{ 0x0800e394, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
+-	{ 0000000000, 0000000000 },
++	{0x4200e000, 0000000000},
++	{0x4000e000, 0000000000},
++	{0x000000af, 0x00000008},
++	{0x000000b3, 0x00000008},
++	{0x6c5a504f, 0000000000},
++	{0x4f4f497a, 0000000000},
++	{0x5a578288, 0000000000},
++	{0x4f91906a, 0000000000},
++	{0x4f4f4f4f, 0000000000},
++	{0x4fe24f44, 0000000000},
++	{0x4f9c9c9c, 0000000000},
++	{0xdc4f4fde, 0000000000},
++	{0xa1cd4f4f, 0000000000},
++	{0xd29d9d9d, 0000000000},
++	{0x4f0f9fd7, 0000000000},
++	{0x000ca000, 0x00000004},
++	{0x000d0012, 0x00000038},
++	{0x0000e8b4, 0x00000004},
++	{0x000d0014, 0x00000038},
++	{0x0000e8b6, 0x00000004},
++	{0x000d0016, 0x00000038},
++	{0x0000e854, 0x00000004},
++	{0x000d0018, 0x00000038},
++	{0x0000e855, 0x00000004},
++	{0x000d001a, 0x00000038},
++	{0x0000e856, 0x00000004},
++	{0x000d001c, 0x00000038},
++	{0x0000e857, 0x00000004},
++	{0x000d001e, 0x00000038},
++	{0x0000e824, 0x00000004},
++	{0x000d0020, 0x00000038},
++	{0x0000e825, 0x00000004},
++	{0x000d0022, 0x00000038},
++	{0x0000e830, 0x00000004},
++	{0x000d0024, 0x00000038},
++	{0x0000f0c0, 0x00000004},
++	{0x000d0026, 0x00000038},
++	{0x0000f0c1, 0x00000004},
++	{0x000d0028, 0x00000038},
++	{0x0000f041, 0x00000004},
++	{0x000d002a, 0x00000038},
++	{0x0000f184, 0x00000004},
++	{0x000d002c, 0x00000038},
++	{0x0000f185, 0x00000004},
++	{0x000d002e, 0x00000038},
++	{0x0000f186, 0x00000004},
++	{0x000d0030, 0x00000038},
++	{0x0000f187, 0x00000004},
++	{0x000d0032, 0x00000038},
++	{0x0000f180, 0x00000004},
++	{0x000d0034, 0x00000038},
++	{0x0000f393, 0x00000004},
++	{0x000d0036, 0x00000038},
++	{0x0000f38a, 0x00000004},
++	{0x000d0038, 0x00000038},
++	{0x0000f38e, 0x00000004},
++	{0x0000e821, 0x00000004},
++	{0x0140a000, 0x00000004},
++	{0x00000043, 0x00000018},
++	{0x00cce800, 0x00000004},
++	{0x001b0001, 0x00000004},
++	{0x08004800, 0x00000004},
++	{0x001b0001, 0x00000004},
++	{0x08004800, 0x00000004},
++	{0x001b0001, 0x00000004},
++	{0x08004800, 0x00000004},
++	{0x0000003a, 0x00000008},
++	{0x0000a000, 0000000000},
++	{0x02c0a000, 0x00000004},
++	{0x000ca000, 0x00000004},
++	{0x00130000, 0x00000004},
++	{0x000c2000, 0x00000004},
++	{0xc980c045, 0x00000008},
++	{0x2000451d, 0x00000004},
++	{0x0000e580, 0x00000004},
++	{0x000ce581, 0x00000004},
++	{0x08004580, 0x00000004},
++	{0x000ce581, 0x00000004},
++	{0x0000004c, 0x00000008},
++	{0x0000a000, 0000000000},
++	{0x000c2000, 0x00000004},
++	{0x0000e50e, 0x00000004},
++	{0x00032000, 0x00000004},
++	{0x00022056, 0x00000028},
++	{0x00000056, 0x00000024},
++	{0x0800450f, 0x00000004},
++	{0x0000a050, 0x00000008},
++	{0x0000e565, 0x00000004},
++	{0x0000e566, 0x00000004},
++	{0x00000057, 0x00000008},
++	{0x03cca5b4, 0x00000004},
++	{0x05432000, 0x00000004},
++	{0x00022000, 0x00000004},
++	{0x4ccce063, 0x00000030},
++	{0x08274565, 0x00000004},
++	{0x00000063, 0x00000030},
++	{0x08004564, 0x00000004},
++	{0x0000e566, 0x00000004},
++	{0x0000005a, 0x00000008},
++	{0x00802066, 0x00000010},
++	{0x00202000, 0x00000004},
++	{0x001b00ff, 0x00000004},
++	{0x01000069, 0x00000010},
++	{0x001f2000, 0x00000004},
++	{0x001c00ff, 0x00000004},
++	{0000000000, 0x0000000c},
++	{0x00000085, 0x00000030},
++	{0x0000005a, 0x00000008},
++	{0x0000e576, 0x00000004},
++	{0x000ca000, 0x00000004},
++	{0x00012000, 0x00000004},
++	{0x00082000, 0x00000004},
++	{0x1800650e, 0x00000004},
++	{0x00092000, 0x00000004},
++	{0x000a2000, 0x00000004},
++	{0x000f0000, 0x00000004},
++	{0x00400000, 0x00000004},
++	{0x00000079, 0x00000018},
++	{0x0000e563, 0x00000004},
++	{0x00c0e5f9, 0x000000c2},
++	{0x0000006e, 0x00000008},
++	{0x0000a06e, 0x00000008},
++	{0x0000e576, 0x00000004},
++	{0x0000e577, 0x00000004},
++	{0x0000e50e, 0x00000004},
++	{0x0000e50f, 0x00000004},
++	{0x0140a000, 0x00000004},
++	{0x0000007c, 0x00000018},
++	{0x00c0e5f9, 0x000000c2},
++	{0x0000007c, 0x00000008},
++	{0x0014e50e, 0x00000004},
++	{0x0040e50f, 0x00000004},
++	{0x00c0007f, 0x00000008},
++	{0x0000e570, 0x00000004},
++	{0x0000e571, 0x00000004},
++	{0x0000e572, 0x0000000c},
++	{0x0000a000, 0x00000004},
++	{0x0140a000, 0x00000004},
++	{0x0000e568, 0x00000004},
++	{0x000c2000, 0x00000004},
++	{0x00000089, 0x00000018},
++	{0x000b0000, 0x00000004},
++	{0x18c0e562, 0x00000004},
++	{0x0000008b, 0x00000008},
++	{0x00c0008a, 0x00000008},
++	{0x000700e4, 0x00000004},
++	{0x00000097, 0x00000038},
++	{0x000ca099, 0x00000030},
++	{0x080045bb, 0x00000004},
++	{0x000c209a, 0x00000030},
++	{0x0800e5bc, 0000000000},
++	{0x0000e5bb, 0x00000004},
++	{0x0000e5bc, 0000000000},
++	{0x00120000, 0x0000000c},
++	{0x00120000, 0x00000004},
++	{0x001b0002, 0x0000000c},
++	{0x0000a000, 0x00000004},
++	{0x0000e821, 0x00000004},
++	{0x0000e800, 0000000000},
++	{0x0000e821, 0x00000004},
++	{0x0000e82e, 0000000000},
++	{0x02cca000, 0x00000004},
++	{0x00140000, 0x00000004},
++	{0x000ce1cc, 0x00000004},
++	{0x050de1cd, 0x00000004},
++	{0x000000a7, 0x00000020},
++	{0x4200e000, 0000000000},
++	{0x000000ae, 0x00000038},
++	{0x000ca000, 0x00000004},
++	{0x00140000, 0x00000004},
++	{0x000c2000, 0x00000004},
++	{0x00160000, 0x00000004},
++	{0x700ce000, 0x00000004},
++	{0x001400aa, 0x00000008},
++	{0x4000e000, 0000000000},
++	{0x02400000, 0x00000004},
++	{0x400ee000, 0x00000004},
++	{0x02400000, 0x00000004},
++	{0x4000e000, 0000000000},
++	{0x000c2000, 0x00000004},
++	{0x0240e51b, 0x00000004},
++	{0x0080e50a, 0x00000005},
++	{0x0080e50b, 0x00000005},
++	{0x00220000, 0x00000004},
++	{0x000700e4, 0x00000004},
++	{0x000000c1, 0x00000038},
++	{0x000c209a, 0x00000030},
++	{0x0880e5bd, 0x00000005},
++	{0x000c2099, 0x00000030},
++	{0x0800e5bb, 0x00000005},
++	{0x000c209a, 0x00000030},
++	{0x0880e5bc, 0x00000005},
++	{0x000000c4, 0x00000008},
++	{0x0080e5bd, 0x00000005},
++	{0x0000e5bb, 0x00000005},
++	{0x0080e5bc, 0x00000005},
++	{0x00210000, 0x00000004},
++	{0x02800000, 0x00000004},
++	{0x00c000c8, 0x00000018},
++	{0x4180e000, 0x00000040},
++	{0x000000ca, 0x00000024},
++	{0x01000000, 0x0000000c},
++	{0x0100e51d, 0x0000000c},
++	{0x000045bb, 0x00000004},
++	{0x000080c4, 0x00000008},
++	{0x0000f3ce, 0x00000004},
++	{0x0140a000, 0x00000004},
++	{0x00cc2000, 0x00000004},
++	{0x08c053cf, 0x00000040},
++	{0x00008000, 0000000000},
++	{0x0000f3d2, 0x00000004},
++	{0x0140a000, 0x00000004},
++	{0x00cc2000, 0x00000004},
++	{0x08c053d3, 0x00000040},
++	{0x00008000, 0000000000},
++	{0x0000f39d, 0x00000004},
++	{0x0140a000, 0x00000004},
++	{0x00cc2000, 0x00000004},
++	{0x08c0539e, 0x00000040},
++	{0x00008000, 0000000000},
++	{0x03c00830, 0x00000004},
++	{0x4200e000, 0000000000},
++	{0x0000a000, 0x00000004},
++	{0x200045e0, 0x00000004},
++	{0x0000e5e1, 0000000000},
++	{0x00000001, 0000000000},
++	{0x000700e1, 0x00000004},
++	{0x0800e394, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
++	{0000000000, 0000000000},
+ };
+ 
+-static int RADEON_READ_PLL(drm_device_t *dev, int addr)
++static int RADEON_READ_PLL(drm_device_t * dev, int addr)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 
+@@ -825,145 +824,148 @@ static int RADEON_READ_PLL(drm_device_t 
+ 	return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
+ }
+ 
++static int RADEON_READ_PCIE(drm_radeon_private_t * dev_priv, int addr)
++{
++	RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
++	return RADEON_READ(RADEON_PCIE_DATA);
++}
++
+ #if RADEON_FIFO_DEBUG
+-static void radeon_status( drm_radeon_private_t *dev_priv )
++static void radeon_status(drm_radeon_private_t * dev_priv)
+ {
+-	printk( "%s:\n", __FUNCTION__ );
+-	printk( "RBBM_STATUS = 0x%08x\n",
+-		(unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) );
+-	printk( "CP_RB_RTPR = 0x%08x\n",
+-		(unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) );
+-	printk( "CP_RB_WTPR = 0x%08x\n",
+-		(unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) );
+-	printk( "AIC_CNTL = 0x%08x\n",
+-		(unsigned int)RADEON_READ( RADEON_AIC_CNTL ) );
+-	printk( "AIC_STAT = 0x%08x\n",
+-		(unsigned int)RADEON_READ( RADEON_AIC_STAT ) );
+-	printk( "AIC_PT_BASE = 0x%08x\n",
+-		(unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) );
+-	printk( "TLB_ADDR = 0x%08x\n",
+-		(unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) );
+-	printk( "TLB_DATA = 0x%08x\n",
+-		(unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) );
++	printk("%s:\n", __FUNCTION__);
++	printk("RBBM_STATUS = 0x%08x\n",
++	       (unsigned int)RADEON_READ(RADEON_RBBM_STATUS));
++	printk("CP_RB_RTPR = 0x%08x\n",
++	       (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR));
++	printk("CP_RB_WTPR = 0x%08x\n",
++	       (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR));
++	printk("AIC_CNTL = 0x%08x\n",
++	       (unsigned int)RADEON_READ(RADEON_AIC_CNTL));
++	printk("AIC_STAT = 0x%08x\n",
++	       (unsigned int)RADEON_READ(RADEON_AIC_STAT));
++	printk("AIC_PT_BASE = 0x%08x\n",
++	       (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE));
++	printk("TLB_ADDR = 0x%08x\n",
++	       (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR));
++	printk("TLB_DATA = 0x%08x\n",
++	       (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA));
+ }
+ #endif
+ 
+-
+ /* ================================================================
+  * Engine, FIFO control
+  */
+ 
+-static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv )
++static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
+ {
+ 	u32 tmp;
+ 	int i;
+ 
+ 	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+ 
+-	tmp  = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT );
++	tmp = RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT);
+ 	tmp |= RADEON_RB2D_DC_FLUSH_ALL;
+-	RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp );
++	RADEON_WRITE(RADEON_RB2D_DSTCACHE_CTLSTAT, tmp);
+ 
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		if ( !(RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT )
+-		       & RADEON_RB2D_DC_BUSY) ) {
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		if (!(RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT)
++		      & RADEON_RB2D_DC_BUSY)) {
+ 			return 0;
+ 		}
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+ #if RADEON_FIFO_DEBUG
+-	DRM_ERROR( "failed!\n" );
+-	radeon_status( dev_priv );
++	DRM_ERROR("failed!\n");
++	radeon_status(dev_priv);
+ #endif
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv,
+-				    int entries )
++static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries)
+ {
+ 	int i;
+ 
+ 	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+ 
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		int slots = ( RADEON_READ( RADEON_RBBM_STATUS )
+-			      & RADEON_RBBM_FIFOCNT_MASK );
+-		if ( slots >= entries ) return 0;
+-		DRM_UDELAY( 1 );
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		int slots = (RADEON_READ(RADEON_RBBM_STATUS)
++			     & RADEON_RBBM_FIFOCNT_MASK);
++		if (slots >= entries)
++			return 0;
++		DRM_UDELAY(1);
+ 	}
+ 
+ #if RADEON_FIFO_DEBUG
+-	DRM_ERROR( "failed!\n" );
+-	radeon_status( dev_priv );
++	DRM_ERROR("failed!\n");
++	radeon_status(dev_priv);
+ #endif
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
++static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
+ {
+ 	int i, ret;
+ 
+ 	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+ 
+-	ret = radeon_do_wait_for_fifo( dev_priv, 64 );
+-	if ( ret ) return ret;
++	ret = radeon_do_wait_for_fifo(dev_priv, 64);
++	if (ret)
++		return ret;
+ 
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		if ( !(RADEON_READ( RADEON_RBBM_STATUS )
+-		       & RADEON_RBBM_ACTIVE) ) {
+-			radeon_do_pixcache_flush( dev_priv );
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		if (!(RADEON_READ(RADEON_RBBM_STATUS)
++		      & RADEON_RBBM_ACTIVE)) {
++			radeon_do_pixcache_flush(dev_priv);
+ 			return 0;
+ 		}
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+ #if RADEON_FIFO_DEBUG
+-	DRM_ERROR( "failed!\n" );
+-	radeon_status( dev_priv );
++	DRM_ERROR("failed!\n");
++	radeon_status(dev_priv);
+ #endif
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-
+ /* ================================================================
+  * CP control, initialization
+  */
+ 
+ /* Load the microcode for the CP */
+-static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
++static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
+ {
+ 	int i;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	radeon_do_wait_for_idle( dev_priv );
++	radeon_do_wait_for_idle(dev_priv);
+ 
+-	RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 );
++	RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
+ 
+-	if (dev_priv->microcode_version==UCODE_R200) {
++	if (dev_priv->microcode_version == UCODE_R200) {
+ 		DRM_INFO("Loading R200 Microcode\n");
+-		for ( i = 0 ; i < 256 ; i++ ) 
+-		{
+-			RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
+-				      R200_cp_microcode[i][1] );
+-			RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
+-				      R200_cp_microcode[i][0] );
++		for (i = 0; i < 256; i++) {
++			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
++				     R200_cp_microcode[i][1]);
++			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
++				     R200_cp_microcode[i][0]);
+ 		}
+-	} else if (dev_priv->microcode_version==UCODE_R300) {
++	} else if (dev_priv->microcode_version == UCODE_R300) {
+ 		DRM_INFO("Loading R300 Microcode\n");
+-		for ( i = 0 ; i < 256 ; i++ ) 
+-		{
+-			RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
+-				      R300_cp_microcode[i][1] );
+-			RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
+-				      R300_cp_microcode[i][0] );
++		for (i = 0; i < 256; i++) {
++			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
++				     R300_cp_microcode[i][1]);
++			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
++				     R300_cp_microcode[i][0]);
+ 		}
+ 	} else {
+-		for ( i = 0 ; i < 256 ; i++ ) {
+-			RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
+-				      radeon_cp_microcode[i][1] );
+-			RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
+-				      radeon_cp_microcode[i][0] );
++		for (i = 0; i < 256; i++) {
++			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
++				     radeon_cp_microcode[i][1]);
++			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
++				     radeon_cp_microcode[i][0]);
+ 		}
+ 	}
+ }
+@@ -972,25 +974,25 @@ static void radeon_cp_load_microcode( dr
+  * prior to a wait for idle, as it informs the engine that the command
+  * stream is ending.
+  */
+-static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
++static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv)
+ {
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ #if 0
+ 	u32 tmp;
+ 
+-	tmp = RADEON_READ( RADEON_CP_RB_WPTR ) | (1 << 31);
+-	RADEON_WRITE( RADEON_CP_RB_WPTR, tmp );
++	tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31);
++	RADEON_WRITE(RADEON_CP_RB_WPTR, tmp);
+ #endif
+ }
+ 
+ /* Wait for the CP to go idle.
+  */
+-int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
++int radeon_do_cp_idle(drm_radeon_private_t * dev_priv)
+ {
+ 	RING_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	BEGIN_RING( 6 );
++	BEGIN_RING(6);
+ 
+ 	RADEON_PURGE_CACHE();
+ 	RADEON_PURGE_ZCACHE();
+@@ -999,23 +1001,23 @@ int radeon_do_cp_idle( drm_radeon_privat
+ 	ADVANCE_RING();
+ 	COMMIT_RING();
+ 
+-	return radeon_do_wait_for_idle( dev_priv );
++	return radeon_do_wait_for_idle(dev_priv);
+ }
+ 
+ /* Start the Command Processor.
+  */
+-static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
++static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
+ {
+ 	RING_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	radeon_do_wait_for_idle( dev_priv );
++	radeon_do_wait_for_idle(dev_priv);
+ 
+-	RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode );
++	RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode);
+ 
+ 	dev_priv->cp_running = 1;
+ 
+-	BEGIN_RING( 6 );
++	BEGIN_RING(6);
+ 
+ 	RADEON_PURGE_CACHE();
+ 	RADEON_PURGE_ZCACHE();
+@@ -1029,14 +1031,14 @@ static void radeon_do_cp_start( drm_rade
+  * commands, so you must wait for the CP command stream to complete
+  * before calling this routine.
+  */
+-static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
++static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
+ {
+ 	u32 cur_read_ptr;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
+-	RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
+-	SET_RING_HEAD( dev_priv, cur_read_ptr );
++	cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
++	RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
++	SET_RING_HEAD(dev_priv, cur_read_ptr);
+ 	dev_priv->ring.tail = cur_read_ptr;
+ }
+ 
+@@ -1044,91 +1046,90 @@ static void radeon_do_cp_reset( drm_rade
+  * commands, so you must flush the command stream and wait for the CP
+  * to go idle before calling this routine.
+  */
+-static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
++static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
+ {
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
++	RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
+ 
+ 	dev_priv->cp_running = 0;
+ }
+ 
+ /* Reset the engine.  This will stop the CP if it is running.
+  */
+-static int radeon_do_engine_reset( drm_device_t *dev )
++static int radeon_do_engine_reset(drm_device_t * dev)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+-	DRM_DEBUG( "\n" );
+-
+-	radeon_do_pixcache_flush( dev_priv );
+-
+-	clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX );
+-	mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL );
++	DRM_DEBUG("\n");
+ 
+-	RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl |
+-					      RADEON_FORCEON_MCLKA |
+-					      RADEON_FORCEON_MCLKB |
+- 					      RADEON_FORCEON_YCLKA |
+-					      RADEON_FORCEON_YCLKB |
+-					      RADEON_FORCEON_MC |
+-					      RADEON_FORCEON_AIC ) );
++	radeon_do_pixcache_flush(dev_priv);
+ 
+-	rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET );
++	clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
++	mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
+ 
+-	RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset |
+-						RADEON_SOFT_RESET_CP |
++	RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
++					    RADEON_FORCEON_MCLKA |
++					    RADEON_FORCEON_MCLKB |
++					    RADEON_FORCEON_YCLKA |
++					    RADEON_FORCEON_YCLKB |
++					    RADEON_FORCEON_MC |
++					    RADEON_FORCEON_AIC));
++
++	rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
++
++	RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
++					      RADEON_SOFT_RESET_CP |
++					      RADEON_SOFT_RESET_HI |
++					      RADEON_SOFT_RESET_SE |
++					      RADEON_SOFT_RESET_RE |
++					      RADEON_SOFT_RESET_PP |
++					      RADEON_SOFT_RESET_E2 |
++					      RADEON_SOFT_RESET_RB));
++	RADEON_READ(RADEON_RBBM_SOFT_RESET);
++	RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
++					      ~(RADEON_SOFT_RESET_CP |
+ 						RADEON_SOFT_RESET_HI |
+ 						RADEON_SOFT_RESET_SE |
+ 						RADEON_SOFT_RESET_RE |
+ 						RADEON_SOFT_RESET_PP |
+ 						RADEON_SOFT_RESET_E2 |
+-						RADEON_SOFT_RESET_RB ) );
+-	RADEON_READ( RADEON_RBBM_SOFT_RESET );
+-	RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset &
+-						~( RADEON_SOFT_RESET_CP |
+-						   RADEON_SOFT_RESET_HI |
+-						   RADEON_SOFT_RESET_SE |
+-						   RADEON_SOFT_RESET_RE |
+-						   RADEON_SOFT_RESET_PP |
+-						   RADEON_SOFT_RESET_E2 |
+-						   RADEON_SOFT_RESET_RB ) ) );
+-	RADEON_READ( RADEON_RBBM_SOFT_RESET );
+-
+-
+-	RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl );
+-	RADEON_WRITE( RADEON_CLOCK_CNTL_INDEX, clock_cntl_index );
+-	RADEON_WRITE( RADEON_RBBM_SOFT_RESET,  rbbm_soft_reset );
++						RADEON_SOFT_RESET_RB)));
++	RADEON_READ(RADEON_RBBM_SOFT_RESET);
++
++	RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
++	RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
++	RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
+ 
+ 	/* Reset the CP ring */
+-	radeon_do_cp_reset( dev_priv );
++	radeon_do_cp_reset(dev_priv);
+ 
+ 	/* The CP is no longer running after an engine reset */
+ 	dev_priv->cp_running = 0;
+ 
+ 	/* Reset any pending vertex, indirect buffers */
+-	radeon_freelist_reset( dev );
++	radeon_freelist_reset(dev);
+ 
+ 	return 0;
+ }
+ 
+-static void radeon_cp_init_ring_buffer( drm_device_t *dev,
+-				        drm_radeon_private_t *dev_priv )
++static void radeon_cp_init_ring_buffer(drm_device_t * dev,
++				       drm_radeon_private_t * dev_priv)
+ {
+ 	u32 ring_start, cur_read_ptr;
+ 	u32 tmp;
+ 
+ 	/* Initialize the memory controller */
+-	RADEON_WRITE( RADEON_MC_FB_LOCATION,
+-		      ( ( dev_priv->gart_vm_start - 1 ) & 0xffff0000 )
+-		    | ( dev_priv->fb_location >> 16 ) );
++	RADEON_WRITE(RADEON_MC_FB_LOCATION,
++		     ((dev_priv->gart_vm_start - 1) & 0xffff0000)
++		     | (dev_priv->fb_location >> 16));
+ 
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci ) {
+-		RADEON_WRITE( RADEON_MC_AGP_LOCATION,
+-			      (((dev_priv->gart_vm_start - 1 +
+-				 dev_priv->gart_size) & 0xffff0000) |
+-			       (dev_priv->gart_vm_start >> 16)) );
++	if (!dev_priv->is_pci) {
++		RADEON_WRITE(RADEON_MC_AGP_LOCATION,
++			     (((dev_priv->gart_vm_start - 1 +
++				dev_priv->gart_size) & 0xffff0000) |
++			      (dev_priv->gart_vm_start >> 16)));
+ 
+ 		ring_start = (dev_priv->cp_ring->offset
+ 			      - dev->agp->base
+@@ -1139,25 +1140,24 @@ static void radeon_cp_init_ring_buffer( 
+ 			      - (unsigned long)dev->sg->virtual
+ 			      + dev_priv->gart_vm_start);
+ 
+-	RADEON_WRITE( RADEON_CP_RB_BASE, ring_start );
++	RADEON_WRITE(RADEON_CP_RB_BASE, ring_start);
+ 
+ 	/* Set the write pointer delay */
+-	RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 );
++	RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0);
+ 
+ 	/* Initialize the ring buffer's read and write pointers */
+-	cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
+-	RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
+-	SET_RING_HEAD( dev_priv, cur_read_ptr );
++	cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
++	RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
++	SET_RING_HEAD(dev_priv, cur_read_ptr);
+ 	dev_priv->ring.tail = cur_read_ptr;
+ 
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci ) {
++	if (!dev_priv->is_pci) {
+ 		/* set RADEON_AGP_BASE here instead of relying on X from user space */
+ 		RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
+-		RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
+-			      dev_priv->ring_rptr->offset
+-			      - dev->agp->base
+-			      + dev_priv->gart_vm_start);
++		RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
++			     dev_priv->ring_rptr->offset
++			     - dev->agp->base + dev_priv->gart_vm_start);
+ 	} else
+ #endif
+ 	{
+@@ -1168,11 +1168,10 @@ static void radeon_cp_init_ring_buffer( 
+ 				(unsigned long)dev->sg->virtual;
+ 		page_ofs = tmp_ofs >> PAGE_SHIFT;
+ 
+-		RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
+-			     entry->busaddr[page_ofs]);
+-		DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
+-			   (unsigned long) entry->busaddr[page_ofs],
+-			   entry->handle + tmp_ofs );
++		RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]);
++		DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n",
++			  (unsigned long)entry->busaddr[page_ofs],
++			  entry->handle + tmp_ofs);
+ 	}
+ 
+ 	/* Initialize the scratch register pointer.  This will cause
+@@ -1182,127 +1181,168 @@ static void radeon_cp_init_ring_buffer( 
+ 	 * We simply put this behind the ring read pointer, this works
+ 	 * with PCI GART as well as (whatever kind of) AGP GART
+ 	 */
+-	RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR )
+-					 + RADEON_SCRATCH_REG_OFFSET );
++	RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
++		     + RADEON_SCRATCH_REG_OFFSET);
+ 
+ 	dev_priv->scratch = ((__volatile__ u32 *)
+ 			     dev_priv->ring_rptr->handle +
+ 			     (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
+ 
+-	RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
++	RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
+ 
+ 	/* Writeback doesn't seem to work everywhere, test it first */
+-	DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 );
+-	RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef );
++	DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
++	RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
+ 
+-	for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) {
+-		if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef )
++	for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
++		if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
++		    0xdeadbeef)
+ 			break;
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+-	if ( tmp < dev_priv->usec_timeout ) {
++	if (tmp < dev_priv->usec_timeout) {
+ 		dev_priv->writeback_works = 1;
+-		DRM_DEBUG( "writeback test succeeded, tmp=%d\n", tmp );
++		DRM_DEBUG("writeback test succeeded, tmp=%d\n", tmp);
+ 	} else {
+ 		dev_priv->writeback_works = 0;
+-		DRM_DEBUG( "writeback test failed\n" );
++		DRM_DEBUG("writeback test failed\n");
++	}
++	if (radeon_no_wb == 1) {
++		dev_priv->writeback_works = 0;
++		DRM_DEBUG("writeback forced off\n");
+ 	}
+ 
+ 	dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
+-	RADEON_WRITE( RADEON_LAST_FRAME_REG,
+-		      dev_priv->sarea_priv->last_frame );
++	RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
+ 
+ 	dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0;
+-	RADEON_WRITE( RADEON_LAST_DISPATCH_REG,
+-		      dev_priv->sarea_priv->last_dispatch );
++	RADEON_WRITE(RADEON_LAST_DISPATCH_REG,
++		     dev_priv->sarea_priv->last_dispatch);
+ 
+ 	dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
+-	RADEON_WRITE( RADEON_LAST_CLEAR_REG,
+-		      dev_priv->sarea_priv->last_clear );
++	RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear);
+ 
+ 	/* Set ring buffer size */
+ #ifdef __BIG_ENDIAN
+-	RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT );
++	RADEON_WRITE(RADEON_CP_RB_CNTL,
++		     dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT);
+ #else
+-	RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
++	RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw);
+ #endif
+ 
+-	radeon_do_wait_for_idle( dev_priv );
++	radeon_do_wait_for_idle(dev_priv);
+ 
+ 	/* Turn on bus mastering */
+-	tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS;
+-	RADEON_WRITE( RADEON_BUS_CNTL, tmp );
++	tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
++	RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ 
+ 	/* Sync everything up */
+-	RADEON_WRITE( RADEON_ISYNC_CNTL,
+-		      (RADEON_ISYNC_ANY2D_IDLE3D |
+-		       RADEON_ISYNC_ANY3D_IDLE2D |
+-		       RADEON_ISYNC_WAIT_IDLEGUI |
+-		       RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
++	RADEON_WRITE(RADEON_ISYNC_CNTL,
++		     (RADEON_ISYNC_ANY2D_IDLE3D |
++		      RADEON_ISYNC_ANY3D_IDLE2D |
++		      RADEON_ISYNC_WAIT_IDLEGUI |
++		      RADEON_ISYNC_CPSCRATCH_IDLEGUI));
++}
++
++/* Enable or disable PCI-E GART on the chip */
++static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
++{
++	u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
++	if (on) {
++
++		DRM_DEBUG("programming pcie %08X %08lX %08X\n",
++			  dev_priv->gart_vm_start,
++			  (long)dev_priv->gart_info.bus_addr,
++			  dev_priv->gart_size);
++		RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO,
++				  dev_priv->gart_vm_start);
++		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE,
++				  dev_priv->gart_info.bus_addr);
++		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO,
++				  dev_priv->gart_vm_start);
++		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO,
++				  dev_priv->gart_vm_start +
++				  dev_priv->gart_size - 1);
++
++		RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0);	/* ?? */
++
++		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
++				  RADEON_PCIE_TX_GART_EN);
++	} else {
++		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
++				  tmp & ~RADEON_PCIE_TX_GART_EN);
++	}
+ }
+ 
+ /* Enable or disable PCI GART on the chip */
+-static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on )
++static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
+ {
+-	u32 tmp	= RADEON_READ( RADEON_AIC_CNTL );
++	u32 tmp = RADEON_READ(RADEON_AIC_CNTL);
+ 
+-	if ( on ) {
+-		RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN );
++	if (dev_priv->flags & CHIP_IS_PCIE) {
++		radeon_set_pciegart(dev_priv, on);
++		return;
++	}
++
++	if (on) {
++		RADEON_WRITE(RADEON_AIC_CNTL,
++			     tmp | RADEON_PCIGART_TRANSLATE_EN);
+ 
+ 		/* set PCI GART page-table base address
+ 		 */
+-		RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart );
++		RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr);
+ 
+ 		/* set address range for PCI address translate
+ 		 */
+-		RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start );
+-		RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start
+-						  + dev_priv->gart_size - 1);
++		RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start);
++		RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start
++			     + dev_priv->gart_size - 1);
+ 
+ 		/* Turn off AGP aperture -- is this required for PCI GART?
+ 		 */
+-		RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
+-		RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
++		RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0);	/* ?? */
++		RADEON_WRITE(RADEON_AGP_COMMAND, 0);	/* clear AGP_COMMAND */
+ 	} else {
+-		RADEON_WRITE( RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN );
++		RADEON_WRITE(RADEON_AIC_CNTL,
++			     tmp & ~RADEON_PCIGART_TRANSLATE_EN);
+ 	}
+ }
+ 
+-static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
++static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	dev_priv->is_pci = init->is_pci;
+ 
+-	if ( dev_priv->is_pci && !dev->sg ) {
+-		DRM_ERROR( "PCI GART memory not allocated!\n" );
++	if (dev_priv->is_pci && !dev->sg) {
++		DRM_ERROR("PCI GART memory not allocated!\n");
+ 		dev->dev_private = (void *)dev_priv;
+ 		radeon_do_cleanup_cp(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	dev_priv->usec_timeout = init->usec_timeout;
+-	if ( dev_priv->usec_timeout < 1 ||
+-	     dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) {
+-		DRM_DEBUG( "TIMEOUT problem!\n" );
++	if (dev_priv->usec_timeout < 1 ||
++	    dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
++		DRM_DEBUG("TIMEOUT problem!\n");
+ 		dev->dev_private = (void *)dev_priv;
+ 		radeon_do_cleanup_cp(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	switch(init->func) {
++	switch (init->func) {
+ 	case RADEON_INIT_R200_CP:
+-		dev_priv->microcode_version=UCODE_R200;
++		dev_priv->microcode_version = UCODE_R200;
+ 		break;
+ 	case RADEON_INIT_R300_CP:
+-		dev_priv->microcode_version=UCODE_R300;
++		dev_priv->microcode_version = UCODE_R300;
+ 		break;
+ 	default:
+-		dev_priv->microcode_version=UCODE_R100;
++		dev_priv->microcode_version = UCODE_R100;
+ 	}
+-	
++
+ 	dev_priv->do_boxes = 0;
+ 	dev_priv->cp_mode = init->cp_mode;
+ 
+@@ -1310,15 +1350,15 @@ static int radeon_do_init_cp( drm_device
+ 	 * but the ring can be in either AGP or PCI space for the ring
+ 	 * read pointer.
+ 	 */
+-	if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) &&
+-	     ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) {
+-		DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode );
++	if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
++	    (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
++		DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
+ 		dev->dev_private = (void *)dev_priv;
+ 		radeon_do_cleanup_cp(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	switch ( init->fb_bpp ) {
++	switch (init->fb_bpp) {
+ 	case 16:
+ 		dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
+ 		break;
+@@ -1327,12 +1367,12 @@ static int radeon_do_init_cp( drm_device
+ 		dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
+ 		break;
+ 	}
+-	dev_priv->front_offset	= init->front_offset;
+-	dev_priv->front_pitch	= init->front_pitch;
+-	dev_priv->back_offset	= init->back_offset;
+-	dev_priv->back_pitch	= init->back_pitch;
++	dev_priv->front_offset = init->front_offset;
++	dev_priv->front_pitch = init->front_pitch;
++	dev_priv->back_offset = init->back_offset;
++	dev_priv->back_pitch = init->back_pitch;
+ 
+-	switch ( init->depth_bpp ) {
++	switch (init->depth_bpp) {
+ 	case 16:
+ 		dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z;
+ 		break;
+@@ -1341,8 +1381,8 @@ static int radeon_do_init_cp( drm_device
+ 		dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z;
+ 		break;
+ 	}
+-	dev_priv->depth_offset	= init->depth_offset;
+-	dev_priv->depth_pitch	= init->depth_pitch;
++	dev_priv->depth_offset = init->depth_offset;
++	dev_priv->depth_pitch = init->depth_pitch;
+ 
+ 	/* Hardware state for depth clears.  Remove this if/when we no
+ 	 * longer clear the depth buffer with a 3D rectangle.  Hard-code
+@@ -1351,16 +1391,16 @@ static int radeon_do_init_cp( drm_device
+ 	 */
+ 	dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
+ 					   (dev_priv->color_fmt << 10) |
+-					   (dev_priv->microcode_version == UCODE_R100 ? RADEON_ZBLOCK16 : 0));
++					   (dev_priv->microcode_version ==
++					    UCODE_R100 ? RADEON_ZBLOCK16 : 0));
+ 
+-	dev_priv->depth_clear.rb3d_zstencilcntl = 
+-		(dev_priv->depth_fmt |
+-		 RADEON_Z_TEST_ALWAYS |
+-		 RADEON_STENCIL_TEST_ALWAYS |
+-		 RADEON_STENCIL_S_FAIL_REPLACE |
+-		 RADEON_STENCIL_ZPASS_REPLACE |
+-		 RADEON_STENCIL_ZFAIL_REPLACE |
+-		 RADEON_Z_WRITE_ENABLE);
++	dev_priv->depth_clear.rb3d_zstencilcntl =
++	    (dev_priv->depth_fmt |
++	     RADEON_Z_TEST_ALWAYS |
++	     RADEON_STENCIL_TEST_ALWAYS |
++	     RADEON_STENCIL_S_FAIL_REPLACE |
++	     RADEON_STENCIL_ZPASS_REPLACE |
++	     RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE);
+ 
+ 	dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW |
+ 					 RADEON_BFACE_SOLID |
+@@ -1382,8 +1422,8 @@ static int radeon_do_init_cp( drm_device
+ 	dev_priv->ring_rptr_offset = init->ring_rptr_offset;
+ 	dev_priv->buffers_offset = init->buffers_offset;
+ 	dev_priv->gart_textures_offset = init->gart_textures_offset;
+-	
+-	if(!dev_priv->sarea) {
++
++	if (!dev_priv->sarea) {
+ 		DRM_ERROR("could not find sarea!\n");
+ 		dev->dev_private = (void *)dev_priv;
+ 		radeon_do_cleanup_cp(dev);
+@@ -1391,21 +1431,21 @@ static int radeon_do_init_cp( drm_device
+ 	}
+ 
+ 	dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
+-	if(!dev_priv->mmio) {
++	if (!dev_priv->mmio) {
+ 		DRM_ERROR("could not find mmio region!\n");
+ 		dev->dev_private = (void *)dev_priv;
+ 		radeon_do_cleanup_cp(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 	dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
+-	if(!dev_priv->cp_ring) {
++	if (!dev_priv->cp_ring) {
+ 		DRM_ERROR("could not find cp ring region!\n");
+ 		dev->dev_private = (void *)dev_priv;
+ 		radeon_do_cleanup_cp(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 	dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
+-	if(!dev_priv->ring_rptr) {
++	if (!dev_priv->ring_rptr) {
+ 		DRM_ERROR("could not find ring read pointer!\n");
+ 		dev->dev_private = (void *)dev_priv;
+ 		radeon_do_cleanup_cp(dev);
+@@ -1413,16 +1453,17 @@ static int radeon_do_init_cp( drm_device
+ 	}
+ 	dev->agp_buffer_token = init->buffers_offset;
+ 	dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+-	if(!dev->agp_buffer_map) {
++	if (!dev->agp_buffer_map) {
+ 		DRM_ERROR("could not find dma buffer region!\n");
+ 		dev->dev_private = (void *)dev_priv;
+ 		radeon_do_cleanup_cp(dev);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( init->gart_textures_offset ) {
+-		dev_priv->gart_textures = drm_core_findmap(dev, init->gart_textures_offset);
+-		if ( !dev_priv->gart_textures ) {
++	if (init->gart_textures_offset) {
++		dev_priv->gart_textures =
++		    drm_core_findmap(dev, init->gart_textures_offset);
++		if (!dev_priv->gart_textures) {
+ 			DRM_ERROR("could not find GART texture region!\n");
+ 			dev->dev_private = (void *)dev_priv;
+ 			radeon_do_cleanup_cp(dev);
+@@ -1431,17 +1472,17 @@ static int radeon_do_init_cp( drm_device
+ 	}
+ 
+ 	dev_priv->sarea_priv =
+-		(drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
+-				       init->sarea_priv_offset);
++	    (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle +
++				    init->sarea_priv_offset);
+ 
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci ) {
+-		drm_core_ioremap( dev_priv->cp_ring, dev );
+-		drm_core_ioremap( dev_priv->ring_rptr, dev );
+-		drm_core_ioremap( dev->agp_buffer_map, dev );
+-		if(!dev_priv->cp_ring->handle ||
+-		   !dev_priv->ring_rptr->handle ||
+-		   !dev->agp_buffer_map->handle) {
++	if (!dev_priv->is_pci) {
++		drm_core_ioremap(dev_priv->cp_ring, dev);
++		drm_core_ioremap(dev_priv->ring_rptr, dev);
++		drm_core_ioremap(dev->agp_buffer_map, dev);
++		if (!dev_priv->cp_ring->handle ||
++		    !dev_priv->ring_rptr->handle ||
++		    !dev->agp_buffer_map->handle) {
+ 			DRM_ERROR("could not find ioremap agp regions!\n");
+ 			dev->dev_private = (void *)dev_priv;
+ 			radeon_do_cleanup_cp(dev);
+@@ -1450,220 +1491,251 @@ static int radeon_do_init_cp( drm_device
+ 	} else
+ #endif
+ 	{
+-		dev_priv->cp_ring->handle =
+-			(void *)dev_priv->cp_ring->offset;
++		dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
+ 		dev_priv->ring_rptr->handle =
+-			(void *)dev_priv->ring_rptr->offset;
+-		dev->agp_buffer_map->handle = (void *)dev->agp_buffer_map->offset;
+-
+-		DRM_DEBUG( "dev_priv->cp_ring->handle %p\n",
+-			   dev_priv->cp_ring->handle );
+-		DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n",
+-			   dev_priv->ring_rptr->handle );
+-		DRM_DEBUG( "dev->agp_buffer_map->handle %p\n",
+-			   dev->agp_buffer_map->handle );
+-	}
+-
+-	dev_priv->fb_location = ( RADEON_READ( RADEON_MC_FB_LOCATION )
+-				& 0xffff ) << 16;
+-
+-	dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) |
+-					( ( dev_priv->front_offset
+-					  + dev_priv->fb_location ) >> 10 ) );
+-
+-	dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) |
+-				       ( ( dev_priv->back_offset
+-					 + dev_priv->fb_location ) >> 10 ) );
+-
+-	dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) |
+-					( ( dev_priv->depth_offset
+-					  + dev_priv->fb_location ) >> 10 ) );
+-
++		    (void *)dev_priv->ring_rptr->offset;
++		dev->agp_buffer_map->handle =
++		    (void *)dev->agp_buffer_map->offset;
++
++		DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
++			  dev_priv->cp_ring->handle);
++		DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
++			  dev_priv->ring_rptr->handle);
++		DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
++			  dev->agp_buffer_map->handle);
++	}
++
++	dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION)
++				 & 0xffff) << 16;
++
++	dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
++					((dev_priv->front_offset
++					  + dev_priv->fb_location) >> 10));
++
++	dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) |
++				       ((dev_priv->back_offset
++					 + dev_priv->fb_location) >> 10));
++
++	dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) |
++					((dev_priv->depth_offset
++					  + dev_priv->fb_location) >> 10));
+ 
+ 	dev_priv->gart_size = init->gart_size;
+ 	dev_priv->gart_vm_start = dev_priv->fb_location
+-				+ RADEON_READ( RADEON_CONFIG_APER_SIZE );
++	    + RADEON_READ(RADEON_CONFIG_APER_SIZE);
+ 
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci )
++	if (!dev_priv->is_pci)
+ 		dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
+-						- dev->agp->base
+-						+ dev_priv->gart_vm_start);
++						 - dev->agp->base
++						 + dev_priv->gart_vm_start);
+ 	else
+ #endif
+ 		dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
+ 					- (unsigned long)dev->sg->virtual
+ 					+ dev_priv->gart_vm_start);
+ 
+-	DRM_DEBUG( "dev_priv->gart_size %d\n",
+-		   dev_priv->gart_size );
+-	DRM_DEBUG( "dev_priv->gart_vm_start 0x%x\n",
+-		   dev_priv->gart_vm_start );
+-	DRM_DEBUG( "dev_priv->gart_buffers_offset 0x%lx\n",
+-		   dev_priv->gart_buffers_offset );
++	DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size);
++	DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start);
++	DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n",
++		  dev_priv->gart_buffers_offset);
+ 
+-	dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle;
+-	dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle
++	dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
++	dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
+ 			      + init->ring_size / sizeof(u32));
+ 	dev_priv->ring.size = init->ring_size;
+-	dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
++	dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
+ 
+-	dev_priv->ring.tail_mask =
+-		(dev_priv->ring.size / sizeof(u32)) - 1;
++	dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
+ 
+ 	dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
+ 
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci ) {
++	if (!dev_priv->is_pci) {
+ 		/* Turn off PCI GART */
+-		radeon_set_pcigart( dev_priv, 0 );
++		radeon_set_pcigart(dev_priv, 0);
+ 	} else
+ #endif
+ 	{
+-		if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart,
+-					    &dev_priv->bus_pci_gart)) {
+-			DRM_ERROR( "failed to init PCI GART!\n" );
++		/* if we have an offset set from userspace */
++		if (dev_priv->pcigart_offset) {
++			dev_priv->gart_info.bus_addr =
++			    dev_priv->pcigart_offset + dev_priv->fb_location;
++			dev_priv->gart_info.addr =
++			    (unsigned long)drm_ioremap(dev_priv->gart_info.
++						       bus_addr,
++						       RADEON_PCIGART_TABLE_SIZE,
++						       dev);
++
++			dev_priv->gart_info.is_pcie =
++			    !!(dev_priv->flags & CHIP_IS_PCIE);
++			dev_priv->gart_info.gart_table_location =
++			    DRM_ATI_GART_FB;
++
++			DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n",
++				  dev_priv->gart_info.addr,
++				  dev_priv->pcigart_offset);
++		} else {
++			dev_priv->gart_info.gart_table_location =
++			    DRM_ATI_GART_MAIN;
++			dev_priv->gart_info.addr =
++			    dev_priv->gart_info.bus_addr = 0;
++			if (dev_priv->flags & CHIP_IS_PCIE) {
++				DRM_ERROR
++				    ("Cannot use PCI Express without GART in FB memory\n");
++				radeon_do_cleanup_cp(dev);
++				return DRM_ERR(EINVAL);
++			}
++		}
++
++		if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
++			DRM_ERROR("failed to init PCI GART!\n");
+ 			dev->dev_private = (void *)dev_priv;
+ 			radeon_do_cleanup_cp(dev);
+ 			return DRM_ERR(ENOMEM);
+ 		}
+ 
+ 		/* Turn on PCI GART */
+-		radeon_set_pcigart( dev_priv, 1 );
++		radeon_set_pcigart(dev_priv, 1);
+ 	}
+ 
+-	radeon_cp_load_microcode( dev_priv );
+-	radeon_cp_init_ring_buffer( dev, dev_priv );
++	radeon_cp_load_microcode(dev_priv);
++	radeon_cp_init_ring_buffer(dev, dev_priv);
+ 
+ 	dev_priv->last_buf = 0;
+ 
+ 	dev->dev_private = (void *)dev_priv;
+ 
+-	radeon_do_engine_reset( dev );
++	radeon_do_engine_reset(dev);
+ 
+ 	return 0;
+ }
+ 
+-static int radeon_do_cleanup_cp( drm_device_t *dev )
++static int radeon_do_cleanup_cp(drm_device_t * dev)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	/* Make sure interrupts are disabled here because the uninstall ioctl
+ 	 * may not have been called from userspace and after dev_private
+ 	 * is freed, it's too late.
+ 	 */
+-	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
++	if (dev->irq_enabled)
++		drm_irq_uninstall(dev);
+ 
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci ) {
+-		if ( dev_priv->cp_ring != NULL )
+-			drm_core_ioremapfree( dev_priv->cp_ring, dev );
+-		if ( dev_priv->ring_rptr != NULL )
+-			drm_core_ioremapfree( dev_priv->ring_rptr, dev );
+-		if ( dev->agp_buffer_map != NULL )
+-		{
+-			drm_core_ioremapfree( dev->agp_buffer_map, dev );
++	if (!dev_priv->is_pci) {
++		if (dev_priv->cp_ring != NULL)
++			drm_core_ioremapfree(dev_priv->cp_ring, dev);
++		if (dev_priv->ring_rptr != NULL)
++			drm_core_ioremapfree(dev_priv->ring_rptr, dev);
++		if (dev->agp_buffer_map != NULL) {
++			drm_core_ioremapfree(dev->agp_buffer_map, dev);
+ 			dev->agp_buffer_map = NULL;
+ 		}
+ 	} else
+ #endif
+ 	{
+-		if (!drm_ati_pcigart_cleanup( dev,
+-					      dev_priv->phys_pci_gart,
+-					      dev_priv->bus_pci_gart ))
+-			DRM_ERROR( "failed to cleanup PCI GART!\n" );
++		if (dev_priv->gart_info.bus_addr)
++			if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
++				DRM_ERROR("failed to cleanup PCI GART!\n");
++
++		if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) {
++			drm_ioremapfree((void *)dev_priv->gart_info.addr,
++					RADEON_PCIGART_TABLE_SIZE, dev);
++			dev_priv->gart_info.addr = 0;
++		}
+ 	}
+-	
++
+ 	/* only clear to the start of flags */
+ 	memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
+ 
+ 	return 0;
+ }
+ 
+-/* This code will reinit the Radeon CP hardware after a resume from disc.  
+- * AFAIK, it would be very difficult to pickle the state at suspend time, so 
++/* This code will reinit the Radeon CP hardware after a resume from disc.
++ * AFAIK, it would be very difficult to pickle the state at suspend time, so
+  * here we make sure that all Radeon hardware initialisation is re-done without
+  * affecting running applications.
+  *
+  * Charl P. Botha <http://cpbotha.net>
+  */
+-static int radeon_do_resume_cp( drm_device_t *dev )
++static int radeon_do_resume_cp(drm_device_t * dev)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "Called with no initialization\n" );
+-		return DRM_ERR( EINVAL );
++	if (!dev_priv) {
++		DRM_ERROR("Called with no initialization\n");
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	DRM_DEBUG("Starting radeon_do_resume_cp()\n");
+ 
+ #if __OS_HAS_AGP
+-	if ( !dev_priv->is_pci ) {
++	if (!dev_priv->is_pci) {
+ 		/* Turn off PCI GART */
+-		radeon_set_pcigart( dev_priv, 0 );
++		radeon_set_pcigart(dev_priv, 0);
+ 	} else
+ #endif
+ 	{
+ 		/* Turn on PCI GART */
+-		radeon_set_pcigart( dev_priv, 1 );
++		radeon_set_pcigart(dev_priv, 1);
+ 	}
+ 
+-	radeon_cp_load_microcode( dev_priv );
+-	radeon_cp_init_ring_buffer( dev, dev_priv );
++	radeon_cp_load_microcode(dev_priv);
++	radeon_cp_init_ring_buffer(dev, dev_priv);
+ 
+-	radeon_do_engine_reset( dev );
++	radeon_do_engine_reset(dev);
+ 
+ 	DRM_DEBUG("radeon_do_resume_cp() complete\n");
+ 
+ 	return 0;
+ }
+ 
+-
+-int radeon_cp_init( DRM_IOCTL_ARGS )
++int radeon_cp_init(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_init_t init;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t __user *)data, sizeof(init) );
++	DRM_COPY_FROM_USER_IOCTL(init, (drm_radeon_init_t __user *) data,
++				 sizeof(init));
+ 
+-	if(init.func == RADEON_INIT_R300_CP)
++	if (init.func == RADEON_INIT_R300_CP)
+ 		r300_init_reg_flags();
+ 
+-	switch ( init.func ) {
++	switch (init.func) {
+ 	case RADEON_INIT_CP:
+ 	case RADEON_INIT_R200_CP:
+ 	case RADEON_INIT_R300_CP:
+-		return radeon_do_init_cp( dev, &init );
++		return radeon_do_init_cp(dev, &init);
+ 	case RADEON_CLEANUP_CP:
+-		return radeon_do_cleanup_cp( dev );
++		return radeon_do_cleanup_cp(dev);
+ 	}
+ 
+ 	return DRM_ERR(EINVAL);
+ }
+ 
+-int radeon_cp_start( DRM_IOCTL_ARGS )
++int radeon_cp_start(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( dev_priv->cp_running ) {
+-		DRM_DEBUG( "%s while CP running\n", __FUNCTION__ );
++	if (dev_priv->cp_running) {
++		DRM_DEBUG("%s while CP running\n", __FUNCTION__);
+ 		return 0;
+ 	}
+-	if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) {
+-		DRM_DEBUG( "%s called with bogus CP mode (%d)\n",
+-			   __FUNCTION__, dev_priv->cp_mode );
++	if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) {
++		DRM_DEBUG("%s called with bogus CP mode (%d)\n",
++			  __FUNCTION__, dev_priv->cp_mode);
+ 		return 0;
+ 	}
+ 
+-	radeon_do_cp_start( dev_priv );
++	radeon_do_cp_start(dev_priv);
+ 
+ 	return 0;
+ }
+@@ -1671,17 +1743,18 @@ int radeon_cp_start( DRM_IOCTL_ARGS )
+ /* Stop the CP.  The engine must have been idled before calling this
+  * routine.
+  */
+-int radeon_cp_stop( DRM_IOCTL_ARGS )
++int radeon_cp_stop(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_cp_stop_t stop;
+ 	int ret;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t __user *)data, sizeof(stop) );
++	DRM_COPY_FROM_USER_IOCTL(stop, (drm_radeon_cp_stop_t __user *) data,
++				 sizeof(stop));
+ 
+ 	if (!dev_priv->cp_running)
+ 		return 0;
+@@ -1689,32 +1762,32 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
+ 	/* Flush any pending CP commands.  This ensures any outstanding
+ 	 * commands are exectuted by the engine before we turn it off.
+ 	 */
+-	if ( stop.flush ) {
+-		radeon_do_cp_flush( dev_priv );
++	if (stop.flush) {
++		radeon_do_cp_flush(dev_priv);
+ 	}
+ 
+ 	/* If we fail to make the engine go idle, we return an error
+ 	 * code so that the DRM ioctl wrapper can try again.
+ 	 */
+-	if ( stop.idle ) {
+-		ret = radeon_do_cp_idle( dev_priv );
+-		if ( ret ) return ret;
++	if (stop.idle) {
++		ret = radeon_do_cp_idle(dev_priv);
++		if (ret)
++			return ret;
+ 	}
+ 
+ 	/* Finally, we can turn off the CP.  If the engine isn't idle,
+ 	 * we will get some dropped triangles as they won't be fully
+ 	 * rendered before the CP is shut down.
+ 	 */
+-	radeon_do_cp_stop( dev_priv );
++	radeon_do_cp_stop(dev_priv);
+ 
+ 	/* Reset the engine */
+-	radeon_do_engine_reset( dev );
++	radeon_do_engine_reset(dev);
+ 
+ 	return 0;
+ }
+ 
+-
+-void radeon_do_release( drm_device_t *dev )
++void radeon_do_release(drm_device_t * dev)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	int i, ret;
+@@ -1722,7 +1795,7 @@ void radeon_do_release( drm_device_t *de
+ 	if (dev_priv) {
+ 		if (dev_priv->cp_running) {
+ 			/* Stop the cp */
+-			while ((ret = radeon_do_cp_idle( dev_priv )) != 0) {
++			while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
+ 				DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
+ #ifdef __linux__
+ 				schedule();
+@@ -1730,47 +1803,49 @@ void radeon_do_release( drm_device_t *de
+ 				tsleep(&ret, PZERO, "rdnrel", 1);
+ #endif
+ 			}
+-			radeon_do_cp_stop( dev_priv );
+-			radeon_do_engine_reset( dev );
++			radeon_do_cp_stop(dev_priv);
++			radeon_do_engine_reset(dev);
+ 		}
+ 
+ 		/* Disable *all* interrupts */
+ 		if (dev_priv->mmio)	/* remove this after permanent addmaps */
+-			RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
++			RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
+ 
+-		if (dev_priv->mmio) {/* remove all surfaces */
++		if (dev_priv->mmio) {	/* remove all surfaces */
+ 			for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+-				RADEON_WRITE(RADEON_SURFACE0_INFO + 16*i, 0);
+-				RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*i, 0);
+-				RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*i, 0);
++				RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
++				RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
++					     16 * i, 0);
++				RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
++					     16 * i, 0);
+ 			}
+ 		}
+ 
+ 		/* Free memory heap structures */
+-		radeon_mem_takedown( &(dev_priv->gart_heap) );
+-		radeon_mem_takedown( &(dev_priv->fb_heap) );
++		radeon_mem_takedown(&(dev_priv->gart_heap));
++		radeon_mem_takedown(&(dev_priv->fb_heap));
+ 
+ 		/* deallocate kernel resources */
+-		radeon_do_cleanup_cp( dev );
++		radeon_do_cleanup_cp(dev);
+ 	}
+ }
+ 
+ /* Just reset the CP ring.  Called as part of an X Server engine reset.
+  */
+-int radeon_cp_reset( DRM_IOCTL_ARGS )
++int radeon_cp_reset(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_DEBUG("%s called before init done\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	radeon_do_cp_reset( dev_priv );
++	radeon_do_cp_reset(dev_priv);
+ 
+ 	/* The CP is no longer running after an engine reset */
+ 	dev_priv->cp_running = 0;
+@@ -1778,50 +1853,47 @@ int radeon_cp_reset( DRM_IOCTL_ARGS )
+ 	return 0;
+ }
+ 
+-int radeon_cp_idle( DRM_IOCTL_ARGS )
++int radeon_cp_idle(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	return radeon_do_cp_idle( dev_priv );
++	return radeon_do_cp_idle(dev_priv);
+ }
+ 
+ /* Added by Charl P. Botha to call radeon_do_resume_cp().
+  */
+-int radeon_cp_resume( DRM_IOCTL_ARGS )
++int radeon_cp_resume(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 
+ 	return radeon_do_resume_cp(dev);
+ }
+ 
+-
+-int radeon_engine_reset( DRM_IOCTL_ARGS )
++int radeon_engine_reset(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	return radeon_do_engine_reset( dev );
++	return radeon_do_engine_reset(dev);
+ }
+ 
+-
+ /* ================================================================
+  * Fullscreen mode
+  */
+ 
+ /* KW: Deprecated to say the least:
+  */
+-int radeon_fullscreen( DRM_IOCTL_ARGS )
++int radeon_fullscreen(DRM_IOCTL_ARGS)
+ {
+ 	return 0;
+ }
+ 
+-
+ /* ================================================================
+  * Freelist management
+  */
+@@ -1830,20 +1902,20 @@ int radeon_fullscreen( DRM_IOCTL_ARGS )
+  *   bufs until freelist code is used.  Note this hides a problem with
+  *   the scratch register * (used to keep track of last buffer
+  *   completed) being written to before * the last buffer has actually
+- *   completed rendering.  
++ *   completed rendering.
+  *
+  * KW:  It's also a good way to find free buffers quickly.
+  *
+  * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't
+  * sleep.  However, bugs in older versions of radeon_accel.c mean that
+  * we essentially have to do this, else old clients will break.
+- * 
++ *
+  * However, it does leave open a potential deadlock where all the
+  * buffers are held by other clients, which can't release them because
+- * they can't get the lock.  
++ * they can't get the lock.
+  */
+ 
+-drm_buf_t *radeon_freelist_get( drm_device_t *dev )
++drm_buf_t *radeon_freelist_get(drm_device_t * dev)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+@@ -1852,19 +1924,19 @@ drm_buf_t *radeon_freelist_get( drm_devi
+ 	int i, t;
+ 	int start;
+ 
+-	if ( ++dev_priv->last_buf >= dma->buf_count )
++	if (++dev_priv->last_buf >= dma->buf_count)
+ 		dev_priv->last_buf = 0;
+ 
+ 	start = dev_priv->last_buf;
+ 
+-	for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
+-		u32 done_age = GET_SCRATCH( 1 );
+-		DRM_DEBUG("done_age = %d\n",done_age);
+-		for ( i = start ; i < dma->buf_count ; i++ ) {
++	for (t = 0; t < dev_priv->usec_timeout; t++) {
++		u32 done_age = GET_SCRATCH(1);
++		DRM_DEBUG("done_age = %d\n", done_age);
++		for (i = start; i < dma->buf_count; i++) {
+ 			buf = dma->buflist[i];
+ 			buf_priv = buf->dev_private;
+-			if ( buf->filp == 0 || (buf->pending && 
+-					       buf_priv->age <= done_age) ) {
++			if (buf->filp == 0 || (buf->pending &&
++					       buf_priv->age <= done_age)) {
+ 				dev_priv->stats.requested_bufs++;
+ 				buf->pending = 0;
+ 				return buf;
+@@ -1873,16 +1945,17 @@ drm_buf_t *radeon_freelist_get( drm_devi
+ 		}
+ 
+ 		if (t) {
+-			DRM_UDELAY( 1 );
++			DRM_UDELAY(1);
+ 			dev_priv->stats.freelist_loops++;
+ 		}
+ 	}
+ 
+-	DRM_DEBUG( "returning NULL!\n" );
++	DRM_DEBUG("returning NULL!\n");
+ 	return NULL;
+ }
++
+ #if 0
+-drm_buf_t *radeon_freelist_get( drm_device_t *dev )
++drm_buf_t *radeon_freelist_get(drm_device_t * dev)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+@@ -1892,18 +1965,18 @@ drm_buf_t *radeon_freelist_get( drm_devi
+ 	int start;
+ 	u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
+ 
+-	if ( ++dev_priv->last_buf >= dma->buf_count )
++	if (++dev_priv->last_buf >= dma->buf_count)
+ 		dev_priv->last_buf = 0;
+ 
+ 	start = dev_priv->last_buf;
+ 	dev_priv->stats.freelist_loops++;
+-	
+-	for ( t = 0 ; t < 2 ; t++ ) {
+-		for ( i = start ; i < dma->buf_count ; i++ ) {
++
++	for (t = 0; t < 2; t++) {
++		for (i = start; i < dma->buf_count; i++) {
+ 			buf = dma->buflist[i];
+ 			buf_priv = buf->dev_private;
+-			if ( buf->filp == 0 || (buf->pending && 
+-					       buf_priv->age <= done_age) ) {
++			if (buf->filp == 0 || (buf->pending &&
++					       buf_priv->age <= done_age)) {
+ 				dev_priv->stats.requested_bufs++;
+ 				buf->pending = 0;
+ 				return buf;
+@@ -1916,73 +1989,74 @@ drm_buf_t *radeon_freelist_get( drm_devi
+ }
+ #endif
+ 
+-void radeon_freelist_reset( drm_device_t *dev )
++void radeon_freelist_reset(drm_device_t * dev)
+ {
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	int i;
+ 
+ 	dev_priv->last_buf = 0;
+-	for ( i = 0 ; i < dma->buf_count ; i++ ) {
++	for (i = 0; i < dma->buf_count; i++) {
+ 		drm_buf_t *buf = dma->buflist[i];
+ 		drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
+ 		buf_priv->age = 0;
+ 	}
+ }
+ 
+-
+ /* ================================================================
+  * CP command submission
+  */
+ 
+-int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n )
++int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n)
+ {
+ 	drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
+ 	int i;
+-	u32 last_head = GET_RING_HEAD( dev_priv );
++	u32 last_head = GET_RING_HEAD(dev_priv);
+ 
+-	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+-		u32 head = GET_RING_HEAD( dev_priv );
++	for (i = 0; i < dev_priv->usec_timeout; i++) {
++		u32 head = GET_RING_HEAD(dev_priv);
+ 
+ 		ring->space = (head - ring->tail) * sizeof(u32);
+-		if ( ring->space <= 0 )
++		if (ring->space <= 0)
+ 			ring->space += ring->size;
+-		if ( ring->space > n )
++		if (ring->space > n)
+ 			return 0;
+-		
++
+ 		dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+ 
+ 		if (head != last_head)
+ 			i = 0;
+ 		last_head = head;
+ 
+-		DRM_UDELAY( 1 );
++		DRM_UDELAY(1);
+ 	}
+ 
+ 	/* FIXME: This return value is ignored in the BEGIN_RING macro! */
+ #if RADEON_FIFO_DEBUG
+-	radeon_status( dev_priv );
+-	DRM_ERROR( "failed!\n" );
++	radeon_status(dev_priv);
++	DRM_ERROR("failed!\n");
+ #endif
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-static int radeon_cp_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d )
++static int radeon_cp_get_buffers(DRMFILE filp, drm_device_t * dev,
++				 drm_dma_t * d)
+ {
+ 	int i;
+ 	drm_buf_t *buf;
+ 
+-	for ( i = d->granted_count ; i < d->request_count ; i++ ) {
+-		buf = radeon_freelist_get( dev );
+-		if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */
++	for (i = d->granted_count; i < d->request_count; i++) {
++		buf = radeon_freelist_get(dev);
++		if (!buf)
++			return DRM_ERR(EBUSY);	/* NOTE: broken client */
+ 
+ 		buf->filp = filp;
+ 
+-		if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx,
+-				   sizeof(buf->idx) ) )
++		if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
++				     sizeof(buf->idx)))
+ 			return DRM_ERR(EFAULT);
+-		if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total,
+-				   sizeof(buf->total) ) )
++		if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
++				     sizeof(buf->total)))
+ 			return DRM_ERR(EFAULT);
+ 
+ 		d->granted_count++;
+@@ -1990,7 +2064,7 @@ static int radeon_cp_get_buffers( DRMFIL
+ 	return 0;
+ }
+ 
+-int radeon_cp_buffers( DRM_IOCTL_ARGS )
++int radeon_cp_buffers(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_device_dma_t *dma = dev->dma;
+@@ -1998,33 +2072,33 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS )
+ 	drm_dma_t __user *argp = (void __user *)data;
+ 	drm_dma_t d;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) );
++	DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d));
+ 
+ 	/* Please don't send us buffers.
+ 	 */
+-	if ( d.send_count != 0 ) {
+-		DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
+-			   DRM_CURRENTPID, d.send_count );
++	if (d.send_count != 0) {
++		DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
++			  DRM_CURRENTPID, d.send_count);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	/* We'll send you buffers.
+ 	 */
+-	if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
+-		DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
+-			   DRM_CURRENTPID, d.request_count, dma->buf_count );
++	if (d.request_count < 0 || d.request_count > dma->buf_count) {
++		DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
++			  DRM_CURRENTPID, d.request_count, dma->buf_count);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	d.granted_count = 0;
+ 
+-	if ( d.request_count ) {
+-		ret = radeon_cp_get_buffers( filp, dev, &d );
++	if (d.request_count) {
++		ret = radeon_cp_get_buffers(filp, dev, &d);
+ 	}
+ 
+-	DRM_COPY_TO_USER_IOCTL( argp, d, sizeof(d) );
++	DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d));
+ 
+ 	return ret;
+ }
+@@ -2051,13 +2125,16 @@ int radeon_driver_preinit(struct drm_dev
+ 		dev_priv->flags |= CHIP_HAS_HIERZ;
+ 		break;
+ 	default:
+-	/* all other chips have no hierarchical z buffer */
++		/* all other chips have no hierarchical z buffer */
+ 		break;
+ 	}
+ 
+ 	if (drm_device_is_agp(dev))
+ 		dev_priv->flags |= CHIP_IS_AGP;
+-	
++
++	if (drm_device_is_pcie(dev))
++		dev_priv->flags |= CHIP_IS_PCIE;
++
+ 	DRM_DEBUG("%s card detected\n",
+ 		  ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI"));
+ 	return ret;
+diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
+--- a/drivers/char/drm/radeon_drm.h
++++ b/drivers/char/drm/radeon_drm.h
+@@ -57,78 +57,77 @@
+ #define RADEON_UPLOAD_TEX0IMAGES	0x00001000
+ #define RADEON_UPLOAD_TEX1IMAGES	0x00002000
+ #define RADEON_UPLOAD_TEX2IMAGES	0x00004000
+-#define RADEON_UPLOAD_CLIPRECTS		0x00008000 /* handled client-side */
++#define RADEON_UPLOAD_CLIPRECTS		0x00008000	/* handled client-side */
+ #define RADEON_REQUIRE_QUIESCENCE	0x00010000
+-#define RADEON_UPLOAD_ZBIAS		0x00020000 /* version 1.2 and newer */
++#define RADEON_UPLOAD_ZBIAS		0x00020000	/* version 1.2 and newer */
+ #define RADEON_UPLOAD_ALL		0x003effff
+ #define RADEON_UPLOAD_CONTEXT_ALL       0x003e01ff
+ 
+-
+ /* New style per-packet identifiers for use in cmd_buffer ioctl with
+  * the RADEON_EMIT_PACKET command.  Comments relate new packets to old
+  * state bits and the packet size:
+  */
+-#define RADEON_EMIT_PP_MISC                         0 /* context/7 */
+-#define RADEON_EMIT_PP_CNTL                         1 /* context/3 */
+-#define RADEON_EMIT_RB3D_COLORPITCH                 2 /* context/1 */
+-#define RADEON_EMIT_RE_LINE_PATTERN                 3 /* line/2 */
+-#define RADEON_EMIT_SE_LINE_WIDTH                   4 /* line/1 */
+-#define RADEON_EMIT_PP_LUM_MATRIX                   5 /* bumpmap/1 */
+-#define RADEON_EMIT_PP_ROT_MATRIX_0                 6 /* bumpmap/2 */
+-#define RADEON_EMIT_RB3D_STENCILREFMASK             7 /* masks/3 */
+-#define RADEON_EMIT_SE_VPORT_XSCALE                 8 /* viewport/6 */
+-#define RADEON_EMIT_SE_CNTL                         9 /* setup/2 */
+-#define RADEON_EMIT_SE_CNTL_STATUS                  10 /* setup/1 */
+-#define RADEON_EMIT_RE_MISC                         11 /* misc/1 */
+-#define RADEON_EMIT_PP_TXFILTER_0                   12 /* tex0/6 */
+-#define RADEON_EMIT_PP_BORDER_COLOR_0               13 /* tex0/1 */
+-#define RADEON_EMIT_PP_TXFILTER_1                   14 /* tex1/6 */
+-#define RADEON_EMIT_PP_BORDER_COLOR_1               15 /* tex1/1 */
+-#define RADEON_EMIT_PP_TXFILTER_2                   16 /* tex2/6 */
+-#define RADEON_EMIT_PP_BORDER_COLOR_2               17 /* tex2/1 */
+-#define RADEON_EMIT_SE_ZBIAS_FACTOR                 18 /* zbias/2 */
+-#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT           19 /* tcl/11 */
+-#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED   20 /* material/17 */
+-#define R200_EMIT_PP_TXCBLEND_0                     21 /* tex0/4 */
+-#define R200_EMIT_PP_TXCBLEND_1                     22 /* tex1/4 */
+-#define R200_EMIT_PP_TXCBLEND_2                     23 /* tex2/4 */
+-#define R200_EMIT_PP_TXCBLEND_3                     24 /* tex3/4 */
+-#define R200_EMIT_PP_TXCBLEND_4                     25 /* tex4/4 */
+-#define R200_EMIT_PP_TXCBLEND_5                     26 /* tex5/4 */
+-#define R200_EMIT_PP_TXCBLEND_6                     27 /* /4 */
+-#define R200_EMIT_PP_TXCBLEND_7                     28 /* /4 */
+-#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0             29 /* tcl/7 */
+-#define R200_EMIT_TFACTOR_0                         30 /* tf/7 */
+-#define R200_EMIT_VTX_FMT_0                         31 /* vtx/5 */
+-#define R200_EMIT_VAP_CTL                           32 /* vap/1 */
+-#define R200_EMIT_MATRIX_SELECT_0                   33 /* msl/5 */
+-#define R200_EMIT_TEX_PROC_CTL_2                    34 /* tcg/5 */
+-#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL            35 /* tcl/1 */
+-#define R200_EMIT_PP_TXFILTER_0                     36 /* tex0/6 */
+-#define R200_EMIT_PP_TXFILTER_1                     37 /* tex1/6 */
+-#define R200_EMIT_PP_TXFILTER_2                     38 /* tex2/6 */
+-#define R200_EMIT_PP_TXFILTER_3                     39 /* tex3/6 */
+-#define R200_EMIT_PP_TXFILTER_4                     40 /* tex4/6 */
+-#define R200_EMIT_PP_TXFILTER_5                     41 /* tex5/6 */
+-#define R200_EMIT_PP_TXOFFSET_0                     42 /* tex0/1 */
+-#define R200_EMIT_PP_TXOFFSET_1                     43 /* tex1/1 */
+-#define R200_EMIT_PP_TXOFFSET_2                     44 /* tex2/1 */
+-#define R200_EMIT_PP_TXOFFSET_3                     45 /* tex3/1 */
+-#define R200_EMIT_PP_TXOFFSET_4                     46 /* tex4/1 */
+-#define R200_EMIT_PP_TXOFFSET_5                     47 /* tex5/1 */
+-#define R200_EMIT_VTE_CNTL                          48 /* vte/1 */
+-#define R200_EMIT_OUTPUT_VTX_COMP_SEL               49 /* vtx/1 */
+-#define R200_EMIT_PP_TAM_DEBUG3                     50 /* tam/1 */
+-#define R200_EMIT_PP_CNTL_X                         51 /* cst/1 */
+-#define R200_EMIT_RB3D_DEPTHXY_OFFSET               52 /* cst/1 */
+-#define R200_EMIT_RE_AUX_SCISSOR_CNTL               53 /* cst/1 */
+-#define R200_EMIT_RE_SCISSOR_TL_0                   54 /* cst/2 */
+-#define R200_EMIT_RE_SCISSOR_TL_1                   55 /* cst/2 */
+-#define R200_EMIT_RE_SCISSOR_TL_2                   56 /* cst/2 */
+-#define R200_EMIT_SE_VAP_CNTL_STATUS                57 /* cst/1 */
+-#define R200_EMIT_SE_VTX_STATE_CNTL                 58 /* cst/1 */
+-#define R200_EMIT_RE_POINTSIZE                      59 /* cst/1 */
+-#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0       60 /* cst/4 */
++#define RADEON_EMIT_PP_MISC                         0	/* context/7 */
++#define RADEON_EMIT_PP_CNTL                         1	/* context/3 */
++#define RADEON_EMIT_RB3D_COLORPITCH                 2	/* context/1 */
++#define RADEON_EMIT_RE_LINE_PATTERN                 3	/* line/2 */
++#define RADEON_EMIT_SE_LINE_WIDTH                   4	/* line/1 */
++#define RADEON_EMIT_PP_LUM_MATRIX                   5	/* bumpmap/1 */
++#define RADEON_EMIT_PP_ROT_MATRIX_0                 6	/* bumpmap/2 */
++#define RADEON_EMIT_RB3D_STENCILREFMASK             7	/* masks/3 */
++#define RADEON_EMIT_SE_VPORT_XSCALE                 8	/* viewport/6 */
++#define RADEON_EMIT_SE_CNTL                         9	/* setup/2 */
++#define RADEON_EMIT_SE_CNTL_STATUS                  10	/* setup/1 */
++#define RADEON_EMIT_RE_MISC                         11	/* misc/1 */
++#define RADEON_EMIT_PP_TXFILTER_0                   12	/* tex0/6 */
++#define RADEON_EMIT_PP_BORDER_COLOR_0               13	/* tex0/1 */
++#define RADEON_EMIT_PP_TXFILTER_1                   14	/* tex1/6 */
++#define RADEON_EMIT_PP_BORDER_COLOR_1               15	/* tex1/1 */
++#define RADEON_EMIT_PP_TXFILTER_2                   16	/* tex2/6 */
++#define RADEON_EMIT_PP_BORDER_COLOR_2               17	/* tex2/1 */
++#define RADEON_EMIT_SE_ZBIAS_FACTOR                 18	/* zbias/2 */
++#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT           19	/* tcl/11 */
++#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED   20	/* material/17 */
++#define R200_EMIT_PP_TXCBLEND_0                     21	/* tex0/4 */
++#define R200_EMIT_PP_TXCBLEND_1                     22	/* tex1/4 */
++#define R200_EMIT_PP_TXCBLEND_2                     23	/* tex2/4 */
++#define R200_EMIT_PP_TXCBLEND_3                     24	/* tex3/4 */
++#define R200_EMIT_PP_TXCBLEND_4                     25	/* tex4/4 */
++#define R200_EMIT_PP_TXCBLEND_5                     26	/* tex5/4 */
++#define R200_EMIT_PP_TXCBLEND_6                     27	/* /4 */
++#define R200_EMIT_PP_TXCBLEND_7                     28	/* /4 */
++#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0             29	/* tcl/7 */
++#define R200_EMIT_TFACTOR_0                         30	/* tf/7 */
++#define R200_EMIT_VTX_FMT_0                         31	/* vtx/5 */
++#define R200_EMIT_VAP_CTL                           32	/* vap/1 */
++#define R200_EMIT_MATRIX_SELECT_0                   33	/* msl/5 */
++#define R200_EMIT_TEX_PROC_CTL_2                    34	/* tcg/5 */
++#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL            35	/* tcl/1 */
++#define R200_EMIT_PP_TXFILTER_0                     36	/* tex0/6 */
++#define R200_EMIT_PP_TXFILTER_1                     37	/* tex1/6 */
++#define R200_EMIT_PP_TXFILTER_2                     38	/* tex2/6 */
++#define R200_EMIT_PP_TXFILTER_3                     39	/* tex3/6 */
++#define R200_EMIT_PP_TXFILTER_4                     40	/* tex4/6 */
++#define R200_EMIT_PP_TXFILTER_5                     41	/* tex5/6 */
++#define R200_EMIT_PP_TXOFFSET_0                     42	/* tex0/1 */
++#define R200_EMIT_PP_TXOFFSET_1                     43	/* tex1/1 */
++#define R200_EMIT_PP_TXOFFSET_2                     44	/* tex2/1 */
++#define R200_EMIT_PP_TXOFFSET_3                     45	/* tex3/1 */
++#define R200_EMIT_PP_TXOFFSET_4                     46	/* tex4/1 */
++#define R200_EMIT_PP_TXOFFSET_5                     47	/* tex5/1 */
++#define R200_EMIT_VTE_CNTL                          48	/* vte/1 */
++#define R200_EMIT_OUTPUT_VTX_COMP_SEL               49	/* vtx/1 */
++#define R200_EMIT_PP_TAM_DEBUG3                     50	/* tam/1 */
++#define R200_EMIT_PP_CNTL_X                         51	/* cst/1 */
++#define R200_EMIT_RB3D_DEPTHXY_OFFSET               52	/* cst/1 */
++#define R200_EMIT_RE_AUX_SCISSOR_CNTL               53	/* cst/1 */
++#define R200_EMIT_RE_SCISSOR_TL_0                   54	/* cst/2 */
++#define R200_EMIT_RE_SCISSOR_TL_1                   55	/* cst/2 */
++#define R200_EMIT_RE_SCISSOR_TL_2                   56	/* cst/2 */
++#define R200_EMIT_SE_VAP_CNTL_STATUS                57	/* cst/1 */
++#define R200_EMIT_SE_VTX_STATE_CNTL                 58	/* cst/1 */
++#define R200_EMIT_RE_POINTSIZE                      59	/* cst/1 */
++#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0       60	/* cst/4 */
+ #define R200_EMIT_PP_CUBIC_FACES_0                  61
+ #define R200_EMIT_PP_CUBIC_OFFSETS_0                62
+ #define R200_EMIT_PP_CUBIC_FACES_1                  63
+@@ -153,42 +152,50 @@
+ #define RADEON_EMIT_PP_CUBIC_FACES_2                82
+ #define RADEON_EMIT_PP_CUBIC_OFFSETS_T2             83
+ #define R200_EMIT_PP_TRI_PERF_CNTL                  84
+-#define RADEON_MAX_STATE_PACKETS                    85
++#define R200_EMIT_PP_AFS_0                          85
++#define R200_EMIT_PP_AFS_1                          86
++#define R200_EMIT_ATF_TFACTOR                       87
++#define R200_EMIT_PP_TXCTLALL_0                     88
++#define R200_EMIT_PP_TXCTLALL_1                     89
++#define R200_EMIT_PP_TXCTLALL_2                     90
++#define R200_EMIT_PP_TXCTLALL_3                     91
++#define R200_EMIT_PP_TXCTLALL_4                     92
++#define R200_EMIT_PP_TXCTLALL_5                     93
++#define RADEON_MAX_STATE_PACKETS                    94
+ 
+ /* Commands understood by cmd_buffer ioctl.  More can be added but
+  * obviously these can't be removed or changed:
+  */
+-#define RADEON_CMD_PACKET      1 /* emit one of the register packets above */
+-#define RADEON_CMD_SCALARS     2 /* emit scalar data */
+-#define RADEON_CMD_VECTORS     3 /* emit vector data */
+-#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
+-#define RADEON_CMD_PACKET3     5 /* emit hw packet */
+-#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
+-#define RADEON_CMD_SCALARS2     7 /* r200 stopgap */
+-#define RADEON_CMD_WAIT         8 /* emit hw wait commands -- note:
+-				   *  doesn't make the cpu wait, just
+-				   *  the graphics hardware */
+-
++#define RADEON_CMD_PACKET      1	/* emit one of the register packets above */
++#define RADEON_CMD_SCALARS     2	/* emit scalar data */
++#define RADEON_CMD_VECTORS     3	/* emit vector data */
++#define RADEON_CMD_DMA_DISCARD 4	/* discard current dma buf */
++#define RADEON_CMD_PACKET3     5	/* emit hw packet */
++#define RADEON_CMD_PACKET3_CLIP 6	/* emit hw packet wrapped in cliprects */
++#define RADEON_CMD_SCALARS2     7	/* r200 stopgap */
++#define RADEON_CMD_WAIT         8	/* emit hw wait commands -- note:
++					 *  doesn't make the cpu wait, just
++					 *  the graphics hardware */
+ 
+ typedef union {
+ 	int i;
+-	struct { 
++	struct {
+ 		unsigned char cmd_type, pad0, pad1, pad2;
+ 	} header;
+-	struct { 
++	struct {
+ 		unsigned char cmd_type, packet_id, pad0, pad1;
+ 	} packet;
+-	struct { 
+-		unsigned char cmd_type, offset, stride, count; 
++	struct {
++		unsigned char cmd_type, offset, stride, count;
+ 	} scalars;
+-	struct { 
+-		unsigned char cmd_type, offset, stride, count; 
++	struct {
++		unsigned char cmd_type, offset, stride, count;
+ 	} vectors;
+-	struct { 
+-		unsigned char cmd_type, buf_idx, pad0, pad1; 
++	struct {
++		unsigned char cmd_type, buf_idx, pad0, pad1;
+ 	} dma;
+-	struct { 
+-		unsigned char cmd_type, flags, pad0, pad1; 
++	struct {
++		unsigned char cmd_type, flags, pad0, pad1;
+ 	} wait;
+ } drm_radeon_cmd_header_t;
+ 
+@@ -204,10 +211,10 @@ typedef union {
+  * The interface has not been stabilized, so some of these may be removed
+  * and eventually reordered before stabilization.
+  */
+-#define R300_CMD_PACKET0		1 
+-#define R300_CMD_VPU			2 /* emit vertex program upload */
+-#define R300_CMD_PACKET3		3 /* emit a packet3 */
+-#define R300_CMD_END3D			4 /* emit sequence ending 3d rendering */
++#define R300_CMD_PACKET0		1
++#define R300_CMD_VPU			2	/* emit vertex program upload */
++#define R300_CMD_PACKET3		3	/* emit a packet3 */
++#define R300_CMD_END3D			4	/* emit sequence ending 3d rendering */
+ #define R300_CMD_CP_DELAY		5
+ #define R300_CMD_DMA_DISCARD		6
+ #define R300_CMD_WAIT			7
+@@ -232,13 +239,13 @@ typedef union {
+ 	} packet3;
+ 	struct {
+ 		unsigned char cmd_type, packet;
+-		unsigned short count; /* amount of packet2 to emit */
++		unsigned short count;	/* amount of packet2 to emit */
+ 	} delay;
+ 	struct {
+ 		unsigned char cmd_type, buf_idx, pad0, pad1;
+ 	} dma;
+ 	struct {
+-		unsigned char cmd_type, flags, pad0, pad1;	
++		unsigned char cmd_type, flags, pad0, pad1;
+ 	} wait;
+ } drm_r300_cmd_header_t;
+ 
+@@ -292,7 +299,7 @@ typedef union {
+ #define RADEON_OFFSET_ALIGN             (1 << RADEON_OFFSET_SHIFT)
+ #define RADEON_OFFSET_MASK              (RADEON_OFFSET_ALIGN - 1)
+ 
+-#endif /* __RADEON_SAREA_DEFINES__ */
++#endif				/* __RADEON_SAREA_DEFINES__ */
+ 
+ typedef struct {
+ 	unsigned int red;
+@@ -303,7 +310,7 @@ typedef struct {
+ 
+ typedef struct {
+ 	/* Context state */
+-	unsigned int pp_misc;				/* 0x1c14 */
++	unsigned int pp_misc;	/* 0x1c14 */
+ 	unsigned int pp_fog_color;
+ 	unsigned int re_solid_color;
+ 	unsigned int rb3d_blendcntl;
+@@ -311,7 +318,7 @@ typedef struct {
+ 	unsigned int rb3d_depthpitch;
+ 	unsigned int rb3d_zstencilcntl;
+ 
+-	unsigned int pp_cntl;				/* 0x1c38 */
++	unsigned int pp_cntl;	/* 0x1c38 */
+ 	unsigned int rb3d_cntl;
+ 	unsigned int rb3d_coloroffset;
+ 	unsigned int re_width_height;
+@@ -319,27 +326,27 @@ typedef struct {
+ 	unsigned int se_cntl;
+ 
+ 	/* Vertex format state */
+-	unsigned int se_coord_fmt;			/* 0x1c50 */
++	unsigned int se_coord_fmt;	/* 0x1c50 */
+ 
+ 	/* Line state */
+-	unsigned int re_line_pattern;			/* 0x1cd0 */
++	unsigned int re_line_pattern;	/* 0x1cd0 */
+ 	unsigned int re_line_state;
+ 
+-	unsigned int se_line_width;			/* 0x1db8 */
++	unsigned int se_line_width;	/* 0x1db8 */
+ 
+ 	/* Bumpmap state */
+-	unsigned int pp_lum_matrix;			/* 0x1d00 */
++	unsigned int pp_lum_matrix;	/* 0x1d00 */
+ 
+-	unsigned int pp_rot_matrix_0;			/* 0x1d58 */
++	unsigned int pp_rot_matrix_0;	/* 0x1d58 */
+ 	unsigned int pp_rot_matrix_1;
+ 
+ 	/* Mask state */
+-	unsigned int rb3d_stencilrefmask;		/* 0x1d7c */
++	unsigned int rb3d_stencilrefmask;	/* 0x1d7c */
+ 	unsigned int rb3d_ropcntl;
+ 	unsigned int rb3d_planemask;
+ 
+ 	/* Viewport state */
+-	unsigned int se_vport_xscale;			/* 0x1d98 */
++	unsigned int se_vport_xscale;	/* 0x1d98 */
+ 	unsigned int se_vport_xoffset;
+ 	unsigned int se_vport_yscale;
+ 	unsigned int se_vport_yoffset;
+@@ -347,20 +354,19 @@ typedef struct {
+ 	unsigned int se_vport_zoffset;
+ 
+ 	/* Setup state */
+-	unsigned int se_cntl_status;			/* 0x2140 */
++	unsigned int se_cntl_status;	/* 0x2140 */
+ 
+ 	/* Misc state */
+-	unsigned int re_top_left;			/* 0x26c0 */
++	unsigned int re_top_left;	/* 0x26c0 */
+ 	unsigned int re_misc;
+ } drm_radeon_context_regs_t;
+ 
+ typedef struct {
+ 	/* Zbias state */
+-	unsigned int se_zbias_factor;			/* 0x1dac */
++	unsigned int se_zbias_factor;	/* 0x1dac */
+ 	unsigned int se_zbias_constant;
+ } drm_radeon_context2_regs_t;
+ 
+-
+ /* Setup registers for each texture unit
+  */
+ typedef struct {
+@@ -378,11 +384,10 @@ typedef struct {
+ 	unsigned int finish;
+ 	unsigned int prim:8;
+ 	unsigned int stateidx:8;
+-	unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
+-        unsigned int vc_format;   /* vertex format */
++	unsigned int numverts:16;	/* overloaded as offset/64 for elt prims */
++	unsigned int vc_format;	/* vertex format */
+ } drm_radeon_prim_t;
+ 
+-
+ typedef struct {
+ 	drm_radeon_context_regs_t context;
+ 	drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS];
+@@ -390,7 +395,6 @@ typedef struct {
+ 	unsigned int dirty;
+ } drm_radeon_state_t;
+ 
+-
+ typedef struct {
+ 	/* The channel for communication of state information to the
+ 	 * kernel on firing a vertex buffer with either of the
+@@ -413,16 +417,16 @@ typedef struct {
+ 	unsigned int last_dispatch;
+ 	unsigned int last_clear;
+ 
+-	drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
++	drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS +
++						       1];
+ 	unsigned int tex_age[RADEON_NR_TEX_HEAPS];
+ 	int ctx_owner;
+-        int pfState;                /* number of 3d windows (0,1,2ormore) */
+-        int pfCurrentPage;	    /* which buffer is being displayed? */
+-	int crtc2_base;		    /* CRTC2 frame offset */
++	int pfState;		/* number of 3d windows (0,1,2ormore) */
++	int pfCurrentPage;	/* which buffer is being displayed? */
++	int crtc2_base;		/* CRTC2 frame offset */
+ 	int tiling_enabled;	/* set by drm, read by 2d + 3d clients */
+ } drm_radeon_sarea_t;
+ 
+-
+ /* WARNING: If you change any of these defines, make sure to change the
+  * defines in the Xserver file (xf86drmRadeon.h)
+  *
+@@ -432,15 +436,15 @@ typedef struct {
+ /* Radeon specific ioctls
+  * The device specific ioctl range is 0x40 to 0x79.
+  */
+-#define DRM_RADEON_CP_INIT    0x00 
+-#define DRM_RADEON_CP_START   0x01 
++#define DRM_RADEON_CP_INIT    0x00
++#define DRM_RADEON_CP_START   0x01
+ #define DRM_RADEON_CP_STOP    0x02
+ #define DRM_RADEON_CP_RESET   0x03
+ #define DRM_RADEON_CP_IDLE    0x04
+-#define DRM_RADEON_RESET      0x05 
++#define DRM_RADEON_RESET      0x05
+ #define DRM_RADEON_FULLSCREEN 0x06
+-#define DRM_RADEON_SWAP       0x07 
+-#define DRM_RADEON_CLEAR      0x08 
++#define DRM_RADEON_SWAP       0x07
++#define DRM_RADEON_CLEAR      0x08
+ #define DRM_RADEON_VERTEX     0x09
+ #define DRM_RADEON_INDICES    0x0A
+ #define DRM_RADEON_NOT_USED
+@@ -491,7 +495,7 @@ typedef struct {
+ 
+ typedef struct drm_radeon_init {
+ 	enum {
+-		RADEON_INIT_CP    = 0x01,
++		RADEON_INIT_CP = 0x01,
+ 		RADEON_CLEANUP_CP = 0x02,
+ 		RADEON_INIT_R200_CP = 0x03,
+ 		RADEON_INIT_R300_CP = 0x04
+@@ -524,7 +528,7 @@ typedef struct drm_radeon_cp_stop {
+ 
+ typedef struct drm_radeon_fullscreen {
+ 	enum {
+-		RADEON_INIT_FULLSCREEN    = 0x01,
++		RADEON_INIT_FULLSCREEN = 0x01,
+ 		RADEON_CLEANUP_FULLSCREEN = 0x02
+ 	} func;
+ } drm_radeon_fullscreen_t;
+@@ -545,15 +549,15 @@ typedef struct drm_radeon_clear {
+ 	unsigned int clear_color;
+ 	unsigned int clear_depth;
+ 	unsigned int color_mask;
+-	unsigned int depth_mask;   /* misnamed field:  should be stencil */
++	unsigned int depth_mask;	/* misnamed field:  should be stencil */
+ 	drm_radeon_clear_rect_t __user *depth_boxes;
+ } drm_radeon_clear_t;
+ 
+ typedef struct drm_radeon_vertex {
+ 	int prim;
+-	int idx;			/* Index of vertex buffer */
+-	int count;			/* Number of vertices in buffer */
+-	int discard;			/* Client finished with buffer? */
++	int idx;		/* Index of vertex buffer */
++	int count;		/* Number of vertices in buffer */
++	int discard;		/* Client finished with buffer? */
+ } drm_radeon_vertex_t;
+ 
+ typedef struct drm_radeon_indices {
+@@ -561,7 +565,7 @@ typedef struct drm_radeon_indices {
+ 	int idx;
+ 	int start;
+ 	int end;
+-	int discard;			/* Client finished with buffer? */
++	int discard;		/* Client finished with buffer? */
+ } drm_radeon_indices_t;
+ 
+ /* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices
+@@ -569,8 +573,8 @@ typedef struct drm_radeon_indices {
+  *      - supports driver change to emit native primitives
+  */
+ typedef struct drm_radeon_vertex2 {
+-	int idx;			/* Index of vertex buffer */
+-	int discard;			/* Client finished with buffer? */
++	int idx;		/* Index of vertex buffer */
++	int discard;		/* Client finished with buffer? */
+ 	int nr_states;
+ 	drm_radeon_state_t __user *state;
+ 	int nr_prims;
+@@ -578,10 +582,10 @@ typedef struct drm_radeon_vertex2 {
+ } drm_radeon_vertex2_t;
+ 
+ /* v1.3 - obsoletes drm_radeon_vertex2
+- *      - allows arbitarily large cliprect list 
++ *      - allows arbitarily large cliprect list
+  *      - allows updating of tcl packet, vector and scalar state
+  *      - allows memory-efficient description of state updates
+- *      - allows state to be emitted without a primitive 
++ *      - allows state to be emitted without a primitive
+  *           (for clears, ctx switches)
+  *      - allows more than one dma buffer to be referenced per ioctl
+  *      - supports tcl driver
+@@ -595,7 +599,7 @@ typedef struct drm_radeon_cmd_buffer {
+ } drm_radeon_cmd_buffer_t;
+ 
+ typedef struct drm_radeon_tex_image {
+-	unsigned int x, y;		/* Blit coordinates */
++	unsigned int x, y;	/* Blit coordinates */
+ 	unsigned int width, height;
+ 	const void __user *data;
+ } drm_radeon_tex_image_t;
+@@ -604,7 +608,7 @@ typedef struct drm_radeon_texture {
+ 	unsigned int offset;
+ 	int pitch;
+ 	int format;
+-	int width;			/* Texture image coordinates */
++	int width;		/* Texture image coordinates */
+ 	int height;
+ 	drm_radeon_tex_image_t __user *image;
+ } drm_radeon_texture_t;
+@@ -620,19 +624,18 @@ typedef struct drm_radeon_indirect {
+ 	int discard;
+ } drm_radeon_indirect_t;
+ 
+-
+ /* 1.3: An ioctl to get parameters that aren't available to the 3d
+- * client any other way.  
++ * client any other way.
+  */
+-#define RADEON_PARAM_GART_BUFFER_OFFSET    1 /* card offset of 1st GART buffer */
++#define RADEON_PARAM_GART_BUFFER_OFFSET    1	/* card offset of 1st GART buffer */
+ #define RADEON_PARAM_LAST_FRAME            2
+ #define RADEON_PARAM_LAST_DISPATCH         3
+ #define RADEON_PARAM_LAST_CLEAR            4
+ /* Added with DRM version 1.6. */
+ #define RADEON_PARAM_IRQ_NR                5
+-#define RADEON_PARAM_GART_BASE             6 /* card offset of GART base */
++#define RADEON_PARAM_GART_BASE             6	/* card offset of GART base */
+ /* Added with DRM version 1.8. */
+-#define RADEON_PARAM_REGISTER_HANDLE       7 /* for drmMap() */
++#define RADEON_PARAM_REGISTER_HANDLE       7	/* for drmMap() */
+ #define RADEON_PARAM_STATUS_HANDLE         8
+ #define RADEON_PARAM_SAREA_HANDLE          9
+ #define RADEON_PARAM_GART_TEX_HANDLE       10
+@@ -663,10 +666,9 @@ typedef struct drm_radeon_mem_free {
+ typedef struct drm_radeon_mem_init_heap {
+ 	int region;
+ 	int size;
+-	int start;	
++	int start;
+ } drm_radeon_mem_init_heap_t;
+ 
+-
+ /* 1.6: Userspace can request & wait on irq's:
+  */
+ typedef struct drm_radeon_irq_emit {
+@@ -677,18 +679,18 @@ typedef struct drm_radeon_irq_wait {
+ 	int irq_seq;
+ } drm_radeon_irq_wait_t;
+ 
+-
+ /* 1.10: Clients tell the DRM where they think the framebuffer is located in
+  * the card's address space, via a new generic ioctl to set parameters
+  */
+ 
+ typedef struct drm_radeon_setparam {
+ 	unsigned int param;
+-	int64_t      value;
++	int64_t value;
+ } drm_radeon_setparam_t;
+ 
+ #define RADEON_SETPARAM_FB_LOCATION    1	/* determined framebuffer location */
+ #define RADEON_SETPARAM_SWITCH_TILING  2	/* enable/disable color tiling */
++#define RADEON_SETPARAM_PCIGART_LOCATION 3	/* PCI Gart Location */
+ 
+ /* 1.14: Clients can allocate/free a surface
+  */
+diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
+--- a/drivers/char/drm/radeon_drv.c
++++ b/drivers/char/drm/radeon_drv.c
+@@ -29,7 +29,6 @@
+  * OTHER DEALINGS IN THE SOFTWARE.
+  */
+ 
+-
+ #include <linux/config.h>
+ #include "drmP.h"
+ #include "drm.h"
+@@ -38,30 +37,33 @@
+ 
+ #include "drm_pciids.h"
+ 
+-static int postinit( struct drm_device *dev, unsigned long flags )
++int radeon_no_wb;
++
++MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
++module_param_named(no_wb, radeon_no_wb, int, 0444);
++
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->primary.minor,
+-		pci_pretty_name(dev->pdev)
+-		);
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR,
++		 DRIVER_PATCHLEVEL,
++		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
++	    );
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+@@ -69,11 +71,11 @@ static struct pci_device_id pciidlist[] 
+ 	radeon_PCI_IDS
+ };
+ 
+-extern drm_ioctl_desc_t radeon_ioctls[];
+-extern int radeon_max_ioctl;
+-
+ static struct drm_driver driver = {
+-	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
++	.driver_features =
++	    DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
++	    DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
++	    DRIVER_IRQ_VBL,
+ 	.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
+ 	.preinit = radeon_driver_preinit,
+ 	.presetup = radeon_presetup,
+@@ -95,21 +97,22 @@ static struct drm_driver driver = {
+ 	.ioctls = radeon_ioctls,
+ 	.dma_ioctl = radeon_cp_buffers,
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
+ #ifdef CONFIG_COMPAT
+-		.compat_ioctl = radeon_compat_ioctl,
++		 .compat_ioctl = radeon_compat_ioctl,
+ #endif
+-	},
++		 }
++	,
+ 	.pci_driver = {
+-		.name          = DRIVER_NAME,
+-		.id_table      = pciidlist,
+-	}
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
+ };
+ 
+ static int __init radeon_init(void)
+@@ -126,6 +129,6 @@ static void __exit radeon_exit(void)
+ module_init(radeon_init);
+ module_exit(radeon_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
+--- a/drivers/char/drm/radeon_drv.h
++++ b/drivers/char/drm/radeon_drv.h
+@@ -38,7 +38,7 @@
+ 
+ #define DRIVER_NAME		"radeon"
+ #define DRIVER_DESC		"ATI Radeon"
+-#define DRIVER_DATE		"20050311"
++#define DRIVER_DATE		"20050911"
+ 
+ /* Interface history:
+  *
+@@ -68,7 +68,7 @@
+  * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
+  *       Add texture rectangle support for r100.
+  * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
+- *       clients use to tell the DRM where they think the framebuffer is 
++ *       clients use to tell the DRM where they think the framebuffer is
+  *       located in the card's address space
+  * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
+  *       and GL_EXT_blend_[func|equation]_separate on r200
+@@ -83,9 +83,14 @@
+  * 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear
+  *       texture filtering on r200
+  * 1.17- Add initial support for R300 (3D).
++ * 1.18- Add support for GL_ATI_fragment_shader, new packets
++ *       R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces
++ *       R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR
++ *       (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6)
++ * 1.19- Add support for gart table in FB memory and PCIE r300
+  */
+ #define DRIVER_MAJOR		1
+-#define DRIVER_MINOR		17
++#define DRIVER_MINOR		19
+ #define DRIVER_PATCHLEVEL	0
+ 
+ #define GET_RING_HEAD(dev_priv)		DRM_READ32(  (dev_priv)->ring_rptr, 0 )
+@@ -129,14 +134,15 @@ enum radeon_chip_flags {
+ 	CHIP_IS_IGP = 0x00020000UL,
+ 	CHIP_SINGLE_CRTC = 0x00040000UL,
+ 	CHIP_IS_AGP = 0x00080000UL,
+-	CHIP_HAS_HIERZ = 0x00100000UL, 
++	CHIP_HAS_HIERZ = 0x00100000UL,
++	CHIP_IS_PCIE = 0x00200000UL,
+ };
+ 
+ typedef struct drm_radeon_freelist {
+-   	unsigned int age;
+-   	drm_buf_t *buf;
+-   	struct drm_radeon_freelist *next;
+-   	struct drm_radeon_freelist *prev;
++	unsigned int age;
++	drm_buf_t *buf;
++	struct drm_radeon_freelist *next;
++	struct drm_radeon_freelist *prev;
+ } drm_radeon_freelist_t;
+ 
+ typedef struct drm_radeon_ring_buffer {
+@@ -198,8 +204,8 @@ typedef struct drm_radeon_private {
+ 	int cp_mode;
+ 	int cp_running;
+ 
+-   	drm_radeon_freelist_t *head;
+-   	drm_radeon_freelist_t *tail;
++	drm_radeon_freelist_t *head;
++	drm_radeon_freelist_t *tail;
+ 	int last_buf;
+ 	volatile u32 *scratch;
+ 	int writeback_works;
+@@ -209,8 +215,6 @@ typedef struct drm_radeon_private {
+ 	int microcode_version;
+ 
+ 	int is_pci;
+-	unsigned long phys_pci_gart;
+-	dma_addr_t bus_pci_gart;
+ 
+ 	struct {
+ 		u32 boxes;
+@@ -242,7 +246,7 @@ typedef struct drm_radeon_private {
+ 	u32 depth_pitch_offset;
+ 
+ 	drm_radeon_depth_clear_t depth_clear;
+-	
++
+ 	unsigned long fb_offset;
+ 	unsigned long mmio_offset;
+ 	unsigned long ring_offset;
+@@ -260,11 +264,14 @@ typedef struct drm_radeon_private {
+ 	struct mem_block *fb_heap;
+ 
+ 	/* SW interrupt */
+-   	wait_queue_head_t swi_queue;
+-   	atomic_t swi_emitted;
++	wait_queue_head_t swi_queue;
++	atomic_t swi_emitted;
+ 
+ 	struct radeon_surface surfaces[RADEON_MAX_SURFACES];
+-	struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES];
++	struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
++
++	unsigned long pcigart_offset;
++	drm_ati_pcigart_info gart_info;
+ 
+ 	/* starting from here on, data is preserved accross an open */
+ 	uint32_t flags;		/* see radeon_chip_flags */
+@@ -274,63 +281,76 @@ typedef struct drm_radeon_buf_priv {
+ 	u32 age;
+ } drm_radeon_buf_priv_t;
+ 
++typedef struct drm_radeon_kcmd_buffer {
++	int bufsz;
++	char *buf;
++	int nbox;
++	drm_clip_rect_t __user *boxes;
++} drm_radeon_kcmd_buffer_t;
++
++extern int radeon_no_wb;
++extern drm_ioctl_desc_t radeon_ioctls[];
++extern int radeon_max_ioctl;
++
+ 				/* radeon_cp.c */
+-extern int radeon_cp_init( DRM_IOCTL_ARGS );
+-extern int radeon_cp_start( DRM_IOCTL_ARGS );
+-extern int radeon_cp_stop( DRM_IOCTL_ARGS );
+-extern int radeon_cp_reset( DRM_IOCTL_ARGS );
+-extern int radeon_cp_idle( DRM_IOCTL_ARGS );
+-extern int radeon_cp_resume( DRM_IOCTL_ARGS );
+-extern int radeon_engine_reset( DRM_IOCTL_ARGS );
+-extern int radeon_fullscreen( DRM_IOCTL_ARGS );
+-extern int radeon_cp_buffers( DRM_IOCTL_ARGS );
++extern int radeon_cp_init(DRM_IOCTL_ARGS);
++extern int radeon_cp_start(DRM_IOCTL_ARGS);
++extern int radeon_cp_stop(DRM_IOCTL_ARGS);
++extern int radeon_cp_reset(DRM_IOCTL_ARGS);
++extern int radeon_cp_idle(DRM_IOCTL_ARGS);
++extern int radeon_cp_resume(DRM_IOCTL_ARGS);
++extern int radeon_engine_reset(DRM_IOCTL_ARGS);
++extern int radeon_fullscreen(DRM_IOCTL_ARGS);
++extern int radeon_cp_buffers(DRM_IOCTL_ARGS);
+ 
+-extern void radeon_freelist_reset( drm_device_t *dev );
+-extern drm_buf_t *radeon_freelist_get( drm_device_t *dev );
++extern void radeon_freelist_reset(drm_device_t * dev);
++extern drm_buf_t *radeon_freelist_get(drm_device_t * dev);
+ 
+-extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
++extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n);
+ 
+-extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
++extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv);
+ 
+ extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
+ extern int radeon_presetup(struct drm_device *dev);
+ extern int radeon_driver_postcleanup(struct drm_device *dev);
+ 
+-extern int radeon_mem_alloc( DRM_IOCTL_ARGS );
+-extern int radeon_mem_free( DRM_IOCTL_ARGS );
+-extern int radeon_mem_init_heap( DRM_IOCTL_ARGS );
+-extern void radeon_mem_takedown( struct mem_block **heap );
+-extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap );
++extern int radeon_mem_alloc(DRM_IOCTL_ARGS);
++extern int radeon_mem_free(DRM_IOCTL_ARGS);
++extern int radeon_mem_init_heap(DRM_IOCTL_ARGS);
++extern void radeon_mem_takedown(struct mem_block **heap);
++extern void radeon_mem_release(DRMFILE filp, struct mem_block *heap);
+ 
+ 				/* radeon_irq.c */
+-extern int radeon_irq_emit( DRM_IOCTL_ARGS );
+-extern int radeon_irq_wait( DRM_IOCTL_ARGS );
++extern int radeon_irq_emit(DRM_IOCTL_ARGS);
++extern int radeon_irq_wait(DRM_IOCTL_ARGS);
+ 
+-extern void radeon_do_release(drm_device_t *dev);
+-extern int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
+-extern irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS );
+-extern void radeon_driver_irq_preinstall( drm_device_t *dev );
+-extern void radeon_driver_irq_postinstall( drm_device_t *dev );
+-extern void radeon_driver_irq_uninstall( drm_device_t *dev );
+-extern void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+-extern void radeon_driver_pretakedown(drm_device_t *dev);
+-extern int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv);
+-extern void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv);
+-
+-extern int radeon_preinit( struct drm_device *dev, unsigned long flags );
+-extern int radeon_postinit( struct drm_device *dev, unsigned long flags );
+-extern int radeon_postcleanup( struct drm_device *dev );
++extern void radeon_do_release(drm_device_t * dev);
++extern int radeon_driver_vblank_wait(drm_device_t * dev,
++				     unsigned int *sequence);
++extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
++extern void radeon_driver_irq_preinstall(drm_device_t * dev);
++extern void radeon_driver_irq_postinstall(drm_device_t * dev);
++extern void radeon_driver_irq_uninstall(drm_device_t * dev);
++extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp);
++extern void radeon_driver_pretakedown(drm_device_t * dev);
++extern int radeon_driver_open_helper(drm_device_t * dev,
++				     drm_file_t * filp_priv);
++extern void radeon_driver_free_filp_priv(drm_device_t * dev,
++					 drm_file_t * filp_priv);
++
++extern int radeon_preinit(struct drm_device *dev, unsigned long flags);
++extern int radeon_postinit(struct drm_device *dev, unsigned long flags);
++extern int radeon_postcleanup(struct drm_device *dev);
+ 
+ extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
+ 				unsigned long arg);
+ 
+-
+ /* r300_cmdbuf.c */
+ extern void r300_init_reg_flags(void);
+ 
+-extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
+-			     drm_file_t* filp_priv,
+-			     drm_radeon_cmd_buffer_t* cmdbuf);
++extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
++			     drm_file_t * filp_priv,
++			     drm_radeon_kcmd_buffer_t * cmdbuf);
+ 
+ /* Flags for stats.boxes
+  */
+@@ -340,8 +360,6 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ #define RADEON_BOX_WAIT_IDLE     0x8
+ #define RADEON_BOX_TEXTURE_LOAD  0x10
+ 
+-
+-
+ /* Register definitions, register access macros and drmAddMap constants
+  * for Radeon kernel driver.
+  */
+@@ -369,6 +387,25 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ #define RADEON_CRTC2_OFFSET		0x0324
+ #define RADEON_CRTC2_OFFSET_CNTL	0x0328
+ 
++#define RADEON_PCIE_INDEX               0x0030
++#define RADEON_PCIE_DATA                0x0034
++#define RADEON_PCIE_TX_GART_CNTL	0x10
++#	define RADEON_PCIE_TX_GART_EN   	(1 << 0)
++#	define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0<<1)
++#	define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO  (1<<1)
++#	define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD   (3<<1)
++#	define RADEON_PCIE_TX_GART_MODE_32_128_CACHE	(0<<3)
++#	define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE	(1<<3)
++#	define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN      (1<<5)
++#	define RADEON_PCIE_TX_GART_INVALIDATE_TLB	(1<<8)
++#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11
++#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12
++#define RADEON_PCIE_TX_GART_BASE  	0x13
++#define RADEON_PCIE_TX_GART_START_LO	0x14
++#define RADEON_PCIE_TX_GART_START_HI	0x15
++#define RADEON_PCIE_TX_GART_END_LO	0x16
++#define RADEON_PCIE_TX_GART_END_HI	0x17
++
+ #define RADEON_MPP_TB_CONFIG		0x01c0
+ #define RADEON_MEM_CNTL			0x0140
+ #define RADEON_MEM_SDRAM_MODE_REG	0x0158
+@@ -416,7 +453,6 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ 				? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
+ 				: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
+ 
+-
+ #define RADEON_GEN_INT_CNTL		0x0040
+ #	define RADEON_CRTC_VBLANK_MASK		(1 << 0)
+ #	define RADEON_GUI_IDLE_INT_ENABLE	(1 << 19)
+@@ -624,7 +660,6 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ #	define RADEON_DEPTH_FORMAT_16BIT_INT_Z	(0 << 0)
+ #	define RADEON_DEPTH_FORMAT_24BIT_INT_Z	(2 << 0)
+ 
+-
+ /* CP registers */
+ #define RADEON_CP_ME_RAM_ADDR		0x07d4
+ #define RADEON_CP_ME_RAM_RADDR		0x07d8
+@@ -672,7 +707,7 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ #       define RADEON_CP_NEXT_CHAR              0x00001900
+ #       define RADEON_CP_PLY_NEXTSCAN           0x00001D00
+ #       define RADEON_CP_SET_SCISSORS           0x00001E00
+-             /* GEN_INDX_PRIM is unsupported starting with R300 */
++	     /* GEN_INDX_PRIM is unsupported starting with R300 */
+ #	define RADEON_3D_RNDR_GEN_INDX_PRIM	0x00002300
+ #	define RADEON_WAIT_FOR_IDLE		0x00002600
+ #	define RADEON_3D_DRAW_VBUF		0x00002800
+@@ -756,19 +791,19 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ #define R200_PP_TXCBLEND_5                0x2f50
+ #define R200_PP_TXCBLEND_6                0x2f60
+ #define R200_PP_TXCBLEND_7                0x2f70
+-#define R200_SE_TCL_LIGHT_MODEL_CTL_0     0x2268 
++#define R200_SE_TCL_LIGHT_MODEL_CTL_0     0x2268
+ #define R200_PP_TFACTOR_0                 0x2ee0
+ #define R200_SE_VTX_FMT_0                 0x2088
+ #define R200_SE_VAP_CNTL                  0x2080
+ #define R200_SE_TCL_MATRIX_SEL_0          0x2230
+-#define R200_SE_TCL_TEX_PROC_CTL_2        0x22a8 
+-#define R200_SE_TCL_UCP_VERT_BLEND_CTL    0x22c0 
+-#define R200_PP_TXFILTER_5                0x2ca0 
+-#define R200_PP_TXFILTER_4                0x2c80 
+-#define R200_PP_TXFILTER_3                0x2c60 
+-#define R200_PP_TXFILTER_2                0x2c40 
+-#define R200_PP_TXFILTER_1                0x2c20 
+-#define R200_PP_TXFILTER_0                0x2c00 
++#define R200_SE_TCL_TEX_PROC_CTL_2        0x22a8
++#define R200_SE_TCL_UCP_VERT_BLEND_CTL    0x22c0
++#define R200_PP_TXFILTER_5                0x2ca0
++#define R200_PP_TXFILTER_4                0x2c80
++#define R200_PP_TXFILTER_3                0x2c60
++#define R200_PP_TXFILTER_2                0x2c40
++#define R200_PP_TXFILTER_1                0x2c20
++#define R200_PP_TXFILTER_0                0x2c00
+ #define R200_PP_TXOFFSET_5                0x2d78
+ #define R200_PP_TXOFFSET_4                0x2d60
+ #define R200_PP_TXOFFSET_3                0x2d48
+@@ -822,13 +857,13 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ #define R200_RE_SCISSOR_TL_0              0x1cd8
+ #define R200_RE_SCISSOR_TL_1              0x1ce0
+ #define R200_RE_SCISSOR_TL_2              0x1ce8
+-#define R200_RB3D_DEPTHXY_OFFSET          0x1d60 
++#define R200_RB3D_DEPTHXY_OFFSET          0x1d60
+ #define R200_RE_AUX_SCISSOR_CNTL          0x26f0
+ #define R200_SE_VTX_STATE_CNTL            0x2180
+ #define R200_RE_POINTSIZE                 0x2648
+ #define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254
+ 
+-#define RADEON_PP_TEX_SIZE_0                0x1d04  /* NPOT */
++#define RADEON_PP_TEX_SIZE_0                0x1d04	/* NPOT */
+ #define RADEON_PP_TEX_SIZE_1                0x1d0c
+ #define RADEON_PP_TEX_SIZE_2                0x1d14
+ 
+@@ -849,7 +884,7 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ #define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT               0x0000000b
+ #define R200_3D_DRAW_IMMD_2      0xC0003500
+ #define R200_SE_VTX_FMT_1                 0x208c
+-#define R200_RE_CNTL                      0x1c50 
++#define R200_RE_CNTL                      0x1c50
+ 
+ #define R200_RB3D_BLENDCOLOR              0x3218
+ 
+@@ -857,6 +892,9 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ 
+ #define R200_PP_TRI_PERF 0x2cf8
+ 
++#define R200_PP_AFS_0                     0x2f80
++#define R200_PP_AFS_1                     0x2f00	/* same as txcblend_0 */
++
+ /* Constants */
+ #define RADEON_MAX_USEC_TIMEOUT		100000	/* 100 ms */
+ 
+@@ -871,6 +909,8 @@ extern int r300_do_cp_cmdbuf(drm_device_
+ 
+ #define RADEON_RING_HIGH_MARK		128
+ 
++#define RADEON_PCIGART_TABLE_SIZE      (32*1024)
++
+ #define RADEON_READ(reg)	DRM_READ32(  dev_priv->mmio, (reg) )
+ #define RADEON_WRITE(reg,val)	DRM_WRITE32( dev_priv->mmio, (reg), (val) )
+ #define RADEON_READ8(reg)	DRM_READ8(  dev_priv->mmio, (reg) )
+@@ -883,6 +923,13 @@ do {									\
+ 	RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) );			\
+ } while (0)
+ 
++#define RADEON_WRITE_PCIE( addr, val )					\
++do {									\
++	RADEON_WRITE8( RADEON_PCIE_INDEX,				\
++			((addr) & 0xff));				\
++	RADEON_WRITE( RADEON_PCIE_DATA, (val) );			\
++} while (0)
++
+ #define CP_PACKET0( reg, n )						\
+ 	(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
+ #define CP_PACKET0_TABLE( reg, n )					\
+@@ -894,7 +941,6 @@ do {									\
+ #define CP_PACKET3( pkt, n )						\
+ 	(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
+ 
+-
+ /* ================================================================
+  * Engine control helper macros
+  */
+@@ -943,12 +989,11 @@ do {									\
+ 	OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL );				\
+ } while (0)
+ 
+-
+ /* ================================================================
+  * Misc helper macros
+  */
+ 
+-/* Perfbox functionality only.  
++/* Perfbox functionality only.
+  */
+ #define RING_SPACE_TEST_WITH_RETURN( dev_priv )				\
+ do {									\
+@@ -985,7 +1030,6 @@ do {									\
+ 	OUT_RING( age );						\
+ } while (0)
+ 
+-
+ /* ================================================================
+  * Ring control
+  */
+@@ -1046,7 +1090,6 @@ do {									\
+ 	OUT_RING( val );						\
+ } while (0)
+ 
+-
+ #define OUT_RING_TABLE( tab, sz ) do {					\
+ 	int _size = (sz);					\
+ 	int *_tab = (int *)(tab);				\
+@@ -1071,5 +1114,4 @@ do {									\
+ 	write &= mask;						\
+ } while (0)
+ 
+-
+-#endif /* __RADEON_DRV_H__ */
++#endif				/* __RADEON_DRV_H__ */
+diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c
+--- a/drivers/char/drm/radeon_ioc32.c
++++ b/drivers/char/drm/radeon_ioc32.c
+@@ -94,7 +94,7 @@ static int compat_radeon_cp_init(struct 
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RADEON_CP_INIT, (unsigned long) init);
++			 DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
+ }
+ 
+ typedef struct drm_radeon_clear32 {
+@@ -102,8 +102,8 @@ typedef struct drm_radeon_clear32 {
+ 	unsigned int clear_color;
+ 	unsigned int clear_depth;
+ 	unsigned int color_mask;
+-	unsigned int depth_mask;   /* misnamed field:  should be stencil */
+-	u32	     depth_boxes;
++	unsigned int depth_mask;	/* misnamed field:  should be stencil */
++	u32 depth_boxes;
+ } drm_radeon_clear32_t;
+ 
+ static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
+@@ -127,7 +127,7 @@ static int compat_radeon_cp_clear(struct
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RADEON_CLEAR, (unsigned long) clr);
++			 DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
+ }
+ 
+ typedef struct drm_radeon_stipple32 {
+@@ -137,7 +137,7 @@ typedef struct drm_radeon_stipple32 {
+ static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
+ 				    unsigned long arg)
+ {
+-	drm_radeon_stipple32_t __user *argp = (void __user *) arg;
++	drm_radeon_stipple32_t __user *argp = (void __user *)arg;
+ 	drm_radeon_stipple_t __user *request;
+ 	u32 mask;
+ 
+@@ -146,16 +146,16 @@ static int compat_radeon_cp_stipple(stru
+ 
+ 	request = compat_alloc_user_space(sizeof(*request));
+ 	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+-	    || __put_user((unsigned int __user *)(unsigned long) mask,
++	    || __put_user((unsigned int __user *)(unsigned long)mask,
+ 			  &request->mask))
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RADEON_STIPPLE, (unsigned long) request);
++			 DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
+ }
+ 
+ typedef struct drm_radeon_tex_image32 {
+-	unsigned int x, y;		/* Blit coordinates */
++	unsigned int x, y;	/* Blit coordinates */
+ 	unsigned int width, height;
+ 	u32 data;
+ } drm_radeon_tex_image32_t;
+@@ -164,7 +164,7 @@ typedef struct drm_radeon_texture32 {
+ 	unsigned int offset;
+ 	int pitch;
+ 	int format;
+-	int width;			/* Texture image coordinates */
++	int width;		/* Texture image coordinates */
+ 	int height;
+ 	u32 image;
+ } drm_radeon_texture32_t;
+@@ -177,7 +177,7 @@ static int compat_radeon_cp_texture(stru
+ 	drm_radeon_tex_image32_t img32;
+ 	drm_radeon_tex_image_t __user *image;
+ 
+-	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
++	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+ 		return -EFAULT;
+ 	if (req32.image == 0)
+ 		return -EINVAL;
+@@ -206,12 +206,12 @@ static int compat_radeon_cp_texture(stru
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RADEON_TEXTURE, (unsigned long) request);
++			 DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
+ }
+ 
+ typedef struct drm_radeon_vertex2_32 {
+-	int idx;			/* Index of vertex buffer */
+-	int discard;			/* Client finished with buffer? */
++	int idx;		/* Index of vertex buffer */
++	int discard;		/* Client finished with buffer? */
+ 	int nr_states;
+ 	u32 state;
+ 	int nr_prims;
+@@ -224,7 +224,7 @@ static int compat_radeon_cp_vertex2(stru
+ 	drm_radeon_vertex2_32_t req32;
+ 	drm_radeon_vertex2_t __user *request;
+ 
+-	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
++	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+ 		return -EFAULT;
+ 
+ 	request = compat_alloc_user_space(sizeof(*request));
+@@ -240,7 +240,7 @@ static int compat_radeon_cp_vertex2(stru
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RADEON_VERTEX2, (unsigned long) request);
++			 DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
+ }
+ 
+ typedef struct drm_radeon_cmd_buffer32 {
+@@ -256,7 +256,7 @@ static int compat_radeon_cp_cmdbuf(struc
+ 	drm_radeon_cmd_buffer32_t req32;
+ 	drm_radeon_cmd_buffer_t __user *request;
+ 
+-	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
++	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+ 		return -EFAULT;
+ 
+ 	request = compat_alloc_user_space(sizeof(*request));
+@@ -270,7 +270,7 @@ static int compat_radeon_cp_cmdbuf(struc
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RADEON_CMDBUF, (unsigned long) request);
++			 DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
+ }
+ 
+ typedef struct drm_radeon_getparam32 {
+@@ -284,7 +284,7 @@ static int compat_radeon_cp_getparam(str
+ 	drm_radeon_getparam32_t req32;
+ 	drm_radeon_getparam_t __user *request;
+ 
+-	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
++	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+ 		return -EFAULT;
+ 
+ 	request = compat_alloc_user_space(sizeof(*request));
+@@ -295,7 +295,7 @@ static int compat_radeon_cp_getparam(str
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RADEON_GETPARAM, (unsigned long) request);
++			 DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
+ }
+ 
+ typedef struct drm_radeon_mem_alloc32 {
+@@ -311,7 +311,7 @@ static int compat_radeon_mem_alloc(struc
+ 	drm_radeon_mem_alloc32_t req32;
+ 	drm_radeon_mem_alloc_t __user *request;
+ 
+-	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
++	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+ 		return -EFAULT;
+ 
+ 	request = compat_alloc_user_space(sizeof(*request));
+@@ -324,7 +324,7 @@ static int compat_radeon_mem_alloc(struc
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RADEON_ALLOC, (unsigned long) request);
++			 DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
+ }
+ 
+ typedef struct drm_radeon_irq_emit32 {
+@@ -337,7 +337,7 @@ static int compat_radeon_irq_emit(struct
+ 	drm_radeon_irq_emit32_t req32;
+ 	drm_radeon_irq_emit_t __user *request;
+ 
+-	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
++	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
+ 		return -EFAULT;
+ 
+ 	request = compat_alloc_user_space(sizeof(*request));
+@@ -347,7 +347,7 @@ static int compat_radeon_irq_emit(struct
+ 		return -EFAULT;
+ 
+ 	return drm_ioctl(file->f_dentry->d_inode, file,
+-			 DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long) request);
++			 DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
+ }
+ 
+ drm_ioctl_compat_t *radeon_compat_ioctls[] = {
+@@ -371,8 +371,7 @@ drm_ioctl_compat_t *radeon_compat_ioctls
+  * \param arg user argument.
+  * \return zero on success or negative number on failure.
+  */
+-long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
+-			 unsigned long arg)
++long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ 	unsigned int nr = DRM_IOCTL_NR(cmd);
+ 	drm_ioctl_compat_t *fn = NULL;
+@@ -386,7 +385,7 @@ long radeon_compat_ioctl(struct file *fi
+ 
+ 	lock_kernel();		/* XXX for now */
+ 	if (fn != NULL)
+-		ret = (*fn)(filp, cmd, arg);
++		ret = (*fn) (filp, cmd, arg);
+ 	else
+ 		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+ 	unlock_kernel();
+diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
+--- a/drivers/char/drm/radeon_irq.c
++++ b/drivers/char/drm/radeon_irq.c
+@@ -1,7 +1,7 @@
+ /* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*-
+  *
+  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+- * 
++ *
+  * The Weather Channel (TM) funded Tungsten Graphics to develop the
+  * initial release of the Radeon 8500 driver under the XFree86 license.
+  * This notice must be preserved.
+@@ -35,7 +35,8 @@
+ #include "radeon_drm.h"
+ #include "radeon_drv.h"
+ 
+-static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask)
++static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
++					      u32 mask)
+ {
+ 	u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
+ 	if (irqs)
+@@ -61,37 +62,37 @@ static __inline__ u32 radeon_acknowledge
+  * tied to dma at all, this is just a hangover from dri prehistory.
+  */
+ 
+-irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS )
++irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
+ {
+ 	drm_device_t *dev = (drm_device_t *) arg;
+-	drm_radeon_private_t *dev_priv = 
+-	   (drm_radeon_private_t *)dev->dev_private;
+-   	u32 stat;
++	drm_radeon_private_t *dev_priv =
++	    (drm_radeon_private_t *) dev->dev_private;
++	u32 stat;
+ 
+ 	/* Only consider the bits we're interested in - others could be used
+ 	 * outside the DRM
+ 	 */
+-	stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 
++	stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
+ 						  RADEON_CRTC_VBLANK_STAT));
+ 	if (!stat)
+ 		return IRQ_NONE;
+ 
+ 	/* SW interrupt */
+ 	if (stat & RADEON_SW_INT_TEST) {
+-		DRM_WAKEUP( &dev_priv->swi_queue );
++		DRM_WAKEUP(&dev_priv->swi_queue);
+ 	}
+ 
+ 	/* VBLANK interrupt */
+ 	if (stat & RADEON_CRTC_VBLANK_STAT) {
+ 		atomic_inc(&dev->vbl_received);
+ 		DRM_WAKEUP(&dev->vbl_queue);
+-		drm_vbl_send_signals( dev );
++		drm_vbl_send_signals(dev);
+ 	}
+ 
+ 	return IRQ_HANDLED;
+ }
+ 
+-static int radeon_emit_irq(drm_device_t *dev)
++static int radeon_emit_irq(drm_device_t * dev)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	unsigned int ret;
+@@ -100,42 +101,41 @@ static int radeon_emit_irq(drm_device_t 
+ 	atomic_inc(&dev_priv->swi_emitted);
+ 	ret = atomic_read(&dev_priv->swi_emitted);
+ 
+-	BEGIN_RING( 4 );
+-	OUT_RING_REG( RADEON_LAST_SWI_REG, ret );
+-	OUT_RING_REG( RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE );
+-	ADVANCE_RING(); 
+- 	COMMIT_RING();
++	BEGIN_RING(4);
++	OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
++	OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
++	ADVANCE_RING();
++	COMMIT_RING();
+ 
+ 	return ret;
+ }
+ 
+-
+-static int radeon_wait_irq(drm_device_t *dev, int swi_nr)
++static int radeon_wait_irq(drm_device_t * dev, int swi_nr)
+ {
+-  	drm_radeon_private_t *dev_priv = 
+-	   (drm_radeon_private_t *)dev->dev_private;
++	drm_radeon_private_t *dev_priv =
++	    (drm_radeon_private_t *) dev->dev_private;
+ 	int ret = 0;
+ 
+- 	if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr)  
+- 		return 0; 
++	if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
++		return 0;
+ 
+ 	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+ 
+-	DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, 
+-		     RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr );
++	DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
++		    RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
+ 
+ 	return ret;
+ }
+ 
+-int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
++int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
+ {
+-  	drm_radeon_private_t *dev_priv = 
+-	   (drm_radeon_private_t *)dev->dev_private;
++	drm_radeon_private_t *dev_priv =
++	    (drm_radeon_private_t *) dev->dev_private;
+ 	unsigned int cur_vblank;
+ 	int ret = 0;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -145,101 +145,100 @@ int radeon_driver_vblank_wait(drm_device
+ 
+ 	/* Assume that the user has missed the current sequence number
+ 	 * by about a day rather than she wants to wait for years
+-	 * using vertical blanks... 
++	 * using vertical blanks...
+ 	 */
+-	DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, 
+-		     ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
+-			 - *sequence ) <= (1<<23) ) );
++	DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
++		    (((cur_vblank = atomic_read(&dev->vbl_received))
++		      - *sequence) <= (1 << 23)));
+ 
+ 	*sequence = cur_vblank;
+ 
+ 	return ret;
+ }
+ 
+-
+ /* Needs the lock as it touches the ring.
+  */
+-int radeon_irq_emit( DRM_IOCTL_ARGS )
++int radeon_irq_emit(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_irq_emit_t emit;
+ 	int result;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( emit, (drm_radeon_irq_emit_t __user *)data,
+-				  sizeof(emit) );
++	DRM_COPY_FROM_USER_IOCTL(emit, (drm_radeon_irq_emit_t __user *) data,
++				 sizeof(emit));
+ 
+-	result = radeon_emit_irq( dev );
++	result = radeon_emit_irq(dev);
+ 
+-	if ( DRM_COPY_TO_USER( emit.irq_seq, &result, sizeof(int) ) ) {
+-		DRM_ERROR( "copy_to_user\n" );
++	if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) {
++		DRM_ERROR("copy_to_user\n");
+ 		return DRM_ERR(EFAULT);
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-
+ /* Doesn't need the hardware lock.
+  */
+-int radeon_irq_wait( DRM_IOCTL_ARGS )
++int radeon_irq_wait(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_irq_wait_t irqwait;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( irqwait, (drm_radeon_irq_wait_t __user*)data,
+-				  sizeof(irqwait) );
++	DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_radeon_irq_wait_t __user *) data,
++				 sizeof(irqwait));
+ 
+-	return radeon_wait_irq( dev, irqwait.irq_seq );
++	return radeon_wait_irq(dev, irqwait.irq_seq);
+ }
+ 
+-
+ /* drm_dma.h hooks
+ */
+-void radeon_driver_irq_preinstall( drm_device_t *dev ) {
++void radeon_driver_irq_preinstall(drm_device_t * dev)
++{
+ 	drm_radeon_private_t *dev_priv =
+-		(drm_radeon_private_t *)dev->dev_private;
++	    (drm_radeon_private_t *) dev->dev_private;
+ 
+- 	/* Disable *all* interrupts */
+-      	RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
++	/* Disable *all* interrupts */
++	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
+ 
+ 	/* Clear bits if they're already high */
+ 	radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
+ 					   RADEON_CRTC_VBLANK_STAT));
+ }
+ 
+-void radeon_driver_irq_postinstall( drm_device_t *dev ) {
++void radeon_driver_irq_postinstall(drm_device_t * dev)
++{
+ 	drm_radeon_private_t *dev_priv =
+-		(drm_radeon_private_t *)dev->dev_private;
++	    (drm_radeon_private_t *) dev->dev_private;
+ 
+-   	atomic_set(&dev_priv->swi_emitted, 0);
+-	DRM_INIT_WAITQUEUE( &dev_priv->swi_queue );
++	atomic_set(&dev_priv->swi_emitted, 0);
++	DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
+ 
+ 	/* Turn on SW and VBL ints */
+-   	RADEON_WRITE( RADEON_GEN_INT_CNTL,
+-		      RADEON_CRTC_VBLANK_MASK |	
+-		      RADEON_SW_INT_ENABLE );
++	RADEON_WRITE(RADEON_GEN_INT_CNTL,
++		     RADEON_CRTC_VBLANK_MASK | RADEON_SW_INT_ENABLE);
+ }
+ 
+-void radeon_driver_irq_uninstall( drm_device_t *dev ) {
++void radeon_driver_irq_uninstall(drm_device_t * dev)
++{
+ 	drm_radeon_private_t *dev_priv =
+-		(drm_radeon_private_t *)dev->dev_private;
++	    (drm_radeon_private_t *) dev->dev_private;
+ 	if (!dev_priv)
+ 		return;
+ 
+ 	/* Disable *all* interrupts */
+-	RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
++	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
+ }
+diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c
+--- a/drivers/char/drm/radeon_mem.c
++++ b/drivers/char/drm/radeon_mem.c
+@@ -1,7 +1,7 @@
+ /* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*-
+  *
+  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+- * 
++ *
+  * The Weather Channel (TM) funded Tungsten Graphics to develop the
+  * initial release of the Radeon 8500 driver under the XFree86 license.
+  * This notice must be preserved.
+@@ -35,16 +35,17 @@
+ #include "radeon_drv.h"
+ 
+ /* Very simple allocator for GART memory, working on a static range
+- * already mapped into each client's address space.  
++ * already mapped into each client's address space.
+  */
+ 
+ static struct mem_block *split_block(struct mem_block *p, int start, int size,
+-				     DRMFILE filp )
++				     DRMFILE filp)
+ {
+ 	/* Maybe cut off the start of an existing block */
+ 	if (start > p->start) {
+-		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
+-		if (!newblock) 
++		struct mem_block *newblock =
++		    drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
++		if (!newblock)
+ 			goto out;
+ 		newblock->start = start;
+ 		newblock->size = p->size - (start - p->start);
+@@ -56,10 +57,11 @@ static struct mem_block *split_block(str
+ 		p->size -= newblock->size;
+ 		p = newblock;
+ 	}
+-   
++
+ 	/* Maybe cut off the end of an existing block */
+ 	if (size < p->size) {
+-		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
++		struct mem_block *newblock =
++		    drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
+ 		if (!newblock)
+ 			goto out;
+ 		newblock->start = start + size;
+@@ -72,40 +74,39 @@ static struct mem_block *split_block(str
+ 		p->size = size;
+ 	}
+ 
+- out:
++      out:
+ 	/* Our block is in the middle */
+ 	p->filp = filp;
+ 	return p;
+ }
+ 
+-static struct mem_block *alloc_block( struct mem_block *heap, int size, 
+-				      int align2, DRMFILE filp )
++static struct mem_block *alloc_block(struct mem_block *heap, int size,
++				     int align2, DRMFILE filp)
+ {
+ 	struct mem_block *p;
+-	int mask = (1 << align2)-1;
++	int mask = (1 << align2) - 1;
+ 
+ 	list_for_each(p, heap) {
+ 		int start = (p->start + mask) & ~mask;
+ 		if (p->filp == 0 && start + size <= p->start + p->size)
+-			return split_block( p, start, size, filp );
++			return split_block(p, start, size, filp);
+ 	}
+ 
+ 	return NULL;
+ }
+ 
+-static struct mem_block *find_block( struct mem_block *heap, int start )
++static struct mem_block *find_block(struct mem_block *heap, int start)
+ {
+ 	struct mem_block *p;
+ 
+ 	list_for_each(p, heap)
+-		if (p->start == start)
+-			return p;
++	    if (p->start == start)
++		return p;
+ 
+ 	return NULL;
+ }
+ 
+-
+-static void free_block( struct mem_block *p )
++static void free_block(struct mem_block *p)
+ {
+ 	p->filp = NULL;
+ 
+@@ -117,7 +118,7 @@ static void free_block( struct mem_block
+ 		p->size += q->size;
+ 		p->next = q->next;
+ 		p->next->prev = p;
+-		drm_free(q, sizeof(*q), DRM_MEM_BUFS );
++		drm_free(q, sizeof(*q), DRM_MEM_BUFS);
+ 	}
+ 
+ 	if (p->prev->filp == 0) {
+@@ -125,7 +126,7 @@ static void free_block( struct mem_block
+ 		q->size += p->size;
+ 		q->next = p->next;
+ 		q->next->prev = q;
+-		drm_free(p, sizeof(*q), DRM_MEM_BUFS );
++		drm_free(p, sizeof(*q), DRM_MEM_BUFS);
+ 	}
+ }
+ 
+@@ -133,14 +134,14 @@ static void free_block( struct mem_block
+  */
+ static int init_heap(struct mem_block **heap, int start, int size)
+ {
+-	struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS );
++	struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS);
+ 
+-	if (!blocks) 
++	if (!blocks)
+ 		return DRM_ERR(ENOMEM);
+-	
+-	*heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS );
++
++	*heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS);
+ 	if (!*heap) {
+-		drm_free( blocks, sizeof(*blocks), DRM_MEM_BUFS );
++		drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS);
+ 		return DRM_ERR(ENOMEM);
+ 	}
+ 
+@@ -149,16 +150,15 @@ static int init_heap(struct mem_block **
+ 	blocks->filp = NULL;
+ 	blocks->next = blocks->prev = *heap;
+ 
+-	memset( *heap, 0, sizeof(**heap) );
+-	(*heap)->filp = (DRMFILE) -1;
++	memset(*heap, 0, sizeof(**heap));
++	(*heap)->filp = (DRMFILE) - 1;
+ 	(*heap)->next = (*heap)->prev = blocks;
+ 	return 0;
+ }
+ 
+-
+ /* Free all blocks associated with the releasing file.
+  */
+-void radeon_mem_release( DRMFILE filp, struct mem_block *heap )
++void radeon_mem_release(DRMFILE filp, struct mem_block *heap)
+ {
+ 	struct mem_block *p;
+ 
+@@ -166,7 +166,7 @@ void radeon_mem_release( DRMFILE filp, s
+ 		return;
+ 
+ 	list_for_each(p, heap) {
+-		if (p->filp == filp) 
++		if (p->filp == filp)
+ 			p->filp = NULL;
+ 	}
+ 
+@@ -179,40 +179,37 @@ void radeon_mem_release( DRMFILE filp, s
+ 			p->size += q->size;
+ 			p->next = q->next;
+ 			p->next->prev = p;
+-			drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
++			drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
+ 		}
+ 	}
+ }
+ 
+ /* Shutdown.
+  */
+-void radeon_mem_takedown( struct mem_block **heap )
++void radeon_mem_takedown(struct mem_block **heap)
+ {
+ 	struct mem_block *p;
+-	
++
+ 	if (!*heap)
+ 		return;
+ 
+-	for (p = (*heap)->next ; p != *heap ; ) {
++	for (p = (*heap)->next; p != *heap;) {
+ 		struct mem_block *q = p;
+ 		p = p->next;
+-		drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
++		drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
+ 	}
+ 
+-	drm_free( *heap, sizeof(**heap),DRM_MEM_DRIVER );
++	drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER);
+ 	*heap = NULL;
+ }
+ 
+-
+-
+ /* IOCTL HANDLERS */
+ 
+-static struct mem_block **get_heap( drm_radeon_private_t *dev_priv,
+-				   int region )
++static struct mem_block **get_heap(drm_radeon_private_t * dev_priv, int region)
+ {
+-	switch( region ) {
++	switch (region) {
+ 	case RADEON_MEM_REGION_GART:
+- 		return &dev_priv->gart_heap; 
++		return &dev_priv->gart_heap;
+ 	case RADEON_MEM_REGION_FB:
+ 		return &dev_priv->fb_heap;
+ 	default:
+@@ -220,103 +217,98 @@ static struct mem_block **get_heap( drm_
+ 	}
+ }
+ 
+-int radeon_mem_alloc( DRM_IOCTL_ARGS )
++int radeon_mem_alloc(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_mem_alloc_t alloc;
+ 	struct mem_block *block, **heap;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( alloc, (drm_radeon_mem_alloc_t __user *)data,
+-				  sizeof(alloc) );
++	DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_mem_alloc_t __user *) data,
++				 sizeof(alloc));
+ 
+-	heap = get_heap( dev_priv, alloc.region );
++	heap = get_heap(dev_priv, alloc.region);
+ 	if (!heap || !*heap)
+ 		return DRM_ERR(EFAULT);
+-	
++
+ 	/* Make things easier on ourselves: all allocations at least
+ 	 * 4k aligned.
+ 	 */
+ 	if (alloc.alignment < 12)
+ 		alloc.alignment = 12;
+ 
+-	block = alloc_block( *heap, alloc.size, alloc.alignment,
+-			     filp );
++	block = alloc_block(*heap, alloc.size, alloc.alignment, filp);
+ 
+-	if (!block) 
++	if (!block)
+ 		return DRM_ERR(ENOMEM);
+ 
+-	if ( DRM_COPY_TO_USER( alloc.region_offset, &block->start, 
+-			       sizeof(int) ) ) {
+-		DRM_ERROR( "copy_to_user\n" );
++	if (DRM_COPY_TO_USER(alloc.region_offset, &block->start, sizeof(int))) {
++		DRM_ERROR("copy_to_user\n");
+ 		return DRM_ERR(EFAULT);
+ 	}
+-	
++
+ 	return 0;
+ }
+ 
+-
+-
+-int radeon_mem_free( DRM_IOCTL_ARGS )
++int radeon_mem_free(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_mem_free_t memfree;
+ 	struct mem_block *block, **heap;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( memfree, (drm_radeon_mem_free_t __user *)data,
+-				  sizeof(memfree) );
++	DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data,
++				 sizeof(memfree));
+ 
+-	heap = get_heap( dev_priv, memfree.region );
++	heap = get_heap(dev_priv, memfree.region);
+ 	if (!heap || !*heap)
+ 		return DRM_ERR(EFAULT);
+-	
+-	block = find_block( *heap, memfree.region_offset );
++
++	block = find_block(*heap, memfree.region_offset);
+ 	if (!block)
+ 		return DRM_ERR(EFAULT);
+ 
+ 	if (block->filp != filp)
+ 		return DRM_ERR(EPERM);
+ 
+-	free_block( block );	
++	free_block(block);
+ 	return 0;
+ }
+ 
+-int radeon_mem_init_heap( DRM_IOCTL_ARGS )
++int radeon_mem_init_heap(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_mem_init_heap_t initheap;
+ 	struct mem_block **heap;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( initheap, (drm_radeon_mem_init_heap_t __user *)data,
+-				  sizeof(initheap) );
++	DRM_COPY_FROM_USER_IOCTL(initheap,
++				 (drm_radeon_mem_init_heap_t __user *) data,
++				 sizeof(initheap));
+ 
+-	heap = get_heap( dev_priv, initheap.region );
+-	if (!heap) 
++	heap = get_heap(dev_priv, initheap.region);
++	if (!heap)
+ 		return DRM_ERR(EFAULT);
+-	
++
+ 	if (*heap) {
+ 		DRM_ERROR("heap already initialized?");
+ 		return DRM_ERR(EFAULT);
+ 	}
+-		
+-	return init_heap( heap, initheap.start, initheap.size );
+-}
+-
+ 
++	return init_heap(heap, initheap.start, initheap.size);
++}
+diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
+--- a/drivers/char/drm/radeon_state.c
++++ b/drivers/char/drm/radeon_state.c
+@@ -37,51 +37,58 @@
+  * Helper functions for client state checking and fixup
+  */
+ 
+-static __inline__ int radeon_check_and_fixup_offset( drm_radeon_private_t *dev_priv,
+-						     drm_file_t *filp_priv,
+-						     u32 *offset ) {
++static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
++						    dev_priv,
++						    drm_file_t * filp_priv,
++						    u32 *offset)
++{
+ 	u32 off = *offset;
+ 	struct drm_radeon_driver_file_fields *radeon_priv;
+ 
+-	if ( off >= dev_priv->fb_location &&
+-	     off < ( dev_priv->gart_vm_start + dev_priv->gart_size ) )
++	if (off >= dev_priv->fb_location &&
++	    off < (dev_priv->gart_vm_start + dev_priv->gart_size))
+ 		return 0;
+ 
+ 	radeon_priv = filp_priv->driver_priv;
+ 	off += radeon_priv->radeon_fb_delta;
+ 
+-	DRM_DEBUG( "offset fixed up to 0x%x\n", off );
++	DRM_DEBUG("offset fixed up to 0x%x\n", off);
+ 
+-	if ( off < dev_priv->fb_location ||
+-	     off >= ( dev_priv->gart_vm_start + dev_priv->gart_size ) )
+-		return DRM_ERR( EINVAL );
++	if (off < dev_priv->fb_location ||
++	    off >= (dev_priv->gart_vm_start + dev_priv->gart_size))
++		return DRM_ERR(EINVAL);
+ 
+ 	*offset = off;
+ 
+ 	return 0;
+ }
+ 
+-static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv,
+-						      drm_file_t *filp_priv,
+-						      int id,
+-						      u32 __user *data ) {
+-	switch ( id ) {
++static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
++						     dev_priv,
++						     drm_file_t * filp_priv,
++						     int id, u32 *data)
++{
++	switch (id) {
+ 
+ 	case RADEON_EMIT_PP_MISC:
+-		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-						    &data[( RADEON_RB3D_DEPTHOFFSET
+-							    - RADEON_PP_MISC ) / 4] ) ) {
+-			DRM_ERROR( "Invalid depth buffer offset\n" );
+-			return DRM_ERR( EINVAL );
++		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
++						  &data[(RADEON_RB3D_DEPTHOFFSET
++							 -
++							 RADEON_PP_MISC) /
++							4])) {
++			DRM_ERROR("Invalid depth buffer offset\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+ 
+ 	case RADEON_EMIT_PP_CNTL:
+-		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-						    &data[( RADEON_RB3D_COLOROFFSET
+-							    - RADEON_PP_CNTL ) / 4] ) ) {
+-			DRM_ERROR( "Invalid colour buffer offset\n" );
+-			return DRM_ERR( EINVAL );
++		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
++						  &data[(RADEON_RB3D_COLOROFFSET
++							 -
++							 RADEON_PP_CNTL) /
++							4])) {
++			DRM_ERROR("Invalid colour buffer offset\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+ 
+@@ -91,21 +98,23 @@ static __inline__ int radeon_check_and_f
+ 	case R200_EMIT_PP_TXOFFSET_3:
+ 	case R200_EMIT_PP_TXOFFSET_4:
+ 	case R200_EMIT_PP_TXOFFSET_5:
+-		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-						    &data[0] ) ) {
+-			DRM_ERROR( "Invalid R200 texture offset\n" );
+-			return DRM_ERR( EINVAL );
++		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
++						  &data[0])) {
++			DRM_ERROR("Invalid R200 texture offset\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+ 
+ 	case RADEON_EMIT_PP_TXFILTER_0:
+ 	case RADEON_EMIT_PP_TXFILTER_1:
+ 	case RADEON_EMIT_PP_TXFILTER_2:
+-		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-						    &data[( RADEON_PP_TXOFFSET_0
+-							    - RADEON_PP_TXFILTER_0 ) / 4] ) ) {
+-			DRM_ERROR( "Invalid R100 texture offset\n" );
+-			return DRM_ERR( EINVAL );
++		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
++						  &data[(RADEON_PP_TXOFFSET_0
++							 -
++							 RADEON_PP_TXFILTER_0) /
++							4])) {
++			DRM_ERROR("Invalid R100 texture offset\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+ 
+@@ -114,17 +123,18 @@ static __inline__ int radeon_check_and_f
+ 	case R200_EMIT_PP_CUBIC_OFFSETS_2:
+ 	case R200_EMIT_PP_CUBIC_OFFSETS_3:
+ 	case R200_EMIT_PP_CUBIC_OFFSETS_4:
+-	case R200_EMIT_PP_CUBIC_OFFSETS_5: {
+-		int i;
+-		for ( i = 0; i < 5; i++ ) {
+-			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-							    &data[i] ) ) {
+-				DRM_ERROR( "Invalid R200 cubic texture offset\n" );
+-				return DRM_ERR( EINVAL );
++	case R200_EMIT_PP_CUBIC_OFFSETS_5:{
++			int i;
++			for (i = 0; i < 5; i++) {
++				if (radeon_check_and_fixup_offset
++				    (dev_priv, filp_priv, &data[i])) {
++					DRM_ERROR
++					    ("Invalid R200 cubic texture offset\n");
++					return DRM_ERR(EINVAL);
++				}
+ 			}
++			break;
+ 		}
+-		break;
+-	}
+ 
+ 	case RADEON_EMIT_PP_CUBIC_OFFSETS_T0:
+ 	case RADEON_EMIT_PP_CUBIC_OFFSETS_T1:
+@@ -207,247 +217,259 @@ static __inline__ int radeon_check_and_f
+ 	case RADEON_EMIT_PP_CUBIC_FACES_1:
+ 	case RADEON_EMIT_PP_CUBIC_FACES_2:
+ 	case R200_EMIT_PP_TRI_PERF_CNTL:
++	case R200_EMIT_PP_AFS_0:
++	case R200_EMIT_PP_AFS_1:
++	case R200_EMIT_ATF_TFACTOR:
++	case R200_EMIT_PP_TXCTLALL_0:
++	case R200_EMIT_PP_TXCTLALL_1:
++	case R200_EMIT_PP_TXCTLALL_2:
++	case R200_EMIT_PP_TXCTLALL_3:
++	case R200_EMIT_PP_TXCTLALL_4:
++	case R200_EMIT_PP_TXCTLALL_5:
+ 		/* These packets don't contain memory offsets */
+ 		break;
+ 
+ 	default:
+-		DRM_ERROR( "Unknown state packet ID %d\n", id );
+-		return DRM_ERR( EINVAL );
++		DRM_ERROR("Unknown state packet ID %d\n", id);
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-static __inline__ int radeon_check_and_fixup_packet3( drm_radeon_private_t *dev_priv,
+-						      drm_file_t *filp_priv,
+-						      drm_radeon_cmd_buffer_t *cmdbuf,
+-						      unsigned int *cmdsz ) {
++static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
++						     dev_priv,
++						     drm_file_t * filp_priv,
++						     drm_radeon_kcmd_buffer_t *cmdbuf,
++						     unsigned int *cmdsz)
++{
+ 	u32 *cmd = (u32 *) cmdbuf->buf;
+ 
+-	*cmdsz = 2 + ( ( cmd[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 );
++	*cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
+ 
+-	if ( ( cmd[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) {
+-		DRM_ERROR( "Not a type 3 packet\n" );
+-		return DRM_ERR( EINVAL );
++	if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) {
++		DRM_ERROR("Not a type 3 packet\n");
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( 4 * *cmdsz > cmdbuf->bufsz ) {
+-		DRM_ERROR( "Packet size larger than size of data provided\n" );
+-		return DRM_ERR( EINVAL );
++	if (4 * *cmdsz > cmdbuf->bufsz) {
++		DRM_ERROR("Packet size larger than size of data provided\n");
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	/* Check client state and fix it up if necessary */
+-	if ( cmd[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */
++	if (cmd[0] & 0x8000) {	/* MSB of opcode: next DWORD GUI_CNTL */
+ 		u32 offset;
+ 
+-		if ( cmd[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL
+-			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
++		if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
++			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
+ 			offset = cmd[2] << 10;
+-			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
+-				DRM_ERROR( "Invalid first packet offset\n" );
+-				return DRM_ERR( EINVAL );
++			if (radeon_check_and_fixup_offset
++			    (dev_priv, filp_priv, &offset)) {
++				DRM_ERROR("Invalid first packet offset\n");
++				return DRM_ERR(EINVAL);
+ 			}
+-			cmd[2] = ( cmd[2] & 0xffc00000 ) | offset >> 10;
++			cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10;
+ 		}
+ 
+-		if ( ( cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) &&
+-		     ( cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
++		if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
++		    (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
+ 			offset = cmd[3] << 10;
+-			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
+-				DRM_ERROR( "Invalid second packet offset\n" );
+-				return DRM_ERR( EINVAL );
++			if (radeon_check_and_fixup_offset
++			    (dev_priv, filp_priv, &offset)) {
++				DRM_ERROR("Invalid second packet offset\n");
++				return DRM_ERR(EINVAL);
+ 			}
+-			cmd[3] = ( cmd[3] & 0xffc00000 ) | offset >> 10;
++			cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
+ 		}
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-
+ /* ================================================================
+  * CP hardware state programming functions
+  */
+ 
+-static __inline__ void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
+-					  drm_clip_rect_t *box )
++static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv,
++					     drm_clip_rect_t * box)
+ {
+ 	RING_LOCALS;
+ 
+-	DRM_DEBUG( "   box:  x1=%d y1=%d  x2=%d y2=%d\n",
+-		   box->x1, box->y1, box->x2, box->y2 );
++	DRM_DEBUG("   box:  x1=%d y1=%d  x2=%d y2=%d\n",
++		  box->x1, box->y1, box->x2, box->y2);
+ 
+-	BEGIN_RING( 4 );
+-	OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
+-	OUT_RING( (box->y1 << 16) | box->x1 );
+-	OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
+-	OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
++	BEGIN_RING(4);
++	OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0));
++	OUT_RING((box->y1 << 16) | box->x1);
++	OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
++	OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1));
+ 	ADVANCE_RING();
+ }
+ 
+ /* Emit 1.1 state
+  */
+-static int radeon_emit_state( drm_radeon_private_t *dev_priv,
+-			      drm_file_t *filp_priv,
+-			      drm_radeon_context_regs_t *ctx,
+-			      drm_radeon_texture_regs_t *tex,
+-			      unsigned int dirty )
++static int radeon_emit_state(drm_radeon_private_t * dev_priv,
++			     drm_file_t * filp_priv,
++			     drm_radeon_context_regs_t * ctx,
++			     drm_radeon_texture_regs_t * tex,
++			     unsigned int dirty)
+ {
+ 	RING_LOCALS;
+-	DRM_DEBUG( "dirty=0x%08x\n", dirty );
++	DRM_DEBUG("dirty=0x%08x\n", dirty);
+ 
+-	if ( dirty & RADEON_UPLOAD_CONTEXT ) {
+-		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-						    &ctx->rb3d_depthoffset ) ) {
+-			DRM_ERROR( "Invalid depth buffer offset\n" );
+-			return DRM_ERR( EINVAL );
++	if (dirty & RADEON_UPLOAD_CONTEXT) {
++		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
++						  &ctx->rb3d_depthoffset)) {
++			DRM_ERROR("Invalid depth buffer offset\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 
+-		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-						    &ctx->rb3d_coloroffset ) ) {
+-			DRM_ERROR( "Invalid depth buffer offset\n" );
+-			return DRM_ERR( EINVAL );
++		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
++						  &ctx->rb3d_coloroffset)) {
++			DRM_ERROR("Invalid depth buffer offset\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 
+-		BEGIN_RING( 14 );
+-		OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) );
+-		OUT_RING( ctx->pp_misc );
+-		OUT_RING( ctx->pp_fog_color );
+-		OUT_RING( ctx->re_solid_color );
+-		OUT_RING( ctx->rb3d_blendcntl );
+-		OUT_RING( ctx->rb3d_depthoffset );
+-		OUT_RING( ctx->rb3d_depthpitch );
+-		OUT_RING( ctx->rb3d_zstencilcntl );
+-		OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) );
+-		OUT_RING( ctx->pp_cntl );
+-		OUT_RING( ctx->rb3d_cntl );
+-		OUT_RING( ctx->rb3d_coloroffset );
+-		OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) );
+-		OUT_RING( ctx->rb3d_colorpitch );
++		BEGIN_RING(14);
++		OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6));
++		OUT_RING(ctx->pp_misc);
++		OUT_RING(ctx->pp_fog_color);
++		OUT_RING(ctx->re_solid_color);
++		OUT_RING(ctx->rb3d_blendcntl);
++		OUT_RING(ctx->rb3d_depthoffset);
++		OUT_RING(ctx->rb3d_depthpitch);
++		OUT_RING(ctx->rb3d_zstencilcntl);
++		OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2));
++		OUT_RING(ctx->pp_cntl);
++		OUT_RING(ctx->rb3d_cntl);
++		OUT_RING(ctx->rb3d_coloroffset);
++		OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0));
++		OUT_RING(ctx->rb3d_colorpitch);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_VERTFMT ) {
+-		BEGIN_RING( 2 );
+-		OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) );
+-		OUT_RING( ctx->se_coord_fmt );
++	if (dirty & RADEON_UPLOAD_VERTFMT) {
++		BEGIN_RING(2);
++		OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0));
++		OUT_RING(ctx->se_coord_fmt);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_LINE ) {
+-		BEGIN_RING( 5 );
+-		OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) );
+-		OUT_RING( ctx->re_line_pattern );
+-		OUT_RING( ctx->re_line_state );
+-		OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) );
+-		OUT_RING( ctx->se_line_width );
++	if (dirty & RADEON_UPLOAD_LINE) {
++		BEGIN_RING(5);
++		OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1));
++		OUT_RING(ctx->re_line_pattern);
++		OUT_RING(ctx->re_line_state);
++		OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0));
++		OUT_RING(ctx->se_line_width);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_BUMPMAP ) {
+-		BEGIN_RING( 5 );
+-		OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) );
+-		OUT_RING( ctx->pp_lum_matrix );
+-		OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) );
+-		OUT_RING( ctx->pp_rot_matrix_0 );
+-		OUT_RING( ctx->pp_rot_matrix_1 );
++	if (dirty & RADEON_UPLOAD_BUMPMAP) {
++		BEGIN_RING(5);
++		OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0));
++		OUT_RING(ctx->pp_lum_matrix);
++		OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1));
++		OUT_RING(ctx->pp_rot_matrix_0);
++		OUT_RING(ctx->pp_rot_matrix_1);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_MASKS ) {
+-		BEGIN_RING( 4 );
+-		OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) );
+-		OUT_RING( ctx->rb3d_stencilrefmask );
+-		OUT_RING( ctx->rb3d_ropcntl );
+-		OUT_RING( ctx->rb3d_planemask );
++	if (dirty & RADEON_UPLOAD_MASKS) {
++		BEGIN_RING(4);
++		OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2));
++		OUT_RING(ctx->rb3d_stencilrefmask);
++		OUT_RING(ctx->rb3d_ropcntl);
++		OUT_RING(ctx->rb3d_planemask);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_VIEWPORT ) {
+-		BEGIN_RING( 7 );
+-		OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) );
+-		OUT_RING( ctx->se_vport_xscale );
+-		OUT_RING( ctx->se_vport_xoffset );
+-		OUT_RING( ctx->se_vport_yscale );
+-		OUT_RING( ctx->se_vport_yoffset );
+-		OUT_RING( ctx->se_vport_zscale );
+-		OUT_RING( ctx->se_vport_zoffset );
++	if (dirty & RADEON_UPLOAD_VIEWPORT) {
++		BEGIN_RING(7);
++		OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5));
++		OUT_RING(ctx->se_vport_xscale);
++		OUT_RING(ctx->se_vport_xoffset);
++		OUT_RING(ctx->se_vport_yscale);
++		OUT_RING(ctx->se_vport_yoffset);
++		OUT_RING(ctx->se_vport_zscale);
++		OUT_RING(ctx->se_vport_zoffset);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_SETUP ) {
+-		BEGIN_RING( 4 );
+-		OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) );
+-		OUT_RING( ctx->se_cntl );
+-		OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) );
+-		OUT_RING( ctx->se_cntl_status );
++	if (dirty & RADEON_UPLOAD_SETUP) {
++		BEGIN_RING(4);
++		OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0));
++		OUT_RING(ctx->se_cntl);
++		OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0));
++		OUT_RING(ctx->se_cntl_status);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_MISC ) {
+-		BEGIN_RING( 2 );
+-		OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) );
+-		OUT_RING( ctx->re_misc );
++	if (dirty & RADEON_UPLOAD_MISC) {
++		BEGIN_RING(2);
++		OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0));
++		OUT_RING(ctx->re_misc);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_TEX0 ) {
+-		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-						    &tex[0].pp_txoffset ) ) {
+-			DRM_ERROR( "Invalid texture offset for unit 0\n" );
+-			return DRM_ERR( EINVAL );
++	if (dirty & RADEON_UPLOAD_TEX0) {
++		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
++						  &tex[0].pp_txoffset)) {
++			DRM_ERROR("Invalid texture offset for unit 0\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 
+-		BEGIN_RING( 9 );
+-		OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) );
+-		OUT_RING( tex[0].pp_txfilter );
+-		OUT_RING( tex[0].pp_txformat );
+-		OUT_RING( tex[0].pp_txoffset );
+-		OUT_RING( tex[0].pp_txcblend );
+-		OUT_RING( tex[0].pp_txablend );
+-		OUT_RING( tex[0].pp_tfactor );
+-		OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) );
+-		OUT_RING( tex[0].pp_border_color );
++		BEGIN_RING(9);
++		OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5));
++		OUT_RING(tex[0].pp_txfilter);
++		OUT_RING(tex[0].pp_txformat);
++		OUT_RING(tex[0].pp_txoffset);
++		OUT_RING(tex[0].pp_txcblend);
++		OUT_RING(tex[0].pp_txablend);
++		OUT_RING(tex[0].pp_tfactor);
++		OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0));
++		OUT_RING(tex[0].pp_border_color);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_TEX1 ) {
+-		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-						    &tex[1].pp_txoffset ) ) {
+-			DRM_ERROR( "Invalid texture offset for unit 1\n" );
+-			return DRM_ERR( EINVAL );
++	if (dirty & RADEON_UPLOAD_TEX1) {
++		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
++						  &tex[1].pp_txoffset)) {
++			DRM_ERROR("Invalid texture offset for unit 1\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 
+-		BEGIN_RING( 9 );
+-		OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) );
+-		OUT_RING( tex[1].pp_txfilter );
+-		OUT_RING( tex[1].pp_txformat );
+-		OUT_RING( tex[1].pp_txoffset );
+-		OUT_RING( tex[1].pp_txcblend );
+-		OUT_RING( tex[1].pp_txablend );
+-		OUT_RING( tex[1].pp_tfactor );
+-		OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) );
+-		OUT_RING( tex[1].pp_border_color );
++		BEGIN_RING(9);
++		OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5));
++		OUT_RING(tex[1].pp_txfilter);
++		OUT_RING(tex[1].pp_txformat);
++		OUT_RING(tex[1].pp_txoffset);
++		OUT_RING(tex[1].pp_txcblend);
++		OUT_RING(tex[1].pp_txablend);
++		OUT_RING(tex[1].pp_tfactor);
++		OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0));
++		OUT_RING(tex[1].pp_border_color);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	if ( dirty & RADEON_UPLOAD_TEX2 ) {
+-		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+-						    &tex[2].pp_txoffset ) ) {
+-			DRM_ERROR( "Invalid texture offset for unit 2\n" );
+-			return DRM_ERR( EINVAL );
++	if (dirty & RADEON_UPLOAD_TEX2) {
++		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
++						  &tex[2].pp_txoffset)) {
++			DRM_ERROR("Invalid texture offset for unit 2\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 
+-		BEGIN_RING( 9 );
+-		OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) );
+-		OUT_RING( tex[2].pp_txfilter );
+-		OUT_RING( tex[2].pp_txformat );
+-		OUT_RING( tex[2].pp_txoffset );
+-		OUT_RING( tex[2].pp_txcblend );
+-		OUT_RING( tex[2].pp_txablend );
+-		OUT_RING( tex[2].pp_tfactor );
+-		OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) );
+-		OUT_RING( tex[2].pp_border_color );
++		BEGIN_RING(9);
++		OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5));
++		OUT_RING(tex[2].pp_txfilter);
++		OUT_RING(tex[2].pp_txformat);
++		OUT_RING(tex[2].pp_txoffset);
++		OUT_RING(tex[2].pp_txcblend);
++		OUT_RING(tex[2].pp_txablend);
++		OUT_RING(tex[2].pp_tfactor);
++		OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0));
++		OUT_RING(tex[2].pp_border_color);
+ 		ADVANCE_RING();
+ 	}
+ 
+@@ -456,129 +478,137 @@ static int radeon_emit_state( drm_radeon
+ 
+ /* Emit 1.2 state
+  */
+-static int radeon_emit_state2( drm_radeon_private_t *dev_priv,
+-			       drm_file_t *filp_priv,
+-			       drm_radeon_state_t *state )
++static int radeon_emit_state2(drm_radeon_private_t * dev_priv,
++			      drm_file_t * filp_priv,
++			      drm_radeon_state_t * state)
+ {
+ 	RING_LOCALS;
+ 
+ 	if (state->dirty & RADEON_UPLOAD_ZBIAS) {
+-		BEGIN_RING( 3 );
+-		OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) );
+-		OUT_RING( state->context2.se_zbias_factor ); 
+-		OUT_RING( state->context2.se_zbias_constant ); 
++		BEGIN_RING(3);
++		OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1));
++		OUT_RING(state->context2.se_zbias_factor);
++		OUT_RING(state->context2.se_zbias_constant);
+ 		ADVANCE_RING();
+ 	}
+ 
+-	return radeon_emit_state( dev_priv, filp_priv, &state->context,
+-			   state->tex, state->dirty );
++	return radeon_emit_state(dev_priv, filp_priv, &state->context,
++				 state->tex, state->dirty);
+ }
+ 
+ /* New (1.3) state mechanism.  3 commands (packet, scalar, vector) in
+  * 1.3 cmdbuffers allow all previous state to be updated as well as
+- * the tcl scalar and vector areas.  
++ * the tcl scalar and vector areas.
+  */
+-static struct { 
+-	int start; 
+-	int len; 
++static struct {
++	int start;
++	int len;
+ 	const char *name;
+ } packet[RADEON_MAX_STATE_PACKETS] = {
+-	{ RADEON_PP_MISC,7,"RADEON_PP_MISC" },
+-	{ RADEON_PP_CNTL,3,"RADEON_PP_CNTL" },
+-	{ RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" },
+-	{ RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" },
+-	{ RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" },
+-	{ RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" },
+-	{ RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" },
+-	{ RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" },
+-	{ RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" },
+-	{ RADEON_SE_CNTL,2,"RADEON_SE_CNTL" },
+-	{ RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" },
+-	{ RADEON_RE_MISC,1,"RADEON_RE_MISC" },
+-	{ RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" },
+-	{ RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" },
+-	{ RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" },
+-	{ RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" },
+-	{ RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" },
+-	{ RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" },
+-	{ RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" },
+-	{ RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
+-	{ RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
+-	{ R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" },
+-	{ R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" },
+-	{ R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" },
+-	{ R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" },
+-	{ R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" },
+-	{ R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" },
+-	{ R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" },
+-	{ R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" },
+-	{ R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" },
+-	{ R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" },
+-	{ R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" },
+-	{ R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" },
+-	{ R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" },
+-	{ R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" },
+-	{ R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" },
+-	{ R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" },
+-	{ R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" },
+-	{ R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" },
+-	{ R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" },
+-	{ R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" },
+-	{ R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" },
+-	{ R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" },
+-	{ R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" },
+-	{ R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" },
+-	{ R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" },
+-	{ R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" },
+-	{ R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" },
+-	{ R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" },
+-	{ R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" },
+-	{ R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" },
+-	{ R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, 
+-	{ R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, 
+-	{ R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, 
+-	{ R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, 
+-	{ R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, 
+-	{ R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, 
+-	{ R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, 
+-	{ R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, 
+-	{ R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, 
+-	{ R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },
+-	{ R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */
+-	{ R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */
+-	{ R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" },
+-	{ R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" },
+-	{ R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" },
+-	{ R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" },
+-	{ R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" },
+-	{ R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" },
+-	{ R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" },
+-	{ R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" },
+-	{ R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" },
+-	{ R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" },
+-	{ RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" },
+-	{ RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },
+-	{ RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" },
+-	{ R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" },
+-	{ R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL" },
+-	{ RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"},
+-	{ RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
+-	{ RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"},
+-	{ RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
+-	{ RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
+-	{ RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
+-	{ R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
++	{RADEON_PP_MISC, 7, "RADEON_PP_MISC"},
++	{RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"},
++	{RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"},
++	{RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"},
++	{RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"},
++	{RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"},
++	{RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"},
++	{RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"},
++	{RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"},
++	{RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"},
++	{RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"},
++	{RADEON_RE_MISC, 1, "RADEON_RE_MISC"},
++	{RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"},
++	{RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"},
++	{RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"},
++	{RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"},
++	{RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"},
++	{RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"},
++	{RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"},
++	{RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"},
++	{RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17,
++		    "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"},
++	{R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"},
++	{R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"},
++	{R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"},
++	{R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"},
++	{R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"},
++	{R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"},
++	{R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"},
++	{R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"},
++	{R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"},
++	{R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"},
++	{R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"},
++	{R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"},
++	{R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"},
++	{R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"},
++	{R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"},
++	{R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"},
++	{R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"},
++	{R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"},
++	{R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"},
++	{R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"},
++	{R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"},
++	{R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"},
++	{R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"},
++	{R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"},
++	{R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"},
++	{R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"},
++	{R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"},
++	{R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"},
++	{R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
++	{R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"},
++	{R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"},
++	{R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"},
++	{R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"},
++	{R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"},
++	{R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"},
++	{R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"},
++	{R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"},
++	{R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"},
++	{R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"},
++	{R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4,
++		    "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
++	{R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"},	/* 61 */
++	{R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"},	/* 62 */
++	{R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"},
++	{R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
++	{R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"},
++	{R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"},
++	{R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"},
++	{R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"},
++	{R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"},
++	{R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"},
++	{R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"},
++	{R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"},
++	{RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"},
++	{RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"},
++	{RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"},
++	{R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"},
++	{R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},
++	{RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"},
++	{RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
++	{RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"},
++	{RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
++	{RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
++	{RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
++	{R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
++	{R200_PP_AFS_0, 32, "R200_PP_AFS_0"},	/* 85 */
++	{R200_PP_AFS_1, 32, "R200_PP_AFS_1"},
++	{R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},
++	{R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},
++	{R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"},
++	{R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"},
++	{R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"},
++	{R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"},
++	{R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"},
+ };
+ 
+-
+-
+ /* ================================================================
+  * Performance monitoring functions
+  */
+ 
+-static void radeon_clear_box( drm_radeon_private_t *dev_priv,
+-			      int x, int y, int w, int h,
+-			      int r, int g, int b )
++static void radeon_clear_box(drm_radeon_private_t * dev_priv,
++			     int x, int y, int w, int h, int r, int g, int b)
+ {
+ 	u32 color;
+ 	RING_LOCALS;
+@@ -586,49 +616,47 @@ static void radeon_clear_box( drm_radeon
+ 	x += dev_priv->sarea_priv->boxes[0].x1;
+ 	y += dev_priv->sarea_priv->boxes[0].y1;
+ 
+-	switch ( dev_priv->color_fmt ) {
++	switch (dev_priv->color_fmt) {
+ 	case RADEON_COLOR_FORMAT_RGB565:
+ 		color = (((r & 0xf8) << 8) |
+-			 ((g & 0xfc) << 3) |
+-			 ((b & 0xf8) >> 3));
++			 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
+ 		break;
+ 	case RADEON_COLOR_FORMAT_ARGB8888:
+ 	default:
+-		color = (((0xff) << 24) | (r << 16) | (g <<  8) | b);
++		color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
+ 		break;
+ 	}
+ 
+-	BEGIN_RING( 4 );
+-	RADEON_WAIT_UNTIL_3D_IDLE();		
+-	OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
+-	OUT_RING( 0xffffffff );
++	BEGIN_RING(4);
++	RADEON_WAIT_UNTIL_3D_IDLE();
++	OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
++	OUT_RING(0xffffffff);
+ 	ADVANCE_RING();
+ 
+-	BEGIN_RING( 6 );
++	BEGIN_RING(6);
+ 
+-	OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
+-	OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+-		  RADEON_GMC_BRUSH_SOLID_COLOR |
+-		  (dev_priv->color_fmt << 8) |
+-		  RADEON_GMC_SRC_DATATYPE_COLOR |
+-		  RADEON_ROP3_P |
+-		  RADEON_GMC_CLR_CMP_CNTL_DIS );
+-
+- 	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { 
+-		OUT_RING( dev_priv->front_pitch_offset );
+- 	} else {	 
+-		OUT_RING( dev_priv->back_pitch_offset );
+- 	} 
++	OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
++	OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
++		 RADEON_GMC_BRUSH_SOLID_COLOR |
++		 (dev_priv->color_fmt << 8) |
++		 RADEON_GMC_SRC_DATATYPE_COLOR |
++		 RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
+ 
+-	OUT_RING( color );
++	if (dev_priv->page_flipping && dev_priv->current_page == 1) {
++		OUT_RING(dev_priv->front_pitch_offset);
++	} else {
++		OUT_RING(dev_priv->back_pitch_offset);
++	}
+ 
+-	OUT_RING( (x << 16) | y );
+-	OUT_RING( (w << 16) | h );
++	OUT_RING(color);
++
++	OUT_RING((x << 16) | y);
++	OUT_RING((w << 16) | h);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv )
++static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
+ {
+ 	/* Collapse various things into a wait flag -- trying to
+ 	 * guess if userspase slept -- better just to have them tell us.
+@@ -644,50 +672,50 @@ static void radeon_cp_performance_boxes(
+ 
+ 	/* Purple box for page flipping
+ 	 */
+-	if ( dev_priv->stats.boxes & RADEON_BOX_FLIP ) 
+-		radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 );
++	if (dev_priv->stats.boxes & RADEON_BOX_FLIP)
++		radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255);
+ 
+ 	/* Red box if we have to wait for idle at any point
+ 	 */
+-	if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE ) 
+-		radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 );
++	if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE)
++		radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0);
+ 
+ 	/* Blue box: lost context?
+ 	 */
+ 
+ 	/* Yellow box for texture swaps
+ 	 */
+-	if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD ) 
+-		radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 );
++	if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD)
++		radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0);
+ 
+ 	/* Green box if hardware never idles (as far as we can tell)
+ 	 */
+-	if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) ) 
+-		radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
+-
++	if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE))
++		radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
+ 
+-	/* Draw bars indicating number of buffers allocated 
++	/* Draw bars indicating number of buffers allocated
+ 	 * (not a great measure, easily confused)
+ 	 */
+ 	if (dev_priv->stats.requested_bufs) {
+ 		if (dev_priv->stats.requested_bufs > 100)
+ 			dev_priv->stats.requested_bufs = 100;
+ 
+-		radeon_clear_box( dev_priv, 4, 16,  
+-				  dev_priv->stats.requested_bufs, 4,
+-				  196, 128, 128 );
++		radeon_clear_box(dev_priv, 4, 16,
++				 dev_priv->stats.requested_bufs, 4,
++				 196, 128, 128);
+ 	}
+ 
+-	memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) );
++	memset(&dev_priv->stats, 0, sizeof(dev_priv->stats));
+ 
+ }
++
+ /* ================================================================
+  * CP command dispatch functions
+  */
+ 
+-static void radeon_cp_dispatch_clear( drm_device_t *dev,
+-				      drm_radeon_clear_t *clear,
+-				      drm_radeon_clear_rect_t *depth_boxes )
++static void radeon_cp_dispatch_clear(drm_device_t * dev,
++				     drm_radeon_clear_t * clear,
++				     drm_radeon_clear_rect_t * depth_boxes)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+@@ -695,32 +723,34 @@ static void radeon_cp_dispatch_clear( dr
+ 	int nbox = sarea_priv->nbox;
+ 	drm_clip_rect_t *pbox = sarea_priv->boxes;
+ 	unsigned int flags = clear->flags;
+-	u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0;
++	u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0;
+ 	int i;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "flags = 0x%x\n", flags );
++	DRM_DEBUG("flags = 0x%x\n", flags);
+ 
+ 	dev_priv->stats.clears++;
+ 
+-	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
++	if (dev_priv->page_flipping && dev_priv->current_page == 1) {
+ 		unsigned int tmp = flags;
+ 
+ 		flags &= ~(RADEON_FRONT | RADEON_BACK);
+-		if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK;
+-		if ( tmp & RADEON_BACK )  flags |= RADEON_FRONT;
++		if (tmp & RADEON_FRONT)
++			flags |= RADEON_BACK;
++		if (tmp & RADEON_BACK)
++			flags |= RADEON_FRONT;
+ 	}
+ 
+-	if ( flags & (RADEON_FRONT | RADEON_BACK) ) {
++	if (flags & (RADEON_FRONT | RADEON_BACK)) {
+ 
+-		BEGIN_RING( 4 );
++		BEGIN_RING(4);
+ 
+ 		/* Ensure the 3D stream is idle before doing a
+ 		 * 2D fill to clear the front or back buffer.
+ 		 */
+ 		RADEON_WAIT_UNTIL_3D_IDLE();
+-		
+-		OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
+-		OUT_RING( clear->color_mask );
++
++		OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
++		OUT_RING(clear->color_mask);
+ 
+ 		ADVANCE_RING();
+ 
+@@ -728,121 +758,130 @@ static void radeon_cp_dispatch_clear( dr
+ 		 */
+ 		dev_priv->sarea_priv->ctx_owner = 0;
+ 
+-		for ( i = 0 ; i < nbox ; i++ ) {
++		for (i = 0; i < nbox; i++) {
+ 			int x = pbox[i].x1;
+ 			int y = pbox[i].y1;
+ 			int w = pbox[i].x2 - x;
+ 			int h = pbox[i].y2 - y;
+ 
+-			DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
+-				   x, y, w, h, flags );
++			DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
++				  x, y, w, h, flags);
++
++			if (flags & RADEON_FRONT) {
++				BEGIN_RING(6);
++
++				OUT_RING(CP_PACKET3
++					 (RADEON_CNTL_PAINT_MULTI, 4));
++				OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
++					 RADEON_GMC_BRUSH_SOLID_COLOR |
++					 (dev_priv->
++					  color_fmt << 8) |
++					 RADEON_GMC_SRC_DATATYPE_COLOR |
++					 RADEON_ROP3_P |
++					 RADEON_GMC_CLR_CMP_CNTL_DIS);
++
++				OUT_RING(dev_priv->front_pitch_offset);
++				OUT_RING(clear->clear_color);
++
++				OUT_RING((x << 16) | y);
++				OUT_RING((w << 16) | h);
+ 
+-			if ( flags & RADEON_FRONT ) {
+-				BEGIN_RING( 6 );
+-				
+-				OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
+-				OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+-					  RADEON_GMC_BRUSH_SOLID_COLOR |
+-					  (dev_priv->color_fmt << 8) |
+-					  RADEON_GMC_SRC_DATATYPE_COLOR |
+-					  RADEON_ROP3_P |
+-					  RADEON_GMC_CLR_CMP_CNTL_DIS );
+-
+-				OUT_RING( dev_priv->front_pitch_offset );
+-				OUT_RING( clear->clear_color );
+-				
+-				OUT_RING( (x << 16) | y );
+-				OUT_RING( (w << 16) | h );
+-				
+ 				ADVANCE_RING();
+ 			}
+-			
+-			if ( flags & RADEON_BACK ) {
+-				BEGIN_RING( 6 );
+-				
+-				OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
+-				OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+-					  RADEON_GMC_BRUSH_SOLID_COLOR |
+-					  (dev_priv->color_fmt << 8) |
+-					  RADEON_GMC_SRC_DATATYPE_COLOR |
+-					  RADEON_ROP3_P |
+-					  RADEON_GMC_CLR_CMP_CNTL_DIS );
+-				
+-				OUT_RING( dev_priv->back_pitch_offset );
+-				OUT_RING( clear->clear_color );
+ 
+-				OUT_RING( (x << 16) | y );
+-				OUT_RING( (w << 16) | h );
++			if (flags & RADEON_BACK) {
++				BEGIN_RING(6);
++
++				OUT_RING(CP_PACKET3
++					 (RADEON_CNTL_PAINT_MULTI, 4));
++				OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
++					 RADEON_GMC_BRUSH_SOLID_COLOR |
++					 (dev_priv->
++					  color_fmt << 8) |
++					 RADEON_GMC_SRC_DATATYPE_COLOR |
++					 RADEON_ROP3_P |
++					 RADEON_GMC_CLR_CMP_CNTL_DIS);
++
++				OUT_RING(dev_priv->back_pitch_offset);
++				OUT_RING(clear->clear_color);
++
++				OUT_RING((x << 16) | y);
++				OUT_RING((w << 16) | h);
+ 
+ 				ADVANCE_RING();
+ 			}
+ 		}
+ 	}
+-	
++
+ 	/* hyper z clear */
+ 	/* no docs available, based on reverse engeneering by Stephane Marchesin */
+-	if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) && (flags & RADEON_CLEAR_FASTZ)) {
++	if ((flags & (RADEON_DEPTH | RADEON_STENCIL))
++	    && (flags & RADEON_CLEAR_FASTZ)) {
+ 
+ 		int i;
+-		int depthpixperline = dev_priv->depth_fmt==RADEON_DEPTH_FORMAT_16BIT_INT_Z? 
+-			(dev_priv->depth_pitch / 2): (dev_priv->depth_pitch / 4);
+-		
++		int depthpixperline =
++		    dev_priv->depth_fmt ==
++		    RADEON_DEPTH_FORMAT_16BIT_INT_Z ? (dev_priv->depth_pitch /
++						       2) : (dev_priv->
++							     depth_pitch / 4);
++
+ 		u32 clearmask;
+ 
+ 		u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth |
+-			((clear->depth_mask & 0xff) << 24);
+-	
+-		
++		    ((clear->depth_mask & 0xff) << 24);
++
+ 		/* Make sure we restore the 3D state next time.
+ 		 * we haven't touched any "normal" state - still need this?
+ 		 */
+ 		dev_priv->sarea_priv->ctx_owner = 0;
+ 
+-		if ((dev_priv->flags & CHIP_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) {
+-		/* FIXME : reverse engineer that for Rx00 cards */
+-		/* FIXME : the mask supposedly contains low-res z values. So can't set
+-		   just to the max (0xff? or actually 0x3fff?), need to take z clear
+-		   value into account? */
+-		/* pattern seems to work for r100, though get slight
+-		   rendering errors with glxgears. If hierz is not enabled for r100,
+-		   only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
+-		   other ones are ignored, and the same clear mask can be used. That's
+-		   very different behaviour than R200 which needs different clear mask
+-		   and different number of tiles to clear if hierz is enabled or not !?!
+-		*/
+-			clearmask = (0xff<<22)|(0xff<<6)| 0x003f003f;
+-		}
+-		else {
+-		/* clear mask : chooses the clearing pattern.
+-		   rv250: could be used to clear only parts of macrotiles
+-		   (but that would get really complicated...)?
+-		   bit 0 and 1 (either or both of them ?!?!) are used to
+-		   not clear tile (or maybe one of the bits indicates if the tile is
+-		   compressed or not), bit 2 and 3 to not clear tile 1,...,.
+-		   Pattern is as follows:
+-		        | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
+-		   bits -------------------------------------------------
+-		        | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
+-		   rv100: clearmask covers 2x8 4x1 tiles, but one clear still
+-		   covers 256 pixels ?!?
+-		*/
++		if ((dev_priv->flags & CHIP_HAS_HIERZ)
++		    && (flags & RADEON_USE_HIERZ)) {
++			/* FIXME : reverse engineer that for Rx00 cards */
++			/* FIXME : the mask supposedly contains low-res z values. So can't set
++			   just to the max (0xff? or actually 0x3fff?), need to take z clear
++			   value into account? */
++			/* pattern seems to work for r100, though get slight
++			   rendering errors with glxgears. If hierz is not enabled for r100,
++			   only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
++			   other ones are ignored, and the same clear mask can be used. That's
++			   very different behaviour than R200 which needs different clear mask
++			   and different number of tiles to clear if hierz is enabled or not !?!
++			 */
++			clearmask = (0xff << 22) | (0xff << 6) | 0x003f003f;
++		} else {
++			/* clear mask : chooses the clearing pattern.
++			   rv250: could be used to clear only parts of macrotiles
++			   (but that would get really complicated...)?
++			   bit 0 and 1 (either or both of them ?!?!) are used to
++			   not clear tile (or maybe one of the bits indicates if the tile is
++			   compressed or not), bit 2 and 3 to not clear tile 1,...,.
++			   Pattern is as follows:
++			   | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
++			   bits -------------------------------------------------
++			   | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
++			   rv100: clearmask covers 2x8 4x1 tiles, but one clear still
++			   covers 256 pixels ?!?
++			 */
+ 			clearmask = 0x0;
+ 		}
+ 
+-		BEGIN_RING( 8 );
++		BEGIN_RING(8);
+ 		RADEON_WAIT_UNTIL_2D_IDLE();
+-		OUT_RING_REG( RADEON_RB3D_DEPTHCLEARVALUE,
+-			tempRB3D_DEPTHCLEARVALUE);
++		OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE,
++			     tempRB3D_DEPTHCLEARVALUE);
+ 		/* what offset is this exactly ? */
+-		OUT_RING_REG( RADEON_RB3D_ZMASKOFFSET, 0 );
++		OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET, 0);
+ 		/* need ctlstat, otherwise get some strange black flickering */
+-		OUT_RING_REG( RADEON_RB3D_ZCACHE_CTLSTAT, RADEON_RB3D_ZC_FLUSH_ALL );
++		OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT,
++			     RADEON_RB3D_ZC_FLUSH_ALL);
+ 		ADVANCE_RING();
+ 
+ 		for (i = 0; i < nbox; i++) {
+ 			int tileoffset, nrtilesx, nrtilesy, j;
+ 			/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
+-			if ((dev_priv->flags&CHIP_HAS_HIERZ) && !(dev_priv->microcode_version==UCODE_R200)) {
++			if ((dev_priv->flags & CHIP_HAS_HIERZ)
++			    && !(dev_priv->microcode_version == UCODE_R200)) {
+ 				/* FIXME : figure this out for r200 (when hierz is enabled). Or
+ 				   maybe r200 actually doesn't need to put the low-res z value into
+ 				   the tile cache like r100, but just needs to clear the hi-level z-buffer?
+@@ -850,59 +889,74 @@ static void radeon_cp_dispatch_clear( dr
+ 				   R100 seems to operate on 2x1 8x8 tiles, but...
+ 				   odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially
+ 				   problematic with resolutions which are not 64 pix aligned? */
+-				tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 6;
+-				nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4;
+-				nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
++				tileoffset =
++				    ((pbox[i].y1 >> 3) * depthpixperline +
++				     pbox[i].x1) >> 6;
++				nrtilesx =
++				    ((pbox[i].x2 & ~63) -
++				     (pbox[i].x1 & ~63)) >> 4;
++				nrtilesy =
++				    (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
+ 				for (j = 0; j <= nrtilesy; j++) {
+-					BEGIN_RING( 4 );
+-					OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
++					BEGIN_RING(4);
++					OUT_RING(CP_PACKET3
++						 (RADEON_3D_CLEAR_ZMASK, 2));
+ 					/* first tile */
+-					OUT_RING( tileoffset * 8 );
++					OUT_RING(tileoffset * 8);
+ 					/* the number of tiles to clear */
+-					OUT_RING( nrtilesx + 4 );
++					OUT_RING(nrtilesx + 4);
+ 					/* clear mask : chooses the clearing pattern. */
+-					OUT_RING( clearmask );
++					OUT_RING(clearmask);
+ 					ADVANCE_RING();
+ 					tileoffset += depthpixperline >> 6;
+ 				}
+-			}
+-			else if (dev_priv->microcode_version==UCODE_R200) {
++			} else if (dev_priv->microcode_version == UCODE_R200) {
+ 				/* works for rv250. */
+ 				/* find first macro tile (8x2 4x4 z-pixels on rv250) */
+-				tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 5;
+-				nrtilesx = (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
+-				nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
++				tileoffset =
++				    ((pbox[i].y1 >> 3) * depthpixperline +
++				     pbox[i].x1) >> 5;
++				nrtilesx =
++				    (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
++				nrtilesy =
++				    (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
+ 				for (j = 0; j <= nrtilesy; j++) {
+-					BEGIN_RING( 4 );
+-					OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
++					BEGIN_RING(4);
++					OUT_RING(CP_PACKET3
++						 (RADEON_3D_CLEAR_ZMASK, 2));
+ 					/* first tile */
+ 					/* judging by the first tile offset needed, could possibly
+ 					   directly address/clear 4x4 tiles instead of 8x2 * 4x4
+ 					   macro tiles, though would still need clear mask for
+ 					   right/bottom if truely 4x4 granularity is desired ? */
+-					OUT_RING( tileoffset * 16 );
++					OUT_RING(tileoffset * 16);
+ 					/* the number of tiles to clear */
+-					OUT_RING( nrtilesx + 1 );
++					OUT_RING(nrtilesx + 1);
+ 					/* clear mask : chooses the clearing pattern. */
+-					OUT_RING( clearmask );
++					OUT_RING(clearmask);
+ 					ADVANCE_RING();
+ 					tileoffset += depthpixperline >> 5;
+ 				}
+-			}
+-			else { /* rv 100 */
++			} else {	/* rv 100 */
+ 				/* rv100 might not need 64 pix alignment, who knows */
+ 				/* offsets are, hmm, weird */
+-				tileoffset = ((pbox[i].y1 >> 4) * depthpixperline + pbox[i].x1) >> 6;
+-				nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4;
+-				nrtilesy = (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
++				tileoffset =
++				    ((pbox[i].y1 >> 4) * depthpixperline +
++				     pbox[i].x1) >> 6;
++				nrtilesx =
++				    ((pbox[i].x2 & ~63) -
++				     (pbox[i].x1 & ~63)) >> 4;
++				nrtilesy =
++				    (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
+ 				for (j = 0; j <= nrtilesy; j++) {
+-					BEGIN_RING( 4 );
+-					OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
+-					OUT_RING( tileoffset * 128 );
++					BEGIN_RING(4);
++					OUT_RING(CP_PACKET3
++						 (RADEON_3D_CLEAR_ZMASK, 2));
++					OUT_RING(tileoffset * 128);
+ 					/* the number of tiles to clear */
+-					OUT_RING( nrtilesx + 4 );
++					OUT_RING(nrtilesx + 4);
+ 					/* clear mask : chooses the clearing pattern. */
+-					OUT_RING( clearmask );
++					OUT_RING(clearmask);
+ 					ADVANCE_RING();
+ 					tileoffset += depthpixperline >> 6;
+ 				}
+@@ -910,18 +964,19 @@ static void radeon_cp_dispatch_clear( dr
+ 		}
+ 
+ 		/* TODO don't always clear all hi-level z tiles */
+-		if ((dev_priv->flags & CHIP_HAS_HIERZ) && (dev_priv->microcode_version==UCODE_R200)
+-			&& (flags & RADEON_USE_HIERZ))
+-		/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
+-		/* FIXME : the mask supposedly contains low-res z values. So can't set
+-		   just to the max (0xff? or actually 0x3fff?), need to take z clear
+-		   value into account? */
++		if ((dev_priv->flags & CHIP_HAS_HIERZ)
++		    && (dev_priv->microcode_version == UCODE_R200)
++		    && (flags & RADEON_USE_HIERZ))
++			/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
++			/* FIXME : the mask supposedly contains low-res z values. So can't set
++			   just to the max (0xff? or actually 0x3fff?), need to take z clear
++			   value into account? */
+ 		{
+-			BEGIN_RING( 4 );
+-			OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_HIZ, 2 ) );
+-			OUT_RING( 0x0 ); /* First tile */
+-			OUT_RING( 0x3cc0 );
+-			OUT_RING( (0xff<<22)|(0xff<<6)| 0x003f003f);
++			BEGIN_RING(4);
++			OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ, 2));
++			OUT_RING(0x0);	/* First tile */
++			OUT_RING(0x3cc0);
++			OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f);
+ 			ADVANCE_RING();
+ 		}
+ 	}
+@@ -956,30 +1011,27 @@ static void radeon_cp_dispatch_clear( dr
+ 
+ 		tempSE_CNTL = depth_clear->se_cntl;
+ 
+-
+-
+ 		/* Disable TCL */
+ 
+-		tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK |  */
+-				   (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
++		tempSE_VAP_CNTL = (	/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK |  */
++					  (0x9 <<
++					   SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
+ 
+ 		tempRB3D_PLANEMASK = 0x0;
+ 
+ 		tempRE_AUX_SCISSOR_CNTL = 0x0;
+ 
+ 		tempSE_VTE_CNTL =
+-			SE_VTE_CNTL__VTX_XY_FMT_MASK |
+-			SE_VTE_CNTL__VTX_Z_FMT_MASK;
++		    SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK;
+ 
+-		/* Vertex format (X, Y, Z, W)*/
++		/* Vertex format (X, Y, Z, W) */
+ 		tempSE_VTX_FMT_0 =
+-			SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |
+-			SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;
++		    SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |
++		    SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;
+ 		tempSE_VTX_FMT_1 = 0x0;
+ 
+-
+-		/* 
+-		 * Depth buffer specific enables 
++		/*
++		 * Depth buffer specific enables
+ 		 */
+ 		if (flags & RADEON_DEPTH) {
+ 			/* Enable depth buffer */
+@@ -989,12 +1041,12 @@ static void radeon_cp_dispatch_clear( dr
+ 			tempRB3D_CNTL &= ~RADEON_Z_ENABLE;
+ 		}
+ 
+-		/* 
++		/*
+ 		 * Stencil buffer specific enables
+ 		 */
+-		if ( flags & RADEON_STENCIL ) {
+-			tempRB3D_CNTL |=  RADEON_STENCIL_ENABLE;
+-			tempRB3D_STENCILREFMASK = clear->depth_mask; 
++		if (flags & RADEON_STENCIL) {
++			tempRB3D_CNTL |= RADEON_STENCIL_ENABLE;
++			tempRB3D_STENCILREFMASK = clear->depth_mask;
+ 		} else {
+ 			tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE;
+ 			tempRB3D_STENCILREFMASK = 0x00000000;
+@@ -1002,79 +1054,75 @@ static void radeon_cp_dispatch_clear( dr
+ 
+ 		if (flags & RADEON_USE_COMP_ZBUF) {
+ 			tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
+-				RADEON_Z_DECOMPRESSION_ENABLE;
++			    RADEON_Z_DECOMPRESSION_ENABLE;
+ 		}
+ 		if (flags & RADEON_USE_HIERZ) {
+ 			tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
+ 		}
+ 
+-		BEGIN_RING( 26 );
++		BEGIN_RING(26);
+ 		RADEON_WAIT_UNTIL_2D_IDLE();
+ 
+-		OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL );
+-		OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL );
+-		OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL );
+-		OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL,
+-			      tempRB3D_ZSTENCILCNTL );
+-		OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, 
+-			      tempRB3D_STENCILREFMASK );
+-		OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK );
+-		OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL );
+-		OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL );
+-		OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 );
+-		OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 );
+-		OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL );
+-		OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL, 
+-			      tempRE_AUX_SCISSOR_CNTL );
++		OUT_RING_REG(RADEON_PP_CNTL, tempPP_CNTL);
++		OUT_RING_REG(R200_RE_CNTL, tempRE_CNTL);
++		OUT_RING_REG(RADEON_RB3D_CNTL, tempRB3D_CNTL);
++		OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
++		OUT_RING_REG(RADEON_RB3D_STENCILREFMASK,
++			     tempRB3D_STENCILREFMASK);
++		OUT_RING_REG(RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK);
++		OUT_RING_REG(RADEON_SE_CNTL, tempSE_CNTL);
++		OUT_RING_REG(R200_SE_VTE_CNTL, tempSE_VTE_CNTL);
++		OUT_RING_REG(R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0);
++		OUT_RING_REG(R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1);
++		OUT_RING_REG(R200_SE_VAP_CNTL, tempSE_VAP_CNTL);
++		OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL);
+ 		ADVANCE_RING();
+ 
+ 		/* Make sure we restore the 3D state next time.
+ 		 */
+ 		dev_priv->sarea_priv->ctx_owner = 0;
+ 
+-		for ( i = 0 ; i < nbox ; i++ ) {
+-			
+-			/* Funny that this should be required -- 
++		for (i = 0; i < nbox; i++) {
++
++			/* Funny that this should be required --
+ 			 *  sets top-left?
+ 			 */
+-			radeon_emit_clip_rect( dev_priv,
+-					       &sarea_priv->boxes[i] );
++			radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
+ 
+-			BEGIN_RING( 14 );
+-			OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) );
+-			OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |
+-				   RADEON_PRIM_WALK_RING |
+-				   (3 << RADEON_NUM_VERTICES_SHIFT)) );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_Y1] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+-			OUT_RING( 0x3f800000 );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+-			OUT_RING( 0x3f800000 );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_X2] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+-			OUT_RING( 0x3f800000 );
++			BEGIN_RING(14);
++			OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 12));
++			OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
++				  RADEON_PRIM_WALK_RING |
++				  (3 << RADEON_NUM_VERTICES_SHIFT)));
++			OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
++			OUT_RING(0x3f800000);
++			OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
++			OUT_RING(0x3f800000);
++			OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
++			OUT_RING(0x3f800000);
+ 			ADVANCE_RING();
+ 		}
+-	} 
+-	else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) {
++	} else if ((flags & (RADEON_DEPTH | RADEON_STENCIL))) {
+ 
+ 		int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
+ 
+ 		rb3d_cntl = depth_clear->rb3d_cntl;
+ 
+-		if ( flags & RADEON_DEPTH ) {
+-			rb3d_cntl |=  RADEON_Z_ENABLE;
++		if (flags & RADEON_DEPTH) {
++			rb3d_cntl |= RADEON_Z_ENABLE;
+ 		} else {
+ 			rb3d_cntl &= ~RADEON_Z_ENABLE;
+ 		}
+ 
+-		if ( flags & RADEON_STENCIL ) {
+-			rb3d_cntl |=  RADEON_STENCIL_ENABLE;
+-			rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */
++		if (flags & RADEON_STENCIL) {
++			rb3d_cntl |= RADEON_STENCIL_ENABLE;
++			rb3d_stencilrefmask = clear->depth_mask;	/* misnamed field */
+ 		} else {
+ 			rb3d_cntl &= ~RADEON_STENCIL_ENABLE;
+ 			rb3d_stencilrefmask = 0x00000000;
+@@ -1082,66 +1130,61 @@ static void radeon_cp_dispatch_clear( dr
+ 
+ 		if (flags & RADEON_USE_COMP_ZBUF) {
+ 			tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
+-				RADEON_Z_DECOMPRESSION_ENABLE;
++			    RADEON_Z_DECOMPRESSION_ENABLE;
+ 		}
+ 		if (flags & RADEON_USE_HIERZ) {
+ 			tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
+ 		}
+ 
+-		BEGIN_RING( 13 );
++		BEGIN_RING(13);
+ 		RADEON_WAIT_UNTIL_2D_IDLE();
+ 
+-		OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) );
+-		OUT_RING( 0x00000000 );
+-		OUT_RING( rb3d_cntl );
+-		
+-		OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL );
+-		OUT_RING_REG( RADEON_RB3D_STENCILREFMASK,
+-			      rb3d_stencilrefmask );
+-		OUT_RING_REG( RADEON_RB3D_PLANEMASK,
+-			      0x00000000 );
+-		OUT_RING_REG( RADEON_SE_CNTL,
+-			      depth_clear->se_cntl );
++		OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 1));
++		OUT_RING(0x00000000);
++		OUT_RING(rb3d_cntl);
++
++		OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
++		OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask);
++		OUT_RING_REG(RADEON_RB3D_PLANEMASK, 0x00000000);
++		OUT_RING_REG(RADEON_SE_CNTL, depth_clear->se_cntl);
+ 		ADVANCE_RING();
+ 
+ 		/* Make sure we restore the 3D state next time.
+ 		 */
+ 		dev_priv->sarea_priv->ctx_owner = 0;
+ 
+-		for ( i = 0 ; i < nbox ; i++ ) {
+-			
+-			/* Funny that this should be required -- 
++		for (i = 0; i < nbox; i++) {
++
++			/* Funny that this should be required --
+ 			 *  sets top-left?
+ 			 */
+-			radeon_emit_clip_rect( dev_priv,
+-					       &sarea_priv->boxes[i] );
++			radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
+ 
+-			BEGIN_RING( 15 );
++			BEGIN_RING(15);
+ 
+-			OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) );
+-			OUT_RING( RADEON_VTX_Z_PRESENT |
+-				  RADEON_VTX_PKCOLOR_PRESENT);
+-			OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |
+-				   RADEON_PRIM_WALK_RING |
+-				   RADEON_MAOS_ENABLE |
+-				   RADEON_VTX_FMT_RADEON_MODE |
+-				   (3 << RADEON_NUM_VERTICES_SHIFT)) );
+-
+-
+-			OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_Y1] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+-			OUT_RING( 0x0 );
+-
+-			OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+-			OUT_RING( 0x0 );
+-
+-			OUT_RING( depth_boxes[i].ui[CLEAR_X2] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
+-			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+-			OUT_RING( 0x0 );
++			OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD, 13));
++			OUT_RING(RADEON_VTX_Z_PRESENT |
++				 RADEON_VTX_PKCOLOR_PRESENT);
++			OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
++				  RADEON_PRIM_WALK_RING |
++				  RADEON_MAOS_ENABLE |
++				  RADEON_VTX_FMT_RADEON_MODE |
++				  (3 << RADEON_NUM_VERTICES_SHIFT)));
++
++			OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
++			OUT_RING(0x0);
++
++			OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
++			OUT_RING(0x0);
++
++			OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
++			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
++			OUT_RING(0x0);
+ 
+ 			ADVANCE_RING();
+ 		}
+@@ -1153,15 +1196,15 @@ static void radeon_cp_dispatch_clear( dr
+ 	 */
+ 	dev_priv->sarea_priv->last_clear++;
+ 
+-	BEGIN_RING( 4 );
++	BEGIN_RING(4);
+ 
+-	RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear );
++	RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear);
+ 	RADEON_WAIT_UNTIL_IDLE();
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static void radeon_cp_dispatch_swap( drm_device_t *dev )
++static void radeon_cp_dispatch_swap(drm_device_t * dev)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+@@ -1169,59 +1212,55 @@ static void radeon_cp_dispatch_swap( drm
+ 	drm_clip_rect_t *pbox = sarea_priv->boxes;
+ 	int i;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	/* Do some trivial performance monitoring...
+ 	 */
+ 	if (dev_priv->do_boxes)
+-		radeon_cp_performance_boxes( dev_priv );
+-
++		radeon_cp_performance_boxes(dev_priv);
+ 
+ 	/* Wait for the 3D stream to idle before dispatching the bitblt.
+ 	 * This will prevent data corruption between the two streams.
+ 	 */
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 
+ 	RADEON_WAIT_UNTIL_3D_IDLE();
+ 
+ 	ADVANCE_RING();
+ 
+-	for ( i = 0 ; i < nbox ; i++ ) {
++	for (i = 0; i < nbox; i++) {
+ 		int x = pbox[i].x1;
+ 		int y = pbox[i].y1;
+ 		int w = pbox[i].x2 - x;
+ 		int h = pbox[i].y2 - y;
+ 
+-		DRM_DEBUG( "dispatch swap %d,%d-%d,%d\n",
+-			   x, y, w, h );
++		DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h);
+ 
+-		BEGIN_RING( 7 );
++		BEGIN_RING(7);
++
++		OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
++		OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
++			 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
++			 RADEON_GMC_BRUSH_NONE |
++			 (dev_priv->color_fmt << 8) |
++			 RADEON_GMC_SRC_DATATYPE_COLOR |
++			 RADEON_ROP3_S |
++			 RADEON_DP_SRC_SOURCE_MEMORY |
++			 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
+ 
+-		OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) );
+-		OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
+-			  RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+-			  RADEON_GMC_BRUSH_NONE |
+-			  (dev_priv->color_fmt << 8) |
+-			  RADEON_GMC_SRC_DATATYPE_COLOR |
+-			  RADEON_ROP3_S |
+-			  RADEON_DP_SRC_SOURCE_MEMORY |
+-			  RADEON_GMC_CLR_CMP_CNTL_DIS |
+-			  RADEON_GMC_WR_MSK_DIS );
+-		
+ 		/* Make this work even if front & back are flipped:
+ 		 */
+ 		if (dev_priv->current_page == 0) {
+-			OUT_RING( dev_priv->back_pitch_offset );
+-			OUT_RING( dev_priv->front_pitch_offset );
+-		} 
+-		else {
+-			OUT_RING( dev_priv->front_pitch_offset );
+-			OUT_RING( dev_priv->back_pitch_offset );
++			OUT_RING(dev_priv->back_pitch_offset);
++			OUT_RING(dev_priv->front_pitch_offset);
++		} else {
++			OUT_RING(dev_priv->front_pitch_offset);
++			OUT_RING(dev_priv->back_pitch_offset);
+ 		}
+ 
+-		OUT_RING( (x << 16) | y );
+-		OUT_RING( (x << 16) | y );
+-		OUT_RING( (w << 16) | h );
++		OUT_RING((x << 16) | y);
++		OUT_RING((x << 16) | y);
++		OUT_RING((w << 16) | h);
+ 
+ 		ADVANCE_RING();
+ 	}
+@@ -1232,44 +1271,43 @@ static void radeon_cp_dispatch_swap( drm
+ 	 */
+ 	dev_priv->sarea_priv->last_frame++;
+ 
+-	BEGIN_RING( 4 );
++	BEGIN_RING(4);
+ 
+-	RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );
++	RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
+ 	RADEON_WAIT_UNTIL_2D_IDLE();
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static void radeon_cp_dispatch_flip( drm_device_t *dev )
++static void radeon_cp_dispatch_flip(drm_device_t * dev)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+-	drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle;
++	drm_sarea_t *sarea = (drm_sarea_t *) dev_priv->sarea->handle;
+ 	int offset = (dev_priv->current_page == 1)
+-		   ? dev_priv->front_offset : dev_priv->back_offset;
++	    ? dev_priv->front_offset : dev_priv->back_offset;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", 
+-		__FUNCTION__, 
+-		dev_priv->current_page,
+-		dev_priv->sarea_priv->pfCurrentPage);
++	DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
++		  __FUNCTION__,
++		  dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
+ 
+ 	/* Do some trivial performance monitoring...
+ 	 */
+ 	if (dev_priv->do_boxes) {
+ 		dev_priv->stats.boxes |= RADEON_BOX_FLIP;
+-		radeon_cp_performance_boxes( dev_priv );
++		radeon_cp_performance_boxes(dev_priv);
+ 	}
+ 
+ 	/* Update the frame offsets for both CRTCs
+ 	 */
+-	BEGIN_RING( 6 );
++	BEGIN_RING(6);
+ 
+ 	RADEON_WAIT_UNTIL_3D_IDLE();
+-	OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch
+-					      + sarea->frame.x 
+-					      * ( dev_priv->color_fmt - 2 ) ) & ~7 )
+-					  + offset );
+-	OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
+-					   + offset );
++	OUT_RING_REG(RADEON_CRTC_OFFSET,
++		     ((sarea->frame.y * dev_priv->front_pitch +
++		       sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7)
++		     + offset);
++	OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
++		     + offset);
+ 
+ 	ADVANCE_RING();
+ 
+@@ -1279,16 +1317,16 @@ static void radeon_cp_dispatch_flip( drm
+ 	 */
+ 	dev_priv->sarea_priv->last_frame++;
+ 	dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
+-					      1 - dev_priv->current_page;
++	    1 - dev_priv->current_page;
+ 
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 
+-	RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );
++	RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static int bad_prim_vertex_nr( int primitive, int nr )
++static int bad_prim_vertex_nr(int primitive, int nr)
+ {
+ 	switch (primitive & RADEON_PRIM_TYPE_MASK) {
+ 	case RADEON_PRIM_TYPE_NONE:
+@@ -1308,24 +1346,21 @@ static int bad_prim_vertex_nr( int primi
+ 		return nr < 3;
+ 	default:
+ 		return 1;
+-	}	
++	}
+ }
+ 
+-
+-
+ typedef struct {
+ 	unsigned int start;
+ 	unsigned int finish;
+ 	unsigned int prim;
+ 	unsigned int numverts;
+-	unsigned int offset;   
+-        unsigned int vc_format;
++	unsigned int offset;
++	unsigned int vc_format;
+ } drm_radeon_tcl_prim_t;
+ 
+-static void radeon_cp_dispatch_vertex( drm_device_t *dev,
+-				       drm_buf_t *buf,
+-				       drm_radeon_tcl_prim_t *prim )
+-
++static void radeon_cp_dispatch_vertex(drm_device_t * dev,
++				      drm_buf_t * buf,
++				      drm_radeon_tcl_prim_t * prim)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+@@ -1337,45 +1372,39 @@ static void radeon_cp_dispatch_vertex( d
+ 
+ 	DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
+ 		  prim->prim,
+-		  prim->vc_format,
+-		  prim->start,
+-		  prim->finish,
+-		  prim->numverts);
+-
+-	if (bad_prim_vertex_nr( prim->prim, prim->numverts )) {
+-		DRM_ERROR( "bad prim %x numverts %d\n", 
+-			   prim->prim, prim->numverts );
++		  prim->vc_format, prim->start, prim->finish, prim->numverts);
++
++	if (bad_prim_vertex_nr(prim->prim, prim->numverts)) {
++		DRM_ERROR("bad prim %x numverts %d\n",
++			  prim->prim, prim->numverts);
+ 		return;
+ 	}
+ 
+ 	do {
+ 		/* Emit the next cliprect */
+-		if ( i < nbox ) {
+-			radeon_emit_clip_rect( dev_priv, 
+-					       &sarea_priv->boxes[i] );
++		if (i < nbox) {
++			radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
+ 		}
+ 
+ 		/* Emit the vertex buffer rendering commands */
+-		BEGIN_RING( 5 );
++		BEGIN_RING(5);
+ 
+-		OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) );
+-		OUT_RING( offset );
+-		OUT_RING( numverts );
+-		OUT_RING( prim->vc_format );
+-		OUT_RING( prim->prim | RADEON_PRIM_WALK_LIST |
+-			  RADEON_COLOR_ORDER_RGBA |
+-			  RADEON_VTX_FMT_RADEON_MODE |
+-			  (numverts << RADEON_NUM_VERTICES_SHIFT) );
++		OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, 3));
++		OUT_RING(offset);
++		OUT_RING(numverts);
++		OUT_RING(prim->vc_format);
++		OUT_RING(prim->prim | RADEON_PRIM_WALK_LIST |
++			 RADEON_COLOR_ORDER_RGBA |
++			 RADEON_VTX_FMT_RADEON_MODE |
++			 (numverts << RADEON_NUM_VERTICES_SHIFT));
+ 
+ 		ADVANCE_RING();
+ 
+ 		i++;
+-	} while ( i < nbox );
++	} while (i < nbox);
+ }
+ 
+-
+-
+-static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf )
++static void radeon_cp_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
+@@ -1384,24 +1413,22 @@ static void radeon_cp_discard_buffer( dr
+ 	buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
+ 
+ 	/* Emit the vertex buffer age */
+-	BEGIN_RING( 2 );
+-	RADEON_DISPATCH_AGE( buf_priv->age );
++	BEGIN_RING(2);
++	RADEON_DISPATCH_AGE(buf_priv->age);
+ 	ADVANCE_RING();
+ 
+ 	buf->pending = 1;
+ 	buf->used = 0;
+ }
+ 
+-static void radeon_cp_dispatch_indirect( drm_device_t *dev,
+-					 drm_buf_t *buf,
+-					 int start, int end )
++static void radeon_cp_dispatch_indirect(drm_device_t * dev,
++					drm_buf_t * buf, int start, int end)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
+-		   buf->idx, start, end );
++	DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
+ 
+-	if ( start != end ) {
++	if (start != end) {
+ 		int offset = (dev_priv->gart_buffers_offset
+ 			      + buf->offset + start);
+ 		int dwords = (end - start + 3) / sizeof(u32);
+@@ -1410,28 +1437,27 @@ static void radeon_cp_dispatch_indirect(
+ 		 * dwords, so if we've been given an odd number we must
+ 		 * pad the data with a Type-2 CP packet.
+ 		 */
+-		if ( dwords & 1 ) {
++		if (dwords & 1) {
+ 			u32 *data = (u32 *)
+-				((char *)dev->agp_buffer_map->handle
+-				 + buf->offset + start);
++			    ((char *)dev->agp_buffer_map->handle
++			     + buf->offset + start);
+ 			data[dwords++] = RADEON_CP_PACKET2;
+ 		}
+ 
+ 		/* Fire off the indirect buffer */
+-		BEGIN_RING( 3 );
++		BEGIN_RING(3);
+ 
+-		OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) );
+-		OUT_RING( offset );
+-		OUT_RING( dwords );
++		OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
++		OUT_RING(offset);
++		OUT_RING(dwords);
+ 
+ 		ADVANCE_RING();
+ 	}
+ }
+ 
+-
+-static void radeon_cp_dispatch_indices( drm_device_t *dev,
+-					drm_buf_t *elt_buf,
+-					drm_radeon_tcl_prim_t *prim )
++static void radeon_cp_dispatch_indices(drm_device_t * dev,
++				       drm_buf_t * elt_buf,
++				       drm_radeon_tcl_prim_t * prim)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+@@ -1446,30 +1472,24 @@ static void radeon_cp_dispatch_indices( 
+ 	DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
+ 		  prim->prim,
+ 		  prim->vc_format,
+-		  prim->start,
+-		  prim->finish,
+-		  prim->offset,
+-		  prim->numverts);
+-
+-	if (bad_prim_vertex_nr( prim->prim, count )) {
+-		DRM_ERROR( "bad prim %x count %d\n", 
+-			   prim->prim, count );
++		  prim->start, prim->finish, prim->offset, prim->numverts);
++
++	if (bad_prim_vertex_nr(prim->prim, count)) {
++		DRM_ERROR("bad prim %x count %d\n", prim->prim, count);
+ 		return;
+ 	}
+ 
+-
+-	if ( start >= prim->finish ||
+-	     (prim->start & 0x7) ) {
+-		DRM_ERROR( "buffer prim %d\n", prim->prim );
++	if (start >= prim->finish || (prim->start & 0x7)) {
++		DRM_ERROR("buffer prim %d\n", prim->prim);
+ 		return;
+ 	}
+ 
+ 	dwords = (prim->finish - prim->start + 3) / sizeof(u32);
+ 
+-	data = (u32 *)((char *)dev->agp_buffer_map->handle +
+-		       elt_buf->offset + prim->start);
++	data = (u32 *) ((char *)dev->agp_buffer_map->handle +
++			elt_buf->offset + prim->start);
+ 
+-	data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
++	data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2);
+ 	data[1] = offset;
+ 	data[2] = prim->numverts;
+ 	data[3] = prim->vc_format;
+@@ -1477,28 +1497,26 @@ static void radeon_cp_dispatch_indices( 
+ 		   RADEON_PRIM_WALK_IND |
+ 		   RADEON_COLOR_ORDER_RGBA |
+ 		   RADEON_VTX_FMT_RADEON_MODE |
+-		   (count << RADEON_NUM_VERTICES_SHIFT) );
++		   (count << RADEON_NUM_VERTICES_SHIFT));
+ 
+ 	do {
+-		if ( i < nbox ) 
+-			radeon_emit_clip_rect( dev_priv, 
+-					       &sarea_priv->boxes[i] );
+-
+-		radeon_cp_dispatch_indirect( dev, elt_buf,
+-					     prim->start,
+-					     prim->finish );
++		if (i < nbox)
++			radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
++
++		radeon_cp_dispatch_indirect(dev, elt_buf,
++					    prim->start, prim->finish);
+ 
+ 		i++;
+-	} while ( i < nbox );
++	} while (i < nbox);
+ 
+ }
+ 
+ #define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
+ 
+-static int radeon_cp_dispatch_texture( DRMFILE filp,
+-				       drm_device_t *dev,
+-				       drm_radeon_texture_t *tex,
+-				       drm_radeon_tex_image_t *image )
++static int radeon_cp_dispatch_texture(DRMFILE filp,
++				      drm_device_t * dev,
++				      drm_radeon_texture_t * tex,
++				      drm_radeon_tex_image_t * image)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_file_t *filp_priv;
+@@ -1513,11 +1531,11 @@ static int radeon_cp_dispatch_texture( D
+ 	u32 offset;
+ 	RING_LOCALS;
+ 
+-	DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
++	DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
+ 
+-	if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &tex->offset ) ) {
+-		DRM_ERROR( "Invalid destination offset\n" );
+-		return DRM_ERR( EINVAL );
++	if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &tex->offset)) {
++		DRM_ERROR("Invalid destination offset\n");
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD;
+@@ -1526,7 +1544,7 @@ static int radeon_cp_dispatch_texture( D
+ 	 * up with the texture data from the host data blit, otherwise
+ 	 * part of the texture image may be corrupted.
+ 	 */
+-	BEGIN_RING( 4 );
++	BEGIN_RING(4);
+ 	RADEON_FLUSH_CACHE();
+ 	RADEON_WAIT_UNTIL_IDLE();
+ 	ADVANCE_RING();
+@@ -1535,7 +1553,7 @@ static int radeon_cp_dispatch_texture( D
+ 	 * even if the only legal values are powers of two.  Thus, we'll
+ 	 * use a shift instead.
+ 	 */
+-	switch ( tex->format ) {
++	switch (tex->format) {
+ 	case RADEON_TXFORMAT_ARGB8888:
+ 	case RADEON_TXFORMAT_RGBA8888:
+ 		format = RADEON_COLOR_FORMAT_ARGB8888;
+@@ -1559,7 +1577,7 @@ static int radeon_cp_dispatch_texture( D
+ 		blit_width = image->width * 1;
+ 		break;
+ 	default:
+-		DRM_ERROR( "invalid texture format %d\n", tex->format );
++		DRM_ERROR("invalid texture format %d\n", tex->format);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 	spitch = blit_width >> 6;
+@@ -1574,49 +1592,49 @@ static int radeon_cp_dispatch_texture( D
+ 			/* we got tiled coordinates, untile them */
+ 			image->x *= 2;
+ 		}
+-	}
+-	else microtile = 0;
++	} else
++		microtile = 0;
+ 
+-	DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width );
++	DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
+ 
+ 	do {
+-		DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
+-			   tex->offset >> 10, tex->pitch, tex->format,
+-			   image->x, image->y, image->width, image->height );
++		DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
++			  tex->offset >> 10, tex->pitch, tex->format,
++			  image->x, image->y, image->width, image->height);
+ 
+ 		/* Make a copy of some parameters in case we have to
+ 		 * update them for a multi-pass texture blit.
+ 		 */
+ 		height = image->height;
+ 		data = (const u8 __user *)image->data;
+-		
++
+ 		size = height * blit_width;
+ 
+-		if ( size > RADEON_MAX_TEXTURE_SIZE ) {
++		if (size > RADEON_MAX_TEXTURE_SIZE) {
+ 			height = RADEON_MAX_TEXTURE_SIZE / blit_width;
+ 			size = height * blit_width;
+-		} else if ( size < 4 && size > 0 ) {
++		} else if (size < 4 && size > 0) {
+ 			size = 4;
+-		} else if ( size == 0 ) {
++		} else if (size == 0) {
+ 			return 0;
+ 		}
+ 
+-		buf = radeon_freelist_get( dev );
+-		if ( 0 && !buf ) {
+-			radeon_do_cp_idle( dev_priv );
+-			buf = radeon_freelist_get( dev );
++		buf = radeon_freelist_get(dev);
++		if (0 && !buf) {
++			radeon_do_cp_idle(dev_priv);
++			buf = radeon_freelist_get(dev);
+ 		}
+-		if ( !buf ) {
++		if (!buf) {
+ 			DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
+-			if (DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ))
++			if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
+ 				return DRM_ERR(EFAULT);
+ 			return DRM_ERR(EAGAIN);
+ 		}
+ 
+-
+ 		/* Dispatch the indirect buffer.
+ 		 */
+-		buffer = (u32*)((char*)dev->agp_buffer_map->handle + buf->offset);
++		buffer =
++		    (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
+ 		dwords = size / 4;
+ 
+ 		if (microtile) {
+@@ -1631,20 +1649,26 @@ static int radeon_cp_dispatch_texture( D
+ 			if (tex->height == 1) {
+ 				if (tex_width >= 64 || tex_width <= 16) {
+ 					if (DRM_COPY_FROM_USER(buffer, data,
+-							       tex_width * sizeof(u32))) {
+-						DRM_ERROR("EFAULT on pad, %d bytes\n",
+-							  tex_width);
++							       tex_width *
++							       sizeof(u32))) {
++						DRM_ERROR
++						    ("EFAULT on pad, %d bytes\n",
++						     tex_width);
+ 						return DRM_ERR(EFAULT);
+ 					}
+ 				} else if (tex_width == 32) {
+-					if (DRM_COPY_FROM_USER(buffer, data, 16)) {
+-						DRM_ERROR("EFAULT on pad, %d bytes\n",
+-							  tex_width);
++					if (DRM_COPY_FROM_USER
++					    (buffer, data, 16)) {
++						DRM_ERROR
++						    ("EFAULT on pad, %d bytes\n",
++						     tex_width);
+ 						return DRM_ERR(EFAULT);
+ 					}
+-					if (DRM_COPY_FROM_USER(buffer + 8, data + 16, 16)) {
+-						DRM_ERROR("EFAULT on pad, %d bytes\n",
+-							  tex_width);
++					if (DRM_COPY_FROM_USER
++					    (buffer + 8, data + 16, 16)) {
++						DRM_ERROR
++						    ("EFAULT on pad, %d bytes\n",
++						     tex_width);
+ 						return DRM_ERR(EFAULT);
+ 					}
+ 				}
+@@ -1657,9 +1681,11 @@ static int radeon_cp_dispatch_texture( D
+ 				}
+ 			} else if (tex_width < 16) {
+ 				for (i = 0; i < tex->height; i++) {
+-					if (DRM_COPY_FROM_USER(buffer, data, tex_width)) {
+-						DRM_ERROR("EFAULT on pad, %d bytes\n",
+-							  tex_width);
++					if (DRM_COPY_FROM_USER
++					    (buffer, data, tex_width)) {
++						DRM_ERROR
++						    ("EFAULT on pad, %d bytes\n",
++						     tex_width);
+ 						return DRM_ERR(EFAULT);
+ 					}
+ 					buffer += 4;
+@@ -1669,35 +1695,42 @@ static int radeon_cp_dispatch_texture( D
+ 				/* TODO: make sure this works when not fitting in one buffer
+ 				   (i.e. 32bytes x 2048...) */
+ 				for (i = 0; i < tex->height; i += 2) {
+-					if (DRM_COPY_FROM_USER(buffer, data, 16)) {
+-						DRM_ERROR("EFAULT on pad, %d bytes\n",
+-							  tex_width);
++					if (DRM_COPY_FROM_USER
++					    (buffer, data, 16)) {
++						DRM_ERROR
++						    ("EFAULT on pad, %d bytes\n",
++						     tex_width);
+ 						return DRM_ERR(EFAULT);
+ 					}
+ 					data += 16;
+-					if (DRM_COPY_FROM_USER(buffer + 8, data, 16)) {
+-						DRM_ERROR("EFAULT on pad, %d bytes\n",
+-							  tex_width);
++					if (DRM_COPY_FROM_USER
++					    (buffer + 8, data, 16)) {
++						DRM_ERROR
++						    ("EFAULT on pad, %d bytes\n",
++						     tex_width);
+ 						return DRM_ERR(EFAULT);
+ 					}
+ 					data += 16;
+-					if (DRM_COPY_FROM_USER(buffer + 4, data, 16)) {
+-						DRM_ERROR("EFAULT on pad, %d bytes\n",
+-							  tex_width);
++					if (DRM_COPY_FROM_USER
++					    (buffer + 4, data, 16)) {
++						DRM_ERROR
++						    ("EFAULT on pad, %d bytes\n",
++						     tex_width);
+ 						return DRM_ERR(EFAULT);
+ 					}
+ 					data += 16;
+-					if (DRM_COPY_FROM_USER(buffer + 12, data, 16)) {
+-						DRM_ERROR("EFAULT on pad, %d bytes\n",
+-							  tex_width);
++					if (DRM_COPY_FROM_USER
++					    (buffer + 12, data, 16)) {
++						DRM_ERROR
++						    ("EFAULT on pad, %d bytes\n",
++						     tex_width);
+ 						return DRM_ERR(EFAULT);
+ 					}
+ 					data += 16;
+ 					buffer += 16;
+ 				}
+ 			}
+-		}
+-		else {
++		} else {
+ 			if (tex_width >= 32) {
+ 				/* Texture image width is larger than the minimum, so we
+ 				 * can upload it directly.
+@@ -1713,9 +1746,12 @@ static int radeon_cp_dispatch_texture( D
+ 				 * need to pad out each image scanline to the minimum
+ 				 * width.
+ 				 */
+-				for (i = 0 ; i < tex->height ; i++) {
+-					if (DRM_COPY_FROM_USER(buffer, data, tex_width )) {
+-						DRM_ERROR("EFAULT on pad, %d bytes\n", tex_width);
++				for (i = 0; i < tex->height; i++) {
++					if (DRM_COPY_FROM_USER
++					    (buffer, data, tex_width)) {
++						DRM_ERROR
++						    ("EFAULT on pad, %d bytes\n",
++						     tex_width);
+ 						return DRM_ERR(EFAULT);
+ 					}
+ 					buffer += 8;
+@@ -1736,8 +1772,7 @@ static int radeon_cp_dispatch_texture( D
+ 			 RADEON_GMC_SRC_DATATYPE_COLOR |
+ 			 RADEON_ROP3_S |
+ 			 RADEON_DP_SRC_SOURCE_MEMORY |
+-			 RADEON_GMC_CLR_CMP_CNTL_DIS |
+-			 RADEON_GMC_WR_MSK_DIS );
++			 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
+ 		OUT_RING((spitch << 22) | (offset >> 10));
+ 		OUT_RING((texpitch << 22) | (tex->offset >> 10));
+ 		OUT_RING(0);
+@@ -1758,62 +1793,62 @@ static int radeon_cp_dispatch_texture( D
+ 	 * the texture data is written out to memory before rendering
+ 	 * continues.
+ 	 */
+-	BEGIN_RING( 4 );
++	BEGIN_RING(4);
+ 	RADEON_FLUSH_CACHE();
+ 	RADEON_WAIT_UNTIL_2D_IDLE();
+ 	ADVANCE_RING();
+ 	return 0;
+ }
+ 
+-
+-static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
++static void radeon_cp_dispatch_stipple(drm_device_t * dev, u32 * stipple)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	int i;
+ 	RING_LOCALS;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	BEGIN_RING( 35 );
++	BEGIN_RING(35);
+ 
+-	OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) );
+-	OUT_RING( 0x00000000 );
++	OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0));
++	OUT_RING(0x00000000);
+ 
+-	OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA, 31 ) );
+-	for ( i = 0 ; i < 32 ; i++ ) {
+-		OUT_RING( stipple[i] );
++	OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA, 31));
++	for (i = 0; i < 32; i++) {
++		OUT_RING(stipple[i]);
+ 	}
+ 
+ 	ADVANCE_RING();
+ }
+ 
+-static void radeon_apply_surface_regs(int surf_index, drm_radeon_private_t *dev_priv)
++static void radeon_apply_surface_regs(int surf_index,
++				      drm_radeon_private_t * dev_priv)
+ {
+ 	if (!dev_priv->mmio)
+ 		return;
+ 
+ 	radeon_do_cp_idle(dev_priv);
+ 
+-	RADEON_WRITE(RADEON_SURFACE0_INFO + 16*surf_index,
+-		dev_priv->surfaces[surf_index].flags);
+-	RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*surf_index,
+-		dev_priv->surfaces[surf_index].lower);
+-	RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*surf_index,
+-		dev_priv->surfaces[surf_index].upper);
++	RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * surf_index,
++		     dev_priv->surfaces[surf_index].flags);
++	RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * surf_index,
++		     dev_priv->surfaces[surf_index].lower);
++	RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * surf_index,
++		     dev_priv->surfaces[surf_index].upper);
+ }
+ 
+-
+ /* Allocates a virtual surface
+- * doesn't always allocate a real surface, will stretch an existing 
++ * doesn't always allocate a real surface, will stretch an existing
+  * surface when possible.
+  *
+  * Note that refcount can be at most 2, since during a free refcount=3
+  * might mean we have to allocate a new surface which might not always
+  * be available.
+- * For example : we allocate three contigous surfaces ABC. If B is 
++ * For example : we allocate three contigous surfaces ABC. If B is
+  * freed, we suddenly need two surfaces to store A and C, which might
+  * not always be available.
+  */
+-static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t *dev_priv, DRMFILE filp)
++static int alloc_surface(drm_radeon_surface_alloc_t * new,
++			 drm_radeon_private_t * dev_priv, DRMFILE filp)
+ {
+ 	struct radeon_virt_surface *s;
+ 	int i;
+@@ -1825,34 +1860,37 @@ static int alloc_surface(drm_radeon_surf
+ 
+ 	/* sanity check */
+ 	if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) ||
+-		((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) != RADEON_SURF_ADDRESS_FIXED_MASK) ||
+-		((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
++	    ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) !=
++	     RADEON_SURF_ADDRESS_FIXED_MASK)
++	    || ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
+ 		return -1;
+ 
+ 	/* make sure there is no overlap with existing surfaces */
+ 	for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+ 		if ((dev_priv->surfaces[i].refcount != 0) &&
+-		(( (new_lower >= dev_priv->surfaces[i].lower) &&
+-			(new_lower < dev_priv->surfaces[i].upper) ) ||
+-		 ( (new_lower < dev_priv->surfaces[i].lower) &&
+-			(new_upper > dev_priv->surfaces[i].lower) )) ){
+-		return -1;}
++		    (((new_lower >= dev_priv->surfaces[i].lower) &&
++		      (new_lower < dev_priv->surfaces[i].upper)) ||
++		     ((new_lower < dev_priv->surfaces[i].lower) &&
++		      (new_upper > dev_priv->surfaces[i].lower)))) {
++			return -1;
++		}
+ 	}
+ 
+ 	/* find a virtual surface */
+-	for (i = 0; i < 2*RADEON_MAX_SURFACES; i++)
++	for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
+ 		if (dev_priv->virt_surfaces[i].filp == 0)
+ 			break;
+-	if (i == 2*RADEON_MAX_SURFACES) {
+-		return -1;}
++	if (i == 2 * RADEON_MAX_SURFACES) {
++		return -1;
++	}
+ 	virt_surface_index = i;
+ 
+ 	/* try to reuse an existing surface */
+ 	for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+ 		/* extend before */
+ 		if ((dev_priv->surfaces[i].refcount == 1) &&
+-		  (new->flags == dev_priv->surfaces[i].flags) &&
+-		  (new_upper + 1 == dev_priv->surfaces[i].lower)) {
++		    (new->flags == dev_priv->surfaces[i].flags) &&
++		    (new_upper + 1 == dev_priv->surfaces[i].lower)) {
+ 			s = &(dev_priv->virt_surfaces[virt_surface_index]);
+ 			s->surface_index = i;
+ 			s->lower = new_lower;
+@@ -1867,8 +1905,8 @@ static int alloc_surface(drm_radeon_surf
+ 
+ 		/* extend after */
+ 		if ((dev_priv->surfaces[i].refcount == 1) &&
+-		  (new->flags == dev_priv->surfaces[i].flags) &&
+-		  (new_lower == dev_priv->surfaces[i].upper + 1)) {
++		    (new->flags == dev_priv->surfaces[i].flags) &&
++		    (new_lower == dev_priv->surfaces[i].upper + 1)) {
+ 			s = &(dev_priv->virt_surfaces[virt_surface_index]);
+ 			s->surface_index = i;
+ 			s->lower = new_lower;
+@@ -1904,26 +1942,34 @@ static int alloc_surface(drm_radeon_surf
+ 	return -1;
+ }
+ 
+-static int free_surface(DRMFILE filp, drm_radeon_private_t *dev_priv, int lower)
++static int free_surface(DRMFILE filp, drm_radeon_private_t * dev_priv,
++			int lower)
+ {
+ 	struct radeon_virt_surface *s;
+ 	int i;
+ 	/* find the virtual surface */
+-	for(i = 0; i < 2*RADEON_MAX_SURFACES; i++) {
++	for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
+ 		s = &(dev_priv->virt_surfaces[i]);
+ 		if (s->filp) {
+ 			if ((lower == s->lower) && (filp == s->filp)) {
+-				if (dev_priv->surfaces[s->surface_index].lower == s->lower)
+-					dev_priv->surfaces[s->surface_index].lower = s->upper;
+-
+-				if (dev_priv->surfaces[s->surface_index].upper == s->upper)
+-					dev_priv->surfaces[s->surface_index].upper = s->lower;
++				if (dev_priv->surfaces[s->surface_index].
++				    lower == s->lower)
++					dev_priv->surfaces[s->surface_index].
++					    lower = s->upper;
++
++				if (dev_priv->surfaces[s->surface_index].
++				    upper == s->upper)
++					dev_priv->surfaces[s->surface_index].
++					    upper = s->lower;
+ 
+ 				dev_priv->surfaces[s->surface_index].refcount--;
+-				if (dev_priv->surfaces[s->surface_index].refcount == 0)
+-					dev_priv->surfaces[s->surface_index].flags = 0;
++				if (dev_priv->surfaces[s->surface_index].
++				    refcount == 0)
++					dev_priv->surfaces[s->surface_index].
++					    flags = 0;
+ 				s->filp = NULL;
+-				radeon_apply_surface_regs(s->surface_index, dev_priv);
++				radeon_apply_surface_regs(s->surface_index,
++							  dev_priv);
+ 				return 0;
+ 			}
+ 		}
+@@ -1931,13 +1977,14 @@ static int free_surface(DRMFILE filp, dr
+ 	return 1;
+ }
+ 
+-static void radeon_surfaces_release(DRMFILE filp, drm_radeon_private_t *dev_priv)
++static void radeon_surfaces_release(DRMFILE filp,
++				    drm_radeon_private_t * dev_priv)
+ {
+ 	int i;
+-	for( i = 0; i < 2*RADEON_MAX_SURFACES; i++)
+-	{
++	for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
+ 		if (dev_priv->virt_surfaces[i].filp == filp)
+-			free_surface(filp, dev_priv, dev_priv->virt_surfaces[i].lower);
++			free_surface(filp, dev_priv,
++				     dev_priv->virt_surfaces[i].lower);
+ 	}
+ }
+ 
+@@ -1951,12 +1998,13 @@ static int radeon_surface_alloc(DRM_IOCT
+ 	drm_radeon_surface_alloc_t alloc;
+ 
+ 	if (!dev_priv) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_surface_alloc_t __user *)data,
+-				  sizeof(alloc));
++	DRM_COPY_FROM_USER_IOCTL(alloc,
++				 (drm_radeon_surface_alloc_t __user *) data,
++				 sizeof(alloc));
+ 
+ 	if (alloc_surface(&alloc, dev_priv, filp) == -1)
+ 		return DRM_ERR(EINVAL);
+@@ -1971,12 +2019,12 @@ static int radeon_surface_free(DRM_IOCTL
+ 	drm_radeon_surface_free_t memfree;
+ 
+ 	if (!dev_priv) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *)data,
+-				  sizeof(memfree) );
++	DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data,
++				 sizeof(memfree));
+ 
+ 	if (free_surface(filp, dev_priv, memfree.address))
+ 		return DRM_ERR(EINVAL);
+@@ -1984,51 +2032,52 @@ static int radeon_surface_free(DRM_IOCTL
+ 		return 0;
+ }
+ 
+-static int radeon_cp_clear( DRM_IOCTL_ARGS )
++static int radeon_cp_clear(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ 	drm_radeon_clear_t clear;
+ 	drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t __user *)data,
+-			     sizeof(clear) );
++	DRM_COPY_FROM_USER_IOCTL(clear, (drm_radeon_clear_t __user *) data,
++				 sizeof(clear));
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+-	if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
++	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
+ 		sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
+ 
+-	if ( DRM_COPY_FROM_USER( &depth_boxes, clear.depth_boxes,
+-			     sarea_priv->nbox * sizeof(depth_boxes[0]) ) )
++	if (DRM_COPY_FROM_USER(&depth_boxes, clear.depth_boxes,
++			       sarea_priv->nbox * sizeof(depth_boxes[0])))
+ 		return DRM_ERR(EFAULT);
+ 
+-	radeon_cp_dispatch_clear( dev, &clear, depth_boxes );
++	radeon_cp_dispatch_clear(dev, &clear, depth_boxes);
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-
+ /* Not sure why this isn't set all the time:
+- */ 
+-static int radeon_do_init_pageflip( drm_device_t *dev )
++ */
++static int radeon_do_init_pageflip(drm_device_t * dev)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	RING_LOCALS;
+ 
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	BEGIN_RING( 6 );
++	BEGIN_RING(6);
+ 	RADEON_WAIT_UNTIL_3D_IDLE();
+-	OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) );
+-	OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL );
+-	OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) );
+-	OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL );
++	OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL, 0));
++	OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL) |
++		 RADEON_CRTC_OFFSET_FLIP_CNTL);
++	OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL, 0));
++	OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL) |
++		 RADEON_CRTC_OFFSET_FLIP_CNTL);
+ 	ADVANCE_RING();
+ 
+ 	dev_priv->page_flipping = 1;
+@@ -2041,62 +2090,62 @@ static int radeon_do_init_pageflip( drm_
+ /* Called whenever a client dies, from drm_release.
+  * NOTE:  Lock isn't necessarily held when this is called!
+  */
+-static int radeon_do_cleanup_pageflip( drm_device_t *dev )
++static int radeon_do_cleanup_pageflip(drm_device_t * dev)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+ 	if (dev_priv->current_page != 0)
+-		radeon_cp_dispatch_flip( dev );
++		radeon_cp_dispatch_flip(dev);
+ 
+ 	dev_priv->page_flipping = 0;
+ 	return 0;
+ }
+ 
+ /* Swapping and flipping are different operations, need different ioctls.
+- * They can & should be intermixed to support multiple 3d windows.  
++ * They can & should be intermixed to support multiple 3d windows.
+  */
+-static int radeon_cp_flip( DRM_IOCTL_ARGS )
++static int radeon_cp_flip(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+-	if (!dev_priv->page_flipping) 
+-		radeon_do_init_pageflip( dev );
+-		
+-	radeon_cp_dispatch_flip( dev );
++	if (!dev_priv->page_flipping)
++		radeon_do_init_pageflip(dev);
++
++	radeon_cp_dispatch_flip(dev);
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int radeon_cp_swap( DRM_IOCTL_ARGS )
++static int radeon_cp_swap(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+-	DRM_DEBUG( "\n" );
++	DRM_DEBUG("\n");
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+-	if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
++	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
+ 		sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
+ 
+-	radeon_cp_dispatch_swap( dev );
++	radeon_cp_dispatch_swap(dev);
+ 	dev_priv->sarea_priv->ctx_owner = 0;
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int radeon_cp_vertex( DRM_IOCTL_ARGS )
++static int radeon_cp_vertex(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+@@ -2107,55 +2156,53 @@ static int radeon_cp_vertex( DRM_IOCTL_A
+ 	drm_radeon_vertex_t vertex;
+ 	drm_radeon_tcl_prim_t prim;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
++	DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex_t __user *)data,
+-			     sizeof(vertex) );
++	DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data,
++				 sizeof(vertex));
+ 
+-	DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
+-		   DRM_CURRENTPID,
+-		   vertex.idx, vertex.count, vertex.discard );
++	DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
++		  DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard);
+ 
+-	if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
+-		DRM_ERROR( "buffer index %d (of %d max)\n",
+-			   vertex.idx, dma->buf_count - 1 );
++	if (vertex.idx < 0 || vertex.idx >= dma->buf_count) {
++		DRM_ERROR("buffer index %d (of %d max)\n",
++			  vertex.idx, dma->buf_count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( vertex.prim < 0 ||
+-	     vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
+-		DRM_ERROR( "buffer prim %d\n", vertex.prim );
++	if (vertex.prim < 0 || vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
++		DRM_ERROR("buffer prim %d\n", vertex.prim);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	buf = dma->buflist[vertex.idx];
+ 
+-	if ( buf->filp != filp ) {
+-		DRM_ERROR( "process %d using buffer owned by %p\n",
+-			   DRM_CURRENTPID, buf->filp );
++	if (buf->filp != filp) {
++		DRM_ERROR("process %d using buffer owned by %p\n",
++			  DRM_CURRENTPID, buf->filp);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( buf->pending ) {
+-		DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
++	if (buf->pending) {
++		DRM_ERROR("sending pending buffer %d\n", vertex.idx);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	/* Build up a prim_t record:
+ 	 */
+ 	if (vertex.count) {
+-		buf->used = vertex.count; /* not used? */
++		buf->used = vertex.count;	/* not used? */
+ 
+-		if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
+-			if ( radeon_emit_state( dev_priv, filp_priv,
+-						&sarea_priv->context_state,
+-						sarea_priv->tex_state,
+-						sarea_priv->dirty ) ) {
+-				DRM_ERROR( "radeon_emit_state failed\n" );
+-				return DRM_ERR( EINVAL );
++		if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
++			if (radeon_emit_state(dev_priv, filp_priv,
++					      &sarea_priv->context_state,
++					      sarea_priv->tex_state,
++					      sarea_priv->dirty)) {
++				DRM_ERROR("radeon_emit_state failed\n");
++				return DRM_ERR(EINVAL);
+ 			}
+ 
+ 			sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
+@@ -2165,23 +2212,23 @@ static int radeon_cp_vertex( DRM_IOCTL_A
+ 		}
+ 
+ 		prim.start = 0;
+-		prim.finish = vertex.count; /* unused */
++		prim.finish = vertex.count;	/* unused */
+ 		prim.prim = vertex.prim;
+ 		prim.numverts = vertex.count;
+ 		prim.vc_format = dev_priv->sarea_priv->vc_format;
+-		
+-		radeon_cp_dispatch_vertex( dev, buf, &prim );
++
++		radeon_cp_dispatch_vertex(dev, buf, &prim);
+ 	}
+ 
+ 	if (vertex.discard) {
+-		radeon_cp_discard_buffer( dev, buf );
++		radeon_cp_discard_buffer(dev, buf);
+ 	}
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int radeon_cp_indices( DRM_IOCTL_ARGS )
++static int radeon_cp_indices(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+@@ -2193,69 +2240,67 @@ static int radeon_cp_indices( DRM_IOCTL_
+ 	drm_radeon_tcl_prim_t prim;
+ 	int count;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
++	DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( elts, (drm_radeon_indices_t __user *)data,
+-			     sizeof(elts) );
++	DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data,
++				 sizeof(elts));
+ 
+-	DRM_DEBUG( "pid=%d index=%d start=%d end=%d discard=%d\n",
+-		   DRM_CURRENTPID,
+-		   elts.idx, elts.start, elts.end, elts.discard );
++	DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
++		  DRM_CURRENTPID, elts.idx, elts.start, elts.end, elts.discard);
+ 
+-	if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
+-		DRM_ERROR( "buffer index %d (of %d max)\n",
+-			   elts.idx, dma->buf_count - 1 );
++	if (elts.idx < 0 || elts.idx >= dma->buf_count) {
++		DRM_ERROR("buffer index %d (of %d max)\n",
++			  elts.idx, dma->buf_count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( elts.prim < 0 ||
+-	     elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
+-		DRM_ERROR( "buffer prim %d\n", elts.prim );
++	if (elts.prim < 0 || elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
++		DRM_ERROR("buffer prim %d\n", elts.prim);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	buf = dma->buflist[elts.idx];
+ 
+-	if ( buf->filp != filp ) {
+-		DRM_ERROR( "process %d using buffer owned by %p\n",
+-			   DRM_CURRENTPID, buf->filp );
++	if (buf->filp != filp) {
++		DRM_ERROR("process %d using buffer owned by %p\n",
++			  DRM_CURRENTPID, buf->filp);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( buf->pending ) {
+-		DRM_ERROR( "sending pending buffer %d\n", elts.idx );
++	if (buf->pending) {
++		DRM_ERROR("sending pending buffer %d\n", elts.idx);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	count = (elts.end - elts.start) / sizeof(u16);
+ 	elts.start -= RADEON_INDEX_PRIM_OFFSET;
+ 
+-	if ( elts.start & 0x7 ) {
+-		DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
++	if (elts.start & 0x7) {
++		DRM_ERROR("misaligned buffer 0x%x\n", elts.start);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( elts.start < buf->used ) {
+-		DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
++	if (elts.start < buf->used) {
++		DRM_ERROR("no header 0x%x - 0x%x\n", elts.start, buf->used);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	buf->used = elts.end;
+ 
+-	if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
+-		if ( radeon_emit_state( dev_priv, filp_priv,
+-					&sarea_priv->context_state,
+-					sarea_priv->tex_state,
+-					sarea_priv->dirty ) ) {
+-			DRM_ERROR( "radeon_emit_state failed\n" );
+-			return DRM_ERR( EINVAL );
++	if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
++		if (radeon_emit_state(dev_priv, filp_priv,
++				      &sarea_priv->context_state,
++				      sarea_priv->tex_state,
++				      sarea_priv->dirty)) {
++			DRM_ERROR("radeon_emit_state failed\n");
++			return DRM_ERR(EINVAL);
+ 		}
+ 
+ 		sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
+@@ -2264,26 +2309,25 @@ static int radeon_cp_indices( DRM_IOCTL_
+ 				       RADEON_REQUIRE_QUIESCENCE);
+ 	}
+ 
+-
+ 	/* Build up a prim_t record:
+ 	 */
+ 	prim.start = elts.start;
+-	prim.finish = elts.end; 
++	prim.finish = elts.end;
+ 	prim.prim = elts.prim;
+ 	prim.offset = 0;	/* offset from start of dma buffers */
+-	prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
++	prim.numverts = RADEON_MAX_VB_VERTS;	/* duh */
+ 	prim.vc_format = dev_priv->sarea_priv->vc_format;
+-	
+-	radeon_cp_dispatch_indices( dev, buf, &prim );
++
++	radeon_cp_dispatch_indices(dev, buf, &prim);
+ 	if (elts.discard) {
+-		radeon_cp_discard_buffer( dev, buf );
++		radeon_cp_discard_buffer(dev, buf);
+ 	}
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int radeon_cp_texture( DRM_IOCTL_ARGS )
++static int radeon_cp_texture(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+@@ -2291,53 +2335,54 @@ static int radeon_cp_texture( DRM_IOCTL_
+ 	drm_radeon_tex_image_t image;
+ 	int ret;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t __user *)data, sizeof(tex) );
++	DRM_COPY_FROM_USER_IOCTL(tex, (drm_radeon_texture_t __user *) data,
++				 sizeof(tex));
+ 
+-	if ( tex.image == NULL ) {
+-		DRM_ERROR( "null texture image!\n" );
++	if (tex.image == NULL) {
++		DRM_ERROR("null texture image!\n");
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( DRM_COPY_FROM_USER( &image,
+-			     (drm_radeon_tex_image_t __user *)tex.image,
+-			     sizeof(image) ) )
++	if (DRM_COPY_FROM_USER(&image,
++			       (drm_radeon_tex_image_t __user *) tex.image,
++			       sizeof(image)))
+ 		return DRM_ERR(EFAULT);
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+-	ret = radeon_cp_dispatch_texture( filp, dev, &tex, &image );
++	ret = radeon_cp_dispatch_texture(filp, dev, &tex, &image);
+ 
+ 	COMMIT_RING();
+ 	return ret;
+ }
+ 
+-static int radeon_cp_stipple( DRM_IOCTL_ARGS )
++static int radeon_cp_stipple(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_stipple_t stipple;
+ 	u32 mask[32];
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t __user *)data,
+-			     sizeof(stipple) );
++	DRM_COPY_FROM_USER_IOCTL(stipple, (drm_radeon_stipple_t __user *) data,
++				 sizeof(stipple));
+ 
+-	if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 32 * sizeof(u32) ) )
++	if (DRM_COPY_FROM_USER(&mask, stipple.mask, 32 * sizeof(u32)))
+ 		return DRM_ERR(EFAULT);
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+-	radeon_cp_dispatch_stipple( dev, mask );
++	radeon_cp_dispatch_stipple(dev, mask);
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int radeon_cp_indirect( DRM_IOCTL_ARGS )
++static int radeon_cp_indirect(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+@@ -2346,53 +2391,53 @@ static int radeon_cp_indirect( DRM_IOCTL
+ 	drm_radeon_indirect_t indirect;
+ 	RING_LOCALS;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( indirect, (drm_radeon_indirect_t __user *)data,
+-			     sizeof(indirect) );
++	DRM_COPY_FROM_USER_IOCTL(indirect,
++				 (drm_radeon_indirect_t __user *) data,
++				 sizeof(indirect));
+ 
+-	DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
+-		   indirect.idx, indirect.start,
+-		   indirect.end, indirect.discard );
++	DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
++		  indirect.idx, indirect.start, indirect.end, indirect.discard);
+ 
+-	if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
+-		DRM_ERROR( "buffer index %d (of %d max)\n",
+-			   indirect.idx, dma->buf_count - 1 );
++	if (indirect.idx < 0 || indirect.idx >= dma->buf_count) {
++		DRM_ERROR("buffer index %d (of %d max)\n",
++			  indirect.idx, dma->buf_count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	buf = dma->buflist[indirect.idx];
+ 
+-	if ( buf->filp != filp ) {
+-		DRM_ERROR( "process %d using buffer owned by %p\n",
+-			   DRM_CURRENTPID, buf->filp );
++	if (buf->filp != filp) {
++		DRM_ERROR("process %d using buffer owned by %p\n",
++			  DRM_CURRENTPID, buf->filp);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if ( buf->pending ) {
+-		DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
++	if (buf->pending) {
++		DRM_ERROR("sending pending buffer %d\n", indirect.idx);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( indirect.start < buf->used ) {
+-		DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
+-			   indirect.start, buf->used );
++	if (indirect.start < buf->used) {
++		DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
++			  indirect.start, buf->used);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	buf->used = indirect.end;
+ 
+ 	/* Wait for the 3D stream to idle before the indirect buffer
+ 	 * containing 2D acceleration commands is processed.
+ 	 */
+-	BEGIN_RING( 2 );
++	BEGIN_RING(2);
+ 
+ 	RADEON_WAIT_UNTIL_3D_IDLE();
+ 
+@@ -2402,17 +2447,16 @@ static int radeon_cp_indirect( DRM_IOCTL
+ 	 * X server.  This is insecure and is thus only available to
+ 	 * privileged clients.
+ 	 */
+-	radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end );
++	radeon_cp_dispatch_indirect(dev, buf, indirect.start, indirect.end);
+ 	if (indirect.discard) {
+-		radeon_cp_discard_buffer( dev, buf );
++		radeon_cp_discard_buffer(dev, buf);
+ 	}
+ 
+-
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-static int radeon_cp_vertex2( DRM_IOCTL_ARGS )
++static int radeon_cp_vertex2(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+@@ -2424,65 +2468,64 @@ static int radeon_cp_vertex2( DRM_IOCTL_
+ 	int i;
+ 	unsigned char laststate;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
++	DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t __user *)data,
+-			     sizeof(vertex) );
++	DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data,
++				 sizeof(vertex));
+ 
+-	DRM_DEBUG( "pid=%d index=%d discard=%d\n",
+-		   DRM_CURRENTPID,
+-		   vertex.idx, vertex.discard );
++	DRM_DEBUG("pid=%d index=%d discard=%d\n",
++		  DRM_CURRENTPID, vertex.idx, vertex.discard);
+ 
+-	if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
+-		DRM_ERROR( "buffer index %d (of %d max)\n",
+-			   vertex.idx, dma->buf_count - 1 );
++	if (vertex.idx < 0 || vertex.idx >= dma->buf_count) {
++		DRM_ERROR("buffer index %d (of %d max)\n",
++			  vertex.idx, dma->buf_count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	buf = dma->buflist[vertex.idx];
+ 
+-	if ( buf->filp != filp ) {
+-		DRM_ERROR( "process %d using buffer owned by %p\n",
+-			   DRM_CURRENTPID, buf->filp );
++	if (buf->filp != filp) {
++		DRM_ERROR("process %d using buffer owned by %p\n",
++			  DRM_CURRENTPID, buf->filp);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( buf->pending ) {
+-		DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
++	if (buf->pending) {
++		DRM_ERROR("sending pending buffer %d\n", vertex.idx);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	
++
+ 	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
+ 		return DRM_ERR(EINVAL);
+ 
+-	for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) {
++	for (laststate = 0xff, i = 0; i < vertex.nr_prims; i++) {
+ 		drm_radeon_prim_t prim;
+ 		drm_radeon_tcl_prim_t tclprim;
+-		
+-		if ( DRM_COPY_FROM_USER( &prim, &vertex.prim[i], sizeof(prim) ) )
++
++		if (DRM_COPY_FROM_USER(&prim, &vertex.prim[i], sizeof(prim)))
+ 			return DRM_ERR(EFAULT);
+-		
+-		if ( prim.stateidx != laststate ) {
+-			drm_radeon_state_t state;			       
+-				
+-			if ( DRM_COPY_FROM_USER( &state, 
+-					     &vertex.state[prim.stateidx], 
+-					     sizeof(state) ) )
++
++		if (prim.stateidx != laststate) {
++			drm_radeon_state_t state;
++
++			if (DRM_COPY_FROM_USER(&state,
++					       &vertex.state[prim.stateidx],
++					       sizeof(state)))
+ 				return DRM_ERR(EFAULT);
+ 
+-			if ( radeon_emit_state2( dev_priv, filp_priv, &state ) ) {
+-				DRM_ERROR( "radeon_emit_state2 failed\n" );
+-				return DRM_ERR( EINVAL );
++			if (radeon_emit_state2(dev_priv, filp_priv, &state)) {
++				DRM_ERROR("radeon_emit_state2 failed\n");
++				return DRM_ERR(EINVAL);
+ 			}
+ 
+ 			laststate = prim.stateidx;
+@@ -2493,42 +2536,40 @@ static int radeon_cp_vertex2( DRM_IOCTL_
+ 		tclprim.prim = prim.prim;
+ 		tclprim.vc_format = prim.vc_format;
+ 
+-		if ( prim.prim & RADEON_PRIM_WALK_IND ) {
++		if (prim.prim & RADEON_PRIM_WALK_IND) {
+ 			tclprim.offset = prim.numverts * 64;
+-			tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
++			tclprim.numverts = RADEON_MAX_VB_VERTS;	/* duh */
+ 
+-			radeon_cp_dispatch_indices( dev, buf, &tclprim );
++			radeon_cp_dispatch_indices(dev, buf, &tclprim);
+ 		} else {
+ 			tclprim.numverts = prim.numverts;
+-			tclprim.offset = 0; /* not used */
++			tclprim.offset = 0;	/* not used */
+ 
+-			radeon_cp_dispatch_vertex( dev, buf, &tclprim );
++			radeon_cp_dispatch_vertex(dev, buf, &tclprim);
+ 		}
+-		
++
+ 		if (sarea_priv->nbox == 1)
+ 			sarea_priv->nbox = 0;
+ 	}
+ 
+-	if ( vertex.discard ) {
+-		radeon_cp_discard_buffer( dev, buf );
++	if (vertex.discard) {
++		radeon_cp_discard_buffer(dev, buf);
+ 	}
+ 
+ 	COMMIT_RING();
+ 	return 0;
+ }
+ 
+-
+-static int radeon_emit_packets( 
+-	drm_radeon_private_t *dev_priv,
+-	drm_file_t *filp_priv,
+-	drm_radeon_cmd_header_t header,
+-	drm_radeon_cmd_buffer_t *cmdbuf )
++static int radeon_emit_packets(drm_radeon_private_t * dev_priv,
++			       drm_file_t * filp_priv,
++			       drm_radeon_cmd_header_t header,
++			       drm_radeon_kcmd_buffer_t *cmdbuf)
+ {
+ 	int id = (int)header.packet.packet_id;
+ 	int sz, reg;
+ 	int *data = (int *)cmdbuf->buf;
+ 	RING_LOCALS;
+-   
++
+ 	if (id >= RADEON_MAX_STATE_PACKETS)
+ 		return DRM_ERR(EINVAL);
+ 
+@@ -2536,18 +2577,18 @@ static int radeon_emit_packets( 
+ 	reg = packet[id].start;
+ 
+ 	if (sz * sizeof(int) > cmdbuf->bufsz) {
+-		DRM_ERROR( "Packet size provided larger than data provided\n" );
++		DRM_ERROR("Packet size provided larger than data provided\n");
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( radeon_check_and_fixup_packets( dev_priv, filp_priv, id, data ) ) {
+-		DRM_ERROR( "Packet verification failed\n" );
+-		return DRM_ERR( EINVAL );
++	if (radeon_check_and_fixup_packets(dev_priv, filp_priv, id, data)) {
++		DRM_ERROR("Packet verification failed\n");
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	BEGIN_RING(sz+1);
+-	OUT_RING( CP_PACKET0( reg, (sz-1) ) );
+-	OUT_RING_TABLE( data, sz );
++	BEGIN_RING(sz + 1);
++	OUT_RING(CP_PACKET0(reg, (sz - 1)));
++	OUT_RING_TABLE(data, sz);
+ 	ADVANCE_RING();
+ 
+ 	cmdbuf->buf += sz * sizeof(int);
+@@ -2555,21 +2596,20 @@ static int radeon_emit_packets( 
+ 	return 0;
+ }
+ 
+-static __inline__ int radeon_emit_scalars( 
+-	drm_radeon_private_t *dev_priv,
+-	drm_radeon_cmd_header_t header,
+-	drm_radeon_cmd_buffer_t *cmdbuf )
++static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv,
++					  drm_radeon_cmd_header_t header,
++					  drm_radeon_kcmd_buffer_t * cmdbuf)
+ {
+ 	int sz = header.scalars.count;
+ 	int start = header.scalars.offset;
+ 	int stride = header.scalars.stride;
+ 	RING_LOCALS;
+ 
+-	BEGIN_RING( 3+sz );
+-	OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
+-	OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
+-	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
+-	OUT_RING_TABLE( cmdbuf->buf, sz );
++	BEGIN_RING(3 + sz);
++	OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
++	OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
++	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
++	OUT_RING_TABLE(cmdbuf->buf, sz);
+ 	ADVANCE_RING();
+ 	cmdbuf->buf += sz * sizeof(int);
+ 	cmdbuf->bufsz -= sz * sizeof(int);
+@@ -2578,42 +2618,40 @@ static __inline__ int radeon_emit_scalar
+ 
+ /* God this is ugly
+  */
+-static __inline__ int radeon_emit_scalars2( 
+-	drm_radeon_private_t *dev_priv,
+-	drm_radeon_cmd_header_t header,
+-	drm_radeon_cmd_buffer_t *cmdbuf )
++static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv,
++					   drm_radeon_cmd_header_t header,
++					   drm_radeon_kcmd_buffer_t * cmdbuf)
+ {
+ 	int sz = header.scalars.count;
+ 	int start = ((unsigned int)header.scalars.offset) + 0x100;
+ 	int stride = header.scalars.stride;
+ 	RING_LOCALS;
+ 
+-	BEGIN_RING( 3+sz );
+-	OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
+-	OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
+-	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
+-	OUT_RING_TABLE( cmdbuf->buf, sz );
++	BEGIN_RING(3 + sz);
++	OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
++	OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
++	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
++	OUT_RING_TABLE(cmdbuf->buf, sz);
+ 	ADVANCE_RING();
+ 	cmdbuf->buf += sz * sizeof(int);
+ 	cmdbuf->bufsz -= sz * sizeof(int);
+ 	return 0;
+ }
+ 
+-static __inline__ int radeon_emit_vectors( 
+-	drm_radeon_private_t *dev_priv,
+-	drm_radeon_cmd_header_t header,
+-	drm_radeon_cmd_buffer_t *cmdbuf )
++static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv,
++					  drm_radeon_cmd_header_t header,
++					  drm_radeon_kcmd_buffer_t * cmdbuf)
+ {
+ 	int sz = header.vectors.count;
+ 	int start = header.vectors.offset;
+ 	int stride = header.vectors.stride;
+ 	RING_LOCALS;
+ 
+-	BEGIN_RING( 3+sz );
+-	OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) );
+-	OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
+-	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) );
+-	OUT_RING_TABLE( cmdbuf->buf, sz );
++	BEGIN_RING(3 + sz);
++	OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
++	OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
++	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
++	OUT_RING_TABLE(cmdbuf->buf, sz);
+ 	ADVANCE_RING();
+ 
+ 	cmdbuf->buf += sz * sizeof(int);
+@@ -2621,10 +2659,9 @@ static __inline__ int radeon_emit_vector
+ 	return 0;
+ }
+ 
+-
+-static int radeon_emit_packet3( drm_device_t *dev,
+-				drm_file_t *filp_priv,
+-				drm_radeon_cmd_buffer_t *cmdbuf )
++static int radeon_emit_packet3(drm_device_t * dev,
++			       drm_file_t * filp_priv,
++			       drm_radeon_kcmd_buffer_t *cmdbuf)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	unsigned int cmdsz;
+@@ -2633,14 +2670,14 @@ static int radeon_emit_packet3( drm_devi
+ 
+ 	DRM_DEBUG("\n");
+ 
+-	if ( ( ret = radeon_check_and_fixup_packet3( dev_priv, filp_priv,
+-						     cmdbuf, &cmdsz ) ) ) {
+-		DRM_ERROR( "Packet verification failed\n" );
++	if ((ret = radeon_check_and_fixup_packet3(dev_priv, filp_priv,
++						  cmdbuf, &cmdsz))) {
++		DRM_ERROR("Packet verification failed\n");
+ 		return ret;
+ 	}
+ 
+-	BEGIN_RING( cmdsz );
+-	OUT_RING_TABLE( cmdbuf->buf, cmdsz );
++	BEGIN_RING(cmdsz);
++	OUT_RING_TABLE(cmdbuf->buf, cmdsz);
+ 	ADVANCE_RING();
+ 
+ 	cmdbuf->buf += cmdsz * 4;
+@@ -2648,11 +2685,10 @@ static int radeon_emit_packet3( drm_devi
+ 	return 0;
+ }
+ 
+-
+-static int radeon_emit_packet3_cliprect( drm_device_t *dev,
+-					 drm_file_t *filp_priv,
+-					 drm_radeon_cmd_buffer_t *cmdbuf,
+-					 int orig_nbox )
++static int radeon_emit_packet3_cliprect(drm_device_t * dev,
++					drm_file_t * filp_priv,
++					drm_radeon_kcmd_buffer_t *cmdbuf,
++					int orig_nbox)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_clip_rect_t box;
+@@ -2664,9 +2700,9 @@ static int radeon_emit_packet3_cliprect(
+ 
+ 	DRM_DEBUG("\n");
+ 
+-	if ( ( ret = radeon_check_and_fixup_packet3( dev_priv, filp_priv,
+-						     cmdbuf, &cmdsz ) ) ) {
+-		DRM_ERROR( "Packet verification failed\n" );
++	if ((ret = radeon_check_and_fixup_packet3(dev_priv, filp_priv,
++						  cmdbuf, &cmdsz))) {
++		DRM_ERROR("Packet verification failed\n");
+ 		return ret;
+ 	}
+ 
+@@ -2674,8 +2710,8 @@ static int radeon_emit_packet3_cliprect(
+ 		goto out;
+ 
+ 	do {
+-		if ( i < cmdbuf->nbox ) {
+-			if (DRM_COPY_FROM_USER( &box, &boxes[i], sizeof(box) ))
++		if (i < cmdbuf->nbox) {
++			if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box)))
+ 				return DRM_ERR(EFAULT);
+ 			/* FIXME The second and subsequent times round
+ 			 * this loop, send a WAIT_UNTIL_3D_IDLE before
+@@ -2689,30 +2725,29 @@ static int radeon_emit_packet3_cliprect(
+ 			 * the correct place to fix it but this works
+ 			 * around it until I can figure that out - Tim
+ 			 * Smith */
+-			if ( i ) {
+-				BEGIN_RING( 2 );
++			if (i) {
++				BEGIN_RING(2);
+ 				RADEON_WAIT_UNTIL_3D_IDLE();
+ 				ADVANCE_RING();
+ 			}
+-			radeon_emit_clip_rect( dev_priv, &box );
++			radeon_emit_clip_rect(dev_priv, &box);
+ 		}
+-		
+-		BEGIN_RING( cmdsz );
+-		OUT_RING_TABLE( cmdbuf->buf, cmdsz );
++
++		BEGIN_RING(cmdsz);
++		OUT_RING_TABLE(cmdbuf->buf, cmdsz);
+ 		ADVANCE_RING();
+ 
+-	} while ( ++i < cmdbuf->nbox );
+- 	if (cmdbuf->nbox == 1)
++	} while (++i < cmdbuf->nbox);
++	if (cmdbuf->nbox == 1)
+ 		cmdbuf->nbox = 0;
+ 
+- out:
++      out:
+ 	cmdbuf->buf += cmdsz * 4;
+ 	cmdbuf->bufsz -= cmdsz * 4;
+ 	return 0;
+ }
+ 
+-
+-static int radeon_emit_wait( drm_device_t *dev, int flags )
++static int radeon_emit_wait(drm_device_t * dev, int flags)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	RING_LOCALS;
+@@ -2720,18 +2755,18 @@ static int radeon_emit_wait( drm_device_
+ 	DRM_DEBUG("%s: %x\n", __FUNCTION__, flags);
+ 	switch (flags) {
+ 	case RADEON_WAIT_2D:
+-		BEGIN_RING( 2 );
+-		RADEON_WAIT_UNTIL_2D_IDLE(); 
++		BEGIN_RING(2);
++		RADEON_WAIT_UNTIL_2D_IDLE();
+ 		ADVANCE_RING();
+ 		break;
+ 	case RADEON_WAIT_3D:
+-		BEGIN_RING( 2 );
+-		RADEON_WAIT_UNTIL_3D_IDLE(); 
++		BEGIN_RING(2);
++		RADEON_WAIT_UNTIL_3D_IDLE();
+ 		ADVANCE_RING();
+ 		break;
+-	case RADEON_WAIT_2D|RADEON_WAIT_3D:
+-		BEGIN_RING( 2 );
+-		RADEON_WAIT_UNTIL_IDLE(); 
++	case RADEON_WAIT_2D | RADEON_WAIT_3D:
++		BEGIN_RING(2);
++		RADEON_WAIT_UNTIL_IDLE();
+ 		ADVANCE_RING();
+ 		break;
+ 	default:
+@@ -2741,7 +2776,7 @@ static int radeon_emit_wait( drm_device_
+ 	return 0;
+ }
+ 
+-static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
++static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+@@ -2749,27 +2784,28 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_buf_t *buf = NULL;
+ 	int idx;
+-	drm_radeon_cmd_buffer_t cmdbuf;
++	drm_radeon_kcmd_buffer_t cmdbuf;
+ 	drm_radeon_cmd_header_t header;
+ 	int orig_nbox, orig_bufsz;
+-	char *kbuf=NULL;
++	char *kbuf = NULL;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
++	DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t __user *)data,
+-			     sizeof(cmdbuf) );
++	DRM_COPY_FROM_USER_IOCTL(cmdbuf,
++				 (drm_radeon_cmd_buffer_t __user *) data,
++				 sizeof(cmdbuf));
+ 
+-	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+-	VB_AGE_TEST_WITH_RETURN( dev_priv );
++	RING_SPACE_TEST_WITH_RETURN(dev_priv);
++	VB_AGE_TEST_WITH_RETURN(dev_priv);
+ 
+-	if (cmdbuf.bufsz > 64*1024 || cmdbuf.bufsz<0) {
++	if (cmdbuf.bufsz > 64 * 1024 || cmdbuf.bufsz < 0) {
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -2782,7 +2818,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 		kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER);
+ 		if (kbuf == NULL)
+ 			return DRM_ERR(ENOMEM);
+-		if (DRM_COPY_FROM_USER(kbuf, cmdbuf.buf, cmdbuf.bufsz)) {
++		if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, cmdbuf.bufsz)) {
+ 			drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
+ 			return DRM_ERR(EFAULT);
+ 		}
+@@ -2791,27 +2827,28 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 
+ 	orig_nbox = cmdbuf.nbox;
+ 
+-	if(dev_priv->microcode_version == UCODE_R300) {
++	if (dev_priv->microcode_version == UCODE_R300) {
+ 		int temp;
+-		temp=r300_do_cp_cmdbuf(dev, filp, filp_priv, &cmdbuf);
+-	
++		temp = r300_do_cp_cmdbuf(dev, filp, filp_priv, &cmdbuf);
++
+ 		if (orig_bufsz != 0)
+ 			drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
+-	
++
+ 		return temp;
+ 	}
+ 
+ 	/* microcode_version != r300 */
+-	while ( cmdbuf.bufsz >= sizeof(header) ) {
++	while (cmdbuf.bufsz >= sizeof(header)) {
+ 
+ 		header.i = *(int *)cmdbuf.buf;
+ 		cmdbuf.buf += sizeof(header);
+ 		cmdbuf.bufsz -= sizeof(header);
+ 
+ 		switch (header.header.cmd_type) {
+-		case RADEON_CMD_PACKET: 
++		case RADEON_CMD_PACKET:
+ 			DRM_DEBUG("RADEON_CMD_PACKET\n");
+-			if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) {
++			if (radeon_emit_packets
++			    (dev_priv, filp_priv, header, &cmdbuf)) {
+ 				DRM_ERROR("radeon_emit_packets failed\n");
+ 				goto err;
+ 			}
+@@ -2819,7 +2856,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 
+ 		case RADEON_CMD_SCALARS:
+ 			DRM_DEBUG("RADEON_CMD_SCALARS\n");
+-			if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) {
++			if (radeon_emit_scalars(dev_priv, header, &cmdbuf)) {
+ 				DRM_ERROR("radeon_emit_scalars failed\n");
+ 				goto err;
+ 			}
+@@ -2827,7 +2864,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 
+ 		case RADEON_CMD_VECTORS:
+ 			DRM_DEBUG("RADEON_CMD_VECTORS\n");
+-			if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) {
++			if (radeon_emit_vectors(dev_priv, header, &cmdbuf)) {
+ 				DRM_ERROR("radeon_emit_vectors failed\n");
+ 				goto err;
+ 			}
+@@ -2836,25 +2873,25 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 		case RADEON_CMD_DMA_DISCARD:
+ 			DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
+ 			idx = header.dma.buf_idx;
+-			if ( idx < 0 || idx >= dma->buf_count ) {
+-				DRM_ERROR( "buffer index %d (of %d max)\n",
+-					   idx, dma->buf_count - 1 );
++			if (idx < 0 || idx >= dma->buf_count) {
++				DRM_ERROR("buffer index %d (of %d max)\n",
++					  idx, dma->buf_count - 1);
+ 				goto err;
+ 			}
+ 
+ 			buf = dma->buflist[idx];
+-			if ( buf->filp != filp || buf->pending ) {
+-				DRM_ERROR( "bad buffer %p %p %d\n",
+-					   buf->filp, filp, buf->pending);
++			if (buf->filp != filp || buf->pending) {
++				DRM_ERROR("bad buffer %p %p %d\n",
++					  buf->filp, filp, buf->pending);
+ 				goto err;
+ 			}
+ 
+-			radeon_cp_discard_buffer( dev, buf );
++			radeon_cp_discard_buffer(dev, buf);
+ 			break;
+ 
+ 		case RADEON_CMD_PACKET3:
+ 			DRM_DEBUG("RADEON_CMD_PACKET3\n");
+-			if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) {
++			if (radeon_emit_packet3(dev, filp_priv, &cmdbuf)) {
+ 				DRM_ERROR("radeon_emit_packet3 failed\n");
+ 				goto err;
+ 			}
+@@ -2862,7 +2899,8 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 
+ 		case RADEON_CMD_PACKET3_CLIP:
+ 			DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
+-			if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) {
++			if (radeon_emit_packet3_cliprect
++			    (dev, filp_priv, &cmdbuf, orig_nbox)) {
+ 				DRM_ERROR("radeon_emit_packet3_clip failed\n");
+ 				goto err;
+ 			}
+@@ -2870,7 +2908,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 
+ 		case RADEON_CMD_SCALARS2:
+ 			DRM_DEBUG("RADEON_CMD_SCALARS2\n");
+-			if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) {
++			if (radeon_emit_scalars2(dev_priv, header, &cmdbuf)) {
+ 				DRM_ERROR("radeon_emit_scalars2 failed\n");
+ 				goto err;
+ 			}
+@@ -2878,13 +2916,13 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 
+ 		case RADEON_CMD_WAIT:
+ 			DRM_DEBUG("RADEON_CMD_WAIT\n");
+-			if (radeon_emit_wait( dev, header.wait.flags )) {
++			if (radeon_emit_wait(dev, header.wait.flags)) {
+ 				DRM_ERROR("radeon_emit_wait failed\n");
+ 				goto err;
+ 			}
+ 			break;
+ 		default:
+-			DRM_ERROR("bad cmd_type %d at %p\n", 
++			DRM_ERROR("bad cmd_type %d at %p\n",
+ 				  header.header.cmd_type,
+ 				  cmdbuf.buf - sizeof(header));
+ 			goto err;
+@@ -2898,45 +2936,43 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_A
+ 	COMMIT_RING();
+ 	return 0;
+ 
+-err:
++      err:
+ 	if (orig_bufsz != 0)
+ 		drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
+ 	return DRM_ERR(EINVAL);
+ }
+ 
+-
+-
+-static int radeon_cp_getparam( DRM_IOCTL_ARGS )
++static int radeon_cp_getparam(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_radeon_getparam_t param;
+ 	int value;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t __user *)data,
+-			     sizeof(param) );
++	DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data,
++				 sizeof(param));
+ 
+-	DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
++	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
+ 
+-	switch( param.param ) {
++	switch (param.param) {
+ 	case RADEON_PARAM_GART_BUFFER_OFFSET:
+ 		value = dev_priv->gart_buffers_offset;
+ 		break;
+ 	case RADEON_PARAM_LAST_FRAME:
+ 		dev_priv->stats.last_frame_reads++;
+-		value = GET_SCRATCH( 0 );
++		value = GET_SCRATCH(0);
+ 		break;
+ 	case RADEON_PARAM_LAST_DISPATCH:
+-		value = GET_SCRATCH( 1 );
++		value = GET_SCRATCH(1);
+ 		break;
+ 	case RADEON_PARAM_LAST_CLEAR:
+ 		dev_priv->stats.last_clear_reads++;
+-		value = GET_SCRATCH( 2 );
++		value = GET_SCRATCH(2);
+ 		break;
+ 	case RADEON_PARAM_IRQ_NR:
+ 		value = dev->irq;
+@@ -2951,15 +2987,15 @@ static int radeon_cp_getparam( DRM_IOCTL
+ 		value = dev_priv->ring_rptr_offset;
+ 		break;
+ #if BITS_PER_LONG == 32
+-	/*
+-	 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
+-	 * pointer which can't fit into an int-sized variable.  According to
+-	 * Michel Dänzer, the ioctl() is only used on embedded platforms, so
+-	 * not supporting it shouldn't be a problem.  If the same functionality
+-	 * is needed on 64-bit platforms, a new ioctl() would have to be added,
+-	 * so backwards-compatibility for the embedded platforms can be
+-	 * maintained.  --davidm 4-Feb-2004.
+-	 */
++		/*
++		 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
++		 * pointer which can't fit into an int-sized variable.  According to
++		 * Michel Dänzer, the ioctl() is only used on embedded platforms, so
++		 * not supporting it shouldn't be a problem.  If the same functionality
++		 * is needed on 64-bit platforms, a new ioctl() would have to be added,
++		 * so backwards-compatibility for the embedded platforms can be
++		 * maintained.  --davidm 4-Feb-2004.
++		 */
+ 	case RADEON_PARAM_SAREA_HANDLE:
+ 		/* The lock is the first dword in the sarea. */
+ 		value = (long)dev->lock.hw_lock;
+@@ -2972,53 +3008,56 @@ static int radeon_cp_getparam( DRM_IOCTL
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
+-		DRM_ERROR( "copy_to_user\n" );
++	if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) {
++		DRM_ERROR("copy_to_user\n");
+ 		return DRM_ERR(EFAULT);
+ 	}
+-	
++
+ 	return 0;
+ }
+ 
+-static int radeon_cp_setparam( DRM_IOCTL_ARGS ) {
++static int radeon_cp_setparam(DRM_IOCTL_ARGS)
++{
+ 	DRM_DEVICE;
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	drm_file_t *filp_priv;
+ 	drm_radeon_setparam_t sp;
+ 	struct drm_radeon_driver_file_fields *radeon_priv;
+ 
+-	if ( !dev_priv ) {
+-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+-		return DRM_ERR( EINVAL );
++	if (!dev_priv) {
++		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
++	DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL( sp, ( drm_radeon_setparam_t __user * )data,
+-				  sizeof( sp ) );
++	DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data,
++				 sizeof(sp));
+ 
+-	switch( sp.param ) {
++	switch (sp.param) {
+ 	case RADEON_SETPARAM_FB_LOCATION:
+ 		radeon_priv = filp_priv->driver_priv;
+ 		radeon_priv->radeon_fb_delta = dev_priv->fb_location - sp.value;
+ 		break;
+ 	case RADEON_SETPARAM_SWITCH_TILING:
+ 		if (sp.value == 0) {
+-			DRM_DEBUG( "color tiling disabled\n" );
++			DRM_DEBUG("color tiling disabled\n");
+ 			dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
+ 			dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
+ 			dev_priv->sarea_priv->tiling_enabled = 0;
+-		}
+-		else if (sp.value == 1) {
+-			DRM_DEBUG( "color tiling enabled\n" );
++		} else if (sp.value == 1) {
++			DRM_DEBUG("color tiling enabled\n");
+ 			dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
+ 			dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
+ 			dev_priv->sarea_priv->tiling_enabled = 1;
+ 		}
+-		break;	
++		break;
++	case RADEON_SETPARAM_PCIGART_LOCATION:
++		dev_priv->pcigart_offset = sp.value;
++		break;
+ 	default:
+-		DRM_DEBUG( "Invalid parameter %d\n", sp.param );
+-		return DRM_ERR( EINVAL );
++		DRM_DEBUG("Invalid parameter %d\n", sp.param);
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	return 0;
+@@ -3030,78 +3069,80 @@ static int radeon_cp_setparam( DRM_IOCTL
+  *
+  * DRM infrastructure takes care of reclaiming dma buffers.
+  */
+-void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp)
++void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+ {
+-	if ( dev->dev_private ) {				
+-		drm_radeon_private_t *dev_priv = dev->dev_private; 
+-		if ( dev_priv->page_flipping ) {		
+-			radeon_do_cleanup_pageflip( dev );	
+-		}						
+-		radeon_mem_release( filp, dev_priv->gart_heap ); 
+-		radeon_mem_release( filp, dev_priv->fb_heap );	
++	if (dev->dev_private) {
++		drm_radeon_private_t *dev_priv = dev->dev_private;
++		if (dev_priv->page_flipping) {
++			radeon_do_cleanup_pageflip(dev);
++		}
++		radeon_mem_release(filp, dev_priv->gart_heap);
++		radeon_mem_release(filp, dev_priv->fb_heap);
+ 		radeon_surfaces_release(filp, dev_priv);
+-	}				
++	}
+ }
+ 
+-void radeon_driver_pretakedown(drm_device_t *dev)
++void radeon_driver_pretakedown(drm_device_t * dev)
+ {
+ 	radeon_do_release(dev);
+ }
+ 
+-int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv)
++int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv)
+ {
+ 	drm_radeon_private_t *dev_priv = dev->dev_private;
+ 	struct drm_radeon_driver_file_fields *radeon_priv;
+-	
+-	radeon_priv = (struct drm_radeon_driver_file_fields *)drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
+-	
++
++	radeon_priv =
++	    (struct drm_radeon_driver_file_fields *)
++	    drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
++
+ 	if (!radeon_priv)
+ 		return -ENOMEM;
+ 
+ 	filp_priv->driver_priv = radeon_priv;
+-	if ( dev_priv )
++	if (dev_priv)
+ 		radeon_priv->radeon_fb_delta = dev_priv->fb_location;
+ 	else
+ 		radeon_priv->radeon_fb_delta = 0;
+ 	return 0;
+ }
+ 
+-
+-void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv)
++void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv)
+ {
+-	 struct drm_radeon_driver_file_fields *radeon_priv = filp_priv->driver_priv;
+-	 
+-	 drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
++	struct drm_radeon_driver_file_fields *radeon_priv =
++	    filp_priv->driver_priv;
++
++	drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
+ }
+ 
+ drm_ioctl_desc_t radeon_ioctls[] = {
+-	[DRM_IOCTL_NR(DRM_RADEON_CP_INIT)]    = { radeon_cp_init,      1, 1 },
+-	[DRM_IOCTL_NR(DRM_RADEON_CP_START)]   = { radeon_cp_start,     1, 1 },
+-	[DRM_IOCTL_NR(DRM_RADEON_CP_STOP)]    = { radeon_cp_stop,      1, 1 },
+-	[DRM_IOCTL_NR(DRM_RADEON_CP_RESET)]   = { radeon_cp_reset,     1, 1 },
+-	[DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)]    = { radeon_cp_idle,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)]  = { radeon_cp_resume,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_RESET)]      = { radeon_engine_reset, 1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = { radeon_fullscreen,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_SWAP)]       = { radeon_cp_swap,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_CLEAR)]      = { radeon_cp_clear,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_VERTEX)]     = { radeon_cp_vertex,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_INDICES)]    = { radeon_cp_indices,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_TEXTURE)]    = { radeon_cp_texture,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_STIPPLE)]    = { radeon_cp_stipple,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_INDIRECT)]   = { radeon_cp_indirect,  1, 1 },
+-	[DRM_IOCTL_NR(DRM_RADEON_VERTEX2)]    = { radeon_cp_vertex2,   1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_CMDBUF)]     = { radeon_cp_cmdbuf,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_GETPARAM)]   = { radeon_cp_getparam,  1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_FLIP)]       = { radeon_cp_flip,      1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_ALLOC)]      = { radeon_mem_alloc,    1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_FREE)]       = { radeon_mem_free,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)]  = { radeon_mem_init_heap,1, 1 },
+-	[DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)]   = { radeon_irq_emit,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)]   = { radeon_irq_wait,     1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_SETPARAM)]   = { radeon_cp_setparam,  1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = { radeon_surface_alloc,1, 0 },
+-	[DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)]  = { radeon_surface_free, 1, 0 }
++	[DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, 1, 1},
++	[DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, 1, 1},
++	[DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, 1, 1},
++	[DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, 1, 1},
++	[DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, 1, 1},
++	[DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, 1, 1},
++	[DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, 1, 0},
++	[DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, 1, 0}
+ };
+ 
+ int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
+diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
+--- a/drivers/char/drm/savage_bci.c
++++ b/drivers/char/drm/savage_bci.c
+@@ -28,12 +28,12 @@
+ 
+ /* Need a long timeout for shadow status updates can take a while
+  * and so can waiting for events when the queue is full. */
+-#define SAVAGE_DEFAULT_USEC_TIMEOUT	1000000 /* 1s */
+-#define SAVAGE_EVENT_USEC_TIMEOUT	5000000 /* 5s */
++#define SAVAGE_DEFAULT_USEC_TIMEOUT	1000000	/* 1s */
++#define SAVAGE_EVENT_USEC_TIMEOUT	5000000	/* 5s */
+ #define SAVAGE_FREELIST_DEBUG		0
+ 
+ static int
+-savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n)
++savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n)
+ {
+ 	uint32_t mask = dev_priv->status_used_mask;
+ 	uint32_t threshold = dev_priv->bci_threshold_hi;
+@@ -62,7 +62,7 @@ savage_bci_wait_fifo_shadow(drm_savage_p
+ }
+ 
+ static int
+-savage_bci_wait_fifo_s3d(drm_savage_private_t *dev_priv, unsigned int n)
++savage_bci_wait_fifo_s3d(drm_savage_private_t * dev_priv, unsigned int n)
+ {
+ 	uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
+ 	uint32_t status;
+@@ -83,7 +83,7 @@ savage_bci_wait_fifo_s3d(drm_savage_priv
+ }
+ 
+ static int
+-savage_bci_wait_fifo_s4(drm_savage_private_t *dev_priv, unsigned int n)
++savage_bci_wait_fifo_s4(drm_savage_private_t * dev_priv, unsigned int n)
+ {
+ 	uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
+ 	uint32_t status;
+@@ -115,7 +115,7 @@ savage_bci_wait_fifo_s4(drm_savage_priva
+  * rule. Otherwise there may be glitches every 2^16 events.
+  */
+ static int
+-savage_bci_wait_event_shadow(drm_savage_private_t *dev_priv, uint16_t e)
++savage_bci_wait_event_shadow(drm_savage_private_t * dev_priv, uint16_t e)
+ {
+ 	uint32_t status;
+ 	int i;
+@@ -138,7 +138,7 @@ savage_bci_wait_event_shadow(drm_savage_
+ }
+ 
+ static int
+-savage_bci_wait_event_reg(drm_savage_private_t *dev_priv, uint16_t e)
++savage_bci_wait_event_reg(drm_savage_private_t * dev_priv, uint16_t e)
+ {
+ 	uint32_t status;
+ 	int i;
+@@ -159,7 +159,7 @@ savage_bci_wait_event_reg(drm_savage_pri
+ 	return DRM_ERR(EBUSY);
+ }
+ 
+-uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
++uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv,
+ 			       unsigned int flags)
+ {
+ 	uint16_t count;
+@@ -175,12 +175,12 @@ uint16_t savage_bci_emit_event(drm_savag
+ 	}
+ 	count = (count + 1) & 0xffff;
+ 	if (count == 0) {
+-		count++; /* See the comment above savage_wait_event_*. */
++		count++;	/* See the comment above savage_wait_event_*. */
+ 		dev_priv->event_wrap++;
+ 	}
+ 	dev_priv->event_counter = count;
+ 	if (dev_priv->status_ptr)
+-		dev_priv->status_ptr[1023] = (uint32_t)count;
++		dev_priv->status_ptr[1023] = (uint32_t) count;
+ 
+ 	if ((flags & (SAVAGE_WAIT_2D | SAVAGE_WAIT_3D))) {
+ 		unsigned int wait_cmd = BCI_CMD_WAIT;
+@@ -193,7 +193,7 @@ uint16_t savage_bci_emit_event(drm_savag
+ 	} else {
+ 		BEGIN_BCI(1);
+ 	}
+-	BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t)count);
++	BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t) count);
+ 
+ 	return count;
+ }
+@@ -201,7 +201,7 @@ uint16_t savage_bci_emit_event(drm_savag
+ /*
+  * Freelist management
+  */
+-static int savage_freelist_init(drm_device_t *dev)
++static int savage_freelist_init(drm_device_t * dev)
+ {
+ 	drm_savage_private_t *dev_priv = dev->dev_private;
+ 	drm_device_dma_t *dma = dev->dma;
+@@ -234,7 +234,7 @@ static int savage_freelist_init(drm_devi
+ 	return 0;
+ }
+ 
+-static drm_buf_t *savage_freelist_get(drm_device_t *dev)
++static drm_buf_t *savage_freelist_get(drm_device_t * dev)
+ {
+ 	drm_savage_private_t *dev_priv = dev->dev_private;
+ 	drm_savage_buf_priv_t *tail = dev_priv->tail.prev;
+@@ -249,7 +249,7 @@ static drm_buf_t *savage_freelist_get(dr
+ 		event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
+ 	wrap = dev_priv->event_wrap;
+ 	if (event > dev_priv->event_counter)
+-		wrap--; /* hardware hasn't passed the last wrap yet */
++		wrap--;		/* hardware hasn't passed the last wrap yet */
+ 
+ 	DRM_DEBUG("   tail=0x%04x %d\n", tail->age.event, tail->age.wrap);
+ 	DRM_DEBUG("   head=0x%04x %d\n", event, wrap);
+@@ -267,7 +267,7 @@ static drm_buf_t *savage_freelist_get(dr
+ 	return NULL;
+ }
+ 
+-void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf)
++void savage_freelist_put(drm_device_t * dev, drm_buf_t * buf)
+ {
+ 	drm_savage_private_t *dev_priv = dev->dev_private;
+ 	drm_savage_buf_priv_t *entry = buf->dev_private, *prev, *next;
+@@ -290,15 +290,14 @@ void savage_freelist_put(drm_device_t *d
+ /*
+  * Command DMA
+  */
+-static int savage_dma_init(drm_savage_private_t *dev_priv)
++static int savage_dma_init(drm_savage_private_t * dev_priv)
+ {
+ 	unsigned int i;
+ 
+ 	dev_priv->nr_dma_pages = dev_priv->cmd_dma->size /
+-		(SAVAGE_DMA_PAGE_SIZE*4);
++	    (SAVAGE_DMA_PAGE_SIZE * 4);
+ 	dev_priv->dma_pages = drm_alloc(sizeof(drm_savage_dma_page_t) *
+-					dev_priv->nr_dma_pages,
+-					DRM_MEM_DRIVER);
++					dev_priv->nr_dma_pages, DRM_MEM_DRIVER);
+ 	if (dev_priv->dma_pages == NULL)
+ 		return DRM_ERR(ENOMEM);
+ 
+@@ -315,7 +314,7 @@ static int savage_dma_init(drm_savage_pr
+ 	return 0;
+ }
+ 
+-void savage_dma_reset(drm_savage_private_t *dev_priv)
++void savage_dma_reset(drm_savage_private_t * dev_priv)
+ {
+ 	uint16_t event;
+ 	unsigned int wrap, i;
+@@ -330,7 +329,7 @@ void savage_dma_reset(drm_savage_private
+ 	dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
+ }
+ 
+-void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page)
++void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page)
+ {
+ 	uint16_t event;
+ 	unsigned int wrap;
+@@ -346,7 +345,7 @@ void savage_dma_wait(drm_savage_private_
+ 		event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
+ 	wrap = dev_priv->event_wrap;
+ 	if (event > dev_priv->event_counter)
+-		wrap--; /* hardware hasn't passed the last wrap yet */
++		wrap--;		/* hardware hasn't passed the last wrap yet */
+ 
+ 	if (dev_priv->dma_pages[page].age.wrap > wrap ||
+ 	    (dev_priv->dma_pages[page].age.wrap == wrap &&
+@@ -358,13 +357,13 @@ void savage_dma_wait(drm_savage_private_
+ 	}
+ }
+ 
+-uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
++uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, unsigned int n)
+ {
+ 	unsigned int cur = dev_priv->current_dma_page;
+ 	unsigned int rest = SAVAGE_DMA_PAGE_SIZE -
+-		dev_priv->dma_pages[cur].used;
+-	unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE-1) /
+-		SAVAGE_DMA_PAGE_SIZE;
++	    dev_priv->dma_pages[cur].used;
++	unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE - 1) /
++	    SAVAGE_DMA_PAGE_SIZE;
+ 	uint32_t *dma_ptr;
+ 	unsigned int i;
+ 
+@@ -372,9 +371,8 @@ uint32_t *savage_dma_alloc(drm_savage_pr
+ 		  cur, dev_priv->dma_pages[cur].used, n, rest, nr_pages);
+ 
+ 	if (cur + nr_pages < dev_priv->nr_dma_pages) {
+-		dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
+-			cur*SAVAGE_DMA_PAGE_SIZE +
+-			dev_priv->dma_pages[cur].used;
++		dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
++		    cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
+ 		if (n < rest)
+ 			rest = n;
+ 		dev_priv->dma_pages[cur].used += rest;
+@@ -382,13 +380,14 @@ uint32_t *savage_dma_alloc(drm_savage_pr
+ 		cur++;
+ 	} else {
+ 		dev_priv->dma_flush(dev_priv);
+-		nr_pages = (n + SAVAGE_DMA_PAGE_SIZE-1) / SAVAGE_DMA_PAGE_SIZE;
++		nr_pages =
++		    (n + SAVAGE_DMA_PAGE_SIZE - 1) / SAVAGE_DMA_PAGE_SIZE;
+ 		for (i = cur; i < dev_priv->nr_dma_pages; ++i) {
+ 			dev_priv->dma_pages[i].age = dev_priv->last_dma_age;
+ 			dev_priv->dma_pages[i].used = 0;
+ 			dev_priv->dma_pages[i].flushed = 0;
+ 		}
+-		dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle;
++		dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle;
+ 		dev_priv->first_dma_page = cur = 0;
+ 	}
+ 	for (i = cur; nr_pages > 0; ++i, --nr_pages) {
+@@ -414,7 +413,7 @@ uint32_t *savage_dma_alloc(drm_savage_pr
+ 	return dma_ptr;
+ }
+ 
+-static void savage_dma_flush(drm_savage_private_t *dev_priv)
++static void savage_dma_flush(drm_savage_private_t * dev_priv)
+ {
+ 	unsigned int first = dev_priv->first_dma_page;
+ 	unsigned int cur = dev_priv->current_dma_page;
+@@ -439,11 +438,10 @@ static void savage_dma_flush(drm_savage_
+ 
+ 	/* pad with noops */
+ 	if (pad) {
+-		uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
+-			cur * SAVAGE_DMA_PAGE_SIZE +
+-			dev_priv->dma_pages[cur].used;
++		uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
++		    cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
+ 		dev_priv->dma_pages[cur].used += pad;
+-		while(pad != 0) {
++		while (pad != 0) {
+ 			*dma_ptr++ = BCI_CMD_WAIT;
+ 			pad--;
+ 		}
+@@ -453,11 +451,10 @@ static void savage_dma_flush(drm_savage_
+ 
+ 	/* do flush ... */
+ 	phys_addr = dev_priv->cmd_dma->offset +
+-		(first * SAVAGE_DMA_PAGE_SIZE +
+-		 dev_priv->dma_pages[first].flushed) * 4;
++	    (first * SAVAGE_DMA_PAGE_SIZE +
++	     dev_priv->dma_pages[first].flushed) * 4;
+ 	len = (cur - first) * SAVAGE_DMA_PAGE_SIZE +
+-		dev_priv->dma_pages[cur].used -
+-		dev_priv->dma_pages[first].flushed;
++	    dev_priv->dma_pages[cur].used - dev_priv->dma_pages[first].flushed;
+ 
+ 	DRM_DEBUG("phys_addr=%lx, len=%u\n",
+ 		  phys_addr | dev_priv->dma_type, len);
+@@ -499,7 +496,7 @@ static void savage_dma_flush(drm_savage_
+ 		  dev_priv->dma_pages[cur].flushed);
+ }
+ 
+-static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
++static void savage_fake_dma_flush(drm_savage_private_t * dev_priv)
+ {
+ 	unsigned int i, j;
+ 	BCI_LOCALS;
+@@ -515,8 +512,8 @@ static void savage_fake_dma_flush(drm_sa
+ 	for (i = dev_priv->first_dma_page;
+ 	     i <= dev_priv->current_dma_page && dev_priv->dma_pages[i].used;
+ 	     ++i) {
+-		uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
+-			i * SAVAGE_DMA_PAGE_SIZE;
++		uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
++		    i * SAVAGE_DMA_PAGE_SIZE;
+ #if SAVAGE_DMA_DEBUG
+ 		/* Sanity check: all pages except the last one must be full. */
+ 		if (i < dev_priv->current_dma_page &&
+@@ -543,7 +540,7 @@ static void savage_fake_dma_flush(drm_sa
+  * initialized. We also need to take care of deleting the MTRRs in
+  * postcleanup.
+  */
+-int savage_preinit(drm_device_t *dev, unsigned long chipset)
++int savage_preinit(drm_device_t * dev, unsigned long chipset)
+ {
+ 	drm_savage_private_t *dev_priv;
+ 	unsigned long mmio_base, fb_base, fb_size, aperture_base;
+@@ -578,19 +575,22 @@ int savage_preinit(drm_device_t *dev, un
+ 			 * MTRRs. */
+ 			dev_priv->mtrr[0].base = fb_base;
+ 			dev_priv->mtrr[0].size = 0x01000000;
+-			dev_priv->mtrr[0].handle = mtrr_add(
+-				dev_priv->mtrr[0].base, dev_priv->mtrr[0].size,
+-				MTRR_TYPE_WRCOMB, 1);
+-			dev_priv->mtrr[1].base = fb_base+0x02000000;
++			dev_priv->mtrr[0].handle =
++			    mtrr_add(dev_priv->mtrr[0].base,
++				     dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB,
++				     1);
++			dev_priv->mtrr[1].base = fb_base + 0x02000000;
+ 			dev_priv->mtrr[1].size = 0x02000000;
+-			dev_priv->mtrr[1].handle = mtrr_add(
+-				dev_priv->mtrr[1].base, dev_priv->mtrr[1].size,
+-				MTRR_TYPE_WRCOMB, 1);
+-			dev_priv->mtrr[2].base = fb_base+0x04000000;
++			dev_priv->mtrr[1].handle =
++			    mtrr_add(dev_priv->mtrr[1].base,
++				     dev_priv->mtrr[1].size, MTRR_TYPE_WRCOMB,
++				     1);
++			dev_priv->mtrr[2].base = fb_base + 0x04000000;
+ 			dev_priv->mtrr[2].size = 0x04000000;
+-			dev_priv->mtrr[2].handle = mtrr_add(
+-				dev_priv->mtrr[2].base, dev_priv->mtrr[2].size,
+-				MTRR_TYPE_WRCOMB, 1);
++			dev_priv->mtrr[2].handle =
++			    mtrr_add(dev_priv->mtrr[2].base,
++				     dev_priv->mtrr[2].size, MTRR_TYPE_WRCOMB,
++				     1);
+ 		} else {
+ 			DRM_ERROR("strange pci_resource_len %08lx\n",
+ 				  drm_get_resource_len(dev, 0));
+@@ -608,9 +608,10 @@ int savage_preinit(drm_device_t *dev, un
+ 			 * aperture. */
+ 			dev_priv->mtrr[0].base = fb_base;
+ 			dev_priv->mtrr[0].size = 0x08000000;
+-			dev_priv->mtrr[0].handle = mtrr_add(
+-				dev_priv->mtrr[0].base, dev_priv->mtrr[0].size,
+-				MTRR_TYPE_WRCOMB, 1);
++			dev_priv->mtrr[0].handle =
++			    mtrr_add(dev_priv->mtrr[0].base,
++				     dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB,
++				     1);
+ 		} else {
+ 			DRM_ERROR("strange pci_resource_len %08lx\n",
+ 				  drm_get_resource_len(dev, 1));
+@@ -647,7 +648,7 @@ int savage_preinit(drm_device_t *dev, un
+ /*
+  * Delete MTRRs and free device-private data.
+  */
+-int savage_postcleanup(drm_device_t *dev)
++int savage_postcleanup(drm_device_t * dev)
+ {
+ 	drm_savage_private_t *dev_priv = dev->dev_private;
+ 	int i;
+@@ -663,7 +664,7 @@ int savage_postcleanup(drm_device_t *dev
+ 	return 0;
+ }
+ 
+-static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
++static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init)
+ {
+ 	drm_savage_private_t *dev_priv = dev->dev_private;
+ 
+@@ -731,7 +732,7 @@ static int savage_do_init_bci(drm_device
+ 	}
+ 	if (init->agp_textures_offset) {
+ 		dev_priv->agp_textures =
+-			drm_core_findmap(dev, init->agp_textures_offset);
++		    drm_core_findmap(dev, init->agp_textures_offset);
+ 		if (!dev_priv->agp_textures) {
+ 			DRM_ERROR("could not find agp texture region!\n");
+ 			savage_do_cleanup_bci(dev);
+@@ -802,8 +803,8 @@ static int savage_do_init_bci(drm_device
+ 	}
+ 
+ 	dev_priv->sarea_priv =
+-		(drm_savage_sarea_t *)((uint8_t *)dev_priv->sarea->handle +
+-				       init->sarea_priv_offset);
++	    (drm_savage_sarea_t *) ((uint8_t *) dev_priv->sarea->handle +
++				    init->sarea_priv_offset);
+ 
+ 	/* setup bitmap descriptors */
+ 	{
+@@ -812,35 +813,36 @@ static int savage_do_init_bci(drm_device
+ 		unsigned int front_stride, back_stride, depth_stride;
+ 		if (dev_priv->chipset <= S3_SAVAGE4) {
+ 			color_tile_format = dev_priv->fb_bpp == 16 ?
+-				SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
++			    SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
+ 			depth_tile_format = dev_priv->depth_bpp == 16 ?
+-				SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
++			    SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
+ 		} else {
+ 			color_tile_format = SAVAGE_BD_TILE_DEST;
+ 			depth_tile_format = SAVAGE_BD_TILE_DEST;
+ 		}
+-		front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp/8);
+-		back_stride  = dev_priv-> back_pitch / (dev_priv->fb_bpp/8);
+-		depth_stride = dev_priv->depth_pitch / (dev_priv->depth_bpp/8);
++		front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp / 8);
++		back_stride = dev_priv->back_pitch / (dev_priv->fb_bpp / 8);
++		depth_stride =
++		    dev_priv->depth_pitch / (dev_priv->depth_bpp / 8);
+ 
+ 		dev_priv->front_bd = front_stride | SAVAGE_BD_BW_DISABLE |
+-			(dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
+-			(color_tile_format << SAVAGE_BD_TILE_SHIFT);
++		    (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
++		    (color_tile_format << SAVAGE_BD_TILE_SHIFT);
+ 
+-		dev_priv-> back_bd =  back_stride | SAVAGE_BD_BW_DISABLE |
+-			(dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
+-			(color_tile_format << SAVAGE_BD_TILE_SHIFT);
++		dev_priv->back_bd = back_stride | SAVAGE_BD_BW_DISABLE |
++		    (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
++		    (color_tile_format << SAVAGE_BD_TILE_SHIFT);
+ 
+ 		dev_priv->depth_bd = depth_stride | SAVAGE_BD_BW_DISABLE |
+-			(dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) |
+-			(depth_tile_format << SAVAGE_BD_TILE_SHIFT);
++		    (dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) |
++		    (depth_tile_format << SAVAGE_BD_TILE_SHIFT);
+ 	}
+ 
+ 	/* setup status and bci ptr */
+ 	dev_priv->event_counter = 0;
+ 	dev_priv->event_wrap = 0;
+ 	dev_priv->bci_ptr = (volatile uint32_t *)
+-	    ((uint8_t *)dev_priv->mmio->handle + SAVAGE_BCI_OFFSET);
++	    ((uint8_t *) dev_priv->mmio->handle + SAVAGE_BCI_OFFSET);
+ 	if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
+ 		dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S3D;
+ 	} else {
+@@ -848,7 +850,7 @@ static int savage_do_init_bci(drm_device
+ 	}
+ 	if (dev_priv->status != NULL) {
+ 		dev_priv->status_ptr =
+-			(volatile uint32_t *)dev_priv->status->handle;
++		    (volatile uint32_t *)dev_priv->status->handle;
+ 		dev_priv->wait_fifo = savage_bci_wait_fifo_shadow;
+ 		dev_priv->wait_evnt = savage_bci_wait_event_shadow;
+ 		dev_priv->status_ptr[1023] = dev_priv->event_counter;
+@@ -874,7 +876,7 @@ static int savage_do_init_bci(drm_device
+ 		return DRM_ERR(ENOMEM);
+ 	}
+ 
+-	if (savage_dma_init(dev_priv) <  0) {
++	if (savage_dma_init(dev_priv) < 0) {
+ 		DRM_ERROR("could not initialize command DMA\n");
+ 		savage_do_cleanup_bci(dev);
+ 		return DRM_ERR(ENOMEM);
+@@ -883,7 +885,7 @@ static int savage_do_init_bci(drm_device
+ 	return 0;
+ }
+ 
+-int savage_do_cleanup_bci(drm_device_t *dev)
++int savage_do_cleanup_bci(drm_device_t * dev)
+ {
+ 	drm_savage_private_t *dev_priv = dev->dev_private;
+ 
+@@ -907,7 +909,7 @@ int savage_do_cleanup_bci(drm_device_t *
+ 
+ 	if (dev_priv->dma_pages)
+ 		drm_free(dev_priv->dma_pages,
+-			 sizeof(drm_savage_dma_page_t)*dev_priv->nr_dma_pages,
++			 sizeof(drm_savage_dma_page_t) * dev_priv->nr_dma_pages,
+ 			 DRM_MEM_DRIVER);
+ 
+ 	return 0;
+@@ -920,7 +922,7 @@ static int savage_bci_init(DRM_IOCTL_ARG
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *)data,
++	DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *) data,
+ 				 sizeof(init));
+ 
+ 	switch (init.func) {
+@@ -943,13 +945,13 @@ static int savage_bci_event_emit(DRM_IOC
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *)data,
++	DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *) data,
+ 				 sizeof(event));
+ 
+ 	event.count = savage_bci_emit_event(dev_priv, event.flags);
+ 	event.count |= dev_priv->event_wrap << 16;
+-	DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *)data)->count,
+-			       event.count, sizeof(event.count));
++	DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *) data)->
++			       count, event.count, sizeof(event.count));
+ 	return 0;
+ }
+ 
+@@ -963,7 +965,7 @@ static int savage_bci_event_wait(DRM_IOC
+ 
+ 	DRM_DEBUG("\n");
+ 
+-	DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *)data,
++	DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *) data,
+ 				 sizeof(event));
+ 
+ 	UPDATE_EVENT_COUNTER();
+@@ -973,7 +975,7 @@ static int savage_bci_event_wait(DRM_IOC
+ 		hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
+ 	hw_w = dev_priv->event_wrap;
+ 	if (hw_e > dev_priv->event_counter)
+-		hw_w--; /* hardware hasn't passed the last wrap yet */
++		hw_w--;		/* hardware hasn't passed the last wrap yet */
+ 
+ 	event_e = event.count & 0xffff;
+ 	event_w = event.count >> 16;
+@@ -982,7 +984,7 @@ static int savage_bci_event_wait(DRM_IOC
+ 	 * - event counter wrapped since the event was emitted or
+ 	 * - the hardware has advanced up to or over the event to wait for.
+ 	 */
+-	if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e) )
++	if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e))
+ 		return 0;
+ 	else
+ 		return dev_priv->wait_evnt(dev_priv, event_e);
+@@ -992,7 +994,8 @@ static int savage_bci_event_wait(DRM_IOC
+  * DMA buffer management
+  */
+ 
+-static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d)
++static int savage_bci_get_buffers(DRMFILE filp, drm_device_t * dev,
++				  drm_dma_t * d)
+ {
+ 	drm_buf_t *buf;
+ 	int i;
+@@ -1025,7 +1028,7 @@ int savage_bci_buffers(DRM_IOCTL_ARGS)
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *)data, sizeof(d));
++	DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *) data, sizeof(d));
+ 
+ 	/* Please don't send us buffers.
+ 	 */
+@@ -1049,12 +1052,13 @@ int savage_bci_buffers(DRM_IOCTL_ARGS)
+ 		ret = savage_bci_get_buffers(filp, dev, &d);
+ 	}
+ 
+-	DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *)data, d, sizeof(d));
++	DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *) data, d, sizeof(d));
+ 
+ 	return ret;
+ }
+ 
+-void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) {
++void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp)
++{
+ 	drm_device_dma_t *dma = dev->dma;
+ 	drm_savage_private_t *dev_priv = dev->dev_private;
+ 	int i;
+@@ -1066,7 +1070,7 @@ void savage_reclaim_buffers(drm_device_t
+ 	if (!dma->buflist)
+ 		return;
+ 
+-	/*i830_flush_queue(dev);*/
++	/*i830_flush_queue(dev); */
+ 
+ 	for (i = 0; i < dma->buf_count; i++) {
+ 		drm_buf_t *buf = dma->buflist[i];
+@@ -1085,7 +1089,6 @@ void savage_reclaim_buffers(drm_device_t
+ 	drm_core_reclaim_buffers(dev, filp);
+ }
+ 
+-
+ drm_ioctl_desc_t savage_ioctls[] = {
+ 	[DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1},
+ 	[DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0},
+diff --git a/drivers/char/drm/savage_drm.h b/drivers/char/drm/savage_drm.h
+--- a/drivers/char/drm/savage_drm.h
++++ b/drivers/char/drm/savage_drm.h
+@@ -42,12 +42,13 @@
+ #define SAVAGE_NR_TEX_REGIONS		16
+ #define SAVAGE_LOG_MIN_TEX_REGION_SIZE	16
+ 
+-#endif /* __SAVAGE_SAREA_DEFINES__ */
++#endif				/* __SAVAGE_SAREA_DEFINES__ */
+ 
+ typedef struct _drm_savage_sarea {
+ 	/* LRU lists for texture memory in agp space and on the card.
+ 	 */
+-	drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1];
++	drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS +
++						      1];
+ 	unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
+ 
+ 	/* Mechanism to validate card state.
+@@ -101,24 +102,24 @@ typedef struct drm_savage_init {
+ 
+ typedef union drm_savage_cmd_header drm_savage_cmd_header_t;
+ typedef struct drm_savage_cmdbuf {
+-				/* command buffer in client's address space */
++	/* command buffer in client's address space */
+ 	drm_savage_cmd_header_t __user *cmd_addr;
+ 	unsigned int size;	/* size of the command buffer in 64bit units */
+ 
+ 	unsigned int dma_idx;	/* DMA buffer index to use */
+ 	int discard;		/* discard DMA buffer when done */
+-				/* vertex buffer in client's address space */
++	/* vertex buffer in client's address space */
+ 	unsigned int __user *vb_addr;
+ 	unsigned int vb_size;	/* size of client vertex buffer in bytes */
+ 	unsigned int vb_stride;	/* stride of vertices in 32bit words */
+-				/* boxes in client's address space */
++	/* boxes in client's address space */
+ 	drm_clip_rect_t __user *box_addr;
+ 	unsigned int nbox;	/* number of clipping boxes */
+ } drm_savage_cmdbuf_t;
+ 
+-#define SAVAGE_WAIT_2D  0x1 /* wait for 2D idle before updating event tag */
+-#define SAVAGE_WAIT_3D  0x2 /* wait for 3D idle before updating event tag */
+-#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */
++#define SAVAGE_WAIT_2D  0x1	/* wait for 2D idle before updating event tag */
++#define SAVAGE_WAIT_3D  0x2	/* wait for 3D idle before updating event tag */
++#define SAVAGE_WAIT_IRQ 0x4	/* emit or wait for IRQ, not implemented yet */
+ typedef struct drm_savage_event {
+ 	unsigned int count;
+ 	unsigned int flags;
+@@ -126,21 +127,21 @@ typedef struct drm_savage_event {
+ 
+ /* Commands for the cmdbuf ioctl
+  */
+-#define SAVAGE_CMD_STATE	0  /* a range of state registers */
+-#define SAVAGE_CMD_DMA_PRIM	1  /* vertices from DMA buffer */
+-#define SAVAGE_CMD_VB_PRIM	2  /* vertices from client vertex buffer */
+-#define SAVAGE_CMD_DMA_IDX	3  /* indexed vertices from DMA buffer */
+-#define SAVAGE_CMD_VB_IDX	4  /* indexed vertices client vertex buffer */
+-#define SAVAGE_CMD_CLEAR	5  /* clear buffers */
+-#define SAVAGE_CMD_SWAP		6  /* swap buffers */
++#define SAVAGE_CMD_STATE	0	/* a range of state registers */
++#define SAVAGE_CMD_DMA_PRIM	1	/* vertices from DMA buffer */
++#define SAVAGE_CMD_VB_PRIM	2	/* vertices from client vertex buffer */
++#define SAVAGE_CMD_DMA_IDX	3	/* indexed vertices from DMA buffer */
++#define SAVAGE_CMD_VB_IDX	4	/* indexed vertices client vertex buffer */
++#define SAVAGE_CMD_CLEAR	5	/* clear buffers */
++#define SAVAGE_CMD_SWAP		6	/* swap buffers */
+ 
+ /* Primitive types
+ */
+-#define SAVAGE_PRIM_TRILIST	0  /* triangle list */
+-#define SAVAGE_PRIM_TRISTRIP	1  /* triangle strip */
+-#define SAVAGE_PRIM_TRIFAN	2  /* triangle fan */
+-#define SAVAGE_PRIM_TRILIST_201	3  /* reorder verts for correct flat
+-				    * shading on s3d */
++#define SAVAGE_PRIM_TRILIST	0	/* triangle list */
++#define SAVAGE_PRIM_TRISTRIP	1	/* triangle strip */
++#define SAVAGE_PRIM_TRIFAN	2	/* triangle fan */
++#define SAVAGE_PRIM_TRILIST_201	3	/* reorder verts for correct flat
++					 * shading on s3d */
+ 
+ /* Skip flags (vertex format)
+  */
+@@ -172,38 +173,38 @@ union drm_savage_cmd_header {
+ 		unsigned short pad1;
+ 		unsigned short pad2;
+ 		unsigned short pad3;
+-	} cmd; /* generic */
++	} cmd;			/* generic */
+ 	struct {
+ 		unsigned char cmd;
+ 		unsigned char global;	/* need idle engine? */
+ 		unsigned short count;	/* number of consecutive registers */
+ 		unsigned short start;	/* first register */
+ 		unsigned short pad3;
+-	} state; /* SAVAGE_CMD_STATE */
++	} state;		/* SAVAGE_CMD_STATE */
+ 	struct {
+ 		unsigned char cmd;
+ 		unsigned char prim;	/* primitive type */
+ 		unsigned short skip;	/* vertex format (skip flags) */
+ 		unsigned short count;	/* number of vertices */
+ 		unsigned short start;	/* first vertex in DMA/vertex buffer */
+-	} prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */
++	} prim;			/* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */
+ 	struct {
+ 		unsigned char cmd;
+ 		unsigned char prim;
+ 		unsigned short skip;
+ 		unsigned short count;	/* number of indices that follow */
+ 		unsigned short pad3;
+-	} idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */
++	} idx;			/* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */
+ 	struct {
+ 		unsigned char cmd;
+ 		unsigned char pad0;
+ 		unsigned short pad1;
+ 		unsigned int flags;
+-	} clear0; /* SAVAGE_CMD_CLEAR */
++	} clear0;		/* SAVAGE_CMD_CLEAR */
+ 	struct {
+ 		unsigned int mask;
+ 		unsigned int value;
+-	} clear1; /* SAVAGE_CMD_CLEAR data */
++	} clear1;		/* SAVAGE_CMD_CLEAR data */
+ };
+ 
+ #endif
+diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c
+--- a/drivers/char/drm/savage_drv.c
++++ b/drivers/char/drm/savage_drv.c
+@@ -30,30 +30,28 @@
+ 
+ #include "drm_pciids.h"
+ 
+-static int postinit( struct drm_device *dev, unsigned long flags )
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->primary.minor,
+-		pci_pretty_name(dev->pdev)
+-		);
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR,
++		 DRIVER_PATCHLEVEL,
++		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
++	    );
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+@@ -61,13 +59,9 @@ static struct pci_device_id pciidlist[] 
+ 	savage_PCI_IDS
+ };
+ 
+-extern drm_ioctl_desc_t savage_ioctls[];
+-extern int savage_max_ioctl;
+-
+ static struct drm_driver driver = {
+ 	.driver_features =
+-	    DRIVER_USE_AGP | DRIVER_USE_MTRR |
+-	    DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
++	    DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
+ 	.dev_priv_size = sizeof(drm_savage_buf_priv_t),
+ 	.preinit = savage_preinit,
+ 	.postinit = postinit,
+@@ -79,18 +73,19 @@ static struct drm_driver driver = {
+ 	.ioctls = savage_ioctls,
+ 	.dma_ioctl = savage_bci_buffers,
+ 	.fops = {
+-		.owner   = THIS_MODULE,
+-		.open	 = drm_open,
+-		.release = drm_release,
+-		.ioctl	 = drm_ioctl,
+-		.mmap	 = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync  = drm_fasync,
+-	},
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
++		 }
++	,
+ 	.pci_driver = {
+-		.name          = DRIVER_NAME,
+-		.id_table      = pciidlist,
+-	}
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
+ };
+ 
+ static int __init savage_init(void)
+@@ -107,6 +102,6 @@ static void __exit savage_exit(void)
+ module_init(savage_init);
+ module_exit(savage_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h
+--- a/drivers/char/drm/savage_drv.h
++++ b/drivers/char/drm/savage_drv.h
+@@ -65,7 +65,7 @@ typedef struct drm_savage_dma_page {
+ 	drm_savage_age_t age;
+ 	unsigned int used, flushed;
+ } drm_savage_dma_page_t;
+-#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */
++#define SAVAGE_DMA_PAGE_SIZE 1024	/* in dwords */
+ /* Fake DMA buffer size in bytes. 4 pages. Allows a maximum command
+  * size of 16kbytes or 4k entries. Minimum requirement would be
+  * 10kbytes for 255 40-byte vertices in one drawing command. */
+@@ -104,6 +104,9 @@ enum savage_family {
+ 	S3_LAST
+ };
+ 
++extern drm_ioctl_desc_t savage_ioctls[];
++extern int savage_max_ioctl;
++
+ #define S3_SAVAGE3D_SERIES(chip)  ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
+ 
+ #define S3_SAVAGE4_SERIES(chip)  ((chip==S3_SAVAGE4)            \
+@@ -184,13 +187,13 @@ typedef struct drm_savage_private {
+ 	unsigned int waiting;
+ 
+ 	/* config/hardware-dependent function pointers */
+-	int (*wait_fifo)(struct drm_savage_private *dev_priv, unsigned int n);
+-	int (*wait_evnt)(struct drm_savage_private *dev_priv, uint16_t e);
++	int (*wait_fifo) (struct drm_savage_private * dev_priv, unsigned int n);
++	int (*wait_evnt) (struct drm_savage_private * dev_priv, uint16_t e);
+ 	/* Err, there is a macro wait_event in include/linux/wait.h.
+ 	 * Avoid unwanted macro expansion. */
+-	void (*emit_clip_rect)(struct drm_savage_private *dev_priv,
+-			       drm_clip_rect_t *pbox);
+-	void (*dma_flush)(struct drm_savage_private *dev_priv);
++	void (*emit_clip_rect) (struct drm_savage_private * dev_priv,
++				drm_clip_rect_t * pbox);
++	void (*dma_flush) (struct drm_savage_private * dev_priv);
+ } drm_savage_private_t;
+ 
+ /* ioctls */
+@@ -198,23 +201,23 @@ extern int savage_bci_cmdbuf(DRM_IOCTL_A
+ extern int savage_bci_buffers(DRM_IOCTL_ARGS);
+ 
+ /* BCI functions */
+-extern uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
++extern uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv,
+ 				      unsigned int flags);
+-extern void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf);
+-extern void savage_dma_reset(drm_savage_private_t *dev_priv);
+-extern void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page);
+-extern uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv,
++extern void savage_freelist_put(drm_device_t * dev, drm_buf_t * buf);
++extern void savage_dma_reset(drm_savage_private_t * dev_priv);
++extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page);
++extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv,
+ 				  unsigned int n);
+-extern int savage_preinit(drm_device_t *dev, unsigned long chipset);
+-extern int savage_postcleanup(drm_device_t *dev);
+-extern int savage_do_cleanup_bci(drm_device_t *dev);
+-extern void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp);
++extern int savage_preinit(drm_device_t * dev, unsigned long chipset);
++extern int savage_postcleanup(drm_device_t * dev);
++extern int savage_do_cleanup_bci(drm_device_t * dev);
++extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp);
+ 
+ /* state functions */
+-extern void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
+-				      drm_clip_rect_t *pbox);
+-extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
+-				     drm_clip_rect_t *pbox);
++extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
++				      drm_clip_rect_t * pbox);
++extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
++				     drm_clip_rect_t * pbox);
+ 
+ #define SAVAGE_FB_SIZE_S3	0x01000000	/*  16MB */
+ #define SAVAGE_FB_SIZE_S4	0x02000000	/*  32MB */
+@@ -222,10 +225,10 @@ extern void savage_emit_clip_rect_s4(drm
+ #define SAVAGE_APERTURE_OFFSET  0x02000000	/*  32MB */
+ #define SAVAGE_APERTURE_SIZE    0x05000000	/* 5 tiled surfaces, 16MB each */
+ 
+-#define SAVAGE_BCI_OFFSET       0x00010000      /* offset of the BCI region
++#define SAVAGE_BCI_OFFSET       0x00010000	/* offset of the BCI region
+ 						 * inside the MMIO region */
+-#define SAVAGE_BCI_FIFO_SIZE	32		/* number of entries in on-chip
+-						 * BCI FIFO */
++#define SAVAGE_BCI_FIFO_SIZE	32	/* number of entries in on-chip
++					 * BCI FIFO */
+ 
+ /*
+  * MMIO registers
+@@ -278,7 +281,7 @@ extern void savage_emit_clip_rect_s4(drm
+ #define SAVAGE_TEXADDR1_S4		0x23
+ #define SAVAGE_TEXBLEND0_S4		0x24
+ #define SAVAGE_TEXBLEND1_S4		0x25
+-#define SAVAGE_TEXXPRCLR_S4		0x26 /* never used */
++#define SAVAGE_TEXXPRCLR_S4		0x26	/* never used */
+ #define SAVAGE_TEXDESCR_S4		0x27
+ #define SAVAGE_FOGTABLE_S4		0x28
+ #define SAVAGE_FOGCTRL_S4		0x30
+@@ -293,7 +296,7 @@ extern void savage_emit_clip_rect_s4(drm
+ #define SAVAGE_TEXBLENDCOLOR_S4		0x39
+ /* Savage3D/MX/IX 3D registers */
+ #define SAVAGE_TEXPALADDR_S3D		0x18
+-#define SAVAGE_TEXXPRCLR_S3D		0x19 /* never used */
++#define SAVAGE_TEXXPRCLR_S3D		0x19	/* never used */
+ #define SAVAGE_TEXADDR_S3D		0x1A
+ #define SAVAGE_TEXDESCR_S3D		0x1B
+ #define SAVAGE_TEXCTRL_S3D		0x1C
+@@ -305,7 +308,7 @@ extern void savage_emit_clip_rect_s4(drm
+ #define SAVAGE_DESTCTRL_S3D		0x34
+ #define SAVAGE_SCSTART_S3D		0x35
+ #define SAVAGE_SCEND_S3D		0x36
+-#define SAVAGE_ZWATERMARK_S3D		0x37 
++#define SAVAGE_ZWATERMARK_S3D		0x37
+ #define SAVAGE_DESTTEXRWWATERMARK_S3D	0x38
+ /* common stuff */
+ #define SAVAGE_VERTBUFADDR		0x3e
+@@ -313,9 +316,9 @@ extern void savage_emit_clip_rect_s4(drm
+ #define SAVAGE_DMABUFADDR		0x51
+ 
+ /* texture enable bits (needed for tex addr checking) */
+-#define SAVAGE_TEXCTRL_TEXEN_MASK	0x00010000 /* S3D */
+-#define SAVAGE_TEXDESCR_TEX0EN_MASK	0x02000000 /* S4 */
+-#define SAVAGE_TEXDESCR_TEX1EN_MASK	0x04000000 /* S4 */
++#define SAVAGE_TEXCTRL_TEXEN_MASK	0x00010000	/* S3D */
++#define SAVAGE_TEXDESCR_TEX0EN_MASK	0x02000000	/* S4 */
++#define SAVAGE_TEXDESCR_TEX1EN_MASK	0x04000000	/* S4 */
+ 
+ /* Global fields in Savage4/Twister/ProSavage 3D registers:
+  *
+@@ -576,4 +579,4 @@ extern void savage_emit_clip_rect_s4(drm
+ #define TEST_AGE( age, e, w )				\
+ 	( (age)->wrap < (w) || ( (age)->wrap == (w) && (age)->event <= (e) ) )
+ 
+-#endif /* __SAVAGE_DRV_H__ */
++#endif				/* __SAVAGE_DRV_H__ */
+diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c
+--- a/drivers/char/drm/savage_state.c
++++ b/drivers/char/drm/savage_state.c
+@@ -26,48 +26,48 @@
+ #include "savage_drm.h"
+ #include "savage_drv.h"
+ 
+-void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
+-			       drm_clip_rect_t *pbox)
++void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
++			       drm_clip_rect_t * pbox)
+ {
+ 	uint32_t scstart = dev_priv->state.s3d.new_scstart;
+-	uint32_t scend   = dev_priv->state.s3d.new_scend;
++	uint32_t scend = dev_priv->state.s3d.new_scend;
+ 	scstart = (scstart & ~SAVAGE_SCISSOR_MASK_S3D) |
+-		((uint32_t)pbox->x1 & 0x000007ff) | 
+-		(((uint32_t)pbox->y1 << 16) & 0x07ff0000);
+-	scend   = (scend   & ~SAVAGE_SCISSOR_MASK_S3D) |
+-		(((uint32_t)pbox->x2-1) & 0x000007ff) |
+-		((((uint32_t)pbox->y2-1) << 16) & 0x07ff0000);
++	    ((uint32_t) pbox->x1 & 0x000007ff) |
++	    (((uint32_t) pbox->y1 << 16) & 0x07ff0000);
++	scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) |
++	    (((uint32_t) pbox->x2 - 1) & 0x000007ff) |
++	    ((((uint32_t) pbox->y2 - 1) << 16) & 0x07ff0000);
+ 	if (scstart != dev_priv->state.s3d.scstart ||
+-	    scend   != dev_priv->state.s3d.scend) {
++	    scend != dev_priv->state.s3d.scend) {
+ 		DMA_LOCALS;
+ 		BEGIN_DMA(4);
+-		DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
++		DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
+ 		DMA_SET_REGISTERS(SAVAGE_SCSTART_S3D, 2);
+ 		DMA_WRITE(scstart);
+ 		DMA_WRITE(scend);
+ 		dev_priv->state.s3d.scstart = scstart;
+-		dev_priv->state.s3d.scend   = scend;
++		dev_priv->state.s3d.scend = scend;
+ 		dev_priv->waiting = 1;
+ 		DMA_COMMIT();
+ 	}
+ }
+ 
+-void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
+-			      drm_clip_rect_t *pbox)
++void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
++			      drm_clip_rect_t * pbox)
+ {
+ 	uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0;
+ 	uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1;
+ 	drawctrl0 = (drawctrl0 & ~SAVAGE_SCISSOR_MASK_S4) |
+-		((uint32_t)pbox->x1 & 0x000007ff) |
+-		(((uint32_t)pbox->y1 << 12) & 0x00fff000);
++	    ((uint32_t) pbox->x1 & 0x000007ff) |
++	    (((uint32_t) pbox->y1 << 12) & 0x00fff000);
+ 	drawctrl1 = (drawctrl1 & ~SAVAGE_SCISSOR_MASK_S4) |
+-		(((uint32_t)pbox->x2-1) & 0x000007ff) |
+-		((((uint32_t)pbox->y2-1) << 12) & 0x00fff000);
++	    (((uint32_t) pbox->x2 - 1) & 0x000007ff) |
++	    ((((uint32_t) pbox->y2 - 1) << 12) & 0x00fff000);
+ 	if (drawctrl0 != dev_priv->state.s4.drawctrl0 ||
+ 	    drawctrl1 != dev_priv->state.s4.drawctrl1) {
+ 		DMA_LOCALS;
+ 		BEGIN_DMA(4);
+-		DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
++		DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
+ 		DMA_SET_REGISTERS(SAVAGE_DRAWCTRL0_S4, 2);
+ 		DMA_WRITE(drawctrl0);
+ 		DMA_WRITE(drawctrl1);
+@@ -78,22 +78,23 @@ void savage_emit_clip_rect_s4(drm_savage
+ 	}
+ }
+ 
+-static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
++static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit,
+ 				 uint32_t addr)
+ {
+-	if ((addr & 6) != 2) { /* reserved bits */
++	if ((addr & 6) != 2) {	/* reserved bits */
+ 		DRM_ERROR("bad texAddr%d %08x (reserved bits)\n", unit, addr);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-	if (!(addr & 1)) { /* local */
++	if (!(addr & 1)) {	/* local */
+ 		addr &= ~7;
+-		if (addr <  dev_priv->texture_offset ||
+-		    addr >= dev_priv->texture_offset+dev_priv->texture_size) {
+-			DRM_ERROR("bad texAddr%d %08x (local addr out of range)\n",
+-				  unit, addr);
++		if (addr < dev_priv->texture_offset ||
++		    addr >= dev_priv->texture_offset + dev_priv->texture_size) {
++			DRM_ERROR
++			    ("bad texAddr%d %08x (local addr out of range)\n",
++			     unit, addr);
+ 			return DRM_ERR(EINVAL);
+ 		}
+-	} else { /* AGP */
++	} else {		/* AGP */
+ 		if (!dev_priv->agp_textures) {
+ 			DRM_ERROR("bad texAddr%d %08x (AGP not available)\n",
+ 				  unit, addr);
+@@ -103,8 +104,9 @@ static int savage_verify_texaddr(drm_sav
+ 		if (addr < dev_priv->agp_textures->offset ||
+ 		    addr >= (dev_priv->agp_textures->offset +
+ 			     dev_priv->agp_textures->size)) {
+-			DRM_ERROR("bad texAddr%d %08x (AGP addr out of range)\n",
+-				  unit, addr);
++			DRM_ERROR
++			    ("bad texAddr%d %08x (AGP addr out of range)\n",
++			     unit, addr);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 	}
+@@ -122,14 +124,14 @@ static int savage_verify_texaddr(drm_sav
+ 			(dev_priv->state.where & ~(mask));	\
+ 	}							\
+ } while (0)
+-static int savage_verify_state_s3d(drm_savage_private_t *dev_priv,
++static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
+ 				   unsigned int start, unsigned int count,
+-				   const uint32_t __user *regs)
++				   const uint32_t __user * regs)
+ {
+ 	if (start < SAVAGE_TEXPALADDR_S3D ||
+-	    start+count-1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
++	    start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
+ 		DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
+-			  start, start+count-1);
++			  start, start + count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -140,28 +142,29 @@ static int savage_verify_state_s3d(drm_s
+ 
+ 	/* if any texture regs were changed ... */
+ 	if (start <= SAVAGE_TEXCTRL_S3D &&
+-	    start+count > SAVAGE_TEXPALADDR_S3D) {
++	    start + count > SAVAGE_TEXPALADDR_S3D) {
+ 		/* ... check texture state */
+ 		SAVE_STATE(SAVAGE_TEXCTRL_S3D, s3d.texctrl);
+ 		SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr);
+ 		if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK)
+-			return savage_verify_texaddr(
+-				dev_priv, 0, dev_priv->state.s3d.texaddr);
++			return savage_verify_texaddr(dev_priv, 0,
++						     dev_priv->state.s3d.
++						     texaddr);
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-static int savage_verify_state_s4(drm_savage_private_t *dev_priv,
++static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
+ 				  unsigned int start, unsigned int count,
+-				  const uint32_t __user *regs)
++				  const uint32_t __user * regs)
+ {
+ 	int ret = 0;
+ 
+ 	if (start < SAVAGE_DRAWLOCALCTRL_S4 ||
+-	    start+count-1 > SAVAGE_TEXBLENDCOLOR_S4) {
++	    start + count - 1 > SAVAGE_TEXBLENDCOLOR_S4) {
+ 		DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
+-			  start, start+count-1);
++			  start, start + count - 1);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -171,28 +174,30 @@ static int savage_verify_state_s4(drm_sa
+ 			~SAVAGE_SCISSOR_MASK_S4);
+ 
+ 	/* if any texture regs were changed ... */
+-	if (start <= SAVAGE_TEXDESCR_S4 &&
+-	    start+count > SAVAGE_TEXPALADDR_S4) {
++	if (start <= SAVAGE_TEXDESCR_S4 && start + count > SAVAGE_TEXPALADDR_S4) {
+ 		/* ... check texture state */
+ 		SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr);
+ 		SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0);
+ 		SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1);
+ 		if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK)
+-			ret |= savage_verify_texaddr(
+-				dev_priv, 0, dev_priv->state.s4.texaddr0);
++			ret |=
++			    savage_verify_texaddr(dev_priv, 0,
++						  dev_priv->state.s4.texaddr0);
+ 		if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK)
+-			ret |= savage_verify_texaddr(
+-				dev_priv, 1, dev_priv->state.s4.texaddr1);
++			ret |=
++			    savage_verify_texaddr(dev_priv, 1,
++						  dev_priv->state.s4.texaddr1);
+ 	}
+ 
+ 	return ret;
+ }
++
+ #undef SAVE_STATE
+ #undef SAVE_STATE_MASK
+ 
+-static int savage_dispatch_state(drm_savage_private_t *dev_priv,
+-				 const drm_savage_cmd_header_t *cmd_header,
+-				 const uint32_t __user *regs)
++static int savage_dispatch_state(drm_savage_private_t * dev_priv,
++				 const drm_savage_cmd_header_t * cmd_header,
++				 const uint32_t __user * regs)
+ {
+ 	unsigned int count = cmd_header->state.count;
+ 	unsigned int start = cmd_header->state.start;
+@@ -204,7 +209,7 @@ static int savage_dispatch_state(drm_sav
+ 	if (!count)
+ 		return 0;
+ 
+-	if (DRM_VERIFYAREA_READ(regs, count*4))
++	if (DRM_VERIFYAREA_READ(regs, count * 4))
+ 		return DRM_ERR(EFAULT);
+ 
+ 	if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
+@@ -213,14 +218,14 @@ static int savage_dispatch_state(drm_sav
+ 			return ret;
+ 		/* scissor regs are emitted in savage_dispatch_draw */
+ 		if (start < SAVAGE_SCSTART_S3D) {
+-			if (start+count > SAVAGE_SCEND_S3D+1)
+-				count2 = count - (SAVAGE_SCEND_S3D+1 - start);
+-			if (start+count > SAVAGE_SCSTART_S3D)
++			if (start + count > SAVAGE_SCEND_S3D + 1)
++				count2 = count - (SAVAGE_SCEND_S3D + 1 - start);
++			if (start + count > SAVAGE_SCSTART_S3D)
+ 				count = SAVAGE_SCSTART_S3D - start;
+ 		} else if (start <= SAVAGE_SCEND_S3D) {
+-			if (start+count > SAVAGE_SCEND_S3D+1) {
+-				count -= SAVAGE_SCEND_S3D+1 - start;
+-				start = SAVAGE_SCEND_S3D+1;
++			if (start + count > SAVAGE_SCEND_S3D + 1) {
++				count -= SAVAGE_SCEND_S3D + 1 - start;
++				start = SAVAGE_SCEND_S3D + 1;
+ 			} else
+ 				return 0;
+ 		}
+@@ -230,23 +235,24 @@ static int savage_dispatch_state(drm_sav
+ 			return ret;
+ 		/* scissor regs are emitted in savage_dispatch_draw */
+ 		if (start < SAVAGE_DRAWCTRL0_S4) {
+-			if (start+count > SAVAGE_DRAWCTRL1_S4+1)
+-				count2 = count - (SAVAGE_DRAWCTRL1_S4+1 - start);
+-			if (start+count > SAVAGE_DRAWCTRL0_S4)
++			if (start + count > SAVAGE_DRAWCTRL1_S4 + 1)
++				count2 =
++				    count - (SAVAGE_DRAWCTRL1_S4 + 1 - start);
++			if (start + count > SAVAGE_DRAWCTRL0_S4)
+ 				count = SAVAGE_DRAWCTRL0_S4 - start;
+ 		} else if (start <= SAVAGE_DRAWCTRL1_S4) {
+-			if (start+count > SAVAGE_DRAWCTRL1_S4+1) {
+-				count -= SAVAGE_DRAWCTRL1_S4+1 - start;
+-				start = SAVAGE_DRAWCTRL1_S4+1;
++			if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) {
++				count -= SAVAGE_DRAWCTRL1_S4 + 1 - start;
++				start = SAVAGE_DRAWCTRL1_S4 + 1;
+ 			} else
+ 				return 0;
+ 		}
+ 	}
+ 
+-	bci_size = count + (count+254)/255 + count2 + (count2+254)/255;
++	bci_size = count + (count + 254) / 255 + count2 + (count2 + 254) / 255;
+ 
+ 	if (cmd_header->state.global) {
+-		BEGIN_DMA(bci_size+1);
++		BEGIN_DMA(bci_size + 1);
+ 		DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
+ 		dev_priv->waiting = 1;
+ 	} else {
+@@ -273,9 +279,9 @@ static int savage_dispatch_state(drm_sav
+ 	return 0;
+ }
+ 
+-static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
+-				    const drm_savage_cmd_header_t *cmd_header,
+-				    const drm_buf_t *dmabuf)
++static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv,
++				    const drm_savage_cmd_header_t * cmd_header,
++				    const drm_buf_t * dmabuf)
+ {
+ 	unsigned char reorder = 0;
+ 	unsigned int prim = cmd_header->prim.prim;
+@@ -286,8 +292,8 @@ static int savage_dispatch_dma_prim(drm_
+ 	BCI_LOCALS;
+ 
+ 	if (!dmabuf) {
+-	    DRM_ERROR("called without dma buffers!\n");
+-	    return DRM_ERR(EINVAL);
++		DRM_ERROR("called without dma buffers!\n");
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	if (!n)
+@@ -307,8 +313,9 @@ static int savage_dispatch_dma_prim(drm_
+ 	case SAVAGE_PRIM_TRISTRIP:
+ 	case SAVAGE_PRIM_TRIFAN:
+ 		if (n < 3) {
+-			DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n",
+-				  n);
++			DRM_ERROR
++			    ("wrong number of vertices %u in TRIFAN/STRIP\n",
++			     n);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+@@ -319,17 +326,15 @@ static int savage_dispatch_dma_prim(drm_
+ 
+ 	if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
+ 		if (skip != 0) {
+-			DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
+-				  skip);
++			DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 	} else {
+ 		unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
+-			(skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
+-			(skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
++		    (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
++		    (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
+ 		if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
+-			DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
+-				  skip);
++			DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		if (reorder) {
+@@ -338,9 +343,9 @@ static int savage_dispatch_dma_prim(drm_
+ 		}
+ 	}
+ 
+-	if (start + n > dmabuf->total/32) {
++	if (start + n > dmabuf->total / 32) {
+ 		DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
+-			  start, start + n - 1, dmabuf->total/32);
++			  start, start + n - 1, dmabuf->total / 32);
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -375,32 +380,33 @@ static int savage_dispatch_dma_prim(drm_
+ 			/* Need to reorder indices for correct flat
+ 			 * shading while preserving the clock sense
+ 			 * for correct culling. Only on Savage3D. */
+-			int reorder[3] = {-1, -1, -1};
+-			reorder[start%3] = 2;
++			int reorder[3] = { -1, -1, -1 };
++			reorder[start % 3] = 2;
+ 
+-			BEGIN_BCI((count+1+1)/2);
+-			BCI_DRAW_INDICES_S3D(count, prim, start+2);
++			BEGIN_BCI((count + 1 + 1) / 2);
++			BCI_DRAW_INDICES_S3D(count, prim, start + 2);
+ 
+-			for (i = start+1; i+1 < start+count; i += 2)
++			for (i = start + 1; i + 1 < start + count; i += 2)
+ 				BCI_WRITE((i + reorder[i % 3]) |
+-					  ((i+1 + reorder[(i+1) % 3]) << 16));
+-			if (i < start+count)
+-				BCI_WRITE(i + reorder[i%3]);
++					  ((i + 1 +
++					    reorder[(i + 1) % 3]) << 16));
++			if (i < start + count)
++				BCI_WRITE(i + reorder[i % 3]);
+ 		} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
+-			BEGIN_BCI((count+1+1)/2);
++			BEGIN_BCI((count + 1 + 1) / 2);
+ 			BCI_DRAW_INDICES_S3D(count, prim, start);
+ 
+-			for (i = start+1; i+1 < start+count; i += 2)
+-				BCI_WRITE(i | ((i+1) << 16));
+-			if (i < start+count)
++			for (i = start + 1; i + 1 < start + count; i += 2)
++				BCI_WRITE(i | ((i + 1) << 16));
++			if (i < start + count)
+ 				BCI_WRITE(i);
+ 		} else {
+-			BEGIN_BCI((count+2+1)/2);
++			BEGIN_BCI((count + 2 + 1) / 2);
+ 			BCI_DRAW_INDICES_S4(count, prim, skip);
+ 
+-			for (i = start; i+1 < start+count; i += 2)
+-				BCI_WRITE(i | ((i+1) << 16));
+-			if (i < start+count)
++			for (i = start; i + 1 < start + count; i += 2)
++				BCI_WRITE(i | ((i + 1) << 16));
++			if (i < start + count)
+ 				BCI_WRITE(i);
+ 		}
+ 
+@@ -413,11 +419,10 @@ static int savage_dispatch_dma_prim(drm_
+ 	return 0;
+ }
+ 
+-static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
+-				   const drm_savage_cmd_header_t *cmd_header,
+-				   const uint32_t __user *vtxbuf,
+-				   unsigned int vb_size,
+-				   unsigned int vb_stride)
++static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
++				   const drm_savage_cmd_header_t * cmd_header,
++				   const uint32_t __user * vtxbuf,
++				   unsigned int vb_size, unsigned int vb_stride)
+ {
+ 	unsigned char reorder = 0;
+ 	unsigned int prim = cmd_header->prim.prim;
+@@ -445,8 +450,9 @@ static int savage_dispatch_vb_prim(drm_s
+ 	case SAVAGE_PRIM_TRISTRIP:
+ 	case SAVAGE_PRIM_TRIFAN:
+ 		if (n < 3) {
+-			DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n",
+-				  n);
++			DRM_ERROR
++			    ("wrong number of vertices %u in TRIFAN/STRIP\n",
++			     n);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+@@ -460,18 +466,18 @@ static int savage_dispatch_vb_prim(drm_s
+ 			DRM_ERROR("invalid skip flags 0x%04x\n", skip);
+ 			return DRM_ERR(EINVAL);
+ 		}
+-		vtx_size = 8; /* full vertex */
++		vtx_size = 8;	/* full vertex */
+ 	} else {
+ 		if (skip > SAVAGE_SKIP_ALL_S4) {
+ 			DRM_ERROR("invalid skip flags 0x%04x\n", skip);
+ 			return DRM_ERR(EINVAL);
+ 		}
+-		vtx_size = 10; /* full vertex */
++		vtx_size = 10;	/* full vertex */
+ 	}
+ 
+ 	vtx_size -= (skip & 1) + (skip >> 1 & 1) +
+-		(skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
+-		(skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
++	    (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
++	    (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
+ 
+ 	if (vtx_size > vb_stride) {
+ 		DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
+@@ -479,9 +485,9 @@ static int savage_dispatch_vb_prim(drm_s
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if (start + n > vb_size / (vb_stride*4)) {
++	if (start + n > vb_size / (vb_stride * 4)) {
+ 		DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
+-			  start, start + n - 1, vb_size / (vb_stride*4));
++			  start, start + n - 1, vb_size / (vb_stride * 4));
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+@@ -493,31 +499,31 @@ static int savage_dispatch_vb_prim(drm_s
+ 			/* Need to reorder vertices for correct flat
+ 			 * shading while preserving the clock sense
+ 			 * for correct culling. Only on Savage3D. */
+-			int reorder[3] = {-1, -1, -1};
+-			reorder[start%3] = 2;
++			int reorder[3] = { -1, -1, -1 };
++			reorder[start % 3] = 2;
+ 
+-			BEGIN_DMA(count*vtx_size+1);
++			BEGIN_DMA(count * vtx_size + 1);
+ 			DMA_DRAW_PRIMITIVE(count, prim, skip);
+ 
+-			for (i = start; i < start+count; ++i) {
++			for (i = start; i < start + count; ++i) {
+ 				unsigned int j = i + reorder[i % 3];
+-				DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
++				DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
+ 						   vtx_size);
+ 			}
+ 
+ 			DMA_COMMIT();
+ 		} else {
+-			BEGIN_DMA(count*vtx_size+1);
++			BEGIN_DMA(count * vtx_size + 1);
+ 			DMA_DRAW_PRIMITIVE(count, prim, skip);
+ 
+ 			if (vb_stride == vtx_size) {
+-				DMA_COPY_FROM_USER(&vtxbuf[vb_stride*start],
+-						   vtx_size*count);
++				DMA_COPY_FROM_USER(&vtxbuf[vb_stride * start],
++						   vtx_size * count);
+ 			} else {
+-				for (i = start; i < start+count; ++i) {
+-					DMA_COPY_FROM_USER(
+-						&vtxbuf[vb_stride*i],
+-						vtx_size);
++				for (i = start; i < start + count; ++i) {
++					DMA_COPY_FROM_USER(&vtxbuf
++							   [vb_stride * i],
++							   vtx_size);
+ 				}
+ 			}
+ 
+@@ -533,10 +539,10 @@ static int savage_dispatch_vb_prim(drm_s
+ 	return 0;
+ }
+ 
+-static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
+-				   const drm_savage_cmd_header_t *cmd_header,
+-				   const uint16_t __user *usr_idx,
+-				   const drm_buf_t *dmabuf)
++static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
++				   const drm_savage_cmd_header_t * cmd_header,
++				   const uint16_t __user * usr_idx,
++				   const drm_buf_t * dmabuf)
+ {
+ 	unsigned char reorder = 0;
+ 	unsigned int prim = cmd_header->idx.prim;
+@@ -546,8 +552,8 @@ static int savage_dispatch_dma_idx(drm_s
+ 	BCI_LOCALS;
+ 
+ 	if (!dmabuf) {
+-	    DRM_ERROR("called without dma buffers!\n");
+-	    return DRM_ERR(EINVAL);
++		DRM_ERROR("called without dma buffers!\n");
++		return DRM_ERR(EINVAL);
+ 	}
+ 
+ 	if (!n)
+@@ -559,16 +565,15 @@ static int savage_dispatch_dma_idx(drm_s
+ 		prim = SAVAGE_PRIM_TRILIST;
+ 	case SAVAGE_PRIM_TRILIST:
+ 		if (n % 3 != 0) {
+-			DRM_ERROR("wrong number of indices %u in TRILIST\n",
+-				  n);
++			DRM_ERROR("wrong number of indices %u in TRILIST\n", n);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+ 	case SAVAGE_PRIM_TRISTRIP:
+ 	case SAVAGE_PRIM_TRIFAN:
+ 		if (n < 3) {
+-			DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n",
+-				  n);
++			DRM_ERROR
++			    ("wrong number of indices %u in TRIFAN/STRIP\n", n);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+@@ -579,17 +584,15 @@ static int savage_dispatch_dma_idx(drm_s
+ 
+ 	if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
+ 		if (skip != 0) {
+-			DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
+-				  skip);
++			DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 	} else {
+ 		unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
+-			(skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
+-			(skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
++		    (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
++		    (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
+ 		if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
+-			DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
+-				  skip);
++			DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		if (reorder) {
+@@ -629,11 +632,11 @@ static int savage_dispatch_dma_idx(drm_s
+ 		uint16_t idx[255];
+ 
+ 		/* Copy and check indices */
+-		DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2);
++		DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
+ 		for (i = 0; i < count; ++i) {
+-			if (idx[i] > dmabuf->total/32) {
++			if (idx[i] > dmabuf->total / 32) {
+ 				DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
+-					  i, idx[i], dmabuf->total/32);
++					  i, idx[i], dmabuf->total / 32);
+ 				return DRM_ERR(EINVAL);
+ 			}
+ 		}
+@@ -642,30 +645,31 @@ static int savage_dispatch_dma_idx(drm_s
+ 			/* Need to reorder indices for correct flat
+ 			 * shading while preserving the clock sense
+ 			 * for correct culling. Only on Savage3D. */
+-			int reorder[3] = {2, -1, -1};
++			int reorder[3] = { 2, -1, -1 };
+ 
+-			BEGIN_BCI((count+1+1)/2);
++			BEGIN_BCI((count + 1 + 1) / 2);
+ 			BCI_DRAW_INDICES_S3D(count, prim, idx[2]);
+ 
+-			for (i = 1; i+1 < count; i += 2)
++			for (i = 1; i + 1 < count; i += 2)
+ 				BCI_WRITE(idx[i + reorder[i % 3]] |
+-					  (idx[i+1 + reorder[(i+1) % 3]] << 16));
++					  (idx[i + 1 + reorder[(i + 1) % 3]] <<
++					   16));
+ 			if (i < count)
+-				BCI_WRITE(idx[i + reorder[i%3]]);
++				BCI_WRITE(idx[i + reorder[i % 3]]);
+ 		} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
+-			BEGIN_BCI((count+1+1)/2);
++			BEGIN_BCI((count + 1 + 1) / 2);
+ 			BCI_DRAW_INDICES_S3D(count, prim, idx[0]);
+ 
+-			for (i = 1; i+1 < count; i += 2)
+-				BCI_WRITE(idx[i] | (idx[i+1] << 16));
++			for (i = 1; i + 1 < count; i += 2)
++				BCI_WRITE(idx[i] | (idx[i + 1] << 16));
+ 			if (i < count)
+ 				BCI_WRITE(idx[i]);
+ 		} else {
+-			BEGIN_BCI((count+2+1)/2);
++			BEGIN_BCI((count + 2 + 1) / 2);
+ 			BCI_DRAW_INDICES_S4(count, prim, skip);
+ 
+-			for (i = 0; i+1 < count; i += 2)
+-				BCI_WRITE(idx[i] | (idx[i+1] << 16));
++			for (i = 0; i + 1 < count; i += 2)
++				BCI_WRITE(idx[i] | (idx[i + 1] << 16));
+ 			if (i < count)
+ 				BCI_WRITE(idx[i]);
+ 		}
+@@ -679,12 +683,11 @@ static int savage_dispatch_dma_idx(drm_s
+ 	return 0;
+ }
+ 
+-static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
+-				  const drm_savage_cmd_header_t *cmd_header,
+-				  const uint16_t __user *usr_idx,
+-				  const uint32_t __user *vtxbuf,
+-				  unsigned int vb_size,
+-				  unsigned int vb_stride)
++static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
++				  const drm_savage_cmd_header_t * cmd_header,
++				  const uint16_t __user * usr_idx,
++				  const uint32_t __user * vtxbuf,
++				  unsigned int vb_size, unsigned int vb_stride)
+ {
+ 	unsigned char reorder = 0;
+ 	unsigned int prim = cmd_header->idx.prim;
+@@ -703,16 +706,15 @@ static int savage_dispatch_vb_idx(drm_sa
+ 		prim = SAVAGE_PRIM_TRILIST;
+ 	case SAVAGE_PRIM_TRILIST:
+ 		if (n % 3 != 0) {
+-			DRM_ERROR("wrong number of indices %u in TRILIST\n",
+-				  n);
++			DRM_ERROR("wrong number of indices %u in TRILIST\n", n);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+ 	case SAVAGE_PRIM_TRISTRIP:
+ 	case SAVAGE_PRIM_TRIFAN:
+ 		if (n < 3) {
+-			DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n",
+-				  n);
++			DRM_ERROR
++			    ("wrong number of indices %u in TRIFAN/STRIP\n", n);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		break;
+@@ -726,18 +728,18 @@ static int savage_dispatch_vb_idx(drm_sa
+ 			DRM_ERROR("invalid skip flags 0x%04x\n", skip);
+ 			return DRM_ERR(EINVAL);
+ 		}
+-		vtx_size = 8; /* full vertex */
++		vtx_size = 8;	/* full vertex */
+ 	} else {
+ 		if (skip > SAVAGE_SKIP_ALL_S4) {
+ 			DRM_ERROR("invalid skip flags 0x%04x\n", skip);
+ 			return DRM_ERR(EINVAL);
+ 		}
+-		vtx_size = 10; /* full vertex */
++		vtx_size = 10;	/* full vertex */
+ 	}
+ 
+ 	vtx_size -= (skip & 1) + (skip >> 1 & 1) +
+-		(skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
+-		(skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
++	    (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
++	    (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
+ 
+ 	if (vtx_size > vb_stride) {
+ 		DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
+@@ -753,11 +755,11 @@ static int savage_dispatch_vb_idx(drm_sa
+ 		uint16_t idx[255];
+ 
+ 		/* Copy and check indices */
+-		DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2);
++		DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
+ 		for (i = 0; i < count; ++i) {
+-			if (idx[i] > vb_size / (vb_stride*4)) {
++			if (idx[i] > vb_size / (vb_stride * 4)) {
+ 				DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
+-					  i, idx[i],  vb_size / (vb_stride*4));
++					  i, idx[i], vb_size / (vb_stride * 4));
+ 				return DRM_ERR(EINVAL);
+ 			}
+ 		}
+@@ -766,25 +768,25 @@ static int savage_dispatch_vb_idx(drm_sa
+ 			/* Need to reorder vertices for correct flat
+ 			 * shading while preserving the clock sense
+ 			 * for correct culling. Only on Savage3D. */
+-			int reorder[3] = {2, -1, -1};
++			int reorder[3] = { 2, -1, -1 };
+ 
+-			BEGIN_DMA(count*vtx_size+1);
++			BEGIN_DMA(count * vtx_size + 1);
+ 			DMA_DRAW_PRIMITIVE(count, prim, skip);
+ 
+ 			for (i = 0; i < count; ++i) {
+ 				unsigned int j = idx[i + reorder[i % 3]];
+-				DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
++				DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
+ 						   vtx_size);
+ 			}
+ 
+ 			DMA_COMMIT();
+ 		} else {
+-			BEGIN_DMA(count*vtx_size+1);
++			BEGIN_DMA(count * vtx_size + 1);
+ 			DMA_DRAW_PRIMITIVE(count, prim, skip);
+ 
+ 			for (i = 0; i < count; ++i) {
+ 				unsigned int j = idx[i];
+-				DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
++				DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
+ 						   vtx_size);
+ 			}
+ 
+@@ -800,11 +802,11 @@ static int savage_dispatch_vb_idx(drm_sa
+ 	return 0;
+ }
+ 
+-static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
+-				 const drm_savage_cmd_header_t *cmd_header,
+-				 const drm_savage_cmd_header_t __user *data,
++static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
++				 const drm_savage_cmd_header_t * cmd_header,
++				 const drm_savage_cmd_header_t __user * data,
+ 				 unsigned int nbox,
+-				 const drm_clip_rect_t __user *usr_boxes)
++				 const drm_clip_rect_t __user * usr_boxes)
+ {
+ 	unsigned int flags = cmd_header->clear0.flags, mask, value;
+ 	unsigned int clear_cmd;
+@@ -814,18 +816,15 @@ static int savage_dispatch_clear(drm_sav
+ 	if (nbox == 0)
+ 		return 0;
+ 
+-	DRM_GET_USER_UNCHECKED(mask, &((const drm_savage_cmd_header_t*)data)
+-			       ->clear1.mask);
+-	DRM_GET_USER_UNCHECKED(value, &((const drm_savage_cmd_header_t*)data)
+-			       ->clear1.value);
++	DRM_GET_USER_UNCHECKED(mask, &data->clear1.mask);
++	DRM_GET_USER_UNCHECKED(value, &data->clear1.value);
+ 
+ 	clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
+-		BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
+-	BCI_CMD_SET_ROP(clear_cmd,0xCC);
++	    BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
++	BCI_CMD_SET_ROP(clear_cmd, 0xCC);
+ 
+ 	nbufs = ((flags & SAVAGE_FRONT) ? 1 : 0) +
+-		((flags & SAVAGE_BACK) ? 1 : 0) +
+-		((flags & SAVAGE_DEPTH) ? 1 : 0);
++	    ((flags & SAVAGE_BACK) ? 1 : 0) + ((flags & SAVAGE_DEPTH) ? 1 : 0);
+ 	if (nbufs == 0)
+ 		return 0;
+ 
+@@ -844,12 +843,12 @@ static int savage_dispatch_clear(drm_sav
+ 		x = box.x1, y = box.y1;
+ 		w = box.x2 - box.x1;
+ 		h = box.y2 - box.y1;
+-		BEGIN_DMA(nbufs*6);
++		BEGIN_DMA(nbufs * 6);
+ 		for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) {
+ 			if (!(flags & buf))
+ 				continue;
+ 			DMA_WRITE(clear_cmd);
+-			switch(buf) {
++			switch (buf) {
+ 			case SAVAGE_FRONT:
+ 				DMA_WRITE(dev_priv->front_offset);
+ 				DMA_WRITE(dev_priv->front_bd);
+@@ -880,9 +879,9 @@ static int savage_dispatch_clear(drm_sav
+ 	return 0;
+ }
+ 
+-static int savage_dispatch_swap(drm_savage_private_t *dev_priv,
++static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
+ 				unsigned int nbox,
+-				const drm_clip_rect_t __user *usr_boxes)
++				const drm_clip_rect_t __user * usr_boxes)
+ {
+ 	unsigned int swap_cmd;
+ 	unsigned int i;
+@@ -892,8 +891,8 @@ static int savage_dispatch_swap(drm_sava
+ 		return 0;
+ 
+ 	swap_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
+-		BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD;
+-	BCI_CMD_SET_ROP(swap_cmd,0xCC);
++	    BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD;
++	BCI_CMD_SET_ROP(swap_cmd, 0xCC);
+ 
+ 	for (i = 0; i < nbox; ++i) {
+ 		drm_clip_rect_t box;
+@@ -905,21 +904,21 @@ static int savage_dispatch_swap(drm_sava
+ 		DMA_WRITE(dev_priv->back_bd);
+ 		DMA_WRITE(BCI_X_Y(box.x1, box.y1));
+ 		DMA_WRITE(BCI_X_Y(box.x1, box.y1));
+-		DMA_WRITE(BCI_W_H(box.x2-box.x1, box.y2-box.y1));
++		DMA_WRITE(BCI_W_H(box.x2 - box.x1, box.y2 - box.y1));
+ 		DMA_COMMIT();
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-static int savage_dispatch_draw(drm_savage_private_t *dev_priv,
+-				const drm_savage_cmd_header_t __user *start,
+-				const drm_savage_cmd_header_t __user *end,
+-				const drm_buf_t *dmabuf,
+-				const unsigned int __user *usr_vtxbuf,
++static int savage_dispatch_draw(drm_savage_private_t * dev_priv,
++				const drm_savage_cmd_header_t __user * start,
++				const drm_savage_cmd_header_t __user * end,
++				const drm_buf_t * dmabuf,
++				const unsigned int __user * usr_vtxbuf,
+ 				unsigned int vb_size, unsigned int vb_stride,
+ 				unsigned int nbox,
+-				const drm_clip_rect_t __user *usr_boxes)
++				const drm_clip_rect_t __user * usr_boxes)
+ {
+ 	unsigned int i, j;
+ 	int ret;
+@@ -938,32 +937,42 @@ static int savage_dispatch_draw(drm_sava
+ 			usr_cmdbuf++;
+ 			switch (cmd_header.cmd.cmd) {
+ 			case SAVAGE_CMD_DMA_PRIM:
+-				ret = savage_dispatch_dma_prim(
+-					dev_priv, &cmd_header, dmabuf);
++				ret =
++				    savage_dispatch_dma_prim(dev_priv,
++							     &cmd_header,
++							     dmabuf);
+ 				break;
+ 			case SAVAGE_CMD_VB_PRIM:
+-				ret = savage_dispatch_vb_prim(
+-					dev_priv, &cmd_header,
+-					(const uint32_t __user *)usr_vtxbuf,
+-					vb_size, vb_stride);
++				ret =
++				    savage_dispatch_vb_prim(dev_priv,
++							    &cmd_header,
++							    (const uint32_t
++							     __user *)
++							    usr_vtxbuf, vb_size,
++							    vb_stride);
+ 				break;
+ 			case SAVAGE_CMD_DMA_IDX:
+ 				j = (cmd_header.idx.count + 3) / 4;
+ 				/* j was check in savage_bci_cmdbuf */
+-				ret = savage_dispatch_dma_idx(
+-					dev_priv, &cmd_header,
+-					(const uint16_t __user *)usr_cmdbuf,
+-					dmabuf);
++				ret =
++				    savage_dispatch_dma_idx(dev_priv,
++							    &cmd_header,
++							    (const uint16_t
++							     __user *)
++							    usr_cmdbuf, dmabuf);
+ 				usr_cmdbuf += j;
+ 				break;
+ 			case SAVAGE_CMD_VB_IDX:
+ 				j = (cmd_header.idx.count + 3) / 4;
+ 				/* j was check in savage_bci_cmdbuf */
+-				ret = savage_dispatch_vb_idx(
+-					dev_priv, &cmd_header,
+-					(const uint16_t __user *)usr_cmdbuf,
+-					(const uint32_t __user *)usr_vtxbuf,
+-					vb_size, vb_stride);
++				ret =
++				    savage_dispatch_vb_idx(dev_priv,
++							   &cmd_header,
++							   (const uint16_t
++							    __user *)usr_cmdbuf,
++							   (const uint32_t
++							    __user *)usr_vtxbuf,
++							   vb_size, vb_stride);
+ 				usr_cmdbuf += j;
+ 				break;
+ 			default:
+@@ -997,16 +1006,17 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
+ 	int ret = 0;
+ 
+ 	DRM_DEBUG("\n");
+-	
++
+ 	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+-	DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *)data,
++	DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *) data,
+ 				 sizeof(cmdbuf));
+ 
+ 	if (dma && dma->buflist) {
+ 		if (cmdbuf.dma_idx > dma->buf_count) {
+-			DRM_ERROR("vertex buffer index %u out of range (0-%u)\n",
+-				  cmdbuf.dma_idx, dma->buf_count-1);
++			DRM_ERROR
++			    ("vertex buffer index %u out of range (0-%u)\n",
++			     cmdbuf.dma_idx, dma->buf_count - 1);
+ 			return DRM_ERR(EINVAL);
+ 		}
+ 		dmabuf = dma->buflist[cmdbuf.dma_idx];
+@@ -1014,14 +1024,14 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
+ 		dmabuf = NULL;
+ 	}
+ 
+-	usr_cmdbuf = (drm_savage_cmd_header_t __user *)cmdbuf.cmd_addr;
++	usr_cmdbuf = (drm_savage_cmd_header_t __user *) cmdbuf.cmd_addr;
+ 	usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr;
+-	usr_boxes = (drm_clip_rect_t __user *)cmdbuf.box_addr;
+-	if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size*8)) ||
+-	    (cmdbuf.vb_size && DRM_VERIFYAREA_READ(
+-		    usr_vtxbuf, cmdbuf.vb_size)) ||
+-	    (cmdbuf.nbox && DRM_VERIFYAREA_READ(
+-		    usr_boxes, cmdbuf.nbox*sizeof(drm_clip_rect_t))))
++	usr_boxes = (drm_clip_rect_t __user *) cmdbuf.box_addr;
++	if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size * 8)) ||
++	    (cmdbuf.vb_size && DRM_VERIFYAREA_READ(usr_vtxbuf, cmdbuf.vb_size))
++	    || (cmdbuf.nbox
++		&& DRM_VERIFYAREA_READ(usr_boxes,
++				       cmdbuf.nbox * sizeof(drm_clip_rect_t))))
+ 		return DRM_ERR(EFAULT);
+ 
+ 	/* Make sure writes to DMA buffers are finished before sending
+@@ -1058,17 +1068,21 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
+ 		case SAVAGE_CMD_DMA_PRIM:
+ 		case SAVAGE_CMD_VB_PRIM:
+ 			if (!first_draw_cmd)
+-				first_draw_cmd = usr_cmdbuf-1;
++				first_draw_cmd = usr_cmdbuf - 1;
+ 			usr_cmdbuf += j;
+ 			i += j;
+ 			break;
+ 		default:
+ 			if (first_draw_cmd) {
+-				ret = savage_dispatch_draw (
+-					dev_priv, first_draw_cmd, usr_cmdbuf-1,
+-					dmabuf, usr_vtxbuf, cmdbuf.vb_size,
+-					cmdbuf.vb_stride,
+-					cmdbuf.nbox, usr_boxes);
++				ret =
++				    savage_dispatch_draw(dev_priv,
++							 first_draw_cmd,
++							 usr_cmdbuf - 1, dmabuf,
++							 usr_vtxbuf,
++							 cmdbuf.vb_size,
++							 cmdbuf.vb_stride,
++							 cmdbuf.nbox,
++							 usr_boxes);
+ 				if (ret != 0)
+ 					return ret;
+ 				first_draw_cmd = NULL;
+@@ -1086,9 +1100,9 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
+ 				DMA_FLUSH();
+ 				return DRM_ERR(EINVAL);
+ 			}
+-			ret = savage_dispatch_state(
+-				dev_priv, &cmd_header,
+-				(uint32_t __user *)usr_cmdbuf);
++			ret = savage_dispatch_state(dev_priv, &cmd_header,
++						    (uint32_t __user *)
++						    usr_cmdbuf);
+ 			usr_cmdbuf += j;
+ 			i += j;
+ 			break;
+@@ -1122,10 +1136,11 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
+ 	}
+ 
+ 	if (first_draw_cmd) {
+-		ret = savage_dispatch_draw (
+-			dev_priv, first_draw_cmd, usr_cmdbuf, dmabuf,
+-			usr_vtxbuf, cmdbuf.vb_size, cmdbuf.vb_stride,
+-			cmdbuf.nbox, usr_boxes);
++		ret =
++		    savage_dispatch_draw(dev_priv, first_draw_cmd, usr_cmdbuf,
++					 dmabuf, usr_vtxbuf, cmdbuf.vb_size,
++					 cmdbuf.vb_stride, cmdbuf.nbox,
++					 usr_boxes);
+ 		if (ret != 0) {
+ 			DMA_FLUSH();
+ 			return ret;
+diff --git a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h
+--- a/drivers/char/drm/sis_drm.h
++++ b/drivers/char/drm/sis_drm.h
+@@ -39,4 +39,4 @@ typedef struct {
+ 	unsigned int offset, size;
+ } drm_sis_fb_t;
+ 
+-#endif /* __SIS_DRM_H__ */
++#endif				/* __SIS_DRM_H__ */
+diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
+--- a/drivers/char/drm/sis_drv.c
++++ b/drivers/char/drm/sis_drv.c
+@@ -10,11 +10,11 @@
+  * 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 (including the next
+  * paragraph) 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
+@@ -31,31 +31,29 @@
+ #include "sis_drv.h"
+ 
+ #include "drm_pciids.h"
+-  
+-static int postinit( struct drm_device *dev, unsigned long flags )
++
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->primary.minor,
+-		pci_pretty_name(dev->pdev)
+-		);
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR,
++		 DRIVER_PATCHLEVEL,
++		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
++	    );
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+@@ -63,9 +61,6 @@ static struct pci_device_id pciidlist[] 
+ 	sisdrv_PCI_IDS
+ };
+ 
+-extern drm_ioctl_desc_t sis_ioctls[];
+-extern int sis_max_ioctl;
+-
+ static struct drm_driver driver = {
+ 	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR,
+ 	.context_ctor = sis_init_context,
+@@ -77,18 +72,18 @@ static struct drm_driver driver = {
+ 	.version = version,
+ 	.ioctls = sis_ioctls,
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
+-	},
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
++		 },
+ 	.pci_driver = {
+-		.name          = DRIVER_NAME,
+-		.id_table      = pciidlist,
+-	}
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
+ };
+ 
+ static int __init sis_init(void)
+@@ -105,6 +100,6 @@ static void __exit sis_exit(void)
+ module_init(sis_init);
+ module_exit(sis_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h
+--- a/drivers/char/drm/sis_drv.h
++++ b/drivers/char/drm/sis_drv.h
+@@ -10,11 +10,11 @@
+  * 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 (including the next
+  * paragraph) 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
+@@ -22,7 +22,7 @@
+  * 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 _SIS_DRV_H_
+@@ -46,7 +46,10 @@ typedef struct drm_sis_private {
+ 	memHeap_t *FBHeap;
+ } drm_sis_private_t;
+ 
+-extern int sis_init_context(drm_device_t *dev, int context);
+-extern int sis_final_context(drm_device_t *dev, int context);
++extern int sis_init_context(drm_device_t * dev, int context);
++extern int sis_final_context(drm_device_t * dev, int context);
++
++extern drm_ioctl_desc_t sis_ioctls[];
++extern int sis_max_ioctl;
+ 
+ #endif
+diff --git a/drivers/char/drm/sis_ds.c b/drivers/char/drm/sis_ds.c
+--- a/drivers/char/drm/sis_ds.c
++++ b/drivers/char/drm/sis_ds.c
+@@ -10,11 +10,11 @@
+  * 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 (including the next
+  * paragraph) 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
+@@ -22,10 +22,10 @@
+  * 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.
+- * 
++ *
+  * Authors:
+  *    Sung-Ching Lin <sclin at sis.com.tw>
+- * 
++ *
+  */
+ 
+ #include "drmP.h"
+@@ -41,13 +41,13 @@ set_t *setInit(void)
+ 	int i;
+ 	set_t *set;
+ 
+-	set = (set_t *)drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
++	set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
+ 	if (set != NULL) {
+ 		for (i = 0; i < SET_SIZE; i++) {
+-			set->list[i].free_next = i + 1;    
++			set->list[i].free_next = i + 1;
+ 			set->list[i].alloc_next = -1;
+ 		}
+-		set->list[SET_SIZE-1].free_next = -1;
++		set->list[SET_SIZE - 1].free_next = -1;
+ 		set->free = 0;
+ 		set->alloc = -1;
+ 		set->trace = -1;
+@@ -55,10 +55,10 @@ set_t *setInit(void)
+ 	return set;
+ }
+ 
+-int setAdd(set_t *set, ITEM_TYPE item)
++int setAdd(set_t * set, ITEM_TYPE item)
+ {
+ 	int free = set->free;
+-  
++
+ 	if (free != -1) {
+ 		set->list[free].val = item;
+ 		set->free = set->list[free].free_next;
+@@ -67,16 +67,16 @@ int setAdd(set_t *set, ITEM_TYPE item)
+ 	}
+ 
+ 	set->list[free].alloc_next = set->alloc;
+-	set->alloc = free;  
+-	set->list[free].free_next = -1;    
++	set->alloc = free;
++	set->list[free].free_next = -1;
+ 
+ 	return 1;
+ }
+ 
+-int setDel(set_t *set, ITEM_TYPE item)
++int setDel(set_t * set, ITEM_TYPE item)
+ {
+ 	int alloc = set->alloc;
+-	int prev = -1;  
++	int prev = -1;
+ 
+ 	while (alloc != -1) {
+ 		if (set->list[alloc].val == item) {
+@@ -103,7 +103,7 @@ int setDel(set_t *set, ITEM_TYPE item)
+ 
+ /* setFirst -> setAdd -> setNext is wrong */
+ 
+-int setFirst(set_t *set, ITEM_TYPE *item)
++int setFirst(set_t * set, ITEM_TYPE * item)
+ {
+ 	if (set->alloc == -1)
+ 		return 0;
+@@ -114,7 +114,7 @@ int setFirst(set_t *set, ITEM_TYPE *item
+ 	return 1;
+ }
+ 
+-int setNext(set_t *set, ITEM_TYPE *item)
++int setNext(set_t * set, ITEM_TYPE * item)
+ {
+ 	if (set->trace == -1)
+ 		return 0;
+@@ -125,7 +125,7 @@ int setNext(set_t *set, ITEM_TYPE *item)
+ 	return 1;
+ }
+ 
+-int setDestroy(set_t *set)
++int setDestroy(set_t * set)
+ {
+ 	drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
+ 
+@@ -149,35 +149,34 @@ int setDestroy(set_t *set)
+  * 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
+- * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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 
++ * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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.
+  *
+  */
+ 
+ #define ISFREE(bptr) ((bptr)->free)
+ 
+-memHeap_t *mmInit(int ofs,
+-		  int size)
++memHeap_t *mmInit(int ofs, int size)
+ {
+ 	PMemBlock blocks;
+ 
+ 	if (size <= 0)
+ 		return NULL;
+ 
+-	blocks = (TMemBlock *)drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
++	blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
+ 	if (blocks != NULL) {
+ 		blocks->ofs = ofs;
+ 		blocks->size = size;
+ 		blocks->free = 1;
+-		return (memHeap_t *)blocks;
++		return (memHeap_t *) blocks;
+ 	} else
+ 		return NULL;
+ }
+ 
+ /* Checks if a pointer 'b' is part of the heap 'heap' */
+-int mmBlockInHeap(memHeap_t *heap, PMemBlock b)
++int mmBlockInHeap(memHeap_t * heap, PMemBlock b)
+ {
+ 	TMemBlock *p;
+ 
+@@ -194,16 +193,16 @@ int mmBlockInHeap(memHeap_t *heap, PMemB
+ 		return 0;
+ }
+ 
+-static TMemBlock* SliceBlock(TMemBlock *p, 
+-			     int startofs, int size, 
++static TMemBlock *SliceBlock(TMemBlock * p,
++			     int startofs, int size,
+ 			     int reserved, int alignment)
+ {
+ 	TMemBlock *newblock;
+ 
+ 	/* break left */
+ 	if (startofs > p->ofs) {
+-		newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
+-		    DRM_MEM_DRIVER);
++		newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
++						    DRM_MEM_DRIVER);
+ 		newblock->ofs = startofs;
+ 		newblock->size = p->size - (startofs - p->ofs);
+ 		newblock->free = 1;
+@@ -215,8 +214,8 @@ static TMemBlock* SliceBlock(TMemBlock *
+ 
+ 	/* break right */
+ 	if (size < p->size) {
+-		newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
+-		    DRM_MEM_DRIVER);
++		newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
++						    DRM_MEM_DRIVER);
+ 		newblock->ofs = startofs + size;
+ 		newblock->size = p->size - size;
+ 		newblock->free = 1;
+@@ -232,37 +231,37 @@ static TMemBlock* SliceBlock(TMemBlock *
+ 	return p;
+ }
+ 
+-PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
++PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch)
+ {
+-	int mask,startofs, endofs;
++	int mask, startofs, endofs;
+ 	TMemBlock *p;
+-	
++
+ 	if (heap == NULL || align2 < 0 || size <= 0)
+ 		return NULL;
+ 
+-	mask = (1 << align2)-1;
++	mask = (1 << align2) - 1;
+ 	startofs = 0;
+-	p = (TMemBlock *)heap;
++	p = (TMemBlock *) heap;
+ 	while (p != NULL) {
+ 		if (ISFREE(p)) {
+ 			startofs = (p->ofs + mask) & ~mask;
+-			if ( startofs < startSearch ) {
++			if (startofs < startSearch) {
+ 				startofs = startSearch;
+ 			}
+-			endofs = startofs+size;
+-			if (endofs <= (p->ofs+p->size))
++			endofs = startofs + size;
++			if (endofs <= (p->ofs + p->size))
+ 				break;
+ 		}
+ 		p = p->next;
+ 	}
+ 	if (p == NULL)
+ 		return NULL;
+-	p = SliceBlock(p,startofs,size,0,mask+1);
++	p = SliceBlock(p, startofs, size, 0, mask + 1);
+ 	p->heap = heap;
+ 	return p;
+ }
+ 
+-static __inline__ int Join2Blocks(TMemBlock *p)
++static __inline__ int Join2Blocks(TMemBlock * p)
+ {
+ 	if (p->free && p->next && p->next->free) {
+ 		TMemBlock *q = p->next;
+@@ -295,7 +294,6 @@ int mmFreeMem(PMemBlock b)
+ 	p->free = 1;
+ 	Join2Blocks(p);
+ 	if (prev)
+-	Join2Blocks(prev);
++		Join2Blocks(prev);
+ 	return 0;
+ }
+-
+diff --git a/drivers/char/drm/sis_ds.h b/drivers/char/drm/sis_ds.h
+--- a/drivers/char/drm/sis_ds.h
++++ b/drivers/char/drm/sis_ds.h
+@@ -10,11 +10,11 @@
+  * 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 (including the next
+  * paragraph) 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
+@@ -22,10 +22,10 @@
+  * 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.
+- * 
++ *
+  * Authors:
+  *    Sung-Ching Lin <sclin at sis.com.tw>
+- * 
++ *
+  */
+ 
+ #ifndef __SIS_DS_H__
+@@ -50,11 +50,11 @@ typedef struct {
+ } set_t;
+ 
+ set_t *setInit(void);
+-int setAdd(set_t *set, ITEM_TYPE item);
+-int setDel(set_t *set, ITEM_TYPE item);
+-int setFirst(set_t *set, ITEM_TYPE *item);
+-int setNext(set_t *set, ITEM_TYPE *item);
+-int setDestroy(set_t *set);
++int setAdd(set_t * set, ITEM_TYPE item);
++int setDel(set_t * set, ITEM_TYPE item);
++int setFirst(set_t * set, ITEM_TYPE * item);
++int setNext(set_t * set, ITEM_TYPE * item);
++int setDestroy(set_t * set);
+ 
+ /*
+  * GLX Hardware Device Driver common code
+@@ -73,9 +73,9 @@ int setDestroy(set_t *set);
+  * 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
+- * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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 
++ * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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.
+  *
+  */
+@@ -83,7 +83,7 @@ int setDestroy(set_t *set);
+ struct mem_block_t {
+ 	struct mem_block_t *next;
+ 	struct mem_block_t *heap;
+-	int ofs,size;
++	int ofs, size;
+ 	int align;
+ 	unsigned int free:1;
+ 	unsigned int reserved:1;
+@@ -109,11 +109,11 @@ static __inline__ void mmMarkReserved(PM
+ 	b->reserved = 1;
+ }
+ 
+-/* 
++/*
+  * input: total size in bytes
+  * return: a heap pointer if OK, NULL if error
+  */
+-memHeap_t *mmInit( int ofs, int size );
++memHeap_t *mmInit(int ofs, int size);
+ 
+ /*
+  * Allocate 'size' bytes with 2^align2 bytes alignment,
+@@ -125,21 +125,21 @@ memHeap_t *mmInit( int ofs, int size );
+  *		startSearch = linear offset from start of heap to begin search
+  * return: pointer to the allocated block, 0 if error
+  */
+-PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch );
++PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch);
+ 
+ /*
+  * Returns 1 if the block 'b' is part of the heap 'heap'
+  */
+-int mmBlockInHeap( PMemBlock heap, PMemBlock b );
++int mmBlockInHeap(PMemBlock heap, PMemBlock b);
+ 
+ /*
+  * Free block starts at offset
+  * input: pointer to a block
+  * return: 0 if OK, -1 if error
+  */
+-int mmFreeMem( PMemBlock b );
++int mmFreeMem(PMemBlock b);
+ 
+ /* For debuging purpose. */
+-void mmDumpMemInfo( memHeap_t *mmInit );
++void mmDumpMemInfo(memHeap_t * mmInit);
+ 
+-#endif /* __SIS_DS_H__ */
++#endif				/* __SIS_DS_H__ */
+diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
+--- a/drivers/char/drm/sis_mm.c
++++ b/drivers/char/drm/sis_mm.c
+@@ -10,11 +10,11 @@
+  * 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 (including the next
+  * paragraph) 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
+@@ -22,10 +22,10 @@
+  * 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.
+- * 
++ *
+  * Authors:
+  *    Sung-Ching Lin <sclin at sis.com.tw>
+- * 
++ *
+  */
+ 
+ #include "drmP.h"
+@@ -37,25 +37,23 @@
+ #endif
+ 
+ #define MAX_CONTEXT 100
+-#define VIDEO_TYPE 0 
++#define VIDEO_TYPE 0
+ #define AGP_TYPE 1
+ 
+ typedef struct {
+ 	int used;
+ 	int context;
+-	set_t *sets[2]; /* 0 for video, 1 for AGP */
++	set_t *sets[2];		/* 0 for video, 1 for AGP */
+ } sis_context_t;
+ 
+ static sis_context_t global_ppriv[MAX_CONTEXT];
+ 
+-
+ static int add_alloc_set(int context, int type, unsigned int val)
+ {
+ 	int i, retval = 0;
+-	
++
+ 	for (i = 0; i < MAX_CONTEXT; i++) {
+-		if (global_ppriv[i].used && global_ppriv[i].context == context)
+-		{
++		if (global_ppriv[i].used && global_ppriv[i].context == context) {
+ 			retval = setAdd(global_ppriv[i].sets[type], val);
+ 			break;
+ 		}
+@@ -64,12 +62,11 @@ static int add_alloc_set(int context, in
+ }
+ 
+ static int del_alloc_set(int context, int type, unsigned int val)
+-{  
++{
+ 	int i, retval = 0;
+ 
+ 	for (i = 0; i < MAX_CONTEXT; i++) {
+-		if (global_ppriv[i].used && global_ppriv[i].context == context)
+-		{
++		if (global_ppriv[i].used && global_ppriv[i].context == context) {
+ 			retval = setDel(global_ppriv[i].sets[type], val);
+ 			break;
+ 		}
+@@ -77,15 +74,15 @@ static int del_alloc_set(int context, in
+ 	return retval;
+ }
+ 
+-/* fb management via fb device */ 
++/* fb management via fb device */
+ #if defined(__linux__) && defined(CONFIG_FB_SIS)
+ 
+-static int sis_fb_init( DRM_IOCTL_ARGS )
++static int sis_fb_init(DRM_IOCTL_ARGS)
+ {
+ 	return 0;
+ }
+ 
+-static int sis_fb_alloc( DRM_IOCTL_ARGS )
++static int sis_fb_alloc(DRM_IOCTL_ARGS)
+ {
+ 	drm_sis_mem_t fb;
+ 	struct sis_memreq req;
+@@ -105,7 +102,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS 
+ 			sis_free(req.offset);
+ 			retval = DRM_ERR(EINVAL);
+ 		}
+-	} else {  
++	} else {
+ 		fb.offset = 0;
+ 		fb.size = 0;
+ 		fb.free = 0;
+@@ -118,19 +115,19 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS 
+ 	return retval;
+ }
+ 
+-static int sis_fb_free( DRM_IOCTL_ARGS )
++static int sis_fb_free(DRM_IOCTL_ARGS)
+ {
+ 	drm_sis_mem_t fb;
+ 	int retval = 0;
+ 
+-	DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *)data, sizeof(fb));
++	DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb));
+ 
+ 	if (!fb.free)
+ 		return DRM_ERR(EINVAL);
+ 
+ 	if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
+ 		retval = DRM_ERR(EINVAL);
+-	sis_free((u32)fb.free);
++	sis_free((u32) fb.free);
+ 
+ 	DRM_DEBUG("free fb, offset = %lu\n", fb.free);
+ 
+@@ -149,17 +146,17 @@ static int sis_fb_free( DRM_IOCTL_ARGS )
+  *    X driver/sisfb                                  HW-   Command-
+  *  framebuffer memory           DRI heap           Cursor   queue
+  */
+-static int sis_fb_init( DRM_IOCTL_ARGS )
++static int sis_fb_init(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_sis_private_t *dev_priv = dev->dev_private;
+ 	drm_sis_fb_t fb;
+ 
+-	DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *)data, sizeof(fb));
++	DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *) data, sizeof(fb));
+ 
+ 	if (dev_priv == NULL) {
+ 		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
+-		    DRM_MEM_DRIVER);
++					      DRM_MEM_DRIVER);
+ 		dev_priv = dev->dev_private;
+ 		if (dev_priv == NULL)
+ 			return ENOMEM;
+@@ -175,7 +172,7 @@ static int sis_fb_init( DRM_IOCTL_ARGS )
+ 	return 0;
+ }
+ 
+-static int sis_fb_alloc( DRM_IOCTL_ARGS )
++static int sis_fb_alloc(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_sis_private_t *dev_priv = dev->dev_private;
+@@ -186,9 +183,9 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS 
+ 
+ 	if (dev_priv == NULL || dev_priv->FBHeap == NULL)
+ 		return DRM_ERR(EINVAL);
+-  
++
+ 	DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb));
+-  
++
+ 	block = mmAllocMem(dev_priv->FBHeap, fb.size, 0, 0);
+ 	if (block) {
+ 		/* TODO */
+@@ -196,7 +193,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS 
+ 		fb.free = (unsigned long)block;
+ 		if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) {
+ 			DRM_DEBUG("adding to allocation set fails\n");
+-			mmFreeMem((PMemBlock)fb.free);
++			mmFreeMem((PMemBlock) fb.free);
+ 			retval = DRM_ERR(EINVAL);
+ 		}
+ 	} else {
+@@ -212,7 +209,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS 
+ 	return retval;
+ }
+ 
+-static int sis_fb_free( DRM_IOCTL_ARGS )
++static int sis_fb_free(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_sis_private_t *dev_priv = dev->dev_private;
+@@ -221,14 +218,14 @@ static int sis_fb_free( DRM_IOCTL_ARGS )
+ 	if (dev_priv == NULL || dev_priv->FBHeap == NULL)
+ 		return DRM_ERR(EINVAL);
+ 
+-	DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *)data, sizeof(fb));
++	DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb));
+ 
+-	if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock)fb.free))
++	if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock) fb.free))
+ 		return DRM_ERR(EINVAL);
+ 
+ 	if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
+ 		return DRM_ERR(EINVAL);
+-	mmFreeMem((PMemBlock)fb.free);
++	mmFreeMem((PMemBlock) fb.free);
+ 
+ 	DRM_DEBUG("free fb, free = 0x%lx\n", fb.free);
+ 
+@@ -237,9 +234,9 @@ static int sis_fb_free( DRM_IOCTL_ARGS )
+ 
+ #endif
+ 
+-/* agp memory management */ 
++/* agp memory management */
+ 
+-static int sis_ioctl_agp_init( DRM_IOCTL_ARGS )
++static int sis_ioctl_agp_init(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_sis_private_t *dev_priv = dev->dev_private;
+@@ -247,7 +244,7 @@ static int sis_ioctl_agp_init( DRM_IOCTL
+ 
+ 	if (dev_priv == NULL) {
+ 		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
+-		    DRM_MEM_DRIVER);
++					      DRM_MEM_DRIVER);
+ 		dev_priv = dev->dev_private;
+ 		if (dev_priv == NULL)
+ 			return ENOMEM;
+@@ -256,16 +253,17 @@ static int sis_ioctl_agp_init( DRM_IOCTL
+ 	if (dev_priv->AGPHeap != NULL)
+ 		return DRM_ERR(EINVAL);
+ 
+-	DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *)data, sizeof(agp));
++	DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *) data,
++				 sizeof(agp));
+ 
+ 	dev_priv->AGPHeap = mmInit(agp.offset, agp.size);
+ 
+ 	DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
+-  
++
+ 	return 0;
+ }
+ 
+-static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
++static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_sis_private_t *dev_priv = dev->dev_private;
+@@ -273,12 +271,12 @@ static int sis_ioctl_agp_alloc( DRM_IOCT
+ 	drm_sis_mem_t agp;
+ 	PMemBlock block;
+ 	int retval = 0;
+-   
++
+ 	if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
+ 		return DRM_ERR(EINVAL);
+-  
++
+ 	DRM_COPY_FROM_USER_IOCTL(agp, argp, sizeof(agp));
+-  
++
+ 	block = mmAllocMem(dev_priv->AGPHeap, agp.size, 0, 0);
+ 	if (block) {
+ 		/* TODO */
+@@ -286,10 +284,10 @@ static int sis_ioctl_agp_alloc( DRM_IOCT
+ 		agp.free = (unsigned long)block;
+ 		if (!add_alloc_set(agp.context, AGP_TYPE, agp.free)) {
+ 			DRM_DEBUG("adding to allocation set fails\n");
+-			mmFreeMem((PMemBlock)agp.free);
++			mmFreeMem((PMemBlock) agp.free);
+ 			retval = -1;
+ 		}
+-	} else {  
++	} else {
+ 		agp.offset = 0;
+ 		agp.size = 0;
+ 		agp.free = 0;
+@@ -302,7 +300,7 @@ static int sis_ioctl_agp_alloc( DRM_IOCT
+ 	return retval;
+ }
+ 
+-static int sis_ioctl_agp_free( DRM_IOCTL_ARGS )
++static int sis_ioctl_agp_free(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_sis_private_t *dev_priv = dev->dev_private;
+@@ -311,12 +309,13 @@ static int sis_ioctl_agp_free( DRM_IOCTL
+ 	if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
+ 		return DRM_ERR(EINVAL);
+ 
+-	DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *)data, sizeof(agp));
++	DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *) data,
++				 sizeof(agp));
+ 
+-	if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock)agp.free))
++	if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock) agp.free))
+ 		return DRM_ERR(EINVAL);
+ 
+-	mmFreeMem((PMemBlock)agp.free);
++	mmFreeMem((PMemBlock) agp.free);
+ 	if (!del_alloc_set(agp.context, AGP_TYPE, agp.free))
+ 		return DRM_ERR(EINVAL);
+ 
+@@ -329,31 +328,30 @@ int sis_init_context(struct drm_device *
+ {
+ 	int i;
+ 
+-	for (i = 0; i < MAX_CONTEXT ; i++) {
++	for (i = 0; i < MAX_CONTEXT; i++) {
+ 		if (global_ppriv[i].used &&
+ 		    (global_ppriv[i].context == context))
+ 			break;
+ 	}
+ 
+ 	if (i >= MAX_CONTEXT) {
+-		for (i = 0; i < MAX_CONTEXT ; i++) {
++		for (i = 0; i < MAX_CONTEXT; i++) {
+ 			if (!global_ppriv[i].used) {
+ 				global_ppriv[i].context = context;
+ 				global_ppriv[i].used = 1;
+ 				global_ppriv[i].sets[0] = setInit();
+ 				global_ppriv[i].sets[1] = setInit();
+ 				DRM_DEBUG("init allocation set, socket=%d, "
+-				    "context = %d\n", i, context);
++					  "context = %d\n", i, context);
+ 				break;
+ 			}
+ 		}
+ 		if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
+-		    (global_ppriv[i].sets[1] == NULL))
+-		{
++		    (global_ppriv[i].sets[1] == NULL)) {
+ 			return 0;
+ 		}
+ 	}
+-	
++
+ 	return 1;
+ }
+ 
+@@ -361,7 +359,7 @@ int sis_final_context(struct drm_device 
+ {
+ 	int i;
+ 
+-	for (i=0; i<MAX_CONTEXT; i++) {
++	for (i = 0; i < MAX_CONTEXT; i++) {
+ 		if (global_ppriv[i].used &&
+ 		    (global_ppriv[i].context == context))
+ 			break;
+@@ -382,7 +380,7 @@ int sis_final_context(struct drm_device 
+ #if defined(__linux__) && defined(CONFIG_FB_SIS)
+ 			sis_free(item);
+ #else
+-			mmFreeMem((PMemBlock)item);
++			mmFreeMem((PMemBlock) item);
+ #endif
+ 			retval = setNext(set, &item);
+ 		}
+@@ -393,25 +391,24 @@ int sis_final_context(struct drm_device 
+ 		retval = setFirst(set, &item);
+ 		while (retval) {
+ 			DRM_DEBUG("free agp memory 0x%x\n", item);
+-			mmFreeMem((PMemBlock)item);
++			mmFreeMem((PMemBlock) item);
+ 			retval = setNext(set, &item);
+ 		}
+ 		setDestroy(set);
+ 
+-		global_ppriv[i].used = 0;	  
+-        }
+-	
++		global_ppriv[i].used = 0;
++	}
++
+ 	return 1;
+ }
+ 
+ drm_ioctl_desc_t sis_ioctls[] = {
+-	[DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)]  = { sis_fb_alloc,        1, 0 },
+-	[DRM_IOCTL_NR(DRM_SIS_FB_FREE)]   = { sis_fb_free,         1, 0 },
+-	[DRM_IOCTL_NR(DRM_SIS_AGP_INIT)]  = { sis_ioctl_agp_init,  1, 1 },
+-	[DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = { sis_ioctl_agp_alloc, 1, 0 },
+-	[DRM_IOCTL_NR(DRM_SIS_AGP_FREE)]  = { sis_ioctl_agp_free,  1, 0 },
+-	[DRM_IOCTL_NR(DRM_SIS_FB_INIT)]   = { sis_fb_init,         1, 1 }
++	[DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, 1, 0},
++	[DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, 1, 0},
++	[DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, 1, 1},
++	[DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, 1, 0},
++	[DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, 1, 0},
++	[DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, 1, 1}
+ };
+ 
+ int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
+-
+diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
+--- a/drivers/char/drm/tdfx_drv.c
++++ b/drivers/char/drm/tdfx_drv.c
+@@ -36,30 +36,28 @@
+ 
+ #include "drm_pciids.h"
+ 
+-static int postinit( struct drm_device *dev, unsigned long flags )
++static int postinit(struct drm_device *dev, unsigned long flags)
+ {
+-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+-		DRIVER_NAME,
+-		DRIVER_MAJOR,
+-		DRIVER_MINOR,
+-		DRIVER_PATCHLEVEL,
+-		DRIVER_DATE,
+-		dev->primary.minor,
+-		pci_pretty_name(dev->pdev)
+-		);
++	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
++		 DRIVER_NAME,
++		 DRIVER_MAJOR,
++		 DRIVER_MINOR,
++		 DRIVER_PATCHLEVEL,
++		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
++	    );
+ 	return 0;
+ }
+ 
+-static int version( drm_version_t *version )
++static int version(drm_version_t * version)
+ {
+ 	int len;
+ 
+ 	version->version_major = DRIVER_MAJOR;
+ 	version->version_minor = DRIVER_MINOR;
+ 	version->version_patchlevel = DRIVER_PATCHLEVEL;
+-	DRM_COPY( version->name, DRIVER_NAME );
+-	DRM_COPY( version->date, DRIVER_DATE );
+-	DRM_COPY( version->desc, DRIVER_DESC );
++	DRM_COPY(version->name, DRIVER_NAME);
++	DRM_COPY(version->date, DRIVER_DATE);
++	DRM_COPY(version->desc, DRIVER_DESC);
+ 	return 0;
+ }
+ 
+@@ -75,18 +73,18 @@ static struct drm_driver driver = {
+ 	.postinit = postinit,
+ 	.version = version,
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
+-	},
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
++		 },
+ 	.pci_driver = {
+-		.name          = DRIVER_NAME,
+-		.id_table      = pciidlist,
+-	}
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
+ };
+ 
+ static int __init tdfx_init(void)
+@@ -102,6 +100,6 @@ static void __exit tdfx_exit(void)
+ module_init(tdfx_init);
+ module_exit(tdfx_exit);
+ 
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL and additional rights");
+diff --git a/drivers/char/drm/via_3d_reg.h b/drivers/char/drm/via_3d_reg.h
+--- a/drivers/char/drm/via_3d_reg.h
++++ b/drivers/char/drm/via_3d_reg.h
+@@ -1643,7 +1643,6 @@
+ #define HC_HAGPBpID_STOP        0x00000002
+ #define HC_HAGPBpH_MASK         0x00ffffff
+ 
+-
+ #define VIA_VIDEO_HEADER5       0xFE040000
+ #define VIA_VIDEO_HEADER6       0xFE050000
+ #define VIA_VIDEO_HEADER7       0xFE060000
+diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
+--- a/drivers/char/drm/via_dma.c
++++ b/drivers/char/drm/via_dma.c
+@@ -1,11 +1,11 @@
+ /* via_dma.c -- DMA support for the VIA Unichrome/Pro
+- * 
++ *
+  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+  * All Rights Reserved.
+  *
+  * Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A.
+  * All Rights Reserved.
+- * 
++ *
+  * Copyright 2004 The Unichrome project.
+  * All Rights Reserved.
+  *
+@@ -23,14 +23,14 @@
+  * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 
++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
+  *
+- * Authors: 
+- *    Tungsten Graphics, 
+- *    Erdi Chen, 
++ * Authors:
++ *    Tungsten Graphics,
++ *    Erdi Chen,
+  *    Thomas Hellstrom.
+  */
+ 
+@@ -61,34 +61,31 @@
+ 	dev_priv->dma_low +=8;					\
+ }
+ 
+-#define via_flush_write_combine() DRM_MEMORYBARRIER() 
++#define via_flush_write_combine() DRM_MEMORYBARRIER()
+ 
+ #define VIA_OUT_RING_QW(w1,w2)			\
+ 	*vb++ = (w1);				\
+ 	*vb++ = (w2);				\
+-	dev_priv->dma_low += 8; 
++	dev_priv->dma_low += 8;
+ 
+ static void via_cmdbuf_start(drm_via_private_t * dev_priv);
+ static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
+ static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
+ static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
+ static int via_wait_idle(drm_via_private_t * dev_priv);
+-static void via_pad_cache(drm_via_private_t *dev_priv, int qwords);
+-
++static void via_pad_cache(drm_via_private_t * dev_priv, int qwords);
+ 
+ /*
+  * Free space in command buffer.
+  */
+ 
+-static uint32_t
+-via_cmdbuf_space(drm_via_private_t *dev_priv)
++static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv)
+ {
+-	uint32_t agp_base = dev_priv->dma_offset + 
+-		(uint32_t) dev_priv->agpAddr;
++	uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+ 	uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
+-	
+-	return ((hw_addr <= dev_priv->dma_low) ? 
+-		(dev_priv->dma_high + hw_addr - dev_priv->dma_low) : 
++
++	return ((hw_addr <= dev_priv->dma_low) ?
++		(dev_priv->dma_high + hw_addr - dev_priv->dma_low) :
+ 		(hw_addr - dev_priv->dma_low));
+ }
+ 
+@@ -96,15 +93,13 @@ via_cmdbuf_space(drm_via_private_t *dev_
+  * How much does the command regulator lag behind?
+  */
+ 
+-static uint32_t
+-via_cmdbuf_lag(drm_via_private_t *dev_priv)
++static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv)
+ {
+-	uint32_t agp_base = dev_priv->dma_offset + 
+-		(uint32_t) dev_priv->agpAddr;
++	uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+ 	uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
+-	
+-	return ((hw_addr <= dev_priv->dma_low) ? 
+-		(dev_priv->dma_low - hw_addr) : 
++
++	return ((hw_addr <= dev_priv->dma_low) ?
++		(dev_priv->dma_low - hw_addr) :
+ 		(dev_priv->dma_wrap + dev_priv->dma_low - hw_addr));
+ }
+ 
+@@ -121,20 +116,20 @@ via_cmdbuf_wait(drm_via_private_t * dev_
+ 	uint32_t count;
+ 	hw_addr_ptr = dev_priv->hw_addr_ptr;
+ 	cur_addr = dev_priv->dma_low;
+-	next_addr = cur_addr + size + 512*1024;
++	next_addr = cur_addr + size + 512 * 1024;
+ 	count = 1000000;
+ 	do {
+-	        hw_addr = *hw_addr_ptr - agp_base;
++		hw_addr = *hw_addr_ptr - agp_base;
+ 		if (count-- == 0) {
+-			DRM_ERROR("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
+-				  hw_addr, cur_addr, next_addr);
++			DRM_ERROR
++			    ("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
++			     hw_addr, cur_addr, next_addr);
+ 			return -1;
+ 		}
+ 	} while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
+ 	return 0;
+ }
+ 
+-
+ /*
+  * Checks whether buffer head has reach the end. Rewind the ring buffer
+  * when necessary.
+@@ -145,7 +140,8 @@ via_cmdbuf_wait(drm_via_private_t * dev_
+ static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
+ 				      unsigned int size)
+ {
+-	if ((dev_priv->dma_low + size + 4*CMDBUF_ALIGNMENT_SIZE) > dev_priv->dma_high) {
++	if ((dev_priv->dma_low + size + 4 * CMDBUF_ALIGNMENT_SIZE) >
++	    dev_priv->dma_high) {
+ 		via_cmdbuf_rewind(dev_priv);
+ 	}
+ 	if (via_cmdbuf_wait(dev_priv, size) != 0) {
+@@ -159,7 +155,7 @@ int via_dma_cleanup(drm_device_t * dev)
+ {
+ 	if (dev->dev_private) {
+ 		drm_via_private_t *dev_priv =
+-			(drm_via_private_t *) dev->dev_private;
++		    (drm_via_private_t *) dev->dev_private;
+ 
+ 		if (dev_priv->ring.virtual_start) {
+ 			via_cmdbuf_reset(dev_priv);
+@@ -189,7 +185,7 @@ static int via_initialize(drm_device_t *
+ 	}
+ 
+ 	if (!dev->agp || !dev->agp->base) {
+-		DRM_ERROR("%s called with no agp memory available\n", 
++		DRM_ERROR("%s called with no agp memory available\n",
+ 			  __FUNCTION__);
+ 		return DRM_ERR(EFAULT);
+ 	}
+@@ -247,10 +243,10 @@ int via_dma_init(DRM_IOCTL_ARGS)
+ 		else
+ 			retcode = via_dma_cleanup(dev);
+ 		break;
+-        case VIA_DMA_INITIALIZED:
+-		retcode = (dev_priv->ring.virtual_start != NULL) ? 
+-			0: DRM_ERR( EFAULT );
+-	        break;
++	case VIA_DMA_INITIALIZED:
++		retcode = (dev_priv->ring.virtual_start != NULL) ?
++		    0 : DRM_ERR(EFAULT);
++		break;
+ 	default:
+ 		retcode = DRM_ERR(EINVAL);
+ 		break;
+@@ -259,8 +255,6 @@ int via_dma_init(DRM_IOCTL_ARGS)
+ 	return retcode;
+ }
+ 
+-
+-
+ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
+ {
+ 	drm_via_private_t *dev_priv;
+@@ -277,8 +271,7 @@ static int via_dispatch_cmdbuffer(drm_de
+ 
+ 	if (cmd->size > VIA_PCI_BUF_SIZE) {
+ 		return DRM_ERR(ENOMEM);
+-	} 
+-
++	}
+ 
+ 	if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
+ 		return DRM_ERR(EFAULT);
+@@ -289,19 +282,19 @@ static int via_dispatch_cmdbuffer(drm_de
+ 	 * copy it to AGP memory when ready.
+ 	 */
+ 
+-		
+-	if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 1))) {
++	if ((ret =
++	     via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
++				       cmd->size, dev, 1))) {
+ 		return ret;
+ 	}
+-       	
+-	
++
+ 	vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size);
+ 	if (vb == NULL) {
+ 		return DRM_ERR(EAGAIN);
+ 	}
+ 
+ 	memcpy(vb, dev_priv->pci_buf, cmd->size);
+-	
++
+ 	dev_priv->dma_low += cmd->size;
+ 
+ 	/*
+@@ -310,7 +303,7 @@ static int via_dispatch_cmdbuffer(drm_de
+ 	 */
+ 
+ 	if (cmd->size < 0x100)
+-	  via_pad_cache(dev_priv,(0x100 - cmd->size) >> 3);
++		via_pad_cache(dev_priv, (0x100 - cmd->size) >> 3);
+ 	via_cmdbuf_pause(dev_priv);
+ 
+ 	return 0;
+@@ -330,7 +323,7 @@ int via_flush_ioctl(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+ 	return via_driver_dma_quiescent(dev);
+ }
+@@ -341,7 +334,7 @@ int via_cmdbuffer(DRM_IOCTL_ARGS)
+ 	drm_via_cmdbuffer_t cmdbuf;
+ 	int ret;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+ 	DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data,
+ 				 sizeof(cmdbuf));
+@@ -356,8 +349,9 @@ int via_cmdbuffer(DRM_IOCTL_ARGS)
+ 	return 0;
+ }
+ 
+-extern int 
+-via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size);
++extern int
++via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
++			 unsigned int size);
+ static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
+ 				      drm_via_cmdbuffer_t * cmd)
+ {
+@@ -366,15 +360,19 @@ static int via_dispatch_pci_cmdbuffer(dr
+ 
+ 	if (cmd->size > VIA_PCI_BUF_SIZE) {
+ 		return DRM_ERR(ENOMEM);
+-	} 
++	}
+ 	if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
+ 		return DRM_ERR(EFAULT);
+-	
+-	if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 0))) {
++
++	if ((ret =
++	     via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
++				       cmd->size, dev, 0))) {
+ 		return ret;
+ 	}
+-	
+-	ret = via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf, cmd->size);
++
++	ret =
++	    via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf,
++				     cmd->size);
+ 	return ret;
+ }
+ 
+@@ -384,7 +382,7 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
+ 	drm_via_cmdbuffer_t cmdbuf;
+ 	int ret;
+ 
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+ 	DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data,
+ 				 sizeof(cmdbuf));
+@@ -400,17 +398,15 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
+ 	return 0;
+ }
+ 
+-
+ static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
+ 					 uint32_t * vb, int qw_count)
+ {
+-        for (; qw_count > 0; --qw_count) {
++	for (; qw_count > 0; --qw_count) {
+ 		VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY);
+ 	}
+ 	return vb;
+ }
+ 
+-
+ /*
+  * This function is used internally by ring buffer mangement code.
+  *
+@@ -426,7 +422,7 @@ static inline uint32_t *via_get_dma(drm_
+  * modifying the pause address stored in the buffer itself. If
+  * the regulator has already paused, restart it.
+  */
+-static int via_hook_segment(drm_via_private_t *dev_priv,
++static int via_hook_segment(drm_via_private_t * dev_priv,
+ 			    uint32_t pause_addr_hi, uint32_t pause_addr_lo,
+ 			    int no_pci_fire)
+ {
+@@ -434,7 +430,7 @@ static int via_hook_segment(drm_via_priv
+ 	volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
+ 
+ 	via_flush_write_combine();
+-	while(! *(via_get_dma(dev_priv)-1));
++	while (!*(via_get_dma(dev_priv) - 1)) ;
+ 	*dev_priv->last_pause_ptr = pause_addr_lo;
+ 	via_flush_write_combine();
+ 
+@@ -443,55 +439,53 @@ static int via_hook_segment(drm_via_priv
+ 	 * Not sure it is needed.
+ 	 */
+ 
+-	while(! *dev_priv->last_pause_ptr);
++	while (!*dev_priv->last_pause_ptr) ;
+ 	dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
+-	while(! *dev_priv->last_pause_ptr);
+-
++	while (!*dev_priv->last_pause_ptr) ;
+ 
+ 	paused = 0;
+-	count = 20; 
++	count = 20;
+ 
+-	while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--);
++	while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--) ;
+ 	if ((count <= 8) && (count >= 0)) {
+ 		uint32_t rgtr, ptr;
+ 		rgtr = *(dev_priv->hw_addr_ptr);
+-		ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) + 
+-			dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 - 
+-			CMDBUF_ALIGNMENT_SIZE;
++		ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
++		    dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 -
++		    CMDBUF_ALIGNMENT_SIZE;
+ 		if (rgtr <= ptr) {
+-			DRM_ERROR("Command regulator\npaused at count %d, address %x, "
+-				  "while current pause address is %x.\n"
+-				  "Please mail this message to "
+-				  "<unichrome-devel at lists.sourceforge.net>\n",
+-				  count, rgtr, ptr);
++			DRM_ERROR
++			    ("Command regulator\npaused at count %d, address %x, "
++			     "while current pause address is %x.\n"
++			     "Please mail this message to "
++			     "<unichrome-devel at lists.sourceforge.net>\n", count,
++			     rgtr, ptr);
+ 		}
+ 	}
+-		
++
+ 	if (paused && !no_pci_fire) {
+-	        uint32_t rgtr,ptr;
++		uint32_t rgtr, ptr;
+ 		uint32_t ptr_low;
+ 
+ 		count = 1000000;
+-		while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) && count--);
+-		
++		while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY)
++		       && count--) ;
++
+ 		rgtr = *(dev_priv->hw_addr_ptr);
+-		ptr = ((char *)paused_at - dev_priv->dma_ptr) + 
+-			dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
+-		
++		ptr = ((char *)paused_at - dev_priv->dma_ptr) +
++		    dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
+ 
+-		ptr_low = (ptr > 3*CMDBUF_ALIGNMENT_SIZE) ? 
+-			ptr - 3*CMDBUF_ALIGNMENT_SIZE : 0;
++		ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ?
++		    ptr - 3 * CMDBUF_ALIGNMENT_SIZE : 0;
+ 		if (rgtr <= ptr && rgtr >= ptr_low) {
+ 			VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
+ 			VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
+ 			VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
+-		} 
++		}
+ 	}
+ 	return paused;
+ }
+ 
+-
+-
+ static int via_wait_idle(drm_via_private_t * dev_priv)
+ {
+ 	int count = 10000000;
+@@ -502,9 +496,8 @@ static int via_wait_idle(drm_via_private
+ }
+ 
+ static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
+-			       uint32_t addr, uint32_t *cmd_addr_hi, 
+-			       uint32_t *cmd_addr_lo,
+-			       int skip_wait)
++			       uint32_t addr, uint32_t * cmd_addr_hi,
++			       uint32_t * cmd_addr_lo, int skip_wait)
+ {
+ 	uint32_t agp_base;
+ 	uint32_t cmd_addr, addr_lo, addr_hi;
+@@ -512,31 +505,26 @@ static uint32_t *via_align_cmd(drm_via_p
+ 	uint32_t qw_pad_count;
+ 
+ 	if (!skip_wait)
+-		via_cmdbuf_wait(dev_priv, 2*CMDBUF_ALIGNMENT_SIZE);
++		via_cmdbuf_wait(dev_priv, 2 * CMDBUF_ALIGNMENT_SIZE);
+ 
+ 	vb = via_get_dma(dev_priv);
+-	VIA_OUT_RING_QW( HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
+-			 (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16); 
++	VIA_OUT_RING_QW(HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
++			(VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
+ 	agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+ 	qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) -
+-		((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
++	    ((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
+ 
+-	
+-	cmd_addr = (addr) ? addr : 
+-		agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
++	cmd_addr = (addr) ? addr :
++	    agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
+ 	addr_lo = ((HC_SubA_HAGPBpL << 24) | (cmd_type & HC_HAGPBpID_MASK) |
+ 		   (cmd_addr & HC_HAGPBpL_MASK));
+ 	addr_hi = ((HC_SubA_HAGPBpH << 24) | (cmd_addr >> 24));
+ 
+ 	vb = via_align_buffer(dev_priv, vb, qw_pad_count - 1);
+-	VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, 
+-			*cmd_addr_lo = addr_lo);
++	VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, *cmd_addr_lo = addr_lo);
+ 	return vb;
+ }
+ 
+-
+-
+-
+ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
+ {
+ 	uint32_t pause_addr_lo, pause_addr_hi;
+@@ -545,7 +533,6 @@ static void via_cmdbuf_start(drm_via_pri
+ 	uint32_t command;
+ 	uint32_t agp_base;
+ 
+-
+ 	dev_priv->dma_low = 0;
+ 
+ 	agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+@@ -557,12 +544,12 @@ static void via_cmdbuf_start(drm_via_pri
+ 	command = ((HC_SubA_HAGPCMNT << 24) | (start_addr >> 24) |
+ 		   ((end_addr & 0xff000000) >> 16));
+ 
+-	dev_priv->last_pause_ptr = 
+-		via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, 
+-			      &pause_addr_hi, & pause_addr_lo, 1) - 1;
++	dev_priv->last_pause_ptr =
++	    via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0,
++			  &pause_addr_hi, &pause_addr_lo, 1) - 1;
+ 
+ 	via_flush_write_combine();
+-	while(! *dev_priv->last_pause_ptr);
++	while (!*dev_priv->last_pause_ptr) ;
+ 
+ 	VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
+ 	VIA_WRITE(VIA_REG_TRANSPACE, command);
+@@ -575,14 +562,14 @@ static void via_cmdbuf_start(drm_via_pri
+ 	VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
+ }
+ 
+-static void via_pad_cache(drm_via_private_t *dev_priv, int qwords)
++static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
+ {
+ 	uint32_t *vb;
+ 
+ 	via_cmdbuf_wait(dev_priv, qwords + 2);
+ 	vb = via_get_dma(dev_priv);
+-	VIA_OUT_RING_QW( HC_HEADER2, HC_ParaType_NotTex << 16);
+-	via_align_buffer(dev_priv,vb,qwords);
++	VIA_OUT_RING_QW(HC_HEADER2, HC_ParaType_NotTex << 16);
++	via_align_buffer(dev_priv, vb, qwords);
+ }
+ 
+ static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
+@@ -590,10 +577,9 @@ static inline void via_dummy_bitblt(drm_
+ 	uint32_t *vb = via_get_dma(dev_priv);
+ 	SetReg2DAGP(0x0C, (0 | (0 << 16)));
+ 	SetReg2DAGP(0x10, 0 | (0 << 16));
+-	SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000); 
++	SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
+ }
+ 
+-
+ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
+ {
+ 	uint32_t agp_base;
+@@ -603,11 +589,10 @@ static void via_cmdbuf_jump(drm_via_priv
+ 	uint32_t dma_low_save1, dma_low_save2;
+ 
+ 	agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+-	via_align_cmd(dev_priv,  HC_HAGPBpID_JUMP, 0, &jump_addr_hi, 
++	via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
+ 		      &jump_addr_lo, 0);
+-	
+-	dev_priv->dma_wrap = dev_priv->dma_low;
+ 
++	dev_priv->dma_wrap = dev_priv->dma_low;
+ 
+ 	/*
+ 	 * Wrap command buffer to the beginning.
+@@ -619,11 +604,12 @@ static void via_cmdbuf_jump(drm_via_priv
+ 	}
+ 
+ 	via_dummy_bitblt(dev_priv);
+-	via_dummy_bitblt(dev_priv); 
++	via_dummy_bitblt(dev_priv);
+ 
+-	last_pause_ptr = via_align_cmd(dev_priv,  HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, 
+-				       &pause_addr_lo, 0) -1;
+-	via_align_cmd(dev_priv,  HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, 
++	last_pause_ptr =
++	    via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
++			  &pause_addr_lo, 0) - 1;
++	via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ 		      &pause_addr_lo, 0);
+ 
+ 	*last_pause_ptr = pause_addr_lo;
+@@ -638,23 +624,23 @@ static void via_cmdbuf_jump(drm_via_priv
+ 	 * does not seem to get updated immediately when a jump occurs.
+ 	 */
+ 
+-	last_pause_ptr = via_align_cmd(dev_priv,  HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, 
+-				       &pause_addr_lo, 0) -1;
+-	via_align_cmd(dev_priv,  HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, 
++	last_pause_ptr =
++	    via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
++			  &pause_addr_lo, 0) - 1;
++	via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ 		      &pause_addr_lo, 0);
+ 	*last_pause_ptr = pause_addr_lo;
+ 
+ 	dma_low_save2 = dev_priv->dma_low;
+-	dev_priv->dma_low = dma_low_save1;	
+-	via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0);
++	dev_priv->dma_low = dma_low_save1;
++	via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0);
+ 	dev_priv->dma_low = dma_low_save2;
+-	via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
++	via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
+ }
+ 
+-
+ static void via_cmdbuf_rewind(drm_via_private_t * dev_priv)
+ {
+-	via_cmdbuf_jump(dev_priv); 
++	via_cmdbuf_jump(dev_priv);
+ }
+ 
+ static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
+@@ -662,10 +648,9 @@ static void via_cmdbuf_flush(drm_via_pri
+ 	uint32_t pause_addr_lo, pause_addr_hi;
+ 
+ 	via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0);
+-	via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
++	via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
+ }
+ 
+-
+ static void via_cmdbuf_pause(drm_via_private_t * dev_priv)
+ {
+ 	via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE);
+@@ -681,8 +666,7 @@ static void via_cmdbuf_reset(drm_via_pri
+  * User interface to the space and lag functions.
+  */
+ 
+-int 
+-via_cmdbuf_size(DRM_IOCTL_ARGS)
++int via_cmdbuf_size(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_via_cmdbuf_size_t d_siz;
+@@ -691,7 +675,7 @@ via_cmdbuf_size(DRM_IOCTL_ARGS)
+ 	drm_via_private_t *dev_priv;
+ 
+ 	DRM_DEBUG("via cmdbuf_size\n");
+-	LOCK_TEST_WITH_RETURN( dev, filp );
++	LOCK_TEST_WITH_RETURN(dev, filp);
+ 
+ 	dev_priv = (drm_via_private_t *) dev->dev_private;
+ 
+@@ -704,12 +688,12 @@ via_cmdbuf_size(DRM_IOCTL_ARGS)
+ 	DRM_COPY_FROM_USER_IOCTL(d_siz, (drm_via_cmdbuf_size_t __user *) data,
+ 				 sizeof(d_siz));
+ 
+-
+ 	count = 1000000;
+ 	tmp_size = d_siz.size;
+-	switch(d_siz.func) {
++	switch (d_siz.func) {
+ 	case VIA_CMDBUF_SPACE:
+-		while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size) && count--) {
++		while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size)
++		       && count--) {
+ 			if (!d_siz.wait) {
+ 				break;
+ 			}
+@@ -720,7 +704,8 @@ via_cmdbuf_size(DRM_IOCTL_ARGS)
+ 		}
+ 		break;
+ 	case VIA_CMDBUF_LAG:
+-		while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size) && count--) {
++		while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size)
++		       && count--) {
+ 			if (!d_siz.wait) {
+ 				break;
+ 			}
+diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h
+--- a/drivers/char/drm/via_drm.h
++++ b/drivers/char/drm/via_drm.h
+@@ -149,7 +149,7 @@ typedef struct _drm_via_dma_init {
+ 	enum {
+ 		VIA_INIT_DMA = 0x01,
+ 		VIA_CLEANUP_DMA = 0x02,
+-                VIA_DMA_INITIALIZED = 0x03
++		VIA_DMA_INITIALIZED = 0x03
+ 	} func;
+ 
+ 	unsigned long offset;
+@@ -212,7 +212,7 @@ typedef enum {
+ 
+ #define VIA_IRQ_FLAGS_MASK 0xF0000000
+ 
+-struct drm_via_wait_irq_request{
++struct drm_via_wait_irq_request {
+ 	unsigned irq;
+ 	via_irq_seq_type_t type;
+ 	uint32_t sequence;
+diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
+--- a/drivers/char/drm/via_drv.c
++++ b/drivers/char/drm/via_drv.c
+@@ -93,18 +93,18 @@ static struct drm_driver driver = {
+ 	.ioctls = ioctls,
+ 	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+ 	.fops = {
+-		.owner = THIS_MODULE,
+-		.open = drm_open,
+-		.release = drm_release,
+-		.ioctl = drm_ioctl,
+-		.mmap = drm_mmap,
+-		.poll = drm_poll,
+-		.fasync = drm_fasync,
+-		},
++		 .owner = THIS_MODULE,
++		 .open = drm_open,
++		 .release = drm_release,
++		 .ioctl = drm_ioctl,
++		 .mmap = drm_mmap,
++		 .poll = drm_poll,
++		 .fasync = drm_fasync,
++		 },
+ 	.pci_driver = {
+-		.name = DRIVER_NAME,
+-		.id_table = pciidlist,
+-	}
++		       .name = DRIVER_NAME,
++		       .id_table = pciidlist,
++		       }
+ };
+ 
+ static int __init via_init(void)
+diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
+--- a/drivers/char/drm/via_drv.h
++++ b/drivers/char/drm/via_drv.h
+@@ -40,8 +40,6 @@
+ #define VIA_FIRE_BUF_SIZE  1024
+ #define VIA_NUM_IRQS 2
+ 
+-
+-
+ typedef struct drm_via_ring_buffer {
+ 	drm_map_t map;
+ 	char *virtual_start;
+@@ -55,7 +53,7 @@ typedef struct drm_via_irq {
+ 	uint32_t enable_mask;
+ 	wait_queue_head_t irq_queue;
+ } drm_via_irq_t;
+-	
++
+ typedef struct drm_via_private {
+ 	drm_via_sarea_t *sarea_priv;
+ 	drm_map_t *sarea;
+@@ -71,9 +69,9 @@ typedef struct drm_via_private {
+ 	volatile uint32_t *last_pause_ptr;
+ 	volatile uint32_t *hw_addr_ptr;
+ 	drm_via_ring_buffer_t ring;
+-        struct timeval last_vblank;
+-        int last_vblank_valid;
+-        unsigned usec_per_vblank;
++	struct timeval last_vblank;
++	int last_vblank_valid;
++	unsigned usec_per_vblank;
+ 	drm_via_state_t hc_state;
+ 	char pci_buf[VIA_PCI_BUF_SIZE];
+ 	const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
+@@ -82,8 +80,8 @@ typedef struct drm_via_private {
+ 	drm_via_irq_t via_irqs[VIA_NUM_IRQS];
+ 	unsigned num_irqs;
+ 	maskarray_t *irq_masks;
+-	uint32_t irq_enable_mask; 
+-	uint32_t irq_pending_mask;	
++	uint32_t irq_enable_mask;
++	uint32_t irq_pending_mask;
+ } drm_via_private_t;
+ 
+ /* VIA MMIO register access */
+@@ -110,9 +108,11 @@ extern void via_driver_irq_uninstall(drm
+ extern int via_dma_cleanup(drm_device_t * dev);
+ extern void via_init_command_verifier(void);
+ extern int via_driver_dma_quiescent(drm_device_t * dev);
+-extern void via_init_futex(drm_via_private_t *dev_priv);
+-extern void via_cleanup_futex(drm_via_private_t *dev_priv);
+-extern void via_release_futex(drm_via_private_t *dev_priv, int context);
++extern void via_init_futex(drm_via_private_t * dev_priv);
++extern void via_cleanup_futex(drm_via_private_t * dev_priv);
++extern void via_release_futex(drm_via_private_t * dev_priv, int context);
+ 
++extern int via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
++				    unsigned int size);
+ 
+ #endif
+diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
+--- a/drivers/char/drm/via_irq.c
++++ b/drivers/char/drm/via_irq.c
+@@ -54,23 +54,26 @@
+ /*
+  * Device-specific IRQs go here. This type might need to be extended with
+  * the register if there are multiple IRQ control registers.
+- * Currently we activate the HQV interrupts of  Unichrome Pro group A. 
++ * Currently we activate the HQV interrupts of  Unichrome Pro group A.
+  */
+ 
+ static maskarray_t via_pro_group_a_irqs[] = {
+-	{VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 0x00000000 },
+-	{VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 0x00000000 }};
+-static int via_num_pro_group_a = sizeof(via_pro_group_a_irqs)/sizeof(maskarray_t);
++	{VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010,
++	 0x00000000},
++	{VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010,
++	 0x00000000}
++};
++static int via_num_pro_group_a =
++    sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t);
+ 
+-static maskarray_t via_unichrome_irqs[] = {};
+-static int via_num_unichrome = sizeof(via_unichrome_irqs)/sizeof(maskarray_t);
++static maskarray_t via_unichrome_irqs[] = { };
++static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t);
+ 
+-
+-static unsigned time_diff(struct timeval *now,struct timeval *then) 
++static unsigned time_diff(struct timeval *now, struct timeval *then)
+ {
+-    return (now->tv_usec >= then->tv_usec) ?
+-        now->tv_usec - then->tv_usec :
+-        1000000 - (then->tv_usec - now->tv_usec);
++	return (now->tv_usec >= then->tv_usec) ?
++	    now->tv_usec - then->tv_usec :
++	    1000000 - (then->tv_usec - now->tv_usec);
+ }
+ 
+ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
+@@ -86,38 +89,37 @@ irqreturn_t via_driver_irq_handler(DRM_I
+ 	status = VIA_READ(VIA_REG_INTERRUPT);
+ 	if (status & VIA_IRQ_VBLANK_PENDING) {
+ 		atomic_inc(&dev->vbl_received);
+-                if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
++		if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
+ 			do_gettimeofday(&cur_vblank);
+-                        if (dev_priv->last_vblank_valid) {
+-				dev_priv->usec_per_vblank = 
+-					time_diff( &cur_vblank,&dev_priv->last_vblank) >> 4;
++			if (dev_priv->last_vblank_valid) {
++				dev_priv->usec_per_vblank =
++				    time_diff(&cur_vblank,
++					      &dev_priv->last_vblank) >> 4;
+ 			}
+ 			dev_priv->last_vblank = cur_vblank;
+ 			dev_priv->last_vblank_valid = 1;
+-                }
+-                if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
++		}
++		if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
+ 			DRM_DEBUG("US per vblank is: %u\n",
+-				dev_priv->usec_per_vblank);
++				  dev_priv->usec_per_vblank);
+ 		}
+ 		DRM_WAKEUP(&dev->vbl_queue);
+ 		drm_vbl_send_signals(dev);
+ 		handled = 1;
+ 	}
+-	
+ 
+-	for (i=0; i<dev_priv->num_irqs; ++i) {
++	for (i = 0; i < dev_priv->num_irqs; ++i) {
+ 		if (status & cur_irq->pending_mask) {
+-			atomic_inc( &cur_irq->irq_received );
+-			DRM_WAKEUP( &cur_irq->irq_queue );
++			atomic_inc(&cur_irq->irq_received);
++			DRM_WAKEUP(&cur_irq->irq_queue);
+ 			handled = 1;
+ 		}
+ 		cur_irq++;
+ 	}
+-	
++
+ 	/* Acknowlege interrupts */
+ 	VIA_WRITE(VIA_REG_INTERRUPT, status);
+ 
+-
+ 	if (handled)
+ 		return IRQ_HANDLED;
+ 	else
+@@ -131,7 +133,7 @@ static __inline__ void viadrv_acknowledg
+ 	if (dev_priv) {
+ 		/* Acknowlege interrupts */
+ 		status = VIA_READ(VIA_REG_INTERRUPT);
+-		VIA_WRITE(VIA_REG_INTERRUPT, status | 
++		VIA_WRITE(VIA_REG_INTERRUPT, status |
+ 			  dev_priv->irq_pending_mask);
+ 	}
+ }
+@@ -158,12 +160,12 @@ int via_driver_vblank_wait(drm_device_t 
+ 	DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+ 		    (((cur_vblank = atomic_read(&dev->vbl_received)) -
+ 		      *sequence) <= (1 << 23)));
+-	
++
+ 	*sequence = cur_vblank;
+ 	return ret;
+ }
+ 
+-static int 
++static int
+ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
+ 		    unsigned int *sequence)
+ {
+@@ -180,27 +182,29 @@ via_driver_irq_wait(drm_device_t * dev, 
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 
+-	if (irq >= dev_priv->num_irqs ) {
+-		DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irq);
++	if (irq >= dev_priv->num_irqs) {
++		DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
++			  irq);
+ 		return DRM_ERR(EINVAL);
+ 	}
+-		
++
+ 	cur_irq += irq;
+ 
+ 	if (masks[irq][2] && !force_sequence) {
+ 		DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
+-			    ((VIA_READ(masks[irq][2]) & masks[irq][3]) == masks[irq][4]));
++			    ((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
++			     masks[irq][4]));
+ 		cur_irq_sequence = atomic_read(&cur_irq->irq_received);
+ 	} else {
+ 		DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
+-			    (((cur_irq_sequence = atomic_read(&cur_irq->irq_received)) -
+-			      *sequence) <= (1 << 23)));		
++			    (((cur_irq_sequence =
++			       atomic_read(&cur_irq->irq_received)) -
++			      *sequence) <= (1 << 23)));
+ 	}
+ 	*sequence = cur_irq_sequence;
+ 	return ret;
+ }
+ 
+-
+ /*
+  * drm_dma.h hooks
+  */
+@@ -219,29 +223,29 @@ void via_driver_irq_preinstall(drm_devic
+ 		dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
+ 
+ 		dev_priv->irq_masks = (dev_priv->pro_group_a) ?
+-			via_pro_group_a_irqs : via_unichrome_irqs;
++		    via_pro_group_a_irqs : via_unichrome_irqs;
+ 		dev_priv->num_irqs = (dev_priv->pro_group_a) ?
+-			via_num_pro_group_a : via_num_unichrome;
+-		
+-		for(i=0; i < dev_priv->num_irqs; ++i) {
++		    via_num_pro_group_a : via_num_unichrome;
++
++		for (i = 0; i < dev_priv->num_irqs; ++i) {
+ 			atomic_set(&cur_irq->irq_received, 0);
+-			cur_irq->enable_mask = dev_priv->irq_masks[i][0]; 
++			cur_irq->enable_mask = dev_priv->irq_masks[i][0];
+ 			cur_irq->pending_mask = dev_priv->irq_masks[i][1];
+-			DRM_INIT_WAITQUEUE( &cur_irq->irq_queue );
++			DRM_INIT_WAITQUEUE(&cur_irq->irq_queue);
+ 			dev_priv->irq_enable_mask |= cur_irq->enable_mask;
+ 			dev_priv->irq_pending_mask |= cur_irq->pending_mask;
+ 			cur_irq++;
+-			
++
+ 			DRM_DEBUG("Initializing IRQ %d\n", i);
+ 		}
+-			
+-	        dev_priv->last_vblank_valid = 0;
++
++		dev_priv->last_vblank_valid = 0;
+ 
+ 		// Clear VSync interrupt regs
+ 		status = VIA_READ(VIA_REG_INTERRUPT);
+-		VIA_WRITE(VIA_REG_INTERRUPT, status & 
++		VIA_WRITE(VIA_REG_INTERRUPT, status &
+ 			  ~(dev_priv->irq_enable_mask));
+-		
++
+ 		/* Clear bits if they're already high */
+ 		viadrv_acknowledge_irqs(dev_priv);
+ 	}
+@@ -262,7 +266,7 @@ void via_driver_irq_postinstall(drm_devi
+ 
+ 		VIA_WRITE8(0x83d4, 0x11);
+ 		VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
+-		
++
+ 	}
+ }
+ 
+@@ -280,7 +284,7 @@ void via_driver_irq_uninstall(drm_device
+ 		VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
+ 
+ 		status = VIA_READ(VIA_REG_INTERRUPT);
+-		VIA_WRITE(VIA_REG_INTERRUPT, status & 
++		VIA_WRITE(VIA_REG_INTERRUPT, status &
+ 			  ~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask));
+ 	}
+ }
+@@ -302,7 +306,7 @@ int via_wait_irq(DRM_IOCTL_ARGS)
+ 
+ 	DRM_COPY_FROM_USER_IOCTL(irqwait, argp, sizeof(irqwait));
+ 	if (irqwait.request.irq >= dev_priv->num_irqs) {
+-		DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, 
++		DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
+ 			  irqwait.request.irq);
+ 		return DRM_ERR(EINVAL);
+ 	}
+@@ -320,7 +324,7 @@ int via_wait_irq(DRM_IOCTL_ARGS)
+ 	}
+ 
+ 	if (irqwait.request.type & VIA_IRQ_SIGNAL) {
+-		DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n", 
++		DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n",
+ 			  __FUNCTION__);
+ 		return DRM_ERR(EINVAL);
+ 	}
+diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
+--- a/drivers/char/drm/via_map.c
++++ b/drivers/char/drm/via_map.c
+@@ -66,7 +66,7 @@ static int via_do_init_map(drm_device_t 
+ 
+ 	dev_priv->agpAddr = init->agpAddr;
+ 
+-	via_init_futex( dev_priv );
++	via_init_futex(dev_priv);
+ 	dev_priv->pro_group_a = (dev->pdev->device == 0x3118);
+ 
+ 	dev->dev_private = (void *)dev_priv;
+@@ -107,5 +107,3 @@ int via_map_init(DRM_IOCTL_ARGS)
+ 
+ 	return -EINVAL;
+ }
+-
+-
+diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
+--- a/drivers/char/drm/via_mm.c
++++ b/drivers/char/drm/via_mm.c
+@@ -81,7 +81,8 @@ int via_agp_init(DRM_IOCTL_ARGS)
+ 
+ 	AgpHeap = via_mmInit(agp.offset, agp.size);
+ 
+-	DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset, (unsigned long)agp.size);
++	DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset,
++		  (unsigned long)agp.size);
+ 
+ 	return 0;
+ }
+@@ -97,7 +98,8 @@ int via_fb_init(DRM_IOCTL_ARGS)
+ 
+ 	FBHeap = via_mmInit(fb.offset, fb.size);
+ 
+-	DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset, (unsigned long)fb.size);
++	DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset,
++		  (unsigned long)fb.size);
+ 
+ 	return 0;
+ }
+@@ -134,8 +136,8 @@ int via_init_context(struct drm_device *
+ }
+ 
+ int via_final_context(struct drm_device *dev, int context)
+-{	
+-        int i;
++{
++	int i;
+ 	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ 
+ 	for (i = 0; i < MAX_CONTEXT; i++)
+@@ -171,14 +173,13 @@ int via_final_context(struct drm_device 
+ 		via_setDestroy(set);
+ 		global_ppriv[i].used = 0;
+ 	}
+-	via_release_futex(dev_priv, context); 
+-	
+-			
++	via_release_futex(dev_priv, context);
++
+ #if defined(__linux__)
+ 	/* Linux specific until context tracking code gets ported to BSD */
+ 	/* Last context, perform cleanup */
+ 	if (dev->ctx_count == 1 && dev->dev_private) {
+-	        DRM_DEBUG("Last Context\n");
++		DRM_DEBUG("Last Context\n");
+ 		if (dev->irq)
+ 			drm_irq_uninstall(dev);
+ 
+diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c
+--- a/drivers/char/drm/via_verifier.c
++++ b/drivers/char/drm/via_verifier.c
+@@ -28,7 +28,6 @@
+  * be very slow.
+  */
+ 
+-
+ #include "via_3d_reg.h"
+ #include "drmP.h"
+ #include "drm.h"
+@@ -36,7 +35,7 @@
+ #include "via_verifier.h"
+ #include "via_drv.h"
+ 
+-typedef enum{
++typedef enum {
+ 	state_command,
+ 	state_header2,
+ 	state_header1,
+@@ -45,8 +44,7 @@ typedef enum{
+ 	state_error
+ } verifier_state_t;
+ 
+-
+-typedef enum{
++typedef enum {
+ 	no_check = 0,
+ 	check_for_header2,
+ 	check_for_header1,
+@@ -74,16 +72,16 @@ typedef enum{
+ 	check_for_vertex_count,
+ 	check_number_texunits,
+ 	forbidden_command
+-}hazard_t;
++} hazard_t;
+ 
+ /*
+  * Associates each hazard above with a possible multi-command
+  * sequence. For example an address that is split over multiple
+- * commands and that needs to be checked at the first command 
++ * commands and that needs to be checked at the first command
+  * that does not include any part of the address.
+  */
+ 
+-static drm_via_sequence_t seqs[] = { 
++static drm_via_sequence_t seqs[] = {
+ 	no_sequence,
+ 	no_sequence,
+ 	no_sequence,
+@@ -110,14 +108,12 @@ static drm_via_sequence_t seqs[] = { 
+ 	tex_address,
+ 	no_sequence
+ };
+-    
+-typedef struct{
++
++typedef struct {
+ 	unsigned int code;
+ 	hazard_t hz;
+ } hz_init_t;
+ 
+-
+-
+ static hz_init_t init_table1[] = {
+ 	{0xf2, check_for_header2_err},
+ 	{0xf0, check_for_header1_err},
+@@ -169,8 +165,6 @@ static hz_init_t init_table1[] = {
+ 	{0x7D, check_for_vertex_count}
+ };
+ 
+-   
+-		       
+ static hz_init_t init_table2[] = {
+ 	{0xf2, check_for_header2_err},
+ 	{0xf0, check_for_header1_err},
+@@ -235,49 +229,49 @@ static hz_init_t init_table3[] = {
+ 	{0xcc, check_for_dummy},
+ 	{0x00, check_number_texunits}
+ };
+-   
+-		       
+-static hazard_t table1[256]; 
+-static hazard_t table2[256]; 
+-static hazard_t table3[256]; 
+-
+ 
++static hazard_t table1[256];
++static hazard_t table2[256];
++static hazard_t table3[256];
+ 
+ static __inline__ int
+-eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words)
++eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
+ {
+ 	if ((*buf - buf_end) >= num_words) {
+ 		*buf += num_words;
+ 		return 0;
+-	} 
++	}
+ 	DRM_ERROR("Illegal termination of DMA command buffer\n");
+ 	return 1;
+ }
+ 
+-
+ /*
+  * Partially stolen from drm_memory.h
+  */
+ 
+-static __inline__ drm_map_t *
+-via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned long size, 
+-			drm_device_t *dev)
++static __inline__ drm_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq,
++						    unsigned long offset,
++						    unsigned long size,
++						    drm_device_t * dev)
+ {
+ 	struct list_head *list;
+ 	drm_map_list_t *r_list;
+ 	drm_map_t *map = seq->map_cache;
+ 
+-	if (map && map->offset <= offset && (offset + size) <= (map->offset + map->size)) {
++	if (map && map->offset <= offset
++	    && (offset + size) <= (map->offset + map->size)) {
+ 		return map;
+ 	}
+-		
++
+ 	list_for_each(list, &dev->maplist->head) {
+ 		r_list = (drm_map_list_t *) list;
+ 		map = r_list->map;
+ 		if (!map)
+ 			continue;
+-		if (map->offset <= offset && (offset + size) <= (map->offset + map->size) && 
+-		    !(map->flags & _DRM_RESTRICTED) && (map->type == _DRM_AGP)) {
++		if (map->offset <= offset
++		    && (offset + size) <= (map->offset + map->size)
++		    && !(map->flags & _DRM_RESTRICTED)
++		    && (map->type == _DRM_AGP)) {
+ 			seq->map_cache = map;
+ 			return map;
+ 		}
+@@ -285,54 +279,60 @@ via_drm_lookup_agp_map (drm_via_state_t 
+ 	return NULL;
+ }
+ 
+-
+ /*
+- * Require that all AGP texture levels reside in the same AGP map which should 
++ * Require that all AGP texture levels reside in the same AGP map which should
+  * be mappable by the client. This is not a big restriction.
+- * FIXME: To actually enforce this security policy strictly, drm_rmmap 
+- * would have to wait for dma quiescent before removing an AGP map. 
++ * FIXME: To actually enforce this security policy strictly, drm_rmmap
++ * would have to wait for dma quiescent before removing an AGP map.
+  * The via_drm_lookup_agp_map call in reality seems to take
+  * very little CPU time.
+  */
+ 
+-
+-static __inline__ int
+-finish_current_sequence(drm_via_state_t *cur_seq) 
++static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq)
+ {
+-	switch(cur_seq->unfinished) {
++	switch (cur_seq->unfinished) {
+ 	case z_address:
+ 		DRM_DEBUG("Z Buffer start address is 0x%x\n", cur_seq->z_addr);
+ 		break;
+ 	case dest_address:
+-		DRM_DEBUG("Destination start address is 0x%x\n", cur_seq->d_addr);
++		DRM_DEBUG("Destination start address is 0x%x\n",
++			  cur_seq->d_addr);
+ 		break;
+ 	case tex_address:
+-		if (cur_seq->agp_texture) {			 
+-			unsigned start = cur_seq->tex_level_lo[cur_seq->texture];
++		if (cur_seq->agp_texture) {
++			unsigned start =
++			    cur_seq->tex_level_lo[cur_seq->texture];
+ 			unsigned end = cur_seq->tex_level_hi[cur_seq->texture];
+-			unsigned long lo=~0, hi=0, tmp;
++			unsigned long lo = ~0, hi = 0, tmp;
+ 			uint32_t *addr, *pitch, *height, tex;
+ 			unsigned i;
+ 
+-			if (end > 9) end = 9;
+-			if (start > 9) start = 9;
++			if (end > 9)
++				end = 9;
++			if (start > 9)
++				start = 9;
+ 
+-			addr =&(cur_seq->t_addr[tex = cur_seq->texture][start]);
++			addr =
++			    &(cur_seq->t_addr[tex = cur_seq->texture][start]);
+ 			pitch = &(cur_seq->pitch[tex][start]);
+ 			height = &(cur_seq->height[tex][start]);
+ 
+-			for (i=start; i<= end; ++i) {
++			for (i = start; i <= end; ++i) {
+ 				tmp = *addr++;
+-				if (tmp < lo) lo = tmp;
++				if (tmp < lo)
++					lo = tmp;
+ 				tmp += (*height++ << *pitch++);
+-				if (tmp > hi) hi = tmp;
++				if (tmp > hi)
++					hi = tmp;
+ 			}
+ 
+-			if (! via_drm_lookup_agp_map (cur_seq, lo, hi - lo, cur_seq->dev)) {
+-				DRM_ERROR("AGP texture is not in allowed map\n");
++			if (!via_drm_lookup_agp_map
++			    (cur_seq, lo, hi - lo, cur_seq->dev)) {
++				DRM_ERROR
++				    ("AGP texture is not in allowed map\n");
+ 				return 2;
+ 			}
+-		}	
++		}
+ 		break;
+ 	default:
+ 		break;
+@@ -341,73 +341,84 @@ finish_current_sequence(drm_via_state_t 
+ 	return 0;
+ }
+ 
+-static __inline__ int 
+-investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
++static __inline__ int
++investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq)
+ {
+ 	register uint32_t tmp, *tmp_addr;
+ 
+ 	if (cur_seq->unfinished && (cur_seq->unfinished != seqs[hz])) {
+ 		int ret;
+-		if ((ret = finish_current_sequence(cur_seq))) return ret;
++		if ((ret = finish_current_sequence(cur_seq)))
++			return ret;
+ 	}
+ 
+-	switch(hz) {
++	switch (hz) {
+ 	case check_for_header2:
+-		if (cmd == HALCYON_HEADER2) return 1;
++		if (cmd == HALCYON_HEADER2)
++			return 1;
+ 		return 0;
+ 	case check_for_header1:
+-		if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
++		if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
++			return 1;
+ 		return 0;
+ 	case check_for_header2_err:
+-		if (cmd == HALCYON_HEADER2) return 1;
++		if (cmd == HALCYON_HEADER2)
++			return 1;
+ 		DRM_ERROR("Illegal DMA HALCYON_HEADER2 command\n");
+ 		break;
+ 	case check_for_header1_err:
+-		if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
++		if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
++			return 1;
+ 		DRM_ERROR("Illegal DMA HALCYON_HEADER1 command\n");
+ 		break;
+ 	case check_for_fire:
+-		if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD) return 1; 
++		if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD)
++			return 1;
+ 		DRM_ERROR("Illegal DMA HALCYON_FIRECMD command\n");
+ 		break;
+ 	case check_for_dummy:
+-		if (HC_DUMMY == cmd) return 0;
++		if (HC_DUMMY == cmd)
++			return 0;
+ 		DRM_ERROR("Illegal DMA HC_DUMMY command\n");
+ 		break;
+ 	case check_for_dd:
+-		if (0xdddddddd == cmd) return 0;
++		if (0xdddddddd == cmd)
++			return 0;
+ 		DRM_ERROR("Illegal DMA 0xdddddddd command\n");
+ 		break;
+ 	case check_z_buffer_addr0:
+ 		cur_seq->unfinished = z_address;
+ 		cur_seq->z_addr = (cur_seq->z_addr & 0xFF000000) |
+-			(cmd & 0x00FFFFFF);
++		    (cmd & 0x00FFFFFF);
+ 		return 0;
+ 	case check_z_buffer_addr1:
+ 		cur_seq->unfinished = z_address;
+ 		cur_seq->z_addr = (cur_seq->z_addr & 0x00FFFFFF) |
+-			((cmd & 0xFF) << 24);
++		    ((cmd & 0xFF) << 24);
+ 		return 0;
+ 	case check_z_buffer_addr_mode:
+ 		cur_seq->unfinished = z_address;
+-		if ((cmd & 0x0000C000) == 0) return 0;
++		if ((cmd & 0x0000C000) == 0)
++			return 0;
+ 		DRM_ERROR("Attempt to place Z buffer in system memory\n");
+ 		return 2;
+ 	case check_destination_addr0:
+ 		cur_seq->unfinished = dest_address;
+ 		cur_seq->d_addr = (cur_seq->d_addr & 0xFF000000) |
+-			(cmd & 0x00FFFFFF);
++		    (cmd & 0x00FFFFFF);
+ 		return 0;
+ 	case check_destination_addr1:
+ 		cur_seq->unfinished = dest_address;
+ 		cur_seq->d_addr = (cur_seq->d_addr & 0x00FFFFFF) |
+-			((cmd & 0xFF) << 24);
++		    ((cmd & 0xFF) << 24);
+ 		return 0;
+ 	case check_destination_addr_mode:
+ 		cur_seq->unfinished = dest_address;
+-		if ((cmd & 0x0000C000) == 0) return 0;
+-		DRM_ERROR("Attempt to place 3D drawing buffer in system memory\n");
+-		return 2;	    
++		if ((cmd & 0x0000C000) == 0)
++			return 0;
++		DRM_ERROR
++		    ("Attempt to place 3D drawing buffer in system memory\n");
++		return 2;
+ 	case check_texture_addr0:
+ 		cur_seq->unfinished = tex_address;
+ 		tmp = (cmd >> 24);
+@@ -433,9 +444,11 @@ investigate_hazard( uint32_t cmd, hazard
+ 	case check_texture_addr3:
+ 		cur_seq->unfinished = tex_address;
+ 		tmp = ((cmd >> 24) - 0x2B);
+-		cur_seq->pitch[cur_seq->texture][tmp] = (cmd & 0x00F00000) >> 20;
++		cur_seq->pitch[cur_seq->texture][tmp] =
++		    (cmd & 0x00F00000) >> 20;
+ 		if (!tmp && (cmd & 0x000FFFFF)) {
+-			DRM_ERROR("Unimplemented texture level 0 pitch mode.\n");
++			DRM_ERROR
++			    ("Unimplemented texture level 0 pitch mode.\n");
+ 			return 2;
+ 		}
+ 		return 0;
+@@ -449,7 +462,7 @@ investigate_hazard( uint32_t cmd, hazard
+ 		cur_seq->unfinished = tex_address;
+ 		/*
+ 		 * Texture width. We don't care since we have the pitch.
+-		 */  
++		 */
+ 		return 0;
+ 	case check_texture_addr7:
+ 		cur_seq->unfinished = tex_address;
+@@ -465,25 +478,26 @@ investigate_hazard( uint32_t cmd, hazard
+ 		cur_seq->unfinished = tex_address;
+ 		tmp_addr = &(cur_seq->height[cur_seq->texture][0]);
+ 		tmp_addr[9] = 1 << ((cmd & 0x0000F000) >> 12);
+-	        tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8);
++		tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8);
+ 		tmp_addr[7] = 1 << ((cmd & 0x000000F0) >> 4);
+ 		tmp_addr[6] = 1 << (cmd & 0x0000000F);
+ 		return 0;
+ 	case check_texture_addr_mode:
+ 		cur_seq->unfinished = tex_address;
+-		if ( 2 == (tmp = cmd & 0x00000003)) {
+-			DRM_ERROR("Attempt to fetch texture from system memory.\n"); 
++		if (2 == (tmp = cmd & 0x00000003)) {
++			DRM_ERROR
++			    ("Attempt to fetch texture from system memory.\n");
+ 			return 2;
+ 		}
+ 		cur_seq->agp_texture = (tmp == 3);
+-		cur_seq->tex_palette_size[cur_seq->texture] = 
+-			(cmd >> 16) & 0x000000007;
++		cur_seq->tex_palette_size[cur_seq->texture] =
++		    (cmd >> 16) & 0x000000007;
+ 		return 0;
+ 	case check_for_vertex_count:
+ 		cur_seq->vertex_count = cmd & 0x0000FFFF;
+ 		return 0;
+ 	case check_number_texunits:
+-	        cur_seq->multitex = (cmd >> 3) & 1;
++		cur_seq->multitex = (cmd >> 3) & 1;
+ 		return 0;
+ 	default:
+ 		DRM_ERROR("Illegal DMA data: 0x%x\n", cmd);
+@@ -492,25 +506,27 @@ investigate_hazard( uint32_t cmd, hazard
+ 	return 2;
+ }
+ 
+-
+ static __inline__ int
+-via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
+-		    drm_via_state_t *cur_seq)
++via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end,
++		    drm_via_state_t * cur_seq)
+ {
+-	drm_via_private_t *dev_priv = (drm_via_private_t *) cur_seq->dev->dev_private;
+-	uint32_t a_fire, bcmd , dw_count;
++	drm_via_private_t *dev_priv =
++	    (drm_via_private_t *) cur_seq->dev->dev_private;
++	uint32_t a_fire, bcmd, dw_count;
+ 	int ret = 0;
+ 	int have_fire;
+ 	const uint32_t *buf = *buffer;
+ 
+-	while(buf < buf_end) {
+-	        have_fire = 0;
++	while (buf < buf_end) {
++		have_fire = 0;
+ 		if ((buf_end - buf) < 2) {
+-			DRM_ERROR("Unexpected termination of primitive list.\n");
++			DRM_ERROR
++			    ("Unexpected termination of primitive list.\n");
+ 			ret = 1;
+ 			break;
+ 		}
+-		if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB) break;
++		if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB)
++			break;
+ 		bcmd = *buf++;
+ 		if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdA) {
+ 			DRM_ERROR("Expected Vertex List A command, got 0x%x\n",
+@@ -518,43 +534,56 @@ via_check_prim_list(uint32_t const **buf
+ 			ret = 1;
+ 			break;
+ 		}
+-		a_fire = *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;	
+-	
++		a_fire =
++		    *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK |
++		    HC_HE3Fire_MASK;
++
+ 		/*
+ 		 * How many dwords per vertex ?
+-		 */ 
+-		
++		 */
++
+ 		if (cur_seq->agp && ((bcmd & (0xF << 11)) == 0)) {
+ 			DRM_ERROR("Illegal B command vertex data for AGP.\n");
+ 			ret = 1;
+ 			break;
+-		} 
++		}
+ 
+ 		dw_count = 0;
+-		if (bcmd & (1 << 7)) dw_count += (cur_seq->multitex) ? 2:1;
+-		if (bcmd & (1 << 8)) dw_count += (cur_seq->multitex) ? 2:1;
+-		if (bcmd & (1 << 9)) dw_count++;
+-		if (bcmd & (1 << 10)) dw_count++;
+-		if (bcmd & (1 << 11)) dw_count++;
+-		if (bcmd & (1 << 12)) dw_count++;
+-		if (bcmd & (1 << 13)) dw_count++;
+-		if (bcmd & (1 << 14)) dw_count++;
++		if (bcmd & (1 << 7))
++			dw_count += (cur_seq->multitex) ? 2 : 1;
++		if (bcmd & (1 << 8))
++			dw_count += (cur_seq->multitex) ? 2 : 1;
++		if (bcmd & (1 << 9))
++			dw_count++;
++		if (bcmd & (1 << 10))
++			dw_count++;
++		if (bcmd & (1 << 11))
++			dw_count++;
++		if (bcmd & (1 << 12))
++			dw_count++;
++		if (bcmd & (1 << 13))
++			dw_count++;
++		if (bcmd & (1 << 14))
++			dw_count++;
+ 
+-		while(buf < buf_end) {
++		while (buf < buf_end) {
+ 			if (*buf == a_fire) {
+-				if (dev_priv->num_fire_offsets >= VIA_FIRE_BUF_SIZE) {
++				if (dev_priv->num_fire_offsets >=
++				    VIA_FIRE_BUF_SIZE) {
+ 					DRM_ERROR("Fire offset buffer full.\n");
+ 					ret = 1;
+ 					break;
+ 				}
+-				dev_priv->fire_offsets[dev_priv->num_fire_offsets++] = buf;
+-			        have_fire = 1;
++				dev_priv->fire_offsets[dev_priv->
++						       num_fire_offsets++] =
++				    buf;
++				have_fire = 1;
+ 				buf++;
+-				if (buf < buf_end && *buf == a_fire) 
++				if (buf < buf_end && *buf == a_fire)
+ 					buf++;
+ 				break;
+ 			}
+-			if ((*buf == HALCYON_HEADER2) || 
++			if ((*buf == HALCYON_HEADER2) ||
+ 			    ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) {
+ 				DRM_ERROR("Missing Vertex Fire command, "
+ 					  "Stray Vertex Fire command  or verifier "
+@@ -576,18 +605,14 @@ via_check_prim_list(uint32_t const **buf
+ 			ret = 1;
+ 			break;
+ 		}
+-	} 
++	}
+ 	*buffer = buf;
+ 	return ret;
+ }
+ 
+-
+-		       
+-
+-
+ static __inline__ verifier_state_t
+-via_check_header2( uint32_t const **buffer, const uint32_t *buf_end, 
+-		   drm_via_state_t *hc_state)
++via_check_header2(uint32_t const **buffer, const uint32_t * buf_end,
++		  drm_via_state_t * hc_state)
+ {
+ 	uint32_t cmd;
+ 	int hz_mode;
+@@ -595,17 +620,17 @@ via_check_header2( uint32_t const **buff
+ 	const uint32_t *buf = *buffer;
+ 	const hazard_t *hz_table;
+ 
+-
+ 	if ((buf_end - buf) < 2) {
+-		DRM_ERROR("Illegal termination of DMA HALCYON_HEADER2 sequence.\n");
++		DRM_ERROR
++		    ("Illegal termination of DMA HALCYON_HEADER2 sequence.\n");
+ 		return state_error;
+ 	}
+ 	buf++;
+ 	cmd = (*buf++ & 0xFFFF0000) >> 16;
+ 
+-	switch(cmd) {
++	switch (cmd) {
+ 	case HC_ParaType_CmdVdata:
+-		if (via_check_prim_list(&buf, buf_end, hc_state )) 
++		if (via_check_prim_list(&buf, buf_end, hc_state))
+ 			return state_error;
+ 		*buffer = buf;
+ 		return state_command;
+@@ -650,13 +675,13 @@ via_check_header2( uint32_t const **buff
+ 		 */
+ 
+ 		DRM_ERROR("Invalid or unimplemented HALCYON_HEADER2 "
+-			  "DMA subcommand: 0x%x. Previous dword: 0x%x\n", 
+-			  cmd, *(buf -2));
++			  "DMA subcommand: 0x%x. Previous dword: 0x%x\n",
++			  cmd, *(buf - 2));
+ 		*buffer = buf;
+ 		return state_error;
+ 	}
+ 
+-	while(buf < buf_end) {
++	while (buf < buf_end) {
+ 		cmd = *buf++;
+ 		if ((hz = hz_table[cmd >> 24])) {
+ 			if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) {
+@@ -666,7 +691,7 @@ via_check_header2( uint32_t const **buff
+ 				}
+ 				return state_error;
+ 			}
+-		} else if (hc_state->unfinished && 
++		} else if (hc_state->unfinished &&
+ 			   finish_current_sequence(hc_state)) {
+ 			return state_error;
+ 		}
+@@ -679,64 +704,65 @@ via_check_header2( uint32_t const **buff
+ }
+ 
+ static __inline__ verifier_state_t
+-via_parse_header2( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end,
+-		   int *fire_count)
++via_parse_header2(drm_via_private_t * dev_priv, uint32_t const **buffer,
++		  const uint32_t * buf_end, int *fire_count)
+ {
+ 	uint32_t cmd;
+ 	const uint32_t *buf = *buffer;
+-	const uint32_t *next_fire; 
++	const uint32_t *next_fire;
+ 	int burst = 0;
+ 
+ 	next_fire = dev_priv->fire_offsets[*fire_count];
+ 	buf++;
+ 	cmd = (*buf & 0xFFFF0000) >> 16;
+ 	VIA_WRITE(HC_REG_TRANS_SET + HC_REG_BASE, *buf++);
+-	switch(cmd) {
++	switch (cmd) {
+ 	case HC_ParaType_CmdVdata:
+ 		while ((buf < buf_end) &&
+-		       (*fire_count < dev_priv->num_fire_offsets) && 
+-		       (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB ) {
+-			while(buf <= next_fire) {
+-				VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
++		       (*fire_count < dev_priv->num_fire_offsets) &&
++		       (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB) {
++			while (buf <= next_fire) {
++				VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE +
++					  (burst & 63), *buf++);
+ 				burst += 4;
+ 			}
+-			if ( ( buf < buf_end ) && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD))
++			if ((buf < buf_end)
++			    && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD))
+ 				buf++;
+ 
+-			if (++(*fire_count) < dev_priv->num_fire_offsets) 
++			if (++(*fire_count) < dev_priv->num_fire_offsets)
+ 				next_fire = dev_priv->fire_offsets[*fire_count];
+ 		}
+ 		break;
+ 	default:
+-		while(buf < buf_end) {
+-			
+-			if ( *buf == HC_HEADER2 ||
+-			     (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1  ||
+-			     (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 ||
+-			     (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6 ) break;
+-			
+-			VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
+-			burst +=4;
++		while (buf < buf_end) {
++
++			if (*buf == HC_HEADER2 ||
++			    (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 ||
++			    (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 ||
++			    (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
++				break;
++
++			VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE +
++				  (burst & 63), *buf++);
++			burst += 4;
+ 		}
+ 	}
+ 	*buffer = buf;
+ 	return state_command;
+ }
+ 
+-
+-
+-static __inline__ int
+-verify_mmio_address( uint32_t address)
++static __inline__ int verify_mmio_address(uint32_t address)
+ {
+-	if ((address > 0x3FF) && (address < 0xC00 )) {
++	if ((address > 0x3FF) && (address < 0xC00)) {
+ 		DRM_ERROR("Invalid VIDEO DMA command. "
+ 			  "Attempt to access 3D- or command burst area.\n");
+ 		return 1;
+ 	} else if ((address > 0xCFF) && (address < 0x1300)) {
+ 		DRM_ERROR("Invalid VIDEO DMA command. "
+ 			  "Attempt to access PCI DMA area.\n");
+-		return 1;		
+-	} else if (address > 0x13FF ) {
++		return 1;
++	} else if (address > 0x13FF) {
+ 		DRM_ERROR("Invalid VIDEO DMA command. "
+ 			  "Attempt to access VGA registers.\n");
+ 		return 1;
+@@ -745,7 +771,8 @@ verify_mmio_address( uint32_t address)
+ }
+ 
+ static __inline__ int
+-verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dwords) 
++verify_video_tail(uint32_t const **buffer, const uint32_t * buf_end,
++		  uint32_t dwords)
+ {
+ 	const uint32_t *buf = *buffer;
+ 
+@@ -762,10 +789,9 @@ verify_video_tail( uint32_t const **buff
+ 	*buffer = buf;
+ 	return 0;
+ }
+-		
+ 
+ static __inline__ verifier_state_t
+-via_check_header1( uint32_t const **buffer, const uint32_t *buf_end )
++via_check_header1(uint32_t const **buffer, const uint32_t * buf_end)
+ {
+ 	uint32_t cmd;
+ 	const uint32_t *buf = *buffer;
+@@ -774,21 +800,21 @@ via_check_header1( uint32_t const **buff
+ 	while (buf < buf_end) {
+ 		cmd = *buf;
+ 		if ((cmd > ((0x3FF >> 2) | HALCYON_HEADER1)) &&
+-		    (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) {			
+-			if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) 
++		    (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) {
++			if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
+ 				break;
+ 			DRM_ERROR("Invalid HALCYON_HEADER1 command. "
+ 				  "Attempt to access 3D- or command burst area.\n");
+ 			ret = state_error;
+ 			break;
+ 		} else if (cmd > ((0xCFF >> 2) | HALCYON_HEADER1)) {
+-			if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) 
++			if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
+ 				break;
+ 			DRM_ERROR("Invalid HALCYON_HEADER1 command. "
+ 				  "Attempt to access VGA registers.\n");
+ 			ret = state_error;
+-			break;			
+-		} else {			
++			break;
++		} else {
+ 			buf += 2;
+ 		}
+ 	}
+@@ -797,15 +823,17 @@ via_check_header1( uint32_t const **buff
+ }
+ 
+ static __inline__ verifier_state_t
+-via_parse_header1( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
++via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer,
++		  const uint32_t * buf_end)
+ {
+ 	register uint32_t cmd;
+ 	const uint32_t *buf = *buffer;
+ 
+ 	while (buf < buf_end) {
+ 		cmd = *buf;
+-		if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) break;
+-		VIA_WRITE( (cmd & ~HALCYON_HEADER1MASK) << 2, *++buf); 
++		if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
++			break;
++		VIA_WRITE((cmd & ~HALCYON_HEADER1MASK) << 2, *++buf);
+ 		buf++;
+ 	}
+ 	*buffer = buf;
+@@ -813,7 +841,7 @@ via_parse_header1( drm_via_private_t *de
+ }
+ 
+ static __inline__ verifier_state_t
+-via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end )
++via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end)
+ {
+ 	uint32_t data;
+ 	const uint32_t *buf = *buffer;
+@@ -836,41 +864,41 @@ via_check_vheader5( uint32_t const **buf
+ 		DRM_ERROR("Illegal header5 header data\n");
+ 		return state_error;
+ 	}
+-	if (eat_words(&buf, buf_end, data)) 
++	if (eat_words(&buf, buf_end, data))
+ 		return state_error;
+-	if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3))) 
++	if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
+ 		return state_error;
+ 	*buffer = buf;
+ 	return state_command;
+-	       
+-} 
++
++}
+ 
+ static __inline__ verifier_state_t
+-via_parse_vheader5( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
++via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer,
++		   const uint32_t * buf_end)
+ {
+-  uint32_t addr, count, i;
++	uint32_t addr, count, i;
+ 	const uint32_t *buf = *buffer;
+-	
++
+ 	addr = *buf++ & ~VIA_VIDEOMASK;
+ 	i = count = *buf;
+ 	buf += 3;
+-	while(i--) {
++	while (i--) {
+ 		VIA_WRITE(addr, *buf++);
+ 	}
+-	if (count & 3) buf += 4 - (count & 3);
++	if (count & 3)
++		buf += 4 - (count & 3);
+ 	*buffer = buf;
+-	return state_command;	       
+-} 
+-
++	return state_command;
++}
+ 
+ static __inline__ verifier_state_t
+-via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end )
++via_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end)
+ {
+ 	uint32_t data;
+ 	const uint32_t *buf = *buffer;
+ 	uint32_t i;
+ 
+-
+ 	if (buf_end - buf < 4) {
+ 		DRM_ERROR("Illegal termination of video header6 command\n");
+ 		return state_error;
+@@ -889,7 +917,7 @@ via_check_vheader6( uint32_t const **buf
+ 		DRM_ERROR("Illegal termination of video header6 command\n");
+ 		return state_error;
+ 	}
+-	for (i=0; i<data; ++i) {
++	for (i = 0; i < data; ++i) {
+ 		if (verify_mmio_address(*buf++))
+ 			return state_error;
+ 		buf++;
+@@ -899,42 +927,42 @@ via_check_vheader6( uint32_t const **buf
+ 		return state_error;
+ 	*buffer = buf;
+ 	return state_command;
+-} 
++}
+ 
+ static __inline__ verifier_state_t
+-via_parse_vheader6( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
++via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer,
++		   const uint32_t * buf_end)
+ {
+ 
+-  uint32_t addr, count, i;
++	uint32_t addr, count, i;
+ 	const uint32_t *buf = *buffer;
+ 
+ 	i = count = *++buf;
+ 	buf += 3;
+-	while(i--) {
++	while (i--) {
+ 		addr = *buf++;
+ 		VIA_WRITE(addr, *buf++);
+ 	}
+ 	count <<= 1;
+-	if (count & 3) buf += 4 - (count & 3);
++	if (count & 3)
++		buf += 4 - (count & 3);
+ 	*buffer = buf;
+ 	return state_command;
+-} 
+-
+-
++}
+ 
+-int 
+-via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t *dev,
+-			  int agp)
++int
++via_verify_command_stream(const uint32_t * buf, unsigned int size,
++			  drm_device_t * dev, int agp)
+ {
+ 
+ 	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ 	drm_via_state_t *hc_state = &dev_priv->hc_state;
+ 	drm_via_state_t saved_state = *hc_state;
+ 	uint32_t cmd;
+-	const uint32_t *buf_end = buf + ( size >> 2 );
++	const uint32_t *buf_end = buf + (size >> 2);
+ 	verifier_state_t state = state_command;
+ 	int pro_group_a = dev_priv->pro_group_a;
+-	
++
+ 	hc_state->dev = dev;
+ 	hc_state->unfinished = no_sequence;
+ 	hc_state->map_cache = NULL;
+@@ -946,38 +974,41 @@ via_verify_command_stream(const uint32_t
+ 
+ 		switch (state) {
+ 		case state_header2:
+-		  state = via_check_header2( &buf, buf_end, hc_state );
++			state = via_check_header2(&buf, buf_end, hc_state);
+ 			break;
+ 		case state_header1:
+-			state = via_check_header1( &buf, buf_end );
++			state = via_check_header1(&buf, buf_end);
+ 			break;
+ 		case state_vheader5:
+-			state = via_check_vheader5( &buf, buf_end );
++			state = via_check_vheader5(&buf, buf_end);
+ 			break;
+ 		case state_vheader6:
+-			state = via_check_vheader6( &buf, buf_end );
++			state = via_check_vheader6(&buf, buf_end);
+ 			break;
+ 		case state_command:
+-			if (HALCYON_HEADER2 == (cmd = *buf)) 
++			if (HALCYON_HEADER2 == (cmd = *buf))
+ 				state = state_header2;
+-			else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) 
++			else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
+ 				state = state_header1;
+-			else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
++			else if (pro_group_a
++				 && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
+ 				state = state_vheader5;
+-			else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
++			else if (pro_group_a
++				 && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
+ 				state = state_vheader6;
+ 			else {
+-				DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
+-					  cmd);
++				DRM_ERROR
++				    ("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
++				     cmd);
+ 				state = state_error;
+ 			}
+ 			break;
+ 		case state_error:
+ 		default:
+ 			*hc_state = saved_state;
+-			return DRM_ERR(EINVAL);			
++			return DRM_ERR(EINVAL);
+ 		}
+-	}	
++	}
+ 	if (state == state_error) {
+ 		*hc_state = saved_state;
+ 		return DRM_ERR(EINVAL);
+@@ -985,77 +1016,81 @@ via_verify_command_stream(const uint32_t
+ 	return 0;
+ }
+ 
+-int 
+-via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size)
++int
++via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
++			 unsigned int size)
+ {
+ 
+ 	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ 	uint32_t cmd;
+-	const uint32_t *buf_end = buf + ( size >> 2 );
++	const uint32_t *buf_end = buf + (size >> 2);
+ 	verifier_state_t state = state_command;
+ 	int fire_count = 0;
+-	
++
+ 	while (buf < buf_end) {
+ 
+ 		switch (state) {
+ 		case state_header2:
+-		  state = via_parse_header2( dev_priv, &buf, buf_end, &fire_count );
++			state =
++			    via_parse_header2(dev_priv, &buf, buf_end,
++					      &fire_count);
+ 			break;
+ 		case state_header1:
+-			state = via_parse_header1( dev_priv, &buf, buf_end );
++			state = via_parse_header1(dev_priv, &buf, buf_end);
+ 			break;
+ 		case state_vheader5:
+-			state = via_parse_vheader5( dev_priv, &buf, buf_end );
++			state = via_parse_vheader5(dev_priv, &buf, buf_end);
+ 			break;
+ 		case state_vheader6:
+-			state = via_parse_vheader6( dev_priv, &buf, buf_end );
++			state = via_parse_vheader6(dev_priv, &buf, buf_end);
+ 			break;
+ 		case state_command:
+-			if (HALCYON_HEADER2 == (cmd = *buf)) 
++			if (HALCYON_HEADER2 == (cmd = *buf))
+ 				state = state_header2;
+-			else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) 
++			else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
+ 				state = state_header1;
+ 			else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
+ 				state = state_vheader5;
+ 			else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
+ 				state = state_vheader6;
+ 			else {
+-				DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
+-					  cmd);
++				DRM_ERROR
++				    ("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
++				     cmd);
+ 				state = state_error;
+ 			}
+ 			break;
+ 		case state_error:
+ 		default:
+-			return DRM_ERR(EINVAL);			
++			return DRM_ERR(EINVAL);
+ 		}
+-	}	
++	}
+ 	if (state == state_error) {
+ 		return DRM_ERR(EINVAL);
+ 	}
+ 	return 0;
+ }
+ 
+-
+-
+-static void 
++static void
+ setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size)
+ {
+ 	int i;
+ 
+-	for(i=0; i<256; ++i) {
++	for (i = 0; i < 256; ++i) {
+ 		table[i] = forbidden_command;
+ 	}
+ 
+-	for(i=0; i<size; ++i) {
++	for (i = 0; i < size; ++i) {
+ 		table[init_table[i].code] = init_table[i].hz;
+ 	}
+ }
+ 
+-void 
+-via_init_command_verifier( void )
++void via_init_command_verifier(void)
+ {
+-	setup_hazard_table(init_table1, table1, sizeof(init_table1) / sizeof(hz_init_t));
+-	setup_hazard_table(init_table2, table2, sizeof(init_table2) / sizeof(hz_init_t));
+-	setup_hazard_table(init_table3, table3, sizeof(init_table3) / sizeof(hz_init_t));
++	setup_hazard_table(init_table1, table1,
++			   sizeof(init_table1) / sizeof(hz_init_t));
++	setup_hazard_table(init_table2, table2,
++			   sizeof(init_table2) / sizeof(hz_init_t));
++	setup_hazard_table(init_table3, table3,
++			   sizeof(init_table3) / sizeof(hz_init_t));
+ }
+diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
+--- a/drivers/char/drm/via_verifier.h
++++ b/drivers/char/drm/via_verifier.h
+@@ -26,23 +26,21 @@
+ #ifndef _VIA_VERIFIER_H_
+ #define _VIA_VERIFIER_H_
+ 
+-typedef enum{
+-	no_sequence = 0, 
++typedef enum {
++	no_sequence = 0,
+ 	z_address,
+ 	dest_address,
+ 	tex_address
+-}drm_via_sequence_t;
++} drm_via_sequence_t;
+ 
+-
+-
+-typedef struct{
++typedef struct {
+ 	unsigned texture;
+-	uint32_t z_addr; 
+-	uint32_t d_addr; 
+-        uint32_t t_addr[2][10];
++	uint32_t z_addr;
++	uint32_t d_addr;
++	uint32_t t_addr[2][10];
+ 	uint32_t pitch[2][10];
+ 	uint32_t height[2][10];
+-	uint32_t tex_level_lo[2]; 
++	uint32_t tex_level_lo[2];
+ 	uint32_t tex_level_hi[2];
+ 	uint32_t tex_palette_size[2];
+ 	drm_via_sequence_t unfinished;
+@@ -55,7 +53,7 @@ typedef struct{
+ 	const uint32_t *buf_start;
+ } drm_via_state_t;
+ 
+-extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, 
+-				     drm_device_t *dev, int agp);
++extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
++				     drm_device_t * dev, int agp);
+ 
+ #endif
+diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c
+--- a/drivers/char/drm/via_video.c
++++ b/drivers/char/drm/via_video.c
+@@ -29,8 +29,7 @@
+ #include "via_drm.h"
+ #include "via_drv.h"
+ 
+-void
+-via_init_futex(drm_via_private_t *dev_priv)
++void via_init_futex(drm_via_private_t * dev_priv)
+ {
+ 	unsigned int i;
+ 
+@@ -42,30 +41,28 @@ via_init_futex(drm_via_private_t *dev_pr
+ 	}
+ }
+ 
+-void
+-via_cleanup_futex(drm_via_private_t *dev_priv)
++void via_cleanup_futex(drm_via_private_t * dev_priv)
+ {
+-}	
++}
+ 
+-void
+-via_release_futex(drm_via_private_t *dev_priv, int context)
++void via_release_futex(drm_via_private_t * dev_priv, int context)
+ {
+ 	unsigned int i;
+ 	volatile int *lock;
+ 
+-	for (i=0; i < VIA_NR_XVMC_LOCKS; ++i) {
+-	        lock = (int *) XVMCLOCKPTR(dev_priv->sarea_priv, i);
+-		if ( (_DRM_LOCKING_CONTEXT( *lock ) == context)) {
+-			if (_DRM_LOCK_IS_HELD( *lock ) && (*lock & _DRM_LOCK_CONT)) {
+-				DRM_WAKEUP( &(dev_priv->decoder_queue[i]));
++	for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
++		lock = (int *)XVMCLOCKPTR(dev_priv->sarea_priv, i);
++		if ((_DRM_LOCKING_CONTEXT(*lock) == context)) {
++			if (_DRM_LOCK_IS_HELD(*lock)
++			    && (*lock & _DRM_LOCK_CONT)) {
++				DRM_WAKEUP(&(dev_priv->decoder_queue[i]));
+ 			}
+ 			*lock = 0;
+ 		}
+-	}	
+-}	
++	}
++}
+ 
+-int 
+-via_decoder_futex(DRM_IOCTL_ARGS)
++int via_decoder_futex(DRM_IOCTL_ARGS)
+ {
+ 	DRM_DEVICE;
+ 	drm_via_futex_t fx;
+@@ -95,4 +92,3 @@ via_decoder_futex(DRM_IOCTL_ARGS)
+ 	}
+ 	return 0;
+ }
+-
+diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
+--- a/drivers/char/dsp56k.c
++++ b/drivers/char/dsp56k.c
+@@ -515,7 +515,7 @@ static int __init dsp56k_init_driver(voi
+ 		err = PTR_ERR(dsp56k_class);
+ 		goto out_chrdev;
+ 	}
+-	class_device_create(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
++	class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
+ 
+ 	err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0),
+ 		      S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k");
+diff --git a/drivers/char/epca.c b/drivers/char/epca.c
+--- a/drivers/char/epca.c
++++ b/drivers/char/epca.c
+@@ -3113,6 +3113,7 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
+ int __init init_PCI (void)
+ {	/* Begin init_PCI */
+ 	memset (&epca_driver, 0, sizeof (epca_driver));
++	epca_driver.owner = THIS_MODULE;
+ 	epca_driver.name = "epca";
+ 	epca_driver.id_table = epca_pci_tbl;
+ 	epca_driver.probe = epca_init_one;
+diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
+--- a/drivers/char/ftape/zftape/zftape-init.c
++++ b/drivers/char/ftape/zftape/zftape-init.c
+@@ -331,27 +331,27 @@ KERN_INFO
+ 
+ 	zft_class = class_create(THIS_MODULE, "zft");
+ 	for (i = 0; i < 4; i++) {
+-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
++		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
+ 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i),
+ 				S_IFCHR | S_IRUSR | S_IWUSR,
+ 				"qft%i", i);
+-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
++		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
+ 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4),
+ 				S_IFCHR | S_IRUSR | S_IWUSR,
+ 				"nqft%i", i);
+-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
++		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
+ 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16),
+ 				S_IFCHR | S_IRUSR | S_IWUSR,
+ 				"zqft%i", i);
+-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
++		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
+ 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20),
+ 				S_IFCHR | S_IRUSR | S_IWUSR,
+ 				"nzqft%i", i);
+-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
++		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
+ 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32),
+ 				S_IFCHR | S_IRUSR | S_IWUSR,
+ 				"rawqft%i", i);
+-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
++		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
+ 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36),
+ 				S_IFCHR | S_IRUSR | S_IWUSR,
+ 				"nrawqft%i", i);
+diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
+--- a/drivers/char/hangcheck-timer.c
++++ b/drivers/char/hangcheck-timer.c
+@@ -117,7 +117,7 @@ __setup("hcheck_reboot", hangcheck_parse
+ __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks);
+ #endif /* not MODULE */
+ 
+-#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
++#if defined(CONFIG_X86)
+ # define HAVE_MONOTONIC
+ # define TIMER_FREQ 1000000000ULL
+ #elif defined(CONFIG_ARCH_S390)
+diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
+--- a/drivers/char/hpet.c
++++ b/drivers/char/hpet.c
+@@ -49,7 +49,9 @@
+ #define	HPET_USER_FREQ	(64)
+ #define	HPET_DRIFT	(500)
+ 
+-static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
++#define HPET_RANGE_SIZE		1024	/* from HPET spec */
++
++static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
+ 
+ /* A lock for concurrent access by app and isr hpet activity. */
+ static DEFINE_SPINLOCK(hpet_lock);
+@@ -78,7 +80,7 @@ struct hpets {
+ 	struct hpet __iomem *hp_hpet;
+ 	unsigned long hp_hpet_phys;
+ 	struct time_interpolator *hp_interpolator;
+-	unsigned long hp_period;
++	unsigned long long hp_tick_freq;
+ 	unsigned long hp_delta;
+ 	unsigned int hp_ntimer;
+ 	unsigned int hp_which;
+@@ -90,6 +92,7 @@ static struct hpets *hpets;
+ #define	HPET_OPEN		0x0001
+ #define	HPET_IE			0x0002	/* interrupt enabled */
+ #define	HPET_PERIODIC		0x0004
++#define	HPET_SHARED_IRQ		0x0008
+ 
+ #if BITS_PER_LONG == 64
+ #define	write_counter(V, MC)	writeq(V, MC)
+@@ -120,6 +123,11 @@ static irqreturn_t hpet_interrupt(int ir
+ 	unsigned long isr;
+ 
+ 	devp = data;
++	isr = 1 << (devp - devp->hd_hpets->hp_dev);
++
++	if ((devp->hd_flags & HPET_SHARED_IRQ) &&
++	    !(isr & readl(&devp->hd_hpet->hpet_isr)))
++		return IRQ_NONE;
+ 
+ 	spin_lock(&hpet_lock);
+ 	devp->hd_irqdata++;
+@@ -137,8 +145,8 @@ static irqreturn_t hpet_interrupt(int ir
+ 			      &devp->hd_timer->hpet_compare);
+ 	}
+ 
+-	isr = (1 << (devp - devp->hd_hpets->hp_dev));
+-	writeq(isr, &devp->hd_hpet->hpet_isr);
++	if (devp->hd_flags & HPET_SHARED_IRQ)
++		writel(isr, &devp->hd_hpet->hpet_isr);
+ 	spin_unlock(&hpet_lock);
+ 
+ 	spin_lock(&hpet_task_lock);
+@@ -276,7 +284,8 @@ static int hpet_mmap(struct file *file, 
+ 
+ 	if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
+ 					PAGE_SIZE, vma->vm_page_prot)) {
+-		printk(KERN_ERR "remap_pfn_range failed in hpet.c\n");
++		printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
++			__FUNCTION__);
+ 		return -EAGAIN;
+ 	}
+ 
+@@ -364,7 +373,9 @@ static int hpet_ioctl_ieon(struct hpet_d
+ 	hpet = devp->hd_hpet;
+ 	hpetp = devp->hd_hpets;
+ 
+-	v = readq(&timer->hpet_config);
++	if (!devp->hd_ireqfreq)
++		return -EIO;
++
+ 	spin_lock_irq(&hpet_lock);
+ 
+ 	if (devp->hd_flags & HPET_IE) {
+@@ -373,16 +384,21 @@ static int hpet_ioctl_ieon(struct hpet_d
+ 	}
+ 
+ 	devp->hd_flags |= HPET_IE;
++
++	if (readl(&timer->hpet_config) & Tn_INT_TYPE_CNF_MASK)
++		devp->hd_flags |= HPET_SHARED_IRQ;
+ 	spin_unlock_irq(&hpet_lock);
+ 
+-	t = readq(&timer->hpet_config);
+ 	irq = devp->hd_hdwirq;
+ 
+ 	if (irq) {
+-		sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
++		unsigned long irq_flags;
+ 
+-		if (request_irq
+-		    (irq, hpet_interrupt, SA_INTERRUPT, devp->hd_name, (void *)devp)) {
++		sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
++		irq_flags = devp->hd_flags & HPET_SHARED_IRQ
++						? SA_SHIRQ : SA_INTERRUPT;
++		if (request_irq(irq, hpet_interrupt, irq_flags,
++				devp->hd_name, (void *)devp)) {
+ 			printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
+ 			irq = 0;
+ 		}
+@@ -416,20 +432,24 @@ static int hpet_ioctl_ieon(struct hpet_d
+ 		write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
+ 	}
+ 
+-	isr = (1 << (devp - hpets->hp_dev));
+-	writeq(isr, &hpet->hpet_isr);
++	if (devp->hd_flags & HPET_SHARED_IRQ) {
++		isr = 1 << (devp - devp->hd_hpets->hp_dev);
++		writel(isr, &hpet->hpet_isr);
++	}
+ 	writeq(g, &timer->hpet_config);
+ 	local_irq_restore(flags);
+ 
+ 	return 0;
+ }
+ 
+-static inline unsigned long hpet_time_div(unsigned long dis)
++/* converts Hz to number of timer ticks */
++static inline unsigned long hpet_time_div(struct hpets *hpets,
++					  unsigned long dis)
+ {
+-	unsigned long long m = 1000000000000000ULL;
++	unsigned long long m;
+ 
++	m = hpets->hp_tick_freq + (dis >> 1);
+ 	do_div(m, dis);
+-
+ 	return (unsigned long)m;
+ }
+ 
+@@ -477,14 +497,21 @@ hpet_ioctl_common(struct hpet_dev *devp,
+ 		{
+ 			struct hpet_info info;
+ 
+-			info.hi_ireqfreq = hpet_time_div(hpetp->hp_period *
+-							 devp->hd_ireqfreq);
++			if (devp->hd_ireqfreq)
++				info.hi_ireqfreq =
++					hpet_time_div(hpetp, devp->hd_ireqfreq);
++			else
++				info.hi_ireqfreq = 0;
+ 			info.hi_flags =
+ 			    readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK;
+-			info.hi_hpet = devp->hd_hpets->hp_which;
+-			info.hi_timer = devp - devp->hd_hpets->hp_dev;
+-			if (copy_to_user((void __user *)arg, &info, sizeof(info)))
+-				err = -EFAULT;
++			info.hi_hpet = hpetp->hp_which;
++			info.hi_timer = devp - hpetp->hp_dev;
++			if (kernel)
++				memcpy((void *)arg, &info, sizeof(info));
++			else
++				if (copy_to_user((void __user *)arg, &info,
++						 sizeof(info)))
++					err = -EFAULT;
+ 			break;
+ 		}
+ 	case HPET_EPI:
+@@ -516,12 +543,12 @@ hpet_ioctl_common(struct hpet_dev *devp,
+ 			break;
+ 		}
+ 
+-		if (arg & (arg - 1)) {
++		if (!arg) {
+ 			err = -EINVAL;
+ 			break;
+ 		}
+ 
+-		devp->hd_ireqfreq = hpet_time_div(hpetp->hp_period * arg);
++		devp->hd_ireqfreq = hpet_time_div(hpetp, arg);
+ 	}
+ 
+ 	return err;
+@@ -539,6 +566,17 @@ static struct file_operations hpet_fops 
+ 	.mmap = hpet_mmap,
+ };
+ 
++static int hpet_is_known(struct hpet_data *hdp)
++{
++	struct hpets *hpetp;
++
++	for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
++		if (hpetp->hp_hpet_phys == hdp->hd_phys_address)
++			return 1;
++
++	return 0;
++}
++
+ EXPORT_SYMBOL(hpet_alloc);
+ EXPORT_SYMBOL(hpet_register);
+ EXPORT_SYMBOL(hpet_unregister);
+@@ -563,6 +601,8 @@ int hpet_register(struct hpet_task *tp, 
+ 		return -EINVAL;
+ 	}
+ 
++	tp->ht_opaque = NULL;
++
+ 	spin_lock_irq(&hpet_task_lock);
+ 	spin_lock(&hpet_lock);
+ 
+@@ -702,15 +742,14 @@ static void hpet_register_interpolator(s
+ #ifdef	CONFIG_TIME_INTERPOLATION
+ 	struct time_interpolator *ti;
+ 
+-	ti = kmalloc(sizeof(*ti), GFP_KERNEL);
++	ti = kzalloc(sizeof(*ti), GFP_KERNEL);
+ 	if (!ti)
+ 		return;
+ 
+-	memset(ti, 0, sizeof(*ti));
+ 	ti->source = TIME_SOURCE_MMIO64;
+ 	ti->shift = 10;
+ 	ti->addr = &hpetp->hp_hpet->hpet_mc;
+-	ti->frequency = hpet_time_div(hpets->hp_period);
++	ti->frequency = hpetp->hp_tick_freq;
+ 	ti->drift = HPET_DRIFT;
+ 	ti->mask = -1;
+ 
+@@ -743,11 +782,11 @@ static unsigned long hpet_calibrate(stru
+ 	if (!timer)
+ 		return 0;
+ 
+-	hpet = hpets->hp_hpet;
++	hpet = hpetp->hp_hpet;
+ 	t = read_counter(&timer->hpet_compare);
+ 
+ 	i = 0;
+-	count = hpet_time_div(hpetp->hp_period * TICK_CALIBRATE);
++	count = hpet_time_div(hpetp, TICK_CALIBRATE);
+ 
+ 	local_irq_save(flags);
+ 
+@@ -771,28 +810,29 @@ int hpet_alloc(struct hpet_data *hdp)
+ 	struct hpets *hpetp;
+ 	size_t siz;
+ 	struct hpet __iomem *hpet;
+-	static struct hpets *last = (struct hpets *)0;
+-	unsigned long ns;
++	static struct hpets *last = NULL;
++	unsigned long period;
++	unsigned long long temp;
+ 
+ 	/*
+ 	 * hpet_alloc can be called by platform dependent code.
+-	 * if platform dependent code has allocated the hpet
+-	 * ACPI also reports hpet, then we catch it here.
++	 * If platform dependent code has allocated the hpet that
++	 * ACPI has also reported, then we catch it here.
+ 	 */
+-	for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
+-		if (hpetp->hp_hpet == hdp->hd_address)
+-			return 0;
++	if (hpet_is_known(hdp)) {
++		printk(KERN_DEBUG "%s: duplicate HPET ignored\n",
++			__FUNCTION__);
++		return 0;
++	}
+ 
+ 	siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
+ 				      sizeof(struct hpet_dev));
+ 
+-	hpetp = kmalloc(siz, GFP_KERNEL);
++	hpetp = kzalloc(siz, GFP_KERNEL);
+ 
+ 	if (!hpetp)
+ 		return -ENOMEM;
+ 
+-	memset(hpetp, 0, siz);
+-
+ 	hpetp->hp_which = hpet_nhpet++;
+ 	hpetp->hp_hpet = hdp->hd_address;
+ 	hpetp->hp_hpet_phys = hdp->hd_phys_address;
+@@ -822,21 +862,23 @@ int hpet_alloc(struct hpet_data *hdp)
+ 
+ 	last = hpetp;
+ 
+-	hpetp->hp_period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
+-	    HPET_COUNTER_CLK_PERIOD_SHIFT;
++	period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
++		HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */
++	temp = 1000000000000000uLL; /* 10^15 femtoseconds per second */
++	temp += period >> 1; /* round */
++	do_div(temp, period);
++	hpetp->hp_tick_freq = temp; /* ticks per second */
+ 
+-	printk(KERN_INFO "hpet%d: at MMIO 0x%lx, IRQ%s",
+-		hpetp->hp_which, hdp->hd_phys_address,
++	printk(KERN_INFO "hpet%d: at MMIO 0x%lx (virtual 0x%p), IRQ%s",
++		hpetp->hp_which, hdp->hd_phys_address, hdp->hd_address,
+ 		hpetp->hp_ntimer > 1 ? "s" : "");
+ 	for (i = 0; i < hpetp->hp_ntimer; i++)
+ 		printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
+ 	printk("\n");
+ 
+-	ns = hpetp->hp_period;	/* femptoseconds, 10^-15 */
+-	ns /= 1000000;		/* convert to nanoseconds, 10^-9 */
+-	printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n",
+-		hpetp->hp_which, ns, hpetp->hp_ntimer,
+-		cap & HPET_COUNTER_SIZE_MASK ? 64 : 32);
++	printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n",
++	       hpetp->hp_which, hpetp->hp_ntimer,
++	       cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, hpetp->hp_tick_freq);
+ 
+ 	mcfg = readq(&hpet->hpet_config);
+ 	if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) {
+@@ -845,13 +887,10 @@ int hpet_alloc(struct hpet_data *hdp)
+ 		writeq(mcfg, &hpet->hpet_config);
+ 	}
+ 
+-	for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer;
+-	     i++, hpet_ntimer++, devp++) {
+-		unsigned long v;
++	for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; i++, devp++) {
+ 		struct hpet_timer __iomem *timer;
+ 
+ 		timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
+-		v = readq(&timer->hpet_config);
+ 
+ 		devp->hd_hpets = hpetp;
+ 		devp->hd_hpet = hpet;
+@@ -880,7 +919,6 @@ static acpi_status hpet_resources(struct
+ 	struct hpet_data *hdp;
+ 	acpi_status status;
+ 	struct acpi_resource_address64 addr;
+-	struct hpets *hpetp;
+ 
+ 	hdp = data;
+ 
+@@ -893,9 +931,29 @@ static acpi_status hpet_resources(struct
+ 		hdp->hd_phys_address = addr.min_address_range;
+ 		hdp->hd_address = ioremap(addr.min_address_range, size);
+ 
+-		for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
+-			if (hpetp->hp_hpet == hdp->hd_address)
+-				return -EBUSY;
++		if (hpet_is_known(hdp)) {
++			printk(KERN_DEBUG "%s: 0x%lx is busy\n",
++				__FUNCTION__, hdp->hd_phys_address);
++			iounmap(hdp->hd_address);
++			return -EBUSY;
++		}
++	} else if (res->id == ACPI_RSTYPE_FIXED_MEM32) {
++		struct acpi_resource_fixed_mem32 *fixmem32;
++
++		fixmem32 = &res->data.fixed_memory32;
++		if (!fixmem32)
++			return -EINVAL;
++
++		hdp->hd_phys_address = fixmem32->range_base_address;
++		hdp->hd_address = ioremap(fixmem32->range_base_address,
++						HPET_RANGE_SIZE);
++
++		if (hpet_is_known(hdp)) {
++			printk(KERN_DEBUG "%s: 0x%lx is busy\n",
++				__FUNCTION__, hdp->hd_phys_address);
++			iounmap(hdp->hd_address);
++			return -EBUSY;
++		}
+ 	} else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
+ 		struct acpi_resource_ext_irq *irqp;
+ 		int i;
+diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
+--- a/drivers/char/hvc_vio.c
++++ b/drivers/char/hvc_vio.c
+@@ -95,11 +95,11 @@ static int __devexit hvc_vio_remove(stru
+ }
+ 
+ static struct vio_driver hvc_vio_driver = {
+-	.name		= hvc_driver_name,
+ 	.id_table	= hvc_driver_table,
+ 	.probe		= hvc_vio_probe,
+ 	.remove		= hvc_vio_remove,
+ 	.driver		= {
++		.name	= hvc_driver_name,
+ 		.owner	= THIS_MODULE,
+ 	}
+ };
+diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
+--- a/drivers/char/hvcs.c
++++ b/drivers/char/hvcs.c
+@@ -720,10 +720,13 @@ static int __devexit hvcs_remove(struct 
+ };
+ 
+ static struct vio_driver hvcs_vio_driver = {
+-	.name		= hvcs_driver_name,
+ 	.id_table	= hvcs_driver_table,
+ 	.probe		= hvcs_probe,
+ 	.remove		= hvcs_remove,
++	.driver		= {
++		.name	= hvcs_driver_name,
++		.owner	= THIS_MODULE,
++	}
+ };
+ 
+ /* Only called from hvcs_get_pi please */
+diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
+--- a/drivers/char/ip2main.c
++++ b/drivers/char/ip2main.c
+@@ -721,8 +721,9 @@ ip2_loadmain(int *iop, int *irqp, unsign
+ 			}
+ 
+ 			if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
+-				class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
+-						4 * i), NULL, "ipl%d", i);
++				class_device_create(ip2_class, NULL,
++						MKDEV(IP2_IPL_MAJOR, 4 * i),
++						NULL, "ipl%d", i);
+ 				err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
+ 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
+ 						"ip2/ipl%d", i);
+@@ -732,8 +733,9 @@ ip2_loadmain(int *iop, int *irqp, unsign
+ 					goto out_class;
+ 				}
+ 
+-				class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
+-						4 * i + 1), NULL, "stat%d", i);
++				class_device_create(ip2_class, NULL,
++						MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
++						NULL, "stat%d", i);
+ 				err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+ 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
+ 						"ip2/stat%d", i);
+diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
+--- a/drivers/char/ipmi/ipmi_devintf.c
++++ b/drivers/char/ipmi/ipmi_devintf.c
+@@ -798,7 +798,7 @@ static void ipmi_new_smi(int if_num)
+ 	devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
+ 		      "ipmidev/%d", if_num);
+ 
+-	class_device_create(ipmi_class, dev, NULL, "ipmi%d", if_num);
++	class_device_create(ipmi_class, NULL, dev, NULL, "ipmi%d", if_num);
+ }
+ 
+ static void ipmi_smi_gone(int if_num)
+diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
+--- a/drivers/char/istallion.c
++++ b/drivers/char/istallion.c
+@@ -5246,7 +5246,8 @@ int __init stli_init(void)
+ 		devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
+ 			       S_IFCHR | S_IRUSR | S_IWUSR,
+ 			       "staliomem/%d", i);
+-		class_device_create(istallion_class, MKDEV(STL_SIOMEMMAJOR, i),
++		class_device_create(istallion_class, NULL,
++				MKDEV(STL_SIOMEMMAJOR, i),
+ 				NULL, "staliomem%d", i);
+ 	}
+ 
+diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
+--- a/drivers/char/lcd.c
++++ b/drivers/char/lcd.c
+@@ -575,8 +575,8 @@ static inline int button_pressed(void)
+ 
+ static int lcd_waiters = 0;
+ 
+-static long lcd_read(struct inode *inode, struct file *file, char *buf,
+-		     unsigned long count)
++static ssize_t lcd_read(struct file *file, char *buf,
++		     size_t count, loff_t *ofs)
+ {
+ 	long buttons_now;
+ 
+diff --git a/drivers/char/lcd.h b/drivers/char/lcd.h
+--- a/drivers/char/lcd.h
++++ b/drivers/char/lcd.h
+@@ -22,7 +22,7 @@ static int timeout(volatile unsigned lon
+ #define MAX_IDLE_TIME 120
+ 
+ struct lcd_display {
+-        unsigned long buttons;
++        unsigned buttons;
+         int size1;
+         int size2;
+         unsigned char line1[LCD_CHARS_PER_LINE];
+diff --git a/drivers/char/lp.c b/drivers/char/lp.c
+--- a/drivers/char/lp.c
++++ b/drivers/char/lp.c
+@@ -805,7 +805,7 @@ static int lp_register(int nr, struct pa
+ 	if (reset)
+ 		lp_reset(nr);
+ 
+-	class_device_create(lp_class, MKDEV(LP_MAJOR, nr), NULL,
++	class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL,
+ 				"lp%d", nr);
+ 	devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO,
+ 			"printers/%d", nr);
+diff --git a/drivers/char/mem.c b/drivers/char/mem.c
+--- a/drivers/char/mem.c
++++ b/drivers/char/mem.c
+@@ -231,9 +231,7 @@ static ssize_t write_mem(struct file * f
+ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+ {
+ #if defined(__HAVE_PHYS_MEM_ACCESS_PROT)
+-	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+-
+-	vma->vm_page_prot = phys_mem_access_prot(file, offset,
++	vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
+ 						 vma->vm_end - vma->vm_start,
+ 						 vma->vm_page_prot);
+ #elif defined(pgprot_noncached)
+@@ -920,7 +918,8 @@ static int __init chr_dev_init(void)
+ 
+ 	mem_class = class_create(THIS_MODULE, "mem");
+ 	for (i = 0; i < ARRAY_SIZE(devlist); i++) {
+-		class_device_create(mem_class, MKDEV(MEM_MAJOR, devlist[i].minor),
++		class_device_create(mem_class, NULL,
++					MKDEV(MEM_MAJOR, devlist[i].minor),
+ 					NULL, devlist[i].name);
+ 		devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
+ 				S_IFCHR | devlist[i].mode, devlist[i].name);
+diff --git a/drivers/char/misc.c b/drivers/char/misc.c
+--- a/drivers/char/misc.c
++++ b/drivers/char/misc.c
+@@ -234,7 +234,7 @@ int misc_register(struct miscdevice * mi
+ 	}
+ 	dev = MKDEV(MISC_MAJOR, misc->minor);
+ 
+-	misc->class = class_device_create(misc_class, dev, misc->dev,
++	misc->class = class_device_create(misc_class, NULL, dev, misc->dev,
+ 					  "%s", misc->name);
+ 	if (IS_ERR(misc->class)) {
+ 		err = PTR_ERR(misc->class);
+diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
+--- a/drivers/char/mmtimer.c
++++ b/drivers/char/mmtimer.c
+@@ -441,7 +441,7 @@ static irqreturn_t
+ mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	int i;
+-	mmtimer_t *base = timers + cpuid_to_cnodeid(smp_processor_id()) *
++	mmtimer_t *base = timers + cpu_to_node(smp_processor_id()) *
+ 						NUM_COMPARATORS;
+ 	unsigned long expires = 0;
+ 	int result = IRQ_NONE;
+@@ -608,7 +608,7 @@ static int sgi_timer_set(struct k_itimer
+ 	 */
+ 	preempt_disable();
+ 
+-	nodeid =  cpuid_to_cnodeid(smp_processor_id());
++	nodeid =  cpu_to_node(smp_processor_id());
+ 	base = timers + nodeid * NUM_COMPARATORS;
+ retry:
+ 	/* Don't use an allocated timer, or a deleted one that's pending */
+diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c
+--- a/drivers/char/mwave/3780i.c
++++ b/drivers/char/mwave/3780i.c
+@@ -53,6 +53,8 @@
+ #include <linux/ioport.h>
+ #include <linux/init.h>
+ #include <linux/bitops.h>
++#include <linux/sched.h>	/* cond_resched() */
++
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
+--- a/drivers/char/n_tty.c
++++ b/drivers/char/n_tty.c
+@@ -62,7 +62,7 @@
+ 
+ static inline unsigned char *alloc_buf(void)
+ {
+-	unsigned int prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
++	gfp_t prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+ 
+ 	if (PAGE_SIZE != N_TTY_BUF_SIZE)
+ 		return kmalloc(N_TTY_BUF_SIZE, prio);
+diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
+--- a/drivers/char/nvram.c
++++ b/drivers/char/nvram.c
+@@ -32,9 +32,11 @@
+  * 		added changelog
+  * 	1.2	Erik Gilling: Cobalt Networks support
+  * 		Tim Hockin: general cleanup, Cobalt support
++ * 	1.3	Jon Ringle: Comdial MP1000 support
++ *
+  */
+ 
+-#define NVRAM_VERSION	"1.2"
++#define NVRAM_VERSION	"1.3"
+ 
+ #include <linux/module.h>
+ #include <linux/config.h>
+@@ -45,6 +47,7 @@
+ #define PC		1
+ #define ATARI		2
+ #define COBALT		3
++#define MP1000		4
+ 
+ /* select machine configuration */
+ #if defined(CONFIG_ATARI)
+@@ -54,6 +57,9 @@
+ #  if defined(CONFIG_COBALT)
+ #    include <linux/cobalt-nvram.h>
+ #    define MACH COBALT
++#  elif defined(CONFIG_MACH_MP1000)
++#    undef MACH
++#    define MACH MP1000
+ #  else
+ #    define MACH PC
+ #  endif
+@@ -112,6 +118,23 @@
+ 
+ #endif
+ 
++#if MACH == MP1000
++
++/* RTC in a MP1000 */
++#define CHECK_DRIVER_INIT()	1
++
++#define MP1000_CKS_RANGE_START	0
++#define MP1000_CKS_RANGE_END	111
++#define MP1000_CKS_LOC		112
++
++#define NVRAM_BYTES		(128-NVRAM_FIRST_BYTE)
++
++#define mach_check_checksum	mp1000_check_checksum
++#define mach_set_checksum	mp1000_set_checksum
++#define mach_proc_infos		mp1000_proc_infos
++
++#endif
++
+ /* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with
+  * rtc_lock held. Due to the index-port/data-port design of the RTC, we
+  * don't want two different things trying to get to it at once. (e.g. the
+@@ -915,6 +938,91 @@ atari_proc_infos(unsigned char *nvram, c
+ 
+ #endif /* MACH == ATARI */
+ 
++#if MACH == MP1000
++
++static int
++mp1000_check_checksum(void)
++{
++	int i;
++	unsigned short sum = 0;
++	unsigned short expect;
++
++	for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i)
++		sum += __nvram_read_byte(i);
++
++        expect = __nvram_read_byte(MP1000_CKS_LOC+1)<<8 |
++	    __nvram_read_byte(MP1000_CKS_LOC);
++	return ((sum & 0xffff) == expect);
++}
++
++static void
++mp1000_set_checksum(void)
++{
++	int i;
++	unsigned short sum = 0;
++
++	for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i)
++		sum += __nvram_read_byte(i);
++	__nvram_write_byte(sum >> 8, MP1000_CKS_LOC + 1);
++	__nvram_write_byte(sum & 0xff, MP1000_CKS_LOC);
++}
++
++#ifdef CONFIG_PROC_FS
++
++#define         SERVER_N_LEN         32
++#define         PATH_N_LEN           32
++#define         FILE_N_LEN           32
++#define         NVRAM_MAGIC_SIG      0xdead
++
++typedef struct NvRamImage
++{
++	unsigned short int    magic;
++	unsigned short int    mode;
++	char                  fname[FILE_N_LEN];
++	char                  path[PATH_N_LEN];
++	char                  server[SERVER_N_LEN];
++	char                  pad[12];
++} NvRam;
++
++static int
++mp1000_proc_infos(unsigned char *nvram, char *buffer, int *len,
++    off_t *begin, off_t offset, int size)
++{
++	int checksum;
++        NvRam* nv = (NvRam*)nvram;
++
++	spin_lock_irq(&rtc_lock);
++	checksum = __nvram_check_checksum();
++	spin_unlock_irq(&rtc_lock);
++
++	PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not ");
++
++        switch( nv->mode )
++        {
++           case 0 :
++                    PRINT_PROC( "\tMode 0, tftp prompt\n" );
++                    break;
++           case 1 :
++                    PRINT_PROC( "\tMode 1, booting from disk\n" );
++                    break;
++           case 2 :
++                    PRINT_PROC( "\tMode 2, Alternate boot from disk /boot/%s\n", nv->fname );
++                    break;
++           case 3 :
++                    PRINT_PROC( "\tMode 3, Booting from net:\n" );
++                    PRINT_PROC( "\t\t%s:%s%s\n",nv->server, nv->path, nv->fname );
++                    break;
++           default:
++                    PRINT_PROC( "\tInconsistant nvram?\n" );
++                    break;
++        }
++
++	return 1;
++}
++#endif
++
++#endif /* MACH == MP1000 */
++
+ MODULE_LICENSE("GPL");
+ 
+ EXPORT_SYMBOL(__nvram_read_byte);
+diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
+--- a/drivers/char/ppdev.c
++++ b/drivers/char/ppdev.c
+@@ -752,7 +752,7 @@ static struct file_operations pp_fops = 
+ 
+ static void pp_attach(struct parport *port)
+ {
+-	class_device_create(ppdev_class, MKDEV(PP_MAJOR, port->number),
++	class_device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number),
+ 			NULL, "parport%d", port->number);
+ }
+ 
+diff --git a/drivers/char/qtronix.c b/drivers/char/qtronix.c
+--- a/drivers/char/qtronix.c
++++ b/drivers/char/qtronix.c
+@@ -591,6 +591,11 @@ static int __init psaux_init(void)
+ 		return retval;
+ 
+ 	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
++	if (!queue) {
++		misc_deregister(&psaux_mouse);
++		return -ENOMEM;
++	}
++		
+ 	memset(queue, 0, sizeof(*queue));
+ 	queue->head = queue->tail = 0;
+ 	init_waitqueue_head(&queue->proc_list);
+diff --git a/drivers/char/raw.c b/drivers/char/raw.c
+--- a/drivers/char/raw.c
++++ b/drivers/char/raw.c
+@@ -128,7 +128,7 @@ raw_ioctl(struct inode *inode, struct fi
+ static void bind_device(struct raw_config_request *rq)
+ {
+ 	class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
+-	class_device_create(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor),
++	class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
+ 				      NULL, "raw%d", rq->raw_minor);
+ }
+ 
+@@ -307,7 +307,7 @@ static int __init raw_init(void)
+ 		unregister_chrdev_region(dev, MAX_RAW_MINORS);
+ 		goto error;
+ 	}
+-	class_device_create(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
++	class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
+ 
+ 	devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
+ 		      S_IFCHR | S_IRUGO | S_IWUGO,
+diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
+--- a/drivers/char/rocket.c
++++ b/drivers/char/rocket.c
+@@ -256,7 +256,6 @@ static int sInitController(CONTROLLER_T 
+ static int sReadAiopID(ByteIO_t io);
+ static int sReadAiopNumChan(WordIO_t io);
+ 
+-#ifdef MODULE
+ MODULE_AUTHOR("Theodore Ts'o");
+ MODULE_DESCRIPTION("Comtrol RocketPort driver");
+ module_param(board1, ulong, 0);
+@@ -288,17 +287,14 @@ MODULE_PARM_DESC(pc104_3, "set interface
+ module_param_array(pc104_4, ulong, NULL, 0);
+ MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
+ 
+-int rp_init(void);
++static int rp_init(void);
+ static void rp_cleanup_module(void);
+ 
+ module_init(rp_init);
+ module_exit(rp_cleanup_module);
+ 
+-#endif
+ 
+-#ifdef MODULE_LICENSE
+ MODULE_LICENSE("Dual BSD/GPL");
+-#endif
+ 
+ /*************************************************************************/
+ /*                     Module code starts here                           */
+@@ -2378,7 +2374,7 @@ static struct tty_operations rocket_ops 
+ /*
+  * The module "startup" routine; it's run when the module is loaded.
+  */
+-int __init rp_init(void)
++static int __init rp_init(void)
+ {
+ 	int retval, pci_boards_found, isa_boards_found, i;
+ 
+@@ -2502,7 +2498,6 @@ int __init rp_init(void)
+ 	return 0;
+ }
+ 
+-#ifdef MODULE
+ 
+ static void rp_cleanup_module(void)
+ {
+@@ -2530,7 +2525,6 @@ static void rp_cleanup_module(void)
+ 	if (controller)
+ 		release_region(controller, 4);
+ }
+-#endif
+ 
+ /***************************************************************************
+ Function: sInitController
+diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
+--- a/drivers/char/s3c2410-rtc.c
++++ b/drivers/char/s3c2410-rtc.c
+@@ -20,7 +20,7 @@
+ #include <linux/fs.h>
+ #include <linux/string.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ #include <linux/rtc.h>
+ #include <linux/bcd.h>
+@@ -519,30 +519,28 @@ static struct timespec s3c2410_rtc_delta
+ 
+ static int ticnt_save;
+ 
+-static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state, u32 level)
++static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct rtc_time tm;
+ 	struct timespec time;
+ 
+ 	time.tv_nsec = 0;
+ 
+-	if (level == SUSPEND_POWER_DOWN) {
+-		/* save TICNT for anyone using periodic interrupts */
++	/* save TICNT for anyone using periodic interrupts */
+ 
+-		ticnt_save = readb(S3C2410_TICNT);
++	ticnt_save = readb(S3C2410_TICNT);
+ 
+-		/* calculate time delta for suspend */
++	/* calculate time delta for suspend */
+ 
+-		s3c2410_rtc_gettime(&tm);
+-		rtc_tm_to_time(&tm, &time.tv_sec);
+-		save_time_delta(&s3c2410_rtc_delta, &time);
+-		s3c2410_rtc_enable(dev, 0);
+-	}
++	s3c2410_rtc_gettime(&tm);
++	rtc_tm_to_time(&tm, &time.tv_sec);
++	save_time_delta(&s3c2410_rtc_delta, &time);
++	s3c2410_rtc_enable(dev, 0);
+ 
+ 	return 0;
+ }
+ 
+-static int s3c2410_rtc_resume(struct device *dev, u32 level)
++static int s3c2410_rtc_resume(struct device *dev)
+ {
+ 	struct rtc_time tm;
+ 	struct timespec time;
+diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
+--- a/drivers/char/ser_a2232.c
++++ b/drivers/char/ser_a2232.c
+@@ -790,7 +790,7 @@ static int __init a2232board_init(void)
+ 
+ 	}	
+ 
+-	printk("Total: %d A2232 boards initialized.\n.", nr_a2232); /* Some status report if no card was found */
++	printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */
+ 
+ 	a2232_init_portstructs();
+ 
+diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
+--- a/drivers/char/snsc.c
++++ b/drivers/char/snsc.c
+@@ -377,7 +377,7 @@ scdrv_init(void)
+ 	dev_t first_dev, dev;
+ 	nasid_t event_nasid = ia64_sn_get_console_nasid();
+ 
+-	if (alloc_chrdev_region(&first_dev, 0, numionodes,
++	if (alloc_chrdev_region(&first_dev, 0, num_cnodes,
+ 				SYSCTL_BASENAME) < 0) {
+ 		printk("%s: failed to register SN system controller device\n",
+ 		       __FUNCTION__);
+@@ -385,7 +385,7 @@ scdrv_init(void)
+ 	}
+ 	snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME);
+ 
+-	for (cnode = 0; cnode < numionodes; cnode++) {
++	for (cnode = 0; cnode < num_cnodes; cnode++) {
+ 			geoid = cnodeid_get_geoid(cnode);
+ 			devnamep = devname;
+ 			format_module_id(devnamep, geo_module(geoid),
+@@ -437,7 +437,7 @@ scdrv_init(void)
+ 				continue;
+ 			}
+ 
+-			class_device_create(snsc_class, dev, NULL,
++			class_device_create(snsc_class, NULL, dev, NULL,
+ 						"%s", devname);
+ 
+ 			ia64_sn_irtr_intr_enable(scd->scd_nasid,
+diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
+--- a/drivers/char/sonypi.c
++++ b/drivers/char/sonypi.c
+@@ -48,6 +48,7 @@
+ #include <linux/dmi.h>
+ #include <linux/err.h>
+ #include <linux/kfifo.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -424,10 +425,6 @@ static struct sonypi_eventtypes {
+ 
+ #define SONYPI_BUF_SIZE	128
+ 
+-/* The name of the devices for the input device drivers */
+-#define SONYPI_JOG_INPUTNAME	"Sony Vaio Jogdial"
+-#define SONYPI_KEY_INPUTNAME	"Sony Vaio Keys"
+-
+ /* Correspondance table between sonypi events and input layer events */
+ static struct {
+ 	int sonypiev;
+@@ -490,8 +487,8 @@ static struct sonypi_device {
+ 	struct fasync_struct *fifo_async;
+ 	int open_count;
+ 	int model;
+-	struct input_dev input_jog_dev;
+-	struct input_dev input_key_dev;
++	struct input_dev *input_jog_dev;
++	struct input_dev *input_key_dev;
+ 	struct work_struct input_work;
+ 	struct kfifo *input_fifo;
+ 	spinlock_t input_fifo_lock;
+@@ -779,8 +776,8 @@ static void input_keyrelease(void *data)
+ 
+ static void sonypi_report_input_event(u8 event)
+ {
+-	struct input_dev *jog_dev = &sonypi_device.input_jog_dev;
+-	struct input_dev *key_dev = &sonypi_device.input_key_dev;
++	struct input_dev *jog_dev = sonypi_device.input_jog_dev;
++	struct input_dev *key_dev = sonypi_device.input_key_dev;
+ 	struct sonypi_keypress kp = { NULL };
+ 	int i;
+ 
+@@ -1171,19 +1168,17 @@ static int sonypi_disable(void)
+ #ifdef CONFIG_PM
+ static int old_camera_power;
+ 
+-static int sonypi_suspend(struct device *dev, pm_message_t state, u32 level)
++static int sonypi_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_DISABLE) {
+-		old_camera_power = sonypi_device.camera_power;
+-		sonypi_disable();
+-	}
++	old_camera_power = sonypi_device.camera_power;
++	sonypi_disable();
++
+ 	return 0;
+ }
+ 
+-static int sonypi_resume(struct device *dev, u32 level)
++static int sonypi_resume(struct device *dev)
+ {
+-	if (level == RESUME_ENABLE)
+-		sonypi_enable(old_camera_power);
++	sonypi_enable(old_camera_power);
+ 	return 0;
+ }
+ #endif
+@@ -1203,6 +1198,47 @@ static struct device_driver sonypi_drive
+ 	.shutdown	= sonypi_shutdown,
+ };
+ 
++static int __devinit sonypi_create_input_devices(void)
++{
++	struct input_dev *jog_dev;
++	struct input_dev *key_dev;
++	int i;
++
++	sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
++	if (!jog_dev)
++		return -ENOMEM;
++
++	jog_dev->name = "Sony Vaio Jogdial";
++	jog_dev->id.bustype = BUS_ISA;
++	jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
++
++	jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++	jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
++	jog_dev->relbit[0] = BIT(REL_WHEEL);
++
++	sonypi_device.input_key_dev = key_dev = input_allocate_device();
++	if (!key_dev) {
++		input_free_device(jog_dev);
++		sonypi_device.input_jog_dev = NULL;
++		return -ENOMEM;
++	}
++
++	key_dev->name = "Sony Vaio Keys";
++	key_dev->id.bustype = BUS_ISA;
++	key_dev->id.vendor = PCI_VENDOR_ID_SONY;
++
++	/* Initialize the Input Drivers: special keys */
++	key_dev->evbit[0] = BIT(EV_KEY);
++	for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
++		if (sonypi_inputkeys[i].inputev)
++			set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
++
++	input_register_device(jog_dev);
++	input_register_device(key_dev);
++
++	return 0;
++}
++
+ static int __devinit sonypi_probe(void)
+ {
+ 	int i, ret;
+@@ -1298,34 +1334,10 @@ static int __devinit sonypi_probe(void)
+ 	}
+ 
+ 	if (useinput) {
+-		/* Initialize the Input Drivers: jogdial */
+-		int i;
+-		sonypi_device.input_jog_dev.evbit[0] =
+-			BIT(EV_KEY) | BIT(EV_REL);
+-		sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] =
+-			BIT(BTN_MIDDLE);
+-		sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL);
+-		sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME;
+-		sonypi_device.input_jog_dev.id.bustype = BUS_ISA;
+-		sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY;
+-
+-		input_register_device(&sonypi_device.input_jog_dev);
+-		printk(KERN_INFO "%s input method installed.\n",
+-		       sonypi_device.input_jog_dev.name);
+ 
+-		/* Initialize the Input Drivers: special keys */
+-		sonypi_device.input_key_dev.evbit[0] = BIT(EV_KEY);
+-		for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
+-			if (sonypi_inputkeys[i].inputev)
+-				set_bit(sonypi_inputkeys[i].inputev,
+-					sonypi_device.input_key_dev.keybit);
+-		sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME;
+-		sonypi_device.input_key_dev.id.bustype = BUS_ISA;
+-		sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY;
+-
+-		input_register_device(&sonypi_device.input_key_dev);
+-		printk(KERN_INFO "%s input method installed.\n",
+-		       sonypi_device.input_key_dev.name);
++		ret = sonypi_create_input_devices();
++		if (ret)
++			goto out_inputdevices;
+ 
+ 		spin_lock_init(&sonypi_device.input_fifo_lock);
+ 		sonypi_device.input_fifo =
+@@ -1375,8 +1387,9 @@ static int __devinit sonypi_probe(void)
+ out_platformdev:
+ 	kfifo_free(sonypi_device.input_fifo);
+ out_infifo:
+-	input_unregister_device(&sonypi_device.input_key_dev);
+-	input_unregister_device(&sonypi_device.input_jog_dev);
++	input_unregister_device(sonypi_device.input_key_dev);
++	input_unregister_device(sonypi_device.input_jog_dev);
++out_inputdevices:
+ 	free_irq(sonypi_device.irq, sonypi_irq);
+ out_reqirq:
+ 	release_region(sonypi_device.ioport1, sonypi_device.region_size);
+@@ -1402,8 +1415,8 @@ static void __devexit sonypi_remove(void
+ 	platform_device_unregister(sonypi_device.pdev);
+ 
+ 	if (useinput) {
+-		input_unregister_device(&sonypi_device.input_key_dev);
+-		input_unregister_device(&sonypi_device.input_jog_dev);
++		input_unregister_device(sonypi_device.input_key_dev);
++		input_unregister_device(sonypi_device.input_jog_dev);
+ 		kfifo_free(sonypi_device.input_fifo);
+ 	}
+ 
+diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
+--- a/drivers/char/specialix.c
++++ b/drivers/char/specialix.c
+@@ -38,19 +38,19 @@
+  *
+  * Revision 1.0:  April 1st 1997.
+  *                Initial release for alpha testing.
+- * Revision 1.1:  April 14th 1997. 
+- *                Incorporated Richard Hudsons suggestions, 
++ * Revision 1.1:  April 14th 1997.
++ *                Incorporated Richard Hudsons suggestions,
+  *                removed some debugging printk's.
+  * Revision 1.2:  April 15th 1997.
+  *                Ported to 2.1.x kernels.
+- * Revision 1.3:  April 17th 1997 
+- *                Backported to 2.0. (Compatibility macros). 
++ * Revision 1.3:  April 17th 1997
++ *                Backported to 2.0. (Compatibility macros).
+  * Revision 1.4:  April 18th 1997
+- *                Fixed DTR/RTS bug that caused the card to indicate 
+- *                "don't send data" to a modem after the password prompt.  
++ *                Fixed DTR/RTS bug that caused the card to indicate
++ *                "don't send data" to a modem after the password prompt.
+  *                Fixed bug for premature (fake) interrupts.
+  * Revision 1.5:  April 19th 1997
+- *                fixed a minor typo in the header file, cleanup a little. 
++ *                fixed a minor typo in the header file, cleanup a little.
+  *                performance warnings are now MAXed at once per minute.
+  * Revision 1.6:  May 23 1997
+  *                Changed the specialix=... format to include interrupt.
+@@ -60,10 +60,10 @@
+  *                port to linux-2.1.43 kernel.
+  * Revision 1.9:  Oct 9  1998
+  *                Added stuff for the IO8+/PCI version.
+- * Revision 1.10: Oct 22  1999 / Jan 21 2000. 
+- *                Added stuff for setserial. 
++ * Revision 1.10: Oct 22  1999 / Jan 21 2000.
++ *                Added stuff for setserial.
+  *                Nicolas Mailhot (Nicolas.Mailhot at email.enst.fr)
+- * 
++ *
+  */
+ 
+ #define VERSION "1.11"
+@@ -154,7 +154,7 @@ static int sx_poll = HZ;
+ 
+ 
+ 
+-/* 
++/*
+  * The following defines are mostly for testing purposes. But if you need
+  * some nice reporting in your syslog, you can define them also.
+  */
+@@ -188,7 +188,7 @@ static DECLARE_MUTEX(tmp_buf_sem);
+ 
+ static unsigned long baud_table[] =  {
+ 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+-	9600, 19200, 38400, 57600, 115200, 0, 
++	9600, 19200, 38400, 57600, 115200, 0,
+ };
+ 
+ static struct specialix_board sx_board[SX_NBOARD] =  {
+@@ -216,7 +216,7 @@ static inline int sx_paranoia_check(stru
+ 		KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
+ 	static const char *badinfo =
+ 		KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
+- 
++
+ 	if (!port) {
+ 		printk(badinfo, name, routine);
+ 		return 1;
+@@ -231,9 +231,9 @@ static inline int sx_paranoia_check(stru
+ 
+ 
+ /*
+- * 
++ *
+  *  Service functions for specialix IO8+ driver.
+- * 
++ *
+  */
+ 
+ /* Get board number from pointer */
+@@ -246,7 +246,7 @@ static inline int board_No (struct speci
+ /* Get port number from pointer */
+ static inline int port_No (struct specialix_port const * port)
+ {
+-	return SX_PORT(port - sx_port); 
++	return SX_PORT(port - sx_port);
+ }
+ 
+ 
+@@ -309,7 +309,7 @@ static inline void sx_wait_CCR(struct sp
+ 			return;
+ 		udelay (1);
+ 	}
+-	
++
+ 	printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
+ }
+ 
+@@ -329,7 +329,7 @@ static inline void sx_wait_CCR_off(struc
+ 			return;
+ 		udelay (1);
+ 	}
+-	
++
+ 	printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
+ }
+ 
+@@ -338,34 +338,28 @@ static inline void sx_wait_CCR_off(struc
+  *  specialix IO8+ IO range functions.
+  */
+ 
+-static inline int sx_check_io_range(struct specialix_board * bp)
++static inline int sx_request_io_range(struct specialix_board * bp)
+ {
+-	return check_region (bp->base, SX_IO_SPACE);
+-}
+-
+-
+-static inline void sx_request_io_range(struct specialix_board * bp)
+-{
+-	request_region(bp->base, 
+-	               bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE,
+-	               "specialix IO8+" );
++	return request_region(bp->base,
++		bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
++		"specialix IO8+") == NULL;
+ }
+ 
+ 
+ static inline void sx_release_io_range(struct specialix_board * bp)
+ {
+-	release_region(bp->base, 
++	release_region(bp->base,
+ 	               bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
+ }
+ 
+-	
++
+ /* Must be called with enabled interrupts */
+-/* Ugly. Very ugly. Don't use this for anything else than initialization 
++/* Ugly. Very ugly. Don't use this for anything else than initialization
+    code */
+ static inline void sx_long_delay(unsigned long delay)
+ {
+ 	unsigned long i;
+-	
++
+ 	for (i = jiffies + delay; time_after(i, jiffies); ) ;
+ }
+ 
+@@ -378,7 +372,7 @@ static int sx_set_irq ( struct specialix
+ 	int i;
+ 	unsigned long flags;
+ 
+-	if (bp->flags & SX_BOARD_IS_PCI) 
++	if (bp->flags & SX_BOARD_IS_PCI)
+ 		return 1;
+ 	switch (bp->irq) {
+ 	/* In the same order as in the docs... */
+@@ -420,7 +414,7 @@ static int sx_init_CD186x(struct special
+ 	sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT);      /* Prio for receiver intr    */
+ 	/* Set RegAckEn */
+ 	sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
+-	
++
+ 	/* Setting up prescaler. We need 4 ticks per 1 ms */
+ 	scaler =  SX_OSCFREQ/SPECIALIX_TPS;
+ 
+@@ -448,7 +442,7 @@ static int read_cross_byte (struct speci
+ 	spin_lock_irqsave(&bp->lock, flags);
+ 	for (i=0, t=0;i<8;i++) {
+ 		sx_out_off (bp, CD186x_CAR, i);
+-		if (sx_in_off (bp, reg) & bit) 
++		if (sx_in_off (bp, reg) & bit)
+ 			t |= 1 << i;
+ 	}
+ 	spin_unlock_irqrestore(&bp->lock, flags);
+@@ -472,7 +466,7 @@ void missed_irq (unsigned long data)
+ 	spin_unlock_irqrestore(&bp->lock, flags);
+ 	if (irq) {
+ 		printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
+-		sx_interrupt (((struct specialix_board *)data)->irq, 
++		sx_interrupt (((struct specialix_board *)data)->irq,
+ 		              (void*)data, NULL);
+ 	}
+ 	missed_irq_timer.expires = jiffies + sx_poll;
+@@ -495,7 +489,7 @@ static int sx_probe(struct specialix_boa
+ 
+ 	func_enter();
+ 
+-	if (sx_check_io_range(bp)) {
++	if (sx_request_io_range(bp)) {
+ 		func_exit();
+ 		return 1;
+ 	}
+@@ -509,15 +503,16 @@ static int sx_probe(struct specialix_boa
+ 	short_pause ();
+ 	val2 = sx_in_off(bp, CD186x_PPRL);
+ 
+-	
++
+ 	if ((val1 != 0x5a) || (val2 != 0xa5)) {
+ 		printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
+ 		       board_No(bp), bp->base);
++		sx_release_io_range(bp);
+ 		func_exit();
+ 		return 1;
+ 	}
+ 
+-	/* Check the DSR lines that Specialix uses as board 
++	/* Check the DSR lines that Specialix uses as board
+ 	   identification */
+ 	val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
+ 	val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
+@@ -532,6 +527,7 @@ static int sx_probe(struct specialix_boa
+ 	if (val1 != val2) {
+ 		printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
+ 		       board_No(bp), val2, bp->base, val1);
++		sx_release_io_range(bp);
+ 		func_exit();
+ 		return 1;
+ 	}
+@@ -546,7 +542,7 @@ static int sx_probe(struct specialix_boa
+ 		sx_wait_CCR(bp);
+ 		sx_out(bp, CD186x_CCR, CCR_TXEN);        /* Enable transmitter     */
+ 		sx_out(bp, CD186x_IER, IER_TXRDY);       /* Enable tx empty intr   */
+-		sx_long_delay(HZ/20);	       		
++		sx_long_delay(HZ/20);
+ 		irqs = probe_irq_off(irqs);
+ 
+ 		dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
+@@ -561,14 +557,15 @@ static int sx_probe(struct specialix_boa
+ 		}
+ 
+ 		dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
+-		        val1, val2, val3); 
+-	
++		        val1, val2, val3);
++
+ 	}
+-	
++
+ #if 0
+ 	if (irqs <= 0) {
+ 		printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
+ 		       board_No(bp), bp->base);
++		sx_release_io_range(bp);
+ 		func_exit();
+ 		return 1;
+ 	}
+@@ -579,19 +576,20 @@ static int sx_probe(struct specialix_boa
+ #endif
+ 	/* Reset CD186x again  */
+ 	if (!sx_init_CD186x(bp)) {
++		sx_release_io_range(bp);
+ 		func_exit();
+-		return -EIO;
++		return 1;
+ 	}
+ 
+ 	sx_request_io_range(bp);
+ 	bp->flags |= SX_BOARD_PRESENT;
+-	
++
+ 	/* Chip           revcode   pkgtype
+ 	                  GFRCR     SRCR bit 7
+ 	   CD180 rev B    0x81      0
+ 	   CD180 rev C    0x82      0
+ 	   CD1864 rev A   0x82      1
+-	   CD1865 rev A   0x83      1  -- Do not use!!! Does not work. 
++	   CD1865 rev A   0x83      1  -- Do not use!!! Does not work.
+ 	   CD1865 rev B   0x84      1
+ 	 -- Thanks to Gwen Wang, Cirrus Logic.
+ 	 */
+@@ -623,8 +621,8 @@ static int sx_probe(struct specialix_boa
+ 	return 0;
+ }
+ 
+-/* 
+- * 
++/*
++ *
+  *  Interrupt processing routines.
+  * */
+ 
+@@ -657,7 +655,7 @@ static inline struct specialix_port * sx
+ 			return port;
+ 		}
+ 	}
+-	printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n", 
++	printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
+ 	       board_No(bp), what, channel);
+ 	return NULL;
+ }
+@@ -681,7 +679,7 @@ static inline void sx_receive_exc(struct
+ 	tty = port->tty;
+ 	dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
+ 		 port,  tty->flip.count, TTY_FLIPBUF_SIZE);
+-	
++
+ 	status = sx_in(bp, CD186x_RCSR);
+ 
+ 	dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
+@@ -707,30 +705,30 @@ static inline void sx_receive_exc(struct
+ 		return;
+ 	}
+ 	if (status & RCSR_TOUT) {
+-		printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n", 
++		printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
+ 		       board_No(bp), port_No(port));
+ 		func_exit();
+ 		return;
+-		
++
+ 	} else if (status & RCSR_BREAK) {
+ 		dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
+ 		       board_No(bp), port_No(port));
+ 		*tty->flip.flag_buf_ptr++ = TTY_BREAK;
+ 		if (port->flags & ASYNC_SAK)
+ 			do_SAK(tty);
+-		
+-	} else if (status & RCSR_PE) 
++
++	} else if (status & RCSR_PE)
+ 		*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+-	
+-	else if (status & RCSR_FE) 
++
++	else if (status & RCSR_FE)
+ 		*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+-	
++
+ 	else if (status & RCSR_OE)
+ 		*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+-	
++
+ 	else
+ 		*tty->flip.flag_buf_ptr++ = 0;
+-	
++
+ 	*tty->flip.char_buf_ptr++ = ch;
+ 	tty->flip.count++;
+ 	schedule_delayed_work(&tty->flip.work, 1);
+@@ -746,18 +744,18 @@ static inline void sx_receive(struct spe
+ 	unsigned char count;
+ 
+ 	func_enter();
+-	
++
+ 	if (!(port = sx_get_port(bp, "Receive"))) {
+ 		dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
+ 		func_exit();
+ 		return;
+ 	}
+ 	tty = port->tty;
+-	
++
+ 	count = sx_in(bp, CD186x_RDCR);
+ 	dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
+ 	port->hits[count > 8 ? 9 : count]++;
+-	
++
+ 	while (count--) {
+ 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ 			printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
+@@ -787,7 +785,7 @@ static inline void sx_transmit(struct sp
+ 	}
+ 	dprintk (SX_DEBUG_TX, "port: %p\n", port);
+ 	tty = port->tty;
+-	
++
+ 	if (port->IER & IER_TXEMPTY) {
+ 		/* FIFO drained */
+ 		sx_out(bp, CD186x_CAR, port_No(port));
+@@ -796,7 +794,7 @@ static inline void sx_transmit(struct sp
+ 		func_exit();
+ 		return;
+ 	}
+-	
++
+ 	if ((port->xmit_cnt <= 0 && !port->break_length)
+ 	    || tty->stopped || tty->hw_stopped) {
+ 		sx_out(bp, CD186x_CAR, port_No(port));
+@@ -805,7 +803,7 @@ static inline void sx_transmit(struct sp
+ 		func_exit();
+ 		return;
+ 	}
+-	
++
+ 	if (port->break_length) {
+ 		if (port->break_length > 0) {
+ 			if (port->COR2 & COR2_ETC) {
+@@ -831,7 +829,7 @@ static inline void sx_transmit(struct sp
+ 		func_exit();
+ 		return;
+ 	}
+-	
++
+ 	count = CD186x_NFIFO;
+ 	do {
+ 		sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
+@@ -839,7 +837,7 @@ static inline void sx_transmit(struct sp
+ 		if (--port->xmit_cnt <= 0)
+ 			break;
+ 	} while (--count > 0);
+-	
++
+ 	if (port->xmit_cnt <= 0) {
+ 		sx_out(bp, CD186x_CAR, port_No(port));
+ 		port->IER &= ~IER_TXRDY;
+@@ -862,9 +860,9 @@ static inline void sx_check_modem(struct
+ 	dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
+ 	if (!(port = sx_get_port(bp, "Modem")))
+ 		return;
+-	
++
+ 	tty = port->tty;
+-	
++
+ 	mcr = sx_in(bp, CD186x_MCR);
+ 	printk ("mcr = %02x.\n", mcr);
+ 
+@@ -879,7 +877,7 @@ static inline void sx_check_modem(struct
+ 			schedule_work(&port->tqueue_hangup);
+ 		}
+ 	}
+-	
++
+ #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
+ 	if (mcr & MCR_CTSCHG) {
+ 		if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
+@@ -906,7 +904,7 @@ static inline void sx_check_modem(struct
+ 		sx_out(bp, CD186x_IER, port->IER);
+ 	}
+ #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
+-	
++
+ 	/* Clear change bits */
+ 	sx_out(bp, CD186x_MCR, 0);
+ }
+@@ -940,7 +938,7 @@ static irqreturn_t sx_interrupt(int irq,
+ 	while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
+ 	                                   (SRSR_RREQint |
+ 		                            SRSR_TREQint |
+-	                                    SRSR_MREQint)))) {	
++	                                    SRSR_MREQint)))) {
+ 		if (status & SRSR_RREQint) {
+ 			ack = sx_in(bp, CD186x_RRAR);
+ 
+@@ -951,7 +949,7 @@ static irqreturn_t sx_interrupt(int irq,
+ 			else
+ 				printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
+ 				       board_No(bp), status, ack);
+-		
++
+ 		} else if (status & SRSR_TREQint) {
+ 			ack = sx_in(bp, CD186x_TRAR);
+ 
+@@ -963,13 +961,13 @@ static irqreturn_t sx_interrupt(int irq,
+ 		} else if (status & SRSR_MREQint) {
+ 			ack = sx_in(bp, CD186x_MRAR);
+ 
+-			if (ack == (SX_ID | GIVR_IT_MODEM)) 
++			if (ack == (SX_ID | GIVR_IT_MODEM))
+ 				sx_check_modem(bp);
+ 			else
+ 				printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
+ 				       board_No(bp), status, ack);
+-		
+-		} 
++
++		}
+ 
+ 		sx_out(bp, CD186x_EOIR, 0);   /* Mark end of interrupt */
+ 	}
+@@ -1026,7 +1024,7 @@ static inline int sx_setup_board(struct 
+ {
+ 	int error;
+ 
+-	if (bp->flags & SX_BOARD_ACTIVE) 
++	if (bp->flags & SX_BOARD_ACTIVE)
+ 		return 0;
+ 
+ 	if (bp->flags & SX_BOARD_IS_PCI)
+@@ -1034,7 +1032,7 @@ static inline int sx_setup_board(struct 
+ 	else
+ 		error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
+ 
+-	if (error) 
++	if (error)
+ 		return error;
+ 
+ 	turn_ints_on (bp);
+@@ -1055,7 +1053,7 @@ static inline void sx_shutdown_board(str
+ 	}
+ 
+ 	bp->flags &= ~SX_BOARD_ACTIVE;
+-	
++
+ 	dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
+ 		 bp->irq, board_No (bp));
+ 	free_irq(bp->irq, bp);
+@@ -1068,7 +1066,7 @@ static inline void sx_shutdown_board(str
+ 
+ 
+ /*
+- * Setting up port characteristics. 
++ * Setting up port characteristics.
+  * Must be called with disabled interrupts
+  */
+ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
+@@ -1103,10 +1101,10 @@ static void sx_change_speed(struct speci
+ 	spin_unlock_irqrestore(&bp->lock, flags);
+ 	dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
+ 	baud = C_BAUD(tty);
+-	
++
+ 	if (baud & CBAUDEX) {
+ 		baud &= ~CBAUDEX;
+-		if (baud < 1 || baud > 2) 
++		if (baud < 1 || baud > 2)
+ 			port->tty->termios->c_cflag &= ~CBAUDEX;
+ 		else
+ 			baud += 15;
+@@ -1117,8 +1115,8 @@ static void sx_change_speed(struct speci
+ 		if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ 			baud += 2;
+ 	}
+-	
+-	
++
++
+ 	if (!baud_table[baud]) {
+ 		/* Drop DTR & exit */
+ 		dprintk (SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
+@@ -1127,7 +1125,7 @@ static void sx_change_speed(struct speci
+ 			spin_lock_irqsave(&bp->lock, flags);
+ 			sx_out(bp, CD186x_MSVR, port->MSVR );
+ 			spin_unlock_irqrestore(&bp->lock, flags);
+-		} 
++		}
+ 		else
+ 			dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
+ 		return;
+@@ -1137,9 +1135,9 @@ static void sx_change_speed(struct speci
+ 			port ->MSVR |= MSVR_DTR;
+ 		}
+ 	}
+-	
++
+ 	/*
+-	 * Now we must calculate some speed depended things 
++	 * Now we must calculate some speed depended things
+ 	 */
+ 
+ 	/* Set baud rate for port */
+@@ -1152,7 +1150,7 @@ static void sx_change_speed(struct speci
+ 		tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
+ 		         CD186x_TPC/2) / CD186x_TPC);
+ 
+-	if ((tmp < 0x10) && time_before(again, jiffies)) { 
++	if ((tmp < 0x10) && time_before(again, jiffies)) {
+ 		again = jiffies + HZ * 60;
+ 		/* Page 48 of version 2.0 of the CL-CD1865 databook */
+ 		if (tmp >= 12) {
+@@ -1164,27 +1162,27 @@ static void sx_change_speed(struct speci
+ 			printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
+ 			        "Warning: overstressing Cirrus chip. "
+ 			        "This might not work.\n"
+-			        "Read specialix.txt for more info.\n", 
++			        "Read specialix.txt for more info.\n",
+ 			        port_No (port), tmp);
+ 		}
+ 	}
+ 	spin_lock_irqsave(&bp->lock, flags);
+-	sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); 
+-	sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); 
+-	sx_out(bp, CD186x_RBPRL, tmp & 0xff); 
++	sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
++	sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
++	sx_out(bp, CD186x_RBPRL, tmp & 0xff);
+ 	sx_out(bp, CD186x_TBPRL, tmp & 0xff);
+ 	spin_unlock_irqrestore(&bp->lock, flags);
+ 	if (port->custom_divisor) {
+ 		baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
+ 		baud = ( baud + 5 ) / 10;
+-	} else 
++	} else
+ 		baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
+ 
+ 	/* Two timer ticks seems enough to wakeup something like SLIP driver */
+-	tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;		
++	tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
+ 	port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
+ 					      SERIAL_XMIT_SIZE - 1 : tmp);
+-	
++
+ 	/* Receiver timeout will be transmission time for 1.5 chars */
+ 	tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
+ 	tmp = (tmp > 0xff) ? 0xff : tmp;
+@@ -1205,29 +1203,29 @@ static void sx_change_speed(struct speci
+ 		cor1 |= COR1_8BITS;
+ 		break;
+ 	}
+-	
+-	if (C_CSTOPB(tty)) 
++
++	if (C_CSTOPB(tty))
+ 		cor1 |= COR1_2SB;
+-	
++
+ 	cor1 |= COR1_IGNORE;
+ 	if (C_PARENB(tty)) {
+ 		cor1 |= COR1_NORMPAR;
+-		if (C_PARODD(tty)) 
++		if (C_PARODD(tty))
+ 			cor1 |= COR1_ODDP;
+-		if (I_INPCK(tty)) 
++		if (I_INPCK(tty))
+ 			cor1 &= ~COR1_IGNORE;
+ 	}
+ 	/* Set marking of some errors */
+ 	port->mark_mask = RCSR_OE | RCSR_TOUT;
+-	if (I_INPCK(tty)) 
++	if (I_INPCK(tty))
+ 		port->mark_mask |= RCSR_FE | RCSR_PE;
+-	if (I_BRKINT(tty) || I_PARMRK(tty)) 
++	if (I_BRKINT(tty) || I_PARMRK(tty))
+ 		port->mark_mask |= RCSR_BREAK;
+-	if (I_IGNPAR(tty)) 
++	if (I_IGNPAR(tty))
+ 		port->mark_mask &= ~(RCSR_FE | RCSR_PE);
+ 	if (I_IGNBRK(tty)) {
+ 		port->mark_mask &= ~RCSR_BREAK;
+-		if (I_IGNPAR(tty)) 
++		if (I_IGNPAR(tty))
+ 			/* Real raw mode. Ignore all */
+ 			port->mark_mask &= ~RCSR_OE;
+ 	}
+@@ -1241,7 +1239,7 @@ static void sx_change_speed(struct speci
+ 		tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
+ 		spin_unlock_irqrestore(&bp->lock, flags);
+ #else
+-		port->COR2 |= COR2_CTSAE; 
++		port->COR2 |= COR2_CTSAE;
+ #endif
+ 	}
+ 	/* Enable Software Flow Control. FIXME: I'm not sure about this */
+@@ -1264,11 +1262,11 @@ static void sx_change_speed(struct speci
+ 		mcor1 |= MCOR1_CDZD;
+ 		mcor2 |= MCOR2_CDOD;
+ 	}
+-	
+-	if (C_CREAD(tty)) 
++
++	if (C_CREAD(tty))
+ 		/* Enable receiver */
+ 		port->IER |= IER_RXD;
+-	
++
+ 	/* Set input FIFO size (1-8 bytes) */
+ 	cor3 |= sx_rxfifo;
+ 	/* Setting up CD186x channel registers */
+@@ -1311,11 +1309,11 @@ static int sx_setup_port(struct speciali
+ 		func_exit();
+ 		return 0;
+ 	}
+-	
++
+ 	if (!port->xmit_buf) {
+ 		/* We may sleep in get_zeroed_page() */
+ 		unsigned long tmp;
+-		
++
+ 		if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
+ 			func_exit();
+ 			return -ENOMEM;
+@@ -1328,10 +1326,10 @@ static int sx_setup_port(struct speciali
+ 		}
+ 		port->xmit_buf = (unsigned char *) tmp;
+ 	}
+-		
++
+ 	spin_lock_irqsave(&port->lock, flags);
+ 
+-	if (port->tty) 
++	if (port->tty)
+ 		clear_bit(TTY_IO_ERROR, &port->tty->flags);
+ 
+ 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
+@@ -1340,7 +1338,7 @@ static int sx_setup_port(struct speciali
+ 
+ 	spin_unlock_irqrestore(&port->lock, flags);
+ 
+-		
++
+ 	func_exit();
+ 	return 0;
+ }
+@@ -1352,14 +1350,14 @@ static void sx_shutdown_port(struct spec
+ 	struct tty_struct *tty;
+ 	int i;
+ 	unsigned long flags;
+-	
++
+ 	func_enter();
+ 
+ 	if (!(port->flags & ASYNC_INITIALIZED)) {
+ 		func_exit();
+ 		return;
+ 	}
+-	
++
+ 	if (sx_debug & SX_DEBUG_FIFO) {
+ 		dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
+ 			board_No(bp), port_No(port), port->overrun);
+@@ -1394,13 +1392,13 @@ static void sx_shutdown_port(struct spec
+ 	if (tty)
+ 		set_bit(TTY_IO_ERROR, &tty->flags);
+ 	port->flags &= ~ASYNC_INITIALIZED;
+-	
+-	if (!bp->count) 
++
++	if (!bp->count)
+ 		sx_shutdown_board(bp);
+ 	func_exit();
+ }
+ 
+-	
++
+ static int block_til_ready(struct tty_struct *tty, struct file * filp,
+                            struct specialix_port *port)
+ {
+@@ -1427,7 +1425,7 @@ static int block_til_ready(struct tty_st
+ 			return -ERESTARTSYS;
+ 		}
+ 	}
+-	
++
+ 	/*
+ 	 * If non-blocking mode is set, or the port is not enabled,
+ 	 * then make the check up front and then exit.
+@@ -1477,7 +1475,7 @@ static int block_til_ready(struct tty_st
+ 			if (port->flags & ASYNC_HUP_NOTIFY)
+ 				retval = -EAGAIN;
+ 			else
+-				retval = -ERESTARTSYS;	
++				retval = -ERESTARTSYS;
+ 			break;
+ 		}
+ 		if (!(port->flags & ASYNC_CLOSING) &&
+@@ -1506,7 +1504,7 @@ static int block_til_ready(struct tty_st
+ 	port->flags |= ASYNC_NORMAL_ACTIVE;
+ 	func_exit();
+ 	return 0;
+-}	
++}
+ 
+ 
+ static int sx_open(struct tty_struct * tty, struct file * filp)
+@@ -1526,7 +1524,7 @@ static int sx_open(struct tty_struct * t
+ 		func_exit();
+ 		return -ENODEV;
+ 	}
+-	
++
+ 	bp = &sx_board[board];
+ 	port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
+ 	port->overrun = 0;
+@@ -1557,7 +1555,7 @@ static int sx_open(struct tty_struct * t
+ 		func_enter();
+ 		return error;
+ 	}
+-	
++
+ 	if ((error = block_til_ready(tty, filp, port))) {
+ 		func_enter();
+ 		return error;
+@@ -1574,7 +1572,7 @@ static void sx_close(struct tty_struct *
+ 	struct specialix_board *bp;
+ 	unsigned long flags;
+ 	unsigned long timeout;
+-	
++
+ 	func_enter();
+ 	if (!port || sx_paranoia_check(port, tty->name, "close")) {
+ 		func_exit();
+@@ -1587,7 +1585,7 @@ static void sx_close(struct tty_struct *
+ 		func_exit();
+ 		return;
+ 	}
+-	
++
+ 	bp = port_Board(port);
+ 	if ((tty->count == 1) && (port->count != 1)) {
+ 		printk(KERN_ERR "sx%d: sx_close: bad port count;"
+@@ -1607,7 +1605,7 @@ static void sx_close(struct tty_struct *
+ 	}
+ 	port->flags |= ASYNC_CLOSING;
+ 	/*
+-	 * Now we wait for the transmit buffer to clear; and we notify 
++	 * Now we wait for the transmit buffer to clear; and we notify
+ 	 * the line discipline to only process XON/XOFF characters.
+ 	 */
+ 	tty->closing = 1;
+@@ -1681,7 +1679,7 @@ static void sx_close(struct tty_struct *
+ }
+ 
+ 
+-static int sx_write(struct tty_struct * tty, 
++static int sx_write(struct tty_struct * tty,
+                     const unsigned char *buf, int count)
+ {
+ 	struct specialix_port *port = (struct specialix_port *)tty->driver_data;
+@@ -1694,7 +1692,7 @@ static int sx_write(struct tty_struct * 
+ 		func_exit();
+ 		return 0;
+ 	}
+-	
++
+ 	bp = port_Board(port);
+ 
+ 	if (!tty || !port->xmit_buf || !tmp_buf) {
+@@ -1824,7 +1822,7 @@ static int sx_chars_in_buffer(struct tty
+ 	struct specialix_port *port = (struct specialix_port *)tty->driver_data;
+ 
+ 	func_enter();
+-	
++
+ 	if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
+ 		func_exit();
+ 		return 0;
+@@ -1881,13 +1879,13 @@ static int sx_tiocmget(struct tty_struct
+ 		port_No(port), status, sx_in (bp, CD186x_CAR));
+ 	dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
+ 	if (SX_CRTSCTS(port->tty)) {
+-		result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ 
++		result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
+ 		          |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
+ 		          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
+ 		          |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
+ 		          |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
+ 	} else {
+-		result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ 
++		result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
+ 		          |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
+ 		          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
+ 		          |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
+@@ -1955,7 +1953,7 @@ static inline void sx_send_break(struct 
+ {
+ 	struct specialix_board *bp = port_Board(port);
+ 	unsigned long flags;
+-	
++
+ 	func_enter();
+ 
+ 	spin_lock_irqsave (&port->lock, flags);
+@@ -1996,8 +1994,8 @@ static inline int sx_set_serial_info(str
+ 		func_enter();
+ 		return -EFAULT;
+ 	}
+-	
+-#if 0	
++
++#if 0
+ 	if ((tmp.irq != bp->irq) ||
+ 	    (tmp.port != bp->base) ||
+ 	    (tmp.type != PORT_CIRRUS) ||
+@@ -2008,12 +2006,12 @@ static inline int sx_set_serial_info(str
+ 		func_exit();
+ 		return -EINVAL;
+ 	}
+-#endif	
++#endif
+ 
+ 	change_speed = ((port->flags & ASYNC_SPD_MASK) !=
+ 			(tmp.flags & ASYNC_SPD_MASK));
+ 	change_speed |= (tmp.custom_divisor != port->custom_divisor);
+-	
++
+ 	if (!capable(CAP_SYS_ADMIN)) {
+ 		if ((tmp.close_delay != port->close_delay) ||
+ 		    (tmp.closing_wait != port->closing_wait) ||
+@@ -2045,7 +2043,7 @@ static inline int sx_get_serial_info(str
+ {
+ 	struct serial_struct tmp;
+ 	struct specialix_board *bp = port_Board(port);
+-	
++
+ 	func_enter();
+ 
+ 	/*
+@@ -2074,7 +2072,7 @@ static inline int sx_get_serial_info(str
+ }
+ 
+ 
+-static int sx_ioctl(struct tty_struct * tty, struct file * filp, 
++static int sx_ioctl(struct tty_struct * tty, struct file * filp,
+                     unsigned int cmd, unsigned long arg)
+ {
+ 	struct specialix_port *port = (struct specialix_port *)tty->driver_data;
+@@ -2087,7 +2085,7 @@ static int sx_ioctl(struct tty_struct * 
+ 		func_exit();
+ 		return -ENODEV;
+ 	}
+-	
++
+ 	switch (cmd) {
+ 	 case TCSBRK:	/* SVID version: non-zero arg --> no break */
+ 		retval = tty_check_change(tty);
+@@ -2129,7 +2127,7 @@ static int sx_ioctl(struct tty_struct * 
+ 	 case TIOCGSERIAL:
+ 		 func_exit();
+ 		return sx_get_serial_info(port, argp);
+-	 case TIOCSSERIAL:	
++	 case TIOCSSERIAL:
+ 		 func_exit();
+ 		return sx_set_serial_info(port, argp);
+ 	 default:
+@@ -2153,16 +2151,16 @@ static void sx_throttle(struct tty_struc
+ 		func_exit();
+ 		return;
+ 	}
+-	
++
+ 	bp = port_Board(port);
+-	
++
+ 	/* Use DTR instead of RTS ! */
+-	if (SX_CRTSCTS (tty)) 
++	if (SX_CRTSCTS (tty))
+ 		port->MSVR &= ~MSVR_DTR;
+ 	else {
+ 		/* Auch!!! I think the system shouldn't call this then. */
+ 		/* Or maybe we're supposed (allowed?) to do our side of hw
+-		   handshake anyway, even when hardware handshake is off. 
++		   handshake anyway, even when hardware handshake is off.
+ 		   When you see this in your logs, please report.... */
+ 		printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
+ 	                 port_No (port));
+@@ -2193,14 +2191,14 @@ static void sx_unthrottle(struct tty_str
+ 	unsigned long flags;
+ 
+ 	func_enter();
+-				
++
+ 	if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
+ 		func_exit();
+ 		return;
+ 	}
+-	
++
+ 	bp = port_Board(port);
+-	
++
+ 	spin_lock_irqsave(&port->lock, flags);
+ 	/* XXXX Use DTR INSTEAD???? */
+ 	if (SX_CRTSCTS(tty)) {
+@@ -2234,14 +2232,14 @@ static void sx_stop(struct tty_struct * 
+ 	unsigned long flags;
+ 
+ 	func_enter();
+-	
++
+ 	if (sx_paranoia_check(port, tty->name, "sx_stop")) {
+ 		func_exit();
+ 		return;
+ 	}
+ 
+ 	bp = port_Board(port);
+-	
++
+ 	spin_lock_irqsave(&port->lock, flags);
+ 	port->IER &= ~IER_TXRDY;
+ 	spin_lock_irqsave(&bp->lock, flags);
+@@ -2261,14 +2259,14 @@ static void sx_start(struct tty_struct *
+ 	unsigned long flags;
+ 
+ 	func_enter();
+-				
++
+ 	if (sx_paranoia_check(port, tty->name, "sx_start")) {
+ 		func_exit();
+ 		return;
+ 	}
+-	
++
+ 	bp = port_Board(port);
+-	
++
+ 	spin_lock_irqsave(&port->lock, flags);
+ 	if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
+ 		port->IER |= IER_TXRDY;
+@@ -2290,13 +2288,13 @@ static void sx_start(struct tty_struct *
+  *
+  * 	serial interrupt routine -> (workqueue) ->
+  * 	do_sx_hangup() -> tty->hangup() -> sx_hangup()
+- * 
++ *
+  */
+ static void do_sx_hangup(void *private_)
+ {
+ 	struct specialix_port	*port = (struct specialix_port *) private_;
+ 	struct tty_struct	*tty;
+-	
++
+ 	func_enter();
+ 
+ 	tty = port->tty;
+@@ -2319,9 +2317,9 @@ static void sx_hangup(struct tty_struct 
+ 		func_exit();
+ 		return;
+ 	}
+-	
++
+ 	bp = port_Board(port);
+-	
++
+ 	sx_shutdown_port(bp, port);
+ 	spin_lock_irqsave(&port->lock, flags);
+ 	port->event = 0;
+@@ -2346,10 +2344,10 @@ static void sx_set_termios(struct tty_st
+ 	struct specialix_port *port = (struct specialix_port *)tty->driver_data;
+ 	unsigned long flags;
+ 	struct specialix_board  * bp;
+-				
++
+ 	if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
+ 		return;
+-	
++
+ 	if (tty->termios->c_cflag == old_termios->c_cflag &&
+ 	    tty->termios->c_iflag == old_termios->c_iflag)
+ 		return;
+@@ -2420,7 +2418,7 @@ static int sx_init_drivers(void)
+ 		func_exit();
+ 		return 1;
+ 	}
+-	
++
+ 	if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
+ 		printk(KERN_ERR "sx: Couldn't get free page.\n");
+ 		put_tty_driver(specialix_driver);
+@@ -2457,7 +2455,7 @@ static int sx_init_drivers(void)
+ 		init_waitqueue_head(&sx_port[i].close_wait);
+ 		spin_lock_init(&sx_port[i].lock);
+ 	}
+-	
++
+ 	func_exit();
+ 	return 0;
+ }
+@@ -2472,8 +2470,8 @@ static void sx_release_drivers(void)
+ 	func_exit();
+ }
+ 
+-/* 
+- * This routine must be called by kernel at boot time 
++/*
++ * This routine must be called by kernel at boot time
+  */
+ static int __init specialix_init(void)
+ {
+@@ -2489,7 +2487,7 @@ static int __init specialix_init(void)
+ #else
+ 	printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
+ #endif
+-	
++
+ 	for (i = 0; i < SX_NBOARD; i++)
+ 		sx_board[i].lock = SPIN_LOCK_UNLOCKED;
+ 
+@@ -2498,7 +2496,7 @@ static int __init specialix_init(void)
+ 		return -EIO;
+ 	}
+ 
+-	for (i = 0; i < SX_NBOARD; i++) 
++	for (i = 0; i < SX_NBOARD; i++)
+ 		if (sx_board[i].base && !sx_probe(&sx_board[i]))
+ 			found++;
+ 
+@@ -2512,8 +2510,8 @@ static int __init specialix_init(void)
+ 				i++;
+ 				continue;
+ 			}
+-			pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+-			                        PCI_DEVICE_ID_SPECIALIX_IO8, 
++			pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
++			                        PCI_DEVICE_ID_SPECIALIX_IO8,
+ 			                        pdev);
+ 			if (!pdev) break;
+ 
+@@ -2557,10 +2555,10 @@ module_param(sx_poll, int, 0);
+ /*
+  * You can setup up to 4 boards.
+  * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
+- * You should specify the IRQs too in that case "irq=....,...". 
+- * 
++ * You should specify the IRQs too in that case "irq=....,...".
++ *
+  * More than 4 boards in one computer is not possible, as the card can
+- * only use 4 different interrupts. 
++ * only use 4 different interrupts.
+  *
+  */
+ static int __init specialix_init_module(void)
+@@ -2583,16 +2581,16 @@ static int __init specialix_init_module(
+ 
+ 	return specialix_init();
+ }
+-	
++
+ static void __exit specialix_exit_module(void)
+ {
+ 	int i;
+-	
++
+ 	func_enter();
+ 
+ 	sx_release_drivers();
+ 	for (i = 0; i < SX_NBOARD; i++)
+-		if (sx_board[i].flags & SX_BOARD_PRESENT) 
++		if (sx_board[i].flags & SX_BOARD_PRESENT)
+ 			sx_release_io_range(&sx_board[i]);
+ #ifdef SPECIALIX_TIMER
+ 	del_timer (&missed_irq_timer);
+diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
+--- a/drivers/char/stallion.c
++++ b/drivers/char/stallion.c
+@@ -3095,7 +3095,9 @@ static int __init stl_init(void)
+ 		devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
+ 				S_IFCHR|S_IRUSR|S_IWUSR,
+ 				"staliomem/%d", i);
+-		class_device_create(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i);
++		class_device_create(stallion_class, NULL,
++				    MKDEV(STL_SIOMEMMAJOR, i), NULL,
++				    "staliomem%d", i);
+ 	}
+ 
+ 	stl_serial->owner = THIS_MODULE;
+diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
+--- a/drivers/char/synclink.c
++++ b/drivers/char/synclink.c
+@@ -912,6 +912,7 @@ MODULE_DEVICE_TABLE(pci, synclink_pci_tb
+ MODULE_LICENSE("GPL");
+ 
+ static struct pci_driver synclink_pci_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "synclink",
+ 	.id_table	= synclink_pci_tbl,
+ 	.probe		= synclink_init_one,
+diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
+--- a/drivers/char/synclinkmp.c
++++ b/drivers/char/synclinkmp.c
+@@ -500,6 +500,7 @@ MODULE_DEVICE_TABLE(pci, synclinkmp_pci_
+ MODULE_LICENSE("GPL");
+ 
+ static struct pci_driver synclinkmp_pci_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "synclinkmp",
+ 	.id_table	= synclinkmp_pci_tbl,
+ 	.probe		= synclinkmp_init_one,
+diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
+--- a/drivers/char/tb0219.c
++++ b/drivers/char/tb0219.c
+@@ -17,7 +17,7 @@
+  *  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/platform_device.h>
+ #include <linux/fs.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
+--- a/drivers/char/tipar.c
++++ b/drivers/char/tipar.c
+@@ -436,7 +436,7 @@ tipar_register(int nr, struct parport *p
+ 		goto out;
+ 	}
+ 
+-	class_device_create(tipar_class, MKDEV(TIPAR_MAJOR,
++	class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
+ 			TIPAR_MINOR + nr), NULL, "par%d", nr);
+ 	/* Use devfs, tree: /dev/ticables/par/[0..2] */
+ 	err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
+diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/char/tlclk.c
+@@ -0,0 +1,897 @@
++/*
++ * Telecom Clock driver for Intel NetStructure(tm) MPCBL0010
++ *
++ * Copyright (C) 2005 Kontron Canada
++ *
++ * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Send feedback to <sebastien.bouchard at ca.kontron.com> and the current
++ * Maintainer  <mark.gross at intel.com>
++ *
++ * Description : This is the TELECOM CLOCK module driver for the ATCA
++ * MPCBL0010 ATCA computer.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>	/* printk() */
++#include <linux/fs.h>		/* everything... */
++#include <linux/errno.h>	/* error codes */
++#include <linux/delay.h>	/* udelay */
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/timer.h>
++#include <linux/sysfs.h>
++#include <linux/device.h>
++#include <linux/miscdevice.h>
++#include <linux/platform_device.h>
++#include <asm/io.h>		/* inb/outb */
++#include <asm/uaccess.h>
++
++MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard at ca.kontron.com>");
++MODULE_LICENSE("GPL");
++
++/*Hardware Reset of the PLL */
++#define RESET_ON	0x00
++#define RESET_OFF	0x01
++
++/* MODE SELECT */
++#define NORMAL_MODE 	0x00
++#define HOLDOVER_MODE	0x10
++#define FREERUN_MODE	0x20
++
++/* FILTER SELECT */
++#define FILTER_6HZ	0x04
++#define FILTER_12HZ	0x00
++
++/* SELECT REFERENCE FREQUENCY */
++#define REF_CLK1_8kHz		0x00
++#define REF_CLK2_19_44MHz	0x02
++
++/* Select primary or secondary redundant clock */
++#define PRIMARY_CLOCK	0x00
++#define SECONDARY_CLOCK	0x01
++
++/* CLOCK TRANSMISSION DEFINE */
++#define CLK_8kHz	0xff
++#define CLK_16_384MHz	0xfb
++
++#define CLK_1_544MHz	0x00
++#define CLK_2_048MHz	0x01
++#define CLK_4_096MHz	0x02
++#define CLK_6_312MHz	0x03
++#define CLK_8_192MHz	0x04
++#define CLK_19_440MHz	0x06
++
++#define CLK_8_592MHz	0x08
++#define CLK_11_184MHz	0x09
++#define CLK_34_368MHz	0x0b
++#define CLK_44_736MHz	0x0a
++
++/* RECEIVED REFERENCE */
++#define AMC_B1 0
++#define AMC_B2 1
++
++/* HARDWARE SWITCHING DEFINE */
++#define HW_ENABLE	0x80
++#define HW_DISABLE	0x00
++
++/* HARDWARE SWITCHING MODE DEFINE */
++#define PLL_HOLDOVER	0x40
++#define LOST_CLOCK	0x00
++
++/* ALARMS DEFINE */
++#define UNLOCK_MASK	0x10
++#define HOLDOVER_MASK	0x20
++#define SEC_LOST_MASK	0x40
++#define PRI_LOST_MASK	0x80
++
++/* INTERRUPT CAUSE DEFINE */
++
++#define PRI_LOS_01_MASK		0x01
++#define PRI_LOS_10_MASK		0x02
++
++#define SEC_LOS_01_MASK		0x04
++#define SEC_LOS_10_MASK		0x08
++
++#define HOLDOVER_01_MASK	0x10
++#define HOLDOVER_10_MASK	0x20
++
++#define UNLOCK_01_MASK		0x40
++#define UNLOCK_10_MASK		0x80
++
++struct tlclk_alarms {
++	__u32 lost_clocks;
++	__u32 lost_primary_clock;
++	__u32 lost_secondary_clock;
++	__u32 primary_clock_back;
++	__u32 secondary_clock_back;
++	__u32 switchover_primary;
++	__u32 switchover_secondary;
++	__u32 pll_holdover;
++	__u32 pll_end_holdover;
++	__u32 pll_lost_sync;
++	__u32 pll_sync;
++};
++/* Telecom clock I/O register definition */
++#define TLCLK_BASE 0xa08
++#define TLCLK_REG0 TLCLK_BASE
++#define TLCLK_REG1 (TLCLK_BASE+1)
++#define TLCLK_REG2 (TLCLK_BASE+2)
++#define TLCLK_REG3 (TLCLK_BASE+3)
++#define TLCLK_REG4 (TLCLK_BASE+4)
++#define TLCLK_REG5 (TLCLK_BASE+5)
++#define TLCLK_REG6 (TLCLK_BASE+6)
++#define TLCLK_REG7 (TLCLK_BASE+7)
++
++#define SET_PORT_BITS(port, mask, val) outb(((inb(port) & mask) | val), port)
++
++/* 0 = Dynamic allocation of the major device number */
++#define TLCLK_MAJOR 0
++
++/* sysfs interface definition:
++Upon loading the driver will create a sysfs directory under
++/sys/devices/platform/telco_clock.
++
++This directory exports the following interfaces.  There operation is
++documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4.
++alarms				:
++current_ref			:
++enable_clk3a_output		:
++enable_clk3b_output		:
++enable_clka0_output		:
++enable_clka1_output		:
++enable_clkb0_output		:
++enable_clkb1_output		:
++filter_select			:
++hardware_switching		:
++hardware_switching_mode		:
++interrupt_switch		:
++mode_select			:
++refalign			:
++reset				:
++select_amcb1_transmit_clock	:
++select_amcb2_transmit_clock	:
++select_redundant_clock		:
++select_ref_frequency		:
++test_mode			:
++
++All sysfs interfaces are integers in hex format, i.e echo 99 > refalign
++has the same effect as echo 0x99 > refalign.
++*/
++
++static unsigned int telclk_interrupt;
++
++static int int_events;		/* Event that generate a interrupt */
++static int got_event;		/* if events processing have been done */
++
++static void switchover_timeout(unsigned long data);
++static struct timer_list switchover_timer =
++	TIMER_INITIALIZER(switchover_timeout , 0, 0);
++
++static struct tlclk_alarms *alarm_events;
++
++static DEFINE_SPINLOCK(event_lock);
++
++static int tlclk_major = TLCLK_MAJOR;
++
++static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs);
++
++static DECLARE_WAIT_QUEUE_HEAD(wq);
++
++static int tlclk_open(struct inode *inode, struct file *filp)
++{
++	int result;
++
++	/* Make sure there is no interrupt pending while
++	 * initialising interrupt handler */
++	inb(TLCLK_REG6);
++
++	/* This device is wired through the FPGA IO space of the ATCA blade
++	 * we can't share this IRQ */
++	result = request_irq(telclk_interrupt, &tlclk_interrupt,
++			     SA_INTERRUPT, "telco_clock", tlclk_interrupt);
++	if (result == -EBUSY) {
++		printk(KERN_ERR "telco_clock: Interrupt can't be reserved!\n");
++		return -EBUSY;
++	}
++	inb(TLCLK_REG6);	/* Clear interrupt events */
++
++	return 0;
++}
++
++static int tlclk_release(struct inode *inode, struct file *filp)
++{
++	free_irq(telclk_interrupt, tlclk_interrupt);
++
++	return 0;
++}
++
++ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
++		loff_t *f_pos)
++{
++	if (count < sizeof(struct tlclk_alarms))
++		return -EIO;
++
++	wait_event_interruptible(wq, got_event);
++	if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms)))
++		return -EFAULT;
++
++	memset(alarm_events, 0, sizeof(struct tlclk_alarms));
++	got_event = 0;
++
++	return  sizeof(struct tlclk_alarms);
++}
++
++ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count,
++	    loff_t *f_pos)
++{
++	return 0;
++}
++
++static struct file_operations tlclk_fops = {
++	.read = tlclk_read,
++	.write = tlclk_write,
++	.open = tlclk_open,
++	.release = tlclk_release,
++
++};
++
++static struct miscdevice tlclk_miscdev = {
++	.minor = MISC_DYNAMIC_MINOR,
++	.name = "telco_clock",
++	.fops = &tlclk_fops,
++};
++
++static ssize_t show_current_ref(struct device *d,
++		struct device_attribute *attr, char *buf)
++{
++	unsigned long ret_val;
++	unsigned long flags;
++
++	spin_lock_irqsave(&event_lock, flags);
++	ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return sprintf(buf, "0x%lX\n", ret_val);
++}
++
++static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
++
++
++static ssize_t show_interrupt_switch(struct device *d,
++		struct device_attribute *attr, char *buf)
++{
++	unsigned long ret_val;
++	unsigned long flags;
++
++	spin_lock_irqsave(&event_lock, flags);
++	ret_val = inb(TLCLK_REG6);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return sprintf(buf, "0x%lX\n", ret_val);
++}
++
++static DEVICE_ATTR(interrupt_switch, S_IRUGO,
++		show_interrupt_switch, NULL);
++
++static ssize_t show_alarms(struct device *d,
++		struct device_attribute *attr,  char *buf)
++{
++	unsigned long ret_val;
++	unsigned long flags;
++
++	spin_lock_irqsave(&event_lock, flags);
++	ret_val = (inb(TLCLK_REG2) & 0xf0);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return sprintf(buf, "0x%lX\n", ret_val);
++}
++
++static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
++
++static ssize_t store_enable_clk3b_output(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned char val;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, ": tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL,
++		store_enable_clk3b_output);
++
++static ssize_t store_enable_clk3a_output(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long flags;
++	unsigned long tmp;
++	unsigned char val;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL,
++		store_enable_clk3a_output);
++
++static ssize_t store_enable_clkb1_output(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long flags;
++	unsigned long tmp;
++	unsigned char val;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL,
++		store_enable_clkb1_output);
++
++
++static ssize_t store_enable_clka1_output(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long flags;
++	unsigned long tmp;
++	unsigned char val;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL,
++		store_enable_clka1_output);
++
++static ssize_t store_enable_clkb0_output(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long flags;
++	unsigned long tmp;
++	unsigned char val;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL,
++		store_enable_clkb0_output);
++
++static ssize_t store_enable_clka0_output(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long flags;
++	unsigned long tmp;
++	unsigned char val;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG2, 0xfe, val);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL,
++		store_enable_clka0_output);
++
++static ssize_t store_test_mode(struct device *d,
++		struct device_attribute *attr,  const char *buf, size_t count)
++{
++	unsigned long flags;
++	unsigned long tmp;
++	unsigned char val;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG4, 0xfd, 2);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(test_mode, S_IWUGO, NULL, store_test_mode);
++
++static ssize_t store_select_amcb2_transmit_clock(struct device *d,
++		struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long flags;
++	unsigned long tmp;
++	unsigned char val;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++		if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
++			SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28);
++			SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
++		} else if (val >= CLK_8_592MHz) {
++			SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38);
++			switch (val) {
++			case CLK_8_592MHz:
++				SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
++				break;
++			case CLK_11_184MHz:
++				SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
++				break;
++			case CLK_34_368MHz:
++				SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
++				break;
++			case CLK_44_736MHz:
++				SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
++				break;
++			}
++		} else
++			SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3);
++
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL,
++	store_select_amcb2_transmit_clock);
++
++static ssize_t store_select_amcb1_transmit_clock(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned char val;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++		if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
++			SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5);
++			SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
++		} else if (val >= CLK_8_592MHz) {
++			SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7);
++			switch (val) {
++			case CLK_8_592MHz:
++				SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
++				break;
++			case CLK_11_184MHz:
++				SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
++				break;
++			case CLK_34_368MHz:
++				SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
++				break;
++			case CLK_44_736MHz:
++				SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
++				break;
++			}
++		} else
++			SET_PORT_BITS(TLCLK_REG3, 0xf8, val);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL,
++		store_select_amcb1_transmit_clock);
++
++static ssize_t store_select_redundant_clock(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned char val;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG1, 0xfe, val);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL,
++		store_select_redundant_clock);
++
++static ssize_t store_select_ref_frequency(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned char val;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG1, 0xfd, val);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL,
++		store_select_ref_frequency);
++
++static ssize_t store_filter_select(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned char val;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG0, 0xfb, val);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select);
++
++static ssize_t store_hardware_switching_mode(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned char val;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG0, 0xbf, val);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL,
++		store_hardware_switching_mode);
++
++static ssize_t store_hardware_switching(struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned char val;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG0, 0x7f, val);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL,
++		store_hardware_switching);
++
++static ssize_t store_refalign (struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
++	udelay(2);
++	SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08);
++	udelay(2);
++	SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign);
++
++static ssize_t store_mode_select (struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned char val;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG0, 0xcf, val);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select);
++
++static ssize_t store_reset (struct device *d,
++		 struct device_attribute *attr, const char *buf, size_t count)
++{
++	unsigned long tmp;
++	unsigned char val;
++	unsigned long flags;
++
++	sscanf(buf, "%lX", &tmp);
++	dev_dbg(d, "tmp = 0x%lX\n", tmp);
++
++	val = (unsigned char)tmp;
++	spin_lock_irqsave(&event_lock, flags);
++	SET_PORT_BITS(TLCLK_REG4, 0xfd, val);
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return strnlen(buf, count);
++}
++
++static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset);
++
++static struct attribute *tlclk_sysfs_entries[] = {
++	&dev_attr_current_ref.attr,
++	&dev_attr_interrupt_switch.attr,
++	&dev_attr_alarms.attr,
++	&dev_attr_enable_clk3a_output.attr,
++	&dev_attr_enable_clk3b_output.attr,
++	&dev_attr_enable_clkb1_output.attr,
++	&dev_attr_enable_clka1_output.attr,
++	&dev_attr_enable_clkb0_output.attr,
++	&dev_attr_enable_clka0_output.attr,
++	&dev_attr_test_mode.attr,
++	&dev_attr_select_amcb1_transmit_clock.attr,
++	&dev_attr_select_amcb2_transmit_clock.attr,
++	&dev_attr_select_redundant_clock.attr,
++	&dev_attr_select_ref_frequency.attr,
++	&dev_attr_filter_select.attr,
++	&dev_attr_hardware_switching_mode.attr,
++	&dev_attr_hardware_switching.attr,
++	&dev_attr_refalign.attr,
++	&dev_attr_mode_select.attr,
++	&dev_attr_reset.attr,
++	NULL
++};
++
++static struct attribute_group tlclk_attribute_group = {
++	.name = NULL,		/* put in device directory */
++	.attrs = tlclk_sysfs_entries,
++};
++
++static struct platform_device *tlclk_device;
++
++static int __init tlclk_init(void)
++{
++	int ret;
++
++	ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops);
++	if (ret < 0) {
++		printk(KERN_ERR "telco_clock: can't get major! %d\n", tlclk_major);
++		return ret;
++	}
++	alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
++	if (!alarm_events)
++		goto out1;
++
++	/* Read telecom clock IRQ number (Set by BIOS) */
++	if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
++		printk(KERN_ERR "tlclk: request_region failed! 0x%X\n",
++			TLCLK_BASE);
++		ret = -EBUSY;
++		goto out2;
++	}
++	telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
++
++	if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */
++		printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw\n",
++			telclk_interrupt);
++		ret = -ENXIO;
++		goto out3;
++	}
++
++	init_timer(&switchover_timer);
++
++	ret = misc_register(&tlclk_miscdev);
++	if (ret < 0) {
++		printk(KERN_ERR " misc_register retruns %d\n", ret);
++		ret = -EBUSY;
++		goto out3;
++	}
++
++	tlclk_device = platform_device_register_simple("telco_clock",
++				-1, NULL, 0);
++	if (!tlclk_device) {
++		printk(KERN_ERR " platform_device_register retruns 0x%X\n",
++			(unsigned int) tlclk_device);
++		ret = -EBUSY;
++		goto out4;
++	}
++
++	ret = sysfs_create_group(&tlclk_device->dev.kobj,
++			&tlclk_attribute_group);
++	if (ret) {
++		printk(KERN_ERR "failed to create sysfs device attributes\n");
++		sysfs_remove_group(&tlclk_device->dev.kobj,
++			&tlclk_attribute_group);
++		goto out5;
++	}
++
++	return 0;
++out5:
++	platform_device_unregister(tlclk_device);
++out4:
++	misc_deregister(&tlclk_miscdev);
++out3:
++	release_region(TLCLK_BASE, 8);
++out2:
++	kfree(alarm_events);
++out1:
++	unregister_chrdev(tlclk_major, "telco_clock");
++	return ret;
++}
++
++static void __exit tlclk_cleanup(void)
++{
++	sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group);
++	platform_device_unregister(tlclk_device);
++	misc_deregister(&tlclk_miscdev);
++	unregister_chrdev(tlclk_major, "telco_clock");
++
++	release_region(TLCLK_BASE, 8);
++	del_timer_sync(&switchover_timer);
++	kfree(alarm_events);
++
++}
++
++static void switchover_timeout(unsigned long data)
++{
++	if ((data & 1)) {
++		if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08))
++			alarm_events->switchover_primary++;
++	} else {
++		if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08))
++			alarm_events->switchover_secondary++;
++	}
++
++	/* Alarm processing is done, wake up read task */
++	del_timer(&switchover_timer);
++	got_event = 1;
++	wake_up(&wq);
++}
++
++static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&event_lock, flags);
++	/* Read and clear interrupt events */
++	int_events = inb(TLCLK_REG6);
++
++	/* Primary_Los changed from 0 to 1 ? */
++	if (int_events & PRI_LOS_01_MASK) {
++		if (inb(TLCLK_REG2) & SEC_LOST_MASK)
++			alarm_events->lost_clocks++;
++		else
++			alarm_events->lost_primary_clock++;
++	}
++
++	/* Primary_Los changed from 1 to 0 ? */
++	if (int_events & PRI_LOS_10_MASK) {
++		alarm_events->primary_clock_back++;
++		SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
++	}
++	/* Secondary_Los changed from 0 to 1 ? */
++	if (int_events & SEC_LOS_01_MASK) {
++		if (inb(TLCLK_REG2) & PRI_LOST_MASK)
++			alarm_events->lost_clocks++;
++		else
++			alarm_events->lost_secondary_clock++;
++	}
++	/* Secondary_Los changed from 1 to 0 ? */
++	if (int_events & SEC_LOS_10_MASK) {
++		alarm_events->secondary_clock_back++;
++		SET_PORT_BITS(TLCLK_REG1, 0xFE, 0);
++	}
++	if (int_events & HOLDOVER_10_MASK)
++		alarm_events->pll_end_holdover++;
++
++	if (int_events & UNLOCK_01_MASK)
++		alarm_events->pll_lost_sync++;
++
++	if (int_events & UNLOCK_10_MASK)
++		alarm_events->pll_sync++;
++
++	/* Holdover changed from 0 to 1 ? */
++	if (int_events & HOLDOVER_01_MASK) {
++		alarm_events->pll_holdover++;
++
++		/* TIMEOUT in ~10ms */
++		switchover_timer.expires = jiffies + msecs_to_jiffies(10);
++		switchover_timer.data = inb(TLCLK_REG1);
++		add_timer(&switchover_timer);
++	} else {
++		got_event = 1;
++		wake_up(&wq);
++	}
++	spin_unlock_irqrestore(&event_lock, flags);
++
++	return IRQ_HANDLED;
++}
++
++module_init(tlclk_init);
++module_exit(tlclk_cleanup);
+diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
+--- a/drivers/char/tpm/tpm.c
++++ b/drivers/char/tpm/tpm.c
+@@ -64,7 +64,7 @@ static ssize_t tpm_transmit(struct tpm_c
+ 	if (count == 0)
+ 		return -ENODATA;
+ 	if (count > bufsiz) {
+-		dev_err(&chip->pci_dev->dev,
++		dev_err(chip->dev,
+ 			"invalid count value %x %zx \n", count, bufsiz);
+ 		return -E2BIG;
+ 	}
+@@ -72,21 +72,21 @@ static ssize_t tpm_transmit(struct tpm_c
+ 	down(&chip->tpm_mutex);
+ 
+ 	if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+-		dev_err(&chip->pci_dev->dev,
++		dev_err(chip->dev,
+ 			"tpm_transmit: tpm_send: error %zd\n", rc);
+ 		goto out;
+ 	}
+ 
+ 	stop = jiffies + 2 * 60 * HZ;
+ 	do {
+-		u8 status = inb(chip->vendor->base + 1);
++		u8 status = chip->vendor->status(chip);
+ 		if ((status & chip->vendor->req_complete_mask) ==
+ 		    chip->vendor->req_complete_val) {
+ 			goto out_recv;
+ 		}
+ 
+ 		if ((status == chip->vendor->req_canceled)) {
+-			dev_err(&chip->pci_dev->dev, "Operation Canceled\n");
++			dev_err(chip->dev, "Operation Canceled\n");
+ 			rc = -ECANCELED;
+ 			goto out;
+ 		}
+@@ -97,14 +97,14 @@ static ssize_t tpm_transmit(struct tpm_c
+ 
+ 
+ 	chip->vendor->cancel(chip);
+-	dev_err(&chip->pci_dev->dev, "Operation Timed out\n");
++	dev_err(chip->dev, "Operation Timed out\n");
+ 	rc = -ETIME;
+ 	goto out;
+ 
+ out_recv:
+ 	rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+ 	if (rc < 0)
+-		dev_err(&chip->pci_dev->dev,
++		dev_err(chip->dev,
+ 			"tpm_transmit: tpm_recv: error %zd\n", rc);
+ out:
+ 	up(&chip->tpm_mutex);
+@@ -139,15 +139,14 @@ ssize_t tpm_show_pcrs(struct device *dev
+ 	__be32 index;
+ 	char *str = buf;
+ 
+-	struct tpm_chip *chip =
+-	    pci_get_drvdata(to_pci_dev(dev));
++	struct tpm_chip *chip = dev_get_drvdata(dev);
+ 	if (chip == NULL)
+ 		return -ENODEV;
+ 
+ 	memcpy(data, cap_pcr, sizeof(cap_pcr));
+ 	if ((len = tpm_transmit(chip, data, sizeof(data)))
+ 	    < CAP_PCR_RESULT_SIZE) {
+-		dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
++		dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ 				"attempting to determine the number of PCRS\n",
+ 			be32_to_cpu(*((__be32 *) (data + 6))));
+ 		return 0;
+@@ -161,9 +160,10 @@ ssize_t tpm_show_pcrs(struct device *dev
+ 		memcpy(data + 10, &index, 4);
+ 		if ((len = tpm_transmit(chip, data, sizeof(data)))
+ 		    < READ_PCR_RESULT_SIZE){
+-			dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred"
++			dev_dbg(chip->dev, "A TPM error (%d) occurred"
+ 				" attempting to read PCR %d of %d\n",
+-				be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs);
++				be32_to_cpu(*((__be32 *) (data + 6))),
++				i, num_pcrs);
+ 			goto out;
+ 		}
+ 		str += sprintf(str, "PCR-%02d: ", i);
+@@ -191,21 +191,19 @@ ssize_t tpm_show_pubek(struct device *de
+ 	int i, rc;
+ 	char *str = buf;
+ 
+-	struct tpm_chip *chip =
+-	    pci_get_drvdata(to_pci_dev(dev));
++	struct tpm_chip *chip = dev_get_drvdata(dev);
+ 	if (chip == NULL)
+ 		return -ENODEV;
+ 
+-	data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
++	data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
+ 	if (!data)
+ 		return -ENOMEM;
+ 
+ 	memcpy(data, readpubek, sizeof(readpubek));
+-	memset(data + sizeof(readpubek), 0, 20);	/* zero nonce */
+ 
+ 	if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
+ 	    READ_PUBEK_RESULT_SIZE) {
+-		dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
++		dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ 				"attempting to read the PUBEK\n",
+ 			    be32_to_cpu(*((__be32 *) (data + 6))));
+ 		rc = 0;
+@@ -245,7 +243,6 @@ out:
+ 	kfree(data);
+ 	return rc;
+ }
+-
+ EXPORT_SYMBOL_GPL(tpm_show_pubek);
+ 
+ #define CAP_VER_RESULT_SIZE 18
+@@ -274,8 +271,7 @@ ssize_t tpm_show_caps(struct device *dev
+ 	ssize_t len;
+ 	char *str = buf;
+ 
+-	struct tpm_chip *chip =
+-	    pci_get_drvdata(to_pci_dev(dev));
++	struct tpm_chip *chip = dev_get_drvdata(dev);
+ 	if (chip == NULL)
+ 		return -ENODEV;
+ 
+@@ -315,7 +311,6 @@ ssize_t tpm_store_cancel(struct device *
+ }
+ EXPORT_SYMBOL_GPL(tpm_store_cancel);
+ 
+-
+ /*
+  * Device file system interface to the TPM
+  */
+@@ -339,21 +334,20 @@ int tpm_open(struct inode *inode, struct
+ 	}
+ 
+ 	if (chip->num_opens) {
+-		dev_dbg(&chip->pci_dev->dev,
+-			"Another process owns this TPM\n");
++		dev_dbg(chip->dev, "Another process owns this TPM\n");
+ 		rc = -EBUSY;
+ 		goto err_out;
+ 	}
+ 
+ 	chip->num_opens++;
+-	pci_dev_get(chip->pci_dev);
++	get_device(chip->dev);
+ 
+ 	spin_unlock(&driver_lock);
+ 
+ 	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
+ 	if (chip->data_buffer == NULL) {
+ 		chip->num_opens--;
+-		pci_dev_put(chip->pci_dev);
++		put_device(chip->dev);
+ 		return -ENOMEM;
+ 	}
+ 
+@@ -366,7 +360,6 @@ err_out:
+ 	spin_unlock(&driver_lock);
+ 	return rc;
+ }
+-
+ EXPORT_SYMBOL_GPL(tpm_open);
+ 
+ int tpm_release(struct inode *inode, struct file *file)
+@@ -378,15 +371,14 @@ int tpm_release(struct inode *inode, str
+ 	chip->num_opens--;
+ 	del_singleshot_timer_sync(&chip->user_read_timer);
+ 	atomic_set(&chip->data_pending, 0);
+-	pci_dev_put(chip->pci_dev);
++	put_device(chip->dev);
+ 	kfree(chip->data_buffer);
+ 	spin_unlock(&driver_lock);
+ 	return 0;
+ }
+-
+ EXPORT_SYMBOL_GPL(tpm_release);
+ 
+-ssize_t tpm_write(struct file * file, const char __user * buf,
++ssize_t tpm_write(struct file *file, const char __user *buf,
+ 		  size_t size, loff_t * off)
+ {
+ 	struct tpm_chip *chip = file->private_data;
+@@ -422,7 +414,7 @@ ssize_t tpm_write(struct file * file, co
+ 
+ EXPORT_SYMBOL_GPL(tpm_write);
+ 
+-ssize_t tpm_read(struct file * file, char __user * buf,
++ssize_t tpm_read(struct file * file, char __user *buf,
+ 		 size_t size, loff_t * off)
+ {
+ 	struct tpm_chip *chip = file->private_data;
+@@ -444,15 +436,14 @@ ssize_t tpm_read(struct file * file, cha
+ 
+ 	return ret_size;
+ }
+-
+ EXPORT_SYMBOL_GPL(tpm_read);
+ 
+-void __devexit tpm_remove(struct pci_dev *pci_dev)
++void tpm_remove_hardware(struct device *dev)
+ {
+-	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
++	struct tpm_chip *chip = dev_get_drvdata(dev);
+ 
+ 	if (chip == NULL) {
+-		dev_err(&pci_dev->dev, "No device data found\n");
++		dev_err(dev, "No device data found\n");
+ 		return;
+ 	}
+ 
+@@ -462,22 +453,20 @@ void __devexit tpm_remove(struct pci_dev
+ 
+ 	spin_unlock(&driver_lock);
+ 
+-	pci_set_drvdata(pci_dev, NULL);
++	dev_set_drvdata(dev, NULL);
+ 	misc_deregister(&chip->vendor->miscdev);
+ 	kfree(chip->vendor->miscdev.name);
+ 
+-	sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
++	sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
+ 
+-	pci_disable_device(pci_dev);
+-
+-	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
++	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
++		!(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+ 
+ 	kfree(chip);
+ 
+-	pci_dev_put(pci_dev);
++	put_device(dev);
+ }
+-
+-EXPORT_SYMBOL_GPL(tpm_remove);
++EXPORT_SYMBOL_GPL(tpm_remove_hardware);
+ 
+ static u8 savestate[] = {
+ 	0, 193,			/* TPM_TAG_RQU_COMMAND */
+@@ -489,32 +478,30 @@ static u8 savestate[] = {
+  * We are about to suspend. Save the TPM state
+  * so that it can be restored.
+  */
+-int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
++int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
+ {
+-	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
++	struct tpm_chip *chip = dev_get_drvdata(dev);
+ 	if (chip == NULL)
+ 		return -ENODEV;
+ 
+ 	tpm_transmit(chip, savestate, sizeof(savestate));
+ 	return 0;
+ }
+-
+ EXPORT_SYMBOL_GPL(tpm_pm_suspend);
+ 
+ /*
+  * Resume from a power safe. The BIOS already restored
+  * the TPM state.
+  */
+-int tpm_pm_resume(struct pci_dev *pci_dev)
++int tpm_pm_resume(struct device *dev)
+ {
+-	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
++	struct tpm_chip *chip = dev_get_drvdata(dev);
+ 
+ 	if (chip == NULL)
+ 		return -ENODEV;
+ 
+ 	return 0;
+ }
+-
+ EXPORT_SYMBOL_GPL(tpm_pm_resume);
+ 
+ /*
+@@ -524,8 +511,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
+  * upon errant exit from this function specific probe function should call
+  * pci_disable_device
+  */
+-int tpm_register_hardware(struct pci_dev *pci_dev,
+-			  struct tpm_vendor_specific *entry)
++int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
+ {
+ #define DEVNAME_SIZE 7
+ 
+@@ -534,12 +520,10 @@ int tpm_register_hardware(struct pci_dev
+ 	int i, j;
+ 
+ 	/* Driver specific per-device data */
+-	chip = kmalloc(sizeof(*chip), GFP_KERNEL);
++	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ 	if (chip == NULL)
+ 		return -ENOMEM;
+ 
+-	memset(chip, 0, sizeof(struct tpm_chip));
+-
+ 	init_MUTEX(&chip->buffer_mutex);
+ 	init_MUTEX(&chip->tpm_mutex);
+ 	INIT_LIST_HEAD(&chip->list);
+@@ -563,8 +547,7 @@ int tpm_register_hardware(struct pci_dev
+ 
+ dev_num_search_complete:
+ 	if (chip->dev_num < 0) {
+-		dev_err(&pci_dev->dev,
+-			"No available tpm device numbers\n");
++		dev_err(dev, "No available tpm device numbers\n");
+ 		kfree(chip);
+ 		return -ENODEV;
+ 	} else if (chip->dev_num == 0)
+@@ -576,15 +559,15 @@ dev_num_search_complete:
+ 	scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
+ 	chip->vendor->miscdev.name = devname;
+ 
+-	chip->vendor->miscdev.dev = &(pci_dev->dev);
+-	chip->pci_dev = pci_dev_get(pci_dev);
++	chip->vendor->miscdev.dev = dev;
++	chip->dev = get_device(dev);
+ 
+ 	if (misc_register(&chip->vendor->miscdev)) {
+-		dev_err(&chip->pci_dev->dev,
++		dev_err(chip->dev,
+ 			"unable to misc_register %s, minor %d\n",
+ 			chip->vendor->miscdev.name,
+ 			chip->vendor->miscdev.minor);
+-		pci_dev_put(pci_dev);
++		put_device(dev);
+ 		kfree(chip);
+ 		dev_mask[i] &= !(1 << j);
+ 		return -ENODEV;
+@@ -592,17 +575,16 @@ dev_num_search_complete:
+ 
+ 	spin_lock(&driver_lock);
+ 
+-	pci_set_drvdata(pci_dev, chip);
++	dev_set_drvdata(dev, chip);
+ 
+ 	list_add(&chip->list, &tpm_chip_list);
+ 
+ 	spin_unlock(&driver_lock);
+ 
+-	sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
++	sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
+ 
+ 	return 0;
+ }
+-
+ EXPORT_SYMBOL_GPL(tpm_register_hardware);
+ 
+ MODULE_AUTHOR("Leendert van Doorn (leendert at watson.ibm.com)");
+diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
+--- a/drivers/char/tpm/tpm.h
++++ b/drivers/char/tpm/tpm.h
+@@ -24,6 +24,7 @@
+ #include <linux/delay.h>
+ #include <linux/fs.h>
+ #include <linux/miscdevice.h>
++#include <linux/platform_device.h>
+ 
+ enum tpm_timeout {
+ 	TPM_TIMEOUT = 5,	/* msecs */
+@@ -55,12 +56,13 @@ struct tpm_vendor_specific {
+ 	int (*recv) (struct tpm_chip *, u8 *, size_t);
+ 	int (*send) (struct tpm_chip *, u8 *, size_t);
+ 	void (*cancel) (struct tpm_chip *);
++	u8 (*status) (struct tpm_chip *);
+ 	struct miscdevice miscdev;
+ 	struct attribute_group *attr_group;
+ };
+ 
+ struct tpm_chip {
+-	struct pci_dev *pci_dev;	/* PCI device stuff */
++	struct device *dev;	/* Device stuff */
+ 
+ 	int dev_num;		/* /dev/tpm# */
+ 	int num_opens;		/* only one allowed */
+@@ -91,13 +93,13 @@ static inline void tpm_write_index(int b
+ 	outb(value & 0xFF, base+1);
+ }
+ 
+-extern int tpm_register_hardware(struct pci_dev *,
++extern int tpm_register_hardware(struct device *,
+ 				 struct tpm_vendor_specific *);
+ extern int tpm_open(struct inode *, struct file *);
+ extern int tpm_release(struct inode *, struct file *);
+ extern ssize_t tpm_write(struct file *, const char __user *, size_t,
+ 			 loff_t *);
+ extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
+-extern void __devexit tpm_remove(struct pci_dev *);
+-extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
+-extern int tpm_pm_resume(struct pci_dev *);
++extern void tpm_remove_hardware(struct device *);
++extern int tpm_pm_suspend(struct device *, pm_message_t);
++extern int tpm_pm_resume(struct device *);
+diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
+--- a/drivers/char/tpm/tpm_atmel.c
++++ b/drivers/char/tpm/tpm_atmel.c
+@@ -19,6 +19,7 @@
+  * 
+  */
+ 
++#include <linux/platform_device.h>
+ #include "tpm.h"
+ 
+ /* Atmel definitions */
+@@ -40,7 +41,7 @@ enum tpm_atmel_read_status {
+ 	ATML_STATUS_READY = 0x08
+ };
+ 
+-static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
++static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+ {
+ 	u8 status, *hdr = buf;
+ 	u32 size;
+@@ -54,7 +55,7 @@ static int tpm_atml_recv(struct tpm_chip
+ 	for (i = 0; i < 6; i++) {
+ 		status = inb(chip->vendor->base + 1);
+ 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+-			dev_err(&chip->pci_dev->dev,
++			dev_err(chip->dev,
+ 				"error reading header\n");
+ 			return -EIO;
+ 		}
+@@ -66,12 +67,12 @@ static int tpm_atml_recv(struct tpm_chip
+ 	size = be32_to_cpu(*native_size);
+ 
+ 	if (count < size) {
+-		dev_err(&chip->pci_dev->dev,
++		dev_err(chip->dev,
+ 			"Recv size(%d) less than available space\n", size);
+ 		for (; i < size; i++) {	/* clear the waiting data anyway */
+ 			status = inb(chip->vendor->base + 1);
+ 			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+-				dev_err(&chip->pci_dev->dev,
++				dev_err(chip->dev,
+ 					"error reading data\n");
+ 				return -EIO;
+ 			}
+@@ -83,7 +84,7 @@ static int tpm_atml_recv(struct tpm_chip
+ 	for (; i < size; i++) {
+ 		status = inb(chip->vendor->base + 1);
+ 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+-			dev_err(&chip->pci_dev->dev,
++			dev_err(chip->dev,
+ 				"error reading data\n");
+ 			return -EIO;
+ 		}
+@@ -93,20 +94,20 @@ static int tpm_atml_recv(struct tpm_chip
+ 	/* make sure data available is gone */
+ 	status = inb(chip->vendor->base + 1);
+ 	if (status & ATML_STATUS_DATA_AVAIL) {
+-		dev_err(&chip->pci_dev->dev, "data available is stuck\n");
++		dev_err(chip->dev, "data available is stuck\n");
+ 		return -EIO;
+ 	}
+ 
+ 	return size;
+ }
+ 
+-static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count)
++static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
+ {
+ 	int i;
+ 
+-	dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: ");
++	dev_dbg(chip->dev, "tpm_atml_send:\n");
+ 	for (i = 0; i < count; i++) {
+-		dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]);
++		dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
+ 		outb(buf[i], chip->vendor->base);
+ 	}
+ 
+@@ -118,6 +119,11 @@ static void tpm_atml_cancel(struct tpm_c
+ 	outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
+ }
+ 
++static u8 tpm_atml_status(struct tpm_chip *chip)
++{
++	return inb(chip->vendor->base + 1);
++}
++
+ static struct file_operations atmel_ops = {
+ 	.owner = THIS_MODULE,
+ 	.llseek = no_llseek,
+@@ -137,7 +143,7 @@ static struct attribute* atmel_attrs[] =
+ 	&dev_attr_pcrs.attr,
+ 	&dev_attr_caps.attr,
+ 	&dev_attr_cancel.attr,
+-	0,
++	NULL,
+ };
+ 
+ static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
+@@ -146,6 +152,7 @@ static struct tpm_vendor_specific tpm_at
+ 	.recv = tpm_atml_recv,
+ 	.send = tpm_atml_send,
+ 	.cancel = tpm_atml_cancel,
++	.status = tpm_atml_status,
+ 	.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
+ 	.req_complete_val = ATML_STATUS_DATA_AVAIL,
+ 	.req_canceled = ATML_STATUS_READY,
+@@ -153,86 +160,94 @@ static struct tpm_vendor_specific tpm_at
+ 	.miscdev = { .fops = &atmel_ops, },
+ };
+ 
+-static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
+-				   const struct pci_device_id *pci_id)
++static struct platform_device *pdev;
++
++static void __devexit tpm_atml_remove(struct device *dev)
++{
++	struct tpm_chip *chip = dev_get_drvdata(dev);
++	if (chip) {
++		release_region(chip->vendor->base, 2);
++		tpm_remove_hardware(chip->dev);
++	}
++}
++
++static struct device_driver atml_drv = {
++	.name = "tpm_atmel",
++	.bus = &platform_bus_type,
++	.owner = THIS_MODULE,
++	.suspend = tpm_pm_suspend,
++	.resume = tpm_pm_resume,
++};
++
++static int __init init_atmel(void)
+ {
+-	u8 version[4];
+ 	int rc = 0;
+ 	int lo, hi;
+ 
+-	if (pci_enable_device(pci_dev))
+-		return -EIO;
++	driver_register(&atml_drv);
+ 
+ 	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+ 	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
+ 
+ 	tpm_atmel.base = (hi<<8)|lo;
+-	dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
+ 
+ 	/* verify that it is an Atmel part */
+ 	if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
+ 	    || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
+-		rc = -ENODEV;
+-		goto out_err;
++		return -ENODEV;
+ 	}
+ 
+-	/* query chip for its version number */
+-	if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
+-		version[1] = tpm_read_index(TPM_ADDR, 0x01);
+-		version[2] = tpm_read_index(TPM_ADDR, 0x02);
+-		version[3] = tpm_read_index(TPM_ADDR, 0x03);
+-	} else {
+-		dev_info(&pci_dev->dev, "version query failed\n");
+-		rc = -ENODEV;
+-		goto out_err;
+-	}
+-
+-	if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0)
+-		goto out_err;
+-
+-	dev_info(&pci_dev->dev,
+-		 "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1],
+-		 version[2], version[3]);
++	/* verify chip version number is 1.1 */
++	if (	(tpm_read_index(TPM_ADDR, 0x00) != 0x01) ||
++		(tpm_read_index(TPM_ADDR, 0x01) != 0x01 ))
++		return -ENODEV;
+ 
+-	return 0;
+-out_err:
+-	pci_disable_device(pci_dev);
+-	return rc;
+-}
+-
+-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)},
+-	{0,}
+-};
++	pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
++	if ( !pdev )
++		return -ENOMEM;
+ 
+-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
++	pdev->name = "tpm_atmel0";
++	pdev->id = -1;
++	pdev->num_resources = 0;
++	pdev->dev.release = tpm_atml_remove;
++	pdev->dev.driver = &atml_drv;
+ 
+-static struct pci_driver atmel_pci_driver = {
+-	.name = "tpm_atmel",
+-	.id_table = tpm_pci_tbl,
+-	.probe = tpm_atml_init,
+-	.remove = __devexit_p(tpm_remove),
+-	.suspend = tpm_pm_suspend,
+-	.resume = tpm_pm_resume,
+-};
++	if ((rc = platform_device_register(pdev)) < 0) {
++		kfree(pdev);
++		pdev = NULL;
++		return rc;
++	}
+ 
+-static int __init init_atmel(void)
+-{
+-	return pci_register_driver(&atmel_pci_driver);
++	if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) {
++		platform_device_unregister(pdev);
++		kfree(pdev);
++		pdev = NULL;
++		return -EBUSY;
++	}
++
++	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) {
++		release_region(tpm_atmel.base, 2);
++		platform_device_unregister(pdev);
++		kfree(pdev);
++		pdev = NULL;
++		return rc;
++	}
++
++	dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n",
++			tpm_atmel.base);
++	return 0;
+ }
+ 
+ static void __exit cleanup_atmel(void)
+ {
+-	pci_unregister_driver(&atmel_pci_driver);
++	if (pdev) {
++		tpm_atml_remove(&pdev->dev);
++		platform_device_unregister(pdev);
++		kfree(pdev);
++		pdev = NULL;
++	}
++
++	driver_unregister(&atml_drv);
+ }
+ 
+ module_init(init_atmel);
+diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
+--- a/drivers/char/tpm/tpm_infineon.c
++++ b/drivers/char/tpm/tpm_infineon.c
+@@ -5,6 +5,7 @@
+  * Specifications at www.trustedcomputinggroup.org
+  *
+  * Copyright (C) 2005, Marcel Selhorst <selhorst at crypto.rub.de>
++ * Sirrix AG - security technologies, http://www.sirrix.com and
+  * Applied Data Security Group, Ruhr-University Bochum, Germany
+  * Project-Homepage: http://www.prosec.rub.de/tpm
+  *
+@@ -29,9 +30,10 @@
+ #define	TPM_INFINEON_DEV_VEN_VALUE	0x15D1
+ 
+ /* These values will be filled after PnP-call */
+-static int TPM_INF_DATA = 0;
+-static int TPM_INF_ADDR = 0;
+-static int pnp_registered = 0;
++static int TPM_INF_DATA;
++static int TPM_INF_ADDR;
++static int TPM_INF_BASE;
++static int TPM_INF_PORT_LEN;
+ 
+ /* TPM header definitions */
+ enum infineon_tpm_header {
+@@ -143,11 +145,9 @@ static int wait(struct tpm_chip *chip, i
+ 	}
+ 	if (i == TPM_MAX_TRIES) {	/* timeout occurs */
+ 		if (wait_for_bit == STAT_XFE)
+-			dev_err(&chip->pci_dev->dev,
+-				"Timeout in wait(STAT_XFE)\n");
++			dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n");
+ 		if (wait_for_bit == STAT_RDA)
+-			dev_err(&chip->pci_dev->dev,
+-				"Timeout in wait(STAT_RDA)\n");
++			dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n");
+ 		return -EIO;
+ 	}
+ 	return 0;
+@@ -170,7 +170,7 @@ static void wait_and_send(struct tpm_chi
+ static void tpm_wtx(struct tpm_chip *chip)
+ {
+ 	number_of_wtx++;
+-	dev_info(&chip->pci_dev->dev, "Granting WTX (%02d / %02d)\n",
++	dev_info(chip->dev, "Granting WTX (%02d / %02d)\n",
+ 		 number_of_wtx, TPM_MAX_WTX_PACKAGES);
+ 	wait_and_send(chip, TPM_VL_VER);
+ 	wait_and_send(chip, TPM_CTRL_WTX);
+@@ -181,7 +181,7 @@ static void tpm_wtx(struct tpm_chip *chi
+ 
+ static void tpm_wtx_abort(struct tpm_chip *chip)
+ {
+-	dev_info(&chip->pci_dev->dev, "Aborting WTX\n");
++	dev_info(chip->dev, "Aborting WTX\n");
+ 	wait_and_send(chip, TPM_VL_VER);
+ 	wait_and_send(chip, TPM_CTRL_WTX_ABORT);
+ 	wait_and_send(chip, 0x00);
+@@ -206,7 +206,7 @@ recv_begin:
+ 	}
+ 
+ 	if (buf[0] != TPM_VL_VER) {
+-		dev_err(&chip->pci_dev->dev,
++		dev_err(chip->dev,
+ 			"Wrong transport protocol implementation!\n");
+ 		return -EIO;
+ 	}
+@@ -221,8 +221,7 @@ recv_begin:
+ 		}
+ 
+ 		if ((size == 0x6D00) && (buf[1] == 0x80)) {
+-			dev_err(&chip->pci_dev->dev,
+-				"Error handling on vendor layer!\n");
++			dev_err(chip->dev, "Error handling on vendor layer!\n");
+ 			return -EIO;
+ 		}
+ 
+@@ -234,7 +233,7 @@ recv_begin:
+ 	}
+ 
+ 	if (buf[1] == TPM_CTRL_WTX) {
+-		dev_info(&chip->pci_dev->dev, "WTX-package received\n");
++		dev_info(chip->dev, "WTX-package received\n");
+ 		if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
+ 			tpm_wtx(chip);
+ 			goto recv_begin;
+@@ -245,14 +244,14 @@ recv_begin:
+ 	}
+ 
+ 	if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
+-		dev_info(&chip->pci_dev->dev, "WTX-abort acknowledged\n");
++		dev_info(chip->dev, "WTX-abort acknowledged\n");
+ 		return size;
+ 	}
+ 
+ 	if (buf[1] == TPM_CTRL_ERROR) {
+-		dev_err(&chip->pci_dev->dev, "ERROR-package received:\n");
++		dev_err(chip->dev, "ERROR-package received:\n");
+ 		if (buf[4] == TPM_INF_NAK)
+-			dev_err(&chip->pci_dev->dev,
++			dev_err(chip->dev,
+ 				"-> Negative acknowledgement"
+ 				" - retransmit command!\n");
+ 		return -EIO;
+@@ -271,7 +270,7 @@ static int tpm_inf_send(struct tpm_chip 
+ 
+ 	ret = empty_fifo(chip, 1);
+ 	if (ret) {
+-		dev_err(&chip->pci_dev->dev, "Timeout while clearing FIFO\n");
++		dev_err(chip->dev, "Timeout while clearing FIFO\n");
+ 		return -EIO;
+ 	}
+ 
+@@ -316,6 +315,11 @@ static void tpm_inf_cancel(struct tpm_ch
+ 	 */
+ }
+ 
++static u8 tpm_inf_status(struct tpm_chip *chip)
++{
++	return inb(chip->vendor->base + STAT);
++}
++
+ static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+ static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+ static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+@@ -344,6 +348,7 @@ static struct tpm_vendor_specific tpm_in
+ 	.recv = tpm_inf_recv,
+ 	.send = tpm_inf_send,
+ 	.cancel = tpm_inf_cancel,
++	.status = tpm_inf_status,
+ 	.req_complete_mask = 0,
+ 	.req_complete_val = 0,
+ 	.attr_group = &inf_attr_grp,
+@@ -356,30 +361,11 @@ static const struct pnp_device_id tpm_pn
+ 	{"IFX0102", 0},
+ 	{"", 0}
+ };
++
+ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
+ 
+ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
+-					const struct pnp_device_id *dev_id)
+-{
+-	if (pnp_port_valid(dev, 0)) {
+-		TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff);
+-		TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff);
+-		tpm_inf.base = pnp_port_start(dev, 1);
+-		dev_info(&dev->dev, "Found %s with ID %s\n",
+-		dev->name, dev_id->id);
+-		return 0;
+-	}
+-	return -ENODEV;
+-}
+-
+-static struct pnp_driver tpm_inf_pnp = {
+-	.name = "tpm_inf_pnp",
+-	.id_table = tpm_pnp_tbl,
+-	.probe = tpm_inf_pnp_probe,
+-};
+-
+-static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
+-				   const struct pci_device_id *pci_id)
++				       const struct pnp_device_id *dev_id)
+ {
+ 	int rc = 0;
+ 	u8 iol, ioh;
+@@ -388,30 +374,28 @@ static int __devinit tpm_inf_probe(struc
+ 	int productid[2];
+ 	char chipname[20];
+ 
+-	rc = pci_enable_device(pci_dev);
+-	if (rc)
+-		return rc;
+-
+-	dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device);
+-
+-	/* read IO-ports from PnP */
+-	rc = pnp_register_driver(&tpm_inf_pnp);
+-	if (rc < 0) {
+-		dev_err(&pci_dev->dev,
+-			"Error %x from pnp_register_driver!\n",rc);
+-		goto error2;
+-	}
+-	if (!rc) {
+-		dev_info(&pci_dev->dev, "No Infineon TPM found!\n");
+-		goto error;
++	/* read IO-ports through PnP */
++	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
++	    !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
++		TPM_INF_ADDR = pnp_port_start(dev, 0);
++		TPM_INF_DATA = (TPM_INF_ADDR + 1);
++		TPM_INF_BASE = pnp_port_start(dev, 1);
++		TPM_INF_PORT_LEN = pnp_port_len(dev, 1);
++		if (!TPM_INF_PORT_LEN)
++			return -EINVAL;
++		dev_info(&dev->dev, "Found %s with ID %s\n",
++			 dev->name, dev_id->id);
++		if (!((TPM_INF_BASE >> 8) & 0xff))
++			return -EINVAL;
++		/* publish my base address and request region */
++		tpm_inf.base = TPM_INF_BASE;
++		if (request_region
++		    (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
++			release_region(tpm_inf.base, TPM_INF_PORT_LEN);
++			return -EINVAL;
++		}
+ 	} else {
+-		pnp_registered = 1;
+-	}
+-
+-	/* Make sure, we have received valid config ports */
+-	if (!TPM_INF_ADDR) {
+-		dev_err(&pci_dev->dev, "No valid IO-ports received!\n");
+-		goto error;
++		return -EINVAL;
+ 	}
+ 
+ 	/* query chip for its vendor, its version number a.s.o. */
+@@ -443,10 +427,6 @@ static int __devinit tpm_inf_probe(struc
+ 
+ 	if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
+ 
+-		if (tpm_inf.base == 0) {
+-			dev_err(&pci_dev->dev, "No IO-ports found!\n");
+-			goto error;
+-		}
+ 		/* configure TPM with IO-ports */
+ 		outb(IOLIMH, TPM_INF_ADDR);
+ 		outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
+@@ -460,10 +440,11 @@ static int __devinit tpm_inf_probe(struc
+ 		iol = inb(TPM_INF_DATA);
+ 
+ 		if ((ioh << 8 | iol) != tpm_inf.base) {
+-			dev_err(&pci_dev->dev,
++			dev_err(&dev->dev,
+ 				"Could not set IO-ports to %04x\n",
+ 				tpm_inf.base);
+-			goto error;
++			release_region(tpm_inf.base, TPM_INF_PORT_LEN);
++			return -EIO;
+ 		}
+ 
+ 		/* activate register */
+@@ -475,7 +456,7 @@ static int __devinit tpm_inf_probe(struc
+ 		outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
+ 
+ 		/* Finally, we're done, print some infos */
+-		dev_info(&pci_dev->dev, "TPM found: "
++		dev_info(&dev->dev, "TPM found: "
+ 			 "config base 0x%x, "
+ 			 "io base 0x%x, "
+ 			 "chip version %02x%02x, "
+@@ -483,59 +464,53 @@ static int __devinit tpm_inf_probe(struc
+ 			 "product id %02x%02x"
+ 			 "%s\n",
+ 			 TPM_INF_ADDR,
+-			 tpm_inf.base,
++			 TPM_INF_BASE,
+ 			 version[0], version[1],
+ 			 vendorid[0], vendorid[1],
+ 			 productid[0], productid[1], chipname);
+ 
+-		rc = tpm_register_hardware(pci_dev, &tpm_inf);
+-		if (rc < 0)
+-			goto error;
++		rc = tpm_register_hardware(&dev->dev, &tpm_inf);
++		if (rc < 0) {
++			release_region(tpm_inf.base, TPM_INF_PORT_LEN);
++			return -ENODEV;
++		}
+ 		return 0;
+ 	} else {
+-		dev_info(&pci_dev->dev, "No Infineon TPM found!\n");
+-error:
+-		pnp_unregister_driver(&tpm_inf_pnp);
+-error2:
+-		pci_disable_device(pci_dev);
+-		pnp_registered = 0;
++		dev_info(&dev->dev, "No Infineon TPM found!\n");
+ 		return -ENODEV;
+ 	}
+ }
+ 
+-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2)},
+-	{0,}
+-};
+-
+-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+-
+-static struct pci_driver inf_pci_driver = {
+-	.name = "tpm_inf",
+-	.id_table = tpm_pci_tbl,
+-	.probe = tpm_inf_probe,
+-	.remove = __devexit_p(tpm_remove),
+-	.suspend = tpm_pm_suspend,
+-	.resume = tpm_pm_resume,
++static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
++{
++	struct tpm_chip *chip = pnp_get_drvdata(dev);
++
++	if (chip) {
++		release_region(chip->vendor->base, TPM_INF_PORT_LEN);
++		tpm_remove_hardware(chip->dev);
++	}
++}
++
++static struct pnp_driver tpm_inf_pnp = {
++	.name = "tpm_inf_pnp",
++	.driver = {
++		.owner = THIS_MODULE,
++		.suspend = tpm_pm_suspend,
++		.resume = tpm_pm_resume,
++	},
++	.id_table = tpm_pnp_tbl,
++	.probe = tpm_inf_pnp_probe,
++	.remove = tpm_inf_pnp_remove,
+ };
+ 
+ static int __init init_inf(void)
+ {
+-	return pci_register_driver(&inf_pci_driver);
++	return pnp_register_driver(&tpm_inf_pnp);
+ }
+ 
+ static void __exit cleanup_inf(void)
+ {
+-	if (pnp_registered)
+-		pnp_unregister_driver(&tpm_inf_pnp);
+-	pci_unregister_driver(&inf_pci_driver);
++	pnp_unregister_driver(&tpm_inf_pnp);
+ }
+ 
+ module_init(init_inf);
+@@ -543,5 +518,5 @@ module_exit(cleanup_inf);
+ 
+ MODULE_AUTHOR("Marcel Selhorst <selhorst at crypto.rub.de>");
+ MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
+-MODULE_VERSION("1.5");
++MODULE_VERSION("1.6");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
+--- a/drivers/char/tpm/tpm_nsc.c
++++ b/drivers/char/tpm/tpm_nsc.c
+@@ -19,6 +19,7 @@
+  * 
+  */
+ 
++#include <linux/platform_device.h>
+ #include "tpm.h"
+ 
+ /* National definitions */
+@@ -111,7 +112,7 @@ static int nsc_wait_for_ready(struct tpm
+ 	}
+ 	while (time_before(jiffies, stop));
+ 
+-	dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
++	dev_info(chip->dev, "wait for ready failed\n");
+ 	return -EBUSY;
+ }
+ 
+@@ -127,12 +128,12 @@ static int tpm_nsc_recv(struct tpm_chip 
+ 		return -EIO;
+ 
+ 	if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
+-		dev_err(&chip->pci_dev->dev, "F0 timeout\n");
++		dev_err(chip->dev, "F0 timeout\n");
+ 		return -EIO;
+ 	}
+ 	if ((data =
+ 	     inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
+-		dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n",
++		dev_err(chip->dev, "not in normal mode (0x%x)\n",
+ 			data);
+ 		return -EIO;
+ 	}
+@@ -141,7 +142,7 @@ static int tpm_nsc_recv(struct tpm_chip 
+ 	for (p = buffer; p < &buffer[count]; p++) {
+ 		if (wait_for_stat
+ 		    (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
+-			dev_err(&chip->pci_dev->dev,
++			dev_err(chip->dev,
+ 				"OBF timeout (while reading data)\n");
+ 			return -EIO;
+ 		}
+@@ -152,11 +153,11 @@ static int tpm_nsc_recv(struct tpm_chip 
+ 
+ 	if ((data & NSC_STATUS_F0) == 0 &&
+ 	(wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
+-		dev_err(&chip->pci_dev->dev, "F0 not set\n");
++		dev_err(chip->dev, "F0 not set\n");
+ 		return -EIO;
+ 	}
+ 	if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
+-		dev_err(&chip->pci_dev->dev,
++		dev_err(chip->dev,
+ 			"expected end of command(0x%x)\n", data);
+ 		return -EIO;
+ 	}
+@@ -187,19 +188,19 @@ static int tpm_nsc_send(struct tpm_chip 
+ 		return -EIO;
+ 
+ 	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+-		dev_err(&chip->pci_dev->dev, "IBF timeout\n");
++		dev_err(chip->dev, "IBF timeout\n");
+ 		return -EIO;
+ 	}
+ 
+ 	outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
+ 	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
+-		dev_err(&chip->pci_dev->dev, "IBR timeout\n");
++		dev_err(chip->dev, "IBR timeout\n");
+ 		return -EIO;
+ 	}
+ 
+ 	for (i = 0; i < count; i++) {
+ 		if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+-			dev_err(&chip->pci_dev->dev,
++			dev_err(chip->dev,
+ 				"IBF timeout (while writing data)\n");
+ 			return -EIO;
+ 		}
+@@ -207,7 +208,7 @@ static int tpm_nsc_send(struct tpm_chip 
+ 	}
+ 
+ 	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+-		dev_err(&chip->pci_dev->dev, "IBF timeout\n");
++		dev_err(chip->dev, "IBF timeout\n");
+ 		return -EIO;
+ 	}
+ 	outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
+@@ -220,6 +221,11 @@ static void tpm_nsc_cancel(struct tpm_ch
+ 	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
+ }
+ 
++static u8 tpm_nsc_status(struct tpm_chip *chip)
++{
++	return inb(chip->vendor->base + NSC_STATUS);
++}
++
+ static struct file_operations nsc_ops = {
+ 	.owner = THIS_MODULE,
+ 	.llseek = no_llseek,
+@@ -239,7 +245,7 @@ static struct attribute * nsc_attrs[] = 
+ 	&dev_attr_pcrs.attr,
+ 	&dev_attr_caps.attr,
+ 	&dev_attr_cancel.attr,
+-	0,
++	NULL,
+ };
+ 
+ static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
+@@ -248,6 +254,7 @@ static struct tpm_vendor_specific tpm_ns
+ 	.recv = tpm_nsc_recv,
+ 	.send = tpm_nsc_send,
+ 	.cancel = tpm_nsc_cancel,
++	.status = tpm_nsc_status,
+ 	.req_complete_mask = NSC_STATUS_OBF,
+ 	.req_complete_val = NSC_STATUS_OBF,
+ 	.req_canceled = NSC_STATUS_RDY,
+@@ -255,16 +262,32 @@ static struct tpm_vendor_specific tpm_ns
+ 	.miscdev = { .fops = &nsc_ops, },
+ };
+ 
+-static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
+-				  const struct pci_device_id *pci_id)
++static struct platform_device *pdev = NULL;
++
++static void __devexit tpm_nsc_remove(struct device *dev)
++{
++	struct tpm_chip *chip = dev_get_drvdata(dev);
++	if ( chip ) {
++		release_region(chip->vendor->base, 2);
++		tpm_remove_hardware(chip->dev);
++	}
++}
++
++static struct device_driver nsc_drv = {
++	.name = "tpm_nsc",
++	.bus = &platform_bus_type,
++	.owner = THIS_MODULE,
++	.suspend = tpm_pm_suspend,
++	.resume = tpm_pm_resume,
++};
++
++static int __init init_nsc(void)
+ {
+ 	int rc = 0;
+ 	int lo, hi;
+ 	int nscAddrBase = TPM_ADDR;
+ 
+-
+-	if (pci_enable_device(pci_dev))
+-		return -EIO;
++	driver_register(&nsc_drv);
+ 
+ 	/* select PM channel 1 */
+ 	tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
+@@ -273,37 +296,71 @@ static int __devinit tpm_nsc_init(struct
+ 	if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
+ 		nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
+ 			(tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
+-		if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
+-			rc = -ENODEV;
+-			goto out_err;
+-		}
++		if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6)
++			return -ENODEV;
+ 	}
+ 
+ 	hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
+ 	lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
+ 	tpm_nsc.base = (hi<<8) | lo;
+ 
+-	dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
+-	dev_dbg(&pci_dev->dev,
++	/* enable the DPM module */
++	tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
++
++	pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL);
++	if ( !pdev )
++		return -ENOMEM;
++
++	memset(pdev, 0, sizeof(struct platform_device));
++
++	pdev->name = "tpm_nscl0";
++	pdev->id = -1;
++	pdev->num_resources = 0;
++	pdev->dev.release = tpm_nsc_remove;
++	pdev->dev.driver = &nsc_drv;
++
++	if ((rc=platform_device_register(pdev)) < 0) {
++		kfree(pdev);
++		pdev = NULL;
++		return rc;
++	}
++
++	if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
++		platform_device_unregister(pdev);
++		kfree(pdev);
++		pdev = NULL;
++		return -EBUSY;
++	}
++
++	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) {
++		release_region(tpm_nsc.base, 2);
++		platform_device_unregister(pdev);
++		kfree(pdev);
++		pdev = NULL;
++		return rc;
++	}
++
++	dev_dbg(&pdev->dev, "NSC TPM detected\n");
++	dev_dbg(&pdev->dev,
+ 		"NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
+ 		tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
+ 		tpm_read_index(nscAddrBase,0x27));
+-	dev_dbg(&pci_dev->dev,
++	dev_dbg(&pdev->dev,
+ 		"NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
+ 		tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
+ 		tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
+-	dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
++	dev_dbg(&pdev->dev, "NSC IO Base0 0x%x\n",
+ 		(tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
+-	dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
++	dev_dbg(&pdev->dev, "NSC IO Base1 0x%x\n",
+ 		(tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
+-	dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
++	dev_dbg(&pdev->dev, "NSC Interrupt number and wakeup 0x%x\n",
+ 		tpm_read_index(nscAddrBase,0x70));
+-	dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
++	dev_dbg(&pdev->dev, "NSC IRQ type select 0x%x\n",
+ 		tpm_read_index(nscAddrBase,0x71));
+-	dev_dbg(&pci_dev->dev,
++	dev_dbg(&pdev->dev,
+ 		"NSC DMA channel select0 0x%x, select1 0x%x\n",
+ 		tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
+-	dev_dbg(&pci_dev->dev,
++	dev_dbg(&pdev->dev,
+ 		"NSC Config "
+ 		"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ 		tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
+@@ -312,55 +369,23 @@ static int __devinit tpm_nsc_init(struct
+ 		tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
+ 		tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));
+ 
+-	dev_info(&pci_dev->dev,
++	dev_info(&pdev->dev,
+ 		 "NSC TPM revision %d\n",
+ 		 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
+ 
+-	/* enable the DPM module */
+-	tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
+-
+-	if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
+-		goto out_err;
+-
+ 	return 0;
+-
+-out_err:
+-	pci_disable_device(pci_dev);
+-	return rc;
+-}
+-
+-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
+-	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
+-	{0,}
+-};
+-
+-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+-
+-static struct pci_driver nsc_pci_driver = {
+-	.name = "tpm_nsc",
+-	.id_table = tpm_pci_tbl,
+-	.probe = tpm_nsc_init,
+-	.remove = __devexit_p(tpm_remove),
+-	.suspend = tpm_pm_suspend,
+-	.resume = tpm_pm_resume,
+-};
+-
+-static int __init init_nsc(void)
+-{
+-	return pci_register_driver(&nsc_pci_driver);
+ }
+ 
+ static void __exit cleanup_nsc(void)
+ {
+-	pci_unregister_driver(&nsc_pci_driver);
++	if (pdev) {
++		tpm_nsc_remove(&pdev->dev);
++		platform_device_unregister(pdev);
++		kfree(pdev);
++		pdev = NULL;
++	}
++
++	driver_unregister(&nsc_drv);
+ }
+ 
+ module_init(init_nsc);
+diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -809,7 +809,7 @@ static void do_tty_hangup(void *data)
+ 	check_tty_count(tty, "do_tty_hangup");
+ 	file_list_lock();
+ 	/* This breaks for file handles being sent over AF_UNIX sockets ? */
+-	list_for_each_entry(filp, &tty->tty_files, f_list) {
++	list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
+ 		if (filp->f_op->write == redirected_tty_write)
+ 			cons_filp = filp;
+ 		if (filp->f_op->write != tty_write)
+@@ -2728,7 +2728,7 @@ void tty_register_device(struct tty_driv
+ 		pty_line_name(driver, index, name);
+ 	else
+ 		tty_line_name(driver, index, name);
+-	class_device_create(tty_class, dev, device, name);
++	class_device_create(tty_class, NULL, dev, device, "%s", name);
+ }
+ 
+ /**
+@@ -2983,14 +2983,14 @@ static int __init tty_init(void)
+ 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
+ 		panic("Couldn't register /dev/tty driver\n");
+ 	devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
+-	class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
++	class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
+ 
+ 	cdev_init(&console_cdev, &console_fops);
+ 	if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
+ 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
+ 		panic("Couldn't register /dev/console driver\n");
+ 	devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
+-	class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
++	class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
+ 
+ #ifdef CONFIG_UNIX98_PTYS
+ 	cdev_init(&ptmx_cdev, &ptmx_fops);
+@@ -2998,7 +2998,7 @@ static int __init tty_init(void)
+ 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
+ 		panic("Couldn't register /dev/ptmx driver\n");
+ 	devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
+-	class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
++	class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
+ #endif
+ 
+ #ifdef CONFIG_VT
+@@ -3007,7 +3007,7 @@ static int __init tty_init(void)
+ 	    register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
+ 		panic("Couldn't register /dev/tty0 driver\n");
+ 	devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
+-	class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
++	class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
+ 
+ 	vty_init();
+ #endif
+diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
+--- a/drivers/char/vc_screen.c
++++ b/drivers/char/vc_screen.c
+@@ -484,8 +484,10 @@ void vcs_make_devfs(struct tty_struct *t
+ 	devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129),
+ 			S_IFCHR|S_IRUSR|S_IWUSR,
+ 			"vcc/a%u", tty->index + 1);
+-	class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1);
+-	class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1);
++	class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
++			NULL, "vcs%u", tty->index + 1);
++	class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
++			NULL, "vcsa%u", tty->index + 1);
+ }
+ void vcs_remove_devfs(struct tty_struct *tty)
+ {
+@@ -503,7 +505,7 @@ int __init vcs_init(void)
+ 
+ 	devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0");
+ 	devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0");
+-	class_device_create(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+-	class_device_create(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
++	class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
++	class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+ 	return 0;
+ }
+diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
+--- a/drivers/char/viotape.c
++++ b/drivers/char/viotape.c
+@@ -956,9 +956,9 @@ static int viotape_probe(struct vio_dev 
+ 	state[i].cur_part = 0;
+ 	for (j = 0; j < MAX_PARTITIONS; ++j)
+ 		state[i].part_stat_rwi[j] = VIOT_IDLE;
+-	class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL,
++	class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL,
+ 			"iseries!vt%d", i);
+-	class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80),
++	class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
+ 			NULL, "iseries!nvt%d", i);
+ 	devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR,
+ 			"iseries/vt%d", i);
+@@ -993,13 +993,16 @@ static struct vio_device_id viotape_devi
+ 	{ "viotape", "" },
+ 	{ "", "" }
+ };
+-
+ MODULE_DEVICE_TABLE(vio, viotape_device_table);
++
+ static struct vio_driver viotape_driver = {
+-	.name = "viotape",
+ 	.id_table = viotape_device_table,
+ 	.probe = viotape_probe,
+-	.remove = viotape_remove
++	.remove = viotape_remove,
++	.driver = {
++		.name = "viotape",
++		.owner = THIS_MODULE,
++	}
+ };
+ 
+ 
+diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
+--- a/drivers/char/vr41xx_giu.c
++++ b/drivers/char/vr41xx_giu.c
+@@ -19,7 +19,7 @@
+  *  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/platform_device.h>
+ #include <linux/errno.h>
+ #include <linux/fs.h>
+ #include <linux/init.h>
+diff --git a/drivers/char/vr41xx_rtc.c b/drivers/char/vr41xx_rtc.c
+--- a/drivers/char/vr41xx_rtc.c
++++ b/drivers/char/vr41xx_rtc.c
+@@ -17,7 +17,7 @@
+  *  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/platform_device.h>
+ #include <linux/fs.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
+--- a/drivers/char/vt_ioctl.c
++++ b/drivers/char/vt_ioctl.c
+@@ -192,6 +192,9 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
+ 	int i, j, k;
+ 	int ret;
+ 
++	if (!capable(CAP_SYS_TTY_CONFIG))
++		return -EPERM;
++
+ 	kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
+ 	if (!kbs) {
+ 		ret = -ENOMEM;
+diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
+--- a/drivers/char/watchdog/cpu5wdt.c
++++ b/drivers/char/watchdog/cpu5wdt.c
+@@ -28,6 +28,7 @@
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+ #include <linux/timer.h>
++#include <linux/jiffies.h>
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+ 
+diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
+--- a/drivers/char/watchdog/mixcomwd.c
++++ b/drivers/char/watchdog/mixcomwd.c
+@@ -45,6 +45,8 @@
+ #include <linux/fs.h>
+ #include <linux/reboot.h>
+ #include <linux/init.h>
++#include <linux/jiffies.h>
++#include <linux/timer.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+ 
+diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
+--- a/drivers/char/watchdog/mpcore_wdt.c
++++ b/drivers/char/watchdog/mpcore_wdt.c
+@@ -29,7 +29,7 @@
+ #include <linux/reboot.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/hardware/arm_twd.h>
+ #include <asm/uaccess.h>
+@@ -396,6 +396,7 @@ static int __devexit mpcore_wdt_remove(s
+ }
+ 
+ static struct device_driver mpcore_wdt_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "mpcore_wdt",
+ 	.bus		= &platform_bus_type,
+ 	.probe		= mpcore_wdt_probe,
+diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
+--- a/drivers/char/watchdog/mv64x60_wdt.c
++++ b/drivers/char/watchdog/mv64x60_wdt.c
+@@ -22,6 +22,8 @@
+ #include <linux/miscdevice.h>
+ #include <linux/module.h>
+ #include <linux/watchdog.h>
++#include <linux/platform_device.h>
++
+ #include <asm/mv64x60.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -211,6 +213,7 @@ static int __devexit mv64x60_wdt_remove(
+ }
+ 
+ static struct device_driver mv64x60_wdt_driver = {
++	.owner = THIS_MODULE,
+ 	.name = MV64x60_WDT_NAME,
+ 	.bus = &platform_bus_type,
+ 	.probe = mv64x60_wdt_probe,
+diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
+--- a/drivers/char/watchdog/pcwd.c
++++ b/drivers/char/watchdog/pcwd.c
+@@ -66,7 +66,7 @@
+ #include <linux/init.h>
+ #include <linux/spinlock.h>
+ #include <linux/reboot.h>
+-
++#include <linux/sched.h>	/* TASK_INTERRUPTIBLE, set_current_state() and friends */
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+ 
+diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
+--- a/drivers/char/watchdog/pcwd_pci.c
++++ b/drivers/char/watchdog/pcwd_pci.c
+@@ -1,7 +1,7 @@
+ /*
+  *	Berkshire PCI-PC Watchdog Card Driver
+  *
+- *	(c) Copyright 2003 Wim Van Sebroeck <wim at iguana.be>.
++ *	(c) Copyright 2003-2005 Wim Van Sebroeck <wim at iguana.be>.
+  *
+  *	Based on source code of the following authors:
+  *	  Ken Hollis <kenji at bitgate.com>,
+@@ -21,7 +21,9 @@
+  */
+ 
+ /*
+- *	A bells and whistles driver is available from http://www.pcwd.de/
++ *	A bells and whistles driver is available from: 
++ *	http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/
++ *
+  *	More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/
+  */
+ 
+@@ -753,6 +755,7 @@ static struct pci_device_id pcipcwd_pci_
+ MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl);
+ 
+ static struct pci_driver pcipcwd_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= WATCHDOG_NAME,
+ 	.id_table	= pcipcwd_pci_tbl,
+ 	.probe		= pcipcwd_card_init,
+diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
+--- a/drivers/char/watchdog/s3c2410_wdt.c
++++ b/drivers/char/watchdog/s3c2410_wdt.c
+@@ -44,7 +44,7 @@
+ #include <linux/watchdog.h>
+ #include <linux/fs.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ 
+ #include <asm/uaccess.h>
+@@ -464,32 +464,28 @@ static void s3c2410wdt_shutdown(struct d
+ static unsigned long wtcon_save;
+ static unsigned long wtdat_save;
+ 
+-static int s3c2410wdt_suspend(struct device *dev, pm_message_t state, u32 level)
++static int s3c2410wdt_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_POWER_DOWN) {
+-		/* Save watchdog state, and turn it off. */
+-		wtcon_save = readl(wdt_base + S3C2410_WTCON);
+-		wtdat_save = readl(wdt_base + S3C2410_WTDAT);
++	/* Save watchdog state, and turn it off. */
++	wtcon_save = readl(wdt_base + S3C2410_WTCON);
++	wtdat_save = readl(wdt_base + S3C2410_WTDAT);
+ 
+-		/* Note that WTCNT doesn't need to be saved. */
+-		s3c2410wdt_stop();
+-	}
++	/* Note that WTCNT doesn't need to be saved. */
++	s3c2410wdt_stop();
+ 
+ 	return 0;
+ }
+ 
+-static int s3c2410wdt_resume(struct device *dev, u32 level)
++static int s3c2410wdt_resume(struct device *dev)
+ {
+-	if (level == RESUME_POWER_ON) {
+-		/* Restore watchdog state. */
++	/* Restore watchdog state. */
+ 
+-		writel(wtdat_save, wdt_base + S3C2410_WTDAT);
+-		writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
+-		writel(wtcon_save, wdt_base + S3C2410_WTCON);
++	writel(wtdat_save, wdt_base + S3C2410_WTDAT);
++	writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
++	writel(wtcon_save, wdt_base + S3C2410_WTCON);
+ 
+-		printk(KERN_INFO PFX "watchdog %sabled\n",
+-		       (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
+-	}
++	printk(KERN_INFO PFX "watchdog %sabled\n",
++	       (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
+ 
+ 	return 0;
+ }
+@@ -501,6 +497,7 @@ static int s3c2410wdt_resume(struct devi
+ 
+ 
+ static struct device_driver s3c2410wdt_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "s3c2410-wdt",
+ 	.bus		= &platform_bus_type,
+ 	.probe		= s3c2410wdt_probe,
+diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
+--- a/drivers/char/watchdog/sc520_wdt.c
++++ b/drivers/char/watchdog/sc520_wdt.c
+@@ -63,6 +63,7 @@
+ #include <linux/notifier.h>
+ #include <linux/reboot.h>
+ #include <linux/init.h>
++#include <linux/jiffies.h>
+ 
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
+--- a/drivers/char/watchdog/softdog.c
++++ b/drivers/char/watchdog/softdog.c
+@@ -47,6 +47,8 @@
+ #include <linux/notifier.h>
+ #include <linux/reboot.h>
+ #include <linux/init.h>
++#include <linux/jiffies.h>
++
+ #include <asm/uaccess.h>
+ 
+ #define PFX "SoftDog: "
+diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
+--- a/drivers/char/watchdog/w83627hf_wdt.c
++++ b/drivers/char/watchdog/w83627hf_wdt.c
+@@ -359,5 +359,5 @@ module_exit(wdt_exit);
+ 
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Pádraig Brady <P at draigBrady.com>");
+-MODULE_DESCRIPTION("w38627hf WDT driver");
++MODULE_DESCRIPTION("w83627hf WDT driver");
+ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
+--- a/drivers/char/watchdog/wdt_pci.c
++++ b/drivers/char/watchdog/wdt_pci.c
+@@ -711,6 +711,7 @@ MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl)
+ 
+ 
+ static struct pci_driver wdtpci_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "wdt_pci",
+ 	.id_table	= wdtpci_pci_tbl,
+ 	.probe		= wdtpci_init_one,
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -4,6 +4,9 @@
+  *  Copyright (C) 2001 Russell King
+  *            (C) 2002 - 2003 Dominik Brodowski <linux at brodo.de>
+  *
++ *  Oct 2005 - Ashok Raj <ashok.raj at intel.com>
++ *         		Added handling for CPU hotplug
++ *
+  * 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.
+@@ -36,13 +39,6 @@ static struct cpufreq_policy	*cpufreq_cp
+ static DEFINE_SPINLOCK(cpufreq_driver_lock);
+ 
+ 
+-/* we keep a copy of all ->add'ed CPU's struct sys_device here;
+- * as it is only accessed in ->add and ->remove, no lock or reference
+- * count is necessary.
+- */
+-static struct sys_device	*cpu_sys_devices[NR_CPUS];
+-
+-
+ /* internal prototypes */
+ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
+ static void handle_update(void *data);
+@@ -574,6 +570,9 @@ static int cpufreq_add_dev (struct sys_d
+ 	unsigned long flags;
+ 	unsigned int j;
+ 
++	if (cpu_is_offline(cpu))
++		return 0;
++
+ 	cpufreq_debug_disable_ratelimit();
+ 	dprintk("adding CPU %u\n", cpu);
+ 
+@@ -582,7 +581,6 @@ static int cpufreq_add_dev (struct sys_d
+ 	 * CPU because it is in the same boat. */
+ 	policy = cpufreq_cpu_get(cpu);
+ 	if (unlikely(policy)) {
+-		cpu_sys_devices[cpu] = sys_dev;
+ 		dprintk("CPU already managed, adding link\n");
+ 		sysfs_create_link(&sys_dev->kobj, &policy->kobj, "cpufreq");
+ 		cpufreq_debug_enable_ratelimit();
+@@ -657,7 +655,6 @@ static int cpufreq_add_dev (struct sys_d
+ 	}
+ 
+ 	module_put(cpufreq_driver->owner);
+-	cpu_sys_devices[cpu] = sys_dev;
+ 	dprintk("initialization complete\n");
+ 	cpufreq_debug_enable_ratelimit();
+ 	
+@@ -682,7 +679,7 @@ err_out:
+ 
+ nomem_out:
+ 	module_put(cpufreq_driver->owner);
+- module_out:
++module_out:
+ 	cpufreq_debug_enable_ratelimit();
+ 	return ret;
+ }
+@@ -698,6 +695,7 @@ static int cpufreq_remove_dev (struct sy
+ 	unsigned int cpu = sys_dev->id;
+ 	unsigned long flags;
+ 	struct cpufreq_policy *data;
++	struct sys_device *cpu_sys_dev;
+ #ifdef CONFIG_SMP
+ 	unsigned int j;
+ #endif
+@@ -710,7 +708,6 @@ static int cpufreq_remove_dev (struct sy
+ 
+ 	if (!data) {
+ 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+-		cpu_sys_devices[cpu] = NULL;
+ 		cpufreq_debug_enable_ratelimit();
+ 		return -EINVAL;
+ 	}
+@@ -725,14 +722,12 @@ static int cpufreq_remove_dev (struct sy
+ 		dprintk("removing link\n");
+ 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+ 		sysfs_remove_link(&sys_dev->kobj, "cpufreq");
+-		cpu_sys_devices[cpu] = NULL;
+ 		cpufreq_cpu_put(data);
+ 		cpufreq_debug_enable_ratelimit();
+ 		return 0;
+ 	}
+ #endif
+ 
+-	cpu_sys_devices[cpu] = NULL;
+ 
+ 	if (!kobject_get(&data->kobj)) {
+ 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+@@ -761,7 +756,8 @@ static int cpufreq_remove_dev (struct sy
+ 			if (j == cpu)
+ 				continue;
+ 			dprintk("removing link for cpu %u\n", j);
+-			sysfs_remove_link(&cpu_sys_devices[j]->kobj, "cpufreq");
++			cpu_sys_dev = get_cpu_sysdev(j);
++			sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
+ 			cpufreq_cpu_put(data);
+ 		}
+ 	}
+@@ -772,7 +768,6 @@ static int cpufreq_remove_dev (struct sy
+ 	down(&data->lock);
+ 	if (cpufreq_driver->target)
+ 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
+-	cpufreq_driver->target = NULL;
+ 	up(&data->lock);
+ 
+ 	kobject_unregister(&data->kobj);
+@@ -1119,17 +1114,30 @@ int __cpufreq_driver_target(struct cpufr
+ 			    unsigned int relation)
+ {
+ 	int retval = -EINVAL;
+-	lock_cpu_hotplug();
++
++	/*
++	 * Converted the lock_cpu_hotplug to preempt_disable()
++	 * and preempt_enable(). This is a bit kludgy and relies on how cpu
++	 * hotplug works. All we need is a guarantee that cpu hotplug won't make
++	 * progress on any cpu. Once we do preempt_disable(), this would ensure
++	 * that hotplug threads don't get onto this cpu, thereby delaying
++	 * the cpu remove process.
++	 *
++	 * We removed the lock_cpu_hotplug since we need to call this function
++	 * via cpu hotplug callbacks, which result in locking the cpu hotplug
++	 * thread itself. Agree this is not very clean, cpufreq community
++	 * could improve this if required. - Ashok Raj <ashok.raj at intel.com>
++	 */
++	preempt_disable();
+ 	dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
+ 		target_freq, relation);
+ 	if (cpu_online(policy->cpu) && cpufreq_driver->target)
+ 		retval = cpufreq_driver->target(policy, target_freq, relation);
+-	unlock_cpu_hotplug();
++	preempt_enable();
+ 	return retval;
+ }
+ EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
+ 
+-
+ int cpufreq_driver_target(struct cpufreq_policy *policy,
+ 			  unsigned int target_freq,
+ 			  unsigned int relation)
+@@ -1416,6 +1424,45 @@ int cpufreq_update_policy(unsigned int c
+ }
+ EXPORT_SYMBOL(cpufreq_update_policy);
+ 
++static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
++					unsigned long action, void *hcpu)
++{
++	unsigned int cpu = (unsigned long)hcpu;
++	struct cpufreq_policy *policy;
++	struct sys_device *sys_dev;
++
++	sys_dev = get_cpu_sysdev(cpu);
++
++	if (sys_dev) {
++		switch (action) {
++		case CPU_ONLINE:
++			cpufreq_add_dev(sys_dev);
++			break;
++		case CPU_DOWN_PREPARE:
++			/*
++			 * We attempt to put this cpu in lowest frequency
++			 * possible before going down. This will permit
++			 * hardware-managed P-State to switch other related
++			 * threads to min or higher speeds if possible.
++			 */
++			policy = cpufreq_cpu_data[cpu];
++			if (policy) {
++				cpufreq_driver_target(policy, policy->min,
++						CPUFREQ_RELATION_H);
++			}
++			break;
++		case CPU_DEAD:
++			cpufreq_remove_dev(sys_dev);
++			break;
++		}
++	}
++	return NOTIFY_OK;
++}
++
++static struct notifier_block cpufreq_cpu_notifier =
++{
++    .notifier_call = cpufreq_cpu_callback,
++};
+ 
+ /*********************************************************************
+  *               REGISTER / UNREGISTER CPUFREQ DRIVER                *
+@@ -1476,6 +1523,7 @@ int cpufreq_register_driver(struct cpufr
+ 	}
+ 
+ 	if (!ret) {
++		register_cpu_notifier(&cpufreq_cpu_notifier);
+ 		dprintk("driver %s up and running\n", driver_data->name);
+ 		cpufreq_debug_enable_ratelimit();
+ 	}
+@@ -1507,6 +1555,7 @@ int cpufreq_unregister_driver(struct cpu
+ 	dprintk("unregistering driver %s\n", driver->name);
+ 
+ 	sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
++	unregister_cpu_notifier(&cpufreq_cpu_notifier);
+ 
+ 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
+ 	cpufreq_driver = NULL;
+diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
+--- a/drivers/cpufreq/cpufreq_stats.c
++++ b/drivers/cpufreq/cpufreq_stats.c
+@@ -19,6 +19,7 @@
+ #include <linux/percpu.h>
+ #include <linux/kobject.h>
+ #include <linux/spinlock.h>
++#include <linux/notifier.h>
+ #include <asm/cputime.h>
+ 
+ static spinlock_t cpufreq_stats_lock;
+@@ -298,6 +299,27 @@ cpufreq_stat_notifier_trans (struct noti
+ 	return 0;
+ }
+ 
++static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb,
++					unsigned long action, void *hcpu)
++{
++	unsigned int cpu = (unsigned long)hcpu;
++
++	switch (action) {
++	case CPU_ONLINE:
++		cpufreq_update_policy(cpu);
++		break;
++	case CPU_DEAD:
++		cpufreq_stats_free_table(cpu);
++		break;
++	}
++	return NOTIFY_OK;
++}
++
++static struct notifier_block cpufreq_stat_cpu_notifier =
++{
++	.notifier_call = cpufreq_stat_cpu_callback,
++};
++
+ static struct notifier_block notifier_policy_block = {
+ 	.notifier_call = cpufreq_stat_notifier_policy
+ };
+@@ -311,6 +333,7 @@ __init cpufreq_stats_init(void)
+ {
+ 	int ret;
+ 	unsigned int cpu;
++
+ 	spin_lock_init(&cpufreq_stats_lock);
+ 	if ((ret = cpufreq_register_notifier(&notifier_policy_block,
+ 				CPUFREQ_POLICY_NOTIFIER)))
+@@ -323,20 +346,31 @@ __init cpufreq_stats_init(void)
+ 		return ret;
+ 	}
+ 
+-	for_each_cpu(cpu)
+-		cpufreq_update_policy(cpu);
++	register_cpu_notifier(&cpufreq_stat_cpu_notifier);
++	lock_cpu_hotplug();
++	for_each_online_cpu(cpu) {
++		cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE,
++			(void *)(long)cpu);
++	}
++	unlock_cpu_hotplug();
+ 	return 0;
+ }
+ static void
+ __exit cpufreq_stats_exit(void)
+ {
+ 	unsigned int cpu;
++
+ 	cpufreq_unregister_notifier(&notifier_policy_block,
+ 			CPUFREQ_POLICY_NOTIFIER);
+ 	cpufreq_unregister_notifier(&notifier_trans_block,
+ 			CPUFREQ_TRANSITION_NOTIFIER);
+-	for_each_cpu(cpu)
+-		cpufreq_stats_free_table(cpu);
++	unregister_cpu_notifier(&cpufreq_stat_cpu_notifier);
++	lock_cpu_hotplug();
++	for_each_online_cpu(cpu) {
++		cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD,
++			(void *)(long)cpu);
++	}
++	unlock_cpu_hotplug();
+ }
+ 
+ MODULE_AUTHOR ("Zou Nan hai <nanhai.zou at intel.com>");
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -2,7 +2,7 @@ menu "Hardware crypto devices"
+ 
+ config CRYPTO_DEV_PADLOCK
+ 	tristate "Support for VIA PadLock ACE"
+-	depends on CRYPTO && X86 && !X86_64
++	depends on CRYPTO && X86_32
+ 	help
+ 	  Some VIA processors come with an integrated crypto engine
+ 	  (so called VIA PadLock ACE, Advanced Cryptography Engine)
+diff --git a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c
+--- a/drivers/eisa/virtual_root.c
++++ b/drivers/eisa/virtual_root.c
+@@ -9,7 +9,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/eisa.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
+--- a/drivers/firmware/Kconfig
++++ b/drivers/firmware/Kconfig
+@@ -70,8 +70,7 @@ config DELL_RBU
+ 
+ config DCDBAS
+ 	tristate "Dell Systems Management Base Driver"
+-	depends on X86 || X86_64
+-	default m
++	depends on X86
+ 	help
+ 	  The Dell Systems Management Base Driver provides a sysfs interface
+ 	  for systems management software to perform System Management
+diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
+--- a/drivers/firmware/dcdbas.c
++++ b/drivers/firmware/dcdbas.c
+@@ -20,7 +20,7 @@
+  *  GNU General Public License for more details.
+  */
+ 
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
+--- a/drivers/firmware/dell_rbu.c
++++ b/drivers/firmware/dell_rbu.c
+@@ -41,7 +41,7 @@
+ #include <linux/string.h>
+ #include <linux/errno.h>
+ #include <linux/blkdev.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/spinlock.h>
+ #include <linux/moduleparam.h>
+ #include <linux/firmware.h>
+diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
+--- a/drivers/hwmon/adm1021.c
++++ b/drivers/hwmon/adm1021.c
+@@ -121,7 +121,7 @@ static int adm1021_write_value(struct i2
+ static struct adm1021_data *adm1021_update_device(struct device *dev);
+ 
+ /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
+-static int read_only = 0;
++static int read_only;
+ 
+ 
+ /* This is the driver that will be inserted */
+@@ -204,11 +204,10 @@ static int adm1021_detect(struct i2c_ada
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access adm1021_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto error0;
+ 	}
+-	memset(data, 0, sizeof(struct adm1021_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c
+--- a/drivers/hwmon/adm1025.c
++++ b/drivers/hwmon/adm1025.c
+@@ -331,11 +331,10 @@ static int adm1025_detect(struct i2c_ada
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct adm1025_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct adm1025_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct adm1025_data));
+ 
+ 	/* The common I2C client data is placed right before the
+ 	   ADM1025-specific data. */
+diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
+--- a/drivers/hwmon/adm1026.c
++++ b/drivers/hwmon/adm1026.c
+@@ -315,7 +315,7 @@ static struct i2c_driver adm1026_driver 
+ 	.detach_client  = adm1026_detach_client,
+ };
+ 
+-int adm1026_attach_adapter(struct i2c_adapter *adapter)
++static int adm1026_attach_adapter(struct i2c_adapter *adapter)
+ {
+ 	if (!(adapter->class & I2C_CLASS_HWMON)) {
+ 		return 0;
+@@ -323,7 +323,7 @@ int adm1026_attach_adapter(struct i2c_ad
+ 	return i2c_probe(adapter, &addr_data, adm1026_detect);
+ }
+ 
+-int adm1026_detach_client(struct i2c_client *client)
++static int adm1026_detach_client(struct i2c_client *client)
+ {
+ 	struct adm1026_data *data = i2c_get_clientdata(client);
+ 	hwmon_device_unregister(data->class_dev);
+@@ -332,7 +332,7 @@ int adm1026_detach_client(struct i2c_cli
+ 	return 0;
+ }
+ 
+-int adm1026_read_value(struct i2c_client *client, u8 reg)
++static int adm1026_read_value(struct i2c_client *client, u8 reg)
+ {
+ 	int res;
+ 
+@@ -346,7 +346,7 @@ int adm1026_read_value(struct i2c_client
+ 	return res;
+ }
+ 
+-int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
++static int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
+ {
+ 	int res;
+ 
+@@ -360,7 +360,7 @@ int adm1026_write_value(struct i2c_clien
+ 	return res;
+ }
+ 
+-void adm1026_init_client(struct i2c_client *client)
++static void adm1026_init_client(struct i2c_client *client)
+ {
+ 	int value, i;
+ 	struct adm1026_data *data = i2c_get_clientdata(client);
+@@ -460,7 +460,7 @@ void adm1026_init_client(struct i2c_clie
+ 	}
+ }
+ 
+-void adm1026_print_gpio(struct i2c_client *client)
++static void adm1026_print_gpio(struct i2c_client *client)
+ {
+ 	struct adm1026_data *data = i2c_get_clientdata(client);
+ 	int  i;
+@@ -492,7 +492,7 @@ void adm1026_print_gpio(struct i2c_clien
+ 	}
+ }
+ 
+-void adm1026_fixup_gpio(struct i2c_client *client)
++static void adm1026_fixup_gpio(struct i2c_client *client)
+ {
+ 	struct adm1026_data *data = i2c_get_clientdata(client);
+ 	int  i;
+@@ -1452,8 +1452,8 @@ static DEVICE_ATTR(temp1_auto_point2_pwm
+ static DEVICE_ATTR(temp2_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
+ static DEVICE_ATTR(temp3_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
+ 
+-int adm1026_detect(struct i2c_adapter *adapter, int address,
+-		int kind)
++static int adm1026_detect(struct i2c_adapter *adapter, int address,
++			  int kind)
+ {
+ 	int company, verstep;
+ 	struct i2c_client *new_client;
+@@ -1470,13 +1470,11 @@ int adm1026_detect(struct i2c_adapter *a
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access adm1026_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct adm1026_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+ 
+-	memset(data, 0, sizeof(struct adm1026_data));
+-
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+ 	new_client->addr = address;
+diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
+--- a/drivers/hwmon/adm1031.c
++++ b/drivers/hwmon/adm1031.c
+@@ -740,11 +740,10 @@ static int adm1031_detect(struct i2c_ada
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct adm1031_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct adm1031_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
+--- a/drivers/hwmon/adm9240.c
++++ b/drivers/hwmon/adm9240.c
+@@ -45,6 +45,7 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/i2c.h>
++#include <linux/hwmon-sysfs.h>
+ #include <linux/hwmon.h>
+ #include <linux/hwmon-vid.h>
+ #include <linux/err.h>
+@@ -69,8 +70,7 @@ I2C_CLIENT_INSMOD_3(adm9240, ds1780, lm8
+ #define ADM9240_REG_INT(nr)		(0x41 + (nr))
+ #define ADM9240_REG_INT_MASK(nr)	(0x43 + (nr))
+ #define ADM9240_REG_TEMP		0x27
+-#define ADM9240_REG_TEMP_HIGH		0x39
+-#define ADM9240_REG_TEMP_HYST		0x3a
++#define ADM9240_REG_TEMP_MAX(nr)	(0x39 + (nr)) /* 0, 1 = high, hyst */
+ #define ADM9240_REG_ANALOG_OUT		0x19
+ #define ADM9240_REG_CHASSIS_CLEAR	0x46
+ #define ADM9240_REG_VID_FAN_DIV		0x47
+@@ -162,177 +162,155 @@ struct adm9240_data {
+ 	u8 fan_min[2];		/* rw	fan1_min */
+ 	u8 fan_div[2];		/* rw	fan1_div, read-only accessor */
+ 	s16 temp;		/* ro	temp1_input, 9-bit sign-extended */
+-	s8 temp_high;		/* rw	temp1_max */
+-	s8 temp_hyst;		/* rw	temp1_max_hyst */
++	s8 temp_max[2];		/* rw	0 -> temp_max, 1 -> temp_max_hyst */
+ 	u16 alarms;		/* ro	alarms */
+ 	u8 aout;		/* rw	aout_output */
+ 	u8 vid;			/* ro	vid */
+ 	u8 vrm;			/* --	vrm set on startup, no accessor */
+ };
+ 
+-/* i2c byte read/write interface */
+-static int adm9240_read_value(struct i2c_client *client, u8 reg)
++/*** sysfs accessors ***/
++
++/* temperature */
++static ssize_t show_temp(struct device *dev, struct device_attribute *dummy,
++		char *buf)
+ {
+-	return i2c_smbus_read_byte_data(client, reg);
++	struct adm9240_data *data = adm9240_update_device(dev);
++	return sprintf(buf, "%d\n", data->temp * 500); /* 9-bit value */
+ }
+ 
+-static int adm9240_write_value(struct i2c_client *client, u8 reg, u8 value)
++static ssize_t show_max(struct device *dev, struct device_attribute *devattr,
++		char *buf)
+ {
+-	return i2c_smbus_write_byte_data(client, reg, value);
++	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
++	struct adm9240_data *data = adm9240_update_device(dev);
++	return sprintf(buf, "%d\n", data->temp_max[attr->index] * 1000);
+ }
+ 
+-/*** sysfs accessors ***/
++static ssize_t set_max(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 adm9240_data *data = i2c_get_clientdata(client);
++	long val = simple_strtol(buf, NULL, 10);
++
++	down(&data->update_lock);
++	data->temp_max[attr->index] = TEMP_TO_REG(val);
++	i2c_smbus_write_byte_data(client, ADM9240_REG_TEMP_MAX(attr->index),
++			data->temp_max[attr->index]);
++	up(&data->update_lock);
++	return count;
++}
+ 
+-/* temperature */
+-#define show_temp(value, scale)					\
+-static ssize_t show_##value(struct device *dev,			\
+-			    struct device_attribute *attr,	\
+-			    char *buf)				\
+-{								\
+-	struct adm9240_data *data = adm9240_update_device(dev);	\
+-	return sprintf(buf, "%d\n", data->value * scale);	\
+-}
+-show_temp(temp_high, 1000);
+-show_temp(temp_hyst, 1000);
+-show_temp(temp, 500); /* 0.5'C per bit */
+-
+-#define set_temp(value, reg)					\
+-static ssize_t set_##value(struct device *dev, 			\
+-			   struct device_attribute *attr,	\
+-			   const char *buf, size_t count)	\
+-{								\
+-	struct i2c_client *client = to_i2c_client(dev);		\
+-	struct adm9240_data *data = adm9240_update_device(dev);	\
+-	long temp = simple_strtoul(buf, NULL, 10);		\
+-								\
+-	down(&data->update_lock);				\
+-	data->value = TEMP_TO_REG(temp);			\
+-	adm9240_write_value(client, reg, data->value);		\
+-	up(&data->update_lock);					\
+-	return count;						\
+-}
+-
+-set_temp(temp_high, ADM9240_REG_TEMP_HIGH);
+-set_temp(temp_hyst, ADM9240_REG_TEMP_HYST);
+-
+-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+-		show_temp_high, set_temp_high);
+-static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
+-		show_temp_hyst, set_temp_hyst);
+ static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
++static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
++		show_max, set_max, 0);
++static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
++		show_max, set_max, 1);
+ 
+ /* voltage */
+-static ssize_t show_in(struct device *dev, char *buf, int nr)
++static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
++		char *buf)
+ {
++	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ 	struct adm9240_data *data = adm9240_update_device(dev);
+-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr));
++	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index],
++				attr->index));
+ }
+ 
+-static ssize_t show_in_min(struct device *dev, char *buf, int nr)
++static ssize_t show_in_min(struct device *dev,
++		struct device_attribute *devattr, char *buf)
+ {
++	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ 	struct adm9240_data *data = adm9240_update_device(dev);
+-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr));
++	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index],
++				attr->index));
+ }
+ 
+-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
++static ssize_t show_in_max(struct device *dev,
++		struct device_attribute *devattr, char *buf)
+ {
++	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ 	struct adm9240_data *data = adm9240_update_device(dev);
+-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr));
++	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index],
++				attr->index));
+ }
+ 
+-static ssize_t set_in_min(struct device *dev, const char *buf,
+-		size_t count, int nr)
++static ssize_t set_in_min(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 adm9240_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);
+-	adm9240_write_value(client, ADM9240_REG_IN_MIN(nr), data->in_min[nr]);
++	data->in_min[attr->index] = IN_TO_REG(val, attr->index);
++	i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(attr->index),
++			data->in_min[attr->index]);
+ 	up(&data->update_lock);
+ 	return count;
+ }
+ 
+-static ssize_t set_in_max(struct device *dev, const char *buf,
+-		size_t count, int nr)
++static ssize_t set_in_max(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 adm9240_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);
+-	adm9240_write_value(client, ADM9240_REG_IN_MAX(nr), data->in_max[nr]);
++	data->in_max[attr->index] = IN_TO_REG(val, attr->index);
++	i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(attr->index),
++			data->in_max[attr->index]);
+ 	up(&data->update_lock);
+ 	return count;
+ }
+ 
+-#define show_in_offset(offset)						\
+-static ssize_t show_in##offset(struct device *dev,			\
+-			       struct device_attribute *attr,		\
+-			       char *buf)				\
+-{									\
+-	return show_in(dev, buf, offset);				\
+-}									\
+-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);	\
+-static ssize_t show_in##offset##_min(struct device *dev,		\
+-				     struct device_attribute *attr,	\
+-				     char *buf)				\
+-{									\
+-	return show_in_min(dev, buf, offset);				\
+-}									\
+-static ssize_t show_in##offset##_max(struct device *dev,		\
+-				     struct device_attribute *attr,	\
+-				     char *buf)				\
+-{									\
+-	return show_in_max(dev, buf, offset);				\
+-}									\
+-static ssize_t								\
+-set_in##offset##_min(struct device *dev,				\
+-		     struct device_attribute *attr, const char *buf,	\
+-		     size_t count)					\
+-{									\
+-	return set_in_min(dev, buf, count, offset);			\
+-}									\
+-static ssize_t								\
+-set_in##offset##_max(struct device *dev,				\
+-		     struct device_attribute *attr, const char *buf,	\
+-		     size_t count)					\
+-{									\
+-	return set_in_max(dev, buf, count, offset);			\
+-}									\
+-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,			\
+-		show_in##offset##_min, set_in##offset##_min);		\
+-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,			\
+-		show_in##offset##_max, set_in##offset##_max);
+-
+-show_in_offset(0);
+-show_in_offset(1);
+-show_in_offset(2);
+-show_in_offset(3);
+-show_in_offset(4);
+-show_in_offset(5);
++#define vin(nr)							\
++static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO, 		\
++		show_in, NULL, nr);				\
++static SENSOR_DEVICE_ATTR(in##nr##_min, S_IRUGO | S_IWUSR,	\
++		show_in_min, set_in_min, nr);			\
++static SENSOR_DEVICE_ATTR(in##nr##_max, S_IRUGO | S_IWUSR,	\
++		show_in_max, set_in_max, nr);
++
++vin(0);
++vin(1);
++vin(2);
++vin(3);
++vin(4);
++vin(5);
+ 
+ /* fans */
+-static ssize_t show_fan(struct device *dev, char *buf, int nr)
++static ssize_t show_fan(struct device *dev,
++		struct device_attribute *devattr, char *buf)
+ {
++	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ 	struct adm9240_data *data = adm9240_update_device(dev);
+-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+-				1 << data->fan_div[nr]));
++	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index],
++				1 << data->fan_div[attr->index]));
+ }
+ 
+-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
++static ssize_t show_fan_min(struct device *dev,
++		struct device_attribute *devattr, char *buf)
+ {
++	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ 	struct adm9240_data *data = adm9240_update_device(dev);
+-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+-				1 << data->fan_div[nr]));
++	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[attr->index],
++				1 << data->fan_div[attr->index]));
+ }
+ 
+-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
++static ssize_t show_fan_div(struct device *dev,
++		struct device_attribute *devattr, char *buf)
+ {
++	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ 	struct adm9240_data *data = adm9240_update_device(dev);
+-	return sprintf(buf, "%d\n", 1 << data->fan_div[nr]);
++	return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
+ }
+ 
+ /* write new fan div, callers must hold data->update_lock */
+@@ -341,16 +319,16 @@ static void adm9240_write_fan_div(struct
+ {
+ 	u8 reg, old, shift = (nr + 2) * 2;
+ 
+-	reg = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV);
++	reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
+ 	old = (reg >> shift) & 3;
+ 	reg &= ~(3 << shift);
+ 	reg |= (fan_div << shift);
+-	adm9240_write_value(client, ADM9240_REG_VID_FAN_DIV, reg);
++	i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
+ 	dev_dbg(&client->dev, "fan%d clock divider changed from %u "
+ 			"to %u\n", nr + 1, 1 << old, 1 << fan_div);
+ }
+ 
+-/* 
++/*
+  * set fan speed low limit:
+  *
+  * - value is zero: disable fan speed low limit alarm
+@@ -361,12 +339,15 @@ static void adm9240_write_fan_div(struct
+  * - otherwise: select fan clock divider to suit fan speed low limit,
+  *   measurement code may adjust registers to ensure fan speed reading
+  */
+-static ssize_t set_fan_min(struct device *dev, const char *buf,
+-		size_t count, int nr)
++static ssize_t set_fan_min(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 adm9240_data *data = i2c_get_clientdata(client);
+ 	unsigned long val = simple_strtoul(buf, NULL, 10);
++	int nr = attr->index;
+ 	u8 new_div;
+ 
+ 	down(&data->update_lock);
+@@ -406,50 +387,27 @@ static ssize_t set_fan_min(struct device
+ 		data->fan_div[nr] = new_div;
+ 		adm9240_write_fan_div(client, nr, new_div);
+ 	}
+-	adm9240_write_value(client, ADM9240_REG_FAN_MIN(nr),
++	i2c_smbus_write_byte_data(client, ADM9240_REG_FAN_MIN(nr),
+ 			data->fan_min[nr]);
+ 
+ 	up(&data->update_lock);
+ 	return count;
+ }
+ 
+-#define show_fan_offset(offset)						\
+-static ssize_t show_fan_##offset (struct device *dev,			\
+-				  struct device_attribute *attr,	\
+-				  char *buf)				\
+-{									\
+-return show_fan(dev, buf, offset - 1);					\
+-}									\
+-static ssize_t show_fan_##offset##_div (struct device *dev,		\
+-					struct device_attribute *attr,	\
+-					char *buf)			\
+-{									\
+-return show_fan_div(dev, buf, offset - 1);				\
+-}									\
+-static ssize_t show_fan_##offset##_min (struct device *dev,		\
+-					struct device_attribute *attr,	\
+-					char *buf)			\
+-{									\
+-return show_fan_min(dev, buf, offset - 1);				\
+-}									\
+-static ssize_t set_fan_##offset##_min (struct device *dev, 		\
+-				       struct device_attribute *attr,	\
+-				       const char *buf, size_t count)	\
+-{									\
+-return set_fan_min(dev, buf, count, offset - 1);			\
+-}									\
+-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, 			\
+-		show_fan_##offset, NULL);				\
+-static DEVICE_ATTR(fan##offset##_div, S_IRUGO, 				\
+-		show_fan_##offset##_div, NULL);				\
+-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, 		\
+-		show_fan_##offset##_min, set_fan_##offset##_min);
++#define fan(nr)							\
++static SENSOR_DEVICE_ATTR(fan##nr##_input, S_IRUGO,		\
++		show_fan, NULL, nr - 1);			\
++static SENSOR_DEVICE_ATTR(fan##nr##_div, S_IRUGO,		\
++		show_fan_div, NULL, nr - 1);			\
++static SENSOR_DEVICE_ATTR(fan##nr##_min, S_IRUGO | S_IWUSR,	\
++		show_fan_min, set_fan_min, nr - 1);
+ 
+-show_fan_offset(1);
+-show_fan_offset(2);
++fan(1);
++fan(2);
+ 
+ /* alarms */
+-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
++static ssize_t show_alarms(struct device *dev,
++		struct device_attribute *attr, char *buf)
+ {
+ 	struct adm9240_data *data = adm9240_update_device(dev);
+ 	return sprintf(buf, "%u\n", data->alarms);
+@@ -457,7 +415,8 @@ static ssize_t show_alarms(struct device
+ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+ 
+ /* vid */
+-static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
++static ssize_t show_vid(struct device *dev,
++		struct device_attribute *attr, char *buf)
+ {
+ 	struct adm9240_data *data = adm9240_update_device(dev);
+ 	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+@@ -465,13 +424,16 @@ static ssize_t show_vid(struct device *d
+ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+ 
+ /* analog output */
+-static ssize_t show_aout(struct device *dev, struct device_attribute *attr, char *buf)
++static ssize_t show_aout(struct device *dev,
++		struct device_attribute *attr, char *buf)
+ {
+ 	struct adm9240_data *data = adm9240_update_device(dev);
+ 	return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout));
+ }
+ 
+-static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++static ssize_t set_aout(struct device *dev,
++		struct device_attribute *attr,
++		const char *buf, size_t count)
+ {
+ 	struct i2c_client *client = to_i2c_client(dev);
+ 	struct adm9240_data *data = i2c_get_clientdata(client);
+@@ -479,20 +441,23 @@ static ssize_t set_aout(struct device *d
+ 
+ 	down(&data->update_lock);
+ 	data->aout = AOUT_TO_REG(val);
+-	adm9240_write_value(client, ADM9240_REG_ANALOG_OUT, data->aout);
++	i2c_smbus_write_byte_data(client, ADM9240_REG_ANALOG_OUT, data->aout);
+ 	up(&data->update_lock);
+ 	return count;
+ }
+ static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
+ 
+ /* chassis_clear */
+-static ssize_t chassis_clear(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++static ssize_t chassis_clear(struct device *dev,
++		struct device_attribute *attr,
++		const char *buf, size_t count)
+ {
+ 	struct i2c_client *client = to_i2c_client(dev);
+ 	unsigned long val = simple_strtol(buf, NULL, 10);
+ 
+ 	if (val == 1) {
+-		adm9240_write_value(client, ADM9240_REG_CHASSIS_CLEAR, 0x80);
++		i2c_smbus_write_byte_data(client,
++				ADM9240_REG_CHASSIS_CLEAR, 0x80);
+ 		dev_dbg(&client->dev, "chassis intrusion latch cleared\n");
+ 	}
+ 	return count;
+@@ -513,11 +478,10 @@ static int adm9240_detect(struct i2c_ada
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct adm9240_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct adm9240_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+@@ -533,7 +497,7 @@ static int adm9240_detect(struct i2c_ada
+ 	if (kind < 0) {
+ 
+ 		/* verify chip: reg address should match i2c address */
+-		if (adm9240_read_value(new_client, ADM9240_REG_I2C_ADDR)
++		if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR)
+ 				!= address) {
+ 			dev_err(&adapter->dev, "detect fail: address match, "
+ 					"0x%02x\n", address);
+@@ -541,8 +505,8 @@ static int adm9240_detect(struct i2c_ada
+ 		}
+ 
+ 		/* check known chip manufacturer */
+-		man_id = adm9240_read_value(new_client, ADM9240_REG_MAN_ID);
+-
++		man_id = i2c_smbus_read_byte_data(new_client,
++				ADM9240_REG_MAN_ID);
+ 		if (man_id == 0x23) {
+ 			kind = adm9240;
+ 		} else if (man_id == 0xda) {
+@@ -556,7 +520,8 @@ static int adm9240_detect(struct i2c_ada
+ 		}
+ 
+ 		/* successful detect, print chip info */
+-		die_rev = adm9240_read_value(new_client, ADM9240_REG_DIE_REV);
++		die_rev = i2c_smbus_read_byte_data(new_client,
++				ADM9240_REG_DIE_REV);
+ 		dev_info(&adapter->dev, "found %s revision %u\n",
+ 				man_id == 0x23 ? "ADM9240" :
+ 				man_id == 0xda ? "DS1780" : "LM81", die_rev);
+@@ -588,33 +553,59 @@ static int adm9240_detect(struct i2c_ada
+ 		goto exit_detach;
+ 	}
+ 
+-	device_create_file(&new_client->dev, &dev_attr_in0_input);
+-	device_create_file(&new_client->dev, &dev_attr_in0_min);
+-	device_create_file(&new_client->dev, &dev_attr_in0_max);
+-	device_create_file(&new_client->dev, &dev_attr_in1_input);
+-	device_create_file(&new_client->dev, &dev_attr_in1_min);
+-	device_create_file(&new_client->dev, &dev_attr_in1_max);
+-	device_create_file(&new_client->dev, &dev_attr_in2_input);
+-	device_create_file(&new_client->dev, &dev_attr_in2_min);
+-	device_create_file(&new_client->dev, &dev_attr_in2_max);
+-	device_create_file(&new_client->dev, &dev_attr_in3_input);
+-	device_create_file(&new_client->dev, &dev_attr_in3_min);
+-	device_create_file(&new_client->dev, &dev_attr_in3_max);
+-	device_create_file(&new_client->dev, &dev_attr_in4_input);
+-	device_create_file(&new_client->dev, &dev_attr_in4_min);
+-	device_create_file(&new_client->dev, &dev_attr_in4_max);
+-	device_create_file(&new_client->dev, &dev_attr_in5_input);
+-	device_create_file(&new_client->dev, &dev_attr_in5_min);
+-	device_create_file(&new_client->dev, &dev_attr_in5_max);
+-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+-	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in0_input.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in0_min.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in0_max.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in1_input.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in1_min.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in1_max.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in2_input.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in2_min.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in2_max.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in3_input.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in3_min.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in3_max.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in4_input.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in4_min.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in4_max.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in5_input.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in5_min.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_in5_max.dev_attr);
+ 	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+-	device_create_file(&new_client->dev, &dev_attr_fan1_div);
+-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
+-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
+-	device_create_file(&new_client->dev, &dev_attr_fan2_div);
+-	device_create_file(&new_client->dev, &dev_attr_fan2_min);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_temp1_max.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_temp1_max_hyst.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_fan1_input.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_fan1_div.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_fan1_min.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_fan2_input.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_fan2_div.dev_attr);
++	device_create_file(&new_client->dev,
++			&sensor_dev_attr_fan2_min.dev_attr);
+ 	device_create_file(&new_client->dev, &dev_attr_alarms);
+ 	device_create_file(&new_client->dev, &dev_attr_aout_output);
+ 	device_create_file(&new_client->dev, &dev_attr_chassis_clear);
+@@ -654,8 +645,8 @@ static int adm9240_detach_client(struct 
+ static void adm9240_init_client(struct i2c_client *client)
+ {
+ 	struct adm9240_data *data = i2c_get_clientdata(client);
+-	u8 conf = adm9240_read_value(client, ADM9240_REG_CONFIG);
+-	u8 mode = adm9240_read_value(client, ADM9240_REG_TEMP_CONF) & 3;
++	u8 conf = i2c_smbus_read_byte_data(client, ADM9240_REG_CONFIG);
++	u8 mode = i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP_CONF) & 3;
+ 
+ 	data->vrm = vid_which_vrm(); /* need this to report vid as mV */
+ 
+@@ -672,18 +663,22 @@ static void adm9240_init_client(struct i
+ 
+ 		for (i = 0; i < 6; i++)
+ 		{
+-			adm9240_write_value(client,
++			i2c_smbus_write_byte_data(client,
+ 					ADM9240_REG_IN_MIN(i), 0);
+-			adm9240_write_value(client,
++			i2c_smbus_write_byte_data(client,
+ 					ADM9240_REG_IN_MAX(i), 255);
+ 		}
+-		adm9240_write_value(client, ADM9240_REG_FAN_MIN(0), 255);
+-		adm9240_write_value(client, ADM9240_REG_FAN_MIN(1), 255);
+-		adm9240_write_value(client, ADM9240_REG_TEMP_HIGH, 127);
+-		adm9240_write_value(client, ADM9240_REG_TEMP_HYST, 127);
++		i2c_smbus_write_byte_data(client,
++				ADM9240_REG_FAN_MIN(0), 255);
++		i2c_smbus_write_byte_data(client,
++				ADM9240_REG_FAN_MIN(1), 255);
++		i2c_smbus_write_byte_data(client,
++				ADM9240_REG_TEMP_MAX(0), 127);
++		i2c_smbus_write_byte_data(client,
++				ADM9240_REG_TEMP_MAX(1), 127);
+ 
+ 		/* start measurement cycle */
+-		adm9240_write_value(client, ADM9240_REG_CONFIG, 1);
++		i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1);
+ 
+ 		dev_info(&client->dev, "cold start: config was 0x%02x "
+ 				"mode %u\n", conf, mode);
+@@ -704,25 +699,25 @@ static struct adm9240_data *adm9240_upda
+ 
+ 		for (i = 0; i < 6; i++) /* read voltages */
+ 		{
+-			data->in[i] = adm9240_read_value(client,
++			data->in[i] = i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_IN(i));
+ 		}
+-		data->alarms = adm9240_read_value(client,
++		data->alarms = i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_INT(0)) |
+-					adm9240_read_value(client,
++					i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_INT(1)) << 8;
+ 
+ 		/* read temperature: assume temperature changes less than
+ 		 * 0.5'C per two measurement cycles thus ignore possible
+ 		 * but unlikely aliasing error on lsb reading. --Grant */
+-		data->temp = ((adm9240_read_value(client,
++		data->temp = ((i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_TEMP) << 8) |
+-					adm9240_read_value(client,
++					i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_TEMP_CONF)) / 128;
+ 
+ 		for (i = 0; i < 2; i++) /* read fans */
+ 		{
+-			data->fan[i] = adm9240_read_value(client,
++			data->fan[i] = i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_FAN(i));
+ 
+ 			/* adjust fan clock divider on overflow */
+@@ -747,30 +742,30 @@ static struct adm9240_data *adm9240_upda
+ 
+ 		for (i = 0; i < 6; i++)
+ 		{
+-			data->in_min[i] = adm9240_read_value(client,
++			data->in_min[i] = i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_IN_MIN(i));
+-			data->in_max[i] = adm9240_read_value(client,
++			data->in_max[i] = i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_IN_MAX(i));
+ 		}
+ 		for (i = 0; i < 2; i++)
+ 		{
+-			data->fan_min[i] = adm9240_read_value(client,
++			data->fan_min[i] = i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_FAN_MIN(i));
+ 		}
+-		data->temp_high = adm9240_read_value(client,
+-				ADM9240_REG_TEMP_HIGH);
+-		data->temp_hyst = adm9240_read_value(client,
+-				ADM9240_REG_TEMP_HYST);
++		data->temp_max[0] = i2c_smbus_read_byte_data(client,
++				ADM9240_REG_TEMP_MAX(0));
++		data->temp_max[1] = i2c_smbus_read_byte_data(client,
++				ADM9240_REG_TEMP_MAX(1));
+ 
+ 		/* read fan divs and 5-bit VID */
+-		i = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV);
++		i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
+ 		data->fan_div[0] = (i >> 4) & 3;
+ 		data->fan_div[1] = (i >> 6) & 3;
+ 		data->vid = i & 0x0f;
+-		data->vid |= (adm9240_read_value(client,
++		data->vid |= (i2c_smbus_read_byte_data(client,
+ 					ADM9240_REG_VID4) & 1) << 4;
+ 		/* read analog out */
+-		data->aout = adm9240_read_value(client,
++		data->aout = i2c_smbus_read_byte_data(client,
+ 				ADM9240_REG_ANALOG_OUT);
+ 
+ 		data->last_updated_config = jiffies;
+diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
+--- a/drivers/hwmon/asb100.c
++++ b/drivers/hwmon/asb100.c
+@@ -629,19 +629,17 @@ static int asb100_detect_subclients(stru
+ 	int i, id, err;
+ 	struct asb100_data *data = i2c_get_clientdata(new_client);
+ 
+-	data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ 	if (!(data->lm75[0])) {
+ 		err = -ENOMEM;
+ 		goto ERROR_SC_0;
+ 	}
+-	memset(data->lm75[0], 0x00, sizeof(struct i2c_client));
+ 
+-	data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ 	if (!(data->lm75[1])) {
+ 		err = -ENOMEM;
+ 		goto ERROR_SC_1;
+ 	}
+-	memset(data->lm75[1], 0x00, sizeof(struct i2c_client));
+ 
+ 	id = i2c_adapter_id(adapter);
+ 
+@@ -724,12 +722,11 @@ static int asb100_detect(struct i2c_adap
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access asb100_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
+-		pr_debug("asb100.o: detect failed, kmalloc failed!\n");
++	if (!(data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
++		pr_debug("asb100.o: detect failed, kzalloc failed!\n");
+ 		err = -ENOMEM;
+ 		goto ERROR0;
+ 	}
+-	memset(data, 0, sizeof(struct asb100_data));
+ 
+ 	new_client = &data->client;
+ 	init_MUTEX(&data->lock);
+diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c
+--- a/drivers/hwmon/atxp1.c
++++ b/drivers/hwmon/atxp1.c
+@@ -253,6 +253,8 @@ static DEVICE_ATTR(gpio2, S_IRUGO | S_IW
+ 
+ static int atxp1_attach_adapter(struct i2c_adapter *adapter)
+ {
++	if (!(adapter->class & I2C_CLASS_HWMON))
++		return 0;
+ 	return i2c_probe(adapter, &addr_data, &atxp1_detect);
+ };
+ 
+@@ -266,12 +268,11 @@ static int atxp1_detect(struct i2c_adapt
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct atxp1_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+ 
+-	memset(data, 0, sizeof(struct atxp1_data));
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+ 
+diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
+--- a/drivers/hwmon/ds1621.c
++++ b/drivers/hwmon/ds1621.c
+@@ -180,12 +180,14 @@ static DEVICE_ATTR(temp1_max, S_IWUSR | 
+ 
+ static int ds1621_attach_adapter(struct i2c_adapter *adapter)
+ {
++	if (!(adapter->class & I2C_CLASS_HWMON))
++		return 0;
+ 	return i2c_probe(adapter, &addr_data, ds1621_detect);
+ }
+ 
+ /* This function is called by i2c_probe */
+-int ds1621_detect(struct i2c_adapter *adapter, int address,
+-                  int kind)
++static int ds1621_detect(struct i2c_adapter *adapter, int address,
++			 int kind)
+ {
+ 	int conf, temp;
+ 	struct i2c_client *new_client;
+@@ -200,11 +202,10 @@ int ds1621_detect(struct i2c_adapter *ad
+ 	/* 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 ds1621_{read,write}_value. */
+-	if (!(data = kmalloc(sizeof(struct ds1621_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct ds1621_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct ds1621_data));
+ 	
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c
+--- a/drivers/hwmon/fscher.c
++++ b/drivers/hwmon/fscher.c
+@@ -303,11 +303,10 @@ static int fscher_detect(struct i2c_adap
+ 	/* 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 i2c_smbus_read_byte_data. */
+-	if (!(data = kmalloc(sizeof(struct fscher_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+   	}
+-	memset(data, 0, sizeof(struct fscher_data));
+ 
+ 	/* The common I2C client data is placed right before the
+ 	 * Hermes-specific data. */
+diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c
+--- a/drivers/hwmon/fscpos.c
++++ b/drivers/hwmon/fscpos.c
+@@ -438,7 +438,7 @@ static int fscpos_attach_adapter(struct 
+ 	return i2c_probe(adapter, &addr_data, fscpos_detect);
+ }
+ 
+-int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
++static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
+ {
+ 	struct i2c_client *new_client;
+ 	struct fscpos_data *data;
+@@ -453,11 +453,10 @@ int fscpos_detect(struct i2c_adapter *ad
+ 	 * But it allows us to access fscpos_{read,write}_value.
+ 	 */
+ 
+-	if (!(data = kmalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct fscpos_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
+--- a/drivers/hwmon/gl518sm.c
++++ b/drivers/hwmon/gl518sm.c
+@@ -365,11 +365,10 @@ static int gl518_detect(struct i2c_adapt
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access gl518_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct gl518_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct gl518_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct gl518_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
+--- a/drivers/hwmon/gl520sm.c
++++ b/drivers/hwmon/gl520sm.c
+@@ -536,11 +536,10 @@ static int gl520_detect(struct i2c_adapt
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access gl520_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct gl520_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct gl520_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
+--- a/drivers/hwmon/hdaps.c
++++ b/drivers/hwmon/hdaps.c
+@@ -27,7 +27,7 @@
+  */
+ 
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/input.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+@@ -296,11 +296,9 @@ static int hdaps_probe(struct device *de
+ 	return 0;
+ }
+ 
+-static int hdaps_resume(struct device *dev, u32 level)
++static int hdaps_resume(struct device *dev)
+ {
+-	if (level == RESUME_ENABLE)
+-		return hdaps_device_init();
+-	return 0;
++	return hdaps_device_init();
+ }
+ 
+ static struct device_driver hdaps_driver = {
+diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
+--- a/drivers/hwmon/hwmon.c
++++ b/drivers/hwmon/hwmon.c
+@@ -45,7 +45,7 @@ struct class_device *hwmon_device_regist
+ 		return ERR_PTR(-ENOMEM);
+ 
+ 	id = id & MAX_ID_MASK;
+-	cdev = class_device_create(hwmon_class, MKDEV(0,0), dev,
++	cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev,
+ 					HWMON_ID_FORMAT, id);
+ 
+ 	if (IS_ERR(cdev))
+diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
+--- a/drivers/hwmon/it87.c
++++ b/drivers/hwmon/it87.c
+@@ -2,7 +2,7 @@
+     it87.c - Part of lm_sensors, Linux kernel modules for hardware
+              monitoring.
+ 
+-    Supports: IT8705F  Super I/O chip w/LPC interface & SMBus
++    Supports: IT8705F  Super I/O chip w/LPC interface
+               IT8712F  Super I/O chip w/LPC interface & SMBus
+               Sis950   A clone of the IT8705F
+ 
+@@ -47,7 +47,7 @@
+ /* Addresses to scan */
+ static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
+ 					0x2e, 0x2f, I2C_CLIENT_END };
+-static unsigned short isa_address = 0x290;
++static unsigned short isa_address;
+ 
+ /* Insmod parameters */
+ I2C_CLIENT_INSMOD_2(it87, it8712);
+@@ -706,7 +706,7 @@ static int it87_isa_attach_adapter(struc
+ }
+ 
+ /* SuperIO detection - will change isa_address if a chip is found */
+-static int __init it87_find(int *address)
++static int __init it87_find(unsigned short *address)
+ {
+ 	int err = -ENODEV;
+ 
+@@ -738,7 +738,7 @@ exit:
+ }
+ 
+ /* This function is called by i2c_probe */
+-int it87_detect(struct i2c_adapter *adapter, int address, int kind)
++static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
+ {
+ 	int i;
+ 	struct i2c_client *new_client;
+@@ -757,42 +757,14 @@ int it87_detect(struct i2c_adapter *adap
+ 		if (!request_region(address, IT87_EXTENT, it87_isa_driver.name))
+ 			goto ERROR0;
+ 
+-	/* Probe whether there is anything available on this address. Already
+-	   done for SMBus and Super-I/O clients */
+-	if (kind < 0) {
+-		if (is_isa && !chip_type) {
+-#define REALLY_SLOW_IO
+-			/* We need the timeouts for at least some IT87-like chips. But only
+-			   if we read 'undefined' registers. */
+-			i = inb_p(address + 1);
+-			if (inb_p(address + 2) != i
+-			 || inb_p(address + 3) != i
+-			 || inb_p(address + 7) != i) {
+-		 		err = -ENODEV;
+-				goto ERROR1;
+-			}
+-#undef REALLY_SLOW_IO
+-
+-			/* Let's just hope nothing breaks here */
+-			i = inb_p(address + 5) & 0x7f;
+-			outb_p(~i & 0x7f, address + 5);
+-			if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
+-				outb_p(i, address + 5);
+-				err = -ENODEV;
+-				goto ERROR1;
+-			}
+-		}
+-	}
+-
+-	/* OK. For now, we presume we have a valid client. We now create the
++	/* For now, we presume we have a valid client. We create the
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access it87_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct it87_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto ERROR1;
+ 	}
+-	memset(data, 0, sizeof(struct it87_data));
+ 
+ 	new_client = &data->client;
+ 	if (is_isa)
+@@ -1182,20 +1154,18 @@ static struct it87_data *it87_update_dev
+ 
+ static int __init sm_it87_init(void)
+ {
+-	int addr, res;
+-
+-	if (!it87_find(&addr)) {
+-		isa_address = addr;
+-	}
++	int res;
+ 
+ 	res = i2c_add_driver(&it87_driver);
+ 	if (res)
+ 		return res;
+ 
+-	res = i2c_isa_add_driver(&it87_isa_driver);
+-	if (res) {
+-		i2c_del_driver(&it87_driver);
+-		return res;
++	if (!it87_find(&isa_address)) {
++		res = i2c_isa_add_driver(&it87_isa_driver);
++		if (res) {
++			i2c_del_driver(&it87_driver);
++			return res;
++		}
+ 	}
+ 
+ 	return 0;
+diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
+--- a/drivers/hwmon/lm63.c
++++ b/drivers/hwmon/lm63.c
+@@ -375,11 +375,10 @@ static int lm63_detect(struct i2c_adapte
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct lm63_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct lm63_data));
+ 
+ 	/* The common I2C client data is placed right before the
+ 	   LM63-specific data. */
+diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
+--- a/drivers/hwmon/lm75.c
++++ b/drivers/hwmon/lm75.c
+@@ -127,11 +127,10 @@ static int lm75_detect(struct i2c_adapte
+ 	/* 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 lm75_{read,write}_value. */
+-	if (!(data = kmalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct lm75_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
+--- a/drivers/hwmon/lm77.c
++++ b/drivers/hwmon/lm77.c
+@@ -226,11 +226,10 @@ static int lm77_detect(struct i2c_adapte
+ 	/* 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 lm77_{read,write}_value. */
+-	if (!(data = kmalloc(sizeof(struct lm77_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct lm77_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
+--- a/drivers/hwmon/lm78.c
++++ b/drivers/hwmon/lm78.c
+@@ -480,7 +480,7 @@ static int lm78_isa_attach_adapter(struc
+ }
+ 
+ /* This function is called by i2c_probe */
+-int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
++static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
+ {
+ 	int i, err;
+ 	struct i2c_client *new_client;
+@@ -540,11 +540,10 @@ int lm78_detect(struct i2c_adapter *adap
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access lm78_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto ERROR1;
+ 	}
+-	memset(data, 0, sizeof(struct lm78_data));
+ 
+ 	new_client = &data->client;
+ 	if (is_isa)
+@@ -726,7 +725,6 @@ static int lm78_write_value(struct i2c_c
+ 		return i2c_smbus_write_byte_data(client, reg, value);
+ }
+ 
+-/* Called when we have found a new LM78. It should set limits, etc. */
+ static void lm78_init_client(struct i2c_client *client)
+ {
+ 	u8 config = lm78_read_value(client, LM78_REG_CONFIG);
+diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
+--- a/drivers/hwmon/lm80.c
++++ b/drivers/hwmon/lm80.c
+@@ -393,7 +393,7 @@ static int lm80_attach_adapter(struct i2
+ 	return i2c_probe(adapter, &addr_data, lm80_detect);
+ }
+ 
+-int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
++static int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
+ {
+ 	int i, cur;
+ 	struct i2c_client *new_client;
+@@ -407,11 +407,10 @@ int lm80_detect(struct i2c_adapter *adap
+ 	/* 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 lm80_{read,write}_value. */
+-	if (!(data = kmalloc(sizeof(struct lm80_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm80_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct lm80_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c
+--- a/drivers/hwmon/lm83.c
++++ b/drivers/hwmon/lm83.c
+@@ -230,11 +230,10 @@ static int lm83_detect(struct i2c_adapte
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct lm83_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct lm83_data));
+ 
+ 	/* The common I2C client data is placed right after the
+ 	 * LM83-specific data. */
+diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
+--- a/drivers/hwmon/lm85.c
++++ b/drivers/hwmon/lm85.c
+@@ -1007,14 +1007,14 @@ temp_auto(1);
+ temp_auto(2);
+ temp_auto(3);
+ 
+-int lm85_attach_adapter(struct i2c_adapter *adapter)
++static int lm85_attach_adapter(struct i2c_adapter *adapter)
+ {
+ 	if (!(adapter->class & I2C_CLASS_HWMON))
+ 		return 0;
+ 	return i2c_probe(adapter, &addr_data, lm85_detect);
+ }
+ 
+-int lm85_detect(struct i2c_adapter *adapter, int address,
++static int lm85_detect(struct i2c_adapter *adapter, int address,
+ 		int kind)
+ {
+ 	int company, verstep ;
+@@ -1033,11 +1033,10 @@ int lm85_detect(struct i2c_adapter *adap
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access lm85_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct lm85_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm85_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto ERROR0;
+ 	}
+-	memset(data, 0, sizeof(struct lm85_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+@@ -1236,7 +1235,7 @@ int lm85_detect(struct i2c_adapter *adap
+ 	return err;
+ }
+ 
+-int lm85_detach_client(struct i2c_client *client)
++static int lm85_detach_client(struct i2c_client *client)
+ {
+ 	struct lm85_data *data = i2c_get_clientdata(client);
+ 	hwmon_device_unregister(data->class_dev);
+@@ -1246,7 +1245,7 @@ int lm85_detach_client(struct i2c_client
+ }
+ 
+ 
+-int lm85_read_value(struct i2c_client *client, u8 reg)
++static int lm85_read_value(struct i2c_client *client, u8 reg)
+ {
+ 	int res;
+ 
+@@ -1276,7 +1275,7 @@ int lm85_read_value(struct i2c_client *c
+ 	return res ;
+ }
+ 
+-int lm85_write_value(struct i2c_client *client, u8 reg, int value)
++static int lm85_write_value(struct i2c_client *client, u8 reg, int value)
+ {
+ 	int res ;
+ 
+@@ -1305,7 +1304,7 @@ int lm85_write_value(struct i2c_client *
+ 	return res ;
+ }
+ 
+-void lm85_init_client(struct i2c_client *client)
++static void lm85_init_client(struct i2c_client *client)
+ {
+ 	int value;
+ 	struct lm85_data *data = i2c_get_clientdata(client);
+diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
+--- a/drivers/hwmon/lm87.c
++++ b/drivers/hwmon/lm87.c
+@@ -554,11 +554,10 @@ static int lm87_detect(struct i2c_adapte
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct lm87_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct lm87_data));
+ 
+ 	/* The common I2C client data is placed right before the
+ 	   LM87-specific data. */
+diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
+--- a/drivers/hwmon/lm90.c
++++ b/drivers/hwmon/lm90.c
+@@ -31,7 +31,7 @@
+  * Devices. That chip is similar to the LM90, with a few differences
+  * that are not handled by this driver. Complete datasheet can be
+  * obtained from Analog's website at:
+- *   http://products.analog.com/products/info.asp?product=ADM1032
++ *   http://www.analog.com/en/prod/0,2877,ADM1032,00.html
+  * Among others, it has a higher accuracy than the LM90, much like the
+  * LM86 does.
+  *
+@@ -49,7 +49,7 @@
+  * register values are decoded differently) it is ignored by this
+  * driver. Complete datasheet can be obtained from Analog's website
+  * at:
+- *   http://products.analog.com/products/info.asp?product=ADT7461
++ *   http://www.analog.com/en/prod/0,2877,ADT7461,00.html
+  *
+  * Since the LM90 was the first chipset supported by this driver, most
+  * comments will refer to this chipset, but are actually general and
+@@ -83,10 +83,10 @@
+  * Addresses to scan
+  * Address is fully defined internally and cannot be changed except for
+  * MAX6659.
+- * LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c.
+- * LM89-1, and LM99-1 have address 0x4d.
++ * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658
++ * have address 0x4c.
++ * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d.
+  * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
+- * ADT7461 always has address 0x4c.
+  */
+ 
+ static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
+@@ -345,10 +345,74 @@ static SENSOR_DEVICE_ATTR(temp1_crit_hys
+ static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4);
+ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+ 
++/* pec used for ADM1032 only */
++static ssize_t show_pec(struct device *dev, struct device_attribute *dummy,
++			char *buf)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC));
++}
++
++static ssize_t set_pec(struct device *dev, struct device_attribute *dummy,
++		       const char *buf, size_t count)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	long val = simple_strtol(buf, NULL, 10);
++
++	switch (val) {
++	case 0:
++		client->flags &= ~I2C_CLIENT_PEC;
++		break;
++	case 1:
++		client->flags |= I2C_CLIENT_PEC;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	return count;
++}
++
++static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec);
++
+ /*
+  * Real code
+  */
+ 
++/* The ADM1032 supports PEC but not on write byte transactions, so we need
++   to explicitely ask for a transaction without PEC. */
++static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
++{
++	return i2c_smbus_xfer(client->adapter, client->addr,
++			      client->flags & ~I2C_CLIENT_PEC,
++			      I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
++}
++
++/* It is assumed that client->update_lock is held (unless we are in
++   detection or initialization steps). This matters when PEC is enabled,
++   because we don't want the address pointer to change between the write
++   byte and the read byte transactions. */
++static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value)
++{
++	int err;
++
++ 	if (client->flags & I2C_CLIENT_PEC) {
++ 		err = adm1032_write_byte(client, reg);
++ 		if (err >= 0)
++ 			err = i2c_smbus_read_byte(client);
++ 	} else
++ 		err = i2c_smbus_read_byte_data(client, reg);
++
++	if (err < 0) {
++		dev_warn(&client->dev, "Register %#02x read failed (%d)\n",
++			 reg, err);
++		return err;
++	}
++	*value = err;
++
++	return 0;
++}
++
+ static int lm90_attach_adapter(struct i2c_adapter *adapter)
+ {
+ 	if (!(adapter->class & I2C_CLASS_HWMON))
+@@ -370,11 +434,10 @@ static int lm90_detect(struct i2c_adapte
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct lm90_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct lm90_data));
+ 
+ 	/* The common I2C client data is placed right before the
+ 	   LM90-specific data. */
+@@ -403,20 +466,22 @@ static int lm90_detect(struct i2c_adapte
+ 	if (kind < 0) { /* detection and identification */
+ 		u8 man_id, chip_id, reg_config1, reg_convrate;
+ 
+-		man_id = i2c_smbus_read_byte_data(new_client,
+-			 LM90_REG_R_MAN_ID);
+-		chip_id = i2c_smbus_read_byte_data(new_client,
+-			  LM90_REG_R_CHIP_ID);
+-		reg_config1 = i2c_smbus_read_byte_data(new_client,
+-			      LM90_REG_R_CONFIG1);
+-		reg_convrate = i2c_smbus_read_byte_data(new_client,
+-			       LM90_REG_R_CONVRATE);
++		if (lm90_read_reg(new_client, LM90_REG_R_MAN_ID,
++				  &man_id) < 0
++		 || lm90_read_reg(new_client, LM90_REG_R_CHIP_ID,
++		 		  &chip_id) < 0
++		 || lm90_read_reg(new_client, LM90_REG_R_CONFIG1,
++		 		  &reg_config1) < 0
++		 || lm90_read_reg(new_client, LM90_REG_R_CONVRATE,
++		 		  &reg_convrate) < 0)
++			goto exit_free;
+ 		
+ 		if (man_id == 0x01) { /* National Semiconductor */
+ 			u8 reg_config2;
+ 
+-			reg_config2 = i2c_smbus_read_byte_data(new_client,
+-				      LM90_REG_R_CONFIG2);
++			if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2,
++					  &reg_config2) < 0)
++				goto exit_free;
+ 
+ 			if ((reg_config1 & 0x2A) == 0x00
+ 			 && (reg_config2 & 0xF8) == 0x00
+@@ -435,14 +500,12 @@ static int lm90_detect(struct i2c_adapte
+ 			}
+ 		} else
+ 		if (man_id == 0x41) { /* Analog Devices */
+-			if (address == 0x4C
+-			 && (chip_id & 0xF0) == 0x40 /* ADM1032 */
++			if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
+ 			 && (reg_config1 & 0x3F) == 0x00
+ 			 && reg_convrate <= 0x0A) {
+ 				kind = adm1032;
+ 			} else
+-			if (address == 0x4c
+-			 && chip_id == 0x51 /* ADT7461 */
++			if (chip_id == 0x51 /* ADT7461 */
+ 			 && (reg_config1 & 0x1F) == 0x00 /* check compat mode */
+ 			 && reg_convrate <= 0x0A) {
+ 				kind = adt7461;
+@@ -477,6 +540,10 @@ static int lm90_detect(struct i2c_adapte
+ 		name = "lm90";
+ 	} else if (kind == adm1032) {
+ 		name = "adm1032";
++		/* The ADM1032 supports PEC, but only if combined
++		   transactions are not used. */
++		if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
++			new_client->flags |= I2C_CLIENT_PEC;
+ 	} else if (kind == lm99) {
+ 		name = "lm99";
+ 	} else if (kind == lm86) {
+@@ -529,6 +596,9 @@ static int lm90_detect(struct i2c_adapte
+ 			   &sensor_dev_attr_temp2_crit_hyst.dev_attr);
+ 	device_create_file(&new_client->dev, &dev_attr_alarms);
+ 
++	if (new_client->flags & I2C_CLIENT_PEC)
++		device_create_file(&new_client->dev, &dev_attr_pec);
++
+ 	return 0;
+ 
+ exit_detach:
+@@ -548,7 +618,10 @@ static void lm90_init_client(struct i2c_
+ 	 */
+ 	i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE,
+ 				  5); /* 2 Hz */
+-	config = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1);
++	if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) {
++		dev_warn(&client->dev, "Initialization failed!\n");
++		return;
++	}
+ 	if (config & 0x40)
+ 		i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+ 					  config & 0xBF); /* run */
+@@ -576,21 +649,15 @@ static struct lm90_data *lm90_update_dev
+ 	down(&data->update_lock);
+ 
+ 	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+-		u8 oldh, newh;
++		u8 oldh, newh, l;
+ 
+ 		dev_dbg(&client->dev, "Updating lm90 data.\n");
+-		data->temp8[0] = i2c_smbus_read_byte_data(client,
+-				 LM90_REG_R_LOCAL_TEMP);
+-		data->temp8[1] = i2c_smbus_read_byte_data(client,
+-				 LM90_REG_R_LOCAL_LOW);
+-		data->temp8[2] = i2c_smbus_read_byte_data(client,
+-				 LM90_REG_R_LOCAL_HIGH);
+-		data->temp8[3] = i2c_smbus_read_byte_data(client,
+-				 LM90_REG_R_LOCAL_CRIT);
+-		data->temp8[4] = i2c_smbus_read_byte_data(client,
+-				 LM90_REG_R_REMOTE_CRIT);
+-		data->temp_hyst = i2c_smbus_read_byte_data(client,
+-				  LM90_REG_R_TCRIT_HYST);
++		lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]);
++		lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[1]);
++		lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[2]);
++		lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[3]);
++		lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]);
++		lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst);
+ 
+ 		/*
+ 		 * There is a trick here. We have to read two registers to
+@@ -606,36 +673,20 @@ static struct lm90_data *lm90_update_dev
+ 		 * then we have a valid reading. Else we have to read the low
+ 		 * byte again, and now we believe we have a correct reading.
+ 		 */
+-		oldh = i2c_smbus_read_byte_data(client,
+-		       LM90_REG_R_REMOTE_TEMPH);
+-		data->temp11[0] = i2c_smbus_read_byte_data(client,
+-				  LM90_REG_R_REMOTE_TEMPL);
+-		newh = i2c_smbus_read_byte_data(client,
+-		       LM90_REG_R_REMOTE_TEMPH);
+-		if (newh != oldh) {
+-			data->temp11[0] = i2c_smbus_read_byte_data(client,
+-					  LM90_REG_R_REMOTE_TEMPL);
+-#ifdef DEBUG
+-			oldh = i2c_smbus_read_byte_data(client,
+-			       LM90_REG_R_REMOTE_TEMPH);
+-			/* oldh is actually newer */
+-			if (newh != oldh)
+-				dev_warn(&client->dev, "Remote temperature may be "
+-					 "wrong.\n");
+-#endif
+-		}
+-		data->temp11[0] |= (newh << 8);
+-
+-		data->temp11[1] = (i2c_smbus_read_byte_data(client,
+-				   LM90_REG_R_REMOTE_LOWH) << 8) +
+-				   i2c_smbus_read_byte_data(client,
+-				   LM90_REG_R_REMOTE_LOWL);
+-		data->temp11[2] = (i2c_smbus_read_byte_data(client,
+-				   LM90_REG_R_REMOTE_HIGHH) << 8) +
+-				   i2c_smbus_read_byte_data(client,
+-				   LM90_REG_R_REMOTE_HIGHL);
+-		data->alarms = i2c_smbus_read_byte_data(client,
+-			       LM90_REG_R_STATUS);
++		if (lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &oldh) == 0
++		 && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0
++		 && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &newh) == 0
++		 && (newh == oldh
++		  || lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0))
++			data->temp11[0] = (newh << 8) | l;
++
++		if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &newh) == 0
++		 && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0)
++			data->temp11[1] = (newh << 8) | l;
++		if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0
++		 && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0)
++			data->temp11[2] = (newh << 8) | l;
++		lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
+ 
+ 		data->last_updated = jiffies;
+ 		data->valid = 1;
+diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
+--- a/drivers/hwmon/lm92.c
++++ b/drivers/hwmon/lm92.c
+@@ -300,11 +300,10 @@ static int lm92_detect(struct i2c_adapte
+ 					    | I2C_FUNC_SMBUS_WORD_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct lm92_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct lm92_data));
+ 
+ 	/* Fill in enough client fields so that we can read from the chip,
+ 	   which is required for identication */
+diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
+--- a/drivers/hwmon/max1619.c
++++ b/drivers/hwmon/max1619.c
+@@ -197,11 +197,10 @@ static int max1619_detect(struct i2c_ada
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct max1619_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct max1619_data));
+ 
+ 	/* The common I2C client data is placed right before the
+ 	   MAX1619-specific data. */
+diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
+--- a/drivers/hwmon/pc87360.c
++++ b/drivers/hwmon/pc87360.c
+@@ -754,9 +754,8 @@ static int pc87360_detect(struct i2c_ada
+ 	const char *name = "pc87360";
+ 	int use_thermistors = 0;
+ 
+-	if (!(data = kmalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
++	if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
+ 		return -ENOMEM;
+-	memset(data, 0x00, sizeof(struct pc87360_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
+--- a/drivers/hwmon/sis5595.c
++++ b/drivers/hwmon/sis5595.c
+@@ -518,11 +518,10 @@ static int sis5595_detect(struct i2c_ada
+ 			goto exit_release;
+ 	}
+ 
+-	if (!(data = kmalloc(sizeof(struct sis5595_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit_release;
+ 	}
+-	memset(data, 0, sizeof(struct sis5595_data));
+ 
+ 	new_client = &data->client;
+ 	new_client->addr = address;
+diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
+--- a/drivers/hwmon/smsc47b397.c
++++ b/drivers/hwmon/smsc47b397.c
+@@ -244,11 +244,10 @@ static int smsc47b397_detect(struct i2c_
+ 		return -EBUSY;
+ 	}
+ 
+-	if (!(data = kmalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto error_release;
+ 	}
+-	memset(data, 0x00, sizeof(struct smsc47b397_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+@@ -299,7 +298,7 @@ static int __init smsc47b397_find(unsign
+ 	superio_enter();
+ 	id = superio_inb(SUPERIO_REG_DEVID);
+ 
+-	if (id != 0x6f) {
++	if ((id != 0x6f) && (id != 0x81)) {
+ 		superio_exit();
+ 		return -ENODEV;
+ 	}
+@@ -310,8 +309,9 @@ static int __init smsc47b397_find(unsign
+ 	*addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
+ 		 |  superio_inb(SUPERIO_REG_BASE_LSB);
+ 
+-	printk(KERN_INFO "smsc47b397: found SMSC LPC47B397-NC "
+-		"(base address 0x%04x, revision %u)\n", *addr, rev);
++	printk(KERN_INFO "smsc47b397: found SMSC %s "
++		"(base address 0x%04x, revision %u)\n",
++		id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev);
+ 
+ 	superio_exit();
+ 	return 0;
+diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
+--- a/drivers/hwmon/smsc47m1.c
++++ b/drivers/hwmon/smsc47m1.c
+@@ -3,7 +3,7 @@
+                  for hardware monitoring
+ 
+     Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x,
+-    LPC47M15x and LPC47M192 Super-I/O chips.
++    LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
+ 
+     Copyright (C) 2002 Mark D. Studebaker <mdsxyz123 at yahoo.com>
+     Copyright (C) 2004 Jean Delvare <khali at linux-fr.org>
+@@ -356,6 +356,8 @@ static int __init smsc47m1_find(unsigned
+ 	 * 0x5F) and LPC47B27x (device id 0x51) have fan control.
+ 	 * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
+ 	 * can do much more besides (device id 0x60).
++	 * The LPC47M997 is undocumented, but seems to be compatible with
++	 * the LPC47M192, and has the same device id.
+ 	 */
+ 	if (val == 0x51)
+ 		printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
+@@ -364,7 +366,8 @@ static int __init smsc47m1_find(unsigned
+ 	else if (val == 0x5F)
+ 		printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
+ 	else if (val == 0x60)
+-		printk(KERN_INFO "smsc47m1: Found SMSC LPC47M15x/LPC47M192\n");
++		printk(KERN_INFO "smsc47m1: Found SMSC "
++		       "LPC47M15x/LPC47M192/LPC47M997\n");
+ 	else {
+ 		superio_exit();
+ 		return -ENODEV;
+@@ -396,11 +399,10 @@ static int smsc47m1_detect(struct i2c_ad
+ 		return -EBUSY;
+ 	}
+ 
+-	if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto error_release;
+ 	}
+-	memset(data, 0x00, sizeof(struct smsc47m1_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
+--- a/drivers/hwmon/via686a.c
++++ b/drivers/hwmon/via686a.c
+@@ -44,7 +44,7 @@
+ 
+ /* If force_addr is set to anything different from 0, we forcibly enable
+    the device at the given address. */
+-static unsigned short force_addr = 0;
++static unsigned short force_addr;
+ module_param(force_addr, ushort, 0);
+ MODULE_PARM_DESC(force_addr,
+ 		 "Initialize the base address of the sensors");
+@@ -198,7 +198,7 @@ static inline u8 FAN_TO_REG(long rpm, in
+  but the function is very linear in the useful range (0-80 deg C), so
+  we'll just use linear interpolation for 10-bit readings.)  So, tempLUT
+  is the temp at via register values 0-255: */
+-static const long tempLUT[] =
++static const s16 tempLUT[] =
+ { -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
+ 	-503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
+ 	-362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
+@@ -270,7 +270,7 @@ static inline u8 TEMP_TO_REG(long val)
+ }
+ 
+ /* for 8-bit temperature hyst and over registers */
+-#define TEMP_FROM_REG(val) (tempLUT[(val)] * 100)
++#define TEMP_FROM_REG(val)	((long)tempLUT[val] * 100)
+ 
+ /* for 10-bit temperature readings */
+ static inline long TEMP_FROM_REG10(u16 val)
+@@ -589,10 +589,8 @@ static int via686a_detect(struct i2c_ada
+ 	u16 val;
+ 
+ 	/* 8231 requires multiple of 256, we enforce that on 686 as well */
+-	if (force_addr)
+-		address = force_addr & 0xFF00;
+-
+ 	if (force_addr) {
++		address = force_addr & 0xFF00;
+ 		dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n",
+ 			 address);
+ 		if (PCIBIOS_SUCCESSFUL !=
+@@ -603,11 +601,17 @@ static int via686a_detect(struct i2c_ada
+ 	    pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val))
+ 		return -ENODEV;
+ 	if (!(val & 0x0001)) {
+-		dev_warn(&adapter->dev, "enabling sensors\n");
+-		if (PCIBIOS_SUCCESSFUL !=
+-		    pci_write_config_word(s_bridge, VIA686A_ENABLE_REG,
+-					  val | 0x0001))
++		if (force_addr) {
++			dev_info(&adapter->dev, "enabling sensors\n");
++			if (PCIBIOS_SUCCESSFUL !=
++			    pci_write_config_word(s_bridge, VIA686A_ENABLE_REG,
++						  val | 0x0001))
++				return -ENODEV;
++		} else {
++			dev_warn(&adapter->dev, "sensors disabled - enable "
++				 "with force_addr=0x%x\n", address);
+ 			return -ENODEV;
++		}
+ 	}
+ 
+ 	/* Reserve the ISA region */
+@@ -617,11 +621,10 @@ static int via686a_detect(struct i2c_ada
+ 		return -ENODEV;
+ 	}
+ 
+-	if (!(data = kmalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit_release;
+ 	}
+-	memset(data, 0, sizeof(struct via686a_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+@@ -708,7 +711,6 @@ static int via686a_detach_client(struct 
+ 	return 0;
+ }
+ 
+-/* Called when we have found a new VIA686A. Set limits, etc. */
+ static void via686a_init_client(struct i2c_client *client)
+ {
+ 	u8 reg;
+diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
+--- a/drivers/hwmon/w83627ehf.c
++++ b/drivers/hwmon/w83627ehf.c
+@@ -105,7 +105,9 @@ superio_exit(void)
+  * ISA constants
+  */
+ 
+-#define REGION_LENGTH		8
++#define REGION_ALIGNMENT	~7
++#define REGION_OFFSET		5
++#define REGION_LENGTH		2
+ #define ADDR_REG_OFFSET		5
+ #define DATA_REG_OFFSET		6
+ 
+@@ -673,16 +675,16 @@ static int w83627ehf_detect(struct i2c_a
+ 	struct w83627ehf_data *data;
+ 	int i, err = 0;
+ 
+-	if (!request_region(address, REGION_LENGTH, w83627ehf_driver.name)) {
++	if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
++	                    w83627ehf_driver.name)) {
+ 		err = -EBUSY;
+ 		goto exit;
+ 	}
+ 
+-	if (!(data = kmalloc(sizeof(struct w83627ehf_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct w83627ehf_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit_release;
+ 	}
+-	memset(data, 0, sizeof(struct w83627ehf_data));
+ 
+ 	client = &data->client;
+ 	i2c_set_clientdata(client, data);
+@@ -762,7 +764,7 @@ exit_detach:
+ exit_free:
+ 	kfree(data);
+ exit_release:
+-	release_region(address, REGION_LENGTH);
++	release_region(address + REGION_OFFSET, REGION_LENGTH);
+ exit:
+ 	return err;
+ }
+@@ -776,7 +778,7 @@ static int w83627ehf_detach_client(struc
+ 
+ 	if ((err = i2c_detach_client(client)))
+ 		return err;
+-	release_region(client->addr, REGION_LENGTH);
++	release_region(client->addr + REGION_OFFSET, REGION_LENGTH);
+ 	kfree(data);
+ 
+ 	return 0;
+@@ -807,7 +809,7 @@ static int __init w83627ehf_find(int sio
+ 	superio_select(W83627EHF_LD_HWM);
+ 	val = (superio_inb(SIO_REG_ADDR) << 8)
+ 	    | superio_inb(SIO_REG_ADDR + 1);
+-	*addr = val & ~(REGION_LENGTH - 1);
++	*addr = val & REGION_ALIGNMENT;
+ 	if (*addr == 0) {
+ 		superio_exit();
+ 		return -ENODEV;
+diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
+--- a/drivers/hwmon/w83627hf.c
++++ b/drivers/hwmon/w83627hf.c
+@@ -142,10 +142,14 @@ superio_exit(void)
+ #define WINB_BASE_REG 0x60
+ /* Constants specified below */
+ 
+-/* Length of ISA address segment */
+-#define WINB_EXTENT 8
++/* Alignment of the base address */
++#define WINB_ALIGNMENT		~7
+ 
+-/* Where are the ISA address/data registers relative to the base address */
++/* Offset & size of I/O region we are interested in */
++#define WINB_REGION_OFFSET	5
++#define WINB_REGION_SIZE	2
++
++/* Where are the sensors address/data registers relative to the base address */
+ #define W83781D_ADDR_REG_OFFSET 5
+ #define W83781D_DATA_REG_OFFSET 6
+ 
+@@ -197,7 +201,6 @@ superio_exit(void)
+ 
+ #define W83627HF_REG_PWM1 0x5A
+ #define W83627HF_REG_PWM2 0x5B
+-#define W83627HF_REG_PWMCLK12 0x5C
+ 
+ #define W83627THF_REG_PWM1		0x01	/* 697HF and 637HF too */
+ #define W83627THF_REG_PWM2		0x03	/* 697HF and 637HF too */
+@@ -981,7 +984,7 @@ static int __init w83627hf_find(int sioa
+ 	superio_select(W83627HF_LD_HWM);
+ 	val = (superio_inb(WINB_BASE_REG) << 8) |
+ 	       superio_inb(WINB_BASE_REG + 1);
+-	*addr = val & ~(WINB_EXTENT - 1);
++	*addr = val & WINB_ALIGNMENT;
+ 	if (*addr == 0 && force_addr == 0) {
+ 		superio_exit();
+ 		return -ENODEV;
+@@ -1000,9 +1003,10 @@ static int w83627hf_detect(struct i2c_ad
+ 	const char *client_name = "";
+ 
+ 	if(force_addr)
+-		address = force_addr & ~(WINB_EXTENT - 1);
++		address = force_addr & WINB_ALIGNMENT;
+ 
+-	if (!request_region(address, WINB_EXTENT, w83627hf_driver.name)) {
++	if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE,
++	                    w83627hf_driver.name)) {
+ 		err = -EBUSY;
+ 		goto ERROR0;
+ 	}
+@@ -1041,11 +1045,10 @@ static int w83627hf_detect(struct i2c_ad
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access w83627hf_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto ERROR1;
+ 	}
+-	memset(data, 0, sizeof(struct w83627hf_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+@@ -1148,7 +1151,7 @@ static int w83627hf_detect(struct i2c_ad
+       ERROR2:
+ 	kfree(data);
+       ERROR1:
+-	release_region(address, WINB_EXTENT);
++	release_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE);
+       ERROR0:
+ 	return err;
+ }
+@@ -1163,7 +1166,7 @@ static int w83627hf_detach_client(struct
+ 	if ((err = i2c_detach_client(client)))
+ 		return err;
+ 
+-	release_region(client->addr, WINB_EXTENT);
++	release_region(client->addr + WINB_REGION_OFFSET, WINB_REGION_SIZE);
+ 	kfree(data);
+ 
+ 	return 0;
+@@ -1275,7 +1278,6 @@ static int w83627hf_write_value(struct i
+ 	return 0;
+ }
+ 
+-/* Called when we have found a new W83781D. It should set limits, etc. */
+ static void w83627hf_init_client(struct i2c_client *client)
+ {
+ 	struct w83627hf_data *data = i2c_get_clientdata(client);
+@@ -1369,12 +1371,6 @@ static void w83627hf_init_client(struct 
+ 			}
+ 		}
+ 
+-		if (type == w83627hf) {
+-			/* enable PWM2 control (can't hurt since PWM reg
+-		           should have been reset to 0xff) */
+-			w83627hf_write_value(client, W83627HF_REG_PWMCLK12,
+-					    0x19);
+-		}
+ 		/* enable comparator mode for temp2 and temp3 so
+ 	           alarm indication will work correctly */
+ 		i = w83627hf_read_value(client, W83781D_REG_IRQ);
+diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
+--- a/drivers/hwmon/w83781d.c
++++ b/drivers/hwmon/w83781d.c
+@@ -889,12 +889,11 @@ w83781d_detect_subclients(struct i2c_ada
+ 	const char *client_name = "";
+ 	struct w83781d_data *data = i2c_get_clientdata(new_client);
+ 
+-	data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ 	if (!(data->lm75[0])) {
+ 		err = -ENOMEM;
+ 		goto ERROR_SC_0;
+ 	}
+-	memset(data->lm75[0], 0x00, sizeof (struct i2c_client));
+ 
+ 	id = i2c_adapter_id(adapter);
+ 
+@@ -919,13 +918,11 @@ w83781d_detect_subclients(struct i2c_ada
+ 	}
+ 
+ 	if (kind != w83783s) {
+-
+-		data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
++		data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ 		if (!(data->lm75[1])) {
+ 			err = -ENOMEM;
+ 			goto ERROR_SC_1;
+ 		}
+-		memset(data->lm75[1], 0x0, sizeof(struct i2c_client));
+ 
+ 		if (force_subclients[0] == id &&
+ 		    force_subclients[1] == address) {
+@@ -1064,11 +1061,10 @@ w83781d_detect(struct i2c_adapter *adapt
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access w83781d_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto ERROR1;
+ 	}
+-	memset(data, 0, sizeof(struct w83781d_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+@@ -1451,7 +1447,6 @@ w83781d_write_value(struct i2c_client *c
+ 	return 0;
+ }
+ 
+-/* Called when we have found a new W83781D. It should set limits, etc. */
+ static void
+ w83781d_init_client(struct i2c_client *client)
+ {
+diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
+--- a/drivers/hwmon/w83792d.c
++++ b/drivers/hwmon/w83792d.c
+@@ -1086,11 +1086,10 @@ w83792d_create_subclient(struct i2c_adap
+ 	int err;
+ 	struct i2c_client *sub_client;
+ 
+-	(*sub_cli) = sub_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	(*sub_cli) = sub_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ 	if (!(sub_client)) {
+ 		return -ENOMEM;
+ 	}
+-	memset(sub_client, 0x00, sizeof(struct i2c_client));
+ 	sub_client->addr = 0x48 + addr;
+ 	i2c_set_clientdata(sub_client, NULL);
+ 	sub_client->adapter = adapter;
+@@ -1184,11 +1183,10 @@ w83792d_detect(struct i2c_adapter *adapt
+ 	   client structure, even though we cannot fill it completely yet.
+ 	   But it allows us to access w83792d_{read,write}_value. */
+ 
+-	if (!(data = kmalloc(sizeof(struct w83792d_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto ERROR0;
+ 	}
+-	memset(data, 0, sizeof(struct w83792d_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+@@ -1429,7 +1427,6 @@ w83792d_write_value(struct i2c_client *c
+ 	return 0;
+ }
+ 
+-/* Called when we have found a new W83792D. It should set limits, etc. */
+ static void
+ w83792d_init_client(struct i2c_client *client)
+ {
+diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c
+--- a/drivers/hwmon/w83l785ts.c
++++ b/drivers/hwmon/w83l785ts.c
+@@ -37,6 +37,7 @@
+ #include <linux/jiffies.h>
+ #include <linux/i2c.h>
+ #include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
+ #include <linux/err.h>
+ 
+ /* How many retries on register read error */
+@@ -73,7 +74,7 @@ I2C_CLIENT_INSMOD_1(w83l785ts);
+  * The W83L785TS-S uses signed 8-bit values.
+  */
+ 
+-#define TEMP_FROM_REG(val)	((val & 0x80 ? val-0x100 : val) * 1000)
++#define TEMP_FROM_REG(val)	((val) * 1000)
+ 
+ /*
+  * Functions declaration
+@@ -111,27 +112,24 @@ struct w83l785ts_data {
+ 	unsigned long last_updated; /* in jiffies */
+ 
+ 	/* registers values */
+-	u8 temp, temp_over;
++	s8 temp[2]; /* 0: input
++		       1: critical limit */
+ };
+ 
+ /*
+  * Sysfs stuff
+  */
+ 
+-static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
++static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
++	char *buf)
+ {
++	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ 	struct w83l785ts_data *data = w83l785ts_update_device(dev);
+-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
++	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
+ }
+ 
+-static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
+-{
+-	struct w83l785ts_data *data = w83l785ts_update_device(dev);
+-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
+-}
+-
+-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+-static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL);
++static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
++static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, 1);
+ 
+ /*
+  * Real code
+@@ -158,12 +156,10 @@ static int w83l785ts_detect(struct i2c_a
+ 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct w83l785ts_data));
+-
+ 
+ 	/* The common I2C client data is placed right before the
+ 	 * W83L785TS-specific data. */
+@@ -228,7 +224,7 @@ static int w83l785ts_detect(struct i2c_a
+ 	init_MUTEX(&data->update_lock);
+ 
+ 	/* Default values in case the first read fails (unlikely). */
+-	data->temp_over = data->temp = 0;
++	data->temp[1] = data->temp[0] = 0;
+ 
+ 	/* Tell the I2C layer a new client has arrived. */
+ 	if ((err = i2c_attach_client(new_client))) 
+@@ -246,8 +242,10 @@ static int w83l785ts_detect(struct i2c_a
+ 		goto exit_detach;
+ 	}
+ 
+-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
++	device_create_file(&new_client->dev,
++			   &sensor_dev_attr_temp1_input.dev_attr);
++	device_create_file(&new_client->dev,
++			   &sensor_dev_attr_temp1_max.dev_attr);
+ 
+ 	return 0;
+ 
+@@ -305,10 +303,10 @@ static struct w83l785ts_data *w83l785ts_
+ 
+ 	if (!data->valid || time_after(jiffies, data->last_updated + HZ * 2)) {
+ 		dev_dbg(&client->dev, "Updating w83l785ts data.\n");
+-		data->temp = w83l785ts_read_value(client,
+-			     W83L785TS_REG_TEMP, data->temp);
+-		data->temp_over = w83l785ts_read_value(client,
+-				  W83L785TS_REG_TEMP_OVER, data->temp_over);
++		data->temp[0] = w83l785ts_read_value(client,
++				W83L785TS_REG_TEMP, data->temp[0]);
++		data->temp[1] = w83l785ts_read_value(client,
++				W83L785TS_REG_TEMP_OVER, data->temp[1]);
+ 
+ 		data->last_updated = jiffies;
+ 		data->valid = 1;
+diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
+--- a/drivers/i2c/algos/i2c-algo-pca.c
++++ b/drivers/i2c/algos/i2c-algo-pca.c
+@@ -34,7 +34,7 @@
+ #define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0)
+ #define DEB3(fmt, args...) do { if (i2c_debug>=3) printk(fmt, ## args); } while(0)
+ 
+-static int i2c_debug=0;
++static int i2c_debug;
+ 
+ #define pca_outw(adap, reg, val) adap->write_byte(adap, reg, val)
+ #define pca_inw(adap, reg) adap->read_byte(adap, reg)
+diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c
+--- a/drivers/i2c/algos/i2c-algo-sibyte.c
++++ b/drivers/i2c/algos/i2c-algo-sibyte.c
+@@ -42,7 +42,7 @@
+ 
+ /* module parameters:
+  */
+-static int bit_scan=0;	/* have a look at what's hanging 'round		*/
++static int bit_scan;	/* have a look at what's hanging 'round		*/
+ 
+ 
+ static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, 
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -135,11 +135,12 @@ config I2C_I810
+ 	help
+ 	  If you say yes to this option, support will be included for the Intel
+ 	  810/815 family of mainboard I2C interfaces.  Specifically, the 
+-	  following versions of the chipset is supported:
++	  following versions of the chipset are supported:
+ 	    i810AA
+ 	    i810AB
+ 	    i810E
+ 	    i815
++	    i845G
+ 
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called i2c-i810.
+diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
+--- a/drivers/i2c/busses/i2c-ali1535.c
++++ b/drivers/i2c/busses/i2c-ali1535.c
+@@ -134,7 +134,7 @@
+ 					/*  -> Read  = 1		*/
+ #define	ALI1535_SMBIO_EN	0x04	/* SMB I/O Space enable		*/
+ 
+-
++static struct pci_driver ali1535_driver;
+ static unsigned short ali1535_smba;
+ static DECLARE_MUTEX(i2c_ali1535_sem);
+ 
+@@ -162,7 +162,8 @@ static int ali1535_setup(struct pci_dev 
+ 		goto exit;
+ 	}
+ 
+-	if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE, "ali1535-smb")) {
++	if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
++			    ali1535_driver.name)) {
+ 		dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n",
+ 			ali1535_smba);
+ 		goto exit;
+@@ -480,7 +481,6 @@ static struct i2c_adapter ali1535_adapte
+ 	.owner		= THIS_MODULE,
+ 	.class          = I2C_CLASS_HWMON,
+ 	.algo		= &smbus_algorithm,
+-	.name		= "unset",
+ };
+ 
+ static struct pci_device_id ali1535_ids[] = {
+@@ -513,6 +513,7 @@ static void __devexit ali1535_remove(str
+ }
+ 
+ static struct pci_driver ali1535_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "ali1535_smbus",
+ 	.id_table	= ali1535_ids,
+ 	.probe		= ali1535_probe,
+diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
+--- a/drivers/i2c/busses/i2c-ali1563.c
++++ b/drivers/i2c/busses/i2c-ali1563.c
+@@ -60,6 +60,7 @@
+ 
+ #define HST_CNTL2_SIZEMASK	0x38
+ 
++static struct pci_driver ali1563_pci_driver;
+ static unsigned short ali1563_smba;
+ 
+ static int ali1563_transaction(struct i2c_adapter * a, int size)
+@@ -350,7 +351,8 @@ static int __devinit ali1563_setup(struc
+ 		dev_warn(&dev->dev,"ali1563_smba Uninitialized\n");
+ 		goto Err;
+ 	}
+-	if (!request_region(ali1563_smba,ALI1563_SMB_IOSIZE,"i2c-ali1563")) {
++	if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE,
++			    ali1563_pci_driver.name)) {
+ 		dev_warn(&dev->dev,"Could not allocate I/O space");
+ 		goto Err;
+ 	}
+@@ -406,7 +408,8 @@ static struct pci_device_id __devinitdat
+ MODULE_DEVICE_TABLE (pci, ali1563_id_table);
+ 
+ static struct pci_driver ali1563_pci_driver = {
+- 	.name		= "ali1563_i2c",
++	.owner		= THIS_MODULE,
++ 	.name		= "ali1563_smbus",
+ 	.id_table	= ali1563_id_table,
+  	.probe		= ali1563_probe,
+ 	.remove		= __devexit_p(ali1563_remove),
+diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
+--- a/drivers/i2c/busses/i2c-ali15x3.c
++++ b/drivers/i2c/busses/i2c-ali15x3.c
+@@ -125,12 +125,13 @@
+ 
+ /* If force_addr is set to anything different from 0, we forcibly enable
+    the device at the given address. */
+-static u16 force_addr = 0;
++static u16 force_addr;
+ module_param(force_addr, ushort, 0);
+ MODULE_PARM_DESC(force_addr,
+ 		 "Initialize the base address of the i2c controller");
+ 
+-static unsigned short ali15x3_smba = 0;
++static struct pci_driver ali15x3_driver;
++static unsigned short ali15x3_smba;
+ 
+ static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
+ {
+@@ -166,7 +167,8 @@ static int ali15x3_setup(struct pci_dev 
+ 	if(force_addr)
+ 		ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1);
+ 
+-	if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, "ali15x3-smb")) {
++	if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE,
++			    ali15x3_driver.name)) {
+ 		dev_err(&ALI15X3_dev->dev,
+ 			"ALI15X3_smb region 0x%x already in use!\n",
+ 			ali15x3_smba);
+@@ -470,7 +472,6 @@ static struct i2c_adapter ali15x3_adapte
+ 	.owner		= THIS_MODULE,
+ 	.class          = I2C_CLASS_HWMON,
+ 	.algo		= &smbus_algorithm,
+-	.name		= "unset",
+ };
+ 
+ static struct pci_device_id ali15x3_ids[] = {
+@@ -503,6 +504,7 @@ static void __devexit ali15x3_remove(str
+ }
+ 
+ static struct pci_driver ali15x3_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "ali15x3_smbus",
+ 	.id_table	= ali15x3_ids,
+ 	.probe		= ali15x3_probe,
+diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c
+--- a/drivers/i2c/busses/i2c-amd756-s4882.c
++++ b/drivers/i2c/busses/i2c-amd756-s4882.c
+@@ -169,12 +169,12 @@ static int __init amd756_s4882_init(void
+ 	init_MUTEX(&amd756_lock);
+ 
+ 	/* Define the 5 virtual adapters and algorithms structures */
+-	if (!(s4882_adapter = kmalloc(5 * sizeof(struct i2c_adapter),
++	if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter),
+ 				      GFP_KERNEL))) {
+ 		error = -ENOMEM;
+ 		goto ERROR1;
+ 	}
+-	if (!(s4882_algo = kmalloc(5 * sizeof(struct i2c_algorithm),
++	if (!(s4882_algo = kzalloc(5 * sizeof(struct i2c_algorithm),
+ 				   GFP_KERNEL))) {
+ 		error = -ENOMEM;
+ 		goto ERROR2;
+diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
+--- a/drivers/i2c/busses/i2c-amd756.c
++++ b/drivers/i2c/busses/i2c-amd756.c
+@@ -85,8 +85,8 @@
+ #define AMD756_PROCESS_CALL	0x04
+ #define AMD756_BLOCK_DATA	0x05
+ 
+-
+-static unsigned short amd756_ioport = 0;
++static struct pci_driver amd756_driver;
++static unsigned short amd756_ioport;
+ 
+ /* 
+   SMBUS event = I/O 28-29 bit 11
+@@ -303,7 +303,6 @@ struct i2c_adapter amd756_smbus = {
+ 	.owner		= THIS_MODULE,
+ 	.class          = I2C_CLASS_HWMON,
+ 	.algo		= &smbus_algorithm,
+-	.name		= "unset",
+ };
+ 
+ enum chiptype { AMD756, AMD766, AMD768, NFORCE, AMD8111 };
+@@ -365,7 +364,7 @@ static int __devinit amd756_probe(struct
+ 		amd756_ioport += SMB_ADDR_OFFSET;
+ 	}
+ 
+-	if (!request_region(amd756_ioport, SMB_IOSIZE, "amd756-smbus")) {
++	if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
+ 		dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
+ 			amd756_ioport);
+ 		return -ENODEV;
+@@ -402,6 +401,7 @@ static void __devexit amd756_remove(stru
+ }
+ 
+ static struct pci_driver amd756_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "amd756_smbus",
+ 	.id_table	= amd756_ids,
+ 	.probe		= amd756_probe,
+diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
+--- a/drivers/i2c/busses/i2c-amd8111.c
++++ b/drivers/i2c/busses/i2c-amd8111.c
+@@ -30,6 +30,8 @@ struct amd_smbus {
+ 	int size;
+ };
+ 
++static struct pci_driver amd8111_driver;
++
+ /*
+  * AMD PCI control registers definitions.
+  */
+@@ -242,7 +244,6 @@ static s32 amd8111_access(struct i2c_ada
+ 			break;
+ 
+ 		case I2C_SMBUS_BLOCK_PROC_CALL:
+-			protocol |= pec;
+ 			len = min_t(u8, data->block[0], 31);
+ 			amd_ec_write(smbus, AMD_SMB_CMD, command);
+ 			amd_ec_write(smbus, AMD_SMB_BCNT, len);
+@@ -252,13 +253,6 @@ static s32 amd8111_access(struct i2c_ada
+ 			read_write = I2C_SMBUS_READ;
+ 			break;
+ 
+-		case I2C_SMBUS_WORD_DATA_PEC:
+-		case I2C_SMBUS_BLOCK_DATA_PEC:
+-		case I2C_SMBUS_PROC_CALL_PEC:
+-		case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
+-			dev_warn(&adap->dev, "Unexpected software PEC transaction %d\n.", size);
+-			return -1;
+-
+ 		default:
+ 			dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+ 			return -1;
+@@ -343,16 +337,15 @@ static int __devinit amd8111_probe(struc
+ 	if (~pci_resource_flags(dev, 0) & IORESOURCE_IO)
+ 		return -ENODEV;
+ 
+-	smbus = kmalloc(sizeof(struct amd_smbus), GFP_KERNEL);
++	smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL);
+ 	if (!smbus)
+ 		return -ENOMEM;
+-	memset(smbus, 0, sizeof(struct amd_smbus));
+ 
+ 	smbus->dev = dev;
+ 	smbus->base = pci_resource_start(dev, 0);
+ 	smbus->size = pci_resource_len(dev, 0);
+ 
+-	if (!request_region(smbus->base, smbus->size, "amd8111 SMBus 2.0"))
++	if (!request_region(smbus->base, smbus->size, amd8111_driver.name))
+ 		goto out_kfree;
+ 
+ 	smbus->adapter.owner = THIS_MODULE;
+@@ -391,6 +384,7 @@ static void __devexit amd8111_remove(str
+ }
+ 
+ static struct pci_driver amd8111_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "amd8111_smbus2",
+ 	.id_table	= amd8111_ids,
+ 	.probe		= amd8111_probe,
+diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
+--- a/drivers/i2c/busses/i2c-elektor.c
++++ b/drivers/i2c/busses/i2c-elektor.c
+@@ -22,7 +22,7 @@
+ /* With some changes from Kyösti Mälkki <kmalkki at cc.hut.fi> and even
+    Frodo Looijaard <frodol at dds.nl> */
+ 
+-/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of 
++/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of
+    for Alpha Processor Inc. UP-2000(+) boards */
+ 
+ #include <linux/kernel.h>
+@@ -46,12 +46,14 @@
+ #define DEFAULT_BASE 0x330
+ 
+ static int base;
++static u8 __iomem *base_iomem;
++
+ static int irq;
+ static int clock  = 0x1c;
+ static int own    = 0x55;
+ static int mmapped;
+ 
+-/* vdovikin: removed static struct i2c_pcf_isa gpi; code - 
++/* vdovikin: removed static struct i2c_pcf_isa gpi; code -
+   this module in real supports only one device, due to missing arguments
+   in some functions, called from the algo-pcf module. Sometimes it's
+   need to be rewriten - but for now just remove this for simpler reading */
+@@ -60,40 +62,33 @@ static wait_queue_head_t pcf_wait;
+ static int pcf_pending;
+ static spinlock_t lock;
+ 
++static struct i2c_adapter pcf_isa_ops;
++
+ /* ----- local functions ----------------------------------------------	*/
+ 
+ static void pcf_isa_setbyte(void *data, int ctl, int val)
+ {
+-	int address = ctl ? (base + 1) : base;
++	u8 __iomem *address = ctl ? (base_iomem + 1) : base_iomem;
+ 
+ 	/* enable irq if any specified for serial operation */
+ 	if (ctl && irq && (val & I2C_PCF_ESO)) {
+ 		val |= I2C_PCF_ENI;
+ 	}
+ 
+-	pr_debug("i2c-elektor: Write 0x%X 0x%02X\n", address, val & 255);
+-
+-	switch (mmapped) {
+-	case 0: /* regular I/O */
+-		outb(val, address);
+-		break;
+-	case 2: /* double mapped I/O needed for UP2000 board,
+-                   I don't know why this... */
+-		writeb(val, (void *)address);
+-		/* fall */
+-	case 1: /* memory mapped I/O */
+-		writeb(val, (void *)address);
+-		break;
+-	}
++	pr_debug("%s: Write %p 0x%02X\n", pcf_isa_ops.name, address, val);
++	iowrite8(val, address);
++#ifdef __alpha__
++	/* API UP2000 needs some hardware fudging to make the write stick */
++	iowrite8(val, address);
++#endif
+ }
+ 
+ static int pcf_isa_getbyte(void *data, int ctl)
+ {
+-	int address = ctl ? (base + 1) : base;
+-	int val = mmapped ? readb((void *)address) : inb(address);
+-
+-	pr_debug("i2c-elektor: Read 0x%X 0x%02X\n", address, val);
++	u8 __iomem *address = ctl ? (base_iomem + 1) : base_iomem;
++	int val = ioread8(address);
+ 
++	pr_debug("%s: Read %p 0x%02X\n", pcf_isa_ops.name, address, val);
+ 	return (val);
+ }
+ 
+@@ -149,16 +144,40 @@ static int pcf_isa_init(void)
+ {
+ 	spin_lock_init(&lock);
+ 	if (!mmapped) {
+-		if (!request_region(base, 2, "i2c (isa bus adapter)")) {
+-			printk(KERN_ERR
+-			       "i2c-elektor: requested I/O region (0x%X:2) "
+-			       "is in use.\n", base);
++		if (!request_region(base, 2, pcf_isa_ops.name)) {
++			printk(KERN_ERR "%s: requested I/O region (%#x:2) is "
++			       "in use\n", pcf_isa_ops.name, base);
++			return -ENODEV;
++		}
++		base_iomem = ioport_map(base, 2);
++		if (!base_iomem) {
++			printk(KERN_ERR "%s: remap of I/O region %#x failed\n",
++			       pcf_isa_ops.name, base);
++			release_region(base, 2);
++			return -ENODEV;
++		}
++	} else {
++		if (!request_mem_region(base, 2, pcf_isa_ops.name)) {
++			printk(KERN_ERR "%s: requested memory region (%#x:2) "
++			       "is in use\n", pcf_isa_ops.name, base);
++			return -ENODEV;
++		}
++		base_iomem = ioremap(base, 2);
++		if (base_iomem == NULL) {
++			printk(KERN_ERR "%s: remap of memory region %#x "
++			       "failed\n", pcf_isa_ops.name, base);
++			release_mem_region(base, 2);
+ 			return -ENODEV;
+ 		}
+ 	}
++	pr_debug("%s: registers %#x remapped to %p\n", pcf_isa_ops.name, base,
++		 base_iomem);
++
+ 	if (irq > 0) {
+-		if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", NULL) < 0) {
+-			printk(KERN_ERR "i2c-elektor: Request irq%d failed\n", irq);
++		if (request_irq(irq, pcf_isa_handler, 0, pcf_isa_ops.name,
++				NULL) < 0) {
++			printk(KERN_ERR "%s: Request irq%d failed\n",
++			       pcf_isa_ops.name, irq);
+ 			irq = 0;
+ 		} else
+ 			enable_irq(irq);
+@@ -186,47 +205,49 @@ static struct i2c_adapter pcf_isa_ops = 
+ 	.class		= I2C_CLASS_HWMON,
+ 	.id		= I2C_HW_P_ELEK,
+ 	.algo_data	= &pcf_isa_data,
+-	.name		= "PCF8584 ISA adapter",
++	.name		= "i2c-elektor",
+ };
+ 
+-static int __init i2c_pcfisa_init(void) 
++static int __init i2c_pcfisa_init(void)
+ {
+ #ifdef __alpha__
+-	/* check to see we have memory mapped PCF8584 connected to the 
++	/* check to see we have memory mapped PCF8584 connected to the
+ 	Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
+ 	if (base == 0) {
+ 		struct pci_dev *cy693_dev;
+-		
+-		cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ, 
++
++		cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ,
+ 					   PCI_DEVICE_ID_CONTAQ_82C693, NULL);
+ 		if (cy693_dev) {
+-			char config;
++			unsigned char config;
+ 			/* yeap, we've found cypress, let's check config */
+ 			if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
+-				
+-				pr_debug("i2c-elektor: found cy82c693, config register 0x47 = 0x%02x.\n", config);
++
++				pr_debug("%s: found cy82c693, config "
++					 "register 0x47 = 0x%02x\n",
++					 pcf_isa_ops.name, config);
+ 
+ 				/* UP2000 board has this register set to 0xe1,
+-                                   but the most significant bit as seems can be 
++				   but the most significant bit as seems can be
+ 				   reset during the proper initialisation
+-                                   sequence if guys from API decides to do that
+-                                   (so, we can even enable Tsunami Pchip
+-                                   window for the upper 1 Gb) */
++				   sequence if guys from API decides to do that
++				   (so, we can even enable Tsunami Pchip
++				   window for the upper 1 Gb) */
+ 
+ 				/* so just check for ROMCS at 0xe0000,
+-                                   ROMCS enabled for writes
++				   ROMCS enabled for writes
+ 				   and external XD Bus buffer in use. */
+ 				if ((config & 0x7f) == 0x61) {
+ 					/* seems to be UP2000 like board */
+ 					base = 0xe0000;
+-                                        /* I don't know why we need to
+-                                           write twice */
+-					mmapped = 2;
+-                                        /* UP2000 drives ISA with
++					mmapped = 1;
++					/* UP2000 drives ISA with
+ 					   8.25 MHz (PCI/4) clock
+ 					   (this can be read from cypress) */
+ 					clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
+-					printk(KERN_INFO "i2c-elektor: found API UP2000 like board, will probe PCF8584 later.\n");
++					pr_info("%s: found API UP2000 like "
++						"board, will probe PCF8584 "
++						"later\n", pcf_isa_ops.name);
+ 				}
+ 			}
+ 			pci_dev_put(cy693_dev);
+@@ -236,12 +257,11 @@ static int __init i2c_pcfisa_init(void) 
+ 
+ 	/* sanity checks for mmapped I/O */
+ 	if (mmapped && base < 0xc8000) {
+-		printk(KERN_ERR "i2c-elektor: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
++		printk(KERN_ERR "%s: incorrect base address (%#x) specified "
++		       "for mmapped I/O\n", pcf_isa_ops.name, base);
+ 		return -ENODEV;
+ 	}
+ 
+-	printk(KERN_INFO "i2c-elektor: i2c pcf8584-isa adapter driver\n");
+-
+ 	if (base == 0) {
+ 		base = DEFAULT_BASE;
+ 	}
+@@ -251,8 +271,8 @@ static int __init i2c_pcfisa_init(void) 
+ 		return -ENODEV;
+ 	if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
+ 		goto fail;
+-	
+-	printk(KERN_ERR "i2c-elektor: found device at %#x.\n", base);
++
++	dev_info(&pcf_isa_ops.dev, "found device at %#x\n", base);
+ 
+ 	return 0;
+ 
+@@ -262,8 +282,13 @@ static int __init i2c_pcfisa_init(void) 
+ 		free_irq(irq, NULL);
+ 	}
+ 
+-	if (!mmapped)
+-		release_region(base , 2);
++	if (!mmapped) {
++		ioport_unmap(base_iomem);
++		release_region(base, 2);
++	} else {
++		iounmap(base_iomem);
++		release_mem_region(base, 2);
++	}
+ 	return -ENODEV;
+ }
+ 
+@@ -276,8 +301,13 @@ static void i2c_pcfisa_exit(void)
+ 		free_irq(irq, NULL);
+ 	}
+ 
+-	if (!mmapped)
+-		release_region(base , 2);
++	if (!mmapped) {
++		ioport_unmap(base_iomem);
++		release_region(base, 2);
++	} else {
++		iounmap(base_iomem);
++		release_mem_region(base, 2);
++	}
+ }
+ 
+ MODULE_AUTHOR("Hans Berglund <hb at spacetec.no>");
+diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
+--- a/drivers/i2c/busses/i2c-hydra.c
++++ b/drivers/i2c/busses/i2c-hydra.c
+@@ -155,6 +155,7 @@ static void __devexit hydra_remove(struc
+ 
+ 
+ static struct pci_driver hydra_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "hydra_smbus",
+ 	.id_table	= hydra_ids,
+ 	.probe		= hydra_probe,
+diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
+--- a/drivers/i2c/busses/i2c-i801.c
++++ b/drivers/i2c/busses/i2c-i801.c
+@@ -52,10 +52,6 @@
+ #include <linux/i2c.h>
+ #include <asm/io.h>
+ 
+-#ifdef I2C_FUNC_SMBUS_BLOCK_DATA_PEC
+-#define HAVE_PEC
+-#endif
+-
+ /* I801 SMBus address offsets */
+ #define SMBHSTSTS	(0 + i801_smba)
+ #define SMBHSTCNT	(2 + i801_smba)
+@@ -106,10 +102,11 @@ MODULE_PARM_DESC(force_addr,
+ 		 "EXTREMELY DANGEROUS!");
+ 
+ static int i801_transaction(void);
+-static int i801_block_transaction(union i2c_smbus_data *data,
+-				  char read_write, int command);
++static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
++				  int command, int hwpec);
+ 
+ static unsigned short i801_smba;
++static struct pci_driver i801_driver;
+ static struct pci_dev *I801_dev;
+ static int isich4;
+ 
+@@ -143,7 +140,7 @@ static int i801_setup(struct pci_dev *de
+ 		}
+ 	}
+ 
+-	if (!request_region(i801_smba, (isich4 ? 16 : 8), "i801-smbus")) {
++	if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
+ 		dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
+ 			i801_smba);
+ 		error_return = -EBUSY;
+@@ -252,7 +249,7 @@ static int i801_transaction(void)
+ 
+ /* All-inclusive block transaction function */
+ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+-				  int command)
++				  int command, int hwpec)
+ {
+ 	int i, len;
+ 	int smbcmd;
+@@ -391,8 +388,7 @@ static int i801_block_transaction(union 
+ 			goto END;
+ 	}
+ 
+-#ifdef HAVE_PEC
+-	if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) {
++	if (hwpec) {
+ 		/* wait for INTR bit as advised by Intel */
+ 		timeout = 0;
+ 		do {
+@@ -406,7 +402,6 @@ static int i801_block_transaction(union 
+ 		}
+ 		outb_p(temp, SMBHSTSTS); 
+ 	}
+-#endif
+ 	result = 0;
+ END:
+ 	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
+@@ -421,14 +416,13 @@ static s32 i801_access(struct i2c_adapte
+ 		       unsigned short flags, char read_write, u8 command,
+ 		       int size, union i2c_smbus_data * data)
+ {
+-	int hwpec = 0;
++	int hwpec;
+ 	int block = 0;
+ 	int ret, xact = 0;
+ 
+-#ifdef HAVE_PEC
+-	if(isich4)
+-		hwpec = (flags & I2C_CLIENT_PEC) != 0;
+-#endif
++	hwpec = isich4 && (flags & I2C_CLIENT_PEC)
++		&& size != I2C_SMBUS_QUICK
++		&& size != I2C_SMBUS_I2C_BLOCK_DATA;
+ 
+ 	switch (size) {
+ 	case I2C_SMBUS_QUICK:
+@@ -463,11 +457,6 @@ static s32 i801_access(struct i2c_adapte
+ 		break;
+ 	case I2C_SMBUS_BLOCK_DATA:
+ 	case I2C_SMBUS_I2C_BLOCK_DATA:
+-#ifdef HAVE_PEC
+-	case I2C_SMBUS_BLOCK_DATA_PEC:
+-		if(hwpec && size == I2C_SMBUS_BLOCK_DATA)
+-			size = I2C_SMBUS_BLOCK_DATA_PEC;
+-#endif
+ 		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+ 		       SMBHSTADD);
+ 		outb_p(command, SMBHSTCMD);
+@@ -479,27 +468,18 @@ static s32 i801_access(struct i2c_adapte
+ 		return -1;
+ 	}
+ 
+-#ifdef HAVE_PEC
+-	if(isich4 && hwpec) {
+-		if(size != I2C_SMBUS_QUICK &&
+-		   size != I2C_SMBUS_I2C_BLOCK_DATA)
+-			outb_p(1, SMBAUXCTL);	/* enable HW PEC */
+-	}
+-#endif
++	if (hwpec)
++		outb_p(1, SMBAUXCTL);	/* enable hardware PEC */
++
+ 	if(block)
+-		ret = i801_block_transaction(data, read_write, size);
++		ret = i801_block_transaction(data, read_write, size, hwpec);
+ 	else {
+ 		outb_p(xact | ENABLE_INT9, SMBHSTCNT);
+ 		ret = i801_transaction();
+ 	}
+ 
+-#ifdef HAVE_PEC
+-	if(isich4 && hwpec) {
+-		if(size != I2C_SMBUS_QUICK &&
+-		   size != I2C_SMBUS_I2C_BLOCK_DATA)
+-			outb_p(0, SMBAUXCTL);
+-	}
+-#endif
++	if (hwpec)
++		outb_p(0, SMBAUXCTL);	/* disable hardware PEC */
+ 
+ 	if(block)
+ 		return ret;
+@@ -526,12 +506,7 @@ static u32 i801_func(struct i2c_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_WRITE_I2C_BLOCK
+-#ifdef HAVE_PEC
+-	     | (isich4 ? I2C_FUNC_SMBUS_BLOCK_DATA_PEC |
+-	                 I2C_FUNC_SMBUS_HWPEC_CALC
+-	               : 0)
+-#endif
+-	    ;
++	     | (isich4 ? I2C_FUNC_SMBUS_HWPEC_CALC : 0);
+ }
+ 
+ static struct i2c_algorithm smbus_algorithm = {
+@@ -543,7 +518,6 @@ static struct i2c_adapter i801_adapter =
+ 	.owner		= THIS_MODULE,
+ 	.class		= I2C_CLASS_HWMON,
+ 	.algo		= &smbus_algorithm,
+-	.name		= "unset",
+ };
+ 
+ static struct pci_device_id i801_ids[] = {
+@@ -586,6 +560,7 @@ static void __devexit i801_remove(struct
+ }
+ 
+ static struct pci_driver i801_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "i801_smbus",
+ 	.id_table	= i801_ids,
+ 	.probe		= i801_probe,
+diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
+--- a/drivers/i2c/busses/i2c-i810.c
++++ b/drivers/i2c/busses/i2c-i810.c
+@@ -32,6 +32,7 @@
+    i810AB		7123           
+    i810E		7125           
+    i815			1132           
++   i845G		2562
+ */
+ 
+ #include <linux/kernel.h>
+@@ -232,6 +233,7 @@ static void __devexit i810_remove(struct
+ }
+ 
+ static struct pci_driver i810_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "i810_smbus",
+ 	.id_table	= i810_ids,
+ 	.probe		= i810_probe,
+diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
+--- a/drivers/i2c/busses/i2c-ibm_iic.c
++++ b/drivers/i2c/busses/i2c-ibm_iic.c
+@@ -672,13 +672,12 @@ static int __devinit iic_probe(struct oc
+ 		printk(KERN_WARNING"ibm-iic%d: missing additional data!\n",
+ 			ocp->def->index);
+ 
+-	if (!(dev = kmalloc(sizeof(*dev), GFP_KERNEL))){
++	if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) {
+ 		printk(KERN_CRIT "ibm-iic%d: failed to allocate device data\n",
+ 			ocp->def->index);
+ 		return -ENOMEM;
+ 	}
+ 
+-	memset(dev, 0, sizeof(*dev));
+ 	dev->idx = ocp->def->index;
+ 	ocp_set_drvdata(ocp, dev);
+ 	
+diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
+--- a/drivers/i2c/busses/i2c-iop3xx.c
++++ b/drivers/i2c/busses/i2c-iop3xx.c
+@@ -11,7 +11,7 @@
+  *
+  * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
+  *  
+- * And which acknowledged Kyösti Mälkki <kmalkki at cc.hut.fi>,
++ * And which acknowledged Kyösti Mälkki <kmalkki at cc.hut.fi>,
+  * Frodo Looijaard <frodol at dds.nl>, Martin Bailey<mbailey at littlefeet-inc.com>
+  *
+  * Major cleanup by Deepak Saxena <dsaxena at plexity.net>, 01/2005:
+@@ -35,7 +35,7 @@
+ #include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/i2c.h>
+ 
+ #include <asm/io.h>
+@@ -43,7 +43,7 @@
+ #include "i2c-iop3xx.h"
+ 
+ /* global unit counter */
+-static int i2c_id = 0;
++static int i2c_id;
+ 
+ static inline unsigned char 
+ iic_cook_addr(struct i2c_msg *msg) 
+@@ -184,7 +184,7 @@ iop3xx_i2c_wait_event(struct i2c_algo_io
+ 	do {
+ 		interrupted = wait_event_interruptible_timeout (
+ 			iop3xx_adap->waitq,
+-			(done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap)					,flags )),
++			(done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
+ 			1 * HZ;
+ 			);
+ 		if ((rc = iop3xx_i2c_error(sr)) < 0) {
+@@ -440,19 +440,17 @@ iop3xx_i2c_probe(struct device *dev)
+ 	struct i2c_adapter *new_adapter;
+ 	struct i2c_algo_iop3xx_data *adapter_data;
+ 
+-	new_adapter = kmalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
++	new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+ 	if (!new_adapter) {
+ 		ret = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset((void*)new_adapter, 0, sizeof(*new_adapter));
+ 
+-	adapter_data = kmalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
++	adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
+ 	if (!adapter_data) {
+ 		ret = -ENOMEM;
+ 		goto free_adapter;
+ 	}
+-	memset((void*)adapter_data, 0, sizeof(*adapter_data));
+ 
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ 	if (!res) {
+@@ -474,9 +472,10 @@ iop3xx_i2c_probe(struct device *dev)
+ 		goto release_region;
+ 	}
+ 
+-	res = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0, 
++	ret = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0,
+ 				pdev->name, adapter_data);
+-	if (res) {
++
++	if (ret) {
+ 		ret = -EIO;
+ 		goto unmap;
+ 	}
+@@ -525,6 +524,7 @@ out:
+ 
+ 
+ static struct device_driver iop3xx_i2c_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "IOP3xx-I2C",
+ 	.bus		= &platform_bus_type,
+ 	.probe		= iop3xx_i2c_probe,
+diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
+--- a/drivers/i2c/busses/i2c-isa.c
++++ b/drivers/i2c/busses/i2c-isa.c
+@@ -38,6 +38,7 @@
+ #include <linux/errno.h>
+ #include <linux/i2c.h>
+ #include <linux/i2c-isa.h>
++#include <linux/platform_device.h>
+ 
+ static u32 isa_func(struct i2c_adapter *adapter);
+ 
+@@ -92,6 +93,7 @@ int i2c_isa_add_driver(struct i2c_driver
+ 
+ 	/* Add the driver to the list of i2c drivers in the driver core */
+ 	driver->driver.name = driver->name;
++	driver->driver.owner = driver->owner;
+ 	driver->driver.bus = &i2c_bus_type;
+ 	driver->driver.probe = i2c_isa_device_probe;
+ 	driver->driver.remove = i2c_isa_device_remove;
+diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
+--- a/drivers/i2c/busses/i2c-ixp2000.c
++++ b/drivers/i2c/busses/i2c-ixp2000.c
+@@ -28,7 +28,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <linux/i2c.h>
+ #include <linux/i2c-algo-bit.h>
+@@ -36,6 +36,8 @@
+ #include <asm/hardware.h>	/* Pick up IXP2000-specific bits */
+ #include <asm/arch/gpio.h>
+ 
++static struct device_driver ixp2000_i2c_driver;
++
+ static inline int ixp2000_scl_pin(void *data)
+ {
+ 	return ((struct ixp2000_i2c_pins*)data)->scl_pin;
+@@ -104,11 +106,10 @@ static int ixp2000_i2c_probe(struct devi
+ 	struct platform_device *plat_dev = to_platform_device(dev);
+ 	struct ixp2000_i2c_pins *gpio = plat_dev->dev.platform_data;
+ 	struct ixp2000_i2c_data *drv_data = 
+-		kmalloc(sizeof(struct ixp2000_i2c_data), GFP_KERNEL);
++		kzalloc(sizeof(struct ixp2000_i2c_data), GFP_KERNEL);
+ 
+ 	if (!drv_data)
+ 		return -ENOMEM;
+-	memzero(drv_data, sizeof(*drv_data));
+ 	drv_data->gpio_pins = gpio;
+ 
+ 	drv_data->algo_data.data = gpio;
+@@ -121,6 +122,8 @@ static int ixp2000_i2c_probe(struct devi
+ 	drv_data->algo_data.timeout = 100;
+ 
+ 	drv_data->adapter.id = I2C_HW_B_IXP2000,
++	strlcpy(drv_data->adapter.name, ixp2000_i2c_driver.name,
++		I2C_NAME_SIZE);
+ 	drv_data->adapter.algo_data = &drv_data->algo_data,
+ 
+ 	drv_data->adapter.dev.parent = &plat_dev->dev;
+@@ -142,6 +145,7 @@ static int ixp2000_i2c_probe(struct devi
+ }
+ 
+ static struct device_driver ixp2000_i2c_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "IXP2000-I2C",
+ 	.bus		= &platform_bus_type,
+ 	.probe		= ixp2000_i2c_probe,
+diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c
+--- a/drivers/i2c/busses/i2c-ixp4xx.c
++++ b/drivers/i2c/busses/i2c-ixp4xx.c
+@@ -28,13 +28,15 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <linux/i2c.h>
+ #include <linux/i2c-algo-bit.h>
+ 
+ #include <asm/hardware.h>	/* Pick up IXP4xx-specific bits */
+ 
++static struct device_driver ixp4xx_i2c_driver;
++
+ static inline int ixp4xx_scl_pin(void *data)
+ {
+ 	return ((struct ixp4xx_i2c_pins*)data)->scl_pin;
+@@ -105,12 +107,11 @@ static int ixp4xx_i2c_probe(struct devic
+ 	struct platform_device *plat_dev = to_platform_device(dev);
+ 	struct ixp4xx_i2c_pins *gpio = plat_dev->dev.platform_data;
+ 	struct ixp4xx_i2c_data *drv_data = 
+-		kmalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL);
++		kzalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL);
+ 
+ 	if(!drv_data)
+ 		return -ENOMEM;
+ 
+-	memzero(drv_data, sizeof(struct ixp4xx_i2c_data));
+ 	drv_data->gpio_pins = gpio;
+ 
+ 	/*
+@@ -129,6 +130,8 @@ static int ixp4xx_i2c_probe(struct devic
+ 	drv_data->algo_data.timeout = 100;
+ 
+ 	drv_data->adapter.id = I2C_HW_B_IXP4XX;
++	strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.name,
++		I2C_NAME_SIZE);
+ 	drv_data->adapter.algo_data = &drv_data->algo_data;
+ 
+ 	drv_data->adapter.dev.parent = &plat_dev->dev;
+@@ -151,6 +154,7 @@ static int ixp4xx_i2c_probe(struct devic
+ }
+ 
+ static struct device_driver ixp4xx_i2c_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "IXP4XX-I2C",
+ 	.bus		= &platform_bus_type,
+ 	.probe		= ixp4xx_i2c_probe,
+diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
+--- a/drivers/i2c/busses/i2c-keywest.c
++++ b/drivers/i2c/busses/i2c-keywest.c
+@@ -535,13 +535,12 @@ create_iface(struct device_node *np, str
+ 
+ 	tsize = sizeof(struct keywest_iface) +
+ 		(sizeof(struct keywest_chan) + 4) * nchan;
+-	iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL);
++	iface = kzalloc(tsize, GFP_KERNEL);
+ 	if (iface == NULL) {
+ 		printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n");
+ 		pmac_low_i2c_unlock(np);
+ 		return -ENOMEM;
+ 	}
+-	memset(iface, 0, tsize);
+ 	spin_lock_init(&iface->lock);
+ 	init_completion(&iface->complete);
+ 	iface->node = of_node_get(np);
+@@ -716,6 +715,7 @@ static struct of_device_id i2c_keywest_m
+ 
+ static struct macio_driver i2c_keywest_macio_driver = 
+ {
++	.owner		= THIS_MODULE,
+ 	.name 		= "i2c-keywest",
+ 	.match_table	= i2c_keywest_match,
+ 	.probe		= create_iface_macio,
+@@ -724,6 +724,7 @@ static struct macio_driver i2c_keywest_m
+ 
+ static struct of_platform_driver i2c_keywest_of_platform_driver = 
+ {
++	.owner		= THIS_MODULE,
+ 	.name 		= "i2c-keywest",
+ 	.match_table	= i2c_keywest_match,
+ 	.probe		= create_iface_of_platform,
+diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
+--- a/drivers/i2c/busses/i2c-mpc.c
++++ b/drivers/i2c/busses/i2c-mpc.c
+@@ -19,6 +19,8 @@
+ #include <linux/sched.h>
+ #include <linux/init.h>
+ #include <linux/pci.h>
++#include <linux/platform_device.h>
++
+ #include <asm/io.h>
+ #include <linux/fsl_devices.h>
+ #include <linux/i2c.h>
+@@ -296,10 +298,9 @@ static int fsl_i2c_probe(struct device *
+ 
+ 	pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
+ 
+-	if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
++	if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) {
+ 		return -ENOMEM;
+ 	}
+-	memset(i2c, 0, sizeof(*i2c));
+ 
+ 	i2c->irq = platform_get_irq(pdev, 0);
+ 	i2c->flags = pdata->device_flags;
+@@ -361,6 +362,7 @@ static int fsl_i2c_remove(struct device 
+ 
+ /* Structure for a device driver */
+ static struct device_driver fsl_i2c_driver = {
++	.owner = THIS_MODULE,
+ 	.name = "fsl-i2c",
+ 	.bus = &platform_bus_type,
+ 	.probe = fsl_i2c_probe,
+diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
+--- a/drivers/i2c/busses/i2c-mv64xxx.c
++++ b/drivers/i2c/busses/i2c-mv64xxx.c
+@@ -17,6 +17,8 @@
+ #include <linux/i2c.h>
+ #include <linux/interrupt.h>
+ #include <linux/mv643xx.h>
++#include <linux/platform_device.h>
++
+ #include <asm/io.h>
+ 
+ /* Register defines */
+@@ -500,13 +502,10 @@ mv64xxx_i2c_probe(struct device *dev)
+ 	if ((pd->id != 0) || !pdata)
+ 		return -ENODEV;
+ 
+-	drv_data = kmalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL);
+-
++	drv_data = kzalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL);
+ 	if (!drv_data)
+ 		return -ENOMEM;
+ 
+-	memset(drv_data, 0, sizeof(struct mv64xxx_i2c_data));
+-
+ 	if (mv64xxx_i2c_map_regs(pd, drv_data)) {
+ 		rc = -ENODEV;
+ 		goto exit_kfree;
+@@ -570,6 +569,7 @@ mv64xxx_i2c_remove(struct device *dev)
+ }
+ 
+ static struct device_driver mv64xxx_i2c_driver = {
++	.owner	= THIS_MODULE,
+ 	.name	= MV64XXX_I2C_CTLR_NAME,
+ 	.bus	= &platform_bus_type,
+ 	.probe	= mv64xxx_i2c_probe,
+diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
+--- a/drivers/i2c/busses/i2c-nforce2.c
++++ b/drivers/i2c/busses/i2c-nforce2.c
+@@ -97,6 +97,7 @@ struct nforce2_smbus {
+ #define NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA		0x4a
+ #define NVIDIA_SMB_PRTCL_PEC			0x80
+ 
++static struct pci_driver nforce2_driver;
+ 
+ static s32 nforce2_access(struct i2c_adapter *adap, u16 addr,
+ 		       unsigned short flags, char read_write,
+@@ -113,7 +114,6 @@ static struct i2c_adapter nforce2_adapte
+ 	.owner          = THIS_MODULE,
+ 	.class          = I2C_CLASS_HWMON,
+ 	.algo           = &smbus_algorithm,
+-	.name   	= "unset",
+ };
+ 
+ /* Return -1 on error. See smbus.h for more information */
+@@ -188,13 +188,6 @@ static s32 nforce2_access(struct i2c_ada
+ 			dev_err(&adap->dev, "I2C_SMBUS_BLOCK_PROC_CALL not supported!\n");
+ 			return -1;
+ 
+-		case I2C_SMBUS_WORD_DATA_PEC:
+-		case I2C_SMBUS_BLOCK_DATA_PEC:
+-		case I2C_SMBUS_PROC_CALL_PEC:
+-		case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
+-			dev_err(&adap->dev, "Unexpected software PEC transaction %d\n.", size);
+-			return -1;
+-
+ 		default:
+ 			dev_err(&adap->dev, "Unsupported transaction %d\n", size);
+ 			return -1;
+@@ -285,7 +278,7 @@ static int __devinit nforce2_probe_smb (
+ 	smbus->base = iobase & 0xfffc;
+ 	smbus->size = 8;
+ 
+-	if (!request_region(smbus->base, smbus->size, "nForce2 SMBus")) {
++	if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
+ 		dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
+ 			smbus->base, smbus->base+smbus->size-1, name);
+ 		return -1;
+@@ -313,10 +306,8 @@ static int __devinit nforce2_probe(struc
+ 	int res1, res2;
+ 
+ 	/* we support 2 SMBus adapters */
+-	if (!(smbuses = (void *)kmalloc(2*sizeof(struct nforce2_smbus),
+-				       	GFP_KERNEL)))
++	if (!(smbuses = kzalloc(2*sizeof(struct nforce2_smbus), GFP_KERNEL)))
+ 		return -ENOMEM;
+-	memset (smbuses, 0, 2*sizeof(struct nforce2_smbus));
+ 	pci_set_drvdata(dev, smbuses);
+ 
+ 	/* SMBus adapter 1 */
+@@ -356,6 +347,7 @@ static void __devexit nforce2_remove(str
+ }
+ 
+ static struct pci_driver nforce2_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "nForce2_smbus",
+ 	.id_table	= nforce2_ids,
+ 	.probe		= nforce2_probe,
+diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
+--- a/drivers/i2c/busses/i2c-parport.c
++++ b/drivers/i2c/busses/i2c-parport.c
+@@ -155,12 +155,11 @@ static void i2c_parport_attach (struct p
+ {
+ 	struct i2c_par *adapter;
+ 	
+-	adapter = kmalloc(sizeof(struct i2c_par), GFP_KERNEL);
++	adapter = kzalloc(sizeof(struct i2c_par), GFP_KERNEL);
+ 	if (adapter == NULL) {
+-		printk(KERN_ERR "i2c-parport: Failed to kmalloc\n");
++		printk(KERN_ERR "i2c-parport: Failed to kzalloc\n");
+ 		return;
+ 	}
+-	memset(adapter, 0x00, sizeof(struct i2c_par));
+ 
+ 	pr_debug("i2c-parport: attaching to %s\n", port->name);
+ 	adapter->pdev = parport_register_device(port, "i2c-parport",
+@@ -232,7 +231,7 @@ static void i2c_parport_detach (struct p
+ 	}
+ }
+ 
+-static struct parport_driver i2c_driver = {
++static struct parport_driver i2c_parport_driver = {
+ 	.name	= "i2c-parport",
+ 	.attach	= i2c_parport_attach,
+ 	.detach	= i2c_parport_detach,
+@@ -250,12 +249,12 @@ static int __init i2c_parport_init(void)
+ 		type = 0;
+ 	}
+ 	
+-	return parport_register_driver(&i2c_driver);
++	return parport_register_driver(&i2c_parport_driver);
+ }
+ 
+ static void __exit i2c_parport_exit(void)
+ {
+-	parport_unregister_driver(&i2c_driver);
++	parport_unregister_driver(&i2c_parport_driver);
+ }
+ 
+ MODULE_AUTHOR("Jean Delvare <khali at linux-fr.org>");
+diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
+--- a/drivers/i2c/busses/i2c-piix4.c
++++ b/drivers/i2c/busses/i2c-piix4.c
+@@ -90,13 +90,13 @@ struct sd {
+ 
+ /* If force is set to anything different from 0, we forcibly enable the
+    PIIX4. DANGEROUS! */
+-static int force = 0;
++static int force;
+ module_param (force, int, 0);
+ MODULE_PARM_DESC(force, "Forcibly enable the PIIX4. DANGEROUS!");
+ 
+ /* If force_addr is set to anything different from 0, we forcibly enable
+    the PIIX4 at the given address. VERY DANGEROUS! */
+-static int force_addr = 0;
++static int force_addr;
+ module_param (force_addr, int, 0);
+ MODULE_PARM_DESC(force_addr,
+ 		 "Forcibly enable the PIIX4 at the given address. "
+@@ -104,14 +104,15 @@ MODULE_PARM_DESC(force_addr,
+ 
+ /* If fix_hstcfg is set to anything different from 0, we reset one of the
+    registers to be a valid value. */
+-static int fix_hstcfg = 0;
++static int fix_hstcfg;
+ module_param (fix_hstcfg, int, 0);
+ MODULE_PARM_DESC(fix_hstcfg,
+ 		"Fix config register. Needed on some boards (Force CPCI735).");
+ 
+ static int piix4_transaction(void);
+ 
+-static unsigned short piix4_smba = 0;
++static unsigned short piix4_smba;
++static struct pci_driver piix4_driver;
+ static struct i2c_adapter piix4_adapter;
+ 
+ static struct dmi_system_id __devinitdata piix4_dmi_table[] = {
+@@ -157,7 +158,7 @@ static int __devinit piix4_setup(struct 
+ 		}
+ 	}
+ 
+-	if (!request_region(piix4_smba, SMBIOSIZE, "piix4-smbus")) {
++	if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
+ 		dev_err(&PIIX4_dev->dev, "SMB region 0x%x already in use!\n",
+ 			piix4_smba);
+ 		return -ENODEV;
+@@ -407,7 +408,6 @@ static struct i2c_adapter piix4_adapter 
+ 	.owner		= THIS_MODULE,
+ 	.class		= I2C_CLASS_HWMON,
+ 	.algo		= &smbus_algorithm,
+-	.name		= "unset",
+ };
+ 
+ static struct pci_device_id piix4_ids[] = {
+@@ -462,6 +462,7 @@ static void __devexit piix4_remove(struc
+ }
+ 
+ static struct pci_driver piix4_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "piix4_smbus",
+ 	.id_table	= piix4_ids,
+ 	.probe		= piix4_probe,
+diff --git a/drivers/i2c/busses/i2c-pmac-smu.c b/drivers/i2c/busses/i2c-pmac-smu.c
+--- a/drivers/i2c/busses/i2c-pmac-smu.c
++++ b/drivers/i2c/busses/i2c-pmac-smu.c
+@@ -211,12 +211,11 @@ static int create_iface(struct device_no
+ 	}
+ 	busid = *reg;
+ 
+-	iface = kmalloc(sizeof(struct smu_iface), GFP_KERNEL);
++	iface = kzalloc(sizeof(struct smu_iface), GFP_KERNEL);
+ 	if (iface == NULL) {
+ 		printk(KERN_ERR "i2c-pmac-smu: can't allocate inteface !\n");
+ 		return -ENOMEM;
+ 	}
+-	memset(iface, 0, sizeof(struct smu_iface));
+ 	init_completion(&iface->complete);
+ 	iface->busid = busid;
+ 
+diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
+--- a/drivers/i2c/busses/i2c-prosavage.c
++++ b/drivers/i2c/busses/i2c-prosavage.c
+@@ -83,11 +83,6 @@ struct s_i2c_chip {
+ /*
+  * i2c configuration
+  */
+-#ifndef I2C_HW_B_S3VIA
+-#define I2C_HW_B_S3VIA	0x18	/* S3VIA ProSavage adapter		*/
+-#endif
+-
+-/* delays */
+ #define CYCLE_DELAY	10
+ #define TIMEOUT		(HZ / 2)
+ 
+@@ -241,14 +236,12 @@ static int __devinit prosavage_probe(str
+ 	struct s_i2c_chip *chip;
+ 	struct s_i2c_bus  *bus;
+ 
+-        pci_set_drvdata(dev, kmalloc(sizeof(struct s_i2c_chip), GFP_KERNEL)); 
++	pci_set_drvdata(dev, kzalloc(sizeof(struct s_i2c_chip), GFP_KERNEL));
+ 	chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
+ 	if (chip == NULL) {
+ 		return -ENOMEM;
+ 	}
+ 
+-	memset(chip, 0, sizeof(struct s_i2c_chip));
+-
+ 	base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK;
+ 	len  = dev->resource[0].end - base + 1;
+ 	chip->mmio = ioremap_nocache(base, len);
+@@ -308,6 +301,7 @@ static struct pci_device_id prosavage_pc
+ MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl);
+ 
+ static struct pci_driver prosavage_driver = {
++	.owner		=	THIS_MODULE,
+ 	.name		=	"prosavage_smbus",
+ 	.id_table	=	prosavage_pci_tbl,
+ 	.probe		=	prosavage_probe,
+diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
+--- a/drivers/i2c/busses/i2c-pxa.c
++++ b/drivers/i2c/busses/i2c-pxa.c
+@@ -30,6 +30,7 @@
+ #include <linux/errno.h>
+ #include <linux/interrupt.h>
+ #include <linux/i2c-pxa.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
+--- a/drivers/i2c/busses/i2c-s3c2410.c
++++ b/drivers/i2c/busses/i2c-s3c2410.c
+@@ -33,7 +33,7 @@
+ #include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/err.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+@@ -879,14 +879,12 @@ static int s3c24xx_i2c_remove(struct dev
+ }
+ 
+ #ifdef CONFIG_PM
+-static int s3c24xx_i2c_resume(struct device *dev, u32 level)
++static int s3c24xx_i2c_resume(struct device *dev)
+ {
+ 	struct s3c24xx_i2c *i2c = dev_get_drvdata(dev);
+-	
+-	if (i2c != NULL && level == RESUME_ENABLE) {
+-		dev_dbg(dev, "resume: level %d\n", level);
++
++	if (i2c != NULL)
+ 		s3c24xx_i2c_init(i2c);
+-	}
+ 
+ 	return 0;
+ }
+@@ -898,6 +896,7 @@ static int s3c24xx_i2c_resume(struct dev
+ /* device driver for platform bus bits */
+ 
+ static struct device_driver s3c2410_i2c_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "s3c2410-i2c",
+ 	.bus		= &platform_bus_type,
+ 	.probe		= s3c24xx_i2c_probe,
+@@ -906,6 +905,7 @@ static struct device_driver s3c2410_i2c_
+ };
+ 
+ static struct device_driver s3c2440_i2c_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "s3c2440-i2c",
+ 	.bus		= &platform_bus_type,
+ 	.probe		= s3c24xx_i2c_probe,
+@@ -918,8 +918,11 @@ static int __init i2c_adap_s3c_init(void
+ 	int ret;
+ 
+ 	ret = driver_register(&s3c2410_i2c_driver);
+-	if (ret == 0)
+-		ret = driver_register(&s3c2440_i2c_driver); 
++	if (ret == 0) {
++		ret = driver_register(&s3c2440_i2c_driver);
++		if (ret)
++			driver_unregister(&s3c2410_i2c_driver);
++	}
+ 
+ 	return ret;
+ }
+diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
+--- a/drivers/i2c/busses/i2c-savage4.c
++++ b/drivers/i2c/busses/i2c-savage4.c
+@@ -179,6 +179,7 @@ static void __devexit savage4_remove(str
+ }
+ 
+ static struct pci_driver savage4_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "savage4_smbus",
+ 	.id_table	= savage4_ids,
+ 	.probe		= savage4_probe,
+diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
+--- a/drivers/i2c/busses/i2c-sis5595.c
++++ b/drivers/i2c/busses/i2c-sis5595.c
+@@ -123,11 +123,12 @@ static int blacklist[] = {
+ 
+ /* If force_addr is set to anything different from 0, we forcibly enable
+    the device at the given address. */
+-static u16 force_addr = 0;
++static u16 force_addr;
+ module_param(force_addr, ushort, 0);
+ MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
+ 
+-static unsigned short sis5595_base = 0;
++static struct pci_driver sis5595_driver;
++static unsigned short sis5595_base;
+ 
+ static u8 sis5595_read(u8 reg)
+ {
+@@ -172,7 +173,8 @@ static int sis5595_setup(struct pci_dev 
+ 
+ 	/* NB: We grab just the two SMBus registers here, but this may still
+ 	 * interfere with ACPI :-(  */
+-	if (!request_region(sis5595_base + SMB_INDEX, 2, "sis5595-smbus")) {
++	if (!request_region(sis5595_base + SMB_INDEX, 2,
++			    sis5595_driver.name)) {
+ 		dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
+ 			sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
+ 		return -ENODEV;
+@@ -364,7 +366,6 @@ static struct i2c_algorithm smbus_algori
+ static struct i2c_adapter sis5595_adapter = {
+ 	.owner		= THIS_MODULE,
+ 	.class          = I2C_CLASS_HWMON,
+-	.name		= "unset",
+ 	.algo		= &smbus_algorithm,
+ };
+ 
+@@ -397,6 +398,7 @@ static void __devexit sis5595_remove(str
+ }
+ 
+ static struct pci_driver sis5595_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "sis5595_smbus",
+ 	.id_table	= sis5595_ids,
+ 	.probe		= sis5595_probe,
+diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
+--- a/drivers/i2c/busses/i2c-sis630.c
++++ b/drivers/i2c/busses/i2c-sis630.c
+@@ -92,6 +92,8 @@
+ #define SIS630_PCALL		0x04
+ #define SIS630_BLOCK_DATA	0x05
+ 
++static struct pci_driver sis630_driver;
++
+ /* insmod parameters */
+ static int high_clock;
+ static int force;
+@@ -101,7 +103,7 @@ module_param(force, bool, 0);
+ MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!");
+ 
+ /* acpi base address */
+-static unsigned short acpi_base = 0;
++static unsigned short acpi_base;
+ 
+ /* supported chips */
+ static int supported[] = {
+@@ -432,7 +434,8 @@ static int sis630_setup(struct pci_dev *
+ 	dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base);
+ 
+ 	/* Everything is happy, let's grab the memory and set things up. */
+-	if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, "sis630-smbus")) {
++	if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION,
++			    sis630_driver.name)) {
+ 		dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already "
+ 			"in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA);
+ 		goto exit;
+@@ -455,7 +458,6 @@ static struct i2c_algorithm smbus_algori
+ static struct i2c_adapter sis630_adapter = {
+ 	.owner		= THIS_MODULE,
+ 	.class		= I2C_CLASS_HWMON,
+-	.name		= "unset",
+ 	.algo		= &smbus_algorithm,
+ };
+ 
+@@ -494,6 +496,7 @@ static void __devexit sis630_remove(stru
+ 
+ 
+ static struct pci_driver sis630_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "sis630_smbus",
+ 	.id_table	= sis630_ids,
+ 	.probe		= sis630_probe,
+diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
+--- a/drivers/i2c/busses/i2c-sis96x.c
++++ b/drivers/i2c/busses/i2c-sis96x.c
+@@ -82,8 +82,9 @@
+ #define SIS96x_PROC_CALL  0x04
+ #define SIS96x_BLOCK_DATA 0x05
+ 
++static struct pci_driver sis96x_driver;
+ static struct i2c_adapter sis96x_adapter;
+-static u16 sis96x_smbus_base = 0;
++static u16 sis96x_smbus_base;
+ 
+ static inline u8 sis96x_read(u8 reg)
+ {
+@@ -257,7 +258,6 @@ static struct i2c_adapter sis96x_adapter
+ 	.owner		= THIS_MODULE,
+ 	.class		= I2C_CLASS_HWMON,
+ 	.algo		= &smbus_algorithm,
+-	.name		= "unset",
+ };
+ 
+ static struct pci_device_id sis96x_ids[] = {
+@@ -294,7 +294,8 @@ static int __devinit sis96x_probe(struct
+ 			sis96x_smbus_base);
+ 
+ 	/* Everything is happy, let's grab the memory and set things up. */
+-	if (!request_region(sis96x_smbus_base, SMB_IOSIZE, "sis96x-smbus")) {
++	if (!request_region(sis96x_smbus_base, SMB_IOSIZE,
++			    sis96x_driver.name)) {
+ 		dev_err(&dev->dev, "SMBus registers 0x%04x-0x%04x "
+ 			"already in use!\n", sis96x_smbus_base,
+ 			sis96x_smbus_base + SMB_IOSIZE - 1);
+@@ -328,6 +329,7 @@ static void __devexit sis96x_remove(stru
+ }
+ 
+ static struct pci_driver sis96x_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "sis96x_smbus",
+ 	.id_table	= sis96x_ids,
+ 	.probe		= sis96x_probe,
+diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
+--- a/drivers/i2c/busses/i2c-via.c
++++ b/drivers/i2c/busses/i2c-via.c
+@@ -43,9 +43,9 @@
+ 
+ /* io-region reservation */
+ #define IOSPACE		0x06
+-#define IOTEXT		"via-i2c"
+ 
+-static u16 pm_io_base = 0;
++static struct pci_driver vt586b_driver;
++static u16 pm_io_base;
+ 
+ /*
+    It does not appear from the datasheet that the GPIO pins are
+@@ -130,7 +130,7 @@ static int __devinit vt586b_probe(struct
+ 	pci_read_config_word(dev, base, &pm_io_base);
+ 	pm_io_base &= (0xff << 8);
+ 
+-	if (!request_region(I2C_DIR, IOSPACE, IOTEXT)) {
++	if (!request_region(I2C_DIR, IOSPACE, vt586b_driver.name)) {
+ 		dev_err(&dev->dev, "IO 0x%x-0x%x already in use\n", I2C_DIR, I2C_DIR + IOSPACE);
+ 		return -ENODEV;
+ 	}
+@@ -159,6 +159,7 @@ static void __devexit vt586b_remove(stru
+ 
+ 
+ static struct pci_driver vt586b_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "vt586b_smbus",
+ 	.id_table	= vt586b_ids,
+ 	.probe		= vt586b_probe,
+diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
+--- a/drivers/i2c/busses/i2c-viapro.c
++++ b/drivers/i2c/busses/i2c-viapro.c
+@@ -1,9 +1,10 @@
+ /*
+     i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware
+               monitoring
+-    Copyright (c) 1998 - 2002  Frodo Looijaard <frodol at dds.nl>, 
++    Copyright (c) 1998 - 2002  Frodo Looijaard <frodol at dds.nl>,
+     Philip Edelbrock <phil at netroedge.com>, Kyösti Mälkki <kmalkki at cc.hut.fi>,
+     Mark D. Studebaker <mdsxyz123 at yahoo.com>
++    Copyright (C) 2005  Jean Delvare <khali at linux-fr.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
+@@ -21,15 +22,19 @@
+ */
+ 
+ /*
+-   Supports Via devices:
+-	82C596A/B (0x3050)
+-	82C596B (0x3051)
+-	82C686A/B
+-	8231
+-	8233
+-	8233A (0x3147 and 0x3177)
+-	8235
+-	8237
++   Supports the following VIA south bridges:
++
++   Chip name          PCI ID  REV     I2C block
++   VT82C596A          0x3050             no
++   VT82C596B          0x3051             no
++   VT82C686A          0x3057  0x30       no
++   VT82C686B          0x3057  0x40       yes
++   VT8231             0x8235             no?
++   VT8233             0x3074             yes
++   VT8233A            0x3147             yes?
++   VT8235             0x3177             yes
++   VT8237R            0x3227             yes
++
+    Note: we assume there can only be one device, with one SMBus interface.
+ */
+ 
+@@ -38,7 +43,6 @@
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+ #include <linux/stddef.h>
+-#include <linux/sched.h>
+ #include <linux/ioport.h>
+ #include <linux/i2c.h>
+ #include <linux/init.h>
+@@ -46,48 +50,37 @@
+ 
+ static struct pci_dev *vt596_pdev;
+ 
+-#define SMBBA1	   	 0x90
+-#define SMBBA2     	 0x80
+-#define SMBBA3     	 0xD0
++#define SMBBA1		0x90
++#define SMBBA2		0x80
++#define SMBBA3		0xD0
+ 
+ /* SMBus address offsets */
+ static unsigned short vt596_smba;
+ #define SMBHSTSTS	(vt596_smba + 0)
+-#define SMBHSLVSTS	(vt596_smba + 1)
+ #define SMBHSTCNT	(vt596_smba + 2)
+ #define SMBHSTCMD	(vt596_smba + 3)
+ #define SMBHSTADD	(vt596_smba + 4)
+ #define SMBHSTDAT0	(vt596_smba + 5)
+ #define SMBHSTDAT1	(vt596_smba + 6)
+ #define SMBBLKDAT	(vt596_smba + 7)
+-#define SMBSLVCNT	(vt596_smba + 8)
+-#define SMBSHDWCMD	(vt596_smba + 9)
+-#define SMBSLVEVT	(vt596_smba + 0xA)
+-#define SMBSLVDAT	(vt596_smba + 0xC)
+ 
+ /* PCI Address Constants */
+ 
+ /* SMBus data in configuration space can be found in two places,
+-   We try to select the better one*/
++   We try to select the better one */
+ 
+-static unsigned short smb_cf_hstcfg = 0xD2;
+-
+-#define SMBHSTCFG   (smb_cf_hstcfg)
+-#define SMBSLVC     (smb_cf_hstcfg + 1)
+-#define SMBSHDW1    (smb_cf_hstcfg + 2)
+-#define SMBSHDW2    (smb_cf_hstcfg + 3)
+-#define SMBREV      (smb_cf_hstcfg + 4)
++static unsigned short SMBHSTCFG = 0xD2;
+ 
+ /* Other settings */
+ #define MAX_TIMEOUT	500
+-#define ENABLE_INT9	0
+ 
+ /* VT82C596 constants */
+-#define VT596_QUICK      0x00
+-#define VT596_BYTE       0x04
+-#define VT596_BYTE_DATA  0x08
+-#define VT596_WORD_DATA  0x0C
+-#define VT596_BLOCK_DATA 0x14
++#define VT596_QUICK		0x00
++#define VT596_BYTE		0x04
++#define VT596_BYTE_DATA		0x08
++#define VT596_WORD_DATA		0x0C
++#define VT596_BLOCK_DATA	0x14
++#define VT596_I2C_BLOCK_DATA	0x34
+ 
+ 
+ /* If force is set to anything different from 0, we forcibly enable the
+@@ -105,40 +98,65 @@ MODULE_PARM_DESC(force_addr,
+ 		 "EXTREMELY DANGEROUS!");
+ 
+ 
++static struct pci_driver vt596_driver;
+ static struct i2c_adapter vt596_adapter;
+ 
+-/* Another internally used function */
+-static int vt596_transaction(void)
++#define FEATURE_I2CBLOCK	(1<<0)
++static unsigned int vt596_features;
++
++#ifdef DEBUG
++static void vt596_dump_regs(const char *msg, u8 size)
++{
++	dev_dbg(&vt596_adapter.dev, "%s: STS=%02x CNT=%02x CMD=%02x ADD=%02x "
++		"DAT=%02x,%02x\n", msg, inb_p(SMBHSTSTS), inb_p(SMBHSTCNT),
++		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
++		inb_p(SMBHSTDAT1));
++
++	if (size == VT596_BLOCK_DATA
++	 || size == VT596_I2C_BLOCK_DATA) {
++		int i;
++
++		dev_dbg(&vt596_adapter.dev, "BLK=");
++		for (i = 0; i < I2C_SMBUS_BLOCK_MAX / 2; i++)
++			printk("%02x,", inb_p(SMBBLKDAT));
++		printk("\n");
++		dev_dbg(&vt596_adapter.dev, "    ");
++		for (; i < I2C_SMBUS_BLOCK_MAX - 1; i++)
++			printk("%02x,", inb_p(SMBBLKDAT));
++		printk("%02x\n", inb_p(SMBBLKDAT));
++	}
++}
++#else
++static inline void vt596_dump_regs(const char *msg, u8 size) { }
++#endif
++
++/* Return -1 on error, 0 on success */
++static int vt596_transaction(u8 size)
+ {
+ 	int temp;
+ 	int result = 0;
+ 	int timeout = 0;
+ 
+-	dev_dbg(&vt596_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
+-		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), 
+-		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), 
+-		inb_p(SMBHSTDAT1));
++	vt596_dump_regs("Transaction (pre)", size);
+ 
+ 	/* Make sure the SMBus host is ready to start transmitting */
+ 	if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
+ 		dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
+-				"Resetting...\n", temp);
+-		
++			"Resetting... ", temp);
++
+ 		outb_p(temp, SMBHSTSTS);
+ 		if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
+-			dev_dbg(&vt596_adapter.dev, "Failed! (0x%02x)\n", temp);
+-			
++			printk("Failed! (0x%02x)\n", temp);
+ 			return -1;
+ 		} else {
+-			dev_dbg(&vt596_adapter.dev, "Successfull!\n");
++			printk("Successful!\n");
+ 		}
+ 	}
+ 
+-	/* start the transaction by setting bit 6 */
+-	outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
++	/* Start the transaction by setting bit 6 */
++	outb_p(0x40 | (size & 0x3C), SMBHSTCNT);
+ 
+-	/* We will always wait for a fraction of a second! 
+-	   I don't know if VIA needs this, Intel did  */
++	/* We will always wait for a fraction of a second */
+ 	do {
+ 		msleep(1);
+ 		temp = inb_p(SMBHSTSTS);
+@@ -147,77 +165,61 @@ static int vt596_transaction(void)
+ 	/* If the SMBus is still busy, we give up */
+ 	if (timeout >= MAX_TIMEOUT) {
+ 		result = -1;
+-		dev_dbg(&vt596_adapter.dev, "SMBus Timeout!\n");
++		dev_err(&vt596_adapter.dev, "SMBus timeout!\n");
+ 	}
+ 
+ 	if (temp & 0x10) {
+ 		result = -1;
+-		dev_dbg(&vt596_adapter.dev, "Error: Failed bus transaction\n");
++		dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
++			inb_p(SMBHSTCNT) & 0x3C);
+ 	}
+ 
+ 	if (temp & 0x08) {
+ 		result = -1;
+-		dev_info(&vt596_adapter.dev, "Bus collision! SMBus may be "
+-			"locked until next hard\nreset. (sorry!)\n");
+-		/* Clock stops and slave is stuck in mid-transmission */
++		dev_err(&vt596_adapter.dev, "SMBus collision!\n");
+ 	}
+ 
+ 	if (temp & 0x04) {
+ 		result = -1;
+-		dev_dbg(&vt596_adapter.dev, "Error: no response!\n");
++		/* Quick commands are used to probe for chips, so
++		   errors are expected, and we don't want to frighten the
++		   user. */
++		if ((inb_p(SMBHSTCNT) & 0x3C) != VT596_QUICK)
++			dev_err(&vt596_adapter.dev, "Transaction error!\n");
+ 	}
+ 
+-	if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
++	/* Resetting status register */
++	if (temp & 0x1F)
+ 		outb_p(temp, SMBHSTSTS);
+-		if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
+-			dev_warn(&vt596_adapter.dev, "Failed reset at end "
+-				 "of transaction (%02x)\n", temp);
+-		}
+-	}
+ 
+-	dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
+-		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
+-		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), 
+-		inb_p(SMBHSTDAT1));
+-	
++	vt596_dump_regs("Transaction (post)", size);
++
+ 	return result;
+ }
+ 
+-/* Return -1 on error. */
++/* Return -1 on error, 0 on success */
+ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
+-		unsigned short flags,  char read_write, u8 command,
+-		int size,  union i2c_smbus_data *data)
++		unsigned short flags, char read_write, u8 command,
++		int size, union i2c_smbus_data *data)
+ {
+-	int i, len;
++	int i;
+ 
+ 	switch (size) {
+-	case I2C_SMBUS_PROC_CALL:
+-		dev_info(&vt596_adapter.dev,
+-			 "I2C_SMBUS_PROC_CALL not supported!\n");
+-		return -1;
+ 	case I2C_SMBUS_QUICK:
+-		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+-		       SMBHSTADD);
+ 		size = VT596_QUICK;
+ 		break;
+ 	case I2C_SMBUS_BYTE:
+-		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+-		       SMBHSTADD);
+ 		if (read_write == I2C_SMBUS_WRITE)
+ 			outb_p(command, SMBHSTCMD);
+ 		size = VT596_BYTE;
+ 		break;
+ 	case I2C_SMBUS_BYTE_DATA:
+-		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+-		       SMBHSTADD);
+ 		outb_p(command, SMBHSTCMD);
+ 		if (read_write == I2C_SMBUS_WRITE)
+ 			outb_p(data->byte, SMBHSTDAT0);
+ 		size = VT596_BYTE_DATA;
+ 		break;
+ 	case I2C_SMBUS_WORD_DATA:
+-		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+-		       SMBHSTADD);
+ 		outb_p(command, SMBHSTCMD);
+ 		if (read_write == I2C_SMBUS_WRITE) {
+ 			outb_p(data->word & 0xff, SMBHSTDAT0);
+@@ -225,28 +227,33 @@ static s32 vt596_access(struct i2c_adapt
+ 		}
+ 		size = VT596_WORD_DATA;
+ 		break;
++	case I2C_SMBUS_I2C_BLOCK_DATA:
++		if (!(vt596_features & FEATURE_I2CBLOCK))
++			goto exit_unsupported;
++		if (read_write == I2C_SMBUS_READ)
++			outb_p(I2C_SMBUS_BLOCK_MAX, SMBHSTDAT0);
++		/* Fall through */
+ 	case I2C_SMBUS_BLOCK_DATA:
+-		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+-		       SMBHSTADD);
+ 		outb_p(command, SMBHSTCMD);
+ 		if (read_write == I2C_SMBUS_WRITE) {
+-			len = data->block[0];
+-			if (len < 0)
+-				len = 0;
++			u8 len = data->block[0];
+ 			if (len > I2C_SMBUS_BLOCK_MAX)
+ 				len = I2C_SMBUS_BLOCK_MAX;
+ 			outb_p(len, SMBHSTDAT0);
+-			i = inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
++			inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
+ 			for (i = 1; i <= len; i++)
+ 				outb_p(data->block[i], SMBBLKDAT);
+ 		}
+-		size = VT596_BLOCK_DATA;
++		size = (size == I2C_SMBUS_I2C_BLOCK_DATA) ?
++		       VT596_I2C_BLOCK_DATA : VT596_BLOCK_DATA;
+ 		break;
++	default:
++		goto exit_unsupported;
+ 	}
+ 
+-	outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT);
++	outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD);
+ 
+-	if (vt596_transaction()) /* Error in transaction */
++	if (vt596_transaction(size)) /* Error in transaction */
+ 		return -1;
+ 
+ 	if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK))
+@@ -254,35 +261,39 @@ static s32 vt596_access(struct i2c_adapt
+ 
+ 	switch (size) {
+ 	case VT596_BYTE:
+-		/* Where is the result put? I assume here it is in
+-		 * SMBHSTDAT0 but it might just as well be in the
+-		 * SMBHSTCMD. No clue in the docs 
+-		 */
+-		data->byte = inb_p(SMBHSTDAT0);
+-		break;
+ 	case VT596_BYTE_DATA:
+ 		data->byte = inb_p(SMBHSTDAT0);
+ 		break;
+ 	case VT596_WORD_DATA:
+ 		data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
+ 		break;
++	case VT596_I2C_BLOCK_DATA:
+ 	case VT596_BLOCK_DATA:
+ 		data->block[0] = inb_p(SMBHSTDAT0);
+ 		if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
+ 			data->block[0] = I2C_SMBUS_BLOCK_MAX;
+-		i = inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
++		inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
+ 		for (i = 1; i <= data->block[0]; i++)
+ 			data->block[i] = inb_p(SMBBLKDAT);
+ 		break;
+ 	}
+ 	return 0;
++
++exit_unsupported:
++	dev_warn(&vt596_adapter.dev, "Unsupported command invoked! (0x%02x)\n",
++		 size);
++	return -1;
+ }
+ 
+ static u32 vt596_func(struct i2c_adapter *adapter)
+ {
+-	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
++	u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+ 	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+ 	    I2C_FUNC_SMBUS_BLOCK_DATA;
++
++	if (vt596_features & FEATURE_I2CBLOCK)
++		func |= I2C_FUNC_SMBUS_I2C_BLOCK;
++	return func;
+ }
+ 
+ static struct i2c_algorithm smbus_algorithm = {
+@@ -294,7 +305,6 @@ static struct i2c_adapter vt596_adapter 
+ 	.owner		= THIS_MODULE,
+ 	.class		= I2C_CLASS_HWMON,
+ 	.algo		= &smbus_algorithm,
+-	.name		= "unset",
+ };
+ 
+ static int __devinit vt596_probe(struct pci_dev *pdev,
+@@ -302,7 +312,7 @@ static int __devinit vt596_probe(struct 
+ {
+ 	unsigned char temp;
+ 	int error = -ENODEV;
+-	
++
+ 	/* Determine the address of the SMBus areas */
+ 	if (force_addr) {
+ 		vt596_smba = force_addr & 0xfff0;
+@@ -311,12 +321,12 @@ static int __devinit vt596_probe(struct 
+ 	}
+ 
+ 	if ((pci_read_config_word(pdev, id->driver_data, &vt596_smba)) ||
+-	    !(vt596_smba & 0x1)) {
++	    !(vt596_smba & 0x0001)) {
+ 		/* try 2nd address and config reg. for 596 */
+ 		if (id->device == PCI_DEVICE_ID_VIA_82C596_3 &&
+ 		    !pci_read_config_word(pdev, SMBBA2, &vt596_smba) &&
+-		    (vt596_smba & 0x1)) {
+-			smb_cf_hstcfg = 0x84;
++		    (vt596_smba & 0x0001)) {
++			SMBHSTCFG = 0x84;
+ 		} else {
+ 			/* no matches at all */
+ 			dev_err(&pdev->dev, "Cannot configure "
+@@ -333,10 +343,10 @@ static int __devinit vt596_probe(struct 
+ 		return -ENODEV;
+ 	}
+ 
+- found:
+-	if (!request_region(vt596_smba, 8, "viapro-smbus")) {
++found:
++	if (!request_region(vt596_smba, 8, vt596_driver.name)) {
+ 		dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
+-		        vt596_smba);
++			vt596_smba);
+ 		return -ENODEV;
+ 	}
+ 
+@@ -348,16 +358,16 @@ static int __devinit vt596_probe(struct 
+ 		pci_write_config_word(pdev, id->driver_data, vt596_smba);
+ 		pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
+ 		dev_warn(&pdev->dev, "WARNING: SMBus interface set to new "
+-		     "address 0x%04x!\n", vt596_smba);
+-	} else if ((temp & 1) == 0) {
++			 "address 0x%04x!\n", vt596_smba);
++	} else if (!(temp & 0x01)) {
+ 		if (force) {
+-			/* NOTE: This assumes I/O space and other allocations 
+-			 * WERE done by the Bios!  Don't complain if your 
+-			 * hardware does weird things after enabling this. 
+-			 * :') Check for Bios updates before resorting to 
++			/* NOTE: This assumes I/O space and other allocations
++			 * WERE done by the Bios!  Don't complain if your
++			 * hardware does weird things after enabling this.
++			 * :') Check for Bios updates before resorting to
+ 			 * this.
+ 			 */
+-			pci_write_config_byte(pdev, SMBHSTCFG, temp | 1);
++			pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
+ 			dev_info(&pdev->dev, "Enabling SMBus device\n");
+ 		} else {
+ 			dev_err(&pdev->dev, "SMBUS: Error: Host SMBus "
+@@ -367,22 +377,28 @@ static int __devinit vt596_probe(struct 
+ 		}
+ 	}
+ 
+-	if ((temp & 0x0E) == 8)
+-		dev_dbg(&pdev->dev, "using Interrupt 9 for SMBus.\n");
+-	else if ((temp & 0x0E) == 0)
+-		dev_dbg(&pdev->dev, "using Interrupt SMI# for SMBus.\n");
+-	else
+-		dev_dbg(&pdev->dev, "Illegal Interrupt configuration "
+-			"(or code out of date)!\n");
+-
+-	pci_read_config_byte(pdev, SMBREV, &temp);
+-	dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp);
+ 	dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba);
+ 
++	switch (pdev->device) {
++	case PCI_DEVICE_ID_VIA_8237:
++	case PCI_DEVICE_ID_VIA_8235:
++	case PCI_DEVICE_ID_VIA_8233A:
++	case PCI_DEVICE_ID_VIA_8233_0:
++		vt596_features |= FEATURE_I2CBLOCK;
++		break;
++	case PCI_DEVICE_ID_VIA_82C686_4:
++		/* The VT82C686B (rev 0x40) does support I2C block
++		   transactions, but the VT82C686A (rev 0x30) doesn't */
++		if (!pci_read_config_byte(pdev, PCI_REVISION_ID, &temp)
++		 && temp >= 0x40)
++			vt596_features |= FEATURE_I2CBLOCK;
++		break;
++	}
++
+ 	vt596_adapter.dev.parent = &pdev->dev;
+ 	snprintf(vt596_adapter.name, I2C_NAME_SIZE,
+-			"SMBus Via Pro adapter at %04x", vt596_smba);
+-	
++		 "SMBus Via Pro adapter at %04x", vt596_smba);
++
+ 	vt596_pdev = pci_dev_get(pdev);
+ 	if (i2c_add_adapter(&vt596_adapter)) {
+ 		pci_dev_put(vt596_pdev);
+@@ -395,7 +411,7 @@ static int __devinit vt596_probe(struct 
+ 	 */
+ 	return -ENODEV;
+ 
+- release_region:
++release_region:
+ 	release_region(vt596_smba, 8);
+ 	return error;
+ }
+@@ -420,9 +436,10 @@ static struct pci_device_id vt596_ids[] 
+ 	{ 0, }
+ };
+ 
+-MODULE_DEVICE_TABLE (pci, vt596_ids);
++MODULE_DEVICE_TABLE(pci, vt596_ids);
+ 
+ static struct pci_driver vt596_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "vt596_smbus",
+ 	.id_table	= vt596_ids,
+ 	.probe		= vt596_probe,
+diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
+--- a/drivers/i2c/busses/i2c-voodoo3.c
++++ b/drivers/i2c/busses/i2c-voodoo3.c
+@@ -225,6 +225,7 @@ static void __devexit voodoo3_remove(str
+ }
+ 
+ static struct pci_driver voodoo3_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "voodoo3_smbus",
+ 	.id_table	= voodoo3_ids,
+ 	.probe		= voodoo3_probe,
+diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
+--- a/drivers/i2c/busses/scx200_acb.c
++++ b/drivers/i2c/busses/scx200_acb.c
+@@ -442,14 +442,13 @@ static int  __init scx200_acb_create(int
+ 	int rc = 0;
+ 	char description[64];
+ 
+-	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
++	iface = kzalloc(sizeof(*iface), GFP_KERNEL);
+ 	if (!iface) {
+ 		printk(KERN_ERR NAME ": can't allocate memory\n");
+ 		rc = -ENOMEM;
+ 		goto errout;
+ 	}
+ 
+-	memset(iface, 0, sizeof(*iface));
+ 	adapter = &iface->adapter;
+ 	i2c_set_adapdata(adapter, iface);
+ 	snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
+diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
+--- a/drivers/i2c/chips/Kconfig
++++ b/drivers/i2c/chips/Kconfig
+@@ -126,4 +126,13 @@ config SENSORS_MAX6875
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called max6875.
+ 
++config RTC_X1205_I2C
++	tristate "Xicor X1205 RTC chip"
++	depends on I2C && EXPERIMENTAL
++	help
++	  If you say yes here you get support for the Xicor X1205 RTC chip.
++
++	  This driver can also be built as a module. If so, the module
++	  will be called x1205.
++
+ endmenu
+diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
+--- a/drivers/i2c/chips/Makefile
++++ b/drivers/i2c/chips/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591
+ obj-$(CONFIG_SENSORS_RTC8564)	+= rtc8564.o
+ obj-$(CONFIG_ISP1301_OMAP)	+= isp1301_omap.o
+ obj-$(CONFIG_TPS65010)		+= tps65010.o
++obj-$(CONFIG_RTC_X1205_I2C)	+= x1205.o
+ 
+ ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
+ EXTRA_CFLAGS += -DDEBUG
+diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
+--- a/drivers/i2c/chips/ds1337.c
++++ b/drivers/i2c/chips/ds1337.c
+@@ -243,11 +243,10 @@ static int ds1337_detect(struct i2c_adap
+ 				     I2C_FUNC_I2C))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct ds1337_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct ds1337_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct ds1337_data));
+ 	INIT_LIST_HEAD(&data->list);
+ 
+ 	/* The common I2C client data is placed right before the
+diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c
+--- a/drivers/i2c/chips/ds1374.c
++++ b/drivers/i2c/chips/ds1374.c
+@@ -167,7 +167,8 @@ static void ds1374_set_tlet(ulong arg)
+ 
+ static ulong new_time;
+ 
+-DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, (ulong) & new_time);
++static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet,
++				(ulong) & new_time);
+ 
+ int ds1374_set_rtc_time(ulong nowtime)
+ {
+@@ -193,13 +194,11 @@ static int ds1374_probe(struct i2c_adapt
+ 	struct i2c_client *client;
+ 	int rc;
+ 
+-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ 	if (!client)
+ 		return -ENOMEM;
+ 
+-	memset(client, 0, sizeof(struct i2c_client));
+ 	strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE);
+-	client->flags = I2C_DF_NOTIFY;
+ 	client->addr = addr;
+ 	client->adapter = adap;
+ 	client->driver = &ds1374_driver;
+diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
+--- a/drivers/i2c/chips/eeprom.c
++++ b/drivers/i2c/chips/eeprom.c
+@@ -88,8 +88,8 @@ static void eeprom_update_client(struct 
+ 		dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice);
+ 
+ 		if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+-			for (i = slice << 5; i < (slice + 1) << 5; i += I2C_SMBUS_I2C_BLOCK_MAX)
+-				if (i2c_smbus_read_i2c_block_data(client, i, data->data + i) != I2C_SMBUS_I2C_BLOCK_MAX)
++			for (i = slice << 5; i < (slice + 1) << 5; i += I2C_SMBUS_BLOCK_MAX)
++				if (i2c_smbus_read_i2c_block_data(client, i, data->data + i) != I2C_SMBUS_BLOCK_MAX)
+ 					goto exit;
+ 		} else {
+ 			if (i2c_smbus_write_byte(client, slice << 5)) {
+@@ -155,7 +155,7 @@ static int eeprom_attach_adapter(struct 
+ }
+ 
+ /* This function is called by i2c_probe */
+-int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
++static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
+ {
+ 	struct i2c_client *new_client;
+ 	struct eeprom_data *data;
+@@ -171,11 +171,10 @@ int eeprom_detect(struct i2c_adapter *ad
+ 					    | I2C_FUNC_SMBUS_BYTE))
+ 		goto exit;
+ 
+-	if (!(data = kmalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct eeprom_data));
+ 
+ 	new_client = &data->client;
+ 	memset(data->data, 0xff, EEPROM_SIZE);
+diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
+--- a/drivers/i2c/chips/isp1301_omap.c
++++ b/drivers/i2c/chips/isp1301_omap.c
+@@ -27,7 +27,7 @@
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/usb_ch9.h>
+ #include <linux/usb_gadget.h>
+ #include <linux/usb.h>
+@@ -888,6 +888,7 @@ static int otg_remove(struct device *dev
+ }
+ 
+ struct device_driver omap_otg_driver = {
++	.owner		= THIS_MODULE,
+ 	.name		= "omap_otg",
+ 	.bus		= &platform_bus_type,
+ 	.probe		= otg_probe,
+diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
+--- a/drivers/i2c/chips/m41t00.c
++++ b/drivers/i2c/chips/m41t00.c
+@@ -174,13 +174,11 @@ m41t00_probe(struct i2c_adapter *adap, i
+ 	struct i2c_client *client;
+ 	int rc;
+ 
+-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ 	if (!client)
+ 		return -ENOMEM;
+ 
+-	memset(client, 0, sizeof(struct i2c_client));
+ 	strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE);
+-	client->flags = I2C_DF_NOTIFY;
+ 	client->addr = addr;
+ 	client->adapter = adap;
+ 	client->driver = &m41t00_driver;
+diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c
+--- a/drivers/i2c/chips/max6875.c
++++ b/drivers/i2c/chips/max6875.c
+@@ -179,16 +179,14 @@ static int max6875_detect(struct i2c_ada
+ 	if (address & 1)
+ 		return 0;
+ 
+-	if (!(data = kmalloc(sizeof(struct max6875_data), GFP_KERNEL)))
++	if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
+ 		return -ENOMEM;
+-	memset(data, 0, sizeof(struct max6875_data));
+ 
+ 	/* A fake client is created on the odd address */
+-	if (!(fake_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
++	if (!(fake_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit_kfree1;
+ 	}
+-	memset(fake_client, 0, sizeof(struct i2c_client));
+ 
+ 	/* Init real i2c_client */
+ 	real_client = &data->client;
+diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c
+--- a/drivers/i2c/chips/pca9539.c
++++ b/drivers/i2c/chips/pca9539.c
+@@ -122,11 +122,10 @@ static int pca9539_detect(struct i2c_ada
+ 
+ 	/* OK. For now, we presume we have a valid client. We now create the
+ 	   client structure, even though we cannot fill it completely yet. */
+-	if (!(data = kmalloc(sizeof(struct pca9539_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct pca9539_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct pca9539_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c
+--- a/drivers/i2c/chips/pcf8574.c
++++ b/drivers/i2c/chips/pcf8574.c
+@@ -115,7 +115,7 @@ static int pcf8574_attach_adapter(struct
+ }
+ 
+ /* This function is called by i2c_probe */
+-int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
++static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
+ {
+ 	struct i2c_client *new_client;
+ 	struct pcf8574_data *data;
+@@ -127,11 +127,10 @@ int pcf8574_detect(struct i2c_adapter *a
+ 
+ 	/* OK. For now, we presume we have a valid client. We now create the
+ 	   client structure, even though we cannot fill it completely yet. */
+-	if (!(data = kmalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct pcf8574_data));
+ 
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
+--- a/drivers/i2c/chips/pcf8591.c
++++ b/drivers/i2c/chips/pcf8591.c
+@@ -166,7 +166,7 @@ static int pcf8591_attach_adapter(struct
+ }
+ 
+ /* This function is called by i2c_probe */
+-int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
++static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
+ {
+ 	struct i2c_client *new_client;
+ 	struct pcf8591_data *data;
+@@ -178,11 +178,10 @@ int pcf8591_detect(struct i2c_adapter *a
+ 
+ 	/* OK. For now, we presume we have a valid client. We now create the
+ 	   client structure, even though we cannot fill it completely yet. */
+-	if (!(data = kmalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
++	if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
+ 		err = -ENOMEM;
+ 		goto exit;
+ 	}
+-	memset(data, 0, sizeof(struct pcf8591_data));
+ 	
+ 	new_client = &data->client;
+ 	i2c_set_clientdata(new_client, data);
+diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c
+--- a/drivers/i2c/chips/rtc8564.c
++++ b/drivers/i2c/chips/rtc8564.c
+@@ -148,17 +148,16 @@ static int rtc8564_attach(struct i2c_ada
+ 		{addr, I2C_M_RD, 2, data}
+ 	};
+ 
+-	d = kmalloc(sizeof(struct rtc8564_data), GFP_KERNEL);
++	d = kzalloc(sizeof(struct rtc8564_data), GFP_KERNEL);
+ 	if (!d) {
+ 		ret = -ENOMEM;
+ 		goto done;
+ 	}
+-	memset(d, 0, sizeof(struct rtc8564_data));
+ 	new_client = &d->client;
+ 
+ 	strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
+ 	i2c_set_clientdata(new_client, d);
+-	new_client->flags = I2C_CLIENT_ALLOW_USE | I2C_DF_NOTIFY;
++	new_client->flags = I2C_CLIENT_ALLOW_USE;
+ 	new_client->addr = addr;
+ 	new_client->adapter = adap;
+ 	new_client->driver = &rtc8564_driver;
+diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
+--- a/drivers/i2c/chips/tps65010.c
++++ b/drivers/i2c/chips/tps65010.c
+@@ -500,11 +500,10 @@ tps65010_probe(struct i2c_adapter *bus, 
+ 		return 0;
+ 	}
+ 
+-	tps = kmalloc(sizeof *tps, GFP_KERNEL);
++	tps = kzalloc(sizeof *tps, GFP_KERNEL);
+ 	if (!tps)
+ 		return 0;
+ 
+-	memset(tps, 0, sizeof *tps);
+ 	init_MUTEX(&tps->lock);
+ 	INIT_WORK(&tps->work, tps65010_work, tps);
+ 	tps->irq = -1;
+diff --git a/drivers/i2c/chips/x1205.c b/drivers/i2c/chips/x1205.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/i2c/chips/x1205.c
+@@ -0,0 +1,698 @@
++/*
++ *  x1205.c - An i2c driver for the Xicor X1205 RTC
++ *  Copyright 2004 Karen Spearel
++ *  Copyright 2005 Alessandro Zummo
++ *
++ *  please send all reports to:
++ *	kas11 at tampabay dot rr dot com
++ *      a dot zummo at towertech dot it
++ *
++ *  based on the other drivers in this same directory.
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the 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/slab.h>
++#include <linux/i2c.h>
++#include <linux/string.h>
++#include <linux/bcd.h>
++#include <linux/rtc.h>
++#include <linux/list.h>
++
++#include <linux/x1205.h>
++
++#define DRV_VERSION "0.9.9"
++
++/* Addresses to scan: none. This chip is located at
++ * 0x6f and uses a two bytes register addressing.
++ * Two bytes need to be written to read a single register,
++ * while most other chips just require one and take the second
++ * one as the data to be written. To prevent corrupting
++ * unknown chips, the user must explicitely set the probe parameter.
++ */
++
++static unsigned short normal_i2c[] = { I2C_CLIENT_END };
++
++/* Insmod parameters */
++I2C_CLIENT_INSMOD;
++I2C_CLIENT_MODULE_PARM(hctosys,
++	"Set the system time from the hardware clock upon initialization");
++
++/* offsets into CCR area */
++
++#define CCR_SEC			0
++#define CCR_MIN			1
++#define CCR_HOUR		2
++#define CCR_MDAY		3
++#define CCR_MONTH		4
++#define CCR_YEAR		5
++#define CCR_WDAY		6
++#define CCR_Y2K			7
++
++#define X1205_REG_SR		0x3F	/* status register */
++#define X1205_REG_Y2K		0x37
++#define X1205_REG_DW		0x36
++#define X1205_REG_YR		0x35
++#define X1205_REG_MO		0x34
++#define X1205_REG_DT		0x33
++#define X1205_REG_HR		0x32
++#define X1205_REG_MN		0x31
++#define X1205_REG_SC		0x30
++#define X1205_REG_DTR		0x13
++#define X1205_REG_ATR		0x12
++#define X1205_REG_INT		0x11
++#define X1205_REG_0		0x10
++#define X1205_REG_Y2K1		0x0F
++#define X1205_REG_DWA1		0x0E
++#define X1205_REG_YRA1		0x0D
++#define X1205_REG_MOA1		0x0C
++#define X1205_REG_DTA1		0x0B
++#define X1205_REG_HRA1		0x0A
++#define X1205_REG_MNA1		0x09
++#define X1205_REG_SCA1		0x08
++#define X1205_REG_Y2K0		0x07
++#define X1205_REG_DWA0		0x06
++#define X1205_REG_YRA0		0x05
++#define X1205_REG_MOA0		0x04
++#define X1205_REG_DTA0		0x03
++#define X1205_REG_HRA0		0x02
++#define X1205_REG_MNA0		0x01
++#define X1205_REG_SCA0		0x00
++
++#define X1205_CCR_BASE		0x30	/* Base address of CCR */
++#define X1205_ALM0_BASE		0x00	/* Base address of ALARM0 */
++
++#define X1205_SR_RTCF		0x01	/* Clock failure */
++#define X1205_SR_WEL		0x02	/* Write Enable Latch */
++#define X1205_SR_RWEL		0x04	/* Register Write Enable */
++
++#define X1205_DTR_DTR0		0x01
++#define X1205_DTR_DTR1		0x02
++#define X1205_DTR_DTR2		0x04
++
++#define X1205_HR_MIL		0x80	/* Set in ccr.hour for 24 hr mode */
++
++/* Prototypes */
++static int x1205_attach(struct i2c_adapter *adapter);
++static int x1205_detach(struct i2c_client *client);
++static int x1205_probe(struct i2c_adapter *adapter, int address, int kind);
++static int x1205_command(struct i2c_client *client, unsigned int cmd,
++	void *arg);
++
++static struct i2c_driver x1205_driver = {
++	.owner		= THIS_MODULE,
++	.name		= "x1205",
++	.flags		= I2C_DF_NOTIFY,
++	.attach_adapter = &x1205_attach,
++	.detach_client	= &x1205_detach,
++};
++
++struct x1205_data {
++	struct i2c_client client;
++	struct list_head list;
++	unsigned int epoch;
++};
++
++static const unsigned char days_in_mo[] =
++	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
++
++static LIST_HEAD(x1205_clients);
++
++/* Workaround until the I2C subsytem will allow to send
++ * commands to a specific client. This function will send the command
++ * to the first client.
++ */
++int x1205_do_command(unsigned int cmd, void *arg)
++{
++	struct list_head *walk;
++	struct list_head *tmp;
++	struct x1205_data *data;
++
++	list_for_each_safe(walk, tmp, &x1205_clients) {
++		data = list_entry(walk, struct x1205_data, list);
++		return x1205_command(&data->client, cmd, arg);
++	}
++
++	return -ENODEV;
++}
++
++#define is_leap(year) \
++	((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
++
++/* make sure the rtc_time values are in bounds */
++static int x1205_validate_tm(struct rtc_time *tm)
++{
++	int year = tm->tm_year + 1900;
++
++	if ((tm->tm_year < 70) || (tm->tm_year > 255))
++		return -EINVAL;
++
++	if ((tm->tm_mon > 11) || (tm->tm_mday == 0))
++		return -EINVAL;
++
++	if (tm->tm_mday > days_in_mo[tm->tm_mon]
++		+ ((tm->tm_mon == 1) && is_leap(year)))
++		return -EINVAL;
++
++	if ((tm->tm_hour >= 24) || (tm->tm_min >= 60) || (tm->tm_sec >= 60))
++		return -EINVAL;
++
++	return 0;
++}
++
++/*
++ * In the routines that deal directly with the x1205 hardware, we use
++ * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
++ * Epoch is initialized as 2000. Time is set to UTC.
++ */
++static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
++				u8 reg_base)
++{
++	unsigned char dt_addr[2] = { 0, reg_base };
++	static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
++
++	unsigned char buf[8], sr;
++
++	struct i2c_msg msgs[] = {
++		{ client->addr, 0, 2, sr_addr },	/* setup read ptr */
++		{ client->addr, I2C_M_RD, 1, &sr }, 	/* read status */
++		{ client->addr, 0, 2, dt_addr },	/* setup read ptr */
++		{ client->addr, I2C_M_RD, 8, buf },	/* read date */
++	};
++
++	struct x1205_data *data = i2c_get_clientdata(client);
++
++	/* read status register */
++	if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
++		dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
++		return -EIO;
++	}
++
++	/* check for battery failure */
++	if (sr & X1205_SR_RTCF) {
++		dev_warn(&client->dev,
++			"Clock had a power failure, you must set the date.\n");
++		return -EINVAL;
++	}
++
++	/* read date registers */
++	if ((i2c_transfer(client->adapter, &msgs[2], 2)) != 2) {
++		dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
++		return -EIO;
++	}
++
++	dev_dbg(&client->dev,
++		"%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
++		"mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
++		__FUNCTION__,
++		buf[0], buf[1], buf[2], buf[3],
++		buf[4], buf[5], buf[6], buf[7]);
++
++	tm->tm_sec = BCD2BIN(buf[CCR_SEC]);
++	tm->tm_min = BCD2BIN(buf[CCR_MIN]);
++	tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
++	tm->tm_mday = BCD2BIN(buf[CCR_MDAY]);
++	tm->tm_mon = BCD2BIN(buf[CCR_MONTH]);
++	data->epoch = BCD2BIN(buf[CCR_Y2K]) * 100;
++	tm->tm_year = BCD2BIN(buf[CCR_YEAR]) + data->epoch - 1900;
++	tm->tm_wday = buf[CCR_WDAY];
++
++	dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
++		"mday=%d, mon=%d, year=%d, wday=%d\n",
++		__FUNCTION__,
++		tm->tm_sec, tm->tm_min, tm->tm_hour,
++		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
++
++	return 0;
++}
++
++static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
++				int datetoo, u8 reg_base)
++{
++	int i, err, xfer;
++
++	unsigned char buf[8];
++
++	static const unsigned char wel[3] = { 0, X1205_REG_SR,
++						X1205_SR_WEL };
++
++	static const unsigned char rwel[3] = { 0, X1205_REG_SR,
++						X1205_SR_WEL | X1205_SR_RWEL };
++
++	static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
++
++	struct x1205_data *data = i2c_get_clientdata(client);
++
++	/* check if all values in the tm struct are correct */
++	if ((err = x1205_validate_tm(tm)) < 0)
++		return err;
++
++	dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
++		"mday=%d, mon=%d, year=%d, wday=%d\n",
++		__FUNCTION__,
++		tm->tm_sec, tm->tm_min, tm->tm_hour,
++		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
++
++	buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
++	buf[CCR_MIN] = BIN2BCD(tm->tm_min);
++
++	/* set hour and 24hr bit */
++	buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL;
++
++	/* should we also set the date? */
++	if (datetoo) {
++		buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
++
++		/* month, 0 - 11 */
++		buf[CCR_MONTH] = BIN2BCD(tm->tm_mon);
++
++		/* year, since 1900 */
++		buf[CCR_YEAR] = BIN2BCD(tm->tm_year + 1900 - data->epoch);
++		buf[CCR_WDAY] = tm->tm_wday & 0x07;
++		buf[CCR_Y2K] = BIN2BCD(data->epoch / 100);
++	}
++
++	/* this sequence is required to unlock the chip */
++	xfer = i2c_master_send(client, wel, 3);
++	if (xfer != 3) {
++		dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer);
++		return -EIO;
++	}
++
++	xfer = i2c_master_send(client, rwel, 3);
++	if (xfer != 3) {
++		dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer);
++		return -EIO;
++	}
++
++	/* write register's data */
++	for (i = 0; i < (datetoo ? 8 : 3); i++) {
++		unsigned char rdata[3] = { 0, reg_base + i, buf[i] };
++
++		xfer = i2c_master_send(client, rdata, 3);
++		if (xfer != 3) {
++			dev_err(&client->dev,
++				"%s: xfer=%d addr=%02x, data=%02x\n",
++				__FUNCTION__,
++				 xfer, rdata[1], rdata[2]);
++			return -EIO;
++		}
++	};
++
++	/* disable further writes */
++	xfer = i2c_master_send(client, diswe, 3);
++	if (xfer != 3) {
++		dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer);
++		return -EIO;
++	}
++
++	return 0;
++}
++
++static int x1205_get_dtrim(struct i2c_client *client, int *trim)
++{
++	unsigned char dtr;
++	static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR };
++
++	struct i2c_msg msgs[] = {
++		{ client->addr, 0, 2, dtr_addr },	/* setup read ptr */
++		{ client->addr, I2C_M_RD, 1, &dtr }, 	/* read dtr */
++	};
++
++	/* read dtr register */
++	if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
++		dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
++		return -EIO;
++	}
++
++	dev_dbg(&client->dev, "%s: raw dtr=%x\n", __FUNCTION__, dtr);
++
++	*trim = 0;
++
++	if (dtr & X1205_DTR_DTR0)
++		*trim += 20;
++
++	if (dtr & X1205_DTR_DTR1)
++		*trim += 10;
++
++	if (dtr & X1205_DTR_DTR2)
++		*trim = -*trim;
++
++	return 0;
++}
++
++static int x1205_get_atrim(struct i2c_client *client, int *trim)
++{
++	s8 atr;
++	static unsigned char atr_addr[2] = { 0, X1205_REG_ATR };
++
++	struct i2c_msg msgs[] = {
++		{ client->addr, 0, 2, atr_addr },	/* setup read ptr */
++		{ client->addr, I2C_M_RD, 1, &atr }, 	/* read atr */
++	};
++
++	/* read atr register */
++	if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
++		dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
++		return -EIO;
++	}
++
++	dev_dbg(&client->dev, "%s: raw atr=%x\n", __FUNCTION__, atr);
++
++	/* atr is a two's complement value on 6 bits,
++	 * perform sign extension. The formula is
++	 * Catr = (atr * 0.25pF) + 11.00pF.
++	 */
++	if (atr & 0x20)
++		atr |= 0xC0;
++
++	dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __FUNCTION__, atr, atr);
++
++	*trim = (atr * 250) + 11000;
++
++	dev_dbg(&client->dev, "%s: real=%d\n", __FUNCTION__, *trim);
++
++	return 0;
++}
++
++static int x1205_hctosys(struct i2c_client *client)
++{
++	int err;
++
++	struct rtc_time tm;
++	struct timespec tv;
++
++	err = x1205_command(client, X1205_CMD_GETDATETIME, &tm);
++
++	if (err) {
++		dev_err(&client->dev,
++			"Unable to set the system clock\n");
++		return err;
++	}
++
++	/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
++	 * whether it stores the most close value or the value with partial
++	 * seconds truncated. However, it is important that we use it to store
++	 * the truncated value. This is because otherwise it is necessary,
++	 * in an rtc sync function, to read both xtime.tv_sec and
++	 * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
++	 * of >32bits is not possible. So storing the most close value would
++	 * slow down the sync API. So here we have the truncated value and
++	 * the best guess is to add 0.5s.
++	 */
++
++	tv.tv_nsec = NSEC_PER_SEC >> 1;
++
++	/* WARNING: this is not the C library 'mktime' call, it is a built in
++	 * inline function from include/linux/time.h.  It expects (requires)
++	 * the month to be in the range 1-12
++	 */
++
++	tv.tv_sec  = mktime(tm.tm_year + 1900, tm.tm_mon + 1,
++				tm.tm_mday, tm.tm_hour,
++				tm.tm_min, tm.tm_sec);
++
++	do_settimeofday(&tv);
++
++	dev_info(&client->dev,
++		"setting the system clock to %d-%d-%d %d:%d:%d\n",
++		tm.tm_year + 1900, tm.tm_mon + 1,
++		tm.tm_mday, tm.tm_hour, tm.tm_min,
++		tm.tm_sec);
++
++	return 0;
++}
++
++struct x1205_limit
++{
++	unsigned char reg;
++	unsigned char mask;
++	unsigned char min;
++	unsigned char max;
++};
++
++static int x1205_validate_client(struct i2c_client *client)
++{
++	int i, xfer;
++
++	/* Probe array. We will read the register at the specified
++	 * address and check if the given bits are zero.
++	 */
++	static const unsigned char probe_zero_pattern[] = {
++		/* register, mask */
++		X1205_REG_SR,	0x18,
++		X1205_REG_DTR,	0xF8,
++		X1205_REG_ATR,	0xC0,
++		X1205_REG_INT,	0x18,
++		X1205_REG_0,	0xFF,
++	};
++
++	static const struct x1205_limit probe_limits_pattern[] = {
++		/* register, mask, min, max */
++		{ X1205_REG_Y2K,	0xFF,	19,	20	},
++		{ X1205_REG_DW,		0xFF,	0,	6	},
++		{ X1205_REG_YR,		0xFF,	0,	99	},
++		{ X1205_REG_MO,		0xFF,	0,	12	},
++		{ X1205_REG_DT,		0xFF,	0,	31	},
++		{ X1205_REG_HR,		0x7F,	0,	23	},
++		{ X1205_REG_MN,		0xFF,	0,	59	},
++		{ X1205_REG_SC,		0xFF,	0,	59	},
++		{ X1205_REG_Y2K1,	0xFF,	19,	20	},
++		{ X1205_REG_Y2K0,	0xFF,	19,	20	},
++	};
++
++	/* check that registers have bits a 0 where expected */
++	for (i = 0; i < ARRAY_SIZE(probe_zero_pattern); i += 2) {
++		unsigned char buf;
++
++		unsigned char addr[2] = { 0, probe_zero_pattern[i] };
++
++		struct i2c_msg msgs[2] = {
++			{ client->addr, 0, 2, addr },
++			{ client->addr, I2C_M_RD, 1, &buf },
++		};
++
++		xfer = i2c_transfer(client->adapter, msgs, 2);
++		if (xfer != 2) {
++			dev_err(&client->adapter->dev,
++				"%s: could not read register %x\n",
++				__FUNCTION__, addr[1]);
++
++			return -EIO;
++		}
++
++		if ((buf & probe_zero_pattern[i+1]) != 0) {
++			dev_err(&client->adapter->dev,
++				"%s: register=%02x, zero pattern=%d, value=%x\n",
++				__FUNCTION__, addr[1], i, buf);
++
++			return -ENODEV;
++		}
++	}
++
++	/* check limits (only registers with bcd values) */
++	for (i = 0; i < ARRAY_SIZE(probe_limits_pattern); i++) {
++		unsigned char reg, value;
++
++		unsigned char addr[2] = { 0, probe_limits_pattern[i].reg };
++
++		struct i2c_msg msgs[2] = {
++			{ client->addr, 0, 2, addr },
++			{ client->addr, I2C_M_RD, 1, &reg },
++		};
++
++		xfer = i2c_transfer(client->adapter, msgs, 2);
++
++		if (xfer != 2) {
++			dev_err(&client->adapter->dev,
++				"%s: could not read register %x\n",
++				__FUNCTION__, addr[1]);
++
++			return -EIO;
++		}
++
++		value = BCD2BIN(reg & probe_limits_pattern[i].mask);
++
++		if (value > probe_limits_pattern[i].max ||
++			value < probe_limits_pattern[i].min) {
++			dev_dbg(&client->adapter->dev,
++				"%s: register=%x, lim pattern=%d, value=%d\n",
++				__FUNCTION__, addr[1], i, value);
++
++			return -ENODEV;
++		}
++	}
++
++	return 0;
++}
++
++static int x1205_attach(struct i2c_adapter *adapter)
++{
++	dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
++
++	return i2c_probe(adapter, &addr_data, x1205_probe);
++}
++
++int x1205_direct_attach(int adapter_id,
++	struct i2c_client_address_data *address_data)
++{
++	int err;
++	struct i2c_adapter *adapter = i2c_get_adapter(adapter_id);
++
++	if (adapter) {
++		err = i2c_probe(adapter,
++			address_data, x1205_probe);
++
++		i2c_put_adapter(adapter);
++
++		return err;
++	}
++
++	return -ENODEV;
++}
++
++static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
++{
++	struct i2c_client *client;
++	struct x1205_data *data;
++
++	int err = 0;
++
++	dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
++
++	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
++		err = -ENODEV;
++		goto exit;
++	}
++
++	if (!(data = kzalloc(sizeof(struct x1205_data), GFP_KERNEL))) {
++		err = -ENOMEM;
++		goto exit;
++	}
++
++	/* Initialize our structures */
++	data->epoch = 2000;
++
++	client = &data->client;
++	client->addr = address;
++	client->driver = &x1205_driver;
++	client->adapter	= adapter;
++
++	strlcpy(client->name, "x1205", I2C_NAME_SIZE);
++
++	i2c_set_clientdata(client, data);
++
++	/* Verify the chip is really an X1205 */
++	if (kind < 0) {
++		if (x1205_validate_client(client) < 0) {
++			err = -ENODEV;
++			goto exit_kfree;
++		}
++	}
++
++	/* Inform the i2c layer */
++	if ((err = i2c_attach_client(client)))
++		goto exit_kfree;
++
++	list_add(&data->list, &x1205_clients);
++
++	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
++
++	/* If requested, set the system time */
++	if (hctosys)
++		x1205_hctosys(client);
++
++	return 0;
++
++exit_kfree:
++	kfree(data);
++
++exit:
++	return err;
++}
++
++static int x1205_detach(struct i2c_client *client)
++{
++	int err;
++	struct x1205_data *data = i2c_get_clientdata(client);
++
++	dev_dbg(&client->dev, "%s\n", __FUNCTION__);
++
++	if ((err = i2c_detach_client(client)))
++		return err;
++
++	list_del(&data->list);
++
++	kfree(data);
++
++	return 0;
++}
++
++static int x1205_command(struct i2c_client *client, unsigned int cmd,
++	void *param)
++{
++	if (param == NULL)
++		return -EINVAL;
++
++	if (!capable(CAP_SYS_TIME))
++		return -EACCES;
++
++	dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
++
++	switch (cmd) {
++	case X1205_CMD_GETDATETIME:
++		return x1205_get_datetime(client, param, X1205_CCR_BASE);
++
++	case X1205_CMD_SETTIME:
++		return x1205_set_datetime(client, param, 0,
++				X1205_CCR_BASE);
++
++	case X1205_CMD_SETDATETIME:
++		return x1205_set_datetime(client, param, 1,
++				X1205_CCR_BASE);
++
++	case X1205_CMD_GETALARM:
++		return x1205_get_datetime(client, param, X1205_ALM0_BASE);
++
++	case X1205_CMD_SETALARM:
++		return x1205_set_datetime(client, param, 1,
++				X1205_ALM0_BASE);
++
++	case X1205_CMD_GETDTRIM:
++		return x1205_get_dtrim(client, param);
++
++	case X1205_CMD_GETATRIM:
++		return x1205_get_atrim(client, param);
++
++	default:
++		return -EINVAL;
++	}
++}
++
++static int __init x1205_init(void)
++{
++	return i2c_add_driver(&x1205_driver);
++}
++
++static void __exit x1205_exit(void)
++{
++	i2c_del_driver(&x1205_driver);
++}
++
++MODULE_AUTHOR(
++	"Karen Spearel <kas11 at tampabay.rr.com>, "
++	"Alessandro Zummo <a.zummo at towertech.it>");
++MODULE_DESCRIPTION("Xicor X1205 RTC driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
++
++EXPORT_SYMBOL_GPL(x1205_do_command);
++EXPORT_SYMBOL_GPL(x1205_direct_attach);
++
++module_init(x1205_init);
++module_exit(x1205_exit);
+diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -19,7 +19,8 @@
+ 
+ /* With some changes from Kyösti Mälkki <kmalkki at cc.hut.fi>.
+    All SMBus-related things are written by Frodo Looijaard <frodol at dds.nl>
+-   SMBus 2.0 support by Mark Studebaker <mdsxyz123 at yahoo.com>                */
++   SMBus 2.0 support by Mark Studebaker <mdsxyz123 at yahoo.com> and
++   Jean Delvare <khali at linux-fr.org> */
+ 
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -29,6 +30,7 @@
+ #include <linux/init.h>
+ #include <linux/idr.h>
+ #include <linux/seq_file.h>
++#include <linux/platform_device.h>
+ #include <asm/uaccess.h>
+ 
+ 
+@@ -48,7 +50,7 @@ static int i2c_bus_suspend(struct device
+ 	int rc = 0;
+ 
+ 	if (dev->driver && dev->driver->suspend)
+-		rc = dev->driver->suspend(dev,state,0);
++		rc = dev->driver->suspend(dev, state);
+ 	return rc;
+ }
+ 
+@@ -57,7 +59,7 @@ static int i2c_bus_resume(struct device 
+ 	int rc = 0;
+ 	
+ 	if (dev->driver && dev->driver->resume)
+-		rc = dev->driver->resume(dev,0);
++		rc = dev->driver->resume(dev);
+ 	return rc;
+ }
+ 
+@@ -85,6 +87,7 @@ void i2c_adapter_dev_release(struct devi
+ }
+ 
+ struct device_driver i2c_adapter_driver = {
++	.owner = THIS_MODULE,
+ 	.name =	"i2c_adapter",
+ 	.bus = &i2c_bus_type,
+ 	.probe = i2c_device_probe,
+@@ -98,6 +101,7 @@ static void i2c_adapter_class_dev_releas
+ }
+ 
+ struct class i2c_adapter_class = {
++	.owner =	THIS_MODULE,
+ 	.name =		"i2c-adapter",
+ 	.release =	&i2c_adapter_class_dev_release,
+ };
+@@ -291,6 +295,7 @@ int i2c_add_driver(struct i2c_driver *dr
+ 	down(&core_lists);
+ 
+ 	/* add the driver to the list of i2c drivers in the driver core */
++	driver->driver.owner = driver->owner;
+ 	driver->driver.name = driver->name;
+ 	driver->driver.bus = &i2c_bus_type;
+ 	driver->driver.probe = i2c_device_probe;
+@@ -706,10 +711,6 @@ int i2c_probe(struct i2c_adapter *adapte
+ 	int i, err;
+ 	int adap_id = i2c_adapter_id(adapter);
+ 
+-	/* Forget it if we can't probe using SMBUS_QUICK */
+-	if (! i2c_check_functionality(adapter,I2C_FUNC_SMBUS_QUICK))
+-		return -1;
+-
+ 	/* Force entries are done first, and are not affected by ignore
+ 	   entries */
+ 	if (address_data->forces) {
+@@ -736,6 +737,17 @@ int i2c_probe(struct i2c_adapter *adapte
+ 		}
+ 	}
+ 
++	/* Stop here if we can't use SMBUS_QUICK */
++	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
++		if (address_data->probe[0] == I2C_CLIENT_END
++		 && address_data->normal_i2c[0] == I2C_CLIENT_END)
++		 	return 0;
++
++		dev_warn(&adapter->dev, "SMBus Quick command not supported, "
++			 "can't probe for chips\n");
++		return -1;
++	}
++
+ 	/* Probe entries are done second, and are not affected by ignore
+ 	   entries either */
+ 	for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) {
+@@ -820,101 +832,44 @@ crc8(u16 data)
+ 	return (u8)(data >> 8);
+ }
+ 
+-/* CRC over count bytes in the first array plus the bytes in the rest
+-   array if it is non-null. rest[0] is the (length of rest) - 1
+-   and is included. */
+-static u8 i2c_smbus_partial_pec(u8 crc, int count, u8 *first, u8 *rest)
++/* Incremental CRC8 over count bytes in the array pointed to by p */
++static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
+ {
+ 	int i;
+ 
+ 	for(i = 0; i < count; i++)
+-		crc = crc8((crc ^ first[i]) << 8);
+-	if(rest != NULL)
+-		for(i = 0; i <= rest[0]; i++)
+-			crc = crc8((crc ^ rest[i]) << 8);
++		crc = crc8((crc ^ p[i]) << 8);
+ 	return crc;
+ }
+ 
+-static u8 i2c_smbus_pec(int count, u8 *first, u8 *rest)
++/* Assume a 7-bit address, which is reasonable for SMBus */
++static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg)
+ {
+-	return i2c_smbus_partial_pec(0, count, first, rest);
++	/* The address will be sent first */
++	u8 addr = (msg->addr << 1) | !!(msg->flags & I2C_M_RD);
++	pec = i2c_smbus_pec(pec, &addr, 1);
++
++	/* The data buffer follows */
++	return i2c_smbus_pec(pec, msg->buf, msg->len);
+ }
+ 
+-/* Returns new "size" (transaction type)
+-   Note that we convert byte to byte_data and byte_data to word_data
+-   rather than invent new xxx_PEC transactions. */
+-static int i2c_smbus_add_pec(u16 addr, u8 command, int size,
+-			     union i2c_smbus_data *data)
++/* Used for write only transactions */
++static inline void i2c_smbus_add_pec(struct i2c_msg *msg)
+ {
+-	u8 buf[3];
+-
+-	buf[0] = addr << 1;
+-	buf[1] = command;
+-	switch(size) {
+-		case I2C_SMBUS_BYTE:
+-			data->byte = i2c_smbus_pec(2, buf, NULL);
+-			size = I2C_SMBUS_BYTE_DATA;
+-			break;
+-		case I2C_SMBUS_BYTE_DATA:
+-			buf[2] = data->byte;
+-			data->word = buf[2] ||
+-			            (i2c_smbus_pec(3, buf, NULL) << 8);
+-			size = I2C_SMBUS_WORD_DATA;
+-			break;
+-		case I2C_SMBUS_WORD_DATA:
+-			/* unsupported */
+-			break;
+-		case I2C_SMBUS_BLOCK_DATA:
+-			data->block[data->block[0] + 1] =
+-			             i2c_smbus_pec(2, buf, data->block);
+-			size = I2C_SMBUS_BLOCK_DATA_PEC;
+-			break;
+-	}
+-	return size;	
++	msg->buf[msg->len] = i2c_smbus_msg_pec(0, msg);
++	msg->len++;
+ }
+ 
+-static int i2c_smbus_check_pec(u16 addr, u8 command, int size, u8 partial,
+-			       union i2c_smbus_data *data)
++/* Return <0 on CRC error
++   If there was a write before this read (most cases) we need to take the
++   partial CRC from the write part into account.
++   Note that this function does modify the message (we need to decrease the
++   message length to hide the CRC byte from the caller). */
++static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg)
+ {
+-	u8 buf[3], rpec, cpec;
++	u8 rpec = msg->buf[--msg->len];
++	cpec = i2c_smbus_msg_pec(cpec, msg);
+ 
+-	buf[1] = command;
+-	switch(size) {
+-		case I2C_SMBUS_BYTE_DATA:
+-			buf[0] = (addr << 1) | 1;
+-			cpec = i2c_smbus_pec(2, buf, NULL);
+-			rpec = data->byte;
+-			break;
+-		case I2C_SMBUS_WORD_DATA:
+-			buf[0] = (addr << 1) | 1;
+-			buf[2] = data->word & 0xff;
+-			cpec = i2c_smbus_pec(3, buf, NULL);
+-			rpec = data->word >> 8;
+-			break;
+-		case I2C_SMBUS_WORD_DATA_PEC:
+-			/* unsupported */
+-			cpec = rpec = 0;
+-			break;
+-		case I2C_SMBUS_PROC_CALL_PEC:
+-			/* unsupported */
+-			cpec = rpec = 0;
+-			break;
+-		case I2C_SMBUS_BLOCK_DATA_PEC:
+-			buf[0] = (addr << 1);
+-			buf[2] = (addr << 1) | 1;
+-			cpec = i2c_smbus_pec(3, buf, data->block);
+-			rpec = data->block[data->block[0] + 1];
+-			break;
+-		case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
+-			buf[0] = (addr << 1) | 1;
+-			rpec = i2c_smbus_partial_pec(partial, 1,
+-			                             buf, data->block);
+-			cpec = data->block[data->block[0] + 1];
+-			break;
+-		default:
+-			cpec = rpec = 0;
+-			break;
+-	}
+ 	if (rpec != cpec) {
+ 		pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n",
+ 			rpec, cpec);
+@@ -941,9 +896,8 @@ s32 i2c_smbus_read_byte(struct i2c_clien
+ 
+ s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value)
+ {
+-	union i2c_smbus_data data;	/* only for PEC */
+ 	return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
+-	                      I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,&data);
++	                      I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
+ }
+ 
+ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command)
+@@ -1026,13 +980,14 @@ static s32 i2c_smbus_xfer_emulated(struc
+ 	  need to use only one message; when reading, we need two. We initialize
+ 	  most things with sane defaults, to keep the code below somewhat
+ 	  simpler. */
+-	unsigned char msgbuf0[34];
+-	unsigned char msgbuf1[34];
++	unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
++	unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
+ 	int num = read_write == I2C_SMBUS_READ?2:1;
+ 	struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, 
+ 	                          { addr, flags | I2C_M_RD, 0, msgbuf1 }
+ 	                        };
+ 	int i;
++	u8 partial_pec = 0;
+ 
+ 	msgbuf0[0] = command;
+ 	switch(size) {
+@@ -1075,7 +1030,6 @@ static s32 i2c_smbus_xfer_emulated(struc
+ 		msgbuf0[2] = (data->word >> 8) & 0xff;
+ 		break;
+ 	case I2C_SMBUS_BLOCK_DATA:
+-	case I2C_SMBUS_BLOCK_DATA_PEC:
+ 		if (read_write == I2C_SMBUS_READ) {
+ 			dev_err(&adapter->dev, "Block read not supported "
+ 			       "under I2C emulation!\n");
+@@ -1088,23 +1042,20 @@ static s32 i2c_smbus_xfer_emulated(struc
+ 				       data->block[0]);
+ 				return -1;
+ 			}
+-			if(size == I2C_SMBUS_BLOCK_DATA_PEC)
+-				(msg[0].len)++;
+-			for (i = 1; i <= msg[0].len; i++)
++			for (i = 1; i < msg[0].len; i++)
+ 				msgbuf0[i] = data->block[i-1];
+ 		}
+ 		break;
+ 	case I2C_SMBUS_BLOCK_PROC_CALL:
+-	case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
+ 		dev_dbg(&adapter->dev, "Block process call not supported "
+ 		       "under I2C emulation!\n");
+ 		return -1;
+ 	case I2C_SMBUS_I2C_BLOCK_DATA:
+ 		if (read_write == I2C_SMBUS_READ) {
+-			msg[1].len = I2C_SMBUS_I2C_BLOCK_MAX;
++			msg[1].len = I2C_SMBUS_BLOCK_MAX;
+ 		} else {
+ 			msg[0].len = data->block[0] + 1;
+-			if (msg[0].len > I2C_SMBUS_I2C_BLOCK_MAX + 1) {
++			if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {
+ 				dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with "
+ 				       "invalid block write size (%d)\n",
+ 				       data->block[0]);
+@@ -1120,9 +1071,30 @@ static s32 i2c_smbus_xfer_emulated(struc
+ 		return -1;
+ 	}
+ 
++	i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK
++				      && size != I2C_SMBUS_I2C_BLOCK_DATA);
++	if (i) {
++		/* Compute PEC if first message is a write */
++		if (!(msg[0].flags & I2C_M_RD)) {
++		 	if (num == 1) /* Write only */
++				i2c_smbus_add_pec(&msg[0]);
++			else /* Write followed by read */
++				partial_pec = i2c_smbus_msg_pec(0, &msg[0]);
++		}
++		/* Ask for PEC if last message is a read */
++		if (msg[num-1].flags & I2C_M_RD)
++		 	msg[num-1].len++;
++	}
++
+ 	if (i2c_transfer(adapter, msg, num) < 0)
+ 		return -1;
+ 
++	/* Check PEC if last message is a read */
++	if (i && (msg[num-1].flags & I2C_M_RD)) {
++		if (i2c_smbus_check_pec(partial_pec, &msg[num-1]) < 0)
++			return -1;
++	}
++
+ 	if (read_write == I2C_SMBUS_READ)
+ 		switch(size) {
+ 			case I2C_SMBUS_BYTE:
+@@ -1137,8 +1109,8 @@ static s32 i2c_smbus_xfer_emulated(struc
+ 				break;
+ 			case I2C_SMBUS_I2C_BLOCK_DATA:
+ 				/* fixed at 32 for now */
+-				data->block[0] = I2C_SMBUS_I2C_BLOCK_MAX;
+-				for (i = 0; i < I2C_SMBUS_I2C_BLOCK_MAX; i++)
++				data->block[0] = I2C_SMBUS_BLOCK_MAX;
++				for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
+ 					data->block[i+1] = msgbuf1[i];
+ 				break;
+ 		}
+@@ -1151,28 +1123,8 @@ s32 i2c_smbus_xfer(struct i2c_adapter * 
+                    union i2c_smbus_data * data)
+ {
+ 	s32 res;
+-	int swpec = 0;
+-	u8 partial = 0;
+ 
+ 	flags &= I2C_M_TEN | I2C_CLIENT_PEC;
+-	if((flags & I2C_CLIENT_PEC) &&
+-	   !(i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HWPEC_CALC))) {
+-		swpec = 1;
+-		if(read_write == I2C_SMBUS_READ &&
+-		   size == I2C_SMBUS_BLOCK_DATA)
+-			size = I2C_SMBUS_BLOCK_DATA_PEC;
+-		else if(size == I2C_SMBUS_PROC_CALL)
+-			size = I2C_SMBUS_PROC_CALL_PEC;
+-		else if(size == I2C_SMBUS_BLOCK_PROC_CALL) {
+-			i2c_smbus_add_pec(addr, command,
+-		                          I2C_SMBUS_BLOCK_DATA, data);
+-			partial = data->block[data->block[0] + 1];
+-			size = I2C_SMBUS_BLOCK_PROC_CALL_PEC;
+-		} else if(read_write == I2C_SMBUS_WRITE &&
+-		          size != I2C_SMBUS_QUICK &&
+-		          size != I2C_SMBUS_I2C_BLOCK_DATA)
+-			size = i2c_smbus_add_pec(addr, command, size, data);
+-	}
+ 
+ 	if (adapter->algo->smbus_xfer) {
+ 		down(&adapter->bus_lock);
+@@ -1183,13 +1135,6 @@ s32 i2c_smbus_xfer(struct i2c_adapter * 
+ 		res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
+ 	                                      command,size,data);
+ 
+-	if(res >= 0 && swpec &&
+-	   size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA &&
+-	   (read_write == I2C_SMBUS_READ || size == I2C_SMBUS_PROC_CALL_PEC ||
+-	    size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) {
+-		if(i2c_smbus_check_pec(addr, command, size, partial, data))
+-			return -1;
+-	}
+ 	return res;
+ }
+ 
+diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
+--- a/drivers/i2c/i2c-dev.c
++++ b/drivers/i2c/i2c-dev.c
+@@ -26,18 +26,15 @@
+ 
+ /* The I2C_RDWR ioctl code is written by Kolja Waschk <waschk at telos.de> */
+ 
+-/* The devfs code is contributed by Philipp Matthias Hahn 
+-   <pmhahn at titan.lahn.de> */
+-
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/slab.h>
+ #include <linux/smp_lock.h>
+-#include <linux/devfs_fs_kernel.h>
+ #include <linux/init.h>
+ #include <linux/i2c.h>
+ #include <linux/i2c-dev.h>
++#include <linux/platform_device.h>
+ #include <asm/uaccess.h>
+ 
+ static struct i2c_client i2cdev_client_template;
+@@ -80,10 +77,9 @@ static struct i2c_dev *get_free_i2c_dev(
+ {
+ 	struct i2c_dev *i2c_dev;
+ 
+-	i2c_dev = kmalloc(sizeof(*i2c_dev), GFP_KERNEL);
++	i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
+ 	if (!i2c_dev)
+ 		return ERR_PTR(-ENOMEM);
+-	memset(i2c_dev, 0x00, sizeof(*i2c_dev));
+ 
+ 	spin_lock(&i2c_dev_array_lock);
+ 	if (i2c_dev_array[adap->nr]) {
+@@ -177,8 +173,8 @@ static int i2cdev_ioctl(struct inode *in
+ 	int i,datasize,res;
+ 	unsigned long funcs;
+ 
+-	dev_dbg(&client->adapter->dev, "i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
+-		iminor(inode),cmd, arg);
++	dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
++		cmd, arg);
+ 
+ 	switch ( cmd ) {
+ 	case I2C_SLAVE:
+@@ -432,8 +428,6 @@ static int i2cdev_attach_adapter(struct 
+ 	if (IS_ERR(i2c_dev))
+ 		return PTR_ERR(i2c_dev);
+ 
+-	devfs_mk_cdev(MKDEV(I2C_MAJOR, i2c_dev->minor),
+-			S_IFCHR|S_IRUSR|S_IWUSR, "i2c/%d", i2c_dev->minor);
+ 	pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",
+ 		 adap->name, i2c_dev->minor);
+ 
+@@ -466,7 +460,6 @@ static int i2cdev_detach_adapter(struct 
+ 		return -ENODEV;
+ 
+ 	init_completion(&i2c_dev->released);
+-	devfs_remove("i2c/%d", i2c_dev->minor);
+ 	return_i2c_dev(i2c_dev);
+ 	class_device_unregister(&i2c_dev->class_dev);
+ 	wait_for_completion(&i2c_dev->released);
+@@ -522,8 +515,6 @@ static int __init i2c_dev_init(void)
+ 	if (res)
+ 		goto out_unreg_class;
+ 
+-	devfs_mk_dir("i2c");
+-
+ 	return 0;
+ 
+ out_unreg_class:
+@@ -539,7 +530,6 @@ static void __exit i2c_dev_exit(void)
+ {
+ 	i2c_del_driver(&i2cdev_driver);
+ 	class_unregister(&i2c_dev_class);
+-	devfs_remove("i2c");
+ 	unregister_chrdev(I2C_MAJOR,"i2c");
+ }
+ 
+diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
+--- a/drivers/ide/Kconfig
++++ b/drivers/ide/Kconfig
+@@ -778,6 +778,35 @@ config BLK_DEV_IDE_PMAC_BLINK
+ 	  This option enables the use of the sleep LED as a hard drive
+ 	  activity LED.
+ 
++config BLK_DEV_IDE_AU1XXX
++       bool "IDE for AMD Alchemy Au1200"
++       depends on SOC_AU1200
++choice
++       prompt "IDE Mode for AMD Alchemy Au1200"
++       default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
++       depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
++
++config BLK_DEV_IDE_AU1XXX_PIO_DBDMA
++       bool "PIO+DbDMA IDE for AMD Alchemy Au1200"
++
++config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++       bool "MDMA2+DbDMA IDE for AMD Alchemy Au1200"
++       depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
++endchoice
++
++config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
++        bool "Enable burstable Mode on DbDMA"
++        default false
++        depends BLK_DEV_IDE_AU1XXX
++        help
++          This option enable the burstable Flag on DbDMA controller
++          (cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY").
++
++config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
++       int "Maximum transfer size (KB) per request (up to 128)"
++       default "128"
++       depends BLK_DEV_IDE_AU1XXX
++
+ config IDE_ARM
+ 	def_bool ARM && (ARCH_A5K || ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
+ 
+@@ -1013,7 +1042,7 @@ config BLK_DEV_UMC8672
+ endif
+ 
+ config BLK_DEV_IDEDMA
+-	def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS
++	def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ 
+ config IDEDMA_IVB
+ 	bool "IGNORE word93 Validation BITS"
+diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
+--- a/drivers/ide/ide-cd.c
++++ b/drivers/ide/ide-cd.c
+@@ -2211,13 +2211,12 @@ static int cdrom_read_toc(ide_drive_t *d
+ 
+ 	if (toc == NULL) {
+ 		/* Try to allocate space. */
+-		toc = (struct atapi_toc *) kmalloc (sizeof (struct atapi_toc),
+-						    GFP_KERNEL);
+-		info->toc = toc;
++		toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
+ 		if (toc == NULL) {
+ 			printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
+ 			return -ENOMEM;
+ 		}
++		info->toc = toc;
+ 	}
+ 
+ 	/* Check to see if the existing data is still valid.
+@@ -2240,7 +2239,8 @@ static int cdrom_read_toc(ide_drive_t *d
+ 	/* First read just the header, so we know how long the TOC is. */
+ 	stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
+ 				    sizeof(struct atapi_toc_header), sense);
+-	if (stat) return stat;
++	if (stat)
++		return stat;
+ 
+ #if ! STANDARD_ATAPI
+ 	if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
+@@ -2324,7 +2324,8 @@ static int cdrom_read_toc(ide_drive_t *d
+ 		/* Read the multisession information. */
+ 		stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
+ 					   sizeof(ms_tmp), sense);
+-		if (stat) return stat;
++		if (stat)
++			return stat;
+ 
+ 		toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
+ 	} else {
+@@ -2460,7 +2461,7 @@ static int ide_cdrom_packet(struct cdrom
+ 			    struct packet_command *cgc)
+ {
+ 	struct request req;
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 
+ 	if (cgc->timeout <= 0)
+ 		cgc->timeout = ATAPI_WAIT_PC;
+@@ -2537,7 +2538,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_
+ 			   unsigned int cmd, void *arg)
+ 			   
+ {
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 	struct cdrom_info *info = drive->driver_data;
+ 	int stat;
+ 
+@@ -2548,7 +2549,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_
+ 	 */
+ 	case CDROMPLAYTRKIND: {
+ 		unsigned long lba_start, lba_end;
+-		struct cdrom_ti *ti = (struct cdrom_ti *)arg;
++		struct cdrom_ti *ti = arg;
+ 		struct atapi_toc_entry *first_toc, *last_toc;
+ 
+ 		stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
+@@ -2571,12 +2572,13 @@ int ide_cdrom_audio_ioctl (struct cdrom_
+ 	}
+ 
+ 	case CDROMREADTOCHDR: {
+-		struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg;
++		struct cdrom_tochdr *tochdr = arg;
+ 		struct atapi_toc *toc;
+ 
+ 		/* Make sure our saved TOC is valid. */
+ 		stat = cdrom_read_toc(drive, NULL);
+-		if (stat) return stat;
++		if (stat)
++			return stat;
+ 
+ 		toc = info->toc;
+ 		tochdr->cdth_trk0 = toc->hdr.first_track;
+@@ -2586,11 +2588,12 @@ int ide_cdrom_audio_ioctl (struct cdrom_
+ 	}
+ 
+ 	case CDROMREADTOCENTRY: {
+-		struct cdrom_tocentry *tocentry = (struct cdrom_tocentry*) arg;
++		struct cdrom_tocentry *tocentry = arg;
+ 		struct atapi_toc_entry *toce;
+ 
+ 		stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, &toce);
+-		if (stat) return stat;
++		if (stat)
++			return stat;
+ 
+ 		tocentry->cdte_ctrl = toce->control;
+ 		tocentry->cdte_adr  = toce->adr;
+@@ -2613,7 +2616,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_
+ static
+ int ide_cdrom_reset (struct cdrom_device_info *cdi)
+ {
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 	struct request_sense sense;
+ 	struct request req;
+ 	int ret;
+@@ -2636,12 +2639,13 @@ int ide_cdrom_reset (struct cdrom_device
+ static
+ int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
+ {
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 	struct request_sense sense;
+ 
+ 	if (position) {
+ 		int stat = cdrom_lockdoor(drive, 0, &sense);
+-		if (stat) return stat;
++		if (stat)
++			return stat;
+ 	}
+ 
+ 	return cdrom_eject(drive, !position, &sense);
+@@ -2650,7 +2654,7 @@ int ide_cdrom_tray_move (struct cdrom_de
+ static
+ int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
+ {
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 	return cdrom_lockdoor(drive, lock, NULL);
+ }
+ 
+@@ -2700,7 +2704,7 @@ void ide_cdrom_update_speed (ide_drive_t
+ static
+ int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
+ {
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 	struct request_sense sense;
+ 	struct atapi_capabilities_page cap;
+ 	int stat;
+@@ -2723,7 +2727,7 @@ int ide_cdrom_select_speed (struct cdrom
+ static
+ int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
+ {
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 	struct media_event_desc med;
+ 	struct request_sense sense;
+ 	int stat;
+@@ -2769,7 +2773,7 @@ int ide_cdrom_get_last_session (struct c
+ 				struct cdrom_multisession *ms_info)
+ {
+ 	struct atapi_toc *toc;
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 	struct cdrom_info *info = drive->driver_data;
+ 	struct request_sense sense;
+ 	int ret;
+@@ -2791,7 +2795,7 @@ int ide_cdrom_get_mcn (struct cdrom_devi
+ {
+ 	int stat;
+ 	char mcnbuf[24];
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 
+ /* get MCN */
+ 	if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
+@@ -2815,7 +2819,7 @@ static
+ int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
+ 				       int slot_nr)
+ {
+-	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++	ide_drive_t *drive = cdi->handle;
+ 	int retval;
+ 	
+ 	if (slot_nr == CDSL_CURRENT) {
+@@ -2886,7 +2890,7 @@ static int ide_cdrom_register (ide_drive
+ 	devinfo->mask = 0;
+ 	devinfo->speed = CDROM_STATE_FLAGS(drive)->current_speed;
+ 	devinfo->capacity = nslots;
+-	devinfo->handle = (void *) drive;
++	devinfo->handle = drive;
+ 	strcpy(devinfo->name, drive->name);
+ 	
+ 	/* set capability mask to match the probe. */
+@@ -2942,7 +2946,7 @@ int ide_cdrom_probe_capabilities (ide_dr
+ 	 * registered with the Uniform layer yet, it can't do this.
+ 	 * Same goes for cdi->ops.
+ 	 */
+-	cdi->handle = (ide_drive_t *) drive;
++	cdi->handle = drive;
+ 	cdi->ops = &ide_cdrom_dops;
+ 
+ 	if (ide_cdrom_get_capabilities(drive, &cap))
+@@ -3254,6 +3258,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PROC_FS
+ static
+ sector_t ide_cdrom_capacity (ide_drive_t *drive)
+ {
+@@ -3264,6 +3269,7 @@ sector_t ide_cdrom_capacity (ide_drive_t
+ 
+ 	return capacity * sectors_per_frame;
+ }
++#endif
+ 
+ static int ide_cd_remove(struct device *dev)
+ {
+@@ -3309,7 +3315,7 @@ static int ide_cd_probe(struct device *)
+ static int proc_idecd_read_capacity
+ 	(char *page, char **start, off_t off, int count, int *eof, void *data)
+ {
+-	ide_drive_t*drive = (ide_drive_t *)data;
++	ide_drive_t *drive = data;
+ 	int len;
+ 
+ 	len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
+@@ -3449,7 +3455,7 @@ static int ide_cd_probe(struct device *d
+ 		printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
+ 		goto failed;
+ 	}
+-	info = (struct cdrom_info *) kmalloc (sizeof (struct cdrom_info), GFP_KERNEL);
++	info = kmalloc(sizeof(struct cdrom_info), GFP_KERNEL);
+ 	if (info == NULL) {
+ 		printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
+ 		goto failed;
+diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
+--- a/drivers/ide/ide-proc.c
++++ b/drivers/ide/ide-proc.c
+@@ -64,6 +64,7 @@ static int proc_ide_read_imodel
+ 		case ide_cy82c693:	name = "cy82c693";	break;
+ 		case ide_4drives:	name = "4drives";	break;
+ 		case ide_pmac:		name = "mac-io";	break;
++		case ide_au1xxx:	name = "au1xxx";	break;
+ 		default:		name = "(unknown)";	break;
+ 	}
+ 	len = sprintf(page, "%s\n", name);
+diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
+--- a/drivers/ide/ide-tape.c
++++ b/drivers/ide/ide-tape.c
+@@ -1013,6 +1013,8 @@ typedef struct ide_tape_obj {
+ 
+ static DECLARE_MUTEX(idetape_ref_sem);
+ 
++static struct class *idetape_sysfs_class;
++
+ #define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref)
+ 
+ #define ide_tape_g(disk) \
+@@ -4704,6 +4706,10 @@ static void ide_tape_release(struct kref
+ 
+ 	drive->dsc_overlap = 0;
+ 	drive->driver_data = NULL;
++	class_device_destroy(idetape_sysfs_class,
++			MKDEV(IDETAPE_MAJOR, tape->minor));
++	class_device_destroy(idetape_sysfs_class,
++			MKDEV(IDETAPE_MAJOR, tape->minor + 128));
+ 	devfs_remove("%s/mt", drive->devfs_name);
+ 	devfs_remove("%s/mtn", drive->devfs_name);
+ 	devfs_unregister_tape(g->number);
+@@ -4878,6 +4884,11 @@ static int ide_tape_probe(struct device 
+ 
+ 	idetape_setup(drive, tape, minor);
+ 
++	class_device_create(idetape_sysfs_class, NULL,
++			MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name);
++	class_device_create(idetape_sysfs_class, NULL,
++			MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name);
++
+ 	devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
+ 			S_IFCHR | S_IRUGO | S_IWUGO,
+ 			"%s/mt", drive->devfs_name);
+@@ -4903,6 +4914,7 @@ MODULE_LICENSE("GPL");
+ static void __exit idetape_exit (void)
+ {
+ 	driver_unregister(&idetape_driver.gen_driver);
++	class_destroy(idetape_sysfs_class);
+ 	unregister_chrdev(IDETAPE_MAJOR, "ht");
+ }
+ 
+@@ -4911,11 +4923,33 @@ static void __exit idetape_exit (void)
+  */
+ static int idetape_init (void)
+ {
++	int error = 1;
++	idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
++	if (IS_ERR(idetape_sysfs_class)) {
++		idetape_sysfs_class = NULL;
++		printk(KERN_ERR "Unable to create sysfs class for ide tapes\n");
++		error = -EBUSY;
++		goto out;
++	}
++
+ 	if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) {
+ 		printk(KERN_ERR "ide-tape: Failed to register character device interface\n");
+-		return -EBUSY;
++		error = -EBUSY;
++		goto out_free_class;
+ 	}
+-	return driver_register(&idetape_driver.gen_driver);
++
++	error = driver_register(&idetape_driver.gen_driver);
++	if (error)
++		goto out_free_driver;
++
++	return 0;
++
++out_free_driver:
++	driver_unregister(&idetape_driver.gen_driver);
++out_free_class:
++	class_destroy(idetape_sysfs_class);
++out:
++	return error;
+ }
+ 
+ module_init(idetape_init);
+diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/ide/mips/au1xxx-ide.c
+@@ -0,0 +1,1250 @@
++/*
++ * linux/drivers/ide/mips/au1xxx-ide.c  version 01.30.00        Aug. 02 2005
++ *
++ * BRIEF MODULE DESCRIPTION
++ * AMD Alchemy Au1xxx IDE interface routines over the Static Bus
++ *
++ * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
++ *
++ * This program is free software; you can redistribute it and/or modify it under
++ * the terms of the 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 SOFTWARE IS PROVIDED ``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 AUTHOR
++ * 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.
++ *
++ * You 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.
++ *
++ * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
++ *       Interface and Linux Device Driver" Application Note.
++ */
++#undef REALLY_SLOW_IO           /* most systems can safely undef this */
++
++#include <linux/config.h>       /* for CONFIG_BLK_DEV_IDEPCI */
++#include <linux/types.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/timer.h>
++#include <linux/mm.h>
++#include <linux/ioport.h>
++#include <linux/hdreg.h>
++#include <linux/init.h>
++#include <linux/ide.h>
++#include <linux/sysdev.h>
++
++#include <linux/dma-mapping.h>
++
++#include <asm/io.h>
++#include <asm/mach-au1x00/au1xxx.h>
++#include <asm/mach-au1x00/au1xxx_dbdma.h>
++
++#if CONFIG_PM
++#include <asm/mach-au1x00/au1xxx_pm.h>
++#endif
++
++#include <asm/mach-au1x00/au1xxx_ide.h>
++
++#define DRV_NAME	"au1200-ide"
++#define DRV_VERSION	"1.0"
++#define DRV_AUTHOR	"AMD PCS / Pete Popov <ppopov at embeddedalley.com>"
++#define DRV_DESC	"Au1200 IDE"
++
++static _auide_hwif auide_hwif;
++static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED;
++static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED;
++static int dbdma_init_done = 0;
++
++/*
++ * local I/O functions
++ */
++u8 auide_inb(unsigned long port)
++{
++        return (au_readb(port));
++}
++
++u16 auide_inw(unsigned long port)
++{
++        return (au_readw(port));
++}
++
++u32 auide_inl(unsigned long port)
++{
++        return (au_readl(port));
++}
++
++void auide_insw(unsigned long port, void *addr, u32 count)
++{
++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
++
++        _auide_hwif *ahwif = &auide_hwif;
++        chan_tab_t *ctp;
++        au1x_ddma_desc_t *dp;
++
++        if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
++				DDMA_FLAGS_NOIE)) {
++                printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
++                return;
++        }
++        ctp = *((chan_tab_t **)ahwif->rx_chan);
++        dp = ctp->cur_ptr;
++        while (dp->dscr_cmd0 & DSCR_CMD0_V)
++                ;
++        ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
++#else
++        while (count--)
++        {
++                *(u16 *)addr = au_readw(port);
++                addr +=2 ;
++        }
++#endif
++}
++
++void auide_insl(unsigned long port, void *addr, u32 count)
++{
++        while (count--)
++        {
++                *(u32 *)addr = au_readl(port);
++                /* NOTE: For IDE interfaces over PCMCIA,
++                 * 32-bit access does not work
++                 */
++                addr += 4;
++        }
++}
++
++void auide_outb(u8 addr, unsigned long port)
++{
++        return (au_writeb(addr, port));
++}
++
++void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
++{
++        return (au_writeb(addr, port));
++}
++
++void auide_outw(u16 addr, unsigned long port)
++{
++        return (au_writew(addr, port));
++}
++
++void auide_outl(u32 addr, unsigned long port)
++{
++        return (au_writel(addr, port));
++}
++
++void auide_outsw(unsigned long port, void *addr, u32 count)
++{
++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
++        _auide_hwif *ahwif = &auide_hwif;
++        chan_tab_t *ctp;
++        au1x_ddma_desc_t *dp;
++
++        if(!put_source_flags(ahwif->tx_chan, (void*)addr,
++                                          count << 1, DDMA_FLAGS_NOIE)) {
++                printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
++                return;
++        }
++        ctp = *((chan_tab_t **)ahwif->tx_chan);
++        dp = ctp->cur_ptr;
++        while (dp->dscr_cmd0 & DSCR_CMD0_V)
++                ;
++        ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
++#else
++        while (count--)
++        {
++                au_writew(*(u16 *)addr, port);
++                addr += 2;
++        }
++#endif
++}
++
++void auide_outsl(unsigned long port, void *addr, u32 count)
++{
++        while (count--)
++        {
++                au_writel(*(u32 *)addr, port);
++                /* NOTE: For IDE interfaces over PCMCIA,
++                 * 32-bit access does not work
++                 */
++                addr += 4;
++        }
++}
++
++static void auide_tune_drive(ide_drive_t *drive, byte pio)
++{
++        int mem_sttime;
++        int mem_stcfg;
++        unsigned long flags;
++        u8 speed;
++
++        /* get the best pio mode for the drive */
++        pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
++
++        printk("%s: setting Au1XXX IDE to PIO mode%d\n",
++                drive->name, pio);
++
++        spin_lock_irqsave(&ide_tune_drive_spin_lock, flags);
++
++        mem_sttime = 0;
++        mem_stcfg  = au_readl(MEM_STCFG2);
++
++        /* set pio mode! */
++        switch(pio) {
++                case 0:
++                        /* set timing parameters for RCS2# */
++                        mem_sttime =   SBC_IDE_PIO0_TWCS
++                                     | SBC_IDE_PIO0_TCSH
++                                     | SBC_IDE_PIO0_TCSOFF
++                                     | SBC_IDE_PIO0_TWP
++                                     | SBC_IDE_PIO0_TCSW
++                                     | SBC_IDE_PIO0_TPM
++                                     | SBC_IDE_PIO0_TA;
++                        /* set configuration for RCS2# */
++                        mem_stcfg |= TS_MASK;
++                        mem_stcfg &= ~TCSOE_MASK;
++                        mem_stcfg &= ~TOECS_MASK;
++                        mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
++
++                        au_writel(mem_sttime,MEM_STTIME2);
++                        au_writel(mem_stcfg,MEM_STCFG2);
++                        break;
++
++                case 1:
++                        /* set timing parameters for RCS2# */
++                        mem_sttime =   SBC_IDE_PIO1_TWCS
++                                     | SBC_IDE_PIO1_TCSH
++                                     | SBC_IDE_PIO1_TCSOFF
++                                     | SBC_IDE_PIO1_TWP
++                                     | SBC_IDE_PIO1_TCSW
++                                     | SBC_IDE_PIO1_TPM
++                                     | SBC_IDE_PIO1_TA;
++                        /* set configuration for RCS2# */
++                        mem_stcfg |= TS_MASK;
++                        mem_stcfg &= ~TCSOE_MASK;
++                        mem_stcfg &= ~TOECS_MASK;
++                        mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
++                        break;
++
++                case 2:
++                        /* set timing parameters for RCS2# */
++                        mem_sttime =   SBC_IDE_PIO2_TWCS
++                                     | SBC_IDE_PIO2_TCSH
++                                     | SBC_IDE_PIO2_TCSOFF
++                                     | SBC_IDE_PIO2_TWP
++                                     | SBC_IDE_PIO2_TCSW
++                                     | SBC_IDE_PIO2_TPM
++                                     | SBC_IDE_PIO2_TA;
++                        /* set configuration for RCS2# */
++                        mem_stcfg &= ~TS_MASK;
++                        mem_stcfg &= ~TCSOE_MASK;
++                        mem_stcfg &= ~TOECS_MASK;
++                        mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
++                        break;
++
++                case 3:
++                        /* set timing parameters for RCS2# */
++                        mem_sttime =   SBC_IDE_PIO3_TWCS
++                                     | SBC_IDE_PIO3_TCSH
++                                     | SBC_IDE_PIO3_TCSOFF
++                                     | SBC_IDE_PIO3_TWP
++                                     | SBC_IDE_PIO3_TCSW
++                                     | SBC_IDE_PIO3_TPM
++                                     | SBC_IDE_PIO3_TA;
++                        /* set configuration for RCS2# */
++                        mem_stcfg |= TS_MASK;
++                        mem_stcfg &= ~TS_MASK;
++                        mem_stcfg &= ~TCSOE_MASK;
++                        mem_stcfg &= ~TOECS_MASK;
++                        mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
++
++                        break;
++
++                case 4:
++                        /* set timing parameters for RCS2# */
++                        mem_sttime =   SBC_IDE_PIO4_TWCS
++                                     | SBC_IDE_PIO4_TCSH
++                                     | SBC_IDE_PIO4_TCSOFF
++                                     | SBC_IDE_PIO4_TWP
++                                     | SBC_IDE_PIO4_TCSW
++                                     | SBC_IDE_PIO4_TPM
++                                     | SBC_IDE_PIO4_TA;
++                        /* set configuration for RCS2# */
++                        mem_stcfg &= ~TS_MASK;
++                        mem_stcfg &= ~TCSOE_MASK;
++                        mem_stcfg &= ~TOECS_MASK;
++                        mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
++                        break;
++        }
++
++        au_writel(mem_sttime,MEM_STTIME2);
++        au_writel(mem_stcfg,MEM_STCFG2);
++
++        spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags);
++
++        speed = pio + XFER_PIO_0;
++        ide_config_drive_speed(drive, speed);
++}
++
++static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
++{
++        u8 mode = 0;
++        int mem_sttime;
++        int mem_stcfg;
++        unsigned long flags;
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++        struct hd_driveid *id = drive->id;
++
++        /*
++         * Now see what the current drive is capable of,
++         * selecting UDMA only if the mate said it was ok.
++         */
++        if (id && (id->capability & 1) && drive->autodma &&
++            !__ide_dma_bad_drive(drive)) {
++                if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
++                        if      (id->dma_mword & 4)
++                                mode = XFER_MW_DMA_2;
++                        else if (id->dma_mword & 2)
++                                mode = XFER_MW_DMA_1;
++                        else if (id->dma_mword & 1)
++                                mode = XFER_MW_DMA_0;
++                }
++        }
++#endif
++
++        spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags);
++
++        mem_sttime = 0;
++        mem_stcfg  = au_readl(MEM_STCFG2);
++
++        switch(speed) {
++                case XFER_PIO_4:
++                case XFER_PIO_3:
++                case XFER_PIO_2:
++                case XFER_PIO_1:
++                case XFER_PIO_0:
++                        auide_tune_drive(drive, (speed - XFER_PIO_0));
++                        break;
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++                case XFER_MW_DMA_2:
++                        /* set timing parameters for RCS2# */
++                        mem_sttime =   SBC_IDE_MDMA2_TWCS
++                                     | SBC_IDE_MDMA2_TCSH
++                                     | SBC_IDE_MDMA2_TCSOFF
++                                     | SBC_IDE_MDMA2_TWP
++                                     | SBC_IDE_MDMA2_TCSW
++                                     | SBC_IDE_MDMA2_TPM
++                                     | SBC_IDE_MDMA2_TA;
++                        /* set configuration for RCS2# */
++                        mem_stcfg &= ~TS_MASK;
++                        mem_stcfg &= ~TCSOE_MASK;
++                        mem_stcfg &= ~TOECS_MASK;
++                        mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
++
++                        mode = XFER_MW_DMA_2;
++                        break;
++                case XFER_MW_DMA_1:
++                        /* set timing parameters for RCS2# */
++                        mem_sttime =   SBC_IDE_MDMA1_TWCS
++                                     | SBC_IDE_MDMA1_TCSH
++                                     | SBC_IDE_MDMA1_TCSOFF
++                                     | SBC_IDE_MDMA1_TWP
++                                     | SBC_IDE_MDMA1_TCSW
++                                     | SBC_IDE_MDMA1_TPM
++                                     | SBC_IDE_MDMA1_TA;
++                        /* set configuration for RCS2# */
++                        mem_stcfg &= ~TS_MASK;
++                        mem_stcfg &= ~TCSOE_MASK;
++                        mem_stcfg &= ~TOECS_MASK;
++                        mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
++
++                        mode = XFER_MW_DMA_1;
++                        break;
++                case XFER_MW_DMA_0:
++                        /* set timing parameters for RCS2# */
++                        mem_sttime =   SBC_IDE_MDMA0_TWCS
++                                     | SBC_IDE_MDMA0_TCSH
++                                     | SBC_IDE_MDMA0_TCSOFF
++                                     | SBC_IDE_MDMA0_TWP
++                                     | SBC_IDE_MDMA0_TCSW
++                                     | SBC_IDE_MDMA0_TPM
++                                     | SBC_IDE_MDMA0_TA;
++                        /* set configuration for RCS2# */
++                        mem_stcfg |= TS_MASK;
++                        mem_stcfg &= ~TCSOE_MASK;
++                        mem_stcfg &= ~TOECS_MASK;
++                        mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
++
++                        mode = XFER_MW_DMA_0;
++                        break;
++#endif
++                default:
++                        return 1;
++        }
++
++        /*
++         * Tell the drive to switch to the new mode; abort on failure.
++         */
++        if (!mode || ide_config_drive_speed(drive, mode))
++        {
++                return 1;       /* failure */
++        }
++
++
++        au_writel(mem_sttime,MEM_STTIME2);
++        au_writel(mem_stcfg,MEM_STCFG2);
++
++        spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags);
++
++        return 0;
++}
++
++/*
++ * Multi-Word DMA + DbDMA functions
++ */
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++
++static int in_drive_list(struct hd_driveid *id,
++                         const struct drive_list_entry *drive_table)
++{
++        for ( ; drive_table->id_model ; drive_table++){
++                if ((!strcmp(drive_table->id_model, id->model)) &&
++                        ((strstr(drive_table->id_firmware, id->fw_rev)) ||
++                        (!strcmp(drive_table->id_firmware, "ALL")))
++                )
++                        return 1;
++        }
++        return 0;
++}
++
++static int auide_build_sglist(ide_drive_t *drive,  struct request *rq)
++{
++        ide_hwif_t *hwif = drive->hwif;
++        _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
++        struct scatterlist *sg = hwif->sg_table;
++
++        ide_map_sg(drive, rq);
++
++        if (rq_data_dir(rq) == READ)
++                hwif->sg_dma_direction = DMA_FROM_DEVICE;
++        else
++                hwif->sg_dma_direction = DMA_TO_DEVICE;
++
++        return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
++                          hwif->sg_dma_direction);
++}
++
++static int auide_build_dmatable(ide_drive_t *drive)
++{
++        int i, iswrite, count = 0;
++        ide_hwif_t *hwif = HWIF(drive);
++
++        struct request *rq = HWGROUP(drive)->rq;
++
++        _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
++        struct scatterlist *sg;
++
++        iswrite = (rq_data_dir(rq) == WRITE);
++        /* Save for interrupt context */
++        ahwif->drive = drive;
++
++        /* Build sglist */
++        hwif->sg_nents = i = auide_build_sglist(drive, rq);
++
++        if (!i)
++                return 0;
++
++        /* fill the descriptors */
++        sg = hwif->sg_table;
++        while (i && sg_dma_len(sg)) {
++                u32 cur_addr;
++                u32 cur_len;
++
++                cur_addr = sg_dma_address(sg);
++                cur_len = sg_dma_len(sg);
++
++                while (cur_len) {
++                        u32 flags = DDMA_FLAGS_NOIE;
++                        unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
++
++                        if (++count >= PRD_ENTRIES) {
++                                printk(KERN_WARNING "%s: DMA table too small\n",
++                                drive->name);
++                                goto use_pio_instead;
++                        }
++
++                        /* Lets enable intr for the last descriptor only */
++                        if (1==i)
++                                flags = DDMA_FLAGS_IE;
++                        else
++                                flags = DDMA_FLAGS_NOIE;
++
++                        if (iswrite) {
++				if(!put_source_flags(ahwif->tx_chan,
++						(void*)(page_address(sg->page)
++							+ sg->offset),
++						tc, flags)) {
++					printk(KERN_ERR "%s failed %d\n",
++							__FUNCTION__, __LINE__);
++				}
++                        } else
++			{
++				if(!put_dest_flags(ahwif->rx_chan,
++						(void*)(page_address(sg->page)
++							+ sg->offset),
++						tc, flags)) {
++					printk(KERN_ERR "%s failed %d\n",
++							__FUNCTION__, __LINE__);
++				}
++                        }
++
++                        cur_addr += tc;
++                        cur_len -= tc;
++                }
++                sg++;
++                i--;
++        }
++
++        if (count)
++                return 1;
++
++use_pio_instead:
++        dma_unmap_sg(ahwif->dev,
++                     hwif->sg_table,
++                     hwif->sg_nents,
++                     hwif->sg_dma_direction);
++
++        return 0; /* revert to PIO for this request */
++}
++
++static int auide_dma_end(ide_drive_t *drive)
++{
++        ide_hwif_t *hwif = HWIF(drive);
++        _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
++
++        if (hwif->sg_nents) {
++                dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
++                             hwif->sg_dma_direction);
++                hwif->sg_nents = 0;
++        }
++
++        return 0;
++}
++
++static void auide_dma_start(ide_drive_t *drive )
++{
++//      printk("%s\n", __FUNCTION__);
++}
++
++ide_startstop_t auide_dma_intr(ide_drive_t *drive)
++{
++        //printk("%s\n", __FUNCTION__);
++
++        u8 stat = 0, dma_stat = 0;
++
++        dma_stat = HWIF(drive)->ide_dma_end(drive);
++        stat = HWIF(drive)->INB(IDE_STATUS_REG);        /* get drive status */
++        if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
++                if (!dma_stat) {
++                        struct request *rq = HWGROUP(drive)->rq;
++
++                        ide_end_request(drive, 1, rq->nr_sectors);
++                        return ide_stopped;
++                }
++                printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
++                                 drive->name, dma_stat);
++        }
++        return ide_error(drive, "dma_intr", stat);
++}
++
++static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
++{
++        //printk("%s\n", __FUNCTION__);
++
++        /* issue cmd to drive */
++        ide_execute_command(drive, command, &auide_dma_intr,
++                            (2*WAIT_CMD), NULL);
++}
++
++static int auide_dma_setup(ide_drive_t *drive)
++{
++//      printk("%s\n", __FUNCTION__);
++
++        if (drive->media != ide_disk)
++                return 1;
++
++        if (!auide_build_dmatable(drive))
++                        /* try PIO instead of DMA */
++                        return 1;
++
++        drive->waiting_for_dma = 1;
++
++        return 0;
++}
++
++static int auide_dma_check(ide_drive_t *drive)
++{
++//      printk("%s\n", __FUNCTION__);
++
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++        if( !dbdma_init_done ){
++                auide_hwif.white_list = in_drive_list(drive->id,
++                                                      dma_white_list);
++                auide_hwif.black_list = in_drive_list(drive->id,
++                                                      dma_black_list);
++                auide_hwif.drive = drive;
++                auide_ddma_init(&auide_hwif);
++                dbdma_init_done = 1;
++        }
++#endif
++
++        /* Is the drive in our DMA black list? */
++        if ( auide_hwif.black_list ) {
++                drive->using_dma = 0;
++                printk("%s found in dma_blacklist[]! Disabling DMA.\n",
++                drive->id->model);
++        }
++        else
++                drive->using_dma = 1;
++
++        return HWIF(drive)->ide_dma_host_on(drive);
++}
++
++static int auide_dma_test_irq(ide_drive_t *drive)
++{
++//      printk("%s\n", __FUNCTION__);
++
++        if (!drive->waiting_for_dma)
++                printk(KERN_WARNING "%s: ide_dma_test_irq \
++                                     called while not waiting\n", drive->name);
++
++        /* If dbdma didn't execute the STOP command yet, the
++         * active bit is still set
++	 */
++        drive->waiting_for_dma++;
++        if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
++                printk(KERN_WARNING "%s: timeout waiting for ddma to \
++                                     complete\n", drive->name);
++                return 1;
++        }
++        udelay(10);
++        return 0;
++}
++
++static int auide_dma_host_on(ide_drive_t *drive)
++{
++//      printk("%s\n", __FUNCTION__);
++        return 0;
++}
++
++static int auide_dma_on(ide_drive_t *drive)
++{
++//      printk("%s\n", __FUNCTION__);
++        drive->using_dma = 1;
++        return auide_dma_host_on(drive);
++}
++
++
++static int auide_dma_host_off(ide_drive_t *drive)
++{
++//      printk("%s\n", __FUNCTION__);
++        return 0;
++}
++
++static int auide_dma_off_quietly(ide_drive_t *drive)
++{
++//      printk("%s\n", __FUNCTION__);
++        drive->using_dma = 0;
++        return auide_dma_host_off(drive);
++}
++
++static int auide_dma_lostirq(ide_drive_t *drive)
++{
++//      printk("%s\n", __FUNCTION__);
++
++        printk(KERN_ERR "%s: IRQ lost\n", drive->name);
++        return 0;
++}
++
++static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs)
++{
++//      printk("%s\n", __FUNCTION__);
++
++        _auide_hwif *ahwif = (_auide_hwif*)param;
++        ahwif->drive->waiting_for_dma = 0;
++        return;
++}
++
++static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs)
++{
++//      printk("%s\n", __FUNCTION__);
++
++        _auide_hwif *ahwif = (_auide_hwif*)param;
++        ahwif->drive->waiting_for_dma = 0;
++        return;
++}
++
++static int auide_dma_timeout(ide_drive_t *drive)
++{
++//      printk("%s\n", __FUNCTION__);
++
++        printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
++
++        if (HWIF(drive)->ide_dma_test_irq(drive))
++                return 0;
++
++        return HWIF(drive)->ide_dma_end(drive);
++}
++#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
++
++
++static int auide_ddma_init( _auide_hwif *auide )
++{
++//      printk("%s\n", __FUNCTION__);
++
++        dbdev_tab_t source_dev_tab;
++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
++        dbdev_tab_t target_dev_tab;
++        ide_hwif_t *hwif = auide->hwif;
++        char warning_output [2][80];
++        int i;
++#endif
++
++        /* Add our custom device to DDMA device table */
++        /* Create our new device entries in the table */
++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
++        source_dev_tab.dev_id = AU1XXX_ATA_DDMA_REQ;
++
++        if( auide->white_list || auide->black_list ){
++                source_dev_tab.dev_tsize       = 8;
++                source_dev_tab.dev_devwidth    = 32;
++                source_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
++                source_dev_tab.dev_intlevel    = 0;
++                source_dev_tab.dev_intpolarity = 0;
++
++                /* init device table for target - static bus controller - */
++                target_dev_tab.dev_id          = DSCR_CMD0_ALWAYS;
++                target_dev_tab.dev_tsize       = 8;
++                target_dev_tab.dev_devwidth    = 32;
++                target_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
++                target_dev_tab.dev_intlevel    = 0;
++                target_dev_tab.dev_intpolarity = 0;
++                target_dev_tab.dev_flags       = DEV_FLAGS_ANYUSE;
++        }
++        else{
++                source_dev_tab.dev_tsize       = 1;
++                source_dev_tab.dev_devwidth    = 16;
++                source_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
++                source_dev_tab.dev_intlevel    = 0;
++                source_dev_tab.dev_intpolarity = 0;
++
++                /* init device table for target - static bus controller - */
++                target_dev_tab.dev_id          = DSCR_CMD0_ALWAYS;
++                target_dev_tab.dev_tsize       = 1;
++                target_dev_tab.dev_devwidth    = 16;
++                target_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
++                target_dev_tab.dev_intlevel    = 0;
++                target_dev_tab.dev_intpolarity = 0;
++                target_dev_tab.dev_flags       = DEV_FLAGS_ANYUSE;
++
++                sprintf(&warning_output[0][0],
++                        "%s is not on ide driver white list.",
++                        auide_hwif.drive->id->model);
++                for ( i=strlen(&warning_output[0][0]) ; i<76; i++ ){
++                        sprintf(&warning_output[0][i]," ");
++                }
++
++                sprintf(&warning_output[1][0],
++                "To add %s please read 'Documentation/mips/AU1xxx_IDE.README'.",
++                        auide_hwif.drive->id->model);
++                for ( i=strlen(&warning_output[1][0]) ; i<76; i++ ){
++                        sprintf(&warning_output[1][i]," ");
++                }
++
++                printk("\n****************************************");
++                printk("****************************************\n");
++                printk("* %s *\n",&warning_output[0][0]);
++                printk("* Switch to safe MWDMA Mode!            ");
++                printk("                                       *\n");
++                printk("* %s *\n",&warning_output[1][0]);
++                printk("****************************************");
++                printk("****************************************\n\n");
++        }
++#else
++        source_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
++        source_dev_tab.dev_tsize       = 8;
++        source_dev_tab.dev_devwidth    = 32;
++        source_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
++        source_dev_tab.dev_intlevel    = 0;
++        source_dev_tab.dev_intpolarity = 0;
++#endif
++
++#if CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
++        /* set flags for tx channel */
++        source_dev_tab.dev_flags =  DEV_FLAGS_OUT
++                                  | DEV_FLAGS_SYNC
++                                  | DEV_FLAGS_BURSTABLE;
++        auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
++        /* set flags for rx channel */
++        source_dev_tab.dev_flags =  DEV_FLAGS_IN
++                                  | DEV_FLAGS_SYNC
++                                  | DEV_FLAGS_BURSTABLE;
++        auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
++#else
++        /* set flags for tx channel */
++        source_dev_tab.dev_flags = DEV_FLAGS_OUT | DEV_FLAGS_SYNC;
++        auide->tx_dev_id         = au1xxx_ddma_add_device( &source_dev_tab );
++        /* set flags for rx channel */
++        source_dev_tab.dev_flags = DEV_FLAGS_IN | DEV_FLAGS_SYNC;
++        auide->rx_dev_id         = au1xxx_ddma_add_device( &source_dev_tab );
++#endif
++
++#if  defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
++
++        auide->target_dev_id           = au1xxx_ddma_add_device(&target_dev_tab);
++
++        /* Get a channel for TX */
++        auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
++                                                 auide->tx_dev_id,
++                                                 auide_ddma_tx_callback,
++                                                 (void*)auide);
++        /* Get a channel for RX */
++        auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
++                                                 auide->target_dev_id,
++                                                 auide_ddma_rx_callback,
++                                                 (void*)auide);
++#else   /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
++        /*
++         * Note: if call back is not enabled, update ctp->cur_ptr manually
++         */
++        auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
++                                                 auide->tx_dev_id,
++                                                 NULL,
++                                                 (void*)auide);
++        auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
++                                                 DSCR_CMD0_ALWAYS,
++                                                 NULL,
++                                                 (void*)auide);
++#endif
++        auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
++                                                             NUM_DESCRIPTORS);
++        auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
++                                                             NUM_DESCRIPTORS);
++
++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
++        hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
++                                                PRD_ENTRIES * PRD_BYTES,        /* 1 Page */
++                                                &hwif->dmatable_dma, GFP_KERNEL);
++
++        auide->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
++                                GFP_KERNEL|GFP_DMA);
++        if (auide->sg_table == NULL) {
++                return -ENOMEM;
++        }
++#endif
++        au1xxx_dbdma_start( auide->tx_chan );
++        au1xxx_dbdma_start( auide->rx_chan );
++        return 0;
++}
++
++static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
++{
++        int i;
++#define ide_ioreg_t unsigned long
++        ide_ioreg_t *ata_regs = hw->io_ports;
++
++	/* fixme */
++        for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
++                *ata_regs++ = (ide_ioreg_t) ahwif->regbase
++                            + (ide_ioreg_t)(i << AU1XXX_ATA_REG_OFFSET);
++        }
++
++        /* set the Alternative Status register */
++        *ata_regs = (ide_ioreg_t) ahwif->regbase
++                  + (ide_ioreg_t)(14 << AU1XXX_ATA_REG_OFFSET);
++}
++
++static int au_ide_probe(struct device *dev)
++{
++	struct platform_device *pdev = to_platform_device(dev);
++        _auide_hwif *ahwif = &auide_hwif;
++        ide_hwif_t *hwif;
++	struct resource *res;
++	int ret = 0;
++
++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
++        char *mode = "MWDMA2";
++#elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
++        char *mode = "PIO+DDMA(offload)";
++#endif
++
++        memset(&auide_hwif, 0, sizeof(_auide_hwif));
++        auide_hwif.dev                  = 0;
++
++	ahwif->dev = dev;
++	ahwif->irq = platform_get_irq(pdev, 0);
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++	if (res == NULL) {
++		pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id);
++		ret = -ENODEV;
++		goto out;
++	}
++
++        if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
++		pr_debug("%s: request_mem_region failed\n", DRV_NAME);
++                ret =  -EBUSY;
++		goto out;
++        }
++
++	ahwif->regbase = (u32)ioremap(res->start, res->end-res->start);
++	if (ahwif->regbase == 0) {
++		ret = -ENOMEM;
++		goto out;
++	}
++
++        hwif                            = &ide_hwifs[pdev->id];
++	hw_regs_t *hw 			= &hwif->hw;
++        hwif->irq = hw->irq             = ahwif->irq;
++        hwif->chipset                   = ide_au1xxx;
++
++        auide_setup_ports(hw, ahwif);
++	memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
++
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
++        hwif->rqsize = CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ;
++        hwif->rqsize                    = ((hwif->rqsize > AU1XXX_ATA_RQSIZE)
++                                        || (hwif->rqsize < 32)) ? AU1XXX_ATA_RQSIZE : hwif->rqsize;
++#else /* if kernel config is not set */
++        hwif->rqsize                    = AU1XXX_ATA_RQSIZE;
++#endif
++
++        hwif->ultra_mask                = 0x0;  /* Disable Ultra DMA */
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++        hwif->mwdma_mask                = 0x07; /* Multimode-2 DMA  */
++        hwif->swdma_mask                = 0x07;
++#else
++        hwif->mwdma_mask                = 0x0;
++        hwif->swdma_mask                = 0x0;
++#endif
++        //hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
++        hwif->noprobe = 0;
++        hwif->drives[0].unmask          = 1;
++        hwif->drives[1].unmask          = 1;
++
++        /* hold should be on in all cases */
++        hwif->hold                      = 1;
++        hwif->mmio                      = 2;
++
++        /* set up local I/O function entry points */
++        hwif->INB                       = auide_inb;
++        hwif->INW                       = auide_inw;
++        hwif->INL                       = auide_inl;
++        hwif->INSW                      = auide_insw;
++        hwif->INSL                      = auide_insl;
++        hwif->OUTB                      = auide_outb;
++        hwif->OUTBSYNC                  = auide_outbsync;
++        hwif->OUTW                      = auide_outw;
++        hwif->OUTL                      = auide_outl;
++        hwif->OUTSW                     = auide_outsw;
++        hwif->OUTSL                     = auide_outsl;
++
++        hwif->tuneproc                  = &auide_tune_drive;
++        hwif->speedproc                 = &auide_tune_chipset;
++
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++        hwif->ide_dma_off_quietly       = &auide_dma_off_quietly;
++        hwif->ide_dma_timeout           = &auide_dma_timeout;
++
++        hwif->ide_dma_check             = &auide_dma_check;
++        hwif->dma_exec_cmd              = &auide_dma_exec_cmd;
++        hwif->dma_start                 = &auide_dma_start;
++        hwif->ide_dma_end               = &auide_dma_end;
++        hwif->dma_setup                 = &auide_dma_setup;
++        hwif->ide_dma_test_irq          = &auide_dma_test_irq;
++        hwif->ide_dma_host_off          = &auide_dma_host_off;
++        hwif->ide_dma_host_on           = &auide_dma_host_on;
++        hwif->ide_dma_lostirq           = &auide_dma_lostirq;
++        hwif->ide_dma_on                = &auide_dma_on;
++
++        hwif->autodma                   = 1;
++        hwif->drives[0].autodma         = hwif->autodma;
++        hwif->drives[1].autodma         = hwif->autodma;
++        hwif->atapi_dma                 = 1;
++        hwif->drives[0].using_dma       = 1;
++        hwif->drives[1].using_dma       = 1;
++#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
++        hwif->autodma                   = 0;
++        hwif->channel                   = 0;
++        hwif->hold                      = 1;
++        hwif->select_data               = 0;    /* no chipset-specific code */
++        hwif->config_data               = 0;    /* no chipset-specific code */
++
++        hwif->drives[0].autodma         = 0;
++        hwif->drives[0].drive_data      = 0;    /* no drive data */
++        hwif->drives[0].using_dma       = 0;
++        hwif->drives[0].waiting_for_dma = 0;
++        hwif->drives[0].autotune        = 1;    /* 1=autotune, 2=noautotune, 0=default */
++        /* secondary hdd not supported */
++        hwif->drives[1].autodma         = 0;
++
++        hwif->drives[1].drive_data      = 0;
++        hwif->drives[1].using_dma       = 0;
++        hwif->drives[1].waiting_for_dma = 0;
++        hwif->drives[1].autotune        = 2;   /* 1=autotune, 2=noautotune, 0=default */
++#endif
++        hwif->drives[0].io_32bit        = 0;   /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
++        hwif->drives[1].io_32bit        = 0;   /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
++
++        /*Register Driver with PM Framework*/
++#ifdef CONFIG_PM
++        auide_hwif.pm.lock    = SPIN_LOCK_UNLOCKED;
++        auide_hwif.pm.stopped = 0;
++
++        auide_hwif.pm.dev = new_au1xxx_power_device( "ide",
++                                                &au1200ide_pm_callback,
++                                                NULL);
++        if ( auide_hwif.pm.dev == NULL )
++                printk(KERN_INFO "Unable to create a power management \
++                                device entry for the au1200-IDE.\n");
++        else
++                printk(KERN_INFO "Power management device entry for the \
++                                au1200-IDE loaded.\n");
++#endif
++
++        auide_hwif.hwif                 = hwif;
++        hwif->hwif_data                 = &auide_hwif;
++
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
++        auide_ddma_init(&auide_hwif);
++        dbdma_init_done = 1;
++#endif
++
++	probe_hwif_init(hwif);
++	dev_set_drvdata(dev, hwif);
++
++        printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
++
++out:
++        return ret;
++}
++
++static int au_ide_remove(struct device *dev)
++{
++	struct platform_device *pdev = to_platform_device(dev);
++	struct resource *res;
++	ide_hwif_t *hwif = dev_get_drvdata(dev);
++        _auide_hwif *ahwif = &auide_hwif;
++
++	ide_unregister(hwif - ide_hwifs);
++
++	iounmap((void *)ahwif->regbase);
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	release_mem_region(res->start, res->end - res->start);
++
++	return 0;
++}
++
++static struct device_driver au1200_ide_driver = {
++	.name		= "au1200-ide",
++	.bus		= &platform_bus_type,
++	.probe 		= au_ide_probe,
++	.remove		= au_ide_remove,
++};
++
++static int __init au_ide_init(void)
++{
++	return driver_register(&au1200_ide_driver);
++}
++
++static void __init au_ide_exit(void)
++{
++	driver_unregister(&au1200_ide_driver);
++}
++
++#ifdef CONFIG_PM
++int au1200ide_pm_callback( au1xxx_power_dev_t *dev,\
++                        au1xxx_request_t request, void *data) {
++
++        unsigned int d, err = 0;
++        unsigned long flags;
++
++        spin_lock_irqsave(auide_hwif.pm.lock, flags);
++
++        switch (request){
++                case AU1XXX_PM_SLEEP:
++                        err = au1xxxide_pm_sleep(dev);
++                        break;
++                case AU1XXX_PM_WAKEUP:
++                        d = *((unsigned int*)data);
++                        if ( d > 0 && d <= 99) {
++                                err = au1xxxide_pm_standby(dev);
++                        }
++                        else {
++                                err = au1xxxide_pm_resume(dev);
++                        }
++                        break;
++                case AU1XXX_PM_GETSTATUS:
++                        err = au1xxxide_pm_getstatus(dev);
++                        break;
++                case AU1XXX_PM_ACCESS:
++                        err = au1xxxide_pm_access(dev);
++                        break;
++                case AU1XXX_PM_IDLE:
++                        err = au1xxxide_pm_idle(dev);
++                        break;
++                case AU1XXX_PM_CLEANUP:
++                        err = au1xxxide_pm_cleanup(dev);
++                        break;
++                default:
++                        err = -1;
++                        break;
++        }
++
++        spin_unlock_irqrestore(auide_hwif.pm.lock, flags);
++
++        return err;
++}
++
++static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ) {
++        return 0;
++}
++
++static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ) {
++
++        int retval;
++        ide_hwif_t *hwif = auide_hwif.hwif;
++        struct request rq;
++        struct request_pm_state rqpm;
++        ide_task_t args;
++
++        if(auide_hwif.pm.stopped)
++                return -1;
++
++        /*
++         * wait until hard disc is ready
++         */
++        if ( wait_for_ready(&hwif->drives[0], 35000) ) {
++                printk("Wait for drive sleep timeout!\n");
++                retval = -1;
++        }
++
++        /*
++         * sequenz to tell the high level ide driver that pm is resuming
++         */
++        memset(&rq, 0, sizeof(rq));
++        memset(&rqpm, 0, sizeof(rqpm));
++        memset(&args, 0, sizeof(args));
++        rq.flags = REQ_PM_SUSPEND;
++        rq.special = &args;
++        rq.pm = &rqpm;
++        rqpm.pm_step = ide_pm_state_start_suspend;
++        rqpm.pm_state = PMSG_SUSPEND;
++
++        retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_wait);
++
++        if (wait_for_ready (&hwif->drives[0], 35000)) {
++                printk("Wait for drive sleep timeout!\n");
++                retval = -1;
++        }
++
++        /*
++         * stop dbdma channels
++         */
++        au1xxx_dbdma_reset(auide_hwif.tx_chan);
++        au1xxx_dbdma_reset(auide_hwif.rx_chan);
++
++        auide_hwif.pm.stopped = 1;
++
++        return retval;
++}
++
++static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ) {
++
++        int retval;
++        ide_hwif_t *hwif = auide_hwif.hwif;
++        struct request rq;
++        struct request_pm_state rqpm;
++        ide_task_t args;
++
++        if(!auide_hwif.pm.stopped)
++                return -1;
++
++        /*
++         * start dbdma channels
++         */
++        au1xxx_dbdma_start(auide_hwif.tx_chan);
++        au1xxx_dbdma_start(auide_hwif.rx_chan);
++
++        /*
++         * wait until hard disc is ready
++         */
++        if (wait_for_ready ( &hwif->drives[0], 35000)) {
++                printk("Wait for drive wake up timeout!\n");
++                retval = -1;
++        }
++
++        /*
++         * sequenz to tell the high level ide driver that pm is resuming
++         */
++        memset(&rq, 0, sizeof(rq));
++        memset(&rqpm, 0, sizeof(rqpm));
++        memset(&args, 0, sizeof(args));
++        rq.flags = REQ_PM_RESUME;
++        rq.special = &args;
++        rq.pm = &rqpm;
++        rqpm.pm_step = ide_pm_state_start_resume;
++        rqpm.pm_state = PMSG_ON;
++
++        retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_head_wait);
++
++        /*
++        * wait for hard disc
++        */
++        if ( wait_for_ready(&hwif->drives[0], 35000) ) {
++                printk("Wait for drive wake up timeout!\n");
++                retval = -1;
++        }
++
++        auide_hwif.pm.stopped = 0;
++
++        return retval;
++}
++
++static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ) {
++        return dev->cur_state;
++}
++
++static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ) {
++        if (dev->cur_state != AWAKE_STATE)
++                return 0;
++        else
++                return -1;
++}
++
++static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ) {
++        return 0;
++}
++
++static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ) {
++        return 0;
++}
++#endif /* CONFIG_PM */
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("AU1200 IDE driver");
++
++module_init(au_ide_init);
++module_exit(au_ide_exit);
+diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
+--- a/drivers/ide/ppc/pmac.c
++++ b/drivers/ide/ppc/pmac.c
+@@ -81,7 +81,7 @@ typedef struct pmac_ide_hwif {
+ 	
+ } pmac_ide_hwif_t;
+ 
+-static pmac_ide_hwif_t pmac_ide[MAX_HWIFS] __pmacdata;
++static pmac_ide_hwif_t pmac_ide[MAX_HWIFS];
+ static int pmac_ide_count;
+ 
+ enum {
+@@ -242,7 +242,7 @@ struct mdma_timings_t {
+ 	int	cycleTime;
+ };
+ 
+-struct mdma_timings_t mdma_timings_33[] __pmacdata =
++struct mdma_timings_t mdma_timings_33[] =
+ {
+     { 240, 240, 480 },
+     { 180, 180, 360 },
+@@ -255,7 +255,7 @@ struct mdma_timings_t mdma_timings_33[] 
+     {   0,   0,   0 }
+ };
+ 
+-struct mdma_timings_t mdma_timings_33k[] __pmacdata =
++struct mdma_timings_t mdma_timings_33k[] =
+ {
+     { 240, 240, 480 },
+     { 180, 180, 360 },
+@@ -268,7 +268,7 @@ struct mdma_timings_t mdma_timings_33k[]
+     {   0,   0,   0 }
+ };
+ 
+-struct mdma_timings_t mdma_timings_66[] __pmacdata =
++struct mdma_timings_t mdma_timings_66[] =
+ {
+     { 240, 240, 480 },
+     { 180, 180, 360 },
+@@ -286,7 +286,7 @@ struct {
+ 	int	addrSetup; /* ??? */
+ 	int	rdy2pause;
+ 	int	wrDataSetup;
+-} kl66_udma_timings[] __pmacdata =
++} kl66_udma_timings[] =
+ {
+     {   0, 180,  120 },	/* Mode 0 */
+     {   0, 150,  90 },	/*      1 */
+@@ -301,7 +301,7 @@ struct kauai_timing {
+ 	u32	timing_reg;
+ };
+ 
+-static struct kauai_timing	kauai_pio_timings[] __pmacdata =
++static struct kauai_timing	kauai_pio_timings[] =
+ {
+ 	{ 930	, 0x08000fff },
+ 	{ 600	, 0x08000a92 },
+@@ -316,7 +316,7 @@ static struct kauai_timing	kauai_pio_tim
+ 	{ 120	, 0x04000148 }
+ };
+ 
+-static struct kauai_timing	kauai_mdma_timings[] __pmacdata =
++static struct kauai_timing	kauai_mdma_timings[] =
+ {
+ 	{ 1260	, 0x00fff000 },
+ 	{ 480	, 0x00618000 },
+@@ -330,7 +330,7 @@ static struct kauai_timing	kauai_mdma_ti
+ 	{ 0	, 0 },
+ };
+ 
+-static struct kauai_timing	kauai_udma_timings[] __pmacdata =
++static struct kauai_timing	kauai_udma_timings[] =
+ {
+ 	{ 120	, 0x000070c0 },
+ 	{ 90	, 0x00005d80 },
+@@ -341,7 +341,7 @@ static struct kauai_timing	kauai_udma_ti
+ 	{ 0	, 0 },
+ };
+ 
+-static struct kauai_timing	shasta_pio_timings[] __pmacdata =
++static struct kauai_timing	shasta_pio_timings[] =
+ {
+ 	{ 930	, 0x08000fff },
+ 	{ 600	, 0x0A000c97 },
+@@ -356,7 +356,7 @@ static struct kauai_timing	shasta_pio_ti
+ 	{ 120	, 0x0400010a }
+ };
+ 
+-static struct kauai_timing	shasta_mdma_timings[] __pmacdata =
++static struct kauai_timing	shasta_mdma_timings[] =
+ {
+ 	{ 1260	, 0x00fff000 },
+ 	{ 480	, 0x00820800 },
+@@ -370,7 +370,7 @@ static struct kauai_timing	shasta_mdma_t
+ 	{ 0	, 0 },
+ };
+ 
+-static struct kauai_timing	shasta_udma133_timings[] __pmacdata =
++static struct kauai_timing	shasta_udma133_timings[] =
+ {
+ 	{ 120   , 0x00035901, },
+ 	{ 90    , 0x000348b1, },
+@@ -522,7 +522,7 @@ pmu_hd_blink_init(void)
+  * N.B. this can't be an initfunc, because the media-bay task can
+  * call ide_[un]register at any time.
+  */
+-void __pmac
++void
+ pmac_ide_init_hwif_ports(hw_regs_t *hw,
+ 			      unsigned long data_port, unsigned long ctrl_port,
+ 			      int *irq)
+@@ -559,7 +559,7 @@ pmac_ide_init_hwif_ports(hw_regs_t *hw,
+  * timing register when selecting that unit. This version is for
+  * ASICs with a single timing register
+  */
+-static void __pmac
++static void
+ pmac_ide_selectproc(ide_drive_t *drive)
+ {
+ 	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+@@ -579,7 +579,7 @@ pmac_ide_selectproc(ide_drive_t *drive)
+  * timing register when selecting that unit. This version is for
+  * ASICs with a dual timing register (Kauai)
+  */
+-static void __pmac
++static void
+ pmac_ide_kauai_selectproc(ide_drive_t *drive)
+ {
+ 	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+@@ -600,7 +600,7 @@ pmac_ide_kauai_selectproc(ide_drive_t *d
+ /*
+  * Force an update of controller timing values for a given drive
+  */
+-static void __pmac
++static void
+ pmac_ide_do_update_timings(ide_drive_t *drive)
+ {
+ 	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+@@ -633,7 +633,7 @@ pmac_outbsync(ide_drive_t *drive, u8 val
+  * to sort that out sooner or later and see if I can finally get the
+  * common version to work properly in all cases
+  */
+-static int __pmac
++static int
+ pmac_ide_do_setfeature(ide_drive_t *drive, u8 command)
+ {
+ 	ide_hwif_t *hwif = HWIF(drive);
+@@ -710,7 +710,7 @@ out:
+ /*
+  * Old tuning functions (called on hdparm -p), sets up drive PIO timings
+  */
+-static void __pmac
++static void
+ pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
+ {
+ 	ide_pio_data_t d;
+@@ -801,7 +801,7 @@ pmac_ide_tuneproc(ide_drive_t *drive, u8
+ /*
+  * Calculate KeyLargo ATA/66 UDMA timings
+  */
+-static int __pmac
++static int
+ set_timings_udma_ata4(u32 *timings, u8 speed)
+ {
+ 	unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks;
+@@ -829,7 +829,7 @@ set_timings_udma_ata4(u32 *timings, u8 s
+ /*
+  * Calculate Kauai ATA/100 UDMA timings
+  */
+-static int __pmac
++static int
+ set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed)
+ {
+ 	struct ide_timing *t = ide_timing_find_mode(speed);
+@@ -849,7 +849,7 @@ set_timings_udma_ata6(u32 *pio_timings, 
+ /*
+  * Calculate Shasta ATA/133 UDMA timings
+  */
+-static int __pmac
++static int
+ set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed)
+ {
+ 	struct ide_timing *t = ide_timing_find_mode(speed);
+@@ -869,7 +869,7 @@ set_timings_udma_shasta(u32 *pio_timings
+ /*
+  * Calculate MDMA timings for all cells
+  */
+-static int __pmac
++static int
+ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
+ 			u8 speed, int drive_cycle_time)
+ {
+@@ -1014,7 +1014,7 @@ set_timings_mdma(ide_drive_t *drive, int
+  * our dedicated function is more precise as it uses the drive provided
+  * cycle time value. We should probably fix this one to deal with that too...
+  */
+-static int __pmac
++static int
+ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
+ {
+ 	int unit = (drive->select.b.unit & 0x01);
+@@ -1092,7 +1092,7 @@ pmac_ide_tune_chipset (ide_drive_t *driv
+  * Blast some well known "safe" values to the timing registers at init or
+  * wakeup from sleep time, before we do real calculation
+  */
+-static void __pmac
++static void
+ sanitize_timings(pmac_ide_hwif_t *pmif)
+ {
+ 	unsigned int value, value2 = 0;
+@@ -1123,13 +1123,13 @@ sanitize_timings(pmac_ide_hwif_t *pmif)
+ 	pmif->timings[2] = pmif->timings[3] = value2;
+ }
+ 
+-unsigned long __pmac
++unsigned long
+ pmac_ide_get_base(int index)
+ {
+ 	return pmac_ide[index].regbase;
+ }
+ 
+-int __pmac
++int
+ pmac_ide_check_base(unsigned long base)
+ {
+ 	int ix;
+@@ -1140,7 +1140,7 @@ pmac_ide_check_base(unsigned long base)
+ 	return -1;
+ }
+ 
+-int __pmac
++int
+ pmac_ide_get_irq(unsigned long base)
+ {
+ 	int ix;
+@@ -1151,7 +1151,7 @@ pmac_ide_get_irq(unsigned long base)
+ 	return 0;
+ }
+ 
+-static int ide_majors[]  __pmacdata = { 3, 22, 33, 34, 56, 57 };
++static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };
+ 
+ dev_t __init
+ pmac_find_ide_boot(char *bootdevice, int n)
+@@ -1701,7 +1701,7 @@ pmac_ide_probe(void)
+  * pmac_ide_build_dmatable builds the DBDMA command list
+  * for a transfer and sets the DBDMA channel to point to it.
+  */
+-static int __pmac
++static int
+ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+ {
+ 	struct dbdma_cmd *table;
+@@ -1785,7 +1785,7 @@ pmac_ide_build_dmatable(ide_drive_t *dri
+ }
+ 
+ /* Teardown mappings after DMA has completed.  */
+-static void __pmac
++static void
+ pmac_ide_destroy_dmatable (ide_drive_t *drive)
+ {
+ 	ide_hwif_t *hwif = drive->hwif;
+@@ -1802,7 +1802,7 @@ pmac_ide_destroy_dmatable (ide_drive_t *
+ /*
+  * Pick up best MDMA timing for the drive and apply it
+  */
+-static int __pmac
++static int
+ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode)
+ {
+ 	ide_hwif_t *hwif = HWIF(drive);
+@@ -1859,7 +1859,7 @@ pmac_ide_mdma_enable(ide_drive_t *drive,
+ /*
+  * Pick up best UDMA timing for the drive and apply it
+  */
+-static int __pmac
++static int
+ pmac_ide_udma_enable(ide_drive_t *drive, u16 mode)
+ {
+ 	ide_hwif_t *hwif = HWIF(drive);
+@@ -1915,7 +1915,7 @@ pmac_ide_udma_enable(ide_drive_t *drive,
+  * Check what is the best DMA timing setting for the drive and
+  * call appropriate functions to apply it.
+  */
+-static int __pmac
++static int
+ pmac_ide_dma_check(ide_drive_t *drive)
+ {
+ 	struct hd_driveid *id = drive->id;
+@@ -1967,7 +1967,7 @@ pmac_ide_dma_check(ide_drive_t *drive)
+  * Prepare a DMA transfer. We build the DMA table, adjust the timings for
+  * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
+  */
+-static int __pmac
++static int
+ pmac_ide_dma_setup(ide_drive_t *drive)
+ {
+ 	ide_hwif_t *hwif = HWIF(drive);
+@@ -1997,7 +1997,7 @@ pmac_ide_dma_setup(ide_drive_t *drive)
+ 	return 0;
+ }
+ 
+-static void __pmac
++static void
+ pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
+ {
+ 	/* issue cmd to drive */
+@@ -2008,7 +2008,7 @@ pmac_ide_dma_exec_cmd(ide_drive_t *drive
+  * Kick the DMA controller into life after the DMA command has been issued
+  * to the drive.
+  */
+-static void __pmac
++static void
+ pmac_ide_dma_start(ide_drive_t *drive)
+ {
+ 	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+@@ -2024,7 +2024,7 @@ pmac_ide_dma_start(ide_drive_t *drive)
+ /*
+  * After a DMA transfer, make sure the controller is stopped
+  */
+-static int __pmac
++static int
+ pmac_ide_dma_end (ide_drive_t *drive)
+ {
+ 	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+@@ -2052,7 +2052,7 @@ pmac_ide_dma_end (ide_drive_t *drive)
+  * that's not implemented yet), on the other hand, we don't have shared interrupts
+  * so it's not really a problem
+  */
+-static int __pmac
++static int
+ pmac_ide_dma_test_irq (ide_drive_t *drive)
+ {
+ 	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+@@ -2108,19 +2108,19 @@ pmac_ide_dma_test_irq (ide_drive_t *driv
+ 	return 1;
+ }
+ 
+-static int __pmac
++static int
+ pmac_ide_dma_host_off (ide_drive_t *drive)
+ {
+ 	return 0;
+ }
+ 
+-static int __pmac
++static int
+ pmac_ide_dma_host_on (ide_drive_t *drive)
+ {
+ 	return 0;
+ }
+ 
+-static int __pmac
++static int
+ pmac_ide_dma_lostirq (ide_drive_t *drive)
+ {
+ 	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
+--- a/drivers/ieee1394/dv1394.c
++++ b/drivers/ieee1394/dv1394.c
+@@ -2361,7 +2361,7 @@ static void dv1394_add_host (struct hpsb
+ 
+ 	ohci = (struct ti_ohci *)host->hostdata;
+ 
+-	class_device_create(hpsb_protocol_class, MKDEV(
++	class_device_create(hpsb_protocol_class, NULL, MKDEV(
+ 		IEEE1394_MAJOR,	IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), 
+ 		NULL, "dv1394-%d", id);
+ 	devfs_mk_dir("ieee1394/dv/host%d", id);
+diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
+--- a/drivers/ieee1394/eth1394.c
++++ b/drivers/ieee1394/eth1394.c
+@@ -1630,7 +1630,7 @@ static void ether1394_complete_cb(void *
+ /* Transmit a packet (called by kernel) */
+ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
+ {
+-	int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
++	gfp_t kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+ 	struct eth1394hdr *eth;
+ 	struct eth1394_priv *priv = netdev_priv(dev);
+ 	int proto;
+diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
+--- a/drivers/ieee1394/nodemgr.c
++++ b/drivers/ieee1394/nodemgr.c
+@@ -1292,7 +1292,7 @@ static void nodemgr_suspend_ne(struct no
+ 
+ 		if (ud->device.driver &&
+ 		    (!ud->device.driver->suspend ||
+-		      ud->device.driver->suspend(&ud->device, PMSG_SUSPEND, 0)))
++		      ud->device.driver->suspend(&ud->device, PMSG_SUSPEND)))
+ 			device_release_driver(&ud->device);
+ 	}
+ 	up_write(&ne->device.bus->subsys.rwsem);
+@@ -1315,7 +1315,7 @@ static void nodemgr_resume_ne(struct nod
+ 			continue;
+ 
+ 		if (ud->device.driver && ud->device.driver->resume)
+-			ud->device.driver->resume(&ud->device, 0);
++			ud->device.driver->resume(&ud->device);
+ 	}
+ 	up_read(&ne->device.bus->subsys.rwsem);
+ 
+diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
+--- a/drivers/ieee1394/raw1394.c
++++ b/drivers/ieee1394/raw1394.c
+@@ -2912,7 +2912,7 @@ static int __init init_raw1394(void)
+ 
+ 	hpsb_register_highlevel(&raw1394_highlevel);
+ 
+-	if (IS_ERR(class_device_create(hpsb_protocol_class, MKDEV(
++	if (IS_ERR(class_device_create(hpsb_protocol_class, NULL, MKDEV(
+ 		IEEE1394_MAJOR,	IEEE1394_MINOR_BLOCK_RAW1394 * 16), 
+ 		NULL, RAW1394_DEVICE_NAME))) {
+ 		ret = -EFAULT;
+diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
+--- a/drivers/ieee1394/video1394.c
++++ b/drivers/ieee1394/video1394.c
+@@ -1370,7 +1370,7 @@ static void video1394_add_host (struct h
+ 	hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
+ 
+ 	minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
+-	class_device_create(hpsb_protocol_class, MKDEV(
++	class_device_create(hpsb_protocol_class, NULL, MKDEV(
+ 		IEEE1394_MAJOR,	minor), 
+ 		NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
+ 	devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),
+diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
+--- a/drivers/infiniband/core/agent.c
++++ b/drivers/infiniband/core/agent.c
+@@ -37,58 +37,41 @@
+  * $Id: agent.c 1389 2004-12-27 22:56:47Z roland $
+  */
+ 
+-#include <linux/dma-mapping.h>
+-
+-#include <asm/bug.h>
++#include "agent.h"
++#include "smi.h"
+ 
+-#include <rdma/ib_smi.h>
++#define SPFX "ib_agent: "
+ 
+-#include "smi.h"
+-#include "agent_priv.h"
+-#include "mad_priv.h"
+-#include "agent.h"
++struct ib_agent_port_private {
++	struct list_head port_list;
++	struct ib_mad_agent *agent[2];
++};
+ 
+-spinlock_t ib_agent_port_list_lock;
++static DEFINE_SPINLOCK(ib_agent_port_list_lock);
+ static LIST_HEAD(ib_agent_port_list);
+ 
+-/*
+- * Caller must hold ib_agent_port_list_lock
+- */
+-static inline struct ib_agent_port_private *
+-__ib_get_agent_port(struct ib_device *device, int port_num,
+-		    struct ib_mad_agent *mad_agent)
++static struct ib_agent_port_private *
++__ib_get_agent_port(struct ib_device *device, int port_num)
+ {
+ 	struct ib_agent_port_private *entry;
+ 
+-	BUG_ON(!(!!device ^ !!mad_agent));  /* Exactly one MUST be (!NULL) */
+-
+-	if (device) {
+-		list_for_each_entry(entry, &ib_agent_port_list, port_list) {
+-			if (entry->smp_agent->device == device &&
+-			    entry->port_num == port_num)
+-				return entry;
+-		}
+-	} else {
+-		list_for_each_entry(entry, &ib_agent_port_list, port_list) {
+-			if ((entry->smp_agent == mad_agent) ||
+-			    (entry->perf_mgmt_agent == mad_agent))
+-				return entry;
+-		}
++	list_for_each_entry(entry, &ib_agent_port_list, port_list) {
++		if (entry->agent[0]->device == device &&
++		    entry->agent[0]->port_num == port_num)
++			return entry;
+ 	}
+ 	return NULL;
+ }
+ 
+-static inline struct ib_agent_port_private *
+-ib_get_agent_port(struct ib_device *device, int port_num,
+-		  struct ib_mad_agent *mad_agent)
++static struct ib_agent_port_private *
++ib_get_agent_port(struct ib_device *device, int port_num)
+ {
+ 	struct ib_agent_port_private *entry;
+ 	unsigned long flags;
+ 
+ 	spin_lock_irqsave(&ib_agent_port_list_lock, flags);
+-	entry = __ib_get_agent_port(device, port_num, mad_agent);
++	entry = __ib_get_agent_port(device, port_num);
+ 	spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
+-
+ 	return entry;
+ }
+ 
+@@ -100,192 +83,76 @@ int smi_check_local_dr_smp(struct ib_smp
+ 
+ 	if (smp->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+ 		return 1;
+-	port_priv = ib_get_agent_port(device, port_num, NULL);
++
++	port_priv = ib_get_agent_port(device, port_num);
+ 	if (!port_priv) {
+ 		printk(KERN_DEBUG SPFX "smi_check_local_dr_smp %s port %d "
+-		       "not open\n",
+-		       device->name, port_num);
++		       "not open\n", device->name, port_num);
+ 		return 1;
+ 	}
+ 
+-	return smi_check_local_smp(port_priv->smp_agent, smp);
++	return smi_check_local_smp(port_priv->agent[0], smp);
+ }
+ 
+-static int agent_mad_send(struct ib_mad_agent *mad_agent,
+-			  struct ib_agent_port_private *port_priv,
+-			  struct ib_mad_private *mad_priv,
+-			  struct ib_grh *grh,
+-			  struct ib_wc *wc)
+-{
+-	struct ib_agent_send_wr *agent_send_wr;
+-	struct ib_sge gather_list;
+-	struct ib_send_wr send_wr;
+-	struct ib_send_wr *bad_send_wr;
+-	struct ib_ah_attr ah_attr;
+-	unsigned long flags;
+-	int ret = 1;
+-
+-	agent_send_wr = kmalloc(sizeof(*agent_send_wr), GFP_KERNEL);
+-	if (!agent_send_wr)
+-		goto out;
+-	agent_send_wr->mad = mad_priv;
+-
+-	gather_list.addr = dma_map_single(mad_agent->device->dma_device,
+-					  &mad_priv->mad,
+-					  sizeof(mad_priv->mad),
+-					  DMA_TO_DEVICE);
+-	gather_list.length = sizeof(mad_priv->mad);
+-	gather_list.lkey = mad_agent->mr->lkey;
+-
+-	send_wr.next = NULL;
+-	send_wr.opcode = IB_WR_SEND;
+-	send_wr.sg_list = &gather_list;
+-	send_wr.num_sge = 1;
+-	send_wr.wr.ud.remote_qpn = wc->src_qp; /* DQPN */
+-	send_wr.wr.ud.timeout_ms = 0;
+-	send_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_SOLICITED;
+-
+-	ah_attr.dlid = wc->slid;
+-	ah_attr.port_num = mad_agent->port_num;
+-	ah_attr.src_path_bits = wc->dlid_path_bits;
+-	ah_attr.sl = wc->sl;
+-	ah_attr.static_rate = 0;
+-	ah_attr.ah_flags = 0; /* No GRH */
+-	if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) {
+-		if (wc->wc_flags & IB_WC_GRH) {
+-			ah_attr.ah_flags = IB_AH_GRH;
+-			/* Should sgid be looked up ? */
+-			ah_attr.grh.sgid_index = 0;
+-			ah_attr.grh.hop_limit = grh->hop_limit;
+-			ah_attr.grh.flow_label = be32_to_cpu(
+-				grh->version_tclass_flow)  & 0xfffff;
+-			ah_attr.grh.traffic_class = (be32_to_cpu(
+-				grh->version_tclass_flow) >> 20) & 0xff;
+-			memcpy(ah_attr.grh.dgid.raw,
+-			       grh->sgid.raw,
+-			       sizeof(ah_attr.grh.dgid));
+-		}
+-	}
+-
+-	agent_send_wr->ah = ib_create_ah(mad_agent->qp->pd, &ah_attr);
+-	if (IS_ERR(agent_send_wr->ah)) {
+-		printk(KERN_ERR SPFX "No memory for address handle\n");
+-		kfree(agent_send_wr);
+-		goto out;
+-	}
+-
+-	send_wr.wr.ud.ah = agent_send_wr->ah;
+-	if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) {
+-		send_wr.wr.ud.pkey_index = wc->pkey_index;
+-		send_wr.wr.ud.remote_qkey = IB_QP1_QKEY;
+-	} else { 	/* for SMPs */
+-		send_wr.wr.ud.pkey_index = 0;
+-		send_wr.wr.ud.remote_qkey = 0;
+-	}
+-	send_wr.wr.ud.mad_hdr = &mad_priv->mad.mad.mad_hdr;
+-	send_wr.wr_id = (unsigned long)agent_send_wr;
+-
+-	pci_unmap_addr_set(agent_send_wr, mapping, gather_list.addr);
+-
+-	/* Send */
+-	spin_lock_irqsave(&port_priv->send_list_lock, flags);
+-	if (ib_post_send_mad(mad_agent, &send_wr, &bad_send_wr)) {
+-		spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
+-		dma_unmap_single(mad_agent->device->dma_device,
+-				 pci_unmap_addr(agent_send_wr, mapping),
+-				 sizeof(mad_priv->mad),
+-				 DMA_TO_DEVICE);
+-		ib_destroy_ah(agent_send_wr->ah);
+-		kfree(agent_send_wr);
+-	} else {
+-		list_add_tail(&agent_send_wr->send_list,
+-			      &port_priv->send_posted_list);
+-		spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
+-		ret = 0;
+-	}
+-
+-out:
+-	return ret;
+-}
+-
+-int agent_send(struct ib_mad_private *mad,
+-	       struct ib_grh *grh,
+-	       struct ib_wc *wc,
+-	       struct ib_device *device,
+-	       int port_num)
++int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
++			struct ib_wc *wc, struct ib_device *device,
++			int port_num, int qpn)
+ {
+ 	struct ib_agent_port_private *port_priv;
+-	struct ib_mad_agent *mad_agent;
++	struct ib_mad_agent *agent;
++	struct ib_mad_send_buf *send_buf;
++	struct ib_ah *ah;
++	int ret;
+ 
+-	port_priv = ib_get_agent_port(device, port_num, NULL);
++	port_priv = ib_get_agent_port(device, port_num);
+ 	if (!port_priv) {
+-		printk(KERN_DEBUG SPFX "agent_send %s port %d not open\n",
+-		       device->name, port_num);
+-		return 1;
++		printk(KERN_ERR SPFX "Unable to find port agent\n");
++		return -ENODEV;
+ 	}
+ 
+-	/* Get mad agent based on mgmt_class in MAD */
+-	switch (mad->mad.mad.mad_hdr.mgmt_class) {
+-		case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
+-		case IB_MGMT_CLASS_SUBN_LID_ROUTED:
+-			mad_agent = port_priv->smp_agent;
+-			break;
+-		case IB_MGMT_CLASS_PERF_MGMT:
+-			mad_agent = port_priv->perf_mgmt_agent;
+-			break;
+-		default:
+-			return 1;
++	agent = port_priv->agent[qpn];
++	ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num);
++	if (IS_ERR(ah)) {
++		ret = PTR_ERR(ah);
++		printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret);
++		return ret;
++	}
++
++	send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0,
++				      IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
++				      GFP_KERNEL);
++	if (IS_ERR(send_buf)) {
++		ret = PTR_ERR(send_buf);
++		printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret);
++		goto err1;
++	}
++
++	memcpy(send_buf->mad, mad, sizeof *mad);
++	send_buf->ah = ah;
++	if ((ret = ib_post_send_mad(send_buf, NULL))) {
++		printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret);
++		goto err2;
+ 	}
+-
+-	return agent_mad_send(mad_agent, port_priv, mad, grh, wc);
++	return 0;
++err2:
++	ib_free_send_mad(send_buf);
++err1:
++	ib_destroy_ah(ah);
++	return ret;
+ }
+ 
+ static void agent_send_handler(struct ib_mad_agent *mad_agent,
+ 			       struct ib_mad_send_wc *mad_send_wc)
+ {
+-	struct ib_agent_port_private	*port_priv;
+-	struct ib_agent_send_wr		*agent_send_wr;
+-	unsigned long			flags;
+-
+-	/* Find matching MAD agent */
+-	port_priv = ib_get_agent_port(NULL, 0, mad_agent);
+-	if (!port_priv) {
+-		printk(KERN_ERR SPFX "agent_send_handler: no matching MAD "
+-		       "agent %p\n", mad_agent);
+-		return;
+-	}
+-
+-	agent_send_wr = (struct ib_agent_send_wr *)(unsigned long)mad_send_wc->wr_id;
+-	spin_lock_irqsave(&port_priv->send_list_lock, flags);
+-	/* Remove completed send from posted send MAD list */
+-	list_del(&agent_send_wr->send_list);
+-	spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
+-
+-	dma_unmap_single(mad_agent->device->dma_device,
+-			 pci_unmap_addr(agent_send_wr, mapping),
+-			 sizeof(agent_send_wr->mad->mad),
+-			 DMA_TO_DEVICE);
+-
+-	ib_destroy_ah(agent_send_wr->ah);
+-
+-	/* Release allocated memory */
+-	kmem_cache_free(ib_mad_cache, agent_send_wr->mad);
+-	kfree(agent_send_wr);
++	ib_destroy_ah(mad_send_wc->send_buf->ah);
++	ib_free_send_mad(mad_send_wc->send_buf);
+ }
+ 
+ int ib_agent_port_open(struct ib_device *device, int port_num)
+ {
+-	int ret;
+ 	struct ib_agent_port_private *port_priv;
+ 	unsigned long flags;
+-
+-	/* First, check if port already open for SMI */
+-	port_priv = ib_get_agent_port(device, port_num, NULL);
+-	if (port_priv) {
+-		printk(KERN_DEBUG SPFX "%s port %d already open\n",
+-		       device->name, port_num);
+-		return 0;
+-	}
++	int ret;
+ 
+ 	/* Create new device info */
+ 	port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL);
+@@ -294,32 +161,25 @@ int ib_agent_port_open(struct ib_device 
+ 		ret = -ENOMEM;
+ 		goto error1;
+ 	}
+-
+ 	memset(port_priv, 0, sizeof *port_priv);
+-	port_priv->port_num = port_num;
+-	spin_lock_init(&port_priv->send_list_lock);
+-	INIT_LIST_HEAD(&port_priv->send_posted_list);
+-
+-	/* Obtain send only MAD agent for SM class (SMI QP) */
+-	port_priv->smp_agent = ib_register_mad_agent(device, port_num,
+-						     IB_QPT_SMI,
+-						     NULL, 0,
+-						    &agent_send_handler,
+-						     NULL, NULL);
+ 
+-	if (IS_ERR(port_priv->smp_agent)) {
+-		ret = PTR_ERR(port_priv->smp_agent);
++	/* Obtain send only MAD agent for SMI QP */
++	port_priv->agent[0] = ib_register_mad_agent(device, port_num,
++						    IB_QPT_SMI, NULL, 0,
++						    &agent_send_handler,
++						    NULL, NULL);
++	if (IS_ERR(port_priv->agent[0])) {
++		ret = PTR_ERR(port_priv->agent[0]);
+ 		goto error2;
+ 	}
+ 
+-	/* Obtain send only MAD agent for PerfMgmt class (GSI QP) */
+-	port_priv->perf_mgmt_agent = ib_register_mad_agent(device, port_num,
+-							   IB_QPT_GSI,
+-							   NULL, 0,
+-							  &agent_send_handler,
+-							   NULL, NULL);
+-	if (IS_ERR(port_priv->perf_mgmt_agent)) {
+-		ret = PTR_ERR(port_priv->perf_mgmt_agent);
++	/* Obtain send only MAD agent for GSI QP */
++	port_priv->agent[1] = ib_register_mad_agent(device, port_num,
++						    IB_QPT_GSI, NULL, 0,
++						    &agent_send_handler,
++						    NULL, NULL);
++	if (IS_ERR(port_priv->agent[1])) {
++		ret = PTR_ERR(port_priv->agent[1]);
+ 		goto error3;
+ 	}
+ 
+@@ -330,7 +190,7 @@ int ib_agent_port_open(struct ib_device 
+ 	return 0;
+ 
+ error3:
+-	ib_unregister_mad_agent(port_priv->smp_agent);
++	ib_unregister_mad_agent(port_priv->agent[0]);
+ error2:
+ 	kfree(port_priv);
+ error1:
+@@ -343,7 +203,7 @@ int ib_agent_port_close(struct ib_device
+ 	unsigned long flags;
+ 
+ 	spin_lock_irqsave(&ib_agent_port_list_lock, flags);
+-	port_priv = __ib_get_agent_port(device, port_num, NULL);
++	port_priv = __ib_get_agent_port(device, port_num);
+ 	if (port_priv == NULL) {
+ 		spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
+ 		printk(KERN_ERR SPFX "Port %d not found\n", port_num);
+@@ -352,9 +212,8 @@ int ib_agent_port_close(struct ib_device
+ 	list_del(&port_priv->port_list);
+ 	spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
+ 
+-	ib_unregister_mad_agent(port_priv->perf_mgmt_agent);
+-	ib_unregister_mad_agent(port_priv->smp_agent);
++	ib_unregister_mad_agent(port_priv->agent[1]);
++	ib_unregister_mad_agent(port_priv->agent[0]);
+ 	kfree(port_priv);
+-
+ 	return 0;
+ }
+diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h
+--- a/drivers/infiniband/core/agent.h
++++ b/drivers/infiniband/core/agent.h
+@@ -39,17 +39,15 @@
+ #ifndef __AGENT_H_
+ #define __AGENT_H_
+ 
+-extern spinlock_t ib_agent_port_list_lock;
++#include <linux/err.h>
++#include <rdma/ib_mad.h>
+ 
+-extern int ib_agent_port_open(struct ib_device *device,
+-			      int port_num);
++extern int ib_agent_port_open(struct ib_device *device, int port_num);
+ 
+ extern int ib_agent_port_close(struct ib_device *device, int port_num);
+ 
+-extern int agent_send(struct ib_mad_private *mad,
+-		      struct ib_grh *grh,
+-		      struct ib_wc *wc,
+-		      struct ib_device *device,
+-		      int port_num);
++extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
++			       struct ib_wc *wc, struct ib_device *device,
++			       int port_num, int qpn);
+ 
+ #endif	/* __AGENT_H_ */
+diff --git a/drivers/infiniband/core/agent_priv.h b/drivers/infiniband/core/agent_priv.h
+deleted file mode 100644
+--- a/drivers/infiniband/core/agent_priv.h
++++ /dev/null
+@@ -1,62 +0,0 @@
+-/*
+- * Copyright (c) 2004, 2005 Mellanox Technologies Ltd.  All rights reserved.
+- * Copyright (c) 2004, 2005 Infinicon Corporation.  All rights reserved.
+- * Copyright (c) 2004, 2005 Intel Corporation.  All rights reserved.
+- * Copyright (c) 2004, 2005 Topspin Corporation.  All rights reserved.
+- * Copyright (c) 2004, 2005 Voltaire 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.
+- *
+- * $Id: agent_priv.h 1640 2005-01-24 22:39:02Z halr $
+- */
+-
+-#ifndef __IB_AGENT_PRIV_H__
+-#define __IB_AGENT_PRIV_H__
+-
+-#include <linux/pci.h>
+-
+-#define SPFX "ib_agent: "
+-
+-struct ib_agent_send_wr {
+-	struct list_head send_list;
+-	struct ib_ah *ah;
+-	struct ib_mad_private *mad;
+-	DECLARE_PCI_UNMAP_ADDR(mapping)
+-};
+-
+-struct ib_agent_port_private {
+-	struct list_head port_list;
+-	struct list_head send_posted_list;
+-	spinlock_t send_list_lock;
+-	int port_num;
+-	struct ib_mad_agent *smp_agent;	      /* SM class */
+-	struct ib_mad_agent *perf_mgmt_agent; /* PerfMgmt class */
+-};
+-
+-#endif	/* __IB_AGENT_PRIV_H__ */
+diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
+--- a/drivers/infiniband/core/cache.c
++++ b/drivers/infiniband/core/cache.c
+@@ -38,6 +38,7 @@
+ #include <linux/module.h>
+ #include <linux/errno.h>
+ #include <linux/slab.h>
++#include <linux/sched.h>	/* INIT_WORK, schedule_work(), flush_scheduled_work() */
+ 
+ #include <rdma/ib_cache.h>
+ 
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -135,6 +135,7 @@ struct cm_id_private {
+ 	__be64 tid;
+ 	__be32 local_qpn;
+ 	__be32 remote_qpn;
++	enum ib_qp_type qp_type;
+ 	__be32 sq_psn;
+ 	__be32 rq_psn;
+ 	int timeout_ms;
+@@ -175,8 +176,7 @@ static int cm_alloc_msg(struct cm_id_pri
+ 
+ 	m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn, 
+ 			       cm_id_priv->av.pkey_index,
+-			       ah, 0, sizeof(struct ib_mad_hdr),
+-			       sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr),
++			       0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+ 			       GFP_ATOMIC);
+ 	if (IS_ERR(m)) {
+ 		ib_destroy_ah(ah);
+@@ -184,7 +184,8 @@ static int cm_alloc_msg(struct cm_id_pri
+ 	}
+ 
+ 	/* Timeout set by caller if response is expected. */
+-	m->send_wr.wr.ud.retries = cm_id_priv->max_cm_retries;
++	m->ah = ah;
++	m->retries = cm_id_priv->max_cm_retries;
+ 
+ 	atomic_inc(&cm_id_priv->refcount);
+ 	m->context[0] = cm_id_priv;
+@@ -205,20 +206,20 @@ static int cm_alloc_response_msg(struct 
+ 		return PTR_ERR(ah);
+ 
+ 	m = ib_create_send_mad(port->mad_agent, 1, mad_recv_wc->wc->pkey_index,
+-			       ah, 0, sizeof(struct ib_mad_hdr),
+-			       sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr),
++			       0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+ 			       GFP_ATOMIC);
+ 	if (IS_ERR(m)) {
+ 		ib_destroy_ah(ah);
+ 		return PTR_ERR(m);
+ 	}
++	m->ah = ah;
+ 	*msg = m;
+ 	return 0;
+ }
+ 
+ static void cm_free_msg(struct ib_mad_send_buf *msg)
+ {
+-	ib_destroy_ah(msg->send_wr.wr.ud.ah);
++	ib_destroy_ah(msg->ah);
+ 	if (msg->context[0])
+ 		cm_deref_id(msg->context[0]);
+ 	ib_free_send_mad(msg);
+@@ -366,9 +367,15 @@ static struct cm_id_private * cm_insert_
+ 		cur_cm_id_priv = rb_entry(parent, struct cm_id_private,
+ 					  service_node);
+ 		if ((cur_cm_id_priv->id.service_mask & service_id) ==
+-		    (service_mask & cur_cm_id_priv->id.service_id))
+-			return cm_id_priv;
+-		if (service_id < cur_cm_id_priv->id.service_id)
++		    (service_mask & cur_cm_id_priv->id.service_id) &&
++		    (cm_id_priv->id.device == cur_cm_id_priv->id.device))
++			return cur_cm_id_priv;
++
++		if (cm_id_priv->id.device < cur_cm_id_priv->id.device)
++			link = &(*link)->rb_left;
++		else if (cm_id_priv->id.device > cur_cm_id_priv->id.device)
++			link = &(*link)->rb_right;
++		else if (service_id < cur_cm_id_priv->id.service_id)
+ 			link = &(*link)->rb_left;
+ 		else
+ 			link = &(*link)->rb_right;
+@@ -378,7 +385,8 @@ static struct cm_id_private * cm_insert_
+ 	return NULL;
+ }
+ 
+-static struct cm_id_private * cm_find_listen(__be64 service_id)
++static struct cm_id_private * cm_find_listen(struct ib_device *device,
++					     __be64 service_id)
+ {
+ 	struct rb_node *node = cm.listen_service_table.rb_node;
+ 	struct cm_id_private *cm_id_priv;
+@@ -386,9 +394,15 @@ static struct cm_id_private * cm_find_li
+ 	while (node) {
+ 		cm_id_priv = rb_entry(node, struct cm_id_private, service_node);
+ 		if ((cm_id_priv->id.service_mask & service_id) ==
+-		    (cm_id_priv->id.service_mask & cm_id_priv->id.service_id))
++		     cm_id_priv->id.service_id &&
++		    (cm_id_priv->id.device == device))
+ 			return cm_id_priv;
+-		if (service_id < cm_id_priv->id.service_id)
++
++		if (device < cm_id_priv->id.device)
++			node = node->rb_left;
++		else if (device > cm_id_priv->id.device)
++			node = node->rb_right;
++		else if (service_id < cm_id_priv->id.service_id)
+ 			node = node->rb_left;
+ 		else
+ 			node = node->rb_right;
+@@ -523,7 +537,8 @@ static void cm_reject_sidr_req(struct cm
+ 	ib_send_cm_sidr_rep(&cm_id_priv->id, &param);
+ }
+ 
+-struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
++struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
++				 ib_cm_handler cm_handler,
+ 				 void *context)
+ {
+ 	struct cm_id_private *cm_id_priv;
+@@ -535,6 +550,7 @@ struct ib_cm_id *ib_create_cm_id(ib_cm_h
+ 
+ 	memset(cm_id_priv, 0, sizeof *cm_id_priv);
+ 	cm_id_priv->id.state = IB_CM_IDLE;
++	cm_id_priv->id.device = device;
+ 	cm_id_priv->id.cm_handler = cm_handler;
+ 	cm_id_priv->id.context = context;
+ 	cm_id_priv->id.remote_cm_qpn = 1;
+@@ -662,8 +678,7 @@ retest:
+ 		break;
+ 	case IB_CM_SIDR_REQ_SENT:
+ 		cm_id->state = IB_CM_IDLE;
+-		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-			      (unsigned long) cm_id_priv->msg);
++		ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 		break;
+ 	case IB_CM_SIDR_REQ_RCVD:
+@@ -674,8 +689,7 @@ retest:
+ 	case IB_CM_MRA_REQ_RCVD:
+ 	case IB_CM_REP_SENT:
+ 	case IB_CM_MRA_REP_RCVD:
+-		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-			      (unsigned long) cm_id_priv->msg);
++		ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 		/* Fall through */
+ 	case IB_CM_REQ_RCVD:
+ 	case IB_CM_MRA_REQ_SENT:
+@@ -692,8 +706,7 @@ retest:
+ 		ib_send_cm_dreq(cm_id, NULL, 0);
+ 		goto retest;
+ 	case IB_CM_DREQ_SENT:
+-		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-			      (unsigned long) cm_id_priv->msg);
++		ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 		cm_enter_timewait(cm_id_priv);
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 		break;
+@@ -867,7 +880,6 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
+ 		   struct ib_cm_req_param *param)
+ {
+ 	struct cm_id_private *cm_id_priv;
+-	struct ib_send_wr *bad_send_wr;
+ 	struct cm_req_msg *req_msg;
+ 	unsigned long flags;
+ 	int ret;
+@@ -911,6 +923,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
+ 	cm_id_priv->responder_resources = param->responder_resources;
+ 	cm_id_priv->retry_count = param->retry_count;
+ 	cm_id_priv->path_mtu = param->primary_path->mtu;
++	cm_id_priv->qp_type = param->qp_type;
+ 
+ 	ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg);
+ 	if (ret)
+@@ -919,7 +932,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
+ 	req_msg = (struct cm_req_msg *) cm_id_priv->msg->mad;
+ 	cm_format_req(req_msg, cm_id_priv, param);
+ 	cm_id_priv->tid = req_msg->hdr.tid;
+-	cm_id_priv->msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
++	cm_id_priv->msg->timeout_ms = cm_id_priv->timeout_ms;
+ 	cm_id_priv->msg->context[1] = (void *) (unsigned long) IB_CM_REQ_SENT;
+ 
+ 	cm_id_priv->local_qpn = cm_req_get_local_qpn(req_msg);
+@@ -928,8 +941,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
+ 				cm_req_get_primary_local_ack_timeout(req_msg);
+ 
+ 	spin_lock_irqsave(&cm_id_priv->lock, flags);
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-				&cm_id_priv->msg->send_wr, &bad_send_wr);
++	ret = ib_post_send_mad(cm_id_priv->msg, NULL);
+ 	if (ret) {
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 		goto error2;
+@@ -952,7 +964,6 @@ static int cm_issue_rej(struct cm_port *
+ 			void *ari, u8 ari_length)
+ {
+ 	struct ib_mad_send_buf *msg = NULL;
+-	struct ib_send_wr *bad_send_wr;
+ 	struct cm_rej_msg *rej_msg, *rcv_msg;
+ 	int ret;
+ 
+@@ -975,7 +986,7 @@ static int cm_issue_rej(struct cm_port *
+ 		memcpy(rej_msg->ari, ari, ari_length);
+ 	}
+ 
+-	ret = ib_post_send_mad(port->mad_agent, &msg->send_wr, &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret)
+ 		cm_free_msg(msg);
+ 
+@@ -1047,7 +1058,6 @@ static void cm_format_req_event(struct c
+ 	req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
+ 	param = &work->cm_event.param.req_rcvd;
+ 	param->listen_id = listen_id;
+-	param->device = cm_id_priv->av.port->mad_agent->device;
+ 	param->port = cm_id_priv->av.port->port_num;
+ 	param->primary_path = &work->path[0];
+ 	if (req_msg->alt_local_lid)
+@@ -1156,7 +1166,6 @@ static void cm_dup_req_handler(struct cm
+ 			       struct cm_id_private *cm_id_priv)
+ {
+ 	struct ib_mad_send_buf *msg = NULL;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -1185,8 +1194,7 @@ static void cm_dup_req_handler(struct cm
+ 	}
+ 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
+-			       &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret)
+ 		goto free;
+ 	return;
+@@ -1226,7 +1234,8 @@ static struct cm_id_private * cm_match_r
+ 	}
+ 
+ 	/* Find matching listen request. */
+-	listen_cm_id_priv = cm_find_listen(req_msg->service_id);
++	listen_cm_id_priv = cm_find_listen(cm_id_priv->id.device,
++					   req_msg->service_id);
+ 	if (!listen_cm_id_priv) {
+ 		spin_unlock_irqrestore(&cm.lock, flags);
+ 		cm_issue_rej(work->port, work->mad_recv_wc,
+@@ -1254,7 +1263,7 @@ static int cm_req_handler(struct cm_work
+ 
+ 	req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
+ 
+-	cm_id = ib_create_cm_id(NULL, NULL);
++	cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
+ 	if (IS_ERR(cm_id))
+ 		return PTR_ERR(cm_id);
+ 
+@@ -1305,6 +1314,7 @@ static int cm_req_handler(struct cm_work
+ 				cm_req_get_primary_local_ack_timeout(req_msg);
+ 	cm_id_priv->retry_count = cm_req_get_retry_count(req_msg);
+ 	cm_id_priv->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg);
++	cm_id_priv->qp_type = cm_req_get_qp_type(req_msg);
+ 
+ 	cm_format_req_event(work, cm_id_priv, &listen_cm_id_priv->id);
+ 	cm_process_work(cm_id_priv, work);
+@@ -1349,7 +1359,6 @@ int ib_send_cm_rep(struct ib_cm_id *cm_i
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+ 	struct cm_rep_msg *rep_msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -1371,11 +1380,10 @@ int ib_send_cm_rep(struct ib_cm_id *cm_i
+ 
+ 	rep_msg = (struct cm_rep_msg *) msg->mad;
+ 	cm_format_rep(rep_msg, cm_id_priv, param);
+-	msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
++	msg->timeout_ms = cm_id_priv->timeout_ms;
+ 	msg->context[1] = (void *) (unsigned long) IB_CM_REP_SENT;
+ 
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-			       &msg->send_wr, &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret) {
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 		cm_free_msg(msg);
+@@ -1413,7 +1421,6 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_i
+ {
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	void *data;
+ 	int ret;
+@@ -1440,8 +1447,7 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_i
+ 	cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv,
+ 		      private_data, private_data_len);
+ 
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-			       &msg->send_wr, &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret) {
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 		cm_free_msg(msg);
+@@ -1486,7 +1492,6 @@ static void cm_dup_rep_handler(struct cm
+ 	struct cm_id_private *cm_id_priv;
+ 	struct cm_rep_msg *rep_msg;
+ 	struct ib_mad_send_buf *msg = NULL;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -1514,8 +1519,7 @@ static void cm_dup_rep_handler(struct cm
+ 		goto unlock;
+ 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
+-			       &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret)
+ 		goto free;
+ 	goto deref;
+@@ -1583,8 +1587,7 @@ static int cm_rep_handler(struct cm_work
+ 
+ 	/* todo: handle peer_to_peer */
+ 
+-	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-		      (unsigned long) cm_id_priv->msg);
++	ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+ 	if (!ret)
+ 		list_add_tail(&work->list, &cm_id_priv->work_list);
+@@ -1618,8 +1621,7 @@ static int cm_establish_handler(struct c
+ 		goto out;
+ 	}
+ 
+-	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-		      (unsigned long) cm_id_priv->msg);
++	ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+ 	if (!ret)
+ 		list_add_tail(&work->list, &cm_id_priv->work_list);
+@@ -1658,8 +1660,7 @@ static int cm_rtu_handler(struct cm_work
+ 	}
+ 	cm_id_priv->id.state = IB_CM_ESTABLISHED;
+ 
+-	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-		      (unsigned long) cm_id_priv->msg);
++	ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+ 	if (!ret)
+ 		list_add_tail(&work->list, &cm_id_priv->work_list);
+@@ -1696,7 +1697,6 @@ int ib_send_cm_dreq(struct ib_cm_id *cm_
+ {
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -1718,11 +1718,10 @@ int ib_send_cm_dreq(struct ib_cm_id *cm_
+ 
+ 	cm_format_dreq((struct cm_dreq_msg *) msg->mad, cm_id_priv,
+ 		       private_data, private_data_len);
+-	msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
++	msg->timeout_ms = cm_id_priv->timeout_ms;
+ 	msg->context[1] = (void *) (unsigned long) IB_CM_DREQ_SENT;
+ 
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-			       &msg->send_wr, &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret) {
+ 		cm_enter_timewait(cm_id_priv);
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+@@ -1756,7 +1755,6 @@ int ib_send_cm_drep(struct ib_cm_id *cm_
+ {
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	void *data;
+ 	int ret;
+@@ -1786,8 +1784,7 @@ int ib_send_cm_drep(struct ib_cm_id *cm_
+ 	cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv,
+ 		       private_data, private_data_len);
+ 
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
+-			       &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret) {
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 		cm_free_msg(msg);
+@@ -1804,7 +1801,6 @@ static int cm_dreq_handler(struct cm_wor
+ 	struct cm_id_private *cm_id_priv;
+ 	struct cm_dreq_msg *dreq_msg;
+ 	struct ib_mad_send_buf *msg = NULL;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -1823,8 +1819,7 @@ static int cm_dreq_handler(struct cm_wor
+ 	switch (cm_id_priv->id.state) {
+ 	case IB_CM_REP_SENT:
+ 	case IB_CM_DREQ_SENT:
+-		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-			      (unsigned long) cm_id_priv->msg);
++		ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 		break;
+ 	case IB_CM_ESTABLISHED:
+ 	case IB_CM_MRA_REP_RCVD:
+@@ -1838,8 +1833,7 @@ static int cm_dreq_handler(struct cm_wor
+ 			       cm_id_priv->private_data_len);
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 
+-		if (ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-				     &msg->send_wr, &bad_send_wr))
++		if (ib_post_send_mad(msg, NULL))
+ 			cm_free_msg(msg);
+ 		goto deref;
+ 	default:
+@@ -1886,8 +1880,7 @@ static int cm_drep_handler(struct cm_wor
+ 	}
+ 	cm_enter_timewait(cm_id_priv);
+ 
+-	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-		      (unsigned long) cm_id_priv->msg);
++	ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+ 	if (!ret)
+ 		list_add_tail(&work->list, &cm_id_priv->work_list);
+@@ -1912,7 +1905,6 @@ int ib_send_cm_rej(struct ib_cm_id *cm_i
+ {
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -1956,8 +1948,7 @@ int ib_send_cm_rej(struct ib_cm_id *cm_i
+ 	if (ret)
+ 		goto out;
+ 
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-			       &msg->send_wr, &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret)
+ 		cm_free_msg(msg);
+ 
+@@ -2033,8 +2024,7 @@ static int cm_rej_handler(struct cm_work
+ 	case IB_CM_MRA_REQ_RCVD:
+ 	case IB_CM_REP_SENT:
+ 	case IB_CM_MRA_REP_RCVD:
+-		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-			      (unsigned long) cm_id_priv->msg);
++		ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 		/* fall through */
+ 	case IB_CM_REQ_RCVD:
+ 	case IB_CM_MRA_REQ_SENT:
+@@ -2044,8 +2034,7 @@ static int cm_rej_handler(struct cm_work
+ 			cm_reset_to_idle(cm_id_priv);
+ 		break;
+ 	case IB_CM_DREQ_SENT:
+-		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-			      (unsigned long) cm_id_priv->msg);
++		ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 		/* fall through */
+ 	case IB_CM_REP_RCVD:
+ 	case IB_CM_MRA_REP_SENT:
+@@ -2080,7 +2069,6 @@ int ib_send_cm_mra(struct ib_cm_id *cm_i
+ {
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	void *data;
+ 	unsigned long flags;
+ 	int ret;
+@@ -2104,8 +2092,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_i
+ 		cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+ 			      CM_MSG_RESPONSE_REQ, service_timeout,
+ 			      private_data, private_data_len);
+-		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-				       &msg->send_wr, &bad_send_wr);
++		ret = ib_post_send_mad(msg, NULL);
+ 		if (ret)
+ 			goto error2;
+ 		cm_id->state = IB_CM_MRA_REQ_SENT;
+@@ -2118,8 +2105,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_i
+ 		cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+ 			      CM_MSG_RESPONSE_REP, service_timeout,
+ 			      private_data, private_data_len);
+-		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-				       &msg->send_wr, &bad_send_wr);
++		ret = ib_post_send_mad(msg, NULL);
+ 		if (ret)
+ 			goto error2;
+ 		cm_id->state = IB_CM_MRA_REP_SENT;
+@@ -2132,8 +2118,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_i
+ 		cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+ 			      CM_MSG_RESPONSE_OTHER, service_timeout,
+ 			      private_data, private_data_len);
+-		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-				       &msg->send_wr, &bad_send_wr);
++		ret = ib_post_send_mad(msg, NULL);
+ 		if (ret)
+ 			goto error2;
+ 		cm_id->lap_state = IB_CM_MRA_LAP_SENT;
+@@ -2195,14 +2180,14 @@ static int cm_mra_handler(struct cm_work
+ 	case IB_CM_REQ_SENT:
+ 		if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REQ ||
+ 		    ib_modify_mad(cm_id_priv->av.port->mad_agent,
+-				  (unsigned long) cm_id_priv->msg, timeout))
++				  cm_id_priv->msg, timeout))
+ 			goto out;
+ 		cm_id_priv->id.state = IB_CM_MRA_REQ_RCVD;
+ 		break;
+ 	case IB_CM_REP_SENT:
+ 		if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REP ||
+ 		    ib_modify_mad(cm_id_priv->av.port->mad_agent,
+-				  (unsigned long) cm_id_priv->msg, timeout))
++				  cm_id_priv->msg, timeout))
+ 			goto out;
+ 		cm_id_priv->id.state = IB_CM_MRA_REP_RCVD;
+ 		break;
+@@ -2210,7 +2195,7 @@ static int cm_mra_handler(struct cm_work
+ 		if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_OTHER ||
+ 		    cm_id_priv->id.lap_state != IB_CM_LAP_SENT ||
+ 		    ib_modify_mad(cm_id_priv->av.port->mad_agent,
+-				  (unsigned long) cm_id_priv->msg, timeout))
++				  cm_id_priv->msg, timeout))
+ 			goto out;
+ 		cm_id_priv->id.lap_state = IB_CM_MRA_LAP_RCVD;
+ 		break;
+@@ -2273,7 +2258,6 @@ int ib_send_cm_lap(struct ib_cm_id *cm_i
+ {
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -2294,11 +2278,10 @@ int ib_send_cm_lap(struct ib_cm_id *cm_i
+ 
+ 	cm_format_lap((struct cm_lap_msg *) msg->mad, cm_id_priv,
+ 		      alternate_path, private_data, private_data_len);
+-	msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
++	msg->timeout_ms = cm_id_priv->timeout_ms;
+ 	msg->context[1] = (void *) (unsigned long) IB_CM_ESTABLISHED;
+ 
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-			       &msg->send_wr, &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret) {
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 		cm_free_msg(msg);
+@@ -2342,7 +2325,6 @@ static int cm_lap_handler(struct cm_work
+ 	struct cm_lap_msg *lap_msg;
+ 	struct ib_cm_lap_event_param *param;
+ 	struct ib_mad_send_buf *msg = NULL;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -2376,8 +2358,7 @@ static int cm_lap_handler(struct cm_work
+ 			      cm_id_priv->private_data_len);
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 
+-		if (ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-				     &msg->send_wr, &bad_send_wr))
++		if (ib_post_send_mad(msg, NULL))
+ 			cm_free_msg(msg);
+ 		goto deref;
+ 	default:
+@@ -2433,7 +2414,6 @@ int ib_send_cm_apr(struct ib_cm_id *cm_i
+ {
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -2456,8 +2436,7 @@ int ib_send_cm_apr(struct ib_cm_id *cm_i
+ 
+ 	cm_format_apr((struct cm_apr_msg *) msg->mad, cm_id_priv, status,
+ 		      info, info_length, private_data, private_data_len);
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-			       &msg->send_wr, &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret) {
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 		cm_free_msg(msg);
+@@ -2496,8 +2475,7 @@ static int cm_apr_handler(struct cm_work
+ 		goto out;
+ 	}
+ 	cm_id_priv->id.lap_state = IB_CM_LAP_IDLE;
+-	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-		      (unsigned long) cm_id_priv->msg);
++	ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 	cm_id_priv->msg = NULL;
+ 
+ 	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+@@ -2572,7 +2550,6 @@ int ib_send_cm_sidr_req(struct ib_cm_id 
+ {
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -2595,13 +2572,12 @@ int ib_send_cm_sidr_req(struct ib_cm_id 
+ 
+ 	cm_format_sidr_req((struct cm_sidr_req_msg *) msg->mad, cm_id_priv,
+ 			   param);
+-	msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
++	msg->timeout_ms = cm_id_priv->timeout_ms;
+ 	msg->context[1] = (void *) (unsigned long) IB_CM_SIDR_REQ_SENT;
+ 
+ 	spin_lock_irqsave(&cm_id_priv->lock, flags);
+ 	if (cm_id->state == IB_CM_IDLE)
+-		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-				       &msg->send_wr, &bad_send_wr);
++		ret = ib_post_send_mad(msg, NULL);
+ 	else
+ 		ret = -EINVAL;
+ 
+@@ -2629,7 +2605,6 @@ static void cm_format_sidr_req_event(str
+ 	param = &work->cm_event.param.sidr_req_rcvd;
+ 	param->pkey = __be16_to_cpu(sidr_req_msg->pkey);
+ 	param->listen_id = listen_id;
+-	param->device = work->port->mad_agent->device;
+ 	param->port = work->port->port_num;
+ 	work->cm_event.private_data = &sidr_req_msg->private_data;
+ }
+@@ -2642,7 +2617,7 @@ static int cm_sidr_req_handler(struct cm
+ 	struct ib_wc *wc;
+ 	unsigned long flags;
+ 
+-	cm_id = ib_create_cm_id(NULL, NULL);
++	cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
+ 	if (IS_ERR(cm_id))
+ 		return PTR_ERR(cm_id);
+ 	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+@@ -2666,7 +2641,8 @@ static int cm_sidr_req_handler(struct cm
+ 		spin_unlock_irqrestore(&cm.lock, flags);
+ 		goto out; /* Duplicate message. */
+ 	}
+-	cur_cm_id_priv = cm_find_listen(sidr_req_msg->service_id);
++	cur_cm_id_priv = cm_find_listen(cm_id->device,
++					sidr_req_msg->service_id);
+ 	if (!cur_cm_id_priv) {
+ 		rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
+ 		spin_unlock_irqrestore(&cm.lock, flags);
+@@ -2715,7 +2691,6 @@ int ib_send_cm_sidr_rep(struct ib_cm_id 
+ {
+ 	struct cm_id_private *cm_id_priv;
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -2737,8 +2712,7 @@ int ib_send_cm_sidr_rep(struct ib_cm_id 
+ 
+ 	cm_format_sidr_rep((struct cm_sidr_rep_msg *) msg->mad, cm_id_priv,
+ 			   param);
+-	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+-			       &msg->send_wr, &bad_send_wr);
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret) {
+ 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 		cm_free_msg(msg);
+@@ -2791,8 +2765,7 @@ static int cm_sidr_rep_handler(struct cm
+ 		goto out;
+ 	}
+ 	cm_id_priv->id.state = IB_CM_IDLE;
+-	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+-		      (unsigned long) cm_id_priv->msg);
++	ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+ 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ 
+ 	cm_format_sidr_rep_event(work);
+@@ -2860,9 +2833,7 @@ discard:
+ static void cm_send_handler(struct ib_mad_agent *mad_agent,
+ 			    struct ib_mad_send_wc *mad_send_wc)
+ {
+-	struct ib_mad_send_buf *msg;
+-
+-	msg = (struct ib_mad_send_buf *)(unsigned long)mad_send_wc->wr_id;
++	struct ib_mad_send_buf *msg = mad_send_wc->send_buf;
+ 
+ 	switch (mad_send_wc->status) {
+ 	case IB_WC_SUCCESS:
+@@ -3064,10 +3035,10 @@ static int cm_init_qp_init_attr(struct c
+ 	case IB_CM_ESTABLISHED:
+ 		*qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS |
+ 				IB_QP_PKEY_INDEX | IB_QP_PORT;
+-		qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE;
++		qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE |
++					   IB_ACCESS_REMOTE_WRITE;
+ 		if (cm_id_priv->responder_resources)
+-			qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_WRITE |
+-						    IB_ACCESS_REMOTE_READ;
++			qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ;
+ 		qp_attr->pkey_index = cm_id_priv->av.pkey_index;
+ 		qp_attr->port_num = cm_id_priv->av.port->port_num;
+ 		ret = 0;
+@@ -3097,14 +3068,18 @@ static int cm_init_qp_rtr_attr(struct cm
+ 	case IB_CM_MRA_REP_RCVD:
+ 	case IB_CM_ESTABLISHED:
+ 		*qp_attr_mask = IB_QP_STATE | IB_QP_AV | IB_QP_PATH_MTU |
+-				IB_QP_DEST_QPN | IB_QP_RQ_PSN |
+-				IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_MIN_RNR_TIMER;
++				IB_QP_DEST_QPN | IB_QP_RQ_PSN;
+ 		qp_attr->ah_attr = cm_id_priv->av.ah_attr;
+ 		qp_attr->path_mtu = cm_id_priv->path_mtu;
+ 		qp_attr->dest_qp_num = be32_to_cpu(cm_id_priv->remote_qpn);
+ 		qp_attr->rq_psn = be32_to_cpu(cm_id_priv->rq_psn);
+-		qp_attr->max_dest_rd_atomic = cm_id_priv->responder_resources;
+-		qp_attr->min_rnr_timer = 0;
++		if (cm_id_priv->qp_type == IB_QPT_RC) {
++			*qp_attr_mask |= IB_QP_MAX_DEST_RD_ATOMIC |
++					 IB_QP_MIN_RNR_TIMER;
++			qp_attr->max_dest_rd_atomic =
++					cm_id_priv->responder_resources;
++			qp_attr->min_rnr_timer = 0;
++		}
+ 		if (cm_id_priv->alt_av.ah_attr.dlid) {
+ 			*qp_attr_mask |= IB_QP_ALT_PATH;
+ 			qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr;
+@@ -3133,14 +3108,17 @@ static int cm_init_qp_rts_attr(struct cm
+ 	case IB_CM_REP_SENT:
+ 	case IB_CM_MRA_REP_RCVD:
+ 	case IB_CM_ESTABLISHED:
+-		*qp_attr_mask = IB_QP_STATE | IB_QP_TIMEOUT | IB_QP_RETRY_CNT |
+-				IB_QP_RNR_RETRY | IB_QP_SQ_PSN |
+-				IB_QP_MAX_QP_RD_ATOMIC;
+-		qp_attr->timeout = cm_id_priv->local_ack_timeout;
+-		qp_attr->retry_cnt = cm_id_priv->retry_count;
+-		qp_attr->rnr_retry = cm_id_priv->rnr_retry_count;
++		*qp_attr_mask = IB_QP_STATE | IB_QP_SQ_PSN;
+ 		qp_attr->sq_psn = be32_to_cpu(cm_id_priv->sq_psn);
+-		qp_attr->max_rd_atomic = cm_id_priv->initiator_depth;
++		if (cm_id_priv->qp_type == IB_QPT_RC) {
++			*qp_attr_mask |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT |
++					 IB_QP_RNR_RETRY |
++					 IB_QP_MAX_QP_RD_ATOMIC;
++			qp_attr->timeout = cm_id_priv->local_ack_timeout;
++			qp_attr->retry_cnt = cm_id_priv->retry_count;
++			qp_attr->rnr_retry = cm_id_priv->rnr_retry_count;
++			qp_attr->max_rd_atomic = cm_id_priv->initiator_depth;
++		}
+ 		if (cm_id_priv->alt_av.ah_attr.dlid) {
+ 			*qp_attr_mask |= IB_QP_PATH_MIG_STATE;
+ 			qp_attr->path_mig_state = IB_MIG_REARM;
+@@ -3323,6 +3301,7 @@ static void __exit ib_cm_cleanup(void)
+ 	flush_workqueue(cm.wq);
+ 	destroy_workqueue(cm.wq);
+ 	ib_unregister_client(&cm_client);
++	idr_destroy(&cm.local_id_table);
+ }
+ 
+ module_init(ib_cm_init);
+diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h
+--- a/drivers/infiniband/core/cm_msgs.h
++++ b/drivers/infiniband/core/cm_msgs.h
+@@ -186,6 +186,7 @@ static inline void cm_req_set_qp_type(st
+ 		req_msg->offset40 = cpu_to_be32((be32_to_cpu(
+ 						  req_msg->offset40) &
+ 						   0xFFFFFFF9) | 0x2);
++		break;
+ 	default:
+ 		req_msg->offset40 = cpu_to_be32(be32_to_cpu(
+ 						 req_msg->offset40) &
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -514,6 +514,12 @@ int ib_query_port(struct ib_device *devi
+ 		  u8 port_num,
+ 		  struct ib_port_attr *port_attr)
+ {
++	if (device->node_type == IB_NODE_SWITCH) {
++		if (port_num)
++			return -EINVAL;
++	} else if (port_num < 1 || port_num > device->phys_port_cnt)
++		return -EINVAL;
++
+ 	return device->query_port(device, port_num, port_attr);
+ }
+ EXPORT_SYMBOL(ib_query_port);
+@@ -583,6 +589,12 @@ int ib_modify_port(struct ib_device *dev
+ 		   u8 port_num, int port_modify_mask,
+ 		   struct ib_port_modify *port_modify)
+ {
++	if (device->node_type == IB_NODE_SWITCH) {
++		if (port_num)
++			return -EINVAL;
++	} else if (port_num < 1 || port_num > device->phys_port_cnt)
++		return -EINVAL;
++
+ 	return device->modify_port(device, port_num, port_modify_mask,
+ 				   port_modify);
+ }
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -579,7 +579,7 @@ static void dequeue_mad(struct ib_mad_li
+ }
+ 
+ static void snoop_send(struct ib_mad_qp_info *qp_info,
+-		       struct ib_send_wr *send_wr,
++		       struct ib_mad_send_buf *send_buf,
+ 		       struct ib_mad_send_wc *mad_send_wc,
+ 		       int mad_snoop_flags)
+ {
+@@ -597,7 +597,7 @@ static void snoop_send(struct ib_mad_qp_
+ 		atomic_inc(&mad_snoop_priv->refcount);
+ 		spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
+ 		mad_snoop_priv->agent.snoop_handler(&mad_snoop_priv->agent,
+-						    send_wr, mad_send_wc);
++						    send_buf, mad_send_wc);
+ 		if (atomic_dec_and_test(&mad_snoop_priv->refcount))
+ 			wake_up(&mad_snoop_priv->wait);
+ 		spin_lock_irqsave(&qp_info->snoop_lock, flags);
+@@ -654,10 +654,10 @@ static void build_smp_wc(u64 wr_id, u16 
+  * Return < 0 if error
+  */
+ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
+-				  struct ib_smp *smp,
+-				  struct ib_send_wr *send_wr)
++				  struct ib_mad_send_wr_private *mad_send_wr)
+ {
+ 	int ret;
++	struct ib_smp *smp = mad_send_wr->send_buf.mad;
+ 	unsigned long flags;
+ 	struct ib_mad_local_private *local;
+ 	struct ib_mad_private *mad_priv;
+@@ -666,6 +666,7 @@ static int handle_outgoing_dr_smp(struct
+ 	struct ib_device *device = mad_agent_priv->agent.device;
+ 	u8 port_num = mad_agent_priv->agent.port_num;
+ 	struct ib_wc mad_wc;
++	struct ib_send_wr *send_wr = &mad_send_wr->send_wr;
+ 
+ 	if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
+ 		ret = -EINVAL;
+@@ -745,13 +746,7 @@ static int handle_outgoing_dr_smp(struct
+ 		goto out;
+ 	}
+ 
+-	local->send_wr = *send_wr;
+-	local->send_wr.sg_list = local->sg_list;
+-	memcpy(local->sg_list, send_wr->sg_list,
+-	       sizeof *send_wr->sg_list * send_wr->num_sge);
+-	local->send_wr.next = NULL;
+-	local->tid = send_wr->wr.ud.mad_hdr->tid;
+-	local->wr_id = send_wr->wr_id;
++	local->mad_send_wr = mad_send_wr;
+ 	/* Reference MAD agent until send side of local completion handled */
+ 	atomic_inc(&mad_agent_priv->refcount);
+ 	/* Queue local completion to local list */
+@@ -781,17 +776,17 @@ static int get_buf_length(int hdr_len, i
+ 
+ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
+ 					    u32 remote_qpn, u16 pkey_index,
+-					    struct ib_ah *ah, int rmpp_active,
++					    int rmpp_active,
+ 					    int hdr_len, int data_len,
+ 					    gfp_t gfp_mask)
+ {
+ 	struct ib_mad_agent_private *mad_agent_priv;
+-	struct ib_mad_send_buf *send_buf;
++	struct ib_mad_send_wr_private *mad_send_wr;
+ 	int buf_size;
+ 	void *buf;
+ 
+-	mad_agent_priv = container_of(mad_agent,
+-				      struct ib_mad_agent_private, agent);
++	mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private,
++				      agent);
+ 	buf_size = get_buf_length(hdr_len, data_len);
+ 
+ 	if ((!mad_agent->rmpp_version &&
+@@ -799,45 +794,40 @@ struct ib_mad_send_buf * ib_create_send_
+ 	    (!rmpp_active && buf_size > sizeof(struct ib_mad)))
+ 		return ERR_PTR(-EINVAL);
+ 
+-	buf = kmalloc(sizeof *send_buf + buf_size, gfp_mask);
++	buf = kmalloc(sizeof *mad_send_wr + buf_size, gfp_mask);
+ 	if (!buf)
+ 		return ERR_PTR(-ENOMEM);
+-	memset(buf, 0, sizeof *send_buf + buf_size);
++	memset(buf, 0, sizeof *mad_send_wr + buf_size);
+ 
+-	send_buf = buf + buf_size;
+-	send_buf->mad = buf;
++	mad_send_wr = buf + buf_size;
++	mad_send_wr->send_buf.mad = buf;
+ 
+-	send_buf->sge.addr = dma_map_single(mad_agent->device->dma_device,
+-					    buf, buf_size, DMA_TO_DEVICE);
+-	pci_unmap_addr_set(send_buf, mapping, send_buf->sge.addr);
+-	send_buf->sge.length = buf_size;
+-	send_buf->sge.lkey = mad_agent->mr->lkey;
+-
+-	send_buf->send_wr.wr_id = (unsigned long) send_buf;
+-	send_buf->send_wr.sg_list = &send_buf->sge;
+-	send_buf->send_wr.num_sge = 1;
+-	send_buf->send_wr.opcode = IB_WR_SEND;
+-	send_buf->send_wr.send_flags = IB_SEND_SIGNALED;
+-	send_buf->send_wr.wr.ud.ah = ah;
+-	send_buf->send_wr.wr.ud.mad_hdr = &send_buf->mad->mad_hdr;
+-	send_buf->send_wr.wr.ud.remote_qpn = remote_qpn;
+-	send_buf->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY;
+-	send_buf->send_wr.wr.ud.pkey_index = pkey_index;
++	mad_send_wr->mad_agent_priv = mad_agent_priv;
++	mad_send_wr->sg_list[0].length = buf_size;
++	mad_send_wr->sg_list[0].lkey = mad_agent->mr->lkey;
++
++	mad_send_wr->send_wr.wr_id = (unsigned long) mad_send_wr;
++	mad_send_wr->send_wr.sg_list = mad_send_wr->sg_list;
++	mad_send_wr->send_wr.num_sge = 1;
++	mad_send_wr->send_wr.opcode = IB_WR_SEND;
++	mad_send_wr->send_wr.send_flags = IB_SEND_SIGNALED;
++	mad_send_wr->send_wr.wr.ud.remote_qpn = remote_qpn;
++	mad_send_wr->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY;
++	mad_send_wr->send_wr.wr.ud.pkey_index = pkey_index;
+ 
+ 	if (rmpp_active) {
+-		struct ib_rmpp_mad *rmpp_mad;
+-		rmpp_mad = (struct ib_rmpp_mad *)send_buf->mad;
++		struct ib_rmpp_mad *rmpp_mad = mad_send_wr->send_buf.mad;
+ 		rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(hdr_len -
+-			offsetof(struct ib_rmpp_mad, data) + data_len);
++						   IB_MGMT_RMPP_HDR + data_len);
+ 		rmpp_mad->rmpp_hdr.rmpp_version = mad_agent->rmpp_version;
+ 		rmpp_mad->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_DATA;
+ 		ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr,
+ 				  IB_MGMT_RMPP_FLAG_ACTIVE);
+ 	}
+ 
+-	send_buf->mad_agent = mad_agent;
++	mad_send_wr->send_buf.mad_agent = mad_agent;
+ 	atomic_inc(&mad_agent_priv->refcount);
+-	return send_buf;
++	return &mad_send_wr->send_buf;
+ }
+ EXPORT_SYMBOL(ib_create_send_mad);
+ 
+@@ -847,10 +837,6 @@ void ib_free_send_mad(struct ib_mad_send
+ 
+ 	mad_agent_priv = container_of(send_buf->mad_agent,
+ 				      struct ib_mad_agent_private, agent);
+-
+-	dma_unmap_single(send_buf->mad_agent->device->dma_device,
+-			 pci_unmap_addr(send_buf, mapping),
+-			 send_buf->sge.length, DMA_TO_DEVICE);
+ 	kfree(send_buf->mad);
+ 
+ 	if (atomic_dec_and_test(&mad_agent_priv->refcount))
+@@ -861,8 +847,10 @@ EXPORT_SYMBOL(ib_free_send_mad);
+ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
+ {
+ 	struct ib_mad_qp_info *qp_info;
+-	struct ib_send_wr *bad_send_wr;
+ 	struct list_head *list;
++	struct ib_send_wr *bad_send_wr;
++	struct ib_mad_agent *mad_agent;
++	struct ib_sge *sge;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -871,10 +859,17 @@ int ib_send_mad(struct ib_mad_send_wr_pr
+ 	mad_send_wr->send_wr.wr_id = (unsigned long)&mad_send_wr->mad_list;
+ 	mad_send_wr->mad_list.mad_queue = &qp_info->send_queue;
+ 
++	mad_agent = mad_send_wr->send_buf.mad_agent;
++	sge = mad_send_wr->sg_list;
++	sge->addr = dma_map_single(mad_agent->device->dma_device,
++				   mad_send_wr->send_buf.mad, sge->length,
++				   DMA_TO_DEVICE);
++	pci_unmap_addr_set(mad_send_wr, mapping, sge->addr);
++
+ 	spin_lock_irqsave(&qp_info->send_queue.lock, flags);
+ 	if (qp_info->send_queue.count < qp_info->send_queue.max_active) {
+-		ret = ib_post_send(mad_send_wr->mad_agent_priv->agent.qp,
+-				   &mad_send_wr->send_wr, &bad_send_wr);
++		ret = ib_post_send(mad_agent->qp, &mad_send_wr->send_wr,
++				   &bad_send_wr);
+ 		list = &qp_info->send_queue.list;
+ 	} else {
+ 		ret = 0;
+@@ -886,6 +881,11 @@ int ib_send_mad(struct ib_mad_send_wr_pr
+ 		list_add_tail(&mad_send_wr->mad_list.list, list);
+ 	}
+ 	spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
++	if (ret)
++		dma_unmap_single(mad_agent->device->dma_device,
++				 pci_unmap_addr(mad_send_wr, mapping),
++				 sge->length, DMA_TO_DEVICE);
++
+ 	return ret;
+ }
+ 
+@@ -893,45 +893,28 @@ int ib_send_mad(struct ib_mad_send_wr_pr
+  * ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated
+  *  with the registered client
+  */
+-int ib_post_send_mad(struct ib_mad_agent *mad_agent,
+-		     struct ib_send_wr *send_wr,
+-		     struct ib_send_wr **bad_send_wr)
++int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
++		     struct ib_mad_send_buf **bad_send_buf)
+ {
+-	int ret = -EINVAL;
+ 	struct ib_mad_agent_private *mad_agent_priv;
+-
+-	/* Validate supplied parameters */
+-	if (!bad_send_wr)
+-		goto error1;
+-
+-	if (!mad_agent || !send_wr)
+-		goto error2;
+-
+-	if (!mad_agent->send_handler)
+-		goto error2;
+-
+-	mad_agent_priv = container_of(mad_agent,
+-				      struct ib_mad_agent_private,
+-				      agent);
++	struct ib_mad_send_buf *next_send_buf;
++	struct ib_mad_send_wr_private *mad_send_wr;
++	unsigned long flags;
++	int ret = -EINVAL;
+ 
+ 	/* Walk list of send WRs and post each on send list */
+-	while (send_wr) {
+-		unsigned long			flags;
+-		struct ib_send_wr		*next_send_wr;
+-		struct ib_mad_send_wr_private	*mad_send_wr;
+-		struct ib_smp			*smp;
++	for (; send_buf; send_buf = next_send_buf) {
+ 
+-		/* Validate more parameters */
+-		if (send_wr->num_sge > IB_MAD_SEND_REQ_MAX_SG)
+-			goto error2;
+-
+-		if (send_wr->wr.ud.timeout_ms && !mad_agent->recv_handler)
+-			goto error2;
++		mad_send_wr = container_of(send_buf,
++					   struct ib_mad_send_wr_private,
++					   send_buf);
++		mad_agent_priv = mad_send_wr->mad_agent_priv;
+ 
+-		if (!send_wr->wr.ud.mad_hdr) {
+-			printk(KERN_ERR PFX "MAD header must be supplied "
+-			       "in WR %p\n", send_wr);
+-			goto error2;
++		if (!send_buf->mad_agent->send_handler ||
++		    (send_buf->timeout_ms &&
++		     !send_buf->mad_agent->recv_handler)) {
++			ret = -EINVAL;
++			goto error;
+ 		}
+ 
+ 		/*
+@@ -939,40 +922,24 @@ int ib_post_send_mad(struct ib_mad_agent
+ 		 * current one completes, and the user modifies the work
+ 		 * request associated with the completion
+ 		 */
+-		next_send_wr = (struct ib_send_wr *)send_wr->next;
++		next_send_buf = send_buf->next;
++		mad_send_wr->send_wr.wr.ud.ah = send_buf->ah;
+ 
+-		smp = (struct ib_smp *)send_wr->wr.ud.mad_hdr;
+-		if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
+-			ret = handle_outgoing_dr_smp(mad_agent_priv, smp,
+-						     send_wr);
++		if (((struct ib_mad_hdr *) send_buf->mad)->mgmt_class ==
++		    IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
++			ret = handle_outgoing_dr_smp(mad_agent_priv,
++						     mad_send_wr);
+ 			if (ret < 0)		/* error */
+-				goto error2;
++				goto error;
+ 			else if (ret == 1)	/* locally consumed */
+-				goto next;
+-		}
+-
+-		/* Allocate MAD send WR tracking structure */
+-		mad_send_wr = kmalloc(sizeof *mad_send_wr, GFP_ATOMIC);
+-		if (!mad_send_wr) {
+-			printk(KERN_ERR PFX "No memory for "
+-			       "ib_mad_send_wr_private\n");
+-			ret = -ENOMEM;
+-			goto error2;
++				continue;
+ 		}
+-		memset(mad_send_wr, 0, sizeof *mad_send_wr);
+ 
+-		mad_send_wr->send_wr = *send_wr;
+-		mad_send_wr->send_wr.sg_list = mad_send_wr->sg_list;
+-		memcpy(mad_send_wr->sg_list, send_wr->sg_list,
+-		       sizeof *send_wr->sg_list * send_wr->num_sge);
+-		mad_send_wr->wr_id = send_wr->wr_id;
+-		mad_send_wr->tid = send_wr->wr.ud.mad_hdr->tid;
+-		mad_send_wr->mad_agent_priv = mad_agent_priv;
++		mad_send_wr->tid = ((struct ib_mad_hdr *) send_buf->mad)->tid;
+ 		/* Timeout will be updated after send completes */
+-		mad_send_wr->timeout = msecs_to_jiffies(send_wr->wr.
+-							ud.timeout_ms);
+-		mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries;
+-		/* One reference for each work request to QP + response */
++		mad_send_wr->timeout = msecs_to_jiffies(send_buf->timeout_ms);
++		mad_send_wr->retries = send_buf->retries;
++		/* Reference for work request to QP + response */
+ 		mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0);
+ 		mad_send_wr->status = IB_WC_SUCCESS;
+ 
+@@ -995,16 +962,13 @@ int ib_post_send_mad(struct ib_mad_agent
+ 			list_del(&mad_send_wr->agent_list);
+ 			spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+ 			atomic_dec(&mad_agent_priv->refcount);
+-			goto error2;
++			goto error;
+ 		}
+-next:
+-		send_wr = next_send_wr;
+ 	}
+ 	return 0;
+-
+-error2:
+-	*bad_send_wr = send_wr;
+-error1:
++error:
++	if (bad_send_buf)
++		*bad_send_buf = send_buf;
+ 	return ret;
+ }
+ EXPORT_SYMBOL(ib_post_send_mad);
+@@ -1447,8 +1411,7 @@ find_mad_agent(struct ib_mad_port_privat
+ 		 * of MAD.
+ 		 */
+ 		hi_tid = be64_to_cpu(mad->mad_hdr.tid) >> 32;
+-		list_for_each_entry(entry, &port_priv->agent_list,
+-				    agent_list) {
++		list_for_each_entry(entry, &port_priv->agent_list, agent_list) {
+ 			if (entry->agent.hi_tid == hi_tid) {
+ 				mad_agent = entry;
+ 				break;
+@@ -1571,8 +1534,7 @@ ib_find_send_mad(struct ib_mad_agent_pri
+ 	 */
+ 	list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
+ 			    agent_list) {
+-		if (is_data_mad(mad_agent_priv,
+-				mad_send_wr->send_wr.wr.ud.mad_hdr) &&
++		if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) &&
+ 		    mad_send_wr->tid == tid && mad_send_wr->timeout) {
+ 			/* Verify request has not been canceled */
+ 			return (mad_send_wr->status == IB_WC_SUCCESS) ?
+@@ -1628,14 +1590,14 @@ static void ib_mad_complete_recv(struct 
+ 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+ 
+ 		/* Defined behavior is to complete response before request */
+-		mad_recv_wc->wc->wr_id = mad_send_wr->wr_id;
++		mad_recv_wc->wc->wr_id = (unsigned long) &mad_send_wr->send_buf;
+ 		mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
+ 						   mad_recv_wc);
+ 		atomic_dec(&mad_agent_priv->refcount);
+ 
+ 		mad_send_wc.status = IB_WC_SUCCESS;
+ 		mad_send_wc.vendor_err = 0;
+-		mad_send_wc.wr_id = mad_send_wr->wr_id;
++		mad_send_wc.send_buf = &mad_send_wr->send_buf;
+ 		ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc);
+ 	} else {
+ 		mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
+@@ -1728,11 +1690,11 @@ local:
+ 			if (ret & IB_MAD_RESULT_CONSUMED)
+ 				goto out;
+ 			if (ret & IB_MAD_RESULT_REPLY) {
+-				/* Send response */
+-				if (!agent_send(response, &recv->grh, wc,
+-						port_priv->device,
+-						port_priv->port_num))
+-					response = NULL;
++				agent_send_response(&response->mad.mad,
++						    &recv->grh, wc,
++						    port_priv->device,
++						    port_priv->port_num,
++						    qp_info->qp->qp_num);
+ 				goto out;
+ 			}
+ 		}
+@@ -1866,15 +1828,15 @@ void ib_mad_complete_send_wr(struct ib_m
+ 
+ 	if (mad_send_wr->status != IB_WC_SUCCESS )
+ 		mad_send_wc->status = mad_send_wr->status;
+-	if (ret != IB_RMPP_RESULT_INTERNAL)
++	if (ret == IB_RMPP_RESULT_INTERNAL)
++		ib_rmpp_send_handler(mad_send_wc);
++	else
+ 		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
+ 						   mad_send_wc);
+ 
+ 	/* Release reference on agent taken when sending */
+ 	if (atomic_dec_and_test(&mad_agent_priv->refcount))
+ 		wake_up(&mad_agent_priv->wait);
+-
+-	kfree(mad_send_wr);
+ 	return;
+ done:
+ 	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+@@ -1888,6 +1850,7 @@ static void ib_mad_send_done_handler(str
+ 	struct ib_mad_qp_info		*qp_info;
+ 	struct ib_mad_queue		*send_queue;
+ 	struct ib_send_wr		*bad_send_wr;
++	struct ib_mad_send_wc		mad_send_wc;
+ 	unsigned long flags;
+ 	int ret;
+ 
+@@ -1898,6 +1861,9 @@ static void ib_mad_send_done_handler(str
+ 	qp_info = send_queue->qp_info;
+ 
+ retry:
++	dma_unmap_single(mad_send_wr->send_buf.mad_agent->device->dma_device,
++			 pci_unmap_addr(mad_send_wr, mapping),
++			 mad_send_wr->sg_list[0].length, DMA_TO_DEVICE);
+ 	queued_send_wr = NULL;
+ 	spin_lock_irqsave(&send_queue->lock, flags);
+ 	list_del(&mad_list->list);
+@@ -1914,17 +1880,17 @@ retry:
+ 	}
+ 	spin_unlock_irqrestore(&send_queue->lock, flags);
+ 
+-	/* Restore client wr_id in WC and complete send */
+-	wc->wr_id = mad_send_wr->wr_id;
++	mad_send_wc.send_buf = &mad_send_wr->send_buf;
++	mad_send_wc.status = wc->status;
++	mad_send_wc.vendor_err = wc->vendor_err;
+ 	if (atomic_read(&qp_info->snoop_count))
+-		snoop_send(qp_info, &mad_send_wr->send_wr,
+-			   (struct ib_mad_send_wc *)wc,
++		snoop_send(qp_info, &mad_send_wr->send_buf, &mad_send_wc,
+ 			   IB_MAD_SNOOP_SEND_COMPLETIONS);
+-	ib_mad_complete_send_wr(mad_send_wr, (struct ib_mad_send_wc *)wc);
++	ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc);
+ 
+ 	if (queued_send_wr) {
+ 		ret = ib_post_send(qp_info->qp, &queued_send_wr->send_wr,
+-				&bad_send_wr);
++				   &bad_send_wr);
+ 		if (ret) {
+ 			printk(KERN_ERR PFX "ib_post_send failed: %d\n", ret);
+ 			mad_send_wr = queued_send_wr;
+@@ -2066,38 +2032,37 @@ static void cancel_mads(struct ib_mad_ag
+ 
+ 	list_for_each_entry_safe(mad_send_wr, temp_mad_send_wr,
+ 				 &cancel_list, agent_list) {
+-		mad_send_wc.wr_id = mad_send_wr->wr_id;
++		mad_send_wc.send_buf = &mad_send_wr->send_buf;
++		list_del(&mad_send_wr->agent_list);
+ 		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
+ 						   &mad_send_wc);
+-
+-		list_del(&mad_send_wr->agent_list);
+-		kfree(mad_send_wr);
+ 		atomic_dec(&mad_agent_priv->refcount);
+ 	}
+ }
+ 
+ static struct ib_mad_send_wr_private*
+-find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv, u64 wr_id)
++find_send_wr(struct ib_mad_agent_private *mad_agent_priv,
++	     struct ib_mad_send_buf *send_buf)
+ {
+ 	struct ib_mad_send_wr_private *mad_send_wr;
+ 
+ 	list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list,
+ 			    agent_list) {
+-		if (mad_send_wr->wr_id == wr_id)
++		if (&mad_send_wr->send_buf == send_buf)
+ 			return mad_send_wr;
+ 	}
+ 
+ 	list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
+ 			    agent_list) {
+-		if (is_data_mad(mad_agent_priv,
+-				mad_send_wr->send_wr.wr.ud.mad_hdr) &&
+-		    mad_send_wr->wr_id == wr_id)
++		if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) &&
++		    &mad_send_wr->send_buf == send_buf)
+ 			return mad_send_wr;
+ 	}
+ 	return NULL;
+ }
+ 
+-int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms)
++int ib_modify_mad(struct ib_mad_agent *mad_agent,
++		  struct ib_mad_send_buf *send_buf, u32 timeout_ms)
+ {
+ 	struct ib_mad_agent_private *mad_agent_priv;
+ 	struct ib_mad_send_wr_private *mad_send_wr;
+@@ -2107,7 +2072,7 @@ int ib_modify_mad(struct ib_mad_agent *m
+ 	mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private,
+ 				      agent);
+ 	spin_lock_irqsave(&mad_agent_priv->lock, flags);
+-	mad_send_wr = find_send_by_wr_id(mad_agent_priv, wr_id);
++	mad_send_wr = find_send_wr(mad_agent_priv, send_buf);
+ 	if (!mad_send_wr || mad_send_wr->status != IB_WC_SUCCESS) {
+ 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+ 		return -EINVAL;
+@@ -2119,7 +2084,7 @@ int ib_modify_mad(struct ib_mad_agent *m
+ 		mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
+ 	}
+ 
+-	mad_send_wr->send_wr.wr.ud.timeout_ms = timeout_ms;
++	mad_send_wr->send_buf.timeout_ms = timeout_ms;
+ 	if (active)
+ 		mad_send_wr->timeout = msecs_to_jiffies(timeout_ms);
+ 	else
+@@ -2130,9 +2095,10 @@ int ib_modify_mad(struct ib_mad_agent *m
+ }
+ EXPORT_SYMBOL(ib_modify_mad);
+ 
+-void ib_cancel_mad(struct ib_mad_agent *mad_agent, u64 wr_id)
++void ib_cancel_mad(struct ib_mad_agent *mad_agent,
++		   struct ib_mad_send_buf *send_buf)
+ {
+-	ib_modify_mad(mad_agent, wr_id, 0);
++	ib_modify_mad(mad_agent, send_buf, 0);
+ }
+ EXPORT_SYMBOL(ib_cancel_mad);
+ 
+@@ -2166,10 +2132,9 @@ static void local_completions(void *data
+ 			 * Defined behavior is to complete response
+ 			 * before request
+ 			 */
+-			build_smp_wc(local->wr_id,
++			build_smp_wc((unsigned long) local->mad_send_wr,
+ 				     be16_to_cpu(IB_LID_PERMISSIVE),
+-				     0 /* pkey index */,
+-				     recv_mad_agent->agent.port_num, &wc);
++				     0, recv_mad_agent->agent.port_num, &wc);
+ 
+ 			local->mad_priv->header.recv_wc.wc = &wc;
+ 			local->mad_priv->header.recv_wc.mad_len =
+@@ -2196,11 +2161,11 @@ local_send_completion:
+ 		/* Complete send */
+ 		mad_send_wc.status = IB_WC_SUCCESS;
+ 		mad_send_wc.vendor_err = 0;
+-		mad_send_wc.wr_id = local->wr_id;
++		mad_send_wc.send_buf = &local->mad_send_wr->send_buf;
+ 		if (atomic_read(&mad_agent_priv->qp_info->snoop_count))
+-			snoop_send(mad_agent_priv->qp_info, &local->send_wr,
+-				  &mad_send_wc,
+-				   IB_MAD_SNOOP_SEND_COMPLETIONS);
++			snoop_send(mad_agent_priv->qp_info,
++				   &local->mad_send_wr->send_buf,
++				   &mad_send_wc, IB_MAD_SNOOP_SEND_COMPLETIONS);
+ 		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
+ 						   &mad_send_wc);
+ 
+@@ -2221,8 +2186,7 @@ static int retry_send(struct ib_mad_send
+ 	if (!mad_send_wr->retries--)
+ 		return -ETIMEDOUT;
+ 
+-	mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_wr.
+-						wr.ud.timeout_ms);
++	mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms);
+ 
+ 	if (mad_send_wr->mad_agent_priv->agent.rmpp_version) {
+ 		ret = ib_retry_rmpp(mad_send_wr);
+@@ -2285,11 +2249,10 @@ static void timeout_sends(void *data)
+ 			mad_send_wc.status = IB_WC_RESP_TIMEOUT_ERR;
+ 		else
+ 			mad_send_wc.status = mad_send_wr->status;
+-		mad_send_wc.wr_id = mad_send_wr->wr_id;
++		mad_send_wc.send_buf = &mad_send_wr->send_buf;
+ 		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
+ 						   &mad_send_wc);
+ 
+-		kfree(mad_send_wr);
+ 		atomic_dec(&mad_agent_priv->refcount);
+ 		spin_lock_irqsave(&mad_agent_priv->lock, flags);
+ 	}
+@@ -2683,40 +2646,47 @@ static int ib_mad_port_close(struct ib_d
+ 
+ static void ib_mad_init_device(struct ib_device *device)
+ {
+-	int num_ports, cur_port, i;
++	int start, end, i;
+ 
+ 	if (device->node_type == IB_NODE_SWITCH) {
+-		num_ports = 1;
+-		cur_port = 0;
++		start = 0;
++		end   = 0;
+ 	} else {
+-		num_ports = device->phys_port_cnt;
+-		cur_port = 1;
++		start = 1;
++		end   = device->phys_port_cnt;
+ 	}
+-	for (i = 0; i < num_ports; i++, cur_port++) {
+-		if (ib_mad_port_open(device, cur_port)) {
++
++	for (i = start; i <= end; i++) {
++		if (ib_mad_port_open(device, i)) {
+ 			printk(KERN_ERR PFX "Couldn't open %s port %d\n",
+-			       device->name, cur_port);
+-			goto error_device_open;
++			       device->name, i);
++			goto error;
+ 		}
+-		if (ib_agent_port_open(device, cur_port)) {
++		if (ib_agent_port_open(device, i)) {
+ 			printk(KERN_ERR PFX "Couldn't open %s port %d "
+ 			       "for agents\n",
+-			       device->name, cur_port);
+-			goto error_device_open;
++			       device->name, i);
++			goto error_agent;
+ 		}
+ 	}
+ 	return;
+ 
+-error_device_open:
+-	while (i > 0) {
+-		cur_port--;
+-		if (ib_agent_port_close(device, cur_port))
++error_agent:
++	if (ib_mad_port_close(device, i))
++		printk(KERN_ERR PFX "Couldn't close %s port %d\n",
++		       device->name, i);
++
++error:
++	i--;
++
++	while (i >= start) {
++		if (ib_agent_port_close(device, i))
+ 			printk(KERN_ERR PFX "Couldn't close %s port %d "
+ 			       "for agents\n",
+-			       device->name, cur_port);
+-		if (ib_mad_port_close(device, cur_port))
++			       device->name, i);
++		if (ib_mad_port_close(device, i))
+ 			printk(KERN_ERR PFX "Couldn't close %s port %d\n",
+-			       device->name, cur_port);
++			       device->name, i);
+ 		i--;
+ 	}
+ }
+@@ -2754,7 +2724,6 @@ static int __init ib_mad_init_module(voi
+ 	int ret;
+ 
+ 	spin_lock_init(&ib_mad_port_list_lock);
+-	spin_lock_init(&ib_agent_port_list_lock);
+ 
+ 	ib_mad_cache = kmem_cache_create("ib_mad",
+ 					 sizeof(struct ib_mad_private),
+diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
+--- a/drivers/infiniband/core/mad_priv.h
++++ b/drivers/infiniband/core/mad_priv.h
+@@ -118,9 +118,10 @@ struct ib_mad_send_wr_private {
+ 	struct ib_mad_list_head mad_list;
+ 	struct list_head agent_list;
+ 	struct ib_mad_agent_private *mad_agent_priv;
++	struct ib_mad_send_buf send_buf;
++	DECLARE_PCI_UNMAP_ADDR(mapping)
+ 	struct ib_send_wr send_wr;
+ 	struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
+-	u64 wr_id;			/* client WR ID */
+ 	__be64 tid;
+ 	unsigned long timeout;
+ 	int retries;
+@@ -141,10 +142,7 @@ struct ib_mad_local_private {
+ 	struct list_head completion_list;
+ 	struct ib_mad_private *mad_priv;
+ 	struct ib_mad_agent_private *recv_mad_agent;
+-	struct ib_send_wr send_wr;
+-	struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
+-	u64 wr_id;			/* client WR ID */
+-	__be64 tid;
++	struct ib_mad_send_wr_private *mad_send_wr;
+ };
+ 
+ struct ib_mad_mgmt_method_table {
+diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
+--- a/drivers/infiniband/core/mad_rmpp.c
++++ b/drivers/infiniband/core/mad_rmpp.c
+@@ -103,12 +103,12 @@ void ib_cancel_rmpp_recvs(struct ib_mad_
+ static int data_offset(u8 mgmt_class)
+ {
+ 	if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
+-		return offsetof(struct ib_sa_mad, data);
++		return IB_MGMT_SA_HDR;
+ 	else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
+ 		 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
+-		return offsetof(struct ib_vendor_mad, data);
++		return IB_MGMT_VENDOR_HDR;
+ 	else
+-		return offsetof(struct ib_rmpp_mad, data);
++		return IB_MGMT_RMPP_HDR;
+ }
+ 
+ static void format_ack(struct ib_rmpp_mad *ack,
+@@ -135,55 +135,52 @@ static void ack_recv(struct mad_rmpp_rec
+ 		     struct ib_mad_recv_wc *recv_wc)
+ {
+ 	struct ib_mad_send_buf *msg;
+-	struct ib_send_wr *bad_send_wr;
+-	int hdr_len, ret;
++	int ret;
+ 
+-	hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr);
+ 	msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
+-				 recv_wc->wc->pkey_index, rmpp_recv->ah, 1,
+-				 hdr_len, sizeof(struct ib_rmpp_mad) - hdr_len,
+-				 GFP_KERNEL);
++				 recv_wc->wc->pkey_index, 1, IB_MGMT_RMPP_HDR,
++				 IB_MGMT_RMPP_DATA, GFP_KERNEL);
+ 	if (!msg)
+ 		return;
+ 
+-	format_ack((struct ib_rmpp_mad *) msg->mad,
+-		   (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv);
+-	ret = ib_post_send_mad(&rmpp_recv->agent->agent, &msg->send_wr,
+-			       &bad_send_wr);
++	format_ack(msg->mad, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad,
++		   rmpp_recv);
++	msg->ah = rmpp_recv->ah;
++	ret = ib_post_send_mad(msg, NULL);
+ 	if (ret)
+ 		ib_free_send_mad(msg);
+ }
+ 
+-static int alloc_response_msg(struct ib_mad_agent *agent,
+-			      struct ib_mad_recv_wc *recv_wc,
+-			      struct ib_mad_send_buf **msg)
++static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent,
++						  struct ib_mad_recv_wc *recv_wc)
+ {
+-	struct ib_mad_send_buf *m;
++	struct ib_mad_send_buf *msg;
+ 	struct ib_ah *ah;
+-	int hdr_len;
+ 
+ 	ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc,
+ 				  recv_wc->recv_buf.grh, agent->port_num);
+ 	if (IS_ERR(ah))
+-		return PTR_ERR(ah);
++		return (void *) ah;
+ 
+-	hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr);
+-	m = ib_create_send_mad(agent, recv_wc->wc->src_qp,
+-			       recv_wc->wc->pkey_index, ah, 1, hdr_len,
+-			       sizeof(struct ib_rmpp_mad) - hdr_len,
+-			       GFP_KERNEL);
+-	if (IS_ERR(m)) {
++	msg = ib_create_send_mad(agent, recv_wc->wc->src_qp,
++				 recv_wc->wc->pkey_index, 1,
++				 IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA,
++				 GFP_KERNEL);
++	if (IS_ERR(msg))
+ 		ib_destroy_ah(ah);
+-		return PTR_ERR(m);
+-	}
+-	*msg = m;
+-	return 0;
++	else
++		msg->ah = ah;
++
++	return msg;
+ }
+ 
+-static void free_msg(struct ib_mad_send_buf *msg)
++void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc)
+ {
+-	ib_destroy_ah(msg->send_wr.wr.ud.ah);
+-	ib_free_send_mad(msg);
++	struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad;
++
++	if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK)
++		ib_destroy_ah(mad_send_wc->send_buf->ah);
++	ib_free_send_mad(mad_send_wc->send_buf);
+ }
+ 
+ static void nack_recv(struct ib_mad_agent_private *agent,
+@@ -191,14 +188,13 @@ static void nack_recv(struct ib_mad_agen
+ {
+ 	struct ib_mad_send_buf *msg;
+ 	struct ib_rmpp_mad *rmpp_mad;
+-	struct ib_send_wr *bad_send_wr;
+ 	int ret;
+ 
+-	ret = alloc_response_msg(&agent->agent, recv_wc, &msg);
+-	if (ret)
++	msg = alloc_response_msg(&agent->agent, recv_wc);
++	if (IS_ERR(msg))
+ 		return;
+ 
+-	rmpp_mad = (struct ib_rmpp_mad *) msg->mad;
++	rmpp_mad = msg->mad;
+ 	memcpy(rmpp_mad, recv_wc->recv_buf.mad,
+ 	       data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class));
+ 
+@@ -210,9 +206,11 @@ static void nack_recv(struct ib_mad_agen
+ 	rmpp_mad->rmpp_hdr.seg_num = 0;
+ 	rmpp_mad->rmpp_hdr.paylen_newwin = 0;
+ 
+-	ret = ib_post_send_mad(&agent->agent, &msg->send_wr, &bad_send_wr);
+-	if (ret)
+-		free_msg(msg);
++	ret = ib_post_send_mad(msg, NULL);
++	if (ret) {
++		ib_destroy_ah(msg->ah);
++		ib_free_send_mad(msg);
++	}
+ }
+ 
+ static void recv_timeout_handler(void *data)
+@@ -585,7 +583,7 @@ static int send_next_seg(struct ib_mad_s
+ 	int timeout;
+ 	u32 paylen;
+ 
+-	rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
++	rmpp_mad = mad_send_wr->send_buf.mad;
+ 	ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
+ 	rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(mad_send_wr->seg_num);
+ 
+@@ -612,7 +610,7 @@ static int send_next_seg(struct ib_mad_s
+ 	}
+ 
+ 	/* 2 seconds for an ACK until we can find the packet lifetime */
+-	timeout = mad_send_wr->send_wr.wr.ud.timeout_ms;
++	timeout = mad_send_wr->send_buf.timeout_ms;
+ 	if (!timeout || timeout > 2000)
+ 		mad_send_wr->timeout = msecs_to_jiffies(2000);
+ 	mad_send_wr->seg_num++;
+@@ -640,7 +638,7 @@ static void abort_send(struct ib_mad_age
+ 
+ 	wc.status = IB_WC_REM_ABORT_ERR;
+ 	wc.vendor_err = rmpp_status;
+-	wc.wr_id = mad_send_wr->wr_id;
++	wc.send_buf = &mad_send_wr->send_buf;
+ 	ib_mad_complete_send_wr(mad_send_wr, &wc);
+ 	return;
+ out:
+@@ -694,12 +692,12 @@ static void process_rmpp_ack(struct ib_m
+ 
+ 	if (seg_num > mad_send_wr->last_ack) {
+ 		mad_send_wr->last_ack = seg_num;
+-		mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries;
++		mad_send_wr->retries = mad_send_wr->send_buf.retries;
+ 	}
+ 	mad_send_wr->newwin = newwin;
+ 	if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
+ 		/* If no response is expected, the ACK completes the send */
+-		if (!mad_send_wr->send_wr.wr.ud.timeout_ms) {
++		if (!mad_send_wr->send_buf.timeout_ms) {
+ 			struct ib_mad_send_wc wc;
+ 
+ 			ib_mark_mad_done(mad_send_wr);
+@@ -707,13 +705,13 @@ static void process_rmpp_ack(struct ib_m
+ 
+ 			wc.status = IB_WC_SUCCESS;
+ 			wc.vendor_err = 0;
+-			wc.wr_id = mad_send_wr->wr_id;
++			wc.send_buf = &mad_send_wr->send_buf;
+ 			ib_mad_complete_send_wr(mad_send_wr, &wc);
+ 			return;
+ 		}
+ 		if (mad_send_wr->refcount == 1)
+-			ib_reset_mad_timeout(mad_send_wr, mad_send_wr->
+-					     send_wr.wr.ud.timeout_ms);
++			ib_reset_mad_timeout(mad_send_wr,
++					     mad_send_wr->send_buf.timeout_ms);
+ 	} else if (mad_send_wr->refcount == 1 &&
+ 		   mad_send_wr->seg_num < mad_send_wr->newwin &&
+ 		   mad_send_wr->seg_num <= mad_send_wr->total_seg) {
+@@ -842,7 +840,7 @@ int ib_send_rmpp_mad(struct ib_mad_send_
+ 	struct ib_rmpp_mad *rmpp_mad;
+ 	int i, total_len, ret;
+ 
+-	rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
++	rmpp_mad = mad_send_wr->send_buf.mad;
+ 	if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+ 	      IB_MGMT_RMPP_FLAG_ACTIVE))
+ 		return IB_RMPP_RESULT_UNHANDLED;
+@@ -863,7 +861,7 @@ int ib_send_rmpp_mad(struct ib_mad_send_
+ 
+         mad_send_wr->total_seg = (total_len - mad_send_wr->data_offset) /
+ 			(sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset);
+-	mad_send_wr->pad = total_len - offsetof(struct ib_rmpp_mad, data) -
++	mad_send_wr->pad = total_len - IB_MGMT_RMPP_HDR -
+ 			   be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
+ 
+ 	/* We need to wait for the final ACK even if there isn't a response */
+@@ -878,23 +876,15 @@ int ib_process_rmpp_send_wc(struct ib_ma
+ 			    struct ib_mad_send_wc *mad_send_wc)
+ {
+ 	struct ib_rmpp_mad *rmpp_mad;
+-	struct ib_mad_send_buf *msg;
+ 	int ret;
+ 
+-	rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
++	rmpp_mad = mad_send_wr->send_buf.mad;
+ 	if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+ 	      IB_MGMT_RMPP_FLAG_ACTIVE))
+ 		return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */
+ 
+-	if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) {
+-		msg = (struct ib_mad_send_buf *) (unsigned long)
+-		      mad_send_wc->wr_id;
+-		if (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_ACK)
+-			ib_free_send_mad(msg);
+-		else
+-			free_msg(msg);
++	if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA)
+ 		return IB_RMPP_RESULT_INTERNAL;	 /* ACK, STOP, or ABORT */
+-	}
+ 
+ 	if (mad_send_wc->status != IB_WC_SUCCESS ||
+ 	    mad_send_wr->status != IB_WC_SUCCESS)
+@@ -905,7 +895,7 @@ int ib_process_rmpp_send_wc(struct ib_ma
+ 
+ 	if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
+ 		mad_send_wr->timeout =
+-			msecs_to_jiffies(mad_send_wr->send_wr.wr.ud.timeout_ms);
++			msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms);
+ 		return IB_RMPP_RESULT_PROCESSED; /* Send done */
+ 	}
+ 
+@@ -926,7 +916,7 @@ int ib_retry_rmpp(struct ib_mad_send_wr_
+ 	struct ib_rmpp_mad *rmpp_mad;
+ 	int ret;
+ 
+-	rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
++	rmpp_mad = mad_send_wr->send_buf.mad;
+ 	if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+ 	      IB_MGMT_RMPP_FLAG_ACTIVE))
+ 		return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */
+diff --git a/drivers/infiniband/core/mad_rmpp.h b/drivers/infiniband/core/mad_rmpp.h
+--- a/drivers/infiniband/core/mad_rmpp.h
++++ b/drivers/infiniband/core/mad_rmpp.h
+@@ -51,6 +51,8 @@ ib_process_rmpp_recv_wc(struct ib_mad_ag
+ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
+ 			    struct ib_mad_send_wc *mad_send_wc);
+ 
++void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc);
++
+ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent);
+ 
+ int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr);
+diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
+--- a/drivers/infiniband/core/sa_query.c
++++ b/drivers/infiniband/core/sa_query.c
+@@ -43,6 +43,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/kref.h>
+ #include <linux/idr.h>
++#include <linux/workqueue.h>
+ 
+ #include <rdma/ib_pack.h>
+ #include <rdma/ib_sa.h>
+@@ -73,11 +74,10 @@ struct ib_sa_device {
+ struct ib_sa_query {
+ 	void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
+ 	void (*release)(struct ib_sa_query *);
+-	struct ib_sa_port  *port;
+-	struct ib_sa_mad   *mad;
+-	struct ib_sa_sm_ah *sm_ah;
+-	DECLARE_PCI_UNMAP_ADDR(mapping)
+-	int                 id;
++	struct ib_sa_port      *port;
++	struct ib_mad_send_buf *mad_buf;
++	struct ib_sa_sm_ah     *sm_ah;
++	int			id;
+ };
+ 
+ struct ib_sa_service_query {
+@@ -426,6 +426,7 @@ void ib_sa_cancel_query(int id, struct i
+ {
+ 	unsigned long flags;
+ 	struct ib_mad_agent *agent;
++	struct ib_mad_send_buf *mad_buf;
+ 
+ 	spin_lock_irqsave(&idr_lock, flags);
+ 	if (idr_find(&query_idr, id) != query) {
+@@ -433,9 +434,10 @@ void ib_sa_cancel_query(int id, struct i
+ 		return;
+ 	}
+ 	agent = query->port->agent;
++	mad_buf = query->mad_buf;
+ 	spin_unlock_irqrestore(&idr_lock, flags);
+ 
+-	ib_cancel_mad(agent, id);
++	ib_cancel_mad(agent, mad_buf);
+ }
+ EXPORT_SYMBOL(ib_sa_cancel_query);
+ 
+@@ -457,71 +459,46 @@ static void init_mad(struct ib_sa_mad *m
+ 
+ static int send_mad(struct ib_sa_query *query, int timeout_ms)
+ {
+-	struct ib_sa_port *port = query->port;
+ 	unsigned long flags;
+-	int ret;
+-	struct ib_sge      gather_list;
+-	struct ib_send_wr *bad_wr, wr = {
+-		.opcode      = IB_WR_SEND,
+-		.sg_list     = &gather_list,
+-		.num_sge     = 1,
+-		.send_flags  = IB_SEND_SIGNALED,
+-		.wr	     = {
+-			 .ud = {
+-				 .mad_hdr     = &query->mad->mad_hdr,
+-				 .remote_qpn  = 1,
+-				 .remote_qkey = IB_QP1_QKEY,
+-				 .timeout_ms  = timeout_ms,
+-			 }
+-		 }
+-	};
++	int ret, id;
+ 
+ retry:
+ 	if (!idr_pre_get(&query_idr, GFP_ATOMIC))
+ 		return -ENOMEM;
+ 	spin_lock_irqsave(&idr_lock, flags);
+-	ret = idr_get_new(&query_idr, query, &query->id);
++	ret = idr_get_new(&query_idr, query, &id);
+ 	spin_unlock_irqrestore(&idr_lock, flags);
+ 	if (ret == -EAGAIN)
+ 		goto retry;
+ 	if (ret)
+ 		return ret;
+ 
+-	wr.wr_id = query->id;
++	query->mad_buf->timeout_ms  = timeout_ms;
++	query->mad_buf->context[0] = query;
++	query->id = id;
++
++	spin_lock_irqsave(&query->port->ah_lock, flags);
++	kref_get(&query->port->sm_ah->ref);
++	query->sm_ah = query->port->sm_ah;
++	spin_unlock_irqrestore(&query->port->ah_lock, flags);
+ 
+-	spin_lock_irqsave(&port->ah_lock, flags);
+-	kref_get(&port->sm_ah->ref);
+-	query->sm_ah = port->sm_ah;
+-	wr.wr.ud.ah  = port->sm_ah->ah;
+-	spin_unlock_irqrestore(&port->ah_lock, flags);
+-
+-	gather_list.addr   = dma_map_single(port->agent->device->dma_device,
+-					    query->mad,
+-					    sizeof (struct ib_sa_mad),
+-					    DMA_TO_DEVICE);
+-	gather_list.length = sizeof (struct ib_sa_mad);
+-	gather_list.lkey   = port->agent->mr->lkey;
+-	pci_unmap_addr_set(query, mapping, gather_list.addr);
++	query->mad_buf->ah = query->sm_ah->ah;
+ 
+-	ret = ib_post_send_mad(port->agent, &wr, &bad_wr);
++	ret = ib_post_send_mad(query->mad_buf, NULL);
+ 	if (ret) {
+-		dma_unmap_single(port->agent->device->dma_device,
+-				 pci_unmap_addr(query, mapping),
+-				 sizeof (struct ib_sa_mad),
+-				 DMA_TO_DEVICE);
+-		kref_put(&query->sm_ah->ref, free_sm_ah);
+ 		spin_lock_irqsave(&idr_lock, flags);
+-		idr_remove(&query_idr, query->id);
++		idr_remove(&query_idr, id);
+ 		spin_unlock_irqrestore(&idr_lock, flags);
++
++		kref_put(&query->sm_ah->ref, free_sm_ah);
+ 	}
+ 
+ 	/*
+ 	 * It's not safe to dereference query any more, because the
+ 	 * send may already have completed and freed the query in
+-	 * another context.  So use wr.wr_id, which has a copy of the
+-	 * query's id.
++	 * another context.
+ 	 */
+-	return ret ? ret : wr.wr_id;
++	return ret ? ret : id;
+ }
+ 
+ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
+@@ -543,7 +520,6 @@ static void ib_sa_path_rec_callback(stru
+ 
+ static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
+ {
+-	kfree(sa_query->mad);
+ 	kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
+ }
+ 
+@@ -583,43 +559,58 @@ int ib_sa_path_rec_get(struct ib_device 
+ {
+ 	struct ib_sa_path_query *query;
+ 	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
+-	struct ib_sa_port   *port   = &sa_dev->port[port_num - sa_dev->start_port];
+-	struct ib_mad_agent *agent  = port->agent;
++	struct ib_sa_port   *port;
++	struct ib_mad_agent *agent;
++	struct ib_sa_mad *mad;
+ 	int ret;
+ 
++	if (!sa_dev)
++		return -ENODEV;
++
++	port  = &sa_dev->port[port_num - sa_dev->start_port];
++	agent = port->agent;
++
+ 	query = kmalloc(sizeof *query, gfp_mask);
+ 	if (!query)
+ 		return -ENOMEM;
+-	query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
+-	if (!query->sa_query.mad) {
+-		kfree(query);
+-		return -ENOMEM;
++
++	query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
++						     0, IB_MGMT_SA_HDR,
++						     IB_MGMT_SA_DATA, gfp_mask);
++	if (!query->sa_query.mad_buf) {
++		ret = -ENOMEM;
++		goto err1;
+ 	}
+ 
+ 	query->callback = callback;
+ 	query->context  = context;
+ 
+-	init_mad(query->sa_query.mad, agent);
++	mad = query->sa_query.mad_buf->mad;
++	init_mad(mad, agent);
+ 
+-	query->sa_query.callback              = callback ? ib_sa_path_rec_callback : NULL;
+-	query->sa_query.release               = ib_sa_path_rec_release;
+-	query->sa_query.port                  = port;
+-	query->sa_query.mad->mad_hdr.method   = IB_MGMT_METHOD_GET;
+-	query->sa_query.mad->mad_hdr.attr_id  = cpu_to_be16(IB_SA_ATTR_PATH_REC);
+-	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
++	query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
++	query->sa_query.release  = ib_sa_path_rec_release;
++	query->sa_query.port     = port;
++	mad->mad_hdr.method	 = IB_MGMT_METHOD_GET;
++	mad->mad_hdr.attr_id	 = cpu_to_be16(IB_SA_ATTR_PATH_REC);
++	mad->sa_hdr.comp_mask	 = comp_mask;
+ 
+-	ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table),
+-		rec, query->sa_query.mad->data);
++	ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, mad->data);
+ 
+ 	*sa_query = &query->sa_query;
+ 
+ 	ret = send_mad(&query->sa_query, timeout_ms);
+-	if (ret < 0) {
+-		*sa_query = NULL;
+-		kfree(query->sa_query.mad);
+-		kfree(query);
+-	}
++	if (ret < 0)
++		goto err2;
++
++	return ret;
+ 
++err2:
++	*sa_query = NULL;
++	ib_free_send_mad(query->sa_query.mad_buf);
++
++err1:
++	kfree(query);
+ 	return ret;
+ }
+ EXPORT_SYMBOL(ib_sa_path_rec_get);
+@@ -643,7 +634,6 @@ static void ib_sa_service_rec_callback(s
+ 
+ static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
+ {
+-	kfree(sa_query->mad);
+ 	kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
+ }
+ 
+@@ -685,10 +675,17 @@ int ib_sa_service_rec_query(struct ib_de
+ {
+ 	struct ib_sa_service_query *query;
+ 	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
+-	struct ib_sa_port   *port   = &sa_dev->port[port_num - sa_dev->start_port];
+-	struct ib_mad_agent *agent  = port->agent;
++	struct ib_sa_port   *port;
++	struct ib_mad_agent *agent;
++	struct ib_sa_mad *mad;
+ 	int ret;
+ 
++	if (!sa_dev)
++		return -ENODEV;
++
++	port  = &sa_dev->port[port_num - sa_dev->start_port];
++	agent = port->agent;
++
+ 	if (method != IB_MGMT_METHOD_GET &&
+ 	    method != IB_MGMT_METHOD_SET &&
+ 	    method != IB_SA_METHOD_DELETE)
+@@ -697,37 +694,45 @@ int ib_sa_service_rec_query(struct ib_de
+ 	query = kmalloc(sizeof *query, gfp_mask);
+ 	if (!query)
+ 		return -ENOMEM;
+-	query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
+-	if (!query->sa_query.mad) {
+-		kfree(query);
+-		return -ENOMEM;
++
++	query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
++						     0, IB_MGMT_SA_HDR,
++						     IB_MGMT_SA_DATA, gfp_mask);
++	if (!query->sa_query.mad_buf) {
++		ret = -ENOMEM;
++		goto err1;
+ 	}
+ 
+ 	query->callback = callback;
+ 	query->context  = context;
+ 
+-	init_mad(query->sa_query.mad, agent);
++	mad = query->sa_query.mad_buf->mad;
++	init_mad(mad, agent);
+ 
+-	query->sa_query.callback              = callback ? ib_sa_service_rec_callback : NULL;
+-	query->sa_query.release               = ib_sa_service_rec_release;
+-	query->sa_query.port                  = port;
+-	query->sa_query.mad->mad_hdr.method   = method;
+-	query->sa_query.mad->mad_hdr.attr_id  =
+-				cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
+-	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
++	query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
++	query->sa_query.release  = ib_sa_service_rec_release;
++	query->sa_query.port     = port;
++	mad->mad_hdr.method	 = method;
++	mad->mad_hdr.attr_id	 = cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
++	mad->sa_hdr.comp_mask	 = comp_mask;
+ 
+ 	ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
+-		rec, query->sa_query.mad->data);
++		rec, mad->data);
+ 
+ 	*sa_query = &query->sa_query;
+ 
+ 	ret = send_mad(&query->sa_query, timeout_ms);
+-	if (ret < 0) {
+-		*sa_query = NULL;
+-		kfree(query->sa_query.mad);
+-		kfree(query);
+-	}
++	if (ret < 0)
++		goto err2;
++
++	return ret;
+ 
++err2:
++	*sa_query = NULL;
++	ib_free_send_mad(query->sa_query.mad_buf);
++
++err1:
++	kfree(query);
+ 	return ret;
+ }
+ EXPORT_SYMBOL(ib_sa_service_rec_query);
+@@ -751,7 +756,6 @@ static void ib_sa_mcmember_rec_callback(
+ 
+ static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
+ {
+-	kfree(sa_query->mad);
+ 	kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
+ }
+ 
+@@ -768,60 +772,69 @@ int ib_sa_mcmember_rec_query(struct ib_d
+ {
+ 	struct ib_sa_mcmember_query *query;
+ 	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
+-	struct ib_sa_port   *port   = &sa_dev->port[port_num - sa_dev->start_port];
+-	struct ib_mad_agent *agent  = port->agent;
++	struct ib_sa_port   *port;
++	struct ib_mad_agent *agent;
++	struct ib_sa_mad *mad;
+ 	int ret;
+ 
++	if (!sa_dev)
++		return -ENODEV;
++
++	port  = &sa_dev->port[port_num - sa_dev->start_port];
++	agent = port->agent;
++
+ 	query = kmalloc(sizeof *query, gfp_mask);
+ 	if (!query)
+ 		return -ENOMEM;
+-	query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
+-	if (!query->sa_query.mad) {
+-		kfree(query);
+-		return -ENOMEM;
++
++	query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
++						     0, IB_MGMT_SA_HDR,
++						     IB_MGMT_SA_DATA, gfp_mask);
++	if (!query->sa_query.mad_buf) {
++		ret = -ENOMEM;
++		goto err1;
+ 	}
+ 
+ 	query->callback = callback;
+ 	query->context  = context;
+ 
+-	init_mad(query->sa_query.mad, agent);
++	mad = query->sa_query.mad_buf->mad;
++	init_mad(mad, agent);
+ 
+-	query->sa_query.callback              = callback ? ib_sa_mcmember_rec_callback : NULL;
+-	query->sa_query.release               = ib_sa_mcmember_rec_release;
+-	query->sa_query.port                  = port;
+-	query->sa_query.mad->mad_hdr.method   = method;
+-	query->sa_query.mad->mad_hdr.attr_id  = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
+-	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
++	query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
++	query->sa_query.release  = ib_sa_mcmember_rec_release;
++	query->sa_query.port     = port;
++	mad->mad_hdr.method	 = method;
++	mad->mad_hdr.attr_id	 = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
++	mad->sa_hdr.comp_mask	 = comp_mask;
+ 
+ 	ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
+-		rec, query->sa_query.mad->data);
++		rec, mad->data);
+ 
+ 	*sa_query = &query->sa_query;
+ 
+ 	ret = send_mad(&query->sa_query, timeout_ms);
+-	if (ret < 0) {
+-		*sa_query = NULL;
+-		kfree(query->sa_query.mad);
+-		kfree(query);
+-	}
++	if (ret < 0)
++		goto err2;
+ 
+ 	return ret;
++
++err2:
++	*sa_query = NULL;
++	ib_free_send_mad(query->sa_query.mad_buf);
++
++err1:
++	kfree(query);
++	return ret;
+ }
+ EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
+ 
+ static void send_handler(struct ib_mad_agent *agent,
+ 			 struct ib_mad_send_wc *mad_send_wc)
+ {
+-	struct ib_sa_query *query;
++	struct ib_sa_query *query = mad_send_wc->send_buf->context[0];
+ 	unsigned long flags;
+ 
+-	spin_lock_irqsave(&idr_lock, flags);
+-	query = idr_find(&query_idr, mad_send_wc->wr_id);
+-	spin_unlock_irqrestore(&idr_lock, flags);
+-
+-	if (!query)
+-		return;
+-
+ 	if (query->callback)
+ 		switch (mad_send_wc->status) {
+ 		case IB_WC_SUCCESS:
+@@ -838,30 +851,25 @@ static void send_handler(struct ib_mad_a
+ 			break;
+ 		}
+ 
+-	dma_unmap_single(agent->device->dma_device,
+-			 pci_unmap_addr(query, mapping),
+-			 sizeof (struct ib_sa_mad),
+-			 DMA_TO_DEVICE);
+-	kref_put(&query->sm_ah->ref, free_sm_ah);
+-
+-	query->release(query);
+-
+ 	spin_lock_irqsave(&idr_lock, flags);
+-	idr_remove(&query_idr, mad_send_wc->wr_id);
++	idr_remove(&query_idr, query->id);
+ 	spin_unlock_irqrestore(&idr_lock, flags);
++
++        ib_free_send_mad(mad_send_wc->send_buf);
++	kref_put(&query->sm_ah->ref, free_sm_ah);
++	query->release(query);
+ }
+ 
+ static void recv_handler(struct ib_mad_agent *mad_agent,
+ 			 struct ib_mad_recv_wc *mad_recv_wc)
+ {
+ 	struct ib_sa_query *query;
+-	unsigned long flags;
++	struct ib_mad_send_buf *mad_buf;
+ 
+-	spin_lock_irqsave(&idr_lock, flags);
+-	query = idr_find(&query_idr, mad_recv_wc->wc->wr_id);
+-	spin_unlock_irqrestore(&idr_lock, flags);
++	mad_buf = (void *) (unsigned long) mad_recv_wc->wc->wr_id;
++	query = mad_buf->context[0];
+ 
+-	if (query && query->callback) {
++	if (query->callback) {
+ 		if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
+ 			query->callback(query,
+ 					mad_recv_wc->recv_buf.mad->mad_hdr.status ?
+@@ -975,6 +983,7 @@ static int __init ib_sa_init(void)
+ static void __exit ib_sa_cleanup(void)
+ {
+ 	ib_unregister_client(&sa_client);
++	idr_destroy(&query_idr);
+ }
+ 
+ module_init(ib_sa_init);
+diff --git a/drivers/infiniband/core/smi.h b/drivers/infiniband/core/smi.h
+--- a/drivers/infiniband/core/smi.h
++++ b/drivers/infiniband/core/smi.h
+@@ -39,6 +39,8 @@
+ #ifndef __SMI_H_
+ #define __SMI_H_
+ 
++#include <rdma/ib_smi.h>
++
+ int smi_handle_dr_smp_recv(struct ib_smp *smp,
+ 			   u8 node_type,
+ 			   int port_num,
+diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
+--- a/drivers/infiniband/core/sysfs.c
++++ b/drivers/infiniband/core/sysfs.c
+@@ -65,6 +65,11 @@ struct port_table_attribute {
+ 	int			index;
+ };
+ 
++static inline int ibdev_is_alive(const struct ib_device *dev) 
++{
++	return dev->reg_state == IB_DEV_REGISTERED;
++}
++
+ static ssize_t port_attr_show(struct kobject *kobj,
+ 			      struct attribute *attr, char *buf)
+ {
+@@ -74,6 +79,8 @@ static ssize_t port_attr_show(struct kob
+ 
+ 	if (!port_attr->show)
+ 		return -EIO;
++	if (!ibdev_is_alive(p->ibdev))
++		return -ENODEV;
+ 
+ 	return port_attr->show(p, port_attr, buf);
+ }
+@@ -581,6 +588,9 @@ static ssize_t show_node_type(struct cla
+ {
+ 	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+ 
++	if (!ibdev_is_alive(dev))
++		return -ENODEV;
++
+ 	switch (dev->node_type) {
+ 	case IB_NODE_CA:     return sprintf(buf, "%d: CA\n", dev->node_type);
+ 	case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
+@@ -595,6 +605,9 @@ static ssize_t show_sys_image_guid(struc
+ 	struct ib_device_attr attr;
+ 	ssize_t ret;
+ 
++	if (!ibdev_is_alive(dev))
++		return -ENODEV;
++
+ 	ret = ib_query_device(dev, &attr);
+ 	if (ret)
+ 		return ret;
+@@ -612,6 +625,9 @@ static ssize_t show_node_guid(struct cla
+ 	struct ib_device_attr attr;
+ 	ssize_t ret;
+ 
++	if (!ibdev_is_alive(dev))
++		return -ENODEV;
++
+ 	ret = ib_query_device(dev, &attr);
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
+--- a/drivers/infiniband/core/ucm.c
++++ b/drivers/infiniband/core/ucm.c
+@@ -41,37 +41,81 @@
+ #include <linux/file.h>
+ #include <linux/mount.h>
+ #include <linux/cdev.h>
++#include <linux/idr.h>
+ 
+ #include <asm/uaccess.h>
+ 
+-#include "ucm.h"
++#include <rdma/ib_cm.h>
++#include <rdma/ib_user_cm.h>
+ 
+ MODULE_AUTHOR("Libor Michalek");
+ MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access");
+ MODULE_LICENSE("Dual BSD/GPL");
+ 
+-static int ucm_debug_level;
++struct ib_ucm_device {
++	int			devnum;
++	struct cdev		dev;
++	struct class_device	class_dev;
++	struct ib_device	*ib_dev;
++};
++
++struct ib_ucm_file {
++	struct semaphore mutex;
++	struct file *filp;
++	struct ib_ucm_device *device;
++
++	struct list_head  ctxs;
++	struct list_head  events;
++	wait_queue_head_t poll_wait;
++};
+ 
+-module_param_named(debug_level, ucm_debug_level, int, 0644);
+-MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
++struct ib_ucm_context {
++	int                 id;
++	wait_queue_head_t   wait;
++	atomic_t            ref;
++	int		    events_reported;
++
++	struct ib_ucm_file *file;
++	struct ib_cm_id    *cm_id;
++	__u64		   uid;
++
++	struct list_head    events;    /* list of pending events. */
++	struct list_head    file_list; /* member in file ctx list */
++};
++
++struct ib_ucm_event {
++	struct ib_ucm_context *ctx;
++	struct list_head file_list; /* member in file event list */
++	struct list_head ctx_list;  /* member in ctx event list */
++
++	struct ib_cm_id *cm_id;
++	struct ib_ucm_event_resp resp;
++	void *data;
++	void *info;
++	int data_len;
++	int info_len;
++};
+ 
+ enum {
+ 	IB_UCM_MAJOR = 231,
+-	IB_UCM_MINOR = 255
++	IB_UCM_BASE_MINOR = 224,
++	IB_UCM_MAX_DEVICES = 32
+ };
+ 
+-#define IB_UCM_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_MINOR)
++#define IB_UCM_BASE_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_BASE_MINOR)
+ 
+-#define PFX "UCM: "
++static void ib_ucm_add_one(struct ib_device *device);
++static void ib_ucm_remove_one(struct ib_device *device);
+ 
+-#define ucm_dbg(format, arg...)			\
+-	do {					\
+-		if (ucm_debug_level > 0)	\
+-			printk(KERN_DEBUG PFX format, ## arg); \
+-	} while (0)
++static struct ib_client ucm_client = {
++	.name   = "ucm",
++	.add    = ib_ucm_add_one,
++	.remove = ib_ucm_remove_one
++};
+ 
+-static struct semaphore ctx_id_mutex;
+-static struct idr       ctx_id_table;
++static DECLARE_MUTEX(ctx_id_mutex);
++static DEFINE_IDR(ctx_id_table);
++static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES);
+ 
+ static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)
+ {
+@@ -152,17 +196,13 @@ static struct ib_ucm_context *ib_ucm_ctx
+ 		goto error;
+ 
+ 	list_add_tail(&ctx->file_list, &file->ctxs);
+-	ucm_dbg("Allocated CM ID <%d>\n", ctx->id);
+ 	return ctx;
+ 
+ error:
+ 	kfree(ctx);
+ 	return NULL;
+ }
+-/*
+- * Event portion of the API, handle CM events
+- * and allow event polling.
+- */
++
+ static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath,
+ 				  struct ib_sa_path_rec	 *kpath)
+ {
+@@ -209,6 +249,7 @@ static void ib_ucm_event_req_get(struct 
+ 	ureq->retry_count                = kreq->retry_count;
+ 	ureq->rnr_retry_count            = kreq->rnr_retry_count;
+ 	ureq->srq                        = kreq->srq;
++	ureq->port			 = kreq->port;
+ 
+ 	ib_ucm_event_path_get(&ureq->primary_path, kreq->primary_path);
+ 	ib_ucm_event_path_get(&ureq->alternate_path, kreq->alternate_path);
+@@ -295,6 +336,8 @@ static int ib_ucm_event_process(struct i
+ 	case IB_CM_SIDR_REQ_RECEIVED:
+ 		uvt->resp.u.sidr_req_resp.pkey = 
+ 					evt->param.sidr_req_rcvd.pkey;
++		uvt->resp.u.sidr_req_resp.port = 
++					evt->param.sidr_req_rcvd.port;
+ 		uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE;
+ 		break;
+ 	case IB_CM_SIDR_REP_RECEIVED:
+@@ -387,9 +430,7 @@ static ssize_t ib_ucm_event(struct ib_uc
+ 
+ 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ 		return -EFAULT;
+-	/*
+-	 * wait
+-	 */
++
+ 	down(&file->mutex);
+ 	while (list_empty(&file->events)) {
+ 
+@@ -471,7 +512,6 @@ done:
+ 	return result;
+ }
+ 
+-
+ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,
+ 				const char __user *inbuf,
+ 				int in_len, int out_len)
+@@ -494,29 +534,27 @@ static ssize_t ib_ucm_create_id(struct i
+ 		return -ENOMEM;
+ 
+ 	ctx->uid = cmd.uid;
+-	ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, ctx);
++	ctx->cm_id = ib_create_cm_id(file->device->ib_dev,
++				     ib_ucm_event_handler, ctx);
+ 	if (IS_ERR(ctx->cm_id)) {
+ 		result = PTR_ERR(ctx->cm_id);
+-		goto err;
++		goto err1;
+ 	}
+ 
+ 	resp.id = ctx->id;
+ 	if (copy_to_user((void __user *)(unsigned long)cmd.response,
+ 			 &resp, sizeof(resp))) {
+ 		result = -EFAULT;
+-		goto err;
++		goto err2;
+ 	}
+-
+ 	return 0;
+ 
+-err:
++err2:
++	ib_destroy_cm_id(ctx->cm_id);
++err1:
+ 	down(&ctx_id_mutex);
+ 	idr_remove(&ctx_id_table, ctx->id);
+ 	up(&ctx_id_mutex);
+-
+-	if (!IS_ERR(ctx->cm_id))
+-		ib_destroy_cm_id(ctx->cm_id);
+-
+ 	kfree(ctx);
+ 	return result;
+ }
+@@ -1184,9 +1222,6 @@ static ssize_t ib_ucm_write(struct file 
+ 	if (copy_from_user(&hdr, buf, sizeof(hdr)))
+ 		return -EFAULT;
+ 
+-	ucm_dbg("Write. cmd <%d> in <%d> out <%d> len <%Zu>\n",
+-		hdr.cmd, hdr.in, hdr.out, len);
+-
+ 	if (hdr.cmd < 0 || hdr.cmd >= ARRAY_SIZE(ucm_cmd_table))
+ 		return -EINVAL;
+ 
+@@ -1231,8 +1266,7 @@ static int ib_ucm_open(struct inode *ino
+ 
+ 	filp->private_data = file;
+ 	file->filp = filp;
+-
+-	ucm_dbg("Created struct\n");
++	file->device = container_of(inode->i_cdev, struct ib_ucm_device, dev);
+ 
+ 	return 0;
+ }
+@@ -1263,7 +1297,17 @@ static int ib_ucm_close(struct inode *in
+ 	return 0;
+ }
+ 
+-static struct file_operations ib_ucm_fops = {
++static void ib_ucm_release_class_dev(struct class_device *class_dev)
++{
++	struct ib_ucm_device *dev;
++
++	dev = container_of(class_dev, struct ib_ucm_device, class_dev);
++	cdev_del(&dev->dev);
++	clear_bit(dev->devnum, dev_map);
++	kfree(dev);
++}
++
++static struct file_operations ucm_fops = {
+ 	.owner 	 = THIS_MODULE,
+ 	.open 	 = ib_ucm_open,
+ 	.release = ib_ucm_close,
+@@ -1271,55 +1315,142 @@ static struct file_operations ib_ucm_fop
+ 	.poll    = ib_ucm_poll,
+ };
+ 
++static struct class ucm_class = {
++	.name    = "infiniband_cm",
++	.release = ib_ucm_release_class_dev
++};
+ 
+-static struct class *ib_ucm_class;
+-static struct cdev	  ib_ucm_cdev;
++static ssize_t show_dev(struct class_device *class_dev, char *buf)
++{
++	struct ib_ucm_device *dev;
++	
++	dev = container_of(class_dev, struct ib_ucm_device, class_dev);
++	return print_dev_t(buf, dev->dev.dev);
++}
++static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
+ 
+-static int __init ib_ucm_init(void)
++static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+ {
+-	int result;
++	struct ib_ucm_device *dev;
++	
++	dev = container_of(class_dev, struct ib_ucm_device, class_dev);
++	return sprintf(buf, "%s\n", dev->ib_dev->name);
++}
++static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+ 
+-	result = register_chrdev_region(IB_UCM_DEV, 1, "infiniband_cm");
+-	if (result) {
+-		ucm_dbg("Error <%d> registering dev\n", result);
+-		goto err_chr;
+-	}
++static void ib_ucm_add_one(struct ib_device *device)
++{
++	struct ib_ucm_device *ucm_dev;
++
++	if (!device->alloc_ucontext)
++		return;
+ 
+-	cdev_init(&ib_ucm_cdev, &ib_ucm_fops);
++	ucm_dev = kmalloc(sizeof *ucm_dev, GFP_KERNEL);
++	if (!ucm_dev)
++		return;
++
++	memset(ucm_dev, 0, sizeof *ucm_dev);
++	ucm_dev->ib_dev = device;
+ 
+-	result = cdev_add(&ib_ucm_cdev, IB_UCM_DEV, 1);
+-	if (result) {
+- 		ucm_dbg("Error <%d> adding cdev\n", result);
++	ucm_dev->devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES);
++	if (ucm_dev->devnum >= IB_UCM_MAX_DEVICES)
++		goto err;
++
++	set_bit(ucm_dev->devnum, dev_map);
++
++	cdev_init(&ucm_dev->dev, &ucm_fops);
++	ucm_dev->dev.owner = THIS_MODULE;
++	kobject_set_name(&ucm_dev->dev.kobj, "ucm%d", ucm_dev->devnum);
++	if (cdev_add(&ucm_dev->dev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1))
++		goto err;
++
++	ucm_dev->class_dev.class = &ucm_class;
++	ucm_dev->class_dev.dev = device->dma_device;
++	snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d",
++		 ucm_dev->devnum);
++	if (class_device_register(&ucm_dev->class_dev))
+ 		goto err_cdev;
+-	}
+ 
+-	ib_ucm_class = class_create(THIS_MODULE, "infiniband_cm");
+-	if (IS_ERR(ib_ucm_class)) {
+-		result = PTR_ERR(ib_ucm_class);
+- 		ucm_dbg("Error <%d> creating class\n", result);
++	if (class_device_create_file(&ucm_dev->class_dev,
++				     &class_device_attr_dev))
+ 		goto err_class;
++	if (class_device_create_file(&ucm_dev->class_dev,
++				     &class_device_attr_ibdev))
++		goto err_class;
++
++	ib_set_client_data(device, &ucm_client, ucm_dev);
++	return;
++
++err_class:
++	class_device_unregister(&ucm_dev->class_dev);
++err_cdev:
++	cdev_del(&ucm_dev->dev);
++	clear_bit(ucm_dev->devnum, dev_map);
++err:
++	kfree(ucm_dev);
++	return;
++}
++
++static void ib_ucm_remove_one(struct ib_device *device)
++{
++	struct ib_ucm_device *ucm_dev = ib_get_client_data(device, &ucm_client);
++
++	if (!ucm_dev)
++		return;
++
++	class_device_unregister(&ucm_dev->class_dev);
++}
++
++static ssize_t show_abi_version(struct class *class, char *buf)
++{
++	return sprintf(buf, "%d\n", IB_USER_CM_ABI_VERSION);
++}
++static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
++
++static int __init ib_ucm_init(void)
++{
++	int ret;
++
++	ret = register_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES,
++				     "infiniband_cm");
++	if (ret) {
++		printk(KERN_ERR "ucm: couldn't register device number\n");
++		goto err;
+ 	}
+ 
+-	class_device_create(ib_ucm_class, IB_UCM_DEV, NULL, "ucm");
++	ret = class_register(&ucm_class);
++	if (ret) {
++		printk(KERN_ERR "ucm: couldn't create class infiniband_cm\n");
++		goto err_chrdev;
++	}
+ 
+-	idr_init(&ctx_id_table);
+-	init_MUTEX(&ctx_id_mutex);
++	ret = class_create_file(&ucm_class, &class_attr_abi_version);
++	if (ret) {
++		printk(KERN_ERR "ucm: couldn't create abi_version attribute\n");
++		goto err_class;
++	}
+ 
++	ret = ib_register_client(&ucm_client);
++	if (ret) {
++		printk(KERN_ERR "ucm: couldn't register client\n");
++		goto err_class;
++	}
+ 	return 0;
++
+ err_class:
+-	cdev_del(&ib_ucm_cdev);
+-err_cdev:
+-	unregister_chrdev_region(IB_UCM_DEV, 1);
+-err_chr:
+-	return result;
++	class_unregister(&ucm_class);
++err_chrdev:
++	unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
++err:
++	return ret;
+ }
+ 
+ static void __exit ib_ucm_cleanup(void)
+ {
+-	class_device_destroy(ib_ucm_class, IB_UCM_DEV);
+-	class_destroy(ib_ucm_class);
+-	cdev_del(&ib_ucm_cdev);
+-	unregister_chrdev_region(IB_UCM_DEV, 1);
++	ib_unregister_client(&ucm_client);
++	class_unregister(&ucm_class);
++	unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
++	idr_destroy(&ctx_id_table);
+ }
+ 
+ module_init(ib_ucm_init);
+diff --git a/drivers/infiniband/core/ucm.h b/drivers/infiniband/core/ucm.h
+deleted file mode 100644
+--- a/drivers/infiniband/core/ucm.h
++++ /dev/null
+@@ -1,83 +0,0 @@
+-/*
+- * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+- * 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.
+- *
+- * $Id: ucm.h 2208 2005-04-22 23:24:31Z libor $
+- */
+-
+-#ifndef UCM_H
+-#define UCM_H
+-
+-#include <linux/fs.h>
+-#include <linux/device.h>
+-#include <linux/cdev.h>
+-#include <linux/idr.h>
+-
+-#include <rdma/ib_cm.h>
+-#include <rdma/ib_user_cm.h>
+-
+-struct ib_ucm_file {
+-	struct semaphore mutex;
+-	struct file *filp;
+-
+-	struct list_head  ctxs;   /* list of active connections */
+-	struct list_head  events; /* list of pending events */
+-	wait_queue_head_t poll_wait;
+-};
+-
+-struct ib_ucm_context {
+-	int                 id;
+-	wait_queue_head_t   wait;
+-	atomic_t            ref;
+-	int		    events_reported;
+-
+-	struct ib_ucm_file *file;
+-	struct ib_cm_id    *cm_id;
+-	__u64		   uid;
+-
+-	struct list_head    events;    /* list of pending events. */
+-	struct list_head    file_list; /* member in file ctx list */
+-};
+-
+-struct ib_ucm_event {
+-	struct ib_ucm_context *ctx;
+-	struct list_head file_list; /* member in file event list */
+-	struct list_head ctx_list;  /* member in ctx event list */
+-
+-	struct ib_cm_id *cm_id;
+-	struct ib_ucm_event_resp resp;
+-	void *data;
+-	void *info;
+-	int data_len;
+-	int info_len;
+-};
+-
+-#endif /* UCM_H */
+diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
+--- a/drivers/infiniband/core/user_mad.c
++++ b/drivers/infiniband/core/user_mad.c
+@@ -64,18 +64,39 @@ enum {
+ 	IB_UMAD_MINOR_BASE = 0
+ };
+ 
++/*
++ * Our lifetime rules for these structs are the following: each time a
++ * device special file is opened, we look up the corresponding struct
++ * ib_umad_port by minor in the umad_port[] table while holding the
++ * port_lock.  If this lookup succeeds, we take a reference on the
++ * ib_umad_port's struct ib_umad_device while still holding the
++ * port_lock; if the lookup fails, we fail the open().  We drop these
++ * references in the corresponding close().
++ *
++ * In addition to references coming from open character devices, there
++ * is one more reference to each ib_umad_device representing the
++ * module's reference taken when allocating the ib_umad_device in
++ * ib_umad_add_one().
++ *
++ * When destroying an ib_umad_device, we clear all of its
++ * ib_umad_ports from umad_port[] while holding port_lock before
++ * dropping the module's reference to the ib_umad_device.  This is
++ * always safe because any open() calls will either succeed and obtain
++ * a reference before we clear the umad_port[] entries, or fail after
++ * we clear the umad_port[] entries.
++ */
++
+ struct ib_umad_port {
+-	int                    devnum;
+-	struct cdev            dev;
+-	struct class_device    class_dev;
+-
+-	int                    sm_devnum;
+-	struct cdev            sm_dev;
+-	struct class_device    sm_class_dev;
++	struct cdev           *dev;
++	struct class_device   *class_dev;
++
++	struct cdev           *sm_dev;
++	struct class_device   *sm_class_dev;
+ 	struct semaphore       sm_sem;
+ 
+ 	struct ib_device      *ib_dev;
+ 	struct ib_umad_device *umad_dev;
++	int                    dev_num;
+ 	u8                     port_num;
+ };
+ 
+@@ -96,21 +117,31 @@ struct ib_umad_file {
+ };
+ 
+ struct ib_umad_packet {
+-	struct ib_ah      *ah;
+ 	struct ib_mad_send_buf *msg;
+ 	struct list_head   list;
+ 	int		   length;
+-	DECLARE_PCI_UNMAP_ADDR(mapping)
+ 	struct ib_user_mad mad;
+ };
+ 
++static struct class *umad_class;
++
+ static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);
+-static spinlock_t map_lock;
++
++static DEFINE_SPINLOCK(port_lock);
++static struct ib_umad_port *umad_port[IB_UMAD_MAX_PORTS];
+ static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS * 2);
+ 
+ static void ib_umad_add_one(struct ib_device *device);
+ static void ib_umad_remove_one(struct ib_device *device);
+ 
++static void ib_umad_release_dev(struct kref *ref)
++{
++	struct ib_umad_device *dev =
++		container_of(ref, struct ib_umad_device, ref);
++
++	kfree(dev);
++}
++
+ static int queue_packet(struct ib_umad_file *file,
+ 			struct ib_mad_agent *agent,
+ 			struct ib_umad_packet *packet)
+@@ -139,22 +170,19 @@ static void send_handler(struct ib_mad_a
+ 			 struct ib_mad_send_wc *send_wc)
+ {
+ 	struct ib_umad_file *file = agent->context;
+-	struct ib_umad_packet *timeout, *packet =
+-		(void *) (unsigned long) send_wc->wr_id;
++	struct ib_umad_packet *timeout;
++	struct ib_umad_packet *packet = send_wc->send_buf->context[0];
+ 
+-	ib_destroy_ah(packet->msg->send_wr.wr.ud.ah);
++	ib_destroy_ah(packet->msg->ah);
+ 	ib_free_send_mad(packet->msg);
+ 
+ 	if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
+-		timeout = kmalloc(sizeof *timeout + sizeof (struct ib_mad_hdr),
+-				  GFP_KERNEL);
++		timeout = kzalloc(sizeof *timeout + IB_MGMT_MAD_HDR, GFP_KERNEL);
+ 		if (!timeout)
+ 			goto out;
+ 
+-		memset(timeout, 0, sizeof *timeout + sizeof (struct ib_mad_hdr));
+-
+-		timeout->length = sizeof (struct ib_mad_hdr);
+-		timeout->mad.hdr.id = packet->mad.hdr.id;
++		timeout->length 	= IB_MGMT_MAD_HDR;
++		timeout->mad.hdr.id 	= packet->mad.hdr.id;
+ 		timeout->mad.hdr.status = ETIMEDOUT;
+ 		memcpy(timeout->mad.data, packet->mad.data,
+ 		       sizeof (struct ib_mad_hdr));
+@@ -177,11 +205,10 @@ static void recv_handler(struct ib_mad_a
+ 		goto out;
+ 
+ 	length = mad_recv_wc->mad_len;
+-	packet = kmalloc(sizeof *packet + length, GFP_KERNEL);
++	packet = kzalloc(sizeof *packet + length, GFP_KERNEL);
+ 	if (!packet)
+ 		goto out;
+ 
+-	memset(packet, 0, sizeof *packet + length);
+ 	packet->length = length;
+ 
+ 	ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data);
+@@ -247,7 +274,7 @@ static ssize_t ib_umad_read(struct file 
+ 		else
+ 			ret = -ENOSPC;
+ 	} else if (copy_to_user(buf, &packet->mad,
+-			      packet->length + sizeof (struct ib_user_mad)))
++				packet->length + sizeof (struct ib_user_mad)))
+ 		ret = -EFAULT;
+ 	else
+ 		ret = packet->length + sizeof (struct ib_user_mad);
+@@ -268,26 +295,23 @@ static ssize_t ib_umad_write(struct file
+ 	struct ib_umad_packet *packet;
+ 	struct ib_mad_agent *agent;
+ 	struct ib_ah_attr ah_attr;
+-	struct ib_send_wr *bad_wr;
++	struct ib_ah *ah;
+ 	struct ib_rmpp_mad *rmpp_mad;
+ 	u8 method;
+ 	__be64 *tid;
+-	int ret, length, hdr_len, data_len, rmpp_hdr_size;
++	int ret, length, hdr_len, copy_offset;
+ 	int rmpp_active = 0;
+ 
+ 	if (count < sizeof (struct ib_user_mad))
+ 		return -EINVAL;
+ 
+ 	length = count - sizeof (struct ib_user_mad);
+-	packet = kmalloc(sizeof *packet + sizeof(struct ib_mad_hdr) +
+-			 sizeof(struct ib_rmpp_hdr), GFP_KERNEL);
++	packet = kmalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL);
+ 	if (!packet)
+ 		return -ENOMEM;
+ 
+ 	if (copy_from_user(&packet->mad, buf,
+-			    sizeof (struct ib_user_mad) +
+-			    sizeof(struct ib_mad_hdr) +
+-			    sizeof(struct ib_rmpp_hdr))) {
++			    sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)) {
+ 		ret = -EFAULT;
+ 		goto err;
+ 	}
+@@ -298,8 +322,6 @@ static ssize_t ib_umad_write(struct file
+ 		goto err;
+ 	}
+ 
+-	packet->length = length;
+-
+ 	down_read(&file->agent_mutex);
+ 
+ 	agent = file->agent[packet->mad.hdr.id];
+@@ -321,9 +343,9 @@ static ssize_t ib_umad_write(struct file
+ 		ah_attr.grh.traffic_class  = packet->mad.hdr.traffic_class;
+ 	}
+ 
+-	packet->ah = ib_create_ah(agent->qp->pd, &ah_attr);
+-	if (IS_ERR(packet->ah)) {
+-		ret = PTR_ERR(packet->ah);
++	ah = ib_create_ah(agent->qp->pd, &ah_attr);
++	if (IS_ERR(ah)) {
++		ret = PTR_ERR(ah);
+ 		goto err_up;
+ 	}
+ 
+@@ -337,64 +359,44 @@ static ssize_t ib_umad_write(struct file
+ 
+ 		/* Validate that the management class can support RMPP */
+ 		if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) {
+-			hdr_len = offsetof(struct ib_sa_mad, data);
+-			data_len = length - hdr_len;
++			hdr_len = IB_MGMT_SA_HDR;
+ 		} else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
+ 			    (rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) {
+-				hdr_len = offsetof(struct ib_vendor_mad, data);
+-				data_len = length - hdr_len;
++				hdr_len = IB_MGMT_VENDOR_HDR;
+ 		} else {
+ 			ret = -EINVAL;
+ 			goto err_ah;
+ 		}
+ 		rmpp_active = 1;
++		copy_offset = IB_MGMT_RMPP_HDR;
+ 	} else {
+-		if (length > sizeof(struct ib_mad)) {
+-			ret = -EINVAL;
+-			goto err_ah;
+-		}
+-		hdr_len = offsetof(struct ib_mad, data);
+-		data_len = length - hdr_len;
++		hdr_len = IB_MGMT_MAD_HDR;
++		copy_offset = IB_MGMT_MAD_HDR;
+ 	}
+ 
+ 	packet->msg = ib_create_send_mad(agent,
+ 					 be32_to_cpu(packet->mad.hdr.qpn),
+-					 0, packet->ah, rmpp_active,
+-					 hdr_len, data_len,
++					 0, rmpp_active,
++					 hdr_len, length - hdr_len,
+ 					 GFP_KERNEL);
+ 	if (IS_ERR(packet->msg)) {
+ 		ret = PTR_ERR(packet->msg);
+ 		goto err_ah;
+ 	}
+ 
+-	packet->msg->send_wr.wr.ud.timeout_ms  = packet->mad.hdr.timeout_ms;
+-	packet->msg->send_wr.wr.ud.retries = packet->mad.hdr.retries;
+-
+-	/* Override send WR WRID initialized in ib_create_send_mad */
+-	packet->msg->send_wr.wr_id = (unsigned long) packet;
+-
+-	if (!rmpp_active) {
+-		/* Copy message from user into send buffer */
+-		if (copy_from_user(packet->msg->mad,
+-				   buf + sizeof(struct ib_user_mad), length)) {
+-			ret = -EFAULT;
+-			goto err_msg;
+-		}
+-	} else {
+-		rmpp_hdr_size = sizeof(struct ib_mad_hdr) +
+-				sizeof(struct ib_rmpp_hdr);
+-
+-		/* Only copy MAD headers (RMPP header in place) */
+-		memcpy(packet->msg->mad, packet->mad.data,
+-		       sizeof(struct ib_mad_hdr));
+-
+-		/* Now, copy rest of message from user into send buffer */
+-		if (copy_from_user(((struct ib_rmpp_mad *) packet->msg->mad)->data,
+-				   buf + sizeof (struct ib_user_mad) + rmpp_hdr_size,
+-				   length - rmpp_hdr_size)) {
+-			ret = -EFAULT;
+-			goto err_msg;
+-		}
++	packet->msg->ah 	= ah;
++	packet->msg->timeout_ms = packet->mad.hdr.timeout_ms;
++	packet->msg->retries 	= packet->mad.hdr.retries;
++	packet->msg->context[0] = packet;
++
++	/* Copy MAD headers (RMPP header in place) */
++	memcpy(packet->msg->mad, packet->mad.data, IB_MGMT_MAD_HDR);
++	/* Now, copy rest of message from user into send buffer */
++	if (copy_from_user(packet->msg->mad + copy_offset,
++			   buf + sizeof (struct ib_user_mad) + copy_offset,
++			   length - copy_offset)) {
++		ret = -EFAULT;
++		goto err_msg;
+ 	}
+ 
+ 	/*
+@@ -403,29 +405,29 @@ static ssize_t ib_umad_write(struct file
+ 	 * transaction ID matches the agent being used to send the
+ 	 * MAD.
+ 	 */
+-	method = packet->msg->mad->mad_hdr.method;
++	method = ((struct ib_mad_hdr *) packet->msg->mad)->method;
+ 
+ 	if (!(method & IB_MGMT_METHOD_RESP)       &&
+ 	    method != IB_MGMT_METHOD_TRAP_REPRESS &&
+ 	    method != IB_MGMT_METHOD_SEND) {
+-		tid = &packet->msg->mad->mad_hdr.tid;
++		tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid;
+ 		*tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
+ 				   (be64_to_cpup(tid) & 0xffffffff));
+ 	}
+ 
+-	ret = ib_post_send_mad(agent, &packet->msg->send_wr, &bad_wr);
++	ret = ib_post_send_mad(packet->msg, NULL);
+ 	if (ret)
+ 		goto err_msg;
+ 
+ 	up_read(&file->agent_mutex);
+ 
+-	return sizeof (struct ib_user_mad_hdr) + packet->length;
++	return count;
+ 
+ err_msg:
+ 	ib_free_send_mad(packet->msg);
+ 
+ err_ah:
+-	ib_destroy_ah(packet->ah);
++	ib_destroy_ah(ah);
+ 
+ err_up:
+ 	up_read(&file->agent_mutex);
+@@ -565,15 +567,23 @@ static long ib_umad_ioctl(struct file *f
+ 
+ static int ib_umad_open(struct inode *inode, struct file *filp)
+ {
+-	struct ib_umad_port *port =
+-		container_of(inode->i_cdev, struct ib_umad_port, dev);
++	struct ib_umad_port *port;
+ 	struct ib_umad_file *file;
+ 
+-	file = kmalloc(sizeof *file, GFP_KERNEL);
+-	if (!file)
++	spin_lock(&port_lock);
++	port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE];
++	if (port)
++		kref_get(&port->umad_dev->ref);
++	spin_unlock(&port_lock);
++
++	if (!port)
++		return -ENXIO;
++
++	file = kzalloc(sizeof *file, GFP_KERNEL);
++	if (!file) {
++		kref_put(&port->umad_dev->ref, ib_umad_release_dev);
+ 		return -ENOMEM;
+-
+-	memset(file, 0, sizeof *file);
++	}
+ 
+ 	spin_lock_init(&file->recv_lock);
+ 	init_rwsem(&file->agent_mutex);
+@@ -589,6 +599,7 @@ static int ib_umad_open(struct inode *in
+ static int ib_umad_close(struct inode *inode, struct file *filp)
+ {
+ 	struct ib_umad_file *file = filp->private_data;
++	struct ib_umad_device *dev = file->port->umad_dev;
+ 	struct ib_umad_packet *packet, *tmp;
+ 	int i;
+ 
+@@ -603,6 +614,8 @@ static int ib_umad_close(struct inode *i
+ 
+ 	kfree(file);
+ 
++	kref_put(&dev->ref, ib_umad_release_dev);
++
+ 	return 0;
+ }
+ 
+@@ -619,30 +632,46 @@ static struct file_operations umad_fops 
+ 
+ static int ib_umad_sm_open(struct inode *inode, struct file *filp)
+ {
+-	struct ib_umad_port *port =
+-		container_of(inode->i_cdev, struct ib_umad_port, sm_dev);
++	struct ib_umad_port *port;
+ 	struct ib_port_modify props = {
+ 		.set_port_cap_mask = IB_PORT_SM
+ 	};
+ 	int ret;
+ 
++	spin_lock(&port_lock);
++	port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE - IB_UMAD_MAX_PORTS];
++	if (port)
++		kref_get(&port->umad_dev->ref);
++	spin_unlock(&port_lock);
++
++	if (!port)
++		return -ENXIO;
++
+ 	if (filp->f_flags & O_NONBLOCK) {
+-		if (down_trylock(&port->sm_sem))
+-			return -EAGAIN;
++		if (down_trylock(&port->sm_sem)) {
++			ret = -EAGAIN;
++			goto fail;
++		}
+ 	} else {
+-		if (down_interruptible(&port->sm_sem))
+-			return -ERESTARTSYS;
++		if (down_interruptible(&port->sm_sem)) {
++			ret = -ERESTARTSYS;
++			goto fail;
++		}
+ 	}
+ 
+ 	ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
+ 	if (ret) {
+ 		up(&port->sm_sem);
+-		return ret;
++		goto fail;
+ 	}
+ 
+ 	filp->private_data = port;
+ 
+ 	return 0;
++
++fail:
++	kref_put(&port->umad_dev->ref, ib_umad_release_dev);
++	return ret;
+ }
+ 
+ static int ib_umad_sm_close(struct inode *inode, struct file *filp)
+@@ -656,6 +685,8 @@ static int ib_umad_sm_close(struct inode
+ 	ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
+ 	up(&port->sm_sem);
+ 
++	kref_put(&port->umad_dev->ref, ib_umad_release_dev);
++
+ 	return ret;
+ }
+ 
+@@ -671,21 +702,13 @@ static struct ib_client umad_client = {
+ 	.remove = ib_umad_remove_one
+ };
+ 
+-static ssize_t show_dev(struct class_device *class_dev, char *buf)
+-{
+-	struct ib_umad_port *port = class_get_devdata(class_dev);
+-
+-	if (class_dev == &port->class_dev)
+-		return print_dev_t(buf, port->dev.dev);
+-	else
+-		return print_dev_t(buf, port->sm_dev.dev);
+-}
+-static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
+-
+ static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+ {
+ 	struct ib_umad_port *port = class_get_devdata(class_dev);
+ 
++	if (!port)
++		return -ENODEV;
++
+ 	return sprintf(buf, "%s\n", port->ib_dev->name);
+ }
+ static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+@@ -694,38 +717,13 @@ static ssize_t show_port(struct class_de
+ {
+ 	struct ib_umad_port *port = class_get_devdata(class_dev);
+ 
++	if (!port)
++		return -ENODEV;
++
+ 	return sprintf(buf, "%d\n", port->port_num);
+ }
+ static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
+ 
+-static void ib_umad_release_dev(struct kref *ref)
+-{
+-	struct ib_umad_device *dev =
+-		container_of(ref, struct ib_umad_device, ref);
+-
+-	kfree(dev);
+-}
+-
+-static void ib_umad_release_port(struct class_device *class_dev)
+-{
+-	struct ib_umad_port *port = class_get_devdata(class_dev);
+-
+-	if (class_dev == &port->class_dev) {
+-		cdev_del(&port->dev);
+-		clear_bit(port->devnum, dev_map);
+-	} else {
+-		cdev_del(&port->sm_dev);
+-		clear_bit(port->sm_devnum, dev_map);
+-	}
+-
+-	kref_put(&port->umad_dev->ref, ib_umad_release_dev);
+-}
+-
+-static struct class umad_class = {
+-	.name    = "infiniband_mad",
+-	.release = ib_umad_release_port
+-};
+-
+ static ssize_t show_abi_version(struct class *class, char *buf)
+ {
+ 	return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
+@@ -735,91 +733,102 @@ static CLASS_ATTR(abi_version, S_IRUGO, 
+ static int ib_umad_init_port(struct ib_device *device, int port_num,
+ 			     struct ib_umad_port *port)
+ {
+-	spin_lock(&map_lock);
+-	port->devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
+-	if (port->devnum >= IB_UMAD_MAX_PORTS) {
+-		spin_unlock(&map_lock);
+-		return -1;
+-	}
+-	port->sm_devnum = find_next_zero_bit(dev_map, IB_UMAD_MAX_PORTS * 2, IB_UMAD_MAX_PORTS);
+-	if (port->sm_devnum >= IB_UMAD_MAX_PORTS * 2) {
+-		spin_unlock(&map_lock);
++	spin_lock(&port_lock);
++	port->dev_num = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
++	if (port->dev_num >= IB_UMAD_MAX_PORTS) {
++		spin_unlock(&port_lock);
+ 		return -1;
+ 	}
+-	set_bit(port->devnum, dev_map);
+-	set_bit(port->sm_devnum, dev_map);
+-	spin_unlock(&map_lock);
++	set_bit(port->dev_num, dev_map);
++	spin_unlock(&port_lock);
+ 
+ 	port->ib_dev   = device;
+ 	port->port_num = port_num;
+ 	init_MUTEX(&port->sm_sem);
+ 
+-	cdev_init(&port->dev, &umad_fops);
+-	port->dev.owner = THIS_MODULE;
+-	kobject_set_name(&port->dev.kobj, "umad%d", port->devnum);
+-	if (cdev_add(&port->dev, base_dev + port->devnum, 1))
++	port->dev = cdev_alloc();
++	if (!port->dev)
+ 		return -1;
+-
+-	port->class_dev.class = &umad_class;
+-	port->class_dev.dev   = device->dma_device;
+-
+-	snprintf(port->class_dev.class_id, BUS_ID_SIZE, "umad%d", port->devnum);
+-
+-	if (class_device_register(&port->class_dev))
++	port->dev->owner = THIS_MODULE;
++	port->dev->ops   = &umad_fops;
++	kobject_set_name(&port->dev->kobj, "umad%d", port->dev_num);
++	if (cdev_add(port->dev, base_dev + port->dev_num, 1))
+ 		goto err_cdev;
+ 
+-	class_set_devdata(&port->class_dev, port);
+-	kref_get(&port->umad_dev->ref);
++	port->class_dev = class_device_create(umad_class, NULL, port->dev->dev,
++					      device->dma_device,
++					      "umad%d", port->dev_num);
++	if (IS_ERR(port->class_dev))
++		goto err_cdev;
+ 
+-	if (class_device_create_file(&port->class_dev, &class_device_attr_dev))
+-		goto err_class;
+-	if (class_device_create_file(&port->class_dev, &class_device_attr_ibdev))
++	if (class_device_create_file(port->class_dev, &class_device_attr_ibdev))
+ 		goto err_class;
+-	if (class_device_create_file(&port->class_dev, &class_device_attr_port))
++	if (class_device_create_file(port->class_dev, &class_device_attr_port))
+ 		goto err_class;
+ 
+-	cdev_init(&port->sm_dev, &umad_sm_fops);
+-	port->sm_dev.owner = THIS_MODULE;
+-	kobject_set_name(&port->dev.kobj, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
+-	if (cdev_add(&port->sm_dev, base_dev + port->sm_devnum, 1))
+-		return -1;
+-
+-	port->sm_class_dev.class = &umad_class;
+-	port->sm_class_dev.dev   = device->dma_device;
+-
+-	snprintf(port->sm_class_dev.class_id, BUS_ID_SIZE, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
++	port->sm_dev = cdev_alloc();
++	if (!port->sm_dev)
++		goto err_class;
++	port->sm_dev->owner = THIS_MODULE;
++	port->sm_dev->ops   = &umad_sm_fops;
++	kobject_set_name(&port->dev->kobj, "issm%d", port->dev_num);
++	if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
++		goto err_sm_cdev;
+ 
+-	if (class_device_register(&port->sm_class_dev))
++	port->sm_class_dev = class_device_create(umad_class, NULL, port->sm_dev->dev,
++						 device->dma_device,
++						 "issm%d", port->dev_num);
++	if (IS_ERR(port->sm_class_dev))
+ 		goto err_sm_cdev;
+ 
+-	class_set_devdata(&port->sm_class_dev, port);
+-	kref_get(&port->umad_dev->ref);
++	class_set_devdata(port->class_dev,    port);
++	class_set_devdata(port->sm_class_dev, port);
+ 
+-	if (class_device_create_file(&port->sm_class_dev, &class_device_attr_dev))
+-		goto err_sm_class;
+-	if (class_device_create_file(&port->sm_class_dev, &class_device_attr_ibdev))
++	if (class_device_create_file(port->sm_class_dev, &class_device_attr_ibdev))
+ 		goto err_sm_class;
+-	if (class_device_create_file(&port->sm_class_dev, &class_device_attr_port))
++	if (class_device_create_file(port->sm_class_dev, &class_device_attr_port))
+ 		goto err_sm_class;
+ 
++	spin_lock(&port_lock);
++	umad_port[port->dev_num] = port;
++	spin_unlock(&port_lock);
++
+ 	return 0;
+ 
+ err_sm_class:
+-	class_device_unregister(&port->sm_class_dev);
++	class_device_destroy(umad_class, port->sm_dev->dev);
+ 
+ err_sm_cdev:
+-	cdev_del(&port->sm_dev);
++	cdev_del(port->sm_dev);
+ 
+ err_class:
+-	class_device_unregister(&port->class_dev);
++	class_device_destroy(umad_class, port->dev->dev);
+ 
+ err_cdev:
+-	cdev_del(&port->dev);
+-	clear_bit(port->devnum, dev_map);
++	cdev_del(port->dev);
++	clear_bit(port->dev_num, dev_map);
+ 
+ 	return -1;
+ }
+ 
++static void ib_umad_kill_port(struct ib_umad_port *port)
++{
++	class_set_devdata(port->class_dev,    NULL);
++	class_set_devdata(port->sm_class_dev, NULL);
++
++	class_device_destroy(umad_class, port->dev->dev);
++	class_device_destroy(umad_class, port->sm_dev->dev);
++
++	cdev_del(port->dev);
++	cdev_del(port->sm_dev);
++
++	spin_lock(&port_lock);
++	umad_port[port->dev_num] = NULL;
++	spin_unlock(&port_lock);
++
++	clear_bit(port->dev_num, dev_map);
++}
++
+ static void ib_umad_add_one(struct ib_device *device)
+ {
+ 	struct ib_umad_device *umad_dev;
+@@ -832,15 +841,12 @@ static void ib_umad_add_one(struct ib_de
+ 		e = device->phys_port_cnt;
+ 	}
+ 
+-	umad_dev = kmalloc(sizeof *umad_dev +
++	umad_dev = kzalloc(sizeof *umad_dev +
+ 			   (e - s + 1) * sizeof (struct ib_umad_port),
+ 			   GFP_KERNEL);
+ 	if (!umad_dev)
+ 		return;
+ 
+-	memset(umad_dev, 0, sizeof *umad_dev +
+-	       (e - s + 1) * sizeof (struct ib_umad_port));
+-
+ 	kref_init(&umad_dev->ref);
+ 
+ 	umad_dev->start_port = s;
+@@ -858,10 +864,8 @@ static void ib_umad_add_one(struct ib_de
+ 	return;
+ 
+ err:
+-	while (--i >= s) {
+-		class_device_unregister(&umad_dev->port[i - s].class_dev);
+-		class_device_unregister(&umad_dev->port[i - s].sm_class_dev);
+-	}
++	while (--i >= s)
++		ib_umad_kill_port(&umad_dev->port[i]);
+ 
+ 	kref_put(&umad_dev->ref, ib_umad_release_dev);
+ }
+@@ -874,10 +878,8 @@ static void ib_umad_remove_one(struct ib
+ 	if (!umad_dev)
+ 		return;
+ 
+-	for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i) {
+-		class_device_unregister(&umad_dev->port[i].class_dev);
+-		class_device_unregister(&umad_dev->port[i].sm_class_dev);
+-	}
++	for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i)
++		ib_umad_kill_port(&umad_dev->port[i]);
+ 
+ 	kref_put(&umad_dev->ref, ib_umad_release_dev);
+ }
+@@ -886,8 +888,6 @@ static int __init ib_umad_init(void)
+ {
+ 	int ret;
+ 
+-	spin_lock_init(&map_lock);
+-
+ 	ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2,
+ 				     "infiniband_mad");
+ 	if (ret) {
+@@ -895,13 +895,14 @@ static int __init ib_umad_init(void)
+ 		goto out;
+ 	}
+ 
+-	ret = class_register(&umad_class);
+-	if (ret) {
++	umad_class = class_create(THIS_MODULE, "infiniband_mad");
++	if (IS_ERR(umad_class)) {
++		ret = PTR_ERR(umad_class);
+ 		printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n");
+ 		goto out_chrdev;
+ 	}
+ 
+-	ret = class_create_file(&umad_class, &class_attr_abi_version);
++	ret = class_create_file(umad_class, &class_attr_abi_version);
+ 	if (ret) {
+ 		printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n");
+ 		goto out_class;
+@@ -916,7 +917,7 @@ static int __init ib_umad_init(void)
+ 	return 0;
+ 
+ out_class:
+-	class_unregister(&umad_class);
++	class_destroy(umad_class);
+ 
+ out_chrdev:
+ 	unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
+@@ -928,7 +929,7 @@ out:
+ static void __exit ib_umad_cleanup(void)
+ {
+ 	ib_unregister_client(&umad_client);
+-	class_unregister(&umad_class);
++	class_destroy(umad_class);
+ 	unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
+ }
+ 
+diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
+--- a/drivers/infiniband/core/uverbs.h
++++ b/drivers/infiniband/core/uverbs.h
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
+  * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
++ * Copyright (c) 2005 PathScale, 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
+@@ -38,29 +39,47 @@
+ #ifndef UVERBS_H
+ #define UVERBS_H
+ 
+-/* Include device.h and fs.h until cdev.h is self-sufficient */
+-#include <linux/fs.h>
+-#include <linux/device.h>
+-#include <linux/cdev.h>
+ #include <linux/kref.h>
+ #include <linux/idr.h>
+ 
+ #include <rdma/ib_verbs.h>
+ #include <rdma/ib_user_verbs.h>
+ 
++/*
++ * Our lifetime rules for these structs are the following:
++ *
++ * struct ib_uverbs_device: One reference is held by the module and
++ * released in ib_uverbs_remove_one().  Another reference is taken by
++ * ib_uverbs_open() each time the character special file is opened,
++ * and released in ib_uverbs_release_file() when the file is released.
++ *
++ * struct ib_uverbs_file: One reference is held by the VFS and
++ * released when the file is closed.  Another reference is taken when
++ * an asynchronous event queue file is created and released when the
++ * event file is closed.
++ *
++ * struct ib_uverbs_event_file: One reference is held by the VFS and
++ * released when the file is closed.  For asynchronous event files,
++ * another reference is held by the corresponding main context file
++ * and released when that file is closed.  For completion event files,
++ * a reference is taken when a CQ is created that uses the file, and
++ * released when the CQ is destroyed.
++ */
++
+ struct ib_uverbs_device {
++	struct kref				ref;
+ 	int					devnum;
+-	struct cdev				dev;
+-	struct class_device			class_dev;
++	struct cdev			       *dev;
++	struct class_device		       *class_dev;
+ 	struct ib_device		       *ib_dev;
+-	int					num_comp;
++	int					num_comp_vectors;
+ };
+ 
+ struct ib_uverbs_event_file {
+ 	struct kref				ref;
++	struct file			       *file;
+ 	struct ib_uverbs_file		       *uverbs_file;
+ 	spinlock_t				lock;
+-	int					fd;
+ 	int					is_async;
+ 	wait_queue_head_t			poll_wait;
+ 	struct fasync_struct		       *async_queue;
+@@ -73,8 +92,7 @@ struct ib_uverbs_file {
+ 	struct ib_uverbs_device		       *device;
+ 	struct ib_ucontext		       *ucontext;
+ 	struct ib_event_handler			event_handler;
+-	struct ib_uverbs_event_file	        async_file;
+-	struct ib_uverbs_event_file	        comp_file[1];
++	struct ib_uverbs_event_file	       *async_file;
+ };
+ 
+ struct ib_uverbs_event {
+@@ -110,10 +128,23 @@ extern struct idr ib_uverbs_cq_idr;
+ extern struct idr ib_uverbs_qp_idr;
+ extern struct idr ib_uverbs_srq_idr;
+ 
++struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
++					int is_async, int *fd);
++void ib_uverbs_release_event_file(struct kref *ref);
++struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd);
++
++void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
++			   struct ib_uverbs_event_file *ev_file,
++			   struct ib_ucq_object *uobj);
++void ib_uverbs_release_uevent(struct ib_uverbs_file *file,
++			      struct ib_uevent_object *uobj);
++
+ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
+ void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
+ void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
+ void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr);
++void ib_uverbs_event_handler(struct ib_event_handler *handler,
++			     struct ib_event *event);
+ 
+ int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
+ 		void *addr, size_t size, int write);
+@@ -125,21 +156,26 @@ void ib_umem_release_on_close(struct ib_
+ 				 const char __user *buf, int in_len,	\
+ 				 int out_len)
+ 
+-IB_UVERBS_DECLARE_CMD(query_params);
+ IB_UVERBS_DECLARE_CMD(get_context);
+ IB_UVERBS_DECLARE_CMD(query_device);
+ IB_UVERBS_DECLARE_CMD(query_port);
+-IB_UVERBS_DECLARE_CMD(query_gid);
+-IB_UVERBS_DECLARE_CMD(query_pkey);
+ IB_UVERBS_DECLARE_CMD(alloc_pd);
+ IB_UVERBS_DECLARE_CMD(dealloc_pd);
+ IB_UVERBS_DECLARE_CMD(reg_mr);
+ IB_UVERBS_DECLARE_CMD(dereg_mr);
++IB_UVERBS_DECLARE_CMD(create_comp_channel);
+ IB_UVERBS_DECLARE_CMD(create_cq);
++IB_UVERBS_DECLARE_CMD(poll_cq);
++IB_UVERBS_DECLARE_CMD(req_notify_cq);
+ IB_UVERBS_DECLARE_CMD(destroy_cq);
+ IB_UVERBS_DECLARE_CMD(create_qp);
+ IB_UVERBS_DECLARE_CMD(modify_qp);
+ IB_UVERBS_DECLARE_CMD(destroy_qp);
++IB_UVERBS_DECLARE_CMD(post_send);
++IB_UVERBS_DECLARE_CMD(post_recv);
++IB_UVERBS_DECLARE_CMD(post_srq_recv);
++IB_UVERBS_DECLARE_CMD(create_ah);
++IB_UVERBS_DECLARE_CMD(destroy_ah);
+ IB_UVERBS_DECLARE_CMD(attach_mcast);
+ IB_UVERBS_DECLARE_CMD(detach_mcast);
+ IB_UVERBS_DECLARE_CMD(create_srq);
+diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
+--- a/drivers/infiniband/core/uverbs_cmd.c
++++ b/drivers/infiniband/core/uverbs_cmd.c
+@@ -1,6 +1,7 @@
+ /*
+  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+  * Copyright (c) 2005 Cisco Systems.  All rights reserved.
++ * Copyright (c) 2005 PathScale, 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
+@@ -33,6 +34,9 @@
+  * $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $
+  */
+ 
++#include <linux/file.h>
++#include <linux/fs.h>
++
+ #include <asm/uaccess.h>
+ 
+ #include "uverbs.h"
+@@ -45,29 +49,6 @@
+ 		(udata)->outlen = (olen);				\
+ 	} while (0)
+ 
+-ssize_t ib_uverbs_query_params(struct ib_uverbs_file *file,
+-			       const char __user *buf,
+-			       int in_len, int out_len)
+-{
+-	struct ib_uverbs_query_params      cmd;
+-	struct ib_uverbs_query_params_resp resp;
+-
+-	if (out_len < sizeof resp)
+-		return -ENOSPC;
+-
+-	if (copy_from_user(&cmd, buf, sizeof cmd))
+-		return -EFAULT;
+-
+-	memset(&resp, 0, sizeof resp);
+-
+-	resp.num_cq_events = file->device->num_comp;
+-
+-	if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp))
+-	    return -EFAULT;
+-
+-	return in_len;
+-}
+-
+ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
+ 			      const char __user *buf,
+ 			      int in_len, int out_len)
+@@ -77,7 +58,7 @@ ssize_t ib_uverbs_get_context(struct ib_
+ 	struct ib_udata                   udata;
+ 	struct ib_device                 *ibdev = file->device->ib_dev;
+ 	struct ib_ucontext		 *ucontext;
+-	int i;
++	struct file			 *filp;
+ 	int ret;
+ 
+ 	if (out_len < sizeof resp)
+@@ -110,26 +91,42 @@ ssize_t ib_uverbs_get_context(struct ib_
+ 	INIT_LIST_HEAD(&ucontext->srq_list);
+ 	INIT_LIST_HEAD(&ucontext->ah_list);
+ 
+-	resp.async_fd = file->async_file.fd;
+-	for (i = 0; i < file->device->num_comp; ++i)
+-		if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
+-				 i * sizeof (__u32),
+-				 &file->comp_file[i].fd, sizeof (__u32))) {
+-			ret = -EFAULT;
+-			goto err_free;
+-		}
++	resp.num_comp_vectors = file->device->num_comp_vectors;
++
++	filp = ib_uverbs_alloc_event_file(file, 1, &resp.async_fd);
++	if (IS_ERR(filp)) {
++		ret = PTR_ERR(filp);
++		goto err_free;
++	}
+ 
+ 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ 			 &resp, sizeof resp)) {
+ 		ret = -EFAULT;
+-		goto err_free;
++		goto err_file;
+ 	}
+ 
++	file->async_file = filp->private_data;
++
++	INIT_IB_EVENT_HANDLER(&file->event_handler, file->device->ib_dev,
++			      ib_uverbs_event_handler);
++	ret = ib_register_event_handler(&file->event_handler);
++	if (ret)
++		goto err_file;
++
++	kref_get(&file->async_file->ref);
++	kref_get(&file->ref);
+ 	file->ucontext = ucontext;
++
++	fd_install(resp.async_fd, filp);
++
+ 	up(&file->mutex);
+ 
+ 	return in_len;
+ 
++err_file:
++	put_unused_fd(resp.async_fd);
++	fput(filp);
++
+ err_free:
+ 	ibdev->dealloc_ucontext(ucontext);
+ 
+@@ -255,62 +252,6 @@ ssize_t ib_uverbs_query_port(struct ib_u
+ 	return in_len;
+ }
+ 
+-ssize_t ib_uverbs_query_gid(struct ib_uverbs_file *file,
+-			    const char __user *buf,
+-			    int in_len, int out_len)
+-{
+-	struct ib_uverbs_query_gid      cmd;
+-	struct ib_uverbs_query_gid_resp resp;
+-	int                             ret;
+-
+-	if (out_len < sizeof resp)
+-		return -ENOSPC;
+-
+-	if (copy_from_user(&cmd, buf, sizeof cmd))
+-		return -EFAULT;
+-
+-	memset(&resp, 0, sizeof resp);
+-
+-	ret = ib_query_gid(file->device->ib_dev, cmd.port_num, cmd.index,
+-			   (union ib_gid *) resp.gid);
+-	if (ret)
+-		return ret;
+-
+-	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+-			 &resp, sizeof resp))
+-		return -EFAULT;
+-
+-	return in_len;
+-}
+-
+-ssize_t ib_uverbs_query_pkey(struct ib_uverbs_file *file,
+-			     const char __user *buf,
+-			     int in_len, int out_len)
+-{
+-	struct ib_uverbs_query_pkey      cmd;
+-	struct ib_uverbs_query_pkey_resp resp;
+-	int                              ret;
+-
+-	if (out_len < sizeof resp)
+-		return -ENOSPC;
+-
+-	if (copy_from_user(&cmd, buf, sizeof cmd))
+-		return -EFAULT;
+-
+-	memset(&resp, 0, sizeof resp);
+-
+-	ret = ib_query_pkey(file->device->ib_dev, cmd.port_num, cmd.index,
+-			    &resp.pkey);
+-	if (ret)
+-		return ret;
+-
+-	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+-			 &resp, sizeof resp))
+-		return -EFAULT;
+-
+-	return in_len;
+-}
+-
+ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
+ 			   const char __user *buf,
+ 			   int in_len, int out_len)
+@@ -349,24 +290,20 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uve
+ 	pd->uobject = uobj;
+ 	atomic_set(&pd->usecnt, 0);
+ 
++	down(&ib_uverbs_idr_mutex);
++
+ retry:
+ 	if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) {
+ 		ret = -ENOMEM;
+-		goto err_pd;
++		goto err_up;
+ 	}
+ 
+-	down(&ib_uverbs_idr_mutex);
+ 	ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id);
+-	up(&ib_uverbs_idr_mutex);
+ 
+ 	if (ret == -EAGAIN)
+ 		goto retry;
+ 	if (ret)
+-		goto err_pd;
+-
+-	down(&file->mutex);
+-	list_add_tail(&uobj->list, &file->ucontext->pd_list);
+-	up(&file->mutex);
++		goto err_up;
+ 
+ 	memset(&resp, 0, sizeof resp);
+ 	resp.pd_handle = uobj->id;
+@@ -374,21 +311,22 @@ retry:
+ 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ 			 &resp, sizeof resp)) {
+ 		ret = -EFAULT;
+-		goto err_list;
++		goto err_idr;
+ 	}
+ 
+-	return in_len;
+-
+-err_list:
+- 	down(&file->mutex);
+-	list_del(&uobj->list);
++	down(&file->mutex);
++	list_add_tail(&uobj->list, &file->ucontext->pd_list);
+ 	up(&file->mutex);
+ 
+-	down(&ib_uverbs_idr_mutex);
+-	idr_remove(&ib_uverbs_pd_idr, uobj->id);
+ 	up(&ib_uverbs_idr_mutex);
+ 
+-err_pd:
++	return in_len;
++
++err_idr:
++	idr_remove(&ib_uverbs_pd_idr, uobj->id);
++
++err_up:
++	up(&ib_uverbs_idr_mutex);
+ 	ib_dealloc_pd(pd);
+ 
+ err:
+@@ -459,6 +397,14 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverb
+ 	if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
+ 		return -EINVAL;
+ 
++	/*
++	 * Local write permission is required if remote write or
++	 * remote atomic permission is also requested.
++	 */
++	if (cmd.access_flags & (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE) &&
++	    !(cmd.access_flags & IB_ACCESS_LOCAL_WRITE))
++		return -EINVAL;
++
+ 	obj = kmalloc(sizeof *obj, GFP_KERNEL);
+ 	if (!obj)
+ 		return -ENOMEM;
+@@ -524,24 +470,22 @@ retry:
+ 
+ 	resp.mr_handle = obj->uobject.id;
+ 
+-	down(&file->mutex);
+-	list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
+-	up(&file->mutex);
+-
+ 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ 			 &resp, sizeof resp)) {
+ 		ret = -EFAULT;
+-		goto err_list;
++		goto err_idr;
+ 	}
+ 
++	down(&file->mutex);
++	list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
++	up(&file->mutex);
++
+ 	up(&ib_uverbs_idr_mutex);
+ 
+ 	return in_len;
+ 
+-err_list:
+-	down(&file->mutex);
+-	list_del(&obj->uobject.list);
+-	up(&file->mutex);
++err_idr:
++	idr_remove(&ib_uverbs_mr_idr, obj->uobject.id);
+ 
+ err_unreg:
+ 	ib_dereg_mr(mr);
+@@ -595,6 +539,35 @@ out:
+ 	return ret ? ret : in_len;
+ }
+ 
++ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
++				      const char __user *buf, int in_len,
++				      int out_len)
++{
++	struct ib_uverbs_create_comp_channel	   cmd;
++	struct ib_uverbs_create_comp_channel_resp  resp;
++	struct file				  *filp;
++
++	if (out_len < sizeof resp)
++		return -ENOSPC;
++
++	if (copy_from_user(&cmd, buf, sizeof cmd))
++		return -EFAULT;
++
++	filp = ib_uverbs_alloc_event_file(file, 0, &resp.fd);
++	if (IS_ERR(filp))
++		return PTR_ERR(filp);
++
++	if (copy_to_user((void __user *) (unsigned long) cmd.response,
++			 &resp, sizeof resp)) {
++		put_unused_fd(resp.fd);
++		fput(filp);
++		return -EFAULT;
++	}
++
++	fd_install(resp.fd, filp);
++	return in_len;
++}
++
+ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
+ 			    const char __user *buf, int in_len,
+ 			    int out_len)
+@@ -603,6 +576,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uv
+ 	struct ib_uverbs_create_cq_resp resp;
+ 	struct ib_udata                 udata;
+ 	struct ib_ucq_object           *uobj;
++	struct ib_uverbs_event_file    *ev_file = NULL;
+ 	struct ib_cq                   *cq;
+ 	int                             ret;
+ 
+@@ -616,9 +590,12 @@ ssize_t ib_uverbs_create_cq(struct ib_uv
+ 		   (unsigned long) cmd.response + sizeof resp,
+ 		   in_len - sizeof cmd, out_len - sizeof resp);
+ 
+-	if (cmd.event_handler >= file->device->num_comp)
++	if (cmd.comp_vector >= file->device->num_comp_vectors)
+ 		return -EINVAL;
+ 
++	if (cmd.comp_channel >= 0)
++		ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel);
++
+ 	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
+ 	if (!uobj)
+ 		return -ENOMEM;
+@@ -641,27 +618,23 @@ ssize_t ib_uverbs_create_cq(struct ib_uv
+ 	cq->uobject       = &uobj->uobject;
+ 	cq->comp_handler  = ib_uverbs_comp_handler;
+ 	cq->event_handler = ib_uverbs_cq_event_handler;
+-	cq->cq_context    = file;
++	cq->cq_context    = ev_file;
+ 	atomic_set(&cq->usecnt, 0);
+ 
++	down(&ib_uverbs_idr_mutex);
++
+ retry:
+ 	if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) {
+ 		ret = -ENOMEM;
+-		goto err_cq;
++		goto err_up;
+ 	}
+ 
+-	down(&ib_uverbs_idr_mutex);
+ 	ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->uobject.id);
+-	up(&ib_uverbs_idr_mutex);
+ 
+ 	if (ret == -EAGAIN)
+ 		goto retry;
+ 	if (ret)
+-		goto err_cq;
+-
+-	down(&file->mutex);
+-	list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
+-	up(&file->mutex);
++		goto err_up;
+ 
+ 	memset(&resp, 0, sizeof resp);
+ 	resp.cq_handle = uobj->uobject.id;
+@@ -670,21 +643,22 @@ retry:
+ 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ 			 &resp, sizeof resp)) {
+ 		ret = -EFAULT;
+-		goto err_list;
++		goto err_idr;
+ 	}
+ 
+-	return in_len;
+-
+-err_list:
+- 	down(&file->mutex);
+-	list_del(&uobj->uobject.list);
++	down(&file->mutex);
++	list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
+ 	up(&file->mutex);
+ 
+-	down(&ib_uverbs_idr_mutex);
+-	idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
+ 	up(&ib_uverbs_idr_mutex);
+ 
+-err_cq:
++	return in_len;
++
++err_idr:
++	idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
++
++err_up:
++	up(&ib_uverbs_idr_mutex);
+ 	ib_destroy_cq(cq);
+ 
+ err:
+@@ -692,6 +666,93 @@ err:
+ 	return ret;
+ }
+ 
++ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
++			  const char __user *buf, int in_len,
++			  int out_len)
++{
++	struct ib_uverbs_poll_cq       cmd;
++	struct ib_uverbs_poll_cq_resp *resp;
++	struct ib_cq                  *cq;
++	struct ib_wc                  *wc;
++	int                            ret = 0;
++	int                            i;
++	int                            rsize;
++
++	if (copy_from_user(&cmd, buf, sizeof cmd))
++		return -EFAULT;
++
++	wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL);
++	if (!wc)
++		return -ENOMEM;
++
++	rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc);
++	resp = kmalloc(rsize, GFP_KERNEL);
++	if (!resp) {
++		ret = -ENOMEM;
++		goto out_wc;
++	}
++
++	down(&ib_uverbs_idr_mutex);
++	cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
++	if (!cq || cq->uobject->context != file->ucontext) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	resp->count = ib_poll_cq(cq, cmd.ne, wc);
++
++	for (i = 0; i < resp->count; i++) {
++		resp->wc[i].wr_id 	   = wc[i].wr_id;
++		resp->wc[i].status 	   = wc[i].status;
++		resp->wc[i].opcode 	   = wc[i].opcode;
++		resp->wc[i].vendor_err 	   = wc[i].vendor_err;
++		resp->wc[i].byte_len 	   = wc[i].byte_len;
++		resp->wc[i].imm_data 	   = wc[i].imm_data;
++		resp->wc[i].qp_num 	   = wc[i].qp_num;
++		resp->wc[i].src_qp 	   = wc[i].src_qp;
++		resp->wc[i].wc_flags 	   = wc[i].wc_flags;
++		resp->wc[i].pkey_index 	   = wc[i].pkey_index;
++		resp->wc[i].slid 	   = wc[i].slid;
++		resp->wc[i].sl 		   = wc[i].sl;
++		resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
++		resp->wc[i].port_num 	   = wc[i].port_num;
++	}
++
++	if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
++		ret = -EFAULT;
++
++out:
++	up(&ib_uverbs_idr_mutex);
++	kfree(resp);
++
++out_wc:
++	kfree(wc);
++	return ret ? ret : in_len;
++}
++
++ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
++				const char __user *buf, int in_len,
++				int out_len)
++{
++	struct ib_uverbs_req_notify_cq cmd;
++	struct ib_cq                  *cq;
++	int                            ret = -EINVAL;
++
++	if (copy_from_user(&cmd, buf, sizeof cmd))
++		return -EFAULT;
++
++	down(&ib_uverbs_idr_mutex);
++	cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
++	if (cq && cq->uobject->context == file->ucontext) {
++		ib_req_notify_cq(cq, cmd.solicited_only ?
++					IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
++		ret = in_len;
++	}
++	up(&ib_uverbs_idr_mutex);
++
++	return ret;
++}
++
+ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
+ 			     const char __user *buf, int in_len,
+ 			     int out_len)
+@@ -700,7 +761,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_u
+ 	struct ib_uverbs_destroy_cq_resp resp;
+ 	struct ib_cq               	*cq;
+ 	struct ib_ucq_object        	*uobj;
+-	struct ib_uverbs_event		*evt, *tmp;
++	struct ib_uverbs_event_file	*ev_file;
+ 	u64				 user_handle;
+ 	int                        	 ret = -EINVAL;
+ 
+@@ -716,7 +777,8 @@ ssize_t ib_uverbs_destroy_cq(struct ib_u
+ 		goto out;
+ 
+ 	user_handle = cq->uobject->user_handle;
+-	uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
++	uobj        = container_of(cq->uobject, struct ib_ucq_object, uobject);
++	ev_file     = cq->cq_context;
+ 
+ 	ret = ib_destroy_cq(cq);
+ 	if (ret)
+@@ -728,19 +790,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_u
+ 	list_del(&uobj->uobject.list);
+ 	up(&file->mutex);
+ 
+-	spin_lock_irq(&file->comp_file[0].lock);
+-	list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
+-		list_del(&evt->list);
+-		kfree(evt);
+-	}
+-	spin_unlock_irq(&file->comp_file[0].lock);
+-
+-	spin_lock_irq(&file->async_file.lock);
+-	list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) {
+-		list_del(&evt->list);
+-		kfree(evt);
+-	}
+-	spin_unlock_irq(&file->async_file.lock);
++	ib_uverbs_release_ucq(file, ev_file, uobj);
+ 
+ 	resp.comp_events_reported  = uobj->comp_events_reported;
+ 	resp.async_events_reported = uobj->async_events_reported;
+@@ -859,24 +909,22 @@ retry:
+ 
+ 	resp.qp_handle = uobj->uobject.id;
+ 
+-	down(&file->mutex);
+-	list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list);
+-	up(&file->mutex);
+-
+ 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ 			 &resp, sizeof resp)) {
+ 		ret = -EFAULT;
+-		goto err_list;
++		goto err_idr;
+ 	}
+ 
++	down(&file->mutex);
++	list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list);
++	up(&file->mutex);
++
+ 	up(&ib_uverbs_idr_mutex);
+ 
+ 	return in_len;
+ 
+-err_list:
+-	down(&file->mutex);
+-	list_del(&uobj->uobject.list);
+-	up(&file->mutex);
++err_idr:
++	idr_remove(&ib_uverbs_qp_idr, uobj->uobject.id);
+ 
+ err_destroy:
+ 	ib_destroy_qp(qp);
+@@ -979,7 +1027,6 @@ ssize_t ib_uverbs_destroy_qp(struct ib_u
+ 	struct ib_uverbs_destroy_qp_resp resp;
+ 	struct ib_qp               	*qp;
+ 	struct ib_uevent_object        	*uobj;
+-	struct ib_uverbs_event		*evt, *tmp;
+ 	int                        	 ret = -EINVAL;
+ 
+ 	if (copy_from_user(&cmd, buf, sizeof cmd))
+@@ -1005,12 +1052,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_u
+ 	list_del(&uobj->uobject.list);
+ 	up(&file->mutex);
+ 
+-	spin_lock_irq(&file->async_file.lock);
+-	list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
+-		list_del(&evt->list);
+-		kfree(evt);
+-	}
+-	spin_unlock_irq(&file->async_file.lock);
++	ib_uverbs_release_uevent(file, uobj);
+ 
+ 	resp.events_reported = uobj->events_reported;
+ 
+@@ -1026,6 +1068,468 @@ out:
+ 	return ret ? ret : in_len;
+ }
+ 
++ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
++                            const char __user *buf, int in_len,
++                            int out_len)
++{
++	struct ib_uverbs_post_send      cmd;
++	struct ib_uverbs_post_send_resp resp;
++	struct ib_uverbs_send_wr       *user_wr;
++	struct ib_send_wr              *wr = NULL, *last, *next, *bad_wr;
++	struct ib_qp                   *qp;
++	int                             i, sg_ind;
++	ssize_t                         ret = -EINVAL;
++
++	if (copy_from_user(&cmd, buf, sizeof cmd))
++		return -EFAULT;
++
++	if (in_len < sizeof cmd + cmd.wqe_size * cmd.wr_count +
++	    cmd.sge_count * sizeof (struct ib_uverbs_sge))
++		return -EINVAL;
++
++	if (cmd.wqe_size < sizeof (struct ib_uverbs_send_wr))
++		return -EINVAL;
++
++	user_wr = kmalloc(cmd.wqe_size, GFP_KERNEL);
++	if (!user_wr)
++		return -ENOMEM;
++
++	down(&ib_uverbs_idr_mutex);
++
++	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
++	if (!qp || qp->uobject->context != file->ucontext)
++		goto out;
++
++	sg_ind = 0;
++	last = NULL;
++	for (i = 0; i < cmd.wr_count; ++i) {
++		if (copy_from_user(user_wr,
++				   buf + sizeof cmd + i * cmd.wqe_size,
++				   cmd.wqe_size)) {
++			ret = -EFAULT;
++			goto out;
++		}
++
++		if (user_wr->num_sge + sg_ind > cmd.sge_count) {
++			ret = -EINVAL;
++			goto out;
++		}
++
++		next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
++			       user_wr->num_sge * sizeof (struct ib_sge),
++			       GFP_KERNEL);
++		if (!next) {
++			ret = -ENOMEM;
++			goto out;
++		}
++
++		if (!last)
++			wr = next;
++		else
++			last->next = next;
++		last = next;
++
++		next->next       = NULL;
++		next->wr_id      = user_wr->wr_id;
++		next->num_sge    = user_wr->num_sge;
++		next->opcode     = user_wr->opcode;
++		next->send_flags = user_wr->send_flags;
++		next->imm_data   = user_wr->imm_data;
++
++		if (qp->qp_type == IB_QPT_UD) {
++			next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr,
++						  user_wr->wr.ud.ah);
++			if (!next->wr.ud.ah) {
++				ret = -EINVAL;
++				goto out;
++			}
++			next->wr.ud.remote_qpn  = user_wr->wr.ud.remote_qpn;
++			next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey;
++		} else {
++			switch (next->opcode) {
++			case IB_WR_RDMA_WRITE:
++			case IB_WR_RDMA_WRITE_WITH_IMM:
++			case IB_WR_RDMA_READ:
++				next->wr.rdma.remote_addr =
++					user_wr->wr.rdma.remote_addr;
++				next->wr.rdma.rkey        =
++					user_wr->wr.rdma.rkey;
++				break;
++			case IB_WR_ATOMIC_CMP_AND_SWP:
++			case IB_WR_ATOMIC_FETCH_AND_ADD:
++				next->wr.atomic.remote_addr =
++					user_wr->wr.atomic.remote_addr;
++				next->wr.atomic.compare_add =
++					user_wr->wr.atomic.compare_add;
++				next->wr.atomic.swap = user_wr->wr.atomic.swap;
++				next->wr.atomic.rkey = user_wr->wr.atomic.rkey;
++				break;
++			default:
++				break;
++			}
++		}
++
++		if (next->num_sge) {
++			next->sg_list = (void *) next +
++				ALIGN(sizeof *next, sizeof (struct ib_sge));
++			if (copy_from_user(next->sg_list,
++					   buf + sizeof cmd +
++					   cmd.wr_count * cmd.wqe_size +
++					   sg_ind * sizeof (struct ib_sge),
++					   next->num_sge * sizeof (struct ib_sge))) {
++				ret = -EFAULT;
++				goto out;
++			}
++			sg_ind += next->num_sge;
++		} else
++			next->sg_list = NULL;
++	}
++
++	resp.bad_wr = 0;
++	ret = qp->device->post_send(qp, wr, &bad_wr);
++	if (ret)
++		for (next = wr; next; next = next->next) {
++			++resp.bad_wr;
++			if (next == bad_wr)
++				break;
++		}
++
++	if (copy_to_user((void __user *) (unsigned long) cmd.response,
++			 &resp, sizeof resp))
++		ret = -EFAULT;
++
++out:
++	up(&ib_uverbs_idr_mutex);
++
++	while (wr) {
++		next = wr->next;
++		kfree(wr);
++		wr = next;
++	}
++
++	kfree(user_wr);
++
++	return ret ? ret : in_len;
++}
++
++static struct ib_recv_wr *ib_uverbs_unmarshall_recv(const char __user *buf,
++						    int in_len,
++						    u32 wr_count,
++						    u32 sge_count,
++						    u32 wqe_size)
++{
++	struct ib_uverbs_recv_wr *user_wr;
++	struct ib_recv_wr        *wr = NULL, *last, *next;
++	int                       sg_ind;
++	int                       i;
++	int                       ret;
++
++	if (in_len < wqe_size * wr_count +
++	    sge_count * sizeof (struct ib_uverbs_sge))
++		return ERR_PTR(-EINVAL);
++
++	if (wqe_size < sizeof (struct ib_uverbs_recv_wr))
++		return ERR_PTR(-EINVAL);
++
++	user_wr = kmalloc(wqe_size, GFP_KERNEL);
++	if (!user_wr)
++		return ERR_PTR(-ENOMEM);
++
++	sg_ind = 0;
++	last = NULL;
++	for (i = 0; i < wr_count; ++i) {
++		if (copy_from_user(user_wr, buf + i * wqe_size,
++				   wqe_size)) {
++			ret = -EFAULT;
++			goto err;
++		}
++
++		if (user_wr->num_sge + sg_ind > sge_count) {
++			ret = -EINVAL;
++			goto err;
++		}
++
++		next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
++			       user_wr->num_sge * sizeof (struct ib_sge),
++			       GFP_KERNEL);
++		if (!next) {
++			ret = -ENOMEM;
++			goto err;
++		}
++
++		if (!last)
++			wr = next;
++		else
++			last->next = next;
++		last = next;
++
++		next->next       = NULL;
++		next->wr_id      = user_wr->wr_id;
++		next->num_sge    = user_wr->num_sge;
++
++		if (next->num_sge) {
++			next->sg_list = (void *) next +
++				ALIGN(sizeof *next, sizeof (struct ib_sge));
++			if (copy_from_user(next->sg_list,
++					   buf + wr_count * wqe_size +
++					   sg_ind * sizeof (struct ib_sge),
++					   next->num_sge * sizeof (struct ib_sge))) {
++				ret = -EFAULT;
++				goto err;
++			}
++			sg_ind += next->num_sge;
++		} else
++			next->sg_list = NULL;
++	}
++
++	kfree(user_wr);
++	return wr;
++
++err:
++	kfree(user_wr);
++
++	while (wr) {
++		next = wr->next;
++		kfree(wr);
++		wr = next;
++	}
++
++	return ERR_PTR(ret);
++}
++
++ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
++                            const char __user *buf, int in_len,
++                            int out_len)
++{
++	struct ib_uverbs_post_recv      cmd;
++	struct ib_uverbs_post_recv_resp resp;
++	struct ib_recv_wr              *wr, *next, *bad_wr;
++	struct ib_qp                   *qp;
++	ssize_t                         ret = -EINVAL;
++
++	if (copy_from_user(&cmd, buf, sizeof cmd))
++		return -EFAULT;
++
++	wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
++				       in_len - sizeof cmd, cmd.wr_count,
++				       cmd.sge_count, cmd.wqe_size);
++	if (IS_ERR(wr))
++		return PTR_ERR(wr);
++
++	down(&ib_uverbs_idr_mutex);
++
++	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
++	if (!qp || qp->uobject->context != file->ucontext)
++		goto out;
++
++	resp.bad_wr = 0;
++	ret = qp->device->post_recv(qp, wr, &bad_wr);
++	if (ret)
++		for (next = wr; next; next = next->next) {
++			++resp.bad_wr;
++			if (next == bad_wr)
++				break;
++		}
++
++
++	if (copy_to_user((void __user *) (unsigned long) cmd.response,
++			 &resp, sizeof resp))
++		ret = -EFAULT;
++
++out:
++	up(&ib_uverbs_idr_mutex);
++
++	while (wr) {
++		next = wr->next;
++		kfree(wr);
++		wr = next;
++	}
++
++	return ret ? ret : in_len;
++}
++
++ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
++                            const char __user *buf, int in_len,
++                            int out_len)
++{
++	struct ib_uverbs_post_srq_recv      cmd;
++	struct ib_uverbs_post_srq_recv_resp resp;
++	struct ib_recv_wr                  *wr, *next, *bad_wr;
++	struct ib_srq                      *srq;
++	ssize_t                             ret = -EINVAL;
++
++	if (copy_from_user(&cmd, buf, sizeof cmd))
++		return -EFAULT;
++
++	wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
++				       in_len - sizeof cmd, cmd.wr_count,
++				       cmd.sge_count, cmd.wqe_size);
++	if (IS_ERR(wr))
++		return PTR_ERR(wr);
++
++	down(&ib_uverbs_idr_mutex);
++
++	srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
++	if (!srq || srq->uobject->context != file->ucontext)
++		goto out;
++
++	resp.bad_wr = 0;
++	ret = srq->device->post_srq_recv(srq, wr, &bad_wr);
++	if (ret)
++		for (next = wr; next; next = next->next) {
++			++resp.bad_wr;
++			if (next == bad_wr)
++				break;
++		}
++
++
++	if (copy_to_user((void __user *) (unsigned long) cmd.response,
++			 &resp, sizeof resp))
++		ret = -EFAULT;
++
++out:
++	up(&ib_uverbs_idr_mutex);
++
++	while (wr) {
++		next = wr->next;
++		kfree(wr);
++		wr = next;
++	}
++
++	return ret ? ret : in_len;
++}
++
++ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
++			    const char __user *buf, int in_len,
++			    int out_len)
++{
++	struct ib_uverbs_create_ah	 cmd;
++	struct ib_uverbs_create_ah_resp	 resp;
++	struct ib_uobject		*uobj;
++	struct ib_pd			*pd;
++	struct ib_ah			*ah;
++	struct ib_ah_attr		attr;
++	int ret;
++
++	if (out_len < sizeof resp)
++		return -ENOSPC;
++
++	if (copy_from_user(&cmd, buf, sizeof cmd))
++		return -EFAULT;
++
++	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
++	if (!uobj)
++		return -ENOMEM;
++
++	down(&ib_uverbs_idr_mutex);
++
++	pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
++	if (!pd || pd->uobject->context != file->ucontext) {
++		ret = -EINVAL;
++		goto err_up;
++	}
++
++	uobj->user_handle = cmd.user_handle;
++	uobj->context     = file->ucontext;
++
++	attr.dlid 	       = cmd.attr.dlid;
++	attr.sl 	       = cmd.attr.sl;
++	attr.src_path_bits     = cmd.attr.src_path_bits;
++	attr.static_rate       = cmd.attr.static_rate;
++	attr.port_num 	       = cmd.attr.port_num;
++	attr.grh.flow_label    = cmd.attr.grh.flow_label;
++	attr.grh.sgid_index    = cmd.attr.grh.sgid_index;
++	attr.grh.hop_limit     = cmd.attr.grh.hop_limit;
++	attr.grh.traffic_class = cmd.attr.grh.traffic_class;
++	memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16);
++
++	ah = ib_create_ah(pd, &attr);
++	if (IS_ERR(ah)) {
++		ret = PTR_ERR(ah);
++		goto err_up;
++	}
++
++	ah->uobject = uobj;
++
++retry:
++	if (!idr_pre_get(&ib_uverbs_ah_idr, GFP_KERNEL)) {
++		ret = -ENOMEM;
++		goto err_destroy;
++	}
++
++	ret = idr_get_new(&ib_uverbs_ah_idr, ah, &uobj->id);
++
++	if (ret == -EAGAIN)
++		goto retry;
++	if (ret)
++		goto err_destroy;
++
++	resp.ah_handle = uobj->id;
++
++	if (copy_to_user((void __user *) (unsigned long) cmd.response,
++			 &resp, sizeof resp)) {
++		ret = -EFAULT;
++		goto err_idr;
++	}
++
++	down(&file->mutex);
++	list_add_tail(&uobj->list, &file->ucontext->ah_list);
++	up(&file->mutex);
++
++	up(&ib_uverbs_idr_mutex);
++
++	return in_len;
++
++err_idr:
++	idr_remove(&ib_uverbs_ah_idr, uobj->id);
++
++err_destroy:
++	ib_destroy_ah(ah);
++
++err_up:
++	up(&ib_uverbs_idr_mutex);
++
++	kfree(uobj);
++	return ret;
++}
++
++ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,
++			     const char __user *buf, int in_len, int out_len)
++{
++	struct ib_uverbs_destroy_ah cmd;
++	struct ib_ah		   *ah;
++	struct ib_uobject	   *uobj;
++	int			    ret = -EINVAL;
++
++	if (copy_from_user(&cmd, buf, sizeof cmd))
++		return -EFAULT;
++
++	down(&ib_uverbs_idr_mutex);
++
++	ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle);
++	if (!ah || ah->uobject->context != file->ucontext)
++		goto out;
++
++	uobj = ah->uobject;
++
++	ret = ib_destroy_ah(ah);
++	if (ret)
++		goto out;
++
++	idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle);
++
++	down(&file->mutex);
++	list_del(&uobj->list);
++	up(&file->mutex);
++
++	kfree(uobj);
++
++out:
++	up(&ib_uverbs_idr_mutex);
++
++	return ret ? ret : in_len;
++}
++
+ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
+ 			       const char __user *buf, int in_len,
+ 			       int out_len)
+@@ -1148,24 +1652,22 @@ retry:
+ 
+ 	resp.srq_handle = uobj->uobject.id;
+ 
+-	down(&file->mutex);
+-	list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
+-	up(&file->mutex);
+-
+ 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ 			 &resp, sizeof resp)) {
+ 		ret = -EFAULT;
+-		goto err_list;
++		goto err_idr;
+ 	}
+ 
++	down(&file->mutex);
++	list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
++	up(&file->mutex);
++
+ 	up(&ib_uverbs_idr_mutex);
+ 
+ 	return in_len;
+ 
+-err_list:
+-	down(&file->mutex);
+-	list_del(&uobj->uobject.list);
+-	up(&file->mutex);
++err_idr:
++	idr_remove(&ib_uverbs_srq_idr, uobj->uobject.id);
+ 
+ err_destroy:
+ 	ib_destroy_srq(srq);
+@@ -1217,7 +1719,6 @@ ssize_t ib_uverbs_destroy_srq(struct ib_
+ 	struct ib_uverbs_destroy_srq_resp resp;
+ 	struct ib_srq               	 *srq;
+ 	struct ib_uevent_object        	 *uobj;
+-	struct ib_uverbs_event		 *evt, *tmp;
+ 	int                         	  ret = -EINVAL;
+ 
+ 	if (copy_from_user(&cmd, buf, sizeof cmd))
+@@ -1243,12 +1744,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_
+ 	list_del(&uobj->uobject.list);
+ 	up(&file->mutex);
+ 
+-	spin_lock_irq(&file->async_file.lock);
+-	list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
+-		list_del(&evt->list);
+-		kfree(evt);
+-	}
+-	spin_unlock_irq(&file->async_file.lock);
++	ib_uverbs_release_uevent(file, uobj);
+ 
+ 	resp.events_reported = uobj->events_reported;
+ 
+diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
+--- a/drivers/infiniband/core/uverbs_main.c
++++ b/drivers/infiniband/core/uverbs_main.c
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
+  * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
++ * Copyright (c) 2005 PathScale, 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
+@@ -43,6 +44,7 @@
+ #include <linux/poll.h>
+ #include <linux/file.h>
+ #include <linux/mount.h>
++#include <linux/cdev.h>
+ 
+ #include <asm/uaccess.h>
+ 
+@@ -62,6 +64,8 @@ enum {
+ 
+ #define IB_UVERBS_BASE_DEV	MKDEV(IB_UVERBS_MAJOR, IB_UVERBS_BASE_MINOR)
+ 
++static struct class *uverbs_class;
++
+ DECLARE_MUTEX(ib_uverbs_idr_mutex);
+ DEFINE_IDR(ib_uverbs_pd_idr);
+ DEFINE_IDR(ib_uverbs_mr_idr);
+@@ -72,31 +76,37 @@ DEFINE_IDR(ib_uverbs_qp_idr);
+ DEFINE_IDR(ib_uverbs_srq_idr);
+ 
+ static spinlock_t map_lock;
++static struct ib_uverbs_device *dev_table[IB_UVERBS_MAX_DEVICES];
+ static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
+ 
+ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
+ 				     const char __user *buf, int in_len,
+ 				     int out_len) = {
+-	[IB_USER_VERBS_CMD_QUERY_PARAMS]  = ib_uverbs_query_params,
+-	[IB_USER_VERBS_CMD_GET_CONTEXT]   = ib_uverbs_get_context,
+-	[IB_USER_VERBS_CMD_QUERY_DEVICE]  = ib_uverbs_query_device,
+-	[IB_USER_VERBS_CMD_QUERY_PORT]    = ib_uverbs_query_port,
+-	[IB_USER_VERBS_CMD_QUERY_GID]     = ib_uverbs_query_gid,
+-	[IB_USER_VERBS_CMD_QUERY_PKEY]    = ib_uverbs_query_pkey,
+-	[IB_USER_VERBS_CMD_ALLOC_PD]      = ib_uverbs_alloc_pd,
+-	[IB_USER_VERBS_CMD_DEALLOC_PD]    = ib_uverbs_dealloc_pd,
+-	[IB_USER_VERBS_CMD_REG_MR]        = ib_uverbs_reg_mr,
+-	[IB_USER_VERBS_CMD_DEREG_MR]      = ib_uverbs_dereg_mr,
+-	[IB_USER_VERBS_CMD_CREATE_CQ]     = ib_uverbs_create_cq,
+-	[IB_USER_VERBS_CMD_DESTROY_CQ]    = ib_uverbs_destroy_cq,
+-	[IB_USER_VERBS_CMD_CREATE_QP]     = ib_uverbs_create_qp,
+-	[IB_USER_VERBS_CMD_MODIFY_QP]     = ib_uverbs_modify_qp,
+-	[IB_USER_VERBS_CMD_DESTROY_QP]    = ib_uverbs_destroy_qp,
+-	[IB_USER_VERBS_CMD_ATTACH_MCAST]  = ib_uverbs_attach_mcast,
+-	[IB_USER_VERBS_CMD_DETACH_MCAST]  = ib_uverbs_detach_mcast,
+-	[IB_USER_VERBS_CMD_CREATE_SRQ]    = ib_uverbs_create_srq,
+-	[IB_USER_VERBS_CMD_MODIFY_SRQ]    = ib_uverbs_modify_srq,
+-	[IB_USER_VERBS_CMD_DESTROY_SRQ]   = ib_uverbs_destroy_srq,
++	[IB_USER_VERBS_CMD_GET_CONTEXT]   	= ib_uverbs_get_context,
++	[IB_USER_VERBS_CMD_QUERY_DEVICE]  	= ib_uverbs_query_device,
++	[IB_USER_VERBS_CMD_QUERY_PORT]    	= ib_uverbs_query_port,
++	[IB_USER_VERBS_CMD_ALLOC_PD]      	= ib_uverbs_alloc_pd,
++	[IB_USER_VERBS_CMD_DEALLOC_PD]    	= ib_uverbs_dealloc_pd,
++	[IB_USER_VERBS_CMD_REG_MR]        	= ib_uverbs_reg_mr,
++	[IB_USER_VERBS_CMD_DEREG_MR]      	= ib_uverbs_dereg_mr,
++	[IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel,
++	[IB_USER_VERBS_CMD_CREATE_CQ]     	= ib_uverbs_create_cq,
++	[IB_USER_VERBS_CMD_POLL_CQ]     	= ib_uverbs_poll_cq,
++	[IB_USER_VERBS_CMD_REQ_NOTIFY_CQ]     	= ib_uverbs_req_notify_cq,
++	[IB_USER_VERBS_CMD_DESTROY_CQ]    	= ib_uverbs_destroy_cq,
++	[IB_USER_VERBS_CMD_CREATE_QP]     	= ib_uverbs_create_qp,
++	[IB_USER_VERBS_CMD_MODIFY_QP]     	= ib_uverbs_modify_qp,
++	[IB_USER_VERBS_CMD_DESTROY_QP]    	= ib_uverbs_destroy_qp,
++	[IB_USER_VERBS_CMD_POST_SEND]    	= ib_uverbs_post_send,
++	[IB_USER_VERBS_CMD_POST_RECV]    	= ib_uverbs_post_recv,
++	[IB_USER_VERBS_CMD_POST_SRQ_RECV]    	= ib_uverbs_post_srq_recv,
++	[IB_USER_VERBS_CMD_CREATE_AH]    	= ib_uverbs_create_ah,
++	[IB_USER_VERBS_CMD_DESTROY_AH]    	= ib_uverbs_destroy_ah,
++	[IB_USER_VERBS_CMD_ATTACH_MCAST]  	= ib_uverbs_attach_mcast,
++	[IB_USER_VERBS_CMD_DETACH_MCAST]  	= ib_uverbs_detach_mcast,
++	[IB_USER_VERBS_CMD_CREATE_SRQ]    	= ib_uverbs_create_srq,
++	[IB_USER_VERBS_CMD_MODIFY_SRQ]    	= ib_uverbs_modify_srq,
++	[IB_USER_VERBS_CMD_DESTROY_SRQ]   	= ib_uverbs_destroy_srq,
+ };
+ 
+ static struct vfsmount *uverbs_event_mnt;
+@@ -104,7 +114,54 @@ static struct vfsmount *uverbs_event_mnt
+ static void ib_uverbs_add_one(struct ib_device *device);
+ static void ib_uverbs_remove_one(struct ib_device *device);
+ 
+-static int ib_dealloc_ucontext(struct ib_ucontext *context)
++static void ib_uverbs_release_dev(struct kref *ref)
++{
++	struct ib_uverbs_device *dev =
++		container_of(ref, struct ib_uverbs_device, ref);
++
++	kfree(dev);
++}
++
++void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
++			  struct ib_uverbs_event_file *ev_file,
++			  struct ib_ucq_object *uobj)
++{
++	struct ib_uverbs_event *evt, *tmp;
++
++	if (ev_file) {
++		spin_lock_irq(&ev_file->lock);
++		list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
++			list_del(&evt->list);
++			kfree(evt);
++		}
++		spin_unlock_irq(&ev_file->lock);
++
++		kref_put(&ev_file->ref, ib_uverbs_release_event_file);
++	}
++
++	spin_lock_irq(&file->async_file->lock);
++	list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) {
++		list_del(&evt->list);
++		kfree(evt);
++	}
++	spin_unlock_irq(&file->async_file->lock);
++}
++
++void ib_uverbs_release_uevent(struct ib_uverbs_file *file,
++			      struct ib_uevent_object *uobj)
++{
++	struct ib_uverbs_event *evt, *tmp;
++
++	spin_lock_irq(&file->async_file->lock);
++	list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
++		list_del(&evt->list);
++		kfree(evt);
++	}
++	spin_unlock_irq(&file->async_file->lock);
++}
++
++static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
++				      struct ib_ucontext *context)
+ {
+ 	struct ib_uobject *uobj, *tmp;
+ 
+@@ -113,30 +170,46 @@ static int ib_dealloc_ucontext(struct ib
+ 
+ 	down(&ib_uverbs_idr_mutex);
+ 
+-	/* XXX Free AHs */
++	list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) {
++		struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id);
++		idr_remove(&ib_uverbs_ah_idr, uobj->id);
++		ib_destroy_ah(ah);
++		list_del(&uobj->list);
++		kfree(uobj);
++	}
+ 
+ 	list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) {
+ 		struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id);
++		struct ib_uevent_object *uevent =
++			container_of(uobj, struct ib_uevent_object, uobject);
+ 		idr_remove(&ib_uverbs_qp_idr, uobj->id);
+ 		ib_destroy_qp(qp);
+ 		list_del(&uobj->list);
+-		kfree(container_of(uobj, struct ib_uevent_object, uobject));
++		ib_uverbs_release_uevent(file, uevent);
++		kfree(uevent);
+ 	}
+ 
+ 	list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) {
+ 		struct ib_cq *cq = idr_find(&ib_uverbs_cq_idr, uobj->id);
++		struct ib_uverbs_event_file *ev_file = cq->cq_context;
++		struct ib_ucq_object *ucq =
++			container_of(uobj, struct ib_ucq_object, uobject);
+ 		idr_remove(&ib_uverbs_cq_idr, uobj->id);
+ 		ib_destroy_cq(cq);
+ 		list_del(&uobj->list);
+-		kfree(container_of(uobj, struct ib_ucq_object, uobject));
++		ib_uverbs_release_ucq(file, ev_file, ucq);
++		kfree(ucq);
+ 	}
+ 
+ 	list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
+ 		struct ib_srq *srq = idr_find(&ib_uverbs_srq_idr, uobj->id);
++		struct ib_uevent_object *uevent =
++			container_of(uobj, struct ib_uevent_object, uobject);
+ 		idr_remove(&ib_uverbs_srq_idr, uobj->id);
+ 		ib_destroy_srq(srq);
+ 		list_del(&uobj->list);
+-		kfree(container_of(uobj, struct ib_uevent_object, uobject));
++		ib_uverbs_release_uevent(file, uevent);
++		kfree(uevent);
+ 	}
+ 
+ 	/* XXX Free MWs */
+@@ -175,6 +248,8 @@ static void ib_uverbs_release_file(struc
+ 		container_of(ref, struct ib_uverbs_file, ref);
+ 
+ 	module_put(file->device->ib_dev->owner);
++	kref_put(&file->device->ref, ib_uverbs_release_dev);
++
+ 	kfree(file);
+ }
+ 
+@@ -188,25 +263,19 @@ static ssize_t ib_uverbs_event_read(stru
+ 
+ 	spin_lock_irq(&file->lock);
+ 
+-	while (list_empty(&file->event_list) && file->fd >= 0) {
++	while (list_empty(&file->event_list)) {
+ 		spin_unlock_irq(&file->lock);
+ 
+ 		if (filp->f_flags & O_NONBLOCK)
+ 			return -EAGAIN;
+ 
+ 		if (wait_event_interruptible(file->poll_wait,
+-					     !list_empty(&file->event_list) ||
+-					     file->fd < 0))
++					     !list_empty(&file->event_list)))
+ 			return -ERESTARTSYS;
+ 
+ 		spin_lock_irq(&file->lock);
+ 	}
+ 
+-	if (file->fd < 0) {
+-		spin_unlock_irq(&file->lock);
+-		return -ENODEV;
+-	}
+-
+ 	event = list_entry(file->event_list.next, struct ib_uverbs_event, list);
+ 
+ 	if (file->is_async)
+@@ -248,26 +317,19 @@ static unsigned int ib_uverbs_event_poll
+ 	poll_wait(filp, &file->poll_wait, wait);
+ 
+ 	spin_lock_irq(&file->lock);
+-	if (file->fd < 0)
+-		pollflags = POLLERR;
+-	else if (!list_empty(&file->event_list))
++	if (!list_empty(&file->event_list))
+ 		pollflags = POLLIN | POLLRDNORM;
+ 	spin_unlock_irq(&file->lock);
+ 
+ 	return pollflags;
+ }
+ 
+-static void ib_uverbs_event_release(struct ib_uverbs_event_file *file)
++void ib_uverbs_release_event_file(struct kref *ref)
+ {
+-	struct ib_uverbs_event *entry, *tmp;
++	struct ib_uverbs_event_file *file =
++		container_of(ref, struct ib_uverbs_event_file, ref);
+ 
+-	spin_lock_irq(&file->lock);
+-	if (file->fd != -1) {
+-		file->fd = -1;
+-		list_for_each_entry_safe(entry, tmp, &file->event_list, list)
+-			kfree(entry);
+-	}
+-	spin_unlock_irq(&file->lock);
++	kfree(file);
+ }
+ 
+ static int ib_uverbs_event_fasync(int fd, struct file *filp, int on)
+@@ -280,21 +342,30 @@ static int ib_uverbs_event_fasync(int fd
+ static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
+ {
+ 	struct ib_uverbs_event_file *file = filp->private_data;
++	struct ib_uverbs_event *entry, *tmp;
++
++	spin_lock_irq(&file->lock);
++	file->file = NULL;
++	list_for_each_entry_safe(entry, tmp, &file->event_list, list) {
++		if (entry->counter)
++			list_del(&entry->obj_list);
++		kfree(entry);
++	}
++	spin_unlock_irq(&file->lock);
+ 
+-	ib_uverbs_event_release(file);
+ 	ib_uverbs_event_fasync(-1, filp, 0);
+-	kref_put(&file->uverbs_file->ref, ib_uverbs_release_file);
++
++	if (file->is_async) {
++		ib_unregister_event_handler(&file->uverbs_file->event_handler);
++		kref_put(&file->uverbs_file->ref, ib_uverbs_release_file);
++	}
++	kref_put(&file->ref, ib_uverbs_release_event_file);
+ 
+ 	return 0;
+ }
+ 
+ static struct file_operations uverbs_event_fops = {
+-	/*
+-	 * No .owner field since we artificially create event files,
+-	 * so there is no increment to the module reference count in
+-	 * the open path.  All event files come from a uverbs command
+-	 * file, which already takes a module reference, so this is OK.
+-	 */
++	.owner	 = THIS_MODULE,
+ 	.read 	 = ib_uverbs_event_read,
+ 	.poll    = ib_uverbs_event_poll,
+ 	.release = ib_uverbs_event_close,
+@@ -303,27 +374,37 @@ static struct file_operations uverbs_eve
+ 
+ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
+ {
+-	struct ib_uverbs_file  *file = cq_context;
+-	struct ib_ucq_object   *uobj;
+-	struct ib_uverbs_event *entry;
+-	unsigned long           flags;
++	struct ib_uverbs_event_file    *file = cq_context;
++	struct ib_ucq_object	       *uobj;
++	struct ib_uverbs_event	       *entry;
++	unsigned long			flags;
++
++	if (!file)
++		return;
++
++	spin_lock_irqsave(&file->lock, flags);
++	if (!file->file) {
++		spin_unlock_irqrestore(&file->lock, flags);
++		return;
++	}
+ 
+ 	entry = kmalloc(sizeof *entry, GFP_ATOMIC);
+-	if (!entry)
++	if (!entry) {
++		spin_unlock_irqrestore(&file->lock, flags);
+ 		return;
++	}
+ 
+ 	uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
+ 
+ 	entry->desc.comp.cq_handle = cq->uobject->user_handle;
+ 	entry->counter		   = &uobj->comp_events_reported;
+ 
+-	spin_lock_irqsave(&file->comp_file[0].lock, flags);
+-	list_add_tail(&entry->list, &file->comp_file[0].event_list);
++	list_add_tail(&entry->list, &file->event_list);
+ 	list_add_tail(&entry->obj_list, &uobj->comp_list);
+-	spin_unlock_irqrestore(&file->comp_file[0].lock, flags);
++	spin_unlock_irqrestore(&file->lock, flags);
+ 
+-	wake_up_interruptible(&file->comp_file[0].poll_wait);
+-	kill_fasync(&file->comp_file[0].async_queue, SIGIO, POLL_IN);
++	wake_up_interruptible(&file->poll_wait);
++	kill_fasync(&file->async_queue, SIGIO, POLL_IN);
+ }
+ 
+ static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
+@@ -334,32 +415,40 @@ static void ib_uverbs_async_handler(stru
+ 	struct ib_uverbs_event *entry;
+ 	unsigned long flags;
+ 
++	spin_lock_irqsave(&file->async_file->lock, flags);
++	if (!file->async_file->file) {
++		spin_unlock_irqrestore(&file->async_file->lock, flags);
++		return;
++	}
++
+ 	entry = kmalloc(sizeof *entry, GFP_ATOMIC);
+-	if (!entry)
++	if (!entry) {
++		spin_unlock_irqrestore(&file->async_file->lock, flags);
+ 		return;
++	}
+ 
+ 	entry->desc.async.element    = element;
+ 	entry->desc.async.event_type = event;
+ 	entry->counter               = counter;
+ 
+-	spin_lock_irqsave(&file->async_file.lock, flags);
+-	list_add_tail(&entry->list, &file->async_file.event_list);
++	list_add_tail(&entry->list, &file->async_file->event_list);
+ 	if (obj_list)
+ 		list_add_tail(&entry->obj_list, obj_list);
+-	spin_unlock_irqrestore(&file->async_file.lock, flags);
++	spin_unlock_irqrestore(&file->async_file->lock, flags);
+ 
+-	wake_up_interruptible(&file->async_file.poll_wait);
+-	kill_fasync(&file->async_file.async_queue, SIGIO, POLL_IN);
++	wake_up_interruptible(&file->async_file->poll_wait);
++	kill_fasync(&file->async_file->async_queue, SIGIO, POLL_IN);
+ }
+ 
+ void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
+ {
++	struct ib_uverbs_event_file *ev_file = context_ptr;
+ 	struct ib_ucq_object *uobj;
+ 
+ 	uobj = container_of(event->element.cq->uobject,
+ 			    struct ib_ucq_object, uobject);
+ 
+-	ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,
++	ib_uverbs_async_handler(ev_file->uverbs_file, uobj->uobject.user_handle,
+ 				event->event, &uobj->async_list,
+ 				&uobj->async_events_reported);
+ 				
+@@ -389,8 +478,8 @@ void ib_uverbs_srq_event_handler(struct 
+ 				&uobj->events_reported);
+ }
+ 
+-static void ib_uverbs_event_handler(struct ib_event_handler *handler,
+-				    struct ib_event *event)
++void ib_uverbs_event_handler(struct ib_event_handler *handler,
++			     struct ib_event *event)
+ {
+ 	struct ib_uverbs_file *file =
+ 		container_of(handler, struct ib_uverbs_file, event_handler);
+@@ -399,38 +488,90 @@ static void ib_uverbs_event_handler(stru
+ 				NULL, NULL);
+ }
+ 
+-static int ib_uverbs_event_init(struct ib_uverbs_event_file *file,
+-				struct ib_uverbs_file *uverbs_file)
++struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
++					int is_async, int *fd)
+ {
++	struct ib_uverbs_event_file *ev_file;
+ 	struct file *filp;
++	int ret;
+ 
+-	spin_lock_init(&file->lock);
+-	INIT_LIST_HEAD(&file->event_list);
+-	init_waitqueue_head(&file->poll_wait);
+-	file->uverbs_file = uverbs_file;
+-	file->async_queue = NULL;
+-
+-	file->fd = get_unused_fd();
+-	if (file->fd < 0)
+-		return file->fd;
++	ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL);
++	if (!ev_file)
++		return ERR_PTR(-ENOMEM);
++
++	kref_init(&ev_file->ref);
++	spin_lock_init(&ev_file->lock);
++	INIT_LIST_HEAD(&ev_file->event_list);
++	init_waitqueue_head(&ev_file->poll_wait);
++	ev_file->uverbs_file = uverbs_file;
++	ev_file->async_queue = NULL;
++	ev_file->is_async    = is_async;
++
++	*fd = get_unused_fd();
++	if (*fd < 0) {
++		ret = *fd;
++		goto err;
++	}
+ 
+ 	filp = get_empty_filp();
+ 	if (!filp) {
+-		put_unused_fd(file->fd);
+-		return -ENFILE;
++		ret = -ENFILE;
++		goto err_fd;
+ 	}
+ 
+-	filp->f_op 	   = &uverbs_event_fops;
++	ev_file->file      = filp;
++
++	/*
++	 * fops_get() can't fail here, because we're coming from a
++	 * system call on a uverbs file, which will already have a
++	 * module reference.
++	 */
++	filp->f_op 	   = fops_get(&uverbs_event_fops);
+ 	filp->f_vfsmnt 	   = mntget(uverbs_event_mnt);
+ 	filp->f_dentry 	   = dget(uverbs_event_mnt->mnt_root);
+ 	filp->f_mapping    = filp->f_dentry->d_inode->i_mapping;
+ 	filp->f_flags      = O_RDONLY;
+ 	filp->f_mode       = FMODE_READ;
+-	filp->private_data = file;
++	filp->private_data = ev_file;
+ 
+-	fd_install(file->fd, filp);
++	return filp;
+ 
+-	return 0;
++err_fd:
++	put_unused_fd(*fd);
++
++err:
++	kfree(ev_file);
++	return ERR_PTR(ret);
++}
++
++/*
++ * Look up a completion event file by FD.  If lookup is successful,
++ * takes a ref to the event file struct that it returns; if
++ * unsuccessful, returns NULL.
++ */
++struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd)
++{
++	struct ib_uverbs_event_file *ev_file = NULL;
++	struct file *filp;
++
++	filp = fget(fd);
++	if (!filp)
++		return NULL;
++
++	if (filp->f_op != &uverbs_event_fops)
++		goto out;
++
++	ev_file = filp->private_data;
++	if (ev_file->is_async) {
++		ev_file = NULL;
++		goto out;
++	}
++
++	kref_get(&ev_file->ref);
++
++out:
++	fput(filp);
++	return ev_file;
+ }
+ 
+ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
+@@ -450,11 +591,11 @@ static ssize_t ib_uverbs_write(struct fi
+ 
+ 	if (hdr.command < 0				||
+ 	    hdr.command >= ARRAY_SIZE(uverbs_cmd_table) ||
+-	    !uverbs_cmd_table[hdr.command])
++	    !uverbs_cmd_table[hdr.command]		||
++	    !(file->device->ib_dev->uverbs_cmd_mask & (1ull << hdr.command)))
+ 		return -EINVAL;
+ 
+-	if (!file->ucontext                               &&
+-	    hdr.command != IB_USER_VERBS_CMD_QUERY_PARAMS &&
++	if (!file->ucontext &&
+ 	    hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT)
+ 		return -EINVAL;
+ 
+@@ -474,84 +615,57 @@ static int ib_uverbs_mmap(struct file *f
+ 
+ static int ib_uverbs_open(struct inode *inode, struct file *filp)
+ {
+-	struct ib_uverbs_device *dev =
+-		container_of(inode->i_cdev, struct ib_uverbs_device, dev);
++	struct ib_uverbs_device *dev;
+ 	struct ib_uverbs_file *file;
+-	int i = 0;
+ 	int ret;
+ 
+-	if (!try_module_get(dev->ib_dev->owner))
+-		return -ENODEV;
++	spin_lock(&map_lock);
++	dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR];
++	if (dev)
++		kref_get(&dev->ref);
++	spin_unlock(&map_lock);
++
++	if (!dev)
++		return -ENXIO;
+ 
+-	file = kmalloc(sizeof *file +
+-		       (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file),
+-		       GFP_KERNEL);
++	if (!try_module_get(dev->ib_dev->owner)) {
++		ret = -ENODEV;
++		goto err;
++	}
++
++	file = kmalloc(sizeof *file, GFP_KERNEL);
+ 	if (!file) {
+ 		ret = -ENOMEM;
+-		goto err;
++		goto err_module;
+ 	}
+ 
+-	file->device = dev;
++	file->device	 = dev;
++	file->ucontext	 = NULL;
++	file->async_file = NULL;
+ 	kref_init(&file->ref);
+ 	init_MUTEX(&file->mutex);
+ 
+-	file->ucontext = NULL;
+-
+-	kref_get(&file->ref);
+-	ret = ib_uverbs_event_init(&file->async_file, file);
+-	if (ret)
+-		goto err_kref;
+-
+-	file->async_file.is_async = 1;
+-
+-	for (i = 0; i < dev->num_comp; ++i) {
+-		kref_get(&file->ref);
+-		ret = ib_uverbs_event_init(&file->comp_file[i], file);
+-		if (ret)
+-			goto err_async;
+-		file->comp_file[i].is_async = 0;
+-	}
+-
+-
+ 	filp->private_data = file;
+ 
+-	INIT_IB_EVENT_HANDLER(&file->event_handler, dev->ib_dev,
+-			      ib_uverbs_event_handler);
+-	if (ib_register_event_handler(&file->event_handler))
+-		goto err_async;
+-
+ 	return 0;
+ 
+-err_async:
+-	while (i--)
+-		ib_uverbs_event_release(&file->comp_file[i]);
+-
+-	ib_uverbs_event_release(&file->async_file);
+-
+-err_kref:
+-	/*
+-	 * One extra kref_put() because we took a reference before the
+-	 * event file creation that failed and got us here.
+-	 */
+-	kref_put(&file->ref, ib_uverbs_release_file);
+-	kref_put(&file->ref, ib_uverbs_release_file);
++err_module:
++	module_put(dev->ib_dev->owner);
+ 
+ err:
+-	module_put(dev->ib_dev->owner);
++	kref_put(&dev->ref, ib_uverbs_release_dev);
++
+ 	return ret;
+ }
+ 
+ static int ib_uverbs_close(struct inode *inode, struct file *filp)
+ {
+ 	struct ib_uverbs_file *file = filp->private_data;
+-	int i;
+ 
+-	ib_unregister_event_handler(&file->event_handler);
+-	ib_uverbs_event_release(&file->async_file);
+-	ib_dealloc_ucontext(file->ucontext);
++	ib_uverbs_cleanup_ucontext(file, file->ucontext);
+ 
+-	for (i = 0; i < file->device->num_comp; ++i)
+-		ib_uverbs_event_release(&file->comp_file[i]);
++	if (file->async_file)
++		kref_put(&file->async_file->ref, ib_uverbs_release_event_file);
+ 
+ 	kref_put(&file->ref, ib_uverbs_release_file);
+ 
+@@ -581,27 +695,25 @@ static struct ib_client uverbs_client = 
+ 
+ static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+ {
+-	struct ib_uverbs_device *dev =
+-		container_of(class_dev, struct ib_uverbs_device, class_dev);
++	struct ib_uverbs_device *dev = class_get_devdata(class_dev);
++
++	if (!dev)
++		return -ENODEV;
+ 
+ 	return sprintf(buf, "%s\n", dev->ib_dev->name);
+ }
+ static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+ 
+-static void ib_uverbs_release_class_dev(struct class_device *class_dev)
++static ssize_t show_dev_abi_version(struct class_device *class_dev, char *buf)
+ {
+-	struct ib_uverbs_device *dev =
+-		container_of(class_dev, struct ib_uverbs_device, class_dev);
++	struct ib_uverbs_device *dev = class_get_devdata(class_dev);
+ 
+-	cdev_del(&dev->dev);
+-	clear_bit(dev->devnum, dev_map);
+-	kfree(dev);
+-}
++	if (!dev)
++		return -ENODEV;
+ 
+-static struct class uverbs_class = {
+-	.name    = "infiniband_verbs",
+-	.release = ib_uverbs_release_class_dev
+-};
++	return sprintf(buf, "%d\n", dev->ib_dev->uverbs_abi_ver);
++}
++static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
+ 
+ static ssize_t show_abi_version(struct class *class, char *buf)
+ {
+@@ -622,6 +734,8 @@ static void ib_uverbs_add_one(struct ib_
+ 
+ 	memset(uverbs_dev, 0, sizeof *uverbs_dev);
+ 
++	kref_init(&uverbs_dev->ref);
++
+ 	spin_lock(&map_lock);
+ 	uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
+ 	if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) {
+@@ -631,41 +745,49 @@ static void ib_uverbs_add_one(struct ib_
+ 	set_bit(uverbs_dev->devnum, dev_map);
+ 	spin_unlock(&map_lock);
+ 
+-	uverbs_dev->ib_dev   = device;
+-	uverbs_dev->num_comp = 1;
++	uverbs_dev->ib_dev           = device;
++	uverbs_dev->num_comp_vectors = 1;
+ 
+-	if (device->mmap)
+-		cdev_init(&uverbs_dev->dev, &uverbs_mmap_fops);
+-	else
+-		cdev_init(&uverbs_dev->dev, &uverbs_fops);
+-	uverbs_dev->dev.owner = THIS_MODULE;
+-	kobject_set_name(&uverbs_dev->dev.kobj, "uverbs%d", uverbs_dev->devnum);
+-	if (cdev_add(&uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
++	uverbs_dev->dev = cdev_alloc();
++	if (!uverbs_dev->dev)
+ 		goto err;
++	uverbs_dev->dev->owner = THIS_MODULE;
++	uverbs_dev->dev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
++	kobject_set_name(&uverbs_dev->dev->kobj, "uverbs%d", uverbs_dev->devnum);
++	if (cdev_add(uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
++		goto err_cdev;
+ 
+-	uverbs_dev->class_dev.class = &uverbs_class;
+-	uverbs_dev->class_dev.dev   = device->dma_device;
+-	uverbs_dev->class_dev.devt  = uverbs_dev->dev.dev;
+-	snprintf(uverbs_dev->class_dev.class_id, BUS_ID_SIZE, "uverbs%d", uverbs_dev->devnum);
+-	if (class_device_register(&uverbs_dev->class_dev))
++	uverbs_dev->class_dev = class_device_create(uverbs_class, NULL,
++						    uverbs_dev->dev->dev,
++						    device->dma_device,
++						    "uverbs%d", uverbs_dev->devnum);
++	if (IS_ERR(uverbs_dev->class_dev))
+ 		goto err_cdev;
+ 
+-	if (class_device_create_file(&uverbs_dev->class_dev, &class_device_attr_ibdev))
++	class_set_devdata(uverbs_dev->class_dev, uverbs_dev);
++
++	if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_ibdev))
++		goto err_class;
++	if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_abi_version))
+ 		goto err_class;
+ 
++	spin_lock(&map_lock);
++	dev_table[uverbs_dev->devnum] = uverbs_dev;
++	spin_unlock(&map_lock);
++
+ 	ib_set_client_data(device, &uverbs_client, uverbs_dev);
+ 
+ 	return;
+ 
+ err_class:
+-	class_device_unregister(&uverbs_dev->class_dev);
++	class_device_destroy(uverbs_class, uverbs_dev->dev->dev);
+ 
+ err_cdev:
+-	cdev_del(&uverbs_dev->dev);
++	cdev_del(uverbs_dev->dev);
+ 	clear_bit(uverbs_dev->devnum, dev_map);
+ 
+ err:
+-	kfree(uverbs_dev);
++	kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
+ 	return;
+ }
+ 
+@@ -676,7 +798,16 @@ static void ib_uverbs_remove_one(struct 
+ 	if (!uverbs_dev)
+ 		return;
+ 
+-	class_device_unregister(&uverbs_dev->class_dev);
++	class_set_devdata(uverbs_dev->class_dev, NULL);
++	class_device_destroy(uverbs_class, uverbs_dev->dev->dev);
++	cdev_del(uverbs_dev->dev);
++
++	spin_lock(&map_lock);
++	dev_table[uverbs_dev->devnum] = NULL;
++	spin_unlock(&map_lock);
++
++	clear_bit(uverbs_dev->devnum, dev_map);
++	kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
+ }
+ 
+ static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
+@@ -706,13 +837,14 @@ static int __init ib_uverbs_init(void)
+ 		goto out;
+ 	}
+ 
+-	ret = class_register(&uverbs_class);
+-	if (ret) {
++	uverbs_class = class_create(THIS_MODULE, "infiniband_verbs");
++	if (IS_ERR(uverbs_class)) {
++		ret = PTR_ERR(uverbs_class);
+ 		printk(KERN_ERR "user_verbs: couldn't create class infiniband_verbs\n");
+ 		goto out_chrdev;
+ 	}
+ 
+-	ret = class_create_file(&uverbs_class, &class_attr_abi_version);
++	ret = class_create_file(uverbs_class, &class_attr_abi_version);
+ 	if (ret) {
+ 		printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");
+ 		goto out_class;
+@@ -746,7 +878,7 @@ out_fs:
+ 	unregister_filesystem(&uverbs_event_fs);
+ 
+ out_class:
+-	class_unregister(&uverbs_class);
++	class_destroy(uverbs_class);
+ 
+ out_chrdev:
+ 	unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
+@@ -760,8 +892,15 @@ static void __exit ib_uverbs_cleanup(voi
+ 	ib_unregister_client(&uverbs_client);
+ 	mntput(uverbs_event_mnt);
+ 	unregister_filesystem(&uverbs_event_fs);
+-	class_unregister(&uverbs_class);
++	class_destroy(uverbs_class);
+ 	unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
++	idr_destroy(&ib_uverbs_pd_idr);
++	idr_destroy(&ib_uverbs_mr_idr);
++	idr_destroy(&ib_uverbs_mw_idr);
++	idr_destroy(&ib_uverbs_ah_idr);
++	idr_destroy(&ib_uverbs_cq_idr);
++	idr_destroy(&ib_uverbs_qp_idr);
++	idr_destroy(&ib_uverbs_srq_idr);
+ }
+ 
+ module_init(ib_uverbs_init);
+diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
+--- a/drivers/infiniband/core/verbs.c
++++ b/drivers/infiniband/core/verbs.c
+@@ -523,16 +523,22 @@ EXPORT_SYMBOL(ib_dealloc_fmr);
+ 
+ int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
+ {
+-	return qp->device->attach_mcast ?
+-		qp->device->attach_mcast(qp, gid, lid) :
+-		-ENOSYS;
++	if (!qp->device->attach_mcast)
++		return -ENOSYS;
++	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
++		return -EINVAL;
++
++	return qp->device->attach_mcast(qp, gid, lid);
+ }
+ EXPORT_SYMBOL(ib_attach_mcast);
+ 
+ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
+ {
+-	return qp->device->detach_mcast ?
+-		qp->device->detach_mcast(qp, gid, lid) :
+-		-ENOSYS;
++	if (!qp->device->detach_mcast)
++		return -ENOSYS;
++	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
++		return -EINVAL;
++
++	return qp->device->detach_mcast(qp, gid, lid);
+ }
+ EXPORT_SYMBOL(ib_detach_mcast);
+diff --git a/drivers/infiniband/hw/mthca/Makefile b/drivers/infiniband/hw/mthca/Makefile
+--- a/drivers/infiniband/hw/mthca/Makefile
++++ b/drivers/infiniband/hw/mthca/Makefile
+@@ -7,4 +7,5 @@ obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mth
+ ib_mthca-y :=	mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \
+ 		mthca_allocator.o mthca_eq.o mthca_pd.o mthca_cq.o \
+ 		mthca_mr.o mthca_qp.o mthca_av.o mthca_mcg.o mthca_mad.o \
+-		mthca_provider.o mthca_memfree.o mthca_uar.o mthca_srq.o
++		mthca_provider.o mthca_memfree.o mthca_uar.o mthca_srq.o \
++		mthca_catas.o
+diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
+--- a/drivers/infiniband/hw/mthca/mthca_av.c
++++ b/drivers/infiniband/hw/mthca/mthca_av.c
+@@ -34,6 +34,8 @@
+  */
+ 
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include <rdma/ib_verbs.h>
+ #include <rdma/ib_cache.h>
+diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/infiniband/hw/mthca/mthca_catas.c
+@@ -0,0 +1,153 @@
++/*
++ * Copyright (c) 2005 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$
++ */
++
++#include "mthca_dev.h"
++
++enum {
++	MTHCA_CATAS_POLL_INTERVAL	= 5 * HZ,
++
++	MTHCA_CATAS_TYPE_INTERNAL	= 0,
++	MTHCA_CATAS_TYPE_UPLINK		= 3,
++	MTHCA_CATAS_TYPE_DDR		= 4,
++	MTHCA_CATAS_TYPE_PARITY		= 5,
++};
++
++static DEFINE_SPINLOCK(catas_lock);
++
++static void handle_catas(struct mthca_dev *dev)
++{
++	struct ib_event event;
++	const char *type;
++	int i;
++
++	event.device = &dev->ib_dev;
++	event.event  = IB_EVENT_DEVICE_FATAL;
++	event.element.port_num = 0;
++
++	ib_dispatch_event(&event);
++
++	switch (swab32(readl(dev->catas_err.map)) >> 24) {
++	case MTHCA_CATAS_TYPE_INTERNAL:
++		type = "internal error";
++		break;
++	case MTHCA_CATAS_TYPE_UPLINK:
++		type = "uplink bus error";
++		break;
++	case MTHCA_CATAS_TYPE_DDR:
++		type = "DDR data error";
++		break;
++	case MTHCA_CATAS_TYPE_PARITY:
++		type = "internal parity error";
++		break;
++	default:
++		type = "unknown error";
++		break;
++	}
++
++	mthca_err(dev, "Catastrophic error detected: %s\n", type);
++	for (i = 0; i < dev->catas_err.size; ++i)
++		mthca_err(dev, "  buf[%02x]: %08x\n",
++			  i, swab32(readl(dev->catas_err.map + i)));
++}
++
++static void poll_catas(unsigned long dev_ptr)
++{
++	struct mthca_dev *dev = (struct mthca_dev *) dev_ptr;
++	unsigned long flags;
++	int i;
++
++	for (i = 0; i < dev->catas_err.size; ++i)
++		if (readl(dev->catas_err.map + i)) {
++			handle_catas(dev);
++			return;
++		}
++
++	spin_lock_irqsave(&catas_lock, flags);
++	if (dev->catas_err.stop)
++		mod_timer(&dev->catas_err.timer,
++			  jiffies + MTHCA_CATAS_POLL_INTERVAL);
++	spin_unlock_irqrestore(&catas_lock, flags);
++
++	return;
++}
++
++void mthca_start_catas_poll(struct mthca_dev *dev)
++{
++	unsigned long addr;
++
++	init_timer(&dev->catas_err.timer);
++	dev->catas_err.stop = 0;
++	dev->catas_err.map  = NULL;
++
++	addr = pci_resource_start(dev->pdev, 0) +
++		((pci_resource_len(dev->pdev, 0) - 1) &
++		 dev->catas_err.addr);
++
++	if (!request_mem_region(addr, dev->catas_err.size * 4,
++				DRV_NAME)) {
++		mthca_warn(dev, "couldn't request catastrophic error region "
++			   "at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4);
++		return;
++	}
++
++	dev->catas_err.map = ioremap(addr, dev->catas_err.size * 4);
++	if (!dev->catas_err.map) {
++		mthca_warn(dev, "couldn't map catastrophic error region "
++			   "at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4);
++		release_mem_region(addr, dev->catas_err.size * 4);
++		return;
++	}
++
++	dev->catas_err.timer.data     = (unsigned long) dev;
++	dev->catas_err.timer.function = poll_catas;
++	dev->catas_err.timer.expires  = jiffies + MTHCA_CATAS_POLL_INTERVAL;
++	add_timer(&dev->catas_err.timer);
++}
++
++void mthca_stop_catas_poll(struct mthca_dev *dev)
++{
++	spin_lock_irq(&catas_lock);
++	dev->catas_err.stop = 1;
++	spin_unlock_irq(&catas_lock);
++
++	del_timer_sync(&dev->catas_err.timer);
++
++	if (dev->catas_err.map) {
++		iounmap(dev->catas_err.map);
++		release_mem_region(pci_resource_start(dev->pdev, 0) +
++				   ((pci_resource_len(dev->pdev, 0) - 1) &
++				    dev->catas_err.addr),
++				   dev->catas_err.size * 4);
++	}
++}
+diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
+--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
++++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
+@@ -1,6 +1,7 @@
+ /*
+  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
+  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
++ * Copyright (c) 2005 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
+@@ -524,7 +525,7 @@ void mthca_cmd_use_polling(struct mthca_
+ }
+ 
+ struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev,
+-					  unsigned int gfp_mask)
++					  gfp_t gfp_mask)
+ {
+ 	struct mthca_mailbox *mailbox;
+ 
+@@ -706,9 +707,13 @@ int mthca_QUERY_FW(struct mthca_dev *dev
+ 
+ 	MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
+ 	dev->cmd.max_cmds = 1 << lg;
++	MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET);
++	MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET);
+ 
+ 	mthca_dbg(dev, "FW version %012llx, max commands %d\n",
+ 		  (unsigned long long) dev->fw_ver, dev->cmd.max_cmds);
++	mthca_dbg(dev, "Catastrophic error buffer at 0x%llx, size 0x%x\n",
++		  (unsigned long long) dev->catas_err.addr, dev->catas_err.size);
+ 
+ 	if (mthca_is_memfree(dev)) {
+ 		MTHCA_GET(dev->fw.arbel.fw_pages,       outbox, QUERY_FW_SIZE_OFFSET);
+@@ -933,9 +938,9 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev
+ 		goto out;
+ 
+ 	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET);
+-	dev_lim->max_srq_sz = 1 << field;
++	dev_lim->max_srq_sz = (1 << field) - 1;
+ 	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET);
+-	dev_lim->max_qp_sz = 1 << field;
++	dev_lim->max_qp_sz = (1 << field) - 1;
+ 	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET);
+ 	dev_lim->reserved_qps = 1 << (field & 0xf);
+ 	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET);
+@@ -1045,6 +1050,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev
+ 		  dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars);
+ 	mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n",
+ 		  dev_lim->max_pds, dev_lim->reserved_mgms);
++	mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n",
++		  dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz);
+ 
+ 	mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags);
+ 
+diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
+--- a/drivers/infiniband/hw/mthca/mthca_cmd.h
++++ b/drivers/infiniband/hw/mthca/mthca_cmd.h
+@@ -248,7 +248,7 @@ void mthca_cmd_event(struct mthca_dev *d
+ 		     u8  status, u64 out_param);
+ 
+ struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev,
+-					  unsigned int gfp_mask);
++					  gfp_t gfp_mask);
+ void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox);
+ 
+ int mthca_SYS_EN(struct mthca_dev *dev, u8 *status);
+diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
+--- a/drivers/infiniband/hw/mthca/mthca_dev.h
++++ b/drivers/infiniband/hw/mthca/mthca_dev.h
+@@ -83,6 +83,8 @@ enum {
+ 	/* Arbel FW gives us these, but we need them for Tavor */
+ 	MTHCA_MPT_ENTRY_SIZE  =  0x40,
+ 	MTHCA_MTT_SEG_SIZE    =  0x40,
++
++	MTHCA_QP_PER_MGM      = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
+ };
+ 
+ enum {
+@@ -128,12 +130,16 @@ struct mthca_limits {
+ 	int      num_uars;
+ 	int      max_sg;
+ 	int      num_qps;
++	int      max_wqes;
++	int	 max_qp_init_rdma;
+ 	int      reserved_qps;
+ 	int      num_srqs;
++	int      max_srq_wqes;
+ 	int      reserved_srqs;
+ 	int      num_eecs;
+ 	int      reserved_eecs;
+ 	int      num_cqs;
++	int      max_cqes;
+ 	int      reserved_cqs;
+ 	int      num_eqs;
+ 	int      reserved_eqs;
+@@ -148,6 +154,7 @@ struct mthca_limits {
+ 	int      reserved_mcgs;
+ 	int      num_pds;
+ 	int      reserved_pds;
++	u32      flags;
+ 	u8       port_width_cap;
+ };
+ 
+@@ -251,6 +258,14 @@ struct mthca_mcg_table {
+ 	struct mthca_icm_table *table;
+ };
+ 
++struct mthca_catas_err {
++	u64			addr;
++	u32 __iomem	       *map;
++	unsigned long		stop;
++	u32			size;
++	struct timer_list	timer;
++};
++
+ struct mthca_dev {
+ 	struct ib_device  ib_dev;
+ 	struct pci_dev   *pdev;
+@@ -311,6 +326,8 @@ struct mthca_dev {
+ 	struct mthca_av_table  av_table;
+ 	struct mthca_mcg_table mcg_table;
+ 
++	struct mthca_catas_err catas_err;
++
+ 	struct mthca_uar       driver_uar;
+ 	struct mthca_db_table *db_tab;
+ 	struct mthca_pd        driver_pd;
+@@ -398,6 +415,9 @@ void mthca_cleanup_mcg_table(struct mthc
+ int mthca_register_device(struct mthca_dev *dev);
+ void mthca_unregister_device(struct mthca_dev *dev);
+ 
++void mthca_start_catas_poll(struct mthca_dev *dev);
++void mthca_stop_catas_poll(struct mthca_dev *dev);
++
+ int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar);
+ void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar);
+ 
+@@ -447,6 +467,8 @@ void mthca_cq_clean(struct mthca_dev *de
+ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
+ 		    struct ib_srq_attr *attr, struct mthca_srq *srq);
+ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
++int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
++		     enum ib_srq_attr_mask attr_mask);
+ void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
+ 		     enum ib_event_type event_type);
+ void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);
+diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
+--- a/drivers/infiniband/hw/mthca/mthca_eq.c
++++ b/drivers/infiniband/hw/mthca/mthca_eq.c
+@@ -83,7 +83,8 @@ enum {
+ 	MTHCA_EVENT_TYPE_PATH_MIG   	    = 0x01,
+ 	MTHCA_EVENT_TYPE_COMM_EST   	    = 0x02,
+ 	MTHCA_EVENT_TYPE_SQ_DRAINED 	    = 0x03,
+-	MTHCA_EVENT_TYPE_SRQ_LAST_WQE       = 0x13,
++	MTHCA_EVENT_TYPE_SRQ_QP_LAST_WQE    = 0x13,
++	MTHCA_EVENT_TYPE_SRQ_LIMIT	    = 0x14,
+ 	MTHCA_EVENT_TYPE_CQ_ERROR   	    = 0x04,
+ 	MTHCA_EVENT_TYPE_WQ_CATAS_ERROR     = 0x05,
+ 	MTHCA_EVENT_TYPE_EEC_CATAS_ERROR    = 0x06,
+@@ -110,8 +111,9 @@ enum {
+ 				(1ULL << MTHCA_EVENT_TYPE_LOCAL_CATAS_ERROR)  | \
+ 				(1ULL << MTHCA_EVENT_TYPE_PORT_CHANGE)        | \
+ 				(1ULL << MTHCA_EVENT_TYPE_ECC_DETECT))
+-#define MTHCA_SRQ_EVENT_MASK    (1ULL << MTHCA_EVENT_TYPE_SRQ_CATAS_ERROR)    | \
+-				(1ULL << MTHCA_EVENT_TYPE_SRQ_LAST_WQE)
++#define MTHCA_SRQ_EVENT_MASK   ((1ULL << MTHCA_EVENT_TYPE_SRQ_CATAS_ERROR)    | \
++				(1ULL << MTHCA_EVENT_TYPE_SRQ_QP_LAST_WQE)    | \
++				(1ULL << MTHCA_EVENT_TYPE_SRQ_LIMIT))
+ #define MTHCA_CMD_EVENT_MASK    (1ULL << MTHCA_EVENT_TYPE_CMD)
+ 
+ #define MTHCA_EQ_DB_INC_CI     (1 << 24)
+@@ -142,6 +144,9 @@ struct mthca_eqe {
+ 			__be32 qpn;
+ 		} __attribute__((packed)) qp;
+ 		struct {
++			__be32 srqn;
++		} __attribute__((packed)) srq;
++		struct {
+ 			__be32 cqn;
+ 			u32    reserved1;
+ 			u8     reserved2[3];
+@@ -305,6 +310,16 @@ static int mthca_eq_int(struct mthca_dev
+ 				       IB_EVENT_SQ_DRAINED);
+ 			break;
+ 
++		case MTHCA_EVENT_TYPE_SRQ_QP_LAST_WQE:
++			mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
++				       IB_EVENT_QP_LAST_WQE_REACHED);
++			break;
++
++		case MTHCA_EVENT_TYPE_SRQ_LIMIT:
++			mthca_srq_event(dev, be32_to_cpu(eqe->event.srq.srqn) & 0xffffff,
++					IB_EVENT_SRQ_LIMIT_REACHED);
++			break;
++
+ 		case MTHCA_EVENT_TYPE_WQ_CATAS_ERROR:
+ 			mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
+ 				       IB_EVENT_QP_FATAL);
+diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
+--- a/drivers/infiniband/hw/mthca/mthca_mad.c
++++ b/drivers/infiniband/hw/mthca/mthca_mad.c
+@@ -34,6 +34,9 @@
+  * $Id: mthca_mad.c 1349 2004-12-16 21:09:43Z roland $
+  */
+ 
++#include <linux/string.h>
++#include <linux/slab.h>
++
+ #include <rdma/ib_verbs.h>
+ #include <rdma/ib_mad.h>
+ #include <rdma/ib_smi.h>
+@@ -46,11 +49,6 @@ enum {
+ 	MTHCA_VENDOR_CLASS2 = 0xa
+ };
+ 
+-struct mthca_trap_mad {
+-	struct ib_mad *mad;
+-	DECLARE_PCI_UNMAP_ADDR(mapping)
+-};
+-
+ static void update_sm_ah(struct mthca_dev *dev,
+ 			 u8 port_num, u16 lid, u8 sl)
+ {
+@@ -116,49 +114,14 @@ static void forward_trap(struct mthca_de
+ 			 struct ib_mad *mad)
+ {
+ 	int qpn = mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_SUBN_LID_ROUTED;
+-	struct mthca_trap_mad *tmad;
+-	struct ib_sge      gather_list;
+-	struct ib_send_wr *bad_wr, wr = {
+-		.opcode      = IB_WR_SEND,
+-		.sg_list     = &gather_list,
+-		.num_sge     = 1,
+-		.send_flags  = IB_SEND_SIGNALED,
+-		.wr	     = {
+-			 .ud = {
+-				 .remote_qpn  = qpn,
+-				 .remote_qkey = qpn ? IB_QP1_QKEY : 0,
+-				 .timeout_ms  = 0
+-			 }
+-		 }
+-	};
++	struct ib_mad_send_buf *send_buf;
+ 	struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn];
+ 	int ret;
+ 	unsigned long flags;
+ 
+ 	if (agent) {
+-		tmad = kmalloc(sizeof *tmad, GFP_KERNEL);
+-		if (!tmad)
+-			return;
+-
+-		tmad->mad = kmalloc(sizeof *tmad->mad, GFP_KERNEL);
+-		if (!tmad->mad) {
+-			kfree(tmad);
+-			return;
+-		}
+-
+-		memcpy(tmad->mad, mad, sizeof *mad);
+-
+-		wr.wr.ud.mad_hdr = &tmad->mad->mad_hdr;
+-		wr.wr_id         = (unsigned long) tmad;
+-
+-		gather_list.addr   = dma_map_single(agent->device->dma_device,
+-						    tmad->mad,
+-						    sizeof *tmad->mad,
+-						    DMA_TO_DEVICE);
+-		gather_list.length = sizeof *tmad->mad;
+-		gather_list.lkey   = to_mpd(agent->qp->pd)->ntmr.ibmr.lkey;
+-		pci_unmap_addr_set(tmad, mapping, gather_list.addr);
+-
++		send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR,
++					      IB_MGMT_MAD_DATA, GFP_ATOMIC);
+ 		/*
+ 		 * We rely here on the fact that MLX QPs don't use the
+ 		 * address handle after the send is posted (this is
+@@ -166,21 +129,15 @@ static void forward_trap(struct mthca_de
+ 		 * it's OK for our devices).
+ 		 */
+ 		spin_lock_irqsave(&dev->sm_lock, flags);
+-		wr.wr.ud.ah      = dev->sm_ah[port_num - 1];
+-		if (wr.wr.ud.ah)
+-			ret = ib_post_send_mad(agent, &wr, &bad_wr);
++		memcpy(send_buf->mad, mad, sizeof *mad);
++		if ((send_buf->ah = dev->sm_ah[port_num - 1]))
++			ret = ib_post_send_mad(send_buf, NULL);
+ 		else
+ 			ret = -EINVAL;
+ 		spin_unlock_irqrestore(&dev->sm_lock, flags);
+ 
+-		if (ret) {
+-			dma_unmap_single(agent->device->dma_device,
+-					 pci_unmap_addr(tmad, mapping),
+-					 sizeof *tmad->mad,
+-					 DMA_TO_DEVICE);
+-			kfree(tmad->mad);
+-			kfree(tmad);
+-		}
++		if (ret)
++			ib_free_send_mad(send_buf);
+ 	}
+ }
+ 
+@@ -267,15 +224,7 @@ int mthca_process_mad(struct ib_device *
+ static void send_handler(struct ib_mad_agent *agent,
+ 			 struct ib_mad_send_wc *mad_send_wc)
+ {
+-	struct mthca_trap_mad *tmad =
+-		(void *) (unsigned long) mad_send_wc->wr_id;
+-
+-	dma_unmap_single(agent->device->dma_device,
+-			 pci_unmap_addr(tmad, mapping),
+-			 sizeof *tmad->mad,
+-			 DMA_TO_DEVICE);
+-	kfree(tmad->mad);
+-	kfree(tmad);
++	ib_free_send_mad(mad_send_wc->send_buf);
+ }
+ 
+ int mthca_create_agents(struct mthca_dev *dev)
+diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
+--- a/drivers/infiniband/hw/mthca/mthca_main.c
++++ b/drivers/infiniband/hw/mthca/mthca_main.c
+@@ -162,9 +162,18 @@ static int __devinit mthca_dev_lim(struc
+ 	mdev->limits.pkey_table_len 	= dev_lim->max_pkeys;
+ 	mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay;
+ 	mdev->limits.max_sg             = dev_lim->max_sg;
++	mdev->limits.max_wqes           = dev_lim->max_qp_sz;
++	mdev->limits.max_qp_init_rdma   = dev_lim->max_requester_per_qp;
+ 	mdev->limits.reserved_qps       = dev_lim->reserved_qps;
++	mdev->limits.max_srq_wqes       = dev_lim->max_srq_sz;
+ 	mdev->limits.reserved_srqs      = dev_lim->reserved_srqs;
+ 	mdev->limits.reserved_eecs      = dev_lim->reserved_eecs;
++	/*
++	 * Subtract 1 from the limit because we need to allocate a
++	 * spare CQE so the HCA HW can tell the difference between an
++	 * empty CQ and a full CQ.
++	 */
++	mdev->limits.max_cqes           = dev_lim->max_cq_sz - 1;
+ 	mdev->limits.reserved_cqs       = dev_lim->reserved_cqs;
+ 	mdev->limits.reserved_eqs       = dev_lim->reserved_eqs;
+ 	mdev->limits.reserved_mtts      = dev_lim->reserved_mtts;
+@@ -172,6 +181,7 @@ static int __devinit mthca_dev_lim(struc
+ 	mdev->limits.reserved_uars      = dev_lim->reserved_uars;
+ 	mdev->limits.reserved_pds       = dev_lim->reserved_pds;
+ 	mdev->limits.port_width_cap     = dev_lim->max_port_width;
++	mdev->limits.flags              = dev_lim->flags;
+ 
+ 	/* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
+ 	   May be doable since hardware supports it for SRQ.
+@@ -1186,6 +1196,7 @@ MODULE_DEVICE_TABLE(pci, mthca_pci_table
+ 
+ static struct pci_driver mthca_driver = {
+ 	.name		= DRV_NAME,
++	.owner		= THIS_MODULE,
+ 	.id_table	= mthca_pci_table,
+ 	.probe		= mthca_init_one,
+ 	.remove		= __devexit_p(mthca_remove_one)
+diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
+--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
++++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
+@@ -33,14 +33,12 @@
+  */
+ 
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "mthca_dev.h"
+ #include "mthca_cmd.h"
+ 
+-enum {
+-	MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
+-};
+-
+ struct mthca_mgm {
+ 	__be32 next_gid_index;
+ 	u32    reserved[3];
+@@ -189,7 +187,12 @@ int mthca_multicast_attach(struct ib_qp 
+ 	}
+ 
+ 	for (i = 0; i < MTHCA_QP_PER_MGM; ++i)
+-		if (!(mgm->qp[i] & cpu_to_be32(1 << 31))) {
++		if (mgm->qp[i] == cpu_to_be32(ibqp->qp_num | (1 << 31))) {
++			mthca_dbg(dev, "QP %06x already a member of MGM\n", 
++				  ibqp->qp_num);
++			err = 0;
++			goto out;
++		} else if (!(mgm->qp[i] & cpu_to_be32(1 << 31))) {
+ 			mgm->qp[i] = cpu_to_be32(ibqp->qp_num | (1 << 31));
+ 			break;
+ 		}
+diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
+--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
++++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
+@@ -82,7 +82,7 @@ void mthca_free_icm(struct mthca_dev *de
+ }
+ 
+ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
+-				  unsigned int gfp_mask)
++				  gfp_t gfp_mask)
+ {
+ 	struct mthca_icm *icm;
+ 	struct mthca_icm_chunk *chunk = NULL;
+@@ -487,7 +487,8 @@ void mthca_cleanup_user_db_tab(struct mt
+ 	}
+ }
+ 
+-int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
++int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
++		   u32 qn, __be32 **db)
+ {
+ 	int group;
+ 	int start, end, dir;
+diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
+--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
++++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
+@@ -77,7 +77,7 @@ struct mthca_icm_iter {
+ struct mthca_dev;
+ 
+ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
+-				  unsigned int gfp_mask);
++				  gfp_t gfp_mask);
+ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm);
+ 
+ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
+@@ -173,7 +173,8 @@ void mthca_cleanup_user_db_tab(struct mt
+ 
+ int mthca_init_db_tab(struct mthca_dev *dev);
+ void mthca_cleanup_db_tab(struct mthca_dev *dev);
+-int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db);
++int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
++		   u32 qn, __be32 **db);
+ void mthca_free_db(struct mthca_dev *dev, int type, int db_index);
+ 
+ #endif /* MTHCA_MEMFREE_H */
+diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c
+--- a/drivers/infiniband/hw/mthca/mthca_profile.c
++++ b/drivers/infiniband/hw/mthca/mthca_profile.c
+@@ -35,6 +35,8 @@
+ 
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "mthca_profile.h"
+ 
+diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
+--- a/drivers/infiniband/hw/mthca/mthca_provider.c
++++ b/drivers/infiniband/hw/mthca/mthca_provider.c
+@@ -37,6 +37,7 @@
+  */
+ 
+ #include <rdma/ib_smi.h>
++#include <rdma/ib_user_verbs.h>
+ #include <linux/mm.h>
+ 
+ #include "mthca_dev.h"
+@@ -90,15 +91,26 @@ static int mthca_query_device(struct ib_
+ 
+ 	props->max_mr_size         = ~0ull;
+ 	props->max_qp              = mdev->limits.num_qps - mdev->limits.reserved_qps;
+-	props->max_qp_wr           = 0xffff;
++	props->max_qp_wr           = mdev->limits.max_wqes;
+ 	props->max_sge             = mdev->limits.max_sg;
+ 	props->max_cq              = mdev->limits.num_cqs - mdev->limits.reserved_cqs;
+-	props->max_cqe             = 0xffff;
++	props->max_cqe             = mdev->limits.max_cqes;
+ 	props->max_mr              = mdev->limits.num_mpts - mdev->limits.reserved_mrws;
+ 	props->max_pd              = mdev->limits.num_pds - mdev->limits.reserved_pds;
+ 	props->max_qp_rd_atom      = 1 << mdev->qp_table.rdb_shift;
+-	props->max_qp_init_rd_atom = 1 << mdev->qp_table.rdb_shift;
++	props->max_qp_init_rd_atom = mdev->limits.max_qp_init_rdma;
++	props->max_res_rd_atom     = props->max_qp_rd_atom * props->max_qp;
++	props->max_srq             = mdev->limits.num_srqs - mdev->limits.reserved_srqs;
++	props->max_srq_wr          = mdev->limits.max_srq_wqes;
++	props->max_srq_sge         = mdev->limits.max_sg;
+ 	props->local_ca_ack_delay  = mdev->limits.local_ca_ack_delay;
++	props->atomic_cap          = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ? 
++					IB_ATOMIC_HCA : IB_ATOMIC_NONE;
++	props->max_pkeys           = mdev->limits.pkey_table_len;
++	props->max_mcast_grp       = mdev->limits.num_mgms + mdev->limits.num_amgms;
++	props->max_mcast_qp_attach = MTHCA_QP_PER_MGM;
++	props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * 
++					   props->max_mcast_grp;
+ 
+ 	err = 0;
+  out:
+@@ -150,9 +162,13 @@ static int mthca_query_port(struct ib_de
+ 	props->gid_tbl_len       = to_mdev(ibdev)->limits.gid_table_len;
+ 	props->max_msg_sz        = 0x80000000;
+ 	props->pkey_tbl_len      = to_mdev(ibdev)->limits.pkey_table_len;
++	props->bad_pkey_cntr     = be16_to_cpup((__be16 *) (out_mad->data + 46));
+ 	props->qkey_viol_cntr    = be16_to_cpup((__be16 *) (out_mad->data + 48));
+ 	props->active_width      = out_mad->data[31] & 0xf;
+ 	props->active_speed      = out_mad->data[35] >> 4;
++	props->max_mtu           = out_mad->data[41] & 0xf;
++	props->active_mtu        = out_mad->data[36] >> 4;
++	props->subnet_timeout    = out_mad->data[51] & 0x1f;
+ 
+  out:
+ 	kfree(in_mad);
+@@ -634,6 +650,9 @@ static struct ib_cq *mthca_create_cq(str
+ 	int nent;
+ 	int err;
+ 
++	if (entries < 1 || entries > to_mdev(ibdev)->limits.max_cqes)
++		return ERR_PTR(-EINVAL);
++
+ 	if (context) {
+ 		if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
+ 			return ERR_PTR(-EFAULT);
+@@ -1058,6 +1077,26 @@ int mthca_register_device(struct mthca_d
+ 	strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
+ 	dev->ib_dev.owner                = THIS_MODULE;
+ 
++	dev->ib_dev.uverbs_abi_ver	 = MTHCA_UVERBS_ABI_VERSION;
++	dev->ib_dev.uverbs_cmd_mask	 =
++		(1ull << IB_USER_VERBS_CMD_GET_CONTEXT)		|
++		(1ull << IB_USER_VERBS_CMD_QUERY_DEVICE)	|
++		(1ull << IB_USER_VERBS_CMD_QUERY_PORT)		|
++		(1ull << IB_USER_VERBS_CMD_ALLOC_PD)		|
++		(1ull << IB_USER_VERBS_CMD_DEALLOC_PD)		|
++		(1ull << IB_USER_VERBS_CMD_REG_MR)		|
++		(1ull << IB_USER_VERBS_CMD_DEREG_MR)		|
++		(1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL)	|
++		(1ull << IB_USER_VERBS_CMD_CREATE_CQ)		|
++		(1ull << IB_USER_VERBS_CMD_DESTROY_CQ)		|
++		(1ull << IB_USER_VERBS_CMD_CREATE_QP)		|
++		(1ull << IB_USER_VERBS_CMD_MODIFY_QP)		|
++		(1ull << IB_USER_VERBS_CMD_DESTROY_QP)		|
++		(1ull << IB_USER_VERBS_CMD_ATTACH_MCAST)	|
++		(1ull << IB_USER_VERBS_CMD_DETACH_MCAST)	|
++		(1ull << IB_USER_VERBS_CMD_CREATE_SRQ)		|
++		(1ull << IB_USER_VERBS_CMD_MODIFY_SRQ)		|
++		(1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
+ 	dev->ib_dev.node_type            = IB_NODE_CA;
+ 	dev->ib_dev.phys_port_cnt        = dev->limits.num_ports;
+ 	dev->ib_dev.dma_device           = &dev->pdev->dev;
+@@ -1077,6 +1116,7 @@ int mthca_register_device(struct mthca_d
+ 
+ 	if (dev->mthca_flags & MTHCA_FLAG_SRQ) {
+ 		dev->ib_dev.create_srq           = mthca_create_srq;
++		dev->ib_dev.modify_srq		 = mthca_modify_srq;
+ 		dev->ib_dev.destroy_srq          = mthca_destroy_srq;
+ 
+ 		if (mthca_is_memfree(dev))
+@@ -1135,10 +1175,13 @@ int mthca_register_device(struct mthca_d
+ 		}
+ 	}
+ 
++	mthca_start_catas_poll(dev);
++
+ 	return 0;
+ }
+ 
+ void mthca_unregister_device(struct mthca_dev *dev)
+ {
++	mthca_stop_catas_poll(dev);
+ 	ib_unregister_device(&dev->ib_dev);
+ }
+diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
+--- a/drivers/infiniband/hw/mthca/mthca_qp.c
++++ b/drivers/infiniband/hw/mthca/mthca_qp.c
+@@ -36,6 +36,8 @@
+  */
+ 
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include <rdma/ib_verbs.h>
+ #include <rdma/ib_cache.h>
+@@ -338,8 +340,7 @@ static const struct {
+ 				[UC]  = (IB_QP_AV                  |
+ 					 IB_QP_PATH_MTU            |
+ 					 IB_QP_DEST_QPN            |
+-					 IB_QP_RQ_PSN              |
+-					 IB_QP_MAX_DEST_RD_ATOMIC),
++					 IB_QP_RQ_PSN),
+ 				[RC]  = (IB_QP_AV                  |
+ 					 IB_QP_PATH_MTU            |
+ 					 IB_QP_DEST_QPN            |
+@@ -368,8 +369,7 @@ static const struct {
+ 			.trans = MTHCA_TRANS_RTR2RTS,
+ 			.req_param = {
+ 				[UD]  = IB_QP_SQ_PSN,
+-				[UC]  = (IB_QP_SQ_PSN            |
+-					 IB_QP_MAX_QP_RD_ATOMIC),
++				[UC]  = IB_QP_SQ_PSN,
+ 				[RC]  = (IB_QP_TIMEOUT           |
+ 					 IB_QP_RETRY_CNT         |
+ 					 IB_QP_RNR_RETRY         |
+@@ -446,8 +446,6 @@ static const struct {
+ 				[UD]  = (IB_QP_PKEY_INDEX            |
+ 					 IB_QP_QKEY),
+ 				[UC]  = (IB_QP_AV                    |
+-					 IB_QP_MAX_QP_RD_ATOMIC      |
+-					 IB_QP_MAX_DEST_RD_ATOMIC    |
+ 					 IB_QP_CUR_STATE             |
+ 					 IB_QP_ALT_PATH              |
+ 					 IB_QP_ACCESS_FLAGS          |
+@@ -478,7 +476,7 @@ static const struct {
+ 			.opt_param = {
+ 				[UD]  = (IB_QP_CUR_STATE             |
+ 					 IB_QP_QKEY),
+-				[UC]  = (IB_QP_CUR_STATE),
++				[UC]  = IB_QP_CUR_STATE,
+ 				[RC]  = (IB_QP_CUR_STATE             |
+ 					 IB_QP_MIN_RNR_TIMER),
+ 				[MLX] = (IB_QP_CUR_STATE             |
+@@ -1112,8 +1110,10 @@ static int mthca_set_qp_size(struct mthc
+ 			     struct mthca_qp *qp)
+ {
+ 	/* Sanity check QP size before proceeding */
+-	if (cap->max_send_wr  > 65536 || cap->max_recv_wr  > 65536 ||
+-	    cap->max_send_sge > 64    || cap->max_recv_sge > 64)
++	if (cap->max_send_wr  > dev->limits.max_wqes ||
++	    cap->max_recv_wr  > dev->limits.max_wqes ||
++	    cap->max_send_sge > dev->limits.max_sg   ||
++	    cap->max_recv_sge > dev->limits.max_sg)
+ 		return -EINVAL;
+ 
+ 	if (mthca_is_memfree(dev)) {
+diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
+--- a/drivers/infiniband/hw/mthca/mthca_reset.c
++++ b/drivers/infiniband/hw/mthca/mthca_reset.c
+@@ -37,6 +37,7 @@
+ #include <linux/errno.h>
+ #include <linux/pci.h>
+ #include <linux/delay.h>
++#include <linux/slab.h>
+ 
+ #include "mthca_dev.h"
+ #include "mthca_cmd.h"
+diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
+--- a/drivers/infiniband/hw/mthca/mthca_srq.c
++++ b/drivers/infiniband/hw/mthca/mthca_srq.c
+@@ -186,7 +186,8 @@ int mthca_alloc_srq(struct mthca_dev *de
+ 	int err;
+ 
+ 	/* Sanity check SRQ size before proceeding */
+-	if (attr->max_wr > 16 << 20 || attr->max_sge > 64)
++	if (attr->max_wr  > dev->limits.max_srq_wqes ||
++	    attr->max_sge > dev->limits.max_sg)
+ 		return -EINVAL;
+ 
+ 	srq->max      = attr->max_wr;
+@@ -332,6 +333,29 @@ void mthca_free_srq(struct mthca_dev *de
+ 	mthca_free_mailbox(dev, mailbox);
+ }
+ 
++int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
++		     enum ib_srq_attr_mask attr_mask)
++{	
++	struct mthca_dev *dev = to_mdev(ibsrq->device);
++	struct mthca_srq *srq = to_msrq(ibsrq);
++	int ret;
++	u8 status;
++
++	/* We don't support resizing SRQs (yet?) */
++	if (attr_mask & IB_SRQ_MAX_WR)
++		return -EINVAL;
++
++	if (attr_mask & IB_SRQ_LIMIT) {
++		ret = mthca_ARM_SRQ(dev, srq->srqn, attr->srq_limit, &status);
++		if (ret)
++			return ret;
++		if (status)
++			return -EINVAL;
++	}
++
++	return 0;
++}
++
+ void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
+ 		     enum ib_event_type event_type)
+ {
+@@ -354,7 +378,7 @@ void mthca_srq_event(struct mthca_dev *d
+ 
+ 	event.device      = &dev->ib_dev;
+ 	event.event       = event_type;
+-	event.element.srq  = &srq->ibsrq;
++	event.element.srq = &srq->ibsrq;
+ 	srq->ibsrq.event_handler(&event, srq->ibsrq.srq_context);
+ 
+ out:
+@@ -415,6 +439,14 @@ int mthca_tavor_post_srq_recv(struct ib_
+ 
+ 		wqe       = get_wqe(srq, ind);
+ 		next_ind  = *wqe_to_link(wqe);
++
++		if (next_ind < 0) {
++			mthca_err(dev, "SRQ %06x full\n", srq->srqn);
++			err = -ENOMEM;
++			*bad_wr = wr;
++			break;
++		}
++
+ 		prev_wqe  = srq->last;
+ 		srq->last = wqe;
+ 
+@@ -506,6 +538,13 @@ int mthca_arbel_post_srq_recv(struct ib_
+ 		wqe       = get_wqe(srq, ind);
+ 		next_ind  = *wqe_to_link(wqe);
+ 
++		if (next_ind < 0) {
++			mthca_err(dev, "SRQ %06x full\n", srq->srqn);
++			err = -ENOMEM;
++			*bad_wr = wr;
++			break;
++		}
++
+ 		((struct mthca_next_seg *) wqe)->nda_op =
+ 			cpu_to_be32((next_ind << srq->wqe_shift) | 1);
+ 		((struct mthca_next_seg *) wqe)->ee_nds = 0;
+diff --git a/drivers/infiniband/hw/mthca/mthca_uar.c b/drivers/infiniband/hw/mthca/mthca_uar.c
+--- a/drivers/infiniband/hw/mthca/mthca_uar.c
++++ b/drivers/infiniband/hw/mthca/mthca_uar.c
+@@ -32,6 +32,8 @@
+  * $Id$
+  */
+ 
++#include <asm/page.h>		/* PAGE_SHIFT */
++
+ #include "mthca_dev.h"
+ #include "mthca_memfree.h"
+ 
+diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h
+--- a/drivers/infiniband/hw/mthca/mthca_user.h
++++ b/drivers/infiniband/hw/mthca/mthca_user.h
+@@ -38,6 +38,12 @@
+ #include <linux/types.h>
+ 
+ /*
++ * Increment this value if any changes that break userspace ABI
++ * compatibility are made.
++ */
++#define MTHCA_UVERBS_ABI_VERSION	1
++
++/*
+  * Make sure that all structs defined in this file remain laid out so
+  * that they pack the same way on 32-bit and 64-bit architectures (to
+  * avoid incompatibility between 32-bit userspace and 64-bit kernels).
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
+--- a/drivers/infiniband/ulp/ipoib/ipoib.h
++++ b/drivers/infiniband/ulp/ipoib/ipoib.h
+@@ -100,7 +100,12 @@ struct ipoib_pseudoheader {
+ 
+ struct ipoib_mcast;
+ 
+-struct ipoib_buf {
++struct ipoib_rx_buf {
++	struct sk_buff *skb;
++	dma_addr_t	mapping;
++};
++
++struct ipoib_tx_buf {
+ 	struct sk_buff *skb;
+ 	DECLARE_PCI_UNMAP_ADDR(mapping)
+ };
+@@ -150,14 +155,14 @@ struct ipoib_dev_priv {
+ 	unsigned int admin_mtu;
+ 	unsigned int mcast_mtu;
+ 
+-	struct ipoib_buf *rx_ring;
++	struct ipoib_rx_buf *rx_ring;
+ 
+-	spinlock_t        tx_lock;
+-	struct ipoib_buf *tx_ring;
+-	unsigned          tx_head;
+-	unsigned          tx_tail;
+-	struct ib_sge     tx_sge;
+-	struct ib_send_wr tx_wr;
++	spinlock_t           tx_lock;
++	struct ipoib_tx_buf *tx_ring;
++	unsigned             tx_head;
++	unsigned             tx_tail;
++	struct ib_sge        tx_sge;
++	struct ib_send_wr    tx_wr;
+ 
+ 	struct ib_wc ibwc[IPOIB_NUM_WC];
+ 
+@@ -277,7 +282,7 @@ int ipoib_mcast_attach(struct net_device
+ int ipoib_mcast_detach(struct net_device *dev, u16 mlid,
+ 		       union ib_gid *mgid);
+ 
+-int ipoib_qp_create(struct net_device *dev);
++int ipoib_init_qp(struct net_device *dev);
+ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca);
+ void ipoib_transport_dev_cleanup(struct net_device *dev);
+ 
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+@@ -95,57 +95,65 @@ void ipoib_free_ah(struct kref *kref)
+ 	}
+ }
+ 
+-static inline int ipoib_ib_receive(struct ipoib_dev_priv *priv,
+-				   unsigned int wr_id,
+-				   dma_addr_t addr)
+-{
+-	struct ib_sge list = {
+-		.addr    = addr,
+-		.length  = IPOIB_BUF_SIZE,
+-		.lkey    = priv->mr->lkey,
+-	};
+-	struct ib_recv_wr param = {
+-		.wr_id 	    = wr_id | IPOIB_OP_RECV,
+-		.sg_list    = &list,
+-		.num_sge    = 1,
+-	};
++static int ipoib_ib_post_receive(struct net_device *dev, int id)
++{
++	struct ipoib_dev_priv *priv = netdev_priv(dev);
++	struct ib_sge list;
++	struct ib_recv_wr param;
+ 	struct ib_recv_wr *bad_wr;
++	int ret;
++
++	list.addr     = priv->rx_ring[id].mapping;
++	list.length   = IPOIB_BUF_SIZE;
++	list.lkey     = priv->mr->lkey;
++
++	param.next    = NULL;
++	param.wr_id   = id | IPOIB_OP_RECV;
++	param.sg_list = &list;
++	param.num_sge = 1;
++
++	ret = ib_post_recv(priv->qp, &param, &bad_wr);
++	if (unlikely(ret)) {
++		ipoib_warn(priv, "receive failed for buf %d (%d)\n", id, ret);
++		dma_unmap_single(priv->ca->dma_device,
++				 priv->rx_ring[id].mapping,
++				 IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
++		dev_kfree_skb_any(priv->rx_ring[id].skb);
++		priv->rx_ring[id].skb = NULL;
++	}
+ 
+-	return ib_post_recv(priv->qp, &param, &bad_wr);
++	return ret;
+ }
+ 
+-static int ipoib_ib_post_receive(struct net_device *dev, int id)
++static int ipoib_alloc_rx_skb(struct net_device *dev, int id)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 	struct sk_buff *skb;
+ 	dma_addr_t addr;
+-	int ret;
+ 
+ 	skb = dev_alloc_skb(IPOIB_BUF_SIZE + 4);
+-	if (!skb) {
+-		ipoib_warn(priv, "failed to allocate receive buffer\n");
+-
+-		priv->rx_ring[id].skb = NULL;
++	if (!skb)
+ 		return -ENOMEM;
+-	}
+-	skb_reserve(skb, 4);	/* 16 byte align IP header */
+-	priv->rx_ring[id].skb = skb;
++
++	/*
++	 * IB will leave a 40 byte gap for a GRH and IPoIB adds a 4 byte
++	 * header.  So we need 4 more bytes to get to 48 and align the
++	 * IP header to a multiple of 16.
++	 */
++	skb_reserve(skb, 4);
++
+ 	addr = dma_map_single(priv->ca->dma_device,
+ 			      skb->data, IPOIB_BUF_SIZE,
+ 			      DMA_FROM_DEVICE);
+-	pci_unmap_addr_set(&priv->rx_ring[id], mapping, addr);
+-
+-	ret = ipoib_ib_receive(priv, id, addr);
+-	if (ret) {
+-		ipoib_warn(priv, "ipoib_ib_receive failed for buf %d (%d)\n",
+-			   id, ret);
+-		dma_unmap_single(priv->ca->dma_device, addr,
+-				 IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
++	if (unlikely(dma_mapping_error(addr))) {
+ 		dev_kfree_skb_any(skb);
+-		priv->rx_ring[id].skb = NULL;
++		return -EIO;
+ 	}
+ 
+-	return ret;
++	priv->rx_ring[id].skb     = skb;
++	priv->rx_ring[id].mapping = addr;
++
++	return 0;
+ }
+ 
+ static int ipoib_ib_post_receives(struct net_device *dev)
+@@ -154,6 +162,10 @@ static int ipoib_ib_post_receives(struct
+ 	int i;
+ 
+ 	for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) {
++		if (ipoib_alloc_rx_skb(dev, i)) {
++			ipoib_warn(priv, "failed to allocate receive buffer %d\n", i);
++			return -ENOMEM;
++		}
+ 		if (ipoib_ib_post_receive(dev, i)) {
+ 			ipoib_warn(priv, "ipoib_ib_post_receive failed for buf %d\n", i);
+ 			return -EIO;
+@@ -176,28 +188,36 @@ static void ipoib_ib_handle_wc(struct ne
+ 		wr_id &= ~IPOIB_OP_RECV;
+ 
+ 		if (wr_id < IPOIB_RX_RING_SIZE) {
+-			struct sk_buff *skb = priv->rx_ring[wr_id].skb;
+-
+-			priv->rx_ring[wr_id].skb = NULL;
++			struct sk_buff *skb  = priv->rx_ring[wr_id].skb;
++			dma_addr_t      addr = priv->rx_ring[wr_id].mapping;
+ 
+-			dma_unmap_single(priv->ca->dma_device,
+-					 pci_unmap_addr(&priv->rx_ring[wr_id],
+-							mapping),
+-					 IPOIB_BUF_SIZE,
+-					 DMA_FROM_DEVICE);
+-
+-			if (wc->status != IB_WC_SUCCESS) {
++			if (unlikely(wc->status != IB_WC_SUCCESS)) {
+ 				if (wc->status != IB_WC_WR_FLUSH_ERR)
+ 					ipoib_warn(priv, "failed recv event "
+ 						   "(status=%d, wrid=%d vend_err %x)\n",
+ 						   wc->status, wr_id, wc->vendor_err);
++				dma_unmap_single(priv->ca->dma_device, addr,
++						 IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
+ 				dev_kfree_skb_any(skb);
++				priv->rx_ring[wr_id].skb = NULL;
+ 				return;
+ 			}
+ 
++			/*
++			 * If we can't allocate a new RX buffer, dump
++			 * this packet and reuse the old buffer.
++			 */
++			if (unlikely(ipoib_alloc_rx_skb(dev, wr_id))) {
++				++priv->stats.rx_dropped;
++				goto repost;
++			}
++
+ 			ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n",
+ 				       wc->byte_len, wc->slid);
+ 
++			dma_unmap_single(priv->ca->dma_device, addr,
++					 IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
++
+ 			skb_put(skb, wc->byte_len);
+ 			skb_pull(skb, IB_GRH_BYTES);
+ 
+@@ -220,8 +240,8 @@ static void ipoib_ib_handle_wc(struct ne
+ 				dev_kfree_skb_any(skb);
+ 			}
+ 
+-			/* repost receive */
+-			if (ipoib_ib_post_receive(dev, wr_id))
++		repost:
++			if (unlikely(ipoib_ib_post_receive(dev, wr_id)))
+ 				ipoib_warn(priv, "ipoib_ib_post_receive failed "
+ 					   "for buf %d\n", wr_id);
+ 		} else
+@@ -229,7 +249,7 @@ static void ipoib_ib_handle_wc(struct ne
+ 				   wr_id);
+ 
+ 	} else {
+-		struct ipoib_buf *tx_req;
++		struct ipoib_tx_buf *tx_req;
+ 		unsigned long flags;
+ 
+ 		if (wr_id >= IPOIB_TX_RING_SIZE) {
+@@ -302,7 +322,7 @@ void ipoib_send(struct net_device *dev, 
+ 		struct ipoib_ah *address, u32 qpn)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+-	struct ipoib_buf *tx_req;
++	struct ipoib_tx_buf *tx_req;
+ 	dma_addr_t addr;
+ 
+ 	if (skb->len > dev->mtu + INFINIBAND_ALEN) {
+@@ -387,9 +407,9 @@ int ipoib_ib_dev_open(struct net_device 
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 	int ret;
+ 
+-	ret = ipoib_qp_create(dev);
++	ret = ipoib_init_qp(dev);
+ 	if (ret) {
+-		ipoib_warn(priv, "ipoib_qp_create returned %d\n", ret);
++		ipoib_warn(priv, "ipoib_init_qp returned %d\n", ret);
+ 		return -1;
+ 	}
+ 
+@@ -468,7 +488,7 @@ int ipoib_ib_dev_stop(struct net_device 
+ 	struct ib_qp_attr qp_attr;
+ 	int attr_mask;
+ 	unsigned long begin;
+-	struct ipoib_buf *tx_req;
++	struct ipoib_tx_buf *tx_req;
+ 	int i;
+ 
+ 	/* Kill the existing QP and allocate a new one */
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -637,8 +637,11 @@ static void ipoib_timeout(struct net_dev
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 
+-	ipoib_warn(priv, "transmit timeout: latency %ld\n",
+-		   jiffies - dev->trans_start);
++	ipoib_warn(priv, "transmit timeout: latency %d msecs\n",
++		   jiffies_to_msecs(jiffies - dev->trans_start));
++	ipoib_warn(priv, "queue stopped %d, tx_head %u, tx_tail %u\n",
++		   netif_queue_stopped(dev),
++		   priv->tx_head, priv->tx_tail);
+ 	/* XXX reset QP, etc. */
+ }
+ 
+@@ -729,7 +732,7 @@ int ipoib_dev_init(struct net_device *de
+ 
+ 	/* Allocate RX/TX "rings" to hold queued skbs */
+ 
+-	priv->rx_ring =	kmalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_buf),
++	priv->rx_ring =	kmalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_rx_buf),
+ 				GFP_KERNEL);
+ 	if (!priv->rx_ring) {
+ 		printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n",
+@@ -737,9 +740,9 @@ int ipoib_dev_init(struct net_device *de
+ 		goto out;
+ 	}
+ 	memset(priv->rx_ring, 0,
+-	       IPOIB_RX_RING_SIZE * sizeof (struct ipoib_buf));
++	       IPOIB_RX_RING_SIZE * sizeof (struct ipoib_rx_buf));
+ 
+-	priv->tx_ring = kmalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_buf),
++	priv->tx_ring = kmalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_tx_buf),
+ 				GFP_KERNEL);
+ 	if (!priv->tx_ring) {
+ 		printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n",
+@@ -747,7 +750,7 @@ int ipoib_dev_init(struct net_device *de
+ 		goto out_rx_ring_cleanup;
+ 	}
+ 	memset(priv->tx_ring, 0,
+-	       IPOIB_TX_RING_SIZE * sizeof (struct ipoib_buf));
++	       IPOIB_TX_RING_SIZE * sizeof (struct ipoib_tx_buf));
+ 
+ 	/* priv->tx_head & tx_tail are already 0 */
+ 
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+@@ -92,7 +92,7 @@ int ipoib_mcast_detach(struct net_device
+ 	return ret;
+ }
+ 
+-int ipoib_qp_create(struct net_device *dev)
++int ipoib_init_qp(struct net_device *dev)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 	int ret;
+@@ -149,10 +149,11 @@ int ipoib_qp_create(struct net_device *d
+ 	return 0;
+ 
+ out_fail:
+-	ib_destroy_qp(priv->qp);
+-	priv->qp = NULL;
++	qp_attr.qp_state = IB_QPS_RESET;
++	if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
++		ipoib_warn(priv, "Failed to modify QP to RESET state\n");
+ 
+-	return -EINVAL;
++	return ret;
+ }
+ 
+ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
+diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
+--- a/drivers/input/evdev.c
++++ b/drivers/input/evdev.c
+@@ -20,7 +20,6 @@
+ #include <linux/major.h>
+ #include <linux/smp_lock.h>
+ #include <linux/device.h>
+-#include <linux/devfs_fs_kernel.h>
+ #include <linux/compat.h>
+ 
+ struct evdev {
+@@ -566,6 +565,7 @@ static long evdev_ioctl_compat(struct fi
+ 						case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
+ 						case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
+ 						case EV_FF:  bits = dev->ffbit;  max = FF_MAX;  break;
++						case EV_SW:  bits = dev->swbit;  max = SW_MAX;  break;
+ 						default: return -EINVAL;
+ 					}
+ 					bit_to_user(bits, max);
+@@ -580,6 +580,9 @@ static long evdev_ioctl_compat(struct fi
+ 				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
+ 					bit_to_user(dev->snd, SND_MAX);
+ 
++				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
++					bit_to_user(dev->sw, SW_MAX);
++
+ 				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
+ 					int len;
+ 					if (!dev->name) return -ENOENT;
+@@ -662,6 +665,7 @@ static struct file_operations evdev_fops
+ static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+ {
+ 	struct evdev *evdev;
++	struct class_device *cdev;
+ 	int minor;
+ 
+ 	for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
+@@ -687,11 +691,13 @@ static struct input_handle *evdev_connec
+ 
+ 	evdev_table[minor] = evdev;
+ 
+-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
+-			S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor);
+-	class_device_create(input_class,
++	cdev = class_device_create(&input_class, &dev->cdev,
+ 			MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
+-			dev->dev, "event%d", minor);
++			dev->cdev.dev, evdev->name);
++
++	/* temporary symlink to keep userspace happy */
++	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
++			  evdev->name);
+ 
+ 	return &evdev->handle;
+ }
+@@ -701,9 +707,9 @@ static void evdev_disconnect(struct inpu
+ 	struct evdev *evdev = handle->private;
+ 	struct evdev_list *list;
+ 
+-	class_device_destroy(input_class,
++	sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
++	class_device_destroy(&input_class,
+ 			MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
+-	devfs_remove("input/event%d", evdev->minor);
+ 	evdev->exist = 0;
+ 
+ 	if (evdev->open) {
+diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
+--- a/drivers/input/gameport/gameport.c
++++ b/drivers/input/gameport/gameport.c
+@@ -21,6 +21,7 @@
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+ #include <linux/kthread.h>
++#include <linux/sched.h>	/* HZ */
+ 
+ /*#include <asm/io.h>*/
+ 
+diff --git a/drivers/input/input.c b/drivers/input/input.c
+--- a/drivers/input/input.c
++++ b/drivers/input/input.c
+@@ -22,12 +22,12 @@
+ #include <linux/interrupt.h>
+ #include <linux/poll.h>
+ #include <linux/device.h>
+-#include <linux/devfs_fs_kernel.h>
+ 
+ MODULE_AUTHOR("Vojtech Pavlik <vojtech at suse.cz>");
+ MODULE_DESCRIPTION("Input core");
+ MODULE_LICENSE("GPL");
+ 
++EXPORT_SYMBOL(input_allocate_device);
+ EXPORT_SYMBOL(input_register_device);
+ EXPORT_SYMBOL(input_unregister_device);
+ EXPORT_SYMBOL(input_register_handler);
+@@ -39,7 +39,7 @@ EXPORT_SYMBOL(input_close_device);
+ EXPORT_SYMBOL(input_accept_process);
+ EXPORT_SYMBOL(input_flush_device);
+ EXPORT_SYMBOL(input_event);
+-EXPORT_SYMBOL(input_class);
++EXPORT_SYMBOL_GPL(input_class);
+ 
+ #define INPUT_DEVICES	256
+ 
+@@ -316,124 +316,21 @@ static struct input_device_id *input_mat
+ 	return NULL;
+ }
+ 
+-
+-/*
+- * Input hotplugging interface - loading event handlers based on
+- * device bitfields.
+- */
+-
+-#ifdef CONFIG_HOTPLUG
+-
+-/*
+- * Input hotplugging invokes what /proc/sys/kernel/hotplug says
+- * (normally /sbin/hotplug) when input devices get added or removed.
+- *
+- * This invokes a user mode policy agent, typically helping to load driver
+- * or other modules, configure the device, and more.  Drivers can provide
+- * a MODULE_DEVICE_TABLE to help with module loading subtasks.
+- *
+- */
+-
+-#define SPRINTF_BIT_A(bit, name, max) \
+-	do { \
+-		envp[i++] = scratch; \
+-		scratch += sprintf(scratch, name); \
+-		for (j = NBITS(max) - 1; j >= 0; j--) \
+-			if (dev->bit[j]) break; \
+-		for (; j >= 0; j--) \
+-			scratch += sprintf(scratch, "%lx ", dev->bit[j]); \
+-		scratch++; \
+-	} while (0)
+-
+-#define SPRINTF_BIT_A2(bit, name, max, ev) \
+-	do { \
+-		if (test_bit(ev, dev->evbit)) \
+-			SPRINTF_BIT_A(bit, name, max); \
+-	} while (0)
+-
+-static void input_call_hotplug(char *verb, struct input_dev *dev)
++static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int max)
+ {
+-	char *argv[3], **envp, *buf, *scratch;
+-	int i = 0, j, value;
+-
+-	if (!hotplug_path[0]) {
+-		printk(KERN_ERR "input.c: calling hotplug without a hotplug agent defined\n");
+-		return;
+-	}
+-	if (in_interrupt()) {
+-		printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
+-		return;
+-	}
+-	if (!current->fs->root) {
+-		printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
+-		return;
+-	}
+-	if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
+-		printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
+-		return;
+-	}
+-	if (!(buf = kmalloc(1024, GFP_KERNEL))) {
+-		kfree (envp);
+-		printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
+-		return;
+-	}
+-
+-	argv[0] = hotplug_path;
+-	argv[1] = "input";
+-	argv[2] = NULL;
+-
+-	envp[i++] = "HOME=/";
+-	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+-
+-	scratch = buf;
+-
+-	envp[i++] = scratch;
+-	scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
+-
+-	envp[i++] = scratch;
+-	scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
+-		dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
+-
+-	if (dev->name) {
+-		envp[i++] = scratch;
+-		scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
+-	}
+-
+-	if (dev->phys) {
+-		envp[i++] = scratch;
+-		scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
+-	}
+-
+-	SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
+-	SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
+-	SPRINTF_BIT_A2(relbit, "REL=", REL_MAX, EV_REL);
+-	SPRINTF_BIT_A2(absbit, "ABS=", ABS_MAX, EV_ABS);
+-	SPRINTF_BIT_A2(mscbit, "MSC=", MSC_MAX, EV_MSC);
+-	SPRINTF_BIT_A2(ledbit, "LED=", LED_MAX, EV_LED);
+-	SPRINTF_BIT_A2(sndbit, "SND=", SND_MAX, EV_SND);
+-	SPRINTF_BIT_A2(ffbit,  "FF=",  FF_MAX, EV_FF);
+-	SPRINTF_BIT_A2(swbit,  "SW=",  SW_MAX, EV_SW);
+-
+-	envp[i++] = NULL;
+-
+-#ifdef INPUT_DEBUG
+-	printk(KERN_DEBUG "input.c: calling %s %s [%s %s %s %s %s]\n",
+-		argv[0], argv[1], envp[0], envp[1], envp[2], envp[3], envp[4]);
+-#endif
+-
+-	value = call_usermodehelper(argv [0], argv, envp, 0);
++	int i;
++	int len = 0;
+ 
+-	kfree(buf);
+-	kfree(envp);
++	for (i = NBITS(max) - 1; i > 0; i--)
++		if (bitmap[i])
++			break;
+ 
+-#ifdef INPUT_DEBUG
+-	if (value != 0)
+-		printk(KERN_DEBUG "input.c: hotplug returned %d\n", value);
+-#endif
++	for (; i >= 0; i--)
++		len += snprintf(buf + len, max(buf_size - len, 0),
++				"%lx%s", bitmap[i], i > 0 ? " " : "");
++	return len;
+ }
+ 
+-#endif
+-
+ #ifdef CONFIG_PROC_FS
+ 
+ static struct proc_dir_entry *proc_bus_input_dir;
+@@ -455,37 +352,39 @@ static unsigned int input_devices_poll(s
+ 	return 0;
+ }
+ 
+-#define SPRINTF_BIT_B(bit, name, max) \
+-	do { \
+-		len += sprintf(buf + len, "B: %s", name); \
+-		for (i = NBITS(max) - 1; i >= 0; i--) \
+-			if (dev->bit[i]) break; \
+-		for (; i >= 0; i--) \
+-			len += sprintf(buf + len, "%lx ", dev->bit[i]); \
+-		len += sprintf(buf + len, "\n"); \
++#define SPRINTF_BIT(ev, bm)						\
++	do {								\
++		len += sprintf(buf + len, "B: %s=", #ev);		\
++		len += input_print_bitmap(buf + len, INT_MAX,		\
++					dev->bm##bit, ev##_MAX);	\
++		len += sprintf(buf + len, "\n");			\
+ 	} while (0)
+ 
+-#define SPRINTF_BIT_B2(bit, name, max, ev) \
+-	do { \
+-		if (test_bit(ev, dev->evbit)) \
+-			SPRINTF_BIT_B(bit, name, max); \
++#define TEST_AND_SPRINTF_BIT(ev, bm)					\
++	do {								\
++		if (test_bit(EV_##ev, dev->evbit))			\
++			SPRINTF_BIT(ev, bm);				\
+ 	} while (0)
+ 
+ static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
+ {
+ 	struct input_dev *dev;
+ 	struct input_handle *handle;
++	const char *path;
+ 
+ 	off_t at = 0;
+-	int i, len, cnt = 0;
++	int len, cnt = 0;
+ 
+ 	list_for_each_entry(dev, &input_dev_list, node) {
+ 
++		path = dev->dynalloc ? kobject_get_path(&dev->cdev.kobj, GFP_KERNEL) : NULL;
++
+ 		len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
+ 			dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
+ 
+ 		len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
+ 		len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : "");
++		len += sprintf(buf + len, "S: Sysfs=%s\n", path ? path : "");
+ 		len += sprintf(buf + len, "H: Handlers=");
+ 
+ 		list_for_each_entry(handle, &dev->h_list, d_node)
+@@ -493,15 +392,15 @@ static int input_devices_read(char *buf,
+ 
+ 		len += sprintf(buf + len, "\n");
+ 
+-		SPRINTF_BIT_B(evbit, "EV=", EV_MAX);
+-		SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY);
+-		SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL);
+-		SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS);
+-		SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC);
+-		SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
+-		SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
+-		SPRINTF_BIT_B2(ffbit,  "FF=",  FF_MAX, EV_FF);
+-		SPRINTF_BIT_B2(swbit,  "SW=",  SW_MAX, EV_SW);
++		SPRINTF_BIT(EV, ev);
++		TEST_AND_SPRINTF_BIT(KEY, key);
++		TEST_AND_SPRINTF_BIT(REL, rel);
++		TEST_AND_SPRINTF_BIT(ABS, abs);
++		TEST_AND_SPRINTF_BIT(MSC, msc);
++		TEST_AND_SPRINTF_BIT(LED, led);
++		TEST_AND_SPRINTF_BIT(SND, snd);
++		TEST_AND_SPRINTF_BIT(FF, ff);
++		TEST_AND_SPRINTF_BIT(SW, sw);
+ 
+ 		len += sprintf(buf + len, "\n");
+ 
+@@ -516,6 +415,8 @@ static int input_devices_read(char *buf,
+ 			if (cnt >= count)
+ 				break;
+ 		}
++
++		kfree(path);
+ 	}
+ 
+ 	if (&dev->node == &input_dev_list)
+@@ -606,6 +507,240 @@ static inline int input_proc_init(void) 
+ static inline void input_proc_exit(void) { }
+ #endif
+ 
++#define INPUT_DEV_STRING_ATTR_SHOW(name)					\
++static ssize_t input_dev_show_##name(struct class_device *dev, char *buf)	\
++{										\
++	struct input_dev *input_dev = to_input_dev(dev);			\
++	int retval;								\
++										\
++	retval = down_interruptible(&input_dev->sem);				\
++	if (retval)								\
++		return retval;							\
++										\
++	retval = sprintf(buf, "%s\n", input_dev->name ? input_dev->name : "");	\
++										\
++	up(&input_dev->sem);							\
++										\
++	return retval;								\
++}										\
++static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
++
++INPUT_DEV_STRING_ATTR_SHOW(name);
++INPUT_DEV_STRING_ATTR_SHOW(phys);
++INPUT_DEV_STRING_ATTR_SHOW(uniq);
++
++static struct attribute *input_dev_attrs[] = {
++	&class_device_attr_name.attr,
++	&class_device_attr_phys.attr,
++	&class_device_attr_uniq.attr,
++	NULL
++};
++
++static struct attribute_group input_dev_group = {
++	.attrs	= input_dev_attrs,
++};
++
++#define INPUT_DEV_ID_ATTR(name)							\
++static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf)	\
++{										\
++	struct input_dev *input_dev = to_input_dev(dev);			\
++	return sprintf(buf, "%04x\n", input_dev->id.name);			\
++}										\
++static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
++
++INPUT_DEV_ID_ATTR(bustype);
++INPUT_DEV_ID_ATTR(vendor);
++INPUT_DEV_ID_ATTR(product);
++INPUT_DEV_ID_ATTR(version);
++
++static struct attribute *input_dev_id_attrs[] = {
++	&class_device_attr_bustype.attr,
++	&class_device_attr_vendor.attr,
++	&class_device_attr_product.attr,
++	&class_device_attr_version.attr,
++	NULL
++};
++
++static struct attribute_group input_dev_id_attr_group = {
++	.name	= "id",
++	.attrs	= input_dev_id_attrs,
++};
++
++#define INPUT_DEV_CAP_ATTR(ev, bm)						\
++static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf)	\
++{										\
++	struct input_dev *input_dev = to_input_dev(dev);			\
++	return input_print_bitmap(buf, PAGE_SIZE, input_dev->bm##bit, ev##_MAX);\
++}										\
++static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
++
++INPUT_DEV_CAP_ATTR(EV, ev);
++INPUT_DEV_CAP_ATTR(KEY, key);
++INPUT_DEV_CAP_ATTR(REL, rel);
++INPUT_DEV_CAP_ATTR(ABS, abs);
++INPUT_DEV_CAP_ATTR(MSC, msc);
++INPUT_DEV_CAP_ATTR(LED, led);
++INPUT_DEV_CAP_ATTR(SND, snd);
++INPUT_DEV_CAP_ATTR(FF, ff);
++INPUT_DEV_CAP_ATTR(SW, sw);
++
++static struct attribute *input_dev_caps_attrs[] = {
++	&class_device_attr_ev.attr,
++	&class_device_attr_key.attr,
++	&class_device_attr_rel.attr,
++	&class_device_attr_abs.attr,
++	&class_device_attr_msc.attr,
++	&class_device_attr_led.attr,
++	&class_device_attr_snd.attr,
++	&class_device_attr_ff.attr,
++	&class_device_attr_sw.attr,
++	NULL
++};
++
++static struct attribute_group input_dev_caps_attr_group = {
++	.name	= "capabilities",
++	.attrs	= input_dev_caps_attrs,
++};
++
++static void input_dev_release(struct class_device *class_dev)
++{
++	struct input_dev *dev = to_input_dev(class_dev);
++
++	kfree(dev);
++	module_put(THIS_MODULE);
++}
++
++/*
++ * Input hotplugging interface - loading event handlers based on
++ * device bitfields.
++ */
++static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
++				    char *buffer, int buffer_size, int *cur_len,
++				    const char *name, unsigned long *bitmap, int max)
++{
++	if (*cur_index >= num_envp - 1)
++		return -ENOMEM;
++
++	envp[*cur_index] = buffer + *cur_len;
++
++	*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name);
++	if (*cur_len > buffer_size)
++		return -ENOMEM;
++
++	*cur_len += input_print_bitmap(buffer + *cur_len,
++					max(buffer_size - *cur_len, 0),
++					bitmap, max) + 1;
++	if (*cur_len > buffer_size)
++		return -ENOMEM;
++
++	(*cur_index)++;
++	return 0;
++}
++
++#define INPUT_ADD_HOTPLUG_VAR(fmt, val...)				\
++	do {								\
++		int err = add_hotplug_env_var(envp, num_envp, &i,	\
++					buffer, buffer_size, &len,	\
++					fmt, val);			\
++		if (err)						\
++			return err;					\
++	} while (0)
++
++#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max)				\
++	do {								\
++		int err = input_add_hotplug_bm_var(envp, num_envp, &i,	\
++					buffer, buffer_size, &len,	\
++					name, bm, max);			\
++		if (err)						\
++			return err;					\
++	} while (0)
++
++static int input_dev_hotplug(struct class_device *cdev, char **envp,
++			     int num_envp, char *buffer, int buffer_size)
++{
++	struct input_dev *dev = to_input_dev(cdev);
++	int i = 0;
++	int len = 0;
++
++	INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
++				dev->id.bustype, dev->id.vendor,
++				dev->id.product, dev->id.version);
++	if (dev->name)
++		INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name);
++	if (dev->phys)
++		INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys);
++	if (dev->phys)
++		INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);
++
++	INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);
++	if (test_bit(EV_KEY, dev->evbit))
++		INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX);
++	if (test_bit(EV_REL, dev->evbit))
++		INPUT_ADD_HOTPLUG_BM_VAR("REL=", dev->relbit, REL_MAX);
++	if (test_bit(EV_ABS, dev->evbit))
++		INPUT_ADD_HOTPLUG_BM_VAR("ABS=", dev->absbit, ABS_MAX);
++	if (test_bit(EV_MSC, dev->evbit))
++		INPUT_ADD_HOTPLUG_BM_VAR("MSC=", dev->mscbit, MSC_MAX);
++	if (test_bit(EV_LED, dev->evbit))
++		INPUT_ADD_HOTPLUG_BM_VAR("LED=", dev->ledbit, LED_MAX);
++	if (test_bit(EV_SND, dev->evbit))
++		INPUT_ADD_HOTPLUG_BM_VAR("SND=", dev->sndbit, SND_MAX);
++	if (test_bit(EV_FF, dev->evbit))
++		INPUT_ADD_HOTPLUG_BM_VAR("FF=", dev->ffbit, FF_MAX);
++	if (test_bit(EV_SW, dev->evbit))
++		INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);
++
++	envp[i] = NULL;
++
++	return 0;
++}
++
++struct class input_class = {
++	.name			= "input",
++	.release		= input_dev_release,
++	.hotplug		= input_dev_hotplug,
++};
++
++struct input_dev *input_allocate_device(void)
++{
++	struct input_dev *dev;
++
++	dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
++	if (dev) {
++		dev->dynalloc = 1;
++		dev->cdev.class = &input_class;
++		class_device_initialize(&dev->cdev);
++		INIT_LIST_HEAD(&dev->h_list);
++		INIT_LIST_HEAD(&dev->node);
++	}
++
++	return dev;
++}
++
++static void input_register_classdevice(struct input_dev *dev)
++{
++	static atomic_t input_no = ATOMIC_INIT(0);
++	const char *path;
++
++	__module_get(THIS_MODULE);
++
++	dev->dev = dev->cdev.dev;
++
++	snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
++		 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
++
++	path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
++	printk(KERN_INFO "input: %s as %s/%s\n",
++		dev->name ? dev->name : "Unspecified device",
++		path ? path : "", dev->cdev.class_id);
++	kfree(path);
++
++	class_device_add(&dev->cdev);
++	sysfs_create_group(&dev->cdev.kobj, &input_dev_group);
++	sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
++	sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
++}
++
+ void input_register_device(struct input_dev *dev)
+ {
+ 	struct input_handle *handle;
+@@ -632,15 +767,15 @@ void input_register_device(struct input_
+ 	INIT_LIST_HEAD(&dev->h_list);
+ 	list_add_tail(&dev->node, &input_dev_list);
+ 
++	if (dev->dynalloc)
++		input_register_classdevice(dev);
++
+ 	list_for_each_entry(handler, &input_handler_list, node)
+ 		if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
+ 			if ((id = input_match_device(handler->id_table, dev)))
+ 				if ((handle = handler->connect(handler, dev, id)))
+ 					input_link_handle(handle);
+ 
+-#ifdef CONFIG_HOTPLUG
+-	input_call_hotplug("add", dev);
+-#endif
+ 
+ 	input_wakeup_procfs_readers();
+ }
+@@ -660,12 +795,14 @@ void input_unregister_device(struct inpu
+ 		handle->handler->disconnect(handle);
+ 	}
+ 
+-#ifdef CONFIG_HOTPLUG
+-	input_call_hotplug("remove", dev);
+-#endif
+-
+ 	list_del_init(&dev->node);
+ 
++	if (dev->dynalloc) {
++		sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
++		sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
++		class_device_unregister(&dev->cdev);
++	}
++
+ 	input_wakeup_procfs_readers();
+ }
+ 
+@@ -748,16 +885,14 @@ static struct file_operations input_fops
+ 	.open = input_open_file,
+ };
+ 
+-struct class *input_class;
+-
+ static int __init input_init(void)
+ {
+ 	int err;
+ 
+-	input_class = class_create(THIS_MODULE, "input");
+-	if (IS_ERR(input_class)) {
+-		printk(KERN_ERR "input: unable to register input class\n");
+-		return PTR_ERR(input_class);
++	err = class_register(&input_class);
++	if (err) {
++		printk(KERN_ERR "input: unable to register input_dev class\n");
++		return err;
+ 	}
+ 
+ 	err = input_proc_init();
+@@ -770,24 +905,18 @@ static int __init input_init(void)
+ 		goto fail2;
+ 	}
+ 
+-	err = devfs_mk_dir("input");
+-	if (err)
+-		goto fail3;
+-
+ 	return 0;
+ 
+- fail3:	unregister_chrdev(INPUT_MAJOR, "input");
+  fail2:	input_proc_exit();
+- fail1:	class_destroy(input_class);
++ fail1:	class_unregister(&input_class);
+ 	return err;
+ }
+ 
+ static void __exit input_exit(void)
+ {
+ 	input_proc_exit();
+-	devfs_remove("input");
+ 	unregister_chrdev(INPUT_MAJOR, "input");
+-	class_destroy(input_class);
++	class_unregister(&input_class);
+ }
+ 
+ subsys_initcall(input_init);
+diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
+--- a/drivers/input/joydev.c
++++ b/drivers/input/joydev.c
+@@ -26,7 +26,6 @@
+ #include <linux/init.h>
+ #include <linux/smp_lock.h>
+ #include <linux/device.h>
+-#include <linux/devfs_fs_kernel.h>
+ 
+ MODULE_AUTHOR("Vojtech Pavlik <vojtech at ucw.cz>");
+ MODULE_DESCRIPTION("Joystick device interfaces");
+@@ -449,6 +448,7 @@ static struct file_operations joydev_fop
+ static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+ {
+ 	struct joydev *joydev;
++	struct class_device *cdev;
+ 	int i, j, t, minor;
+ 
+ 	for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
+@@ -514,11 +514,13 @@ static struct input_handle *joydev_conne
+ 
+ 	joydev_table[minor] = joydev;
+ 
+-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
+-			S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor);
+-	class_device_create(input_class,
++	cdev = class_device_create(&input_class, &dev->cdev,
+ 			MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
+-			dev->dev, "js%d", minor);
++			dev->cdev.dev, joydev->name);
++
++	/* temporary symlink to keep userspace happy */
++	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
++			  joydev->name);
+ 
+ 	return &joydev->handle;
+ }
+@@ -528,8 +530,8 @@ static void joydev_disconnect(struct inp
+ 	struct joydev *joydev = handle->private;
+ 	struct joydev_list *list;
+ 
+-	class_device_destroy(input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
+-	devfs_remove("input/js%d", joydev->minor);
++	sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
++	class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
+ 	joydev->exist = 0;
+ 
+ 	if (joydev->open) {
+diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
+--- a/drivers/input/joystick/a3d.c
++++ b/drivers/input/joystick/a3d.c
+@@ -34,6 +34,7 @@
+ #include <linux/init.h>
+ #include <linux/gameport.h>
+ #include <linux/input.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"FP-Gaming Assasin 3D joystick driver"
+ 
+diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
+--- a/drivers/input/joystick/adi.c
++++ b/drivers/input/joystick/adi.c
+@@ -34,6 +34,7 @@
+ #include <linux/input.h>
+ #include <linux/gameport.h>
+ #include <linux/init.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"Logitech ADI joystick family driver"
+ 
+@@ -54,7 +55,7 @@ MODULE_LICENSE("GPL");
+ #define ADI_MIN_LENGTH		8
+ #define ADI_MIN_LEN_LENGTH	10
+ #define ADI_MIN_ID_LENGTH	66
+-#define ADI_MAX_NAME_LENGTH	48
++#define ADI_MAX_NAME_LENGTH	64
+ #define ADI_MAX_CNAME_LENGTH	16
+ #define ADI_MAX_PHYS_LENGTH	64
+ 
+@@ -106,7 +107,7 @@ static struct {
+  */
+ 
+ struct adi {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	int length;
+ 	int ret;
+ 	int idx;
+@@ -215,7 +216,7 @@ static inline int adi_get_bits(struct ad
+ 
+ static int adi_decode(struct adi *adi)
+ {
+-	struct input_dev *dev = &adi->dev;
++	struct input_dev *dev = adi->dev;
+ 	char *abs = adi->abs;
+ 	short *key = adi->key;
+ 	int i, t;
+@@ -318,7 +319,8 @@ static void adi_init_digital(struct game
+ 
+ 	for (i = 0; seq[i]; i++) {
+ 		gameport_trigger(gameport);
+-		if (seq[i] > 0) msleep(seq[i]);
++		if (seq[i] > 0)
++			msleep(seq[i]);
+ 		if (seq[i] < 0) {
+ 			mdelay(-seq[i]);
+ 			udelay(-seq[i]*14);	/* It looks like mdelay() is off by approx 1.4% */
+@@ -397,42 +399,46 @@ static void adi_id_decode(struct adi *ad
+ 	}
+ }
+ 
+-static void adi_init_input(struct adi *adi, struct adi_port *port, int half)
++static int adi_init_input(struct adi *adi, struct adi_port *port, int half)
+ {
+-	int i, t;
++	struct input_dev *input_dev;
+ 	char buf[ADI_MAX_NAME_LENGTH];
++	int i, t;
+ 
+-	if (!adi->length) return;
+-
+-	init_input_dev(&adi->dev);
++	adi->dev = input_dev = input_allocate_device();
++	if (!input_dev)
++		return -ENOMEM;
+ 
+ 	t = adi->id < ADI_ID_MAX ? adi->id : ADI_ID_MAX;
+ 
+ 	snprintf(buf, ADI_MAX_PHYS_LENGTH, adi_names[t], adi->id);
+-	snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s", buf);
++	snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s [%s]", buf, adi->cname);
+ 	snprintf(adi->phys, ADI_MAX_PHYS_LENGTH, "%s/input%d", port->gameport->phys, half);
+ 
+ 	adi->abs = adi_abs[t];
+ 	adi->key = adi_key[t];
+ 
+-	adi->dev.open = adi_open;
+-	adi->dev.close = adi_close;
++	input_dev->name = adi->name;
++	input_dev->phys = adi->phys;
++	input_dev->id.bustype = BUS_GAMEPORT;
++	input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH;
++	input_dev->id.product = adi->id;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &port->gameport->dev;
++	input_dev->private = port;
+ 
+-	adi->dev.name = adi->name;
+-	adi->dev.phys = adi->phys;
+-	adi->dev.id.bustype = BUS_GAMEPORT;
+-	adi->dev.id.vendor = GAMEPORT_ID_VENDOR_LOGITECH;
+-	adi->dev.id.product = adi->id;
+-	adi->dev.id.version = 0x0100;
++	input_dev->open = adi_open;
++	input_dev->close = adi_close;
+ 
+-	adi->dev.private = port;
+-	adi->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+ 	for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++)
+-		set_bit(adi->abs[i], adi->dev.absbit);
++		set_bit(adi->abs[i], input_dev->absbit);
+ 
+ 	for (i = 0; i < adi->buttons; i++)
+-		set_bit(adi->key[i], adi->dev.keybit);
++		set_bit(adi->key[i], input_dev->keybit);
++
++	return 0;
+ }
+ 
+ static void adi_init_center(struct adi *adi)
+@@ -445,17 +451,17 @@ static void adi_init_center(struct adi *
+ 	for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) {
+ 
+ 		t = adi->abs[i];
+-		x = adi->dev.abs[t];
++		x = adi->dev->abs[t];
+ 
+ 		if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE)
+ 			x = i < adi->axes10 ? 512 : 128;
+ 
+ 		if (i < adi->axes10)
+-			input_set_abs_params(&adi->dev, t, 64, x * 2 - 64, 2, 16);
++			input_set_abs_params(adi->dev, t, 64, x * 2 - 64, 2, 16);
+ 		else if (i < adi->axes10 + adi->axes8)
+-			input_set_abs_params(&adi->dev, t, 48, x * 2 - 48, 1, 16);
++			input_set_abs_params(adi->dev, t, 48, x * 2 - 48, 1, 16);
+ 		else
+-			input_set_abs_params(&adi->dev, t, -1, 1, 0, 0);
++			input_set_abs_params(adi->dev, t, -1, 1, 0, 0);
+ 	}
+ }
+ 
+@@ -469,7 +475,8 @@ static int adi_connect(struct gameport *
+ 	int i;
+ 	int err;
+ 
+-	if (!(port = kzalloc(sizeof(struct adi_port), GFP_KERNEL)))
++	port = kzalloc(sizeof(struct adi_port), GFP_KERNEL);
++	if (!port)
+ 		return -ENOMEM;
+ 
+ 	port->gameport = gameport;
+@@ -477,10 +484,8 @@ static int adi_connect(struct gameport *
+ 	gameport_set_drvdata(gameport, port);
+ 
+ 	err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
+-	if (err) {
+-		kfree(port);
+-		return err;
+-	}
++	if (err)
++		goto fail1;
+ 
+ 	adi_init_digital(gameport);
+ 	adi_read_packet(port);
+@@ -490,13 +495,18 @@ static int adi_connect(struct gameport *
+ 
+ 	for (i = 0; i < 2; i++) {
+ 		adi_id_decode(port->adi + i, port);
+-		adi_init_input(port->adi + i, port, i);
++
++		if (!port->adi[i].length)
++			continue;
++
++		err = adi_init_input(port->adi + i, port, i);
++		if (err)
++			goto fail2;
+ 	}
+ 
+ 	if (!port->adi[0].length && !port->adi[1].length) {
+-		gameport_close(gameport);
+-		kfree(port);
+-		return -ENODEV;
++		err = -ENODEV;
++		goto fail2;
+ 	}
+ 
+ 	gameport_set_poll_handler(gameport, adi_poll);
+@@ -511,12 +521,18 @@ static int adi_connect(struct gameport *
+ 	for (i = 0; i < 2; i++)
+ 		if (port->adi[i].length > 0) {
+ 			adi_init_center(port->adi + i);
+-			input_register_device(&port->adi[i].dev);
+-			printk(KERN_INFO "input: %s [%s] on %s\n",
+-				port->adi[i].name, port->adi[i].cname, gameport->phys);
++			input_register_device(port->adi[i].dev);
+ 		}
+ 
+ 	return 0;
++
++ fail2:	for (i = 0; i < 2; i++)
++		if (port->adi[i].dev)
++			input_free_device(port->adi[i].dev);
++	gameport_close(gameport);
++ fail1:	gameport_set_drvdata(gameport, NULL);
++	kfree(port);
++	return err;
+ }
+ 
+ static void adi_disconnect(struct gameport *gameport)
+@@ -526,7 +542,7 @@ static void adi_disconnect(struct gamepo
+ 
+ 	for (i = 0; i < 2; i++)
+ 		if (port->adi[i].length > 0)
+-			input_unregister_device(&port->adi[i].dev);
++			input_unregister_device(port->adi[i].dev);
+ 	gameport_close(gameport);
+ 	gameport_set_drvdata(gameport, NULL);
+ 	kfree(port);
+diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
+--- a/drivers/input/joystick/amijoy.c
++++ b/drivers/input/joystick/amijoy.c
+@@ -53,11 +53,9 @@ __obsolete_setup("amijoy=");
+ 
+ static int amijoy_used;
+ static DECLARE_MUTEX(amijoy_sem);
+-static struct input_dev amijoy_dev[2];
++static struct input_dev *amijoy_dev[2];
+ static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
+ 
+-static char *amijoy_name = "Amiga joystick";
+-
+ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
+ {
+ 	int i, data = 0, button = 0;
+@@ -70,15 +68,15 @@ static irqreturn_t amijoy_interrupt(int 
+ 				case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
+ 			}
+ 
+-			input_regs(amijoy_dev + i, fp);
++			input_regs(amijoy_dev[i], fp);
+ 
+-			input_report_key(amijoy_dev + i, BTN_TRIGGER, button);
++			input_report_key(amijoy_dev[i], BTN_TRIGGER, button);
+ 
+-			input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
++			input_report_abs(amijoy_dev[i], ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
+ 			data = ~(data ^ (data << 1));
+-			input_report_abs(amijoy_dev + i, ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
++			input_report_abs(amijoy_dev[i], ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
+ 
+-			input_sync(amijoy_dev + i);
++			input_sync(amijoy_dev[i]);
+ 		}
+ 	return IRQ_HANDLED;
+ }
+@@ -114,39 +112,52 @@ static void amijoy_close(struct input_de
+ static int __init amijoy_init(void)
+ {
+ 	int i, j;
++	int err;
+ 
+-	for (i = 0; i < 2; i++)
+-		if (amijoy[i]) {
+-			if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2,
+-						"amijoy [Denise]")) {
+-				if (i == 1 && amijoy[0]) {
+-					input_unregister_device(amijoy_dev);
+-					release_mem_region(CUSTOM_PHYSADDR+10, 2);
+-				}
+-				return -EBUSY;
+-			}
+-
+-			amijoy_dev[i].open = amijoy_open;
+-			amijoy_dev[i].close = amijoy_close;
+-			amijoy_dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-			amijoy_dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+-			amijoy_dev[i].keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+-			for (j = 0; j < 2; j++) {
+-				amijoy_dev[i].absmin[ABS_X + j] = -1;
+-				amijoy_dev[i].absmax[ABS_X + j] = 1;
+-			}
++	for (i = 0; i < 2; i++) {
++		if (!amijoy[i])
++			continue;
++
++		amijoy_dev[i] = input_allocate_device();
++		if (!amijoy_dev[i]) {
++			err = -ENOMEM;
++			goto fail;
++		}
+ 
+-			amijoy_dev[i].name = amijoy_name;
+-			amijoy_dev[i].phys = amijoy_phys[i];
+-			amijoy_dev[i].id.bustype = BUS_AMIGA;
+-			amijoy_dev[i].id.vendor = 0x0001;
+-			amijoy_dev[i].id.product = 0x0003;
+-			amijoy_dev[i].id.version = 0x0100;
++		if (!request_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2, "amijoy [Denise]")) {
++			input_free_device(amijoy_dev[i]);
++			err = -EBUSY;
++			goto fail;
++		}
+ 
+-			input_register_device(amijoy_dev + i);
+-			printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i);
++		amijoy_dev[i]->name = "Amiga joystick";
++		amijoy_dev[i]->phys = amijoy_phys[i];
++		amijoy_dev[i]->id.bustype = BUS_AMIGA;
++		amijoy_dev[i]->id.vendor = 0x0001;
++		amijoy_dev[i]->id.product = 0x0003;
++		amijoy_dev[i]->id.version = 0x0100;
++
++		amijoy_dev[i]->open = amijoy_open;
++		amijoy_dev[i]->close = amijoy_close;
++
++		amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++		amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
++		amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++		for (j = 0; j < 2; j++) {
++			amijoy_dev[i]->absmin[ABS_X + j] = -1;
++			amijoy_dev[i]->absmax[ABS_X + j] = 1;
+ 		}
++
++		input_register_device(amijoy_dev[i]);
++	}
+ 	return 0;
++
++ fail:	while (--i >= 0)
++		if (amijoy[i]) {
++			input_unregister_device(amijoy_dev[i]);
++			release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
++		}
++	return err;
+ }
+ 
+ static void __exit amijoy_exit(void)
+@@ -155,8 +166,8 @@ static void __exit amijoy_exit(void)
+ 
+ 	for (i = 0; i < 2; i++)
+ 		if (amijoy[i]) {
+-			input_unregister_device(amijoy_dev + i);
+-			release_mem_region(CUSTOM_PHYSADDR+10+i*2, 2);
++			input_unregister_device(amijoy_dev[i]);
++			release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
+ 		}
+ }
+ 
+diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
+--- a/drivers/input/joystick/analog.c
++++ b/drivers/input/joystick/analog.c
+@@ -38,6 +38,7 @@
+ #include <linux/init.h>
+ #include <linux/input.h>
+ #include <linux/gameport.h>
++#include <linux/jiffies.h>
+ #include <asm/timex.h>
+ 
+ #define DRIVER_DESC	"Analog joystick and gamepad driver"
+@@ -111,7 +112,7 @@ static short analog_joy_btn[] = { BTN_TR
+ static unsigned char analog_chf[] = { 0xf, 0x0, 0x1, 0x9, 0x2, 0x4, 0xc, 0x8, 0x3, 0x5, 0xb, 0x7, 0xd, 0xe, 0xa, 0x6 };
+ 
+ struct analog {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	int mask;
+ 	short *buttons;
+ 	char name[ANALOG_MAX_NAME_LENGTH];
+@@ -182,7 +183,7 @@ static unsigned long analog_faketime = 0
+ 
+ static void analog_decode(struct analog *analog, int *axes, int *initial, int buttons)
+ {
+-	struct input_dev *dev = &analog->dev;
++	struct input_dev *dev = analog->dev;
+ 	int i, j;
+ 
+ 	if (analog->mask & ANALOG_HAT_FCS)
+@@ -428,27 +429,30 @@ static void analog_name(struct analog *a
+  * analog_init_device()
+  */
+ 
+-static void analog_init_device(struct analog_port *port, struct analog *analog, int index)
++static int analog_init_device(struct analog_port *port, struct analog *analog, int index)
+ {
++	struct input_dev *input_dev;
+ 	int i, j, t, v, w, x, y, z;
+ 
+ 	analog_name(analog);
+ 	sprintf(analog->phys, "%s/input%d", port->gameport->phys, index);
+ 	analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn;
+ 
+-	init_input_dev(&analog->dev);
+-
+-	analog->dev.name = analog->name;
+-	analog->dev.phys = analog->phys;
+-	analog->dev.id.bustype = BUS_GAMEPORT;
+-	analog->dev.id.vendor = GAMEPORT_ID_VENDOR_ANALOG;
+-	analog->dev.id.product = analog->mask >> 4;
+-	analog->dev.id.version = 0x0100;
+-
+-	analog->dev.open = analog_open;
+-	analog->dev.close = analog_close;
+-	analog->dev.private = port;
+-	analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	analog->dev = input_dev = input_allocate_device();
++	if (!input_dev)
++		return -ENOMEM;
++
++	input_dev->name = analog->name;
++	input_dev->phys = analog->phys;
++	input_dev->id.bustype = BUS_GAMEPORT;
++	input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG;
++	input_dev->id.product = analog->mask >> 4;
++	input_dev->id.version = 0x0100;
++
++	input_dev->open = analog_open;
++	input_dev->close = analog_close;
++	input_dev->private = port;
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+ 	for (i = j = 0; i < 4; i++)
+ 		if (analog->mask & (1 << i)) {
+@@ -461,8 +465,6 @@ static void analog_init_device(struct an
+ 			v = (x >> 3);
+ 			w = (x >> 3);
+ 
+-			set_bit(t, analog->dev.absbit);
+-
+ 			if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3)))
+ 				x = y;
+ 
+@@ -472,11 +474,7 @@ static void analog_init_device(struct an
+ 				w = (x >> 4);
+ 			}
+ 
+-			analog->dev.absmax[t] = (x << 1) - v;
+-			analog->dev.absmin[t] = v;
+-			analog->dev.absfuzz[t] = port->fuzz;
+-			analog->dev.absflat[t] = w;
+-
++			input_set_abs_params(input_dev, t, v, (x << 1) - v, port->fuzz, w);
+ 			j++;
+ 		}
+ 
+@@ -484,41 +482,30 @@ static void analog_init_device(struct an
+ 		if (analog->mask & analog_exts[i])
+ 			for (x = 0; x < 2; x++) {
+ 				t = analog_hats[j++];
+-				set_bit(t, analog->dev.absbit);
+-				analog->dev.absmax[t] = 1;
+-				analog->dev.absmin[t] = -1;
++				input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+ 			}
+ 
+ 	for (i = j = 0; i < 4; i++)
+ 		if (analog->mask & (0x10 << i))
+-			set_bit(analog->buttons[j++], analog->dev.keybit);
++			set_bit(analog->buttons[j++], input_dev->keybit);
+ 
+ 	if (analog->mask & ANALOG_BTNS_CHF)
+ 		for (i = 0; i < 2; i++)
+-			set_bit(analog->buttons[j++], analog->dev.keybit);
++			set_bit(analog->buttons[j++], input_dev->keybit);
+ 
+ 	if (analog->mask & ANALOG_HBTN_CHF)
+ 		for (i = 0; i < 4; i++)
+-			set_bit(analog->buttons[j++], analog->dev.keybit);
++			set_bit(analog->buttons[j++], input_dev->keybit);
+ 
+ 	for (i = 0; i < 4; i++)
+ 		if (analog->mask & (ANALOG_BTN_TL << i))
+-			set_bit(analog_pads[i], analog->dev.keybit);
++			set_bit(analog_pads[i], input_dev->keybit);
+ 
+ 	analog_decode(analog, port->axes, port->initial, port->buttons);
+ 
+-	input_register_device(&analog->dev);
+-
+-	printk(KERN_INFO "input: %s at %s", analog->name, port->gameport->phys);
++	input_register_device(analog->dev);
+ 
+-	if (port->cooked)
+-		printk(" [ADC port]\n");
+-	else
+-		printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
+-		port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
+-		port->speed > 10000 ? "M" : "k",
+-		port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
+-				    : (port->loop * 1000000) / port->speed);
++	return 0;
+ }
+ 
+ /*
+@@ -659,37 +646,41 @@ static int analog_connect(struct gamepor
+ 		return - ENOMEM;
+ 
+ 	err = analog_init_port(gameport, drv, port);
+-	if (err) {
+-		kfree(port);
+-		return err;
+-	}
++	if (err)
++		goto fail1;
+ 
+ 	err = analog_init_masks(port);
+-	if (err) {
+-		gameport_close(gameport);
+-		gameport_set_drvdata(gameport, NULL);
+-		kfree(port);
+-		return err;
+-	}
++	if (err)
++		goto fail2;
+ 
+ 	gameport_set_poll_handler(gameport, analog_poll);
+ 	gameport_set_poll_interval(gameport, 10);
+ 
+ 	for (i = 0; i < 2; i++)
+-		if (port->analog[i].mask)
+-			analog_init_device(port, port->analog + i, i);
++		if (port->analog[i].mask) {
++			err = analog_init_device(port, port->analog + i, i);
++			if (err)
++				goto fail3;
++		}
+ 
+ 	return 0;
++
++ fail3: while (--i >= 0)
++		input_unregister_device(port->analog[i].dev);
++ fail2:	gameport_close(gameport);
++ fail1:	gameport_set_drvdata(gameport, NULL);
++	kfree(port);
++	return err;
+ }
+ 
+ static void analog_disconnect(struct gameport *gameport)
+ {
+-	int i;
+ 	struct analog_port *port = gameport_get_drvdata(gameport);
++	int i;
+ 
+ 	for (i = 0; i < 2; i++)
+ 		if (port->analog[i].mask)
+-			input_unregister_device(&port->analog[i].dev);
++			input_unregister_device(port->analog[i].dev);
+ 	gameport_close(gameport);
+ 	gameport_set_drvdata(gameport, NULL);
+ 	printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on %s failed\n",
+diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
+--- a/drivers/input/joystick/cobra.c
++++ b/drivers/input/joystick/cobra.c
+@@ -34,6 +34,7 @@
+ #include <linux/init.h>
+ #include <linux/gameport.h>
+ #include <linux/input.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"Creative Labs Blaster GamePad Cobra driver"
+ 
+@@ -44,13 +45,11 @@ MODULE_LICENSE("GPL");
+ #define COBRA_MAX_STROBE	45	/* 45 us max wait for first strobe */
+ #define COBRA_LENGTH		36
+ 
+-static char* cobra_name = "Creative Labs Blaster GamePad Cobra";
+-
+ static int cobra_btn[] = { BTN_START, BTN_SELECT, BTN_TL, BTN_TR, BTN_X, BTN_Y, BTN_Z, BTN_A, BTN_B, BTN_C, BTN_TL2, BTN_TR2, 0 };
+ 
+ struct cobra {
+ 	struct gameport *gameport;
+-	struct input_dev dev[2];
++	struct input_dev *dev[2];
+ 	int reads;
+ 	int bads;
+ 	unsigned char exists;
+@@ -128,7 +127,7 @@ static void cobra_poll(struct gameport *
+ 	for (i = 0; i < 2; i++)
+ 		if (cobra->exists & r & (1 << i)) {
+ 
+-			dev = cobra->dev + i;
++			dev = cobra->dev[i];
+ 
+ 			input_report_abs(dev, ABS_X, ((data[i] >> 4) & 1) - ((data[i] >> 3) & 1));
+ 			input_report_abs(dev, ABS_Y, ((data[i] >> 2) & 1) - ((data[i] >> 1) & 1));
+@@ -159,11 +158,13 @@ static void cobra_close(struct input_dev
+ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
+ {
+ 	struct cobra *cobra;
++	struct input_dev *input_dev;
+ 	unsigned int data[2];
+ 	int i, j;
+ 	int err;
+ 
+-	if (!(cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL)))
++	cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL);
++	if (!cobra)
+ 		return -ENOMEM;
+ 
+ 	cobra->gameport = gameport;
+@@ -191,38 +192,46 @@ static int cobra_connect(struct gameport
+ 	gameport_set_poll_handler(gameport, cobra_poll);
+ 	gameport_set_poll_interval(gameport, 20);
+ 
+-	for (i = 0; i < 2; i++)
+-		if ((cobra->exists >> i) & 1) {
+-
+-			sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
+-
+-			cobra->dev[i].private = cobra;
+-			cobra->dev[i].open = cobra_open;
+-			cobra->dev[i].close = cobra_close;
+-
+-			cobra->dev[i].name = cobra_name;
+-			cobra->dev[i].phys = cobra->phys[i];
+-			cobra->dev[i].id.bustype = BUS_GAMEPORT;
+-			cobra->dev[i].id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
+-			cobra->dev[i].id.product = 0x0008;
+-			cobra->dev[i].id.version = 0x0100;
++	for (i = 0; i < 2; i++) {
++		if (~(cobra->exists >> i) & 1)
++			continue;
+ 
+-			cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++		cobra->dev[i] = input_dev = input_allocate_device();
++		if (!input_dev) {
++			err = -ENOMEM;
++			goto fail3;
++		}
+ 
+-			input_set_abs_params(&cobra->dev[i], ABS_X, -1, 1, 0, 0);
+-			input_set_abs_params(&cobra->dev[i], ABS_Y, -1, 1, 0, 0);
++		sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
+ 
+-			for (j = 0; cobra_btn[j]; j++)
+-				set_bit(cobra_btn[j], cobra->dev[i].keybit);
++		input_dev->name = "Creative Labs Blaster GamePad Cobra";
++		input_dev->phys = cobra->phys[i];
++		input_dev->id.bustype = BUS_GAMEPORT;
++		input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
++		input_dev->id.product = 0x0008;
++		input_dev->id.version = 0x0100;
++		input_dev->cdev.dev = &gameport->dev;
++		input_dev->private = cobra;
++
++		input_dev->open = cobra_open;
++		input_dev->close = cobra_close;
++
++		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++		input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
++		input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
++		for (j = 0; cobra_btn[j]; j++)
++			set_bit(cobra_btn[j], input_dev->keybit);
+ 
+-			input_register_device(&cobra->dev[i]);
+-			printk(KERN_INFO "input: %s on %s\n", cobra_name, gameport->phys);
+-		}
++		input_register_device(cobra->dev[i]);
++	}
+ 
+ 	return 0;
+ 
+-fail2:	gameport_close(gameport);
+-fail1:	gameport_set_drvdata(gameport, NULL);
++ fail3:	for (i = 0; i < 2; i++)
++		if (cobra->dev[i])
++			input_unregister_device(cobra->dev[i]);
++ fail2:	gameport_close(gameport);
++ fail1:	gameport_set_drvdata(gameport, NULL);
+ 	kfree(cobra);
+ 	return err;
+ }
+@@ -234,7 +243,7 @@ static void cobra_disconnect(struct game
+ 
+ 	for (i = 0; i < 2; i++)
+ 		if ((cobra->exists >> i) & 1)
+-			input_unregister_device(cobra->dev + i);
++			input_unregister_device(cobra->dev[i]);
+ 	gameport_close(gameport);
+ 	gameport_set_drvdata(gameport, NULL);
+ 	kfree(cobra);
+diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
+--- a/drivers/input/joystick/db9.c
++++ b/drivers/input/joystick/db9.c
+@@ -43,25 +43,28 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech at u
+ MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
+ MODULE_LICENSE("GPL");
+ 
+-static int db9[] __initdata = { -1, 0 };
+-static int db9_nargs __initdata = 0;
+-module_param_array_named(dev, db9, int, &db9_nargs, 0);
+-MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
++struct db9_config {
++	int args[2];
++	int nargs;
++};
+ 
+-static int db9_2[] __initdata = { -1, 0 };
+-static int db9_nargs_2 __initdata = 0;
+-module_param_array_named(dev2, db9_2, int, &db9_nargs_2, 0);
+-MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
++#define DB9_MAX_PORTS		3
++static struct db9_config db9[DB9_MAX_PORTS] __initdata;
+ 
+-static int db9_3[] __initdata = { -1, 0 };
+-static int db9_nargs_3 __initdata = 0;
+-module_param_array_named(dev3, db9_3, int, &db9_nargs_3, 0);
++module_param_array_named(dev, db9[0].args, int, &db9[0].nargs, 0);
++MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
++module_param_array_named(dev2, db9[1].args, int, &db9[0].nargs, 0);
++MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
++module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0);
+ MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
+ 
+ __obsolete_setup("db9=");
+ __obsolete_setup("db9_2=");
+ __obsolete_setup("db9_3=");
+ 
++#define DB9_ARG_PARPORT		0
++#define DB9_ARG_MODE		1
++
+ #define DB9_MULTI_STICK		0x01
+ #define DB9_MULTI2_STICK	0x02
+ #define DB9_GENESIS_PAD		0x03
+@@ -87,40 +90,53 @@ __obsolete_setup("db9_3=");
+ #define DB9_NORMAL		0x0a
+ #define DB9_NOSELECT		0x08
+ 
+-#define DB9_MAX_DEVICES		2
+-
+ #define DB9_GENESIS6_DELAY	14
+ #define DB9_REFRESH_TIME	HZ/100
+ 
++#define DB9_MAX_DEVICES		2
++
++struct db9_mode_data {
++	const char *name;
++	const short *buttons;
++	int n_buttons;
++	int n_pads;
++	int n_axis;
++	int bidirectional;
++	int reverse;
++};
++
+ struct db9 {
+-	struct input_dev dev[DB9_MAX_DEVICES];
++	struct input_dev *dev[DB9_MAX_DEVICES];
+ 	struct timer_list timer;
+ 	struct pardevice *pd;
+ 	int mode;
+ 	int used;
+ 	struct semaphore sem;
+-	char phys[2][32];
++	char phys[DB9_MAX_DEVICES][32];
+ };
+ 
+ static struct db9 *db9_base[3];
+ 
+-static short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
+-static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
+-static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
+-
+-static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 9, 1, 1, 7, 9, 9 };
+-static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
+-					db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn,
+-					db9_cd32_btn, db9_cd32_btn };
+-static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
+-				      NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
+-				     "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad", "Saturn dpp", "Saturn dpp dual" };
+-
+-static const int db9_max_pads[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 6, 1, 2, 1, 6, 12 };
+-static const int db9_num_axis[DB9_MAX_PAD] = { 0, 2, 2, 2, 0, 2, 2, 7, 2, 2, 2 ,7, 7 };
++static const short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
++static const short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
++static const short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
+ static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
+-static const int db9_bidirectional[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0 };
+-static const int db9_reverse[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 };
++
++static const struct db9_mode_data db9_modes[] = {
++	{ NULL,					 NULL,		  0,  0,  0,  0,  0 },
++	{ "Multisystem joystick",		 db9_multi_btn,	  1,  1,  2,  1,  1 },
++	{ "Multisystem joystick (2 fire)",	 db9_multi_btn,	  2,  1,  2,  1,  1 },
++	{ "Genesis pad",			 db9_genesis_btn, 4,  1,  2,  1,  1 },
++	{ NULL,					 NULL,		  0,  0,  0,  0,  0 },
++	{ "Genesis 5 pad",			 db9_genesis_btn, 6,  1,  2,  1,  1 },
++	{ "Genesis 6 pad",			 db9_genesis_btn, 8,  1,  2,  1,  1 },
++	{ "Saturn pad",				 db9_cd32_btn,	  9,  6,  7,  0,  1 },
++	{ "Multisystem (0.8.0.2) joystick",	 db9_multi_btn,	  1,  1,  2,  1,  1 },
++	{ "Multisystem (0.8.0.2-dual) joystick", db9_multi_btn,	  1,  2,  2,  1,  1 },
++	{ "Amiga CD-32 pad",			 db9_cd32_btn,	  7,  1,  2,  1,  1 },
++	{ "Saturn dpp",				 db9_cd32_btn,	  9,  6,  7,  0,  0 },
++	{ "Saturn dpp dual",			 db9_cd32_btn,	  9,  12, 7,  0,  0 },
++};
+ 
+ /*
+  * Saturn controllers
+@@ -342,7 +358,7 @@ static int db9_saturn(int mode, struct p
+ 	default:
+ 		return -1;
+ 	}
+-	max_pads = min(db9_max_pads[mode], DB9_MAX_DEVICES);
++	max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES);
+ 	for (tmp = 0, i = 0; i < n; i++) {
+ 		id = db9_saturn_read_packet(port, data, type + i, 1);
+ 		tmp = db9_saturn_report(id, data, dev, tmp, max_pads);
+@@ -354,17 +370,18 @@ static void db9_timer(unsigned long priv
+ {
+ 	struct db9 *db9 = (void *) private;
+ 	struct parport *port = db9->pd->port;
+-	struct input_dev *dev = db9->dev;
++	struct input_dev *dev = db9->dev[0];
++	struct input_dev *dev2 = db9->dev[1];
+ 	int data, i;
+ 
+-	switch(db9->mode) {
++	switch (db9->mode) {
+ 		case DB9_MULTI_0802_2:
+ 
+ 			data = parport_read_data(port) >> 3;
+ 
+-			input_report_abs(dev + 1, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+-			input_report_abs(dev + 1, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
+-			input_report_key(dev + 1, BTN_TRIGGER, ~data & DB9_FIRE1);
++			input_report_abs(dev2, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
++			input_report_abs(dev2, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
++			input_report_key(dev2, BTN_TRIGGER, ~data & DB9_FIRE1);
+ 
+ 		case DB9_MULTI_0802:
+ 
+@@ -405,7 +422,7 @@ static void db9_timer(unsigned long priv
+ 			input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
+ 
+ 			parport_write_control(port, DB9_NORMAL);
+-			data=parport_read_data(port);
++			data = parport_read_data(port);
+ 
+ 			input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
+ 			input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
+@@ -414,7 +431,7 @@ static void db9_timer(unsigned long priv
+ 		case DB9_GENESIS5_PAD:
+ 
+ 			parport_write_control(port, DB9_NOSELECT);
+-			data=parport_read_data(port);
++			data = parport_read_data(port);
+ 
+ 			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ 			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
+@@ -422,7 +439,7 @@ static void db9_timer(unsigned long priv
+ 			input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
+ 
+ 			parport_write_control(port, DB9_NORMAL);
+-			data=parport_read_data(port);
++			data = parport_read_data(port);
+ 
+ 			input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
+ 			input_report_key(dev, BTN_X,     ~data & DB9_FIRE2);
+@@ -434,7 +451,7 @@ static void db9_timer(unsigned long priv
+ 
+ 			parport_write_control(port, DB9_NOSELECT); /* 1 */
+ 			udelay(DB9_GENESIS6_DELAY);
+-			data=parport_read_data(port);
++			data = parport_read_data(port);
+ 
+ 			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ 			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
+@@ -443,7 +460,7 @@ static void db9_timer(unsigned long priv
+ 
+ 			parport_write_control(port, DB9_NORMAL);
+ 			udelay(DB9_GENESIS6_DELAY);
+-			data=parport_read_data(port);
++			data = parport_read_data(port);
+ 
+ 			input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
+ 			input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
+@@ -477,7 +494,7 @@ static void db9_timer(unsigned long priv
+ 
+ 		case DB9_CD32_PAD:
+ 
+-			data=parport_read_data(port);
++			data = parport_read_data(port);
+ 
+ 			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ 			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
+@@ -489,7 +506,7 @@ static void db9_timer(unsigned long priv
+ 				parport_write_control(port, 0x02);
+ 				parport_write_control(port, 0x0a);
+ 				input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
+-				}
++			}
+ 
+ 			parport_write_control(port, 0x00);
+ 			break;
+@@ -513,7 +530,7 @@ static int db9_open(struct input_dev *de
+ 	if (!db9->used++) {
+ 		parport_claim(db9->pd);
+ 		parport_write_data(port, 0xff);
+-		if (db9_reverse[db9->mode]) {
++		if (db9_modes[db9->mode].reverse) {
+ 			parport_data_reverse(port);
+ 			parport_write_control(port, DB9_NORMAL);
+ 		}
+@@ -539,117 +556,160 @@ static void db9_close(struct input_dev *
+ 	up(&db9->sem);
+ }
+ 
+-static struct db9 __init *db9_probe(int *config, int nargs)
++static struct db9 __init *db9_probe(int parport, int mode)
+ {
+ 	struct db9 *db9;
++	const struct db9_mode_data *db9_mode;
+ 	struct parport *pp;
++	struct pardevice *pd;
++	struct input_dev *input_dev;
+ 	int i, j;
++	int err;
+ 
+-	if (config[0] < 0)
+-		return NULL;
+-
+-	if (nargs < 2) {
+-		printk(KERN_ERR "db9.c: Device type must be specified.\n");
+-		return NULL;
++	if (mode < 1 || mode >= DB9_MAX_PAD || !db9_modes[mode].n_buttons) {
++		printk(KERN_ERR "db9.c: Bad device type %d\n", mode);
++		err = -EINVAL;
++		goto err_out;
+ 	}
+ 
+-	if (config[1] < 1 || config[1] >= DB9_MAX_PAD || !db9_buttons[config[1]]) {
+-		printk(KERN_ERR "db9.c: bad config\n");
+-		return NULL;
+-	}
++	db9_mode = &db9_modes[mode];
+ 
+-	pp = parport_find_number(config[0]);
++	pp = parport_find_number(parport);
+ 	if (!pp) {
+ 		printk(KERN_ERR "db9.c: no such parport\n");
+-		return NULL;
++		err = -ENODEV;
++		goto err_out;
+ 	}
+ 
+-	if (db9_bidirectional[config[1]]) {
+-		if (!(pp->modes & PARPORT_MODE_TRISTATE)) {
+-			printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
+-			parport_put_port(pp);
+-			return NULL;
+-		}
++	if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) {
++		printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
++		err = -EINVAL;
++		goto err_put_pp;
++	}
++
++	pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
++	if (!pd) {
++		printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
++		err = -EBUSY;
++		goto err_put_pp;
+ 	}
+ 
+-	if (!(db9 = kzalloc(sizeof(struct db9), GFP_KERNEL))) {
+-		parport_put_port(pp);
+-		return NULL;
++	db9 = kzalloc(sizeof(struct db9), GFP_KERNEL);
++	if (!db9) {
++		printk(KERN_ERR "db9.c: Not enough memory\n");
++		err = -ENOMEM;
++		goto err_unreg_pardev;
+ 	}
+ 
+ 	init_MUTEX(&db9->sem);
+-	db9->mode = config[1];
++	db9->pd = pd;
++	db9->mode = mode;
+ 	init_timer(&db9->timer);
+ 	db9->timer.data = (long) db9;
+ 	db9->timer.function = db9_timer;
+ 
+-	db9->pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+-	parport_put_port(pp);
++	for (i = 0; i < (min(db9_mode->n_pads, DB9_MAX_DEVICES)); i++) {
+ 
+-	if (!db9->pd) {
+-		printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
+-		kfree(db9);
+-		return NULL;
+-	}
+-
+-	for (i = 0; i < (min(db9_max_pads[db9->mode], DB9_MAX_DEVICES)); i++) {
++		db9->dev[i] = input_dev = input_allocate_device();
++		if (!input_dev) {
++			printk(KERN_ERR "db9.c: Not enough memory for input device\n");
++			err = -ENOMEM;
++			goto err_free_devs;
++		}
+ 
+ 		sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i);
+ 
+-		db9->dev[i].private = db9;
+-		db9->dev[i].open = db9_open;
+-		db9->dev[i].close = db9_close;
+-
+-		db9->dev[i].name = db9_name[db9->mode];
+-		db9->dev[i].phys = db9->phys[i];
+-		db9->dev[i].id.bustype = BUS_PARPORT;
+-		db9->dev[i].id.vendor = 0x0002;
+-		db9->dev[i].id.product = config[1];
+-		db9->dev[i].id.version = 0x0100;
+-
+-		db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-		for (j = 0; j < db9_buttons[db9->mode]; j++)
+-			set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
+-		for (j = 0; j < db9_num_axis[db9->mode]; j++) {
+-			set_bit(db9_abs[j], db9->dev[i].absbit);
+-			if (j < 2) {
+-				db9->dev[i].absmin[db9_abs[j]] = -1;
+-				db9->dev[i].absmax[db9_abs[j]] = 1;
+-			} else {
+-				db9->dev[i].absmin[db9_abs[j]] = 1;
+-				db9->dev[i].absmax[db9_abs[j]] = 255;
+-				db9->dev[i].absflat[db9_abs[j]] = 0;
+-			}
++		input_dev->name = db9_mode->name;
++		input_dev->phys = db9->phys[i];
++		input_dev->id.bustype = BUS_PARPORT;
++		input_dev->id.vendor = 0x0002;
++		input_dev->id.product = mode;
++		input_dev->id.version = 0x0100;
++		input_dev->private = db9;
++
++		input_dev->open = db9_open;
++		input_dev->close = db9_close;
++
++		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++		for (j = 0; j < db9_mode->n_buttons; j++)
++			set_bit(db9_mode->buttons[j], input_dev->keybit);
++		for (j = 0; j < db9_mode->n_axis; j++) {
++			if (j < 2)
++				input_set_abs_params(input_dev, db9_abs[j], -1, 1, 0, 0);
++			else
++				input_set_abs_params(input_dev, db9_abs[j], 1, 255, 0, 0);
+ 		}
+-		input_register_device(db9->dev + i);
+-		printk(KERN_INFO "input: %s on %s\n", db9->dev[i].name, db9->pd->port->name);
++
++		input_register_device(input_dev);
+ 	}
+ 
++	parport_put_port(pp);
+ 	return db9;
++
++ err_free_devs:
++	while (--i >= 0)
++		input_unregister_device(db9->dev[i]);
++	kfree(db9);
++ err_unreg_pardev:
++	parport_unregister_device(pd);
++ err_put_pp:
++	parport_put_port(pp);
++ err_out:
++	return ERR_PTR(err);
++}
++
++static void __exit db9_remove(struct db9 *db9)
++{
++	int i;
++
++	for (i = 0; i < min(db9_modes[db9->mode].n_pads, DB9_MAX_DEVICES); i++)
++		input_unregister_device(db9->dev[i]);
++	parport_unregister_device(db9->pd);
++	kfree(db9);
+ }
+ 
+ static int __init db9_init(void)
+ {
+-	db9_base[0] = db9_probe(db9, db9_nargs);
+-	db9_base[1] = db9_probe(db9_2, db9_nargs_2);
+-	db9_base[2] = db9_probe(db9_3, db9_nargs_3);
++	int i;
++	int have_dev = 0;
++	int err = 0;
++
++	for (i = 0; i < DB9_MAX_PORTS; i++) {
++		if (db9[i].nargs == 0 || db9[i].args[DB9_ARG_PARPORT] < 0)
++			continue;
++
++		if (db9[i].nargs < 2) {
++			printk(KERN_ERR "db9.c: Device type must be specified.\n");
++			err = -EINVAL;
++			break;
++		}
+ 
+-	if (db9_base[0] || db9_base[1] || db9_base[2])
+-		return 0;
++		db9_base[i] = db9_probe(db9[i].args[DB9_ARG_PARPORT],
++					db9[i].args[DB9_ARG_MODE]);
++		if (IS_ERR(db9_base[i])) {
++			err = PTR_ERR(db9_base[i]);
++			break;
++		}
+ 
+-	return -ENODEV;
++		have_dev = 1;
++	}
++
++	if (err) {
++		while (--i >= 0)
++			db9_remove(db9_base[i]);
++		return err;
++	}
++
++	return have_dev ? 0 : -ENODEV;
+ }
+ 
+ static void __exit db9_exit(void)
+ {
+-	int i, j;
++	int i;
+ 
+-	for (i = 0; i < 3; i++)
+-		if (db9_base[i]) {
+-			for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++)
+-				input_unregister_device(db9_base[i]->dev + j);
+-		parport_unregister_device(db9_base[i]->pd);
+-	}
++	for (i = 0; i < DB9_MAX_PORTS; i++)
++		if (db9_base[i])
++			db9_remove(db9_base[i]);
+ }
+ 
+ module_init(db9_init);
+diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
+--- a/drivers/input/joystick/gamecon.c
++++ b/drivers/input/joystick/gamecon.c
+@@ -41,20 +41,22 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech at u
+ MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
+ MODULE_LICENSE("GPL");
+ 
+-static int gc[] __initdata = { -1, 0, 0, 0, 0, 0 };
+-static int gc_nargs __initdata = 0;
+-module_param_array_named(map, gc, int, &gc_nargs, 0);
+-MODULE_PARM_DESC(map, "Describers first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
+-
+-static int gc_2[] __initdata = { -1, 0, 0, 0, 0, 0 };
+-static int gc_nargs_2 __initdata = 0;
+-module_param_array_named(map2, gc_2, int, &gc_nargs_2, 0);
+-MODULE_PARM_DESC(map2, "Describers second set of devices");
+-
+-static int gc_3[] __initdata = { -1, 0, 0, 0, 0, 0 };
+-static int gc_nargs_3 __initdata = 0;
+-module_param_array_named(map3, gc_3, int, &gc_nargs_3, 0);
+-MODULE_PARM_DESC(map3, "Describers third set of devices");
++#define GC_MAX_PORTS		3
++#define GC_MAX_DEVICES		5
++
++struct gc_config {
++	int args[GC_MAX_DEVICES + 1];
++	int nargs;
++};
++
++static struct gc_config gc[GC_MAX_PORTS] __initdata;
++
++module_param_array_named(map, gc[0].args, int, &gc[0].nargs, 0);
++MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
++module_param_array_named(map2, gc[1].args, int, &gc[1].nargs, 0);
++MODULE_PARM_DESC(map2, "Describes second set of devices");
++module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0);
++MODULE_PARM_DESC(map3, "Describes third set of devices");
+ 
+ __obsolete_setup("gc=");
+ __obsolete_setup("gc_2=");
+@@ -77,12 +79,12 @@ __obsolete_setup("gc_3=");
+ 
+ struct gc {
+ 	struct pardevice *pd;
+-	struct input_dev dev[5];
++	struct input_dev *dev[GC_MAX_DEVICES];
+ 	struct timer_list timer;
+ 	unsigned char pads[GC_MAX + 1];
+ 	int used;
+ 	struct semaphore sem;
+-	char phys[5][32];
++	char phys[GC_MAX_DEVICES][32];
+ };
+ 
+ static struct gc *gc_base[3];
+@@ -330,7 +332,6 @@ static void gc_psx_read_packet(struct gc
+ static void gc_timer(unsigned long private)
+ {
+ 	struct gc *gc = (void *) private;
+-	struct input_dev *dev = gc->dev;
+ 	unsigned char data[GC_MAX_LENGTH];
+ 	unsigned char data_psx[5][GC_PSX_BYTES];
+ 	int i, j, s;
+@@ -357,16 +358,16 @@ static void gc_timer(unsigned long priva
+ 					if (data[31 - j] & s) axes[1] |= 1 << j;
+ 				}
+ 
+-				input_report_abs(dev + i, ABS_X,  axes[0]);
+-				input_report_abs(dev + i, ABS_Y, -axes[1]);
++				input_report_abs(gc->dev[i], ABS_X,  axes[0]);
++				input_report_abs(gc->dev[i], ABS_Y, -axes[1]);
+ 
+-				input_report_abs(dev + i, ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
+-				input_report_abs(dev + i, ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
++				input_report_abs(gc->dev[i], ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
++				input_report_abs(gc->dev[i], ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
+ 
+ 				for (j = 0; j < 10; j++)
+-					input_report_key(dev + i, gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
++					input_report_key(gc->dev[i], gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
+ 
+-				input_sync(dev + i);
++				input_sync(gc->dev[i]);
+ 			}
+ 		}
+ 	}
+@@ -384,19 +385,19 @@ static void gc_timer(unsigned long priva
+ 			s = gc_status_bit[i];
+ 
+ 			if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) {
+-				input_report_abs(dev + i, ABS_X, !(s & data[6]) - !(s & data[7]));
+-				input_report_abs(dev + i, ABS_Y, !(s & data[4]) - !(s & data[5]));
++				input_report_abs(gc->dev[i], ABS_X, !(s & data[6]) - !(s & data[7]));
++				input_report_abs(gc->dev[i], ABS_Y, !(s & data[4]) - !(s & data[5]));
+ 			}
+ 
+ 			if (s & gc->pads[GC_NES])
+ 				for (j = 0; j < 4; j++)
+-					input_report_key(dev + i, gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
++					input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
+ 
+ 			if (s & gc->pads[GC_SNES])
+ 				for (j = 0; j < 8; j++)
+-					input_report_key(dev + i, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
++					input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
+ 
+-			input_sync(dev + i);
++			input_sync(gc->dev[i]);
+ 		}
+ 	}
+ 
+@@ -413,15 +414,15 @@ static void gc_timer(unsigned long priva
+ 			s = gc_status_bit[i];
+ 
+ 			if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) {
+-				input_report_abs(dev + i, ABS_X,  !(s & data[2]) - !(s & data[3]));
+-				input_report_abs(dev + i, ABS_Y,  !(s & data[0]) - !(s & data[1]));
+-				input_report_key(dev + i, BTN_TRIGGER, s & data[4]);
++				input_report_abs(gc->dev[i], ABS_X,  !(s & data[2]) - !(s & data[3]));
++				input_report_abs(gc->dev[i], ABS_Y,  !(s & data[0]) - !(s & data[1]));
++				input_report_key(gc->dev[i], BTN_TRIGGER, s & data[4]);
+ 			}
+ 
+ 			if (s & gc->pads[GC_MULTI2])
+-				input_report_key(dev + i, BTN_THUMB, s & data[5]);
++				input_report_key(gc->dev[i], BTN_THUMB, s & data[5]);
+ 
+-			input_sync(dev + i);
++			input_sync(gc->dev[i]);
+ 		}
+ 	}
+ 
+@@ -438,44 +439,44 @@ static void gc_timer(unsigned long priva
+ 
+ 				case GC_PSX_RUMBLE:
+ 
+-					input_report_key(dev + i, BTN_THUMBL, ~data_psx[i][0] & 0x04);
+-					input_report_key(dev + i, BTN_THUMBR, ~data_psx[i][0] & 0x02);
++					input_report_key(gc->dev[i], BTN_THUMBL, ~data_psx[i][0] & 0x04);
++					input_report_key(gc->dev[i], BTN_THUMBR, ~data_psx[i][0] & 0x02);
+ 
+ 				case GC_PSX_NEGCON:
+ 				case GC_PSX_ANALOG:
+ 
+-					if(gc->pads[GC_DDR] & gc_status_bit[i]) {
++					if (gc->pads[GC_DDR] & gc_status_bit[i]) {
+ 						for(j = 0; j < 4; j++)
+-							input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
++							input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
+ 					} else {
+ 						for (j = 0; j < 4; j++)
+-							input_report_abs(dev + i, gc_psx_abs[j+2], data_psx[i][j + 2]);
++							input_report_abs(gc->dev[i], gc_psx_abs[j+2], data_psx[i][j + 2]);
+ 
+-						input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
+-						input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
++						input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
++						input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
+ 					}
+ 
+ 					for (j = 0; j < 8; j++)
+-						input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
++						input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
+ 
+-					input_report_key(dev + i, BTN_START,  ~data_psx[i][0] & 0x08);
+-					input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
++					input_report_key(gc->dev[i], BTN_START,  ~data_psx[i][0] & 0x08);
++					input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
+ 
+-					input_sync(dev + i);
++					input_sync(gc->dev[i]);
+ 
+ 					break;
+ 
+ 				case GC_PSX_NORMAL:
+-					if(gc->pads[GC_DDR] & gc_status_bit[i]) {
++					if (gc->pads[GC_DDR] & gc_status_bit[i]) {
+ 						for(j = 0; j < 4; j++)
+-							input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
++							input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
+ 					} else {
+-						input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
+-						input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
++						input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
++						input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
+ 
+ 						/* for some reason if the extra axes are left unset they drift */
+ 						/* for (j = 0; j < 4; j++)
+-							input_report_abs(dev + i, gc_psx_abs[j+2], 128);
++							input_report_abs(gc->dev[i], gc_psx_abs[j+2], 128);
+ 						 * This needs to be debugged properly,
+ 						 * maybe fuzz processing needs to be done in input_sync()
+ 						 *				 --vojtech
+@@ -483,12 +484,12 @@ static void gc_timer(unsigned long priva
+ 					}
+ 
+ 					for (j = 0; j < 8; j++)
+-						input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
++						input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
+ 
+-					input_report_key(dev + i, BTN_START,  ~data_psx[i][0] & 0x08);
+-					input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
++					input_report_key(gc->dev[i], BTN_START,  ~data_psx[i][0] & 0x08);
++					input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
+ 
+-					input_sync(dev + i);
++					input_sync(gc->dev[i]);
+ 
+ 					break;
+ 
+@@ -533,177 +534,212 @@ static void gc_close(struct input_dev *d
+ 	up(&gc->sem);
+ }
+ 
+-static struct gc __init *gc_probe(int *config, int nargs)
++static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
+ {
+-	struct gc *gc;
+-	struct parport *pp;
+-	int i, j;
+-
+-	if (config[0] < 0)
+-		return NULL;
+-
+-	if (nargs < 2) {
+-		printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
+-		return NULL;
+-	}
++	struct input_dev *input_dev;
++	int i;
+ 
+-	pp = parport_find_number(config[0]);
++	if (!pad_type)
++		return 0;
+ 
+-	if (!pp) {
+-		printk(KERN_ERR "gamecon.c: no such parport\n");
+-		return NULL;
++	if (pad_type < 1 || pad_type > GC_MAX) {
++		printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type);
++		return -EINVAL;
+ 	}
+ 
+-	if (!(gc = kzalloc(sizeof(struct gc), GFP_KERNEL))) {
+-		parport_put_port(pp);
+-		return NULL;
++	gc->dev[idx] = input_dev = input_allocate_device();
++	if (!input_dev) {
++		printk(KERN_ERR "gamecon.c: Not enough memory for input device\n");
++		return -ENOMEM;
+ 	}
+ 
+-	init_MUTEX(&gc->sem);
++	input_dev->name = gc_names[pad_type];
++	input_dev->phys = gc->phys[idx];
++	input_dev->id.bustype = BUS_PARPORT;
++	input_dev->id.vendor = 0x0001;
++	input_dev->id.product = pad_type;
++	input_dev->id.version = 0x0100;
++	input_dev->private = gc;
+ 
+-	gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
++	input_dev->open = gc_open;
++	input_dev->close = gc_close;
+ 
+-	parport_put_port(pp);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+-	if (!gc->pd) {
+-		printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
+-		kfree(gc);
+-		return NULL;
+-	}
++	for (i = 0; i < 2; i++)
++		input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
+ 
+-	parport_claim(gc->pd);
++	gc->pads[0] |= gc_status_bit[idx];
++	gc->pads[pad_type] |= gc_status_bit[idx];
+ 
+-	init_timer(&gc->timer);
+-	gc->timer.data = (long) gc;
+-	gc->timer.function = gc_timer;
++	switch (pad_type) {
+ 
+-	for (i = 0; i < nargs - 1; i++) {
++		case GC_N64:
++			for (i = 0; i < 10; i++)
++				set_bit(gc_n64_btn[i], input_dev->keybit);
+ 
+-		if (!config[i + 1])
+-			continue;
+-
+-		if (config[i + 1] < 1 || config[i + 1] > GC_MAX) {
+-			printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", config[i + 1]);
+-			continue;
+-		}
++			for (i = 0; i < 2; i++) {
++				input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2);
++				input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
++			}
+ 
+-                gc->dev[i].private = gc;
+-                gc->dev[i].open = gc_open;
+-                gc->dev[i].close = gc_close;
+-
+-                gc->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-
+-		for (j = 0; j < 2; j++) {
+-			set_bit(ABS_X + j, gc->dev[i].absbit);
+-			gc->dev[i].absmin[ABS_X + j] = -1;
+-			gc->dev[i].absmax[ABS_X + j] =  1;
+-		}
++			break;
+ 
+-		gc->pads[0] |= gc_status_bit[i];
+-		gc->pads[config[i + 1]] |= gc_status_bit[i];
++		case GC_SNES:
++			for (i = 4; i < 8; i++)
++				set_bit(gc_snes_btn[i], input_dev->keybit);
++		case GC_NES:
++			for (i = 0; i < 4; i++)
++				set_bit(gc_snes_btn[i], input_dev->keybit);
++			break;
++
++		case GC_MULTI2:
++			set_bit(BTN_THUMB, input_dev->keybit);
++		case GC_MULTI:
++			set_bit(BTN_TRIGGER, input_dev->keybit);
++			break;
++
++		case GC_PSX:
++			for (i = 0; i < 6; i++)
++				input_set_abs_params(input_dev, gc_psx_abs[i], 4, 252, 0, 2);
++			for (i = 0; i < 12; i++)
++				set_bit(gc_psx_btn[i], input_dev->keybit);
++
++			break;
++
++		case GC_DDR:
++			for (i = 0; i < 4; i++)
++				set_bit(gc_psx_ddr_btn[i], input_dev->keybit);
++			for (i = 0; i < 12; i++)
++				set_bit(gc_psx_btn[i], input_dev->keybit);
+ 
+-		switch(config[i + 1]) {
++			break;
++	}
+ 
+-			case GC_N64:
+-				for (j = 0; j < 10; j++)
+-					set_bit(gc_n64_btn[j], gc->dev[i].keybit);
++	return 0;
++}
+ 
+-				for (j = 0; j < 2; j++) {
+-					set_bit(ABS_X + j, gc->dev[i].absbit);
+-					gc->dev[i].absmin[ABS_X + j] = -127;
+-					gc->dev[i].absmax[ABS_X + j] =  126;
+-					gc->dev[i].absflat[ABS_X + j] = 2;
+-					set_bit(ABS_HAT0X + j, gc->dev[i].absbit);
+-					gc->dev[i].absmin[ABS_HAT0X + j] = -1;
+-					gc->dev[i].absmax[ABS_HAT0X + j] =  1;
+-				}
++static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
++{
++	struct gc *gc;
++	struct parport *pp;
++	struct pardevice *pd;
++	int i;
++	int err;
+ 
+-				break;
++	pp = parport_find_number(parport);
++	if (!pp) {
++		printk(KERN_ERR "gamecon.c: no such parport\n");
++		err = -EINVAL;
++		goto err_out;
++	}
+ 
+-			case GC_SNES:
+-				for (j = 4; j < 8; j++)
+-					set_bit(gc_snes_btn[j], gc->dev[i].keybit);
+-			case GC_NES:
+-				for (j = 0; j < 4; j++)
+-					set_bit(gc_snes_btn[j], gc->dev[i].keybit);
+-				break;
++	pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
++	if (!pd) {
++		printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
++		err = -EBUSY;
++		goto err_put_pp;
++	}
+ 
+-			case GC_MULTI2:
+-				set_bit(BTN_THUMB, gc->dev[i].keybit);
+-			case GC_MULTI:
+-				set_bit(BTN_TRIGGER, gc->dev[i].keybit);
+-				break;
+-
+-			case GC_PSX:
+-			case GC_DDR:
+-				if(config[i + 1] == GC_DDR) {
+-					for (j = 0; j < 4; j++)
+-						set_bit(gc_psx_ddr_btn[j], gc->dev[i].keybit);
+-				} else {
+-					for (j = 0; j < 6; j++) {
+-						set_bit(gc_psx_abs[j], gc->dev[i].absbit);
+-						gc->dev[i].absmin[gc_psx_abs[j]] = 4;
+-						gc->dev[i].absmax[gc_psx_abs[j]] = 252;
+-						gc->dev[i].absflat[gc_psx_abs[j]] = 2;
+-					}
+-				}
++	gc = kzalloc(sizeof(struct gc), GFP_KERNEL);
++	if (!gc) {
++		printk(KERN_ERR "gamecon.c: Not enough memory\n");
++		err = -ENOMEM;
++		goto err_unreg_pardev;
++	}
+ 
+-				for (j = 0; j < 12; j++)
+-					set_bit(gc_psx_btn[j], gc->dev[i].keybit);
++	init_MUTEX(&gc->sem);
++	gc->pd = pd;
++	init_timer(&gc->timer);
++	gc->timer.data = (long) gc;
++	gc->timer.function = gc_timer;
+ 
+-				break;
+-		}
++	for (i = 0; i < n_pads; i++) {
++		if (!pads[i])
++			continue;
+ 
+ 		sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
++		err = gc_setup_pad(gc, i, pads[i]);
++		if (err)
++			goto err_free_devs;
+ 
+-                gc->dev[i].name = gc_names[config[i + 1]];
+-		gc->dev[i].phys = gc->phys[i];
+-                gc->dev[i].id.bustype = BUS_PARPORT;
+-                gc->dev[i].id.vendor = 0x0001;
+-                gc->dev[i].id.product = config[i + 1];
+-                gc->dev[i].id.version = 0x0100;
++		input_register_device(gc->dev[i]);
+ 	}
+ 
+-	parport_release(gc->pd);
+-
+ 	if (!gc->pads[0]) {
+-		parport_unregister_device(gc->pd);
+-		kfree(gc);
+-		return NULL;
++		printk(KERN_ERR "gamecon.c: No valid devices specified\n");
++		err = -EINVAL;
++		goto err_free_gc;
+ 	}
+ 
+-	for (i = 0; i < 5; i++)
+-		if (gc->pads[0] & gc_status_bit[i]) {
+-			input_register_device(gc->dev + i);
+-			printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name);
+-		}
+-
++	parport_put_port(pp);
+ 	return gc;
++
++ err_free_devs:
++	while (--i >= 0)
++		input_unregister_device(gc->dev[i]);
++ err_free_gc:
++	kfree(gc);
++ err_unreg_pardev:
++	parport_unregister_device(pd);
++ err_put_pp:
++	parport_put_port(pp);
++ err_out:
++	return ERR_PTR(err);
++}
++
++static void __exit gc_remove(struct gc *gc)
++{
++	int i;
++
++	for (i = 0; i < GC_MAX_DEVICES; i++)
++		if (gc->dev[i])
++			input_unregister_device(gc->dev[i]);
++	parport_unregister_device(gc->pd);
++	kfree(gc);
+ }
+ 
+ static int __init gc_init(void)
+ {
+-	gc_base[0] = gc_probe(gc, gc_nargs);
+-	gc_base[1] = gc_probe(gc_2, gc_nargs_2);
+-	gc_base[2] = gc_probe(gc_3, gc_nargs_3);
++	int i;
++	int have_dev = 0;
++	int err = 0;
+ 
+-	if (gc_base[0] || gc_base[1] || gc_base[2])
+-		return 0;
++	for (i = 0; i < GC_MAX_PORTS; i++) {
++		if (gc[i].nargs == 0 || gc[i].args[0] < 0)
++			continue;
++
++		if (gc[i].nargs < 2) {
++			printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
++			err = -EINVAL;
++			break;
++		}
+ 
+-	return -ENODEV;
++		gc_base[i] = gc_probe(gc[i].args[0], gc[i].args + 1, gc[i].nargs - 1);
++		if (IS_ERR(gc_base[i])) {
++			err = PTR_ERR(gc_base[i]);
++			break;
++		}
++
++		have_dev = 1;
++	}
++
++	if (err) {
++		while (--i >= 0)
++			gc_remove(gc_base[i]);
++		return err;
++	}
++
++	return have_dev ? 0 : -ENODEV;
+ }
+ 
+ static void __exit gc_exit(void)
+ {
+-	int i, j;
++	int i;
+ 
+-	for (i = 0; i < 3; i++)
+-		if (gc_base[i]) {
+-			for (j = 0; j < 5; j++)
+-				if (gc_base[i]->pads[0] & gc_status_bit[j])
+-					input_unregister_device(gc_base[i]->dev + j);
+-			parport_unregister_device(gc_base[i]->pd);
+-		}
++	for (i = 0; i < GC_MAX_PORTS; i++)
++		if (gc_base[i])
++			gc_remove(gc_base[i]);
+ }
+ 
+ module_init(gc_init);
+diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
+--- a/drivers/input/joystick/gf2k.c
++++ b/drivers/input/joystick/gf2k.c
+@@ -35,6 +35,7 @@
+ #include <linux/init.h>
+ #include <linux/input.h>
+ #include <linux/gameport.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"Genius Flight 2000 joystick driver"
+ 
+@@ -81,7 +82,7 @@ static short gf2k_seq_digital[] = { 590,
+ 
+ struct gf2k {
+ 	struct gameport *gameport;
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	int reads;
+ 	int bads;
+ 	unsigned char id;
+@@ -175,7 +176,7 @@ static int gf2k_get_bits(unsigned char *
+ 
+ static void gf2k_read(struct gf2k *gf2k, unsigned char *data)
+ {
+-	struct input_dev *dev = &gf2k->dev;
++	struct input_dev *dev = gf2k->dev;
+ 	int i, t;
+ 
+ 	for (i = 0; i < 4 && i < gf2k_axes[gf2k->id]; i++)
+@@ -239,13 +240,19 @@ static void gf2k_close(struct input_dev 
+ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
+ {
+ 	struct gf2k *gf2k;
++	struct input_dev *input_dev;
+ 	unsigned char data[GF2K_LENGTH];
+ 	int i, err;
+ 
+-	if (!(gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL)))
+-		return -ENOMEM;
++	gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!gf2k || !input_dev) {
++		err = -ENOMEM;
++		goto fail1;
++	}
+ 
+ 	gf2k->gameport = gameport;
++	gf2k->dev = input_dev;
+ 
+ 	gameport_set_drvdata(gameport, gf2k);
+ 
+@@ -295,53 +302,52 @@ static int gf2k_connect(struct gameport 
+ 
+ 	gf2k->length = gf2k_lens[gf2k->id];
+ 
+-	init_input_dev(&gf2k->dev);
+-
+-	gf2k->dev.private = gf2k;
+-	gf2k->dev.open = gf2k_open;
+-	gf2k->dev.close = gf2k_close;
+-	gf2k->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-
+-	gf2k->dev.name = gf2k_names[gf2k->id];
+-	gf2k->dev.phys = gf2k->phys;
+-	gf2k->dev.id.bustype = BUS_GAMEPORT;
+-	gf2k->dev.id.vendor = GAMEPORT_ID_VENDOR_GENIUS;
+-	gf2k->dev.id.product = gf2k->id;
+-	gf2k->dev.id.version = 0x0100;
++	input_dev->name = gf2k_names[gf2k->id];
++	input_dev->phys = gf2k->phys;
++	input_dev->id.bustype = BUS_GAMEPORT;
++	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS;
++	input_dev->id.product = gf2k->id;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &gameport->dev;
++	input_dev->private = gf2k;
++
++	input_dev->open = gf2k_open;
++	input_dev->close = gf2k_close;
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+ 	for (i = 0; i < gf2k_axes[gf2k->id]; i++)
+-		set_bit(gf2k_abs[i], gf2k->dev.absbit);
++		set_bit(gf2k_abs[i], input_dev->absbit);
+ 
+ 	for (i = 0; i < gf2k_hats[gf2k->id]; i++) {
+-		set_bit(ABS_HAT0X + i, gf2k->dev.absbit);
+-		gf2k->dev.absmin[ABS_HAT0X + i] = -1;
+-		gf2k->dev.absmax[ABS_HAT0X + i] = 1;
++		set_bit(ABS_HAT0X + i, input_dev->absbit);
++		input_dev->absmin[ABS_HAT0X + i] = -1;
++		input_dev->absmax[ABS_HAT0X + i] = 1;
+ 	}
+ 
+ 	for (i = 0; i < gf2k_joys[gf2k->id]; i++)
+-		set_bit(gf2k_btn_joy[i], gf2k->dev.keybit);
++		set_bit(gf2k_btn_joy[i], input_dev->keybit);
+ 
+ 	for (i = 0; i < gf2k_pads[gf2k->id]; i++)
+-		set_bit(gf2k_btn_pad[i], gf2k->dev.keybit);
++		set_bit(gf2k_btn_pad[i], input_dev->keybit);
+ 
+ 	gf2k_read_packet(gameport, gf2k->length, data);
+ 	gf2k_read(gf2k, data);
+ 
+ 	for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
+-		gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 :
+-			  gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
+-		gf2k->dev.absmin[gf2k_abs[i]] = 32;
+-		gf2k->dev.absfuzz[gf2k_abs[i]] = 8;
+-		gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
++		input_dev->absmax[gf2k_abs[i]] = (i < 2) ? input_dev->abs[gf2k_abs[i]] * 2 - 32 :
++			  input_dev->abs[gf2k_abs[0]] + input_dev->abs[gf2k_abs[1]] - 32;
++		input_dev->absmin[gf2k_abs[i]] = 32;
++		input_dev->absfuzz[gf2k_abs[i]] = 8;
++		input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
+ 	}
+ 
+-	input_register_device(&gf2k->dev);
+-	printk(KERN_INFO "input: %s on %s\n", gf2k_names[gf2k->id], gameport->phys);
++	input_register_device(gf2k->dev);
+ 
+ 	return 0;
+ 
+-fail2:	gameport_close(gameport);
+-fail1:	gameport_set_drvdata(gameport, NULL);
++ fail2:	gameport_close(gameport);
++ fail1:	gameport_set_drvdata(gameport, NULL);
++	input_free_device(input_dev);
+ 	kfree(gf2k);
+ 	return err;
+ }
+@@ -350,7 +356,7 @@ static void gf2k_disconnect(struct gamep
+ {
+ 	struct gf2k *gf2k = gameport_get_drvdata(gameport);
+ 
+-	input_unregister_device(&gf2k->dev);
++	input_unregister_device(gf2k->dev);
+ 	gameport_close(gameport);
+ 	gameport_set_drvdata(gameport, NULL);
+ 	kfree(gf2k);
+diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
+--- a/drivers/input/joystick/grip.c
++++ b/drivers/input/joystick/grip.c
+@@ -34,6 +34,7 @@
+ #include <linux/slab.h>
+ #include <linux/gameport.h>
+ #include <linux/input.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"Gravis GrIP protocol joystick driver"
+ 
+@@ -55,7 +56,7 @@ MODULE_LICENSE("GPL");
+ 
+ struct grip {
+ 	struct gameport *gameport;
+-	struct input_dev dev[2];
++	struct input_dev *dev[2];
+ 	unsigned char mode[2];
+ 	int reads;
+ 	int bads;
+@@ -190,7 +191,7 @@ static void grip_poll(struct gameport *g
+ 
+ 	for (i = 0; i < 2; i++) {
+ 
+-		dev = grip->dev + i;
++		dev = grip->dev[i];
+ 		grip->reads++;
+ 
+ 		switch (grip->mode[i]) {
+@@ -297,6 +298,7 @@ static void grip_close(struct input_dev 
+ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
+ {
+ 	struct grip *grip;
++	struct input_dev *input_dev;
+ 	unsigned int data[GRIP_LENGTH_XT];
+ 	int i, j, t;
+ 	int err;
+@@ -339,48 +341,56 @@ static int grip_connect(struct gameport 
+ 	gameport_set_poll_handler(gameport, grip_poll);
+ 	gameport_set_poll_interval(gameport, 20);
+ 
+-	for (i = 0; i < 2; i++)
+-		if (grip->mode[i]) {
+-
+-			sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
+-
+-			grip->dev[i].private = grip;
+-
+-			grip->dev[i].open = grip_open;
+-			grip->dev[i].close = grip_close;
++	for (i = 0; i < 2; i++) {
++		if (!grip->mode[i])
++			continue;
+ 
+-			grip->dev[i].name = grip_name[grip->mode[i]];
+-			grip->dev[i].phys = grip->phys[i];
+-			grip->dev[i].id.bustype = BUS_GAMEPORT;
+-			grip->dev[i].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
+-			grip->dev[i].id.product = grip->mode[i];
+-			grip->dev[i].id.version = 0x0100;
++		grip->dev[i] = input_dev = input_allocate_device();
++		if (!input_dev) {
++			err = -ENOMEM;
++			goto fail3;
++		}
+ 
+-			grip->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++		sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
+ 
+-			for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
++		input_dev->name = grip_name[grip->mode[i]];
++		input_dev->phys = grip->phys[i];
++		input_dev->id.bustype = BUS_GAMEPORT;
++		input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
++		input_dev->id.product = grip->mode[i];
++		input_dev->id.version = 0x0100;
++		input_dev->cdev.dev = &gameport->dev;
++		input_dev->private = grip;
++
++		input_dev->open = grip_open;
++		input_dev->close = grip_close;
++
++		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++
++		for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
++
++			if (j < grip_cen[grip->mode[i]])
++				input_set_abs_params(input_dev, t, 14, 52, 1, 2);
++			else if (j < grip_anx[grip->mode[i]])
++				input_set_abs_params(input_dev, t, 3, 57, 1, 0);
++			else
++				input_set_abs_params(input_dev, t, -1, 1, 0, 0);
++		}
+ 
+-				if (j < grip_cen[grip->mode[i]])
+-					input_set_abs_params(&grip->dev[i], t, 14, 52, 1, 2);
+-				else if (j < grip_anx[grip->mode[i]])
+-					input_set_abs_params(&grip->dev[i], t, 3, 57, 1, 0);
+-				else
+-					input_set_abs_params(&grip->dev[i], t, -1, 1, 0, 0);
+-			}
++		for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
++			if (t > 0)
++				set_bit(t, input_dev->keybit);
+ 
+-			for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
+-				if (t > 0)
+-					set_bit(t, grip->dev[i].keybit);
+-
+-			printk(KERN_INFO "input: %s on %s\n",
+-				grip_name[grip->mode[i]], gameport->phys);
+-			input_register_device(grip->dev + i);
+-		}
++		input_register_device(grip->dev[i]);
++	}
+ 
+ 	return 0;
+ 
+-fail2:	gameport_close(gameport);
+-fail1:	gameport_set_drvdata(gameport, NULL);
++ fail3: for (i = 0; i < 2; i++)
++		if (grip->dev[i])
++			input_unregister_device(grip->dev[i]);
++ fail2:	gameport_close(gameport);
++ fail1:	gameport_set_drvdata(gameport, NULL);
+ 	kfree(grip);
+ 	return err;
+ }
+@@ -391,8 +401,8 @@ static void grip_disconnect(struct gamep
+ 	int i;
+ 
+ 	for (i = 0; i < 2; i++)
+-		if (grip->mode[i])
+-			input_unregister_device(grip->dev + i);
++		if (grip->dev[i])
++			input_unregister_device(grip->dev[i]);
+ 	gameport_close(gameport);
+ 	gameport_set_drvdata(gameport, NULL);
+ 	kfree(grip);
+diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
+--- a/drivers/input/joystick/grip_mp.c
++++ b/drivers/input/joystick/grip_mp.c
+@@ -19,6 +19,7 @@
+ #include <linux/input.h>
+ #include <linux/delay.h>
+ #include <linux/proc_fs.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"Gravis Grip Multiport driver"
+ 
+@@ -32,23 +33,37 @@ MODULE_LICENSE("GPL");
+ #define dbg(format, arg...) do {} while (0)
+ #endif
+ 
++#define GRIP_MAX_PORTS	4
+ /*
+  * Grip multiport state
+  */
+ 
++struct grip_port {
++	struct input_dev *dev;
++	int mode;
++	int registered;
++
++	/* individual gamepad states */
++	int buttons;
++	int xaxes;
++	int yaxes;
++	int dirty;     /* has the state been updated? */
++};
++
+ struct grip_mp {
+ 	struct gameport *gameport;
+-	struct input_dev dev[4];
+-	int mode[4];
+-	int registered[4];
++	struct grip_port *port[GRIP_MAX_PORTS];
++//	struct input_dev *dev[4];
++//	int mode[4];
++//	int registered[4];
+ 	int reads;
+ 	int bads;
+ 
+ 	/* individual gamepad states */
+-	int buttons[4];
+-	int xaxes[4];
+-	int yaxes[4];
+-	int dirty[4];     /* has the state been updated? */
++//	int buttons[4];
++//	int xaxes[4];
++//	int yaxes[4];
++//	int dirty[4];     /* has the state been updated? */
+ };
+ 
+ /*
+@@ -85,16 +100,16 @@ struct grip_mp {
+ #define GRIP_MODE_GP		2
+ #define GRIP_MODE_C64		3
+ 
+-static int grip_btn_gp[]  = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
+-static int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
++static const int grip_btn_gp[]  = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
++static const int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
+ 
+-static int grip_abs_gp[]  = { ABS_X, ABS_Y, -1 };
+-static int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
++static const int grip_abs_gp[]  = { ABS_X, ABS_Y, -1 };
++static const int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
+ 
+-static int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
+-static int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
++static const int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
++static const int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
+ 
+-static char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
++static const char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
+ 
+ static const int init_seq[] = {
+ 	1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+@@ -104,9 +119,9 @@ static const int init_seq[] = {
+ 
+ /* Maps multiport directional values to X,Y axis values (each axis encoded in 3 bits) */
+ 
+-static int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
++static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
+ 
+-static void register_slot(int i, struct grip_mp *grip);
++static int register_slot(int i, struct grip_mp *grip);
+ 
+ /*
+  * Returns whether an odd or even number of bits are on in pkt.
+@@ -353,9 +368,10 @@ static int dig_mode_start(struct gamepor
+ 
+ static int get_and_decode_packet(struct grip_mp *grip, int flags)
+ {
++	struct grip_port *port;
+ 	u32 packet;
+ 	int joytype = 0;
+-	int slot = 0;
++	int slot;
+ 
+ 	/* Get a packet and check for validity */
+ 
+@@ -377,6 +393,8 @@ static int get_and_decode_packet(struct 
+ 	if ((slot < 0) || (slot > 3))
+ 		return flags;
+ 
++	port = grip->port[slot];
++
+ 	/*
+ 	 * Handle "reset" packets, which occur at startup, and when gamepads
+ 	 * are removed or plugged in.  May contain configuration of a new gamepad.
+@@ -385,14 +403,14 @@ static int get_and_decode_packet(struct 
+ 	joytype = (packet >> 16) & 0x1f;
+ 	if (!joytype) {
+ 
+-		if (grip->registered[slot]) {
++		if (port->registered) {
+ 			printk(KERN_INFO "grip_mp: removing %s, slot %d\n",
+-			       grip_name[grip->mode[slot]], slot);
+-			input_unregister_device(grip->dev + slot);
+-			grip->registered[slot] = 0;
++			       grip_name[port->mode], slot);
++			input_unregister_device(port->dev);
++			port->registered = 0;
+ 		}
+ 		dbg("Reset: grip multiport slot %d\n", slot);
+-		grip->mode[slot] = GRIP_MODE_RESET;
++		port->mode = GRIP_MODE_RESET;
+ 		flags |= IO_SLOT_CHANGE;
+ 		return flags;
+ 	}
+@@ -402,17 +420,17 @@ static int get_and_decode_packet(struct 
+ 	if (joytype == 0x1f) {
+ 
+ 		int dir = (packet >> 8) & 0xf;          /* eight way directional value */
+-		grip->buttons[slot] = (~packet) & 0xff;
+-		grip->yaxes[slot] = ((axis_map[dir] >> 2) & 3) - 1;
+-		grip->xaxes[slot] = (axis_map[dir] & 3) - 1;
+-		grip->dirty[slot] = 1;
++		port->buttons = (~packet) & 0xff;
++		port->yaxes = ((axis_map[dir] >> 2) & 3) - 1;
++		port->xaxes = (axis_map[dir] & 3) - 1;
++		port->dirty = 1;
+ 
+-		if (grip->mode[slot] == GRIP_MODE_RESET)
++		if (port->mode == GRIP_MODE_RESET)
+ 			flags |= IO_SLOT_CHANGE;
+ 
+-		grip->mode[slot] = GRIP_MODE_GP;
++		port->mode = GRIP_MODE_GP;
+ 
+-		if (!grip->registered[slot]) {
++		if (!port->registered) {
+ 			dbg("New Grip pad in multiport slot %d.\n", slot);
+ 			register_slot(slot, grip);
+ 		}
+@@ -445,9 +463,9 @@ static int slots_valid(struct grip_mp *g
+ 		return 0;
+ 
+ 	for (slot = 0; slot < 4; slot++) {
+-		if (grip->mode[slot] == GRIP_MODE_RESET)
++		if (grip->port[slot]->mode == GRIP_MODE_RESET)
+ 			invalid = 1;
+-		if (grip->mode[slot] != GRIP_MODE_NONE)
++		if (grip->port[slot]->mode != GRIP_MODE_NONE)
+ 			active = 1;
+ 	}
+ 
+@@ -484,7 +502,7 @@ static int multiport_init(struct grip_mp
+ 
+ 	/* Get packets, store multiport state, and check state's validity */
+ 	for (tries = 0; tries < 4096; tries++) {
+-		if ( slots_valid(grip) ) {
++		if (slots_valid(grip)) {
+ 			initialized = 1;
+ 			break;
+ 		}
+@@ -499,24 +517,24 @@ static int multiport_init(struct grip_mp
+ 
+ static void report_slot(struct grip_mp *grip, int slot)
+ {
+-	struct input_dev *dev = &(grip->dev[slot]);
+-	int i, buttons = grip->buttons[slot];
++	struct grip_port *port = grip->port[slot];
++	int i;
+ 
+ 	/* Store button states with linux input driver */
+ 
+ 	for (i = 0; i < 8; i++)
+-		input_report_key(dev, grip_btn_gp[i], (buttons >> i) & 1);
++		input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1);
+ 
+ 	/* Store axis states with linux driver */
+ 
+-	input_report_abs(dev, ABS_X, grip->xaxes[slot]);
+-	input_report_abs(dev, ABS_Y, grip->yaxes[slot]);
++	input_report_abs(port->dev, ABS_X, port->xaxes);
++	input_report_abs(port->dev, ABS_Y, port->yaxes);
+ 
+ 	/* Tell the receiver of the events to process them */
+ 
+-	input_sync(dev);
++	input_sync(port->dev);
+ 
+-	grip->dirty[slot] = 0;
++	port->dirty = 0;
+ }
+ 
+ /*
+@@ -540,7 +558,7 @@ static void grip_poll(struct gameport *g
+ 	}
+ 
+ 	for (i = 0; i < 4; i++)
+-		if (grip->dirty[i])
++		if (grip->port[i]->dirty)
+ 			report_slot(grip, i);
+ }
+ 
+@@ -571,35 +589,43 @@ static void grip_close(struct input_dev 
+  * Tell the linux input layer about a newly plugged-in gamepad.
+  */
+ 
+-static void register_slot(int slot, struct grip_mp *grip)
++static int register_slot(int slot, struct grip_mp *grip)
+ {
++	struct grip_port *port = grip->port[slot];
++	struct input_dev *input_dev;
+ 	int j, t;
+ 
+-	grip->dev[slot].private = grip;
+-	grip->dev[slot].open = grip_open;
+-	grip->dev[slot].close = grip_close;
+-	grip->dev[slot].name = grip_name[grip->mode[slot]];
+-	grip->dev[slot].id.bustype = BUS_GAMEPORT;
+-	grip->dev[slot].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
+-	grip->dev[slot].id.product = 0x0100 + grip->mode[slot];
+-	grip->dev[slot].id.version = 0x0100;
+-	grip->dev[slot].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	port->dev = input_dev = input_allocate_device();
++	if (!input_dev)
++		return -ENOMEM;
++
++	input_dev->name = grip_name[port->mode];
++	input_dev->id.bustype = BUS_GAMEPORT;
++	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
++	input_dev->id.product = 0x0100 + port->mode;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &grip->gameport->dev;
++	input_dev->private = grip;
++
++	input_dev->open = grip_open;
++	input_dev->close = grip_close;
+ 
+-	for (j = 0; (t = grip_abs[grip->mode[slot]][j]) >= 0; j++)
+-		input_set_abs_params(&grip->dev[slot], t, -1, 1, 0, 0);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+-	for (j = 0; (t = grip_btn[grip->mode[slot]][j]) >= 0; j++)
++	for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
++		input_set_abs_params(input_dev, t, -1, 1, 0, 0);
++
++	for (j = 0; (t = grip_btn[port->mode][j]) >= 0; j++)
+ 		if (t > 0)
+-			set_bit(t, grip->dev[slot].keybit);
++			set_bit(t, input_dev->keybit);
+ 
+-	input_register_device(grip->dev + slot);
+-	grip->registered[slot] = 1;
++	input_register_device(port->dev);
++	port->registered = 1;
+ 
+-	if (grip->dirty[slot])	            /* report initial state, if any */
++	if (port->dirty)	            /* report initial state, if any */
+ 		report_slot(grip, slot);
+ 
+-	printk(KERN_INFO "grip_mp: added %s, slot %d\n",
+-	       grip_name[grip->mode[slot]], slot);
++	return 0;
+ }
+ 
+ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
+@@ -626,7 +652,7 @@ static int grip_connect(struct gameport 
+ 		goto fail2;
+ 	}
+ 
+-	if (!grip->mode[0] && !grip->mode[1] && !grip->mode[2] && !grip->mode[3]) {
++	if (!grip->port[0]->mode && !grip->port[1]->mode && !grip->port[2]->mode && !grip->port[3]->mode) {
+ 		/* nothing plugged in */
+ 		err = -ENODEV;
+ 		goto fail2;
+@@ -646,8 +672,8 @@ static void grip_disconnect(struct gamep
+ 	int i;
+ 
+ 	for (i = 0; i < 4; i++)
+-		if (grip->registered[i])
+-			input_unregister_device(grip->dev + i);
++		if (grip->port[i]->registered)
++			input_unregister_device(grip->port[i]->dev);
+ 	gameport_close(gameport);
+ 	gameport_set_drvdata(gameport, NULL);
+ 	kfree(grip);
+diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
+--- a/drivers/input/joystick/guillemot.c
++++ b/drivers/input/joystick/guillemot.c
+@@ -35,6 +35,7 @@
+ #include <linux/init.h>
+ #include <linux/gameport.h>
+ #include <linux/input.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"Guillemot Digital joystick driver"
+ 
+@@ -67,7 +68,7 @@ struct guillemot_type {
+ 
+ struct guillemot {
+ 	struct gameport *gameport;
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	int bads;
+ 	int reads;
+ 	struct guillemot_type *type;
+@@ -123,7 +124,7 @@ static int guillemot_read_packet(struct 
+ static void guillemot_poll(struct gameport *gameport)
+ {
+ 	struct guillemot *guillemot = gameport_get_drvdata(gameport);
+-	struct input_dev *dev = &guillemot->dev;
++	struct input_dev *dev = guillemot->dev;
+ 	u8 data[GUILLEMOT_MAX_LENGTH];
+ 	int i;
+ 
+@@ -179,14 +180,20 @@ static void guillemot_close(struct input
+ static int guillemot_connect(struct gameport *gameport, struct gameport_driver *drv)
+ {
+ 	struct guillemot *guillemot;
++	struct input_dev *input_dev;
+ 	u8 data[GUILLEMOT_MAX_LENGTH];
+ 	int i, t;
+ 	int err;
+ 
+-	if (!(guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL)))
+-		return -ENOMEM;
++	guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!guillemot || !input_dev) {
++		err = -ENOMEM;
++		goto fail1;
++	}
+ 
+ 	guillemot->gameport = gameport;
++	guillemot->dev = input_dev;
+ 
+ 	gameport_set_drvdata(gameport, guillemot);
+ 
+@@ -216,41 +223,40 @@ static int guillemot_connect(struct game
+ 	gameport_set_poll_interval(gameport, 20);
+ 
+ 	sprintf(guillemot->phys, "%s/input0", gameport->phys);
+-
+ 	guillemot->type = guillemot_type + i;
+ 
+-	guillemot->dev.private = guillemot;
+-	guillemot->dev.open = guillemot_open;
+-	guillemot->dev.close = guillemot_close;
+-
+-	guillemot->dev.name = guillemot_type[i].name;
+-	guillemot->dev.phys = guillemot->phys;
+-	guillemot->dev.id.bustype = BUS_GAMEPORT;
+-	guillemot->dev.id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
+-	guillemot->dev.id.product = guillemot_type[i].id;
+-	guillemot->dev.id.version = (int)data[14] << 8 | data[15];
++	input_dev->name = guillemot_type[i].name;
++	input_dev->phys = guillemot->phys;
++	input_dev->id.bustype = BUS_GAMEPORT;
++	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
++	input_dev->id.product = guillemot_type[i].id;
++	input_dev->id.version = (int)data[14] << 8 | data[15];
++	input_dev->cdev.dev = &gameport->dev;
++	input_dev->private = guillemot;
++
++	input_dev->open = guillemot_open;
++	input_dev->close = guillemot_close;
+ 
+-	guillemot->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+ 	for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++)
+-		input_set_abs_params(&guillemot->dev, t, 0, 255, 0, 0);
++		input_set_abs_params(input_dev, t, 0, 255, 0, 0);
+ 
+ 	if (guillemot->type->hat) {
+-		input_set_abs_params(&guillemot->dev, ABS_HAT0X, -1, 1, 0, 0);
+-		input_set_abs_params(&guillemot->dev, ABS_HAT0Y, -1, 1, 0, 0);
++		input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
++		input_set_abs_params(input_dev, ABS_HAT0Y, -1, 1, 0, 0);
+ 	}
+ 
+ 	for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++)
+-		set_bit(t, guillemot->dev.keybit);
++		set_bit(t, input_dev->keybit);
+ 
+-	input_register_device(&guillemot->dev);
+-	printk(KERN_INFO "input: %s ver %d.%02d on %s\n",
+-		guillemot->type->name, data[14], data[15], gameport->phys);
++	input_register_device(guillemot->dev);
+ 
+ 	return 0;
+ 
+ fail2:	gameport_close(gameport);
+ fail1:  gameport_set_drvdata(gameport, NULL);
++	input_free_device(input_dev);
+ 	kfree(guillemot);
+ 	return err;
+ }
+@@ -260,7 +266,7 @@ static void guillemot_disconnect(struct 
+ 	struct guillemot *guillemot = gameport_get_drvdata(gameport);
+ 
+ 	printk(KERN_INFO "guillemot.c: Failed %d reads out of %d on %s\n", guillemot->reads, guillemot->bads, guillemot->phys);
+-	input_unregister_device(&guillemot->dev);
++	input_unregister_device(guillemot->dev);
+ 	gameport_close(gameport);
+ 	kfree(guillemot);
+ }
+diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
+--- a/drivers/input/joystick/iforce/iforce-main.c
++++ b/drivers/input/joystick/iforce/iforce-main.c
+@@ -144,7 +144,7 @@ static int iforce_upload_effect(struct i
+ 	int is_update;
+ 
+ /* Check this effect type is supported by this device */
+-	if (!test_bit(effect->type, iforce->dev.ffbit))
++	if (!test_bit(effect->type, iforce->dev->ffbit))
+ 		return -EINVAL;
+ 
+ /*
+@@ -152,30 +152,31 @@ static int iforce_upload_effect(struct i
+  */
+ 	if (effect->id == -1) {
+ 
+-		for (id=0; id < FF_EFFECTS_MAX; ++id)
+-			if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) break;
++		for (id = 0; id < FF_EFFECTS_MAX; ++id)
++			if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags))
++				break;
+ 
+-		if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max)
++		if (id == FF_EFFECTS_MAX || id >= iforce->dev->ff_effects_max)
+ 			return -ENOMEM;
+ 
+ 		effect->id = id;
+ 		iforce->core_effects[id].owner = current->pid;
+-		iforce->core_effects[id].flags[0] = (1<<FF_CORE_IS_USED);	/* Only IS_USED bit must be set */
++		iforce->core_effects[id].flags[0] = (1 << FF_CORE_IS_USED);	/* Only IS_USED bit must be set */
+ 
+ 		is_update = FALSE;
+ 	}
+ 	else {
+ 		/* We want to update an effect */
+-		if (!CHECK_OWNERSHIP(effect->id, iforce)) return -EACCES;
++		if (!CHECK_OWNERSHIP(effect->id, iforce))
++			return -EACCES;
+ 
+ 		/* Parameter type cannot be updated */
+ 		if (effect->type != iforce->core_effects[effect->id].effect.type)
+ 			return -EINVAL;
+ 
+ 		/* Check the effect is not already being updated */
+-		if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) {
++		if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags))
+ 			return -EAGAIN;
+-		}
+ 
+ 		is_update = TRUE;
+ 	}
+@@ -339,15 +340,19 @@ void iforce_delete_device(struct iforce 
+ 
+ int iforce_init_device(struct iforce *iforce)
+ {
++	struct input_dev *input_dev;
+ 	unsigned char c[] = "CEOV";
+ 	int i;
+ 
++	input_dev = input_allocate_device();
++	if (input_dev)
++		return -ENOMEM;
++
+ 	init_waitqueue_head(&iforce->wait);
+ 	spin_lock_init(&iforce->xmit_lock);
+ 	init_MUTEX(&iforce->mem_mutex);
+ 	iforce->xmit.buf = iforce->xmit_data;
+-
+-	iforce->dev.ff_effects_max = 10;
++	iforce->dev = input_dev;
+ 
+ /*
+  * Input device fields.
+@@ -356,26 +361,27 @@ int iforce_init_device(struct iforce *if
+ 	switch (iforce->bus) {
+ #ifdef CONFIG_JOYSTICK_IFORCE_USB
+ 	case IFORCE_USB:
+-		iforce->dev.id.bustype = BUS_USB;
+-		iforce->dev.dev = &iforce->usbdev->dev;
++		input_dev->id.bustype = BUS_USB;
++		input_dev->cdev.dev = &iforce->usbdev->dev;
+ 		break;
+ #endif
+ #ifdef CONFIG_JOYSTICK_IFORCE_232
+ 	case IFORCE_232:
+-		iforce->dev.id.bustype = BUS_RS232;
+-		iforce->dev.dev = &iforce->serio->dev;
++		input_dev->id.bustype = BUS_RS232;
++		input_dev->cdev.dev = &iforce->serio->dev;
+ 		break;
+ #endif
+ 	}
+ 
+-	iforce->dev.private = iforce;
+-	iforce->dev.name = "Unknown I-Force device";
+-	iforce->dev.open = iforce_open;
+-	iforce->dev.close = iforce_release;
+-	iforce->dev.flush = iforce_flush;
+-	iforce->dev.event = iforce_input_event;
+-	iforce->dev.upload_effect = iforce_upload_effect;
+-	iforce->dev.erase_effect = iforce_erase_effect;
++	input_dev->private = iforce;
++	input_dev->name = "Unknown I-Force device";
++	input_dev->open = iforce_open;
++	input_dev->close = iforce_release;
++	input_dev->flush = iforce_flush;
++	input_dev->event = iforce_input_event;
++	input_dev->upload_effect = iforce_upload_effect;
++	input_dev->erase_effect = iforce_erase_effect;
++	input_dev->ff_effects_max = 10;
+ 
+ /*
+  * On-device memory allocation.
+@@ -399,7 +405,8 @@ int iforce_init_device(struct iforce *if
+ 
+ 	if (i == 20) { /* 5 seconds */
+ 		printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n");
+-		return -1;
++		input_free_device(input_dev);
++		return -ENODEV;
+ 	}
+ 
+ /*
+@@ -407,12 +414,12 @@ int iforce_init_device(struct iforce *if
+  */
+ 
+ 	if (!iforce_get_id_packet(iforce, "M"))
+-		iforce->dev.id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
++		input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
+ 	else
+ 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n");
+ 
+ 	if (!iforce_get_id_packet(iforce, "P"))
+-		iforce->dev.id.product = (iforce->edata[2] << 8) | iforce->edata[1];
++		input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
+ 	else
+ 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n");
+ 
+@@ -422,15 +429,15 @@ int iforce_init_device(struct iforce *if
+ 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
+ 
+ 	if (!iforce_get_id_packet(iforce, "N"))
+-		iforce->dev.ff_effects_max = iforce->edata[1];
++		iforce->dev->ff_effects_max = iforce->edata[1];
+ 	else
+ 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
+ 
+ 	/* Check if the device can store more effects than the driver can really handle */
+-	if (iforce->dev.ff_effects_max > FF_EFFECTS_MAX) {
++	if (iforce->dev->ff_effects_max > FF_EFFECTS_MAX) {
+ 		printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n",
+-			iforce->dev.ff_effects_max, FF_EFFECTS_MAX);
+-		iforce->dev.ff_effects_max = FF_EFFECTS_MAX;
++			iforce->dev->ff_effects_max, FF_EFFECTS_MAX);
++		iforce->dev->ff_effects_max = FF_EFFECTS_MAX;
+ 	}
+ 
+ /*
+@@ -453,29 +460,28 @@ int iforce_init_device(struct iforce *if
+  */
+ 
+ 	for (i = 0; iforce_device[i].idvendor; i++)
+-		if (iforce_device[i].idvendor == iforce->dev.id.vendor &&
+-		    iforce_device[i].idproduct == iforce->dev.id.product)
++		if (iforce_device[i].idvendor == input_dev->id.vendor &&
++		    iforce_device[i].idproduct == input_dev->id.product)
+ 			break;
+ 
+ 	iforce->type = iforce_device + i;
+-	iforce->dev.name = iforce->type->name;
++	input_dev->name = iforce->type->name;
+ 
+ /*
+  * Set input device bitfields and ranges.
+  */
+ 
+-	iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
+ 
+ 	for (i = 0; iforce->type->btn[i] >= 0; i++) {
+ 		signed short t = iforce->type->btn[i];
+-		set_bit(t, iforce->dev.keybit);
++		set_bit(t, input_dev->keybit);
+ 	}
+-	set_bit(BTN_DEAD, iforce->dev.keybit);
++	set_bit(BTN_DEAD, input_dev->keybit);
+ 
+ 	for (i = 0; iforce->type->abs[i] >= 0; i++) {
+ 
+ 		signed short t = iforce->type->abs[i];
+-		set_bit(t, iforce->dev.absbit);
+ 
+ 		switch (t) {
+ 
+@@ -483,52 +489,42 @@ int iforce_init_device(struct iforce *if
+ 			case ABS_Y:
+ 			case ABS_WHEEL:
+ 
+-				iforce->dev.absmax[t] =  1920;
+-				iforce->dev.absmin[t] = -1920;
+-				iforce->dev.absflat[t] = 128;
+-				iforce->dev.absfuzz[t] = 16;
+-
+-				set_bit(t, iforce->dev.ffbit);
++				input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
++				set_bit(t, input_dev->ffbit);
+ 				break;
+ 
+ 			case ABS_THROTTLE:
+ 			case ABS_GAS:
+ 			case ABS_BRAKE:
+ 
+-				iforce->dev.absmax[t] = 255;
+-				iforce->dev.absmin[t] = 0;
++				input_set_abs_params(input_dev, t, 0, 255, 0, 0);
+ 				break;
+ 
+ 			case ABS_RUDDER:
+ 
+-				iforce->dev.absmax[t] = 127;
+-				iforce->dev.absmin[t] = -128;
++				input_set_abs_params(input_dev, t, -128, 127, 0, 0);
+ 				break;
+ 
+ 			case ABS_HAT0X:
+ 			case ABS_HAT0Y:
+ 		        case ABS_HAT1X:
+ 		        case ABS_HAT1Y:
+-				iforce->dev.absmax[t] =  1;
+-				iforce->dev.absmin[t] = -1;
++
++				input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+ 				break;
+ 		}
+ 	}
+ 
+ 	for (i = 0; iforce->type->ff[i] >= 0; i++)
+-		set_bit(iforce->type->ff[i], iforce->dev.ffbit);
++		set_bit(iforce->type->ff[i], input_dev->ffbit);
+ 
+ /*
+  * Register input device.
+  */
+ 
+-	input_register_device(&iforce->dev);
+-
+-	printk(KERN_DEBUG "iforce->dev.open = %p\n", iforce->dev.open);
++	input_register_device(iforce->dev);
+ 
+-	printk(KERN_INFO "input: %s [%d effects, %ld bytes memory]\n",
+-		iforce->dev.name, iforce->dev.ff_effects_max,
+-		iforce->device_memory.end);
++	printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
+--- a/drivers/input/joystick/iforce/iforce-packets.c
++++ b/drivers/input/joystick/iforce/iforce-packets.c
+@@ -139,7 +139,8 @@ printk(KERN_DEBUG "iforce-packets.c: con
+ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
+ {
+ 	int i;
+-	for (i=0; i<iforce->dev.ff_effects_max; ++i) {
++
++	for (i = 0; i < iforce->dev->ff_effects_max; ++i) {
+ 		if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
+ 		    (iforce->core_effects[i].mod1_chunk.start == addr ||
+ 		     iforce->core_effects[i].mod2_chunk.start == addr)) {
+@@ -153,7 +154,7 @@ static int mark_core_as_ready(struct ifo
+ 
+ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &iforce->dev;
++	struct input_dev *dev = iforce->dev;
+ 	int i;
+ 	static int being_used = 0;
+ 
+diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
+--- a/drivers/input/joystick/iforce/iforce-serio.c
++++ b/drivers/input/joystick/iforce/iforce-serio.c
+@@ -131,11 +131,10 @@ static int iforce_serio_connect(struct s
+ 	struct iforce *iforce;
+ 	int err;
+ 
+-	if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL)))
++	iforce = kzalloc(sizeof(struct iforce), GFP_KERNEL);
++	if (!iforce)
+ 		return -ENOMEM;
+ 
+-	memset(iforce, 0, sizeof(struct iforce));
+-
+ 	iforce->bus = IFORCE_232;
+ 	iforce->serio = serio;
+ 
+@@ -148,7 +147,8 @@ static int iforce_serio_connect(struct s
+ 		return err;
+ 	}
+ 
+-	if (iforce_init_device(iforce)) {
++	err = iforce_init_device(iforce);
++	if (err) {
+ 		serio_close(serio);
+ 		serio_set_drvdata(serio, NULL);
+ 		kfree(iforce);
+@@ -162,7 +162,7 @@ static void iforce_serio_disconnect(stru
+ {
+ 	struct iforce *iforce = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&iforce->dev);
++	input_unregister_device(iforce->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
+ 	kfree(iforce);
+diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
+--- a/drivers/input/joystick/iforce/iforce-usb.c
++++ b/drivers/input/joystick/iforce/iforce-usb.c
+@@ -135,28 +135,24 @@ static int iforce_usb_probe(struct usb_i
+ 	struct usb_host_interface *interface;
+ 	struct usb_endpoint_descriptor *epirq, *epout;
+ 	struct iforce *iforce;
++	int err = -ENOMEM;
+ 
+ 	interface = intf->cur_altsetting;
+ 
+ 	epirq = &interface->endpoint[0].desc;
+ 	epout = &interface->endpoint[1].desc;
+ 
+-	if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
++	if (!(iforce = kzalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
+ 		goto fail;
+ 
+-	memset(iforce, 0, sizeof(struct iforce));
+-
+-	if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL))) {
++	if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL)))
+ 		goto fail;
+-	}
+ 
+-	if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL))) {
++	if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL)))
+ 		goto fail;
+-	}
+ 
+-	if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL))) {
++	if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL)))
+ 		goto fail;
+-	}
+ 
+ 	iforce->bus = IFORCE_USB;
+ 	iforce->usbdev = dev;
+@@ -174,7 +170,9 @@ static int iforce_usb_probe(struct usb_i
+ 	usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
+ 			(void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce);
+ 
+-	if (iforce_init_device(iforce)) goto fail;
++	err = iforce_init_device(iforce);
++	if (err)
++		goto fail;
+ 
+ 	usb_set_intfdata(intf, iforce);
+ 	return 0;
+@@ -187,7 +185,7 @@ fail:
+ 		kfree(iforce);
+ 	}
+ 
+-	return -ENODEV;
++	return err;
+ }
+ 
+ /* Called by iforce_delete() */
+@@ -211,7 +209,7 @@ static void iforce_usb_disconnect(struct
+ 	usb_set_intfdata(intf, NULL);
+ 	if (iforce) {
+ 		iforce->usbdev = NULL;
+-		input_unregister_device(&iforce->dev);
++		input_unregister_device(iforce->dev);
+ 
+ 		if (!open) {
+ 			iforce_delete_device(iforce);
+diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
+--- a/drivers/input/joystick/iforce/iforce.h
++++ b/drivers/input/joystick/iforce/iforce.h
+@@ -117,7 +117,7 @@ struct iforce_device {
+ };
+ 
+ struct iforce {
+-	struct input_dev dev;		/* Input device interface */
++	struct input_dev *dev;		/* Input device interface */
+ 	struct iforce_device *type;
+ 	int bus;
+ 
+diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
+--- a/drivers/input/joystick/interact.c
++++ b/drivers/input/joystick/interact.c
+@@ -38,6 +38,7 @@
+ #include <linux/init.h>
+ #include <linux/gameport.h>
+ #include <linux/input.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"InterAct digital joystick driver"
+ 
+@@ -54,7 +55,7 @@ MODULE_LICENSE("GPL");
+ 
+ struct interact {
+ 	struct gameport *gameport;
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	int bads;
+ 	int reads;
+ 	unsigned char type;
+@@ -130,7 +131,7 @@ static int interact_read_packet(struct g
+ static void interact_poll(struct gameport *gameport)
+ {
+ 	struct interact *interact = gameport_get_drvdata(gameport);
+-	struct input_dev *dev = &interact->dev;
++	struct input_dev *dev = interact->dev;
+ 	u32 data[3];
+ 	int i;
+ 
+@@ -208,14 +209,20 @@ static void interact_close(struct input_
+ static int interact_connect(struct gameport *gameport, struct gameport_driver *drv)
+ {
+ 	struct interact *interact;
++	struct input_dev *input_dev;
+ 	__u32 data[3];
+ 	int i, t;
+ 	int err;
+ 
+-	if (!(interact = kzalloc(sizeof(struct interact), GFP_KERNEL)))
+-		return -ENOMEM;
++	interact = kzalloc(sizeof(struct interact), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!interact || !input_dev) {
++		err = -ENOMEM;
++		goto fail1;
++	}
+ 
+ 	interact->gameport = gameport;
++	interact->dev = input_dev;
+ 
+ 	gameport_set_drvdata(gameport, interact);
+ 
+@@ -249,41 +256,40 @@ static int interact_connect(struct gamep
+ 	interact->type = i;
+ 	interact->length = interact_type[i].length;
+ 
+-	interact->dev.private = interact;
+-	interact->dev.open = interact_open;
+-	interact->dev.close = interact_close;
+-
+-	interact->dev.name = interact_type[i].name;
+-	interact->dev.phys = interact->phys;
+-	interact->dev.id.bustype = BUS_GAMEPORT;
+-	interact->dev.id.vendor = GAMEPORT_ID_VENDOR_INTERACT;
+-	interact->dev.id.product = interact_type[i].id;
+-	interact->dev.id.version = 0x0100;
++	input_dev->name = interact_type[i].name;
++	input_dev->phys = interact->phys;
++	input_dev->id.bustype = BUS_GAMEPORT;
++	input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT;
++	input_dev->id.product = interact_type[i].id;
++	input_dev->id.version = 0x0100;
++	input_dev->private = interact;
++
++	input_dev->open = interact_open;
++	input_dev->close = interact_close;
+ 
+-	interact->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+ 	for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
+-		set_bit(t, interact->dev.absbit);
++		set_bit(t, input_dev->absbit);
+ 		if (i < interact_type[interact->type].b8) {
+-			interact->dev.absmin[t] = 0;
+-			interact->dev.absmax[t] = 255;
++			input_dev->absmin[t] = 0;
++			input_dev->absmax[t] = 255;
+ 		} else {
+-			interact->dev.absmin[t] = -1;
+-			interact->dev.absmax[t] = 1;
++			input_dev->absmin[t] = -1;
++			input_dev->absmax[t] = 1;
+ 		}
+ 	}
+ 
+ 	for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++)
+-		set_bit(t, interact->dev.keybit);
++		set_bit(t, input_dev->keybit);
+ 
+-	input_register_device(&interact->dev);
+-	printk(KERN_INFO "input: %s on %s\n",
+-		interact_type[interact->type].name, gameport->phys);
++	input_register_device(interact->dev);
+ 
+ 	return 0;
+ 
+ fail2:	gameport_close(gameport);
+ fail1:  gameport_set_drvdata(gameport, NULL);
++	input_free_device(input_dev);
+ 	kfree(interact);
+ 	return err;
+ }
+@@ -292,7 +298,7 @@ static void interact_disconnect(struct g
+ {
+ 	struct interact *interact = gameport_get_drvdata(gameport);
+ 
+-	input_unregister_device(&interact->dev);
++	input_unregister_device(interact->dev);
+ 	gameport_close(gameport);
+ 	gameport_set_drvdata(gameport, NULL);
+ 	kfree(interact);
+diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c
+--- a/drivers/input/joystick/joydump.c
++++ b/drivers/input/joystick/joydump.c
+@@ -34,6 +34,7 @@
+ #include <linux/kernel.h>
+ #include <linux/delay.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ 
+ #define DRIVER_DESC	"Gameport data dumper module"
+ 
+diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
+--- a/drivers/input/joystick/magellan.c
++++ b/drivers/input/joystick/magellan.c
+@@ -49,14 +49,13 @@ MODULE_LICENSE("GPL");
+ 
+ static int magellan_buttons[] = { BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8 };
+ static int magellan_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
+-static char *magellan_name = "LogiCad3D Magellan / SpaceMouse";
+ 
+ /*
+  * Per-Magellan data.
+  */
+ 
+ struct magellan {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	int idx;
+ 	unsigned char data[MAGELLAN_MAX_LENGTH];
+ 	char phys[32];
+@@ -85,7 +84,7 @@ static int magellan_crunch_nibbles(unsig
+ 
+ static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &magellan->dev;
++	struct input_dev *dev = magellan->dev;
+ 	unsigned char *data = magellan->data;
+ 	int i, t;
+ 
+@@ -138,9 +137,9 @@ static void magellan_disconnect(struct s
+ {
+ 	struct magellan* magellan = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&magellan->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(magellan->dev);
+ 	kfree(magellan);
+ }
+ 
+@@ -153,52 +152,48 @@ static void magellan_disconnect(struct s
+ static int magellan_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct magellan *magellan;
+-	int i, t;
+-	int err;
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
++	int i;
++
++	magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!magellan || !input_dev)
++		goto fail;
+ 
+-	if (!(magellan = kmalloc(sizeof(struct magellan), GFP_KERNEL)))
+-		return -ENOMEM;
++	magellan->dev = input_dev;
++	sprintf(magellan->phys, "%s/input0", serio->phys);
+ 
+-	memset(magellan, 0, sizeof(struct magellan));
++	input_dev->name = "LogiCad3D Magellan / SpaceMouse";
++	input_dev->phys = magellan->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_MAGELLAN;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = magellan;
+ 
+-	magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+ 	for (i = 0; i < 9; i++)
+-		set_bit(magellan_buttons[i], magellan->dev.keybit);
+-
+-	for (i = 0; i < 6; i++) {
+-		t = magellan_axes[i];
+-		set_bit(t, magellan->dev.absbit);
+-		magellan->dev.absmin[t] = -360;
+-		magellan->dev.absmax[t] =  360;
+-	}
+-
+-	sprintf(magellan->phys, "%s/input0", serio->phys);
++		set_bit(magellan_buttons[i], input_dev->keybit);
+ 
+-	init_input_dev(&magellan->dev);
+-	magellan->dev.private = magellan;
+-	magellan->dev.name = magellan_name;
+-	magellan->dev.phys = magellan->phys;
+-	magellan->dev.id.bustype = BUS_RS232;
+-	magellan->dev.id.vendor = SERIO_MAGELLAN;
+-	magellan->dev.id.product = 0x0001;
+-	magellan->dev.id.version = 0x0100;
+-	magellan->dev.dev = &serio->dev;
++	for (i = 0; i < 6; i++)
++		input_set_abs_params(input_dev, magellan_axes[i], -360, 360, 0, 0);
+ 
+ 	serio_set_drvdata(serio, magellan);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(magellan);
+-		return err;
+-	}
+-
+-	input_register_device(&magellan->dev);
+-
+-	printk(KERN_INFO "input: %s on %s\n", magellan_name, serio->phys);
++	if (err)
++		goto fail;
+ 
++	input_register_device(magellan->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(magellan);
++	return err;
+ }
+ 
+ /*
+diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
+--- a/drivers/input/joystick/sidewinder.c
++++ b/drivers/input/joystick/sidewinder.c
+@@ -33,6 +33,7 @@
+ #include <linux/init.h>
+ #include <linux/input.h>
+ #include <linux/gameport.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"Microsoft SideWinder joystick family driver"
+ 
+@@ -113,7 +114,7 @@ static struct {
+ 
+ struct sw {
+ 	struct gameport *gameport;
+-	struct input_dev dev[4];
++	struct input_dev *dev[4];
+ 	char name[64];
+ 	char phys[4][32];
+ 	int length;
+@@ -301,7 +302,7 @@ static int sw_check(__u64 t)
+ static int sw_parse(unsigned char *buf, struct sw *sw)
+ {
+ 	int hat, i, j;
+-	struct input_dev *dev = sw->dev;
++	struct input_dev *dev;
+ 
+ 	switch (sw->type) {
+ 
+@@ -310,6 +311,8 @@ static int sw_parse(unsigned char *buf, 
+ 			if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8)
+ 				return -1;
+ 
++			dev = sw->dev[0];
++
+ 			input_report_abs(dev, ABS_X,        (GB( 3,3) << 7) | GB(16,7));
+ 			input_report_abs(dev, ABS_Y,        (GB( 0,3) << 7) | GB(24,7));
+ 			input_report_abs(dev, ABS_RZ,       (GB(35,2) << 7) | GB(40,7));
+@@ -335,13 +338,13 @@ static int sw_parse(unsigned char *buf, 
+ 				if (sw_parity(GB(i*15,15)))
+ 					return -1;
+ 
+-				input_report_abs(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
+-				input_report_abs(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
++				input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
++				input_report_abs(sw->dev[i], ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
+ 
+ 				for (j = 0; j < 10; j++)
+-					input_report_key(dev + i, sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
++					input_report_key(sw->dev[i], sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
+ 
+-				input_sync(dev + i);
++				input_sync(sw->dev[i]);
+ 			}
+ 
+ 			return 0;
+@@ -352,6 +355,7 @@ static int sw_parse(unsigned char *buf, 
+ 			if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8)
+ 				return -1;
+ 
++			dev = sw->dev[0];
+ 			input_report_abs(dev, ABS_X,        GB( 9,10));
+ 			input_report_abs(dev, ABS_Y,        GB(19,10));
+ 			input_report_abs(dev, ABS_RZ,       GB(36, 6));
+@@ -372,6 +376,7 @@ static int sw_parse(unsigned char *buf, 
+ 			if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8)
+ 				return -1;
+ 
++			dev = sw->dev[0];
+ 			input_report_abs(dev, ABS_X,        GB( 0,10));
+ 			input_report_abs(dev, ABS_Y,        GB(16,10));
+ 			input_report_abs(dev, ABS_THROTTLE, GB(32, 6));
+@@ -396,6 +401,7 @@ static int sw_parse(unsigned char *buf, 
+ 			if (!sw_parity(GB(0,33)))
+ 				return -1;
+ 
++			dev = sw->dev[0];
+ 			input_report_abs(dev, ABS_RX,       GB( 0,10));
+ 			input_report_abs(dev, ABS_RUDDER,   GB(10, 6));
+ 			input_report_abs(dev, ABS_THROTTLE, GB(16, 6));
+@@ -581,6 +587,7 @@ static int sw_guess_mode(unsigned char *
+ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
+ {
+ 	struct sw *sw;
++	struct input_dev *input_dev;
+ 	int i, j, k, l;
+ 	int err;
+ 	unsigned char *buf = NULL;	/* [SW_LENGTH] */
+@@ -729,42 +736,50 @@ static int sw_connect(struct gameport *g
+ 		sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]);
+ 		sprintf(sw->phys[i], "%s/input%d", gameport->phys, i);
+ 
+-		sw->dev[i].private = sw;
+-
+-		sw->dev[i].open = sw_open;
+-		sw->dev[i].close = sw_close;
++		input_dev = input_allocate_device();
++		if (!input_dev) {
++			err = -ENOMEM;
++			goto fail3;
++		}
++
++		input_dev->name = sw->name;
++		input_dev->phys = sw->phys[i];
++		input_dev->id.bustype = BUS_GAMEPORT;
++		input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
++		input_dev->id.product = sw->type;
++		input_dev->id.version = 0x0100;
++		input_dev->cdev.dev = &gameport->dev;
++		input_dev->private = sw;
+ 
+-		sw->dev[i].name = sw->name;
+-		sw->dev[i].phys = sw->phys[i];
+-		sw->dev[i].id.bustype = BUS_GAMEPORT;
+-		sw->dev[i].id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
+-		sw->dev[i].id.product = sw->type;
+-		sw->dev[i].id.version = 0x0100;
++		input_dev->open = sw_open;
++		input_dev->close = sw_close;
+ 
+-		sw->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+ 		for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
+ 			code = sw_abs[sw->type][j];
+-			set_bit(code, sw->dev[i].absbit);
+-			sw->dev[i].absmax[code] = (1 << bits) - 1;
+-			sw->dev[i].absmin[code] = (bits == 1) ? -1 : 0;
+-			sw->dev[i].absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0;
++			set_bit(code, input_dev->absbit);
++			input_dev->absmax[code] = (1 << bits) - 1;
++			input_dev->absmin[code] = (bits == 1) ? -1 : 0;
++			input_dev->absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0;
+ 			if (code != ABS_THROTTLE)
+-				sw->dev[i].absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0;
++				input_dev->absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0;
+ 		}
+ 
+ 		for (j = 0; (code = sw_btn[sw->type][j]); j++)
+-			set_bit(code, sw->dev[i].keybit);
++			set_bit(code, input_dev->keybit);
++
++		dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k);
+ 
+-		input_register_device(sw->dev + i);
+-		printk(KERN_INFO "input: %s%s on %s [%d-bit id %d data %d]\n",
+-			sw->name, comment, gameport->phys, m, l, k);
++		input_register_device(sw->dev[i]);
+ 	}
+ 
+ 	return 0;
+ 
+-fail2:	gameport_close(gameport);
+-fail1:	gameport_set_drvdata(gameport, NULL);
++ fail3: while (--i >= 0)
++		input_unregister_device(sw->dev[i]);
++ fail2:	gameport_close(gameport);
++ fail1:	gameport_set_drvdata(gameport, NULL);
+ 	kfree(sw);
+ 	kfree(buf);
+ 	kfree(idbuf);
+@@ -777,7 +792,7 @@ static void sw_disconnect(struct gamepor
+ 	int i;
+ 
+ 	for (i = 0; i < sw->number; i++)
+-		input_unregister_device(sw->dev + i);
++		input_unregister_device(sw->dev[i]);
+ 	gameport_close(gameport);
+ 	gameport_set_drvdata(gameport, NULL);
+ 	kfree(sw);
+diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
+--- a/drivers/input/joystick/spaceball.c
++++ b/drivers/input/joystick/spaceball.c
+@@ -70,8 +70,7 @@ static char *spaceball_names[] = {
+  */
+ 
+ struct spaceball {
+-	struct input_dev dev;
+-	struct serio *serio;
++	struct input_dev *dev;
+ 	int idx;
+ 	int escape;
+ 	unsigned char data[SPACEBALL_MAX_LENGTH];
+@@ -85,7 +84,7 @@ struct spaceball {
+ 
+ static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &spaceball->dev;
++	struct input_dev *dev = spaceball->dev;
+ 	unsigned char *data = spaceball->data;
+ 	int i;
+ 
+@@ -193,9 +192,9 @@ static void spaceball_disconnect(struct 
+ {
+ 	struct spaceball* spaceball = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&spaceball->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(spaceball->dev);
+ 	kfree(spaceball);
+ }
+ 
+@@ -208,69 +207,62 @@ static void spaceball_disconnect(struct 
+ static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct spaceball *spaceball;
+-	int i, t, id;
+-	int err;
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
++	int i, id;
+ 
+ 	if ((id = serio->id.id) > SPACEBALL_MAX_ID)
+ 		return -ENODEV;
+ 
+-	if (!(spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL)))
+-		return - ENOMEM;
++	spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!spaceball || !input_dev)
++		goto fail;
+ 
+-	memset(spaceball, 0, sizeof(struct spaceball));
++	spaceball->dev = input_dev;
++	sprintf(spaceball->phys, "%s/input0", serio->phys);
++
++	input_dev->name = spaceball_names[id];
++	input_dev->phys = spaceball->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_SPACEBALL;
++	input_dev->id.product = id;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = spaceball;
+ 
+-	spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+ 	switch (id) {
+ 		case SPACEBALL_4000FLX:
+ 		case SPACEBALL_4000FLX_L:
+-			spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_9);
+-			spaceball->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
++			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9);
++			input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
+ 		default:
+-			spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
++			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
+ 				| BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
+ 		case SPACEBALL_3003C:
+-			spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
++			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
+ 	}
+ 
+-	for (i = 0; i < 6; i++) {
+-		t = spaceball_axes[i];
+-		set_bit(t, spaceball->dev.absbit);
+-		spaceball->dev.absmin[t] = i < 3 ? -8000 : -1600;
+-		spaceball->dev.absmax[t] = i < 3 ?  8000 :  1600;
+-		spaceball->dev.absflat[t] = i < 3 ? 40 : 8;
+-		spaceball->dev.absfuzz[t] = i < 3 ? 8 : 2;
++	for (i = 0; i < 3; i++) {
++		input_set_abs_params(input_dev, ABS_X + i, -8000, 8000, 8, 40);
++		input_set_abs_params(input_dev, ABS_RX + i, -1600, 1600, 2, 8);
+ 	}
+ 
+-	spaceball->serio = serio;
+-	spaceball->dev.private = spaceball;
+-
+-	sprintf(spaceball->phys, "%s/input0", serio->phys);
+-
+-	init_input_dev(&spaceball->dev);
+-	spaceball->dev.name = spaceball_names[id];
+-	spaceball->dev.phys = spaceball->phys;
+-	spaceball->dev.id.bustype = BUS_RS232;
+-	spaceball->dev.id.vendor = SERIO_SPACEBALL;
+-	spaceball->dev.id.product = id;
+-	spaceball->dev.id.version = 0x0100;
+-	spaceball->dev.dev = &serio->dev;
+-
+ 	serio_set_drvdata(serio, spaceball);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(spaceball);
+-		return err;
+-	}
+-
+-	input_register_device(&spaceball->dev);
+-
+-	printk(KERN_INFO "input: %s on serio%s\n",
+-		spaceball_names[id], serio->phys);
++	if (err)
++		goto fail;
+ 
++	input_register_device(spaceball->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(spaceball);
++	return err;
+ }
+ 
+ /*
+diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
+--- a/drivers/input/joystick/spaceorb.c
++++ b/drivers/input/joystick/spaceorb.c
+@@ -52,15 +52,13 @@ MODULE_LICENSE("GPL");
+ 
+ static int spaceorb_buttons[] = { BTN_TL, BTN_TR, BTN_Y, BTN_X, BTN_B, BTN_A };
+ static int spaceorb_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
+-static char *spaceorb_name = "SpaceTec SpaceOrb 360 / Avenger";
+ 
+ /*
+  * Per-Orb data.
+  */
+ 
+ struct spaceorb {
+-	struct input_dev dev;
+-	struct serio *serio;
++	struct input_dev *dev;
+ 	int idx;
+ 	unsigned char data[SPACEORB_MAX_LENGTH];
+ 	char phys[32];
+@@ -78,7 +76,7 @@ static unsigned char *spaceorb_errors[] 
+ 
+ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &spaceorb->dev;
++	struct input_dev *dev = spaceorb->dev;
+ 	unsigned char *data = spaceorb->data;
+ 	unsigned char c = 0;
+ 	int axes[6];
+@@ -95,8 +93,8 @@ static void spaceorb_process_packet(stru
+ 		case 'R':				/* Reset packet */
+ 			spaceorb->data[spaceorb->idx - 1] = 0;
+ 			for (i = 1; i < spaceorb->idx && spaceorb->data[i] == ' '; i++);
+-			printk(KERN_INFO "input: %s [%s] on %s\n",
+-				 spaceorb_name, spaceorb->data + i, spaceorb->serio->phys);
++			printk(KERN_INFO "input: %s [%s] is %s\n",
++				 dev->name, spaceorb->data + i, spaceorb->phys);
+ 			break;
+ 
+ 		case 'D':				/* Ball + button data */
+@@ -123,7 +121,7 @@ static void spaceorb_process_packet(stru
+ 
+ 		case 'E':				/* Error packet */
+ 			if (spaceorb->idx != 4) return;
+-			printk(KERN_ERR "joy-spaceorb: Device error. [ ");
++			printk(KERN_ERR "spaceorb: Device error. [ ");
+ 			for (i = 0; i < 7; i++) if (data[1] & (1 << i)) printk("%s ", spaceorb_errors[i]);
+ 			printk("]\n");
+ 			break;
+@@ -154,9 +152,9 @@ static void spaceorb_disconnect(struct s
+ {
+ 	struct spaceorb* spaceorb = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&spaceorb->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(spaceorb->dev);
+ 	kfree(spaceorb);
+ }
+ 
+@@ -169,52 +167,48 @@ static void spaceorb_disconnect(struct s
+ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct spaceorb *spaceorb;
+-	int i, t;
+-	int err;
+-
+-	if (!(spaceorb = kmalloc(sizeof(struct spaceorb), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset(spaceorb, 0, sizeof(struct spaceorb));
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
++	int i;
+ 
+-	spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!spaceorb || !input_dev)
++		goto fail;
+ 
+-	for (i = 0; i < 6; i++)
+-		set_bit(spaceorb_buttons[i], spaceorb->dev.keybit);
++	spaceorb->dev = input_dev;
++	sprintf(spaceorb->phys, "%s/input0", serio->phys);
+ 
+-	for (i = 0; i < 6; i++) {
+-		t = spaceorb_axes[i];
+-		set_bit(t, spaceorb->dev.absbit);
+-		spaceorb->dev.absmin[t] = -508;
+-		spaceorb->dev.absmax[t] =  508;
+-	}
++	input_dev->name = "SpaceTec SpaceOrb 360 / Avenger";
++	input_dev->phys = spaceorb->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_SPACEORB;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = spaceorb;
+ 
+-	spaceorb->serio = serio;
+-	spaceorb->dev.private = spaceorb;
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+-	sprintf(spaceorb->phys, "%s/input0", serio->phys);
++	for (i = 0; i < 6; i++)
++		set_bit(spaceorb_buttons[i], input_dev->keybit);
+ 
+-	init_input_dev(&spaceorb->dev);
+-	spaceorb->dev.name = spaceorb_name;
+-	spaceorb->dev.phys = spaceorb->phys;
+-	spaceorb->dev.id.bustype = BUS_RS232;
+-	spaceorb->dev.id.vendor = SERIO_SPACEORB;
+-	spaceorb->dev.id.product = 0x0001;
+-	spaceorb->dev.id.version = 0x0100;
+-	spaceorb->dev.dev = &serio->dev;
++	for (i = 0; i < 6; i++)
++		input_set_abs_params(input_dev, spaceorb_axes[i], -508, 508, 0, 0);
+ 
+ 	serio_set_drvdata(serio, spaceorb);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(spaceorb);
+-		return err;
+-	}
+-
+-	input_register_device(&spaceorb->dev);
++	if (err)
++		goto fail;
+ 
++	input_register_device(spaceorb->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(spaceorb);
++	return err;
+ }
+ 
+ /*
+diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
+--- a/drivers/input/joystick/stinger.c
++++ b/drivers/input/joystick/stinger.c
+@@ -48,14 +48,12 @@ MODULE_LICENSE("GPL");
+ 
+ #define STINGER_MAX_LENGTH 8
+ 
+-static char *stinger_name = "Gravis Stinger";
+-
+ /*
+  * Per-Stinger data.
+  */
+ 
+ struct stinger {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	int idx;
+ 	unsigned char data[STINGER_MAX_LENGTH];
+ 	char phys[32];
+@@ -68,7 +66,7 @@ struct stinger {
+ 
+ static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &stinger->dev;
++	struct input_dev *dev = stinger->dev;
+ 	unsigned char *data = stinger->data;
+ 
+ 	if (!stinger->idx) return;
+@@ -126,9 +124,9 @@ static void stinger_disconnect(struct se
+ {
+ 	struct stinger *stinger = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&stinger->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(stinger->dev);
+ 	kfree(stinger);
+ }
+ 
+@@ -141,53 +139,46 @@ static void stinger_disconnect(struct se
+ static int stinger_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct stinger *stinger;
+-	int i;
+-	int err;
+-
+-	if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset(stinger, 0, sizeof(struct stinger));
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
+ 
+-	stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-	stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \
+-					   BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \
+-					   BIT(BTN_START) | BIT(BTN_SELECT);
+-	stinger->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
++	stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!stinger || !input_dev)
++		goto fail;
+ 
++	stinger->dev = input_dev;
+ 	sprintf(stinger->phys, "%s/serio0", serio->phys);
+ 
+-	init_input_dev(&stinger->dev);
+-	stinger->dev.name = stinger_name;
+-	stinger->dev.phys = stinger->phys;
+-	stinger->dev.id.bustype = BUS_RS232;
+-	stinger->dev.id.vendor = SERIO_STINGER;
+-	stinger->dev.id.product = 0x0001;
+-	stinger->dev.id.version = 0x0100;
+-	stinger->dev.dev = &serio->dev;
+-
+-	for (i = 0; i < 2; i++) {
+-		stinger->dev.absmax[ABS_X+i] =  64;
+-		stinger->dev.absmin[ABS_X+i] = -64;
+-		stinger->dev.absflat[ABS_X+i] = 4;
+-	}
+-
+-	stinger->dev.private = stinger;
++	input_dev->name = "Gravis Stinger";
++	input_dev->phys = stinger->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_STINGER;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = stinger;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) |
++					 BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) |
++					 BIT(BTN_START) | BIT(BTN_SELECT);
++	input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4);
++	input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4);
+ 
+ 	serio_set_drvdata(serio, stinger);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(stinger);
+-		return err;
+-	}
+-
+-	input_register_device(&stinger->dev);
+-
+-	printk(KERN_INFO "input: %s on %s\n",  stinger_name, serio->phys);
++	if (err)
++		goto fail;
+ 
++	input_register_device(stinger->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(stinger);
++	return err;
+ }
+ 
+ /*
+diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
+--- a/drivers/input/joystick/tmdc.c
++++ b/drivers/input/joystick/tmdc.c
+@@ -38,6 +38,7 @@
+ #include <linux/init.h>
+ #include <linux/gameport.h>
+ #include <linux/input.h>
++#include <linux/jiffies.h>
+ 
+ #define DRIVER_DESC	"ThrustMaster DirectConnect joystick driver"
+ 
+@@ -63,37 +64,70 @@ MODULE_LICENSE("GPL");
+ #define TMDC_ABS_HAT		4
+ #define TMDC_BTN		16
+ 
+-static unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 };
+-static unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 };
++static const unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 };
++static const unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 };
+ 
+-static signed char tmdc_abs[TMDC_ABS] =
++static const signed char tmdc_abs[TMDC_ABS] =
+ 	{ ABS_X, ABS_Y, ABS_RUDDER, ABS_THROTTLE, ABS_RX, ABS_RY, ABS_RZ };
+-static signed char tmdc_abs_hat[TMDC_ABS_HAT] =
++static const signed char tmdc_abs_hat[TMDC_ABS_HAT] =
+ 	{ ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
+-static signed char tmdc_abs_at[TMDC_ABS] =
++static const signed char tmdc_abs_at[TMDC_ABS] =
+ 	{ ABS_X, ABS_Y, ABS_RUDDER, -1, ABS_THROTTLE };
+-static signed char tmdc_abs_fm[TMDC_ABS] =
++static const signed char tmdc_abs_fm[TMDC_ABS] =
+ 	{ ABS_RX, ABS_RY, ABS_X, ABS_Y };
+ 
+-static short tmdc_btn_pad[TMDC_BTN] =
++static const short tmdc_btn_pad[TMDC_BTN] =
+ 	{ BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_START, BTN_SELECT, BTN_TL, BTN_TR };
+-static short tmdc_btn_joy[TMDC_BTN] =
++static const short tmdc_btn_joy[TMDC_BTN] =
+ 	{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_THUMB2, BTN_PINKIE,
+ 	  BTN_BASE3, BTN_BASE4, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z };
+-static short tmdc_btn_fm[TMDC_BTN] =
++static const short tmdc_btn_fm[TMDC_BTN] =
+         { BTN_TRIGGER, BTN_C, BTN_B, BTN_A, BTN_THUMB, BTN_X, BTN_Y, BTN_Z, BTN_TOP, BTN_TOP2 };
+-static short tmdc_btn_at[TMDC_BTN] =
++static const short tmdc_btn_at[TMDC_BTN] =
+         { BTN_TRIGGER, BTN_THUMB2, BTN_PINKIE, BTN_THUMB, BTN_BASE6, BTN_BASE5, BTN_BASE4,
+           BTN_BASE3, BTN_BASE2, BTN_BASE };
+ 
+-static struct {
++static const struct {
+         int x;
+         int y;
+ } tmdc_hat_to_axis[] = {{ 0, 0}, { 1, 0}, { 0,-1}, {-1, 0}, { 0, 1}};
+ 
++static const struct tmdc_model {
++	unsigned char id;
++	const char *name;
++	char abs;
++	char hats;
++	char btnc[4];
++	char btno[4];
++	const signed char *axes;
++	const short *buttons;
++} tmdc_models[] = {
++	{   1, "ThrustMaster Millenium 3D Inceptor",	  6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy },
++	{   3, "ThrustMaster Rage 3D Gamepad",		  2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
++	{   4, "ThrustMaster Attack Throttle",		  5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at },
++	{   8, "ThrustMaster FragMaster",		  4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm },
++	{ 163, "Thrustmaster Fusion GamePad",		  2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
++	{   0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }
++};
++
++
++struct tmdc_port {
++	struct input_dev *dev;
++	char name[64];
++	char phys[32];
++	int mode;
++	const signed char *abs;
++	const short *btn;
++	unsigned char absc;
++	unsigned char btnc[4];
++	unsigned char btno[4];
++};
++
+ struct tmdc {
+ 	struct gameport *gameport;
+-	struct input_dev dev[2];
++	struct tmdc_port *port[2];
++#if 0
++	struct input_dev *dev[2];
+ 	char name[2][64];
+ 	char phys[2][32];
+ 	int mode[2];
+@@ -102,6 +136,7 @@ struct tmdc {
+ 	unsigned char absc[2];
+ 	unsigned char btnc[2][4];
+ 	unsigned char btno[2][4];
++#endif
+ 	int reads;
+ 	int bads;
+ 	unsigned char exists;
+@@ -156,6 +191,50 @@ static int tmdc_read_packet(struct gamep
+ 	return (i[0] == TMDC_MAX_LENGTH) | ((i[1] == TMDC_MAX_LENGTH) << 1);
+ }
+ 
++static int tmdc_parse_packet(struct tmdc_port *port, unsigned char *data)
++{
++	int i, k, l;
++
++	if (data[TMDC_BYTE_ID] != port->mode)
++		return -1;
++
++	for (i = 0; i < port->absc; i++) {
++		if (port->abs[i] < 0)
++			return 0;
++
++		input_report_abs(port->dev, port->abs[i], data[tmdc_byte_a[i]]);
++	}
++
++	switch (port->mode) {
++
++		case TMDC_MODE_M3DI:
++
++			i = tmdc_byte_d[0];
++			input_report_abs(port->dev, ABS_HAT0X, ((data[i] >> 3) & 1) - ((data[i] >> 1) & 1));
++			input_report_abs(port->dev, ABS_HAT0Y, ((data[i] >> 2) & 1) - ( data[i]       & 1));
++			break;
++
++		case TMDC_MODE_AT:
++
++			i = tmdc_byte_a[3];
++			input_report_abs(port->dev, ABS_HAT0X, tmdc_hat_to_axis[(data[i] - 141) / 25].x);
++			input_report_abs(port->dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[i] - 141) / 25].y);
++			break;
++
++	}
++
++	for (k = l = 0; k < 4; k++) {
++		for (i = 0; i < port->btnc[k]; i++)
++			input_report_key(port->dev, port->btn[i + l],
++				((data[tmdc_byte_d[k]] >> (i + port->btno[k])) & 1));
++		l += port->btnc[k];
++	}
++
++	input_sync(port->dev);
++
++	return 0;
++}
++
+ /*
+  * tmdc_poll() reads and analyzes ThrustMaster joystick data.
+  */
+@@ -164,57 +243,21 @@ static void tmdc_poll(struct gameport *g
+ {
+ 	unsigned char data[2][TMDC_MAX_LENGTH];
+ 	struct tmdc *tmdc = gameport_get_drvdata(gameport);
+-	struct input_dev *dev;
+ 	unsigned char r, bad = 0;
+-	int i, j, k, l;
++	int i;
+ 
+ 	tmdc->reads++;
+ 
+ 	if ((r = tmdc_read_packet(tmdc->gameport, data)) != tmdc->exists)
+ 		bad = 1;
+-	else
+-
+-	for (j = 0; j < 2; j++)
+-		if (r & (1 << j) & tmdc->exists) {
+-
+-			if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) {
+-				bad = 1;
+-				continue;
+-			}
+-
+-			dev = tmdc->dev + j;
++	else {
++		for (i = 0; i < 2; i++) {
++			if (r & (1 << i) & tmdc->exists) {
+ 
+-			for (i = 0; i < tmdc->absc[j]; i++) {
+-				if (tmdc->abs[j][i] < 0) continue;
+-				input_report_abs(dev, tmdc->abs[j][i], data[j][tmdc_byte_a[i]]);
++				if (tmdc_parse_packet(tmdc->port[i], data[i]))
++					bad = 1;
+ 			}
+-
+-			switch (tmdc->mode[j]) {
+-
+-				case TMDC_MODE_M3DI:
+-
+-					i = tmdc_byte_d[0];
+-					input_report_abs(dev, ABS_HAT0X, ((data[j][i] >> 3) & 1) - ((data[j][i] >> 1) & 1));
+-					input_report_abs(dev, ABS_HAT0Y, ((data[j][i] >> 2) & 1) - ( data[j][i]       & 1));
+-					break;
+-
+-				case TMDC_MODE_AT:
+-
+-					i = tmdc_byte_a[3];
+-					input_report_abs(dev, ABS_HAT0X, tmdc_hat_to_axis[(data[j][i] - 141) / 25].x);
+-					input_report_abs(dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[j][i] - 141) / 25].y);
+-					break;
+-
+-			}
+-
+-			for (k = l = 0; k < 4; k++) {
+-				for (i = 0; i < tmdc->btnc[j][k]; i++)
+-					input_report_key(dev, tmdc->btn[j][i + l],
+-						((data[j][tmdc_byte_d[k]] >> (i + tmdc->btno[j][k])) & 1));
+-				l += tmdc->btnc[j][k];
+-			}
+-
+-			input_sync(dev);
++		}
+ 	}
+ 
+ 	tmdc->bads += bad;
+@@ -235,31 +278,89 @@ static void tmdc_close(struct input_dev 
+ 	gameport_stop_polling(tmdc->gameport);
+ }
+ 
++static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data)
++{
++	const struct tmdc_model *model;
++	struct tmdc_port *port;
++	struct input_dev *input_dev;
++	int i, j, b = 0;
++
++	tmdc->port[idx] = port = kzalloc(sizeof (struct tmdc_port), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!port || !input_dev) {
++		kfree(port);
++		input_free_device(input_dev);
++		return -ENOMEM;
++	}
++
++	port->mode = data[TMDC_BYTE_ID];
++
++	for (model = tmdc_models; model->id && model->id != port->mode; model++)
++		/* empty */;
++
++	port->abs = model->axes;
++	port->btn = model->buttons;
++
++	if (!model->id) {
++		port->absc = data[TMDC_BYTE_DEF] >> 4;
++		for (i = 0; i < 4; i++)
++			port->btnc[i] = i < (data[TMDC_BYTE_DEF] & 0xf) ? 8 : 0;
++	} else {
++		port->absc = model->abs;
++		for (i = 0; i < 4; i++)
++			port->btnc[i] = model->btnc[i];
++	}
++
++	for (i = 0; i < 4; i++)
++		port->btno[i] = model->btno[i];
++
++	snprintf(port->name, sizeof(port->name), model->name,
++		 port->absc, (data[TMDC_BYTE_DEF] & 0xf) << 3, port->mode);
++	snprintf(port->phys, sizeof(port->phys), "%s/input%d", tmdc->gameport->phys, i);
++
++	port->dev = input_dev;
++
++	input_dev->name = port->name;
++	input_dev->phys = port->phys;
++	input_dev->id.bustype = BUS_GAMEPORT;
++	input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER;
++	input_dev->id.product = model->id;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &tmdc->gameport->dev;
++	input_dev->private = tmdc;
++
++	input_dev->open = tmdc_open;
++	input_dev->close = tmdc_close;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++
++	for (i = 0; i < port->absc && i < TMDC_ABS; i++)
++		if (port->abs[i] >= 0)
++			input_set_abs_params(input_dev, port->abs[i], 8, 248, 2, 4);
++
++	for (i = 0; i < model->hats && i < TMDC_ABS_HAT; i++)
++		input_set_abs_params(input_dev, tmdc_abs_hat[i], -1, 1, 0, 0);
++
++	for (i = 0; i < 4; i++) {
++		for (j = 0; j < port->btnc[i] && j < TMDC_BTN; j++)
++			set_bit(port->btn[j + b], input_dev->keybit);
++		b += port->btnc[i];
++	}
++
++	input_register_device(port->dev);
++
++	return 0;
++}
++
+ /*
+  * tmdc_probe() probes for ThrustMaster type joysticks.
+  */
+ 
+ static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv)
+ {
+-	static struct models {
+-		unsigned char id;
+-		char *name;
+-		char abs;
+-		char hats;
+-		char btnc[4];
+-		char btno[4];
+-		signed char *axes;
+-		short *buttons;
+-	} models[] = {	{   1, "ThrustMaster Millenium 3D Inceptor",	  6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy },
+-			{   3, "ThrustMaster Rage 3D Gamepad",		  2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
+-			{   4, "ThrustMaster Attack Throttle",		  5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at },
+-			{   8, "ThrustMaster FragMaster",		  4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm },
+-			{ 163, "Thrustmaster Fusion GamePad",		  2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
+-			{   0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }};
+-
+ 	unsigned char data[2][TMDC_MAX_LENGTH];
+ 	struct tmdc *tmdc;
+-	int i, j, k, l, m;
++	int i;
+ 	int err;
+ 
+ 	if (!(tmdc = kzalloc(sizeof(struct tmdc), GFP_KERNEL)))
+@@ -281,68 +382,25 @@ static int tmdc_connect(struct gameport 
+ 	gameport_set_poll_handler(gameport, tmdc_poll);
+ 	gameport_set_poll_interval(gameport, 20);
+ 
+-	for (j = 0; j < 2; j++)
+-		if (tmdc->exists & (1 << j)) {
+-
+-			tmdc->mode[j] = data[j][TMDC_BYTE_ID];
+-
+-			for (m = 0; models[m].id && models[m].id != tmdc->mode[j]; m++);
++	for (i = 0; i < 2; i++) {
++		if (tmdc->exists & (1 << i)) {
+ 
+-			tmdc->abs[j] = models[m].axes;
+-			tmdc->btn[j] = models[m].buttons;
+-
+-			if (!models[m].id) {
+-				models[m].abs = data[j][TMDC_BYTE_DEF] >> 4;
+-				for (k = 0; k < 4; k++)
+-					models[m].btnc[k] = k < (data[j][TMDC_BYTE_DEF] & 0xf) ? 8 : 0;
+-			}
+-
+-			tmdc->absc[j] = models[m].abs;
+-			for (k = 0; k < 4; k++) {
+-				tmdc->btnc[j][k] = models[m].btnc[k];
+-				tmdc->btno[j][k] = models[m].btno[k];
+-			}
+-
+-			sprintf(tmdc->name[j], models[m].name, models[m].abs,
+-				(data[j][TMDC_BYTE_DEF] & 0xf) << 3, tmdc->mode[j]);
+-
+-			sprintf(tmdc->phys[j], "%s/input%d", gameport->phys, j);
+-
+-			tmdc->dev[j].private = tmdc;
+-			tmdc->dev[j].open = tmdc_open;
+-			tmdc->dev[j].close = tmdc_close;
+-
+-			tmdc->dev[j].name = tmdc->name[j];
+-			tmdc->dev[j].phys = tmdc->phys[j];
+-			tmdc->dev[j].id.bustype = BUS_GAMEPORT;
+-			tmdc->dev[j].id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER;
+-			tmdc->dev[j].id.product = models[m].id;
+-			tmdc->dev[j].id.version = 0x0100;
+-
+-			tmdc->dev[j].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-
+-			for (i = 0; i < models[m].abs && i < TMDC_ABS; i++)
+-				if (tmdc->abs[j][i] >= 0)
+-					input_set_abs_params(&tmdc->dev[j], tmdc->abs[j][i], 8, 248, 2, 4);
+-
+-			for (i = 0; i < models[m].hats && i < TMDC_ABS_HAT; i++)
+-				input_set_abs_params(&tmdc->dev[j], tmdc_abs_hat[i], -1, 1, 0, 0);
+-
+-
+-			for (k = l = 0; k < 4; k++) {
+-				for (i = 0; i < models[m].btnc[k] && i < TMDC_BTN; i++)
+-					set_bit(tmdc->btn[j][i + l], tmdc->dev[j].keybit);
+-				l += models[m].btnc[k];
+-			}
+-
+-			input_register_device(tmdc->dev + j);
+-			printk(KERN_INFO "input: %s on %s\n", tmdc->name[j], gameport->phys);
++			err = tmdc_setup_port(tmdc, i, data[i]);
++			if (err)
++				goto fail3;
+ 		}
++	}
+ 
+ 	return 0;
+ 
+-fail2:	gameport_close(gameport);
+-fail1:	gameport_set_drvdata(gameport, NULL);
++ fail3: while (--i >= 0) {
++		if (tmdc->port[i]) {
++			input_unregister_device(tmdc->port[i]->dev);
++			kfree(tmdc->port[i]);
++		}
++	}
++ fail2:	gameport_close(gameport);
++ fail1:	gameport_set_drvdata(gameport, NULL);
+ 	kfree(tmdc);
+ 	return err;
+ }
+@@ -352,9 +410,12 @@ static void tmdc_disconnect(struct gamep
+ 	struct tmdc *tmdc = gameport_get_drvdata(gameport);
+ 	int i;
+ 
+-	for (i = 0; i < 2; i++)
+-		if (tmdc->exists & (1 << i))
+-			input_unregister_device(tmdc->dev + i);
++	for (i = 0; i < 2; i++) {
++		if (tmdc->port[i]) {
++			input_unregister_device(tmdc->port[i]->dev);
++			kfree(tmdc->port[i]);
++		}
++	}
+ 	gameport_close(gameport);
+ 	gameport_set_drvdata(gameport, NULL);
+ 	kfree(tmdc);
+diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
+--- a/drivers/input/joystick/turbografx.c
++++ b/drivers/input/joystick/turbografx.c
+@@ -42,19 +42,21 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech at u
+ MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
+ MODULE_LICENSE("GPL");
+ 
+-static int tgfx[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
+-static int tgfx_nargs __initdata = 0;
+-module_param_array_named(map, tgfx, int, &tgfx_nargs, 0);
+-MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
++#define TGFX_MAX_PORTS		3
++#define TGFX_MAX_DEVICES	7
+ 
+-static int tgfx_2[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
+-static int tgfx_nargs_2 __initdata = 0;
+-module_param_array_named(map2, tgfx_2, int, &tgfx_nargs_2, 0);
+-MODULE_PARM_DESC(map2, "Describes second set of devices");
++struct tgfx_config {
++	int args[TGFX_MAX_DEVICES + 1];
++	int nargs;
++};
++
++static struct tgfx_config tgfx[TGFX_MAX_PORTS] __initdata;
+ 
+-static int tgfx_3[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
+-static int tgfx_nargs_3 __initdata = 0;
+-module_param_array_named(map3, tgfx_3, int, &tgfx_nargs_3, 0);
++module_param_array_named(map, tgfx[0].args, int, &tgfx[0].nargs, 0);
++MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
++module_param_array_named(map2, tgfx[1].args, int, &tgfx[1].nargs, 0);
++MODULE_PARM_DESC(map2, "Describes second set of devices");
++module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0);
+ MODULE_PARM_DESC(map3, "Describes third set of devices");
+ 
+ __obsolete_setup("tgfx=");
+@@ -75,17 +77,17 @@ __obsolete_setup("tgfx_3=");
+ #define TGFX_TOP2		0x08
+ 
+ static int tgfx_buttons[] = { BTN_TRIGGER, BTN_THUMB, BTN_THUMB2, BTN_TOP, BTN_TOP2 };
+-static char *tgfx_name = "TurboGraFX Multisystem joystick";
+ 
+ static struct tgfx {
+ 	struct pardevice *pd;
+ 	struct timer_list timer;
+-	struct input_dev dev[7];
+-	char phys[7][32];
++	struct input_dev *dev[TGFX_MAX_DEVICES];
++	char name[TGFX_MAX_DEVICES][64];
++	char phys[TGFX_MAX_DEVICES][32];
+ 	int sticks;
+ 	int used;
+ 	struct semaphore sem;
+-} *tgfx_base[3];
++} *tgfx_base[TGFX_MAX_PORTS];
+ 
+ /*
+  * tgfx_timer() reads and analyzes TurboGraFX joystick data.
+@@ -100,7 +102,7 @@ static void tgfx_timer(unsigned long pri
+ 	for (i = 0; i < 7; i++)
+ 		if (tgfx->sticks & (1 << i)) {
+ 
+-			dev = tgfx->dev + i;
++			dev = tgfx->dev[i];
+ 
+ 			parport_write_data(tgfx->pd->port, ~(1 << i));
+ 			data1 = parport_read_status(tgfx->pd->port) ^ 0x7f;
+@@ -153,118 +155,165 @@ static void tgfx_close(struct input_dev 
+ 	up(&tgfx->sem);
+ }
+ 
++
++
+ /*
+  * tgfx_probe() probes for tg gamepads.
+  */
+ 
+-static struct tgfx __init *tgfx_probe(int *config, int nargs)
++static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
+ {
+ 	struct tgfx *tgfx;
++	struct input_dev *input_dev;
+ 	struct parport *pp;
++	struct pardevice *pd;
+ 	int i, j;
++	int err;
+ 
+-	if (config[0] < 0)
+-		return NULL;
+-
+-	if (nargs < 2) {
+-		printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
+-		return NULL;
+-	}
+-
+-	pp = parport_find_number(config[0]);
+-
++	pp = parport_find_number(parport);
+ 	if (!pp) {
+ 		printk(KERN_ERR "turbografx.c: no such parport\n");
+-		return NULL;
++		err = -EINVAL;
++		goto err_out;
+ 	}
+ 
+-	if (!(tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL))) {
+-		parport_put_port(pp);
+-		return NULL;
++	pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
++	if (!pd) {
++		printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
++		err = -EBUSY;
++		goto err_put_pp;
+ 	}
+ 
+-	init_MUTEX(&tgfx->sem);
+-
+-	tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+-
+-	parport_put_port(pp);
+-
+-	if (!tgfx->pd) {
+-		printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
+-		kfree(tgfx);
+-		return NULL;
++	tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL);
++	if (!tgfx) {
++		printk(KERN_ERR "turbografx.c: Not enough memory\n");
++		err = -ENOMEM;
++		goto err_unreg_pardev;
+ 	}
+ 
++	init_MUTEX(&tgfx->sem);
++	tgfx->pd = pd;
+ 	init_timer(&tgfx->timer);
+ 	tgfx->timer.data = (long) tgfx;
+ 	tgfx->timer.function = tgfx_timer;
+ 
+-	tgfx->sticks = 0;
+-
+-	for (i = 0; i < nargs - 1; i++)
+-		if (config[i+1] > 0 && config[i+1] < 6) {
+-
+-			tgfx->sticks |= (1 << i);
+-
+-			tgfx->dev[i].private = tgfx;
+-			tgfx->dev[i].open = tgfx_open;
+-			tgfx->dev[i].close = tgfx_close;
+-
+-			sprintf(tgfx->phys[i], "%s/input0", tgfx->pd->port->name);
+-
+-			tgfx->dev[i].name = tgfx_name;
+-			tgfx->dev[i].phys = tgfx->phys[i];
+-			tgfx->dev[i].id.bustype = BUS_PARPORT;
+-			tgfx->dev[i].id.vendor = 0x0003;
+-			tgfx->dev[i].id.product = config[i+1];
+-			tgfx->dev[i].id.version = 0x0100;
++	for (i = 0; i < n_devs; i++) {
++		if (n_buttons[i] < 1)
++			continue;
++
++		if (n_buttons[i] > 6) {
++			printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]);
++			err = -EINVAL;
++			goto err_free_devs;
++		}
+ 
+-			tgfx->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-			tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
++		tgfx->dev[i] = input_dev = input_allocate_device();
++		if (!input_dev) {
++			printk(KERN_ERR "turbografx.c: Not enough memory for input device\n");
++			err = -ENOMEM;
++			goto err_free_devs;
++		}
+ 
+-			for (j = 0; j < config[i+1]; j++)
+-				set_bit(tgfx_buttons[j], tgfx->dev[i].keybit);
++		tgfx->sticks |= (1 << i);
++		snprintf(tgfx->name[i], sizeof(tgfx->name[i]),
++			 "TurboGraFX %d-button Multisystem joystick", n_buttons[i]);
++		snprintf(tgfx->phys[i], sizeof(tgfx->phys[i]),
++			 "%s/input%d", tgfx->pd->port->name, i);
++
++		input_dev->name = tgfx->name[i];
++		input_dev->phys = tgfx->phys[i];
++		input_dev->id.bustype = BUS_PARPORT;
++		input_dev->id.vendor = 0x0003;
++		input_dev->id.product = n_buttons[i];
++		input_dev->id.version = 0x0100;
++
++		input_dev->private = tgfx;
++		input_dev->open = tgfx_open;
++		input_dev->close = tgfx_close;
++
++		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++		input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
++		input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
+ 
+-			tgfx->dev[i].absmin[ABS_X] = -1; tgfx->dev[i].absmax[ABS_X] = 1;
+-			tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1;
++		for (j = 0; j < n_buttons[i]; j++)
++			set_bit(tgfx_buttons[j], input_dev->keybit);
+ 
+-			input_register_device(tgfx->dev + i);
+-			printk(KERN_INFO "input: %d-button Multisystem joystick on %s\n",
+-				config[i+1], tgfx->pd->port->name);
+-		}
++		input_register_device(tgfx->dev[i]);
++	}
+ 
+         if (!tgfx->sticks) {
+-		parport_unregister_device(tgfx->pd);
+-		kfree(tgfx);
+-		return NULL;
++		printk(KERN_ERR "turbografx.c: No valid devices specified\n");
++		err = -EINVAL;
++		goto err_free_tgfx;
+         }
+ 
+ 	return tgfx;
++
++ err_free_devs:
++	while (--i >= 0)
++		input_unregister_device(tgfx->dev[i]);
++ err_free_tgfx:
++	kfree(tgfx);
++ err_unreg_pardev:
++	parport_unregister_device(pd);
++ err_put_pp:
++	parport_put_port(pp);
++ err_out:
++	return ERR_PTR(err);
++}
++
++static void __exit tgfx_remove(struct tgfx *tgfx)
++{
++	int i;
++
++	for (i = 0; i < TGFX_MAX_DEVICES; i++)
++		if (tgfx->dev[i])
++			input_unregister_device(tgfx->dev[i]);
++	parport_unregister_device(tgfx->pd);
++	kfree(tgfx);
+ }
+ 
+ static int __init tgfx_init(void)
+ {
+-	tgfx_base[0] = tgfx_probe(tgfx, tgfx_nargs);
+-	tgfx_base[1] = tgfx_probe(tgfx_2, tgfx_nargs_2);
+-	tgfx_base[2] = tgfx_probe(tgfx_3, tgfx_nargs_3);
++	int i;
++	int have_dev = 0;
++	int err = 0;
++
++	for (i = 0; i < TGFX_MAX_PORTS; i++) {
++		if (tgfx[i].nargs == 0 || tgfx[i].args[0] < 0)
++			continue;
++
++		if (tgfx[i].nargs < 2) {
++			printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
++			err = -EINVAL;
++			break;
++		}
+ 
+-	if (tgfx_base[0] || tgfx_base[1] || tgfx_base[2])
+-		return 0;
++		tgfx_base[i] = tgfx_probe(tgfx[i].args[0], tgfx[i].args + 1, tgfx[i].nargs - 1);
++		if (IS_ERR(tgfx_base[i])) {
++			err = PTR_ERR(tgfx_base[i]);
++			break;
++		}
++
++		have_dev = 1;
++	}
+ 
+-	return -ENODEV;
++	if (err) {
++		while (--i >= 0)
++			tgfx_remove(tgfx_base[i]);
++		return err;
++	}
++
++	return have_dev ? 0 : -ENODEV;
+ }
+ 
+ static void __exit tgfx_exit(void)
+ {
+-	int i, j;
++	int i;
+ 
+-	for (i = 0; i < 3; i++)
+-		if (tgfx_base[i]) {
+-			for (j = 0; j < 7; j++)
+-				if (tgfx_base[i]->sticks & (1 << j))
+-					input_unregister_device(tgfx_base[i]->dev + j);
+-		parport_unregister_device(tgfx_base[i]->pd);
+-	}
++	for (i = 0; i < TGFX_MAX_PORTS; i++)
++		if (tgfx_base[i])
++			tgfx_remove(tgfx_base[i]);
+ }
+ 
+ module_init(tgfx_init);
+diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
+--- a/drivers/input/joystick/twidjoy.c
++++ b/drivers/input/joystick/twidjoy.c
+@@ -69,8 +69,6 @@ MODULE_LICENSE("GPL");
+ 
+ #define TWIDJOY_MAX_LENGTH 5
+ 
+-static char *twidjoy_name = "Handykey Twiddler";
+-
+ static struct twidjoy_button_spec {
+ 	int bitshift;
+ 	int bitmask;
+@@ -95,7 +93,7 @@ twidjoy_buttons[] = {
+  */
+ 
+ struct twidjoy {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	int idx;
+ 	unsigned char data[TWIDJOY_MAX_LENGTH];
+ 	char phys[32];
+@@ -108,37 +106,33 @@ struct twidjoy {
+ 
+ static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs)
+ {
+-	if (twidjoy->idx == TWIDJOY_MAX_LENGTH) {
+-		struct input_dev *dev = &twidjoy->dev;
+-		unsigned char *data = twidjoy->data;
+-		struct twidjoy_button_spec *bp;
+-		int button_bits, abs_x, abs_y;
+-
+-		button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
++	struct input_dev *dev = twidjoy->dev;
++	unsigned char *data = twidjoy->data;
++	struct twidjoy_button_spec *bp;
++	int button_bits, abs_x, abs_y;
+ 
+-		input_regs(dev, regs);
++	button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
+ 
+-		for (bp = twidjoy_buttons; bp->bitmask; bp++) {
+-			int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
+-			int i;
++	input_regs(dev, regs);
+ 
+-			for (i = 0; i < bp->bitmask; i++)
+-				input_report_key(dev, bp->buttons[i], i+1 == value);
+-		}
++	for (bp = twidjoy_buttons; bp->bitmask; bp++) {
++		int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
++		int i;
+ 
+-		abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
+-		if (data[4] & 0x08) abs_x -= 256;
++		for (i = 0; i < bp->bitmask; i++)
++			input_report_key(dev, bp->buttons[i], i+1 == value);
++	}
+ 
+-		abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
+-		if (data[3] & 0x02) abs_y -= 256;
++	abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
++	if (data[4] & 0x08) abs_x -= 256;
+ 
+-		input_report_abs(dev, ABS_X, -abs_x);
+-		input_report_abs(dev, ABS_Y, +abs_y);
++	abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
++	if (data[3] & 0x02) abs_y -= 256;
+ 
+-		input_sync(dev);
+-	}
++	input_report_abs(dev, ABS_X, -abs_x);
++	input_report_abs(dev, ABS_Y, +abs_y);
+ 
+-	return;
++	input_sync(dev);
+ }
+ 
+ /*
+@@ -179,9 +173,9 @@ static void twidjoy_disconnect(struct se
+ {
+ 	struct twidjoy *twidjoy = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&twidjoy->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(twidjoy->dev);
+ 	kfree(twidjoy);
+ }
+ 
+@@ -195,59 +189,49 @@ static int twidjoy_connect(struct serio 
+ {
+ 	struct twidjoy_button_spec *bp;
+ 	struct twidjoy *twidjoy;
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
+ 	int i;
+-	int err;
+-
+-	if (!(twidjoy = kmalloc(sizeof(struct twidjoy), GFP_KERNEL)))
+-		return -ENOMEM;
+ 
+-	memset(twidjoy, 0, sizeof(struct twidjoy));
++	twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!twidjoy || !input_dev)
++		goto fail;
+ 
++	twidjoy->dev = input_dev;
+ 	sprintf(twidjoy->phys, "%s/input0", serio->phys);
+ 
+-	init_input_dev(&twidjoy->dev);
+-	twidjoy->dev.name = twidjoy_name;
+-	twidjoy->dev.phys = twidjoy->phys;
+-	twidjoy->dev.id.bustype = BUS_RS232;
+-	twidjoy->dev.id.vendor = SERIO_TWIDJOY;
+-	twidjoy->dev.id.product = 0x0001;
+-	twidjoy->dev.id.version = 0x0100;
+-	twidjoy->dev.dev = &serio->dev;
++	input_dev->name = "Handykey Twiddler";
++	input_dev->phys = twidjoy->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_TWIDJOY;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = twidjoy;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
++	input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4);
++	input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4);
+ 
+-	twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-
+-	for (bp = twidjoy_buttons; bp->bitmask; bp++) {
++	for (bp = twidjoy_buttons; bp->bitmask; bp++)
+ 		for (i = 0; i < bp->bitmask; i++)
+-			set_bit(bp->buttons[i], twidjoy->dev.keybit);
+-	}
+-
+-	twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+-
+-	for (i = 0; i < 2; i++) {
+-		twidjoy->dev.absmax[ABS_X+i] =  50;
+-		twidjoy->dev.absmin[ABS_X+i] = -50;
+-
+-		/* TODO: arndt 20010708: Are these values appropriate? */
+-		twidjoy->dev.absfuzz[ABS_X+i] = 4;
+-		twidjoy->dev.absflat[ABS_X+i] = 4;
+-	}
+-
+-	twidjoy->dev.private = twidjoy;
++			set_bit(bp->buttons[i], input_dev->keybit);
+ 
+ 	serio_set_drvdata(serio, twidjoy);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(twidjoy);
+-		return err;
+-	}
+-
+-	input_register_device(&twidjoy->dev);
+-
+-	printk(KERN_INFO "input: %s on %s\n", twidjoy_name, serio->phys);
++	if (err)
++		goto fail;
+ 
++	input_register_device(twidjoy->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(twidjoy);
++	return err;
+ }
+ 
+ /*
+diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
+--- a/drivers/input/joystick/warrior.c
++++ b/drivers/input/joystick/warrior.c
+@@ -47,14 +47,13 @@ MODULE_LICENSE("GPL");
+ 
+ #define WARRIOR_MAX_LENGTH	16
+ static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 };
+-static char *warrior_name = "Logitech WingMan Warrior";
+ 
+ /*
+  * Per-Warrior data.
+  */
+ 
+ struct warrior {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	int idx, len;
+ 	unsigned char data[WARRIOR_MAX_LENGTH];
+ 	char phys[32];
+@@ -67,7 +66,7 @@ struct warrior {
+ 
+ static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &warrior->dev;
++	struct input_dev *dev = warrior->dev;
+ 	unsigned char *data = warrior->data;
+ 
+ 	if (!warrior->idx) return;
+@@ -131,9 +130,9 @@ static void warrior_disconnect(struct se
+ {
+ 	struct warrior *warrior = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&warrior->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(warrior->dev);
+ 	kfree(warrior);
+ }
+ 
+@@ -146,60 +145,48 @@ static void warrior_disconnect(struct se
+ static int warrior_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct warrior *warrior;
+-	int i;
+-	int err;
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
+ 
+-	if (!(warrior = kmalloc(sizeof(struct warrior), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset(warrior, 0, sizeof(struct warrior));
+-
+-	warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
+-	warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
+-	warrior->dev.relbit[0] = BIT(REL_DIAL);
+-	warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y);
++	warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!warrior || !input_dev)
++		goto fail;
+ 
++	warrior->dev = input_dev;
+ 	sprintf(warrior->phys, "%s/input0", serio->phys);
+ 
+-	init_input_dev(&warrior->dev);
+-	warrior->dev.name = warrior_name;
+-	warrior->dev.phys = warrior->phys;
+-	warrior->dev.id.bustype = BUS_RS232;
+-	warrior->dev.id.vendor = SERIO_WARRIOR;
+-	warrior->dev.id.product = 0x0001;
+-	warrior->dev.id.version = 0x0100;
+-	warrior->dev.dev = &serio->dev;
+-
+-	for (i = 0; i < 2; i++) {
+-		warrior->dev.absmax[ABS_X+i] = -64;
+-		warrior->dev.absmin[ABS_X+i] =  64;
+-		warrior->dev.absflat[ABS_X+i] = 8;
+-	}
+-
+-	warrior->dev.absmax[ABS_THROTTLE] = -112;
+-	warrior->dev.absmin[ABS_THROTTLE] =  112;
+-
+-	for (i = 0; i < 2; i++) {
+-		warrior->dev.absmax[ABS_HAT0X+i] = -1;
+-		warrior->dev.absmin[ABS_HAT0X+i] =  1;
+-	}
+-
+-	warrior->dev.private = warrior;
++	input_dev->name = "Logitech WingMan Warrior";
++	input_dev->phys = warrior->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_WARRIOR;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = warrior;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
++	input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
++	input_dev->relbit[0] = BIT(REL_DIAL);
++	input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8);
++	input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8);
++	input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0);
++	input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
++	input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
+ 
+ 	serio_set_drvdata(serio, warrior);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(warrior);
+-		return err;
+-	}
+-
+-	input_register_device(&warrior->dev);
+-
+-	printk(KERN_INFO "input: Logitech WingMan Warrior on %s\n", serio->phys);
++	if (err)
++		goto fail;
+ 
++	input_register_device(warrior->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(warrior);
++	return err;
+ }
+ 
+ /*
+diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
+--- a/drivers/input/keyboard/Kconfig
++++ b/drivers/input/keyboard/Kconfig
+@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD
+ if INPUT_KEYBOARD
+ 
+ config KEYBOARD_ATKBD
+-	tristate "AT keyboard" if !PC
++	tristate "AT keyboard" if !X86_PC
+ 	default y
+ 	select SERIO
+ 	select SERIO_LIBPS2
+-	select SERIO_I8042 if PC
++	select SERIO_I8042 if X86_PC
+ 	select SERIO_GSCPS2 if GSC
+ 	help
+ 	  Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
+diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
+--- a/drivers/input/keyboard/amikbd.c
++++ b/drivers/input/keyboard/amikbd.c
+@@ -155,10 +155,7 @@ static const char *amikbd_messages[8] = 
+ 	[7] = KERN_WARNING "amikbd: keyboard interrupt\n"
+ };
+ 
+-static struct input_dev amikbd_dev;
+-
+-static char *amikbd_name = "Amiga keyboard";
+-static char *amikbd_phys = "amikbd/input0";
++static struct input_dev *amikbd_dev;
+ 
+ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
+ {
+@@ -176,16 +173,16 @@ static irqreturn_t amikbd_interrupt(int 
+ 
+ 		scancode = amikbd_keycode[scancode];
+ 
+-		input_regs(&amikbd_dev, fp);
++		input_regs(amikbd_dev, fp);
+ 
+ 		if (scancode == KEY_CAPSLOCK) {	/* CapsLock is a toggle switch key on Amiga */
+-			input_report_key(&amikbd_dev, scancode, 1);
+-			input_report_key(&amikbd_dev, scancode, 0);
+-			input_sync(&amikbd_dev);
++			input_report_key(amikbd_dev, scancode, 1);
++			input_report_key(amikbd_dev, scancode, 0);
+ 		} else {
+-			input_report_key(&amikbd_dev, scancode, down);
+-			input_sync(&amikbd_dev);
++			input_report_key(amikbd_dev, scancode, down);
+ 		}
++
++		input_sync(amikbd_dev);
+ 	} else				/* scancodes >= 0x78 are error codes */
+ 		printk(amikbd_messages[scancode - 0x78]);
+ 
+@@ -202,39 +199,41 @@ static int __init amikbd_init(void)
+ 	if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
+ 		return -EBUSY;
+ 
+-	init_input_dev(&amikbd_dev);
+-
+-	amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+-	amikbd_dev.keycode = amikbd_keycode;
+-	amikbd_dev.keycodesize = sizeof(unsigned char);
+-	amikbd_dev.keycodemax = ARRAY_SIZE(amikbd_keycode);
++	amikbd_dev = input_allocate_device();
++	if (!amikbd_dev) {
++		printk(KERN_ERR "amikbd: not enough memory for input device\n");
++		release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
++		return -ENOMEM;
++	}
++
++	amikbd_dev->name = "Amiga Keyboard";
++	amikbd_dev->phys = "amikbd/input0";
++	amikbd_dev->id.bustype = BUS_AMIGA;
++	amikbd_dev->id.vendor = 0x0001;
++	amikbd_dev->id.product = 0x0001;
++	amikbd_dev->id.version = 0x0100;
++
++	amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++	amikbd_dev->keycode = amikbd_keycode;
++	amikbd_dev->keycodesize = sizeof(unsigned char);
++	amikbd_dev->keycodemax = ARRAY_SIZE(amikbd_keycode);
+ 
+ 	for (i = 0; i < 0x78; i++)
+ 		if (amikbd_keycode[i])
+-			set_bit(amikbd_keycode[i], amikbd_dev.keybit);
++			set_bit(amikbd_keycode[i], amikbd_dev->keybit);
+ 
+ 	ciaa.cra &= ~0x41;	 /* serial data in, turn off TA */
+ 	request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt);
+ 
+-	amikbd_dev.name = amikbd_name;
+-	amikbd_dev.phys = amikbd_phys;
+-	amikbd_dev.id.bustype = BUS_AMIGA;
+-	amikbd_dev.id.vendor = 0x0001;
+-	amikbd_dev.id.product = 0x0001;
+-	amikbd_dev.id.version = 0x0100;
+-
+-	input_register_device(&amikbd_dev);
+-
+-	printk(KERN_INFO "input: %s\n", amikbd_name);
+-
++	input_register_device(amikbd_dev);
+ 	return 0;
+ }
+ 
+ static void __exit amikbd_exit(void)
+ {
+-	input_unregister_device(&amikbd_dev);
+ 	free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt);
+-	release_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100);
++	input_unregister_device(amikbd_dev);
++	release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
+ }
+ 
+ module_init(amikbd_init);
+diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
+--- a/drivers/input/keyboard/atkbd.c
++++ b/drivers/input/keyboard/atkbd.c
+@@ -185,12 +185,12 @@ static struct {
+ 
+ struct atkbd {
+ 
+-	struct ps2dev	ps2dev;
++	struct ps2dev ps2dev;
++	struct input_dev *dev;
+ 
+ 	/* Written only during init */
+ 	char name[64];
+ 	char phys[32];
+-	struct input_dev dev;
+ 
+ 	unsigned short id;
+ 	unsigned char keycode[512];
+@@ -290,7 +290,7 @@ static irqreturn_t atkbd_interrupt(struc
+ 	if (!atkbd->enabled)
+ 		goto out;
+ 
+-	input_event(&atkbd->dev, EV_MSC, MSC_RAW, code);
++	input_event(atkbd->dev, EV_MSC, MSC_RAW, code);
+ 
+ 	if (atkbd->translated) {
+ 
+@@ -326,10 +326,10 @@ static irqreturn_t atkbd_interrupt(struc
+ 			atkbd->release = 1;
+ 			goto out;
+ 		case ATKBD_RET_HANGUEL:
+-			atkbd_report_key(&atkbd->dev, regs, KEY_HANGUEL, 3);
++			atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3);
+ 			goto out;
+ 		case ATKBD_RET_HANJA:
+-			atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3);
++			atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3);
+ 			goto out;
+ 		case ATKBD_RET_ERR:
+ 			printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+@@ -345,7 +345,7 @@ static irqreturn_t atkbd_interrupt(struc
+ 	}
+ 
+ 	if (atkbd->keycode[code] != ATKBD_KEY_NULL)
+-		input_event(&atkbd->dev, EV_MSC, MSC_SCAN, code);
++		input_event(atkbd->dev, EV_MSC, MSC_SCAN, code);
+ 
+ 	switch (atkbd->keycode[code]) {
+ 		case ATKBD_KEY_NULL:
+@@ -365,7 +365,7 @@ static irqreturn_t atkbd_interrupt(struc
+ 				       "to make it known.\n",
+ 				       code & 0x80 ? "e0" : "", code & 0x7f);
+ 			}
+-			input_sync(&atkbd->dev);
++			input_sync(atkbd->dev);
+ 			break;
+ 		case ATKBD_SCR_1:
+ 			scroll = 1 - atkbd->release * 2;
+@@ -390,7 +390,7 @@ static irqreturn_t atkbd_interrupt(struc
+ 			break;
+ 		default:
+ 			value = atkbd->release ? 0 :
+-				(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
++				(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev->key)));
+ 
+ 			switch (value) {	/* Workaround Toshiba laptop multiple keypress */
+ 				case 0:
+@@ -398,7 +398,7 @@ static irqreturn_t atkbd_interrupt(struc
+ 					break;
+ 				case 1:
+ 					atkbd->last = code;
+-					atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev.rep[REP_DELAY]) / 2;
++					atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev->rep[REP_DELAY]) / 2;
+ 					break;
+ 				case 2:
+ 					if (!time_after(jiffies, atkbd->time) && atkbd->last == code)
+@@ -406,16 +406,16 @@ static irqreturn_t atkbd_interrupt(struc
+ 					break;
+ 			}
+ 
+-			atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value);
++			atkbd_report_key(atkbd->dev, regs, atkbd->keycode[code], value);
+ 	}
+ 
+ 	if (atkbd->scroll) {
+-		input_regs(&atkbd->dev, regs);
++		input_regs(atkbd->dev, regs);
+ 		if (click != -1)
+-			input_report_key(&atkbd->dev, BTN_MIDDLE, click);
+-		input_report_rel(&atkbd->dev, REL_WHEEL, scroll);
+-		input_report_rel(&atkbd->dev, REL_HWHEEL, hscroll);
+-		input_sync(&atkbd->dev);
++			input_report_key(atkbd->dev, BTN_MIDDLE, click);
++		input_report_rel(atkbd->dev, REL_WHEEL, scroll);
++		input_report_rel(atkbd->dev, REL_HWHEEL, hscroll);
++		input_sync(atkbd->dev);
+ 	}
+ 
+ 	atkbd->release = 0;
+@@ -463,7 +463,6 @@ static int atkbd_event(struct input_dev 
+ 
+ 			return 0;
+ 
+-
+ 		case EV_REP:
+ 
+ 			if (atkbd->softrepeat) return 0;
+@@ -693,7 +692,7 @@ static void atkbd_disconnect(struct seri
+ 	device_remove_file(&serio->dev, &atkbd_attr_softrepeat);
+ 	device_remove_file(&serio->dev, &atkbd_attr_softraw);
+ 
+-	input_unregister_device(&atkbd->dev);
++	input_unregister_device(atkbd->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
+ 	kfree(atkbd);
+@@ -701,7 +700,7 @@ static void atkbd_disconnect(struct seri
+ 
+ 
+ /*
+- * atkbd_set_device_attrs() initializes keyboard's keycode table
++ * atkbd_set_keycode_table() initializes keyboard's keycode table
+  * according to the selected scancode set
+  */
+ 
+@@ -737,53 +736,58 @@ static void atkbd_set_keycode_table(stru
+ 
+ static void atkbd_set_device_attrs(struct atkbd *atkbd)
+ {
++	struct input_dev *input_dev = atkbd->dev;
+ 	int i;
+ 
+-	memset(&atkbd->dev, 0, sizeof(struct input_dev));
++	if (atkbd->extra)
++		sprintf(atkbd->name, "AT Set 2 Extra keyboard");
++	else
++		sprintf(atkbd->name, "AT %s Set %d keyboard",
++			atkbd->translated ? "Translated" : "Raw", atkbd->set);
+ 
+-	init_input_dev(&atkbd->dev);
++	sprintf(atkbd->phys, "%s/input0", atkbd->ps2dev.serio->phys);
+ 
+-	atkbd->dev.name = atkbd->name;
+-	atkbd->dev.phys = atkbd->phys;
+-	atkbd->dev.id.bustype = BUS_I8042;
+-	atkbd->dev.id.vendor = 0x0001;
+-	atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set;
+-	atkbd->dev.id.version = atkbd->id;
+-	atkbd->dev.event = atkbd_event;
+-	atkbd->dev.private = atkbd;
+-	atkbd->dev.dev = &atkbd->ps2dev.serio->dev;
++	input_dev->name = atkbd->name;
++	input_dev->phys = atkbd->phys;
++	input_dev->id.bustype = BUS_I8042;
++	input_dev->id.vendor = 0x0001;
++	input_dev->id.product = atkbd->translated ? 1 : atkbd->set;
++	input_dev->id.version = atkbd->id;
++	input_dev->event = atkbd_event;
++	input_dev->private = atkbd;
++	input_dev->cdev.dev = &atkbd->ps2dev.serio->dev;
+ 
+-	atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
+ 
+ 	if (atkbd->write) {
+-		atkbd->dev.evbit[0] |= BIT(EV_LED);
+-		atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
++		input_dev->evbit[0] |= BIT(EV_LED);
++		input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+ 	}
+ 
+ 	if (atkbd->extra)
+-		atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
++		input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
+ 					BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
+ 
+ 	if (!atkbd->softrepeat) {
+-		atkbd->dev.rep[REP_DELAY] = 250;
+-		atkbd->dev.rep[REP_PERIOD] = 33;
++		input_dev->rep[REP_DELAY] = 250;
++		input_dev->rep[REP_PERIOD] = 33;
+ 	}
+ 
+-	atkbd->dev.mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
++	input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
+ 
+ 	if (atkbd->scroll) {
+-		atkbd->dev.evbit[0] |= BIT(EV_REL);
+-		atkbd->dev.relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
+-		set_bit(BTN_MIDDLE, atkbd->dev.keybit);
++		input_dev->evbit[0] |= BIT(EV_REL);
++		input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
++		set_bit(BTN_MIDDLE, input_dev->keybit);
+ 	}
+ 
+-	atkbd->dev.keycode = atkbd->keycode;
+-	atkbd->dev.keycodesize = sizeof(unsigned char);
+-	atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
++	input_dev->keycode = atkbd->keycode;
++	input_dev->keycodesize = sizeof(unsigned char);
++	input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
+ 
+ 	for (i = 0; i < 512; i++)
+ 		if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
+-			set_bit(atkbd->keycode[i], atkbd->dev.keybit);
++			set_bit(atkbd->keycode[i], input_dev->keybit);
+ }
+ 
+ /*
+@@ -796,13 +800,15 @@ static void atkbd_set_device_attrs(struc
+ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct atkbd *atkbd;
+-	int err;
+-
+-	if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
+-		return - ENOMEM;
++	struct input_dev *dev;
++	int err = -ENOMEM;
+ 
+-	memset(atkbd, 0, sizeof(struct atkbd));
++	atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL);
++	dev = input_allocate_device();
++	if (!atkbd || !dev)
++		goto fail;
+ 
++	atkbd->dev = dev;
+ 	ps2_init(&atkbd->ps2dev, serio);
+ 
+ 	switch (serio->id.type) {
+@@ -828,19 +834,15 @@ static int atkbd_connect(struct serio *s
+ 	serio_set_drvdata(serio, atkbd);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(atkbd);
+-		return err;
+-	}
++	if (err)
++		goto fail;
+ 
+ 	if (atkbd->write) {
+ 
+ 		if (atkbd_probe(atkbd)) {
+ 			serio_close(serio);
+-			serio_set_drvdata(serio, NULL);
+-			kfree(atkbd);
+-			return -ENODEV;
++			err = -ENODEV;
++			goto fail;
+ 		}
+ 
+ 		atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
+@@ -851,19 +853,9 @@ static int atkbd_connect(struct serio *s
+ 		atkbd->id = 0xab00;
+ 	}
+ 
+-	if (atkbd->extra)
+-		sprintf(atkbd->name, "AT Set 2 Extra keyboard");
+-	else
+-		sprintf(atkbd->name, "AT %s Set %d keyboard",
+-			atkbd->translated ? "Translated" : "Raw", atkbd->set);
+-
+-	sprintf(atkbd->phys, "%s/input0", serio->phys);
+-
+ 	atkbd_set_keycode_table(atkbd);
+ 	atkbd_set_device_attrs(atkbd);
+ 
+-	input_register_device(&atkbd->dev);
+-
+ 	device_create_file(&serio->dev, &atkbd_attr_extra);
+ 	device_create_file(&serio->dev, &atkbd_attr_scroll);
+ 	device_create_file(&serio->dev, &atkbd_attr_set);
+@@ -872,9 +864,14 @@ static int atkbd_connect(struct serio *s
+ 
+ 	atkbd_enable(atkbd);
+ 
+-	printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
++	input_register_device(atkbd->dev);
+ 
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(dev);
++	kfree(atkbd);
++	return err;
+ }
+ 
+ /*
+@@ -896,9 +893,9 @@ static int atkbd_reconnect(struct serio 
+ 	atkbd_disable(atkbd);
+ 
+ 	if (atkbd->write) {
+-		param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
+-		         | (test_bit(LED_NUML,    atkbd->dev.led) ? 2 : 0)
+-		         | (test_bit(LED_CAPSL,   atkbd->dev.led) ? 4 : 0);
++		param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0)
++		         | (test_bit(LED_NUML,    atkbd->dev->led) ? 2 : 0)
++		         | (test_bit(LED_CAPSL,   atkbd->dev->led) ? 4 : 0);
+ 
+ 		if (atkbd_probe(atkbd))
+ 			return -1;
+@@ -1008,6 +1005,7 @@ static ssize_t atkbd_show_extra(struct a
+ 
+ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count)
+ {
++	struct input_dev *new_dev;
+ 	unsigned long value;
+ 	char *rest;
+ 
+@@ -1019,12 +1017,19 @@ static ssize_t atkbd_set_extra(struct at
+ 		return -EINVAL;
+ 
+ 	if (atkbd->extra != value) {
+-		/* unregister device as it's properties will change */
+-		input_unregister_device(&atkbd->dev);
++		/*
++		 * Since device's properties will change we need to
++		 * unregister old device. But allocate new one first
++		 * to make sure we have it.
++		 */
++		if (!(new_dev = input_allocate_device()))
++			return -ENOMEM;
++		input_unregister_device(atkbd->dev);
++		atkbd->dev = new_dev;
+ 		atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
+ 		atkbd_activate(atkbd);
+ 		atkbd_set_device_attrs(atkbd);
+-		input_register_device(&atkbd->dev);
++		input_register_device(atkbd->dev);
+ 	}
+ 	return count;
+ }
+@@ -1036,6 +1041,7 @@ static ssize_t atkbd_show_scroll(struct 
+ 
+ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count)
+ {
++	struct input_dev *new_dev;
+ 	unsigned long value;
+ 	char *rest;
+ 
+@@ -1044,12 +1050,14 @@ static ssize_t atkbd_set_scroll(struct a
+ 		return -EINVAL;
+ 
+ 	if (atkbd->scroll != value) {
+-		/* unregister device as it's properties will change */
+-		input_unregister_device(&atkbd->dev);
++		if (!(new_dev = input_allocate_device()))
++			return -ENOMEM;
++		input_unregister_device(atkbd->dev);
++		atkbd->dev = new_dev;
+ 		atkbd->scroll = value;
+ 		atkbd_set_keycode_table(atkbd);
+ 		atkbd_set_device_attrs(atkbd);
+-		input_register_device(&atkbd->dev);
++		input_register_device(atkbd->dev);
+ 	}
+ 	return count;
+ }
+@@ -1061,6 +1069,7 @@ static ssize_t atkbd_show_set(struct atk
+ 
+ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
+ {
++	struct input_dev *new_dev;
+ 	unsigned long value;
+ 	char *rest;
+ 
+@@ -1072,13 +1081,15 @@ static ssize_t atkbd_set_set(struct atkb
+ 		return -EINVAL;
+ 
+ 	if (atkbd->set != value) {
+-		/* unregister device as it's properties will change */
+-		input_unregister_device(&atkbd->dev);
++		if (!(new_dev = input_allocate_device()))
++			return -ENOMEM;
++		input_unregister_device(atkbd->dev);
++		atkbd->dev = new_dev;
+ 		atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra);
+ 		atkbd_activate(atkbd);
+ 		atkbd_set_keycode_table(atkbd);
+ 		atkbd_set_device_attrs(atkbd);
+-		input_register_device(&atkbd->dev);
++		input_register_device(atkbd->dev);
+ 	}
+ 	return count;
+ }
+@@ -1090,6 +1101,7 @@ static ssize_t atkbd_show_softrepeat(str
+ 
+ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count)
+ {
++	struct input_dev *new_dev;
+ 	unsigned long value;
+ 	char *rest;
+ 
+@@ -1101,15 +1113,16 @@ static ssize_t atkbd_set_softrepeat(stru
+ 		return -EINVAL;
+ 
+ 	if (atkbd->softrepeat != value) {
+-		/* unregister device as it's properties will change */
+-		input_unregister_device(&atkbd->dev);
++		if (!(new_dev = input_allocate_device()))
++			return -ENOMEM;
++		input_unregister_device(atkbd->dev);
++		atkbd->dev = new_dev;
+ 		atkbd->softrepeat = value;
+ 		if (atkbd->softrepeat)
+ 			atkbd->softraw = 1;
+ 		atkbd_set_device_attrs(atkbd);
+-		input_register_device(&atkbd->dev);
++		input_register_device(atkbd->dev);
+ 	}
+-
+ 	return count;
+ }
+ 
+@@ -1121,6 +1134,7 @@ static ssize_t atkbd_show_softraw(struct
+ 
+ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count)
+ {
++	struct input_dev *new_dev;
+ 	unsigned long value;
+ 	char *rest;
+ 
+@@ -1129,11 +1143,13 @@ static ssize_t atkbd_set_softraw(struct 
+ 		return -EINVAL;
+ 
+ 	if (atkbd->softraw != value) {
+-		/* unregister device as it's properties will change */
+-		input_unregister_device(&atkbd->dev);
++		if (!(new_dev = input_allocate_device()))
++			return -ENOMEM;
++		input_unregister_device(atkbd->dev);
++		atkbd->dev = new_dev;
+ 		atkbd->softraw = value;
+ 		atkbd_set_device_attrs(atkbd);
+-		input_register_device(&atkbd->dev);
++		input_register_device(atkbd->dev);
+ 	}
+ 	return count;
+ }
+diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
+--- a/drivers/input/keyboard/corgikbd.c
++++ b/drivers/input/keyboard/corgikbd.c
+@@ -12,7 +12,7 @@
+  */
+ 
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/init.h>
+ #include <linux/input.h>
+ #include <linux/interrupt.h>
+@@ -70,8 +70,7 @@ static unsigned char corgikbd_keycode[NR
+ 
+ struct corgikbd {
+ 	unsigned char keycode[ARRAY_SIZE(corgikbd_keycode)];
+-	struct input_dev input;
+-	char phys[32];
++	struct input_dev *input;
+ 
+ 	spinlock_t lock;
+ 	struct timer_list timer;
+@@ -147,7 +146,7 @@ static void corgikbd_scankeyboard(struct
+ 	spin_lock_irqsave(&corgikbd_data->lock, flags);
+ 
+ 	if (regs)
+-		input_regs(&corgikbd_data->input, regs);
++		input_regs(corgikbd_data->input, regs);
+ 
+ 	num_pressed = 0;
+ 	for (col = 0; col < KB_COLS; col++) {
+@@ -169,14 +168,14 @@ static void corgikbd_scankeyboard(struct
+ 			scancode = SCANCODE(row, col);
+ 			pressed = rowd & KB_ROWMASK(row);
+ 
+-			input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
++			input_report_key(corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
+ 
+ 			if (pressed)
+ 				num_pressed++;
+ 
+ 			if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
+ 					&& time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) {
+-				input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
++				input_event(corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
+ 				corgikbd_data->suspend_jiffies=jiffies;
+ 			}
+ 		}
+@@ -185,7 +184,7 @@ static void corgikbd_scankeyboard(struct
+ 
+ 	corgikbd_activate_all();
+ 
+-	input_sync(&corgikbd_data->input);
++	input_sync(corgikbd_data->input);
+ 
+ 	/* if any keys are pressed, enable the timer */
+ 	if (num_pressed)
+@@ -249,9 +248,9 @@ static void corgikbd_hinge_timer(unsigne
+ 		if (hinge_count >= HINGE_STABLE_COUNT) {
+ 			spin_lock_irqsave(&corgikbd_data->lock, flags);
+ 
+-			input_report_switch(&corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
+-			input_report_switch(&corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
+-			input_sync(&corgikbd_data->input);
++			input_report_switch(corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
++			input_report_switch(corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
++			input_sync(corgikbd_data->input);
+ 
+ 			spin_unlock_irqrestore(&corgikbd_data->lock, flags);
+ 		}
+@@ -260,24 +259,22 @@ static void corgikbd_hinge_timer(unsigne
+ }
+ 
+ #ifdef CONFIG_PM
+-static int corgikbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
++static int corgikbd_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_POWER_DOWN) {
+-		struct corgikbd *corgikbd = dev_get_drvdata(dev);
+-		corgikbd->suspended = 1;
+-	}
++	struct corgikbd *corgikbd = dev_get_drvdata(dev);
++	corgikbd->suspended = 1;
++
+ 	return 0;
+ }
+ 
+-static int corgikbd_resume(struct device *dev, uint32_t level)
++static int corgikbd_resume(struct device *dev)
+ {
+-	if (level == RESUME_POWER_ON) {
+-		struct corgikbd *corgikbd = dev_get_drvdata(dev);
++	struct corgikbd *corgikbd = dev_get_drvdata(dev);
++
++	/* Upon resume, ignore the suspend key for a short while */
++	corgikbd->suspend_jiffies=jiffies;
++	corgikbd->suspended = 0;
+ 
+-		/* Upon resume, ignore the suspend key for a short while */
+-		corgikbd->suspend_jiffies=jiffies;
+-		corgikbd->suspended = 0;
+-	}
+ 	return 0;
+ }
+ #else
+@@ -287,16 +284,21 @@ static int corgikbd_resume(struct device
+ 
+ static int __init corgikbd_probe(struct device *dev)
+ {
+-	int i;
+ 	struct corgikbd *corgikbd;
++	struct input_dev *input_dev;
++	int i;
+ 
+ 	corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL);
+-	if (!corgikbd)
++	input_dev = input_allocate_device();
++	if (!corgikbd || !input_dev) {
++		kfree(corgikbd);
++		input_free_device(input_dev);
+ 		return -ENOMEM;
++	}
+ 
+-	dev_set_drvdata(dev,corgikbd);
+-	strcpy(corgikbd->phys, "corgikbd/input0");
++	dev_set_drvdata(dev, corgikbd);
+ 
++	corgikbd->input = input_dev;
+ 	spin_lock_init(&corgikbd->lock);
+ 
+ 	/* Init Keyboard rescan timer */
+@@ -311,28 +313,30 @@ static int __init corgikbd_probe(struct 
+ 
+ 	corgikbd->suspend_jiffies=jiffies;
+ 
+-	init_input_dev(&corgikbd->input);
+-	corgikbd->input.private = corgikbd;
+-	corgikbd->input.name = "Corgi Keyboard";
+-	corgikbd->input.dev = dev;
+-	corgikbd->input.phys = corgikbd->phys;
+-	corgikbd->input.id.bustype = BUS_HOST;
+-	corgikbd->input.id.vendor = 0x0001;
+-	corgikbd->input.id.product = 0x0001;
+-	corgikbd->input.id.version = 0x0100;
+-	corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+-	corgikbd->input.keycode = corgikbd->keycode;
+-	corgikbd->input.keycodesize = sizeof(unsigned char);
+-	corgikbd->input.keycodemax = ARRAY_SIZE(corgikbd_keycode);
+-
+ 	memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode));
++
++	input_dev->name = "Corgi Keyboard";
++	input_dev->phys = "corgikbd/input0";
++	input_dev->id.bustype = BUS_HOST;
++	input_dev->id.vendor = 0x0001;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = dev;
++	input_dev->private = corgikbd;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
++	input_dev->keycode = corgikbd->keycode;
++	input_dev->keycodesize = sizeof(unsigned char);
++	input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
++
+ 	for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
+-		set_bit(corgikbd->keycode[i], corgikbd->input.keybit);
+-	clear_bit(0, corgikbd->input.keybit);
+-	set_bit(SW_0, corgikbd->input.swbit);
+-	set_bit(SW_1, corgikbd->input.swbit);
++		set_bit(corgikbd->keycode[i], input_dev->keybit);
++	clear_bit(0, input_dev->keybit);
++	set_bit(SW_0, input_dev->swbit);
++	set_bit(SW_1, input_dev->swbit);
++
++	input_register_device(corgikbd->input);
+ 
+-	input_register_device(&corgikbd->input);
+ 	mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL);
+ 
+ 	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
+@@ -349,8 +353,6 @@ static int __init corgikbd_probe(struct 
+ 	for (i = 0; i < CORGI_KEY_STROBE_NUM; i++)
+ 		pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
+ 
+-	printk(KERN_INFO "input: Corgi Keyboard Registered\n");
+-
+ 	return 0;
+ }
+ 
+@@ -365,7 +367,7 @@ static int corgikbd_remove(struct device
+ 	del_timer_sync(&corgikbd->htimer);
+ 	del_timer_sync(&corgikbd->timer);
+ 
+-	input_unregister_device(&corgikbd->input);
++	input_unregister_device(corgikbd->input);
+ 
+ 	kfree(corgikbd);
+ 
+diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
+--- a/drivers/input/keyboard/hil_kbd.c
++++ b/drivers/input/keyboard/hil_kbd.c
+@@ -204,7 +204,7 @@ static irqreturn_t hil_kbd_interrupt(str
+ 	hil_packet packet;
+ 	int idx;
+ 
+-	kbd = (struct hil_kbd *)serio->private;
++	kbd = serio_get_drvdata(serio);
+ 	if (kbd == NULL) {
+ 		BUG();
+ 		return IRQ_HANDLED;
+@@ -234,7 +234,7 @@ static void hil_kbd_disconnect(struct se
+ {
+ 	struct hil_kbd *kbd;
+ 
+-	kbd = (struct hil_kbd *)serio->private;
++	kbd = serio_get_drvdata(serio);
+ 	if (kbd == NULL) {
+ 		BUG();
+ 		return;
+@@ -245,20 +245,20 @@ static void hil_kbd_disconnect(struct se
+ 	kfree(kbd);
+ }
+ 
+-static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
++static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct hil_kbd	*kbd;
+ 	uint8_t		did, *idd;
+ 	int		i;
+ 	
+-	if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return;
+-
+-	if (!(kbd = kmalloc(sizeof(struct hil_kbd), GFP_KERNEL))) return;
++	kbd = kmalloc(sizeof(*kbd), GFP_KERNEL);
++	if (!kbd)
++		return -ENOMEM;
+ 	memset(kbd, 0, sizeof(struct hil_kbd));
+ 
+ 	if (serio_open(serio, drv)) goto bail0;
+ 
+-	serio->private = kbd;
++	serio_set_drvdata(serio, kbd);
+ 	kbd->serio = serio;
+ 	kbd->dev.private = kbd;
+ 
+@@ -342,19 +342,31 @@ static void hil_kbd_connect(struct serio
+ 	down(&(kbd->sem));
+ 	up(&(kbd->sem));
+ 
+-	return;
++	return 0;
+  bail1:
+ 	serio_close(serio);
+  bail0:
+ 	kfree(kbd);
++	serio_set_drvdata(serio, NULL);
++	return -EIO;
+ }
+ 
++static struct serio_device_id hil_kbd_ids[] = {
++	{
++		.type = SERIO_HIL_MLC,
++		.proto = SERIO_HIL,
++		.id = SERIO_ANY,
++		.extra = SERIO_ANY,
++	},
++	{ 0 }
++};
+ 
+ struct serio_driver hil_kbd_serio_drv = {
+ 	.driver		= {
+ 		.name	= "hil_kbd",
+ 	},
+ 	.description	= "HP HIL keyboard driver",
++	.id_table	= hil_kbd_ids,
+ 	.connect 	= hil_kbd_connect,
+ 	.disconnect 	= hil_kbd_disconnect,
+ 	.interrupt 	= hil_kbd_interrupt
+diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
+--- a/drivers/input/keyboard/hilkbd.c
++++ b/drivers/input/keyboard/hilkbd.c
+@@ -22,7 +22,7 @@
+ #include <linux/errno.h>
+ #include <linux/input.h>
+ #include <linux/init.h>
+-#include <linux/irq.h>
++#include <linux/interrupt.h>
+ #include <linux/hil.h>
+ #include <linux/spinlock.h>
+ 
+@@ -278,11 +278,11 @@ static int __init
+ hil_init_chip(struct parisc_device *dev)
+ {
+ 	if (!dev->irq) {
+-		printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa);
++		printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start);
+ 		return -ENODEV;
+ 	}
+ 
+-	hil_base = dev->hpa;
++	hil_base = dev->hpa.start;
+ 	hil_irq  = dev->irq;
+ 	hil_dev.dev_id = dev;
+ 	
+@@ -299,7 +299,7 @@ static struct parisc_device_id hil_tbl[]
+ MODULE_DEVICE_TABLE(parisc, hil_tbl);
+ 
+ static struct parisc_driver hil_driver = {
+-	.name =		"HIL",
++	.name =		"hil",
+ 	.id_table =	hil_tbl,
+ 	.probe =	hil_init_chip,
+ };
+diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
+--- a/drivers/input/keyboard/lkkbd.c
++++ b/drivers/input/keyboard/lkkbd.c
+@@ -102,7 +102,7 @@ static int ctrlclick_volume = 100; /* % 
+ module_param (ctrlclick_volume, int, 0);
+ MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
+ 
+-static int lk201_compose_is_alt = 0;
++static int lk201_compose_is_alt;
+ module_param (lk201_compose_is_alt, int, 0);
+ MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key "
+ 		"will act as an Alt key");
+@@ -274,7 +274,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM
+ };
+ 
+ #define CHECK_LED(LED, BITS) do {		\
+-	if (test_bit (LED, lk->dev.led))	\
++	if (test_bit (LED, lk->dev->led))	\
+ 		leds_on |= BITS;		\
+ 	else					\
+ 		leds_off |= BITS;		\
+@@ -287,7 +287,7 @@ struct lkkbd {
+ 	lk_keycode_t keycode[LK_NUM_KEYCODES];
+ 	int ignore_bytes;
+ 	unsigned char id[LK_NUM_IGNORE_BYTES];
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct serio *serio;
+ 	struct work_struct tq;
+ 	char name[64];
+@@ -423,8 +423,7 @@ lkkbd_interrupt (struct serio *serio, un
+ 	DBG (KERN_INFO "Got byte 0x%02x\n", data);
+ 
+ 	if (lk->ignore_bytes > 0) {
+-		DBG (KERN_INFO "Ignoring a byte on %s\n",
+-				lk->name);
++		DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name);
+ 		lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
+ 
+ 		if (lk->ignore_bytes == 0)
+@@ -435,11 +434,11 @@ lkkbd_interrupt (struct serio *serio, un
+ 
+ 	switch (data) {
+ 		case LK_ALL_KEYS_UP:
+-			input_regs (&lk->dev, regs);
++			input_regs (lk->dev, regs);
+ 			for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
+ 				if (lk->keycode[i] != KEY_RESERVED)
+-					input_report_key (&lk->dev, lk->keycode[i], 0);
+-			input_sync (&lk->dev);
++					input_report_key (lk->dev, lk->keycode[i], 0);
++			input_sync (lk->dev);
+ 			break;
+ 		case LK_METRONOME:
+ 			DBG (KERN_INFO "Got LK_METRONOME and don't "
+@@ -482,12 +481,12 @@ lkkbd_interrupt (struct serio *serio, un
+ 
+ 		default:
+ 			if (lk->keycode[data] != KEY_RESERVED) {
+-				input_regs (&lk->dev, regs);
+-				if (!test_bit (lk->keycode[data], lk->dev.key))
+-					input_report_key (&lk->dev, lk->keycode[data], 1);
++				input_regs (lk->dev, regs);
++				if (!test_bit (lk->keycode[data], lk->dev->key))
++					input_report_key (lk->dev, lk->keycode[data], 1);
+ 				else
+-					input_report_key (&lk->dev, lk->keycode[data], 0);
+-				input_sync (&lk->dev);
++					input_report_key (lk->dev, lk->keycode[data], 0);
++				input_sync (lk->dev);
+                         } else
+                                 printk (KERN_WARNING "%s: Unknown key with "
+ 						"scancode 0x%02x on %s.\n",
+@@ -605,7 +604,7 @@ lkkbd_reinit (void *data)
+ 	lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume));
+ 
+ 	/* Enable/disable keyclick (and possibly set volume) */
+-	if (test_bit (SND_CLICK, lk->dev.snd)) {
++	if (test_bit (SND_CLICK, lk->dev->snd)) {
+ 		lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
+ 		lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
+ 		lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
+@@ -616,7 +615,7 @@ lkkbd_reinit (void *data)
+ 	}
+ 
+ 	/* Sound the bell if needed */
+-	if (test_bit (SND_BELL, lk->dev.snd))
++	if (test_bit (SND_BELL, lk->dev->snd))
+ 		lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
+ }
+ 
+@@ -627,71 +626,70 @@ static int
+ lkkbd_connect (struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct lkkbd *lk;
++	struct input_dev *input_dev;
+ 	int i;
+ 	int err;
+ 
+-	if (!(lk = kmalloc (sizeof (struct lkkbd), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset (lk, 0, sizeof (struct lkkbd));
+-
+-	init_input_dev (&lk->dev);
+-	set_bit (EV_KEY, lk->dev.evbit);
+-	set_bit (EV_LED, lk->dev.evbit);
+-	set_bit (EV_SND, lk->dev.evbit);
+-	set_bit (EV_REP, lk->dev.evbit);
+-	set_bit (LED_CAPSL, lk->dev.ledbit);
+-	set_bit (LED_SLEEP, lk->dev.ledbit);
+-	set_bit (LED_COMPOSE, lk->dev.ledbit);
+-	set_bit (LED_SCROLLL, lk->dev.ledbit);
+-	set_bit (SND_BELL, lk->dev.sndbit);
+-	set_bit (SND_CLICK, lk->dev.sndbit);
++	lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL);
++	input_dev = input_allocate_device ();
++	if (!lk || !input_dev) {
++		err = -ENOMEM;
++		goto fail;
++	}
+ 
+ 	lk->serio = serio;
+-
++	lk->dev = input_dev;
+ 	INIT_WORK (&lk->tq, lkkbd_reinit, lk);
+-
+ 	lk->bell_volume = bell_volume;
+ 	lk->keyclick_volume = keyclick_volume;
+ 	lk->ctrlclick_volume = ctrlclick_volume;
++	memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
+ 
+-	lk->dev.keycode = lk->keycode;
+-	lk->dev.keycodesize = sizeof (lk_keycode_t);
+-	lk->dev.keycodemax = LK_NUM_KEYCODES;
++	strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name));
++	snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
+ 
+-	lk->dev.event = lkkbd_event;
+-	lk->dev.private = lk;
++	input_dev->name = lk->name;
++	input_dev->phys = lk->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_LKKBD;
++	input_dev->id.product = 0;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->event = lkkbd_event;
++	input_dev->private = lk;
++
++	set_bit (EV_KEY, input_dev->evbit);
++	set_bit (EV_LED, input_dev->evbit);
++	set_bit (EV_SND, input_dev->evbit);
++	set_bit (EV_REP, input_dev->evbit);
++	set_bit (LED_CAPSL, input_dev->ledbit);
++	set_bit (LED_SLEEP, input_dev->ledbit);
++	set_bit (LED_COMPOSE, input_dev->ledbit);
++	set_bit (LED_SCROLLL, input_dev->ledbit);
++	set_bit (SND_BELL, input_dev->sndbit);
++	set_bit (SND_CLICK, input_dev->sndbit);
++
++	input_dev->keycode = lk->keycode;
++	input_dev->keycodesize = sizeof (lk_keycode_t);
++	input_dev->keycodemax = LK_NUM_KEYCODES;
++	for (i = 0; i < LK_NUM_KEYCODES; i++)
++		set_bit (lk->keycode[i], input_dev->keybit);
+ 
+ 	serio_set_drvdata (serio, lk);
+ 
+ 	err = serio_open (serio, drv);
+-	if (err) {
+-		serio_set_drvdata (serio, NULL);
+-		kfree (lk);
+-		return err;
+-	}
++	if (err)
++		goto fail;
+ 
+-	sprintf (lk->name, "DEC LK keyboard");
+-	sprintf (lk->phys, "%s/input0", serio->phys);
+-
+-	memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
+-	for (i = 0; i < LK_NUM_KEYCODES; i++)
+-		set_bit (lk->keycode[i], lk->dev.keybit);
+-
+-	lk->dev.name = lk->name;
+-	lk->dev.phys = lk->phys;
+-	lk->dev.id.bustype = BUS_RS232;
+-	lk->dev.id.vendor = SERIO_LKKBD;
+-	lk->dev.id.product = 0;
+-	lk->dev.id.version = 0x0100;
+-	lk->dev.dev = &serio->dev;
+-
+-	input_register_device (&lk->dev);
+-
+-	printk (KERN_INFO "input: %s on %s, initiating reset\n", lk->name, serio->phys);
++	input_register_device (lk->dev);
+ 	lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
+ 
+ 	return 0;
++
++ fail:	serio_set_drvdata (serio, NULL);
++	input_free_device (input_dev);
++	kfree (lk);
++	return err;
+ }
+ 
+ /*
+@@ -702,9 +700,11 @@ lkkbd_disconnect (struct serio *serio)
+ {
+ 	struct lkkbd *lk = serio_get_drvdata (serio);
+ 
+-	input_unregister_device (&lk->dev);
++	input_get_device (lk->dev);
++	input_unregister_device (lk->dev);
+ 	serio_close (serio);
+ 	serio_set_drvdata (serio, NULL);
++	input_put_device (lk->dev);
+ 	kfree (lk);
+ }
+ 
+diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c
+--- a/drivers/input/keyboard/maple_keyb.c
++++ b/drivers/input/keyboard/maple_keyb.c
+@@ -37,7 +37,7 @@ static unsigned char dc_kbd_keycode[256]
+ 
+ 
+ struct dc_kbd {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	unsigned char new[8];
+ 	unsigned char old[8];
+ };
+@@ -46,30 +46,24 @@ struct dc_kbd {
+ static void dc_scan_kbd(struct dc_kbd *kbd)
+ {
+ 	int i;
+-	struct input_dev *dev = &kbd->dev;
++	struct input_dev *dev = kbd->dev;
+ 
+-	for(i=0; i<8; i++)
+-		input_report_key(dev,
+-				 dc_kbd_keycode[i+224],
+-				 (kbd->new[0]>>i)&1);
+-
+-	for(i=2; i<8; i++) {
+-
+-		if(kbd->old[i]>3&&memscan(kbd->new+2, kbd->old[i], 6)==NULL) {
+-			if(dc_kbd_keycode[kbd->old[i]])
+-				input_report_key(dev,
+-						 dc_kbd_keycode[kbd->old[i]],
+-						 0);
++	for (i = 0; i < 8; i++)
++		input_report_key(dev, dc_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
++
++	for (i = 2; i < 8; i++) {
++
++		if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == NULL) {
++			if (dc_kbd_keycode[kbd->old[i]])
++				input_report_key(dev, dc_kbd_keycode[kbd->old[i]], 0);
+ 			else
+ 				printk("Unknown key (scancode %#x) released.",
+ 				       kbd->old[i]);
+ 		}
+ 
+-		if(kbd->new[i]>3&&memscan(kbd->old+2, kbd->new[i], 6)!=NULL) {
++		if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) != NULL) {
+ 			if(dc_kbd_keycode[kbd->new[i]])
+-				input_report_key(dev,
+-						 dc_kbd_keycode[kbd->new[i]],
+-						 1);
++				input_report_key(dev, dc_kbd_keycode[kbd->new[i]], 1);
+ 			else
+ 				printk("Unknown key (scancode %#x) pressed.",
+ 				       kbd->new[i]);
+@@ -89,43 +83,39 @@ static void dc_kbd_callback(struct maple
+ 	unsigned long *buf = mq->recvbuf;
+ 
+ 	if (buf[1] == mapledev->function) {
+-		memcpy(kbd->new, buf+2, 8);
++		memcpy(kbd->new, buf + 2, 8);
+ 		dc_scan_kbd(kbd);
+ 	}
+ }
+ 
+ static int dc_kbd_connect(struct maple_device *dev)
+ {
+-	int i;
+-	unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
+ 	struct dc_kbd *kbd;
++	struct input_dev *input_dev;
++	unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
++	int i;
+ 
+-	if (!(kbd = kmalloc(sizeof(struct dc_kbd), GFP_KERNEL)))
+-		return -1;
+-	memset(kbd, 0, sizeof(struct dc_kbd));
+-
+-	dev->private_data = kbd;
+-
+-	kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+-
+-	init_input_dev(&kbd->dev);
+-
+-	for (i=0; i<255; i++)
+-		set_bit(dc_kbd_keycode[i], kbd->dev.keybit);
+-
+-	clear_bit(0, kbd->dev.keybit);
++	dev->private_data = kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!kbd || !input_dev) {
++		kfree(kbd);
++		input_free_device(input_dev);
++		return -ENOMEM;
++	}
+ 
+-	kbd->dev.private = kbd;
++	kbd->dev = input_dev;
+ 
+-	kbd->dev.name = dev->product_name;
+-	kbd->dev.id.bustype = BUS_MAPLE;
++	input_dev->name = dev->product_name;
++	input_dev->id.bustype = BUS_MAPLE;
++	input_dev->private = kbd;
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++	for (i = 0; i < 255; i++)
++		set_bit(dc_kbd_keycode[i], input_dev->keybit);
++	clear_bit(0, input_dev->keybit);
+ 
+-	input_register_device(&kbd->dev);
++	input_register_device(kbd->dev);
+ 
+ 	maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD);
+-
+-	printk(KERN_INFO "input: keyboard(0x%lx): %s\n", data, kbd->dev.name);
+-
+ 	return 0;
+ }
+ 
+@@ -134,7 +124,7 @@ static void dc_kbd_disconnect(struct map
+ {
+ 	struct dc_kbd *kbd = dev->private_data;
+ 
+-	input_unregister_device(&kbd->dev);
++	input_unregister_device(kbd->dev);
+ 	kfree(kbd);
+ }
+ 
+diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
+--- a/drivers/input/keyboard/newtonkbd.c
++++ b/drivers/input/keyboard/newtonkbd.c
+@@ -57,11 +57,9 @@ static unsigned char nkbd_keycode[128] =
+ 	KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0
+ };
+ 
+-static char *nkbd_name = "Newton Keyboard";
+-
+ struct nkbd {
+ 	unsigned char keycode[128];
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct serio *serio;
+ 	char phys[32];
+ };
+@@ -73,13 +71,13 @@ static irqreturn_t nkbd_interrupt(struct
+ 
+ 	/* invalid scan codes are probably the init sequence, so we ignore them */
+ 	if (nkbd->keycode[data & NKBD_KEY]) {
+-		input_regs(&nkbd->dev, regs);
+-		input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
+-		input_sync(&nkbd->dev);
++		input_regs(nkbd->dev, regs);
++		input_report_key(nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
++		input_sync(nkbd->dev);
+ 	}
+ 
+ 	else if (data == 0xe7) /* end of init sequence */
+-		printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
++		printk(KERN_INFO "input: %s on %s\n", nkbd->dev->name, serio->phys);
+ 	return IRQ_HANDLED;
+ 
+ }
+@@ -87,62 +85,59 @@ static irqreturn_t nkbd_interrupt(struct
+ static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct nkbd *nkbd;
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
+ 	int i;
+-	int err;
+-
+-	if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset(nkbd, 0, sizeof(struct nkbd));
+ 
+-	nkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++	nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!nkbd || !input_dev)
++		goto fail;
+ 
+ 	nkbd->serio = serio;
++	nkbd->dev = input_dev;
++	sprintf(nkbd->phys, "%s/input0", serio->phys);
++	memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
+ 
+-	init_input_dev(&nkbd->dev);
+-	nkbd->dev.keycode = nkbd->keycode;
+-	nkbd->dev.keycodesize = sizeof(unsigned char);
+-	nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);
+-	nkbd->dev.private = nkbd;
++	input_dev->name = "Newton Keyboard";
++	input_dev->phys = nkbd->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_NEWTON;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = nkbd;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++	input_dev->keycode = nkbd->keycode;
++	input_dev->keycodesize = sizeof(unsigned char);
++	input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode);
++	for (i = 0; i < 128; i++)
++		set_bit(nkbd->keycode[i], input_dev->keybit);
++	clear_bit(0, input_dev->keybit);
+ 
+ 	serio_set_drvdata(serio, nkbd);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(nkbd);
+-		return err;
+-	}
+-
+-	memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
+-	for (i = 0; i < 128; i++)
+-		set_bit(nkbd->keycode[i], nkbd->dev.keybit);
+-	clear_bit(0, nkbd->dev.keybit);
+-
+-	sprintf(nkbd->phys, "%s/input0", serio->phys);
+-
+-	nkbd->dev.name = nkbd_name;
+-	nkbd->dev.phys = nkbd->phys;
+-	nkbd->dev.id.bustype = BUS_RS232;
+-	nkbd->dev.id.vendor = SERIO_NEWTON;
+-	nkbd->dev.id.product = 0x0001;
+-	nkbd->dev.id.version = 0x0100;
+-	nkbd->dev.dev = &serio->dev;
+-
+-	input_register_device(&nkbd->dev);
+-
+-	printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
++	if (err)
++		goto fail;
+ 
++	input_register_device(nkbd->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(nkbd);
++	return err;
+ }
+ 
+ static void nkbd_disconnect(struct serio *serio)
+ {
+ 	struct nkbd *nkbd = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&nkbd->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(nkbd->dev);
+ 	kfree(nkbd);
+ }
+ 
+diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
+--- a/drivers/input/keyboard/spitzkbd.c
++++ b/drivers/input/keyboard/spitzkbd.c
+@@ -12,7 +12,7 @@
+  */
+ 
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/init.h>
+ #include <linux/input.h>
+ #include <linux/interrupt.h>
+@@ -85,7 +85,7 @@ static int spitz_senses[] = {
+ 
+ struct spitzkbd {
+ 	unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)];
+-	struct input_dev input;
++	struct input_dev *input;
+ 	char phys[32];
+ 
+ 	spinlock_t lock;
+@@ -187,8 +187,7 @@ static void spitzkbd_scankeyboard(struct
+ 
+ 	spin_lock_irqsave(&spitzkbd_data->lock, flags);
+ 
+-	if (regs)
+-		input_regs(&spitzkbd_data->input, regs);
++	input_regs(spitzkbd_data->input, regs);
+ 
+ 	num_pressed = 0;
+ 	for (col = 0; col < KB_COLS; col++) {
+@@ -210,7 +209,7 @@ static void spitzkbd_scankeyboard(struct
+ 			scancode = SCANCODE(row, col);
+ 			pressed = rowd & KB_ROWMASK(row);
+ 
+-			input_report_key(&spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
++			input_report_key(spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
+ 
+ 			if (pressed)
+ 				num_pressed++;
+@@ -220,15 +219,15 @@ static void spitzkbd_scankeyboard(struct
+ 
+ 	spitzkbd_activate_all();
+ 
+-	input_report_key(&spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
+-	input_report_key(&spitzkbd_data->input, KEY_SUSPEND, pwrkey);
++	input_report_key(spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
++	input_report_key(spitzkbd_data->input, KEY_SUSPEND, pwrkey);
+ 
+ 	if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) {
+-		input_event(&spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
++		input_event(spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
+ 		spitzkbd_data->suspend_jiffies = jiffies;
+ 	}
+ 
+-	input_sync(&spitzkbd_data->input);
++	input_sync(spitzkbd_data->input);
+ 
+ 	/* if any keys are pressed, enable the timer */
+ 	if (num_pressed)
+@@ -259,6 +258,7 @@ static irqreturn_t spitzkbd_interrupt(in
+ static void spitzkbd_timer_callback(unsigned long data)
+ {
+ 	struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
++
+ 	spitzkbd_scankeyboard(spitzkbd_data, NULL);
+ }
+ 
+@@ -298,9 +298,9 @@ static void spitzkbd_hinge_timer(unsigne
+ 	if (hinge_count >= HINGE_STABLE_COUNT) {
+ 		spin_lock_irqsave(&spitzkbd_data->lock, flags);
+ 
+-		input_report_switch(&spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
+-		input_report_switch(&spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
+-		input_sync(&spitzkbd_data->input);
++		input_report_switch(spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
++		input_report_switch(spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
++		input_sync(spitzkbd_data->input);
+ 
+ 		spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
+ 	} else {
+@@ -309,34 +309,32 @@ static void spitzkbd_hinge_timer(unsigne
+ }
+ 
+ #ifdef CONFIG_PM
+-static int spitzkbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
++static int spitzkbd_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_POWER_DOWN) {
+-		int i;
+-		struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+-		spitzkbd->suspended = 1;
+-
+-		/* Set Strobe lines as inputs - *except* strobe line 0 leave this
+-		   enabled so we can detect a power button press for resume */
+-		for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
+-			pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
+-	}
++	int i;
++	struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
++	spitzkbd->suspended = 1;
++
++	/* Set Strobe lines as inputs - *except* strobe line 0 leave this
++	   enabled so we can detect a power button press for resume */
++	for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
++		pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
++
+ 	return 0;
+ }
+ 
+-static int spitzkbd_resume(struct device *dev, uint32_t level)
++static int spitzkbd_resume(struct device *dev)
+ {
+-	if (level == RESUME_POWER_ON) {
+-		int i;
+-		struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+-
+-		for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
+-			pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
+-
+-		/* Upon resume, ignore the suspend key for a short while */
+-		spitzkbd->suspend_jiffies = jiffies;
+-		spitzkbd->suspended = 0;
+-	}
++	int i;
++	struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
++
++	for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
++		pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
++
++	/* Upon resume, ignore the suspend key for a short while */
++	spitzkbd->suspend_jiffies = jiffies;
++	spitzkbd->suspended = 0;
++
+ 	return 0;
+ }
+ #else
+@@ -346,14 +344,21 @@ static int spitzkbd_resume(struct device
+ 
+ static int __init spitzkbd_probe(struct device *dev)
+ {
+-	int i;
+ 	struct spitzkbd *spitzkbd;
++	struct input_dev *input_dev;
++	int i;
+ 
+ 	spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL);
+ 	if (!spitzkbd)
+ 		return -ENOMEM;
+ 
+-	dev_set_drvdata(dev,spitzkbd);
++	input_dev = input_allocate_device();
++	if (!input_dev) {
++		kfree(spitzkbd);
++		return -ENOMEM;
++	}
++
++	dev_set_drvdata(dev, spitzkbd);
+ 	strcpy(spitzkbd->phys, "spitzkbd/input0");
+ 
+ 	spin_lock_init(&spitzkbd->lock);
+@@ -368,30 +373,34 @@ static int __init spitzkbd_probe(struct 
+ 	spitzkbd->htimer.function = spitzkbd_hinge_timer;
+ 	spitzkbd->htimer.data = (unsigned long) spitzkbd;
+ 
+-	spitzkbd->suspend_jiffies=jiffies;
++	spitzkbd->suspend_jiffies = jiffies;
+ 
+-	init_input_dev(&spitzkbd->input);
+-	spitzkbd->input.private = spitzkbd;
+-	spitzkbd->input.name = "Spitz Keyboard";
+-	spitzkbd->input.dev = dev;
+-	spitzkbd->input.phys = spitzkbd->phys;
+-	spitzkbd->input.id.bustype = BUS_HOST;
+-	spitzkbd->input.id.vendor = 0x0001;
+-	spitzkbd->input.id.product = 0x0001;
+-	spitzkbd->input.id.version = 0x0100;
+-	spitzkbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+-	spitzkbd->input.keycode = spitzkbd->keycode;
+-	spitzkbd->input.keycodesize = sizeof(unsigned char);
+-	spitzkbd->input.keycodemax = ARRAY_SIZE(spitzkbd_keycode);
++	spitzkbd->input = input_dev;
++
++	input_dev->private = spitzkbd;
++	input_dev->name = "Spitz Keyboard";
++	input_dev->phys = spitzkbd->phys;
++	input_dev->cdev.dev = dev;
++
++	input_dev->id.bustype = BUS_HOST;
++	input_dev->id.vendor = 0x0001;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
++	input_dev->keycode = spitzkbd->keycode;
++	input_dev->keycodesize = sizeof(unsigned char);
++	input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode);
+ 
+ 	memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode));
+ 	for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++)
+-		set_bit(spitzkbd->keycode[i], spitzkbd->input.keybit);
+-	clear_bit(0, spitzkbd->input.keybit);
+-	set_bit(SW_0, spitzkbd->input.swbit);
+-	set_bit(SW_1, spitzkbd->input.swbit);
++		set_bit(spitzkbd->keycode[i], input_dev->keybit);
++	clear_bit(0, input_dev->keybit);
++	set_bit(SW_0, input_dev->swbit);
++	set_bit(SW_1, input_dev->swbit);
++
++	input_register_device(input_dev);
+ 
+-	input_register_device(&spitzkbd->input);
+ 	mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
+ 
+ 	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
+@@ -444,7 +453,7 @@ static int spitzkbd_remove(struct device
+ 	del_timer_sync(&spitzkbd->htimer);
+ 	del_timer_sync(&spitzkbd->timer);
+ 
+-	input_unregister_device(&spitzkbd->input);
++	input_unregister_device(spitzkbd->input);
+ 
+ 	kfree(spitzkbd);
+ 
+diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
+--- a/drivers/input/keyboard/sunkbd.c
++++ b/drivers/input/keyboard/sunkbd.c
+@@ -76,13 +76,14 @@ static unsigned char sunkbd_keycode[128]
+ 
+ struct sunkbd {
+ 	unsigned char keycode[128];
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct serio *serio;
+ 	struct work_struct tq;
+ 	wait_queue_head_t wait;
+ 	char name[64];
+ 	char phys[32];
+ 	char type;
++	unsigned char enabled;
+ 	volatile s8 reset;
+ 	volatile s8 layout;
+ };
+@@ -124,10 +125,13 @@ static irqreturn_t sunkbd_interrupt(stru
+ 			break;
+ 
+ 		default:
++			if (!sunkbd->enabled)
++				break;
++
+ 			if (sunkbd->keycode[data & SUNKBD_KEY]) {
+-				input_regs(&sunkbd->dev, regs);
+-                                input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
+-				input_sync(&sunkbd->dev);
++				input_regs(sunkbd->dev, regs);
++                                input_report_key(sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
++				input_sync(sunkbd->dev);
+                         } else {
+                                 printk(KERN_WARNING "sunkbd.c: Unknown key (scancode %#x) %s.\n",
+                                         data & SUNKBD_KEY, data & SUNKBD_RELEASE ? "released" : "pressed");
+@@ -184,7 +188,7 @@ static int sunkbd_initialize(struct sunk
+ 	sunkbd->reset = -2;
+ 	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET);
+ 	wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
+-	if (sunkbd->reset <0)
++	if (sunkbd->reset < 0)
+ 		return -1;
+ 
+ 	sunkbd->type = sunkbd->reset;
+@@ -213,10 +217,17 @@ static void sunkbd_reinit(void *data)
+ 
+ 	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
+ 	sunkbd->serio->write(sunkbd->serio,
+-		(!!test_bit(LED_CAPSL, sunkbd->dev.led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev.led) << 2) |
+-		(!!test_bit(LED_COMPOSE, sunkbd->dev.led) << 1) | !!test_bit(LED_NUML, sunkbd->dev.led));
+-	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev.snd));
+-	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev.snd));
++		(!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) |
++		(!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) | !!test_bit(LED_NUML, sunkbd->dev->led));
++	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd));
++	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd));
++}
++
++static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
++{
++	serio_pause_rx(sunkbd->serio);
++	sunkbd->enabled = 1;
++	serio_continue_rx(sunkbd->serio);
+ }
+ 
+ /*
+@@ -226,70 +237,64 @@ static void sunkbd_reinit(void *data)
+ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct sunkbd *sunkbd;
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
+ 	int i;
+-	int err;
+-
+-	if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
+-		return -ENOMEM;
+ 
+-	memset(sunkbd, 0, sizeof(struct sunkbd));
+-
+-	init_input_dev(&sunkbd->dev);
+-	init_waitqueue_head(&sunkbd->wait);
+-
+-	sunkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
+-	sunkbd->dev.ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
+-	sunkbd->dev.sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
++	sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!sunkbd || !input_dev)
++		goto fail;
+ 
+ 	sunkbd->serio = serio;
+-
++	sunkbd->dev = input_dev;
++	init_waitqueue_head(&sunkbd->wait);
+ 	INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd);
+-
+-	sunkbd->dev.keycode = sunkbd->keycode;
+-	sunkbd->dev.keycodesize = sizeof(unsigned char);
+-	sunkbd->dev.keycodemax = ARRAY_SIZE(sunkbd_keycode);
+-
+-	sunkbd->dev.event = sunkbd_event;
+-	sunkbd->dev.private = sunkbd;
++	snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys);
+ 
+ 	serio_set_drvdata(serio, sunkbd);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(sunkbd);
+-		return err;
+-	}
++	if (err)
++		goto fail;
+ 
+ 	if (sunkbd_initialize(sunkbd) < 0) {
+ 		serio_close(serio);
+-		serio_set_drvdata(serio, NULL);
+-		kfree(sunkbd);
+-		return -ENODEV;
++		goto fail;
+ 	}
+ 
+ 	sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
+-
+ 	memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
+-	for (i = 0; i < 128; i++)
+-		set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
+-	clear_bit(0, sunkbd->dev.keybit);
+-
+-	sprintf(sunkbd->phys, "%s/input0", serio->phys);
+-
+-	sunkbd->dev.name = sunkbd->name;
+-	sunkbd->dev.phys = sunkbd->phys;
+-	sunkbd->dev.id.bustype = BUS_RS232;
+-	sunkbd->dev.id.vendor = SERIO_SUNKBD;
+-	sunkbd->dev.id.product = sunkbd->type;
+-	sunkbd->dev.id.version = 0x0100;
+-	sunkbd->dev.dev = &serio->dev;
+ 
+-	input_register_device(&sunkbd->dev);
+-
+-	printk(KERN_INFO "input: %s on %s\n", sunkbd->name, serio->phys);
++	input_dev->name = sunkbd->name;
++	input_dev->phys = sunkbd->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor  = SERIO_SUNKBD;
++	input_dev->id.product = sunkbd->type;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = sunkbd;
++	input_dev->event = sunkbd_event;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
++	input_dev->ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
++	input_dev->sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
++
++	input_dev->keycode = sunkbd->keycode;
++	input_dev->keycodesize = sizeof(unsigned char);
++	input_dev->keycodemax = ARRAY_SIZE(sunkbd_keycode);
++	for (i = 0; i < 128; i++)
++		set_bit(sunkbd->keycode[i], input_dev->keybit);
++	clear_bit(0, input_dev->keybit);
+ 
++	sunkbd_enable(sunkbd, 1);
++	input_register_device(sunkbd->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(sunkbd);
++	return err;
+ }
+ 
+ /*
+@@ -299,7 +304,9 @@ static int sunkbd_connect(struct serio *
+ static void sunkbd_disconnect(struct serio *serio)
+ {
+ 	struct sunkbd *sunkbd = serio_get_drvdata(serio);
+-	input_unregister_device(&sunkbd->dev);
++
++	sunkbd_enable(sunkbd, 0);
++	input_unregister_device(sunkbd->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
+ 	kfree(sunkbd);
+diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
+--- a/drivers/input/keyboard/xtkbd.c
++++ b/drivers/input/keyboard/xtkbd.c
+@@ -56,11 +56,9 @@ static unsigned char xtkbd_keycode[256] 
+ 	106
+ };
+ 
+-static char *xtkbd_name = "XT Keyboard";
+-
+ struct xtkbd {
+ 	unsigned char keycode[256];
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct serio *serio;
+ 	char phys[32];
+ };
+@@ -77,9 +75,9 @@ static irqreturn_t xtkbd_interrupt(struc
+ 		default:
+ 
+ 			if (xtkbd->keycode[data & XTKBD_KEY]) {
+-				input_regs(&xtkbd->dev, regs);
+-				input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
+-				input_sync(&xtkbd->dev);
++				input_regs(xtkbd->dev, regs);
++				input_report_key(xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
++				input_sync(xtkbd->dev);
+ 			} else {
+ 				printk(KERN_WARNING "xtkbd.c: Unknown key (scancode %#x) %s.\n",
+ 					data & XTKBD_KEY, data & XTKBD_RELEASE ? "released" : "pressed");
+@@ -91,62 +89,60 @@ static irqreturn_t xtkbd_interrupt(struc
+ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct xtkbd *xtkbd;
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
+ 	int i;
+-	int err;
+-
+-	if (!(xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset(xtkbd, 0, sizeof(struct xtkbd));
+ 
+-	xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++	xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!xtkbd || !input_dev)
++		goto fail;
+ 
+ 	xtkbd->serio = serio;
+-
+-	init_input_dev(&xtkbd->dev);
+-	xtkbd->dev.keycode = xtkbd->keycode;
+-	xtkbd->dev.keycodesize = sizeof(unsigned char);
+-	xtkbd->dev.keycodemax = ARRAY_SIZE(xtkbd_keycode);
+-	xtkbd->dev.private = xtkbd;
+-
+-	serio_set_drvdata(serio, xtkbd);
+-
+-	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(xtkbd);
+-		return err;
+-	}
+-
++	xtkbd->dev = input_dev;
++	sprintf(xtkbd->phys, "%s/input0", serio->phys);
+ 	memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
+-	for (i = 0; i < 255; i++)
+-		set_bit(xtkbd->keycode[i], xtkbd->dev.keybit);
+-	clear_bit(0, xtkbd->dev.keybit);
+ 
+-	sprintf(xtkbd->phys, "%s/input0", serio->phys);
++	input_dev->name = "XT Keyboard";
++	input_dev->phys = xtkbd->phys;
++	input_dev->id.bustype = BUS_XTKBD;
++	input_dev->id.vendor  = 0x0001;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = xtkbd;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++	input_dev->keycode = xtkbd->keycode;
++	input_dev->keycodesize = sizeof(unsigned char);
++	input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode);
+ 
+-	xtkbd->dev.name = xtkbd_name;
+-	xtkbd->dev.phys = xtkbd->phys;
+-	xtkbd->dev.id.bustype = BUS_XTKBD;
+-	xtkbd->dev.id.vendor = 0x0001;
+-	xtkbd->dev.id.product = 0x0001;
+-	xtkbd->dev.id.version = 0x0100;
+-	xtkbd->dev.dev = &serio->dev;
++	for (i = 0; i < 255; i++)
++		set_bit(xtkbd->keycode[i], input_dev->keybit);
++	clear_bit(0, input_dev->keybit);
+ 
+-	input_register_device(&xtkbd->dev);
++	serio_set_drvdata(serio, xtkbd);
+ 
+-	printk(KERN_INFO "input: %s on %s\n", xtkbd_name, serio->phys);
++	err = serio_open(serio, drv);
++	if (err)
++		goto fail;
+ 
++	input_register_device(xtkbd->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(xtkbd);
++	return err;
+ }
+ 
+ static void xtkbd_disconnect(struct serio *serio)
+ {
+ 	struct xtkbd *xtkbd = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&xtkbd->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(xtkbd->dev);
+ 	kfree(xtkbd);
+ }
+ 
+diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
+--- a/drivers/input/misc/Kconfig
++++ b/drivers/input/misc/Kconfig
+@@ -14,7 +14,7 @@ if INPUT_MISC
+ 
+ config INPUT_PCSPKR
+ 	tristate "PC Speaker support"
+-	depends on ALPHA || X86 || X86_64 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
++	depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
+ 	help
+ 	  Say Y here if you want the standard PC Speaker to be used for
+ 	  bells and whistles.
+diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c
+--- a/drivers/input/misc/m68kspkr.c
++++ b/drivers/input/misc/m68kspkr.c
+@@ -24,9 +24,7 @@ MODULE_AUTHOR("Richard Zidlicky <rz at linu
+ MODULE_DESCRIPTION("m68k beeper driver");
+ MODULE_LICENSE("GPL");
+ 
+-static char m68kspkr_name[] = "m68k beeper";
+-static char m68kspkr_phys[] = "m68k/generic";
+-static struct input_dev m68kspkr_dev;
++static struct input_dev *m68kspkr_dev;
+ 
+ static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+ {
+@@ -51,32 +49,34 @@ static int m68kspkr_event(struct input_d
+ 
+ static int __init m68kspkr_init(void)
+ {
+-        if (!mach_beep){
+-		printk("%s: no lowlevel beep support\n", m68kspkr_name);
+-		return -1;
++        if (!mach_beep) {
++		printk(KERN_INFO "m68kspkr: no lowlevel beep support\n");
++		return -ENODEV;
+         }
+ 
+-	m68kspkr_dev.evbit[0] = BIT(EV_SND);
+-	m68kspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+-	m68kspkr_dev.event = m68kspkr_event;
+-
+-	m68kspkr_dev.name = m68kspkr_name;
+-	m68kspkr_dev.phys = m68kspkr_phys;
+-	m68kspkr_dev.id.bustype = BUS_HOST;
+-	m68kspkr_dev.id.vendor = 0x001f;
+-	m68kspkr_dev.id.product = 0x0001;
+-	m68kspkr_dev.id.version = 0x0100;
+-
+-	input_register_device(&m68kspkr_dev);
++	m68kspkr_dev = input_allocate_device();
++	if (!m68kspkr_dev)
++		return -ENOMEM;
++
++	m68kspkr_dev->name = "m68k beeper";
++	m68kspkr_dev->phys = "m68k/generic";
++	m68kspkr_dev->id.bustype = BUS_HOST;
++	m68kspkr_dev->id.vendor = 0x001f;
++	m68kspkr_dev->id.product = 0x0001;
++	m68kspkr_dev->id.version = 0x0100;
++
++	m68kspkr_dev->evbit[0] = BIT(EV_SND);
++	m68kspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
++	m68kspkr_dev->event = m68kspkr_event;
+ 
+-        printk(KERN_INFO "input: %s\n", m68kspkr_name);
++	input_register_device(m68kspkr_dev);
+ 
+ 	return 0;
+ }
+ 
+ static void __exit m68kspkr_exit(void)
+ {
+-        input_unregister_device(&m68kspkr_dev);
++        input_unregister_device(m68kspkr_dev);
+ }
+ 
+ module_init(m68kspkr_init);
+diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
+--- a/drivers/input/misc/pcspkr.c
++++ b/drivers/input/misc/pcspkr.c
+@@ -23,9 +23,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech at u
+ MODULE_DESCRIPTION("PC Speaker beeper driver");
+ MODULE_LICENSE("GPL");
+ 
+-static char pcspkr_name[] = "PC Speaker";
+-static char pcspkr_phys[] = "isa0061/input0";
+-static struct input_dev pcspkr_dev;
++static struct input_dev *pcspkr_dev;
+ 
+ static DEFINE_SPINLOCK(i8253_beep_lock);
+ 
+@@ -68,27 +66,29 @@ static int pcspkr_event(struct input_dev
+ 
+ static int __init pcspkr_init(void)
+ {
+-	pcspkr_dev.evbit[0] = BIT(EV_SND);
+-	pcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+-	pcspkr_dev.event = pcspkr_event;
+-
+-	pcspkr_dev.name = pcspkr_name;
+-	pcspkr_dev.phys = pcspkr_phys;
+-	pcspkr_dev.id.bustype = BUS_ISA;
+-	pcspkr_dev.id.vendor = 0x001f;
+-	pcspkr_dev.id.product = 0x0001;
+-	pcspkr_dev.id.version = 0x0100;
++	pcspkr_dev = input_allocate_device();
++	if (!pcspkr_dev)
++		return -ENOMEM;
++
++	pcspkr_dev->name = "PC Speaker";
++	pcspkr_dev->phys = "isa0061/input0";
++	pcspkr_dev->id.bustype = BUS_ISA;
++	pcspkr_dev->id.vendor = 0x001f;
++	pcspkr_dev->id.product = 0x0001;
++	pcspkr_dev->id.version = 0x0100;
++
++	pcspkr_dev->evbit[0] = BIT(EV_SND);
++	pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
++	pcspkr_dev->event = pcspkr_event;
+ 
+-	input_register_device(&pcspkr_dev);
+-
+-        printk(KERN_INFO "input: %s\n", pcspkr_name);
++	input_register_device(pcspkr_dev);
+ 
+ 	return 0;
+ }
+ 
+ static void __exit pcspkr_exit(void)
+ {
+-        input_unregister_device(&pcspkr_dev);
++        input_unregister_device(pcspkr_dev);
+ 	/* turn off the speaker */
+ 	pcspkr_event(NULL, EV_SND, SND_BELL, 0);
+ }
+diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
+--- a/drivers/input/misc/sparcspkr.c
++++ b/drivers/input/misc/sparcspkr.c
+@@ -17,28 +17,24 @@
+ #endif
+ 
+ MODULE_AUTHOR("David S. Miller <davem at redhat.com>");
+-MODULE_DESCRIPTION("PC Speaker beeper driver");
++MODULE_DESCRIPTION("Sparc Speaker beeper driver");
+ MODULE_LICENSE("GPL");
+ 
+ static unsigned long beep_iobase;
+-
+-static char *sparcspkr_isa_name = "Sparc ISA Speaker";
+-static char *sparcspkr_ebus_name = "Sparc EBUS Speaker";
+-static char *sparcspkr_phys = "sparc/input0";
+-static struct input_dev sparcspkr_dev;
++static struct input_dev *sparcspkr_dev;
+ 
+ DEFINE_SPINLOCK(beep_lock);
+ 
+ static void __init init_sparcspkr_struct(void)
+ {
+-	sparcspkr_dev.evbit[0] = BIT(EV_SND);
+-	sparcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
++	sparcspkr_dev->evbit[0] = BIT(EV_SND);
++	sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ 
+-	sparcspkr_dev.phys = sparcspkr_phys;
+-	sparcspkr_dev.id.bustype = BUS_ISA;
+-	sparcspkr_dev.id.vendor = 0x001f;
+-	sparcspkr_dev.id.product = 0x0001;
+-	sparcspkr_dev.id.version = 0x0100;
++	sparcspkr_dev->phys = "sparc/input0";
++	sparcspkr_dev->id.bustype = BUS_ISA;
++	sparcspkr_dev->id.vendor = 0x001f;
++	sparcspkr_dev->id.product = 0x0001;
++	sparcspkr_dev->id.version = 0x0100;
+ }
+ 
+ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+@@ -84,14 +80,15 @@ static int __init init_ebus_beep(struct 
+ {
+ 	beep_iobase = edev->resource[0].start;
+ 
+-	init_sparcspkr_struct();
++	sparcspkr_dev = input_allocate_device();
++	if (!sparcspkr_dev)
++		return -ENOMEM;
+ 
+-	sparcspkr_dev.name = sparcspkr_ebus_name;
+-	sparcspkr_dev.event = ebus_spkr_event;
++	sparcspkr_dev->name = "Sparc EBUS Speaker";
++	sparcspkr_dev->event = ebus_spkr_event;
+ 
+-	input_register_device(&sparcspkr_dev);
++	input_register_device(sparcspkr_dev);
+ 
+-        printk(KERN_INFO "input: %s\n", sparcspkr_ebus_name);
+ 	return 0;
+ }
+ 
+@@ -137,15 +134,17 @@ static int __init init_isa_beep(struct s
+ {
+ 	beep_iobase = isa_dev->resource.start;
+ 
++	sparcspkr_dev = input_allocate_device();
++	if (!sparcspkr_dev)
++		return -ENOMEM;
++
+ 	init_sparcspkr_struct();
+ 
+-	sparcspkr_dev.name = sparcspkr_isa_name;
+-	sparcspkr_dev.event = isa_spkr_event;
+-	sparcspkr_dev.id.bustype = BUS_ISA;
++	sparcspkr_dev->name = "Sparc ISA Speaker";
++	sparcspkr_dev->event = isa_spkr_event;
+ 
+-	input_register_device(&sparcspkr_dev);
++	input_register_device(sparcspkr_dev);
+ 
+-        printk(KERN_INFO "input: %s\n", sparcspkr_isa_name);
+ 	return 0;
+ }
+ #endif
+@@ -182,7 +181,7 @@ static int __init sparcspkr_init(void)
+ 
+ static void __exit sparcspkr_exit(void)
+ {
+-	input_unregister_device(&sparcspkr_dev);
++	input_unregister_device(sparcspkr_dev);
+ }
+ 
+ module_init(sparcspkr_init);
+diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
+--- a/drivers/input/mouse/Kconfig
++++ b/drivers/input/mouse/Kconfig
+@@ -17,7 +17,7 @@ config MOUSE_PS2
+ 	default y
+ 	select SERIO
+ 	select SERIO_LIBPS2
+-	select SERIO_I8042 if PC
++	select SERIO_I8042 if X86_PC
+ 	select SERIO_GSCPS2 if GSC
+ 	---help---
+ 	  Say Y here if you have a PS/2 mouse connected to your system. This
+diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
+--- a/drivers/input/mouse/alps.c
++++ b/drivers/input/mouse/alps.c
+@@ -79,8 +79,8 @@ static void alps_process_packet(struct p
+ {
+ 	struct alps_data *priv = psmouse->private;
+ 	unsigned char *packet = psmouse->packet;
+-	struct input_dev *dev = &psmouse->dev;
+-	struct input_dev *dev2 = &priv->dev2;
++	struct input_dev *dev = psmouse->dev;
++	struct input_dev *dev2 = priv->dev2;
+ 	int x, y, z, ges, fin, left, right, middle;
+ 	int back = 0, forward = 0;
+ 
+@@ -379,20 +379,24 @@ static int alps_reconnect(struct psmouse
+ static void alps_disconnect(struct psmouse *psmouse)
+ {
+ 	struct alps_data *priv = psmouse->private;
++
+ 	psmouse_reset(psmouse);
+-	input_unregister_device(&priv->dev2);
++	input_unregister_device(priv->dev2);
+ 	kfree(priv);
+ }
+ 
+ int alps_init(struct psmouse *psmouse)
+ {
+ 	struct alps_data *priv;
++	struct input_dev *dev1 = psmouse->dev, *dev2;
+ 	int version;
+ 
+-	psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL);
+-	if (!priv)
++	psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
++	dev2 = input_allocate_device();
++	if (!priv || !dev2)
+ 		goto init_fail;
+-	memset(priv, 0, sizeof(struct alps_data));
++
++	priv->dev2 = dev2;
+ 
+ 	if (!(priv->i = alps_get_model(psmouse, &version)))
+ 		goto init_fail;
+@@ -411,41 +415,39 @@ int alps_init(struct psmouse *psmouse)
+ 	if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
+ 		goto init_fail;
+ 
+-	psmouse->dev.evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
+-	psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
+-	psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
+-	psmouse->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+-
+-	psmouse->dev.evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
+-	input_set_abs_params(&psmouse->dev, ABS_X, 0, 1023, 0, 0);
+-	input_set_abs_params(&psmouse->dev, ABS_Y, 0, 767, 0, 0);
+-	input_set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0);
++	dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
++	dev1->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
++	dev1->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
++	dev1->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++
++	dev1->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
++	input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
++	input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
++	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
+ 
+ 	if (priv->i->flags & ALPS_WHEEL) {
+-		psmouse->dev.evbit[LONG(EV_REL)] |= BIT(EV_REL);
+-		psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
++		dev1->evbit[LONG(EV_REL)] |= BIT(EV_REL);
++		dev1->relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
+ 	}
+ 
+ 	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
+-		psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
+-		psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
++		dev1->keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
++		dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
+ 	}
+ 
+ 	sprintf(priv->phys, "%s/input1", psmouse->ps2dev.serio->phys);
+-	priv->dev2.phys = priv->phys;
+-	priv->dev2.name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
+-	priv->dev2.id.bustype = BUS_I8042;
+-	priv->dev2.id.vendor = 0x0002;
+-	priv->dev2.id.product = PSMOUSE_ALPS;
+-	priv->dev2.id.version = 0x0000;
+-
+-	priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+-	priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
+-	priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+-
+-	input_register_device(&priv->dev2);
++	dev2->phys = priv->phys;
++	dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
++	dev2->id.bustype = BUS_I8042;
++	dev2->id.vendor  = 0x0002;
++	dev2->id.product = PSMOUSE_ALPS;
++	dev2->id.version = 0x0000;
++
++	dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++	dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
++	dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ 
+-	printk(KERN_INFO "input: %s on %s\n", priv->dev2.name, psmouse->ps2dev.serio->phys);
++	input_register_device(priv->dev2);
+ 
+ 	psmouse->protocol_handler = alps_process_byte;
+ 	psmouse->disconnect = alps_disconnect;
+@@ -455,6 +457,7 @@ int alps_init(struct psmouse *psmouse)
+ 	return 0;
+ 
+ init_fail:
++	input_free_device(dev2);
+ 	kfree(priv);
+ 	return -1;
+ }
+diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
+--- a/drivers/input/mouse/alps.h
++++ b/drivers/input/mouse/alps.h
+@@ -22,7 +22,7 @@ struct alps_model_info {
+ };
+ 
+ struct alps_data {
+-	struct input_dev dev2;		/* Relative device */
++	struct input_dev *dev2;		/* Relative device */
+ 	char name[32];			/* Name */
+ 	char phys[32];			/* Phys */
+ 	struct alps_model_info *i; 	/* Info */
+diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
+--- a/drivers/input/mouse/amimouse.c
++++ b/drivers/input/mouse/amimouse.c
+@@ -34,10 +34,7 @@ MODULE_DESCRIPTION("Amiga mouse driver")
+ MODULE_LICENSE("GPL");
+ 
+ static int amimouse_lastx, amimouse_lasty;
+-static struct input_dev amimouse_dev;
+-
+-static char *amimouse_name = "Amiga mouse";
+-static char *amimouse_phys = "amimouse/input0";
++static struct input_dev *amimouse_dev;
+ 
+ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
+ {
+@@ -62,16 +59,16 @@ static irqreturn_t amimouse_interrupt(in
+ 
+ 	potgor = custom.potgor;
+ 
+-	input_regs(&amimouse_dev, fp);
++	input_regs(amimouse_dev, fp);
+ 
+-	input_report_rel(&amimouse_dev, REL_X, dx);
+-	input_report_rel(&amimouse_dev, REL_Y, dy);
++	input_report_rel(amimouse_dev, REL_X, dx);
++	input_report_rel(amimouse_dev, REL_Y, dy);
+ 
+-	input_report_key(&amimouse_dev, BTN_LEFT,   ciaa.pra & 0x40);
+-	input_report_key(&amimouse_dev, BTN_MIDDLE, potgor & 0x0100);
+-	input_report_key(&amimouse_dev, BTN_RIGHT,  potgor & 0x0400);
++	input_report_key(amimouse_dev, BTN_LEFT,   ciaa.pra & 0x40);
++	input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100);
++	input_report_key(amimouse_dev, BTN_RIGHT,  potgor & 0x0400);
+ 
+-	input_sync(&amimouse_dev);
++	input_sync(amimouse_dev);
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -103,28 +100,30 @@ static int __init amimouse_init(void)
+ 	if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE))
+ 		return -ENODEV;
+ 
+-	amimouse_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+-	amimouse_dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+-	amimouse_dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+-	amimouse_dev.open = amimouse_open;
+-	amimouse_dev.close = amimouse_close;
+-
+-	amimouse_dev.name = amimouse_name;
+-	amimouse_dev.phys = amimouse_phys;
+-	amimouse_dev.id.bustype = BUS_AMIGA;
+-	amimouse_dev.id.vendor = 0x0001;
+-	amimouse_dev.id.product = 0x0002;
+-	amimouse_dev.id.version = 0x0100;
++	if (!(amimouse_dev = input_allocate_device()))
++		return -ENOMEM;
++
++	amimouse_dev->name = "Amiga mouse";
++	amimouse_dev->phys = "amimouse/input0";
++	amimouse_dev->id.bustype = BUS_AMIGA;
++	amimouse_dev->id.vendor = 0x0001;
++	amimouse_dev->id.product = 0x0002;
++	amimouse_dev->id.version = 0x0100;
++
++	amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++	amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
++	amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++	amimouse_dev->open = amimouse_open;
++	amimouse_dev->close = amimouse_close;
+ 
+-	input_register_device(&amimouse_dev);
++	input_register_device(amimouse_dev);
+ 
+-        printk(KERN_INFO "input: %s at joy0dat\n", amimouse_name);
+ 	return 0;
+ }
+ 
+ static void __exit amimouse_exit(void)
+ {
+-        input_unregister_device(&amimouse_dev);
++        input_unregister_device(amimouse_dev);
+ }
+ 
+ module_init(amimouse_init);
+diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
+--- a/drivers/input/mouse/hil_ptr.c
++++ b/drivers/input/mouse/hil_ptr.c
+@@ -196,7 +196,7 @@ static irqreturn_t hil_ptr_interrupt(str
+ 	hil_packet packet;
+ 	int idx;
+ 
+-	ptr = (struct hil_ptr *)serio->private;
++	ptr = serio_get_drvdata(serio);
+ 	if (ptr == NULL) {
+ 		BUG();
+ 		return IRQ_HANDLED;
+@@ -227,7 +227,7 @@ static void hil_ptr_disconnect(struct se
+ {
+ 	struct hil_ptr *ptr;
+ 
+-	ptr = (struct hil_ptr *)serio->private;
++	ptr = serio_get_drvdata(serio);
+ 	if (ptr == NULL) {
+ 		BUG();
+ 		return;
+@@ -238,21 +238,19 @@ static void hil_ptr_disconnect(struct se
+ 	kfree(ptr);
+ }
+ 
+-static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
++static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
+ {
+ 	struct hil_ptr	*ptr;
+ 	char		*txt;
+ 	unsigned int	i, naxsets, btntype;
+ 	uint8_t		did, *idd;
+ 
+-	if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return;
+-
+-	if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return;
++	if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM;
+ 	memset(ptr, 0, sizeof(struct hil_ptr));
+ 
+ 	if (serio_open(serio, driver)) goto bail0;
+ 
+-	serio->private = ptr;
++	serio_set_drvdata(serio, ptr);
+ 	ptr->serio = serio;
+ 	ptr->dev.private = ptr;
+ 
+@@ -380,23 +378,34 @@ static void hil_ptr_connect(struct serio
+ 		(btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
+ 		did);
+ 
+-	return;
++	return 0;
+  bail1:
+ 	serio_close(serio);
+  bail0:
+ 	kfree(ptr);
+-	return;
++	serio_set_drvdata(serio, NULL);
++	return -ENODEV;
+ }
+ 
++static struct serio_device_id hil_ptr_ids[] = {
++	{
++		.type = SERIO_HIL_MLC,
++		.proto = SERIO_HIL,
++		.id = SERIO_ANY,
++		.extra = SERIO_ANY,
++	},
++	{ 0 }
++};
+ 
+ static struct serio_driver hil_ptr_serio_driver = {
+ 	.driver		= {
+ 		.name	= "hil_ptr",
+ 	},
+ 	.description	= "HP HIL mouse/tablet driver",
+-	.connect =	hil_ptr_connect,
+-	.disconnect =	hil_ptr_disconnect,
+-	.interrupt =	hil_ptr_interrupt
++	.id_table	= hil_ptr_ids,
++	.connect	= hil_ptr_connect,
++	.disconnect	= hil_ptr_disconnect,
++	.interrupt	= hil_ptr_interrupt
+ };
+ 
+ static int __init hil_ptr_init(void)
+diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
+--- a/drivers/input/mouse/inport.c
++++ b/drivers/input/mouse/inport.c
+@@ -87,40 +87,7 @@ MODULE_PARM_DESC(irq, "IRQ number (5=def
+ 
+ __obsolete_setup("inport_irq=");
+ 
+-static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+-
+-static int inport_open(struct input_dev *dev)
+-{
+-	if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
+-		return -EBUSY;
+-	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+-	outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
+-
+-	return 0;
+-}
+-
+-static void inport_close(struct input_dev *dev)
+-{
+-	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+-	outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
+-	free_irq(inport_irq, NULL);
+-}
+-
+-static struct input_dev inport_dev = {
+-	.evbit	= { BIT(EV_KEY) | BIT(EV_REL) },
+-	.keybit	= { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
+-	.relbit	= { BIT(REL_X) | BIT(REL_Y) },
+-	.open	= inport_open,
+-	.close	= inport_close,
+-	.name	= INPORT_NAME,
+-	.phys	= "isa023c/input0",
+-	.id = {
+-		.bustype = BUS_ISA,
+-		.vendor  = INPORT_VENDOR,
+-		.product = 0x0001,
+-		.version = 0x0100,
+-	},
+-};
++static struct input_dev *inport_dev;
+ 
+ static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+@@ -129,31 +96,48 @@ static irqreturn_t inport_interrupt(int 
+ 	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+ 	outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
+ 
+-	input_regs(&inport_dev, regs);
++	input_regs(inport_dev, regs);
+ 
+ 	outb(INPORT_REG_X, INPORT_CONTROL_PORT);
+-	input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_PORT));
++	input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT));
+ 
+ 	outb(INPORT_REG_Y, INPORT_CONTROL_PORT);
+-	input_report_rel(&inport_dev, REL_Y, inb(INPORT_DATA_PORT));
++	input_report_rel(inport_dev, REL_Y, inb(INPORT_DATA_PORT));
+ 
+ 	outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT);
+ 	buttons = inb(INPORT_DATA_PORT);
+ 
+-	input_report_key(&inport_dev, BTN_MIDDLE, buttons & 1);
+-	input_report_key(&inport_dev, BTN_LEFT,   buttons & 2);
+-	input_report_key(&inport_dev, BTN_RIGHT,  buttons & 4);
++	input_report_key(inport_dev, BTN_MIDDLE, buttons & 1);
++	input_report_key(inport_dev, BTN_LEFT,   buttons & 2);
++	input_report_key(inport_dev, BTN_RIGHT,  buttons & 4);
+ 
+ 	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+ 	outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
+ 
+-	input_sync(&inport_dev);
++	input_sync(inport_dev);
+ 	return IRQ_HANDLED;
+ }
+ 
++static int inport_open(struct input_dev *dev)
++{
++	if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
++		return -EBUSY;
++	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
++	outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
++
++	return 0;
++}
++
++static void inport_close(struct input_dev *dev)
++{
++	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
++	outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
++	free_irq(inport_irq, NULL);
++}
++
+ static int __init inport_init(void)
+ {
+-	unsigned char a,b,c;
++	unsigned char a, b, c;
+ 
+ 	if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) {
+ 		printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE);
+@@ -163,26 +147,44 @@ static int __init inport_init(void)
+ 	a = inb(INPORT_SIGNATURE_PORT);
+ 	b = inb(INPORT_SIGNATURE_PORT);
+ 	c = inb(INPORT_SIGNATURE_PORT);
+-	if (( a == b ) || ( a != c )) {
++	if (a == b || a != c) {
+ 		release_region(INPORT_BASE, INPORT_EXTENT);
+ 		printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE);
+ 		return -ENODEV;
+ 	}
+ 
++	if (!(inport_dev = input_allocate_device())) {
++		printk(KERN_ERR "inport.c: Not enough memory for input device\n");
++		release_region(INPORT_BASE, INPORT_EXTENT);
++		return -ENOMEM;
++	}
++
++	inport_dev->name = INPORT_NAME;
++	inport_dev->phys = "isa023c/input0";
++	inport_dev->id.bustype = BUS_ISA;
++	inport_dev->id.vendor  = INPORT_VENDOR;
++	inport_dev->id.product = 0x0001;
++	inport_dev->id.version = 0x0100;
++
++	inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++	inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++	inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
++
++	inport_dev->open  = inport_open;
++	inport_dev->close = inport_close;
++
+ 	outb(INPORT_RESET, INPORT_CONTROL_PORT);
+ 	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+ 	outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
+ 
+-	input_register_device(&inport_dev);
+-
+-	printk(KERN_INFO "input: " INPORT_NAME " at %#x irq %d\n", INPORT_BASE, inport_irq);
++	input_register_device(inport_dev);
+ 
+ 	return 0;
+ }
+ 
+ static void __exit inport_exit(void)
+ {
+-	input_unregister_device(&inport_dev);
++	input_unregister_device(inport_dev);
+ 	release_region(INPORT_BASE, INPORT_EXTENT);
+ }
+ 
+diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
+--- a/drivers/input/mouse/lifebook.c
++++ b/drivers/input/mouse/lifebook.c
+@@ -34,7 +34,7 @@ static struct dmi_system_id lifebook_dmi
+ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+ {
+ 	unsigned char *packet = psmouse->packet;
+-	struct input_dev *dev = &psmouse->dev;
++	struct input_dev *dev = psmouse->dev;
+ 
+ 	if (psmouse->pktcnt != 3)
+ 		return PSMOUSE_GOOD_DATA;
+@@ -113,15 +113,17 @@ int lifebook_detect(struct psmouse *psmo
+ 
+ int lifebook_init(struct psmouse *psmouse)
+ {
++	struct input_dev *input_dev = psmouse->dev;
++
+ 	if (lifebook_absolute_mode(psmouse))
+ 		return -1;
+ 
+-	psmouse->dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
+-	psmouse->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+-	psmouse->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+-	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+-	input_set_abs_params(&psmouse->dev, ABS_X, 0, 1024, 0, 0);
+-	input_set_abs_params(&psmouse->dev, ABS_Y, 0, 1024, 0, 0);
++	input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
++	input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
++	input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0);
++	input_set_abs_params(input_dev, ABS_Y, 0, 1024, 0, 0);
+ 
+ 	psmouse->protocol_handler = lifebook_process_byte;
+ 	psmouse->set_resolution = lifebook_set_resolution;
+diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
+--- a/drivers/input/mouse/logibm.c
++++ b/drivers/input/mouse/logibm.c
+@@ -77,39 +77,7 @@ MODULE_PARM_DESC(irq, "IRQ number (5=def
+ 
+ __obsolete_setup("logibm_irq=");
+ 
+-static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+-
+-static int logibm_open(struct input_dev *dev)
+-{
+-	if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) {
+-		printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq);
+-		return -EBUSY;
+-	}
+-	outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
+-	return 0;
+-}
+-
+-static void logibm_close(struct input_dev *dev)
+-{
+-	outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
+-	free_irq(logibm_irq, NULL);
+-}
+-
+-static struct input_dev logibm_dev = {
+-	.evbit	= { BIT(EV_KEY) | BIT(EV_REL) },
+-	.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
+-	.relbit	= { BIT(REL_X) | BIT(REL_Y) },
+-	.open	= logibm_open,
+-	.close	= logibm_close,
+-	.name	= "Logitech bus mouse",
+-	.phys	= "isa023c/input0",
+-	.id	= {
+-		.bustype = BUS_ISA,
+-		.vendor  = 0x0003,
+-		.product = 0x0001,
+-		.version = 0x0100,
+-	},
+-};
++static struct input_dev *logibm_dev;
+ 
+ static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+@@ -127,18 +95,34 @@ static irqreturn_t logibm_interrupt(int 
+ 	dy |= (buttons & 0xf) << 4;
+ 	buttons = ~buttons >> 5;
+ 
+-	input_regs(&logibm_dev, regs);
+-	input_report_rel(&logibm_dev, REL_X, dx);
+-	input_report_rel(&logibm_dev, REL_Y, dy);
+-	input_report_key(&logibm_dev, BTN_RIGHT,  buttons & 1);
+-	input_report_key(&logibm_dev, BTN_MIDDLE, buttons & 2);
+-	input_report_key(&logibm_dev, BTN_LEFT,   buttons & 4);
+-	input_sync(&logibm_dev);
++	input_regs(logibm_dev, regs);
++	input_report_rel(logibm_dev, REL_X, dx);
++	input_report_rel(logibm_dev, REL_Y, dy);
++	input_report_key(logibm_dev, BTN_RIGHT,  buttons & 1);
++	input_report_key(logibm_dev, BTN_MIDDLE, buttons & 2);
++	input_report_key(logibm_dev, BTN_LEFT,   buttons & 4);
++	input_sync(logibm_dev);
+ 
+ 	outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
+ 	return IRQ_HANDLED;
+ }
+ 
++static int logibm_open(struct input_dev *dev)
++{
++	if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) {
++		printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq);
++		return -EBUSY;
++	}
++	outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
++	return 0;
++}
++
++static void logibm_close(struct input_dev *dev)
++{
++	outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
++	free_irq(logibm_irq, NULL);
++}
++
+ static int __init logibm_init(void)
+ {
+ 	if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "logibm")) {
+@@ -159,16 +143,34 @@ static int __init logibm_init(void)
+ 	outb(LOGIBM_DEFAULT_MODE, LOGIBM_CONFIG_PORT);
+ 	outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
+ 
+-	input_register_device(&logibm_dev);
++	if (!(logibm_dev = input_allocate_device())) {
++		printk(KERN_ERR "logibm.c: Not enough memory for input device\n");
++		release_region(LOGIBM_BASE, LOGIBM_EXTENT);
++		return -ENOMEM;
++	}
++
++	logibm_dev->name = "Logitech bus mouse";
++	logibm_dev->phys = "isa023c/input0";
++	logibm_dev->id.bustype = BUS_ISA;
++	logibm_dev->id.vendor  = 0x0003;
++	logibm_dev->id.product = 0x0001;
++	logibm_dev->id.version = 0x0100;
++
++	logibm_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++	logibm_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++	logibm_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
++
++	logibm_dev->open  = logibm_open;
++	logibm_dev->close = logibm_close;
+ 
+-	printk(KERN_INFO "input: Logitech bus mouse at %#x irq %d\n", LOGIBM_BASE, logibm_irq);
++	input_register_device(logibm_dev);
+ 
+ 	return 0;
+ }
+ 
+ static void __exit logibm_exit(void)
+ {
+-	input_unregister_device(&logibm_dev);
++	input_unregister_device(logibm_dev);
+ 	release_region(LOGIBM_BASE, LOGIBM_EXTENT);
+ }
+ 
+diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
+--- a/drivers/input/mouse/logips2pp.c
++++ b/drivers/input/mouse/logips2pp.c
+@@ -40,7 +40,7 @@ struct ps2pp_info {
+ 
+ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &psmouse->dev;
++	struct input_dev *dev = psmouse->dev;
+ 	unsigned char *packet = psmouse->packet;
+ 
+ 	if (psmouse->pktcnt < 3)
+@@ -257,25 +257,27 @@ static struct ps2pp_info *get_model_info
+ static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info,
+ 				       int using_ps2pp)
+ {
++	struct input_dev *input_dev = psmouse->dev;
++
+ 	if (model_info->features & PS2PP_SIDE_BTN)
+-		set_bit(BTN_SIDE, psmouse->dev.keybit);
++		set_bit(BTN_SIDE, input_dev->keybit);
+ 
+ 	if (model_info->features & PS2PP_EXTRA_BTN)
+-		set_bit(BTN_EXTRA, psmouse->dev.keybit);
++		set_bit(BTN_EXTRA, input_dev->keybit);
+ 
+ 	if (model_info->features & PS2PP_TASK_BTN)
+-		set_bit(BTN_TASK, psmouse->dev.keybit);
++		set_bit(BTN_TASK, input_dev->keybit);
+ 
+ 	if (model_info->features & PS2PP_NAV_BTN) {
+-		set_bit(BTN_FORWARD, psmouse->dev.keybit);
+-		set_bit(BTN_BACK, psmouse->dev.keybit);
++		set_bit(BTN_FORWARD, input_dev->keybit);
++		set_bit(BTN_BACK, input_dev->keybit);
+ 	}
+ 
+ 	if (model_info->features & PS2PP_WHEEL)
+-		set_bit(REL_WHEEL, psmouse->dev.relbit);
++		set_bit(REL_WHEEL, input_dev->relbit);
+ 
+ 	if (model_info->features & PS2PP_HWHEEL)
+-		set_bit(REL_HWHEEL, psmouse->dev.relbit);
++		set_bit(REL_HWHEEL, input_dev->relbit);
+ 
+ 	switch (model_info->kind) {
+ 		case PS2PP_KIND_WHEEL:
+@@ -387,7 +389,7 @@ int ps2pp_init(struct psmouse *psmouse, 
+ 		}
+ 
+ 		if (buttons < 3)
+-			clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
++			clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
+ 
+ 		if (model_info)
+ 			ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
+diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c
+--- a/drivers/input/mouse/maplemouse.c
++++ b/drivers/input/mouse/maplemouse.c
+@@ -41,13 +41,12 @@ static int dc_mouse_connect(struct maple
+ 	unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
+ 	struct input_dev *input_dev;
+ 
+-	if (!(input_dev = kmalloc(sizeof(struct input_dev), GFP_KERNEL)))
+-		return -1;
++	dev->private_data = input_dev = input_allocate_device();
++	if (!input_dev)
++		return -ENOMEM;
+ 
+ 	dev->private_data = input_dev;
+ 
+-	memset(input_dev, 0, sizeof(struct dc_mouse));
+-	init_input_dev(input_dev);
+ 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ 	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+ 	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL);
+@@ -59,8 +58,6 @@ static int dc_mouse_connect(struct maple
+ 
+ 	maple_getcond_callback(dev, dc_mouse_callback, 1, MAPLE_FUNC_MOUSE);
+ 
+-	printk(KERN_INFO "input: mouse(0x%lx): %s\n", data, input_dev->name);
+-
+ 	return 0;
+ }
+ 
+@@ -70,7 +67,6 @@ static void dc_mouse_disconnect(struct m
+ 	struct input_dev *input_dev = dev->private_data;
+ 
+ 	input_unregister_device(input_dev);
+-	kfree(input_dev);
+ }
+ 
+ 
+diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
+--- a/drivers/input/mouse/pc110pad.c
++++ b/drivers/input/mouse/pc110pad.c
+@@ -53,13 +53,10 @@ MODULE_LICENSE("GPL");
+ static int pc110pad_irq = 10;
+ static int pc110pad_io = 0x15e0;
+ 
+-static struct input_dev pc110pad_dev;
++static struct input_dev *pc110pad_dev;
+ static int pc110pad_data[3];
+ static int pc110pad_count;
+ 
+-static char *pc110pad_name = "IBM PC110 TouchPad";
+-static char *pc110pad_phys = "isa15e0/input0";
+-
+ static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs)
+ {
+ 	int value     = inb_p(pc110pad_io);
+@@ -74,14 +71,14 @@ static irqreturn_t pc110pad_interrupt(in
+ 	if (pc110pad_count < 3)
+ 		return IRQ_HANDLED;
+ 
+-	input_regs(&pc110pad_dev, regs);
+-	input_report_key(&pc110pad_dev, BTN_TOUCH,
++	input_regs(pc110pad_dev, regs);
++	input_report_key(pc110pad_dev, BTN_TOUCH,
+ 		pc110pad_data[0] & 0x01);
+-	input_report_abs(&pc110pad_dev, ABS_X,
++	input_report_abs(pc110pad_dev, ABS_X,
+ 		pc110pad_data[1] | ((pc110pad_data[0] << 3) & 0x80) | ((pc110pad_data[0] << 1) & 0x100));
+-	input_report_abs(&pc110pad_dev, ABS_Y,
++	input_report_abs(pc110pad_dev, ABS_Y,
+ 		pc110pad_data[2] | ((pc110pad_data[0] << 4) & 0x80));
+-	input_sync(&pc110pad_dev);
++	input_sync(pc110pad_dev);
+ 
+ 	pc110pad_count = 0;
+ 	return IRQ_HANDLED;
+@@ -94,9 +91,9 @@ static void pc110pad_close(struct input_
+ 
+ static int pc110pad_open(struct input_dev *dev)
+ {
+-	pc110pad_interrupt(0,NULL,NULL);
+-	pc110pad_interrupt(0,NULL,NULL);
+-	pc110pad_interrupt(0,NULL,NULL);
++	pc110pad_interrupt(0, NULL, NULL);
++	pc110pad_interrupt(0, NULL, NULL);
++	pc110pad_interrupt(0, NULL, NULL);
+ 	outb(PC110PAD_ON, pc110pad_io + 2);
+ 	pc110pad_count = 0;
+ 
+@@ -127,45 +124,46 @@ static int __init pc110pad_init(void)
+ 
+ 	outb(PC110PAD_OFF, pc110pad_io + 2);
+ 
+-	if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL))
+-	{
++	if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) {
+ 		release_region(pc110pad_io, 4);
+ 		printk(KERN_ERR "pc110pad: Unable to get irq %d.\n", pc110pad_irq);
+ 		return -EBUSY;
+ 	}
+ 
+-        pc110pad_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-        pc110pad_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+-        pc110pad_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+-
+-	pc110pad_dev.absmax[ABS_X] = 0x1ff;
+-	pc110pad_dev.absmax[ABS_Y] = 0x0ff;
+-
+-	pc110pad_dev.open = pc110pad_open;
+-        pc110pad_dev.close = pc110pad_close;
+-
+-	pc110pad_dev.name = pc110pad_name;
+-	pc110pad_dev.phys = pc110pad_phys;
+-	pc110pad_dev.id.bustype = BUS_ISA;
+-	pc110pad_dev.id.vendor = 0x0003;
+-	pc110pad_dev.id.product = 0x0001;
+-	pc110pad_dev.id.version = 0x0100;
++	if (!(pc110pad_dev = input_allocate_device())) {
++		free_irq(pc110pad_irq, NULL);
++		release_region(pc110pad_io, 4);
++		printk(KERN_ERR "pc110pad: Not enough memory.\n");
++		return -ENOMEM;
++	}
++
++	pc110pad_dev->name = "IBM PC110 TouchPad";
++	pc110pad_dev->phys = "isa15e0/input0";
++	pc110pad_dev->id.bustype = BUS_ISA;
++	pc110pad_dev->id.vendor = 0x0003;
++	pc110pad_dev->id.product = 0x0001;
++	pc110pad_dev->id.version = 0x0100;
++
++	pc110pad_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	pc110pad_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
++	pc110pad_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ 
+-	input_register_device(&pc110pad_dev);
++	pc110pad_dev->absmax[ABS_X] = 0x1ff;
++	pc110pad_dev->absmax[ABS_Y] = 0x0ff;
+ 
+-	printk(KERN_INFO "input: %s at %#x irq %d\n",
+-		pc110pad_name, pc110pad_io, pc110pad_irq);
++	pc110pad_dev->open = pc110pad_open;
++	pc110pad_dev->close = pc110pad_close;
++
++	input_register_device(pc110pad_dev);
+ 
+ 	return 0;
+ }
+ 
+ static void __exit pc110pad_exit(void)
+ {
+-	input_unregister_device(&pc110pad_dev);
+-
+ 	outb(PC110PAD_OFF, pc110pad_io + 2);
+-
+ 	free_irq(pc110pad_irq, NULL);
++	input_unregister_device(pc110pad_dev);
+ 	release_region(pc110pad_io, 4);
+ }
+ 
+diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
+--- a/drivers/input/mouse/psmouse-base.c
++++ b/drivers/input/mouse/psmouse-base.c
+@@ -114,7 +114,7 @@ struct psmouse_protocol {
+ 
+ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &psmouse->dev;
++	struct input_dev *dev = psmouse->dev;
+ 	unsigned char *packet = psmouse->packet;
+ 
+ 	if (psmouse->pktcnt < psmouse->pktsize)
+@@ -333,12 +333,11 @@ static int genius_detect(struct psmouse 
+ 		return -1;
+ 
+ 	if (set_properties) {
+-		set_bit(BTN_EXTRA, psmouse->dev.keybit);
+-		set_bit(BTN_SIDE, psmouse->dev.keybit);
+-		set_bit(REL_WHEEL, psmouse->dev.relbit);
++		set_bit(BTN_EXTRA, psmouse->dev->keybit);
++		set_bit(BTN_SIDE, psmouse->dev->keybit);
++		set_bit(REL_WHEEL, psmouse->dev->relbit);
+ 
+ 		psmouse->vendor = "Genius";
+-		psmouse->name = "Wheel Mouse";
+ 		psmouse->pktsize = 4;
+ 	}
+ 
+@@ -365,8 +364,8 @@ static int intellimouse_detect(struct ps
+ 		return -1;
+ 
+ 	if (set_properties) {
+-		set_bit(BTN_MIDDLE, psmouse->dev.keybit);
+-		set_bit(REL_WHEEL, psmouse->dev.relbit);
++		set_bit(BTN_MIDDLE, psmouse->dev->keybit);
++		set_bit(REL_WHEEL, psmouse->dev->relbit);
+ 
+ 		if (!psmouse->vendor) psmouse->vendor = "Generic";
+ 		if (!psmouse->name) psmouse->name = "Wheel Mouse";
+@@ -398,10 +397,10 @@ static int im_explorer_detect(struct psm
+ 		return -1;
+ 
+ 	if (set_properties) {
+-		set_bit(BTN_MIDDLE, psmouse->dev.keybit);
+-		set_bit(REL_WHEEL, psmouse->dev.relbit);
+-		set_bit(BTN_SIDE, psmouse->dev.keybit);
+-		set_bit(BTN_EXTRA, psmouse->dev.keybit);
++		set_bit(BTN_MIDDLE, psmouse->dev->keybit);
++		set_bit(REL_WHEEL, psmouse->dev->relbit);
++		set_bit(BTN_SIDE, psmouse->dev->keybit);
++		set_bit(BTN_EXTRA, psmouse->dev->keybit);
+ 
+ 		if (!psmouse->vendor) psmouse->vendor = "Generic";
+ 		if (!psmouse->name) psmouse->name = "Explorer Mouse";
+@@ -433,7 +432,7 @@ static int thinking_detect(struct psmous
+ 		return -1;
+ 
+ 	if (set_properties) {
+-		set_bit(BTN_EXTRA, psmouse->dev.keybit);
++		set_bit(BTN_EXTRA, psmouse->dev->keybit);
+ 
+ 		psmouse->vendor = "Kensington";
+ 		psmouse->name = "ThinkingMouse";
+@@ -839,9 +838,9 @@ static void psmouse_disconnect(struct se
+ 
+ 	psmouse_set_state(psmouse, PSMOUSE_IGNORE);
+ 
+-	input_unregister_device(&psmouse->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(psmouse->dev);
+ 	kfree(psmouse);
+ 
+ 	if (parent)
+@@ -852,16 +851,14 @@ static void psmouse_disconnect(struct se
+ 
+ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto)
+ {
+-	memset(&psmouse->dev, 0, sizeof(struct input_dev));
++	struct input_dev *input_dev = psmouse->dev;
+ 
+-	init_input_dev(&psmouse->dev);
++	input_dev->private = psmouse;
++	input_dev->cdev.dev = &psmouse->ps2dev.serio->dev;
+ 
+-	psmouse->dev.private = psmouse;
+-	psmouse->dev.dev = &psmouse->ps2dev.serio->dev;
+-
+-	psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+-	psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+-	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ 
+ 	psmouse->set_rate = psmouse_set_rate;
+ 	psmouse->set_resolution = psmouse_set_resolution;
+@@ -883,12 +880,12 @@ static int psmouse_switch_protocol(struc
+ 	sprintf(psmouse->devname, "%s %s %s",
+ 		psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
+ 
+-	psmouse->dev.name = psmouse->devname;
+-	psmouse->dev.phys = psmouse->phys;
+-	psmouse->dev.id.bustype = BUS_I8042;
+-	psmouse->dev.id.vendor = 0x0002;
+-	psmouse->dev.id.product = psmouse->type;
+-	psmouse->dev.id.version = psmouse->model;
++	input_dev->name = psmouse->devname;
++	input_dev->phys = psmouse->phys;
++	input_dev->id.bustype = BUS_I8042;
++	input_dev->id.vendor = 0x0002;
++	input_dev->id.product = psmouse->type;
++	input_dev->id.version = psmouse->model;
+ 
+ 	return 0;
+ }
+@@ -900,7 +897,8 @@ static int psmouse_switch_protocol(struc
+ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct psmouse *psmouse, *parent = NULL;
+-	int retval;
++	struct input_dev *input_dev;
++	int retval = -ENOMEM;
+ 
+ 	down(&psmouse_sem);
+ 
+@@ -913,12 +911,13 @@ static int psmouse_connect(struct serio 
+ 		psmouse_deactivate(parent);
+ 	}
+ 
+-	if (!(psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL))) {
+-		retval = -ENOMEM;
++	psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!psmouse || !input_dev)
+ 		goto out;
+-	}
+ 
+ 	ps2_init(&psmouse->ps2dev, serio);
++	psmouse->dev = input_dev;
+ 	sprintf(psmouse->phys, "%s/input0", serio->phys);
+ 
+ 	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+@@ -926,16 +925,11 @@ static int psmouse_connect(struct serio 
+ 	serio_set_drvdata(serio, psmouse);
+ 
+ 	retval = serio_open(serio, drv);
+-	if (retval) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(psmouse);
++	if (retval)
+ 		goto out;
+-	}
+ 
+ 	if (psmouse_probe(psmouse) < 0) {
+ 		serio_close(serio);
+-		serio_set_drvdata(serio, NULL);
+-		kfree(psmouse);
+ 		retval = -ENODEV;
+ 		goto out;
+ 	}
+@@ -947,13 +941,11 @@ static int psmouse_connect(struct serio 
+ 
+ 	psmouse_switch_protocol(psmouse, NULL);
+ 
+-	input_register_device(&psmouse->dev);
+-	printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
+-
+ 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
+-
+ 	psmouse_initialize(psmouse);
+ 
++	input_register_device(psmouse->dev);
++
+ 	if (parent && parent->pt_activate)
+ 		parent->pt_activate(parent);
+ 
+@@ -964,6 +956,12 @@ static int psmouse_connect(struct serio 
+ 	retval = 0;
+ 
+ out:
++	if (retval) {
++		serio_set_drvdata(serio, NULL);
++		input_free_device(input_dev);
++		kfree(psmouse);
++	}
++
+ 	/* If this is a pass-through port the parent needs to be re-activated */
+ 	if (parent)
+ 		psmouse_activate(parent);
+@@ -1161,6 +1159,7 @@ static ssize_t psmouse_attr_set_protocol
+ {
+ 	struct serio *serio = psmouse->ps2dev.serio;
+ 	struct psmouse *parent = NULL;
++	struct input_dev *new_dev;
+ 	struct psmouse_protocol *proto;
+ 	int retry = 0;
+ 
+@@ -1170,9 +1169,13 @@ static ssize_t psmouse_attr_set_protocol
+ 	if (psmouse->type == proto->type)
+ 		return count;
+ 
++	if (!(new_dev = input_allocate_device()))
++		return -ENOMEM;
++
+ 	while (serio->child) {
+ 		if (++retry > 3) {
+ 			printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n");
++			input_free_device(new_dev);
+ 			return -EIO;
+ 		}
+ 
+@@ -1182,11 +1185,15 @@ static ssize_t psmouse_attr_set_protocol
+ 		serio_pin_driver_uninterruptible(serio);
+ 		down(&psmouse_sem);
+ 
+-		if (serio->drv != &psmouse_drv)
++		if (serio->drv != &psmouse_drv) {
++			input_free_device(new_dev);
+ 			return -ENODEV;
++		}
+ 
+-		if (psmouse->type == proto->type)
++		if (psmouse->type == proto->type) {
++			input_free_device(new_dev);
+ 			return count; /* switched by other thread */
++		}
+ 	}
+ 
+ 	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
+@@ -1199,8 +1206,9 @@ static ssize_t psmouse_attr_set_protocol
+ 		psmouse->disconnect(psmouse);
+ 
+ 	psmouse_set_state(psmouse, PSMOUSE_IGNORE);
+-	input_unregister_device(&psmouse->dev);
++	input_unregister_device(psmouse->dev);
+ 
++	psmouse->dev = new_dev;
+ 	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+ 
+ 	if (psmouse_switch_protocol(psmouse, proto) < 0) {
+@@ -1212,8 +1220,7 @@ static ssize_t psmouse_attr_set_protocol
+ 	psmouse_initialize(psmouse);
+ 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
+ 
+-	input_register_device(&psmouse->dev);
+-	printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
++	input_register_device(psmouse->dev);
+ 
+ 	if (parent && parent->pt_activate)
+ 		parent->pt_activate(parent);
+diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
+--- a/drivers/input/mouse/psmouse.h
++++ b/drivers/input/mouse/psmouse.h
+@@ -36,7 +36,7 @@ typedef enum {
+ 
+ struct psmouse {
+ 	void *private;
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct ps2dev ps2dev;
+ 	char *vendor;
+ 	char *name;
+diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
+--- a/drivers/input/mouse/rpcmouse.c
++++ b/drivers/input/mouse/rpcmouse.c
+@@ -34,20 +34,7 @@ MODULE_DESCRIPTION("Acorn RiscPC mouse d
+ MODULE_LICENSE("GPL");
+ 
+ static short rpcmouse_lastx, rpcmouse_lasty;
+-
+-static struct input_dev rpcmouse_dev = {
+-	.evbit	= { BIT(EV_KEY) | BIT(EV_REL) },
+-	.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
+-	.relbit	= { BIT(REL_X) | BIT(REL_Y) },
+-	.name	= "Acorn RiscPC Mouse",
+-	.phys	= "rpcmouse/input0",
+-	.id	= {
+-		.bustype = BUS_HOST,
+-		.vendor  = 0x0005,
+-		.product = 0x0001,
+-		.version = 0x0100,
+-	},
+-};
++static struct input_dev *rpcmouse_dev;
+ 
+ static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs)
+ {
+@@ -78,29 +65,41 @@ static irqreturn_t rpcmouse_irq(int irq,
+ 	return IRQ_HANDLED;
+ }
+ 
++
+ static int __init rpcmouse_init(void)
+ {
+-	init_input_dev(&rpcmouse_dev);
++	if (!(rpcmouse_dev = input_allocate_device()))
++		return -ENOMEM;
++
++	rpcmouse_dev->name = "Acorn RiscPC Mouse";
++	rpcmouse_dev->phys = "rpcmouse/input0";
++	rpcmouse_dev->id.bustype = BUS_HOST;
++	rpcmouse_dev->id.vendor  = 0x0005;
++	rpcmouse_dev->id.product = 0x0001;
++	rpcmouse_dev->id.version = 0x0100;
++
++	rpcmouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++	rpcmouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++	rpcmouse_dev->relbit[0]	= BIT(REL_X) | BIT(REL_Y);
+ 
+ 	rpcmouse_lastx = (short) iomd_readl(IOMD_MOUSEX);
+ 	rpcmouse_lasty = (short) iomd_readl(IOMD_MOUSEY);
+ 
+-	if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, SA_SHIRQ, "rpcmouse", &rpcmouse_dev)) {
++	if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, SA_SHIRQ, "rpcmouse", rpcmouse_dev)) {
+ 		printk(KERN_ERR "rpcmouse: unable to allocate VSYNC interrupt\n");
+-		return -1;
++		input_free_device(rpcmouse_dev);
++		return -EBUSY;
+ 	}
+ 
+-	input_register_device(&rpcmouse_dev);
+-
+-	printk(KERN_INFO "input: Acorn RiscPC mouse\n");
++	input_register_device(rpcmouse_dev);
+ 
+ 	return 0;
+ }
+ 
+ static void __exit rpcmouse_exit(void)
+ {
+-	input_unregister_device(&rpcmouse_dev);
+-	free_irq(IRQ_VSYNCPULSE, &rpcmouse_dev);
++	free_irq(IRQ_VSYNCPULSE, rpcmouse_dev);
++	input_unregister_device(rpcmouse_dev);
+ }
+ 
+ module_init(rpcmouse_init);
+diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
+--- a/drivers/input/mouse/sermouse.c
++++ b/drivers/input/mouse/sermouse.c
+@@ -48,7 +48,7 @@ static char *sermouse_protocols[] = { "N
+ 					"Logitech MZ++ Mouse"};
+ 
+ struct sermouse {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	signed char buf[8];
+ 	unsigned char count;
+ 	unsigned char type;
+@@ -64,7 +64,7 @@ struct sermouse {
+ 
+ static void sermouse_process_msc(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &sermouse->dev;
++	struct input_dev *dev = sermouse->dev;
+ 	signed char *buf = sermouse->buf;
+ 
+ 	input_regs(dev, regs);
+@@ -107,7 +107,7 @@ static void sermouse_process_msc(struct 
+ 
+ static void sermouse_process_ms(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &sermouse->dev;
++	struct input_dev *dev = sermouse->dev;
+ 	signed char *buf = sermouse->buf;
+ 
+ 	if (data & 0x40) sermouse->count = 0;
+@@ -230,9 +230,9 @@ static void sermouse_disconnect(struct s
+ {
+ 	struct sermouse *sermouse = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&sermouse->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_unregister_device(sermouse->dev);
+ 	kfree(sermouse);
+ }
+ 
+@@ -244,56 +244,52 @@ static void sermouse_disconnect(struct s
+ static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct sermouse *sermouse;
+-	unsigned char c;
+-	int err;
+-
+-	if (!serio->id.proto || serio->id.proto > SERIO_MZPP)
+-		return -ENODEV;
+-
+-	if (!(sermouse = kmalloc(sizeof(struct sermouse), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset(sermouse, 0, sizeof(struct sermouse));
+-
+-	init_input_dev(&sermouse->dev);
+-	sermouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+-	sermouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+-	sermouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+-	sermouse->dev.private = sermouse;
+-
+-	sermouse->type = serio->id.proto;
+-	c = serio->id.extra;
+-
+-	if (c & 0x01) set_bit(BTN_MIDDLE, sermouse->dev.keybit);
+-	if (c & 0x02) set_bit(BTN_SIDE, sermouse->dev.keybit);
+-	if (c & 0x04) set_bit(BTN_EXTRA, sermouse->dev.keybit);
+-	if (c & 0x10) set_bit(REL_WHEEL, sermouse->dev.relbit);
+-	if (c & 0x20) set_bit(REL_HWHEEL, sermouse->dev.relbit);
++	struct input_dev *input_dev;
++	unsigned char c = serio->id.extra;
++	int err = -ENOMEM;
++
++	sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!sermouse || !input_dev)
++		goto fail;
+ 
++	sermouse->dev = input_dev;
+ 	sprintf(sermouse->phys, "%s/input0", serio->phys);
++	sermouse->type = serio->id.proto;
+ 
+-	sermouse->dev.name = sermouse_protocols[sermouse->type];
+-	sermouse->dev.phys = sermouse->phys;
+-	sermouse->dev.id.bustype = BUS_RS232;
+-	sermouse->dev.id.vendor = sermouse->type;
+-	sermouse->dev.id.product = c;
+-	sermouse->dev.id.version = 0x0100;
+-	sermouse->dev.dev = &serio->dev;
++	input_dev->name = sermouse_protocols[sermouse->type];
++	input_dev->phys = sermouse->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor  = sermouse->type;
++	input_dev->id.product = c;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++
++	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);
++	input_dev->private = sermouse;
++
++	if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit);
++	if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit);
++	if (c & 0x04) set_bit(BTN_EXTRA, input_dev->keybit);
++	if (c & 0x10) set_bit(REL_WHEEL, input_dev->relbit);
++	if (c & 0x20) set_bit(REL_HWHEEL, input_dev->relbit);
+ 
+ 	serio_set_drvdata(serio, sermouse);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(sermouse);
+-		return err;
+-	}
+-
+-	input_register_device(&sermouse->dev);
++	if (err)
++		goto fail;
+ 
+-	printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys);
++	input_register_device(sermouse->dev);
+ 
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(sermouse);
++	return err;
+ }
+ 
+ static struct serio_device_id sermouse_serio_ids[] = {
+diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
+--- a/drivers/input/mouse/synaptics.c
++++ b/drivers/input/mouse/synaptics.c
+@@ -342,7 +342,7 @@ static void synaptics_parse_hw_state(uns
+  */
+ static void synaptics_process_packet(struct psmouse *psmouse)
+ {
+-	struct input_dev *dev = &psmouse->dev;
++	struct input_dev *dev = psmouse->dev;
+ 	struct synaptics_data *priv = psmouse->private;
+ 	struct synaptics_hw_state hw;
+ 	int num_fingers;
+@@ -473,7 +473,7 @@ static unsigned char synaptics_detect_pk
+ 
+ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &psmouse->dev;
++	struct input_dev *dev = psmouse->dev;
+ 	struct synaptics_data *priv = psmouse->private;
+ 
+ 	input_regs(dev, regs);
+@@ -645,7 +645,7 @@ int synaptics_init(struct psmouse *psmou
+ 		SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
+ 		priv->model_id, priv->capabilities, priv->ext_cap);
+ 
+-	set_input_params(&psmouse->dev, priv);
++	set_input_params(psmouse->dev, priv);
+ 
+ 	psmouse->protocol_handler = synaptics_process_byte;
+ 	psmouse->set_rate = synaptics_set_rate;
+diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
+--- a/drivers/input/mouse/vsxxxaa.c
++++ b/drivers/input/mouse/vsxxxaa.c
+@@ -112,7 +112,7 @@ MODULE_LICENSE ("GPL");
+ 
+ 
+ struct vsxxxaa {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct serio *serio;
+ #define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
+ 	unsigned char buf[BUFLEN];
+@@ -211,7 +211,7 @@ vsxxxaa_smells_like_packet (struct vsxxx
+ static void
+ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &mouse->dev;
++	struct input_dev *dev = mouse->dev;
+ 	unsigned char *buf = mouse->buf;
+ 	int left, middle, right;
+ 	int dx, dy;
+@@ -269,7 +269,7 @@ vsxxxaa_handle_REL_packet (struct vsxxxa
+ static void
+ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &mouse->dev;
++	struct input_dev *dev = mouse->dev;
+ 	unsigned char *buf = mouse->buf;
+ 	int left, middle, right, touch;
+ 	int x, y;
+@@ -323,7 +323,7 @@ vsxxxaa_handle_ABS_packet (struct vsxxxa
+ static void
+ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &mouse->dev;
++	struct input_dev *dev = mouse->dev;
+ 	unsigned char *buf = mouse->buf;
+ 	int left, middle, right;
+ 	unsigned char error;
+@@ -483,9 +483,9 @@ vsxxxaa_disconnect (struct serio *serio)
+ {
+ 	struct vsxxxaa *mouse = serio_get_drvdata (serio);
+ 
+-	input_unregister_device (&mouse->dev);
+ 	serio_close (serio);
+ 	serio_set_drvdata (serio, NULL);
++	input_unregister_device (mouse->dev);
+ 	kfree (mouse);
+ }
+ 
+@@ -493,61 +493,57 @@ static int
+ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct vsxxxaa *mouse;
+-	int err;
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
+ 
+-	if (!(mouse = kmalloc (sizeof (struct vsxxxaa), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset (mouse, 0, sizeof (struct vsxxxaa));
+-
+-	init_input_dev (&mouse->dev);
+-	set_bit (EV_KEY, mouse->dev.evbit);		/* We have buttons */
+-	set_bit (EV_REL, mouse->dev.evbit);
+-	set_bit (EV_ABS, mouse->dev.evbit);
+-	set_bit (BTN_LEFT, mouse->dev.keybit);		/* We have 3 buttons */
+-	set_bit (BTN_MIDDLE, mouse->dev.keybit);
+-	set_bit (BTN_RIGHT, mouse->dev.keybit);
+-	set_bit (BTN_TOUCH, mouse->dev.keybit);		/* ...and Tablet */
+-	set_bit (REL_X, mouse->dev.relbit);
+-	set_bit (REL_Y, mouse->dev.relbit);
+-	set_bit (ABS_X, mouse->dev.absbit);
+-	set_bit (ABS_Y, mouse->dev.absbit);
+-
+-	mouse->dev.absmin[ABS_X] = 0;
+-	mouse->dev.absmax[ABS_X] = 1023;
+-	mouse->dev.absmin[ABS_Y] = 0;
+-	mouse->dev.absmax[ABS_Y] = 1023;
+-
+-	mouse->dev.private = mouse;
++	mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL);
++	input_dev = input_allocate_device ();
++	if (!mouse || !input_dev)
++		goto fail;
+ 
++	mouse->dev = input_dev;
++	mouse->serio = serio;
+ 	sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer");
+ 	sprintf (mouse->phys, "%s/input0", serio->phys);
+-	mouse->dev.name = mouse->name;
+-	mouse->dev.phys = mouse->phys;
+-	mouse->dev.id.bustype = BUS_RS232;
+-	mouse->dev.dev = &serio->dev;
+-	mouse->serio = serio;
++
++	input_dev->name = mouse->name;
++	input_dev->phys = mouse->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = mouse;
++
++	set_bit (EV_KEY, input_dev->evbit);		/* We have buttons */
++	set_bit (EV_REL, input_dev->evbit);
++	set_bit (EV_ABS, input_dev->evbit);
++	set_bit (BTN_LEFT, input_dev->keybit);		/* We have 3 buttons */
++	set_bit (BTN_MIDDLE, input_dev->keybit);
++	set_bit (BTN_RIGHT, input_dev->keybit);
++	set_bit (BTN_TOUCH, input_dev->keybit);		/* ...and Tablet */
++	set_bit (REL_X, input_dev->relbit);
++	set_bit (REL_Y, input_dev->relbit);
++	input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0);
++	input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0);
+ 
+ 	serio_set_drvdata (serio, mouse);
+ 
+ 	err = serio_open (serio, drv);
+-	if (err) {
+-		serio_set_drvdata (serio, NULL);
+-		kfree (mouse);
+-		return err;
+-	}
++	if (err)
++		goto fail;
+ 
+ 	/*
+ 	 * Request selftest. Standard packet format and differential
+ 	 * mode will be requested after the device ID'ed successfully.
+ 	 */
+-	mouse->serio->write (mouse->serio, 'T'); /* Test */
+-
+-	input_register_device (&mouse->dev);
++	serio->write (serio, 'T'); /* Test */
+ 
+-	printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys);
++	input_register_device (input_dev);
+ 
+ 	return 0;
++
++ fail:	serio_set_drvdata (serio, NULL);
++	input_free_device (input_dev);
++	kfree (mouse);
++	return err;
+ }
+ 
+ static struct serio_device_id vsxxaa_serio_ids[] = {
+diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
+--- a/drivers/input/mousedev.c
++++ b/drivers/input/mousedev.c
+@@ -9,7 +9,7 @@
+  * the Free Software Foundation.
+  */
+ 
+-#define MOUSEDEV_MINOR_BASE 	32
++#define MOUSEDEV_MINOR_BASE	32
+ #define MOUSEDEV_MINORS		32
+ #define MOUSEDEV_MIX		31
+ 
+@@ -24,7 +24,6 @@
+ #include <linux/random.h>
+ #include <linux/major.h>
+ #include <linux/device.h>
+-#include <linux/devfs_fs_kernel.h>
+ #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
+ #include <linux/miscdevice.h>
+ #endif
+@@ -621,6 +620,7 @@ static struct file_operations mousedev_f
+ static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+ {
+ 	struct mousedev *mousedev;
++	struct class_device *cdev;
+ 	int minor = 0;
+ 
+ 	for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
+@@ -649,11 +649,13 @@ static struct input_handle *mousedev_con
+ 
+ 	mousedev_table[minor] = mousedev;
+ 
+-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
+-			S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor);
+-	class_device_create(input_class,
++	cdev = class_device_create(&input_class, &dev->cdev,
+ 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
+-			dev->dev, "mouse%d", minor);
++			dev->cdev.dev, mousedev->name);
++
++	/* temporary symlink to keep userspace happy */
++	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
++			  mousedev->name);
+ 
+ 	return &mousedev->handle;
+ }
+@@ -663,9 +665,9 @@ static void mousedev_disconnect(struct i
+ 	struct mousedev *mousedev = handle->private;
+ 	struct mousedev_list *list;
+ 
+-	class_device_destroy(input_class,
++	sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name);
++	class_device_destroy(&input_class,
+ 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
+-	devfs_remove("input/mouse%d", mousedev->minor);
+ 	mousedev->exist = 0;
+ 
+ 	if (mousedev->open) {
+@@ -738,9 +740,7 @@ static int __init mousedev_init(void)
+ 	mousedev_mix.exist = 1;
+ 	mousedev_mix.minor = MOUSEDEV_MIX;
+ 
+-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX),
+-			S_IFCHR|S_IRUGO|S_IWUSR, "input/mice");
+-	class_device_create(input_class,
++	class_device_create(&input_class, NULL,
+ 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
+ 
+ #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
+@@ -759,8 +759,7 @@ static void __exit mousedev_exit(void)
+ 	if (psaux_registered)
+ 		misc_deregister(&psaux_mouse);
+ #endif
+-	devfs_remove("input/mice");
+-	class_device_destroy(input_class,
++	class_device_destroy(&input_class,
+ 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
+ 	input_unregister_handler(&mousedev_handler);
+ }
+diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
+--- a/drivers/input/serio/ct82c710.c
++++ b/drivers/input/serio/ct82c710.c
+@@ -37,6 +37,7 @@
+ #include <linux/serio.h>
+ #include <linux/errno.h>
+ #include <linux/err.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ 
+diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
+--- a/drivers/input/serio/gscps2.c
++++ b/drivers/input/serio/gscps2.c
+@@ -211,9 +211,6 @@ static void gscps2_reset(struct gscps2po
+ 	writeb(0xff, addr+GSC_RESET);
+ 	gscps2_flush(ps2port);
+ 	spin_unlock_irqrestore(&ps2port->lock, flags);
+-
+-	/* enable it */
+-	gscps2_enable(ps2port, ENABLE);
+ }
+ 
+ static LIST_HEAD(ps2port_list);
+@@ -307,6 +304,9 @@ static int gscps2_open(struct serio *por
+ 
+ 	gscps2_reset(ps2port);
+ 
++	/* enable it */
++	gscps2_enable(ps2port, ENABLE);
++
+ 	gscps2_interrupt(0, NULL, NULL);
+ 
+ 	return 0;
+@@ -331,7 +331,7 @@ static int __init gscps2_probe(struct pa
+ {
+ 	struct gscps2port *ps2port;
+ 	struct serio *serio;
+-	unsigned long hpa = dev->hpa;
++	unsigned long hpa = dev->hpa.start;
+ 	int ret;
+ 
+ 	if (!dev->irq)
+@@ -370,8 +370,6 @@ static int __init gscps2_probe(struct pa
+ 	serio->port_data	= ps2port;
+ 	serio->dev.parent	= &dev->dev;
+ 
+-	list_add_tail(&ps2port->node, &ps2port_list);
+-
+ 	ret = -EBUSY;
+ 	if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->port->name, ps2port))
+ 		goto fail_miserably;
+@@ -396,15 +394,16 @@ static int __init gscps2_probe(struct pa
+ 
+ 	serio_register_port(ps2port->port);
+ 
++	list_add_tail(&ps2port->node, &ps2port_list);
++
+ 	return 0;
+ 
+ fail:
+ 	free_irq(dev->irq, ps2port);
+ 
+ fail_miserably:
+-	list_del(&ps2port->node);
+ 	iounmap(ps2port->addr);
+-	release_mem_region(dev->hpa, GSC_STATUS + 4);
++	release_mem_region(dev->hpa.start, GSC_STATUS + 4);
+ 
+ fail_nomem:
+ 	kfree(ps2port);
+@@ -444,7 +443,7 @@ static struct parisc_device_id gscps2_de
+ };
+ 
+ static struct parisc_driver parisc_ps2_driver = {
+-	.name		= "GSC PS2",
++	.name		= "gsc_ps2",
+ 	.id_table	= gscps2_device_tbl,
+ 	.probe		= gscps2_probe,
+ 	.remove		= gscps2_remove,
+diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
+--- a/drivers/input/serio/hil_mlc.c
++++ b/drivers/input/serio/hil_mlc.c
+@@ -801,7 +801,8 @@ static int hil_mlc_serio_open(struct ser
+ 	struct hil_mlc_serio_map *map;
+ 	struct hil_mlc *mlc;
+ 
+-	if (serio->private != NULL) return -EBUSY;
++	if (serio_get_drvdata(serio) != NULL)
++		return -EBUSY;
+ 
+ 	map = serio->port_data;
+ 	if (map == NULL) {
+@@ -832,11 +833,18 @@ static void hil_mlc_serio_close(struct s
+ 		return;
+ 	}
+ 
+-	serio->private = NULL;
++	serio_set_drvdata(serio, NULL);
+ 	serio->drv = NULL;
+ 	/* TODO wake up interruptable */
+ }
+ 
++static struct serio_device_id hil_mlc_serio_id = {
++	.type = SERIO_HIL_MLC,
++	.proto = SERIO_HIL,
++	.extra = SERIO_ANY,
++	.id = SERIO_ANY,
++};
++
+ int hil_mlc_register(hil_mlc *mlc) {
+ 	int i;
+         unsigned long flags;
+@@ -867,7 +875,7 @@ int hil_mlc_register(hil_mlc *mlc) {
+ 		mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL);
+ 		mlc->serio[i] = mlc_serio;
+ 		memset(mlc_serio, 0, sizeof(*mlc_serio));
+-		mlc_serio->type			= SERIO_HIL | SERIO_HIL_MLC;
++		mlc_serio->id			= hil_mlc_serio_id;
+ 		mlc_serio->write		= hil_mlc_serio_write;
+ 		mlc_serio->open			= hil_mlc_serio_open;
+ 		mlc_serio->close		= hil_mlc_serio_close;
+diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
+--- a/drivers/input/serio/hp_sdc.c
++++ b/drivers/input/serio/hp_sdc.c
+@@ -764,7 +764,7 @@ MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
+ static int __init hp_sdc_init_hppa(struct parisc_device *d);
+ 
+ static struct parisc_driver hp_sdc_driver = {
+-	.name =		"HP SDC",
++	.name =		"hp_sdc",
+ 	.id_table =	hp_sdc_tbl,
+ 	.probe =	hp_sdc_init_hppa,
+ };
+@@ -875,9 +875,9 @@ static int __init hp_sdc_init_hppa(struc
+ 	hp_sdc.dev		= d;
+ 	hp_sdc.irq		= d->irq;
+ 	hp_sdc.nmi		= d->aux_irq;
+-	hp_sdc.base_io		= d->hpa;
+-	hp_sdc.data_io		= d->hpa + 0x800;
+-	hp_sdc.status_io	= d->hpa + 0x801;
++	hp_sdc.base_io		= d->hpa.start;
++	hp_sdc.data_io		= d->hpa.start + 0x800;
++	hp_sdc.status_io	= d->hpa.start + 0x801;
+ 
+ 	return hp_sdc_init();
+ }
+diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c
+--- a/drivers/input/serio/hp_sdc_mlc.c
++++ b/drivers/input/serio/hp_sdc_mlc.c
+@@ -40,6 +40,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/string.h>
++#include <asm/semaphore.h>
+ 
+ #define PREFIX "HP SDC MLC: "
+ 
+diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -20,6 +20,7 @@
+ #include <linux/serio.h>
+ #include <linux/err.h>
+ #include <linux/rcupdate.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ 
+@@ -911,12 +912,10 @@ static long i8042_panic_blink(long count
+  * Here we try to restore the original BIOS settings
+  */
+ 
+-static int i8042_suspend(struct device *dev, pm_message_t state, u32 level)
++static int i8042_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_DISABLE) {
+-		del_timer_sync(&i8042_timer);
+-		i8042_controller_reset();
+-	}
++	del_timer_sync(&i8042_timer);
++	i8042_controller_reset();
+ 
+ 	return 0;
+ }
+@@ -926,13 +925,10 @@ static int i8042_suspend(struct device *
+  * Here we try to reset everything back to a state in which suspended
+  */
+ 
+-static int i8042_resume(struct device *dev, u32 level)
++static int i8042_resume(struct device *dev)
+ {
+ 	int i;
+ 
+-	if (level != RESUME_ENABLE)
+-		return 0;
+-
+ 	if (i8042_ctl_test())
+ 		return -1;
+ 
+diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
+--- a/drivers/input/serio/maceps2.c
++++ b/drivers/input/serio/maceps2.c
+@@ -14,7 +14,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
+ #include <linux/err.h>
+diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
+--- a/drivers/input/serio/q40kbd.c
++++ b/drivers/input/serio/q40kbd.c
+@@ -37,6 +37,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/err.h>
+ #include <linux/bitops.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
+--- a/drivers/input/serio/rpckbd.c
++++ b/drivers/input/serio/rpckbd.c
+@@ -34,6 +34,7 @@
+ #include <linux/init.h>
+ #include <linux/serio.h>
+ #include <linux/err.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/irq.h>
+ #include <asm/hardware.h>
+diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
+--- a/drivers/input/touchscreen/corgi_ts.c
++++ b/drivers/input/touchscreen/corgi_ts.c
+@@ -11,7 +11,7 @@
+ 
+ 
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/init.h>
+ #include <linux/input.h>
+ #include <linux/interrupt.h>
+@@ -41,8 +41,7 @@ struct ts_event {
+ };
+ 
+ struct corgi_ts {
+-	char phys[32];
+-	struct input_dev input;
++	struct input_dev *input;
+ 	struct timer_list timer;
+ 	struct ts_event tc;
+ 	int pendown;
+@@ -182,14 +181,12 @@ static void new_data(struct corgi_ts *co
+ 	if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0)
+ 		return;
+ 
+-	if (regs)
+-		input_regs(&corgi_ts->input, regs);
+-
+-	input_report_abs(&corgi_ts->input, ABS_X, corgi_ts->tc.x);
+-	input_report_abs(&corgi_ts->input, ABS_Y, corgi_ts->tc.y);
+-	input_report_abs(&corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure);
+-	input_report_key(&corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0));
+-	input_sync(&corgi_ts->input);
++	input_regs(corgi_ts->input, regs);
++	input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x);
++	input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y);
++	input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure);
++	input_report_key(corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0));
++	input_sync(corgi_ts->input);
+ }
+ 
+ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs)
+@@ -234,34 +231,32 @@ static irqreturn_t ts_interrupt(int irq,
+ }
+ 
+ #ifdef CONFIG_PM
+-static int corgits_suspend(struct device *dev, pm_message_t state, uint32_t level)
++static int corgits_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_POWER_DOWN) {
+-		struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
+-
+-		if (corgi_ts->pendown) {
+-			del_timer_sync(&corgi_ts->timer);
+-			corgi_ts->tc.pressure = 0;
+-			new_data(corgi_ts, NULL);
+-			corgi_ts->pendown = 0;
+-		}
+-		corgi_ts->power_mode = PWR_MODE_SUSPEND;
++	struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
+ 
+-		corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
++	if (corgi_ts->pendown) {
++		del_timer_sync(&corgi_ts->timer);
++		corgi_ts->tc.pressure = 0;
++		new_data(corgi_ts, NULL);
++		corgi_ts->pendown = 0;
+ 	}
++	corgi_ts->power_mode = PWR_MODE_SUSPEND;
++
++	corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
++
+ 	return 0;
+ }
+ 
+-static int corgits_resume(struct device *dev, uint32_t level)
++static int corgits_resume(struct device *dev)
+ {
+-	if (level == RESUME_POWER_ON) {
+-		struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
++	struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
++
++	corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
++	/* Enable Falling Edge */
++	set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
++	corgi_ts->power_mode = PWR_MODE_ACTIVE;
+ 
+-		corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+-		/* Enable Falling Edge */
+-		set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
+-		corgi_ts->power_mode = PWR_MODE_ACTIVE;
+-	}
+ 	return 0;
+ }
+ #else
+@@ -273,39 +268,44 @@ static int __init corgits_probe(struct d
+ {
+ 	struct corgi_ts *corgi_ts;
+ 	struct platform_device *pdev = to_platform_device(dev);
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
+ 
+-	if (!(corgi_ts = kmalloc(sizeof(struct corgi_ts), GFP_KERNEL)))
+-		return -ENOMEM;
++	corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!corgi_ts || !input_dev)
++		goto fail;
+ 
+ 	dev_set_drvdata(dev, corgi_ts);
+ 
+-	memset(corgi_ts, 0, sizeof(struct corgi_ts));
+-
+ 	corgi_ts->machinfo = dev->platform_data;
+ 	corgi_ts->irq_gpio = platform_get_irq(pdev, 0);
+ 
+ 	if (corgi_ts->irq_gpio < 0) {
+-		kfree(corgi_ts);
+-		return -ENODEV;
++		err = -ENODEV;
++		goto fail;
+ 	}
+ 
+-	init_input_dev(&corgi_ts->input);
+-	corgi_ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-	corgi_ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+-	input_set_abs_params(&corgi_ts->input, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
+-	input_set_abs_params(&corgi_ts->input, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
+-	input_set_abs_params(&corgi_ts->input, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
+-
+-	strcpy(corgi_ts->phys, "corgits/input0");
+-
+-	corgi_ts->input.private = corgi_ts;
+-	corgi_ts->input.name = "Corgi Touchscreen";
+-	corgi_ts->input.dev = dev;
+-	corgi_ts->input.phys = corgi_ts->phys;
+-	corgi_ts->input.id.bustype = BUS_HOST;
+-	corgi_ts->input.id.vendor = 0x0001;
+-	corgi_ts->input.id.product = 0x0002;
+-	corgi_ts->input.id.version = 0x0100;
++	corgi_ts->input = input_dev;
++
++	init_timer(&corgi_ts->timer);
++	corgi_ts->timer.data = (unsigned long) corgi_ts;
++	corgi_ts->timer.function = corgi_ts_timer;
++
++	input_dev->name = "Corgi Touchscreen";
++	input_dev->phys = "corgits/input0";
++	input_dev->id.bustype = BUS_HOST;
++	input_dev->id.vendor = 0x0001;
++	input_dev->id.product = 0x0002;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = dev;
++	input_dev->private = corgi_ts;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++	input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
++	input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
++	input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
+ 
+ 	pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN);
+ 
+@@ -319,25 +319,24 @@ static int __init corgits_probe(struct d
+ 	corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+ 	mdelay(5);
+ 
+-	init_timer(&corgi_ts->timer);
+-	corgi_ts->timer.data = (unsigned long) corgi_ts;
+-	corgi_ts->timer.function = corgi_ts_timer;
+-
+-	input_register_device(&corgi_ts->input);
+-	corgi_ts->power_mode = PWR_MODE_ACTIVE;
+-
+ 	if (request_irq(corgi_ts->irq_gpio, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) {
+-		input_unregister_device(&corgi_ts->input);
+-		kfree(corgi_ts);
+-		return -EBUSY;
++		err = -EBUSY;
++		goto fail;
+ 	}
+ 
++	input_register_device(corgi_ts->input);
++
++	corgi_ts->power_mode = PWR_MODE_ACTIVE;
++
+ 	/* Enable Falling Edge */
+ 	set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
+ 
+-	printk(KERN_INFO "input: Corgi Touchscreen Registered\n");
+-
+ 	return 0;
++
++ fail:	input_free_device(input_dev);
++	kfree(corgi_ts);
++	return err;
++
+ }
+ 
+ static int corgits_remove(struct device *dev)
+@@ -347,7 +346,7 @@ static int corgits_remove(struct device 
+ 	free_irq(corgi_ts->irq_gpio, NULL);
+ 	del_timer_sync(&corgi_ts->timer);
+ 	corgi_ts->machinfo->put_hsync();
+-	input_unregister_device(&corgi_ts->input);
++	input_unregister_device(corgi_ts->input);
+ 	kfree(corgi_ts);
+ 	return 0;
+ }
+diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
+--- a/drivers/input/touchscreen/elo.c
++++ b/drivers/input/touchscreen/elo.c
+@@ -36,14 +36,12 @@ MODULE_LICENSE("GPL");
+ 
+ #define	ELO_MAX_LENGTH	10
+ 
+-static char *elo_name = "Elo Serial TouchScreen";
+-
+ /*
+  * Per-touchscreen data.
+  */
+ 
+ struct elo {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct serio *serio;
+ 	int id;
+ 	int idx;
+@@ -54,7 +52,7 @@ struct elo {
+ 
+ static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &elo->dev;
++	struct input_dev *dev = elo->dev;
+ 
+ 	elo->csum += elo->data[elo->idx] = data;
+ 
+@@ -80,7 +78,7 @@ static void elo_process_data_10(struct e
+ 				input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
+ 				input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
+ 				input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]);
+-				input_report_key(dev, BTN_TOUCH, elo->data[2] & 3);
++				input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]);
+ 				input_sync(dev);
+ 			}
+ 			elo->idx = 0;
+@@ -91,7 +89,7 @@ static void elo_process_data_10(struct e
+ 
+ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &elo->dev;
++	struct input_dev *dev = elo->dev;
+ 
+ 	elo->data[elo->idx] = data;
+ 
+@@ -129,7 +127,7 @@ static void elo_process_data_6(struct el
+ 		case 5:
+ 			if ((data & 0xf0) == 0) {
+ 				input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
+-				input_report_key(dev, BTN_TOUCH, elo->data[5]);
++				input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
+ 			}
+ 			input_sync(dev);
+ 			elo->idx = 0;
+@@ -139,7 +137,7 @@ static void elo_process_data_6(struct el
+ 
+ static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &elo->dev;
++	struct input_dev *dev = elo->dev;
+ 
+ 	elo->data[elo->idx] = data;
+ 
+@@ -191,7 +189,7 @@ static void elo_disconnect(struct serio 
+ {
+ 	struct elo* elo = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&elo->dev);
++	input_unregister_device(elo->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
+ 	kfree(elo);
+@@ -206,67 +204,68 @@ static void elo_disconnect(struct serio 
+ static int elo_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct elo *elo;
++	struct input_dev *input_dev;
+ 	int err;
+ 
+-	if (!(elo = kmalloc(sizeof(struct elo), GFP_KERNEL)))
+-		return -ENOMEM;
++	elo = kzalloc(sizeof(struct elo), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!elo || !input_dev) {
++		err = -ENOMEM;
++		goto fail;
++	}
+ 
+-	memset(elo, 0, sizeof(struct elo));
++	elo->serio = serio;
++	elo->id = serio->id.id;
++	elo->dev = input_dev;
++	snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
+ 
+-	init_input_dev(&elo->dev);
+-	elo->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-	elo->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++	input_dev->private = elo;
++	input_dev->name = "Elo Serial TouchScreen";
++	input_dev->phys = elo->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_ELO;
++	input_dev->id.product = elo->id;
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
+ 
+-	elo->id = serio->id.id;
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ 
+ 	switch (elo->id) {
+ 
+ 		case 0: /* 10-byte protocol */
+-			input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0);
+-			input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0);
+-			input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 255, 0, 0);
++			input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
++			input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
++			input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
+ 			break;
+ 
+ 		case 1: /* 6-byte protocol */
+-			input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 15, 0, 0);
++			input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
+ 
+ 		case 2: /* 4-byte protocol */
+-			input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0);
+-			input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0);
++			input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
++			input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
+ 			break;
+ 
+ 		case 3: /* 3-byte protocol */
+-			input_set_abs_params(&elo->dev, ABS_X, 0, 255, 0, 0);
+-			input_set_abs_params(&elo->dev, ABS_Y, 0, 255, 0, 0);
++			input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
++			input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
+ 			break;
+ 	}
+ 
+-	elo->serio = serio;
+-
+-	sprintf(elo->phys, "%s/input0", serio->phys);
+-
+-	elo->dev.private = elo;
+-	elo->dev.name = elo_name;
+-	elo->dev.phys = elo->phys;
+-	elo->dev.id.bustype = BUS_RS232;
+-	elo->dev.id.vendor = SERIO_ELO;
+-	elo->dev.id.product = elo->id;
+-	elo->dev.id.version = 0x0100;
+-
+ 	serio_set_drvdata(serio, elo);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(elo);
+-		return err;
+-	}
+-
+-	input_register_device(&elo->dev);
+-
+-	printk(KERN_INFO "input: %s on %s\n", elo_name, serio->phys);
++	if (err)
++		goto fail;
+ 
++	input_register_device(elo->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(elo);
++	return err;
+ }
+ 
+ /*
+diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
+--- a/drivers/input/touchscreen/gunze.c
++++ b/drivers/input/touchscreen/gunze.c
+@@ -48,14 +48,12 @@ MODULE_LICENSE("GPL");
+ 
+ #define	GUNZE_MAX_LENGTH	10
+ 
+-static char *gunze_name = "Gunze AHL-51S TouchScreen";
+-
+ /*
+  * Per-touchscreen data.
+  */
+ 
+ struct gunze {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct serio *serio;
+ 	int idx;
+ 	unsigned char data[GUNZE_MAX_LENGTH];
+@@ -64,7 +62,7 @@ struct gunze {
+ 
+ static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &gunze->dev;
++	struct input_dev *dev = gunze->dev;
+ 
+ 	if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' ||
+ 		(gunze->data[0] != 'T' && gunze->data[0] != 'R')) {
+@@ -100,11 +98,13 @@ static irqreturn_t gunze_interrupt(struc
+ 
+ static void gunze_disconnect(struct serio *serio)
+ {
+-	struct gunze* gunze = serio_get_drvdata(serio);
++	struct gunze *gunze = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&gunze->dev);
++	input_get_device(gunze->dev);
++	input_unregister_device(gunze->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_put_device(gunze->dev);
+ 	kfree(gunze);
+ }
+ 
+@@ -117,45 +117,45 @@ static void gunze_disconnect(struct seri
+ static int gunze_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct gunze *gunze;
++	struct input_dev *input_dev;
+ 	int err;
+ 
+-	if (!(gunze = kmalloc(sizeof(struct gunze), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset(gunze, 0, sizeof(struct gunze));
+-
+-	init_input_dev(&gunze->dev);
+-	gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-	gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+-	input_set_abs_params(&gunze->dev, ABS_X, 24, 1000, 0, 0);
+-	input_set_abs_params(&gunze->dev, ABS_Y, 24, 1000, 0, 0);
++	gunze = kzalloc(sizeof(struct gunze), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!gunze || !input_dev) {
++		err = -ENOMEM;
++		goto fail;
++	}
+ 
+ 	gunze->serio = serio;
+-
++	gunze->dev = input_dev;
+ 	sprintf(gunze->phys, "%s/input0", serio->phys);
+ 
+-	gunze->dev.private = gunze;
+-	gunze->dev.name = gunze_name;
+-	gunze->dev.phys = gunze->phys;
+-	gunze->dev.id.bustype = BUS_RS232;
+-	gunze->dev.id.vendor = SERIO_GUNZE;
+-	gunze->dev.id.product = 0x0051;
+-	gunze->dev.id.version = 0x0100;
++	input_dev->private = gunze;
++	input_dev->name = "Gunze AHL-51S TouchScreen";
++	input_dev->phys = gunze->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_GUNZE;
++	input_dev->id.product = 0x0051;
++	input_dev->id.version = 0x0100;
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++	input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0);
++	input_set_abs_params(input_dev, ABS_Y, 24, 1000, 0, 0);
+ 
+ 	serio_set_drvdata(serio, gunze);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(gunze);
+-		return err;
+-	}
+-
+-	input_register_device(&gunze->dev);
+-
+-	printk(KERN_INFO "input: %s on %s\n", gunze_name, serio->phys);
++	if (err)
++		goto fail;
+ 
++	input_register_device(gunze->dev);
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(gunze);
++	return err;
+ }
+ 
+ /*
+diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
+--- a/drivers/input/touchscreen/h3600_ts_input.c
++++ b/drivers/input/touchscreen/h3600_ts_input.c
+@@ -39,7 +39,6 @@
+ #include <linux/serio.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+-#include <linux/pm.h>
+ 
+ /* SA1100 serial defines */
+ #include <asm/arch/hardware.h>
+@@ -93,16 +92,12 @@ MODULE_LICENSE("GPL");
+ #define H3600_SCANCODE_LEFT	8	 /* 8 -> left */
+ #define H3600_SCANCODE_DOWN	9	 /* 9 -> down */
+ 
+-static char *h3600_name = "H3600 TouchScreen";
+-
+ /*
+  * Per-touchscreen data.
+  */
+ struct h3600_dev {
+-	struct input_dev dev;
+-	struct pm_dev *pm_dev;
++	struct input_dev *dev;
+ 	struct serio *serio;
+-	struct pm_dev *pm_dev;
+ 	unsigned char event;	/* event ID from packet */
+ 	unsigned char chksum;
+ 	unsigned char len;
+@@ -163,33 +158,6 @@ unsigned int h3600_flite_power(struct in
+ 	return 0;
+ }
+ 
+-static int suspended = 0;
+-static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
+-				void *data)
+-{
+-	struct input_dev *dev = (struct input_dev *) data;
+-
+-	switch (req) {
+-	case PM_SUSPEND: /* enter D1-D3 */
+-		suspended = 1;
+-		h3600_flite_power(dev, FLITE_PWR_OFF);
+-		break;
+-	case PM_BLANK:
+-		if (!suspended)
+-			h3600_flite_power(dev, FLITE_PWR_OFF);
+-		break;
+-	case PM_RESUME:  /* enter D0 */
+-		/* same as unblank */
+-	case PM_UNBLANK:
+-		if (suspended) {
+-			//initSerial();
+-			suspended = 0;
+-		}
+-		h3600_flite_power(dev, FLITE_PWR_ON);
+-		break;
+-	}
+-	return 0;
+-}
+ #endif
+ 
+ /*
+@@ -199,7 +167,7 @@ static int h3600ts_pm_callback(struct pm
+  */
+ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &ts->dev;
++	struct input_dev *dev = ts->dev;
+ 	static int touched = 0;
+ 	int key, down = 0;
+ 
+@@ -295,6 +263,7 @@ static void h3600ts_process_packet(struc
+ static int h3600ts_event(struct input_dev *dev, unsigned int type,
+ 			 unsigned int code, int value)
+ {
++#if 0
+ 	struct h3600_dev *ts = dev->private;
+ 
+ 	switch (type) {
+@@ -304,6 +273,8 @@ static int h3600ts_event(struct input_de
+ 		}
+ 	}
+ 	return -1;
++#endif
++	return 0;
+ }
+ 
+ /*
+@@ -380,14 +351,48 @@ static irqreturn_t h3600ts_interrupt(str
+ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct h3600_dev *ts;
++	struct input_dev *input_dev;
+ 	int err;
+ 
+-	if (!(ts = kmalloc(sizeof(struct h3600_dev), GFP_KERNEL)))
+-		return -ENOMEM;
++	ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!ts || !input_dev) {
++		err = -ENOMEM;
++		goto fail1;
++	}
+ 
+-	memset(ts, 0, sizeof(struct h3600_dev));
++	ts->serio = serio;
++	ts->dev = input_dev;
++	sprintf(ts->phys, "%s/input0", serio->phys);
+ 
+-	init_input_dev(&ts->dev);
++	input_dev->name = "H3600 TouchScreen";
++	input_dev->phys = ts->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_H3600;
++	input_dev->id.product = 0x0666;  /* FIXME !!! We can ask the hardware */
++	input_dev->id.version = 0x0100;
++	input_dev->cdev.dev = &serio->dev;
++	input_dev->private = ts;
++
++	input_dev->event = h3600ts_event;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
++	input_dev->ledbit[0] = BIT(LED_SLEEP);
++	input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0);
++	input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0);
++
++	set_bit(KEY_RECORD, input_dev->keybit);
++	set_bit(KEY_Q, input_dev->keybit);
++	set_bit(KEY_PROG1, input_dev->keybit);
++	set_bit(KEY_PROG2, input_dev->keybit);
++	set_bit(KEY_PROG3, input_dev->keybit);
++	set_bit(KEY_UP, input_dev->keybit);
++	set_bit(KEY_RIGHT, input_dev->keybit);
++	set_bit(KEY_LEFT, input_dev->keybit);
++	set_bit(KEY_DOWN, input_dev->keybit);
++	set_bit(KEY_ENTER, input_dev->keybit);
++	set_bit(KEY_SUSPEND, input_dev->keybit);
++	set_bit(BTN_TOUCH, input_dev->keybit);
+ 
+ 	/* Device specific stuff */
+ 	set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
+@@ -397,73 +402,35 @@ static int h3600ts_connect(struct serio 
+ 			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
+ 			"h3600_action", &ts->dev)) {
+ 		printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
+-		kfree(ts);
+-		return -EBUSY;
++		err = -EBUSY;
++		goto fail2;
+ 	}
+ 
+ 	if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
+ 			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
+ 			"h3600_suspend", &ts->dev)) {
+-		free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
+ 		printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
+-		kfree(ts);
+-		return -EBUSY;
++		err = -EBUSY;
++		goto fail3;
+ 	}
+ 
+-	/* Now we have things going we setup our input device */
+-	ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
+-	ts->dev.ledbit[0] = BIT(LED_SLEEP);
+-	input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0);
+-	input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0);
+-
+-	set_bit(KEY_RECORD, ts->dev.keybit);
+-	set_bit(KEY_Q, ts->dev.keybit);
+-	set_bit(KEY_PROG1, ts->dev.keybit);
+-	set_bit(KEY_PROG2, ts->dev.keybit);
+-	set_bit(KEY_PROG3, ts->dev.keybit);
+-	set_bit(KEY_UP, ts->dev.keybit);
+-	set_bit(KEY_RIGHT, ts->dev.keybit);
+-	set_bit(KEY_LEFT, ts->dev.keybit);
+-	set_bit(KEY_DOWN, ts->dev.keybit);
+-	set_bit(KEY_ENTER, ts->dev.keybit);
+-	ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
+-	ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
+-
+-	ts->serio = serio;
+-
+-	sprintf(ts->phys, "%s/input0", serio->phys);
+-
+-	ts->dev.event = h3600ts_event;
+-	ts->dev.private = ts;
+-	ts->dev.name = h3600_name;
+-	ts->dev.phys = ts->phys;
+-	ts->dev.id.bustype = BUS_RS232;
+-	ts->dev.id.vendor = SERIO_H3600;
+-	ts->dev.id.product = 0x0666;  /* FIXME !!! We can ask the hardware */
+-	ts->dev.id.version = 0x0100;
+-
+ 	serio_set_drvdata(serio, ts);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts);
+-		free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts);
+-		serio_set_drvdata(serio, NULL);
+-		kfree(ts);
++	if (err)
+ 		return err;
+-	}
+ 
+ 	//h3600_flite_control(1, 25);     /* default brightness */
+-#ifdef CONFIG_PM
+-	ts->pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
+-				h3600ts_pm_callback);
+-	printk("registered pm callback\n");
+-#endif
+-	input_register_device(&ts->dev);
+-
+-	printk(KERN_INFO "input: %s on %s\n", h3600_name, serio->phys);
++	input_register_device(ts->dev);
+ 
+ 	return 0;
++
++fail3:	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
++fail2:	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
++fail1:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(ts);
++	return err;
+ }
+ 
+ /*
+@@ -476,9 +443,11 @@ static void h3600ts_disconnect(struct se
+ 
+ 	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
+ 	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
+-	input_unregister_device(&ts->dev);
++	input_get_device(ts->dev);
++	input_unregister_device(ts->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_put_device(ts->dev);
+ 	kfree(ts);
+ }
+ 
+diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
+--- a/drivers/input/touchscreen/hp680_ts_input.c
++++ b/drivers/input/touchscreen/hp680_ts_input.c
+@@ -21,10 +21,8 @@
+ 
+ static void do_softint(void *data);
+ 
+-static struct input_dev hp680_ts_dev;
++static struct input_dev *hp680_ts_dev;
+ static DECLARE_WORK(work, do_softint, 0);
+-static char *hp680_ts_name = "HP Jornada touchscreen";
+-static char *hp680_ts_phys = "input0";
+ 
+ static void do_softint(void *data)
+ {
+@@ -58,14 +56,14 @@ static void do_softint(void *data)
+ 	}
+ 
+ 	if (touched) {
+-		input_report_key(&hp680_ts_dev, BTN_TOUCH, 1);
+-		input_report_abs(&hp680_ts_dev, ABS_X, absx);
+-		input_report_abs(&hp680_ts_dev, ABS_Y, absy);
++		input_report_key(hp680_ts_dev, BTN_TOUCH, 1);
++		input_report_abs(hp680_ts_dev, ABS_X, absx);
++		input_report_abs(hp680_ts_dev, ABS_Y, absy);
+ 	} else {
+-		input_report_key(&hp680_ts_dev, BTN_TOUCH, 0);
++		input_report_key(hp680_ts_dev, BTN_TOUCH, 0);
+ 	}
+ 
+-	input_sync(&hp680_ts_dev);
++	input_sync(hp680_ts_dev);
+ 	enable_irq(HP680_TS_IRQ);
+ }
+ 
+@@ -92,27 +90,29 @@ static int __init hp680_ts_init(void)
+ 	scpcr |= SCPCR_TS_ENABLE;
+ 	ctrl_outw(scpcr, SCPCR);
+ 
+-	memset(&hp680_ts_dev, 0, sizeof(hp680_ts_dev));
+-	init_input_dev(&hp680_ts_dev);
+-
+-	hp680_ts_dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
+-	hp680_ts_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+-	hp680_ts_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+-
+-	hp680_ts_dev.absmin[ABS_X] = HP680_TS_ABS_X_MIN;
+-	hp680_ts_dev.absmin[ABS_Y] = HP680_TS_ABS_Y_MIN;
+-	hp680_ts_dev.absmax[ABS_X] = HP680_TS_ABS_X_MAX;
+-	hp680_ts_dev.absmax[ABS_Y] = HP680_TS_ABS_Y_MAX;
+-
+-	hp680_ts_dev.name = hp680_ts_name;
+-	hp680_ts_dev.phys = hp680_ts_phys;
+-	input_register_device(&hp680_ts_dev);
+-
+-	if (request_irq
+-	    (HP680_TS_IRQ, hp680_ts_interrupt, SA_INTERRUPT, MODNAME, 0) < 0) {
+-		printk(KERN_ERR "hp680_touchscreen.c : Can't allocate irq %d\n",
++	hp680_ts_dev = input_allocate_device();
++	if (!hp680_ts_dev)
++		return -ENOMEM;
++
++	hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
++	hp680_ts_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
++	hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++
++	hp680_ts_dev->absmin[ABS_X] = HP680_TS_ABS_X_MIN;
++	hp680_ts_dev->absmin[ABS_Y] = HP680_TS_ABS_Y_MIN;
++	hp680_ts_dev->absmax[ABS_X] = HP680_TS_ABS_X_MAX;
++	hp680_ts_dev->absmax[ABS_Y] = HP680_TS_ABS_Y_MAX;
++
++	hp680_ts_dev->name = "HP Jornada touchscreen";
++	hp680_ts_dev->phys = "hp680_ts/input0";
++
++	input_register_device(hp680_ts_dev);
++
++	if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt,
++			SA_INTERRUPT, MODNAME, 0) < 0) {
++		printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n",
+ 		       HP680_TS_IRQ);
+-		input_unregister_device(&hp680_ts_dev);
++		input_unregister_device(hp680_ts_dev);
+ 		return -EBUSY;
+ 	}
+ 
+@@ -124,7 +124,7 @@ static void __exit hp680_ts_exit(void)
+ 	free_irq(HP680_TS_IRQ, 0);
+ 	cancel_delayed_work(&work);
+ 	flush_scheduled_work();
+-	input_unregister_device(&hp680_ts_dev);
++	input_unregister_device(hp680_ts_dev);
+ }
+ 
+ module_init(hp680_ts_init);
+diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
+--- a/drivers/input/touchscreen/mk712.c
++++ b/drivers/input/touchscreen/mk712.c
+@@ -77,7 +77,7 @@ MODULE_PARM_DESC(irq, "IRQ of MK712 touc
+ #define MK712_READ_ONE_POINT			0x20
+ #define MK712_POWERUP				0x40
+ 
+-static struct input_dev mk712_dev;
++static struct input_dev *mk712_dev;
+ static DEFINE_SPINLOCK(mk712_lock);
+ 
+ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+@@ -88,7 +88,7 @@ static irqreturn_t mk712_interrupt(int i
+ 	static unsigned short last_y;
+ 
+ 	spin_lock(&mk712_lock);
+-	input_regs(&mk712_dev, regs);
++	input_regs(mk712_dev, regs);
+ 
+ 	status = inb(mk712_io + MK712_STATUS);
+ 
+@@ -100,7 +100,7 @@ static irqreturn_t mk712_interrupt(int i
+ 	if (~status & MK712_STATUS_TOUCH)
+ 	{
+ 		debounce = 1;
+-		input_report_key(&mk712_dev, BTN_TOUCH, 0);
++		input_report_key(mk712_dev, BTN_TOUCH, 0);
+ 		goto end;
+ 	}
+ 
+@@ -110,15 +110,15 @@ static irqreturn_t mk712_interrupt(int i
+ 		goto end;
+ 	}
+ 
+-	input_report_key(&mk712_dev, BTN_TOUCH, 1);
+-	input_report_abs(&mk712_dev, ABS_X, last_x);
+-	input_report_abs(&mk712_dev, ABS_Y, last_y);
++	input_report_key(mk712_dev, BTN_TOUCH, 1);
++	input_report_abs(mk712_dev, ABS_X, last_x);
++	input_report_abs(mk712_dev, ABS_Y, last_y);
+ 
+ end:
+ 
+ 	last_x = inw(mk712_io + MK712_X) & 0x0fff;
+ 	last_y = inw(mk712_io + MK712_Y) & 0x0fff;
+-	input_sync(&mk712_dev);
++	input_sync(mk712_dev);
+ 	spin_unlock(&mk712_lock);
+ 	return IRQ_HANDLED;
+ }
+@@ -154,30 +154,11 @@ static void mk712_close(struct input_dev
+ 	spin_unlock_irqrestore(&mk712_lock, flags);
+ }
+ 
+-static struct input_dev mk712_dev = {
+-	.evbit   = { BIT(EV_KEY) | BIT(EV_ABS) },
+-	.keybit  = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
+-	.absbit  = { BIT(ABS_X) | BIT(ABS_Y) },
+-	.open    = mk712_open,
+-	.close   = mk712_close,
+-	.name    = "ICS MicroClock MK712 TouchScreen",
+-	.phys    = "isa0260/input0",
+-	.absmin  = { [ABS_X] = 0, [ABS_Y] = 0 },
+-	.absmax  = { [ABS_X] = 0xfff, [ABS_Y] = 0xfff },
+-	.absfuzz = { [ABS_X] = 88, [ABS_Y] = 88 },
+-	.id      = {
+-		.bustype = BUS_ISA,
+-		.vendor  = 0x0005,
+-		.product = 0x0001,
+-		.version = 0x0100,
+-	},
+-};
+-
+ int __init mk712_init(void)
+ {
++	int err;
+ 
+-	if(!request_region(mk712_io, 8, "mk712"))
+-	{
++	if (!request_region(mk712_io, 8, "mk712")) {
+ 		printk(KERN_WARNING "mk712: unable to get IO region\n");
+ 		return -ENODEV;
+ 	}
+@@ -188,28 +169,49 @@ int __init mk712_init(void)
+ 	    (inw(mk712_io + MK712_Y) & 0xf000) ||
+ 	    (inw(mk712_io + MK712_STATUS) & 0xf333)) {
+ 		printk(KERN_WARNING "mk712: device not present\n");
+-		release_region(mk712_io, 8);
+-		return -ENODEV;
++		err = -ENODEV;
++		goto fail;
+ 	}
+ 
+-	if(request_irq(mk712_irq, mk712_interrupt, 0, "mk712", &mk712_dev))
+-	{
+-		printk(KERN_WARNING "mk712: unable to get IRQ\n");
+-		release_region(mk712_io, 8);
+-		return -EBUSY;
++	if (!(mk712_dev = input_allocate_device())) {
++		printk(KERN_ERR "mk712: not enough memory\n");
++		err = -ENOMEM;
++		goto fail;
+ 	}
+ 
+-	input_register_device(&mk712_dev);
++	mk712_dev->name = "ICS MicroClock MK712 TouchScreen";
++	mk712_dev->phys = "isa0260/input0";
++	mk712_dev->id.bustype = BUS_ISA;
++	mk712_dev->id.vendor  = 0x0005;
++	mk712_dev->id.product = 0x0001;
++	mk712_dev->id.version = 0x0100;
++
++	mk712_dev->open    = mk712_open;
++	mk712_dev->close   = mk712_close;
+ 
+-	printk(KERN_INFO "input: ICS MicroClock MK712 TouchScreen at %#x irq %d\n", mk712_io, mk712_irq);
++	mk712_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	mk712_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++	input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0);
++	input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0);
+ 
++	if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) {
++		printk(KERN_WARNING "mk712: unable to get IRQ\n");
++		err = -EBUSY;
++		goto fail;
++	}
++
++	input_register_device(mk712_dev);
+ 	return 0;
++
++ fail:	input_free_device(mk712_dev);
++	release_region(mk712_io, 8);
++	return err;
+ }
+ 
+ static void __exit mk712_exit(void)
+ {
+-	input_unregister_device(&mk712_dev);
+-	free_irq(mk712_irq, &mk712_dev);
++	input_unregister_device(mk712_dev);
++	free_irq(mk712_irq, mk712_dev);
+ 	release_region(mk712_io, 8);
+ }
+ 
+diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c
+--- a/drivers/input/touchscreen/mtouch.c
++++ b/drivers/input/touchscreen/mtouch.c
+@@ -51,14 +51,12 @@ MODULE_LICENSE("GPL");
+ #define MTOUCH_GET_YC(data) (((data[4])<<7) | data[3])
+ #define MTOUCH_GET_TOUCHED(data) (MTOUCH_FORMAT_TABLET_TOUCH_BIT & data[0])
+ 
+-static char *mtouch_name = "MicroTouch Serial TouchScreen";
+-
+ /*
+  * Per-touchscreen data.
+  */
+ 
+ struct mtouch {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct serio *serio;
+ 	int idx;
+ 	unsigned char data[MTOUCH_MAX_LENGTH];
+@@ -67,7 +65,7 @@ struct mtouch {
+ 
+ static void mtouch_process_format_tablet(struct mtouch *mtouch, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &mtouch->dev;
++	struct input_dev *dev = mtouch->dev;
+ 
+ 	if (MTOUCH_FORMAT_TABLET_LENGTH == ++mtouch->idx) {
+ 		input_regs(dev, regs);
+@@ -116,9 +114,11 @@ static void mtouch_disconnect(struct ser
+ {
+ 	struct mtouch* mtouch = serio_get_drvdata(serio);
+ 
+-	input_unregister_device(&mtouch->dev);
++	input_get_device(mtouch->dev);
++	input_unregister_device(mtouch->dev);
+ 	serio_close(serio);
+ 	serio_set_drvdata(serio, NULL);
++	input_put_device(mtouch->dev);
+ 	kfree(mtouch);
+ }
+ 
+@@ -131,46 +131,46 @@ static void mtouch_disconnect(struct ser
+ static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
+ {
+ 	struct mtouch *mtouch;
++	struct input_dev *input_dev;
+ 	int err;
+ 
+-	if (!(mtouch = kmalloc(sizeof(*mtouch), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset(mtouch, 0, sizeof(*mtouch));
+-
+-	init_input_dev(&mtouch->dev);
+-	mtouch->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-	mtouch->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+-
+-	input_set_abs_params(&mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
+-	input_set_abs_params(&mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
++	mtouch = kzalloc(sizeof(struct mtouch), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!mtouch || !input_dev) {
++		err = -ENOMEM;
++		goto fail;
++	}
+ 
+ 	mtouch->serio = serio;
+-
++	mtouch->dev = input_dev;
+ 	sprintf(mtouch->phys, "%s/input0", serio->phys);
+ 
+-	mtouch->dev.private = mtouch;
+-	mtouch->dev.name = mtouch_name;
+-	mtouch->dev.phys = mtouch->phys;
+-	mtouch->dev.id.bustype = BUS_RS232;
+-	mtouch->dev.id.vendor = SERIO_MICROTOUCH;
+-	mtouch->dev.id.product = 0;
+-	mtouch->dev.id.version = 0x0100;
++	input_dev->private = mtouch;
++	input_dev->name = "MicroTouch Serial TouchScreen";
++	input_dev->phys = mtouch->phys;
++	input_dev->id.bustype = BUS_RS232;
++	input_dev->id.vendor = SERIO_MICROTOUCH;
++	input_dev->id.product = 0;
++	input_dev->id.version = 0x0100;
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++	input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
++	input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
+ 
+ 	serio_set_drvdata(serio, mtouch);
+ 
+ 	err = serio_open(serio, drv);
+-	if (err) {
+-		serio_set_drvdata(serio, NULL);
+-		kfree(mtouch);
+-		return err;
+-	}
+-
+-	input_register_device(&mtouch->dev);
++	if (err)
++		goto fail;
+ 
+-	printk(KERN_INFO "input: %s on %s\n", mtouch->dev.name, serio->phys);
++	input_register_device(mtouch->dev);
+ 
+ 	return 0;
++
++ fail:	serio_set_drvdata(serio, NULL);
++	input_free_device(input_dev);
++	kfree(mtouch);
++	return err;
+ }
+ 
+ /*
+diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
+--- a/drivers/input/tsdev.c
++++ b/drivers/input/tsdev.c
+@@ -53,7 +53,6 @@
+ #include <linux/random.h>
+ #include <linux/time.h>
+ #include <linux/device.h>
+-#include <linux/devfs_fs_kernel.h>
+ 
+ #ifndef CONFIG_INPUT_TSDEV_SCREEN_X
+ #define CONFIG_INPUT_TSDEV_SCREEN_X	240
+@@ -369,6 +368,7 @@ static struct input_handle *tsdev_connec
+ 					  struct input_device_id *id)
+ {
+ 	struct tsdev *tsdev;
++	struct class_device *cdev;
+ 	int minor, delta;
+ 
+ 	for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor];
+@@ -410,13 +410,13 @@ static struct input_handle *tsdev_connec
+ 
+ 	tsdev_table[minor] = tsdev;
+ 
+-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
+-			S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);
+-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2),
+-			S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor);
+-	class_device_create(input_class,
++	cdev = class_device_create(&input_class, &dev->cdev,
+ 			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
+-			dev->dev, "ts%d", minor);
++			dev->cdev.dev, tsdev->name);
++
++	/* temporary symlink to keep userspace happy */
++	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
++			  tsdev->name);
+ 
+ 	return &tsdev->handle;
+ }
+@@ -426,10 +426,9 @@ static void tsdev_disconnect(struct inpu
+ 	struct tsdev *tsdev = handle->private;
+ 	struct tsdev_list *list;
+ 
+-	class_device_destroy(input_class,
++	sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
++	class_device_destroy(&input_class,
+ 			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
+-	devfs_remove("input/ts%d", tsdev->minor);
+-	devfs_remove("input/tsraw%d", tsdev->minor);
+ 	tsdev->exist = 0;
+ 
+ 	if (tsdev->open) {
+diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
+--- a/drivers/isdn/capi/capi.c
++++ b/drivers/isdn/capi/capi.c
+@@ -1505,7 +1505,7 @@ static int __init capi_init(void)
+ 		return PTR_ERR(capi_class);
+ 	}
+ 
+-	class_device_create(capi_class, MKDEV(capi_major, 0), NULL, "capi");
++	class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
+ 	devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
+ 			"isdn/capi20");
+ 
+diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
+--- a/drivers/isdn/capi/capifs.c
++++ b/drivers/isdn/capi/capifs.c
+@@ -15,6 +15,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/ctype.h>
++#include <linux/sched.h>	/* current */
+ 
+ MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
+ MODULE_AUTHOR("Carsten Paeth");
+diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
+--- a/drivers/isdn/hisax/hfc4s8s_l1.c
++++ b/drivers/isdn/hisax/hfc4s8s_l1.c
+@@ -1063,7 +1063,7 @@ tx_b_frame(struct hfc4s8s_btype *bch)
+ 				Write_hfc8(l1->hw, A_INC_RES_FIFO, 1);
+ 			}
+ 			ack_len += skb->truesize;
+-			bch->tx_skb = 0;
++			bch->tx_skb = NULL;
+ 			bch->tx_cnt = 0;
+ 			dev_kfree_skb(skb);
+ 		} else
+@@ -1659,10 +1659,10 @@ hfc4s8s_remove(struct pci_dev *pdev)
+ }
+ 
+ static struct pci_driver hfc4s8s_driver = {
+-      name:"hfc4s8s_l1",
+-      probe:hfc4s8s_probe,
+-      remove:__devexit_p(hfc4s8s_remove),
+-      id_table:hfc4s8s_ids,
++      .name	= "hfc4s8s_l1",
++      .probe	= hfc4s8s_probe,
++      .remove	= __devexit_p(hfc4s8s_remove),
++      .id_table	= hfc4s8s_ids,
+ };
+ 
+ /**********************/
+diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
+--- a/drivers/macintosh/adb.c
++++ b/drivers/macintosh/adb.c
+@@ -905,5 +905,5 @@ adbdev_init(void)
+ 	adb_dev_class = class_create(THIS_MODULE, "adb");
+ 	if (IS_ERR(adb_dev_class))
+ 		return;
+-	class_device_create(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb");
++	class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
+ }
+diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
+--- a/drivers/macintosh/adbhid.c
++++ b/drivers/macintosh/adbhid.c
+@@ -206,7 +206,7 @@ u8 adb_to_linux_keycodes[128] = {
+ };
+ 
+ struct adbhid {
+-	struct input_dev input;
++	struct input_dev *input;
+ 	int id;
+ 	int default_id;
+ 	int original_handler_id;
+@@ -291,10 +291,10 @@ adbhid_input_keycode(int id, int keycode
+ 
+ 	switch (keycode) {
+ 	case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */
+-		input_regs(&ahid->input, regs);
+-		input_report_key(&ahid->input, KEY_CAPSLOCK, 1);
+-		input_report_key(&ahid->input, KEY_CAPSLOCK, 0);
+-		input_sync(&ahid->input);
++		input_regs(ahid->input, regs);
++		input_report_key(ahid->input, KEY_CAPSLOCK, 1);
++		input_report_key(ahid->input, KEY_CAPSLOCK, 0);
++		input_sync(ahid->input);
+ 		return;
+ #ifdef CONFIG_PPC_PMAC
+ 	case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */
+@@ -347,10 +347,10 @@ adbhid_input_keycode(int id, int keycode
+ 	}
+ 
+ 	if (adbhid[id]->keycode[keycode]) {
+-		input_regs(&adbhid[id]->input, regs);
+-		input_report_key(&adbhid[id]->input,
++		input_regs(adbhid[id]->input, regs);
++		input_report_key(adbhid[id]->input,
+ 				 adbhid[id]->keycode[keycode], !up_flag);
+-		input_sync(&adbhid[id]->input);
++		input_sync(adbhid[id]->input);
+ 	} else
+ 		printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode,
+ 		       up_flag ? "released" : "pressed");
+@@ -441,20 +441,20 @@ adbhid_mouse_input(unsigned char *data, 
+                 break;
+ 	}
+ 
+-	input_regs(&adbhid[id]->input, regs);
++	input_regs(adbhid[id]->input, regs);
+ 
+-	input_report_key(&adbhid[id]->input, BTN_LEFT,   !((data[1] >> 7) & 1));
+-	input_report_key(&adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
++	input_report_key(adbhid[id]->input, BTN_LEFT,   !((data[1] >> 7) & 1));
++	input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
+ 
+ 	if (nb >= 4 && adbhid[id]->mouse_kind != ADBMOUSE_TRACKPAD)
+-		input_report_key(&adbhid[id]->input, BTN_RIGHT,  !((data[3] >> 7) & 1));
++		input_report_key(adbhid[id]->input, BTN_RIGHT,  !((data[3] >> 7) & 1));
+ 
+-	input_report_rel(&adbhid[id]->input, REL_X,
++	input_report_rel(adbhid[id]->input, REL_X,
+ 			 ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 ));
+-	input_report_rel(&adbhid[id]->input, REL_Y,
++	input_report_rel(adbhid[id]->input, REL_Y,
+ 			 ((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 ));
+ 
+-	input_sync(&adbhid[id]->input);
++	input_sync(adbhid[id]->input);
+ }
+ 
+ static void
+@@ -467,7 +467,7 @@ adbhid_buttons_input(unsigned char *data
+ 		return;
+ 	}
+ 
+-	input_regs(&adbhid[id]->input, regs);
++	input_regs(adbhid[id]->input, regs);
+ 
+ 	switch (adbhid[id]->original_handler_id) {
+ 	default:
+@@ -477,19 +477,19 @@ adbhid_buttons_input(unsigned char *data
+ 
+ 		switch (data[1] & 0x0f) {
+ 		case 0x0:	/* microphone */
+-			input_report_key(&adbhid[id]->input, KEY_SOUND, down);
++			input_report_key(adbhid[id]->input, KEY_SOUND, down);
+ 			break;
+ 
+ 		case 0x1:	/* mute */
+-			input_report_key(&adbhid[id]->input, KEY_MUTE, down);
++			input_report_key(adbhid[id]->input, KEY_MUTE, down);
+ 			break;
+ 
+ 		case 0x2:	/* volume decrease */
+-			input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down);
++			input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
+ 			break;
+ 
+ 		case 0x3:	/* volume increase */
+-			input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down);
++			input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
+ 			break;
+ 
+ 		default:
+@@ -513,19 +513,19 @@ adbhid_buttons_input(unsigned char *data
+ 
+ 		switch (data[1] & 0x0f) {
+ 		case 0x8:	/* mute */
+-			input_report_key(&adbhid[id]->input, KEY_MUTE, down);
++			input_report_key(adbhid[id]->input, KEY_MUTE, down);
+ 			break;
+ 
+ 		case 0x7:	/* volume decrease */
+-			input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down);
++			input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
+ 			break;
+ 
+ 		case 0x6:	/* volume increase */
+-			input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down);
++			input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
+ 			break;
+ 
+ 		case 0xb:	/* eject */
+-			input_report_key(&adbhid[id]->input, KEY_EJECTCD, down);
++			input_report_key(adbhid[id]->input, KEY_EJECTCD, down);
+ 			break;
+ 
+ 		case 0xa:	/* brightness decrease */
+@@ -539,7 +539,7 @@ adbhid_buttons_input(unsigned char *data
+ 				}
+ 			}
+ #endif /* CONFIG_PMAC_BACKLIGHT */
+-			input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
++			input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
+ 			break;
+ 
+ 		case 0x9:	/* brightness increase */
+@@ -553,19 +553,19 @@ adbhid_buttons_input(unsigned char *data
+ 				}
+ 			}
+ #endif /* CONFIG_PMAC_BACKLIGHT */
+-			input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down);
++			input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down);
+ 			break;
+ 
+ 		case 0xc:	/* videomode switch */
+-			input_report_key(&adbhid[id]->input, KEY_SWITCHVIDEOMODE, down);
++			input_report_key(adbhid[id]->input, KEY_SWITCHVIDEOMODE, down);
+ 			break;
+ 
+ 		case 0xd:	/* keyboard illumination toggle */
+-			input_report_key(&adbhid[id]->input, KEY_KBDILLUMTOGGLE, down);
++			input_report_key(adbhid[id]->input, KEY_KBDILLUMTOGGLE, down);
+ 			break;
+ 
+ 		case 0xe:	/* keyboard illumination decrease */
+-			input_report_key(&adbhid[id]->input, KEY_KBDILLUMDOWN, down);
++			input_report_key(adbhid[id]->input, KEY_KBDILLUMDOWN, down);
+ 			break;
+ 
+ 		case 0xf:
+@@ -573,7 +573,7 @@ adbhid_buttons_input(unsigned char *data
+ 			case 0x8f:
+ 			case 0x0f:
+ 				/* keyboard illumination increase */
+-				input_report_key(&adbhid[id]->input, KEY_KBDILLUMUP, down);
++				input_report_key(adbhid[id]->input, KEY_KBDILLUMUP, down);
+ 				break;
+ 
+ 			case 0x7f:
+@@ -596,7 +596,7 @@ adbhid_buttons_input(unsigned char *data
+ 	  break;
+ 	}
+ 
+-	input_sync(&adbhid[id]->input);
++	input_sync(adbhid[id]->input);
+ }
+ 
+ static struct adb_request led_request;
+@@ -683,7 +683,7 @@ adb_message_handler(struct notifier_bloc
+ 			int i;
+ 			for (i = 1; i < 16; i++) {
+ 				if (adbhid[i])
+-					del_timer_sync(&adbhid[i]->input.timer);
++					del_timer_sync(&adbhid[i]->input->timer);
+ 			}
+ 		}
+ 
+@@ -699,153 +699,164 @@ adb_message_handler(struct notifier_bloc
+ 	return NOTIFY_DONE;
+ }
+ 
+-static void
++static int
+ adbhid_input_register(int id, int default_id, int original_handler_id,
+ 		      int current_handler_id, int mouse_kind)
+ {
++	struct adbhid *hid;
++	struct input_dev *input_dev;
++	int err;
+ 	int i;
+ 
+ 	if (adbhid[id]) {
+ 		printk(KERN_ERR "Trying to reregister ADB HID on ID %d\n", id);
+-		return;
++		return -EEXIST;
+ 	}
+ 
+-	if (!(adbhid[id] = kmalloc(sizeof(struct adbhid), GFP_KERNEL)))
+-		return;
+-
+-	memset(adbhid[id], 0, sizeof(struct adbhid));
+-	sprintf(adbhid[id]->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
++	adbhid[id] = hid = kzalloc(sizeof(struct adbhid), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!hid || !input_dev) {
++		err = -ENOMEM;
++		goto fail;
+ 
+-	init_input_dev(&adbhid[id]->input);
++	}
+ 
+-	adbhid[id]->id = default_id;
+-	adbhid[id]->original_handler_id = original_handler_id;
+-	adbhid[id]->current_handler_id = current_handler_id;
+-	adbhid[id]->mouse_kind = mouse_kind;
+-	adbhid[id]->flags = 0;
+-	adbhid[id]->input.private = adbhid[id];
+-	adbhid[id]->input.name = adbhid[id]->name;
+-	adbhid[id]->input.phys = adbhid[id]->phys;
+-	adbhid[id]->input.id.bustype = BUS_ADB;
+-	adbhid[id]->input.id.vendor = 0x0001;
+-	adbhid[id]->input.id.product = (id << 12) | (default_id << 8) | original_handler_id;
+-	adbhid[id]->input.id.version = 0x0100;
++	sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
++
++	hid->input = input_dev;
++	hid->id = default_id;
++	hid->original_handler_id = original_handler_id;
++	hid->current_handler_id = current_handler_id;
++	hid->mouse_kind = mouse_kind;
++	hid->flags = 0;
++	input_dev->private = hid;
++	input_dev->name = hid->name;
++	input_dev->phys = hid->phys;
++	input_dev->id.bustype = BUS_ADB;
++	input_dev->id.vendor = 0x0001;
++	input_dev->id.product = (id << 12) | (default_id << 8) | original_handler_id;
++	input_dev->id.version = 0x0100;
+ 
+ 	switch (default_id) {
+ 	case ADB_KEYBOARD:
+-		if (!(adbhid[id]->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL))) {
+-			kfree(adbhid[id]);
+-			return;
++		hid->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL);
++		if (!hid->keycode) {
++			err = -ENOMEM;
++			goto fail;
+ 		}
+ 
+-		sprintf(adbhid[id]->name, "ADB keyboard");
++		sprintf(hid->name, "ADB keyboard");
+ 
+-		memcpy(adbhid[id]->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
++		memcpy(hid->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
+ 
+ 		printk(KERN_INFO "Detected ADB keyboard, type ");
+ 		switch (original_handler_id) {
+ 		default:
+ 			printk("<unknown>.\n");
+-			adbhid[id]->input.id.version = ADB_KEYBOARD_UNKNOWN;
++			input_dev->id.version = ADB_KEYBOARD_UNKNOWN;
+ 			break;
+ 
+ 		case 0x01: case 0x02: case 0x03: case 0x06: case 0x08:
+ 		case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C:
+ 		case 0xC0: case 0xC3: case 0xC6:
+ 			printk("ANSI.\n");
+-			adbhid[id]->input.id.version = ADB_KEYBOARD_ANSI;
++			input_dev->id.version = ADB_KEYBOARD_ANSI;
+ 			break;
+ 
+ 		case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
+ 		case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
+ 		case 0xC4: case 0xC7:
+ 			printk("ISO, swapping keys.\n");
+-			adbhid[id]->input.id.version = ADB_KEYBOARD_ISO;
+-			i = adbhid[id]->keycode[10];
+-			adbhid[id]->keycode[10] = adbhid[id]->keycode[50];
+-			adbhid[id]->keycode[50] = i;
++			input_dev->id.version = ADB_KEYBOARD_ISO;
++			i = hid->keycode[10];
++			hid->keycode[10] = hid->keycode[50];
++			hid->keycode[50] = i;
+ 			break;
+ 
+ 		case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A:
+ 		case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9:
+ 			printk("JIS.\n");
+-			adbhid[id]->input.id.version = ADB_KEYBOARD_JIS;
++			input_dev->id.version = ADB_KEYBOARD_JIS;
+ 			break;
+ 		}
+ 
+ 		for (i = 0; i < 128; i++)
+-			if (adbhid[id]->keycode[i])
+-				set_bit(adbhid[id]->keycode[i], adbhid[id]->input.keybit);
++			if (hid->keycode[i])
++				set_bit(hid->keycode[i], input_dev->keybit);
+ 
+-		adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+-		adbhid[id]->input.ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
+-		adbhid[id]->input.event = adbhid_kbd_event;
+-		adbhid[id]->input.keycodemax = 127;
+-		adbhid[id]->input.keycodesize = 1;
++		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
++		input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
++		input_dev->event = adbhid_kbd_event;
++		input_dev->keycodemax = 127;
++		input_dev->keycodesize = 1;
+ 		break;
+ 
+ 	case ADB_MOUSE:
+-		sprintf(adbhid[id]->name, "ADB mouse");
++		sprintf(hid->name, "ADB mouse");
+ 
+-		adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+-		adbhid[id]->input.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+-		adbhid[id]->input.relbit[0] = BIT(REL_X) | BIT(REL_Y);
++		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++		input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++		input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ 		break;
+ 
+ 	case ADB_MISC:
+ 		switch (original_handler_id) {
+ 		case 0x02: /* Adjustable keyboard button device */
+-			sprintf(adbhid[id]->name, "ADB adjustable keyboard buttons");
+-			adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+-			set_bit(KEY_SOUND, adbhid[id]->input.keybit);
+-			set_bit(KEY_MUTE, adbhid[id]->input.keybit);
+-			set_bit(KEY_VOLUMEUP, adbhid[id]->input.keybit);
+-			set_bit(KEY_VOLUMEDOWN, adbhid[id]->input.keybit);
++			sprintf(hid->name, "ADB adjustable keyboard buttons");
++			input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++			set_bit(KEY_SOUND, input_dev->keybit);
++			set_bit(KEY_MUTE, input_dev->keybit);
++			set_bit(KEY_VOLUMEUP, input_dev->keybit);
++			set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
+ 			break;
+ 		case 0x1f: /* Powerbook button device */
+-			sprintf(adbhid[id]->name, "ADB Powerbook buttons");
+-			adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+-			set_bit(KEY_MUTE, adbhid[id]->input.keybit);
+-			set_bit(KEY_VOLUMEUP, adbhid[id]->input.keybit);
+-			set_bit(KEY_VOLUMEDOWN, adbhid[id]->input.keybit);
+-			set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit);
+-			set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit);
+-			set_bit(KEY_EJECTCD, adbhid[id]->input.keybit);
+-			set_bit(KEY_SWITCHVIDEOMODE, adbhid[id]->input.keybit);
+-			set_bit(KEY_KBDILLUMTOGGLE, adbhid[id]->input.keybit);
+-			set_bit(KEY_KBDILLUMDOWN, adbhid[id]->input.keybit);
+-			set_bit(KEY_KBDILLUMUP, adbhid[id]->input.keybit);
++			sprintf(hid->name, "ADB Powerbook buttons");
++			input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++			set_bit(KEY_MUTE, input_dev->keybit);
++			set_bit(KEY_VOLUMEUP, input_dev->keybit);
++			set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
++			set_bit(KEY_BRIGHTNESSUP, input_dev->keybit);
++			set_bit(KEY_BRIGHTNESSDOWN, input_dev->keybit);
++			set_bit(KEY_EJECTCD, input_dev->keybit);
++			set_bit(KEY_SWITCHVIDEOMODE, input_dev->keybit);
++			set_bit(KEY_KBDILLUMTOGGLE, input_dev->keybit);
++			set_bit(KEY_KBDILLUMDOWN, input_dev->keybit);
++			set_bit(KEY_KBDILLUMUP, input_dev->keybit);
+ 			break;
+ 		}
+-		if (adbhid[id]->name[0])
++		if (hid->name[0])
+ 			break;
+ 		/* else fall through */
+ 
+ 	default:
+ 		printk(KERN_INFO "Trying to register unknown ADB device to input layer.\n");
+-		kfree(adbhid[id]);
+-		return;
++		err = -ENODEV;
++		goto fail;
+ 	}
+ 
+-	adbhid[id]->input.keycode = adbhid[id]->keycode;
+-
+-	input_register_device(&adbhid[id]->input);
++	input_dev->keycode = hid->keycode;
+ 
+-	printk(KERN_INFO "input: %s on %s\n",
+-	       adbhid[id]->name, adbhid[id]->phys);
++	input_register_device(input_dev);
+ 
+ 	if (default_id == ADB_KEYBOARD) {
+ 		/* HACK WARNING!! This should go away as soon there is an utility
+ 		 * to control that for event devices.
+ 		 */
+-		adbhid[id]->input.rep[REP_DELAY] = 500;   /* input layer default: 250 */
+-		adbhid[id]->input.rep[REP_PERIOD] = 66; /* input layer default: 33 */
++		input_dev->rep[REP_DELAY] = 500;   /* input layer default: 250 */
++		input_dev->rep[REP_PERIOD] = 66; /* input layer default: 33 */
+ 	}
++
++	return 0;
++
++ fail:	input_free_device(input_dev);
++	kfree(hid);
++	adbhid[id] = NULL;
++	return err;
+ }
+ 
+ static void adbhid_input_unregister(int id)
+ {
+-	input_unregister_device(&adbhid[id]->input);
++	input_unregister_device(adbhid[id]->input);
+ 	if (adbhid[id]->keycode)
+ 		kfree(adbhid[id]->keycode);
+ 	kfree(adbhid[id]);
+@@ -858,7 +869,7 @@ adbhid_input_reregister(int id, int defa
+ 			int cur_handler_id, int mk)
+ {
+ 	if (adbhid[id]) {
+-		if (adbhid[id]->input.id.product !=
++		if (adbhid[id]->input->id.product !=
+ 		    ((id << 12)|(default_id << 8)|org_handler_id)) {
+ 			adbhid_input_unregister(id);
+ 			adbhid_input_register(id, default_id, org_handler_id,
+diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c
+--- a/drivers/macintosh/ans-lcd.c
++++ b/drivers/macintosh/ans-lcd.c
+@@ -27,7 +27,7 @@ static volatile unsigned char __iomem *a
+ 
+ #undef DEBUG
+ 
+-static void __pmac
++static void
+ anslcd_write_byte_ctrl ( unsigned char c )
+ {
+ #ifdef DEBUG
+@@ -43,14 +43,14 @@ anslcd_write_byte_ctrl ( unsigned char c
+ 	}
+ }
+ 
+-static void __pmac
++static void
+ anslcd_write_byte_data ( unsigned char c )
+ {
+ 	out_8(anslcd_ptr + ANSLCD_DATA_IX, c);
+ 	udelay(anslcd_short_delay);
+ }
+ 
+-static ssize_t __pmac
++static ssize_t
+ anslcd_write( struct file * file, const char __user * buf, 
+ 				size_t count, loff_t *ppos )
+ {
+@@ -73,7 +73,7 @@ anslcd_write( struct file * file, const 
+ 	return p - buf;
+ }
+ 
+-static int __pmac
++static int
+ anslcd_ioctl( struct inode * inode, struct file * file,
+ 				unsigned int cmd, unsigned long arg )
+ {
+@@ -115,7 +115,7 @@ anslcd_ioctl( struct inode * inode, stru
+ 	}
+ }
+ 
+-static int __pmac
++static int
+ anslcd_open( struct inode * inode, struct file * file )
+ {
+ 	return 0;
+diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c
+--- a/drivers/macintosh/apm_emu.c
++++ b/drivers/macintosh/apm_emu.c
+@@ -430,8 +430,8 @@ static int apm_emu_get_info(char *buf, c
+ 	      -1: Unknown
+ 	   8) min = minutes; sec = seconds */
+ 
+-	unsigned short  ac_line_status = 0xff;
+-	unsigned short  battery_status = 0xff;
++	unsigned short  ac_line_status;
++	unsigned short  battery_status = 0;
+ 	unsigned short  battery_flag   = 0xff;
+ 	int		percentage     = -1;
+ 	int             time_units     = -1;
+@@ -446,6 +446,7 @@ static int apm_emu_get_info(char *buf, c
+ 	ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0);
+ 	for (i=0; i<pmu_battery_count; i++) {
+ 		if (pmu_batteries[i].flags & PMU_BATT_PRESENT) {
++			battery_status++;
+ 			if (percentage < 0)
+ 				percentage = 0;
+ 			if (charge < 0)
+@@ -461,6 +462,9 @@ static int apm_emu_get_info(char *buf, c
+ 				charging++;
+ 		}
+ 	}
++	if (0 == battery_status)
++		ac_line_status = 1;
++	battery_status = 0xff;
+ 	if (real_count) {
+ 		if (amperage < 0) {
+ 			if (btype == PMU_BATT_TYPE_SMART)
+diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
+--- a/drivers/macintosh/mac_hid.c
++++ b/drivers/macintosh/mac_hid.c
+@@ -16,8 +16,8 @@
+ #include <linux/module.h>
+ 
+ 
+-static struct input_dev emumousebtn;
+-static void emumousebtn_input_register(void);
++static struct input_dev *emumousebtn;
++static int emumousebtn_input_register(void);
+ static int mouse_emulate_buttons = 0;
+ static int mouse_button2_keycode = KEY_RIGHTCTRL;	/* right control key */
+ static int mouse_button3_keycode = KEY_RIGHTALT;	/* right option key */
+@@ -90,10 +90,10 @@ int mac_hid_mouse_emulate_buttons(int ca
+ 		    && (keycode == mouse_button2_keycode
+ 			|| keycode == mouse_button3_keycode)) {
+ 			if (mouse_emulate_buttons == 1) {
+-			 	input_report_key(&emumousebtn,
++				input_report_key(emumousebtn,
+ 						 keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
+ 						 down);
+-				input_sync(&emumousebtn);
++				input_sync(emumousebtn);
+ 				return 1;
+ 			}
+ 			mouse_last_keycode = down ? keycode : 0;
+@@ -105,30 +105,34 @@ int mac_hid_mouse_emulate_buttons(int ca
+ 
+ EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons);
+ 
+-static void emumousebtn_input_register(void)
++static int emumousebtn_input_register(void)
+ {
+-	emumousebtn.name = "Macintosh mouse button emulation";
++	emumousebtn = input_allocate_device();
++	if (!emumousebtn)
++		return -ENOMEM;
++
++	emumousebtn->name = "Macintosh mouse button emulation";
++	emumousebtn->id.bustype = BUS_ADB;
++	emumousebtn->id.vendor = 0x0001;
++	emumousebtn->id.product = 0x0001;
++	emumousebtn->id.version = 0x0100;
++
++	emumousebtn->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++	emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
++	emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ 
+-	init_input_dev(&emumousebtn);
++	input_register_device(emumousebtn);
+ 
+-	emumousebtn.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+-	emumousebtn.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+-	emumousebtn.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+-
+-	emumousebtn.id.bustype = BUS_ADB;
+-	emumousebtn.id.vendor = 0x0001;
+-	emumousebtn.id.product = 0x0001;
+-	emumousebtn.id.version = 0x0100;
+-
+-	input_register_device(&emumousebtn);
+-
+-	printk(KERN_INFO "input: Macintosh mouse button emulation\n");
++	return 0;
+ }
+ 
+ int __init mac_hid_init(void)
+ {
++	int err;
+ 
+-	emumousebtn_input_register();
++	err = emumousebtn_input_register();
++	if (err)
++		return err;
+ 
+ #if defined(CONFIG_SYSCTL)
+ 	mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir, 1);
+diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
+--- a/drivers/macintosh/macio_asic.c
++++ b/drivers/macintosh/macio_asic.c
+@@ -17,6 +17,8 @@
+ #include <linux/pci_ids.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
++#include <linux/slab.h>
++
+ #include <asm/machdep.h>
+ #include <asm/macio.h>
+ #include <asm/pmac_feature.h>
+diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
+--- a/drivers/macintosh/macio_sysfs.c
++++ b/drivers/macintosh/macio_sysfs.c
+@@ -39,6 +39,31 @@ compatible_show (struct device *dev, str
+ 	return length;
+ }
+ 
++static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
++			      char *buf)
++{
++	struct of_device *of;
++	char *compat;
++	int cplen;
++	int length;
++
++	of = &to_macio_device (dev)->ofdev;
++	compat = (char *) get_property (of->node, "compatible", &cplen);
++	if (!compat) compat = "", cplen = 1;
++	length = sprintf (buf, "of:N%sT%s", of->node->name, of->node->type);
++	buf += length;
++	while (cplen > 0) {
++		int l;
++		length += sprintf (buf, "C%s", compat);
++		buf += length;
++		l = strlen (compat) + 1;
++		compat += l;
++		cplen -= l;
++	}
++
++	return length;
++}
++
+ macio_config_of_attr (name, "%s\n");
+ macio_config_of_attr (type, "%s\n");
+ 
+@@ -46,5 +71,6 @@ struct device_attribute macio_dev_attrs[
+ 	__ATTR_RO(name),
+ 	__ATTR_RO(type),
+ 	__ATTR_RO(compatible),
++	__ATTR_RO(modalias),
+ 	__ATTR_NULL
+ };
+diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
+--- a/drivers/macintosh/mediabay.c
++++ b/drivers/macintosh/mediabay.c
+@@ -167,19 +167,19 @@ enum {
+  * Functions for polling content of media bay
+  */
+  
+-static u8 __pmac
++static u8
+ ohare_mb_content(struct media_bay_info *bay)
+ {
+ 	return (MB_IN32(bay, OHARE_MBCR) >> 12) & 7;
+ }
+ 
+-static u8 __pmac
++static u8
+ heathrow_mb_content(struct media_bay_info *bay)
+ {
+ 	return (MB_IN32(bay, HEATHROW_MBCR) >> 12) & 7;
+ }
+ 
+-static u8 __pmac
++static u8
+ keylargo_mb_content(struct media_bay_info *bay)
+ {
+ 	int new_gpio;
+@@ -205,7 +205,7 @@ keylargo_mb_content(struct media_bay_inf
+  * into reset state as well
+  */
+ 
+-static void __pmac
++static void
+ ohare_mb_power(struct media_bay_info* bay, int on_off)
+ {
+ 	if (on_off) {
+@@ -224,7 +224,7 @@ ohare_mb_power(struct media_bay_info* ba
+ 	MB_BIC(bay, OHARE_MBCR, 0x00000F00);
+ }
+ 
+-static void __pmac
++static void
+ heathrow_mb_power(struct media_bay_info* bay, int on_off)
+ {
+ 	if (on_off) {
+@@ -243,7 +243,7 @@ heathrow_mb_power(struct media_bay_info*
+ 	MB_BIC(bay, HEATHROW_MBCR, 0x00000F00);
+ }
+ 
+-static void __pmac
++static void
+ keylargo_mb_power(struct media_bay_info* bay, int on_off)
+ {
+ 	if (on_off) {
+@@ -267,7 +267,7 @@ keylargo_mb_power(struct media_bay_info*
+  * enable the related busses
+  */
+ 
+-static int __pmac
++static int
+ ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
+ {
+ 	switch(device_id) {
+@@ -287,7 +287,7 @@ ohare_mb_setup_bus(struct media_bay_info
+ 	return -ENODEV;
+ }
+ 
+-static int __pmac
++static int
+ heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
+ {
+ 	switch(device_id) {
+@@ -307,7 +307,7 @@ heathrow_mb_setup_bus(struct media_bay_i
+ 	return -ENODEV;
+ }
+ 
+-static int __pmac
++static int
+ keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
+ {
+ 	switch(device_id) {
+@@ -330,43 +330,43 @@ keylargo_mb_setup_bus(struct media_bay_i
+  * Functions for tweaking resets
+  */
+ 
+-static void __pmac
++static void
+ ohare_mb_un_reset(struct media_bay_info* bay)
+ {
+ 	MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
+ }
+ 
+-static void __pmac keylargo_mb_init(struct media_bay_info *bay)
++static void keylargo_mb_init(struct media_bay_info *bay)
+ {
+ 	MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
+ }
+ 
+-static void __pmac heathrow_mb_un_reset(struct media_bay_info* bay)
++static void heathrow_mb_un_reset(struct media_bay_info* bay)
+ {
+ 	MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
+ }
+ 
+-static void __pmac keylargo_mb_un_reset(struct media_bay_info* bay)
++static void keylargo_mb_un_reset(struct media_bay_info* bay)
+ {
+ 	MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
+ }
+ 
+-static void __pmac ohare_mb_un_reset_ide(struct media_bay_info* bay)
++static void ohare_mb_un_reset_ide(struct media_bay_info* bay)
+ {
+ 	MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
+ }
+ 
+-static void __pmac heathrow_mb_un_reset_ide(struct media_bay_info* bay)
++static void heathrow_mb_un_reset_ide(struct media_bay_info* bay)
+ {
+ 	MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
+ }
+ 
+-static void __pmac keylargo_mb_un_reset_ide(struct media_bay_info* bay)
++static void keylargo_mb_un_reset_ide(struct media_bay_info* bay)
+ {
+ 	MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
+ }
+ 
+-static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff)
++static inline void set_mb_power(struct media_bay_info* bay, int onoff)
+ {
+ 	/* Power up up and assert the bay reset line */
+ 	if (onoff) {
+@@ -382,7 +382,7 @@ static inline void __pmac set_mb_power(s
+ 	bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
+ }
+ 
+-static void __pmac poll_media_bay(struct media_bay_info* bay)
++static void poll_media_bay(struct media_bay_info* bay)
+ {
+ 	int id = bay->ops->content(bay);
+ 
+@@ -415,7 +415,7 @@ static void __pmac poll_media_bay(struct
+ 	}
+ }
+ 
+-int __pmac check_media_bay(struct device_node *which_bay, int what)
++int check_media_bay(struct device_node *which_bay, int what)
+ {
+ #ifdef CONFIG_BLK_DEV_IDE
+ 	int	i;
+@@ -432,7 +432,7 @@ int __pmac check_media_bay(struct device
+ }
+ EXPORT_SYMBOL(check_media_bay);
+ 
+-int __pmac check_media_bay_by_base(unsigned long base, int what)
++int check_media_bay_by_base(unsigned long base, int what)
+ {
+ #ifdef CONFIG_BLK_DEV_IDE
+ 	int	i;
+@@ -449,7 +449,7 @@ int __pmac check_media_bay_by_base(unsig
+ 	return -ENODEV;
+ }
+ 
+-int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
++int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
+ 	int irq, int index)
+ {
+ #ifdef CONFIG_BLK_DEV_IDE
+@@ -489,7 +489,7 @@ int __pmac media_bay_set_ide_infos(struc
+ 	return -ENODEV;
+ }
+ 
+-static void __pmac media_bay_step(int i)
++static void media_bay_step(int i)
+ {
+ 	struct media_bay_info* bay = &media_bays[i];
+ 
+@@ -619,7 +619,7 @@ static void __pmac media_bay_step(int i)
+  * with the IDE driver.  It needs to be a thread because
+  * ide_register can't be called from interrupt context.
+  */
+-static int __pmac media_bay_task(void *x)
++static int media_bay_task(void *x)
+ {
+ 	int	i;
+ 
+@@ -704,7 +704,7 @@ static int __devinit media_bay_attach(st
+ 
+ }
+ 
+-static int __pmac media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
++static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
+ {
+ 	struct media_bay_info	*bay = macio_get_drvdata(mdev);
+ 
+@@ -719,7 +719,7 @@ static int __pmac media_bay_suspend(stru
+ 	return 0;
+ }
+ 
+-static int __pmac media_bay_resume(struct macio_dev *mdev)
++static int media_bay_resume(struct macio_dev *mdev)
+ {
+ 	struct media_bay_info	*bay = macio_get_drvdata(mdev);
+ 
+@@ -760,7 +760,7 @@ static int __pmac media_bay_resume(struc
+ 
+ /* Definitions of "ops" structures.
+  */
+-static struct mb_ops ohare_mb_ops __pmacdata = {
++static struct mb_ops ohare_mb_ops = {
+ 	.name		= "Ohare",
+ 	.content	= ohare_mb_content,
+ 	.power		= ohare_mb_power,
+@@ -769,7 +769,7 @@ static struct mb_ops ohare_mb_ops __pmac
+ 	.un_reset_ide	= ohare_mb_un_reset_ide,
+ };
+ 
+-static struct mb_ops heathrow_mb_ops __pmacdata = {
++static struct mb_ops heathrow_mb_ops = {
+ 	.name		= "Heathrow",
+ 	.content	= heathrow_mb_content,
+ 	.power		= heathrow_mb_power,
+@@ -778,7 +778,7 @@ static struct mb_ops heathrow_mb_ops __p
+ 	.un_reset_ide	= heathrow_mb_un_reset_ide,
+ };
+ 
+-static struct mb_ops keylargo_mb_ops __pmacdata = {
++static struct mb_ops keylargo_mb_ops = {
+ 	.name		= "KeyLargo",
+ 	.init		= keylargo_mb_init,
+ 	.content	= keylargo_mb_content,
+diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
+--- a/drivers/macintosh/smu.c
++++ b/drivers/macintosh/smu.c
+@@ -1094,7 +1094,7 @@ static int smu_release(struct inode *ino
+ }
+ 
+ 
+-static struct file_operations smu_device_fops __pmacdata = {
++static struct file_operations smu_device_fops = {
+ 	.llseek		= no_llseek,
+ 	.read		= smu_read,
+ 	.write		= smu_write,
+@@ -1103,7 +1103,7 @@ static struct file_operations smu_device
+ 	.release	= smu_release,
+ };
+ 
+-static struct miscdevice pmu_device __pmacdata = {
++static struct miscdevice pmu_device = {
+ 	MISC_DYNAMIC_MINOR, "smu", &smu_device_fops
+ };
+ 
+diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
+--- a/drivers/macintosh/via-cuda.c
++++ b/drivers/macintosh/via-cuda.c
+@@ -37,7 +37,6 @@ static DEFINE_SPINLOCK(cuda_lock);
+ 
+ #ifdef CONFIG_MAC
+ #define CUDA_IRQ IRQ_MAC_ADB
+-#define __openfirmware
+ #define eieio()
+ #else
+ #define CUDA_IRQ vias->intrs[0].line
+diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
+--- a/drivers/macintosh/via-pmu.c
++++ b/drivers/macintosh/via-pmu.c
+@@ -244,7 +244,7 @@ int pmu_wink(struct adb_request *req);
+  * - the number of response bytes which the PMU will return, or
+  *   -1 if it will send a length byte.
+  */
+-static const s8 pmu_data_len[256][2] __openfirmwaredata = {
++static const s8 pmu_data_len[256][2] = {
+ /*	   0	   1	   2	   3	   4	   5	   6	   7  */
+ /*00*/	{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
+ /*08*/	{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
+@@ -295,7 +295,7 @@ static struct backlight_controller pmu_b
+ };
+ #endif /* CONFIG_PMAC_BACKLIGHT */
+ 
+-int __openfirmware
++int
+ find_via_pmu(void)
+ {
+ 	if (via != 0)
+@@ -374,7 +374,7 @@ find_via_pmu(void)
+ }
+ 
+ #ifdef CONFIG_ADB
+-static int __openfirmware
++static int
+ pmu_probe(void)
+ {
+ 	return vias == NULL? -ENODEV: 0;
+@@ -405,7 +405,7 @@ static int __init via_pmu_start(void)
+ 	bright_req_2.complete = 1;
+ 	batt_req.complete = 1;
+ 
+-#ifdef CONFIG_PPC32
++#if defined(CONFIG_PPC32) && !defined(CONFIG_PPC_MERGE)
+ 	if (pmu_kind == PMU_KEYLARGO_BASED)
+ 		openpic_set_irq_priority(vias->intrs[0].line,
+ 					 OPENPIC_PRIORITY_DEFAULT + 1);
+@@ -520,7 +520,7 @@ static int __init via_pmu_dev_init(void)
+ 
+ device_initcall(via_pmu_dev_init);
+ 
+-static int __openfirmware
++static int
+ init_pmu(void)
+ {
+ 	int timeout;
+@@ -588,17 +588,6 @@ pmu_get_model(void)
+ 	return pmu_kind;
+ }
+ 
+-#ifndef CONFIG_PPC64
+-static inline void wakeup_decrementer(void)
+-{
+-	set_dec(tb_ticks_per_jiffy);
+-	/* No currently-supported powerbook has a 601,
+-	 * so use get_tbl, not native
+-	 */
+-	last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
+-}
+-#endif
+-
+ static void pmu_set_server_mode(int server_mode)
+ {
+ 	struct adb_request req;
+@@ -625,7 +614,7 @@ static void pmu_set_server_mode(int serv
+ /* This new version of the code for 2400/3400/3500 powerbooks
+  * is inspired from the implementation in gkrellm-pmu
+  */
+-static void __pmac
++static void
+ done_battery_state_ohare(struct adb_request* req)
+ {
+ 	/* format:
+@@ -713,7 +702,7 @@ done_battery_state_ohare(struct adb_requ
+ 	clear_bit(0, &async_req_locks);
+ }
+ 
+-static void __pmac
++static void
+ done_battery_state_smart(struct adb_request* req)
+ {
+ 	/* format:
+@@ -791,7 +780,7 @@ done_battery_state_smart(struct adb_requ
+ 	clear_bit(0, &async_req_locks);
+ }
+ 
+-static void __pmac
++static void
+ query_battery_state(void)
+ {
+ 	if (test_and_set_bit(0, &async_req_locks))
+@@ -804,7 +793,7 @@ query_battery_state(void)
+ 			2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
+ }
+ 
+-static int __pmac
++static int
+ proc_get_info(char *page, char **start, off_t off,
+ 		int count, int *eof, void *data)
+ {
+@@ -819,7 +808,7 @@ proc_get_info(char *page, char **start, 
+ 	return p - page;
+ }
+ 
+-static int __pmac
++static int
+ proc_get_irqstats(char *page, char **start, off_t off,
+ 		  int count, int *eof, void *data)
+ {
+@@ -846,7 +835,7 @@ proc_get_irqstats(char *page, char **sta
+ 	return p - page;
+ }
+ 
+-static int __pmac
++static int
+ proc_get_batt(char *page, char **start, off_t off,
+ 		int count, int *eof, void *data)
+ {
+@@ -870,7 +859,7 @@ proc_get_batt(char *page, char **start, 
+ 	return p - page;
+ }
+ 
+-static int __pmac
++static int
+ proc_read_options(char *page, char **start, off_t off,
+ 			int count, int *eof, void *data)
+ {
+@@ -887,7 +876,7 @@ proc_read_options(char *page, char **sta
+ 	return p - page;
+ }
+ 			
+-static int __pmac
++static int
+ proc_write_options(struct file *file, const char __user *buffer,
+ 			unsigned long count, void *data)
+ {
+@@ -934,7 +923,7 @@ proc_write_options(struct file *file, co
+ 
+ #ifdef CONFIG_ADB
+ /* Send an ADB command */
+-static int __pmac
++static int
+ pmu_send_request(struct adb_request *req, int sync)
+ {
+ 	int i, ret;
+@@ -1014,7 +1003,7 @@ pmu_send_request(struct adb_request *req
+ }
+ 
+ /* Enable/disable autopolling */
+-static int __pmac
++static int
+ pmu_adb_autopoll(int devs)
+ {
+ 	struct adb_request req;
+@@ -1037,7 +1026,7 @@ pmu_adb_autopoll(int devs)
+ }
+ 
+ /* Reset the ADB bus */
+-static int __pmac
++static int
+ pmu_adb_reset_bus(void)
+ {
+ 	struct adb_request req;
+@@ -1072,7 +1061,7 @@ pmu_adb_reset_bus(void)
+ #endif /* CONFIG_ADB */
+ 
+ /* Construct and send a pmu request */
+-int __openfirmware
++int
+ pmu_request(struct adb_request *req, void (*done)(struct adb_request *),
+ 	    int nbytes, ...)
+ {
+@@ -1098,7 +1087,7 @@ pmu_request(struct adb_request *req, voi
+ 	return pmu_queue_request(req);
+ }
+ 
+-int __pmac
++int
+ pmu_queue_request(struct adb_request *req)
+ {
+ 	unsigned long flags;
+@@ -1190,7 +1179,7 @@ pmu_done(struct adb_request *req)
+ 		(*done)(req);
+ }
+ 
+-static void __pmac
++static void
+ pmu_start(void)
+ {
+ 	struct adb_request *req;
+@@ -1214,7 +1203,7 @@ pmu_start(void)
+ 	send_byte(req->data[0]);
+ }
+ 
+-void __openfirmware
++void
+ pmu_poll(void)
+ {
+ 	if (!via)
+@@ -1224,7 +1213,7 @@ pmu_poll(void)
+ 	via_pmu_interrupt(0, NULL, NULL);
+ }
+ 
+-void __openfirmware
++void
+ pmu_poll_adb(void)
+ {
+ 	if (!via)
+@@ -1239,7 +1228,7 @@ pmu_poll_adb(void)
+ 		|| req_awaiting_reply));
+ }
+ 
+-void __openfirmware
++void
+ pmu_wait_complete(struct adb_request *req)
+ {
+ 	if (!via)
+@@ -1253,7 +1242,7 @@ pmu_wait_complete(struct adb_request *re
+  * This is done to avoid spurrious shutdowns when we know we'll have
+  * interrupts switched off for a long time
+  */
+-void __openfirmware
++void
+ pmu_suspend(void)
+ {
+ 	unsigned long flags;
+@@ -1293,7 +1282,7 @@ pmu_suspend(void)
+ 	} while (1);
+ }
+ 
+-void __openfirmware
++void
+ pmu_resume(void)
+ {
+ 	unsigned long flags;
+@@ -1323,7 +1312,7 @@ pmu_resume(void)
+ }
+ 
+ /* Interrupt data could be the result data from an ADB cmd */
+-static void __pmac
++static void
+ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
+ {
+ 	unsigned char ints, pirq;
+@@ -1435,7 +1424,7 @@ next:
+ 	goto next;
+ }
+ 
+-static struct adb_request* __pmac
++static struct adb_request*
+ pmu_sr_intr(struct pt_regs *regs)
+ {
+ 	struct adb_request *req;
+@@ -1541,7 +1530,7 @@ pmu_sr_intr(struct pt_regs *regs)
+ 	return NULL;
+ }
+ 
+-static irqreturn_t __pmac
++static irqreturn_t
+ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
+ {
+ 	unsigned long flags;
+@@ -1629,7 +1618,7 @@ no_free_slot:			
+ 	return IRQ_RETVAL(handled);
+ }
+ 
+-void __pmac
++void
+ pmu_unlock(void)
+ {
+ 	unsigned long flags;
+@@ -1642,7 +1631,7 @@ pmu_unlock(void)
+ }
+ 
+ 
+-static irqreturn_t __pmac
++static irqreturn_t
+ gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
+ {
+ 	unsigned long flags;
+@@ -1663,12 +1652,12 @@ gpio1_interrupt(int irq, void *arg, stru
+ }
+ 
+ #ifdef CONFIG_PMAC_BACKLIGHT
+-static int backlight_to_bright[] __pmacdata = {
++static int backlight_to_bright[] = {
+ 	0x7f, 0x46, 0x42, 0x3e, 0x3a, 0x36, 0x32, 0x2e,
+ 	0x2a, 0x26, 0x22, 0x1e, 0x1a, 0x16, 0x12, 0x0e
+ };
+  
+-static int __openfirmware
++static int
+ pmu_set_backlight_enable(int on, int level, void* data)
+ {
+ 	struct adb_request req;
+@@ -1688,7 +1677,7 @@ pmu_set_backlight_enable(int on, int lev
+ 	return 0;
+ }
+ 
+-static void __openfirmware
++static void
+ pmu_bright_complete(struct adb_request *req)
+ {
+ 	if (req == &bright_req_1)
+@@ -1697,7 +1686,7 @@ pmu_bright_complete(struct adb_request *
+ 		clear_bit(2, &async_req_locks);
+ }
+ 
+-static int __openfirmware
++static int
+ pmu_set_backlight_level(int level, void* data)
+ {
+ 	if (vias == NULL)
+@@ -1717,7 +1706,7 @@ pmu_set_backlight_level(int level, void*
+ }
+ #endif /* CONFIG_PMAC_BACKLIGHT */
+ 
+-void __pmac
++void
+ pmu_enable_irled(int on)
+ {
+ 	struct adb_request req;
+@@ -1732,7 +1721,7 @@ pmu_enable_irled(int on)
+ 	pmu_wait_complete(&req);
+ }
+ 
+-void __pmac
++void
+ pmu_restart(void)
+ {
+ 	struct adb_request req;
+@@ -1757,7 +1746,7 @@ pmu_restart(void)
+ 		;
+ }
+ 
+-void __pmac
++void
+ pmu_shutdown(void)
+ {
+ 	struct adb_request req;
+@@ -2076,7 +2065,7 @@ pmu_unregister_sleep_notifier(struct pmu
+ }
+ 
+ /* Sleep is broadcast last-to-first */
+-static int __pmac
++static int
+ broadcast_sleep(int when, int fallback)
+ {
+ 	int ret = PBOOK_SLEEP_OK;
+@@ -2101,7 +2090,7 @@ broadcast_sleep(int when, int fallback)
+ }
+ 
+ /* Wake is broadcast first-to-last */
+-static int __pmac
++static int
+ broadcast_wake(void)
+ {
+ 	int ret = PBOOK_SLEEP_OK;
+@@ -2132,7 +2121,7 @@ static struct pci_save {
+ } *pbook_pci_saves;
+ static int pbook_npci_saves;
+ 
+-static void __pmac
++static void
+ pbook_alloc_pci_save(void)
+ {
+ 	int npci;
+@@ -2149,7 +2138,7 @@ pbook_alloc_pci_save(void)
+ 	pbook_npci_saves = npci;
+ }
+ 
+-static void __pmac
++static void
+ pbook_free_pci_save(void)
+ {
+ 	if (pbook_pci_saves == NULL)
+@@ -2159,7 +2148,7 @@ pbook_free_pci_save(void)
+ 	pbook_npci_saves = 0;
+ }
+ 
+-static void __pmac
++static void
+ pbook_pci_save(void)
+ {
+ 	struct pci_save *ps = pbook_pci_saves;
+@@ -2190,7 +2179,7 @@ pbook_pci_save(void)
+  * during boot, it will be in the pci dev list. If it's disabled at this point
+  * (and it will probably be), then you can't access it's config space.
+  */
+-static void __pmac
++static void
+ pbook_pci_restore(void)
+ {
+ 	u16 cmd;
+@@ -2238,7 +2227,7 @@ pbook_pci_restore(void)
+ 
+ #ifdef DEBUG_SLEEP
+ /* N.B. This doesn't work on the 3400 */
+-void  __pmac
++void 
+ pmu_blink(int n)
+ {
+ 	struct adb_request req;
+@@ -2277,9 +2266,9 @@ pmu_blink(int n)
+  * Put the powerbook to sleep.
+  */
+  
+-static u32 save_via[8] __pmacdata;
++static u32 save_via[8];
+ 
+-static void __pmac
++static void
+ save_via_state(void)
+ {
+ 	save_via[0] = in_8(&via[ANH]);
+@@ -2291,7 +2280,7 @@ save_via_state(void)
+ 	save_via[6] = in_8(&via[T1CL]);
+ 	save_via[7] = in_8(&via[T1CH]);
+ }
+-static void __pmac
++static void
+ restore_via_state(void)
+ {
+ 	out_8(&via[ANH], save_via[0]);
+@@ -2307,7 +2296,7 @@ restore_via_state(void)
+ 	out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
+ }
+ 
+-static int __pmac
++static int
+ pmac_suspend_devices(void)
+ {
+ 	int ret;
+@@ -2397,7 +2386,7 @@ pmac_suspend_devices(void)
+ 	return 0;
+ }
+ 
+-static int __pmac
++static int
+ pmac_wakeup_devices(void)
+ {
+ 	mdelay(100);
+@@ -2436,7 +2425,7 @@ pmac_wakeup_devices(void)
+ #define	GRACKLE_NAP	(1<<4)
+ #define	GRACKLE_SLEEP	(1<<3)
+ 
+-int __pmac
++int
+ powerbook_sleep_grackle(void)
+ {
+ 	unsigned long save_l2cr;
+@@ -2520,7 +2509,7 @@ powerbook_sleep_grackle(void)
+ 	return 0;
+ }
+ 
+-static int __pmac
++static int
+ powerbook_sleep_Core99(void)
+ {
+ 	unsigned long save_l2cr;
+@@ -2620,7 +2609,7 @@ powerbook_sleep_Core99(void)
+ #define PB3400_MEM_CTRL		0xf8000000
+ #define PB3400_MEM_CTRL_SLEEP	0x70
+ 
+-static int __pmac
++static int
+ powerbook_sleep_3400(void)
+ {
+ 	int ret, i, x;
+@@ -2720,9 +2709,9 @@ struct pmu_private {
+ };
+ 
+ static LIST_HEAD(all_pmu_pvt);
+-static DEFINE_SPINLOCK(all_pvt_lock __pmacdata);
++static DEFINE_SPINLOCK(all_pvt_lock);
+ 
+-static void __pmac
++static void
+ pmu_pass_intr(unsigned char *data, int len)
+ {
+ 	struct pmu_private *pp;
+@@ -2751,7 +2740,7 @@ pmu_pass_intr(unsigned char *data, int l
+ 	spin_unlock_irqrestore(&all_pvt_lock, flags);
+ }
+ 
+-static int __pmac
++static int
+ pmu_open(struct inode *inode, struct file *file)
+ {
+ 	struct pmu_private *pp;
+@@ -2773,7 +2762,7 @@ pmu_open(struct inode *inode, struct fil
+ 	return 0;
+ }
+ 
+-static ssize_t  __pmac
++static ssize_t 
+ pmu_read(struct file *file, char __user *buf,
+ 			size_t count, loff_t *ppos)
+ {
+@@ -2825,14 +2814,14 @@ pmu_read(struct file *file, char __user 
+ 	return ret;
+ }
+ 
+-static ssize_t __pmac
++static ssize_t
+ pmu_write(struct file *file, const char __user *buf,
+ 			 size_t count, loff_t *ppos)
+ {
+ 	return 0;
+ }
+ 
+-static unsigned int __pmac
++static unsigned int
+ pmu_fpoll(struct file *filp, poll_table *wait)
+ {
+ 	struct pmu_private *pp = filp->private_data;
+@@ -2849,7 +2838,7 @@ pmu_fpoll(struct file *filp, poll_table 
+ 	return mask;
+ }
+ 
+-static int __pmac
++static int
+ pmu_release(struct inode *inode, struct file *file)
+ {
+ 	struct pmu_private *pp = file->private_data;
+@@ -2874,8 +2863,7 @@ pmu_release(struct inode *inode, struct 
+ 	return 0;
+ }
+ 
+-/* Note: removed __openfirmware here since it causes link errors */
+-static int __pmac
++static int
+ pmu_ioctl(struct inode * inode, struct file *filp,
+ 		     u_int cmd, u_long arg)
+ {
+@@ -2957,7 +2945,7 @@ pmu_ioctl(struct inode * inode, struct f
+ 	return error;
+ }
+ 
+-static struct file_operations pmu_device_fops __pmacdata = {
++static struct file_operations pmu_device_fops = {
+ 	.read		= pmu_read,
+ 	.write		= pmu_write,
+ 	.poll		= pmu_fpoll,
+@@ -2966,7 +2954,7 @@ static struct file_operations pmu_device
+ 	.release	= pmu_release,
+ };
+ 
+-static struct miscdevice pmu_device __pmacdata = {
++static struct miscdevice pmu_device = {
+ 	PMU_MINOR, "pmu", &pmu_device_fops
+ };
+ 
+@@ -2982,7 +2970,7 @@ device_initcall(pmu_device_init);
+ 
+ 
+ #ifdef DEBUG_SLEEP
+-static inline void  __pmac
++static inline void 
+ polled_handshake(volatile unsigned char __iomem *via)
+ {
+ 	via[B] &= ~TREQ; eieio();
+@@ -2993,7 +2981,7 @@ polled_handshake(volatile unsigned char 
+ 		;
+ }
+ 
+-static inline void  __pmac
++static inline void 
+ polled_send_byte(volatile unsigned char __iomem *via, int x)
+ {
+ 	via[ACR] |= SR_OUT | SR_EXT; eieio();
+@@ -3001,7 +2989,7 @@ polled_send_byte(volatile unsigned char 
+ 	polled_handshake(via);
+ }
+ 
+-static inline int __pmac
++static inline int
+ polled_recv_byte(volatile unsigned char __iomem *via)
+ {
+ 	int x;
+@@ -3013,7 +3001,7 @@ polled_recv_byte(volatile unsigned char 
+ 	return x;
+ }
+ 
+-int __pmac
++int
+ pmu_polled_request(struct adb_request *req)
+ {
+ 	unsigned long flags;
+diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
+--- a/drivers/macintosh/via-pmu68k.c
++++ b/drivers/macintosh/via-pmu68k.c
+@@ -835,7 +835,7 @@ static struct pci_save {
+ } *pbook_pci_saves;
+ static int n_pbook_pci_saves;
+ 
+-static inline void __openfirmware
++static inline void
+ pbook_pci_save(void)
+ {
+ 	int npci;
+@@ -863,7 +863,7 @@ pbook_pci_save(void)
+ 	}
+ }
+ 
+-static inline void __openfirmware
++static inline void
+ pbook_pci_restore(void)
+ {
+ 	u16 cmd;
+@@ -902,7 +902,7 @@ pbook_pci_restore(void)
+ #define IRQ_ENABLE	((unsigned int *)0xf3000024)
+ #define MEM_CTRL	((unsigned int *)0xf8000070)
+ 
+-int __openfirmware powerbook_sleep(void)
++int powerbook_sleep(void)
+ {
+ 	int ret, i, x;
+ 	static int save_backlight;
+@@ -1001,25 +1001,24 @@ int __openfirmware powerbook_sleep(void)
+ /*
+  * Support for /dev/pmu device
+  */
+-static int __openfirmware pmu_open(struct inode *inode, struct file *file)
++static int pmu_open(struct inode *inode, struct file *file)
+ {
+ 	return 0;
+ }
+ 
+-static ssize_t __openfirmware pmu_read(struct file *file, char *buf,
++static ssize_t pmu_read(struct file *file, char *buf,
+ 			size_t count, loff_t *ppos)
+ {
+ 	return 0;
+ }
+ 
+-static ssize_t __openfirmware pmu_write(struct file *file, const char *buf,
++static ssize_t pmu_write(struct file *file, const char *buf,
+ 			 size_t count, loff_t *ppos)
+ {
+ 	return 0;
+ }
+ 
+-/* Note: removed __openfirmware here since it causes link errors */
+-static int /*__openfirmware*/ pmu_ioctl(struct inode * inode, struct file *filp,
++static int pmu_ioctl(struct inode * inode, struct file *filp,
+ 		     u_int cmd, u_long arg)
+ {
+ 	int error;
+diff --git a/drivers/mca/mca-device.c b/drivers/mca/mca-device.c
+--- a/drivers/mca/mca-device.c
++++ b/drivers/mca/mca-device.c
+@@ -29,6 +29,7 @@
+ #include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/mca.h>
++#include <linux/string.h>
+ 
+ /**
+  *	mca_device_read_stored_pos - read POS register from stored data
+diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
+--- a/drivers/md/bitmap.c
++++ b/drivers/md/bitmap.c
+@@ -91,7 +91,7 @@ int bitmap_active(struct bitmap *bitmap)
+ 
+ #define WRITE_POOL_SIZE 256
+ /* mempool for queueing pending writes on the bitmap file */
+-static void *write_pool_alloc(unsigned int gfp_flags, void *data)
++static void *write_pool_alloc(gfp_t gfp_flags, void *data)
+ {
+ 	return kmalloc(sizeof(struct page_list), gfp_flags);
+ }
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -15,7 +15,7 @@
+ #include <linux/crypto.h>
+ #include <linux/workqueue.h>
+ #include <asm/atomic.h>
+-#include <asm/scatterlist.h>
++#include <linux/scatterlist.h>
+ #include <asm/page.h>
+ 
+ #include "dm.h"
+@@ -164,9 +164,7 @@ static int crypt_iv_essiv_ctr(struct cry
+ 		return -ENOMEM;
+ 	}
+ 
+-	sg.page = virt_to_page(cc->key);
+-	sg.offset = offset_in_page(cc->key);
+-	sg.length = cc->key_size;
++	sg_set_buf(&sg, cc->key, cc->key_size);
+ 	crypto_digest_digest(hash_tfm, &sg, 1, salt);
+ 	crypto_free_tfm(hash_tfm);
+ 
+@@ -207,14 +205,12 @@ static void crypt_iv_essiv_dtr(struct cr
+ 
+ static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
+ {
+-	struct scatterlist sg = { NULL, };
++	struct scatterlist sg;
+ 
+ 	memset(iv, 0, cc->iv_size);
+ 	*(u64 *)iv = cpu_to_le64(sector);
+ 
+-	sg.page = virt_to_page(iv);
+-	sg.offset = offset_in_page(iv);
+-	sg.length = cc->iv_size;
++	sg_set_buf(&sg, iv, cc->iv_size);
+ 	crypto_cipher_encrypt((struct crypto_tfm *)cc->iv_gen_private,
+ 	                      &sg, &sg, cc->iv_size);
+ 
+@@ -331,7 +327,7 @@ crypt_alloc_buffer(struct crypt_config *
+ {
+ 	struct bio *bio;
+ 	unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+-	int gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
++	gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
+ 	unsigned int i;
+ 
+ 	/*
+diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
+--- a/drivers/media/common/ir-common.c
++++ b/drivers/media/common/ir-common.c
+@@ -22,6 +22,7 @@
+ 
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
++#include <linux/string.h>
+ #include <media/ir-common.h>
+ 
+ /* -------------------------------------------------------------------------- */
+@@ -252,7 +253,6 @@ void ir_input_init(struct input_dev *dev
+ 	if (ir_codes)
+ 		memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
+ 
+-        init_input_dev(dev);
+ 	dev->keycode     = ir->ir_codes;
+ 	dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
+ 	dev->keycodemax  = IR_KEYTAB_SIZE;
+diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
+--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
++++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
+@@ -137,7 +137,8 @@ struct cinergyt2 {
+ 	struct urb *stream_urb [STREAM_URB_COUNT];
+ 
+ #ifdef ENABLE_RC
+-	struct input_dev rc_input_dev;
++	struct input_dev *rc_input_dev;
++	char phys[64];
+ 	struct work_struct rc_query_work;
+ 	int rc_input_event;
+ 	u32 rc_last_code;
+@@ -683,6 +684,7 @@ static struct dvb_device cinergyt2_fe_te
+ };
+ 
+ #ifdef ENABLE_RC
++
+ static void cinergyt2_query_rc (void *data)
+ {
+ 	struct cinergyt2 *cinergyt2 = data;
+@@ -703,7 +705,7 @@ static void cinergyt2_query_rc (void *da
+ 			/* stop key repeat */
+ 			if (cinergyt2->rc_input_event != KEY_MAX) {
+ 				dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
+-				input_report_key(&cinergyt2->rc_input_dev,
++				input_report_key(cinergyt2->rc_input_dev,
+ 						 cinergyt2->rc_input_event, 0);
+ 				cinergyt2->rc_input_event = KEY_MAX;
+ 			}
+@@ -722,7 +724,7 @@ static void cinergyt2_query_rc (void *da
+ 			/* keyrepeat bit -> just repeat last rc_input_event */
+ 		} else {
+ 			cinergyt2->rc_input_event = KEY_MAX;
+-			for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) {
++			for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) {
+ 				if (rc_keys[i + 0] == rc_events[n].type &&
+ 				    rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) {
+ 					cinergyt2->rc_input_event = rc_keys[i + 2];
+@@ -736,11 +738,11 @@ static void cinergyt2_query_rc (void *da
+ 			    cinergyt2->rc_last_code != ~0) {
+ 				/* emit a key-up so the double event is recognized */
+ 				dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event);
+-				input_report_key(&cinergyt2->rc_input_dev,
++				input_report_key(cinergyt2->rc_input_dev,
+ 						 cinergyt2->rc_input_event, 0);
+ 			}
+ 			dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
+-			input_report_key(&cinergyt2->rc_input_dev,
++			input_report_key(cinergyt2->rc_input_dev,
+ 					 cinergyt2->rc_input_event, 1);
+ 			cinergyt2->rc_last_code = rc_events[n].value;
+ 		}
+@@ -752,7 +754,59 @@ out:
+ 
+ 	up(&cinergyt2->sem);
+ }
+-#endif
++
++static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
++{
++	struct input_dev *input_dev;
++	int i;
++
++	cinergyt2->rc_input_dev = input_dev = input_allocate_device();
++	if (!input_dev)
++		return -ENOMEM;
++
++	usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys));
++	strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys));
++	cinergyt2->rc_input_event = KEY_MAX;
++	cinergyt2->rc_last_code = ~0;
++	INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
++
++	input_dev->name = DRIVER_NAME " remote control";
++	input_dev->phys = cinergyt2->phys;
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++	for (i = 0; ARRAY_SIZE(rc_keys); i += 3)
++		set_bit(rc_keys[i + 2], input_dev->keybit);
++	input_dev->keycodesize = 0;
++	input_dev->keycodemax = 0;
++
++	input_register_device(cinergyt2->rc_input_dev);
++	schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
++}
++
++static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2)
++{
++	cancel_delayed_work(&cinergyt2->rc_query_work);
++	flush_scheduled_work();
++	input_unregister_device(cinergyt2->rc_input_dev);
++}
++
++static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2)
++{
++	cancel_delayed_work(&cinergyt2->rc_query_work);
++}
++
++static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2)
++{
++	schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
++}
++
++#else
++
++static inline int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { return 0; }
++static inline void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { }
++static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { }
++static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { }
++
++#endif /* ENABLE_RC */
+ 
+ static void cinergyt2_query (void *data)
+ {
+@@ -789,9 +843,6 @@ static int cinergyt2_probe (struct usb_i
+ {
+ 	struct cinergyt2 *cinergyt2;
+ 	int err;
+-#ifdef ENABLE_RC
+-	int i;
+-#endif
+ 
+ 	if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
+ 		dprintk(1, "out of memory?!?\n");
+@@ -846,30 +897,17 @@ static int cinergyt2_probe (struct usb_i
+ 			    &cinergyt2_fe_template, cinergyt2,
+ 			    DVB_DEVICE_FRONTEND);
+ 
+-#ifdef ENABLE_RC
+-	cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+-	cinergyt2->rc_input_dev.keycodesize = 0;
+-	cinergyt2->rc_input_dev.keycodemax = 0;
+-	cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
+-
+-	for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3)
+-		set_bit(rc_keys[i + 2], cinergyt2->rc_input_dev.keybit);
+-
+-	input_register_device(&cinergyt2->rc_input_dev);
+-
+-	cinergyt2->rc_input_event = KEY_MAX;
+-	cinergyt2->rc_last_code = ~0;
++	err = cinergyt2_register_rc(cinergyt2);
++	if (err)
++		goto bailout;
+ 
+-	INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
+-	schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
+-#endif
+ 	return 0;
+ 
+ bailout:
+ 	dvb_dmxdev_release(&cinergyt2->dmxdev);
+ 	dvb_dmx_release(&cinergyt2->demux);
+-	dvb_unregister_adapter (&cinergyt2->adapter);
+-	cinergyt2_free_stream_urbs (cinergyt2);
++	dvb_unregister_adapter(&cinergyt2->adapter);
++	cinergyt2_free_stream_urbs(cinergyt2);
+ 	kfree(cinergyt2);
+ 	return -ENOMEM;
+ }
+@@ -881,11 +919,7 @@ static void cinergyt2_disconnect (struct
+ 	if (down_interruptible(&cinergyt2->sem))
+ 		return;
+ 
+-#ifdef ENABLE_RC
+-	cancel_delayed_work(&cinergyt2->rc_query_work);
+-	flush_scheduled_work();
+-	input_unregister_device(&cinergyt2->rc_input_dev);
+-#endif
++	cinergyt2_unregister_rc(cinergyt2);
+ 
+ 	cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
+ 	dvb_net_release(&cinergyt2->dvbnet);
+@@ -908,9 +942,8 @@ static int cinergyt2_suspend (struct usb
+ 
+ 	if (state.event > PM_EVENT_ON) {
+ 		struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
+-#ifdef ENABLE_RC
+-		cancel_delayed_work(&cinergyt2->rc_query_work);
+-#endif
++
++		cinergyt2_suspend_rc(cinergyt2);
+ 		cancel_delayed_work(&cinergyt2->query_work);
+ 		if (cinergyt2->streaming)
+ 			cinergyt2_stop_stream_xfer(cinergyt2);
+@@ -938,9 +971,8 @@ static int cinergyt2_resume (struct usb_
+ 		schedule_delayed_work(&cinergyt2->query_work, HZ/2);
+ 	}
+ 
+-#ifdef ENABLE_RC
+-	schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
+-#endif
++	cinergyt2_resume_rc(cinergyt2);
++
+ 	up(&cinergyt2->sem);
+ 	return 0;
+ }
+diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
++++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+@@ -36,6 +36,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/delay.h>
+ #include <linux/rwsem.h>
++#include <linux/sched.h>
+ 
+ #include "dvb_ca_en50221.h"
+ #include "dvb_ringbuffer.h"
+diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
+--- a/drivers/media/dvb/dvb-core/dvbdev.c
++++ b/drivers/media/dvb/dvb-core/dvbdev.c
+@@ -235,7 +235,7 @@ int dvb_register_device(struct dvb_adapt
+ 			S_IFCHR | S_IRUSR | S_IWUSR,
+ 			"dvb/adapter%d/%s%d", adap->num, dnames[type], id);
+ 
+-	class_device_create(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
++	class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
+ 			    NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
+ 
+ 	dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
+diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
+--- a/drivers/media/dvb/dvb-usb/dtt200u.c
++++ b/drivers/media/dvb/dvb-usb/dtt200u.c
+@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u
+ 		  .cold_ids = { &dtt200u_usb_table[0], NULL },
+ 		  .warm_ids = { &dtt200u_usb_table[1], NULL },
+ 		},
+-		{ 0 },
++		{ NULL },
+ 	}
+ };
+ 
+@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_
+ 		  .cold_ids = { &dtt200u_usb_table[2], NULL },
+ 		  .warm_ids = { &dtt200u_usb_table[3], NULL },
+ 		},
+-		{ 0 },
++		{ NULL },
+ 	}
+ };
+ 
+diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
++++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+@@ -39,9 +39,9 @@ static void dvb_usb_read_remote_control(
+ 			d->last_event = event;
+ 		case REMOTE_KEY_REPEAT:
+ 			deb_rc("key repeated\n");
+-			input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1);
+-			input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
+-			input_sync(&d->rc_input_dev);
++			input_event(d->rc_input_dev, EV_KEY, event, 1);
++			input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
++			input_sync(d->rc_input_dev);
+ 			break;
+ 		default:
+ 			break;
+@@ -53,8 +53,8 @@ static void dvb_usb_read_remote_control(
+ 			deb_rc("NO KEY PRESSED\n");
+ 			if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+ 				deb_rc("releasing event %d\n",d->last_event);
+-				input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
+-				input_sync(&d->rc_input_dev);
++				input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
++				input_sync(d->rc_input_dev);
+ 			}
+ 			d->last_state = REMOTE_NO_KEY_PRESSED;
+ 			d->last_event = 0;
+@@ -63,8 +63,8 @@ static void dvb_usb_read_remote_control(
+ 			deb_rc("KEY PRESSED\n");
+ 			deb_rc("pressing event %d\n",event);
+ 
+-			input_event(&d->rc_input_dev, EV_KEY, event, 1);
+-			input_sync(&d->rc_input_dev);
++			input_event(d->rc_input_dev, EV_KEY, event, 1);
++			input_sync(d->rc_input_dev);
+ 
+ 			d->last_event = event;
+ 			d->last_state = REMOTE_KEY_PRESSED;
+@@ -73,8 +73,8 @@ static void dvb_usb_read_remote_control(
+ 			deb_rc("KEY_REPEAT\n");
+ 			if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+ 				deb_rc("repeating event %d\n",d->last_event);
+-				input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2);
+-				input_sync(&d->rc_input_dev);
++				input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
++				input_sync(d->rc_input_dev);
+ 				d->last_state = REMOTE_KEY_REPEAT;
+ 			}
+ 		default:
+@@ -89,24 +89,30 @@ schedule:
+ int dvb_usb_remote_init(struct dvb_usb_device *d)
+ {
+ 	int i;
++
+ 	if (d->props.rc_key_map == NULL ||
+ 		d->props.rc_query == NULL ||
+ 		dvb_usb_disable_rc_polling)
+ 		return 0;
+ 
+-	/* Initialise the remote-control structures.*/
+-	init_input_dev(&d->rc_input_dev);
++	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
++	strlcpy(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+ 
+-	d->rc_input_dev.evbit[0] = BIT(EV_KEY);
+-	d->rc_input_dev.keycodesize = sizeof(unsigned char);
+-	d->rc_input_dev.keycodemax = KEY_MAX;
+-	d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver";
++	d->rc_input_dev = input_allocate_device();
++	if (!d->rc_input_dev)
++		return -ENOMEM;
++
++	d->rc_input_dev->evbit[0] = BIT(EV_KEY);
++	d->rc_input_dev->keycodesize = sizeof(unsigned char);
++	d->rc_input_dev->keycodemax = KEY_MAX;
++	d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver";
++	d->rc_input_dev->phys = d->rc_phys;
+ 
+ 	/* set the bits for the keys */
+-	deb_rc("key map size: %d\n",d->props.rc_key_map_size);
++	deb_rc("key map size: %d\n", d->props.rc_key_map_size);
+ 	for (i = 0; i < d->props.rc_key_map_size; i++) {
+ 		deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
+-		set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit);
++		set_bit(d->props.rc_key_map[i].event, d->rc_input_dev->keybit);
+ 	}
+ 
+ 	/* Start the remote-control polling. */
+@@ -114,14 +120,14 @@ int dvb_usb_remote_init(struct dvb_usb_d
+ 		d->props.rc_interval = 100; /* default */
+ 
+ 	/* setting these two values to non-zero, we have to manage key repeats */
+-	d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval;
+-	d->rc_input_dev.rep[REP_DELAY]  = d->props.rc_interval + 150;
++	d->rc_input_dev->rep[REP_PERIOD] = d->props.rc_interval;
++	d->rc_input_dev->rep[REP_DELAY]  = d->props.rc_interval + 150;
+ 
+-	input_register_device(&d->rc_input_dev);
++	input_register_device(d->rc_input_dev);
+ 
+ 	INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
+ 
+-	info("schedule remote query interval to %d msecs.",d->props.rc_interval);
++	info("schedule remote query interval to %d msecs.", d->props.rc_interval);
+ 	schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
+ 
+ 	d->state |= DVB_USB_STATE_REMOTE;
+@@ -134,7 +140,7 @@ int dvb_usb_remote_exit(struct dvb_usb_d
+ 	if (d->state & DVB_USB_STATE_REMOTE) {
+ 		cancel_delayed_work(&d->rc_query_work);
+ 		flush_scheduled_work();
+-		input_unregister_device(&d->rc_input_dev);
++		input_unregister_device(d->rc_input_dev);
+ 	}
+ 	d->state &= ~DVB_USB_STATE_REMOTE;
+ 	return 0;
+diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
+--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
++++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
+@@ -300,7 +300,8 @@ struct dvb_usb_device {
+ 	int (*fe_init)  (struct dvb_frontend *);
+ 
+ 	/* remote control */
+-	struct input_dev rc_input_dev;
++	struct input_dev *rc_input_dev;
++	char rc_phys[64];
+ 	struct work_struct rc_query_work;
+ 	u32 last_event;
+ 	int last_state;
+diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
+--- a/drivers/media/dvb/dvb-usb/vp7045.c
++++ b/drivers/media/dvb/dvb-usb/vp7045.c
+@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_
+ 		  .cold_ids = { &vp7045_usb_table[2], NULL },
+ 		  .warm_ids = { &vp7045_usb_table[3], NULL },
+ 		},
+-		{ 0 },
++		{ NULL },
+ 	}
+ };
+ 
+diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
+--- a/drivers/media/dvb/frontends/bcm3510.c
++++ b/drivers/media/dvb/frontends/bcm3510.c
+@@ -36,6 +36,9 @@
+ #include <linux/moduleparam.h>
+ #include <linux/device.h>
+ #include <linux/firmware.h>
++#include <linux/jiffies.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "dvb_frontend.h"
+ #include "bcm3510.h"
+diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
+--- a/drivers/media/dvb/frontends/dib3000mb.c
++++ b/drivers/media/dvb/frontends/dib3000mb.c
+@@ -27,6 +27,8 @@
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "dib3000-common.h"
+ #include "dib3000mb_priv.h"
+diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
+--- a/drivers/media/dvb/frontends/dib3000mc.c
++++ b/drivers/media/dvb/frontends/dib3000mc.c
+@@ -26,6 +26,8 @@
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "dib3000-common.h"
+ #include "dib3000mc_priv.h"
+diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
+--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
++++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
+@@ -22,6 +22,8 @@
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "dvb_frontend.h"
+ #include "dvb_dummy_fe.h"
+diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
+--- a/drivers/media/dvb/frontends/lgdt330x.c
++++ b/drivers/media/dvb/frontends/lgdt330x.c
+@@ -37,6 +37,8 @@
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include <asm/byteorder.h>
+ 
+ #include "dvb_frontend.h"
+diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
+--- a/drivers/media/dvb/frontends/mt312.c
++++ b/drivers/media/dvb/frontends/mt312.c
+@@ -29,6 +29,8 @@
+ #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 "mt312_priv.h"
+diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
+--- a/drivers/media/dvb/frontends/mt352.c
++++ b/drivers/media/dvb/frontends/mt352.c
+@@ -35,6 +35,8 @@
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "dvb_frontend.h"
+ #include "mt352_priv.h"
+diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
+--- a/drivers/media/dvb/frontends/nxt2002.c
++++ b/drivers/media/dvb/frontends/nxt2002.c
+@@ -32,6 +32,8 @@
+ #include <linux/moduleparam.h>
+ #include <linux/device.h>
+ #include <linux/firmware.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "dvb_frontend.h"
+ #include "nxt2002.h"
+diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
+--- a/drivers/media/dvb/frontends/or51132.c
++++ b/drivers/media/dvb/frontends/or51132.c
+@@ -36,6 +36,8 @@
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include <asm/byteorder.h>
+ 
+ #include "dvb_frontend.h"
+diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
+--- a/drivers/media/dvb/frontends/or51211.c
++++ b/drivers/media/dvb/frontends/or51211.c
+@@ -34,6 +34,8 @@
+ #include <linux/moduleparam.h>
+ #include <linux/device.h>
+ #include <linux/firmware.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include <asm/byteorder.h>
+ 
+ #include "dvb_frontend.h"
+diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
+--- a/drivers/media/dvb/frontends/s5h1420.c
++++ b/drivers/media/dvb/frontends/s5h1420.c
+@@ -26,6 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridg
+ #include <linux/string.h>
+ #include <linux/slab.h>
+ #include <linux/delay.h>
++#include <linux/jiffies.h>
++#include <asm/div64.h>
+ 
+ #include "dvb_frontend.h"
+ #include "s5h1420.h"
+diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
+--- a/drivers/media/dvb/frontends/sp8870.c
++++ b/drivers/media/dvb/frontends/sp8870.c
+@@ -32,6 +32,8 @@
+ #include <linux/device.h>
+ #include <linux/firmware.h>
+ #include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "dvb_frontend.h"
+ #include "sp8870.h"
+diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
+--- a/drivers/media/dvb/frontends/sp887x.c
++++ b/drivers/media/dvb/frontends/sp887x.c
+@@ -14,6 +14,8 @@
+ #include <linux/moduleparam.h>
+ #include <linux/device.h>
+ #include <linux/firmware.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #include "dvb_frontend.h"
+ #include "sp887x.h"
+diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
+--- a/drivers/media/dvb/frontends/stv0297.c
++++ b/drivers/media/dvb/frontends/stv0297.c
+@@ -24,6 +24,8 @@
+ #include <linux/module.h>
+ #include <linux/string.h>
+ #include <linux/delay.h>
++#include <linux/jiffies.h>
++#include <linux/slab.h>
+ 
+ #include "dvb_frontend.h"
+ #include "stv0297.h"
+diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
+--- a/drivers/media/dvb/frontends/stv0299.c
++++ b/drivers/media/dvb/frontends/stv0299.c
+@@ -48,6 +48,7 @@
+ #include <linux/moduleparam.h>
+ #include <linux/string.h>
+ #include <linux/slab.h>
++#include <linux/jiffies.h>
+ #include <asm/div64.h>
+ 
+ #include "dvb_frontend.h"
+diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
+--- a/drivers/media/dvb/frontends/tda1004x.c
++++ b/drivers/media/dvb/frontends/tda1004x.c
+@@ -32,6 +32,10 @@
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/device.h>
++#include <linux/jiffies.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++
+ #include "dvb_frontend.h"
+ #include "tda1004x.h"
+ 
+diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
+--- a/drivers/media/dvb/frontends/tda8083.c
++++ b/drivers/media/dvb/frontends/tda8083.c
+@@ -30,6 +30,7 @@
+ #include <linux/moduleparam.h>
+ #include <linux/string.h>
+ #include <linux/slab.h>
++#include <linux/jiffies.h>
+ #include "dvb_frontend.h"
+ #include "tda8083.h"
+ 
+diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
+--- a/drivers/media/dvb/ttpci/av7110_ir.c
++++ b/drivers/media/dvb/ttpci/av7110_ir.c
+@@ -15,7 +15,7 @@
+ 
+ static int av_cnt;
+ static struct av7110 *av_list[4];
+-static struct input_dev input_dev;
++static struct input_dev *input_dev;
+ 
+ static u16 key_map [256] = {
+ 	KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
+@@ -43,10 +43,10 @@ static u16 key_map [256] = {
+ 
+ static void av7110_emit_keyup(unsigned long data)
+ {
+-	if (!data || !test_bit(data, input_dev.key))
++	if (!data || !test_bit(data, input_dev->key))
+ 		return;
+ 
+-	input_event(&input_dev, EV_KEY, data, !!0);
++	input_event(input_dev, EV_KEY, data, !!0);
+ }
+ 
+ 
+@@ -112,13 +112,13 @@ static void av7110_emit_key(unsigned lon
+ 	if (timer_pending(&keyup_timer)) {
+ 		del_timer(&keyup_timer);
+ 		if (keyup_timer.data != keycode || new_toggle != old_toggle) {
+-			input_event(&input_dev, EV_KEY, keyup_timer.data, !!0);
+-			input_event(&input_dev, EV_KEY, keycode, !0);
++			input_event(input_dev, EV_KEY, keyup_timer.data, !!0);
++			input_event(input_dev, EV_KEY, keycode, !0);
+ 		} else
+-			input_event(&input_dev, EV_KEY, keycode, 2);
++			input_event(input_dev, EV_KEY, keycode, 2);
+ 
+ 	} else
+-		input_event(&input_dev, EV_KEY, keycode, !0);
++		input_event(input_dev, EV_KEY, keycode, !0);
+ 
+ 	keyup_timer.expires = jiffies + UP_TIMEOUT;
+ 	keyup_timer.data = keycode;
+@@ -132,13 +132,13 @@ static void input_register_keys(void)
+ {
+ 	int i;
+ 
+-	memset(input_dev.keybit, 0, sizeof(input_dev.keybit));
++	memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
+ 
+-	for (i = 0; i < sizeof(key_map) / sizeof(key_map[0]); i++) {
++	for (i = 0; i < ARRAY_SIZE(key_map); i++) {
+ 		if (key_map[i] > KEY_MAX)
+ 			key_map[i] = 0;
+ 		else if (key_map[i] > KEY_RESERVED)
+-			set_bit(key_map[i], input_dev.keybit);
++			set_bit(key_map[i], input_dev->keybit);
+ 	}
+ }
+ 
+@@ -216,12 +216,17 @@ int __init av7110_ir_init(struct av7110 
+ 		init_timer(&keyup_timer);
+ 		keyup_timer.data = 0;
+ 
+-		input_dev.name = "DVB on-card IR receiver";
+-		set_bit(EV_KEY, input_dev.evbit);
+-		set_bit(EV_REP, input_dev.evbit);
++		input_dev = input_allocate_device();
++		if (!input_dev)
++			return -ENOMEM;
++
++		input_dev->name = "DVB on-card IR receiver";
++
++		set_bit(EV_KEY, input_dev->evbit);
++		set_bit(EV_REP, input_dev->evbit);
+ 		input_register_keys();
+-		input_register_device(&input_dev);
+-		input_dev.timer.function = input_repeat_key;
++		input_register_device(input_dev);
++		input_dev->timer.function = input_repeat_key;
+ 
+ 		e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
+ 		if (e) {
+@@ -256,7 +261,7 @@ void __exit av7110_ir_exit(struct av7110
+ 	if (av_cnt == 1) {
+ 		del_timer_sync(&keyup_timer);
+ 		remove_proc_entry("av7110_ir", NULL);
+-		input_unregister_device(&input_dev);
++		input_unregister_device(input_dev);
+ 	}
+ 
+ 	av_cnt--;
+diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
+--- a/drivers/media/dvb/ttpci/budget-ci.c
++++ b/drivers/media/dvb/ttpci/budget-ci.c
+@@ -64,7 +64,7 @@
+ 
+ struct budget_ci {
+ 	struct budget budget;
+-	struct input_dev input_dev;
++	struct input_dev *input_dev;
+ 	struct tasklet_struct msp430_irq_tasklet;
+ 	struct tasklet_struct ciintf_irq_tasklet;
+ 	int slot_status;
+@@ -145,7 +145,7 @@ static void msp430_ir_debounce(unsigned 
+ static void msp430_ir_interrupt(unsigned long data)
+ {
+ 	struct budget_ci *budget_ci = (struct budget_ci *) data;
+-	struct input_dev *dev = &budget_ci->input_dev;
++	struct input_dev *dev = budget_ci->input_dev;
+ 	unsigned int code =
+ 		ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
+ 
+@@ -181,25 +181,27 @@ static void msp430_ir_interrupt(unsigned
+ static int msp430_ir_init(struct budget_ci *budget_ci)
+ {
+ 	struct saa7146_dev *saa = budget_ci->budget.dev;
++	struct input_dev *input_dev;
+ 	int i;
+ 
+-	memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
++	budget_ci->input_dev = input_dev = input_allocate_device();
++	if (!input_dev)
++		return -ENOMEM;
+ 
+ 	sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
+-	budget_ci->input_dev.name = budget_ci->ir_dev_name;
+ 
+-	set_bit(EV_KEY, budget_ci->input_dev.evbit);
++	input_dev->name = budget_ci->ir_dev_name;
+ 
+-	for (i = 0; i < sizeof(key_map) / sizeof(*key_map); i++)
++	set_bit(EV_KEY, input_dev->evbit);
++	for (i = 0; i < ARRAY_SIZE(key_map); i++)
+ 		if (key_map[i])
+-			set_bit(key_map[i], budget_ci->input_dev.keybit);
++			set_bit(key_map[i], input_dev->keybit);
+ 
+-	input_register_device(&budget_ci->input_dev);
++	input_register_device(budget_ci->input_dev);
+ 
+-	budget_ci->input_dev.timer.function = msp430_ir_debounce;
++	input_dev->timer.function = msp430_ir_debounce;
+ 
+ 	saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
+-
+ 	saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
+ 
+ 	return 0;
+@@ -208,7 +210,7 @@ static int msp430_ir_init(struct budget_
+ static void msp430_ir_deinit(struct budget_ci *budget_ci)
+ {
+ 	struct saa7146_dev *saa = budget_ci->budget.dev;
+-	struct input_dev *dev = &budget_ci->input_dev;
++	struct input_dev *dev = budget_ci->input_dev;
+ 
+ 	saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
+ 	saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
+diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
++++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+@@ -152,7 +152,8 @@ struct ttusb_dec {
+ 	struct list_head	filter_info_list;
+ 	spinlock_t		filter_info_list_lock;
+ 
+-	struct input_dev	rc_input_dev;
++	struct input_dev	*rc_input_dev;
++	char			rc_phys[64];
+ 
+ 	int			active; /* Loaded successfully */
+ };
+@@ -235,9 +236,9 @@ static void ttusb_dec_handle_irq( struct
+ 		 * this should/could be added later ...
+ 		 * for now lets report each signal as a key down and up*/
+ 		dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]);
+-		input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],1);
+-		input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],0);
+-		input_sync(&dec->rc_input_dev);
++		input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
++		input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
++		input_sync(dec->rc_input_dev);
+ 	}
+ 
+ exit:	retval = usb_submit_urb(urb, GFP_ATOMIC);
+@@ -1181,29 +1182,38 @@ static void ttusb_dec_init_tasklet(struc
+ 		     (unsigned long)dec);
+ }
+ 
+-static void ttusb_init_rc( struct ttusb_dec *dec)
++static int ttusb_init_rc(struct ttusb_dec *dec)
+ {
++	struct input_dev *input_dev;
+ 	u8 b[] = { 0x00, 0x01 };
+ 	int i;
+ 
+-	init_input_dev(&dec->rc_input_dev);
++	usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
++	strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
+ 
+-	dec->rc_input_dev.name = "ttusb_dec remote control";
+-	dec->rc_input_dev.evbit[0] = BIT(EV_KEY);
+-	dec->rc_input_dev.keycodesize = sizeof(u16);
+-	dec->rc_input_dev.keycodemax = 0x1a;
+-	dec->rc_input_dev.keycode = rc_keys;
++	dec->rc_input_dev = input_dev = input_allocate_device();
++	if (!input_dev)
++		return -ENOMEM;
++
++	input_dev->name = "ttusb_dec remote control";
++	input_dev->phys = dec->rc_phys;
++	input_dev->evbit[0] = BIT(EV_KEY);
++	input_dev->keycodesize = sizeof(u16);
++	input_dev->keycodemax = 0x1a;
++	input_dev->keycode = rc_keys;
+ 
+-	 for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
+-                set_bit(rc_keys[i], dec->rc_input_dev.keybit);
++	for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
++                set_bit(rc_keys[i], input_dev->keybit);
+ 
+-	input_register_device(&dec->rc_input_dev);
++	input_register_device(input_dev);
+ 
+-	if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) {
++	if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
+ 		printk("%s: usb_submit_urb failed\n",__FUNCTION__);
+-	}
++
+ 	/* enable irq pipe */
+ 	ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
++
++	return 0;
+ }
+ 
+ static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
+@@ -1513,7 +1523,7 @@ static void ttusb_dec_exit_rc(struct ttu
+ 	  * As the irq is submitted after the interface is changed,
+ 	  * this is the best method i figured out.
+ 	  * Any others?*/
+-	if(dec->interface == TTUSB_DEC_INTERFACE_IN)
++	if (dec->interface == TTUSB_DEC_INTERFACE_IN)
+ 		usb_kill_urb(dec->irq_urb);
+ 
+ 	usb_free_urb(dec->irq_urb);
+@@ -1521,7 +1531,10 @@ static void ttusb_dec_exit_rc(struct ttu
+ 	usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
+ 		           dec->irq_buffer, dec->irq_dma_handle);
+ 
+-	input_unregister_device(&dec->rc_input_dev);
++	if (dec->rc_input_dev) {
++		input_unregister_device(dec->rc_input_dev);
++		dec->rc_input_dev = NULL;
++	}
+ }
+ 
+ 
+@@ -1659,7 +1672,7 @@ static int ttusb_dec_probe(struct usb_in
+ 
+ 	ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
+ 
+-	if(enable_rc)
++	if (enable_rc)
+ 		ttusb_init_rc(dec);
+ 
+ 	return 0;
+diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
+--- a/drivers/media/radio/miropcm20-rds.c
++++ b/drivers/media/radio/miropcm20-rds.c
+@@ -14,6 +14,7 @@
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+ #include <linux/miscdevice.h>
++#include <linux/sched.h>	/* current, TASK_*, schedule_timeout() */
+ #include <linux/delay.h>
+ #include <asm/uaccess.h>
+ #include "miropcm20-rds-core.h"
+diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
+--- a/drivers/media/video/bttvp.h
++++ b/drivers/media/video/bttvp.h
+@@ -240,7 +240,7 @@ struct bttv_pll_info {
+ 
+ /* for gpio-connected remote control */
+ struct bttv_input {
+-	struct input_dev      dev;
++	struct input_dev      *dev;
+ 	struct ir_input_state ir;
+ 	char                  name[32];
+ 	char                  phys[32];
+diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
+--- a/drivers/media/video/cx88/cx88-input.c
++++ b/drivers/media/video/cx88/cx88-input.c
+@@ -260,7 +260,7 @@ static IR_KEYTAB_TYPE ir_codes_cinergy_1
+ 
+ struct cx88_IR {
+ 	struct cx88_core *core;
+-	struct input_dev input;
++	struct input_dev *input;
+ 	struct ir_input_state ir;
+ 	char name[32];
+ 	char phys[32];
+@@ -315,23 +315,23 @@ static void cx88_ir_handle_key(struct cx
+ 	if (ir->mask_keydown) {
+ 		/* bit set on keydown */
+ 		if (gpio & ir->mask_keydown) {
+-			ir_input_keydown(&ir->input, &ir->ir, data, data);
++			ir_input_keydown(ir->input, &ir->ir, data, data);
+ 		} else {
+-			ir_input_nokey(&ir->input, &ir->ir);
++			ir_input_nokey(ir->input, &ir->ir);
+ 		}
+ 
+ 	} else if (ir->mask_keyup) {
+ 		/* bit cleared on keydown */
+ 		if (0 == (gpio & ir->mask_keyup)) {
+-			ir_input_keydown(&ir->input, &ir->ir, data, data);
++			ir_input_keydown(ir->input, &ir->ir, data, data);
+ 		} else {
+-			ir_input_nokey(&ir->input, &ir->ir);
++			ir_input_nokey(ir->input, &ir->ir);
+ 		}
+ 
+ 	} else {
+ 		/* can't distinguish keydown/up :-/ */
+-		ir_input_keydown(&ir->input, &ir->ir, data, data);
+-		ir_input_nokey(&ir->input, &ir->ir);
++		ir_input_keydown(ir->input, &ir->ir, data, data);
++		ir_input_nokey(ir->input, &ir->ir);
+ 	}
+ }
+ 
+@@ -357,13 +357,19 @@ static void cx88_ir_work(void *data)
+ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
+ {
+ 	struct cx88_IR *ir;
++	struct input_dev *input_dev;
+ 	IR_KEYTAB_TYPE *ir_codes = NULL;
+ 	int ir_type = IR_TYPE_OTHER;
+ 
+-	ir = kmalloc(sizeof(*ir), GFP_KERNEL);
+-	if (NULL == ir)
++	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!ir || !input_dev) {
++		kfree(ir);
++		input_free_device(input_dev);
+ 		return -ENOMEM;
+-	memset(ir, 0, sizeof(*ir));
++	}
++
++	ir->input = input_dev;
+ 
+ 	/* detect & configure */
+ 	switch (core->board) {
+@@ -425,6 +431,7 @@ int cx88_ir_init(struct cx88_core *core,
+ 
+ 	if (NULL == ir_codes) {
+ 		kfree(ir);
++		input_free_device(input_dev);
+ 		return -ENODEV;
+ 	}
+ 
+@@ -433,19 +440,19 @@ int cx88_ir_init(struct cx88_core *core,
+ 		 cx88_boards[core->board].name);
+ 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
+ 
+-	ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
+-	ir->input.name = ir->name;
+-	ir->input.phys = ir->phys;
+-	ir->input.id.bustype = BUS_PCI;
+-	ir->input.id.version = 1;
++	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
++	input_dev->name = ir->name;
++	input_dev->phys = ir->phys;
++	input_dev->id.bustype = BUS_PCI;
++	input_dev->id.version = 1;
+ 	if (pci->subsystem_vendor) {
+-		ir->input.id.vendor = pci->subsystem_vendor;
+-		ir->input.id.product = pci->subsystem_device;
++		input_dev->id.vendor = pci->subsystem_vendor;
++		input_dev->id.product = pci->subsystem_device;
+ 	} else {
+-		ir->input.id.vendor = pci->vendor;
+-		ir->input.id.product = pci->device;
++		input_dev->id.vendor = pci->vendor;
++		input_dev->id.product = pci->device;
+ 	}
+-	ir->input.dev = &pci->dev;
++	input_dev->cdev.dev = &pci->dev;
+ 
+ 	/* record handles to ourself */
+ 	ir->core = core;
+@@ -465,8 +472,7 @@ int cx88_ir_init(struct cx88_core *core,
+ 	}
+ 
+ 	/* all done */
+-	input_register_device(&ir->input);
+-	printk("%s: registered IR remote control\n", core->name);
++	input_register_device(ir->input);
+ 
+ 	return 0;
+ }
+@@ -484,7 +490,7 @@ int cx88_ir_fini(struct cx88_core *core)
+ 		flush_scheduled_work();
+ 	}
+ 
+-	input_unregister_device(&ir->input);
++	input_unregister_device(ir->input);
+ 	kfree(ir);
+ 
+ 	/* done */
+@@ -515,7 +521,7 @@ void cx88_ir_irq(struct cx88_core *core)
+ 	if (!ir->scount) {
+ 		/* nothing to sample */
+ 		if (ir->ir.keypressed && time_after(jiffies, ir->release))
+-			ir_input_nokey(&ir->input, &ir->ir);
++			ir_input_nokey(ir->input, &ir->ir);
+ 		return;
+ 	}
+ 
+@@ -557,7 +563,7 @@ void cx88_ir_irq(struct cx88_core *core)
+ 
+ 		ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
+ 
+-		ir_input_keydown(&ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
++		ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
+ 		ir->release = jiffies + msecs_to_jiffies(120);
+ 		break;
+ 	case CX88_BOARD_HAUPPAUGE:
+@@ -566,7 +572,7 @@ void cx88_ir_irq(struct cx88_core *core)
+ 		ir_dprintk("biphase decoded: %x\n", ircode);
+ 		if ((ircode & 0xfffff000) != 0x3000)
+ 			break;
+-		ir_input_keydown(&ir->input, &ir->ir, ircode & 0x3f, ircode);
++		ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode);
+ 		ir->release = jiffies + msecs_to_jiffies(120);
+ 		break;
+ 	}
+diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
+--- a/drivers/media/video/indycam.c
++++ b/drivers/media/video/indycam.c
+@@ -9,16 +9,16 @@
+  *  published by the Free Software Foundation.
+  */
+ 
+-#include <linux/module.h>
+-#include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/fs.h>
++#include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/major.h>
+-#include <linux/slab.h>
++#include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/sched.h>
++#include <linux/slab.h>
+ 
+ #include <linux/videodev.h>
+ /* IndyCam decodes stream of photons into digital image representation ;-) */
+@@ -44,8 +44,6 @@ MODULE_LICENSE("GPL");
+ #define indycam_regdump(client)
+ #endif
+ 
+-#define VINO_ADAPTER	(I2C_ALGO_SGI | I2C_HW_SGI_VINO)
+-
+ struct indycam {
+ 	struct i2c_client *client;
+ 	int version;
+@@ -300,7 +298,7 @@ out_free_client:
+ static int indycam_probe(struct i2c_adapter *adap)
+ {
+ 	/* Indy specific crap */
+-	if (adap->id == VINO_ADAPTER)
++	if (adap->id == I2C_HW_SGI_VINO)
+ 		return indycam_attach(adap, INDYCAM_ADDR, 0);
+ 	/* Feel free to add probe here :-) */
+ 	return -ENODEV;
+diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
+--- a/drivers/media/video/ir-kbd-gpio.c
++++ b/drivers/media/video/ir-kbd-gpio.c
+@@ -158,7 +158,7 @@ static IR_KEYTAB_TYPE ir_codes_apac_view
+ 
+ struct IR {
+ 	struct bttv_sub_device  *sub;
+-	struct input_dev        input;
++	struct input_dev        *input;
+ 	struct ir_input_state   ir;
+ 	char                    name[32];
+ 	char                    phys[32];
+@@ -217,23 +217,23 @@ static void ir_handle_key(struct IR *ir)
+ 	if (ir->mask_keydown) {
+ 		/* bit set on keydown */
+ 		if (gpio & ir->mask_keydown) {
+-			ir_input_keydown(&ir->input,&ir->ir,data,data);
++			ir_input_keydown(ir->input, &ir->ir, data, data);
+ 		} else {
+-			ir_input_nokey(&ir->input,&ir->ir);
++			ir_input_nokey(ir->input, &ir->ir);
+ 		}
+ 
+ 	} else if (ir->mask_keyup) {
+ 		/* bit cleared on keydown */
+ 		if (0 == (gpio & ir->mask_keyup)) {
+-			ir_input_keydown(&ir->input,&ir->ir,data,data);
++			ir_input_keydown(ir->input, &ir->ir, data, data);
+ 		} else {
+-			ir_input_nokey(&ir->input,&ir->ir);
++			ir_input_nokey(ir->input, &ir->ir);
+ 		}
+ 
+ 	} else {
+ 		/* can't disturgissh keydown/up :-/ */
+-		ir_input_keydown(&ir->input,&ir->ir,data,data);
+-		ir_input_nokey(&ir->input,&ir->ir);
++		ir_input_keydown(ir->input, &ir->ir, data, data);
++		ir_input_nokey(ir->input, &ir->ir);
+ 	}
+ }
+ 
+@@ -268,13 +268,17 @@ static int ir_probe(struct device *dev)
+ {
+ 	struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
+ 	struct IR *ir;
++	struct input_dev *input_dev;
+ 	IR_KEYTAB_TYPE *ir_codes = NULL;
+ 	int ir_type = IR_TYPE_OTHER;
+ 
+-	ir = kmalloc(sizeof(*ir),GFP_KERNEL);
+-	if (NULL == ir)
++	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!ir || !input_dev) {
++		kfree(ir);
++		input_free_device(input_dev);
+ 		return -ENOMEM;
+-	memset(ir,0,sizeof(*ir));
++	}
+ 
+ 	/* detect & configure */
+ 	switch (sub->core->type) {
+@@ -328,6 +332,7 @@ static int ir_probe(struct device *dev)
+ 	}
+ 	if (NULL == ir_codes) {
+ 		kfree(ir);
++		input_free_device(input_dev);
+ 		return -ENODEV;
+ 	}
+ 
+@@ -341,19 +346,19 @@ static int ir_probe(struct device *dev)
+ 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
+ 		 pci_name(sub->core->pci));
+ 
+-	ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
+-	ir->input.name = ir->name;
+-	ir->input.phys = ir->phys;
+-	ir->input.id.bustype = BUS_PCI;
+-	ir->input.id.version = 1;
++	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
++	input_dev->name = ir->name;
++	input_dev->phys = ir->phys;
++	input_dev->id.bustype = BUS_PCI;
++	input_dev->id.version = 1;
+ 	if (sub->core->pci->subsystem_vendor) {
+-		ir->input.id.vendor  = sub->core->pci->subsystem_vendor;
+-		ir->input.id.product = sub->core->pci->subsystem_device;
++		input_dev->id.vendor  = sub->core->pci->subsystem_vendor;
++		input_dev->id.product = sub->core->pci->subsystem_device;
+ 	} else {
+-		ir->input.id.vendor  = sub->core->pci->vendor;
+-		ir->input.id.product = sub->core->pci->device;
++		input_dev->id.vendor  = sub->core->pci->vendor;
++		input_dev->id.product = sub->core->pci->device;
+ 	}
+-	ir->input.dev = &sub->core->pci->dev;
++	input_dev->cdev.dev = &sub->core->pci->dev;
+ 
+ 	if (ir->polling) {
+ 		INIT_WORK(&ir->work, ir_work, ir);
+@@ -364,9 +369,8 @@ static int ir_probe(struct device *dev)
+ 	}
+ 
+ 	/* all done */
+-	dev_set_drvdata(dev,ir);
+-	input_register_device(&ir->input);
+-	printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys);
++	dev_set_drvdata(dev, ir);
++	input_register_device(ir->input);
+ 
+ 	return 0;
+ }
+@@ -380,7 +384,7 @@ static int ir_remove(struct device *dev)
+ 		flush_scheduled_work();
+ 	}
+ 
+-	input_unregister_device(&ir->input);
++	input_unregister_device(ir->input);
+ 	kfree(ir);
+ 	return 0;
+ }
+diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
+--- a/drivers/media/video/ir-kbd-i2c.c
++++ b/drivers/media/video/ir-kbd-i2c.c
+@@ -121,10 +121,9 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[
+ 
+ };
+ 
+-struct IR;
+ struct IR {
+ 	struct i2c_client      c;
+-	struct input_dev       input;
++	struct input_dev       *input;
+ 	struct ir_input_state  ir;
+ 
+ 	struct work_struct     work;
+@@ -271,9 +270,9 @@ static void ir_key_poll(struct IR *ir)
+ 	}
+ 
+ 	if (0 == rc) {
+-		ir_input_nokey(&ir->input,&ir->ir);
++		ir_input_nokey(ir->input, &ir->ir);
+ 	} else {
+-		ir_input_keydown(&ir->input,&ir->ir, ir_key, ir_raw);
++		ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw);
+ 	}
+ }
+ 
+@@ -318,11 +317,18 @@ static int ir_attach(struct i2c_adapter 
+ 	char *name;
+ 	int ir_type;
+         struct IR *ir;
++	struct input_dev *input_dev;
+ 
+-        if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL)))
++	ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!ir || !input_dev) {
++		kfree(ir);
++		input_free_device(input_dev);
+                 return -ENOMEM;
+-	memset(ir,0,sizeof(*ir));
++	}
++
+ 	ir->c = client_template;
++	ir->input = input_dev;
+ 
+ 	i2c_set_clientdata(&ir->c, ir);
+ 	ir->c.adapter = adap;
+@@ -375,13 +381,12 @@ static int ir_attach(struct i2c_adapter 
+ 		 ir->c.dev.bus_id);
+ 
+ 	/* init + register input device */
+-	ir_input_init(&ir->input,&ir->ir,ir_type,ir_codes);
+-	ir->input.id.bustype = BUS_I2C;
+-	ir->input.name       = ir->c.name;
+-	ir->input.phys       = ir->phys;
+-	input_register_device(&ir->input);
+-	printk(DEVNAME ": %s detected at %s [%s]\n",
+-	       ir->input.name,ir->input.phys,adap->name);
++	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
++	input_dev->id.bustype	= BUS_I2C;
++	input_dev->name		= ir->c.name;
++	input_dev->phys		= ir->phys;
++
++	input_register_device(ir->input);
+ 
+ 	/* start polling via eventd */
+ 	INIT_WORK(&ir->work, ir_work, ir);
+@@ -402,7 +407,7 @@ static int ir_detach(struct i2c_client *
+ 	flush_scheduled_work();
+ 
+ 	/* unregister devices */
+-	input_unregister_device(&ir->input);
++	input_unregister_device(ir->input);
+ 	i2c_detach_client(&ir->c);
+ 
+ 	/* free memory */
+diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
+--- a/drivers/media/video/msp3400.c
++++ b/drivers/media/video/msp3400.c
+@@ -1420,8 +1420,8 @@ static int msp_detach(struct i2c_client 
+ static int msp_probe(struct i2c_adapter *adap);
+ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
+ 
+-static int msp_suspend(struct device * dev, pm_message_t state, u32 level);
+-static int msp_resume(struct device * dev, u32 level);
++static int msp_suspend(struct device * dev, pm_message_t state);
++static int msp_resume(struct device * dev);
+ 
+ static void msp_wake_thread(struct i2c_client *client);
+ 
+@@ -1821,7 +1821,7 @@ static int msp_command(struct i2c_client
+ 	return 0;
+ }
+ 
+-static int msp_suspend(struct device * dev, pm_message_t state, u32 level)
++static int msp_suspend(struct device * dev, pm_message_t state)
+ {
+ 	struct i2c_client *c = container_of(dev, struct i2c_client, dev);
+ 
+@@ -1830,7 +1830,7 @@ static int msp_suspend(struct device * d
+ 	return 0;
+ }
+ 
+-static int msp_resume(struct device * dev, u32 level)
++static int msp_resume(struct device * dev)
+ {
+ 	struct i2c_client *c = container_of(dev, struct i2c_client, dev);
+ 
+diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
+--- a/drivers/media/video/saa7134/saa7134-input.c
++++ b/drivers/media/video/saa7134/saa7134-input.c
+@@ -425,9 +425,9 @@ static int build_key(struct saa7134_dev 
+ 
+ 	if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
+ 	    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
+-		ir_input_keydown(&ir->dev,&ir->ir,data,data);
++		ir_input_keydown(ir->dev, &ir->ir, data, data);
+ 	} else {
+-		ir_input_nokey(&ir->dev,&ir->ir);
++		ir_input_nokey(ir->dev, &ir->ir);
+ 	}
+ 	return 0;
+ }
+@@ -456,6 +456,7 @@ static void saa7134_input_timer(unsigned
+ int saa7134_input_init1(struct saa7134_dev *dev)
+ {
+ 	struct saa7134_ir *ir;
++	struct input_dev *input_dev;
+ 	IR_KEYTAB_TYPE *ir_codes = NULL;
+ 	u32 mask_keycode = 0;
+ 	u32 mask_keydown = 0;
+@@ -535,10 +536,13 @@ int saa7134_input_init1(struct saa7134_d
+ 		return -ENODEV;
+ 	}
+ 
+-	ir = kmalloc(sizeof(*ir),GFP_KERNEL);
+-	if (NULL == ir)
++	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!ir || !input_dev) {
++		kfree(ir);
++		input_free_device(input_dev);
+ 		return -ENOMEM;
+-	memset(ir,0,sizeof(*ir));
++	}
+ 
+ 	/* init hardware-specific stuff */
+ 	ir->mask_keycode = mask_keycode;
+@@ -552,19 +556,19 @@ int saa7134_input_init1(struct saa7134_d
+ 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
+ 		 pci_name(dev->pci));
+ 
+-	ir_input_init(&ir->dev, &ir->ir, ir_type, ir_codes);
+-	ir->dev.name = ir->name;
+-	ir->dev.phys = ir->phys;
+-	ir->dev.id.bustype = BUS_PCI;
+-	ir->dev.id.version = 1;
++	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
++	input_dev->name = ir->name;
++	input_dev->phys = ir->phys;
++	input_dev->id.bustype = BUS_PCI;
++	input_dev->id.version = 1;
+ 	if (dev->pci->subsystem_vendor) {
+-		ir->dev.id.vendor  = dev->pci->subsystem_vendor;
+-		ir->dev.id.product = dev->pci->subsystem_device;
++		input_dev->id.vendor  = dev->pci->subsystem_vendor;
++		input_dev->id.product = dev->pci->subsystem_device;
+ 	} else {
+-		ir->dev.id.vendor  = dev->pci->vendor;
+-		ir->dev.id.product = dev->pci->device;
++		input_dev->id.vendor  = dev->pci->vendor;
++		input_dev->id.product = dev->pci->device;
+ 	}
+-	ir->dev.dev = &dev->pci->dev;
++	input_dev->cdev.dev = &dev->pci->dev;
+ 
+ 	/* all done */
+ 	dev->remote = ir;
+@@ -576,8 +580,7 @@ int saa7134_input_init1(struct saa7134_d
+ 		add_timer(&ir->timer);
+ 	}
+ 
+-	input_register_device(&dev->remote->dev);
+-	printk("%s: registered input device for IR\n",dev->name);
++	input_register_device(ir->dev);
+ 	return 0;
+ }
+ 
+@@ -586,9 +589,9 @@ void saa7134_input_fini(struct saa7134_d
+ 	if (NULL == dev->remote)
+ 		return;
+ 
+-	input_unregister_device(&dev->remote->dev);
+ 	if (dev->remote->polling)
+ 		del_timer_sync(&dev->remote->timer);
++	input_unregister_device(dev->remote->dev);
+ 	kfree(dev->remote);
+ 	dev->remote = NULL;
+ }
+diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
+--- a/drivers/media/video/saa7134/saa7134.h
++++ b/drivers/media/video/saa7134/saa7134.h
+@@ -351,7 +351,7 @@ struct saa7134_oss {
+ 
+ /* IR input */
+ struct saa7134_ir {
+-	struct input_dev           dev;
++	struct input_dev           *dev;
+ 	struct ir_input_state      ir;
+ 	char                       name[32];
+ 	char                       phys[32];
+diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
+--- a/drivers/media/video/saa7191.c
++++ b/drivers/media/video/saa7191.c
+@@ -9,16 +9,16 @@
+  *  published by the Free Software Foundation.
+  */
+ 
+-#include <linux/module.h>
+-#include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/fs.h>
++#include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/major.h>
+-#include <linux/slab.h>
++#include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/sched.h>
++#include <linux/slab.h>
+ 
+ #include <linux/videodev.h>
+ #include <linux/video_decoder.h>
+@@ -33,8 +33,6 @@ MODULE_VERSION(SAA7191_MODULE_VERSION);
+ MODULE_AUTHOR("Mikael Nousiainen <tmnousia at cc.hut.fi>");
+ MODULE_LICENSE("GPL");
+ 
+-#define VINO_ADAPTER	(I2C_ALGO_SGI | I2C_HW_SGI_VINO)
+-
+ struct saa7191 {
+ 	struct i2c_client *client;
+ 
+@@ -337,7 +335,7 @@ out_free_client:
+ static int saa7191_probe(struct i2c_adapter *adap)
+ {
+ 	/* Always connected to VINO */
+-	if (adap->id == VINO_ADAPTER)
++	if (adap->id == I2C_HW_SGI_VINO)
+ 		return saa7191_attach(adap, SAA7191_ADDR, 0);
+ 	/* Feel free to add probe here :-) */
+ 	return -ENODEV;
+@@ -364,7 +362,7 @@ static int saa7191_command(struct i2c_cl
+ 
+ 		cap->flags  = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
+ 			      VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
+-		cap->inputs = (client->adapter->id == VINO_ADAPTER) ? 2 : 1;
++		cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
+ 		cap->outputs = 1;
+ 		break;
+ 	}
+@@ -422,7 +420,7 @@ static int saa7191_command(struct i2c_cl
+ 		int *iarg = arg;
+ 
+ 		switch (client->adapter->id) {
+-		case VINO_ADAPTER:
++		case I2C_HW_SGI_VINO:
+ 			return saa7191_set_input(client, *iarg);
+ 		default:
+ 			if (*iarg != 0)
+diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
+--- a/drivers/media/video/tda9887.c
++++ b/drivers/media/video/tda9887.c
+@@ -784,13 +784,13 @@ tda9887_command(struct i2c_client *clien
+ 	return 0;
+ }
+ 
+-static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level)
++static int tda9887_suspend(struct device * dev, pm_message_t state)
+ {
+ 	dprintk("tda9887: suspend\n");
+ 	return 0;
+ }
+ 
+-static int tda9887_resume(struct device * dev, u32 level)
++static int tda9887_resume(struct device * dev)
+ {
+ 	struct i2c_client *c = container_of(dev, struct i2c_client, dev);
+ 	struct tda9887 *t = i2c_get_clientdata(c);
+diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
+--- a/drivers/media/video/tuner-core.c
++++ b/drivers/media/video/tuner-core.c
+@@ -697,7 +697,7 @@ static int tuner_command(struct i2c_clie
+ 	return 0;
+ }
+ 
+-static int tuner_suspend(struct device *dev, pm_message_t state, u32 level)
++static int tuner_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct i2c_client *c = container_of (dev, struct i2c_client, dev);
+ 	struct tuner *t = i2c_get_clientdata (c);
+@@ -707,7 +707,7 @@ static int tuner_suspend(struct device *
+ 	return 0;
+ }
+ 
+-static int tuner_resume(struct device *dev, u32 level)
++static int tuner_resume(struct device *dev)
+ {
+ 	struct i2c_client *c = container_of (dev, struct i2c_client, dev);
+ 	struct tuner *t = i2c_get_clientdata (c);
+diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
+--- a/drivers/media/video/vino.c
++++ b/drivers/media/video/vino.c
+@@ -26,14 +26,15 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/delay.h>
++#include <linux/dma-mapping.h>
+ #include <linux/errno.h>
+ #include <linux/fs.h>
++#include <linux/interrupt.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+-#include <linux/interrupt.h>
+-#include <linux/dma-mapping.h>
+-#include <linux/time.h>
+ #include <linux/moduleparam.h>
++#include <linux/time.h>
++#include <linux/version.h>
+ 
+ #ifdef CONFIG_KMOD
+ #include <linux/kmod.h>
+diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
+--- a/drivers/message/i2o/core.h
++++ b/drivers/message/i2o/core.h
+@@ -36,9 +36,6 @@ extern void __exit i2o_pci_exit(void);
+ extern void i2o_device_remove(struct i2o_device *);
+ extern int i2o_device_parse_lct(struct i2o_controller *);
+ 
+-extern int i2o_device_init(void);
+-extern void i2o_device_exit(void);
+-
+ /* IOP */
+ extern struct i2o_controller *i2o_iop_alloc(void);
+ extern void i2o_iop_free(struct i2o_controller *);
+diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c
+--- a/drivers/message/i2o/debug.c
++++ b/drivers/message/i2o/debug.c
+@@ -90,7 +90,7 @@ static void i2o_report_fail_status(u8 re
+ 	};
+ 
+ 	if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE)
+-		printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x)\n.",
++		printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x).\n",
+ 		       req_status);
+ 	else
+ 		printk(KERN_DEBUG "TRANSPORT_%s.\n",
+diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
+--- a/drivers/message/i2o/device.c
++++ b/drivers/message/i2o/device.c
+@@ -16,6 +16,8 @@
+ #include <linux/module.h>
+ #include <linux/i2o.h>
+ #include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include "core.h"
+ 
+ /**
+@@ -45,10 +47,10 @@ static inline int i2o_device_issue_claim
+ 	writel(type, &msg->body[0]);
+ 
+ 	return i2o_msg_post_wait(dev->iop, m, 60);
+-};
++}
+ 
+ /**
+- * 	i2o_device_claim - claim a device for use by an OSM
++ *	i2o_device_claim - claim a device for use by an OSM
+  *	@dev: I2O device to claim
+  *	@drv: I2O driver which wants to claim the device
+  *
+@@ -73,7 +75,7 @@ int i2o_device_claim(struct i2o_device *
+ 	up(&dev->lock);
+ 
+ 	return rc;
+-};
++}
+ 
+ /**
+  *	i2o_device_claim_release - release a device that the OSM is using
+@@ -119,7 +121,8 @@ int i2o_device_claim_release(struct i2o_
+ 	up(&dev->lock);
+ 
+ 	return rc;
+-};
++}
++
+ 
+ /**
+  *	i2o_device_release - release the memory for a I2O device
+@@ -135,39 +138,47 @@ static void i2o_device_release(struct de
+ 	pr_debug("i2o: device %s released\n", dev->bus_id);
+ 
+ 	kfree(i2o_dev);
+-};
++}
++
+ 
+ /**
+- *	i2o_device_class_release - Remove I2O device attributes
+- *	@cd: I2O class device which is added to the I2O device class
++ *	i2o_device_class_show_class_id - Displays class id of I2O device
++ *	@cd: class device of which the class id should be displayed
++ *	@buf: buffer into which the class id should be printed
+  *
+- *	Removes attributes from the I2O device again. Also search each device
+- *	on the controller for I2O devices which refert to this device as parent
+- *	or user and remove this links also.
++ *	Returns the number of bytes which are printed into the buffer.
+  */
+-static void i2o_device_class_release(struct class_device *cd)
++static ssize_t i2o_device_show_class_id(struct device *dev,
++					struct device_attribute *attr,
++					char *buf)
+ {
+-	struct i2o_device *i2o_dev, *tmp;
+-	struct i2o_controller *c;
++	struct i2o_device *i2o_dev = to_i2o_device(dev);
+ 
+-	i2o_dev = to_i2o_device(cd->dev);
+-	c = i2o_dev->iop;
++	sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id);
++	return strlen(buf) + 1;
++}
+ 
+-	sysfs_remove_link(&i2o_dev->device.kobj, "parent");
+-	sysfs_remove_link(&i2o_dev->device.kobj, "user");
++/**
++ *	i2o_device_class_show_tid - Displays TID of I2O device
++ *	@cd: class device of which the TID should be displayed
++ *	@buf: buffer into which the class id should be printed
++ *
++ *	Returns the number of bytes which are printed into the buffer.
++ */
++static ssize_t i2o_device_show_tid(struct device *dev,
++				   struct device_attribute *attr,
++				   char *buf)
++{
++	struct i2o_device *i2o_dev = to_i2o_device(dev);
+ 
+-	list_for_each_entry(tmp, &c->devices, list) {
+-		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+-			sysfs_remove_link(&tmp->device.kobj, "parent");
+-		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+-			sysfs_remove_link(&tmp->device.kobj, "user");
+-	}
+-};
++	sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid);
++	return strlen(buf) + 1;
++}
+ 
+-/* I2O device class */
+-static struct class i2o_device_class = {
+-	.name = "i2o_device",
+-	.release = i2o_device_class_release
++struct device_attribute i2o_device_attrs[] = {
++	__ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL),
++	__ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL),
++	__ATTR_NULL
+ };
+ 
+ /**
+@@ -193,11 +204,69 @@ static struct i2o_device *i2o_device_all
+ 
+ 	dev->device.bus = &i2o_bus_type;
+ 	dev->device.release = &i2o_device_release;
+-	dev->classdev.class = &i2o_device_class;
+-	dev->classdev.dev = &dev->device;
+ 
+ 	return dev;
+-};
++}
++
++/**
++ *	i2o_setup_sysfs_links - Adds attributes to the I2O device
++ *	@cd: I2O class device which is added to the I2O device class
++ *
++ *	This function get called when a I2O device is added to the class. It
++ *	creates the attributes for each device and creates user/parent symlink
++ *	if necessary.
++ *
++ *	Returns 0 on success or negative error code on failure.
++ */
++static void i2o_setup_sysfs_links(struct i2o_device *i2o_dev)
++{
++	struct i2o_controller *c = i2o_dev->iop;
++	struct i2o_device *tmp;
++
++	/* create user entries for this device */
++	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
++	if (tmp && tmp != i2o_dev)
++		sysfs_create_link(&i2o_dev->device.kobj,
++				  &tmp->device.kobj, "user");
++
++	/* create user entries refering to this device */
++	list_for_each_entry(tmp, &c->devices, list)
++		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid &&
++		    tmp != i2o_dev)
++			sysfs_create_link(&tmp->device.kobj,
++					  &i2o_dev->device.kobj, "user");
++
++	/* create parent entries for this device */
++	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
++	if (tmp && tmp != i2o_dev)
++		sysfs_create_link(&i2o_dev->device.kobj,
++				  &tmp->device.kobj, "parent");
++
++	/* create parent entries refering to this device */
++	list_for_each_entry(tmp, &c->devices, list)
++		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid &&
++		    tmp != i2o_dev)
++		sysfs_create_link(&tmp->device.kobj,
++				  &i2o_dev->device.kobj, "parent");
++}
++
++static void i2o_remove_sysfs_links(struct i2o_device *i2o_dev)
++{
++	struct i2o_controller *c = i2o_dev->iop;
++	struct i2o_device *tmp;
++
++	sysfs_remove_link(&i2o_dev->device.kobj, "parent");
++	sysfs_remove_link(&i2o_dev->device.kobj, "user");
++
++	list_for_each_entry(tmp, &c->devices, list) {
++		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
++			sysfs_remove_link(&tmp->device.kobj, "parent");
++		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
++			sysfs_remove_link(&tmp->device.kobj, "user");
++	}
++}
++
++
+ 
+ /**
+  *	i2o_device_add - allocate a new I2O device and add it to the IOP
+@@ -222,28 +291,25 @@ static struct i2o_device *i2o_device_add
+ 	}
+ 
+ 	dev->lct_data = *entry;
++	dev->iop = c;
+ 
+ 	snprintf(dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit,
+ 		 dev->lct_data.tid);
+ 
+-	snprintf(dev->classdev.class_id, BUS_ID_SIZE, "%d:%03x", c->unit,
+-		 dev->lct_data.tid);
+-
+-	dev->iop = c;
+ 	dev->device.parent = &c->device;
+ 
+ 	device_register(&dev->device);
+ 
+ 	list_add_tail(&dev->list, &c->devices);
+ 
+-	class_device_register(&dev->classdev);
++	i2o_setup_sysfs_links(dev);
+ 
+ 	i2o_driver_notify_device_add_all(dev);
+ 
+ 	pr_debug("i2o: device %s added\n", dev->device.bus_id);
+ 
+ 	return dev;
+-};
++}
+ 
+ /**
+  *	i2o_device_remove - remove an I2O device from the I2O core
+@@ -256,10 +322,10 @@ static struct i2o_device *i2o_device_add
+ void i2o_device_remove(struct i2o_device *i2o_dev)
+ {
+ 	i2o_driver_notify_device_remove_all(i2o_dev);
+-	class_device_unregister(&i2o_dev->classdev);
++	i2o_remove_sysfs_links(i2o_dev);
+ 	list_del(&i2o_dev->list);
+ 	device_unregister(&i2o_dev->device);
+-};
++}
+ 
+ /**
+  *	i2o_device_parse_lct - Parse a previously fetched LCT and create devices
+@@ -337,99 +403,8 @@ int i2o_device_parse_lct(struct i2o_cont
+ 	up(&c->lct_lock);
+ 
+ 	return 0;
+-};
+-
+-/**
+- *	i2o_device_class_show_class_id - Displays class id of I2O device
+- *	@cd: class device of which the class id should be displayed
+- *	@buf: buffer into which the class id should be printed
+- *
+- *	Returns the number of bytes which are printed into the buffer.
+- */
+-static ssize_t i2o_device_class_show_class_id(struct class_device *cd,
+-					      char *buf)
+-{
+-	struct i2o_device *dev = to_i2o_device(cd->dev);
+-
+-	sprintf(buf, "0x%03x\n", dev->lct_data.class_id);
+-	return strlen(buf) + 1;
+-};
+-
+-/**
+- *	i2o_device_class_show_tid - Displays TID of I2O device
+- *	@cd: class device of which the TID should be displayed
+- *	@buf: buffer into which the class id should be printed
+- *
+- *	Returns the number of bytes which are printed into the buffer.
+- */
+-static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf)
+-{
+-	struct i2o_device *dev = to_i2o_device(cd->dev);
+-
+-	sprintf(buf, "0x%03x\n", dev->lct_data.tid);
+-	return strlen(buf) + 1;
+-};
+-
+-/* I2O device class attributes */
+-static CLASS_DEVICE_ATTR(class_id, S_IRUGO, i2o_device_class_show_class_id,
+-			 NULL);
+-static CLASS_DEVICE_ATTR(tid, S_IRUGO, i2o_device_class_show_tid, NULL);
+-
+-/**
+- *	i2o_device_class_add - Adds attributes to the I2O device
+- *	@cd: I2O class device which is added to the I2O device class
+- *
+- *	This function get called when a I2O device is added to the class. It
+- *	creates the attributes for each device and creates user/parent symlink
+- *	if necessary.
+- *
+- *	Returns 0 on success or negative error code on failure.
+- */
+-static int i2o_device_class_add(struct class_device *cd)
+-{
+-	struct i2o_device *i2o_dev, *tmp;
+-	struct i2o_controller *c;
+-
+-	i2o_dev = to_i2o_device(cd->dev);
+-	c = i2o_dev->iop;
+-
+-	class_device_create_file(cd, &class_device_attr_class_id);
+-	class_device_create_file(cd, &class_device_attr_tid);
+-
+-	/* create user entries for this device */
+-	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
+-	if (tmp && (tmp != i2o_dev))
+-		sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
+-				  "user");
+-
+-	/* create user entries refering to this device */
+-	list_for_each_entry(tmp, &c->devices, list)
+-	    if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+-		&& (tmp != i2o_dev))
+-		sysfs_create_link(&tmp->device.kobj,
+-				  &i2o_dev->device.kobj, "user");
+-
+-	/* create parent entries for this device */
+-	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
+-	if (tmp && (tmp != i2o_dev))
+-		sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
+-				  "parent");
+-
+-	/* create parent entries refering to this device */
+-	list_for_each_entry(tmp, &c->devices, list)
+-	    if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+-		&& (tmp != i2o_dev))
+-		sysfs_create_link(&tmp->device.kobj,
+-				  &i2o_dev->device.kobj, "parent");
+-
+-	return 0;
+-};
++}
+ 
+-/* I2O device class interface */
+-static struct class_interface i2o_device_class_interface = {
+-	.class = &i2o_device_class,
+-	.add = i2o_device_class_add
+-};
+ 
+ /*
+  *	Run time support routines
+@@ -553,11 +528,11 @@ int i2o_parm_field_get(struct i2o_device
+ }
+ 
+ /*
+- * 	if oper == I2O_PARAMS_TABLE_GET, get from all rows
+- * 		if fieldcount == -1 return all fields
++ *	if oper == I2O_PARAMS_TABLE_GET, get from all rows
++ *		if fieldcount == -1 return all fields
+  *			ibuf and ibuflen are unused (use NULL, 0)
+- * 		else return specific fields
+- *  			ibuf contains fieldindexes
++ *		else return specific fields
++ *			ibuf contains fieldindexes
+  *
+  * 	if oper == I2O_PARAMS_LIST_GET, get from specific rows
+  * 		if fieldcount == -1 return all fields
+@@ -602,35 +577,6 @@ int i2o_parm_table_get(struct i2o_device
+ 	return size;
+ }
+ 
+-/**
+- *	i2o_device_init - Initialize I2O devices
+- *
+- *	Registers the I2O device class.
+- *
+- *	Returns 0 on success or negative error code on failure.
+- */
+-int i2o_device_init(void)
+-{
+-	int rc;
+-
+-	rc = class_register(&i2o_device_class);
+-	if (rc)
+-		return rc;
+-
+-	return class_interface_register(&i2o_device_class_interface);
+-};
+-
+-/**
+- *	i2o_device_exit - I2O devices exit function
+- *
+- *	Unregisters the I2O device class.
+- */
+-void i2o_device_exit(void)
+-{
+-	class_interface_register(&i2o_device_class_interface);
+-	class_unregister(&i2o_device_class);
+-};
+-
+ EXPORT_SYMBOL(i2o_device_claim);
+ EXPORT_SYMBOL(i2o_device_claim_release);
+ EXPORT_SYMBOL(i2o_parm_field_get);
+diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
+--- a/drivers/message/i2o/driver.c
++++ b/drivers/message/i2o/driver.c
+@@ -17,6 +17,9 @@
+ #include <linux/module.h>
+ #include <linux/rwsem.h>
+ #include <linux/i2o.h>
++#include <linux/workqueue.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include "core.h"
+ 
+ #define OSM_NAME	"i2o"
+@@ -58,9 +61,12 @@ static int i2o_bus_match(struct device *
+ };
+ 
+ /* I2O bus type */
++extern struct device_attribute i2o_device_attrs[];
++
+ struct bus_type i2o_bus_type = {
+ 	.name = "i2o",
+ 	.match = i2o_bus_match,
++	.dev_attrs = i2o_device_attrs,
+ };
+ 
+ /**
+diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
+--- a/drivers/message/i2o/exec-osm.c
++++ b/drivers/message/i2o/exec-osm.c
+@@ -30,6 +30,10 @@
+ #include <linux/module.h>
+ #include <linux/i2o.h>
+ #include <linux/delay.h>
++#include <linux/workqueue.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <asm/param.h>		/* HZ */
+ #include "core.h"
+ 
+ #define OSM_NAME "exec-osm"
+diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
+--- a/drivers/message/i2o/iop.c
++++ b/drivers/message/i2o/iop.c
+@@ -28,6 +28,7 @@
+ #include <linux/module.h>
+ #include <linux/i2o.h>
+ #include <linux/delay.h>
++#include <linux/sched.h>
+ #include "core.h"
+ 
+ #define OSM_NAME	"i2o"
+@@ -833,6 +834,7 @@ void i2o_iop_remove(struct i2o_controlle
+ 	list_for_each_entry_safe(dev, tmp, &c->devices, list)
+ 	    i2o_device_remove(dev);
+ 
++	class_device_unregister(c->classdev);
+ 	device_del(&c->device);
+ 
+ 	/* Ask the IOP to switch to RESET state */
+@@ -1077,9 +1079,7 @@ static void i2o_iop_release(struct devic
+ };
+ 
+ /* I2O controller class */
+-static struct class i2o_controller_class = {
+-	.name = "i2o_controller",
+-};
++static struct class *i2o_controller_class;
+ 
+ /**
+  *	i2o_iop_alloc - Allocate and initialize a i2o_controller struct
+@@ -1110,14 +1110,10 @@ struct i2o_controller *i2o_iop_alloc(voi
+ 	sprintf(c->name, "iop%d", c->unit);
+ 
+ 	device_initialize(&c->device);
+-	class_device_initialize(&c->classdev);
+ 
+ 	c->device.release = &i2o_iop_release;
+-	c->classdev.class = &i2o_controller_class;
+-	c->classdev.dev = &c->device;
+ 
+ 	snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit);
+-	snprintf(c->classdev.class_id, BUS_ID_SIZE, "iop%d", c->unit);
+ 
+ #if BITS_PER_LONG == 64
+ 	spin_lock_init(&c->context_list_lock);
+@@ -1146,7 +1142,9 @@ int i2o_iop_add(struct i2o_controller *c
+ 		goto iop_reset;
+ 	}
+ 
+-	if ((rc = class_device_add(&c->classdev))) {
++	c->classdev = class_device_create(i2o_controller_class, NULL, MKDEV(0,0),
++			&c->device, "iop%d", c->unit);
++	if (IS_ERR(c->classdev)) {
+ 		osm_err("%s: could not add controller class\n", c->name);
+ 		goto device_del;
+ 	}
+@@ -1184,7 +1182,7 @@ int i2o_iop_add(struct i2o_controller *c
+ 	return 0;
+ 
+       class_del:
+-	class_device_del(&c->classdev);
++	class_device_unregister(c->classdev);
+ 
+       device_del:
+ 	device_del(&c->device);
+@@ -1246,13 +1244,10 @@ static int __init i2o_iop_init(void)
+ 
+ 	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
+ 
+-	rc = i2o_device_init();
+-	if (rc)
+-		goto exit;
+-
+-	if ((rc = class_register(&i2o_controller_class))) {
++	i2o_controller_class = class_create(THIS_MODULE, "i2o_controller");
++	if (IS_ERR(i2o_controller_class)) {
+ 		osm_err("can't register class i2o_controller\n");
+-		goto device_exit;
++		goto exit;
+ 	}
+ 
+ 	if ((rc = i2o_driver_init()))
+@@ -1273,10 +1268,7 @@ static int __init i2o_iop_init(void)
+ 	i2o_driver_exit();
+ 
+       class_exit:
+-	class_unregister(&i2o_controller_class);
+-
+-      device_exit:
+-	i2o_device_exit();
++	class_destroy(i2o_controller_class);
+ 
+       exit:
+ 	return rc;
+@@ -1292,8 +1284,7 @@ static void __exit i2o_iop_exit(void)
+ 	i2o_pci_exit();
+ 	i2o_exec_exit();
+ 	i2o_driver_exit();
+-	class_unregister(&i2o_controller_class);
+-	i2o_device_exit();
++	class_destroy(i2o_controller_class);
+ };
+ 
+ module_init(i2o_iop_init);
+diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
+--- a/drivers/mfd/mcp-sa11x0.c
++++ b/drivers/mfd/mcp-sa11x0.c
+@@ -18,7 +18,7 @@
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+ #include <linux/slab.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/dma.h>
+ #include <asm/hardware.h>
+@@ -219,26 +219,24 @@ static int mcp_sa11x0_remove(struct devi
+ 	return 0;
+ }
+ 
+-static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state, u32 level)
++static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct mcp *mcp = dev_get_drvdata(dev);
+ 
+-	if (level == SUSPEND_DISABLE) {
+-		priv(mcp)->mccr0 = Ser4MCCR0;
+-		priv(mcp)->mccr1 = Ser4MCCR1;
+-		Ser4MCCR0 &= ~MCCR0_MCE;
+-	}
++	priv(mcp)->mccr0 = Ser4MCCR0;
++	priv(mcp)->mccr1 = Ser4MCCR1;
++	Ser4MCCR0 &= ~MCCR0_MCE;
++
+ 	return 0;
+ }
+ 
+-static int mcp_sa11x0_resume(struct device *dev, u32 level)
++static int mcp_sa11x0_resume(struct device *dev)
+ {
+ 	struct mcp *mcp = dev_get_drvdata(dev);
+ 
+-	if (level == RESUME_RESTORE_STATE) {
+-		Ser4MCCR1 = priv(mcp)->mccr1;
+-		Ser4MCCR0 = priv(mcp)->mccr0;
+-	}
++	Ser4MCCR1 = priv(mcp)->mccr1;
++	Ser4MCCR0 = priv(mcp)->mccr0;
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
+--- a/drivers/mfd/ucb1x00-ts.c
++++ b/drivers/mfd/ucb1x00-ts.c
+@@ -32,15 +32,18 @@
+ #include <linux/suspend.h>
+ #include <linux/slab.h>
+ #include <linux/kthread.h>
++#include <linux/delay.h>
+ 
+ #include <asm/dma.h>
+ #include <asm/semaphore.h>
++#include <asm/arch/collie.h>
++#include <asm/mach-types.h>
+ 
+ #include "ucb1x00.h"
+ 
+ 
+ struct ucb1x00_ts {
+-	struct input_dev	idev;
++	struct input_dev	*idev;
+ 	struct ucb1x00		*ucb;
+ 
+ 	wait_queue_head_t	irq_wait;
+@@ -56,16 +59,16 @@ static int adcsync;
+ 
+ static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
+ {
+-	input_report_abs(&ts->idev, ABS_X, x);
+-	input_report_abs(&ts->idev, ABS_Y, y);
+-	input_report_abs(&ts->idev, ABS_PRESSURE, pressure);
+-	input_sync(&ts->idev);
++	input_report_abs(ts->idev, ABS_X, x);
++	input_report_abs(ts->idev, ABS_Y, y);
++	input_report_abs(ts->idev, ABS_PRESSURE, pressure);
++	input_sync(ts->idev);
+ }
+ 
+ static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
+ {
+-	input_report_abs(&ts->idev, ABS_PRESSURE, 0);
+-	input_sync(&ts->idev);
++	input_report_abs(ts->idev, ABS_PRESSURE, 0);
++	input_sync(ts->idev);
+ }
+ 
+ /*
+@@ -85,12 +88,23 @@ static inline void ucb1x00_ts_mode_int(s
+  */
+ static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
+ {
+-	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+-			UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
+-			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
+-			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++	if (machine_is_collie()) {
++		ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0);
++		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
++				  UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW |
++				  UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+ 
+-	return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
++		udelay(55);
++
++		return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync);
++	} else {
++		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
++				  UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
++				  UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
++				  UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++
++		return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
++	}
+ }
+ 
+ /*
+@@ -101,12 +115,16 @@ static inline unsigned int ucb1x00_ts_re
+  */
+ static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
+ {
+-	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+-			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+-			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+-	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+-			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+-			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++	if (machine_is_collie())
++		ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
++	else {
++		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
++				  UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
++				  UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
++				  UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
++				  UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++	}
+ 	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ 			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ 			UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+@@ -124,12 +142,17 @@ static inline unsigned int ucb1x00_ts_re
+  */
+ static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
+ {
+-	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+-			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+-			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+-	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+-			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+-			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++	if (machine_is_collie())
++		ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
++	else {
++		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
++				  UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
++				  UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
++				  UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
++				  UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++	}
++
+ 	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ 			UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+@@ -163,6 +186,15 @@ static inline unsigned int ucb1x00_ts_re
+ 	return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
+ }
+ 
++static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
++{
++	unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
++	if (machine_is_collie())
++		return (!(val & (UCB_TS_CR_TSPX_LOW)));
++	else
++		return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
++}
++
+ /*
+  * This is a RT kernel thread that handles the ADC accesses
+  * (mainly so we can use semaphores in the UCB1200 core code
+@@ -186,7 +218,7 @@ static int ucb1x00_thread(void *_ts)
+ 
+ 	add_wait_queue(&ts->irq_wait, &wait);
+ 	while (!kthread_should_stop()) {
+-		unsigned int x, y, p, val;
++		unsigned int x, y, p;
+ 		signed long timeout;
+ 
+ 		ts->restart = 0;
+@@ -206,12 +238,12 @@ static int ucb1x00_thread(void *_ts)
+ 		msleep(10);
+ 
+ 		ucb1x00_enable(ts->ucb);
+-		val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
+ 
+-		if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {
++
++		if (ucb1x00_ts_pen_down(ts)) {
+ 			set_task_state(tsk, TASK_INTERRUPTIBLE);
+ 
+-			ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
++			ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
+ 			ucb1x00_disable(ts->ucb);
+ 
+ 			/*
+@@ -341,26 +373,30 @@ static int ucb1x00_ts_add(struct ucb1x00
+ {
+ 	struct ucb1x00_ts *ts;
+ 
+-	ts = kmalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
++	ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
+ 	if (!ts)
+ 		return -ENOMEM;
+ 
+-	memset(ts, 0, sizeof(struct ucb1x00_ts));
++	ts->idev = input_allocate_device();
++	if (!ts->idev) {
++		kfree(ts);
++		return -ENOMEM;
++	}
+ 
+ 	ts->ucb = dev->ucb;
+ 	ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
+ 
+-	ts->idev.name       = "Touchscreen panel";
+-	ts->idev.id.product = ts->ucb->id;
+-	ts->idev.open       = ucb1x00_ts_open;
+-	ts->idev.close      = ucb1x00_ts_close;
+-
+-	__set_bit(EV_ABS, ts->idev.evbit);
+-	__set_bit(ABS_X, ts->idev.absbit);
+-	__set_bit(ABS_Y, ts->idev.absbit);
+-	__set_bit(ABS_PRESSURE, ts->idev.absbit);
++	ts->idev->name       = "Touchscreen panel";
++	ts->idev->id.product = ts->ucb->id;
++	ts->idev->open       = ucb1x00_ts_open;
++	ts->idev->close      = ucb1x00_ts_close;
++
++	__set_bit(EV_ABS, ts->idev->evbit);
++	__set_bit(ABS_X, ts->idev->absbit);
++	__set_bit(ABS_Y, ts->idev->absbit);
++	__set_bit(ABS_PRESSURE, ts->idev->absbit);
+ 
+-	input_register_device(&ts->idev);
++	input_register_device(ts->idev);
+ 
+ 	dev->priv = ts;
+ 
+@@ -370,7 +406,8 @@ static int ucb1x00_ts_add(struct ucb1x00
+ static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
+ {
+ 	struct ucb1x00_ts *ts = dev->priv;
+-	input_unregister_device(&ts->idev);
++
++	input_unregister_device(ts->idev);
+ 	kfree(ts);
+ }
+ 
+diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
+--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
++++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
+@@ -21,7 +21,7 @@
+ #include <linux/miscdevice.h>
+ #include <linux/pci.h>
+ #include <linux/proc_fs.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <asm/uaccess.h>
+ #include <linux/hdpu_features.h>
+ 
+diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
+--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
++++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
+@@ -21,7 +21,7 @@
+ #include <linux/hdpu_features.h>
+ #include <linux/pci.h>
+ 
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ static int hdpu_nexus_probe(struct device *ddev);
+ static int hdpu_nexus_remove(struct device *ddev);
+diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
+--- a/drivers/mmc/Kconfig
++++ b/drivers/mmc/Kconfig
+@@ -60,4 +60,13 @@ config MMC_WBSD
+ 
+ 	  If unsure, say N.
+ 
++config MMC_AU1X
++	tristate "Alchemy AU1XX0 MMC Card Interface support"
++	depends on SOC_AU1X00 && MMC
++	help
++	  This selects the AMD Alchemy(R) Multimedia card interface.
++	  iIf you have a Alchemy platform with a MMC slot, say Y or M here.
++
++	  If unsure, say N.
++
+ endmenu
+diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
+--- a/drivers/mmc/Makefile
++++ b/drivers/mmc/Makefile
+@@ -18,5 +18,6 @@ obj-$(CONFIG_MMC_BLOCK)		+= mmc_block.o
+ obj-$(CONFIG_MMC_ARMMMCI)	+= mmci.o
+ obj-$(CONFIG_MMC_PXA)		+= pxamci.o
+ obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
++obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
+ 
+ mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
+diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/mmc/au1xmmc.c
+@@ -0,0 +1,1026 @@
++/*
++ * linux/drivers/mmc/au1xmmc.c - AU1XX0 MMC driver
++ *
++ *  Copyright (c) 2005, Advanced Micro Devices, Inc.
++ *
++ *  Developed with help from the 2.4.30 MMC AU1XXX controller including
++ *  the following copyright notices:
++ *     Copyright (c) 2003-2004 Embedded Edge, LLC.
++ *     Portions Copyright (C) 2002 Embedix, Inc
++ *     Copyright 2002 Hewlett-Packard Company
++
++ *  2.6 version of this driver inspired by:
++ *     (drivers/mmc/wbsd.c) Copyright (C) 2004-2005 Pierre Ossman,
++ *     All Rights Reserved.
++ *     (drivers/mmc/pxa.c) Copyright (C) 2003 Russell King,
++ *     All Rights Reserved.
++ *
++
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++/* Why is a timer used to detect insert events?
++ *
++ * From the AU1100 MMC application guide:
++ * If the Au1100-based design is intended to support both MultiMediaCards
++ * and 1- or 4-data bit SecureDigital cards, then the solution is to
++ * connect a weak (560KOhm) pull-up resistor to connector pin 1.
++ * In doing so, a MMC card never enters SPI-mode communications,
++ * but now the SecureDigital card-detect feature of CD/DAT3 is ineffective
++ * (the low to high transition will not occur).
++ *
++ * So we use the timer to check the status manually.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/mm.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++
++#include <linux/mmc/host.h>
++#include <linux/mmc/protocol.h>
++#include <asm/io.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-au1x00/au1xxx_dbdma.h>
++#include <asm/mach-au1x00/au1100_mmc.h>
++#include <asm/scatterlist.h>
++
++#include <au1xxx.h>
++#include "au1xmmc.h"
++
++#define DRIVER_NAME "au1xxx-mmc"
++
++/* Set this to enable special debugging macros */
++/* #define MMC_DEBUG */
++
++#ifdef MMC_DEBUG
++#define DEBUG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args)
++#else
++#define DEBUG(fmt, idx, args...)
++#endif
++
++const struct {
++	u32 iobase;
++	u32 tx_devid, rx_devid;
++	u16 bcsrpwr;
++	u16 bcsrstatus;
++	u16 wpstatus;
++} au1xmmc_card_table[] = {
++	{ SD0_BASE, DSCR_CMD0_SDMS_TX0, DSCR_CMD0_SDMS_RX0,
++	  BCSR_BOARD_SD0PWR, BCSR_INT_SD0INSERT, BCSR_STATUS_SD0WP },
++#ifndef CONFIG_MIPS_DB1200
++	{ SD1_BASE, DSCR_CMD0_SDMS_TX1, DSCR_CMD0_SDMS_RX1,
++	  BCSR_BOARD_DS1PWR, BCSR_INT_SD1INSERT, BCSR_STATUS_SD1WP }
++#endif
++};
++
++#define AU1XMMC_CONTROLLER_COUNT \
++	(sizeof(au1xmmc_card_table) / sizeof(au1xmmc_card_table[0]))
++
++/* This array stores pointers for the hosts (used by the IRQ handler) */
++struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];
++static int dma = 1;
++
++#ifdef MODULE
++MODULE_PARM(dma, "i");
++MODULE_PARM_DESC(dma, "Use DMA engine for data transfers (0 = disabled)");
++#endif
++
++static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask)
++{
++	u32 val = au_readl(HOST_CONFIG(host));
++	val |= mask;
++	au_writel(val, HOST_CONFIG(host));
++	au_sync();
++}
++
++static inline void FLUSH_FIFO(struct au1xmmc_host *host)
++{
++	u32 val = au_readl(HOST_CONFIG2(host));
++
++	au_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host));
++	au_sync_delay(1);
++
++	/* SEND_STOP will turn off clock control - this re-enables it */
++	val &= ~SD_CONFIG2_DF;
++
++	au_writel(val, HOST_CONFIG2(host));
++	au_sync();
++}
++
++static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask)
++{
++	u32 val = au_readl(HOST_CONFIG(host));
++	val &= ~mask;
++	au_writel(val, HOST_CONFIG(host));
++	au_sync();
++}
++
++static inline void SEND_STOP(struct au1xmmc_host *host)
++{
++
++	/* We know the value of CONFIG2, so avoid a read we don't need */
++	u32 mask = SD_CONFIG2_EN;
++
++	WARN_ON(host->status != HOST_S_DATA);
++	host->status = HOST_S_STOP;
++
++	au_writel(mask | SD_CONFIG2_DF, HOST_CONFIG2(host));
++	au_sync();
++
++	/* Send the stop commmand */
++	au_writel(STOP_CMD, HOST_CMD(host));
++}
++
++static void au1xmmc_set_power(struct au1xmmc_host *host, int state)
++{
++
++	u32 val = au1xmmc_card_table[host->id].bcsrpwr;
++
++	bcsr->board &= ~val;
++	if (state) bcsr->board |= val;
++
++	au_sync_delay(1);
++}
++
++static inline int au1xmmc_card_inserted(struct au1xmmc_host *host)
++{
++	return (bcsr->sig_status & au1xmmc_card_table[host->id].bcsrstatus)
++		? 1 : 0;
++}
++
++static inline int au1xmmc_card_readonly(struct au1xmmc_host *host)
++{
++	return (bcsr->status & au1xmmc_card_table[host->id].wpstatus)
++		? 1 : 0;
++}
++
++static void au1xmmc_finish_request(struct au1xmmc_host *host)
++{
++
++	struct mmc_request *mrq = host->mrq;
++
++	host->mrq = NULL;
++	host->flags &= HOST_F_ACTIVE;
++
++	host->dma.len = 0;
++	host->dma.dir = 0;
++
++	host->pio.index  = 0;
++	host->pio.offset = 0;
++	host->pio.len = 0;
++
++	host->status = HOST_S_IDLE;
++
++	bcsr->disk_leds |= (1 << 8);
++
++	mmc_request_done(host->mmc, mrq);
++}
++
++static void au1xmmc_tasklet_finish(unsigned long param)
++{
++	struct au1xmmc_host *host = (struct au1xmmc_host *) param;
++	au1xmmc_finish_request(host);
++}
++
++static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
++				struct mmc_command *cmd)
++{
++
++	u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
++
++	switch(cmd->flags) {
++	case MMC_RSP_R1:
++		mmccmd |= SD_CMD_RT_1;
++		break;
++	case MMC_RSP_R1B:
++		mmccmd |= SD_CMD_RT_1B;
++		break;
++	case MMC_RSP_R2:
++		mmccmd |= SD_CMD_RT_2;
++		break;
++	case MMC_RSP_R3:
++		mmccmd |= SD_CMD_RT_3;
++		break;
++	}
++
++	switch(cmd->opcode) {
++	case MMC_READ_SINGLE_BLOCK:
++	case SD_APP_SEND_SCR:
++		mmccmd |= SD_CMD_CT_2;
++		break;
++	case MMC_READ_MULTIPLE_BLOCK:
++		mmccmd |= SD_CMD_CT_4;
++		break;
++	case MMC_WRITE_BLOCK:
++		mmccmd |= SD_CMD_CT_1;
++		break;
++
++	case MMC_WRITE_MULTIPLE_BLOCK:
++		mmccmd |= SD_CMD_CT_3;
++		break;
++	case MMC_STOP_TRANSMISSION:
++		mmccmd |= SD_CMD_CT_7;
++		break;
++	}
++
++	au_writel(cmd->arg, HOST_CMDARG(host));
++	au_sync();
++
++	if (wait)
++		IRQ_OFF(host, SD_CONFIG_CR);
++
++	au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
++	au_sync();
++
++	/* Wait for the command to go on the line */
++
++	while(1) {
++		if (!(au_readl(HOST_CMD(host)) & SD_CMD_GO))
++			break;
++	}
++
++	/* Wait for the command to come back */
++
++	if (wait) {
++		u32 status = au_readl(HOST_STATUS(host));
++
++		while(!(status & SD_STATUS_CR))
++			status = au_readl(HOST_STATUS(host));
++
++		/* Clear the CR status */
++		au_writel(SD_STATUS_CR, HOST_STATUS(host));
++
++		IRQ_ON(host, SD_CONFIG_CR);
++	}
++
++	return MMC_ERR_NONE;
++}
++
++static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
++{
++
++	struct mmc_request *mrq = host->mrq;
++	struct mmc_data *data;
++	u32 crc;
++
++	WARN_ON(host->status != HOST_S_DATA && host->status != HOST_S_STOP);
++
++	if (host->mrq == NULL)
++		return;
++
++	data = mrq->cmd->data;
++
++	if (status == 0)
++		status = au_readl(HOST_STATUS(host));
++
++	/* The transaction is really over when the SD_STATUS_DB bit is clear */
++
++	while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
++		status = au_readl(HOST_STATUS(host));
++
++	data->error = MMC_ERR_NONE;
++	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);
++
++        /* Process any errors */
++
++	crc = (status & (SD_STATUS_WC | SD_STATUS_RC));
++	if (host->flags & HOST_F_XMIT)
++		crc |= ((status & 0x07) == 0x02) ? 0 : 1;
++
++	if (crc)
++		data->error = MMC_ERR_BADCRC;
++
++	/* Clear the CRC bits */
++	au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));
++
++	data->bytes_xfered = 0;
++
++	if (data->error == MMC_ERR_NONE) {
++		if (host->flags & HOST_F_DMA) {
++			u32 chan = DMA_CHANNEL(host);
++
++			chan_tab_t *c = *((chan_tab_t **) chan);
++			au1x_dma_chan_t *cp = c->chan_ptr;
++			data->bytes_xfered = cp->ddma_bytecnt;
++		}
++		else
++			data->bytes_xfered =
++				(data->blocks * (1 << data->blksz_bits)) -
++				host->pio.len;
++	}
++
++	au1xmmc_finish_request(host);
++}
++
++static void au1xmmc_tasklet_data(unsigned long param)
++{
++	struct au1xmmc_host *host = (struct au1xmmc_host *) param;
++
++	u32 status = au_readl(HOST_STATUS(host));
++	au1xmmc_data_complete(host, status);
++}
++
++#define AU1XMMC_MAX_TRANSFER 8
++
++static void au1xmmc_send_pio(struct au1xmmc_host *host)
++{
++
++	struct mmc_data *data = 0;
++	int sg_len, max, count = 0;
++	unsigned char *sg_ptr;
++	u32 status = 0;
++	struct scatterlist *sg;
++
++	data = host->mrq->data;
++
++	if (!(host->flags & HOST_F_XMIT))
++		return;
++
++	/* This is the pointer to the data buffer */
++	sg = &data->sg[host->pio.index];
++	sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
++
++	/* This is the space left inside the buffer */
++	sg_len = data->sg[host->pio.index].length - host->pio.offset;
++
++	/* Check to if we need less then the size of the sg_buffer */
++
++	max = (sg_len > host->pio.len) ? host->pio.len : sg_len;
++	if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER;
++
++	for(count = 0; count < max; count++ ) {
++		unsigned char val;
++
++		status = au_readl(HOST_STATUS(host));
++
++		if (!(status & SD_STATUS_TH))
++			break;
++
++		val = *sg_ptr++;
++
++		au_writel((unsigned long) val, HOST_TXPORT(host));
++		au_sync();
++	}
++
++	host->pio.len -= count;
++	host->pio.offset += count;
++
++	if (count == sg_len) {
++		host->pio.index++;
++		host->pio.offset = 0;
++	}
++
++	if (host->pio.len == 0) {
++		IRQ_OFF(host, SD_CONFIG_TH);
++
++		if (host->flags & HOST_F_STOP)
++			SEND_STOP(host);
++
++		tasklet_schedule(&host->data_task);
++	}
++}
++
++static void au1xmmc_receive_pio(struct au1xmmc_host *host)
++{
++
++	struct mmc_data *data = 0;
++	int sg_len = 0, max = 0, count = 0;
++	unsigned char *sg_ptr = 0;
++	u32 status = 0;
++	struct scatterlist *sg;
++
++	data = host->mrq->data;
++
++	if (!(host->flags & HOST_F_RECV))
++		return;
++
++	max = host->pio.len;
++
++	if (host->pio.index < host->dma.len) {
++		sg = &data->sg[host->pio.index];
++		sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
++
++		/* This is the space left inside the buffer */
++		sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
++
++		/* Check to if we need less then the size of the sg_buffer */
++		if (sg_len < max) max = sg_len;
++	}
++
++	if (max > AU1XMMC_MAX_TRANSFER)
++		max = AU1XMMC_MAX_TRANSFER;
++
++	for(count = 0; count < max; count++ ) {
++		u32 val;
++		status = au_readl(HOST_STATUS(host));
++
++		if (!(status & SD_STATUS_NE))
++			break;
++
++		if (status & SD_STATUS_RC) {
++			DEBUG("RX CRC Error [%d + %d].\n", host->id,
++					host->pio.len, count);
++			break;
++		}
++
++		if (status & SD_STATUS_RO) {
++			DEBUG("RX Overrun [%d + %d]\n", host->id,
++					host->pio.len, count);
++			break;
++		}
++		else if (status & SD_STATUS_RU) {
++			DEBUG("RX Underrun [%d + %d]\n", host->id,
++					host->pio.len,	count);
++			break;
++		}
++
++		val = au_readl(HOST_RXPORT(host));
++
++		if (sg_ptr)
++			*sg_ptr++ = (unsigned char) (val & 0xFF);
++	}
++
++	host->pio.len -= count;
++	host->pio.offset += count;
++
++	if (sg_len && count == sg_len) {
++		host->pio.index++;
++		host->pio.offset = 0;
++	}
++
++	if (host->pio.len == 0) {
++		//IRQ_OFF(host, SD_CONFIG_RA | SD_CONFIG_RF);
++		IRQ_OFF(host, SD_CONFIG_NE);
++
++		if (host->flags & HOST_F_STOP)
++			SEND_STOP(host);
++
++		tasklet_schedule(&host->data_task);
++	}
++}
++
++/* static void au1xmmc_cmd_complete
++   This is called when a command has been completed - grab the response
++   and check for errors.  Then start the data transfer if it is indicated.
++*/
++
++static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
++{
++
++	struct mmc_request *mrq = host->mrq;
++	struct mmc_command *cmd;
++	int trans;
++
++	if (!host->mrq)
++		return;
++
++	cmd = mrq->cmd;
++	cmd->error = MMC_ERR_NONE;
++
++	if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) {
++
++		/* Techincally, we should be getting all 48 bits of the response
++		 * (SD_RESP1 + SD_RESP2), but because our response omits the CRC,
++		 * our data ends up being shifted 8 bits to the right.  In this case,
++		 * that means that the OSR data starts at bit 31, so we can just
++		 * read RESP0 and return that
++		 */
++
++		cmd->resp[0] = au_readl(host->iobase + SD_RESP0);
++	}
++	else if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_LONG) {
++		u32 r[4];
++		int i;
++
++		r[0] = au_readl(host->iobase + SD_RESP3);
++		r[1] = au_readl(host->iobase + SD_RESP2);
++		r[2] = au_readl(host->iobase + SD_RESP1);
++		r[3] = au_readl(host->iobase + SD_RESP0);
++
++		/* The CRC is omitted from the response, so really we only got
++		 * 120 bytes, but the engine expects 128 bits, so we have to shift
++		 * things up
++		 */
++
++		for(i = 0; i < 4; i++) {
++			cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
++			if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24;
++		}
++	}
++
++        /* Figure out errors */
++
++	if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC))
++		cmd->error = MMC_ERR_BADCRC;
++
++	trans = host->flags & (HOST_F_XMIT | HOST_F_RECV);
++
++	if (!trans || cmd->error != MMC_ERR_NONE) {
++
++		IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF);
++		tasklet_schedule(&host->finish_task);
++		return;
++	}
++
++	host->status = HOST_S_DATA;
++
++	if (host->flags & HOST_F_DMA) {
++		u32 channel = DMA_CHANNEL(host);
++
++		/* Start the DMA as soon as the buffer gets something in it */
++
++		if (host->flags & HOST_F_RECV) {
++			u32 mask = SD_STATUS_DB | SD_STATUS_NE;
++
++			while((status & mask) != mask)
++				status = au_readl(HOST_STATUS(host));
++		}
++
++		au1xxx_dbdma_start(channel);
++	}
++}
++
++static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate)
++{
++
++	unsigned int pbus = get_au1x00_speed();
++	unsigned int divisor;
++	u32 config;
++
++	/* From databook:
++	   divisor = ((((cpuclock / sbus_divisor) / 2) / mmcclock) / 2) - 1
++	*/
++
++	pbus /= ((au_readl(SYS_POWERCTRL) & 0x3) + 2);
++	pbus /= 2;
++
++	divisor = ((pbus / rate) / 2) - 1;
++
++	config = au_readl(HOST_CONFIG(host));
++
++	config &= ~(SD_CONFIG_DIV);
++	config |= (divisor & SD_CONFIG_DIV) | SD_CONFIG_DE;
++
++	au_writel(config, HOST_CONFIG(host));
++	au_sync();
++}
++
++static int
++au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
++{
++
++	int datalen = data->blocks * (1 << data->blksz_bits);
++
++	if (dma != 0)
++		host->flags |= HOST_F_DMA;
++
++	if (data->flags & MMC_DATA_READ)
++		host->flags |= HOST_F_RECV;
++	else
++		host->flags |= HOST_F_XMIT;
++
++	if (host->mrq->stop)
++		host->flags |= HOST_F_STOP;
++
++	host->dma.dir = DMA_BIDIRECTIONAL;
++
++	host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg,
++				   data->sg_len, host->dma.dir);
++
++	if (host->dma.len == 0)
++		return MMC_ERR_TIMEOUT;
++
++	au_writel((1 << data->blksz_bits) - 1, HOST_BLKSIZE(host));
++
++	if (host->flags & HOST_F_DMA) {
++		int i;
++		u32 channel = DMA_CHANNEL(host);
++
++		au1xxx_dbdma_stop(channel);
++
++		for(i = 0; i < host->dma.len; i++) {
++			u32 ret = 0, flags = DDMA_FLAGS_NOIE;
++			struct scatterlist *sg = &data->sg[i];
++			int sg_len = sg->length;
++
++			int len = (datalen > sg_len) ? sg_len : datalen;
++
++			if (i == host->dma.len - 1)
++				flags = DDMA_FLAGS_IE;
++
++    			if (host->flags & HOST_F_XMIT){
++      				ret = au1xxx_dbdma_put_source_flags(channel,
++					(void *) (page_address(sg->page) +
++						  sg->offset),
++					len, flags);
++			}
++    			else {
++      				ret = au1xxx_dbdma_put_dest_flags(channel,
++					(void *) (page_address(sg->page) +
++						  sg->offset),
++					len, flags);
++			}
++
++    			if (!ret)
++				goto dataerr;
++
++			datalen -= len;
++		}
++	}
++	else {
++		host->pio.index = 0;
++		host->pio.offset = 0;
++		host->pio.len = datalen;
++
++		if (host->flags & HOST_F_XMIT)
++			IRQ_ON(host, SD_CONFIG_TH);
++		else
++			IRQ_ON(host, SD_CONFIG_NE);
++			//IRQ_ON(host, SD_CONFIG_RA|SD_CONFIG_RF);
++	}
++
++	return MMC_ERR_NONE;
++
++ dataerr:
++	dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir);
++	return MMC_ERR_TIMEOUT;
++}
++
++/* static void au1xmmc_request
++   This actually starts a command or data transaction
++*/
++
++static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
++{
++
++	struct au1xmmc_host *host = mmc_priv(mmc);
++	int ret = MMC_ERR_NONE;
++
++	WARN_ON(irqs_disabled());
++	WARN_ON(host->status != HOST_S_IDLE);
++
++	host->mrq = mrq;
++	host->status = HOST_S_CMD;
++
++	bcsr->disk_leds &= ~(1 << 8);
++
++	if (mrq->data) {
++		FLUSH_FIFO(host);
++		ret = au1xmmc_prepare_data(host, mrq->data);
++	}
++
++	if (ret == MMC_ERR_NONE)
++		ret = au1xmmc_send_command(host, 0, mrq->cmd);
++
++	if (ret != MMC_ERR_NONE) {
++		mrq->cmd->error = ret;
++		au1xmmc_finish_request(host);
++	}
++}
++
++static void au1xmmc_reset_controller(struct au1xmmc_host *host)
++{
++
++	/* Apply the clock */
++	au_writel(SD_ENABLE_CE, HOST_ENABLE(host));
++        au_sync_delay(1);
++
++	au_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host));
++	au_sync_delay(5);
++
++	au_writel(~0, HOST_STATUS(host));
++	au_sync();
++
++	au_writel(0, HOST_BLKSIZE(host));
++	au_writel(0x001fffff, HOST_TIMEOUT(host));
++	au_sync();
++
++	au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
++        au_sync();
++
++	au_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host));
++	au_sync_delay(1);
++
++	au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
++	au_sync();
++
++	/* Configure interrupts */
++	au_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host));
++	au_sync();
++}
++
++
++static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
++{
++	struct au1xmmc_host *host = mmc_priv(mmc);
++
++	DEBUG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n",
++	      host->id, ios->power_mode, ios->clock, ios->vdd,
++	      ios->bus_mode);
++
++	if (ios->power_mode == MMC_POWER_OFF)
++		au1xmmc_set_power(host, 0);
++	else if (ios->power_mode == MMC_POWER_ON) {
++		au1xmmc_set_power(host, 1);
++	}
++
++	if (ios->clock && ios->clock != host->clock) {
++		au1xmmc_set_clock(host, ios->clock);
++		host->clock = ios->clock;
++	}
++}
++
++static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id;
++	u32 status;
++
++	/* Avoid spurious interrupts */
++
++	if (!host->mrq)
++		return;
++
++	if (host->flags & HOST_F_STOP)
++		SEND_STOP(host);
++
++	tasklet_schedule(&host->data_task);
++}
++
++#define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT)
++#define STATUS_DATA_IN  (SD_STATUS_NE)
++#define STATUS_DATA_OUT (SD_STATUS_TH)
++
++static irqreturn_t au1xmmc_irq(int irq, void *dev_id, struct pt_regs *regs)
++{
++
++	u32 status;
++	int i, ret = 0;
++
++	disable_irq(AU1100_SD_IRQ);
++
++	for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
++		struct au1xmmc_host * host = au1xmmc_hosts[i];
++		u32 handled = 1;
++
++		status = au_readl(HOST_STATUS(host));
++
++		if (host->mrq && (status & STATUS_TIMEOUT)) {
++			if (status & SD_STATUS_RAT)
++				host->mrq->cmd->error = MMC_ERR_TIMEOUT;
++
++			else if (status & SD_STATUS_DT)
++				host->mrq->data->error = MMC_ERR_TIMEOUT;
++
++			/* In PIO mode, interrupts might still be enabled */
++			IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);
++
++			//IRQ_OFF(host, SD_CONFIG_TH|SD_CONFIG_RA|SD_CONFIG_RF);
++			tasklet_schedule(&host->finish_task);
++		}
++#if 0
++		else if (status & SD_STATUS_DD) {
++
++			/* Sometimes we get a DD before a NE in PIO mode */
++
++			if (!(host->flags & HOST_F_DMA) &&
++					(status & SD_STATUS_NE))
++				au1xmmc_receive_pio(host);
++			else {
++				au1xmmc_data_complete(host, status);
++				//tasklet_schedule(&host->data_task);
++			}
++		}
++#endif
++		else if (status & (SD_STATUS_CR)) {
++			if (host->status == HOST_S_CMD)
++				au1xmmc_cmd_complete(host,status);
++		}
++		else if (!(host->flags & HOST_F_DMA)) {
++			if ((host->flags & HOST_F_XMIT) &&
++			    (status & STATUS_DATA_OUT))
++				au1xmmc_send_pio(host);
++			else if ((host->flags & HOST_F_RECV) &&
++			    (status & STATUS_DATA_IN))
++				au1xmmc_receive_pio(host);
++		}
++		else if (status & 0x203FBC70) {
++			DEBUG("Unhandled status %8.8x\n", host->id, status);
++			handled = 0;
++		}
++
++		au_writel(status, HOST_STATUS(host));
++		au_sync();
++
++		ret |= handled;
++	}
++
++	enable_irq(AU1100_SD_IRQ);
++	return ret;
++}
++
++static void au1xmmc_poll_event(unsigned long arg)
++{
++	struct au1xmmc_host *host = (struct au1xmmc_host *) arg;
++
++	int card = au1xmmc_card_inserted(host);
++        int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0;
++
++	if (card != controller) {
++		host->flags &= ~HOST_F_ACTIVE;
++		if (card) host->flags |= HOST_F_ACTIVE;
++		mmc_detect_change(host->mmc, 0);
++	}
++
++	if (host->mrq != NULL) {
++		u32 status = au_readl(HOST_STATUS(host));
++		DEBUG("PENDING - %8.8x\n", host->id, status);
++	}
++
++	mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT);
++}
++
++static dbdev_tab_t au1xmmc_mem_dbdev =
++{
++	DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 8, 0x00000000, 0, 0
++};
++
++static void au1xmmc_init_dma(struct au1xmmc_host *host)
++{
++
++	u32 rxchan, txchan;
++
++	int txid = au1xmmc_card_table[host->id].tx_devid;
++	int rxid = au1xmmc_card_table[host->id].rx_devid;
++
++	/* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride
++	   of 8 bits.  And since devices are shared, we need to create
++	   our own to avoid freaking out other devices
++	*/
++
++	int memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev);
++
++	txchan = au1xxx_dbdma_chan_alloc(memid, txid,
++					 au1xmmc_dma_callback, (void *) host);
++
++	rxchan = au1xxx_dbdma_chan_alloc(rxid, memid,
++					 au1xmmc_dma_callback, (void *) host);
++
++	au1xxx_dbdma_set_devwidth(txchan, 8);
++	au1xxx_dbdma_set_devwidth(rxchan, 8);
++
++	au1xxx_dbdma_ring_alloc(txchan, AU1XMMC_DESCRIPTOR_COUNT);
++	au1xxx_dbdma_ring_alloc(rxchan, AU1XMMC_DESCRIPTOR_COUNT);
++
++	host->tx_chan = txchan;
++	host->rx_chan = rxchan;
++}
++
++struct mmc_host_ops au1xmmc_ops = {
++	.request	= au1xmmc_request,
++	.set_ios	= au1xmmc_set_ios,
++};
++
++static int au1xmmc_probe(struct device *dev)
++{
++
++	int i, ret = 0;
++
++	/* THe interrupt is shared among all controllers */
++	ret = request_irq(AU1100_SD_IRQ, au1xmmc_irq, SA_INTERRUPT, "MMC", 0);
++
++	if (ret) {
++		printk(DRIVER_NAME "ERROR: Couldn't get int %d: %d\n",
++				AU1100_SD_IRQ, ret);
++		return -ENXIO;
++	}
++
++	disable_irq(AU1100_SD_IRQ);
++
++	for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
++		struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), dev);
++		struct au1xmmc_host *host = 0;
++
++		if (!mmc) {
++			printk(DRIVER_NAME "ERROR: no mem for host %d\n", i);
++			au1xmmc_hosts[i] = 0;
++			continue;
++		}
++
++		mmc->ops = &au1xmmc_ops;
++
++		mmc->f_min =   450000;
++		mmc->f_max = 24000000;
++
++		mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE;
++		mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
++
++		mmc->ocr_avail = AU1XMMC_OCR;
++
++		host = mmc_priv(mmc);
++		host->mmc = mmc;
++
++		host->id = i;
++		host->iobase = au1xmmc_card_table[host->id].iobase;
++		host->clock = 0;
++		host->power_mode = MMC_POWER_OFF;
++
++		host->flags = au1xmmc_card_inserted(host) ? HOST_F_ACTIVE : 0;
++		host->status = HOST_S_IDLE;
++
++		init_timer(&host->timer);
++
++		host->timer.function = au1xmmc_poll_event;
++		host->timer.data = (unsigned long) host;
++		host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT;
++
++		tasklet_init(&host->data_task, au1xmmc_tasklet_data,
++				(unsigned long) host);
++
++		tasklet_init(&host->finish_task, au1xmmc_tasklet_finish,
++				(unsigned long) host);
++
++		spin_lock_init(&host->lock);
++
++		if (dma != 0)
++			au1xmmc_init_dma(host);
++
++		au1xmmc_reset_controller(host);
++
++		mmc_add_host(mmc);
++		au1xmmc_hosts[i] = host;
++
++		add_timer(&host->timer);
++
++		printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X (mode=%s)\n",
++		       host->id, host->iobase, dma ? "dma" : "pio");
++	}
++
++	enable_irq(AU1100_SD_IRQ);
++
++	return 0;
++}
++
++static int au1xmmc_remove(struct device *dev)
++{
++
++	int i;
++
++	disable_irq(AU1100_SD_IRQ);
++
++	for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
++		struct au1xmmc_host *host = au1xmmc_hosts[i];
++		if (!host) continue;
++
++		tasklet_kill(&host->data_task);
++		tasklet_kill(&host->finish_task);
++
++		del_timer_sync(&host->timer);
++		au1xmmc_set_power(host, 0);
++
++		mmc_remove_host(host->mmc);
++
++		au1xxx_dbdma_chan_free(host->tx_chan);
++		au1xxx_dbdma_chan_free(host->rx_chan);
++
++		au_writel(0x0, HOST_ENABLE(host));
++		au_sync();
++	}
++
++	free_irq(AU1100_SD_IRQ, 0);
++	return 0;
++}
++
++static struct device_driver au1xmmc_driver = {
++	.name          = DRIVER_NAME,
++	.bus           = &platform_bus_type,
++	.probe         = au1xmmc_probe,
++	.remove        = au1xmmc_remove,
++	.suspend       = NULL,
++	.resume        = NULL
++};
++
++static int __init au1xmmc_init(void)
++{
++	return driver_register(&au1xmmc_driver);
++}
++
++static void __exit au1xmmc_exit(void)
++{
++	driver_unregister(&au1xmmc_driver);
++}
++
++module_init(au1xmmc_init);
++module_exit(au1xmmc_exit);
++
++#ifdef MODULE
++MODULE_AUTHOR("Advanced Micro Devices, Inc");
++MODULE_DESCRIPTION("MMC/SD driver for the Alchemy Au1XXX");
++MODULE_LICENSE("GPL");
++#endif
++
+diff --git a/drivers/mmc/au1xmmc.h b/drivers/mmc/au1xmmc.h
+new file mode 100644
+--- /dev/null
++++ b/drivers/mmc/au1xmmc.h
+@@ -0,0 +1,96 @@
++#ifndef _AU1XMMC_H_
++#define _AU1XMMC_H_
++
++/* Hardware definitions */
++
++#define AU1XMMC_DESCRIPTOR_COUNT 1
++#define AU1XMMC_DESCRIPTOR_SIZE  2048
++
++#define AU1XMMC_OCR ( MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30  | \
++		      MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33  | \
++		      MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36)
++
++/* Easy access macros */
++
++#define HOST_STATUS(h)	((h)->iobase + SD_STATUS)
++#define HOST_CONFIG(h)	((h)->iobase + SD_CONFIG)
++#define HOST_ENABLE(h)	((h)->iobase + SD_ENABLE)
++#define HOST_TXPORT(h)	((h)->iobase + SD_TXPORT)
++#define HOST_RXPORT(h)	((h)->iobase + SD_RXPORT)
++#define HOST_CMDARG(h)	((h)->iobase + SD_CMDARG)
++#define HOST_BLKSIZE(h)	((h)->iobase + SD_BLKSIZE)
++#define HOST_CMD(h)	((h)->iobase + SD_CMD)
++#define HOST_CONFIG2(h)	((h)->iobase + SD_CONFIG2)
++#define HOST_TIMEOUT(h)	((h)->iobase + SD_TIMEOUT)
++#define HOST_DEBUG(h)	((h)->iobase + SD_DEBUG)
++
++#define DMA_CHANNEL(h) \
++	( ((h)->flags & HOST_F_XMIT) ? (h)->tx_chan : (h)->rx_chan)
++
++/* This gives us a hard value for the stop command that we can write directly
++ * to the command register
++ */
++
++#define STOP_CMD (SD_CMD_RT_1B|SD_CMD_CT_7|(0xC << SD_CMD_CI_SHIFT)|SD_CMD_GO)
++
++/* This is the set of interrupts that we configure by default */
++
++#if 0
++#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | SD_CONFIG_DD | \
++		SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
++#endif
++
++#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | \
++		SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
++/* The poll event (looking for insert/remove events runs twice a second */
++#define AU1XMMC_DETECT_TIMEOUT (HZ/2)
++
++struct au1xmmc_host {
++  struct mmc_host *mmc;
++  struct mmc_request *mrq;
++
++  u32 id;
++
++  u32 flags;
++  u32 iobase;
++  u32 clock;
++  u32 bus_width;
++  u32 power_mode;
++
++  int status;
++
++   struct {
++	   int len;
++	   int dir;
++  } dma;
++
++   struct {
++	   int index;
++	   int offset;
++	   int len;
++  } pio;
++
++  u32 tx_chan;
++  u32 rx_chan;
++
++  struct timer_list timer;
++  struct tasklet_struct finish_task;
++  struct tasklet_struct data_task;
++
++  spinlock_t lock;
++};
++
++/* Status flags used by the host structure */
++
++#define HOST_F_XMIT   0x0001
++#define HOST_F_RECV   0x0002
++#define HOST_F_DMA    0x0010
++#define HOST_F_ACTIVE 0x0100
++#define HOST_F_STOP   0x1000
++
++#define HOST_S_IDLE   0x0001
++#define HOST_S_CMD    0x0002
++#define HOST_S_DATA   0x0003
++#define HOST_S_STOP   0x0004
++
++#endif
+diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
+--- a/drivers/mmc/mmc_block.c
++++ b/drivers/mmc/mmc_block.c
+@@ -85,6 +85,12 @@ static void mmc_blk_put(struct mmc_blk_d
+ 	up(&open_lock);
+ }
+ 
++static inline int mmc_blk_readonly(struct mmc_card *card)
++{
++	return mmc_card_readonly(card) ||
++	       !(card->csd.cmdclass & CCC_BLOCK_WRITE);
++}
++
+ static int mmc_blk_open(struct inode *inode, struct file *filp)
+ {
+ 	struct mmc_blk_data *md;
+@@ -97,7 +103,7 @@ static int mmc_blk_open(struct inode *in
+ 		ret = 0;
+ 
+ 		if ((filp->f_mode & FMODE_WRITE) &&
+-			mmc_card_readonly(md->queue.card))
++			mmc_blk_readonly(md->queue.card))
+ 			ret = -EROFS;
+ 	}
+ 
+@@ -410,7 +416,7 @@ static int mmc_blk_probe(struct mmc_card
+ 	printk(KERN_INFO "%s: %s %s %dKiB %s\n",
+ 		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
+ 		(card->csd.capacity << card->csd.read_blkbits) / 1024,
+-		mmc_card_readonly(card)?"(ro)":"");
++		mmc_blk_readonly(card)?"(ro)":"");
+ 
+ 	mmc_set_drvdata(card, md);
+ 	add_disk(md->disk);
+diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
+--- a/drivers/mmc/mmci.c
++++ b/drivers/mmc/mmci.c
+@@ -24,6 +24,7 @@
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/scatterlist.h>
++#include <asm/sizes.h>
+ #include <asm/hardware/amba.h>
+ #include <asm/hardware/clock.h>
+ #include <asm/mach/mmc.h>
+diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
+--- a/drivers/mmc/pxamci.c
++++ b/drivers/mmc/pxamci.c
+@@ -20,7 +20,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+ #include <linux/dma-mapping.h>
+@@ -29,7 +29,6 @@
+ 
+ #include <asm/dma.h>
+ #include <asm/io.h>
+-#include <asm/irq.h>
+ #include <asm/scatterlist.h>
+ #include <asm/sizes.h>
+ 
+@@ -571,23 +570,23 @@ static int pxamci_remove(struct device *
+ }
+ 
+ #ifdef CONFIG_PM
+-static int pxamci_suspend(struct device *dev, pm_message_t state, u32 level)
++static int pxamci_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct mmc_host *mmc = dev_get_drvdata(dev);
+ 	int ret = 0;
+ 
+-	if (mmc && level == SUSPEND_DISABLE)
++	if (mmc)
+ 		ret = mmc_suspend_host(mmc, state);
+ 
+ 	return ret;
+ }
+ 
+-static int pxamci_resume(struct device *dev, u32 level)
++static int pxamci_resume(struct device *dev)
+ {
+ 	struct mmc_host *mmc = dev_get_drvdata(dev);
+ 	int ret = 0;
+ 
+-	if (mmc && level == RESUME_ENABLE)
++	if (mmc)
+ 		ret = mmc_resume_host(mmc);
+ 
+ 	return ret;
+diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
+--- a/drivers/mmc/wbsd.c
++++ b/drivers/mmc/wbsd.c
+@@ -26,7 +26,7 @@
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/delay.h>
+@@ -1033,13 +1033,16 @@ static void wbsd_set_ios(struct mmc_host
+ 	}
+ 	else
+ 	{
+-		setup &= ~WBSD_DAT3_H;
++		if (setup & WBSD_DAT3_H)
++		{
++			setup &= ~WBSD_DAT3_H;
+ 
+-		/*
+-		 * We cannot resume card detection immediatly
+-		 * because of capacitance and delays in the chip.
+-		 */
+-		mod_timer(&host->ignore_timer, jiffies + HZ/100);
++			/*
++			 * We cannot resume card detection immediatly
++			 * because of capacitance and delays in the chip.
++			 */
++			mod_timer(&host->ignore_timer, jiffies + HZ/100);
++		}
+ 	}
+ 	wbsd_write_index(host, WBSD_IDX_SETUP, setup);
+ 
+@@ -1461,8 +1464,10 @@ static int __devinit wbsd_scan(struct wb
+ 		{
+ 			id = 0xFFFF;
+ 
+-			outb(unlock_codes[j], config_ports[i]);
+-			outb(unlock_codes[j], config_ports[i]);
++			host->config = config_ports[i];
++			host->unlock_code = unlock_codes[j];
++
++			wbsd_unlock_config(host);
+ 
+ 			outb(WBSD_CONF_ID_HI, config_ports[i]);
+ 			id = inb(config_ports[i] + 1) << 8;
+@@ -1470,13 +1475,13 @@ static int __devinit wbsd_scan(struct wb
+ 			outb(WBSD_CONF_ID_LO, config_ports[i]);
+ 			id |= inb(config_ports[i] + 1);
+ 
++			wbsd_lock_config(host);
++
+ 			for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++)
+ 			{
+ 				if (id == valid_ids[k])
+ 				{
+ 					host->chip_id = id;
+-					host->config = config_ports[i];
+-					host->unlock_code = unlock_codes[i];
+ 
+ 					return 0;
+ 				}
+@@ -1487,13 +1492,14 @@ static int __devinit wbsd_scan(struct wb
+ 				DBG("Unknown hardware (id %x) found at %x\n",
+ 					id, config_ports[i]);
+ 			}
+-
+-			outb(LOCK_CODE, config_ports[i]);
+ 		}
+ 
+ 		release_region(config_ports[i], 2);
+ 	}
+ 
++	host->config = 0;
++	host->unlock_code = 0;
++
+ 	return -ENODEV;
+ }
+ 
+@@ -1699,8 +1705,10 @@ static void __devexit wbsd_release_resou
+  * Configure the resources the chip should use.
+  */
+ 
+-static void __devinit wbsd_chip_config(struct wbsd_host* host)
++static void wbsd_chip_config(struct wbsd_host* host)
+ {
++	wbsd_unlock_config(host);
++
+ 	/*
+ 	 * Reset the chip.
+ 	 */
+@@ -1733,16 +1741,20 @@ static void __devinit wbsd_chip_config(s
+ 	 */
+ 	wbsd_write_config(host, WBSD_CONF_ENABLE, 1);
+ 	wbsd_write_config(host, WBSD_CONF_POWER, 0x20);
++
++	wbsd_lock_config(host);
+ }
+ 
+ /*
+  * Check that configured resources are correct.
+  */
+ 
+-static int __devinit wbsd_chip_validate(struct wbsd_host* host)
++static int wbsd_chip_validate(struct wbsd_host* host)
+ {
+ 	int base, irq, dma;
+ 
++	wbsd_unlock_config(host);
++
+ 	/*
+ 	 * Select SD/MMC function.
+ 	 */
+@@ -1758,6 +1770,8 @@ static int __devinit wbsd_chip_validate(
+ 
+ 	dma = wbsd_read_config(host, WBSD_CONF_DRQ);
+ 
++	wbsd_lock_config(host);
++
+ 	/*
+ 	 * Validate against given configuration.
+ 	 */
+@@ -1771,6 +1785,20 @@ static int __devinit wbsd_chip_validate(
+ 	return 1;
+ }
+ 
++/*
++ * Powers down the SD function
++ */
++
++static void wbsd_chip_poweroff(struct wbsd_host* host)
++{
++	wbsd_unlock_config(host);
++
++	wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
++	wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
++
++	wbsd_lock_config(host);
++}
++
+ /*****************************************************************************\
+  *                                                                           *
+  * Devices setup and shutdown                                                *
+@@ -1844,7 +1872,11 @@ static int __devinit wbsd_init(struct de
+ 	 */
+ #ifdef CONFIG_PM
+ 	if (host->config)
++	{
++		wbsd_unlock_config(host);
+ 		wbsd_write_config(host, WBSD_CONF_PME, 0xA0);
++		wbsd_lock_config(host);
++	}
+ #endif
+ 	/*
+ 	 * Allow device to initialise itself properly.
+@@ -1885,16 +1917,11 @@ static void __devexit wbsd_shutdown(stru
+ 
+ 	mmc_remove_host(mmc);
+ 
++	/*
++	 * Power down the SD/MMC function.
++	 */
+ 	if (!pnp)
+-	{
+-		/*
+-		 * Power down the SD/MMC function.
+-		 */
+-		wbsd_unlock_config(host);
+-		wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
+-		wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
+-		wbsd_lock_config(host);
+-	}
++		wbsd_chip_poweroff(host);
+ 
+ 	wbsd_release_resources(host);
+ 
+@@ -1955,23 +1982,59 @@ static void __devexit wbsd_pnp_remove(st
+  */
+ 
+ #ifdef CONFIG_PM
+-static int wbsd_suspend(struct device *dev, pm_message_t state, u32 level)
++
++static int wbsd_suspend(struct device *dev, pm_message_t state)
+ {
+-	DBGF("Not yet supported\n");
++	struct mmc_host *mmc = dev_get_drvdata(dev);
++	struct wbsd_host *host;
++	int ret;
++
++	if (!mmc)
++		return 0;
++
++	DBG("Suspending...\n");
++
++	ret = mmc_suspend_host(mmc, state);
++	if (!ret)
++		return ret;
++
++	host = mmc_priv(mmc);
++
++	wbsd_chip_poweroff(host);
+ 
+ 	return 0;
+ }
+ 
+-static int wbsd_resume(struct device *dev, u32 level)
++static int wbsd_resume(struct device *dev)
+ {
+-	DBGF("Not yet supported\n");
++	struct mmc_host *mmc = dev_get_drvdata(dev);
++	struct wbsd_host *host;
+ 
+-	return 0;
++	if (!mmc)
++		return 0;
++
++	DBG("Resuming...\n");
++
++	host = mmc_priv(mmc);
++
++	wbsd_chip_config(host);
++
++	/*
++	 * Allow device to initialise itself properly.
++	 */
++	mdelay(5);
++
++	wbsd_init_device(host);
++
++	return mmc_resume_host(mmc);
+ }
+-#else
++
++#else /* CONFIG_PM */
++
+ #define wbsd_suspend NULL
+ #define wbsd_resume NULL
+-#endif
++
++#endif /* CONFIG_PM */
+ 
+ static struct platform_device *wbsd_device;
+ 
+diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
+--- a/drivers/mtd/chips/jedec.c
++++ b/drivers/mtd/chips/jedec.c
+@@ -17,6 +17,7 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
++#include <linux/slab.h>
+ #include <linux/mtd/jedec.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/mtd.h>
+diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
+--- a/drivers/mtd/devices/lart.c
++++ b/drivers/mtd/devices/lart.c
+@@ -44,6 +44,7 @@
+ #include <linux/types.h>
+ #include <linux/init.h>
+ #include <linux/errno.h>
++#include <linux/string.h>
+ #include <linux/mtd/mtd.h>
+ #ifdef HAVE_PARTITIONS
+ #include <linux/mtd/partitions.h>
+diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
+--- a/drivers/mtd/devices/phram.c
++++ b/drivers/mtd/devices/phram.c
+@@ -22,6 +22,7 @@
+ #include <linux/list.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
++#include <linux/slab.h>
+ #include <linux/mtd/mtd.h>
+ 
+ #define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args)
+diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
+--- a/drivers/mtd/maps/bast-flash.c
++++ b/drivers/mtd/maps/bast-flash.c
+@@ -33,7 +33,8 @@
+ #include <linux/string.h>
+ #include <linux/ioport.h>
+ #include <linux/device.h>
+-
++#include <linux/slab.h>
++#include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
+--- a/drivers/mtd/maps/ceiva.c
++++ b/drivers/mtd/maps/ceiva.c
+@@ -20,6 +20,7 @@
+ #include <linux/ioport.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ 
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c
+--- a/drivers/mtd/maps/dc21285.c
++++ b/drivers/mtd/maps/dc21285.c
+@@ -13,6 +13,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
++#include <linux/slab.h>
+ 
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
+--- a/drivers/mtd/maps/dilnetpc.c
++++ b/drivers/mtd/maps/dilnetpc.c
+@@ -30,12 +30,15 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <asm/io.h>
++#include <linux/string.h>
++
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/mtd/concat.h>
+ 
++#include <asm/io.h>
++
+ /*
+ ** The DIL/NetPC keeps its BIOS in two distinct flash blocks.
+ ** Destroying any of these blocks transforms the DNPC into
+diff --git a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c
+--- a/drivers/mtd/maps/epxa10db-flash.c
++++ b/drivers/mtd/maps/epxa10db-flash.c
+@@ -27,12 +27,15 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <asm/io.h>
++#include <linux/slab.h>
++
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+ 
++#include <asm/io.h>
+ #include <asm/hardware.h>
++
+ #ifdef CONFIG_EPXA10DB
+ #define BOARD_NAME "EPXA10DB"
+ #else
+diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c
+--- a/drivers/mtd/maps/fortunet.c
++++ b/drivers/mtd/maps/fortunet.c
+@@ -7,11 +7,14 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <asm/io.h>
++#include <linux/string.h>
++
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+ 
++#include <asm/io.h>
++
+ #define MAX_NUM_REGIONS		4
+ #define MAX_NUM_PARTITIONS	8
+ 
+diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
+--- a/drivers/mtd/maps/integrator-flash.c
++++ b/drivers/mtd/maps/integrator-flash.c
+@@ -32,7 +32,7 @@
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/init.h>
+ 
+ #include <linux/mtd/mtd.h>
+diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
+--- a/drivers/mtd/maps/ixp2000.c
++++ b/drivers/mtd/maps/ixp2000.c
+@@ -22,11 +22,14 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+-#include <linux/ioport.h>
+-#include <linux/device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/hardware.h>
+diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
+--- a/drivers/mtd/maps/ixp4xx.c
++++ b/drivers/mtd/maps/ixp4xx.c
+@@ -20,11 +20,15 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+-#include <linux/ioport.h>
+-#include <linux/device.h>
++
+ #include <asm/io.h>
+ #include <asm/mach/flash.h>
+ 
+diff --git a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c
+--- a/drivers/mtd/maps/lubbock-flash.c
++++ b/drivers/mtd/maps/lubbock-flash.c
+@@ -15,10 +15,13 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
++
+ #include <linux/dma-mapping.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
++
+ #include <asm/io.h>
+ #include <asm/hardware.h>
+ #include <asm/arch/pxa-regs.h>
+diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
+--- a/drivers/mtd/maps/mainstone-flash.c
++++ b/drivers/mtd/maps/mainstone-flash.c
+@@ -16,9 +16,12 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/dma-mapping.h>
++#include <linux/slab.h>
++
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
++
+ #include <asm/io.h>
+ #include <asm/hardware.h>
+ #include <asm/arch/pxa-regs.h>
+diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c
+--- a/drivers/mtd/maps/omap-toto-flash.c
++++ b/drivers/mtd/maps/omap-toto-flash.c
+@@ -12,9 +12,9 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+-
+ #include <linux/errno.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ 
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
+--- a/drivers/mtd/maps/omap_nor.c
++++ b/drivers/mtd/maps/omap_nor.c
+@@ -30,12 +30,14 @@
+  * 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
++#include <linux/slab.h>
++
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
+--- a/drivers/mtd/maps/pci.c
++++ b/drivers/mtd/maps/pci.c
+@@ -17,6 +17,7 @@
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ 
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
+--- a/drivers/mtd/maps/plat-ram.c
++++ b/drivers/mtd/maps/plat-ram.c
+@@ -30,6 +30,8 @@
+ #include <linux/string.h>
+ #include <linux/ioport.h>
+ #include <linux/device.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
+ 
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
+--- a/drivers/mtd/maps/sa1100-flash.c
++++ b/drivers/mtd/maps/sa1100-flash.c
+@@ -13,7 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/slab.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/err.h>
+ 
+ #include <linux/mtd/mtd.h>
+@@ -21,6 +21,7 @@
+ #include <linux/mtd/partitions.h>
+ #include <linux/mtd/concat.h>
+ 
++#include <asm/hardware.h>
+ #include <asm/io.h>
+ #include <asm/sizes.h>
+ #include <asm/mach/flash.h>
+@@ -129,20 +130,21 @@ struct sa_subdev_info {
+ 	char name[16];
+ 	struct map_info map;
+ 	struct mtd_info *mtd;
+-	struct flash_platform_data *data;
++	struct flash_platform_data *plat;
+ };
+ 
+ struct sa_info {
+ 	struct mtd_partition	*parts;
+ 	struct mtd_info		*mtd;
+ 	int			num_subdev;
++	unsigned int		nr_parts;
+ 	struct sa_subdev_info	subdev[0];
+ };
+ 
+ static void sa1100_set_vpp(struct map_info *map, int on)
+ {
+ 	struct sa_subdev_info *subdev = container_of(map, struct sa_subdev_info, map);
+-	subdev->data->set_vpp(on);
++	subdev->plat->set_vpp(on);
+ }
+ 
+ static void sa1100_destroy_subdev(struct sa_subdev_info *subdev)
+@@ -186,7 +188,7 @@ static int sa1100_probe_subdev(struct sa
+ 		goto out;
+ 	}
+ 
+-	if (subdev->data->set_vpp)
++	if (subdev->plat->set_vpp)
+ 		subdev->map.set_vpp = sa1100_set_vpp;
+ 
+ 	subdev->map.phys = phys;
+@@ -203,7 +205,7 @@ static int sa1100_probe_subdev(struct sa
+ 	 * Now let's probe for the actual flash.  Do it here since
+ 	 * specific machine settings might have been set above.
+ 	 */
+-	subdev->mtd = do_map_probe(subdev->data->map_name, &subdev->map);
++	subdev->mtd = do_map_probe(subdev->plat->map_name, &subdev->map);
+ 	if (subdev->mtd == NULL) {
+ 		ret = -ENXIO;
+ 		goto err;
+@@ -222,13 +224,17 @@ static int sa1100_probe_subdev(struct sa
+ 	return ret;
+ }
+ 
+-static void sa1100_destroy(struct sa_info *info)
++static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *plat)
+ {
+ 	int i;
+ 
+ 	if (info->mtd) {
+-		del_mtd_partitions(info->mtd);
+-
++		if (info->nr_parts == 0)
++			del_mtd_device(info->mtd);
++#ifdef CONFIG_MTD_PARTITIONS
++		else
++			del_mtd_partitions(info->mtd);
++#endif
+ #ifdef CONFIG_MTD_CONCAT
+ 		if (info->mtd != info->subdev[0].mtd)
+ 			mtd_concat_destroy(info->mtd);
+@@ -241,10 +247,13 @@ static void sa1100_destroy(struct sa_inf
+ 	for (i = info->num_subdev - 1; i >= 0; i--)
+ 		sa1100_destroy_subdev(&info->subdev[i]);
+ 	kfree(info);
++
++	if (plat->exit)
++		plat->exit();
+ }
+ 
+ static struct sa_info *__init
+-sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash)
++sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
+ {
+ 	struct sa_info *info;
+ 	int nr, size, i, ret = 0;
+@@ -274,6 +283,12 @@ sa1100_setup_mtd(struct platform_device 
+ 
+ 	memset(info, 0, size);
+ 
++	if (plat->init) {
++		ret = plat->init();
++		if (ret)
++			goto err;
++	}
++
+ 	/*
+ 	 * Claim and then map the memory regions.
+ 	 */
+@@ -286,8 +301,8 @@ sa1100_setup_mtd(struct platform_device 
+ 			break;
+ 
+ 		subdev->map.name = subdev->name;
+-		sprintf(subdev->name, "sa1100-%d", i);
+-		subdev->data = flash;
++		sprintf(subdev->name, "%s-%d", plat->name, i);
++		subdev->plat = plat;
+ 
+ 		ret = sa1100_probe_subdev(subdev, res);
+ 		if (ret)
+@@ -308,7 +323,7 @@ sa1100_setup_mtd(struct platform_device 
+ 	 * otherwise fail.  Either way, it'll be called "sa1100".
+ 	 */
+ 	if (info->num_subdev == 1) {
+-		strcpy(info->subdev[0].name, "sa1100");
++		strcpy(info->subdev[0].name, plat->name);
+ 		info->mtd = info->subdev[0].mtd;
+ 		ret = 0;
+ 	} else if (info->num_subdev > 1) {
+@@ -321,7 +336,7 @@ sa1100_setup_mtd(struct platform_device 
+ 			cdev[i] = info->subdev[i].mtd;
+ 
+ 		info->mtd = mtd_concat_create(cdev, info->num_subdev,
+-					      "sa1100");
++					      plat->name);
+ 		if (info->mtd == NULL)
+ 			ret = -ENXIO;
+ #else
+@@ -335,7 +350,7 @@ sa1100_setup_mtd(struct platform_device 
+ 		return info;
+ 
+  err:
+-	sa1100_destroy(info);
++	sa1100_destroy(info, plat);
+  out:
+ 	return ERR_PTR(ret);
+ }
+@@ -345,16 +360,16 @@ static const char *part_probes[] = { "cm
+ static int __init sa1100_mtd_probe(struct device *dev)
+ {
+ 	struct platform_device *pdev = to_platform_device(dev);
+-	struct flash_platform_data *flash = pdev->dev.platform_data;
++	struct flash_platform_data *plat = pdev->dev.platform_data;
+ 	struct mtd_partition *parts;
+ 	const char *part_type = NULL;
+ 	struct sa_info *info;
+ 	int err, nr_parts = 0;
+ 
+-	if (!flash)
++	if (!plat)
+ 		return -ENODEV;
+ 
+-	info = sa1100_setup_mtd(pdev, flash);
++	info = sa1100_setup_mtd(pdev, plat);
+ 	if (IS_ERR(info)) {
+ 		err = PTR_ERR(info);
+ 		goto out;
+@@ -371,8 +386,8 @@ static int __init sa1100_mtd_probe(struc
+ 	} else
+ #endif
+ 	{
+-		parts = flash->parts;
+-		nr_parts = flash->nr_parts;
++		parts = plat->parts;
++		nr_parts = plat->nr_parts;
+ 		part_type = "static";
+ 	}
+ 
+@@ -386,6 +401,8 @@ static int __init sa1100_mtd_probe(struc
+ 		add_mtd_partitions(info->mtd, parts, nr_parts);
+ 	}
+ 
++	info->nr_parts = nr_parts;
++
+ 	dev_set_drvdata(dev, info);
+ 	err = 0;
+ 
+@@ -396,33 +413,44 @@ static int __init sa1100_mtd_probe(struc
+ static int __exit sa1100_mtd_remove(struct device *dev)
+ {
+ 	struct sa_info *info = dev_get_drvdata(dev);
++	struct flash_platform_data *plat = dev->platform_data;
++
+ 	dev_set_drvdata(dev, NULL);
+-	sa1100_destroy(info);
++	sa1100_destroy(info, plat);
++
+ 	return 0;
+ }
+ 
+ #ifdef CONFIG_PM
+-static int sa1100_mtd_suspend(struct device *dev, pm_message_t state, u32 level)
++static int sa1100_mtd_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct sa_info *info = dev_get_drvdata(dev);
+ 	int ret = 0;
+ 
+-	if (info && level == SUSPEND_SAVE_STATE)
++	if (info)
+ 		ret = info->mtd->suspend(info->mtd);
+ 
+ 	return ret;
+ }
+ 
+-static int sa1100_mtd_resume(struct device *dev, u32 level)
++static int sa1100_mtd_resume(struct device *dev)
+ {
+ 	struct sa_info *info = dev_get_drvdata(dev);
+-	if (info && level == RESUME_RESTORE_STATE)
++	if (info)
+ 		info->mtd->resume(info->mtd);
+ 	return 0;
+ }
++
++static void sa1100_mtd_shutdown(struct device *dev)
++{
++	struct sa_info *info = dev_get_drvdata(dev);
++	if (info && info->mtd->suspend(info->mtd) == 0)
++		info->mtd->resume(info->mtd);
++}
+ #else
+ #define sa1100_mtd_suspend NULL
+ #define sa1100_mtd_resume  NULL
++#define sa1100_mtd_shutdown NULL
+ #endif
+ 
+ static struct device_driver sa1100_mtd_driver = {
+@@ -432,6 +460,7 @@ static struct device_driver sa1100_mtd_d
+ 	.remove		= __exit_p(sa1100_mtd_remove),
+ 	.suspend	= sa1100_mtd_suspend,
+ 	.resume		= sa1100_mtd_resume,
++	.shutdown	= sa1100_mtd_shutdown,
+ };
+ 
+ static int __init sa1100_mtd_init(void)
+diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
+--- a/drivers/mtd/maps/tqm8xxl.c
++++ b/drivers/mtd/maps/tqm8xxl.c
+@@ -27,12 +27,14 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <asm/io.h>
++#include <linux/slab.h>
+ 
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+ 
++#include <asm/io.h>
++
+ #define FLASH_ADDR 0x40000000
+ #define FLASH_SIZE 0x00800000
+ #define FLASH_BANK_MAX 4
+diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
+--- a/drivers/mtd/mtdblock.c
++++ b/drivers/mtd/mtdblock.c
+@@ -15,6 +15,7 @@
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/vmalloc.h>
++#include <linux/sched.h>	/* TASK_* */
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/blktrans.h>
+ 
+diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
+--- a/drivers/mtd/mtdchar.c
++++ b/drivers/mtd/mtdchar.c
+@@ -13,6 +13,7 @@
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/fs.h>
++#include <linux/sched.h>	/* TASK_* */
+ #include <asm/uaccess.h>
+ 
+ #include <linux/device.h>
+@@ -24,10 +25,10 @@ static void mtd_notify_add(struct mtd_in
+ 	if (!mtd)
+ 		return;
+ 
+-	class_device_create(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
++	class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+ 			    NULL, "mtd%d", mtd->index);
+ 	
+-	class_device_create(mtd_class, 
++	class_device_create(mtd_class, NULL,
+ 			    MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
+ 			    NULL, "mtd%dro", mtd->index);
+ }
+diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
+--- a/drivers/mtd/mtdconcat.c
++++ b/drivers/mtd/mtdconcat.c
+@@ -14,7 +14,7 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+-
++#include <linux/sched.h>	/* TASK_* */
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/concat.h>
+ 
+diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
+--- a/drivers/mtd/nand/s3c2410.c
++++ b/drivers/mtd/nand/s3c2410.c
+@@ -48,9 +48,10 @@
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/delay.h>
+ #include <linux/err.h>
++#include <linux/slab.h>
+ 
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/nand.h>
+diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
+--- a/drivers/net/8139cp.c
++++ b/drivers/net/8139cp.c
+@@ -1027,8 +1027,7 @@ static void cp_reset_hw (struct cp_priva
+ 		if (!(cpr8(Cmd) & CmdReset))
+ 			return;
+ 
+-		set_current_state(TASK_UNINTERRUPTIBLE);
+-		schedule_timeout(10);
++		schedule_timeout_uninterruptible(10);
+ 	}
+ 
+ 	printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
+@@ -1575,6 +1574,7 @@ static struct ethtool_ops cp_ethtool_ops
+ 	.set_wol		= cp_set_wol,
+ 	.get_strings		= cp_get_strings,
+ 	.get_ethtool_stats	= cp_get_ethtool_stats,
++	.get_perm_addr		= ethtool_op_get_perm_addr,
+ };
+ 
+ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
+@@ -1773,6 +1773,7 @@ static int cp_init_one (struct pci_dev *
+ 	for (i = 0; i < 3; i++)
+ 		((u16 *) (dev->dev_addr))[i] =
+ 		    le16_to_cpu (read_eeprom (regs, i + 7, addr_len));
++	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+ 	dev->open = cp_open;
+ 	dev->stop = cp_close;
+diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
+--- a/drivers/net/8139too.c
++++ b/drivers/net/8139too.c
+@@ -552,7 +552,8 @@ const static struct {
+ 
+ 	{ "RTL-8100B/8139D",
+ 	  HW_REVID(1, 1, 1, 0, 1, 0, 1),
+-	  HasLWake,
++	  HasHltClk /* XXX undocumented? */
++	| HasLWake,
+ 	},
+ 
+ 	{ "RTL-8101",
+@@ -970,6 +971,7 @@ static int __devinit rtl8139_init_one (s
+ 	for (i = 0; i < 3; i++)
+ 		((u16 *) (dev->dev_addr))[i] =
+ 		    le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
++	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+ 	/* The Rtl8139-specific entries in the device structure. */
+ 	dev->open = rtl8139_open;
+@@ -2465,6 +2467,7 @@ static struct ethtool_ops rtl8139_ethtoo
+ 	.get_strings		= rtl8139_get_strings,
+ 	.get_stats_count	= rtl8139_get_stats_count,
+ 	.get_ethtool_stats	= rtl8139_get_ethtool_stats,
++	.get_perm_addr		= ethtool_op_get_perm_addr,
+ };
+ 
+ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -475,6 +475,14 @@ config SGI_IOC3_ETH_HW_TX_CSUM
+ 	  the moment only acceleration of IPv4 is supported.  This option
+ 	  enables offloading for checksums on transmit.  If unsure, say Y.
+ 
++config MIPS_SIM_NET
++	tristate "MIPS simulator Network device (EXPERIMENTAL)"
++	depends on NETDEVICES && MIPS_SIM && EXPERIMENTAL
++	help
++	  The MIPSNET device is a simple Ethernet network device which is
++	  emulated by the MIPS Simulator.
++	  If you are not using a MIPSsim or are unsure, say N.
++
+ config SGI_O2MACE_ETH
+ 	tristate "SGI O2 MACE Fast Ethernet support"
+ 	depends on NET_ETHERNET && SGI_IP32=y
+@@ -1155,38 +1163,74 @@ config IBMVETH
+ 	  be called ibmveth.
+ 
+ config IBM_EMAC
+-	bool "IBM PPC4xx EMAC driver support"
++	tristate "PowerPC 4xx on-chip Ethernet support"
+ 	depends on 4xx
+-	select CRC32
+-	---help---
+-	  This driver supports the IBM PPC4xx EMAC family of on-chip
+-	  Ethernet controllers.
+-
+-config IBM_EMAC_ERRMSG
+-	bool "Verbose error messages"
+-	depends on IBM_EMAC && BROKEN
++	help
++	  This driver supports the PowerPC 4xx EMAC family of on-chip
++          Ethernet controllers.
+ 
+ config IBM_EMAC_RXB
+ 	int "Number of receive buffers"
+ 	depends on IBM_EMAC
+-	default "128" if IBM_EMAC4
+-	default "64"
++	default "128"
+ 
+ config IBM_EMAC_TXB
+ 	int "Number of transmit buffers"
+ 	depends on IBM_EMAC
+-	default "128" if IBM_EMAC4
+-	default "8"
++	default "64"
++
++config IBM_EMAC_POLL_WEIGHT
++	int "MAL NAPI polling weight"
++	depends on IBM_EMAC
++	default "32"
+ 
+-config IBM_EMAC_FGAP
+-	int "Frame gap"
++config IBM_EMAC_RX_COPY_THRESHOLD
++	int "RX skb copy threshold (bytes)"
+ 	depends on IBM_EMAC
+-	default "8"
++	default "256"
+ 
+-config IBM_EMAC_SKBRES
+-	int "Skb reserve amount"
++config IBM_EMAC_RX_SKB_HEADROOM
++	int "Additional RX skb headroom (bytes)"
+ 	depends on IBM_EMAC
+ 	default "0"
++	help
++	  Additional receive skb headroom. Note, that driver
++	  will always reserve at least 2 bytes to make IP header
++	  aligned, so usualy there is no need to add any additional
++	  headroom.
++	  
++	  If unsure, set to 0.
++
++config IBM_EMAC_PHY_RX_CLK_FIX
++	bool "PHY Rx clock workaround"
++	depends on IBM_EMAC && (405EP || 440GX || 440EP)
++	help
++	  Enable this if EMAC attached to a PHY which doesn't generate
++	  RX clock if there is no link, if this is the case, you will 
++	  see "TX disable timeout" or "RX disable timeout" in the system
++	  log.
++	  
++	  If unsure, say N.
++
++config IBM_EMAC_DEBUG
++	bool "Debugging"
++	depends on IBM_EMAC
++	default n
++
++config IBM_EMAC_ZMII
++	bool
++	depends on IBM_EMAC && (NP405H || NP405L || 44x)
++	default y
++
++config IBM_EMAC_RGMII
++	bool
++	depends on IBM_EMAC && 440GX
++	default y
++		
++config IBM_EMAC_TAH
++	bool
++	depends on IBM_EMAC && 440GX
++	default y
+ 
+ config NET_PCI
+ 	bool "EISA, VLB, PCI and on board controllers"
+@@ -1330,7 +1374,7 @@ config FORCEDETH
+ 
+ config CS89x0
+ 	tristate "CS89x0 support"
+-	depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105
++	depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105 || MACH_MP1000
+ 	---help---
+ 	  Support for CS89x0 chipset based Ethernet cards. If you have a
+ 	  network (Ethernet) card of this type, say Y and read the
+@@ -1767,6 +1811,7 @@ config NE_H8300
+ 	  controller on the Renesas H8/300 processor.
+ 
+ source "drivers/net/fec_8xx/Kconfig"
++source "drivers/net/fs_enet/Kconfig"
+ 
+ endmenu
+ 
+@@ -2083,6 +2128,7 @@ config SPIDER_NET
+ config GIANFAR
+ 	tristate "Gianfar Ethernet"
+ 	depends on 85xx || 83xx
++	select PHYLIB
+ 	help
+ 	  This driver supports the Gigabit TSEC on the MPC85xx 
+ 	  family of chips, and the FEC on the 8540
+@@ -2192,8 +2238,8 @@ config S2IO
+ 	depends on PCI
+ 	---help---
+ 	  This driver supports the 10Gbe XFrame NIC of S2IO. 
+-	  For help regarding driver compilation, installation and 
+-	  tuning please look into ~/drivers/net/s2io/README.txt.
++	  More specific information on configuring the driver is in 
++	  <file:Documentation/networking/s2io.txt>.
+ 
+ config S2IO_NAPI
+ 	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
+@@ -2243,6 +2289,20 @@ config ISERIES_VETH
+ 	tristate "iSeries Virtual Ethernet driver support"
+ 	depends on PPC_ISERIES
+ 
++config RIONET
++	tristate "RapidIO Ethernet over messaging driver support"
++	depends on NETDEVICES && RAPIDIO
++
++config RIONET_TX_SIZE
++	int "Number of outbound queue entries"
++	depends on RIONET
++	default "128"
++
++config RIONET_RX_SIZE
++	int "Number of inbound queue entries"
++	depends on RIONET
++	default "128"
++
+ config FDDI
+ 	bool "FDDI driver support"
+ 	depends on (PCI || EISA)
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -13,7 +13,7 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
+ obj-$(CONFIG_BONDING) += bonding/
+ obj-$(CONFIG_GIANFAR) += gianfar_driver.o
+ 
+-gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_phy.o
++gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
+ 
+ #
+ # link order important here
+@@ -64,6 +64,7 @@ obj-$(CONFIG_SKFP) += skfp/
+ obj-$(CONFIG_VIA_RHINE) += via-rhine.o
+ obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
+ obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
++obj-$(CONFIG_RIONET) += rionet.o
+ 
+ #
+ # end link order section
+@@ -166,6 +167,7 @@ obj-$(CONFIG_EQUALIZER) += eql.o
+ obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
+ obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o
+ obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
++obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
+ obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
+ obj-$(CONFIG_DECLANCE) += declance.o
+ obj-$(CONFIG_ATARILANCE) += atarilance.o
+@@ -201,3 +203,6 @@ obj-$(CONFIG_IRDA) += irda/
+ obj-$(CONFIG_ETRAX_ETHERNET) += cris/
+ 
+ obj-$(CONFIG_NETCONSOLE) += netconsole.o
++
++obj-$(CONFIG_FS_ENET) += fs_enet/
++
+diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
+old mode 100755
+new mode 100644
+diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h
+old mode 100755
+new mode 100644
+diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
+--- a/drivers/net/arm/am79c961a.c
++++ b/drivers/net/arm/am79c961a.c
+@@ -26,10 +26,11 @@
+ #include <linux/init.h>
+ #include <linux/crc32.h>
+ #include <linux/bitops.h>
++#include <linux/platform_device.h>
+ 
+-#include <asm/system.h>
+-#include <asm/irq.h>
++#include <asm/hardware.h>
+ #include <asm/io.h>
++#include <asm/system.h>
+ 
+ #define TX_BUFFERS 15
+ #define RX_BUFFERS 25
+@@ -279,10 +280,13 @@ static void am79c961_timer(unsigned long
+ 	lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
+ 	carrier = netif_carrier_ok(dev);
+ 
+-	if (lnkstat && !carrier)
++	if (lnkstat && !carrier) {
+ 		netif_carrier_on(dev);
+-	else if (!lnkstat && carrier)
++		printk("%s: link up\n", dev->name);
++	} else if (!lnkstat && carrier) {
+ 		netif_carrier_off(dev);
++		printk("%s: link down\n", dev->name);
++	}
+ 
+ 	mod_timer(&priv->timer, jiffies + msecs_to_jiffies(500));
+ }
+@@ -664,17 +668,25 @@ static void __init am79c961_banner(void)
+ 		printk(KERN_INFO "%s", version);
+ }
+ 
+-static int __init am79c961_init(void)
++static int __init am79c961_probe(struct device *_dev)
+ {
++	struct platform_device *pdev = to_platform_device(_dev);
++	struct resource *res;
+ 	struct net_device *dev;
+ 	struct dev_priv *priv;
+ 	int i, ret;
+ 
++	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
++	if (!res)
++		return -ENODEV;
++
+ 	dev = alloc_etherdev(sizeof(struct dev_priv));
+ 	ret = -ENOMEM;
+ 	if (!dev)
+ 		goto out;
+ 
++	SET_NETDEV_DEV(dev, &pdev->dev);
++
+ 	priv = netdev_priv(dev);
+ 
+ 	/*
+@@ -682,8 +694,8 @@ static int __init am79c961_init(void)
+ 	 * The PNP initialisation should have been
+ 	 * done by the ether bootp loader.
+ 	 */
+-	dev->base_addr = 0x220;
+-	dev->irq = IRQ_EBSA110_ETHERNET;
++	dev->base_addr = res->start;
++	dev->irq = platform_get_irq(pdev, 0);
+ 
+     	ret = -ENODEV;
+ 	if (!request_region(dev->base_addr, 0x18, dev->name))
+@@ -704,11 +716,11 @@ static int __init am79c961_init(void)
+ 	    inb(dev->base_addr + 4) != 0x2b)
+ 	    	goto release;
+ 
+-	am79c961_banner();
+-
+ 	for (i = 0; i < 6; i++)
+ 		dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff;
+ 
++	am79c961_banner();
++
+ 	spin_lock_init(&priv->chip_lock);
+ 	init_timer(&priv->timer);
+ 	priv->timer.data = (unsigned long)dev;
+@@ -731,6 +743,7 @@ static int __init am79c961_init(void)
+ 	if (ret == 0) {
+ 		printk(KERN_INFO "%s: ether address ", dev->name);
+ 
++		/* Retrive and print the ethernet address. */
+ 		for (i = 0; i < 6; i++)
+ 			printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]);
+ 
+@@ -745,4 +758,15 @@ out:
+ 	return ret;
+ }
+ 
++static struct device_driver am79c961_driver = {
++	.name		= "am79c961",
++	.bus		= &platform_bus_type,
++	.probe		= am79c961_probe,
++};
++
++static int __init am79c961_init(void)
++{
++	return driver_register(&am79c961_driver);
++}
++
+ __initcall(am79c961_init);
+diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h
+--- a/drivers/net/arm/am79c961a.h
++++ b/drivers/net/arm/am79c961a.h
+@@ -143,6 +143,4 @@ struct dev_priv {
+     struct timer_list	timer;
+ };
+ 
+-extern int	am79c961_probe (struct net_device *dev);
+-
+ #endif
+diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
+--- a/drivers/net/au1000_eth.c
++++ b/drivers/net/au1000_eth.c
+@@ -151,13 +151,6 @@ struct au1000_private *au_macs[NUM_ETH_I
+ 	SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
+ 	SUPPORTED_Autoneg
+ 
+-static char *phy_link[] = 
+-{	"unknown", 
+-	"10Base2", "10BaseT", 
+-	"AUI",
+-	"100BaseT", "100BaseTX", "100BaseFX"
+-};
+-
+ int bcm_5201_init(struct net_device *dev, int phy_addr)
+ {
+ 	s16 data;
+@@ -785,6 +778,7 @@ static struct mii_chip_info {
+ 	{"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0},
+ 	{"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0},
+ 	{"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1},
++	{"NS DP83847 PHY", 0x2000, 0x5c30, &bcm_5201_ops ,0},
+ 	{"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0},
+ 	{"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0},
+ 	{"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0},
+@@ -1045,7 +1039,7 @@ found:
+ #endif
+ 
+ 	if (aup->mii->chip_info == NULL) {
+-		printk(KERN_ERR "%s: Au1x No MII transceivers found!\n",
++		printk(KERN_ERR "%s: Au1x No known MII transceivers found!\n",
+ 				dev->name);
+ 		return -1;
+ 	}
+@@ -1546,6 +1540,9 @@ au1000_probe(u32 ioaddr, int irq, int po
+ 		printk(KERN_ERR "%s: out of memory\n", dev->name);
+ 		goto err_out;
+ 	}
++	aup->mii->next = NULL;
++	aup->mii->chip_info = NULL;
++	aup->mii->status = 0;
+ 	aup->mii->mii_control_reg = 0;
+ 	aup->mii->mii_data_reg = 0;
+ 
+@@ -1609,8 +1606,7 @@ err_out:
+ 	/* here we should have a valid dev plus aup-> register addresses
+ 	 * so we can reset the mac properly.*/
+ 	reset_mac(dev);
+-	if (aup->mii)
+-		kfree(aup->mii);
++	kfree(aup->mii);
+ 	for (i = 0; i < NUM_RX_DMA; i++) {
+ 		if (aup->rx_db_inuse[i])
+ 			ReleaseDB(aup, aup->rx_db_inuse[i]);
+@@ -1809,8 +1805,7 @@ static void __exit au1000_cleanup_module
+ 		if (dev) {
+ 			aup = (struct au1000_private *) dev->priv;
+ 			unregister_netdev(dev);
+-			if (aup->mii)
+-				kfree(aup->mii);
++			kfree(aup->mii);
+ 			for (j = 0; j < NUM_RX_DMA; j++) {
+ 				if (aup->rx_db_inuse[j])
+ 					ReleaseDB(aup, aup->rx_db_inuse[j]);
+diff --git a/drivers/net/b44.c b/drivers/net/b44.c
+--- a/drivers/net/b44.c
++++ b/drivers/net/b44.c
+@@ -19,6 +19,7 @@
+ #include <linux/delay.h>
+ #include <linux/init.h>
+ #include <linux/version.h>
++#include <linux/dma-mapping.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -106,6 +107,29 @@ static int b44_poll(struct net_device *d
+ static void b44_poll_controller(struct net_device *dev);
+ #endif
+ 
++static int dma_desc_align_mask;
++static int dma_desc_sync_size;
++
++static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
++                                                dma_addr_t dma_base,
++                                                unsigned long offset,
++                                                enum dma_data_direction dir)
++{
++	dma_sync_single_range_for_device(&pdev->dev, dma_base,
++	                                 offset & dma_desc_align_mask,
++	                                 dma_desc_sync_size, dir);
++}
++
++static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
++                                             dma_addr_t dma_base,
++                                             unsigned long offset,
++                                             enum dma_data_direction dir)
++{
++	dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
++	                              offset & dma_desc_align_mask,
++	                              dma_desc_sync_size, dir);
++}
++
+ static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
+ {
+ 	return readl(bp->regs + reg);
+@@ -668,6 +692,11 @@ static int b44_alloc_rx_skb(struct b44 *
+ 	dp->ctrl = cpu_to_le32(ctrl);
+ 	dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
+ 
++	if (bp->flags & B44_FLAG_RX_RING_HACK)
++		b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
++		                             dest_idx * sizeof(dp),
++		                             DMA_BIDIRECTIONAL);
++
+ 	return RX_PKT_BUF_SZ;
+ }
+ 
+@@ -692,6 +721,11 @@ static void b44_recycle_rx(struct b44 *b
+ 	pci_unmap_addr_set(dest_map, mapping,
+ 			   pci_unmap_addr(src_map, mapping));
+ 
++	if (bp->flags & B44_FLAG_RX_RING_HACK)
++		b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
++		                          src_idx * sizeof(src_desc),
++		                          DMA_BIDIRECTIONAL);
++
+ 	ctrl = src_desc->ctrl;
+ 	if (dest_idx == (B44_RX_RING_SIZE - 1))
+ 		ctrl |= cpu_to_le32(DESC_CTRL_EOT);
+@@ -700,8 +734,14 @@ static void b44_recycle_rx(struct b44 *b
+ 
+ 	dest_desc->ctrl = ctrl;
+ 	dest_desc->addr = src_desc->addr;
++
+ 	src_map->skb = NULL;
+ 
++	if (bp->flags & B44_FLAG_RX_RING_HACK)
++		b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
++		                             dest_idx * sizeof(dest_desc),
++		                             DMA_BIDIRECTIONAL);
++
+ 	pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
+ 				       RX_PKT_BUF_SZ,
+ 				       PCI_DMA_FROMDEVICE);
+@@ -959,6 +999,11 @@ static int b44_start_xmit(struct sk_buff
+ 	bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl);
+ 	bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
+ 
++	if (bp->flags & B44_FLAG_TX_RING_HACK)
++		b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
++		                             entry * sizeof(bp->tx_ring[0]),
++		                             DMA_TO_DEVICE);
++
+ 	entry = NEXT_TX(entry);
+ 
+ 	bp->tx_prod = entry;
+@@ -1064,6 +1109,16 @@ static void b44_init_rings(struct b44 *b
+ 	memset(bp->rx_ring, 0, B44_RX_RING_BYTES);
+ 	memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
+ 
++	if (bp->flags & B44_FLAG_RX_RING_HACK)
++		dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
++		                           DMA_TABLE_BYTES,
++		                           PCI_DMA_BIDIRECTIONAL);
++
++	if (bp->flags & B44_FLAG_TX_RING_HACK)
++		dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
++		                           DMA_TABLE_BYTES,
++		                           PCI_DMA_TODEVICE);
++
+ 	for (i = 0; i < bp->rx_pending; i++) {
+ 		if (b44_alloc_rx_skb(bp, -1, i) < 0)
+ 			break;
+@@ -1076,23 +1131,33 @@ static void b44_init_rings(struct b44 *b
+  */
+ static void b44_free_consistent(struct b44 *bp)
+ {
+-	if (bp->rx_buffers) {
+-		kfree(bp->rx_buffers);
+-		bp->rx_buffers = NULL;
+-	}
+-	if (bp->tx_buffers) {
+-		kfree(bp->tx_buffers);
+-		bp->tx_buffers = NULL;
+-	}
++	kfree(bp->rx_buffers);
++	bp->rx_buffers = NULL;
++	kfree(bp->tx_buffers);
++	bp->tx_buffers = NULL;
+ 	if (bp->rx_ring) {
+-		pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+-				    bp->rx_ring, bp->rx_ring_dma);
++		if (bp->flags & B44_FLAG_RX_RING_HACK) {
++			dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
++				         DMA_TABLE_BYTES,
++				         DMA_BIDIRECTIONAL);
++			kfree(bp->rx_ring);
++		} else
++			pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
++					    bp->rx_ring, bp->rx_ring_dma);
+ 		bp->rx_ring = NULL;
++		bp->flags &= ~B44_FLAG_RX_RING_HACK;
+ 	}
+ 	if (bp->tx_ring) {
+-		pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+-				    bp->tx_ring, bp->tx_ring_dma);
++		if (bp->flags & B44_FLAG_TX_RING_HACK) {
++			dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
++				         DMA_TABLE_BYTES,
++				         DMA_TO_DEVICE);
++			kfree(bp->tx_ring);
++		} else
++			pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
++					    bp->tx_ring, bp->tx_ring_dma);
+ 		bp->tx_ring = NULL;
++		bp->flags &= ~B44_FLAG_TX_RING_HACK;
+ 	}
+ }
+ 
+@@ -1118,12 +1183,56 @@ static int b44_alloc_consistent(struct b
+ 
+ 	size = DMA_TABLE_BYTES;
+ 	bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
+-	if (!bp->rx_ring)
+-		goto out_err;
++	if (!bp->rx_ring) {
++		/* Allocation may have failed due to pci_alloc_consistent
++		   insisting on use of GFP_DMA, which is more restrictive
++		   than necessary...  */
++		struct dma_desc *rx_ring;
++		dma_addr_t rx_ring_dma;
++
++		if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
++			goto out_err;
++
++		memset(rx_ring, 0, size);
++		rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
++		                             DMA_TABLE_BYTES,
++		                             DMA_BIDIRECTIONAL);
++
++		if (rx_ring_dma + size > B44_DMA_MASK) {
++			kfree(rx_ring);
++			goto out_err;
++		}
++
++		bp->rx_ring = rx_ring;
++		bp->rx_ring_dma = rx_ring_dma;
++		bp->flags |= B44_FLAG_RX_RING_HACK;
++	}
+ 
+ 	bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
+-	if (!bp->tx_ring)
+-		goto out_err;
++	if (!bp->tx_ring) {
++		/* Allocation may have failed due to pci_alloc_consistent
++		   insisting on use of GFP_DMA, which is more restrictive
++		   than necessary...  */
++		struct dma_desc *tx_ring;
++		dma_addr_t tx_ring_dma;
++
++		if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
++			goto out_err;
++
++		memset(tx_ring, 0, size);
++		tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
++		                             DMA_TABLE_BYTES,
++		                             DMA_TO_DEVICE);
++
++		if (tx_ring_dma + size > B44_DMA_MASK) {
++			kfree(tx_ring);
++			goto out_err;
++		}
++
++		bp->tx_ring = tx_ring;
++		bp->tx_ring_dma = tx_ring_dma;
++		bp->flags |= B44_FLAG_TX_RING_HACK;
++	}
+ 
+ 	return 0;
+ 
+@@ -1507,14 +1616,14 @@ static int b44_get_settings(struct net_d
+ 
+ 	cmd->advertising = 0;
+ 	if (bp->flags & B44_FLAG_ADV_10HALF)
+-		cmd->advertising |= ADVERTISE_10HALF;
++		cmd->advertising |= ADVERTISED_10baseT_Half;
+ 	if (bp->flags & B44_FLAG_ADV_10FULL)
+-		cmd->advertising |= ADVERTISE_10FULL;
++		cmd->advertising |= ADVERTISED_10baseT_Full;
+ 	if (bp->flags & B44_FLAG_ADV_100HALF)
+-		cmd->advertising |= ADVERTISE_100HALF;
++		cmd->advertising |= ADVERTISED_100baseT_Half;
+ 	if (bp->flags & B44_FLAG_ADV_100FULL)
+-		cmd->advertising |= ADVERTISE_100FULL;
+-	cmd->advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
++		cmd->advertising |= ADVERTISED_100baseT_Full;
++	cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
+ 	cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
+ 		SPEED_100 : SPEED_10;
+ 	cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
+@@ -1676,6 +1785,7 @@ static struct ethtool_ops b44_ethtool_op
+ 	.set_pauseparam		= b44_set_pauseparam,
+ 	.get_msglevel		= b44_get_msglevel,
+ 	.set_msglevel		= b44_set_msglevel,
++	.get_perm_addr		= ethtool_op_get_perm_addr,
+ };
+ 
+ static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+@@ -1718,6 +1828,7 @@ static int __devinit b44_get_invariants(
+ 	bp->dev->dev_addr[3] = eeprom[80];
+ 	bp->dev->dev_addr[4] = eeprom[83];
+ 	bp->dev->dev_addr[5] = eeprom[82];
++	memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
+ 
+ 	bp->phy_addr = eeprom[90] & 0x1f;
+ 
+@@ -1930,6 +2041,8 @@ static int b44_suspend(struct pci_dev *p
+ 	b44_free_rings(bp);
+ 
+ 	spin_unlock_irq(&bp->lock);
++
++	free_irq(dev->irq, dev);
+ 	pci_disable_device(pdev);
+ 	return 0;
+ }
+@@ -1946,6 +2059,9 @@ static int b44_resume(struct pci_dev *pd
+ 	if (!netif_running(dev))
+ 		return 0;
+ 
++	if (request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev))
++		printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name);
++
+ 	spin_lock_irq(&bp->lock);
+ 
+ 	b44_init_rings(bp);
+@@ -1971,6 +2087,12 @@ static struct pci_driver b44_driver = {
+ 
+ static int __init b44_init(void)
+ {
++	unsigned int dma_desc_align_size = dma_get_cache_alignment();
++
++	/* Setup paramaters for syncing RX/TX DMA descriptors */
++	dma_desc_align_mask = ~(dma_desc_align_size - 1);
++	dma_desc_sync_size = max(dma_desc_align_size, sizeof(struct dma_desc));
++
+ 	return pci_module_init(&b44_driver);
+ }
+ 
+diff --git a/drivers/net/b44.h b/drivers/net/b44.h
+--- a/drivers/net/b44.h
++++ b/drivers/net/b44.h
+@@ -400,6 +400,8 @@ struct b44 {
+ #define B44_FLAG_ADV_100HALF	0x04000000
+ #define B44_FLAG_ADV_100FULL	0x08000000
+ #define B44_FLAG_INTERNAL_PHY	0x10000000
++#define B44_FLAG_RX_RING_HACK	0x20000000
++#define B44_FLAG_TX_RING_HACK	0x40000000
+ 
+ 	u32			rx_offset;
+ 
+diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
+--- a/drivers/net/bmac.c
++++ b/drivers/net/bmac.c
+@@ -1658,6 +1658,7 @@ static struct of_device_id bmac_match[] 
+ 	},
+ 	{},
+ };
++MODULE_DEVICE_TABLE (of, bmac_match);
+ 
+ static struct macio_driver bmac_driver = 
+ {
+@@ -1689,10 +1690,8 @@ static void __exit bmac_exit(void)
+ {
+ 	macio_unregister_driver(&bmac_driver);
+ 
+-	if (bmac_emergency_rxbuf != NULL) {
+-		kfree(bmac_emergency_rxbuf);
+-		bmac_emergency_rxbuf = NULL;
+-	}
++	kfree(bmac_emergency_rxbuf);
++	bmac_emergency_rxbuf = NULL;
+ }
+ 
+ MODULE_AUTHOR("Randy Gobbel/Paul Mackerras");
+diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
+--- a/drivers/net/bnx2.c
++++ b/drivers/net/bnx2.c
+@@ -314,20 +314,16 @@ bnx2_free_mem(struct bnx2 *bp)
+ 				    bp->tx_desc_ring, bp->tx_desc_mapping);
+ 		bp->tx_desc_ring = NULL;
+ 	}
+-	if (bp->tx_buf_ring) {
+-		kfree(bp->tx_buf_ring);
+-		bp->tx_buf_ring = NULL;
+-	}
++	kfree(bp->tx_buf_ring);
++	bp->tx_buf_ring = NULL;
+ 	if (bp->rx_desc_ring) {
+ 		pci_free_consistent(bp->pdev,
+ 				    sizeof(struct rx_bd) * RX_DESC_CNT,
+ 				    bp->rx_desc_ring, bp->rx_desc_mapping);
+ 		bp->rx_desc_ring = NULL;
+ 	}
+-	if (bp->rx_buf_ring) {
+-		kfree(bp->rx_buf_ring);
+-		bp->rx_buf_ring = NULL;
+-	}
++	kfree(bp->rx_buf_ring);
++	bp->rx_buf_ring = NULL;
+ }
+ 
+ static int
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4241,6 +4241,43 @@ out:
+ 	return 0;
+ }
+ 
++static void bond_activebackup_xmit_copy(struct sk_buff *skb,
++                                        struct bonding *bond,
++                                        struct slave *slave)
++{
++	struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
++	struct ethhdr *eth_data;
++	u8 *hwaddr;
++	int res;
++
++	if (!skb2) {
++		printk(KERN_ERR DRV_NAME ": Error: "
++		       "bond_activebackup_xmit_copy(): skb_copy() failed\n");
++		return;
++	}
++
++	skb2->mac.raw = (unsigned char *)skb2->data;
++	eth_data = eth_hdr(skb2);
++
++	/* Pick an appropriate source MAC address
++	 *	-- use slave's perm MAC addr, unless used by bond
++	 *	-- otherwise, borrow active slave's perm MAC addr
++	 *	   since that will not be used
++	 */
++	hwaddr = slave->perm_hwaddr;
++	if (!memcmp(eth_data->h_source, hwaddr, ETH_ALEN))
++		hwaddr = bond->curr_active_slave->perm_hwaddr;
++
++	/* Set source MAC address appropriately */
++	memcpy(eth_data->h_source, hwaddr, ETH_ALEN);
++
++	res = bond_dev_queue_xmit(bond, skb2, slave->dev);
++	if (res)
++		dev_kfree_skb(skb2);
++
++	return;
++}
++
+ /*
+  * in active-backup mode, we know that bond->curr_active_slave is always valid if
+  * the bond has a usable interface.
+@@ -4257,10 +4294,26 @@ static int bond_xmit_activebackup(struct
+ 		goto out;
+ 	}
+ 
+-	if (bond->curr_active_slave) { /* one usable interface */
+-		res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
++	if (!bond->curr_active_slave)
++		goto out;
++
++	/* Xmit IGMP frames on all slaves to ensure rapid fail-over
++	   for multicast traffic on snooping switches */
++	if (skb->protocol == __constant_htons(ETH_P_IP) &&
++	    skb->nh.iph->protocol == IPPROTO_IGMP) {
++		struct slave *slave, *active_slave;
++		int i;
++
++		active_slave = bond->curr_active_slave;
++		bond_for_each_slave_from_to(bond, slave, i, active_slave->next,
++		                            active_slave->prev)
++			if (IS_UP(slave->dev) &&
++			    (slave->link == BOND_LINK_UP))
++				bond_activebackup_xmit_copy(skb, bond, slave);
+ 	}
+ 
++	res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
++
+ out:
+ 	if (res) {
+ 		/* no suitable interface, frame not sent */
+diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
+--- a/drivers/net/cassini.c
++++ b/drivers/net/cassini.c
+@@ -489,7 +489,7 @@ static int cas_page_free(struct cas *cp,
+ /* local page allocation routines for the receive buffers. jumbo pages
+  * require at least 8K contiguous and 8K aligned buffers.
+  */
+-static cas_page_t *cas_page_alloc(struct cas *cp, const int flags)
++static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags)
+ {
+ 	cas_page_t *page;
+ 
+@@ -561,7 +561,7 @@ static void cas_spare_free(struct cas *c
+ }
+ 
+ /* replenish spares if needed */
+-static void cas_spare_recover(struct cas *cp, const int flags)
++static void cas_spare_recover(struct cas *cp, const gfp_t flags)
+ {
+ 	struct list_head list, *elem, *tmp;
+ 	int needed, i;
+diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
+--- a/drivers/net/cs89x0.c
++++ b/drivers/net/cs89x0.c
+@@ -182,6 +182,10 @@ static unsigned int cs8900_irq_map[] = {
+ #define CIRRUS_DEFAULT_IRQ	VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
+ static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0};
+ static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
++#elif defined(CONFIG_MACH_MP1000)
++#include <asm/arch/mp1000-seprom.h>
++static unsigned int netcard_portlist[] __initdata = {MP1000_EIO_BASE+0x300, 0};
++static unsigned int cs8900_irq_map[] = {IRQ_EINT3,0,0,0};
+ #else
+ static unsigned int netcard_portlist[] __initdata =
+    { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
+@@ -590,6 +594,10 @@ cs89x0_probe1(struct net_device *dev, in
+ 			cnt -= j;
+ 		}
+ 	} else
++#elif defined(CONFIG_MACH_MP1000)
++	if (1) {
++		memcpy(dev->dev_addr, get_eeprom_mac_address(), ETH_ALEN);
++	} else
+ #endif
+ 
+         if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) == 
+@@ -649,6 +657,10 @@ cs89x0_probe1(struct net_device *dev, in
+ 	if (1) {
+ 		printk(KERN_NOTICE "cs89x0: No EEPROM on HiCO.SH4\n");
+ 	} else
++#elif defined(CONFIG_MACH_MP1000)
++	if (1) {
++		lp->force |= FORCE_RJ45;
++	} else
+ #endif
+ 	if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
+ 		printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n");
+@@ -1231,7 +1243,7 @@ net_open(struct net_device *dev)
+ 	else
+ #endif
+ 	{
+-#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105)
++#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105) && !defined(CONFIG_MACH_MP1000)
+ 		if (((1 << dev->irq) & lp->irq_map) == 0) {
+ 			printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
+                                dev->name, dev->irq, lp->irq_map);
+diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h
+--- a/drivers/net/cs89x0.h
++++ b/drivers/net/cs89x0.h
+@@ -16,7 +16,7 @@
+ 
+ #include <linux/config.h>
+ 
+-#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
++#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105) || defined (CONFIG_MACH_MP1000)
+ /* IXDP2401/IXDP2801 uses dword-aligned register addressing */
+ #define CS89x0_PORT(reg) ((reg) * 2)
+ #else
+diff --git a/drivers/net/declance.c b/drivers/net/declance.c
+--- a/drivers/net/declance.c
++++ b/drivers/net/declance.c
+@@ -5,7 +5,7 @@
+  *
+  *      adopted from sunlance.c by Richard van den Berg
+  *
+- *      Copyright (C) 2002, 2003  Maciej W. Rozycki
++ *      Copyright (C) 2002, 2003, 2005  Maciej W. Rozycki
+  *
+  *      additional sources:
+  *      - PMAD-AA TURBOchannel Ethernet Module Functional Specification,
+@@ -57,13 +57,15 @@
+ #include <linux/string.h>
+ 
+ #include <asm/addrspace.h>
++#include <asm/system.h>
++
+ #include <asm/dec/interrupts.h>
+ #include <asm/dec/ioasic.h>
+ #include <asm/dec/ioasic_addrs.h>
+ #include <asm/dec/kn01.h>
+ #include <asm/dec/machtype.h>
++#include <asm/dec/system.h>
+ #include <asm/dec/tc.h>
+-#include <asm/system.h>
+ 
+ static char version[] __devinitdata =
+ "declance.c: v0.009 by Linux MIPS DECstation task force\n";
+@@ -79,10 +81,6 @@ MODULE_LICENSE("GPL");
+ #define PMAD_LANCE 2
+ #define PMAX_LANCE 3
+ 
+-#ifndef CONFIG_TC
+-unsigned long system_base;
+-unsigned long dmaptr;
+-#endif
+ 
+ #define LE_CSR0 0
+ #define LE_CSR1 1
+@@ -237,7 +235,7 @@ struct lance_init_block {
+ /*
+  * This works *only* for the ring descriptors
+  */
+-#define LANCE_ADDR(x) (PHYSADDR(x) >> 1)
++#define LANCE_ADDR(x) (CPHYSADDR(x) >> 1)
+ 
+ struct lance_private {
+ 	struct net_device *next;
+@@ -697,12 +695,13 @@ out:
+ 	spin_unlock(&lp->lock);
+ }
+ 
+-static void lance_dma_merr_int(const int irq, void *dev_id,
+-				struct pt_regs *regs)
++static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id,
++				      struct pt_regs *regs)
+ {
+ 	struct net_device *dev = (struct net_device *) dev_id;
+ 
+ 	printk("%s: DMA error\n", dev->name);
++	return IRQ_HANDLED;
+ }
+ 
+ static irqreturn_t
+@@ -1026,10 +1025,6 @@ static int __init dec_lance_init(const i
+ 	unsigned long esar_base;
+ 	unsigned char *esar;
+ 
+-#ifndef CONFIG_TC
+-	system_base = KN01_LANCE_BASE;
+-#endif
+-
+ 	if (dec_lance_debug && version_printed++ == 0)
+ 		printk(version);
+ 
+@@ -1062,16 +1057,16 @@ static int __init dec_lance_init(const i
+ 	switch (type) {
+ #ifdef CONFIG_TC
+ 	case ASIC_LANCE:
+-		dev->base_addr = system_base + IOASIC_LANCE;
++		dev->base_addr = CKSEG1ADDR(dec_kn_slot_base + IOASIC_LANCE);
+ 
+ 		/* buffer space for the on-board LANCE shared memory */
+ 		/*
+ 		 * FIXME: ugly hack!
+ 		 */
+-		dev->mem_start = KSEG1ADDR(0x00020000);
++		dev->mem_start = CKSEG1ADDR(0x00020000);
+ 		dev->mem_end = dev->mem_start + 0x00020000;
+ 		dev->irq = dec_interrupt[DEC_IRQ_LANCE];
+-		esar_base = system_base + IOASIC_ESAR;
++		esar_base = CKSEG1ADDR(dec_kn_slot_base + IOASIC_ESAR);
+ 
+ 		/* Workaround crash with booting KN04 2.1k from Disk */
+ 		memset((void *)dev->mem_start, 0,
+@@ -1101,14 +1096,14 @@ static int __init dec_lance_init(const i
+ 		/* Setup I/O ASIC LANCE DMA.  */
+ 		lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR];
+ 		ioasic_write(IO_REG_LANCE_DMA_P,
+-			     PHYSADDR(dev->mem_start) << 3);
++			     CPHYSADDR(dev->mem_start) << 3);
+ 
+ 		break;
+ 
+ 	case PMAD_LANCE:
+ 		claim_tc_card(slot);
+ 
+-		dev->mem_start = get_tc_base_addr(slot);
++		dev->mem_start = CKSEG1ADDR(get_tc_base_addr(slot));
+ 		dev->base_addr = dev->mem_start + 0x100000;
+ 		dev->irq = get_tc_irq_nr(slot);
+ 		esar_base = dev->mem_start + 0x1c0002;
+@@ -1137,9 +1132,9 @@ static int __init dec_lance_init(const i
+ 
+ 	case PMAX_LANCE:
+ 		dev->irq = dec_interrupt[DEC_IRQ_LANCE];
+-		dev->base_addr = KN01_LANCE_BASE;
+-		dev->mem_start = KN01_LANCE_BASE + 0x01000000;
+-		esar_base = KN01_RTC_BASE + 1;
++		dev->base_addr = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE);
++		dev->mem_start = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE_MEM);
++		esar_base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_ESAR + 1);
+ 		lp->dma_irq = -1;
+ 
+ 		/*
+diff --git a/drivers/net/depca.c b/drivers/net/depca.c
+--- a/drivers/net/depca.c
++++ b/drivers/net/depca.c
+@@ -254,7 +254,7 @@
+ #include <linux/unistd.h>
+ #include <linux/ctype.h>
+ #include <linux/moduleparam.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/bitops.h>
+ 
+ #include <asm/uaccess.h>
+diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
+--- a/drivers/net/dm9000.c
++++ b/drivers/net/dm9000.c
+@@ -66,6 +66,7 @@
+ #include <linux/mii.h>
+ #include <linux/dm9000.h>
+ #include <linux/delay.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/delay.h>
+ #include <asm/irq.h>
+@@ -1140,11 +1141,11 @@ dm9000_phy_write(struct net_device *dev,
+ }
+ 
+ static int
+-dm9000_drv_suspend(struct device *dev, pm_message_t state, u32 level)
++dm9000_drv_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct net_device *ndev = dev_get_drvdata(dev);
+ 
+-	if (ndev && level == SUSPEND_DISABLE) {
++	if (ndev) {
+ 		if (netif_running(ndev)) {
+ 			netif_device_detach(ndev);
+ 			dm9000_shutdown(ndev);
+@@ -1154,12 +1155,12 @@ dm9000_drv_suspend(struct device *dev, p
+ }
+ 
+ static int
+-dm9000_drv_resume(struct device *dev, u32 level)
++dm9000_drv_resume(struct device *dev)
+ {
+ 	struct net_device *ndev = dev_get_drvdata(dev);
+ 	board_info_t *db = (board_info_t *) ndev->priv;
+ 
+-	if (ndev && level == RESUME_ENABLE) {
++	if (ndev) {
+ 
+ 		if (netif_running(ndev)) {
+ 			dm9000_reset(db);
+diff --git a/drivers/net/e100.c b/drivers/net/e100.c
+--- a/drivers/net/e100.c
++++ b/drivers/net/e100.c
+@@ -2201,6 +2201,7 @@ static struct ethtool_ops e100_ethtool_o
+ 	.phys_id		= e100_phys_id,
+ 	.get_stats_count	= e100_get_stats_count,
+ 	.get_ethtool_stats	= e100_get_ethtool_stats,
++	.get_perm_addr		= ethtool_op_get_perm_addr,
+ };
+ 
+ static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+@@ -2351,7 +2352,8 @@ static int __devinit e100_probe(struct p
+ 	e100_phy_init(nic);
+ 
+ 	memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
+-	if(!is_valid_ether_addr(netdev->dev_addr)) {
++	memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN);
++	if(!is_valid_ether_addr(netdev->perm_addr)) {
+ 		DPRINTK(PROBE, ERR, "Invalid MAC address from "
+ 			"EEPROM, aborting.\n");
+ 		err = -EAGAIN;
+diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
+--- a/drivers/net/e1000/e1000.h
++++ b/drivers/net/e1000/e1000.h
+@@ -72,6 +72,10 @@
+ #include <linux/mii.h>
+ #include <linux/ethtool.h>
+ #include <linux/if_vlan.h>
++#ifdef CONFIG_E1000_MQ
++#include <linux/cpu.h>
++#include <linux/smp.h>
++#endif
+ 
+ #define BAR_0		0
+ #define BAR_1		1
+@@ -165,10 +169,33 @@ struct e1000_buffer {
+ 	uint16_t next_to_watch;
+ };
+ 
+-struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; };
+-struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; };
++struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; };
++struct e1000_ps_page_dma { uint64_t ps_page_dma[PS_PAGE_BUFFERS]; };
++
++struct e1000_tx_ring {
++	/* pointer to the descriptor ring memory */
++	void *desc;
++	/* physical address of the descriptor ring */
++	dma_addr_t dma;
++	/* length of descriptor ring in bytes */
++	unsigned int size;
++	/* number of descriptors in the ring */
++	unsigned int count;
++	/* next descriptor to associate a buffer with */
++	unsigned int next_to_use;
++	/* next descriptor to check for DD status bit */
++	unsigned int next_to_clean;
++	/* array of buffer information structs */
++	struct e1000_buffer *buffer_info;
++
++	struct e1000_buffer previous_buffer_info;
++	spinlock_t tx_lock;
++	uint16_t tdh;
++	uint16_t tdt;
++	uint64_t pkt;
++};
+ 
+-struct e1000_desc_ring {
++struct e1000_rx_ring {
+ 	/* pointer to the descriptor ring memory */
+ 	void *desc;
+ 	/* physical address of the descriptor ring */
+@@ -186,6 +213,10 @@ struct e1000_desc_ring {
+ 	/* arrays of page information for packet split */
+ 	struct e1000_ps_page *ps_page;
+ 	struct e1000_ps_page_dma *ps_page_dma;
++
++	uint16_t rdh;
++	uint16_t rdt;
++	uint64_t pkt;
+ };
+ 
+ #define E1000_DESC_UNUSED(R) \
+@@ -227,9 +258,10 @@ struct e1000_adapter {
+ 	unsigned long led_status;
+ 
+ 	/* TX */
+-	struct e1000_desc_ring tx_ring;
+-	struct e1000_buffer previous_buffer_info;
+-	spinlock_t tx_lock;
++	struct e1000_tx_ring *tx_ring;      /* One per active queue */
++#ifdef CONFIG_E1000_MQ
++	struct e1000_tx_ring **cpu_tx_ring; /* per-cpu */
++#endif
+ 	uint32_t txd_cmd;
+ 	uint32_t tx_int_delay;
+ 	uint32_t tx_abs_int_delay;
+@@ -246,19 +278,33 @@ struct e1000_adapter {
+ 
+ 	/* RX */
+ #ifdef CONFIG_E1000_NAPI
+-	boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done,
+-			  int work_to_do);
++	boolean_t (*clean_rx) (struct e1000_adapter *adapter,
++			       struct e1000_rx_ring *rx_ring,
++			       int *work_done, int work_to_do);
+ #else
+-	boolean_t (*clean_rx) (struct e1000_adapter *adapter);
++	boolean_t (*clean_rx) (struct e1000_adapter *adapter,
++			       struct e1000_rx_ring *rx_ring);
+ #endif
+-	void (*alloc_rx_buf) (struct e1000_adapter *adapter);
+-	struct e1000_desc_ring rx_ring;
++	void (*alloc_rx_buf) (struct e1000_adapter *adapter,
++			      struct e1000_rx_ring *rx_ring);
++	struct e1000_rx_ring *rx_ring;      /* One per active queue */
++#ifdef CONFIG_E1000_NAPI
++	struct net_device *polling_netdev;  /* One per active queue */
++#endif
++#ifdef CONFIG_E1000_MQ
++	struct net_device **cpu_netdev;     /* per-cpu */
++	struct call_async_data_struct rx_sched_call_data;
++	int cpu_for_queue[4];
++#endif
++	int num_queues;
++
+ 	uint64_t hw_csum_err;
+ 	uint64_t hw_csum_good;
++	uint64_t rx_hdr_split;
+ 	uint32_t rx_int_delay;
+ 	uint32_t rx_abs_int_delay;
+ 	boolean_t rx_csum;
+-	boolean_t rx_ps;
++	unsigned int rx_ps_pages;
+ 	uint32_t gorcl;
+ 	uint64_t gorcl_old;
+ 	uint16_t rx_ps_bsize0;
+@@ -278,8 +324,8 @@ struct e1000_adapter {
+ 	struct e1000_phy_stats phy_stats;
+ 
+ 	uint32_t test_icr;
+-	struct e1000_desc_ring test_tx_ring;
+-	struct e1000_desc_ring test_rx_ring;
++	struct e1000_tx_ring test_tx_ring;
++	struct e1000_rx_ring test_rx_ring;
+ 
+ 
+ 	int msg_enable;
+diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
+--- a/drivers/net/e1000/e1000_ethtool.c
++++ b/drivers/net/e1000/e1000_ethtool.c
+@@ -39,10 +39,10 @@ extern int e1000_up(struct e1000_adapter
+ extern void e1000_down(struct e1000_adapter *adapter);
+ extern void e1000_reset(struct e1000_adapter *adapter);
+ extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+-extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
+-extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
+-extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
+-extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
++extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
++extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
++extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
++extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+ extern void e1000_update_stats(struct e1000_adapter *adapter);
+ 
+ struct e1000_stats {
+@@ -91,7 +91,8 @@ static const struct e1000_stats e1000_gs
+ 	{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
+ 	{ "rx_long_byte_count", E1000_STAT(stats.gorcl) },
+ 	{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
+-	{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }
++	{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
++	{ "rx_header_split", E1000_STAT(rx_hdr_split) },
+ };
+ #define E1000_STATS_LEN	\
+ 	sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
+@@ -546,8 +547,10 @@ e1000_set_eeprom(struct net_device *netd
+ 	ret_val = e1000_write_eeprom(hw, first_word,
+ 				     last_word - first_word + 1, eeprom_buff);
+ 
+-	/* Update the checksum over the first part of the EEPROM if needed */
+-	if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
++	/* Update the checksum over the first part of the EEPROM if needed 
++	 * and flush shadow RAM for 82573 conrollers */
++	if((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) || 
++				(hw->mac_type == e1000_82573)))
+ 		e1000_update_eeprom_checksum(hw);
+ 
+ 	kfree(eeprom_buff);
+@@ -576,8 +579,8 @@ e1000_get_ringparam(struct net_device *n
+ {
+ 	struct e1000_adapter *adapter = netdev_priv(netdev);
+ 	e1000_mac_type mac_type = adapter->hw.mac_type;
+-	struct e1000_desc_ring *txdr = &adapter->tx_ring;
+-	struct e1000_desc_ring *rxdr = &adapter->rx_ring;
++	struct e1000_tx_ring *txdr = adapter->tx_ring;
++	struct e1000_rx_ring *rxdr = adapter->rx_ring;
+ 
+ 	ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
+ 		E1000_MAX_82544_RXD;
+@@ -597,20 +600,40 @@ e1000_set_ringparam(struct net_device *n
+ {
+ 	struct e1000_adapter *adapter = netdev_priv(netdev);
+ 	e1000_mac_type mac_type = adapter->hw.mac_type;
+-	struct e1000_desc_ring *txdr = &adapter->tx_ring;
+-	struct e1000_desc_ring *rxdr = &adapter->rx_ring;
+-	struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new;
+-	int err;
++	struct e1000_tx_ring *txdr, *tx_old, *tx_new;
++	struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
++	int i, err, tx_ring_size, rx_ring_size;
++
++	tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
++	rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
++
++	if (netif_running(adapter->netdev))
++		e1000_down(adapter);
+ 
+ 	tx_old = adapter->tx_ring;
+ 	rx_old = adapter->rx_ring;
+ 
++	adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
++	if (!adapter->tx_ring) {
++		err = -ENOMEM;
++		goto err_setup_rx;
++	}
++	memset(adapter->tx_ring, 0, tx_ring_size);
++
++	adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
++	if (!adapter->rx_ring) {
++		kfree(adapter->tx_ring);
++		err = -ENOMEM;
++		goto err_setup_rx;
++	}
++	memset(adapter->rx_ring, 0, rx_ring_size);
++
++	txdr = adapter->tx_ring;
++	rxdr = adapter->rx_ring;
++
+ 	if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+ 		return -EINVAL;
+ 
+-	if(netif_running(adapter->netdev))
+-		e1000_down(adapter);
+-
+ 	rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
+ 	rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
+ 		E1000_MAX_RXD : E1000_MAX_82544_RXD));
+@@ -621,11 +644,16 @@ e1000_set_ringparam(struct net_device *n
+ 		E1000_MAX_TXD : E1000_MAX_82544_TXD));
+ 	E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); 
+ 
++	for (i = 0; i < adapter->num_queues; i++) {
++		txdr[i].count = txdr->count;
++		rxdr[i].count = rxdr->count;
++	}
++
+ 	if(netif_running(adapter->netdev)) {
+ 		/* Try to get new resources before deleting old */
+-		if((err = e1000_setup_rx_resources(adapter)))
++		if ((err = e1000_setup_all_rx_resources(adapter)))
+ 			goto err_setup_rx;
+-		if((err = e1000_setup_tx_resources(adapter)))
++		if ((err = e1000_setup_all_tx_resources(adapter)))
+ 			goto err_setup_tx;
+ 
+ 		/* save the new, restore the old in order to free it,
+@@ -635,8 +663,10 @@ e1000_set_ringparam(struct net_device *n
+ 		tx_new = adapter->tx_ring;
+ 		adapter->rx_ring = rx_old;
+ 		adapter->tx_ring = tx_old;
+-		e1000_free_rx_resources(adapter);
+-		e1000_free_tx_resources(adapter);
++		e1000_free_all_rx_resources(adapter);
++		e1000_free_all_tx_resources(adapter);
++		kfree(tx_old);
++		kfree(rx_old);
+ 		adapter->rx_ring = rx_new;
+ 		adapter->tx_ring = tx_new;
+ 		if((err = e1000_up(adapter)))
+@@ -645,7 +675,7 @@ e1000_set_ringparam(struct net_device *n
+ 
+ 	return 0;
+ err_setup_tx:
+-	e1000_free_rx_resources(adapter);
++	e1000_free_all_rx_resources(adapter);
+ err_setup_rx:
+ 	adapter->rx_ring = rx_old;
+ 	adapter->tx_ring = tx_old;
+@@ -696,6 +726,11 @@ e1000_reg_test(struct e1000_adapter *ada
+ 	 * Some bits that get toggled are ignored.
+ 	 */
+         switch (adapter->hw.mac_type) {
++	/* there are several bits on newer hardware that are r/w */
++	case e1000_82571:
++	case e1000_82572:
++		toggle = 0x7FFFF3FF;
++		break;
+ 	case e1000_82573:
+ 		toggle = 0x7FFFF033;
+ 		break;
+@@ -898,8 +933,8 @@ e1000_intr_test(struct e1000_adapter *ad
+ static void
+ e1000_free_desc_rings(struct e1000_adapter *adapter)
+ {
+-	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
+-	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
++	struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
++	struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 	int i;
+ 
+@@ -930,19 +965,16 @@ e1000_free_desc_rings(struct e1000_adapt
+ 	if(rxdr->desc)
+ 		pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
+ 
+-	if(txdr->buffer_info)
+-		kfree(txdr->buffer_info);
+-	if(rxdr->buffer_info)
+-		kfree(rxdr->buffer_info);
+-
++	kfree(txdr->buffer_info);
++	kfree(rxdr->buffer_info);
+ 	return;
+ }
+ 
+ static int
+ e1000_setup_desc_rings(struct e1000_adapter *adapter)
+ {
+-	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
+-	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
++	struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
++	struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 	uint32_t rctl;
+ 	int size, i, ret_val;
+@@ -1245,6 +1277,8 @@ e1000_set_phy_loopback(struct e1000_adap
+ 	case e1000_82541_rev_2:
+ 	case e1000_82547:
+ 	case e1000_82547_rev_2:
++	case e1000_82571:
++	case e1000_82572:
+ 	case e1000_82573:
+ 		return e1000_integrated_phy_loopback(adapter);
+ 		break;
+@@ -1340,8 +1374,8 @@ e1000_check_lbtest_frame(struct sk_buff 
+ static int
+ e1000_run_loopback_test(struct e1000_adapter *adapter)
+ {
+-	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
+-	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
++	struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
++	struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 	int i, j, k, l, lc, good_cnt, ret_val=0;
+ 	unsigned long time;
+@@ -1509,6 +1543,7 @@ e1000_diag_test(struct net_device *netde
+ 		data[2] = 0;
+ 		data[3] = 0;
+ 	}
++	msleep_interruptible(4 * 1000);
+ }
+ 
+ static void
+@@ -1625,7 +1660,7 @@ e1000_phys_id(struct net_device *netdev,
+ 	if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
+ 		data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
+ 
+-	if(adapter->hw.mac_type < e1000_82573) {
++	if(adapter->hw.mac_type < e1000_82571) {
+ 		if(!adapter->blink_timer.function) {
+ 			init_timer(&adapter->blink_timer);
+ 			adapter->blink_timer.function = e1000_led_blink_callback;
+@@ -1739,6 +1774,7 @@ struct ethtool_ops e1000_ethtool_ops = {
+ 	.phys_id                = e1000_phys_id,
+ 	.get_stats_count        = e1000_get_stats_count,
+ 	.get_ethtool_stats      = e1000_get_ethtool_stats,
++	.get_perm_addr		= ethtool_op_get_perm_addr,
+ };
+ 
+ void e1000_set_ethtool_ops(struct net_device *netdev)
+diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
+--- a/drivers/net/e1000/e1000_hw.c
++++ b/drivers/net/e1000/e1000_hw.c
+@@ -83,14 +83,14 @@ uint16_t e1000_igp_cable_length_table[IG
+ 
+ static const
+ uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
+-    { 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43,
+-      22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58,
+-      32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74,
+-      43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90,
+-      57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108,
+-      73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124,
+-      91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128,
+-      108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
++    { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
++      0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
++      6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
++      21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
++      40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
++      60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
++      83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
++      104, 109, 114, 118, 121, 124};
+ 
+ 
+ /******************************************************************************
+@@ -286,7 +286,6 @@ e1000_set_mac_type(struct e1000_hw *hw)
+     case E1000_DEV_ID_82546GB_FIBER:
+     case E1000_DEV_ID_82546GB_SERDES:
+     case E1000_DEV_ID_82546GB_PCIE:
+-    case E1000_DEV_ID_82546GB_QUAD_COPPER:
+         hw->mac_type = e1000_82546_rev_3;
+         break;
+     case E1000_DEV_ID_82541EI:
+@@ -305,8 +304,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
+     case E1000_DEV_ID_82547GI:
+         hw->mac_type = e1000_82547_rev_2;
+         break;
++    case E1000_DEV_ID_82571EB_COPPER:
++    case E1000_DEV_ID_82571EB_FIBER:
++    case E1000_DEV_ID_82571EB_SERDES:
++            hw->mac_type = e1000_82571;
++        break;
++    case E1000_DEV_ID_82572EI_COPPER:
++    case E1000_DEV_ID_82572EI_FIBER:
++    case E1000_DEV_ID_82572EI_SERDES:
++        hw->mac_type = e1000_82572;
++        break;
+     case E1000_DEV_ID_82573E:
+     case E1000_DEV_ID_82573E_IAMT:
++    case E1000_DEV_ID_82573L:
+         hw->mac_type = e1000_82573;
+         break;
+     default:
+@@ -315,6 +325,8 @@ e1000_set_mac_type(struct e1000_hw *hw)
+     }
+ 
+     switch(hw->mac_type) {
++    case e1000_82571:
++    case e1000_82572:
+     case e1000_82573:
+         hw->eeprom_semaphore_present = TRUE;
+         /* fall through */
+@@ -351,6 +363,8 @@ e1000_set_media_type(struct e1000_hw *hw
+     switch (hw->device_id) {
+     case E1000_DEV_ID_82545GM_SERDES:
+     case E1000_DEV_ID_82546GB_SERDES:
++    case E1000_DEV_ID_82571EB_SERDES:
++    case E1000_DEV_ID_82572EI_SERDES:
+         hw->media_type = e1000_media_type_internal_serdes;
+         break;
+     default:
+@@ -523,6 +537,8 @@ e1000_reset_hw(struct e1000_hw *hw)
+             E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+             E1000_WRITE_FLUSH(hw);
+             /* fall through */
++        case e1000_82571:
++        case e1000_82572:
+             ret_val = e1000_get_auto_rd_done(hw);
+             if(ret_val)
+                 /* We don't want to continue accessing MAC registers. */
+@@ -683,6 +699,9 @@ e1000_init_hw(struct e1000_hw *hw)
+         switch (hw->mac_type) {
+         default:
+             break;
++        case e1000_82571:
++        case e1000_82572:
++            ctrl |= (1 << 22);
+         case e1000_82573:
+             ctrl |= E1000_TXDCTL_COUNT_DESC;
+             break;
+@@ -694,6 +713,26 @@ e1000_init_hw(struct e1000_hw *hw)
+         e1000_enable_tx_pkt_filtering(hw); 
+     }
+ 
++    switch (hw->mac_type) {
++    default:
++        break;
++    case e1000_82571:
++    case e1000_82572:
++        ctrl = E1000_READ_REG(hw, TXDCTL1);
++        ctrl &= ~E1000_TXDCTL_WTHRESH;
++        ctrl |= E1000_TXDCTL_COUNT_DESC | E1000_TXDCTL_FULL_TX_DESC_WB;
++        ctrl |= (1 << 22);
++        E1000_WRITE_REG(hw, TXDCTL1, ctrl);
++        break;
++    }
++
++
++
++    if (hw->mac_type == e1000_82573) {
++        uint32_t gcr = E1000_READ_REG(hw, GCR);
++        gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
++        E1000_WRITE_REG(hw, GCR, gcr);
++    }
+ 
+     /* Clear all of the statistics registers (clear on read).  It is
+      * important that we do this after we have tried to establish link
+@@ -878,6 +917,14 @@ e1000_setup_fiber_serdes_link(struct e10
+ 
+     DEBUGFUNC("e1000_setup_fiber_serdes_link");
+ 
++    /* On 82571 and 82572 Fiber connections, SerDes loopback mode persists
++     * until explicitly turned off or a power cycle is performed.  A read to
++     * the register does not indicate its status.  Therefore, we ensure
++     * loopback mode is disabled during initialization.
++     */
++    if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
++        E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
++
+     /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
+      * set when the optics detect a signal. On older adapters, it will be
+      * cleared when there is a signal.  This applies to fiber media only.
+@@ -2943,6 +2990,8 @@ e1000_phy_reset(struct e1000_hw *hw)
+ 
+     switch (hw->mac_type) {
+     case e1000_82541_rev_2:
++    case e1000_82571:
++    case e1000_82572:
+         ret_val = e1000_phy_hw_reset(hw);
+         if(ret_val)
+             return ret_val;
+@@ -2981,6 +3030,16 @@ e1000_detect_gig_phy(struct e1000_hw *hw
+ 
+     DEBUGFUNC("e1000_detect_gig_phy");
+ 
++    /* The 82571 firmware may still be configuring the PHY.  In this
++     * case, we cannot access the PHY until the configuration is done.  So
++     * we explicitly set the PHY values. */
++    if(hw->mac_type == e1000_82571 ||
++       hw->mac_type == e1000_82572) {
++        hw->phy_id = IGP01E1000_I_PHY_ID;
++        hw->phy_type = e1000_phy_igp_2;
++        return E1000_SUCCESS;
++    }
++
+     /* Read the PHY ID Registers to identify which PHY is onboard. */
+     ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
+     if(ret_val)
+@@ -3334,6 +3393,21 @@ e1000_init_eeprom_params(struct e1000_hw
+         eeprom->use_eerd = FALSE;
+         eeprom->use_eewr = FALSE;
+         break;
++    case e1000_82571:
++    case e1000_82572:
++        eeprom->type = e1000_eeprom_spi;
++        eeprom->opcode_bits = 8;
++        eeprom->delay_usec = 1;
++        if (eecd & E1000_EECD_ADDR_BITS) {
++            eeprom->page_size = 32;
++            eeprom->address_bits = 16;
++        } else {
++            eeprom->page_size = 8;
++            eeprom->address_bits = 8;
++        }
++        eeprom->use_eerd = FALSE;
++        eeprom->use_eewr = FALSE;
++        break;
+     case e1000_82573:
+         eeprom->type = e1000_eeprom_spi;
+         eeprom->opcode_bits = 8;
+@@ -3543,25 +3617,26 @@ e1000_acquire_eeprom(struct e1000_hw *hw
+     eecd = E1000_READ_REG(hw, EECD);
+ 
+     if (hw->mac_type != e1000_82573) {
+-    /* Request EEPROM Access */
+-    if(hw->mac_type > e1000_82544) {
+-        eecd |= E1000_EECD_REQ;
+-        E1000_WRITE_REG(hw, EECD, eecd);
+-        eecd = E1000_READ_REG(hw, EECD);
+-        while((!(eecd & E1000_EECD_GNT)) &&
+-              (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
+-            i++;
+-            udelay(5);
+-            eecd = E1000_READ_REG(hw, EECD);
+-        }
+-        if(!(eecd & E1000_EECD_GNT)) {
+-            eecd &= ~E1000_EECD_REQ;
++        /* Request EEPROM Access */
++        if(hw->mac_type > e1000_82544) {
++            eecd |= E1000_EECD_REQ;
+             E1000_WRITE_REG(hw, EECD, eecd);
+-            DEBUGOUT("Could not acquire EEPROM grant\n");
+-            return -E1000_ERR_EEPROM;
++            eecd = E1000_READ_REG(hw, EECD);
++            while((!(eecd & E1000_EECD_GNT)) &&
++                  (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
++                i++;
++                udelay(5);
++                eecd = E1000_READ_REG(hw, EECD);
++            }
++            if(!(eecd & E1000_EECD_GNT)) {
++                eecd &= ~E1000_EECD_REQ;
++                E1000_WRITE_REG(hw, EECD, eecd);
++                DEBUGOUT("Could not acquire EEPROM grant\n");
++                e1000_put_hw_eeprom_semaphore(hw);
++                return -E1000_ERR_EEPROM;
++            }
+         }
+     }
+-    }
+ 
+     /* Setup EEPROM for Read/Write */
+ 
+@@ -4064,7 +4139,7 @@ e1000_write_eeprom(struct e1000_hw *hw,
+         return -E1000_ERR_EEPROM;
+     }
+ 
+-    /* 82573 reads only through eerd */
++    /* 82573 writes only through eewr */
+     if(eeprom->use_eewr == TRUE)
+         return e1000_write_eeprom_eewr(hw, offset, words, data);
+ 
+@@ -4353,9 +4428,16 @@ e1000_read_mac_addr(struct e1000_hw * hw
+         hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
+         hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
+     }
+-    if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
+-       (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
++    switch (hw->mac_type) {
++    default:
++        break;
++    case e1000_82546:
++    case e1000_82546_rev_3:
++    case e1000_82571:
++        if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
+             hw->perm_mac_addr[5] ^= 0x01;
++        break;
++    }
+ 
+     for(i = 0; i < NODE_ADDRESS_SIZE; i++)
+         hw->mac_addr[i] = hw->perm_mac_addr[i];
+@@ -4385,6 +4467,12 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
+     e1000_rar_set(hw, hw->mac_addr, 0);
+ 
+     rar_num = E1000_RAR_ENTRIES;
++
++    /* Reserve a spot for the Locally Administered Address to work around
++     * an 82571 issue in which a reset on one port will reload the MAC on
++     * the other port. */
++    if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
++        rar_num -= 1;
+     /* Zero out the other 15 receive addresses. */
+     DEBUGOUT("Clearing RAR[1-15]\n");
+     for(i = 1; i < rar_num; i++) {
+@@ -4427,6 +4515,12 @@ e1000_mc_addr_list_update(struct e1000_h
+     /* Clear RAR[1-15] */
+     DEBUGOUT(" Clearing RAR[1-15]\n");
+     num_rar_entry = E1000_RAR_ENTRIES;
++    /* Reserve a spot for the Locally Administered Address to work around
++     * an 82571 issue in which a reset on one port will reload the MAC on
++     * the other port. */
++    if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
++        num_rar_entry -= 1;
++
+     for(i = rar_used_count; i < num_rar_entry; i++) {
+         E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
+         E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
+@@ -4984,7 +5078,6 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw
+     temp = E1000_READ_REG(hw, ICTXQEC);
+     temp = E1000_READ_REG(hw, ICTXQMTC);
+     temp = E1000_READ_REG(hw, ICRXDMTC);
+-
+ }
+ 
+ /******************************************************************************
+@@ -5151,6 +5244,8 @@ e1000_get_bus_info(struct e1000_hw *hw)
+         hw->bus_speed = e1000_bus_speed_unknown;
+         hw->bus_width = e1000_bus_width_unknown;
+         break;
++    case e1000_82571:
++    case e1000_82572:
+     case e1000_82573:
+         hw->bus_type = e1000_bus_type_pci_express;
+         hw->bus_speed = e1000_bus_speed_2500;
+@@ -5250,6 +5345,7 @@ e1000_get_cable_length(struct e1000_hw *
+     int32_t ret_val;
+     uint16_t agc_value = 0;
+     uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
++    uint16_t max_agc = 0;
+     uint16_t i, phy_data;
+     uint16_t cable_length;
+ 
+@@ -5338,6 +5434,40 @@ e1000_get_cable_length(struct e1000_hw *
+                        IGP01E1000_AGC_RANGE) : 0;
+         *max_length = e1000_igp_cable_length_table[agc_value] +
+                       IGP01E1000_AGC_RANGE;
++    } else if (hw->phy_type == e1000_phy_igp_2) {
++        uint16_t agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
++                                                         {IGP02E1000_PHY_AGC_A,
++                                                          IGP02E1000_PHY_AGC_B,
++                                                          IGP02E1000_PHY_AGC_C,
++                                                          IGP02E1000_PHY_AGC_D};
++        /* Read the AGC registers for all channels */
++        for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
++            ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
++            if (ret_val)
++                return ret_val;
++
++	    /* Getting bits 15:9, which represent the combination of course and
++             * fine gain values.  The result is a number that can be put into
++             * the lookup table to obtain the approximate cable length. */
++            cur_agc = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
++                      IGP02E1000_AGC_LENGTH_MASK;
++
++            /* Remove min & max AGC values from calculation. */
++            if (e1000_igp_2_cable_length_table[min_agc] > e1000_igp_2_cable_length_table[cur_agc])
++                min_agc = cur_agc;
++	    if (e1000_igp_2_cable_length_table[max_agc] < e1000_igp_2_cable_length_table[cur_agc])
++                max_agc = cur_agc;
++
++            agc_value += e1000_igp_2_cable_length_table[cur_agc];
++        }
++
++        agc_value -= (e1000_igp_2_cable_length_table[min_agc] + e1000_igp_2_cable_length_table[max_agc]);
++        agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
++
++        /* Calculate cable length with the error range of +/- 10 meters. */
++        *min_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
++                       (agc_value - IGP02E1000_AGC_RANGE) : 0;
++        *max_length = agc_value + IGP02E1000_AGC_RANGE;
+     }
+ 
+     return E1000_SUCCESS;
+@@ -6465,6 +6595,8 @@ e1000_get_auto_rd_done(struct e1000_hw *
+     default:
+         msec_delay(5);
+         break;
++    case e1000_82571:
++    case e1000_82572:
+     case e1000_82573:
+         while(timeout) {
+             if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break;
+@@ -6494,10 +6626,31 @@ e1000_get_auto_rd_done(struct e1000_hw *
+ int32_t
+ e1000_get_phy_cfg_done(struct e1000_hw *hw)
+ {
++    int32_t timeout = PHY_CFG_TIMEOUT;
++    uint32_t cfg_mask = E1000_EEPROM_CFG_DONE;
++
+     DEBUGFUNC("e1000_get_phy_cfg_done");
+ 
+-    /* Simply wait for 10ms */
+-    msec_delay(10);
++    switch (hw->mac_type) {
++    default:
++        msec_delay(10);
++        break;
++    case e1000_82571:
++    case e1000_82572:
++        while (timeout) {
++            if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask)
++                break;
++            else
++                msec_delay(1);
++            timeout--;
++        }
++
++        if (!timeout) {
++            DEBUGOUT("MNG configuration cycle has not completed.\n");
++            return -E1000_ERR_RESET;
++        }
++        break;
++    }
+ 
+     return E1000_SUCCESS;
+ }
+@@ -6569,8 +6722,7 @@ e1000_put_hw_eeprom_semaphore(struct e10
+         return;
+ 
+     swsm = E1000_READ_REG(hw, SWSM);
+-    /* Release both semaphores. */
+-    swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
++        swsm &= ~(E1000_SWSM_SWESMBI);
+     E1000_WRITE_REG(hw, SWSM, swsm);
+ }
+ 
+@@ -6606,6 +6758,8 @@ e1000_arc_subsystem_valid(struct e1000_h
+      * if this is the case.  We read FWSM to determine the manageability mode.
+      */
+     switch (hw->mac_type) {
++    case e1000_82571:
++    case e1000_82572:
+     case e1000_82573:
+         fwsm = E1000_READ_REG(hw, FWSM);
+         if((fwsm & E1000_FWSM_MODE_MASK) != 0)
+diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
+--- a/drivers/net/e1000/e1000_hw.h
++++ b/drivers/net/e1000/e1000_hw.h
+@@ -57,6 +57,8 @@ typedef enum {
+     e1000_82541_rev_2,
+     e1000_82547,
+     e1000_82547_rev_2,
++    e1000_82571,
++    e1000_82572,
+     e1000_82573,
+     e1000_num_macs
+ } e1000_mac_type;
+@@ -478,10 +480,16 @@ uint8_t e1000_arc_subsystem_valid(struct
+ #define E1000_DEV_ID_82546GB_SERDES      0x107B
+ #define E1000_DEV_ID_82546GB_PCIE        0x108A
+ #define E1000_DEV_ID_82547EI             0x1019
++#define E1000_DEV_ID_82571EB_COPPER      0x105E
++#define E1000_DEV_ID_82571EB_FIBER       0x105F
++#define E1000_DEV_ID_82571EB_SERDES      0x1060
++#define E1000_DEV_ID_82572EI_COPPER      0x107D
++#define E1000_DEV_ID_82572EI_FIBER       0x107E
++#define E1000_DEV_ID_82572EI_SERDES      0x107F
+ #define E1000_DEV_ID_82573E              0x108B
+ #define E1000_DEV_ID_82573E_IAMT         0x108C
++#define E1000_DEV_ID_82573L              0x109A
+ 
+-#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
+ 
+ #define NODE_ADDRESS_SIZE 6
+ #define ETH_LENGTH_OF_ADDRESS 6
+@@ -833,6 +841,8 @@ struct e1000_ffvt_entry {
+ #define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+ #define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+ 
++#define E1000_DISABLE_SERDES_LOOPBACK   0x0400
++
+ /* Register Set. (82543, 82544)
+  *
+  * Registers are defined to be 32 bits and  should be accessed as 32 bit values.
+@@ -853,6 +863,7 @@ struct e1000_ffvt_entry {
+ #define E1000_CTRL_EXT 0x00018  /* Extended Device Control - RW */
+ #define E1000_FLA      0x0001C  /* Flash Access - RW */
+ #define E1000_MDIC     0x00020  /* MDI Control - RW */
++#define E1000_SCTL     0x00024  /* SerDes Control - RW */
+ #define E1000_FCAL     0x00028  /* Flow Control Address Low - RW */
+ #define E1000_FCAH     0x0002C  /* Flow Control Address High -RW */
+ #define E1000_FCT      0x00030  /* Flow Control Type - RW */
+@@ -864,6 +875,12 @@ struct e1000_ffvt_entry {
+ #define E1000_IMC      0x000D8  /* Interrupt Mask Clear - WO */
+ #define E1000_IAM      0x000E0  /* Interrupt Acknowledge Auto Mask */
+ #define E1000_RCTL     0x00100  /* RX Control - RW */
++#define E1000_RDTR1    0x02820  /* RX Delay Timer (1) - RW */
++#define E1000_RDBAL1   0x02900  /* RX Descriptor Base Address Low (1) - RW */
++#define E1000_RDBAH1   0x02904  /* RX Descriptor Base Address High (1) - RW */
++#define E1000_RDLEN1   0x02908  /* RX Descriptor Length (1) - RW */
++#define E1000_RDH1     0x02910  /* RX Descriptor Head (1) - RW */
++#define E1000_RDT1     0x02918  /* RX Descriptor Tail (1) - RW */
+ #define E1000_FCTTV    0x00170  /* Flow Control Transmit Timer Value - RW */
+ #define E1000_TXCW     0x00178  /* TX Configuration Word - RW */
+ #define E1000_RXCW     0x00180  /* RX Configuration Word - RO */
+@@ -895,6 +912,12 @@ struct e1000_ffvt_entry {
+ #define E1000_RDH      0x02810  /* RX Descriptor Head - RW */
+ #define E1000_RDT      0x02818  /* RX Descriptor Tail - RW */
+ #define E1000_RDTR     0x02820  /* RX Delay Timer - RW */
++#define E1000_RDBAL0   E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
++#define E1000_RDBAH0   E1000_RDBAH /* RX Desc Base Address High (0) - RW */
++#define E1000_RDLEN0   E1000_RDLEN /* RX Desc Length (0) - RW */
++#define E1000_RDH0     E1000_RDH   /* RX Desc Head (0) - RW */
++#define E1000_RDT0     E1000_RDT   /* RX Desc Tail (0) - RW */
++#define E1000_RDTR0    E1000_RDTR  /* RX Delay Timer (0) - RW */
+ #define E1000_RXDCTL   0x02828  /* RX Descriptor Control - RW */
+ #define E1000_RADV     0x0282C  /* RX Interrupt Absolute Delay Timer - RW */
+ #define E1000_RSRPD    0x02C00  /* RX Small Packet Detect - RW */
+@@ -980,15 +1003,15 @@ struct e1000_ffvt_entry {
+ #define E1000_BPTC     0x040F4  /* Broadcast Packets TX Count - R/clr */
+ #define E1000_TSCTC    0x040F8  /* TCP Segmentation Context TX - R/clr */
+ #define E1000_TSCTFC   0x040FC  /* TCP Segmentation Context TX Fail - R/clr */
+-#define E1000_IAC       0x4100  /* Interrupt Assertion Count */
+-#define E1000_ICRXPTC   0x4104  /* Interrupt Cause Rx Packet Timer Expire Count */
+-#define E1000_ICRXATC   0x4108  /* Interrupt Cause Rx Absolute Timer Expire Count */
+-#define E1000_ICTXPTC   0x410C  /* Interrupt Cause Tx Packet Timer Expire Count */
+-#define E1000_ICTXATC   0x4110  /* Interrupt Cause Tx Absolute Timer Expire Count */
+-#define E1000_ICTXQEC   0x4118  /* Interrupt Cause Tx Queue Empty Count */
+-#define E1000_ICTXQMTC  0x411C  /* Interrupt Cause Tx Queue Minimum Threshold Count */
+-#define E1000_ICRXDMTC  0x4120  /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
+-#define E1000_ICRXOC    0x4124  /* Interrupt Cause Receiver Overrun Count */
++#define E1000_IAC      0x04100  /* Interrupt Assertion Count */
++#define E1000_ICRXPTC  0x04104  /* Interrupt Cause Rx Packet Timer Expire Count */
++#define E1000_ICRXATC  0x04108  /* Interrupt Cause Rx Absolute Timer Expire Count */
++#define E1000_ICTXPTC  0x0410C  /* Interrupt Cause Tx Packet Timer Expire Count */
++#define E1000_ICTXATC  0x04110  /* Interrupt Cause Tx Absolute Timer Expire Count */
++#define E1000_ICTXQEC  0x04118  /* Interrupt Cause Tx Queue Empty Count */
++#define E1000_ICTXQMTC 0x0411C  /* Interrupt Cause Tx Queue Minimum Threshold Count */
++#define E1000_ICRXDMTC 0x04120  /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
++#define E1000_ICRXOC   0x04124  /* Interrupt Cause Receiver Overrun Count */
+ #define E1000_RXCSUM   0x05000  /* RX Checksum Control - RW */
+ #define E1000_RFCTL    0x05008  /* Receive Filter Control*/
+ #define E1000_MTA      0x05200  /* Multicast Table Array - RW Array */
+@@ -1018,6 +1041,14 @@ struct e1000_ffvt_entry {
+ #define E1000_FWSM      0x05B54 /* FW Semaphore */
+ #define E1000_FFLT_DBG  0x05F04 /* Debug Register */
+ #define E1000_HICR      0x08F00 /* Host Inteface Control */
++
++/* RSS registers */
++#define E1000_CPUVEC    0x02C10 /* CPU Vector Register - RW */
++#define E1000_MRQC      0x05818 /* Multiple Receive Control - RW */
++#define E1000_RETA      0x05C00 /* Redirection Table - RW Array */
++#define E1000_RSSRK     0x05C80 /* RSS Random Key - RW Array */
++#define E1000_RSSIM     0x05864 /* RSS Interrupt Mask */
++#define E1000_RSSIR     0x05868 /* RSS Interrupt Request */
+ /* Register Set (82542)
+  *
+  * Some of the 82542 registers are located at different offsets than they are
+@@ -1032,6 +1063,7 @@ struct e1000_ffvt_entry {
+ #define E1000_82542_CTRL_EXT E1000_CTRL_EXT
+ #define E1000_82542_FLA      E1000_FLA
+ #define E1000_82542_MDIC     E1000_MDIC
++#define E1000_82542_SCTL     E1000_SCTL
+ #define E1000_82542_FCAL     E1000_FCAL
+ #define E1000_82542_FCAH     E1000_FCAH
+ #define E1000_82542_FCT      E1000_FCT
+@@ -1049,6 +1081,18 @@ struct e1000_ffvt_entry {
+ #define E1000_82542_RDLEN    0x00118
+ #define E1000_82542_RDH      0x00120
+ #define E1000_82542_RDT      0x00128
++#define E1000_82542_RDTR0    E1000_82542_RDTR
++#define E1000_82542_RDBAL0   E1000_82542_RDBAL
++#define E1000_82542_RDBAH0   E1000_82542_RDBAH
++#define E1000_82542_RDLEN0   E1000_82542_RDLEN
++#define E1000_82542_RDH0     E1000_82542_RDH
++#define E1000_82542_RDT0     E1000_82542_RDT
++#define E1000_82542_RDTR1    0x00130
++#define E1000_82542_RDBAL1   0x00138
++#define E1000_82542_RDBAH1   0x0013C
++#define E1000_82542_RDLEN1   0x00140
++#define E1000_82542_RDH1     0x00148
++#define E1000_82542_RDT1     0x00150
+ #define E1000_82542_FCRTH    0x00160
+ #define E1000_82542_FCRTL    0x00168
+ #define E1000_82542_FCTTV    E1000_FCTTV
+@@ -1197,6 +1241,13 @@ struct e1000_ffvt_entry {
+ #define E1000_82542_ICRXOC      E1000_ICRXOC
+ #define E1000_82542_HICR        E1000_HICR
+ 
++#define E1000_82542_CPUVEC      E1000_CPUVEC
++#define E1000_82542_MRQC        E1000_MRQC
++#define E1000_82542_RETA        E1000_RETA
++#define E1000_82542_RSSRK       E1000_RSSRK
++#define E1000_82542_RSSIM       E1000_RSSIM
++#define E1000_82542_RSSIR       E1000_RSSIR
++
+ /* Statistics counters collected by the MAC */
+ struct e1000_hw_stats {
+     uint64_t crcerrs;
+@@ -1336,6 +1387,7 @@ struct e1000_hw {
+     boolean_t serdes_link_down;
+     boolean_t tbi_compatibility_en;
+     boolean_t tbi_compatibility_on;
++    boolean_t laa_is_present;
+     boolean_t phy_reset_disable;
+     boolean_t fc_send_xon;
+     boolean_t fc_strict_ieee;
+@@ -1374,6 +1426,7 @@ struct e1000_hw {
+ #define E1000_CTRL_BEM32    0x00000400  /* Big Endian 32 mode */
+ #define E1000_CTRL_FRCSPD   0x00000800  /* Force Speed */
+ #define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */
++#define E1000_CTRL_D_UD_EN  0x00002000  /* Dock/Undock enable */
+ #define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
+ #define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
+ #define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
+@@ -1491,6 +1544,8 @@ struct e1000_hw {
+ #define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
+ #define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
+ #define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
++#define E1000_CTRL_EXT_CANC           0x04000000  /* Interrupt delay cancellation */
++#define E1000_CTRL_EXT_DRV_LOAD       0x10000000  /* Driver loaded bit for FW */
+ #define E1000_CTRL_EXT_IAME           0x08000000  /* Interrupt acknowledge Auto-mask */
+ #define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000  /* Clear Interrupt timers after IMS clear */
+ 
+@@ -1524,6 +1579,7 @@ struct e1000_hw {
+ #define E1000_LEDCTL_LED2_BLINK           0x00800000
+ #define E1000_LEDCTL_LED3_MODE_MASK       0x0F000000
+ #define E1000_LEDCTL_LED3_MODE_SHIFT      24
++#define E1000_LEDCTL_LED3_BLINK_RATE      0x20000000
+ #define E1000_LEDCTL_LED3_IVRT            0x40000000
+ #define E1000_LEDCTL_LED3_BLINK           0x80000000
+ 
+@@ -1784,6 +1840,16 @@ struct e1000_hw {
+ #define E1000_RXCSUM_IPPCSE    0x00001000   /* IP payload checksum enable */
+ #define E1000_RXCSUM_PCSD      0x00002000   /* packet checksum disabled */
+ 
++/* Multiple Receive Queue Control */
++#define E1000_MRQC_ENABLE_MASK              0x00000003
++#define E1000_MRQC_ENABLE_RSS_2Q            0x00000001
++#define E1000_MRQC_ENABLE_RSS_INT           0x00000004
++#define E1000_MRQC_RSS_FIELD_MASK           0xFFFF0000
++#define E1000_MRQC_RSS_FIELD_IPV4_TCP       0x00010000
++#define E1000_MRQC_RSS_FIELD_IPV4           0x00020000
++#define E1000_MRQC_RSS_FIELD_IPV6_TCP       0x00040000
++#define E1000_MRQC_RSS_FIELD_IPV6_EX        0x00080000
++#define E1000_MRQC_RSS_FIELD_IPV6           0x00100000
+ 
+ /* Definitions for power management and wakeup registers */
+ /* Wake Up Control */
+@@ -1928,6 +1994,7 @@ struct e1000_host_command_info {
+ #define E1000_MDALIGN          4096
+ 
+ #define E1000_GCR_BEM32                 0x00400000
++#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
+ /* Function Active and Power State to MNG */
+ #define E1000_FACTPS_FUNC0_POWER_STATE_MASK         0x00000003
+ #define E1000_FACTPS_LAN0_VALID                     0x00000004
+@@ -1980,6 +2047,7 @@ struct e1000_host_command_info {
+ /* EEPROM Word Offsets */
+ #define EEPROM_COMPAT                 0x0003
+ #define EEPROM_ID_LED_SETTINGS        0x0004
++#define EEPROM_VERSION                0x0005
+ #define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude adjustment. */
+ #define EEPROM_PHY_CLASS_WORD         0x0007
+ #define EEPROM_INIT_CONTROL1_REG      0x000A
+@@ -1990,6 +2058,8 @@ struct e1000_host_command_info {
+ #define EEPROM_FLASH_VERSION          0x0032
+ #define EEPROM_CHECKSUM_REG           0x003F
+ 
++#define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */
++
+ /* Word definitions for ID LED Settings */
+ #define ID_LED_RESERVED_0000 0x0000
+ #define ID_LED_RESERVED_FFFF 0xFFFF
+@@ -2108,6 +2178,8 @@ struct e1000_host_command_info {
+ #define E1000_PBA_22K 0x0016
+ #define E1000_PBA_24K 0x0018
+ #define E1000_PBA_30K 0x001E
++#define E1000_PBA_32K 0x0020
++#define E1000_PBA_38K 0x0026
+ #define E1000_PBA_40K 0x0028
+ #define E1000_PBA_48K 0x0030    /* 48KB, default RX allocation */
+ 
+@@ -2592,11 +2664,11 @@ struct e1000_host_command_info {
+ 
+ /* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
+ #define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
+-#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128
++#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 113
+ 
+ /* The precision error of the cable length is +/- 10 meters */
+ #define IGP01E1000_AGC_RANGE    10
+-#define IGP02E1000_AGC_RANGE    10
++#define IGP02E1000_AGC_RANGE    15
+ 
+ /* IGP01E1000 PCS Initialization register */
+ /* bits 3:6 in the PCS registers stores the channels polarity */
+diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
+--- a/drivers/net/e1000/e1000_main.c
++++ b/drivers/net/e1000/e1000_main.c
+@@ -43,7 +43,7 @@ char e1000_driver_string[] = "Intel(R) P
+ #else
+ #define DRIVERNAPI "-NAPI"
+ #endif
+-#define DRV_VERSION		"6.0.60-k2"DRIVERNAPI
++#define DRV_VERSION "6.1.16-k2"DRIVERNAPI
+ char e1000_driver_version[] = DRV_VERSION;
+ char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
+ 
+@@ -80,6 +80,9 @@ static struct pci_device_id e1000_pci_tb
+ 	INTEL_E1000_ETHERNET_DEVICE(0x1026),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x1027),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x1028),
++	INTEL_E1000_ETHERNET_DEVICE(0x105E),
++	INTEL_E1000_ETHERNET_DEVICE(0x105F),
++	INTEL_E1000_ETHERNET_DEVICE(0x1060),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x1075),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x1076),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x1077),
+@@ -88,10 +91,13 @@ static struct pci_device_id e1000_pci_tb
+ 	INTEL_E1000_ETHERNET_DEVICE(0x107A),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x107B),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x107C),
++	INTEL_E1000_ETHERNET_DEVICE(0x107D),
++	INTEL_E1000_ETHERNET_DEVICE(0x107E),
++	INTEL_E1000_ETHERNET_DEVICE(0x107F),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x108A),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x108B),
+ 	INTEL_E1000_ETHERNET_DEVICE(0x108C),
+-	INTEL_E1000_ETHERNET_DEVICE(0x1099),
++	INTEL_E1000_ETHERNET_DEVICE(0x109A),
+ 	/* required last entry */
+ 	{0,}
+ };
+@@ -102,10 +108,18 @@ int e1000_up(struct e1000_adapter *adapt
+ void e1000_down(struct e1000_adapter *adapter);
+ void e1000_reset(struct e1000_adapter *adapter);
+ int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+-int e1000_setup_tx_resources(struct e1000_adapter *adapter);
+-int e1000_setup_rx_resources(struct e1000_adapter *adapter);
+-void e1000_free_tx_resources(struct e1000_adapter *adapter);
+-void e1000_free_rx_resources(struct e1000_adapter *adapter);
++int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
++int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
++void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
++void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
++int e1000_setup_tx_resources(struct e1000_adapter *adapter,
++                             struct e1000_tx_ring *txdr);
++int e1000_setup_rx_resources(struct e1000_adapter *adapter,
++                             struct e1000_rx_ring *rxdr);
++void e1000_free_tx_resources(struct e1000_adapter *adapter,
++                             struct e1000_tx_ring *tx_ring);
++void e1000_free_rx_resources(struct e1000_adapter *adapter,
++                             struct e1000_rx_ring *rx_ring);
+ void e1000_update_stats(struct e1000_adapter *adapter);
+ 
+ /* Local Function Prototypes */
+@@ -114,14 +128,22 @@ static int e1000_init_module(void);
+ static void e1000_exit_module(void);
+ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+ static void __devexit e1000_remove(struct pci_dev *pdev);
++static int e1000_alloc_queues(struct e1000_adapter *adapter);
++#ifdef CONFIG_E1000_MQ
++static void e1000_setup_queue_mapping(struct e1000_adapter *adapter);
++#endif
+ static int e1000_sw_init(struct e1000_adapter *adapter);
+ static int e1000_open(struct net_device *netdev);
+ static int e1000_close(struct net_device *netdev);
+ static void e1000_configure_tx(struct e1000_adapter *adapter);
+ static void e1000_configure_rx(struct e1000_adapter *adapter);
+ static void e1000_setup_rctl(struct e1000_adapter *adapter);
+-static void e1000_clean_tx_ring(struct e1000_adapter *adapter);
+-static void e1000_clean_rx_ring(struct e1000_adapter *adapter);
++static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
++static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
++static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
++                                struct e1000_tx_ring *tx_ring);
++static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
++                                struct e1000_rx_ring *rx_ring);
+ static void e1000_set_multi(struct net_device *netdev);
+ static void e1000_update_phy_info(unsigned long data);
+ static void e1000_watchdog(unsigned long data);
+@@ -132,19 +154,26 @@ static struct net_device_stats * e1000_g
+ static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
+ static int e1000_set_mac(struct net_device *netdev, void *p);
+ static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
+-static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
++static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter,
++                                    struct e1000_tx_ring *tx_ring);
+ #ifdef CONFIG_E1000_NAPI
+-static int e1000_clean(struct net_device *netdev, int *budget);
++static int e1000_clean(struct net_device *poll_dev, int *budget);
+ static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
++                                    struct e1000_rx_ring *rx_ring,
+                                     int *work_done, int work_to_do);
+ static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
++                                       struct e1000_rx_ring *rx_ring,
+                                        int *work_done, int work_to_do);
+ #else
+-static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter);
+-static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter);
++static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
++                                    struct e1000_rx_ring *rx_ring);
++static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
++                                       struct e1000_rx_ring *rx_ring);
+ #endif
+-static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
+-static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter);
++static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
++                                   struct e1000_rx_ring *rx_ring);
++static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
++                                      struct e1000_rx_ring *rx_ring);
+ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
+ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
+ 			   int cmd);
+@@ -162,8 +191,8 @@ static void e1000_vlan_rx_add_vid(struct
+ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
+ static void e1000_restore_vlan(struct e1000_adapter *adapter);
+ 
+-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
+ #ifdef CONFIG_PM
++static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
+ static int e1000_resume(struct pci_dev *pdev);
+ #endif
+ 
+@@ -172,6 +201,11 @@ static int e1000_resume(struct pci_dev *
+ static void e1000_netpoll (struct net_device *netdev);
+ #endif
+ 
++#ifdef CONFIG_E1000_MQ
++/* for multiple Rx queues */
++void e1000_rx_schedule(void *data);
++#endif
++
+ /* Exported from other modules */
+ 
+ extern void e1000_check_options(struct e1000_adapter *adapter);
+@@ -289,7 +323,7 @@ int
+ e1000_up(struct e1000_adapter *adapter)
+ {
+ 	struct net_device *netdev = adapter->netdev;
+-	int err;
++	int i, err;
+ 
+ 	/* hardware has been reset, we need to reload some things */
+ 
+@@ -308,7 +342,8 @@ e1000_up(struct e1000_adapter *adapter)
+ 	e1000_configure_tx(adapter);
+ 	e1000_setup_rctl(adapter);
+ 	e1000_configure_rx(adapter);
+-	adapter->alloc_rx_buf(adapter);
++	for (i = 0; i < adapter->num_queues; i++)
++		adapter->alloc_rx_buf(adapter, &adapter->rx_ring[i]);
+ 
+ #ifdef CONFIG_PCI_MSI
+ 	if(adapter->hw.mac_type > e1000_82547_rev_2) {
+@@ -344,6 +379,9 @@ e1000_down(struct e1000_adapter *adapter
+ 	struct net_device *netdev = adapter->netdev;
+ 
+ 	e1000_irq_disable(adapter);
++#ifdef CONFIG_E1000_MQ
++	while (atomic_read(&adapter->rx_sched_call_data.count) != 0);
++#endif
+ 	free_irq(adapter->pdev->irq, netdev);
+ #ifdef CONFIG_PCI_MSI
+ 	if(adapter->hw.mac_type > e1000_82547_rev_2 &&
+@@ -363,11 +401,10 @@ e1000_down(struct e1000_adapter *adapter
+ 	netif_stop_queue(netdev);
+ 
+ 	e1000_reset(adapter);
+-	e1000_clean_tx_ring(adapter);
+-	e1000_clean_rx_ring(adapter);
++	e1000_clean_all_tx_rings(adapter);
++	e1000_clean_all_rx_rings(adapter);
+ 
+-	/* If WoL is not enabled
+-	 * and management mode is not IAMT
++	/* If WoL is not enabled and management mode is not IAMT
+ 	 * Power down the PHY so no link is implied when interface is down */
+ 	if(!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
+ 	   adapter->hw.media_type == e1000_media_type_copper &&
+@@ -398,6 +435,10 @@ e1000_reset(struct e1000_adapter *adapte
+ 	case e1000_82547_rev_2:
+ 		pba = E1000_PBA_30K;
+ 		break;
++	case e1000_82571:
++	case e1000_82572:
++		pba = E1000_PBA_38K;
++		break;
+ 	case e1000_82573:
+ 		pba = E1000_PBA_12K;
+ 		break;
+@@ -475,6 +516,7 @@ e1000_probe(struct pci_dev *pdev,
+ 	struct net_device *netdev;
+ 	struct e1000_adapter *adapter;
+ 	unsigned long mmio_start, mmio_len;
++	uint32_t ctrl_ext;
+ 	uint32_t swsm;
+ 
+ 	static int cards_found = 0;
+@@ -614,8 +656,9 @@ e1000_probe(struct pci_dev *pdev,
+ 	if(e1000_read_mac_addr(&adapter->hw))
+ 		DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
+ 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
++	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
+ 
+-	if(!is_valid_ether_addr(netdev->dev_addr)) {
++	if(!is_valid_ether_addr(netdev->perm_addr)) {
+ 		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
+ 		err = -EIO;
+ 		goto err_eeprom;
+@@ -687,6 +730,12 @@ e1000_probe(struct pci_dev *pdev,
+ 
+ 	/* Let firmware know the driver has taken over */
+ 	switch(adapter->hw.mac_type) {
++	case e1000_82571:
++	case e1000_82572:
++		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
++		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
++				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
++		break;
+ 	case e1000_82573:
+ 		swsm = E1000_READ_REG(&adapter->hw, SWSM);
+ 		E1000_WRITE_REG(&adapter->hw, SWSM,
+@@ -731,7 +780,11 @@ e1000_remove(struct pci_dev *pdev)
+ {
+ 	struct net_device *netdev = pci_get_drvdata(pdev);
+ 	struct e1000_adapter *adapter = netdev_priv(netdev);
++	uint32_t ctrl_ext;
+ 	uint32_t manc, swsm;
++#ifdef CONFIG_E1000_NAPI
++	int i;
++#endif
+ 
+ 	flush_scheduled_work();
+ 
+@@ -745,6 +798,12 @@ e1000_remove(struct pci_dev *pdev)
+ 	}
+ 
+ 	switch(adapter->hw.mac_type) {
++	case e1000_82571:
++	case e1000_82572:
++		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
++		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
++				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
++		break;
+ 	case e1000_82573:
+ 		swsm = E1000_READ_REG(&adapter->hw, SWSM);
+ 		E1000_WRITE_REG(&adapter->hw, SWSM,
+@@ -756,13 +815,27 @@ e1000_remove(struct pci_dev *pdev)
+ 	}
+ 
+ 	unregister_netdev(netdev);
++#ifdef CONFIG_E1000_NAPI
++	for (i = 0; i < adapter->num_queues; i++)
++		__dev_put(&adapter->polling_netdev[i]);
++#endif
+ 
+ 	if(!e1000_check_phy_reset_block(&adapter->hw))
+ 		e1000_phy_hw_reset(&adapter->hw);
+ 
++	kfree(adapter->tx_ring);
++	kfree(adapter->rx_ring);
++#ifdef CONFIG_E1000_NAPI
++	kfree(adapter->polling_netdev);
++#endif
++
+ 	iounmap(adapter->hw.hw_addr);
+ 	pci_release_regions(pdev);
+ 
++#ifdef CONFIG_E1000_MQ
++	free_percpu(adapter->cpu_netdev);
++	free_percpu(adapter->cpu_tx_ring);
++#endif
+ 	free_netdev(netdev);
+ 
+ 	pci_disable_device(pdev);
+@@ -783,6 +856,9 @@ e1000_sw_init(struct e1000_adapter *adap
+ 	struct e1000_hw *hw = &adapter->hw;
+ 	struct net_device *netdev = adapter->netdev;
+ 	struct pci_dev *pdev = adapter->pdev;
++#ifdef CONFIG_E1000_NAPI
++	int i;
++#endif
+ 
+ 	/* PCI config space info */
+ 
+@@ -840,14 +916,123 @@ e1000_sw_init(struct e1000_adapter *adap
+ 		hw->master_slave = E1000_MASTER_SLAVE;
+ 	}
+ 
++#ifdef CONFIG_E1000_MQ
++	/* Number of supported queues */
++	switch (hw->mac_type) {
++	case e1000_82571:
++	case e1000_82572:
++		adapter->num_queues = 2;
++		break;
++	default:
++		adapter->num_queues = 1;
++		break;
++	}
++	adapter->num_queues = min(adapter->num_queues, num_online_cpus());
++#else
++	adapter->num_queues = 1;
++#endif
++
++	if (e1000_alloc_queues(adapter)) {
++		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
++		return -ENOMEM;
++	}
++
++#ifdef CONFIG_E1000_NAPI
++	for (i = 0; i < adapter->num_queues; i++) {
++		adapter->polling_netdev[i].priv = adapter;
++		adapter->polling_netdev[i].poll = &e1000_clean;
++		adapter->polling_netdev[i].weight = 64;
++		dev_hold(&adapter->polling_netdev[i]);
++		set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
++	}
++#endif
++
++#ifdef CONFIG_E1000_MQ
++	e1000_setup_queue_mapping(adapter);
++#endif
++
+ 	atomic_set(&adapter->irq_sem, 1);
+ 	spin_lock_init(&adapter->stats_lock);
+-	spin_lock_init(&adapter->tx_lock);
+ 
+ 	return 0;
+ }
+ 
+ /**
++ * e1000_alloc_queues - Allocate memory for all rings
++ * @adapter: board private structure to initialize
++ *
++ * We allocate one ring per queue at run-time since we don't know the
++ * number of queues at compile-time.  The polling_netdev array is
++ * intended for Multiqueue, but should work fine with a single queue.
++ **/
++
++static int __devinit
++e1000_alloc_queues(struct e1000_adapter *adapter)
++{
++	int size;
++
++	size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
++	adapter->tx_ring = kmalloc(size, GFP_KERNEL);
++	if (!adapter->tx_ring)
++		return -ENOMEM;
++	memset(adapter->tx_ring, 0, size);
++
++	size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
++	adapter->rx_ring = kmalloc(size, GFP_KERNEL);
++	if (!adapter->rx_ring) {
++		kfree(adapter->tx_ring);
++		return -ENOMEM;
++	}
++	memset(adapter->rx_ring, 0, size);
++
++#ifdef CONFIG_E1000_NAPI
++	size = sizeof(struct net_device) * adapter->num_queues;
++	adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
++	if (!adapter->polling_netdev) {
++		kfree(adapter->tx_ring);
++		kfree(adapter->rx_ring);
++		return -ENOMEM;
++	}
++	memset(adapter->polling_netdev, 0, size);
++#endif
++
++	return E1000_SUCCESS;
++}
++
++#ifdef CONFIG_E1000_MQ
++static void __devinit
++e1000_setup_queue_mapping(struct e1000_adapter *adapter)
++{
++	int i, cpu;
++
++	adapter->rx_sched_call_data.func = e1000_rx_schedule;
++	adapter->rx_sched_call_data.info = adapter->netdev;
++	cpus_clear(adapter->rx_sched_call_data.cpumask);
++
++	adapter->cpu_netdev = alloc_percpu(struct net_device *);
++	adapter->cpu_tx_ring = alloc_percpu(struct e1000_tx_ring *);
++
++	lock_cpu_hotplug();
++	i = 0;
++	for_each_online_cpu(cpu) {
++		*per_cpu_ptr(adapter->cpu_tx_ring, cpu) = &adapter->tx_ring[i % adapter->num_queues];
++		/* This is incomplete because we'd like to assign separate
++		 * physical cpus to these netdev polling structures and
++		 * avoid saturating a subset of cpus.
++		 */
++		if (i < adapter->num_queues) {
++			*per_cpu_ptr(adapter->cpu_netdev, cpu) = &adapter->polling_netdev[i];
++			adapter->cpu_for_queue[i] = cpu;
++		} else
++			*per_cpu_ptr(adapter->cpu_netdev, cpu) = NULL;
++
++		i++;
++	}
++	unlock_cpu_hotplug();
++}
++#endif
++
++/**
+  * e1000_open - Called when a network interface is made active
+  * @netdev: network interface device structure
+  *
+@@ -868,12 +1053,12 @@ e1000_open(struct net_device *netdev)
+ 
+ 	/* allocate transmit descriptors */
+ 
+-	if((err = e1000_setup_tx_resources(adapter)))
++	if ((err = e1000_setup_all_tx_resources(adapter)))
+ 		goto err_setup_tx;
+ 
+ 	/* allocate receive descriptors */
+ 
+-	if((err = e1000_setup_rx_resources(adapter)))
++	if ((err = e1000_setup_all_rx_resources(adapter)))
+ 		goto err_setup_rx;
+ 
+ 	if((err = e1000_up(adapter)))
+@@ -887,9 +1072,9 @@ e1000_open(struct net_device *netdev)
+ 	return E1000_SUCCESS;
+ 
+ err_up:
+-	e1000_free_rx_resources(adapter);
++	e1000_free_all_rx_resources(adapter);
+ err_setup_rx:
+-	e1000_free_tx_resources(adapter);
++	e1000_free_all_tx_resources(adapter);
+ err_setup_tx:
+ 	e1000_reset(adapter);
+ 
+@@ -915,8 +1100,8 @@ e1000_close(struct net_device *netdev)
+ 
+ 	e1000_down(adapter);
+ 
+-	e1000_free_tx_resources(adapter);
+-	e1000_free_rx_resources(adapter);
++	e1000_free_all_tx_resources(adapter);
++	e1000_free_all_rx_resources(adapter);
+ 
+ 	if((adapter->hw.mng_cookie.status &
+ 			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
+@@ -951,25 +1136,28 @@ e1000_check_64k_bound(struct e1000_adapt
+ /**
+  * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
+  * @adapter: board private structure
++ * @txdr:    tx descriptor ring (for a specific queue) to setup
+  *
+  * Return 0 on success, negative on failure
+  **/
+ 
+ int
+-e1000_setup_tx_resources(struct e1000_adapter *adapter)
++e1000_setup_tx_resources(struct e1000_adapter *adapter,
++                         struct e1000_tx_ring *txdr)
+ {
+-	struct e1000_desc_ring *txdr = &adapter->tx_ring;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 	int size;
+ 
+ 	size = sizeof(struct e1000_buffer) * txdr->count;
+-	txdr->buffer_info = vmalloc(size);
++
++	txdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
+ 	if(!txdr->buffer_info) {
+ 		DPRINTK(PROBE, ERR,
+ 		"Unable to allocate memory for the transmit descriptor ring\n");
+ 		return -ENOMEM;
+ 	}
+ 	memset(txdr->buffer_info, 0, size);
++	memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer));
+ 
+ 	/* round up to nearest 4K */
+ 
+@@ -1018,11 +1206,41 @@ setup_tx_desc_die:
+ 
+ 	txdr->next_to_use = 0;
+ 	txdr->next_to_clean = 0;
++	spin_lock_init(&txdr->tx_lock);
+ 
+ 	return 0;
+ }
+ 
+ /**
++ * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
++ * 				  (Descriptors) for all queues
++ * @adapter: board private structure
++ *
++ * If this function returns with an error, then it's possible one or
++ * more of the rings is populated (while the rest are not).  It is the
++ * callers duty to clean those orphaned rings.
++ *
++ * Return 0 on success, negative on failure
++ **/
++
++int
++e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
++{
++	int i, err = 0;
++
++	for (i = 0; i < adapter->num_queues; i++) {
++		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
++		if (err) {
++			DPRINTK(PROBE, ERR,
++				"Allocation for Tx Queue %u failed\n", i);
++			break;
++		}
++	}
++
++	return err;
++}
++
++/**
+  * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
+  * @adapter: board private structure
+  *
+@@ -1032,23 +1250,43 @@ setup_tx_desc_die:
+ static void
+ e1000_configure_tx(struct e1000_adapter *adapter)
+ {
+-	uint64_t tdba = adapter->tx_ring.dma;
+-	uint32_t tdlen = adapter->tx_ring.count * sizeof(struct e1000_tx_desc);
+-	uint32_t tctl, tipg;
+-
+-	E1000_WRITE_REG(&adapter->hw, TDBAL, (tdba & 0x00000000ffffffffULL));
+-	E1000_WRITE_REG(&adapter->hw, TDBAH, (tdba >> 32));
+-
+-	E1000_WRITE_REG(&adapter->hw, TDLEN, tdlen);
++	uint64_t tdba;
++	struct e1000_hw *hw = &adapter->hw;
++	uint32_t tdlen, tctl, tipg, tarc;
+ 
+ 	/* Setup the HW Tx Head and Tail descriptor pointers */
+ 
+-	E1000_WRITE_REG(&adapter->hw, TDH, 0);
+-	E1000_WRITE_REG(&adapter->hw, TDT, 0);
++	switch (adapter->num_queues) {
++	case 2:
++		tdba = adapter->tx_ring[1].dma;
++		tdlen = adapter->tx_ring[1].count *
++			sizeof(struct e1000_tx_desc);
++		E1000_WRITE_REG(hw, TDBAL1, (tdba & 0x00000000ffffffffULL));
++		E1000_WRITE_REG(hw, TDBAH1, (tdba >> 32));
++		E1000_WRITE_REG(hw, TDLEN1, tdlen);
++		E1000_WRITE_REG(hw, TDH1, 0);
++		E1000_WRITE_REG(hw, TDT1, 0);
++		adapter->tx_ring[1].tdh = E1000_TDH1;
++		adapter->tx_ring[1].tdt = E1000_TDT1;
++		/* Fall Through */
++	case 1:
++	default:
++		tdba = adapter->tx_ring[0].dma;
++		tdlen = adapter->tx_ring[0].count *
++			sizeof(struct e1000_tx_desc);
++		E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
++		E1000_WRITE_REG(hw, TDBAH, (tdba >> 32));
++		E1000_WRITE_REG(hw, TDLEN, tdlen);
++		E1000_WRITE_REG(hw, TDH, 0);
++		E1000_WRITE_REG(hw, TDT, 0);
++		adapter->tx_ring[0].tdh = E1000_TDH;
++		adapter->tx_ring[0].tdt = E1000_TDT;
++		break;
++	}
+ 
+ 	/* Set the default values for the Tx Inter Packet Gap timer */
+ 
+-	switch (adapter->hw.mac_type) {
++	switch (hw->mac_type) {
+ 	case e1000_82542_rev2_0:
+ 	case e1000_82542_rev2_1:
+ 		tipg = DEFAULT_82542_TIPG_IPGT;
+@@ -1056,67 +1294,81 @@ e1000_configure_tx(struct e1000_adapter 
+ 		tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+ 		break;
+ 	default:
+-		if(adapter->hw.media_type == e1000_media_type_fiber ||
+-		   adapter->hw.media_type == e1000_media_type_internal_serdes)
++		if (hw->media_type == e1000_media_type_fiber ||
++		    hw->media_type == e1000_media_type_internal_serdes)
+ 			tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
+ 		else
+ 			tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
+ 		tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
+ 		tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+ 	}
+-	E1000_WRITE_REG(&adapter->hw, TIPG, tipg);
++	E1000_WRITE_REG(hw, TIPG, tipg);
+ 
+ 	/* Set the Tx Interrupt Delay register */
+ 
+-	E1000_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay);
+-	if(adapter->hw.mac_type >= e1000_82540)
+-		E1000_WRITE_REG(&adapter->hw, TADV, adapter->tx_abs_int_delay);
++	E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
++	if (hw->mac_type >= e1000_82540)
++		E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
+ 
+ 	/* Program the Transmit Control Register */
+ 
+-	tctl = E1000_READ_REG(&adapter->hw, TCTL);
++	tctl = E1000_READ_REG(hw, TCTL);
+ 
+ 	tctl &= ~E1000_TCTL_CT;
+-	tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
++	tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_RTLC |
+ 		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+ 
+-	E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
++	E1000_WRITE_REG(hw, TCTL, tctl);
++
++	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
++		tarc = E1000_READ_REG(hw, TARC0);
++		tarc |= ((1 << 25) | (1 << 21));
++		E1000_WRITE_REG(hw, TARC0, tarc);
++		tarc = E1000_READ_REG(hw, TARC1);
++		tarc |= (1 << 25);
++		if (tctl & E1000_TCTL_MULR)
++			tarc &= ~(1 << 28);
++		else
++			tarc |= (1 << 28);
++		E1000_WRITE_REG(hw, TARC1, tarc);
++	}
+ 
+-	e1000_config_collision_dist(&adapter->hw);
++	e1000_config_collision_dist(hw);
+ 
+ 	/* Setup Transmit Descriptor Settings for eop descriptor */
+ 	adapter->txd_cmd = E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP |
+ 		E1000_TXD_CMD_IFCS;
+ 
+-	if(adapter->hw.mac_type < e1000_82543)
++	if (hw->mac_type < e1000_82543)
+ 		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
+ 	else
+ 		adapter->txd_cmd |= E1000_TXD_CMD_RS;
+ 
+ 	/* Cache if we're 82544 running in PCI-X because we'll
+ 	 * need this to apply a workaround later in the send path. */
+-	if(adapter->hw.mac_type == e1000_82544 &&
+-	   adapter->hw.bus_type == e1000_bus_type_pcix)
++	if (hw->mac_type == e1000_82544 &&
++	    hw->bus_type == e1000_bus_type_pcix)
+ 		adapter->pcix_82544 = 1;
+ }
+ 
+ /**
+  * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
+  * @adapter: board private structure
++ * @rxdr:    rx descriptor ring (for a specific queue) to setup
+  *
+  * Returns 0 on success, negative on failure
+  **/
+ 
+ int
+-e1000_setup_rx_resources(struct e1000_adapter *adapter)
++e1000_setup_rx_resources(struct e1000_adapter *adapter,
++                         struct e1000_rx_ring *rxdr)
+ {
+-	struct e1000_desc_ring *rxdr = &adapter->rx_ring;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 	int size, desc_len;
+ 
+ 	size = sizeof(struct e1000_buffer) * rxdr->count;
+-	rxdr->buffer_info = vmalloc(size);
+-	if(!rxdr->buffer_info) {
++	rxdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
++	if (!rxdr->buffer_info) {
+ 		DPRINTK(PROBE, ERR,
+ 		"Unable to allocate memory for the receive descriptor ring\n");
+ 		return -ENOMEM;
+@@ -1156,13 +1408,13 @@ e1000_setup_rx_resources(struct e1000_ad
+ 
+ 	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
+ 
+-	if(!rxdr->desc) {
++	if (!rxdr->desc) {
++		DPRINTK(PROBE, ERR,
++		"Unable to allocate memory for the receive descriptor ring\n");
+ setup_rx_desc_die:
+ 		vfree(rxdr->buffer_info);
+ 		kfree(rxdr->ps_page);
+ 		kfree(rxdr->ps_page_dma);
+-		DPRINTK(PROBE, ERR,
+-		"Unable to allocate memory for the receive descriptor ring\n");
+ 		return -ENOMEM;
+ 	}
+ 
+@@ -1174,9 +1426,12 @@ setup_rx_desc_die:
+ 				     "at %p\n", rxdr->size, rxdr->desc);
+ 		/* Try again, without freeing the previous */
+ 		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
+-		if(!rxdr->desc) {
+ 		/* Failed allocation, critical failure */
++		if (!rxdr->desc) {
+ 			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
++			DPRINTK(PROBE, ERR,
++				"Unable to allocate memory "
++				"for the receive descriptor ring\n");
+ 			goto setup_rx_desc_die;
+ 		}
+ 
+@@ -1188,10 +1443,7 @@ setup_rx_desc_die:
+ 			DPRINTK(PROBE, ERR,
+ 				"Unable to allocate aligned memory "
+ 				"for the receive descriptor ring\n");
+-			vfree(rxdr->buffer_info);
+-			kfree(rxdr->ps_page);
+-			kfree(rxdr->ps_page_dma);
+-			return -ENOMEM;
++			goto setup_rx_desc_die;
+ 		} else {
+ 			/* Free old allocation, new allocation was successful */
+ 			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+@@ -1206,15 +1458,48 @@ setup_rx_desc_die:
+ }
+ 
+ /**
++ * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
++ * 				  (Descriptors) for all queues
++ * @adapter: board private structure
++ *
++ * If this function returns with an error, then it's possible one or
++ * more of the rings is populated (while the rest are not).  It is the
++ * callers duty to clean those orphaned rings.
++ *
++ * Return 0 on success, negative on failure
++ **/
++
++int
++e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
++{
++	int i, err = 0;
++
++	for (i = 0; i < adapter->num_queues; i++) {
++		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
++		if (err) {
++			DPRINTK(PROBE, ERR,
++				"Allocation for Rx Queue %u failed\n", i);
++			break;
++		}
++	}
++
++	return err;
++}
++
++/**
+  * e1000_setup_rctl - configure the receive control registers
+  * @adapter: Board private structure
+  **/
+-
++#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
++			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
+ static void
+ e1000_setup_rctl(struct e1000_adapter *adapter)
+ {
+ 	uint32_t rctl, rfctl;
+ 	uint32_t psrctl = 0;
++#ifdef CONFIG_E1000_PACKET_SPLIT
++	uint32_t pages = 0;
++#endif
+ 
+ 	rctl = E1000_READ_REG(&adapter->hw, RCTL);
+ 
+@@ -1235,7 +1520,7 @@ e1000_setup_rctl(struct e1000_adapter *a
+ 		rctl |= E1000_RCTL_LPE;
+ 
+ 	/* Setup buffer sizes */
+-	if(adapter->hw.mac_type == e1000_82573) {
++	if(adapter->hw.mac_type >= e1000_82571) {
+ 		/* We can now specify buffers in 1K increments.
+ 		 * BSIZE and BSEX are ignored in this case. */
+ 		rctl |= adapter->rx_buffer_len << 0x11;
+@@ -1268,11 +1553,14 @@ e1000_setup_rctl(struct e1000_adapter *a
+ 	 * followed by the page buffers.  Therefore, skb->data is
+ 	 * sized to hold the largest protocol header.
+ 	 */
+-	adapter->rx_ps = (adapter->hw.mac_type > e1000_82547_rev_2) 
+-			  && (adapter->netdev->mtu 
+-	                      < ((3 * PAGE_SIZE) + adapter->rx_ps_bsize0));
++	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
++	if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) &&
++	    PAGE_SIZE <= 16384)
++		adapter->rx_ps_pages = pages;
++	else
++		adapter->rx_ps_pages = 0;
+ #endif
+-	if(adapter->rx_ps) {
++	if (adapter->rx_ps_pages) {
+ 		/* Configure extra packet-split registers */
+ 		rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
+ 		rfctl |= E1000_RFCTL_EXTEN;
+@@ -1284,12 +1572,19 @@ e1000_setup_rctl(struct e1000_adapter *a
+ 		
+ 		psrctl |= adapter->rx_ps_bsize0 >>
+ 			E1000_PSRCTL_BSIZE0_SHIFT;
+-		psrctl |= PAGE_SIZE >>
+-			E1000_PSRCTL_BSIZE1_SHIFT;
+-		psrctl |= PAGE_SIZE <<
+-			E1000_PSRCTL_BSIZE2_SHIFT;
+-		psrctl |= PAGE_SIZE <<
+-			E1000_PSRCTL_BSIZE3_SHIFT;
++
++		switch (adapter->rx_ps_pages) {
++		case 3:
++			psrctl |= PAGE_SIZE <<
++				E1000_PSRCTL_BSIZE3_SHIFT;
++		case 2:
++			psrctl |= PAGE_SIZE <<
++				E1000_PSRCTL_BSIZE2_SHIFT;
++		case 1:
++			psrctl |= PAGE_SIZE >>
++				E1000_PSRCTL_BSIZE1_SHIFT;
++			break;
++		}
+ 
+ 		E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
+ 	}
+@@ -1307,91 +1602,181 @@ e1000_setup_rctl(struct e1000_adapter *a
+ static void
+ e1000_configure_rx(struct e1000_adapter *adapter)
+ {
+-	uint64_t rdba = adapter->rx_ring.dma;
+-	uint32_t rdlen, rctl, rxcsum;
++	uint64_t rdba;
++	struct e1000_hw *hw = &adapter->hw;
++	uint32_t rdlen, rctl, rxcsum, ctrl_ext;
++#ifdef CONFIG_E1000_MQ
++	uint32_t reta, mrqc;
++	int i;
++#endif
+ 
+-	if(adapter->rx_ps) {
+-		rdlen = adapter->rx_ring.count *
++	if (adapter->rx_ps_pages) {
++		rdlen = adapter->rx_ring[0].count *
+ 			sizeof(union e1000_rx_desc_packet_split);
+ 		adapter->clean_rx = e1000_clean_rx_irq_ps;
+ 		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
+ 	} else {
+-		rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc);
++		rdlen = adapter->rx_ring[0].count *
++			sizeof(struct e1000_rx_desc);
+ 		adapter->clean_rx = e1000_clean_rx_irq;
+ 		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
+ 	}
+ 
+ 	/* disable receives while setting up the descriptors */
+-	rctl = E1000_READ_REG(&adapter->hw, RCTL);
+-	E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN);
++	rctl = E1000_READ_REG(hw, RCTL);
++	E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
+ 
+ 	/* set the Receive Delay Timer Register */
+-	E1000_WRITE_REG(&adapter->hw, RDTR, adapter->rx_int_delay);
++	E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
+ 
+-	if(adapter->hw.mac_type >= e1000_82540) {
+-		E1000_WRITE_REG(&adapter->hw, RADV, adapter->rx_abs_int_delay);
++	if (hw->mac_type >= e1000_82540) {
++		E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
+ 		if(adapter->itr > 1)
+-			E1000_WRITE_REG(&adapter->hw, ITR,
++			E1000_WRITE_REG(hw, ITR,
+ 				1000000000 / (adapter->itr * 256));
+ 	}
+ 
+-	/* Setup the Base and Length of the Rx Descriptor Ring */
+-	E1000_WRITE_REG(&adapter->hw, RDBAL, (rdba & 0x00000000ffffffffULL));
+-	E1000_WRITE_REG(&adapter->hw, RDBAH, (rdba >> 32));
+-
+-	E1000_WRITE_REG(&adapter->hw, RDLEN, rdlen);
+-
+-	/* Setup the HW Rx Head and Tail Descriptor Pointers */
+-	E1000_WRITE_REG(&adapter->hw, RDH, 0);
+-	E1000_WRITE_REG(&adapter->hw, RDT, 0);
++	if (hw->mac_type >= e1000_82571) {
++		/* Reset delay timers after every interrupt */
++		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
++		ctrl_ext |= E1000_CTRL_EXT_CANC;
++		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
++		E1000_WRITE_FLUSH(hw);
++	}
++
++	/* Setup the HW Rx Head and Tail Descriptor Pointers and
++	 * the Base and Length of the Rx Descriptor Ring */
++	switch (adapter->num_queues) {
++#ifdef CONFIG_E1000_MQ
++	case 2:
++		rdba = adapter->rx_ring[1].dma;
++		E1000_WRITE_REG(hw, RDBAL1, (rdba & 0x00000000ffffffffULL));
++		E1000_WRITE_REG(hw, RDBAH1, (rdba >> 32));
++		E1000_WRITE_REG(hw, RDLEN1, rdlen);
++		E1000_WRITE_REG(hw, RDH1, 0);
++		E1000_WRITE_REG(hw, RDT1, 0);
++		adapter->rx_ring[1].rdh = E1000_RDH1;
++		adapter->rx_ring[1].rdt = E1000_RDT1;
++		/* Fall Through */
++#endif
++	case 1:
++	default:
++		rdba = adapter->rx_ring[0].dma;
++		E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
++		E1000_WRITE_REG(hw, RDBAH, (rdba >> 32));
++		E1000_WRITE_REG(hw, RDLEN, rdlen);
++		E1000_WRITE_REG(hw, RDH, 0);
++		E1000_WRITE_REG(hw, RDT, 0);
++		adapter->rx_ring[0].rdh = E1000_RDH;
++		adapter->rx_ring[0].rdt = E1000_RDT;
++		break;
++	}
++
++#ifdef CONFIG_E1000_MQ
++	if (adapter->num_queues > 1) {
++		uint32_t random[10];
++
++		get_random_bytes(&random[0], 40);
++
++		if (hw->mac_type <= e1000_82572) {
++			E1000_WRITE_REG(hw, RSSIR, 0);
++			E1000_WRITE_REG(hw, RSSIM, 0);
++		}
++
++		switch (adapter->num_queues) {
++		case 2:
++		default:
++			reta = 0x00800080;
++			mrqc = E1000_MRQC_ENABLE_RSS_2Q;
++			break;
++		}
++
++		/* Fill out redirection table */
++		for (i = 0; i < 32; i++)
++			E1000_WRITE_REG_ARRAY(hw, RETA, i, reta);
++		/* Fill out hash function seeds */
++		for (i = 0; i < 10; i++)
++			E1000_WRITE_REG_ARRAY(hw, RSSRK, i, random[i]);
++
++		mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
++			 E1000_MRQC_RSS_FIELD_IPV4_TCP);
++		E1000_WRITE_REG(hw, MRQC, mrqc);
++	}
++
++	/* Multiqueue and packet checksumming are mutually exclusive. */
++	if (hw->mac_type >= e1000_82571) {
++		rxcsum = E1000_READ_REG(hw, RXCSUM);
++		rxcsum |= E1000_RXCSUM_PCSD;
++		E1000_WRITE_REG(hw, RXCSUM, rxcsum);
++	}
++
++#else
+ 
+ 	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
+-	if(adapter->hw.mac_type >= e1000_82543) {
+-		rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM);
++	if (hw->mac_type >= e1000_82543) {
++		rxcsum = E1000_READ_REG(hw, RXCSUM);
+ 		if(adapter->rx_csum == TRUE) {
+ 			rxcsum |= E1000_RXCSUM_TUOFL;
+ 
+-			/* Enable 82573 IPv4 payload checksum for UDP fragments
++			/* Enable 82571 IPv4 payload checksum for UDP fragments
+ 			 * Must be used in conjunction with packet-split. */
+-			if((adapter->hw.mac_type > e1000_82547_rev_2) && 
+-			   (adapter->rx_ps)) {
++			if ((hw->mac_type >= e1000_82571) && 
++			   (adapter->rx_ps_pages)) {
+ 				rxcsum |= E1000_RXCSUM_IPPCSE;
+ 			}
+ 		} else {
+ 			rxcsum &= ~E1000_RXCSUM_TUOFL;
+ 			/* don't need to clear IPPCSE as it defaults to 0 */
+ 		}
+-		E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum);
++		E1000_WRITE_REG(hw, RXCSUM, rxcsum);
+ 	}
++#endif /* CONFIG_E1000_MQ */
+ 
+-	if (adapter->hw.mac_type == e1000_82573)
+-		E1000_WRITE_REG(&adapter->hw, ERT, 0x0100);
++	if (hw->mac_type == e1000_82573)
++		E1000_WRITE_REG(hw, ERT, 0x0100);
+ 
+ 	/* Enable Receives */
+-	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
++	E1000_WRITE_REG(hw, RCTL, rctl);
+ }
+ 
+ /**
+- * e1000_free_tx_resources - Free Tx Resources
++ * e1000_free_tx_resources - Free Tx Resources per Queue
+  * @adapter: board private structure
++ * @tx_ring: Tx descriptor ring for a specific queue
+  *
+  * Free all transmit software resources
+  **/
+ 
+ void
+-e1000_free_tx_resources(struct e1000_adapter *adapter)
++e1000_free_tx_resources(struct e1000_adapter *adapter,
++                        struct e1000_tx_ring *tx_ring)
+ {
+ 	struct pci_dev *pdev = adapter->pdev;
+ 
+-	e1000_clean_tx_ring(adapter);
++	e1000_clean_tx_ring(adapter, tx_ring);
+ 
+-	vfree(adapter->tx_ring.buffer_info);
+-	adapter->tx_ring.buffer_info = NULL;
++	vfree(tx_ring->buffer_info);
++	tx_ring->buffer_info = NULL;
+ 
+-	pci_free_consistent(pdev, adapter->tx_ring.size,
+-	                    adapter->tx_ring.desc, adapter->tx_ring.dma);
++	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
++
++	tx_ring->desc = NULL;
++}
++
++/**
++ * e1000_free_all_tx_resources - Free Tx Resources for All Queues
++ * @adapter: board private structure
++ *
++ * Free all transmit software resources
++ **/
++
++void
++e1000_free_all_tx_resources(struct e1000_adapter *adapter)
++{
++	int i;
+ 
+-	adapter->tx_ring.desc = NULL;
++	for (i = 0; i < adapter->num_queues; i++)
++		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
+ }
+ 
+ static inline void
+@@ -1414,21 +1799,22 @@ e1000_unmap_and_free_tx_resource(struct 
+ /**
+  * e1000_clean_tx_ring - Free Tx Buffers
+  * @adapter: board private structure
++ * @tx_ring: ring to be cleaned
+  **/
+ 
+ static void
+-e1000_clean_tx_ring(struct e1000_adapter *adapter)
++e1000_clean_tx_ring(struct e1000_adapter *adapter,
++                    struct e1000_tx_ring *tx_ring)
+ {
+-	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ 	struct e1000_buffer *buffer_info;
+ 	unsigned long size;
+ 	unsigned int i;
+ 
+ 	/* Free all the Tx ring sk_buffs */
+ 
+-	if (likely(adapter->previous_buffer_info.skb != NULL)) {
++	if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
+ 		e1000_unmap_and_free_tx_resource(adapter,
+-				&adapter->previous_buffer_info);
++				&tx_ring->previous_buffer_info);
+ 	}
+ 
+ 	for(i = 0; i < tx_ring->count; i++) {
+@@ -1446,24 +1832,39 @@ e1000_clean_tx_ring(struct e1000_adapter
+ 	tx_ring->next_to_use = 0;
+ 	tx_ring->next_to_clean = 0;
+ 
+-	E1000_WRITE_REG(&adapter->hw, TDH, 0);
+-	E1000_WRITE_REG(&adapter->hw, TDT, 0);
++	writel(0, adapter->hw.hw_addr + tx_ring->tdh);
++	writel(0, adapter->hw.hw_addr + tx_ring->tdt);
++}
++
++/**
++ * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
++ * @adapter: board private structure
++ **/
++
++static void
++e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
++{
++	int i;
++
++	for (i = 0; i < adapter->num_queues; i++)
++		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
+ }
+ 
+ /**
+  * e1000_free_rx_resources - Free Rx Resources
+  * @adapter: board private structure
++ * @rx_ring: ring to clean the resources from
+  *
+  * Free all receive software resources
+  **/
+ 
+ void
+-e1000_free_rx_resources(struct e1000_adapter *adapter)
++e1000_free_rx_resources(struct e1000_adapter *adapter,
++                        struct e1000_rx_ring *rx_ring)
+ {
+-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 
+-	e1000_clean_rx_ring(adapter);
++	e1000_clean_rx_ring(adapter, rx_ring);
+ 
+ 	vfree(rx_ring->buffer_info);
+ 	rx_ring->buffer_info = NULL;
+@@ -1478,14 +1879,31 @@ e1000_free_rx_resources(struct e1000_ada
+ }
+ 
+ /**
+- * e1000_clean_rx_ring - Free Rx Buffers
++ * e1000_free_all_rx_resources - Free Rx Resources for All Queues
+  * @adapter: board private structure
++ *
++ * Free all receive software resources
++ **/
++
++void
++e1000_free_all_rx_resources(struct e1000_adapter *adapter)
++{
++	int i;
++
++	for (i = 0; i < adapter->num_queues; i++)
++		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
++}
++
++/**
++ * e1000_clean_rx_ring - Free Rx Buffers per Queue
++ * @adapter: board private structure
++ * @rx_ring: ring to free buffers from
+  **/
+ 
+ static void
+-e1000_clean_rx_ring(struct e1000_adapter *adapter)
++e1000_clean_rx_ring(struct e1000_adapter *adapter,
++                    struct e1000_rx_ring *rx_ring)
+ {
+-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ 	struct e1000_buffer *buffer_info;
+ 	struct e1000_ps_page *ps_page;
+ 	struct e1000_ps_page_dma *ps_page_dma;
+@@ -1508,7 +1926,7 @@ e1000_clean_rx_ring(struct e1000_adapter
+ 			dev_kfree_skb(buffer_info->skb);
+ 			buffer_info->skb = NULL;
+ 
+-			for(j = 0; j < PS_PAGE_BUFFERS; j++) {
++			for(j = 0; j < adapter->rx_ps_pages; j++) {
+ 				if(!ps_page->ps_page[j]) break;
+ 				pci_unmap_single(pdev,
+ 						 ps_page_dma->ps_page_dma[j],
+@@ -1534,8 +1952,22 @@ e1000_clean_rx_ring(struct e1000_adapter
+ 	rx_ring->next_to_clean = 0;
+ 	rx_ring->next_to_use = 0;
+ 
+-	E1000_WRITE_REG(&adapter->hw, RDH, 0);
+-	E1000_WRITE_REG(&adapter->hw, RDT, 0);
++	writel(0, adapter->hw.hw_addr + rx_ring->rdh);
++	writel(0, adapter->hw.hw_addr + rx_ring->rdt);
++}
++
++/**
++ * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
++ * @adapter: board private structure
++ **/
++
++static void
++e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
++{
++	int i;
++
++	for (i = 0; i < adapter->num_queues; i++)
++		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
+ }
+ 
+ /* The 82542 2.0 (revision 2) needs to have the receive unit in reset
+@@ -1556,7 +1988,7 @@ e1000_enter_82542_rst(struct e1000_adapt
+ 	mdelay(5);
+ 
+ 	if(netif_running(netdev))
+-		e1000_clean_rx_ring(adapter);
++		e1000_clean_all_rx_rings(adapter);
+ }
+ 
+ static void
+@@ -1576,7 +2008,7 @@ e1000_leave_82542_rst(struct e1000_adapt
+ 
+ 	if(netif_running(netdev)) {
+ 		e1000_configure_rx(adapter);
+-		e1000_alloc_rx_buffers(adapter);
++		e1000_alloc_rx_buffers(adapter, &adapter->rx_ring[0]);
+ 	}
+ }
+ 
+@@ -1607,6 +2039,22 @@ e1000_set_mac(struct net_device *netdev,
+ 
+ 	e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
+ 
++	/* With 82571 controllers, LAA may be overwritten (with the default)
++	 * due to controller reset from the other port. */
++	if (adapter->hw.mac_type == e1000_82571) {
++		/* activate the work around */
++		adapter->hw.laa_is_present = 1;
++
++		/* Hold a copy of the LAA in RAR[14] This is done so that 
++		 * between the time RAR[0] gets clobbered  and the time it 
++		 * gets fixed (in e1000_watchdog), the actual LAA is in one 
++		 * of the RARs and no incoming packets directed to this port
++		 * are dropped. Eventaully the LAA will be in RAR[0] and 
++		 * RAR[14] */
++		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 
++					E1000_RAR_ENTRIES - 1);
++	}
++
+ 	if(adapter->hw.mac_type == e1000_82542_rev2_0)
+ 		e1000_leave_82542_rst(adapter);
+ 
+@@ -1629,12 +2077,13 @@ e1000_set_multi(struct net_device *netde
+ 	struct e1000_adapter *adapter = netdev_priv(netdev);
+ 	struct e1000_hw *hw = &adapter->hw;
+ 	struct dev_mc_list *mc_ptr;
+-	unsigned long flags;
+ 	uint32_t rctl;
+ 	uint32_t hash_value;
+-	int i;
++	int i, rar_entries = E1000_RAR_ENTRIES;
+ 
+-	spin_lock_irqsave(&adapter->tx_lock, flags);
++	/* reserve RAR[14] for LAA over-write work-around */
++	if (adapter->hw.mac_type == e1000_82571)
++		rar_entries--;
+ 
+ 	/* Check for Promiscuous and All Multicast modes */
+ 
+@@ -1659,11 +2108,12 @@ e1000_set_multi(struct net_device *netde
+ 	/* load the first 14 multicast address into the exact filters 1-14
+ 	 * RAR 0 is used for the station MAC adddress
+ 	 * if there are not 14 addresses, go ahead and clear the filters
++	 * -- with 82571 controllers only 0-13 entries are filled here
+ 	 */
+ 	mc_ptr = netdev->mc_list;
+ 
+-	for(i = 1; i < E1000_RAR_ENTRIES; i++) {
+-		if(mc_ptr) {
++	for(i = 1; i < rar_entries; i++) {
++		if (mc_ptr) {
+ 			e1000_rar_set(hw, mc_ptr->dmi_addr, i);
+ 			mc_ptr = mc_ptr->next;
+ 		} else {
+@@ -1686,8 +2136,6 @@ e1000_set_multi(struct net_device *netde
+ 
+ 	if(hw->mac_type == e1000_82542_rev2_0)
+ 		e1000_leave_82542_rst(adapter);
+-
+-	spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ }
+ 
+ /* Need to wait a few seconds after link up to get diagnostic information from
+@@ -1759,7 +2207,7 @@ static void
+ e1000_watchdog_task(struct e1000_adapter *adapter)
+ {
+ 	struct net_device *netdev = adapter->netdev;
+-	struct e1000_desc_ring *txdr = &adapter->tx_ring;
++	struct e1000_tx_ring *txdr = &adapter->tx_ring[0];
+ 	uint32_t link;
+ 
+ 	e1000_check_for_link(&adapter->hw);
+@@ -1818,8 +2266,8 @@ e1000_watchdog_task(struct e1000_adapter
+ 
+ 	e1000_update_adaptive(&adapter->hw);
+ 
+-	if(!netif_carrier_ok(netdev)) {
+-		if(E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
++	if (adapter->num_queues == 1 && !netif_carrier_ok(netdev)) {
++		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
+ 			/* We've lost link, so the controller stops DMA,
+ 			 * but we've got queued Tx work that's never going
+ 			 * to get done, so reset controller to flush Tx.
+@@ -1847,6 +2295,11 @@ e1000_watchdog_task(struct e1000_adapter
+ 	/* Force detection of hung controller every watchdog period */
+ 	adapter->detect_tx_hung = TRUE;
+ 
++	/* With 82571 controllers, LAA may be overwritten due to controller 
++	 * reset from the other port. Set the appropriate LAA in RAR[0] */
++	if (adapter->hw.mac_type == e1000_82571 && adapter->hw.laa_is_present)
++		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
++
+ 	/* Reset the timer */
+ 	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+ }
+@@ -1859,7 +2312,8 @@ e1000_watchdog_task(struct e1000_adapter
+ #define E1000_TX_FLAGS_VLAN_SHIFT	16
+ 
+ static inline int
+-e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
++e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
++          struct sk_buff *skb)
+ {
+ #ifdef NETIF_F_TSO
+ 	struct e1000_context_desc *context_desc;
+@@ -1910,8 +2364,8 @@ e1000_tso(struct e1000_adapter *adapter,
+ 		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
+ 			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
+ 
+-		i = adapter->tx_ring.next_to_use;
+-		context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
++		i = tx_ring->next_to_use;
++		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
+ 
+ 		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
+ 		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
+@@ -1923,8 +2377,8 @@ e1000_tso(struct e1000_adapter *adapter,
+ 		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
+ 		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
+ 
+-		if(++i == adapter->tx_ring.count) i = 0;
+-		adapter->tx_ring.next_to_use = i;
++		if (++i == tx_ring->count) i = 0;
++		tx_ring->next_to_use = i;
+ 
+ 		return 1;
+ 	}
+@@ -1934,7 +2388,8 @@ e1000_tso(struct e1000_adapter *adapter,
+ }
+ 
+ static inline boolean_t
+-e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
++e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
++              struct sk_buff *skb)
+ {
+ 	struct e1000_context_desc *context_desc;
+ 	unsigned int i;
+@@ -1943,8 +2398,8 @@ e1000_tx_csum(struct e1000_adapter *adap
+ 	if(likely(skb->ip_summed == CHECKSUM_HW)) {
+ 		css = skb->h.raw - skb->data;
+ 
+-		i = adapter->tx_ring.next_to_use;
+-		context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
++		i = tx_ring->next_to_use;
++		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
+ 
+ 		context_desc->upper_setup.tcp_fields.tucss = css;
+ 		context_desc->upper_setup.tcp_fields.tucso = css + skb->csum;
+@@ -1952,8 +2407,8 @@ e1000_tx_csum(struct e1000_adapter *adap
+ 		context_desc->tcp_seg_setup.data = 0;
+ 		context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
+ 
+-		if(unlikely(++i == adapter->tx_ring.count)) i = 0;
+-		adapter->tx_ring.next_to_use = i;
++		if (unlikely(++i == tx_ring->count)) i = 0;
++		tx_ring->next_to_use = i;
+ 
+ 		return TRUE;
+ 	}
+@@ -1965,11 +2420,10 @@ e1000_tx_csum(struct e1000_adapter *adap
+ #define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
+ 
+ static inline int
+-e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
+-	unsigned int first, unsigned int max_per_txd,
+-	unsigned int nr_frags, unsigned int mss)
++e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
++             struct sk_buff *skb, unsigned int first, unsigned int max_per_txd,
++             unsigned int nr_frags, unsigned int mss)
+ {
+-	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ 	struct e1000_buffer *buffer_info;
+ 	unsigned int len = skb->len;
+ 	unsigned int offset = 0, size, count = 0, i;
+@@ -2065,9 +2519,9 @@ e1000_tx_map(struct e1000_adapter *adapt
+ }
+ 
+ static inline void
+-e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
++e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
++               int tx_flags, int count)
+ {
+-	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ 	struct e1000_tx_desc *tx_desc = NULL;
+ 	struct e1000_buffer *buffer_info;
+ 	uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
+@@ -2113,7 +2567,7 @@ e1000_tx_queue(struct e1000_adapter *ada
+ 	wmb();
+ 
+ 	tx_ring->next_to_use = i;
+-	E1000_WRITE_REG(&adapter->hw, TDT, i);
++	writel(i, adapter->hw.hw_addr + tx_ring->tdt);
+ }
+ 
+ /**
+@@ -2206,6 +2660,7 @@ static int
+ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+ {
+ 	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_tx_ring *tx_ring;
+ 	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
+ 	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
+ 	unsigned int tx_flags = 0;
+@@ -2218,7 +2673,13 @@ e1000_xmit_frame(struct sk_buff *skb, st
+ 	unsigned int f;
+ 	len -= skb->data_len;
+ 
+-	if(unlikely(skb->len <= 0)) {
++#ifdef CONFIG_E1000_MQ
++	tx_ring = *per_cpu_ptr(adapter->cpu_tx_ring, smp_processor_id());
++#else
++	tx_ring = adapter->tx_ring;
++#endif
++
++	if (unlikely(skb->len <= 0)) {
+ 		dev_kfree_skb_any(skb);
+ 		return NETDEV_TX_OK;
+ 	}
+@@ -2262,21 +2723,42 @@ e1000_xmit_frame(struct sk_buff *skb, st
+ 	if(adapter->pcix_82544)
+ 		count += nr_frags;
+ 
+- 	local_irq_save(flags); 
+- 	if (!spin_trylock(&adapter->tx_lock)) { 
+- 		/* Collision - tell upper layer to requeue */ 
+- 		local_irq_restore(flags); 
+- 		return NETDEV_TX_LOCKED; 
+- 	} 
++#ifdef NETIF_F_TSO
++	/* TSO Workaround for 82571/2 Controllers -- if skb->data
++	 * points to just header, pull a few bytes of payload from 
++	 * frags into skb->data */
++	if (skb_shinfo(skb)->tso_size) {
++		uint8_t hdr_len;
++		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
++		if (skb->data_len && (hdr_len < (skb->len - skb->data_len)) && 
++			(adapter->hw.mac_type == e1000_82571 ||
++			adapter->hw.mac_type == e1000_82572)) {
++			unsigned int pull_size;
++			pull_size = min((unsigned int)4, skb->data_len);
++			if (!__pskb_pull_tail(skb, pull_size)) {
++				printk(KERN_ERR "__pskb_pull_tail failed.\n");
++				dev_kfree_skb_any(skb);
++				return -EFAULT;
++			}
++		}
++	}
++#endif
++
+ 	if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
+ 		e1000_transfer_dhcp_info(adapter, skb);
+ 
++	local_irq_save(flags);
++	if (!spin_trylock(&tx_ring->tx_lock)) {
++		/* Collision - tell upper layer to requeue */
++		local_irq_restore(flags);
++		return NETDEV_TX_LOCKED;
++	}
+ 
+ 	/* need: count + 2 desc gap to keep tail from touching
+ 	 * head, otherwise try next time */
+-	if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2)) {
++	if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
+ 		netif_stop_queue(netdev);
+-		spin_unlock_irqrestore(&adapter->tx_lock, flags);
++		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ 		return NETDEV_TX_BUSY;
+ 	}
+ 
+@@ -2284,7 +2766,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
+ 		if(unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
+ 			netif_stop_queue(netdev);
+ 			mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
+-			spin_unlock_irqrestore(&adapter->tx_lock, flags);
++			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ 			return NETDEV_TX_BUSY;
+ 		}
+ 	}
+@@ -2294,37 +2776,37 @@ e1000_xmit_frame(struct sk_buff *skb, st
+ 		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
+ 	}
+ 
+-	first = adapter->tx_ring.next_to_use;
++	first = tx_ring->next_to_use;
+ 	
+-	tso = e1000_tso(adapter, skb);
++	tso = e1000_tso(adapter, tx_ring, skb);
+ 	if (tso < 0) {
+ 		dev_kfree_skb_any(skb);
+-		spin_unlock_irqrestore(&adapter->tx_lock, flags);
++		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ 		return NETDEV_TX_OK;
+ 	}
+ 
+ 	if (likely(tso))
+ 		tx_flags |= E1000_TX_FLAGS_TSO;
+-	else if(likely(e1000_tx_csum(adapter, skb)))
++	else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
+ 		tx_flags |= E1000_TX_FLAGS_CSUM;
+ 
+ 	/* Old method was to assume IPv4 packet by default if TSO was enabled.
+-	 * 82573 hardware supports TSO capabilities for IPv6 as well...
++	 * 82571 hardware supports TSO capabilities for IPv6 as well...
+ 	 * no longer assume, we must. */
+-	if(likely(skb->protocol == ntohs(ETH_P_IP)))
++	if (likely(skb->protocol == ntohs(ETH_P_IP)))
+ 		tx_flags |= E1000_TX_FLAGS_IPV4;
+ 
+-	e1000_tx_queue(adapter,
+-		e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss),
+-		tx_flags);
++	e1000_tx_queue(adapter, tx_ring, tx_flags,
++	               e1000_tx_map(adapter, tx_ring, skb, first,
++	                            max_per_txd, nr_frags, mss));
+ 
+ 	netdev->trans_start = jiffies;
+ 
+ 	/* Make sure there is space in the ring for the next send. */
+-	if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < MAX_SKB_FRAGS + 2))
++	if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
+ 		netif_stop_queue(netdev);
+ 
+-	spin_unlock_irqrestore(&adapter->tx_lock, flags);
++	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ 	return NETDEV_TX_OK;
+ }
+ 
+@@ -2388,9 +2870,18 @@ e1000_change_mtu(struct net_device *netd
+ 			return -EINVAL;
+ 	}
+ 
+-#define MAX_STD_JUMBO_FRAME_SIZE 9216
++#define MAX_STD_JUMBO_FRAME_SIZE 9234
+ 	/* might want this to be bigger enum check... */
+-	if (adapter->hw.mac_type == e1000_82573 &&
++	/* 82571 controllers limit jumbo frame size to 10500 bytes */
++	if ((adapter->hw.mac_type == e1000_82571 || 
++	     adapter->hw.mac_type == e1000_82572) &&
++	    max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
++		DPRINTK(PROBE, ERR, "MTU > 9216 bytes not supported "
++				    "on 82571 and 82572 controllers.\n");
++		return -EINVAL;
++	}
++
++	if(adapter->hw.mac_type == e1000_82573 &&
+ 	    max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
+ 		DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
+ 				    "on 82573\n");
+@@ -2578,6 +3069,29 @@ e1000_update_stats(struct e1000_adapter 
+ 	spin_unlock_irqrestore(&adapter->stats_lock, flags);
+ }
+ 
++#ifdef CONFIG_E1000_MQ
++void
++e1000_rx_schedule(void *data)
++{
++	struct net_device *poll_dev, *netdev = data;
++	struct e1000_adapter *adapter = netdev->priv;
++	int this_cpu = get_cpu();
++
++	poll_dev = *per_cpu_ptr(adapter->cpu_netdev, this_cpu);
++	if (poll_dev == NULL) {
++		put_cpu();
++		return;
++	}
++
++	if (likely(netif_rx_schedule_prep(poll_dev)))
++		__netif_rx_schedule(poll_dev);
++	else
++		e1000_irq_enable(adapter);
++
++	put_cpu();
++}
++#endif
++
+ /**
+  * e1000_intr - Interrupt Handler
+  * @irq: interrupt number
+@@ -2592,8 +3106,8 @@ e1000_intr(int irq, void *data, struct p
+ 	struct e1000_adapter *adapter = netdev_priv(netdev);
+ 	struct e1000_hw *hw = &adapter->hw;
+ 	uint32_t icr = E1000_READ_REG(hw, ICR);
+-#ifndef CONFIG_E1000_NAPI
+-	unsigned int i;
++#if defined(CONFIG_E1000_NAPI) && defined(CONFIG_E1000_MQ) || !defined(CONFIG_E1000_NAPI)
++	int i;
+ #endif
+ 
+ 	if(unlikely(!icr))
+@@ -2605,17 +3119,31 @@ e1000_intr(int irq, void *data, struct p
+ 	}
+ 
+ #ifdef CONFIG_E1000_NAPI
+-	if(likely(netif_rx_schedule_prep(netdev))) {
+-
+-		/* Disable interrupts and register for poll. The flush 
+-		  of the posted write is intentionally left out.
+-		*/
+-
+-		atomic_inc(&adapter->irq_sem);
+-		E1000_WRITE_REG(hw, IMC, ~0);
+-		__netif_rx_schedule(netdev);
++	atomic_inc(&adapter->irq_sem);
++	E1000_WRITE_REG(hw, IMC, ~0);
++	E1000_WRITE_FLUSH(hw);
++#ifdef CONFIG_E1000_MQ
++	if (atomic_read(&adapter->rx_sched_call_data.count) == 0) {
++		cpu_set(adapter->cpu_for_queue[0],
++			adapter->rx_sched_call_data.cpumask);
++		for (i = 1; i < adapter->num_queues; i++) {
++			cpu_set(adapter->cpu_for_queue[i],
++				adapter->rx_sched_call_data.cpumask);
++			atomic_inc(&adapter->irq_sem);
++		}
++		atomic_set(&adapter->rx_sched_call_data.count, i);
++		smp_call_async_mask(&adapter->rx_sched_call_data);
++	} else {
++		printk("call_data.count == %u\n", atomic_read(&adapter->rx_sched_call_data.count));
+ 	}
+-#else
++#else /* if !CONFIG_E1000_MQ */
++	if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0])))
++		__netif_rx_schedule(&adapter->polling_netdev[0]);
++	else
++		e1000_irq_enable(adapter);
++#endif /* CONFIG_E1000_MQ */
++
++#else /* if !CONFIG_E1000_NAPI */
+ 	/* Writing IMC and IMS is needed for 82547.
+ 	   Due to Hub Link bus being occupied, an interrupt
+ 	   de-assertion message is not able to be sent.
+@@ -2632,13 +3160,14 @@ e1000_intr(int irq, void *data, struct p
+ 	}
+ 
+ 	for(i = 0; i < E1000_MAX_INTR; i++)
+-		if(unlikely(!adapter->clean_rx(adapter) &
+-		   !e1000_clean_tx_irq(adapter)))
++		if(unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
++		   !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+ 			break;
+ 
+ 	if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
+ 		e1000_irq_enable(adapter);
+-#endif
++
++#endif /* CONFIG_E1000_NAPI */
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -2650,22 +3179,37 @@ e1000_intr(int irq, void *data, struct p
+  **/
+ 
+ static int
+-e1000_clean(struct net_device *netdev, int *budget)
++e1000_clean(struct net_device *poll_dev, int *budget)
+ {
+-	struct e1000_adapter *adapter = netdev_priv(netdev);
+-	int work_to_do = min(*budget, netdev->quota);
+-	int tx_cleaned;
+-	int work_done = 0;
++	struct e1000_adapter *adapter;
++	int work_to_do = min(*budget, poll_dev->quota);
++	int tx_cleaned, i = 0, work_done = 0;
+ 
+-	tx_cleaned = e1000_clean_tx_irq(adapter);
+-	adapter->clean_rx(adapter, &work_done, work_to_do);
++	/* Must NOT use netdev_priv macro here. */
++	adapter = poll_dev->priv;
++
++	/* Keep link state information with original netdev */
++	if (!netif_carrier_ok(adapter->netdev))
++		goto quit_polling;
++
++	while (poll_dev != &adapter->polling_netdev[i]) {
++		i++;
++		if (unlikely(i == adapter->num_queues))
++			BUG();
++	}
++
++	tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]);
++	adapter->clean_rx(adapter, &adapter->rx_ring[i],
++	                  &work_done, work_to_do);
+ 
+ 	*budget -= work_done;
+-	netdev->quota -= work_done;
++	poll_dev->quota -= work_done;
+ 	
+-	if ((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
+ 	/* If no Tx and not enough Rx work done, exit the polling mode */
+-		netif_rx_complete(netdev);
++	if((!tx_cleaned && (work_done == 0)) ||
++	   !netif_running(adapter->netdev)) {
++quit_polling:
++		netif_rx_complete(poll_dev);
+ 		e1000_irq_enable(adapter);
+ 		return 0;
+ 	}
+@@ -2680,9 +3224,9 @@ e1000_clean(struct net_device *netdev, i
+  **/
+ 
+ static boolean_t
+-e1000_clean_tx_irq(struct e1000_adapter *adapter)
++e1000_clean_tx_irq(struct e1000_adapter *adapter,
++                   struct e1000_tx_ring *tx_ring)
+ {
+-	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ 	struct net_device *netdev = adapter->netdev;
+ 	struct e1000_tx_desc *tx_desc, *eop_desc;
+ 	struct e1000_buffer *buffer_info;
+@@ -2693,12 +3237,12 @@ e1000_clean_tx_irq(struct e1000_adapter 
+ 	eop = tx_ring->buffer_info[i].next_to_watch;
+ 	eop_desc = E1000_TX_DESC(*tx_ring, eop);
+ 
+-	while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
++	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
+ 		/* Premature writeback of Tx descriptors clear (free buffers
+ 		 * and unmap pci_mapping) previous_buffer_info */
+-		if (likely(adapter->previous_buffer_info.skb != NULL)) {
++		if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
+ 			e1000_unmap_and_free_tx_resource(adapter,
+-					&adapter->previous_buffer_info);
++					&tx_ring->previous_buffer_info);
+ 		}
+ 
+ 		for(cleaned = FALSE; !cleaned; ) {
+@@ -2714,7 +3258,7 @@ e1000_clean_tx_irq(struct e1000_adapter 
+ #ifdef NETIF_F_TSO
+ 			} else {
+ 				if (cleaned) {
+-					memcpy(&adapter->previous_buffer_info,
++					memcpy(&tx_ring->previous_buffer_info,
+ 					       buffer_info,
+ 					       sizeof(struct e1000_buffer));
+ 					memset(buffer_info, 0,
+@@ -2732,6 +3276,8 @@ e1000_clean_tx_irq(struct e1000_adapter 
+ 
+ 			if(unlikely(++i == tx_ring->count)) i = 0;
+ 		}
++
++		tx_ring->pkt++;
+ 		
+ 		eop = tx_ring->buffer_info[i].next_to_watch;
+ 		eop_desc = E1000_TX_DESC(*tx_ring, eop);
+@@ -2739,15 +3285,15 @@ e1000_clean_tx_irq(struct e1000_adapter 
+ 
+ 	tx_ring->next_to_clean = i;
+ 
+-	spin_lock(&adapter->tx_lock);
++	spin_lock(&tx_ring->tx_lock);
+ 
+ 	if(unlikely(cleaned && netif_queue_stopped(netdev) &&
+ 		    netif_carrier_ok(netdev)))
+ 		netif_wake_queue(netdev);
+ 
+-	spin_unlock(&adapter->tx_lock);
+-	if(adapter->detect_tx_hung) {
++	spin_unlock(&tx_ring->tx_lock);
+ 
++	if (adapter->detect_tx_hung) {
+ 		/* Detect a transmit hang in hardware, this serializes the
+ 		 * check with the clearing of time_stamp and movement of i */
+ 		adapter->detect_tx_hung = FALSE;
+@@ -2771,8 +3317,8 @@ e1000_clean_tx_irq(struct e1000_adapter 
+ 					"  next_to_watch        <%x>\n"
+ 					"  jiffies              <%lx>\n"
+ 					"  next_to_watch.status <%x>\n",
+-				E1000_READ_REG(&adapter->hw, TDH),
+-				E1000_READ_REG(&adapter->hw, TDT),
++				readl(adapter->hw.hw_addr + tx_ring->tdh),
++				readl(adapter->hw.hw_addr + tx_ring->tdt),
+ 				tx_ring->next_to_use,
+ 				i,
+ 				(unsigned long long)tx_ring->buffer_info[i].dma,
+@@ -2784,12 +3330,10 @@ e1000_clean_tx_irq(struct e1000_adapter 
+ 		}
+ 	}
+ #ifdef NETIF_F_TSO
+-
+-	if( unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+-	    time_after(jiffies, adapter->previous_buffer_info.time_stamp + HZ)))
++	if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
++	    time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ)))
+ 		e1000_unmap_and_free_tx_resource(
+-		    adapter, &adapter->previous_buffer_info);
+-
++		    adapter, &tx_ring->previous_buffer_info);
+ #endif
+ 	return cleaned;
+ }
+@@ -2852,13 +3396,14 @@ e1000_rx_checksum(struct e1000_adapter *
+ 
+ static boolean_t
+ #ifdef CONFIG_E1000_NAPI
+-e1000_clean_rx_irq(struct e1000_adapter *adapter, int *work_done,
+-                   int work_to_do)
++e1000_clean_rx_irq(struct e1000_adapter *adapter,
++                   struct e1000_rx_ring *rx_ring,
++                   int *work_done, int work_to_do)
+ #else
+-e1000_clean_rx_irq(struct e1000_adapter *adapter)
++e1000_clean_rx_irq(struct e1000_adapter *adapter,
++                   struct e1000_rx_ring *rx_ring)
+ #endif
+ {
+-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ 	struct net_device *netdev = adapter->netdev;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 	struct e1000_rx_desc *rx_desc;
+@@ -2944,6 +3489,7 @@ e1000_clean_rx_irq(struct e1000_adapter 
+ 		}
+ #endif /* CONFIG_E1000_NAPI */
+ 		netdev->last_rx = jiffies;
++		rx_ring->pkt++;
+ 
+ next_desc:
+ 		rx_desc->status = 0;
+@@ -2953,7 +3499,7 @@ next_desc:
+ 		rx_desc = E1000_RX_DESC(*rx_ring, i);
+ 	}
+ 	rx_ring->next_to_clean = i;
+-	adapter->alloc_rx_buf(adapter);
++	adapter->alloc_rx_buf(adapter, rx_ring);
+ 
+ 	return cleaned;
+ }
+@@ -2965,13 +3511,14 @@ next_desc:
+ 
+ static boolean_t
+ #ifdef CONFIG_E1000_NAPI
+-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, int *work_done,
+-                      int work_to_do)
++e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
++                      struct e1000_rx_ring *rx_ring,
++                      int *work_done, int work_to_do)
+ #else
+-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
++e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
++                      struct e1000_rx_ring *rx_ring)
+ #endif
+ {
+-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ 	union e1000_rx_desc_packet_split *rx_desc;
+ 	struct net_device *netdev = adapter->netdev;
+ 	struct pci_dev *pdev = adapter->pdev;
+@@ -3027,7 +3574,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
+ 		/* Good Receive */
+ 		skb_put(skb, length);
+ 
+-		for(j = 0; j < PS_PAGE_BUFFERS; j++) {
++		for(j = 0; j < adapter->rx_ps_pages; j++) {
+ 			if(!(length = le16_to_cpu(rx_desc->wb.upper.length[j])))
+ 				break;
+ 
+@@ -3048,11 +3595,13 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
+ 				  rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
+ 		skb->protocol = eth_type_trans(skb, netdev);
+ 
+-#ifdef HAVE_RX_ZERO_COPY
+ 		if(likely(rx_desc->wb.upper.header_status &
+-			  E1000_RXDPS_HDRSTAT_HDRSP))
++			  E1000_RXDPS_HDRSTAT_HDRSP)) {
++			adapter->rx_hdr_split++;
++#ifdef HAVE_RX_ZERO_COPY
+ 			skb_shinfo(skb)->zero_copy = TRUE;
+ #endif
++	        }
+ #ifdef CONFIG_E1000_NAPI
+ 		if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
+ 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+@@ -3071,6 +3620,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
+ 		}
+ #endif /* CONFIG_E1000_NAPI */
+ 		netdev->last_rx = jiffies;
++		rx_ring->pkt++;
+ 
+ next_desc:
+ 		rx_desc->wb.middle.status_error &= ~0xFF;
+@@ -3081,7 +3631,7 @@ next_desc:
+ 		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
+ 	}
+ 	rx_ring->next_to_clean = i;
+-	adapter->alloc_rx_buf(adapter);
++	adapter->alloc_rx_buf(adapter, rx_ring);
+ 
+ 	return cleaned;
+ }
+@@ -3092,9 +3642,9 @@ next_desc:
+  **/
+ 
+ static void
+-e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
++e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
++                       struct e1000_rx_ring *rx_ring)
+ {
+-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ 	struct net_device *netdev = adapter->netdev;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 	struct e1000_rx_desc *rx_desc;
+@@ -3178,7 +3728,7 @@ e1000_alloc_rx_buffers(struct e1000_adap
+ 			 * applicable for weak-ordered memory model archs,
+ 			 * such as IA-64). */
+ 			wmb();
+-			E1000_WRITE_REG(&adapter->hw, RDT, i);
++			writel(i, adapter->hw.hw_addr + rx_ring->rdt);
+ 		}
+ 
+ 		if(unlikely(++i == rx_ring->count)) i = 0;
+@@ -3194,9 +3744,9 @@ e1000_alloc_rx_buffers(struct e1000_adap
+  **/
+ 
+ static void
+-e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
++e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
++                          struct e1000_rx_ring *rx_ring)
+ {
+-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ 	struct net_device *netdev = adapter->netdev;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 	union e1000_rx_desc_packet_split *rx_desc;
+@@ -3215,22 +3765,26 @@ e1000_alloc_rx_buffers_ps(struct e1000_a
+ 		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
+ 
+ 		for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+-			if(unlikely(!ps_page->ps_page[j])) {
+-				ps_page->ps_page[j] =
+-					alloc_page(GFP_ATOMIC);
+-				if(unlikely(!ps_page->ps_page[j]))
+-					goto no_buffers;
+-				ps_page_dma->ps_page_dma[j] =
+-					pci_map_page(pdev,
+-						     ps_page->ps_page[j],
+-						     0, PAGE_SIZE,
+-						     PCI_DMA_FROMDEVICE);
+-			}
+-			/* Refresh the desc even if buffer_addrs didn't
+-			 * change because each write-back erases this info.
+-			 */
+-			rx_desc->read.buffer_addr[j+1] =
+-				cpu_to_le64(ps_page_dma->ps_page_dma[j]);
++			if (j < adapter->rx_ps_pages) {
++				if (likely(!ps_page->ps_page[j])) {
++					ps_page->ps_page[j] =
++						alloc_page(GFP_ATOMIC);
++					if (unlikely(!ps_page->ps_page[j]))
++						goto no_buffers;
++					ps_page_dma->ps_page_dma[j] =
++						pci_map_page(pdev,
++							    ps_page->ps_page[j],
++							    0, PAGE_SIZE,
++							    PCI_DMA_FROMDEVICE);
++				}
++				/* Refresh the desc even if buffer_addrs didn't
++				 * change because each write-back erases 
++				 * this info.
++				 */
++				rx_desc->read.buffer_addr[j+1] =
++				     cpu_to_le64(ps_page_dma->ps_page_dma[j]);
++			} else
++				rx_desc->read.buffer_addr[j+1] = ~0;
+ 		}
+ 
+ 		skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
+@@ -3264,7 +3818,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_a
+ 			 * descriptors are 32 bytes...so we increment tail
+ 			 * twice as much.
+ 			 */
+-			E1000_WRITE_REG(&adapter->hw, RDT, i<<1);
++			writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
+ 		}
+ 
+ 		if(unlikely(++i == rx_ring->count)) i = 0;
+@@ -3640,6 +4194,7 @@ e1000_set_spd_dplx(struct e1000_adapter 
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
+ static int
+ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+ {
+@@ -3715,6 +4270,12 @@ e1000_suspend(struct pci_dev *pdev, pm_m
+ 	}
+ 
+ 	switch(adapter->hw.mac_type) {
++	case e1000_82571:
++	case e1000_82572:
++		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
++		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
++				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
++		break;
+ 	case e1000_82573:
+ 		swsm = E1000_READ_REG(&adapter->hw, SWSM);
+ 		E1000_WRITE_REG(&adapter->hw, SWSM,
+@@ -3730,13 +4291,13 @@ e1000_suspend(struct pci_dev *pdev, pm_m
+ 	return 0;
+ }
+ 
+-#ifdef CONFIG_PM
+ static int
+ e1000_resume(struct pci_dev *pdev)
+ {
+ 	struct net_device *netdev = pci_get_drvdata(pdev);
+ 	struct e1000_adapter *adapter = netdev_priv(netdev);
+ 	uint32_t manc, ret_val, swsm;
++	uint32_t ctrl_ext;
+ 
+ 	pci_set_power_state(pdev, PCI_D0);
+ 	pci_restore_state(pdev);
+@@ -3762,6 +4323,12 @@ e1000_resume(struct pci_dev *pdev)
+ 	}
+ 
+ 	switch(adapter->hw.mac_type) {
++	case e1000_82571:
++	case e1000_82572:
++		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
++		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
++				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
++		break;
+ 	case e1000_82573:
+ 		swsm = E1000_READ_REG(&adapter->hw, SWSM);
+ 		E1000_WRITE_REG(&adapter->hw, SWSM,
+@@ -3786,7 +4353,7 @@ e1000_netpoll(struct net_device *netdev)
+ 	struct e1000_adapter *adapter = netdev_priv(netdev);
+ 	disable_irq(adapter->pdev->irq);
+ 	e1000_intr(adapter->pdev->irq, netdev, NULL);
+-	e1000_clean_tx_irq(adapter);
++	e1000_clean_tx_irq(adapter, adapter->tx_ring);
+ 	enable_irq(adapter->pdev->irq);
+ }
+ #endif
+diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
+--- a/drivers/net/e1000/e1000_param.c
++++ b/drivers/net/e1000/e1000_param.c
+@@ -306,7 +306,8 @@ e1000_check_options(struct e1000_adapter
+ 			.def  = E1000_DEFAULT_TXD,
+ 			.arg  = { .r = { .min = E1000_MIN_TXD }}
+ 		};
+-		struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
++		struct e1000_tx_ring *tx_ring = adapter->tx_ring;
++		int i;
+ 		e1000_mac_type mac_type = adapter->hw.mac_type;
+ 		opt.arg.r.max = mac_type < e1000_82544 ?
+ 			E1000_MAX_TXD : E1000_MAX_82544_TXD;
+@@ -319,6 +320,8 @@ e1000_check_options(struct e1000_adapter
+ 		} else {
+ 			tx_ring->count = opt.def;
+ 		}
++		for (i = 0; i < adapter->num_queues; i++)
++			tx_ring[i].count = tx_ring->count;
+ 	}
+ 	{ /* Receive Descriptor Count */
+ 		struct e1000_option opt = {
+@@ -329,7 +332,8 @@ e1000_check_options(struct e1000_adapter
+ 			.def  = E1000_DEFAULT_RXD,
+ 			.arg  = { .r = { .min = E1000_MIN_RXD }}
+ 		};
+-		struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
++		struct e1000_rx_ring *rx_ring = adapter->rx_ring;
++		int i;
+ 		e1000_mac_type mac_type = adapter->hw.mac_type;
+ 		opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
+ 			E1000_MAX_82544_RXD;
+@@ -342,6 +346,8 @@ e1000_check_options(struct e1000_adapter
+ 		} else {
+ 			rx_ring->count = opt.def;
+ 		}
++		for (i = 0; i < adapter->num_queues; i++)
++			rx_ring[i].count = rx_ring->count;
+ 	}
+ 	{ /* Checksum Offload Enable/Disable */
+ 		struct e1000_option opt = {
+diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
+--- a/drivers/net/eepro.c
++++ b/drivers/net/eepro.c
+@@ -552,8 +552,7 @@ static int __init do_eepro_probe(struct 
+ 	{
+ 		unsigned short int WS[32]=WakeupSeq;
+ 
+-		if (check_region(WakeupPort, 2)==0) {
+-
++		if (request_region(WakeupPort, 2, "eepro wakeup")) {
+ 			if (net_debug>5)
+ 				printk(KERN_DEBUG "Waking UP\n");
+ 
+@@ -563,7 +562,10 @@ static int __init do_eepro_probe(struct 
+ 				outb_p(WS[i],WakeupPort);
+ 				if (net_debug>5) printk(KERN_DEBUG ": %#x ",WS[i]);
+ 			}
+-		} else printk(KERN_WARNING "Checkregion Failed!\n");
++
++			release_region(WakeupPort, 2);
++		} else
++			printk(KERN_WARNING "PnP wakeup region busy!\n");
+ 	}
+ #endif
+ 
+@@ -705,7 +707,7 @@ static void __init eepro_print_info (str
+ 					dev->name, (unsigned)dev->base_addr);
+ 			break;
+ 		case LAN595FX:
+-			printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 
++			printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
+ 					dev->name, (unsigned)dev->base_addr);
+ 			break;
+ 		case LAN595TX:
+@@ -713,7 +715,7 @@ static void __init eepro_print_info (str
+ 					dev->name, (unsigned)dev->base_addr);
+ 			break;
+ 		case LAN595:
+-			printk("%s: Intel 82595-based lan card at %#x,", 
++			printk("%s: Intel 82595-based lan card at %#x,",
+ 					dev->name, (unsigned)dev->base_addr);
+ 	}
+ 
+@@ -726,7 +728,7 @@ static void __init eepro_print_info (str
+ 
+ 	if (dev->irq > 2)
+ 		printk(", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
+-	else 
++	else
+ 		printk(", %s.\n", ifmap[dev->if_port]);
+ 
+ 	if (net_debug > 3) {
+@@ -756,7 +758,7 @@ static int __init eepro_probe1(struct ne
+ 	int err;
+ 
+ 	/* Grab the region so we can find another board if autoIRQ fails. */
+-	if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) { 
++	if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
+ 		if (!autoprobe)
+ 			printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
+ 				ioaddr);
+@@ -838,15 +840,15 @@ static int __init eepro_probe1(struct ne
+  		/* Mask off INT number */
+  		int count = lp->word[1] & 7;
+  		unsigned irqMask = lp->word[7];
+- 
++
+  		while (count--)
+  			irqMask &= irqMask - 1;
+- 
++
+  		count = ffs(irqMask);
+- 
++
+  		if (count)
+  			dev->irq = count - 1;
+- 
++
+  		if (dev->irq < 2) {
+  			printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
+  			goto exit;
+@@ -854,7 +856,7 @@ static int __init eepro_probe1(struct ne
+  			dev->irq = 9;
+  		}
+  	}
+- 
++
+  	dev->open               = eepro_open;
+  	dev->stop               = eepro_close;
+  	dev->hard_start_xmit    = eepro_send_packet;
+@@ -863,7 +865,7 @@ static int __init eepro_probe1(struct ne
+  	dev->tx_timeout		= eepro_tx_timeout;
+  	dev->watchdog_timeo	= TX_TIMEOUT;
+ 	dev->ethtool_ops	= &eepro_ethtool_ops;
+- 
++
+ 	/* print boot time info */
+ 	eepro_print_info(dev);
+ 
+@@ -1047,8 +1049,8 @@ static int eepro_open(struct net_device 
+ 
+ 
+ 	/* Initialize the RCV and XMT upper and lower limits */
+-	outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG); 
+-	outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG); 
++	outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG);
++	outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG);
+ 	outb(lp->xmt_lower_limit >> 8, ioaddr + lp->xmt_lower_limit_reg);
+ 	outb(lp->xmt_upper_limit >> 8, ioaddr + lp->xmt_upper_limit_reg);
+ 
+@@ -1065,12 +1067,12 @@ static int eepro_open(struct net_device 
+ 	eepro_clear_int(ioaddr);
+ 
+ 	/* Initialize RCV */
+-	outw(lp->rcv_lower_limit, ioaddr + RCV_BAR); 
++	outw(lp->rcv_lower_limit, ioaddr + RCV_BAR);
+ 	lp->rx_start = lp->rcv_lower_limit;
+-	outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP); 
++	outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP);
+ 
+ 	/* Initialize XMT */
+-	outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar); 
++	outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar);
+ 	lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
+ 	lp->tx_last = 0;
+ 
+@@ -1411,7 +1413,7 @@ set_multicast_list(struct net_device *de
+ 				outb(0x08, ioaddr + STATUS_REG);
+ 
+ 				if (i & 0x20) { /* command ABORTed */
+-					printk(KERN_NOTICE "%s: multicast setup failed.\n", 
++					printk(KERN_NOTICE "%s: multicast setup failed.\n",
+ 						dev->name);
+ 					break;
+ 				} else if ((i & 0x0f) == 0x03)	{ /* MC-Done */
+@@ -1512,7 +1514,7 @@ hardware_send_packet(struct net_device *
+ 		end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
+ 
+ 	if (end >= lp->xmt_upper_limit + 2) { /* the transmit buffer is wrapped around */
+-		if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {	
++		if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {
+ 				/* Arrrr!!!, must keep the xmt header together,
+ 				several days were lost to chase this one down. */
+ 			last = lp->xmt_lower_limit;
+@@ -1643,7 +1645,7 @@ eepro_rx(struct net_device *dev)
+ 			else if (rcv_status & 0x0800)
+ 				lp->stats.rx_crc_errors++;
+ 
+-			printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n", 
++			printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
+ 				dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
+ 		}
+ 
+@@ -1674,10 +1676,10 @@ eepro_transmit_interrupt(struct net_devi
+ {
+ 	struct eepro_local *lp = netdev_priv(dev);
+ 	short ioaddr = dev->base_addr;
+-	short boguscount = 25; 
++	short boguscount = 25;
+ 	short xmt_status;
+ 
+-	while ((lp->tx_start != lp->tx_end) && boguscount--) { 
++	while ((lp->tx_start != lp->tx_end) && boguscount--) {
+ 
+ 		outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
+ 		xmt_status = inw(ioaddr+IO_PORT);
+@@ -1723,7 +1725,7 @@ static int eepro_ethtool_get_settings(st
+ {
+ 	struct eepro_local	*lp = (struct eepro_local *)dev->priv;
+ 
+-	cmd->supported = 	SUPPORTED_10baseT_Half | 
++	cmd->supported = 	SUPPORTED_10baseT_Half |
+ 				SUPPORTED_10baseT_Full |
+ 				SUPPORTED_Autoneg;
+ 	cmd->advertising =	ADVERTISED_10baseT_Half |
+@@ -1797,10 +1799,9 @@ MODULE_AUTHOR("Pascal Dupuis and others"
+ MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
+ MODULE_LICENSE("GPL");
+ 
+-static int num_params;
+-module_param_array(io, int, &num_params, 0);
+-module_param_array(irq, int, &num_params, 0);
+-module_param_array(mem, int, &num_params, 0);
++module_param_array(io, int, NULL, 0);
++module_param_array(irq, int, NULL, 0);
++module_param_array(mem, int, NULL, 0);
+ module_param(autodetect, int, 0);
+ MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
+ MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
+diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
+--- a/drivers/net/epic100.c
++++ b/drivers/net/epic100.c
+@@ -1334,7 +1334,7 @@ static void epic_rx_err(struct net_devic
+ static int epic_poll(struct net_device *dev, int *budget)
+ {
+ 	struct epic_private *ep = dev->priv;
+-	int work_done, orig_budget;
++	int work_done = 0, orig_budget;
+ 	long ioaddr = dev->base_addr;
+ 
+ 	orig_budget = (*budget > dev->quota) ? dev->quota : *budget;
+@@ -1343,7 +1343,7 @@ rx_action:
+ 
+ 	epic_tx(dev, ep);
+ 
+-	work_done = epic_rx(dev, *budget);
++	work_done += epic_rx(dev, *budget);
+ 
+ 	epic_rx_err(dev, ep);
+ 
+diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
+--- a/drivers/net/forcedeth.c
++++ b/drivers/net/forcedeth.c
+@@ -95,6 +95,8 @@
+  *			   of nv_remove
+  *      0.42: 06 Aug 2005: Fix lack of link speed initialization
+  *			   in the second (and later) nv_open call
++ *      0.43: 10 Aug 2005: Add support for tx checksum.
++ *      0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
+  *
+  * Known bugs:
+  * We suspect that on some hardware no TX done interrupts are generated.
+@@ -106,7 +108,7 @@
+  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
+  * superfluous timer interrupts from the nic.
+  */
+-#define FORCEDETH_VERSION		"0.41"
++#define FORCEDETH_VERSION		"0.44"
+ #define DRV_NAME			"forcedeth"
+ 
+ #include <linux/module.h>
+@@ -145,6 +147,7 @@
+ #define DEV_NEED_LINKTIMER	0x0002	/* poll link settings. Relies on the timer irq */
+ #define DEV_HAS_LARGEDESC	0x0004	/* device supports jumbo frames and needs packet format 2 */
+ #define DEV_HAS_HIGH_DMA        0x0008  /* device supports 64bit dma */
++#define DEV_HAS_CHECKSUM        0x0010  /* device supports tx and rx checksum offloads */
+ 
+ enum {
+ 	NvRegIrqStatus = 0x000,
+@@ -241,6 +244,9 @@ enum {
+ #define NVREG_TXRXCTL_IDLE	0x0008
+ #define NVREG_TXRXCTL_RESET	0x0010
+ #define NVREG_TXRXCTL_RXCHECK	0x0400
++#define NVREG_TXRXCTL_DESC_1	0
++#define NVREG_TXRXCTL_DESC_2	0x02100
++#define NVREG_TXRXCTL_DESC_3	0x02200
+ 	NvRegMIIStatus = 0x180,
+ #define NVREG_MIISTAT_ERROR		0x0001
+ #define NVREG_MIISTAT_LINKCHANGE	0x0008
+@@ -335,6 +341,10 @@ typedef union _ring_type {
+ /* error and valid are the same for both */
+ #define NV_TX2_ERROR		(1<<30)
+ #define NV_TX2_VALID		(1<<31)
++#define NV_TX2_TSO		(1<<28)
++#define NV_TX2_TSO_SHIFT	14
++#define NV_TX2_CHECKSUM_L3	(1<<27)
++#define NV_TX2_CHECKSUM_L4	(1<<26)
+ 
+ #define NV_RX_DESCRIPTORVALID	(1<<16)
+ #define NV_RX_MISSEDFRAME	(1<<17)
+@@ -417,14 +427,14 @@ typedef union _ring_type {
+ 
+ /* 
+  * desc_ver values:
+- * This field has two purposes:
+- * - Newer nics uses a different ring layout. The layout is selected by
+- *   comparing np->desc_ver with DESC_VER_xy.
+- * - It contains bits that are forced on when writing to NvRegTxRxControl.
++ * The nic supports three different descriptor types:
++ * - DESC_VER_1: Original
++ * - DESC_VER_2: support for jumbo frames.
++ * - DESC_VER_3: 64-bit format.
+  */
+-#define DESC_VER_1	0x0
+-#define DESC_VER_2	(0x02100|NVREG_TXRXCTL_RXCHECK)
+-#define DESC_VER_3      (0x02200|NVREG_TXRXCTL_RXCHECK)
++#define DESC_VER_1	1
++#define DESC_VER_2	2
++#define DESC_VER_3	3
+ 
+ /* PHY defines */
+ #define PHY_OUI_MARVELL	0x5043
+@@ -491,6 +501,7 @@ struct fe_priv {
+ 	u32 orig_mac[2];
+ 	u32 irqmask;
+ 	u32 desc_ver;
++	u32 txrxctl_bits;
+ 
+ 	void __iomem *base;
+ 
+@@ -534,7 +545,7 @@ static inline struct fe_priv *get_nvpriv
+ 
+ static inline u8 __iomem *get_hwbase(struct net_device *dev)
+ {
+-	return get_nvpriv(dev)->base;
++	return ((struct fe_priv *)netdev_priv(dev))->base;
+ }
+ 
+ static inline void pci_push(u8 __iomem *base)
+@@ -623,7 +634,7 @@ static int mii_rw(struct net_device *dev
+ 
+ static int phy_reset(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u32 miicontrol;
+ 	unsigned int tries = 0;
+ 
+@@ -726,7 +737,7 @@ static int phy_init(struct net_device *d
+ 
+ static void nv_start_rx(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 
+ 	dprintk(KERN_DEBUG "%s: nv_start_rx\n", dev->name);
+@@ -782,14 +793,14 @@ static void nv_stop_tx(struct net_device
+ 
+ static void nv_txrx_reset(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 
+ 	dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name);
+-	writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl);
++	writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
+ 	pci_push(base);
+ 	udelay(NV_TXRX_RESET_DELAY);
+-	writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl);
++	writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
+ 	pci_push(base);
+ }
+ 
+@@ -801,7 +812,7 @@ static void nv_txrx_reset(struct net_dev
+  */
+ static struct net_device_stats *nv_get_stats(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 
+ 	/* It seems that the nic always generates interrupts and doesn't
+ 	 * accumulate errors internally. Thus the current values in np->stats
+@@ -817,7 +828,7 @@ static struct net_device_stats *nv_get_s
+  */
+ static int nv_alloc_rx(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	unsigned int refill_rx = np->refill_rx;
+ 	int nr;
+ 
+@@ -861,7 +872,7 @@ static int nv_alloc_rx(struct net_device
+ static void nv_do_rx_refill(unsigned long data)
+ {
+ 	struct net_device *dev = (struct net_device *) data;
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 
+ 	disable_irq(dev->irq);
+ 	if (nv_alloc_rx(dev)) {
+@@ -875,7 +886,7 @@ static void nv_do_rx_refill(unsigned lon
+ 
+ static void nv_init_rx(struct net_device *dev) 
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	int i;
+ 
+ 	np->cur_rx = RX_RING;
+@@ -889,15 +900,17 @@ static void nv_init_rx(struct net_device
+ 
+ static void nv_init_tx(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	int i;
+ 
+ 	np->next_tx = np->nic_tx = 0;
+-	for (i = 0; i < TX_RING; i++)
++	for (i = 0; i < TX_RING; i++) {
+ 		if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+ 			np->tx_ring.orig[i].FlagLen = 0;
+ 	        else
+ 			np->tx_ring.ex[i].FlagLen = 0;
++		np->tx_skbuff[i] = NULL;
++	}
+ }
+ 
+ static int nv_init_ring(struct net_device *dev)
+@@ -907,21 +920,44 @@ static int nv_init_ring(struct net_devic
+ 	return nv_alloc_rx(dev);
+ }
+ 
++static void nv_release_txskb(struct net_device *dev, unsigned int skbnr)
++{
++	struct fe_priv *np = netdev_priv(dev);
++	struct sk_buff *skb = np->tx_skbuff[skbnr];
++	unsigned int j, entry, fragments;
++			
++	dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d, skb %p\n",
++		dev->name, skbnr, np->tx_skbuff[skbnr]);
++	
++	entry = skbnr;
++	if ((fragments = skb_shinfo(skb)->nr_frags) != 0) {
++		for (j = fragments; j >= 1; j--) {
++			skb_frag_t *frag = &skb_shinfo(skb)->frags[j-1];
++			pci_unmap_page(np->pci_dev, np->tx_dma[entry],
++				       frag->size,
++				       PCI_DMA_TODEVICE);
++			entry = (entry - 1) % TX_RING;
++		}
++	}
++	pci_unmap_single(np->pci_dev, np->tx_dma[entry],
++			 skb->len - skb->data_len,
++			 PCI_DMA_TODEVICE);
++	dev_kfree_skb_irq(skb);
++	np->tx_skbuff[skbnr] = NULL;
++}
++
+ static void nv_drain_tx(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
+-	int i;
++	struct fe_priv *np = netdev_priv(dev);
++	unsigned int i;
++	
+ 	for (i = 0; i < TX_RING; i++) {
+ 		if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+ 			np->tx_ring.orig[i].FlagLen = 0;
+ 		else
+ 			np->tx_ring.ex[i].FlagLen = 0;
+ 		if (np->tx_skbuff[i]) {
+-			pci_unmap_single(np->pci_dev, np->tx_dma[i],
+-						np->tx_skbuff[i]->len,
+-						PCI_DMA_TODEVICE);
+-			dev_kfree_skb(np->tx_skbuff[i]);
+-			np->tx_skbuff[i] = NULL;
++			nv_release_txskb(dev, i);
+ 			np->stats.tx_dropped++;
+ 		}
+ 	}
+@@ -929,7 +965,7 @@ static void nv_drain_tx(struct net_devic
+ 
+ static void nv_drain_rx(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	int i;
+ 	for (i = 0; i < RX_RING; i++) {
+ 		if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+@@ -959,28 +995,69 @@ static void drain_ring(struct net_device
+  */
+ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
+-	int nr = np->next_tx % TX_RING;
++	struct fe_priv *np = netdev_priv(dev);
++	u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET);
++	unsigned int fragments = skb_shinfo(skb)->nr_frags;
++	unsigned int nr = (np->next_tx + fragments) % TX_RING;
++	unsigned int i;
++
++	spin_lock_irq(&np->lock);
++
++	if ((np->next_tx - np->nic_tx + fragments) > TX_LIMIT_STOP) {
++		spin_unlock_irq(&np->lock);
++		netif_stop_queue(dev);
++		return NETDEV_TX_BUSY;
++	}
+ 
+ 	np->tx_skbuff[nr] = skb;
+-	np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len,
+-					PCI_DMA_TODEVICE);
++	
++	if (fragments) {
++		dprintk(KERN_DEBUG "%s: nv_start_xmit: buffer contains %d fragments\n", dev->name, fragments);
++		/* setup descriptors in reverse order */
++		for (i = fragments; i >= 1; i--) {
++			skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
++			np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset, frag->size,
++							PCI_DMA_TODEVICE);
+ 
+-	if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
++			if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
++				np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
++				np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
++			} else {
++				np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
++				np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
++				np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
++			}
++			
++			nr = (nr - 1) % TX_RING;
++
++			if (np->desc_ver == DESC_VER_1)
++				tx_flags_extra &= ~NV_TX_LASTPACKET;
++			else
++				tx_flags_extra &= ~NV_TX2_LASTPACKET;		
++		}
++	}
++
++#ifdef NETIF_F_TSO
++	if (skb_shinfo(skb)->tso_size)
++		tx_flags_extra |= NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
++	else
++#endif
++	tx_flags_extra |= (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
++
++	np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len-skb->data_len,
++					PCI_DMA_TODEVICE);
++	
++	if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
+ 		np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
+-	else {
++		np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
++	} else {
+ 		np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
+ 		np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
+-	}
++		np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
++	}	
+ 
+-	spin_lock_irq(&np->lock);
+-	wmb();
+-	if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+-		np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
+-	else
+-		np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
+-	dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n",
+-				dev->name, np->next_tx);
++	dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission. tx_flags_extra: %x\n",
++				dev->name, np->next_tx, tx_flags_extra);
+ 	{
+ 		int j;
+ 		for (j=0; j<64; j++) {
+@@ -991,15 +1068,13 @@ static int nv_start_xmit(struct sk_buff 
+ 		dprintk("\n");
+ 	}
+ 
+-	np->next_tx++;
++	np->next_tx += 1 + fragments;
+ 
+ 	dev->trans_start = jiffies;
+-	if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP)
+-		netif_stop_queue(dev);
+ 	spin_unlock_irq(&np->lock);
+-	writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
++	writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
+ 	pci_push(get_hwbase(dev));
+-	return 0;
++	return NETDEV_TX_OK;
+ }
+ 
+ /*
+@@ -1009,9 +1084,10 @@ static int nv_start_xmit(struct sk_buff 
+  */
+ static void nv_tx_done(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u32 Flags;
+-	int i;
++	unsigned int i;
++	struct sk_buff *skb;
+ 
+ 	while (np->nic_tx != np->next_tx) {
+ 		i = np->nic_tx % TX_RING;
+@@ -1026,35 +1102,38 @@ static void nv_tx_done(struct net_device
+ 		if (Flags & NV_TX_VALID)
+ 			break;
+ 		if (np->desc_ver == DESC_VER_1) {
+-			if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
+-							NV_TX_UNDERFLOW|NV_TX_ERROR)) {
+-				if (Flags & NV_TX_UNDERFLOW)
+-					np->stats.tx_fifo_errors++;
+-				if (Flags & NV_TX_CARRIERLOST)
+-					np->stats.tx_carrier_errors++;
+-				np->stats.tx_errors++;
+-			} else {
+-				np->stats.tx_packets++;
+-				np->stats.tx_bytes += np->tx_skbuff[i]->len;
++			if (Flags & NV_TX_LASTPACKET) {
++				skb = np->tx_skbuff[i];
++				if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
++					     NV_TX_UNDERFLOW|NV_TX_ERROR)) {
++					if (Flags & NV_TX_UNDERFLOW)
++						np->stats.tx_fifo_errors++;
++					if (Flags & NV_TX_CARRIERLOST)
++						np->stats.tx_carrier_errors++;
++					np->stats.tx_errors++;
++				} else {
++					np->stats.tx_packets++;
++					np->stats.tx_bytes += skb->len;
++				}
++				nv_release_txskb(dev, i);
+ 			}
+ 		} else {
+-			if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
+-							NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
+-				if (Flags & NV_TX2_UNDERFLOW)
+-					np->stats.tx_fifo_errors++;
+-				if (Flags & NV_TX2_CARRIERLOST)
+-					np->stats.tx_carrier_errors++;
+-				np->stats.tx_errors++;
+-			} else {
+-				np->stats.tx_packets++;
+-				np->stats.tx_bytes += np->tx_skbuff[i]->len;
++			if (Flags & NV_TX2_LASTPACKET) {
++				skb = np->tx_skbuff[i];
++				if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
++					     NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
++					if (Flags & NV_TX2_UNDERFLOW)
++						np->stats.tx_fifo_errors++;
++					if (Flags & NV_TX2_CARRIERLOST)
++						np->stats.tx_carrier_errors++;
++					np->stats.tx_errors++;
++				} else {
++					np->stats.tx_packets++;
++					np->stats.tx_bytes += skb->len;
++				}				
++				nv_release_txskb(dev, i);
+ 			}
+ 		}
+-		pci_unmap_single(np->pci_dev, np->tx_dma[i],
+-					np->tx_skbuff[i]->len,
+-					PCI_DMA_TODEVICE);
+-		dev_kfree_skb_irq(np->tx_skbuff[i]);
+-		np->tx_skbuff[i] = NULL;
+ 		np->nic_tx++;
+ 	}
+ 	if (np->next_tx - np->nic_tx < TX_LIMIT_START)
+@@ -1067,7 +1146,7 @@ static void nv_tx_done(struct net_device
+  */
+ static void nv_tx_timeout(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 
+ 	printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name,
+@@ -1200,7 +1279,7 @@ static int nv_getlen(struct net_device *
+ 
+ static void nv_rx_process(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u32 Flags;
+ 
+ 	for (;;) {
+@@ -1355,7 +1434,7 @@ static void set_bufsize(struct net_devic
+  */
+ static int nv_change_mtu(struct net_device *dev, int new_mtu)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	int old_mtu;
+ 
+ 	if (new_mtu < 64 || new_mtu > np->pkt_limit)
+@@ -1408,7 +1487,7 @@ static int nv_change_mtu(struct net_devi
+ 		writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT),
+ 			base + NvRegRingSizes);
+ 		pci_push(base);
+-		writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
++		writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
+ 		pci_push(base);
+ 
+ 		/* restart rx engine */
+@@ -1440,7 +1519,7 @@ static void nv_copy_mac_to_hw(struct net
+  */
+ static int nv_set_mac_address(struct net_device *dev, void *addr)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	struct sockaddr *macaddr = (struct sockaddr*)addr;
+ 
+ 	if(!is_valid_ether_addr(macaddr->sa_data))
+@@ -1475,7 +1554,7 @@ static int nv_set_mac_address(struct net
+  */
+ static void nv_set_multicast(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 	u32 addr[2];
+ 	u32 mask[2];
+@@ -1535,7 +1614,7 @@ static void nv_set_multicast(struct net_
+ 
+ static int nv_update_linkspeed(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 	int adv, lpa;
+ 	int newls = np->linkspeed;
+@@ -1705,7 +1784,7 @@ static void nv_link_irq(struct net_devic
+ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
+ {
+ 	struct net_device *dev = (struct net_device *) data;
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 	u32 events;
+ 	int i;
+@@ -1777,7 +1856,7 @@ static irqreturn_t nv_nic_irq(int foo, v
+ static void nv_do_nic_poll(unsigned long data)
+ {
+ 	struct net_device *dev = (struct net_device *) data;
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 
+ 	disable_irq(dev->irq);
+@@ -1801,7 +1880,7 @@ static void nv_poll_controller(struct ne
+ 
+ static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	strcpy(info->driver, "forcedeth");
+ 	strcpy(info->version, FORCEDETH_VERSION);
+ 	strcpy(info->bus_info, pci_name(np->pci_dev));
+@@ -1809,7 +1888,7 @@ static void nv_get_drvinfo(struct net_de
+ 
+ static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	wolinfo->supported = WAKE_MAGIC;
+ 
+ 	spin_lock_irq(&np->lock);
+@@ -1820,7 +1899,7 @@ static void nv_get_wol(struct net_device
+ 
+ static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 
+ 	spin_lock_irq(&np->lock);
+@@ -2021,7 +2100,7 @@ static int nv_get_regs_len(struct net_de
+ 
+ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 	u32 *rbuf = buf;
+ 	int i;
+@@ -2035,7 +2114,7 @@ static void nv_get_regs(struct net_devic
+ 
+ static int nv_nway_reset(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	int ret;
+ 
+ 	spin_lock_irq(&np->lock);
+@@ -2065,11 +2144,12 @@ static struct ethtool_ops ops = {
+ 	.get_regs_len = nv_get_regs_len,
+ 	.get_regs = nv_get_regs,
+ 	.nway_reset = nv_nway_reset,
++	.get_perm_addr = ethtool_op_get_perm_addr,
+ };
+ 
+ static int nv_open(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base = get_hwbase(dev);
+ 	int ret, oom, i;
+ 
+@@ -2114,9 +2194,9 @@ static int nv_open(struct net_device *de
+ 	/* 5) continue setup */
+ 	writel(np->linkspeed, base + NvRegLinkSpeed);
+ 	writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
+-	writel(np->desc_ver, base + NvRegTxRxControl);
++	writel(np->txrxctl_bits, base + NvRegTxRxControl);
+ 	pci_push(base);
+-	writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl);
++	writel(NVREG_TXRXCTL_BIT1|np->txrxctl_bits, base + NvRegTxRxControl);
+ 	reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
+ 			NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
+ 			KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
+@@ -2205,7 +2285,7 @@ out_drain:
+ 
+ static int nv_close(struct net_device *dev)
+ {
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 	u8 __iomem *base;
+ 
+ 	spin_lock_irq(&np->lock);
+@@ -2261,7 +2341,7 @@ static int __devinit nv_probe(struct pci
+ 	if (!dev)
+ 		goto out;
+ 
+-	np = get_nvpriv(dev);
++	np = netdev_priv(dev);
+ 	np->pci_dev = pci_dev;
+ 	spin_lock_init(&np->lock);
+ 	SET_MODULE_OWNER(dev);
+@@ -2313,19 +2393,32 @@ static int __devinit nv_probe(struct pci
+ 		if (pci_set_dma_mask(pci_dev, 0x0000007fffffffffULL)) {
+ 			printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
+ 					pci_name(pci_dev));
++		} else {
++			dev->features |= NETIF_F_HIGHDMA;
+ 		}
++		np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
+ 	} else if (id->driver_data & DEV_HAS_LARGEDESC) {
+ 		/* packet format 2: supports jumbo frames */
+ 		np->desc_ver = DESC_VER_2;
++		np->txrxctl_bits = NVREG_TXRXCTL_DESC_2;
+ 	} else {
+ 		/* original packet format */
+ 		np->desc_ver = DESC_VER_1;
++		np->txrxctl_bits = NVREG_TXRXCTL_DESC_1;
+ 	}
+ 
+ 	np->pkt_limit = NV_PKTLIMIT_1;
+ 	if (id->driver_data & DEV_HAS_LARGEDESC)
+ 		np->pkt_limit = NV_PKTLIMIT_2;
+ 
++	if (id->driver_data & DEV_HAS_CHECKSUM) {
++		np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
++		dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
++#ifdef NETIF_F_TSO
++		dev->features |= NETIF_F_TSO;
++#endif
++ 	}
++
+ 	err = -ENOMEM;
+ 	np->base = ioremap(addr, NV_PCI_REGSZ);
+ 	if (!np->base)
+@@ -2377,8 +2470,9 @@ static int __devinit nv_probe(struct pci
+ 	dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
+ 	dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
+ 	dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
++	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+-	if (!is_valid_ether_addr(dev->dev_addr)) {
++	if (!is_valid_ether_addr(dev->perm_addr)) {
+ 		/*
+ 		 * Bad mac address. At least one bios sets the mac address
+ 		 * to 01:23:45:67:89:ab
+@@ -2403,9 +2497,9 @@ static int __devinit nv_probe(struct pci
+ 	np->wolenabled = 0;
+ 
+ 	if (np->desc_ver == DESC_VER_1) {
+-		np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID;
++		np->tx_flags = NV_TX_VALID;
+ 	} else {
+-		np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID;
++		np->tx_flags = NV_TX2_VALID;
+ 	}
+ 	np->irqmask = NVREG_IRQMASK_WANTED;
+ 	if (id->driver_data & DEV_NEED_TIMERIRQ)
+@@ -2494,7 +2588,7 @@ out:
+ static void __devexit nv_remove(struct pci_dev *pci_dev)
+ {
+ 	struct net_device *dev = pci_get_drvdata(pci_dev);
+-	struct fe_priv *np = get_nvpriv(dev);
++	struct fe_priv *np = netdev_priv(dev);
+ 
+ 	unregister_netdev(dev);
+ 
+@@ -2525,35 +2619,35 @@ static struct pci_device_id pci_tbl[] = 
+ 	},
+ 	{	/* nForce3 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
+ 	},
+ 	{	/* nForce3 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
+ 	},
+ 	{	/* nForce3 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
+ 	},
+ 	{	/* nForce3 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
+ 	},
+ 	{	/* CK804 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
+ 	},
+ 	{	/* CK804 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
+ 	},
+ 	{	/* MCP04 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
+ 	},
+ 	{	/* MCP04 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
+ 	},
+ 	{	/* MCP51 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
+@@ -2565,11 +2659,11 @@ static struct pci_device_id pci_tbl[] = 
+ 	},
+ 	{	/* MCP55 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
+ 	},
+ 	{	/* MCP55 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
+ 	},
+ 	{0,},
+ };
+diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/Kconfig
+@@ -0,0 +1,20 @@
++config FS_ENET
++       tristate "Freescale Ethernet Driver"
++       depends on NET_ETHERNET && (CPM1 || CPM2)
++       select MII
++
++config FS_ENET_HAS_SCC
++	bool "Chip has an SCC usable for ethernet"
++	depends on FS_ENET && (CPM1 || CPM2)
++	default y
++
++config FS_ENET_HAS_FCC
++	bool "Chip has an FCC usable for ethernet"
++	depends on FS_ENET && CPM2
++	default y
++
++config FS_ENET_HAS_FEC
++	bool "Chip has an FEC usable for ethernet"
++	depends on FS_ENET && CPM1
++	default y
++
+diff --git a/drivers/net/fs_enet/Makefile b/drivers/net/fs_enet/Makefile
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/Makefile
+@@ -0,0 +1,10 @@
++#
++# Makefile for the Freescale Ethernet controllers
++#
++
++obj-$(CONFIG_FS_ENET) += fs_enet.o
++
++obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o
++obj-$(CONFIG_8260) += mac-fcc.o
++
++fs_enet-objs := fs_enet-main.o fs_enet-mii.o mii-bitbang.o mii-fixed.o
+diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/fs_enet-main.c
+@@ -0,0 +1,1226 @@
++/*
++ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
++ *
++ * Copyright (c) 2003 Intracom S.A. 
++ *  by Pantelis Antoniou <panto at intracom.gr>
++ * 
++ * 2005 (c) MontaVista Software, Inc. 
++ * Vitaly Bordug <vbordug at ru.mvista.com>
++ *
++ * Heavily based on original FEC driver by Dan Malek <dan at embeddededge.com>
++ * and modifications by Joakim Tjernlund <joakim.tjernlund at lumentis.se>
++ *
++ * 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/kernel.h>
++#include <linux/types.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/fs.h>
++
++#include <linux/vmalloc.h>
++#include <asm/pgtable.h>
++
++#include <asm/pgtable.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#include "fs_enet.h"
++
++/*************************************************/
++
++static char version[] __devinitdata =
++    DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n";
++
++MODULE_AUTHOR("Pantelis Antoniou <panto at intracom.gr>");
++MODULE_DESCRIPTION("Freescale Ethernet Driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_MODULE_VERSION);
++
++MODULE_PARM(fs_enet_debug, "i");
++MODULE_PARM_DESC(fs_enet_debug,
++		 "Freescale bitmapped debugging message enable value");
++
++int fs_enet_debug = -1;		/* -1 == use FS_ENET_DEF_MSG_ENABLE as value */
++
++static void fs_set_multicast_list(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	(*fep->ops->set_multicast_list)(dev);
++}
++
++/* NAPI receive function */
++static int fs_enet_rx_napi(struct net_device *dev, int *budget)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++	cbd_t *bdp;
++	struct sk_buff *skb, *skbn, *skbt;
++	int received = 0;
++	u16 pkt_len, sc;
++	int curidx;
++	int rx_work_limit = 0;	/* pacify gcc */
++
++	rx_work_limit = min(dev->quota, *budget);
++
++	if (!netif_running(dev))
++		return 0;
++
++	/*
++	 * First, grab all of the stats for the incoming packet.
++	 * These get messed up if we get called due to a busy condition.
++	 */
++	bdp = fep->cur_rx;
++
++	/* clear RX status bits for napi*/
++	(*fep->ops->napi_clear_rx_event)(dev);
++
++	while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
++
++		curidx = bdp - fep->rx_bd_base;
++
++		/*
++		 * Since we have allocated space to hold a complete frame,
++		 * the last indicator should be set.
++		 */
++		if ((sc & BD_ENET_RX_LAST) == 0)
++			printk(KERN_WARNING DRV_MODULE_NAME
++			       ": %s rcv is not +last\n",
++			       dev->name);
++
++		/*
++		 * Check for errors. 
++		 */
++		if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
++			  BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
++			fep->stats.rx_errors++;
++			/* Frame too long or too short. */
++			if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
++				fep->stats.rx_length_errors++;
++			/* Frame alignment */
++			if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL))
++				fep->stats.rx_frame_errors++;
++			/* CRC Error */
++			if (sc & BD_ENET_RX_CR)
++				fep->stats.rx_crc_errors++;
++			/* FIFO overrun */
++			if (sc & BD_ENET_RX_OV)
++				fep->stats.rx_crc_errors++;
++
++			skb = fep->rx_skbuff[curidx];
++
++			dma_unmap_single(fep->dev, skb->data,
++				L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++				DMA_FROM_DEVICE);
++
++			skbn = skb;
++
++		} else {
++
++			/* napi, got packet but no quota */
++			if (--rx_work_limit < 0)
++				break;
++
++			skb = fep->rx_skbuff[curidx];
++
++			dma_unmap_single(fep->dev, skb->data,
++				L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++				DMA_FROM_DEVICE);
++
++			/*
++			 * Process the incoming frame.
++			 */
++			fep->stats.rx_packets++;
++			pkt_len = CBDR_DATLEN(bdp) - 4;	/* remove CRC */
++			fep->stats.rx_bytes += pkt_len + 4;
++
++			if (pkt_len <= fpi->rx_copybreak) {
++				/* +2 to make IP header L1 cache aligned */
++				skbn = dev_alloc_skb(pkt_len + 2);
++				if (skbn != NULL) {
++					skb_reserve(skbn, 2);	/* align IP header */
++					memcpy(skbn->data, skb->data, pkt_len);
++					/* swap */
++					skbt = skb;
++					skb = skbn;
++					skbn = skbt;
++				}
++			} else
++				skbn = dev_alloc_skb(ENET_RX_FRSIZE);
++
++			if (skbn != NULL) {
++				skb->dev = dev;
++				skb_put(skb, pkt_len);	/* Make room */
++				skb->protocol = eth_type_trans(skb, dev);
++				received++;
++				netif_receive_skb(skb);
++			} else {
++				printk(KERN_WARNING DRV_MODULE_NAME
++				       ": %s Memory squeeze, dropping packet.\n",
++				       dev->name);
++				fep->stats.rx_dropped++;
++				skbn = skb;
++			}
++		}
++
++		fep->rx_skbuff[curidx] = skbn;
++		CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
++			     L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++			     DMA_FROM_DEVICE));
++		CBDW_DATLEN(bdp, 0);
++		CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
++
++		/*
++		 * Update BD pointer to next entry. 
++		 */
++		if ((sc & BD_ENET_RX_WRAP) == 0)
++			bdp++;
++		else
++			bdp = fep->rx_bd_base;
++
++		(*fep->ops->rx_bd_done)(dev);
++	}
++
++	fep->cur_rx = bdp;
++
++	dev->quota -= received;
++	*budget -= received;
++
++	if (rx_work_limit < 0)
++		return 1;	/* not done */
++
++	/* done */
++	netif_rx_complete(dev);
++
++	(*fep->ops->napi_enable_rx)(dev);
++
++	return 0;
++}
++
++/* non NAPI receive function */
++static int fs_enet_rx_non_napi(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++	cbd_t *bdp;
++	struct sk_buff *skb, *skbn, *skbt;
++	int received = 0;
++	u16 pkt_len, sc;
++	int curidx;
++	/*
++	 * First, grab all of the stats for the incoming packet.
++	 * These get messed up if we get called due to a busy condition.
++	 */
++	bdp = fep->cur_rx;
++
++	while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
++
++		curidx = bdp - fep->rx_bd_base;
++
++		/*
++		 * Since we have allocated space to hold a complete frame,
++		 * the last indicator should be set.
++		 */
++		if ((sc & BD_ENET_RX_LAST) == 0)
++			printk(KERN_WARNING DRV_MODULE_NAME
++			       ": %s rcv is not +last\n",
++			       dev->name);
++
++		/*
++		 * Check for errors. 
++		 */
++		if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
++			  BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
++			fep->stats.rx_errors++;
++			/* Frame too long or too short. */
++			if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
++				fep->stats.rx_length_errors++;
++			/* Frame alignment */
++			if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL))
++				fep->stats.rx_frame_errors++;
++			/* CRC Error */
++			if (sc & BD_ENET_RX_CR)
++				fep->stats.rx_crc_errors++;
++			/* FIFO overrun */
++			if (sc & BD_ENET_RX_OV)
++				fep->stats.rx_crc_errors++;
++
++			skb = fep->rx_skbuff[curidx];
++
++			dma_unmap_single(fep->dev, skb->data,
++				L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++				DMA_FROM_DEVICE);
++
++			skbn = skb;
++
++		} else {
++
++			skb = fep->rx_skbuff[curidx];
++
++			dma_unmap_single(fep->dev, skb->data,
++				L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++				DMA_FROM_DEVICE);
++
++			/*
++			 * Process the incoming frame.
++			 */
++			fep->stats.rx_packets++;
++			pkt_len = CBDR_DATLEN(bdp) - 4;	/* remove CRC */
++			fep->stats.rx_bytes += pkt_len + 4;
++
++			if (pkt_len <= fpi->rx_copybreak) {
++				/* +2 to make IP header L1 cache aligned */
++				skbn = dev_alloc_skb(pkt_len + 2);
++				if (skbn != NULL) {
++					skb_reserve(skbn, 2);	/* align IP header */
++					memcpy(skbn->data, skb->data, pkt_len);
++					/* swap */
++					skbt = skb;
++					skb = skbn;
++					skbn = skbt;
++				}
++			} else
++				skbn = dev_alloc_skb(ENET_RX_FRSIZE);
++
++			if (skbn != NULL) {
++				skb->dev = dev;
++				skb_put(skb, pkt_len);	/* Make room */
++				skb->protocol = eth_type_trans(skb, dev);
++				received++;
++				netif_rx(skb);
++			} else {
++				printk(KERN_WARNING DRV_MODULE_NAME
++				       ": %s Memory squeeze, dropping packet.\n",
++				       dev->name);
++				fep->stats.rx_dropped++;
++				skbn = skb;
++			}
++		}
++
++		fep->rx_skbuff[curidx] = skbn;
++		CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
++			     L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++			     DMA_FROM_DEVICE));
++		CBDW_DATLEN(bdp, 0);
++		CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
++
++		/*
++		 * Update BD pointer to next entry. 
++		 */
++		if ((sc & BD_ENET_RX_WRAP) == 0)
++			bdp++;
++		else
++			bdp = fep->rx_bd_base;
++
++		(*fep->ops->rx_bd_done)(dev);
++	}
++
++	fep->cur_rx = bdp;
++
++	return 0;
++}
++
++static void fs_enet_tx(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	cbd_t *bdp;
++	struct sk_buff *skb;
++	int dirtyidx, do_wake, do_restart;
++	u16 sc;
++
++	spin_lock(&fep->lock);
++	bdp = fep->dirty_tx;
++
++	do_wake = do_restart = 0;
++	while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
++
++		dirtyidx = bdp - fep->tx_bd_base;
++
++		if (fep->tx_free == fep->tx_ring)
++			break;
++
++		skb = fep->tx_skbuff[dirtyidx];
++
++		/*
++		 * Check for errors. 
++		 */
++		if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
++			  BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {
++
++			if (sc & BD_ENET_TX_HB)	/* No heartbeat */
++				fep->stats.tx_heartbeat_errors++;
++			if (sc & BD_ENET_TX_LC)	/* Late collision */
++				fep->stats.tx_window_errors++;
++			if (sc & BD_ENET_TX_RL)	/* Retrans limit */
++				fep->stats.tx_aborted_errors++;
++			if (sc & BD_ENET_TX_UN)	/* Underrun */
++				fep->stats.tx_fifo_errors++;
++			if (sc & BD_ENET_TX_CSL)	/* Carrier lost */
++				fep->stats.tx_carrier_errors++;
++
++			if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
++				fep->stats.tx_errors++;
++				do_restart = 1;
++			}
++		} else
++			fep->stats.tx_packets++;
++
++		if (sc & BD_ENET_TX_READY)
++			printk(KERN_WARNING DRV_MODULE_NAME
++			       ": %s HEY! Enet xmit interrupt and TX_READY.\n",
++			       dev->name);
++
++		/*
++		 * Deferred means some collisions occurred during transmit,
++		 * but we eventually sent the packet OK.
++		 */
++		if (sc & BD_ENET_TX_DEF)
++			fep->stats.collisions++;
++
++		/* unmap */
++		dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE);
++
++		/*
++		 * Free the sk buffer associated with this last transmit. 
++		 */
++		dev_kfree_skb_irq(skb);
++		fep->tx_skbuff[dirtyidx] = NULL;
++
++		/*
++		 * Update pointer to next buffer descriptor to be transmitted. 
++		 */
++		if ((sc & BD_ENET_TX_WRAP) == 0)
++			bdp++;
++		else
++			bdp = fep->tx_bd_base;
++
++		/*
++		 * Since we have freed up a buffer, the ring is no longer
++		 * full.
++		 */
++		if (!fep->tx_free++)
++			do_wake = 1;
++	}
++
++	fep->dirty_tx = bdp;
++
++	if (do_restart)
++		(*fep->ops->tx_restart)(dev);
++
++	spin_unlock(&fep->lock);
++
++	if (do_wake)
++		netif_wake_queue(dev);
++}
++
++/*
++ * The interrupt handler.
++ * This is called from the MPC core interrupt.
++ */
++static irqreturn_t
++fs_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct net_device *dev = dev_id;
++	struct fs_enet_private *fep;
++	const struct fs_platform_info *fpi;
++	u32 int_events;
++	u32 int_clr_events;
++	int nr, napi_ok;
++	int handled;
++
++	fep = netdev_priv(dev);
++	fpi = fep->fpi;
++
++	nr = 0;
++	while ((int_events = (*fep->ops->get_int_events)(dev)) != 0) {
++
++		nr++;
++
++		int_clr_events = int_events;
++		if (fpi->use_napi)
++			int_clr_events &= ~fep->ev_napi_rx;
++
++		(*fep->ops->clear_int_events)(dev, int_clr_events);
++
++		if (int_events & fep->ev_err)
++			(*fep->ops->ev_error)(dev, int_events);
++
++		if (int_events & fep->ev_rx) {
++			if (!fpi->use_napi)
++				fs_enet_rx_non_napi(dev);
++			else {
++				napi_ok = netif_rx_schedule_prep(dev);
++
++				(*fep->ops->napi_disable_rx)(dev);
++				(*fep->ops->clear_int_events)(dev, fep->ev_napi_rx);
++
++				/* NOTE: it is possible for FCCs in NAPI mode    */
++				/* to submit a spurious interrupt while in poll  */
++				if (napi_ok)
++					__netif_rx_schedule(dev);
++			}
++		}
++
++		if (int_events & fep->ev_tx)
++			fs_enet_tx(dev);
++	}
++
++	handled = nr > 0;
++	return IRQ_RETVAL(handled);
++}
++
++void fs_init_bds(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	cbd_t *bdp;
++	struct sk_buff *skb;
++	int i;
++
++	fs_cleanup_bds(dev);
++
++	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
++	fep->tx_free = fep->tx_ring;
++	fep->cur_rx = fep->rx_bd_base;
++
++	/*
++	 * Initialize the receive buffer descriptors. 
++	 */
++	for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
++		skb = dev_alloc_skb(ENET_RX_FRSIZE);
++		if (skb == NULL) {
++			printk(KERN_WARNING DRV_MODULE_NAME
++			       ": %s Memory squeeze, unable to allocate skb\n",
++			       dev->name);
++			break;
++		}
++		fep->rx_skbuff[i] = skb;
++		skb->dev = dev;
++		CBDW_BUFADDR(bdp,
++			dma_map_single(fep->dev, skb->data,
++				L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++				DMA_FROM_DEVICE));
++		CBDW_DATLEN(bdp, 0);	/* zero */
++		CBDW_SC(bdp, BD_ENET_RX_EMPTY |
++			((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP));
++	}
++	/*
++	 * if we failed, fillup remainder 
++	 */
++	for (; i < fep->rx_ring; i++, bdp++) {
++		fep->rx_skbuff[i] = NULL;
++		CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP);
++	}
++
++	/*
++	 * ...and the same for transmit.  
++	 */
++	for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) {
++		fep->tx_skbuff[i] = NULL;
++		CBDW_BUFADDR(bdp, 0);
++		CBDW_DATLEN(bdp, 0);
++		CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP);
++	}
++}
++
++void fs_cleanup_bds(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	struct sk_buff *skb;
++	int i;
++
++	/*
++	 * Reset SKB transmit buffers.  
++	 */
++	for (i = 0; i < fep->tx_ring; i++) {
++		if ((skb = fep->tx_skbuff[i]) == NULL)
++			continue;
++
++		/* unmap */
++		dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE);
++
++		fep->tx_skbuff[i] = NULL;
++		dev_kfree_skb(skb);
++	}
++
++	/*
++	 * Reset SKB receive buffers 
++	 */
++	for (i = 0; i < fep->rx_ring; i++) {
++		if ((skb = fep->rx_skbuff[i]) == NULL)
++			continue;
++
++		/* unmap */
++		dma_unmap_single(fep->dev, skb->data,
++			L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++			DMA_FROM_DEVICE);
++
++		fep->rx_skbuff[i] = NULL;
++
++		dev_kfree_skb(skb);
++	}
++}
++
++/**********************************************************************************/
++
++static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	cbd_t *bdp;
++	int curidx;
++	u16 sc;
++	unsigned long flags;
++
++	spin_lock_irqsave(&fep->tx_lock, flags);
++
++	/*
++	 * Fill in a Tx ring entry 
++	 */
++	bdp = fep->cur_tx;
++
++	if (!fep->tx_free || (CBDR_SC(bdp) & BD_ENET_TX_READY)) {
++		netif_stop_queue(dev);
++		spin_unlock_irqrestore(&fep->tx_lock, flags);
++
++		/*
++		 * Ooops.  All transmit buffers are full.  Bail out.
++		 * This should not happen, since the tx queue should be stopped.
++		 */
++		printk(KERN_WARNING DRV_MODULE_NAME
++		       ": %s tx queue full!.\n", dev->name);
++		return NETDEV_TX_BUSY;
++	}
++
++	curidx = bdp - fep->tx_bd_base;
++	/*
++	 * Clear all of the status flags. 
++	 */
++	CBDC_SC(bdp, BD_ENET_TX_STATS);
++
++	/*
++	 * Save skb pointer. 
++	 */
++	fep->tx_skbuff[curidx] = skb;
++
++	fep->stats.tx_bytes += skb->len;
++
++	/*
++	 * Push the data cache so the CPM does not get stale memory data. 
++	 */
++	CBDW_BUFADDR(bdp, dma_map_single(fep->dev,
++				skb->data, skb->len, DMA_TO_DEVICE));
++	CBDW_DATLEN(bdp, skb->len);
++
++	dev->trans_start = jiffies;
++
++	/*
++	 * If this was the last BD in the ring, start at the beginning again. 
++	 */
++	if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0)
++		fep->cur_tx++;
++	else
++		fep->cur_tx = fep->tx_bd_base;
++
++	if (!--fep->tx_free)
++		netif_stop_queue(dev);
++
++	/* Trigger transmission start */
++	sc = BD_ENET_TX_READY | BD_ENET_TX_INTR |
++	     BD_ENET_TX_LAST | BD_ENET_TX_TC;
++
++	/* note that while FEC does not have this bit
++	 * it marks it as available for software use
++	 * yay for hw reuse :) */
++	if (skb->len <= 60)
++		sc |= BD_ENET_TX_PAD;
++	CBDS_SC(bdp, sc);
++
++	(*fep->ops->tx_kickstart)(dev);
++
++	spin_unlock_irqrestore(&fep->tx_lock, flags);
++
++	return NETDEV_TX_OK;
++}
++
++static int fs_request_irq(struct net_device *dev, int irq, const char *name,
++		irqreturn_t (*irqf)(int irq, void *dev_id, struct pt_regs *regs))
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	(*fep->ops->pre_request_irq)(dev, irq);
++	return request_irq(irq, irqf, SA_SHIRQ, name, dev);
++}
++
++static void fs_free_irq(struct net_device *dev, int irq)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	free_irq(irq, dev);
++	(*fep->ops->post_free_irq)(dev, irq);
++}
++
++/**********************************************************************************/
++
++/* This interrupt occurs when the PHY detects a link change. */
++static irqreturn_t
++fs_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct net_device *dev = dev_id;
++	struct fs_enet_private *fep;
++	const struct fs_platform_info *fpi;
++
++	fep = netdev_priv(dev);
++	fpi = fep->fpi;
++
++	/*
++	 * Acknowledge the interrupt if possible. If we have not
++	 * found the PHY yet we can't process or acknowledge the
++	 * interrupt now. Instead we ignore this interrupt for now,
++	 * which we can do since it is edge triggered. It will be
++	 * acknowledged later by fs_enet_open().
++	 */
++	if (!fep->phy)
++		return IRQ_NONE;
++
++	fs_mii_ack_int(dev);
++	fs_mii_link_status_change_check(dev, 0);
++
++	return IRQ_HANDLED;
++}
++
++static void fs_timeout(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	unsigned long flags;
++	int wake = 0;
++
++	fep->stats.tx_errors++;
++
++	spin_lock_irqsave(&fep->lock, flags);
++
++	if (dev->flags & IFF_UP) {
++		(*fep->ops->stop)(dev);
++		(*fep->ops->restart)(dev);
++	}
++
++	wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY);
++	spin_unlock_irqrestore(&fep->lock, flags);
++
++	if (wake)
++		netif_wake_queue(dev);
++}
++
++static int fs_enet_open(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++	int r;
++
++	/* Install our interrupt handler. */
++	r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt);
++	if (r != 0) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       ": %s Could not allocate FEC IRQ!", dev->name);
++		return -EINVAL;
++	}
++
++	/* Install our phy interrupt handler */
++	if (fpi->phy_irq != -1) {
++
++		r = fs_request_irq(dev, fpi->phy_irq, "fs_enet-phy", fs_mii_link_interrupt);
++		if (r != 0) {
++			printk(KERN_ERR DRV_MODULE_NAME
++			       ": %s Could not allocate PHY IRQ!", dev->name);
++			fs_free_irq(dev, fep->interrupt);
++			return -EINVAL;
++		}
++	}
++
++	fs_mii_startup(dev);
++	netif_carrier_off(dev);
++	fs_mii_link_status_change_check(dev, 1);
++
++	return 0;
++}
++
++static int fs_enet_close(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++	unsigned long flags;
++
++	netif_stop_queue(dev);
++	netif_carrier_off(dev);
++	fs_mii_shutdown(dev);
++
++	spin_lock_irqsave(&fep->lock, flags);
++	(*fep->ops->stop)(dev);
++	spin_unlock_irqrestore(&fep->lock, flags);
++
++	/* release any irqs */
++	if (fpi->phy_irq != -1)
++		fs_free_irq(dev, fpi->phy_irq);
++	fs_free_irq(dev, fep->interrupt);
++
++	return 0;
++}
++
++static struct net_device_stats *fs_enet_get_stats(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	return &fep->stats;
++}
++
++/*************************************************************************/
++
++static void fs_get_drvinfo(struct net_device *dev,
++			    struct ethtool_drvinfo *info)
++{
++	strcpy(info->driver, DRV_MODULE_NAME);
++	strcpy(info->version, DRV_MODULE_VERSION);
++}
++
++static int fs_get_regs_len(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	return (*fep->ops->get_regs_len)(dev);
++}
++
++static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs,
++			 void *p)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	unsigned long flags;
++	int r, len;
++
++	len = regs->len;
++
++	spin_lock_irqsave(&fep->lock, flags);
++	r = (*fep->ops->get_regs)(dev, p, &len);
++	spin_unlock_irqrestore(&fep->lock, flags);
++
++	if (r == 0)
++		regs->version = 0;
++}
++
++static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	unsigned long flags;
++	int rc;
++
++	spin_lock_irqsave(&fep->lock, flags);
++	rc = mii_ethtool_gset(&fep->mii_if, cmd);
++	spin_unlock_irqrestore(&fep->lock, flags);
++
++	return rc;
++}
++
++static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	unsigned long flags;
++	int rc;
++
++	spin_lock_irqsave(&fep->lock, flags);
++	rc = mii_ethtool_sset(&fep->mii_if, cmd);
++	spin_unlock_irqrestore(&fep->lock, flags);
++
++	return rc;
++}
++
++static int fs_nway_reset(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	return mii_nway_restart(&fep->mii_if);
++}
++
++static u32 fs_get_msglevel(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	return fep->msg_enable;
++}
++
++static void fs_set_msglevel(struct net_device *dev, u32 value)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fep->msg_enable = value;
++}
++
++static struct ethtool_ops fs_ethtool_ops = {
++	.get_drvinfo = fs_get_drvinfo,
++	.get_regs_len = fs_get_regs_len,
++	.get_settings = fs_get_settings,
++	.set_settings = fs_set_settings,
++	.nway_reset = fs_nway_reset,
++	.get_link = ethtool_op_get_link,
++	.get_msglevel = fs_get_msglevel,
++	.set_msglevel = fs_set_msglevel,
++	.get_tx_csum = ethtool_op_get_tx_csum,
++	.set_tx_csum = ethtool_op_set_tx_csum,	/* local! */
++	.get_sg = ethtool_op_get_sg,
++	.set_sg = ethtool_op_set_sg,
++	.get_regs = fs_get_regs,
++};
++
++static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data;
++	unsigned long flags;
++	int rc;
++
++	if (!netif_running(dev))
++		return -EINVAL;
++
++	spin_lock_irqsave(&fep->lock, flags);
++	rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL);
++	spin_unlock_irqrestore(&fep->lock, flags);
++	return rc;
++}
++
++extern int fs_mii_connect(struct net_device *dev);
++extern void fs_mii_disconnect(struct net_device *dev);
++
++static struct net_device *fs_init_instance(struct device *dev,
++		const struct fs_platform_info *fpi)
++{
++	struct net_device *ndev = NULL;
++	struct fs_enet_private *fep = NULL;
++	int privsize, i, r, err = 0, registered = 0;
++
++	/* guard */
++	if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX)
++		return ERR_PTR(-EINVAL);
++
++	privsize = sizeof(*fep) + (sizeof(struct sk_buff **) *
++			    (fpi->rx_ring + fpi->tx_ring));
++
++	ndev = alloc_etherdev(privsize);
++	if (!ndev) {
++		err = -ENOMEM;
++		goto err;
++	}
++	SET_MODULE_OWNER(ndev);
++
++	fep = netdev_priv(ndev);
++	memset(fep, 0, privsize);	/* clear everything */
++
++	fep->dev = dev;
++	dev_set_drvdata(dev, ndev);
++	fep->fpi = fpi;
++	if (fpi->init_ioports)
++		fpi->init_ioports();
++
++#ifdef CONFIG_FS_ENET_HAS_FEC
++	if (fs_get_fec_index(fpi->fs_no) >= 0)
++		fep->ops = &fs_fec_ops;
++#endif
++
++#ifdef CONFIG_FS_ENET_HAS_SCC
++	if (fs_get_scc_index(fpi->fs_no) >=0 )
++		fep->ops = &fs_scc_ops;
++#endif
++
++#ifdef CONFIG_FS_ENET_HAS_FCC
++	if (fs_get_fcc_index(fpi->fs_no) >= 0)
++		fep->ops = &fs_fcc_ops;
++#endif
++
++	if (fep->ops == NULL) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       ": %s No matching ops found (%d).\n",
++		       ndev->name, fpi->fs_no);
++		err = -EINVAL;
++		goto err;
++	}
++
++	r = (*fep->ops->setup_data)(ndev);
++	if (r != 0) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       ": %s setup_data failed\n",
++			ndev->name);
++		err = r;
++		goto err;
++	}
++
++	/* point rx_skbuff, tx_skbuff */
++	fep->rx_skbuff = (struct sk_buff **)&fep[1];
++	fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring;
++
++	/* init locks */
++	spin_lock_init(&fep->lock);
++	spin_lock_init(&fep->tx_lock);
++
++	/*
++	 * Set the Ethernet address. 
++	 */
++	for (i = 0; i < 6; i++)
++		ndev->dev_addr[i] = fpi->macaddr[i];
++	
++	r = (*fep->ops->allocate_bd)(ndev);
++	
++	if (fep->ring_base == NULL) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       ": %s buffer descriptor alloc failed (%d).\n", ndev->name, r);
++		err = r;
++		goto err;
++	}
++
++	/*
++	 * Set receive and transmit descriptor base.
++	 */
++	fep->rx_bd_base = fep->ring_base;
++	fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring;
++
++	/* initialize ring size variables */
++	fep->tx_ring = fpi->tx_ring;
++	fep->rx_ring = fpi->rx_ring;
++
++	/*
++	 * The FEC Ethernet specific entries in the device structure. 
++	 */
++	ndev->open = fs_enet_open;
++	ndev->hard_start_xmit = fs_enet_start_xmit;
++	ndev->tx_timeout = fs_timeout;
++	ndev->watchdog_timeo = 2 * HZ;
++	ndev->stop = fs_enet_close;
++	ndev->get_stats = fs_enet_get_stats;
++	ndev->set_multicast_list = fs_set_multicast_list;
++	if (fpi->use_napi) {
++		ndev->poll = fs_enet_rx_napi;
++		ndev->weight = fpi->napi_weight;
++	}
++	ndev->ethtool_ops = &fs_ethtool_ops;
++	ndev->do_ioctl = fs_ioctl;
++
++	init_timer(&fep->phy_timer_list);
++
++	netif_carrier_off(ndev);
++
++	err = register_netdev(ndev);
++	if (err != 0) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       ": %s register_netdev failed.\n", ndev->name);
++		goto err;
++	}
++	registered = 1;
++
++	err = fs_mii_connect(ndev);
++	if (err != 0) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       ": %s fs_mii_connect failed.\n", ndev->name);
++		goto err;
++	}
++
++	return ndev;
++
++      err:
++	if (ndev != NULL) {
++
++		if (registered)
++			unregister_netdev(ndev);
++
++		if (fep != NULL) {
++			(*fep->ops->free_bd)(ndev);
++			(*fep->ops->cleanup_data)(ndev);
++		}
++
++		free_netdev(ndev);
++	}
++
++	dev_set_drvdata(dev, NULL);
++
++	return ERR_PTR(err);
++}
++
++static int fs_cleanup_instance(struct net_device *ndev)
++{
++	struct fs_enet_private *fep;
++	const struct fs_platform_info *fpi;
++	struct device *dev;
++
++	if (ndev == NULL)
++		return -EINVAL;
++
++	fep = netdev_priv(ndev);
++	if (fep == NULL)
++		return -EINVAL;
++
++	fpi = fep->fpi;
++
++	fs_mii_disconnect(ndev);
++
++	unregister_netdev(ndev);
++
++	dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
++			  fep->ring_base, fep->ring_mem_addr);
++
++	/* reset it */
++	(*fep->ops->cleanup_data)(ndev);
++
++	dev = fep->dev;
++	if (dev != NULL) {
++		dev_set_drvdata(dev, NULL);
++		fep->dev = NULL;
++	}
++
++	free_netdev(ndev);
++
++	return 0;
++}
++
++/**************************************************************************************/
++
++/* handy pointer to the immap */
++void *fs_enet_immap = NULL;
++
++static int setup_immap(void)
++{
++	phys_addr_t paddr = 0;
++	unsigned long size = 0;
++
++#ifdef CONFIG_CPM1
++	paddr = IMAP_ADDR;
++	size = 0x10000;	/* map 64K */
++#endif
++
++#ifdef CONFIG_CPM2
++	paddr = CPM_MAP_ADDR;
++	size = 0x40000;	/* map 256 K */
++#endif
++	fs_enet_immap = ioremap(paddr, size);
++	if (fs_enet_immap == NULL)
++		return -EBADF;	/* XXX ahem; maybe just BUG_ON? */
++
++	return 0;
++}
++
++static void cleanup_immap(void)
++{
++	if (fs_enet_immap != NULL) {
++		iounmap(fs_enet_immap);
++		fs_enet_immap = NULL;
++	}
++}
++
++/**************************************************************************************/
++
++static int __devinit fs_enet_probe(struct device *dev)
++{
++	struct net_device *ndev;
++
++	/* no fixup - no device */
++	if (dev->platform_data == NULL) {
++		printk(KERN_INFO "fs_enet: "
++				"probe called with no platform data; "
++				"remove unused devices\n");
++		return -ENODEV;
++	}
++
++	ndev = fs_init_instance(dev, dev->platform_data);
++	if (IS_ERR(ndev))
++		return PTR_ERR(ndev);
++	return 0;
++}
++
++static int fs_enet_remove(struct device *dev)
++{
++	return fs_cleanup_instance(dev_get_drvdata(dev));
++}
++
++static struct device_driver fs_enet_fec_driver = {
++	.name	  	= "fsl-cpm-fec",
++	.bus		= &platform_bus_type,
++	.probe		= fs_enet_probe,
++	.remove		= fs_enet_remove,
++#ifdef CONFIG_PM
++/*	.suspend	= fs_enet_suspend,	TODO */
++/*	.resume		= fs_enet_resume,	TODO */
++#endif
++};
++
++static struct device_driver fs_enet_scc_driver = {
++	.name	  	= "fsl-cpm-scc",
++	.bus		= &platform_bus_type,
++	.probe		= fs_enet_probe,
++	.remove		= fs_enet_remove,
++#ifdef CONFIG_PM
++/*	.suspend	= fs_enet_suspend,	TODO */
++/*	.resume		= fs_enet_resume,	TODO */
++#endif
++};
++
++static struct device_driver fs_enet_fcc_driver = {
++	.name	  	= "fsl-cpm-fcc",
++	.bus		= &platform_bus_type,
++	.probe		= fs_enet_probe,
++	.remove		= fs_enet_remove,
++#ifdef CONFIG_PM
++/*	.suspend	= fs_enet_suspend,	TODO */
++/*	.resume		= fs_enet_resume,	TODO */
++#endif
++};
++
++static int __init fs_init(void)
++{
++	int r;
++
++	printk(KERN_INFO
++			"%s", version);
++
++	r = setup_immap();
++	if (r != 0)
++		return r;
++	r = driver_register(&fs_enet_fec_driver);
++	if (r != 0)
++		goto err;
++
++	r = driver_register(&fs_enet_fcc_driver);
++	if (r != 0)
++		goto err;
++
++	r = driver_register(&fs_enet_scc_driver);
++	if (r != 0)
++		goto err;
++
++	return 0;
++err:
++	cleanup_immap();
++	return r;
++	
++}
++
++static void __exit fs_cleanup(void)
++{
++	driver_unregister(&fs_enet_fec_driver);
++	driver_unregister(&fs_enet_fcc_driver);
++	driver_unregister(&fs_enet_scc_driver);
++	cleanup_immap();
++}
++
++/**************************************************************************************/
++
++module_init(fs_init);
++module_exit(fs_cleanup);
+diff --git a/drivers/net/fs_enet/fs_enet-mii.c b/drivers/net/fs_enet/fs_enet-mii.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/fs_enet-mii.c
+@@ -0,0 +1,507 @@
++/*
++ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
++ *
++ * Copyright (c) 2003 Intracom S.A. 
++ *  by Pantelis Antoniou <panto at intracom.gr>
++ * 
++ * 2005 (c) MontaVista Software, Inc. 
++ * Vitaly Bordug <vbordug at ru.mvista.com>
++ *
++ * Heavily based on original FEC driver by Dan Malek <dan at embeddededge.com>
++ * and modifications by Joakim Tjernlund <joakim.tjernlund at lumentis.se>
++ *
++ * 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 <asm/pgtable.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#include "fs_enet.h"
++
++/*************************************************/
++
++/*
++ * Generic PHY support.
++ * Should work for all PHYs, but link change is detected by polling
++ */
++
++static void generic_timer_callback(unsigned long data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	fep->phy_timer_list.expires = jiffies + HZ / 2;
++
++	add_timer(&fep->phy_timer_list);
++
++	fs_mii_link_status_change_check(dev, 0);
++}
++
++static void generic_startup(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	fep->phy_timer_list.expires = jiffies + HZ / 2;	/* every 500ms */
++	fep->phy_timer_list.data = (unsigned long)dev;
++	fep->phy_timer_list.function = generic_timer_callback;
++	add_timer(&fep->phy_timer_list);
++}
++
++static void generic_shutdown(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	del_timer_sync(&fep->phy_timer_list);
++}
++
++/* ------------------------------------------------------------------------- */
++/* The Davicom DM9161 is used on the NETTA board			     */
++
++/* register definitions */
++
++#define MII_DM9161_ANAR		4	/* Aux. Config Register         */
++#define MII_DM9161_ACR		16	/* Aux. Config Register         */
++#define MII_DM9161_ACSR		17	/* Aux. Config/Status Register  */
++#define MII_DM9161_10TCSR	18	/* 10BaseT Config/Status Reg.   */
++#define MII_DM9161_INTR		21	/* Interrupt Register           */
++#define MII_DM9161_RECR		22	/* Receive Error Counter Reg.   */
++#define MII_DM9161_DISCR	23	/* Disconnect Counter Register  */
++
++static void dm9161_startup(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000);
++	/* Start autonegotiation */
++	fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200);
++
++	set_current_state(TASK_UNINTERRUPTIBLE);
++	schedule_timeout(HZ*8);
++}
++
++static void dm9161_ack_int(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR);
++}
++
++static void dm9161_shutdown(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00);
++}
++
++/**********************************************************************************/
++
++static const struct phy_info phy_info[] = {
++	{
++		.id = 0x00181b88,
++		.name = "DM9161",
++		.startup = dm9161_startup,
++		.ack_int = dm9161_ack_int,
++		.shutdown = dm9161_shutdown,
++	}, {
++		.id = 0,
++		.name = "GENERIC",
++		.startup = generic_startup,
++		.shutdown = generic_shutdown,
++	},
++};
++
++/**********************************************************************************/
++
++static int phy_id_detect(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++	struct fs_enet_mii_bus *bus = fep->mii_bus;
++	int i, r, start, end, phytype, physubtype;
++	const struct phy_info *phy;
++	int phy_hwid, phy_id;
++
++	phy_hwid = -1;
++	fep->phy = NULL;
++
++	/* auto-detect? */
++	if (fpi->phy_addr == -1) {
++		start = 1;
++		end = 32;
++	} else {		/* direct */
++		start = fpi->phy_addr;
++		end = start + 1;
++	}
++
++	for (phy_id = start; phy_id < end; phy_id++) {
++		/* skip already used phy addresses on this bus */ 
++		if (bus->usage_map & (1 << phy_id))
++			continue;
++		r = fs_mii_read(dev, phy_id, MII_PHYSID1);
++		if (r == -1 || (phytype = (r & 0xffff)) == 0xffff)
++			continue;
++		r = fs_mii_read(dev, phy_id, MII_PHYSID2);
++		if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff)
++			continue;
++		phy_hwid = (phytype << 16) | physubtype;
++		if (phy_hwid != -1)
++			break;
++	}
++
++	if (phy_hwid == -1) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       ": %s No PHY detected! range=0x%02x-0x%02x\n",
++			dev->name, start, end);
++		return -1;
++	}
++
++	for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++)
++		if (phy->id == (phy_hwid >> 4) || phy->id == 0)
++			break;
++
++	if (i >= ARRAY_SIZE(phy_info)) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       ": %s PHY id 0x%08x is not supported!\n",
++		       dev->name, phy_hwid);
++		return -1;
++	}
++
++	fep->phy = phy;
++
++	/* mark this address as used */
++	bus->usage_map |= (1 << phy_id);
++
++	printk(KERN_INFO DRV_MODULE_NAME
++	       ": %s Phy @ 0x%x, type %s (0x%08x)%s\n",
++	       dev->name, phy_id, fep->phy->name, phy_hwid,
++	       fpi->phy_addr == -1 ? " (auto-detected)" : "");
++
++	return phy_id;
++}
++
++void fs_mii_startup(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	if (fep->phy->startup)
++		(*fep->phy->startup) (dev);
++}
++
++void fs_mii_shutdown(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	if (fep->phy->shutdown)
++		(*fep->phy->shutdown) (dev);
++}
++
++void fs_mii_ack_int(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	if (fep->phy->ack_int)
++		(*fep->phy->ack_int) (dev);
++}
++
++#define MII_LINK	0x0001
++#define MII_HALF	0x0002
++#define MII_FULL	0x0004
++#define MII_BASE4	0x0008
++#define MII_10M		0x0010
++#define MII_100M	0x0020
++#define MII_1G		0x0040
++#define MII_10G		0x0080
++
++/* return full mii info at one gulp, with a usable form */
++static unsigned int mii_full_status(struct mii_if_info *mii)
++{
++	unsigned int status;
++	int bmsr, adv, lpa, neg;
++	struct fs_enet_private* fep = netdev_priv(mii->dev);
++	
++	/* first, a dummy read, needed to latch some MII phys */
++	(void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
++	bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
++
++	/* no link */
++	if ((bmsr & BMSR_LSTATUS) == 0)
++		return 0;
++
++	status = MII_LINK;
++	
++	/* Lets look what ANEG says if it's supported - otherwize we shall
++	   take the right values from the platform info*/
++	if(!mii->force_media) {
++		/* autoneg not completed; don't bother */
++		if ((bmsr & BMSR_ANEGCOMPLETE) == 0)
++			return 0;
++
++		adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE);
++		lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA);
++
++		neg = lpa & adv;
++	} else {
++		neg = fep->fpi->bus_info->lpa;
++	}
++
++	if (neg & LPA_100FULL)
++		status |= MII_FULL | MII_100M;
++	else if (neg & LPA_100BASE4)
++		status |= MII_FULL | MII_BASE4 | MII_100M;
++	else if (neg & LPA_100HALF)
++		status |= MII_HALF | MII_100M;
++	else if (neg & LPA_10FULL)
++		status |= MII_FULL | MII_10M;
++	else
++		status |= MII_HALF | MII_10M;
++	
++	return status;
++}
++
++void fs_mii_link_status_change_check(struct net_device *dev, int init_media)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	struct mii_if_info *mii = &fep->mii_if;
++	unsigned int mii_status;
++	int ok_to_print, link, duplex, speed;
++	unsigned long flags;
++
++	ok_to_print = netif_msg_link(fep);
++
++	mii_status = mii_full_status(mii);
++
++	if (!init_media && mii_status == fep->last_mii_status)
++		return;
++
++	fep->last_mii_status = mii_status;
++
++	link = !!(mii_status & MII_LINK);
++	duplex = !!(mii_status & MII_FULL);
++	speed = (mii_status & MII_100M) ? 100 : 10;
++
++	if (link == 0) {
++		netif_carrier_off(mii->dev);
++		netif_stop_queue(dev);
++		if (!init_media) {
++			spin_lock_irqsave(&fep->lock, flags);
++			(*fep->ops->stop)(dev);
++			spin_unlock_irqrestore(&fep->lock, flags);
++		}
++
++		if (ok_to_print)
++			printk(KERN_INFO "%s: link down\n", mii->dev->name);
++
++	} else {
++
++		mii->full_duplex = duplex;
++
++		netif_carrier_on(mii->dev);
++
++		spin_lock_irqsave(&fep->lock, flags);
++		fep->duplex = duplex;
++		fep->speed = speed;
++		(*fep->ops->restart)(dev);
++		spin_unlock_irqrestore(&fep->lock, flags);
++
++		netif_start_queue(dev);
++
++		if (ok_to_print)
++			printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n",
++			       dev->name, speed, duplex ? "full" : "half");
++	}
++}
++
++/**********************************************************************************/
++
++int fs_mii_read(struct net_device *dev, int phy_id, int location)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	struct fs_enet_mii_bus *bus = fep->mii_bus;
++
++	unsigned long flags;
++	int ret;
++
++	spin_lock_irqsave(&bus->mii_lock, flags);
++	ret = (*bus->mii_read)(bus, phy_id, location);
++	spin_unlock_irqrestore(&bus->mii_lock, flags);
++
++	return ret;
++}
++
++void fs_mii_write(struct net_device *dev, int phy_id, int location, int value)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	struct fs_enet_mii_bus *bus = fep->mii_bus;
++	unsigned long flags;
++
++	spin_lock_irqsave(&bus->mii_lock, flags);
++	(*bus->mii_write)(bus, phy_id, location, value);
++	spin_unlock_irqrestore(&bus->mii_lock, flags);
++}
++
++/*****************************************************************************/
++
++/* list of all registered mii buses */
++static LIST_HEAD(fs_mii_bus_list);
++
++static struct fs_enet_mii_bus *lookup_bus(int method, int id)
++{
++	struct list_head *ptr;
++	struct fs_enet_mii_bus *bus;
++
++	list_for_each(ptr, &fs_mii_bus_list) {
++		bus = list_entry(ptr, struct fs_enet_mii_bus, list);
++		if (bus->bus_info->method == method &&
++			bus->bus_info->id == id)
++			return bus;
++	}
++	return NULL;
++}
++
++static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi)
++{
++	struct fs_enet_mii_bus *bus;
++	int ret = 0;
++
++	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
++	if (bus == NULL) {
++		ret = -ENOMEM;
++		goto err;
++	}
++	memset(bus, 0, sizeof(*bus));
++	spin_lock_init(&bus->mii_lock);
++	bus->bus_info = bi;
++	bus->refs = 0;
++	bus->usage_map = 0;
++
++	/* perform initialization */
++	switch (bi->method) {
++
++		case fsmii_fixed:
++			ret = fs_mii_fixed_init(bus);
++			if (ret != 0)
++				goto err;
++			break;
++
++		case fsmii_bitbang:
++			ret = fs_mii_bitbang_init(bus);
++			if (ret != 0)
++				goto err;
++			break;
++#ifdef CONFIG_FS_ENET_HAS_FEC
++		case fsmii_fec:
++			ret = fs_mii_fec_init(bus);
++			if (ret != 0)
++				goto err;
++			break;
++#endif
++		default:
++			ret = -EINVAL;
++			goto err;
++	}
++
++	list_add(&bus->list, &fs_mii_bus_list);
++
++	return bus;
++
++err:
++	if (bus)
++		kfree(bus);
++	return ERR_PTR(ret);
++}
++
++static void destroy_bus(struct fs_enet_mii_bus *bus)
++{
++	/* remove from bus list */
++	list_del(&bus->list);
++
++	/* nothing more needed */
++	kfree(bus);
++}
++
++int fs_mii_connect(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++	struct fs_enet_mii_bus *bus = NULL;
++
++	/* check method validity */
++	switch (fpi->bus_info->method) {
++		case fsmii_fixed:
++		case fsmii_bitbang:
++			break;
++#ifdef CONFIG_FS_ENET_HAS_FEC
++		case fsmii_fec:
++			break;
++#endif
++		default:
++			printk(KERN_ERR DRV_MODULE_NAME
++			       ": %s Unknown MII bus method (%d)!\n",
++			       dev->name, fpi->bus_info->method);
++			return -EINVAL; 
++	}
++
++	bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id);
++
++	/* if not found create new bus */
++	if (bus == NULL) {
++		bus = create_bus(fpi->bus_info);
++		if (IS_ERR(bus)) {
++			printk(KERN_ERR DRV_MODULE_NAME
++			       ": %s MII bus creation failure!\n", dev->name);
++			return PTR_ERR(bus);
++		}
++	}
++
++	bus->refs++;
++
++	fep->mii_bus = bus;
++
++	fep->mii_if.dev = dev;
++	fep->mii_if.phy_id_mask = 0x1f;
++	fep->mii_if.reg_num_mask = 0x1f;
++	fep->mii_if.mdio_read = fs_mii_read;
++	fep->mii_if.mdio_write = fs_mii_write;
++	fep->mii_if.force_media = fpi->bus_info->disable_aneg;
++	fep->mii_if.phy_id = phy_id_detect(dev);
++
++	return 0;
++}
++
++void fs_mii_disconnect(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	struct fs_enet_mii_bus *bus = NULL;
++
++	bus = fep->mii_bus;
++	fep->mii_bus = NULL;
++
++	if (--bus->refs <= 0)
++		destroy_bus(bus);
++}
+diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/fs_enet.h
+@@ -0,0 +1,245 @@
++#ifndef FS_ENET_H
++#define FS_ENET_H
++
++#include <linux/mii.h>
++#include <linux/netdevice.h>
++#include <linux/types.h>
++#include <linux/version.h>
++#include <linux/list.h>
++
++#include <linux/fs_enet_pd.h>
++
++#include <asm/dma-mapping.h>
++
++#ifdef CONFIG_CPM1
++#include <asm/commproc.h>
++#endif
++
++#ifdef CONFIG_CPM2
++#include <asm/cpm2.h>
++#endif
++
++/* hw driver ops */
++struct fs_ops {
++	int (*setup_data)(struct net_device *dev);
++	int (*allocate_bd)(struct net_device *dev);
++	void (*free_bd)(struct net_device *dev);
++	void (*cleanup_data)(struct net_device *dev);
++	void (*set_multicast_list)(struct net_device *dev);
++	void (*restart)(struct net_device *dev);
++	void (*stop)(struct net_device *dev);
++	void (*pre_request_irq)(struct net_device *dev, int irq);
++	void (*post_free_irq)(struct net_device *dev, int irq);
++	void (*napi_clear_rx_event)(struct net_device *dev);
++	void (*napi_enable_rx)(struct net_device *dev);
++	void (*napi_disable_rx)(struct net_device *dev);
++	void (*rx_bd_done)(struct net_device *dev);
++	void (*tx_kickstart)(struct net_device *dev);
++	u32 (*get_int_events)(struct net_device *dev);
++	void (*clear_int_events)(struct net_device *dev, u32 int_events);
++	void (*ev_error)(struct net_device *dev, u32 int_events);
++	int (*get_regs)(struct net_device *dev, void *p, int *sizep);
++	int (*get_regs_len)(struct net_device *dev);
++	void (*tx_restart)(struct net_device *dev);
++};
++
++struct phy_info {
++	unsigned int id;
++	const char *name;
++	void (*startup) (struct net_device * dev);
++	void (*shutdown) (struct net_device * dev);
++	void (*ack_int) (struct net_device * dev);
++};
++
++/* The FEC stores dest/src/type, data, and checksum for receive packets.
++ */
++#define MAX_MTU 1508		/* Allow fullsized pppoe packets over VLAN */
++#define MIN_MTU 46		/* this is data size */
++#define CRC_LEN 4
++
++#define PKT_MAXBUF_SIZE		(MAX_MTU+ETH_HLEN+CRC_LEN)
++#define PKT_MINBUF_SIZE		(MIN_MTU+ETH_HLEN+CRC_LEN)
++
++/* Must be a multiple of 32 (to cover both FEC & FCC) */
++#define PKT_MAXBLR_SIZE		((PKT_MAXBUF_SIZE + 31) & ~31)
++/* This is needed so that invalidate_xxx wont invalidate too much */
++#define ENET_RX_FRSIZE		L1_CACHE_ALIGN(PKT_MAXBUF_SIZE)
++
++struct fs_enet_mii_bus {
++	struct list_head list;
++	spinlock_t mii_lock;
++	const struct fs_mii_bus_info *bus_info;
++	int refs;
++	u32 usage_map;
++
++	int (*mii_read)(struct fs_enet_mii_bus *bus,
++			int phy_id, int location);
++
++	void (*mii_write)(struct fs_enet_mii_bus *bus,
++			int phy_id, int location, int value);
++
++	union {
++		struct {
++			unsigned int mii_speed;
++			void *fecp;
++		} fec;
++
++		struct {
++			/* note that the actual port size may */
++			/* be different; cpm(s) handle it OK  */
++			u8 mdio_msk;
++			u8 *mdio_dir;
++			u8 *mdio_dat;
++			u8 mdc_msk;
++			u8 *mdc_dir;
++			u8 *mdc_dat;
++		} bitbang;
++
++		struct {
++			u16 lpa;
++		} fixed;
++	};
++};
++
++int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus);
++int fs_mii_fixed_init(struct fs_enet_mii_bus *bus);
++int fs_mii_fec_init(struct fs_enet_mii_bus *bus);
++
++struct fs_enet_private {
++	struct device *dev;	/* pointer back to the device (must be initialized first) */
++	spinlock_t lock;	/* during all ops except TX pckt processing */
++	spinlock_t tx_lock;	/* during fs_start_xmit and fs_tx         */
++	const struct fs_platform_info *fpi;
++	const struct fs_ops *ops;
++	int rx_ring, tx_ring;
++	dma_addr_t ring_mem_addr;
++	void *ring_base;
++	struct sk_buff **rx_skbuff;
++	struct sk_buff **tx_skbuff;
++	cbd_t *rx_bd_base;	/* Address of Rx and Tx buffers.    */
++	cbd_t *tx_bd_base;
++	cbd_t *dirty_tx;	/* ring entries to be free()ed.     */
++	cbd_t *cur_rx;
++	cbd_t *cur_tx;
++	int tx_free;
++	struct net_device_stats stats;
++	struct timer_list phy_timer_list;
++	const struct phy_info *phy;
++	u32 msg_enable;
++	struct mii_if_info mii_if;
++	unsigned int last_mii_status;
++	struct fs_enet_mii_bus *mii_bus;
++	int interrupt;
++
++	int duplex, speed;	/* current settings */
++
++	/* event masks */
++	u32 ev_napi_rx;		/* mask of NAPI rx events */
++	u32 ev_rx;		/* rx event mask          */
++	u32 ev_tx;		/* tx event mask          */
++	u32 ev_err;		/* error event mask       */
++
++	u16 bd_rx_empty;	/* mask of BD rx empty	  */
++	u16 bd_rx_err;		/* mask of BD rx errors   */
++
++	union {
++		struct {
++			int idx;		/* FEC1 = 0, FEC2 = 1  */
++			void *fecp;		/* hw registers        */
++			u32 hthi, htlo;		/* state for multicast */
++		} fec;
++
++		struct {
++			int idx;		/* FCC1-3 = 0-2	       */
++			void *fccp;		/* hw registers	       */
++			void *ep;		/* parameter ram       */
++			void *fcccp;		/* hw registers cont.  */
++			void *mem;		/* FCC DPRAM */
++			u32 gaddrh, gaddrl;	/* group address       */
++		} fcc;
++
++		struct {
++			int idx;		/* FEC1 = 0, FEC2 = 1  */
++			void *sccp;		/* hw registers        */
++			void *ep;		/* parameter ram       */
++			u32 hthi, htlo;		/* state for multicast */
++		} scc;
++
++	};
++};
++
++/***************************************************************************/
++
++int fs_mii_read(struct net_device *dev, int phy_id, int location);
++void fs_mii_write(struct net_device *dev, int phy_id, int location, int value);
++
++void fs_mii_startup(struct net_device *dev);
++void fs_mii_shutdown(struct net_device *dev);
++void fs_mii_ack_int(struct net_device *dev);
++
++void fs_mii_link_status_change_check(struct net_device *dev, int init_media);
++
++void fs_init_bds(struct net_device *dev);
++void fs_cleanup_bds(struct net_device *dev);
++
++/***************************************************************************/
++
++#define DRV_MODULE_NAME		"fs_enet"
++#define PFX DRV_MODULE_NAME	": "
++#define DRV_MODULE_VERSION	"1.0"
++#define DRV_MODULE_RELDATE	"Aug 8, 2005"
++
++/***************************************************************************/
++
++int fs_enet_platform_init(void);
++void fs_enet_platform_cleanup(void);
++
++/***************************************************************************/
++
++/* buffer descriptor access macros */
++
++/* access macros */
++#if defined(CONFIG_CPM1)
++/* for a a CPM1 __raw_xxx's are sufficient */
++#define __cbd_out32(addr, x)	__raw_writel(x, addr)
++#define __cbd_out16(addr, x)	__raw_writew(x, addr)
++#define __cbd_in32(addr)	__raw_readl(addr)
++#define __cbd_in16(addr)	__raw_readw(addr)
++#else
++/* for others play it safe */
++#define __cbd_out32(addr, x)	out_be32(addr, x)
++#define __cbd_out16(addr, x)	out_be16(addr, x)
++#define __cbd_in32(addr)	in_be32(addr)
++#define __cbd_in16(addr)	in_be16(addr)
++#endif
++
++/* write */
++#define CBDW_SC(_cbd, _sc) 		__cbd_out16(&(_cbd)->cbd_sc, (_sc))
++#define CBDW_DATLEN(_cbd, _datlen)	__cbd_out16(&(_cbd)->cbd_datlen, (_datlen))
++#define CBDW_BUFADDR(_cbd, _bufaddr)	__cbd_out32(&(_cbd)->cbd_bufaddr, (_bufaddr))
++
++/* read */
++#define CBDR_SC(_cbd) 			__cbd_in16(&(_cbd)->cbd_sc)
++#define CBDR_DATLEN(_cbd)		__cbd_in16(&(_cbd)->cbd_datlen)
++#define CBDR_BUFADDR(_cbd)		__cbd_in32(&(_cbd)->cbd_bufaddr)
++
++/* set bits */
++#define CBDS_SC(_cbd, _sc) 		CBDW_SC(_cbd, CBDR_SC(_cbd) | (_sc))
++
++/* clear bits */
++#define CBDC_SC(_cbd, _sc) 		CBDW_SC(_cbd, CBDR_SC(_cbd) & ~(_sc))
++
++/*******************************************************************/
++
++extern const struct fs_ops fs_fec_ops;
++extern const struct fs_ops fs_fcc_ops;
++extern const struct fs_ops fs_scc_ops;
++
++/*******************************************************************/
++
++/* handy pointer to the immap */
++extern void *fs_enet_immap;
++
++/*******************************************************************/
++
++#endif
+diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/mac-fcc.c
+@@ -0,0 +1,578 @@
++/*
++ * FCC driver for Motorola MPC82xx (PQ2).
++ *
++ * Copyright (c) 2003 Intracom S.A. 
++ *  by Pantelis Antoniou <panto at intracom.gr>
++ *
++ * 2005 (c) MontaVista Software, Inc. 
++ * Vitaly Bordug <vbordug at 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/kernel.h>
++#include <linux/types.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/fs.h>
++
++#include <asm/immap_cpm2.h>
++#include <asm/mpc8260.h>
++#include <asm/cpm2.h>
++
++#include <asm/pgtable.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#include "fs_enet.h"
++
++/*************************************************/
++
++/* FCC access macros */
++
++#define __fcc_out32(addr, x)	out_be32((unsigned *)addr, x)
++#define __fcc_out16(addr, x)	out_be16((unsigned short *)addr, x)
++#define __fcc_out8(addr, x)	out_8((unsigned char *)addr, x)
++#define __fcc_in32(addr)	in_be32((unsigned *)addr)
++#define __fcc_in16(addr)	in_be16((unsigned short *)addr)
++#define __fcc_in8(addr)		in_8((unsigned char *)addr)
++
++/* parameter space */
++
++/* write, read, set bits, clear bits */
++#define W32(_p, _m, _v)	__fcc_out32(&(_p)->_m, (_v))
++#define R32(_p, _m)	__fcc_in32(&(_p)->_m)
++#define S32(_p, _m, _v)	W32(_p, _m, R32(_p, _m) | (_v))
++#define C32(_p, _m, _v)	W32(_p, _m, R32(_p, _m) & ~(_v))
++
++#define W16(_p, _m, _v)	__fcc_out16(&(_p)->_m, (_v))
++#define R16(_p, _m)	__fcc_in16(&(_p)->_m)
++#define S16(_p, _m, _v)	W16(_p, _m, R16(_p, _m) | (_v))
++#define C16(_p, _m, _v)	W16(_p, _m, R16(_p, _m) & ~(_v))
++
++#define W8(_p, _m, _v)	__fcc_out8(&(_p)->_m, (_v))
++#define R8(_p, _m)	__fcc_in8(&(_p)->_m)
++#define S8(_p, _m, _v)	W8(_p, _m, R8(_p, _m) | (_v))
++#define C8(_p, _m, _v)	W8(_p, _m, R8(_p, _m) & ~(_v))
++
++/*************************************************/
++
++#define FCC_MAX_MULTICAST_ADDRS	64
++
++#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 MAX_CR_CMD_LOOPS	10000
++
++static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op)
++{
++	const struct fs_platform_info *fpi = fep->fpi;
++
++	cpm2_map_t *immap = fs_enet_immap;
++	cpm_cpm2_t *cpmp = &immap->im_cpm;
++	u32 v;
++	int i;
++
++	/* Currently I don't know what feature call will look like. But 
++	   I guess there'd be something like do_cpm_cmd() which will require page & sblock */
++	v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op);
++	W32(cpmp, cp_cpcr, v | CPM_CR_FLG);
++	for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
++		if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
++			break;
++
++	if (i >= MAX_CR_CMD_LOOPS) {
++		printk(KERN_ERR "%s(): Not able to issue CPM command\n",
++		       __FUNCTION__);
++		return 1;
++	}
++
++	return 0;
++}
++
++static int do_pd_setup(struct fs_enet_private *fep)
++{
++	struct platform_device *pdev = to_platform_device(fep->dev);
++	struct resource *r;
++
++	/* Fill out IRQ field */
++	fep->interrupt = platform_get_irq(pdev, 0);
++
++	/* Attach the memory for the FCC Parameter RAM */
++	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram");
++	fep->fcc.ep = (void *)r->start;
++
++	if (fep->fcc.ep == NULL)
++		return -EINVAL;
++
++	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs");
++	fep->fcc.fccp = (void *)r->start;
++
++	if (fep->fcc.fccp == NULL)
++		return -EINVAL;
++
++	fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c;
++
++	if (fep->fcc.fcccp == NULL)
++		return -EINVAL;
++
++	return 0;
++}
++
++#define FCC_NAPI_RX_EVENT_MSK	(FCC_ENET_RXF | FCC_ENET_RXB)
++#define FCC_RX_EVENT		(FCC_ENET_RXF)
++#define FCC_TX_EVENT		(FCC_ENET_TXB)
++#define FCC_ERR_EVENT_MSK	(FCC_ENET_TXE | FCC_ENET_BSY)
++
++static int setup_data(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++
++	fep->fcc.idx = fs_get_fcc_index(fpi->fs_no);
++	if ((unsigned int)fep->fcc.idx >= 3)	/* max 3 FCCs */
++		return -EINVAL;
++
++	fep->fcc.mem = (void *)fpi->mem_offset;
++
++	if (do_pd_setup(fep) != 0)
++		return -EINVAL;
++
++	fep->ev_napi_rx = FCC_NAPI_RX_EVENT_MSK;
++	fep->ev_rx = FCC_RX_EVENT;
++	fep->ev_tx = FCC_TX_EVENT;
++	fep->ev_err = FCC_ERR_EVENT_MSK;
++
++	return 0;
++}
++
++static int allocate_bd(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++
++	fep->ring_base = dma_alloc_coherent(fep->dev,
++					    (fpi->tx_ring + fpi->rx_ring) *
++					    sizeof(cbd_t), &fep->ring_mem_addr,
++					    GFP_KERNEL);
++	if (fep->ring_base == NULL)
++		return -ENOMEM;
++
++	return 0;
++}
++
++static void free_bd(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++
++	if (fep->ring_base)
++		dma_free_coherent(fep->dev,
++			(fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
++			fep->ring_base, fep->ring_mem_addr);
++}
++
++static void cleanup_data(struct net_device *dev)
++{
++	/* nothing */
++}
++
++static void set_promiscuous_mode(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_t *fccp = fep->fcc.fccp;
++
++	S32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
++}
++
++static void set_multicast_start(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_enet_t *ep = fep->fcc.ep;
++
++	W32(ep, fen_gaddrh, 0);
++	W32(ep, fen_gaddrl, 0);
++}
++
++static void set_multicast_one(struct net_device *dev, const u8 *mac)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_enet_t *ep = fep->fcc.ep;
++	u16 taddrh, taddrm, taddrl;
++
++	taddrh = ((u16)mac[5] << 8) | mac[4];
++	taddrm = ((u16)mac[3] << 8) | mac[2];
++	taddrl = ((u16)mac[1] << 8) | mac[0];
++
++	W16(ep, fen_taddrh, taddrh);
++	W16(ep, fen_taddrm, taddrm);
++	W16(ep, fen_taddrl, taddrl);
++	fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR);
++}
++
++static void set_multicast_finish(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_t *fccp = fep->fcc.fccp;
++	fcc_enet_t *ep = fep->fcc.ep;
++
++	/* clear promiscuous always */
++	C32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
++
++	/* if all multi or too many multicasts; just enable all */
++	if ((dev->flags & IFF_ALLMULTI) != 0 ||
++	    dev->mc_count > FCC_MAX_MULTICAST_ADDRS) {
++
++		W32(ep, fen_gaddrh, 0xffffffff);
++		W32(ep, fen_gaddrl, 0xffffffff);
++	}
++
++	/* read back */
++	fep->fcc.gaddrh = R32(ep, fen_gaddrh);
++	fep->fcc.gaddrl = R32(ep, fen_gaddrl);
++}
++
++static void set_multicast_list(struct net_device *dev)
++{
++	struct dev_mc_list *pmc;
++
++	if ((dev->flags & IFF_PROMISC) == 0) {
++		set_multicast_start(dev);
++		for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
++			set_multicast_one(dev, pmc->dmi_addr);
++		set_multicast_finish(dev);
++	} else
++		set_promiscuous_mode(dev);
++}
++
++static void restart(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++	fcc_t *fccp = fep->fcc.fccp;
++	fcc_c_t *fcccp = fep->fcc.fcccp;
++	fcc_enet_t *ep = fep->fcc.ep;
++	dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
++	u16 paddrh, paddrm, paddrl;
++	u16 mem_addr;
++	const unsigned char *mac;
++	int i;
++
++	C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
++
++	/* clear everything (slow & steady does it) */
++	for (i = 0; i < sizeof(*ep); i++)
++		__fcc_out8((char *)ep + i, 0);
++
++	/* get physical address */
++	rx_bd_base_phys = fep->ring_mem_addr;
++	tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring;
++
++	/* point to bds */
++	W32(ep, fen_genfcc.fcc_rbase, rx_bd_base_phys);
++	W32(ep, fen_genfcc.fcc_tbase, tx_bd_base_phys);
++
++	/* Set maximum bytes per receive buffer.
++	 * It must be a multiple of 32.
++	 */
++	W16(ep, fen_genfcc.fcc_mrblr, PKT_MAXBLR_SIZE);
++
++	W32(ep, fen_genfcc.fcc_rstate, (CPMFCR_GBL | CPMFCR_EB) << 24);
++	W32(ep, fen_genfcc.fcc_tstate, (CPMFCR_GBL | CPMFCR_EB) << 24);
++
++	/* Allocate space in the reserved FCC area of DPRAM for the
++	 * internal buffers.  No one uses this space (yet), so we
++	 * can do this.  Later, we will add resource management for
++	 * this area.
++	 */
++
++	mem_addr = (u32) fep->fcc.mem;	/* de-fixup dpram offset */
++
++	W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff));
++	W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff));
++	W16(ep, fen_padptr, mem_addr + 64);
++
++	/* fill with special symbol...  */
++	memset(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32);
++
++	W32(ep, fen_genfcc.fcc_rbptr, 0);
++	W32(ep, fen_genfcc.fcc_tbptr, 0);
++	W32(ep, fen_genfcc.fcc_rcrc, 0);
++	W32(ep, fen_genfcc.fcc_tcrc, 0);
++	W16(ep, fen_genfcc.fcc_res1, 0);
++	W32(ep, fen_genfcc.fcc_res2, 0);
++
++	/* no CAM */
++	W32(ep, fen_camptr, 0);
++
++	/* Set CRC preset and mask */
++	W32(ep, fen_cmask, 0xdebb20e3);
++	W32(ep, fen_cpres, 0xffffffff);
++
++	W32(ep, fen_crcec, 0);		/* CRC Error counter       */
++	W32(ep, fen_alec, 0);		/* alignment error counter */
++	W32(ep, fen_disfc, 0);		/* discard frame counter   */
++	W16(ep, fen_retlim, 15);	/* Retry limit threshold   */
++	W16(ep, fen_pper, 0);		/* Normal persistence      */
++
++	/* set group address */
++	W32(ep, fen_gaddrh, fep->fcc.gaddrh);
++	W32(ep, fen_gaddrl, fep->fcc.gaddrh);
++
++	/* Clear hash filter tables */
++	W32(ep, fen_iaddrh, 0);
++	W32(ep, fen_iaddrl, 0);
++
++	/* Clear the Out-of-sequence TxBD  */
++	W16(ep, fen_tfcstat, 0);
++	W16(ep, fen_tfclen, 0);
++	W32(ep, fen_tfcptr, 0);
++
++	W16(ep, fen_mflr, PKT_MAXBUF_SIZE);	/* maximum frame length register */
++	W16(ep, fen_minflr, PKT_MINBUF_SIZE);	/* minimum frame length register */
++
++	/* set address */
++	mac = dev->dev_addr;
++	paddrh = ((u16)mac[5] << 8) | mac[4];
++	paddrm = ((u16)mac[3] << 8) | mac[2];
++	paddrl = ((u16)mac[1] << 8) | mac[0];
++
++	W16(ep, fen_paddrh, paddrh);
++	W16(ep, fen_paddrm, paddrm);
++	W16(ep, fen_paddrl, paddrl);
++
++	W16(ep, fen_taddrh, 0);
++	W16(ep, fen_taddrm, 0);
++	W16(ep, fen_taddrl, 0);
++
++	W16(ep, fen_maxd1, 1520);	/* maximum DMA1 length */
++	W16(ep, fen_maxd2, 1520);	/* maximum DMA2 length */
++
++	/* Clear stat counters, in case we ever enable RMON */
++	W32(ep, fen_octc, 0);
++	W32(ep, fen_colc, 0);
++	W32(ep, fen_broc, 0);
++	W32(ep, fen_mulc, 0);
++	W32(ep, fen_uspc, 0);
++	W32(ep, fen_frgc, 0);
++	W32(ep, fen_ospc, 0);
++	W32(ep, fen_jbrc, 0);
++	W32(ep, fen_p64c, 0);
++	W32(ep, fen_p65c, 0);
++	W32(ep, fen_p128c, 0);
++	W32(ep, fen_p256c, 0);
++	W32(ep, fen_p512c, 0);
++	W32(ep, fen_p1024c, 0);
++
++	W16(ep, fen_rfthr, 0);	/* Suggested by manual */
++	W16(ep, fen_rfcnt, 0);
++	W16(ep, fen_cftype, 0);
++
++	fs_init_bds(dev);
++
++	/* adjust to speed (for RMII mode) */
++	if (fpi->use_rmii) {
++		if (fep->speed == 100)
++			C8(fcccp, fcc_gfemr, 0x20);
++		else
++			S8(fcccp, fcc_gfemr, 0x20);
++	}
++
++	fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX);
++
++	/* clear events */
++	W16(fccp, fcc_fcce, 0xffff);
++
++	/* Enable interrupts we wish to service */
++	W16(fccp, fcc_fccm, FCC_ENET_TXE | FCC_ENET_RXF | FCC_ENET_TXB);
++
++	/* Set GFMR to enable Ethernet operating mode */
++	W32(fccp, fcc_gfmr, FCC_GFMR_TCI | FCC_GFMR_MODE_ENET);
++
++	/* set sync/delimiters */
++	W16(fccp, fcc_fdsr, 0xd555);
++
++	W32(fccp, fcc_fpsmr, FCC_PSMR_ENCRC);
++
++	if (fpi->use_rmii)
++		S32(fccp, fcc_fpsmr, FCC_PSMR_RMII);
++
++	/* adjust to duplex mode */
++	if (fep->duplex)
++		S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
++	else
++		C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
++
++	S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
++}
++
++static void stop(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_t *fccp = fep->fcc.fccp;
++
++	/* stop ethernet */
++	C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
++
++	/* clear events */
++	W16(fccp, fcc_fcce, 0xffff);
++
++	/* clear interrupt mask */
++	W16(fccp, fcc_fccm, 0);
++
++	fs_cleanup_bds(dev);
++}
++
++static void pre_request_irq(struct net_device *dev, int irq)
++{
++	/* nothing */
++}
++
++static void post_free_irq(struct net_device *dev, int irq)
++{
++	/* nothing */
++}
++
++static void napi_clear_rx_event(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_t *fccp = fep->fcc.fccp;
++
++	W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK);
++}
++
++static void napi_enable_rx(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_t *fccp = fep->fcc.fccp;
++
++	S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
++}
++
++static void napi_disable_rx(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_t *fccp = fep->fcc.fccp;
++
++	C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
++}
++
++static void rx_bd_done(struct net_device *dev)
++{
++	/* nothing */
++}
++
++static void tx_kickstart(struct net_device *dev)
++{
++	/* nothing */
++}
++
++static u32 get_int_events(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_t *fccp = fep->fcc.fccp;
++
++	return (u32)R16(fccp, fcc_fcce);
++}
++
++static void clear_int_events(struct net_device *dev, u32 int_events)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_t *fccp = fep->fcc.fccp;
++
++	W16(fccp, fcc_fcce, int_events & 0xffff);
++}
++
++static void ev_error(struct net_device *dev, u32 int_events)
++{
++	printk(KERN_WARNING DRV_MODULE_NAME
++	       ": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events);
++}
++
++int get_regs(struct net_device *dev, void *p, int *sizep)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t))
++		return -EINVAL;
++
++	memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t));
++	p = (char *)p + sizeof(fcc_t);
++
++	memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t));
++	p = (char *)p + sizeof(fcc_c_t);
++
++	memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t));
++
++	return 0;
++}
++
++int get_regs_len(struct net_device *dev)
++{
++	return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t);
++}
++
++/* Some transmit errors cause the transmitter to shut
++ * down.  We now issue a restart transmit.  Since the
++ * errors close the BD and update the pointers, the restart
++ * _should_ pick up without having to reset any of our
++ * pointers either.  Also, To workaround 8260 device erratum 
++ * CPM37, we must disable and then re-enable the transmitter
++ * following a Late Collision, Underrun, or Retry Limit error.
++ */
++void tx_restart(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fcc_t *fccp = fep->fcc.fccp;
++
++	C32(fccp, fcc_gfmr, FCC_GFMR_ENT);
++	udelay(10);
++	S32(fccp, fcc_gfmr, FCC_GFMR_ENT);
++
++	fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX);
++}
++
++/*************************************************************************/
++
++const struct fs_ops fs_fcc_ops = {
++	.setup_data		= setup_data,
++	.cleanup_data		= cleanup_data,
++	.set_multicast_list	= set_multicast_list,
++	.restart		= restart,
++	.stop			= stop,
++	.pre_request_irq	= pre_request_irq,
++	.post_free_irq		= post_free_irq,
++	.napi_clear_rx_event	= napi_clear_rx_event,
++	.napi_enable_rx		= napi_enable_rx,
++	.napi_disable_rx	= napi_disable_rx,
++	.rx_bd_done		= rx_bd_done,
++	.tx_kickstart		= tx_kickstart,
++	.get_int_events		= get_int_events,
++	.clear_int_events	= clear_int_events,
++	.ev_error		= ev_error,
++	.get_regs		= get_regs,
++	.get_regs_len		= get_regs_len,
++	.tx_restart		= tx_restart,
++	.allocate_bd		= allocate_bd,
++	.free_bd		= free_bd,
++};
+diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/mac-fec.c
+@@ -0,0 +1,653 @@
++/*
++ * Freescale Ethernet controllers
++ *
++ * Copyright (c) 2005 Intracom S.A. 
++ *  by Pantelis Antoniou <panto at intracom.gr>
++ *
++ * 2005 (c) MontaVista Software, Inc. 
++ * Vitaly Bordug <vbordug at 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/kernel.h>
++#include <linux/types.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/fs.h>
++
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#ifdef CONFIG_8xx
++#include <asm/8xx_immap.h>
++#include <asm/pgtable.h>
++#include <asm/mpc8xx.h>
++#include <asm/commproc.h>
++#endif
++
++#include "fs_enet.h"
++
++/*************************************************/
++
++#if defined(CONFIG_CPM1)
++/* for a CPM1 __raw_xxx's are sufficient */
++#define __fs_out32(addr, x)	__raw_writel(x, addr)
++#define __fs_out16(addr, x)	__raw_writew(x, addr)
++#define __fs_in32(addr)	__raw_readl(addr)
++#define __fs_in16(addr)	__raw_readw(addr)
++#else
++/* for others play it safe */
++#define __fs_out32(addr, x)	out_be32(addr, x)
++#define __fs_out16(addr, x)	out_be16(addr, x)
++#define __fs_in32(addr)	in_be32(addr)
++#define __fs_in16(addr)	in_be16(addr)
++#endif
++
++/* write */
++#define FW(_fecp, _reg, _v) __fs_out32(&(_fecp)->fec_ ## _reg, (_v))
++
++/* read */
++#define FR(_fecp, _reg)	__fs_in32(&(_fecp)->fec_ ## _reg)
++
++/* set bits */
++#define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v))
++
++/* clear bits */
++#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v))
++
++
++/* 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
++
++
++/* 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
++
++/*
++ * Delay to wait for FEC reset command to complete (in us) 
++ */
++#define FEC_RESET_DELAY		50
++
++static int whack_reset(fec_t * fecp)
++{
++	int i;
++
++	FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET);
++	for (i = 0; i < FEC_RESET_DELAY; i++) {
++		if ((FR(fecp, ecntrl) & FEC_ECNTRL_RESET) == 0)
++			return 0;	/* OK */
++		udelay(1);
++	}
++
++	return -1;
++}
++
++static int do_pd_setup(struct fs_enet_private *fep)
++{
++	struct platform_device *pdev = to_platform_device(fep->dev); 
++	struct resource	*r;
++	
++	/* Fill out IRQ field */
++	fep->interrupt = platform_get_irq_byname(pdev,"interrupt");
++	
++	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
++	fep->fec.fecp =(void*)r->start;
++
++	if(fep->fec.fecp == NULL)
++		return -EINVAL;
++
++	return 0;
++	
++}
++
++#define FEC_NAPI_RX_EVENT_MSK	(FEC_ENET_RXF | FEC_ENET_RXB)
++#define FEC_RX_EVENT		(FEC_ENET_RXF)
++#define FEC_TX_EVENT		(FEC_ENET_TXF)
++#define FEC_ERR_EVENT_MSK	(FEC_ENET_HBERR | FEC_ENET_BABR | \
++				 FEC_ENET_BABT | FEC_ENET_EBERR)
++
++static int setup_data(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	if (do_pd_setup(fep) != 0)
++		return -EINVAL;
++
++	fep->fec.hthi = 0;
++	fep->fec.htlo = 0;
++
++	fep->ev_napi_rx = FEC_NAPI_RX_EVENT_MSK;
++	fep->ev_rx = FEC_RX_EVENT;
++	fep->ev_tx = FEC_TX_EVENT;
++	fep->ev_err = FEC_ERR_EVENT_MSK;
++
++	return 0;
++}
++
++static int allocate_bd(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++	
++	fep->ring_base = dma_alloc_coherent(fep->dev,
++					    (fpi->tx_ring + fpi->rx_ring) *
++					    sizeof(cbd_t), &fep->ring_mem_addr,
++					    GFP_KERNEL);
++	if (fep->ring_base == NULL)
++		return -ENOMEM;
++
++	return 0;
++}
++
++static void free_bd(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++
++	if(fep->ring_base)
++		dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring)
++					* sizeof(cbd_t),
++					fep->ring_base,
++					fep->ring_mem_addr);
++}
++
++static void cleanup_data(struct net_device *dev)
++{
++	/* nothing */
++}
++
++static void set_promiscuous_mode(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++
++	FS(fecp, r_cntrl, FEC_RCNTRL_PROM);
++}
++
++static void set_multicast_start(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	fep->fec.hthi = 0;
++	fep->fec.htlo = 0;
++}
++
++static void set_multicast_one(struct net_device *dev, const u8 *mac)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	int temp, hash_index, i, j;
++	u32 crc, csrVal;
++	u8 byte, msb;
++
++	crc = 0xffffffff;
++	for (i = 0; i < 6; i++) {
++		byte = mac[i];
++		for (j = 0; j < 8; j++) {
++			msb = crc >> 31;
++			crc <<= 1;
++			if (msb ^ (byte & 0x1))
++				crc ^= FEC_CRC_POLY;
++			byte >>= 1;
++		}
++	}
++
++	temp = (crc & 0x3f) >> 1;
++	hash_index = ((temp & 0x01) << 4) |
++		     ((temp & 0x02) << 2) |
++		     ((temp & 0x04)) |
++		     ((temp & 0x08) >> 2) |
++		     ((temp & 0x10) >> 4);
++	csrVal = 1 << hash_index;
++	if (crc & 1)
++		fep->fec.hthi |= csrVal;
++	else
++		fep->fec.htlo |= csrVal;
++}
++
++static void set_multicast_finish(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++
++	/* if all multi or too many multicasts; just enable all */
++	if ((dev->flags & IFF_ALLMULTI) != 0 ||
++	    dev->mc_count > FEC_MAX_MULTICAST_ADDRS) {
++		fep->fec.hthi = 0xffffffffU;
++		fep->fec.htlo = 0xffffffffU;
++	}
++
++	FC(fecp, r_cntrl, FEC_RCNTRL_PROM);
++	FW(fecp, hash_table_high, fep->fec.hthi);
++	FW(fecp, hash_table_low, fep->fec.htlo);
++}
++
++static void set_multicast_list(struct net_device *dev)
++{
++	struct dev_mc_list *pmc;
++
++	if ((dev->flags & IFF_PROMISC) == 0) {
++		set_multicast_start(dev);
++		for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
++			set_multicast_one(dev, pmc->dmi_addr);
++		set_multicast_finish(dev);
++	} else
++		set_promiscuous_mode(dev);
++}
++
++static void restart(struct net_device *dev)
++{
++#ifdef CONFIG_DUET
++	immap_t *immap = fs_enet_immap;
++	u32 cptr;
++#endif
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++	const struct fs_platform_info *fpi = fep->fpi;
++	dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
++	int r;
++	u32 addrhi, addrlo;
++
++	r = whack_reset(fep->fec.fecp);
++	if (r != 0)
++		printk(KERN_ERR DRV_MODULE_NAME
++				": %s FEC Reset FAILED!\n", dev->name);
++
++	/*
++	 * Set station address. 
++	 */
++	addrhi = ((u32) dev->dev_addr[0] << 24) |
++		 ((u32) dev->dev_addr[1] << 16) |
++		 ((u32) dev->dev_addr[2] <<  8) |
++		  (u32) dev->dev_addr[3];
++	addrlo = ((u32) dev->dev_addr[4] << 24) |
++		 ((u32) dev->dev_addr[5] << 16);
++	FW(fecp, addr_low, addrhi);
++	FW(fecp, addr_high, addrlo);
++
++	/*
++	 * Reset all multicast. 
++	 */
++	FW(fecp, hash_table_high, fep->fec.hthi);
++	FW(fecp, hash_table_low, fep->fec.htlo);
++
++	/*
++	 * Set maximum receive buffer size. 
++	 */
++	FW(fecp, r_buff_size, PKT_MAXBLR_SIZE);
++	FW(fecp, r_hash, PKT_MAXBUF_SIZE);
++
++	/* get physical address */
++	rx_bd_base_phys = fep->ring_mem_addr;
++	tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring;
++
++	/*
++	 * Set receive and transmit descriptor base. 
++	 */
++	FW(fecp, r_des_start, rx_bd_base_phys);
++	FW(fecp, x_des_start, tx_bd_base_phys);
++
++	fs_init_bds(dev);
++
++	/*
++	 * Enable big endian and don't care about SDMA FC. 
++	 */
++	FW(fecp, fun_code, 0x78000000);
++
++	/*
++	 * Set MII speed. 
++	 */
++	FW(fecp, mii_speed, fep->mii_bus->fec.mii_speed);
++
++	/*
++	 * Clear any outstanding interrupt. 
++	 */
++	FW(fecp, ievent, 0xffc0);
++	FW(fecp, ivec, (fep->interrupt / 2) << 29);
++	
++
++	/*
++	 * adjust to speed (only for DUET & RMII) 
++	 */
++#ifdef CONFIG_DUET
++	if (fpi->use_rmii) {
++		cptr = in_be32(&immap->im_cpm.cp_cptr);
++		switch (fs_get_fec_index(fpi->fs_no)) {
++		case 0:
++			cptr |= 0x100;
++			if (fep->speed == 10)
++				cptr |= 0x0000010;
++			else if (fep->speed == 100)
++				cptr &= ~0x0000010;
++			break;
++		case 1:
++			cptr |= 0x80;
++			if (fep->speed == 10)
++				cptr |= 0x0000008;
++			else if (fep->speed == 100)
++				cptr &= ~0x0000008;
++			break;
++		default:
++			BUG();	/* should never happen */
++			break;
++		}
++		out_be32(&immap->im_cpm.cp_cptr, cptr);
++	}
++#endif
++
++	FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE);	/* MII enable */
++	/*
++	 * adjust to duplex mode 
++	 */
++	if (fep->duplex) {
++		FC(fecp, r_cntrl, FEC_RCNTRL_DRT);
++		FS(fecp, x_cntrl, FEC_TCNTRL_FDEN);	/* FD enable */
++	} else {
++		FS(fecp, r_cntrl, FEC_RCNTRL_DRT);
++		FC(fecp, x_cntrl, FEC_TCNTRL_FDEN);	/* FD disable */
++	}
++
++	/*
++	 * Enable interrupts we wish to service. 
++	 */
++	FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB |
++	   FEC_ENET_RXF | FEC_ENET_RXB);
++
++	/*
++	 * And last, enable the transmit and receive processing. 
++	 */
++	FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
++	FW(fecp, r_des_active, 0x01000000);
++}
++
++static void stop(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++	struct fs_enet_mii_bus *bus = fep->mii_bus;
++	const struct fs_mii_bus_info *bi = bus->bus_info;
++	int i;
++
++	if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0)
++		return;		/* already down */
++
++	FW(fecp, x_cntrl, 0x01);	/* Graceful transmit stop */
++	for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) &&
++	     i < FEC_RESET_DELAY; i++)
++		udelay(1);
++
++	if (i == FEC_RESET_DELAY)
++		printk(KERN_WARNING DRV_MODULE_NAME
++		       ": %s FEC timeout on graceful transmit stop\n",
++		       dev->name);
++	/*
++	 * Disable FEC. Let only MII interrupts. 
++	 */
++	FW(fecp, imask, 0);
++	FC(fecp, ecntrl, FEC_ECNTRL_ETHER_EN);
++
++	fs_cleanup_bds(dev);
++
++	/* shut down FEC1? that's where the mii bus is */
++	if (fep->fec.idx == 0 && bus->refs > 1 && bi->method == fsmii_fec) {
++		FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE);	/* MII enable */
++		FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
++		FW(fecp, ievent, FEC_ENET_MII);
++		FW(fecp, mii_speed, bus->fec.mii_speed);
++	}
++}
++
++static void pre_request_irq(struct net_device *dev, int irq)
++{
++	immap_t *immap = fs_enet_immap;
++	u32 siel;
++
++	/* SIU interrupt */
++	if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) {
++
++		siel = in_be32(&immap->im_siu_conf.sc_siel);
++		if ((irq & 1) == 0)
++			siel |= (0x80000000 >> irq);
++		else
++			siel &= ~(0x80000000 >> (irq & ~1));
++		out_be32(&immap->im_siu_conf.sc_siel, siel);
++	}
++}
++
++static void post_free_irq(struct net_device *dev, int irq)
++{
++	/* nothing */
++}
++
++static void napi_clear_rx_event(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++
++	FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
++}
++
++static void napi_enable_rx(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++
++	FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
++}
++
++static void napi_disable_rx(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++
++	FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
++}
++
++static void rx_bd_done(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++
++	FW(fecp, r_des_active, 0x01000000);
++}
++
++static void tx_kickstart(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++
++	FW(fecp, x_des_active, 0x01000000);
++}
++
++static u32 get_int_events(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++
++	return FR(fecp, ievent) & FR(fecp, imask);
++}
++
++static void clear_int_events(struct net_device *dev, u32 int_events)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	fec_t *fecp = fep->fec.fecp;
++
++	FW(fecp, ievent, int_events);
++}
++
++static void ev_error(struct net_device *dev, u32 int_events)
++{
++	printk(KERN_WARNING DRV_MODULE_NAME
++	       ": %s FEC ERROR(s) 0x%x\n", dev->name, int_events);
++}
++
++int get_regs(struct net_device *dev, void *p, int *sizep)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	if (*sizep < sizeof(fec_t))
++		return -EINVAL;
++
++	memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t));
++
++	return 0;
++}
++
++int get_regs_len(struct net_device *dev)
++{
++	return sizeof(fec_t);
++}
++
++void tx_restart(struct net_device *dev)
++{
++	/* nothing */
++}
++
++/*************************************************************************/
++
++const struct fs_ops fs_fec_ops = {
++	.setup_data		= setup_data,
++	.cleanup_data		= cleanup_data,
++	.set_multicast_list	= set_multicast_list,
++	.restart		= restart,
++	.stop			= stop,
++	.pre_request_irq	= pre_request_irq,
++	.post_free_irq		= post_free_irq,
++	.napi_clear_rx_event	= napi_clear_rx_event,
++	.napi_enable_rx		= napi_enable_rx,
++	.napi_disable_rx	= napi_disable_rx,
++	.rx_bd_done		= rx_bd_done,
++	.tx_kickstart		= tx_kickstart,
++	.get_int_events		= get_int_events,
++	.clear_int_events	= clear_int_events,
++	.ev_error		= ev_error,
++	.get_regs		= get_regs,
++	.get_regs_len		= get_regs_len,
++	.tx_restart		= tx_restart,
++	.allocate_bd		= allocate_bd,
++	.free_bd		= free_bd,
++};
++
++/***********************************************************************/
++
++static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
++{
++	fec_t *fecp = bus->fec.fecp;
++	int i, ret = -1;
++
++	if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
++		BUG();
++
++	/* Add PHY address to register command.  */
++	FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location));
++
++	for (i = 0; i < FEC_MII_LOOPS; i++)
++		if ((FR(fecp, ievent) & FEC_ENET_MII) != 0)
++			break;
++
++	if (i < FEC_MII_LOOPS) {
++		FW(fecp, ievent, FEC_ENET_MII);
++		ret = FR(fecp, mii_data) & 0xffff;
++	}
++
++	return ret;
++}
++
++static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int value)
++{
++	fec_t *fecp = bus->fec.fecp;
++	int i;
++
++	/* this must never happen */
++	if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
++		BUG();
++
++	/* Add PHY address to register command.  */
++	FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value));
++
++	for (i = 0; i < FEC_MII_LOOPS; i++)
++		if ((FR(fecp, ievent) & FEC_ENET_MII) != 0)
++			break;
++
++	if (i < FEC_MII_LOOPS)
++		FW(fecp, ievent, FEC_ENET_MII);
++}
++
++int fs_mii_fec_init(struct fs_enet_mii_bus *bus)
++{
++	bd_t *bd = (bd_t *)__res;
++	const struct fs_mii_bus_info *bi = bus->bus_info;
++	fec_t *fecp;
++
++	if (bi->id != 0)
++		return -1;
++
++	bus->fec.fecp = &((immap_t *)fs_enet_immap)->im_cpm.cp_fec;
++	bus->fec.mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2)
++				& 0x3F) << 1;
++
++	fecp = bus->fec.fecp;
++
++	FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE);	/* MII enable */
++	FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
++	FW(fecp, ievent, FEC_ENET_MII);
++	FW(fecp, mii_speed, bus->fec.mii_speed);
++
++	bus->mii_read = mii_read;
++	bus->mii_write = mii_write;
++
++	return 0;
++}
+diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/mac-scc.c
+@@ -0,0 +1,524 @@
++/*
++ * Ethernet on Serial Communications Controller (SCC) driver for Motorola MPC8xx and MPC82xx.
++ *
++ * Copyright (c) 2003 Intracom S.A. 
++ *  by Pantelis Antoniou <panto at intracom.gr>
++ * 
++ * 2005 (c) MontaVista Software, Inc. 
++ * Vitaly Bordug <vbordug at 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/kernel.h>
++#include <linux/types.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/fs.h>
++
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#ifdef CONFIG_8xx
++#include <asm/8xx_immap.h>
++#include <asm/pgtable.h>
++#include <asm/mpc8xx.h>
++#include <asm/commproc.h>
++#endif
++
++#include "fs_enet.h"
++
++/*************************************************/
++
++#if defined(CONFIG_CPM1)
++/* for a 8xx __raw_xxx's are sufficient */
++#define __fs_out32(addr, x)	__raw_writel(x, addr)
++#define __fs_out16(addr, x)	__raw_writew(x, addr)
++#define __fs_out8(addr, x)	__raw_writeb(x, addr)
++#define __fs_in32(addr)	__raw_readl(addr)
++#define __fs_in16(addr)	__raw_readw(addr)
++#define __fs_in8(addr)	__raw_readb(addr)
++#else
++/* for others play it safe */
++#define __fs_out32(addr, x)	out_be32(addr, x)
++#define __fs_out16(addr, x)	out_be16(addr, x)
++#define __fs_in32(addr)	in_be32(addr)
++#define __fs_in16(addr)	in_be16(addr)
++#endif
++
++/* write, read, set bits, clear bits */
++#define W32(_p, _m, _v) __fs_out32(&(_p)->_m, (_v))
++#define R32(_p, _m)     __fs_in32(&(_p)->_m)
++#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v))
++#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v))
++
++#define W16(_p, _m, _v) __fs_out16(&(_p)->_m, (_v))
++#define R16(_p, _m)     __fs_in16(&(_p)->_m)
++#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v))
++#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v))
++
++#define W8(_p, _m, _v)  __fs_out8(&(_p)->_m, (_v))
++#define R8(_p, _m)      __fs_in8(&(_p)->_m)
++#define S8(_p, _m, _v)  W8(_p, _m, R8(_p, _m) | (_v))
++#define C8(_p, _m, _v)  W8(_p, _m, R8(_p, _m) & ~(_v))
++
++#define SCC_MAX_MULTICAST_ADDRS	64
++
++/*
++ * Delay to wait for SCC reset command to complete (in us) 
++ */
++#define SCC_RESET_DELAY		50
++#define MAX_CR_CMD_LOOPS	10000
++
++static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
++{
++	cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm;
++	u32 v, ch;
++	int i = 0;
++
++	ch = fep->scc.idx << 2;
++	v = mk_cr_cmd(ch, op);
++	W16(cpmp, cp_cpcr, v | CPM_CR_FLG);
++	for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
++		if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
++			break;
++
++	if (i >= MAX_CR_CMD_LOOPS) {
++		printk(KERN_ERR "%s(): Not able to issue CPM command\n",
++			__FUNCTION__);
++		return 1;
++	}
++	return 0;
++}
++
++static int do_pd_setup(struct fs_enet_private *fep)
++{
++	struct platform_device *pdev = to_platform_device(fep->dev);
++	struct resource *r;
++
++	/* Fill out IRQ field */
++	fep->interrupt = platform_get_irq_byname(pdev, "interrupt");
++
++	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
++	fep->scc.sccp = (void *)r->start;
++
++	if (fep->scc.sccp == NULL)
++		return -EINVAL;
++
++	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram");
++	fep->scc.ep = (void *)r->start;
++
++	if (fep->scc.ep == NULL)
++		return -EINVAL;
++
++	return 0;
++}
++
++#define SCC_NAPI_RX_EVENT_MSK	(SCCE_ENET_RXF | SCCE_ENET_RXB)
++#define SCC_RX_EVENT		(SCCE_ENET_RXF)
++#define SCC_TX_EVENT		(SCCE_ENET_TXB)
++#define SCC_ERR_EVENT_MSK	(SCCE_ENET_TXE | SCCE_ENET_BSY)
++
++static int setup_data(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++
++	fep->scc.idx = fs_get_scc_index(fpi->fs_no);
++	if ((unsigned int)fep->fcc.idx > 4)	/* max 4 SCCs */
++		return -EINVAL;
++
++	do_pd_setup(fep);
++
++	fep->scc.hthi = 0;
++	fep->scc.htlo = 0;
++
++	fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK;
++	fep->ev_rx = SCC_RX_EVENT;
++	fep->ev_tx = SCC_TX_EVENT;
++	fep->ev_err = SCC_ERR_EVENT_MSK;
++
++	return 0;
++}
++
++static int allocate_bd(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	const struct fs_platform_info *fpi = fep->fpi;
++
++	fep->ring_mem_addr = cpm_dpalloc((fpi->tx_ring + fpi->rx_ring) *
++					 sizeof(cbd_t), 8);
++	if (IS_DPERR(fep->ring_mem_addr))
++		return -ENOMEM;
++
++	fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr);
++
++	return 0;
++}
++
++static void free_bd(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	if (fep->ring_base)
++		cpm_dpfree(fep->ring_mem_addr);
++}
++
++static void cleanup_data(struct net_device *dev)
++{
++	/* nothing */
++}
++
++static void set_promiscuous_mode(struct net_device *dev)
++{				
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_t *sccp = fep->scc.sccp;
++
++	S16(sccp, scc_psmr, SCC_PSMR_PRO);
++}
++
++static void set_multicast_start(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_enet_t *ep = fep->scc.ep;
++
++	W16(ep, sen_gaddr1, 0);
++	W16(ep, sen_gaddr2, 0);
++	W16(ep, sen_gaddr3, 0);
++	W16(ep, sen_gaddr4, 0);
++}
++
++static void set_multicast_one(struct net_device *dev, const u8 * mac)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_enet_t *ep = fep->scc.ep;
++	u16 taddrh, taddrm, taddrl;
++
++	taddrh = ((u16) mac[5] << 8) | mac[4];
++	taddrm = ((u16) mac[3] << 8) | mac[2];
++	taddrl = ((u16) mac[1] << 8) | mac[0];
++
++	W16(ep, sen_taddrh, taddrh);
++	W16(ep, sen_taddrm, taddrm);
++	W16(ep, sen_taddrl, taddrl);
++	scc_cr_cmd(fep, CPM_CR_SET_GADDR);
++}
++
++static void set_multicast_finish(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_t *sccp = fep->scc.sccp;
++	scc_enet_t *ep = fep->scc.ep;
++
++	/* clear promiscuous always */
++	C16(sccp, scc_psmr, SCC_PSMR_PRO);
++
++	/* if all multi or too many multicasts; just enable all */
++	if ((dev->flags & IFF_ALLMULTI) != 0 ||
++	    dev->mc_count > SCC_MAX_MULTICAST_ADDRS) {
++
++		W16(ep, sen_gaddr1, 0xffff);
++		W16(ep, sen_gaddr2, 0xffff);
++		W16(ep, sen_gaddr3, 0xffff);
++		W16(ep, sen_gaddr4, 0xffff);
++	}
++}
++
++static void set_multicast_list(struct net_device *dev)
++{
++	struct dev_mc_list *pmc;
++
++	if ((dev->flags & IFF_PROMISC) == 0) {
++		set_multicast_start(dev);
++		for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
++			set_multicast_one(dev, pmc->dmi_addr);
++		set_multicast_finish(dev);
++	} else
++		set_promiscuous_mode(dev);
++}
++
++/*
++ * This function is called to start or restart the FEC during a link
++ * change.  This only happens when switching between half and full
++ * duplex.
++ */
++static void restart(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_t *sccp = fep->scc.sccp;
++	scc_enet_t *ep = fep->scc.ep;
++	const struct fs_platform_info *fpi = fep->fpi;
++	u16 paddrh, paddrm, paddrl;
++	const unsigned char *mac;
++	int i;
++
++	C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
++
++	/* clear everything (slow & steady does it) */
++	for (i = 0; i < sizeof(*ep); i++)
++		__fs_out8((char *)ep + i, 0);
++
++	/* point to bds */
++	W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr);
++	W16(ep, sen_genscc.scc_tbase,
++	    fep->ring_mem_addr + sizeof(cbd_t) * fpi->rx_ring);
++
++	/* Initialize function code registers for big-endian.
++	 */
++	W8(ep, sen_genscc.scc_rfcr, SCC_EB);
++	W8(ep, sen_genscc.scc_tfcr, SCC_EB);
++
++	/* Set maximum bytes per receive buffer.
++	 * This appears to be an Ethernet frame size, not the buffer
++	 * fragment size.  It must be a multiple of four.
++	 */
++	W16(ep, sen_genscc.scc_mrblr, 0x5f0);
++
++	/* Set CRC preset and mask.
++	 */
++	W32(ep, sen_cpres, 0xffffffff);
++	W32(ep, sen_cmask, 0xdebb20e3);
++
++	W32(ep, sen_crcec, 0);	/* CRC Error counter */
++	W32(ep, sen_alec, 0);	/* alignment error counter */
++	W32(ep, sen_disfc, 0);	/* discard frame counter */
++
++	W16(ep, sen_pads, 0x8888);	/* Tx short frame pad character */
++	W16(ep, sen_retlim, 15);	/* Retry limit threshold */
++
++	W16(ep, sen_maxflr, 0x5ee);	/* maximum frame length register */
++
++	W16(ep, sen_minflr, PKT_MINBUF_SIZE);	/* minimum frame length register */
++
++	W16(ep, sen_maxd1, 0x000005f0);	/* maximum DMA1 length */
++	W16(ep, sen_maxd2, 0x000005f0);	/* maximum DMA2 length */
++
++	/* Clear hash tables.
++	 */
++	W16(ep, sen_gaddr1, 0);
++	W16(ep, sen_gaddr2, 0);
++	W16(ep, sen_gaddr3, 0);
++	W16(ep, sen_gaddr4, 0);
++	W16(ep, sen_iaddr1, 0);
++	W16(ep, sen_iaddr2, 0);
++	W16(ep, sen_iaddr3, 0);
++	W16(ep, sen_iaddr4, 0);
++
++	/* set address 
++	 */
++	mac = dev->dev_addr;
++	paddrh = ((u16) mac[5] << 8) | mac[4];
++	paddrm = ((u16) mac[3] << 8) | mac[2];
++	paddrl = ((u16) mac[1] << 8) | mac[0];
++
++	W16(ep, sen_paddrh, paddrh);
++	W16(ep, sen_paddrm, paddrm);
++	W16(ep, sen_paddrl, paddrl);
++
++	W16(ep, sen_pper, 0);
++	W16(ep, sen_taddrl, 0);
++	W16(ep, sen_taddrm, 0);
++	W16(ep, sen_taddrh, 0);
++
++	fs_init_bds(dev);
++
++	scc_cr_cmd(fep, CPM_CR_INIT_TRX);
++
++	W16(sccp, scc_scce, 0xffff);
++
++	/* Enable interrupts we wish to service. 
++	 */
++	W16(sccp, scc_sccm, SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);
++
++	/* Set GSMR_H to enable all normal operating modes.
++	 * Set GSMR_L to enable Ethernet to MC68160.
++	 */
++	W32(sccp, scc_gsmrh, 0);
++	W32(sccp, scc_gsmrl,
++	    SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 |
++	    SCC_GSMRL_MODE_ENET);
++
++	/* Set sync/delimiters.
++	 */
++	W16(sccp, scc_dsr, 0xd555);
++
++	/* Set processing mode.  Use Ethernet CRC, catch broadcast, and
++	 * start frame search 22 bit times after RENA.
++	 */
++	W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22);
++
++	/* Set full duplex mode if needed */
++	if (fep->duplex)
++		S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE);
++
++	S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
++}
++
++static void stop(struct net_device *dev)	
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_t *sccp = fep->scc.sccp;
++	int i;
++
++	for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++)
++		udelay(1);
++
++	if (i == SCC_RESET_DELAY)
++		printk(KERN_WARNING DRV_MODULE_NAME
++		       ": %s SCC timeout on graceful transmit stop\n",
++		       dev->name);
++
++	W16(sccp, scc_sccm, 0);
++	C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
++
++	fs_cleanup_bds(dev);
++}
++
++static void pre_request_irq(struct net_device *dev, int irq)
++{
++	immap_t *immap = fs_enet_immap;
++	u32 siel;
++
++	/* SIU interrupt */
++	if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) {
++
++		siel = in_be32(&immap->im_siu_conf.sc_siel);
++		if ((irq & 1) == 0)
++			siel |= (0x80000000 >> irq);
++		else
++			siel &= ~(0x80000000 >> (irq & ~1));
++		out_be32(&immap->im_siu_conf.sc_siel, siel);
++	}
++}
++
++static void post_free_irq(struct net_device *dev, int irq)
++{
++	/* nothing */
++}
++
++static void napi_clear_rx_event(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_t *sccp = fep->scc.sccp;
++
++	W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK);
++}
++
++static void napi_enable_rx(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_t *sccp = fep->scc.sccp;
++
++	S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
++}
++
++static void napi_disable_rx(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_t *sccp = fep->scc.sccp;
++
++	C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
++}
++
++static void rx_bd_done(struct net_device *dev)
++{
++	/* nothing */
++}
++
++static void tx_kickstart(struct net_device *dev)
++{
++	/* nothing */
++}
++
++static u32 get_int_events(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_t *sccp = fep->scc.sccp;
++
++	return (u32) R16(sccp, scc_scce);
++}
++
++static void clear_int_events(struct net_device *dev, u32 int_events)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++	scc_t *sccp = fep->scc.sccp;
++
++	W16(sccp, scc_scce, int_events & 0xffff);
++}
++
++static void ev_error(struct net_device *dev, u32 int_events)
++{
++	printk(KERN_WARNING DRV_MODULE_NAME
++	       ": %s SCC ERROR(s) 0x%x\n", dev->name, int_events);
++}
++
++static int get_regs(struct net_device *dev, void *p, int *sizep)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t))
++		return -EINVAL;
++
++	memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t));
++	p = (char *)p + sizeof(scc_t);
++
++	memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t));
++
++	return 0;
++}
++
++static int get_regs_len(struct net_device *dev)
++{
++	return sizeof(scc_t) + sizeof(scc_enet_t);
++}
++
++static void tx_restart(struct net_device *dev)
++{
++	struct fs_enet_private *fep = netdev_priv(dev);
++
++	scc_cr_cmd(fep, CPM_CR_RESTART_TX);
++}
++
++/*************************************************************************/
++
++const struct fs_ops fs_scc_ops = {
++	.setup_data		= setup_data,
++	.cleanup_data		= cleanup_data,
++	.set_multicast_list	= set_multicast_list,
++	.restart		= restart,
++	.stop			= stop,
++	.pre_request_irq	= pre_request_irq,
++	.post_free_irq		= post_free_irq,
++	.napi_clear_rx_event	= napi_clear_rx_event,
++	.napi_enable_rx		= napi_enable_rx,
++	.napi_disable_rx	= napi_disable_rx,
++	.rx_bd_done		= rx_bd_done,
++	.tx_kickstart		= tx_kickstart,
++	.get_int_events		= get_int_events,
++	.clear_int_events	= clear_int_events,
++	.ev_error		= ev_error,
++	.get_regs		= get_regs,
++	.get_regs_len		= get_regs_len,
++	.tx_restart		= tx_restart,
++	.allocate_bd		= allocate_bd,
++	.free_bd		= free_bd,
++};
+diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/mii-bitbang.c
+@@ -0,0 +1,405 @@
++/*
++ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
++ *
++ * Copyright (c) 2003 Intracom S.A. 
++ *  by Pantelis Antoniou <panto at intracom.gr>
++ * 
++ * 2005 (c) MontaVista Software, Inc. 
++ * Vitaly Bordug <vbordug at 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 <asm/pgtable.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#include "fs_enet.h"
++
++#ifdef CONFIG_8xx
++static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit)
++{
++	immap_t *im = (immap_t *)fs_enet_immap;
++	void *dir, *dat, *ppar;
++	int adv;
++	u8 msk;
++
++	switch (port) {
++		case fsiop_porta:
++			dir = &im->im_ioport.iop_padir;
++			dat = &im->im_ioport.iop_padat;
++			ppar = &im->im_ioport.iop_papar;
++			break;
++
++		case fsiop_portb:
++			dir = &im->im_cpm.cp_pbdir;
++			dat = &im->im_cpm.cp_pbdat;
++			ppar = &im->im_cpm.cp_pbpar;
++			break;
++
++		case fsiop_portc:
++			dir = &im->im_ioport.iop_pcdir;
++			dat = &im->im_ioport.iop_pcdat;
++			ppar = &im->im_ioport.iop_pcpar;
++			break;
++
++		case fsiop_portd:
++			dir = &im->im_ioport.iop_pddir;
++			dat = &im->im_ioport.iop_pddat;
++			ppar = &im->im_ioport.iop_pdpar;
++			break;
++
++		case fsiop_porte:
++			dir = &im->im_cpm.cp_pedir;
++			dat = &im->im_cpm.cp_pedat;
++			ppar = &im->im_cpm.cp_pepar;
++			break;
++
++		default:
++			printk(KERN_ERR DRV_MODULE_NAME
++			       "Illegal port value %d!\n", port);
++			return -EINVAL;
++	}
++
++	adv = bit >> 3;
++	dir = (char *)dir + adv;
++	dat = (char *)dat + adv;
++	ppar = (char *)ppar + adv;
++
++	msk = 1 << (7 - (bit & 7));
++	if ((in_8(ppar) & msk) != 0) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       "pin %d on port %d is not general purpose!\n", bit, port);
++		return -EINVAL;
++	}
++
++	*dirp = dir;
++	*datp = dat;
++	*mskp = msk;
++
++	return 0;
++}
++#endif
++
++#ifdef CONFIG_8260
++static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit)
++{
++	iop_cpm2_t *io = &((cpm2_map_t *)fs_enet_immap)->im_ioport;
++	void *dir, *dat, *ppar;
++	int adv;
++	u8 msk;
++
++	switch (port) {
++		case fsiop_porta:
++			dir = &io->iop_pdira;
++			dat = &io->iop_pdata;
++			ppar = &io->iop_ppara;
++			break;
++
++		case fsiop_portb:
++			dir = &io->iop_pdirb;
++			dat = &io->iop_pdatb;
++			ppar = &io->iop_pparb;
++			break;
++
++		case fsiop_portc:
++			dir = &io->iop_pdirc;
++			dat = &io->iop_pdatc;
++			ppar = &io->iop_pparc;
++			break;
++
++		case fsiop_portd:
++			dir = &io->iop_pdird;
++			dat = &io->iop_pdatd;
++			ppar = &io->iop_ppard;
++			break;
++
++		default:
++			printk(KERN_ERR DRV_MODULE_NAME
++			       "Illegal port value %d!\n", port);
++			return -EINVAL;
++	}
++
++	adv = bit >> 3;
++	dir = (char *)dir + adv;
++	dat = (char *)dat + adv;
++	ppar = (char *)ppar + adv;
++
++	msk = 1 << (7 - (bit & 7));
++	if ((in_8(ppar) & msk) != 0) {
++		printk(KERN_ERR DRV_MODULE_NAME
++		       "pin %d on port %d is not general purpose!\n", bit, port);
++		return -EINVAL;
++	}
++
++	*dirp = dir;
++	*datp = dat;
++	*mskp = msk;
++
++	return 0;
++}
++#endif
++
++static inline void bb_set(u8 *p, u8 m)
++{
++	out_8(p, in_8(p) | m);
++}
++
++static inline void bb_clr(u8 *p, u8 m)
++{
++	out_8(p, in_8(p) & ~m);
++}
++
++static inline int bb_read(u8 *p, u8 m)
++{
++	return (in_8(p) & m) != 0;
++}
++
++static inline void mdio_active(struct fs_enet_mii_bus *bus)
++{
++	bb_set(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk);
++}
++
++static inline void mdio_tristate(struct fs_enet_mii_bus *bus)
++{
++	bb_clr(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk);
++}
++
++static inline int mdio_read(struct fs_enet_mii_bus *bus)
++{
++	return bb_read(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
++}
++
++static inline void mdio(struct fs_enet_mii_bus *bus, int what)
++{
++	if (what)
++		bb_set(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
++	else
++		bb_clr(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
++}
++
++static inline void mdc(struct fs_enet_mii_bus *bus, int what)
++{
++	if (what)
++		bb_set(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk);
++	else
++		bb_clr(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk);
++}
++
++static inline void mii_delay(struct fs_enet_mii_bus *bus)
++{
++	udelay(bus->bus_info->i.bitbang.delay);
++}
++
++/* Utility to send the preamble, address, and register (common to read and write). */
++static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg)
++{
++	int j;
++
++	/*
++	 * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
++	 * The IEEE spec says this is a PHY optional requirement.  The AMD
++	 * 79C874 requires one after power up and one after a MII communications
++	 * error.  This means that we are doing more preambles than we need,
++	 * but it is safer and will be much more robust.
++	 */
++
++	mdio_active(bus);
++	mdio(bus, 1);
++	for (j = 0; j < 32; j++) {
++		mdc(bus, 0);
++		mii_delay(bus);
++		mdc(bus, 1);
++		mii_delay(bus);
++	}
++
++	/* send the start bit (01) and the read opcode (10) or write (10) */
++	mdc(bus, 0);
++	mdio(bus, 0);
++	mii_delay(bus);
++	mdc(bus, 1);
++	mii_delay(bus);
++	mdc(bus, 0);
++	mdio(bus, 1);
++	mii_delay(bus);
++	mdc(bus, 1);
++	mii_delay(bus);
++	mdc(bus, 0);
++	mdio(bus, read);
++	mii_delay(bus);
++	mdc(bus, 1);
++	mii_delay(bus);
++	mdc(bus, 0);
++	mdio(bus, !read);
++	mii_delay(bus);
++	mdc(bus, 1);
++	mii_delay(bus);
++
++	/* send the PHY address */
++	for (j = 0; j < 5; j++) {
++		mdc(bus, 0);
++		mdio(bus, (addr & 0x10) != 0);
++		mii_delay(bus);
++		mdc(bus, 1);
++		mii_delay(bus);
++		addr <<= 1;
++	}
++
++	/* send the register address */
++	for (j = 0; j < 5; j++) {
++		mdc(bus, 0);
++		mdio(bus, (reg & 0x10) != 0);
++		mii_delay(bus);
++		mdc(bus, 1);
++		mii_delay(bus);
++		reg <<= 1;
++	}
++}
++
++static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
++{
++	u16 rdreg;
++	int ret, j;
++	u8 addr = phy_id & 0xff;
++	u8 reg = location & 0xff;
++
++	bitbang_pre(bus, 1, addr, reg);
++
++	/* tri-state our MDIO I/O pin so we can read */
++	mdc(bus, 0);
++	mdio_tristate(bus);
++	mii_delay(bus);
++	mdc(bus, 1);
++	mii_delay(bus);
++
++	/* check the turnaround bit: the PHY should be driving it to zero */
++	if (mdio_read(bus) != 0) {
++		/* PHY didn't drive TA low */
++		for (j = 0; j < 32; j++) {
++			mdc(bus, 0);
++			mii_delay(bus);
++			mdc(bus, 1);
++			mii_delay(bus);
++		}
++		ret = -1;
++		goto out;
++	}
++
++	mdc(bus, 0);
++	mii_delay(bus);
++
++	/* read 16 bits of register data, MSB first */
++	rdreg = 0;
++	for (j = 0; j < 16; j++) {
++		mdc(bus, 1);
++		mii_delay(bus);
++		rdreg <<= 1;
++		rdreg |= mdio_read(bus);
++		mdc(bus, 0);
++		mii_delay(bus);
++	}
++
++	mdc(bus, 1);
++	mii_delay(bus);
++	mdc(bus, 0);
++	mii_delay(bus);
++	mdc(bus, 1);
++	mii_delay(bus);
++
++	ret = rdreg;
++out:
++	return ret;
++}
++
++static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val)
++{
++	int j;
++	u8 addr = phy_id & 0xff;
++	u8 reg = location & 0xff;
++	u16 value = val & 0xffff;
++
++	bitbang_pre(bus, 0, addr, reg);
++
++	/* send the turnaround (10) */
++	mdc(bus, 0);
++	mdio(bus, 1);
++	mii_delay(bus);
++	mdc(bus, 1);
++	mii_delay(bus);
++	mdc(bus, 0);
++	mdio(bus, 0);
++	mii_delay(bus);
++	mdc(bus, 1);
++	mii_delay(bus);
++
++	/* write 16 bits of register data, MSB first */
++	for (j = 0; j < 16; j++) {
++		mdc(bus, 0);
++		mdio(bus, (value & 0x8000) != 0);
++		mii_delay(bus);
++		mdc(bus, 1);
++		mii_delay(bus);
++		value <<= 1;
++	}
++
++	/*
++	 * Tri-state the MDIO line.
++	 */
++	mdio_tristate(bus);
++	mdc(bus, 0);
++	mii_delay(bus);
++	mdc(bus, 1);
++	mii_delay(bus);
++}
++
++int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus)
++{
++	const struct fs_mii_bus_info *bi = bus->bus_info;
++	int r;
++
++	r = bitbang_prep_bit(&bus->bitbang.mdio_dir,
++			 &bus->bitbang.mdio_dat,
++			 &bus->bitbang.mdio_msk,
++			 bi->i.bitbang.mdio_port,
++			 bi->i.bitbang.mdio_bit);
++	if (r != 0)
++		return r;
++
++	r = bitbang_prep_bit(&bus->bitbang.mdc_dir,
++			 &bus->bitbang.mdc_dat,
++			 &bus->bitbang.mdc_msk,
++			 bi->i.bitbang.mdc_port,
++			 bi->i.bitbang.mdc_bit);
++	if (r != 0)
++		return r;
++
++	bus->mii_read = mii_read;
++	bus->mii_write = mii_write;
++
++	return 0;
++}
+diff --git a/drivers/net/fs_enet/mii-fixed.c b/drivers/net/fs_enet/mii-fixed.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/fs_enet/mii-fixed.c
+@@ -0,0 +1,92 @@
++/*
++ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
++ *
++ * Copyright (c) 2003 Intracom S.A. 
++ *  by Pantelis Antoniou <panto at intracom.gr>
++ * 
++ * 2005 (c) MontaVista Software, Inc. 
++ * Vitaly Bordug <vbordug at 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 <asm/pgtable.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#include "fs_enet.h"
++
++static const u16 mii_regs[7] = {
++	0x3100,
++	0x786d,
++	0x0fff,
++	0x0fff,
++	0x01e1,
++	0x45e1,
++	0x0003,
++};
++
++static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
++{
++	int ret = 0;
++
++	if ((unsigned int)location >= ARRAY_SIZE(mii_regs))
++		return -1;
++
++	if (location != 5)
++		ret = mii_regs[location];
++	else
++		ret = bus->fixed.lpa;
++
++	return ret;
++}
++
++static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val)
++{
++	/* do nothing */
++}
++
++int fs_mii_fixed_init(struct fs_enet_mii_bus *bus)
++{
++	const struct fs_mii_bus_info *bi = bus->bus_info;
++
++	bus->fixed.lpa = 0x45e1;	/* default 100Mb, full duplex */
++
++	/* if speed is fixed at 10Mb, remove 100Mb modes */
++	if (bi->i.fixed.speed == 10)
++		bus->fixed.lpa &= ~LPA_100;
++
++	/* if duplex is half, remove full duplex modes */
++	if (bi->i.fixed.duplex == 0)
++		bus->fixed.lpa &= ~LPA_DUPLEX;
++
++	bus->mii_read = mii_read;
++	bus->mii_write = mii_write;
++
++	return 0;
++}
+diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
+--- a/drivers/net/gianfar.c
++++ b/drivers/net/gianfar.c
+@@ -29,12 +29,7 @@
+  *  define the configuration needed by the board are defined in a
+  *  board structure in arch/ppc/platforms (though I do not
+  *  discount the possibility that other architectures could one
+- *  day be supported.  One assumption the driver currently makes
+- *  is that the PHY is configured in such a way to advertise all
+- *  capabilities.  This is a sensible default, and on certain
+- *  PHYs, changing this default encounters substantial errata
+- *  issues.  Future versions may remove this requirement, but for
+- *  now, it is best for the firmware to ensure this is the case.
++ *  day be supported.
+  *
+  *  The Gianfar Ethernet Controller uses a ring of buffer
+  *  descriptors.  The beginning is indicated by a register
+@@ -47,7 +42,7 @@
+  *  corresponding bit in the IMASK register is also set (if
+  *  interrupt coalescing is active, then the interrupt may not
+  *  happen immediately, but will wait until either a set number
+- *  of frames or amount of time have passed.).  In NAPI, the
++ *  of frames or amount of time have passed).  In NAPI, the
+  *  interrupt handler will signal there is work to be done, and
+  *  exit.  Without NAPI, the packet(s) will be handled
+  *  immediately.  Both methods will start at the last known empty
+@@ -75,6 +70,7 @@
+ #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>
+@@ -85,7 +81,7 @@
+ #include <linux/if_vlan.h>
+ #include <linux/spinlock.h>
+ #include <linux/mm.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/ip.h>
+ #include <linux/tcp.h>
+ #include <linux/udp.h>
+@@ -97,9 +93,11 @@
+ #include <linux/version.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/crc32.h>
++#include <linux/mii.h>
++#include <linux/phy.h>
+ 
+ #include "gianfar.h"
+-#include "gianfar_phy.h"
++#include "gianfar_mii.h"
+ 
+ #define TX_TIMEOUT      (1*HZ)
+ #define SKB_ALLOC_TIMEOUT 1000000
+@@ -113,9 +111,8 @@
+ #endif
+ 
+ const char gfar_driver_name[] = "Gianfar Ethernet";
+-const char gfar_driver_version[] = "1.1";
++const char gfar_driver_version[] = "1.2";
+ 
+-int startup_gfar(struct net_device *dev);
+ static int gfar_enet_open(struct net_device *dev);
+ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ static void gfar_timeout(struct net_device *dev);
+@@ -126,17 +123,13 @@ static int gfar_set_mac_address(struct n
+ static int gfar_change_mtu(struct net_device *dev, int new_mtu);
+ static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs);
+ static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs);
+-static irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
+ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+-static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+-static void gfar_phy_change(void *data);
+-static void gfar_phy_timer(unsigned long data);
+ static void adjust_link(struct net_device *dev);
+ static void init_registers(struct net_device *dev);
+ static int init_phy(struct net_device *dev);
+ static int gfar_probe(struct device *device);
+ static int gfar_remove(struct device *device);
+-void free_skb_resources(struct gfar_private *priv);
++static void free_skb_resources(struct gfar_private *priv);
+ static void gfar_set_multi(struct net_device *dev);
+ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
+ #ifdef CONFIG_GFAR_NAPI
+@@ -144,7 +137,6 @@ static int gfar_poll(struct net_device *
+ #endif
+ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
+ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
+-static void gfar_phy_startup_timer(unsigned long data);
+ static void gfar_vlan_rx_register(struct net_device *netdev,
+ 		                struct vlan_group *grp);
+ static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
+@@ -162,6 +154,9 @@ int gfar_uses_fcb(struct gfar_private *p
+ 	else
+ 		return 0;
+ }
++
++/* Set up the ethernet device structure, private data,
++ * and anything else we need before we start */
+ static int gfar_probe(struct device *device)
+ {
+ 	u32 tempval;
+@@ -175,7 +170,7 @@ static int gfar_probe(struct device *dev
+ 
+ 	einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
+ 
+-	if (einfo == NULL) {
++	if (NULL == einfo) {
+ 		printk(KERN_ERR "gfar %d: Missing additional data!\n",
+ 		       pdev->id);
+ 
+@@ -185,7 +180,7 @@ static int gfar_probe(struct device *dev
+ 	/* Create an ethernet device instance */
+ 	dev = alloc_etherdev(sizeof (*priv));
+ 
+-	if (dev == NULL)
++	if (NULL == dev)
+ 		return -ENOMEM;
+ 
+ 	priv = netdev_priv(dev);
+@@ -207,20 +202,11 @@ static int gfar_probe(struct device *dev
+ 	priv->regs = (struct gfar *)
+ 		ioremap(r->start, sizeof (struct gfar));
+ 
+-	if (priv->regs == NULL) {
++	if (NULL == priv->regs) {
+ 		err = -ENOMEM;
+ 		goto regs_fail;
+ 	}
+ 
+-	/* Set the PHY base address */
+-	priv->phyregs = (struct gfar *)
+-	    ioremap(einfo->phy_reg_addr, sizeof (struct gfar));
+-
+-	if (priv->phyregs == NULL) {
+-		err = -ENOMEM;
+-		goto phy_regs_fail;
+-	}
+-
+ 	spin_lock_init(&priv->lock);
+ 
+ 	dev_set_drvdata(device, dev);
+@@ -386,12 +372,10 @@ static int gfar_probe(struct device *dev
+ 	return 0;
+ 
+ register_fail:
+-	iounmap((void *) priv->phyregs);
+-phy_regs_fail:
+ 	iounmap((void *) priv->regs);
+ regs_fail:
+ 	free_netdev(dev);
+-	return -ENOMEM;
++	return err;
+ }
+ 
+ static int gfar_remove(struct device *device)
+@@ -402,108 +386,41 @@ static int gfar_remove(struct device *de
+ 	dev_set_drvdata(device, NULL);
+ 
+ 	iounmap((void *) priv->regs);
+-	iounmap((void *) priv->phyregs);
+ 	free_netdev(dev);
+ 
+ 	return 0;
+ }
+ 
+ 
+-/* Configure the PHY for dev.
+- * returns 0 if success.  -1 if failure
++/* Initializes driver's PHY state, and attaches to the PHY.
++ * Returns 0 on success.
+  */
+ static int init_phy(struct net_device *dev)
+ {
+ 	struct gfar_private *priv = netdev_priv(dev);
+-	struct phy_info *curphy;
+-	unsigned int timeout = PHY_INIT_TIMEOUT;
+-	struct gfar *phyregs = priv->phyregs;
+-	struct gfar_mii_info *mii_info;
+-	int err;
++	uint gigabit_support =
++		priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
++		SUPPORTED_1000baseT_Full : 0;
++	struct phy_device *phydev;
+ 
+ 	priv->oldlink = 0;
+ 	priv->oldspeed = 0;
+ 	priv->oldduplex = -1;
+ 
+-	mii_info = kmalloc(sizeof(struct gfar_mii_info),
+-			GFP_KERNEL);
+-
+-	if(NULL == mii_info) {
+-		if (netif_msg_ifup(priv))
+-			printk(KERN_ERR "%s: Could not allocate mii_info\n",
+-					dev->name);
+-		return -ENOMEM;
+-	}
+-
+-	mii_info->speed = SPEED_1000;
+-	mii_info->duplex = DUPLEX_FULL;
+-	mii_info->pause = 0;
+-	mii_info->link = 1;
+-
+-	mii_info->advertising = (ADVERTISED_10baseT_Half |
+-			ADVERTISED_10baseT_Full |
+-			ADVERTISED_100baseT_Half |
+-			ADVERTISED_100baseT_Full |
+-			ADVERTISED_1000baseT_Full);
+-	mii_info->autoneg = 1;
++	phydev = phy_connect(dev, priv->einfo->bus_id, &adjust_link, 0);
+ 
+-	spin_lock_init(&mii_info->mdio_lock);
+-
+-	mii_info->mii_id = priv->einfo->phyid;
+-
+-	mii_info->dev = dev;
+-
+-	mii_info->mdio_read = &read_phy_reg;
+-	mii_info->mdio_write = &write_phy_reg;
+-
+-	priv->mii_info = mii_info;
+-
+-	/* Reset the management interface */
+-	gfar_write(&phyregs->miimcfg, MIIMCFG_RESET);
+-
+-	/* Setup the MII Mgmt clock speed */
+-	gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE);
+-
+-	/* Wait until the bus is free */
+-	while ((gfar_read(&phyregs->miimind) & MIIMIND_BUSY) &&
+-			timeout--)
+-		cpu_relax();
+-
+-	if(timeout <= 0) {
+-		printk(KERN_ERR "%s: The MII Bus is stuck!\n",
+-				dev->name);
+-		err = -1;
+-		goto bus_fail;
+-	}
+-
+-	/* get info for this PHY */
+-	curphy = get_phy_info(priv->mii_info);
+-
+-	if (curphy == NULL) {
+-		if (netif_msg_ifup(priv))
+-			printk(KERN_ERR "%s: No PHY found\n", dev->name);
+-		err = -1;
+-		goto no_phy;
++	if (IS_ERR(phydev)) {
++		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
++		return PTR_ERR(phydev);
+ 	}
+ 
+-	mii_info->phyinfo = curphy;
++	/* Remove any features not supported by the controller */
++	phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
++	phydev->advertising = phydev->supported;
+ 
+-	/* Run the commands which initialize the PHY */
+-	if(curphy->init) {
+-		err = curphy->init(priv->mii_info);
+-
+-		if (err)
+-			goto phy_init_fail;
+-	}
++	priv->phydev = phydev;
+ 
+ 	return 0;
+-
+-phy_init_fail:
+-no_phy:
+-bus_fail:
+-	kfree(mii_info);
+-
+-	return err;
+ }
+ 
+ static void init_registers(struct net_device *dev)
+@@ -603,24 +520,13 @@ void stop_gfar(struct net_device *dev)
+ 	struct gfar *regs = priv->regs;
+ 	unsigned long flags;
+ 
++	phy_stop(priv->phydev);
++
+ 	/* Lock it down */
+ 	spin_lock_irqsave(&priv->lock, flags);
+ 
+-	/* Tell the kernel the link is down */
+-	priv->mii_info->link = 0;
+-	adjust_link(dev);
+-
+ 	gfar_halt(dev);
+ 
+-	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
+-		/* Clear any pending interrupts */
+-		mii_clear_phy_interrupt(priv->mii_info);
+-
+-		/* Disable PHY Interrupts */
+-		mii_configure_phy_interrupt(priv->mii_info,
+-				MII_INTERRUPT_DISABLED);
+-	}
+-
+ 	spin_unlock_irqrestore(&priv->lock, flags);
+ 
+ 	/* Free the IRQs */
+@@ -629,13 +535,7 @@ void stop_gfar(struct net_device *dev)
+ 		free_irq(priv->interruptTransmit, dev);
+ 		free_irq(priv->interruptReceive, dev);
+ 	} else {
+-		free_irq(priv->interruptTransmit, dev);
+-	}
+-
+-	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
+-		free_irq(priv->einfo->interruptPHY, dev);
+-	} else {
+-		del_timer_sync(&priv->phy_info_timer);
++ 		free_irq(priv->interruptTransmit, dev);
+ 	}
+ 
+ 	free_skb_resources(priv);
+@@ -649,7 +549,7 @@ void stop_gfar(struct net_device *dev)
+ 
+ /* If there are any tx skbs or rx skbs still around, free them.
+  * Then free tx_skbuff and rx_skbuff */
+-void free_skb_resources(struct gfar_private *priv)
++static void free_skb_resources(struct gfar_private *priv)
+ {
+ 	struct rxbd8 *rxbdp;
+ 	struct txbd8 *txbdp;
+@@ -770,7 +670,7 @@ int startup_gfar(struct net_device *dev)
+ 	    (struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
+ 					priv->tx_ring_size, GFP_KERNEL);
+ 
+-	if (priv->tx_skbuff == NULL) {
++	if (NULL == priv->tx_skbuff) {
+ 		if (netif_msg_ifup(priv))
+ 			printk(KERN_ERR "%s: Could not allocate tx_skbuff\n",
+ 					dev->name);
+@@ -785,7 +685,7 @@ int startup_gfar(struct net_device *dev)
+ 	    (struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
+ 					priv->rx_ring_size, GFP_KERNEL);
+ 
+-	if (priv->rx_skbuff == NULL) {
++	if (NULL == priv->rx_skbuff) {
+ 		if (netif_msg_ifup(priv))
+ 			printk(KERN_ERR "%s: Could not allocate rx_skbuff\n",
+ 					dev->name);
+@@ -879,13 +779,7 @@ int startup_gfar(struct net_device *dev)
+ 		}
+ 	}
+ 
+-	/* Set up the PHY change work queue */
+-	INIT_WORK(&priv->tq, gfar_phy_change, dev);
+-
+-	init_timer(&priv->phy_info_timer);
+-	priv->phy_info_timer.function = &gfar_phy_startup_timer;
+-	priv->phy_info_timer.data = (unsigned long) priv->mii_info;
+-	mod_timer(&priv->phy_info_timer, jiffies + HZ);
++	phy_start(priv->phydev);
+ 
+ 	/* Configure the coalescing support */
+ 	if (priv->txcoalescing)
+@@ -933,11 +827,6 @@ tx_skb_fail:
+ 			priv->tx_bd_base,
+ 			gfar_read(&regs->tbase0));
+ 
+-	if (priv->mii_info->phyinfo->close)
+-		priv->mii_info->phyinfo->close(priv->mii_info);
+-
+-	kfree(priv->mii_info);
+-
+ 	return err;
+ }
+ 
+@@ -1035,7 +924,7 @@ static int gfar_start_xmit(struct sk_buf
+ 	txbdp->status &= TXBD_WRAP;
+ 
+ 	/* Set up checksumming */
+-	if ((dev->features & NETIF_F_IP_CSUM) 
++	if ((dev->features & NETIF_F_IP_CSUM)
+ 			&& (CHECKSUM_HW == skb->ip_summed)) {
+ 		fcb = gfar_add_fcb(skb, txbdp);
+ 		gfar_tx_checksum(skb, fcb);
+@@ -1103,11 +992,9 @@ static int gfar_close(struct net_device 
+ 	struct gfar_private *priv = netdev_priv(dev);
+ 	stop_gfar(dev);
+ 
+-	/* Shutdown the PHY */
+-	if (priv->mii_info->phyinfo->close)
+-		priv->mii_info->phyinfo->close(priv->mii_info);
+-
+-	kfree(priv->mii_info);
++	/* Disconnect from the PHY */
++	phy_disconnect(priv->phydev);
++	priv->phydev = NULL;
+ 
+ 	netif_stop_queue(dev);
+ 
+@@ -1343,7 +1230,7 @@ struct sk_buff * gfar_new_skb(struct net
+ 	while ((!skb) && timeout--)
+ 		skb = dev_alloc_skb(priv->rx_buffer_size + RXBUF_ALIGNMENT);
+ 
+-	if (skb == NULL)
++	if (NULL == skb)
+ 		return NULL;
+ 
+ 	/* We need the data buffer to be aligned properly.  We will reserve
+@@ -1490,7 +1377,7 @@ static int gfar_process_frame(struct net
+ 	struct gfar_private *priv = netdev_priv(dev);
+ 	struct rxfcb *fcb = NULL;
+ 
+-	if (skb == NULL) {
++	if (NULL == skb) {
+ 		if (netif_msg_rx_err(priv))
+ 			printk(KERN_WARNING "%s: Missing skb!!.\n", dev->name);
+ 		priv->stats.rx_dropped++;
+@@ -1718,131 +1605,9 @@ static irqreturn_t gfar_interrupt(int ir
+ 	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;
+-	struct gfar_private *priv = netdev_priv(dev);
+-
+-	/* Clear the interrupt */
+-	mii_clear_phy_interrupt(priv->mii_info);
+-
+-	/* Disable PHY interrupts */
+-	mii_configure_phy_interrupt(priv->mii_info,
+-			MII_INTERRUPT_DISABLED);
+-
+-	/* Schedule the phy change */
+-	schedule_work(&priv->tq);
+-
+-	return IRQ_HANDLED;
+-}
+-
+-/* Scheduled by the phy_interrupt/timer to handle PHY changes */
+-static void gfar_phy_change(void *data)
+-{
+-	struct net_device *dev = (struct net_device *) data;
+-	struct gfar_private *priv = netdev_priv(dev);
+-	int result = 0;
+-
+-	/* Delay to give the PHY a chance to change the
+-	 * register state */
+-	msleep(1);
+-
+-	/* Update the link, speed, duplex */
+-	result = priv->mii_info->phyinfo->read_status(priv->mii_info);
+-
+-	/* Adjust the known status as long as the link
+-	 * isn't still coming up */
+-	if((0 == result) || (priv->mii_info->link == 0))
+-		adjust_link(dev);
+-
+-	/* Reenable interrupts, if needed */
+-	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR)
+-		mii_configure_phy_interrupt(priv->mii_info,
+-				MII_INTERRUPT_ENABLED);
+-}
+-
+-/* Called every so often on systems that don't interrupt
+- * the core for PHY changes */
+-static void gfar_phy_timer(unsigned long data)
+-{
+-	struct net_device *dev = (struct net_device *) data;
+-	struct gfar_private *priv = netdev_priv(dev);
+-
+-	schedule_work(&priv->tq);
+-
+-	mod_timer(&priv->phy_info_timer, jiffies +
+-			GFAR_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 gfar_phy_timer to check status */
+-static void gfar_phy_startup_timer(unsigned long data)
+-{
+-	int result;
+-	static int secondary = GFAR_AN_TIMEOUT;
+-	struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
+-	struct gfar_private *priv = netdev_priv(mii_info->dev);
+-
+-	/* 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(&priv->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) {
+-			if (netif_msg_link(priv))
+-				printk(KERN_ERR "%s: Forcing failed!\n",
+-						mii_info->dev->name);
+-			return;
+-		}
+-	}
+-
+-	/* Kill the timer so it can be restarted */
+-	del_timer_sync(&priv->phy_info_timer);
+-
+-	/* Grab the PHY interrupt, if necessary/possible */
+-	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
+-		if (request_irq(priv->einfo->interruptPHY,
+-					phy_interrupt,
+-					SA_SHIRQ,
+-					"phy_interrupt",
+-					mii_info->dev) < 0) {
+-			if (netif_msg_intr(priv))
+-				printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n",
+-						mii_info->dev->name,
+-					priv->einfo->interruptPHY);
+-		} else {
+-			mii_configure_phy_interrupt(priv->mii_info,
+-					MII_INTERRUPT_ENABLED);
+-			return;
+-		}
+-	}
+-
+-	/* Start the timer again, this time in order to
+-	 * handle a change in status */
+-	init_timer(&priv->phy_info_timer);
+-	priv->phy_info_timer.function = &gfar_phy_timer;
+-	priv->phy_info_timer.data = (unsigned long) mii_info->dev;
+-	mod_timer(&priv->phy_info_timer, jiffies +
+-			GFAR_PHY_CHANGE_TIME * HZ);
+-}
+-
+ /* 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 priv structure, and this
++ * information through variables in the phydev structure, and this
+  * function converts those variables into the appropriate
+  * register values, and can bring down the device if needed.
+  */
+@@ -1850,84 +1615,68 @@ static void adjust_link(struct net_devic
+ {
+ 	struct gfar_private *priv = netdev_priv(dev);
+ 	struct gfar *regs = priv->regs;
+-	u32 tempval;
+-	struct gfar_mii_info *mii_info = priv->mii_info;
++	unsigned long flags;
++	struct phy_device *phydev = priv->phydev;
++	int new_state = 0;
++
++	spin_lock_irqsave(&priv->lock, flags);
++	if (phydev->link) {
++		u32 tempval = gfar_read(&regs->maccfg2);
+ 
+-	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 != priv->oldduplex) {
+-			if (!(mii_info->duplex)) {
+-				tempval = gfar_read(&regs->maccfg2);
++		if (phydev->duplex != priv->oldduplex) {
++			new_state = 1;
++			if (!(phydev->duplex))
+ 				tempval &= ~(MACCFG2_FULL_DUPLEX);
+-				gfar_write(&regs->maccfg2, tempval);
+-
+-				if (netif_msg_link(priv))
+-					printk(KERN_INFO "%s: Half Duplex\n",
+-							dev->name);
+-			} else {
+-				tempval = gfar_read(&regs->maccfg2);
++			else
+ 				tempval |= MACCFG2_FULL_DUPLEX;
+-				gfar_write(&regs->maccfg2, tempval);
+ 
+-				if (netif_msg_link(priv))
+-					printk(KERN_INFO "%s: Full Duplex\n",
+-							dev->name);
+-			}
+-
+-			priv->oldduplex = mii_info->duplex;
++			priv->oldduplex = phydev->duplex;
+ 		}
+ 
+-		if (mii_info->speed != priv->oldspeed) {
+-			switch (mii_info->speed) {
++		if (phydev->speed != priv->oldspeed) {
++			new_state = 1;
++			switch (phydev->speed) {
+ 			case 1000:
+-				tempval = gfar_read(&regs->maccfg2);
+ 				tempval =
+ 				    ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
+-				gfar_write(&regs->maccfg2, tempval);
+ 				break;
+ 			case 100:
+ 			case 10:
+-				tempval = gfar_read(&regs->maccfg2);
+ 				tempval =
+ 				    ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
+-				gfar_write(&regs->maccfg2, tempval);
+ 				break;
+ 			default:
+ 				if (netif_msg_link(priv))
+ 					printk(KERN_WARNING
+-							"%s: Ack!  Speed (%d) is not 10/100/1000!\n",
+-							dev->name, mii_info->speed);
++						"%s: Ack!  Speed (%d) is not 10/100/1000!\n",
++						dev->name, phydev->speed);
+ 				break;
+ 			}
+ 
+-			if (netif_msg_link(priv))
+-				printk(KERN_INFO "%s: Speed %dBT\n", dev->name,
+-						mii_info->speed);
+-
+-			priv->oldspeed = mii_info->speed;
++			priv->oldspeed = phydev->speed;
+ 		}
+ 
++		gfar_write(&regs->maccfg2, tempval);
++
+ 		if (!priv->oldlink) {
+-			if (netif_msg_link(priv))
+-				printk(KERN_INFO "%s: Link is up\n", dev->name);
++			new_state = 1;
+ 			priv->oldlink = 1;
+-			netif_carrier_on(dev);
+ 			netif_schedule(dev);
+ 		}
+-	} else {
+-		if (priv->oldlink) {
+-			if (netif_msg_link(priv))
+-				printk(KERN_INFO "%s: Link is down\n",
+-						dev->name);
+-			priv->oldlink = 0;
+-			priv->oldspeed = 0;
+-			priv->oldduplex = -1;
+-			netif_carrier_off(dev);
+-		}
++	} else if (priv->oldlink) {
++		new_state = 1;
++		priv->oldlink = 0;
++		priv->oldspeed = 0;
++		priv->oldduplex = -1;
+ 	}
+-}
+ 
++	if (new_state && netif_msg_link(priv))
++		phy_print_status(phydev);
++
++	spin_unlock_irqrestore(&priv->lock, flags);
++}
+ 
+ /* Update the hash table based on the current list of multicast
+  * addresses we subscribe to.  Also, change the promiscuity of
+@@ -2122,12 +1871,23 @@ static struct device_driver gfar_driver 
+ 
+ static int __init gfar_init(void)
+ {
+-	return driver_register(&gfar_driver);
++	int err = gfar_mdio_init();
++
++	if (err)
++		return err;
++
++	err = driver_register(&gfar_driver);
++
++	if (err)
++		gfar_mdio_exit();
++	
++	return err;
+ }
+ 
+ static void __exit gfar_exit(void)
+ {
+ 	driver_unregister(&gfar_driver);
++	gfar_mdio_exit();
+ }
+ 
+ module_init(gfar_init);
+diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
+--- a/drivers/net/gianfar.h
++++ b/drivers/net/gianfar.h
+@@ -17,7 +17,6 @@
+  *
+  *  Still left to do:
+  *      -Add support for module parameters
+- *	-Add support for ethtool -s
+  *	-Add patch for ethtool phys id
+  */
+ #ifndef __GIANFAR_H
+@@ -37,7 +36,8 @@
+ #include <linux/skbuff.h>
+ #include <linux/spinlock.h>
+ #include <linux/mm.h>
+-#include <linux/fsl_devices.h>
++#include <linux/mii.h>
++#include <linux/phy.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -48,7 +48,8 @@
+ #include <linux/workqueue.h>
+ #include <linux/ethtool.h>
+ #include <linux/netdevice.h>
+-#include "gianfar_phy.h"
++#include <linux/fsl_devices.h>
++#include "gianfar_mii.h"
+ 
+ /* The maximum number of packets to be handled in one call of gfar_poll */
+ #define GFAR_DEV_WEIGHT 64
+@@ -73,7 +74,7 @@
+ #define PHY_INIT_TIMEOUT 100000
+ #define GFAR_PHY_CHANGE_TIME 2
+ 
+-#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.1, "
++#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.2, "
+ #define DRV_NAME "gfar-enet"
+ extern const char gfar_driver_name[];
+ extern const char gfar_driver_version[];
+@@ -578,12 +579,7 @@ struct gfar {
+ 	u32	hafdup;		/* 0x.50c - Half Duplex Register */
+ 	u32	maxfrm;		/* 0x.510 - Maximum Frame Length Register */
+ 	u8	res18[12];
+-	u32	miimcfg;	/* 0x.520 - MII Management Configuration Register */
+-	u32	miimcom;	/* 0x.524 - MII Management Command Register */
+-	u32	miimadd;	/* 0x.528 - MII Management Address Register */
+-	u32	miimcon;	/* 0x.52c - MII Management Control Register */
+-	u32	miimstat;	/* 0x.530 - MII Management Status Register */
+-	u32	miimind;	/* 0x.534 - MII Management Indicator Register */
++	u8	gfar_mii_regs[24];	/* See gianfar_phy.h */
+ 	u8	res19[4];
+ 	u32	ifstat;		/* 0x.53c - Interface Status Register */
+ 	u32	macstnaddr1;	/* 0x.540 - Station Address Part 1 Register */
+@@ -688,9 +684,6 @@ struct gfar_private {
+ 	struct gfar *regs;	/* Pointer to the GFAR memory mapped Registers */
+ 	u32 *hash_regs[16];
+ 	int hash_width;
+-	struct gfar *phyregs;
+-	struct work_struct tq;
+-	struct timer_list phy_info_timer;
+ 	struct net_device_stats stats; /* linux network statistics */
+ 	struct gfar_extra_stats extra_stats;
+ 	spinlock_t lock;
+@@ -710,7 +703,8 @@ struct gfar_private {
+ 	unsigned int interruptError;
+ 	struct gianfar_platform_data *einfo;
+ 
+-	struct gfar_mii_info *mii_info;
++	struct phy_device *phydev;
++	struct mii_bus *mii_bus;
+ 	int oldspeed;
+ 	int oldduplex;
+ 	int oldlink;
+@@ -732,4 +726,12 @@ extern inline void gfar_write(volatile u
+ 
+ extern struct ethtool_ops *gfar_op_array[];
+ 
++extern irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
++extern int startup_gfar(struct net_device *dev);
++extern void stop_gfar(struct net_device *dev);
++extern void gfar_halt(struct net_device *dev);
++extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
++		int enable, u32 regnum, u32 read);
++void gfar_setup_stashing(struct net_device *dev);
++
+ #endif /* __GIANFAR_H */
+diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
+--- a/drivers/net/gianfar_ethtool.c
++++ b/drivers/net/gianfar_ethtool.c
+@@ -39,17 +39,18 @@
+ #include <asm/types.h>
+ #include <asm/uaccess.h>
+ #include <linux/ethtool.h>
++#include <linux/mii.h>
++#include <linux/phy.h>
+ 
+ #include "gianfar.h"
+ 
+ #define is_power_of_2(x)        ((x) != 0 && (((x) & ((x) - 1)) == 0))
+ 
+-extern int startup_gfar(struct net_device *dev);
+-extern void stop_gfar(struct net_device *dev);
+-extern void gfar_halt(struct net_device *dev);
+ extern void gfar_start(struct net_device *dev);
+ extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
+ 
++#define GFAR_MAX_COAL_USECS 0xffff
++#define GFAR_MAX_COAL_FRAMES 0xff
+ static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
+ 		     u64 * buf);
+ static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
+@@ -182,38 +183,32 @@ static void gfar_gdrvinfo(struct net_dev
+ 	drvinfo->eedump_len = 0;
+ }
+ 
++
++static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct gfar_private *priv = netdev_priv(dev);
++	struct phy_device *phydev = priv->phydev;
++
++	if (NULL == phydev)
++		return -ENODEV;
++
++	return phy_ethtool_sset(phydev, cmd);
++}
++
++
+ /* Return the current settings in the ethtool_cmd structure */
+ static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+ 	struct gfar_private *priv = netdev_priv(dev);
+-	uint gigabit_support = 
+-		priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
+-			SUPPORTED_1000baseT_Full : 0;
+-	uint gigabit_advert = 
+-		priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
+-			ADVERTISED_1000baseT_Full: 0;
+-
+-	cmd->supported = (SUPPORTED_10baseT_Half
+-			  | SUPPORTED_100baseT_Half
+-			  | SUPPORTED_100baseT_Full
+-			  | gigabit_support | SUPPORTED_Autoneg);
+-
+-	/* For now, we always advertise everything */
+-	cmd->advertising = (ADVERTISED_10baseT_Half
+-			    | ADVERTISED_100baseT_Half
+-			    | ADVERTISED_100baseT_Full
+-			    | gigabit_advert | ADVERTISED_Autoneg);
+-
+-	cmd->speed = priv->mii_info->speed;
+-	cmd->duplex = priv->mii_info->duplex;
+-	cmd->port = PORT_MII;
+-	cmd->phy_address = priv->mii_info->mii_id;
+-	cmd->transceiver = XCVR_EXTERNAL;
+-	cmd->autoneg = AUTONEG_ENABLE;
++	struct phy_device *phydev = priv->phydev;
++
++	if (NULL == phydev)
++		return -ENODEV;
++	
+ 	cmd->maxtxpkt = priv->txcount;
+ 	cmd->maxrxpkt = priv->rxcount;
+ 
+-	return 0;
++	return phy_ethtool_gset(phydev, cmd);
+ }
+ 
+ /* Return the length of the register structure */
+@@ -241,14 +236,14 @@ static unsigned int gfar_usecs2ticks(str
+ 	unsigned int count;
+ 
+ 	/* The timer is different, depending on the interface speed */
+-	switch (priv->mii_info->speed) {
+-	case 1000:
++	switch (priv->phydev->speed) {
++	case SPEED_1000:
+ 		count = GFAR_GBIT_TIME;
+ 		break;
+-	case 100:
++	case SPEED_100:
+ 		count = GFAR_100_TIME;
+ 		break;
+-	case 10:
++	case SPEED_10:
+ 	default:
+ 		count = GFAR_10_TIME;
+ 		break;
+@@ -265,14 +260,14 @@ static unsigned int gfar_ticks2usecs(str
+ 	unsigned int count;
+ 
+ 	/* The timer is different, depending on the interface speed */
+-	switch (priv->mii_info->speed) {
+-	case 1000:
++	switch (priv->phydev->speed) {
++	case SPEED_1000:
+ 		count = GFAR_GBIT_TIME;
+ 		break;
+-	case 100:
++	case SPEED_100:
+ 		count = GFAR_100_TIME;
+ 		break;
+-	case 10:
++	case SPEED_10:
+ 	default:
+ 		count = GFAR_10_TIME;
+ 		break;
+@@ -292,6 +287,9 @@ static int gfar_gcoalesce(struct net_dev
+ 	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
+ 		return -EOPNOTSUPP;
+ 
++	if (NULL == priv->phydev)
++		return -ENODEV;
++
+ 	cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
+ 	cvals->rx_max_coalesced_frames = priv->rxcount;
+ 
+@@ -348,6 +346,22 @@ static int gfar_scoalesce(struct net_dev
+ 	else
+ 		priv->rxcoalescing = 1;
+ 
++	if (NULL == priv->phydev)
++		return -ENODEV;
++
++	/* Check the bounds of the values */
++	if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
++		pr_info("Coalescing is limited to %d microseconds\n",
++				GFAR_MAX_COAL_USECS);
++		return -EINVAL;
++	}
++
++	if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
++		pr_info("Coalescing is limited to %d frames\n",
++				GFAR_MAX_COAL_FRAMES);
++		return -EINVAL;
++	}
++
+ 	priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
+ 	priv->rxcount = cvals->rx_max_coalesced_frames;
+ 
+@@ -358,6 +372,19 @@ static int gfar_scoalesce(struct net_dev
+ 	else
+ 		priv->txcoalescing = 1;
+ 
++	/* Check the bounds of the values */
++	if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
++		pr_info("Coalescing is limited to %d microseconds\n",
++				GFAR_MAX_COAL_USECS);
++		return -EINVAL;
++	}
++
++	if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
++		pr_info("Coalescing is limited to %d frames\n",
++				GFAR_MAX_COAL_FRAMES);
++		return -EINVAL;
++	}
++
+ 	priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
+ 	priv->txcount = cvals->tx_max_coalesced_frames;
+ 
+@@ -536,6 +563,7 @@ static void gfar_set_msglevel(struct net
+ 
+ struct ethtool_ops gfar_ethtool_ops = {
+ 	.get_settings = gfar_gsettings,
++	.set_settings = gfar_ssettings,
+ 	.get_drvinfo = gfar_gdrvinfo,
+ 	.get_regs_len = gfar_reglen,
+ 	.get_regs = gfar_get_regs,
+diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/gianfar_mii.c
+@@ -0,0 +1,220 @@
++/* 
++ * drivers/net/gianfar_mii.c
++ *
++ * Gianfar Ethernet Driver -- MIIM bus implementation
++ * Provides Bus interface for MIIM regs
++ *
++ * Author: Andy Fleming
++ * Maintainer: Kumar Gala (kumar.gala at freescale.com)
++ *
++ * Copyright (c) 2002-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.
++ *
++ */
++
++#include <linux/config.h>
++#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/version.h>
++#include <linux/platform_device.h>
++#include <asm/ocp.h>
++#include <linux/crc32.h>
++#include <linux/mii.h>
++#include <linux/phy.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#include "gianfar.h"
++#include "gianfar_mii.h"
++
++/* Write value to the PHY at mii_id at register regnum,
++ * on the bus, waiting until the write is done before returning.
++ * All PHY configuration is done through the TSEC1 MIIM regs */
++int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
++{
++	struct gfar_mii *regs = bus->priv;
++
++	/* Set the PHY address and the register address we want to write */
++	gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
++
++	/* Write out the value we want */
++	gfar_write(&regs->miimcon, value);
++
++	/* Wait for the transaction to finish */
++	while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
++		cpu_relax();
++
++	return 0;
++}
++
++/* Read the bus for PHY at addr mii_id, register regnum, and
++ * return the value.  Clears miimcom first.  All PHY
++ * configuration has to be done through the TSEC1 MIIM regs */
++int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
++{
++	struct gfar_mii *regs = bus->priv;
++	u16 value;
++
++	/* Set the PHY address and the register address we want to read */
++	gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
++
++	/* Clear miimcom, and then initiate a read */
++	gfar_write(&regs->miimcom, 0);
++	gfar_write(&regs->miimcom, MII_READ_COMMAND);
++
++	/* Wait for the transaction to finish */
++	while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
++		cpu_relax();
++
++	/* Grab the value of the register from miimstat */
++	value = gfar_read(&regs->miimstat);
++
++	return value;
++}
++
++
++/* Reset the MIIM registers, and wait for the bus to free */
++int gfar_mdio_reset(struct mii_bus *bus)
++{
++	struct gfar_mii *regs = bus->priv;
++	unsigned int timeout = PHY_INIT_TIMEOUT;
++
++	spin_lock_bh(&bus->mdio_lock);
++
++	/* Reset the management interface */
++	gfar_write(&regs->miimcfg, MIIMCFG_RESET);
++
++	/* Setup the MII Mgmt clock speed */
++	gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);
++
++	/* Wait until the bus is free */
++	while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
++			timeout--)
++		cpu_relax();
++
++	spin_unlock_bh(&bus->mdio_lock);
++
++	if(timeout <= 0) {
++		printk(KERN_ERR "%s: The MII Bus is stuck!\n",
++				bus->name);
++		return -EBUSY;
++	}
++
++	return 0;
++}
++
++
++int gfar_mdio_probe(struct device *dev)
++{
++	struct platform_device *pdev = to_platform_device(dev);
++	struct gianfar_mdio_data *pdata;
++	struct gfar_mii *regs;
++	struct mii_bus *new_bus;
++	int err = 0;
++
++	if (NULL == dev)
++		return -EINVAL;
++
++	new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
++
++	if (NULL == new_bus)
++		return -ENOMEM;
++
++	new_bus->name = "Gianfar MII Bus",
++	new_bus->read = &gfar_mdio_read,
++	new_bus->write = &gfar_mdio_write,
++	new_bus->reset = &gfar_mdio_reset,
++	new_bus->id = pdev->id;
++
++	pdata = (struct gianfar_mdio_data *)pdev->dev.platform_data;
++
++	if (NULL == pdata) {
++		printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
++		return -ENODEV;
++	}
++
++	/* Set the PHY base address */
++	regs = (struct gfar_mii *) ioremap(pdata->paddr, 
++			sizeof (struct gfar_mii));
++
++	if (NULL == regs) {
++		err = -ENOMEM;
++		goto reg_map_fail;
++	}
++
++	new_bus->priv = regs;
++
++	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:
++	iounmap((void *) regs);
++reg_map_fail:
++	kfree(new_bus);
++
++	return err;
++}
++
++
++int gfar_mdio_remove(struct device *dev)
++{
++	struct mii_bus *bus = dev_get_drvdata(dev);
++
++	mdiobus_unregister(bus);
++
++	dev_set_drvdata(dev, NULL);
++
++	iounmap((void *) (&bus->priv));
++	bus->priv = NULL;
++	kfree(bus);
++
++	return 0;
++}
++
++static struct device_driver gianfar_mdio_driver = {
++	.name = "fsl-gianfar_mdio",
++	.bus = &platform_bus_type,
++	.probe = gfar_mdio_probe,
++	.remove = gfar_mdio_remove,
++};
++
++int __init gfar_mdio_init(void)
++{
++	return driver_register(&gianfar_mdio_driver);
++}
++
++void __exit gfar_mdio_exit(void)
++{
++	driver_unregister(&gianfar_mdio_driver);
++}
+diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/gianfar_mii.h
+@@ -0,0 +1,45 @@
++/* 
++ * drivers/net/gianfar_mii.h
++ *
++ * Gianfar Ethernet Driver -- MII Management Bus Implementation
++ * Driver for the MDIO bus controller in the Gianfar register space
++ *
++ * Author: Andy Fleming
++ * Maintainer: Kumar Gala (kumar.gala at freescale.com)
++ *
++ * Copyright (c) 2002-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 __GIANFAR_MII_H
++#define __GIANFAR_MII_H
++
++#define MIIMIND_BUSY            0x00000001
++#define MIIMIND_NOTVALID        0x00000004
++
++#define MII_READ_COMMAND       0x00000001
++
++#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
++		| SUPPORTED_100baseT_Half \
++		| SUPPORTED_100baseT_Full \
++		| SUPPORTED_Autoneg \
++		| SUPPORTED_MII)
++
++struct gfar_mii {
++	u32	miimcfg;	/* 0x.520 - MII Management Config Register */
++	u32	miimcom;	/* 0x.524 - MII Management Command Register */
++	u32	miimadd;	/* 0x.528 - MII Management Address Register */
++	u32	miimcon;	/* 0x.52c - MII Management Control Register */
++	u32	miimstat;	/* 0x.530 - MII Management Status Register */
++	u32	miimind;	/* 0x.534 - MII Management Indicator Register */
++};
++
++int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
++int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
++int __init gfar_mdio_init(void);
++void __exit gfar_mdio_exit(void);
++#endif /* GIANFAR_PHY_H */
+diff --git a/drivers/net/gianfar_phy.c b/drivers/net/gianfar_phy.c
+deleted file mode 100644
+--- a/drivers/net/gianfar_phy.c
++++ /dev/null
+@@ -1,661 +0,0 @@
+-/* 
+- * drivers/net/gianfar_phy.c
+- *
+- * Gianfar Ethernet Driver -- PHY handling
+- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
+- * Based on 8260_io/fcc_enet.c
+- *
+- * Author: Andy Fleming
+- * Maintainer: Kumar Gala (kumar.gala at freescale.com)
+- *
+- * Copyright (c) 2002-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.
+- *
+- */
+-
+-#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 <asm/io.h>
+-#include <asm/irq.h>
+-#include <asm/uaccess.h>
+-#include <linux/module.h>
+-#include <linux/version.h>
+-#include <linux/crc32.h>
+-#include <linux/mii.h>
+-
+-#include "gianfar.h"
+-#include "gianfar_phy.h"
+-
+-static void config_genmii_advert(struct gfar_mii_info *mii_info);
+-static void genmii_setup_forced(struct gfar_mii_info *mii_info);
+-static void genmii_restart_aneg(struct gfar_mii_info *mii_info);
+-static int gbit_config_aneg(struct gfar_mii_info *mii_info);
+-static int genmii_config_aneg(struct gfar_mii_info *mii_info);
+-static int genmii_update_link(struct gfar_mii_info *mii_info);
+-static int genmii_read_status(struct gfar_mii_info *mii_info);
+-u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum);
+-void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val);
+-
+-/* 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)
+-{
+-	struct gfar_private *priv = netdev_priv(dev);
+-	struct gfar *regbase = priv->phyregs;
+-
+-	/* Set the PHY address and the register address we want to write */
+-	gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
+-
+-	/* Write out the value we want */
+-	gfar_write(&regbase->miimcon, value);
+-
+-	/* Wait for the transaction to finish */
+-	while (gfar_read(&regbase->miimind) & MIIMIND_BUSY)
+-		cpu_relax();
+-}
+-
+-/* 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)
+-{
+-	struct gfar_private *priv = netdev_priv(dev);
+-	struct gfar *regbase = priv->phyregs;
+-	u16 value;
+-
+-	/* Set the PHY address and the register address we want to read */
+-	gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
+-
+-	/* Clear miimcom, and then initiate a read */
+-	gfar_write(&regbase->miimcom, 0);
+-	gfar_write(&regbase->miimcom, MII_READ_COMMAND);
+-
+-	/* Wait for the transaction to finish */
+-	while (gfar_read(&regbase->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
+-		cpu_relax();
+-
+-	/* Grab the value of the register from miimstat */
+-	value = gfar_read(&regbase->miimstat);
+-
+-	return value;
+-}
+-
+-void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info)
+-{
+-	if(mii_info->phyinfo->ack_interrupt)
+-		mii_info->phyinfo->ack_interrupt(mii_info);
+-}
+-
+-
+-void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts)
+-{
+-	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 gfar_mii_info *mii_info)
+-{
+-	u32 advertise;
+-	u16 adv;
+-
+-	/* 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 gfar_mii_info *mii_info)
+-{
+-	u16 ctrl;
+-	u32 features = mii_info->phyinfo->features;
+-	
+-	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! */
+-			printk(KERN_ERR "%s: Bad speed!\n", 
+-					mii_info->dev->name);
+-			break;
+-	}
+-
+-	phy_write(mii_info, MII_BMCR, ctrl);
+-}
+-
+-
+-/* Enable and Restart Autonegotiation */
+-static void genmii_restart_aneg(struct gfar_mii_info *mii_info)
+-{
+-	u16 ctl;
+-
+-	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 gfar_mii_info *mii_info)
+-{
+-	u16 adv;
+-	u32 advertise;
+-
+-	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 marvell_config_aneg(struct gfar_mii_info *mii_info)
+-{
+-	/* 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 genmii_config_aneg(struct gfar_mii_info *mii_info)
+-{
+-	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 gfar_mii_info *mii_info)
+-{
+-	u16 status;
+-
+-	/* 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 gfar_mii_info *mii_info)
+-{
+-	u16 status;
+-	int err;
+-
+-	/* 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_read_status(struct gfar_mii_info *mii_info)
+-{
+-	u16 status;
+-	int err;
+-
+-	/* 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);
+-
+-#if 0
+-		/* If speed and duplex aren't resolved,
+-		 * return an error.  Isn't this handled
+-		 * by checking aneg?
+-		 */
+-		if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0)
+-			return -EAGAIN;
+-#endif
+-
+-		/* 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 cis820x_read_status(struct gfar_mii_info *mii_info)
+-{
+-	u16 status;
+-	int err;
+-
+-	/* 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 marvell_ack_interrupt(struct gfar_mii_info *mii_info)
+-{
+-	/* Clear the interrupts by reading the reg */
+-	phy_read(mii_info, MII_M1011_IEVENT);
+-
+-	return 0;
+-}
+-
+-static int marvell_config_intr(struct gfar_mii_info *mii_info)
+-{
+-	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 gfar_mii_info *mii_info)
+-{
+-	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_ack_interrupt(struct gfar_mii_info *mii_info)
+-{
+-	phy_read(mii_info, MII_CIS8201_ISTAT);
+-
+-	return 0;
+-}
+-
+-static int cis820x_config_intr(struct gfar_mii_info *mii_info)
+-{
+-	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 gfar_mii_info *mii_info)
+-{
+-	u16 status;
+-	int err;
+-
+-	/* 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 gfar_mii_info *mii_info)
+-{
+-	struct dm9161_private *priv = mii_info->priv;
+-
+-	if(0 == priv->resetdone)
+-		return -EAGAIN;
+-
+-	return 0;
+-}
+-
+-static void dm9161_timer(unsigned long data)
+-{
+-	struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
+-	struct dm9161_private *priv = mii_info->priv;
+-	u16 status = phy_read(mii_info, MII_BMSR);
+-
+-	if (status & BMSR_ANEGCOMPLETE) {
+-		priv->resetdone = 1;
+-	} else
+-		mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
+-}
+-
+-static int dm9161_init(struct gfar_mii_info *mii_info)
+-{
+-	struct dm9161_private *priv;
+-
+-	/* 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;
+-
+-	/* Isolate the PHY */
+-	phy_write(mii_info, MII_BMCR, BMCR_ISOLATE);
+-
+-	/* Do not bypass the scrambler/descrambler */
+-	phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
+-
+-	/* Clear 10BTCSR to default */
+-	phy_write(mii_info, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT);
+-
+-	/* Reconnect the PHY, and enable Autonegotiation */
+-	phy_write(mii_info, MII_BMCR, BMCR_ANENABLE);
+-
+-	/* 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 gfar_mii_info *mii_info)
+-{
+-	struct dm9161_private *priv = mii_info->priv;
+-
+-	del_timer_sync(&priv->timer);
+-	kfree(priv);
+-}
+-
+-#if 0
+-static int dm9161_ack_interrupt(struct gfar_mii_info *mii_info)
+-{
+-	phy_read(mii_info, MII_DM9161_INTR);
+-
+-	return 0;
+-}
+-#endif
+-
+-/* Cicada 820x */
+-static struct phy_info phy_info_cis820x = {
+-	0x000fc440,
+-	"Cicada Cis8204",
+-	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,
+-	.name		= "Davicom DM9161E",
+-	.phy_id_mask	= 0x0ffffff0,
+-	.init		= dm9161_init,
+-	.config_aneg	= dm9161_config_aneg,
+-	.read_status	= dm9161_read_status,
+-	.close		= dm9161_close,
+-};
+-
+-static struct phy_info phy_info_marvell = {
+-	.phy_id		= 0x01410c00,
+-	.phy_id_mask	= 0xffffff00,
+-	.name		= "Marvell 88E1101/88E1111",
+-	.features	= MII_GBIT_FEATURES,
+-	.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_genmii,
+-	NULL
+-};
+-
+-u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum)
+-{
+-	u16 retval;
+-	unsigned long flags;
+-
+-	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 gfar_mii_info *mii_info, u16 regnum, u16 val)
+-{
+-	unsigned long flags;
+-
+-	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 gfar_mii_info *mii_info)
+-{
+-	u16 phy_reg;
+-	u32 phy_ID;
+-	int i;
+-	struct phy_info *theInfo = NULL;
+-	struct net_device *dev = mii_info->dev;
+-
+-	/* 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) {
+-		printk("%s: PHY id %x is not supported!\n", dev->name, phy_ID);
+-		return NULL;
+-	} else {
+-		printk("%s: PHY is %s (%x)\n", dev->name, theInfo->name,
+-		       phy_ID);
+-	}
+-
+-	return theInfo;
+-}
+diff --git a/drivers/net/gianfar_phy.h b/drivers/net/gianfar_phy.h
+deleted file mode 100644
+--- a/drivers/net/gianfar_phy.h
++++ /dev/null
+@@ -1,213 +0,0 @@
+-/* 
+- * drivers/net/gianfar_phy.h
+- *
+- * Gianfar Ethernet Driver -- PHY handling
+- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
+- * Based on 8260_io/fcc_enet.c
+- *
+- * Author: Andy Fleming
+- * Maintainer: Kumar Gala (kumar.gala at freescale.com)
+- *
+- * Copyright (c) 2002-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 __GIANFAR_PHY_H
+-#define __GIANFAR_PHY_H
+-
+-#define MII_end ((u32)-2)
+-#define MII_read ((u32)-1)
+-
+-#define MIIMIND_BUSY            0x00000001
+-#define MIIMIND_NOTVALID        0x00000004
+-
+-#define GFAR_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 gfar_mii_info {
+-	/* Information about the PHY type */
+-	/* And management functions */
+-	struct phy_info *phyinfo;
+-
+-	/* 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 gfar_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 gfar_mii_info *mii_info);
+-
+-	/* Called to suspend the PHY for power */
+-	int (*suspend)(struct gfar_mii_info *mii_info);
+-
+-	/* Reconfigures autonegotiation (or disables it) */
+-	int (*config_aneg)(struct gfar_mii_info *mii_info);
+-
+-	/* Determines the negotiated speed and duplex */
+-	int (*read_status)(struct gfar_mii_info *mii_info);
+-
+-	/* Clears any pending interrupts */
+-	int (*ack_interrupt)(struct gfar_mii_info *mii_info);
+-
+-	/* Enables or disables interrupts */
+-	int (*config_intr)(struct gfar_mii_info *mii_info);
+-
+-	/* Clears up any memory if needed */
+-	void (*close)(struct gfar_mii_info *mii_info);
+-};
+-
+-struct phy_info *get_phy_info(struct gfar_mii_info *mii_info);
+-int read_phy_reg(struct net_device *dev, int mii_id, int regnum);
+-void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value);
+-void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info);
+-void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts);
+-
+-struct dm9161_private {
+-	struct timer_list timer;
+-	int resetdone;
+-};
+-
+-#endif /* GIANFAR_PHY_H */
+diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
+--- a/drivers/net/hamradio/Kconfig
++++ b/drivers/net/hamradio/Kconfig
+@@ -1,6 +1,7 @@
+ config MKISS
+ 	tristate "Serial port KISS driver"
+ 	depends on AX25
++	select CRC16
+ 	---help---
+ 	  KISS is a protocol used for the exchange of data between a computer
+ 	  and a Terminal Node Controller (a small embedded system commonly
+diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
+--- a/drivers/net/hamradio/bpqether.c
++++ b/drivers/net/hamradio/bpqether.c
+@@ -144,7 +144,7 @@ static inline struct net_device *bpq_get
+ {
+ 	struct bpqdev *bpq;
+ 
+-	list_for_each_entry(bpq, &bpq_devices, bpq_list) {
++	list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list) {
+ 		if (bpq->ethdev == dev)
+ 			return bpq->axdev;
+ 	}
+@@ -399,7 +399,7 @@ static void *bpq_seq_start(struct seq_fi
+ 	if (*pos == 0)
+ 		return SEQ_START_TOKEN;
+ 	
+-	list_for_each_entry(bpqdev, &bpq_devices, bpq_list) {
++	list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
+ 		if (i == *pos)
+ 			return bpqdev;
+ 	}
+@@ -418,7 +418,7 @@ static void *bpq_seq_next(struct seq_fil
+ 		p = ((struct bpqdev *)v)->bpq_list.next;
+ 
+ 	return (p == &bpq_devices) ? NULL 
+-		: list_entry(p, struct bpqdev, bpq_list);
++		: rcu_dereference(list_entry(p, struct bpqdev, bpq_list));
+ }
+ 
+ static void bpq_seq_stop(struct seq_file *seq, void *v)
+@@ -561,8 +561,6 @@ static int bpq_device_event(struct notif
+ 	if (!dev_is_ethdev(dev))
+ 		return NOTIFY_DONE;
+ 
+-	rcu_read_lock();
+-
+ 	switch (event) {
+ 	case NETDEV_UP:		/* new ethernet device -> new BPQ interface */
+ 		if (bpq_get_ax25_dev(dev) == NULL)
+@@ -581,7 +579,6 @@ static int bpq_device_event(struct notif
+ 	default:
+ 		break;
+ 	}
+-	rcu_read_unlock();
+ 
+ 	return NOTIFY_DONE;
+ }
+diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
+--- a/drivers/net/hamradio/mkiss.c
++++ b/drivers/net/hamradio/mkiss.c
+@@ -14,13 +14,14 @@
+  *
+  * Copyright (C) Hans Alblas PE1AYX <hans at esrac.ele.tue.nl>
+  * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf at linux-mips.org>
++ * Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas at x-berg.in-berlin.de>
+  */
+-
+ #include <linux/config.h>
+ #include <linux/module.h>
+ #include <asm/system.h>
+ #include <linux/bitops.h>
+ #include <asm/uaccess.h>
++#include <linux/crc16.h>
+ #include <linux/string.h>
+ #include <linux/mm.h>
+ #include <linux/interrupt.h>
+@@ -39,11 +40,6 @@
+ 
+ #include <net/ax25.h>
+ 
+-#ifdef CONFIG_INET
+-#include <linux/ip.h>
+-#include <linux/tcp.h>
+-#endif
+-
+ #define AX_MTU		236
+ 
+ /* SLIP/KISS protocol characters. */
+@@ -80,9 +76,13 @@ struct mkiss {
+ 
+ 	int		mode;
+         int		crcmode;	/* MW: for FlexNet, SMACK etc.  */
+-#define CRC_MODE_NONE   0
+-#define CRC_MODE_FLEX   1
+-#define CRC_MODE_SMACK  2
++	int		crcauto;	/* CRC auto mode */
++
++#define CRC_MODE_NONE		0
++#define CRC_MODE_FLEX		1
++#define CRC_MODE_SMACK		2
++#define CRC_MODE_FLEX_TEST	3
++#define CRC_MODE_SMACK_TEST	4
+ 
+ 	atomic_t		refcnt;
+ 	struct semaphore	dead_sem;
+@@ -151,6 +151,21 @@ static int check_crc_flex(unsigned char 
+ 	return 0;
+ }
+ 
++static int check_crc_16(unsigned char *cp, int size)
++{
++	unsigned short crc = 0x0000;
++
++	if (size < 3)
++		return -1;
++
++	crc = crc16(0, cp, size);
++
++	if (crc != 0x0000)
++		return -1;
++
++	return 0;
++}
++
+ /*
+  * Standard encapsulation
+  */
+@@ -237,19 +252,42 @@ static void ax_bump(struct mkiss *ax)
+ 
+ 	spin_lock_bh(&ax->buflock);
+ 	if (ax->rbuff[0] > 0x0f) {
+-		if (ax->rbuff[0] & 0x20) {
+-		        ax->crcmode = CRC_MODE_FLEX;
++		if (ax->rbuff[0] & 0x80) {
++			if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
++				ax->stats.rx_errors++;
++				spin_unlock_bh(&ax->buflock);
++
++				return;
++			}
++			if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
++				printk(KERN_INFO
++				       "mkiss: %s: Switchting to crc-smack\n",
++				       ax->dev->name);
++				ax->crcmode = CRC_MODE_SMACK;
++			}
++			ax->rcount -= 2;
++			*ax->rbuff &= ~0x80;
++		} else if (ax->rbuff[0] & 0x20)  {
+ 			if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
+-			        ax->stats.rx_errors++;
++				ax->stats.rx_errors++;
++				spin_unlock_bh(&ax->buflock);
+ 				return;
+ 			}
++			if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
++				printk(KERN_INFO
++				       "mkiss: %s: Switchting to crc-flexnet\n",
++				       ax->dev->name);
++				ax->crcmode = CRC_MODE_FLEX;
++			}
+ 			ax->rcount -= 2;
+-                        /* dl9sau bugfix: the trailling two bytes flexnet crc
+-                         * will not be passed to the kernel. thus we have
+-                         * to correct the kissparm signature, because it
+-                         * indicates a crc but there's none
++
++			/*
++			 * dl9sau bugfix: the trailling two bytes flexnet crc
++			 * will not be passed to the kernel. thus we have to
++			 * correct the kissparm signature, because it indicates
++			 * a crc but there's none
+ 			 */
+-                        *ax->rbuff &= ~0x20;
++			*ax->rbuff &= ~0x20;
+ 		}
+  	}
+ 	spin_unlock_bh(&ax->buflock);
+@@ -352,10 +390,8 @@ static void ax_changedmtu(struct mkiss *
+ 		       "MTU change cancelled.\n",
+ 		       ax->dev->name);
+ 		dev->mtu = ax->mtu;
+-		if (xbuff != NULL)
+-			kfree(xbuff);
+-		if (rbuff != NULL)
+-			kfree(rbuff);
++		kfree(xbuff);
++		kfree(rbuff);
+ 		return;
+ 	}
+ 
+@@ -417,20 +453,69 @@ static void ax_encaps(struct net_device 
+ 	p = icp;
+ 
+ 	spin_lock_bh(&ax->buflock);
+-        switch (ax->crcmode) {
+-	         unsigned short crc;
++	if ((*p & 0x0f) != 0) {
++		/* Configuration Command (kissparms(1).
++		 * Protocol spec says: never append CRC.
++		 * This fixes a very old bug in the linux
++		 * kiss driver. -- dl9sau */
++		switch (*p & 0xff) {
++		case 0x85:
++			/* command from userspace especially for us,
++			 * not for delivery to the tnc */
++			if (len > 1) {
++				int cmd = (p[1] & 0xff);
++				switch(cmd) {
++				case 3:
++				  ax->crcmode = CRC_MODE_SMACK;
++				  break;
++				case 2:
++				  ax->crcmode = CRC_MODE_FLEX;
++				  break;
++				case 1:
++				  ax->crcmode = CRC_MODE_NONE;
++				  break;
++				case 0:
++				default:
++				  ax->crcmode = CRC_MODE_SMACK_TEST;
++				  cmd = 0;
++				}
++				ax->crcauto = (cmd ? 0 : 1);
++				printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd);
++			}
++			spin_unlock_bh(&ax->buflock);
++			netif_start_queue(dev);
+ 
+-	case CRC_MODE_FLEX:
+-	         *p |= 0x20;
+-	         crc = calc_crc_flex(p, len);
+-		 count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
+-		 break;
++			return;
++		default:
++			count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
++		}
++	} else {
++		unsigned short crc;
++		switch (ax->crcmode) {
++		case CRC_MODE_SMACK_TEST:
++			ax->crcmode  = CRC_MODE_FLEX_TEST;
++			printk(KERN_INFO "mkiss: %s: Trying crc-smack\n", ax->dev->name);
++			// fall through
++		case CRC_MODE_SMACK:
++			*p |= 0x80;
++			crc = swab16(crc16(0, p, len));
++			count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
++			break;
++		case CRC_MODE_FLEX_TEST:
++			ax->crcmode = CRC_MODE_NONE;
++			printk(KERN_INFO "mkiss: %s: Trying crc-flexnet\n", ax->dev->name);
++			// fall through
++		case CRC_MODE_FLEX:
++			*p |= 0x20;
++			crc = calc_crc_flex(p, len);
++			count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
++			break;
++
++		default:
++			count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
++		}
++  	}
+ 
+-	default:
+-	         count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
+-		 break;
+-	}
+-	
+ 	set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
+ 	actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
+ 	ax->stats.tx_packets++;
+@@ -439,8 +524,6 @@ static void ax_encaps(struct net_device 
+ 	ax->dev->trans_start = jiffies;
+ 	ax->xleft = count - actual;
+ 	ax->xhead = ax->xbuff + actual;
+-
+-	spin_unlock_bh(&ax->buflock);
+ }
+ 
+ /* Encapsulate an AX.25 packet and kick it into a TTY queue. */
+@@ -622,7 +705,7 @@ static void ax_setup(struct net_device *
+  * best way to fix this is to use a rwlock in the tty struct, but for now we
+  * use a single global rwlock for all ttys in ppp line discipline.
+  */
+-static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
++static DEFINE_RWLOCK(disc_data_lock);
+ 
+ static struct mkiss *mkiss_get(struct tty_struct *tty)
+ {
+@@ -643,6 +726,8 @@ static void mkiss_put(struct mkiss *ax)
+ 		up(&ax->dead_sem);
+ }
+ 
++static int crc_force = 0;	/* Can be overridden with insmod */
++
+ static int mkiss_open(struct tty_struct *tty)
+ {
+ 	struct net_device *dev;
+@@ -682,6 +767,33 @@ static int mkiss_open(struct tty_struct 
+ 	if (register_netdev(dev))
+ 		goto out_free_buffers;
+ 
++	/* after register_netdev() - because else printk smashes the kernel */
++	switch (crc_force) {
++	case 3:
++		ax->crcmode  = CRC_MODE_SMACK;
++		printk(KERN_INFO "mkiss: %s: crc mode smack forced.\n",
++		       ax->dev->name);
++		break;
++	case 2:
++		ax->crcmode  = CRC_MODE_FLEX;
++		printk(KERN_INFO "mkiss: %s: crc mode flexnet forced.\n",
++		       ax->dev->name);
++		break;
++	case 1:
++		ax->crcmode  = CRC_MODE_NONE;
++		printk(KERN_INFO "mkiss: %s: crc mode disabled.\n",
++		       ax->dev->name);
++		break;
++	case 0:
++		/* fall through */
++	default:
++		crc_force = 0;
++		printk(KERN_INFO "mkiss: %s: crc mode is auto.\n",
++		       ax->dev->name);
++		ax->crcmode  = CRC_MODE_SMACK_TEST;
++	}
++	ax->crcauto = (crc_force ? 0 : 1);
++
+ 	netif_start_queue(dev);
+ 
+ 	/* Done.  We have linked the TTY line to a channel. */
+@@ -765,7 +877,6 @@ static int mkiss_ioctl(struct tty_struct
+ 
+ 	case SIOCSIFHWADDR: {
+ 		char addr[AX25_ADDR_LEN];
+-printk(KERN_INFO "In SIOCSIFHWADDR");
+ 
+ 		if (copy_from_user(&addr,
+ 		                   (void __user *) arg, AX25_ADDR_LEN)) {
+@@ -864,6 +975,7 @@ out:
+ }
+ 
+ static struct tty_ldisc ax_ldisc = {
++	.owner		= THIS_MODULE,
+ 	.magic		= TTY_LDISC_MAGIC,
+ 	.name		= "mkiss",
+ 	.open		= mkiss_open,
+@@ -904,6 +1016,8 @@ static void __exit mkiss_exit_driver(voi
+ 
+ MODULE_AUTHOR("Ralf Baechle DL5RB <ralf at linux-mips.org>");
+ MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
++MODULE_PARM(crc_force, "i");
++MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]");
+ MODULE_LICENSE("GPL");
+ MODULE_ALIAS_LDISC(N_AX25);
+ 
+diff --git a/drivers/net/hamradio/mkiss.h b/drivers/net/hamradio/mkiss.h
+deleted file mode 100644
+--- a/drivers/net/hamradio/mkiss.h
++++ /dev/null
+@@ -1,62 +0,0 @@
+-/****************************************************************************
+- *	Defines for the Multi-KISS driver.
+- ****************************************************************************/
+-
+-#define AX25_MAXDEV	16		/* MAX number of AX25 channels;
+-					   This can be overridden with
+-					   insmod -oax25_maxdev=nnn	*/
+-#define AX_MTU		236	
+-
+-/* SLIP/KISS protocol characters. */
+-#define END             0300		/* indicates end of frame	*/
+-#define ESC             0333		/* indicates byte stuffing	*/
+-#define ESC_END         0334		/* ESC ESC_END means END 'data'	*/
+-#define ESC_ESC         0335		/* ESC ESC_ESC means ESC 'data'	*/
+-
+-struct ax_disp {
+-	int                magic;
+-
+-	/* Various fields. */
+-	struct tty_struct  *tty;		/* ptr to TTY structure		*/
+-	struct net_device      *dev;		/* easy for intr handling	*/
+-
+-	/* These are pointers to the malloc()ed frame buffers. */
+-	unsigned char      *rbuff;		/* receiver buffer		*/
+-	int                rcount;		/* received chars counter       */
+-	unsigned char      *xbuff;		/* transmitter buffer		*/
+-	unsigned char      *xhead;		/* pointer to next byte to XMIT */
+-	int                xleft;		/* bytes left in XMIT queue     */
+-
+-	/* SLIP interface statistics. */
+-	unsigned long      rx_packets;		/* inbound frames counter	*/
+-	unsigned long      tx_packets;		/* outbound frames counter      */
+-	unsigned long      rx_bytes;		/* inbound bytes counter        */
+-	unsigned long      tx_bytes;		/* outbound bytes counter       */
+-	unsigned long      rx_errors;		/* Parity, etc. errors          */
+-	unsigned long      tx_errors;		/* Planned stuff                */
+-	unsigned long      rx_dropped;		/* No memory for skb            */
+-	unsigned long      tx_dropped;		/* When MTU change              */
+-	unsigned long      rx_over_errors;	/* Frame bigger then SLIP buf.  */
+-
+-	/* Detailed SLIP statistics. */
+-	int                 mtu;		/* Our mtu (to spot changes!)   */
+-	int                 buffsize;		/* Max buffers sizes            */
+-
+-
+-	unsigned long   flags;		/* Flag values/ mode etc	*/
+-					/* long req'd: used by set_bit --RR */
+-#define AXF_INUSE	0		/* Channel in use               */
+-#define AXF_ESCAPE	1               /* ESC received                 */
+-#define AXF_ERROR	2               /* Parity, etc. error           */
+-#define AXF_KEEPTEST	3		/* Keepalive test flag		*/
+-#define AXF_OUTWAIT	4		/* is outpacket was flag	*/
+-
+-	int                 mode;
+-        int                 crcmode;    /* MW: for FlexNet, SMACK etc.  */ 
+-#define CRC_MODE_NONE   0
+-#define CRC_MODE_FLEX   1
+-#define CRC_MODE_SMACK  2
+-	spinlock_t          buflock;	/* lock for rbuf and xbuf */
+-};
+-
+-#define AX25_MAGIC		0x5316
+diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
+--- a/drivers/net/hp100.c
++++ b/drivers/net/hp100.c
+@@ -2517,10 +2517,8 @@ static int hp100_down_vg_link(struct net
+ 	do {
+ 		if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
+ 			break;
+-		if (!in_interrupt()) {
+-			set_current_state(TASK_INTERRUPTIBLE);
+-			schedule_timeout(1);
+-		}
++		if (!in_interrupt())
++			schedule_timeout_interruptible(1);
+ 	} while (time_after(time, jiffies));
+ 
+ 	if (time_after_eq(jiffies, time))	/* no signal->no logout */
+@@ -2536,10 +2534,8 @@ static int hp100_down_vg_link(struct net
+ 	do {
+ 		if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
+ 			break;
+-		if (!in_interrupt()) {
+-			set_current_state(TASK_INTERRUPTIBLE);
+-			schedule_timeout(1);
+-		}
++		if (!in_interrupt())
++			schedule_timeout_interruptible(1);
+ 	} while (time_after(time, jiffies));
+ 
+ #ifdef HP100_DEBUG
+@@ -2577,10 +2573,8 @@ static int hp100_down_vg_link(struct net
+ 		do {
+ 			if (!(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST))
+ 				break;
+-			if (!in_interrupt()) {
+-				set_current_state(TASK_INTERRUPTIBLE);
+-				schedule_timeout(1);
+-			}
++			if (!in_interrupt())
++				schedule_timeout_interruptible(1);
+ 		} while (time_after(time, jiffies));
+ 
+ 		hp100_orb(HP100_AUTO_MODE, MAC_CFG_3);	/* Autosel back on */
+@@ -2591,10 +2585,8 @@ static int hp100_down_vg_link(struct net
+ 	do {
+ 		if ((hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) == 0)
+ 			break;
+-		if (!in_interrupt()) {
+-			set_current_state(TASK_INTERRUPTIBLE);
+-			schedule_timeout(1);
+-		}
++		if (!in_interrupt())
++			schedule_timeout_interruptible(1);
+ 	} while (time_after(time, jiffies));
+ 
+ 	if (time_before_eq(time, jiffies)) {
+@@ -2606,10 +2598,8 @@ static int hp100_down_vg_link(struct net
+ 
+ 	time = jiffies + (2 * HZ);	/* This seems to take a while.... */
+ 	do {
+-		if (!in_interrupt()) {
+-			set_current_state(TASK_INTERRUPTIBLE);
+-			schedule_timeout(1);
+-		}
++		if (!in_interrupt())
++			schedule_timeout_interruptible(1);
+ 	} while (time_after(time, jiffies));
+ 
+ 	return 0;
+@@ -2659,10 +2649,8 @@ static int hp100_login_to_vg_hub(struct 
+ 		do {
+ 			if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
+ 				break;
+-			if (!in_interrupt()) {
+-				set_current_state(TASK_INTERRUPTIBLE);
+-				schedule_timeout(1);
+-			}
++			if (!in_interrupt())
++				schedule_timeout_interruptible(1);
+ 		} while (time_after(time, jiffies));
+ 
+ 		/* Start an addressed training and optionally request promiscuous port */
+@@ -2697,10 +2685,8 @@ static int hp100_login_to_vg_hub(struct 
+ 		do {
+ 			if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
+ 				break;
+-			if (!in_interrupt()) {
+-				set_current_state(TASK_INTERRUPTIBLE);
+-				schedule_timeout(1);
+-			}
++			if (!in_interrupt())
++				schedule_timeout_interruptible(1);
+ 		} while (time_before(jiffies, time));
+ 
+ 		if (time_after_eq(jiffies, time)) {
+@@ -2723,10 +2709,8 @@ static int hp100_login_to_vg_hub(struct 
+ #endif
+ 					break;
+ 				}
+-				if (!in_interrupt()) {
+-					set_current_state(TASK_INTERRUPTIBLE);
+-					schedule_timeout(1);
+-				}
++				if (!in_interrupt())
++					schedule_timeout_interruptible(1);
+ 			} while (time_after(time, jiffies));
+ 		}
+ 
+diff --git a/drivers/net/ibm_emac/Makefile b/drivers/net/ibm_emac/Makefile
+--- a/drivers/net/ibm_emac/Makefile
++++ b/drivers/net/ibm_emac/Makefile
+@@ -1,12 +1,11 @@
+ #
+-# Makefile for the IBM PPC4xx EMAC controllers
++# Makefile for the PowerPC 4xx on-chip ethernet driver
+ #
+ 
+ obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
+ 
+-ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o
+-
+-# Only need this if you want to see additional debug messages
+-ifeq ($(CONFIG_IBM_EMAC_ERRMSG), y)
+-ibm_emac-objs += ibm_emac_debug.o
+-endif
++ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o 
++ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += ibm_emac_zmii.o
++ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += ibm_emac_rgmii.o
++ibm_emac-$(CONFIG_IBM_EMAC_TAH) += ibm_emac_tah.o
++ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += ibm_emac_debug.o
+diff --git a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
+--- a/drivers/net/ibm_emac/ibm_emac.h
++++ b/drivers/net/ibm_emac/ibm_emac.h
+@@ -1,110 +1,142 @@
+ /*
+- * ibm_emac.h
++ * drivers/net/ibm_emac/ibm_emac.h
+  *
++ * Register definitions for PowerPC 4xx on-chip ethernet contoller
+  *
+- *      Armin Kuster akuster at mvista.com
+- *      June, 2002
++ * Copyright (c) 2004, 2005 Zultys Technologies.
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
+  *
+- * Copyright 2002 MontaVista Softare Inc.
++ * Based on original work by
++ *      Matt Porter <mporter at kernel.crashing.org>
++ *      Armin Kuster <akuster at mvista.com>
++ * 	Copyright 2002-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 as published by the
+  * Free Software Foundation;  either version 2 of the  License, or (at your
+  * option) any later version.
++ *
+  */
++#ifndef __IBM_EMAC_H_
++#define __IBM_EMAC_H_
++
++#include <linux/config.h>
++#include <linux/types.h>
++
++/* This is a simple check to prevent use of this driver on non-tested SoCs */
++#if !defined(CONFIG_405GP) && !defined(CONFIG_405GPR) && !defined(CONFIG_405EP) && \
++    !defined(CONFIG_440GP) && !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && \
++    !defined(CONFIG_440EP) && !defined(CONFIG_NP405H)
++#error	"Unknown SoC. Please, check chip user manual and make sure EMAC defines are OK"
++#endif
++
++/* EMAC registers 		Write Access rules */
++struct emac_regs {
++	u32 mr0;		/* special 	*/
++	u32 mr1;		/* Reset 	*/
++	u32 tmr0;		/* special 	*/
++	u32 tmr1;		/* special 	*/
++	u32 rmr;		/* Reset 	*/
++	u32 isr;		/* Always 	*/
++	u32 iser;		/* Reset 	*/
++	u32 iahr;		/* Reset, R, T 	*/
++	u32 ialr;		/* Reset, R, T 	*/
++	u32 vtpid;		/* Reset, R, T 	*/
++	u32 vtci;		/* Reset, R, T 	*/
++	u32 ptr;		/* Reset,    T 	*/
++	u32 iaht1;		/* Reset, R	*/
++	u32 iaht2;		/* Reset, R	*/
++	u32 iaht3;		/* Reset, R	*/
++	u32 iaht4;		/* Reset, R	*/
++	u32 gaht1;		/* Reset, R	*/
++	u32 gaht2;		/* Reset, R	*/
++	u32 gaht3;		/* Reset, R	*/
++	u32 gaht4;		/* Reset, R	*/
++	u32 lsah;
++	u32 lsal;
++	u32 ipgvr;		/* Reset,    T 	*/
++	u32 stacr;		/* special 	*/
++	u32 trtr;		/* special 	*/
++	u32 rwmr;		/* Reset 	*/
++	u32 octx;
++	u32 ocrx;
++	u32 ipcr;
++};
++
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_ETHTOOL_REGS_VER		0
++#define EMAC_ETHTOOL_REGS_SIZE		(sizeof(struct emac_regs) - sizeof(u32))
++#else
++#define EMAC_ETHTOOL_REGS_VER		1
++#define EMAC_ETHTOOL_REGS_SIZE		sizeof(struct emac_regs)
++#endif
++
++/* EMACx_MR0 */
++#define EMAC_MR0_RXI			0x80000000
++#define EMAC_MR0_TXI			0x40000000
++#define EMAC_MR0_SRST			0x20000000
++#define EMAC_MR0_TXE			0x10000000
++#define EMAC_MR0_RXE			0x08000000
++#define EMAC_MR0_WKE			0x04000000
++
++/* EMACx_MR1 */
++#define EMAC_MR1_FDE			0x80000000
++#define EMAC_MR1_ILE			0x40000000
++#define EMAC_MR1_VLE			0x20000000
++#define EMAC_MR1_EIFC			0x10000000
++#define EMAC_MR1_APP			0x08000000
++#define EMAC_MR1_IST			0x01000000
++
++#define EMAC_MR1_MF_MASK		0x00c00000
++#define EMAC_MR1_MF_10			0x00000000
++#define EMAC_MR1_MF_100			0x00400000
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_MR1_MF_1000		0x00000000
++#define EMAC_MR1_MF_1000GPCS		0x00000000
++#define EMAC_MR1_MF_IPPA(id)		0x00000000
++#else
++#define EMAC_MR1_MF_1000		0x00800000
++#define EMAC_MR1_MF_1000GPCS		0x00c00000
++#define EMAC_MR1_MF_IPPA(id)		(((id) & 0x1f) << 6)
++#endif
++
++#define EMAC_TX_FIFO_SIZE		2048
+ 
+-#ifndef _IBM_EMAC_H_
+-#define _IBM_EMAC_H_
+-/* General defines needed for the driver */
+-
+-/* Emac */
+-typedef struct emac_regs {
+-	u32 em0mr0;
+-	u32 em0mr1;
+-	u32 em0tmr0;
+-	u32 em0tmr1;
+-	u32 em0rmr;
+-	u32 em0isr;
+-	u32 em0iser;
+-	u32 em0iahr;
+-	u32 em0ialr;
+-	u32 em0vtpid;
+-	u32 em0vtci;
+-	u32 em0ptr;
+-	u32 em0iaht1;
+-	u32 em0iaht2;
+-	u32 em0iaht3;
+-	u32 em0iaht4;
+-	u32 em0gaht1;
+-	u32 em0gaht2;
+-	u32 em0gaht3;
+-	u32 em0gaht4;
+-	u32 em0lsah;
+-	u32 em0lsal;
+-	u32 em0ipgvr;
+-	u32 em0stacr;
+-	u32 em0trtr;
+-	u32 em0rwmr;
+-} emac_t;
+-
+-/* MODE REG 0 */
+-#define EMAC_M0_RXI			0x80000000
+-#define EMAC_M0_TXI			0x40000000
+-#define EMAC_M0_SRST			0x20000000
+-#define EMAC_M0_TXE			0x10000000
+-#define EMAC_M0_RXE			0x08000000
+-#define EMAC_M0_WKE			0x04000000
+-
+-/* MODE Reg 1 */
+-#define EMAC_M1_FDE			0x80000000
+-#define EMAC_M1_ILE			0x40000000
+-#define EMAC_M1_VLE			0x20000000
+-#define EMAC_M1_EIFC			0x10000000
+-#define EMAC_M1_APP			0x08000000
+-#define EMAC_M1_AEMI			0x02000000
+-#define EMAC_M1_IST			0x01000000
+-#define EMAC_M1_MF_1000GPCS		0x00c00000	/* Internal GPCS */
+-#define EMAC_M1_MF_1000MBPS		0x00800000	/* External GPCS */
+-#define EMAC_M1_MF_100MBPS		0x00400000
+-#define EMAC_M1_RFS_16K                 0x00280000	/* 000 for 512 byte */
+-#define EMAC_M1_TR			0x00008000
+-#ifdef CONFIG_IBM_EMAC4
+-#define EMAC_M1_RFS_8K                  0x00200000
+-#define EMAC_M1_RFS_4K                  0x00180000
+-#define EMAC_M1_RFS_2K                  0x00100000
+-#define EMAC_M1_RFS_1K                  0x00080000
+-#define EMAC_M1_TX_FIFO_16K             0x00050000	/* 0's for 512 byte */
+-#define EMAC_M1_TX_FIFO_8K              0x00040000
+-#define EMAC_M1_TX_FIFO_4K              0x00030000
+-#define EMAC_M1_TX_FIFO_2K              0x00020000
+-#define EMAC_M1_TX_FIFO_1K              0x00010000
+-#define EMAC_M1_TX_TR                   0x00008000
+-#define EMAC_M1_TX_MWSW                 0x00001000	/* 0 wait for status */
+-#define EMAC_M1_JUMBO_ENABLE            0x00000800	/* Upt to 9Kr status */
+-#define EMAC_M1_OPB_CLK_66              0x00000008	/* 66Mhz */
+-#define EMAC_M1_OPB_CLK_83              0x00000010	/* 83Mhz */
+-#define EMAC_M1_OPB_CLK_100             0x00000018	/* 100Mhz */
+-#define EMAC_M1_OPB_CLK_100P            0x00000020	/* 100Mhz+ */
+-#else				/* CONFIG_IBM_EMAC4 */
+-#define EMAC_M1_RFS_4K			0x00300000	/* ~4k for 512 byte */
+-#define EMAC_M1_RFS_2K			0x00200000
+-#define EMAC_M1_RFS_1K			0x00100000
+-#define EMAC_M1_TX_FIFO_2K		0x00080000	/* 0's for 512 byte */
+-#define EMAC_M1_TX_FIFO_1K		0x00040000
+-#define EMAC_M1_TR0_DEPEND		0x00010000	/* 0'x for single packet */
+-#define EMAC_M1_TR1_DEPEND		0x00004000
+-#define EMAC_M1_TR1_MULTI		0x00002000
+-#define EMAC_M1_JUMBO_ENABLE		0x00001000
+-#endif				/* CONFIG_IBM_EMAC4 */
+-#define EMAC_M1_BASE			(EMAC_M1_TX_FIFO_2K | \
+-					EMAC_M1_APP | \
+-					EMAC_M1_TR | EMAC_M1_VLE)
+-
+-/* Transmit Mode Register 0 */
+-#define EMAC_TMR0_GNP0			0x80000000
+-#define EMAC_TMR0_GNP1			0x40000000
+-#define EMAC_TMR0_GNPD			0x20000000
+-#define EMAC_TMR0_FC			0x10000000
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_MR1_RFS_4K			0x00300000
++#define EMAC_MR1_RFS_16K		0x00000000
++#define EMAC_RX_FIFO_SIZE(gige)		4096
++#define EMAC_MR1_TFS_2K			0x00080000
++#define EMAC_MR1_TR0_MULT		0x00008000
++#define EMAC_MR1_JPSM			0x00000000
++#define EMAC_MR1_BASE(opb)		(EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT)
++#else
++#define EMAC_MR1_RFS_4K			0x00180000
++#define EMAC_MR1_RFS_16K		0x00280000
++#define EMAC_RX_FIFO_SIZE(gige)		((gige) ? 16384 : 4096)
++#define EMAC_MR1_TFS_2K			0x00020000
++#define EMAC_MR1_TR			0x00008000
++#define EMAC_MR1_MWSW_001		0x00001000
++#define EMAC_MR1_JPSM			0x00000800
++#define EMAC_MR1_OBCI_MASK		0x00000038
++#define EMAC_MR1_OBCI_50		0x00000000
++#define EMAC_MR1_OBCI_66		0x00000008
++#define EMAC_MR1_OBCI_83		0x00000010
++#define EMAC_MR1_OBCI_100		0x00000018
++#define EMAC_MR1_OBCI_100P		0x00000020
++#define EMAC_MR1_OBCI(freq)		((freq) <= 50  ? EMAC_MR1_OBCI_50 : \
++					 (freq) <= 66  ? EMAC_MR1_OBCI_66 : \
++					 (freq) <= 83  ? EMAC_MR1_OBCI_83 : \
++					 (freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P)
++#define EMAC_MR1_BASE(opb)		(EMAC_MR1_TFS_2K | EMAC_MR1_TR | \
++					 EMAC_MR1_MWSW_001 | EMAC_MR1_OBCI(opb))
++#endif
++
++/* EMACx_TMR0 */
++#define EMAC_TMR0_GNP			0x80000000
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_TMR0_DEFAULT		0x00000000	
++#else
+ #define EMAC_TMR0_TFAE_2_32		0x00000001
+ #define EMAC_TMR0_TFAE_4_64		0x00000002
+ #define EMAC_TMR0_TFAE_8_128		0x00000003
+@@ -112,14 +144,36 @@ typedef struct emac_regs {
+ #define EMAC_TMR0_TFAE_32_512		0x00000005
+ #define EMAC_TMR0_TFAE_64_1024		0x00000006
+ #define EMAC_TMR0_TFAE_128_2048		0x00000007
++#define EMAC_TMR0_DEFAULT		EMAC_TMR0_TFAE_2_32
++#endif
++#define EMAC_TMR0_XMIT			(EMAC_TMR0_GNP | EMAC_TMR0_DEFAULT)
++
++/* EMACx_TMR1 */
++
++/* IBM manuals are not very clear here. 
++ * This is my interpretation of how things are. --ebs
++ */
++#if defined(CONFIG_40x)
++#define EMAC_FIFO_ENTRY_SIZE		8
++#define EMAC_MAL_BURST_SIZE		(16 * 4)
++#else
++#define EMAC_FIFO_ENTRY_SIZE		16
++#define EMAC_MAL_BURST_SIZE		(64 * 4)
++#endif
++
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_TMR1(l,h)			(((l) << 27) | (((h) & 0xff) << 16))
++#else
++#define EMAC_TMR1(l,h)			(((l) << 27) | (((h) & 0x3ff) << 14))
++#endif
+ 
+-/* Receive Mode Register */
++/* EMACx_RMR */
+ #define EMAC_RMR_SP			0x80000000
+ #define EMAC_RMR_SFCS			0x40000000
+-#define EMAC_RMR_ARRP			0x20000000
+-#define EMAC_RMR_ARP			0x10000000
+-#define EMAC_RMR_AROP			0x08000000
+-#define EMAC_RMR_ARPI			0x04000000
++#define EMAC_RMR_RRP			0x20000000
++#define EMAC_RMR_RFP			0x10000000
++#define EMAC_RMR_ROP			0x08000000
++#define EMAC_RMR_RPIR			0x04000000
+ #define EMAC_RMR_PPP			0x02000000
+ #define EMAC_RMR_PME			0x01000000
+ #define EMAC_RMR_PMME			0x00800000
+@@ -127,6 +181,9 @@ typedef struct emac_regs {
+ #define EMAC_RMR_MIAE			0x00200000
+ #define EMAC_RMR_BAE			0x00100000
+ #define EMAC_RMR_MAE			0x00080000
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_RMR_BASE			0x00000000
++#else
+ #define EMAC_RMR_RFAF_2_32		0x00000001
+ #define EMAC_RMR_RFAF_4_64		0x00000002
+ #define EMAC_RMR_RFAF_8_128		0x00000003
+@@ -134,9 +191,21 @@ typedef struct emac_regs {
+ #define EMAC_RMR_RFAF_32_512		0x00000005
+ #define EMAC_RMR_RFAF_64_1024		0x00000006
+ #define EMAC_RMR_RFAF_128_2048		0x00000007
+-#define EMAC_RMR_BASE			(EMAC_RMR_IAE | EMAC_RMR_BAE)
++#define EMAC_RMR_BASE			EMAC_RMR_RFAF_128_2048
++#endif
+ 
+-/* Interrupt Status & enable Regs */
++/* EMACx_ISR & EMACx_ISER */
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_ISR_TXPE			0x00000000
++#define EMAC_ISR_RXPE			0x00000000
++#define EMAC_ISR_TXUE			0x00000000
++#define EMAC_ISR_RXOE			0x00000000
++#else
++#define EMAC_ISR_TXPE			0x20000000
++#define EMAC_ISR_RXPE			0x10000000
++#define EMAC_ISR_TXUE			0x08000000
++#define EMAC_ISR_RXOE			0x04000000
++#endif
+ #define EMAC_ISR_OVR			0x02000000
+ #define EMAC_ISR_PP			0x01000000
+ #define EMAC_ISR_BP			0x00800000
+@@ -147,53 +216,62 @@ typedef struct emac_regs {
+ #define EMAC_ISR_PTLE			0x00040000
+ #define EMAC_ISR_ORE			0x00020000
+ #define EMAC_ISR_IRE			0x00010000
+-#define EMAC_ISR_DBDM			0x00000200
+-#define EMAC_ISR_DB0			0x00000100
+-#define EMAC_ISR_SE0			0x00000080
+-#define EMAC_ISR_TE0			0x00000040
+-#define EMAC_ISR_DB1			0x00000020
+-#define EMAC_ISR_SE1			0x00000010
+-#define EMAC_ISR_TE1			0x00000008
++#define EMAC_ISR_SQE			0x00000080
++#define EMAC_ISR_TE			0x00000040
+ #define EMAC_ISR_MOS			0x00000002
+ #define EMAC_ISR_MOF			0x00000001
+ 
+-/* STA CONTROL REG */
++/* EMACx_STACR */
++#define EMAC_STACR_PHYD_MASK		0xffff
++#define EMAC_STACR_PHYD_SHIFT		16
+ #define EMAC_STACR_OC			0x00008000
+ #define EMAC_STACR_PHYE			0x00004000
+-#define EMAC_STACR_WRITE		0x00002000
+-#define EMAC_STACR_READ			0x00001000
+-#define EMAC_STACR_CLK_83MHZ		0x00000800	/* 0's for 50Mhz */
+-#define EMAC_STACR_CLK_66MHZ		0x00000400
+-#define EMAC_STACR_CLK_100MHZ		0x00000C00
+-
+-/* Transmit Request Threshold Register */
+-#define EMAC_TRTR_1600			0x18000000	/* 0's for 64 Bytes */
+-#define EMAC_TRTR_1024			0x0f000000
+-#define EMAC_TRTR_512			0x07000000
+-#define EMAC_TRTR_256			0x03000000
+-#define EMAC_TRTR_192			0x10000000
+-#define EMAC_TRTR_128			0x01000000
++#define EMAC_STACR_STAC_MASK		0x00003000
++#define EMAC_STACR_STAC_READ		0x00001000
++#define EMAC_STACR_STAC_WRITE		0x00002000
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_STACR_OPBC_MASK		0x00000C00
++#define EMAC_STACR_OPBC_50		0x00000000
++#define EMAC_STACR_OPBC_66		0x00000400
++#define EMAC_STACR_OPBC_83		0x00000800
++#define EMAC_STACR_OPBC_100		0x00000C00
++#define EMAC_STACR_OPBC(freq)		((freq) <= 50 ? EMAC_STACR_OPBC_50 : \
++					 (freq) <= 66 ? EMAC_STACR_OPBC_66 : \
++					 (freq) <= 83 ? EMAC_STACR_OPBC_83 : EMAC_STACR_OPBC_100)
++#define EMAC_STACR_BASE(opb)		EMAC_STACR_OPBC(opb)
++#else
++#define EMAC_STACR_BASE(opb)		0x00000000
++#endif
++#define EMAC_STACR_PCDA_MASK		0x1f
++#define EMAC_STACR_PCDA_SHIFT		5
++#define EMAC_STACR_PRA_MASK		0x1f
++
++/* EMACx_TRTR */
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_TRTR_SHIFT			27
++#else
++#define EMAC_TRTR_SHIFT			24
++#endif
++#define EMAC_TRTR(size)			((((size) >> 6) - 1) << EMAC_TRTR_SHIFT)
+ 
++/* EMACx_RWMR */
++#if !defined(CONFIG_IBM_EMAC4)
++#define EMAC_RWMR(l,h)			(((l) << 23) | ( ((h) & 0x1ff) << 7))	
++#else
++#define EMAC_RWMR(l,h)			(((l) << 22) | ( ((h) & 0x3ff) << 6))	
++#endif
++
++/* EMAC specific TX descriptor control fields (write access) */
+ #define EMAC_TX_CTRL_GFCS		0x0200
+ #define EMAC_TX_CTRL_GP			0x0100
+ #define EMAC_TX_CTRL_ISA		0x0080
+ #define EMAC_TX_CTRL_RSA		0x0040
+ #define EMAC_TX_CTRL_IVT		0x0020
+ #define EMAC_TX_CTRL_RVT		0x0010
+-#define EMAC_TX_CTRL_TAH_CSUM		0x000e	/* TAH only */
+-#define EMAC_TX_CTRL_TAH_SEG4		0x000a	/* TAH only */
+-#define EMAC_TX_CTRL_TAH_SEG3		0x0008	/* TAH only */
+-#define EMAC_TX_CTRL_TAH_SEG2		0x0006	/* TAH only */
+-#define EMAC_TX_CTRL_TAH_SEG1		0x0004	/* TAH only */
+-#define EMAC_TX_CTRL_TAH_SEG0		0x0002	/* TAH only */
+-#define EMAC_TX_CTRL_TAH_DIS		0x0000	/* TAH only */
+-
+-#define EMAC_TX_CTRL_DFLT ( \
+-	MAL_TX_CTRL_INTR | EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP )
++#define EMAC_TX_CTRL_TAH_CSUM		0x000e
+ 
+-/* madmal transmit status / Control bits */
++/* EMAC specific TX descriptor status fields (read access) */
+ #define EMAC_TX_ST_BFCS			0x0200
+-#define EMAC_TX_ST_BPP			0x0100
+ #define EMAC_TX_ST_LCS			0x0080
+ #define EMAC_TX_ST_ED			0x0040
+ #define EMAC_TX_ST_EC			0x0020
+@@ -202,8 +280,16 @@ typedef struct emac_regs {
+ #define EMAC_TX_ST_SC			0x0004
+ #define EMAC_TX_ST_UR			0x0002
+ #define EMAC_TX_ST_SQE			0x0001
++#if !defined(CONFIG_IBM_EMAC_TAH)
++#define EMAC_IS_BAD_TX(v)		((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \
++					 EMAC_TX_ST_EC | EMAC_TX_ST_LC | \
++					 EMAC_TX_ST_MC | EMAC_TX_ST_UR))
++#else
++#define EMAC_IS_BAD_TX(v)		((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \
++					 EMAC_TX_ST_EC | EMAC_TX_ST_LC))
++#endif					 
+ 
+-/* madmal receive status / Control bits */
++/* EMAC specific RX descriptor status fields (read access) */
+ #define EMAC_RX_ST_OE			0x0200
+ #define EMAC_RX_ST_PP			0x0100
+ #define EMAC_RX_ST_BP			0x0080
+@@ -214,54 +300,10 @@ typedef struct emac_regs {
+ #define EMAC_RX_ST_PTL			0x0004
+ #define EMAC_RX_ST_ORE			0x0002
+ #define EMAC_RX_ST_IRE			0x0001
+-#define EMAC_BAD_RX_PACKET		0x02ff
+-#define EMAC_CSUM_VER_ERROR		0x0003
+-
+-/* identify a bad rx packet dependent on emac features */
+-#ifdef CONFIG_IBM_EMAC4
+-#define EMAC_IS_BAD_RX_PACKET(desc) \
+-	(((desc & (EMAC_BAD_RX_PACKET & ~EMAC_CSUM_VER_ERROR)) || \
+-	((desc & EMAC_CSUM_VER_ERROR) == EMAC_RX_ST_ORE) || \
+-	((desc & EMAC_CSUM_VER_ERROR) == EMAC_RX_ST_IRE)))
+-#else
+-#define EMAC_IS_BAD_RX_PACKET(desc) \
+-	 (desc & EMAC_BAD_RX_PACKET)
+-#endif
+-
+-/* SoC implementation specific EMAC register defaults */
+-#if defined(CONFIG_440GP)
+-#define EMAC_RWMR_DEFAULT		0x80009000
+-#define EMAC_TMR0_DEFAULT		0x00000000
+-#define EMAC_TMR1_DEFAULT		0xf8640000
+-#elif defined(CONFIG_440GX)
+-#define EMAC_RWMR_DEFAULT		0x1000a200
+-#define EMAC_TMR0_DEFAULT		EMAC_TMR0_TFAE_2_32
+-#define EMAC_TMR1_DEFAULT		0xa00f0000
+-#elif defined(CONFIG_440SP)
+-#define EMAC_RWMR_DEFAULT		0x08002000
+-#define EMAC_TMR0_DEFAULT		EMAC_TMR0_TFAE_128_2048
+-#define EMAC_TMR1_DEFAULT		0xf8200000
+-#else
+-#define EMAC_RWMR_DEFAULT		0x0f002000
+-#define EMAC_TMR0_DEFAULT		0x00000000
+-#define EMAC_TMR1_DEFAULT		0x380f0000
+-#endif				/* CONFIG_440GP */
+-
+-/* Revision specific EMAC register defaults */
+-#ifdef CONFIG_IBM_EMAC4
+-#define EMAC_M1_DEFAULT			(EMAC_M1_BASE | \
+-					EMAC_M1_OPB_CLK_83 | \
+-					EMAC_M1_TX_MWSW)
+-#define EMAC_RMR_DEFAULT		(EMAC_RMR_BASE | \
+-					EMAC_RMR_RFAF_128_2048)
+-#define EMAC_TMR0_XMIT			(EMAC_TMR0_GNP0 | \
+-					EMAC_TMR0_DEFAULT)
+-#define EMAC_TRTR_DEFAULT		EMAC_TRTR_1024
+-#else				/* !CONFIG_IBM_EMAC4 */
+-#define EMAC_M1_DEFAULT			EMAC_M1_BASE
+-#define EMAC_RMR_DEFAULT		EMAC_RMR_BASE
+-#define EMAC_TMR0_XMIT			EMAC_TMR0_GNP0
+-#define EMAC_TRTR_DEFAULT		EMAC_TRTR_1600
+-#endif				/* CONFIG_IBM_EMAC4 */
+-
+-#endif
++#define EMAC_RX_TAH_BAD_CSUM		0x0003
++#define EMAC_BAD_RX_MASK		(EMAC_RX_ST_OE | EMAC_RX_ST_BP | \
++					 EMAC_RX_ST_RP | EMAC_RX_ST_SE | \
++					 EMAC_RX_ST_AE | EMAC_RX_ST_BFCS | \
++					 EMAC_RX_ST_PTL | EMAC_RX_ST_ORE | \
++					 EMAC_RX_ST_IRE )
++#endif /* __IBM_EMAC_H_ */
+diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
+--- a/drivers/net/ibm_emac/ibm_emac_core.c
++++ b/drivers/net/ibm_emac/ibm_emac_core.c
+@@ -1,13 +1,14 @@
+ /*
+- * ibm_emac_core.c
++ * drivers/net/ibm_emac/ibm_emac_core.c
+  *
+- * Ethernet driver for the built in ethernet on the IBM 4xx PowerPC
+- * processors.
+- * 
+- * (c) 2003 Benjamin Herrenschmidt <benh at kernel.crashing.org>
++ * Driver for PowerPC 4xx on-chip ethernet controller.
+  *
+- * Based on original work by
++ * Copyright (c) 2004, 2005 Zultys Technologies.
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
+  *
++ * Based on original work by
++ * 	Matt Porter <mporter at kernel.crashing.org>
++ *	(c) 2003 Benjamin Herrenschmidt <benh at kernel.crashing.org>
+  *      Armin Kuster <akuster at mvista.com>
+  * 	Johnnie Peters <jpeters at mvista.com>
+  *
+@@ -15,29 +16,24 @@
+  * under  the terms of  the GNU General  Public License as published by the
+  * Free Software Foundation;  either version 2 of the  License, or (at your
+  * option) any later version.
+- * TODO
+- *       - Check for races in the "remove" code path
+- *       - Add some Power Management to the MAC and the PHY
+- *       - Audit remaining of non-rewritten code (--BenH)
+- *       - Cleanup message display using msglevel mecanism
+- *       - Address all errata
+- *       - Audit all register update paths to ensure they
+- *         are being written post soft reset if required.
++ *
+  */
++
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/string.h>
+-#include <linux/timer.h>
+-#include <linux/ptrace.h>
+ #include <linux/errno.h>
+-#include <linux/ioport.h>
+-#include <linux/slab.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/init.h>
+ #include <linux/types.h>
+-#include <linux/dma-mapping.h>
++#include <linux/pci.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/crc32.h>
+ #include <linux/ethtool.h>
+ #include <linux/mii.h>
+ #include <linux/bitops.h>
+@@ -45,1691 +41,1893 @@
+ #include <asm/processor.h>
+ #include <asm/io.h>
+ #include <asm/dma.h>
+-#include <asm/irq.h>
+ #include <asm/uaccess.h>
+ #include <asm/ocp.h>
+ 
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/skbuff.h>
+-#include <linux/crc32.h>
+-
+ #include "ibm_emac_core.h"
+-
+-//#define MDIO_DEBUG(fmt) printk fmt
+-#define MDIO_DEBUG(fmt)
+-
+-//#define LINK_DEBUG(fmt) printk fmt
+-#define LINK_DEBUG(fmt)
+-
+-//#define PKT_DEBUG(fmt) printk fmt
+-#define PKT_DEBUG(fmt)
+-
+-#define DRV_NAME        "emac"
+-#define DRV_VERSION     "2.0"
+-#define DRV_AUTHOR      "Benjamin Herrenschmidt <benh at kernel.crashing.org>"
+-#define DRV_DESC        "IBM EMAC Ethernet driver"
++#include "ibm_emac_debug.h"
+ 
+ /*
+- * When mdio_idx >= 0, contains a list of emac ocp_devs
+- * that have had their initialization deferred until the
+- * common MDIO controller has been initialized.
++ * Lack of dma_unmap_???? calls is intentional.
++ *
++ * API-correct usage requires additional support state information to be 
++ * maintained for every RX and TX buffer descriptor (BD). Unfortunately, due to
++ * EMAC design (e.g. TX buffer passed from network stack can be split into
++ * several BDs, dma_map_single/dma_map_page can be used to map particular BD),
++ * maintaining such information will add additional overhead.
++ * Current DMA API implementation for 4xx processors only ensures cache coherency
++ * and dma_unmap_???? routines are empty and are likely to stay this way.
++ * I decided to omit dma_unmap_??? calls because I don't want to add additional
++ * complexity just for the sake of following some abstract API, when it doesn't
++ * add any real benefit to the driver. I understand that this decision maybe 
++ * controversial, but I really tried to make code API-correct and efficient 
++ * at the same time and didn't come up with code I liked :(.                --ebs
+  */
+-LIST_HEAD(emac_init_list);
+ 
+-MODULE_AUTHOR(DRV_AUTHOR);
++#define DRV_NAME        "emac"
++#define DRV_VERSION     "3.53"
++#define DRV_DESC        "PPC 4xx OCP EMAC driver"
++
+ MODULE_DESCRIPTION(DRV_DESC);
++MODULE_AUTHOR
++    ("Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>");
+ MODULE_LICENSE("GPL");
+ 
+-static int skb_res = SKB_RES;
+-module_param(skb_res, int, 0444);
+-MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n"
+-		 "The 405 handles a misaligned IP header fine but\n"
+-		 "this can help if you are routing to a tunnel or a\n"
+-		 "device that needs aligned data. 0..2");
+-
+-#define RGMII_PRIV(ocpdev) ((struct ibm_ocp_rgmii*)ocp_get_drvdata(ocpdev))
+-
+-static unsigned int rgmii_enable[] = {
+-	RGMII_RTBI,
+-	RGMII_RGMII,
+-	RGMII_TBI,
+-	RGMII_GMII
+-};
+-
+-static unsigned int rgmii_speed_mask[] = {
+-	RGMII_MII2_SPDMASK,
+-	RGMII_MII3_SPDMASK
+-};
+-
+-static unsigned int rgmii_speed100[] = {
+-	RGMII_MII2_100MB,
+-	RGMII_MII3_100MB
+-};
++/* minimum number of free TX descriptors required to wake up TX process */
++#define EMAC_TX_WAKEUP_THRESH		(NUM_TX_BUFF / 4)
+ 
+-static unsigned int rgmii_speed1000[] = {
+-	RGMII_MII2_1000MB,
+-	RGMII_MII3_1000MB
+-};
+-
+-#define ZMII_PRIV(ocpdev) ((struct ibm_ocp_zmii*)ocp_get_drvdata(ocpdev))
+-
+-static unsigned int zmii_enable[][4] = {
+-	{ZMII_SMII0, ZMII_RMII0, ZMII_MII0,
+-	 ~(ZMII_MDI1 | ZMII_MDI2 | ZMII_MDI3)},
+-	{ZMII_SMII1, ZMII_RMII1, ZMII_MII1,
+-	 ~(ZMII_MDI0 | ZMII_MDI2 | ZMII_MDI3)},
+-	{ZMII_SMII2, ZMII_RMII2, ZMII_MII2,
+-	 ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)},
+-	{ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)}
+-};
+-
+-static unsigned int mdi_enable[] = {
+-	ZMII_MDI0,
+-	ZMII_MDI1,
+-	ZMII_MDI2,
+-	ZMII_MDI3
+-};
+-
+-static unsigned int zmii_speed = 0x0;
+-static unsigned int zmii_speed100[] = {
+-	ZMII_MII0_100MB,
+-	ZMII_MII1_100MB,
+-	ZMII_MII2_100MB,
+-	ZMII_MII3_100MB
+-};
++/* If packet size is less than this number, we allocate small skb and copy packet 
++ * contents into it instead of just sending original big skb up
++ */
++#define EMAC_RX_COPY_THRESH		CONFIG_IBM_EMAC_RX_COPY_THRESHOLD
+ 
+ /* Since multiple EMACs share MDIO lines in various ways, we need
+  * to avoid re-using the same PHY ID in cases where the arch didn't
+  * setup precise phy_map entries
+  */
+-static u32 busy_phy_map = 0;
+-
+-/* If EMACs share a common MDIO device, this points to it */
+-static struct net_device *mdio_ndev = NULL;
++static u32 busy_phy_map;
+ 
+-struct emac_def_dev {
+-	struct list_head link;
+-	struct ocp_device *ocpdev;
+-	struct ibm_ocp_mal *mal;
+-};
+-
+-static struct net_device_stats *emac_stats(struct net_device *dev)
+-{
+-	struct ocp_enet_private *fep = dev->priv;
+-	return &fep->stats;
+-};
+-
+-static int
+-emac_init_rgmii(struct ocp_device *rgmii_dev, int input, int phy_mode)
++#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && (defined(CONFIG_405EP) || defined(CONFIG_440EP))
++/* 405EP has "EMAC to PHY Control Register" (CPC0_EPCTL) which can help us
++ * with PHY RX clock problem.
++ * 440EP has more sane SDR0_MFR register implementation than 440GX, which
++ * also allows controlling each EMAC clock
++ */
++static inline void EMAC_RX_CLK_TX(int idx)
+ {
+-	struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(rgmii_dev);
+-	const char *mode_name[] = { "RTBI", "RGMII", "TBI", "GMII" };
+-	int mode = -1;
++	unsigned long flags;
++	local_irq_save(flags);
+ 
+-	if (!rgmii) {
+-		rgmii = kmalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL);
++#if defined(CONFIG_405EP)
++	mtdcr(0xf3, mfdcr(0xf3) | (1 << idx));
++#else /* CONFIG_440EP */
++	SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) | (0x08000000 >> idx));
++#endif
+ 
+-		if (rgmii == NULL) {
+-			printk(KERN_ERR
+-			       "rgmii%d: Out of memory allocating RGMII structure!\n",
+-			       rgmii_dev->def->index);
+-			return -ENOMEM;
+-		}
++	local_irq_restore(flags);
++}
+ 
+-		memset(rgmii, 0, sizeof(*rgmii));
++static inline void EMAC_RX_CLK_DEFAULT(int idx)
++{
++	unsigned long flags;
++	local_irq_save(flags);
+ 
+-		rgmii->base =
+-		    (struct rgmii_regs *)ioremap(rgmii_dev->def->paddr,
+-						 sizeof(*rgmii->base));
+-		if (rgmii->base == NULL) {
+-			printk(KERN_ERR
+-			       "rgmii%d: Cannot ioremap bridge registers!\n",
+-			       rgmii_dev->def->index);
++#if defined(CONFIG_405EP)
++	mtdcr(0xf3, mfdcr(0xf3) & ~(1 << idx));
++#else /* CONFIG_440EP */
++	SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~(0x08000000 >> idx));
++#endif
+ 
+-			kfree(rgmii);
+-			return -ENOMEM;
+-		}
+-		ocp_set_drvdata(rgmii_dev, rgmii);
+-	}
++	local_irq_restore(flags);
++}
++#else
++#define EMAC_RX_CLK_TX(idx)		((void)0)
++#define EMAC_RX_CLK_DEFAULT(idx)	((void)0)
++#endif
+ 
+-	if (phy_mode) {
+-		switch (phy_mode) {
+-		case PHY_MODE_GMII:
+-			mode = GMII;
+-			break;
+-		case PHY_MODE_TBI:
+-			mode = TBI;
+-			break;
+-		case PHY_MODE_RTBI:
+-			mode = RTBI;
+-			break;
+-		case PHY_MODE_RGMII:
+-		default:
+-			mode = RGMII;
+-		}
+-		rgmii->base->fer &= ~RGMII_FER_MASK(input);
+-		rgmii->base->fer |= rgmii_enable[mode] << (4 * input);
+-	} else {
+-		switch ((rgmii->base->fer & RGMII_FER_MASK(input)) >> (4 *
+-								       input)) {
+-		case RGMII_RTBI:
+-			mode = RTBI;
+-			break;
+-		case RGMII_RGMII:
+-			mode = RGMII;
+-			break;
+-		case RGMII_TBI:
+-			mode = TBI;
+-			break;
+-		case RGMII_GMII:
+-			mode = GMII;
+-		}
+-	}
++#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && defined(CONFIG_440GX)
++/* We can switch Ethernet clock to the internal source through SDR0_MFR[ECS],
++ * unfortunately this is less flexible than 440EP case, because it's a global 
++ * setting for all EMACs, therefore we do this clock trick only during probe.
++ */
++#define EMAC_CLK_INTERNAL		SDR_WRITE(DCRN_SDR_MFR, \
++					    SDR_READ(DCRN_SDR_MFR) | 0x08000000)
++#define EMAC_CLK_EXTERNAL		SDR_WRITE(DCRN_SDR_MFR, \
++					    SDR_READ(DCRN_SDR_MFR) & ~0x08000000)
++#else
++#define EMAC_CLK_INTERNAL		((void)0)
++#define EMAC_CLK_EXTERNAL		((void)0)
++#endif
+ 
+-	/* Set mode to RGMII if nothing valid is detected */
+-	if (mode < 0)
+-		mode = RGMII;
++/* I don't want to litter system log with timeout errors 
++ * when we have brain-damaged PHY.
++ */
++static inline void emac_report_timeout_error(struct ocp_enet_private *dev,
++					     const char *error)
++{
++#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX)
++	DBG("%d: %s" NL, dev->def->index, error);
++#else
++	if (net_ratelimit())
++		printk(KERN_ERR "emac%d: %s\n", dev->def->index, error);
++#endif
++}
+ 
+-	printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n",
+-	       rgmii_dev->def->index, input, mode_name[mode]);
++/* PHY polling intervals */
++#define PHY_POLL_LINK_ON	HZ
++#define PHY_POLL_LINK_OFF	(HZ / 5)
++
++/* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */
++static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {
++	"rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum",
++	"tx_packets_csum", "tx_undo", "rx_dropped_stack", "rx_dropped_oom",
++	"rx_dropped_error", "rx_dropped_resize", "rx_dropped_mtu",
++	"rx_stopped", "rx_bd_errors", "rx_bd_overrun", "rx_bd_bad_packet",
++	"rx_bd_runt_packet", "rx_bd_short_event", "rx_bd_alignment_error",
++	"rx_bd_bad_fcs", "rx_bd_packet_too_long", "rx_bd_out_of_range",
++	"rx_bd_in_range", "rx_parity", "rx_fifo_overrun", "rx_overrun",
++	"rx_bad_packet", "rx_runt_packet", "rx_short_event",
++	"rx_alignment_error", "rx_bad_fcs", "rx_packet_too_long",
++	"rx_out_of_range", "rx_in_range", "tx_dropped", "tx_bd_errors",
++	"tx_bd_bad_fcs", "tx_bd_carrier_loss", "tx_bd_excessive_deferral",
++	"tx_bd_excessive_collisions", "tx_bd_late_collision",
++	"tx_bd_multple_collisions", "tx_bd_single_collision",
++	"tx_bd_underrun", "tx_bd_sqe", "tx_parity", "tx_underrun", "tx_sqe",
++	"tx_errors"
++};
+ 
+-	rgmii->mode[input] = mode;
+-	rgmii->users++;
++static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs);
++static void emac_clean_tx_ring(struct ocp_enet_private *dev);
+ 
+-	return 0;
++static inline int emac_phy_supports_gige(int phy_mode)
++{
++	return  phy_mode == PHY_MODE_GMII ||
++		phy_mode == PHY_MODE_RGMII ||
++		phy_mode == PHY_MODE_TBI ||
++		phy_mode == PHY_MODE_RTBI;
+ }
+ 
+-static void
+-emac_rgmii_port_speed(struct ocp_device *ocpdev, int input, int speed)
++static inline int emac_phy_gpcs(int phy_mode)
+ {
+-	struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(ocpdev);
+-	unsigned int rgmii_speed;
++	return  phy_mode == PHY_MODE_TBI ||
++		phy_mode == PHY_MODE_RTBI;
++}
+ 
+-	rgmii_speed = in_be32(&rgmii->base->ssr);
++static inline void emac_tx_enable(struct ocp_enet_private *dev)
++{
++	struct emac_regs *p = dev->emacp;
++	unsigned long flags;
++	u32 r;
+ 
+-	rgmii_speed &= ~rgmii_speed_mask[input];
++	local_irq_save(flags);
+ 
+-	if (speed == 1000)
+-		rgmii_speed |= rgmii_speed1000[input];
+-	else if (speed == 100)
+-		rgmii_speed |= rgmii_speed100[input];
++	DBG("%d: tx_enable" NL, dev->def->index);
+ 
+-	out_be32(&rgmii->base->ssr, rgmii_speed);
++	r = in_be32(&p->mr0);
++	if (!(r & EMAC_MR0_TXE))
++		out_be32(&p->mr0, r | EMAC_MR0_TXE);
++	local_irq_restore(flags);
+ }
+ 
+-static void emac_close_rgmii(struct ocp_device *ocpdev)
++static void emac_tx_disable(struct ocp_enet_private *dev)
+ {
+-	struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(ocpdev);
+-	BUG_ON(!rgmii || rgmii->users == 0);
++	struct emac_regs *p = dev->emacp;
++	unsigned long flags;
++	u32 r;
++
++	local_irq_save(flags);
++
++	DBG("%d: tx_disable" NL, dev->def->index);
+ 
+-	if (!--rgmii->users) {
+-		ocp_set_drvdata(ocpdev, NULL);
+-		iounmap((void *)rgmii->base);
+-		kfree(rgmii);
++	r = in_be32(&p->mr0);
++	if (r & EMAC_MR0_TXE) {
++		int n = 300;
++		out_be32(&p->mr0, r & ~EMAC_MR0_TXE);
++		while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n)
++			--n;
++		if (unlikely(!n))
++			emac_report_timeout_error(dev, "TX disable timeout");
+ 	}
++	local_irq_restore(flags);
+ }
+ 
+-static int emac_init_zmii(struct ocp_device *zmii_dev, int input, int phy_mode)
++static void emac_rx_enable(struct ocp_enet_private *dev)
+ {
+-	struct ibm_ocp_zmii *zmii = ZMII_PRIV(zmii_dev);
+-	const char *mode_name[] = { "SMII", "RMII", "MII" };
+-	int mode = -1;
++	struct emac_regs *p = dev->emacp;
++	unsigned long flags;
++	u32 r;
+ 
+-	if (!zmii) {
+-		zmii = kmalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL);
+-		if (zmii == NULL) {
+-			printk(KERN_ERR
+-			       "zmii%d: Out of memory allocating ZMII structure!\n",
+-			       zmii_dev->def->index);
+-			return -ENOMEM;
+-		}
+-		memset(zmii, 0, sizeof(*zmii));
+-
+-		zmii->base =
+-		    (struct zmii_regs *)ioremap(zmii_dev->def->paddr,
+-						sizeof(*zmii->base));
+-		if (zmii->base == NULL) {
+-			printk(KERN_ERR
+-			       "zmii%d: Cannot ioremap bridge registers!\n",
+-			       zmii_dev->def->index);
++	local_irq_save(flags);
++	if (unlikely(dev->commac.rx_stopped))
++		goto out;
+ 
+-			kfree(zmii);
+-			return -ENOMEM;
+-		}
+-		ocp_set_drvdata(zmii_dev, zmii);
+-	}
++	DBG("%d: rx_enable" NL, dev->def->index);
+ 
+-	if (phy_mode) {
+-		switch (phy_mode) {
+-		case PHY_MODE_MII:
+-			mode = MII;
+-			break;
+-		case PHY_MODE_RMII:
+-			mode = RMII;
+-			break;
+-		case PHY_MODE_SMII:
+-		default:
+-			mode = SMII;
+-		}
+-		zmii->base->fer &= ~ZMII_FER_MASK(input);
+-		zmii->base->fer |= zmii_enable[input][mode];
+-	} else {
+-		switch ((zmii->base->fer & ZMII_FER_MASK(input)) << (4 * input)) {
+-		case ZMII_MII0:
+-			mode = MII;
+-			break;
+-		case ZMII_RMII0:
+-			mode = RMII;
+-			break;
+-		case ZMII_SMII0:
+-			mode = SMII;
++	r = in_be32(&p->mr0);
++	if (!(r & EMAC_MR0_RXE)) {
++		if (unlikely(!(r & EMAC_MR0_RXI))) {
++			/* Wait if previous async disable is still in progress */
++			int n = 100;
++			while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
++				--n;
++			if (unlikely(!n))
++				emac_report_timeout_error(dev,
++							  "RX disable timeout");
+ 		}
++		out_be32(&p->mr0, r | EMAC_MR0_RXE);
+ 	}
+-
+-	/* Set mode to SMII if nothing valid is detected */
+-	if (mode < 0)
+-		mode = SMII;
+-
+-	printk(KERN_NOTICE "zmii%d: input %d in %s mode\n",
+-	       zmii_dev->def->index, input, mode_name[mode]);
+-
+-	zmii->mode[input] = mode;
+-	zmii->users++;
+-
+-	return 0;
++      out:
++	local_irq_restore(flags);
+ }
+ 
+-static void emac_enable_zmii_port(struct ocp_device *ocpdev, int input)
++static void emac_rx_disable(struct ocp_enet_private *dev)
+ {
+-	u32 mask;
+-	struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
+-
+-	mask = in_be32(&zmii->base->fer);
+-	mask &= zmii_enable[input][MDI];	/* turn all non enabled MDI's off */
+-	mask |= zmii_enable[input][zmii->mode[input]] | mdi_enable[input];
+-	out_be32(&zmii->base->fer, mask);
+-}
++	struct emac_regs *p = dev->emacp;
++	unsigned long flags;
++	u32 r;
+ 
+-static void
+-emac_zmii_port_speed(struct ocp_device *ocpdev, int input, int speed)
+-{
+-	struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
++	local_irq_save(flags);
+ 
+-	if (speed == 100)
+-		zmii_speed |= zmii_speed100[input];
+-	else
+-		zmii_speed &= ~zmii_speed100[input];
++	DBG("%d: rx_disable" NL, dev->def->index);
+ 
+-	out_be32(&zmii->base->ssr, zmii_speed);
++	r = in_be32(&p->mr0);
++	if (r & EMAC_MR0_RXE) {
++		int n = 300;
++		out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
++		while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
++			--n;
++		if (unlikely(!n))
++			emac_report_timeout_error(dev, "RX disable timeout");
++	}
++	local_irq_restore(flags);
+ }
+ 
+-static void emac_close_zmii(struct ocp_device *ocpdev)
++static inline void emac_rx_disable_async(struct ocp_enet_private *dev)
+ {
+-	struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
+-	BUG_ON(!zmii || zmii->users == 0);
++	struct emac_regs *p = dev->emacp;
++	unsigned long flags;
++	u32 r;
+ 
+-	if (!--zmii->users) {
+-		ocp_set_drvdata(ocpdev, NULL);
+-		iounmap((void *)zmii->base);
+-		kfree(zmii);
+-	}
++	local_irq_save(flags);
++
++	DBG("%d: rx_disable_async" NL, dev->def->index);
++
++	r = in_be32(&p->mr0);
++	if (r & EMAC_MR0_RXE)
++		out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
++	local_irq_restore(flags);
+ }
+ 
+-int emac_phy_read(struct net_device *dev, int mii_id, int reg)
++static int emac_reset(struct ocp_enet_private *dev)
+ {
+-	int count;
+-	uint32_t stacr;
+-	struct ocp_enet_private *fep = dev->priv;
+-	emac_t *emacp = fep->emacp;
++	struct emac_regs *p = dev->emacp;
++	unsigned long flags;
++	int n = 20;
+ 
+-	MDIO_DEBUG(("%s: phy_read, id: 0x%x, reg: 0x%x\n", dev->name, mii_id,
+-		    reg));
++	DBG("%d: reset" NL, dev->def->index);
+ 
+-	/* Enable proper ZMII port */
+-	if (fep->zmii_dev)
+-		emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input);
++	local_irq_save(flags);
+ 
+-	/* Use the EMAC that has the MDIO port */
+-	if (fep->mdio_dev) {
+-		dev = fep->mdio_dev;
+-		fep = dev->priv;
+-		emacp = fep->emacp;
++	if (!dev->reset_failed) {
++		/* 40x erratum suggests stopping RX channel before reset,
++		 * we stop TX as well
++		 */
++		emac_rx_disable(dev);
++		emac_tx_disable(dev);
+ 	}
+ 
+-	count = 0;
+-	while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
+-					&& (count++ < MDIO_DELAY))
+-		udelay(1);
+-	MDIO_DEBUG((" (count was %d)\n", count));
++	out_be32(&p->mr0, EMAC_MR0_SRST);
++	while ((in_be32(&p->mr0) & EMAC_MR0_SRST) && n)
++		--n;
++	local_irq_restore(flags);
+ 
+-	if ((stacr & EMAC_STACR_OC) == 0) {
+-		printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name);
+-		return -1;
++	if (n) {
++		dev->reset_failed = 0;
++		return 0;
++	} else {
++		emac_report_timeout_error(dev, "reset timeout");
++		dev->reset_failed = 1;
++		return -ETIMEDOUT;
+ 	}
++}
+ 
+-	/* Clear the speed bits and make a read request to the PHY */
+-	stacr = ((EMAC_STACR_READ | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ);
+-	stacr |= ((mii_id & 0x1F) << 5);
++static void emac_hash_mc(struct ocp_enet_private *dev)
++{
++	struct emac_regs *p = dev->emacp;
++	u16 gaht[4] = { 0 };
++	struct dev_mc_list *dmi;
+ 
+-	out_be32(&emacp->em0stacr, stacr);
++	DBG("%d: hash_mc %d" NL, dev->def->index, dev->ndev->mc_count);
+ 
+-	count = 0;
+-	while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
+-					&& (count++ < MDIO_DELAY))
+-		udelay(1);
+-	MDIO_DEBUG((" (count was %d)\n", count));
++	for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
++		int bit;
++		DBG2("%d: mc %02x:%02x:%02x:%02x:%02x:%02x" NL,
++		     dev->def->index,
++		     dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
++		     dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
+ 
+-	if ((stacr & EMAC_STACR_OC) == 0) {
+-		printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name);
+-		return -1;
++		bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26);
++		gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f);
+ 	}
++	out_be32(&p->gaht1, gaht[0]);
++	out_be32(&p->gaht2, gaht[1]);
++	out_be32(&p->gaht3, gaht[2]);
++	out_be32(&p->gaht4, gaht[3]);
++}
+ 
+-	/* Check for a read error */
+-	if (stacr & EMAC_STACR_PHYE) {
+-		MDIO_DEBUG(("EMAC MDIO PHY error !\n"));
+-		return -1;
+-	}
++static inline u32 emac_iff2rmr(struct net_device *ndev)
++{
++	u32 r = EMAC_RMR_SP | EMAC_RMR_SFCS | EMAC_RMR_IAE | EMAC_RMR_BAE |
++	    EMAC_RMR_BASE;
+ 
+-	MDIO_DEBUG((" -> 0x%x\n", stacr >> 16));
++	if (ndev->flags & IFF_PROMISC)
++		r |= EMAC_RMR_PME;
++	else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32)
++		r |= EMAC_RMR_PMME;
++	else if (ndev->mc_count > 0)
++		r |= EMAC_RMR_MAE;
++
++	return r;
++}
+ 
+-	return (stacr >> 16);
++static inline int emac_opb_mhz(void)
++{
++	return (ocp_sys_info.opb_bus_freq + 500000) / 1000000;
+ }
+ 
+-void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data)
++/* BHs disabled */
++static int emac_configure(struct ocp_enet_private *dev)
+ {
+-	int count;
+-	uint32_t stacr;
+-	struct ocp_enet_private *fep = dev->priv;
+-	emac_t *emacp = fep->emacp;
++	struct emac_regs *p = dev->emacp;
++	struct net_device *ndev = dev->ndev;
++	int gige;
++	u32 r;
+ 
+-	MDIO_DEBUG(("%s phy_write, id: 0x%x, reg: 0x%x, data: 0x%x\n",
+-		    dev->name, mii_id, reg, data));
++	DBG("%d: configure" NL, dev->def->index);
+ 
+-	/* Enable proper ZMII port */
+-	if (fep->zmii_dev)
+-		emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input);
++	if (emac_reset(dev) < 0)
++		return -ETIMEDOUT;
+ 
+-	/* Use the EMAC that has the MDIO port */
+-	if (fep->mdio_dev) {
+-		dev = fep->mdio_dev;
+-		fep = dev->priv;
+-		emacp = fep->emacp;
+-	}
++	tah_reset(dev->tah_dev);
+ 
+-	count = 0;
+-	while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
+-					&& (count++ < MDIO_DELAY))
+-		udelay(1);
+-	MDIO_DEBUG((" (count was %d)\n", count));
++	/* Mode register */
++	r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;
++	if (dev->phy.duplex == DUPLEX_FULL)
++		r |= EMAC_MR1_FDE;
++	switch (dev->phy.speed) {
++	case SPEED_1000:
++		if (emac_phy_gpcs(dev->phy.mode)) {
++			r |= EMAC_MR1_MF_1000GPCS |
++			    EMAC_MR1_MF_IPPA(dev->phy.address);
+ 
+-	if ((stacr & EMAC_STACR_OC) == 0) {
+-		printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
+-		return;
++			/* Put some arbitrary OUI, Manuf & Rev IDs so we can
++			 * identify this GPCS PHY later.
++			 */
++			out_be32(&p->ipcr, 0xdeadbeef);
++		} else
++			r |= EMAC_MR1_MF_1000;
++		r |= EMAC_MR1_RFS_16K;
++		gige = 1;
++		
++		if (dev->ndev->mtu > ETH_DATA_LEN)
++			r |= EMAC_MR1_JPSM;
++		break;
++	case SPEED_100:
++		r |= EMAC_MR1_MF_100;
++		/* Fall through */
++	default:
++		r |= EMAC_MR1_RFS_4K;
++		gige = 0;
++		break;
+ 	}
+ 
+-	/* Clear the speed bits and make a read request to the PHY */
++	if (dev->rgmii_dev)
++		rgmii_set_speed(dev->rgmii_dev, dev->rgmii_input,
++				dev->phy.speed);
++	else
++		zmii_set_speed(dev->zmii_dev, dev->zmii_input, dev->phy.speed);
+ 
+-	stacr = ((EMAC_STACR_WRITE | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ);
+-	stacr |= ((mii_id & 0x1f) << 5) | ((data & 0xffff) << 16);
++#if !defined(CONFIG_40x)
++	/* on 40x erratum forces us to NOT use integrated flow control, 
++	 * let's hope it works on 44x ;)
++	 */
++	if (dev->phy.duplex == DUPLEX_FULL) {
++		if (dev->phy.pause)
++			r |= EMAC_MR1_EIFC | EMAC_MR1_APP;
++		else if (dev->phy.asym_pause)
++			r |= EMAC_MR1_APP;
++	}
++#endif
++	out_be32(&p->mr1, r);
+ 
+-	out_be32(&emacp->em0stacr, stacr);
++	/* Set individual MAC address */
++	out_be32(&p->iahr, (ndev->dev_addr[0] << 8) | ndev->dev_addr[1]);
++	out_be32(&p->ialr, (ndev->dev_addr[2] << 24) |
++		 (ndev->dev_addr[3] << 16) | (ndev->dev_addr[4] << 8) |
++		 ndev->dev_addr[5]);
++
++	/* VLAN Tag Protocol ID */
++	out_be32(&p->vtpid, 0x8100);
++
++	/* Receive mode register */
++	r = emac_iff2rmr(ndev);
++	if (r & EMAC_RMR_MAE)
++		emac_hash_mc(dev);
++	out_be32(&p->rmr, r);
++
++	/* FIFOs thresholds */
++	r = EMAC_TMR1((EMAC_MAL_BURST_SIZE / EMAC_FIFO_ENTRY_SIZE) + 1,
++		      EMAC_TX_FIFO_SIZE / 2 / EMAC_FIFO_ENTRY_SIZE);
++	out_be32(&p->tmr1, r);
++	out_be32(&p->trtr, EMAC_TRTR(EMAC_TX_FIFO_SIZE / 2));
++
++	/* PAUSE frame is sent when RX FIFO reaches its high-water mark,
++	   there should be still enough space in FIFO to allow the our link
++	   partner time to process this frame and also time to send PAUSE 
++	   frame itself.
++
++	   Here is the worst case scenario for the RX FIFO "headroom"
++	   (from "The Switch Book") (100Mbps, without preamble, inter-frame gap):
++
++	   1) One maximum-length frame on TX                    1522 bytes
++	   2) One PAUSE frame time                                64 bytes
++	   3) PAUSE frame decode time allowance                   64 bytes
++	   4) One maximum-length frame on RX                    1522 bytes
++	   5) Round-trip propagation delay of the link (100Mb)    15 bytes
++	   ----------       
++	   3187 bytes
+ 
+-	count = 0;
+-	while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
+-					&& (count++ < MDIO_DELAY))
+-		udelay(1);
+-	MDIO_DEBUG((" (count was %d)\n", count));
++	   I chose to set high-water mark to RX_FIFO_SIZE / 4 (1024 bytes)
++	   low-water mark  to RX_FIFO_SIZE / 8 (512 bytes)
++	 */
++	r = EMAC_RWMR(EMAC_RX_FIFO_SIZE(gige) / 8 / EMAC_FIFO_ENTRY_SIZE,
++		      EMAC_RX_FIFO_SIZE(gige) / 4 / EMAC_FIFO_ENTRY_SIZE);
++	out_be32(&p->rwmr, r);
++
++	/* Set PAUSE timer to the maximum */
++	out_be32(&p->ptr, 0xffff);
++
++	/* IRQ sources */
++	out_be32(&p->iser, EMAC_ISR_TXPE | EMAC_ISR_RXPE | /* EMAC_ISR_TXUE |
++		 EMAC_ISR_RXOE | */ EMAC_ISR_OVR | EMAC_ISR_BP | EMAC_ISR_SE |
++		 EMAC_ISR_ALE | EMAC_ISR_BFCS | EMAC_ISR_PTLE | EMAC_ISR_ORE |
++		 EMAC_ISR_IRE | EMAC_ISR_TE);
++		 
++	/* We need to take GPCS PHY out of isolate mode after EMAC reset */
++	if (emac_phy_gpcs(dev->phy.mode)) 
++		mii_reset_phy(&dev->phy);
++		 
++	return 0;
++}
+ 
+-	if ((stacr & EMAC_STACR_OC) == 0)
+-		printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
++/* BHs disabled */
++static void emac_reinitialize(struct ocp_enet_private *dev)
++{
++	DBG("%d: reinitialize" NL, dev->def->index);
+ 
+-	/* Check for a write error */
+-	if ((stacr & EMAC_STACR_PHYE) != 0) {
+-		MDIO_DEBUG(("EMAC MDIO PHY error !\n"));
++	if (!emac_configure(dev)) {
++		emac_tx_enable(dev);
++		emac_rx_enable(dev);
+ 	}
+ }
+ 
+-static void emac_txeob_dev(void *param, u32 chanmask)
++/* BHs disabled */
++static void emac_full_tx_reset(struct net_device *ndev)
+ {
+-	struct net_device *dev = param;
+-	struct ocp_enet_private *fep = dev->priv;
+-	unsigned long flags;
++	struct ocp_enet_private *dev = ndev->priv;
++	struct ocp_func_emac_data *emacdata = dev->def->additions;
+ 
+-	spin_lock_irqsave(&fep->lock, flags);
++	DBG("%d: full_tx_reset" NL, dev->def->index);
+ 
+-	PKT_DEBUG(("emac_txeob_dev() entry, tx_cnt: %d\n", fep->tx_cnt));
++	emac_tx_disable(dev);
++	mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan);
++	emac_clean_tx_ring(dev);
++	dev->tx_cnt = dev->tx_slot = dev->ack_slot = 0;
+ 
+-	while (fep->tx_cnt &&
+-	       !(fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_READY)) {
++	emac_configure(dev);
+ 
+-		if (fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_LAST) {
+-			/* Tell the system the transmit completed. */
+-			dma_unmap_single(&fep->ocpdev->dev,
+-					 fep->tx_desc[fep->ack_slot].data_ptr,
+-					 fep->tx_desc[fep->ack_slot].data_len,
+-					 DMA_TO_DEVICE);
+-			dev_kfree_skb_irq(fep->tx_skb[fep->ack_slot]);
++	mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan);
++	emac_tx_enable(dev);
++	emac_rx_enable(dev);
+ 
+-			if (fep->tx_desc[fep->ack_slot].ctrl &
+-			    (EMAC_TX_ST_EC | EMAC_TX_ST_MC | EMAC_TX_ST_SC))
+-				fep->stats.collisions++;
+-		}
+-
+-		fep->tx_skb[fep->ack_slot] = (struct sk_buff *)NULL;
+-		if (++fep->ack_slot == NUM_TX_BUFF)
+-			fep->ack_slot = 0;
+-
+-		fep->tx_cnt--;
+-	}
+-	if (fep->tx_cnt < NUM_TX_BUFF)
+-		netif_wake_queue(dev);
+-
+-	PKT_DEBUG(("emac_txeob_dev() exit, tx_cnt: %d\n", fep->tx_cnt));
+-
+-	spin_unlock_irqrestore(&fep->lock, flags);
++	netif_wake_queue(ndev);
+ }
+ 
+-/*
+-  Fill/Re-fill the rx chain with valid ctrl/ptrs.
+-  This function will fill from rx_slot up to the parm end.
+-  So to completely fill the chain pre-set rx_slot to 0 and
+-  pass in an end of 0.
+- */
+-static void emac_rx_fill(struct net_device *dev, int end)
++static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg)
+ {
+-	int i;
+-	struct ocp_enet_private *fep = dev->priv;
++	struct emac_regs *p = dev->emacp;
++	u32 r;
++	int n;
+ 
+-	i = fep->rx_slot;
+-	do {
+-		/* We don't want the 16 bytes skb_reserve done by dev_alloc_skb,
+-		 * it breaks our cache line alignement. However, we still allocate
+-		 * +16 so that we end up allocating the exact same size as
+-		 * dev_alloc_skb() would do.
+-		 * Also, because of the skb_res, the max DMA size we give to EMAC
+-		 * is slighly wrong, causing it to potentially DMA 2 more bytes
+-		 * from a broken/oversized packet. These 16 bytes will take care
+-		 * that we don't walk on somebody else toes with that.
+-		 */
+-		fep->rx_skb[i] =
+-		    alloc_skb(fep->rx_buffer_size + 16, GFP_ATOMIC);
++	DBG2("%d: mdio_read(%02x,%02x)" NL, dev->def->index, id, reg);
+ 
+-		if (fep->rx_skb[i] == NULL) {
+-			/* Keep rx_slot here, the next time clean/fill is called
+-			 * we will try again before the MAL wraps back here
+-			 * If the MAL tries to use this descriptor with
+-			 * the EMPTY bit off it will cause the
+-			 * rxde interrupt.  That is where we will
+-			 * try again to allocate an sk_buff.
+-			 */
+-			break;
++	/* Enable proper MDIO port */
++	zmii_enable_mdio(dev->zmii_dev, dev->zmii_input);
+ 
+-		}
+-
+-		if (skb_res)
+-			skb_reserve(fep->rx_skb[i], skb_res);
++	/* Wait for management interface to become idle */
++	n = 10;
++	while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) {
++		udelay(1);
++		if (!--n)
++			goto to;
++	}
+ 
+-		/* We must NOT dma_map_single the cache line right after the
+-		 * buffer, so we must crop our sync size to account for the
+-		 * reserved space
+-		 */
+-		fep->rx_desc[i].data_ptr =
+-		    (unsigned char *)dma_map_single(&fep->ocpdev->dev,
+-						    (void *)fep->rx_skb[i]->
+-						    data,
+-						    fep->rx_buffer_size -
+-						    skb_res, DMA_FROM_DEVICE);
+-
+-		/*
+-		 * Some 4xx implementations use the previously
+-		 * reserved bits in data_len to encode the MS
+-		 * 4-bits of a 36-bit physical address (ERPN)
+-		 * This must be initialized.
+-		 */
+-		fep->rx_desc[i].data_len = 0;
+-		fep->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR |
+-		    (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
++	/* Issue read command */
++	out_be32(&p->stacr,
++		 EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_READ |
++		 (reg & EMAC_STACR_PRA_MASK)
++		 | ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT));
++
++	/* Wait for read to complete */
++	n = 100;
++	while (!((r = in_be32(&p->stacr)) & EMAC_STACR_OC)) {
++		udelay(1);
++		if (!--n)
++			goto to;
++	}
+ 
+-	} while ((i = (i + 1) % NUM_RX_BUFF) != end);
++	if (unlikely(r & EMAC_STACR_PHYE)) {
++		DBG("%d: mdio_read(%02x, %02x) failed" NL, dev->def->index,
++		    id, reg);
++		return -EREMOTEIO;
++	}
+ 
+-	fep->rx_slot = i;
++	r = ((r >> EMAC_STACR_PHYD_SHIFT) & EMAC_STACR_PHYD_MASK);
++	DBG2("%d: mdio_read -> %04x" NL, dev->def->index, r);
++	return r;
++      to:
++	DBG("%d: MII management interface timeout (read)" NL, dev->def->index);
++	return -ETIMEDOUT;
+ }
+ 
+-static void
+-emac_rx_csum(struct net_device *dev, unsigned short ctrl, struct sk_buff *skb)
++static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg,
++			      u16 val)
+ {
+-	struct ocp_enet_private *fep = dev->priv;
++	struct emac_regs *p = dev->emacp;
++	int n;
++
++	DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg,
++	     val);
+ 
+-	/* Exit if interface has no TAH engine */
+-	if (!fep->tah_dev) {
+-		skb->ip_summed = CHECKSUM_NONE;
+-		return;
++	/* Enable proper MDIO port */
++	zmii_enable_mdio(dev->zmii_dev, dev->zmii_input);
++
++	/* Wait for management interface to be idle */
++	n = 10;
++	while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) {
++		udelay(1);
++		if (!--n)
++			goto to;
+ 	}
+ 
+-	/* Check for TCP/UDP/IP csum error */
+-	if (ctrl & EMAC_CSUM_VER_ERROR) {
+-		/* Let the stack verify checksum errors */
+-		skb->ip_summed = CHECKSUM_NONE;
+-/*		adapter->hw_csum_err++; */
+-	} else {
+-		/* Csum is good */
+-		skb->ip_summed = CHECKSUM_UNNECESSARY;
+-/*		adapter->hw_csum_good++; */
++	/* Issue write command */
++	out_be32(&p->stacr,
++		 EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_WRITE |
++		 (reg & EMAC_STACR_PRA_MASK) |
++		 ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT) |
++		 (val << EMAC_STACR_PHYD_SHIFT));
++
++	/* Wait for write to complete */
++	n = 100;
++	while (!(in_be32(&p->stacr) & EMAC_STACR_OC)) {
++		udelay(1);
++		if (!--n)
++			goto to;
+ 	}
++	return;
++      to:
++	DBG("%d: MII management interface timeout (write)" NL, dev->def->index);
+ }
+ 
+-static int emac_rx_clean(struct net_device *dev)
++static int emac_mdio_read(struct net_device *ndev, int id, int reg)
+ {
+-	int i, b, bnum = 0, buf[6];
+-	int error, frame_length;
+-	struct ocp_enet_private *fep = dev->priv;
+-	unsigned short ctrl;
+-
+-	i = fep->rx_slot;
+-
+-	PKT_DEBUG(("emac_rx_clean() entry, rx_slot: %d\n", fep->rx_slot));
+-
+-	do {
+-		if (fep->rx_skb[i] == NULL)
+-			continue;	/*we have already handled the packet but haved failed to alloc */
+-		/* 
+-		   since rx_desc is in uncached mem we don't keep reading it directly 
+-		   we pull out a local copy of ctrl and do the checks on the copy.
+-		 */
+-		ctrl = fep->rx_desc[i].ctrl;
+-		if (ctrl & MAL_RX_CTRL_EMPTY)
+-			break;	/*we don't have any more ready packets */
+-
+-		if (EMAC_IS_BAD_RX_PACKET(ctrl)) {
+-			fep->stats.rx_errors++;
+-			fep->stats.rx_dropped++;
+-
+-			if (ctrl & EMAC_RX_ST_OE)
+-				fep->stats.rx_fifo_errors++;
+-			if (ctrl & EMAC_RX_ST_AE)
+-				fep->stats.rx_frame_errors++;
+-			if (ctrl & EMAC_RX_ST_BFCS)
+-				fep->stats.rx_crc_errors++;
+-			if (ctrl & (EMAC_RX_ST_RP | EMAC_RX_ST_PTL |
+-				    EMAC_RX_ST_ORE | EMAC_RX_ST_IRE))
+-				fep->stats.rx_length_errors++;
+-		} else {
+-			if ((ctrl & (MAL_RX_CTRL_FIRST | MAL_RX_CTRL_LAST)) ==
+-			    (MAL_RX_CTRL_FIRST | MAL_RX_CTRL_LAST)) {
+-				/* Single descriptor packet */
+-				emac_rx_csum(dev, ctrl, fep->rx_skb[i]);
+-				/* Send the skb up the chain. */
+-				frame_length = fep->rx_desc[i].data_len - 4;
+-				skb_put(fep->rx_skb[i], frame_length);
+-				fep->rx_skb[i]->dev = dev;
+-				fep->rx_skb[i]->protocol =
+-				    eth_type_trans(fep->rx_skb[i], dev);
+-				error = netif_rx(fep->rx_skb[i]);
+-
+-				if ((error == NET_RX_DROP) ||
+-				    (error == NET_RX_BAD)) {
+-					fep->stats.rx_dropped++;
+-				} else {
+-					fep->stats.rx_packets++;
+-					fep->stats.rx_bytes += frame_length;
+-				}
+-				fep->rx_skb[i] = NULL;
+-			} else {
+-				/* Multiple descriptor packet */
+-				if (ctrl & MAL_RX_CTRL_FIRST) {
+-					if (fep->rx_desc[(i + 1) % NUM_RX_BUFF].
+-					    ctrl & MAL_RX_CTRL_EMPTY)
+-						break;
+-					bnum = 0;
+-					buf[bnum] = i;
+-					++bnum;
+-					continue;
+-				}
+-				if (((ctrl & MAL_RX_CTRL_FIRST) !=
+-				     MAL_RX_CTRL_FIRST) &&
+-				    ((ctrl & MAL_RX_CTRL_LAST) !=
+-				     MAL_RX_CTRL_LAST)) {
+-					if (fep->rx_desc[(i + 1) %
+-							 NUM_RX_BUFF].ctrl &
+-					    MAL_RX_CTRL_EMPTY) {
+-						i = buf[0];
+-						break;
+-					}
+-					buf[bnum] = i;
+-					++bnum;
+-					continue;
+-				}
+-				if (ctrl & MAL_RX_CTRL_LAST) {
+-					buf[bnum] = i;
+-					++bnum;
+-					skb_put(fep->rx_skb[buf[0]],
+-						fep->rx_desc[buf[0]].data_len);
+-					for (b = 1; b < bnum; b++) {
+-						/*
+-						 * MAL is braindead, we need
+-						 * to copy the remainder
+-						 * of the packet from the
+-						 * latter descriptor buffers
+-						 * to the first skb. Then
+-						 * dispose of the source
+-						 * skbs.
+-						 *
+-						 * Once the stack is fixed
+-						 * to handle frags on most
+-						 * protocols we can generate
+-						 * a fragmented skb with
+-						 * no copies.
+-						 */
+-						memcpy(fep->rx_skb[buf[0]]->
+-						       data +
+-						       fep->rx_skb[buf[0]]->len,
+-						       fep->rx_skb[buf[b]]->
+-						       data,
+-						       fep->rx_desc[buf[b]].
+-						       data_len);
+-						skb_put(fep->rx_skb[buf[0]],
+-							fep->rx_desc[buf[b]].
+-							data_len);
+-						dma_unmap_single(&fep->ocpdev->
+-								 dev,
+-								 fep->
+-								 rx_desc[buf
+-									 [b]].
+-								 data_ptr,
+-								 fep->
+-								 rx_desc[buf
+-									 [b]].
+-								 data_len,
+-								 DMA_FROM_DEVICE);
+-						dev_kfree_skb(fep->
+-							      rx_skb[buf[b]]);
+-					}
+-					emac_rx_csum(dev, ctrl,
+-						     fep->rx_skb[buf[0]]);
+-
+-					fep->rx_skb[buf[0]]->dev = dev;
+-					fep->rx_skb[buf[0]]->protocol =
+-					    eth_type_trans(fep->rx_skb[buf[0]],
+-							   dev);
+-					error = netif_rx(fep->rx_skb[buf[0]]);
+-
+-					if ((error == NET_RX_DROP)
+-					    || (error == NET_RX_BAD)) {
+-						fep->stats.rx_dropped++;
+-					} else {
+-						fep->stats.rx_packets++;
+-						fep->stats.rx_bytes +=
+-						    fep->rx_skb[buf[0]]->len;
+-					}
+-					for (b = 0; b < bnum; b++)
+-						fep->rx_skb[buf[b]] = NULL;
+-				}
+-			}
+-		}
+-	} while ((i = (i + 1) % NUM_RX_BUFF) != fep->rx_slot);
++	struct ocp_enet_private *dev = ndev->priv;
++	int res;
+ 
+-	PKT_DEBUG(("emac_rx_clean() exit, rx_slot: %d\n", fep->rx_slot));
+-
+-	return i;
++	local_bh_disable();
++	res = __emac_mdio_read(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id,
++			       (u8) reg);
++	local_bh_enable();
++	return res;
+ }
+ 
+-static void emac_rxeob_dev(void *param, u32 chanmask)
++static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val)
+ {
+-	struct net_device *dev = param;
+-	struct ocp_enet_private *fep = dev->priv;
+-	unsigned long flags;
+-	int n;
++	struct ocp_enet_private *dev = ndev->priv;
+ 
+-	spin_lock_irqsave(&fep->lock, flags);
+-	if ((n = emac_rx_clean(dev)) != fep->rx_slot)
+-		emac_rx_fill(dev, n);
+-	spin_unlock_irqrestore(&fep->lock, flags);
++	local_bh_disable();
++	__emac_mdio_write(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id,
++			  (u8) reg, (u16) val);
++	local_bh_enable();
+ }
+ 
+-/*
+- * This interrupt should never occurr, we don't program
+- * the MAL for contiunous mode.
+- */
+-static void emac_txde_dev(void *param, u32 chanmask)
++/* BHs disabled */
++static void emac_set_multicast_list(struct net_device *ndev)
+ {
+-	struct net_device *dev = param;
+-	struct ocp_enet_private *fep = dev->priv;
++	struct ocp_enet_private *dev = ndev->priv;
++	struct emac_regs *p = dev->emacp;
++	u32 rmr = emac_iff2rmr(ndev);
+ 
+-	printk(KERN_WARNING "%s: transmit descriptor error\n", dev->name);
++	DBG("%d: multicast %08x" NL, dev->def->index, rmr);
++	BUG_ON(!netif_running(dev->ndev));
+ 
+-	emac_mac_dump(dev);
+-	emac_mal_dump(dev);
+-
+-	/* Reenable the transmit channel */
+-	mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
++	/* I decided to relax register access rules here to avoid
++	 * full EMAC reset.
++	 *
++	 * There is a real problem with EMAC4 core if we use MWSW_001 bit 
++	 * in MR1 register and do a full EMAC reset.
++	 * One TX BD status update is delayed and, after EMAC reset, it 
++	 * never happens, resulting in TX hung (it'll be recovered by TX 
++	 * timeout handler eventually, but this is just gross).
++	 * So we either have to do full TX reset or try to cheat here :)
++	 *
++	 * The only required change is to RX mode register, so I *think* all
++	 * we need is just to stop RX channel. This seems to work on all
++	 * tested SoCs.                                                --ebs
++	 */
++	emac_rx_disable(dev);
++	if (rmr & EMAC_RMR_MAE)
++		emac_hash_mc(dev);
++	out_be32(&p->rmr, rmr);
++	emac_rx_enable(dev);
+ }
+ 
+-/*
+- * This interrupt should be very rare at best.  This occurs when
+- * the hardware has a problem with the receive descriptors.  The manual
+- * states that it occurs when the hardware cannot the receive descriptor
+- * empty bit is not set.  The recovery mechanism will be to
+- * traverse through the descriptors, handle any that are marked to be
+- * handled and reinitialize each along the way.  At that point the driver
+- * will be restarted.
+- */
+-static void emac_rxde_dev(void *param, u32 chanmask)
++/* BHs disabled */
++static int emac_resize_rx_ring(struct ocp_enet_private *dev, int new_mtu)
+ {
+-	struct net_device *dev = param;
+-	struct ocp_enet_private *fep = dev->priv;
+-	unsigned long flags;
++	struct ocp_func_emac_data *emacdata = dev->def->additions;
++	int rx_sync_size = emac_rx_sync_size(new_mtu);
++	int rx_skb_size = emac_rx_skb_size(new_mtu);
++	int i, ret = 0;
+ 
+-	if (net_ratelimit()) {
+-		printk(KERN_WARNING "%s: receive descriptor error\n",
+-		       fep->ndev->name);
++	emac_rx_disable(dev);
++	mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+ 
+-		emac_mac_dump(dev);
+-		emac_mal_dump(dev);
+-		emac_desc_dump(dev);
++	if (dev->rx_sg_skb) {
++		++dev->estats.rx_dropped_resize;
++		dev_kfree_skb(dev->rx_sg_skb);
++		dev->rx_sg_skb = NULL;
+ 	}
+ 
+-	/* Disable RX channel */
+-	spin_lock_irqsave(&fep->lock, flags);
+-	mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
++	/* Make a first pass over RX ring and mark BDs ready, dropping 
++	 * non-processed packets on the way. We need this as a separate pass
++	 * to simplify error recovery in the case of allocation failure later.
++	 */
++	for (i = 0; i < NUM_RX_BUFF; ++i) {
++		if (dev->rx_desc[i].ctrl & MAL_RX_CTRL_FIRST)
++			++dev->estats.rx_dropped_resize;
+ 
+-	/* For now, charge the error against all emacs */
+-	fep->stats.rx_errors++;
++		dev->rx_desc[i].data_len = 0;
++		dev->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY |
++		    (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
++	}
+ 
+-	/* so do we have any good packets still? */
+-	emac_rx_clean(dev);
++	/* Reallocate RX ring only if bigger skb buffers are required */
++	if (rx_skb_size <= dev->rx_skb_size)
++		goto skip;
+ 
+-	/* When the interface is restarted it resets processing to the
+-	 *  first descriptor in the table.
+-	 */
++	/* Second pass, allocate new skbs */
++	for (i = 0; i < NUM_RX_BUFF; ++i) {
++		struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
++		if (!skb) {
++			ret = -ENOMEM;
++			goto oom;
++		}
+ 
+-	fep->rx_slot = 0;
+-	emac_rx_fill(dev, 0);
++		BUG_ON(!dev->rx_skb[i]);
++		dev_kfree_skb(dev->rx_skb[i]);
+ 
+-	set_mal_dcrn(fep->mal, DCRN_MALRXEOBISR, fep->commac.rx_chan_mask);
+-	set_mal_dcrn(fep->mal, DCRN_MALRXDEIR, fep->commac.rx_chan_mask);
++		skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
++		dev->rx_desc[i].data_ptr =
++		    dma_map_single(dev->ldev, skb->data - 2, rx_sync_size,
++				   DMA_FROM_DEVICE) + 2;
++		dev->rx_skb[i] = skb;
++	}
++      skip:
++	/* Check if we need to change "Jumbo" bit in MR1 */
++	if ((new_mtu > ETH_DATA_LEN) ^ (dev->ndev->mtu > ETH_DATA_LEN)) {
++		/* This is to prevent starting RX channel in emac_rx_enable() */
++		dev->commac.rx_stopped = 1;
+ 
+-	/* Reenable the receive channels */
+-	mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+-	spin_unlock_irqrestore(&fep->lock, flags);
++		dev->ndev->mtu = new_mtu;
++		emac_full_tx_reset(dev->ndev);
++	}
++
++	mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(new_mtu));
++      oom:
++	/* Restart RX */
++	dev->commac.rx_stopped = dev->rx_slot = 0;
++	mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
++	emac_rx_enable(dev);
++
++	return ret;
+ }
+ 
+-static irqreturn_t
+-emac_mac_irq(int irq, void *dev_instance, struct pt_regs *regs)
++/* Process ctx, rtnl_lock semaphore */
++static int emac_change_mtu(struct net_device *ndev, int new_mtu)
+ {
+-	struct net_device *dev = dev_instance;
+-	struct ocp_enet_private *fep = dev->priv;
+-	emac_t *emacp = fep->emacp;
+-	unsigned long tmp_em0isr;
++	struct ocp_enet_private *dev = ndev->priv;
++	int ret = 0;
+ 
+-	/* EMAC interrupt */
+-	tmp_em0isr = in_be32(&emacp->em0isr);
+-	if (tmp_em0isr & (EMAC_ISR_TE0 | EMAC_ISR_TE1)) {
+-		/* This error is a hard transmit error - could retransmit */
+-		fep->stats.tx_errors++;
++	if (new_mtu < EMAC_MIN_MTU || new_mtu > EMAC_MAX_MTU)
++		return -EINVAL;
+ 
+-		/* Reenable the transmit channel */
+-		mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
++	DBG("%d: change_mtu(%d)" NL, dev->def->index, new_mtu);
+ 
+-	} else {
+-		fep->stats.rx_errors++;
++	local_bh_disable();
++	if (netif_running(ndev)) {
++		/* Check if we really need to reinitalize RX ring */
++		if (emac_rx_skb_size(ndev->mtu) != emac_rx_skb_size(new_mtu))
++			ret = emac_resize_rx_ring(dev, new_mtu);
+ 	}
+ 
+-	if (tmp_em0isr & EMAC_ISR_RP)
+-		fep->stats.rx_length_errors++;
+-	if (tmp_em0isr & EMAC_ISR_ALE)
+-		fep->stats.rx_frame_errors++;
+-	if (tmp_em0isr & EMAC_ISR_BFCS)
+-		fep->stats.rx_crc_errors++;
+-	if (tmp_em0isr & EMAC_ISR_PTLE)
+-		fep->stats.rx_length_errors++;
+-	if (tmp_em0isr & EMAC_ISR_ORE)
+-		fep->stats.rx_length_errors++;
+-	if (tmp_em0isr & EMAC_ISR_TE0)
+-		fep->stats.tx_aborted_errors++;
+-
+-	emac_err_dump(dev, tmp_em0isr);
++	if (!ret) {
++		ndev->mtu = new_mtu;
++		dev->rx_skb_size = emac_rx_skb_size(new_mtu);
++		dev->rx_sync_size = emac_rx_sync_size(new_mtu);
++	}	
++	local_bh_enable();
+ 
+-	out_be32(&emacp->em0isr, tmp_em0isr);
+-
+-	return IRQ_HANDLED;
++	return ret;
+ }
+ 
+-static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
++static void emac_clean_tx_ring(struct ocp_enet_private *dev)
+ {
+-	unsigned short ctrl;
+-	unsigned long flags;
+-	struct ocp_enet_private *fep = dev->priv;
+-	emac_t *emacp = fep->emacp;
+-	int len = skb->len;
+-	unsigned int offset = 0, size, f, tx_slot_first;
+-	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
+-
+-	spin_lock_irqsave(&fep->lock, flags);
+-
+-	len -= skb->data_len;
+-
+-	if ((fep->tx_cnt + nr_frags + len / DESC_BUF_SIZE + 1) > NUM_TX_BUFF) {
+-		PKT_DEBUG(("emac_start_xmit() stopping queue\n"));
+-		netif_stop_queue(dev);
+-		spin_unlock_irqrestore(&fep->lock, flags);
+-		return -EBUSY;
+-	}
+-
+-	tx_slot_first = fep->tx_slot;
+-
+-	while (len) {
+-		size = min(len, DESC_BUF_SIZE);
+-
+-		fep->tx_desc[fep->tx_slot].data_len = (short)size;
+-		fep->tx_desc[fep->tx_slot].data_ptr =
+-		    (unsigned char *)dma_map_single(&fep->ocpdev->dev,
+-						    (void *)((unsigned int)skb->
+-							     data + offset),
+-						    size, DMA_TO_DEVICE);
+-
+-		ctrl = EMAC_TX_CTRL_DFLT;
+-		if (fep->tx_slot != tx_slot_first)
+-			ctrl |= MAL_TX_CTRL_READY;
+-		if ((NUM_TX_BUFF - 1) == fep->tx_slot)
+-			ctrl |= MAL_TX_CTRL_WRAP;
+-		if (!nr_frags && (len == size)) {
+-			ctrl |= MAL_TX_CTRL_LAST;
+-			fep->tx_skb[fep->tx_slot] = skb;
++	int i;
++	for (i = 0; i < NUM_TX_BUFF; ++i) {
++		if (dev->tx_skb[i]) {
++			dev_kfree_skb(dev->tx_skb[i]);
++			dev->tx_skb[i] = NULL;
++			if (dev->tx_desc[i].ctrl & MAL_TX_CTRL_READY)
++				++dev->estats.tx_dropped;
+ 		}
+-		if (skb->ip_summed == CHECKSUM_HW)
+-			ctrl |= EMAC_TX_CTRL_TAH_CSUM;
+-
+-		fep->tx_desc[fep->tx_slot].ctrl = ctrl;
+-
+-		len -= size;
+-		offset += size;
++		dev->tx_desc[i].ctrl = 0;
++		dev->tx_desc[i].data_ptr = 0;
++	}
++}
+ 
+-		/* Bump tx count */
+-		if (++fep->tx_cnt == NUM_TX_BUFF)
+-			netif_stop_queue(dev);
++static void emac_clean_rx_ring(struct ocp_enet_private *dev)
++{
++	int i;
++	for (i = 0; i < NUM_RX_BUFF; ++i)
++		if (dev->rx_skb[i]) {
++			dev->rx_desc[i].ctrl = 0;
++			dev_kfree_skb(dev->rx_skb[i]);
++			dev->rx_skb[i] = NULL;
++			dev->rx_desc[i].data_ptr = 0;
++		}
+ 
+-		/* Next descriptor */
+-		if (++fep->tx_slot == NUM_TX_BUFF)
+-			fep->tx_slot = 0;
++	if (dev->rx_sg_skb) {
++		dev_kfree_skb(dev->rx_sg_skb);
++		dev->rx_sg_skb = NULL;
+ 	}
++}
+ 
+-	for (f = 0; f < nr_frags; f++) {
+-		struct skb_frag_struct *frag;
++static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot,
++				    int flags)
++{
++	struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
++	if (unlikely(!skb))
++		return -ENOMEM;
+ 
+-		frag = &skb_shinfo(skb)->frags[f];
+-		len = frag->size;
+-		offset = 0;
++	dev->rx_skb[slot] = skb;
++	dev->rx_desc[slot].data_len = 0;
+ 
+-		while (len) {
+-			size = min(len, DESC_BUF_SIZE);
++	skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
++	dev->rx_desc[slot].data_ptr = 
++	    dma_map_single(dev->ldev, skb->data - 2, dev->rx_sync_size, 
++			   DMA_FROM_DEVICE) + 2;
++	barrier();
++	dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
++	    (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
+ 
+-			dma_map_page(&fep->ocpdev->dev,
+-				     frag->page,
+-				     frag->page_offset + offset,
+-				     size, DMA_TO_DEVICE);
+-
+-			ctrl = EMAC_TX_CTRL_DFLT | MAL_TX_CTRL_READY;
+-			if ((NUM_TX_BUFF - 1) == fep->tx_slot)
+-				ctrl |= MAL_TX_CTRL_WRAP;
+-			if ((f == (nr_frags - 1)) && (len == size)) {
+-				ctrl |= MAL_TX_CTRL_LAST;
+-				fep->tx_skb[fep->tx_slot] = skb;
+-			}
++	return 0;
++}
+ 
+-			if (skb->ip_summed == CHECKSUM_HW)
+-				ctrl |= EMAC_TX_CTRL_TAH_CSUM;
++static void emac_print_link_status(struct ocp_enet_private *dev)
++{
++	if (netif_carrier_ok(dev->ndev))
++		printk(KERN_INFO "%s: link is up, %d %s%s\n",
++		       dev->ndev->name, dev->phy.speed,
++		       dev->phy.duplex == DUPLEX_FULL ? "FDX" : "HDX",
++		       dev->phy.pause ? ", pause enabled" :
++		       dev->phy.asym_pause ? ", assymetric pause enabled" : "");
++	else
++		printk(KERN_INFO "%s: link is down\n", dev->ndev->name);
++}
+ 
+-			fep->tx_desc[fep->tx_slot].data_len = (short)size;
+-			fep->tx_desc[fep->tx_slot].data_ptr =
+-			    (char *)((page_to_pfn(frag->page) << PAGE_SHIFT) +
+-				     frag->page_offset + offset);
+-			fep->tx_desc[fep->tx_slot].ctrl = ctrl;
++/* Process ctx, rtnl_lock semaphore */
++static int emac_open(struct net_device *ndev)
++{
++	struct ocp_enet_private *dev = ndev->priv;
++	struct ocp_func_emac_data *emacdata = dev->def->additions;
++	int err, i;
++
++	DBG("%d: open" NL, dev->def->index);
++
++	/* Setup error IRQ handler */
++	err = request_irq(dev->def->irq, emac_irq, 0, "EMAC", dev);
++	if (err) {
++		printk(KERN_ERR "%s: failed to request IRQ %d\n",
++		       ndev->name, dev->def->irq);
++		return err;
++	}
++
++	/* Allocate RX ring */
++	for (i = 0; i < NUM_RX_BUFF; ++i)
++		if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
++			printk(KERN_ERR "%s: failed to allocate RX ring\n",
++			       ndev->name);
++			goto oom;
++		}
++
++	local_bh_disable();
++	dev->tx_cnt = dev->tx_slot = dev->ack_slot = dev->rx_slot =
++	    dev->commac.rx_stopped = 0;
++	dev->rx_sg_skb = NULL;
++
++	if (dev->phy.address >= 0) {
++		int link_poll_interval;
++		if (dev->phy.def->ops->poll_link(&dev->phy)) {
++			dev->phy.def->ops->read_link(&dev->phy);
++			EMAC_RX_CLK_DEFAULT(dev->def->index);
++			netif_carrier_on(dev->ndev);
++			link_poll_interval = PHY_POLL_LINK_ON;
++		} else {
++			EMAC_RX_CLK_TX(dev->def->index);
++			netif_carrier_off(dev->ndev);
++			link_poll_interval = PHY_POLL_LINK_OFF;
++		}
++		mod_timer(&dev->link_timer, jiffies + link_poll_interval);
++		emac_print_link_status(dev);
++	} else
++		netif_carrier_on(dev->ndev);
++
++	emac_configure(dev);
++	mal_poll_add(dev->mal, &dev->commac);
++	mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan);
++	mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(ndev->mtu));
++	mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
++	emac_tx_enable(dev);
++	emac_rx_enable(dev);
++	netif_start_queue(ndev);
++	local_bh_enable();
+ 
+-			len -= size;
+-			offset += size;
++	return 0;
++      oom:
++	emac_clean_rx_ring(dev);
++	free_irq(dev->def->irq, dev);
++	return -ENOMEM;
++}
+ 
+-			/* Bump tx count */
+-			if (++fep->tx_cnt == NUM_TX_BUFF)
+-				netif_stop_queue(dev);
++/* BHs disabled */
++static int emac_link_differs(struct ocp_enet_private *dev)
++{
++	u32 r = in_be32(&dev->emacp->mr1);
+ 
+-			/* Next descriptor */
+-			if (++fep->tx_slot == NUM_TX_BUFF)
+-				fep->tx_slot = 0;
+-		}
+-	}
++	int duplex = r & EMAC_MR1_FDE ? DUPLEX_FULL : DUPLEX_HALF;
++	int speed, pause, asym_pause;
+ 
+-	/*
+-	 * Deferred set READY on first descriptor of packet to
+-	 * avoid TX MAL race.
+-	 */
+-	fep->tx_desc[tx_slot_first].ctrl |= MAL_TX_CTRL_READY;
++	if (r & (EMAC_MR1_MF_1000 | EMAC_MR1_MF_1000GPCS))
++		speed = SPEED_1000;
++	else if (r & EMAC_MR1_MF_100)
++		speed = SPEED_100;
++	else
++		speed = SPEED_10;
+ 
+-	/* Send the packet out. */
+-	out_be32(&emacp->em0tmr0, EMAC_TMR0_XMIT);
++	switch (r & (EMAC_MR1_EIFC | EMAC_MR1_APP)) {
++	case (EMAC_MR1_EIFC | EMAC_MR1_APP):
++		pause = 1;
++		asym_pause = 0;
++		break;
++	case EMAC_MR1_APP:
++		pause = 0;
++		asym_pause = 1;
++		break;
++	default:
++		pause = asym_pause = 0;
++	}
++	return speed != dev->phy.speed || duplex != dev->phy.duplex ||
++	    pause != dev->phy.pause || asym_pause != dev->phy.asym_pause;
++}
+ 
+-	fep->stats.tx_packets++;
+-	fep->stats.tx_bytes += skb->len;
++/* BHs disabled */
++static void emac_link_timer(unsigned long data)
++{
++	struct ocp_enet_private *dev = (struct ocp_enet_private *)data;
++	int link_poll_interval;
+ 
+-	PKT_DEBUG(("emac_start_xmit() exitn"));
++	DBG2("%d: link timer" NL, dev->def->index);
+ 
+-	spin_unlock_irqrestore(&fep->lock, flags);
++	if (dev->phy.def->ops->poll_link(&dev->phy)) {
++		if (!netif_carrier_ok(dev->ndev)) {
++			EMAC_RX_CLK_DEFAULT(dev->def->index);
+ 
+-	return 0;
+-}
++			/* Get new link parameters */
++			dev->phy.def->ops->read_link(&dev->phy);
+ 
+-static int emac_adjust_to_link(struct ocp_enet_private *fep)
+-{
+-	emac_t *emacp = fep->emacp;
+-	unsigned long mode_reg;
+-	int full_duplex, speed;
++			if (dev->tah_dev || emac_link_differs(dev))
++				emac_full_tx_reset(dev->ndev);
+ 
+-	full_duplex = 0;
+-	speed = SPEED_10;
++			netif_carrier_on(dev->ndev);
++			emac_print_link_status(dev);
++		}
++		link_poll_interval = PHY_POLL_LINK_ON;
++	} else {
++		if (netif_carrier_ok(dev->ndev)) {
++			EMAC_RX_CLK_TX(dev->def->index);
++#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX)
++			emac_reinitialize(dev);
++#endif
++			netif_carrier_off(dev->ndev);
++			emac_print_link_status(dev);
++		}
+ 
+-	/* set mode register 1 defaults */
+-	mode_reg = EMAC_M1_DEFAULT;
++		/* Retry reset if the previous attempt failed.
++		 * This is needed mostly for CONFIG_IBM_EMAC_PHY_RX_CLK_FIX
++		 * case, but I left it here because it shouldn't trigger for
++		 * sane PHYs anyway.
++		 */
++		if (unlikely(dev->reset_failed))
++			emac_reinitialize(dev);
+ 
+-	/* Read link mode on PHY */
+-	if (fep->phy_mii.def->ops->read_link(&fep->phy_mii) == 0) {
+-		/* If an error occurred, we don't deal with it yet */
+-		full_duplex = (fep->phy_mii.duplex == DUPLEX_FULL);
+-		speed = fep->phy_mii.speed;
++		link_poll_interval = PHY_POLL_LINK_OFF;
+ 	}
++	mod_timer(&dev->link_timer, jiffies + link_poll_interval);
++}
+ 
++/* BHs disabled */
++static void emac_force_link_update(struct ocp_enet_private *dev)
++{
++	netif_carrier_off(dev->ndev);
++	if (timer_pending(&dev->link_timer))
++		mod_timer(&dev->link_timer, jiffies + PHY_POLL_LINK_OFF);
++}
+ 
+-	/* set speed (default is 10Mb) */
+-	switch (speed) {
+-	case SPEED_1000:
+-		mode_reg |= EMAC_M1_RFS_16K;
+-		if (fep->rgmii_dev) {
+-			struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(fep->rgmii_dev);
+-
+-			if ((rgmii->mode[fep->rgmii_input] == RTBI)
+-			    || (rgmii->mode[fep->rgmii_input] == TBI))
+-				mode_reg |= EMAC_M1_MF_1000GPCS;
+-			else
+-				mode_reg |= EMAC_M1_MF_1000MBPS;
++/* Process ctx, rtnl_lock semaphore */
++static int emac_close(struct net_device *ndev)
++{
++	struct ocp_enet_private *dev = ndev->priv;
++	struct ocp_func_emac_data *emacdata = dev->def->additions;
+ 
+-			emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
+-					      1000);
+-		}
+-		break;
+-	case SPEED_100:
+-		mode_reg |= EMAC_M1_MF_100MBPS | EMAC_M1_RFS_4K;
+-		if (fep->rgmii_dev)
+-			emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
+-					      100);
+-		if (fep->zmii_dev)
+-			emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
+-					     100);
+-		break;
+-	case SPEED_10:
+-	default:
+-		mode_reg = (mode_reg & ~EMAC_M1_MF_100MBPS) | EMAC_M1_RFS_4K;
+-		if (fep->rgmii_dev)
+-			emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
+-					      10);
+-		if (fep->zmii_dev)
+-			emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
+-					     10);
+-	}
++	DBG("%d: close" NL, dev->def->index);
+ 
+-	if (full_duplex)
+-		mode_reg |= EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_IST;
+-	else
+-		mode_reg &= ~(EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_ILE);
++	local_bh_disable();
++
++	if (dev->phy.address >= 0)
++		del_timer_sync(&dev->link_timer);
+ 
+-	LINK_DEBUG(("%s: adjust to link, speed: %d, duplex: %d, opened: %d\n",
+-		    fep->ndev->name, speed, full_duplex, fep->opened));
++	netif_stop_queue(ndev);
++	emac_rx_disable(dev);
++	emac_tx_disable(dev);
++	mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan);
++	mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan);
++	mal_poll_del(dev->mal, &dev->commac);
++	local_bh_enable();
+ 
+-	printk(KERN_INFO "%s: Speed: %d, %s duplex.\n",
+-	       fep->ndev->name, speed, full_duplex ? "Full" : "Half");
+-	if (fep->opened)
+-		out_be32(&emacp->em0mr1, mode_reg);
++	emac_clean_tx_ring(dev);
++	emac_clean_rx_ring(dev);
++	free_irq(dev->def->irq, dev);
+ 
+ 	return 0;
+ }
+ 
+-static int emac_set_mac_address(struct net_device *ndev, void *p)
++static inline u16 emac_tx_csum(struct ocp_enet_private *dev,
++			       struct sk_buff *skb)
+ {
+-	struct ocp_enet_private *fep = ndev->priv;
+-	emac_t *emacp = fep->emacp;
+-	struct sockaddr *addr = p;
++#if defined(CONFIG_IBM_EMAC_TAH)
++	if (skb->ip_summed == CHECKSUM_HW) {
++		++dev->stats.tx_packets_csum;
++		return EMAC_TX_CTRL_TAH_CSUM;
++	}
++#endif
++	return 0;
++}
+ 
+-	if (!is_valid_ether_addr(addr->sa_data))
+-		return -EADDRNOTAVAIL;
++static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len)
++{
++	struct emac_regs *p = dev->emacp;
++	struct net_device *ndev = dev->ndev;
+ 
+-	memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
++	/* Send the packet out */
++	out_be32(&p->tmr0, EMAC_TMR0_XMIT);
+ 
+-	/* set the high address */
+-	out_be32(&emacp->em0iahr,
+-		 (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]);
++	if (unlikely(++dev->tx_cnt == NUM_TX_BUFF)) {
++		netif_stop_queue(ndev);
++		DBG2("%d: stopped TX queue" NL, dev->def->index);
++	}
+ 
+-	/* set the low address */
+-	out_be32(&emacp->em0ialr,
+-		 (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16)
+-		 | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]);
++	ndev->trans_start = jiffies;
++	++dev->stats.tx_packets;
++	dev->stats.tx_bytes += len;
+ 
+ 	return 0;
+ }
+ 
+-static int emac_change_mtu(struct net_device *dev, int new_mtu)
++/* BHs disabled */
++static int emac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ {
+-	struct ocp_enet_private *fep = dev->priv;
+-	int old_mtu = dev->mtu;
+-	unsigned long mode_reg;
+-	emac_t *emacp = fep->emacp;
+-	u32 em0mr0;
+-	int i, full;
+-	unsigned long flags;
+-
+-	if ((new_mtu < EMAC_MIN_MTU) || (new_mtu > EMAC_MAX_MTU)) {
+-		printk(KERN_ERR
+-		       "emac: Invalid MTU setting, MTU must be between %d and %d\n",
+-		       EMAC_MIN_MTU, EMAC_MAX_MTU);
+-		return -EINVAL;
+-	}
++	struct ocp_enet_private *dev = ndev->priv;
++	unsigned int len = skb->len;
++	int slot;
+ 
+-	if (old_mtu != new_mtu && netif_running(dev)) {
+-		/* Stop rx engine */
+-		em0mr0 = in_be32(&emacp->em0mr0);
+-		out_be32(&emacp->em0mr0, em0mr0 & ~EMAC_M0_RXE);
+-
+-		/* Wait for descriptors to be empty */
+-		do {
+-			full = 0;
+-			for (i = 0; i < NUM_RX_BUFF; i++)
+-				if (!(fep->rx_desc[i].ctrl & MAL_RX_CTRL_EMPTY)) {
+-					printk(KERN_NOTICE
+-					       "emac: RX ring is still full\n");
+-					full = 1;
+-				}
+-		} while (full);
+-
+-		spin_lock_irqsave(&fep->lock, flags);
+-
+-		mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+-
+-		/* Destroy all old rx skbs */
+-		for (i = 0; i < NUM_RX_BUFF; i++) {
+-			dma_unmap_single(&fep->ocpdev->dev,
+-					 fep->rx_desc[i].data_ptr,
+-					 fep->rx_desc[i].data_len,
+-					 DMA_FROM_DEVICE);
+-			dev_kfree_skb(fep->rx_skb[i]);
+-			fep->rx_skb[i] = NULL;
+-		}
+-
+-		/* Set new rx_buffer_size, jumbo cap, and advertise new mtu */
+-		mode_reg = in_be32(&emacp->em0mr1);
+-		if (new_mtu > ENET_DEF_MTU_SIZE) {
+-			mode_reg |= EMAC_M1_JUMBO_ENABLE;
+-			fep->rx_buffer_size = EMAC_MAX_FRAME;
+-		} else {
+-			mode_reg &= ~EMAC_M1_JUMBO_ENABLE;
+-			fep->rx_buffer_size = ENET_DEF_BUF_SIZE;
+-		}
+-		dev->mtu = new_mtu;
+-		out_be32(&emacp->em0mr1, mode_reg);
++	u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
++	    MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb);
+ 
+-		/* Re-init rx skbs */
+-		fep->rx_slot = 0;
+-		emac_rx_fill(dev, 0);
++	slot = dev->tx_slot++;
++	if (dev->tx_slot == NUM_TX_BUFF) {
++		dev->tx_slot = 0;
++		ctrl |= MAL_TX_CTRL_WRAP;
++	}
+ 
+-		/* Restart the rx engine */
+-		mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+-		out_be32(&emacp->em0mr0, em0mr0 | EMAC_M0_RXE);
++	DBG2("%d: xmit(%u) %d" NL, dev->def->index, len, slot);
+ 
+-		spin_unlock_irqrestore(&fep->lock, flags);
+-	}
++	dev->tx_skb[slot] = skb;
++	dev->tx_desc[slot].data_ptr = dma_map_single(dev->ldev, skb->data, len,
++						     DMA_TO_DEVICE);
++	dev->tx_desc[slot].data_len = (u16) len;
++	barrier();
++	dev->tx_desc[slot].ctrl = ctrl;
+ 
+-	return 0;
++	return emac_xmit_finish(dev, len);
+ }
+ 
+-static void __emac_set_multicast_list(struct net_device *dev)
++#if defined(CONFIG_IBM_EMAC_TAH)
++static inline int emac_xmit_split(struct ocp_enet_private *dev, int slot,
++				  u32 pd, int len, int last, u16 base_ctrl)
+ {
+-	struct ocp_enet_private *fep = dev->priv;
+-	emac_t *emacp = fep->emacp;
+-	u32 rmr = in_be32(&emacp->em0rmr);
+-
+-	/* First clear all special bits, they can be set later */
+-	rmr &= ~(EMAC_RMR_PME | EMAC_RMR_PMME | EMAC_RMR_MAE);
+-
+-	if (dev->flags & IFF_PROMISC) {
+-		rmr |= EMAC_RMR_PME;
+-	} else if (dev->flags & IFF_ALLMULTI || 32 < dev->mc_count) {
+-		/*
+-		 * Must be setting up to use multicast
+-		 * Now check for promiscuous multicast
+-		 */
+-		rmr |= EMAC_RMR_PMME;
+-	} else if (dev->flags & IFF_MULTICAST && 0 < dev->mc_count) {
+-		unsigned short em0gaht[4] = { 0, 0, 0, 0 };
+-		struct dev_mc_list *dmi;
++	while (1) {
++		u16 ctrl = base_ctrl;
++		int chunk = min(len, MAL_MAX_TX_SIZE);
++		len -= chunk;
+ 
+-		/* Need to hash on the multicast address. */
+-		for (dmi = dev->mc_list; dmi; dmi = dmi->next) {
+-			unsigned long mc_crc;
+-			unsigned int bit_number;
++		slot = (slot + 1) % NUM_TX_BUFF;
+ 
+-			mc_crc = ether_crc(6, (char *)dmi->dmi_addr);
+-			bit_number = 63 - (mc_crc >> 26);	/* MSB: 0 LSB: 63 */
+-			em0gaht[bit_number >> 4] |=
+-			    0x8000 >> (bit_number & 0x0f);
+-		}
+-		emacp->em0gaht1 = em0gaht[0];
+-		emacp->em0gaht2 = em0gaht[1];
+-		emacp->em0gaht3 = em0gaht[2];
+-		emacp->em0gaht4 = em0gaht[3];
++		if (last && !len)
++			ctrl |= MAL_TX_CTRL_LAST;
++		if (slot == NUM_TX_BUFF - 1)
++			ctrl |= MAL_TX_CTRL_WRAP;
++
++		dev->tx_skb[slot] = NULL;
++		dev->tx_desc[slot].data_ptr = pd;
++		dev->tx_desc[slot].data_len = (u16) chunk;
++		dev->tx_desc[slot].ctrl = ctrl;
++		++dev->tx_cnt;
++
++		if (!len)
++			break;
+ 
+-		/* Turn on multicast addressing */
+-		rmr |= EMAC_RMR_MAE;
++		pd += chunk;
+ 	}
+-	out_be32(&emacp->em0rmr, rmr);
++	return slot;
+ }
+ 
+-static int emac_init_tah(struct ocp_enet_private *fep)
++/* BHs disabled (SG version for TAH equipped EMACs) */
++static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
+ {
+-	tah_t *tahp;
++	struct ocp_enet_private *dev = ndev->priv;
++	int nr_frags = skb_shinfo(skb)->nr_frags;
++	int len = skb->len, chunk;
++	int slot, i;
++	u16 ctrl;
++	u32 pd;
+ 
+-	/* Initialize TAH and enable checksum verification */
+-	tahp = (tah_t *) ioremap(fep->tah_dev->def->paddr, sizeof(*tahp));
++	/* This is common "fast" path */
++	if (likely(!nr_frags && len <= MAL_MAX_TX_SIZE))
++		return emac_start_xmit(skb, ndev);
+ 
+-	if (tahp == NULL) {
+-		printk(KERN_ERR "tah%d: Cannot ioremap TAH registers!\n",
+-		       fep->tah_dev->def->index);
++	len -= skb->data_len;
+ 
+-		return -ENOMEM;
++	/* Note, this is only an *estimation*, we can still run out of empty
++	 * slots because of the additional fragmentation into
++	 * MAL_MAX_TX_SIZE-sized chunks
++	 */
++	if (unlikely(dev->tx_cnt + nr_frags + mal_tx_chunks(len) > NUM_TX_BUFF))
++		goto stop_queue;
++
++	ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
++	    emac_tx_csum(dev, skb);
++	slot = dev->tx_slot;
++
++	/* skb data */
++	dev->tx_skb[slot] = NULL;
++	chunk = min(len, MAL_MAX_TX_SIZE);
++	dev->tx_desc[slot].data_ptr = pd =
++	    dma_map_single(dev->ldev, skb->data, len, DMA_TO_DEVICE);
++	dev->tx_desc[slot].data_len = (u16) chunk;
++	len -= chunk;
++	if (unlikely(len))
++		slot = emac_xmit_split(dev, slot, pd + chunk, len, !nr_frags,
++				       ctrl);
++	/* skb fragments */
++	for (i = 0; i < nr_frags; ++i) {
++		struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
++		len = frag->size;
++
++		if (unlikely(dev->tx_cnt + mal_tx_chunks(len) >= NUM_TX_BUFF))
++			goto undo_frame;
++
++		pd = dma_map_page(dev->ldev, frag->page, frag->page_offset, len,
++				  DMA_TO_DEVICE);
++
++		slot = emac_xmit_split(dev, slot, pd, len, i == nr_frags - 1,
++				       ctrl);
+ 	}
+ 
+-	out_be32(&tahp->tah_mr, TAH_MR_SR);
++	DBG2("%d: xmit_sg(%u) %d - %d" NL, dev->def->index, skb->len,
++	     dev->tx_slot, slot);
+ 
+-	/* wait for reset to complete */
+-	while (in_be32(&tahp->tah_mr) & TAH_MR_SR) ;
++	/* Attach skb to the last slot so we don't release it too early */
++	dev->tx_skb[slot] = skb;
+ 
+-	/* 10KB TAH TX FIFO accomodates the max MTU of 9000 */
+-	out_be32(&tahp->tah_mr,
+-		 TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
+-		 TAH_MR_DIG);
++	/* Send the packet out */
++	if (dev->tx_slot == NUM_TX_BUFF - 1)
++		ctrl |= MAL_TX_CTRL_WRAP;
++	barrier();
++	dev->tx_desc[dev->tx_slot].ctrl = ctrl;
++	dev->tx_slot = (slot + 1) % NUM_TX_BUFF;
+ 
+-	iounmap(tahp);
++	return emac_xmit_finish(dev, skb->len);
+ 
+-	return 0;
++      undo_frame:
++	/* Well, too bad. Our previous estimation was overly optimistic. 
++	 * Undo everything.
++	 */
++	while (slot != dev->tx_slot) {
++		dev->tx_desc[slot].ctrl = 0;
++		--dev->tx_cnt;
++		if (--slot < 0)
++			slot = NUM_TX_BUFF - 1;
++	}
++	++dev->estats.tx_undo;
++
++      stop_queue:
++	netif_stop_queue(ndev);
++	DBG2("%d: stopped TX queue" NL, dev->def->index);
++	return 1;
++}
++#else
++# define emac_start_xmit_sg	emac_start_xmit
++#endif	/* !defined(CONFIG_IBM_EMAC_TAH) */
++
++/* BHs disabled */
++static void emac_parse_tx_error(struct ocp_enet_private *dev, u16 ctrl)
++{
++	struct ibm_emac_error_stats *st = &dev->estats;
++	DBG("%d: BD TX error %04x" NL, dev->def->index, ctrl);
++
++	++st->tx_bd_errors;
++	if (ctrl & EMAC_TX_ST_BFCS)
++		++st->tx_bd_bad_fcs;
++	if (ctrl & EMAC_TX_ST_LCS)
++		++st->tx_bd_carrier_loss;
++	if (ctrl & EMAC_TX_ST_ED)
++		++st->tx_bd_excessive_deferral;
++	if (ctrl & EMAC_TX_ST_EC)
++		++st->tx_bd_excessive_collisions;
++	if (ctrl & EMAC_TX_ST_LC)
++		++st->tx_bd_late_collision;
++	if (ctrl & EMAC_TX_ST_MC)
++		++st->tx_bd_multple_collisions;
++	if (ctrl & EMAC_TX_ST_SC)
++		++st->tx_bd_single_collision;
++	if (ctrl & EMAC_TX_ST_UR)
++		++st->tx_bd_underrun;
++	if (ctrl & EMAC_TX_ST_SQE)
++		++st->tx_bd_sqe;
++}
++
++static void emac_poll_tx(void *param)
++{
++	struct ocp_enet_private *dev = param;
++	DBG2("%d: poll_tx, %d %d" NL, dev->def->index, dev->tx_cnt,
++	     dev->ack_slot);
++
++	if (dev->tx_cnt) {
++		u16 ctrl;
++		int slot = dev->ack_slot, n = 0;
++	      again:
++		ctrl = dev->tx_desc[slot].ctrl;
++		if (!(ctrl & MAL_TX_CTRL_READY)) {
++			struct sk_buff *skb = dev->tx_skb[slot];
++			++n;
++
++			if (skb) {
++				dev_kfree_skb(skb);
++				dev->tx_skb[slot] = NULL;
++			}
++			slot = (slot + 1) % NUM_TX_BUFF;
++
++			if (unlikely(EMAC_IS_BAD_TX(ctrl)))
++				emac_parse_tx_error(dev, ctrl);
++
++			if (--dev->tx_cnt)
++				goto again;
++		}
++		if (n) {
++			dev->ack_slot = slot;
++			if (netif_queue_stopped(dev->ndev) &&
++			    dev->tx_cnt < EMAC_TX_WAKEUP_THRESH)
++				netif_wake_queue(dev->ndev);
++
++			DBG2("%d: tx %d pkts" NL, dev->def->index, n);
++		}
++	}
+ }
+ 
+-static void emac_init_rings(struct net_device *dev)
++static inline void emac_recycle_rx_skb(struct ocp_enet_private *dev, int slot,
++				       int len)
+ {
+-	struct ocp_enet_private *ep = dev->priv;
+-	int loop;
++	struct sk_buff *skb = dev->rx_skb[slot];
++	DBG2("%d: recycle %d %d" NL, dev->def->index, slot, len);
+ 
+-	ep->tx_desc = (struct mal_descriptor *)((char *)ep->mal->tx_virt_addr +
+-						(ep->mal_tx_chan *
+-						 MAL_DT_ALIGN));
+-	ep->rx_desc =
+-	    (struct mal_descriptor *)((char *)ep->mal->rx_virt_addr +
+-				      (ep->mal_rx_chan * MAL_DT_ALIGN));
+-
+-	/* Fill in the transmit descriptor ring. */
+-	for (loop = 0; loop < NUM_TX_BUFF; loop++) {
+-		if (ep->tx_skb[loop]) {
+-			dma_unmap_single(&ep->ocpdev->dev,
+-					 ep->tx_desc[loop].data_ptr,
+-					 ep->tx_desc[loop].data_len,
+-					 DMA_TO_DEVICE);
+-			dev_kfree_skb_irq(ep->tx_skb[loop]);
+-		}
+-		ep->tx_skb[loop] = NULL;
+-		ep->tx_desc[loop].ctrl = 0;
+-		ep->tx_desc[loop].data_len = 0;
+-		ep->tx_desc[loop].data_ptr = NULL;
+-	}
+-	ep->tx_desc[loop - 1].ctrl |= MAL_TX_CTRL_WRAP;
+-
+-	/* Format the receive descriptor ring. */
+-	ep->rx_slot = 0;
+-	/* Default is MTU=1500 + Ethernet overhead */
+-	ep->rx_buffer_size = dev->mtu + ENET_HEADER_SIZE + ENET_FCS_SIZE;
+-	emac_rx_fill(dev, 0);
+-	if (ep->rx_slot != 0) {
+-		printk(KERN_ERR
+-		       "%s: Not enough mem for RxChain durning Open?\n",
+-		       dev->name);
+-		/*We couldn't fill the ring at startup?
+-		 *We could clean up and fail to open but right now we will try to
+-		 *carry on. It may be a sign of a bad NUM_RX_BUFF value
+-		 */
+-	}
++	if (len) 
++		dma_map_single(dev->ldev, skb->data - 2, 
++			       EMAC_DMA_ALIGN(len + 2), DMA_FROM_DEVICE);
+ 
+-	ep->tx_cnt = 0;
+-	ep->tx_slot = 0;
+-	ep->ack_slot = 0;
++	dev->rx_desc[slot].data_len = 0;
++	barrier();
++	dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
++	    (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
+ }
+ 
+-static void emac_reset_configure(struct ocp_enet_private *fep)
++static void emac_parse_rx_error(struct ocp_enet_private *dev, u16 ctrl)
+ {
+-	emac_t *emacp = fep->emacp;
+-	int i;
++	struct ibm_emac_error_stats *st = &dev->estats;
++	DBG("%d: BD RX error %04x" NL, dev->def->index, ctrl);
+ 
+-	mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+-	mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
++	++st->rx_bd_errors;
++	if (ctrl & EMAC_RX_ST_OE)
++		++st->rx_bd_overrun;
++	if (ctrl & EMAC_RX_ST_BP)
++		++st->rx_bd_bad_packet;
++	if (ctrl & EMAC_RX_ST_RP)
++		++st->rx_bd_runt_packet;
++	if (ctrl & EMAC_RX_ST_SE)
++		++st->rx_bd_short_event;
++	if (ctrl & EMAC_RX_ST_AE)
++		++st->rx_bd_alignment_error;
++	if (ctrl & EMAC_RX_ST_BFCS)
++		++st->rx_bd_bad_fcs;
++	if (ctrl & EMAC_RX_ST_PTL)
++		++st->rx_bd_packet_too_long;
++	if (ctrl & EMAC_RX_ST_ORE)
++		++st->rx_bd_out_of_range;
++	if (ctrl & EMAC_RX_ST_IRE)
++		++st->rx_bd_in_range;
++}
+ 
+-	/*
+-	 * Check for a link, some PHYs don't provide a clock if
+-	 * no link is present.  Some EMACs will not come out of
+-	 * soft reset without a PHY clock present.
+-	 */
+-	if (fep->phy_mii.def->ops->poll_link(&fep->phy_mii)) {
+-		/* Reset the EMAC */
+-		out_be32(&emacp->em0mr0, EMAC_M0_SRST);
+-		udelay(20);
+-		for (i = 0; i < 100; i++) {
+-			if ((in_be32(&emacp->em0mr0) & EMAC_M0_SRST) == 0)
+-				break;
+-			udelay(10);
+-		}
++static inline void emac_rx_csum(struct ocp_enet_private *dev,
++				struct sk_buff *skb, u16 ctrl)
++{
++#if defined(CONFIG_IBM_EMAC_TAH)
++	if (!ctrl && dev->tah_dev) {
++		skb->ip_summed = CHECKSUM_UNNECESSARY;
++		++dev->stats.rx_packets_csum;
++	}
++#endif
++}
+ 
+-		if (i >= 100) {
+-			printk(KERN_ERR "%s: Cannot reset EMAC\n",
+-			       fep->ndev->name);
+-			return;
++static inline int emac_rx_sg_append(struct ocp_enet_private *dev, int slot)
++{
++	if (likely(dev->rx_sg_skb != NULL)) {
++		int len = dev->rx_desc[slot].data_len;
++		int tot_len = dev->rx_sg_skb->len + len;
++
++		if (unlikely(tot_len + 2 > dev->rx_skb_size)) {
++			++dev->estats.rx_dropped_mtu;
++			dev_kfree_skb(dev->rx_sg_skb);
++			dev->rx_sg_skb = NULL;
++		} else {
++			cacheable_memcpy(dev->rx_sg_skb->tail,
++					 dev->rx_skb[slot]->data, len);
++			skb_put(dev->rx_sg_skb, len);
++			emac_recycle_rx_skb(dev, slot, len);
++			return 0;
+ 		}
+ 	}
++	emac_recycle_rx_skb(dev, slot, 0);
++	return -1;
++}
++
++/* BHs disabled */
++static int emac_poll_rx(void *param, int budget)
++{
++	struct ocp_enet_private *dev = param;
++	int slot = dev->rx_slot, received = 0;
+ 
+-	/* Switch IRQs off for now */
+-	out_be32(&emacp->em0iser, 0);
++	DBG2("%d: poll_rx(%d)" NL, dev->def->index, budget);
+ 
+-	/* Configure MAL rx channel */
+-	mal_set_rcbs(fep->mal, fep->mal_rx_chan, DESC_BUF_SIZE_REG);
++      again:
++	while (budget > 0) {
++		int len;
++		struct sk_buff *skb;
++		u16 ctrl = dev->rx_desc[slot].ctrl;
+ 
+-	/* set the high address */
+-	out_be32(&emacp->em0iahr,
+-		 (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]);
++		if (ctrl & MAL_RX_CTRL_EMPTY)
++			break;
+ 
+-	/* set the low address */
+-	out_be32(&emacp->em0ialr,
+-		 (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16)
+-		 | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]);
++		skb = dev->rx_skb[slot];
++		barrier();
++		len = dev->rx_desc[slot].data_len;
++
++		if (unlikely(!MAL_IS_SINGLE_RX(ctrl)))
++			goto sg;
++
++		ctrl &= EMAC_BAD_RX_MASK;
++		if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) {
++			emac_parse_rx_error(dev, ctrl);
++			++dev->estats.rx_dropped_error;
++			emac_recycle_rx_skb(dev, slot, 0);
++			len = 0;
++			goto next;
++		}
++
++		if (len && len < EMAC_RX_COPY_THRESH) {
++			struct sk_buff *copy_skb =
++			    alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC);
++			if (unlikely(!copy_skb))
++				goto oom;
++
++			skb_reserve(copy_skb, EMAC_RX_SKB_HEADROOM + 2);
++			cacheable_memcpy(copy_skb->data - 2, skb->data - 2,
++					 len + 2);
++			emac_recycle_rx_skb(dev, slot, len);
++			skb = copy_skb;
++		} else if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC)))
++			goto oom;
++
++		skb_put(skb, len);
++	      push_packet:
++		skb->dev = dev->ndev;
++		skb->protocol = eth_type_trans(skb, dev->ndev);
++		emac_rx_csum(dev, skb, ctrl);
++
++		if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
++			++dev->estats.rx_dropped_stack;
++	      next:
++		++dev->stats.rx_packets;
++	      skip:
++		dev->stats.rx_bytes += len;
++		slot = (slot + 1) % NUM_RX_BUFF;
++		--budget;
++		++received;
++		continue;
++	      sg:
++		if (ctrl & MAL_RX_CTRL_FIRST) {
++			BUG_ON(dev->rx_sg_skb);
++			if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC))) {
++				DBG("%d: rx OOM %d" NL, dev->def->index, slot);
++				++dev->estats.rx_dropped_oom;
++				emac_recycle_rx_skb(dev, slot, 0);
++			} else {
++				dev->rx_sg_skb = skb;
++				skb_put(skb, len);
++			}
++		} else if (!emac_rx_sg_append(dev, slot) &&
++			   (ctrl & MAL_RX_CTRL_LAST)) {
+ 
+-	/* Adjust to link */
+-	if (netif_carrier_ok(fep->ndev))
+-		emac_adjust_to_link(fep);
++			skb = dev->rx_sg_skb;
++			dev->rx_sg_skb = NULL;
+ 
+-	/* enable broadcast/individual address and RX FIFO defaults */
+-	out_be32(&emacp->em0rmr, EMAC_RMR_DEFAULT);
++			ctrl &= EMAC_BAD_RX_MASK;
++			if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) {
++				emac_parse_rx_error(dev, ctrl);
++				++dev->estats.rx_dropped_error;
++				dev_kfree_skb(skb);
++				len = 0;
++			} else
++				goto push_packet;
++		}
++		goto skip;
++	      oom:
++		DBG("%d: rx OOM %d" NL, dev->def->index, slot);
++		/* Drop the packet and recycle skb */
++		++dev->estats.rx_dropped_oom;
++		emac_recycle_rx_skb(dev, slot, 0);
++		goto next;
++	}
+ 
+-	/* set transmit request threshold register */
+-	out_be32(&emacp->em0trtr, EMAC_TRTR_DEFAULT);
++	if (received) {
++		DBG2("%d: rx %d BDs" NL, dev->def->index, received);
++		dev->rx_slot = slot;
++	}
+ 
+-	/* Reconfigure multicast */
+-	__emac_set_multicast_list(fep->ndev);
++	if (unlikely(budget && dev->commac.rx_stopped)) {
++		struct ocp_func_emac_data *emacdata = dev->def->additions;
+ 
+-	/* Set receiver/transmitter defaults */
+-	out_be32(&emacp->em0rwmr, EMAC_RWMR_DEFAULT);
+-	out_be32(&emacp->em0tmr0, EMAC_TMR0_DEFAULT);
+-	out_be32(&emacp->em0tmr1, EMAC_TMR1_DEFAULT);
++		barrier();
++		if (!(dev->rx_desc[slot].ctrl & MAL_RX_CTRL_EMPTY)) {
++			DBG2("%d: rx restart" NL, dev->def->index);
++			received = 0;
++			goto again;
++		}
+ 
+-	/* set frame gap */
+-	out_be32(&emacp->em0ipgvr, CONFIG_IBM_EMAC_FGAP);
+-	
+-	/* set VLAN Tag Protocol Identifier */
+-	out_be32(&emacp->em0vtpid, 0x8100);
++		if (dev->rx_sg_skb) {
++			DBG2("%d: dropping partial rx packet" NL,
++			     dev->def->index);
++			++dev->estats.rx_dropped_error;
++			dev_kfree_skb(dev->rx_sg_skb);
++			dev->rx_sg_skb = NULL;
++		}
+ 
+-	/* Init ring buffers */
+-	emac_init_rings(fep->ndev);
++		dev->commac.rx_stopped = 0;
++		mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
++		emac_rx_enable(dev);
++		dev->rx_slot = 0;
++	}
++	return received;
+ }
+ 
+-static void emac_kick(struct ocp_enet_private *fep)
++/* BHs disabled */
++static int emac_peek_rx(void *param)
+ {
+-	emac_t *emacp = fep->emacp;
+-	unsigned long emac_ier;
+-
+-	emac_ier = EMAC_ISR_PP | EMAC_ISR_BP | EMAC_ISR_RP |
+-	    EMAC_ISR_SE | EMAC_ISR_PTLE | EMAC_ISR_ALE |
+-	    EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE;
+-
+-	out_be32(&emacp->em0iser, emac_ier);
+-
+-	/* enable all MAL transmit and receive channels */
+-	mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+-	mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+-
+-	/* set transmit and receive enable */
+-	out_be32(&emacp->em0mr0, EMAC_M0_TXE | EMAC_M0_RXE);
++	struct ocp_enet_private *dev = param;
++	return !(dev->rx_desc[dev->rx_slot].ctrl & MAL_RX_CTRL_EMPTY);
+ }
+ 
+-static void
+-emac_start_link(struct ocp_enet_private *fep, struct ethtool_cmd *ep)
++/* BHs disabled */
++static int emac_peek_rx_sg(void *param)
+ {
+-	u32 advertise;
+-	int autoneg;
+-	int forced_speed;
+-	int forced_duplex;
++	struct ocp_enet_private *dev = param;
++	int slot = dev->rx_slot;
++	while (1) {
++		u16 ctrl = dev->rx_desc[slot].ctrl;
++		if (ctrl & MAL_RX_CTRL_EMPTY)
++			return 0;
++		else if (ctrl & MAL_RX_CTRL_LAST)
++			return 1;
++
++		slot = (slot + 1) % NUM_RX_BUFF;
++
++		/* I'm just being paranoid here :) */
++		if (unlikely(slot == dev->rx_slot))
++			return 0;
++	}
++}
+ 
+-	/* Default advertise */
+-	advertise = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+-	    ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+-	    ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full;
+-	autoneg = fep->want_autoneg;
+-	forced_speed = fep->phy_mii.speed;
+-	forced_duplex = fep->phy_mii.duplex;
++/* Hard IRQ */
++static void emac_rxde(void *param)
++{
++	struct ocp_enet_private *dev = param;
++	++dev->estats.rx_stopped;
++	emac_rx_disable_async(dev);
++}
++
++/* Hard IRQ */
++static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs)
++{
++	struct ocp_enet_private *dev = dev_instance;
++	struct emac_regs *p = dev->emacp;
++	struct ibm_emac_error_stats *st = &dev->estats;
++
++	u32 isr = in_be32(&p->isr);
++	out_be32(&p->isr, isr);
++
++	DBG("%d: isr = %08x" NL, dev->def->index, isr);
++
++	if (isr & EMAC_ISR_TXPE)
++		++st->tx_parity;
++	if (isr & EMAC_ISR_RXPE)
++		++st->rx_parity;
++	if (isr & EMAC_ISR_TXUE)
++		++st->tx_underrun;
++	if (isr & EMAC_ISR_RXOE)
++		++st->rx_fifo_overrun;
++	if (isr & EMAC_ISR_OVR)
++		++st->rx_overrun;
++	if (isr & EMAC_ISR_BP)
++		++st->rx_bad_packet;
++	if (isr & EMAC_ISR_RP)
++		++st->rx_runt_packet;
++	if (isr & EMAC_ISR_SE)
++		++st->rx_short_event;
++	if (isr & EMAC_ISR_ALE)
++		++st->rx_alignment_error;
++	if (isr & EMAC_ISR_BFCS)
++		++st->rx_bad_fcs;
++	if (isr & EMAC_ISR_PTLE)
++		++st->rx_packet_too_long;
++	if (isr & EMAC_ISR_ORE)
++		++st->rx_out_of_range;
++	if (isr & EMAC_ISR_IRE)
++		++st->rx_in_range;
++	if (isr & EMAC_ISR_SQE)
++		++st->tx_sqe;
++	if (isr & EMAC_ISR_TE)
++		++st->tx_errors;
+ 
+-	/* Setup link parameters */
+-	if (ep) {
+-		if (ep->autoneg == AUTONEG_ENABLE) {
+-			advertise = ep->advertising;
+-			autoneg = 1;
+-		} else {
+-			autoneg = 0;
+-			forced_speed = ep->speed;
+-			forced_duplex = ep->duplex;
+-		}
+-	}
++	return IRQ_HANDLED;
++}
+ 
+-	/* Configure PHY & start aneg */
+-	fep->want_autoneg = autoneg;
+-	if (autoneg) {
+-		LINK_DEBUG(("%s: start link aneg, advertise: 0x%x\n",
+-			    fep->ndev->name, advertise));
+-		fep->phy_mii.def->ops->setup_aneg(&fep->phy_mii, advertise);
+-	} else {
+-		LINK_DEBUG(("%s: start link forced, speed: %d, duplex: %d\n",
+-			    fep->ndev->name, forced_speed, forced_duplex));
+-		fep->phy_mii.def->ops->setup_forced(&fep->phy_mii, forced_speed,
+-						    forced_duplex);
+-	}
+-	fep->timer_ticks = 0;
+-	mod_timer(&fep->link_timer, jiffies + HZ);
++static struct net_device_stats *emac_stats(struct net_device *ndev)
++{
++	struct ocp_enet_private *dev = ndev->priv;
++	struct ibm_emac_stats *st = &dev->stats;
++	struct ibm_emac_error_stats *est = &dev->estats;
++	struct net_device_stats *nst = &dev->nstats;
++
++	DBG2("%d: stats" NL, dev->def->index);
++
++	/* Compute "legacy" statistics */
++	local_irq_disable();
++	nst->rx_packets = (unsigned long)st->rx_packets;
++	nst->rx_bytes = (unsigned long)st->rx_bytes;
++	nst->tx_packets = (unsigned long)st->tx_packets;
++	nst->tx_bytes = (unsigned long)st->tx_bytes;
++	nst->rx_dropped = (unsigned long)(est->rx_dropped_oom +
++					  est->rx_dropped_error +
++					  est->rx_dropped_resize +
++					  est->rx_dropped_mtu);
++	nst->tx_dropped = (unsigned long)est->tx_dropped;
++
++	nst->rx_errors = (unsigned long)est->rx_bd_errors;
++	nst->rx_fifo_errors = (unsigned long)(est->rx_bd_overrun +
++					      est->rx_fifo_overrun +
++					      est->rx_overrun);
++	nst->rx_frame_errors = (unsigned long)(est->rx_bd_alignment_error +
++					       est->rx_alignment_error);
++	nst->rx_crc_errors = (unsigned long)(est->rx_bd_bad_fcs +
++					     est->rx_bad_fcs);
++	nst->rx_length_errors = (unsigned long)(est->rx_bd_runt_packet +
++						est->rx_bd_short_event +
++						est->rx_bd_packet_too_long +
++						est->rx_bd_out_of_range +
++						est->rx_bd_in_range +
++						est->rx_runt_packet +
++						est->rx_short_event +
++						est->rx_packet_too_long +
++						est->rx_out_of_range +
++						est->rx_in_range);
++
++	nst->tx_errors = (unsigned long)(est->tx_bd_errors + est->tx_errors);
++	nst->tx_fifo_errors = (unsigned long)(est->tx_bd_underrun +
++					      est->tx_underrun);
++	nst->tx_carrier_errors = (unsigned long)est->tx_bd_carrier_loss;
++	nst->collisions = (unsigned long)(est->tx_bd_excessive_deferral +
++					  est->tx_bd_excessive_collisions +
++					  est->tx_bd_late_collision +
++					  est->tx_bd_multple_collisions);
++	local_irq_enable();
++	return nst;
+ }
+ 
+-static void emac_link_timer(unsigned long data)
++static void emac_remove(struct ocp_device *ocpdev)
+ {
+-	struct ocp_enet_private *fep = (struct ocp_enet_private *)data;
+-	int link;
++	struct ocp_enet_private *dev = ocp_get_drvdata(ocpdev);
+ 
+-	if (fep->going_away)
+-		return;
++	DBG("%d: remove" NL, dev->def->index);
+ 
+-	spin_lock_irq(&fep->lock);
++	ocp_set_drvdata(ocpdev, 0);
++	unregister_netdev(dev->ndev);
+ 
+-	link = fep->phy_mii.def->ops->poll_link(&fep->phy_mii);
+-	LINK_DEBUG(("%s: poll_link: %d\n", fep->ndev->name, link));
++	tah_fini(dev->tah_dev);
++	rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
++	zmii_fini(dev->zmii_dev, dev->zmii_input);
+ 
+-	if (link == netif_carrier_ok(fep->ndev)) {
+-		if (!link && fep->want_autoneg && (++fep->timer_ticks) > 10)
+-			emac_start_link(fep, NULL);
+-		goto out;
+-	}
+-	printk(KERN_INFO "%s: Link is %s\n", fep->ndev->name,
+-	       link ? "Up" : "Down");
+-	if (link) {
+-		netif_carrier_on(fep->ndev);
+-		/* Chip needs a full reset on config change. That sucks, so I
+-		 * should ultimately move that to some tasklet to limit
+-		 * latency peaks caused by this code
+-		 */
+-		emac_reset_configure(fep);
+-		if (fep->opened)
+-			emac_kick(fep);
+-	} else {
+-		fep->timer_ticks = 0;
+-		netif_carrier_off(fep->ndev);
+-	}
+-      out:
+-	mod_timer(&fep->link_timer, jiffies + HZ);
+-	spin_unlock_irq(&fep->lock);
++	emac_dbg_register(dev->def->index, 0);
++
++	mal_unregister_commac(dev->mal, &dev->commac);
++	iounmap((void *)dev->emacp);
++	kfree(dev->ndev);
+ }
+ 
+-static void emac_set_multicast_list(struct net_device *dev)
+-{
+-	struct ocp_enet_private *fep = dev->priv;
++static struct mal_commac_ops emac_commac_ops = {
++	.poll_tx = &emac_poll_tx,
++	.poll_rx = &emac_poll_rx,
++	.peek_rx = &emac_peek_rx,
++	.rxde = &emac_rxde,
++};
+ 
+-	spin_lock_irq(&fep->lock);
+-	__emac_set_multicast_list(dev);
+-	spin_unlock_irq(&fep->lock);
+-}
++static struct mal_commac_ops emac_commac_sg_ops = {
++	.poll_tx = &emac_poll_tx,
++	.poll_rx = &emac_poll_rx,
++	.peek_rx = &emac_peek_rx_sg,
++	.rxde = &emac_rxde,
++};
+ 
+-static int emac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
++/* Ethtool support */
++static int emac_ethtool_get_settings(struct net_device *ndev,
++				     struct ethtool_cmd *cmd)
+ {
+-	struct ocp_enet_private *fep = ndev->priv;
++	struct ocp_enet_private *dev = ndev->priv;
+ 
+-	cmd->supported = fep->phy_mii.def->features;
++	cmd->supported = dev->phy.features;
+ 	cmd->port = PORT_MII;
+-	cmd->transceiver = XCVR_EXTERNAL;
+-	cmd->phy_address = fep->mii_phy_addr;
+-	spin_lock_irq(&fep->lock);
+-	cmd->autoneg = fep->want_autoneg;
+-	cmd->speed = fep->phy_mii.speed;
+-	cmd->duplex = fep->phy_mii.duplex;
+-	spin_unlock_irq(&fep->lock);
++	cmd->phy_address = dev->phy.address;
++	cmd->transceiver =
++	    dev->phy.address >= 0 ? XCVR_EXTERNAL : XCVR_INTERNAL;
++
++	local_bh_disable();
++	cmd->advertising = dev->phy.advertising;
++	cmd->autoneg = dev->phy.autoneg;
++	cmd->speed = dev->phy.speed;
++	cmd->duplex = dev->phy.duplex;
++	local_bh_enable();
++
+ 	return 0;
+ }
+ 
+-static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
++static int emac_ethtool_set_settings(struct net_device *ndev,
++				     struct ethtool_cmd *cmd)
+ {
+-	struct ocp_enet_private *fep = ndev->priv;
+-	unsigned long features = fep->phy_mii.def->features;
++	struct ocp_enet_private *dev = ndev->priv;
++	u32 f = dev->phy.features;
+ 
+-	if (!capable(CAP_NET_ADMIN))
+-		return -EPERM;
++	DBG("%d: set_settings(%d, %d, %d, 0x%08x)" NL, dev->def->index,
++	    cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising);
+ 
++	/* Basic sanity checks */
++	if (dev->phy.address < 0)
++		return -EOPNOTSUPP;
+ 	if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
+ 		return -EINVAL;
+ 	if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
+ 		return -EINVAL;
+ 	if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
+ 		return -EINVAL;
+-	if (cmd->autoneg == AUTONEG_DISABLE)
++
++	if (cmd->autoneg == AUTONEG_DISABLE) {
+ 		switch (cmd->speed) {
+ 		case SPEED_10:
+-			if (cmd->duplex == DUPLEX_HALF &&
+-			    (features & SUPPORTED_10baseT_Half) == 0)
++			if (cmd->duplex == DUPLEX_HALF
++			    && !(f & SUPPORTED_10baseT_Half))
+ 				return -EINVAL;
+-			if (cmd->duplex == DUPLEX_FULL &&
+-			    (features & SUPPORTED_10baseT_Full) == 0)
++			if (cmd->duplex == DUPLEX_FULL
++			    && !(f & SUPPORTED_10baseT_Full))
+ 				return -EINVAL;
+ 			break;
+ 		case SPEED_100:
+-			if (cmd->duplex == DUPLEX_HALF &&
+-			    (features & SUPPORTED_100baseT_Half) == 0)
++			if (cmd->duplex == DUPLEX_HALF
++			    && !(f & SUPPORTED_100baseT_Half))
+ 				return -EINVAL;
+-			if (cmd->duplex == DUPLEX_FULL &&
+-			    (features & SUPPORTED_100baseT_Full) == 0)
++			if (cmd->duplex == DUPLEX_FULL
++			    && !(f & SUPPORTED_100baseT_Full))
+ 				return -EINVAL;
+ 			break;
+ 		case SPEED_1000:
+-			if (cmd->duplex == DUPLEX_HALF &&
+-			    (features & SUPPORTED_1000baseT_Half) == 0)
++			if (cmd->duplex == DUPLEX_HALF
++			    && !(f & SUPPORTED_1000baseT_Half))
+ 				return -EINVAL;
+-			if (cmd->duplex == DUPLEX_FULL &&
+-			    (features & SUPPORTED_1000baseT_Full) == 0)
++			if (cmd->duplex == DUPLEX_FULL
++			    && !(f & SUPPORTED_1000baseT_Full))
+ 				return -EINVAL;
+ 			break;
+ 		default:
+ 			return -EINVAL;
+-	} else if ((features & SUPPORTED_Autoneg) == 0)
+-		return -EINVAL;
+-	spin_lock_irq(&fep->lock);
+-	emac_start_link(fep, cmd);
+-	spin_unlock_irq(&fep->lock);
++		}
++
++		local_bh_disable();
++		dev->phy.def->ops->setup_forced(&dev->phy, cmd->speed,
++						cmd->duplex);
++
++	} else {
++		if (!(f & SUPPORTED_Autoneg))
++			return -EINVAL;
++
++		local_bh_disable();
++		dev->phy.def->ops->setup_aneg(&dev->phy,
++					      (cmd->advertising & f) |
++					      (dev->phy.advertising &
++					       (ADVERTISED_Pause |
++						ADVERTISED_Asym_Pause)));
++	}
++	emac_force_link_update(dev);
++	local_bh_enable();
++
+ 	return 0;
+ }
+ 
+-static void
+-emac_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
++static void emac_ethtool_get_ringparam(struct net_device *ndev,
++				       struct ethtool_ringparam *rp)
++{
++	rp->rx_max_pending = rp->rx_pending = NUM_RX_BUFF;
++	rp->tx_max_pending = rp->tx_pending = NUM_TX_BUFF;
++}
++
++static void emac_ethtool_get_pauseparam(struct net_device *ndev,
++					struct ethtool_pauseparam *pp)
+ {
+-	struct ocp_enet_private *fep = ndev->priv;
++	struct ocp_enet_private *dev = ndev->priv;
+ 
+-	strcpy(info->driver, DRV_NAME);
+-	strcpy(info->version, DRV_VERSION);
+-	info->fw_version[0] = '\0';
+-	sprintf(info->bus_info, "IBM EMAC %d", fep->ocpdev->def->index);
+-	info->regdump_len = 0;
++	local_bh_disable();
++	if ((dev->phy.features & SUPPORTED_Autoneg) &&
++	    (dev->phy.advertising & (ADVERTISED_Pause | ADVERTISED_Asym_Pause)))
++		pp->autoneg = 1;
++
++	if (dev->phy.duplex == DUPLEX_FULL) {
++		if (dev->phy.pause)
++			pp->rx_pause = pp->tx_pause = 1;
++		else if (dev->phy.asym_pause)
++			pp->tx_pause = 1;
++	}
++	local_bh_enable();
+ }
+ 
+-static int emac_nway_reset(struct net_device *ndev)
++static u32 emac_ethtool_get_rx_csum(struct net_device *ndev)
+ {
+-	struct ocp_enet_private *fep = ndev->priv;
++	struct ocp_enet_private *dev = ndev->priv;
++	return dev->tah_dev != 0;
++}
+ 
+-	if (!fep->want_autoneg)
+-		return -EINVAL;
+-	spin_lock_irq(&fep->lock);
+-	emac_start_link(fep, NULL);
+-	spin_unlock_irq(&fep->lock);
+-	return 0;
++static int emac_get_regs_len(struct ocp_enet_private *dev)
++{
++	return sizeof(struct emac_ethtool_regs_subhdr) + EMAC_ETHTOOL_REGS_SIZE;
+ }
+ 
+-static u32 emac_get_link(struct net_device *ndev)
++static int emac_ethtool_get_regs_len(struct net_device *ndev)
+ {
+-	return netif_carrier_ok(ndev);
++	struct ocp_enet_private *dev = ndev->priv;
++	return sizeof(struct emac_ethtool_regs_hdr) +
++	    emac_get_regs_len(dev) + mal_get_regs_len(dev->mal) +
++	    zmii_get_regs_len(dev->zmii_dev) +
++	    rgmii_get_regs_len(dev->rgmii_dev) +
++	    tah_get_regs_len(dev->tah_dev);
+ }
+ 
+-static struct ethtool_ops emac_ethtool_ops = {
+-	.get_settings = emac_get_settings,
+-	.set_settings = emac_set_settings,
+-	.get_drvinfo = emac_get_drvinfo,
+-	.nway_reset = emac_nway_reset,
+-	.get_link = emac_get_link
+-};
++static void *emac_dump_regs(struct ocp_enet_private *dev, void *buf)
++{
++	struct emac_ethtool_regs_subhdr *hdr = buf;
++
++	hdr->version = EMAC_ETHTOOL_REGS_VER;
++	hdr->index = dev->def->index;
++	memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE);
++	return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE);
++}
+ 
+-static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
++static void emac_ethtool_get_regs(struct net_device *ndev,
++				  struct ethtool_regs *regs, void *buf)
+ {
+-	struct ocp_enet_private *fep = dev->priv;
+-	uint16_t *data = (uint16_t *) & rq->ifr_ifru;
++	struct ocp_enet_private *dev = ndev->priv;
++	struct emac_ethtool_regs_hdr *hdr = buf;
+ 
+-	switch (cmd) {
+-	case SIOCGMIIPHY:
+-		data[0] = fep->mii_phy_addr;
+-		/* Fall through */
+-	case SIOCGMIIREG:
+-		data[3] = emac_phy_read(dev, fep->mii_phy_addr, data[1]);
+-		return 0;
+-	case SIOCSMIIREG:
+-		if (!capable(CAP_NET_ADMIN))
+-			return -EPERM;
++	hdr->components = 0;
++	buf = hdr + 1;
+ 
+-		emac_phy_write(dev, fep->mii_phy_addr, data[1], data[2]);
+-		return 0;
+-	default:
+-		return -EOPNOTSUPP;
++	local_irq_disable();
++	buf = mal_dump_regs(dev->mal, buf);
++	buf = emac_dump_regs(dev, buf);
++	if (dev->zmii_dev) {
++		hdr->components |= EMAC_ETHTOOL_REGS_ZMII;
++		buf = zmii_dump_regs(dev->zmii_dev, buf);
++	}
++	if (dev->rgmii_dev) {
++		hdr->components |= EMAC_ETHTOOL_REGS_RGMII;
++		buf = rgmii_dump_regs(dev->rgmii_dev, buf);
+ 	}
++	if (dev->tah_dev) {
++		hdr->components |= EMAC_ETHTOOL_REGS_TAH;
++		buf = tah_dump_regs(dev->tah_dev, buf);
++	}
++	local_irq_enable();
+ }
+ 
+-static int emac_open(struct net_device *dev)
++static int emac_ethtool_nway_reset(struct net_device *ndev)
+ {
+-	struct ocp_enet_private *fep = dev->priv;
+-	int rc;
++	struct ocp_enet_private *dev = ndev->priv;
++	int res = 0;
+ 
+-	spin_lock_irq(&fep->lock);
++	DBG("%d: nway_reset" NL, dev->def->index);
+ 
+-	fep->opened = 1;
+-	netif_carrier_off(dev);
++	if (dev->phy.address < 0)
++		return -EOPNOTSUPP;
+ 
+-	/* Reset & configure the chip */
+-	emac_reset_configure(fep);
++	local_bh_disable();
++	if (!dev->phy.autoneg) {
++		res = -EINVAL;
++		goto out;
++	}
+ 
+-	spin_unlock_irq(&fep->lock);
++	dev->phy.def->ops->setup_aneg(&dev->phy, dev->phy.advertising);
++	emac_force_link_update(dev);
+ 
+-	/* Request our interrupt lines */
+-	rc = request_irq(dev->irq, emac_mac_irq, 0, "IBM EMAC MAC", dev);
+-	if (rc != 0) {
+-		printk("dev->irq %d failed\n", dev->irq);
+-		goto bail;
+-	}
+-	/* Kick the chip rx & tx channels into life */
+-	spin_lock_irq(&fep->lock);
+-	emac_kick(fep);
+-	spin_unlock_irq(&fep->lock);
++      out:
++	local_bh_enable();
++	return res;
++}
+ 
+-	netif_start_queue(dev);
+-      bail:
+-	return rc;
++static int emac_ethtool_get_stats_count(struct net_device *ndev)
++{
++	return EMAC_ETHTOOL_STATS_COUNT;
+ }
+ 
+-static int emac_close(struct net_device *dev)
++static void emac_ethtool_get_strings(struct net_device *ndev, u32 stringset,
++				     u8 * buf)
+ {
+-	struct ocp_enet_private *fep = dev->priv;
+-	emac_t *emacp = fep->emacp;
++	if (stringset == ETH_SS_STATS)
++		memcpy(buf, &emac_stats_keys, sizeof(emac_stats_keys));
++}
+ 
+-	/* XXX Stop IRQ emitting here */
+-	spin_lock_irq(&fep->lock);
+-	fep->opened = 0;
+-	mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+-	mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+-	netif_carrier_off(dev);
+-	netif_stop_queue(dev);
++static void emac_ethtool_get_ethtool_stats(struct net_device *ndev,
++					   struct ethtool_stats *estats,
++					   u64 * tmp_stats)
++{
++	struct ocp_enet_private *dev = ndev->priv;
++	local_irq_disable();
++	memcpy(tmp_stats, &dev->stats, sizeof(dev->stats));
++	tmp_stats += sizeof(dev->stats) / sizeof(u64);
++	memcpy(tmp_stats, &dev->estats, sizeof(dev->estats));
++	local_irq_enable();
++}
+ 
+-	/*
+-	 * Check for a link, some PHYs don't provide a clock if
+-	 * no link is present.  Some EMACs will not come out of
+-	 * soft reset without a PHY clock present.
+-	 */
+-	if (fep->phy_mii.def->ops->poll_link(&fep->phy_mii)) {
+-		out_be32(&emacp->em0mr0, EMAC_M0_SRST);
+-		udelay(10);
++static void emac_ethtool_get_drvinfo(struct net_device *ndev,
++				     struct ethtool_drvinfo *info)
++{
++	struct ocp_enet_private *dev = ndev->priv;
+ 
+-		if (emacp->em0mr0 & EMAC_M0_SRST) {
+-			/*not sure what to do here hopefully it clears before another open */
+-			printk(KERN_ERR
+-			       "%s: Phy SoftReset didn't clear, no link?\n",
+-			       dev->name);
+-		}
+-	}
++	strcpy(info->driver, "ibm_emac");
++	strcpy(info->version, DRV_VERSION);
++	info->fw_version[0] = '\0';
++	sprintf(info->bus_info, "PPC 4xx EMAC %d", dev->def->index);
++	info->n_stats = emac_ethtool_get_stats_count(ndev);
++	info->regdump_len = emac_ethtool_get_regs_len(ndev);
++}
+ 
+-	/* Free the irq's */
+-	free_irq(dev->irq, dev);
++static struct ethtool_ops emac_ethtool_ops = {
++	.get_settings = emac_ethtool_get_settings,
++	.set_settings = emac_ethtool_set_settings,
++	.get_drvinfo = emac_ethtool_get_drvinfo,
+ 
+-	spin_unlock_irq(&fep->lock);
++	.get_regs_len = emac_ethtool_get_regs_len,
++	.get_regs = emac_ethtool_get_regs,
+ 
+-	return 0;
+-}
++	.nway_reset = emac_ethtool_nway_reset,
+ 
+-static void emac_remove(struct ocp_device *ocpdev)
+-{
+-	struct net_device *dev = ocp_get_drvdata(ocpdev);
+-	struct ocp_enet_private *ep = dev->priv;
++	.get_ringparam = emac_ethtool_get_ringparam,
++	.get_pauseparam = emac_ethtool_get_pauseparam,
+ 
+-	/* FIXME: locking, races, ... */
+-	ep->going_away = 1;
+-	ocp_set_drvdata(ocpdev, NULL);
+-	if (ep->rgmii_dev)
+-		emac_close_rgmii(ep->rgmii_dev);
+-	if (ep->zmii_dev)
+-		emac_close_zmii(ep->zmii_dev);
+-
+-	unregister_netdev(dev);
+-	del_timer_sync(&ep->link_timer);
+-	mal_unregister_commac(ep->mal, &ep->commac);
+-	iounmap((void *)ep->emacp);
+-	kfree(dev);
+-}
+-
+-struct mal_commac_ops emac_commac_ops = {
+-	.txeob = &emac_txeob_dev,
+-	.txde = &emac_txde_dev,
+-	.rxeob = &emac_rxeob_dev,
+-	.rxde = &emac_rxde_dev,
++	.get_rx_csum = emac_ethtool_get_rx_csum,
++
++	.get_strings = emac_ethtool_get_strings,
++	.get_stats_count = emac_ethtool_get_stats_count,
++	.get_ethtool_stats = emac_ethtool_get_ethtool_stats,
++
++	.get_link = ethtool_op_get_link,
++	.get_tx_csum = ethtool_op_get_tx_csum,
++	.get_sg = ethtool_op_get_sg,
+ };
+ 
+-#ifdef CONFIG_NET_POLL_CONTROLLER
+-static void emac_netpoll(struct net_device *ndev)
++static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
+ {
+-	emac_rxeob_dev((void *)ndev, 0);
+-	emac_txeob_dev((void *)ndev, 0);
++	struct ocp_enet_private *dev = ndev->priv;
++	uint16_t *data = (uint16_t *) & rq->ifr_ifru;
++
++	DBG("%d: ioctl %08x" NL, dev->def->index, cmd);
++
++	if (dev->phy.address < 0)
++		return -EOPNOTSUPP;
++
++	switch (cmd) {
++	case SIOCGMIIPHY:
++	case SIOCDEVPRIVATE:
++		data[0] = dev->phy.address;
++		/* Fall through */
++	case SIOCGMIIREG:
++	case SIOCDEVPRIVATE + 1:
++		data[3] = emac_mdio_read(ndev, dev->phy.address, data[1]);
++		return 0;
++
++	case SIOCSMIIREG:
++	case SIOCDEVPRIVATE + 2:
++		if (!capable(CAP_NET_ADMIN))
++			return -EPERM;
++		emac_mdio_write(ndev, dev->phy.address, data[1], data[2]);
++		return 0;
++	default:
++		return -EOPNOTSUPP;
++	}
+ }
+-#endif
+ 
+-static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
++static int __init emac_probe(struct ocp_device *ocpdev)
+ {
+-	int deferred_init = 0;
+-	int rc = 0, i;
++	struct ocp_func_emac_data *emacdata = ocpdev->def->additions;
+ 	struct net_device *ndev;
+-	struct ocp_enet_private *ep;
+-	struct ocp_func_emac_data *emacdata;
+-	int commac_reg = 0;
+-	u32 phy_map;
++	struct ocp_device *maldev;
++	struct ocp_enet_private *dev;
++	int err, i;
++
++	DBG("%d: probe" NL, ocpdev->def->index);
+ 
+-	emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions;
+ 	if (!emacdata) {
+ 		printk(KERN_ERR "emac%d: Missing additional data!\n",
+ 		       ocpdev->def->index);
+@@ -1738,304 +1936,312 @@ static int emac_init_device(struct ocp_d
+ 
+ 	/* Allocate our net_device structure */
+ 	ndev = alloc_etherdev(sizeof(struct ocp_enet_private));
+-	if (ndev == NULL) {
+-		printk(KERN_ERR
+-		       "emac%d: Could not allocate ethernet device.\n",
++	if (!ndev) {
++		printk(KERN_ERR "emac%d: could not allocate ethernet device!\n",
+ 		       ocpdev->def->index);
+ 		return -ENOMEM;
+ 	}
+-	ep = ndev->priv;
+-	ep->ndev = ndev;
+-	ep->ocpdev = ocpdev;
+-	ndev->irq = ocpdev->def->irq;
+-	ep->wol_irq = emacdata->wol_irq;
+-	if (emacdata->mdio_idx >= 0) {
+-		if (emacdata->mdio_idx == ocpdev->def->index) {
+-			/* Set the common MDIO net_device */
+-			mdio_ndev = ndev;
+-			deferred_init = 1;
++	dev = ndev->priv;
++	dev->ndev = ndev;
++	dev->ldev = &ocpdev->dev;
++	dev->def = ocpdev->def;
++	SET_MODULE_OWNER(ndev);
++
++	/* Find MAL device we are connected to */
++	maldev =
++	    ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_MAL, emacdata->mal_idx);
++	if (!maldev) {
++		printk(KERN_ERR "emac%d: unknown mal%d device!\n",
++		       dev->def->index, emacdata->mal_idx);
++		err = -ENODEV;
++		goto out;
++	}
++	dev->mal = ocp_get_drvdata(maldev);
++	if (!dev->mal) {
++		printk(KERN_ERR "emac%d: mal%d hasn't been initialized yet!\n",
++		       dev->def->index, emacdata->mal_idx);
++		err = -ENODEV;
++		goto out;
++	}
++
++	/* Register with MAL */
++	dev->commac.ops = &emac_commac_ops;
++	dev->commac.dev = dev;
++	dev->commac.tx_chan_mask = MAL_CHAN_MASK(emacdata->mal_tx_chan);
++	dev->commac.rx_chan_mask = MAL_CHAN_MASK(emacdata->mal_rx_chan);
++	err = mal_register_commac(dev->mal, &dev->commac);
++	if (err) {
++		printk(KERN_ERR "emac%d: failed to register with mal%d!\n",
++		       dev->def->index, emacdata->mal_idx);
++		goto out;
++	}
++	dev->rx_skb_size = emac_rx_skb_size(ndev->mtu);
++	dev->rx_sync_size = emac_rx_sync_size(ndev->mtu);
++
++	/* Get pointers to BD rings */
++	dev->tx_desc =
++	    dev->mal->bd_virt + mal_tx_bd_offset(dev->mal,
++						 emacdata->mal_tx_chan);
++	dev->rx_desc =
++	    dev->mal->bd_virt + mal_rx_bd_offset(dev->mal,
++						 emacdata->mal_rx_chan);
++
++	DBG("%d: tx_desc %p" NL, ocpdev->def->index, dev->tx_desc);
++	DBG("%d: rx_desc %p" NL, ocpdev->def->index, dev->rx_desc);
++
++	/* Clean rings */
++	memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor));
++	memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor));
++
++	/* If we depend on another EMAC for MDIO, check whether it was probed already */
++	if (emacdata->mdio_idx >= 0 && emacdata->mdio_idx != ocpdev->def->index) {
++		struct ocp_device *mdiodev =
++		    ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC,
++				    emacdata->mdio_idx);
++		if (!mdiodev) {
++			printk(KERN_ERR "emac%d: unknown emac%d device!\n",
++			       dev->def->index, emacdata->mdio_idx);
++			err = -ENODEV;
++			goto out2;
++		}
++		dev->mdio_dev = ocp_get_drvdata(mdiodev);
++		if (!dev->mdio_dev) {
++			printk(KERN_ERR
++			       "emac%d: emac%d hasn't been initialized yet!\n",
++			       dev->def->index, emacdata->mdio_idx);
++			err = -ENODEV;
++			goto out2;
+ 		}
+-		ep->mdio_dev = mdio_ndev;
+-	} else {
+-		ep->mdio_dev = ndev;
+ 	}
+ 
+-	ocp_set_drvdata(ocpdev, ndev);
++	/* Attach to ZMII, if needed */
++	if ((err = zmii_attach(dev)) != 0)
++		goto out2;
++
++	/* Attach to RGMII, if needed */
++	if ((err = rgmii_attach(dev)) != 0)
++		goto out3;
++
++	/* Attach to TAH, if needed */
++	if ((err = tah_attach(dev)) != 0)
++		goto out4;
++
++	/* Map EMAC regs */
++	dev->emacp =
++	    (struct emac_regs *)ioremap(dev->def->paddr,
++					sizeof(struct emac_regs));
++	if (!dev->emacp) {
++		printk(KERN_ERR "emac%d: could not ioremap device registers!\n",
++		       dev->def->index);
++		err = -ENOMEM;
++		goto out5;
++	}
++
++	/* Fill in MAC address */
++	for (i = 0; i < 6; ++i)
++		ndev->dev_addr[i] = emacdata->mac_addr[i];
+ 
+-	spin_lock_init(&ep->lock);
++	/* Set some link defaults before we can find out real parameters */
++	dev->phy.speed = SPEED_100;
++	dev->phy.duplex = DUPLEX_FULL;
++	dev->phy.autoneg = AUTONEG_DISABLE;
++	dev->phy.pause = dev->phy.asym_pause = 0;
++	init_timer(&dev->link_timer);
++	dev->link_timer.function = emac_link_timer;
++	dev->link_timer.data = (unsigned long)dev;
++
++	/* Find PHY if any */
++	dev->phy.dev = ndev;
++	dev->phy.mode = emacdata->phy_mode;
++	if (emacdata->phy_map != 0xffffffff) {
++		u32 phy_map = emacdata->phy_map | busy_phy_map;
++		u32 adv;
++
++		DBG("%d: PHY maps %08x %08x" NL, dev->def->index,
++		    emacdata->phy_map, busy_phy_map);
+ 
+-	/* Fill out MAL informations and register commac */
+-	ep->mal = mal;
+-	ep->mal_tx_chan = emacdata->mal_tx_chan;
+-	ep->mal_rx_chan = emacdata->mal_rx_chan;
+-	ep->commac.ops = &emac_commac_ops;
+-	ep->commac.dev = ndev;
+-	ep->commac.tx_chan_mask = MAL_CHAN_MASK(ep->mal_tx_chan);
+-	ep->commac.rx_chan_mask = MAL_CHAN_MASK(ep->mal_rx_chan);
+-	rc = mal_register_commac(ep->mal, &ep->commac);
+-	if (rc != 0)
+-		goto bail;
+-	commac_reg = 1;
+-
+-	/* Map our MMIOs */
+-	ep->emacp = (emac_t *) ioremap(ocpdev->def->paddr, sizeof(emac_t));
+-
+-	/* Check if we need to attach to a ZMII */
+-	if (emacdata->zmii_idx >= 0) {
+-		ep->zmii_input = emacdata->zmii_mux;
+-		ep->zmii_dev =
+-		    ocp_find_device(OCP_ANY_ID, OCP_FUNC_ZMII,
+-				    emacdata->zmii_idx);
+-		if (ep->zmii_dev == NULL)
+-			printk(KERN_WARNING
+-			       "emac%d: ZMII %d requested but not found !\n",
+-			       ocpdev->def->index, emacdata->zmii_idx);
+-		else if ((rc =
+-			  emac_init_zmii(ep->zmii_dev, ep->zmii_input,
+-					 emacdata->phy_mode)) != 0)
+-			goto bail;
+-	}
+-
+-	/* Check if we need to attach to a RGMII */
+-	if (emacdata->rgmii_idx >= 0) {
+-		ep->rgmii_input = emacdata->rgmii_mux;
+-		ep->rgmii_dev =
+-		    ocp_find_device(OCP_ANY_ID, OCP_FUNC_RGMII,
+-				    emacdata->rgmii_idx);
+-		if (ep->rgmii_dev == NULL)
+-			printk(KERN_WARNING
+-			       "emac%d: RGMII %d requested but not found !\n",
+-			       ocpdev->def->index, emacdata->rgmii_idx);
+-		else if ((rc =
+-			  emac_init_rgmii(ep->rgmii_dev, ep->rgmii_input,
+-					  emacdata->phy_mode)) != 0)
+-			goto bail;
+-	}
+-
+-	/* Check if we need to attach to a TAH */
+-	if (emacdata->tah_idx >= 0) {
+-		ep->tah_dev =
+-		    ocp_find_device(OCP_ANY_ID, OCP_FUNC_TAH,
+-				    emacdata->tah_idx);
+-		if (ep->tah_dev == NULL)
+-			printk(KERN_WARNING
+-			       "emac%d: TAH %d requested but not found !\n",
+-			       ocpdev->def->index, emacdata->tah_idx);
+-		else if ((rc = emac_init_tah(ep)) != 0)
+-			goto bail;
+-	}
+-
+-	if (deferred_init) {
+-		if (!list_empty(&emac_init_list)) {
+-			struct list_head *entry;
+-			struct emac_def_dev *ddev;
+-
+-			list_for_each(entry, &emac_init_list) {
+-				ddev =
+-				    list_entry(entry, struct emac_def_dev,
+-					       link);
+-				emac_init_device(ddev->ocpdev, ddev->mal);
+-			}
++		EMAC_RX_CLK_TX(dev->def->index);
++
++		dev->phy.mdio_read = emac_mdio_read;
++		dev->phy.mdio_write = emac_mdio_write;
++
++		/* Configure EMAC with defaults so we can at least use MDIO
++		 * This is needed mostly for 440GX
++		 */
++		if (emac_phy_gpcs(dev->phy.mode)) {
++			/* XXX
++			 * Make GPCS PHY address equal to EMAC index.
++			 * We probably should take into account busy_phy_map
++			 * and/or phy_map here.
++			 */
++			dev->phy.address = dev->def->index;
+ 		}
+-	}
++		
++		emac_configure(dev);
+ 
+-	/* Init link monitoring timer */
+-	init_timer(&ep->link_timer);
+-	ep->link_timer.function = emac_link_timer;
+-	ep->link_timer.data = (unsigned long)ep;
+-	ep->timer_ticks = 0;
+-
+-	/* Fill up the mii_phy structure */
+-	ep->phy_mii.dev = ndev;
+-	ep->phy_mii.mdio_read = emac_phy_read;
+-	ep->phy_mii.mdio_write = emac_phy_write;
+-	ep->phy_mii.mode = emacdata->phy_mode;
+-
+-	/* Find PHY */
+-	phy_map = emacdata->phy_map | busy_phy_map;
+-	for (i = 0; i <= 0x1f; i++, phy_map >>= 1) {
+-		if ((phy_map & 0x1) == 0) {
+-			int val = emac_phy_read(ndev, i, MII_BMCR);
+-			if (val != 0xffff && val != -1)
+-				break;
++		for (i = 0; i < 0x20; phy_map >>= 1, ++i)
++			if (!(phy_map & 1)) {
++				int r;
++				busy_phy_map |= 1 << i;
++
++				/* Quick check if there is a PHY at the address */
++				r = emac_mdio_read(dev->ndev, i, MII_BMCR);
++				if (r == 0xffff || r < 0)
++					continue;
++				if (!mii_phy_probe(&dev->phy, i))
++					break;
++			}
++		if (i == 0x20) {
++			printk(KERN_WARNING "emac%d: can't find PHY!\n",
++			       dev->def->index);
++			goto out6;
+ 		}
+-	}
+-	if (i == 0x20) {
+-		printk(KERN_WARNING "emac%d: Can't find PHY.\n",
+-		       ocpdev->def->index);
+-		rc = -ENODEV;
+-		goto bail;
+-	}
+-	busy_phy_map |= 1 << i;
+-	ep->mii_phy_addr = i;
+-	rc = mii_phy_probe(&ep->phy_mii, i);
+-	if (rc) {
+-		printk(KERN_WARNING "emac%d: Failed to probe PHY type.\n",
+-		       ocpdev->def->index);
+-		rc = -ENODEV;
+-		goto bail;
+-	}
+-	
+-	/* Disable any PHY features not supported by the platform */
+-	ep->phy_mii.def->features &= ~emacdata->phy_feat_exc;
+-
+-	/* Setup initial PHY config & startup aneg */
+-	if (ep->phy_mii.def->ops->init)
+-		ep->phy_mii.def->ops->init(&ep->phy_mii);
+-	netif_carrier_off(ndev);
+-	if (ep->phy_mii.def->features & SUPPORTED_Autoneg)
+-		ep->want_autoneg = 1;
+-	else {
+-		ep->want_autoneg = 0;
++
++		/* Init PHY */
++		if (dev->phy.def->ops->init)
++			dev->phy.def->ops->init(&dev->phy);
+ 		
+-		/* Select highest supported speed/duplex */
+-		if (ep->phy_mii.def->features & SUPPORTED_1000baseT_Full) {
+-			ep->phy_mii.speed = SPEED_1000;
+-			ep->phy_mii.duplex = DUPLEX_FULL;
+-		} else if (ep->phy_mii.def->features & 
+-			   SUPPORTED_1000baseT_Half) {
+-			ep->phy_mii.speed = SPEED_1000;
+-			ep->phy_mii.duplex = DUPLEX_HALF;
+-		} else if (ep->phy_mii.def->features & 
+-			   SUPPORTED_100baseT_Full) {
+-			ep->phy_mii.speed = SPEED_100;
+-			ep->phy_mii.duplex = DUPLEX_FULL;
+-		} else if (ep->phy_mii.def->features & 
+-			   SUPPORTED_100baseT_Half) {
+-			ep->phy_mii.speed = SPEED_100;
+-			ep->phy_mii.duplex = DUPLEX_HALF;
+-		} else if (ep->phy_mii.def->features & 
+-			   SUPPORTED_10baseT_Full) {
+-			ep->phy_mii.speed = SPEED_10;
+-			ep->phy_mii.duplex = DUPLEX_FULL;
++		/* Disable any PHY features not supported by the platform */
++		dev->phy.def->features &= ~emacdata->phy_feat_exc;
++
++		/* Setup initial link parameters */
++		if (dev->phy.features & SUPPORTED_Autoneg) {
++			adv = dev->phy.features;
++#if !defined(CONFIG_40x)
++			adv |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
++#endif
++			/* Restart autonegotiation */
++			dev->phy.def->ops->setup_aneg(&dev->phy, adv);
+ 		} else {
+-			ep->phy_mii.speed = SPEED_10;
+-			ep->phy_mii.duplex = DUPLEX_HALF;
++			u32 f = dev->phy.def->features;
++			int speed = SPEED_10, fd = DUPLEX_HALF;
++
++			/* Select highest supported speed/duplex */
++			if (f & SUPPORTED_1000baseT_Full) {
++				speed = SPEED_1000;
++				fd = DUPLEX_FULL;
++			} else if (f & SUPPORTED_1000baseT_Half)
++				speed = SPEED_1000;
++			else if (f & SUPPORTED_100baseT_Full) {
++				speed = SPEED_100;
++				fd = DUPLEX_FULL;
++			} else if (f & SUPPORTED_100baseT_Half)
++				speed = SPEED_100;
++			else if (f & SUPPORTED_10baseT_Full)
++				fd = DUPLEX_FULL;
++
++			/* Force link parameters */
++			dev->phy.def->ops->setup_forced(&dev->phy, speed, fd);
+ 		}
+-	}
+-	emac_start_link(ep, NULL);
++	} else {
++		emac_reset(dev);
+ 
+-	/* read the MAC Address */
+-	for (i = 0; i < 6; i++)
+-		ndev->dev_addr[i] = emacdata->mac_addr[i];
++		/* PHY-less configuration.
++		 * XXX I probably should move these settings to emacdata
++		 */
++		dev->phy.address = -1;
++		dev->phy.features = SUPPORTED_100baseT_Full | SUPPORTED_MII;
++		dev->phy.pause = 1;
++	}
+ 
+ 	/* Fill in the driver function table */
+ 	ndev->open = &emac_open;
+-	ndev->hard_start_xmit = &emac_start_xmit;
++	if (dev->tah_dev) {
++		ndev->hard_start_xmit = &emac_start_xmit_sg;
++		ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
++	} else
++		ndev->hard_start_xmit = &emac_start_xmit;
++	ndev->tx_timeout = &emac_full_tx_reset;
++	ndev->watchdog_timeo = 5 * HZ;
+ 	ndev->stop = &emac_close;
+ 	ndev->get_stats = &emac_stats;
+-	if (emacdata->jumbo)
+-		ndev->change_mtu = &emac_change_mtu;
+-	ndev->set_mac_address = &emac_set_mac_address;
+ 	ndev->set_multicast_list = &emac_set_multicast_list;
+ 	ndev->do_ioctl = &emac_ioctl;
++	if (emac_phy_supports_gige(emacdata->phy_mode)) {
++		ndev->change_mtu = &emac_change_mtu;
++		dev->commac.ops = &emac_commac_sg_ops;
++	}
+ 	SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
+-	if (emacdata->tah_idx >= 0)
+-		ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
+-#ifdef CONFIG_NET_POLL_CONTROLLER
+-	ndev->poll_controller = emac_netpoll;
+-#endif
+ 
+-	SET_MODULE_OWNER(ndev);
++	netif_carrier_off(ndev);
++	netif_stop_queue(ndev);
++
++	err = register_netdev(ndev);
++	if (err) {
++		printk(KERN_ERR "emac%d: failed to register net device (%d)!\n",
++		       dev->def->index, err);
++		goto out6;
++	}
+ 
+-	rc = register_netdev(ndev);
+-	if (rc != 0)
+-		goto bail;
++	ocp_set_drvdata(ocpdev, dev);
+ 
+-	printk("%s: IBM emac, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+-	       ndev->name,
++	printk("%s: emac%d, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
++	       ndev->name, dev->def->index,
+ 	       ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
+ 	       ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+-	printk(KERN_INFO "%s: Found %s PHY (0x%02x)\n",
+-	       ndev->name, ep->phy_mii.def->name, ep->mii_phy_addr);
+-
+-      bail:
+-	if (rc && commac_reg)
+-		mal_unregister_commac(ep->mal, &ep->commac);
+-	if (rc && ndev)
+-		kfree(ndev);
+-
+-	return rc;
+-}
+-
+-static int emac_probe(struct ocp_device *ocpdev)
+-{
+-	struct ocp_device *maldev;
+-	struct ibm_ocp_mal *mal;
+-	struct ocp_func_emac_data *emacdata;
+-
+-	emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions;
+-	if (emacdata == NULL) {
+-		printk(KERN_ERR "emac%d: Missing additional datas !\n",
+-		       ocpdev->def->index);
+-		return -ENODEV;
+-	}
+ 
+-	/* Get the MAL device  */
+-	maldev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_MAL, emacdata->mal_idx);
+-	if (maldev == NULL) {
+-		printk("No maldev\n");
+-		return -ENODEV;
+-	}
+-	/*
+-	 * Get MAL driver data, it must be here due to link order.
+-	 * When the driver is modularized, symbol dependencies will
+-	 * ensure the MAL driver is already present if built as a
+-	 * module.
+-	 */
+-	mal = (struct ibm_ocp_mal *)ocp_get_drvdata(maldev);
+-	if (mal == NULL) {
+-		printk("No maldrv\n");
+-		return -ENODEV;
+-	}
++	if (dev->phy.address >= 0)
++		printk("%s: found %s PHY (0x%02x)\n", ndev->name,
++		       dev->phy.def->name, dev->phy.address);
+ 
+-	/* If we depend on another EMAC for MDIO, wait for it to show up */
+-	if (emacdata->mdio_idx >= 0 &&
+-	    (emacdata->mdio_idx != ocpdev->def->index) && !mdio_ndev) {
+-		struct emac_def_dev *ddev;
+-		/* Add this index to the deferred init table */
+-		ddev = kmalloc(sizeof(struct emac_def_dev), GFP_KERNEL);
+-		ddev->ocpdev = ocpdev;
+-		ddev->mal = mal;
+-		list_add_tail(&ddev->link, &emac_init_list);
+-	} else {
+-		emac_init_device(ocpdev, mal);
+-	}
++	emac_dbg_register(dev->def->index, dev);
+ 
+ 	return 0;
++      out6:
++	iounmap((void *)dev->emacp);
++      out5:
++	tah_fini(dev->tah_dev);
++      out4:
++	rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
++      out3:
++	zmii_fini(dev->zmii_dev, dev->zmii_input);
++      out2:
++	mal_unregister_commac(dev->mal, &dev->commac);
++      out:
++	kfree(ndev);
++	return err;
+ }
+ 
+-/* Structure for a device driver */
+ static struct ocp_device_id emac_ids[] = {
+-	{.vendor = OCP_ANY_ID,.function = OCP_FUNC_EMAC},
+-	{.vendor = OCP_VENDOR_INVALID}
++	{ .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_EMAC },
++	{ .vendor = OCP_VENDOR_INVALID}
+ };
+ 
+ static struct ocp_driver emac_driver = {
+ 	.name = "emac",
+ 	.id_table = emac_ids,
+-
+ 	.probe = emac_probe,
+ 	.remove = emac_remove,
+ };
+ 
+ static int __init emac_init(void)
+ {
+-	printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n");
+-	printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n");
++	printk(KERN_INFO DRV_DESC ", version " DRV_VERSION "\n");
++
++	DBG(": init" NL);
+ 
+-	if (skb_res > 2) {
+-		printk(KERN_WARNING "Invalid skb_res: %d, cropping to 2\n",
+-		       skb_res);
+-		skb_res = 2;
++	if (mal_init())
++		return -ENODEV;
++
++	EMAC_CLK_INTERNAL;
++	if (ocp_register_driver(&emac_driver)) {
++		EMAC_CLK_EXTERNAL;
++		ocp_unregister_driver(&emac_driver);
++		mal_exit();
++		return -ENODEV;
+ 	}
++	EMAC_CLK_EXTERNAL;
+ 
+-	return ocp_register_driver(&emac_driver);
++	emac_init_debug();
++	return 0;
+ }
+ 
+ static void __exit emac_exit(void)
+ {
++	DBG(": exit" NL);
+ 	ocp_unregister_driver(&emac_driver);
++	mal_exit();
++	emac_fini_debug();
+ }
+ 
+ module_init(emac_init);
+diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h
+--- a/drivers/net/ibm_emac/ibm_emac_core.h
++++ b/drivers/net/ibm_emac/ibm_emac_core.h
+@@ -1,146 +1,221 @@
+ /*
+- * ibm_emac_core.h
++ * drivers/net/ibm_emac/ibm_emac_core.h
+  *
+- * Ethernet driver for the built in ethernet on the IBM 405 PowerPC
+- * processor.
++ * Driver for PowerPC 4xx on-chip ethernet controller.
+  *
+- *      Armin Kuster akuster at mvista.com
+- *      Sept, 2001
++ * Copyright (c) 2004, 2005 Zultys Technologies.
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
+  *
+- *      Orignial driver
+- *         Johnnie Peters
+- *         jpeters at mvista.com
+- *
+- * Copyright 2000 MontaVista Softare Inc.
++ * Based on original work by
++ *      Armin Kuster <akuster at mvista.com>
++ * 	Johnnie Peters <jpeters at mvista.com>
++ *      Copyright 2000, 2001 MontaVista Softare 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 __IBM_EMAC_CORE_H_
++#define __IBM_EMAC_CORE_H_
+ 
+-#ifndef _IBM_EMAC_CORE_H_
+-#define _IBM_EMAC_CORE_H_
+-
++#include <linux/config.h>
+ #include <linux/netdevice.h>
++#include <linux/dma-mapping.h>
+ #include <asm/ocp.h>
+-#include <asm/mmu.h>		/* For phys_addr_t */
+ 
+ #include "ibm_emac.h"
+ #include "ibm_emac_phy.h"
+-#include "ibm_emac_rgmii.h"
+ #include "ibm_emac_zmii.h"
++#include "ibm_emac_rgmii.h"
+ #include "ibm_emac_mal.h"
+ #include "ibm_emac_tah.h"
+ 
+-#ifndef CONFIG_IBM_EMAC_TXB
+-#define NUM_TX_BUFF		64
+-#define NUM_RX_BUFF		64
+-#else
+-#define NUM_TX_BUFF		CONFIG_IBM_EMAC_TXB
+-#define NUM_RX_BUFF		CONFIG_IBM_EMAC_RXB
+-#endif
++#define NUM_TX_BUFF			CONFIG_IBM_EMAC_TXB
++#define NUM_RX_BUFF			CONFIG_IBM_EMAC_RXB
+ 
+-/* This does 16 byte alignment, exactly what we need.
+- * The packet length includes FCS, but we don't want to
+- * include that when passing upstream as it messes up
+- * bridging applications.
+- */
+-#ifndef CONFIG_IBM_EMAC_SKBRES
+-#define SKB_RES 2
+-#else
+-#define SKB_RES CONFIG_IBM_EMAC_SKBRES
++/* Simple sanity check */
++#if NUM_TX_BUFF > 256 || NUM_RX_BUFF > 256
++#error Invalid number of buffer descriptors (greater than 256)
+ #endif
+ 
+-/* Note about alignement. alloc_skb() returns a cache line
+- * aligned buffer. However, dev_alloc_skb() will add 16 more
+- * bytes and "reserve" them, so our buffer will actually end
+- * on a half cache line. What we do is to use directly
+- * alloc_skb, allocate 16 more bytes to match the total amount
+- * allocated by dev_alloc_skb(), but we don't reserve.
++// XXX
++#define EMAC_MIN_MTU			46
++#define EMAC_MAX_MTU			9000
++
++/* Maximum L2 header length (VLAN tagged, no FCS) */
++#define EMAC_MTU_OVERHEAD		(6 * 2 + 2 + 4)
++
++/* RX BD size for the given MTU */
++static inline int emac_rx_size(int mtu)
++{
++	if (mtu > ETH_DATA_LEN)
++		return MAL_MAX_RX_SIZE;
++	else
++		return mal_rx_size(ETH_DATA_LEN + EMAC_MTU_OVERHEAD);
++}
++
++#define EMAC_DMA_ALIGN(x)		ALIGN((x), dma_get_cache_alignment())
++
++#define EMAC_RX_SKB_HEADROOM		\
++	EMAC_DMA_ALIGN(CONFIG_IBM_EMAC_RX_SKB_HEADROOM)
++
++/* Size of RX skb for the given MTU */
++static inline int emac_rx_skb_size(int mtu)
++{
++	int size = max(mtu + EMAC_MTU_OVERHEAD, emac_rx_size(mtu));
++	return EMAC_DMA_ALIGN(size + 2) + EMAC_RX_SKB_HEADROOM;
++}
++
++/* RX DMA sync size */
++static inline int emac_rx_sync_size(int mtu)
++{
++	return EMAC_DMA_ALIGN(emac_rx_size(mtu) + 2);
++}
++
++/* Driver statistcs is split into two parts to make it more cache friendly:
++ *   - normal statistics (packet count, etc)
++ *   - error statistics
++ *
++ * When statistics is requested by ethtool, these parts are concatenated,
++ * normal one goes first.
++ *
++ * Please, keep these structures in sync with emac_stats_keys.
+  */
+-#define MAX_NUM_BUF_DESC	255
+-#define DESC_BUF_SIZE		4080	/* max 4096-16 */
+-#define DESC_BUF_SIZE_REG	(DESC_BUF_SIZE / 16)
+-
+-/* Transmitter timeout. */
+-#define TX_TIMEOUT		(2*HZ)
+-
+-/* MDIO latency delay */
+-#define MDIO_DELAY		250
+-
+-/* Power managment shift registers */
+-#define IBM_CPM_EMMII	0	/* Shift value for MII */
+-#define IBM_CPM_EMRX	1	/* Shift value for recv */
+-#define IBM_CPM_EMTX	2	/* Shift value for MAC */
+-#define IBM_CPM_EMAC(x)	(((x)>>IBM_CPM_EMMII) | ((x)>>IBM_CPM_EMRX) | ((x)>>IBM_CPM_EMTX))
+-
+-#define ENET_HEADER_SIZE	14
+-#define ENET_FCS_SIZE		4
+-#define ENET_DEF_MTU_SIZE	1500
+-#define ENET_DEF_BUF_SIZE	(ENET_DEF_MTU_SIZE + ENET_HEADER_SIZE + ENET_FCS_SIZE)
+-#define EMAC_MIN_FRAME		64
+-#define EMAC_MAX_FRAME		9018
+-#define EMAC_MIN_MTU		(EMAC_MIN_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE)
+-#define EMAC_MAX_MTU		(EMAC_MAX_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE)
+-
+-#ifdef CONFIG_IBM_EMAC_ERRMSG
+-void emac_serr_dump_0(struct net_device *dev);
+-void emac_serr_dump_1(struct net_device *dev);
+-void emac_err_dump(struct net_device *dev, int em0isr);
+-void emac_phy_dump(struct net_device *);
+-void emac_desc_dump(struct net_device *);
+-void emac_mac_dump(struct net_device *);
+-void emac_mal_dump(struct net_device *);
+-#else
+-#define emac_serr_dump_0(dev) do { } while (0)
+-#define emac_serr_dump_1(dev) do { } while (0)
+-#define emac_err_dump(dev,x) do { } while (0)
+-#define emac_phy_dump(dev) do { } while (0)
+-#define emac_desc_dump(dev) do { } while (0)
+-#define emac_mac_dump(dev) do { } while (0)
+-#define emac_mal_dump(dev) do { } while (0)
+-#endif
++
++/* Normal TX/RX Statistics */
++struct ibm_emac_stats {
++	u64 rx_packets;
++	u64 rx_bytes;
++	u64 tx_packets;
++	u64 tx_bytes;
++	u64 rx_packets_csum;
++	u64 tx_packets_csum;
++};
++
++/* Error statistics */
++struct ibm_emac_error_stats {
++	u64 tx_undo;
++
++	/* Software RX Errors */
++	u64 rx_dropped_stack;
++	u64 rx_dropped_oom;
++	u64 rx_dropped_error;
++	u64 rx_dropped_resize;
++	u64 rx_dropped_mtu;
++	u64 rx_stopped;
++	/* BD reported RX errors */
++	u64 rx_bd_errors;
++	u64 rx_bd_overrun;
++	u64 rx_bd_bad_packet;
++	u64 rx_bd_runt_packet;
++	u64 rx_bd_short_event;
++	u64 rx_bd_alignment_error;
++	u64 rx_bd_bad_fcs;
++	u64 rx_bd_packet_too_long;
++	u64 rx_bd_out_of_range;
++	u64 rx_bd_in_range;
++	/* EMAC IRQ reported RX errors */
++	u64 rx_parity;
++	u64 rx_fifo_overrun;
++	u64 rx_overrun;
++	u64 rx_bad_packet;
++	u64 rx_runt_packet;
++	u64 rx_short_event;
++	u64 rx_alignment_error;
++	u64 rx_bad_fcs;
++	u64 rx_packet_too_long;
++	u64 rx_out_of_range;
++	u64 rx_in_range;
++
++	/* Software TX Errors */
++	u64 tx_dropped;
++	/* BD reported TX errors */
++	u64 tx_bd_errors;
++	u64 tx_bd_bad_fcs;
++	u64 tx_bd_carrier_loss;
++	u64 tx_bd_excessive_deferral;
++	u64 tx_bd_excessive_collisions;
++	u64 tx_bd_late_collision;
++	u64 tx_bd_multple_collisions;
++	u64 tx_bd_single_collision;
++	u64 tx_bd_underrun;
++	u64 tx_bd_sqe;
++	/* EMAC IRQ reported TX errors */
++	u64 tx_parity;
++	u64 tx_underrun;
++	u64 tx_sqe;
++	u64 tx_errors;
++};
++
++#define EMAC_ETHTOOL_STATS_COUNT	((sizeof(struct ibm_emac_stats) + \
++					  sizeof(struct ibm_emac_error_stats)) \
++					 / sizeof(u64))
+ 
+ struct ocp_enet_private {
+-	struct sk_buff *tx_skb[NUM_TX_BUFF];
+-	struct sk_buff *rx_skb[NUM_RX_BUFF];
+-	struct mal_descriptor *tx_desc;
+-	struct mal_descriptor *rx_desc;
+-	struct mal_descriptor *rx_dirty;
+-	struct net_device_stats stats;
+-	int tx_cnt;
+-	int rx_slot;
+-	int dirty_rx;
+-	int tx_slot;
+-	int ack_slot;
+-	int rx_buffer_size;
+-
+-	struct mii_phy phy_mii;
+-	int mii_phy_addr;
+-	int want_autoneg;
+-	int timer_ticks;
+-	struct timer_list link_timer;
+-	struct net_device *mdio_dev;
+-
+-	struct ocp_device *rgmii_dev;
+-	int rgmii_input;
+-
+-	struct ocp_device *zmii_dev;
+-	int zmii_input;
+-
+-	struct ibm_ocp_mal *mal;
+-	int mal_tx_chan, mal_rx_chan;
+-	struct mal_commac commac;
+-
+-	struct ocp_device *tah_dev;
+-
+-	int opened;
+-	int going_away;
+-	int wol_irq;
+-	emac_t *emacp;
+-	struct ocp_device *ocpdev;
+-	struct net_device *ndev;
+-	spinlock_t lock;
++	struct net_device		*ndev;		/* 0 */
++	struct emac_regs		*emacp;
++	
++	struct mal_descriptor		*tx_desc;
++	int				tx_cnt;
++	int				tx_slot;
++	int				ack_slot;
++
++	struct mal_descriptor		*rx_desc;
++	int				rx_slot;
++	struct sk_buff			*rx_sg_skb;	/* 1 */
++	int 				rx_skb_size;
++	int				rx_sync_size;
++
++	struct ibm_emac_stats 		stats;
++	struct ocp_device		*tah_dev;
++
++	struct ibm_ocp_mal		*mal;
++	struct mal_commac		commac;
++
++	struct sk_buff			*tx_skb[NUM_TX_BUFF];
++	struct sk_buff			*rx_skb[NUM_RX_BUFF];
++
++	struct ocp_device		*zmii_dev;
++	int				zmii_input;
++	struct ocp_enet_private		*mdio_dev;
++	struct ocp_device		*rgmii_dev;
++	int				rgmii_input;
++
++	struct ocp_def			*def;
++
++	struct mii_phy			phy;
++	struct timer_list		link_timer;
++	int				reset_failed;
++
++	struct ibm_emac_error_stats	estats;
++	struct net_device_stats		nstats;
++
++	struct device*			ldev;
++};
++
++/* Ethtool get_regs complex data.
++ * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH 
++ * when available.
++ * 
++ * Returned BLOB consists of the ibm_emac_ethtool_regs_hdr, 
++ * MAL registers, EMAC registers and optional ZMII, RGMII, TAH registers.
++ * Each register component is preceded with emac_ethtool_regs_subhdr.
++ * Order of the optional headers follows their relative bit posititions 
++ * in emac_ethtool_regs_hdr.components
++ */
++#define EMAC_ETHTOOL_REGS_ZMII		0x00000001
++#define EMAC_ETHTOOL_REGS_RGMII		0x00000002
++#define EMAC_ETHTOOL_REGS_TAH		0x00000004
++
++struct emac_ethtool_regs_hdr {
++	u32 components;
+ };
+-#endif				/* _IBM_EMAC_CORE_H_ */
++
++struct emac_ethtool_regs_subhdr {
++	u32 version;
++	u32 index;
++};
++
++#endif				/* __IBM_EMAC_CORE_H_ */
+diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c
+--- a/drivers/net/ibm_emac/ibm_emac_debug.c
++++ b/drivers/net/ibm_emac/ibm_emac_debug.c
+@@ -1,224 +1,213 @@
+ /*
+- * ibm_ocp_debug.c
++ * drivers/net/ibm_emac/ibm_emac_debug.c
+  *
+- * This has all the debug routines that where in *_enet.c
++ * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
+  *
+- *      Armin Kuster akuster at mvista.com
+- *      April , 2002
+- *
+- * Copyright 2002 MontaVista Softare Inc.
++ * Copyright (c) 2004, 2005 Zultys Technologies
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.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/config.h>
++#include <linux/init.h>
++#include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/netdevice.h>
++#include <linux/sysrq.h>
+ #include <asm/io.h>
+-#include "ibm_ocp_mal.h"
+-#include "ibm_ocp_zmii.h"
+-#include "ibm_ocp_enet.h"
+-
+-extern int emac_phy_read(struct net_device *dev, int mii_id, int reg);
+-
+-void emac_phy_dump(struct net_device *dev)
+-{
+-	struct ocp_enet_private *fep = dev->priv;
+-	unsigned long i;
+-	uint data;
+-
+-	printk(KERN_DEBUG " Prepare for Phy dump....\n");
+-	for (i = 0; i < 0x1A; i++) {
+-		data = emac_phy_read(dev, fep->mii_phy_addr, i);
+-		printk(KERN_DEBUG "Phy reg 0x%lx ==> %4x\n", i, data);
+-		if (i == 0x07)
+-			i = 0x0f;
++
++#include "ibm_emac_core.h"
++
++static void emac_desc_dump(int idx, struct ocp_enet_private *p)
++{
++	int i;
++	printk("** EMAC%d TX BDs **\n"
++	       " tx_cnt = %d tx_slot = %d ack_slot = %d\n",
++	       idx, p->tx_cnt, p->tx_slot, p->ack_slot);
++	for (i = 0; i < NUM_TX_BUFF / 2; ++i)
++		printk
++		    ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
++		     i, p->tx_desc[i].data_ptr, p->tx_skb[i] ? 'V' : ' ',
++		     p->tx_desc[i].ctrl, p->tx_desc[i].data_len,
++		     NUM_TX_BUFF / 2 + i,
++		     p->tx_desc[NUM_TX_BUFF / 2 + i].data_ptr,
++		     p->tx_skb[NUM_TX_BUFF / 2 + i] ? 'V' : ' ',
++		     p->tx_desc[NUM_TX_BUFF / 2 + i].ctrl,
++		     p->tx_desc[NUM_TX_BUFF / 2 + i].data_len);
++
++	printk("** EMAC%d RX BDs **\n"
++	       " rx_slot = %d rx_stopped = %d rx_skb_size = %d rx_sync_size = %d\n"
++	       " rx_sg_skb = 0x%p\n",
++	       idx, p->rx_slot, p->commac.rx_stopped, p->rx_skb_size,
++	       p->rx_sync_size, p->rx_sg_skb);
++	for (i = 0; i < NUM_RX_BUFF / 2; ++i)
++		printk
++		    ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
++		     i, p->rx_desc[i].data_ptr, p->rx_skb[i] ? 'V' : ' ',
++		     p->rx_desc[i].ctrl, p->rx_desc[i].data_len,
++		     NUM_RX_BUFF / 2 + i,
++		     p->rx_desc[NUM_RX_BUFF / 2 + i].data_ptr,
++		     p->rx_skb[NUM_RX_BUFF / 2 + i] ? 'V' : ' ',
++		     p->rx_desc[NUM_RX_BUFF / 2 + i].ctrl,
++		     p->rx_desc[NUM_RX_BUFF / 2 + i].data_len);
++}
++
++static void emac_mac_dump(int idx, struct ocp_enet_private *dev)
++{
++	struct emac_regs *p = dev->emacp;
++
++	printk("** EMAC%d registers **\n"
++	       "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n"
++	       "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n"
++	       "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n"
++	       "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x "
++	       "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n"
++	       "LSA = %04x%08x IPGVR = 0x%04x\n"
++	       "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
++	       "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n",
++	       idx, in_be32(&p->mr0), in_be32(&p->mr1),
++	       in_be32(&p->tmr0), in_be32(&p->tmr1),
++	       in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser),
++	       in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid),
++	       in_be32(&p->vtci),
++	       in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3),
++	       in_be32(&p->iaht4),
++	       in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3),
++	       in_be32(&p->gaht4),
++	       in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr),
++	       in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr),
++	       in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr)
++	    );
++
++	emac_desc_dump(idx, dev);
++}
++
++static void emac_mal_dump(struct ibm_ocp_mal *mal)
++{
++	struct ocp_func_mal_data *maldata = mal->def->additions;
++	int i;
++
++	printk("** MAL%d Registers **\n"
++	       "CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n"
++	       "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n"
++	       "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n",
++	       mal->def->index,
++	       get_mal_dcrn(mal, MAL_CFG), get_mal_dcrn(mal, MAL_ESR),
++	       get_mal_dcrn(mal, MAL_IER),
++	       get_mal_dcrn(mal, MAL_TXCASR), get_mal_dcrn(mal, MAL_TXCARR),
++	       get_mal_dcrn(mal, MAL_TXEOBISR), get_mal_dcrn(mal, MAL_TXDEIR),
++	       get_mal_dcrn(mal, MAL_RXCASR), get_mal_dcrn(mal, MAL_RXCARR),
++	       get_mal_dcrn(mal, MAL_RXEOBISR), get_mal_dcrn(mal, MAL_RXDEIR)
++	    );
++
++	printk("TX|");
++	for (i = 0; i < maldata->num_tx_chans; ++i) {
++		if (i && !(i % 4))
++			printk("\n   ");
++		printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_TXCTPR(i)));
++	}
++	printk("\nRX|");
++	for (i = 0; i < maldata->num_rx_chans; ++i) {
++		if (i && !(i % 4))
++			printk("\n   ");
++		printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_RXCTPR(i)));
+ 	}
++	printk("\n   ");
++	for (i = 0; i < maldata->num_rx_chans; ++i) {
++		u32 r = get_mal_dcrn(mal, MAL_RCBS(i));
++		if (i && !(i % 3))
++			printk("\n   ");
++		printk("RCBS%d = 0x%08x (%d) ", i, r, r * 16);
++	}
++	printk("\n");
+ }
+ 
+-void emac_desc_dump(struct net_device *dev)
++static struct ocp_enet_private *__emacs[4];
++static struct ibm_ocp_mal *__mals[1];
++
++void emac_dbg_register(int idx, struct ocp_enet_private *dev)
+ {
+-	struct ocp_enet_private *fep = dev->priv;
+-	int curr_slot;
++	unsigned long flags;
+ 
+-	printk(KERN_DEBUG
+-	       "dumping the receive descriptors:  current slot is %d\n",
+-	       fep->rx_slot);
+-	for (curr_slot = 0; curr_slot < NUM_RX_BUFF; curr_slot++) {
+-		printk(KERN_DEBUG
+-		       "Desc %02d: status 0x%04x, length %3d, addr 0x%x\n",
+-		       curr_slot, fep->rx_desc[curr_slot].ctrl,
+-		       fep->rx_desc[curr_slot].data_len,
+-		       (unsigned int)fep->rx_desc[curr_slot].data_ptr);
++	if (idx >= sizeof(__emacs) / sizeof(__emacs[0])) {
++		printk(KERN_WARNING
++		       "invalid index %d when registering EMAC for debugging\n",
++		       idx);
++		return;
+ 	}
++
++	local_irq_save(flags);
++	__emacs[idx] = dev;
++	local_irq_restore(flags);
+ }
+ 
+-void emac_mac_dump(struct net_device *dev)
++void mal_dbg_register(int idx, struct ibm_ocp_mal *mal)
+ {
+-	struct ocp_enet_private *fep = dev->priv;
+-	volatile emac_t *emacp = fep->emacp;
++	unsigned long flags;
+ 
+-	printk(KERN_DEBUG "EMAC DEBUG ********** \n");
+-	printk(KERN_DEBUG "EMAC_M0  ==> 0x%x\n", in_be32(&emacp->em0mr0));
+-	printk(KERN_DEBUG "EMAC_M1  ==> 0x%x\n", in_be32(&emacp->em0mr1));
+-	printk(KERN_DEBUG "EMAC_TXM0==> 0x%x\n", in_be32(&emacp->em0tmr0));
+-	printk(KERN_DEBUG "EMAC_TXM1==> 0x%x\n", in_be32(&emacp->em0tmr1));
+-	printk(KERN_DEBUG "EMAC_RXM ==> 0x%x\n", in_be32(&emacp->em0rmr));
+-	printk(KERN_DEBUG "EMAC_ISR ==> 0x%x\n", in_be32(&emacp->em0isr));
+-	printk(KERN_DEBUG "EMAC_IER ==> 0x%x\n", in_be32(&emacp->em0iser));
+-	printk(KERN_DEBUG "EMAC_IAH ==> 0x%x\n", in_be32(&emacp->em0iahr));
+-	printk(KERN_DEBUG "EMAC_IAL ==> 0x%x\n", in_be32(&emacp->em0ialr));
+-	printk(KERN_DEBUG "EMAC_VLAN_TPID_REG ==> 0x%x\n",
+-	       in_be32(&emacp->em0vtpid));
+-}
+-
+-void emac_mal_dump(struct net_device *dev)
+-{
+-	struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal;
+-
+-	printk(KERN_DEBUG " MAL DEBUG ********** \n");
+-	printk(KERN_DEBUG " MCR      ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALCR));
+-	printk(KERN_DEBUG " ESR      ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALESR));
+-	printk(KERN_DEBUG " IER      ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALIER));
+-#ifdef CONFIG_40x
+-	printk(KERN_DEBUG " DBR      ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALDBR));
+-#endif				/* CONFIG_40x */
+-	printk(KERN_DEBUG " TXCASR   ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCASR));
+-	printk(KERN_DEBUG " TXCARR   ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCARR));
+-	printk(KERN_DEBUG " TXEOBISR ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALTXEOBISR));
+-	printk(KERN_DEBUG " TXDEIR   ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALTXDEIR));
+-	printk(KERN_DEBUG " RXCASR   ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCASR));
+-	printk(KERN_DEBUG " RXCARR   ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCARR));
+-	printk(KERN_DEBUG " RXEOBISR ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALRXEOBISR));
+-	printk(KERN_DEBUG " RXDEIR   ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALRXDEIR));
+-	printk(KERN_DEBUG " TXCTP0R  ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP0R));
+-	printk(KERN_DEBUG " TXCTP1R  ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP1R));
+-	printk(KERN_DEBUG " TXCTP2R  ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP2R));
+-	printk(KERN_DEBUG " TXCTP3R  ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP3R));
+-	printk(KERN_DEBUG " RXCTP0R  ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCTP0R));
+-	printk(KERN_DEBUG " RXCTP1R  ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCTP1R));
+-	printk(KERN_DEBUG " RCBS0    ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALRCBS0));
+-	printk(KERN_DEBUG " RCBS1    ==> 0x%x\n",
+-	       (unsigned int)get_mal_dcrn(mal, DCRN_MALRCBS1));
+-}
+-
+-void emac_serr_dump_0(struct net_device *dev)
+-{
+-	struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal;
+-	unsigned long int mal_error, plb_error, plb_addr;
+-
+-	mal_error = get_mal_dcrn(mal, DCRN_MALESR);
+-	printk(KERN_DEBUG "ppc405_eth_serr: %s channel %ld \n",
+-	       (mal_error & 0x40000000) ? "Receive" :
+-	       "Transmit", (mal_error & 0x3e000000) >> 25);
+-	printk(KERN_DEBUG "  -----  latched error  -----\n");
+-	if (mal_error & MALESR_DE)
+-		printk(KERN_DEBUG "  DE: descriptor error\n");
+-	if (mal_error & MALESR_OEN)
+-		printk(KERN_DEBUG "  ONE: OPB non-fullword error\n");
+-	if (mal_error & MALESR_OTE)
+-		printk(KERN_DEBUG "  OTE: OPB timeout error\n");
+-	if (mal_error & MALESR_OSE)
+-		printk(KERN_DEBUG "  OSE: OPB slave error\n");
+-
+-	if (mal_error & MALESR_PEIN) {
+-		plb_error = mfdcr(DCRN_PLB0_BESR);
+-		printk(KERN_DEBUG
+-		       "  PEIN: PLB error, PLB0_BESR is 0x%x\n",
+-		       (unsigned int)plb_error);
+-		plb_addr = mfdcr(DCRN_PLB0_BEAR);
+-		printk(KERN_DEBUG
+-		       "  PEIN: PLB error, PLB0_BEAR is 0x%x\n",
+-		       (unsigned int)plb_addr);
++	if (idx >= sizeof(__mals) / sizeof(__mals[0])) {
++		printk(KERN_WARNING
++		       "invalid index %d when registering MAL for debugging\n",
++		       idx);
++		return;
+ 	}
++
++	local_irq_save(flags);
++	__mals[idx] = mal;
++	local_irq_restore(flags);
++}
++
++void emac_dbg_dump_all(void)
++{
++	unsigned int i;
++	unsigned long flags;
++
++	local_irq_save(flags);
++
++	for (i = 0; i < sizeof(__mals) / sizeof(__mals[0]); ++i)
++		if (__mals[i])
++			emac_mal_dump(__mals[i]);
++
++	for (i = 0; i < sizeof(__emacs) / sizeof(__emacs[0]); ++i)
++		if (__emacs[i])
++			emac_mac_dump(i, __emacs[i]);
++
++	local_irq_restore(flags);
++}
++
++#if defined(CONFIG_MAGIC_SYSRQ)
++static void emac_sysrq_handler(int key, struct pt_regs *pt_regs,
++			       struct tty_struct *tty)
++{
++	emac_dbg_dump_all();
+ }
+ 
+-void emac_serr_dump_1(struct net_device *dev)
++static struct sysrq_key_op emac_sysrq_op = {
++	.handler = emac_sysrq_handler,
++	.help_msg = "emaC",
++	.action_msg = "Show EMAC(s) status",
++};
++
++int __init emac_init_debug(void)
+ {
+-	struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal;
+-	int mal_error = get_mal_dcrn(mal, DCRN_MALESR);
++	return register_sysrq_key('c', &emac_sysrq_op);
++}
+ 
+-	printk(KERN_DEBUG "  -----  cumulative errors  -----\n");
+-	if (mal_error & MALESR_DEI)
+-		printk(KERN_DEBUG "  DEI: descriptor error interrupt\n");
+-	if (mal_error & MALESR_ONEI)
+-		printk(KERN_DEBUG "  OPB non-fullword error interrupt\n");
+-	if (mal_error & MALESR_OTEI)
+-		printk(KERN_DEBUG "  OTEI: timeout error interrupt\n");
+-	if (mal_error & MALESR_OSEI)
+-		printk(KERN_DEBUG "  OSEI: slave error interrupt\n");
+-	if (mal_error & MALESR_PBEI)
+-		printk(KERN_DEBUG "  PBEI: PLB bus error interrupt\n");
+-}
+-
+-void emac_err_dump(struct net_device *dev, int em0isr)
+-{
+-	printk(KERN_DEBUG "%s: on-chip ethernet error:\n", dev->name);
+-
+-	if (em0isr & EMAC_ISR_OVR)
+-		printk(KERN_DEBUG "  OVR: overrun\n");
+-	if (em0isr & EMAC_ISR_PP)
+-		printk(KERN_DEBUG "  PP: control pause packet\n");
+-	if (em0isr & EMAC_ISR_BP)
+-		printk(KERN_DEBUG "  BP: packet error\n");
+-	if (em0isr & EMAC_ISR_RP)
+-		printk(KERN_DEBUG "  RP: runt packet\n");
+-	if (em0isr & EMAC_ISR_SE)
+-		printk(KERN_DEBUG "  SE: short event\n");
+-	if (em0isr & EMAC_ISR_ALE)
+-		printk(KERN_DEBUG "  ALE: odd number of nibbles in packet\n");
+-	if (em0isr & EMAC_ISR_BFCS)
+-		printk(KERN_DEBUG "  BFCS: bad FCS\n");
+-	if (em0isr & EMAC_ISR_PTLE)
+-		printk(KERN_DEBUG "  PTLE: oversized packet\n");
+-	if (em0isr & EMAC_ISR_ORE)
+-		printk(KERN_DEBUG
+-		       "  ORE: packet length field > max allowed LLC\n");
+-	if (em0isr & EMAC_ISR_IRE)
+-		printk(KERN_DEBUG "  IRE: In Range error\n");
+-	if (em0isr & EMAC_ISR_DBDM)
+-		printk(KERN_DEBUG "  DBDM: xmit error or SQE\n");
+-	if (em0isr & EMAC_ISR_DB0)
+-		printk(KERN_DEBUG "  DB0: xmit error or SQE on TX channel 0\n");
+-	if (em0isr & EMAC_ISR_SE0)
+-		printk(KERN_DEBUG
+-		       "  SE0: Signal Quality Error test failure from TX channel 0\n");
+-	if (em0isr & EMAC_ISR_TE0)
+-		printk(KERN_DEBUG "  TE0: xmit channel 0 aborted\n");
+-	if (em0isr & EMAC_ISR_DB1)
+-		printk(KERN_DEBUG "  DB1: xmit error or SQE on TX channel \n");
+-	if (em0isr & EMAC_ISR_SE1)
+-		printk(KERN_DEBUG
+-		       "  SE1: Signal Quality Error test failure from TX channel 1\n");
+-	if (em0isr & EMAC_ISR_TE1)
+-		printk(KERN_DEBUG "  TE1: xmit channel 1 aborted\n");
+-	if (em0isr & EMAC_ISR_MOS)
+-		printk(KERN_DEBUG "  MOS\n");
+-	if (em0isr & EMAC_ISR_MOF)
+-		printk(KERN_DEBUG "  MOF\n");
++void __exit emac_fini_debug(void)
++{
++	unregister_sysrq_key('c', &emac_sysrq_op);
++}
+ 
+-	emac_mac_dump(dev);
+-	emac_mal_dump(dev);
++#else
++int __init emac_init_debug(void)
++{
++	return 0;
++}
++void __exit emac_fini_debug(void)
++{
+ }
++#endif				/* CONFIG_MAGIC_SYSRQ */
+diff --git a/drivers/net/ibm_emac/ibm_emac_debug.h b/drivers/net/ibm_emac/ibm_emac_debug.h
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/ibm_emac/ibm_emac_debug.h
+@@ -0,0 +1,63 @@
++/*
++ * drivers/net/ibm_emac/ibm_ocp_debug.h
++ *
++ * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
++ *
++ * Copyright (c) 2004, 2005 Zultys Technologies
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.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.
++ *
++ */
++#ifndef __IBM_EMAC_DEBUG_H_
++#define __IBM_EMAC_DEBUG_H_
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include "ibm_emac_core.h"
++#include "ibm_emac_mal.h"
++
++#if defined(CONFIG_IBM_EMAC_DEBUG)
++void emac_dbg_register(int idx, struct ocp_enet_private *dev);
++void mal_dbg_register(int idx, struct ibm_ocp_mal *mal);
++int emac_init_debug(void) __init;
++void emac_fini_debug(void) __exit;
++void emac_dbg_dump_all(void);
++# define DBG_LEVEL		1
++#else
++# define emac_dbg_register(x,y) ((void)0)
++# define mal_dbg_register(x,y)	((void)0)
++# define emac_init_debug()	((void)0)
++# define emac_fini_debug()	((void)0)
++# define emac_dbg_dump_all()	((void)0)
++# define DBG_LEVEL		0
++#endif
++
++#if DBG_LEVEL > 0
++#  define DBG(f,x...)		printk("emac" f, ##x)
++#  define MAL_DBG(f,x...)	printk("mal" f, ##x)
++#  define ZMII_DBG(f,x...)	printk("zmii" f, ##x)
++#  define RGMII_DBG(f,x...)	printk("rgmii" f, ##x)
++#  define NL			"\n"
++#else
++#  define DBG(f,x...)		((void)0)
++#  define MAL_DBG(f,x...)	((void)0)
++#  define ZMII_DBG(f,x...)	((void)0)
++#  define RGMII_DBG(f,x...)	((void)0)
++#endif
++#if DBG_LEVEL > 1
++#  define DBG2(f,x...) 		DBG(f, ##x)
++#  define MAL_DBG2(f,x...) 	MAL_DBG(f, ##x)
++#  define ZMII_DBG2(f,x...) 	ZMII_DBG(f, ##x)
++#  define RGMII_DBG2(f,x...) 	RGMII_DBG(f, ##x)
++#else
++#  define DBG2(f,x...) 		((void)0)
++#  define MAL_DBG2(f,x...) 	((void)0)
++#  define ZMII_DBG2(f,x...) 	((void)0)
++#  define RGMII_DBG2(f,x...) 	((void)0)
++#endif
++
++#endif				/* __IBM_EMAC_DEBUG_H_ */
+diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c
+--- a/drivers/net/ibm_emac/ibm_emac_mal.c
++++ b/drivers/net/ibm_emac/ibm_emac_mal.c
+@@ -1,436 +1,565 @@
+ /*
+- * ibm_ocp_mal.c
++ * drivers/net/ibm_emac/ibm_emac_mal.c
+  *
+- *      Armin Kuster akuster at mvista.com
+- *      Juen, 2002
++ * Memory Access Layer (MAL) support
++ * 
++ * Copyright (c) 2004, 2005 Zultys Technologies.
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
+  *
+- * Copyright 2002 MontaVista Softare Inc.
++ * Based on original work by
++ *      Benjamin Herrenschmidt <benh at kernel.crashing.org>,
++ *      David Gibson <hermes at gibson.dropbear.id.au>,
++ *
++ *      Armin Kuster <akuster at mvista.com>
++ *      Copyright 2002 MontaVista Softare 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/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/netdevice.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+ #include <linux/dma-mapping.h>
+ 
+-#include <asm/io.h>
+-#include <asm/irq.h>
+ #include <asm/ocp.h>
+ 
++#include "ibm_emac_core.h"
+ #include "ibm_emac_mal.h"
++#include "ibm_emac_debug.h"
+ 
+-// Locking: Should we share a lock with the client ? The client could provide
+-// a lock pointer (optionally) in the commac structure... I don't think this is
+-// really necessary though
+-
+-/* This lock protects the commac list. On today UP implementations, it's
+- * really only used as IRQ protection in mal_{register,unregister}_commac()
+- */
+-static DEFINE_RWLOCK(mal_list_lock);
+-
+-int mal_register_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
++int __init mal_register_commac(struct ibm_ocp_mal *mal,
++			       struct mal_commac *commac)
+ {
+ 	unsigned long flags;
++	local_irq_save(flags);
+ 
+-	write_lock_irqsave(&mal_list_lock, flags);
++	MAL_DBG("%d: reg(%08x, %08x)" NL, mal->def->index,
++		commac->tx_chan_mask, commac->rx_chan_mask);
+ 
+-	/* Don't let multiple commacs claim the same channel */
++	/* Don't let multiple commacs claim the same channel(s) */
+ 	if ((mal->tx_chan_mask & commac->tx_chan_mask) ||
+ 	    (mal->rx_chan_mask & commac->rx_chan_mask)) {
+-		write_unlock_irqrestore(&mal_list_lock, flags);
++		local_irq_restore(flags);
++		printk(KERN_WARNING "mal%d: COMMAC channels conflict!\n",
++		       mal->def->index);
+ 		return -EBUSY;
+ 	}
+ 
+ 	mal->tx_chan_mask |= commac->tx_chan_mask;
+ 	mal->rx_chan_mask |= commac->rx_chan_mask;
++	list_add(&commac->list, &mal->list);
+ 
+-	list_add(&commac->list, &mal->commac);
+-
+-	write_unlock_irqrestore(&mal_list_lock, flags);
+-
++	local_irq_restore(flags);
+ 	return 0;
+ }
+ 
+-int mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
++void __exit mal_unregister_commac(struct ibm_ocp_mal *mal,
++				  struct mal_commac *commac)
+ {
+ 	unsigned long flags;
++	local_irq_save(flags);
+ 
+-	write_lock_irqsave(&mal_list_lock, flags);
++	MAL_DBG("%d: unreg(%08x, %08x)" NL, mal->def->index,
++		commac->tx_chan_mask, commac->rx_chan_mask);
+ 
+ 	mal->tx_chan_mask &= ~commac->tx_chan_mask;
+ 	mal->rx_chan_mask &= ~commac->rx_chan_mask;
+-
+ 	list_del_init(&commac->list);
+ 
+-	write_unlock_irqrestore(&mal_list_lock, flags);
+-
+-	return 0;
++	local_irq_restore(flags);
+ }
+ 
+ int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size)
+ {
+-	switch (channel) {
+-	case 0:
+-		set_mal_dcrn(mal, DCRN_MALRCBS0, size);
+-		break;
+-#ifdef DCRN_MALRCBS1
+-	case 1:
+-		set_mal_dcrn(mal, DCRN_MALRCBS1, size);
+-		break;
+-#endif
+-#ifdef DCRN_MALRCBS2
+-	case 2:
+-		set_mal_dcrn(mal, DCRN_MALRCBS2, size);
+-		break;
+-#endif
+-#ifdef DCRN_MALRCBS3
+-	case 3:
+-		set_mal_dcrn(mal, DCRN_MALRCBS3, size);
+-		break;
+-#endif
+-	default:
++	struct ocp_func_mal_data *maldata = mal->def->additions;
++	BUG_ON(channel < 0 || channel >= maldata->num_rx_chans ||
++	       size > MAL_MAX_RX_SIZE);
++
++	MAL_DBG("%d: set_rbcs(%d, %lu)" NL, mal->def->index, channel, size);
++
++	if (size & 0xf) {
++		printk(KERN_WARNING
++		       "mal%d: incorrect RX size %lu for the channel %d\n",
++		       mal->def->index, size, channel);
+ 		return -EINVAL;
+ 	}
+ 
++	set_mal_dcrn(mal, MAL_RCBS(channel), size >> 4);
+ 	return 0;
+ }
+ 
+-static irqreturn_t mal_serr(int irq, void *dev_instance, struct pt_regs *regs)
++int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel)
+ {
+-	struct ibm_ocp_mal *mal = dev_instance;
+-	unsigned long mal_error;
++	struct ocp_func_mal_data *maldata = mal->def->additions;
++	BUG_ON(channel < 0 || channel >= maldata->num_tx_chans);
++	return channel * NUM_TX_BUFF;
++}
+ 
+-	/*
+-	 * This SERR applies to one of the devices on the MAL, here we charge
+-	 * it against the first EMAC registered for the MAL.
+-	 */
++int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel)
++{
++	struct ocp_func_mal_data *maldata = mal->def->additions;
++	BUG_ON(channel < 0 || channel >= maldata->num_rx_chans);
++	return maldata->num_tx_chans * NUM_TX_BUFF + channel * NUM_RX_BUFF;
++}
+ 
+-	mal_error = get_mal_dcrn(mal, DCRN_MALESR);
++void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel)
++{
++	local_bh_disable();
++	MAL_DBG("%d: enable_tx(%d)" NL, mal->def->index, channel);
++	set_mal_dcrn(mal, MAL_TXCASR,
++		     get_mal_dcrn(mal, MAL_TXCASR) | MAL_CHAN_MASK(channel));
++	local_bh_enable();
++}
+ 
+-	printk(KERN_ERR "%s: System Error (MALESR=%lx)\n",
+-	       "MAL" /* FIXME: get the name right */ , mal_error);
++void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel)
++{
++	set_mal_dcrn(mal, MAL_TXCARR, MAL_CHAN_MASK(channel));
++	MAL_DBG("%d: disable_tx(%d)" NL, mal->def->index, channel);
++}
+ 
+-	/* FIXME: decipher error */
+-	/* DIXME: distribute to commacs, if possible */
++void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel)
++{
++	local_bh_disable();
++	MAL_DBG("%d: enable_rx(%d)" NL, mal->def->index, channel);
++	set_mal_dcrn(mal, MAL_RXCASR,
++		     get_mal_dcrn(mal, MAL_RXCASR) | MAL_CHAN_MASK(channel));
++	local_bh_enable();
++}
+ 
+-	/* Clear the error status register */
+-	set_mal_dcrn(mal, DCRN_MALESR, mal_error);
++void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel)
++{
++	set_mal_dcrn(mal, MAL_RXCARR, MAL_CHAN_MASK(channel));
++	MAL_DBG("%d: disable_rx(%d)" NL, mal->def->index, channel);
++}
+ 
+-	return IRQ_HANDLED;
++void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac)
++{
++	local_bh_disable();
++	MAL_DBG("%d: poll_add(%p)" NL, mal->def->index, commac);
++	list_add_tail(&commac->poll_list, &mal->poll_list);
++	local_bh_enable();
+ }
+ 
+-static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs)
++void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac)
++{
++	local_bh_disable();
++	MAL_DBG("%d: poll_del(%p)" NL, mal->def->index, commac);
++	list_del(&commac->poll_list);
++	local_bh_enable();
++}
++
++/* synchronized by mal_poll() */
++static inline void mal_enable_eob_irq(struct ibm_ocp_mal *mal)
++{
++	MAL_DBG2("%d: enable_irq" NL, mal->def->index);
++	set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) | MAL_CFG_EOPIE);
++}
++
++/* synchronized by __LINK_STATE_RX_SCHED bit in ndev->state */
++static inline void mal_disable_eob_irq(struct ibm_ocp_mal *mal)
++{
++	set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) & ~MAL_CFG_EOPIE);
++	MAL_DBG2("%d: disable_irq" NL, mal->def->index);
++}
++
++static irqreturn_t mal_serr(int irq, void *dev_instance, struct pt_regs *regs)
+ {
+ 	struct ibm_ocp_mal *mal = dev_instance;
+-	struct list_head *l;
+-	unsigned long isr;
++	u32 esr = get_mal_dcrn(mal, MAL_ESR);
+ 
+-	isr = get_mal_dcrn(mal, DCRN_MALTXEOBISR);
+-	set_mal_dcrn(mal, DCRN_MALTXEOBISR, isr);
++	/* Clear the error status register */
++	set_mal_dcrn(mal, MAL_ESR, esr);
+ 
+-	read_lock(&mal_list_lock);
+-	list_for_each(l, &mal->commac) {
+-		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
++	MAL_DBG("%d: SERR %08x" NL, mal->def->index, esr);
++
++	if (esr & MAL_ESR_EVB) {
++		if (esr & MAL_ESR_DE) {
++			/* We ignore Descriptor error,
++			 * TXDE or RXDE interrupt will be generated anyway.
++			 */
++			return IRQ_HANDLED;
++		}
+ 
+-		if (isr & mc->tx_chan_mask) {
+-			mc->ops->txeob(mc->dev, isr & mc->tx_chan_mask);
++		if (esr & MAL_ESR_PEIN) {
++			/* PLB error, it's probably buggy hardware or
++			 * incorrect physical address in BD (i.e. bug)
++			 */
++			if (net_ratelimit())
++				printk(KERN_ERR
++				       "mal%d: system error, PLB (ESR = 0x%08x)\n",
++				       mal->def->index, esr);
++			return IRQ_HANDLED;
+ 		}
++
++		/* OPB error, it's probably buggy hardware or incorrect EBC setup */
++		if (net_ratelimit())
++			printk(KERN_ERR
++			       "mal%d: system error, OPB (ESR = 0x%08x)\n",
++			       mal->def->index, esr);
+ 	}
+-	read_unlock(&mal_list_lock);
++	return IRQ_HANDLED;
++}
++
++static inline void mal_schedule_poll(struct ibm_ocp_mal *mal)
++{
++	if (likely(netif_rx_schedule_prep(&mal->poll_dev))) {
++		MAL_DBG2("%d: schedule_poll" NL, mal->def->index);
++		mal_disable_eob_irq(mal);
++		__netif_rx_schedule(&mal->poll_dev);
++	} else
++		MAL_DBG2("%d: already in poll" NL, mal->def->index);
++}
+ 
++static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs)
++{
++	struct ibm_ocp_mal *mal = dev_instance;
++	u32 r = get_mal_dcrn(mal, MAL_TXEOBISR);
++	MAL_DBG2("%d: txeob %08x" NL, mal->def->index, r);
++	mal_schedule_poll(mal);
++	set_mal_dcrn(mal, MAL_TXEOBISR, r);
+ 	return IRQ_HANDLED;
+ }
+ 
+ static irqreturn_t mal_rxeob(int irq, void *dev_instance, struct pt_regs *regs)
+ {
+ 	struct ibm_ocp_mal *mal = dev_instance;
+-	struct list_head *l;
+-	unsigned long isr;
++	u32 r = get_mal_dcrn(mal, MAL_RXEOBISR);
++	MAL_DBG2("%d: rxeob %08x" NL, mal->def->index, r);
++	mal_schedule_poll(mal);
++	set_mal_dcrn(mal, MAL_RXEOBISR, r);
++	return IRQ_HANDLED;
++}
+ 
+-	isr = get_mal_dcrn(mal, DCRN_MALRXEOBISR);
+-	set_mal_dcrn(mal, DCRN_MALRXEOBISR, isr);
++static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs)
++{
++	struct ibm_ocp_mal *mal = dev_instance;
++	u32 deir = get_mal_dcrn(mal, MAL_TXDEIR);
++	set_mal_dcrn(mal, MAL_TXDEIR, deir);
+ 
+-	read_lock(&mal_list_lock);
+-	list_for_each(l, &mal->commac) {
+-		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
++	MAL_DBG("%d: txde %08x" NL, mal->def->index, deir);
+ 
+-		if (isr & mc->rx_chan_mask) {
+-			mc->ops->rxeob(mc->dev, isr & mc->rx_chan_mask);
+-		}
+-	}
+-	read_unlock(&mal_list_lock);
++	if (net_ratelimit())
++		printk(KERN_ERR
++		       "mal%d: TX descriptor error (TXDEIR = 0x%08x)\n",
++		       mal->def->index, deir);
+ 
+ 	return IRQ_HANDLED;
+ }
+ 
+-static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs)
++static irqreturn_t mal_rxde(int irq, void *dev_instance, struct pt_regs *regs)
+ {
+ 	struct ibm_ocp_mal *mal = dev_instance;
+ 	struct list_head *l;
+-	unsigned long deir;
+-
+-	deir = get_mal_dcrn(mal, DCRN_MALTXDEIR);
++	u32 deir = get_mal_dcrn(mal, MAL_RXDEIR);
+ 
+-	/* FIXME: print which MAL correctly */
+-	printk(KERN_WARNING "%s: Tx descriptor error (MALTXDEIR=%lx)\n",
+-	       "MAL", deir);
++	MAL_DBG("%d: rxde %08x" NL, mal->def->index, deir);
+ 
+-	read_lock(&mal_list_lock);
+-	list_for_each(l, &mal->commac) {
++	list_for_each(l, &mal->list) {
+ 		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+-
+-		if (deir & mc->tx_chan_mask) {
+-			mc->ops->txde(mc->dev, deir & mc->tx_chan_mask);
++		if (deir & mc->rx_chan_mask) {
++			mc->rx_stopped = 1;
++			mc->ops->rxde(mc->dev);
+ 		}
+ 	}
+-	read_unlock(&mal_list_lock);
++
++	mal_schedule_poll(mal);
++	set_mal_dcrn(mal, MAL_RXDEIR, deir);
+ 
+ 	return IRQ_HANDLED;
+ }
+ 
+-/*
+- * This interrupt should be very rare at best.  This occurs when
+- * the hardware has a problem with the receive descriptors.  The manual
+- * states that it occurs when the hardware cannot the receive descriptor
+- * empty bit is not set.  The recovery mechanism will be to
+- * traverse through the descriptors, handle any that are marked to be
+- * handled and reinitialize each along the way.  At that point the driver
+- * will be restarted.
+- */
+-static irqreturn_t mal_rxde(int irq, void *dev_instance, struct pt_regs *regs)
++static int mal_poll(struct net_device *ndev, int *budget)
+ {
+-	struct ibm_ocp_mal *mal = dev_instance;
++	struct ibm_ocp_mal *mal = ndev->priv;
+ 	struct list_head *l;
+-	unsigned long deir;
++	int rx_work_limit = min(ndev->quota, *budget), received = 0, done;
+ 
+-	deir = get_mal_dcrn(mal, DCRN_MALRXDEIR);
++	MAL_DBG2("%d: poll(%d) %d ->" NL, mal->def->index, *budget,
++		 rx_work_limit);
++      again:
++	/* Process TX skbs */
++	list_for_each(l, &mal->poll_list) {
++		struct mal_commac *mc =
++		    list_entry(l, struct mal_commac, poll_list);
++		mc->ops->poll_tx(mc->dev);
++	}
+ 
+-	/*
+-	 * This really is needed.  This case encountered in stress testing.
++	/* Process RX skbs.
++	 * We _might_ need something more smart here to enforce polling fairness.
+ 	 */
+-	if (deir == 0)
+-		return IRQ_HANDLED;
+-
+-	/* FIXME: print which MAL correctly */
+-	printk(KERN_WARNING "%s: Rx descriptor error (MALRXDEIR=%lx)\n",
+-	       "MAL", deir);
+-
+-	read_lock(&mal_list_lock);
+-	list_for_each(l, &mal->commac) {
+-		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
++	list_for_each(l, &mal->poll_list) {
++		struct mal_commac *mc =
++		    list_entry(l, struct mal_commac, poll_list);
++		int n = mc->ops->poll_rx(mc->dev, rx_work_limit);
++		if (n) {
++			received += n;
++			rx_work_limit -= n;
++			if (rx_work_limit <= 0) {
++				done = 0;
++				goto more_work;	// XXX What if this is the last one ?
++			}
++		}
++	}
+ 
+-		if (deir & mc->rx_chan_mask) {
+-			mc->ops->rxde(mc->dev, deir & mc->rx_chan_mask);
++	/* We need to disable IRQs to protect from RXDE IRQ here */
++	local_irq_disable();
++	__netif_rx_complete(ndev);
++	mal_enable_eob_irq(mal);
++	local_irq_enable();
++
++	done = 1;
++
++	/* Check for "rotting" packet(s) */
++	list_for_each(l, &mal->poll_list) {
++		struct mal_commac *mc =
++		    list_entry(l, struct mal_commac, poll_list);
++		if (unlikely(mc->ops->peek_rx(mc->dev) || mc->rx_stopped)) {
++			MAL_DBG2("%d: rotting packet" NL, mal->def->index);
++			if (netif_rx_reschedule(ndev, received))
++				mal_disable_eob_irq(mal);
++			else
++				MAL_DBG2("%d: already in poll list" NL,
++					 mal->def->index);
++
++			if (rx_work_limit > 0)
++				goto again;
++			else
++				goto more_work;
+ 		}
++		mc->ops->poll_tx(mc->dev);
+ 	}
+-	read_unlock(&mal_list_lock);
+ 
+-	return IRQ_HANDLED;
++      more_work:
++	ndev->quota -= received;
++	*budget -= received;
++
++	MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, *budget,
++		 done ? 0 : 1);
++	return done ? 0 : 1;
++}
++
++static void mal_reset(struct ibm_ocp_mal *mal)
++{
++	int n = 10;
++	MAL_DBG("%d: reset" NL, mal->def->index);
++
++	set_mal_dcrn(mal, MAL_CFG, MAL_CFG_SR);
++
++	/* Wait for reset to complete (1 system clock) */
++	while ((get_mal_dcrn(mal, MAL_CFG) & MAL_CFG_SR) && n)
++		--n;
++
++	if (unlikely(!n))
++		printk(KERN_ERR "mal%d: reset timeout\n", mal->def->index);
++}
++
++int mal_get_regs_len(struct ibm_ocp_mal *mal)
++{
++	return sizeof(struct emac_ethtool_regs_subhdr) +
++	    sizeof(struct ibm_mal_regs);
++}
++
++void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf)
++{
++	struct emac_ethtool_regs_subhdr *hdr = buf;
++	struct ibm_mal_regs *regs = (struct ibm_mal_regs *)(hdr + 1);
++	struct ocp_func_mal_data *maldata = mal->def->additions;
++	int i;
++
++	hdr->version = MAL_VERSION;
++	hdr->index = mal->def->index;
++
++	regs->tx_count = maldata->num_tx_chans;
++	regs->rx_count = maldata->num_rx_chans;
++
++	regs->cfg = get_mal_dcrn(mal, MAL_CFG);
++	regs->esr = get_mal_dcrn(mal, MAL_ESR);
++	regs->ier = get_mal_dcrn(mal, MAL_IER);
++	regs->tx_casr = get_mal_dcrn(mal, MAL_TXCASR);
++	regs->tx_carr = get_mal_dcrn(mal, MAL_TXCARR);
++	regs->tx_eobisr = get_mal_dcrn(mal, MAL_TXEOBISR);
++	regs->tx_deir = get_mal_dcrn(mal, MAL_TXDEIR);
++	regs->rx_casr = get_mal_dcrn(mal, MAL_RXCASR);
++	regs->rx_carr = get_mal_dcrn(mal, MAL_RXCARR);
++	regs->rx_eobisr = get_mal_dcrn(mal, MAL_RXEOBISR);
++	regs->rx_deir = get_mal_dcrn(mal, MAL_RXDEIR);
++
++	for (i = 0; i < regs->tx_count; ++i)
++		regs->tx_ctpr[i] = get_mal_dcrn(mal, MAL_TXCTPR(i));
++
++	for (i = 0; i < regs->rx_count; ++i) {
++		regs->rx_ctpr[i] = get_mal_dcrn(mal, MAL_RXCTPR(i));
++		regs->rcbs[i] = get_mal_dcrn(mal, MAL_RCBS(i));
++	}
++	return regs + 1;
+ }
+ 
+ static int __init mal_probe(struct ocp_device *ocpdev)
+ {
+-	struct ibm_ocp_mal *mal = NULL;
++	struct ibm_ocp_mal *mal;
+ 	struct ocp_func_mal_data *maldata;
+-	int err = 0;
++	int err = 0, i, bd_size;
+ 
+-	maldata = (struct ocp_func_mal_data *)ocpdev->def->additions;
++	MAL_DBG("%d: probe" NL, ocpdev->def->index);
++
++	maldata = ocpdev->def->additions;
+ 	if (maldata == NULL) {
+-		printk(KERN_ERR "mal%d: Missing additional datas !\n",
++		printk(KERN_ERR "mal%d: missing additional data!\n",
+ 		       ocpdev->def->index);
+ 		return -ENODEV;
+ 	}
+ 
+-	mal = kmalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL);
+-	if (mal == NULL) {
++	mal = kzalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL);
++	if (!mal) {
+ 		printk(KERN_ERR
+-		       "mal%d: Out of memory allocating MAL structure !\n",
++		       "mal%d: out of memory allocating MAL structure!\n",
+ 		       ocpdev->def->index);
+ 		return -ENOMEM;
+ 	}
+-	memset(mal, 0, sizeof(*mal));
+-
+-	switch (ocpdev->def->index) {
+-	case 0:
+-		mal->dcrbase = DCRN_MAL_BASE;
+-		break;
+-#ifdef DCRN_MAL1_BASE
+-	case 1:
+-		mal->dcrbase = DCRN_MAL1_BASE;
+-		break;
+-#endif
+-	default:
+-		BUG();
+-	}
+-
+-	/**************************/
++	mal->dcrbase = maldata->dcr_base;
++	mal->def = ocpdev->def;
+ 
+-	INIT_LIST_HEAD(&mal->commac);
++	INIT_LIST_HEAD(&mal->poll_list);
++	set_bit(__LINK_STATE_START, &mal->poll_dev.state);
++	mal->poll_dev.weight = CONFIG_IBM_EMAC_POLL_WEIGHT;
++	mal->poll_dev.poll = mal_poll;
++	mal->poll_dev.priv = mal;
++	atomic_set(&mal->poll_dev.refcnt, 1);
+ 
+-	set_mal_dcrn(mal, DCRN_MALRXCARR, 0xFFFFFFFF);
+-	set_mal_dcrn(mal, DCRN_MALTXCARR, 0xFFFFFFFF);
++	INIT_LIST_HEAD(&mal->list);
+ 
+-	set_mal_dcrn(mal, DCRN_MALCR, MALCR_MMSR);	/* 384 */
+-	/* FIXME: Add delay */
++	/* Load power-on reset defaults */
++	mal_reset(mal);
+ 
+ 	/* Set the MAL configuration register */
+-	set_mal_dcrn(mal, DCRN_MALCR,
+-		     MALCR_PLBB | MALCR_OPBBL | MALCR_LEA |
+-		     MALCR_PLBLT_DEFAULT);
+-
+-	/* It would be nice to allocate buffers separately for each
+-	 * channel, but we can't because the channels share the upper
+-	 * 13 bits of address lines.  Each channels buffer must also
+-	 * be 4k aligned, so we allocate 4k for each channel.  This is
+-	 * inefficient FIXME: do better, if possible */
+-	mal->tx_virt_addr = dma_alloc_coherent(&ocpdev->dev,
+-					       MAL_DT_ALIGN *
+-					       maldata->num_tx_chans,
+-					       &mal->tx_phys_addr, GFP_KERNEL);
+-	if (mal->tx_virt_addr == NULL) {
++	set_mal_dcrn(mal, MAL_CFG, MAL_CFG_DEFAULT | MAL_CFG_PLBB |
++		     MAL_CFG_OPBBL | MAL_CFG_LEA);
++
++	mal_enable_eob_irq(mal);
++
++	/* Allocate space for BD rings */
++	BUG_ON(maldata->num_tx_chans <= 0 || maldata->num_tx_chans > 32);
++	BUG_ON(maldata->num_rx_chans <= 0 || maldata->num_rx_chans > 32);
++	bd_size = sizeof(struct mal_descriptor) *
++	    (NUM_TX_BUFF * maldata->num_tx_chans +
++	     NUM_RX_BUFF * maldata->num_rx_chans);
++	mal->bd_virt =
++	    dma_alloc_coherent(&ocpdev->dev, bd_size, &mal->bd_dma, GFP_KERNEL);
++
++	if (!mal->bd_virt) {
+ 		printk(KERN_ERR
+-		       "mal%d: Out of memory allocating MAL descriptors !\n",
+-		       ocpdev->def->index);
++		       "mal%d: out of memory allocating RX/TX descriptors!\n",
++		       mal->def->index);
+ 		err = -ENOMEM;
+ 		goto fail;
+ 	}
++	memset(mal->bd_virt, 0, bd_size);
+ 
+-	/* God, oh, god, I hate DCRs */
+-	set_mal_dcrn(mal, DCRN_MALTXCTP0R, mal->tx_phys_addr);
+-#ifdef DCRN_MALTXCTP1R
+-	if (maldata->num_tx_chans > 1)
+-		set_mal_dcrn(mal, DCRN_MALTXCTP1R,
+-			     mal->tx_phys_addr + MAL_DT_ALIGN);
+-#endif				/* DCRN_MALTXCTP1R */
+-#ifdef DCRN_MALTXCTP2R
+-	if (maldata->num_tx_chans > 2)
+-		set_mal_dcrn(mal, DCRN_MALTXCTP2R,
+-			     mal->tx_phys_addr + 2 * MAL_DT_ALIGN);
+-#endif				/* DCRN_MALTXCTP2R */
+-#ifdef DCRN_MALTXCTP3R
+-	if (maldata->num_tx_chans > 3)
+-		set_mal_dcrn(mal, DCRN_MALTXCTP3R,
+-			     mal->tx_phys_addr + 3 * MAL_DT_ALIGN);
+-#endif				/* DCRN_MALTXCTP3R */
+-#ifdef DCRN_MALTXCTP4R
+-	if (maldata->num_tx_chans > 4)
+-		set_mal_dcrn(mal, DCRN_MALTXCTP4R,
+-			     mal->tx_phys_addr + 4 * MAL_DT_ALIGN);
+-#endif				/* DCRN_MALTXCTP4R */
+-#ifdef DCRN_MALTXCTP5R
+-	if (maldata->num_tx_chans > 5)
+-		set_mal_dcrn(mal, DCRN_MALTXCTP5R,
+-			     mal->tx_phys_addr + 5 * MAL_DT_ALIGN);
+-#endif				/* DCRN_MALTXCTP5R */
+-#ifdef DCRN_MALTXCTP6R
+-	if (maldata->num_tx_chans > 6)
+-		set_mal_dcrn(mal, DCRN_MALTXCTP6R,
+-			     mal->tx_phys_addr + 6 * MAL_DT_ALIGN);
+-#endif				/* DCRN_MALTXCTP6R */
+-#ifdef DCRN_MALTXCTP7R
+-	if (maldata->num_tx_chans > 7)
+-		set_mal_dcrn(mal, DCRN_MALTXCTP7R,
+-			     mal->tx_phys_addr + 7 * MAL_DT_ALIGN);
+-#endif				/* DCRN_MALTXCTP7R */
+-
+-	mal->rx_virt_addr = dma_alloc_coherent(&ocpdev->dev,
+-					       MAL_DT_ALIGN *
+-					       maldata->num_rx_chans,
+-					       &mal->rx_phys_addr, GFP_KERNEL);
+-
+-	set_mal_dcrn(mal, DCRN_MALRXCTP0R, mal->rx_phys_addr);
+-#ifdef DCRN_MALRXCTP1R
+-	if (maldata->num_rx_chans > 1)
+-		set_mal_dcrn(mal, DCRN_MALRXCTP1R,
+-			     mal->rx_phys_addr + MAL_DT_ALIGN);
+-#endif				/* DCRN_MALRXCTP1R */
+-#ifdef DCRN_MALRXCTP2R
+-	if (maldata->num_rx_chans > 2)
+-		set_mal_dcrn(mal, DCRN_MALRXCTP2R,
+-			     mal->rx_phys_addr + 2 * MAL_DT_ALIGN);
+-#endif				/* DCRN_MALRXCTP2R */
+-#ifdef DCRN_MALRXCTP3R
+-	if (maldata->num_rx_chans > 3)
+-		set_mal_dcrn(mal, DCRN_MALRXCTP3R,
+-			     mal->rx_phys_addr + 3 * MAL_DT_ALIGN);
+-#endif				/* DCRN_MALRXCTP3R */
++	for (i = 0; i < maldata->num_tx_chans; ++i)
++		set_mal_dcrn(mal, MAL_TXCTPR(i), mal->bd_dma +
++			     sizeof(struct mal_descriptor) *
++			     mal_tx_bd_offset(mal, i));
++
++	for (i = 0; i < maldata->num_rx_chans; ++i)
++		set_mal_dcrn(mal, MAL_RXCTPR(i), mal->bd_dma +
++			     sizeof(struct mal_descriptor) *
++			     mal_rx_bd_offset(mal, i));
+ 
+ 	err = request_irq(maldata->serr_irq, mal_serr, 0, "MAL SERR", mal);
+ 	if (err)
+-		goto fail;
+-	err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE ", mal);
++		goto fail2;
++	err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE", mal);
+ 	if (err)
+-		goto fail;
++		goto fail3;
+ 	err = request_irq(maldata->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal);
+ 	if (err)
+-		goto fail;
++		goto fail4;
+ 	err = request_irq(maldata->rxde_irq, mal_rxde, 0, "MAL RX DE", mal);
+ 	if (err)
+-		goto fail;
++		goto fail5;
+ 	err = request_irq(maldata->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal);
+ 	if (err)
+-		goto fail;
++		goto fail6;
+ 
+-	set_mal_dcrn(mal, DCRN_MALIER,
+-		     MALIER_DE | MALIER_NE | MALIER_TE |
+-		     MALIER_OPBE | MALIER_PLBE);
++	/* Enable all MAL SERR interrupt sources */
++	set_mal_dcrn(mal, MAL_IER, MAL_IER_EVENTS);
+ 
+-	/* Advertise me to the rest of the world */
++	/* Advertise this instance to the rest of the world */
+ 	ocp_set_drvdata(ocpdev, mal);
+ 
+-	printk(KERN_INFO "mal%d: Initialized, %d tx channels, %d rx channels\n",
+-	       ocpdev->def->index, maldata->num_tx_chans,
+-	       maldata->num_rx_chans);
++	mal_dbg_register(mal->def->index, mal);
+ 
++	printk(KERN_INFO "mal%d: initialized, %d TX channels, %d RX channels\n",
++	       mal->def->index, maldata->num_tx_chans, maldata->num_rx_chans);
+ 	return 0;
+ 
++      fail6:
++	free_irq(maldata->rxde_irq, mal);
++      fail5:
++	free_irq(maldata->txeob_irq, mal);
++      fail4:
++	free_irq(maldata->txde_irq, mal);
++      fail3:
++	free_irq(maldata->serr_irq, mal);
++      fail2:
++	dma_free_coherent(&ocpdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
+       fail:
+-	/* FIXME: dispose requested IRQs ! */
+-	if (err && mal)
+-		kfree(mal);
++	kfree(mal);
+ 	return err;
+ }
+ 
+ static void __exit mal_remove(struct ocp_device *ocpdev)
+ {
+ 	struct ibm_ocp_mal *mal = ocp_get_drvdata(ocpdev);
+-	struct ocp_func_mal_data *maldata = ocpdev->def->additions;
++	struct ocp_func_mal_data *maldata = mal->def->additions;
+ 
+-	BUG_ON(!maldata);
++	MAL_DBG("%d: remove" NL, mal->def->index);
++
++	/* Syncronize with scheduled polling, 
++	   stolen from net/core/dev.c:dev_close() 
++	 */
++	clear_bit(__LINK_STATE_START, &mal->poll_dev.state);
++	netif_poll_disable(&mal->poll_dev);
++
++	if (!list_empty(&mal->list)) {
++		/* This is *very* bad */
++		printk(KERN_EMERG
++		       "mal%d: commac list is not empty on remove!\n",
++		       mal->def->index);
++	}
+ 
+ 	ocp_set_drvdata(ocpdev, NULL);
+ 
+-	/* FIXME: shut down the MAL, deal with dependency with emac */
+ 	free_irq(maldata->serr_irq, mal);
+ 	free_irq(maldata->txde_irq, mal);
+ 	free_irq(maldata->txeob_irq, mal);
+ 	free_irq(maldata->rxde_irq, mal);
+ 	free_irq(maldata->rxeob_irq, mal);
+ 
+-	if (mal->tx_virt_addr)
+-		dma_free_coherent(&ocpdev->dev,
+-				  MAL_DT_ALIGN * maldata->num_tx_chans,
+-				  mal->tx_virt_addr, mal->tx_phys_addr);
+-
+-	if (mal->rx_virt_addr)
+-		dma_free_coherent(&ocpdev->dev,
+-				  MAL_DT_ALIGN * maldata->num_rx_chans,
+-				  mal->rx_virt_addr, mal->rx_phys_addr);
++	mal_reset(mal);
++
++	mal_dbg_register(mal->def->index, NULL);
++
++	dma_free_coherent(&ocpdev->dev,
++			  sizeof(struct mal_descriptor) *
++			  (NUM_TX_BUFF * maldata->num_tx_chans +
++			   NUM_RX_BUFF * maldata->num_rx_chans), mal->bd_virt,
++			  mal->bd_dma);
+ 
+ 	kfree(mal);
+ }
+ 
+ /* Structure for a device driver */
+ static struct ocp_device_id mal_ids[] = {
+-	{.vendor = OCP_ANY_ID,.function = OCP_FUNC_MAL},
+-	{.vendor = OCP_VENDOR_INVALID}
++	{ .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_MAL },
++	{ .vendor = OCP_VENDOR_INVALID}
+ };
+ 
+ static struct ocp_driver mal_driver = {
+@@ -441,23 +570,14 @@ static struct ocp_driver mal_driver = {
+ 	.remove = mal_remove,
+ };
+ 
+-static int __init init_mals(void)
++int __init mal_init(void)
+ {
+-	int rc;
+-
+-	rc = ocp_register_driver(&mal_driver);
+-	if (rc < 0) {
+-		ocp_unregister_driver(&mal_driver);
+-		return -ENODEV;
+-	}
+-
+-	return 0;
++	MAL_DBG(": init" NL);
++	return ocp_register_driver(&mal_driver);
+ }
+ 
+-static void __exit exit_mals(void)
++void __exit mal_exit(void)
+ {
++	MAL_DBG(": exit" NL);
+ 	ocp_unregister_driver(&mal_driver);
+ }
+-
+-module_init(init_mals);
+-module_exit(exit_mals);
+diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h
+--- a/drivers/net/ibm_emac/ibm_emac_mal.h
++++ b/drivers/net/ibm_emac/ibm_emac_mal.h
+@@ -1,131 +1,267 @@
+-#ifndef _IBM_EMAC_MAL_H
+-#define _IBM_EMAC_MAL_H
++/*
++ * drivers/net/ibm_emac/ibm_emac_mal.h
++ *
++ * Memory Access Layer (MAL) support
++ * 
++ * Copyright (c) 2004, 2005 Zultys Technologies.
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
++ *
++ * Based on original work by
++ *      Armin Kuster <akuster at mvista.com>
++ *      Copyright 2002 MontaVista Softare 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 __IBM_EMAC_MAL_H_
++#define __IBM_EMAC_MAL_H_
+ 
++#include <linux/config.h>
++#include <linux/init.h>
+ #include <linux/list.h>
++#include <linux/netdevice.h>
+ 
+-#define MAL_DT_ALIGN	(4096)	/* Alignment for each channel's descriptor table */
++#include <asm/io.h>
+ 
+-#define MAL_CHAN_MASK(chan)	(0x80000000 >> (chan))
++/*
++ * These MAL "versions" probably aren't the real versions IBM uses for these 
++ * MAL cores, I assigned them just to make #ifdefs in this file nicer and 
++ * reflect the fact that 40x and 44x have slightly different MALs. --ebs
++ */
++#if defined(CONFIG_405GP) || defined(CONFIG_405GPR) || defined(CONFIG_405EP) || \
++    defined(CONFIG_440EP) || defined(CONFIG_NP405H)
++#define MAL_VERSION		1
++#elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP)
++#define MAL_VERSION		2
++#else
++#error "Unknown SoC, please check chip manual and choose MAL 'version'"
++#endif
++
++/* MALx DCR registers */
++#define	MAL_CFG			0x00
++#define	  MAL_CFG_SR		0x80000000
++#define   MAL_CFG_PLBB		0x00004000
++#define   MAL_CFG_OPBBL		0x00000080
++#define   MAL_CFG_EOPIE		0x00000004
++#define   MAL_CFG_LEA		0x00000002
++#define   MAL_CFG_SD		0x00000001
++#if MAL_VERSION == 1
++#define   MAL_CFG_PLBP_MASK	0x00c00000
++#define   MAL_CFG_PLBP_10	0x00800000
++#define   MAL_CFG_GA		0x00200000
++#define   MAL_CFG_OA		0x00100000
++#define   MAL_CFG_PLBLE		0x00080000
++#define   MAL_CFG_PLBT_MASK	0x00078000
++#define   MAL_CFG_DEFAULT	(MAL_CFG_PLBP_10 | MAL_CFG_PLBT_MASK)
++#elif MAL_VERSION == 2
++#define   MAL_CFG_RPP_MASK	0x00c00000
++#define   MAL_CFG_RPP_10	0x00800000
++#define   MAL_CFG_RMBS_MASK	0x00300000
++#define   MAL_CFG_WPP_MASK	0x000c0000
++#define   MAL_CFG_WPP_10	0x00080000
++#define   MAL_CFG_WMBS_MASK	0x00030000
++#define   MAL_CFG_PLBLE		0x00008000
++#define   MAL_CFG_DEFAULT	(MAL_CFG_RMBS_MASK | MAL_CFG_WMBS_MASK | \
++				 MAL_CFG_RPP_10 | MAL_CFG_WPP_10)
++#else
++#error "Unknown MAL version"
++#endif
++
++#define MAL_ESR			0x01
++#define   MAL_ESR_EVB		0x80000000
++#define   MAL_ESR_CIDT		0x40000000
++#define   MAL_ESR_CID_MASK	0x3e000000
++#define   MAL_ESR_CID_SHIFT	25
++#define   MAL_ESR_DE		0x00100000
++#define   MAL_ESR_OTE		0x00040000
++#define   MAL_ESR_OSE		0x00020000
++#define   MAL_ESR_PEIN		0x00010000
++#define   MAL_ESR_DEI		0x00000010
++#define   MAL_ESR_OTEI		0x00000004
++#define   MAL_ESR_OSEI		0x00000002
++#define   MAL_ESR_PBEI		0x00000001
++#if MAL_VERSION == 1
++#define   MAL_ESR_ONE		0x00080000
++#define   MAL_ESR_ONEI		0x00000008
++#elif MAL_VERSION == 2
++#define   MAL_ESR_PTE		0x00800000
++#define   MAL_ESR_PRE		0x00400000
++#define   MAL_ESR_PWE		0x00200000
++#define   MAL_ESR_PTEI		0x00000080
++#define   MAL_ESR_PREI		0x00000040
++#define   MAL_ESR_PWEI		0x00000020
++#else
++#error "Unknown MAL version"
++#endif
++
++#define MAL_IER			0x02
++#define   MAL_IER_DE		0x00000010
++#define   MAL_IER_OTE		0x00000004
++#define   MAL_IER_OE		0x00000002
++#define   MAL_IER_PE		0x00000001
++#if MAL_VERSION == 1
++#define   MAL_IER_NWE		0x00000008
++#define   MAL_IER_SOC_EVENTS	MAL_IER_NWE
++#elif MAL_VERSION == 2
++#define   MAL_IER_PT		0x00000080
++#define   MAL_IER_PRE		0x00000040
++#define   MAL_IER_PWE		0x00000020
++#define   MAL_IER_SOC_EVENTS	(MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE)
++#else
++#error "Unknown MAL version"
++#endif
++#define   MAL_IER_EVENTS	(MAL_IER_SOC_EVENTS | MAL_IER_OTE | \
++				 MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE)
++
++#define MAL_TXCASR		0x04
++#define MAL_TXCARR		0x05
++#define MAL_TXEOBISR		0x06
++#define MAL_TXDEIR		0x07
++#define MAL_RXCASR		0x10
++#define MAL_RXCARR		0x11
++#define MAL_RXEOBISR		0x12
++#define MAL_RXDEIR		0x13
++#define MAL_TXCTPR(n)		((n) + 0x20)
++#define MAL_RXCTPR(n)		((n) + 0x40)
++#define MAL_RCBS(n)		((n) + 0x60)
++
++/* In reality MAL can handle TX buffers up to 4095 bytes long, 
++ * but this isn't a good round number :) 		 --ebs
++ */
++#define MAL_MAX_TX_SIZE		4080
++#define MAL_MAX_RX_SIZE		4080
++
++static inline int mal_rx_size(int len)
++{
++	len = (len + 0xf) & ~0xf;
++	return len > MAL_MAX_RX_SIZE ? MAL_MAX_RX_SIZE : len;
++}
++
++static inline int mal_tx_chunks(int len)
++{
++	return (len + MAL_MAX_TX_SIZE - 1) / MAL_MAX_TX_SIZE;
++}
++
++#define MAL_CHAN_MASK(n)	(0x80000000 >> (n))
+ 
+ /* MAL Buffer Descriptor structure */
+ struct mal_descriptor {
+-	unsigned short ctrl;	/* MAL / Commac status control bits */
+-	short data_len;		/* Max length is 4K-1 (12 bits)     */
+-	unsigned char *data_ptr;	/* pointer to actual data buffer    */
+-} __attribute__ ((packed));
++	u16 ctrl;		/* MAL / Commac status control bits */
++	u16 data_len;		/* Max length is 4K-1 (12 bits)     */
++	u32 data_ptr;		/* pointer to actual data buffer    */
++};
+ 
+ /* the following defines are for the MadMAL status and control registers. */
+ /* MADMAL transmit and receive status/control bits  */
+-#define MAL_RX_CTRL_EMPTY		0x8000
+-#define MAL_RX_CTRL_WRAP		0x4000
+-#define MAL_RX_CTRL_CM			0x2000
+-#define MAL_RX_CTRL_LAST		0x1000
+-#define MAL_RX_CTRL_FIRST		0x0800
+-#define MAL_RX_CTRL_INTR		0x0400
+-
+-#define MAL_TX_CTRL_READY		0x8000
+-#define MAL_TX_CTRL_WRAP		0x4000
+-#define MAL_TX_CTRL_CM			0x2000
+-#define MAL_TX_CTRL_LAST		0x1000
+-#define MAL_TX_CTRL_INTR		0x0400
++#define MAL_RX_CTRL_EMPTY	0x8000
++#define MAL_RX_CTRL_WRAP	0x4000
++#define MAL_RX_CTRL_CM		0x2000
++#define MAL_RX_CTRL_LAST	0x1000
++#define MAL_RX_CTRL_FIRST	0x0800
++#define MAL_RX_CTRL_INTR	0x0400
++#define MAL_RX_CTRL_SINGLE	(MAL_RX_CTRL_LAST | MAL_RX_CTRL_FIRST)
++#define MAL_IS_SINGLE_RX(ctrl)	(((ctrl) & MAL_RX_CTRL_SINGLE) == MAL_RX_CTRL_SINGLE)
++
++#define MAL_TX_CTRL_READY	0x8000
++#define MAL_TX_CTRL_WRAP	0x4000
++#define MAL_TX_CTRL_CM		0x2000
++#define MAL_TX_CTRL_LAST	0x1000
++#define MAL_TX_CTRL_INTR	0x0400
+ 
+ struct mal_commac_ops {
+-	void (*txeob) (void *dev, u32 chanmask);
+-	void (*txde) (void *dev, u32 chanmask);
+-	void (*rxeob) (void *dev, u32 chanmask);
+-	void (*rxde) (void *dev, u32 chanmask);
++	void	(*poll_tx) (void *dev);
++	int	(*poll_rx) (void *dev, int budget);
++	int	(*peek_rx) (void *dev);
++	void	(*rxde) (void *dev);
+ };
+ 
+ struct mal_commac {
+-	struct mal_commac_ops *ops;
+-	void *dev;
+-	u32 tx_chan_mask, rx_chan_mask;
+-	struct list_head list;
++	struct mal_commac_ops	*ops;
++	void			*dev;
++	struct list_head	poll_list;
++	int			rx_stopped;
++
++	u32			tx_chan_mask;
++	u32			rx_chan_mask;
++	struct list_head	list;
+ };
+ 
+ struct ibm_ocp_mal {
+-	int dcrbase;
++	int			dcrbase;
+ 
+-	struct list_head commac;
+-	u32 tx_chan_mask, rx_chan_mask;
++	struct list_head	poll_list;
++	struct net_device	poll_dev;
+ 
+-	dma_addr_t tx_phys_addr;
+-	struct mal_descriptor *tx_virt_addr;
++	struct list_head	list;
++	u32			tx_chan_mask;
++	u32			rx_chan_mask;
+ 
+-	dma_addr_t rx_phys_addr;
+-	struct mal_descriptor *rx_virt_addr;
+-};
++	dma_addr_t		bd_dma;
++	struct mal_descriptor	*bd_virt;
+ 
+-#define GET_MAL_STANZA(base,dcrn) \
+-	case base: \
+-		x = mfdcr(dcrn(base)); \
+-		break;
+-
+-#define SET_MAL_STANZA(base,dcrn, val) \
+-	case base: \
+-		mtdcr(dcrn(base), (val)); \
+-		break;
+-
+-#define GET_MAL0_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL_BASE,dcrn)
+-#define SET_MAL0_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL_BASE,dcrn,val)
+-
+-#ifdef DCRN_MAL1_BASE
+-#define GET_MAL1_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL1_BASE,dcrn)
+-#define SET_MAL1_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL1_BASE,dcrn,val)
+-#else				/* ! DCRN_MAL1_BASE */
+-#define GET_MAL1_STANZA(dcrn)
+-#define SET_MAL1_STANZA(dcrn,val)
+-#endif
+-
+-#define get_mal_dcrn(mal, dcrn) ({ \
+-	u32 x; \
+-	switch ((mal)->dcrbase) { \
+-		GET_MAL0_STANZA(dcrn) \
+-		GET_MAL1_STANZA(dcrn) \
+-	default: \
+-		x = 0; \
+-		BUG(); \
+-	} \
+-x; })
+-
+-#define set_mal_dcrn(mal, dcrn, val) do { \
+-	switch ((mal)->dcrbase) { \
+-		SET_MAL0_STANZA(dcrn,val) \
+-		SET_MAL1_STANZA(dcrn,val) \
+-	default: \
+-		BUG(); \
+-	} } while (0)
+-
+-static inline void mal_enable_tx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
+-{
+-	set_mal_dcrn(mal, DCRN_MALTXCASR,
+-		     get_mal_dcrn(mal, DCRN_MALTXCASR) | chanmask);
+-}
+-
+-static inline void mal_disable_tx_channels(struct ibm_ocp_mal *mal,
+-					   u32 chanmask)
+-{
+-	set_mal_dcrn(mal, DCRN_MALTXCARR, chanmask);
+-}
++	struct ocp_def		*def;
++};
+ 
+-static inline void mal_enable_rx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
++static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
+ {
+-	set_mal_dcrn(mal, DCRN_MALRXCASR,
+-		     get_mal_dcrn(mal, DCRN_MALRXCASR) | chanmask);
++	return mfdcr(mal->dcrbase + reg);
+ }
+ 
+-static inline void mal_disable_rx_channels(struct ibm_ocp_mal *mal,
+-					   u32 chanmask)
++static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
+ {
+-	set_mal_dcrn(mal, DCRN_MALRXCARR, chanmask);
++	mtdcr(mal->dcrbase + reg, val);
+ }
+ 
+-extern int mal_register_commac(struct ibm_ocp_mal *mal,
+-			       struct mal_commac *commac);
+-extern int mal_unregister_commac(struct ibm_ocp_mal *mal,
+-				 struct mal_commac *commac);
++/* Register MAL devices */
++int mal_init(void) __init;
++void mal_exit(void) __exit;
++
++int mal_register_commac(struct ibm_ocp_mal *mal,
++			struct mal_commac *commac) __init;
++void mal_unregister_commac(struct ibm_ocp_mal *mal,
++			   struct mal_commac *commac) __exit;
++int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size);
++
++/* Returns BD ring offset for a particular channel
++   (in 'struct mal_descriptor' elements)
++*/
++int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel);
++int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel);
++
++void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel);
++void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel);
++void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel);
++void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel);
++
++/* Add/remove EMAC to/from MAL polling list */
++void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac);
++void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac);
++
++/* Ethtool MAL registers */
++struct ibm_mal_regs {
++	u32 tx_count;
++	u32 rx_count;
++
++	u32 cfg;
++	u32 esr;
++	u32 ier;
++	u32 tx_casr;
++	u32 tx_carr;
++	u32 tx_eobisr;
++	u32 tx_deir;
++	u32 rx_casr;
++	u32 rx_carr;
++	u32 rx_eobisr;
++	u32 rx_deir;
++	u32 tx_ctpr[32];
++	u32 rx_ctpr[32];
++	u32 rcbs[32];
++};
+ 
+-extern int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel,
+-			unsigned long size);
++int mal_get_regs_len(struct ibm_ocp_mal *mal);
++void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf);
+ 
+-#endif				/* _IBM_EMAC_MAL_H */
++#endif				/* __IBM_EMAC_MAL_H_ */
+diff --git a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c
+--- a/drivers/net/ibm_emac/ibm_emac_phy.c
++++ b/drivers/net/ibm_emac/ibm_emac_phy.c
+@@ -1,96 +1,80 @@
+ /*
+- * ibm_ocp_phy.c
++ * drivers/net/ibm_emac/ibm_emac_phy.c
+  *
+- * PHY drivers for the ibm ocp ethernet driver. Borrowed
+- * from sungem_phy.c, though I only kept the generic MII
++ * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
++ * Borrowed from sungem_phy.c, though I only kept the generic MII
+  * driver for now.
+  * 
+  * This file should be shared with other drivers or eventually
+  * merged as the "low level" part of miilib
+  * 
+  * (c) 2003, Benjamin Herrenscmidt (benh at kernel.crashing.org)
++ * (c) 2004-2005, Eugene Surovegin <ebs at ebshome.net>
+  *
+  */
+-
+ #include <linux/config.h>
+-
+ #include <linux/module.h>
+-
+ #include <linux/kernel.h>
+-#include <linux/sched.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+ #include <linux/mii.h>
+ #include <linux/ethtool.h>
+ #include <linux/delay.h>
+ 
++#include <asm/ocp.h>
++
+ #include "ibm_emac_phy.h"
+ 
+-static int reset_one_mii_phy(struct mii_phy *phy, int phy_id)
++static inline int phy_read(struct mii_phy *phy, int reg)
++{
++	return phy->mdio_read(phy->dev, phy->address, reg);
++}
++
++static inline void phy_write(struct mii_phy *phy, int reg, int val)
+ {
+-	u16 val;
++	phy->mdio_write(phy->dev, phy->address, reg, val);
++}
++
++int mii_reset_phy(struct mii_phy *phy)
++{
++	int val;
+ 	int limit = 10000;
+ 
+-	val = __phy_read(phy, phy_id, MII_BMCR);
++	val = phy_read(phy, MII_BMCR);
+ 	val &= ~BMCR_ISOLATE;
+ 	val |= BMCR_RESET;
+-	__phy_write(phy, phy_id, MII_BMCR, val);
++	phy_write(phy, MII_BMCR, val);
+ 
+-	udelay(100);
++	udelay(300);
+ 
+ 	while (limit--) {
+-		val = __phy_read(phy, phy_id, MII_BMCR);
+-		if ((val & BMCR_RESET) == 0)
++		val = phy_read(phy, MII_BMCR);
++		if (val >= 0 && (val & BMCR_RESET) == 0)
+ 			break;
+ 		udelay(10);
+ 	}
+ 	if ((val & BMCR_ISOLATE) && limit > 0)
+-		__phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE);
+-
+-	return (limit <= 0);
+-}
+-
+-static int cis8201_init(struct mii_phy *phy)
+-{
+-	u16 epcr;
+-
+-	epcr = phy_read(phy, MII_CIS8201_EPCR);
+-	epcr &= ~EPCR_MODE_MASK;
+-
+-	switch (phy->mode) {
+-	case PHY_MODE_TBI:
+-		epcr |= EPCR_TBI_MODE;
+-		break;
+-	case PHY_MODE_RTBI:
+-		epcr |= EPCR_RTBI_MODE;
+-		break;
+-	case PHY_MODE_GMII:
+-		epcr |= EPCR_GMII_MODE;
+-		break;
+-	case PHY_MODE_RGMII:
+-	default:
+-		epcr |= EPCR_RGMII_MODE;
+-	}
++		phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
+ 
+-	phy_write(phy, MII_CIS8201_EPCR, epcr);
+-
+-	return 0;
++	return limit <= 0;
+ }
+ 
+ static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
+ {
+-	u16 ctl, adv;
++	int ctl, adv;
+ 
+-	phy->autoneg = 1;
++	phy->autoneg = AUTONEG_ENABLE;
+ 	phy->speed = SPEED_10;
+ 	phy->duplex = DUPLEX_HALF;
+-	phy->pause = 0;
++	phy->pause = phy->asym_pause = 0;
+ 	phy->advertising = advertise;
+ 
+ 	/* Setup standard advertise */
+ 	adv = phy_read(phy, MII_ADVERTISE);
+-	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
++	if (adv < 0)
++		return adv;
++	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
++		 ADVERTISE_PAUSE_ASYM);
+ 	if (advertise & ADVERTISED_10baseT_Half)
+ 		adv |= ADVERTISE_10HALF;
+ 	if (advertise & ADVERTISED_10baseT_Full)
+@@ -99,8 +83,25 @@ static int genmii_setup_aneg(struct mii_
+ 		adv |= ADVERTISE_100HALF;
+ 	if (advertise & ADVERTISED_100baseT_Full)
+ 		adv |= ADVERTISE_100FULL;
++	if (advertise & ADVERTISED_Pause)
++		adv |= ADVERTISE_PAUSE_CAP;
++	if (advertise & ADVERTISED_Asym_Pause)
++		adv |= ADVERTISE_PAUSE_ASYM;
+ 	phy_write(phy, MII_ADVERTISE, adv);
+ 
++	if (phy->features &
++	    (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
++		adv = phy_read(phy, MII_CTRL1000);
++		if (adv < 0)
++			return adv;
++		adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
++		if (advertise & ADVERTISED_1000baseT_Full)
++			adv |= ADVERTISE_1000FULL;
++		if (advertise & ADVERTISED_1000baseT_Half)
++			adv |= ADVERTISE_1000HALF;
++		phy_write(phy, MII_CTRL1000, adv);
++	}
++
+ 	/* Start/Restart aneg */
+ 	ctl = phy_read(phy, MII_BMCR);
+ 	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+@@ -111,14 +112,16 @@ static int genmii_setup_aneg(struct mii_
+ 
+ static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
+ {
+-	u16 ctl;
++	int ctl;
+ 
+-	phy->autoneg = 0;
++	phy->autoneg = AUTONEG_DISABLE;
+ 	phy->speed = speed;
+ 	phy->duplex = fd;
+-	phy->pause = 0;
++	phy->pause = phy->asym_pause = 0;
+ 
+ 	ctl = phy_read(phy, MII_BMCR);
++	if (ctl < 0)
++		return ctl;
+ 	ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE);
+ 
+ 	/* First reset the PHY */
+@@ -132,6 +135,8 @@ static int genmii_setup_forced(struct mi
+ 		ctl |= BMCR_SPEED100;
+ 		break;
+ 	case SPEED_1000:
++		ctl |= BMCR_SPEED1000;
++		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -144,112 +149,143 @@ static int genmii_setup_forced(struct mi
+ 
+ static int genmii_poll_link(struct mii_phy *phy)
+ {
+-	u16 status;
++	int status;
+ 
+-	(void)phy_read(phy, MII_BMSR);
++	/* Clear latched value with dummy read */
++	phy_read(phy, MII_BMSR);
+ 	status = phy_read(phy, MII_BMSR);
+-	if ((status & BMSR_LSTATUS) == 0)
++	if (status < 0 || (status & BMSR_LSTATUS) == 0)
+ 		return 0;
+-	if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE))
++	if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
+ 		return 0;
+ 	return 1;
+ }
+ 
+-#define	MII_CIS8201_ACSR	0x1c
+-#define  ACSR_DUPLEX_STATUS	0x0020
+-#define  ACSR_SPEED_1000BASET	0x0010
+-#define  ACSR_SPEED_100BASET	0x0008
+-
+-static int cis8201_read_link(struct mii_phy *phy)
++static int genmii_read_link(struct mii_phy *phy)
+ {
+-	u16 acsr;
++	if (phy->autoneg == AUTONEG_ENABLE) {
++		int glpa = 0;
++		int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
++		if (lpa < 0)
++			return lpa;
++
++		if (phy->features &
++		    (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
++			int adv = phy_read(phy, MII_CTRL1000);
++			glpa = phy_read(phy, MII_STAT1000);
+ 
+-	if (phy->autoneg) {
+-		acsr = phy_read(phy, MII_CIS8201_ACSR);
++			if (glpa < 0 || adv < 0)
++				return adv;
+ 
+-		if (acsr & ACSR_DUPLEX_STATUS)
++			glpa &= adv << 2;
++		}
++
++		phy->speed = SPEED_10;
++		phy->duplex = DUPLEX_HALF;
++		phy->pause = phy->asym_pause = 0;
++
++		if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
++			phy->speed = SPEED_1000;
++			if (glpa & LPA_1000FULL)
++				phy->duplex = DUPLEX_FULL;
++		} else if (lpa & (LPA_100FULL | LPA_100HALF)) {
++			phy->speed = SPEED_100;
++			if (lpa & LPA_100FULL)
++				phy->duplex = DUPLEX_FULL;
++		} else if (lpa & LPA_10FULL)
++			phy->duplex = DUPLEX_FULL;
++
++		if (phy->duplex == DUPLEX_FULL) {
++			phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
++			phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
++		}
++	} else {
++		int bmcr = phy_read(phy, MII_BMCR);
++		if (bmcr < 0)
++			return bmcr;
++
++		if (bmcr & BMCR_FULLDPLX)
+ 			phy->duplex = DUPLEX_FULL;
+ 		else
+ 			phy->duplex = DUPLEX_HALF;
+-		if (acsr & ACSR_SPEED_1000BASET) {
++		if (bmcr & BMCR_SPEED1000)
+ 			phy->speed = SPEED_1000;
+-		} else if (acsr & ACSR_SPEED_100BASET)
++		else if (bmcr & BMCR_SPEED100)
+ 			phy->speed = SPEED_100;
+ 		else
+ 			phy->speed = SPEED_10;
+-		phy->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
+-	 */
+ 
++		phy->pause = phy->asym_pause = 0;
++	}
+ 	return 0;
+ }
+ 
+-static int genmii_read_link(struct mii_phy *phy)
++/* Generic implementation for most 10/100/1000 PHYs */
++static struct mii_phy_ops generic_phy_ops = {
++	.setup_aneg	= genmii_setup_aneg,
++	.setup_forced	= genmii_setup_forced,
++	.poll_link	= genmii_poll_link,
++	.read_link	= genmii_read_link
++};
++
++static struct mii_phy_def genmii_phy_def = {
++	.phy_id		= 0x00000000,
++	.phy_id_mask	= 0x00000000,
++	.name		= "Generic MII",
++	.ops		= &generic_phy_ops
++};
++
++/* CIS8201 */
++#define MII_CIS8201_EPCR	0x17
++#define  EPCR_MODE_MASK		0x3000
++#define  EPCR_GMII_MODE		0x0000
++#define  EPCR_RGMII_MODE	0x1000
++#define  EPCR_TBI_MODE		0x2000
++#define  EPCR_RTBI_MODE		0x3000
++
++static int cis8201_init(struct mii_phy *phy)
+ {
+-	u16 lpa;
++	int epcr;
+ 
+-	if (phy->autoneg) {
+-		lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
++	epcr = phy_read(phy, MII_CIS8201_EPCR);
++	if (epcr < 0)
++		return epcr;
+ 
+-		phy->speed = SPEED_10;
+-		phy->duplex = DUPLEX_HALF;
+-		phy->pause = 0;
++	epcr &= ~EPCR_MODE_MASK;
+ 
+-		if (lpa & (LPA_100FULL | LPA_100HALF)) {
+-			phy->speed = SPEED_100;
+-			if (lpa & LPA_100FULL)
+-				phy->duplex = DUPLEX_FULL;
+-		} else if (lpa & LPA_10FULL)
+-			phy->duplex = DUPLEX_FULL;
++	switch (phy->mode) {
++	case PHY_MODE_TBI:
++		epcr |= EPCR_TBI_MODE;
++		break;
++	case PHY_MODE_RTBI:
++		epcr |= EPCR_RTBI_MODE;
++		break;
++	case PHY_MODE_GMII:
++		epcr |= EPCR_GMII_MODE;
++		break;
++	case PHY_MODE_RGMII:
++	default:
++		epcr |= EPCR_RGMII_MODE;
+ 	}
+-	/* On non-aneg, we assume what we put in BMCR is the speed,
+-	 * though magic-aneg shouldn't prevent this case from occurring
+-	 */
++
++	phy_write(phy, MII_CIS8201_EPCR, epcr);
+ 
+ 	return 0;
+ }
+ 
+-#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)
+-
+-/* CIS8201 phy ops */
+ static struct mii_phy_ops cis8201_phy_ops = {
+-	init:cis8201_init,
+-	setup_aneg:genmii_setup_aneg,
+-	setup_forced:genmii_setup_forced,
+-	poll_link:genmii_poll_link,
+-	read_link:cis8201_read_link
+-};
+-
+-/* Generic implementation for most 10/100 PHYs */
+-static struct mii_phy_ops generic_phy_ops = {
+-	setup_aneg:genmii_setup_aneg,
+-	setup_forced:genmii_setup_forced,
+-	poll_link:genmii_poll_link,
+-	read_link:genmii_read_link
++	.init		= cis8201_init,
++	.setup_aneg	= genmii_setup_aneg,
++	.setup_forced	= genmii_setup_forced,
++	.poll_link	= genmii_poll_link,
++	.read_link	= genmii_read_link
+ };
+ 
+ static struct mii_phy_def cis8201_phy_def = {
+-	phy_id:0x000fc410,
+-	phy_id_mask:0x000ffff0,
+-	name:"CIS8201 Gigabit Ethernet",
+-	features:MII_GBIT_FEATURES,
+-	magic_aneg:0,
+-	ops:&cis8201_phy_ops
+-};
+-
+-static struct mii_phy_def genmii_phy_def = {
+-	phy_id:0x00000000,
+-	phy_id_mask:0x00000000,
+-	name:"Generic MII",
+-	features:MII_BASIC_FEATURES,
+-	magic_aneg:0,
+-	ops:&generic_phy_ops
++	.phy_id		= 0x000fc410,
++	.phy_id_mask	= 0x000ffff0,
++	.name		= "CIS8201 Gigabit Ethernet",
++	.ops		= &cis8201_phy_ops
+ };
+ 
+ static struct mii_phy_def *mii_phy_table[] = {
+@@ -258,39 +294,60 @@ static struct mii_phy_def *mii_phy_table
+ 	NULL
+ };
+ 
+-int mii_phy_probe(struct mii_phy *phy, int mii_id)
++int mii_phy_probe(struct mii_phy *phy, int address)
+ {
+-	int rc;
+-	u32 id;
+ 	struct mii_phy_def *def;
+ 	int i;
++	u32 id;
+ 
+-	phy->autoneg = 0;
++	phy->autoneg = AUTONEG_DISABLE;
+ 	phy->advertising = 0;
+-	phy->mii_id = mii_id;
+-	phy->speed = 0;
+-	phy->duplex = 0;
+-	phy->pause = 0;
+-
+-	/* Take PHY out of isloate mode and reset it. */
+-	rc = reset_one_mii_phy(phy, mii_id);
+-	if (rc)
++	phy->address = address;
++	phy->speed = SPEED_10;
++	phy->duplex = DUPLEX_HALF;
++	phy->pause = phy->asym_pause = 0;
++
++	/* Take PHY out of isolate mode and reset it. */
++	if (mii_reset_phy(phy))
+ 		return -ENODEV;
+ 
+ 	/* Read ID and find matching entry */
+-	id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2))
+-	    & 0xfffffff0;
++	id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
+ 	for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
+ 		if ((id & def->phy_id_mask) == def->phy_id)
+ 			break;
+ 	/* Should never be NULL (we have a generic entry), but... */
+-	if (def == NULL)
++	if (!def)
+ 		return -ENODEV;
+ 
+ 	phy->def = def;
+ 
++	/* Determine PHY features if needed */
++	phy->features = def->features;
++	if (!phy->features) {
++		u16 bmsr = phy_read(phy, MII_BMSR);
++		if (bmsr & BMSR_ANEGCAPABLE)
++			phy->features |= SUPPORTED_Autoneg;
++		if (bmsr & BMSR_10HALF)
++			phy->features |= SUPPORTED_10baseT_Half;
++		if (bmsr & BMSR_10FULL)
++			phy->features |= SUPPORTED_10baseT_Full;
++		if (bmsr & BMSR_100HALF)
++			phy->features |= SUPPORTED_100baseT_Half;
++		if (bmsr & BMSR_100FULL)
++			phy->features |= SUPPORTED_100baseT_Full;
++		if (bmsr & BMSR_ESTATEN) {
++			u16 esr = phy_read(phy, MII_ESTATUS);
++			if (esr & ESTATUS_1000_TFULL)
++				phy->features |= SUPPORTED_1000baseT_Full;
++			if (esr & ESTATUS_1000_THALF)
++				phy->features |= SUPPORTED_1000baseT_Half;
++		}
++		phy->features |= SUPPORTED_MII;
++	}
++
+ 	/* Setup default advertising */
+-	phy->advertising = def->features;
++	phy->advertising = phy->features;
+ 
+ 	return 0;
+ }
+diff --git a/drivers/net/ibm_emac/ibm_emac_phy.h b/drivers/net/ibm_emac/ibm_emac_phy.h
+--- a/drivers/net/ibm_emac/ibm_emac_phy.h
++++ b/drivers/net/ibm_emac/ibm_emac_phy.h
+@@ -1,65 +1,25 @@
+-
+ /*
+- * ibm_emac_phy.h
+- *
++ * drivers/net/ibm_emac/ibm_emac_phy.h
+  *
+- *      Benjamin Herrenschmidt <benh at kernel.crashing.org>
+- *      February 2003
+- *
+- * This program is free software; you can redistribute  it and/or modify it
+- *  under  the terms of  the GNU General  Public License as published by the
+- *  Free Software Foundation;  either version 2 of the  License, or (at your
+- *  option) any later version.
++ * Driver for PowerPC 4xx on-chip ethernet controller, PHY support
+  *
+- *  THIS  SOFTWARE  IS PROVIDED   ``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 AUTHOR  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.
++ * Benjamin Herrenschmidt <benh at kernel.crashing.org>
++ * February 2003
+  *
+- *  You 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.
++ * Minor additions by Eugene Surovegin <ebs at ebshome.net>, 2004
+  *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the 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 file basically duplicates sungem_phy.{c,h} with different PHYs
+  * supported. I'm looking into merging that in a single mii layer more
+  * flexible than mii.c 
+  */
+ 
+-#ifndef _IBM_EMAC_PHY_H_
+-#define _IBM_EMAC_PHY_H_
+-
+-/*
+- * PHY mode settings
+- * Used for multi-mode capable PHYs
+- */
+-#define PHY_MODE_NA	0
+-#define PHY_MODE_MII	1
+-#define PHY_MODE_RMII	2
+-#define PHY_MODE_SMII	3
+-#define PHY_MODE_RGMII	4
+-#define PHY_MODE_TBI	5
+-#define PHY_MODE_GMII	6
+-#define PHY_MODE_RTBI	7
+-#define PHY_MODE_SGMII	8
+-
+-/*
+- * PHY specific registers/values
+- */
+-
+-/* CIS8201 */
+-#define MII_CIS8201_EPCR	0x17
+-#define EPCR_MODE_MASK		0x3000
+-#define EPCR_GMII_MODE		0x0000
+-#define EPCR_RGMII_MODE		0x1000
+-#define EPCR_TBI_MODE		0x2000
+-#define EPCR_RTBI_MODE		0x3000
++#ifndef _IBM_OCP_PHY_H_
++#define _IBM_OCP_PHY_H_
+ 
+ struct mii_phy;
+ 
+@@ -77,7 +37,8 @@ struct mii_phy_ops {
+ struct mii_phy_def {
+ 	u32 phy_id;		/* Concatenated ID1 << 16 | ID2 */
+ 	u32 phy_id_mask;	/* Significant bits */
+-	u32 features;		/* Ethtool SUPPORTED_* defines */
++	u32 features;		/* Ethtool SUPPORTED_* defines or 
++				   0 for autodetect */
+ 	int magic_aneg;		/* Autoneg does all speed test for us */
+ 	const char *name;
+ 	const struct mii_phy_ops *ops;
+@@ -86,8 +47,11 @@ struct mii_phy_def {
+ /* An instance of a PHY, partially borrowed from mii_if_info */
+ struct mii_phy {
+ 	struct mii_phy_def *def;
+-	int advertising;
+-	int mii_id;
++	u32 advertising;	/* Ethtool ADVERTISED_* defines */
++	u32 features;		/* Copied from mii_phy_def.features 
++				   or determined automaticaly */
++	int address;		/* PHY address */
++	int mode;		/* PHY mode */
+ 
+ 	/* 1: autoneg enabled, 0: disabled */
+ 	int autoneg;
+@@ -98,40 +62,19 @@ struct mii_phy {
+ 	int speed;
+ 	int duplex;
+ 	int pause;
+-
+-	/* PHY mode - if needed */
+-	int mode;
++	int asym_pause;
+ 
+ 	/* Provided by host chip */
+ 	struct net_device *dev;
+-	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 (*mdio_read) (struct net_device * dev, int addr, int reg);
++	void (*mdio_write) (struct net_device * dev, int addr, int reg,
+ 			    int val);
+ };
+ 
+ /* Pass in a struct mii_phy with dev, mdio_read and mdio_write
+  * filled, the remaining fields will be filled on return
+  */
+-extern int mii_phy_probe(struct mii_phy *phy, int mii_id);
+-
+-static inline int __phy_read(struct mii_phy *phy, int id, int reg)
+-{
+-	return phy->mdio_read(phy->dev, id, reg);
+-}
+-
+-static inline void __phy_write(struct mii_phy *phy, int id, int reg, int val)
+-{
+-	phy->mdio_write(phy->dev, id, reg, val);
+-}
+-
+-static inline int phy_read(struct mii_phy *phy, int reg)
+-{
+-	return phy->mdio_read(phy->dev, phy->mii_id, reg);
+-}
+-
+-static inline void phy_write(struct mii_phy *phy, int reg, int val)
+-{
+-	phy->mdio_write(phy->dev, phy->mii_id, reg, val);
+-}
++int mii_phy_probe(struct mii_phy *phy, int address);
++int mii_reset_phy(struct mii_phy *phy);
+ 
+-#endif				/* _IBM_EMAC_PHY_H_ */
++#endif				/* _IBM_OCP_PHY_H_ */
+diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.c b/drivers/net/ibm_emac/ibm_emac_rgmii.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/ibm_emac/ibm_emac_rgmii.c
+@@ -0,0 +1,201 @@
++/*
++ * drivers/net/ibm_emac/ibm_emac_rgmii.c
++ *
++ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
++ *
++ * Copyright (c) 2004, 2005 Zultys Technologies.
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
++ *
++ * Based on original work by
++ * 	Matt Porter <mporter at kernel.crashing.org>
++ * 	Copyright 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 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/ethtool.h>
++#include <asm/io.h>
++
++#include "ibm_emac_core.h"
++#include "ibm_emac_debug.h"
++
++/* RGMIIx_FER */
++#define RGMII_FER_MASK(idx)	(0x7 << ((idx) * 4))
++#define RGMII_FER_RTBI(idx)	(0x4 << ((idx) * 4))
++#define RGMII_FER_RGMII(idx)	(0x5 << ((idx) * 4))
++#define RGMII_FER_TBI(idx)	(0x6 << ((idx) * 4))
++#define RGMII_FER_GMII(idx)	(0x7 << ((idx) * 4))
++
++/* RGMIIx_SSR */
++#define RGMII_SSR_MASK(idx)	(0x7 << ((idx) * 8))
++#define RGMII_SSR_100(idx)	(0x2 << ((idx) * 8))
++#define RGMII_SSR_1000(idx)	(0x4 << ((idx) * 8))
++
++/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
++static inline int rgmii_valid_mode(int phy_mode)
++{
++	return  phy_mode == PHY_MODE_GMII ||
++		phy_mode == PHY_MODE_RGMII ||
++		phy_mode == PHY_MODE_TBI ||
++		phy_mode == PHY_MODE_RTBI;
++}
++
++static inline const char *rgmii_mode_name(int mode)
++{
++	switch (mode) {
++	case PHY_MODE_RGMII:
++		return "RGMII";
++	case PHY_MODE_TBI:
++		return "TBI";
++	case PHY_MODE_GMII:
++		return "GMII";
++	case PHY_MODE_RTBI:
++		return "RTBI";
++	default:
++		BUG();
++	}
++}
++
++static inline u32 rgmii_mode_mask(int mode, int input)
++{
++	switch (mode) {
++	case PHY_MODE_RGMII:
++		return RGMII_FER_RGMII(input);
++	case PHY_MODE_TBI:
++		return RGMII_FER_TBI(input);
++	case PHY_MODE_GMII:
++		return RGMII_FER_GMII(input);
++	case PHY_MODE_RTBI:
++		return RGMII_FER_RTBI(input);
++	default:
++		BUG();
++	}
++}
++
++static int __init rgmii_init(struct ocp_device *ocpdev, int input, int mode)
++{
++	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
++	struct rgmii_regs *p;
++
++	RGMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, mode);
++
++	if (!dev) {
++		dev = kzalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL);
++		if (!dev) {
++			printk(KERN_ERR
++			       "rgmii%d: couldn't allocate device structure!\n",
++			       ocpdev->def->index);
++			return -ENOMEM;
++		}
++
++		p = (struct rgmii_regs *)ioremap(ocpdev->def->paddr,
++						 sizeof(struct rgmii_regs));
++		if (!p) {
++			printk(KERN_ERR
++			       "rgmii%d: could not ioremap device registers!\n",
++			       ocpdev->def->index);
++			kfree(dev);
++			return -ENOMEM;
++		}
++
++		dev->base = p;
++		ocp_set_drvdata(ocpdev, dev);
++
++		/* Disable all inputs by default */
++		out_be32(&p->fer, 0);
++	} else
++		p = dev->base;
++
++	/* Enable this input */
++	out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input));
++
++	printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n",
++	       ocpdev->def->index, input, rgmii_mode_name(mode));
++
++	++dev->users;
++	return 0;
++}
++
++int __init rgmii_attach(void *emac)
++{
++	struct ocp_enet_private *dev = emac;
++	struct ocp_func_emac_data *emacdata = dev->def->additions;
++
++	/* Check if we need to attach to a RGMII */
++	if (emacdata->rgmii_idx >= 0 && rgmii_valid_mode(emacdata->phy_mode)) {
++		dev->rgmii_input = emacdata->rgmii_mux;
++		dev->rgmii_dev =
++		    ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_RGMII,
++				    emacdata->rgmii_idx);
++		if (!dev->rgmii_dev) {
++			printk(KERN_ERR "emac%d: unknown rgmii%d!\n",
++			       dev->def->index, emacdata->rgmii_idx);
++			return -ENODEV;
++		}
++		if (rgmii_init
++		    (dev->rgmii_dev, dev->rgmii_input, emacdata->phy_mode)) {
++			printk(KERN_ERR
++			       "emac%d: rgmii%d initialization failed!\n",
++			       dev->def->index, emacdata->rgmii_idx);
++			return -ENODEV;
++		}
++	}
++	return 0;
++}
++
++void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
++{
++	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
++	u32 ssr = in_be32(&dev->base->ssr) & ~RGMII_SSR_MASK(input);
++
++	RGMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed);
++
++	if (speed == SPEED_1000)
++		ssr |= RGMII_SSR_1000(input);
++	else if (speed == SPEED_100)
++		ssr |= RGMII_SSR_100(input);
++
++	out_be32(&dev->base->ssr, ssr);
++}
++
++void __exit __rgmii_fini(struct ocp_device *ocpdev, int input)
++{
++	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
++	BUG_ON(!dev || dev->users == 0);
++
++	RGMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);
++
++	/* Disable this input */
++	out_be32(&dev->base->fer,
++		 in_be32(&dev->base->fer) & ~RGMII_FER_MASK(input));
++
++	if (!--dev->users) {
++		/* Free everything if this is the last user */
++		ocp_set_drvdata(ocpdev, NULL);
++		iounmap((void *)dev->base);
++		kfree(dev);
++	}
++}
++
++int __rgmii_get_regs_len(struct ocp_device *ocpdev)
++{
++	return sizeof(struct emac_ethtool_regs_subhdr) +
++	    sizeof(struct rgmii_regs);
++}
++
++void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf)
++{
++	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
++	struct emac_ethtool_regs_subhdr *hdr = buf;
++	struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1);
++
++	hdr->version = 0;
++	hdr->index = ocpdev->def->index;
++	memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs));
++	return regs + 1;
++}
+diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h
+--- a/drivers/net/ibm_emac/ibm_emac_rgmii.h
++++ b/drivers/net/ibm_emac/ibm_emac_rgmii.h
+@@ -1,5 +1,7 @@
+ /*
+- * Defines for the IBM RGMII bridge
++ * drivers/net/ibm_emac/ibm_emac_rgmii.c
++ *
++ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
+  *
+  * Based on ocp_zmii.h/ibm_emac_zmii.h
+  * Armin Kuster akuster at mvista.com
+@@ -7,6 +9,9 @@
+  * Copyright 2004 MontaVista Software, Inc.
+  * Matt Porter <mporter at kernel.crashing.org>
+  *
++ * Copyright (c) 2004, 2005 Zultys Technologies.
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.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
+@@ -19,47 +24,42 @@
+ #include <linux/config.h>
+ 
+ /* RGMII bridge */
+-typedef struct rgmii_regs {
++struct rgmii_regs {
+ 	u32 fer;		/* Function enable register */
+ 	u32 ssr;		/* Speed select register */
+-} rgmii_t;
+-
+-#define RGMII_INPUTS			4
++};
+ 
+ /* RGMII device */
+ struct ibm_ocp_rgmii {
+ 	struct rgmii_regs *base;
+-	int mode[RGMII_INPUTS];
+ 	int users;		/* number of EMACs using this RGMII bridge */
+ };
+ 
+-/* Fuctional Enable Reg */
+-#define RGMII_FER_MASK(x)		(0x00000007 << (4*x))
+-#define RGMII_RTBI			0x00000004
+-#define RGMII_RGMII			0x00000005
+-#define RGMII_TBI  			0x00000006
+-#define RGMII_GMII 			0x00000007
+-
+-/* Speed Selection reg */
+-
+-#define RGMII_SP2_100	0x00000002
+-#define RGMII_SP2_1000	0x00000004
+-#define RGMII_SP3_100	0x00000200
+-#define RGMII_SP3_1000	0x00000400
+-
+-#define RGMII_MII2_SPDMASK	 0x00000007
+-#define RGMII_MII3_SPDMASK	 0x00000700
+-
+-#define RGMII_MII2_100MB	 RGMII_SP2_100 & ~RGMII_SP2_1000
+-#define RGMII_MII2_1000MB 	 RGMII_SP2_1000 & ~RGMII_SP2_100
+-#define RGMII_MII2_10MB		 ~(RGMII_SP2_100 | RGMII_SP2_1000)
+-#define RGMII_MII3_100MB	 RGMII_SP3_100 & ~RGMII_SP3_1000
+-#define RGMII_MII3_1000MB 	 RGMII_SP3_1000 & ~RGMII_SP3_100
+-#define RGMII_MII3_10MB		 ~(RGMII_SP3_100 | RGMII_SP3_1000)
+-
+-#define RTBI		0
+-#define RGMII		1
+-#define TBI		2
+-#define GMII		3
++#ifdef CONFIG_IBM_EMAC_RGMII
++int rgmii_attach(void *emac) __init;
++
++void __rgmii_fini(struct ocp_device *ocpdev, int input) __exit;
++static inline void rgmii_fini(struct ocp_device *ocpdev, int input)
++{
++	if (ocpdev)
++		__rgmii_fini(ocpdev, input);
++}
++
++void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed);
++
++int __rgmii_get_regs_len(struct ocp_device *ocpdev);
++static inline int rgmii_get_regs_len(struct ocp_device *ocpdev)
++{
++	return ocpdev ? __rgmii_get_regs_len(ocpdev) : 0;
++}
++
++void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf);
++#else
++# define rgmii_attach(x)	0
++# define rgmii_fini(x,y)	((void)0)
++# define rgmii_set_speed(x,y,z)	((void)0)
++# define rgmii_get_regs_len(x)	0
++# define rgmii_dump_regs(x,buf)	(buf)
++#endif				/* !CONFIG_IBM_EMAC_RGMII */
+ 
+ #endif				/* _IBM_EMAC_RGMII_H_ */
+diff --git a/drivers/net/ibm_emac/ibm_emac_tah.c b/drivers/net/ibm_emac/ibm_emac_tah.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/ibm_emac/ibm_emac_tah.c
+@@ -0,0 +1,111 @@
++/*
++ * drivers/net/ibm_emac/ibm_emac_tah.c
++ *
++ * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
++ *
++ * Copyright 2004 MontaVista Software, Inc.
++ * Matt Porter <mporter at kernel.crashing.org>
++ *
++ * Copyright (c) 2005 Eugene Surovegin <ebs at ebshome.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/config.h>
++#include <asm/io.h>
++
++#include "ibm_emac_core.h"
++
++static int __init tah_init(struct ocp_device *ocpdev)
++{
++	struct tah_regs *p;
++
++	if (ocp_get_drvdata(ocpdev)) {
++		printk(KERN_ERR "tah%d: already in use!\n", ocpdev->def->index);
++		return -EBUSY;
++	}
++
++	/* Initialize TAH and enable IPv4 checksum verification, no TSO yet */
++	p = (struct tah_regs *)ioremap(ocpdev->def->paddr, sizeof(*p));
++	if (!p) {
++		printk(KERN_ERR "tah%d: could not ioremap device registers!\n",
++		       ocpdev->def->index);
++		return -ENOMEM;
++	}
++	ocp_set_drvdata(ocpdev, p);
++	__tah_reset(ocpdev);
++
++	return 0;
++}
++
++int __init tah_attach(void *emac)
++{
++	struct ocp_enet_private *dev = emac;
++	struct ocp_func_emac_data *emacdata = dev->def->additions;
++
++	/* Check if we need to attach to a TAH */
++	if (emacdata->tah_idx >= 0) {
++		dev->tah_dev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_TAH,
++					       emacdata->tah_idx);
++		if (!dev->tah_dev) {
++			printk(KERN_ERR "emac%d: unknown tah%d!\n",
++			       dev->def->index, emacdata->tah_idx);
++			return -ENODEV;
++		}
++		if (tah_init(dev->tah_dev)) {
++			printk(KERN_ERR
++			       "emac%d: tah%d initialization failed!\n",
++			       dev->def->index, emacdata->tah_idx);
++			return -ENODEV;
++		}
++	}
++	return 0;
++}
++
++void __exit __tah_fini(struct ocp_device *ocpdev)
++{
++	struct tah_regs *p = ocp_get_drvdata(ocpdev);
++	BUG_ON(!p);
++	ocp_set_drvdata(ocpdev, NULL);
++	iounmap((void *)p);
++}
++
++void __tah_reset(struct ocp_device *ocpdev)
++{
++	struct tah_regs *p = ocp_get_drvdata(ocpdev);
++	int n;
++
++	/* Reset TAH */
++	out_be32(&p->mr, TAH_MR_SR);
++	n = 100;
++	while ((in_be32(&p->mr) & TAH_MR_SR) && n)
++		--n;
++
++	if (unlikely(!n))
++		printk(KERN_ERR "tah%d: reset timeout\n", ocpdev->def->index);
++
++	/* 10KB TAH TX FIFO accomodates the max MTU of 9000 */
++	out_be32(&p->mr,
++		 TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
++		 TAH_MR_DIG);
++}
++
++int __tah_get_regs_len(struct ocp_device *ocpdev)
++{
++	return sizeof(struct emac_ethtool_regs_subhdr) +
++	    sizeof(struct tah_regs);
++}
++
++void *tah_dump_regs(struct ocp_device *ocpdev, void *buf)
++{
++	struct tah_regs *dev = ocp_get_drvdata(ocpdev);
++	struct emac_ethtool_regs_subhdr *hdr = buf;
++	struct tah_regs *regs = (struct tah_regs *)(hdr + 1);
++
++	hdr->version = 0;
++	hdr->index = ocpdev->def->index;
++	memcpy_fromio(regs, dev, sizeof(struct tah_regs));
++	return regs + 1;
++}
+diff --git a/drivers/net/ibm_emac/ibm_emac_tah.h b/drivers/net/ibm_emac/ibm_emac_tah.h
+--- a/drivers/net/ibm_emac/ibm_emac_tah.h
++++ b/drivers/net/ibm_emac/ibm_emac_tah.h
+@@ -1,9 +1,13 @@
+ /*
+- * Defines for the IBM TAH
++ * drivers/net/ibm_emac/ibm_emac_tah.h
++ *
++ * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
+  *
+  * Copyright 2004 MontaVista Software, Inc.
+  * Matt Porter <mporter at kernel.crashing.org>
+  *
++ * Copyright (c) 2005 Eugene Surovegin <ebs at ebshome.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
+@@ -13,36 +17,72 @@
+ #ifndef _IBM_EMAC_TAH_H
+ #define _IBM_EMAC_TAH_H
+ 
++#include <linux/config.h>
++#include <linux/init.h>
++#include <asm/ocp.h>
++
+ /* TAH */
+-typedef struct tah_regs {
+-	u32 tah_revid;
++struct tah_regs {
++	u32 revid;
+ 	u32 pad[3];
+-	u32 tah_mr;
+-	u32 tah_ssr0;
+-	u32 tah_ssr1;
+-	u32 tah_ssr2;
+-	u32 tah_ssr3;
+-	u32 tah_ssr4;
+-	u32 tah_ssr5;
+-	u32 tah_tsr;
+-} tah_t;
++	u32 mr;
++	u32 ssr0;
++	u32 ssr1;
++	u32 ssr2;
++	u32 ssr3;
++	u32 ssr4;
++	u32 ssr5;
++	u32 tsr;
++};
+ 
+ /* TAH engine */
+-#define TAH_MR_CVR			0x80000000
+-#define TAH_MR_SR			0x40000000
+-#define TAH_MR_ST_256			0x01000000
+-#define TAH_MR_ST_512			0x02000000
+-#define TAH_MR_ST_768			0x03000000
+-#define TAH_MR_ST_1024			0x04000000
+-#define TAH_MR_ST_1280			0x05000000
+-#define TAH_MR_ST_1536			0x06000000
+-#define TAH_MR_TFS_16KB			0x00000000
+-#define TAH_MR_TFS_2KB			0x00200000
+-#define TAH_MR_TFS_4KB			0x00400000
+-#define TAH_MR_TFS_6KB			0x00600000
+-#define TAH_MR_TFS_8KB			0x00800000
+-#define TAH_MR_TFS_10KB			0x00a00000
+-#define TAH_MR_DTFP			0x00100000
+-#define TAH_MR_DIG			0x00080000
++#define TAH_MR_CVR		0x80000000
++#define TAH_MR_SR		0x40000000
++#define TAH_MR_ST_256		0x01000000
++#define TAH_MR_ST_512		0x02000000
++#define TAH_MR_ST_768		0x03000000
++#define TAH_MR_ST_1024		0x04000000
++#define TAH_MR_ST_1280		0x05000000
++#define TAH_MR_ST_1536		0x06000000
++#define TAH_MR_TFS_16KB		0x00000000
++#define TAH_MR_TFS_2KB		0x00200000
++#define TAH_MR_TFS_4KB		0x00400000
++#define TAH_MR_TFS_6KB		0x00600000
++#define TAH_MR_TFS_8KB		0x00800000
++#define TAH_MR_TFS_10KB		0x00a00000
++#define TAH_MR_DTFP		0x00100000
++#define TAH_MR_DIG		0x00080000
++
++#ifdef CONFIG_IBM_EMAC_TAH
++int tah_attach(void *emac) __init;
++
++void __tah_fini(struct ocp_device *ocpdev) __exit;
++static inline void tah_fini(struct ocp_device *ocpdev)
++{
++	if (ocpdev)
++		__tah_fini(ocpdev);
++}
++
++void __tah_reset(struct ocp_device *ocpdev);
++static inline void tah_reset(struct ocp_device *ocpdev)
++{
++	if (ocpdev)
++		__tah_reset(ocpdev);
++}
++
++int __tah_get_regs_len(struct ocp_device *ocpdev);
++static inline int tah_get_regs_len(struct ocp_device *ocpdev)
++{
++	return ocpdev ? __tah_get_regs_len(ocpdev) : 0;
++}
++
++void *tah_dump_regs(struct ocp_device *ocpdev, void *buf);
++#else
++# define tah_attach(x)		0
++# define tah_fini(x)		((void)0)
++# define tah_reset(x)		((void)0)
++# define tah_get_regs_len(x)	0
++# define tah_dump_regs(x,buf)	(buf)
++#endif				/* !CONFIG_IBM_EMAC_TAH */
+ 
+ #endif				/* _IBM_EMAC_TAH_H */
+diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.c b/drivers/net/ibm_emac/ibm_emac_zmii.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/ibm_emac/ibm_emac_zmii.c
+@@ -0,0 +1,255 @@
++/*
++ * drivers/net/ibm_emac/ibm_emac_zmii.c
++ *
++ * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
++ *
++ * Copyright (c) 2004, 2005 Zultys Technologies.
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
++ *
++ * Based on original work by
++ *      Armin Kuster <akuster at mvista.com>
++ * 	Copyright 2001 MontaVista Softare 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/config.h>
++#include <linux/kernel.h>
++#include <linux/ethtool.h>
++#include <asm/io.h>
++
++#include "ibm_emac_core.h"
++#include "ibm_emac_debug.h"
++
++/* ZMIIx_FER */
++#define ZMII_FER_MDI(idx)	(0x80000000 >> ((idx) * 4))
++#define ZMII_FER_MDI_ALL	(ZMII_FER_MDI(0) | ZMII_FER_MDI(1) | \
++				 ZMII_FER_MDI(2) | ZMII_FER_MDI(3))
++
++#define ZMII_FER_SMII(idx)	(0x40000000 >> ((idx) * 4))
++#define ZMII_FER_RMII(idx)	(0x20000000 >> ((idx) * 4))
++#define ZMII_FER_MII(idx)	(0x10000000 >> ((idx) * 4))
++
++/* ZMIIx_SSR */
++#define ZMII_SSR_SCI(idx)	(0x40000000 >> ((idx) * 4))
++#define ZMII_SSR_FSS(idx)	(0x20000000 >> ((idx) * 4))
++#define ZMII_SSR_SP(idx)	(0x10000000 >> ((idx) * 4))
++
++/* ZMII only supports MII, RMII and SMII 
++ * we also support autodetection for backward compatibility
++ */
++static inline int zmii_valid_mode(int mode)
++{
++	return  mode == PHY_MODE_MII ||
++		mode == PHY_MODE_RMII ||
++		mode == PHY_MODE_SMII ||
++		mode == PHY_MODE_NA;
++}
++
++static inline const char *zmii_mode_name(int mode)
++{
++	switch (mode) {
++	case PHY_MODE_MII:
++		return "MII";
++	case PHY_MODE_RMII:
++		return "RMII";
++	case PHY_MODE_SMII:
++		return "SMII";
++	default:
++		BUG();
++	}
++}
++
++static inline u32 zmii_mode_mask(int mode, int input)
++{
++	switch (mode) {
++	case PHY_MODE_MII:
++		return ZMII_FER_MII(input);
++	case PHY_MODE_RMII:
++		return ZMII_FER_RMII(input);
++	case PHY_MODE_SMII:
++		return ZMII_FER_SMII(input);
++	default:
++		return 0;
++	}
++}
++
++static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode)
++{
++	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
++	struct zmii_regs *p;
++
++	ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode);
++
++	if (!dev) {
++		dev = kzalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL);
++		if (!dev) {
++			printk(KERN_ERR
++			       "zmii%d: couldn't allocate device structure!\n",
++			       ocpdev->def->index);
++			return -ENOMEM;
++		}
++		dev->mode = PHY_MODE_NA;
++
++		p = (struct zmii_regs *)ioremap(ocpdev->def->paddr,
++						sizeof(struct zmii_regs));
++		if (!p) {
++			printk(KERN_ERR
++			       "zmii%d: could not ioremap device registers!\n",
++			       ocpdev->def->index);
++			kfree(dev);
++			return -ENOMEM;
++		}
++		dev->base = p;
++		ocp_set_drvdata(ocpdev, dev);
++		
++		/* We may need FER value for autodetection later */
++		dev->fer_save = in_be32(&p->fer);
++
++		/* Disable all inputs by default */
++		out_be32(&p->fer, 0);
++	} else
++		p = dev->base;
++
++	if (!zmii_valid_mode(*mode)) {
++		/* Probably an EMAC connected to RGMII, 
++		 * but it still may need ZMII for MDIO 
++		 */
++		goto out;
++	}
++
++	/* Autodetect ZMII mode if not specified.
++	 * This is only for backward compatibility with the old driver.
++	 * Please, always specify PHY mode in your board port to avoid
++	 * any surprises.
++	 */
++	if (dev->mode == PHY_MODE_NA) {
++		if (*mode == PHY_MODE_NA) {
++			u32 r = dev->fer_save;
++
++			ZMII_DBG("%d: autodetecting mode, FER = 0x%08x" NL,
++				 ocpdev->def->index, r);
++			
++			if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))
++				dev->mode = PHY_MODE_MII;
++			else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))
++				dev->mode = PHY_MODE_RMII;
++			else
++				dev->mode = PHY_MODE_SMII;
++		} else
++			dev->mode = *mode;
++
++		printk(KERN_NOTICE "zmii%d: bridge in %s mode\n",
++		       ocpdev->def->index, zmii_mode_name(dev->mode));
++	} else {
++		/* All inputs must use the same mode */
++		if (*mode != PHY_MODE_NA && *mode != dev->mode) {
++			printk(KERN_ERR
++			       "zmii%d: invalid mode %d specified for input %d\n",
++			       ocpdev->def->index, *mode, input);
++			return -EINVAL;
++		}
++	}
++
++	/* Report back correct PHY mode, 
++	 * it may be used during PHY initialization.
++	 */
++	*mode = dev->mode;
++
++	/* Enable this input */
++	out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input));
++      out:
++	++dev->users;
++	return 0;
++}
++
++int __init zmii_attach(void *emac)
++{
++	struct ocp_enet_private *dev = emac;
++	struct ocp_func_emac_data *emacdata = dev->def->additions;
++
++	if (emacdata->zmii_idx >= 0) {
++		dev->zmii_input = emacdata->zmii_mux;
++		dev->zmii_dev =
++		    ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_ZMII,
++				    emacdata->zmii_idx);
++		if (!dev->zmii_dev) {
++			printk(KERN_ERR "emac%d: unknown zmii%d!\n",
++			       dev->def->index, emacdata->zmii_idx);
++			return -ENODEV;
++		}
++		if (zmii_init
++		    (dev->zmii_dev, dev->zmii_input, &emacdata->phy_mode)) {
++			printk(KERN_ERR
++			       "emac%d: zmii%d initialization failed!\n",
++			       dev->def->index, emacdata->zmii_idx);
++			return -ENODEV;
++		}
++	}
++	return 0;
++}
++
++void __zmii_enable_mdio(struct ocp_device *ocpdev, int input)
++{
++	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
++	u32 fer = in_be32(&dev->base->fer) & ~ZMII_FER_MDI_ALL;
++
++	ZMII_DBG2("%d: mdio(%d)" NL, ocpdev->def->index, input);
++
++	out_be32(&dev->base->fer, fer | ZMII_FER_MDI(input));
++}
++
++void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
++{
++	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
++	u32 ssr = in_be32(&dev->base->ssr);
++
++	ZMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed);
++
++	if (speed == SPEED_100)
++		ssr |= ZMII_SSR_SP(input);
++	else
++		ssr &= ~ZMII_SSR_SP(input);
++
++	out_be32(&dev->base->ssr, ssr);
++}
++
++void __exit __zmii_fini(struct ocp_device *ocpdev, int input)
++{
++	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
++	BUG_ON(!dev || dev->users == 0);
++
++	ZMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);
++
++	/* Disable this input */
++	out_be32(&dev->base->fer,
++		 in_be32(&dev->base->fer) & ~zmii_mode_mask(dev->mode, input));
++
++	if (!--dev->users) {
++		/* Free everything if this is the last user */
++		ocp_set_drvdata(ocpdev, NULL);
++		iounmap((void *)dev->base);
++		kfree(dev);
++	}
++}
++
++int __zmii_get_regs_len(struct ocp_device *ocpdev)
++{
++	return sizeof(struct emac_ethtool_regs_subhdr) +
++	    sizeof(struct zmii_regs);
++}
++
++void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf)
++{
++	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
++	struct emac_ethtool_regs_subhdr *hdr = buf;
++	struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1);
++
++	hdr->version = 0;
++	hdr->index = ocpdev->def->index;
++	memcpy_fromio(regs, dev->base, sizeof(struct zmii_regs));
++	return regs + 1;
++}
+diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.h b/drivers/net/ibm_emac/ibm_emac_zmii.h
+--- a/drivers/net/ibm_emac/ibm_emac_zmii.h
++++ b/drivers/net/ibm_emac/ibm_emac_zmii.h
+@@ -1,23 +1,27 @@
+ /*
+- * ocp_zmii.h
++ * drivers/net/ibm_emac/ibm_emac_zmii.h
+  *
+- * Defines for the IBM ZMII bridge
++ * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
+  *
+- *      Armin Kuster akuster at mvista.com
+- *      Dec, 2001
++ * Copyright (c) 2004, 2005 Zultys Technologies.
++ * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
+  *
+- * Copyright 2001 MontaVista Softare Inc.
++ * Based on original work by
++ *      Armin Kuster <akuster at mvista.com>
++ * 	Copyright 2001 MontaVista Softare 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 _IBM_EMAC_ZMII_H_
+ #define _IBM_EMAC_ZMII_H_
+ 
+ #include <linux/config.h>
++#include <linux/init.h>
++#include <asm/ocp.h>
+ 
+ /* ZMII bridge registers */
+ struct zmii_regs {
+@@ -26,68 +30,54 @@ struct zmii_regs {
+ 	u32 smiirs;		/* SMII status reg */
+ };
+ 
+-#define ZMII_INPUTS	4
+-
+ /* ZMII device */
+ struct ibm_ocp_zmii {
+ 	struct zmii_regs *base;
+-	int mode[ZMII_INPUTS];
++	int mode;		/* subset of PHY_MODE_XXXX */
+ 	int users;		/* number of EMACs using this ZMII bridge */
++	u32 fer_save;		/* FER value left by firmware */
+ };
+ 
+-/* Fuctional Enable Reg */
+-
+-#define ZMII_FER_MASK(x)	(0xf0000000 >> (4*x))
++#ifdef CONFIG_IBM_EMAC_ZMII
++int zmii_attach(void *emac) __init;
+ 
+-#define ZMII_MDI0	0x80000000
+-#define ZMII_SMII0	0x40000000
+-#define ZMII_RMII0	0x20000000
+-#define ZMII_MII0	0x10000000
+-#define ZMII_MDI1	0x08000000
+-#define ZMII_SMII1	0x04000000
+-#define ZMII_RMII1	0x02000000
+-#define ZMII_MII1	0x01000000
+-#define ZMII_MDI2	0x00800000
+-#define ZMII_SMII2	0x00400000
+-#define ZMII_RMII2	0x00200000
+-#define ZMII_MII2	0x00100000
+-#define ZMII_MDI3	0x00080000
+-#define ZMII_SMII3	0x00040000
+-#define ZMII_RMII3	0x00020000
+-#define ZMII_MII3	0x00010000
+-
+-/* Speed Selection reg */
+-
+-#define ZMII_SCI0	0x40000000
+-#define ZMII_FSS0	0x20000000
+-#define ZMII_SP0	0x10000000
+-#define ZMII_SCI1	0x04000000
+-#define ZMII_FSS1	0x02000000
+-#define ZMII_SP1	0x01000000
+-#define ZMII_SCI2	0x00400000
+-#define ZMII_FSS2	0x00200000
+-#define ZMII_SP2	0x00100000
+-#define ZMII_SCI3	0x00040000
+-#define ZMII_FSS3	0x00020000
+-#define ZMII_SP3	0x00010000
+-
+-#define ZMII_MII0_100MB	ZMII_SP0
+-#define ZMII_MII0_10MB	~ZMII_SP0
+-#define ZMII_MII1_100MB	ZMII_SP1
+-#define ZMII_MII1_10MB	~ZMII_SP1
+-#define ZMII_MII2_100MB	ZMII_SP2
+-#define ZMII_MII2_10MB	~ZMII_SP2
+-#define ZMII_MII3_100MB	ZMII_SP3
+-#define ZMII_MII3_10MB	~ZMII_SP3
+-
+-/* SMII Status reg */
+-
+-#define ZMII_STS0 0xFF000000	/* EMAC0 smii status mask */
+-#define ZMII_STS1 0x00FF0000	/* EMAC1 smii status mask */
+-
+-#define SMII	0
+-#define RMII	1
+-#define MII	2
+-#define MDI	3
++void __zmii_fini(struct ocp_device *ocpdev, int input) __exit;
++static inline void zmii_fini(struct ocp_device *ocpdev, int input)
++{
++	if (ocpdev)
++		__zmii_fini(ocpdev, input);
++}
++
++void __zmii_enable_mdio(struct ocp_device *ocpdev, int input);
++static inline void zmii_enable_mdio(struct ocp_device *ocpdev, int input)
++{
++	if (ocpdev)
++		__zmii_enable_mdio(ocpdev, input);
++}
++
++void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed);
++static inline void zmii_set_speed(struct ocp_device *ocpdev, int input,
++				  int speed)
++{
++	if (ocpdev)
++		__zmii_set_speed(ocpdev, input, speed);
++}
++
++int __zmii_get_regs_len(struct ocp_device *ocpdev);
++static inline int zmii_get_regs_len(struct ocp_device *ocpdev)
++{
++	return ocpdev ? __zmii_get_regs_len(ocpdev) : 0;
++}
++
++void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf);
++
++#else
++# define zmii_attach(x)		0
++# define zmii_fini(x,y)		((void)0)
++# define zmii_enable_mdio(x,y)	((void)0)
++# define zmii_set_speed(x,y,z)	((void)0)
++# define zmii_get_regs_len(x)	0
++# define zmii_dump_regs(x,buf)	(buf)
++#endif				/* !CONFIG_IBM_EMAC_ZMII */
+ 
+ #endif				/* _IBM_EMAC_ZMII_H_ */
+diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
+--- a/drivers/net/ibmveth.c
++++ b/drivers/net/ibmveth.c
+@@ -96,7 +96,7 @@ static void ibmveth_proc_unregister_driv
+ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
+ static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
+ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+-static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*);
++static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter);
+ 
+ #ifdef CONFIG_PROC_FS
+ #define IBMVETH_PROC_DIR "net/ibmveth"
+@@ -181,6 +181,7 @@ static int ibmveth_alloc_buffer_pool(str
+ 	atomic_set(&pool->available, 0);
+ 	pool->producer_index = 0;
+ 	pool->consumer_index = 0;
++	pool->active = 0;
+ 
+ 	return 0;
+ }
+@@ -236,7 +237,7 @@ static void ibmveth_replenish_buffer_poo
+ 		lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc);
+ 		    
+ 		if(lpar_rc != H_Success) {
+-			pool->free_map[free_index] = IBM_VETH_INVALID_MAP;
++			pool->free_map[free_index] = index;
+ 			pool->skbuff[index] = NULL;
+ 			pool->consumer_index--;
+ 			dma_unmap_single(&adapter->vdev->dev,
+@@ -255,37 +256,19 @@ static void ibmveth_replenish_buffer_poo
+ 	atomic_add(buffers_added, &(pool->available));
+ }
+ 
+-/* check if replenishing is needed.  */
+-static inline int ibmveth_is_replenishing_needed(struct ibmveth_adapter *adapter)
+-{
+-	return ((atomic_read(&adapter->rx_buff_pool[0].available) < adapter->rx_buff_pool[0].threshold) ||
+-		(atomic_read(&adapter->rx_buff_pool[1].available) < adapter->rx_buff_pool[1].threshold) ||
+-		(atomic_read(&adapter->rx_buff_pool[2].available) < adapter->rx_buff_pool[2].threshold));
+-}
+-
+-/* kick the replenish tasklet if we need replenishing and it isn't already running */
+-static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter *adapter)
+-{
+-	if(ibmveth_is_replenishing_needed(adapter) &&
+-	   (atomic_dec_if_positive(&adapter->not_replenishing) == 0)) {
+-		schedule_work(&adapter->replenish_task);
+-	}
+-}
+-
+-/* replenish tasklet routine */
++/* replenish routine */
+ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) 
+ {
++	int i;
++
+ 	adapter->replenish_task_cycles++;
+ 
+-	ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[0]);
+-	ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[1]);
+-	ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[2]);
++	for(i = 0; i < IbmVethNumBufferPools; i++)
++		if(adapter->rx_buff_pool[i].active)
++			ibmveth_replenish_buffer_pool(adapter, 
++						     &adapter->rx_buff_pool[i]);
+ 
+ 	adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
+-
+-	atomic_inc(&adapter->not_replenishing);
+-
+-	ibmveth_schedule_replenishing(adapter);
+ }
+ 
+ /* empty and free ana buffer pool - also used to do cleanup in error paths */
+@@ -293,10 +276,8 @@ static void ibmveth_free_buffer_pool(str
+ {
+ 	int i;
+ 
+-	if(pool->free_map) {
+-		kfree(pool->free_map);
+-		pool->free_map  = NULL;
+-	}
++	kfree(pool->free_map);
++	pool->free_map = NULL;
+ 
+ 	if(pool->skbuff && pool->dma_addr) {
+ 		for(i = 0; i < pool->size; ++i) {
+@@ -321,6 +302,7 @@ static void ibmveth_free_buffer_pool(str
+ 		kfree(pool->skbuff);
+ 		pool->skbuff = NULL;
+ 	}
++	pool->active = 0;
+ }
+ 
+ /* remove a buffer from a pool */
+@@ -379,6 +361,12 @@ static void ibmveth_rxq_recycle_buffer(s
+ 	ibmveth_assert(pool < IbmVethNumBufferPools);
+ 	ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
+ 
++	if(!adapter->rx_buff_pool[pool].active) {
++		ibmveth_rxq_harvest_buffer(adapter);
++		ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]);
++		return;
++	}
++
+ 	desc.desc = 0;
+ 	desc.fields.valid = 1;
+ 	desc.fields.length = adapter->rx_buff_pool[pool].buff_size;
+@@ -409,6 +397,8 @@ static inline void ibmveth_rxq_harvest_b
+ 
+ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
+ {
++	int i;
++
+ 	if(adapter->buffer_list_addr != NULL) {
+ 		if(!dma_mapping_error(adapter->buffer_list_dma)) {
+ 			dma_unmap_single(&adapter->vdev->dev,
+@@ -443,26 +433,24 @@ static void ibmveth_cleanup(struct ibmve
+ 		adapter->rx_queue.queue_addr = NULL;
+ 	}
+ 
+-	ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[0]);
+-	ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[1]);
+-	ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[2]);
++	for(i = 0; i<IbmVethNumBufferPools; i++)
++		ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[i]);
+ }
+ 
+ static int ibmveth_open(struct net_device *netdev)
+ {
+ 	struct ibmveth_adapter *adapter = netdev->priv;
+ 	u64 mac_address = 0;
+-	int rxq_entries;
++	int rxq_entries = 1;
+ 	unsigned long lpar_rc;
+ 	int rc;
+ 	union ibmveth_buf_desc rxq_desc;
++	int i;
+ 
+ 	ibmveth_debug_printk("open starting\n");
+ 
+-	rxq_entries =
+-		adapter->rx_buff_pool[0].size +
+-		adapter->rx_buff_pool[1].size +
+-		adapter->rx_buff_pool[2].size + 1;
++	for(i = 0; i<IbmVethNumBufferPools; i++)
++		rxq_entries += adapter->rx_buff_pool[i].size;
+     
+ 	adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
+ 	adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
+@@ -502,14 +490,8 @@ static int ibmveth_open(struct net_devic
+ 	adapter->rx_queue.num_slots = rxq_entries;
+ 	adapter->rx_queue.toggle = 1;
+ 
+-	if(ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[0]) ||
+-	   ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[1]) ||
+-	   ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[2]))
+-	{
+-		ibmveth_error_printk("unable to allocate buffer pools\n");
+-		ibmveth_cleanup(adapter);
+-		return -ENOMEM;
+-	}
++	/* call change_mtu to init the buffer pools based in initial mtu */
++	ibmveth_change_mtu(netdev, netdev->mtu);
+ 
+ 	memcpy(&mac_address, netdev->dev_addr, netdev->addr_len);
+ 	mac_address = mac_address >> 16;
+@@ -532,7 +514,7 @@ static int ibmveth_open(struct net_devic
+ 
+ 	if(lpar_rc != H_Success) {
+ 		ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc);
+-		ibmveth_error_printk("buffer TCE:0x%x filter TCE:0x%x rxq desc:0x%lx MAC:0x%lx\n",
++		ibmveth_error_printk("buffer TCE:0x%lx filter TCE:0x%lx rxq desc:0x%lx MAC:0x%lx\n",
+ 				     adapter->buffer_list_dma,
+ 				     adapter->filter_list_dma,
+ 				     rxq_desc.desc,
+@@ -552,10 +534,10 @@ static int ibmveth_open(struct net_devic
+ 		return rc;
+ 	}
+ 
+-	netif_start_queue(netdev);
++	ibmveth_debug_printk("initial replenish cycle\n");
++	ibmveth_interrupt(netdev->irq, netdev, NULL);
+ 
+-	ibmveth_debug_printk("scheduling initial replenish cycle\n");
+-	ibmveth_schedule_replenishing(adapter);
++	netif_start_queue(netdev);
+ 
+ 	ibmveth_debug_printk("open complete\n");
+ 
+@@ -573,9 +555,6 @@ static int ibmveth_close(struct net_devi
+ 
+ 	free_irq(netdev->irq, netdev);
+ 
+-	cancel_delayed_work(&adapter->replenish_task);
+-	flush_scheduled_work();
+-
+ 	do {
+ 		lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
+ 	} while (H_isLongBusy(lpar_rc) || (lpar_rc == H_Busy));
+@@ -640,12 +619,18 @@ static int ibmveth_start_xmit(struct sk_
+ 	unsigned long lpar_rc;
+ 	int nfrags = 0, curfrag;
+ 	unsigned long correlator;
++	unsigned long flags;
+ 	unsigned int retry_count;
++	unsigned int tx_dropped = 0;
++	unsigned int tx_bytes = 0;
++	unsigned int tx_packets = 0;
++	unsigned int tx_send_failed = 0;
++	unsigned int tx_map_failed = 0;
++
+ 
+ 	if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) {
+-		adapter->stats.tx_dropped++;
+-		dev_kfree_skb(skb);
+-		return 0;
++		tx_dropped++;
++		goto out;
+ 	}
+ 
+ 	memset(&desc, 0, sizeof(desc));
+@@ -664,10 +649,9 @@ static int ibmveth_start_xmit(struct sk_
+ 
+ 	if(dma_mapping_error(desc[0].fields.address)) {
+ 		ibmveth_error_printk("tx: unable to map initial fragment\n");
+-		adapter->tx_map_failed++;
+-		adapter->stats.tx_dropped++;
+-		dev_kfree_skb(skb);
+-		return 0;
++		tx_map_failed++;
++		tx_dropped++;
++		goto out;
+ 	}
+ 
+ 	curfrag = nfrags;
+@@ -684,8 +668,8 @@ static int ibmveth_start_xmit(struct sk_
+ 
+ 		if(dma_mapping_error(desc[curfrag+1].fields.address)) {
+ 			ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag);
+-			adapter->tx_map_failed++;
+-			adapter->stats.tx_dropped++;
++			tx_map_failed++;
++			tx_dropped++;
+ 			/* Free all the mappings we just created */
+ 			while(curfrag < nfrags) {
+ 				dma_unmap_single(&adapter->vdev->dev,
+@@ -694,8 +678,7 @@ static int ibmveth_start_xmit(struct sk_
+ 						 DMA_TO_DEVICE);
+ 				curfrag++;
+ 			}
+-			dev_kfree_skb(skb);
+-			return 0;
++			goto out;
+ 		}
+ 	}
+ 
+@@ -720,11 +703,12 @@ static int ibmveth_start_xmit(struct sk_
+ 			ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i,
+ 					     desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address);
+ 		}
+-		adapter->tx_send_failed++;
+-		adapter->stats.tx_dropped++;
++		tx_send_failed++;
++		tx_dropped++;
+ 	} else {
+-		adapter->stats.tx_packets++;
+-		adapter->stats.tx_bytes += skb->len;
++		tx_packets++;
++		tx_bytes += skb->len;
++		netdev->trans_start = jiffies;
+ 	}
+ 
+ 	do {
+@@ -733,6 +717,14 @@ static int ibmveth_start_xmit(struct sk_
+ 				desc[nfrags].fields.length, DMA_TO_DEVICE);
+ 	} while(--nfrags >= 0);
+ 
++out:	spin_lock_irqsave(&adapter->stats_lock, flags);
++	adapter->stats.tx_dropped += tx_dropped;
++	adapter->stats.tx_bytes += tx_bytes;
++	adapter->stats.tx_packets += tx_packets;
++	adapter->tx_send_failed += tx_send_failed;
++	adapter->tx_map_failed += tx_map_failed;
++	spin_unlock_irqrestore(&adapter->stats_lock, flags);
++
+ 	dev_kfree_skb(skb);
+ 	return 0;
+ }
+@@ -776,13 +768,14 @@ static int ibmveth_poll(struct net_devic
+ 				adapter->stats.rx_packets++;
+ 				adapter->stats.rx_bytes += length;
+ 				frames_processed++;
++				netdev->last_rx = jiffies;
+ 			}
+ 		} else {
+ 			more_work = 0;
+ 		}
+ 	} while(more_work && (frames_processed < max_frames_to_process));
+ 
+-	ibmveth_schedule_replenishing(adapter);
++	ibmveth_replenish_task(adapter);
+ 
+ 	if(more_work) {
+ 		/* more work to do - return that we are not done yet */
+@@ -883,17 +876,54 @@ static void ibmveth_set_multicast_list(s
+ 
+ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
+ {
+-	if ((new_mtu < 68) || (new_mtu > (1<<20)))
++	struct ibmveth_adapter *adapter = dev->priv;
++	int i;
++	int prev_smaller = 1;
++
++	if ((new_mtu < 68) || 
++	    (new_mtu > (pool_size[IbmVethNumBufferPools-1]) - IBMVETH_BUFF_OH))
+ 		return -EINVAL;
++
++	for(i = 0; i<IbmVethNumBufferPools; i++) {
++		int activate = 0;
++		if (new_mtu > (pool_size[i]  - IBMVETH_BUFF_OH)) { 
++			activate = 1;
++			prev_smaller= 1;
++		} else {
++			if (prev_smaller)
++				activate = 1;
++			prev_smaller= 0;
++		}
++
++		if (activate && !adapter->rx_buff_pool[i].active) {
++			struct ibmveth_buff_pool *pool = 
++						&adapter->rx_buff_pool[i];
++			if(ibmveth_alloc_buffer_pool(pool)) {
++				ibmveth_error_printk("unable to alloc pool\n");
++				return -ENOMEM;
++			}
++			adapter->rx_buff_pool[i].active = 1;
++		} else if (!activate && adapter->rx_buff_pool[i].active) {
++			adapter->rx_buff_pool[i].active = 0;
++			h_free_logical_lan_buffer(adapter->vdev->unit_address,
++					  (u64)pool_size[i]);
++		}
++
++	}
++
++	/* kick the interrupt handler so that the new buffer pools get
++	   replenished or deallocated */
++	ibmveth_interrupt(dev->irq, dev, NULL);
++
+ 	dev->mtu = new_mtu;
+ 	return 0;	
+ }
+ 
+ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
+ {
+-	int rc;
++	int rc, i;
+ 	struct net_device *netdev;
+-	struct ibmveth_adapter *adapter;
++	struct ibmveth_adapter *adapter = NULL;
+ 
+ 	unsigned char *mac_addr_p;
+ 	unsigned int *mcastFilterSize_p;
+@@ -960,23 +990,21 @@ static int __devinit ibmveth_probe(struc
+ 	netdev->ethtool_ops           = &netdev_ethtool_ops;
+ 	netdev->change_mtu         = ibmveth_change_mtu;
+ 	SET_NETDEV_DEV(netdev, &dev->dev);
++ 	netdev->features |= NETIF_F_LLTX; 
++	spin_lock_init(&adapter->stats_lock);
+ 
+ 	memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
+ 
+-	ibmveth_init_buffer_pool(&adapter->rx_buff_pool[0], 0, IbmVethPool0DftCnt, IbmVethPool0DftSize);
+-	ibmveth_init_buffer_pool(&adapter->rx_buff_pool[1], 1, IbmVethPool1DftCnt, IbmVethPool1DftSize);
+-	ibmveth_init_buffer_pool(&adapter->rx_buff_pool[2], 2, IbmVethPool2DftCnt, IbmVethPool2DftSize);
++	for(i = 0; i<IbmVethNumBufferPools; i++)
++		ibmveth_init_buffer_pool(&adapter->rx_buff_pool[i], i, 
++					 pool_count[i], pool_size[i]);
+ 
+ 	ibmveth_debug_printk("adapter @ 0x%p\n", adapter);
+ 
+-	INIT_WORK(&adapter->replenish_task, (void*)ibmveth_replenish_task, (void*)adapter);
+-
+ 	adapter->buffer_list_dma = DMA_ERROR_CODE;
+ 	adapter->filter_list_dma = DMA_ERROR_CODE;
+ 	adapter->rx_queue.queue_dma = DMA_ERROR_CODE;
+ 
+-	atomic_set(&adapter->not_replenishing, 1);
+-
+ 	ibmveth_debug_printk("registering netdev...\n");
+ 
+ 	rc = register_netdev(netdev);
+@@ -1146,14 +1174,16 @@ static struct vio_device_id ibmveth_devi
+ 	{ "network", "IBM,l-lan"},
+ 	{ "", "" }
+ };
+-
+ MODULE_DEVICE_TABLE(vio, ibmveth_device_table);
+ 
+ static struct vio_driver ibmveth_driver = {
+-	.name        = (char *)ibmveth_driver_name,
+-	.id_table    = ibmveth_device_table,
+-	.probe       = ibmveth_probe,
+-	.remove      = ibmveth_remove
++	.id_table	= ibmveth_device_table,
++	.probe		= ibmveth_probe,
++	.remove		= ibmveth_remove,
++	.driver		= {
++		.name	= ibmveth_driver_name,
++		.owner	= THIS_MODULE,
++	}
+ };
+ 
+ static int __init ibmveth_module_init(void)
+diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
+--- a/drivers/net/ibmveth.h
++++ b/drivers/net/ibmveth.h
+@@ -49,6 +49,7 @@
+ #define H_SEND_LOGICAL_LAN       0x120
+ #define H_MULTICAST_CTRL         0x130
+ #define H_CHANGE_LOGICAL_LAN_MAC 0x14C
++#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
+ 
+ /* hcall macros */
+ #define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \
+@@ -69,13 +70,15 @@
+ #define h_change_logical_lan_mac(ua, mac) \
+   plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)
+ 
+-#define IbmVethNumBufferPools 3
+-#define IbmVethPool0DftSize (1024 * 2)
+-#define IbmVethPool1DftSize (1024 * 4)
+-#define IbmVethPool2DftSize (1024 * 10)
+-#define IbmVethPool0DftCnt  256
+-#define IbmVethPool1DftCnt  256
+-#define IbmVethPool2DftCnt  256
++#define h_free_logical_lan_buffer(ua, bufsize) \
++  plpar_hcall_norets(H_FREE_LOGICAL_LAN_BUFFER, ua, bufsize)
++
++#define IbmVethNumBufferPools 5
++#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
++
++/* pool_size should be sorted */
++static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 };
++static int pool_count[] = { 256, 768, 256, 256, 256 };
+ 
+ #define IBM_VETH_INVALID_MAP ((u16)0xffff)
+ 
+@@ -90,6 +93,7 @@ struct ibmveth_buff_pool {
+     u16 *free_map;
+     dma_addr_t *dma_addr;
+     struct sk_buff **skbuff;
++    int active;
+ };
+ 
+ struct ibmveth_rx_q {
+@@ -114,10 +118,6 @@ struct ibmveth_adapter {
+     dma_addr_t filter_list_dma;
+     struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools];
+     struct ibmveth_rx_q rx_queue;
+-    atomic_t not_replenishing;
+-
+-    /* helper tasks */
+-    struct work_struct replenish_task;
+ 
+     /* adapter specific stats */
+     u64 replenish_task_cycles;
+@@ -131,6 +131,7 @@ struct ibmveth_adapter {
+     u64 tx_linearize_failed;
+     u64 tx_map_failed;
+     u64 tx_send_failed;
++    spinlock_t stats_lock;
+ };
+ 
+ struct ibmveth_buf_desc_fields {	
+diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
+--- a/drivers/net/irda/Kconfig
++++ b/drivers/net/irda/Kconfig
+@@ -400,5 +400,15 @@ config VIA_FIR
+ 	  To compile it as a module, choose M here: the module will be called
+ 	  via-ircc.
+ 
++config PXA_FICP
++	tristate "Intel PXA2xx Internal FICP"
++	depends on ARCH_PXA && IRDA
++	help
++	  Say Y or M here if you want to build support for the PXA2xx
++	  built-in IRDA interface which can support both SIR and FIR.
++	  This driver relies on platform specific helper routines so
++	  available capabilities may vary from one PXA2xx target to
++	  another.
++
+ endmenu
+ 
+diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile
+--- a/drivers/net/irda/Makefile
++++ b/drivers/net/irda/Makefile
+@@ -18,6 +18,7 @@ obj-$(CONFIG_SMC_IRCC_FIR)	+= smsc-ircc2
+ obj-$(CONFIG_ALI_FIR)		+= ali-ircc.o
+ obj-$(CONFIG_VLSI_FIR)		+= vlsi_ir.o
+ obj-$(CONFIG_VIA_FIR)		+= via-ircc.o
++obj-$(CONFIG_PXA_FICP)	        += pxaficp_ir.o
+ # Old dongle drivers for old SIR drivers
+ obj-$(CONFIG_ESI_DONGLE_OLD)		+= esi.o
+ obj-$(CONFIG_TEKRAM_DONGLE_OLD)	+= tekram.o
+diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
+--- a/drivers/net/irda/donauboe.c
++++ b/drivers/net/irda/donauboe.c
+@@ -1695,11 +1695,9 @@ toshoboe_open (struct pci_dev *pci_dev, 
+ 
+ freebufs:
+   for (i = 0; i < TX_SLOTS; ++i)
+-    if (self->tx_bufs[i])
+-      kfree (self->tx_bufs[i]);
++    kfree (self->tx_bufs[i]);
+   for (i = 0; i < RX_SLOTS; ++i)
+-    if (self->rx_bufs[i])
+-      kfree (self->rx_bufs[i]);
++    kfree (self->rx_bufs[i]);
+   kfree(self->ringbuf);
+ 
+ freeregion:
+diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
+--- a/drivers/net/irda/irda-usb.c
++++ b/drivers/net/irda/irda-usb.c
+@@ -1168,10 +1168,8 @@ static inline void irda_usb_close(struct
+ 	unregister_netdev(self->netdev);
+ 
+ 	/* Remove the speed buffer */
+-	if (self->speed_buff != NULL) {
+-		kfree(self->speed_buff);
+-		self->speed_buff = NULL;
+-	}
++	kfree(self->speed_buff);
++	self->speed_buff = NULL;
+ }
+ 
+ /********************** USB CONFIG SUBROUTINES **********************/
+diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c
+--- a/drivers/net/irda/irport.c
++++ b/drivers/net/irda/irport.c
+@@ -235,8 +235,7 @@ static int irport_close(struct irport_cb
+ 		   __FUNCTION__, self->io.sir_base);
+ 	release_region(self->io.sir_base, self->io.sir_ext);
+ 
+-	if (self->tx_buff.head)
+-		kfree(self->tx_buff.head);
++	kfree(self->tx_buff.head);
+ 	
+ 	if (self->rx_buff.skb)
+ 		kfree_skb(self->rx_buff.skb);
+diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/irda/pxaficp_ir.c
+@@ -0,0 +1,866 @@
++/*
++ * linux/drivers/net/irda/pxaficp_ir.c
++ *
++ * Based on sa1100_ir.c by Russell King
++ *
++ * Changes copyright (C) 2003-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 version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor
++ *
++ */
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/netdevice.h>
++#include <linux/slab.h>
++#include <linux/rtnetlink.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
++#include <linux/pm.h>
++
++#include <net/irda/irda.h>
++#include <net/irda/irmod.h>
++#include <net/irda/wrapper.h>
++#include <net/irda/irda_device.h>
++
++#include <asm/irq.h>
++#include <asm/dma.h>
++#include <asm/delay.h>
++#include <asm/hardware.h>
++#include <asm/arch/irda.h>
++#include <asm/arch/pxa-regs.h>
++
++#ifdef CONFIG_MACH_MAINSTONE
++#include <asm/arch/mainstone.h>
++#endif
++
++#define IrSR_RXPL_NEG_IS_ZERO (1<<4)
++#define IrSR_RXPL_POS_IS_ZERO 0x0
++#define IrSR_TXPL_NEG_IS_ZERO (1<<3)
++#define IrSR_TXPL_POS_IS_ZERO 0x0
++#define IrSR_XMODE_PULSE_1_6  (1<<2)
++#define IrSR_XMODE_PULSE_3_16 0x0
++#define IrSR_RCVEIR_IR_MODE   (1<<1)
++#define IrSR_RCVEIR_UART_MODE 0x0
++#define IrSR_XMITIR_IR_MODE   (1<<0)
++#define IrSR_XMITIR_UART_MODE 0x0
++
++#define IrSR_IR_RECEIVE_ON (\
++                IrSR_RXPL_NEG_IS_ZERO | \
++                IrSR_TXPL_POS_IS_ZERO | \
++                IrSR_XMODE_PULSE_3_16 | \
++                IrSR_RCVEIR_IR_MODE   | \
++                IrSR_XMITIR_UART_MODE)
++
++#define IrSR_IR_TRANSMIT_ON (\
++                IrSR_RXPL_NEG_IS_ZERO | \
++                IrSR_TXPL_POS_IS_ZERO | \
++                IrSR_XMODE_PULSE_3_16 | \
++                IrSR_RCVEIR_UART_MODE | \
++                IrSR_XMITIR_IR_MODE)
++
++struct pxa_irda {
++	int			speed;
++	int			newspeed;
++	unsigned long		last_oscr;
++
++	unsigned char		*dma_rx_buff;
++	unsigned char		*dma_tx_buff;
++	dma_addr_t		dma_rx_buff_phy;
++	dma_addr_t		dma_tx_buff_phy;
++	unsigned int		dma_tx_buff_len;
++	int			txdma;
++	int			rxdma;
++
++	struct net_device_stats	stats;
++	struct irlap_cb		*irlap;
++	struct qos_info		qos;
++
++	iobuff_t		tx_buff;
++	iobuff_t		rx_buff;
++
++	struct device		*dev;
++	struct pxaficp_platform_data *pdata;
++};
++
++
++#define IS_FIR(si)		((si)->speed >= 4000000)
++#define IRDA_FRAME_SIZE_LIMIT	2047
++
++inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si)
++{
++	DCSR(si->rxdma)  = DCSR_NODESC;
++	DSADR(si->rxdma) = __PREG(ICDR);
++	DTADR(si->rxdma) = si->dma_rx_buff_phy;
++	DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC |  DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT;
++	DCSR(si->rxdma) |= DCSR_RUN;
++}
++
++inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
++{
++	DCSR(si->txdma)  = DCSR_NODESC;
++	DSADR(si->txdma) = si->dma_tx_buff_phy;
++	DTADR(si->txdma) = __PREG(ICDR);
++	DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG |  DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len;
++	DCSR(si->txdma) |= DCSR_RUN;
++}
++
++/*
++ * Set the IrDA communications speed.
++ */
++static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
++{
++	unsigned long flags;
++	unsigned int divisor;
++
++	switch (speed) {
++	case 9600:	case 19200:	case 38400:
++	case 57600:	case 115200:
++
++		/* refer to PXA250/210 Developer's Manual 10-7 */
++		/*  BaudRate = 14.7456 MHz / (16*Divisor) */
++		divisor = 14745600 / (16 * speed);
++
++		local_irq_save(flags);
++
++		if (IS_FIR(si)) {
++			/* stop RX DMA */
++			DCSR(si->rxdma) &= ~DCSR_RUN;
++			/* disable FICP */
++			ICCR0 = 0;
++			pxa_set_cken(CKEN13_FICP, 0);
++
++			/* set board transceiver to SIR mode */
++			si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
++
++			/* configure GPIO46/47 */
++			pxa_gpio_mode(GPIO46_STRXD_MD);
++			pxa_gpio_mode(GPIO47_STTXD_MD);
++
++			/* enable the STUART clock */
++			pxa_set_cken(CKEN5_STUART, 1);
++		}
++
++		/* disable STUART first */
++		STIER = 0;
++
++		/* access DLL & DLH */
++		STLCR |= LCR_DLAB;
++		STDLL = divisor & 0xff;
++		STDLH = divisor >> 8;
++		STLCR &= ~LCR_DLAB;
++
++		si->speed = speed;
++		STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
++		STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
++
++		local_irq_restore(flags);
++		break;
++
++	case 4000000:
++		local_irq_save(flags);
++
++		/* disable STUART */
++		STIER = 0;
++		STISR = 0;
++		pxa_set_cken(CKEN5_STUART, 0);
++
++		/* disable FICP first */
++		ICCR0 = 0;
++
++		/* set board transceiver to FIR mode */
++		si->pdata->transceiver_mode(si->dev, IR_FIRMODE);
++
++		/* configure GPIO46/47 */
++		pxa_gpio_mode(GPIO46_ICPRXD_MD);
++		pxa_gpio_mode(GPIO47_ICPTXD_MD);
++
++		/* enable the FICP clock */
++		pxa_set_cken(CKEN13_FICP, 1);
++
++		si->speed = speed;
++		pxa_irda_fir_dma_rx_start(si);
++		ICCR0 = ICCR0_ITR | ICCR0_RXE;
++
++		local_irq_restore(flags);
++		break;
++
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++/* SIR interrupt service routine. */
++static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct net_device *dev = dev_id;
++	struct pxa_irda *si = netdev_priv(dev);
++	int iir, lsr, data;
++
++	iir = STIIR;
++
++	switch  (iir & 0x0F) {
++	case 0x06: /* Receiver Line Status */
++	  	lsr = STLSR;
++		while (lsr & LSR_FIFOE) {
++			data = STRBR;
++			if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) {
++				printk(KERN_DEBUG "pxa_ir: sir receiving error\n");
++				si->stats.rx_errors++;
++				if (lsr & LSR_FE)
++					si->stats.rx_frame_errors++;
++				if (lsr & LSR_OE)
++					si->stats.rx_fifo_errors++;
++			} else {
++				si->stats.rx_bytes++;
++				async_unwrap_char(dev, &si->stats, &si->rx_buff, data);
++			}
++			lsr = STLSR;
++		}
++		dev->last_rx = jiffies;
++		si->last_oscr = OSCR;
++		break;
++
++	case 0x04: /* Received Data Available */
++	  	   /* forth through */
++
++	case 0x0C: /* Character Timeout Indication */
++	  	do  {
++		    si->stats.rx_bytes++;
++	            async_unwrap_char(dev, &si->stats, &si->rx_buff, STRBR);
++	  	} while (STLSR & LSR_DR);
++	  	dev->last_rx = jiffies;
++		si->last_oscr = OSCR;
++	  	break;
++
++	case 0x02: /* Transmit FIFO Data Request */
++	    	while ((si->tx_buff.len) && (STLSR & LSR_TDRQ)) {
++	    		STTHR = *si->tx_buff.data++;
++			si->tx_buff.len -= 1;
++	    	}
++
++		if (si->tx_buff.len == 0) {
++			si->stats.tx_packets++;
++			si->stats.tx_bytes += si->tx_buff.data -
++					      si->tx_buff.head;
++
++                        /* We need to ensure that the transmitter has finished. */
++			while ((STLSR & LSR_TEMT) == 0)
++				cpu_relax();
++			si->last_oscr = OSCR;
++
++			/*
++		 	* Ok, we've finished transmitting.  Now enable
++		 	* the receiver.  Sometimes we get a receive IRQ
++		 	* immediately after a transmit...
++		 	*/
++			if (si->newspeed) {
++				pxa_irda_set_speed(si, si->newspeed);
++				si->newspeed = 0;
++			} else {
++				/* enable IR Receiver, disable IR Transmitter */
++				STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
++				/* enable STUART and receive interrupts */
++				STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
++			}
++			/* I'm hungry! */
++			netif_wake_queue(dev);
++		}
++		break;
++	}
++
++	return IRQ_HANDLED;
++}
++
++/* FIR Receive DMA interrupt handler */
++static void pxa_irda_fir_dma_rx_irq(int channel, void *data, struct pt_regs *regs)
++{
++	int dcsr = DCSR(channel);
++
++	DCSR(channel) = dcsr & ~DCSR_RUN;
++
++	printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr);
++}
++
++/* FIR Transmit DMA interrupt handler */
++static void pxa_irda_fir_dma_tx_irq(int channel, void *data, struct pt_regs *regs)
++{
++	struct net_device *dev = data;
++	struct pxa_irda *si = netdev_priv(dev);
++	int dcsr;
++
++	dcsr = DCSR(channel);
++	DCSR(channel) = dcsr & ~DCSR_RUN;
++
++	if (dcsr & DCSR_ENDINTR)  {
++		si->stats.tx_packets++;
++		si->stats.tx_bytes += si->dma_tx_buff_len;
++	} else {
++		si->stats.tx_errors++;
++	}
++
++	while (ICSR1 & ICSR1_TBY)
++		cpu_relax();
++	si->last_oscr = OSCR;
++
++	/*
++	 * HACK: It looks like the TBY bit is dropped too soon.
++	 * Without this delay things break.
++	 */
++	udelay(120);
++
++	if (si->newspeed) {
++		pxa_irda_set_speed(si, si->newspeed);
++		si->newspeed = 0;
++	} else {
++		ICCR0 = 0;
++		pxa_irda_fir_dma_rx_start(si);
++		ICCR0 = ICCR0_ITR | ICCR0_RXE;
++	}
++	netif_wake_queue(dev);
++}
++
++/* EIF(Error in FIFO/End in Frame) handler for FIR */
++static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev)
++{
++	unsigned int len, stat, data;
++
++	/* Get the current data position. */
++	len = DTADR(si->rxdma) - si->dma_rx_buff_phy;
++
++	do {
++		/* Read Status, and then Data. 	 */
++		stat = ICSR1;
++		rmb();
++		data = ICDR;
++
++		if (stat & (ICSR1_CRE | ICSR1_ROR)) {
++			si->stats.rx_errors++;
++			if (stat & ICSR1_CRE) {
++				printk(KERN_DEBUG "pxa_ir: fir receive CRC error\n");
++				si->stats.rx_crc_errors++;
++			}
++			if (stat & ICSR1_ROR) {
++				printk(KERN_DEBUG "pxa_ir: fir receive overrun\n");
++				si->stats.rx_frame_errors++;
++			}
++		} else	{
++			si->dma_rx_buff[len++] = data;
++		}
++		/* If we hit the end of frame, there's no point in continuing. */
++		if (stat & ICSR1_EOF)
++			break;
++	} while (ICSR0 & ICSR0_EIF);
++
++	if (stat & ICSR1_EOF) {
++		/* end of frame. */
++		struct sk_buff *skb = alloc_skb(len+1,GFP_ATOMIC);
++		if (!skb)  {
++			printk(KERN_ERR "pxa_ir: fir out of memory for receive skb\n");
++			si->stats.rx_dropped++;
++			return;
++		}
++
++		/* Align IP header to 20 bytes  */
++		skb_reserve(skb, 1);
++		memcpy(skb->data, si->dma_rx_buff, len);
++		skb_put(skb, len);
++
++		/* Feed it to IrLAP  */
++		skb->dev = dev;
++		skb->mac.raw  = skb->data;
++		skb->protocol = htons(ETH_P_IRDA);
++		netif_rx(skb);
++
++		si->stats.rx_packets++;
++		si->stats.rx_bytes += len;
++
++		dev->last_rx = jiffies;
++	}
++}
++
++/* FIR interrupt handler */
++static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct net_device *dev = dev_id;
++	struct pxa_irda *si = netdev_priv(dev);
++	int icsr0;
++
++	/* stop RX DMA */
++	DCSR(si->rxdma) &= ~DCSR_RUN;
++	si->last_oscr = OSCR;
++	icsr0 = ICSR0;
++
++	if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) {
++		if (icsr0 & ICSR0_FRE) {
++		        printk(KERN_DEBUG "pxa_ir: fir receive frame error\n");
++			si->stats.rx_frame_errors++;
++		} else {
++			printk(KERN_DEBUG "pxa_ir: fir receive abort\n");
++			si->stats.rx_errors++;
++		}
++		ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB);
++	}
++
++	if (icsr0 & ICSR0_EIF) {
++		/* An error in FIFO occured, or there is a end of frame */
++		pxa_irda_fir_irq_eif(si, dev);
++	}
++
++	ICCR0 = 0;
++	pxa_irda_fir_dma_rx_start(si);
++	ICCR0 = ICCR0_ITR | ICCR0_RXE;
++
++	return IRQ_HANDLED;
++}
++
++/* hard_xmit interface of irda device */
++static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++	struct pxa_irda *si = netdev_priv(dev);
++	int speed = irda_get_next_speed(skb);
++
++	/*
++	 * Does this packet contain a request to change the interface
++	 * speed?  If so, remember it until we complete the transmission
++	 * of this frame.
++	 */
++	if (speed != si->speed && speed != -1)
++		si->newspeed = speed;
++
++	/*
++	 * If this is an empty frame, we can bypass a lot.
++	 */
++	if (skb->len == 0) {
++		if (si->newspeed) {
++			si->newspeed = 0;
++			pxa_irda_set_speed(si, speed);
++		}
++		dev_kfree_skb(skb);
++		return 0;
++	}
++
++	netif_stop_queue(dev);
++
++	if (!IS_FIR(si)) {
++		si->tx_buff.data = si->tx_buff.head;
++		si->tx_buff.len  = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize);
++
++		/* Disable STUART interrupts and switch to transmit mode. */
++		STIER = 0;
++		STISR = IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6;
++
++		/* enable STUART and transmit interrupts */
++		STIER = IER_UUE | IER_TIE;
++	} else {
++		unsigned long mtt = irda_get_mtt(skb);
++
++		si->dma_tx_buff_len = skb->len;
++		memcpy(si->dma_tx_buff, skb->data, skb->len);
++
++		if (mtt)
++			while ((unsigned)(OSCR - si->last_oscr)/4 < mtt)
++				cpu_relax();
++
++		/* stop RX DMA,  disable FICP */
++		DCSR(si->rxdma) &= ~DCSR_RUN;
++		ICCR0 = 0;
++
++		pxa_irda_fir_dma_tx_start(si);
++		ICCR0 = ICCR0_ITR | ICCR0_TXE;
++	}
++
++	dev_kfree_skb(skb);
++	dev->trans_start = jiffies;
++	return 0;
++}
++
++static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
++{
++	struct if_irda_req *rq = (struct if_irda_req *)ifreq;
++	struct pxa_irda *si = netdev_priv(dev);
++	int ret;
++
++	switch (cmd) {
++	case SIOCSBANDWIDTH:
++		ret = -EPERM;
++		if (capable(CAP_NET_ADMIN)) {
++			/*
++			 * We are unable to set the speed if the
++			 * device is not running.
++			 */
++			if (netif_running(dev)) {
++				ret = pxa_irda_set_speed(si,
++						rq->ifr_baudrate);
++			} else {
++				printk(KERN_INFO "pxa_ir: SIOCSBANDWIDTH: !netif_running\n");
++				ret = 0;
++			}
++		}
++		break;
++
++	case SIOCSMEDIABUSY:
++		ret = -EPERM;
++		if (capable(CAP_NET_ADMIN)) {
++			irda_device_set_media_busy(dev, TRUE);
++			ret = 0;
++		}
++		break;
++
++	case SIOCGRECEIVING:
++		ret = 0;
++		rq->ifr_receiving = IS_FIR(si) ? 0
++					: si->rx_buff.state != OUTSIDE_FRAME;
++		break;
++
++	default:
++		ret = -EOPNOTSUPP;
++		break;
++	}
++
++	return ret;
++}
++
++static struct net_device_stats *pxa_irda_stats(struct net_device *dev)
++{
++	struct pxa_irda *si = netdev_priv(dev);
++	return &si->stats;
++}
++
++static void pxa_irda_startup(struct pxa_irda *si)
++{
++	/* Disable STUART interrupts */
++	STIER = 0;
++	/* enable STUART interrupt to the processor */
++	STMCR = MCR_OUT2;
++	/* configure SIR frame format: StartBit - Data 7 ... Data 0 - Stop Bit */
++	STLCR = LCR_WLS0 | LCR_WLS1;
++	/* enable FIFO, we use FIFO to improve performance */
++	STFCR = FCR_TRFIFOE | FCR_ITL_32;
++
++	/* disable FICP */
++	ICCR0 = 0;
++	/* configure FICP ICCR2 */
++	ICCR2 = ICCR2_TXP | ICCR2_TRIG_32;
++
++	/* configure DMAC */
++	DRCMR17 = si->rxdma | DRCMR_MAPVLD;
++	DRCMR18 = si->txdma | DRCMR_MAPVLD;
++
++	/* force SIR reinitialization */
++	si->speed = 4000000;
++	pxa_irda_set_speed(si, 9600);
++
++	printk(KERN_DEBUG "pxa_ir: irda startup\n");
++}
++
++static void pxa_irda_shutdown(struct pxa_irda *si)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++
++	/* disable STUART and interrupt */
++	STIER = 0;
++	/* disable STUART SIR mode */
++	STISR = 0;
++	/* disable the STUART clock */
++	pxa_set_cken(CKEN5_STUART, 0);
++
++	/* disable DMA */
++	DCSR(si->txdma) &= ~DCSR_RUN;
++	DCSR(si->rxdma) &= ~DCSR_RUN;
++	/* disable FICP */
++	ICCR0 = 0;
++	/* disable the FICP clock */
++	pxa_set_cken(CKEN13_FICP, 0);
++
++	DRCMR17 = 0;
++	DRCMR18 = 0;
++
++	local_irq_restore(flags);
++
++	/* power off board transceiver */
++	si->pdata->transceiver_mode(si->dev, IR_OFF);
++
++	printk(KERN_DEBUG "pxa_ir: irda shutdown\n");
++}
++
++static int pxa_irda_start(struct net_device *dev)
++{
++	struct pxa_irda *si = netdev_priv(dev);
++	int err;
++
++	si->speed = 9600;
++
++	err = request_irq(IRQ_STUART, pxa_irda_sir_irq, 0, dev->name, dev);
++	if (err)
++		goto err_irq1;
++
++	err = request_irq(IRQ_ICP, pxa_irda_fir_irq, 0, dev->name, dev);
++	if (err)
++		goto err_irq2;
++
++	/*
++	 * The interrupt must remain disabled for now.
++	 */
++	disable_irq(IRQ_STUART);
++	disable_irq(IRQ_ICP);
++
++	err = -EBUSY;
++	si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev);
++	if (si->rxdma < 0)
++		goto err_rx_dma;
++
++	si->txdma = pxa_request_dma("FICP_TX",DMA_PRIO_LOW, pxa_irda_fir_dma_tx_irq, dev);
++	if (si->txdma < 0)
++		goto err_tx_dma;
++
++	err = -ENOMEM;
++	si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
++					     &si->dma_rx_buff_phy, GFP_KERNEL );
++	if (!si->dma_rx_buff)
++		goto err_dma_rx_buff;
++
++	si->dma_tx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
++					     &si->dma_tx_buff_phy, GFP_KERNEL );
++	if (!si->dma_tx_buff)
++		goto err_dma_tx_buff;
++
++	/* Setup the serial port for the initial speed. */
++	pxa_irda_startup(si);
++
++	/*
++	 * Open a new IrLAP layer instance.
++	 */
++	si->irlap = irlap_open(dev, &si->qos, "pxa");
++	err = -ENOMEM;
++	if (!si->irlap)
++		goto err_irlap;
++
++	/*
++	 * Now enable the interrupt and start the queue
++	 */
++	enable_irq(IRQ_STUART);
++	enable_irq(IRQ_ICP);
++	netif_start_queue(dev);
++
++	printk(KERN_DEBUG "pxa_ir: irda driver opened\n");
++
++	return 0;
++
++err_irlap:
++	pxa_irda_shutdown(si);
++	dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
++err_dma_tx_buff:
++	dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
++err_dma_rx_buff:
++	pxa_free_dma(si->txdma);
++err_tx_dma:
++	pxa_free_dma(si->rxdma);
++err_rx_dma:
++	free_irq(IRQ_ICP, dev);
++err_irq2:
++	free_irq(IRQ_STUART, dev);
++err_irq1:
++
++	return err;
++}
++
++static int pxa_irda_stop(struct net_device *dev)
++{
++	struct pxa_irda *si = netdev_priv(dev);
++
++	netif_stop_queue(dev);
++
++	pxa_irda_shutdown(si);
++
++	/* Stop IrLAP */
++	if (si->irlap) {
++		irlap_close(si->irlap);
++		si->irlap = NULL;
++	}
++
++	free_irq(IRQ_STUART, dev);
++	free_irq(IRQ_ICP, dev);
++
++	pxa_free_dma(si->rxdma);
++	pxa_free_dma(si->txdma);
++
++	if (si->dma_rx_buff)
++		dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
++	if (si->dma_tx_buff)
++		dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
++
++	printk(KERN_DEBUG "pxa_ir: irda driver closed\n");
++	return 0;
++}
++
++static int pxa_irda_suspend(struct device *_dev, pm_message_t state)
++{
++	struct net_device *dev = dev_get_drvdata(_dev);
++	struct pxa_irda *si;
++
++	if (dev && netif_running(dev)) {
++		si = netdev_priv(dev);
++		netif_device_detach(dev);
++		pxa_irda_shutdown(si);
++	}
++
++	return 0;
++}
++
++static int pxa_irda_resume(struct device *_dev)
++{
++	struct net_device *dev = dev_get_drvdata(_dev);
++	struct pxa_irda *si;
++
++	if (dev && netif_running(dev)) {
++		si = netdev_priv(dev);
++		pxa_irda_startup(si);
++		netif_device_attach(dev);
++		netif_wake_queue(dev);
++	}
++
++	return 0;
++}
++
++
++static int pxa_irda_init_iobuf(iobuff_t *io, int size)
++{
++	io->head = kmalloc(size, GFP_KERNEL | GFP_DMA);
++	if (io->head != NULL) {
++		io->truesize = size;
++		io->in_frame = FALSE;
++		io->state    = OUTSIDE_FRAME;
++		io->data     = io->head;
++	}
++	return io->head ? 0 : -ENOMEM;
++}
++
++static int pxa_irda_probe(struct device *_dev)
++{
++	struct platform_device *pdev = to_platform_device(_dev);
++	struct net_device *dev;
++	struct pxa_irda *si;
++	unsigned int baudrate_mask;
++	int err;
++
++	if (!pdev->dev.platform_data)
++		return -ENODEV;
++
++	err = request_mem_region(__PREG(STUART), 0x24, "IrDA") ? 0 : -EBUSY;
++	if (err)
++		goto err_mem_1;
++
++	err = request_mem_region(__PREG(FICP), 0x1c, "IrDA") ? 0 : -EBUSY;
++	if (err)
++		goto err_mem_2;
++
++	dev = alloc_irdadev(sizeof(struct pxa_irda));
++	if (!dev)
++		goto err_mem_3;
++
++	si = netdev_priv(dev);
++	si->dev = &pdev->dev;
++	si->pdata = pdev->dev.platform_data;
++
++	/*
++	 * Initialise the SIR buffers
++	 */
++	err = pxa_irda_init_iobuf(&si->rx_buff, 14384);
++	if (err)
++		goto err_mem_4;
++	err = pxa_irda_init_iobuf(&si->tx_buff, 4000);
++	if (err)
++		goto err_mem_5;
++
++	dev->hard_start_xmit	= pxa_irda_hard_xmit;
++	dev->open		= pxa_irda_start;
++	dev->stop		= pxa_irda_stop;
++	dev->do_ioctl		= pxa_irda_ioctl;
++	dev->get_stats		= pxa_irda_stats;
++
++	irda_init_max_qos_capabilies(&si->qos);
++
++	baudrate_mask = 0;
++	if (si->pdata->transceiver_cap & IR_SIRMODE)
++		baudrate_mask |= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
++	if (si->pdata->transceiver_cap & IR_FIRMODE)
++		baudrate_mask |= IR_4000000 << 8;
++
++	si->qos.baud_rate.bits &= baudrate_mask;
++	si->qos.min_turn_time.bits = 7;  /* 1ms or more */
++
++	irda_qos_bits_to_value(&si->qos);
++
++	err = register_netdev(dev);
++
++	if (err == 0)
++		dev_set_drvdata(&pdev->dev, dev);
++
++	if (err) {
++		kfree(si->tx_buff.head);
++err_mem_5:
++		kfree(si->rx_buff.head);
++err_mem_4:
++		free_netdev(dev);
++err_mem_3:
++		release_mem_region(__PREG(FICP), 0x1c);
++err_mem_2:
++		release_mem_region(__PREG(STUART), 0x24);
++	}
++err_mem_1:
++	return err;
++}
++
++static int pxa_irda_remove(struct device *_dev)
++{
++	struct net_device *dev = dev_get_drvdata(_dev);
++
++	if (dev) {
++		struct pxa_irda *si = netdev_priv(dev);
++		unregister_netdev(dev);
++		kfree(si->tx_buff.head);
++		kfree(si->rx_buff.head);
++		free_netdev(dev);
++	}
++
++	release_mem_region(__PREG(STUART), 0x24);
++	release_mem_region(__PREG(FICP), 0x1c);
++
++	return 0;
++}
++
++static struct device_driver pxa_ir_driver = {
++	.name		= "pxa2xx-ir",
++	.bus		= &platform_bus_type,
++	.probe		= pxa_irda_probe,
++	.remove		= pxa_irda_remove,
++	.suspend	= pxa_irda_suspend,
++	.resume		= pxa_irda_resume,
++};
++
++static int __init pxa_irda_init(void)
++{
++	return driver_register(&pxa_ir_driver);
++}
++
++static void __exit pxa_irda_exit(void)
++{
++	driver_unregister(&pxa_ir_driver);
++}
++
++module_init(pxa_irda_init);
++module_exit(pxa_irda_exit);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
+--- a/drivers/net/irda/sa1100_ir.c
++++ b/drivers/net/irda/sa1100_ir.c
+@@ -29,7 +29,7 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ 
+ #include <net/irda/irda.h>
+@@ -291,12 +291,12 @@ static void sa1100_irda_shutdown(struct 
+ /*
+  * Suspend the IrDA interface.
+  */
+-static int sa1100_irda_suspend(struct device *_dev, pm_message_t state, u32 level)
++static int sa1100_irda_suspend(struct device *_dev, pm_message_t state)
+ {
+ 	struct net_device *dev = dev_get_drvdata(_dev);
+ 	struct sa1100_irda *si;
+ 
+-	if (!dev || level != SUSPEND_DISABLE)
++	if (!dev)
+ 		return 0;
+ 
+ 	si = dev->priv;
+@@ -316,12 +316,12 @@ static int sa1100_irda_suspend(struct de
+ /*
+  * Resume the IrDA interface.
+  */
+-static int sa1100_irda_resume(struct device *_dev, u32 level)
++static int sa1100_irda_resume(struct device *_dev)
+ {
+ 	struct net_device *dev = dev_get_drvdata(_dev);
+ 	struct sa1100_irda *si;
+ 
+-	if (!dev || level != RESUME_ENABLE)
++	if (!dev)
+ 		return 0;
+ 
+ 	si = dev->priv;
+diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
+--- a/drivers/net/irda/sir_dev.c
++++ b/drivers/net/irda/sir_dev.c
+@@ -490,8 +490,7 @@ static void sirdev_free_buffers(struct s
+ {
+ 	if (dev->rx_buff.skb)
+ 		kfree_skb(dev->rx_buff.skb);
+-	if (dev->tx_buff.head)
+-		kfree(dev->tx_buff.head);
++	kfree(dev->tx_buff.head);
+ 	dev->rx_buff.head = dev->tx_buff.head = NULL;
+ 	dev->rx_buff.skb = NULL;
+ }
+diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
+--- a/drivers/net/irda/smsc-ircc2.c
++++ b/drivers/net/irda/smsc-ircc2.c
+@@ -53,6 +53,7 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/serial_reg.h>
+ #include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/dma.h>
+@@ -213,8 +214,8 @@ static int  smsc_ircc_probe_transceiver_
+ 
+ /* Power Management */
+ 
+-static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level);
+-static int smsc_ircc_resume(struct device *dev, u32 level);
++static int smsc_ircc_suspend(struct device *dev, pm_message_t state);
++static int smsc_ircc_resume(struct device *dev);
+ 
+ static struct device_driver smsc_ircc_driver = {
+ 	.name		= SMSC_IRCC2_DRIVER_NAME,
+@@ -638,21 +639,14 @@ static void smsc_ircc_setup_qos(struct s
+  */
+ static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
+ {
+-	int iobase, ir_mode, ctrl, fast;
+-
+-	IRDA_ASSERT(self != NULL, return;);
+-
+-	iobase = self->io.fir_base;
+-	ir_mode = IRCC_CFGA_IRDA_SIR_A;
+-	ctrl = 0;
+-	fast = 0;
++	int iobase = self->io.fir_base;
+ 
+ 	register_bank(iobase, 0);
+ 	outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
+ 	outb(0x00, iobase + IRCC_MASTER);
+ 
+ 	register_bank(iobase, 1);
+-	outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | ir_mode),
++	outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | IRCC_CFGA_IRDA_SIR_A),
+ 	     iobase + IRCC_SCE_CFGA);
+ 
+ #ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */
+@@ -666,10 +660,10 @@ static void smsc_ircc_init_chip(struct s
+ 	outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD);
+ 
+ 	register_bank(iobase, 4);
+-	outb((inb(iobase + IRCC_CONTROL) & 0x30) | ctrl, iobase + IRCC_CONTROL);
++	outb((inb(iobase + IRCC_CONTROL) & 0x30), iobase + IRCC_CONTROL);
+ 
+ 	register_bank(iobase, 0);
+-	outb(fast, iobase + IRCC_LCR_A);
++	outb(0, iobase + IRCC_LCR_A);
+ 
+ 	smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
+ 
+@@ -1556,6 +1550,46 @@ static int ircc_is_receiving(struct smsc
+ }
+ #endif /* unused */
+ 
++static int smsc_ircc_request_irq(struct smsc_ircc_cb *self)
++{
++	int error;
++
++	error = request_irq(self->io.irq, smsc_ircc_interrupt, 0,
++			    self->netdev->name, self->netdev);
++	if (error)
++		IRDA_DEBUG(0, "%s(), unable to allocate irq=%d, err=%d\n",
++			   __FUNCTION__, self->io.irq, error);
++
++	return error;
++}
++
++static void smsc_ircc_start_interrupts(struct smsc_ircc_cb *self)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&self->lock, flags);
++
++	self->io.speed = 0;
++	smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
++
++	spin_unlock_irqrestore(&self->lock, flags);
++}
++
++static void smsc_ircc_stop_interrupts(struct smsc_ircc_cb *self)
++{
++	int iobase = self->io.fir_base;
++	unsigned long flags;
++
++	spin_lock_irqsave(&self->lock, flags);
++
++	register_bank(iobase, 0);
++	outb(0, iobase + IRCC_IER);
++	outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
++	outb(0x00, iobase + IRCC_MASTER);
++
++	spin_unlock_irqrestore(&self->lock, flags);
++}
++
+ 
+ /*
+  * Function smsc_ircc_net_open (dev)
+@@ -1567,7 +1601,6 @@ static int smsc_ircc_net_open(struct net
+ {
+ 	struct smsc_ircc_cb *self;
+ 	char hwname[16];
+-	unsigned long flags;
+ 
+ 	IRDA_DEBUG(1, "%s\n", __FUNCTION__);
+ 
+@@ -1575,6 +1608,11 @@ static int smsc_ircc_net_open(struct net
+ 	self = netdev_priv(dev);
+ 	IRDA_ASSERT(self != NULL, return 0;);
+ 
++	if (self->io.suspended) {
++		IRDA_DEBUG(0, "%s(), device is suspended\n", __FUNCTION__);
++		return -EAGAIN;
++	}
++
+ 	if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name,
+ 			(void *) dev)) {
+ 		IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n",
+@@ -1582,11 +1620,7 @@ static int smsc_ircc_net_open(struct net
+ 		return -EAGAIN;
+ 	}
+ 
+-	spin_lock_irqsave(&self->lock, flags);
+-	/*smsc_ircc_sir_start(self);*/
+-	self->io.speed = 0;
+-	smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
+-	spin_unlock_irqrestore(&self->lock, flags);
++	smsc_ircc_start_interrupts(self);
+ 
+ 	/* Give self a hardware name */
+ 	/* It would be cool to offer the chip revision here - Jean II */
+@@ -1639,37 +1673,63 @@ static int smsc_ircc_net_close(struct ne
+ 		irlap_close(self->irlap);
+ 	self->irlap = NULL;
+ 
+-	free_irq(self->io.irq, dev);
++	smsc_ircc_stop_interrupts(self);
++
++	/* if we are called from smsc_ircc_resume we don't have IRQ reserved */
++	if (!self->io.suspended)
++		free_irq(self->io.irq, dev);
++
+ 	disable_dma(self->io.dma);
+ 	free_dma(self->io.dma);
+ 
+ 	return 0;
+ }
+ 
+-static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level)
++static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct smsc_ircc_cb *self = dev_get_drvdata(dev);
+ 
+-	IRDA_MESSAGE("%s, Suspending\n", driver_name);
++	if (!self->io.suspended) {
++		IRDA_DEBUG(1, "%s, Suspending\n", driver_name);
+ 
+-	if (level == SUSPEND_DISABLE && !self->io.suspended) {
+-		smsc_ircc_net_close(self->netdev);
++		rtnl_lock();
++		if (netif_running(self->netdev)) {
++			netif_device_detach(self->netdev);
++			smsc_ircc_stop_interrupts(self);
++			free_irq(self->io.irq, self->netdev);
++			disable_dma(self->io.dma);
++		}
+ 		self->io.suspended = 1;
++		rtnl_unlock();
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-static int smsc_ircc_resume(struct device *dev, u32 level)
++static int smsc_ircc_resume(struct device *dev)
+ {
+ 	struct smsc_ircc_cb *self = dev_get_drvdata(dev);
+ 
+-	if (level == RESUME_ENABLE && self->io.suspended) {
++	if (self->io.suspended) {
++		IRDA_DEBUG(1, "%s, Waking up\n", driver_name);
+ 
+-		smsc_ircc_net_open(self->netdev);
++		rtnl_lock();
++		smsc_ircc_init_chip(self);
++		if (netif_running(self->netdev)) {
++			if (smsc_ircc_request_irq(self)) {
++				/*
++				 * Don't fail resume process, just kill this
++				 * network interface
++				 */
++				unregister_netdevice(self->netdev);
++			} else {
++				enable_dma(self->io.dma);
++				smsc_ircc_start_interrupts(self);
++				netif_device_attach(self->netdev);
++			}
++		}
+ 		self->io.suspended = 0;
+-
+-		IRDA_MESSAGE("%s, Waking up\n", driver_name);
++		rtnl_unlock();
+ 	}
+ 	return 0;
+ }
+@@ -1682,9 +1742,6 @@ static int smsc_ircc_resume(struct devic
+  */
+ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
+ {
+-	int iobase;
+-	unsigned long flags;
+-
+ 	IRDA_DEBUG(1, "%s\n", __FUNCTION__);
+ 
+ 	IRDA_ASSERT(self != NULL, return -1;);
+@@ -1694,22 +1751,7 @@ static int __exit smsc_ircc_close(struct
+ 	/* Remove netdevice */
+ 	unregister_netdev(self->netdev);
+ 
+-	/* Make sure the irq handler is not exectuting */
+-	spin_lock_irqsave(&self->lock, flags);
+-
+-	/* Stop interrupts */
+-	iobase = self->io.fir_base;
+-	register_bank(iobase, 0);
+-	outb(0, iobase + IRCC_IER);
+-	outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
+-	outb(0x00, iobase + IRCC_MASTER);
+-#if 0
+-	/* Reset to SIR mode */
+-	register_bank(iobase, 1);
+-        outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase + IRCC_SCE_CFGA);
+-        outb(IRCC_CFGB_IR, iobase + IRCC_SCE_CFGB);
+-#endif
+-	spin_unlock_irqrestore(&self->lock, flags);
++	smsc_ircc_stop_interrupts(self);
+ 
+ 	/* Release the PORTS that this driver is using */
+ 	IRDA_DEBUG(0, "%s(), releasing 0x%03x\n",  __FUNCTION__,
+diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
+--- a/drivers/net/irda/stir4200.c
++++ b/drivers/net/irda/stir4200.c
+@@ -678,10 +678,9 @@ static void turnaround_delay(const struc
+ 		return;
+ 
+ 	ticks = us / (1000000 / HZ);
+-	if (ticks > 0) {
+-		current->state = TASK_INTERRUPTIBLE;
+-		schedule_timeout(1 + ticks);
+-	} else
++	if (ticks > 0)
++		schedule_timeout_interruptible(1 + ticks);
++	else
+ 		udelay(us);
+ }
+ 
+diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
+--- a/drivers/net/irda/vlsi_ir.c
++++ b/drivers/net/irda/vlsi_ir.c
+@@ -473,8 +473,7 @@ static int vlsi_free_ring(struct vlsi_ri
+ 		rd_set_addr_status(rd, 0, 0);
+ 		if (busaddr)
+ 			pci_unmap_single(r->pdev, busaddr, r->len, r->dir);
+-		if (rd->buf)
+-			kfree(rd->buf);
++		kfree(rd->buf);
+ 	}
+ 	kfree(r);
+ 	return 0;
+diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
+--- a/drivers/net/iseries_veth.c
++++ b/drivers/net/iseries_veth.c
+@@ -70,8 +70,9 @@
+ #include <linux/delay.h>
+ #include <linux/mm.h>
+ #include <linux/ethtool.h>
++
++#include <asm/abs_addr.h>
+ #include <asm/iSeries/mf.h>
+-#include <asm/iSeries/iSeries_pci.h>
+ #include <asm/uaccess.h>
+ 
+ #include <asm/iSeries/HvLpConfig.h>
+@@ -1397,13 +1398,13 @@ static inline void veth_build_dma_list(s
+ 	 * it just at the granularity of iSeries real->absolute
+ 	 * mapping?  Indeed, given the way the allocator works, can we
+ 	 * count on them being absolutely contiguous? */
+-	list[0].addr = ISERIES_HV_ADDR(p);
++	list[0].addr = iseries_hv_addr(p);
+ 	list[0].size = min(length,
+ 			   PAGE_SIZE - ((unsigned long)p & ~PAGE_MASK));
+ 
+ 	done = list[0].size;
+ 	while (done < length) {
+-		list[i].addr = ISERIES_HV_ADDR(p + done);
++		list[i].addr = iseries_hv_addr(p + done);
+ 		list[i].size = min(length-done, PAGE_SIZE);
+ 		done += list[i].size;
+ 		i++;
+@@ -1496,8 +1497,8 @@ static void veth_receive(struct veth_lpa
+ 					    cnx->dst_inst,
+ 					    HvLpDma_AddressType_RealAddress,
+ 					    HvLpDma_AddressType_TceIndex,
+-					    ISERIES_HV_ADDR(&local_list),
+-					    ISERIES_HV_ADDR(&remote_list),
++					    iseries_hv_addr(&local_list),
++					    iseries_hv_addr(&remote_list),
+ 					    length);
+ 		if (rc != HvLpDma_Rc_Good) {
+ 			dev_kfree_skb_irq(skb);
+@@ -1647,10 +1648,13 @@ static struct vio_device_id veth_device_
+ MODULE_DEVICE_TABLE(vio, veth_device_table);
+ 
+ static struct vio_driver veth_driver = {
+-	.name = DRV_NAME,
+ 	.id_table = veth_device_table,
+ 	.probe = veth_probe,
+-	.remove = veth_remove
++	.remove = veth_remove,
++	.driver = {
++		.name = DRV_NAME,
++		.owner = THIS_MODULE,
++	}
+ };
+ 
+ /*
+diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
+--- a/drivers/net/ixgb/ixgb_ethtool.c
++++ b/drivers/net/ixgb/ixgb_ethtool.c
+@@ -645,11 +645,10 @@ ixgb_phys_id(struct net_device *netdev, 
+ 
+ 	mod_timer(&adapter->blink_timer, jiffies);
+ 
+-	set_current_state(TASK_INTERRUPTIBLE);
+-	if(data)
+-		schedule_timeout(data * HZ);
++	if (data)
++		schedule_timeout_interruptible(data * HZ);
+ 	else
+-		schedule_timeout(MAX_SCHEDULE_TIMEOUT);
++		schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
+ 
+ 	del_timer_sync(&adapter->blink_timer);
+ 	ixgb_led_off(&adapter->hw);
+@@ -723,6 +722,7 @@ struct ethtool_ops ixgb_ethtool_ops = {
+ 	.phys_id = ixgb_phys_id,
+ 	.get_stats_count = ixgb_get_stats_count,
+ 	.get_ethtool_stats = ixgb_get_ethtool_stats,
++	.get_perm_addr = ethtool_op_get_perm_addr,
+ };
+ 
+ void ixgb_set_ethtool_ops(struct net_device *netdev)
+diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
+--- a/drivers/net/ixgb/ixgb_main.c
++++ b/drivers/net/ixgb/ixgb_main.c
+@@ -460,8 +460,9 @@ ixgb_probe(struct pci_dev *pdev,
+ 	}
+ 
+ 	ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
++	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+ 
+-	if(!is_valid_ether_addr(netdev->dev_addr)) {
++	if(!is_valid_ether_addr(netdev->perm_addr)) {
+ 		err = -EIO;
+ 		goto err_eeprom;
+ 	}
+diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
+--- a/drivers/net/jazzsonic.c
++++ b/drivers/net/jazzsonic.c
+@@ -33,7 +33,7 @@
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ 
+ #include <asm/bootinfo.h>
+diff --git a/drivers/net/lance.c b/drivers/net/lance.c
+--- a/drivers/net/lance.c
++++ b/drivers/net/lance.c
+@@ -298,7 +298,7 @@ enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_
+ static unsigned char lance_need_isa_bounce_buffers = 1;
+ 
+ static int lance_open(struct net_device *dev);
+-static void lance_init_ring(struct net_device *dev, int mode);
++static void lance_init_ring(struct net_device *dev, gfp_t mode);
+ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ static int lance_rx(struct net_device *dev);
+ static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+@@ -846,7 +846,7 @@ lance_purge_ring(struct net_device *dev)
+ 
+ /* Initialize the LANCE Rx and Tx rings. */
+ static void
+-lance_init_ring(struct net_device *dev, int gfp)
++lance_init_ring(struct net_device *dev, gfp_t gfp)
+ {
+ 	struct lance_private *lp = dev->priv;
+ 	int i;
+diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
+--- a/drivers/net/lasi_82596.c
++++ b/drivers/net/lasi_82596.c
+@@ -415,6 +415,10 @@ static int rx_ring_size = RX_RING_SIZE;
+ static int ticks_limit = 100;
+ static int max_cmd_backlog = TX_RING_SIZE-1;
+ 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void i596_poll_controller(struct net_device *dev);
++#endif
++
+ 
+ static inline void CA(struct net_device *dev)
+ {
+@@ -636,11 +640,11 @@ static int init_i596_mem(struct net_devi
+ 
+ 	disable_irq(dev->irq);	/* disable IRQs from LAN */
+ 	DEB(DEB_INIT,
+-		printk("RESET 82596 port: %p (with IRQ %d disabled)\n",
+-		       (void*)(dev->base_addr + PA_I82596_RESET),
++		printk("RESET 82596 port: %lx (with IRQ %d disabled)\n",
++		       (dev->base_addr + PA_I82596_RESET),
+ 		       dev->irq));
+ 	
+-	gsc_writel(0, (void*)(dev->base_addr + PA_I82596_RESET)); /* Hard Reset */
++	gsc_writel(0, (dev->base_addr + PA_I82596_RESET)); /* Hard Reset */
+ 	udelay(100);			/* Wait 100us - seems to help */
+ 
+ 	/* change the scp address */
+@@ -1209,6 +1213,9 @@ static int __devinit i82596_probe(struct
+ 	dev->set_multicast_list = set_multicast_list;
+ 	dev->tx_timeout = i596_tx_timeout;
+ 	dev->watchdog_timeo = TX_TIMEOUT;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	dev->poll_controller = i596_poll_controller;
++#endif
+ 
+ 	dev->priv = (void *)(dev->mem_start);
+ 
+@@ -1242,6 +1249,14 @@ static int __devinit i82596_probe(struct
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void i596_poll_controller(struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	i596_interrupt(dev->irq, dev, NULL);
++	enable_irq(dev->irq);
++}
++#endif
+ 
+ static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+@@ -1528,17 +1543,18 @@ lan_init_chip(struct parisc_device *dev)
+ 	
+ 	if (!dev->irq) {
+ 		printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
+-			__FILE__, dev->hpa);
++			__FILE__, dev->hpa.start);
+ 		return -ENODEV;
+ 	}
+ 
+-	printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa, dev->irq);
++	printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start,
++			dev->irq);
+ 
+ 	netdevice = alloc_etherdev(0);
+ 	if (!netdevice)
+ 		return -ENOMEM;
+ 
+-	netdevice->base_addr = dev->hpa;
++	netdevice->base_addr = dev->hpa.start;
+ 	netdevice->irq = dev->irq;
+ 
+ 	retval = i82596_probe(netdevice, &dev->dev);
+@@ -1566,7 +1582,7 @@ static struct parisc_device_id lan_tbl[]
+ MODULE_DEVICE_TABLE(parisc, lan_tbl);
+ 
+ static struct parisc_driver lan_driver = {
+-	.name		= "Apricot",
++	.name		= "lasi_82596",
+ 	.id_table	= lan_tbl,
+ 	.probe		= lan_init_chip,
+ };
+diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
+--- a/drivers/net/lne390.c
++++ b/drivers/net/lne390.c
+@@ -298,7 +298,7 @@ static int __init lne390_probe1(struct n
+ 	return 0;
+ unmap:
+ 	if (ei_status.reg0)
+-		iounmap((void *)dev->mem_start);
++		iounmap(ei_status.mem);
+ cleanup:
+ 	free_irq(dev->irq, dev);
+ 	return ret;
+diff --git a/drivers/net/mace.c b/drivers/net/mace.c
+--- a/drivers/net/mace.c
++++ b/drivers/net/mace.c
+@@ -1016,6 +1016,7 @@ static struct of_device_id mace_match[] 
+ 	},
+ 	{},
+ };
++MODULE_DEVICE_TABLE (of, mace_match);
+ 
+ static struct macio_driver mace_driver = 
+ {
+@@ -1035,10 +1036,8 @@ static void __exit mace_cleanup(void)
+ {
+ 	macio_unregister_driver(&mace_driver);
+ 
+-	if (dummy_buf) {
+-		kfree(dummy_buf);
+-		dummy_buf = NULL;
+-	}
++	kfree(dummy_buf);
++	dummy_buf = NULL;
+ }
+ 
+ MODULE_AUTHOR("Paul Mackerras");
+diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
+--- a/drivers/net/macsonic.c
++++ b/drivers/net/macsonic.c
+@@ -47,7 +47,7 @@
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ 
+ #include <asm/bootinfo.h>
+diff --git a/drivers/net/mii.c b/drivers/net/mii.c
+--- a/drivers/net/mii.c
++++ b/drivers/net/mii.c
+@@ -207,6 +207,20 @@ int mii_ethtool_sset(struct mii_if_info 
+ 	return 0;
+ }
+ 
++int mii_check_gmii_support(struct mii_if_info *mii)
++{
++	int reg;
++
++	reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
++	if (reg & BMSR_ESTATEN) {
++		reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS);
++		if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
++			return 1;
++	}
++
++	return 0;
++}
++
+ int mii_link_ok (struct mii_if_info *mii)
+ {
+ 	/* first, a dummy read, needed to latch some MII phys */
+@@ -394,5 +408,6 @@ EXPORT_SYMBOL(mii_ethtool_gset);
+ EXPORT_SYMBOL(mii_ethtool_sset);
+ EXPORT_SYMBOL(mii_check_link);
+ EXPORT_SYMBOL(mii_check_media);
++EXPORT_SYMBOL(mii_check_gmii_support);
+ EXPORT_SYMBOL(generic_mii_ioctl);
+ 
+diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/mipsnet.c
+@@ -0,0 +1,372 @@
++/*
++ * 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.
++ */
++
++#define DEBUG
++
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/netdevice.h>
++#include <linux/sched.h>
++#include <linux/etherdevice.h>
++#include <linux/netdevice.h>
++#include <linux/platform_device.h>
++#include <asm/io.h>
++#include <asm/mips-boards/simint.h>
++
++#include "mipsnet.h"		/* actual device IO mapping */
++
++#define MIPSNET_VERSION "2005-06-20"
++
++#define mipsnet_reg_address(dev, field) (dev->base_addr + field_offset(field))
++
++struct mipsnet_priv {
++	struct net_device_stats stats;
++};
++
++static struct platform_device *mips_plat_dev;
++
++static char mipsnet_string[] = "mipsnet";
++
++/*
++ * Copy data from the MIPSNET rx data port
++ */
++static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
++			int len)
++{
++	uint32_t available_len = inl(mipsnet_reg_address(dev, rxDataCount));
++	if (available_len < len)
++		return -EFAULT;
++
++	for (; len > 0; len--, kdata++) {
++		*kdata = inb(mipsnet_reg_address(dev, rxDataBuffer));
++	}
++
++	return inl(mipsnet_reg_address(dev, rxDataCount));
++}
++
++static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
++	struct sk_buff *skb)
++{
++	int count_to_go = skb->len;
++	char *buf_ptr = skb->data;
++	struct mipsnet_priv *mp = netdev_priv(dev);
++
++	pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
++	         dev->name, __FUNCTION__, skb->len);
++
++	outl(skb->len, mipsnet_reg_address(dev, txDataCount));
++
++	pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
++	         dev->name, __FUNCTION__, skb->len);
++
++	for (; count_to_go; buf_ptr++, count_to_go--) {
++		outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
++	}
++
++	mp->stats.tx_packets++;
++	mp->stats.tx_bytes += skb->len;
++
++	return skb->len;
++}
++
++static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++	pr_debug("%s:%s(): transmitting %d bytes\n",
++	         dev->name, __FUNCTION__, skb->len);
++
++	/* Only one packet at a time. Once TXDONE interrupt is serviced, the
++	 * queue will be restarted.
++	 */
++	netif_stop_queue(dev);
++	mipsnet_put_todevice(dev, skb);
++
++	return 0;
++}
++
++static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
++{
++	struct sk_buff *skb;
++	size_t len = count;
++	struct mipsnet_priv *mp = netdev_priv(dev);
++
++	if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
++		mp->stats.rx_dropped++;
++		return -ENOMEM;
++	}
++
++	skb_reserve(skb, 2);
++	if (ioiocpy_frommipsnet(dev, skb_put(skb, len), len))
++		return -EFAULT;
++
++	skb->dev = dev;
++	skb->protocol = eth_type_trans(skb, dev);
++	skb->ip_summed = CHECKSUM_UNNECESSARY;
++
++	pr_debug("%s:%s(): pushing RXed data to kernel\n",
++	         dev->name, __FUNCTION__);
++	netif_rx(skb);
++
++	mp->stats.rx_packets++;
++	mp->stats.rx_bytes += len;
++
++	return count;
++}
++
++static irqreturn_t
++mipsnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct net_device *dev = dev_id;
++
++	irqreturn_t retval = IRQ_NONE;
++	uint64_t interruptFlags;
++
++	if (irq == dev->irq) {
++		pr_debug("%s:%s(): irq %d for device\n",
++		         dev->name, __FUNCTION__, irq);
++
++		retval = IRQ_HANDLED;
++
++		interruptFlags =
++		    inl(mipsnet_reg_address(dev, interruptControl));
++		pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
++		         __FUNCTION__, interruptFlags);
++
++		if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
++			pr_debug("%s:%s(): got TXDone\n",
++			         dev->name, __FUNCTION__);
++			outl(MIPSNET_INTCTL_TXDONE,
++			     mipsnet_reg_address(dev, interruptControl));
++			// only one packet at a time, we are done.
++			netif_wake_queue(dev);
++		} else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
++			pr_debug("%s:%s(): got RX data\n",
++			         dev->name, __FUNCTION__);
++			mipsnet_get_fromdev(dev,
++			            inl(mipsnet_reg_address(dev, rxDataCount)));
++			pr_debug("%s:%s(): clearing RX int\n",
++			         dev->name, __FUNCTION__);
++			outl(MIPSNET_INTCTL_RXDONE,
++			     mipsnet_reg_address(dev, interruptControl));
++
++		} else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
++			pr_debug("%s:%s(): got test interrupt\n",
++			         dev->name, __FUNCTION__);
++			// TESTBIT is cleared on read.
++			//    And takes effect after a write with 0
++			outl(0, mipsnet_reg_address(dev, interruptControl));
++		} else {
++			pr_debug("%s:%s(): no valid fags 0x%016llx\n",
++			         dev->name, __FUNCTION__, interruptFlags);
++			// Maybe shared IRQ, just ignore, no clearing.
++			retval = IRQ_NONE;
++		}
++
++	} else {
++		printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
++		       dev->name, __FUNCTION__, irq);
++		retval = IRQ_NONE;
++	}
++	return retval;
++}				//mipsnet_interrupt()
++
++static int mipsnet_open(struct net_device *dev)
++{
++	int err;
++	pr_debug("%s: mipsnet_open\n", dev->name);
++
++	err = request_irq(dev->irq, &mipsnet_interrupt,
++			  SA_SHIRQ, dev->name, (void *) dev);
++
++	if (err) {
++		pr_debug("%s: %s(): can't get irq %d\n",
++		         dev->name, __FUNCTION__, dev->irq);
++		release_region(dev->base_addr, MIPSNET_IO_EXTENT);
++		return err;
++	}
++
++	pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
++	         dev->name, __FUNCTION__, dev->base_addr, dev->irq);
++
++
++	netif_start_queue(dev);
++
++	// test interrupt handler
++	outl(MIPSNET_INTCTL_TESTBIT,
++	     mipsnet_reg_address(dev, interruptControl));
++
++
++	return 0;
++}
++
++static int mipsnet_close(struct net_device *dev)
++{
++	pr_debug("%s: %s()\n", dev->name, __FUNCTION__);
++	netif_stop_queue(dev);
++	return 0;
++}
++
++static struct net_device_stats *mipsnet_get_stats(struct net_device *dev)
++{
++	struct mipsnet_priv *mp = netdev_priv(dev);
++
++	return &mp->stats;
++}
++
++static void mipsnet_set_mclist(struct net_device *dev)
++{
++	// we don't do anything
++	return;
++}
++
++static int __init mipsnet_probe(struct device *dev)
++{
++	struct net_device *netdev;
++	int err;
++
++	netdev = alloc_etherdev(sizeof(struct mipsnet_priv));
++	if (!netdev) {
++		err = -ENOMEM;
++		goto out;
++	}
++
++	dev_set_drvdata(dev, netdev);
++
++	netdev->open			= mipsnet_open;
++	netdev->stop			= mipsnet_close;
++	netdev->hard_start_xmit		= mipsnet_xmit;
++	netdev->get_stats		= mipsnet_get_stats;
++	netdev->set_multicast_list	= mipsnet_set_mclist;
++
++	/*
++	 * TODO: probe for these or load them from PARAM
++	 */
++	netdev->base_addr = 0x4200;
++	netdev->irq = MIPSCPU_INT_BASE + MIPSCPU_INT_MB0 +
++	              inl(mipsnet_reg_address(netdev, interruptInfo));
++
++	// Get the io region now, get irq on open()
++	if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
++		pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
++		         "for dev is not availble.\n", netdev->name,
++		         __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
++		err = -EBUSY;
++		goto out_free_netdev;
++	}
++
++	/*
++	 * Lacking any better mechanism to allocate a MAC address we use a
++	 * random one ...
++	 */
++	random_ether_addr(netdev->dev_addr);
++
++	err = register_netdev(netdev);
++	if (err) {
++		printk(KERN_ERR "MIPSNet: failed to register netdev.\n");
++		goto out_free_region;
++	}
++
++	return 0;
++
++out_free_region:
++	release_region(netdev->base_addr, MIPSNET_IO_EXTENT);
++
++out_free_netdev:
++	free_netdev(netdev);
++
++out:
++	return err;
++}
++
++static int __devexit mipsnet_device_remove(struct device *device)
++{
++	struct net_device *dev = dev_get_drvdata(device);
++
++	unregister_netdev(dev);
++	release_region(dev->base_addr, MIPSNET_IO_EXTENT);
++	free_netdev(dev);
++	dev_set_drvdata(device, NULL);
++
++	return 0;
++}
++
++static struct device_driver mipsnet_driver = {
++	.name	= mipsnet_string,
++	.bus	= &platform_bus_type,
++	.probe	= mipsnet_probe,
++	.remove	= __devexit_p(mipsnet_device_remove),
++};
++
++static void mipsnet_platform_release(struct device *device)
++{
++	struct platform_device *pldev;
++
++	/* free device */
++	pldev = to_platform_device(device);
++	kfree(pldev);
++}
++
++static int __init mipsnet_init_module(void)
++{
++	struct platform_device *pldev;
++	int err;
++
++	printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
++	       "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
++
++	if (driver_register(&mipsnet_driver)) {
++		printk(KERN_ERR "Driver registration failed\n");
++		err = -ENODEV;
++		goto out;
++	}
++
++        if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
++		err = -ENOMEM;
++		goto out_unregister_driver;
++	}
++
++	memset (pldev, 0, sizeof (*pldev));
++	pldev->name		= mipsnet_string;
++	pldev->id		= 0;
++	pldev->dev.release	= mipsnet_platform_release;
++
++	if (platform_device_register(pldev)) {
++		err = -ENODEV;
++		goto out_free_pldev;
++	}
++
++        if (!pldev->dev.driver) {
++		/*
++		 * The driver was not bound to this device, there was
++                 * no hardware at this address. Unregister it, as the
++		 * release fuction will take care of freeing the
++		 * allocated structure
++		 */
++		platform_device_unregister (pldev);
++	}
++
++	mips_plat_dev		= pldev;
++
++	return 0;
++
++out_free_pldev:
++	kfree(pldev);
++
++out_unregister_driver:
++	driver_unregister(&mipsnet_driver);
++out:
++	return err;
++}
++
++static void __exit mipsnet_exit_module(void)
++{
++	pr_debug("MIPSNet Ethernet driver exiting\n");
++
++	driver_unregister(&mipsnet_driver);
++}
++
++module_init(mipsnet_init_module);
++module_exit(mipsnet_exit_module);
+diff --git a/drivers/net/mipsnet.h b/drivers/net/mipsnet.h
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/mipsnet.h
+@@ -0,0 +1,127 @@
++//
++// <COPYRIGHT CLASS="1B" YEAR="2005">
++// Unpublished work (c) MIPS Technologies, Inc.  All rights reserved.
++// Unpublished rights reserved under the copyright laws of the U.S.A. and
++//  other countries.
++//
++// PROPRIETARY / SECRET CONFIDENTIAL INFORMATION OF MIPS TECHNOLOGIES, INC.
++// FOR INTERNAL USE ONLY.
++//
++// Under no circumstances (contract or otherwise) may this information be
++// disclosed to, or copied, modified or used by anyone other than employees
++// or contractors of MIPS Technologies having a need to know.
++// </COPYRIGHT>
++//
++//++
++// File: MIPS_Net.h
++//
++// Description:
++//   The definition of the emulated MIPSNET device's interface.
++//
++// Notes: This include file needs to work from a Linux device drivers.
++//
++//--
++//
++
++#ifndef __MIPSNET_H
++#define __MIPSNET_H
++
++/*
++ *  Id of this Net device, as seen by the core.
++ */
++#define MIPS_NET_DEV_ID ((uint64_t)           \
++	                     ((uint64_t)'M'<< 0)| \
++	                     ((uint64_t)'I'<< 8)| \
++	                     ((uint64_t)'P'<<16)| \
++	                     ((uint64_t)'S'<<24)| \
++	                     ((uint64_t)'N'<<32)| \
++	                     ((uint64_t)'E'<<40)| \
++	                     ((uint64_t)'T'<<48)| \
++	                     ((uint64_t)'0'<<56))
++
++/*
++ * Net status/control block as seen by sw in the core.
++ * (Why not use bit fields? can't be bothered with cross-platform struct
++ *  packing.)
++ */
++typedef struct _net_control_block {
++	/// dev info for probing
++	///  reads as MIPSNET%d where %d is some form of version
++	uint64_t devId;		/*0x00 */
++
++	/*
++	 * read only busy flag.
++	 * Set and cleared by the Net Device to indicate that an rx or a tx
++	 * is in progress.
++	 */
++	uint32_t busy;		/*0x08 */
++
++	/*
++	 * Set by the Net Device.
++	 * The device will set it once data has been received.
++	 * The value is the number of bytes that should be read from
++	 * rxDataBuffer.  The value will decrease till 0 until all the data
++	 * from rxDataBuffer has been read.
++	 */
++	uint32_t rxDataCount;	/*0x0c */
++#define MIPSNET_MAX_RXTX_DATACOUNT (1<<16)
++
++	/*
++	 * Settable from the MIPS core, cleared by the Net Device.
++	 * The core should set the number of bytes it wants to send,
++	 *   then it should write those bytes of data to txDataBuffer.
++	 * The device will clear txDataCount has been processed (not necessarily sent).
++	 */
++	uint32_t txDataCount;	/*0x10 */
++
++	/*
++	 * Interrupt control
++	 *
++	 * Used to clear the interrupted generated by this dev.
++	 * Write a 1 to clear the interrupt. (except bit31).
++	 *
++	 * Bit0 is set if it was a tx-done interrupt.
++	 * Bit1 is set when new rx-data is available.
++	 *      Until this bit is cleared there will be no other RXs.
++	 *
++	 * Bit31 is used for testing, it clears after a read.
++	 *    Writing 1 to this bit will cause an interrupt to be generated.
++	 *    To clear the test interrupt, write 0 to this register.
++	 */
++	uint32_t interruptControl;	/*0x14 */
++#define MIPSNET_INTCTL_TXDONE     ((uint32_t)(1<< 0))
++#define MIPSNET_INTCTL_RXDONE     ((uint32_t)(1<< 1))
++#define MIPSNET_INTCTL_TESTBIT    ((uint32_t)(1<<31))
++#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE|MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TESTBIT)
++
++	/*
++	 * Readonly core-specific interrupt info for the device to signal the core.
++	 * The meaning of the contents of this field might change.
++	 */
++	/*###\todo: the whole memIntf interrupt scheme is messy: the device should have
++	 *  no control what so ever of what VPE/register set is being used.
++	 *  The MemIntf should only expose interrupt lines, and something in the
++	 *  config should be responsible for the line<->core/vpe bindings.
++	 */
++	uint32_t interruptInfo;	/*0x18 */
++
++	/*
++	 *  This is where the received data is read out.
++	 *  There is more data to read until rxDataReady is 0.
++	 *  Only 1 byte at this regs offset is used.
++	 */
++	uint32_t rxDataBuffer;	/*0x1c */
++
++	/*
++	 * This is where the data to transmit is written.
++	 * Data should be written for the amount specified in the txDataCount register.
++	 *  Only 1 byte at this regs offset is used.
++	 */
++	uint32_t txDataBuffer;	/*0x20 */
++} MIPS_T_NetControl;
++
++#define MIPSNET_IO_EXTENT 0x40	/* being generous */
++
++#define field_offset(field) ((int)&((MIPS_T_NetControl*)(0))->field)
++
++#endif /* __MIPSNET_H */
+diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
+--- a/drivers/net/mv643xx_eth.c
++++ b/drivers/net/mv643xx_eth.c
+@@ -39,6 +39,8 @@
+ #include <linux/bitops.h>
+ #include <linux/delay.h>
+ #include <linux/ethtool.h>
++#include <linux/platform_device.h>
++
+ #include <asm/io.h>
+ #include <asm/types.h>
+ #include <asm/pgtable.h>
+@@ -1533,6 +1535,9 @@ static int mv643xx_eth_probe(struct devi
+ 	printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name);
+ #endif
+ 
++	if (mp->tx_sram_size > 0)
++		printk(KERN_NOTICE "%s: Using SRAM\n", dev->name);
++
+ 	return 0;
+ 
+ out:
+diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
+--- a/drivers/net/myri_sbus.c
++++ b/drivers/net/myri_sbus.c
+@@ -277,7 +277,7 @@ static void myri_init_rings(struct myri_
+ 	struct recvq __iomem *rq = mp->rq;
+ 	struct myri_rxd __iomem *rxd = &rq->myri_rxd[0];
+ 	struct net_device *dev = mp->dev;
+-	int gfp_flags = GFP_KERNEL;
++	gfp_t gfp_flags = GFP_KERNEL;
+ 	int i;
+ 
+ 	if (from_irq || in_interrupt())
+diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h
+--- a/drivers/net/myri_sbus.h
++++ b/drivers/net/myri_sbus.h
+@@ -296,7 +296,7 @@ struct myri_eth {
+ /* We use this to acquire receive skb's that we can DMA directly into. */
+ #define ALIGNED_RX_SKB_ADDR(addr) \
+         ((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr))
+-static inline struct sk_buff *myri_alloc_skb(unsigned int length, int gfp_flags)
++static inline struct sk_buff *myri_alloc_skb(unsigned int length, gfp_t gfp_flags)
+ {
+ 	struct sk_buff *skb;
+ 
+diff --git a/drivers/net/ne.c b/drivers/net/ne.c
+--- a/drivers/net/ne.c
++++ b/drivers/net/ne.c
+@@ -54,6 +54,10 @@ static const char version2[] =
+ #include <asm/system.h>
+ #include <asm/io.h>
+ 
++#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
++#include <asm/tx4938/rbtx4938.h>
++#endif
++
+ #include "8390.h"
+ 
+ #define DRV_NAME "ne"
+@@ -111,6 +115,9 @@ bad_clone_list[] __initdata = {
+     {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
+     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
+     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
++#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
++    {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
++#endif
+     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
+     {NULL,}
+ };
+@@ -226,6 +233,10 @@ struct net_device * __init ne_probe(int 
+ 	sprintf(dev->name, "eth%d", unit);
+ 	netdev_boot_setup_check(dev);
+ 
++#ifdef CONFIG_TOSHIBA_RBTX4938
++	dev->base_addr = 0x07f20280;
++	dev->irq = RBTX4938_RTL_8019_IRQ;
++#endif
+ 	err = do_ne_probe(dev);
+ 	if (err)
+ 		goto out;
+@@ -506,6 +517,10 @@ static int __init ne_probe1(struct net_d
+ 	ei_status.name = name;
+ 	ei_status.tx_start_page = start_page;
+ 	ei_status.stop_page = stop_page;
++#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
++	wordlength = 1;
++#endif
++
+ #ifdef CONFIG_PLAT_OAKS32R
+ 	ei_status.word16 = 0;
+ #else
+diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
+--- a/drivers/net/ne2k-pci.c
++++ b/drivers/net/ne2k-pci.c
+@@ -372,6 +372,7 @@ static int __devinit ne2k_pci_init_one (
+ 		printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":");
+ 		dev->dev_addr[i] = SA_prom[i];
+ 	}
++	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+ 	return 0;
+ 
+@@ -637,6 +638,7 @@ static struct ethtool_ops ne2k_pci_ethto
+ 	.get_drvinfo		= ne2k_pci_get_drvinfo,
+ 	.get_tx_csum		= ethtool_op_get_tx_csum,
+ 	.get_sg			= ethtool_op_get_sg,
++	.get_perm_addr		= ethtool_op_get_perm_addr,
+ };
+ 
+ static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
+@@ -673,7 +675,6 @@ static int ne2k_pci_resume (struct pci_d
+ 	pci_set_power_state(pdev, 0);
+ 	pci_restore_state(pdev);
+ 	pci_enable_device(pdev);
+-	pci_set_master(pdev);
+ 	NS8390_init(dev, 1);
+ 	netif_device_attach(dev);
+ 
+diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
+--- a/drivers/net/ni65.c
++++ b/drivers/net/ni65.c
+@@ -696,8 +696,7 @@ static void ni65_free_buffer(struct priv
+ 		return;
+ 
+ 	for(i=0;i<TMDNUM;i++) {
+-		if(p->tmdbounce[i])
+-			kfree(p->tmdbounce[i]);
++		kfree(p->tmdbounce[i]);
+ #ifdef XMT_VIA_SKB
+ 		if(p->tmd_skb[i])
+ 			dev_kfree_skb(p->tmd_skb[i]);
+@@ -710,12 +709,10 @@ static void ni65_free_buffer(struct priv
+ 		if(p->recv_skb[i])
+ 			dev_kfree_skb(p->recv_skb[i]);
+ #else
+-		if(p->recvbounce[i])
+-			kfree(p->recvbounce[i]);
++		kfree(p->recvbounce[i]);
+ #endif
+ 	}
+-	if(p->self)
+-		kfree(p->self);
++	kfree(p->self);
+ }
+ 
+ 
+diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
+--- a/drivers/net/ns83820.c
++++ b/drivers/net/ns83820.c
+@@ -1632,8 +1632,7 @@ static void ns83820_run_bist(struct net_
+ 			timed_out = 1;
+ 			break;
+ 		}
+-		set_current_state(TASK_UNINTERRUPTIBLE);
+-		schedule_timeout(1);
++		schedule_timeout_uninterruptible(1);
+ 	}
+ 
+ 	if (status & fail)
+diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
+--- a/drivers/net/pcmcia/pcnet_cs.c
++++ b/drivers/net/pcmcia/pcnet_cs.c
+@@ -1020,6 +1020,12 @@ static void set_misc_reg(struct net_devi
+ 	} else {
+ 	    outb(full_duplex ? 4 : 0, nic_base + DLINK_DIAG);
+ 	}
++    } else if (info->flags & IS_DL10019) {
++	/* Advertise 100F, 100H, 10F, 10H */
++	mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1);
++	/* Restart MII autonegotiation */
++	mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000);
++	mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200);
+     }
+ }
+ 
+diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
+--- a/drivers/net/pcnet32.c
++++ b/drivers/net/pcnet32.c
+@@ -22,8 +22,8 @@
+  *************************************************************************/
+ 
+ #define DRV_NAME	"pcnet32"
+-#define DRV_VERSION	"1.30j"
+-#define DRV_RELDATE	"29.04.2005"
++#define DRV_VERSION	"1.31a"
++#define DRV_RELDATE	"12.Sep.2005"
+ #define PFX		DRV_NAME ": "
+ 
+ static const char *version =
+@@ -257,6 +257,9 @@ static int homepna[MAX_UNITS];
+  * v1.30h  24 Jun 2004 Don Fry correctly select auto, speed, duplex in bcr32.
+  * v1.30i  28 Jun 2004 Don Fry change to use module_param.
+  * v1.30j  29 Apr 2005 Don Fry fix skb/map leak with loopback test.
++ * v1.31   02 Sep 2005 Hubert WS Lin <wslin at tw.ibm.c0m> added set_ringparam().
++ * v1.31a  12 Sep 2005 Hubert WS Lin <wslin at tw.ibm.c0m> set min ring size to 4
++ *	   to allow loopback test to work unchanged.
+  */
+ 
+ 
+@@ -266,17 +269,17 @@ static int homepna[MAX_UNITS];
+  * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
+  */
+ #ifndef PCNET32_LOG_TX_BUFFERS
+-#define PCNET32_LOG_TX_BUFFERS 4
+-#define PCNET32_LOG_RX_BUFFERS 5
++#define PCNET32_LOG_TX_BUFFERS		4
++#define PCNET32_LOG_RX_BUFFERS		5
++#define PCNET32_LOG_MAX_TX_BUFFERS	9	/* 2^9 == 512 */
++#define PCNET32_LOG_MAX_RX_BUFFERS	9
+ #endif
+ 
+ #define TX_RING_SIZE		(1 << (PCNET32_LOG_TX_BUFFERS))
+-#define TX_RING_MOD_MASK	(TX_RING_SIZE - 1)
+-#define TX_RING_LEN_BITS	((PCNET32_LOG_TX_BUFFERS) << 12)
++#define TX_MAX_RING_SIZE	(1 << (PCNET32_LOG_MAX_TX_BUFFERS))
+ 
+ #define RX_RING_SIZE		(1 << (PCNET32_LOG_RX_BUFFERS))
+-#define RX_RING_MOD_MASK	(RX_RING_SIZE - 1)
+-#define RX_RING_LEN_BITS	((PCNET32_LOG_RX_BUFFERS) << 4)
++#define RX_MAX_RING_SIZE	(1 << (PCNET32_LOG_MAX_RX_BUFFERS))
+ 
+ #define PKT_BUF_SZ		1544
+ 
+@@ -334,14 +337,14 @@ struct pcnet32_access {
+ };
+ 
+ /*
+- * The first three fields of pcnet32_private are read by the ethernet device
+- * so we allocate the structure should be allocated by pci_alloc_consistent().
++ * The first field of pcnet32_private is read by the ethernet device
++ * so the structure should be allocated using pci_alloc_consistent().
+  */
+ struct pcnet32_private {
+-    /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
+-    struct pcnet32_rx_head    rx_ring[RX_RING_SIZE];
+-    struct pcnet32_tx_head    tx_ring[TX_RING_SIZE];
+     struct pcnet32_init_block init_block;
++    /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
++    struct pcnet32_rx_head    *rx_ring;
++    struct pcnet32_tx_head    *tx_ring;
+     dma_addr_t		dma_addr;	/* DMA address of beginning of this
+ 					   object, returned by
+ 					   pci_alloc_consistent */
+@@ -349,13 +352,21 @@ struct pcnet32_private {
+ 					   structure */
+     const char		*name;
+     /* The saved address of a sent-in-place packet/buffer, for skfree(). */
+-    struct sk_buff	*tx_skbuff[TX_RING_SIZE];
+-    struct sk_buff	*rx_skbuff[RX_RING_SIZE];
+-    dma_addr_t		tx_dma_addr[TX_RING_SIZE];
+-    dma_addr_t		rx_dma_addr[RX_RING_SIZE];
++    struct sk_buff	**tx_skbuff;
++    struct sk_buff	**rx_skbuff;
++    dma_addr_t		*tx_dma_addr;
++    dma_addr_t		*rx_dma_addr;
+     struct pcnet32_access	a;
+     spinlock_t		lock;		/* Guard lock */
+     unsigned int	cur_rx, cur_tx;	/* The next free ring entry */
++    unsigned int	rx_ring_size;	/* current rx ring size */
++    unsigned int	tx_ring_size;	/* current tx ring size */
++    unsigned int	rx_mod_mask;	/* rx ring modular mask */
++    unsigned int	tx_mod_mask;	/* tx ring modular mask */
++    unsigned short	rx_len_bits;
++    unsigned short	tx_len_bits;
++    dma_addr_t		rx_ring_dma_addr;
++    dma_addr_t		tx_ring_dma_addr;
+     unsigned int	dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
+     struct net_device_stats stats;
+     char		tx_full;
+@@ -397,6 +408,9 @@ static int pcnet32_get_regs_len(struct n
+ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ 	void *ptr);
+ static void pcnet32_purge_tx_ring(struct net_device *dev);
++static int pcnet32_alloc_ring(struct net_device *dev);
++static void pcnet32_free_ring(struct net_device *dev);
++
+ 
+ enum pci_flags_bit {
+     PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+@@ -613,10 +627,62 @@ static void pcnet32_get_ringparam(struct
+ {
+     struct pcnet32_private *lp = dev->priv;
+ 
+-    ering->tx_max_pending = TX_RING_SIZE - 1;
+-    ering->tx_pending = lp->cur_tx - lp->dirty_tx;
+-    ering->rx_max_pending = RX_RING_SIZE - 1;
+-    ering->rx_pending = lp->cur_rx & RX_RING_MOD_MASK;
++    ering->tx_max_pending = TX_MAX_RING_SIZE - 1;
++    ering->tx_pending = lp->tx_ring_size - 1;
++    ering->rx_max_pending = RX_MAX_RING_SIZE - 1;
++    ering->rx_pending = lp->rx_ring_size - 1;
++}
++
++static int pcnet32_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
++{
++    struct pcnet32_private *lp = dev->priv;
++    unsigned long flags;
++    int i;
++
++    if (ering->rx_mini_pending || ering->rx_jumbo_pending)
++	return -EINVAL;
++
++    if (netif_running(dev))
++	pcnet32_close(dev);
++
++    spin_lock_irqsave(&lp->lock, flags);
++    pcnet32_free_ring(dev);
++    lp->tx_ring_size = min(ering->tx_pending, (unsigned int) TX_MAX_RING_SIZE);
++    lp->rx_ring_size = min(ering->rx_pending, (unsigned int) RX_MAX_RING_SIZE);
++
++    /* set the minimum ring size to 4, to allow the loopback test to work
++     * unchanged.
++     */
++    for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
++	if (lp->tx_ring_size <= (1 << i))
++	    break;
++    }
++    lp->tx_ring_size = (1 << i);
++    lp->tx_mod_mask = lp->tx_ring_size - 1;
++    lp->tx_len_bits = (i << 12);
++
++    for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
++	if (lp->rx_ring_size <= (1 << i))
++	    break;
++    }
++    lp->rx_ring_size = (1 << i);
++    lp->rx_mod_mask = lp->rx_ring_size - 1;
++    lp->rx_len_bits = (i << 4);
++
++    if (pcnet32_alloc_ring(dev)) {
++	pcnet32_free_ring(dev);
++	return -ENOMEM;
++    }
++
++    spin_unlock_irqrestore(&lp->lock, flags);
++
++    if (pcnet32_debug & NETIF_MSG_DRV)
++	printk(KERN_INFO PFX "Ring Param Settings: RX: %d, TX: %d\n", lp->rx_ring_size, lp->tx_ring_size);
++
++    if (netif_running(dev))
++	pcnet32_open(dev);
++
++    return 0;
+ }
+ 
+ static void pcnet32_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+@@ -948,6 +1014,7 @@ static struct ethtool_ops pcnet32_ethtoo
+     .nway_reset		= pcnet32_nway_reset,
+     .get_link		= pcnet32_get_link,
+     .get_ringparam	= pcnet32_get_ringparam,
++    .set_ringparam	= pcnet32_set_ringparam,
+     .get_tx_csum	= ethtool_op_get_tx_csum,
+     .get_sg		= ethtool_op_get_sg,
+     .get_tso		= ethtool_op_get_tso,
+@@ -957,6 +1024,7 @@ static struct ethtool_ops pcnet32_ethtoo
+     .phys_id		= pcnet32_phys_id,
+     .get_regs_len	= pcnet32_get_regs_len,
+     .get_regs		= pcnet32_get_regs,
++    .get_perm_addr	= ethtool_op_get_perm_addr,
+ };
+ 
+ /* only probes for non-PCI devices, the rest are handled by
+@@ -1185,9 +1253,10 @@ pcnet32_probe1(unsigned long ioaddr, int
+ 	    memcpy(dev->dev_addr, promaddr, 6);
+ 	}
+     }
++    memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+     /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
+-    if (!is_valid_ether_addr(dev->dev_addr))
++    if (!is_valid_ether_addr(dev->perm_addr))
+ 	memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
+ 
+     if (pcnet32_debug & NETIF_MSG_PROBE) {
+@@ -1239,6 +1308,12 @@ pcnet32_probe1(unsigned long ioaddr, int
+     dev->priv = lp;
+     lp->name = chipname;
+     lp->shared_irq = shared;
++    lp->tx_ring_size = TX_RING_SIZE;		/* default tx ring size */
++    lp->rx_ring_size = RX_RING_SIZE;		/* default rx ring size */
++    lp->tx_mod_mask = lp->tx_ring_size - 1;
++    lp->rx_mod_mask = lp->rx_ring_size - 1;
++    lp->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 12);
++    lp->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4);
+     lp->mii_if.full_duplex = fdx;
+     lp->mii_if.phy_id_mask = 0x1f;
+     lp->mii_if.reg_num_mask = 0x1f;
+@@ -1265,21 +1340,23 @@ pcnet32_probe1(unsigned long ioaddr, int
+     }
+     lp->a = *a;
+ 
++    if (pcnet32_alloc_ring(dev)) {
++	ret = -ENOMEM;
++	goto err_free_ring;
++    }
+     /* detect special T1/E1 WAN card by checking for MAC address */
+     if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0
+ 	    && dev->dev_addr[2] == 0x75)
+ 	lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
+ 
+     lp->init_block.mode = le16_to_cpu(0x0003);	/* Disable Rx and Tx. */
+-    lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
++    lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
+     for (i = 0; i < 6; i++)
+ 	lp->init_block.phys_addr[i] = dev->dev_addr[i];
+     lp->init_block.filter[0] = 0x00000000;
+     lp->init_block.filter[1] = 0x00000000;
+-    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
+-	    offsetof(struct pcnet32_private, rx_ring));
+-    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
+-	    offsetof(struct pcnet32_private, tx_ring));
++    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
++    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
+ 
+     /* switch pcnet32 to 32bit mode */
+     a->write_bcr(ioaddr, 20, 2);
+@@ -1310,7 +1387,7 @@ pcnet32_probe1(unsigned long ioaddr, int
+ 	    if (pcnet32_debug & NETIF_MSG_PROBE)
+ 		printk(", failed to detect IRQ line.\n");
+ 	    ret = -ENODEV;
+-	    goto err_free_consistent;
++	    goto err_free_ring;
+ 	}
+ 	if (pcnet32_debug & NETIF_MSG_PROBE)
+ 	    printk(", probed IRQ %d.\n", dev->irq);
+@@ -1341,7 +1418,7 @@ pcnet32_probe1(unsigned long ioaddr, int
+ 
+     /* Fill in the generic fields of the device structure. */
+     if (register_netdev(dev))
+-	goto err_free_consistent;
++	goto err_free_ring;
+ 
+     if (pdev) {
+ 	pci_set_drvdata(pdev, dev);
+@@ -1359,6 +1436,8 @@ pcnet32_probe1(unsigned long ioaddr, int
+ 
+     return 0;
+ 
++err_free_ring:
++    pcnet32_free_ring(dev);
+ err_free_consistent:
+     pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
+ err_free_netdev:
+@@ -1369,6 +1448,86 @@ err_release_region:
+ }
+ 
+ 
++static int pcnet32_alloc_ring(struct net_device *dev)
++{
++    struct pcnet32_private *lp = dev->priv;
++
++    if ((lp->tx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
++	&lp->tx_ring_dma_addr)) == NULL) {
++	if (pcnet32_debug & NETIF_MSG_DRV)
++	    printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
++	return -ENOMEM;
++    }
++
++    if ((lp->rx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
++	&lp->rx_ring_dma_addr)) == NULL) {
++	if (pcnet32_debug & NETIF_MSG_DRV)
++	    printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
++	return -ENOMEM;
++    }
++
++    if (!(lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size, GFP_ATOMIC))) {
++	if (pcnet32_debug & NETIF_MSG_DRV)
++	    printk(KERN_ERR PFX "Memory allocation failed.\n");
++	return -ENOMEM;
++    }
++    memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size);
++
++    if (!(lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size, GFP_ATOMIC))) {
++	if (pcnet32_debug & NETIF_MSG_DRV)
++	    printk(KERN_ERR PFX "Memory allocation failed.\n");
++	return -ENOMEM;
++    }
++    memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size);
++
++    if (!(lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size, GFP_ATOMIC))) {
++	if (pcnet32_debug & NETIF_MSG_DRV)
++	    printk(KERN_ERR PFX "Memory allocation failed.\n");
++	return -ENOMEM;
++    }
++    memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size);
++
++    if (!(lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size, GFP_ATOMIC))) {
++	if (pcnet32_debug & NETIF_MSG_DRV)
++	    printk(KERN_ERR PFX "Memory allocation failed.\n");
++	return -ENOMEM;
++    }
++    memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size);
++
++    return 0;
++}
++
++
++static void pcnet32_free_ring(struct net_device *dev)
++{
++    struct pcnet32_private *lp = dev->priv;
++
++    kfree(lp->tx_skbuff);
++    lp->tx_skbuff = NULL;
++
++    kfree(lp->rx_skbuff);
++    lp->rx_skbuff = NULL;
++
++    kfree(lp->tx_dma_addr);
++    lp->tx_dma_addr = NULL;
++
++    kfree(lp->rx_dma_addr);
++    lp->rx_dma_addr = NULL;
++
++    if (lp->tx_ring) {
++	pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
++		lp->tx_ring, lp->tx_ring_dma_addr);
++	lp->tx_ring = NULL;
++    }
++
++    if (lp->rx_ring) {
++	pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
++		lp->rx_ring, lp->rx_ring_dma_addr);
++	lp->rx_ring = NULL;
++    }
++}
++
++
+ static int
+ pcnet32_open(struct net_device *dev)
+ {
+@@ -1400,8 +1559,8 @@ pcnet32_open(struct net_device *dev)
+     if (netif_msg_ifup(lp))
+ 	printk(KERN_DEBUG "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
+ 	       dev->name, dev->irq,
+-	       (u32) (lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)),
+-	       (u32) (lp->dma_addr + offsetof(struct pcnet32_private, rx_ring)),
++	       (u32) (lp->tx_ring_dma_addr),
++	       (u32) (lp->rx_ring_dma_addr),
+ 	       (u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block)));
+ 
+     /* set/reset autoselect bit */
+@@ -1521,7 +1680,7 @@ pcnet32_open(struct net_device *dev)
+ 
+ err_free_ring:
+     /* free any allocated skbuffs */
+-    for (i = 0; i < RX_RING_SIZE; i++) {
++    for (i = 0; i < lp->rx_ring_size; i++) {
+ 	lp->rx_ring[i].status = 0;
+ 	if (lp->rx_skbuff[i]) {
+ 	    pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2,
+@@ -1531,6 +1690,9 @@ err_free_ring:
+ 	lp->rx_skbuff[i] = NULL;
+ 	lp->rx_dma_addr[i] = 0;
+     }
++
++    pcnet32_free_ring(dev);
++
+     /*
+      * Switch back to 16bit mode to avoid problems with dumb
+      * DOS packet driver after a warm reboot
+@@ -1562,7 +1724,7 @@ pcnet32_purge_tx_ring(struct net_device 
+     struct pcnet32_private *lp = dev->priv;
+     int i;
+ 
+-    for (i = 0; i < TX_RING_SIZE; i++) {
++    for (i = 0; i < lp->tx_ring_size; i++) {
+ 	lp->tx_ring[i].status = 0;	/* CPU owns buffer */
+ 	wmb();	/* Make sure adapter sees owner change */
+ 	if (lp->tx_skbuff[i]) {
+@@ -1587,7 +1749,7 @@ pcnet32_init_ring(struct net_device *dev
+     lp->cur_rx = lp->cur_tx = 0;
+     lp->dirty_rx = lp->dirty_tx = 0;
+ 
+-    for (i = 0; i < RX_RING_SIZE; i++) {
++    for (i = 0; i < lp->rx_ring_size; i++) {
+ 	struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
+ 	if (rx_skbuff == NULL) {
+ 	    if (!(rx_skbuff = lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) {
+@@ -1611,20 +1773,18 @@ pcnet32_init_ring(struct net_device *dev
+     }
+     /* The Tx buffer address is filled in as needed, but we do need to clear
+      * the upper ownership bit. */
+-    for (i = 0; i < TX_RING_SIZE; i++) {
++    for (i = 0; i < lp->tx_ring_size; i++) {
+ 	lp->tx_ring[i].status = 0;	/* CPU owns buffer */
+ 	wmb();	/* Make sure adapter sees owner change */
+ 	lp->tx_ring[i].base = 0;
+ 	lp->tx_dma_addr[i] = 0;
+     }
+ 
+-    lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
++    lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
+     for (i = 0; i < 6; i++)
+ 	lp->init_block.phys_addr[i] = dev->dev_addr[i];
+-    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
+-	    offsetof(struct pcnet32_private, rx_ring));
+-    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
+-	    offsetof(struct pcnet32_private, tx_ring));
++    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
++    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
+     wmb();	/* Make sure all changes are visible */
+     return 0;
+ }
+@@ -1682,13 +1842,13 @@ pcnet32_tx_timeout (struct net_device *d
+ 	printk(KERN_DEBUG " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
+ 	   lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
+ 	   lp->cur_rx);
+-	for (i = 0 ; i < RX_RING_SIZE; i++)
++	for (i = 0 ; i < lp->rx_ring_size; i++)
+ 	printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
+ 	       le32_to_cpu(lp->rx_ring[i].base),
+ 	       (-le16_to_cpu(lp->rx_ring[i].buf_length)) & 0xffff,
+ 	       le32_to_cpu(lp->rx_ring[i].msg_length),
+ 	       le16_to_cpu(lp->rx_ring[i].status));
+-	for (i = 0 ; i < TX_RING_SIZE; i++)
++	for (i = 0 ; i < lp->tx_ring_size; i++)
+ 	printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
+ 	       le32_to_cpu(lp->tx_ring[i].base),
+ 	       (-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff,
+@@ -1729,7 +1889,7 @@ pcnet32_start_xmit(struct sk_buff *skb, 
+     /* Fill in a Tx ring entry */
+ 
+     /* Mask to ring buffer boundary. */
+-    entry = lp->cur_tx & TX_RING_MOD_MASK;
++    entry = lp->cur_tx & lp->tx_mod_mask;
+ 
+     /* Caution: the write order is important here, set the status
+      * with the "ownership" bits last. */
+@@ -1753,7 +1913,7 @@ pcnet32_start_xmit(struct sk_buff *skb, 
+ 
+     dev->trans_start = jiffies;
+ 
+-    if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base != 0) {
++    if (lp->tx_ring[(entry+1) & lp->tx_mod_mask].base != 0) {
+ 	lp->tx_full = 1;
+ 	netif_stop_queue(dev);
+     }
+@@ -1806,7 +1966,7 @@ pcnet32_interrupt(int irq, void *dev_id,
+ 	    int delta;
+ 
+ 	    while (dirty_tx != lp->cur_tx) {
+-		int entry = dirty_tx & TX_RING_MOD_MASK;
++		int entry = dirty_tx & lp->tx_mod_mask;
+ 		int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
+ 
+ 		if (status < 0)
+@@ -1864,18 +2024,18 @@ pcnet32_interrupt(int irq, void *dev_id,
+ 		dirty_tx++;
+ 	    }
+ 
+-	    delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE);
+-	    if (delta > TX_RING_SIZE) {
++	    delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
++	    if (delta > lp->tx_ring_size) {
+ 		if (netif_msg_drv(lp))
+ 		    printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
+ 			    dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
+-		dirty_tx += TX_RING_SIZE;
+-		delta -= TX_RING_SIZE;
++		dirty_tx += lp->tx_ring_size;
++		delta -= lp->tx_ring_size;
+ 	    }
+ 
+ 	    if (lp->tx_full &&
+ 		netif_queue_stopped(dev) &&
+-		delta < TX_RING_SIZE - 2) {
++		delta < lp->tx_ring_size - 2) {
+ 		/* The ring is no longer full, clear tbusy. */
+ 		lp->tx_full = 0;
+ 		netif_wake_queue (dev);
+@@ -1932,8 +2092,8 @@ static int
+ pcnet32_rx(struct net_device *dev)
+ {
+     struct pcnet32_private *lp = dev->priv;
+-    int entry = lp->cur_rx & RX_RING_MOD_MASK;
+-    int boguscnt = RX_RING_SIZE / 2;
++    int entry = lp->cur_rx & lp->rx_mod_mask;
++    int boguscnt = lp->rx_ring_size / 2;
+ 
+     /* If we own the next entry, it's a new packet. Send it up. */
+     while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
+@@ -1998,12 +2158,12 @@ pcnet32_rx(struct net_device *dev)
+ 		    if (netif_msg_drv(lp))
+ 			printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n",
+ 				dev->name);
+-		    for (i = 0; i < RX_RING_SIZE; i++)
++		    for (i = 0; i < lp->rx_ring_size; i++)
+ 			if ((short)le16_to_cpu(lp->rx_ring[(entry+i)
+-				    & RX_RING_MOD_MASK].status) < 0)
++				    & lp->rx_mod_mask].status) < 0)
+ 			    break;
+ 
+-		    if (i > RX_RING_SIZE -2) {
++		    if (i > lp->rx_ring_size -2) {
+ 			lp->stats.rx_dropped++;
+ 			lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
+ 			wmb();	/* Make sure adapter sees owner change */
+@@ -2041,7 +2201,7 @@ pcnet32_rx(struct net_device *dev)
+ 	lp->rx_ring[entry].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
+ 	wmb(); /* Make sure owner changes after all others are visible */
+ 	lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
+-	entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
++	entry = (++lp->cur_rx) & lp->rx_mod_mask;
+ 	if (--boguscnt <= 0) break;	/* don't stay in loop forever */
+     }
+ 
+@@ -2084,7 +2244,7 @@ pcnet32_close(struct net_device *dev)
+     spin_lock_irqsave(&lp->lock, flags);
+ 
+     /* free all allocated skbuffs */
+-    for (i = 0; i < RX_RING_SIZE; i++) {
++    for (i = 0; i < lp->rx_ring_size; i++) {
+ 	lp->rx_ring[i].status = 0;
+ 	wmb();		/* Make sure adapter sees owner change */
+ 	if (lp->rx_skbuff[i]) {
+@@ -2096,7 +2256,7 @@ pcnet32_close(struct net_device *dev)
+ 	lp->rx_dma_addr[i] = 0;
+     }
+ 
+-    for (i = 0; i < TX_RING_SIZE; i++) {
++    for (i = 0; i < lp->tx_ring_size; i++) {
+ 	lp->tx_ring[i].status = 0;	/* CPU owns buffer */
+ 	wmb();		/* Make sure adapter sees owner change */
+ 	if (lp->tx_skbuff[i]) {
+@@ -2265,6 +2425,7 @@ static void __devexit pcnet32_remove_one
+ 	struct pcnet32_private *lp = dev->priv;
+ 
+ 	unregister_netdev(dev);
++	pcnet32_free_ring(dev);
+ 	release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
+ 	pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
+ 	free_netdev(dev);
+@@ -2340,6 +2501,7 @@ static void __exit pcnet32_cleanup_modul
+ 	struct pcnet32_private *lp = pcnet32_dev->priv;
+ 	next_dev = lp->next;
+ 	unregister_netdev(pcnet32_dev);
++	pcnet32_free_ring(pcnet32_dev);
+ 	release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
+ 	pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
+ 	free_netdev(pcnet32_dev);
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -12,14 +12,6 @@ config PHYLIB
+ 	  devices.  This option provides infrastructure for
+ 	  managing PHY devices.
+ 
+-config PHYCONTROL
+-	bool "  Support for automatically handling PHY state changes"
+-	depends on PHYLIB
+-	help
+-	  Adds code to perform all the work for keeping PHY link
+-	  state (speed/duplex/etc) up-to-date.  Also handles
+-	  interrupts.
+-
+ comment "MII PHY device drivers"
+ 	depends on PHYLIB
+ 
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -133,13 +133,9 @@ static int mdio_bus_suspend(struct devic
+ 	int ret = 0;
+ 	struct device_driver *drv = dev->driver;
+ 
+-	if (drv && drv->suspend) {
+-		ret = drv->suspend(dev, state, SUSPEND_DISABLE);
+-		if (ret == 0)
+-			ret = drv->suspend(dev, state, SUSPEND_SAVE_STATE);
+-		if (ret == 0)
+-			ret = drv->suspend(dev, state, SUSPEND_POWER_DOWN);
+-	}
++	if (drv && drv->suspend)
++		ret = drv->suspend(dev, state);
++
+ 	return ret;
+ }
+ 
+@@ -148,13 +144,9 @@ static int mdio_bus_resume(struct device
+ 	int ret = 0;
+ 	struct device_driver *drv = dev->driver;
+ 
+-	if (drv && drv->resume) {
+-		ret = drv->resume(dev, RESUME_POWER_ON);
+-		if (ret == 0)
+-			ret = drv->resume(dev, RESUME_RESTORE_STATE);
+-		if (ret == 0)
+-			ret = drv->resume(dev, RESUME_ENABLE);
+-	}
++	if (drv && drv->resume)
++		ret = drv->resume(dev);
++
+ 	return ret;
+ }
+ 
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -242,10 +242,6 @@ EXPORT_SYMBOL(phy_sanitize_settings);
+  *   choose the next best ones from the ones selected, so we don't
+  *   care if ethtool tries to give us bad values
+  *
+- * A note about the PHYCONTROL Layer.  If you turn off
+- * CONFIG_PHYCONTROL, you will need to read the PHY status
+- * registers after this function completes, and update your
+- * controller manually.
+  */
+ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
+ {
+@@ -380,7 +376,6 @@ int phy_start_aneg(struct phy_device *ph
+ 
+ 	err = phydev->drv->config_aneg(phydev);
+ 
+-#ifdef CONFIG_PHYCONTROL
+ 	if (err < 0)
+ 		goto out_unlock;
+ 
+@@ -395,14 +390,12 @@ int phy_start_aneg(struct phy_device *ph
+ 	}
+ 
+ out_unlock:
+-#endif
+ 	spin_unlock(&phydev->lock);
+ 	return err;
+ }
+ EXPORT_SYMBOL(phy_start_aneg);
+ 
+ 
+-#ifdef CONFIG_PHYCONTROL
+ static void phy_change(void *data);
+ static void phy_timer(unsigned long data);
+ 
+@@ -868,4 +861,3 @@ static void phy_timer(unsigned long data
+ 	mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
+ }
+ 
+-#endif /* CONFIG_PHYCONTROL */
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -101,7 +101,6 @@ struct phy_device * get_phy_device(struc
+ 	return dev;
+ }
+ 
+-#ifdef CONFIG_PHYCONTROL
+ /* phy_prepare_link:
+  *
+  * description: Tells the PHY infrastructure to handle the
+@@ -160,8 +159,6 @@ void phy_disconnect(struct phy_device *p
+ }
+ EXPORT_SYMBOL(phy_disconnect);
+ 
+-#endif /* CONFIG_PHYCONTROL */
+-
+ /* phy_attach:
+  *
+  *   description: Called by drivers to attach to a particular PHY
+diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
+--- a/drivers/net/ppp_generic.c
++++ b/drivers/net/ppp_generic.c
+@@ -863,7 +863,7 @@ static int __init ppp_init(void)
+ 			err = PTR_ERR(ppp_class);
+ 			goto out_chrdev;
+ 		}
+-		class_device_create(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
++		class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
+ 		err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0),
+ 				S_IFCHR|S_IRUSR|S_IWUSR, "ppp");
+ 		if (err)
+diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -1027,6 +1027,7 @@ static struct ethtool_ops rtl8169_ethtoo
+ 	.get_strings		= rtl8169_get_strings,
+ 	.get_stats_count	= rtl8169_get_stats_count,
+ 	.get_ethtool_stats	= rtl8169_get_ethtool_stats,
++	.get_perm_addr		= ethtool_op_get_perm_addr,
+ };
+ 
+ static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
+@@ -1511,6 +1512,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
+ 	/* Get MAC address.  FIXME: read EEPROM */
+ 	for (i = 0; i < MAC_ADDR_LEN; i++)
+ 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
++	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+ 	dev->open = rtl8169_open;
+ 	dev->hard_start_xmit = rtl8169_start_xmit;
+diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/net/rionet.c
+@@ -0,0 +1,574 @@
++/*
++ * rionet - Ethernet driver over RapidIO messaging services
++ *
++ * Copyright 2005 MontaVista Software, Inc.
++ * Matt Porter <mporter at 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/module.h>
++#include <linux/kernel.h>
++#include <linux/dma-mapping.h>
++#include <linux/delay.h>
++#include <linux/rio.h>
++#include <linux/rio_drv.h>
++#include <linux/rio_ids.h>
++
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/crc32.h>
++#include <linux/ethtool.h>
++
++#define DRV_NAME        "rionet"
++#define DRV_VERSION     "0.2"
++#define DRV_AUTHOR      "Matt Porter <mporter at kernel.crashing.org>"
++#define DRV_DESC        "Ethernet over RapidIO"
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESC);
++MODULE_LICENSE("GPL");
++
++#define RIONET_DEFAULT_MSGLEVEL \
++			(NETIF_MSG_DRV          | \
++			 NETIF_MSG_LINK         | \
++			 NETIF_MSG_RX_ERR       | \
++			 NETIF_MSG_TX_ERR)
++
++#define RIONET_DOORBELL_JOIN	0x1000
++#define RIONET_DOORBELL_LEAVE	0x1001
++
++#define RIONET_MAILBOX		0
++
++#define RIONET_TX_RING_SIZE	CONFIG_RIONET_TX_SIZE
++#define RIONET_RX_RING_SIZE	CONFIG_RIONET_RX_SIZE
++
++static LIST_HEAD(rionet_peers);
++
++struct rionet_private {
++	struct rio_mport *mport;
++	struct sk_buff *rx_skb[RIONET_RX_RING_SIZE];
++	struct sk_buff *tx_skb[RIONET_TX_RING_SIZE];
++	struct net_device_stats stats;
++	int rx_slot;
++	int tx_slot;
++	int tx_cnt;
++	int ack_slot;
++	spinlock_t lock;
++	spinlock_t tx_lock;
++	u32 msg_enable;
++};
++
++struct rionet_peer {
++	struct list_head node;
++	struct rio_dev *rdev;
++	struct resource *res;
++};
++
++static int rionet_check = 0;
++static int rionet_capable = 1;
++
++/*
++ * This is a fast lookup table for for translating TX
++ * Ethernet packets into a destination RIO device. It
++ * could be made into a hash table to save memory depending
++ * on system trade-offs.
++ */
++static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES];
++
++#define is_rionet_capable(pef, src_ops, dst_ops)		\
++			((pef & RIO_PEF_INB_MBOX) &&		\
++			 (pef & RIO_PEF_INB_DOORBELL) &&	\
++			 (src_ops & RIO_SRC_OPS_DOORBELL) &&	\
++			 (dst_ops & RIO_DST_OPS_DOORBELL))
++#define dev_rionet_capable(dev) \
++	is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops)
++
++#define RIONET_MAC_MATCH(x)	(*(u32 *)x == 0x00010001)
++#define RIONET_GET_DESTID(x)	(*(u16 *)(x + 4))
++
++static struct net_device_stats *rionet_stats(struct net_device *ndev)
++{
++	struct rionet_private *rnet = ndev->priv;
++	return &rnet->stats;
++}
++
++static int rionet_rx_clean(struct net_device *ndev)
++{
++	int i;
++	int error = 0;
++	struct rionet_private *rnet = ndev->priv;
++	void *data;
++
++	i = rnet->rx_slot;
++
++	do {
++		if (!rnet->rx_skb[i])
++			continue;
++
++		if (!(data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX)))
++			break;
++
++		rnet->rx_skb[i]->data = data;
++		skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE);
++		rnet->rx_skb[i]->dev = ndev;
++		rnet->rx_skb[i]->protocol =
++		    eth_type_trans(rnet->rx_skb[i], ndev);
++		error = netif_rx(rnet->rx_skb[i]);
++
++		if (error == NET_RX_DROP) {
++			rnet->stats.rx_dropped++;
++		} else if (error == NET_RX_BAD) {
++			if (netif_msg_rx_err(rnet))
++				printk(KERN_WARNING "%s: bad rx packet\n",
++				       DRV_NAME);
++			rnet->stats.rx_errors++;
++		} else {
++			rnet->stats.rx_packets++;
++			rnet->stats.rx_bytes += RIO_MAX_MSG_SIZE;
++		}
++
++	} while ((i = (i + 1) % RIONET_RX_RING_SIZE) != rnet->rx_slot);
++
++	return i;
++}
++
++static void rionet_rx_fill(struct net_device *ndev, int end)
++{
++	int i;
++	struct rionet_private *rnet = ndev->priv;
++
++	i = rnet->rx_slot;
++	do {
++		rnet->rx_skb[i] = dev_alloc_skb(RIO_MAX_MSG_SIZE);
++
++		if (!rnet->rx_skb[i])
++			break;
++
++		rio_add_inb_buffer(rnet->mport, RIONET_MAILBOX,
++				   rnet->rx_skb[i]->data);
++	} while ((i = (i + 1) % RIONET_RX_RING_SIZE) != end);
++
++	rnet->rx_slot = i;
++}
++
++static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
++			       struct rio_dev *rdev)
++{
++	struct rionet_private *rnet = ndev->priv;
++
++	rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len);
++	rnet->tx_skb[rnet->tx_slot] = skb;
++
++	rnet->stats.tx_packets++;
++	rnet->stats.tx_bytes += skb->len;
++
++	if (++rnet->tx_cnt == RIONET_TX_RING_SIZE)
++		netif_stop_queue(ndev);
++
++	++rnet->tx_slot;
++	rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
++
++	if (netif_msg_tx_queued(rnet))
++		printk(KERN_INFO "%s: queued skb %8.8x len %8.8x\n", DRV_NAME,
++		       (u32) skb, skb->len);
++
++	return 0;
++}
++
++static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++	int i;
++	struct rionet_private *rnet = ndev->priv;
++	struct ethhdr *eth = (struct ethhdr *)skb->data;
++	u16 destid;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	if (!spin_trylock(&rnet->tx_lock)) {
++		local_irq_restore(flags);
++		return NETDEV_TX_LOCKED;
++	}
++
++	if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
++		netif_stop_queue(ndev);
++		spin_unlock_irqrestore(&rnet->tx_lock, flags);
++		printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
++		       ndev->name);
++		return NETDEV_TX_BUSY;
++	}
++
++	if (eth->h_dest[0] & 0x01) {
++		for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++)
++			if (rionet_active[i])
++				rionet_queue_tx_msg(skb, ndev,
++						    rionet_active[i]);
++	} else if (RIONET_MAC_MATCH(eth->h_dest)) {
++		destid = RIONET_GET_DESTID(eth->h_dest);
++		if (rionet_active[destid])
++			rionet_queue_tx_msg(skb, ndev, rionet_active[destid]);
++	}
++
++	spin_unlock_irqrestore(&rnet->tx_lock, flags);
++
++	return 0;
++}
++
++static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid,
++			       u16 info)
++{
++	struct net_device *ndev = dev_id;
++	struct rionet_private *rnet = ndev->priv;
++	struct rionet_peer *peer;
++
++	if (netif_msg_intr(rnet))
++		printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
++		       DRV_NAME, sid, tid, info);
++	if (info == RIONET_DOORBELL_JOIN) {
++		if (!rionet_active[sid]) {
++			list_for_each_entry(peer, &rionet_peers, node) {
++				if (peer->rdev->destid == sid)
++					rionet_active[sid] = peer->rdev;
++			}
++			rio_mport_send_doorbell(mport, sid,
++						RIONET_DOORBELL_JOIN);
++		}
++	} else if (info == RIONET_DOORBELL_LEAVE) {
++		rionet_active[sid] = NULL;
++	} else {
++		if (netif_msg_intr(rnet))
++			printk(KERN_WARNING "%s: unhandled doorbell\n",
++			       DRV_NAME);
++	}
++}
++
++static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
++{
++	int n;
++	struct net_device *ndev = dev_id;
++	struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
++
++	if (netif_msg_intr(rnet))
++		printk(KERN_INFO "%s: inbound message event, mbox %d slot %d\n",
++		       DRV_NAME, mbox, slot);
++
++	spin_lock(&rnet->lock);
++	if ((n = rionet_rx_clean(ndev)) != rnet->rx_slot)
++		rionet_rx_fill(ndev, n);
++	spin_unlock(&rnet->lock);
++}
++
++static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
++{
++	struct net_device *ndev = dev_id;
++	struct rionet_private *rnet = ndev->priv;
++
++	spin_lock(&rnet->lock);
++
++	if (netif_msg_intr(rnet))
++		printk(KERN_INFO
++		       "%s: outbound message event, mbox %d slot %d\n",
++		       DRV_NAME, mbox, slot);
++
++	while (rnet->tx_cnt && (rnet->ack_slot != slot)) {
++		/* dma unmap single */
++		dev_kfree_skb_irq(rnet->tx_skb[rnet->ack_slot]);
++		rnet->tx_skb[rnet->ack_slot] = NULL;
++		++rnet->ack_slot;
++		rnet->ack_slot &= (RIONET_TX_RING_SIZE - 1);
++		rnet->tx_cnt--;
++	}
++
++	if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
++		netif_wake_queue(ndev);
++
++	spin_unlock(&rnet->lock);
++}
++
++static int rionet_open(struct net_device *ndev)
++{
++	int i, rc = 0;
++	struct rionet_peer *peer, *tmp;
++	u32 pwdcsr;
++	struct rionet_private *rnet = ndev->priv;
++
++	if (netif_msg_ifup(rnet))
++		printk(KERN_INFO "%s: open\n", DRV_NAME);
++
++	if ((rc = rio_request_inb_dbell(rnet->mport,
++					(void *)ndev,
++					RIONET_DOORBELL_JOIN,
++					RIONET_DOORBELL_LEAVE,
++					rionet_dbell_event)) < 0)
++		goto out;
++
++	if ((rc = rio_request_inb_mbox(rnet->mport,
++				       (void *)ndev,
++				       RIONET_MAILBOX,
++				       RIONET_RX_RING_SIZE,
++				       rionet_inb_msg_event)) < 0)
++		goto out;
++
++	if ((rc = rio_request_outb_mbox(rnet->mport,
++					(void *)ndev,
++					RIONET_MAILBOX,
++					RIONET_TX_RING_SIZE,
++					rionet_outb_msg_event)) < 0)
++		goto out;
++
++	/* Initialize inbound message ring */
++	for (i = 0; i < RIONET_RX_RING_SIZE; i++)
++		rnet->rx_skb[i] = NULL;
++	rnet->rx_slot = 0;
++	rionet_rx_fill(ndev, 0);
++
++	rnet->tx_slot = 0;
++	rnet->tx_cnt = 0;
++	rnet->ack_slot = 0;
++
++	netif_carrier_on(ndev);
++	netif_start_queue(ndev);
++
++	list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
++		if (!(peer->res = rio_request_outb_dbell(peer->rdev,
++							 RIONET_DOORBELL_JOIN,
++							 RIONET_DOORBELL_LEAVE)))
++		{
++			printk(KERN_ERR "%s: error requesting doorbells\n",
++			       DRV_NAME);
++			continue;
++		}
++
++		/*
++		 * If device has initialized inbound doorbells,
++		 * send a join message
++		 */
++		rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr);
++		if (pwdcsr & RIO_DOORBELL_AVAIL)
++			rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
++	}
++
++      out:
++	return rc;
++}
++
++static int rionet_close(struct net_device *ndev)
++{
++	struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
++	struct rionet_peer *peer, *tmp;
++	int i;
++
++	if (netif_msg_ifup(rnet))
++		printk(KERN_INFO "%s: close\n", DRV_NAME);
++
++	netif_stop_queue(ndev);
++	netif_carrier_off(ndev);
++
++	for (i = 0; i < RIONET_RX_RING_SIZE; i++)
++		if (rnet->rx_skb[i])
++			kfree_skb(rnet->rx_skb[i]);
++
++	list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
++		if (rionet_active[peer->rdev->destid]) {
++			rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE);
++			rionet_active[peer->rdev->destid] = NULL;
++		}
++		rio_release_outb_dbell(peer->rdev, peer->res);
++	}
++
++	rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN,
++			      RIONET_DOORBELL_LEAVE);
++	rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX);
++	rio_release_outb_mbox(rnet->mport, RIONET_MAILBOX);
++
++	return 0;
++}
++
++static void rionet_remove(struct rio_dev *rdev)
++{
++	struct net_device *ndev = NULL;
++	struct rionet_peer *peer, *tmp;
++
++	unregister_netdev(ndev);
++	kfree(ndev);
++
++	list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
++		list_del(&peer->node);
++		kfree(peer);
++	}
++}
++
++static void rionet_get_drvinfo(struct net_device *ndev,
++			       struct ethtool_drvinfo *info)
++{
++	struct rionet_private *rnet = ndev->priv;
++
++	strcpy(info->driver, DRV_NAME);
++	strcpy(info->version, DRV_VERSION);
++	strcpy(info->fw_version, "n/a");
++	strcpy(info->bus_info, rnet->mport->name);
++}
++
++static u32 rionet_get_msglevel(struct net_device *ndev)
++{
++	struct rionet_private *rnet = ndev->priv;
++
++	return rnet->msg_enable;
++}
++
++static void rionet_set_msglevel(struct net_device *ndev, u32 value)
++{
++	struct rionet_private *rnet = ndev->priv;
++
++	rnet->msg_enable = value;
++}
++
++static struct ethtool_ops rionet_ethtool_ops = {
++	.get_drvinfo = rionet_get_drvinfo,
++	.get_msglevel = rionet_get_msglevel,
++	.set_msglevel = rionet_set_msglevel,
++	.get_link = ethtool_op_get_link,
++};
++
++static int rionet_setup_netdev(struct rio_mport *mport)
++{
++	int rc = 0;
++	struct net_device *ndev = NULL;
++	struct rionet_private *rnet;
++	u16 device_id;
++
++	/* Allocate our net_device structure */
++	ndev = alloc_etherdev(sizeof(struct rionet_private));
++	if (ndev == NULL) {
++		printk(KERN_INFO "%s: could not allocate ethernet device.\n",
++		       DRV_NAME);
++		rc = -ENOMEM;
++		goto out;
++	}
++
++	/* Set up private area */
++	rnet = (struct rionet_private *)ndev->priv;
++	rnet->mport = mport;
++
++	/* Set the default MAC address */
++	device_id = rio_local_get_device_id(mport);
++	ndev->dev_addr[0] = 0x00;
++	ndev->dev_addr[1] = 0x01;
++	ndev->dev_addr[2] = 0x00;
++	ndev->dev_addr[3] = 0x01;
++	ndev->dev_addr[4] = device_id >> 8;
++	ndev->dev_addr[5] = device_id & 0xff;
++
++	/* Fill in the driver function table */
++	ndev->open = &rionet_open;
++	ndev->hard_start_xmit = &rionet_start_xmit;
++	ndev->stop = &rionet_close;
++	ndev->get_stats = &rionet_stats;
++	ndev->mtu = RIO_MAX_MSG_SIZE - 14;
++	ndev->features = NETIF_F_LLTX;
++	SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
++
++	SET_MODULE_OWNER(ndev);
++
++	spin_lock_init(&rnet->lock);
++	spin_lock_init(&rnet->tx_lock);
++
++	rnet->msg_enable = RIONET_DEFAULT_MSGLEVEL;
++
++	rc = register_netdev(ndev);
++	if (rc != 0)
++		goto out;
++
++	printk("%s: %s %s Version %s, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
++	       ndev->name,
++	       DRV_NAME,
++	       DRV_DESC,
++	       DRV_VERSION,
++	       ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
++	       ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
++
++      out:
++	return rc;
++}
++
++/*
++ * XXX Make multi-net safe
++ */
++static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
++{
++	int rc = -ENODEV;
++	u32 lpef, lsrc_ops, ldst_ops;
++	struct rionet_peer *peer;
++
++	/* If local device is not rionet capable, give up quickly */
++	if (!rionet_capable)
++		goto out;
++
++	/*
++	 * First time through, make sure local device is rionet
++	 * capable, setup netdev,  and set flags so this is skipped
++	 * on later probes
++	 */
++	if (!rionet_check) {
++		rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef);
++		rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
++					 &lsrc_ops);
++		rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
++					 &ldst_ops);
++		if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) {
++			printk(KERN_ERR
++			       "%s: local device is not network capable\n",
++			       DRV_NAME);
++			rionet_check = 1;
++			rionet_capable = 0;
++			goto out;
++		}
++
++		rc = rionet_setup_netdev(rdev->net->hport);
++		rionet_check = 1;
++	}
++
++	/*
++	 * If the remote device has mailbox/doorbell capabilities,
++	 * add it to the peer list.
++	 */
++	if (dev_rionet_capable(rdev)) {
++		if (!(peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL))) {
++			rc = -ENOMEM;
++			goto out;
++		}
++		peer->rdev = rdev;
++		list_add_tail(&peer->node, &rionet_peers);
++	}
++
++      out:
++	return rc;
++}
++
++static struct rio_device_id rionet_id_table[] = {
++	{RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}
++};
++
++static struct rio_driver rionet_driver = {
++	.name = "rionet",
++	.id_table = rionet_id_table,
++	.probe = rionet_probe,
++	.remove = rionet_remove,
++};
++
++static int __init rionet_init(void)
++{
++	return rio_register_driver(&rionet_driver);
++}
++
++static void __exit rionet_exit(void)
++{
++	rio_unregister_driver(&rionet_driver);
++}
++
++module_init(rionet_init);
++module_exit(rionet_exit);
+diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
+--- a/drivers/net/rrunner.c
++++ b/drivers/net/rrunner.c
+@@ -1710,10 +1710,8 @@ static int rr_ioctl(struct net_device *d
+ 			error = -EFAULT;
+ 		}
+ 	wf_out:
+-		if (oldimage)
+-			kfree(oldimage);
+-		if (image)
+-			kfree(image);
++		kfree(oldimage);
++		kfree(image);
+ 		return error;
+ 		
+ 	case SIOCRRID:
+diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
+--- a/drivers/net/s2io-regs.h
++++ b/drivers/net/s2io-regs.h
+@@ -814,6 +814,17 @@ typedef struct _XENA_dev_config {
+ 	u64 rxgxs_ber_0;	/* CHANGED */
+ 	u64 rxgxs_ber_1;	/* CHANGED */
+ 
++	u64 spi_control;
++#define SPI_CONTROL_KEY(key)		vBIT(key,0,4)
++#define SPI_CONTROL_BYTECNT(cnt)	vBIT(cnt,29,3)
++#define SPI_CONTROL_CMD(cmd)		vBIT(cmd,32,8)
++#define SPI_CONTROL_ADDR(addr)		vBIT(addr,40,24)
++#define SPI_CONTROL_SEL1		BIT(4)
++#define SPI_CONTROL_REQ			BIT(7)
++#define SPI_CONTROL_NACK		BIT(5)
++#define SPI_CONTROL_DONE		BIT(6)
++	u64 spi_data;
++#define SPI_DATA_WRITE(data,len)	vBIT(data,0,len)
+ } XENA_dev_config_t;
+ 
+ #define XENA_REG_SPACE	sizeof(XENA_dev_config_t)
+diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
+--- a/drivers/net/s2io.c
++++ b/drivers/net/s2io.c
+@@ -65,9 +65,11 @@
+ #include "s2io.h"
+ #include "s2io-regs.h"
+ 
++#define DRV_VERSION "Version 2.0.9.1"
++
+ /* S2io Driver name & version. */
+ static char s2io_driver_name[] = "Neterion";
+-static char s2io_driver_version[] = "Version 2.0.8.1";
++static char s2io_driver_version[] = DRV_VERSION;
+ 
+ static inline int RXD_IS_UP2DT(RxD_t *rxdp)
+ {
+@@ -307,6 +309,8 @@ static unsigned int indicate_max_pkts;
+ #endif
+ /* Frequency of Rx desc syncs expressed as power of 2 */
+ static unsigned int rxsync_frequency = 3;
++/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */
++static unsigned int intr_type = 0;
+ 
+ /*
+  * S2IO device table.
+@@ -701,8 +705,7 @@ static void free_shared_mem(struct s2io_
+ 			}
+ 			kfree(mac_control->rings[i].ba[j]);
+ 		}
+-		if (mac_control->rings[i].ba)
+-			kfree(mac_control->rings[i].ba);
++		kfree(mac_control->rings[i].ba);
+ 	}
+ #endif
+ 
+@@ -1396,8 +1399,13 @@ static int init_nic(struct s2io_nic *nic
+ 		writeq(val64, &bar0->rti_data1_mem);
+ 
+ 		val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
+-		    RTI_DATA2_MEM_RX_UFC_B(0x2) |
+-		    RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80);
++		    RTI_DATA2_MEM_RX_UFC_B(0x2) ;
++		if (nic->intr_type == MSI_X)
++		    val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \
++				RTI_DATA2_MEM_RX_UFC_D(0x40));
++		else
++		    val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) | \
++				RTI_DATA2_MEM_RX_UFC_D(0x80));
+ 		writeq(val64, &bar0->rti_data2_mem);
+ 
+ 		for (i = 0; i < config->rx_ring_num; i++) {
+@@ -1507,17 +1515,15 @@ static int init_nic(struct s2io_nic *nic
+ #define LINK_UP_DOWN_INTERRUPT		1
+ #define MAC_RMAC_ERR_TIMER		2
+ 
+-#if defined(CONFIG_MSI_MODE) || defined(CONFIG_MSIX_MODE)
+-#define s2io_link_fault_indication(x) MAC_RMAC_ERR_TIMER
+-#else
+ int s2io_link_fault_indication(nic_t *nic)
+ {
++	if (nic->intr_type != INTA)
++		return MAC_RMAC_ERR_TIMER;
+ 	if (nic->device_type == XFRAME_II_DEVICE)
+ 		return LINK_UP_DOWN_INTERRUPT;
+ 	else
+ 		return MAC_RMAC_ERR_TIMER;
+ }
+-#endif
+ 
+ /**
+  *  en_dis_able_nic_intrs - Enable or Disable the interrupts
+@@ -1941,11 +1947,14 @@ static int start_nic(struct s2io_nic *ni
+ 	}
+ 
+ 	/*  Enable select interrupts */
+-	interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
+-	interruptible |= TX_PIC_INTR | RX_PIC_INTR;
+-	interruptible |= TX_MAC_INTR | RX_MAC_INTR;
+-
+-	en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);
++	if (nic->intr_type != INTA)
++		en_dis_able_nic_intrs(nic, ENA_ALL_INTRS, DISABLE_INTRS);
++	else {
++		interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
++		interruptible |= TX_PIC_INTR | RX_PIC_INTR;
++		interruptible |= TX_MAC_INTR | RX_MAC_INTR;
++		en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);
++	}
+ 
+ 	/*
+ 	 * With some switches, link might be already up at this point.
+@@ -2633,11 +2642,11 @@ static void tx_intr_handler(fifo_info_t 
+ 			err = txdlp->Control_1 & TXD_T_CODE;
+ 			if ((err >> 48) == 0xA) {
+ 				DBG_PRINT(TX_DBG, "TxD returned due \
+-						to loss of link\n");
++to loss of link\n");
+ 			}
+ 			else {
+ 				DBG_PRINT(ERR_DBG, "***TxD error \
+-						%llx\n", err);
++%llx\n", err);
+ 			}
+ 		}
+ 
+@@ -2854,6 +2863,9 @@ void s2io_reset(nic_t * sp)
+ 	/* Set swapper to enable I/O register access */
+ 	s2io_set_swapper(sp);
+ 
++	/* Restore the MSIX table entries from local variables */
++	restore_xmsi_data(sp);
++
+ 	/* Clear certain PCI/PCI-X fields after reset */
+ 	if (sp->device_type == XFRAME_II_DEVICE) {
+ 		/* Clear parity err detect bit */
+@@ -2983,8 +2995,9 @@ int s2io_set_swapper(nic_t * sp)
+ 		 SWAPPER_CTRL_RXD_W_FE |
+ 		 SWAPPER_CTRL_RXF_W_FE |
+ 		 SWAPPER_CTRL_XMSI_FE |
+-		 SWAPPER_CTRL_XMSI_SE |
+ 		 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
++	if (sp->intr_type == INTA)
++		val64 |= SWAPPER_CTRL_XMSI_SE;
+ 	writeq(val64, &bar0->swapper_ctrl);
+ #else
+ 	/*
+@@ -3005,8 +3018,9 @@ int s2io_set_swapper(nic_t * sp)
+ 		 SWAPPER_CTRL_RXD_W_SE |
+ 		 SWAPPER_CTRL_RXF_W_FE |
+ 		 SWAPPER_CTRL_XMSI_FE |
+-		 SWAPPER_CTRL_XMSI_SE |
+ 		 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
++	if (sp->intr_type == INTA)
++		val64 |= SWAPPER_CTRL_XMSI_SE;
+ 	writeq(val64, &bar0->swapper_ctrl);
+ #endif
+ 	val64 = readq(&bar0->swapper_ctrl);
+@@ -3028,6 +3042,201 @@ int s2io_set_swapper(nic_t * sp)
+ 	return SUCCESS;
+ }
+ 
++int wait_for_msix_trans(nic_t *nic, int i)
++{
++	XENA_dev_config_t __iomem *bar0 = nic->bar0;
++	u64 val64;
++	int ret = 0, cnt = 0;
++
++	do {
++		val64 = readq(&bar0->xmsi_access);
++		if (!(val64 & BIT(15)))
++			break;
++		mdelay(1);
++		cnt++;
++	} while(cnt < 5);
++	if (cnt == 5) {
++		DBG_PRINT(ERR_DBG, "XMSI # %d Access failed\n", i);
++		ret = 1;
++	}
++
++	return ret;
++}
++
++void restore_xmsi_data(nic_t *nic)
++{
++	XENA_dev_config_t __iomem *bar0 = nic->bar0;
++	u64 val64;
++	int i;
++
++	for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
++		writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
++		writeq(nic->msix_info[i].data, &bar0->xmsi_data);
++		val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
++		writeq(val64, &bar0->xmsi_access);
++		if (wait_for_msix_trans(nic, i)) {
++			DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
++			continue;
++		}
++	}
++}
++
++void store_xmsi_data(nic_t *nic)
++{
++	XENA_dev_config_t __iomem *bar0 = nic->bar0;
++	u64 val64, addr, data;
++	int i;
++
++	/* Store and display */
++	for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
++		val64 = (BIT(15) | vBIT(i, 26, 6));
++		writeq(val64, &bar0->xmsi_access);
++		if (wait_for_msix_trans(nic, i)) {
++			DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
++			continue;
++		}
++		addr = readq(&bar0->xmsi_address);
++		data = readq(&bar0->xmsi_data);
++		if (addr && data) {
++			nic->msix_info[i].addr = addr;
++			nic->msix_info[i].data = data;
++		}
++	}
++}
++
++int s2io_enable_msi(nic_t *nic)
++{
++	XENA_dev_config_t __iomem *bar0 = nic->bar0;
++	u16 msi_ctrl, msg_val;
++	struct config_param *config = &nic->config;
++	struct net_device *dev = nic->dev;
++	u64 val64, tx_mat, rx_mat;
++	int i, err;
++
++	val64 = readq(&bar0->pic_control);
++	val64 &= ~BIT(1);
++	writeq(val64, &bar0->pic_control);
++
++	err = pci_enable_msi(nic->pdev);
++	if (err) {
++		DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n",
++			  nic->dev->name);
++		return err;
++	}
++
++	/*
++	 * Enable MSI and use MSI-1 in stead of the standard MSI-0
++	 * for interrupt handling.
++	 */
++	pci_read_config_word(nic->pdev, 0x4c, &msg_val);
++	msg_val ^= 0x1;
++	pci_write_config_word(nic->pdev, 0x4c, msg_val);
++	pci_read_config_word(nic->pdev, 0x4c, &msg_val);
++
++	pci_read_config_word(nic->pdev, 0x42, &msi_ctrl);
++	msi_ctrl |= 0x10;
++	pci_write_config_word(nic->pdev, 0x42, msi_ctrl);
++
++	/* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */
++	tx_mat = readq(&bar0->tx_mat0_n[0]);
++	for (i=0; i<config->tx_fifo_num; i++) {
++		tx_mat |= TX_MAT_SET(i, 1);
++	}
++	writeq(tx_mat, &bar0->tx_mat0_n[0]);
++
++	rx_mat = readq(&bar0->rx_mat);
++	for (i=0; i<config->rx_ring_num; i++) {
++		rx_mat |= RX_MAT_SET(i, 1);
++	}
++	writeq(rx_mat, &bar0->rx_mat);
++
++	dev->irq = nic->pdev->irq;
++	return 0;
++}
++
++int s2io_enable_msi_x(nic_t *nic)
++{
++	XENA_dev_config_t __iomem *bar0 = nic->bar0;
++	u64 tx_mat, rx_mat;
++	u16 msi_control; /* Temp variable */
++	int ret, i, j, msix_indx = 1;
++
++	nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
++			       GFP_KERNEL);
++	if (nic->entries == NULL) {
++		DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
++		return -ENOMEM;
++	}
++	memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
++
++	nic->s2io_entries =
++		kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
++				   GFP_KERNEL);
++	if (nic->s2io_entries == NULL) {
++		DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
++		kfree(nic->entries);
++		return -ENOMEM;
++	}
++	memset(nic->s2io_entries, 0,
++	       MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
++
++	for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
++		nic->entries[i].entry = i;
++		nic->s2io_entries[i].entry = i;
++		nic->s2io_entries[i].arg = NULL;
++		nic->s2io_entries[i].in_use = 0;
++	}
++
++	tx_mat = readq(&bar0->tx_mat0_n[0]);
++	for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) {
++		tx_mat |= TX_MAT_SET(i, msix_indx);
++		nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i];
++		nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE;
++		nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
++	}
++	writeq(tx_mat, &bar0->tx_mat0_n[0]);
++
++	if (!nic->config.bimodal) {
++		rx_mat = readq(&bar0->rx_mat);
++		for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
++			rx_mat |= RX_MAT_SET(j, msix_indx);
++			nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
++			nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
++			nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
++		}
++		writeq(rx_mat, &bar0->rx_mat);
++	} else {
++		tx_mat = readq(&bar0->tx_mat0_n[7]);
++		for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
++			tx_mat |= TX_MAT_SET(i, msix_indx);
++			nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
++			nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
++			nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
++		}
++		writeq(tx_mat, &bar0->tx_mat0_n[7]);
++	}
++
++	ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X);
++	if (ret) {
++		DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
++		kfree(nic->entries);
++		kfree(nic->s2io_entries);
++		nic->entries = NULL;
++		nic->s2io_entries = NULL;
++		return -ENOMEM;
++	}
++
++	/*
++	 * To enable MSI-X, MSI also needs to be enabled, due to a bug
++	 * in the herc NIC. (Temp change, needs to be removed later)
++	 */
++	pci_read_config_word(nic->pdev, 0x42, &msi_control);
++	msi_control |= 0x1; /* Enable MSI */
++	pci_write_config_word(nic->pdev, 0x42, msi_control);
++
++	return 0;
++}
++
+ /* ********************************************************* *
+  * Functions defined below concern the OS part of the driver *
+  * ********************************************************* */
+@@ -3048,6 +3257,8 @@ int s2io_open(struct net_device *dev)
+ {
+ 	nic_t *sp = dev->priv;
+ 	int err = 0;
++	int i;
++	u16 msi_control; /* Temp variable */
+ 
+ 	/*
+ 	 * Make sure you have link off by default every time
+@@ -3064,13 +3275,55 @@ int s2io_open(struct net_device *dev)
+ 		goto hw_init_failed;
+ 	}
+ 
++	/* Store the values of the MSIX table in the nic_t structure */
++	store_xmsi_data(sp);
++
+ 	/* After proper initialization of H/W, register ISR */
+-	err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ,
+-			  sp->name, dev);
+-	if (err) {
+-		DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
+-			  dev->name);
+-		goto isr_registration_failed;
++	if (sp->intr_type == MSI) {
++		err = request_irq((int) sp->pdev->irq, s2io_msi_handle, 
++			SA_SHIRQ, sp->name, dev);
++		if (err) {
++			DBG_PRINT(ERR_DBG, "%s: MSI registration \
++failed\n", dev->name);
++			goto isr_registration_failed;
++		}
++	}
++	if (sp->intr_type == MSI_X) {
++		for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) {
++			if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) {
++				sprintf(sp->desc1, "%s:MSI-X-%d-TX",
++					dev->name, i);
++				err = request_irq(sp->entries[i].vector,
++					  s2io_msix_fifo_handle, 0, sp->desc1,
++					  sp->s2io_entries[i].arg);
++				DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc1, 
++							sp->msix_info[i].addr);
++			} else {
++				sprintf(sp->desc2, "%s:MSI-X-%d-RX",
++					dev->name, i);
++				err = request_irq(sp->entries[i].vector,
++					  s2io_msix_ring_handle, 0, sp->desc2,
++					  sp->s2io_entries[i].arg);
++				DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc2, 
++							sp->msix_info[i].addr);
++			}
++			if (err) {
++				DBG_PRINT(ERR_DBG, "%s: MSI-X-%d registration \
++failed\n", dev->name, i);
++				DBG_PRINT(ERR_DBG, "Returned: %d\n", err);
++				goto isr_registration_failed;
++			}
++			sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS;
++		}
++	}
++	if (sp->intr_type == INTA) {
++		err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ,
++				sp->name, dev);
++		if (err) {
++			DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
++				  dev->name);
++			goto isr_registration_failed;
++		}
+ 	}
+ 
+ 	if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) {
+@@ -3083,11 +3336,37 @@ int s2io_open(struct net_device *dev)
+ 	return 0;
+ 
+ setting_mac_address_failed:
+-	free_irq(sp->pdev->irq, dev);
++	if (sp->intr_type != MSI_X)
++		free_irq(sp->pdev->irq, dev);
+ isr_registration_failed:
+ 	del_timer_sync(&sp->alarm_timer);
++	if (sp->intr_type == MSI_X) {
++		if (sp->device_type == XFRAME_II_DEVICE) {
++			for (i=1; (sp->s2io_entries[i].in_use == 
++				MSIX_REGISTERED_SUCCESS); i++) {
++				int vector = sp->entries[i].vector;
++				void *arg = sp->s2io_entries[i].arg;
++
++				free_irq(vector, arg);
++			}
++			pci_disable_msix(sp->pdev);
++
++			/* Temp */
++			pci_read_config_word(sp->pdev, 0x42, &msi_control);
++			msi_control &= 0xFFFE; /* Disable MSI */
++			pci_write_config_word(sp->pdev, 0x42, msi_control);
++		}
++	}
++	else if (sp->intr_type == MSI)
++		pci_disable_msi(sp->pdev);
+ 	s2io_reset(sp);
+ hw_init_failed:
++	if (sp->intr_type == MSI_X) {
++		if (sp->entries)
++			kfree(sp->entries);
++		if (sp->s2io_entries)
++			kfree(sp->s2io_entries);
++	}
+ 	return err;
+ }
+ 
+@@ -3107,12 +3386,35 @@ hw_init_failed:
+ int s2io_close(struct net_device *dev)
+ {
+ 	nic_t *sp = dev->priv;
++	int i;
++	u16 msi_control;
++
+ 	flush_scheduled_work();
+ 	netif_stop_queue(dev);
+ 	/* Reset card, kill tasklet and free Tx and Rx buffers. */
+ 	s2io_card_down(sp);
+ 
+-	free_irq(sp->pdev->irq, dev);
++	if (sp->intr_type == MSI_X) {
++		if (sp->device_type == XFRAME_II_DEVICE) {
++			for (i=1; (sp->s2io_entries[i].in_use == 
++					MSIX_REGISTERED_SUCCESS); i++) {
++				int vector = sp->entries[i].vector;
++				void *arg = sp->s2io_entries[i].arg;
++
++				free_irq(vector, arg);
++			}
++			pci_read_config_word(sp->pdev, 0x42, &msi_control);
++			msi_control &= 0xFFFE; /* Disable MSI */
++			pci_write_config_word(sp->pdev, 0x42, msi_control);
++
++			pci_disable_msix(sp->pdev);
++		}
++	}
++	else {
++		free_irq(sp->pdev->irq, dev);
++		if (sp->intr_type == MSI)
++			pci_disable_msi(sp->pdev);
++	}	
+ 	sp->device_close_flag = TRUE;	/* Device is shut down. */
+ 	return 0;
+ }
+@@ -3278,6 +3580,104 @@ s2io_alarm_handle(unsigned long data)
+ 	mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
+ }
+ 
++static irqreturn_t
++s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct net_device *dev = (struct net_device *) dev_id;
++	nic_t *sp = dev->priv;
++	int i;
++	int ret;
++	mac_info_t *mac_control;
++	struct config_param *config;
++
++	atomic_inc(&sp->isr_cnt);
++	mac_control = &sp->mac_control;
++	config = &sp->config;
++	DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__);
++
++	/* If Intr is because of Rx Traffic */
++	for (i = 0; i < config->rx_ring_num; i++)
++		rx_intr_handler(&mac_control->rings[i]);
++
++	/* If Intr is because of Tx Traffic */
++	for (i = 0; i < config->tx_fifo_num; i++)
++		tx_intr_handler(&mac_control->fifos[i]);
++
++	/*
++	 * If the Rx buffer count is below the panic threshold then
++	 * reallocate the buffers from the interrupt handler itself,
++	 * else schedule a tasklet to reallocate the buffers.
++	 */
++	for (i = 0; i < config->rx_ring_num; i++) {
++		int rxb_size = atomic_read(&sp->rx_bufs_left[i]);
++		int level = rx_buffer_level(sp, rxb_size, i);
++
++		if ((level == PANIC) && (!TASKLET_IN_USE)) {
++			DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", dev->name);
++			DBG_PRINT(INTR_DBG, "PANIC levels\n");
++			if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) {
++				DBG_PRINT(ERR_DBG, "%s:Out of memory",
++					  dev->name);
++				DBG_PRINT(ERR_DBG, " in ISR!!\n");
++				clear_bit(0, (&sp->tasklet_status));
++				atomic_dec(&sp->isr_cnt);
++				return IRQ_HANDLED;
++			}
++			clear_bit(0, (&sp->tasklet_status));
++		} else if (level == LOW) {
++			tasklet_schedule(&sp->task);
++		}
++	}
++
++	atomic_dec(&sp->isr_cnt);
++	return IRQ_HANDLED;
++}
++
++static irqreturn_t
++s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs)
++{
++	ring_info_t *ring = (ring_info_t *)dev_id;
++	nic_t *sp = ring->nic;
++	int rxb_size, level, rng_n;
++
++	atomic_inc(&sp->isr_cnt);
++	rx_intr_handler(ring);
++
++	rng_n = ring->ring_no;
++	rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]);
++	level = rx_buffer_level(sp, rxb_size, rng_n);
++
++	if ((level == PANIC) && (!TASKLET_IN_USE)) {
++		int ret;
++		DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__);
++		DBG_PRINT(INTR_DBG, "PANIC levels\n");
++		if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) {
++			DBG_PRINT(ERR_DBG, "Out of memory in %s",
++				  __FUNCTION__);
++			clear_bit(0, (&sp->tasklet_status));
++			return IRQ_HANDLED;
++		}
++		clear_bit(0, (&sp->tasklet_status));
++	} else if (level == LOW) {
++		tasklet_schedule(&sp->task);
++	}
++	atomic_dec(&sp->isr_cnt);
++
++	return IRQ_HANDLED;
++}
++
++static irqreturn_t
++s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs)
++{
++	fifo_info_t *fifo = (fifo_info_t *)dev_id;
++	nic_t *sp = fifo->nic;
++
++	atomic_inc(&sp->isr_cnt);
++	tx_intr_handler(fifo);
++	atomic_dec(&sp->isr_cnt);
++	return IRQ_HANDLED;
++}
++
+ static void s2io_txpic_intr_handle(nic_t *sp)
+ {
+ 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
+@@ -3778,11 +4178,10 @@ static void s2io_ethtool_gdrvinfo(struct
+ {
+ 	nic_t *sp = dev->priv;
+ 
+-	strncpy(info->driver, s2io_driver_name, sizeof(s2io_driver_name));
+-	strncpy(info->version, s2io_driver_version,
+-		sizeof(s2io_driver_version));
+-	strncpy(info->fw_version, "", 32);
+-	strncpy(info->bus_info, pci_name(sp->pdev), 32);
++	strncpy(info->driver, s2io_driver_name, sizeof(info->driver));
++	strncpy(info->version, s2io_driver_version, sizeof(info->version));
++	strncpy(info->fw_version, "", sizeof(info->fw_version));
++	strncpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info));
+ 	info->regdump_len = XENA_REG_SPACE;
+ 	info->eedump_len = XENA_EEPROM_SPACE;
+ 	info->testinfo_len = S2IO_TEST_LEN;
+@@ -3978,29 +4377,53 @@ static int s2io_ethtool_setpause_data(st
+  */
+ 
+ #define S2IO_DEV_ID		5
+-static int read_eeprom(nic_t * sp, int off, u32 * data)
++static int read_eeprom(nic_t * sp, int off, u64 * data)
+ {
+ 	int ret = -1;
+ 	u32 exit_cnt = 0;
+ 	u64 val64;
+ 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
+ 
+-	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
+-	    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
+-	    I2C_CONTROL_CNTL_START;
+-	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+-
+-	while (exit_cnt < 5) {
+-		val64 = readq(&bar0->i2c_control);
+-		if (I2C_CONTROL_CNTL_END(val64)) {
+-			*data = I2C_CONTROL_GET_DATA(val64);
+-			ret = 0;
+-			break;
++	if (sp->device_type == XFRAME_I_DEVICE) {
++		val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
++		    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
++		    I2C_CONTROL_CNTL_START;
++		SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
++
++		while (exit_cnt < 5) {
++			val64 = readq(&bar0->i2c_control);
++			if (I2C_CONTROL_CNTL_END(val64)) {
++				*data = I2C_CONTROL_GET_DATA(val64);
++				ret = 0;
++				break;
++			}
++			msleep(50);
++			exit_cnt++;
+ 		}
+-		msleep(50);
+-		exit_cnt++;
+ 	}
+ 
++	if (sp->device_type == XFRAME_II_DEVICE) {
++		val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
++			SPI_CONTROL_BYTECNT(0x3) | 
++			SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off);
++		SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
++		val64 |= SPI_CONTROL_REQ;
++		SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
++		while (exit_cnt < 5) {
++			val64 = readq(&bar0->spi_control);
++			if (val64 & SPI_CONTROL_NACK) {
++				ret = 1;
++				break;
++			} else if (val64 & SPI_CONTROL_DONE) {
++				*data = readq(&bar0->spi_data);
++				*data &= 0xffffff;
++				ret = 0;
++				break;
++			}
++			msleep(50);
++			exit_cnt++;
++		}
++	}
+ 	return ret;
+ }
+ 
+@@ -4019,28 +4442,53 @@ static int read_eeprom(nic_t * sp, int o
+  *  0 on success, -1 on failure.
+  */
+ 
+-static int write_eeprom(nic_t * sp, int off, u32 data, int cnt)
++static int write_eeprom(nic_t * sp, int off, u64 data, int cnt)
+ {
+ 	int exit_cnt = 0, ret = -1;
+ 	u64 val64;
+ 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
+ 
+-	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
+-	    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) |
+-	    I2C_CONTROL_CNTL_START;
+-	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+-
+-	while (exit_cnt < 5) {
+-		val64 = readq(&bar0->i2c_control);
+-		if (I2C_CONTROL_CNTL_END(val64)) {
+-			if (!(val64 & I2C_CONTROL_NACK))
+-				ret = 0;
+-			break;
++	if (sp->device_type == XFRAME_I_DEVICE) {
++		val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
++		    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA((u32)data) |
++		    I2C_CONTROL_CNTL_START;
++		SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
++
++		while (exit_cnt < 5) {
++			val64 = readq(&bar0->i2c_control);
++			if (I2C_CONTROL_CNTL_END(val64)) {
++				if (!(val64 & I2C_CONTROL_NACK))
++					ret = 0;
++				break;
++			}
++			msleep(50);
++			exit_cnt++;
+ 		}
+-		msleep(50);
+-		exit_cnt++;
+ 	}
+ 
++	if (sp->device_type == XFRAME_II_DEVICE) {
++		int write_cnt = (cnt == 8) ? 0 : cnt;
++		writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data);
++
++		val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
++			SPI_CONTROL_BYTECNT(write_cnt) | 
++			SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off);
++		SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
++		val64 |= SPI_CONTROL_REQ;
++		SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
++		while (exit_cnt < 5) {
++			val64 = readq(&bar0->spi_control);
++			if (val64 & SPI_CONTROL_NACK) {
++				ret = 1;
++				break;
++			} else if (val64 & SPI_CONTROL_DONE) {
++				ret = 0;
++				break;
++			}
++			msleep(50);
++			exit_cnt++;
++		}
++	}
+ 	return ret;
+ }
+ 
+@@ -4060,7 +4508,8 @@ static int write_eeprom(nic_t * sp, int 
+ static int s2io_ethtool_geeprom(struct net_device *dev,
+ 			 struct ethtool_eeprom *eeprom, u8 * data_buf)
+ {
+-	u32 data, i, valid;
++	u32 i, valid;
++	u64 data;
+ 	nic_t *sp = dev->priv;
+ 
+ 	eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16);
+@@ -4098,7 +4547,7 @@ static int s2io_ethtool_seeprom(struct n
+ 				u8 * data_buf)
+ {
+ 	int len = eeprom->len, cnt = 0;
+-	u32 valid = 0, data;
++	u64 valid = 0, data;
+ 	nic_t *sp = dev->priv;
+ 
+ 	if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) {
+@@ -4146,7 +4595,7 @@ static int s2io_ethtool_seeprom(struct n
+ static int s2io_register_test(nic_t * sp, uint64_t * data)
+ {
+ 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
+-	u64 val64 = 0;
++	u64 val64 = 0, exp_val;
+ 	int fail = 0;
+ 
+ 	val64 = readq(&bar0->pif_rd_swapper_fb);
+@@ -4162,7 +4611,11 @@ static int s2io_register_test(nic_t * sp
+ 	}
+ 
+ 	val64 = readq(&bar0->rx_queue_cfg);
+-	if (val64 != 0x0808080808080808ULL) {
++	if (sp->device_type == XFRAME_II_DEVICE)
++		exp_val = 0x0404040404040404ULL;
++	else
++		exp_val = 0x0808080808080808ULL;
++	if (val64 != exp_val) {
+ 		fail = 1;
+ 		DBG_PRINT(INFO_DBG, "Read Test level 3 fails\n");
+ 	}
+@@ -4190,7 +4643,7 @@ static int s2io_register_test(nic_t * sp
+ 	}
+ 
+ 	*data = fail;
+-	return 0;
++	return fail;
+ }
+ 
+ /**
+@@ -4209,58 +4662,83 @@ static int s2io_register_test(nic_t * sp
+ static int s2io_eeprom_test(nic_t * sp, uint64_t * data)
+ {
+ 	int fail = 0;
+-	u32 ret_data;
++	u64 ret_data, org_4F0, org_7F0;
++	u8 saved_4F0 = 0, saved_7F0 = 0;
++	struct net_device *dev = sp->dev;
+ 
+ 	/* Test Write Error at offset 0 */
+-	if (!write_eeprom(sp, 0, 0, 3))
+-		fail = 1;
++	/* Note that SPI interface allows write access to all areas
++	 * of EEPROM. Hence doing all negative testing only for Xframe I.
++	 */
++	if (sp->device_type == XFRAME_I_DEVICE)
++		if (!write_eeprom(sp, 0, 0, 3))
++			fail = 1;
++
++	/* Save current values at offsets 0x4F0 and 0x7F0 */
++	if (!read_eeprom(sp, 0x4F0, &org_4F0))
++		saved_4F0 = 1;
++	if (!read_eeprom(sp, 0x7F0, &org_7F0))
++		saved_7F0 = 1;
+ 
+ 	/* Test Write at offset 4f0 */
+-	if (write_eeprom(sp, 0x4F0, 0x01234567, 3))
++	if (write_eeprom(sp, 0x4F0, 0x012345, 3))
+ 		fail = 1;
+ 	if (read_eeprom(sp, 0x4F0, &ret_data))
+ 		fail = 1;
+ 
+-	if (ret_data != 0x01234567)
++	if (ret_data != 0x012345) {
++		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
+ 		fail = 1;
++	}
+ 
+ 	/* Reset the EEPROM data go FFFF */
+-	write_eeprom(sp, 0x4F0, 0xFFFFFFFF, 3);
++	write_eeprom(sp, 0x4F0, 0xFFFFFF, 3);
+ 
+ 	/* Test Write Request Error at offset 0x7c */
+-	if (!write_eeprom(sp, 0x07C, 0, 3))
+-		fail = 1;
++	if (sp->device_type == XFRAME_I_DEVICE)
++		if (!write_eeprom(sp, 0x07C, 0, 3))
++			fail = 1;
+ 
+-	/* Test Write Request at offset 0x7fc */
+-	if (write_eeprom(sp, 0x7FC, 0x01234567, 3))
++	/* Test Write Request at offset 0x7f0 */
++	if (write_eeprom(sp, 0x7F0, 0x012345, 3))
+ 		fail = 1;
+-	if (read_eeprom(sp, 0x7FC, &ret_data))
++	if (read_eeprom(sp, 0x7F0, &ret_data))
+ 		fail = 1;
+ 
+-	if (ret_data != 0x01234567)
++	if (ret_data != 0x012345) {
++		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
+ 		fail = 1;
++	}
+ 
+ 	/* Reset the EEPROM data go FFFF */
+-	write_eeprom(sp, 0x7FC, 0xFFFFFFFF, 3);
+-
+-	/* Test Write Error at offset 0x80 */
+-	if (!write_eeprom(sp, 0x080, 0, 3))
+-		fail = 1;
+-
+-	/* Test Write Error at offset 0xfc */
+-	if (!write_eeprom(sp, 0x0FC, 0, 3))
+-		fail = 1;
++	write_eeprom(sp, 0x7F0, 0xFFFFFF, 3);
+ 
+-	/* Test Write Error at offset 0x100 */
+-	if (!write_eeprom(sp, 0x100, 0, 3))
+-		fail = 1;
+-
+-	/* Test Write Error at offset 4ec */
+-	if (!write_eeprom(sp, 0x4EC, 0, 3))
+-		fail = 1;
++	if (sp->device_type == XFRAME_I_DEVICE) {
++		/* Test Write Error at offset 0x80 */
++		if (!write_eeprom(sp, 0x080, 0, 3))
++			fail = 1;
++
++		/* Test Write Error at offset 0xfc */
++		if (!write_eeprom(sp, 0x0FC, 0, 3))
++			fail = 1;
++
++		/* Test Write Error at offset 0x100 */
++		if (!write_eeprom(sp, 0x100, 0, 3))
++			fail = 1;
++
++		/* Test Write Error at offset 4ec */
++		if (!write_eeprom(sp, 0x4EC, 0, 3))
++			fail = 1;
++	}
++
++	/* Restore values at offsets 0x4F0 and 0x7F0 */
++	if (saved_4F0)
++		write_eeprom(sp, 0x4F0, org_4F0, 3);
++	if (saved_7F0)
++		write_eeprom(sp, 0x7F0, org_7F0, 3);
+ 
+ 	*data = fail;
+-	return 0;
++	return fail;
+ }
+ 
+ /**
+@@ -4342,7 +4820,7 @@ static int s2io_rldram_test(nic_t * sp, 
+ {
+ 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
+ 	u64 val64;
+-	int cnt, iteration = 0, test_pass = 0;
++	int cnt, iteration = 0, test_fail = 0;
+ 
+ 	val64 = readq(&bar0->adapter_control);
+ 	val64 &= ~ADAPTER_ECC_EN;
+@@ -4350,7 +4828,7 @@ static int s2io_rldram_test(nic_t * sp, 
+ 
+ 	val64 = readq(&bar0->mc_rldram_test_ctrl);
+ 	val64 |= MC_RLDRAM_TEST_MODE;
+-	writeq(val64, &bar0->mc_rldram_test_ctrl);
++	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
+ 
+ 	val64 = readq(&bar0->mc_rldram_mrs);
+ 	val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE;
+@@ -4378,17 +4856,12 @@ static int s2io_rldram_test(nic_t * sp, 
+ 		}
+ 		writeq(val64, &bar0->mc_rldram_test_d2);
+ 
+-		val64 = (u64) (0x0000003fffff0000ULL);
++		val64 = (u64) (0x0000003ffffe0100ULL);
+ 		writeq(val64, &bar0->mc_rldram_test_add);
+ 
+-
+-		val64 = MC_RLDRAM_TEST_MODE;
+-		writeq(val64, &bar0->mc_rldram_test_ctrl);
+-
+-		val64 |=
+-		    MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE |
+-		    MC_RLDRAM_TEST_GO;
+-		writeq(val64, &bar0->mc_rldram_test_ctrl);
++		val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE |
++		    	MC_RLDRAM_TEST_GO;
++		SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
+ 
+ 		for (cnt = 0; cnt < 5; cnt++) {
+ 			val64 = readq(&bar0->mc_rldram_test_ctrl);
+@@ -4400,11 +4873,8 @@ static int s2io_rldram_test(nic_t * sp, 
+ 		if (cnt == 5)
+ 			break;
+ 
+-		val64 = MC_RLDRAM_TEST_MODE;
+-		writeq(val64, &bar0->mc_rldram_test_ctrl);
+-
+-		val64 |= MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO;
+-		writeq(val64, &bar0->mc_rldram_test_ctrl);
++		val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO;
++		SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
+ 
+ 		for (cnt = 0; cnt < 5; cnt++) {
+ 			val64 = readq(&bar0->mc_rldram_test_ctrl);
+@@ -4417,18 +4887,18 @@ static int s2io_rldram_test(nic_t * sp, 
+ 			break;
+ 
+ 		val64 = readq(&bar0->mc_rldram_test_ctrl);
+-		if (val64 & MC_RLDRAM_TEST_PASS)
+-			test_pass = 1;
++		if (!(val64 & MC_RLDRAM_TEST_PASS))
++			test_fail = 1;
+ 
+ 		iteration++;
+ 	}
+ 
+-	if (!test_pass)
+-		*data = 1;
+-	else
+-		*data = 0;
++	*data = test_fail;
+ 
+-	return 0;
++	/* Bring the adapter out of test mode */
++	SPECIAL_REG_WRITE(0, &bar0->mc_rldram_test_ctrl, LF);
++
++	return test_fail;
+ }
+ 
+ /**
+@@ -4932,7 +5402,7 @@ static void s2io_card_down(nic_t * sp)
+ 
+ static int s2io_card_up(nic_t * sp)
+ {
+-	int i, ret;
++	int i, ret = 0;
+ 	mac_info_t *mac_control;
+ 	struct config_param *config;
+ 	struct net_device *dev = (struct net_device *) sp->dev;
+@@ -4944,6 +5414,15 @@ static int s2io_card_up(nic_t * sp)
+ 		return -ENODEV;
+ 	}
+ 
++	if (sp->intr_type == MSI)
++		ret = s2io_enable_msi(sp);
++	else if (sp->intr_type == MSI_X)
++		ret = s2io_enable_msi_x(sp);
++	if (ret) {
++		DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
++		sp->intr_type = INTA;
++	}
++
+ 	/*
+ 	 * Initializing the Rx buffers. For now we are considering only 1
+ 	 * Rx ring and initializing buffers into 30 Rx blocks
+@@ -5228,6 +5707,8 @@ static void s2io_init_pci(nic_t * sp)
+ 
+ MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik at neterion.com>");
+ MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
++
+ module_param(tx_fifo_num, int, 0);
+ module_param(rx_ring_num, int, 0);
+ module_param_array(tx_fifo_len, uint, NULL, 0);
+@@ -5245,6 +5726,7 @@ module_param(bimodal, bool, 0);
+ module_param(indicate_max_pkts, int, 0);
+ #endif
+ module_param(rxsync_frequency, int, 0);
++module_param(intr_type, int, 0);
+ 
+ /**
+  *  s2io_init_nic - Initialization of the adapter .
+@@ -5274,9 +5756,16 @@ s2io_init_nic(struct pci_dev *pdev, cons
+ 	mac_info_t *mac_control;
+ 	struct config_param *config;
+ 	int mode;
++	u8 dev_intr_type = intr_type;
+ 
+ #ifdef CONFIG_S2IO_NAPI
+-	DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n");
++	if (dev_intr_type != INTA) {
++		DBG_PRINT(ERR_DBG, "NAPI cannot be enabled when MSI/MSI-X \
++is enabled. Defaulting to INTA\n");
++		dev_intr_type = INTA;
++	}
++	else
++		DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n");
+ #endif
+ 
+ 	if ((ret = pci_enable_device(pdev))) {
+@@ -5303,10 +5792,35 @@ s2io_init_nic(struct pci_dev *pdev, cons
+ 		return -ENOMEM;
+ 	}
+ 
+-	if (pci_request_regions(pdev, s2io_driver_name)) {
+-		DBG_PRINT(ERR_DBG, "Request Regions failed\n"),
+-		    pci_disable_device(pdev);
+-		return -ENODEV;
++	if ((dev_intr_type == MSI_X) && 
++			((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
++			(pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
++		DBG_PRINT(ERR_DBG, "Xframe I does not support MSI_X. \
++Defaulting to INTA\n");
++		dev_intr_type = INTA;
++	}
++	if (dev_intr_type != MSI_X) {
++		if (pci_request_regions(pdev, s2io_driver_name)) {
++			DBG_PRINT(ERR_DBG, "Request Regions failed\n"),
++			    pci_disable_device(pdev);
++			return -ENODEV;
++		}
++	}
++	else {
++		if (!(request_mem_region(pci_resource_start(pdev, 0),
++               	         pci_resource_len(pdev, 0), s2io_driver_name))) {
++			DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n");
++			pci_disable_device(pdev);
++			return -ENODEV;
++		}
++        	if (!(request_mem_region(pci_resource_start(pdev, 2),
++               	         pci_resource_len(pdev, 2), s2io_driver_name))) {
++			DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n");
++                	release_mem_region(pci_resource_start(pdev, 0),
++                                   pci_resource_len(pdev, 0));
++			pci_disable_device(pdev);
++			return -ENODEV;
++		}
+ 	}
+ 
+ 	dev = alloc_etherdev(sizeof(nic_t));
+@@ -5329,6 +5843,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
+ 	sp->pdev = pdev;
+ 	sp->high_dma_flag = dma_flag;
+ 	sp->device_enabled_once = FALSE;
++	sp->intr_type = dev_intr_type;
+ 
+ 	if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
+ 		(pdev->device == PCI_DEVICE_ID_HERC_UNI))
+@@ -5336,6 +5851,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
+ 	else
+ 		sp->device_type = XFRAME_I_DEVICE;
+ 
++		
+ 	/* Initialize some PCI/PCI-X fields of the NIC. */
+ 	s2io_init_pci(sp);
+ 
+@@ -5571,12 +6087,23 @@ s2io_init_nic(struct pci_dev *pdev, cons
+ 	if (sp->device_type & XFRAME_II_DEVICE) {
+ 		DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ",
+ 			  dev->name);
+-		DBG_PRINT(ERR_DBG, "(rev %d), %s",
++		DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
+ 				get_xena_rev_id(sp->pdev),
+ 				s2io_driver_version);
+ #ifdef CONFIG_2BUFF_MODE
+ 		DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
+ #endif
++		switch(sp->intr_type) {
++			case INTA:
++				DBG_PRINT(ERR_DBG, ", Intr type INTA");
++				break;
++			case MSI:
++				DBG_PRINT(ERR_DBG, ", Intr type MSI");
++				break;
++			case MSI_X:
++				DBG_PRINT(ERR_DBG, ", Intr type MSI-X");
++				break;
++		}
+ 
+ 		DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n");
+ 		DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
+@@ -5595,12 +6122,23 @@ s2io_init_nic(struct pci_dev *pdev, cons
+ 	} else {
+ 		DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ",
+ 			  dev->name);
+-		DBG_PRINT(ERR_DBG, "(rev %d), %s",
++		DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
+ 					get_xena_rev_id(sp->pdev),
+ 					s2io_driver_version);
+ #ifdef CONFIG_2BUFF_MODE
+ 		DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
+ #endif
++		switch(sp->intr_type) {
++			case INTA:
++				DBG_PRINT(ERR_DBG, ", Intr type INTA");
++				break;
++			case MSI:
++				DBG_PRINT(ERR_DBG, ", Intr type MSI");
++				break;
++			case MSI_X:
++				DBG_PRINT(ERR_DBG, ", Intr type MSI-X");
++				break;
++		}
+ 		DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n");
+ 		DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ 			  sp->def_mac_addr[0].mac_addr[0],
+@@ -5644,7 +6182,14 @@ s2io_init_nic(struct pci_dev *pdev, cons
+       mem_alloc_failed:
+ 	free_shared_mem(sp);
+ 	pci_disable_device(pdev);
+-	pci_release_regions(pdev);
++	if (dev_intr_type != MSI_X)
++		pci_release_regions(pdev);
++	else {
++		release_mem_region(pci_resource_start(pdev, 0),
++			pci_resource_len(pdev, 0));
++		release_mem_region(pci_resource_start(pdev, 2),
++			pci_resource_len(pdev, 2));
++	}
+ 	pci_set_drvdata(pdev, NULL);
+ 	free_netdev(dev);
+ 
+@@ -5678,7 +6223,14 @@ static void __devexit s2io_rem_nic(struc
+ 	iounmap(sp->bar0);
+ 	iounmap(sp->bar1);
+ 	pci_disable_device(pdev);
+-	pci_release_regions(pdev);
++	if (sp->intr_type != MSI_X)
++		pci_release_regions(pdev);
++	else {
++		release_mem_region(pci_resource_start(pdev, 0),
++			pci_resource_len(pdev, 0));
++		release_mem_region(pci_resource_start(pdev, 2),
++			pci_resource_len(pdev, 2));
++	}
+ 	pci_set_drvdata(pdev, NULL);
+ 	free_netdev(dev);
+ }
+diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
+--- a/drivers/net/s2io.h
++++ b/drivers/net/s2io.h
+@@ -652,6 +652,30 @@ typedef struct {
+ #define SMALL_BLK_CNT	30
+ #define LARGE_BLK_CNT	100
+ 
++/*
++ * Structure to keep track of the MSI-X vectors and the corresponding
++ * argument registered against each vector
++ */
++#define MAX_REQUESTED_MSI_X	17
++struct s2io_msix_entry
++{
++	u16 vector;
++	u16 entry;
++	void *arg;
++
++	u8 type;
++#define	MSIX_FIFO_TYPE	1
++#define	MSIX_RING_TYPE	2
++
++	u8 in_use;
++#define MSIX_REGISTERED_SUCCESS	0xAA
++};
++
++struct msix_info_st {
++	u64 addr;
++	u64 data;
++};
++
+ /* Structure representing one instance of the NIC */
+ struct s2io_nic {
+ #ifdef CONFIG_S2IO_NAPI
+@@ -719,13 +743,8 @@ struct s2io_nic {
+ 	 *  a schedule task that will set the correct Link state once the
+ 	 *  NIC's PHY has stabilized after a state change.
+ 	 */
+-#ifdef INIT_TQUEUE
+-	struct tq_struct rst_timer_task;
+-	struct tq_struct set_link_task;
+-#else
+ 	struct work_struct rst_timer_task;
+ 	struct work_struct set_link_task;
+-#endif
+ 
+ 	/* Flag that can be used to turn on or turn off the Rx checksum
+ 	 * offload feature.
+@@ -748,10 +767,23 @@ struct s2io_nic {
+ 	atomic_t card_state;
+ 	volatile unsigned long link_state;
+ 	struct vlan_group *vlgrp;
++#define MSIX_FLG                0xA5
++	struct msix_entry *entries;
++	struct s2io_msix_entry *s2io_entries;
++	char desc1[35];
++	char desc2[35];
++
++	struct msix_info_st msix_info[0x3f];
++
+ #define XFRAME_I_DEVICE		1
+ #define XFRAME_II_DEVICE	2
+ 	u8 device_type;
+ 
++#define INTA	0
++#define MSI	1
++#define MSI_X	2
++	u8 intr_type;
++
+ 	spinlock_t	rx_lock;
+ 	atomic_t	isr_cnt;
+ };
+@@ -886,6 +918,13 @@ static int s2io_poll(struct net_device *
+ static void s2io_init_pci(nic_t * sp);
+ int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
+ static void s2io_alarm_handle(unsigned long data);
++static int s2io_enable_msi(nic_t *nic);
++static irqreturn_t s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs);
++static irqreturn_t
++s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs);
++static irqreturn_t
++s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs);
++int s2io_enable_msi_x(nic_t *nic);
+ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs);
+ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag);
+ static struct ethtool_ops netdev_ethtool_ops;
+@@ -894,4 +933,5 @@ int s2io_set_swapper(nic_t * sp);
+ static void s2io_card_down(nic_t *nic);
+ static int s2io_card_up(nic_t *nic);
+ int get_xena_rev_id(struct pci_dev *pdev);
++void restore_xmsi_data(nic_t *nic);
+ #endif				/* _S2IO_H */
+diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
+--- a/drivers/net/saa9730.c
++++ b/drivers/net/saa9730.c
+@@ -997,10 +997,7 @@ static void __devexit saa9730_remove_one
+ 
+         if (dev) {
+                 unregister_netdev(dev);
+-
+-		if (dev->priv)
+-			kfree(dev->priv);
+-
++		kfree(dev->priv);
+                 free_netdev(dev);
+                 pci_release_regions(pdev);
+                 pci_disable_device(pdev);
+@@ -1096,8 +1093,7 @@ static int lan_saa9730_init(struct net_d
+ 	return 0;
+ 
+  out:
+-	if (dev->priv)
+-		kfree(dev->priv);
++	kfree(dev->priv);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
+--- a/drivers/net/sb1250-mac.c
++++ b/drivers/net/sb1250-mac.c
+@@ -10,7 +10,7 @@
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+- * 
++ *
+  * You 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.
+@@ -118,8 +118,6 @@ MODULE_PARM_DESC(int_timeout, "Timeout v
+  ********************************************************************* */
+ 
+ 
+-typedef unsigned long sbmac_port_t;
+-
+ typedef enum { sbmac_speed_auto, sbmac_speed_10,
+ 	       sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t;
+ 
+@@ -129,7 +127,7 @@ typedef enum { sbmac_duplex_auto, sbmac_
+ typedef enum { sbmac_fc_auto, sbmac_fc_disabled, sbmac_fc_frame,
+ 	       sbmac_fc_collision, sbmac_fc_carrier } sbmac_fc_t;
+ 
+-typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on, 
++typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
+ 	       sbmac_state_broken } sbmac_state_t;
+ 
+ 
+@@ -144,17 +142,13 @@ typedef enum { sbmac_state_uninit, sbmac
+ 
+ #define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES)
+ 
+-#define SBMAC_READCSR(t)	__raw_readq((unsigned long)t)
+-#define SBMAC_WRITECSR(t,v)	__raw_writeq(v, (unsigned long)t)
+- 
+-
+ #define SBMAC_MAX_TXDESCR	32
+ #define SBMAC_MAX_RXDESCR	32
+ 
+ #define ETHER_ALIGN	2
+ #define ETHER_ADDR_LEN	6
+-#define ENET_PACKET_SIZE	1518 
+-/*#define ENET_PACKET_SIZE	9216 */ 
++#define ENET_PACKET_SIZE	1518
++/*#define ENET_PACKET_SIZE	9216 */
+ 
+ /**********************************************************************
+  *  DMA Descriptor structure
+@@ -172,12 +166,12 @@ typedef unsigned long paddr_t;
+  ********************************************************************* */
+ 
+ typedef struct sbmacdma_s {
+-	
+-	/* 
++
++	/*
+ 	 * This stuff is used to identify the channel and the registers
+ 	 * associated with it.
+ 	 */
+-	
++
+ 	struct sbmac_softc *sbdma_eth;	        /* back pointer to associated MAC */
+ 	int              sbdma_channel;	/* channel number */
+ 	int		 sbdma_txdir;       /* direction (1=transmit) */
+@@ -187,21 +181,21 @@ typedef struct sbmacdma_s {
+ 	int		 sbdma_int_timeout; /* # usec rx/tx interrupt */
+ #endif
+ 
+-	sbmac_port_t     sbdma_config0;	/* DMA config register 0 */
+-	sbmac_port_t     sbdma_config1;	/* DMA config register 1 */
+-	sbmac_port_t     sbdma_dscrbase;	/* Descriptor base address */
+-	sbmac_port_t     sbdma_dscrcnt;     /* Descriptor count register */
+-	sbmac_port_t     sbdma_curdscr;	/* current descriptor address */
+-	
++	volatile void __iomem *sbdma_config0;	/* DMA config register 0 */
++	volatile void __iomem *sbdma_config1;	/* DMA config register 1 */
++	volatile void __iomem *sbdma_dscrbase;	/* Descriptor base address */
++	volatile void __iomem *sbdma_dscrcnt;     /* Descriptor count register */
++	volatile void __iomem *sbdma_curdscr;	/* current descriptor address */
++
+ 	/*
+ 	 * This stuff is for maintenance of the ring
+ 	 */
+-	
++
+ 	sbdmadscr_t     *sbdma_dscrtable;	/* base of descriptor table */
+ 	sbdmadscr_t     *sbdma_dscrtable_end; /* end of descriptor table */
+-	
++
+ 	struct sk_buff **sbdma_ctxtable;    /* context table, one per descr */
+-	
++
+ 	paddr_t          sbdma_dscrtable_phys; /* and also the phys addr */
+ 	sbdmadscr_t     *sbdma_addptr;	/* next dscr for sw to add */
+ 	sbdmadscr_t     *sbdma_remptr;	/* next dscr for sw to remove */
+@@ -213,15 +207,15 @@ typedef struct sbmacdma_s {
+  ********************************************************************* */
+ 
+ struct sbmac_softc {
+-	
++
+ 	/*
+ 	 * Linux-specific things
+ 	 */
+-	
++
+ 	struct net_device *sbm_dev;		/* pointer to linux device */
+ 	spinlock_t sbm_lock;		/* spin lock */
+ 	struct timer_list sbm_timer;     	/* for monitoring MII */
+-	struct net_device_stats sbm_stats; 
++	struct net_device_stats sbm_stats;
+ 	int sbm_devflags;			/* current device flags */
+ 
+ 	int	     sbm_phy_oldbmsr;
+@@ -229,31 +223,31 @@ struct sbmac_softc {
+ 	int	     sbm_phy_oldk1stsr;
+ 	int	     sbm_phy_oldlinkstat;
+ 	int sbm_buffersize;
+-	
++
+ 	unsigned char sbm_phys[2];
+-	
++
+ 	/*
+ 	 * Controller-specific things
+ 	 */
+-	
+-	unsigned long	sbm_base;          /* MAC's base address */
++
++	volatile void __iomem *sbm_base;          /* MAC's base address */
+ 	sbmac_state_t    sbm_state;         /* current state */
+-	
+-	sbmac_port_t     sbm_macenable;	/* MAC Enable Register */
+-	sbmac_port_t     sbm_maccfg;	/* MAC Configuration Register */
+-	sbmac_port_t     sbm_fifocfg;	/* FIFO configuration register */
+-	sbmac_port_t     sbm_framecfg;	/* Frame configuration register */
+-	sbmac_port_t     sbm_rxfilter;	/* receive filter register */
+-	sbmac_port_t     sbm_isr;		/* Interrupt status register */
+-	sbmac_port_t     sbm_imr;		/* Interrupt mask register */
+-	sbmac_port_t     sbm_mdio;		/* MDIO register */
+-	
++
++	volatile void __iomem	*sbm_macenable;	/* MAC Enable Register */
++	volatile void __iomem	*sbm_maccfg;	/* MAC Configuration Register */
++	volatile void __iomem	*sbm_fifocfg;	/* FIFO configuration register */
++	volatile void __iomem	*sbm_framecfg;	/* Frame configuration register */
++	volatile void __iomem	*sbm_rxfilter;	/* receive filter register */
++	volatile void __iomem	*sbm_isr;	/* Interrupt status register */
++	volatile void __iomem	*sbm_imr;	/* Interrupt mask register */
++	volatile void __iomem	*sbm_mdio;	/* MDIO register */
++
+ 	sbmac_speed_t    sbm_speed;		/* current speed */
+ 	sbmac_duplex_t   sbm_duplex;	/* current duplex */
+ 	sbmac_fc_t       sbm_fc;		/* current flow control setting */
+-	
++
+ 	unsigned char    sbm_hwaddr[ETHER_ADDR_LEN];
+-	
++
+ 	sbmacdma_t       sbm_txdma;		/* for now, only use channel 0 */
+ 	sbmacdma_t       sbm_rxdma;
+ 	int              rx_hw_checksum;
+@@ -302,6 +296,7 @@ static void sbmac_set_rx_mode(struct net
+ static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+ static int sbmac_close(struct net_device *dev);
+ static int sbmac_mii_poll(struct sbmac_softc *s,int noisy);
++static int sbmac_mii_probe(struct net_device *dev);
+ 
+ static void sbmac_mii_sync(struct sbmac_softc *s);
+ static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitcnt);
+@@ -439,6 +434,9 @@ static uint64_t sbmac_orig_hwaddr[MAX_UN
+ 
+ #define	MII_BMCR	0x00 	/* Basic mode control register (rw) */
+ #define	MII_BMSR	0x01	/* Basic mode status register (ro) */
++#define	MII_PHYIDR1	0x02
++#define	MII_PHYIDR2	0x03
++
+ #define MII_K1STSR	0x0A	/* 1K Status Register (ro) */
+ #define	MII_ANLPAR	0x05	/* Autonegotiation lnk partner abilities (rw) */
+ 
+@@ -450,13 +448,13 @@ static uint64_t sbmac_orig_hwaddr[MAX_UN
+ 
+ /**********************************************************************
+  *  SBMAC_MII_SYNC(s)
+- *  
++ *
+  *  Synchronize with the MII - send a pattern of bits to the MII
+  *  that will guarantee that it is ready to accept a command.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   s - sbmac structure
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -467,25 +465,25 @@ static void sbmac_mii_sync(struct sbmac_
+ 	uint64_t bits;
+ 	int mac_mdio_genc;
+ 
+-	mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
+-	
++	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
++
+ 	bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT;
+-	
+-	SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+-	
++
++	__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
++
+ 	for (cnt = 0; cnt < 32; cnt++) {
+-		SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC | mac_mdio_genc);
+-		SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
++		__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
++		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+ 	}
+ }
+ 
+ /**********************************************************************
+  *  SBMAC_MII_SENDDATA(s,data,bitcnt)
+- *  
++ *
+  *  Send some bits to the MII.  The bits to be sent are right-
+  *  justified in the 'data' parameter.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   s - sbmac structure
+  *  	   data - data to send
+  *  	   bitcnt - number of bits to send
+@@ -498,20 +496,20 @@ static void sbmac_mii_senddata(struct sb
+ 	unsigned int curmask;
+ 	int mac_mdio_genc;
+ 
+-	mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
+-	
++	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
++
+ 	bits = M_MAC_MDIO_DIR_OUTPUT;
+-	SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+-	
++	__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
++
+ 	curmask = 1 << (bitcnt - 1);
+-	
++
+ 	for (i = 0; i < bitcnt; i++) {
+ 		if (data & curmask)
+ 			bits |= M_MAC_MDIO_OUT;
+ 		else bits &= ~M_MAC_MDIO_OUT;
+-		SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+-		SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC | mac_mdio_genc);
+-		SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
++		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
++		__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
++		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+ 		curmask >>= 1;
+ 	}
+ }
+@@ -520,14 +518,14 @@ static void sbmac_mii_senddata(struct sb
+ 
+ /**********************************************************************
+  *  SBMAC_MII_READ(s,phyaddr,regidx)
+- *  
++ *
+  *  Read a PHY register.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   s - sbmac structure
+  *  	   phyaddr - PHY's address
+  *  	   regidx = index of register to read
+- *  	   
++ *
+  *  Return value:
+  *  	   value read, or 0 if an error occurred.
+  ********************************************************************* */
+@@ -543,9 +541,9 @@ static unsigned int sbmac_mii_read(struc
+ 	 * Synchronize ourselves so that the PHY knows the next
+ 	 * thing coming down is a command
+ 	 */
+-	
++
+ 	sbmac_mii_sync(s);
+-	
++
+ 	/*
+ 	 * Send the data to the PHY.  The sequence is
+ 	 * a "start" command (2 bits)
+@@ -553,59 +551,55 @@ static unsigned int sbmac_mii_read(struc
+ 	 * the PHY addr (5 bits)
+ 	 * the register index (5 bits)
+ 	 */
+-	
++
+ 	sbmac_mii_senddata(s,MII_COMMAND_START, 2);
+ 	sbmac_mii_senddata(s,MII_COMMAND_READ, 2);
+ 	sbmac_mii_senddata(s,phyaddr, 5);
+ 	sbmac_mii_senddata(s,regidx, 5);
+-	
+-	mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
+-	
+-	/* 
++
++	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
++
++	/*
+ 	 * Switch the port around without a clock transition.
+ 	 */
+-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
+-	
++	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
++
+ 	/*
+ 	 * Send out a clock pulse to signal we want the status
+ 	 */
+-	
+-	SBMAC_WRITECSR(s->sbm_mdio,
+-		       M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc);
+-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
+-	
+-	/* 
++
++	__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
++	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
++
++	/*
+ 	 * If an error occurred, the PHY will signal '1' back
+ 	 */
+-	error = SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN;
+-	
+-	/* 
++	error = __raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN;
++
++	/*
+ 	 * Issue an 'idle' clock pulse, but keep the direction
+ 	 * the same.
+ 	 */
+-	SBMAC_WRITECSR(s->sbm_mdio,
+-		       M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc);
+-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
+-	
++	__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
++	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
++
+ 	regval = 0;
+-	
++
+ 	for (idx = 0; idx < 16; idx++) {
+ 		regval <<= 1;
+-		
++
+ 		if (error == 0) {
+-			if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN)
++			if (__raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN)
+ 				regval |= 1;
+ 		}
+-		
+-		SBMAC_WRITECSR(s->sbm_mdio,
+-			       M_MAC_MDIO_DIR_INPUT|M_MAC_MDC | mac_mdio_genc);
+-		SBMAC_WRITECSR(s->sbm_mdio,
+-			       M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
++
++		__raw_writeq(M_MAC_MDIO_DIR_INPUT|M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
++		__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+ 	}
+-	
++
+ 	/* Switch back to output */
+-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc);
+-	
++	__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
++
+ 	if (error == 0)
+ 		return regval;
+ 	return 0;
+@@ -614,15 +608,15 @@ static unsigned int sbmac_mii_read(struc
+ 
+ /**********************************************************************
+  *  SBMAC_MII_WRITE(s,phyaddr,regidx,regval)
+- *  
++ *
+  *  Write a value to a PHY register.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   s - sbmac structure
+  *  	   phyaddr - PHY to use
+  *  	   regidx - register within the PHY
+  *  	   regval - data to write to register
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -633,7 +627,7 @@ static void sbmac_mii_write(struct sbmac
+ 	int mac_mdio_genc;
+ 
+ 	sbmac_mii_sync(s);
+-	
++
+ 	sbmac_mii_senddata(s,MII_COMMAND_START,2);
+ 	sbmac_mii_senddata(s,MII_COMMAND_WRITE,2);
+ 	sbmac_mii_senddata(s,phyaddr, 5);
+@@ -641,27 +635,27 @@ static void sbmac_mii_write(struct sbmac
+ 	sbmac_mii_senddata(s,MII_COMMAND_ACK,2);
+ 	sbmac_mii_senddata(s,regval,16);
+ 
+-	mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
++	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+ 
+-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc);
++	__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
+ }
+ 
+ 
+ 
+ /**********************************************************************
+  *  SBDMA_INITCTX(d,s,chan,txrx,maxdescr)
+- *  
++ *
+  *  Initialize a DMA channel context.  Since there are potentially
+  *  eight DMA channels per MAC, it's nice to do this in a standard
+- *  way.  
+- *  
+- *  Input parameters: 
++ *  way.
++ *
++ *  Input parameters:
+  *  	   d - sbmacdma_t structure (DMA channel context)
+  *  	   s - sbmac_softc structure (pointer to a MAC)
+  *  	   chan - channel number (0..1 right now)
+  *  	   txrx - Identifies DMA_TX or DMA_RX for channel direction
+  *      maxdescr - number of descriptors
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -672,101 +666,87 @@ static void sbdma_initctx(sbmacdma_t *d,
+ 			  int txrx,
+ 			  int maxdescr)
+ {
+-	/* 
+-	 * Save away interesting stuff in the structure 
++	/*
++	 * Save away interesting stuff in the structure
+ 	 */
+-	
++
+ 	d->sbdma_eth       = s;
+ 	d->sbdma_channel   = chan;
+ 	d->sbdma_txdir     = txrx;
+-	
++
+ #if 0
+ 	/* RMON clearing */
+ 	s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING;
+ #endif
+ 
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0);
+-	SBMAC_WRITECSR(IOADDR(
+-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0);
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)));
++	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)));
+ 
+-	/* 
+-	 * initialize register pointers 
++	/*
++	 * initialize register pointers
+ 	 */
+-	
+-	d->sbdma_config0 = 
++
++	d->sbdma_config0 =
+ 		s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0);
+-	d->sbdma_config1 = 
++	d->sbdma_config1 =
+ 		s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1);
+-	d->sbdma_dscrbase = 
++	d->sbdma_dscrbase =
+ 		s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE);
+-	d->sbdma_dscrcnt = 
++	d->sbdma_dscrcnt =
+ 		s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT);
+-	d->sbdma_curdscr = 	
++	d->sbdma_curdscr =
+ 		s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR);
+-	
++
+ 	/*
+ 	 * Allocate memory for the ring
+ 	 */
+-	
++
+ 	d->sbdma_maxdescr = maxdescr;
+-	
+-	d->sbdma_dscrtable = (sbdmadscr_t *) 
+-		kmalloc(d->sbdma_maxdescr*sizeof(sbdmadscr_t), GFP_KERNEL);
+-	
++
++	d->sbdma_dscrtable = (sbdmadscr_t *)
++		kmalloc((d->sbdma_maxdescr+1)*sizeof(sbdmadscr_t), GFP_KERNEL);
++
++	/*
++	 * The descriptor table must be aligned to at least 16 bytes or the
++	 * MAC will corrupt it.
++	 */
++	d->sbdma_dscrtable = (sbdmadscr_t *)
++		ALIGN((unsigned long)d->sbdma_dscrtable, sizeof(sbdmadscr_t));
++
+ 	memset(d->sbdma_dscrtable,0,d->sbdma_maxdescr*sizeof(sbdmadscr_t));
+-	
++
+ 	d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr;
+-	
++
+ 	d->sbdma_dscrtable_phys = virt_to_phys(d->sbdma_dscrtable);
+-	
++
+ 	/*
+ 	 * And context table
+ 	 */
+-	
+-	d->sbdma_ctxtable = (struct sk_buff **) 
++
++	d->sbdma_ctxtable = (struct sk_buff **)
+ 		kmalloc(d->sbdma_maxdescr*sizeof(struct sk_buff *), GFP_KERNEL);
+-	
++
+ 	memset(d->sbdma_ctxtable,0,d->sbdma_maxdescr*sizeof(struct sk_buff *));
+-	
++
+ #ifdef CONFIG_SBMAC_COALESCE
+ 	/*
+ 	 * Setup Rx/Tx DMA coalescing defaults
+@@ -777,7 +757,7 @@ static void sbdma_initctx(sbmacdma_t *d,
+ 	} else {
+ 		d->sbdma_int_pktcnt = 1;
+ 	}
+-	
++
+ 	if ( int_timeout ) {
+ 		d->sbdma_int_timeout = int_timeout;
+ 	} else {
+@@ -789,13 +769,13 @@ static void sbdma_initctx(sbmacdma_t *d,
+ 
+ /**********************************************************************
+  *  SBDMA_CHANNEL_START(d)
+- *  
++ *
+  *  Initialize the hardware registers for a DMA channel.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   d - DMA channel to init (context must be previously init'd
+  *         rxtx - DMA_RX or DMA_TX depending on what type of channel
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -805,24 +785,21 @@ static void sbdma_channel_start(sbmacdma
+ 	/*
+ 	 * Turn on the DMA channel
+ 	 */
+-	
++
+ #ifdef CONFIG_SBMAC_COALESCE
+-	SBMAC_WRITECSR(d->sbdma_config1,
+-		       V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) |
+-		       0);
+-	SBMAC_WRITECSR(d->sbdma_config0,
+-		       M_DMA_EOP_INT_EN |
++	__raw_writeq(V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) |
++		       0, d->sbdma_config1);
++	__raw_writeq(M_DMA_EOP_INT_EN |
+ 		       V_DMA_RINGSZ(d->sbdma_maxdescr) |
+ 		       V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) |
+-		       0);
++		       0, d->sbdma_config0);
+ #else
+-	SBMAC_WRITECSR(d->sbdma_config1,0);
+-	SBMAC_WRITECSR(d->sbdma_config0,
+-		       V_DMA_RINGSZ(d->sbdma_maxdescr) |
+-		       0);
++	__raw_writeq(0, d->sbdma_config1);
++	__raw_writeq(V_DMA_RINGSZ(d->sbdma_maxdescr) |
++		       0, d->sbdma_config0);
+ #endif
+ 
+-	SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys);
++	__raw_writeq(d->sbdma_dscrtable_phys, d->sbdma_dscrbase);
+ 
+ 	/*
+ 	 * Initialize ring pointers
+@@ -834,12 +811,12 @@ static void sbdma_channel_start(sbmacdma
+ 
+ /**********************************************************************
+  *  SBDMA_CHANNEL_STOP(d)
+- *  
++ *
+  *  Initialize the hardware registers for a DMA channel.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   d - DMA channel to init (context must be previously init'd
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -849,44 +826,44 @@ static void sbdma_channel_stop(sbmacdma_
+ 	/*
+ 	 * Turn off the DMA channel
+ 	 */
+-	
+-	SBMAC_WRITECSR(d->sbdma_config1,0);
+-	
+-	SBMAC_WRITECSR(d->sbdma_dscrbase,0);
+-	
+-	SBMAC_WRITECSR(d->sbdma_config0,0);
+-	
++
++	__raw_writeq(0, d->sbdma_config1);
++
++	__raw_writeq(0, d->sbdma_dscrbase);
++
++	__raw_writeq(0, d->sbdma_config0);
++
+ 	/*
+ 	 * Zero ring pointers
+ 	 */
+-	
+-	d->sbdma_addptr = 0;
+-	d->sbdma_remptr = 0;
++
++	d->sbdma_addptr = NULL;
++	d->sbdma_remptr = NULL;
+ }
+ 
+ static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset)
+ {
+ 	unsigned long addr;
+ 	unsigned long newaddr;
+-	
++
+ 	addr = (unsigned long) skb->data;
+-	
++
+ 	newaddr = (addr + power2 - 1) & ~(power2 - 1);
+-	
++
+ 	skb_reserve(skb,newaddr-addr+offset);
+ }
+ 
+ 
+ /**********************************************************************
+  *  SBDMA_ADD_RCVBUFFER(d,sb)
+- *  
++ *
+  *  Add a buffer to the specified DMA channel.   For receive channels,
+  *  this queues a buffer for inbound packets.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   d - DMA channel descriptor
+  * 	   sb - sk_buff to add, or NULL if we should allocate one
+- *  	   
++ *
+  *  Return value:
+  *  	   0 if buffer could not be added (ring is full)
+  *  	   1 if buffer added successfully
+@@ -899,24 +876,24 @@ static int sbdma_add_rcvbuffer(sbmacdma_
+ 	sbdmadscr_t *nextdsc;
+ 	struct sk_buff *sb_new = NULL;
+ 	int pktsize = ENET_PACKET_SIZE;
+-	
++
+ 	/* get pointer to our current place in the ring */
+-	
++
+ 	dsc = d->sbdma_addptr;
+ 	nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr);
+-	
++
+ 	/*
+ 	 * figure out if the ring is full - if the next descriptor
+ 	 * is the same as the one that we're going to remove from
+ 	 * the ring, the ring is full
+ 	 */
+-	
++
+ 	if (nextdsc == d->sbdma_remptr) {
+ 		return -ENOSPC;
+ 	}
+ 
+-	/* 
+-	 * Allocate a sk_buff if we don't already have one.  
++	/*
++	 * Allocate a sk_buff if we don't already have one.
+ 	 * If we do have an sk_buff, reset it so that it's empty.
+ 	 *
+ 	 * Note: sk_buffs don't seem to be guaranteed to have any sort
+@@ -925,7 +902,7 @@ static int sbdma_add_rcvbuffer(sbmacdma_
+ 	 *
+ 	 *    1. the data does not start in the middle of a cache line.
+ 	 *    2. The data does not end in the middle of a cache line
+-	 *    3. The buffer can be aligned such that the IP addresses are 
++	 *    3. The buffer can be aligned such that the IP addresses are
+ 	 *       naturally aligned.
+ 	 *
+ 	 *  Remember, the SOCs MAC writes whole cache lines at a time,
+@@ -933,7 +910,7 @@ static int sbdma_add_rcvbuffer(sbmacdma_
+ 	 *  data portion starts in the middle of a cache line, the SOC
+ 	 *  DMA will trash the beginning (and ending) portions.
+ 	 */
+-	
++
+ 	if (sb == NULL) {
+ 		sb_new = dev_alloc_skb(ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN);
+ 		if (sb_new == NULL) {
+@@ -949,23 +926,22 @@ static int sbdma_add_rcvbuffer(sbmacdma_
+ 	}
+ 	else {
+ 		sb_new = sb;
+-		/* 
++		/*
+ 		 * nothing special to reinit buffer, it's already aligned
+ 		 * and sb->data already points to a good place.
+ 		 */
+ 	}
+-	
++
+ 	/*
+-	 * fill in the descriptor 
++	 * fill in the descriptor
+ 	 */
+-	
++
+ #ifdef CONFIG_SBMAC_COALESCE
+ 	/*
+ 	 * Do not interrupt per DMA transfer.
+ 	 */
+ 	dsc->dscr_a = virt_to_phys(sb_new->data) |
+-		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
+-		0;
++		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | 0;
+ #else
+ 	dsc->dscr_a = virt_to_phys(sb_new->data) |
+ 		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
+@@ -974,38 +950,38 @@ static int sbdma_add_rcvbuffer(sbmacdma_
+ 
+ 	/* receiving: no options */
+ 	dsc->dscr_b = 0;
+-	
++
+ 	/*
+-	 * fill in the context 
++	 * fill in the context
+ 	 */
+-	
++
+ 	d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb_new;
+-	
+-	/* 
+-	 * point at next packet 
++
++	/*
++	 * point at next packet
+ 	 */
+-	
++
+ 	d->sbdma_addptr = nextdsc;
+-	
+-	/* 
++
++	/*
+ 	 * Give the buffer to the DMA engine.
+ 	 */
+-	
+-	SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
+-	
++
++	__raw_writeq(1, d->sbdma_dscrcnt);
++
+ 	return 0;					/* we did it */
+ }
+ 
+ /**********************************************************************
+  *  SBDMA_ADD_TXBUFFER(d,sb)
+- *  
++ *
+  *  Add a transmit buffer to the specified DMA channel, causing a
+  *  transmit to start.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   d - DMA channel descriptor
+  * 	   sb - sk_buff to add
+- *  	   
++ *
+  *  Return value:
+  *  	   0 transmit queued successfully
+  *  	   otherwise error code
+@@ -1019,70 +995,70 @@ static int sbdma_add_txbuffer(sbmacdma_t
+ 	uint64_t phys;
+ 	uint64_t ncb;
+ 	int length;
+-	
++
+ 	/* get pointer to our current place in the ring */
+-	
++
+ 	dsc = d->sbdma_addptr;
+ 	nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr);
+-	
++
+ 	/*
+ 	 * figure out if the ring is full - if the next descriptor
+ 	 * is the same as the one that we're going to remove from
+ 	 * the ring, the ring is full
+ 	 */
+-	
++
+ 	if (nextdsc == d->sbdma_remptr) {
+ 		return -ENOSPC;
+ 	}
+-	
++
+ 	/*
+ 	 * Under Linux, it's not necessary to copy/coalesce buffers
+ 	 * like it is on NetBSD.  We think they're all contiguous,
+ 	 * but that may not be true for GBE.
+ 	 */
+-	
++
+ 	length = sb->len;
+-	
++
+ 	/*
+ 	 * fill in the descriptor.  Note that the number of cache
+ 	 * blocks in the descriptor is the number of blocks
+ 	 * *spanned*, so we need to add in the offset (if any)
+ 	 * while doing the calculation.
+ 	 */
+-	
++
+ 	phys = virt_to_phys(sb->data);
+ 	ncb = NUMCACHEBLKS(length+(phys & (SMP_CACHE_BYTES - 1)));
+ 
+-	dsc->dscr_a = phys | 
++	dsc->dscr_a = phys |
+ 		V_DMA_DSCRA_A_SIZE(ncb) |
+ #ifndef CONFIG_SBMAC_COALESCE
+ 		M_DMA_DSCRA_INTERRUPT |
+ #endif
+ 		M_DMA_ETHTX_SOP;
+-	
++
+ 	/* transmitting: set outbound options and length */
+ 
+ 	dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
+ 		V_DMA_DSCRB_PKT_SIZE(length);
+-	
++
+ 	/*
+-	 * fill in the context 
++	 * fill in the context
+ 	 */
+-	
++
+ 	d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb;
+-	
+-	/* 
+-	 * point at next packet 
++
++	/*
++	 * point at next packet
+ 	 */
+-	
++
+ 	d->sbdma_addptr = nextdsc;
+-	
+-	/* 
++
++	/*
+ 	 * Give the buffer to the DMA engine.
+ 	 */
+-	
+-	SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
+-	
++
++	__raw_writeq(1, d->sbdma_dscrcnt);
++
+ 	return 0;					/* we did it */
+ }
+ 
+@@ -1091,12 +1067,12 @@ static int sbdma_add_txbuffer(sbmacdma_t
+ 
+ /**********************************************************************
+  *  SBDMA_EMPTYRING(d)
+- *  
++ *
+  *  Free all allocated sk_buffs on the specified DMA channel;
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   d  - DMA channel
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -1105,7 +1081,7 @@ static void sbdma_emptyring(sbmacdma_t *
+ {
+ 	int idx;
+ 	struct sk_buff *sb;
+-	
++
+ 	for (idx = 0; idx < d->sbdma_maxdescr; idx++) {
+ 		sb = d->sbdma_ctxtable[idx];
+ 		if (sb) {
+@@ -1118,13 +1094,13 @@ static void sbdma_emptyring(sbmacdma_t *
+ 
+ /**********************************************************************
+  *  SBDMA_FILLRING(d)
+- *  
++ *
+  *  Fill the specified DMA channel (must be receive channel)
+  *  with sk_buffs
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   d - DMA channel
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -1132,7 +1108,7 @@ static void sbdma_emptyring(sbmacdma_t *
+ static void sbdma_fillring(sbmacdma_t *d)
+ {
+ 	int idx;
+-	
++
+ 	for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++) {
+ 		if (sbdma_add_rcvbuffer(d,NULL) != 0)
+ 			break;
+@@ -1142,16 +1118,16 @@ static void sbdma_fillring(sbmacdma_t *d
+ 
+ /**********************************************************************
+  *  SBDMA_RX_PROCESS(sc,d)
+- *  
+- *  Process "completed" receive buffers on the specified DMA channel.  
++ *
++ *  Process "completed" receive buffers on the specified DMA channel.
+  *  Note that this isn't really ideal for priority channels, since
+- *  it processes all of the packets on a given channel before 
+- *  returning. 
++ *  it processes all of the packets on a given channel before
++ *  returning.
+  *
+- *  Input parameters: 
++ *  Input parameters:
+  *	   sc - softc structure
+  *  	   d - DMA channel context
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -1163,56 +1139,56 @@ static void sbdma_rx_process(struct sbma
+ 	sbdmadscr_t *dsc;
+ 	struct sk_buff *sb;
+ 	int len;
+-	
++
+ 	for (;;) {
+-		/* 
++		/*
+ 		 * figure out where we are (as an index) and where
+ 		 * the hardware is (also as an index)
+ 		 *
+-		 * This could be done faster if (for example) the 
++		 * This could be done faster if (for example) the
+ 		 * descriptor table was page-aligned and contiguous in
+ 		 * both virtual and physical memory -- you could then
+ 		 * just compare the low-order bits of the virtual address
+ 		 * (sbdma_remptr) and the physical address (sbdma_curdscr CSR)
+ 		 */
+-		
++
+ 		curidx = d->sbdma_remptr - d->sbdma_dscrtable;
+-		hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
++		hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+ 				d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
+-		
++
+ 		/*
+ 		 * If they're the same, that means we've processed all
+ 		 * of the descriptors up to (but not including) the one that
+ 		 * the hardware is working on right now.
+ 		 */
+-		
++
+ 		if (curidx == hwidx)
+ 			break;
+-		
++
+ 		/*
+ 		 * Otherwise, get the packet's sk_buff ptr back
+ 		 */
+-		
++
+ 		dsc = &(d->sbdma_dscrtable[curidx]);
+ 		sb = d->sbdma_ctxtable[curidx];
+ 		d->sbdma_ctxtable[curidx] = NULL;
+-		
++
+ 		len = (int)G_DMA_DSCRB_PKT_SIZE(dsc->dscr_b) - 4;
+-		
++
+ 		/*
+ 		 * Check packet status.  If good, process it.
+ 		 * If not, silently drop it and put it back on the
+ 		 * receive ring.
+ 		 */
+-		
++
+ 		if (!(dsc->dscr_a & M_DMA_ETHRX_BAD)) {
+-			
++
+ 			/*
+ 			 * Add a new buffer to replace the old one.  If we fail
+ 			 * to allocate a buffer, we're going to drop this
+ 			 * packet and put it right back on the receive ring.
+ 			 */
+-			
++
+ 			if (sbdma_add_rcvbuffer(d,NULL) == -ENOBUFS) {
+ 				sc->sbm_stats.rx_dropped++;
+ 				sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */
+@@ -1221,7 +1197,7 @@ static void sbdma_rx_process(struct sbma
+ 				 * Set length into the packet
+ 				 */
+ 				skb_put(sb,len);
+-				
++
+ 				/*
+ 				 * Buffer has been replaced on the
+ 				 * receive ring.  Pass the buffer to
+@@ -1240,7 +1216,7 @@ static void sbdma_rx_process(struct sbma
+ 						sb->ip_summed = CHECKSUM_NONE;
+ 					}
+ 				}
+-				
++
+ 				netif_rx(sb);
+ 			}
+ 		} else {
+@@ -1251,14 +1227,14 @@ static void sbdma_rx_process(struct sbma
+ 			sc->sbm_stats.rx_errors++;
+ 			sbdma_add_rcvbuffer(d,sb);
+ 		}
+-		
+-		
+-		/* 
++
++
++		/*
+ 		 * .. and advance to the next buffer.
+ 		 */
+-		
++
+ 		d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
+-		
++
+ 	}
+ }
+ 
+@@ -1266,17 +1242,17 @@ static void sbdma_rx_process(struct sbma
+ 
+ /**********************************************************************
+  *  SBDMA_TX_PROCESS(sc,d)
+- *  
+- *  Process "completed" transmit buffers on the specified DMA channel.  
++ *
++ *  Process "completed" transmit buffers on the specified DMA channel.
+  *  This is normally called within the interrupt service routine.
+  *  Note that this isn't really ideal for priority channels, since
+- *  it processes all of the packets on a given channel before 
+- *  returning. 
++ *  it processes all of the packets on a given channel before
++ *  returning.
+  *
+- *  Input parameters: 
++ *  Input parameters:
+  *      sc - softc structure
+  *  	   d - DMA channel context
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -1290,21 +1266,21 @@ static void sbdma_tx_process(struct sbma
+ 	unsigned long flags;
+ 
+ 	spin_lock_irqsave(&(sc->sbm_lock), flags);
+-	
++
+ 	for (;;) {
+-		/* 
++		/*
+ 		 * figure out where we are (as an index) and where
+ 		 * the hardware is (also as an index)
+ 		 *
+-		 * This could be done faster if (for example) the 
++		 * This could be done faster if (for example) the
+ 		 * descriptor table was page-aligned and contiguous in
+ 		 * both virtual and physical memory -- you could then
+ 		 * just compare the low-order bits of the virtual address
+ 		 * (sbdma_remptr) and the physical address (sbdma_curdscr CSR)
+ 		 */
+-		
++
+ 		curidx = d->sbdma_remptr - d->sbdma_dscrtable;
+-		hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
++		hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+ 				d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
+ 
+ 		/*
+@@ -1312,75 +1288,75 @@ static void sbdma_tx_process(struct sbma
+ 		 * of the descriptors up to (but not including) the one that
+ 		 * the hardware is working on right now.
+ 		 */
+-		
++
+ 		if (curidx == hwidx)
+ 			break;
+-		
++
+ 		/*
+ 		 * Otherwise, get the packet's sk_buff ptr back
+ 		 */
+-		
++
+ 		dsc = &(d->sbdma_dscrtable[curidx]);
+ 		sb = d->sbdma_ctxtable[curidx];
+ 		d->sbdma_ctxtable[curidx] = NULL;
+-		
++
+ 		/*
+ 		 * Stats
+ 		 */
+-		
++
+ 		sc->sbm_stats.tx_bytes += sb->len;
+ 		sc->sbm_stats.tx_packets++;
+-		
++
+ 		/*
+ 		 * for transmits, we just free buffers.
+ 		 */
+-		
++
+ 		dev_kfree_skb_irq(sb);
+-		
+-		/* 
++
++		/*
+ 		 * .. and advance to the next buffer.
+ 		 */
+ 
+ 		d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
+-		
++
+ 	}
+-	
++
+ 	/*
+ 	 * Decide if we should wake up the protocol or not.
+ 	 * Other drivers seem to do this when we reach a low
+ 	 * watermark on the transmit queue.
+ 	 */
+-	
++
+ 	netif_wake_queue(d->sbdma_eth->sbm_dev);
+-	
++
+ 	spin_unlock_irqrestore(&(sc->sbm_lock), flags);
+-	
++
+ }
+ 
+ 
+ 
+ /**********************************************************************
+  *  SBMAC_INITCTX(s)
+- *  
++ *
+  *  Initialize an Ethernet context structure - this is called
+  *  once per MAC on the 1250.  Memory is allocated here, so don't
+  *  call it again from inside the ioctl routines that bring the
+  *  interface up/down
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   s - sbmac context structure
+- *  	   
++ *
+  *  Return value:
+  *  	   0
+  ********************************************************************* */
+ 
+ static int sbmac_initctx(struct sbmac_softc *s)
+ {
+-	
+-	/* 
+-	 * figure out the addresses of some ports 
++
++	/*
++	 * figure out the addresses of some ports
+ 	 */
+-	
++
+ 	s->sbm_macenable = s->sbm_base + R_MAC_ENABLE;
+ 	s->sbm_maccfg    = s->sbm_base + R_MAC_CFG;
+ 	s->sbm_fifocfg   = s->sbm_base + R_MAC_THRSH_CFG;
+@@ -1397,29 +1373,29 @@ static int sbmac_initctx(struct sbmac_so
+ 	s->sbm_phy_oldanlpar = 0;
+ 	s->sbm_phy_oldk1stsr = 0;
+ 	s->sbm_phy_oldlinkstat = 0;
+-	
++
+ 	/*
+ 	 * Initialize the DMA channels.  Right now, only one per MAC is used
+ 	 * Note: Only do this _once_, as it allocates memory from the kernel!
+ 	 */
+-	
++
+ 	sbdma_initctx(&(s->sbm_txdma),s,0,DMA_TX,SBMAC_MAX_TXDESCR);
+ 	sbdma_initctx(&(s->sbm_rxdma),s,0,DMA_RX,SBMAC_MAX_RXDESCR);
+-	
++
+ 	/*
+ 	 * initial state is OFF
+ 	 */
+-	
++
+ 	s->sbm_state = sbmac_state_off;
+-	
++
+ 	/*
+ 	 * Initial speed is (XXX TEMP) 10MBit/s HDX no FC
+ 	 */
+-	
++
+ 	s->sbm_speed = sbmac_speed_10;
+ 	s->sbm_duplex = sbmac_duplex_half;
+ 	s->sbm_fc = sbmac_fc_disabled;
+-	
++
+ 	return 0;
+ }
+ 
+@@ -1430,7 +1406,7 @@ static void sbdma_uninitctx(struct sbmac
+ 		kfree(d->sbdma_dscrtable);
+ 		d->sbdma_dscrtable = NULL;
+ 	}
+-	
++
+ 	if (d->sbdma_ctxtable) {
+ 		kfree(d->sbdma_ctxtable);
+ 		d->sbdma_ctxtable = NULL;
+@@ -1447,12 +1423,12 @@ static void sbmac_uninitctx(struct sbmac
+ 
+ /**********************************************************************
+  *  SBMAC_CHANNEL_START(s)
+- *  
++ *
+  *  Start packet processing on this MAC.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   s - sbmac structure
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -1460,49 +1436,49 @@ static void sbmac_uninitctx(struct sbmac
+ static void sbmac_channel_start(struct sbmac_softc *s)
+ {
+ 	uint64_t reg;
+-	sbmac_port_t port;
++	volatile void __iomem *port;
+ 	uint64_t cfg,fifo,framecfg;
+ 	int idx, th_value;
+-	
++
+ 	/*
+ 	 * Don't do this if running
+ 	 */
+ 
+ 	if (s->sbm_state == sbmac_state_on)
+ 		return;
+-	
++
+ 	/*
+ 	 * Bring the controller out of reset, but leave it off.
+ 	 */
+-	
+-	SBMAC_WRITECSR(s->sbm_macenable,0);
+-	
++
++	__raw_writeq(0, s->sbm_macenable);
++
+ 	/*
+ 	 * Ignore all received packets
+ 	 */
+-	
+-	SBMAC_WRITECSR(s->sbm_rxfilter,0);
+-	
+-	/* 
++
++	__raw_writeq(0, s->sbm_rxfilter);
++
++	/*
+ 	 * Calculate values for various control registers.
+ 	 */
+-	
++
+ 	cfg = M_MAC_RETRY_EN |
+-		M_MAC_TX_HOLD_SOP_EN | 
++		M_MAC_TX_HOLD_SOP_EN |
+ 		V_MAC_TX_PAUSE_CNT_16K |
+ 		M_MAC_AP_STAT_EN |
+ 		M_MAC_FAST_SYNC |
+ 		M_MAC_SS_EN |
+ 		0;
+-	
+-	/* 
++
++	/*
+ 	 * Be sure that RD_THRSH+WR_THRSH <= 32 for pass1 pars
+ 	 * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above
+ 	 * Use a larger RD_THRSH for gigabit
+ 	 */
+-	if (periph_rev >= 2) 
++	if (periph_rev >= 2)
+ 		th_value = 64;
+-	else 
++	else
+ 		th_value = 28;
+ 
+ 	fifo = V_MAC_TX_WR_THRSH(4) |	/* Must be '4' or '8' */
+@@ -1520,51 +1496,51 @@ static void sbmac_channel_start(struct s
+ 		V_MAC_BACKOFF_SEL(1);
+ 
+ 	/*
+-	 * Clear out the hash address map 
++	 * Clear out the hash address map
+ 	 */
+-	
++
+ 	port = s->sbm_base + R_MAC_HASH_BASE;
+ 	for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
+-		SBMAC_WRITECSR(port,0);
++		__raw_writeq(0, port);
+ 		port += sizeof(uint64_t);
+ 	}
+-	
++
+ 	/*
+ 	 * Clear out the exact-match table
+ 	 */
+-	
++
+ 	port = s->sbm_base + R_MAC_ADDR_BASE;
+ 	for (idx = 0; idx < MAC_ADDR_COUNT; idx++) {
+-		SBMAC_WRITECSR(port,0);
++		__raw_writeq(0, port);
+ 		port += sizeof(uint64_t);
+ 	}
+-	
++
+ 	/*
+ 	 * Clear out the DMA Channel mapping table registers
+ 	 */
+-	
++
+ 	port = s->sbm_base + R_MAC_CHUP0_BASE;
+ 	for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
+-		SBMAC_WRITECSR(port,0);
++		__raw_writeq(0, port);
+ 		port += sizeof(uint64_t);
+ 	}
+ 
+ 
+ 	port = s->sbm_base + R_MAC_CHLO0_BASE;
+ 	for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
+-		SBMAC_WRITECSR(port,0);
++		__raw_writeq(0, port);
+ 		port += sizeof(uint64_t);
+ 	}
+-	
++
+ 	/*
+ 	 * Program the hardware address.  It goes into the hardware-address
+ 	 * register as well as the first filter register.
+ 	 */
+-	
++
+ 	reg = sbmac_addr2reg(s->sbm_hwaddr);
+-	
++
+ 	port = s->sbm_base + R_MAC_ADDR_BASE;
+-	SBMAC_WRITECSR(port,reg);
++	__raw_writeq(reg, port);
+ 	port = s->sbm_base + R_MAC_ETHERNET_ADDR;
+ 
+ #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+@@ -1573,108 +1549,105 @@ static void sbmac_channel_start(struct s
+ 	 * destination address in the R_MAC_ETHERNET_ADDR register.
+ 	 * Set the value to zero.
+ 	 */
+-	SBMAC_WRITECSR(port,0);
++	__raw_writeq(0, port);
+ #else
+-	SBMAC_WRITECSR(port,reg);
++	__raw_writeq(reg, port);
+ #endif
+-	
++
+ 	/*
+ 	 * Set the receive filter for no packets, and write values
+ 	 * to the various config registers
+ 	 */
+-	
+-	SBMAC_WRITECSR(s->sbm_rxfilter,0);
+-	SBMAC_WRITECSR(s->sbm_imr,0);
+-	SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
+-	SBMAC_WRITECSR(s->sbm_fifocfg,fifo);
+-	SBMAC_WRITECSR(s->sbm_maccfg,cfg);
+-	
++
++	__raw_writeq(0, s->sbm_rxfilter);
++	__raw_writeq(0, s->sbm_imr);
++	__raw_writeq(framecfg, s->sbm_framecfg);
++	__raw_writeq(fifo, s->sbm_fifocfg);
++	__raw_writeq(cfg, s->sbm_maccfg);
++
+ 	/*
+ 	 * Initialize DMA channels (rings should be ok now)
+ 	 */
+-	
++
+ 	sbdma_channel_start(&(s->sbm_rxdma), DMA_RX);
+ 	sbdma_channel_start(&(s->sbm_txdma), DMA_TX);
+-	
++
+ 	/*
+ 	 * Configure the speed, duplex, and flow control
+ 	 */
+ 
+ 	sbmac_set_speed(s,s->sbm_speed);
+ 	sbmac_set_duplex(s,s->sbm_duplex,s->sbm_fc);
+-	
++
+ 	/*
+ 	 * Fill the receive ring
+ 	 */
+-	
++
+ 	sbdma_fillring(&(s->sbm_rxdma));
+-	
+-	/* 
++
++	/*
+ 	 * Turn on the rest of the bits in the enable register
+-	 */      
+-	
+-	SBMAC_WRITECSR(s->sbm_macenable,
+-		       M_MAC_RXDMA_EN0 |
++	 */
++
++	__raw_writeq(M_MAC_RXDMA_EN0 |
+ 		       M_MAC_TXDMA_EN0 |
+ 		       M_MAC_RX_ENABLE |
+-		       M_MAC_TX_ENABLE);
+-	
+-	
++		       M_MAC_TX_ENABLE, s->sbm_macenable);
++
++
+ 
+ 
+ #ifdef CONFIG_SBMAC_COALESCE
+ 	/*
+ 	 * Accept any TX interrupt and EOP count/timer RX interrupts on ch 0
+ 	 */
+-	SBMAC_WRITECSR(s->sbm_imr,
+-		       ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
+-		       ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0));
++	__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
++		       ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr);
+ #else
+ 	/*
+ 	 * Accept any kind of interrupt on TX and RX DMA channel 0
+ 	 */
+-	SBMAC_WRITECSR(s->sbm_imr,
+-		       (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
+-		       (M_MAC_INT_CHANNEL << S_MAC_RX_CH0));
++	__raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
++		       (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr);
+ #endif
+-	
+-	/* 
+-	 * Enable receiving unicasts and broadcasts 
++
++	/*
++	 * Enable receiving unicasts and broadcasts
+ 	 */
+-	
+-	SBMAC_WRITECSR(s->sbm_rxfilter,M_MAC_UCAST_EN | M_MAC_BCAST_EN);
+-	
++
++	__raw_writeq(M_MAC_UCAST_EN | M_MAC_BCAST_EN, s->sbm_rxfilter);
++
+ 	/*
+-	 * we're running now. 
++	 * we're running now.
+ 	 */
+-	
++
+ 	s->sbm_state = sbmac_state_on;
+-	
+-	/* 
+-	 * Program multicast addresses 
++
++	/*
++	 * Program multicast addresses
+ 	 */
+-	
++
+ 	sbmac_setmulti(s);
+-	
+-	/* 
+-	 * If channel was in promiscuous mode before, turn that on 
++
++	/*
++	 * If channel was in promiscuous mode before, turn that on
+ 	 */
+-	
++
+ 	if (s->sbm_devflags & IFF_PROMISC) {
+ 		sbmac_promiscuous_mode(s,1);
+ 	}
+-	
++
+ }
+ 
+ 
+ /**********************************************************************
+  *  SBMAC_CHANNEL_STOP(s)
+- *  
++ *
+  *  Stop packet processing on this MAC.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   s - sbmac structure
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -1682,49 +1655,49 @@ static void sbmac_channel_start(struct s
+ static void sbmac_channel_stop(struct sbmac_softc *s)
+ {
+ 	/* don't do this if already stopped */
+-	
++
+ 	if (s->sbm_state == sbmac_state_off)
+ 		return;
+-	
++
+ 	/* don't accept any packets, disable all interrupts */
+-	
+-	SBMAC_WRITECSR(s->sbm_rxfilter,0);
+-	SBMAC_WRITECSR(s->sbm_imr,0);
+-	
++
++	__raw_writeq(0, s->sbm_rxfilter);
++	__raw_writeq(0, s->sbm_imr);
++
+ 	/* Turn off ticker */
+-	
++
+ 	/* XXX */
+-	
++
+ 	/* turn off receiver and transmitter */
+-	
+-	SBMAC_WRITECSR(s->sbm_macenable,0);
+-	
++
++	__raw_writeq(0, s->sbm_macenable);
++
+ 	/* We're stopped now. */
+-	
++
+ 	s->sbm_state = sbmac_state_off;
+-	
++
+ 	/*
+ 	 * Stop DMA channels (rings should be ok now)
+ 	 */
+-	
++
+ 	sbdma_channel_stop(&(s->sbm_rxdma));
+ 	sbdma_channel_stop(&(s->sbm_txdma));
+-	
++
+ 	/* Empty the receive and transmit rings */
+-	
++
+ 	sbdma_emptyring(&(s->sbm_rxdma));
+ 	sbdma_emptyring(&(s->sbm_txdma));
+-	
++
+ }
+ 
+ /**********************************************************************
+  *  SBMAC_SET_CHANNEL_STATE(state)
+- *  
++ *
+  *  Set the channel's state ON or OFF
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   state - new state
+- *  	   
++ *
+  *  Return value:
+  *  	   old state
+  ********************************************************************* */
+@@ -1732,43 +1705,43 @@ static sbmac_state_t sbmac_set_channel_s
+ 					     sbmac_state_t state)
+ {
+ 	sbmac_state_t oldstate = sc->sbm_state;
+-	
++
+ 	/*
+ 	 * If same as previous state, return
+ 	 */
+-	
++
+ 	if (state == oldstate) {
+ 		return oldstate;
+ 	}
+-	
++
+ 	/*
+-	 * If new state is ON, turn channel on 
++	 * If new state is ON, turn channel on
+ 	 */
+-	
++
+ 	if (state == sbmac_state_on) {
+ 		sbmac_channel_start(sc);
+ 	}
+ 	else {
+ 		sbmac_channel_stop(sc);
+ 	}
+-	
++
+ 	/*
+ 	 * Return previous state
+ 	 */
+-	
++
+ 	return oldstate;
+ }
+ 
+ 
+ /**********************************************************************
+  *  SBMAC_PROMISCUOUS_MODE(sc,onoff)
+- *  
++ *
+  *  Turn on or off promiscuous mode
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   sc - softc
+  *      onoff - 1 to turn on, 0 to turn off
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -1776,30 +1749,30 @@ static sbmac_state_t sbmac_set_channel_s
+ static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff)
+ {
+ 	uint64_t reg;
+-	
++
+ 	if (sc->sbm_state != sbmac_state_on)
+ 		return;
+-	
++
+ 	if (onoff) {
+-		reg = SBMAC_READCSR(sc->sbm_rxfilter);
++		reg = __raw_readq(sc->sbm_rxfilter);
+ 		reg |= M_MAC_ALLPKT_EN;
+-		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+-	}	
++		__raw_writeq(reg, sc->sbm_rxfilter);
++	}
+ 	else {
+-		reg = SBMAC_READCSR(sc->sbm_rxfilter);
++		reg = __raw_readq(sc->sbm_rxfilter);
+ 		reg &= ~M_MAC_ALLPKT_EN;
+-		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
++		__raw_writeq(reg, sc->sbm_rxfilter);
+ 	}
+ }
+ 
+ /**********************************************************************
+  *  SBMAC_SETIPHDR_OFFSET(sc,onoff)
+- *  
++ *
+  *  Set the iphdr offset as 15 assuming ethernet encapsulation
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   sc - softc
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -1807,12 +1780,12 @@ static void sbmac_promiscuous_mode(struc
+ static void sbmac_set_iphdr_offset(struct sbmac_softc *sc)
+ {
+ 	uint64_t reg;
+-	
++
+ 	/* Hard code the off set to 15 for now */
+-	reg = SBMAC_READCSR(sc->sbm_rxfilter);
++	reg = __raw_readq(sc->sbm_rxfilter);
+ 	reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15);
+-	SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+-	
++	__raw_writeq(reg, sc->sbm_rxfilter);
++
+ 	/* read system identification to determine revision */
+ 	if (periph_rev >= 2) {
+ 		sc->rx_hw_checksum = ENABLE;
+@@ -1824,13 +1797,13 @@ static void sbmac_set_iphdr_offset(struc
+ 
+ /**********************************************************************
+  *  SBMAC_ADDR2REG(ptr)
+- *  
++ *
+  *  Convert six bytes into the 64-bit register value that
+  *  we typically write into the SBMAC's address/mcast registers
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   ptr - pointer to 6 bytes
+- *  	   
++ *
+  *  Return value:
+  *  	   register value
+  ********************************************************************* */
+@@ -1838,35 +1811,35 @@ static void sbmac_set_iphdr_offset(struc
+ static uint64_t sbmac_addr2reg(unsigned char *ptr)
+ {
+ 	uint64_t reg = 0;
+-	
++
+ 	ptr += 6;
+-	
+-	reg |= (uint64_t) *(--ptr); 
++
++	reg |= (uint64_t) *(--ptr);
+ 	reg <<= 8;
+-	reg |= (uint64_t) *(--ptr); 
++	reg |= (uint64_t) *(--ptr);
+ 	reg <<= 8;
+-	reg |= (uint64_t) *(--ptr); 
++	reg |= (uint64_t) *(--ptr);
+ 	reg <<= 8;
+-	reg |= (uint64_t) *(--ptr); 
++	reg |= (uint64_t) *(--ptr);
+ 	reg <<= 8;
+-	reg |= (uint64_t) *(--ptr); 
++	reg |= (uint64_t) *(--ptr);
+ 	reg <<= 8;
+-	reg |= (uint64_t) *(--ptr); 
+-	
++	reg |= (uint64_t) *(--ptr);
++
+ 	return reg;
+ }
+ 
+ 
+ /**********************************************************************
+  *  SBMAC_SET_SPEED(s,speed)
+- *  
++ *
+  *  Configure LAN speed for the specified MAC.
+  *  Warning: must be called when MAC is off!
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   s - sbmac structure
+  *  	   speed - speed to set MAC to (see sbmac_speed_t enum)
+- *  	   
++ *
+  *  Return value:
+  *  	   1 if successful
+  *      0 indicates invalid parameters
+@@ -1880,31 +1853,31 @@ static int sbmac_set_speed(struct sbmac_
+ 	/*
+ 	 * Save new current values
+ 	 */
+-	
++
+ 	s->sbm_speed = speed;
+-	
++
+ 	if (s->sbm_state == sbmac_state_on)
+ 		return 0;	/* save for next restart */
+ 
+ 	/*
+-	 * Read current register values 
++	 * Read current register values
+ 	 */
+-	
+-	cfg = SBMAC_READCSR(s->sbm_maccfg);
+-	framecfg = SBMAC_READCSR(s->sbm_framecfg);
+-	
++
++	cfg = __raw_readq(s->sbm_maccfg);
++	framecfg = __raw_readq(s->sbm_framecfg);
++
+ 	/*
+ 	 * Mask out the stuff we want to change
+ 	 */
+-	
++
+ 	cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL);
+ 	framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH |
+ 		      M_MAC_SLOT_SIZE);
+-	
++
+ 	/*
+ 	 * Now add in the new bits
+ 	 */
+-	
++
+ 	switch (speed) {
+ 	case sbmac_speed_10:
+ 		framecfg |= V_MAC_IFG_RX_10 |
+@@ -1913,7 +1886,7 @@ static int sbmac_set_speed(struct sbmac_
+ 			V_MAC_SLOT_SIZE_10;
+ 		cfg |= V_MAC_SPEED_SEL_10MBPS;
+ 		break;
+-		
++
+ 	case sbmac_speed_100:
+ 		framecfg |= V_MAC_IFG_RX_100 |
+ 			V_MAC_IFG_TX_100 |
+@@ -1921,7 +1894,7 @@ static int sbmac_set_speed(struct sbmac_
+ 			V_MAC_SLOT_SIZE_100;
+ 		cfg |= V_MAC_SPEED_SEL_100MBPS ;
+ 		break;
+-		
++
+ 	case sbmac_speed_1000:
+ 		framecfg |= V_MAC_IFG_RX_1000 |
+ 			V_MAC_IFG_TX_1000 |
+@@ -1929,34 +1902,34 @@ static int sbmac_set_speed(struct sbmac_
+ 			V_MAC_SLOT_SIZE_1000;
+ 		cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN;
+ 		break;
+-		
++
+ 	case sbmac_speed_auto:		/* XXX not implemented */
+ 		/* fall through */
+ 	default:
+ 		return 0;
+ 	}
+-	
++
+ 	/*
+-	 * Send the bits back to the hardware 
++	 * Send the bits back to the hardware
+ 	 */
+-	
+-	SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
+-	SBMAC_WRITECSR(s->sbm_maccfg,cfg);
+-	
++
++	__raw_writeq(framecfg, s->sbm_framecfg);
++	__raw_writeq(cfg, s->sbm_maccfg);
++
+ 	return 1;
+ }
+ 
+ /**********************************************************************
+  *  SBMAC_SET_DUPLEX(s,duplex,fc)
+- *  
++ *
+  *  Set Ethernet duplex and flow control options for this MAC
+  *  Warning: must be called when MAC is off!
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   s - sbmac structure
+  *  	   duplex - duplex setting (see sbmac_duplex_t)
+  *  	   fc - flow control setting (see sbmac_fc_t)
+- *  	   
++ *
+  *  Return value:
+  *  	   1 if ok
+  *  	   0 if an invalid parameter combination was specified
+@@ -1965,67 +1938,67 @@ static int sbmac_set_speed(struct sbmac_
+ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc)
+ {
+ 	uint64_t cfg;
+-	
++
+ 	/*
+ 	 * Save new current values
+ 	 */
+-	
++
+ 	s->sbm_duplex = duplex;
+ 	s->sbm_fc = fc;
+-	
++
+ 	if (s->sbm_state == sbmac_state_on)
+ 		return 0;	/* save for next restart */
+-	
++
+ 	/*
+-	 * Read current register values 
++	 * Read current register values
+ 	 */
+-	
+-	cfg = SBMAC_READCSR(s->sbm_maccfg);
+-	
++
++	cfg = __raw_readq(s->sbm_maccfg);
++
+ 	/*
+ 	 * Mask off the stuff we're about to change
+ 	 */
+-	
++
+ 	cfg &= ~(M_MAC_FC_SEL | M_MAC_FC_CMD | M_MAC_HDX_EN);
+-	
+-	
++
++
+ 	switch (duplex) {
+ 	case sbmac_duplex_half:
+ 		switch (fc) {
+ 		case sbmac_fc_disabled:
+ 			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED;
+ 			break;
+-			
++
+ 		case sbmac_fc_collision:
+ 			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED;
+ 			break;
+-			
++
+ 		case sbmac_fc_carrier:
+ 			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR;
+ 			break;
+-			
++
+ 		case sbmac_fc_auto:		/* XXX not implemented */
+-			/* fall through */					   
++			/* fall through */
+ 		case sbmac_fc_frame:		/* not valid in half duplex */
+ 		default:			/* invalid selection */
+ 			return 0;
+ 		}
+ 		break;
+-		
++
+ 	case sbmac_duplex_full:
+ 		switch (fc) {
+ 		case sbmac_fc_disabled:
+ 			cfg |= V_MAC_FC_CMD_DISABLED;
+ 			break;
+-			
++
+ 		case sbmac_fc_frame:
+ 			cfg |= V_MAC_FC_CMD_ENABLED;
+ 			break;
+-			
++
+ 		case sbmac_fc_collision:	/* not valid in full duplex */
+ 		case sbmac_fc_carrier:		/* not valid in full duplex */
+ 		case sbmac_fc_auto:		/* XXX not implemented */
+-			/* fall through */					   
++			/* fall through */
+ 		default:
+ 			return 0;
+ 		}
+@@ -2034,13 +2007,13 @@ static int sbmac_set_duplex(struct sbmac
+ 		/* XXX not implemented */
+ 		break;
+ 	}
+-	
++
+ 	/*
+-	 * Send the bits back to the hardware 
++	 * Send the bits back to the hardware
+ 	 */
+-	
+-	SBMAC_WRITECSR(s->sbm_maccfg,cfg);
+-	
++
++	__raw_writeq(cfg, s->sbm_maccfg);
++
+ 	return 1;
+ }
+ 
+@@ -2049,12 +2022,12 @@ static int sbmac_set_duplex(struct sbmac
+ 
+ /**********************************************************************
+  *  SBMAC_INTR()
+- *  
++ *
+  *  Interrupt handler for MAC interrupts
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   MAC structure
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -2066,27 +2039,27 @@ static irqreturn_t sbmac_intr(int irq,vo
+ 	int handled = 0;
+ 
+ 	for (;;) {
+-		
++
+ 		/*
+ 		 * Read the ISR (this clears the bits in the real
+ 		 * register, except for counter addr)
+ 		 */
+-		
+-		isr = SBMAC_READCSR(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
+-		
++
++		isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
++
+ 		if (isr == 0)
+ 			break;
+ 
+ 		handled = 1;
+-		
++
+ 		/*
+ 		 * Transmits on channel 0
+ 		 */
+-		
++
+ 		if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) {
+ 			sbdma_tx_process(sc,&(sc->sbm_txdma));
+ 		}
+-		
++
+ 		/*
+ 		 * Receives on channel 0
+ 		 */
+@@ -2106,8 +2079,8 @@ static irqreturn_t sbmac_intr(int irq,vo
+ 		 * EOP_SEEN here takes care of this case.
+ 		 * (EOP_SEEN is part of M_MAC_INT_CHANNEL << S_MAC_RX_CH0)
+ 		 */
+-		 
+-		
++
++
+ 		if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
+ 			sbdma_rx_process(sc,&(sc->sbm_rxdma));
+ 		}
+@@ -2118,29 +2091,29 @@ static irqreturn_t sbmac_intr(int irq,vo
+ 
+ /**********************************************************************
+  *  SBMAC_START_TX(skb,dev)
+- *  
+- *  Start output on the specified interface.  Basically, we 
++ *
++ *  Start output on the specified interface.  Basically, we
+  *  queue as many buffers as we can until the ring fills up, or
+  *  we run off the end of the queue, whichever comes first.
+- *  
+- *  Input parameters: 
+- *  	   
+- *  	   
++ *
++ *  Input parameters:
++ *
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct sbmac_softc *sc = netdev_priv(dev);
+-	
++
+ 	/* lock eth irq */
+ 	spin_lock_irq (&sc->sbm_lock);
+-	
++
+ 	/*
+-	 * Put the buffer on the transmit ring.  If we 
++	 * Put the buffer on the transmit ring.  If we
+ 	 * don't have room, stop the queue.
+ 	 */
+-	
++
+ 	if (sbdma_add_txbuffer(&(sc->sbm_txdma),skb)) {
+ 		/* XXX save skb that we could not send */
+ 		netif_stop_queue(dev);
+@@ -2148,24 +2121,24 @@ static int sbmac_start_tx(struct sk_buff
+ 
+ 		return 1;
+ 	}
+-	
++
+ 	dev->trans_start = jiffies;
+-	
++
+ 	spin_unlock_irq (&sc->sbm_lock);
+-	
++
+ 	return 0;
+ }
+ 
+ /**********************************************************************
+  *  SBMAC_SETMULTI(sc)
+- *  
++ *
+  *  Reprogram the multicast table into the hardware, given
+  *  the list of multicasts associated with the interface
+  *  structure.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   sc - softc
+- *  	   
++ *
+  *  Return value:
+  *  	   nothing
+  ********************************************************************* */
+@@ -2173,75 +2146,75 @@ static int sbmac_start_tx(struct sk_buff
+ static void sbmac_setmulti(struct sbmac_softc *sc)
+ {
+ 	uint64_t reg;
+-	sbmac_port_t port;
++	volatile void __iomem *port;
+ 	int idx;
+ 	struct dev_mc_list *mclist;
+ 	struct net_device *dev = sc->sbm_dev;
+-	
+-	/* 
++
++	/*
+ 	 * Clear out entire multicast table.  We do this by nuking
+ 	 * the entire hash table and all the direct matches except
+-	 * the first one, which is used for our station address 
++	 * the first one, which is used for our station address
+ 	 */
+-	
++
+ 	for (idx = 1; idx < MAC_ADDR_COUNT; idx++) {
+ 		port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t));
+-		SBMAC_WRITECSR(port,0);	
++		__raw_writeq(0, port);
+ 	}
+-	
++
+ 	for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
+ 		port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t));
+-		SBMAC_WRITECSR(port,0);	
++		__raw_writeq(0, port);
+ 	}
+-	
++
+ 	/*
+ 	 * Clear the filter to say we don't want any multicasts.
+ 	 */
+-	
+-	reg = SBMAC_READCSR(sc->sbm_rxfilter);
++
++	reg = __raw_readq(sc->sbm_rxfilter);
+ 	reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN);
+-	SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+-	
++	__raw_writeq(reg, sc->sbm_rxfilter);
++
+ 	if (dev->flags & IFF_ALLMULTI) {
+-		/* 
+-		 * Enable ALL multicasts.  Do this by inverting the 
+-		 * multicast enable bit. 
++		/*
++		 * Enable ALL multicasts.  Do this by inverting the
++		 * multicast enable bit.
+ 		 */
+-		reg = SBMAC_READCSR(sc->sbm_rxfilter);
++		reg = __raw_readq(sc->sbm_rxfilter);
+ 		reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN);
+-		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
++		__raw_writeq(reg, sc->sbm_rxfilter);
+ 		return;
+ 	}
+-	
+ 
+-	/* 
++
++	/*
+ 	 * Progam new multicast entries.  For now, only use the
+ 	 * perfect filter.  In the future we'll need to use the
+ 	 * hash filter if the perfect filter overflows
+ 	 */
+-	
++
+ 	/* XXX only using perfect filter for now, need to use hash
+ 	 * XXX if the table overflows */
+-	
++
+ 	idx = 1;		/* skip station address */
+ 	mclist = dev->mc_list;
+ 	while (mclist && (idx < MAC_ADDR_COUNT)) {
+ 		reg = sbmac_addr2reg(mclist->dmi_addr);
+ 		port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t));
+-		SBMAC_WRITECSR(port,reg);
++		__raw_writeq(reg, port);
+ 		idx++;
+ 		mclist = mclist->next;
+ 	}
+-	
+-	/*	
++
++	/*
+ 	 * Enable the "accept multicast bits" if we programmed at least one
+-	 * multicast. 
++	 * multicast.
+ 	 */
+-	
++
+ 	if (idx > 1) {
+-		reg = SBMAC_READCSR(sc->sbm_rxfilter);
++		reg = __raw_readq(sc->sbm_rxfilter);
+ 		reg |= M_MAC_MCAST_EN;
+-		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
++		__raw_writeq(reg, sc->sbm_rxfilter);
+ 	}
+ }
+ 
+@@ -2250,12 +2223,12 @@ static void sbmac_setmulti(struct sbmac_
+ #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR)
+ /**********************************************************************
+  *  SBMAC_PARSE_XDIGIT(str)
+- *  
++ *
+  *  Parse a hex digit, returning its value
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   str - character
+- *  	   
++ *
+  *  Return value:
+  *  	   hex value, or -1 if invalid
+  ********************************************************************* */
+@@ -2263,7 +2236,7 @@ static void sbmac_setmulti(struct sbmac_
+ static int sbmac_parse_xdigit(char str)
+ {
+ 	int digit;
+-	
++
+ 	if ((str >= '0') && (str <= '9'))
+ 		digit = str - '0';
+ 	else if ((str >= 'a') && (str <= 'f'))
+@@ -2272,20 +2245,20 @@ static int sbmac_parse_xdigit(char str)
+ 		digit = str - 'A' + 10;
+ 	else
+ 		return -1;
+-	
++
+ 	return digit;
+ }
+ 
+ /**********************************************************************
+  *  SBMAC_PARSE_HWADDR(str,hwaddr)
+- *  
++ *
+  *  Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte
+  *  Ethernet address.
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   str - string
+  *  	   hwaddr - pointer to hardware address
+- *  	   
++ *
+  *  Return value:
+  *  	   0 if ok, else -1
+  ********************************************************************* */
+@@ -2294,7 +2267,7 @@ static int sbmac_parse_hwaddr(char *str,
+ {
+ 	int digit1,digit2;
+ 	int idx = 6;
+-	
++
+ 	while (*str && (idx > 0)) {
+ 		digit1 = sbmac_parse_xdigit(*str);
+ 		if (digit1 < 0)
+@@ -2302,7 +2275,7 @@ static int sbmac_parse_hwaddr(char *str,
+ 		str++;
+ 		if (!*str)
+ 			return -1;
+-		
++
+ 		if ((*str == ':') || (*str == '-')) {
+ 			digit2 = digit1;
+ 			digit1 = 0;
+@@ -2313,10 +2286,10 @@ static int sbmac_parse_hwaddr(char *str,
+ 				return -1;
+ 			str++;
+ 		}
+-		
++
+ 		*hwaddr++ = (digit1 << 4) | digit2;
+ 		idx--;
+-		
++
+ 		if (*str == '-')
+ 			str++;
+ 		if (*str == ':')
+@@ -2337,12 +2310,12 @@ static int sb1250_change_mtu(struct net_
+ 
+ /**********************************************************************
+  *  SBMAC_INIT(dev)
+- *  
++ *
+  *  Attach routine - init hardware and hook ourselves into linux
+- *  
+- *  Input parameters: 
++ *
++ *  Input parameters:
+  *  	   dev - net_device structure
+- *  	   
++ *
+  *  Return value:
+  *  	   status
+  ********************************************************************* */
+@@ -2354,53 +2327,53 @@ static int sbmac_init(struct net_device 
+ 	uint64_t ea_reg;
+ 	int i;
+ 	int err;
+-	
++
+ 	sc = netdev_priv(dev);
+-	
++
+ 	/* Determine controller base address */
+-	
++
+ 	sc->sbm_base = IOADDR(dev->base_addr);
+ 	sc->sbm_dev = dev;
+ 	sc->sbe_idx = idx;
+-	
++
+ 	eaddr = sc->sbm_hwaddr;
+-	
+-	/* 
++
++	/*
+ 	 * Read the ethernet address.  The firwmare left this programmed
+ 	 * for us in the ethernet address register for each mac.
+ 	 */
+-	
+-	ea_reg = SBMAC_READCSR(sc->sbm_base + R_MAC_ETHERNET_ADDR);
+-	SBMAC_WRITECSR(sc->sbm_base + R_MAC_ETHERNET_ADDR, 0);
++
++	ea_reg = __raw_readq(sc->sbm_base + R_MAC_ETHERNET_ADDR);
++	__raw_writeq(0, sc->sbm_base + R_MAC_ETHERNET_ADDR);
+ 	for (i = 0; i < 6; i++) {
+ 		eaddr[i] = (uint8_t) (ea_reg & 0xFF);
+ 		ea_reg >>= 8;
+ 	}
+-	
++
+ 	for (i = 0; i < 6; i++) {
+ 		dev->dev_addr[i] = eaddr[i];
+ 	}
+-	
+-	
++
++
+ 	/*
+-	 * Init packet size 
++	 * Init packet size
+ 	 */
+-	
++
+ 	sc->sbm_buffersize = ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN;
+ 
+-	/* 
++	/*
+ 	 * Initialize context (get pointers to registers and stuff), then
+ 	 * allocate the memory for the descriptor tables.
+ 	 */
+-	
++
+ 	sbmac_initctx(sc);
+-	
++
+ 	/*
+ 	 * Set up Linux device callins
+ 	 */
+-	
++
+ 	spin_lock_init(&(sc->sbm_lock));
+-	
++
+ 	dev->open               = sbmac_open;
+ 	dev->hard_start_xmit    = sbmac_start_tx;
+ 	dev->stop               = sbmac_close;
+@@ -2419,7 +2392,7 @@ static int sbmac_init(struct net_device 
+ 	if (err)
+ 		goto out_uninit;
+ 
+-	if (periph_rev >= 2) {
++	if (sc->rx_hw_checksum == ENABLE) {
+ 		printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
+ 			sc->sbm_dev->name);
+ 	}
+@@ -2430,10 +2403,10 @@ static int sbmac_init(struct net_device 
+ 	 * was being displayed)
+ 	 */
+ 	printk(KERN_INFO
+-	       "%s: SiByte Ethernet at 0x%08lX, address: %02X:%02X:%02X:%02X:%02X:%02X\n", 
++	       "%s: SiByte Ethernet at 0x%08lX, address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ 	       dev->name, dev->base_addr,
+ 	       eaddr[0],eaddr[1],eaddr[2],eaddr[3],eaddr[4],eaddr[5]);
+-	
++
+ 
+ 	return 0;
+ 
+@@ -2447,54 +2420,86 @@ out_uninit:
+ static int sbmac_open(struct net_device *dev)
+ {
+ 	struct sbmac_softc *sc = netdev_priv(dev);
+-	
++
+ 	if (debug > 1) {
+ 		printk(KERN_DEBUG "%s: sbmac_open() irq %d.\n", dev->name, dev->irq);
+ 	}
+-	
+-	/* 
++
++	/*
+ 	 * map/route interrupt (clear status first, in case something
+ 	 * weird is pending; we haven't initialized the mac registers
+ 	 * yet)
+ 	 */
+ 
+-	SBMAC_READCSR(sc->sbm_isr);
++	__raw_readq(sc->sbm_isr);
+ 	if (request_irq(dev->irq, &sbmac_intr, SA_SHIRQ, dev->name, dev))
+ 		return -EBUSY;
+ 
+ 	/*
+-	 * Configure default speed 
++	 * Probe phy address
++	 */
++
++	if(sbmac_mii_probe(dev) == -1) {
++		printk("%s: failed to probe PHY.\n", dev->name);
++		return -EINVAL;
++	}
++
++	/*
++	 * Configure default speed
+ 	 */
+ 
+ 	sbmac_mii_poll(sc,noisy_mii);
+-	
++
+ 	/*
+ 	 * Turn on the channel
+ 	 */
+ 
+ 	sbmac_set_channel_state(sc,sbmac_state_on);
+-	
++
+ 	/*
+ 	 * XXX Station address is in dev->dev_addr
+ 	 */
+-	
++
+ 	if (dev->if_port == 0)
+-		dev->if_port = 0; 
+-	
++		dev->if_port = 0;
++
+ 	netif_start_queue(dev);
+-	
++
+ 	sbmac_set_rx_mode(dev);
+-	
++
+ 	/* Set the timer to check for link beat. */
+ 	init_timer(&sc->sbm_timer);
+ 	sc->sbm_timer.expires = jiffies + 2 * HZ/100;
+ 	sc->sbm_timer.data = (unsigned long)dev;
+ 	sc->sbm_timer.function = &sbmac_timer;
+ 	add_timer(&sc->sbm_timer);
+-	
++
+ 	return 0;
+ }
+ 
++static int sbmac_mii_probe(struct net_device *dev)
++{
++	int i;
++	struct sbmac_softc *s = netdev_priv(dev);
++	u16 bmsr, id1, id2;
++	u32 vendor, device;
++
++	for (i=1; i<31; i++) {
++	bmsr = sbmac_mii_read(s, i, MII_BMSR);
++		if (bmsr != 0) {
++			s->sbm_phys[0] = i;
++			id1 = sbmac_mii_read(s, i, MII_PHYIDR1);
++			id2 = sbmac_mii_read(s, i, MII_PHYIDR2);
++			vendor = ((u32)id1 << 6) | ((id2 >> 10) & 0x3f);
++			device = (id2 >> 4) & 0x3f;
++
++			printk(KERN_INFO "%s: found phy %d, vendor %06x part %02x\n",
++				dev->name, i, vendor, device);
++			return i;
++		}
++	}
++	return -1;
++}
+ 
+ 
+ static int sbmac_mii_poll(struct sbmac_softc *s,int noisy)
+@@ -2609,20 +2614,20 @@ static void sbmac_timer(unsigned long da
+ 	int mii_status;
+ 
+ 	spin_lock_irq (&sc->sbm_lock);
+-	
++
+ 	/* make IFF_RUNNING follow the MII status bit "Link established" */
+ 	mii_status = sbmac_mii_read(sc, sc->sbm_phys[0], MII_BMSR);
+-	
++
+ 	if ( (mii_status & BMSR_LINKSTAT) != (sc->sbm_phy_oldlinkstat) ) {
+     	        sc->sbm_phy_oldlinkstat = mii_status & BMSR_LINKSTAT;
+ 		if (mii_status & BMSR_LINKSTAT) {
+ 			netif_carrier_on(dev);
+ 		}
+ 		else {
+-			netif_carrier_off(dev);	
++			netif_carrier_off(dev);
+ 		}
+ 	}
+-	
++
+ 	/*
+ 	 * Poll the PHY to see what speed we should be running at
+ 	 */
+@@ -2640,9 +2645,9 @@ static void sbmac_timer(unsigned long da
+ 			sbmac_channel_start(sc);
+ 		}
+ 	}
+-	
++
+ 	spin_unlock_irq (&sc->sbm_lock);
+-	
++
+ 	sc->sbm_timer.expires = jiffies + next_tick;
+ 	add_timer(&sc->sbm_timer);
+ }
+@@ -2651,13 +2656,13 @@ static void sbmac_timer(unsigned long da
+ static void sbmac_tx_timeout (struct net_device *dev)
+ {
+ 	struct sbmac_softc *sc = netdev_priv(dev);
+-	
++
+ 	spin_lock_irq (&sc->sbm_lock);
+-	
+-	
++
++
+ 	dev->trans_start = jiffies;
+ 	sc->sbm_stats.tx_errors++;
+-	
++
+ 	spin_unlock_irq (&sc->sbm_lock);
+ 
+ 	printk (KERN_WARNING "%s: Transmit timed out\n",dev->name);
+@@ -2670,13 +2675,13 @@ static struct net_device_stats *sbmac_ge
+ {
+ 	struct sbmac_softc *sc = netdev_priv(dev);
+ 	unsigned long flags;
+-	
++
+ 	spin_lock_irqsave(&sc->sbm_lock, flags);
+-	
++
+ 	/* XXX update other stats here */
+-	
++
+ 	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+-	
++
+ 	return &sc->sbm_stats;
+ }
+ 
+@@ -2693,8 +2698,8 @@ static void sbmac_set_rx_mode(struct net
+ 		/*
+ 		 * Promiscuous changed.
+ 		 */
+-		
+-		if (dev->flags & IFF_PROMISC) {	
++
++		if (dev->flags & IFF_PROMISC) {
+ 			/* Unconditionally log net taps. */
+ 			msg_flag = 1;
+ 			sbmac_promiscuous_mode(sc,1);
+@@ -2705,18 +2710,18 @@ static void sbmac_set_rx_mode(struct net
+ 		}
+ 	}
+ 	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+-	
++
+ 	if (msg_flag) {
+ 		printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n",
+ 		       dev->name,(msg_flag==1)?"en":"dis");
+ 	}
+-	
++
+ 	/*
+ 	 * Program the multicasts.  Do this every time.
+ 	 */
+-	
++
+ 	sbmac_setmulti(sc);
+-	
++
+ }
+ 
+ static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+@@ -2725,10 +2730,10 @@ static int sbmac_mii_ioctl(struct net_de
+ 	u16 *data = (u16 *)&rq->ifr_ifru;
+ 	unsigned long flags;
+ 	int retval;
+-	
++
+ 	spin_lock_irqsave(&sc->sbm_lock, flags);
+ 	retval = 0;
+-	
++
+ 	switch(cmd) {
+ 	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
+ 		data[0] = sc->sbm_phys[0] & 0x1f;
+@@ -2750,7 +2755,7 @@ static int sbmac_mii_ioctl(struct net_de
+ 	default:
+ 		retval = -EOPNOTSUPP;
+ 	}
+-	
++
+ 	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+ 	return retval;
+ }
+@@ -2781,7 +2786,7 @@ static int sbmac_close(struct net_device
+ 
+ 	sbdma_emptyring(&(sc->sbm_txdma));
+ 	sbdma_emptyring(&(sc->sbm_rxdma));
+-	
++
+ 	return 0;
+ }
+ 
+@@ -2793,13 +2798,13 @@ sbmac_setup_hwaddr(int chan,char *addr)
+ {
+ 	uint8_t eaddr[6];
+ 	uint64_t val;
+-	sbmac_port_t port;
++	unsigned long port;
+ 
+ 	port = A_MAC_CHANNEL_BASE(chan);
+ 	sbmac_parse_hwaddr(addr,eaddr);
+ 	val = sbmac_addr2reg(eaddr);
+-	SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),val);
+-	val = SBMAC_READCSR(IOADDR(port+R_MAC_ETHERNET_ADDR));
++	__raw_writeq(val, IOADDR(port+R_MAC_ETHERNET_ADDR));
++	val = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
+ }
+ #endif
+ 
+@@ -2810,9 +2815,9 @@ sbmac_init_module(void)
+ {
+ 	int idx;
+ 	struct net_device *dev;
+-	sbmac_port_t port;
++	unsigned long port;
+ 	int chip_max_units;
+-	
++
+ 	/*
+ 	 * For bringup when not using the firmware, we can pre-fill
+ 	 * the MAC addresses using the environment variables
+@@ -2858,13 +2863,13 @@ sbmac_init_module(void)
+ 
+ 	        port = A_MAC_CHANNEL_BASE(idx);
+ 
+-		/*	
++		/*
+ 		 * The R_MAC_ETHERNET_ADDR register will be set to some nonzero
+ 		 * value for us by the firmware if we're going to use this MAC.
+ 		 * If we find a zero, skip this MAC.
+ 		 */
+ 
+-		sbmac_orig_hwaddr[idx] = SBMAC_READCSR(IOADDR(port+R_MAC_ETHERNET_ADDR));
++		sbmac_orig_hwaddr[idx] = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
+ 		if (sbmac_orig_hwaddr[idx] == 0) {
+ 			printk(KERN_DEBUG "sbmac: not configuring MAC at "
+ 			       "%lx\n", port);
+@@ -2876,7 +2881,7 @@ sbmac_init_module(void)
+ 		 */
+ 
+ 		dev = alloc_etherdev(sizeof(struct sbmac_softc));
+-		if (!dev) 
++		if (!dev)
+ 			return -ENOMEM;	/* return ENOMEM */
+ 
+ 		printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
+@@ -2886,8 +2891,7 @@ sbmac_init_module(void)
+ 		dev->mem_end = 0;
+ 		if (sbmac_init(dev, idx)) {
+ 			port = A_MAC_CHANNEL_BASE(idx);
+-			SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),
+-				       sbmac_orig_hwaddr[idx]);
++			__raw_writeq(sbmac_orig_hwaddr[idx], IOADDR(port+R_MAC_ETHERNET_ADDR));
+ 			free_netdev(dev);
+ 			continue;
+ 		}
+diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
+--- a/drivers/net/sgiseeq.c
++++ b/drivers/net/sgiseeq.c
+@@ -32,8 +32,6 @@
+ 
+ #include "sgiseeq.h"
+ 
+-static char *version = "sgiseeq.c: David S. Miller (dm at engr.sgi.com)\n";
+-
+ static char *sgiseeqstr = "SGI Seeq8003";
+ 
+ /*
+@@ -113,9 +111,9 @@ static struct net_device *root_sgiseeq_d
+ 
+ static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
+ {
+-	hregs->rx_reset = HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ;
++	hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
+ 	udelay(20);
+-	hregs->rx_reset = 0;
++	hregs->reset = 0;
+ }
+ 
+ static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs,
+@@ -252,7 +250,6 @@ void sgiseeq_dump_rings(void)
+ 
+ #define TSTAT_INIT_SEEQ (SEEQ_TCMD_IPT|SEEQ_TCMD_I16|SEEQ_TCMD_IC|SEEQ_TCMD_IUF)
+ #define TSTAT_INIT_EDLC ((TSTAT_INIT_SEEQ) | SEEQ_TCMD_RB2)
+-#define RDMACFG_INIT    (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ)
+ 
+ static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
+ 		     struct sgiseeq_regs *sregs)
+@@ -274,8 +271,6 @@ static int init_seeq(struct net_device *
+ 		sregs->tstat = TSTAT_INIT_SEEQ;
+ 	}
+ 
+-	hregs->rx_dconfig |= RDMACFG_INIT;
+-
+ 	hregs->rx_ndptr = CPHYSADDR(sp->rx_desc);
+ 	hregs->tx_ndptr = CPHYSADDR(sp->tx_desc);
+ 
+@@ -446,7 +441,7 @@ static irqreturn_t sgiseeq_interrupt(int
+ 	spin_lock(&sp->tx_lock);
+ 
+ 	/* Ack the IRQ and set software state. */
+-	hregs->rx_reset = HPC3_ERXRST_CLRIRQ;
++	hregs->reset = HPC3_ERST_CLRIRQ;
+ 
+ 	/* Always check for received packets. */
+ 	sgiseeq_rx(dev, sp, hregs, sregs);
+@@ -493,11 +488,13 @@ static int sgiseeq_close(struct net_devi
+ {
+ 	struct sgiseeq_private *sp = netdev_priv(dev);
+ 	struct sgiseeq_regs *sregs = sp->sregs;
++	unsigned int irq = dev->irq;
+ 
+ 	netif_stop_queue(dev);
+ 
+ 	/* Shutdown the Seeq. */
+ 	reset_hpc3_and_seeq(sp->hregs, sregs);
++	free_irq(irq, dev);
+ 
+ 	return 0;
+ }
+@@ -644,7 +641,7 @@ static inline void setup_rx_ring(struct 
+ 
+ #define ALIGNED(x)  ((((unsigned long)(x)) + 0xf) & ~(0xf))
+ 
+-static int sgiseeq_init(struct hpc3_regs* regs, int irq)
++static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq)
+ {
+ 	struct sgiseeq_init_block *sr;
+ 	struct sgiseeq_private *sp;
+@@ -680,8 +677,8 @@ static int sgiseeq_init(struct hpc3_regs
+ 	gpriv = sp;
+ 	gdev = dev;
+ #endif
+-	sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0];
+-	sp->hregs = &hpc3c0->ethregs;
++	sp->sregs = (struct sgiseeq_regs *) &hpcregs->eth_ext[0];
++	sp->hregs = &hpcregs->ethregs;
+ 	sp->name = sgiseeqstr;
+ 	sp->mode = SEEQ_RCMD_RBCAST;
+ 
+@@ -698,6 +695,11 @@ static int sgiseeq_init(struct hpc3_regs
+ 	setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS);
+ 	setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS);
+ 
++	/* Setup PIO and DMA transfer timing */
++	sp->hregs->pconfig = 0x161;
++	sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP |
++			     HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026;
++
+ 	/* Reset the chip. */
+ 	hpc3_eth_reset(sp->hregs);
+ 
+@@ -724,7 +726,7 @@ static int sgiseeq_init(struct hpc3_regs
+ 		goto err_out_free_page;
+ 	}
+ 
+-	printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name);
++	printk(KERN_INFO "%s: %s ", dev->name, sgiseeqstr);
+ 	for (i = 0; i < 6; i++)
+ 		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
+ 
+@@ -734,7 +736,7 @@ static int sgiseeq_init(struct hpc3_regs
+ 	return 0;
+ 
+ err_out_free_page:
+-	free_page((unsigned long) sp);
++	free_page((unsigned long) sp->srings);
+ err_out_free_dev:
+ 	kfree(dev);
+ 
+@@ -744,8 +746,6 @@ err_out:
+ 
+ static int __init sgiseeq_probe(void)
+ {
+-	printk(version);
+-
+ 	/* On board adapter on 1st HPC is always present */
+ 	return sgiseeq_init(hpc3c0, SGI_ENET_IRQ);
+ }
+@@ -754,15 +754,12 @@ static void __exit sgiseeq_exit(void)
+ {
+ 	struct net_device *next, *dev;
+ 	struct sgiseeq_private *sp;
+-	int irq;
+ 
+ 	for (dev = root_sgiseeq_dev; dev; dev = next) {
+ 		sp = (struct sgiseeq_private *) netdev_priv(dev);
+ 		next = sp->next_module;
+-		irq = dev->irq;
+ 		unregister_netdev(dev);
+-		free_irq(irq, dev);
+-		free_page((unsigned long) sp);
++		free_page((unsigned long) sp->srings);
+ 		free_netdev(dev);
+ 	}
+ }
+@@ -770,4 +767,6 @@ static void __exit sgiseeq_exit(void)
+ module_init(sgiseeq_probe);
+ module_exit(sgiseeq_exit);
+ 
++MODULE_DESCRIPTION("SGI Seeq 8003 driver");
++MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips at linux-mips.org>");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
+--- a/drivers/net/sis190.c
++++ b/drivers/net/sis190.c
+@@ -842,7 +842,7 @@ static void sis190_set_rx_mode(struct ne
+ 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ 		     i++, mclist = mclist->next) {
+ 			int bit_nr =
+-				ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
++				ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f;
+ 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+ 			rx_mode |= AcceptMulticast;
+ 		}
+diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
+--- a/drivers/net/sis900.c
++++ b/drivers/net/sis900.c
+@@ -1696,15 +1696,20 @@ static int sis900_rx(struct net_device *
+ 	long ioaddr = net_dev->base_addr;
+ 	unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
+ 	u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
++	int rx_work_limit;
+ 
+ 	if (netif_msg_rx_status(sis_priv))
+ 		printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
+ 		       "status:0x%8.8x\n",
+ 		       sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
++	rx_work_limit = sis_priv->dirty_rx + NUM_RX_DESC - sis_priv->cur_rx;
+ 
+ 	while (rx_status & OWN) {
+ 		unsigned int rx_size;
+ 
++		if (--rx_work_limit < 0)
++			break;
++
+ 		rx_size = (rx_status & DSIZE) - CRC_SIZE;
+ 
+ 		if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
+@@ -1732,9 +1737,11 @@ static int sis900_rx(struct net_device *
+ 			   we are working on NULL sk_buff :-( */
+ 			if (sis_priv->rx_skbuff[entry] == NULL) {
+ 				if (netif_msg_rx_err(sis_priv))
+-					printk(KERN_INFO "%s: NULL pointer " 
+-						"encountered in Rx ring, skipping\n",
+-						net_dev->name);
++					printk(KERN_WARNING "%s: NULL pointer " 
++					      "encountered in Rx ring\n"
++					      "cur_rx:%4.4d, dirty_rx:%4.4d\n",
++					      net_dev->name, sis_priv->cur_rx,
++					      sis_priv->dirty_rx);
+ 				break;
+ 			}
+ 
+@@ -1770,6 +1777,7 @@ static int sis900_rx(struct net_device *
+ 				sis_priv->rx_ring[entry].cmdsts = 0;
+ 				sis_priv->rx_ring[entry].bufptr = 0;
+ 				sis_priv->stats.rx_dropped++;
++				sis_priv->cur_rx++;
+ 				break;
+ 			}
+ 			skb->dev = net_dev;
+@@ -1787,7 +1795,7 @@ static int sis900_rx(struct net_device *
+ 
+ 	/* refill the Rx buffer, what if the rate of refilling is slower
+ 	 * than consuming ?? */
+-	for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) {
++	for (; sis_priv->cur_rx != sis_priv->dirty_rx; sis_priv->dirty_rx++) {
+ 		struct sk_buff *skb;
+ 
+ 		entry = sis_priv->dirty_rx % NUM_RX_DESC;
+diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
+--- a/drivers/net/skfp/smt.c
++++ b/drivers/net/skfp/smt.c
+@@ -1896,7 +1896,7 @@ void smt_swap_para(struct smt_header *sm
+ 
+ static void smt_string_swap(char *data, const char *format, int len)
+ {
+-	const char	*open_paren = 0 ;
++	const char	*open_paren = NULL ;
+ 	int	x ;
+ 
+ 	while (len > 0  && *format) {
+diff --git a/drivers/net/skge.c b/drivers/net/skge.c
+--- a/drivers/net/skge.c
++++ b/drivers/net/skge.c
+@@ -730,6 +730,7 @@ static struct ethtool_ops skge_ethtool_o
+ 	.phys_id	= skge_phys_id,
+ 	.get_stats_count = skge_get_stats_count,
+ 	.get_ethtool_stats = skge_get_ethtool_stats,
++	.get_perm_addr	= ethtool_op_get_perm_addr,
+ };
+ 
+ /*
+@@ -3096,6 +3097,7 @@ static struct net_device *skge_devinit(s
+ 
+ 	/* read the mac address */
+ 	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
++	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+ 	/* device is off until link detection */
+ 	netif_carrier_off(dev);
+diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
+--- a/drivers/net/smc91x.c
++++ b/drivers/net/smc91x.c
+@@ -77,7 +77,7 @@ static const char version[] =
+ #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>
+@@ -1983,6 +1983,10 @@ static int __init smc_probe(struct net_d
+ 	if (lp->version >= (CHIP_91100 << 4))
+ 		smc_phy_detect(dev);
+ 
++	/* then shut everything down to save power */
++	smc_shutdown(dev);
++	smc_phy_powerdown(dev);
++
+ 	/* Set default parameters */
+ 	lp->msg_enable = NETIF_MSG_LINK;
+ 	lp->ctl_rfduplx = 0;
+@@ -2291,11 +2295,11 @@ static int smc_drv_remove(struct device 
+ 	return 0;
+ }
+ 
+-static int smc_drv_suspend(struct device *dev, pm_message_t state, u32 level)
++static int smc_drv_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct net_device *ndev = dev_get_drvdata(dev);
+ 
+-	if (ndev && level == SUSPEND_DISABLE) {
++	if (ndev) {
+ 		if (netif_running(ndev)) {
+ 			netif_device_detach(ndev);
+ 			smc_shutdown(ndev);
+@@ -2305,12 +2309,12 @@ static int smc_drv_suspend(struct device
+ 	return 0;
+ }
+ 
+-static int smc_drv_resume(struct device *dev, u32 level)
++static int smc_drv_resume(struct device *dev)
+ {
+ 	struct platform_device *pdev = to_platform_device(dev);
+ 	struct net_device *ndev = dev_get_drvdata(dev);
+ 
+-	if (ndev && level == RESUME_ENABLE) {
++	if (ndev) {
+ 		struct smc_local *lp = netdev_priv(ndev);
+ 		smc_enable_device(pdev);
+ 		if (netif_running(ndev)) {
+diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
+--- a/drivers/net/smc91x.h
++++ b/drivers/net/smc91x.h
+@@ -230,12 +230,12 @@ SMC_outw(u16 val, void __iomem *ioaddr, 
+ #define SMC_CAN_USE_16BIT	1
+ #define SMC_CAN_USE_32BIT	0
+ 
+-#define SMC_inb(a, r)		inb((a) + (r) - 0xa0000000)
+-#define SMC_inw(a, r)		inw((a) + (r) - 0xa0000000)
+-#define SMC_outb(v, a, r)	outb(v, (a) + (r) - 0xa0000000)
+-#define SMC_outw(v, a, r)	outw(v, (a) + (r) - 0xa0000000)
+-#define SMC_insw(a, r, p, l)	insw((a) + (r) - 0xa0000000, p, l)
+-#define SMC_outsw(a, r, p, l)	outsw((a) + (r) - 0xa0000000, p, l)
++#define SMC_inb(a, r)		inb((u32)a) + (r))
++#define SMC_inw(a, r)		inw(((u32)a) + (r))
++#define SMC_outb(v, a, r)	outb(v, ((u32)a) + (r))
++#define SMC_outw(v, a, r)	outw(v, ((u32)a) + (r))
++#define SMC_insw(a, r, p, l)	insw(((u32)a) + (r), p, l)
++#define SMC_outsw(a, r, p, l)	outsw(((u32)a) + (r), p, l)
+ 
+ #define set_irq_type(irq, type)	do {} while(0)
+ 
+diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
+--- a/drivers/net/starfire.c
++++ b/drivers/net/starfire.c
+@@ -1091,8 +1091,10 @@ static int netdev_open(struct net_device
+ 		rx_ring_size = sizeof(struct starfire_rx_desc) * RX_RING_SIZE;
+ 		np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size;
+ 		np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma);
+-		if (np->queue_mem == 0)
++		if (np->queue_mem == NULL) {
++			free_irq(dev->irq, dev);
+ 			return -ENOMEM;
++		}
+ 
+ 		np->tx_done_q     = np->queue_mem;
+ 		np->tx_done_q_dma = np->queue_mem_dma;
+diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
+--- a/drivers/net/sunbmac.c
++++ b/drivers/net/sunbmac.c
+@@ -214,7 +214,8 @@ static void bigmac_init_rings(struct big
+ {
+ 	struct bmac_init_block *bb = bp->bmac_block;
+ 	struct net_device *dev = bp->dev;
+-	int i, gfp_flags = GFP_KERNEL;
++	int i;
++	gfp_t gfp_flags = GFP_KERNEL;
+ 
+ 	if (from_irq || in_interrupt())
+ 		gfp_flags = GFP_ATOMIC;
+diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h
+--- a/drivers/net/sunbmac.h
++++ b/drivers/net/sunbmac.h
+@@ -339,7 +339,7 @@ struct bigmac {
+ #define ALIGNED_RX_SKB_ADDR(addr) \
+         ((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr))
+ 
+-static inline struct sk_buff *big_mac_alloc_skb(unsigned int length, int gfp_flags)
++static inline struct sk_buff *big_mac_alloc_skb(unsigned int length, gfp_t gfp_flags)
+ {
+ 	struct sk_buff *skb;
+ 
+diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
+--- a/drivers/net/sundance.c
++++ b/drivers/net/sundance.c
+@@ -80,7 +80,7 @@
+ 	  I/O access could affect performance in ARM-based system
+ 	- Add Linux software VLAN support
+ 	
+-	Version LK1.08 (D-Link):
++	Version LK1.08 (Philippe De Muyter phdm at macqel.be):
+ 	- Fix bug of custom mac address 
+ 	(StationAddr register only accept word write) 
+ 
+@@ -91,11 +91,14 @@
+ 	Version LK1.09a (ICPlus):
+ 	- Add the delay time in reading the contents of EEPROM
+ 
++	Version LK1.10 (Philippe De Muyter phdm at macqel.be):
++	- Make 'unblock interface after Tx underrun' work
++
+ */
+ 
+ #define DRV_NAME	"sundance"
+-#define DRV_VERSION	"1.01+LK1.09a"
+-#define DRV_RELDATE	"10-Jul-2003"
++#define DRV_VERSION	"1.01+LK1.10"
++#define DRV_RELDATE	"28-Oct-2005"
+ 
+ 
+ /* The user-configurable values.
+@@ -263,8 +266,10 @@ IV. Notes
+ IVb. References
+ 
+ The Sundance ST201 datasheet, preliminary version.
+-http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
+-http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
++The Kendin KS8723 datasheet, preliminary version.
++The ICplus IP100 datasheet, preliminary version.
++http://www.scyld.com/expert/100mbps.html
++http://www.scyld.com/expert/NWay.html
+ 
+ IVc. Errata
+ 
+@@ -500,6 +505,25 @@ static int netdev_ioctl(struct net_devic
+ static int  netdev_close(struct net_device *dev);
+ static struct ethtool_ops ethtool_ops;
+ 
++static void sundance_reset(struct net_device *dev, unsigned long reset_cmd)
++{
++	struct netdev_private *np = netdev_priv(dev);
++	void __iomem *ioaddr = np->base + ASICCtrl;
++	int countdown;
++
++	/* ST201 documentation states ASICCtrl is a 32bit register */
++	iowrite32 (reset_cmd | ioread32 (ioaddr), ioaddr);
++	/* ST201 documentation states reset can take up to 1 ms */
++	countdown = 10 + 1;
++	while (ioread32 (ioaddr) & (ResetBusy << 16)) {
++		if (--countdown == 0) {
++			printk(KERN_WARNING "%s : reset not completed !!\n", dev->name);
++			break;
++		}
++		udelay(100);
++	}
++}
++
+ static int __devinit sundance_probe1 (struct pci_dev *pdev,
+ 				      const struct pci_device_id *ent)
+ {
+@@ -518,6 +542,7 @@ static int __devinit sundance_probe1 (st
+ #else
+ 	int bar = 1;
+ #endif
++	int phy, phy_idx = 0;
+ 
+ 
+ /* when built into the kernel, we only print version if device is found */
+@@ -549,6 +574,7 @@ static int __devinit sundance_probe1 (st
+ 	for (i = 0; i < 3; i++)
+ 		((u16 *)dev->dev_addr)[i] =
+ 			le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
++	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+ 	dev->base_addr = (unsigned long)ioaddr;
+ 	dev->irq = irq;
+@@ -605,33 +631,31 @@ static int __devinit sundance_probe1 (st
+ 			printk("%2.2x:", dev->dev_addr[i]);
+ 	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
+ 
+-	if (1) {
+-		int phy, phy_idx = 0;
+-		np->phys[0] = 1;		/* Default setting */
+-		np->mii_preamble_required++;
+-		for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
+-			int mii_status = mdio_read(dev, phy, MII_BMSR);
+-			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+-				np->phys[phy_idx++] = phy;
+-				np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
+-				if ((mii_status & 0x0040) == 0)
+-					np->mii_preamble_required++;
+-				printk(KERN_INFO "%s: MII PHY found at address %d, status "
+-					   "0x%4.4x advertising %4.4x.\n",
+-					   dev->name, phy, mii_status, np->mii_if.advertising);
+-			}
+-		}
+-		np->mii_preamble_required--;
+-
+-		if (phy_idx == 0) {
+-			printk(KERN_INFO "%s: No MII transceiver found, aborting.  ASIC status %x\n",
+-				   dev->name, ioread32(ioaddr + ASICCtrl));
+-			goto err_out_unregister;
+-		}
+-
+-		np->mii_if.phy_id = np->phys[0];
++	np->phys[0] = 1;		/* Default setting */
++	np->mii_preamble_required++;
++	for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) {
++		int mii_status = mdio_read(dev, phy, MII_BMSR);
++		int phyx = phy & 0x1f;
++		if (mii_status != 0xffff  &&  mii_status != 0x0000) {
++			np->phys[phy_idx++] = phyx;
++			np->mii_if.advertising = mdio_read(dev, phyx, MII_ADVERTISE);
++			if ((mii_status & 0x0040) == 0)
++				np->mii_preamble_required++;
++			printk(KERN_INFO "%s: MII PHY found at address %d, status "
++				   "0x%4.4x advertising %4.4x.\n",
++				   dev->name, phyx, mii_status, np->mii_if.advertising);
++		}
++	}
++	np->mii_preamble_required--;
++
++	if (phy_idx == 0) {
++		printk(KERN_INFO "%s: No MII transceiver found, aborting.  ASIC status %x\n",
++			   dev->name, ioread32(ioaddr + ASICCtrl));
++		goto err_out_unregister;
+ 	}
+ 
++	np->mii_if.phy_id = np->phys[0];
++
+ 	/* Parse override configuration */
+ 	np->an_enable = 1;
+ 	if (card_idx < MAX_UNITS) {
+@@ -692,7 +716,7 @@ static int __devinit sundance_probe1 (st
+ 	/* Reset the chip to erase previous misconfiguration. */
+ 	if (netif_msg_hw(np))
+ 		printk("ASIC Control is %x.\n", ioread32(ioaddr + ASICCtrl));
+-	iowrite16(0x007f, ioaddr + ASICCtrl + 2);
++	iowrite16(0x00ff, ioaddr + ASICCtrl + 2);
+ 	if (netif_msg_hw(np))
+ 		printk("ASIC Control is now %x.\n", ioread32(ioaddr + ASICCtrl));
+ 
+@@ -1190,23 +1214,33 @@ static irqreturn_t intr_handler(int irq,
+ 					    ("%s: Transmit status is %2.2x.\n",
+ 				     	dev->name, tx_status);
+ 				if (tx_status & 0x1e) {
++					if (netif_msg_tx_err(np))
++						printk("%s: Transmit error status %4.4x.\n",
++							   dev->name, tx_status);
+ 					np->stats.tx_errors++;
+ 					if (tx_status & 0x10)
+ 						np->stats.tx_fifo_errors++;
+ 					if (tx_status & 0x08)
+ 						np->stats.collisions++;
++					if (tx_status & 0x04)
++						np->stats.tx_fifo_errors++;
+ 					if (tx_status & 0x02)
+ 						np->stats.tx_window_errors++;
+-					/* This reset has not been verified!. */
+-					if (tx_status & 0x10) {	/* Reset the Tx. */
+-						np->stats.tx_fifo_errors++;
+-						spin_lock(&np->lock);
+-						reset_tx(dev);
+-						spin_unlock(&np->lock);
++					/*
++					** This reset has been verified on
++					** DFE-580TX boards ! phdm at macqel.be.
++					*/
++					if (tx_status & 0x10) {	/* TxUnderrun */
++						unsigned short txthreshold;
++
++						txthreshold = ioread16 (ioaddr + TxStartThresh);
++						/* Restart Tx FIFO and transmitter */
++						sundance_reset(dev, (NetworkReset|FIFOReset|TxReset) << 16);
++						iowrite16 (txthreshold, ioaddr + TxStartThresh);
++						/* No need to reset the Tx pointer here */
+ 					}
+-					if (tx_status & 0x1e)	/* Restart the Tx. */
+-						iowrite16 (TxEnable,
+-							ioaddr + MACCtrl1);
++					/* Restart the Tx. */
++					iowrite16 (TxEnable, ioaddr + MACCtrl1);
+ 				}
+ 				/* Yup, this is a documentation bug.  It cost me *hours*. */
+ 				iowrite16 (0, ioaddr + TxStatus);
+@@ -1619,6 +1653,7 @@ static struct ethtool_ops ethtool_ops = 
+ 	.get_link = get_link,
+ 	.get_msglevel = get_msglevel,
+ 	.set_msglevel = set_msglevel,
++	.get_perm_addr = ethtool_op_get_perm_addr,
+ };
+ 
+ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
+--- a/drivers/net/tg3.c
++++ b/drivers/net/tg3.c
+@@ -37,6 +37,7 @@
+ #include <linux/tcp.h>
+ #include <linux/workqueue.h>
+ #include <linux/prefetch.h>
++#include <linux/dma-mapping.h>
+ 
+ #include <net/checksum.h>
+ 
+@@ -67,8 +68,8 @@
+ 
+ #define DRV_MODULE_NAME		"tg3"
+ #define PFX DRV_MODULE_NAME	": "
+-#define DRV_MODULE_VERSION	"3.42"
+-#define DRV_MODULE_RELDATE	"Oct 3, 2005"
++#define DRV_MODULE_VERSION	"3.43"
++#define DRV_MODULE_RELDATE	"Oct 24, 2005"
+ 
+ #define TG3_DEF_MAC_MODE	0
+ #define TG3_DEF_RX_MODE		0
+@@ -219,6 +220,10 @@ static struct pci_device_id tg3_pci_tbl[
+ 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F,
+ 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780,
+ 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S,
+@@ -466,6 +471,15 @@ static void tg3_write_mem(struct tg3 *tp
+ 	spin_unlock_irqrestore(&tp->indirect_lock, flags);
+ }
+ 
++static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val)
++{
++	/* If no workaround is needed, write to mem space directly */
++	if (tp->write32 != tg3_write_indirect_reg32)
++		tw32(NIC_SRAM_WIN_BASE + off, val);
++	else
++		tg3_write_mem(tp, off, val);
++}
++
+ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
+ {
+ 	unsigned long flags;
+@@ -570,7 +584,7 @@ static void tg3_switch_clocks(struct tg3
+ 	u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
+ 	u32 orig_clock_ctrl;
+ 
+-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
++	if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+ 		return;
+ 
+ 	orig_clock_ctrl = clock_ctrl;
+@@ -1210,7 +1224,7 @@ static int tg3_set_power_state(struct tg
+ 		     CLOCK_CTRL_ALTCLK |
+ 		     CLOCK_CTRL_PWRDOWN_PLL133);
+ 		udelay(40);
+-	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
++	} else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
+ 		/* do nothing */
+ 	} else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+ 		     (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
+@@ -3712,14 +3726,14 @@ static inline void tg3_set_mtu(struct ne
+ 	dev->mtu = new_mtu;
+ 
+ 	if (new_mtu > ETH_DATA_LEN) {
+-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
++		if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
+ 			tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
+ 			ethtool_op_set_tso(dev, 0);
+ 		}
+ 		else
+ 			tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
+ 	} else {
+-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
++		if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+ 			tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+ 		tp->tg3_flags &= ~TG3_FLAG_JUMBO_RING_ENABLE;
+ 	}
+@@ -3850,7 +3864,7 @@ static void tg3_init_rings(struct tg3 *t
+ 	memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
+ 
+ 	tp->rx_pkt_buf_sz = RX_PKT_BUF_SZ;
+-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) &&
++	if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
+ 	    (tp->dev->mtu > ETH_DATA_LEN))
+ 		tp->rx_pkt_buf_sz = RX_JUMBO_PKT_BUF_SZ;
+ 
+@@ -3905,10 +3919,8 @@ static void tg3_init_rings(struct tg3 *t
+  */
+ static void tg3_free_consistent(struct tg3 *tp)
+ {
+-	if (tp->rx_std_buffers) {
+-		kfree(tp->rx_std_buffers);
+-		tp->rx_std_buffers = NULL;
+-	}
++	kfree(tp->rx_std_buffers);
++	tp->rx_std_buffers = NULL;
+ 	if (tp->rx_std) {
+ 		pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
+ 				    tp->rx_std, tp->rx_std_mapping);
+@@ -4347,7 +4359,7 @@ static int tg3_chip_reset(struct tg3 *tp
+ 	val &= ~PCIX_CAPS_RELAXED_ORDERING;
+ 	pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val);
+ 
+-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
++	if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
+ 		u32 val;
+ 
+ 		/* Chip reset on 5780 will reset MSI enable bit,
+@@ -6003,7 +6015,7 @@ static int tg3_reset_hw(struct tg3 *tp)
+ 	tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
+ 
+ 	if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+-	    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780))
++	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+ 		limit = 8;
+ 	else
+ 		limit = 16;
+@@ -6191,14 +6203,16 @@ static void tg3_timer(unsigned long __op
+ 		tp->timer_counter = tp->timer_multiplier;
+ 	}
+ 
+-	/* Heartbeat is only sent once every 120 seconds.  */
++	/* Heartbeat is only sent once every 2 seconds.  */
+ 	if (!--tp->asf_counter) {
+ 		if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+ 			u32 val;
+ 
+-			tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_ALIVE);
+-			tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
+-			tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 3);
++			tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX,
++					   FWCMD_NICDRV_ALIVE2);
++			tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
++			/* 5 seconds timeout */
++			tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
+ 			val = tr32(GRC_RX_CPU_EVENT);
+ 			val |= (1 << 14);
+ 			tw32(GRC_RX_CPU_EVENT, val);
+@@ -6409,7 +6423,7 @@ static int tg3_open(struct net_device *d
+ 		tp->timer_counter = tp->timer_multiplier =
+ 			(HZ / tp->timer_offset);
+ 		tp->asf_counter = tp->asf_multiplier =
+-			((HZ / tp->timer_offset) * 120);
++			((HZ / tp->timer_offset) * 2);
+ 
+ 		init_timer(&tp->timer);
+ 		tp->timer.expires = jiffies + tp->timer_offset;
+@@ -7237,7 +7251,7 @@ static int tg3_get_settings(struct net_d
+ 		cmd->supported |= (SUPPORTED_1000baseT_Half |
+ 				   SUPPORTED_1000baseT_Full);
+ 
+-	if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES))
++	if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+ 		cmd->supported |= (SUPPORTED_100baseT_Half |
+ 				  SUPPORTED_100baseT_Full |
+ 				  SUPPORTED_10baseT_Half |
+@@ -7264,7 +7278,7 @@ static int tg3_set_settings(struct net_d
+ {
+ 	struct tg3 *tp = netdev_priv(dev);
+   
+-	if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
++	if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { 
+ 		/* These are the only valid advertisement bits allowed.  */
+ 		if (cmd->autoneg == AUTONEG_ENABLE &&
+ 		    (cmd->advertising & ~(ADVERTISED_1000baseT_Half |
+@@ -7272,7 +7286,17 @@ static int tg3_set_settings(struct net_d
+ 					  ADVERTISED_Autoneg |
+ 					  ADVERTISED_FIBRE)))
+ 			return -EINVAL;
+-	}
++		/* Fiber can only do SPEED_1000.  */
++		else if ((cmd->autoneg != AUTONEG_ENABLE) &&
++			 (cmd->speed != SPEED_1000))
++			return -EINVAL;
++	/* Copper cannot force SPEED_1000.  */
++	} else if ((cmd->autoneg != AUTONEG_ENABLE) &&
++		   (cmd->speed == SPEED_1000))
++		return -EINVAL;
++	else if ((cmd->speed == SPEED_1000) &&
++		 (tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
++		return -EINVAL;
+ 
+ 	tg3_full_lock(tp, 0);
+ 
+@@ -8380,7 +8404,7 @@ static void __devinit tg3_get_nvram_info
+ 	}
+ 
+ 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
+-	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)) {
++	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ 		switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
+ 			case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
+ 				tp->nvram_jedecnum = JEDEC_ATMEL;
+@@ -8980,7 +9004,7 @@ static void __devinit tg3_get_eeprom_hw_
+ 
+ 		tp->phy_id = eeprom_phy_id;
+ 		if (eeprom_phy_serdes) {
+-			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
++			if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+ 				tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
+ 			else
+ 				tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+@@ -9393,8 +9417,11 @@ static int __devinit tg3_get_invariants(
+ 	}
+ 
+ 	/* Find msi capability. */
+-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
++	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
++	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
++		tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
+ 		tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
++	}
+ 
+ 	/* Initialize misc host control in PCI block. */
+ 	tp->misc_host_ctrl |= (misc_ctrl_reg &
+@@ -9412,7 +9439,7 @@ static int __devinit tg3_get_invariants(
+ 
+ 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+ 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
+-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
++	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+ 		tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
+ 
+ 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
+@@ -9607,7 +9634,7 @@ static int __devinit tg3_get_invariants(
+ 	 * ether_setup() via the alloc_etherdev() call
+ 	 */
+ 	if (tp->dev->mtu > ETH_DATA_LEN &&
+-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780)
++	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+ 		tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
+ 
+ 	/* Determine WakeOnLan speed to use. */
+@@ -9830,7 +9857,7 @@ static int __devinit tg3_get_device_addr
+ 	mac_offset = 0x7c;
+ 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
+ 	     !(tp->tg3_flags & TG3_FLG2_SUN_570X)) ||
+-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
++	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ 		if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
+ 			mac_offset = 0xcc;
+ 		if (tg3_nvram_lock(tp))
+@@ -10148,6 +10175,9 @@ static int __devinit tg3_test_dma(struct
+ 		} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+ 			/* 5780 always in PCIX mode */
+ 			tp->dma_rwctrl |= 0x00144000;
++		} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
++			/* 5714 always in PCIX mode */
++			tp->dma_rwctrl |= 0x00148000;
+ 		} else {
+ 			tp->dma_rwctrl |= 0x001b000f;
+ 		}
+@@ -10347,6 +10377,7 @@ static char * __devinit tg3_phy_string(s
+ 	case PHY_ID_BCM5705:	return "5705";
+ 	case PHY_ID_BCM5750:	return "5750";
+ 	case PHY_ID_BCM5752:	return "5752";
++	case PHY_ID_BCM5714:	return "5714";
+ 	case PHY_ID_BCM5780:	return "5780";
+ 	case PHY_ID_BCM8002:	return "8002/serdes";
+ 	case 0:			return "serdes";
+@@ -10492,17 +10523,17 @@ static int __devinit tg3_init_one(struct
+ 	}
+ 
+ 	/* Configure DMA attributes. */
+-	err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
++	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ 	if (!err) {
+ 		pci_using_dac = 1;
+-		err = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
++		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ 		if (err < 0) {
+ 			printk(KERN_ERR PFX "Unable to obtain 64 bit DMA "
+ 			       "for consistent allocations\n");
+ 			goto err_out_free_res;
+ 		}
+ 	} else {
+-		err = pci_set_dma_mask(pdev, 0xffffffffULL);
++		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ 		if (err) {
+ 			printk(KERN_ERR PFX "No usable DMA configuration, "
+ 			       "aborting.\n");
+diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
+--- a/drivers/net/tg3.h
++++ b/drivers/net/tg3.h
+@@ -137,6 +137,7 @@
+ #define   ASIC_REV_5750			 0x04
+ #define   ASIC_REV_5752			 0x06
+ #define   ASIC_REV_5780			 0x08
++#define   ASIC_REV_5714			 0x09
+ #define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
+ #define   CHIPREV_5700_AX		 0x70
+ #define   CHIPREV_5700_BX		 0x71
+@@ -531,6 +532,8 @@
+ #define  MAC_SERDES_CFG_EDGE_SELECT	 0x00001000
+ #define MAC_SERDES_STAT			0x00000594
+ /* 0x598 --> 0x5b0 unused */
++#define SERDES_RX_CTRL			0x000005b0	/* 5780/5714 only */
++#define  SERDES_RX_SIG_DETECT		 0x00000400
+ #define SG_DIG_CTRL			0x000005b0
+ #define  SG_DIG_USING_HW_AUTONEG	 0x80000000
+ #define  SG_DIG_SOFT_RESET		 0x40000000
+@@ -1329,6 +1332,8 @@
+ #define  GRC_LCLCTRL_CLEARINT		0x00000002
+ #define  GRC_LCLCTRL_SETINT		0x00000004
+ #define  GRC_LCLCTRL_INT_ON_ATTN	0x00000008
++#define  GRC_LCLCTRL_USE_SIG_DETECT	0x00000010	/* 5714/5780 only */
++#define  GRC_LCLCTRL_USE_EXT_SIG_DETECT	0x00000020	/* 5714/5780 only */
+ #define  GRC_LCLCTRL_GPIO_INPUT3	0x00000020
+ #define  GRC_LCLCTRL_GPIO_OE3		0x00000040
+ #define  GRC_LCLCTRL_GPIO_OUTPUT3	0x00000080
+@@ -1507,6 +1512,7 @@
+ #define  FWCMD_NICDRV_IPV6ADDR_CHG	 0x00000004
+ #define  FWCMD_NICDRV_FIX_DMAR		 0x00000005
+ #define  FWCMD_NICDRV_FIX_DMAW		 0x00000006
++#define  FWCMD_NICDRV_ALIVE2		 0x0000000d
+ #define NIC_SRAM_FW_CMD_LEN_MBOX	0x00000b7c
+ #define NIC_SRAM_FW_CMD_DATA_MBOX	0x00000b80
+ #define NIC_SRAM_FW_ASF_STATUS_MBOX	0x00000c00
+@@ -2175,6 +2181,7 @@ struct tg3 {
+ 					TG3_FLG2_MII_SERDES)
+ #define TG3_FLG2_PARALLEL_DETECT	0x01000000
+ #define TG3_FLG2_ICH_WORKAROUND		0x02000000
++#define TG3_FLG2_5780_CLASS		0x04000000
+ 
+ 	u32				split_mode_max_reqs;
+ #define SPLIT_MODE_5704_MAX_REQ		3
+@@ -2222,6 +2229,7 @@ struct tg3 {
+ #define PHY_ID_BCM5705			0x600081a0
+ #define PHY_ID_BCM5750			0x60008180
+ #define PHY_ID_BCM5752			0x60008100
++#define PHY_ID_BCM5714			0x60008340
+ #define PHY_ID_BCM5780			0x60008350
+ #define PHY_ID_BCM8002			0x60010140
+ #define PHY_ID_INVALID			0xffffffff
+@@ -2246,8 +2254,8 @@ struct tg3 {
+ 	 (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
+ 	 (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
+ 	 (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
+-	 (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5780 || \
+-	 (X) == PHY_ID_BCM8002)
++	 (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
++	 (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM8002)
+ 
+ 	struct tg3_hw_stats		*hw_stats;
+ 	dma_addr_t			stats_mapping;
+diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
+--- a/drivers/net/tokenring/ibmtr.c
++++ b/drivers/net/tokenring/ibmtr.c
+@@ -318,7 +318,7 @@ static void ibmtr_cleanup_card(struct ne
+ 	if (dev->base_addr) {
+ 		outb(0,dev->base_addr+ADAPTRESET);
+ 		
+-		schedule_timeout(TR_RST_TIME); /* wait 50ms */
++		schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
+ 
+ 		outb(0,dev->base_addr+ADAPTRESETREL);
+ 	}
+@@ -854,8 +854,7 @@ static int tok_init_card(struct net_devi
+ 	writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+ 	outb(0, PIOaddr + ADAPTRESET);
+ 
+-	current->state=TASK_UNINTERRUPTIBLE;
+-	schedule_timeout(TR_RST_TIME); /* wait 50ms */
++	schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
+ 
+ 	outb(0, PIOaddr + ADAPTRESETREL);
+ #ifdef ENABLE_PAGING
+@@ -903,8 +902,8 @@ static int tok_open(struct net_device *d
+ 			DPRINTK("Adapter is up and running\n");
+ 			return 0;
+ 		}
+-		current->state=TASK_INTERRUPTIBLE;
+-		i=schedule_timeout(TR_RETRY_INTERVAL); /* wait 30 seconds */
++		i=schedule_timeout_interruptible(TR_RETRY_INTERVAL);
++							/* wait 30 seconds */
+ 		if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */
+ 	}
+ 	outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/
+diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
+--- a/drivers/net/tokenring/olympic.c
++++ b/drivers/net/tokenring/olympic.c
+@@ -1101,7 +1101,7 @@ static int olympic_close(struct net_devi
+ 
+ 	while(olympic_priv->srb_queued) {
+ 
+-		t = schedule_timeout(60*HZ); 
++		t = schedule_timeout_interruptible(60*HZ);
+ 
+         	if(signal_pending(current))	{            
+ 			printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
+diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
+--- a/drivers/net/tokenring/proteon.c
++++ b/drivers/net/tokenring/proteon.c
+@@ -29,6 +29,7 @@ static const char version[] = "proteon.c
+ #include <linux/init.h>
+ #include <linux/netdevice.h>
+ #include <linux/trdevice.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/system.h>
+ #include <asm/io.h>
+diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
+--- a/drivers/net/tokenring/skisa.c
++++ b/drivers/net/tokenring/skisa.c
+@@ -36,6 +36,7 @@ static const char version[] = "skisa.c: 
+ #include <linux/init.h>
+ #include <linux/netdevice.h>
+ #include <linux/trdevice.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/system.h>
+ #include <asm/io.h>
+diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
+--- a/drivers/net/tokenring/tms380tr.c
++++ b/drivers/net/tokenring/tms380tr.c
+@@ -1243,8 +1243,7 @@ void tms380tr_wait(unsigned long time)
+ 	
+ 	tmp = jiffies + time/(1000000/HZ);
+ 	do {
+-  		current->state 		= TASK_INTERRUPTIBLE;
+-		tmp = schedule_timeout(tmp);
++		tmp = schedule_timeout_interruptible(tmp);
+ 	} while(time_after(tmp, jiffies));
+ #else
+ 	udelay(time);
+diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
+--- a/drivers/net/tulip/de2104x.c
++++ b/drivers/net/tulip/de2104x.c
+@@ -1787,10 +1787,15 @@ static void __init de21041_get_srom_info
+ 	/* DEC now has a specification but early board makers
+ 	   just put the address in the first EEPROM locations. */
+ 	/* This does  memcmp(eedata, eedata+16, 8) */
++
++#ifndef CONFIG_MIPS_COBALT
++
+ 	for (i = 0; i < 8; i ++)
+ 		if (ee_data[i] != ee_data[16+i])
+ 			sa_offset = 20;
+ 
++#endif
++
+ 	/* store MAC address */
+ 	for (i = 0; i < 6; i ++)
+ 		de->dev->dev_addr[i] = ee_data[i + sa_offset];
+@@ -2071,8 +2076,7 @@ static int __init de_init_one (struct pc
+ 	return 0;
+ 
+ err_out_iomap:
+-	if (de->ee_data)
+-		kfree(de->ee_data);
++	kfree(de->ee_data);
+ 	iounmap(regs);
+ err_out_res:
+ 	pci_release_regions(pdev);
+@@ -2091,8 +2095,7 @@ static void __exit de_remove_one (struct
+ 	if (!dev)
+ 		BUG();
+ 	unregister_netdev(dev);
+-	if (de->ee_data)
+-		kfree(de->ee_data);
++	kfree(de->ee_data);
+ 	iounmap(de->regs);
+ 	pci_release_regions(pdev);
+ 	pci_disable_device(pdev);
+diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
+--- a/drivers/net/tulip/tulip_core.c
++++ b/drivers/net/tulip/tulip_core.c
+@@ -1727,8 +1727,7 @@ err_out_free_ring:
+ 			     tp->rx_ring, tp->rx_ring_dma);
+ 
+ err_out_mtable:
+-	if (tp->mtable)
+-		kfree (tp->mtable);
++	kfree (tp->mtable);
+ 	pci_iounmap(pdev, ioaddr);
+ 
+ err_out_free_res:
+@@ -1806,8 +1805,7 @@ static void __devexit tulip_remove_one (
+ 			     sizeof (struct tulip_rx_desc) * RX_RING_SIZE +
+ 			     sizeof (struct tulip_tx_desc) * TX_RING_SIZE,
+ 			     tp->rx_ring, tp->rx_ring_dma);
+-	if (tp->mtable)
+-		kfree (tp->mtable);
++	kfree (tp->mtable);
+ 	pci_iounmap(pdev, tp->base_addr);
+ 	free_netdev (dev);
+ 	pci_release_regions (pdev);
+diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
+--- a/drivers/net/typhoon.c
++++ b/drivers/net/typhoon.c
+@@ -419,10 +419,9 @@ typhoon_reset(void __iomem *ioaddr, int 
+ 			   TYPHOON_STATUS_WAITING_FOR_HOST)
+ 				goto out;
+ 
+-			if(wait_type == WaitSleep) {
+-				set_current_state(TASK_UNINTERRUPTIBLE);
+-				schedule_timeout(1);
+-			} else
++			if(wait_type == WaitSleep)
++				schedule_timeout_uninterruptible(1);
++			else
+ 				udelay(TYPHOON_UDELAY);
+ 		}
+ 
+diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
+--- a/drivers/net/via-rhine.c
++++ b/drivers/net/via-rhine.c
+@@ -490,6 +490,8 @@ struct rhine_private {
+ 	u8 tx_thresh, rx_thresh;
+ 
+ 	struct mii_if_info mii_if;
++	struct work_struct tx_timeout_task;
++	struct work_struct check_media_task;
+ 	void __iomem *base;
+ };
+ 
+@@ -497,6 +499,8 @@ static int  mdio_read(struct net_device 
+ static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
+ static int  rhine_open(struct net_device *dev);
+ static void rhine_tx_timeout(struct net_device *dev);
++static void rhine_tx_timeout_task(struct net_device *dev);
++static void rhine_check_media_task(struct net_device *dev);
+ static int  rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
+ static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+ static void rhine_tx(struct net_device *dev);
+@@ -814,8 +818,9 @@ static int __devinit rhine_init_one(stru
+ 
+ 	for (i = 0; i < 6; i++)
+ 		dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
++	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+-	if (!is_valid_ether_addr(dev->dev_addr)) {
++	if (!is_valid_ether_addr(dev->perm_addr)) {
+ 		rc = -EIO;
+ 		printk(KERN_ERR "Invalid MAC address\n");
+ 		goto err_out_unmap;
+@@ -850,6 +855,12 @@ static int __devinit rhine_init_one(stru
+ 	if (rp->quirks & rqRhineI)
+ 		dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
+ 
++	INIT_WORK(&rp->tx_timeout_task,
++		  (void (*)(void *))rhine_tx_timeout_task, dev);
++
++	INIT_WORK(&rp->check_media_task,
++		  (void (*)(void *))rhine_check_media_task, dev);
++
+ 	/* dev->name not defined before register_netdev()! */
+ 	rc = register_netdev(dev);
+ 	if (rc)
+@@ -1076,6 +1087,11 @@ static void rhine_check_media(struct net
+ 		   ioaddr + ChipCmd1);
+ }
+ 
++static void rhine_check_media_task(struct net_device *dev)
++{
++	rhine_check_media(dev, 0);
++}
++
+ static void init_registers(struct net_device *dev)
+ {
+ 	struct rhine_private *rp = netdev_priv(dev);
+@@ -1129,8 +1145,8 @@ static void rhine_disable_linkmon(void _
+ 	if (quirks & rqRhineI) {
+ 		iowrite8(0x01, ioaddr + MIIRegAddr);	// MII_BMSR
+ 
+-		/* Can be called from ISR. Evil. */
+-		mdelay(1);
++		/* Do not call from ISR! */
++		msleep(1);
+ 
+ 		/* 0x80 must be set immediately before turning it off */
+ 		iowrite8(0x80, ioaddr + MIICmd);
+@@ -1220,6 +1236,16 @@ static int rhine_open(struct net_device 
+ static void rhine_tx_timeout(struct net_device *dev)
+ {
+ 	struct rhine_private *rp = netdev_priv(dev);
++
++	/*
++	 * Move bulk of work outside of interrupt context
++	 */
++	schedule_work(&rp->tx_timeout_task);
++}
++
++static void rhine_tx_timeout_task(struct net_device *dev)
++{
++	struct rhine_private *rp = netdev_priv(dev);
+ 	void __iomem *ioaddr = rp->base;
+ 
+ 	printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
+@@ -1625,7 +1651,7 @@ static void rhine_error(struct net_devic
+ 	spin_lock(&rp->lock);
+ 
+ 	if (intr_status & IntrLinkChange)
+-		rhine_check_media(dev, 0);
++		schedule_work(&rp->check_media_task);
+ 	if (intr_status & IntrStatsMax) {
+ 		rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
+ 		rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
+@@ -1829,6 +1855,7 @@ static struct ethtool_ops netdev_ethtool
+ 	.set_wol		= rhine_set_wol,
+ 	.get_sg			= ethtool_op_get_sg,
+ 	.get_tx_csum		= ethtool_op_get_tx_csum,
++	.get_perm_addr		= ethtool_op_get_perm_addr,
+ };
+ 
+ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+@@ -1872,6 +1899,9 @@ static int rhine_close(struct net_device
+ 	spin_unlock_irq(&rp->lock);
+ 
+ 	free_irq(rp->pdev->irq, dev);
++
++	flush_scheduled_work();
++
+ 	free_rbufs(dev);
+ 	free_tbufs(dev);
+ 	free_ring(dev);
+diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
+--- a/drivers/net/via-velocity.c
++++ b/drivers/net/via-velocity.c
+@@ -1212,10 +1212,8 @@ static void velocity_free_td_ring(struct
+ 			velocity_free_td_ring_entry(vptr, j, i);
+ 
+ 		}
+-		if (vptr->td_infos[j]) {
+-			kfree(vptr->td_infos[j]);
+-			vptr->td_infos[j] = NULL;
+-		}
++		kfree(vptr->td_infos[j]);
++		vptr->td_infos[j] = NULL;
+ 	}
+ }
+ 
+diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
+--- a/drivers/net/wan/cosa.c
++++ b/drivers/net/wan/cosa.c
+@@ -400,7 +400,7 @@ static int __init cosa_init(void)
+ 		goto out_chrdev;
+ 	}
+ 	for (i=0; i<nr_cards; i++) {
+-		class_device_create(cosa_class, MKDEV(cosa_major, i),
++		class_device_create(cosa_class, NULL, MKDEV(cosa_major, i),
+ 				NULL, "cosa%d", i);
+ 		err = devfs_mk_cdev(MKDEV(cosa_major, i),
+ 				S_IFCHR|S_IRUSR|S_IWUSR,
+@@ -1617,8 +1617,7 @@ static int get_wait_data(struct cosa_dat
+ 			return r;
+ 		}
+ 		/* sleep if not ready to read */
+-		set_current_state(TASK_INTERRUPTIBLE);
+-		schedule_timeout(1);
++		schedule_timeout_interruptible(1);
+ 	}
+ 	printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n",
+ 		cosa_getstatus(cosa));
+@@ -1644,8 +1643,7 @@ static int put_wait_data(struct cosa_dat
+ 		}
+ #if 0
+ 		/* sleep if not ready to read */
+-		current->state = TASK_INTERRUPTIBLE;
+-		schedule_timeout(1);
++		schedule_timeout_interruptible(1);
+ #endif
+ 	}
+ 	printk(KERN_INFO "cosa%d: timeout in put_wait_data (status 0x%x)\n",
+diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
+--- a/drivers/net/wan/cycx_drv.c
++++ b/drivers/net/wan/cycx_drv.c
+@@ -109,7 +109,7 @@ static long cycx_2x_irq_options[]  = { 7
+  *		< 0	error.
+  * Context:	process */
+ 
+-int __init cycx_drv_init(void)
++static int __init cycx_drv_init(void)
+ {
+ 	printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE,
+ 			 copyright);
+@@ -119,7 +119,7 @@ int __init cycx_drv_init(void)
+ 
+ /* Module 'remove' entry point.
+  * o release all remaining system resources */
+-void cycx_drv_cleanup(void)
++static void cycx_drv_cleanup(void)
+ {
+ }
+ 
+@@ -184,8 +184,7 @@ int cycx_down(struct cycx_hw *hw)
+ }
+ 
+ /* Enable interrupt generation.  */
+-EXPORT_SYMBOL(cycx_inten);
+-void cycx_inten(struct cycx_hw *hw)
++static void cycx_inten(struct cycx_hw *hw)
+ {
+ 	writeb(0, hw->dpmbase);
+ }
+diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
+--- a/drivers/net/wan/cycx_main.c
++++ b/drivers/net/wan/cycx_main.c
+@@ -103,7 +103,7 @@ static struct cycx_device *cycx_card_arr
+  *		< 0	error.
+  * Context:	process
+  */
+-int __init cycx_init(void)
++static int __init cycx_init(void)
+ {
+ 	int cnt, err = -ENOMEM;
+ 
+diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
+--- a/drivers/net/wan/cycx_x25.c
++++ b/drivers/net/wan/cycx_x25.c
+@@ -78,6 +78,7 @@
+ 
+ #define CYCLOMX_X25_DEBUG 1
+ 
++#include <linux/ctype.h>	/* isdigit() */
+ #include <linux/errno.h>	/* return codes */
+ #include <linux/if_arp.h>       /* ARPHRD_HWX25 */
+ #include <linux/kernel.h>	/* printk(), and other useful stuff */
+@@ -418,7 +419,7 @@ static int cycx_wan_new_if(struct wan_de
+ 
+ 		/* Set channel timeouts (default if not specified) */
+ 		chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
+-	} else if (is_digit(conf->addr[0])) {	/* PVC */
++	} else if (isdigit(conf->addr[0])) {	/* PVC */
+ 		s16 lcn = dec_to_uint(conf->addr, 0);
+ 
+ 		if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
+@@ -1531,7 +1532,7 @@ static unsigned dec_to_uint(u8 *str, int
+ 	if (!len)
+ 		len = strlen(str);
+ 
+-	for (; len && is_digit(*str); ++str, --len)
++	for (; len && isdigit(*str); ++str, --len)
+ 		val = (val * 10) + (*str - (unsigned) '0');
+ 
+ 	return val;
+diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
+--- a/drivers/net/wan/dscc4.c
++++ b/drivers/net/wan/dscc4.c
+@@ -446,8 +446,8 @@ static inline unsigned int dscc4_tx_quie
+ 	return readl(dpriv->base_addr + CH0FTDA + dpriv->dev_id*4) == dpriv->ltda;
+ }
+ 
+-int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
+-		const char *msg)
++static int state_check(u32 state, struct dscc4_dev_priv *dpriv,
++		       struct net_device *dev, const char *msg)
+ {
+ 	int ret = 0;
+ 
+@@ -466,8 +466,9 @@ int state_check(u32 state, struct dscc4_
+ 	return ret;
+ }
+ 
+-void dscc4_tx_print(struct net_device *dev, struct dscc4_dev_priv *dpriv,
+-		    char *msg)
++static void dscc4_tx_print(struct net_device *dev,
++			   struct dscc4_dev_priv *dpriv,
++			   char *msg)
+ {
+ 	printk(KERN_DEBUG "%s: tx_current=%02d tx_dirty=%02d (%s)\n",
+ 	       dev->name, dpriv->tx_current, dpriv->tx_dirty, msg);
+@@ -507,7 +508,8 @@ static void dscc4_release_ring(struct ds
+ 	}
+ }
+ 
+-inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, struct net_device *dev)
++static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
++				 struct net_device *dev)
+ {
+ 	unsigned int dirty = dpriv->rx_dirty%RX_RING_SIZE;
+ 	struct RxFD *rx_fd = dpriv->rx_fd + dirty;
+@@ -542,8 +544,7 @@ static int dscc4_wait_ack_cec(struct dsc
+ 			       msg, i);
+ 			goto done;
+ 		}
+-		set_current_state(TASK_UNINTERRUPTIBLE);
+-		schedule_timeout(10);
++		schedule_timeout_uninterruptible(10);
+ 		rmb();
+ 	} while (++i > 0);
+ 	printk(KERN_ERR "%s: %s timeout\n", dev->name, msg);
+@@ -588,8 +589,7 @@ static inline int dscc4_xpr_ack(struct d
+ 		    (dpriv->iqtx[cur] & Xpr))
+ 			break;
+ 		smp_rmb();
+-		set_current_state(TASK_UNINTERRUPTIBLE);
+-		schedule_timeout(10);
++		schedule_timeout_uninterruptible(10);
+ 	} while (++i > 0);
+ 
+ 	return (i >= 0 ) ? i : -EAGAIN;
+@@ -1035,8 +1035,7 @@ static void dscc4_pci_reset(struct pci_d
+ 	/* Flush posted writes */
+ 	readl(ioaddr + GSTAR);
+ 
+-	set_current_state(TASK_UNINTERRUPTIBLE);
+-	schedule_timeout(10);
++	schedule_timeout_uninterruptible(10);
+ 
+ 	for (i = 0; i < 16; i++)
+ 		pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]);
+@@ -1894,7 +1893,7 @@ try:
+  * It failed and locked solid. Thus the introduction of a dummy skb.
+  * Problem is acknowledged in errata sheet DS5. Joy :o/
+  */
+-struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
++static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
+ {
+ 	struct sk_buff *skb;
+ 
+diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
+--- a/drivers/net/wan/farsync.c
++++ b/drivers/net/wan/farsync.c
+@@ -74,11 +74,11 @@ MODULE_LICENSE("GPL");
+ /*
+  * Modules parameters and associated varaibles
+  */
+-int fst_txq_low = FST_LOW_WATER_MARK;
+-int fst_txq_high = FST_HIGH_WATER_MARK;
+-int fst_max_reads = 7;
+-int fst_excluded_cards = 0;
+-int fst_excluded_list[FST_MAX_CARDS];
++static int fst_txq_low = FST_LOW_WATER_MARK;
++static int fst_txq_high = FST_HIGH_WATER_MARK;
++static int fst_max_reads = 7;
++static int fst_excluded_cards = 0;
++static int fst_excluded_list[FST_MAX_CARDS];
+ 
+ module_param(fst_txq_low, int, 0);
+ module_param(fst_txq_high, int, 0);
+@@ -572,13 +572,13 @@ static void do_bottom_half_rx(struct fst
+ static void fst_process_tx_work_q(unsigned long work_q);
+ static void fst_process_int_work_q(unsigned long work_q);
+ 
+-DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
+-DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
++static DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
++static DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
+ 
+-struct fst_card_info *fst_card_array[FST_MAX_CARDS];
+-spinlock_t fst_work_q_lock;
+-u64 fst_work_txq;
+-u64 fst_work_intq;
++static struct fst_card_info *fst_card_array[FST_MAX_CARDS];
++static spinlock_t fst_work_q_lock;
++static u64 fst_work_txq;
++static u64 fst_work_intq;
+ 
+ static void
+ fst_q_work_item(u64 * queue, int card_index)
+@@ -980,8 +980,7 @@ fst_issue_cmd(struct fst_port_info *port
+ 	/* Wait for any previous command to complete */
+ 	while (mbval > NAK) {
+ 		spin_unlock_irqrestore(&card->card_lock, flags);
+-		set_current_state(TASK_UNINTERRUPTIBLE);
+-		schedule_timeout(1);
++		schedule_timeout_uninterruptible(1);
+ 		spin_lock_irqsave(&card->card_lock, flags);
+ 
+ 		if (++safety > 2000) {
+@@ -1498,7 +1497,7 @@ do_bottom_half_rx(struct fst_card_info *
+  *      The interrupt service routine
+  *      Dev_id is our fst_card_info pointer
+  */
+-irqreturn_t
++static irqreturn_t
+ fst_intr(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	struct fst_card_info *card;
+diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
+--- a/drivers/net/wan/hdlc_fr.c
++++ b/drivers/net/wan/hdlc_fr.c
+@@ -330,7 +330,7 @@ static int pvc_close(struct net_device *
+ 
+ 
+ 
+-int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
++static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ {
+ 	pvc_device *pvc = dev_to_pvc(dev);
+ 	fr_proto_pvc_info info;
+diff --git a/drivers/net/wan/lmc/lmc_debug.c b/drivers/net/wan/lmc/lmc_debug.c
+--- a/drivers/net/wan/lmc/lmc_debug.c
++++ b/drivers/net/wan/lmc/lmc_debug.c
+@@ -8,10 +8,10 @@
+ /*
+  * Prints out len, max to 80 octets using printk, 20 per line
+  */
+-void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
+-{
+ #ifdef DEBUG
+ #ifdef LMC_PACKET_LOG
++void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
++{
+   int iNewLine = 1;
+   char str[80], *pstr;
+   
+@@ -43,26 +43,24 @@ void lmcConsoleLog(char *type, unsigned 
+     }
+   sprintf(pstr, "\n");
+   printk(str);
++}
+ #endif
+ #endif
+-}
+ 
+ #ifdef DEBUG
+ u_int32_t lmcEventLogIndex = 0;
+ u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
+-#endif
+ 
+ void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3)
+ {
+-#ifdef DEBUG
+   lmcEventLogBuf[lmcEventLogIndex++] = EventNum;
+   lmcEventLogBuf[lmcEventLogIndex++] = arg2;
+   lmcEventLogBuf[lmcEventLogIndex++] = arg3;
+   lmcEventLogBuf[lmcEventLogIndex++] = jiffies;
+ 
+   lmcEventLogIndex &= (LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS) - 1;
+-#endif
+ }
++#endif  /*  DEBUG  */
+ 
+ void lmc_trace(struct net_device *dev, char *msg){
+ #ifdef LMC_TRACE
+diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c
+--- a/drivers/net/wan/lmc/lmc_media.c
++++ b/drivers/net/wan/lmc/lmc_media.c
+@@ -48,14 +48,6 @@
+   */
+ 
+ /*
+- * For lack of a better place, put the SSI cable stuff here.
+- */
+-char *lmc_t1_cables[] = {
+-  "V.10/RS423", "EIA530A", "reserved", "X.21", "V.35",
+-  "EIA449/EIA530/V.36", "V.28/EIA232", "none", NULL
+-};
+-
+-/*
+  * protocol independent method.
+  */
+ static void lmc_set_protocol (lmc_softc_t * const, lmc_ctl_t *);
+diff --git a/drivers/net/wan/pc300.h b/drivers/net/wan/pc300.h
+--- a/drivers/net/wan/pc300.h
++++ b/drivers/net/wan/pc300.h
+@@ -472,24 +472,8 @@ enum pc300_loopback_cmds {
+ 
+ #ifdef __KERNEL__
+ /* Function Prototypes */
+-int dma_buf_write(pc300_t *, int, ucchar *, int);
+-int dma_buf_read(pc300_t *, int, struct sk_buff *);
+ void tx_dma_start(pc300_t *, int);
+-void rx_dma_start(pc300_t *, int);
+-void tx_dma_stop(pc300_t *, int);
+-void rx_dma_stop(pc300_t *, int);
+-int cpc_queue_xmit(struct sk_buff *, struct net_device *);
+-void cpc_net_rx(struct net_device *);
+-void cpc_sca_status(pc300_t *, int);
+-int cpc_change_mtu(struct net_device *, int);
+-int cpc_ioctl(struct net_device *, struct ifreq *, int);
+-int ch_config(pc300dev_t *);
+-int rx_config(pc300dev_t *);
+-int tx_config(pc300dev_t *);
+-void cpc_opench(pc300dev_t *);
+-void cpc_closech(pc300dev_t *);
+ int cpc_open(struct net_device *dev);
+-int cpc_close(struct net_device *dev);
+ int cpc_set_media(hdlc_device *, int);
+ #endif /* __KERNEL__ */
+ 
+diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
+--- a/drivers/net/wan/pc300_drv.c
++++ b/drivers/net/wan/pc300_drv.c
+@@ -291,6 +291,7 @@ static uclong detect_ram(pc300_t *);
+ static void plx_init(pc300_t *);
+ static void cpc_trace(struct net_device *, struct sk_buff *, char);
+ static int cpc_attach(struct net_device *, unsigned short, unsigned short);
++static int cpc_close(struct net_device *dev);
+ 
+ #ifdef CONFIG_PC300_MLPPP
+ void cpc_tty_init(pc300dev_t * dev);
+@@ -437,7 +438,7 @@ static void rx_dma_buf_check(pc300_t * c
+ 	printk("\n");
+ }
+ 
+-int dma_get_rx_frame_size(pc300_t * card, int ch)
++static int dma_get_rx_frame_size(pc300_t * card, int ch)
+ {
+ 	volatile pcsca_bd_t __iomem *ptdescr;
+ 	ucshort first_bd = card->chan[ch].rx_first_bd;
+@@ -462,7 +463,7 @@ int dma_get_rx_frame_size(pc300_t * card
+  * dma_buf_write: writes a frame to the Tx DMA buffers
+  * NOTE: this function writes one frame at a time.
+  */
+-int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
++static int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
+ {
+ 	int i, nchar;
+ 	volatile pcsca_bd_t __iomem *ptdescr;
+@@ -503,7 +504,7 @@ int dma_buf_write(pc300_t * card, int ch
+  * dma_buf_read: reads a frame from the Rx DMA buffers
+  * NOTE: this function reads one frame at a time.
+  */
+-int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
++static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
+ {
+ 	int nchar;
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+@@ -560,7 +561,7 @@ int dma_buf_read(pc300_t * card, int ch,
+ 	return (rcvd);
+ }
+ 
+-void tx_dma_stop(pc300_t * card, int ch)
++static void tx_dma_stop(pc300_t * card, int ch)
+ {
+ 	void __iomem *scabase = card->hw.scabase;
+ 	ucchar drr_ena_bit = 1 << (5 + 2 * ch);
+@@ -571,7 +572,7 @@ void tx_dma_stop(pc300_t * card, int ch)
+ 	cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
+ }
+ 
+-void rx_dma_stop(pc300_t * card, int ch)
++static void rx_dma_stop(pc300_t * card, int ch)
+ {
+ 	void __iomem *scabase = card->hw.scabase;
+ 	ucchar drr_ena_bit = 1 << (4 + 2 * ch);
+@@ -582,7 +583,7 @@ void rx_dma_stop(pc300_t * card, int ch)
+ 	cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
+ }
+ 
+-void rx_dma_start(pc300_t * card, int ch)
++static void rx_dma_start(pc300_t * card, int ch)
+ {
+ 	void __iomem *scabase = card->hw.scabase;
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+@@ -607,7 +608,7 @@ void rx_dma_start(pc300_t * card, int ch
+ /*************************/
+ /***   FALC Routines   ***/
+ /*************************/
+-void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
++static void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
+ {
+ 	void __iomem *falcbase = card->hw.falcbase;
+ 	unsigned long i = 0;
+@@ -622,7 +623,7 @@ void falc_issue_cmd(pc300_t * card, int 
+ 	cpc_writeb(falcbase + F_REG(CMDR, ch), cmd);
+ }
+ 
+-void falc_intr_enable(pc300_t * card, int ch)
++static void falc_intr_enable(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -672,7 +673,7 @@ void falc_intr_enable(pc300_t * card, in
+ 	}
+ }
+ 
+-void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
++static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
+ {
+ 	void __iomem *falcbase = card->hw.falcbase;
+ 	ucchar tshf = card->chan[ch].falc.offset;
+@@ -688,7 +689,7 @@ void falc_open_timeslot(pc300_t * card, 
+ 			(0x80 >> (timeslot & 0x07)));
+ }
+ 
+-void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
++static void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
+ {
+ 	void __iomem *falcbase = card->hw.falcbase;
+ 	ucchar tshf = card->chan[ch].falc.offset;
+@@ -704,7 +705,7 @@ void falc_close_timeslot(pc300_t * card,
+ 		   ~(0x80 >> (timeslot & 0x07)));
+ }
+ 
+-void falc_close_all_timeslots(pc300_t * card, int ch)
++static void falc_close_all_timeslots(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -726,7 +727,7 @@ void falc_close_all_timeslots(pc300_t * 
+ 	}
+ }
+ 
+-void falc_open_all_timeslots(pc300_t * card, int ch)
++static void falc_open_all_timeslots(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -758,7 +759,7 @@ void falc_open_all_timeslots(pc300_t * c
+ 	}
+ }
+ 
+-void falc_init_timeslot(pc300_t * card, int ch)
++static void falc_init_timeslot(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -776,7 +777,7 @@ void falc_init_timeslot(pc300_t * card, 
+ 	}
+ }
+ 
+-void falc_enable_comm(pc300_t * card, int ch)
++static void falc_enable_comm(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	falc_t *pfalc = (falc_t *) & chan->falc;
+@@ -792,7 +793,7 @@ void falc_enable_comm(pc300_t * card, in
+ 		   ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
+ }
+ 
+-void falc_disable_comm(pc300_t * card, int ch)
++static void falc_disable_comm(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	falc_t *pfalc = (falc_t *) & chan->falc;
+@@ -806,7 +807,7 @@ void falc_disable_comm(pc300_t * card, i
+ 		   ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
+ }
+ 
+-void falc_init_t1(pc300_t * card, int ch)
++static void falc_init_t1(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -975,7 +976,7 @@ void falc_init_t1(pc300_t * card, int ch
+ 	falc_close_all_timeslots(card, ch);
+ }
+ 
+-void falc_init_e1(pc300_t * card, int ch)
++static void falc_init_e1(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1155,7 +1156,7 @@ void falc_init_e1(pc300_t * card, int ch
+ 	falc_close_all_timeslots(card, ch);
+ }
+ 
+-void falc_init_hdlc(pc300_t * card, int ch)
++static void falc_init_hdlc(pc300_t * card, int ch)
+ {
+ 	void __iomem *falcbase = card->hw.falcbase;
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+@@ -1181,7 +1182,7 @@ void falc_init_hdlc(pc300_t * card, int 
+ 	falc_intr_enable(card, ch);
+ }
+ 
+-void te_config(pc300_t * card, int ch)
++static void te_config(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1241,7 +1242,7 @@ void te_config(pc300_t * card, int ch)
+ 	CPC_UNLOCK(card, flags);
+ }
+ 
+-void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
++static void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1397,7 +1398,7 @@ void falc_check_status(pc300_t * card, i
+ 	}
+ }
+ 
+-void falc_update_stats(pc300_t * card, int ch)
++static void falc_update_stats(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1450,7 +1451,7 @@ void falc_update_stats(pc300_t * card, i
+  *		the synchronizer and then sent to the system interface.
+  *----------------------------------------------------------------------------
+  */
+-void falc_remote_loop(pc300_t * card, int ch, int loop_on)
++static void falc_remote_loop(pc300_t * card, int ch, int loop_on)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1495,7 +1496,7 @@ void falc_remote_loop(pc300_t * card, in
+  *		coding must be identical.
+  *----------------------------------------------------------------------------
+  */
+-void falc_local_loop(pc300_t * card, int ch, int loop_on)
++static void falc_local_loop(pc300_t * card, int ch, int loop_on)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	falc_t *pfalc = (falc_t *) & chan->falc;
+@@ -1522,7 +1523,7 @@ void falc_local_loop(pc300_t * card, int
+  *		looped. They are originated by the FALC-LH transmitter.
+  *----------------------------------------------------------------------------
+  */
+-void falc_payload_loop(pc300_t * card, int ch, int loop_on)
++static void falc_payload_loop(pc300_t * card, int ch, int loop_on)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1576,7 +1577,7 @@ void falc_payload_loop(pc300_t * card, i
+  * Description:	Turns XLU bit off in the proper register
+  *----------------------------------------------------------------------------
+  */
+-void turn_off_xlu(pc300_t * card, int ch)
++static void turn_off_xlu(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1597,7 +1598,7 @@ void turn_off_xlu(pc300_t * card, int ch
+  * Description: Turns XLD bit off in the proper register
+  *----------------------------------------------------------------------------
+  */
+-void turn_off_xld(pc300_t * card, int ch)
++static void turn_off_xld(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1619,7 +1620,7 @@ void turn_off_xld(pc300_t * card, int ch
+  *		to generate a LOOP activation code over a T1/E1 line.
+  *----------------------------------------------------------------------------
+  */
+-void falc_generate_loop_up_code(pc300_t * card, int ch)
++static void falc_generate_loop_up_code(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1652,7 +1653,7 @@ void falc_generate_loop_up_code(pc300_t 
+  *		to generate a LOOP deactivation code over a T1/E1 line.
+  *----------------------------------------------------------------------------
+  */
+-void falc_generate_loop_down_code(pc300_t * card, int ch)
++static void falc_generate_loop_down_code(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1682,7 +1683,7 @@ void falc_generate_loop_down_code(pc300_
+  *		it on the reception side.
+  *----------------------------------------------------------------------------
+  */
+-void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
++static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -1729,7 +1730,7 @@ void falc_pattern_test(pc300_t * card, i
+  * Description:	This routine returns the bit error counter value
+  *----------------------------------------------------------------------------
+  */
+-ucshort falc_pattern_test_error(pc300_t * card, int ch)
++static ucshort falc_pattern_test_error(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+ 	falc_t *pfalc = (falc_t *) & chan->falc;
+@@ -1769,7 +1770,7 @@ cpc_trace(struct net_device *dev, struct
+ 	netif_rx(skb);
+ }
+ 
+-void cpc_tx_timeout(struct net_device *dev)
++static void cpc_tx_timeout(struct net_device *dev)
+ {
+ 	pc300dev_t *d = (pc300dev_t *) dev->priv;
+ 	pc300ch_t *chan = (pc300ch_t *) d->chan;
+@@ -1797,7 +1798,7 @@ void cpc_tx_timeout(struct net_device *d
+ 	netif_wake_queue(dev);
+ }
+ 
+-int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
++static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	pc300dev_t *d = (pc300dev_t *) dev->priv;
+ 	pc300ch_t *chan = (pc300ch_t *) d->chan;
+@@ -1880,7 +1881,7 @@ int cpc_queue_xmit(struct sk_buff *skb, 
+ 	return 0;
+ }
+ 
+-void cpc_net_rx(struct net_device *dev)
++static void cpc_net_rx(struct net_device *dev)
+ {
+ 	pc300dev_t *d = (pc300dev_t *) dev->priv;
+ 	pc300ch_t *chan = (pc300ch_t *) d->chan;
+@@ -2403,7 +2404,7 @@ static irqreturn_t cpc_intr(int irq, voi
+ 	return IRQ_HANDLED;
+ }
+ 
+-void cpc_sca_status(pc300_t * card, int ch)
++static void cpc_sca_status(pc300_t * card, int ch)
+ {
+ 	ucchar ilar;
+ 	void __iomem *scabase = card->hw.scabase;
+@@ -2495,7 +2496,7 @@ void cpc_sca_status(pc300_t * card, int 
+ 	}
+ }
+ 
+-void cpc_falc_status(pc300_t * card, int ch)
++static void cpc_falc_status(pc300_t * card, int ch)
+ {
+ 	pc300ch_t *chan = &card->chan[ch];
+ 	falc_t *pfalc = (falc_t *) & chan->falc;
+@@ -2523,7 +2524,7 @@ void cpc_falc_status(pc300_t * card, int
+ 	CPC_UNLOCK(card, flags);
+ }
+ 
+-int cpc_change_mtu(struct net_device *dev, int new_mtu)
++static int cpc_change_mtu(struct net_device *dev, int new_mtu)
+ {
+ 	if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU))
+ 		return -EINVAL;
+@@ -2531,7 +2532,7 @@ int cpc_change_mtu(struct net_device *de
+ 	return 0;
+ }
+ 
+-int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
++static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ {
+ 	hdlc_device *hdlc = dev_to_hdlc(dev);
+ 	pc300dev_t *d = (pc300dev_t *) dev->priv;
+@@ -2856,7 +2857,7 @@ static int clock_rate_calc(uclong rate, 
+ 	}
+ }
+ 
+-int ch_config(pc300dev_t * d)
++static int ch_config(pc300dev_t * d)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) d->chan;
+ 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+@@ -3004,7 +3005,7 @@ int ch_config(pc300dev_t * d)
+ 	return 0;
+ }
+ 
+-int rx_config(pc300dev_t * d)
++static int rx_config(pc300dev_t * d)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) d->chan;
+ 	pc300_t *card = (pc300_t *) chan->card;
+@@ -3035,7 +3036,7 @@ int rx_config(pc300dev_t * d)
+ 	return 0;
+ }
+ 
+-int tx_config(pc300dev_t * d)
++static int tx_config(pc300dev_t * d)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) d->chan;
+ 	pc300_t *card = (pc300_t *) chan->card;
+@@ -3098,7 +3099,7 @@ static int cpc_attach(struct net_device 
+ 	return 0;
+ }
+ 
+-void cpc_opench(pc300dev_t * d)
++static void cpc_opench(pc300dev_t * d)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) d->chan;
+ 	pc300_t *card = (pc300_t *) chan->card;
+@@ -3116,7 +3117,7 @@ void cpc_opench(pc300dev_t * d)
+ 		   cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
+ }
+ 
+-void cpc_closech(pc300dev_t * d)
++static void cpc_closech(pc300dev_t * d)
+ {
+ 	pc300ch_t *chan = (pc300ch_t *) d->chan;
+ 	pc300_t *card = (pc300_t *) chan->card;
+@@ -3173,7 +3174,7 @@ int cpc_open(struct net_device *dev)
+ 	return 0;
+ }
+ 
+-int cpc_close(struct net_device *dev)
++static int cpc_close(struct net_device *dev)
+ {
+ 	hdlc_device *hdlc = dev_to_hdlc(dev);
+ 	pc300dev_t *d = (pc300dev_t *) dev->priv;
+diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
+--- a/drivers/net/wan/pc300_tty.c
++++ b/drivers/net/wan/pc300_tty.c
+@@ -112,10 +112,10 @@ typedef	struct _st_cpc_tty_area {
+ static struct tty_driver serial_drv;
+ 
+ /* local variables */
+-st_cpc_tty_area	cpc_tty_area[CPC_TTY_NPORTS];
++static st_cpc_tty_area	cpc_tty_area[CPC_TTY_NPORTS];
+ 
+-int cpc_tty_cnt=0;	/* number of intrfaces configured with MLPPP */
+-int cpc_tty_unreg_flag = 0;
++static int cpc_tty_cnt = 0;	/* number of intrfaces configured with MLPPP */
++static int cpc_tty_unreg_flag = 0;
+ 
+ /* TTY functions prototype */
+ static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
+@@ -132,9 +132,9 @@ static void cpc_tty_trace(pc300dev_t *de
+ static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
+ static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);
+ 
+-int pc300_tiocmset(struct tty_struct *, struct file *,
+-			unsigned int, unsigned int);
+-int pc300_tiocmget(struct tty_struct *, struct file *);
++static int pc300_tiocmset(struct tty_struct *, struct file *,
++			  unsigned int, unsigned int);
++static int pc300_tiocmget(struct tty_struct *, struct file *);
+ 
+ /* functions called by PC300 driver */
+ void cpc_tty_init(pc300dev_t *dev);
+@@ -538,8 +538,8 @@ static int cpc_tty_chars_in_buffer(struc
+ 	return(0); 
+ } 
+ 
+-int pc300_tiocmset(struct tty_struct *tty, struct file *file,
+-			unsigned int set, unsigned int clear)
++static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
++			  unsigned int set, unsigned int clear)
+ {
+ 	st_cpc_tty_area    *cpc_tty; 
+ 
+@@ -565,7 +565,7 @@ int pc300_tiocmset(struct tty_struct *tt
+ 	return 0;
+ }
+ 
+-int pc300_tiocmget(struct tty_struct *tty, struct file *file)
++static int pc300_tiocmget(struct tty_struct *tty, struct file *file)
+ {
+ 	unsigned int result;
+ 	unsigned char status;
+diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
+--- a/drivers/net/wan/sdla.c
++++ b/drivers/net/wan/sdla.c
+@@ -182,7 +182,7 @@ static char sdla_byte(struct net_device 
+ 	return(byte);
+ }
+ 
+-void sdla_stop(struct net_device *dev)
++static void sdla_stop(struct net_device *dev)
+ {
+ 	struct frad_local *flp;
+ 
+@@ -209,7 +209,7 @@ void sdla_stop(struct net_device *dev)
+ 	}
+ }
+ 
+-void sdla_start(struct net_device *dev)
++static void sdla_start(struct net_device *dev)
+ {
+ 	struct frad_local *flp;
+ 
+@@ -247,7 +247,7 @@ void sdla_start(struct net_device *dev)
+  *
+  ***************************************************/
+ 
+-int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
++static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
+ {
+ 	unsigned long start, done, now;
+ 	char          resp, *temp;
+@@ -505,7 +505,7 @@ static int sdla_cmd(struct net_device *d
+ 
+ static int sdla_reconfig(struct net_device *dev);
+ 
+-int sdla_activate(struct net_device *slave, struct net_device *master)
++static int sdla_activate(struct net_device *slave, struct net_device *master)
+ {
+ 	struct frad_local *flp;
+ 	int i;
+@@ -527,7 +527,7 @@ int sdla_activate(struct net_device *sla
+ 	return(0);
+ }
+ 
+-int sdla_deactivate(struct net_device *slave, struct net_device *master)
++static int sdla_deactivate(struct net_device *slave, struct net_device *master)
+ {
+ 	struct frad_local *flp;
+ 	int               i;
+@@ -549,7 +549,7 @@ int sdla_deactivate(struct net_device *s
+ 	return(0);
+ }
+ 
+-int sdla_assoc(struct net_device *slave, struct net_device *master)
++static int sdla_assoc(struct net_device *slave, struct net_device *master)
+ {
+ 	struct frad_local *flp;
+ 	int               i;
+@@ -585,7 +585,7 @@ int sdla_assoc(struct net_device *slave,
+ 	return(0);
+ }
+ 
+-int sdla_deassoc(struct net_device *slave, struct net_device *master)
++static int sdla_deassoc(struct net_device *slave, struct net_device *master)
+ {
+ 	struct frad_local *flp;
+ 	int               i;
+@@ -613,7 +613,7 @@ int sdla_deassoc(struct net_device *slav
+ 	return(0);
+ }
+ 
+-int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
++static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
+ {
+ 	struct frad_local *flp;
+ 	struct dlci_local *dlp;
+@@ -1324,7 +1324,7 @@ NOTE:  This is rather a useless action r
+ 	return(0);
+ }
+ 
+-int sdla_change_mtu(struct net_device *dev, int new_mtu)
++static int sdla_change_mtu(struct net_device *dev, int new_mtu)
+ {
+ 	struct frad_local *flp;
+ 
+@@ -1337,7 +1337,7 @@ int sdla_change_mtu(struct net_device *d
+ 	return(-EOPNOTSUPP);
+ }
+ 
+-int sdla_set_config(struct net_device *dev, struct ifmap *map)
++static int sdla_set_config(struct net_device *dev, struct ifmap *map)
+ {
+ 	struct frad_local *flp;
+ 	int               i;
+diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
+--- a/drivers/net/wan/sdla_fr.c
++++ b/drivers/net/wan/sdla_fr.c
+@@ -822,7 +822,7 @@ static int new_if(struct wan_device* wan
+ 	chan->card = card;
+ 
+ 	/* verify media address */
+-	if (is_digit(conf->addr[0])) {
++	if (isdigit(conf->addr[0])) {
+ 
+ 		dlci = dec_to_uint(conf->addr, 0);
+ 
+@@ -3456,7 +3456,7 @@ static unsigned int dec_to_uint (unsigne
+ 	if (!len) 
+ 		len = strlen(str);
+ 
+-	for (val = 0; len && is_digit(*str); ++str, --len)
++	for (val = 0; len && isdigit(*str); ++str, --len)
+ 		val = (val * 10) + (*str - (unsigned)'0');
+ 
+ 	return val;
+diff --git a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c
+--- a/drivers/net/wan/sdla_x25.c
++++ b/drivers/net/wan/sdla_x25.c
+@@ -957,7 +957,7 @@ static int new_if(struct wan_device* wan
+ 		chan->hold_timeout = (conf->hold_timeout) ? 
+ 					conf->hold_timeout : 10;
+ 
+-	}else if (is_digit(conf->addr[0])){	/* PVC */
++	}else if (isdigit(conf->addr[0])){	/* PVC */
+ 		int lcn = dec_to_uint(conf->addr, 0);
+ 
+ 		if ((lcn >= card->u.x.lo_pvc) && (lcn <= card->u.x.hi_pvc)){
+@@ -3875,7 +3875,7 @@ static unsigned int dec_to_uint (unsigne
+ 	if (!len) 
+ 		len = strlen(str);
+ 
+-	for (val = 0; len && is_digit(*str); ++str, --len)
++	for (val = 0; len && isdigit(*str); ++str, --len)
+ 		val = (val * 10) + (*str - (unsigned)'0');
+ 	
+ 	return val;
+@@ -3896,9 +3896,9 @@ static unsigned int hex_to_uint (unsigne
+ 	for (val = 0; len; ++str, --len)
+ 	{
+ 		ch = *str;
+-		if (is_digit(ch))
++		if (isdigit(ch))
+ 			val = (val << 4) + (ch - (unsigned)'0');
+-		else if (is_hex_digit(ch))
++		else if (isxdigit(ch))
+ 			val = (val << 4) + ((ch & 0xDF) - (unsigned)'A' + 10);
+ 		else break;
+ 	}
+diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
+--- a/drivers/net/wan/sdladrv.c
++++ b/drivers/net/wan/sdladrv.c
+@@ -642,9 +642,7 @@ int sdla_mapmem (sdlahw_t* hw, unsigned 
+  * Enable interrupt generation.
+  */
+ 
+-EXPORT_SYMBOL(sdla_inten);
+-
+-int sdla_inten (sdlahw_t* hw)
++static int sdla_inten (sdlahw_t* hw)
+ {
+ 	unsigned port = hw->port;
+ 	int tmp, i;
+@@ -698,8 +696,7 @@ int sdla_inten (sdlahw_t* hw)
+  * Disable interrupt generation.
+  */
+ 
+-EXPORT_SYMBOL(sdla_intde);
+-
++#if 0
+ int sdla_intde (sdlahw_t* hw)
+ {
+ 	unsigned port = hw->port;
+@@ -748,14 +745,13 @@ int sdla_intde (sdlahw_t* hw)
+ 	}
+ 	return 0;
+ }
++#endif  /*  0  */
+ 
+ /*============================================================================
+  * Acknowledge SDLA hardware interrupt.
+  */
+ 
+-EXPORT_SYMBOL(sdla_intack);
+-
+-int sdla_intack (sdlahw_t* hw)
++static int sdla_intack (sdlahw_t* hw)
+ {
+ 	unsigned port = hw->port;
+ 	int tmp;
+@@ -827,8 +823,7 @@ void read_S514_int_stat (sdlahw_t* hw, u
+  * Generate an interrupt to adapter's CPU.
+  */
+ 
+-EXPORT_SYMBOL(sdla_intr);
+-
++#if 0
+ int sdla_intr (sdlahw_t* hw)
+ {
+ 	unsigned port = hw->port;
+@@ -863,6 +858,7 @@ int sdla_intr (sdlahw_t* hw)
+ 	}
+ 	return 0;
+ }
++#endif  /*  0  */
+ 
+ /*============================================================================
+  * Execute Adapter Command.
+diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
+--- a/drivers/net/wan/syncppp.c
++++ b/drivers/net/wan/syncppp.c
+@@ -221,7 +221,7 @@ static void sppp_clear_timeout(struct sp
+  *	here.
+  */
+  
+-void sppp_input (struct net_device *dev, struct sk_buff *skb)
++static void sppp_input (struct net_device *dev, struct sk_buff *skb)
+ {
+ 	struct ppp_header *h;
+ 	struct sppp *sp = (struct sppp *)sppp_of(dev);
+@@ -355,8 +355,6 @@ done:
+ 	return;
+ }
+ 
+-EXPORT_SYMBOL(sppp_input);
+-
+ /*
+  *	Handle transmit packets.
+  */
+@@ -990,7 +988,7 @@ EXPORT_SYMBOL(sppp_reopen);
+  *	the mtu is out of range.
+  */
+  
+-int sppp_change_mtu(struct net_device *dev, int new_mtu)
++static int sppp_change_mtu(struct net_device *dev, int new_mtu)
+ {
+ 	if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP))
+ 		return -EINVAL;
+@@ -998,8 +996,6 @@ int sppp_change_mtu(struct net_device *d
+ 	return 0;
+ }
+ 
+-EXPORT_SYMBOL(sppp_change_mtu);
+-
+ /**
+  *	sppp_do_ioctl - Ioctl handler for ppp/hdlc
+  *	@dev: Device subject to ioctl
+@@ -1456,7 +1452,7 @@ static int sppp_rcv(struct sk_buff *skb,
+ 	return 0;
+ }
+ 
+-struct packet_type sppp_packet_type = {
++static struct packet_type sppp_packet_type = {
+ 	.type	= __constant_htons(ETH_P_WAN_PPP),
+ 	.func	= sppp_rcv,
+ };
+diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
+--- a/drivers/net/wireless/airo.c
++++ b/drivers/net/wireless/airo.c
+@@ -35,6 +35,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/in.h>
+ #include <linux/bitops.h>
++#include <linux/scatterlist.h>
+ #include <asm/io.h>
+ #include <asm/system.h>
+ 
+@@ -1046,7 +1047,6 @@ static WifiCtlHdr wifictlhdr8023 = {
+ 	}
+ };
+ 
+-#ifdef WIRELESS_EXT
+ // Frequency list (map channels to frequencies)
+ static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+ 				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
+@@ -1067,7 +1067,6 @@ typedef struct wep_key_t {
+ 
+ /* List of Wireless Handlers (new API) */
+ static const struct iw_handler_def	airo_handler_def;
+-#endif /* WIRELESS_EXT */
+ 
+ static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
+ 
+@@ -1110,10 +1109,8 @@ static irqreturn_t airo_interrupt( int i
+ static int airo_thread(void *data);
+ static void timer_func( struct net_device *dev );
+ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+-#ifdef WIRELESS_EXT
+ static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
+ static void airo_read_wireless_stats (struct airo_info *local);
+-#endif /* WIRELESS_EXT */
+ #ifdef CISCO_EXT
+ static int readrids(struct net_device *dev, aironet_ioctl *comp);
+ static int writerids(struct net_device *dev, aironet_ioctl *comp);
+@@ -1187,12 +1184,10 @@ struct airo_info {
+ 		int fid;
+ 	} xmit, xmit11;
+ 	struct net_device *wifidev;
+-#ifdef WIRELESS_EXT
+ 	struct iw_statistics	wstats;		// wireless stats
+ 	unsigned long		scan_timestamp;	/* Time started to scan */
+ 	struct iw_spy_data	spy_data;
+ 	struct iw_public_data	wireless_data;
+-#endif /* WIRELESS_EXT */
+ #ifdef MICSUPPORT
+ 	/* MIC stuff */
+ 	struct crypto_tfm	*tfm;
+@@ -1596,11 +1591,9 @@ static void emmh32_setseed(emmh32_contex
+ 		aes_counter[12] = (u8)(counter >> 24);
+ 		counter++;
+ 		memcpy (plain, aes_counter, 16);
+-		sg[0].page = virt_to_page(plain);
+-		sg[0].offset = ((long) plain & ~PAGE_MASK);
+-		sg[0].length = 16;
++		sg_set_buf(sg, plain, 16);
+ 		crypto_cipher_encrypt(tfm, sg, sg, 16);
+-		cipher = kmap(sg[0].page) + sg[0].offset;
++		cipher = kmap(sg->page) + sg->offset;
+ 		for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) {
+ 			context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
+ 			j += 4;
+@@ -2387,14 +2380,10 @@ void stop_airo_card( struct net_device *
+ 			dev_kfree_skb(skb);
+ 	}
+ 
+-	if (ai->flash)
+-		kfree(ai->flash);
+-	if (ai->rssi)
+-		kfree(ai->rssi);
+-	if (ai->APList)
+-		kfree(ai->APList);
+-	if (ai->SSID)
+-		kfree(ai->SSID);
++	kfree(ai->flash);
++	kfree(ai->rssi);
++	kfree(ai->APList);
++	kfree(ai->SSID);
+ 	if (freeres) {
+ 		/* PCMCIA frees this stuff, so only for PCI and ISA */
+ 	        release_region( dev->base_addr, 64 );
+@@ -2527,7 +2516,8 @@ static int mpi_map_card(struct airo_info
+ 	unsigned long mem_start, mem_len, aux_start, aux_len;
+ 	int rc = -1;
+ 	int i;
+-	unsigned char *busaddroff,*vpackoff;
++	dma_addr_t busaddroff;
++	unsigned char *vpackoff;
+ 	unsigned char __iomem *pciaddroff;
+ 
+ 	mem_start = pci_resource_start(pci, 1);
+@@ -2570,7 +2560,7 @@ static int mpi_map_card(struct airo_info
+ 	/*
+ 	 * Setup descriptor RX, TX, CONFIG
+ 	 */
+-	busaddroff = (unsigned char *)ai->shared_dma;
++	busaddroff = ai->shared_dma;
+ 	pciaddroff = ai->pciaux + AUX_OFFSET;
+ 	vpackoff   = ai->shared;
+ 
+@@ -2579,7 +2569,7 @@ static int mpi_map_card(struct airo_info
+ 		ai->rxfids[i].pending = 0;
+ 		ai->rxfids[i].card_ram_off = pciaddroff;
+ 		ai->rxfids[i].virtual_host_addr = vpackoff;
+-		ai->rxfids[i].rx_desc.host_addr = (dma_addr_t) busaddroff;
++		ai->rxfids[i].rx_desc.host_addr = busaddroff;
+ 		ai->rxfids[i].rx_desc.valid = 1;
+ 		ai->rxfids[i].rx_desc.len = PKTSIZE;
+ 		ai->rxfids[i].rx_desc.rdy = 0;
+@@ -2594,7 +2584,7 @@ static int mpi_map_card(struct airo_info
+ 		ai->txfids[i].card_ram_off = pciaddroff;
+ 		ai->txfids[i].virtual_host_addr = vpackoff;
+ 		ai->txfids[i].tx_desc.valid = 1;
+-		ai->txfids[i].tx_desc.host_addr = (dma_addr_t) busaddroff;
++		ai->txfids[i].tx_desc.host_addr = busaddroff;
+ 		memcpy(ai->txfids[i].virtual_host_addr,
+ 			&wifictlhdr8023, sizeof(wifictlhdr8023));
+ 
+@@ -2607,8 +2597,8 @@ static int mpi_map_card(struct airo_info
+ 	/* Rid descriptor setup */
+ 	ai->config_desc.card_ram_off = pciaddroff;
+ 	ai->config_desc.virtual_host_addr = vpackoff;
+-	ai->config_desc.rid_desc.host_addr = (dma_addr_t) busaddroff;
+-	ai->ridbus = (dma_addr_t)busaddroff;
++	ai->config_desc.rid_desc.host_addr = busaddroff;
++	ai->ridbus = busaddroff;
+ 	ai->config_desc.rid_desc.rid = 0;
+ 	ai->config_desc.rid_desc.len = RIDSIZE;
+ 	ai->config_desc.rid_desc.valid = 1;
+@@ -2647,9 +2637,7 @@ static void wifi_setup(struct net_device
+ 	dev->get_stats = &airo_get_stats;
+ 	dev->set_mac_address = &airo_set_mac_address;
+ 	dev->do_ioctl = &airo_ioctl;
+-#ifdef WIRELESS_EXT
+ 	dev->wireless_handlers = &airo_handler_def;
+-#endif /* WIRELESS_EXT */
+ 	dev->change_mtu = &airo_change_mtu;
+ 	dev->open = &airo_open;
+ 	dev->stop = &airo_close;
+@@ -2675,9 +2663,7 @@ static struct net_device *init_wifidev(s
+ 	dev->priv = ethdev->priv;
+ 	dev->irq = ethdev->irq;
+ 	dev->base_addr = ethdev->base_addr;
+-#ifdef WIRELESS_EXT
+ 	dev->wireless_data = ethdev->wireless_data;
+-#endif /* WIRELESS_EXT */
+ 	memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
+ 	err = register_netdev(dev);
+ 	if (err<0) {
+@@ -2755,11 +2741,9 @@ static struct net_device *_init_airo_car
+ 	dev->set_multicast_list = &airo_set_multicast_list;
+ 	dev->set_mac_address = &airo_set_mac_address;
+ 	dev->do_ioctl = &airo_ioctl;
+-#ifdef WIRELESS_EXT
+ 	dev->wireless_handlers = &airo_handler_def;
+ 	ai->wireless_data.spy_data = &ai->spy_data;
+ 	dev->wireless_data = &ai->wireless_data;
+-#endif /* WIRELESS_EXT */
+ 	dev->change_mtu = &airo_change_mtu;
+ 	dev->open = &airo_open;
+ 	dev->stop = &airo_close;
+@@ -3637,10 +3621,8 @@ static u16 setup_card(struct airo_info *
+ 	int rc;
+ 
+ 	memset( &mySsid, 0, sizeof( mySsid ) );
+-	if (ai->flash) {
+-		kfree (ai->flash);
+-		ai->flash = NULL;
+-	}
++	kfree (ai->flash);
++	ai->flash = NULL;
+ 
+ 	/* The NOP is the first step in getting the card going */
+ 	cmd.cmd = NOP;
+@@ -3677,14 +3659,10 @@ static u16 setup_card(struct airo_info *
+ 		tdsRssiRid rssi_rid;
+ 		CapabilityRid cap_rid;
+ 
+-		if (ai->APList) {
+-			kfree(ai->APList);
+-			ai->APList = NULL;
+-		}
+-		if (ai->SSID) {
+-			kfree(ai->SSID);
+-			ai->SSID = NULL;
+-		}
++		kfree(ai->APList);
++		ai->APList = NULL;
++		kfree(ai->SSID);
++		ai->SSID = NULL;
+ 		// general configuration (read/modify/write)
+ 		status = readConfigRid(ai, lock);
+ 		if ( status != SUCCESS ) return ERROR;
+@@ -3698,10 +3676,8 @@ static u16 setup_card(struct airo_info *
+ 				memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
+ 		}
+ 		else {
+-			if (ai->rssi) {
+-				kfree(ai->rssi);
+-				ai->rssi = NULL;
+-			}
++			kfree(ai->rssi);
++			ai->rssi = NULL;
+ 			if (cap_rid.softCap & 8)
+ 				ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
+ 			else
+@@ -5380,11 +5356,13 @@ static int proc_BSSList_open( struct ino
+ 
+ static int proc_close( struct inode *inode, struct file *file )
+ {
+-	struct proc_data *data = (struct proc_data *)file->private_data;
+-	if ( data->on_close != NULL ) data->on_close( inode, file );
+-	if ( data->rbuffer ) kfree( data->rbuffer );
+-	if ( data->wbuffer ) kfree( data->wbuffer );
+-	kfree( data );
++	struct proc_data *data = file->private_data;
++
++	if (data->on_close != NULL)
++		data->on_close(inode, file);
++	kfree(data->rbuffer);
++	kfree(data->wbuffer);
++	kfree(data);
+ 	return 0;
+ }
+ 
+@@ -5515,12 +5493,13 @@ static int airo_pci_resume(struct pci_de
+ 	struct net_device *dev = pci_get_drvdata(pdev);
+ 	struct airo_info *ai = dev->priv;
+ 	Resp rsp;
++	pci_power_t prev_state = pdev->current_state;
+ 
+-	pci_set_power_state(pdev, 0);
++	pci_set_power_state(pdev, PCI_D0);
+ 	pci_restore_state(pdev);
+-	pci_enable_wake(pdev, pci_choose_state(pdev, ai->power), 0);
++	pci_enable_wake(pdev, PCI_D0, 0);
+ 
+-	if (ai->power.event > 1) {
++	if (prev_state != PCI_D1) {
+ 		reset_card(dev, 0);
+ 		mpi_init_descriptors(ai);
+ 		setup_card(ai, dev->dev_addr, 0);
+@@ -5598,7 +5577,6 @@ static void __exit airo_cleanup_module( 
+ 	remove_proc_entry("aironet", proc_root_driver);
+ }
+ 
+-#ifdef WIRELESS_EXT
+ /*
+  * Initial Wireless Extension code for Aironet driver by :
+  *	Jean Tourrilhes <jt at hpl.hp.com> - HPL - 17 November 00
+@@ -7107,8 +7085,6 @@ static const struct iw_handler_def	airo_
+ 	.get_wireless_stats = airo_get_wireless_stats,
+ };
+ 
+-#endif /* WIRELESS_EXT */
+-
+ /*
+  * This defines the configuration part of the Wireless Extensions
+  * Note : irq and spinlock protection will occur in the subroutines
+@@ -7187,7 +7163,6 @@ static int airo_ioctl(struct net_device 
+ 	return rc;
+ }
+ 
+-#ifdef WIRELESS_EXT
+ /*
+  * Get the Wireless stats out of the driver
+  * Note : irq and spinlock protection will occur in the subroutines
+@@ -7260,7 +7235,6 @@ static struct iw_statistics *airo_get_wi
+ 
+ 	return &local->wstats;
+ }
+-#endif /* WIRELESS_EXT */
+ 
+ #ifdef CISCO_EXT
+ /*
+diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
+--- a/drivers/net/wireless/airo_cs.c
++++ b/drivers/net/wireless/airo_cs.c
+@@ -258,9 +258,7 @@ static void airo_detach(dev_link_t *link
+ 	
+ 	/* Unlink device structure, free pieces */
+ 	*linkp = link->next;
+-	if (link->priv) {
+-		kfree(link->priv);
+-	}
++	kfree(link->priv);
+ 	kfree(link);
+ 	
+ } /* airo_detach */
+diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
+--- a/drivers/net/wireless/airport.c
++++ b/drivers/net/wireless/airport.c
+@@ -15,28 +15,11 @@
+ #define PFX DRIVER_NAME ": "
+ 
+ #include <linux/config.h>
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/timer.h>
+-#include <linux/ioport.h>
+-#include <linux/netdevice.h>
+-#include <linux/if_arp.h>
+-#include <linux/etherdevice.h>
+-#include <linux/wireless.h>
+-
+-#include <asm/io.h>
+-#include <asm/system.h>
+-#include <asm/current.h>
+-#include <asm/prom.h>
+-#include <asm/machdep.h>
++#include <linux/delay.h>
+ #include <asm/pmac_feature.h>
+-#include <asm/irq.h>
+-#include <asm/uaccess.h>
+ 
+ #include "orinoco.h"
+ 
+diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
+--- a/drivers/net/wireless/atmel.c
++++ b/drivers/net/wireless/atmel.c
+@@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_p
+ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
+ static void atmel_command_irq(struct atmel_private *priv);
+ static int atmel_validate_channel(struct atmel_private *priv, int channel);
+-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header, 
++static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+ 				   u16 frame_len, u8 rssi);
+ static void atmel_management_timer(u_long a);
+ static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
+ static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
+-static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
++static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
+ 					    u8 *body, int body_len);
+ 
+ static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
+@@ -827,7 +827,7 @@ static void tx_update_descriptor(struct 
+ static int start_tx (struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct atmel_private *priv = netdev_priv(dev);
+-	struct ieee80211_hdr header;
++	struct ieee80211_hdr_4addr header;
+ 	unsigned long flags;
+ 	u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
+ 	u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+@@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb
+ }
+ 
+ static void atmel_transmit_management_frame(struct atmel_private *priv, 
+-					    struct ieee80211_hdr *header,
++					    struct ieee80211_hdr_4addr *header,
+ 					    u8 *body, int body_len)
+ {
+ 	u16 buff;
+@@ -917,7 +917,7 @@ static void atmel_transmit_management_fr
+ 	tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
+ }
+ 	
+-static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header, 
++static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+ 			 u16 msdu_size, u16 rx_packet_loc, u32 crc)
+ {
+ 	/* fast path: unfragmented packet copy directly into skbuf */
+@@ -990,7 +990,7 @@ static int probe_crc(struct atmel_privat
+ 	return (crc ^ 0xffffffff) == netcrc;
+ }
+ 
+-static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header, 
++static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+ 			 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
+ {
+ 	u8 mac4[6]; 
+@@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_pr
+ static void rx_done_irq(struct atmel_private *priv)
+ {
+ 	int i;
+-	struct ieee80211_hdr header;
++	struct ieee80211_hdr_4addr header;
+ 	
+ 	for (i = 0; 
+ 	     atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
+@@ -1653,8 +1653,7 @@ void stop_atmel_card(struct net_device *
+ 	unregister_netdev(dev);
+ 	remove_proc_entry("driver/atmel", NULL);
+ 	free_irq(dev->irq, dev);
+-	if (priv->firmware)
+-		kfree(priv->firmware);
++	kfree(priv->firmware);
+ 	if (freeres) {
+ 		/* PCMCIA frees this stuff, so only for PCI */
+ 	        release_region(dev->base_addr, 64);
+@@ -2450,8 +2449,7 @@ static int atmel_ioctl(struct net_device
+ 			break;
+ 		}
+ 
+-		if (priv->firmware)
+-			kfree(priv->firmware);
++		kfree(priv->firmware);
+ 		
+ 		priv->firmware = new_firmware;
+ 		priv->firmware_length = com.len;
+@@ -2650,7 +2648,7 @@ static void handle_beacon_probe(struct a
+  
+ static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
+ {
+-	struct ieee80211_hdr header;
++	struct ieee80211_hdr_4addr header;
+ 	struct auth_body auth;
+ 	
+ 	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); 
+@@ -2688,7 +2686,7 @@ static void send_association_request(str
+ {
+ 	u8 *ssid_el_p;
+ 	int bodysize;
+-	struct ieee80211_hdr header;
++	struct ieee80211_hdr_4addr header;
+ 	struct ass_req_format {
+ 		u16 capability;
+ 		u16 listen_interval; 
+@@ -2738,7 +2736,7 @@ static void send_association_request(str
+ 	atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
+ }
+ 
+-static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr *header)
++static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr_4addr *header)
+ {
+ 	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
+ 		return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
+@@ -2788,7 +2786,7 @@ static int retrieve_bss(struct atmel_pri
+ }
+ 
+ 
+-static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr *header,
++static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
+ 			   u16 capability, u16 beacon_period, u8 channel, u8 rssi, 
+ 			   u8 ssid_len, u8 *ssid, int is_beacon)
+ {
+@@ -3072,7 +3070,7 @@ static void atmel_smooth_qual(struct atm
+ }
+ 
+ /* deals with incoming managment frames. */
+-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header, 
++static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+ 		      u16 frame_len, u8 rssi)
+ {
+ 	u16 subtype;
+diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
+--- a/drivers/net/wireless/atmel_cs.c
++++ b/drivers/net/wireless/atmel_cs.c
+@@ -259,8 +259,7 @@ static void atmel_detach(dev_link_t *lin
+ 
+ 	/* Unlink device structure, free pieces */
+ 	*linkp = link->next;
+-	if (link->priv)
+-		kfree(link->priv);
++	kfree(link->priv);
+ 	kfree(link);
+ }
+ 
+diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
+--- a/drivers/net/wireless/hermes.c
++++ b/drivers/net/wireless/hermes.c
+@@ -39,17 +39,10 @@
+  */
+ 
+ #include <linux/config.h>
+-
+ #include <linux/module.h>
+-#include <linux/types.h>
+-#include <linux/threads.h>
+-#include <linux/smp.h>
+-#include <asm/io.h>
+-#include <linux/delay.h>
+-#include <linux/init.h>
+ #include <linux/kernel.h>
+-#include <linux/net.h>
+-#include <asm/errno.h>
++#include <linux/init.h>
++#include <linux/delay.h>
+ 
+ #include "hermes.h"
+ 
+@@ -451,6 +444,43 @@ int hermes_bap_pwrite(hermes_t *hw, int 
+ 	return err;
+ }
+ 
++/* Write a block of data to the chip's buffer with padding if
++ * neccessary, via the BAP. Synchronization/serialization is the
++ * caller's problem. len must be even.
++ *
++ * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
++ */
++int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, unsigned len,
++		      u16 id, u16 offset)
++{
++	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
++	int err = 0;
++
++	if (len < 0 || len % 2 || data_len > len)
++		return -EINVAL;
++
++	err = hermes_bap_seek(hw, bap, id, offset);
++	if (err)
++		goto out;
++
++	/* Transfer all the complete words of data */
++	hermes_write_words(hw, dreg, buf, data_len/2);
++	/* If there is an odd byte left over pad and transfer it */
++	if (data_len & 1) {
++		u8 end[2];
++		end[1] = 0;
++		end[0] = ((unsigned char *)buf)[data_len - 1];
++		hermes_write_words(hw, dreg, end, 1);
++		data_len ++;
++	}
++	/* Now send zeros for the padding */
++	if (data_len < len)
++		hermes_clear_words(hw, dreg, (len - data_len) / 2);
++	/* Complete */
++ out:
++	return err;
++}
++
+ /* Read a Length-Type-Value record from the card.
+  *
+  * If length is NULL, we ignore the length read from the card, and
+@@ -538,6 +568,7 @@ EXPORT_SYMBOL(hermes_allocate);
+ 
+ EXPORT_SYMBOL(hermes_bap_pread);
+ EXPORT_SYMBOL(hermes_bap_pwrite);
++EXPORT_SYMBOL(hermes_bap_pwrite_pad);
+ EXPORT_SYMBOL(hermes_read_ltv);
+ EXPORT_SYMBOL(hermes_write_ltv);
+ 
+diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
+--- a/drivers/net/wireless/hermes.h
++++ b/drivers/net/wireless/hermes.h
+@@ -30,9 +30,8 @@
+  * access to the hermes_t structure, and to the hardware
+ */
+ 
+-#include <linux/delay.h>
+ #include <linux/if_ether.h>
+-#include <asm/byteorder.h>
++#include <asm/io.h>
+ 
+ /*
+  * Limits and constants
+@@ -192,13 +191,13 @@
+ #define	HERMES_RXSTAT_WMP		(0x6000)	/* Wavelan-II Management Protocol frame */
+ 
+ struct hermes_tx_descriptor {
+-	u16 status;
+-	u16 reserved1;
+-	u16 reserved2;
+-	u32 sw_support;
++	__le16 status;
++	__le16 reserved1;
++	__le16 reserved2;
++	__le32 sw_support;
+ 	u8 retry_count;
+ 	u8 tx_rate;
+-	u16 tx_control;	
++	__le16 tx_control;	
+ } __attribute__ ((packed));
+ 
+ #define HERMES_TXSTAT_RETRYERR		(0x0001)
+@@ -222,60 +221,60 @@ struct hermes_tx_descriptor {
+ #define HERMES_INQ_SEC_STAT_AGERE	(0xF202)
+ 
+ struct hermes_tallies_frame {
+-	u16 TxUnicastFrames;
+-	u16 TxMulticastFrames;
+-	u16 TxFragments;
+-	u16 TxUnicastOctets;
+-	u16 TxMulticastOctets;
+-	u16 TxDeferredTransmissions;
+-	u16 TxSingleRetryFrames;
+-	u16 TxMultipleRetryFrames;
+-	u16 TxRetryLimitExceeded;
+-	u16 TxDiscards;
+-	u16 RxUnicastFrames;
+-	u16 RxMulticastFrames;
+-	u16 RxFragments;
+-	u16 RxUnicastOctets;
+-	u16 RxMulticastOctets;
+-	u16 RxFCSErrors;
+-	u16 RxDiscards_NoBuffer;
+-	u16 TxDiscardsWrongSA;
+-	u16 RxWEPUndecryptable;
+-	u16 RxMsgInMsgFragments;
+-	u16 RxMsgInBadMsgFragments;
++	__le16 TxUnicastFrames;
++	__le16 TxMulticastFrames;
++	__le16 TxFragments;
++	__le16 TxUnicastOctets;
++	__le16 TxMulticastOctets;
++	__le16 TxDeferredTransmissions;
++	__le16 TxSingleRetryFrames;
++	__le16 TxMultipleRetryFrames;
++	__le16 TxRetryLimitExceeded;
++	__le16 TxDiscards;
++	__le16 RxUnicastFrames;
++	__le16 RxMulticastFrames;
++	__le16 RxFragments;
++	__le16 RxUnicastOctets;
++	__le16 RxMulticastOctets;
++	__le16 RxFCSErrors;
++	__le16 RxDiscards_NoBuffer;
++	__le16 TxDiscardsWrongSA;
++	__le16 RxWEPUndecryptable;
++	__le16 RxMsgInMsgFragments;
++	__le16 RxMsgInBadMsgFragments;
+ 	/* Those last are probably not available in very old firmwares */
+-	u16 RxDiscards_WEPICVError;
+-	u16 RxDiscards_WEPExcluded;
++	__le16 RxDiscards_WEPICVError;
++	__le16 RxDiscards_WEPExcluded;
+ } __attribute__ ((packed));
+ 
+ /* Grabbed from wlan-ng - Thanks Mark... - Jean II
+  * This is the result of a scan inquiry command */
+ /* Structure describing info about an Access Point */
+ struct prism2_scan_apinfo {
+-	u16 channel;		/* Channel where the AP sits */
+-	u16 noise;		/* Noise level */
+-	u16 level;		/* Signal level */
++	__le16 channel;		/* Channel where the AP sits */
++	__le16 noise;		/* Noise level */
++	__le16 level;		/* Signal level */
+ 	u8 bssid[ETH_ALEN];	/* MAC address of the Access Point */
+-	u16 beacon_interv;	/* Beacon interval */
+-	u16 capabilities;	/* Capabilities */
+-	u16 essid_len;		/* ESSID length */
++	__le16 beacon_interv;	/* Beacon interval */
++	__le16 capabilities;	/* Capabilities */
++	__le16 essid_len;	/* ESSID length */
+ 	u8 essid[32];		/* ESSID of the network */
+ 	u8 rates[10];		/* Bit rate supported */
+-	u16 proberesp_rate;	/* Data rate of the response frame */
+-	u16 atim;		/* ATIM window time, Kus (hostscan only) */
++	__le16 proberesp_rate;	/* Data rate of the response frame */
++	__le16 atim;		/* ATIM window time, Kus (hostscan only) */
+ } __attribute__ ((packed));
+ 
+ /* Same stuff for the Lucent/Agere card.
+  * Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
+ struct agere_scan_apinfo {
+-	u16 channel;		/* Channel where the AP sits */
+-	u16 noise;		/* Noise level */
+-	u16 level;		/* Signal level */
++	__le16 channel;		/* Channel where the AP sits */
++	__le16 noise;		/* Noise level */
++	__le16 level;		/* Signal level */
+ 	u8 bssid[ETH_ALEN];	/* MAC address of the Access Point */
+-	u16 beacon_interv;	/* Beacon interval */
+-	u16 capabilities;	/* Capabilities */
++	__le16 beacon_interv;	/* Beacon interval */
++	__le16 capabilities;	/* Capabilities */
+ 	/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
+-	u16 essid_len;		/* ESSID length */
++	__le16 essid_len;	/* ESSID length */
+ 	u8 essid[32];		/* ESSID of the network */
+ } __attribute__ ((packed));
+ 
+@@ -283,16 +282,16 @@ struct agere_scan_apinfo {
+ struct symbol_scan_apinfo {
+ 	u8 channel;		/* Channel where the AP sits */
+ 	u8 unknown1;		/* 8 in 2.9x and 3.9x f/w, 0 otherwise */
+-	u16 noise;		/* Noise level */
+-	u16 level;		/* Signal level */
++	__le16 noise;		/* Noise level */
++	__le16 level;		/* Signal level */
+ 	u8 bssid[ETH_ALEN];	/* MAC address of the Access Point */
+-	u16 beacon_interv;	/* Beacon interval */
+-	u16 capabilities;	/* Capabilities */
++	__le16 beacon_interv;	/* Beacon interval */
++	__le16 capabilities;	/* Capabilities */
+ 	/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
+-	u16 essid_len;		/* ESSID length */
++	__le16 essid_len;	/* ESSID length */
+ 	u8 essid[32];		/* ESSID of the network */
+-    	u16 rates[5];		/* Bit rate supported */
+-	u16 basic_rates;	/* Basic rates bitmask */
++    	__le16 rates[5];	/* Bit rate supported */
++	__le16 basic_rates;	/* Basic rates bitmask */
+ 	u8 unknown2[6];		/* Always FF:FF:FF:FF:00:00 */
+ 	u8 unknown3[8];		/* Always 0, appeared in f/w 3.91-68 */
+ } __attribute__ ((packed));
+@@ -312,7 +311,7 @@ union hermes_scan_info {
+ #define HERMES_LINKSTATUS_ASSOC_FAILED    (0x0006)
+   
+ struct hermes_linkstatus {
+-	u16 linkstatus;         /* Link status */
++	__le16 linkstatus;         /* Link status */
+ } __attribute__ ((packed));
+ 
+ struct hermes_response {
+@@ -321,8 +320,8 @@ struct hermes_response {
+ 
+ /* "ID" structure - used for ESSID and station nickname */
+ struct hermes_idstring {
+-	u16 len;
+-	u16 val[16];
++	__le16 len;
++	__le16 val[16];
+ } __attribute__ ((packed));
+ 
+ struct hermes_multicast {
+@@ -377,6 +376,8 @@ int hermes_bap_pread(hermes_t *hw, int b
+ 		       u16 id, u16 offset);
+ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
+ 			u16 id, u16 offset);
++int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf,
++			unsigned data_len, unsigned len, u16 id, u16 offset);
+ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
+ 		    u16 *length, void *buf);
+ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
+@@ -447,7 +448,7 @@ static inline void hermes_clear_words(st
+ 
+ static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
+ {
+-	u16 rec;
++	__le16 rec;
+ 	int err;
+ 
+ 	err = HERMES_READ_RECORD(hw, bap, rid, &rec);
+@@ -457,7 +458,7 @@ static inline int hermes_read_wordrec(he
+ 
+ static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
+ {
+-	u16 rec = cpu_to_le16(word);
++	__le16 rec = cpu_to_le16(word);
+ 	return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
+ }
+ 
+diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
+--- a/drivers/net/wireless/hostap/hostap.c
++++ b/drivers/net/wireless/hostap/hostap.c
+@@ -716,9 +716,6 @@ static int prism2_close(struct net_devic
+ 		hostap_deauth_all_stas(dev, local->ap, 1);
+ #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
+ 
+-	if (local->func->dev_close && local->func->dev_close(local))
+-		return 0;
+-
+ 	if (dev == local->dev) {
+ 		local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL);
+ 	}
+@@ -766,9 +763,6 @@ static int prism2_open(struct net_device
+ 	    local->hw_downloading)
+ 		return -ENODEV;
+ 
+-	if (local->func->dev_open && local->func->dev_open(local))
+-		return 1;
+-
+ 	if (!try_module_get(local->hw_module))
+ 		return -ENODEV;
+ 	local->num_dev_open++;
+diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
+--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
++++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
+@@ -6,10 +6,10 @@
+ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
+ 			  struct hostap_80211_rx_status *rx_stats)
+ {
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u16 fc;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 
+ 	printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
+ 	       "jiffies=%ld\n",
+@@ -51,7 +51,7 @@ int prism2_rx_80211(struct net_device *d
+ 	int hdrlen, phdrlen, head_need, tail_need;
+ 	u16 fc;
+ 	int prism_header, ret;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 
+ 	iface = netdev_priv(dev);
+ 	local = iface->local;
+@@ -70,7 +70,7 @@ int prism2_rx_80211(struct net_device *d
+ 		phdrlen = 0;
+ 	}
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 
+ 	if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
+@@ -215,7 +215,7 @@ prism2_frag_cache_find(local_info_t *loc
+ 
+ /* Called only as a tasklet (software IRQ) */
+ static struct sk_buff *
+-prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
++prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
+ {
+ 	struct sk_buff *skb = NULL;
+ 	u16 sc;
+@@ -229,7 +229,7 @@ prism2_frag_cache_get(local_info_t *loca
+ 	if (frag == 0) {
+ 		/* Reserve enough space to fit maximum frame length */
+ 		skb = dev_alloc_skb(local->dev->mtu +
+-				    sizeof(struct ieee80211_hdr) +
++				    sizeof(struct ieee80211_hdr_4addr) +
+ 				    8 /* LLC */ +
+ 				    2 /* alignment */ +
+ 				    8 /* WEP */ + ETH_ALEN /* WDS */);
+@@ -267,7 +267,7 @@ prism2_frag_cache_get(local_info_t *loca
+ 
+ /* Called only as a tasklet (software IRQ) */
+ static int prism2_frag_cache_invalidate(local_info_t *local,
+-					struct ieee80211_hdr *hdr)
++					struct ieee80211_hdr_4addr *hdr)
+ {
+ 	u16 sc;
+ 	unsigned int seq;
+@@ -441,7 +441,7 @@ hostap_rx_frame_mgmt(local_info_t *local
+ 		     u16 stype)
+ {
+ 	if (local->iw_mode == IW_MODE_MASTER) {
+-		hostap_update_sta_ps(local, (struct ieee80211_hdr *)
++		hostap_update_sta_ps(local, (struct ieee80211_hdr_4addr *)
+ 				     skb->data);
+ 	}
+ 
+@@ -520,7 +520,7 @@ static inline struct net_device *prism2_
+ 
+ 
+ static inline int
+-hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr,
++hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
+ 		    u16 fc, struct net_device **wds)
+ {
+ 	/* FIX: is this really supposed to accept WDS frames only in Master
+@@ -579,13 +579,13 @@ static int hostap_is_eapol_frame(local_i
+ {
+ 	struct net_device *dev = local->dev;
+ 	u16 fc, ethertype;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u8 *pos;
+ 
+ 	if (skb->len < 24)
+ 		return 0;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 
+ 	/* check that the frame is unicast frame to us */
+@@ -619,13 +619,13 @@ static inline int
+ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
+ 			struct ieee80211_crypt_data *crypt)
+ {
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	int res, hdrlen;
+ 
+ 	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
+ 		return 0;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+ 
+ 	if (local->tkip_countermeasures &&
+@@ -658,13 +658,13 @@ static inline int
+ hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
+ 			     int keyidx, struct ieee80211_crypt_data *crypt)
+ {
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	int res, hdrlen;
+ 
+ 	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
+ 		return 0;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+ 
+ 	atomic_inc(&crypt->refcnt);
+@@ -689,7 +689,7 @@ void hostap_80211_rx(struct net_device *
+ {
+ 	struct hostap_interface *iface;
+ 	local_info_t *local;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	size_t hdrlen;
+ 	u16 fc, type, stype, sc;
+ 	struct net_device *wds = NULL;
+@@ -716,7 +716,7 @@ void hostap_80211_rx(struct net_device *
+ 	dev = local->ddev;
+ 	iface = netdev_priv(dev);
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	stats = hostap_get_stats(dev);
+ 
+ 	if (skb->len < 10)
+@@ -737,7 +737,8 @@ void hostap_80211_rx(struct net_device *
+ 		struct iw_quality wstats;
+ 		wstats.level = rx_stats->signal;
+ 		wstats.noise = rx_stats->noise;
+-		wstats.updated = 6;	/* No qual value */
++		wstats.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED
++			| IW_QUAL_QUAL_INVALID | IW_QUAL_DBM;
+ 		/* Update spy records */
+ 		wireless_spy_update(dev, hdr->addr2, &wstats);
+ 	}
+@@ -889,7 +890,7 @@ void hostap_80211_rx(struct net_device *
+ 	if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
+ 	    (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
+ 		goto rx_dropped;
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 
+ 	/* skb: hdr + (possibly fragmented) plaintext payload */
+ 
+@@ -941,7 +942,7 @@ void hostap_80211_rx(struct net_device *
+ 		/* this was the last fragment and the frame will be
+ 		 * delivered, so remove skb from fragment cache */
+ 		skb = frag_skb;
+-		hdr = (struct ieee80211_hdr *) skb->data;
++		hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 		prism2_frag_cache_invalidate(local, hdr);
+ 	}
+ 
+@@ -952,7 +953,7 @@ void hostap_80211_rx(struct net_device *
+ 	    hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
+ 		goto rx_dropped;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
+ 		if (local->ieee_802_1x &&
+ 		    hostap_is_eapol_frame(local, skb)) {
+diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
+--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
++++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
+@@ -1,9 +1,9 @@
+ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
+ {
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u16 fc;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 
+ 	printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
+ 	       name, skb->len, jiffies);
+@@ -41,7 +41,7 @@ int hostap_data_start_xmit(struct sk_buf
+ 	struct hostap_interface *iface;
+ 	local_info_t *local;
+ 	int need_headroom, need_tailroom = 0;
+-	struct ieee80211_hdr hdr;
++	struct ieee80211_hdr_4addr hdr;
+ 	u16 fc, ethertype = 0;
+ 	enum {
+ 		WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
+@@ -244,7 +244,7 @@ int hostap_mgmt_start_xmit(struct sk_buf
+ 	struct hostap_interface *iface;
+ 	local_info_t *local;
+ 	struct hostap_skb_tx_data *meta;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u16 fc;
+ 
+ 	iface = netdev_priv(dev);
+@@ -266,7 +266,7 @@ int hostap_mgmt_start_xmit(struct sk_buf
+ 	meta->iface = iface;
+ 
+ 	if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
+-		hdr = (struct ieee80211_hdr *) skb->data;
++		hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 		fc = le16_to_cpu(hdr->frame_ctl);
+ 		if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
+ 		    WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
+@@ -289,7 +289,7 @@ struct sk_buff * hostap_tx_encrypt(struc
+ {
+ 	struct hostap_interface *iface;
+ 	local_info_t *local;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u16 fc;
+ 	int hdr_len, res;
+ 
+@@ -303,7 +303,7 @@ struct sk_buff * hostap_tx_encrypt(struc
+ 
+ 	if (local->tkip_countermeasures &&
+ 	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
+-		hdr = (struct ieee80211_hdr *) skb->data;
++		hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 		if (net_ratelimit()) {
+ 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
+ 			       "TX packet to " MACSTR "\n",
+@@ -317,15 +317,15 @@ struct sk_buff * hostap_tx_encrypt(struc
+ 	if (skb == NULL)
+ 		return NULL;
+ 
+-	if ((skb_headroom(skb) < crypt->ops->extra_prefix_len ||
+-	     skb_tailroom(skb) < crypt->ops->extra_postfix_len) &&
+-	    pskb_expand_head(skb, crypt->ops->extra_prefix_len,
+-			     crypt->ops->extra_postfix_len, GFP_ATOMIC)) {
++	if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
++	     skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
++	    pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
++			     crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
+ 		kfree_skb(skb);
+ 		return NULL;
+ 	}
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+  	fc = le16_to_cpu(hdr->frame_ctl);
+ 	hdr_len = hostap_80211_get_hdrlen(fc);
+ 
+@@ -360,7 +360,7 @@ int hostap_master_start_xmit(struct sk_b
+ 	ap_tx_ret tx_ret;
+ 	struct hostap_skb_tx_data *meta;
+ 	int no_encrypt = 0;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 
+ 	iface = netdev_priv(dev);
+ 	local = iface->local;
+@@ -403,7 +403,7 @@ int hostap_master_start_xmit(struct sk_b
+ 	tx_ret = hostap_handle_sta_tx(local, &tx);
+ 	skb = tx.skb;
+ 	meta = (struct hostap_skb_tx_data *) skb->cb;
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+  	fc = le16_to_cpu(hdr->frame_ctl);
+ 	switch (tx_ret) {
+ 	case AP_TX_CONTINUE:
+diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
+--- a/drivers/net/wireless/hostap/hostap_ap.c
++++ b/drivers/net/wireless/hostap/hostap_ap.c
+@@ -591,14 +591,14 @@ static void hostap_ap_tx_cb(struct sk_bu
+ {
+ 	struct ap_data *ap = data;
+ 	u16 fc;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 
+ 	if (!ap->local->hostapd || !ap->local->apdev) {
+ 		dev_kfree_skb(skb);
+ 		return;
+ 	}
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 
+ 	/* Pass the TX callback frame to the hostapd; use 802.11 header version
+@@ -623,7 +623,7 @@ static void hostap_ap_tx_cb_auth(struct 
+ {
+ 	struct ap_data *ap = data;
+ 	struct net_device *dev = ap->local->dev;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u16 fc, *pos, auth_alg, auth_transaction, status;
+ 	struct sta_info *sta = NULL;
+ 	char *txt = NULL;
+@@ -633,7 +633,7 @@ static void hostap_ap_tx_cb_auth(struct 
+ 		return;
+ 	}
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 	if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
+ 	    WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
+@@ -692,7 +692,7 @@ static void hostap_ap_tx_cb_assoc(struct
+ {
+ 	struct ap_data *ap = data;
+ 	struct net_device *dev = ap->local->dev;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u16 fc, *pos, status;
+ 	struct sta_info *sta = NULL;
+ 	char *txt = NULL;
+@@ -702,7 +702,7 @@ static void hostap_ap_tx_cb_assoc(struct
+ 		return;
+ 	}
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 	if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
+ 	    (WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
+@@ -757,12 +757,12 @@ static void hostap_ap_tx_cb_assoc(struct
+ static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
+ {
+ 	struct ap_data *ap = data;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	struct sta_info *sta;
+ 
+ 	if (skb->len < 24)
+ 		goto fail;
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	if (ok) {
+ 		spin_lock(&ap->sta_table_lock);
+ 		sta = ap_get_sta(ap, hdr->addr1);
+@@ -918,7 +918,7 @@ static void prism2_send_mgmt(struct net_
+ {
+ 	struct hostap_interface *iface;
+ 	local_info_t *local;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u16 fc;
+ 	struct sk_buff *skb;
+ 	struct hostap_skb_tx_data *meta;
+@@ -944,7 +944,7 @@ static void prism2_send_mgmt(struct net_
+ 
+ 	fc = type_subtype;
+ 	hdrlen = hostap_80211_get_hdrlen(fc);
+-	hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
++	hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
+ 	if (body)
+ 		memcpy(skb_put(skb, body_len), body, body_len);
+ 
+@@ -1256,14 +1256,14 @@ static char * ap_auth_make_challenge(str
+ 	}
+ 
+ 	skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
+-			    ap->crypt->extra_prefix_len +
+-			    ap->crypt->extra_postfix_len);
++			    ap->crypt->extra_mpdu_prefix_len +
++			    ap->crypt->extra_mpdu_postfix_len);
+ 	if (skb == NULL) {
+ 		kfree(tmpbuf);
+ 		return NULL;
+ 	}
+ 
+-	skb_reserve(skb, ap->crypt->extra_prefix_len);
++	skb_reserve(skb, ap->crypt->extra_mpdu_prefix_len);
+ 	memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
+ 	       WLAN_AUTH_CHALLENGE_LEN);
+ 	if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
+@@ -1272,7 +1272,7 @@ static char * ap_auth_make_challenge(str
+ 		return NULL;
+ 	}
+ 
+-	memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
++	memcpy(tmpbuf, skb->data + ap->crypt->extra_mpdu_prefix_len,
+ 	       WLAN_AUTH_CHALLENGE_LEN);
+ 	dev_kfree_skb(skb);
+ 
+@@ -1285,7 +1285,7 @@ static void handle_authen(local_info_t *
+ 			  struct hostap_80211_rx_status *rx_stats)
+ {
+ 	struct net_device *dev = local->dev;
+-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
++	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	size_t hdrlen;
+ 	struct ap_data *ap = local->ap;
+ 	char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
+@@ -1498,7 +1498,7 @@ static void handle_assoc(local_info_t *l
+ 			 struct hostap_80211_rx_status *rx_stats, int reassoc)
+ {
+ 	struct net_device *dev = local->dev;
+-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
++	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	char body[12], *p, *lpos;
+ 	int len, left;
+ 	u16 *pos;
+@@ -1705,7 +1705,7 @@ static void handle_deauth(local_info_t *
+ 			  struct hostap_80211_rx_status *rx_stats)
+ {
+ 	struct net_device *dev = local->dev;
+-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
++	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
+ 	int len;
+ 	u16 reason_code, *pos;
+@@ -1746,7 +1746,7 @@ static void handle_disassoc(local_info_t
+ 			    struct hostap_80211_rx_status *rx_stats)
+ {
+ 	struct net_device *dev = local->dev;
+-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
++	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
+ 	int len;
+ 	u16 reason_code, *pos;
+@@ -1784,7 +1784,7 @@ static void handle_disassoc(local_info_t
+ 
+ /* Called only as a scheduled task for pending AP frames. */
+ static void ap_handle_data_nullfunc(local_info_t *local,
+-				    struct ieee80211_hdr *hdr)
++				    struct ieee80211_hdr_4addr *hdr)
+ {
+ 	struct net_device *dev = local->dev;
+ 
+@@ -1801,7 +1801,7 @@ static void ap_handle_data_nullfunc(loca
+ 
+ /* Called only as a scheduled task for pending AP frames. */
+ static void ap_handle_dropped_data(local_info_t *local,
+-				   struct ieee80211_hdr *hdr)
++				   struct ieee80211_hdr_4addr *hdr)
+ {
+ 	struct net_device *dev = local->dev;
+ 	struct sta_info *sta;
+@@ -1860,7 +1860,7 @@ static void pspoll_send_buffered(local_i
+ 
+ /* Called only as a scheduled task for pending AP frames. */
+ static void handle_pspoll(local_info_t *local,
+-			  struct ieee80211_hdr *hdr,
++			  struct ieee80211_hdr_4addr *hdr,
+ 			  struct hostap_80211_rx_status *rx_stats)
+ {
+ 	struct net_device *dev = local->dev;
+@@ -1979,7 +1979,7 @@ static void handle_wds_oper_queue(void *
+ static void handle_beacon(local_info_t *local, struct sk_buff *skb,
+ 			  struct hostap_80211_rx_status *rx_stats)
+ {
+-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
++	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
+ 	int len, left;
+ 	u16 *pos, beacon_int, capability;
+@@ -2137,11 +2137,11 @@ static void handle_ap_item(local_info_t 
+ 	struct net_device *dev = local->dev;
+ #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
+ 	u16 fc, type, stype;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 
+ 	/* FIX: should give skb->len to handler functions and check that the
+ 	 * buffer is long enough */
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 	type = WLAN_FC_GET_TYPE(fc);
+ 	stype = WLAN_FC_GET_STYPE(fc);
+@@ -2258,7 +2258,7 @@ void hostap_rx(struct net_device *dev, s
+ 	struct hostap_interface *iface;
+ 	local_info_t *local;
+ 	u16 fc;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 
+ 	iface = netdev_priv(dev);
+ 	local = iface->local;
+@@ -2268,7 +2268,7 @@ void hostap_rx(struct net_device *dev, s
+ 
+ 	local->stats.rx_packets++;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 
+ 	if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
+@@ -2289,7 +2289,7 @@ void hostap_rx(struct net_device *dev, s
+ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
+ {
+ 	struct sk_buff *skb;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	struct hostap_80211_rx_status rx_stats;
+ 
+ 	if (skb_queue_empty(&sta->tx_buf))
+@@ -2302,7 +2302,7 @@ static void schedule_packet_send(local_i
+ 		return;
+ 	}
+ 
+-	hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
++	hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
+ 
+ 	/* Generate a fake pspoll frame to start packet delivery */
+ 	hdr->frame_ctl = __constant_cpu_to_le16(
+@@ -2349,7 +2349,7 @@ static int prism2_ap_get_sta_qual(local_
+ 		qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
+ 		qual[count].updated = sta->last_rx_updated;
+ 
+-		sta->last_rx_updated = 0;
++		sta->last_rx_updated = IW_QUAL_DBM;
+ 
+ 		count++;
+ 		if (count >= buf_size)
+@@ -2467,7 +2467,7 @@ static int prism2_ap_translate_scan(stru
+ 		}
+ #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
+ 
+-		sta->last_rx_updated = 0;
++		sta->last_rx_updated = IW_QUAL_DBM;
+ 
+ 		/* To be continued, we should make good use of IWEVCUSTOM */
+ 	}
+@@ -2685,7 +2685,7 @@ ap_tx_ret hostap_handle_sta_tx(local_inf
+ 	struct sta_info *sta = NULL;
+ 	struct sk_buff *skb = tx->skb;
+ 	int set_tim, ret;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	struct hostap_skb_tx_data *meta;
+ 
+ 	meta = (struct hostap_skb_tx_data *) skb->cb;
+@@ -2694,7 +2694,7 @@ ap_tx_ret hostap_handle_sta_tx(local_inf
+ 	    meta->iface->type == HOSTAP_INTERFACE_STA)
+ 		goto out;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 
+ 	if (hdr->addr1[0] & 0x01) {
+ 		/* broadcast/multicast frame - no AP related processing */
+@@ -2821,10 +2821,10 @@ void hostap_handle_sta_release(void *ptr
+ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
+ {
+ 	struct sta_info *sta;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	struct hostap_skb_tx_data *meta;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 	meta = (struct hostap_skb_tx_data *) skb->cb;
+ 
+ 	spin_lock(&local->ap->sta_table_lock);
+@@ -2892,7 +2892,7 @@ static void hostap_update_sta_ps2(local_
+ 
+ /* Called only as a tasklet (software IRQ). Called for each RX frame to update
+  * STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
+-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
++int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
+ {
+ 	struct sta_info *sta;
+ 	u16 fc;
+@@ -2925,12 +2925,12 @@ ap_rx_ret hostap_handle_sta_rx(local_inf
+ 	int ret;
+ 	struct sta_info *sta;
+ 	u16 fc, type, stype;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 
+ 	if (local->ap == NULL)
+ 		return AP_RX_CONTINUE;
+ 
+-	hdr = (struct ieee80211_hdr *) skb->data;
++	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ 
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 	type = WLAN_FC_GET_TYPE(fc);
+@@ -3058,7 +3058,7 @@ ap_rx_ret hostap_handle_sta_rx(local_inf
+ 
+ /* Called only as a tasklet (software IRQ) */
+ int hostap_handle_sta_crypto(local_info_t *local,
+-			     struct ieee80211_hdr *hdr,
++			     struct ieee80211_hdr_4addr *hdr,
+ 			     struct ieee80211_crypt_data **crypt,
+ 			     void **sta_ptr)
+ {
+@@ -3160,7 +3160,7 @@ int hostap_add_sta(struct ap_data *ap, u
+ 
+ /* Called only as a tasklet (software IRQ) */
+ int hostap_update_rx_stats(struct ap_data *ap,
+-			   struct ieee80211_hdr *hdr,
++			   struct ieee80211_hdr_4addr *hdr,
+ 			   struct hostap_80211_rx_status *rx_stats)
+ {
+ 	struct sta_info *sta;
+@@ -3174,7 +3174,7 @@ int hostap_update_rx_stats(struct ap_dat
+ 		sta->last_rx_silence = rx_stats->noise;
+ 		sta->last_rx_signal = rx_stats->signal;
+ 		sta->last_rx_rate = rx_stats->rate;
+-		sta->last_rx_updated = 7;
++		sta->last_rx_updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+ 		if (rx_stats->rate == 10)
+ 			sta->rx_count[0]++;
+ 		else if (rx_stats->rate == 20)
+diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
+--- a/drivers/net/wireless/hostap/hostap_ap.h
++++ b/drivers/net/wireless/hostap/hostap_ap.h
+@@ -233,7 +233,7 @@ struct hostap_tx_data {
+ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
+ void hostap_handle_sta_release(void *ptr);
+ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
+-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
++int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr);
+ typedef enum {
+ 	AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
+ } ap_rx_ret;
+@@ -241,13 +241,13 @@ ap_rx_ret hostap_handle_sta_rx(local_inf
+ 			       struct sk_buff *skb,
+ 			       struct hostap_80211_rx_status *rx_stats,
+ 			       int wds);
+-int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
++int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
+ 			     struct ieee80211_crypt_data **crypt,
+ 			     void **sta_ptr);
+ int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
+ int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
+ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
+-int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
++int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr_4addr *hdr,
+ 			   struct hostap_80211_rx_status *rx_stats);
+ void hostap_update_rates(local_info_t *local);
+ void hostap_add_wds_links(local_info_t *local);
+diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
+--- a/drivers/net/wireless/hostap/hostap_cs.c
++++ b/drivers/net/wireless/hostap/hostap_cs.c
+@@ -492,42 +492,10 @@ static void prism2_pccard_genesis_reset(
+ }
+ 
+ 
+-static int prism2_pccard_dev_open(local_info_t *local)
+-{
+-	struct hostap_cs_priv *hw_priv = local->hw_priv;
+-	hw_priv->link->open++;
+-	return 0;
+-}
+-
+-
+-static int prism2_pccard_dev_close(local_info_t *local)
+-{
+-	struct hostap_cs_priv *hw_priv;
+-
+-	if (local == NULL || local->hw_priv == NULL)
+-		return 1;
+-	hw_priv = local->hw_priv;
+-	if (hw_priv->link == NULL)
+-		return 1;
+-
+-	if (!hw_priv->link->open) {
+-		printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
+-		       "link not open?!\n", local->dev->name);
+-		return 1;
+-	}
+-
+-	hw_priv->link->open--;
+-
+-	return 0;
+-}
+-
+-
+ static struct prism2_helper_functions prism2_pccard_funcs =
+ {
+ 	.card_present	= prism2_pccard_card_present,
+ 	.cor_sreset	= prism2_pccard_cor_sreset,
+-	.dev_open	= prism2_pccard_dev_open,
+-	.dev_close	= prism2_pccard_dev_close,
+ 	.genesis_reset	= prism2_pccard_genesis_reset,
+ 	.hw_type	= HOSTAP_HW_PCCARD,
+ };
+@@ -597,13 +565,14 @@ static void prism2_detach(dev_link_t *li
+ 	*linkp = link->next;
+ 	/* release net devices */
+ 	if (link->priv) {
++		struct hostap_cs_priv *hw_priv;
+ 		struct net_device *dev;
+ 		struct hostap_interface *iface;
+ 		dev = link->priv;
+ 		iface = netdev_priv(dev);
+-		kfree(iface->local->hw_priv);
+-		iface->local->hw_priv = NULL;
++		hw_priv = iface->local->hw_priv;
+ 		prism2_free_local_data(dev);
++		kfree(hw_priv);
+ 	}
+ 	kfree(link);
+ }
+@@ -883,6 +852,13 @@ static int prism2_event(event_t event, i
+ {
+ 	dev_link_t *link = args->client_data;
+ 	struct net_device *dev = (struct net_device *) link->priv;
++	int dev_open = 0;
++
++	if (link->state & DEV_CONFIG) {
++		struct hostap_interface *iface = netdev_priv(dev);
++		if (iface && iface->local)
++			dev_open = iface->local->num_dev_open > 0;
++	}
+ 
+ 	switch (event) {
+ 	case CS_EVENT_CARD_INSERTION:
+@@ -911,7 +887,7 @@ static int prism2_event(event_t event, i
+ 	case CS_EVENT_RESET_PHYSICAL:
+ 		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
+ 		if (link->state & DEV_CONFIG) {
+-			if (link->open) {
++			if (dev_open) {
+ 				netif_stop_queue(dev);
+ 				netif_device_detach(dev);
+ 			}
+@@ -931,8 +907,8 @@ static int prism2_event(event_t event, i
+ 			pcmcia_request_configuration(link->handle,
+ 						     &link->conf);
+ 			prism2_hw_shutdown(dev, 1);
+-			prism2_hw_config(dev, link->open ? 0 : 1);
+-			if (link->open) {
++			prism2_hw_config(dev, dev_open ? 0 : 1);
++			if (dev_open) {
+ 				netif_device_attach(dev);
+ 				netif_start_queue(dev);
+ 			}
+diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
+--- a/drivers/net/wireless/hostap/hostap_hw.c
++++ b/drivers/net/wireless/hostap/hostap_hw.c
+@@ -3322,6 +3322,18 @@ static void prism2_free_local_data(struc
+ 	iface = netdev_priv(dev);
+ 	local = iface->local;
+ 
++	/* Unregister all netdevs before freeing local data. */
++	list_for_each_safe(ptr, n, &local->hostap_interfaces) {
++		iface = list_entry(ptr, struct hostap_interface, list);
++		if (iface->type == HOSTAP_INTERFACE_MASTER) {
++			/* special handling for this interface below */
++			continue;
++		}
++		hostap_remove_interface(iface->dev, 0, 1);
++	}
++
++	unregister_netdev(local->dev);
++
+ 	flush_scheduled_work();
+ 
+ 	if (timer_pending(&local->crypt_deinit_timer))
+@@ -3382,15 +3394,6 @@ static void prism2_free_local_data(struc
+ 	prism2_download_free_data(local->dl_sec);
+ #endif /* PRISM2_DOWNLOAD_SUPPORT */
+ 
+-	list_for_each_safe(ptr, n, &local->hostap_interfaces) {
+-		iface = list_entry(ptr, struct hostap_interface, list);
+-		if (iface->type == HOSTAP_INTERFACE_MASTER) {
+-			/* special handling for this interface below */
+-			continue;
+-		}
+-		hostap_remove_interface(iface->dev, 0, 1);
+-	}
+-
+ 	prism2_clear_set_tim_queue(local);
+ 
+ 	list_for_each_safe(ptr, n, &local->bss_list) {
+@@ -3403,7 +3406,6 @@ static void prism2_free_local_data(struc
+ 	kfree(local->last_scan_results);
+ 	kfree(local->generic_elem);
+ 
+-	unregister_netdev(local->dev);
+ 	free_netdev(local->dev);
+ }
+ 
+diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
+--- a/drivers/net/wireless/hostap/hostap_ioctl.c
++++ b/drivers/net/wireless/hostap/hostap_ioctl.c
+@@ -50,7 +50,8 @@ static struct iw_statistics *hostap_get_
+ #endif /* in_atomic */
+ 
+ 		if (update && prism2_update_comms_qual(dev) == 0)
+-			wstats->qual.updated = 7;
++			wstats->qual.updated = IW_QUAL_ALL_UPDATED |
++				IW_QUAL_DBM;
+ 
+ 		wstats->qual.qual = local->comms_qual;
+ 		wstats->qual.level = local->avg_signal;
+@@ -59,7 +60,7 @@ static struct iw_statistics *hostap_get_
+ 		wstats->qual.qual = 0;
+ 		wstats->qual.level = 0;
+ 		wstats->qual.noise = 0;
+-		wstats->qual.updated = 0;
++		wstats->qual.updated = IW_QUAL_ALL_INVALID;
+ 	}
+ 
+ 	return wstats;
+@@ -551,7 +552,6 @@ static int prism2_ioctl_giwaplist(struct
+ 
+ 	kfree(addr);
+ 	kfree(qual);
+-
+ 	return 0;
+ }
+ 
+@@ -1827,13 +1827,6 @@ static char * __prism2_translate_scan(lo
+ 	iwe.cmd = SIOCGIWAP;
+ 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ 	memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
+-	/* FIX:
+-	 * I do not know how this is possible, but iwe_stream_add_event
+-	 * seems to re-order memcpy execution so that len is set only
+-	 * after copying.. Pre-setting len here "fixes" this, but real
+-	 * problems should be solved (after which these iwe.len
+-	 * settings could be removed from this function). */
+-	iwe.len = IW_EV_ADDR_LEN;
+ 	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+ 					  IW_EV_ADDR_LEN);
+ 
+@@ -1843,7 +1836,6 @@ static char * __prism2_translate_scan(lo
+ 	iwe.cmd = SIOCGIWESSID;
+ 	iwe.u.data.length = ssid_len;
+ 	iwe.u.data.flags = 1;
+-	iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
+ 	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
+ 
+ 	memset(&iwe, 0, sizeof(iwe));
+@@ -1859,7 +1851,6 @@ static char * __prism2_translate_scan(lo
+ 			iwe.u.mode = IW_MODE_MASTER;
+ 		else
+ 			iwe.u.mode = IW_MODE_ADHOC;
+-		iwe.len = IW_EV_UINT_LEN;
+ 		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+ 						  IW_EV_UINT_LEN);
+ 	}
+@@ -1877,7 +1868,6 @@ static char * __prism2_translate_scan(lo
+ 	if (chan > 0) {
+ 		iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
+ 		iwe.u.freq.e = 1;
+-		iwe.len = IW_EV_FREQ_LEN;
+ 		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+ 						  IW_EV_FREQ_LEN);
+ 	}
+@@ -1894,7 +1884,10 @@ static char * __prism2_translate_scan(lo
+ 			iwe.u.qual.noise =
+ 				HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
+ 		}
+-		iwe.len = IW_EV_QUAL_LEN;
++		iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
++			| IW_QUAL_NOISE_UPDATED
++			| IW_QUAL_QUAL_INVALID
++			| IW_QUAL_DBM;
+ 		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+ 						  IW_EV_QUAL_LEN);
+ 	}
+@@ -1906,7 +1899,6 @@ static char * __prism2_translate_scan(lo
+ 	else
+ 		iwe.u.data.flags = IW_ENCODE_DISABLED;
+ 	iwe.u.data.length = 0;
+-	iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
+ 	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+ 
+ 	/* TODO: add SuppRates into BSS table */
+@@ -1930,7 +1922,7 @@ static char * __prism2_translate_scan(lo
+ 	}
+ 
+ 	/* TODO: add BeaconInt,resp_rate,atim into BSS table */
+-	buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
++	buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_ATOMIC);
+ 	if (buf && scan) {
+ 		memset(&iwe, 0, sizeof(iwe));
+ 		iwe.cmd = IWEVCUSTOM;
+@@ -3088,9 +3080,7 @@ static int prism2_ioctl_priv_download(lo
+ 	ret = local->func->download(local, param);
+ 
+  out:
+-	if (param != NULL)
+-		kfree(param);
+-
++	kfree(param);
+ 	return ret;
+ }
+ #endif /* PRISM2_DOWNLOAD_SUPPORT */
+@@ -3897,9 +3887,7 @@ static int prism2_ioctl_priv_hostapd(loc
+ 	}
+ 
+  out:
+-	if (param != NULL)
+-		kfree(param);
+-
++	kfree(param);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
+--- a/drivers/net/wireless/hostap/hostap_pci.c
++++ b/drivers/net/wireless/hostap/hostap_pci.c
+@@ -59,11 +59,13 @@ static struct pci_device_id prism2_pci_i
+ static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
+ {
+ 	struct hostap_interface *iface;
++	struct hostap_pci_priv *hw_priv;
+ 	local_info_t *local;
+ 	unsigned long flags;
+ 
+ 	iface = netdev_priv(dev);
+ 	local = iface->local;
++	hw_priv = local->hw_priv;
+ 
+ 	spin_lock_irqsave(&local->lock, flags);
+ 	prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
+@@ -74,12 +76,14 @@ static inline void hfa384x_outb_debug(st
+ static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
+ {
+ 	struct hostap_interface *iface;
++	struct hostap_pci_priv *hw_priv;
+ 	local_info_t *local;
+ 	unsigned long flags;
+ 	u8 v;
+ 
+ 	iface = netdev_priv(dev);
+ 	local = iface->local;
++	hw_priv = local->hw_priv;
+ 
+ 	spin_lock_irqsave(&local->lock, flags);
+ 	v = readb(hw_priv->mem_start + a);
+@@ -91,11 +95,13 @@ static inline u8 hfa384x_inb_debug(struc
+ static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
+ {
+ 	struct hostap_interface *iface;
++	struct hostap_pci_priv *hw_priv;
+ 	local_info_t *local;
+ 	unsigned long flags;
+ 
+ 	iface = netdev_priv(dev);
+ 	local = iface->local;
++	hw_priv = local->hw_priv;
+ 
+ 	spin_lock_irqsave(&local->lock, flags);
+ 	prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
+@@ -106,12 +112,14 @@ static inline void hfa384x_outw_debug(st
+ static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
+ {
+ 	struct hostap_interface *iface;
++	struct hostap_pci_priv *hw_priv;
+ 	local_info_t *local;
+ 	unsigned long flags;
+ 	u16 v;
+ 
+ 	iface = netdev_priv(dev);
+ 	local = iface->local;
++	hw_priv = local->hw_priv;
+ 
+ 	spin_lock_irqsave(&local->lock, flags);
+ 	v = readw(hw_priv->mem_start + a);
+@@ -277,8 +285,6 @@ static struct prism2_helper_functions pr
+ {
+ 	.card_present	= NULL,
+ 	.cor_sreset	= prism2_pci_cor_sreset,
+-	.dev_open	= NULL,
+-	.dev_close	= NULL,
+ 	.genesis_reset	= prism2_pci_genesis_reset,
+ 	.hw_type	= HOSTAP_HW_PCI,
+ };
+@@ -352,8 +358,6 @@ static int prism2_pci_probe(struct pci_d
+ 	return hostap_hw_ready(dev);
+ 
+  fail:
+-	kfree(hw_priv);
+-
+ 	if (irq_registered && dev)
+ 		free_irq(dev->irq, dev);
+ 
+@@ -364,10 +368,8 @@ static int prism2_pci_probe(struct pci_d
+ 
+  err_out_disable:
+ 	pci_disable_device(pdev);
+-	kfree(hw_priv);
+-	if (local)
+-		local->hw_priv = NULL;
+ 	prism2_free_local_data(dev);
++	kfree(hw_priv);
+ 
+ 	return -ENODEV;
+ }
+@@ -392,9 +394,8 @@ static void prism2_pci_remove(struct pci
+ 		free_irq(dev->irq, dev);
+ 
+ 	mem_start = hw_priv->mem_start;
+-	kfree(hw_priv);
+-	iface->local->hw_priv = NULL;
+ 	prism2_free_local_data(dev);
++	kfree(hw_priv);
+ 
+ 	iounmap(mem_start);
+ 
+@@ -441,7 +442,7 @@ static int prism2_pci_resume(struct pci_
+ MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
+ 
+ static struct pci_driver prism2_pci_drv_id = {
+-	.name		= "prism2_pci",
++	.name		= "hostap_pci",
+ 	.id_table	= prism2_pci_id_table,
+ 	.probe		= prism2_pci_probe,
+ 	.remove		= prism2_pci_remove,
+diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
+--- a/drivers/net/wireless/hostap/hostap_plx.c
++++ b/drivers/net/wireless/hostap/hostap_plx.c
+@@ -328,8 +328,6 @@ static struct prism2_helper_functions pr
+ {
+ 	.card_present	= NULL,
+ 	.cor_sreset	= prism2_plx_cor_sreset,
+-	.dev_open	= NULL,
+-	.dev_close	= NULL,
+ 	.genesis_reset	= prism2_plx_genesis_reset,
+ 	.hw_type	= HOSTAP_HW_PLX,
+ };
+@@ -570,10 +568,8 @@ static int prism2_plx_probe(struct pci_d
+ 	return hostap_hw_ready(dev);
+ 
+  fail:
+-	kfree(hw_priv);
+-	if (local)
+-		local->hw_priv = NULL;
+ 	prism2_free_local_data(dev);
++	kfree(hw_priv);
+ 
+ 	if (irq_registered && dev)
+ 		free_irq(dev->irq, dev);
+@@ -606,9 +602,8 @@ static void prism2_plx_remove(struct pci
+ 	if (dev->irq)
+ 		free_irq(dev->irq, dev);
+ 
+-	kfree(iface->local->hw_priv);
+-	iface->local->hw_priv = NULL;
+ 	prism2_free_local_data(dev);
++	kfree(hw_priv);
+ 	pci_disable_device(pdev);
+ }
+ 
+@@ -616,7 +611,7 @@ static void prism2_plx_remove(struct pci
+ MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
+ 
+ static struct pci_driver prism2_plx_drv_id = {
+-	.name		= "prism2_plx",
++	.name		= "hostap_plx",
+ 	.id_table	= prism2_plx_id_table,
+ 	.probe		= prism2_plx_probe,
+ 	.remove		= prism2_plx_remove,
+diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
+--- a/drivers/net/wireless/hostap/hostap_wlan.h
++++ b/drivers/net/wireless/hostap/hostap_wlan.h
+@@ -552,8 +552,6 @@ struct prism2_helper_functions {
+ 	 * (hostap_{cs,plx,pci}.c */
+ 	int (*card_present)(local_info_t *local);
+ 	void (*cor_sreset)(local_info_t *local);
+-	int (*dev_open)(local_info_t *local);
+-	int (*dev_close)(local_info_t *local);
+ 	void (*genesis_reset)(local_info_t *local, int hcr);
+ 
+ 	/* the following functions are from hostap_hw.c, but they may have some
+diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
+--- a/drivers/net/wireless/ipw2100.c
++++ b/drivers/net/wireless/ipw2100.c
+@@ -800,8 +800,7 @@ static int ipw2100_hw_send_command(struc
+ 	 * doesn't seem to have as many firmware restart cycles...
+ 	 *
+ 	 * As a test, we're sticking in a 1/100s delay here */
+-	set_current_state(TASK_UNINTERRUPTIBLE);
+-	schedule_timeout(HZ / 100);
++	schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+ 
+ 	return 0;
+ 
+@@ -1256,8 +1255,7 @@ static int ipw2100_start_adapter(struct 
+ 	IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n");
+ 	i = 5000;
+ 	do {
+-  		set_current_state(TASK_UNINTERRUPTIBLE);
+-		schedule_timeout(40 * HZ / 1000);
++		schedule_timeout_uninterruptible(msecs_to_jiffies(40));
+ 		/* Todo... wait for sync command ... */
+ 
+ 		read_register(priv->net_dev, IPW_REG_INTA, &inta);
+@@ -1411,8 +1409,7 @@ static int ipw2100_hw_phy_off(struct ipw
+ 		    (val2 & IPW2100_COMMAND_PHY_OFF))
+ 			return 0;
+ 
+-		set_current_state(TASK_UNINTERRUPTIBLE);
+-		schedule_timeout(HW_PHY_OFF_LOOP_DELAY);
++		schedule_timeout_uninterruptible(HW_PHY_OFF_LOOP_DELAY);
+ 	}
+ 
+ 	return -EIO;
+@@ -1466,7 +1463,7 @@ fail_up:
+ 
+ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
+ {
+-#define HW_POWER_DOWN_DELAY (HZ / 10)
++#define HW_POWER_DOWN_DELAY (msecs_to_jiffies(100))
+ 
+ 	struct host_command cmd = {
+ 		.host_command = HOST_PRE_POWER_DOWN,
+@@ -1520,10 +1517,8 @@ static int ipw2100_hw_stop_adapter(struc
+ 			printk(KERN_WARNING DRV_NAME ": "
+ 			       "%s: Power down command failed: Error %d\n",
+ 			       priv->net_dev->name, err);
+-		else {
+-			set_current_state(TASK_UNINTERRUPTIBLE);
+-			schedule_timeout(HW_POWER_DOWN_DELAY);
+-		}
++		else
++			schedule_timeout_uninterruptible(HW_POWER_DOWN_DELAY);
+ 	}
+ 
+ 	priv->status &= ~STATUS_ENABLED;
+@@ -2953,7 +2948,7 @@ static void ipw2100_tx_send_data(struct 
+ 	int next = txq->next;
+         int i = 0;
+ 	struct ipw2100_data_header *ipw_hdr;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_3addr *hdr;
+ 
+ 	while (!list_empty(&priv->tx_pend_list)) {
+ 		/* if there isn't enough space in TBD queue, then
+@@ -2989,7 +2984,7 @@ static void ipw2100_tx_send_data(struct 
+ 		packet->index = txq->next;
+ 
+ 		ipw_hdr = packet->info.d_struct.data;
+-		hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb->
++		hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
+ 			fragments[0]->data;
+ 
+ 		if (priv->ieee->iw_mode == IW_MODE_INFRA) {
+@@ -3274,7 +3269,8 @@ static irqreturn_t ipw2100_interrupt(int
+ 	return IRQ_NONE;
+ }
+ 
+-static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
++static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
++		      int pri)
+ {
+ 	struct ipw2100_priv *priv = ieee80211_priv(dev);
+ 	struct list_head *element;
+diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
+--- a/drivers/net/wireless/ipw2100.h
++++ b/drivers/net/wireless/ipw2100.h
+@@ -808,7 +808,7 @@ struct ipw2100_priv {
+ struct ipw2100_rx {
+ 	union {
+ 		unsigned char payload[IPW_RX_NIC_BUFFER_LENGTH];
+-		struct ieee80211_hdr header;
++		struct ieee80211_hdr_4addr header;
+ 		u32 status;
+ 		struct ipw2100_notification notification;
+ 		struct ipw2100_cmd_header command;
+diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
+--- a/drivers/net/wireless/ipw2200.c
++++ b/drivers/net/wireless/ipw2200.c
+@@ -4030,6 +4030,10 @@ static struct ipw_rx_queue *ipw_rx_queue
+ 	int i;
+ 
+ 	rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
++	if (unlikely(!rxq)) {
++		IPW_ERROR("memory allocation failed\n");
++		return NULL;
++	}
+ 	memset(rxq, 0, sizeof(*rxq));
+ 	spin_lock_init(&rxq->lock);
+ 	INIT_LIST_HEAD(&rxq->rx_free);
+@@ -4904,7 +4908,7 @@ static void ipw_rx(struct ipw_priv *priv
+ {
+ 	struct ipw_rx_mem_buffer *rxb;
+ 	struct ipw_rx_packet *pkt;
+-	struct ieee80211_hdr *header;
++	struct ieee80211_hdr_4addr *header;
+ 	u32 r, w, i;
+ 	u8 network_packet;
+ 
+@@ -4967,8 +4971,9 @@ static void ipw_rx(struct ipw_priv *priv
+ #endif
+ 
+ 				header =
+-				    (struct ieee80211_hdr *)(rxb->skb->data +
+-							     IPW_RX_FRAME_SIZE);
++				    (struct ieee80211_hdr_4addr *)(rxb->skb->
++								   data +
++								   IPW_RX_FRAME_SIZE);
+ 				/* TODO: Check Ad-Hoc dest/source and make sure
+ 				 * that we are actually parsing these packets
+ 				 * correctly -- we should probably use the
+@@ -5317,8 +5322,6 @@ static int ipw_wx_set_freq(struct net_de
+ 
+ 	IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
+ 	return ipw_set_channel(priv, (u8) fwrq->m);
+-
+-	return 0;
+ }
+ 
+ static int ipw_wx_get_freq(struct net_device *dev,
+@@ -6010,12 +6013,12 @@ static int ipw_wx_set_wireless_mode(stru
+ 	}
+ 
+ 	if (priv->adapter == IPW_2915ABG) {
+-		priv->ieee->abg_ture = 1;
++		priv->ieee->abg_true = 1;
+ 		if (mode & IEEE_A) {
+ 			band |= IEEE80211_52GHZ_BAND;
+ 			modulation |= IEEE80211_OFDM_MODULATION;
+ 		} else
+-			priv->ieee->abg_ture = 0;
++			priv->ieee->abg_true = 0;
+ 	} else {
+ 		if (mode & IEEE_A) {
+ 			IPW_WARNING("Attempt to set 2200BG into "
+@@ -6023,20 +6026,20 @@ static int ipw_wx_set_wireless_mode(stru
+ 			return -EINVAL;
+ 		}
+ 
+-		priv->ieee->abg_ture = 0;
++		priv->ieee->abg_true = 0;
+ 	}
+ 
+ 	if (mode & IEEE_B) {
+ 		band |= IEEE80211_24GHZ_BAND;
+ 		modulation |= IEEE80211_CCK_MODULATION;
+ 	} else
+-		priv->ieee->abg_ture = 0;
++		priv->ieee->abg_true = 0;
+ 
+ 	if (mode & IEEE_G) {
+ 		band |= IEEE80211_24GHZ_BAND;
+ 		modulation |= IEEE80211_OFDM_MODULATION;
+ 	} else
+-		priv->ieee->abg_ture = 0;
++		priv->ieee->abg_true = 0;
+ 
+ 	priv->ieee->mode = mode;
+ 	priv->ieee->freq_band = band;
+@@ -6325,7 +6328,7 @@ we need to heavily modify the ieee80211_
+ 
+ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
+ {
+-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)
++	struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
+ 	    txb->fragments[0]->data;
+ 	int i = 0;
+ 	struct tfd_frame *tfd;
+@@ -6448,7 +6451,7 @@ static inline void ipw_tx_skb(struct ipw
+ }
+ 
+ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
+-				   struct net_device *dev)
++				   struct net_device *dev, int pri)
+ {
+ 	struct ipw_priv *priv = ieee80211_priv(dev);
+ 	unsigned long flags;
+@@ -7108,7 +7111,7 @@ static int ipw_pci_probe(struct pci_dev 
+ 		printk(KERN_INFO DRV_NAME
+ 		       ": Detected Intel PRO/Wireless 2915ABG Network "
+ 		       "Connection\n");
+-		priv->ieee->abg_ture = 1;
++		priv->ieee->abg_true = 1;
+ 		band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
+ 		modulation = IEEE80211_OFDM_MODULATION |
+ 		    IEEE80211_CCK_MODULATION;
+@@ -7124,7 +7127,7 @@ static int ipw_pci_probe(struct pci_dev 
+ 			       ": Detected Intel PRO/Wireless 2200BG Network "
+ 			       "Connection\n");
+ 
+-		priv->ieee->abg_ture = 0;
++		priv->ieee->abg_true = 0;
+ 		band = IEEE80211_24GHZ_BAND;
+ 		modulation = IEEE80211_OFDM_MODULATION |
+ 		    IEEE80211_CCK_MODULATION;
+diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
+--- a/drivers/net/wireless/ipw2200.h
++++ b/drivers/net/wireless/ipw2200.h
+@@ -1654,12 +1654,12 @@ static const long ipw_frequencies[] = {
+ 
+ #define IPW_MAX_CONFIG_RETRIES 10
+ 
+-static inline u32 frame_hdr_len(struct ieee80211_hdr *hdr)
++static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
+ {
+ 	u32 retval;
+ 	u16 fc;
+ 
+-	retval = sizeof(struct ieee80211_hdr);
++	retval = sizeof(struct ieee80211_hdr_3addr);
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 
+ 	/*
+diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
+--- a/drivers/net/wireless/netwave_cs.c
++++ b/drivers/net/wireless/netwave_cs.c
+@@ -57,9 +57,7 @@
+ #include <linux/bitops.h>
+ #ifdef CONFIG_NET_RADIO
+ #include <linux/wireless.h>
+-#if WIRELESS_EXT > 12
+ #include <net/iw_handler.h>
+-#endif	/* WIRELESS_EXT > 12 */
+ #endif
+ 
+ #include <pcmcia/cs_types.h>
+@@ -225,10 +223,7 @@ static void update_stats(struct net_devi
+ static struct net_device_stats *netwave_get_stats(struct net_device *dev);
+ 
+ /* Wireless extensions */
+-#ifdef WIRELESS_EXT
+ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
+-#endif
+-static int netwave_ioctl(struct net_device *, struct ifreq *, int);
+ 
+ static void set_multicast_list(struct net_device *dev);
+ 
+@@ -260,26 +255,7 @@ static dev_link_t *dev_list;
+    because they generally can't be allocated dynamically.
+ */
+ 
+-#if WIRELESS_EXT <= 12
+-/* Wireless extensions backward compatibility */
+-
+-/* Part of iw_handler prototype we need */
+-struct iw_request_info
+-{
+-	__u16		cmd;		/* Wireless Extension command */
+-	__u16		flags;		/* More to come ;-) */
+-};
+-
+-/* Wireless Extension Backward compatibility - Jean II
+- * If the new wireless device private ioctl range is not defined,
+- * default to standard device private ioctl range */
+-#ifndef SIOCIWFIRSTPRIV
+-#define SIOCIWFIRSTPRIV	SIOCDEVPRIVATE
+-#endif /* SIOCIWFIRSTPRIV */
+-
+-#else	/* WIRELESS_EXT <= 12 */
+ static const struct iw_handler_def	netwave_handler_def;
+-#endif	/* WIRELESS_EXT <= 12 */
+ 
+ #define SIOCGIPSNAP	SIOCIWFIRSTPRIV	+ 1	/* Site Survey Snapshot */
+ 
+@@ -319,9 +295,7 @@ typedef struct netwave_private {
+     struct timer_list      watchdog;	/* To avoid blocking state */
+     struct site_survey     nss;
+     struct net_device_stats stats;
+-#ifdef WIRELESS_EXT
+     struct iw_statistics   iw_stats;    /* Wireless stats */
+-#endif
+ } netwave_private;
+ 
+ #ifdef NETWAVE_STATS
+@@ -353,7 +327,6 @@ static inline void wait_WOC(unsigned int
+     while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ; 
+ }
+ 
+-#ifdef WIRELESS_EXT
+ static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase, 
+ 			     kio_addr_t iobase) {
+     u_short resultBuffer;
+@@ -376,9 +349,7 @@ static void netwave_snapshot(netwave_pri
+ 		      sizeof(struct site_survey)); 
+     } 
+ }
+-#endif
+ 
+-#ifdef WIRELESS_EXT
+ /*
+  * Function netwave_get_wireless_stats (dev)
+  *
+@@ -411,7 +382,6 @@ static struct iw_statistics *netwave_get
+     
+     return &priv->iw_stats;
+ }
+-#endif
+ 
+ /*
+  * Function netwave_attach (void)
+@@ -471,13 +441,7 @@ static dev_link_t *netwave_attach(void)
+     dev->get_stats  = &netwave_get_stats;
+     dev->set_multicast_list = &set_multicast_list;
+     /* wireless extensions */
+-#if WIRELESS_EXT <= 16
+-    dev->get_wireless_stats = &netwave_get_wireless_stats;
+-#endif /* WIRELESS_EXT <= 16 */
+-#if WIRELESS_EXT > 12
+     dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
+-#endif /* WIRELESS_EXT > 12 */
+-    dev->do_ioctl = &netwave_ioctl;
+ 
+     dev->tx_timeout = &netwave_watchdog;
+     dev->watchdog_timeo = TX_TIMEOUT;
+@@ -576,13 +540,8 @@ static int netwave_set_nwid(struct net_d
+ 	/* Disable interrupts & save flags */
+ 	spin_lock_irqsave(&priv->spinlock, flags);
+ 
+-#if WIRELESS_EXT > 8
+ 	if(!wrqu->nwid.disabled) {
+ 	    domain = wrqu->nwid.value;
+-#else	/* WIRELESS_EXT > 8 */
+-	if(wrqu->nwid.on) {
+-	    domain = wrqu->nwid.nwid;
+-#endif	/* WIRELESS_EXT > 8 */
+ 	    printk( KERN_DEBUG "Setting domain to 0x%x%02x\n", 
+ 		    (domain >> 8) & 0x01, domain & 0xff);
+ 	    wait_WOC(iobase);
+@@ -606,15 +565,9 @@ static int netwave_get_nwid(struct net_d
+ 			    union iwreq_data *wrqu,
+ 			    char *extra)
+ {
+-#if WIRELESS_EXT > 8
+ 	wrqu->nwid.value = domain;
+ 	wrqu->nwid.disabled = 0;
+ 	wrqu->nwid.fixed = 1;
+-#else	/* WIRELESS_EXT > 8 */
+-	wrqu->nwid.nwid = domain;
+-	wrqu->nwid.on = 1;
+-#endif	/* WIRELESS_EXT > 8 */
+-
+ 	return 0;
+ }
+ 
+@@ -657,17 +610,11 @@ static int netwave_get_scramble(struct n
+ {
+ 	key[1] = scramble_key & 0xff;
+ 	key[0] = (scramble_key>>8) & 0xff;
+-#if WIRELESS_EXT > 8
+ 	wrqu->encoding.flags = IW_ENCODE_ENABLED;
+ 	wrqu->encoding.length = 2;
+-#else /* WIRELESS_EXT > 8 */
+-	wrqu->encoding.method = 1;
+-#endif	/* WIRELESS_EXT > 8 */
+-
+ 	return 0;
+ }
+ 
+-#if WIRELESS_EXT > 8
+ /*
+  * Wireless Handler : get mode
+  */
+@@ -683,7 +630,6 @@ static int netwave_get_mode(struct net_d
+ 
+ 	return 0;
+ }
+-#endif	/* WIRELESS_EXT > 8 */
+ 
+ /*
+  * Wireless Handler : get range info
+@@ -702,11 +648,9 @@ static int netwave_get_range(struct net_
+ 	/* Set all the info we don't care or don't know about to zero */
+ 	memset(range, 0, sizeof(struct iw_range));
+ 
+-#if WIRELESS_EXT > 10
+ 	/* Set the Wireless Extension versions */
+ 	range->we_version_compiled = WIRELESS_EXT;
+ 	range->we_version_source = 9;	/* Nothing for us in v10 and v11 */
+-#endif /* WIRELESS_EXT > 10 */
+ 		   
+ 	/* Set information in the range struct */
+ 	range->throughput = 450 * 1000;	/* don't argue on this ! */
+@@ -720,16 +664,12 @@ static int netwave_get_range(struct net_
+ 	range->max_qual.level = 255;
+ 	range->max_qual.noise = 0;
+ 		   
+-#if WIRELESS_EXT > 7
+ 	range->num_bitrates = 1;
+ 	range->bitrate[0] = 1000000;	/* 1 Mb/s */
+-#endif /* WIRELESS_EXT > 7 */
+ 
+-#if WIRELESS_EXT > 8
+ 	range->encoding_size[0] = 2;		/* 16 bits scrambling */
+ 	range->num_encoding_sizes = 1;
+ 	range->max_encoding_tokens = 1;	/* Only one key possible */
+-#endif /* WIRELESS_EXT > 8 */
+ 
+ 	return ret;
+ }
+@@ -775,8 +715,6 @@ static const struct iw_priv_args netwave
+     "getsitesurvey" },
+ };
+ 
+-#if WIRELESS_EXT > 12
+-
+ static const iw_handler		netwave_handler[] =
+ {
+ 	NULL,				/* SIOCSIWNAME */
+@@ -839,131 +777,8 @@ static const struct iw_handler_def	netwa
+ 	.standard	= (iw_handler *) netwave_handler,
+ 	.private	= (iw_handler *) netwave_private_handler,
+ 	.private_args	= (struct iw_priv_args *) netwave_private_args,
+-#if WIRELESS_EXT > 16
+ 	.get_wireless_stats = netwave_get_wireless_stats,
+-#endif /* WIRELESS_EXT > 16 */
+ };
+-#endif /* WIRELESS_EXT > 12 */
+-
+-/*
+- * Function netwave_ioctl (dev, rq, cmd)
+- *
+- *     Perform ioctl : config & info stuff
+- *     This is the stuff that are treated the wireless extensions (iwconfig)
+- *
+- */
+-static int netwave_ioctl(struct net_device *dev, /* ioctl device */
+-			 struct ifreq *rq,	 /* Data passed */
+-			 int	cmd)	     /* Ioctl number */
+-{
+-    int			ret = 0;
+-#ifdef WIRELESS_EXT
+-#if WIRELESS_EXT <= 12
+-    struct iwreq *wrq = (struct iwreq *) rq;
+-#endif
+-#endif
+-	
+-    DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
+-	
+-    /* Look what is the request */
+-    switch(cmd) {
+-	/* --------------- WIRELESS EXTENSIONS --------------- */
+-#ifdef WIRELESS_EXT
+-#if WIRELESS_EXT <= 12
+-    case SIOCGIWNAME:
+-	netwave_get_name(dev, NULL, &(wrq->u), NULL);
+-	break;
+-    case SIOCSIWNWID:
+-	ret = netwave_set_nwid(dev, NULL, &(wrq->u), NULL);
+-	break;
+-    case SIOCGIWNWID:
+-	ret = netwave_get_nwid(dev, NULL, &(wrq->u), NULL);
+-	break;
+-#if WIRELESS_EXT > 8	/* Note : The API did change... */
+-    case SIOCGIWENCODE:
+-	/* Get scramble key */
+-	if(wrq->u.encoding.pointer != (caddr_t) 0)
+-	  {
+-	    char	key[2];
+-	    ret = netwave_get_scramble(dev, NULL, &(wrq->u), key);
+-	    if(copy_to_user(wrq->u.encoding.pointer, key, 2))
+-	      ret = -EFAULT;
+-	  }
+-	break;
+-    case SIOCSIWENCODE:
+-	/* Set  scramble key */
+-	if(wrq->u.encoding.pointer != (caddr_t) 0)
+-	  {
+-	    char	key[2];
+-	    if(copy_from_user(key, wrq->u.encoding.pointer, 2))
+-	      {
+-		ret = -EFAULT;
+-		break;
+-	      }
+-	    ret = netwave_set_scramble(dev, NULL, &(wrq->u), key);
+-	  }
+-	break;
+-    case SIOCGIWMODE:
+-	/* Mode of operation */
+-	ret = netwave_get_mode(dev, NULL, &(wrq->u), NULL);
+-	break;
+-#else /* WIRELESS_EXT > 8 */
+-    case SIOCGIWENCODE:
+-	/* Get scramble key */
+-	ret = netwave_get_scramble(dev, NULL, &(wrq->u),
+-				   (char *) &wrq->u.encoding.code);
+-	break;
+-    case SIOCSIWENCODE:
+-	/* Set  scramble key */
+-	ret = netwave_set_scramble(dev, NULL, &(wrq->u),
+-				   (char *) &wrq->u.encoding.code);
+-	break;
+-#endif /* WIRELESS_EXT > 8 */
+-   case SIOCGIWRANGE:
+-       /* Basic checking... */
+-       if(wrq->u.data.pointer != (caddr_t) 0) {
+-           struct iw_range range;
+-	   ret = netwave_get_range(dev, NULL, &(wrq->u), (char *) &range);
+-	   if (copy_to_user(wrq->u.data.pointer, &range,
+-			    sizeof(struct iw_range)))
+-	       ret = -EFAULT;
+-       }
+-       break;
+-    case SIOCGIWPRIV:
+-	/* Basic checking... */
+-	if(wrq->u.data.pointer != (caddr_t) 0) {
+-	    /* Set the number of ioctl available */
+-	    wrq->u.data.length = sizeof(netwave_private_args) / sizeof(netwave_private_args[0]);
+-			
+-	    /* Copy structure to the user buffer */
+-	    if(copy_to_user(wrq->u.data.pointer,
+-			    (u_char *) netwave_private_args,
+-			    sizeof(netwave_private_args)))
+-	      ret = -EFAULT;
+-	} 
+-	break;
+-    case SIOCGIPSNAP:
+-	if(wrq->u.data.pointer != (caddr_t) 0) {
+-	    char buffer[sizeof( struct site_survey)];
+-	    ret = netwave_get_snap(dev, NULL, &(wrq->u), buffer);
+-	    /* Copy structure to the user buffer */
+-	    if(copy_to_user(wrq->u.data.pointer, 
+-			    buffer,
+-			    sizeof( struct site_survey)))
+-	      {
+-		printk(KERN_DEBUG "Bad buffer!\n");
+-		break;
+-	      }
+-	}
+-	break;
+-#endif /* WIRELESS_EXT <= 12 */
+-#endif /* WIRELESS_EXT */
+-    default:
+-	ret = -EOPNOTSUPP;
+-    }
+-	
+-    return ret;
+-}
+ 
+ /*
+  * Function netwave_pcmcia_config (link)
+diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
+--- a/drivers/net/wireless/orinoco.c
++++ b/drivers/net/wireless/orinoco.c
+@@ -77,30 +77,16 @@
+ #define DRIVER_NAME "orinoco"
+ 
+ #include <linux/config.h>
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/timer.h>
+-#include <linux/ioport.h>
+ #include <linux/netdevice.h>
+-#include <linux/if_arp.h>
+ #include <linux/etherdevice.h>
+ #include <linux/ethtool.h>
+ #include <linux/wireless.h>
+ #include <net/iw_handler.h>
+ #include <net/ieee80211.h>
+ 
+-#include <net/ieee80211.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/io.h>
+-#include <asm/system.h>
+-
+-#include "hermes.h"
+ #include "hermes_rid.h"
+ #include "orinoco.h"
+ 
+@@ -137,7 +123,7 @@ MODULE_PARM_DESC(force_monitor, "Allow m
+ 
+ /* We do this this way to avoid ifdefs in the actual code */
+ #ifdef WIRELESS_SPY
+-#define SPY_NUMBER(priv)	(priv->spy_number)
++#define SPY_NUMBER(priv)	(priv->spy_data.spy_number)
+ #else
+ #define SPY_NUMBER(priv)	0
+ #endif /* WIRELESS_SPY */
+@@ -216,31 +202,32 @@ static struct {
+ /********************************************************************/
+ 
+ /* Used in Event handling.
+- * We avoid nested structres as they break on ARM -- Moustafa */
++ * We avoid nested structures as they break on ARM -- Moustafa */
+ struct hermes_tx_descriptor_802_11 {
+ 	/* hermes_tx_descriptor */
+-	u16 status;
+-	u16 reserved1;
+-	u16 reserved2;
+-	u32 sw_support;
++	__le16 status;
++	__le16 reserved1;
++	__le16 reserved2;
++	__le32 sw_support;
+ 	u8 retry_count;
+ 	u8 tx_rate;
+-	u16 tx_control;
++	__le16 tx_control;
+ 
+-	/* ieee802_11_hdr */
+-	u16 frame_ctl;
+-	u16 duration_id;
++	/* ieee80211_hdr */
++	__le16 frame_ctl;
++	__le16 duration_id;
+ 	u8 addr1[ETH_ALEN];
+ 	u8 addr2[ETH_ALEN];
+ 	u8 addr3[ETH_ALEN];
+-	u16 seq_ctl;
++	__le16 seq_ctl;
+ 	u8 addr4[ETH_ALEN];
+-	u16 data_len;
++
++	__le16 data_len;
+ 
+ 	/* ethhdr */
+-	unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
+-	unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
+-	unsigned short  h_proto;                /* packet type ID field */
++	u8 h_dest[ETH_ALEN];	/* destination eth addr */
++	u8 h_source[ETH_ALEN];	/* source ether addr    */
++	__be16 h_proto;		/* packet type ID field */
+ 
+ 	/* p8022_hdr */
+ 	u8 dsap;
+@@ -248,31 +235,31 @@ struct hermes_tx_descriptor_802_11 {
+ 	u8 ctrl;
+ 	u8 oui[3];
+ 
+-	u16 ethertype;
++	__be16 ethertype;
+ } __attribute__ ((packed));
+ 
+ /* Rx frame header except compatibility 802.3 header */
+ struct hermes_rx_descriptor {
+ 	/* Control */
+-	u16 status;
+-	u32 time;
++	__le16 status;
++	__le32 time;
+ 	u8 silence;
+ 	u8 signal;
+ 	u8 rate;
+ 	u8 rxflow;
+-	u32 reserved;
++	__le32 reserved;
+ 
+ 	/* 802.11 header */
+-	u16 frame_ctl;
+-	u16 duration_id;
++	__le16 frame_ctl;
++	__le16 duration_id;
+ 	u8 addr1[ETH_ALEN];
+ 	u8 addr2[ETH_ALEN];
+ 	u8 addr3[ETH_ALEN];
+-	u16 seq_ctl;
++	__le16 seq_ctl;
+ 	u8 addr4[ETH_ALEN];
+ 
+ 	/* Data length */
+-	u16 data_len;
++	__le16 data_len;
+ } __attribute__ ((packed));
+ 
+ /********************************************************************/
+@@ -396,14 +383,14 @@ static struct iw_statistics *orinoco_get
+ 		/* If a spy address is defined, we report stats of the
+ 		 * first spy address - Jean II */
+ 		if (SPY_NUMBER(priv)) {
+-			wstats->qual.qual = priv->spy_stat[0].qual;
+-			wstats->qual.level = priv->spy_stat[0].level;
+-			wstats->qual.noise = priv->spy_stat[0].noise;
+-			wstats->qual.updated = priv->spy_stat[0].updated;
++			wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
++			wstats->qual.level = priv->spy_data.spy_stat[0].level;
++			wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
++			wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
+ 		}
+ 	} else {
+ 		struct {
+-			u16 qual, signal, noise;
++			__le16 qual, signal, noise;
+ 		} __attribute__ ((packed)) cq;
+ 
+ 		err = HERMES_READ_RECORD(hw, USER_BAP,
+@@ -503,13 +490,12 @@ static int orinoco_xmit(struct sk_buff *
+ 		return 0;
+ 	}
+ 
+-	/* Check packet length, pad short packets, round up odd length */
++	/* Length of the packet body */
++	/* FIXME: what if the skb is smaller than this? */
+ 	len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
+-	if (skb->len < len) {
+-		skb = skb_padto(skb, len);
+-		if (skb == NULL)
+-			goto fail;
+-	}
++	skb = skb_padto(skb, len);
++	if (skb == NULL)
++		goto fail;
+ 	len -= ETH_HLEN;
+ 
+ 	eh = (struct ethhdr *)skb->data;
+@@ -556,13 +542,21 @@ static int orinoco_xmit(struct sk_buff *
+ 			stats->tx_errors++;
+ 			goto fail;
+ 		}
++		/* Actual xfer length - allow for padding */
++		len = ALIGN(data_len, 2);
++		if (len < ETH_ZLEN - ETH_HLEN)
++			len = ETH_ZLEN - ETH_HLEN;
+ 	} else { /* IEEE 802.3 frame */
+ 		data_len = len + ETH_HLEN;
+ 		data_off = HERMES_802_3_OFFSET;
+ 		p = skb->data;
++		/* Actual xfer length - round up for odd length packets */
++		len = ALIGN(data_len, 2);
++		if (len < ETH_ZLEN)
++			len = ETH_ZLEN;
+ 	}
+ 
+-	err = hermes_bap_pwrite(hw, USER_BAP, p, data_len,
++	err = hermes_bap_pwrite_pad(hw, USER_BAP, p, data_len, len,
+ 				txfid, data_off);
+ 	if (err) {
+ 		printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
+@@ -634,16 +628,17 @@ static void __orinoco_ev_txexc(struct ne
+ 	struct orinoco_private *priv = netdev_priv(dev);
+ 	struct net_device_stats *stats = &priv->stats;
+ 	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
++	u16 status;
+ 	struct hermes_tx_descriptor_802_11 hdr;
+ 	int err = 0;
+ 
+ 	if (fid == DUMMY_FID)
+ 		return; /* Nothing's really happened */
+ 
+-	/* Read the frame header */
++	/* Read part of the frame header - we need status and addr1 */
+ 	err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
+-			       sizeof(struct hermes_tx_descriptor) +
+-			       sizeof(struct ieee80211_hdr),
++			       offsetof(struct hermes_tx_descriptor_802_11,
++					addr2),
+ 			       fid, 0);
+ 
+ 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+@@ -663,8 +658,8 @@ static void __orinoco_ev_txexc(struct ne
+ 	 * exceeded, because that's the only status that really mean
+ 	 * that this particular node went away.
+ 	 * Other errors means that *we* screwed up. - Jean II */
+-	hdr.status = le16_to_cpu(hdr.status);
+-	if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
++	status = le16_to_cpu(hdr.status);
++	if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+ 		union iwreq_data	wrqu;
+ 
+ 		/* Copy 802.11 dest address.
+@@ -723,18 +718,13 @@ static inline int is_ethersnap(void *_hd
+ static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
+ 				      int level, int noise)
+ {
+-	struct orinoco_private *priv = netdev_priv(dev);
+-	int i;
+-
+-	/* Gather wireless spy statistics: for each packet, compare the
+-	 * source address with out list, and if match, get the stats... */
+-	for (i = 0; i < priv->spy_number; i++)
+-		if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
+-			priv->spy_stat[i].level = level - 0x95;
+-			priv->spy_stat[i].noise = noise - 0x95;
+-			priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
+-			priv->spy_stat[i].updated = 7;
+-		}
++	struct iw_quality wstats;
++	wstats.level = level - 0x95;
++	wstats.noise = noise - 0x95;
++	wstats.qual = (level > noise) ? (level - noise) : 0;
++	wstats.updated = 7;
++	/* Update spy records */
++	wireless_spy_update(dev, mac, &wstats);
+ }
+ 
+ static void orinoco_stat_gather(struct net_device *dev,
+@@ -1055,7 +1045,7 @@ static void orinoco_join_ap(struct net_d
+ 	unsigned long flags;
+ 	struct join_req {
+ 		u8 bssid[ETH_ALEN];
+-		u16 channel;
++		__le16 channel;
+ 	} __attribute__ ((packed)) req;
+ 	const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
+ 	struct prism2_scan_apinfo *atom = NULL;
+@@ -1070,7 +1060,7 @@ static void orinoco_join_ap(struct net_d
+ 		return;
+ 
+ 	if (orinoco_lock(priv, &flags) != 0)
+-		goto out;
++		goto fail_lock;
+ 
+ 	/* Sanity checks in case user changed something in the meantime */
+ 	if (! priv->bssid_fixed)
+@@ -1115,8 +1105,10 @@ static void orinoco_join_ap(struct net_d
+ 		printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
+ 
+  out:
+-	kfree(buf);
+ 	orinoco_unlock(priv, &flags);
++
++ fail_lock:
++	kfree(buf);
+ }
+ 
+ /* Send new BSSID to userspace */
+@@ -1134,12 +1126,14 @@ static void orinoco_send_wevents(struct 
+ 	err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
+ 			      ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
+ 	if (err != 0)
+-		return;
++		goto out;
+ 
+ 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ 
+ 	/* Send event to user space */
+ 	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
++
++ out:
+ 	orinoco_unlock(priv, &flags);
+ }
+ 
+@@ -1148,8 +1142,8 @@ static void __orinoco_ev_info(struct net
+ 	struct orinoco_private *priv = netdev_priv(dev);
+ 	u16 infofid;
+ 	struct {
+-		u16 len;
+-		u16 type;
++		__le16 len;
++		__le16 type;
+ 	} __attribute__ ((packed)) info;
+ 	int len, type;
+ 	int err;
+@@ -2464,6 +2458,10 @@ struct net_device *alloc_orinocodev(int 
+ 	dev->get_stats = orinoco_get_stats;
+ 	dev->ethtool_ops = &orinoco_ethtool_ops;
+ 	dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
++#ifdef WIRELESS_SPY
++	priv->wireless_data.spy_data = &priv->spy_data;
++	dev->wireless_data = &priv->wireless_data;
++#endif
+ 	dev->change_mtu = orinoco_change_mtu;
+ 	dev->set_multicast_list = orinoco_set_multicast_list;
+ 	/* we use the default eth_mac_addr for setting the MAC addr */
+@@ -2835,7 +2833,7 @@ static int orinoco_ioctl_getiwrange(stru
+ 		}
+ 	}
+ 
+-	if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
++	if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
+ 		/* Quality stats meaningless in ad-hoc mode */
+ 	} else {
+ 		range->max_qual.qual = 0x8b - 0x2f;
+@@ -2882,6 +2880,14 @@ static int orinoco_ioctl_getiwrange(stru
+ 	range->min_r_time = 0;
+ 	range->max_r_time = 65535 * 1000;	/* ??? */
+ 
++	/* Event capability (kernel) */
++	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
++	/* Event capability (driver) */
++	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
++	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
++	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
++	IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
++
+ 	TRACE_EXIT(dev->name);
+ 
+ 	return 0;
+@@ -3841,92 +3847,6 @@ static int orinoco_ioctl_getrid(struct n
+ 	return err;
+ }
+ 
+-/* Spy is used for link quality/strength measurements in Ad-Hoc mode
+- * Jean II */
+-static int orinoco_ioctl_setspy(struct net_device *dev,
+-				struct iw_request_info *info,
+-				struct iw_point *srq,
+-				char *extra)
+-
+-{
+-	struct orinoco_private *priv = netdev_priv(dev);
+-	struct sockaddr *address = (struct sockaddr *) extra;
+-	int number = srq->length;
+-	int i;
+-	unsigned long flags;
+-
+-	/* Make sure nobody mess with the structure while we do */
+-	if (orinoco_lock(priv, &flags) != 0)
+-		return -EBUSY;
+-
+-	/* orinoco_lock() doesn't disable interrupts, so make sure the
+-	 * interrupt rx path don't get confused while we copy */
+-	priv->spy_number = 0;
+-
+-	if (number > 0) {
+-		/* Extract the addresses */
+-		for (i = 0; i < number; i++)
+-			memcpy(priv->spy_address[i], address[i].sa_data,
+-			       ETH_ALEN);
+-		/* Reset stats */
+-		memset(priv->spy_stat, 0,
+-		       sizeof(struct iw_quality) * IW_MAX_SPY);
+-		/* Set number of addresses */
+-		priv->spy_number = number;
+-	}
+-
+-	/* Now, let the others play */
+-	orinoco_unlock(priv, &flags);
+-
+-	/* Do NOT call commit handler */
+-	return 0;
+-}
+-
+-static int orinoco_ioctl_getspy(struct net_device *dev,
+-				struct iw_request_info *info,
+-				struct iw_point *srq,
+-				char *extra)
+-{
+-	struct orinoco_private *priv = netdev_priv(dev);
+-	struct sockaddr *address = (struct sockaddr *) extra;
+-	int number;
+-	int i;
+-	unsigned long flags;
+-
+-	if (orinoco_lock(priv, &flags) != 0)
+-		return -EBUSY;
+-
+-	number = priv->spy_number;
+-	/* Create address struct */
+-	for (i = 0; i < number; i++) {
+-		memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
+-		address[i].sa_family = AF_UNIX;
+-	}
+-	if (number > 0) {
+-		/* Create address struct */
+-		for (i = 0; i < number; i++) {
+-			memcpy(address[i].sa_data, priv->spy_address[i],
+-			       ETH_ALEN);
+-			address[i].sa_family = AF_UNIX;
+-		}
+-		/* Copy stats */
+-		/* In theory, we should disable irqs while copying the stats
+-		 * because the rx path might update it in the middle...
+-		 * Bah, who care ? - Jean II */
+-		memcpy(extra  + (sizeof(struct sockaddr) * number),
+-		       priv->spy_stat, sizeof(struct iw_quality) * number);
+-	}
+-	/* Reset updated flags. */
+-	for (i = 0; i < number; i++)
+-		priv->spy_stat[i].updated = 0;
+-
+-	orinoco_unlock(priv, &flags);
+-
+-	srq->length = number;
+-
+-	return 0;
+-}
+-
+ /* Trigger a scan (look for other cells in the vicinity */
+ static int orinoco_ioctl_setscan(struct net_device *dev,
+ 				 struct iw_request_info *info,
+@@ -3999,7 +3919,7 @@ static int orinoco_ioctl_setscan(struct 
+ 						   HERMES_HOSTSCAN_SYMBOL_BCAST);
+ 			break;
+ 		case FIRMWARE_TYPE_INTERSIL: {
+-			u16 req[3];
++			__le16 req[3];
+ 
+ 			req[0] = cpu_to_le16(0x3fff);	/* All channels */
+ 			req[1] = cpu_to_le16(0x0001);	/* rate 1 Mbps */
+@@ -4073,7 +3993,7 @@ static inline int orinoco_translate_scan
+ 	case FIRMWARE_TYPE_INTERSIL:
+ 		offset = 4;
+ 		if (priv->has_hostscan) {
+-			atom_len = le16_to_cpup((u16 *)scan);
++			atom_len = le16_to_cpup((__le16 *)scan);
+ 			/* Sanity check for atom_len */
+ 			if (atom_len < sizeof(struct prism2_scan_apinfo)) {
+ 				printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
+@@ -4357,8 +4277,10 @@ static const iw_handler	orinoco_handler[
+ 	[SIOCSIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
+ 	[SIOCGIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
+ 	[SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
+-	[SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy,
+-	[SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy,
++	[SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
++	[SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
++	[SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
++	[SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
+ 	[SIOCSIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
+ 	[SIOCGIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
+ 	[SIOCSIWSCAN  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,
+diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
+--- a/drivers/net/wireless/orinoco.h
++++ b/drivers/net/wireless/orinoco.h
+@@ -7,12 +7,11 @@
+ #ifndef _ORINOCO_H
+ #define _ORINOCO_H
+ 
+-#define DRIVER_VERSION "0.15rc2"
++#define DRIVER_VERSION "0.15rc3"
+ 
+-#include <linux/types.h>
+-#include <linux/spinlock.h>
+ #include <linux/netdevice.h>
+ #include <linux/wireless.h>
++#include <net/iw_handler.h>
+ #include <linux/version.h>
+ 
+ #include "hermes.h"
+@@ -28,7 +27,7 @@
+ #define ORINOCO_MAX_KEYS	4
+ 
+ struct orinoco_key {
+-	u16 len;	/* always stored as little-endian */
++	__le16 len;	/* always stored as little-endian */
+ 	char data[ORINOCO_MAX_KEY_SIZE];
+ } __attribute__ ((packed));
+ 
+@@ -36,14 +35,14 @@ struct header_struct {
+ 	/* 802.3 */
+ 	u8 dest[ETH_ALEN];
+ 	u8 src[ETH_ALEN];
+-	u16 len;
++	__be16 len;
+ 	/* 802.2 */
+ 	u8 dsap;
+ 	u8 ssap;
+ 	u8 ctrl;
+ 	/* SNAP */
+ 	u8 oui[3];
+-	u16 ethertype;
++	unsigned short ethertype;
+ } __attribute__ ((packed));
+ 
+ typedef enum {
+@@ -112,9 +111,8 @@ struct orinoco_private {
+ 	u16 pm_on, pm_mcast, pm_period, pm_timeout;
+ 	u16 preamble;
+ #ifdef WIRELESS_SPY
+-	int			spy_number;
+-	u_char			spy_address[IW_MAX_SPY][ETH_ALEN];
+-	struct iw_quality	spy_stat[IW_MAX_SPY];
++ 	struct iw_spy_data spy_data; /* iwspy support */
++	struct iw_public_data	wireless_data;
+ #endif
+ 
+ 	/* Configuration dependent variables */
+diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
+--- a/drivers/net/wireless/orinoco_cs.c
++++ b/drivers/net/wireless/orinoco_cs.c
+@@ -14,33 +14,16 @@
+ #define PFX DRIVER_NAME ": "
+ 
+ #include <linux/config.h>
+-#ifdef  __IN_PCMCIA_PACKAGE__
+-#include <pcmcia/k_compat.h>
+-#endif /* __IN_PCMCIA_PACKAGE__ */
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/sched.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/ioport.h>
+-#include <linux/netdevice.h>
+-#include <linux/if_arp.h>
+-#include <linux/etherdevice.h>
+-#include <linux/wireless.h>
+-
++#include <linux/delay.h>
+ #include <pcmcia/cs_types.h>
+ #include <pcmcia/cs.h>
+ #include <pcmcia/cistpl.h>
+ #include <pcmcia/cisreg.h>
+ #include <pcmcia/ds.h>
+ 
+-#include <asm/uaccess.h>
+-#include <asm/io.h>
+-#include <asm/system.h>
+-
+ #include "orinoco.h"
+ 
+ /********************************************************************/
+@@ -97,17 +80,8 @@ static dev_link_t *dev_list; /* = NULL *
+ /* Function prototypes						    */
+ /********************************************************************/
+ 
+-/* device methods */
+-static int orinoco_cs_hard_reset(struct orinoco_private *priv);
+-
+-/* PCMCIA gumpf */
+-static void orinoco_cs_config(dev_link_t * link);
+-static void orinoco_cs_release(dev_link_t * link);
+-static int orinoco_cs_event(event_t event, int priority,
+-			    event_callback_args_t * args);
+-
+-static dev_link_t *orinoco_cs_attach(void);
+-static void orinoco_cs_detach(dev_link_t *);
++static void orinoco_cs_release(dev_link_t *link);
++static void orinoco_cs_detach(dev_link_t *link);
+ 
+ /********************************************************************/
+ /* Device methods     						    */
+@@ -603,49 +577,85 @@ static char version[] __initdata = DRIVE
+ 	"Pavel Roskin <proski at gnu.org>, et al)";
+ 
+ static struct pcmcia_device_id orinoco_cs_ids[] = {
+-	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
+-	PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
+-	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
+-	PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
+-	PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002),
+-	PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001),
+-	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305),
+-	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613),
+-	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002),
+-	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673),
+-	PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002),
+-	PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002),
+-	PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001),
+-	PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300),
+-	PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021),
+-	PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002),
+-	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
+-	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
++	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
++	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
++	PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
++	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
++	PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
++	PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
++	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
++	PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
++	PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
++	PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
++	PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
++	PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
++	PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
++	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
++	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
++	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
++	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
++	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
++	PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
++	PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
++	PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
++	PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
++	PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
++	PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
++	PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
++	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
++	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
++	PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
+ 	PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
+-	PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
+ 	PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
++	PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
++	PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092),
++	PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
++	PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
++	PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
+ 	PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
++	PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
+ 	PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
++	PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
+ 	PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
++	PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
++	PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39),
+ 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
+ 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
+ 	PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
+ 	PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
+ 	PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
++	PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
++	PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
+ 	PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
+ 	PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
++	PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
++	PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
+ 	PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
++	PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
++	PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
++	PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2),
++	PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
++	PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
+ 	PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
+ 	PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
+ 	PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
+ 	PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
+ 	PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
++	PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
+ 	PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
++	PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
++	PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
++	PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
++	PCMCIA_DEVICE_PROD_ID123("PCMCIA", "11M WLAN Card v2.5", "ISL37300P", 0x281f1c5d, 0x6e440487, 0xc9049a39),
+ 	PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
++	PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
+ 	PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
+ 	PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
+ 	PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
+-	PCMCIA_DEVICE_PROD_ID1("Symbol Technologies", 0x3f02b4d6),
++	PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
++	PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
++	PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39),
++	PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
+ 	PCMCIA_DEVICE_NULL,
+ };
+ MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
+@@ -656,8 +666,8 @@ static struct pcmcia_driver orinoco_driv
+ 		.name	= DRIVER_NAME,
+ 	},
+ 	.attach		= orinoco_cs_attach,
+-	.event		= orinoco_cs_event,
+ 	.detach		= orinoco_cs_detach,
++	.event		= orinoco_cs_event,
+ 	.id_table       = orinoco_cs_ids,
+ };
+ 
+diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
+--- a/drivers/net/wireless/orinoco_nortel.c
++++ b/drivers/net/wireless/orinoco_nortel.c
+@@ -40,29 +40,13 @@
+ #define PFX DRIVER_NAME ": "
+ 
+ #include <linux/config.h>
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/sched.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/timer.h>
+-#include <linux/ioport.h>
+-#include <asm/uaccess.h>
+-#include <asm/io.h>
+-#include <asm/system.h>
+-#include <linux/netdevice.h>
+-#include <linux/if_arp.h>
+-#include <linux/etherdevice.h>
+-#include <linux/list.h>
++#include <linux/delay.h>
+ #include <linux/pci.h>
+-#include <linux/fcntl.h>
+-
+ #include <pcmcia/cisreg.h>
+ 
+-#include "hermes.h"
+ #include "orinoco.h"
+ 
+ #define COR_OFFSET    (0xe0)	/* COR attribute offset of Prism2 PC card */
+@@ -108,7 +92,7 @@ static int nortel_pci_cor_reset(struct o
+ 	return 0;
+ }
+ 
+-int nortel_pci_hw_init(struct nortel_pci_card *card)
++static int nortel_pci_hw_init(struct nortel_pci_card *card)
+ {
+ 	int i;
+ 	u32 reg;
+diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
+--- a/drivers/net/wireless/orinoco_pci.c
++++ b/drivers/net/wireless/orinoco_pci.c
+@@ -93,28 +93,12 @@
+ #define PFX DRIVER_NAME ": "
+ 
+ #include <linux/config.h>
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/sched.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/timer.h>
+-#include <linux/ioport.h>
+-#include <linux/netdevice.h>
+-#include <linux/if_arp.h>
+-#include <linux/etherdevice.h>
+-#include <linux/list.h>
++#include <linux/delay.h>
+ #include <linux/pci.h>
+-#include <linux/fcntl.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/io.h>
+-#include <asm/system.h>
+ 
+-#include "hermes.h"
+ #include "orinoco.h"
+ 
+ /* All the magic there is from wlan-ng */
+diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
+--- a/drivers/net/wireless/orinoco_plx.c
++++ b/drivers/net/wireless/orinoco_plx.c
+@@ -117,29 +117,13 @@
+ #define PFX DRIVER_NAME ": "
+ 
+ #include <linux/config.h>
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/sched.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/timer.h>
+-#include <linux/ioport.h>
+-#include <asm/uaccess.h>
+-#include <asm/io.h>
+-#include <asm/system.h>
+-#include <linux/netdevice.h>
+-#include <linux/if_arp.h>
+-#include <linux/etherdevice.h>
+-#include <linux/list.h>
++#include <linux/delay.h>
+ #include <linux/pci.h>
+-#include <linux/fcntl.h>
+-
+ #include <pcmcia/cisreg.h>
+ 
+-#include "hermes.h"
+ #include "orinoco.h"
+ 
+ #define COR_OFFSET	(0x3e0)	/* COR attribute offset of Prism2 PC card */
+diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
+--- a/drivers/net/wireless/orinoco_tmd.c
++++ b/drivers/net/wireless/orinoco_tmd.c
+@@ -53,29 +53,13 @@
+ #define PFX DRIVER_NAME ": "
+ 
+ #include <linux/config.h>
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/sched.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/timer.h>
+-#include <linux/ioport.h>
+-#include <asm/uaccess.h>
+-#include <asm/io.h>
+-#include <asm/system.h>
+-#include <linux/netdevice.h>
+-#include <linux/if_arp.h>
+-#include <linux/etherdevice.h>
+-#include <linux/list.h>
++#include <linux/delay.h>
+ #include <linux/pci.h>
+-#include <linux/fcntl.h>
+-
+ #include <pcmcia/cisreg.h>
+ 
+-#include "hermes.h"
+ #include "orinoco.h"
+ 
+ #define COR_VALUE	(COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
+diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
+--- a/drivers/net/wireless/prism54/isl_ioctl.c
++++ b/drivers/net/wireless/prism54/isl_ioctl.c
+@@ -462,14 +462,12 @@ prism54_get_range(struct net_device *nde
+ 	/* txpower is supported in dBm's */
+ 	range->txpower_capa = IW_TXPOW_DBM;
+ 
+-#if WIRELESS_EXT > 16
+ 	/* Event capability (kernel + driver) */
+ 	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+ 	IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
+ 	IW_EVENT_CAPA_MASK(SIOCGIWAP));
+ 	range->event_capa[1] = IW_EVENT_CAPA_K_1;
+ 	range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
+-#endif /* WIRELESS_EXT > 16 */
+ 
+ 	if (islpci_get_state(priv) < PRV_STATE_INIT)
+ 		return 0;
+@@ -693,14 +691,13 @@ prism54_get_scan(struct net_device *ndev
+ 						   extra + dwrq->length,
+ 						   &(bsslist->bsslist[i]),
+ 						   noise);
+-#if WIRELESS_EXT > 16
++
+ 		/* Check if there is space for one more entry */
+ 		if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
+ 			/* Ask user space to try again with a bigger buffer */
+ 			rvalue = -E2BIG;
+ 			break;
+ 		}
+-#endif /* WIRELESS_EXT > 16 */
+ 	}
+ 
+ 	kfree(bsslist);
+@@ -2727,12 +2724,7 @@ const struct iw_handler_def prism54_hand
+ 	.standard = (iw_handler *) prism54_handler,
+ 	.private = (iw_handler *) prism54_private_handler,
+ 	.private_args = (struct iw_priv_args *) prism54_private_args,
+-#if WIRELESS_EXT > 16
+ 	.get_wireless_stats = prism54_get_wireless_stats,
+-#endif /* WIRELESS_EXT > 16 */
+-#if WIRELESS_EXT == 16
+-	.spy_offset = offsetof(islpci_private, spy_data),
+-#endif /* WIRELESS_EXT == 16 */
+ };
+ 
+ /* For wpa_supplicant */
+diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
+--- a/drivers/net/wireless/prism54/islpci_dev.c
++++ b/drivers/net/wireless/prism54/islpci_dev.c
+@@ -439,8 +439,7 @@ prism54_bring_down(islpci_private *priv)
+ 	wmb();
+ 
+ 	/* wait a while for the device to reset */
+-	set_current_state(TASK_UNINTERRUPTIBLE);
+-	schedule_timeout(50*HZ/1000);
++	schedule_timeout_uninterruptible(msecs_to_jiffies(50));
+ 
+ 	return 0;
+ }
+@@ -491,8 +490,7 @@ islpci_reset_if(islpci_private *priv)
+ 		/* The software reset acknowledge needs about 220 msec here.
+ 		 * Be conservative and wait for up to one second. */
+ 	
+-		set_current_state(TASK_UNINTERRUPTIBLE);
+-		remaining = schedule_timeout(HZ);
++		remaining = schedule_timeout_uninterruptible(HZ);
+ 
+ 		if(remaining > 0) {
+ 			result = 0;
+@@ -756,8 +754,7 @@ islpci_free_memory(islpci_private *priv)
+ 			pci_unmap_single(priv->pdev, buf->pci_addr,
+ 					 buf->size, PCI_DMA_FROMDEVICE);
+ 		buf->pci_addr = 0;
+-		if (buf->mem)
+-			kfree(buf->mem);
++		kfree(buf->mem);
+ 		buf->size = 0;
+ 		buf->mem = NULL;
+         }
+@@ -839,13 +836,9 @@ islpci_setup(struct pci_dev *pdev)
+ 	priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
+ 		priv->monitor_type : ARPHRD_ETHER;
+ 
+-#if WIRELESS_EXT > 16
+ 	/* Add pointers to enable iwspy support. */
+ 	priv->wireless_data.spy_data = &priv->spy_data;
+ 	ndev->wireless_data = &priv->wireless_data;
+-#else  /* WIRELESS_EXT > 16 */
+-	ndev->get_wireless_stats = &prism54_get_wireless_stats;
+-#endif /* WIRELESS_EXT > 16 */
+ 
+ 	/* save the start and end address of the PCI memory area */
+ 	ndev->mem_start = (unsigned long) priv->device_base;
+diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
+--- a/drivers/net/wireless/prism54/islpci_dev.h
++++ b/drivers/net/wireless/prism54/islpci_dev.h
+@@ -100,9 +100,7 @@ typedef struct {
+ 
+ 	struct iw_spy_data spy_data; /* iwspy support */
+ 
+-#if WIRELESS_EXT > 16
+ 	struct iw_public_data wireless_data;
+-#endif /* WIRELESS_EXT > 16 */
+ 
+ 	int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
+ 
+diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
+--- a/drivers/net/wireless/prism54/islpci_eth.c
++++ b/drivers/net/wireless/prism54/islpci_eth.c
+@@ -97,12 +97,6 @@ islpci_eth_transmit(struct sk_buff *skb,
+ 	/* lock the driver code */
+ 	spin_lock_irqsave(&priv->slock, flags);
+ 
+-	/* determine the amount of fragments needed to store the frame */
+-
+-	frame_size = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+-	if (init_wds)
+-		frame_size += 6;
+-
+ 	/* check whether the destination queue has enough fragments for the frame */
+ 	curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]);
+ 	if (unlikely(curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE)) {
+@@ -213,6 +207,7 @@ islpci_eth_transmit(struct sk_buff *skb,
+ 	/* store the skb address for future freeing  */
+ 	priv->data_low_tx[index] = skb;
+ 	/* set the proper fragment start address and size information */
++	frame_size = skb->len;
+ 	fragment->size = cpu_to_le16(frame_size);
+ 	fragment->flags = cpu_to_le16(0);	/* set to 1 if more fragments */
+ 	fragment->address = cpu_to_le32(pci_map_address);
+@@ -246,12 +241,10 @@ islpci_eth_transmit(struct sk_buff *skb,
+ 	return 0;
+ 
+       drop_free:
+-	/* free the skbuf structure before aborting */
+-	dev_kfree_skb(skb);
+-	skb = NULL;
+-
+ 	priv->statistics.tx_dropped++;
+ 	spin_unlock_irqrestore(&priv->slock, flags);
++	dev_kfree_skb(skb);
++	skb = NULL;
+ 	return err;
+ }
+ 
+diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
+--- a/drivers/net/wireless/prism54/islpci_mgt.c
++++ b/drivers/net/wireless/prism54/islpci_mgt.c
+@@ -137,7 +137,7 @@ islpci_mgmt_rx_fill(struct net_device *n
+ 						       PCI_DMA_FROMDEVICE);
+ 			if (!buf->pci_addr) {
+ 				printk(KERN_WARNING
+-				       "Failed to make memory DMA'able\n.");
++				       "Failed to make memory DMA'able.\n");
+ 				return -ENOMEM;
+ 			}
+ 		}
+@@ -455,7 +455,7 @@ islpci_mgt_transaction(struct net_device
+ 		       struct islpci_mgmtframe **recvframe)
+ {
+ 	islpci_private *priv = netdev_priv(ndev);
+-	const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000;
++	const long wait_cycle_jiffies = msecs_to_jiffies(ISL38XX_WAIT_CYCLE * 10);
+ 	long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies;
+ 	int err;
+ 	DEFINE_WAIT(wait);
+@@ -475,8 +475,7 @@ islpci_mgt_transaction(struct net_device
+ 		int timeleft;
+ 		struct islpci_mgmtframe *frame;
+ 
+-		set_current_state(TASK_UNINTERRUPTIBLE);
+-		timeleft = schedule_timeout(wait_cycle_jiffies);
++		timeleft = schedule_timeout_uninterruptible(wait_cycle_jiffies);
+ 		frame = xchg(&priv->mgmt_received, NULL);
+ 		if (frame) {
+ 			if (frame->header->oid == oid) {
+diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
+--- a/drivers/net/wireless/prism54/oid_mgt.c
++++ b/drivers/net/wireless/prism54/oid_mgt.c
+@@ -268,11 +268,10 @@ mgt_clean(islpci_private *priv)
+ 
+ 	if (!priv->mib)
+ 		return;
+-	for (i = 0; i < OID_NUM_LAST; i++)
+-		if (priv->mib[i]) {
+-			kfree(priv->mib[i]);
+-			priv->mib[i] = NULL;
+-		}
++	for (i = 0; i < OID_NUM_LAST; i++) {
++		kfree(priv->mib[i]);
++		priv->mib[i] = NULL;
++	}
+ 	kfree(priv->mib);
+ 	priv->mib = NULL;
+ }
+diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
+--- a/drivers/net/wireless/ray_cs.c
++++ b/drivers/net/wireless/ray_cs.c
+@@ -1649,28 +1649,28 @@ static iw_stats * ray_get_wireless_stats
+  */
+ 
+ static const iw_handler	ray_handler[] = {
+-	[SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) ray_commit,
+-	[SIOCGIWNAME  -SIOCIWFIRST] (iw_handler) ray_get_name,
+-	[SIOCSIWFREQ  -SIOCIWFIRST] (iw_handler) ray_set_freq,
+-	[SIOCGIWFREQ  -SIOCIWFIRST] (iw_handler) ray_get_freq,
+-	[SIOCSIWMODE  -SIOCIWFIRST] (iw_handler) ray_set_mode,
+-	[SIOCGIWMODE  -SIOCIWFIRST] (iw_handler) ray_get_mode,
+-	[SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) ray_get_range,
++	[SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) ray_commit,
++	[SIOCGIWNAME  -SIOCIWFIRST] = (iw_handler) ray_get_name,
++	[SIOCSIWFREQ  -SIOCIWFIRST] = (iw_handler) ray_set_freq,
++	[SIOCGIWFREQ  -SIOCIWFIRST] = (iw_handler) ray_get_freq,
++	[SIOCSIWMODE  -SIOCIWFIRST] = (iw_handler) ray_set_mode,
++	[SIOCGIWMODE  -SIOCIWFIRST] = (iw_handler) ray_get_mode,
++	[SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) ray_get_range,
+ #ifdef WIRELESS_SPY
+- 	[SIOCSIWSPY   -SIOCIWFIRST] (iw_handler) iw_handler_set_spy,
+-	[SIOCGIWSPY   -SIOCIWFIRST] (iw_handler) iw_handler_get_spy,
+-	[SIOCSIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_set_thrspy,
+-	[SIOCGIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_get_thrspy,
++ 	[SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
++	[SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
++	[SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
++	[SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
+ #endif	/* WIRELESS_SPY */
+-	[SIOCGIWAP    -SIOCIWFIRST] (iw_handler) ray_get_wap,
+-	[SIOCSIWESSID -SIOCIWFIRST] (iw_handler) ray_set_essid,
+-	[SIOCGIWESSID -SIOCIWFIRST] (iw_handler) ray_get_essid,
+-	[SIOCSIWRATE  -SIOCIWFIRST] (iw_handler) ray_set_rate,
+-	[SIOCGIWRATE  -SIOCIWFIRST] (iw_handler) ray_get_rate,
+-	[SIOCSIWRTS   -SIOCIWFIRST] (iw_handler) ray_set_rts,
+-	[SIOCGIWRTS   -SIOCIWFIRST] (iw_handler) ray_get_rts,
+-	[SIOCSIWFRAG  -SIOCIWFIRST] (iw_handler) ray_set_frag,
+-	[SIOCGIWFRAG  -SIOCIWFIRST] (iw_handler) ray_get_frag,
++	[SIOCGIWAP    -SIOCIWFIRST] = (iw_handler) ray_get_wap,
++	[SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) ray_set_essid,
++	[SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) ray_get_essid,
++	[SIOCSIWRATE  -SIOCIWFIRST] = (iw_handler) ray_set_rate,
++	[SIOCGIWRATE  -SIOCIWFIRST] = (iw_handler) ray_get_rate,
++	[SIOCSIWRTS   -SIOCIWFIRST] = (iw_handler) ray_set_rts,
++	[SIOCGIWRTS   -SIOCIWFIRST] = (iw_handler) ray_get_rts,
++	[SIOCSIWFRAG  -SIOCIWFIRST] = (iw_handler) ray_set_frag,
++	[SIOCGIWFRAG  -SIOCIWFIRST] = (iw_handler) ray_get_frag,
+ };
+ 
+ #define SIOCSIPFRAMING	SIOCIWFIRSTPRIV		/* Set framing mode */
+@@ -1678,9 +1678,9 @@ static const iw_handler	ray_handler[] = 
+ #define SIOCGIPCOUNTRY	SIOCIWFIRSTPRIV + 3	/* Get country code */
+ 
+ static const iw_handler	ray_private_handler[] = {
+-	[0] (iw_handler) ray_set_framing,
+-	[1] (iw_handler) ray_get_framing,
+-	[3] (iw_handler) ray_get_country,
++	[0] = (iw_handler) ray_set_framing,
++	[1] = (iw_handler) ray_get_framing,
++	[3] = (iw_handler) ray_get_country,
+ };
+ 
+ static const struct iw_priv_args	ray_private_args[] = {
+diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
+--- a/drivers/net/wireless/spectrum_cs.c
++++ b/drivers/net/wireless/spectrum_cs.c
+@@ -22,58 +22,23 @@
+ #define PFX DRIVER_NAME ": "
+ 
+ #include <linux/config.h>
+-#ifdef  __IN_PCMCIA_PACKAGE__
+-#include <pcmcia/k_compat.h>
+-#endif /* __IN_PCMCIA_PACKAGE__ */
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/sched.h>
+-#include <linux/ptrace.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/ioport.h>
+-#include <linux/netdevice.h>
+-#include <linux/if_arp.h>
+-#include <linux/etherdevice.h>
+-#include <linux/wireless.h>
+-
++#include <linux/delay.h>
++#include <linux/firmware.h>
+ #include <pcmcia/cs_types.h>
+ #include <pcmcia/cs.h>
+ #include <pcmcia/cistpl.h>
+ #include <pcmcia/cisreg.h>
+ #include <pcmcia/ds.h>
+ 
+-#include <asm/uaccess.h>
+-#include <asm/io.h>
+-#include <asm/system.h>
+-
+ #include "orinoco.h"
+ 
+-/*
+- * If SPECTRUM_FW_INCLUDED is defined, the firmware is hardcoded into
+- * the driver.  Use get_symbol_fw script to generate spectrum_fw.h and
+- * copy it to the same directory as spectrum_cs.c.
+- *
+- * If SPECTRUM_FW_INCLUDED is not defined, the firmware is loaded at the
+- * runtime using hotplug.  Use the same get_symbol_fw script to generate
+- * files symbol_sp24t_prim_fw symbol_sp24t_sec_fw, copy them to the
+- * hotplug firmware directory (typically /usr/lib/hotplug/firmware) and
+- * make sure that you have hotplug installed and enabled in the kernel.
+- */
+-/* #define SPECTRUM_FW_INCLUDED 1 */
+-
+-#ifdef SPECTRUM_FW_INCLUDED
+-/* Header with the firmware */
+-#include "spectrum_fw.h"
+-#else	/* !SPECTRUM_FW_INCLUDED */
+-#include <linux/firmware.h>
+ static unsigned char *primsym;
+ static unsigned char *secsym;
+ static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
+ static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
+-#endif	/* !SPECTRUM_FW_INCLUDED */
+ 
+ /********************************************************************/
+ /* Module stuff							    */
+@@ -124,17 +89,8 @@ static dev_link_t *dev_list; /* = NULL *
+ /* Function prototypes						    */
+ /********************************************************************/
+ 
+-/* device methods */
+-static int spectrum_cs_hard_reset(struct orinoco_private *priv);
+-
+-/* PCMCIA gumpf */
+-static void spectrum_cs_config(dev_link_t * link);
+-static void spectrum_cs_release(dev_link_t * link);
+-static int spectrum_cs_event(event_t event, int priority,
+-			    event_callback_args_t * args);
+-
+-static dev_link_t *spectrum_cs_attach(void);
+-static void spectrum_cs_detach(dev_link_t *);
++static void spectrum_cs_release(dev_link_t *link);
++static void spectrum_cs_detach(dev_link_t *link);
+ 
+ /********************************************************************/
+ /* Firmware downloader						    */
+@@ -182,8 +138,8 @@ static void spectrum_cs_detach(dev_link_
+  * Each block has the following structure.
+  */
+ struct dblock {
+-	u32 _addr;		/* adapter address where to write the block */
+-	u16 _len;		/* length of the data only, in bytes */
++	__le32 _addr;		/* adapter address where to write the block */
++	__le16 _len;		/* length of the data only, in bytes */
+ 	char data[0];		/* data to be written */
+ } __attribute__ ((packed));
+ 
+@@ -193,9 +149,9 @@ struct dblock {
+  * items with matching ID should be written.
+  */
+ struct pdr {
+-	u32 _id;		/* record ID */
+-	u32 _addr;		/* adapter address where to write the data */
+-	u32 _len;		/* expected length of the data, in bytes */
++	__le32 _id;		/* record ID */
++	__le32 _addr;		/* adapter address where to write the data */
++	__le32 _len;		/* expected length of the data, in bytes */
+ 	char next[0];		/* next PDR starts here */
+ } __attribute__ ((packed));
+ 
+@@ -206,8 +162,8 @@ struct pdr {
+  * be plugged into the secondary firmware.
+  */
+ struct pdi {
+-	u16 _len;		/* length of ID and data, in words */
+-	u16 _id;		/* record ID */
++	__le16 _len;		/* length of ID and data, in words */
++	__le16 _id;		/* record ID */
+ 	char data[0];		/* plug data */
+ } __attribute__ ((packed));;
+ 
+@@ -414,7 +370,7 @@ spectrum_plug_pdi(hermes_t *hw, struct p
+ 
+ /* Read PDA from the adapter */
+ static int
+-spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
++spectrum_read_pda(hermes_t *hw, __le16 *pda, int pda_len)
+ {
+ 	int ret;
+ 	int pda_size;
+@@ -445,7 +401,7 @@ spectrum_read_pda(hermes_t *hw, u16 *pda
+ /* Parse PDA and write the records into the adapter */
+ static int
+ spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block,
+-		   u16 *pda)
++		   __le16 *pda)
+ {
+ 	int ret;
+ 	struct pdi *pdi;
+@@ -511,7 +467,7 @@ spectrum_dl_image(hermes_t *hw, dev_link
+ 	const struct dblock *first_block;
+ 
+ 	/* Plug Data Area (PDA) */
+-	u16 pda[PDA_WORDS];
++	__le16 pda[PDA_WORDS];
+ 
+ 	/* Binary block begins after the 0x1A marker */
+ 	ptr = image;
+@@ -571,8 +527,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_l
+ {
+ 	int ret;
+ 	client_handle_t handle = link->handle;
+-
+-#ifndef SPECTRUM_FW_INCLUDED
+ 	const struct firmware *fw_entry;
+ 
+ 	if (request_firmware(&fw_entry, primary_fw_name,
+@@ -592,7 +546,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_l
+ 		       secondary_fw_name);
+ 		return -ENOENT;
+ 	}
+-#endif
+ 
+ 	/* Load primary firmware */
+ 	ret = spectrum_dl_image(hw, link, primsym);
+@@ -1085,7 +1038,7 @@ static char version[] __initdata = DRIVE
+ static struct pcmcia_device_id spectrum_cs_ids[] = {
+ 	PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
+ 	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
+-	PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001), /* Intel PRO/Wireless 2011B */
++	PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
+ 	PCMCIA_DEVICE_NULL,
+ };
+ MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
+@@ -1096,8 +1049,8 @@ static struct pcmcia_driver orinoco_driv
+ 		.name	= DRIVER_NAME,
+ 	},
+ 	.attach		= spectrum_cs_attach,
+-	.event		= spectrum_cs_event,
+ 	.detach		= spectrum_cs_detach,
++	.event		= spectrum_cs_event,
+ 	.id_table       = spectrum_cs_ids,
+ };
+ 
+diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
+--- a/drivers/net/wireless/strip.c
++++ b/drivers/net/wireless/strip.c
+@@ -860,12 +860,9 @@ static int allocate_buffers(struct strip
+ 		strip_info->mtu = dev->mtu = mtu;
+ 		return (1);
+ 	}
+-	if (r)
+-		kfree(r);
+-	if (s)
+-		kfree(s);
+-	if (t)
+-		kfree(t);
++	kfree(r);
++	kfree(s);
++	kfree(t);
+ 	return (0);
+ }
+ 
+@@ -922,13 +919,9 @@ static int strip_change_mtu(struct net_d
+ 	printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
+ 	       strip_info->dev->name, old_mtu, strip_info->mtu);
+ 
+-	if (orbuff)
+-		kfree(orbuff);
+-	if (osbuff)
+-		kfree(osbuff);
+-	if (otbuff)
+-		kfree(otbuff);
+-
++	kfree(orbuff);
++	kfree(osbuff);
++	kfree(otbuff);
+ 	return 0;
+ }
+ 
+@@ -2498,18 +2491,13 @@ static int strip_close_low(struct net_de
+ 	/*
+ 	 * Free all STRIP frame buffers.
+ 	 */
+-	if (strip_info->rx_buff) {
+-		kfree(strip_info->rx_buff);
+-		strip_info->rx_buff = NULL;
+-	}
+-	if (strip_info->sx_buff) {
+-		kfree(strip_info->sx_buff);
+-		strip_info->sx_buff = NULL;
+-	}
+-	if (strip_info->tx_buff) {
+-		kfree(strip_info->tx_buff);
+-		strip_info->tx_buff = NULL;
+-	}
++	kfree(strip_info->rx_buff);
++	strip_info->rx_buff = NULL;
++	kfree(strip_info->sx_buff);
++	strip_info->sx_buff = NULL;
++	kfree(strip_info->tx_buff);
++	strip_info->tx_buff = NULL;
++
+ 	del_timer(&strip_info->idle_timer);
+ 	return 0;
+ }
+diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
+--- a/drivers/net/wireless/wavelan.c
++++ b/drivers/net/wireless/wavelan.c
+@@ -430,7 +430,6 @@ static void fee_read(unsigned long ioadd
+ 	}
+ }
+ 
+-#ifdef WIRELESS_EXT		/* if the wireless extension exists in the kernel */
+ 
+ /*------------------------------------------------------------------*/
+ /*
+@@ -514,7 +513,6 @@ static void fee_write(unsigned long ioad
+ 	fee_wait(ioaddr, 10, 100);
+ #endif				/* EEPROM_IS_PROTECTED */
+ }
+-#endif				/* WIRELESS_EXT */
+ 
+ /************************ I82586 SUBROUTINES *************************/
+ /*
+@@ -973,11 +971,9 @@ static void wv_mmc_show(struct net_devic
+ 	mmc_read(ioaddr, 0, (u8 *) & m, sizeof(m));
+ 	mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
+ 
+-#ifdef WIRELESS_EXT		/* if wireless extension exists in the kernel */
+ 	/* Don't forget to update statistics */
+ 	lp->wstats.discard.nwid +=
+ 	    (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
+-#endif				/* WIRELESS_EXT */
+ 
+ 	printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
+ #ifdef DEBUG_SHOW_UNUSED
+@@ -1499,7 +1495,6 @@ static int wavelan_set_mac_address(struc
+ }
+ #endif				/* SET_MAC_ADDRESS */
+ 
+-#ifdef WIRELESS_EXT		/* if wireless extensions exist in the kernel */
+ 
+ /*------------------------------------------------------------------*/
+ /*
+@@ -2473,7 +2468,6 @@ static iw_stats *wavelan_get_wireless_st
+ #endif
+ 	return &lp->wstats;
+ }
+-#endif				/* WIRELESS_EXT */
+ 
+ /************************* PACKET RECEPTION *************************/
+ /*
+@@ -4194,11 +4188,9 @@ static int __init wavelan_config(struct 
+ 	dev->set_mac_address = &wavelan_set_mac_address;
+ #endif				/* SET_MAC_ADDRESS */
+ 
+-#ifdef WIRELESS_EXT		/* if wireless extension exists in the kernel */
+ 	dev->wireless_handlers = &wavelan_handler_def;
+ 	lp->wireless_data.spy_data = &lp->spy_data;
+ 	dev->wireless_data = &lp->wireless_data;
+-#endif
+ 
+ 	dev->mtu = WAVELAN_MTU;
+ 
+diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
+--- a/drivers/net/wireless/wavelan.p.h
++++ b/drivers/net/wireless/wavelan.p.h
+@@ -409,11 +409,9 @@
+ #define MULTICAST_AVOID		/* Avoid extra multicast (I'm sceptical). */
+ #undef SET_MAC_ADDRESS		/* Experimental */
+ 
+-#ifdef WIRELESS_EXT	/* If wireless extensions exist in the kernel */
+ /* Warning:  this stuff will slow down the driver. */
+ #define WIRELESS_SPY		/* Enable spying addresses. */
+ #undef HISTOGRAM		/* Enable histogram of signal level. */
+-#endif
+ 
+ /****************************** DEBUG ******************************/
+ 
+@@ -506,12 +504,10 @@ struct net_local
+   u_short	tx_first_free;
+   u_short	tx_first_in_use;
+ 
+-#ifdef WIRELESS_EXT
+   iw_stats	wstats;		/* Wireless-specific statistics */
+ 
+   struct iw_spy_data	spy_data;
+   struct iw_public_data	wireless_data;
+-#endif
+ 
+ #ifdef HISTOGRAM
+   int		his_number;		/* number of intervals */
+diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
+--- a/drivers/net/wireless/wavelan_cs.c
++++ b/drivers/net/wireless/wavelan_cs.c
+@@ -415,7 +415,6 @@ fee_read(u_long		base,	/* i/o port of th
+     }
+ }
+ 
+-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
+ 
+ /*------------------------------------------------------------------*/
+ /*
+@@ -500,7 +499,6 @@ fee_write(u_long	base,	/* i/o port of th
+   fee_wait(base, 10, 100);
+ #endif	/* EEPROM_IS_PROTECTED */
+ }
+-#endif	/* WIRELESS_EXT */
+ 
+ /******************* WaveLAN Roaming routines... ********************/
+ 
+@@ -1161,10 +1159,8 @@ wv_mmc_show(struct net_device *	dev)
+   mmc_read(base, 0, (u_char *)&m, sizeof(m));
+   mmc_out(base, mmwoff(0, mmw_freeze), 0);
+ 
+-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
+   /* Don't forget to update statistics */
+   lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
+-#endif	/* WIRELESS_EXT */
+ 
+   spin_unlock_irqrestore(&lp->spinlock, flags);
+ 
+@@ -1550,7 +1546,6 @@ wavelan_set_mac_address(struct net_devic
+ }
+ #endif	/* SET_MAC_ADDRESS */
+ 
+-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
+ 
+ /*------------------------------------------------------------------*/
+ /*
+@@ -2793,7 +2788,6 @@ wavelan_get_wireless_stats(struct net_de
+ #endif
+   return &lp->wstats;
+ }
+-#endif	/* WIRELESS_EXT */
+ 
+ /************************* PACKET RECEPTION *************************/
+ /*
+@@ -4679,11 +4673,9 @@ wavelan_attach(void)
+   dev->watchdog_timeo	= WATCHDOG_JIFFIES;
+   SET_ETHTOOL_OPS(dev, &ops);
+ 
+-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
+   dev->wireless_handlers = &wavelan_handler_def;
+   lp->wireless_data.spy_data = &lp->spy_data;
+   dev->wireless_data = &lp->wireless_data;
+-#endif
+ 
+   /* Other specific data */
+   dev->mtu = WAVELAN_MTU;
+diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
+--- a/drivers/net/wireless/wavelan_cs.p.h
++++ b/drivers/net/wireless/wavelan_cs.p.h
+@@ -472,11 +472,9 @@
+ #define MULTICAST_AVOID		/* Avoid extra multicast (I'm sceptical) */
+ #undef SET_MAC_ADDRESS		/* Experimental */
+ 
+-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
+ /* Warning : these stuff will slow down the driver... */
+ #define WIRELESS_SPY		/* Enable spying addresses */
+ #undef HISTOGRAM		/* Enable histogram of sig level... */
+-#endif
+ 
+ /****************************** DEBUG ******************************/
+ 
+@@ -624,12 +622,10 @@ struct net_local
+   int   	rfp;		/* Last DMA machine receive pointer */
+   int		overrunning;	/* Receiver overrun flag */
+ 
+-#ifdef WIRELESS_EXT
+   iw_stats	wstats;		/* Wireless specific stats */
+ 
+   struct iw_spy_data	spy_data;
+   struct iw_public_data	wireless_data;
+-#endif
+ 
+ #ifdef HISTOGRAM
+   int		his_number;		/* Number of intervals */
+diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
+--- a/drivers/net/wireless/wl3501.h
++++ b/drivers/net/wireless/wl3501.h
+@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr {
+ 
+ struct wl3501_80211_tx_hdr {
+ 	struct wl3501_80211_tx_plcp_hdr	pclp_hdr;
+-	struct ieee80211_hdr		mac_hdr;
++	struct ieee80211_hdr_4addr		mac_hdr;
+ } __attribute__ ((packed));
+ 
+ /*
+diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
+--- a/drivers/parisc/asp.c
++++ b/drivers/parisc/asp.c
+@@ -77,12 +77,12 @@ asp_init_chip(struct parisc_device *dev)
+ 	struct gsc_irq gsc_irq;
+ 	int ret;
+ 
+-	asp.version = gsc_readb(dev->hpa + ASP_VER_OFFSET) & 0xf;
++	asp.version = gsc_readb(dev->hpa.start + ASP_VER_OFFSET) & 0xf;
+ 	asp.name = (asp.version == 1) ? "Asp" : "Cutoff";
+ 	asp.hpa = ASP_INTERRUPT_ADDR;
+ 
+ 	printk(KERN_INFO "%s version %d at 0x%lx found.\n", 
+-		asp.name, asp.version, dev->hpa);
++		asp.name, asp.version, dev->hpa.start);
+ 
+ 	/* the IRQ ASP should use */
+ 	ret = -EBUSY;
+@@ -126,7 +126,7 @@ static struct parisc_device_id asp_tbl[]
+ };
+ 
+ struct parisc_driver asp_driver = {
+-	.name =		"Asp",
++	.name =		"asp",
+ 	.id_table =	asp_tbl,
+ 	.probe =	asp_init_chip,
+ };
+diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
+--- a/drivers/parisc/ccio-dma.c
++++ b/drivers/parisc/ccio-dma.c
+@@ -100,9 +100,9 @@
+ #define DBG_RUN_SG(x...)
+ #endif
+ 
+-#define CCIO_INLINE	/* inline */
+-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *)(addr))
+-#define READ_U32(addr) gsc_readl((u32 *)(addr))
++#define CCIO_INLINE	inline
++#define WRITE_U32(value, addr) __raw_writel(value, addr)
++#define READ_U32(addr) __raw_readl(addr)
+ 
+ #define U2_IOA_RUNWAY 0x580
+ #define U2_BC_GSC     0x501
+@@ -115,28 +115,28 @@
+ 
+ struct ioa_registers {
+         /* Runway Supervisory Set */
+-        volatile int32_t    unused1[12];
+-        volatile uint32_t   io_command;             /* Offset 12 */
+-        volatile uint32_t   io_status;              /* Offset 13 */
+-        volatile uint32_t   io_control;             /* Offset 14 */
+-        volatile int32_t    unused2[1];
++        int32_t    unused1[12];
++        uint32_t   io_command;             /* Offset 12 */
++        uint32_t   io_status;              /* Offset 13 */
++        uint32_t   io_control;             /* Offset 14 */
++        int32_t    unused2[1];
+ 
+         /* Runway Auxiliary Register Set */
+-        volatile uint32_t   io_err_resp;            /* Offset  0 */
+-        volatile uint32_t   io_err_info;            /* Offset  1 */
+-        volatile uint32_t   io_err_req;             /* Offset  2 */
+-        volatile uint32_t   io_err_resp_hi;         /* Offset  3 */
+-        volatile uint32_t   io_tlb_entry_m;         /* Offset  4 */
+-        volatile uint32_t   io_tlb_entry_l;         /* Offset  5 */
+-        volatile uint32_t   unused3[1];
+-        volatile uint32_t   io_pdir_base;           /* Offset  7 */
+-        volatile uint32_t   io_io_low_hv;           /* Offset  8 */
+-        volatile uint32_t   io_io_high_hv;          /* Offset  9 */
+-        volatile uint32_t   unused4[1];
+-        volatile uint32_t   io_chain_id_mask;       /* Offset 11 */
+-        volatile uint32_t   unused5[2];
+-        volatile uint32_t   io_io_low;              /* Offset 14 */
+-        volatile uint32_t   io_io_high;             /* Offset 15 */
++        uint32_t   io_err_resp;            /* Offset  0 */
++        uint32_t   io_err_info;            /* Offset  1 */
++        uint32_t   io_err_req;             /* Offset  2 */
++        uint32_t   io_err_resp_hi;         /* Offset  3 */
++        uint32_t   io_tlb_entry_m;         /* Offset  4 */
++        uint32_t   io_tlb_entry_l;         /* Offset  5 */
++        uint32_t   unused3[1];
++        uint32_t   io_pdir_base;           /* Offset  7 */
++        uint32_t   io_io_low_hv;           /* Offset  8 */
++        uint32_t   io_io_high_hv;          /* Offset  9 */
++        uint32_t   unused4[1];
++        uint32_t   io_chain_id_mask;       /* Offset 11 */
++        uint32_t   unused5[2];
++        uint32_t   io_io_low;              /* Offset 14 */
++        uint32_t   io_io_high;             /* Offset 15 */
+ };
+ 
+ /*
+@@ -226,7 +226,7 @@ struct ioa_registers {
+ */
+ 
+ struct ioc {
+-	struct ioa_registers *ioc_hpa;  /* I/O MMU base address */
++	struct ioa_registers __iomem *ioc_regs;  /* I/O MMU base address */
+ 	u8  *res_map;	                /* resource map, bit == pdir entry */
+ 	u64 *pdir_base;	                /* physical base address */
+ 	u32 pdir_size; 			/* bytes, function of IOV Space size */
+@@ -595,7 +595,7 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_
+ 	** Grab virtual index [0:11]
+ 	** Deposit virt_idx bits into I/O PDIR word
+ 	*/
+-	asm volatile ("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
++	asm volatile ("lci %%r0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
+ 	asm volatile ("extru %1,19,12,%0" : "+r" (ci) : "r" (ci));
+ 	asm volatile ("depw  %1,15,12,%0" : "+r" (pa) : "r" (ci));
+ 
+@@ -613,7 +613,7 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_
+ 	** the real mode coherence index generation of U2, the PDIR entry
+ 	** must be flushed to memory to retain coherence."
+ 	*/
+-	asm volatile("fdc 0(%0)" : : "r" (pdir_ptr));
++	asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr));
+ 	asm volatile("sync");
+ }
+ 
+@@ -636,7 +636,7 @@ ccio_clear_io_tlb(struct ioc *ioc, dma_a
+ 	byte_cnt += chain_size;
+ 
+ 	while(byte_cnt > chain_size) {
+-		WRITE_U32(CMD_TLB_PURGE | iovp, &ioc->ioc_hpa->io_command);
++		WRITE_U32(CMD_TLB_PURGE | iovp, &ioc->ioc_regs->io_command);
+ 		iovp += chain_size;
+ 		byte_cnt -= chain_size;
+ 	}
+@@ -684,7 +684,7 @@ ccio_mark_invalid(struct ioc *ioc, dma_a
+ 		** Hopefully someone figures out how to patch (NOP) the
+ 		** FDC/SYNC out at boot time.
+ 		*/
+-		asm volatile("fdc 0(%0)" : : "r" (pdir_ptr[7]));
++		asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr[7]));
+ 
+ 		iovp     += IOVP_SIZE;
+ 		byte_cnt -= IOVP_SIZE;
+@@ -836,7 +836,7 @@ ccio_unmap_single(struct device *dev, dm
+  * This function implements the pci_alloc_consistent function.
+  */
+ static void * 
+-ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
++ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
+ {
+       void *ret;
+ #if 0
+@@ -1251,7 +1251,7 @@ static struct parisc_device_id ccio_tbl[
+ static int ccio_probe(struct parisc_device *dev);
+ 
+ static struct parisc_driver ccio_driver = {
+-	.name =		"U2:Uturn",
++	.name =		"ccio",
+ 	.id_table =	ccio_tbl,
+ 	.probe =	ccio_probe,
+ };
+@@ -1314,14 +1314,13 @@ ccio_ioc_init(struct ioc *ioc)
+ 
+ 	ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
+ 
+-	BUG_ON(ioc->pdir_size >= 4 * 1024 * 1024);   /* max pdir size < 4MB */
++	BUG_ON(ioc->pdir_size > 8 * 1024 * 1024);   /* max pdir size <= 8MB */
+ 
+ 	/* Verify it's a power of two */
+ 	BUG_ON((1 << get_order(ioc->pdir_size)) != (ioc->pdir_size >> PAGE_SHIFT));
+ 
+-	DBG_INIT("%s() hpa 0x%lx mem %luMB IOV %dMB (%d bits)\n",
+-			__FUNCTION__,
+-			ioc->ioc_hpa,
++	DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n",
++			__FUNCTION__, ioc->ioc_regs,
+ 			(unsigned long) num_physpages >> (20 - PAGE_SHIFT),
+ 			iova_space_size>>20,
+ 			iov_order + PAGE_SHIFT);
+@@ -1329,13 +1328,12 @@ ccio_ioc_init(struct ioc *ioc)
+ 	ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL, 
+ 						 get_order(ioc->pdir_size));
+ 	if(NULL == ioc->pdir_base) {
+-		panic("%s:%s() could not allocate I/O Page Table\n", __FILE__,
+-		      __FUNCTION__);
++		panic("%s() could not allocate I/O Page Table\n", __FUNCTION__);
+ 	}
+ 	memset(ioc->pdir_base, 0, ioc->pdir_size);
+ 
+ 	BUG_ON((((unsigned long)ioc->pdir_base) & PAGE_MASK) != (unsigned long)ioc->pdir_base);
+-	DBG_INIT(" base %p", ioc->pdir_base);
++	DBG_INIT(" base %p\n", ioc->pdir_base);
+ 
+ 	/* resource map size dictated by pdir_size */
+  	ioc->res_size = (ioc->pdir_size / sizeof(u64)) >> 3;
+@@ -1344,8 +1342,7 @@ ccio_ioc_init(struct ioc *ioc)
+ 	ioc->res_map = (u8 *)__get_free_pages(GFP_KERNEL, 
+ 					      get_order(ioc->res_size));
+ 	if(NULL == ioc->res_map) {
+-		panic("%s:%s() could not allocate resource map\n", __FILE__,
+-		      __FUNCTION__);
++		panic("%s() could not allocate resource map\n", __FUNCTION__);
+ 	}
+ 	memset(ioc->res_map, 0, ioc->res_size);
+ 
+@@ -1366,44 +1363,58 @@ ccio_ioc_init(struct ioc *ioc)
+ 	** Initialize IOA hardware
+ 	*/
+ 	WRITE_U32(CCIO_CHAINID_MASK << ioc->chainid_shift, 
+-		  &ioc->ioc_hpa->io_chain_id_mask);
++		  &ioc->ioc_regs->io_chain_id_mask);
+ 
+ 	WRITE_U32(virt_to_phys(ioc->pdir_base), 
+-		  &ioc->ioc_hpa->io_pdir_base);
++		  &ioc->ioc_regs->io_pdir_base);
+ 
+ 	/*
+ 	** Go to "Virtual Mode"
+ 	*/
+-	WRITE_U32(IOA_NORMAL_MODE, &ioc->ioc_hpa->io_control);
++	WRITE_U32(IOA_NORMAL_MODE, &ioc->ioc_regs->io_control);
+ 
+ 	/*
+ 	** Initialize all I/O TLB entries to 0 (Valid bit off).
+ 	*/
+-	WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_m);
+-	WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_l);
++	WRITE_U32(0, &ioc->ioc_regs->io_tlb_entry_m);
++	WRITE_U32(0, &ioc->ioc_regs->io_tlb_entry_l);
+ 
+ 	for(i = 1 << CCIO_CHAINID_SHIFT; i ; i--) {
+ 		WRITE_U32((CMD_TLB_DIRECT_WRITE | (i << ioc->chainid_shift)),
+-			  &ioc->ioc_hpa->io_command);
++			  &ioc->ioc_regs->io_command);
+ 	}
+ }
+ 
+ static void
+-ccio_init_resource(struct resource *res, char *name, unsigned long ioaddr)
++ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr)
+ {
+ 	int result;
+ 
+ 	res->parent = NULL;
+ 	res->flags = IORESOURCE_MEM;
+-	res->start = (unsigned long)(signed) __raw_readl(ioaddr) << 16;
+-	res->end = (unsigned long)(signed) (__raw_readl(ioaddr + 4) << 16) - 1;
++	/*
++	 * bracing ((signed) ...) are required for 64bit kernel because
++	 * we only want to sign extend the lower 16 bits of the register.
++	 * The upper 16-bits of range registers are hardcoded to 0xffff.
++	 */
++	res->start = (unsigned long)((signed) READ_U32(ioaddr) << 16);
++	res->end = (unsigned long)((signed) (READ_U32(ioaddr + 4) << 16) - 1);
+ 	res->name = name;
++	/*
++	 * Check if this MMIO range is disable
++	 */
+ 	if (res->end + 1 == res->start)
+ 		return;
+-	result = request_resource(&iomem_resource, res);
++
++	/* On some platforms (e.g. K-Class), we have already registered
++	 * resources for devices reported by firmware. Some are children
++	 * of ccio.
++	 * "insert" ccio ranges in the mmio hierarchy (/proc/iomem).
++	 */
++	result = insert_resource(&iomem_resource, res);
+ 	if (result < 0) {
+-		printk(KERN_ERR "%s: failed to claim CCIO bus address space (%08lx,%08lx)\n", 
+-		       __FILE__, res->start, res->end);
++		printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n", 
++	 		__FUNCTION__, res->start, res->end);
+ 	}
+ }
+ 
+@@ -1414,9 +1425,8 @@ static void __init ccio_init_resources(s
+ 
+ 	sprintf(name, "GSC Bus [%d/]", ioc->hw_path);
+ 
+-	ccio_init_resource(res, name, (unsigned long)&ioc->ioc_hpa->io_io_low);
+-	ccio_init_resource(res + 1, name,
+-			(unsigned long)&ioc->ioc_hpa->io_io_low_hv);
++	ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low);
++	ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv);
+ }
+ 
+ static int new_ioc_area(struct resource *res, unsigned long size,
+@@ -1427,7 +1437,12 @@ static int new_ioc_area(struct resource 
+ 
+ 	res->start = (max - size + 1) &~ (align - 1);
+ 	res->end = res->start + size;
+-	if (!request_resource(&iomem_resource, res))
++	
++	/* We might be trying to expand the MMIO range to include
++	 * a child device that has already registered it's MMIO space.
++	 * Use "insert" instead of request_resource().
++	 */
++	if (!insert_resource(&iomem_resource, res))
+ 		return 0;
+ 
+ 	return new_ioc_area(res, size, min, max - size, align);
+@@ -1486,15 +1501,15 @@ int ccio_allocate_resource(const struct 
+ 
+ 	if (!expand_ioc_area(parent, size, min, max, align)) {
+ 		__raw_writel(((parent->start)>>16) | 0xffff0000,
+-			     (unsigned long)&(ioc->ioc_hpa->io_io_low));
++			     &ioc->ioc_regs->io_io_low);
+ 		__raw_writel(((parent->end)>>16) | 0xffff0000,
+-			     (unsigned long)&(ioc->ioc_hpa->io_io_high));
++			     &ioc->ioc_regs->io_io_high);
+ 	} else if (!expand_ioc_area(parent + 1, size, min, max, align)) {
+ 		parent++;
+ 		__raw_writel(((parent->start)>>16) | 0xffff0000,
+-			     (unsigned long)&(ioc->ioc_hpa->io_io_low_hv));
++			     &ioc->ioc_regs->io_io_low_hv);
+ 		__raw_writel(((parent->end)>>16) | 0xffff0000,
+-			     (unsigned long)&(ioc->ioc_hpa->io_io_high_hv));
++			     &ioc->ioc_regs->io_io_high_hv);
+ 	} else {
+ 		return -EBUSY;
+ 	}
+@@ -1521,7 +1536,12 @@ int ccio_request_resource(const struct p
+ 		return -EBUSY;
+ 	}
+ 
+-	return request_resource(parent, res);
++	/* "transparent" bus bridges need to register MMIO resources
++	 * firmware assigned them. e.g. children of hppb.c (e.g. K-class)
++	 * registered their resources in the PDC "bus walk" (See
++	 * arch/parisc/kernel/inventory.c).
++	 */
++	return insert_resource(parent, res);
+ }
+ 
+ /**
+@@ -1546,7 +1566,7 @@ static int ccio_probe(struct parisc_devi
+ 
+ 	ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
+ 
+-	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
++	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start);
+ 
+ 	for (i = 0; i < ioc_count; i++) {
+ 		ioc_p = &(*ioc_p)->next;
+@@ -1554,7 +1574,7 @@ static int ccio_probe(struct parisc_devi
+ 	*ioc_p = ioc;
+ 
+ 	ioc->hw_path = dev->hw_path;
+-	ioc->ioc_hpa = (struct ioa_registers *)dev->hpa;
++	ioc->ioc_regs = ioremap(dev->hpa.start, 4096);
+ 	ccio_ioc_init(ioc);
+ 	ccio_init_resources(ioc);
+ 	hppa_dma_ops = &ccio_ops;
+diff --git a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
+--- a/drivers/parisc/ccio-rm-dma.c
++++ b/drivers/parisc/ccio-rm-dma.c
+@@ -167,7 +167,7 @@ ccio_probe(struct parisc_device *dev)
+ {
+ 	printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME,
+ 			dev->id.hversion == U2_BC_GSC ? "U2" : "UTurn",
+-			dev->hpa);
++			dev->hpa.start);
+ 
+ /*
+ ** FIXME - should check U2 registers to verify it's really running
+diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
+--- a/drivers/parisc/dino.c
++++ b/drivers/parisc/dino.c
+@@ -178,6 +178,8 @@ static int dino_cfg_read(struct pci_bus 
+ 	void __iomem *base_addr = d->hba.base_addr;
+ 	unsigned long flags;
+ 
++	DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where,
++									size);
+ 	spin_lock_irqsave(&d->dinosaur_pen, flags);
+ 
+ 	/* tell HW which CFG address */
+@@ -211,6 +213,8 @@ static int dino_cfg_write(struct pci_bus
+ 	void __iomem *base_addr = d->hba.base_addr;
+ 	unsigned long flags;
+ 
++	DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where,
++									size);
+ 	spin_lock_irqsave(&d->dinosaur_pen, flags);
+ 
+ 	/* avoid address stepping feature */
+@@ -295,7 +299,7 @@ static void dino_disable_irq(unsigned in
+ 	struct dino_device *dino_dev = irq_desc[irq].handler_data;
+ 	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
+ 
+-	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
++	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq);
+ 
+ 	/* Clear the matching bit in the IMR register */
+ 	dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq));
+@@ -308,7 +312,7 @@ static void dino_enable_irq(unsigned int
+ 	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
+ 	u32 tmp;
+ 
+-	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
++	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq);
+ 
+ 	/*
+ 	** clear pending IRQ bits
+@@ -490,7 +494,7 @@ dino_card_setup(struct pci_bus *bus, voi
+ 		if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB)))
+ 			break;
+ 	}
+-	DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %lx\n",
++	DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %p\n",
+ 	    i, res->start, base_addr + DINO_IO_ADDR_EN);
+ 	__raw_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
+ }
+@@ -683,6 +687,14 @@ static void __init
+ dino_card_init(struct dino_device *dino_dev)
+ {
+ 	u32 brdg_feat = 0x00784e05;
++	unsigned long status;
++
++	status = __raw_readl(dino_dev->hba.base_addr+DINO_IO_STATUS);
++	if (status & 0x0000ff80) {
++		__raw_writel(0x00000005,
++				dino_dev->hba.base_addr+DINO_IO_COMMAND);
++		udelay(1);
++	}
+ 
+ 	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK);
+ 	__raw_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN);
+@@ -902,15 +914,15 @@ void ccio_cujo20_fixup(struct parisc_dev
+ ** If so, initialize the chip appropriately (card-mode vs bridge mode).
+ ** Much of the initialization is common though.
+ */
+-static int __init
+-dino_driver_callback(struct parisc_device *dev)
++static int __init dino_probe(struct parisc_device *dev)
+ {
+ 	struct dino_device *dino_dev;	// Dino specific control struct
+ 	const char *version = "unknown";
+ 	char *name;
+ 	int is_cujo = 0;
+ 	struct pci_bus *bus;
+-	
++	unsigned long hpa = dev->hpa.start;
++
+ 	name = "Dino";
+ 	if (is_card_dino(&dev->id)) {
+ 		version = "3.x (card mode)";
+@@ -928,11 +940,11 @@ dino_driver_callback(struct parisc_devic
+ 		}
+ 	}
+ 
+-	printk("%s version %s found at 0x%lx\n", name, version, dev->hpa);
++	printk("%s version %s found at 0x%lx\n", name, version, hpa);
+ 
+-	if (!request_mem_region(dev->hpa, PAGE_SIZE, name)) {
++	if (!request_mem_region(hpa, PAGE_SIZE, name)) {
+ 		printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n",
+-			dev->hpa);
++			hpa);
+ 		return 1;
+ 	}
+ 
+@@ -940,12 +952,12 @@ dino_driver_callback(struct parisc_devic
+ 	if (is_cujo && dev->id.hversion_rev == 1) {
+ #ifdef CONFIG_IOMMU_CCIO
+ 		printk(KERN_WARNING "Enabling Cujo 2.0 bug workaround\n");
+-		if (dev->hpa == (unsigned long)CUJO_RAVEN_ADDR) {
++		if (hpa == (unsigned long)CUJO_RAVEN_ADDR) {
+ 			ccio_cujo20_fixup(dev, CUJO_RAVEN_BADPAGE);
+-		} else if (dev->hpa == (unsigned long)CUJO_FIREHAWK_ADDR) {
++		} else if (hpa == (unsigned long)CUJO_FIREHAWK_ADDR) {
+ 			ccio_cujo20_fixup(dev, CUJO_FIREHAWK_BADPAGE);
+ 		} else {
+-			printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", dev->hpa);
++			printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", hpa);
+ 		}
+ #endif
+ 	} else if (!is_cujo && !is_card_dino(&dev->id) &&
+@@ -970,7 +982,7 @@ dino_driver_callback(struct parisc_devic
+ 	memset(dino_dev, 0, sizeof(struct dino_device));
+ 
+ 	dino_dev->hba.dev = dev;
+-	dino_dev->hba.base_addr = ioremap(dev->hpa, 4096); /* faster access */
++	dino_dev->hba.base_addr = ioremap(hpa, 4096);
+ 	dino_dev->hba.lmmio_space_offset = 0;	/* CPU addrs == bus addrs */
+ 	spin_lock_init(&dino_dev->dinosaur_pen);
+ 	dino_dev->hba.iommu = ccio_get_iommu(dev);
+@@ -1027,9 +1039,9 @@ static struct parisc_device_id dino_tbl[
+ };
+ 
+ static struct parisc_driver dino_driver = {
+-	.name =		"Dino",
++	.name =		"dino",
+ 	.id_table =	dino_tbl,
+-	.probe =	dino_driver_callback,
++	.probe =	dino_probe,
+ };
+ 
+ /*
+diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
+--- a/drivers/parisc/eisa.c
++++ b/drivers/parisc/eisa.c
+@@ -315,7 +315,7 @@ static int __devinit eisa_probe(struct p
+ 	char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
+ 
+ 	printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", 
+-		name, dev->hpa);
++		name, dev->hpa.start);
+ 
+ 	eisa_dev.hba.dev = dev;
+ 	eisa_dev.hba.iommu = ccio_get_iommu(dev);
+@@ -397,7 +397,7 @@ static struct parisc_device_id eisa_tbl[
+ MODULE_DEVICE_TABLE(parisc, eisa_tbl);
+ 
+ static struct parisc_driver eisa_driver = {
+-	.name =		"EISA Bus Adapter",
++	.name =		"eisa_ba",
+ 	.id_table =	eisa_tbl,
+ 	.probe =	eisa_probe,
+ };
+diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
+--- a/drivers/parisc/gsc.c
++++ b/drivers/parisc/gsc.c
+@@ -183,12 +183,20 @@ void gsc_asic_assign_irq(struct gsc_asic
+ 	*irqp = irq;
+ }
+ 
++static struct device *next_device(struct klist_iter *i)
++{
++	struct klist_node * n = klist_next(i);
++	return n ? container_of(n, struct device, knode_parent) : NULL;
++}
++
+ void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
+ 			void (*choose_irq)(struct parisc_device *, void *))
+ {
+ 	struct device *dev;
++	struct klist_iter i;
+ 
+-	list_for_each_entry(dev, &parent->dev.children, node) {
++	klist_iter_init(&parent->dev.klist_children, &i);
++	while ((dev = next_device(&i))) {
+ 		struct parisc_device *padev = to_parisc_device(dev);
+ 
+ 		/* work-around for 715/64 and others which have parent 
+@@ -197,6 +205,7 @@ void gsc_fixup_irqs(struct parisc_device
+ 			return gsc_fixup_irqs(padev, ctrl, choose_irq);
+ 		choose_irq(padev, ctrl);
+ 	}
++	klist_iter_exit(&i);
+ }
+ 
+ int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)
+diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c
+--- a/drivers/parisc/hppb.c
++++ b/drivers/parisc/hppb.c
+@@ -68,14 +68,14 @@ static int hppb_probe(struct parisc_devi
+ 		memset(card->next, '\0', sizeof(struct hppb_card));
+ 		card = card->next;
+ 	}
+-        printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa);
++        printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start);
+ 
+-	card->hpa = dev->hpa;
++	card->hpa = dev->hpa.start;
+ 	card->mmio_region.name = "HP-PB Bus";
+ 	card->mmio_region.flags = IORESOURCE_MEM;
+ 
+-	card->mmio_region.start = __raw_readl(dev->hpa + IO_IO_LOW);
+-	card->mmio_region.end = __raw_readl(dev->hpa + IO_IO_HIGH) - 1;
++	card->mmio_region.start = gsc_readl(dev->hpa.start + IO_IO_LOW);
++	card->mmio_region.end = gsc_readl(dev->hpa.start + IO_IO_HIGH) - 1;
+ 
+ 	status = ccio_request_resource(dev, &card->mmio_region);
+ 	if(status < 0) {
+@@ -93,7 +93,7 @@ static struct parisc_device_id hppb_tbl[
+ };
+ 
+ static struct parisc_driver hppb_driver = {
+-        .name =         "Gecko Boa",
++        .name =         "gecko_boa",
+         .id_table =     hppb_tbl,
+ 	.probe =        hppb_probe,
+ };
+diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
+--- a/drivers/parisc/iosapic.c
++++ b/drivers/parisc/iosapic.c
+@@ -244,7 +244,7 @@ static struct irt_entry *iosapic_alloc_i
+ 	 * 4-byte alignment on 32-bit kernels
+ 	 */
+ 	a = (unsigned long)kmalloc(sizeof(struct irt_entry) * num_entries + 8, GFP_KERNEL);
+-	a = (a + 7) & ~7;
++	a = (a + 7UL) & ~7UL;
+ 	return (struct irt_entry *)a;
+ }
+ 
+diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
+--- a/drivers/parisc/lasi.c
++++ b/drivers/parisc/lasi.c
+@@ -175,7 +175,7 @@ lasi_init_chip(struct parisc_device *dev
+ 		return -ENOMEM;
+ 
+ 	lasi->name = "Lasi";
+-	lasi->hpa = dev->hpa;
++	lasi->hpa = dev->hpa.start;
+ 
+ 	/* Check the 4-bit (yes, only 4) version register */
+ 	lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf;
+@@ -233,7 +233,7 @@ static struct parisc_device_id lasi_tbl[
+ };
+ 
+ struct parisc_driver lasi_driver = {
+-	.name =		"Lasi",
++	.name =		"lasi",
+ 	.id_table =	lasi_tbl,
+ 	.probe =	lasi_init_chip,
+ };
+diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
+--- a/drivers/parisc/lba_pci.c
++++ b/drivers/parisc/lba_pci.c
+@@ -1288,7 +1288,7 @@ lba_legacy_resources(struct parisc_devic
+ 		** Adjust "window" for this rope.
+ 		*/
+ 		rsize /= ROPES_PER_IOC;
+-		r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa);
++		r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa.start);
+ 		r->end = r->start + rsize;
+ 	} else {
+ 		r->end = r->start = 0;	/* Not enabled. */
+@@ -1458,7 +1458,7 @@ lba_driver_probe(struct parisc_device *d
+ 	u32 func_class;
+ 	void *tmp_obj;
+ 	char *version;
+-	void __iomem *addr = ioremap(dev->hpa, 4096);
++	void __iomem *addr = ioremap(dev->hpa.start, 4096);
+ 
+ 	/* Read HW Rev First */
+ 	func_class = READ_REG32(addr + LBA_FCLASS);
+@@ -1476,7 +1476,7 @@ lba_driver_probe(struct parisc_device *d
+ 		}
+ 
+ 		printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+-			MODULE_NAME, version, func_class & 0xf, dev->hpa);
++			MODULE_NAME, version, func_class & 0xf, dev->hpa.start);
+ 
+ 		if (func_class < 2) {
+ 			printk(KERN_WARNING "Can't support LBA older than "
+@@ -1503,17 +1503,17 @@ lba_driver_probe(struct parisc_device *d
+                  * but for the mask for func_class.
+                  */ 
+ 		printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+-			MODULE_NAME, version, func_class & 0xff, dev->hpa);
++		       MODULE_NAME, version, func_class & 0xff, dev->hpa.start);
+ 		cfg_ops = &mercury_cfg_ops;
+ 	} else {
+-		printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa);
++		printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start);
+ 		return -ENODEV;
+ 	}
+ 
+ 	/*
+ 	** Tell I/O SAPIC driver we have a IRQ handler/region.
+ 	*/
+-	tmp_obj = iosapic_register(dev->hpa + LBA_IOSAPIC_BASE);
++	tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE);
+ 
+ 	/* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't
+ 	**	have an IRT entry will get NULL back from iosapic code.
+@@ -1635,7 +1635,7 @@ void __init lba_init(void)
+ */
+ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
+ {
+-	void __iomem * base_addr = ioremap(lba->hpa, 4096);
++	void __iomem * base_addr = ioremap(lba->hpa.start, 4096);
+ 
+ 	imask <<= 2;	/* adjust for hints - 2 more bits */
+ 
+diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
+--- a/drivers/parisc/led.c
++++ b/drivers/parisc/led.c
+@@ -18,6 +18,9 @@
+  * Changes:
+  *      - Audit copy_from_user in led_proc_write.
+  *                                Daniele Bellucci <bellucda at tiscali.it>
++ *	- Switch from using a tasklet to a work queue, so the led_LCD_driver
++ *	  	can sleep.
++ *	  			  David Pye <dmp at davidmpye.dyndns.org>
+  */
+ 
+ #include <linux/config.h>
+@@ -37,6 +40,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/ctype.h>
+ #include <linux/blkdev.h>
++#include <linux/workqueue.h>
+ #include <linux/rcupdate.h>
+ #include <asm/io.h>
+ #include <asm/processor.h>
+@@ -47,25 +51,30 @@
+ #include <asm/uaccess.h>
+ 
+ /* The control of the LEDs and LCDs on PARISC-machines have to be done 
+-   completely in software. The necessary calculations are done in a tasklet
+-   which is scheduled at every timer interrupt and since the calculations 
+-   may consume relatively much CPU-time some of the calculations can be 
++   completely in software. The necessary calculations are done in a work queue
++   task which is scheduled regularly, and since the calculations may consume a 
++   relatively large amount of CPU time, some of the calculations can be 
+    turned off with the following variables (controlled via procfs) */
+ 
+ static int led_type = -1;
+-static int led_heartbeat = 1;
+-static int led_diskio = 1;
+-static int led_lanrxtx = 1;
++static unsigned char lastleds;	/* LED state from most recent update */
++static unsigned int led_heartbeat = 1;
++static unsigned int led_diskio = 1;
++static unsigned int led_lanrxtx = 1;
+ static char lcd_text[32];
+ static char lcd_text_default[32];
+ 
++
++static struct workqueue_struct *led_wq;
++static void led_work_func(void *);
++static DECLARE_WORK(led_task, led_work_func, NULL);
++
+ #if 0
+ #define DPRINTK(x)	printk x
+ #else
+ #define DPRINTK(x)
+ #endif
+ 
+-
+ struct lcd_block {
+ 	unsigned char command;	/* stores the command byte      */
+ 	unsigned char on;	/* value for turning LED on     */
+@@ -116,12 +125,27 @@ lcd_info __attribute__((aligned(8))) =
+ #define LCD_DATA_REG	lcd_info.lcd_data_reg_addr	 
+ #define LED_DATA_REG	lcd_info.lcd_cmd_reg_addr	/* LASI & ASP only */
+ 
++#define LED_HASLCD 1
++#define LED_NOLCD  0
++
++/* The workqueue must be created at init-time */
++static int start_task(void) 
++{	
++	/* Display the default text now */
++	if (led_type == LED_HASLCD) lcd_print( lcd_text_default );
++
++	/* Create the work queue and queue the LED task */
++	led_wq = create_singlethread_workqueue("led_wq");	
++	queue_work(led_wq, &led_task);
++
++	return 0;
++}
++
++device_initcall(start_task);
+ 
+ /* ptr to LCD/LED-specific function */
+ static void (*led_func_ptr) (unsigned char);
+ 
+-#define LED_HASLCD 1
+-#define LED_NOLCD  0
+ #ifdef CONFIG_PROC_FS
+ static int led_proc_read(char *page, char **start, off_t off, int count, 
+ 	int *eof, void *data)
+@@ -286,52 +310,35 @@ static void led_LASI_driver(unsigned cha
+ /*
+    ** 
+    ** led_LCD_driver()
+-   ** 
+-   ** The logic of the LCD driver is, that we write at every scheduled call
+-   ** only to one of LCD_CMD_REG _or_ LCD_DATA_REG - registers.
+-   ** That way we don't need to let this tasklet busywait for min_cmd_delay
+-   ** milliseconds.
+-   **
+-   ** TODO: check the value of "min_cmd_delay" against the value of HZ.
+    **   
+  */
+ static void led_LCD_driver(unsigned char leds)
+ {
+-	static int last_index;	/* 0:heartbeat, 1:disk, 2:lan_in, 3:lan_out */
+-	static int last_was_cmd;/* 0: CMD was written last, 1: DATA was last */
+-	struct lcd_block *block_ptr;
+-	int value;
+-
+-	switch (last_index) {
+-	    case 0:	block_ptr = &lcd_info.heartbeat;
+-			value = leds & LED_HEARTBEAT;
+-			break;
+-	    case 1:	block_ptr = &lcd_info.disk_io;
+-			value = leds & LED_DISK_IO;
+-			break;					
+-	    case 2:	block_ptr = &lcd_info.lan_rcv;
+-			value = leds & LED_LAN_RCV;
+-			break;					
+-	    case 3:	block_ptr = &lcd_info.lan_tx;
+-			value = leds & LED_LAN_TX;
+-			break;
+-	    default:	/* should never happen: */
+-			return;
+-	}
++	static int i;
++	static unsigned char mask[4] = { LED_HEARTBEAT, LED_DISK_IO,
++		LED_LAN_RCV, LED_LAN_TX };
++	
++	static struct lcd_block * blockp[4] = {
++		&lcd_info.heartbeat,
++		&lcd_info.disk_io,
++		&lcd_info.lan_rcv,
++		&lcd_info.lan_tx
++	};
+ 
+-	if (last_was_cmd) {
+-	    /* write the value to the LCD data port */
+-    	    gsc_writeb( value ? block_ptr->on : block_ptr->off, LCD_DATA_REG );
+-	} else {
+-	    /* write the command-byte to the LCD command register */
+-    	    gsc_writeb( block_ptr->command, LCD_CMD_REG );
+-	}    
+-	
+-	/* now update the vars for the next interrupt iteration */ 
+-	if (++last_was_cmd == 2) { /* switch between cmd & data */
+-	    last_was_cmd = 0;
+-	    if (++last_index == 4) 
+-		last_index = 0;	 /* switch back to heartbeat index */
++	/* Convert min_cmd_delay to milliseconds */
++	unsigned int msec_cmd_delay = 1 + (lcd_info.min_cmd_delay / 1000);
++	
++	for (i=0; i<4; ++i) 
++	{
++		if ((leds & mask[i]) != (lastleds & mask[i])) 
++		{
++			gsc_writeb( blockp[i]->command, LCD_CMD_REG );
++			msleep(msec_cmd_delay);
++			
++			gsc_writeb( leds & mask[i] ? blockp[i]->on : 
++					blockp[i]->off, LCD_DATA_REG );
++			msleep(msec_cmd_delay);
++		}
+ 	}
+ }
+ 
+@@ -356,7 +363,7 @@ static __inline__ int led_get_net_activi
+ 
+ 	rx_total = tx_total = 0;
+ 	
+-	/* we are running as tasklet, so locking dev_base 
++	/* we are running as a workqueue task, so locking dev_base 
+ 	 * for reading should be OK */
+ 	read_lock(&dev_base_lock);
+ 	rcu_read_lock();
+@@ -405,7 +412,7 @@ static __inline__ int led_get_diskio_act
+ 	static unsigned long last_pgpgin, last_pgpgout;
+ 	struct page_state pgstat;
+ 	int changed;
+-	
++
+ 	get_full_page_state(&pgstat); /* get no of sectors in & out */
+ 
+ 	/* Just use a very simple calculation here. Do not care about overflow,
+@@ -413,86 +420,70 @@ static __inline__ int led_get_diskio_act
+ 	changed = (pgstat.pgpgin != last_pgpgin) || (pgstat.pgpgout != last_pgpgout);
+ 	last_pgpgin  = pgstat.pgpgin;
+ 	last_pgpgout = pgstat.pgpgout;
+-	
++
+ 	return (changed ? LED_DISK_IO : 0);
+ }
+ 
+ 
+ 
+ /*
+-   ** led_tasklet_func()
++   ** led_work_func()
+    ** 
+-   ** is scheduled at every timer interrupt from time.c and
+-   ** updates the chassis LCD/LED 
++   ** manages when and which chassis LCD/LED gets updated
+ 
+     TODO:
+     - display load average (older machines like 715/64 have 4 "free" LED's for that)
+     - optimizations
+  */
+ 
+-#define HEARTBEAT_LEN (HZ*6/100)
+-#define HEARTBEAT_2ND_RANGE_START (HZ*22/100)
++#define HEARTBEAT_LEN (HZ*10/100)
++#define HEARTBEAT_2ND_RANGE_START (HZ*28/100)
+ #define HEARTBEAT_2ND_RANGE_END   (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN)
+ 
+-#define NORMALIZED_COUNT(count) (count/(HZ/100))
++#define LED_UPDATE_INTERVAL (1 + (HZ*19/1000))
+ 
+-static void led_tasklet_func(unsigned long unused)
++static void led_work_func (void *unused)
+ {
+-	static unsigned char lastleds;
+-	unsigned char currentleds; /* stores current value of the LEDs */
+-	static unsigned long count; /* static incremented value, not wrapped */
++	static unsigned long last_jiffies;
+ 	static unsigned long count_HZ; /* counter in range 0..HZ */
++	unsigned char currentleds = 0; /* stores current value of the LEDs */
+ 
+ 	/* exit if not initialized */
+ 	if (!led_func_ptr)
+ 	    return;
+ 
+-	/* increment the local counters */
+-	++count;
+-	if (++count_HZ == HZ)
++	/* increment the heartbeat timekeeper */
++	count_HZ += jiffies - last_jiffies;
++	last_jiffies = jiffies;
++	if (count_HZ >= HZ)
+ 	    count_HZ = 0;
+ 
+-	currentleds = lastleds;
+-
+-	if (led_heartbeat)
+-	{
+-		/* flash heartbeat-LED like a real heart (2 x short then a long delay) */
+-		if (count_HZ<HEARTBEAT_LEN || 
+-		    (count_HZ>=HEARTBEAT_2ND_RANGE_START && count_HZ<HEARTBEAT_2ND_RANGE_END)) 
+-		    currentleds |= LED_HEARTBEAT;
+-		else
+-		    currentleds &= ~LED_HEARTBEAT;
+-	}
+-
+-	/* look for network activity and flash LEDs respectively */
+-	if (led_lanrxtx && ((NORMALIZED_COUNT(count)+(8/2)) & 7) == 0)
++	if (likely(led_heartbeat))
+ 	{
+-		currentleds &= ~(LED_LAN_RCV | LED_LAN_TX);
+-		currentleds |= led_get_net_activity();
++		/* flash heartbeat-LED like a real heart
++		 * (2 x short then a long delay)
++		 */
++		if (count_HZ < HEARTBEAT_LEN || 
++				(count_HZ >= HEARTBEAT_2ND_RANGE_START &&
++				count_HZ < HEARTBEAT_2ND_RANGE_END)) 
++			currentleds |= LED_HEARTBEAT;
+ 	}
+ 
+-	/* avoid to calculate diskio-stats at same irq  as netio-stats */
+-	if (led_diskio && (NORMALIZED_COUNT(count) & 7) == 0)
+-	{
+-		currentleds &= ~LED_DISK_IO;
+-		currentleds |= led_get_diskio_activity();
+-	}
++	if (likely(led_lanrxtx))  currentleds |= led_get_net_activity();
++	if (likely(led_diskio))   currentleds |= led_get_diskio_activity();
+ 
+ 	/* blink all LEDs twice a second if we got an Oops (HPMC) */
+-	if (oops_in_progress) {
++	if (unlikely(oops_in_progress)) 
+ 		currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff;
+-	}
+-	
+-	/* update the LCD/LEDs */
+-	if (currentleds != lastleds) {
+-	    led_func_ptr(currentleds);
+-	    lastleds = currentleds;
+-	}
+-}
+ 
+-/* main led tasklet struct (scheduled from time.c) */
+-DECLARE_TASKLET_DISABLED(led_tasklet, led_tasklet_func, 0);
++	if (currentleds != lastleds)
++	{
++		led_func_ptr(currentleds);	/* Update the LCD/LEDs */
++		lastleds = currentleds;
++	}
+ 
++	queue_delayed_work(led_wq, &led_task, LED_UPDATE_INTERVAL);
++}
+ 
+ /*
+    ** led_halt()
+@@ -522,9 +513,13 @@ static int led_halt(struct notifier_bloc
+ 	default:		return NOTIFY_DONE;
+ 	}
+ 	
+-	/* completely stop the LED/LCD tasklet */
+-	tasklet_disable(&led_tasklet);
+-
++	/* Cancel the work item and delete the queue */
++	if (led_wq) {
++		cancel_rearming_delayed_workqueue(led_wq, &led_task);
++		destroy_workqueue(led_wq);
++		led_wq = NULL;
++	}
++ 
+ 	if (lcd_info.model == DISPLAY_MODEL_LCD)
+ 		lcd_print(txt);
+ 	else
+@@ -559,7 +554,6 @@ int __init register_led_driver(int model
+ 		printk(KERN_INFO "LCD display at %lx,%lx registered\n", 
+ 			LCD_CMD_REG , LCD_DATA_REG);
+ 		led_func_ptr = led_LCD_driver;
+-		lcd_print( lcd_text_default );
+ 		led_type = LED_HASLCD;
+ 		break;
+ 
+@@ -589,9 +583,11 @@ int __init register_led_driver(int model
+ 	initialized++;
+ 	register_reboot_notifier(&led_notifier);
+ 
+-	/* start the led tasklet for the first time */
+-	tasklet_enable(&led_tasklet);
+-	
++	/* Ensure the work is queued */
++	if (led_wq) {
++		queue_work(led_wq, &led_task);
++	}
++
+ 	return 0;
+ }
+ 
+@@ -626,8 +622,8 @@ void __init register_led_regions(void)
+    ** lcd_print()
+    ** 
+    ** Displays the given string on the LCD-Display of newer machines.
+-   ** lcd_print() disables the timer-based led tasklet during its 
+-   ** execution and enables it afterwards again.
++   ** lcd_print() disables/enables the timer-based led work queue to
++   ** avoid a race condition while writing the CMD/DATA register pair.
+    **
+  */
+ int lcd_print( char *str )
+@@ -637,12 +633,13 @@ int lcd_print( char *str )
+ 	if (!led_func_ptr || lcd_info.model != DISPLAY_MODEL_LCD)
+ 	    return 0;
+ 	
+-	/* temporarily disable the led tasklet */
+-	tasklet_disable(&led_tasklet);
++	/* temporarily disable the led work task */
++	if (led_wq)
++		cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ 
+ 	/* copy display string to buffer for procfs */
+ 	strlcpy(lcd_text, str, sizeof(lcd_text));
+-	
++
+ 	/* Set LCD Cursor to 1st character */
+ 	gsc_writeb(lcd_info.reset_cmd1, LCD_CMD_REG);
+ 	udelay(lcd_info.min_cmd_delay);
+@@ -656,8 +653,10 @@ int lcd_print( char *str )
+ 	    udelay(lcd_info.min_cmd_delay);
+ 	}
+ 	
+-	/* re-enable the led tasklet */
+-	tasklet_enable(&led_tasklet);
++	/* re-queue the work */
++	if (led_wq) {
++		queue_work(led_wq, &led_task);
++	}
+ 
+ 	return lcd_info.lcd_width;
+ }
+diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
+--- a/drivers/parisc/pdc_stable.c
++++ b/drivers/parisc/pdc_stable.c
+@@ -536,7 +536,7 @@ pdcs_info_read(struct subsystem *entry, 
+ 
+ 	out += sprintf(out, "Memory tested: ");
+ 	if ((result & 0x0F) < 0x0E)
+-		out += sprintf(out, "%.3f MB", 0.256*(1<<(result & 0x0F)));
++		out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256);
+ 	else
+ 		out += sprintf(out, "All");
+ 	out += sprintf(out, "\n");
+diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
+--- a/drivers/parisc/sba_iommu.c
++++ b/drivers/parisc/sba_iommu.c
+@@ -91,8 +91,8 @@ extern struct proc_dir_entry * proc_mcki
+ #define DBG_RES(x...)
+ #endif
+ 
+-#if defined(__LP64__) && !defined(CONFIG_PDC_NARROW)
+-/* "low end" PA8800 machines use ZX1 chipset */
++#if defined(CONFIG_64BIT)
++/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
+ #define ZX1_SUPPORT
+ #endif
+ 
+@@ -231,7 +231,7 @@ struct ioc {
+ 	spinlock_t	res_lock;
+ 	unsigned int	res_bitshift;	/* from the LEFT! */
+ 	unsigned int	res_size;	/* size of resource map in bytes */
+-#if SBA_HINT_SUPPORT
++#ifdef SBA_HINT_SUPPORT
+ /* FIXME : DMA HINTs not used */
+ 	unsigned long	hint_mask_pdir;	/* bits used for DMA hints */
+ 	unsigned int	hint_shift_pdir;
+@@ -294,7 +294,7 @@ static unsigned long piranha_bad_128k = 
+ /* Looks nice and keeps the compiler happy */
+ #define SBA_DEV(d) ((struct sba_device *) (d))
+ 
+-#if SBA_AGP_SUPPORT
++#ifdef SBA_AGP_SUPPORT
+ static int reserve_sba_gart = 1;
+ #endif
+ 
+@@ -314,7 +314,7 @@ static int reserve_sba_gart = 1;
+ #define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr)
+ #define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr)
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ #define READ_REG(addr)		READ_REG64(addr)
+ #define WRITE_REG(value, addr)	WRITE_REG64(value, addr)
+ #else
+@@ -324,7 +324,7 @@ static int reserve_sba_gart = 1;
+ 
+ #ifdef DEBUG_SBA_INIT
+ 
+-/* NOTE: When __LP64__ isn't defined, READ_REG64() is two 32-bit reads */
++/* NOTE: When CONFIG_64BIT isn't defined, READ_REG64() is two 32-bit reads */
+ 
+ /**
+  * sba_dump_ranges - debugging only - print ranges assigned to this IOA
+@@ -364,7 +364,7 @@ static void sba_dump_tlb(void __iomem *h
+ #else
+ #define sba_dump_ranges(x)
+ #define sba_dump_tlb(x)
+-#endif
++#endif	/* DEBUG_SBA_INIT */
+ 
+ 
+ #ifdef ASSERT_PDIR_SANITY
+@@ -674,7 +674,7 @@ sba_free_range(struct ioc *ioc, dma_addr
+ *
+ ***************************************************************/
+ 
+-#if SBA_HINT_SUPPORT
++#ifdef SBA_HINT_SUPPORT
+ #define SBA_DMA_HINT(ioc, val) ((val) << (ioc)->hint_shift_pdir)
+ #endif
+ 
+@@ -743,9 +743,8 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t
+ 	 * (bit #61, big endian), we have to flush and sync every time
+ 	 * IO-PDIR is changed in Ike/Astro.
+ 	 */
+-	if (ioc_needs_fdc) {
+-		asm volatile("fdc 0(%%sr1,%0)\n\tsync" : : "r" (pdir_ptr));
+-	}
++	if (ioc_needs_fdc)
++		asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr));
+ }
+ 
+ 
+@@ -769,42 +768,57 @@ static SBA_INLINE void
+ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
+ {
+ 	u32 iovp = (u32) SBA_IOVP(ioc,iova);
+-
+-	/* Even though this is a big-endian machine, the entries
+-	** in the iopdir are little endian. That's why we clear the byte
+-	** at +7 instead of at +0.
+-	*/
+-	int off = PDIR_INDEX(iovp)*sizeof(u64)+7;
++	u64 *pdir_ptr = &ioc->pdir_base[PDIR_INDEX(iovp)];
+ 
+ #ifdef ASSERT_PDIR_SANITY
+-	/* Assert first pdir entry is set */
+-	if (0x80 != (((u8 *) ioc->pdir_base)[off])) {
++	/* Assert first pdir entry is set.
++	**
++	** Even though this is a big-endian machine, the entries
++	** in the iopdir are little endian. That's why we look at
++	** the byte at +7 instead of at +0.
++	*/
++	if (0x80 != (((u8 *) pdir_ptr)[7])) {
+ 		sba_dump_pdir_entry(ioc,"sba_mark_invalid()", PDIR_INDEX(iovp));
+ 	}
+ #endif
+ 
+-	if (byte_cnt <= IOVP_SIZE)
++	if (byte_cnt > IOVP_SIZE)
+ 	{
+-		iovp |= IOVP_SHIFT;     /* set "size" field for PCOM */
++#if 0
++		unsigned long entries_per_cacheline = ioc_needs_fdc ?
++				L1_CACHE_ALIGN(((unsigned long) pdir_ptr))
++					- (unsigned long) pdir_ptr;
++				: 262144;
++#endif
+ 
+-		/*
+-		** clear I/O PDIR entry "valid" bit
+-		** Do NOT clear the rest - save it for debugging.
+-		** We should only clear bits that have previously
+-		** been enabled.
+-		*/
+-		((u8 *)(ioc->pdir_base))[off] = 0;
+-	} else {
+-		u32 t = get_order(byte_cnt) + PAGE_SHIFT;
++		/* set "size" field for PCOM */
++		iovp |= get_order(byte_cnt) + PAGE_SHIFT;
+ 
+-		iovp |= t;
+ 		do {
+ 			/* clear I/O Pdir entry "valid" bit first */
+-			((u8 *)(ioc->pdir_base))[off] = 0;
+-			off += sizeof(u64);
++			((u8 *) pdir_ptr)[7] = 0;
++			if (ioc_needs_fdc) {
++				asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr));
++#if 0
++				entries_per_cacheline = L1_CACHE_SHIFT - 3;
++#endif
++			}
++			pdir_ptr++;
+ 			byte_cnt -= IOVP_SIZE;
+-		} while (byte_cnt > 0);
+-	}
++		} while (byte_cnt > IOVP_SIZE);
++	} else
++		iovp |= IOVP_SHIFT;     /* set "size" field for PCOM */
++
++	/*
++	** clear I/O PDIR entry "valid" bit.
++	** We have to R/M/W the cacheline regardless how much of the
++	** pdir entry that we clobber.
++	** The rest of the entry would be useful for debugging if we
++	** could dump core on HPMC.
++	*/
++	((u8 *) pdir_ptr)[7] = 0;
++	if (ioc_needs_fdc)
++		asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr));
+ 
+ 	WRITE_REG( SBA_IOVA(ioc, iovp, 0, 0), ioc->ioc_hpa+IOC_PCOM);
+ }
+@@ -819,18 +833,29 @@ sba_mark_invalid(struct ioc *ioc, dma_ad
+ static int sba_dma_supported( struct device *dev, u64 mask)
+ {
+ 	struct ioc *ioc;
++
+ 	if (dev == NULL) {
+ 		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
+ 		BUG();
+ 		return(0);
+ 	}
+ 
+-	ioc = GET_IOC(dev);
++	/* Documentation/DMA-mapping.txt tells drivers to try 64-bit first,
++	 * then fall back to 32-bit if that fails.
++	 * We are just "encouraging" 32-bit DMA masks here since we can
++	 * never allow IOMMU bypass unless we add special support for ZX1.
++	 */
++	if (mask > ~0U)
++		return 0;
+ 
+-	/* check if mask is > than the largest IO Virt Address */
++	ioc = GET_IOC(dev);
+ 
+-	return((int) (mask >= (ioc->ibase +
+-				(ioc->pdir_size / sizeof(u64) * IOVP_SIZE) )));
++	/*
++	 * check if mask is >= than the current max IO Virt Address
++	 * The max IO Virt address will *always* < 30 bits.
++	 */
++	return((int)(mask >= (ioc->ibase - 1 +
++			(ioc->pdir_size / sizeof(u64) * IOVP_SIZE) )));
+ }
+ 
+ 
+@@ -898,11 +923,17 @@ sba_map_single(struct device *dev, void 
+ 		size -= IOVP_SIZE;
+ 		pdir_start++;
+ 	}
+-	/* form complete address */
++
++	/* force FDC ops in io_pdir_entry() to be visible to IOMMU */
++	if (ioc_needs_fdc)
++		asm volatile("sync" : : );
++
+ #ifdef ASSERT_PDIR_SANITY
+ 	sba_check_pdir(ioc,"Check after sba_map_single()");
+ #endif
+ 	spin_unlock_irqrestore(&ioc->res_lock, flags);
++
++	/* form complete address */
+ 	return SBA_IOVA(ioc, iovp, offset, DEFAULT_DMA_HINT_REG);
+ }
+ 
+@@ -958,12 +989,19 @@ sba_unmap_single(struct device *dev, dma
+ 			d--;
+ 		}
+ 		ioc->saved_cnt = 0;
++
+ 		READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
+ 	}
+ #else /* DELAYED_RESOURCE_CNT == 0 */
+ 	sba_free_range(ioc, iova, size);
++
++	/* If fdc's were issued, force fdc's to be visible now */
++	if (ioc_needs_fdc)
++		asm volatile("sync" : : );
++
+ 	READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
+ #endif /* DELAYED_RESOURCE_CNT == 0 */
++
+ 	spin_unlock_irqrestore(&ioc->res_lock, flags);
+ 
+ 	/* XXX REVISIT for 2.5 Linux - need syncdma for zero-copy support.
+@@ -986,7 +1024,7 @@ sba_unmap_single(struct device *dev, dma
+  * See Documentation/DMA-mapping.txt
+  */
+ static void *sba_alloc_consistent(struct device *hwdev, size_t size,
+-					dma_addr_t *dma_handle, int gfp)
++					dma_addr_t *dma_handle, gfp_t gfp)
+ {
+ 	void *ret;
+ 
+@@ -1106,6 +1144,10 @@ sba_map_sg(struct device *dev, struct sc
+ 	*/
+ 	filled = iommu_fill_pdir(ioc, sglist, nents, 0, sba_io_pdir_entry);
+ 
++	/* force FDC ops in io_pdir_entry() to be visible to IOMMU */
++	if (ioc_needs_fdc)
++		asm volatile("sync" : : );
++
+ #ifdef ASSERT_PDIR_SANITY
+ 	if (sba_check_pdir(ioc,"Check after sba_map_sg()"))
+ 	{
+@@ -1234,8 +1276,10 @@ sba_alloc_pdir(unsigned int pdir_size)
+ 	unsigned long pdir_order = get_order(pdir_size);
+ 
+ 	pdir_base = __get_free_pages(GFP_KERNEL, pdir_order);
+-	if (NULL == (void *) pdir_base)
+-		panic("sba_ioc_init() could not allocate I/O Page Table\n");
++	if (NULL == (void *) pdir_base)	{
++		panic("%s() could not allocate I/O Page Table\n",
++			__FUNCTION__);
++	}
+ 
+ 	/* If this is not PA8700 (PCX-W2)
+ 	**	OR newer than ver 2.2
+@@ -1322,19 +1366,29 @@ sba_alloc_pdir(unsigned int pdir_size)
+ 	return (void *) pdir_base;
+ }
+ 
++static struct device *next_device(struct klist_iter *i)
++{
++        struct klist_node * n = klist_next(i);
++        return n ? container_of(n, struct device, knode_parent) : NULL;
++}
++
+ /* setup Mercury or Elroy IBASE/IMASK registers. */
+-static void setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
++static void 
++setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
+ {
+-        /* lba_set_iregs() is in drivers/parisc/lba_pci.c */
++	/* lba_set_iregs() is in drivers/parisc/lba_pci.c */
+         extern void lba_set_iregs(struct parisc_device *, u32, u32);
+ 	struct device *dev;
++	struct klist_iter i;
+ 
+-	list_for_each_entry(dev, &sba->dev.children, node) {
++	klist_iter_init(&sba->dev.klist_children, &i);
++	while ((dev = next_device(&i))) {
+ 		struct parisc_device *lba = to_parisc_device(dev);
+-		int rope_num = (lba->hpa >> 13) & 0xf;
++		int rope_num = (lba->hpa.start >> 13) & 0xf;
+ 		if (rope_num >> 3 == ioc_num)
+ 			lba_set_iregs(lba, ioc->ibase, ioc->imask);
+ 	}
++	klist_iter_exit(&i);
+ }
+ 
+ static void
+@@ -1343,7 +1397,7 @@ sba_ioc_init_pluto(struct parisc_device 
+ 	u32 iova_space_mask;
+ 	u32 iova_space_size;
+ 	int iov_order, tcnfg;
+-#if SBA_AGP_SUPPORT
++#ifdef SBA_AGP_SUPPORT
+ 	int agp_found = 0;
+ #endif
+ 	/*
+@@ -1380,7 +1434,7 @@ sba_ioc_init_pluto(struct parisc_device 
+ 	DBG_INIT("%s() pdir %p size %x\n",
+ 			__FUNCTION__, ioc->pdir_base, ioc->pdir_size);
+ 
+-#if SBA_HINT_SUPPORT
++#ifdef SBA_HINT_SUPPORT
+ 	ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
+ 	ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
+ 
+@@ -1404,7 +1458,7 @@ sba_ioc_init_pluto(struct parisc_device 
+ 
+ 	WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK);
+ 
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ 	/*
+ 	** Setting the upper bits makes checking for bypass addresses
+ 	** a little faster later on.
+@@ -1437,7 +1491,7 @@ sba_ioc_init_pluto(struct parisc_device 
+ 	*/
+ 	WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);
+ 
+-#if SBA_AGP_SUPPORT
++#ifdef SBA_AGP_SUPPORT
+ 	/*
+ 	** If an AGP device is present, only use half of the IOV space
+ 	** for PCI DMA.  Unfortunately we can't know ahead of time
+@@ -1489,11 +1543,9 @@ sba_ioc_init(struct parisc_device *sba, 
+ 	if (iova_space_size < (1 << (20 - PAGE_SHIFT))) {
+ 		iova_space_size = 1 << (20 - PAGE_SHIFT);
+ 	}
+-#ifdef __LP64__
+ 	else if (iova_space_size > (1 << (30 - PAGE_SHIFT))) {
+ 		iova_space_size = 1 << (30 - PAGE_SHIFT);
+ 	}
+-#endif
+ 
+ 	/*
+ 	** iova space must be log2() in size.
+@@ -1519,7 +1571,7 @@ sba_ioc_init(struct parisc_device *sba, 
+ 	DBG_INIT("%s() pdir %p size %x\n",
+ 			__FUNCTION__, ioc->pdir_base, pdir_size);
+ 
+-#if SBA_HINT_SUPPORT
++#ifdef SBA_HINT_SUPPORT
+ 	/* FIXME : DMA HINTs not used */
+ 	ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
+ 	ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
+@@ -1590,7 +1642,7 @@ sba_ioc_init(struct parisc_device *sba, 
+ 
+ static void __iomem *ioc_remap(struct sba_device *sba_dev, int offset)
+ {
+-	return ioremap(sba_dev->dev->hpa + offset, SBA_FUNC_SIZE);
++	return ioremap(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE);
+ }
+ 
+ static void sba_hw_init(struct sba_device *sba_dev)
+@@ -1968,7 +2020,7 @@ sba_driver_callback(struct parisc_device
+ 	u32 func_class;
+ 	int i;
+ 	char *version;
+-	void __iomem *sba_addr = ioremap(dev->hpa, SBA_FUNC_SIZE);
++	void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE);
+ 
+ 	sba_dump_ranges(sba_addr);
+ 
+@@ -2010,7 +2062,7 @@ sba_driver_callback(struct parisc_device
+ 	}
+ 
+ 	printk(KERN_INFO "%s found %s at 0x%lx\n",
+-		MODULE_NAME, version, dev->hpa);
++		MODULE_NAME, version, dev->hpa.start);
+ 
+ 	sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL);
+ 	if (!sba_dev) {
+diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
+--- a/drivers/parisc/superio.c
++++ b/drivers/parisc/superio.c
+@@ -11,6 +11,7 @@
+  * 	(C) Copyright 2000 Alex deVries <alex at onefishtwo.ca>
+  *      (C) Copyright 2001 John Marvin <jsm fc hp com>
+  *      (C) Copyright 2003 Grant Grundler <grundler parisc-linux org>
++ *	(C) Copyright 2005 Kyle McMartin <kyle at parisc-linux.org>
+  *
+  *	This program is free software; you can redistribute it and/or
+  *	modify it under the terms of the GNU General Public License as
+@@ -405,6 +406,7 @@ static void __devinit superio_serial_ini
+         
+ 	serial[0].iobase = sio_dev.sp1_base;
+ 	serial[0].irq = SP1_IRQ;
++	spin_lock_init(&serial[0].lock);
+ 
+ 	retval = early_serial_setup(&serial[0]);
+ 	if (retval < 0) {
+@@ -414,6 +416,7 @@ static void __devinit superio_serial_ini
+ 
+ 	serial[1].iobase = sio_dev.sp2_base;
+ 	serial[1].irq = SP2_IRQ;
++	spin_lock_init(&serial[1].lock);
+ 	retval = early_serial_setup(&serial[1]);
+ 
+ 	if (retval < 0)
+diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c
+--- a/drivers/parisc/wax.c
++++ b/drivers/parisc/wax.c
+@@ -81,7 +81,7 @@ wax_init_chip(struct parisc_device *dev)
+ 		return -ENOMEM;
+ 
+ 	wax->name = "wax";
+-	wax->hpa = dev->hpa;
++	wax->hpa = dev->hpa.start;
+ 
+ 	wax->version = 0;   /* gsc_readb(wax->hpa+WAX_VER); */
+ 	printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
+diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
+--- a/drivers/parport/parport_gsc.c
++++ b/drivers/parport/parport_gsc.c
+@@ -359,11 +359,12 @@ static int __devinit parport_init_chip(s
+ 	unsigned long port;
+ 
+ 	if (!dev->irq) {
+-		printk("IRQ not found for parallel device at 0x%lx\n", dev->hpa);
++		printk(KERN_WARNING "IRQ not found for parallel device at 0x%lx\n",
++			dev->hpa.start);
+ 		return -ENODEV;
+ 	}
+ 
+-	port = dev->hpa + PARPORT_GSC_OFFSET;
++	port = dev->hpa.start + PARPORT_GSC_OFFSET;
+ 	
+ 	/* some older machines with ASP-chip don't support
+ 	 * the enhanced parport modes.
+diff --git a/drivers/pci/access.c b/drivers/pci/access.c
+--- a/drivers/pci/access.c
++++ b/drivers/pci/access.c
+@@ -60,3 +60,92 @@ EXPORT_SYMBOL(pci_bus_read_config_dword)
+ EXPORT_SYMBOL(pci_bus_write_config_byte);
+ EXPORT_SYMBOL(pci_bus_write_config_word);
+ EXPORT_SYMBOL(pci_bus_write_config_dword);
++
++static u32 pci_user_cached_config(struct pci_dev *dev, int pos)
++{
++	u32 data;
++
++	data = dev->saved_config_space[pos/sizeof(dev->saved_config_space[0])];
++	data >>= (pos % sizeof(dev->saved_config_space[0])) * 8;
++	return data;
++}
++
++#define PCI_USER_READ_CONFIG(size,type)					\
++int pci_user_read_config_##size						\
++	(struct pci_dev *dev, int pos, type *val)			\
++{									\
++	unsigned long flags;						\
++	int ret = 0;							\
++	u32 data = -1;							\
++	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
++	spin_lock_irqsave(&pci_lock, flags);				\
++	if (likely(!dev->block_ucfg_access))				\
++		ret = dev->bus->ops->read(dev->bus, dev->devfn,		\
++					pos, sizeof(type), &data);	\
++	else if (pos < sizeof(dev->saved_config_space))			\
++		data = pci_user_cached_config(dev, pos); 		\
++	spin_unlock_irqrestore(&pci_lock, flags);			\
++	*val = (type)data;						\
++	return ret;							\
++}
++
++#define PCI_USER_WRITE_CONFIG(size,type)				\
++int pci_user_write_config_##size					\
++	(struct pci_dev *dev, int pos, type val)			\
++{									\
++	unsigned long flags;						\
++	int ret = -EIO;							\
++	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
++	spin_lock_irqsave(&pci_lock, flags);				\
++	if (likely(!dev->block_ucfg_access))				\
++		ret = dev->bus->ops->write(dev->bus, dev->devfn,	\
++					pos, sizeof(type), val);	\
++	spin_unlock_irqrestore(&pci_lock, flags);			\
++	return ret;							\
++}
++
++PCI_USER_READ_CONFIG(byte, u8)
++PCI_USER_READ_CONFIG(word, u16)
++PCI_USER_READ_CONFIG(dword, u32)
++PCI_USER_WRITE_CONFIG(byte, u8)
++PCI_USER_WRITE_CONFIG(word, u16)
++PCI_USER_WRITE_CONFIG(dword, u32)
++
++/**
++ * pci_block_user_cfg_access - Block userspace PCI config reads/writes
++ * @dev:	pci device struct
++ *
++ * This function blocks any userspace PCI config accesses from occurring.
++ * When blocked, any writes will be bit bucketed and reads will return the
++ * data saved using pci_save_state for the first 64 bytes of config
++ * space and return 0xff for all other config reads.
++ **/
++void pci_block_user_cfg_access(struct pci_dev *dev)
++{
++	unsigned long flags;
++
++	pci_save_state(dev);
++
++	/* spinlock to synchronize with anyone reading config space now */
++	spin_lock_irqsave(&pci_lock, flags);
++	dev->block_ucfg_access = 1;
++	spin_unlock_irqrestore(&pci_lock, flags);
++}
++EXPORT_SYMBOL_GPL(pci_block_user_cfg_access);
++
++/**
++ * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
++ * @dev:	pci device struct
++ *
++ * This function allows userspace PCI config accesses to resume.
++ **/
++void pci_unblock_user_cfg_access(struct pci_dev *dev)
++{
++	unsigned long flags;
++
++	/* spinlock to synchronize with anyone reading saved config space */
++	spin_lock_irqsave(&pci_lock, flags);
++	dev->block_ucfg_access = 0;
++	spin_unlock_irqrestore(&pci_lock, flags);
++}
++EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);
+diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
+--- a/drivers/pci/hotplug/acpiphp_glue.c
++++ b/drivers/pci/hotplug/acpiphp_glue.c
+@@ -58,6 +58,9 @@ static LIST_HEAD(bridge_list);
+ 
+ static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
+ static void handle_hotplug_event_func (acpi_handle, u32, void *);
++static void acpiphp_sanitize_bus(struct pci_bus *bus);
++static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus);
++
+ 
+ /*
+  * initialization & terminatation routines
+@@ -796,8 +799,13 @@ static int enable_device(struct acpiphp_
+ 		}
+ 	}
+ 
++	pci_bus_size_bridges(bus);
+ 	pci_bus_assign_resources(bus);
++	acpiphp_sanitize_bus(bus);
++	pci_enable_bridges(bus);
+ 	pci_bus_add_devices(bus);
++	acpiphp_set_hpp_values(DEVICE_ACPI_HANDLE(&bus->self->dev), bus);
++	acpiphp_configure_ioapics(DEVICE_ACPI_HANDLE(&bus->self->dev));
+ 
+ 	/* associate pci_dev to our representation */
+ 	list_for_each (l, &slot->funcs) {
+diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
+--- a/drivers/pci/hotplug/cpcihp_generic.c
++++ b/drivers/pci/hotplug/cpcihp_generic.c
+@@ -39,6 +39,7 @@
+ #include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/pci.h>
++#include <linux/string.h>
+ #include "cpci_hotplug.h"
+ 
+ #define DRIVER_VERSION	"0.1"
+diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
+--- a/drivers/pci/hotplug/cpcihp_zt5550.c
++++ b/drivers/pci/hotplug/cpcihp_zt5550.c
+@@ -36,6 +36,7 @@
+ #include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/pci.h>
++#include <linux/signal.h>	/* SA_SHIRQ */
+ #include "cpci_hotplug.h"
+ #include "cpcihp_zt5550.h"
+ 
+@@ -78,11 +79,20 @@ static void __iomem *csr_int_mask;
+ 
+ static int zt5550_hc_config(struct pci_dev *pdev)
+ {
++	int ret;
++
+ 	/* Since we know that no boards exist with two HC chips, treat it as an error */
+ 	if(hc_dev) {
+ 		err("too many host controller devices?");
+ 		return -EBUSY;
+ 	}
++
++	ret = pci_enable_device(pdev);
++	if(ret) {
++		err("cannot enable %s\n", pci_name(pdev));
++		return ret;
++	}
++
+ 	hc_dev = pdev;
+ 	dbg("hc_dev = %p", hc_dev);
+ 	dbg("pci resource start %lx", pci_resource_start(hc_dev, 1));
+@@ -91,7 +101,8 @@ static int zt5550_hc_config(struct pci_d
+ 	if(!request_mem_region(pci_resource_start(hc_dev, 1),
+ 				pci_resource_len(hc_dev, 1), MY_NAME)) {
+ 		err("cannot reserve MMIO region");
+-		return -ENOMEM;
++		ret = -ENOMEM;
++		goto exit_disable_device;
+ 	}
+ 
+ 	hc_registers =
+@@ -99,9 +110,8 @@ static int zt5550_hc_config(struct pci_d
+ 	if(!hc_registers) {
+ 		err("cannot remap MMIO region %lx @ %lx",
+ 		    pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1));
+-		release_mem_region(pci_resource_start(hc_dev, 1),
+-				   pci_resource_len(hc_dev, 1));
+-		return -ENODEV;
++		ret = -ENODEV;
++		goto exit_release_region;
+ 	}
+ 
+ 	csr_hc_index = hc_registers + CSR_HCINDEX;
+@@ -124,6 +134,13 @@ static int zt5550_hc_config(struct pci_d
+ 	writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask);
+ 	dbg("disabled timer0, timer1 and ENUM interrupts");
+ 	return 0;
++
++exit_release_region:
++	release_mem_region(pci_resource_start(hc_dev, 1),
++			   pci_resource_len(hc_dev, 1));
++exit_disable_device:
++	pci_disable_device(hc_dev);
++	return ret;
+ }
+ 
+ static int zt5550_hc_cleanup(void)
+@@ -134,6 +151,7 @@ static int zt5550_hc_cleanup(void)
+ 	iounmap(hc_registers);
+ 	release_mem_region(pci_resource_start(hc_dev, 1),
+ 			   pci_resource_len(hc_dev, 1));
++	pci_disable_device(hc_dev);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
+--- a/drivers/pci/hotplug/cpqphp_core.c
++++ b/drivers/pci/hotplug/cpqphp_core.c
+@@ -794,12 +794,21 @@ static int cpqhpc_probe(struct pci_dev *
+ 	u32 rc;
+ 	struct controller *ctrl;
+ 	struct pci_func *func;
++	int err;
++
++	err = pci_enable_device(pdev);
++	if (err) {
++		printk(KERN_ERR MY_NAME ": cannot enable PCI device %s (%d)\n",
++			pci_name(pdev), err);
++		return err;
++	}
+ 
+ 	// Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
+ 	rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
+ 	if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
+ 		err(msg_HPC_non_compaq_or_intel);
+-		return -ENODEV;
++		rc = -ENODEV;
++		goto err_disable_device;
+ 	}
+ 	dbg("Vendor ID: %x\n", vendor_id);
+ 
+@@ -807,7 +816,8 @@ static int cpqhpc_probe(struct pci_dev *
+ 	dbg("revision: %d\n", rev);
+ 	if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
+ 		err(msg_HPC_rev_error);
+-		return -ENODEV;
++		rc = -ENODEV;
++		goto err_disable_device;
+ 	}
+ 
+ 	/* Check for the proper subsytem ID's
+@@ -820,18 +830,20 @@ static int cpqhpc_probe(struct pci_dev *
+ 		rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
+ 		if (rc) {
+ 			err("%s : pci_read_config_word failed\n", __FUNCTION__);
+-			return rc;
++			goto err_disable_device;
+ 		}
+ 		dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
+ 		if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
+ 			err(msg_HPC_non_compaq_or_intel);
+-			return -ENODEV;
++			rc = -ENODEV;
++			goto err_disable_device;
+ 		}
+ 
+ 		ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
+ 		if (!ctrl) {
+ 			err("%s : out of memory\n", __FUNCTION__);
+-			return -ENOMEM;
++			rc = -ENOMEM;
++			goto err_disable_device;
+ 		}
+ 		memset(ctrl, 0, sizeof(struct controller));
+ 
+@@ -1264,6 +1276,8 @@ err_free_bus:
+ 	kfree(ctrl->pci_bus);
+ err_free_ctrl:
+ 	kfree(ctrl);
++err_disable_device:
++	pci_disable_device(pdev);
+ 	return rc;
+ }
+ 
+diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
+--- a/drivers/pci/hotplug/fakephp.c
++++ b/drivers/pci/hotplug/fakephp.c
+@@ -37,6 +37,8 @@
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include "pci_hotplug.h"
+ #include "../pci.h"
+ 
+diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
+--- a/drivers/pci/hotplug/ibmphp_core.c
++++ b/drivers/pci/hotplug/ibmphp_core.c
+@@ -1077,7 +1077,7 @@ static int enable_slot(struct hotplug_sl
+ 	if (rc) {
+ 		err("Adding this card exceeds the limitations of this bus.\n");
+ 		err("(i.e., >1 133MHz cards running on same bus, or "
+-		     ">2 66 PCI cards running on same bus\n.");
++		     ">2 66 PCI cards running on same bus.\n");
+ 		err("Try hot-adding into another bus\n");
+ 		rc = -EINVAL;
+ 		goto error_nopower;
+diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
+--- a/drivers/pci/hotplug/pciehp_pci.c
++++ b/drivers/pci/hotplug/pciehp_pci.c
+@@ -113,7 +113,7 @@ int pciehp_unconfigure_device(struct pci
+  */
+ int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
+ {
+-#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
++#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_IO_APIC)
+ 	int rc;
+ 	u16 temp_word;
+ 	struct pci_dev fakedev;
+diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
+--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
++++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
+@@ -33,10 +33,13 @@
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
++
+ #include <asm/uaccess.h>
+ #ifdef CONFIG_IA64
+ #include <asm/iosapic.h>
+ #endif
++
+ #include "pciehp.h"
+ #include "pciehprm.h"
+ #include "pciehprm_nonacpi.h"
+diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
+--- a/drivers/pci/hotplug/rpadlpar_core.c
++++ b/drivers/pci/hotplug/rpadlpar_core.c
+@@ -16,10 +16,13 @@
+  */
+ #include <linux/init.h>
+ #include <linux/pci.h>
++#include <linux/string.h>
++
+ #include <asm/pci-bridge.h>
+ #include <asm/semaphore.h>
+ #include <asm/rtas.h>
+ #include <asm/vio.h>
++
+ #include "../pci.h"
+ #include "rpaphp.h"
+ #include "rpadlpar.h"
+diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
+--- a/drivers/pci/hotplug/rpaphp.h
++++ b/drivers/pci/hotplug/rpaphp.h
+@@ -92,9 +92,10 @@ extern struct pci_bus *rpaphp_find_pci_b
+ extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
+ extern int rpaphp_enable_pci_slot(struct slot *slot);
+ extern int register_pci_slot(struct slot *slot);
+-extern int rpaphp_unconfig_pci_adapter(struct slot *slot);
+ extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
++
+ extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
++extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus);
+ 
+ /* rpaphp_core.c */
+ extern int rpaphp_add_slot(struct device_node *dn);
+diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
+--- a/drivers/pci/hotplug/rpaphp_core.c
++++ b/drivers/pci/hotplug/rpaphp_core.c
+@@ -426,8 +426,11 @@ static int disable_slot(struct hotplug_s
+ 
+ 	dbg("DISABLING SLOT %s\n", slot->name);
+ 	down(&rpaphp_sem);
+-	retval = rpaphp_unconfig_pci_adapter(slot);
++	retval = rpaphp_unconfig_pci_adapter(slot->bus);
+ 	up(&rpaphp_sem);
++	slot->state = NOT_CONFIGURED;
++	info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
++	     slot->name);
+ exit:
+ 	dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
+ 	return retval;
+diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
+--- a/drivers/pci/hotplug/rpaphp_pci.c
++++ b/drivers/pci/hotplug/rpaphp_pci.c
+@@ -23,11 +23,13 @@
+  *
+  */
+ #include <linux/pci.h>
++#include <linux/string.h>
++
+ #include <asm/pci-bridge.h>
+ #include <asm/rtas.h>
+ #include <asm/machdep.h>
+-#include "../pci.h"		/* for pci_add_new_bus */
+ 
++#include "../pci.h"		/* for pci_add_new_bus */
+ #include "rpaphp.h"
+ 
+ static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
+@@ -319,20 +321,15 @@ static void rpaphp_eeh_remove_bus_device
+ 	return;
+ }
+ 
+-int rpaphp_unconfig_pci_adapter(struct slot *slot)
++int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
+ {
+ 	struct pci_dev *dev, *tmp;
+-	int retval = 0;
+ 
+-	list_for_each_entry_safe(dev, tmp, slot->pci_devs, bus_list) {
++	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
+ 		rpaphp_eeh_remove_bus_device(dev);
+ 		pci_remove_bus_device(dev);
+ 	}
+-
+-	slot->state = NOT_CONFIGURED;
+-	info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
+-	     slot->name);
+-	return retval;
++	return 0;
+ }
+ 
+ static int setup_pci_hotplug_slot_info(struct slot *slot)
+diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
+--- a/drivers/pci/hotplug/rpaphp_slot.c
++++ b/drivers/pci/hotplug/rpaphp_slot.c
+@@ -27,6 +27,9 @@
+ #include <linux/kobject.h>
+ #include <linux/sysfs.h>
+ #include <linux/pci.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++
+ #include <asm/rtas.h>
+ #include "rpaphp.h"
+ 
+diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
+--- a/drivers/pci/hotplug/shpchp.h
++++ b/drivers/pci/hotplug/shpchp.h
+@@ -32,8 +32,8 @@
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/delay.h>
+-#include <asm/semaphore.h>
+-#include <asm/io.h>		
++#include <linux/sched.h>	/* signal_pending(), struct timer_list */
++
+ #include "pci_hotplug.h"
+ 
+ #if !defined(MODULE)
+@@ -52,42 +52,18 @@ extern int shpchp_debug;
+ #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+ #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+ 
+-struct pci_func {
+-	struct pci_func *next;
+-	u8 bus;
+-	u8 device;
+-	u8 function;
+-	u8 is_a_board;
+-	u16 status;
+-	u8 configured;
+-	u8 switch_save;
+-	u8 presence_save;
+-	u8 pwr_save;
+-	u32 base_length[0x06];
+-	u8 base_type[0x06];
+-	u16 reserved2;
+-	u32 config_space[0x20];
+-	struct pci_resource *mem_head;
+-	struct pci_resource *p_mem_head;
+-	struct pci_resource *io_head;
+-	struct pci_resource *bus_head;
+-	struct pci_dev* pci_dev;
+-};
+-
+ #define SLOT_MAGIC	0x67267321
+ struct slot {
+ 	u32 magic;
+ 	struct slot *next;
+ 	u8 bus;
+ 	u8 device;
++	u16 status;
+ 	u32 number;
+ 	u8 is_a_board;
+-	u8 configured;
+ 	u8 state;
+-	u8 switch_save;
+ 	u8 presence_save;
+-	u32 capabilities;
+-	u16 reserved2;
++	u8 pwr_save;
+ 	struct timer_list task_event;
+ 	u8 hp_slot;
+ 	struct controller *ctrl;
+@@ -96,12 +72,6 @@ struct slot {
+ 	struct list_head	slot_list;
+ };
+ 
+-struct pci_resource {
+-	struct pci_resource * next;
+-	u32 base;
+-	u32 length;
+-};
+-
+ struct event_info {
+ 	u32 event_type;
+ 	u8 hp_slot;
+@@ -110,13 +80,9 @@ struct event_info {
+ struct controller {
+ 	struct controller *next;
+ 	struct semaphore crit_sect;	/* critical section semaphore */
+-	void * hpc_ctlr_handle;		/* HPC controller handle */
++	struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
+ 	int num_slots;			/* Number of slots on ctlr */
+ 	int slot_num_inc;		/* 1 or -1 */
+-	struct pci_resource *mem_head;
+-	struct pci_resource *p_mem_head;
+-	struct pci_resource *io_head;
+-	struct pci_resource *bus_head;
+ 	struct pci_dev *pci_dev;
+ 	struct pci_bus *pci_bus;
+ 	struct event_info event_queue[10];
+@@ -124,33 +90,21 @@ struct controller {
+ 	struct hpc_ops *hpc_ops;
+ 	wait_queue_head_t queue;	/* sleep & wake process */
+ 	u8 next_event;
+-	u8 seg;
+ 	u8 bus;
+ 	u8 device;
+ 	u8 function;
+-	u8 rev;
+ 	u8 slot_device_offset;
+ 	u8 add_support;
+ 	enum pci_bus_speed speed;
+ 	u32 first_slot;		/* First physical slot number */
+ 	u8 slot_bus;		/* Bus where the slots handled by this controller sit */
+-	u8 push_flag;
+-	u16 ctlrcap;
+-	u16 vendor_id;
+-};
+-
+-struct irq_mapping {
+-	u8 barber_pole;
+-	u8 valid_INT;
+-	u8 interrupt[4];
+ };
+ 
+-struct resource_lists {
+-	struct pci_resource *mem_head;
+-	struct pci_resource *p_mem_head;
+-	struct pci_resource *io_head;
+-	struct pci_resource *bus_head;
+-	struct irq_mapping *irqs;
++struct hotplug_params {
++	u8	cache_line_size;
++	u8	latency_timer;
++	u8	enable_serr;
++	u8	enable_perr;
+ };
+ 
+ /* Define AMD SHPC ID  */
+@@ -194,24 +148,16 @@ struct resource_lists {
+  * error Messages
+  */
+ #define msg_initialization_err	"Initialization failure, error=%d\n"
+-#define msg_HPC_rev_error	"Unsupported revision of the PCI hot plug controller found.\n"
+-#define msg_HPC_non_shpc	"The PCI hot plug controller is not supported by this driver.\n"
+-#define msg_HPC_not_supported	"This system is not supported by this version of shpcphd mdoule. Upgrade to a newer version of shpchpd\n"
+-#define msg_unable_to_save	"Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
+ #define msg_button_on		"PCI slot #%d - powering on due to button press.\n"
+ #define msg_button_off		"PCI slot #%d - powering off due to button press.\n"
+ #define msg_button_cancel	"PCI slot #%d - action canceled due to button press.\n"
+-#define msg_button_ignore	"PCI slot #%d - button press ignored.  (action in progress...)\n"
+ 
+ /* sysfs functions for the hotplug controller info */
+ extern void shpchp_create_ctrl_files	(struct controller *ctrl);
+ 
+ /* controller functions */
+-extern int	shpchprm_find_available_resources(struct controller *ctrl);
+ extern int	shpchp_event_start_thread(void);
+ extern void	shpchp_event_stop_thread(void);
+-extern struct 	pci_func *shpchp_slot_create(unsigned char busnumber);
+-extern struct 	pci_func *shpchp_slot_find(unsigned char bus, unsigned char device, unsigned char index);
+ extern int	shpchp_enable_slot(struct slot *slot);
+ extern int	shpchp_disable_slot(struct slot *slot);
+ 
+@@ -220,29 +166,20 @@ extern u8	shpchp_handle_switch_change(u8
+ extern u8	shpchp_handle_presence_change(u8 hp_slot, void *inst_id);
+ extern u8	shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
+ 
+-/* resource functions */
+-extern int	shpchp_resource_sort_and_combine(struct pci_resource **head);
+-
+ /* pci functions */
+-extern int	shpchp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
+-/*extern int	shpchp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/
+ extern int	shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
+-extern int	shpchp_save_used_resources(struct controller *ctrl, struct pci_func * func, int flag);
+-extern int	shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot);
+-extern void	shpchp_destroy_board_resources(struct pci_func * func);
+-extern int	shpchp_return_board_resources(struct pci_func * func, struct resource_lists * resources);
+-extern void	shpchp_destroy_resource_list(struct resource_lists * resources);
+-extern int	shpchp_configure_device(struct controller* ctrl, struct pci_func* func);
+-extern int	shpchp_unconfigure_device(struct pci_func* func);
++extern int	shpchp_configure_device(struct slot *p_slot);
++extern int	shpchp_unconfigure_device(struct slot *p_slot);
++extern void	get_hp_hw_control_from_firmware(struct pci_dev *dev);
++extern void	get_hp_params_from_firmware(struct pci_dev *dev,
++		struct hotplug_params *hpp);
++extern int	shpchprm_get_physical_slot_number(struct controller *ctrl,
++		u32 *sun, u8 busnum, u8 devnum);
++extern void	shpchp_remove_ctrl_files(struct controller *ctrl);
+ 
+ 
+ /* Global variables */
+ extern struct controller *shpchp_ctrl_list;
+-extern struct pci_func *shpchp_slot_list[256];
+-
+-/* These are added to support AMD shpc */
+-extern u8 shpchp_nic_irq;
+-extern u8 shpchp_disk_irq;
+ 
+ struct ctrl_reg {
+ 	volatile u32 base_offset;
+@@ -298,7 +235,7 @@ enum ctrl_offsets {
+ 	SLOT11 =	offsetof(struct ctrl_reg, slot11),
+ 	SLOT12 =	offsetof(struct ctrl_reg, slot12),
+ };
+-typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
++typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
+ struct php_ctlr_state_s {
+ 	struct php_ctlr_state_s *pnext;
+ 	struct pci_dev *pci_dev;
+@@ -359,12 +296,9 @@ static inline struct slot *shpchp_find_s
+ 
+ 	p_slot = ctrl->slot;
+ 
+-	dbg("p_slot = %p\n", p_slot);
+-
+ 	while (p_slot && (p_slot->device != device)) {
+ 		tmp_slot = p_slot;
+ 		p_slot = p_slot->next;
+-		dbg("In while loop, p_slot = %p\n", p_slot);
+ 	}
+ 	if (p_slot == NULL) {
+ 		err("ERROR: shpchp_find_slot device=0x%x\n", device);
+@@ -379,8 +313,6 @@ static inline int wait_for_ctrl_irq (str
+     DECLARE_WAITQUEUE(wait, current);
+ 	int retval = 0;
+ 
+-	dbg("%s : start\n",__FUNCTION__);
+-
+ 	add_wait_queue(&ctrl->queue, &wait);
+ 
+ 	if (!shpchp_poll_mode) {
+@@ -394,19 +326,9 @@ static inline int wait_for_ctrl_irq (str
+ 	if (signal_pending(current))
+ 		retval =  -EINTR;
+ 
+-	dbg("%s : end\n", __FUNCTION__);
+ 	return retval;
+ }
+ 
+-/* Puts node back in the resource list pointed to by head */
+-static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
+-{
+-	if (!node || !head)
+-		return;
+-	node->next = *head;
+-	*head = node;
+-}
+-
+ #define SLOT_NAME_SIZE 10
+ 
+ static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
+@@ -420,11 +342,7 @@ enum php_ctlr_type {
+ 	ACPI
+ };
+ 
+-int shpc_init( struct controller *ctrl, struct pci_dev *pdev,
+-		php_intr_callback_t attention_button_callback,
+-		php_intr_callback_t switch_change_callback,
+-		php_intr_callback_t presence_change_callback,
+-		php_intr_callback_t power_fault_callback);
++int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
+ 
+ int shpc_get_ctlr_slot_config( struct controller *ctrl,
+ 		int *num_ctlr_slots,
+@@ -437,8 +355,6 @@ struct hpc_ops {
+ 	int	(*power_on_slot )		(struct slot *slot);
+ 	int	(*slot_enable )			(struct slot *slot);
+ 	int	(*slot_disable )		(struct slot *slot);
+-	int	(*enable_all_slots)		(struct slot *slot);
+-	int	(*pwr_on_all_slots)		(struct slot *slot);
+ 	int	(*set_bus_speed_mode)	(struct slot *slot, enum pci_bus_speed speed);
+ 	int	(*get_power_status)		(struct slot *slot, u8 *status);
+ 	int	(*get_attention_status)	(struct slot *slot, u8 *status);
+diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
+--- a/drivers/pci/hotplug/shpchp_core.c
++++ b/drivers/pci/hotplug/shpchp_core.c
+@@ -27,26 +27,18 @@
+  *
+  */
+ 
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+-#include <linux/proc_fs.h>
+-#include <linux/slab.h>
+-#include <linux/workqueue.h>
+ #include <linux/pci.h>
+-#include <linux/init.h>
+-#include <asm/uaccess.h>
+ #include "shpchp.h"
+-#include "shpchprm.h"
+ 
+ /* Global variables */
+ int shpchp_debug;
+ int shpchp_poll_mode;
+ int shpchp_poll_time;
+ struct controller *shpchp_ctrl_list;	/* = NULL */
+-struct pci_func *shpchp_slot_list[256];
+ 
+ #define DRIVER_VERSION	"0.4"
+ #define DRIVER_AUTHOR	"Dan Zink <dan.zink at compaq.com>, Greg Kroah-Hartman <greg at kroah.com>, Dely Sy <dely.l.sy at intel.com>"
+@@ -113,8 +105,6 @@ static int init_slots(struct controller 
+ 	u32 slot_number, sun;
+ 	int result = -ENOMEM;
+ 
+-	dbg("%s\n",__FUNCTION__);
+-
+ 	number_of_slots = ctrl->num_slots;
+ 	slot_device = ctrl->slot_device_offset;
+ 	slot_number = ctrl->first_slot;
+@@ -352,6 +342,17 @@ static int get_cur_bus_speed (struct hot
+ 	return 0;
+ }
+ 
++static int is_shpc_capable(struct pci_dev *dev)
++{
++       if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device ==
++                               PCI_DEVICE_ID_AMD_GOLAM_7450))
++               return 1;
++       if (pci_find_capability(dev, PCI_CAP_ID_SHPC))
++               return 1;
++
++       return 0;
++}
++
+ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ 	int rc;
+@@ -360,6 +361,9 @@ static int shpc_probe(struct pci_dev *pd
+ 	int first_device_num;	/* first PCI device number supported by this SHPC */
+ 	int num_ctlr_slots;	/* number of slots supported by this SHPC */
+ 
++	if (!is_shpc_capable(pdev))
++		return -ENODEV;
++
+ 	ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
+ 	if (!ctrl) {
+ 		err("%s : out of memory\n", __FUNCTION__);
+@@ -367,19 +371,12 @@ static int shpc_probe(struct pci_dev *pd
+ 	}
+ 	memset(ctrl, 0, sizeof(struct controller));
+ 
+-	dbg("DRV_thread pid = %d\n", current->pid);
+-
+-	rc = shpc_init(ctrl, pdev,
+-			(php_intr_callback_t) shpchp_handle_attention_button,
+-			(php_intr_callback_t) shpchp_handle_switch_change,
+-			(php_intr_callback_t) shpchp_handle_presence_change,
+-			(php_intr_callback_t) shpchp_handle_power_fault);
++	rc = shpc_init(ctrl, pdev);
+ 	if (rc) {
+ 		dbg("%s: controller initialization failed\n", SHPC_MODULE_NAME);
+ 		goto err_out_free_ctrl;
+ 	}
+ 
+-	dbg("%s: controller initialization success\n", __FUNCTION__);
+ 	ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */
+ 
+ 	pci_set_drvdata(pdev, ctrl);
+@@ -411,23 +408,8 @@ static int shpc_probe(struct pci_dev *pd
+ 	first_device_num = ctrl->slot_device_offset;
+ 	num_ctlr_slots = ctrl->num_slots;
+ 
+-	/* Store PCI Config Space for all devices on this bus */
+-	rc = shpchp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
+-	if (rc) {
+-		err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
+-		goto err_out_free_ctrl_bus;
+-	}
+-
+-	/* Get IO, memory, and IRQ resources for new devices */
+-	rc = shpchprm_find_available_resources(ctrl);
+-	ctrl->add_support = !rc;
++	ctrl->add_support = 1;
+ 	
+-	if (rc) {
+-		dbg("shpchprm_find_available_resources = %#x\n", rc);
+-		err("unable to locate PCI configuration resources for hot plug add.\n");
+-		goto err_out_free_ctrl_bus;
+-	}
+-
+ 	/* Setup the slot information structures */
+ 	rc = init_slots(ctrl);
+ 	if (rc) {
+@@ -477,7 +459,6 @@ err_out_none:
+ 
+ static int shpc_start_thread(void)
+ {
+-	int loop;
+ 	int retval = 0;
+ 	
+ 	dbg("Initialize + Start the notification/polling mechanism \n");
+@@ -488,48 +469,21 @@ static int shpc_start_thread(void)
+ 		return retval;
+ 	}
+ 
+-	dbg("Initialize slot lists\n");
+-	/* One slot list for each bus in the system */
+-	for (loop = 0; loop < 256; loop++) {
+-		shpchp_slot_list[loop] = NULL;
+-	}
+-
+ 	return retval;
+ }
+ 
+-static inline void __exit
+-free_shpchp_res(struct pci_resource *res)
+-{
+-	struct pci_resource *tres;
+-
+-	while (res) {
+-		tres = res;
+-		res = res->next;
+-		kfree(tres);
+-	}
+-}
+-
+ static void __exit unload_shpchpd(void)
+ {
+-	struct pci_func *next;
+-	struct pci_func *TempSlot;
+-	int loop;
+ 	struct controller *ctrl;
+ 	struct controller *tctrl;
+ 
+ 	ctrl = shpchp_ctrl_list;
+ 
+ 	while (ctrl) {
++		shpchp_remove_ctrl_files(ctrl);
+ 		cleanup_slots(ctrl);
+ 
+-		free_shpchp_res(ctrl->io_head);
+-		free_shpchp_res(ctrl->mem_head);
+-		free_shpchp_res(ctrl->p_mem_head);
+-		free_shpchp_res(ctrl->bus_head);
+-
+ 		kfree (ctrl->pci_bus);
+-
+-		dbg("%s: calling release_ctlr\n", __FUNCTION__);
+ 		ctrl->hpc_ops->release_ctlr(ctrl);
+ 
+ 		tctrl = ctrl;
+@@ -538,20 +492,6 @@ static void __exit unload_shpchpd(void)
+ 		kfree(tctrl);
+ 	}
+ 
+-	for (loop = 0; loop < 256; loop++) {
+-		next = shpchp_slot_list[loop];
+-		while (next != NULL) {
+-			free_shpchp_res(next->io_head);
+-			free_shpchp_res(next->mem_head);
+-			free_shpchp_res(next->p_mem_head);
+-			free_shpchp_res(next->bus_head);
+-
+-			TempSlot = next;
+-			next = next->next;
+-			kfree(TempSlot);
+-		}
+-	}
+-
+ 	/* Stop the notification mechanism */
+ 	shpchp_event_stop_thread();
+ 
+@@ -596,20 +536,14 @@ static int __init shpcd_init(void)
+ 	if (retval)
+ 		goto error_hpc_init;
+ 
+-	retval = shpchprm_init(PCI);
+-	if (!retval) {
+-		retval = pci_register_driver(&shpc_driver);
+-		dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
+-		info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+-	}
++	retval = pci_register_driver(&shpc_driver);
++	dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
++	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ 
+ error_hpc_init:
+ 	if (retval) {
+-		shpchprm_cleanup();
+ 		shpchp_event_stop_thread();
+-	} else
+-		shpchprm_print_pirt();
+-
++	}
+ 	return retval;
+ }
+ 
+@@ -618,9 +552,6 @@ static void __exit shpcd_cleanup(void)
+ 	dbg("unload_shpchpd()\n");
+ 	unload_shpchpd();
+ 
+-	shpchprm_cleanup();
+-
+-	dbg("pci_unregister_driver\n");
+ 	pci_unregister_driver(&shpc_driver);
+ 
+ 	info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
+diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
+--- a/drivers/pci/hotplug/shpchp_ctrl.c
++++ b/drivers/pci/hotplug/shpchp_ctrl.c
+@@ -27,24 +27,14 @@
+  *
+  */
+ 
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+-#include <linux/slab.h>
+-#include <linux/workqueue.h>
+-#include <linux/interrupt.h>
+-#include <linux/delay.h>
+-#include <linux/wait.h>
+ #include <linux/smp_lock.h>
+ #include <linux/pci.h>
++#include "../pci.h"
+ #include "shpchp.h"
+-#include "shpchprm.h"
+ 
+-static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
+-	u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
+-static int configure_new_function( struct controller *ctrl, struct pci_func *func,
+-	u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
+ static void interrupt_event_handler(struct controller *ctrl);
+ 
+ static struct semaphore event_semaphore;	/* mutex for process loop (up if something to process) */
+@@ -52,28 +42,22 @@ static struct semaphore event_exit;		/* 
+ static int event_finished;
+ static unsigned long pushbutton_pending;	/* = 0 */
+ 
+-u8 shpchp_disk_irq;
+-u8 shpchp_nic_irq;
+-
+ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
+ {
+ 	struct controller *ctrl = (struct controller *) inst_id;
+ 	struct slot *p_slot;
+ 	u8 rc = 0;
+ 	u8 getstatus;
+-	struct pci_func *func;
+ 	struct event_info *taskInfo;
+ 
+ 	/* Attention Button Change */
+ 	dbg("shpchp:  Attention button interrupt received.\n");
+ 	
+-	func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
+-
+ 	/* This is the structure that tells the worker thread what to do */
+ 	taskInfo = &(ctrl->event_queue[ctrl->next_event]);
+ 	p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+ 
+-	p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
++	p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
+ 	p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+ 	
+ 	ctrl->next_event = (ctrl->next_event + 1) % 10;
+@@ -118,14 +102,11 @@ u8 shpchp_handle_switch_change(u8 hp_slo
+ 	struct slot *p_slot;
+ 	u8 rc = 0;
+ 	u8 getstatus;
+-	struct pci_func *func;
+ 	struct event_info *taskInfo;
+ 
+ 	/* Switch Change */
+ 	dbg("shpchp:  Switch interrupt received.\n");
+ 
+-	func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
+-
+ 	/* This is the structure that tells the worker thread
+ 	 * what to do
+ 	 */
+@@ -135,19 +116,18 @@ u8 shpchp_handle_switch_change(u8 hp_slo
+ 
+ 	rc++;
+ 	p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+-	p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
++	p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
+ 	p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+ 	dbg("%s: Card present %x Power status %x\n", __FUNCTION__,
+-		func->presence_save, func->pwr_save);
++		p_slot->presence_save, p_slot->pwr_save);
+ 
+ 	if (getstatus) {
+ 		/*
+ 		 * Switch opened
+ 		 */
+ 		info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
+-		func->switch_save = 0;
+ 		taskInfo->event_type = INT_SWITCH_OPEN;
+-		if (func->pwr_save && func->presence_save) {
++		if (p_slot->pwr_save && p_slot->presence_save) {
+ 			taskInfo->event_type = INT_POWER_FAULT;
+ 			err("Surprise Removal of card\n");
+ 		}
+@@ -156,7 +136,6 @@ u8 shpchp_handle_switch_change(u8 hp_slo
+ 		 *  Switch closed
+ 		 */
+ 		info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
+-		func->switch_save = 0x10;
+ 		taskInfo->event_type = INT_SWITCH_CLOSE;
+ 	}
+ 
+@@ -172,14 +151,11 @@ u8 shpchp_handle_presence_change(u8 hp_s
+ 	struct slot *p_slot;
+ 	u8 rc = 0;
+ 	/*u8 temp_byte;*/
+-	struct pci_func *func;
+ 	struct event_info *taskInfo;
+ 
+ 	/* Presence Change */
+ 	dbg("shpchp:  Presence/Notify input change.\n");
+ 
+-	func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
+-
+ 	/* This is the structure that tells the worker thread
+ 	 * what to do
+ 	 */
+@@ -193,8 +169,8 @@ u8 shpchp_handle_presence_change(u8 hp_s
+ 	/* 
+ 	 * Save the presence state
+ 	 */
+-	p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
+-	if (func->presence_save) {
++	p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
++	if (p_slot->presence_save) {
+ 		/*
+ 		 * Card Present
+ 		 */
+@@ -219,14 +195,11 @@ u8 shpchp_handle_power_fault(u8 hp_slot,
+ 	struct controller *ctrl = (struct controller *) inst_id;
+ 	struct slot *p_slot;
+ 	u8 rc = 0;
+-	struct pci_func *func;
+ 	struct event_info *taskInfo;
+ 
+ 	/* Power fault */
+ 	dbg("shpchp:  Power fault interrupt received.\n");
+ 
+-	func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
+-
+ 	/* This is the structure that tells the worker thread
+ 	 * what to do
+ 	 */
+@@ -242,7 +215,7 @@ u8 shpchp_handle_power_fault(u8 hp_slot,
+ 		 * Power fault Cleared
+ 		 */
+ 		info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
+-		func->status = 0x00;
++		p_slot->status = 0x00;
+ 		taskInfo->event_type = INT_POWER_FAULT_CLEAR;
+ 	} else {
+ 		/*
+@@ -251,7 +224,7 @@ u8 shpchp_handle_power_fault(u8 hp_slot,
+ 		info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
+ 		taskInfo->event_type = INT_POWER_FAULT;
+ 		/* set power fault status for this board */
+-		func->status = 0xFF;
++		p_slot->status = 0xFF;
+ 		info("power fault bit %x set\n", hp_slot);
+ 	}
+ 	if (rc)
+@@ -260,799 +233,13 @@ u8 shpchp_handle_power_fault(u8 hp_slot,
+ 	return rc;
+ }
+ 
+-
+-/*
+- * sort_by_size
+- *
+- * Sorts nodes on the list by their length.
+- * Smallest first.
+- *
+- */
+-static int sort_by_size(struct pci_resource **head)
+-{
+-	struct pci_resource *current_res;
+-	struct pci_resource *next_res;
+-	int out_of_order = 1;
+-
+-	if (!(*head))
+-		return(1);
+-
+-	if (!((*head)->next))
+-		return(0);
+-
+-	while (out_of_order) {
+-		out_of_order = 0;
+-
+-		/* Special case for swapping list head */
+-		if (((*head)->next) &&
+-		    ((*head)->length > (*head)->next->length)) {
+-			out_of_order++;
+-			current_res = *head;
+-			*head = (*head)->next;
+-			current_res->next = (*head)->next;
+-			(*head)->next = current_res;
+-		}
+-
+-		current_res = *head;
+-
+-		while (current_res->next && current_res->next->next) {
+-			if (current_res->next->length > current_res->next->next->length) {
+-				out_of_order++;
+-				next_res = current_res->next;
+-				current_res->next = current_res->next->next;
+-				current_res = current_res->next;
+-				next_res->next = current_res->next;
+-				current_res->next = next_res;
+-			} else
+-				current_res = current_res->next;
+-		}
+-	}  /* End of out_of_order loop */
+-
+-	return(0);
+-}
+-
+-
+-/*
+- * sort_by_max_size
+- *
+- * Sorts nodes on the list by their length.
+- * Largest first.
+- *
+- */
+-static int sort_by_max_size(struct pci_resource **head)
+-{
+-	struct pci_resource *current_res;
+-	struct pci_resource *next_res;
+-	int out_of_order = 1;
+-
+-	if (!(*head))
+-		return(1);
+-
+-	if (!((*head)->next))
+-		return(0);
+-
+-	while (out_of_order) {
+-		out_of_order = 0;
+-
+-		/* Special case for swapping list head */
+-		if (((*head)->next) &&
+-		    ((*head)->length < (*head)->next->length)) {
+-			out_of_order++;
+-			current_res = *head;
+-			*head = (*head)->next;
+-			current_res->next = (*head)->next;
+-			(*head)->next = current_res;
+-		}
+-
+-		current_res = *head;
+-
+-		while (current_res->next && current_res->next->next) {
+-			if (current_res->next->length < current_res->next->next->length) {
+-				out_of_order++;
+-				next_res = current_res->next;
+-				current_res->next = current_res->next->next;
+-				current_res = current_res->next;
+-				next_res->next = current_res->next;
+-				current_res->next = next_res;
+-			} else
+-				current_res = current_res->next;
+-		}
+-	}  /* End of out_of_order loop */
+-
+-	return(0);
+-}
+-
+-
+-/*
+- * do_pre_bridge_resource_split
+- *
+- *	Returns zero or one node of resources that aren't in use
+- *
+- */
+-static struct pci_resource *do_pre_bridge_resource_split (struct pci_resource **head, struct pci_resource **orig_head, u32 alignment)
+-{
+-	struct pci_resource *prevnode = NULL;
+-	struct pci_resource *node;
+-	struct pci_resource *split_node;
+-	u32 rc;
+-	u32 temp_dword;
+-	dbg("do_pre_bridge_resource_split\n");
+-
+-	if (!(*head) || !(*orig_head))
+-		return(NULL);
+-
+-	rc = shpchp_resource_sort_and_combine(head);
+-
+-	if (rc)
+-		return(NULL);
+-
+-	if ((*head)->base != (*orig_head)->base)
+-		return(NULL);
+-
+-	if ((*head)->length == (*orig_head)->length)
+-		return(NULL);
+-
+-
+-	/* If we got here, there the bridge requires some of the resource, but
+-	 *  we may be able to split some off of the front
+-	 */	
+-	node = *head;
+-
+-	if (node->length & (alignment -1)) {
+-		/* This one isn't an aligned length, so we'll make a new entry
+-		 * and split it up.
+-		 */
+-		split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
+-
+-		if (!split_node)
+-			return(NULL);
+-
+-		temp_dword = (node->length | (alignment-1)) + 1 - alignment;
+-
+-		split_node->base = node->base;
+-		split_node->length = temp_dword;
+-
+-		node->length -= temp_dword;
+-		node->base += split_node->length;
+-
+-		/* Put it in the list */
+-		*head = split_node;
+-		split_node->next = node;
+-	}
+-
+-	if (node->length < alignment) {
+-		return(NULL);
+-	}
+-
+-	/* Now unlink it */
+-	if (*head == node) {
+-		*head = node->next;
+-		node->next = NULL;
+-	} else {
+-		prevnode = *head;
+-		while (prevnode->next != node)
+-			prevnode = prevnode->next;
+-
+-		prevnode->next = node->next;
+-		node->next = NULL;
+-	}
+-
+-	return(node);
+-}
+-
+-
+-/*
+- * do_bridge_resource_split
+- *
+- *	Returns zero or one node of resources that aren't in use
+- *
+- */
+-static struct pci_resource *do_bridge_resource_split (struct pci_resource **head, u32 alignment)
+-{
+-	struct pci_resource *prevnode = NULL;
+-	struct pci_resource *node;
+-	u32 rc;
+-	u32 temp_dword;
+-
+-	if (!(*head))
+-		return(NULL);
+-
+-	rc = shpchp_resource_sort_and_combine(head);
+-
+-	if (rc)
+-		return(NULL);
+-
+-	node = *head;
+-
+-	while (node->next) {
+-		prevnode = node;
+-		node = node->next;
+-		kfree(prevnode);
+-	}
+-
+-	if (node->length < alignment) {
+-		kfree(node);
+-		return(NULL);
+-	}
+-
+-	if (node->base & (alignment - 1)) {
+-		/* Short circuit if adjusted size is too small */
+-		temp_dword = (node->base | (alignment-1)) + 1;
+-		if ((node->length - (temp_dword - node->base)) < alignment) {
+-			kfree(node);
+-			return(NULL);
+-		}
+-
+-		node->length -= (temp_dword - node->base);
+-		node->base = temp_dword;
+-	}
+-
+-	if (node->length & (alignment - 1)) {
+-		/* There's stuff in use after this node */
+-		kfree(node);
+-		return(NULL);
+-	}
+-
+-	return(node);
+-}
+-
+-
+-/*
+- * get_io_resource
+- *
+- * this function sorts the resource list by size and then
+- * returns the first node of "size" length that is not in the
+- * ISA aliasing window.  If it finds a node larger than "size"
+- * it will split it up.
+- *
+- * size must be a power of two.
+- */
+-static struct pci_resource *get_io_resource (struct pci_resource **head, u32 size)
+-{
+-	struct pci_resource *prevnode;
+-	struct pci_resource *node;
+-	struct pci_resource *split_node = NULL;
+-	u32 temp_dword;
+-
+-	if (!(*head))
+-		return(NULL);
+-
+-	if ( shpchp_resource_sort_and_combine(head) )
+-		return(NULL);
+-
+-	if ( sort_by_size(head) )
+-		return(NULL);
+-
+-	for (node = *head; node; node = node->next) {
+-		if (node->length < size)
+-			continue;
+-
+-		if (node->base & (size - 1)) {
+-			/* This one isn't base aligned properly
+-			   so we'll make a new entry and split it up */
+-			temp_dword = (node->base | (size-1)) + 1;
+-
+-			/*/ Short circuit if adjusted size is too small */
+-			if ((node->length - (temp_dword - node->base)) < size)
+-				continue;
+-
+-			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
+-
+-			if (!split_node)
+-				return(NULL);
+-
+-			split_node->base = node->base;
+-			split_node->length = temp_dword - node->base;
+-			node->base = temp_dword;
+-			node->length -= split_node->length;
+-
+-			/* Put it in the list */
+-			split_node->next = node->next;
+-			node->next = split_node;
+-		} /* End of non-aligned base */
+-
+-		/* Don't need to check if too small since we already did */
+-		if (node->length > size) {
+-			/* This one is longer than we need
+-			   so we'll make a new entry and split it up */
+-			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
+-
+-			if (!split_node)
+-				return(NULL);
+-
+-			split_node->base = node->base + size;
+-			split_node->length = node->length - size;
+-			node->length = size;
+-
+-			/* Put it in the list */
+-			split_node->next = node->next;
+-			node->next = split_node;
+-		}  /* End of too big on top end */
+-
+-		/* For IO make sure it's not in the ISA aliasing space */
+-		if (node->base & 0x300L)
+-			continue;
+-
+-		/* If we got here, then it is the right size 
+-		   Now take it out of the list */
+-		if (*head == node) {
+-			*head = node->next;
+-		} else {
+-			prevnode = *head;
+-			while (prevnode->next != node)
+-				prevnode = prevnode->next;
+-
+-			prevnode->next = node->next;
+-		}
+-		node->next = NULL;
+-		/* Stop looping */
+-		break;
+-	}
+-
+-	return(node);
+-}
+-
+-
+-/*
+- * get_max_resource
+- *
+- * Gets the largest node that is at least "size" big from the
+- * list pointed to by head.  It aligns the node on top and bottom
+- * to "size" alignment before returning it.
+- * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
+- *  This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
+- */
+-static struct pci_resource *get_max_resource (struct pci_resource **head, u32 size)
+-{
+-	struct pci_resource *max;
+-	struct pci_resource *temp;
+-	struct pci_resource *split_node;
+-	u32 temp_dword;
+-	u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
+-	int i;
+-
+-	if (!(*head))
+-		return(NULL);
+-
+-	if (shpchp_resource_sort_and_combine(head))
+-		return(NULL);
+-
+-	if (sort_by_max_size(head))
+-		return(NULL);
+-
+-	for (max = *head;max; max = max->next) {
+-
+-		/* If not big enough we could probably just bail, 
+-		   instead we'll continue to the next. */
+-		if (max->length < size)
+-			continue;
+-
+-		if (max->base & (size - 1)) {
+-			/* This one isn't base aligned properly
+-			   so we'll make a new entry and split it up */
+-			temp_dword = (max->base | (size-1)) + 1;
+-
+-			/* Short circuit if adjusted size is too small */
+-			if ((max->length - (temp_dword - max->base)) < size)
+-				continue;
+-
+-			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
+-
+-			if (!split_node)
+-				return(NULL);
+-
+-			split_node->base = max->base;
+-			split_node->length = temp_dword - max->base;
+-			max->base = temp_dword;
+-			max->length -= split_node->length;
+-
+-			/* Put it next in the list */
+-			split_node->next = max->next;
+-			max->next = split_node;
+-		}
+-
+-		if ((max->base + max->length) & (size - 1)) {
+-			/* This one isn't end aligned properly at the top
+-			   so we'll make a new entry and split it up */
+-			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
+-
+-			if (!split_node)
+-				return(NULL);
+-			temp_dword = ((max->base + max->length) & ~(size - 1));
+-			split_node->base = temp_dword;
+-			split_node->length = max->length + max->base
+-					     - split_node->base;
+-			max->length -= split_node->length;
+-
+-			/* Put it in the list */
+-			split_node->next = max->next;
+-			max->next = split_node;
+-		}
+-
+-		/* Make sure it didn't shrink too much when we aligned it */
+-		if (max->length < size)
+-			continue;
+-
+-		for ( i = 0; max_size[i] > size; i++) {
+-			if (max->length > max_size[i]) {
+-				split_node = kmalloc(sizeof(*split_node),
+-							GFP_KERNEL);
+-				if (!split_node)
+-					break;	/* return (NULL); */
+-				split_node->base = max->base + max_size[i];
+-				split_node->length = max->length - max_size[i];
+-				max->length = max_size[i];
+-				/* Put it next in the list */
+-				split_node->next = max->next;
+-				max->next = split_node;
+-				break;
+-			}
+-		}
+-
+-		/* Now take it out of the list */
+-		temp = (struct pci_resource*) *head;
+-		if (temp == max) {
+-			*head = max->next;
+-		} else {
+-			while (temp && temp->next != max) {
+-				temp = temp->next;
+-			}
+-
+-			temp->next = max->next;
+-		}
+-
+-		max->next = NULL;
+-		return(max);
+-	}
+-
+-	/* If we get here, we couldn't find one */
+-	return(NULL);
+-}
+-
+-
+-/*
+- * get_resource
+- *
+- * this function sorts the resource list by size and then
+- * returns the first node of "size" length.  If it finds a node
+- * larger than "size" it will split it up.
+- *
+- * size must be a power of two.
+- */
+-static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
+-{
+-	struct pci_resource *prevnode;
+-	struct pci_resource *node;
+-	struct pci_resource *split_node;
+-	u32 temp_dword;
+-
+-	if (!(*head))
+-		return(NULL);
+-
+-	if ( shpchp_resource_sort_and_combine(head) )
+-		return(NULL);
+-
+-	if ( sort_by_size(head) )
+-		return(NULL);
+-
+-	for (node = *head; node; node = node->next) {
+-		dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
+-		    __FUNCTION__, size, node, node->base, node->length);
+-		if (node->length < size)
+-			continue;
+-
+-		if (node->base & (size - 1)) {
+-			dbg("%s: not aligned\n", __FUNCTION__);
+-			/* this one isn't base aligned properly
+-			   so we'll make a new entry and split it up */
+-			temp_dword = (node->base | (size-1)) + 1;
+-
+-			/* Short circuit if adjusted size is too small */
+-			if ((node->length - (temp_dword - node->base)) < size)
+-				continue;
+-
+-			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
+-
+-			if (!split_node)
+-				return(NULL);
+-
+-			split_node->base = node->base;
+-			split_node->length = temp_dword - node->base;
+-			node->base = temp_dword;
+-			node->length -= split_node->length;
+-
+-			/* Put it in the list */
+-			split_node->next = node->next;
+-			node->next = split_node;
+-		} /* End of non-aligned base */
+-
+-		/* Don't need to check if too small since we already did */
+-		if (node->length > size) {
+-			dbg("%s: too big\n", __FUNCTION__);
+-			/* this one is longer than we need
+-			   so we'll make a new entry and split it up */
+-			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
+-
+-			if (!split_node)
+-				return(NULL);
+-
+-			split_node->base = node->base + size;
+-			split_node->length = node->length - size;
+-			node->length = size;
+-
+-			/* Put it in the list */
+-			split_node->next = node->next;
+-			node->next = split_node;
+-		}  /* End of too big on top end */
+-
+-		dbg("%s: got one!!!\n", __FUNCTION__);
+-		/* If we got here, then it is the right size
+-		   Now take it out of the list */
+-		if (*head == node) {
+-			*head = node->next;
+-		} else {
+-			prevnode = *head;
+-			while (prevnode->next != node)
+-				prevnode = prevnode->next;
+-
+-			prevnode->next = node->next;
+-		}
+-		node->next = NULL;
+-		/* Stop looping */
+-		break;
+-	}
+-	return(node);
+-}
+-
+-
+-/*
+- * shpchp_resource_sort_and_combine
+- *
+- * Sorts all of the nodes in the list in ascending order by
+- * their base addresses.  Also does garbage collection by
+- * combining adjacent nodes.
+- *
+- * returns 0 if success
+- */
+-int shpchp_resource_sort_and_combine(struct pci_resource **head)
+-{
+-	struct pci_resource *node1;
+-	struct pci_resource *node2;
+-	int out_of_order = 1;
+-
+-	dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
+-
+-	if (!(*head))
+-		return(1);
+-
+-	dbg("*head->next = %p\n",(*head)->next);
+-
+-	if (!(*head)->next)
+-		return(0);	/* only one item on the list, already sorted! */
+-
+-	dbg("*head->base = 0x%x\n",(*head)->base);
+-	dbg("*head->next->base = 0x%x\n",(*head)->next->base);
+-	while (out_of_order) {
+-		out_of_order = 0;
+-
+-		/* Special case for swapping list head */
+-		if (((*head)->next) &&
+-		    ((*head)->base > (*head)->next->base)) {
+-			node1 = *head;
+-			(*head) = (*head)->next;
+-			node1->next = (*head)->next;
+-			(*head)->next = node1;
+-			out_of_order++;
+-		}
+-
+-		node1 = (*head);
+-
+-		while (node1->next && node1->next->next) {
+-			if (node1->next->base > node1->next->next->base) {
+-				out_of_order++;
+-				node2 = node1->next;
+-				node1->next = node1->next->next;
+-				node1 = node1->next;
+-				node2->next = node1->next;
+-				node1->next = node2;
+-			} else
+-				node1 = node1->next;
+-		}
+-	}  /* End of out_of_order loop */
+-
+-	node1 = *head;
+-
+-	while (node1 && node1->next) {
+-		if ((node1->base + node1->length) == node1->next->base) {
+-			/* Combine */
+-			dbg("8..\n");
+-			node1->length += node1->next->length;
+-			node2 = node1->next;
+-			node1->next = node1->next->next;
+-			kfree(node2);
+-		} else
+-			node1 = node1->next;
+-	}
+-
+-	return(0);
+-}
+-
+-
+-/**
+- * shpchp_slot_create - Creates a node and adds it to the proper bus.
+- * @busnumber - bus where new node is to be located
+- *
+- * Returns pointer to the new node or NULL if unsuccessful
+- */
+-struct pci_func *shpchp_slot_create(u8 busnumber)
+-{
+-	struct pci_func *new_slot;
+-	struct pci_func *next;
+-
+-	new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
+-
+-	if (new_slot == NULL) {
+-		return(new_slot);
+-	}
+-
+-	memset(new_slot, 0, sizeof(struct pci_func));
+-
+-	new_slot->next = NULL;
+-	new_slot->configured = 1;
+-
+-	if (shpchp_slot_list[busnumber] == NULL) {
+-		shpchp_slot_list[busnumber] = new_slot;
+-	} else {
+-		next = shpchp_slot_list[busnumber];
+-		while (next->next != NULL)
+-			next = next->next;
+-		next->next = new_slot;
+-	}
+-	return(new_slot);
+-}
+-
+-
+-/*
+- * slot_remove - Removes a node from the linked list of slots.
+- * @old_slot: slot to remove
+- *
+- * Returns 0 if successful, !0 otherwise.
+- */
+-static int slot_remove(struct pci_func * old_slot)
+-{
+-	struct pci_func *next;
+-
+-	if (old_slot == NULL)
+-		return(1);
+-
+-	next = shpchp_slot_list[old_slot->bus];
+-
+-	if (next == NULL) {
+-		return(1);
+-	}
+-
+-	if (next == old_slot) {
+-		shpchp_slot_list[old_slot->bus] = old_slot->next;
+-		shpchp_destroy_board_resources(old_slot);
+-		kfree(old_slot);
+-		return(0);
+-	}
+-
+-	while ((next->next != old_slot) && (next->next != NULL)) {
+-		next = next->next;
+-	}
+-
+-	if (next->next == old_slot) {
+-		next->next = old_slot->next;
+-		shpchp_destroy_board_resources(old_slot);
+-		kfree(old_slot);
+-		return(0);
+-	} else
+-		return(2);
+-}
+-
+-
+-/**
+- * bridge_slot_remove - Removes a node from the linked list of slots.
+- * @bridge: bridge to remove
+- *
+- * Returns 0 if successful, !0 otherwise.
+- */
+-static int bridge_slot_remove(struct pci_func *bridge)
+-{
+-	u8 subordinateBus, secondaryBus;
+-	u8 tempBus;
+-	struct pci_func *next;
+-
+-	if (bridge == NULL)
+-		return(1);
+-
+-	secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
+-	subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
+-
+-	for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
+-		next = shpchp_slot_list[tempBus];
+-
+-		while (!slot_remove(next)) {
+-			next = shpchp_slot_list[tempBus];
+-		}
+-	}
+-
+-	next = shpchp_slot_list[bridge->bus];
+-
+-	if (next == NULL) {
+-		return(1);
+-	}
+-
+-	if (next == bridge) {
+-		shpchp_slot_list[bridge->bus] = bridge->next;
+-		kfree(bridge);
+-		return(0);
+-	}
+-
+-	while ((next->next != bridge) && (next->next != NULL)) {
+-		next = next->next;
+-	}
+-
+-	if (next->next == bridge) {
+-		next->next = bridge->next;
+-		kfree(bridge);
+-		return(0);
+-	} else
+-		return(2);
+-}
+-
+-
+-/**
+- * shpchp_slot_find - Looks for a node by bus, and device, multiple functions accessed
+- * @bus: bus to find
+- * @device: device to find
+- * @index: is 0 for first function found, 1 for the second...
+- *
+- * Returns pointer to the node if successful, %NULL otherwise.
+- */
+-struct pci_func *shpchp_slot_find(u8 bus, u8 device, u8 index)
+-{
+-	int found = -1;
+-	struct pci_func *func;
+-
+-	func = shpchp_slot_list[bus];
+-
+-	if ((func == NULL) || ((func->device == device) && (index == 0)))
+-		return(func);
+-
+-	if (func->device == device)
+-		found++;
+-
+-	while (func->next != NULL) {
+-		func = func->next;
+-
+-		if (func->device == device)
+-			found++;
+-
+-		if (found == index)
+-			return(func);
+-	}
+-
+-	return(NULL);
+-}
+-
+-static int is_bridge(struct pci_func * func)
+-{
+-	/* Check the header type */
+-	if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
+-		return 1;
+-	else
+-		return 0;
+-}
+-
+-
+ /* The following routines constitute the bulk of the 
+    hotplug controller logic
+  */
+-static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed)
++static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
++		enum pci_bus_speed speed)
+ { 
+-	u32 rc = 0;
++	int rc = 0;
+ 
+ 	dbg("%s: change to speed %d\n", __FUNCTION__, speed);
+ 	down(&ctrl->crit_sect);
+@@ -1074,10 +261,11 @@ static u32 change_bus_speed(struct contr
+ 	return rc;
+ }
+ 
+-static u32 fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag, 
+-enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp)
++static int fix_bus_speed(struct controller *ctrl, struct slot *pslot,
++		u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp,
++		enum pci_bus_speed msp)
+ { 
+-	u32 rc = 0;
++	int rc = 0;
+ 	
+ 	if (flag != 0) { /* Other slots on the same bus are occupied */
+ 		if ( asp < bsp ) {
+@@ -1116,23 +304,20 @@ enum pci_bus_speed asp, enum pci_bus_spe
+  * Configures board
+  *
+  */
+-static u32 board_added(struct pci_func * func, struct controller * ctrl)
++static int board_added(struct slot *p_slot)
+ {
+ 	u8 hp_slot;
+ 	u8 slots_not_empty = 0;
+-	int index;
+-	u32 temp_register = 0xFFFFFFFF;
+-	u32 retval, rc = 0;
+-	struct pci_func *new_func = NULL;
+-	struct slot *p_slot;
+-	struct resource_lists res_lists;
++	int rc = 0;
+ 	enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed;
+ 	u8 pi, mode;
++	struct controller *ctrl = p_slot->ctrl;
+ 
+-	p_slot = shpchp_find_slot(ctrl, func->device);
+-	hp_slot = func->device - ctrl->slot_device_offset;
++	hp_slot = p_slot->device - ctrl->slot_device_offset;
+ 
+-	dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
++	dbg("%s: p_slot->device, slot_offset, hp_slot = %d, %d ,%d\n",
++			__FUNCTION__, p_slot->device,
++			ctrl->slot_device_offset, hp_slot);
+ 
+ 	/* Wait for exclusive access to hardware */
+ 	down(&ctrl->crit_sect);
+@@ -1320,143 +505,68 @@ static u32 board_added(struct pci_func *
+ 	up(&ctrl->crit_sect);
+ 
+ 	/* Wait for ~1 second */
+-	dbg("%s: before long_delay\n", __FUNCTION__);
+ 	wait_for_ctrl_irq (ctrl);
+-	dbg("%s: after long_delay\n", __FUNCTION__);
+ 
+-	dbg("%s: func status = %x\n", __FUNCTION__, func->status);
++	dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
+ 	/* Check for a power fault */
+-	if (func->status == 0xFF) {
++	if (p_slot->status == 0xFF) {
+ 		/* power fault occurred, but it was benign */
+-		temp_register = 0xFFFFFFFF;
+-		dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
++		dbg("%s: power fault\n", __FUNCTION__);
+ 		rc = POWER_FAILURE;
+-		func->status = 0;
+-	} else {
+-		/* Get vendor/device ID u32 */
+-		rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function), 
+-			PCI_VENDOR_ID, &temp_register);
+-		dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
+-		dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
+-
+-		if (rc != 0) {
+-			/* Something's wrong here */
+-			temp_register = 0xFFFFFFFF;
+-			dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
+-		}
+-		/* Preset return code.  It will be changed later if things go okay. */
+-		rc = NO_ADAPTER_PRESENT;
++		p_slot->status = 0;
++		goto err_exit;
+ 	}
+ 
+-	/* All F's is an empty slot or an invalid board */
+-	if (temp_register != 0xFFFFFFFF) {	  /* Check for a board in the slot */
+-		res_lists.io_head = ctrl->io_head;
+-		res_lists.mem_head = ctrl->mem_head;
+-		res_lists.p_mem_head = ctrl->p_mem_head;
+-		res_lists.bus_head = ctrl->bus_head;
+-		res_lists.irqs = NULL;
+-
+-		rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
+-		dbg("%s: back from configure_new_device\n", __FUNCTION__);
+-
+-		ctrl->io_head = res_lists.io_head;
+-		ctrl->mem_head = res_lists.mem_head;
+-		ctrl->p_mem_head = res_lists.p_mem_head;
+-		ctrl->bus_head = res_lists.bus_head;
+-
+-		shpchp_resource_sort_and_combine(&(ctrl->mem_head));
+-		shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
+-		shpchp_resource_sort_and_combine(&(ctrl->io_head));
+-		shpchp_resource_sort_and_combine(&(ctrl->bus_head));
+-
+-		if (rc) {
+-			/* Wait for exclusive access to hardware */
+-			down(&ctrl->crit_sect);
+-
+-			/* turn off slot, turn on Amber LED, turn off Green LED */
+-			retval = p_slot->hpc_ops->slot_disable(p_slot);
+-			if (retval) {
+-				err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
+-				/* Done with exclusive hardware access */
+-				up(&ctrl->crit_sect);
+-				return retval;
+-			}
+-			/* Wait for the command to complete */
+-			wait_for_ctrl_irq (ctrl);
+-
+-			retval = p_slot->hpc_ops->check_cmd_status(ctrl);
+-			if (retval) {
+-				err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, retval);
+-				/* Done with exclusive hardware access */
+-				up(&ctrl->crit_sect);
+-				return retval;  
+-			}
+-
+-			/* Done with exclusive hardware access */
+-			up(&ctrl->crit_sect);
++	if (shpchp_configure_device(p_slot)) {
++		err("Cannot add device at 0x%x:0x%x\n", p_slot->bus,
++				p_slot->device);
++		goto err_exit;
++	}
+ 
+-			return(rc);
+-		}
+-		shpchp_save_slot_config(ctrl, func);
++	p_slot->status = 0;
++	p_slot->is_a_board = 0x01;
++	p_slot->pwr_save = 1;
+ 
+-		func->status = 0;
+-		func->switch_save = 0x10;
+-		func->is_a_board = 0x01;
+-		func->pwr_save = 1;
++	/* Wait for exclusive access to hardware */
++	down(&ctrl->crit_sect);
+ 
+-		/* Next, we will instantiate the linux pci_dev structures 
+-		 * (with appropriate driver notification, if already present) 
+-		 */
+-		index = 0;
+-		do {
+-			new_func = shpchp_slot_find(ctrl->slot_bus, func->device, index++);
+-			if (new_func && !new_func->pci_dev) {
+-				dbg("%s:call pci_hp_configure_dev\n", __FUNCTION__);
+-				shpchp_configure_device(ctrl, new_func);
+-			}
+-		} while (new_func);
++	p_slot->hpc_ops->green_led_on(p_slot);
+ 
+-		/* Wait for exclusive access to hardware */
+-		down(&ctrl->crit_sect);
++	/* Wait for the command to complete */
++	wait_for_ctrl_irq (ctrl);
+ 
+-		p_slot->hpc_ops->green_led_on(p_slot);
++	/* Done with exclusive hardware access */
++	up(&ctrl->crit_sect);
+ 
+-		/* Wait for the command to complete */
+-		wait_for_ctrl_irq (ctrl);
++	return 0;
+ 
++err_exit:
++	/* Wait for exclusive access to hardware */
++	down(&ctrl->crit_sect);
+ 
++	/* turn off slot, turn on Amber LED, turn off Green LED */
++	rc = p_slot->hpc_ops->slot_disable(p_slot);
++	if (rc) {
++		err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
+ 		/* Done with exclusive hardware access */
+ 		up(&ctrl->crit_sect);
++		return rc;
++	}
++	/* Wait for the command to complete */
++	wait_for_ctrl_irq (ctrl);
+ 
+-	} else {
+-		/* Wait for exclusive access to hardware */
+-		down(&ctrl->crit_sect);
+-
+-		/* turn off slot, turn on Amber LED, turn off Green LED */
+-		rc = p_slot->hpc_ops->slot_disable(p_slot);
+-		if (rc) {
+-			err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
+-			/* Done with exclusive hardware access */
+-			up(&ctrl->crit_sect);
+-			return rc;
+-		}
+-		/* Wait for the command to complete */
+-		wait_for_ctrl_irq (ctrl);
+-
+-		rc = p_slot->hpc_ops->check_cmd_status(ctrl);
+-		if (rc) {
+-			err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
+-			/* Done with exclusive hardware access */
+-			up(&ctrl->crit_sect);
+-			return rc;  
+-		}
+-
++	rc = p_slot->hpc_ops->check_cmd_status(ctrl);
++	if (rc) {
++		err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
+ 		/* Done with exclusive hardware access */
+ 		up(&ctrl->crit_sect);
+-
+-		return(rc);
++		return rc;
+ 	}
+-	return 0;
++
++	/* Done with exclusive hardware access */
++	up(&ctrl->crit_sect);
++
++	return(rc);
+ }
+ 
+ 
+@@ -1464,55 +574,23 @@ static u32 board_added(struct pci_func *
+  * remove_board - Turns off slot and LED's
+  *
+  */
+-static u32 remove_board(struct pci_func *func, struct controller *ctrl)
++static int remove_board(struct slot *p_slot)
+ {
+-	int index;
+-	u8 skip = 0;
+-	u8 device;
++	struct controller *ctrl = p_slot->ctrl;
+ 	u8 hp_slot;
+-	u32 rc;
+-	struct resource_lists res_lists;
+-	struct pci_func *temp_func;
+-	struct slot *p_slot;
+-
+-	if (func == NULL)
+-		return(1);
++	int rc;
+ 
+-	if (shpchp_unconfigure_device(func))
++	if (shpchp_unconfigure_device(p_slot))
+ 		return(1);
+ 
+-	device = func->device;
+-
+-	hp_slot = func->device - ctrl->slot_device_offset;
++	hp_slot = p_slot->device - ctrl->slot_device_offset;
+ 	p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+ 
+ 	dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
+ 
+-	if ((ctrl->add_support) &&
+-		!(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
+-		/* Here we check to see if we've saved any of the board's
+-		 * resources already.  If so, we'll skip the attempt to
+-		 * determine what's being used.
+-		 */
+-		index = 0;
+-
+-		temp_func = func;
+-
+-		while ((temp_func = shpchp_slot_find(temp_func->bus, temp_func->device, index++))) {
+-			if (temp_func->bus_head || temp_func->mem_head
+-			    || temp_func->p_mem_head || temp_func->io_head) {
+-				skip = 1;
+-				break;
+-			}
+-		}
+-
+-		if (!skip)
+-			rc = shpchp_save_used_resources(ctrl, func, DISABLE_CARD);
+-	}
+ 	/* Change status to shutdown */
+-	if (func->is_a_board)
+-		func->status = 0x01;
+-	func->configured = 0;
++	if (p_slot->is_a_board)
++		p_slot->status = 0x01;
+ 
+ 	/* Wait for exclusive access to hardware */
+ 	down(&ctrl->crit_sect);
+@@ -1549,55 +627,8 @@ static u32 remove_board(struct pci_func 
+ 	/* Done with exclusive hardware access */
+ 	up(&ctrl->crit_sect);
+ 
+-	if (ctrl->add_support) {
+-		while (func) {
+-			res_lists.io_head = ctrl->io_head;
+-			res_lists.mem_head = ctrl->mem_head;
+-			res_lists.p_mem_head = ctrl->p_mem_head;
+-			res_lists.bus_head = ctrl->bus_head;
+-
+-			dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n", func->bus, 
+-				func->device, func->function);
+-
+-			shpchp_return_board_resources(func, &res_lists);
+-
+-			ctrl->io_head = res_lists.io_head;
+-			ctrl->mem_head = res_lists.mem_head;
+-			ctrl->p_mem_head = res_lists.p_mem_head;
+-			ctrl->bus_head = res_lists.bus_head;
+-
+-			shpchp_resource_sort_and_combine(&(ctrl->mem_head));
+-			shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
+-			shpchp_resource_sort_and_combine(&(ctrl->io_head));
+-			shpchp_resource_sort_and_combine(&(ctrl->bus_head));
+-
+-			if (is_bridge(func)) {
+-				dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, 
+-					func->device, func->function);
+-				bridge_slot_remove(func);
+-			} else
+-				dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, 
+-					func->device, func->function);
+-				slot_remove(func);
+-
+-			func = shpchp_slot_find(ctrl->slot_bus, device, 0);
+-		}
+-
+-		/* Setup slot structure with entry for empty slot */
+-		func = shpchp_slot_create(ctrl->slot_bus);
+-
+-		if (func == NULL) {
+-			return(1);
+-		}
+-
+-		func->bus = ctrl->slot_bus;
+-		func->device = device;
+-		func->function = 0;
+-		func->configured = 0;
+-		func->switch_save = 0x10;
+-		func->pwr_save = 0;
+-		func->is_a_board = 0;
+-	}
++	p_slot->pwr_save = 0;
++	p_slot->is_a_board = 0;
+ 
+ 	return 0;
+ }
+@@ -1633,13 +664,11 @@ static void shpchp_pushbutton_thread (un
+ 	p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+ 	if (getstatus) {
+ 		p_slot->state = POWEROFF_STATE;
+-		dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ 
+ 		shpchp_disable_slot(p_slot);
+ 		p_slot->state = STATIC_STATE;
+ 	} else {
+ 		p_slot->state = POWERON_STATE;
+-		dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ 
+ 		if (shpchp_enable_slot(p_slot)) {
+ 			/* Wait for exclusive access to hardware */
+@@ -1701,7 +730,6 @@ int shpchp_event_start_thread (void)
+ 		err ("Can't start up our event thread\n");
+ 		return -1;
+ 	}
+-	dbg("Our event thread pid = %d\n", pid);
+ 	return 0;
+ }
+ 
+@@ -1709,9 +737,7 @@ int shpchp_event_start_thread (void)
+ void shpchp_event_stop_thread (void)
+ {
+ 	event_finished = 1;
+-	dbg("event_thread finish command given\n");
+ 	up(&event_semaphore);
+-	dbg("wait for event_thread to exit\n");
+ 	down(&event_exit);
+ }
+ 
+@@ -1739,12 +765,10 @@ static void interrupt_event_handler(stru
+ {
+ 	int loop = 0;
+ 	int change = 1;
+-	struct pci_func *func;
+ 	u8 hp_slot;
+ 	u8 getstatus;
+ 	struct slot *p_slot;
+ 
+-	dbg("%s:\n", __FUNCTION__);
+ 	while (change) {
+ 		change = 0;
+ 
+@@ -1754,12 +778,8 @@ static void interrupt_event_handler(stru
+ 					ctrl->event_queue[loop].event_type);
+ 				hp_slot = ctrl->event_queue[loop].hp_slot;
+ 
+-				func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
+-
+ 				p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+ 
+-				dbg("%s: hp_slot %d, func %p, p_slot %p\n", __FUNCTION__, hp_slot, func, p_slot);
+-
+ 				if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
+ 					dbg("%s: button cancel\n", __FUNCTION__);
+ 					del_timer(&p_slot->task_event);
+@@ -1880,13 +900,6 @@ int shpchp_enable_slot (struct slot *p_s
+ {
+ 	u8 getstatus = 0;
+ 	int rc;
+-	struct pci_func *func;
+-
+-	func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
+-	if (!func) {
+-		dbg("%s: Error! slot NULL\n", __FUNCTION__);
+-		return -ENODEV;
+-	}
+ 
+ 	/* Check to see if (latch closed, card present, power off) */
+ 	down(&p_slot->ctrl->crit_sect);
+@@ -1910,72 +923,34 @@ int shpchp_enable_slot (struct slot *p_s
+ 	}
+ 	up(&p_slot->ctrl->crit_sect);
+ 
+-	slot_remove(func);
+-
+-	func = shpchp_slot_create(p_slot->bus);
+-	if (func == NULL)
+-		return -ENOMEM;
+-
+-	func->bus = p_slot->bus;
+-	func->device = p_slot->device;
+-	func->function = 0;
+-	func->configured = 0;
+-	func->is_a_board = 1;
++	p_slot->is_a_board = 1;
+ 
+ 	/* We have to save the presence info for these slots */
+-	p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
+-	p_slot->hpc_ops->get_power_status(p_slot, &(func->pwr_save));
+-	dbg("%s: func->pwr_save %x\n", __FUNCTION__, func->pwr_save);
++	p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
++	p_slot->hpc_ops->get_power_status(p_slot, &(p_slot->pwr_save));
++	dbg("%s: p_slot->pwr_save %x\n", __FUNCTION__, p_slot->pwr_save);
+ 	p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+-	func->switch_save = !getstatus? 0x10:0;
+ 
+-	rc = board_added(func, p_slot->ctrl);
++	rc = board_added(p_slot);
+ 	if (rc) {
+-		if (is_bridge(func))
+-			bridge_slot_remove(func);
+-		else
+-			slot_remove(func);
+-
+-		/* Setup slot structure with entry for empty slot */
+-		func = shpchp_slot_create(p_slot->bus);
+-		if (func == NULL)
+-			return -ENOMEM;	/* Out of memory */
+-
+-		func->bus = p_slot->bus;
+-		func->device = p_slot->device;
+-		func->function = 0;
+-		func->configured = 0;
+-		func->is_a_board = 1;
+-
+-		/* We have to save the presence info for these slots */
+-		p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
++		p_slot->hpc_ops->get_adapter_status(p_slot,
++				&(p_slot->presence_save));
+ 		p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+-		func->switch_save = !getstatus? 0x10:0;
+ 	}
+ 
+-	if (p_slot)
+-		update_slot_info(p_slot);
+-
++	update_slot_info(p_slot);
+ 	return rc;
+ }
+ 
+ 
+ int shpchp_disable_slot (struct slot *p_slot)
+ {
+-	u8 class_code, header_type, BCR;
+-	u8 index = 0;
+ 	u8 getstatus = 0;
+-	u32 rc = 0;
+ 	int ret = 0;
+-	unsigned int devfn;
+-	struct pci_bus *pci_bus;
+-	struct pci_func *func;
+ 
+ 	if (!p_slot->ctrl)
+ 		return -ENODEV;
+ 
+-	pci_bus = p_slot->ctrl->pci_dev->subordinate;
+-
+ 	/* Check to see if (latch closed, card present, power on) */
+ 	down(&p_slot->ctrl->crit_sect);
+ 
+@@ -1999,849 +974,8 @@ int shpchp_disable_slot (struct slot *p_
+ 	}
+ 	up(&p_slot->ctrl->crit_sect);
+ 
+-	func = shpchp_slot_find(p_slot->bus, p_slot->device, index++);
+-
+-	/* Make sure there are no video controllers here
+-	 * for all func of p_slot
+-	 */
+-	while (func && !rc) {
+-		pci_bus->number = func->bus;
+-		devfn = PCI_DEVFN(func->device, func->function);
+-
+-		/* Check the Class Code */
+-		rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+-		if (rc)
+-			return -ENODEV;
+-
+-		if (class_code == PCI_BASE_CLASS_DISPLAY) {
+-			/* Display/Video adapter (not supported) */
+-			rc = REMOVE_NOT_SUPPORTED;
+-		} else {
+-			/* See if it's a bridge */
+-			rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+-			if (rc)
+-				return -ENODEV;
+-
+-			/* If it's a bridge, check the VGA Enable bit */
+-			if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+-				rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
+-				if (rc)
+-					return -ENODEV;
+-
+-				/* If the VGA Enable bit is set, remove isn't supported */
+-				if (BCR & PCI_BRIDGE_CTL_VGA) {
+-					rc = REMOVE_NOT_SUPPORTED;
+-				}
+-			}
+-		}
+-
+-		func = shpchp_slot_find(p_slot->bus, p_slot->device, index++);
+-	}
+-
+-	func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
+-	if ((func != NULL) && !rc) {
+-		rc = remove_board(func, p_slot->ctrl);
+-	} else if (!rc)
+-		rc = -ENODEV;
+-
+-	if (p_slot)
+-		update_slot_info(p_slot);
+-
+-	return rc;
+-}
+-
+-
+-/**
+- * configure_new_device - Configures the PCI header information of one board.
+- *
+- * @ctrl: pointer to controller structure
+- * @func: pointer to function structure
+- * @behind_bridge: 1 if this is a recursive call, 0 if not
+- * @resources: pointer to set of resource lists
+- *
+- * Returns 0 if success
+- *
+- */
+-static u32 configure_new_device (struct controller * ctrl, struct pci_func * func,
+-	u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
+-{
+-	u8 temp_byte, function, max_functions, stop_it;
+-	int rc;
+-	u32 ID;
+-	struct pci_func *new_slot;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	int index;
+-
+-	new_slot = func;
+-
+-	dbg("%s\n", __FUNCTION__);
+-	memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	pci_bus->number = func->bus;
+-
+-	/* Check for Multi-function device */
+-	rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
+-	if (rc) {
+-		dbg("%s: rc = %d\n", __FUNCTION__, rc);
+-		return rc;
+-	}
+-
+-	if (temp_byte & 0x80)	/* Multi-function device */
+-		max_functions = 8;
+-	else
+-		max_functions = 1;
+-
+-	function = 0;
+-
+-	do {
+-		rc = configure_new_function(ctrl, new_slot, behind_bridge, resources, bridge_bus, bridge_dev);
+-
+-		if (rc) {
+-			dbg("configure_new_function failed %d\n",rc);
+-			index = 0;
+-
+-			while (new_slot) {
+-				new_slot = shpchp_slot_find(new_slot->bus, new_slot->device, index++);
+-
+-				if (new_slot)
+-					shpchp_return_board_resources(new_slot, resources);
+-			}
+-
+-			return(rc);
+-		}
+-
+-		function++;
+-
+-		stop_it = 0;
+-
+-		/*  The following loop skips to the next present function
+-		 *  and creates a board structure
+-		 */
+-
+-		while ((function < max_functions) && (!stop_it)) {
+-			pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
+-
+-			if (ID == 0xFFFFFFFF) {	  /* There's nothing there. */
+-				function++;
+-			} else {  /* There's something there */
+-				/* Setup slot structure. */
+-				new_slot = shpchp_slot_create(func->bus);
+-
+-				if (new_slot == NULL) {
+-					/* Out of memory */
+-					return(1);
+-				}
+-
+-				new_slot->bus = func->bus;
+-				new_slot->device = func->device;
+-				new_slot->function = function;
+-				new_slot->is_a_board = 1;
+-				new_slot->status = 0;
+-
+-				stop_it++;
+-			}
+-		}
+-
+-	} while (function < max_functions);
+-	dbg("returning from configure_new_device\n");
+-
+-	return 0;
+-}
+-
+-
+-/*
+- * Configuration logic that involves the hotplug data structures and 
+- * their bookkeeping
+- */
+-
+-
+-/**
+- * configure_new_function - Configures the PCI header information of one device
+- *
+- * @ctrl: pointer to controller structure
+- * @func: pointer to function structure
+- * @behind_bridge: 1 if this is a recursive call, 0 if not
+- * @resources: pointer to set of resource lists
+- *
+- * Calls itself recursively for bridged devices.
+- * Returns 0 if success
+- *
+- */
+-static int configure_new_function (struct controller * ctrl, struct pci_func * func,
+-	u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev)
+-{
+-	int cloop;
+-	u8 temp_byte;
+-	u8 device;
+-	u8 class_code;
+-	u16 temp_word;
+-	u32 rc;
+-	u32 temp_register;
+-	u32 base;
+-	u32 ID;
+-	unsigned int devfn;
+-	struct pci_resource *mem_node;
+-	struct pci_resource *p_mem_node;
+-	struct pci_resource *io_node;
+-	struct pci_resource *bus_node;
+-	struct pci_resource *hold_mem_node;
+-	struct pci_resource *hold_p_mem_node;
+-	struct pci_resource *hold_IO_node;
+-	struct pci_resource *hold_bus_node;
+-	struct irq_mapping irqs;
+-	struct pci_func *new_slot;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	struct resource_lists temp_resources;
+-#if defined(CONFIG_X86_64)
+-	u8 IRQ=0;
+-#endif
+-
+-	memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	pci_bus->number = func->bus;
+-	devfn = PCI_DEVFN(func->device, func->function);
+-
+-	/* Check for Bridge */
+-	rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
+-	if (rc)
+-		return rc;
+-
+-	if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
+-		/* set Primary bus */
+-		dbg("set Primary bus = 0x%x\n", func->bus);
+-		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
+-		if (rc)
+-			return rc;
+-
+-		/* find range of busses to use */
+-		bus_node = get_max_resource(&resources->bus_head, 1L);
+-
+-		/* If we don't have any busses to allocate, we can't continue */
+-		if (!bus_node) {
+-			err("Got NO bus resource to use\n");
+-			return -ENOMEM;
+-		}
+-		dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
+-
+-		/* set Secondary bus */
+-		temp_byte = (u8)bus_node->base;
+-		dbg("set Secondary bus = 0x%x\n", temp_byte);
+-		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
+-		if (rc)
+-			return rc;
+-
+-		/* set subordinate bus */
+-		temp_byte = (u8)(bus_node->base + bus_node->length - 1);
+-		dbg("set subordinate bus = 0x%x\n", temp_byte);
+-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
+-		if (rc)
+-			return rc;
+-
+-		/* Set HP parameters (Cache Line Size, Latency Timer) */
+-		rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
+-		if (rc)
+-			return rc;
+-
+-		/* Setup the IO, memory, and prefetchable windows */
+-
+-		io_node = get_max_resource(&(resources->io_head), 0x1000L);
+-		if (io_node) {
+-			dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
+-		}
+-
+-		mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
+-		if (mem_node) {
+-			dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
+-		}
+-
+-		if (resources->p_mem_head)
+-			p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
+-		else {
+-			/*
+-			 * In some platform implementation, MEM and PMEM are not
+-			 *  distinguished, and hence ACPI _CRS has only MEM entries
+-			 *  for both MEM and PMEM.
+-			 */
+-			dbg("using MEM for PMEM\n");
+-			p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
+-		}
+-		if (p_mem_node) {
+-			dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
+-		}
+-
+-		/* set up the IRQ info */
+-		if (!resources->irqs) {
+-			irqs.barber_pole = 0;
+-			irqs.interrupt[0] = 0;
+-			irqs.interrupt[1] = 0;
+-			irqs.interrupt[2] = 0;
+-			irqs.interrupt[3] = 0;
+-			irqs.valid_INT = 0;
+-		} else {
+-			irqs.barber_pole = resources->irqs->barber_pole;
+-			irqs.interrupt[0] = resources->irqs->interrupt[0];
+-			irqs.interrupt[1] = resources->irqs->interrupt[1];
+-			irqs.interrupt[2] = resources->irqs->interrupt[2];
+-			irqs.interrupt[3] = resources->irqs->interrupt[3];
+-			irqs.valid_INT = resources->irqs->valid_INT;
+-		}
+-
+-		/* set up resource lists that are now aligned on top and bottom
+-		 * for anything behind the bridge.
+-		 */
+-		temp_resources.bus_head = bus_node;
+-		temp_resources.io_head = io_node;
+-		temp_resources.mem_head = mem_node;
+-		temp_resources.p_mem_head = p_mem_node;
+-		temp_resources.irqs = &irqs;
+-
+-		/* Make copies of the nodes we are going to pass down so that
+-		 * if there is a problem,we can just use these to free resources
+-		 */
+-		hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);
+-		hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);
+-		hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);
+-		hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL);
+-
+-		if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
+-			kfree(hold_bus_node);
+-			kfree(hold_IO_node);
+-			kfree(hold_mem_node);
+-			kfree(hold_p_mem_node);
+-
+-			return 1;
+-		}
+-
+-		memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
+-
+-		bus_node->base += 1;
+-		bus_node->length -= 1;
+-		bus_node->next = NULL;
+-
+-		/* If we have IO resources copy them and fill in the bridge's
+-		 * IO range registers
+-		 */
+-		if (io_node) {
+-			memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
+-			io_node->next = NULL;
+-
+-			/* set IO base and Limit registers */
+-			RES_CHECK(io_node->base, 8);
+-			temp_byte = (u8)(io_node->base >> 8);
+-			rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte);
+-
+-			RES_CHECK(io_node->base + io_node->length - 1, 8);
+-			temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
+-			rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
+-		} else {
+-			kfree(hold_IO_node);
+-			hold_IO_node = NULL;
+-		}
+-
+-		/* If we have memory resources copy them and fill in the bridge's
+-		 * memory range registers.  Otherwise, fill in the range
+-		 * registers with values that disable them.
+-		 */
+-		if (mem_node) {
+-			memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
+-			mem_node->next = NULL;
+-
+-			/* set Mem base and Limit registers */
+-			RES_CHECK(mem_node->base, 16);
+-			temp_word = (u32)(mem_node->base >> 16);
+-			rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+-
+-			RES_CHECK(mem_node->base + mem_node->length - 1, 16);
+-			temp_word = (u32)((mem_node->base + mem_node->length - 1) >> 16);
+-			rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+-		} else {
+-			temp_word = 0xFFFF;
+-			rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+-
+-			temp_word = 0x0000;
+-			rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+-
+-			kfree(hold_mem_node);
+-			hold_mem_node = NULL;
+-		}
+-
+-		/* If we have prefetchable memory resources copy them and 
+-		 * fill in the bridge's memory range registers.  Otherwise,
+-		 * fill in the range registers with values that disable them.
+-		 */
+-		if (p_mem_node) {
+-			memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
+-			p_mem_node->next = NULL;
+-
+-			/* set Pre Mem base and Limit registers */
+-			RES_CHECK(p_mem_node->base, 16);
+-			temp_word = (u32)(p_mem_node->base >> 16);
+-			rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+-
+-			RES_CHECK(p_mem_node->base + p_mem_node->length - 1, 16);
+-			temp_word = (u32)((p_mem_node->base + p_mem_node->length - 1) >> 16);
+-			rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+-		} else {
+-			temp_word = 0xFFFF;
+-			rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+-
+-			temp_word = 0x0000;
+-			rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+-
+-			kfree(hold_p_mem_node);
+-			hold_p_mem_node = NULL;
+-		}
+-
+-		/* Adjust this to compensate for extra adjustment in first loop */
+-		irqs.barber_pole--;
+-
+-		rc = 0;
+-
+-		/* Here we actually find the devices and configure them */
+-		for (device = 0; (device <= 0x1F) && !rc; device++) {
+-			irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
+-
+-			ID = 0xFFFFFFFF;
+-			pci_bus->number = hold_bus_node->base;
+-			pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
+-					PCI_VENDOR_ID, &ID);
+-			pci_bus->number = func->bus;
+-
+-			if (ID != 0xFFFFFFFF) {	  /*  device Present */
+-				/* Setup slot structure. */
+-				new_slot = shpchp_slot_create(hold_bus_node->base);
+-
+-				if (new_slot == NULL) {
+-					/* Out of memory */
+-					rc = -ENOMEM;
+-					continue;
+-				}
+-
+-				new_slot->bus = hold_bus_node->base;
+-				new_slot->device = device;
+-				new_slot->function = 0;
+-				new_slot->is_a_board = 1;
+-				new_slot->status = 0;
+-
+-				rc = configure_new_device(ctrl, new_slot, 1, &temp_resources, func->bus, func->device);
+-				dbg("configure_new_device rc=0x%x\n",rc);
+-			}	/* End of IF (device in slot?) */
+-		}		/* End of FOR loop */
+-
+-		if (rc) {
+-			shpchp_destroy_resource_list(&temp_resources);
+-
+-			return_resource(&(resources->bus_head), hold_bus_node);
+-			return_resource(&(resources->io_head), hold_IO_node);
+-			return_resource(&(resources->mem_head), hold_mem_node);
+-			return_resource(&(resources->p_mem_head), hold_p_mem_node);
+-			return(rc);
+-		}
+-
+-		/* save the interrupt routing information */
+-		if (resources->irqs) {
+-			resources->irqs->interrupt[0] = irqs.interrupt[0];
+-			resources->irqs->interrupt[1] = irqs.interrupt[1];
+-			resources->irqs->interrupt[2] = irqs.interrupt[2];
+-			resources->irqs->interrupt[3] = irqs.interrupt[3];
+-			resources->irqs->valid_INT = irqs.valid_INT;
+-		} else if (!behind_bridge) {
+-			/* We need to hook up the interrupts here */
+-			for (cloop = 0; cloop < 4; cloop++) {
+-				if (irqs.valid_INT & (0x01 << cloop)) {
+-					rc = shpchp_set_irq(func->bus, func->device,
+-							   0x0A + cloop, irqs.interrupt[cloop]);
+-					if (rc) {
+-						shpchp_destroy_resource_list (&temp_resources);
+-						return_resource(&(resources->bus_head), hold_bus_node);
+-						return_resource(&(resources->io_head), hold_IO_node);
+-						return_resource(&(resources->mem_head), hold_mem_node);
+-						return_resource(&(resources->p_mem_head), hold_p_mem_node);
+-						return rc;
+-					}
+-				}
+-			}	/* end of for loop */
+-		}
+-
+-		/* Return unused bus resources
+-		 * First use the temporary node to store information for the board
+-		 */
+-		if (hold_bus_node && bus_node && temp_resources.bus_head) {
+-			hold_bus_node->length = bus_node->base - hold_bus_node->base;
+-
+-			hold_bus_node->next = func->bus_head;
+-			func->bus_head = hold_bus_node;
+-
+-			temp_byte = (u8)(temp_resources.bus_head->base - 1);
+-
+-			/* set subordinate bus */
+-			dbg("re-set subordinate bus = 0x%x\n", temp_byte);
+-			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
+-
+-			if (temp_resources.bus_head->length == 0) {
+-				kfree(temp_resources.bus_head);
+-				temp_resources.bus_head = NULL;
+-			} else {
+-				dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
+-					func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
+-				return_resource(&(resources->bus_head), temp_resources.bus_head);
+-			}
+-		}
+-
+-		/* If we have IO space available and there is some left,
+-		 * return the unused portion
+-		 */
+-		if (hold_IO_node && temp_resources.io_head) {
+-			io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
+-							       &hold_IO_node, 0x1000);
+-
+-			/* Check if we were able to split something off */
+-			if (io_node) {
+-				hold_IO_node->base = io_node->base + io_node->length;
+-
+-				RES_CHECK(hold_IO_node->base, 8);
+-				temp_byte = (u8)((hold_IO_node->base) >> 8);
+-				rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
+-
+-				return_resource(&(resources->io_head), io_node);
+-			}
+-
+-			io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
+-
+-			/*  Check if we were able to split something off */
+-			if (io_node) {
+-				/* First use the temporary node to store information for the board */
+-				hold_IO_node->length = io_node->base - hold_IO_node->base;
+-
+-				/* If we used any, add it to the board's list */
+-				if (hold_IO_node->length) {
+-					hold_IO_node->next = func->io_head;
+-					func->io_head = hold_IO_node;
+-
+-					RES_CHECK(io_node->base - 1, 8);
+-					temp_byte = (u8)((io_node->base - 1) >> 8);
+-					rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
+-
+-					return_resource(&(resources->io_head), io_node);
+-				} else {
+-					/* it doesn't need any IO */
+-					temp_byte = 0x00;
+-					rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
+-
+-					return_resource(&(resources->io_head), io_node);
+-					kfree(hold_IO_node);
+-				}
+-			} else {
+-				/* it used most of the range */
+-				hold_IO_node->next = func->io_head;
+-				func->io_head = hold_IO_node;
+-			}
+-		} else if (hold_IO_node) {
+-			/* it used the whole range */
+-			hold_IO_node->next = func->io_head;
+-			func->io_head = hold_IO_node;
+-		}
+-
+-		/* If we have memory space available and there is some left,
+-		 * return the unused portion
+-		 */
+-		if (hold_mem_node && temp_resources.mem_head) {
+-			mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
+-
+-			/* Check if we were able to split something off */
+-			if (mem_node) {
+-				hold_mem_node->base = mem_node->base + mem_node->length;
+-
+-				RES_CHECK(hold_mem_node->base, 16);
+-				temp_word = (u32)((hold_mem_node->base) >> 16);
+-				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+-
+-				return_resource(&(resources->mem_head), mem_node);
+-			}
+-
+-			mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
+-
+-			/* Check if we were able to split something off */
+-			if (mem_node) {
+-				/* First use the temporary node to store information for the board */
+-				hold_mem_node->length = mem_node->base - hold_mem_node->base;
+-
+-				if (hold_mem_node->length) {
+-					hold_mem_node->next = func->mem_head;
+-					func->mem_head = hold_mem_node;
+-
+-					/* configure end address */
+-					RES_CHECK(mem_node->base - 1, 16);
+-					temp_word = (u32)((mem_node->base - 1) >> 16);
+-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+-
+-					/* Return unused resources to the pool */
+-					return_resource(&(resources->mem_head), mem_node);
+-				} else {
+-					/* it doesn't need any Mem */
+-					temp_word = 0x0000;
+-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+-
+-					return_resource(&(resources->mem_head), mem_node);
+-					kfree(hold_mem_node);
+-				}
+-			} else {
+-				/* it used most of the range */
+-				hold_mem_node->next = func->mem_head;
+-				func->mem_head = hold_mem_node;
+-			}
+-		} else if (hold_mem_node) {
+-			/* it used the whole range */
+-			hold_mem_node->next = func->mem_head;
+-			func->mem_head = hold_mem_node;
+-		}
+-
+-		/* If we have prefetchable memory space available and there is some 
+-		 * left at the end, return the unused portion
+-		 */
+-		if (hold_p_mem_node && temp_resources.p_mem_head) {
+-			p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
+-								  &hold_p_mem_node, 0x100000L);
+-
+-			/* Check if we were able to split something off */
+-			if (p_mem_node) {
+-				hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
+-
+-				RES_CHECK(hold_p_mem_node->base, 16);
+-				temp_word = (u32)((hold_p_mem_node->base) >> 16);
+-				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+-
+-				return_resource(&(resources->p_mem_head), p_mem_node);
+-			}
+-
+-			p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
+-
+-			/* Check if we were able to split something off */
+-			if (p_mem_node) {
+-				/* First use the temporary node to store information for the board */
+-				hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
+-
+-				/* If we used any, add it to the board's list */
+-				if (hold_p_mem_node->length) {
+-					hold_p_mem_node->next = func->p_mem_head;
+-					func->p_mem_head = hold_p_mem_node;
+-
+-					RES_CHECK(p_mem_node->base - 1, 16);
+-					temp_word = (u32)((p_mem_node->base - 1) >> 16);
+-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+-
+-					return_resource(&(resources->p_mem_head), p_mem_node);
+-				} else {
+-					/* it doesn't need any PMem */
+-					temp_word = 0x0000;
+-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+-
+-					return_resource(&(resources->p_mem_head), p_mem_node);
+-					kfree(hold_p_mem_node);
+-				}
+-			} else {
+-				/* it used the most of the range */
+-				hold_p_mem_node->next = func->p_mem_head;
+-				func->p_mem_head = hold_p_mem_node;
+-			}
+-		} else if (hold_p_mem_node) {
+-			/* it used the whole range */
+-			hold_p_mem_node->next = func->p_mem_head;
+-			func->p_mem_head = hold_p_mem_node;
+-		}
+-
+-		/* We should be configuring an IRQ and the bridge's base address
+-		 * registers if it needs them.  Although we have never seen such
+-		 * a device
+-		 */
+-
+-		shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
+-
+-		dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
+-	} else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
+-		/* Standard device */
+-		u64	base64;
+-		rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+-
+-		if (class_code == PCI_BASE_CLASS_DISPLAY)
+-			return (DEVICE_TYPE_NOT_SUPPORTED);
+-
+-		/* Figure out IO and memory needs */
+-		for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
+-			temp_register = 0xFFFFFFFF;
+-
+-			rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+-			rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
+-			dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register, func->bus, func->device, 
+-				func->function);
+-
+-			if (!temp_register)
+-				continue;
+-
+-			base64 = 0L;
+-			if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
+-				/* Map IO */
+-
+-				/* set base = amount of IO space */
+-				base = temp_register & 0xFFFFFFFC;
+-				base = ~base + 1;
+-
+-				dbg("NEED IO length(0x%x)\n", base);
+-				io_node = get_io_resource(&(resources->io_head),(ulong)base);
+-
+-				/* allocate the resource to the board */
+-				if (io_node) {
+-					dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
+-					base = (u32)io_node->base;
+-					io_node->next = func->io_head;
+-					func->io_head = io_node;
+-				} else {
+-					err("Got NO IO resource(length=0x%x)\n", base);
+-					return -ENOMEM;
+-				}
+-			} else {	/* map MEM */
+-				int prefetchable = 1;
+-				struct pci_resource **res_node = &func->p_mem_head;
+-				char *res_type_str = "PMEM";
+-				u32	temp_register2;
+-
+-				if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
+-					prefetchable = 0;
+-					res_node = &func->mem_head;
+-					res_type_str++;
+-				}
+-
+-				base = temp_register & 0xFFFFFFF0;
+-				base = ~base + 1;
+-
+-				switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
+-				case PCI_BASE_ADDRESS_MEM_TYPE_32:
+-					dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
+-
+-					if (prefetchable && resources->p_mem_head)
+-						mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
+-					else {
+-						if (prefetchable)
+-							dbg("using MEM for PMEM\n");
+-						mem_node=get_resource(&(resources->mem_head), (ulong)base);
+-					}
+-
+-					/* allocate the resource to the board */
+-					if (mem_node) {
+-						base = (u32)mem_node->base; 
+-						mem_node->next = *res_node;
+-						*res_node = mem_node;
+-						dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base, 
+-							mem_node->length);
+-					} else {
+-						err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
+-						return -ENOMEM;
+-					}
+-					break;
+-				case PCI_BASE_ADDRESS_MEM_TYPE_64:
+-					rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
+-					dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2, 
+-						temp_register, base);
+-
+-					if (prefetchable && resources->p_mem_head)
+-						mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
+-					else {
+-						if (prefetchable)
+-							dbg("using MEM for PMEM\n");
+-						mem_node = get_resource(&(resources->mem_head), (ulong)base);
+-					}
+-
+-					/* allocate the resource to the board */
+-					if (mem_node) {
+-						base64 = mem_node->base; 
+-						mem_node->next = *res_node;
+-						*res_node = mem_node;
+-						dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32), 
+-							(u32)base64, mem_node->length);
+-					} else {
+-						err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
+-						return -ENOMEM;
+-					}
+-					break;
+-				default:
+-					dbg("reserved BAR type=0x%x\n", temp_register);
+-					break;
+-				}
+-
+-			}
+-
+-			if (base64) {
+-				rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
+-				cloop += 4;
+-				base64 >>= 32;
+-
+-				if (base64) {
+-					dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
+-					base64 = 0x0L;
+-				}
+-
+-				rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
+-			} else {
+-				rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
+-			}
+-		}		/* End of base register loop */
+-
+-#if defined(CONFIG_X86_64)
+-		/* Figure out which interrupt pin this function uses */
+-		rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte);
+-
+-		/* If this function needs an interrupt and we are behind a bridge
+-		   and the pin is tied to something that's alread mapped,
+-		   set this one the same
+-		 */
+-		if (temp_byte && resources->irqs && 
+-		    (resources->irqs->valid_INT & 
+-		     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
+-			/* We have to share with something already set up */
+-			IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
+-		} else {
+-			/* Program IRQ based on card type */
+-			rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+-
+-			if (class_code == PCI_BASE_CLASS_STORAGE) {
+-				IRQ = shpchp_disk_irq;
+-			} else {
+-				IRQ = shpchp_nic_irq;
+-			}
+-		}
+-
+-		/* IRQ Line */
+-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
+-
+-		if (!behind_bridge) {
+-			rc = shpchp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
+-			if (rc)
+-				return(1);
+-		} else {
+-			/* TBD - this code may also belong in the other clause of this If statement */
+-			resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
+-			resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
+-		}
+-#endif
+-		/* Disable ROM base Address */
+-		rc = pci_bus_write_config_dword (pci_bus, devfn, PCI_ROM_ADDRESS, 0x00);
+-
+-		/* Set HP parameters (Cache Line Size, Latency Timer) */
+-		rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
+-		if (rc)
+-			return rc;
+-
+-		shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
+-
+-		dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
+-	}			/* End of Not-A-Bridge else */
+-	else {
+-		/* It's some strange type of PCI adapter (Cardbus?) */
+-		return(DEVICE_TYPE_NOT_SUPPORTED);
+-	}
+-
+-	func->configured = 1;
+-
+-	return 0;
++	ret = remove_board(p_slot);
++	update_slot_info(p_slot);
++	return ret;
+ }
+ 
+diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
+--- a/drivers/pci/hotplug/shpchp_hpc.c
++++ b/drivers/pci/hotplug/shpchp_hpc.c
+@@ -27,17 +27,10 @@
+  *
+  */
+ 
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+-#include <linux/slab.h>
+-#include <linux/vmalloc.h>
+-#include <linux/interrupt.h>
+-#include <linux/spinlock.h>
+-#include <linux/delay.h>
+ #include <linux/pci.h>
+-#include <asm/system.h>
+ #include "shpchp.h"
+ 
+ #ifdef DEBUG
+@@ -282,7 +275,7 @@ static void start_int_poll_timer(struct 
+ 
+ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u16 cmd_status;
+ 	int retval = 0;
+ 	u16 temp_word;
+@@ -320,7 +313,6 @@ static int shpc_write_cmd(struct slot *s
+ 	 * command. 
+ 	 */
+ 	writew(temp_word, php_ctlr->creg + CMD);
+-	dbg("%s: temp_word written %x\n", __FUNCTION__, temp_word);
+ 
+ 	DBG_LEAVE_ROUTINE 
+ 	return retval;
+@@ -328,7 +320,7 @@ static int shpc_write_cmd(struct slot *s
+ 
+ static int hpc_check_cmd_status(struct controller *ctrl)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
+ 	u16 cmd_status;
+ 	int retval = 0;
+ 
+@@ -368,7 +360,7 @@ static int hpc_check_cmd_status(struct c
+ 
+ static int hpc_get_attention_status(struct slot *slot, u8 *status)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u32 slot_reg;
+ 	u16 slot_status;
+ 	u8 atten_led_state;
+@@ -408,7 +400,7 @@ static int hpc_get_attention_status(stru
+ 
+ static int hpc_get_power_status(struct slot * slot, u8 *status)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u32 slot_reg;
+ 	u16 slot_status;
+ 	u8 slot_state;
+@@ -450,7 +442,7 @@ static int hpc_get_power_status(struct s
+ 
+ static int hpc_get_latch_status(struct slot *slot, u8 *status)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u32 slot_reg;
+ 	u16 slot_status;
+ 
+@@ -473,7 +465,7 @@ static int hpc_get_latch_status(struct s
+ 
+ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u32 slot_reg;
+ 	u16 slot_status;
+ 	u8 card_state;
+@@ -496,7 +488,7 @@ static int hpc_get_adapter_status(struct
+ 
+ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 
+ 	DBG_ENTER_ROUTINE 
+ 	
+@@ -513,7 +505,7 @@ static int hpc_get_prog_int(struct slot 
+ 
+ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u32 slot_reg;
+ 	u16 slot_status, sec_bus_status;
+ 	u8 m66_cap, pcix_cap, pi;
+@@ -594,7 +586,7 @@ static int hpc_get_adapter_speed(struct 
+ 
+ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u16 sec_bus_status;
+ 	u8 pi;
+ 	int retval = 0;
+@@ -623,7 +615,7 @@ static int hpc_get_mode1_ECC_cap(struct 
+ 
+ static int hpc_query_power_fault(struct slot * slot)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u32 slot_reg;
+ 	u16 slot_status;
+ 	u8 pwr_fault_state, status;
+@@ -647,7 +639,7 @@ static int hpc_query_power_fault(struct 
+ 
+ static int hpc_set_attention_status(struct slot *slot, u8 value)
+ {
+-	struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u8 slot_cmd = 0;
+ 	int rc = 0;
+ 
+@@ -683,7 +675,7 @@ static int hpc_set_attention_status(stru
+ 
+ static void hpc_set_green_led_on(struct slot *slot)
+ {
+-	struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u8 slot_cmd;
+ 
+ 	if (!slot->ctrl->hpc_ctlr_handle) {
+@@ -705,7 +697,7 @@ static void hpc_set_green_led_on(struct 
+ 
+ static void hpc_set_green_led_off(struct slot *slot)
+ {
+-	struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u8 slot_cmd;
+ 
+ 	if (!slot->ctrl->hpc_ctlr_handle) {
+@@ -727,7 +719,7 @@ static void hpc_set_green_led_off(struct
+ 
+ static void hpc_set_green_led_blink(struct slot *slot)
+ {
+-	struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u8 slot_cmd;
+ 
+ 	if (!slot->ctrl->hpc_ctlr_handle) {
+@@ -754,7 +746,7 @@ int shpc_get_ctlr_slot_config(struct con
+ 	int *updown,		/* physical_slot_num increament: 1 or -1	*/
+ 	int *flags)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
+ 
+ 	DBG_ENTER_ROUTINE 
+ 
+@@ -776,7 +768,7 @@ int shpc_get_ctlr_slot_config(struct con
+ 
+ static void hpc_release_ctlr(struct controller *ctrl)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
+ 	struct php_ctlr_state_s *p, *p_prev;
+ 
+ 	DBG_ENTER_ROUTINE 
+@@ -796,10 +788,8 @@ static void hpc_release_ctlr(struct cont
+ 		}
+ 	}
+ 	if (php_ctlr->pci_dev) {
+-		dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
+ 		iounmap(php_ctlr->creg);
+ 		release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0));
+-		dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
+ 		php_ctlr->pci_dev = NULL;
+ 	}
+ 
+@@ -828,7 +818,7 @@ DBG_LEAVE_ROUTINE
+ 
+ static int hpc_power_on_slot(struct slot * slot)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u8 slot_cmd;
+ 	int retval = 0;
+ 
+@@ -859,7 +849,7 @@ static int hpc_power_on_slot(struct slot
+ 
+ static int hpc_slot_enable(struct slot * slot)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u8 slot_cmd;
+ 	int retval = 0;
+ 
+@@ -890,7 +880,7 @@ static int hpc_slot_enable(struct slot *
+ 
+ static int hpc_slot_disable(struct slot * slot)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	u8 slot_cmd;
+ 	int retval = 0;
+ 
+@@ -920,51 +910,12 @@ static int hpc_slot_disable(struct slot 
+ 	return retval;
+ }
+ 
+-static int hpc_enable_all_slots( struct slot *slot )
+-{
+-	int retval = 0;
+-
+-	DBG_ENTER_ROUTINE 
+-	
+-	if (!slot->ctrl->hpc_ctlr_handle) {
+-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
+-		return -1;
+-	}
+-
+-	retval = shpc_write_cmd(slot, 0, SET_ENABLE_ALL);
+-	if (retval) {
+-		err("%s: Write command failed!\n", __FUNCTION__);
+-		return -1;
+-	}
+-
+-	DBG_LEAVE_ROUTINE
+-
+-	return retval;
+-}
+-
+-static int hpc_pwr_on_all_slots(struct slot *slot)
+-{
+-	int retval = 0;
+-
+-	DBG_ENTER_ROUTINE 
+-
+-	retval = shpc_write_cmd(slot, 0, SET_PWR_ON_ALL);
+-
+-	if (retval) {
+-		err("%s: Write command failed!\n", __FUNCTION__);
+-		return -1;
+-	}
+-
+-	DBG_LEAVE_ROUTINE
+-	return retval;
+-}
+-
+ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
+ {
+ 	u8 slot_cmd;
+ 	u8 pi;
+ 	int retval = 0;
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 
+ 	DBG_ENTER_ROUTINE 
+ 	
+@@ -1089,18 +1040,13 @@ static irqreturn_t shpc_isr(int IRQ, voi
+ 
+ 	if (!intr_loc)
+ 		return IRQ_NONE;
+-	dbg("%s: shpc_isr proceeds\n", __FUNCTION__);
+ 	dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); 
+ 
+ 	if(!shpchp_poll_mode) {
+ 		/* Mask Global Interrupt Mask - see implementation note on p. 139 */
+ 		/* of SHPC spec rev 1.0*/
+ 		temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
+-		dbg("%s: Before masking global interrupt, temp_dword = %x\n",
+-			__FUNCTION__, temp_dword); 
+ 		temp_dword |= 0x00000001;
+-		dbg("%s: After masking global interrupt, temp_dword = %x\n",
+-			__FUNCTION__, temp_dword); 
+ 		writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
+ 
+ 		intr_loc2 = readl(php_ctlr->creg + INTR_LOC);  
+@@ -1114,11 +1060,7 @@ static irqreturn_t shpc_isr(int IRQ, voi
+ 		 * Detect bit in Controller SERR-INT register
+ 		 */
+ 		temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
+-		dbg("%s: Before clearing CCIP, temp_dword = %x\n",
+-			__FUNCTION__, temp_dword); 
+ 		temp_dword &= 0xfffeffff;
+-		dbg("%s: After clearing CCIP, temp_dword = %x\n",
+-			__FUNCTION__, temp_dword); 
+ 		writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
+ 		wake_up_interruptible(&ctrl->queue);
+ 	}
+@@ -1126,11 +1068,7 @@ static irqreturn_t shpc_isr(int IRQ, voi
+ 	if ((intr_loc = (intr_loc >> 1)) == 0) {
+ 		/* Unmask Global Interrupt Mask */
+ 		temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
+-		dbg("%s: 1-Before unmasking global interrupt, temp_dword = %x\n",
+-			__FUNCTION__, temp_dword); 
+ 		temp_dword &= 0xfffffffe;
+-		dbg("%s: 1-After unmasking global interrupt, temp_dword = %x\n",
+-			__FUNCTION__, temp_dword); 
+ 		writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
+ 
+ 		return IRQ_NONE;
+@@ -1140,11 +1078,9 @@ static irqreturn_t shpc_isr(int IRQ, voi
+ 	/* To find out which slot has interrupt pending */
+ 		if ((intr_loc >> hp_slot) & 0x01) {
+ 			temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot));
+-			dbg("%s: Slot %x with intr, temp_dword = %x\n",
+-				__FUNCTION__, hp_slot, temp_dword); 
++			dbg("%s: Slot %x with intr, slot register = %x\n",
++				__FUNCTION__, hp_slot, temp_dword);
+ 			temp_byte = (temp_dword >> 16) & 0xFF;
+-			dbg("%s: Slot with intr, temp_byte = %x\n",
+-				__FUNCTION__, temp_byte); 
+ 			if ((php_ctlr->switch_change_callback) && (temp_byte & 0x08))
+ 				schedule_flag += php_ctlr->switch_change_callback(
+ 					hp_slot, php_ctlr->callback_instance_id);
+@@ -1160,8 +1096,6 @@ static irqreturn_t shpc_isr(int IRQ, voi
+ 			
+ 			/* Clear all slot events */
+ 			temp_dword = 0xe01f3fff;
+-			dbg("%s: Clearing slot events, temp_dword = %x\n",
+-				__FUNCTION__, temp_dword); 
+ 			writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot));
+ 
+ 			intr_loc2 = readl(php_ctlr->creg + INTR_LOC);  
+@@ -1171,11 +1105,7 @@ static irqreturn_t shpc_isr(int IRQ, voi
+ 	if (!shpchp_poll_mode) {
+ 		/* Unmask Global Interrupt Mask */
+ 		temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
+-		dbg("%s: 2-Before unmasking global interrupt, temp_dword = %x\n",
+-			__FUNCTION__, temp_dword); 
+ 		temp_dword &= 0xfffffffe;
+-		dbg("%s: 2-After unmasking global interrupt, temp_dword = %x\n",
+-			__FUNCTION__, temp_dword); 
+ 		writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
+ 	}
+ 	
+@@ -1184,7 +1114,7 @@ static irqreturn_t shpc_isr(int IRQ, voi
+ 
+ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
+ 	int retval = 0;
+ 	u8 pi;
+@@ -1253,7 +1183,7 @@ static int hpc_get_max_bus_speed (struct
+ 
+ static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
+ {
+-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
++	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+ 	enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
+ 	u16 sec_bus_status;
+ 	int retval = 0;
+@@ -1367,8 +1297,6 @@ static struct hpc_ops shpchp_hpc_ops = {
+ 	.power_on_slot			= hpc_power_on_slot,
+ 	.slot_enable			= hpc_slot_enable,
+ 	.slot_disable			= hpc_slot_disable,
+-	.enable_all_slots		= hpc_enable_all_slots,
+-	.pwr_on_all_slots		= hpc_pwr_on_all_slots,
+ 	.set_bus_speed_mode		= hpc_set_bus_speed_mode,	  
+ 	.set_attention_status	= hpc_set_attention_status,
+ 	.get_power_status		= hpc_get_power_status,
+@@ -1391,12 +1319,7 @@ static struct hpc_ops shpchp_hpc_ops = {
+ 	.check_cmd_status		= hpc_check_cmd_status,
+ };
+ 
+-int shpc_init(struct controller * ctrl,
+-		struct pci_dev * pdev,
+-		php_intr_callback_t attention_button_callback,
+-		php_intr_callback_t switch_change_callback,
+-		php_intr_callback_t presence_change_callback,
+-		php_intr_callback_t power_fault_callback)
++int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
+ {
+ 	struct php_ctlr_state_s *php_ctlr, *p;
+ 	void *instance_id = ctrl;
+@@ -1405,7 +1328,6 @@ int shpc_init(struct controller * ctrl,
+ 	static int first = 1;
+ 	u32 shpc_cap_offset, shpc_base_offset;
+ 	u32 tempdword, slot_reg;
+-	u16 vendor_id, device_id;
+ 	u8 i;
+ 
+ 	DBG_ENTER_ROUTINE
+@@ -1422,21 +1344,8 @@ int shpc_init(struct controller * ctrl,
+ 
+ 	php_ctlr->pci_dev = pdev;	/* save pci_dev in context */
+ 
+-	rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
+-	dbg("%s: Vendor ID: %x\n",__FUNCTION__, vendor_id);
+-	if (rc) {
+-		err("%s: unable to read PCI configuration data\n", __FUNCTION__);
+-		goto abort_free_ctlr;
+-	}
+-
+-	rc = pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id);
+-	dbg("%s: Device ID: %x\n",__FUNCTION__, device_id);
+-	if (rc) {
+-		err("%s: unable to read PCI configuration data\n", __FUNCTION__);
+-		goto abort_free_ctlr;
+-	}
+-
+-	if ((vendor_id == PCI_VENDOR_ID_AMD) || (device_id == PCI_DEVICE_ID_AMD_GOLAM_7450)) {
++	if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
++				PCI_DEVICE_ID_AMD_GOLAM_7450)) {
+ 		shpc_base_offset = 0;  /* amd shpc driver doesn't use this; assume 0 */
+ 	} else {
+ 		if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) {
+@@ -1469,7 +1378,8 @@ int shpc_init(struct controller * ctrl,
+ 				err("%s : pci_read_config_dword failed\n", __FUNCTION__);
+ 				goto abort_free_ctlr;
+ 			}
+-			dbg("%s: offset %d: tempdword %x\n", __FUNCTION__,i, tempdword);
++			dbg("%s: offset %d: value %x\n", __FUNCTION__,i,
++					tempdword);
+ 		}
+ 	}
+ 
+@@ -1478,13 +1388,6 @@ int shpc_init(struct controller * ctrl,
+ 		first = 0;
+ 	}
+ 
+-	dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number, PCI_SLOT(pdev->devfn), 
+-		PCI_FUNC(pdev->devfn), pdev->irq);
+-	for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
+-		if (pci_resource_len(pdev, rc) > 0)
+-			dbg("pci resource[%d] start=0x%lx(len=0x%lx), shpc_base_offset %x\n", rc,
+-				pci_resource_start(pdev, rc), pci_resource_len(pdev, rc), shpc_base_offset);
+-
+ 	info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, 
+ 		pdev->subsystem_device);
+ 	
+@@ -1504,7 +1407,6 @@ int shpc_init(struct controller * ctrl,
+ 		goto abort_free_ctlr;
+ 	}
+ 	dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
+-	dbg("%s: physical addr %p\n", __FUNCTION__, (void*)pci_resource_start(pdev, 0));
+ 
+ 	init_MUTEX(&ctrl->crit_sect);
+ 	/* Setup wait queue */
+@@ -1512,13 +1414,10 @@ int shpc_init(struct controller * ctrl,
+ 
+ 	/* Find the IRQ */
+ 	php_ctlr->irq = pdev->irq;
+-	dbg("HPC interrupt = %d\n", php_ctlr->irq);
+-
+-	/* Save interrupt callback info */
+-	php_ctlr->attention_button_callback = attention_button_callback;
+-	php_ctlr->switch_change_callback = switch_change_callback;
+-	php_ctlr->presence_change_callback = presence_change_callback;
+-	php_ctlr->power_fault_callback = power_fault_callback;
++	php_ctlr->attention_button_callback = shpchp_handle_attention_button,
++	php_ctlr->switch_change_callback = shpchp_handle_switch_change;
++	php_ctlr->presence_change_callback = shpchp_handle_presence_change;
++	php_ctlr->power_fault_callback = shpchp_handle_power_fault;
+ 	php_ctlr->callback_instance_id = instance_id;
+ 
+ 	/* Return PCI Controller Info */
+@@ -1556,7 +1455,6 @@ int shpc_init(struct controller * ctrl,
+ 		if (rc) {
+ 			info("Can't get msi for the hotplug controller\n");
+ 			info("Use INTx for the hotplug controller\n");
+-			dbg("%s: rc = %x\n", __FUNCTION__, rc);
+ 		} else
+ 			php_ctlr->irq = pdev->irq;
+ 		
+@@ -1566,9 +1464,11 @@ int shpc_init(struct controller * ctrl,
+ 			err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
+ 			goto abort_free_ctlr;
+ 		}
+-		/* Execute OSHP method here */
+ 	}
+-	dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__);
++	dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__,
++			pdev->bus->number, PCI_SLOT(pdev->devfn),
++			PCI_FUNC(pdev->devfn), pdev->irq);
++	get_hp_hw_control_from_firmware(pdev);
+ 
+ 	/*  Add this HPC instance into the HPC list */
+ 	spin_lock(&list_lock);
+@@ -1607,7 +1507,6 @@ int shpc_init(struct controller * ctrl,
+ 		dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
+ 	}
+ 
+-	dbg("%s: Leaving shpc_init\n", __FUNCTION__);
+ 	DBG_LEAVE_ROUTINE
+ 	return 0;
+ 
+diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
+--- a/drivers/pci/hotplug/shpchp_pci.c
++++ b/drivers/pci/hotplug/shpchp_pci.c
+@@ -27,784 +27,151 @@
+  *
+  */
+ 
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+-#include <linux/slab.h>
+-#include <linux/workqueue.h>
+-#include <linux/proc_fs.h>
+ #include <linux/pci.h>
+ #include "../pci.h"
+ #include "shpchp.h"
+-#ifndef CONFIG_IA64
+-#include "../../../arch/i386/pci/pci.h"    /* horrible hack showing how processor dependant we are... */
+-#endif
+ 
+-int shpchp_configure_device (struct controller* ctrl, struct pci_func* func)  
++void program_fw_provided_values(struct pci_dev *dev)
+ {
+-	unsigned char bus;
+-	struct pci_bus *child;
+-	int num;
+-
+-	if (func->pci_dev == NULL)
+-		func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
+-
+-	/* Still NULL ? Well then scan for it ! */
+-	if (func->pci_dev == NULL) {
+-		num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
+-		if (num) {
+-			dbg("%s: subordiante %p number %x\n", __FUNCTION__, ctrl->pci_dev->subordinate,
+-				ctrl->pci_dev->subordinate->number);
+-			pci_bus_add_devices(ctrl->pci_dev->subordinate);
+-		}
+-		
+-		func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
+-		if (func->pci_dev == NULL) {
+-			dbg("ERROR: pci_dev still null\n");
+-			return 0;
+-		}
+-	}
+-
+-	if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+-		pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
+-		child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
+-		pci_do_scan_bus(child);
+-
+-	}
+-
++	u16 pci_cmd, pci_bctl;
++	struct pci_dev *cdev;
++	struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */
++
++	/* Program hpp values for this device */
++	if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
++			(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
++			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
++		return;
++
++	get_hp_params_from_firmware(dev, &hpp);
++
++	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size);
++	pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer);
++	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
++	if (hpp.enable_serr)
++		pci_cmd |= PCI_COMMAND_SERR;
++	else
++		pci_cmd &= ~PCI_COMMAND_SERR;
++	if (hpp.enable_perr)
++		pci_cmd |= PCI_COMMAND_PARITY;
++	else
++		pci_cmd &= ~PCI_COMMAND_PARITY;
++	pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
++
++	/* Program bridge control value and child devices */
++	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
++		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
++				hpp.latency_timer);
++		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
++		if (hpp.enable_serr)
++			pci_bctl |= PCI_BRIDGE_CTL_SERR;
++		else
++			pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
++		if (hpp.enable_perr)
++			pci_bctl |= PCI_BRIDGE_CTL_PARITY;
++		else
++			pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
++		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
++		if (dev->subordinate) {
++			list_for_each_entry(cdev, &dev->subordinate->devices,
++					bus_list)
++				program_fw_provided_values(cdev);
++		}
++	}
++}
++
++int shpchp_configure_device(struct slot *p_slot)
++{
++	struct pci_dev *dev;
++	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
++	int num, fn;
++
++	dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0));
++	if (dev) {
++		err("Device %s already exists at %x:%x, cannot hot-add\n",
++				pci_name(dev), p_slot->bus, p_slot->device);
++		return -EINVAL;
++	}
++
++	num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
++	if (num == 0) {
++		err("No new device found\n");
++		return -ENODEV;
++	}
++
++	for (fn = 0; fn < 8; fn++) {
++		if (!(dev = pci_find_slot(p_slot->bus,
++					PCI_DEVFN(p_slot->device, fn))))
++			continue;
++		if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
++			err("Cannot hot-add display device %s\n",
++					pci_name(dev));
++			continue;
++		}
++		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
++				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
++			/* Find an unused bus number for the new bridge */
++			struct pci_bus *child;
++			unsigned char busnr, start = parent->secondary;
++			unsigned char end = parent->subordinate;
++			for (busnr = start; busnr <= end; busnr++) {
++				if (!pci_find_bus(pci_domain_nr(parent),
++							busnr))
++					break;
++			}
++			if (busnr >= end) {
++				err("No free bus for hot-added bridge\n");
++				continue;
++			}
++			child = pci_add_new_bus(parent, dev, busnr);
++			if (!child) {
++				err("Cannot add new bus for %s\n",
++						pci_name(dev));
++				continue;
++			}
++			child->subordinate = pci_do_scan_bus(child);
++			pci_bus_size_bridges(child);
++		}
++		program_fw_provided_values(dev);
++	}
++
++	pci_bus_assign_resources(parent);
++	pci_bus_add_devices(parent);
++	pci_enable_bridges(parent);
+ 	return 0;
+ }
+ 
+-
+-int shpchp_unconfigure_device(struct pci_func* func) 
++int shpchp_unconfigure_device(struct slot *p_slot)
+ {
+ 	int rc = 0;
+ 	int j;
++	u8 bctl = 0;
+ 	
+-	dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
+-				func->device, func->function);
++	dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device);
+ 
+ 	for (j=0; j<8 ; j++) {
+-		struct pci_dev* temp = pci_find_slot(func->bus,
+-				(func->device << 3) | j);
+-		if (temp) {
+-			pci_remove_bus_device(temp);
+-		}
+-	}
+-	return rc;
+-}
+-
+-/*
+- * shpchp_set_irq
+- *
+- * @bus_num: bus number of PCI device
+- * @dev_num: device number of PCI device
+- * @slot: pointer to u8 where slot number will be returned
+- */
+-int shpchp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
+-{
+-#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
+-	int rc;
+-	u16 temp_word;
+-	struct pci_dev fakedev;
+-	struct pci_bus fakebus;
+-
+-	fakedev.devfn = dev_num << 3;
+-	fakedev.bus = &fakebus;
+-	fakebus.number = bus_num;
+-	dbg("%s: dev %d, bus %d, pin %d, num %d\n",
+-	    __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
+-	rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
+-	dbg("%s: rc %d\n", __FUNCTION__, rc);
+-	if (!rc)
+-		return !rc;
+-
+-	/* set the Edge Level Control Register (ELCR) */
+-	temp_word = inb(0x4d0);
+-	temp_word |= inb(0x4d1) << 8;
+-
+-	temp_word |= 0x01 << irq_num;
+-
+-	/* This should only be for x86 as it sets the Edge Level Control Register */
+-	outb((u8) (temp_word & 0xFF), 0x4d0);
+-	outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
+-#endif
+-	return 0;
+-}
+-
+-/* More PCI configuration routines; this time centered around hotplug controller */
+-
+-
+-/*
+- * shpchp_save_config
+- *
+- * Reads configuration for all slots in a PCI bus and saves info.
+- *
+- * Note:  For non-hot plug busses, the slot # saved is the device #
+- *
+- * returns 0 if success
+- */
+-int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
+-{
+-	int rc;
+-	u8 class_code;
+-	u8 header_type;
+-	u32 ID;
+-	u8 secondary_bus;
+-	struct pci_func *new_slot;
+-	int sub_bus;
+-	int FirstSupported;
+-	int LastSupported;
+-	int max_functions;
+-	int function;
+-	u8 DevError;
+-	int device = 0;
+-	int cloop = 0;
+-	int stop_it;
+-	int index;
+-	int is_hot_plug = num_ctlr_slots || first_device_num;
+-	struct pci_bus lpci_bus, *pci_bus;
+-
+-	dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
+-				num_ctlr_slots, first_device_num);
+-
+-	memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-
+-	dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
+-				num_ctlr_slots, first_device_num);
+-
+-	/*   Decide which slots are supported */
+-	if (is_hot_plug) {
+-		/*********************************
+-		 *  is_hot_plug is the slot mask
+-		 *********************************/
+-		FirstSupported = first_device_num;
+-		LastSupported = FirstSupported + num_ctlr_slots - 1;
+-	} else {
+-		FirstSupported = 0;
+-		LastSupported = 0x1F;
+-	}
+-
+-	dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
+-					LastSupported);
+-
+-	/*   Save PCI configuration space for all devices in supported slots */
+-	pci_bus->number = busnumber;
+-	for (device = FirstSupported; device <= LastSupported; device++) {
+-		ID = 0xFFFFFFFF;
+-		rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
+-					PCI_VENDOR_ID, &ID);
+-
+-		if (ID != 0xFFFFFFFF) {	  /*  device in slot */
+-			rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
+-					0x0B, &class_code);
+-			if (rc)
+-				return rc;
+-
+-			rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
+-					PCI_HEADER_TYPE, &header_type);
+-			if (rc)
+-				return rc;
+-
+-			dbg("class_code = %x, header_type = %x\n", class_code, header_type);
+-
+-			/* If multi-function device, set max_functions to 8 */
+-			if (header_type & 0x80)
+-				max_functions = 8;
+-			else
+-				max_functions = 1;
+-
+-			function = 0;
+-
+-			do {
+-				DevError = 0;
+-
+-				if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {   /* P-P Bridge */
+-					/* Recurse the subordinate bus
+-					 * get the subordinate bus number
+-					 */
+-					rc = pci_bus_read_config_byte(pci_bus,
+-						PCI_DEVFN(device, function), 
+-						PCI_SECONDARY_BUS, &secondary_bus);
+-					if (rc) {
+-						return rc;
+-					} else {
+-						sub_bus = (int) secondary_bus;
+-
+-						/* Save secondary bus cfg spc with this recursive call. */
+-						rc = shpchp_save_config(ctrl, sub_bus, 0, 0);
+-						if (rc)
+-							return rc;
+-					}
+-				}
+-
+-				index = 0;
+-				new_slot = shpchp_slot_find(busnumber, device, index++);
+-
+-				dbg("new_slot = %p\n", new_slot);
+-
+-				while (new_slot && (new_slot->function != (u8) function)) {
+-					new_slot = shpchp_slot_find(busnumber, device, index++);
+-					dbg("new_slot = %p\n", new_slot);
+-				}
+-				if (!new_slot) {
+-					/* Setup slot structure. */
+-					new_slot = shpchp_slot_create(busnumber);
+-					dbg("new_slot = %p\n", new_slot);
+-
+-					if (new_slot == NULL)
+-						return(1);
+-				}
+-
+-				new_slot->bus = (u8) busnumber;
+-				new_slot->device = (u8) device;
+-				new_slot->function = (u8) function;
+-				new_slot->is_a_board = 1;
+-				new_slot->switch_save = 0x10;
+-				new_slot->pwr_save = 1;
+-				/* In case of unsupported board */
+-				new_slot->status = DevError;
+-				new_slot->pci_dev = pci_find_slot(new_slot->bus,
+-					(new_slot->device << 3) | new_slot->function);
+-				dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
+-
+-				for (cloop = 0; cloop < 0x20; cloop++) {
+-					rc = pci_bus_read_config_dword(pci_bus,
+-						PCI_DEVFN(device, function), 
+-						cloop << 2,
+-						(u32 *) &(new_slot->config_space [cloop]));
+-					/* dbg("new_slot->config_space[%x] = %x\n",
+-						cloop, new_slot->config_space[cloop]); */
+-					if (rc)
+-						return rc;
+-				}
+-
+-				function++;
+-
+-				stop_it = 0;
+-
+-				/*  this loop skips to the next present function
+-				 *  reading in Class Code and Header type.
+-				 */
+-
+-				while ((function < max_functions)&&(!stop_it)) {
+-					rc = pci_bus_read_config_dword(pci_bus,
+-						PCI_DEVFN(device, function),
+-						PCI_VENDOR_ID, &ID);
+-
+-					if (ID == 0xFFFFFFFF) {  /* nothing there. */
+-						function++;
+-						dbg("Nothing there\n");
+-					} else {  /* Something there */
+-						rc = pci_bus_read_config_byte(pci_bus,
+-							PCI_DEVFN(device, function), 
+-							0x0B, &class_code);
+-						if (rc)
+-							return rc;
+-
+-						rc = pci_bus_read_config_byte(pci_bus,
+-							PCI_DEVFN(device, function), 
+-							PCI_HEADER_TYPE, &header_type);
+-						if (rc)
+-							return rc;
+-
+-						dbg("class_code = %x, header_type = %x\n",
+-							class_code, header_type);
+-						stop_it++;
+-					}
+-				}
+-
+-			} while (function < max_functions);
+-			/* End of IF (device in slot?) */
+-		} else if (is_hot_plug) {
+-			/* Setup slot structure with entry for empty slot */
+-			new_slot = shpchp_slot_create(busnumber);
+-
+-			if (new_slot == NULL) {
+-				return(1);
+-			}
+-			dbg("new_slot = %p\n", new_slot);
+-
+-			new_slot->bus = (u8) busnumber;
+-			new_slot->device = (u8) device;
+-			new_slot->function = 0;
+-			new_slot->is_a_board = 0;
+-			new_slot->presence_save = 0;
+-			new_slot->switch_save = 0;
+-		}
+-	}			/* End of FOR loop */
+-
+-	return(0);
+-}
+-
+-
+-/*
+- * shpchp_save_slot_config
+- *
+- * Saves configuration info for all PCI devices in a given slot
+- * including subordinate busses.
+- *
+- * returns 0 if success
+- */
+-int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
+-{
+-	int rc;
+-	u8 class_code;
+-	u8 header_type;
+-	u32 ID;
+-	u8 secondary_bus;
+-	int sub_bus;
+-	int max_functions;
+-	int function;
+-	int cloop = 0;
+-	int stop_it;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	pci_bus->number = new_slot->bus;
+-
+-	ID = 0xFFFFFFFF;
+-
+-	pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
+-					PCI_VENDOR_ID, &ID);
+-
+-	if (ID != 0xFFFFFFFF) {	  /*  device in slot */
+-		pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
+-					0x0B, &class_code);
+-
+-		pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
+-					PCI_HEADER_TYPE, &header_type);
+-
+-		if (header_type & 0x80)	/* Multi-function device */
+-			max_functions = 8;
+-		else
+-			max_functions = 1;
+-
+-		function = 0;
+-
+-		do {
+-			if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  /* PCI-PCI Bridge */
+-				/*  Recurse the subordinate bus */
+-				pci_bus_read_config_byte(pci_bus,
+-					PCI_DEVFN(new_slot->device, function), 
+-					PCI_SECONDARY_BUS, &secondary_bus);
+-
+-				sub_bus = (int) secondary_bus;
+-
+-				/* Save the config headers for the secondary bus. */
+-				rc = shpchp_save_config(ctrl, sub_bus, 0, 0);
+-
+-				if (rc)
+-					return rc;
+-
+-			}	/* End of IF */
+-
+-			new_slot->status = 0;
+-
+-			for (cloop = 0; cloop < 0x20; cloop++) {
+-				pci_bus_read_config_dword(pci_bus,
+-					PCI_DEVFN(new_slot->device, function), 
+-					cloop << 2,
+-					(u32 *) &(new_slot->config_space [cloop]));
+-			}
+-
+-			function++;
+-
+-			stop_it = 0;
+-
+-			/*  this loop skips to the next present function
+-			 *  reading in the Class Code and the Header type.
+-			 */
+-
+-			while ((function < max_functions) && (!stop_it)) {
+-				pci_bus_read_config_dword(pci_bus,
+-					PCI_DEVFN(new_slot->device, function),
+-					PCI_VENDOR_ID, &ID);
+-
+-				if (ID == 0xFFFFFFFF) {	 /* nothing there. */
+-					function++;
+-				} else {  /* Something there */
+-					pci_bus_read_config_byte(pci_bus,
+-						PCI_DEVFN(new_slot->device, function),
+-						0x0B, &class_code);
+-
+-					pci_bus_read_config_byte(pci_bus,
+-						PCI_DEVFN(new_slot->device, function),
+-						PCI_HEADER_TYPE, &header_type);
+-
+-					stop_it++;
+-				}
++		struct pci_dev* temp = pci_find_slot(p_slot->bus,
++				(p_slot->device << 3) | j);
++		if (!temp)
++			continue;
++		if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
++			err("Cannot remove display device %s\n",
++					pci_name(temp));
++			continue;
++		}
++		if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
++			pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
++			if (bctl & PCI_BRIDGE_CTL_VGA) {
++				err("Cannot remove display device %s\n",
++						pci_name(temp));
++				continue;
+ 			}
+-
+-		} while (function < max_functions);
+-	}			/* End of IF (device in slot?) */
+-	else {
+-		return 2;
+-	}
+-
+-	return 0;
+-}
+-
+-
+-/*
+- * shpchp_save_used_resources
+- *
+- * Stores used resource information for existing boards.  this is
+- * for boards that were in the system when this driver was loaded.
+- * this function is for hot plug ADD
+- *
+- * returns 0 if success
+- * if disable  == 1(DISABLE_CARD),
+- *  it loops for all functions of the slot and disables them.
+- * else, it just get resources of the function and return.
+- */
+-int shpchp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
+-{
+-	u8 cloop;
+-	u8 header_type;
+-	u8 secondary_bus;
+-	u8 temp_byte;
+-	u16 command;
+-	u16 save_command;
+-	u16 w_base, w_length;
+-	u32 temp_register;
+-	u32 save_base;
+-	u32 base, length;
+-	u64 base64 = 0;
+-	int index = 0;
+-	unsigned int devfn;
+-	struct pci_resource *mem_node = NULL;
+-	struct pci_resource *p_mem_node = NULL;
+-	struct pci_resource *t_mem_node;
+-	struct pci_resource *io_node;
+-	struct pci_resource *bus_node;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-
+-	if (disable)
+-		func = shpchp_slot_find(func->bus, func->device, index++);
+-
+-	while ((func != NULL) && func->is_a_board) {
+-		pci_bus->number = func->bus;
+-		devfn = PCI_DEVFN(func->device, func->function);
+-
+-		/* Save the command register */
+-		pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
+-
+-		if (disable) {
+-			/* disable card */
+-			command = 0x00;
+-			pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
+-		}
+-
+-		/* Check for Bridge */
+-		pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+-
+-		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {     /* PCI-PCI Bridge */
+-			dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
+-					func->bus, func->device, save_command);
+-			if (disable) {
+-				/* Clear Bridge Control Register */
+-				command = 0x00;
+-				pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
+-			}
+-
+-			pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
+-			pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
+-
+-			bus_node = kmalloc(sizeof(struct pci_resource),
+-						GFP_KERNEL);
+-			if (!bus_node)
+-				return -ENOMEM;
+-
+-			bus_node->base = (ulong)secondary_bus;
+-			bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
+-
+-			bus_node->next = func->bus_head;
+-			func->bus_head = bus_node;
+-
+-			/* Save IO base and Limit registers */
+-			pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
+-			base = temp_byte;
+-			pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
+-			length = temp_byte;
+-
+-			if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
+-				io_node = kmalloc(sizeof(struct pci_resource),
+-							GFP_KERNEL);
+-				if (!io_node)
+-					return -ENOMEM;
+-
+-				io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
+-				io_node->length = (ulong)(length - base + 0x10) << 8;
+-
+-				io_node->next = func->io_head;
+-				func->io_head = io_node;
+-			}
+-
+-			/* Save memory base and Limit registers */
+-			pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
+-			pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
+-
+-			if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
+-				mem_node = kmalloc(sizeof(struct pci_resource),
+-						GFP_KERNEL);
+-				if (!mem_node)
+-					return -ENOMEM;
+-
+-				mem_node->base = (ulong)w_base << 16;
+-				mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
+-
+-				mem_node->next = func->mem_head;
+-				func->mem_head = mem_node;
+-			}
+-			/* Save prefetchable memory base and Limit registers */
+-			pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
+-			pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
+-
+-			if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
+-				p_mem_node = kmalloc(sizeof(struct pci_resource),
+-						GFP_KERNEL);
+-				if (!p_mem_node)
+-					return -ENOMEM;
+-
+-				p_mem_node->base = (ulong)w_base << 16;
+-				p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
+-
+-				p_mem_node->next = func->p_mem_head;
+-				func->p_mem_head = p_mem_node;
+-			}
+-		} else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
+-			dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
+-					func->bus, func->device, save_command);
+-
+-			/* Figure out IO and memory base lengths */
+-			for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
+-				pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
+-
+-				temp_register = 0xFFFFFFFF;
+-				pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
+-				pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
+-
+-				if (!disable)
+-					pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
+-
+-				if (!temp_register)
+-					continue;
+-
+-				base = temp_register;
+-
+-				if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
+-						(!disable || (save_command & PCI_COMMAND_IO))) {
+-					/* IO base */
+-					/* set temp_register = amount of IO space requested */
+-					base = base & 0xFFFFFFFCL;
+-					base = (~base) + 1;
+-
+-					io_node =  kmalloc(sizeof (struct pci_resource),
+-								GFP_KERNEL);
+-					if (!io_node)
+-						return -ENOMEM;
+-
+-					io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
+-					io_node->length = (ulong)base;
+-					dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
+-						io_node->base, io_node->length);
+-
+-					io_node->next = func->io_head;
+-					func->io_head = io_node;
+-				} else {  /* map Memory */
+-					int prefetchable = 1;
+-					/* struct pci_resources **res_node; */
+-					char *res_type_str = "PMEM";
+-					u32 temp_register2;
+-
+-					t_mem_node = kmalloc(sizeof (struct pci_resource),
+-								GFP_KERNEL);
+-					if (!t_mem_node)
+-						return -ENOMEM;
+-
+-					if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
+-							(!disable || (save_command & PCI_COMMAND_MEMORY))) {
+-						prefetchable = 0;
+-						mem_node = t_mem_node;
+-						res_type_str++;
+-					} else
+-						p_mem_node = t_mem_node;
+-
+-					base = base & 0xFFFFFFF0L;
+-					base = (~base) + 1;
+-
+-					switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
+-					case PCI_BASE_ADDRESS_MEM_TYPE_32:
+-						if (prefetchable) {
+-							p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
+-							p_mem_node->length = (ulong)base;
+-							dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
+-								res_type_str, 
+-								p_mem_node->base,
+-								p_mem_node->length);
+-
+-							p_mem_node->next = func->p_mem_head;
+-							func->p_mem_head = p_mem_node;
+-						} else {
+-							mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
+-							mem_node->length = (ulong)base;
+-							dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
+-								res_type_str, 
+-								mem_node->base,
+-								mem_node->length);
+-
+-							mem_node->next = func->mem_head;
+-							func->mem_head = mem_node;
+-						}
+-						break;
+-					case PCI_BASE_ADDRESS_MEM_TYPE_64:
+-						pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
+-						base64 = temp_register2;
+-						base64 = (base64 << 32) | save_base;
+-
+-						if (temp_register2) {
+-							dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n", 
+-								res_type_str, temp_register2, (u32)base64);
+-							base64 &= 0x00000000FFFFFFFFL;
+-						}
+-
+-						if (prefetchable) {
+-							p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
+-							p_mem_node->length = base;
+-							dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
+-								res_type_str, 
+-								p_mem_node->base,
+-								p_mem_node->length);
+-
+-							p_mem_node->next = func->p_mem_head;
+-							func->p_mem_head = p_mem_node;
+-						} else {
+-							mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
+-							mem_node->length = base;
+-							dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
+-								res_type_str, 
+-								mem_node->base,
+-								mem_node->length);
+-
+-							mem_node->next = func->mem_head;
+-							func->mem_head = mem_node;
+-						}
+-						cloop += 4;
+-						break;
+-					default:
+-						dbg("asur: reserved BAR type=0x%x\n",
+-							temp_register);
+-						break;
+-					}
+-				} 
+-			}	/* End of base register loop */
+-		} else {	/* Some other unknown header type */
+-			dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
+-					func->bus, func->device);
+ 		}
+-
+-		/* find the next device in this slot */
+-		if (!disable)
+-			break;
+-		func = shpchp_slot_find(func->bus, func->device, index++);
++		pci_remove_bus_device(temp);
+ 	}
+-
+-	return 0;
+-}
+-
+-/**
+- * kfree_resource_list: release memory of all list members
+- * @res: resource list to free
+- */
+-static inline void
+-return_resource_list(struct pci_resource **func, struct pci_resource **res)
+-{
+-	struct pci_resource *node;
+-	struct pci_resource *t_node;
+-
+-	node = *func;
+-	*func = NULL;
+-	while (node) {
+-		t_node = node->next;
+-		return_resource(res, node);
+-		node = t_node;
+-	}
+-}
+-
+-/*
+- * shpchp_return_board_resources
+- *
+- * this routine returns all resources allocated to a board to
+- * the available pool.
+- *
+- * returns 0 if success
+- */
+-int shpchp_return_board_resources(struct pci_func * func,
+-					struct resource_lists * resources)
+-{
+-	int rc;
+-	dbg("%s\n", __FUNCTION__);
+-
+-	if (!func)
+-		return 1;
+-
+-	return_resource_list(&(func->io_head),&(resources->io_head));
+-	return_resource_list(&(func->mem_head),&(resources->mem_head));
+-	return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
+-	return_resource_list(&(func->bus_head),&(resources->bus_head));
+-
+-	rc = shpchp_resource_sort_and_combine(&(resources->mem_head));
+-	rc |= shpchp_resource_sort_and_combine(&(resources->p_mem_head));
+-	rc |= shpchp_resource_sort_and_combine(&(resources->io_head));
+-	rc |= shpchp_resource_sort_and_combine(&(resources->bus_head));
+-
+ 	return rc;
+ }
+ 
+-/**
+- * kfree_resource_list: release memory of all list members
+- * @res: resource list to free
+- */
+-static inline void
+-kfree_resource_list(struct pci_resource **r)
+-{
+-	struct pci_resource *res, *tres;
+-
+-	res = *r;
+-	*r = NULL;
+-
+-	while (res) {
+-		tres = res;
+-		res = res->next;
+-		kfree(tres);
+-	}
+-}
+-
+-/**
+- * shpchp_destroy_resource_list: put node back in the resource list
+- * @resources: list to put nodes back
+- */
+-void shpchp_destroy_resource_list(struct resource_lists *resources)
+-{
+-	kfree_resource_list(&(resources->io_head));
+-	kfree_resource_list(&(resources->mem_head));
+-	kfree_resource_list(&(resources->p_mem_head));
+-	kfree_resource_list(&(resources->bus_head));
+-}
+-
+-/**
+- * shpchp_destroy_board_resources: put node back in the resource list
+- * @resources: list to put nodes back
+- */
+-void shpchp_destroy_board_resources(struct pci_func * func)
+-{
+-	kfree_resource_list(&(func->io_head));
+-	kfree_resource_list(&(func->mem_head));
+-	kfree_resource_list(&(func->p_mem_head));
+-	kfree_resource_list(&(func->bus_head));
+-}
+diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
+--- a/drivers/pci/hotplug/shpchp_sysfs.c
++++ b/drivers/pci/hotplug/shpchp_sysfs.c
+@@ -26,12 +26,9 @@
+  *
+  */
+ 
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+-#include <linux/proc_fs.h>
+-#include <linux/workqueue.h>
+ #include <linux/pci.h>
+ #include "shpchp.h"
+ 
+@@ -40,104 +37,60 @@
+ 
+ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)
+ {
+-	struct pci_dev *pci_dev;
+-	struct controller *ctrl;
++	struct pci_dev *pdev;
+ 	char * out = buf;
+-	int index;
+-	struct pci_resource *res;
++	int index, busnr;
++	struct resource *res;
++	struct pci_bus *bus;
+ 
+-	pci_dev = container_of (dev, struct pci_dev, dev);
+-	ctrl = pci_get_drvdata(pci_dev);
++	pdev = container_of (dev, struct pci_dev, dev);
++	bus = pdev->subordinate;
+ 
+ 	out += sprintf(buf, "Free resources: memory\n");
+-	index = 11;
+-	res = ctrl->mem_head;
+-	while (res && index--) {
+-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+-		res = res->next;
++	for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
++		res = bus->resource[index];
++		if (res && (res->flags & IORESOURCE_MEM) &&
++				!(res->flags & IORESOURCE_PREFETCH)) {
++			out += sprintf(out, "start = %8.8lx, length = %8.8lx\n",
++					res->start, (res->end - res->start));
++		}
+ 	}
+ 	out += sprintf(out, "Free resources: prefetchable memory\n");
+-	index = 11;
+-	res = ctrl->p_mem_head;
+-	while (res && index--) {
+-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+-		res = res->next;
++	for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
++		res = bus->resource[index];
++		if (res && (res->flags & IORESOURCE_MEM) &&
++			       (res->flags & IORESOURCE_PREFETCH)) {
++			out += sprintf(out, "start = %8.8lx, length = %8.8lx\n",
++					res->start, (res->end - res->start));
++		}
+ 	}
+ 	out += sprintf(out, "Free resources: IO\n");
+-	index = 11;
+-	res = ctrl->io_head;
+-	while (res && index--) {
+-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+-		res = res->next;
++	for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
++		res = bus->resource[index];
++		if (res && (res->flags & IORESOURCE_IO)) {
++			out += sprintf(out, "start = %8.8lx, length = %8.8lx\n",
++					res->start, (res->end - res->start));
++		}
+ 	}
+ 	out += sprintf(out, "Free resources: bus numbers\n");
+-	index = 11;
+-	res = ctrl->bus_head;
+-	while (res && index--) {
+-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+-		res = res->next;
++	for (busnr = bus->secondary; busnr <= bus->subordinate; busnr++) {
++		if (!pci_find_bus(pci_domain_nr(bus), busnr))
++			break;
+ 	}
++	if (busnr < bus->subordinate)
++		out += sprintf(out, "start = %8.8x, length = %8.8x\n",
++				busnr, (bus->subordinate - busnr));
+ 
+ 	return out - buf;
+ }
+ static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
+ 
+-static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf)
++void shpchp_create_ctrl_files (struct controller *ctrl)
+ {
+-	struct pci_dev *pci_dev;
+-	struct controller *ctrl;
+-	char * out = buf;
+-	int index;
+-	struct pci_resource *res;
+-	struct pci_func *new_slot;
+-	struct slot *slot;
+-
+-	pci_dev = container_of (dev, struct pci_dev, dev);
+-	ctrl = pci_get_drvdata(pci_dev);
+-
+-	slot=ctrl->slot;
+-
+-	while (slot) {
+-		new_slot = shpchp_slot_find(slot->bus, slot->device, 0);
+-		if (!new_slot)
+-			break;
+-		out += sprintf(out, "assigned resources: memory\n");
+-		index = 11;
+-		res = new_slot->mem_head;
+-		while (res && index--) {
+-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+-			res = res->next;
+-		}
+-		out += sprintf(out, "assigned resources: prefetchable memory\n");
+-		index = 11;
+-		res = new_slot->p_mem_head;
+-		while (res && index--) {
+-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+-			res = res->next;
+-		}
+-		out += sprintf(out, "assigned resources: IO\n");
+-		index = 11;
+-		res = new_slot->io_head;
+-		while (res && index--) {
+-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+-			res = res->next;
+-		}
+-		out += sprintf(out, "assigned resources: bus numbers\n");
+-		index = 11;
+-		res = new_slot->bus_head;
+-		while (res && index--) {
+-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+-			res = res->next;
+-		}
+-		slot=slot->next;
+-	}
+-
+-	return out - buf;
++	device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
+ }
+-static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
+ 
+-void shpchp_create_ctrl_files (struct controller *ctrl)
++void shpchp_remove_ctrl_files(struct controller *ctrl)
+ {
+-	device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
+-	device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
++	device_remove_file(&ctrl->pci_dev->dev, &dev_attr_ctrl);
+ }
+diff --git a/drivers/pci/hotplug/shpchprm.h b/drivers/pci/hotplug/shpchprm.h
+deleted file mode 100644
+--- a/drivers/pci/hotplug/shpchprm.h
++++ /dev/null
+@@ -1,55 +0,0 @@
+-/*
+- * SHPCHPRM : SHPCHP Resource Manager for ACPI/non-ACPI platform
+- *
+- * Copyright (C) 1995,2001 Compaq Computer Corporation
+- * Copyright (C) 2001 Greg Kroah-Hartman (greg at kroah.com)
+- * Copyright (C) 2001 IBM Corp.
+- * Copyright (C) 2003-2004 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+- *
+- * Send feedback to <greg at kroah.com>, <kristen.c.accardi at intel.com>
+- *
+- */
+-
+-#ifndef _SHPCHPRM_H_
+-#define _SHPCHPRM_H_
+-
+-#ifdef	CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
+-#include "shpchprm_legacy.h"
+-#else
+-#include "shpchprm_nonacpi.h"
+-#endif
+-
+-int shpchprm_init(enum php_ctlr_type ct);
+-void shpchprm_cleanup(void);
+-int shpchprm_print_pirt(void);
+-int shpchprm_find_available_resources(struct controller *ctrl);
+-int shpchprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
+-void shpchprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
+-int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum);
+-
+-#ifdef	DEBUG
+-#define RES_CHECK(this, bits)	\
+-	{ if (((this) & (bits - 1))) \
+-		printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
+-#else
+-#define RES_CHECK(this, bits)
+-#endif
+-
+-#endif				/* _SHPCHPRM_H_ */
+diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
+--- a/drivers/pci/hotplug/shpchprm_acpi.c
++++ b/drivers/pci/hotplug/shpchprm_acpi.c
+@@ -24,91 +24,19 @@
+  *
+  */
+ 
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+-#include <linux/init.h>
+-#include <linux/acpi.h>
+-#include <linux/efi.h>
+-#include <asm/uaccess.h>
+-#include <asm/system.h>
+-#ifdef	CONFIG_IA64
+-#include <asm/iosapic.h>
+-#endif
+ #include <acpi/acpi.h>
+ #include <acpi/acpi_bus.h>
+ #include <acpi/actypes.h>
+ #include "shpchp.h"
+-#include "shpchprm.h"
+-
+-#define	PCI_MAX_BUS		0x100
+-#define	ACPI_STA_DEVICE_PRESENT	0x01
+ 
+ #define	METHOD_NAME__SUN	"_SUN"
+ #define	METHOD_NAME__HPP	"_HPP"
+ #define	METHOD_NAME_OSHP	"OSHP"
+ 
+-#define	PHP_RES_BUS		0xA0
+-#define	PHP_RES_IO		0xA1
+-#define	PHP_RES_MEM		0xA2
+-#define	PHP_RES_PMEM		0xA3
+-
+-#define	BRIDGE_TYPE_P2P		0x00
+-#define	BRIDGE_TYPE_HOST	0x01
+-
+-/* this should go to drivers/acpi/include/ */
+-struct acpi__hpp {
+-	u8	cache_line_size;
+-	u8	latency_timer;
+-	u8	enable_serr;
+-	u8	enable_perr;
+-};
+-
+-struct acpi_php_slot {
+-	struct acpi_php_slot	*next;
+-	struct acpi_bridge	*bridge;
+-	acpi_handle		handle;
+-	int	seg;
+-	int	bus;
+-	int	dev;
+-	int	fun;
+-	u32	sun;
+-	struct pci_resource *mem_head;
+-	struct pci_resource *p_mem_head;
+-	struct pci_resource *io_head;
+-	struct pci_resource *bus_head;
+-	void	*slot_ops;	/* _STA, _EJx, etc */
+-	struct slot *slot;
+-};		/* per func */
+-
+-struct acpi_bridge {
+-	struct acpi_bridge	*parent;
+-	struct acpi_bridge	*next;
+-	struct acpi_bridge	*child;
+-	acpi_handle	handle;
+-	int seg;
+-	int pbus;				/* pdev->bus->number		*/
+-	int pdevice;				/* PCI_SLOT(pdev->devfn)	*/
+-	int pfunction;				/* PCI_DEVFN(pdev->devfn)	*/
+-	int bus;				/* pdev->subordinate->number	*/
+-	struct acpi__hpp		*_hpp;
+-	struct acpi_php_slot	*slots;
+-	struct pci_resource 	*tmem_head;	/* total from crs	*/
+-	struct pci_resource 	*tp_mem_head;	/* total from crs	*/
+-	struct pci_resource 	*tio_head;	/* total from crs	*/
+-	struct pci_resource 	*tbus_head;	/* total from crs	*/
+-	struct pci_resource 	*mem_head;	/* available	*/
+-	struct pci_resource 	*p_mem_head;	/* available	*/
+-	struct pci_resource 	*io_head;	/* available	*/
+-	struct pci_resource 	*bus_head;	/* available	*/
+-	int scanned;
+-	int type;
+-};
+-
+-static struct acpi_bridge *acpi_bridges_head;
+-
+ static u8 * acpi_path_name( acpi_handle	handle)
+ {
+ 	acpi_status		status;
+@@ -124,82 +52,43 @@ static u8 * acpi_path_name( acpi_handle	
+ 		return path_name;	
+ }
+ 
+-static void acpi_get__hpp ( struct acpi_bridge	*ab);
+-static void acpi_run_oshp ( struct acpi_bridge	*ab);
+-
+-static int acpi_add_slot_to_php_slots(
+-	struct acpi_bridge	*ab,
+-	int				bus_num,
+-	acpi_handle		handle,
+-	u32				adr,
+-	u32				sun
+-	)
+-{
+-	struct acpi_php_slot	*aps;
+-	static long	samesun = -1;
+-
+-	aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
+-	if (!aps) {
+-		err ("acpi_shpchprm: alloc for aps fail\n");
+-		return -1;
+-	}
+-	memset(aps, 0, sizeof(struct acpi_php_slot));
+-
+-	aps->handle = handle;
+-	aps->bus = bus_num;
+-	aps->dev = (adr >> 16) & 0xffff;
+-	aps->fun = adr & 0xffff;
+-	aps->sun = sun;
+-
+-	aps->next = ab->slots;	/* cling to the bridge */
+-	aps->bridge = ab;
+-	ab->slots = aps;
+-
+-	ab->scanned += 1;
+-	if (!ab->_hpp)
+-		acpi_get__hpp(ab);
+-
+-	acpi_run_oshp(ab);
+-
+-	if (sun != samesun) {
+-		info("acpi_shpchprm:   Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", aps->sun, ab->seg, 
+-			aps->bus, aps->dev, aps->fun);
+-		samesun = sun;
+-	}
+-	return 0;
+-}
+-
+-static void acpi_get__hpp ( struct acpi_bridge	*ab)
++static acpi_status
++acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
+ {
+ 	acpi_status		status;
+ 	u8			nui[4];
+ 	struct acpi_buffer	ret_buf = { 0, NULL};
+ 	union acpi_object	*ext_obj, *package;
+-	u8			*path_name = acpi_path_name(ab->handle);
++	u8			*path_name = acpi_path_name(handle);
+ 	int			i, len = 0;
+ 
+ 	/* get _hpp */
+-	status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
++	status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
+ 	switch (status) {
+ 	case AE_BUFFER_OVERFLOW:
+ 		ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
+ 		if (!ret_buf.pointer) {
+-			err ("acpi_shpchprm:%s alloc for _HPP fail\n", path_name);
+-			return;
++			err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
++					path_name);
++			return AE_NO_MEMORY;
+ 		}
+-		status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
++		status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
++				NULL, &ret_buf);
+ 		if (ACPI_SUCCESS(status))
+ 			break;
+ 	default:
+ 		if (ACPI_FAILURE(status)) {
+-			err("acpi_shpchprm:%s _HPP fail=0x%x\n", path_name, status);
+-			return;
++			dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
++					path_name, status);
++			return status;
+ 		}
+ 	}
+ 
+ 	ext_obj = (union acpi_object *) ret_buf.pointer;
+ 	if (ext_obj->type != ACPI_TYPE_PACKAGE) {
+-		err ("acpi_shpchprm:%s _HPP obj not a package\n", path_name);
++		err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
++				path_name);
++		status = AE_ERROR;
+ 		goto free_and_return;
+ 	}
+ 
+@@ -212,1353 +101,41 @@ static void acpi_get__hpp ( struct acpi_
+ 			nui[i] = (u8)ext_obj->integer.value;
+ 			break;
+ 		default:
+-			err ("acpi_shpchprm:%s _HPP obj type incorrect\n", path_name);
++			err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
++					path_name);
++			status = AE_ERROR;
+ 			goto free_and_return;
+ 		}
+ 	}
+ 
+-	ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
+-	if (!ab->_hpp) {
+-		err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name);
+-		goto free_and_return;
+-	}
+-	memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
+-
+-	ab->_hpp->cache_line_size	= nui[0];
+-	ab->_hpp->latency_timer		= nui[1];
+-	ab->_hpp->enable_serr		= nui[2];
+-	ab->_hpp->enable_perr		= nui[3];
+-
+-	dbg("  _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
+-	dbg("  _HPP: latency timer  =0x%x\n", ab->_hpp->latency_timer);
+-	dbg("  _HPP: enable SERR    =0x%x\n", ab->_hpp->enable_serr);
+-	dbg("  _HPP: enable PERR    =0x%x\n", ab->_hpp->enable_perr);
++	hpp->cache_line_size = nui[0];
++	hpp->latency_timer = nui[1];
++	hpp->enable_serr = nui[2];
++	hpp->enable_perr = nui[3];
++
++	dbg("  _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
++	dbg("  _HPP: latency timer  =0x%x\n", hpp->latency_timer);
++	dbg("  _HPP: enable SERR    =0x%x\n", hpp->enable_serr);
++	dbg("  _HPP: enable PERR    =0x%x\n", hpp->enable_perr);
+ 
+ free_and_return:
+ 	kfree(ret_buf.pointer);
+-}
+-
+-static void acpi_run_oshp ( struct acpi_bridge	*ab)
+-{
+-	acpi_status		status;
+-	u8			*path_name = acpi_path_name(ab->handle);
+-
+-	/* run OSHP */
+-	status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
+-	if (ACPI_FAILURE(status)) {
+-		err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
+-	} else
+-		dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
+-	return;
+-}
+-
+-static acpi_status acpi_evaluate_crs(
+-	acpi_handle		handle,
+-	struct acpi_resource	**retbuf
+-	)
+-{
+-	acpi_status		status;
+-	struct acpi_buffer		crsbuf;
+-	u8			*path_name = acpi_path_name(handle);
+-
+-	crsbuf.length  = 0;
+-	crsbuf.pointer = NULL;
+-
+-	status = acpi_get_current_resources (handle, &crsbuf);
+-
+-	switch (status) {
+-	case AE_BUFFER_OVERFLOW:
+-		break;		/* found */
+-	case AE_NOT_FOUND:
+-		dbg("acpi_shpchprm:%s _CRS not found\n", path_name);
+-		return status;
+-	default:
+-		err ("acpi_shpchprm:%s _CRS fail=0x%x\n", path_name, status);
+-		return status;
+-	}
+-
+-	crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
+-	if (!crsbuf.pointer) {
+-		err ("acpi_shpchprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
+-		return AE_NO_MEMORY;
+-	}
+-
+-	status = acpi_get_current_resources (handle, &crsbuf);
+-	if (ACPI_FAILURE(status)) {
+-		err("acpi_shpchprm: %s _CRS fail=0x%x.\n", path_name, status);
+-		kfree(crsbuf.pointer);
+-		return status;
+-	}
+-
+-	*retbuf = crsbuf.pointer;
+-
+ 	return status;
+ }
+ 
+-static void free_pci_resource ( struct pci_resource	*aprh)
++static void acpi_run_oshp(acpi_handle handle)
+ {
+-	struct pci_resource	*res, *next;
+-
+-	for (res = aprh; res; res = next) {
+-		next = res->next;
+-		kfree(res);
+-	}
+-}
+-
+-static void print_pci_resource ( struct pci_resource	*aprh)
+-{
+-	struct pci_resource	*res;
+-
+-	for (res = aprh; res; res = res->next)
+-		dbg("        base= 0x%x length= 0x%x\n", res->base, res->length);
+-}
+-
+-static void print_slot_resources( struct acpi_php_slot	*aps)
+-{
+-	if (aps->bus_head) {
+-		dbg("    BUS Resources:\n");
+-		print_pci_resource (aps->bus_head);
+-	}
+-
+-	if (aps->io_head) {
+-		dbg("    IO Resources:\n");
+-		print_pci_resource (aps->io_head);
+-	}
+-
+-	if (aps->mem_head) {
+-		dbg("    MEM Resources:\n");
+-		print_pci_resource (aps->mem_head);
+-	}
+-
+-	if (aps->p_mem_head) {
+-		dbg("    PMEM Resources:\n");
+-		print_pci_resource (aps->p_mem_head);
+-	}
+-}
+-
+-static void print_pci_resources( struct acpi_bridge	*ab)
+-{
+-	if (ab->tbus_head) {
+-		dbg("    Total BUS Resources:\n");
+-		print_pci_resource (ab->tbus_head);
+-	}
+-	if (ab->bus_head) {
+-		dbg("    BUS Resources:\n");
+-		print_pci_resource (ab->bus_head);
+-	}
+-
+-	if (ab->tio_head) {
+-		dbg("    Total IO Resources:\n");
+-		print_pci_resource (ab->tio_head);
+-	}
+-	if (ab->io_head) {
+-		dbg("    IO Resources:\n");
+-		print_pci_resource (ab->io_head);
+-	}
+-
+-	if (ab->tmem_head) {
+-		dbg("    Total MEM Resources:\n");
+-		print_pci_resource (ab->tmem_head);
+-	}
+-	if (ab->mem_head) {
+-		dbg("    MEM Resources:\n");
+-		print_pci_resource (ab->mem_head);
+-	}
+-
+-	if (ab->tp_mem_head) {
+-		dbg("    Total PMEM Resources:\n");
+-		print_pci_resource (ab->tp_mem_head);
+-	}
+-	if (ab->p_mem_head) {
+-		dbg("    PMEM Resources:\n");
+-		print_pci_resource (ab->p_mem_head);
+-	}
+-	if (ab->_hpp) {
+-		dbg("    _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
+-		dbg("    _HPP: latency timer  =0x%x\n", ab->_hpp->latency_timer);
+-		dbg("    _HPP: enable SERR    =0x%x\n", ab->_hpp->enable_serr);
+-		dbg("    _HPP: enable PERR    =0x%x\n", ab->_hpp->enable_perr);
+-	}
+-}
+-
+-static int shpchprm_delete_resource(
+-	struct pci_resource **aprh,
+-	ulong base,
+-	ulong size)
+-{
+-	struct pci_resource *res;
+-	struct pci_resource *prevnode;
+-	struct pci_resource *split_node;
+-	ulong tbase;
+-
+-	shpchp_resource_sort_and_combine(aprh);
+-
+-	for (res = *aprh; res; res = res->next) {
+-		if (res->base > base)
+-			continue;
+-
+-		if ((res->base + res->length) < (base + size))
+-			continue;
+-
+-		if (res->base < base) {
+-			tbase = base;
+-
+-			if ((res->length - (tbase - res->base)) < size)
+-				continue;
+-
+-			split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+-			if (!split_node)
+-				return -ENOMEM;
+-
+-			split_node->base = res->base;
+-			split_node->length = tbase - res->base;
+-			res->base = tbase;
+-			res->length -= split_node->length;
+-
+-			split_node->next = res->next;
+-			res->next = split_node;
+-		}
+-
+-		if (res->length >= size) {
+-			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+-			if (!split_node)
+-				return -ENOMEM;
+-
+-			split_node->base = res->base + size;
+-			split_node->length = res->length - size;
+-			res->length = size;
+-
+-			split_node->next = res->next;
+-			res->next = split_node;
+-		}
+-
+-		if (*aprh == res) {
+-			*aprh = res->next;
+-		} else {
+-			prevnode = *aprh;
+-			while (prevnode->next != res)
+-				prevnode = prevnode->next;
+-
+-			prevnode->next = res->next;
+-		}
+-		res->next = NULL;
+-		kfree(res);
+-		break;
+-	}
+-
+-	return 0;
+-}
+-
+-static int shpchprm_delete_resources(
+-	struct pci_resource **aprh,
+-	struct pci_resource *this
+-	)
+-{
+-	struct pci_resource *res;
+-
+-	for (res = this; res; res = res->next)
+-		shpchprm_delete_resource(aprh, res->base, res->length);
+-
+-	return 0;
+-}
+-
+-static int shpchprm_add_resource(
+-	struct pci_resource **aprh,
+-	ulong base,
+-	ulong size)
+-{
+-	struct pci_resource *res;
+-
+-	for (res = *aprh; res; res = res->next) {
+-		if ((res->base + res->length) == base) {
+-			res->length += size;
+-			size = 0L;
+-			break;
+-		}
+-		if (res->next == *aprh)
+-			break;
+-	}
+-
+-	if (size) {
+-		res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+-		if (!res) {
+-			err ("acpi_shpchprm: alloc for res fail\n");
+-			return -ENOMEM;
+-		}
+-		memset(res, 0, sizeof (struct pci_resource));
+-
+-		res->base = base;
+-		res->length = size;
+-		res->next = *aprh;
+-		*aprh = res;
+-	}
+-
+-	return 0;
+-}
+-
+-static int shpchprm_add_resources(
+-	struct pci_resource **aprh,
+-	struct pci_resource *this
+-	)
+-{
+-	struct pci_resource *res;
+-	int	rc = 0;
+-
+-	for (res = this; res && !rc; res = res->next)
+-		rc = shpchprm_add_resource(aprh, res->base, res->length);
+-
+-	return rc;
+-}
+-
+-static void acpi_parse_io (
+-	struct acpi_bridge		*ab,
+-	union acpi_resource_data	*data
+-	)
+-{
+-	struct acpi_resource_io	*dataio;
+-	dataio = (struct acpi_resource_io *) data;
+-
+-	dbg("Io Resource\n");
+-	dbg("  %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10);
+-	dbg("  Range minimum base: %08X\n", dataio->min_base_address);
+-	dbg("  Range maximum base: %08X\n", dataio->max_base_address);
+-	dbg("  Alignment: %08X\n", dataio->alignment);
+-	dbg("  Range Length: %08X\n", dataio->range_length);
+-}
+-
+-static void acpi_parse_fixed_io (
+-	struct acpi_bridge		*ab,
+-	union acpi_resource_data	*data
+-	)
+-{
+-	struct acpi_resource_fixed_io  *datafio;
+-	datafio = (struct acpi_resource_fixed_io *) data;
+-
+-	dbg("Fixed Io Resource\n");
+-	dbg("  Range base address: %08X", datafio->base_address);
+-	dbg("  Range length: %08X", datafio->range_length);
+-}
+-
+-static void acpi_parse_address16_32 (
+-	struct acpi_bridge		*ab,
+-	union acpi_resource_data	*data,
+-	acpi_resource_type		id
+-	)
+-{
+-	/* 
+-	 * acpi_resource_address16 == acpi_resource_address32
+-	 * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
+-	 */
+-	struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data;
+-	struct pci_resource **aprh, **tprh;
+-
+-	if (id == ACPI_RSTYPE_ADDRESS16)
+-		dbg("acpi_shpchprm:16-Bit Address Space Resource\n");
+-	else
+-		dbg("acpi_shpchprm:32-Bit Address Space Resource\n");
+-
+-	switch (data32->resource_type) {
+-	case ACPI_MEMORY_RANGE: 
+-		dbg("  Resource Type: Memory Range\n");
+-		aprh = &ab->mem_head;
+-		tprh = &ab->tmem_head;
+-
+-		switch (data32->attribute.memory.cache_attribute) {
+-		case ACPI_NON_CACHEABLE_MEMORY:
+-			dbg("  Type Specific: Noncacheable memory\n");
+-			break; 
+-		case ACPI_CACHABLE_MEMORY:
+-			dbg("  Type Specific: Cacheable memory\n");
+-			break; 
+-		case ACPI_WRITE_COMBINING_MEMORY:
+-			dbg("  Type Specific: Write-combining memory\n");
+-			break; 
+-		case ACPI_PREFETCHABLE_MEMORY:
+-			aprh = &ab->p_mem_head;
+-			dbg("  Type Specific: Prefetchable memory\n");
+-			break; 
+-		default:
+-			dbg("  Type Specific: Invalid cache attribute\n");
+-			break;
+-		}
+-
+-		dbg("  Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only");
+-		break;
+-
+-	case ACPI_IO_RANGE: 
+-		dbg("  Resource Type: I/O Range\n");
+-		aprh = &ab->io_head;
+-		tprh = &ab->tio_head;
+-
+-		switch (data32->attribute.io.range_attribute) {
+-		case ACPI_NON_ISA_ONLY_RANGES:
+-			dbg("  Type Specific: Non-ISA Io Addresses\n");
+-			break; 
+-		case ACPI_ISA_ONLY_RANGES:
+-			dbg("  Type Specific: ISA Io Addresses\n");
+-			break; 
+-		case ACPI_ENTIRE_RANGE:
+-			dbg("  Type Specific: ISA and non-ISA Io Addresses\n");
+-			break; 
+-		default:
+-			dbg("  Type Specific: Invalid range attribute\n");
+-			break;
+-		}
+-		break;
+-
+-	case ACPI_BUS_NUMBER_RANGE: 
+-		dbg("  Resource Type: Bus Number Range(fixed)\n");
+-		/* fixup to be compatible with the rest of php driver */
+-		data32->min_address_range++;
+-		data32->address_length--;
+-		aprh = &ab->bus_head;
+-		tprh = &ab->tbus_head;
+-		break; 
+-	default: 
+-		dbg("  Resource Type: Invalid resource type. Exiting.\n");
+-		return;
+-	}
+-
+-	dbg("  Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
+-	dbg("  %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
+-	dbg("  Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
+-	dbg("  Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
+-	dbg("  Granularity: %08X\n", data32->granularity);
+-	dbg("  Address range min: %08X\n", data32->min_address_range);
+-	dbg("  Address range max: %08X\n", data32->max_address_range);
+-	dbg("  Address translation offset: %08X\n", data32->address_translation_offset);
+-	dbg("  Address Length: %08X\n", data32->address_length);
+-
+-	if (0xFF != data32->resource_source.index) {
+-		dbg("  Resource Source Index: %X\n", data32->resource_source.index);
+-		/* dbg("  Resource Source: %s\n", data32->resource_source.string_ptr); */
+-	}
+-
+-	shpchprm_add_resource(aprh, data32->min_address_range, data32->address_length);
+-}
+-
+-static acpi_status acpi_parse_crs(
+-	struct acpi_bridge	*ab,
+-	struct acpi_resource	*crsbuf
+-	)
+-{
+-	acpi_status		status = AE_OK;
+-	struct acpi_resource	*resource = crsbuf;
+-	u8			count = 0;
+-	u8			done = 0;
+-
+-	while (!done) {
+-		dbg("acpi_shpchprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
+-		switch (resource->id) {
+-		case ACPI_RSTYPE_IRQ:
+-			dbg("Irq -------- Resource\n");
+-			break; 
+-		case ACPI_RSTYPE_DMA:
+-			dbg("DMA -------- Resource\n");
+-			break; 
+-		case ACPI_RSTYPE_START_DPF:
+-			dbg("Start DPF -------- Resource\n");
+-			break; 
+-		case ACPI_RSTYPE_END_DPF:
+-			dbg("End DPF -------- Resource\n");
+-			break; 
+-		case ACPI_RSTYPE_IO:
+-			acpi_parse_io (ab, &resource->data);
+-			break; 
+-		case ACPI_RSTYPE_FIXED_IO:
+-			acpi_parse_fixed_io (ab, &resource->data);
+-			break; 
+-		case ACPI_RSTYPE_VENDOR:
+-			dbg("Vendor -------- Resource\n");
+-			break; 
+-		case ACPI_RSTYPE_END_TAG:
+-			dbg("End_tag -------- Resource\n");
+-			done = 1;
+-			break; 
+-		case ACPI_RSTYPE_MEM24:
+-			dbg("Mem24 -------- Resource\n");
+-			break; 
+-		case ACPI_RSTYPE_MEM32:
+-			dbg("Mem32 -------- Resource\n");
+-			break; 
+-		case ACPI_RSTYPE_FIXED_MEM32:
+-			dbg("Fixed Mem32 -------- Resource\n");
+-			break; 
+-		case ACPI_RSTYPE_ADDRESS16:
+-			acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
+-			break; 
+-		case ACPI_RSTYPE_ADDRESS32:
+-			acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
+-			break; 
+-		case ACPI_RSTYPE_ADDRESS64:
+-			info("Address64 -------- Resource unparsed\n");
+-			break; 
+-		case ACPI_RSTYPE_EXT_IRQ:
+-			dbg("Ext Irq -------- Resource\n");
+-			break; 
+-		default:
+-			dbg("Invalid -------- resource type 0x%x\n", resource->id);
+-			break;
+-		}
+-
+-		resource = (struct acpi_resource *) ((char *)resource + resource->length);
+-	}
+-
+-	return status;
+-}
+-
+-static acpi_status acpi_get_crs( struct acpi_bridge	*ab)
+-{
+-	acpi_status		status;
+-	struct acpi_resource	*crsbuf;
+-
+-	status = acpi_evaluate_crs(ab->handle, &crsbuf);
+-	if (ACPI_SUCCESS(status)) {
+-		status = acpi_parse_crs(ab, crsbuf);
+-		kfree(crsbuf);
+-
+-		shpchp_resource_sort_and_combine(&ab->bus_head);
+-		shpchp_resource_sort_and_combine(&ab->io_head);
+-		shpchp_resource_sort_and_combine(&ab->mem_head);
+-		shpchp_resource_sort_and_combine(&ab->p_mem_head);
+-
+-		shpchprm_add_resources (&ab->tbus_head, ab->bus_head);
+-		shpchprm_add_resources (&ab->tio_head, ab->io_head);
+-		shpchprm_add_resources (&ab->tmem_head, ab->mem_head);
+-		shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
+-	}
+-
+-	return status;
+-}
+-
+-/* find acpi_bridge downword from ab.  */
+-static struct acpi_bridge *
+-find_acpi_bridge_by_bus(
+-	struct acpi_bridge *ab,
+-	int seg,
+-	int bus		/* pdev->subordinate->number */
+-	)
+-{
+-	struct acpi_bridge	*lab = NULL;
+-
+-	if (!ab)
+-		return NULL;
+-
+-	if ((ab->bus == bus) && (ab->seg == seg))
+-		return ab;
+-
+-	if (ab->child)
+-		lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
+-
+-	if (!lab)
+-	if (ab->next)
+-		lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
+-
+-	return lab;
+-}
+-
+-/*
+- * Build a device tree of ACPI PCI Bridges
+- */
+-static void shpchprm_acpi_register_a_bridge (
+-	struct acpi_bridge	**head,
+-	struct acpi_bridge	*pab,	/* parent bridge to which child bridge is added */
+-	struct acpi_bridge	*cab	/* child bridge to add */
+-	)
+-{
+-	struct acpi_bridge	*lpab;
+-	struct acpi_bridge	*lcab;
+-
+-	lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
+-	if (!lpab) {
+-		if (!(pab->type & BRIDGE_TYPE_HOST))
+-			warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
+-		pab->next = *head;
+-		*head = pab;
+-		lpab = pab;
+-	}
+-
+-	if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
+-		return;
+-
+-	lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
+-	if (lcab) {
+-		if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
+-			err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
+-		return;
+-	} else
+-		lcab = cab;
+-
+-	lcab->parent = lpab;
+-	lcab->next = lpab->child;
+-	lpab->child = lcab;
+-}
+-
+-static acpi_status shpchprm_acpi_build_php_slots_callback(
+-	acpi_handle	handle,
+-	u32		Level,
+-	void		*context,
+-	void		**retval
+-	)
+-{
+-	ulong		bus_num;
+-	ulong		seg_num;
+-	ulong		sun, adr;
+-	ulong		padr = 0;
+-	acpi_handle		phandle = NULL;
+-	struct acpi_bridge	*pab = (struct acpi_bridge *)context;
+-	struct acpi_bridge	*lab;
+ 	acpi_status		status;
+ 	u8			*path_name = acpi_path_name(handle);
+ 
+-	/* get _SUN */
+-	status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
+-	switch(status) {
+-	case AE_NOT_FOUND:
+-		return AE_OK;
+-	default:
+-		if (ACPI_FAILURE(status)) {
+-			err("acpi_shpchprm:%s _SUN fail=0x%x\n", path_name, status);
+-			return status;
+-		}
+-	}
+-
+-	/* get _ADR. _ADR must exist if _SUN exists */
+-	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
+-	if (ACPI_FAILURE(status)) {
+-		err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
+-		return status;
+-	}
+-
+-	dbg("acpi_shpchprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
+-
+-	status = acpi_get_parent(handle, &phandle);
++	/* run OSHP */
++	status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
+ 	if (ACPI_FAILURE(status)) {
+-		err("acpi_shpchprm:%s get_parent fail=0x%x\n", path_name, status);
+-		return (status);
+-	}
+-
+-	bus_num = pab->bus;
+-	seg_num = pab->seg;
+-
+-	if (pab->bus == bus_num) {
+-		lab = pab;
++		err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
++				status);
+ 	} else {
+-		dbg("WARN: pab is not parent\n");
+-		lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
+-		if (!lab) {
+-			dbg("acpi_shpchprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
+-			lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
+-			if (!lab) {
+-				err("acpi_shpchprm: alloc for ab fail\n");
+-				return AE_NO_MEMORY;
+-			}
+-			memset(lab, 0, sizeof(struct acpi_bridge));
+-
+-			lab->handle = phandle;
+-			lab->pbus = pab->bus;
+-			lab->pdevice = (int)(padr >> 16) & 0xffff;
+-			lab->pfunction = (int)(padr & 0xffff);
+-			lab->bus = (int)bus_num;
+-			lab->scanned = 0;
+-			lab->type = BRIDGE_TYPE_P2P;
+-
+-			shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
+-		} else
+-			dbg("acpi_shpchprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
+-	}
+-
+-	acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
+-	return (status);
+-}
+-
+-static int shpchprm_acpi_build_php_slots(
+-	struct acpi_bridge	*ab,
+-	u32			depth
+-	)
+-{
+-	acpi_status	status;
+-	u8		*path_name = acpi_path_name(ab->handle);
+-
+-	/* Walk down this pci bridge to get _SUNs if any behind P2P */
+-	status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
+-				ab->handle,
+-				depth,
+-				shpchprm_acpi_build_php_slots_callback,
+-				ab,
+-				NULL );
+-	if (ACPI_FAILURE(status)) {
+-		dbg("acpi_shpchprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-static void build_a_bridge(
+-	struct acpi_bridge	*pab,
+-	struct acpi_bridge	*ab
+-	)
+-{
+-	u8		*path_name = acpi_path_name(ab->handle);
+-
+-	shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
+-
+-	switch (ab->type) {
+-	case BRIDGE_TYPE_HOST:
+-		dbg("acpi_shpchprm: Registered PCI HOST Bridge(%02x)    on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
+-			ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
+-		break;
+-	case BRIDGE_TYPE_P2P:
+-		dbg("acpi_shpchprm: Registered PCI  P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
+-			ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
+-		break;
+-	};
+-
+-	/* build any immediate PHP slots under this pci bridge */
+-	shpchprm_acpi_build_php_slots(ab, 1);
+-}
+-
+-static struct acpi_bridge * add_p2p_bridge(
+-	acpi_handle handle,
+-	struct acpi_bridge	*pab,	/* parent */
+-	ulong	adr
+-	)
+-{
+-	struct acpi_bridge	*ab;
+-	struct pci_dev	*pdev;
+-	ulong		devnum, funcnum;
+-	u8			*path_name = acpi_path_name(handle);
+-
+-	ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
+-	if (!ab) {
+-		err("acpi_shpchprm: alloc for ab fail\n");
+-		return NULL;
+-	}
+-	memset(ab, 0, sizeof(struct acpi_bridge));
+-
+-	devnum = (adr >> 16) & 0xffff;
+-	funcnum = adr & 0xffff;
+-
+-	pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
+-	if (!pdev || !pdev->subordinate) {
+-		err("acpi_shpchprm:%s is not a P2P Bridge\n", path_name);
+-		kfree(ab);
+-		return NULL;
+-	}
+-
+-	ab->handle = handle;
+-	ab->seg = pab->seg;
+-	ab->pbus = pab->bus;		/* or pdev->bus->number */
+-	ab->pdevice = devnum;		/* or PCI_SLOT(pdev->devfn) */
+-	ab->pfunction = funcnum;	/* or PCI_FUNC(pdev->devfn) */
+-	ab->bus = pdev->subordinate->number;
+-	ab->scanned = 0;
+-	ab->type = BRIDGE_TYPE_P2P;
+-
+-	dbg("acpi_shpchprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
+-		pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+-		pab->bus, (u32)devnum, (u32)funcnum, path_name);
+-
+-	build_a_bridge(pab, ab);
+-
+-	return ab;
+-}
+-
+-static acpi_status scan_p2p_bridge(
+-	acpi_handle		handle,
+-	u32			Level,
+-	void			*context,
+-	void			**retval
+-	)
+-{
+-	struct acpi_bridge	*pab = (struct acpi_bridge *)context;
+-	struct acpi_bridge	*ab;
+-	acpi_status		status;
+-	ulong		adr = 0;
+-	u8			*path_name = acpi_path_name(handle);
+-	ulong		devnum, funcnum;
+-	struct pci_dev	*pdev;
+-
+-	/* get device, function */
+-	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
+-	if (ACPI_FAILURE(status)) {
+-		if (status != AE_NOT_FOUND)
+-			err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
+-		return AE_OK;
+-	}
+-
+-	devnum = (adr >> 16) & 0xffff;
+-	funcnum = adr & 0xffff;
+-
+-	pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
+-	if (!pdev)
+-		return AE_OK;
+-	if (!pdev->subordinate)
+-		return AE_OK;
+-
+-	ab = add_p2p_bridge(handle, pab, adr);
+-	if (ab) {
+-		status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
+-					handle,
+-					(u32)1,
+-					scan_p2p_bridge,
+-					ab,
+-					NULL);
+-		if (ACPI_FAILURE(status))
+-			dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
+-	}
+-
+-	return AE_OK;
+-}
+-
+-static struct acpi_bridge * add_host_bridge(
+-	acpi_handle handle,
+-	ulong	segnum,
+-	ulong	busnum
+-	)
+-{
+-	ulong			adr = 0;
+-	acpi_status		status;
+-	struct acpi_bridge	*ab;
+-	u8			*path_name = acpi_path_name(handle);
+-
+-	/* get device, function: host br adr is always 0000 though.  */
+-	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
+-	if (ACPI_FAILURE(status)) {
+-		err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
+-		return NULL;
+-	}
+-	dbg("acpi_shpchprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum, (u32)busnum, 
+-		(u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
+-
+-	ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
+-	if (!ab) {
+-		err("acpi_shpchprm: alloc for ab fail\n");
+-		return NULL;
+-	}
+-	memset(ab, 0, sizeof(struct acpi_bridge));
+-
+-	ab->handle = handle;
+-	ab->seg = (int)segnum;
+-	ab->bus = ab->pbus = (int)busnum;
+-	ab->pdevice = (int)(adr >> 16) & 0xffff;
+-	ab->pfunction = (int)(adr & 0xffff);
+-	ab->scanned = 0;
+-	ab->type = BRIDGE_TYPE_HOST;
+-
+-	/* get root pci bridge's current resources */
+-	status = acpi_get_crs(ab);
+-	if (ACPI_FAILURE(status)) {
+-		err("acpi_shpchprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
+-		kfree(ab);
+-		return NULL;
++		dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
+ 	}
+-	build_a_bridge(ab, ab);
+-
+-	return ab;
+-}
+-
+-static acpi_status acpi_scan_from_root_pci_callback (
+-	acpi_handle	handle,
+-	u32			Level,
+-	void		*context,
+-	void		**retval
+-	)
+-{
+-	ulong		segnum = 0;
+-	ulong		busnum = 0;
+-	acpi_status		status;
+-	struct acpi_bridge	*ab;
+-	u8			*path_name = acpi_path_name(handle);
+-
+-	/* get bus number of this pci root bridge */
+-	status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
+-	if (ACPI_FAILURE(status)) {
+-		if (status != AE_NOT_FOUND) {
+-			err("acpi_shpchprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
+-			return status;
+-		}
+-		segnum = 0;
+-	}
+-
+-	/* get bus number of this pci root bridge */
+-	status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
+-	if (ACPI_FAILURE(status)) {
+-		err("acpi_shpchprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
+-		return (status);
+-	}
+-
+-	ab = add_host_bridge(handle, segnum, busnum);
+-	if (ab) {
+-		status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
+-					handle,
+-					1,
+-					scan_p2p_bridge,
+-					ab,
+-					NULL);
+-		if (ACPI_FAILURE(status))
+-			dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
+-	}
+-
+-	return AE_OK;
+-}
+-
+-static int shpchprm_acpi_scan_pci (void)
+-{
+-	acpi_status	status;
+-
+-	/*
+-	 * TBD: traverse LDM device tree with the help of
+-	 *  unified ACPI augmented for php device population.
+-	 */
+-	status = acpi_get_devices ( PCI_ROOT_HID_STRING,
+-				acpi_scan_from_root_pci_callback,
+-				NULL,
+-				NULL );
+-	if (ACPI_FAILURE(status)) {
+-		err("acpi_shpchprm:get_device PCI ROOT HID fail=0x%x\n", status);
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-int shpchprm_init(enum php_ctlr_type ctlr_type)
+-{
+-	int	rc;
+-
+-	if (ctlr_type != PCI)
+-		return -ENODEV;
+-
+-	dbg("shpchprm ACPI init <enter>\n");
+-	acpi_bridges_head = NULL;
+-
+-	/* construct PCI bus:device tree of acpi_handles */
+-	rc = shpchprm_acpi_scan_pci();
+-	if (rc)
+-		return rc;
+-
+-	dbg("shpchprm ACPI init %s\n", (rc)?"fail":"success");
+-	return rc;
+-}
+-
+-static void free_a_slot(struct acpi_php_slot *aps)
+-{
+-	dbg("        free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
+-
+-	free_pci_resource (aps->io_head);
+-	free_pci_resource (aps->bus_head);
+-	free_pci_resource (aps->mem_head);
+-	free_pci_resource (aps->p_mem_head);
+-
+-	kfree(aps);
+-}
+-
+-static void free_a_bridge( struct acpi_bridge	*ab)
+-{
+-	struct acpi_php_slot	*aps, *next;
+-
+-	switch (ab->type) {
+-	case BRIDGE_TYPE_HOST:
+-		dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
+-			ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
+-		break;
+-	case BRIDGE_TYPE_P2P:
+-		dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
+-			ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
+-		break;
+-	};
+-
+-	/* free slots first */
+-	for (aps = ab->slots; aps; aps = next) {
+-		next = aps->next;
+-		free_a_slot(aps);
+-	}
+-
+-	free_pci_resource (ab->io_head);
+-	free_pci_resource (ab->tio_head);
+-	free_pci_resource (ab->bus_head);
+-	free_pci_resource (ab->tbus_head);
+-	free_pci_resource (ab->mem_head);
+-	free_pci_resource (ab->tmem_head);
+-	free_pci_resource (ab->p_mem_head);
+-	free_pci_resource (ab->tp_mem_head);
+-
+-	kfree(ab);
+-}
+-
+-static void shpchprm_free_bridges ( struct acpi_bridge	*ab)
+-{
+-	if (!ab)
+-		return;
+-
+-	if (ab->child)
+-		shpchprm_free_bridges (ab->child);
+-
+-	if (ab->next)
+-		shpchprm_free_bridges (ab->next);
+-
+-	free_a_bridge(ab);
+-}
+-
+-void shpchprm_cleanup(void)
+-{
+-	shpchprm_free_bridges (acpi_bridges_head);
+-}
+-
+-static int get_number_of_slots (
+-	struct acpi_bridge	*ab,
+-	int				selfonly
+-	)
+-{
+-	struct acpi_php_slot	*aps;
+-	int	prev_slot = -1;
+-	int	slot_num = 0;
+-
+-	for ( aps = ab->slots; aps; aps = aps->next)
+-		if (aps->dev != prev_slot) {
+-			prev_slot = aps->dev;
+-			slot_num++;
+-		}
+-
+-	if (ab->child)
+-		slot_num += get_number_of_slots (ab->child, 0);
+-
+-	if (selfonly)
+-		return slot_num;
+-
+-	if (ab->next)
+-		slot_num += get_number_of_slots (ab->next, 0);
+-
+-	return slot_num;
+-}
+-
+-static int print_acpi_resources (struct acpi_bridge	*ab)
+-{
+-	struct acpi_php_slot	*aps;
+-	int	i;
+-
+-	switch (ab->type) {
+-	case BRIDGE_TYPE_HOST:
+-		dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
+-		break;
+-	case BRIDGE_TYPE_P2P:
+-		dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
+-		break;
+-	};
+-
+-	print_pci_resources (ab);
+-
+-	for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
+-		if (aps->dev == i)
+-			continue;
+-		dbg("  Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
+-		print_slot_resources(aps);
+-		i = aps->dev;
+-	}
+-
+-	if (ab->child)
+-		print_acpi_resources (ab->child);
+-
+-	if (ab->next)
+-		print_acpi_resources (ab->next);
+-
+-	return 0;
+-}
+-
+-int shpchprm_print_pirt(void)
+-{
+-	dbg("SHPCHPRM ACPI Slots\n");
+-	if (acpi_bridges_head)
+-		print_acpi_resources (acpi_bridges_head);
+-	return 0;
+-}
+-
+-static struct acpi_php_slot * get_acpi_slot (
+-	struct acpi_bridge *ab,
+-	u32 sun
+-	)
+-{
+-	struct acpi_php_slot	*aps = NULL;
+-
+-	for ( aps = ab->slots; aps; aps = aps->next)
+-		if (aps->sun == sun)
+-			return aps;
+-
+-	if (!aps && ab->child) {
+-		aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
+-		if (aps)
+-			return aps;
+-	}
+-
+-	if (!aps && ab->next) {
+-		aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
+-		if (aps)
+-			return aps;
+-	}
+-
+-	return aps;
+-
+-}
+-
+-#if 0
+-static void * shpchprm_get_slot(struct slot *slot)
+-{
+-	struct acpi_bridge	*ab = acpi_bridges_head;
+-	struct acpi_php_slot	*aps = get_acpi_slot (ab, slot->number);
+-
+-	aps->slot = slot;
+-
+-	dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
+-
+-	return (void *)aps;
+-}
+-#endif
+-
+-static void shpchprm_dump_func_res( struct pci_func *fun)
+-{
+-	struct pci_func *func = fun;
+-
+-	if (func->bus_head) {
+-		dbg(":    BUS Resources:\n");
+-		print_pci_resource (func->bus_head);
+-	}
+-	if (func->io_head) {
+-		dbg(":    IO Resources:\n");
+-		print_pci_resource (func->io_head);
+-	}
+-	if (func->mem_head) {
+-		dbg(":    MEM Resources:\n");
+-		print_pci_resource (func->mem_head);
+-	}
+-	if (func->p_mem_head) {
+-		dbg(":    PMEM Resources:\n");
+-		print_pci_resource (func->p_mem_head);
+-	}
+-}
+-
+-static void shpchprm_dump_ctrl_res( struct controller *ctlr)
+-{
+-	struct controller *ctrl = ctlr;
+-
+-	if (ctrl->bus_head) {
+-		dbg(":    BUS Resources:\n");
+-		print_pci_resource (ctrl->bus_head);
+-	}
+-	if (ctrl->io_head) {
+-		dbg(":    IO Resources:\n");
+-		print_pci_resource (ctrl->io_head);
+-	}
+-	if (ctrl->mem_head) {
+-		dbg(":    MEM Resources:\n");
+-		print_pci_resource (ctrl->mem_head);
+-	}
+-	if (ctrl->p_mem_head) {
+-		dbg(":    PMEM Resources:\n");
+-		print_pci_resource (ctrl->p_mem_head);
+-	}
+-}
+-
+-static int shpchprm_get_used_resources (
+-	struct controller *ctrl,
+-	struct pci_func *func
+-	)
+-{
+-	return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
+-}
+-
+-static int configure_existing_function(
+-	struct controller *ctrl,
+-	struct pci_func *func
+-	)
+-{
+-	int rc;
+-
+-	/* see how much resources the func has used. */
+-	rc = shpchprm_get_used_resources (ctrl, func);
+-
+-	if (!rc) {
+-		/* subtract the resources used by the func from ctrl resources */
+-		rc  = shpchprm_delete_resources (&ctrl->bus_head, func->bus_head);
+-		rc |= shpchprm_delete_resources (&ctrl->io_head, func->io_head);
+-		rc |= shpchprm_delete_resources (&ctrl->mem_head, func->mem_head);
+-		rc |= shpchprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
+-		if (rc)
+-			warn("aCEF: cannot del used resources\n");
+-	} else
+-		err("aCEF: cannot get used resources\n");
+-
+-	return rc;
+-}
+-
+-static int bind_pci_resources_to_slots ( struct controller *ctrl)
+-{
+-	struct pci_func *func, new_func;
+-	int busn = ctrl->slot_bus;
+-	int devn, funn;
+-	u32	vid;
+-
+-	for (devn = 0; devn < 32; devn++) {
+-		for (funn = 0; funn < 8; funn++) {
+-			/*
+-			if (devn == ctrl->device && funn == ctrl->function)
+-				continue;
+-			*/
+-			/* find out if this entry is for an occupied slot */
+-			vid = 0xFFFFFFFF;
+-			pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
+-
+-			if (vid != 0xFFFFFFFF) {
+-				func = shpchp_slot_find(busn, devn, funn);
+-				if (!func) {
+-					memset(&new_func, 0, sizeof(struct pci_func));
+-					new_func.bus = busn;
+-					new_func.device = devn;
+-					new_func.function = funn;
+-					new_func.is_a_board = 1;
+-					configure_existing_function(ctrl, &new_func);
+-					shpchprm_dump_func_res(&new_func);
+-				} else {
+-					configure_existing_function(ctrl, func);
+-					shpchprm_dump_func_res(func);
+-				}
+-				dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
+-			}
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static int bind_pci_resources(
+-	struct controller 	*ctrl,
+-	struct acpi_bridge	*ab
+-	)
+-{
+-	int	status = 0;
+-
+-	if (ab->bus_head) {
+-		dbg("bapr:  BUS Resources add on PCI 0x%x\n", ab->bus);
+-		status = shpchprm_add_resources (&ctrl->bus_head, ab->bus_head);
+-		if (shpchprm_delete_resources (&ab->bus_head, ctrl->bus_head))
+-			warn("bapr:  cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
+-		if (status) {
+-			err("bapr:  BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
+-			return status;
+-		}
+-	} else
+-		info("bapr:  No BUS Resource on PCI 0x%x.\n", ab->bus);
+-
+-	if (ab->io_head) {
+-		dbg("bapr:  IO Resources add on PCI 0x%x\n", ab->bus);
+-		status = shpchprm_add_resources (&ctrl->io_head, ab->io_head);
+-		if (shpchprm_delete_resources (&ab->io_head, ctrl->io_head))
+-			warn("bapr:  cannot sub IO Resource on PCI 0x%x\n", ab->bus);
+-		if (status) {
+-			err("bapr:  IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
+-			return status;
+-		}
+-	} else
+-		info("bapr:  No  IO Resource on PCI 0x%x.\n", ab->bus);
+-
+-	if (ab->mem_head) {
+-		dbg("bapr:  MEM Resources add on PCI 0x%x\n", ab->bus);
+-		status = shpchprm_add_resources (&ctrl->mem_head, ab->mem_head);
+-		if (shpchprm_delete_resources (&ab->mem_head, ctrl->mem_head))
+-			warn("bapr:  cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
+-		if (status) {
+-			err("bapr:  MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
+-			return status;
+-		}
+-	} else
+-		info("bapr:  No MEM Resource on PCI 0x%x.\n", ab->bus);
+-
+-	if (ab->p_mem_head) {
+-		dbg("bapr:  PMEM Resources add on PCI 0x%x\n", ab->bus);
+-		status = shpchprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
+-		if (shpchprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
+-			warn("bapr:  cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
+-		if (status) {
+-			err("bapr:  PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
+-			return status;
+-		}
+-	} else
+-		info("bapr:  No PMEM Resource on PCI 0x%x.\n", ab->bus);
+-
+-	return status;
+-}
+-
+-static int no_pci_resources( struct acpi_bridge *ab)
+-{
+-	return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
+-}
+-
+-static int find_pci_bridge_resources (
+-	struct controller *ctrl,
+-	struct acpi_bridge *ab
+-	)
+-{
+-	int	rc = 0;
+-	struct pci_func func;
+-
+-	memset(&func, 0, sizeof(struct pci_func));
+-
+-	func.bus = ab->pbus;
+-	func.device = ab->pdevice;
+-	func.function = ab->pfunction;
+-	func.is_a_board = 1;
+-
+-	/* Get used resources for this PCI bridge */
+-	rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD);
+-
+-	ab->io_head = func.io_head;
+-	ab->mem_head = func.mem_head;
+-	ab->p_mem_head = func.p_mem_head;
+-	ab->bus_head = func.bus_head;
+-	if (ab->bus_head)
+-		shpchprm_delete_resource(&ab->bus_head, ctrl->bus, 1);
+-
+-	return rc;
+-}
+-
+-static int get_pci_resources_from_bridge(
+-	struct controller *ctrl,
+-	struct acpi_bridge *ab
+-	)
+-{
+-	int	rc = 0;
+-
+-	dbg("grfb:  Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
+-
+-	rc = find_pci_bridge_resources (ctrl, ab);
+-
+-	shpchp_resource_sort_and_combine(&ab->bus_head);
+-	shpchp_resource_sort_and_combine(&ab->io_head);
+-	shpchp_resource_sort_and_combine(&ab->mem_head);
+-	shpchp_resource_sort_and_combine(&ab->p_mem_head);
+-
+-	shpchprm_add_resources (&ab->tbus_head, ab->bus_head);
+-	shpchprm_add_resources (&ab->tio_head, ab->io_head);
+-	shpchprm_add_resources (&ab->tmem_head, ab->mem_head);
+-	shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
+-
+-	return rc;
+-}
+-
+-static int get_pci_resources(
+-	struct controller	*ctrl,
+-	struct acpi_bridge	*ab
+-	)
+-{
+-	int	rc = 0;
+-
+-	if (no_pci_resources(ab)) {
+-		dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
+-		rc = get_pci_resources_from_bridge(ctrl, ab);
+-	}
+-
+-	return rc;
+ }
+ 
+ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
+@@ -1570,144 +147,40 @@ int shpchprm_get_physical_slot_number(st
+ 	return 0;
+ }
+ 
+-/*
+- * Get resources for this ctrl.
+- *  1. get total resources from ACPI _CRS or bridge (this ctrl)
+- *  2. find used resources of existing adapters
+- *	3. subtract used resources from total resources
+- */
+-int shpchprm_find_available_resources( struct controller *ctrl)
++void get_hp_hw_control_from_firmware(struct pci_dev *dev)
+ {
+-	int rc = 0;
+-	struct acpi_bridge	*ab;
+-
+-	ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
+-	if (!ab) {
+-		err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
+-		return -1;
+-	}
+-	if (no_pci_resources(ab)) {
+-		rc = get_pci_resources(ctrl, ab);
+-		if (rc) {
+-			err("pfar:cannot get pci resources of PCI 0x%x.\n",ctrl->pci_dev->subordinate->number);
+-			return -1;
+-		}
+-	}
+-
+-	rc = bind_pci_resources(ctrl, ab);
+-	dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
+-	shpchprm_dump_ctrl_res(ctrl);
+-
+-	bind_pci_resources_to_slots (ctrl);
+-
+-	dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
+-	shpchprm_dump_ctrl_res(ctrl);
+-
+-	return rc;
+-}
+-
+-int shpchprm_set_hpp(
+-	struct controller *ctrl,
+-	struct pci_func *func,
+-	u8	card_type
+-	)
+-{
+-	struct acpi_bridge	*ab;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	int				rc = 0;
+-	unsigned int	devfn;
+-	u8				cls= 0x08;	/* default cache line size	*/
+-	u8				lt = 0x40;	/* default latency timer	*/
+-	u8				ep = 0;
+-	u8				es = 0;
+-
+-	memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	pci_bus->number = func->bus;
+-	devfn = PCI_DEVFN(func->device, func->function);
+-
+-	ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus);
+-
+-	if (ab) {
+-		if (ab->_hpp) {
+-			lt  = (u8)ab->_hpp->latency_timer;
+-			cls = (u8)ab->_hpp->cache_line_size;
+-			ep  = (u8)ab->_hpp->enable_perr;
+-			es  = (u8)ab->_hpp->enable_serr;
+-		} else
+-			dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
+-	} else
+-		dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
+-
+-
+-	if (card_type == PCI_HEADER_TYPE_BRIDGE) {
+-		/* set subordinate Latency Timer */
+-		rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
+-	}
+-
+-	/* set base Latency Timer */
+-	rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
+-	dbg("  set latency timer  =0x%02x: %x\n", lt, rc);
+-
+-	rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
+-	dbg("  set cache_line_size=0x%02x: %x\n", cls, rc);
+-
+-	return rc;
++	/*
++	 * OSHP is an optional ACPI firmware control method. If present,
++	 * we need to run it to inform BIOS that we will control SHPC
++	 * hardware from now on.
++	 */
++	acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev));
++	if (!handle)
++		return;
++	acpi_run_oshp(handle);
+ }
+ 
+-void shpchprm_enable_card(
+-	struct controller *ctrl,
+-	struct pci_func *func,
+-	u8 card_type)
++void get_hp_params_from_firmware(struct pci_dev *dev,
++		struct hotplug_params *hpp)
+ {
+-	u16 command, cmd, bcommand, bcmd;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	struct acpi_bridge	*ab;
+-	unsigned int devfn;
+-	int rc;
+-
+-	memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	pci_bus->number = func->bus;
+-	devfn = PCI_DEVFN(func->device, func->function);
+-
+-	rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
+-
+-	if (card_type == PCI_HEADER_TYPE_BRIDGE) {
+-		rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
+-	}
++	acpi_status status = AE_NOT_FOUND;
++	struct pci_dev *pdev = dev;
+ 
+-	cmd = command  = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
+-		| PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+-	bcmd = bcommand  = bcommand | PCI_BRIDGE_CTL_NO_ISA;
+-
+-	ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus);
+-	if (ab) {
+-		if (ab->_hpp) {
+-			if (ab->_hpp->enable_perr) {
+-				command |= PCI_COMMAND_PARITY;
+-				bcommand |= PCI_BRIDGE_CTL_PARITY;
+-			} else {
+-				command &= ~PCI_COMMAND_PARITY;
+-				bcommand &= ~PCI_BRIDGE_CTL_PARITY;
+-			}
+-			if (ab->_hpp->enable_serr) {
+-				command |= PCI_COMMAND_SERR;
+-				bcommand |= PCI_BRIDGE_CTL_SERR;
+-			} else {
+-				command &= ~PCI_COMMAND_SERR;
+-				bcommand &= ~PCI_BRIDGE_CTL_SERR;
+-			}
+-		} else
+-			dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
+-	} else
+-		dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
+-
+-	if (command != cmd) {
+-		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
+-	}
+-	if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
+-		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
++	/*
++	 * _HPP settings apply to all child buses, until another _HPP is
++	 * encountered. If we don't find an _HPP for the input pci dev,
++	 * look for it in the parent device scope since that would apply to
++	 * this pci dev. If we don't find any _HPP, use hardcoded defaults
++	 */
++	while (pdev && (ACPI_FAILURE(status))) {
++		acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
++		if (!handle)
++			break;
++		status = acpi_run_hpp(handle, hpp);
++		if (!(pdev->bus->parent))
++			break;
++		/* Check if a parent object supports _HPP */
++		pdev = pdev->bus->parent->self;
+ 	}
+ }
+ 
+diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
+--- a/drivers/pci/hotplug/shpchprm_legacy.c
++++ b/drivers/pci/hotplug/shpchprm_legacy.c
+@@ -27,33 +27,11 @@
+  *
+  */
+ 
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+-#include <linux/init.h>
+-#include <asm/uaccess.h>
+-#ifdef CONFIG_IA64
+-#include <asm/iosapic.h>
+-#endif
+ #include "shpchp.h"
+-#include "shpchprm.h"
+-#include "shpchprm_legacy.h"
+-
+-static void __iomem *shpchp_rom_start;
+-static u16 unused_IRQ;
+-
+-void shpchprm_cleanup(void)
+-{
+-	if (shpchp_rom_start)
+-		iounmap(shpchp_rom_start);
+-}
+-
+-int shpchprm_print_pirt(void)
+-{
+-	return 0;
+-}
+ 
+ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
+ {
+@@ -63,377 +41,14 @@ int shpchprm_get_physical_slot_number(st
+ 	return 0;
+ }
+ 
+-/* Find the Hot Plug Resource Table in the specified region of memory */
+-static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
+-{
+-	void __iomem *fp;
+-	void __iomem *endp;
+-	u8 temp1, temp2, temp3, temp4;
+-	int status = 0;
+-
+-	endp = (end - sizeof(struct hrt) + 1);
+-
+-	for (fp = begin; fp <= endp; fp += 16) {
+-		temp1 = readb(fp + SIG0);
+-		temp2 = readb(fp + SIG1);
+-		temp3 = readb(fp + SIG2);
+-		temp4 = readb(fp + SIG3);
+-		if (temp1 == '$' && temp2 == 'H' && temp3 == 'R' && temp4 == 'T') {
+-			status = 1;
+-			break;
+-		}
+-	}
+-
+-	if (!status)
+-		fp = NULL;
+-
+-	dbg("Discovered Hotplug Resource Table at %p\n", fp);
+-	return fp;
+-}
+-
+-/*
+- * shpchprm_find_available_resources
+- *
+- *  Finds available memory, IO, and IRQ resources for programming
+- *  devices which may be added to the system
+- *  this function is for hot plug ADD!
+- *
+- * returns 0 if success
+- */
+-int shpchprm_find_available_resources(struct controller *ctrl)
+-{
+-	u8 populated_slot;
+-	u8 bridged_slot;
+-	void __iomem *one_slot;
+-	struct pci_func *func = NULL;
+-	int i = 10, index = 0;
+-	u32 temp_dword, rc;
+-	ulong temp_ulong;
+-	struct pci_resource *mem_node;
+-	struct pci_resource *p_mem_node;
+-	struct pci_resource *io_node;
+-	struct pci_resource *bus_node;
+-	void __iomem *rom_resource_table;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	u8 cfgspc_irq, temp;
+-
+-	memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	rom_resource_table = detect_HRT_floating_pointer(shpchp_rom_start, shpchp_rom_start + 0xffff);
+-	dbg("rom_resource_table = %p\n", rom_resource_table);
+-	if (rom_resource_table == NULL)
+-		return -ENODEV;
+-
+-	/* Sum all resources and setup resource maps */
+-	unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
+-	dbg("unused_IRQ = %x\n", unused_IRQ);
+-
+-	temp = 0;
+-	while (unused_IRQ) {
+-		if (unused_IRQ & 1) {
+-			shpchp_disk_irq = temp;
+-			break;
+-		}
+-		unused_IRQ = unused_IRQ >> 1;
+-		temp++;
+-	}
+-
+-	dbg("shpchp_disk_irq= %d\n", shpchp_disk_irq);
+-	unused_IRQ = unused_IRQ >> 1;
+-	temp++;
+-
+-	while (unused_IRQ) {
+-		if (unused_IRQ & 1) {
+-			shpchp_nic_irq = temp;
+-			break;
+-		}
+-		unused_IRQ = unused_IRQ >> 1;
+-		temp++;
+-	}
+-
+-	dbg("shpchp_nic_irq= %d\n", shpchp_nic_irq);
+-	unused_IRQ = readl(rom_resource_table + PCIIRQ);
+-
+-	temp = 0;
+-
+-	pci_read_config_byte(ctrl->pci_dev, PCI_INTERRUPT_LINE, &cfgspc_irq);
+-
+-	if (!shpchp_nic_irq) {
+-		shpchp_nic_irq = cfgspc_irq;
+-	}
+-
+-	if (!shpchp_disk_irq) {
+-		shpchp_disk_irq = cfgspc_irq;
+-	}
+-
+-	dbg("shpchp_disk_irq, shpchp_nic_irq= %d, %d\n", shpchp_disk_irq, shpchp_nic_irq);
+-
+-	one_slot = rom_resource_table + sizeof(struct hrt);
+-
+-	i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
+-	dbg("number_of_entries = %d\n", i);
+-
+-	if (!readb(one_slot + SECONDARY_BUS))
+-		return (1);
+-
+-	dbg("dev|IO base|length|MEMbase|length|PM base|length|PB SB MB\n");
+-
+-	while (i && readb(one_slot + SECONDARY_BUS)) {
+-		u8 dev_func = readb(one_slot + DEV_FUNC);
+-		u8 primary_bus = readb(one_slot + PRIMARY_BUS);
+-		u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
+-		u8 max_bus = readb(one_slot + MAX_BUS);
+-		u16 io_base = readw(one_slot + IO_BASE);
+-		u16 io_length = readw(one_slot + IO_LENGTH);
+-		u16 mem_base = readw(one_slot + MEM_BASE);
+-		u16 mem_length = readw(one_slot + MEM_LENGTH);
+-		u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
+-		u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);
+-
+-		dbg("%2.2x |  %4.4x | %4.4x |  %4.4x | %4.4x |  %4.4x | %4.4x |%2.2x %2.2x %2.2x\n",
+-				dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
+-				primary_bus, secondary_bus, max_bus);
+-
+-		/* If this entry isn't for our controller's bus, ignore it */
+-		if (primary_bus != ctrl->slot_bus) {
+-			i--;
+-			one_slot += sizeof(struct slot_rt);
+-			continue;
+-		}
+-		/* find out if this entry is for an occupied slot */
+-		temp_dword = 0xFFFFFFFF;
+-		pci_bus->number = primary_bus;
+-		pci_bus_read_config_dword(pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
+-
+-		dbg("temp_D_word = %x\n", temp_dword);
+-
+-		if (temp_dword != 0xFFFFFFFF) {
+-			index = 0;
+-			func = shpchp_slot_find(primary_bus, dev_func >> 3, 0);
+-
+-			while (func && (func->function != (dev_func & 0x07))) {
+-				dbg("func = %p b:d:f(%x:%x:%x)\n", func, primary_bus, dev_func >> 3, index);
+-				func = shpchp_slot_find(primary_bus, dev_func >> 3, index++);
+-			}
+-
+-			/* If we can't find a match, skip this table entry */
+-			if (!func) {
+-				i--;
+-				one_slot += sizeof(struct slot_rt);
+-				continue;
+-			}
+-			/* this may not work and shouldn't be used */
+-			if (secondary_bus != primary_bus)
+-				bridged_slot = 1;
+-			else
+-				bridged_slot = 0;
+-
+-			populated_slot = 1;
+-		} else {
+-			populated_slot = 0;
+-			bridged_slot = 0;
+-		}
+-		dbg("slot populated =%s \n", populated_slot?"yes":"no");
+-
+-		/* If we've got a valid IO base, use it */
+-
+-		temp_ulong = io_base + io_length;
+-
+-		if ((io_base) && (temp_ulong <= 0x10000)) {
+-			io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+-			if (!io_node)
+-				return -ENOMEM;
+-
+-			io_node->base = (ulong)io_base;
+-			io_node->length = (ulong)io_length;
+-			dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length);
+-
+-			if (!populated_slot) {
+-				io_node->next = ctrl->io_head;
+-				ctrl->io_head = io_node;
+-			} else {
+-				io_node->next = func->io_head;
+-				func->io_head = io_node;
+-			}
+-		}
+-
+-		/* If we've got a valid memory base, use it */
+-		temp_ulong = mem_base + mem_length;
+-		if ((mem_base) && (temp_ulong <= 0x10000)) {
+-			mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+-			if (!mem_node)
+-				return -ENOMEM;
+-
+-			mem_node->base = (ulong)mem_base << 16;
+-			mem_node->length = (ulong)(mem_length << 16);
+-			dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length);
+-
+-			if (!populated_slot) {
+-				mem_node->next = ctrl->mem_head;
+-				ctrl->mem_head = mem_node;
+-			} else {
+-				mem_node->next = func->mem_head;
+-				func->mem_head = mem_node;
+-			}
+-		}
+-
+-		/*
+-		 * If we've got a valid prefetchable memory base, and
+-		 * the base + length isn't greater than 0xFFFF
+-		 */
+-		temp_ulong = pre_mem_base + pre_mem_length;
+-		if ((pre_mem_base) && (temp_ulong <= 0x10000)) {
+-			p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+-			if (!p_mem_node)
+-				return -ENOMEM;
+-
+-			p_mem_node->base = (ulong)pre_mem_base << 16;
+-			p_mem_node->length = (ulong)pre_mem_length << 16;
+-			dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length);
+-
+-			if (!populated_slot) {
+-				p_mem_node->next = ctrl->p_mem_head;
+-				ctrl->p_mem_head = p_mem_node;
+-			} else {
+-				p_mem_node->next = func->p_mem_head;
+-				func->p_mem_head = p_mem_node;
+-			}
+-		}
+-
+-		/*
+-		 * If we've got a valid bus number, use it
+-		 * The second condition is to ignore bus numbers on
+-		 * populated slots that don't have PCI-PCI bridges
+-		 */
+-		if (secondary_bus && (secondary_bus != primary_bus)) {
+-			bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+-			if (!bus_node)
+-				return -ENOMEM;
+-
+-			bus_node->base = (ulong)secondary_bus;
+-			bus_node->length = (ulong)(max_bus - secondary_bus + 1);
+-			dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length);
+-
+-			if (!populated_slot) {
+-				bus_node->next = ctrl->bus_head;
+-				ctrl->bus_head = bus_node;
+-			} else {
+-				bus_node->next = func->bus_head;
+-				func->bus_head = bus_node;
+-			}
+-		}
+-
+-		i--;
+-		one_slot += sizeof(struct slot_rt);
+-	}
+-
+-	/* If all of the following fail, we don't have any resources for hot plug add */
+-	rc = 1;
+-	rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head));
+-	rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
+-	rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head));
+-	rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head));
+-
+-	return (rc);
+-}
+-
+-int shpchprm_set_hpp(
+-	struct controller *ctrl,
+-	struct pci_func *func,
+-	u8	card_type)
++void get_hp_params_from_firmware(struct pci_dev *dev,
++		struct hotplug_params *hpp)
+ {
+-	u32 rc;
+-	u8 temp_byte;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	unsigned int	devfn;
+-	memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	pci_bus->number = func->bus;
+-	devfn = PCI_DEVFN(func->device, func->function);
+-
+-	temp_byte = 0x40;	/* hard coded value for LT */
+-	if (card_type == PCI_HEADER_TYPE_BRIDGE) {
+-		/* set subordinate Latency Timer */
+-		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
+-		if (rc) {
+-			dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, 
+-				func->device, func->function);
+-			return rc;
+-		}
+-	}
+-
+-	/* set base Latency Timer */
+-	rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
+-	if (rc) {
+-		dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
+-		return rc;
+-	}
+-
+-	/* set Cache Line size */
+-	temp_byte = 0x08;	/* hard coded value for CLS */
+-	rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
+-	if (rc) {
+-		dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
+-	}
+-
+-	/* set enable_perr */
+-	/* set enable_serr */
+-
+-	return rc;
++	return;
+ }
+ 
+-void shpchprm_enable_card(
+-	struct controller *ctrl,
+-	struct pci_func *func,
+-	u8 card_type)
++void get_hp_hw_control_from_firmware(struct pci_dev *dev)
+ {
+-	u16 command, bcommand;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	unsigned int devfn;
+-	int rc;
+-
+-	memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	pci_bus->number = func->bus;
+-	devfn = PCI_DEVFN(func->device, func->function);
+-
+-	rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
+-	command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
+-		| PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
+-		| PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+-	rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
+-
+-	if (card_type == PCI_HEADER_TYPE_BRIDGE) {
+-		rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
+-		bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
+-			| PCI_BRIDGE_CTL_NO_ISA;
+-		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
+-	}
++	return;
+ }
+ 
+-static int legacy_shpchprm_init_pci(void)
+-{
+-	shpchp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
+-	if (!shpchp_rom_start) {
+-		err("Could not ioremap memory region for ROM\n");
+-		return -EIO;
+-	}
+-
+-	return 0;
+-}
+-
+-int shpchprm_init(enum php_ctlr_type ctrl_type)
+-{
+-	int retval;
+-
+-	switch (ctrl_type) {
+-	case PCI:
+-		retval = legacy_shpchprm_init_pci();
+-		break;
+-	default:
+-		retval = -ENODEV;
+-		break;
+-	}
+-
+-	return retval;
+-}
+diff --git a/drivers/pci/hotplug/shpchprm_legacy.h b/drivers/pci/hotplug/shpchprm_legacy.h
+deleted file mode 100644
+--- a/drivers/pci/hotplug/shpchprm_legacy.h
++++ /dev/null
+@@ -1,113 +0,0 @@
+-/*
+- * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform using HRT
+- *
+- * Copyright (C) 1995,2001 Compaq Computer Corporation
+- * Copyright (C) 2001 Greg Kroah-Hartman (greg at kroah.com)
+- * Copyright (C) 2001 IBM Corp.
+- * Copyright (C) 2003-2004 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+- *
+- * Send feedback to <greg at kroah.com>, <kristen.c.accardi at intel.com>
+- *
+- */
+-
+-#ifndef _SHPCHPRM_LEGACY_H_
+-#define _SHPCHPRM_LEGACY_H_
+-
+-#define ROM_PHY_ADDR	0x0F0000
+-#define ROM_PHY_LEN	0x00FFFF
+-
+-struct slot_rt {
+-	u8 dev_func;
+-	u8 primary_bus;
+-	u8 secondary_bus;
+-	u8 max_bus;
+-	u16 io_base;
+-	u16 io_length;
+-	u16 mem_base;
+-	u16 mem_length;
+-	u16 pre_mem_base;
+-	u16 pre_mem_length;
+-} __attribute__ ((packed));
+-
+-/* offsets to the hotplug slot resource table registers based on the above structure layout */
+-enum slot_rt_offsets {
+-	DEV_FUNC = offsetof(struct slot_rt, dev_func),
+-	PRIMARY_BUS = offsetof(struct slot_rt, primary_bus),
+-	SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus),
+-	MAX_BUS = offsetof(struct slot_rt, max_bus),
+-	IO_BASE = offsetof(struct slot_rt, io_base),
+-	IO_LENGTH = offsetof(struct slot_rt, io_length),
+-	MEM_BASE = offsetof(struct slot_rt, mem_base),
+-	MEM_LENGTH = offsetof(struct slot_rt, mem_length),
+-	PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base),
+-	PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length),
+-};
+-
+-struct hrt {
+-	char sig0;
+-	char sig1;
+-	char sig2;
+-	char sig3;
+-	u16 unused_IRQ;
+-	u16 PCIIRQ;
+-	u8 number_of_entries;
+-	u8 revision;
+-	u16 reserved1;
+-	u32 reserved2;
+-} __attribute__ ((packed));
+-
+-/* offsets to the hotplug resource table registers based on the above structure layout */
+-enum hrt_offsets {
+-	SIG0 = offsetof(struct hrt, sig0),
+-	SIG1 = offsetof(struct hrt, sig1),
+-	SIG2 = offsetof(struct hrt, sig2),
+-	SIG3 = offsetof(struct hrt, sig3),
+-	UNUSED_IRQ = offsetof(struct hrt, unused_IRQ),
+-	PCIIRQ = offsetof(struct hrt, PCIIRQ),
+-	NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries),
+-	REVISION = offsetof(struct hrt, revision),
+-	HRT_RESERVED1 = offsetof(struct hrt, reserved1),
+-	HRT_RESERVED2 = offsetof(struct hrt, reserved2),
+-};
+-
+-struct irq_info {
+-	u8 bus, devfn;		/* bus, device and function */
+-	struct {
+-		u8 link;	/* IRQ line ID, chipset dependent, 0=not routed */
+-		u16 bitmap;	/* Available IRQs */
+-	} __attribute__ ((packed)) irq[4];
+-	u8 slot;		/* slot number, 0=onboard */
+-	u8 rfu;
+-} __attribute__ ((packed));
+-
+-struct irq_routing_table {
+-	u32 signature;		/* PIRQ_SIGNATURE should be here */
+-	u16 version;		/* PIRQ_VERSION */
+-	u16 size;			/* Table size in bytes */
+-	u8 rtr_bus, rtr_devfn;	/* Where the interrupt router lies */
+-	u16 exclusive_irqs;	/* IRQs devoted exclusively to PCI usage */
+-	u16 rtr_vendor, rtr_device;	/* Vendor and device ID of interrupt router */
+-	u32 miniport_data;	/* Crap */
+-	u8 rfu[11];
+-	u8 checksum;		/* Modulo 256 checksum must give zero */
+-	struct irq_info slots[0];
+-} __attribute__ ((packed));
+-
+-#endif				/* _SHPCHPRM_LEGACY_H_ */
+diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
+--- a/drivers/pci/hotplug/shpchprm_nonacpi.c
++++ b/drivers/pci/hotplug/shpchprm_nonacpi.c
+@@ -32,24 +32,9 @@
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+-#include <linux/init.h>
+-#include <asm/uaccess.h>
+-#ifdef CONFIG_IA64
+-#include <asm/iosapic.h>
+-#endif
+-#include "shpchp.h"
+-#include "shpchprm.h"
+-#include "shpchprm_nonacpi.h"
++#include <linux/slab.h>
+ 
+-void shpchprm_cleanup(void)
+-{
+-	return;
+-}
+-
+-int shpchprm_print_pirt(void)
+-{
+-	return 0;
+-}
++#include "shpchp.h"
+ 
+ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
+ {
+@@ -60,375 +45,13 @@ int shpchprm_get_physical_slot_number(st
+ 	return 0;
+ }
+ 
+-static void print_pci_resource ( struct pci_resource	*aprh)
+-{
+-	struct pci_resource	*res;
+-
+-	for (res = aprh; res; res = res->next)
+-		dbg("        base= 0x%x length= 0x%x\n", res->base, res->length);
+-}
+-
+-
+-static void phprm_dump_func_res( struct pci_func *fun)
+-{
+-	struct pci_func *func = fun;
+-
+-	if (func->bus_head) {
+-		dbg(":    BUS Resources:\n");
+-		print_pci_resource (func->bus_head);
+-	}
+-	if (func->io_head) {
+-		dbg(":    IO Resources:\n");
+-		print_pci_resource (func->io_head);
+-	}
+-	if (func->mem_head) {
+-		dbg(":    MEM Resources:\n");
+-		print_pci_resource (func->mem_head);
+-	}
+-	if (func->p_mem_head) {
+-		dbg(":    PMEM Resources:\n");
+-		print_pci_resource (func->p_mem_head);
+-	}
+-}
+-
+-static int phprm_get_used_resources (
+-	struct controller *ctrl,
+-	struct pci_func *func
+-	)
+-{
+-	return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
+-}
+-
+-static int phprm_delete_resource(
+-	struct pci_resource **aprh,
+-	ulong base,
+-	ulong size)
+-{
+-	struct pci_resource *res;
+-	struct pci_resource *prevnode;
+-	struct pci_resource *split_node;
+-	ulong tbase;
+-
+-	shpchp_resource_sort_and_combine(aprh);
+-
+-	for (res = *aprh; res; res = res->next) {
+-		if (res->base > base)
+-			continue;
+-
+-		if ((res->base + res->length) < (base + size))
+-			continue;
+-
+-		if (res->base < base) {
+-			tbase = base;
+-
+-			if ((res->length - (tbase - res->base)) < size)
+-				continue;
+-
+-			split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+-			if (!split_node)
+-				return -ENOMEM;
+-
+-			split_node->base = res->base;
+-			split_node->length = tbase - res->base;
+-			res->base = tbase;
+-			res->length -= split_node->length;
+-
+-			split_node->next = res->next;
+-			res->next = split_node;
+-		}
+-
+-		if (res->length >= size) {
+-			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+-			if (!split_node)
+-				return -ENOMEM;
+-
+-			split_node->base = res->base + size;
+-			split_node->length = res->length - size;
+-			res->length = size;
+-
+-			split_node->next = res->next;
+-			res->next = split_node;
+-		}
+-
+-		if (*aprh == res) {
+-			*aprh = res->next;
+-		} else {
+-			prevnode = *aprh;
+-			while (prevnode->next != res)
+-				prevnode = prevnode->next;
+-
+-			prevnode->next = res->next;
+-		}
+-		res->next = NULL;
+-		kfree(res);
+-		break;
+-	}
+-
+-	return 0;
+-}
+-
+-
+-static int phprm_delete_resources(
+-	struct pci_resource **aprh,
+-	struct pci_resource *this
+-	)
+-{
+-	struct pci_resource *res;
+-
+-	for (res = this; res; res = res->next)
+-		phprm_delete_resource(aprh, res->base, res->length);
+-
+-	return 0;
+-}
+-
+-
+-static int configure_existing_function(
+-	struct controller *ctrl,
+-	struct pci_func *func
+-	)
+-{
+-	int rc;
+-
+-	/* see how much resources the func has used. */
+-	rc = phprm_get_used_resources (ctrl, func);
+-
+-	if (!rc) {
+-		/* subtract the resources used by the func from ctrl resources */
+-		rc  = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
+-		rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
+-		rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
+-		rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
+-		if (rc)
+-			warn("aCEF: cannot del used resources\n");
+-	} else
+-		err("aCEF: cannot get used resources\n");
+-
+-	return rc;
+-}
+-
+-static int bind_pci_resources_to_slots ( struct controller *ctrl)
+-{
+-	struct pci_func *func, new_func;
+-	int busn = ctrl->slot_bus;
+-	int devn, funn;
+-	u32	vid;
+-
+-	for (devn = 0; devn < 32; devn++) {
+-		for (funn = 0; funn < 8; funn++) {
+-			/*
+-			if (devn == ctrl->device && funn == ctrl->function)
+-				continue;
+-			 */
+-			/* find out if this entry is for an occupied slot */
+-			vid = 0xFFFFFFFF;
+-
+-			pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
+-
+-			if (vid != 0xFFFFFFFF) {
+-				func = shpchp_slot_find(busn, devn, funn);
+-				if (!func) {
+-					memset(&new_func, 0, sizeof(struct pci_func));
+-					new_func.bus = busn;
+-					new_func.device = devn;
+-					new_func.function = funn;
+-					new_func.is_a_board = 1;
+-					configure_existing_function(ctrl, &new_func);
+-					phprm_dump_func_res(&new_func);
+-				} else {
+-					configure_existing_function(ctrl, func);
+-					phprm_dump_func_res(func);
+-				}
+-				dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
+-			}
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static void phprm_dump_ctrl_res( struct controller *ctlr)
+-{
+-	struct controller *ctrl = ctlr;
+-
+-	if (ctrl->bus_head) {
+-		dbg(":    BUS Resources:\n");
+-		print_pci_resource (ctrl->bus_head);
+-	}
+-	if (ctrl->io_head) {
+-		dbg(":    IO Resources:\n");
+-		print_pci_resource (ctrl->io_head);
+-	}
+-	if (ctrl->mem_head) {
+-		dbg(":    MEM Resources:\n");
+-		print_pci_resource (ctrl->mem_head);
+-	}
+-	if (ctrl->p_mem_head) {
+-		dbg(":    PMEM Resources:\n");
+-		print_pci_resource (ctrl->p_mem_head);
+-	}
+-}
+-
+-/*
+- * phprm_find_available_resources
+- *
+- *  Finds available memory, IO, and IRQ resources for programming
+- *  devices which may be added to the system
+- *  this function is for hot plug ADD!
+- *
+- * returns 0 if success
+- */
+-int shpchprm_find_available_resources(struct controller *ctrl)
+-{
+-	struct pci_func func;
+-	u32 rc;
+-
+-	memset(&func, 0, sizeof(struct pci_func));
+-
+-	func.bus = ctrl->bus;
+-	func.device = ctrl->device;
+-	func.function = ctrl->function;
+-	func.is_a_board = 1;
+-
+-	/* Get resources for this PCI bridge */
+-	rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD);
+-	dbg("%s: shpchp_save_used_resources rc = %d\n", __FUNCTION__, rc);
+-
+-	if (func.mem_head)
+-		func.mem_head->next = ctrl->mem_head;
+-	ctrl->mem_head = func.mem_head;
+-
+-	if (func.p_mem_head)
+-		func.p_mem_head->next = ctrl->p_mem_head;
+-	ctrl->p_mem_head = func.p_mem_head;
+-
+-	if (func.io_head)
+-		func.io_head->next = ctrl->io_head;
+-	ctrl->io_head = func.io_head;
+-
+-	if(func.bus_head)
+-		func.bus_head->next = ctrl->bus_head;
+-	ctrl->bus_head = func.bus_head;
+-	if (ctrl->bus_head)
+-		phprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
+-
+-	dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
+-	phprm_dump_ctrl_res(ctrl);
+-	bind_pci_resources_to_slots (ctrl);
+-
+-	dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
+-	phprm_dump_ctrl_res(ctrl);
+-
+-
+-	/* If all of the following fail, we don't have any resources for hot plug add */
+-	rc = 1;
+-	rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head));
+-	rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
+-	rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head));
+-	rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head));
+-
+-	return (rc);
+-}
+-
+-int shpchprm_set_hpp(
+-	struct controller *ctrl,
+-	struct pci_func *func,
+-	u8	card_type)
+-{
+-	u32 rc;
+-	u8 temp_byte;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	unsigned int	devfn;
+-	memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	pci_bus->number = func->bus;
+-	devfn = PCI_DEVFN(func->device, func->function);
+-
+-	temp_byte = 0x40;	/* hard coded value for LT */
+-	if (card_type == PCI_HEADER_TYPE_BRIDGE) {
+-		/* set subordinate Latency Timer */
+-		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
+-
+-		if (rc) {
+-			dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, 
+-				func->device, func->function);
+-			return rc;
+-		}
+-	}
+-
+-	/* set base Latency Timer */
+-	rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
+-
+-	if (rc) {
+-		dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
+-		return rc;
+-	}
+-
+-	/* set Cache Line size */
+-	temp_byte = 0x08;	/* hard coded value for CLS */
+-
+-	rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
+-
+-	if (rc) {
+-		dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
+-	}
+-
+-	/* set enable_perr */
+-	/* set enable_serr */
+-
+-	return rc;
+-}
+-
+-void shpchprm_enable_card(
+-	struct controller *ctrl,
+-	struct pci_func *func,
+-	u8 card_type)
++void get_hp_params_from_firmware(struct pci_dev *dev,
++		struct hotplug_params *hpp)
+ {
+-	u16 command, bcommand;
+-	struct pci_bus lpci_bus, *pci_bus;
+-	unsigned int devfn;
+-	int rc;
+-
+-	memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
+-	pci_bus = &lpci_bus;
+-	pci_bus->number = func->bus;
+-	devfn = PCI_DEVFN(func->device, func->function);
+-
+-	rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
+-
+-	command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
+-		| PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
+-		| PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+-
+-	rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
+-
+-	if (card_type == PCI_HEADER_TYPE_BRIDGE) {
+-
+-		rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
+-
+-		bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
+-			| PCI_BRIDGE_CTL_NO_ISA;
+-
+-		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
+-	}
+-}
+-
+-static int legacy_shpchprm_init_pci(void)
+-{
+-	return 0;
++	return;
+ }
+ 
+-int shpchprm_init(enum php_ctlr_type ctrl_type)
++void get_hp_hw_control_from_firmware(struct pci_dev *dev)
+ {
+-	int retval;
+-
+-	switch (ctrl_type) {
+-	case PCI:
+-		retval = legacy_shpchprm_init_pci();
+-		break;
+-	default:
+-		retval = -ENODEV;
+-		break;
+-	}
+-
+-	return retval;
++	return;
+ }
+diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.h b/drivers/pci/hotplug/shpchprm_nonacpi.h
+deleted file mode 100644
+--- a/drivers/pci/hotplug/shpchprm_nonacpi.h
++++ /dev/null
+@@ -1,56 +0,0 @@
+-/*
+- * SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
+- *
+- * Copyright (C) 1995,2001 Compaq Computer Corporation
+- * Copyright (C) 2001 Greg Kroah-Hartman (greg at kroah.com)
+- * Copyright (C) 2001 IBM Corp.
+- * Copyright (C) 2003-2004 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+- *
+- * Send feedback to <greg at kroah.com>, <kristen.c.accardi at intel.com>
+- *
+- */
+-
+-#ifndef _SHPCHPRM_NONACPI_H_
+-#define _SHPCHPRM_NONACPI_H_
+-
+-struct irq_info {
+-	u8 bus, devfn;		/* bus, device and function */
+-	struct {
+-		u8 link;	/* IRQ line ID, chipset dependent, 0=not routed */
+-		u16 bitmap;	/* Available IRQs */
+-	} __attribute__ ((packed)) irq[4];
+-	u8 slot;		/* slot number, 0=onboard */
+-	u8 rfu;
+-} __attribute__ ((packed));
+-
+-struct irq_routing_table {
+-	u32 signature;		/* PIRQ_SIGNATURE should be here */
+-	u16 version;		/* PIRQ_VERSION */
+-	u16 size;			/* Table size in bytes */
+-	u8 rtr_bus, rtr_devfn;	/* Where the interrupt router lies */
+-	u16 exclusive_irqs;	/* IRQs devoted exclusively to PCI usage */
+-	u16 rtr_vendor, rtr_device;	/* Vendor and device ID of interrupt router */
+-	u32 miniport_data;	/* Crap */
+-	u8 rfu[11];
+-	u8 checksum;		/* Modulo 256 checksum must give zero */
+-	struct irq_info slots[0];
+-} __attribute__ ((packed));
+-
+-#endif				/* _SHPCHPRM_NONACPI_H_ */
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -575,6 +575,8 @@ static int msi_capability_init(struct pc
+ /**
+  * msix_capability_init - configure device's MSI-X capability
+  * @dev: pointer to the pci_dev data structure of MSI-X device function
++ * @entries: pointer to an array of struct msix_entry entries
++ * @nvec: number of @entries
+  *
+  * Setup the MSI-X capability structure of device function with a
+  * single MSI-X vector. A return of zero indicates the successful setup of
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -8,6 +8,8 @@
+ #include <linux/init.h>
+ #include <linux/device.h>
+ #include <linux/mempolicy.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include "pci.h"
+ 
+ /*
+@@ -26,7 +28,10 @@ struct pci_dynid {
+ #ifdef CONFIG_HOTPLUG
+ 
+ /**
+- * store_new_id
++ * store_new_id - add a new PCI device ID to this driver and re-probe devices
++ * @driver: target device driver
++ * @buf: buffer for scanning device ID data
++ * @count: input size
+  *
+  * Adds a new dynamic pci device ID to this driver,
+  * and causes the driver to probe for all devices again.
+@@ -194,8 +199,10 @@ static int pci_call_probe(struct pci_dri
+ 
+ /**
+  * __pci_device_probe()
++ * @drv: driver to call to check if it wants the PCI device
++ * @pci_dev: PCI device being probed
+  * 
+- * returns 0  on success, else error.
++ * returns 0 on success, else error.
+  * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
+  */
+ static int
+@@ -377,6 +384,10 @@ int pci_register_driver(struct pci_drive
+ 	 * the pci shutdown function, this test can go away. */
+ 	if (!drv->driver.shutdown)
+ 		drv->driver.shutdown = pci_device_shutdown;
++	else
++		printk(KERN_WARNING "Warning: PCI driver %s has a struct "
++			"device_driver shutdown method, please update!\n",
++			drv->name);
+ 	drv->driver.owner = drv->owner;
+ 	drv->driver.kobj.ktype = &pci_driver_kobj_type;
+ 
+@@ -436,11 +447,11 @@ pci_dev_driver(const struct pci_dev *dev
+ 
+ /**
+  * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
+- * @ids: array of PCI device id structures to search in
+  * @dev: the PCI device structure to match against
++ * @drv: the device driver to search for matching PCI device id structures
+  * 
+  * Used by a driver to check whether a PCI device present in the
+- * system is in its list of supported devices.Returns the matching
++ * system is in its list of supported devices. Returns the matching
+  * pci_device_id structure or %NULL if there is no match.
+  */
+ static int pci_bus_match(struct device *dev, struct device_driver *drv)
+diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -130,7 +130,7 @@ pci_read_config(struct kobject *kobj, ch
+ 
+ 	if ((off & 1) && size) {
+ 		u8 val;
+-		pci_read_config_byte(dev, off, &val);
++		pci_user_read_config_byte(dev, off, &val);
+ 		data[off - init_off] = val;
+ 		off++;
+ 		size--;
+@@ -138,7 +138,7 @@ pci_read_config(struct kobject *kobj, ch
+ 
+ 	if ((off & 3) && size > 2) {
+ 		u16 val;
+-		pci_read_config_word(dev, off, &val);
++		pci_user_read_config_word(dev, off, &val);
+ 		data[off - init_off] = val & 0xff;
+ 		data[off - init_off + 1] = (val >> 8) & 0xff;
+ 		off += 2;
+@@ -147,7 +147,7 @@ pci_read_config(struct kobject *kobj, ch
+ 
+ 	while (size > 3) {
+ 		u32 val;
+-		pci_read_config_dword(dev, off, &val);
++		pci_user_read_config_dword(dev, off, &val);
+ 		data[off - init_off] = val & 0xff;
+ 		data[off - init_off + 1] = (val >> 8) & 0xff;
+ 		data[off - init_off + 2] = (val >> 16) & 0xff;
+@@ -158,7 +158,7 @@ pci_read_config(struct kobject *kobj, ch
+ 
+ 	if (size >= 2) {
+ 		u16 val;
+-		pci_read_config_word(dev, off, &val);
++		pci_user_read_config_word(dev, off, &val);
+ 		data[off - init_off] = val & 0xff;
+ 		data[off - init_off + 1] = (val >> 8) & 0xff;
+ 		off += 2;
+@@ -167,7 +167,7 @@ pci_read_config(struct kobject *kobj, ch
+ 
+ 	if (size > 0) {
+ 		u8 val;
+-		pci_read_config_byte(dev, off, &val);
++		pci_user_read_config_byte(dev, off, &val);
+ 		data[off - init_off] = val;
+ 		off++;
+ 		--size;
+@@ -192,7 +192,7 @@ pci_write_config(struct kobject *kobj, c
+ 	}
+ 	
+ 	if ((off & 1) && size) {
+-		pci_write_config_byte(dev, off, data[off - init_off]);
++		pci_user_write_config_byte(dev, off, data[off - init_off]);
+ 		off++;
+ 		size--;
+ 	}
+@@ -200,7 +200,7 @@ pci_write_config(struct kobject *kobj, c
+ 	if ((off & 3) && size > 2) {
+ 		u16 val = data[off - init_off];
+ 		val |= (u16) data[off - init_off + 1] << 8;
+-                pci_write_config_word(dev, off, val);
++                pci_user_write_config_word(dev, off, val);
+                 off += 2;
+                 size -= 2;
+         }
+@@ -210,7 +210,7 @@ pci_write_config(struct kobject *kobj, c
+ 		val |= (u32) data[off - init_off + 1] << 8;
+ 		val |= (u32) data[off - init_off + 2] << 16;
+ 		val |= (u32) data[off - init_off + 3] << 24;
+-		pci_write_config_dword(dev, off, val);
++		pci_user_write_config_dword(dev, off, val);
+ 		off += 4;
+ 		size -= 4;
+ 	}
+@@ -218,13 +218,13 @@ pci_write_config(struct kobject *kobj, c
+ 	if (size >= 2) {
+ 		u16 val = data[off - init_off];
+ 		val |= (u16) data[off - init_off + 1] << 8;
+-		pci_write_config_word(dev, off, val);
++		pci_user_write_config_word(dev, off, val);
+ 		off += 2;
+ 		size -= 2;
+ 	}
+ 
+ 	if (size) {
+-		pci_write_config_byte(dev, off, data[off - init_off]);
++		pci_user_write_config_byte(dev, off, data[off - init_off]);
+ 		off++;
+ 		--size;
+ 	}
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -15,6 +15,7 @@
+ #include <linux/pci.h>
+ #include <linux/module.h>
+ #include <linux/spinlock.h>
++#include <linux/string.h>
+ #include <asm/dma.h>	/* isa_dma_bridge_buggy */
+ #include "pci.h"
+ 
+@@ -252,6 +253,8 @@ pci_restore_bars(struct pci_dev *dev)
+ 		pci_update_resource(dev, &dev->resource[i], i);
+ }
+ 
++int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
++
+ /**
+  * pci_set_power_state - Set the power state of a PCI device
+  * @dev: PCI device to be suspended
+@@ -266,7 +269,6 @@ pci_restore_bars(struct pci_dev *dev)
+  * -EIO if device does not support PCI PM.
+  * 0 if we can successfully change the power state.
+  */
+-int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
+ int
+ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
+ {
+@@ -314,19 +316,19 @@ pci_set_power_state(struct pci_dev *dev,
+ 	 * sets PowerState to 0.
+ 	 */
+ 	switch (dev->current_state) {
++	case PCI_D0:
++	case PCI_D1:
++	case PCI_D2:
++		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
++		pmcsr |= state;
++		break;
+ 	case PCI_UNKNOWN: /* Boot-up */
+ 		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
+ 		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+ 			need_restore = 1;
+ 		/* Fall-through: force to D0 */
+-	case PCI_D3hot:
+-	case PCI_D3cold:
+-	case PCI_POWER_ERROR:
+-		pmcsr = 0;
+-		break;
+ 	default:
+-		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+-		pmcsr |= state;
++		pmcsr = 0;
+ 		break;
+ 	}
+ 
+@@ -808,8 +810,8 @@ pci_clear_mwi(struct pci_dev *dev)
+ 
+ /**
+  * pci_intx - enables/disables PCI INTx for device dev
+- * @dev: the PCI device to operate on
+- * @enable: boolean
++ * @pdev: the PCI device to operate on
++ * @enable: boolean: whether to enable or disable PCI INTx
+  *
+  * Enables/disables PCI INTx for device dev
+  */
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -15,6 +15,13 @@ extern int pci_bus_alloc_resource(struct
+ extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
+ extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state);
+ 
++extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
++extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
++extern int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val);
++extern int pci_user_write_config_byte(struct pci_dev *dev, int where, u8 val);
++extern int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val);
++extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val);
++
+ /* PCI /proc functions */
+ #ifdef CONFIG_PROC_FS
+ extern int pci_proc_attach_device(struct pci_dev *dev);
+diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
+--- a/drivers/pci/pcie/portdrv_core.c
++++ b/drivers/pci/pcie/portdrv_core.c
+@@ -11,6 +11,8 @@
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/pm.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ #include <linux/pcieport_if.h>
+ 
+ #include "portdrv.h"
+@@ -61,7 +63,7 @@ static int pcie_port_remove_service(stru
+ 
+ static void pcie_port_shutdown_service(struct device *dev) {}
+ 
+-static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32 level)
++static int pcie_port_suspend_service(struct device *dev, pm_message_t state)
+ {
+ 	struct pcie_device *pciedev;
+ 	struct pcie_port_service_driver *driver;
+@@ -76,7 +78,7 @@ static int pcie_port_suspend_service(str
+ 	return 0;
+ }
+ 
+-static int pcie_port_resume_service(struct device *dev, u32 level)
++static int pcie_port_resume_service(struct device *dev)
+ {
+ 	struct pcie_device *pciedev;
+ 	struct pcie_port_service_driver *driver;
+diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
+--- a/drivers/pci/pcie/portdrv_pci.c
++++ b/drivers/pci/pcie/portdrv_pci.c
+@@ -12,6 +12,7 @@
+ #include <linux/errno.h>
+ #include <linux/pm.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ #include <linux/pcieport_if.h>
+ 
+ #include "portdrv.h"
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -669,6 +669,7 @@ static void pci_release_dev(struct devic
+ 
+ /**
+  * pci_cfg_space_size - get the configuration space size of the PCI device.
++ * @dev: PCI device
+  *
+  * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices
+  * have 4096 bytes.  Even if the device is capable, that doesn't mean we can
+diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
+--- a/drivers/pci/proc.c
++++ b/drivers/pci/proc.c
+@@ -80,7 +80,7 @@ proc_bus_pci_read(struct file *file, cha
+ 
+ 	if ((pos & 1) && cnt) {
+ 		unsigned char val;
+-		pci_read_config_byte(dev, pos, &val);
++		pci_user_read_config_byte(dev, pos, &val);
+ 		__put_user(val, buf);
+ 		buf++;
+ 		pos++;
+@@ -89,7 +89,7 @@ proc_bus_pci_read(struct file *file, cha
+ 
+ 	if ((pos & 3) && cnt > 2) {
+ 		unsigned short val;
+-		pci_read_config_word(dev, pos, &val);
++		pci_user_read_config_word(dev, pos, &val);
+ 		__put_user(cpu_to_le16(val), (unsigned short __user *) buf);
+ 		buf += 2;
+ 		pos += 2;
+@@ -98,7 +98,7 @@ proc_bus_pci_read(struct file *file, cha
+ 
+ 	while (cnt >= 4) {
+ 		unsigned int val;
+-		pci_read_config_dword(dev, pos, &val);
++		pci_user_read_config_dword(dev, pos, &val);
+ 		__put_user(cpu_to_le32(val), (unsigned int __user *) buf);
+ 		buf += 4;
+ 		pos += 4;
+@@ -107,7 +107,7 @@ proc_bus_pci_read(struct file *file, cha
+ 
+ 	if (cnt >= 2) {
+ 		unsigned short val;
+-		pci_read_config_word(dev, pos, &val);
++		pci_user_read_config_word(dev, pos, &val);
+ 		__put_user(cpu_to_le16(val), (unsigned short __user *) buf);
+ 		buf += 2;
+ 		pos += 2;
+@@ -116,7 +116,7 @@ proc_bus_pci_read(struct file *file, cha
+ 
+ 	if (cnt) {
+ 		unsigned char val;
+-		pci_read_config_byte(dev, pos, &val);
++		pci_user_read_config_byte(dev, pos, &val);
+ 		__put_user(val, buf);
+ 		buf++;
+ 		pos++;
+@@ -151,7 +151,7 @@ proc_bus_pci_write(struct file *file, co
+ 	if ((pos & 1) && cnt) {
+ 		unsigned char val;
+ 		__get_user(val, buf);
+-		pci_write_config_byte(dev, pos, val);
++		pci_user_write_config_byte(dev, pos, val);
+ 		buf++;
+ 		pos++;
+ 		cnt--;
+@@ -160,7 +160,7 @@ proc_bus_pci_write(struct file *file, co
+ 	if ((pos & 3) && cnt > 2) {
+ 		unsigned short val;
+ 		__get_user(val, (unsigned short __user *) buf);
+-		pci_write_config_word(dev, pos, le16_to_cpu(val));
++		pci_user_write_config_word(dev, pos, le16_to_cpu(val));
+ 		buf += 2;
+ 		pos += 2;
+ 		cnt -= 2;
+@@ -169,7 +169,7 @@ proc_bus_pci_write(struct file *file, co
+ 	while (cnt >= 4) {
+ 		unsigned int val;
+ 		__get_user(val, (unsigned int __user *) buf);
+-		pci_write_config_dword(dev, pos, le32_to_cpu(val));
++		pci_user_write_config_dword(dev, pos, le32_to_cpu(val));
+ 		buf += 4;
+ 		pos += 4;
+ 		cnt -= 4;
+@@ -178,7 +178,7 @@ proc_bus_pci_write(struct file *file, co
+ 	if (cnt >= 2) {
+ 		unsigned short val;
+ 		__get_user(val, (unsigned short __user *) buf);
+-		pci_write_config_word(dev, pos, le16_to_cpu(val));
++		pci_user_write_config_word(dev, pos, le16_to_cpu(val));
+ 		buf += 2;
+ 		pos += 2;
+ 		cnt -= 2;
+@@ -187,7 +187,7 @@ proc_bus_pci_write(struct file *file, co
+ 	if (cnt) {
+ 		unsigned char val;
+ 		__get_user(val, buf);
+-		pci_write_config_byte(dev, pos, val);
++		pci_user_write_config_byte(dev, pos, val);
+ 		buf++;
+ 		pos++;
+ 		cnt--;
+@@ -484,10 +484,10 @@ static int show_dev_config(struct seq_fi
+ 
+ 	drv = pci_dev_driver(dev);
+ 
+-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
+-	pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
+-	pci_read_config_byte (dev, PCI_MIN_GNT, &min_gnt);
+-	pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat);
++	pci_user_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
++	pci_user_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
++	pci_user_read_config_byte (dev, PCI_MIN_GNT, &min_gnt);
++	pci_user_read_config_byte (dev, PCI_MAX_LAT, &max_lat);
+ 	seq_printf(m, "  Bus %2d, device %3d, function %2d:\n",
+ 	       dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+ 	seq_printf(m, "    Class %04x", class_rev >> 16);
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -7,6 +7,9 @@
+  *
+  *  Copyright (c) 1999 Martin Mares <mj at ucw.cz>
+  *
++ *  Init/reset quirks for USB host controllers should be in the
++ *  USB quirks file, where their drivers can access reuse it.
++ *
+  *  The bridge optimization stuff has been removed. If you really
+  *  have a silly BIOS which is unable to set your host bridge right,
+  *  use the PowerTweak utility (see http://powertweak.sourceforge.net).
+@@ -353,7 +356,7 @@ static void piix4_mem_quirk(struct pci_d
+ /*
+  * PIIX4 ACPI: Two IO regions pointed to by longwords at
+  *	0x40 (64 bytes of ACPI registers)
+- *	0x90 (32 bytes of SMB registers)
++ *	0x90 (16 bytes of SMB registers)
+  * and a few strange programmable PIIX4 device resources.
+  */
+ static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
+@@ -363,7 +366,7 @@ static void __devinit quirk_piix4_acpi(s
+ 	pci_read_config_dword(dev, 0x40, &region);
+ 	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI");
+ 	pci_read_config_dword(dev, 0x90, &region);
+-	quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
++	quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
+ 
+ 	/* Device resource A has enables for some of the other ones */
+ 	pci_read_config_dword(dev, 0x5c, &res_a);
+@@ -414,6 +417,18 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801EB_0,		quirk_ich4_lpc_acpi );
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_ESB_1,		quirk_ich4_lpc_acpi );
+ 
++static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev)
++{
++	u32 region;
++
++	pci_read_config_dword(dev, 0x40, &region);
++	quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH6 ACPI/GPIO/TCO");
++
++	pci_read_config_dword(dev, 0x48, &region);
++	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO");
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi );
++
+ /*
+  * VIA ACPI: One IO region pointed to by longword at
+  *	0x48 or 0x20 (256 bytes of ACPI registers)
+@@ -633,28 +648,6 @@ static void quirk_via_irq(struct pci_dev
+ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
+ 
+ /*
+- * PIIX3 USB: We have to disable USB interrupts that are
+- * hardwired to PIRQD# and may be shared with an
+- * external device.
+- *
+- * Legacy Support Register (LEGSUP):
+- *     bit13:  USB PIRQ Enable (USBPIRQDEN),
+- *     bit4:   Trap/SMI On IRQ Enable (USBSMIEN).
+- *
+- * We mask out all r/wc bits, too.
+- */
+-static void __devinit quirk_piix3_usb(struct pci_dev *dev)
+-{
+-	u16 legsup;
+-
+-	pci_read_config_word(dev, 0xc0, &legsup);
+-	legsup &= 0x50ef;
+-	pci_write_config_word(dev, 0xc0, legsup);
+-}
+-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371SB_2,	quirk_piix3_usb );
+-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371AB_2,	quirk_piix3_usb );
+-
+-/*
+  * VIA VT82C598 has its device ID settable and many BIOSes
+  * set it to the ID of VT82C597 for backward compatibility.
+  * We need to switch it off to be able to recognize the real
+@@ -922,6 +915,12 @@ static void __init asus_hides_smbus_host
+ 			case 0x186a: /* M6Ne notebook */
+ 				asus_hides_smbus = 1;
+ 			}
++		if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {
++			switch (dev->subsystem_device) {
++			case 0x1882: /* M6V notebook */
++				asus_hides_smbus = 1;
++			}
++		}
+ 	} else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) {
+ 		if (dev->device ==  PCI_DEVICE_ID_INTEL_82855PM_HB)
+ 			switch(dev->subsystem_device) {
+@@ -932,6 +931,7 @@ static void __init asus_hides_smbus_host
+ 		if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
+ 			switch (dev->subsystem_device) {
+ 			case 0x12bc: /* HP D330L */
++			case 0x12bd: /* HP D530 */
+ 				asus_hides_smbus = 1;
+ 			}
+ 	} else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) {
+@@ -966,6 +966,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_7205_0,	asus_hides_smbus_hostbridge );
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82855PM_HB,	asus_hides_smbus_hostbridge );
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82855GM_HB,	asus_hides_smbus_hostbridge );
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge );
+ 
+ static void __init asus_hides_smbus_lpc(struct pci_dev *dev)
+ {
+@@ -990,6 +991,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801DB_12,	asus_hides_smbus_lpc );
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801EB_0,	asus_hides_smbus_lpc );
+ 
++static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
++{
++	u32 val, rcba;
++	void __iomem *base;
++
++	if (likely(!asus_hides_smbus))
++		return;
++	pci_read_config_dword(dev, 0xF0, &rcba);
++	base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */
++	if (base == NULL) return;
++	val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */
++	writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */
++	iounmap(base);
++	printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n");
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH6_1,	asus_hides_smbus_lpc_ich6 );
++
+ /*
+  * SiS 96x south bridge: BIOS typically hides SMBus device...
+  */
+@@ -1002,234 +1020,6 @@ static void __init quirk_sis_96x_smbus(s
+ 	pci_read_config_byte(dev, 0x77, &val);
+ }
+ 
+-
+-#define UHCI_USBLEGSUP		0xc0		/* legacy support */
+-#define UHCI_USBCMD		0		/* command register */
+-#define UHCI_USBSTS		2		/* status register */
+-#define UHCI_USBINTR		4		/* interrupt register */
+-#define UHCI_USBLEGSUP_DEFAULT	0x2000		/* only PIRQ enable set */
+-#define UHCI_USBCMD_RUN		(1 << 0)	/* RUN/STOP bit */
+-#define UHCI_USBCMD_GRESET	(1 << 2)	/* Global reset */
+-#define UHCI_USBCMD_CONFIGURE	(1 << 6)	/* config semaphore */
+-#define UHCI_USBSTS_HALTED	(1 << 5)	/* HCHalted bit */
+-
+-#define OHCI_CONTROL		0x04
+-#define OHCI_CMDSTATUS		0x08
+-#define OHCI_INTRSTATUS		0x0c
+-#define OHCI_INTRENABLE		0x10
+-#define OHCI_INTRDISABLE	0x14
+-#define OHCI_OCR		(1 << 3)	/* ownership change request */
+-#define OHCI_CTRL_IR		(1 << 8)	/* interrupt routing */
+-#define OHCI_INTR_OC		(1 << 30)	/* ownership change */
+-
+-#define EHCI_HCC_PARAMS		0x08		/* extended capabilities */
+-#define EHCI_USBCMD		0		/* command register */
+-#define EHCI_USBCMD_RUN		(1 << 0)	/* RUN/STOP bit */
+-#define EHCI_USBSTS		4		/* status register */
+-#define EHCI_USBSTS_HALTED	(1 << 12)	/* HCHalted bit */
+-#define EHCI_USBINTR		8		/* interrupt register */
+-#define EHCI_USBLEGSUP		0		/* legacy support register */
+-#define EHCI_USBLEGSUP_BIOS	(1 << 16)	/* BIOS semaphore */
+-#define EHCI_USBLEGSUP_OS	(1 << 24)	/* OS semaphore */
+-#define EHCI_USBLEGCTLSTS	4		/* legacy control/status */
+-#define EHCI_USBLEGCTLSTS_SOOE	(1 << 13)	/* SMI on ownership change */
+-
+-int usb_early_handoff __devinitdata = 0;
+-static int __init usb_handoff_early(char *str)
+-{
+-	usb_early_handoff = 1;
+-	return 0;
+-}
+-__setup("usb-handoff", usb_handoff_early);
+-
+-static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
+-{
+-	unsigned long base = 0;
+-	int wait_time, delta;
+-	u16 val, sts;
+-	int i;
+-
+-	for (i = 0; i < PCI_ROM_RESOURCE; i++)
+-		if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
+-			base = pci_resource_start(pdev, i);
+-			break;
+-		}
+-
+-	if (!base)
+-		return;
+-
+-	/*
+-	 * stop controller
+-	 */
+-	sts = inw(base + UHCI_USBSTS);
+-	val = inw(base + UHCI_USBCMD);
+-	val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE);
+-	outw(val, base + UHCI_USBCMD);
+-
+-	/*
+-	 * wait while it stops if it was running
+-	 */
+-	if ((sts & UHCI_USBSTS_HALTED) == 0)
+-	{
+-		wait_time = 1000;
+-		delta = 100;
+-
+-		do {
+-			outw(0x1f, base + UHCI_USBSTS);
+-			udelay(delta);
+-			wait_time -= delta;
+-			val = inw(base + UHCI_USBSTS);
+-			if (val & UHCI_USBSTS_HALTED)
+-				break;
+-		} while (wait_time > 0);
+-	}
+-
+-	/*
+-	 * disable interrupts & legacy support
+-	 */
+-	outw(0, base + UHCI_USBINTR);
+-	outw(0x1f, base + UHCI_USBSTS);
+-	pci_read_config_word(pdev, UHCI_USBLEGSUP, &val);
+-	if (val & 0xbf) 
+-		pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT);
+-		
+-}
+-
+-static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
+-{
+-	void __iomem *base;
+-	int wait_time;
+-
+-	base = ioremap_nocache(pci_resource_start(pdev, 0),
+-				     pci_resource_len(pdev, 0));
+-	if (base == NULL) return;
+-
+-	if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
+-		wait_time = 500; /* 0.5 seconds */
+-		writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
+-		writel(OHCI_OCR, base + OHCI_CMDSTATUS);
+-		while (wait_time > 0 && 
+-				readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
+-			wait_time -= 10;
+-			msleep(10);
+-		}
+-	}
+-
+-	/*
+-	 * disable interrupts
+-	 */
+-	writel(~(u32)0, base + OHCI_INTRDISABLE);
+-	writel(~(u32)0, base + OHCI_INTRSTATUS);
+-
+-	iounmap(base);
+-}
+-
+-static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
+-{
+-	int wait_time, delta;
+-	void __iomem *base, *op_reg_base;
+-	u32 hcc_params, val, temp;
+-	u8 cap_length;
+-
+-	base = ioremap_nocache(pci_resource_start(pdev, 0),
+-				pci_resource_len(pdev, 0));
+-	if (base == NULL) return;
+-
+-	cap_length = readb(base);
+-	op_reg_base = base + cap_length;
+-	hcc_params = readl(base + EHCI_HCC_PARAMS);
+-	hcc_params = (hcc_params >> 8) & 0xff;
+-	if (hcc_params) {
+-		pci_read_config_dword(pdev, 
+-					hcc_params + EHCI_USBLEGSUP,
+-					&val);
+-		if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) {
+-			/*
+-			 * Ok, BIOS is in smm mode, try to hand off...
+-			 */
+-			pci_read_config_dword(pdev,
+-						hcc_params + EHCI_USBLEGCTLSTS,
+-						&temp);
+-			pci_write_config_dword(pdev,
+-						hcc_params + EHCI_USBLEGCTLSTS,
+-						temp | EHCI_USBLEGCTLSTS_SOOE);
+-			val |= EHCI_USBLEGSUP_OS;
+-			pci_write_config_dword(pdev, 
+-						hcc_params + EHCI_USBLEGSUP, 
+-						val);
+-
+-			wait_time = 500;
+-			do {
+-				msleep(10);
+-				wait_time -= 10;
+-				pci_read_config_dword(pdev,
+-						hcc_params + EHCI_USBLEGSUP,
+-						&val);
+-			} while (wait_time && (val & EHCI_USBLEGSUP_BIOS));
+-			if (!wait_time) {
+-				/*
+-				 * well, possibly buggy BIOS...
+-				 */
+-				printk(KERN_WARNING "EHCI early BIOS handoff "
+-						"failed (BIOS bug ?)\n");
+-				pci_write_config_dword(pdev,
+-						hcc_params + EHCI_USBLEGSUP,
+-						EHCI_USBLEGSUP_OS);
+-				pci_write_config_dword(pdev,
+-						hcc_params + EHCI_USBLEGCTLSTS,
+-						0);
+-			}
+-		}
+-	}
+-
+-	/*
+-	 * halt EHCI & disable its interrupts in any case
+-	 */
+-	val = readl(op_reg_base + EHCI_USBSTS);
+-	if ((val & EHCI_USBSTS_HALTED) == 0) {
+-		val = readl(op_reg_base + EHCI_USBCMD);
+-		val &= ~EHCI_USBCMD_RUN;
+-		writel(val, op_reg_base + EHCI_USBCMD);
+-
+-		wait_time = 2000;
+-		delta = 100;
+-		do {
+-			writel(0x3f, op_reg_base + EHCI_USBSTS);
+-			udelay(delta);
+-			wait_time -= delta;
+-			val = readl(op_reg_base + EHCI_USBSTS);
+-			if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
+-				break;
+-			}
+-		} while (wait_time > 0);
+-	}
+-	writel(0, op_reg_base + EHCI_USBINTR);
+-	writel(0x3f, op_reg_base + EHCI_USBSTS);
+-
+-	iounmap(base);
+-
+-	return;
+-}
+-
+-
+-
+-static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
+-{
+-	if (!usb_early_handoff)
+-		return;
+-
+-	if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */
+-		quirk_usb_handoff_uhci(pdev);
+-	} else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */
+-		quirk_usb_handoff_ohci(pdev);
+-	} else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */
+-		quirk_usb_disable_ehci(pdev);
+-	}
+-
+-	return;
+-}
+-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
+-
+ /*
+  * ... This is further complicated by the fact that some SiS96x south
+  * bridges pretend to be 85C503/5513 instead.  In that case see if we
+diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
+--- a/drivers/pci/rom.c
++++ b/drivers/pci/rom.c
+@@ -9,6 +9,7 @@
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
++#include <linux/slab.h>
+ 
+ #include "pci.h"
+ 
+diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
+--- a/drivers/pci/syscall.c
++++ b/drivers/pci/syscall.c
+@@ -13,7 +13,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/syscalls.h>
+ #include <asm/uaccess.h>
+-
++#include "pci.h"
+ 
+ asmlinkage long
+ sys_pciconfig_read(unsigned long bus, unsigned long dfn,
+@@ -38,13 +38,13 @@ sys_pciconfig_read(unsigned long bus, un
+ 	lock_kernel();
+ 	switch (len) {
+ 	case 1:
+-		cfg_ret = pci_read_config_byte(dev, off, &byte);
++		cfg_ret = pci_user_read_config_byte(dev, off, &byte);
+ 		break;
+ 	case 2:
+-		cfg_ret = pci_read_config_word(dev, off, &word);
++		cfg_ret = pci_user_read_config_word(dev, off, &word);
+ 		break;
+ 	case 4:
+-		cfg_ret = pci_read_config_dword(dev, off, &dword);
++		cfg_ret = pci_user_read_config_dword(dev, off, &dword);
+ 		break;
+ 	default:
+ 		err = -EINVAL;
+@@ -112,7 +112,7 @@ sys_pciconfig_write(unsigned long bus, u
+ 		err = get_user(byte, (u8 __user *)buf);
+ 		if (err)
+ 			break;
+-		err = pci_write_config_byte(dev, off, byte);
++		err = pci_user_write_config_byte(dev, off, byte);
+ 		if (err != PCIBIOS_SUCCESSFUL)
+ 			err = -EIO;
+ 		break;
+@@ -121,7 +121,7 @@ sys_pciconfig_write(unsigned long bus, u
+ 		err = get_user(word, (u16 __user *)buf);
+ 		if (err)
+ 			break;
+-		err = pci_write_config_word(dev, off, word);
++		err = pci_user_write_config_word(dev, off, word);
+ 		if (err != PCIBIOS_SUCCESSFUL)
+ 			err = -EIO;
+ 		break;
+@@ -130,7 +130,7 @@ sys_pciconfig_write(unsigned long bus, u
+ 		err = get_user(dword, (u32 __user *)buf);
+ 		if (err)
+ 			break;
+-		err = pci_write_config_dword(dev, off, dword);
++		err = pci_user_write_config_dword(dev, off, dword);
+ 		if (err != PCIBIOS_SUCCESSFUL)
+ 			err = -EIO;
+ 		break;
+diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
+--- a/drivers/pcmcia/Kconfig
++++ b/drivers/pcmcia/Kconfig
+@@ -154,6 +154,16 @@ config TCIC
+ 	  "Bridge" is the name used for the hardware inside your computer that
+ 	  PCMCIA cards are plugged into. If unsure, say N.
+ 
++config PCMCIA_M8XX
++        tristate "MPC8xx PCMCIA support"
++        depends on PCMCIA && PPC
++        select PCCARD_NONSTATIC
++        help
++        Say Y here to include support for PowerPC 8xx series PCMCIA
++        controller.
++
++        This driver is also available as a module called m8xx_pcmcia.
++
+ config HD64465_PCMCIA
+ 	tristate "HD64465 host bridge support"
+ 	depends on HD64465 && PCMCIA
+diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
+--- a/drivers/pcmcia/Makefile
++++ b/drivers/pcmcia/Makefile
+@@ -25,6 +25,7 @@ obj-$(CONFIG_PD6729)				+= pd6729.o
+ obj-$(CONFIG_I82365)				+= i82365.o
+ obj-$(CONFIG_I82092)				+= i82092.o
+ obj-$(CONFIG_TCIC)				+= tcic.o
++obj-$(CONFIG_PCMCIA_M8XX)                              += m8xx_pcmcia.o
+ obj-$(CONFIG_HD64465_PCMCIA)			+= hd64465_ss.o
+ obj-$(CONFIG_PCMCIA_SA1100)			+= sa11xx_core.o sa1100_cs.o
+ obj-$(CONFIG_PCMCIA_SA1111)			+= sa11xx_core.o sa1111_cs.o
+@@ -42,9 +43,11 @@ pxa2xx_core-y					+= soc_common.o pxa2xx
+ au1x00_ss-y					+= au1000_generic.o
+ au1x00_ss-$(CONFIG_MIPS_PB1000)			+= au1000_pb1x00.o
+ au1x00_ss-$(CONFIG_MIPS_PB1100)			+= au1000_pb1x00.o
++au1x00_ss-$(CONFIG_MIPS_PB1200)			+= au1000_db1x00.o
+ au1x00_ss-$(CONFIG_MIPS_PB1500)			+= au1000_pb1x00.o
+ au1x00_ss-$(CONFIG_MIPS_DB1000)			+= au1000_db1x00.o
+ au1x00_ss-$(CONFIG_MIPS_DB1100)			+= au1000_db1x00.o
++au1x00_ss-$(CONFIG_MIPS_DB1200)                 += au1000_db1x00.o
+ au1x00_ss-$(CONFIG_MIPS_DB1500)			+= au1000_db1x00.o
+ au1x00_ss-$(CONFIG_MIPS_DB1550)			+= au1000_db1x00.o
+ au1x00_ss-$(CONFIG_MIPS_XXS1500)               += au1000_xxs1500.o
+@@ -57,6 +60,7 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720)		+
+ sa1100_cs-y					+= sa1100_generic.o
+ sa1100_cs-$(CONFIG_SA1100_ASSABET)		+= sa1100_assabet.o
+ sa1100_cs-$(CONFIG_SA1100_CERF)			+= sa1100_cerf.o
++sa1100_cs-$(CONFIG_SA1100_COLLIE)              += pxa2xx_sharpsl.o
+ sa1100_cs-$(CONFIG_SA1100_H3600)		+= sa1100_h3600.o
+ sa1100_cs-$(CONFIG_SA1100_SHANNON)		+= sa1100_shannon.o
+ sa1100_cs-$(CONFIG_SA1100_SIMPAD)		+= sa1100_simpad.o
+diff --git a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c
+--- a/drivers/pcmcia/au1000_db1x00.c
++++ b/drivers/pcmcia/au1000_db1x00.c
+@@ -40,7 +40,15 @@
+ #include <asm/irq.h>
+ #include <asm/signal.h>
+ #include <asm/mach-au1x00/au1000.h>
+-#include <asm/mach-db1x00/db1x00.h>
++
++#if defined(CONFIG_MIPS_DB1200)
++	#include <db1200.h>
++#elif defined(CONFIG_MIPS_PB1200)
++	#include <pb1200.h>
++#else
++	#include <asm/mach-db1x00/db1x00.h>
++	static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++#endif
+ 
+ #include "au1000_generic.h"
+ 
+@@ -50,7 +58,6 @@
+ #define debug(x,args...)
+ #endif
+ 
+-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ 
+ struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
+ extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
+@@ -59,6 +66,8 @@ static int db1x00_pcmcia_hw_init(struct 
+ {
+ #ifdef CONFIG_MIPS_DB1550
+ 	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
++#elif defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
++	skt->irq = skt->nr ? BOARD_PC1_INT : BOARD_PC0_INT;
+ #else
+ 	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
+ #endif
+@@ -85,11 +94,19 @@ db1x00_pcmcia_socket_state(struct au1000
+ 	switch (skt->nr) {
+ 	case 0:
+ 		vs = bcsr->status & 0x3;
++#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
++		inserted = BOARD_CARD_INSERTED(0);
++#else
+ 		inserted = !(bcsr->status & (1<<4));
++#endif
+ 		break;
+ 	case 1:
+ 		vs = (bcsr->status & 0xC)>>2;
++#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
++		inserted = BOARD_CARD_INSERTED(1);
++#else
+ 		inserted = !(bcsr->status & (1<<5));
++#endif
+ 		break;
+ 	default:/* should never happen */
+ 		return;
+diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
+--- a/drivers/pcmcia/au1000_generic.c
++++ b/drivers/pcmcia/au1000_generic.c
+@@ -42,7 +42,7 @@
+ #include <linux/notifier.h>
+ #include <linux/interrupt.h>
+ #include <linux/spinlock.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -490,7 +490,7 @@ int au1x00_drv_pcmcia_remove(struct devi
+ 		flush_scheduled_work();
+ 		skt->ops->hw_shutdown(skt);
+ 		au1x00_pcmcia_config_skt(skt, &dead_socket);
+-		iounmap(skt->virt_io);
++		iounmap(skt->virt_io + (u32)mips_io_port_base);
+ 		skt->virt_io = NULL;
+ 	}
+ 
+@@ -519,36 +519,15 @@ static int au1x00_drv_pcmcia_probe(struc
+ }
+ 
+ 
+-static int au1x00_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level)
+-{
+-	int ret = 0;
+-	if (level == SUSPEND_SAVE_STATE)
+-		ret = pcmcia_socket_dev_suspend(dev, state);
+-	return ret;
+-}
+-
+-static int au1x00_drv_pcmcia_resume(struct device *dev, u32 level)
+-{
+-	int ret = 0;
+-	if (level == RESUME_RESTORE_STATE)
+-		ret = pcmcia_socket_dev_resume(dev);
+-	return ret;
+-}
+-
+-
+ static struct device_driver au1x00_pcmcia_driver = {
+ 	.probe		= au1x00_drv_pcmcia_probe,
+ 	.remove		= au1x00_drv_pcmcia_remove,
+ 	.name		= "au1x00-pcmcia",
+ 	.bus		= &platform_bus_type,
+-	.suspend	= au1x00_drv_pcmcia_suspend,
+-	.resume		= au1x00_drv_pcmcia_resume
++	.suspend	= pcmcia_socket_dev_suspend,
++	.resume		= pcmcia_socket_dev_resume,
+ };
+ 
+-static struct platform_device au1x00_device = {
+-	.name = "au1x00-pcmcia",
+-	.id = 0,
+-};
+ 
+ /* au1x00_pcmcia_init()
+  *
+@@ -562,7 +541,6 @@ static int __init au1x00_pcmcia_init(voi
+ 	int error = 0;
+ 	if ((error = driver_register(&au1x00_pcmcia_driver)))
+ 		return error;
+-	platform_device_register(&au1x00_device);
+ 	return error;
+ }
+ 
+@@ -573,7 +551,6 @@ static int __init au1x00_pcmcia_init(voi
+ static void __exit au1x00_pcmcia_exit(void)
+ {
+ 	driver_unregister(&au1x00_pcmcia_driver);
+-	platform_device_unregister(&au1x00_device);
+ }
+ 
+ module_init(au1x00_pcmcia_init);
+diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
+--- a/drivers/pcmcia/au1000_generic.h
++++ b/drivers/pcmcia/au1000_generic.h
+@@ -44,13 +44,13 @@
+ /* pcmcia socket 1 needs external glue logic so the memory map
+  * differs from board to board.
+  */
+-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550)
++#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_PB1200)
+ #define AU1X_SOCK1_IO        0xF08000000
+ #define AU1X_SOCK1_PHYS_ATTR 0xF48000000
+ #define AU1X_SOCK1_PHYS_MEM  0xF88000000
+ #define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4800000
+ #define AU1X_SOCK1_PSEUDO_PHYS_MEM  0xF8800000
+-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
++#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || defined(CONFIG_MIPS_DB1200)
+ #define AU1X_SOCK1_IO        0xF04000000
+ #define AU1X_SOCK1_PHYS_ATTR 0xF44000000
+ #define AU1X_SOCK1_PHYS_MEM  0xF84000000
+diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
+--- a/drivers/pcmcia/ds.c
++++ b/drivers/pcmcia/ds.c
+@@ -1157,7 +1157,8 @@ static struct pcmcia_callback pcmcia_bus
+ 	.requery = pcmcia_bus_rescan,
+ };
+ 
+-static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
++static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
++					   struct class_interface *class_intf)
+ {
+ 	struct pcmcia_socket *socket = class_get_devdata(class_dev);
+ 	int ret;
+@@ -1192,7 +1193,8 @@ static int __devinit pcmcia_bus_add_sock
+ 	return 0;
+ }
+ 
+-static void pcmcia_bus_remove_socket(struct class_device *class_dev)
++static void pcmcia_bus_remove_socket(struct class_device *class_dev,
++				     struct class_interface *class_intf)
+ {
+ 	struct pcmcia_socket *socket = class_get_devdata(class_dev);
+ 
+diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
+--- a/drivers/pcmcia/hd64465_ss.c
++++ b/drivers/pcmcia/hd64465_ss.c
+@@ -37,7 +37,7 @@
+ #include <asm/errno.h>
+ #include <linux/irq.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/hd64465/hd64465.h>
+@@ -844,27 +844,11 @@ static void hs_exit_socket(hs_socket_t *
+ 	local_irq_restore(flags);
+ }
+ 
+-static int hd64465_suspend(struct device *dev, pm_message_t state, u32 level)
+-{
+-	int ret = 0;
+-	if (level == SUSPEND_SAVE_STATE)
+-		ret = pcmcia_socket_dev_suspend(dev, state);
+-	return ret;
+-}
+-
+-static int hd64465_resume(struct device *dev, u32 level)
+-{
+-	int ret = 0;
+-	if (level == RESUME_RESTORE_STATE)
+-		ret = pcmcia_socket_dev_resume(dev);
+-	return ret;
+-}
+-
+ static struct device_driver hd64465_driver = {
+ 	.name = "hd64465-pcmcia",
+ 	.bus = &platform_bus_type,
+-	.suspend = hd64465_suspend,
+-	.resume = hd64465_resume,
++	.suspend = pcmcia_socket_dev_suspend,
++	.resume = pcmcia_socket_dev_resume,
+ };
+ 
+ static struct platform_device hd64465_device = {
+diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
+--- a/drivers/pcmcia/i82365.c
++++ b/drivers/pcmcia/i82365.c
+@@ -47,7 +47,7 @@
+ #include <linux/delay.h>
+ #include <linux/workqueue.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/bitops.h>
+ #include <asm/irq.h>
+ #include <asm/io.h>
+@@ -1332,27 +1332,11 @@ static struct pccard_operations pcic_ope
+ 
+ /*====================================================================*/
+ 
+-static int i82365_suspend(struct device *dev, pm_message_t state, u32 level)
+-{
+-	int ret = 0;
+-	if (level == SUSPEND_SAVE_STATE)
+-		ret = pcmcia_socket_dev_suspend(dev, state);
+-	return ret;
+-}
+-
+-static int i82365_resume(struct device *dev, u32 level)
+-{
+-	int ret = 0;
+-	if (level == RESUME_RESTORE_STATE)
+-		ret = pcmcia_socket_dev_resume(dev);
+-	return ret;
+-}
+-
+ static struct device_driver i82365_driver = {
+ 	.name = "i82365",
+ 	.bus = &platform_bus_type,
+-	.suspend = i82365_suspend,
+-	.resume = i82365_resume,
++	.suspend = pcmcia_socket_dev_suspend,
++	.resume = pcmcia_socket_dev_resume,
+ };
+ 
+ static struct platform_device i82365_device = {
+diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
+--- a/drivers/pcmcia/m32r_cfc.c
++++ b/drivers/pcmcia/m32r_cfc.c
+@@ -23,7 +23,7 @@
+ #include <linux/delay.h>
+ #include <linux/workqueue.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/bitops.h>
+ #include <asm/irq.h>
+ #include <asm/io.h>
+@@ -731,28 +731,11 @@ static struct pccard_operations pcc_oper
+ 
+ /*====================================================================*/
+ 
+-static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level)
+-{
+-	int ret = 0;
+-	if (level == SUSPEND_SAVE_STATE)
+-		ret = pcmcia_socket_dev_suspend(dev, state);
+-	return ret;
+-}
+-
+-static int m32r_pcc_resume(struct device *dev, u32 level)
+-{
+-	int ret = 0;
+-	if (level == RESUME_RESTORE_STATE)
+-		ret = pcmcia_socket_dev_resume(dev);
+-	return ret;
+-}
+-
+-
+ static struct device_driver pcc_driver = {
+ 	.name = "cfc",
+ 	.bus = &platform_bus_type,
+-	.suspend = m32r_pcc_suspend,
+-	.resume = m32r_pcc_resume,
++	.suspend = pcmcia_socket_dev_suspend,
++	.resume = pcmcia_socket_dev_resume,
+ };
+ 
+ static struct platform_device pcc_device = {
+diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
+--- a/drivers/pcmcia/m32r_pcc.c
++++ b/drivers/pcmcia/m32r_pcc.c
+@@ -23,7 +23,7 @@
+ #include <linux/delay.h>
+ #include <linux/workqueue.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <asm/irq.h>
+ #include <asm/io.h>
+ #include <asm/bitops.h>
+@@ -695,28 +695,11 @@ static struct pccard_operations pcc_oper
+ 
+ /*====================================================================*/
+ 
+-static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level)
+-{
+-	int ret = 0;
+-	if (level == SUSPEND_SAVE_STATE)
+-		ret = pcmcia_socket_dev_suspend(dev, state);
+-	return ret;
+-}
+-
+-static int m32r_pcc_resume(struct device *dev, u32 level)
+-{
+-	int ret = 0;
+-	if (level == RESUME_RESTORE_STATE)
+-		ret = pcmcia_socket_dev_resume(dev);
+-	return ret;
+-}
+-
+-
+ static struct device_driver pcc_driver = {
+ 	.name = "pcc",
+ 	.bus = &platform_bus_type,
+-	.suspend = m32r_pcc_suspend,
+-	.resume = m32r_pcc_resume,
++	.suspend = pcmcia_socket_dev_suspend,
++	.resume = pcmcia_socket_dev_resume,
+ };
+ 
+ static struct platform_device pcc_device = {
+diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/pcmcia/m8xx_pcmcia.c
+@@ -0,0 +1,1290 @@
++/*
++ * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
++ *
++ * (C) 1999-2000 Magnus Damm <damm at bitsmart.com>
++ * (C) 2001-2002 Montavista Software, Inc.
++ *     <mlocke at mvista.com>
++ *
++ * Support for two slots by Cyclades Corporation
++ *     <oliver.kurth at cyclades.de>
++ * Further fixes, v2.6 kernel port
++ *     <marcelo.tosatti at cyclades.com>
++ *
++ * "The ExCA standard specifies that socket controllers should provide
++ * two IO and five memory windows per socket, which can be independently
++ * configured and positioned in the host address space and mapped to
++ * arbitrary segments of card address space. " - David A Hinds. 1999
++ *
++ * This controller does _not_ meet the ExCA standard.
++ *
++ * m8xx pcmcia controller brief info:
++ * + 8 windows (attrib, mem, i/o)
++ * + up to two slots (SLOT_A and SLOT_B)
++ * + inputpins, outputpins, event and mask registers.
++ * - no offset register. sigh.
++ *
++ * Because of the lacking offset register we must map the whole card.
++ * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
++ * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
++ * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
++ * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
++ * They are maximum 64KByte each...
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/string.h>
++
++#include <asm/io.h>
++#include <asm/bitops.h>
++#include <asm/segment.h>
++#include <asm/system.h>
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/timer.h>
++#include <linux/ioport.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++
++#include <asm/mpc8xx.h>
++#include <asm/8xx_immap.h>
++#include <asm/irq.h>
++
++#include <pcmcia/version.h>
++#include <pcmcia/cs_types.h>
++#include <pcmcia/cs.h>
++#include <pcmcia/ss.h>
++
++#ifdef PCMCIA_DEBUG
++static int pc_debug = PCMCIA_DEBUG;
++module_param(pc_debug, int, 0);
++#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
++#else
++#define dprintk(args...)
++#endif
++
++#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
++#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
++
++static const char *version = "Version 0.06, Aug 2005";
++MODULE_LICENSE("Dual MPL/GPL");
++
++#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
++
++/* The RPX series use SLOT_B */
++#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
++#define CONFIG_PCMCIA_SLOT_B
++#define CONFIG_BD_IS_MHZ
++#endif
++
++/* The ADS board use SLOT_A */
++#ifdef CONFIG_ADS
++#define CONFIG_PCMCIA_SLOT_A
++#define CONFIG_BD_IS_MHZ
++#endif
++
++/* The FADS series are a mess */
++#ifdef CONFIG_FADS
++#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821)
++#define CONFIG_PCMCIA_SLOT_A
++#else
++#define CONFIG_PCMCIA_SLOT_B
++#endif
++#endif
++
++/* Cyclades ACS uses both slots */
++#ifdef CONFIG_PRxK
++#define CONFIG_PCMCIA_SLOT_A
++#define CONFIG_PCMCIA_SLOT_B
++#endif
++
++#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
++
++#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
++
++#define PCMCIA_SOCKETS_NO 2
++/* We have only 8 windows, dualsocket support will be limited. */
++#define PCMCIA_MEM_WIN_NO 2
++#define PCMCIA_IO_WIN_NO  2
++#define PCMCIA_SLOT_MSG "SLOT_A and SLOT_B"
++
++#elif defined(CONFIG_PCMCIA_SLOT_A) || defined(CONFIG_PCMCIA_SLOT_B)
++
++#define PCMCIA_SOCKETS_NO 1
++/* full support for one slot */
++#define PCMCIA_MEM_WIN_NO 5
++#define PCMCIA_IO_WIN_NO  2
++
++/* define _slot_ to be able to optimize macros */
++
++#ifdef CONFIG_PCMCIA_SLOT_A
++#define _slot_ 0
++#define PCMCIA_SLOT_MSG "SLOT_A"
++#else
++#define _slot_ 1
++#define PCMCIA_SLOT_MSG "SLOT_B"
++#endif
++
++#else
++#error m8xx_pcmcia: Bad configuration!
++#endif
++
++/* ------------------------------------------------------------------------- */
++
++#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0   */
++#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte     */
++#define PCMCIA_IO_WIN_BASE  _IO_BASE   /* base address for io window 0       */
++
++#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level      */
++
++/* ------------------------------------------------------------------------- */
++
++/* 2.4.x and newer has this always in HZ */
++#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
++
++static int pcmcia_schlvl = PCMCIA_SCHLVL;
++
++static spinlock_t events_lock = SPIN_LOCK_UNLOCKED;
++
++
++#define PCMCIA_SOCKET_KEY_5V 1
++#define PCMCIA_SOCKET_KEY_LV 2
++
++/* look up table for pgcrx registers */
++static u32 *m8xx_pgcrx[2] = {
++	&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
++	&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
++};
++
++/*
++ * This structure is used to address each window in the PCMCIA controller.
++ *
++ * Keep in mind that we assume that pcmcia_win[n+1] is mapped directly
++ * after pcmcia_win[n]...
++ */
++
++struct pcmcia_win {
++	u32	br;
++	u32	or;
++};
++
++/*
++ * For some reason the hardware guys decided to make both slots share
++ * some registers.
++ *
++ * Could someone invent object oriented hardware ?
++ *
++ * The macros are used to get the right bit from the registers.
++ * SLOT_A : slot = 0
++ * SLOT_B : slot = 1
++ */
++
++#define M8XX_PCMCIA_VS1(slot)      (0x80000000 >> (slot << 4))
++#define M8XX_PCMCIA_VS2(slot)      (0x40000000 >> (slot << 4))
++#define M8XX_PCMCIA_VS_MASK(slot)  (0xc0000000 >> (slot << 4))
++#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
++
++#define M8XX_PCMCIA_WP(slot)       (0x20000000 >> (slot << 4))
++#define M8XX_PCMCIA_CD2(slot)      (0x10000000 >> (slot << 4))
++#define M8XX_PCMCIA_CD1(slot)      (0x08000000 >> (slot << 4))
++#define M8XX_PCMCIA_BVD2(slot)     (0x04000000 >> (slot << 4))
++#define M8XX_PCMCIA_BVD1(slot)     (0x02000000 >> (slot << 4))
++#define M8XX_PCMCIA_RDY(slot)      (0x01000000 >> (slot << 4))
++#define M8XX_PCMCIA_RDY_L(slot)    (0x00800000 >> (slot << 4))
++#define M8XX_PCMCIA_RDY_H(slot)    (0x00400000 >> (slot << 4))
++#define M8XX_PCMCIA_RDY_R(slot)    (0x00200000 >> (slot << 4))
++#define M8XX_PCMCIA_RDY_F(slot)    (0x00100000 >> (slot << 4))
++#define M8XX_PCMCIA_MASK(slot)     (0xFFFF0000 >> (slot << 4))
++
++#define M8XX_PCMCIA_POR_VALID    0x00000001
++#define M8XX_PCMCIA_POR_WRPROT   0x00000002
++#define M8XX_PCMCIA_POR_ATTRMEM  0x00000010
++#define M8XX_PCMCIA_POR_IO       0x00000018
++#define M8XX_PCMCIA_POR_16BIT    0x00000040
++
++#define M8XX_PGCRX(slot)  m8xx_pgcrx[slot]
++
++#define M8XX_PGCRX_CXOE    0x00000080
++#define M8XX_PGCRX_CXRESET 0x00000040
++
++/* we keep one lookup table per socket to check flags */
++
++#define PCMCIA_EVENTS_MAX 5  /* 4 max at a time + termination */
++
++struct event_table {
++	u32 regbit;
++	u32 eventbit;
++};
++
++struct socket_info {
++	void	(*handler)(void *info, u32 events);
++	void	*info;
++
++	u32 slot;
++
++	socket_state_t state;
++	struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
++	struct pccard_io_map  io_win[PCMCIA_IO_WIN_NO];
++	struct event_table events[PCMCIA_EVENTS_MAX];
++	struct pcmcia_socket socket;
++};
++
++static struct socket_info socket[PCMCIA_SOCKETS_NO];
++
++/*
++ * Search this table to see if the windowsize is
++ * supported...
++ */
++
++#define M8XX_SIZES_NO 32
++
++static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] =
++{
++	0x00000001, 0x00000002, 0x00000008, 0x00000004,
++	0x00000080, 0x00000040, 0x00000010, 0x00000020,
++	0x00008000, 0x00004000, 0x00001000, 0x00002000,
++	0x00000100, 0x00000200, 0x00000800, 0x00000400,
++
++	0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
++	0x01000000, 0x02000000, 0xffffffff, 0x04000000,
++	0x00010000, 0x00020000, 0x00080000, 0x00040000,
++	0x00800000, 0x00400000, 0x00100000, 0x00200000
++};
++
++/* ------------------------------------------------------------------------- */
++
++static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs);
++
++#define PCMCIA_BMT_LIMIT (15*4)  /* Bus Monitor Timeout value */
++
++/* ------------------------------------------------------------------------- */
++/* board specific stuff:                                                     */
++/* voltage_set(), hardware_enable() and hardware_disable()                   */
++/* ------------------------------------------------------------------------- */
++/* RPX Boards from Embedded Planet                                           */
++
++#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
++
++/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
++ * SYPCR is write once only, therefore must the slowest memory be faster
++ * than the bus monitor or we will get a machine check due to the bus timeout.
++ */
++
++#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
++
++#undef PCMCIA_BMT_LIMIT
++#define PCMCIA_BMT_LIMIT (6*8)
++
++static int voltage_set(int slot, int vcc, int vpp)
++{
++	u32 reg = 0;
++
++	switch(vcc) {
++	case 0: break;
++	case 33:
++		reg |= BCSR1_PCVCTL4;
++		break;
++	case 50:
++		reg |= BCSR1_PCVCTL5;
++		break;
++	default:
++		return 1;
++	}
++
++	switch(vpp) {
++	case 0: break;
++	case 33:
++	case 50:
++		if(vcc == vpp)
++			reg |= BCSR1_PCVCTL6;
++		else
++			return 1;
++		break;
++	case 120:
++		reg |= BCSR1_PCVCTL7;
++	default:
++		return 1;
++	}
++
++	if(!((vcc == 50) || (vcc == 0)))
++		return 1;
++
++	/* first, turn off all power */
++
++	out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) & ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7));
++
++	/* enable new powersettings */
++
++	out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) | reg);
++
++	return 0;
++}
++
++#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
++#define hardware_enable(_slot_)  /* No hardware to enable */
++#define hardware_disable(_slot_) /* No hardware to disable */
++
++#endif /* CONFIG_RPXCLASSIC */
++
++/* FADS Boards from Motorola                                               */
++
++#if defined(CONFIG_FADS)
++
++#define PCMCIA_BOARD_MSG "FADS"
++
++static int voltage_set(int slot, int vcc, int vpp)
++{
++	u32 reg = 0;
++
++	switch(vcc) {
++		case 0:
++			break;
++		case 33:
++			reg |= BCSR1_PCCVCC0;
++			break;
++		case 50:
++			reg |= BCSR1_PCCVCC1;
++			break;
++		default:
++			return 1;
++	}
++
++	switch(vpp) {
++		case 0:
++			break;
++		case 33:
++		case 50:
++			if(vcc == vpp)
++				reg |= BCSR1_PCCVPP1;
++			else
++				return 1;
++			break;
++		case 120:
++			if ((vcc == 33) || (vcc == 50))
++				reg |= BCSR1_PCCVPP0;
++			else
++				return 1;
++		default:
++			return 1;
++	}
++
++	/* first, turn off all power */
++	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
++
++	/* enable new powersettings */
++	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg);
++
++	return 0;
++}
++
++#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
++
++static void hardware_enable(int slot)
++{
++	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN);
++}
++
++static void hardware_disable(int slot)
++{
++	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) |  BCSR1_PCCEN);
++}
++
++#endif
++
++/* ------------------------------------------------------------------------- */
++/* Motorola MBX860                                                           */
++
++#if defined(CONFIG_MBX)
++
++#define PCMCIA_BOARD_MSG "MBX"
++
++static int voltage_set(int slot, int vcc, int vpp)
++{
++	u8 reg = 0;
++
++	switch(vcc) {
++		case 0:
++			break;
++		case 33:
++			reg |= CSR2_VCC_33;
++			break;
++		case 50:
++			reg |= CSR2_VCC_50;
++			break;
++		default:
++			return 1;
++	}
++
++	switch(vpp) {
++		case 0:
++			break;
++		case 33:
++		case 50:
++			if(vcc == vpp)
++				reg |= CSR2_VPP_VCC;
++			else
++				return 1;
++			break;
++		case 120:
++			if ((vcc == 33) || (vcc == 50))
++				reg |= CSR2_VPP_12;
++			else
++				return 1;
++		default:
++			return 1;
++	}
++
++	/* first, turn off all power */
++	out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
++
++	/* enable new powersettings */
++	out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg);
++
++	return 0;
++}
++
++#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
++#define hardware_enable(_slot_)  /* No hardware to enable */
++#define hardware_disable(_slot_) /* No hardware to disable */
++
++#endif /* CONFIG_MBX */
++
++#if defined(CONFIG_PRxK)
++#include <asm/cpld.h>
++extern volatile fpga_pc_regs *fpga_pc;
++
++#define PCMCIA_BOARD_MSG "MPC855T"
++
++static int voltage_set(int slot, int vcc, int vpp)
++{
++	u8 reg = 0;
++	u8 regread;
++	cpld_regs *ccpld = get_cpld();
++
++	switch(vcc) {
++		case 0:
++			break;
++		case 33:
++			reg |= PCMCIA_VCC_33;
++			break;
++		case 50:
++			reg |= PCMCIA_VCC_50;
++			break;
++		default:
++			return 1;
++	}
++
++	switch(vpp) {
++		case 0:
++			break;
++		case 33:
++		case 50:
++			if(vcc == vpp)
++				reg |= PCMCIA_VPP_VCC;
++			else
++				return 1;
++			break;
++		case 120:
++			if ((vcc == 33) || (vcc == 50))
++				reg |= PCMCIA_VPP_12;
++			else
++				return 1;
++		default:
++			return 1;
++	}
++
++	reg = reg >> (slot << 2);
++	regread = in_8(&ccpld->fpga_pc_ctl);
++	if (reg != (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) {
++		/* enable new powersettings */
++		regread = regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2));
++		out_8(&ccpld->fpga_pc_ctl, reg | regread);
++		msleep(100);
++	}
++
++	return 0;
++}
++
++#define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV
++#define hardware_enable(_slot_)  /* No hardware to enable */
++#define hardware_disable(_slot_) /* No hardware to disable */
++
++#endif /* CONFIG_PRxK */
++
++static void m8xx_shutdown(void)
++{
++	u32 m, i;
++	struct pcmcia_win *w;
++
++	for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
++		w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
++
++		out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, M8XX_PCMCIA_MASK(i));
++		out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & ~M8XX_PCMCIA_MASK(i));
++
++		/* turn off interrupt and disable CxOE */
++		out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
++
++		/* turn off memory windows */
++		for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
++			out_be32(&w->or, 0); /* set to not valid */
++			w++;
++		}
++
++		/* turn off voltage */
++		voltage_set(i, 0, 0);
++
++		/* disable external hardware */
++		hardware_disable(i);
++	}
++
++	free_irq(pcmcia_schlvl, NULL);
++}
++
++/* copied from tcic.c */
++
++static int m8xx_drv_suspend(struct device *dev, pm_message_t state, u32 level)
++{
++        int ret = 0;
++        if (level == SUSPEND_SAVE_STATE)
++                ret = pcmcia_socket_dev_suspend(dev, state);
++        return ret;
++}
++
++static int m8xx_drv_resume(struct device *dev, u32 level)
++{
++        int ret = 0;
++        if (level == RESUME_RESTORE_STATE)
++                ret = pcmcia_socket_dev_resume(dev);
++        return ret;
++}
++
++static struct device_driver m8xx_driver = {
++        .name = "m8xx-pcmcia",
++        .bus = &platform_bus_type,
++        .suspend = m8xx_drv_suspend,
++        .resume = m8xx_drv_resume,
++};
++
++static struct platform_device m8xx_device = {
++        .name = "m8xx-pcmcia",
++        .id = 0,
++};
++
++static u32 pending_events[PCMCIA_SOCKETS_NO];
++static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
++
++static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs)
++{
++	struct socket_info *s;
++	struct event_table *e;
++	unsigned int i, events, pscr, pipr, per;
++
++	dprintk("Interrupt!\n");
++	/* get interrupt sources */
++
++	pscr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr);
++	pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
++	per = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per);
++
++	for(i = 0; i < PCMCIA_SOCKETS_NO; i++) {
++		s = &socket[i];
++		e = &s->events[0];
++		events = 0;
++
++		while(e->regbit) {
++			if(pscr & e->regbit)
++				events |= e->eventbit;
++
++				e++;
++		}
++
++		/*
++		 * report only if both card detect signals are the same
++		 * not too nice done,
++		 * we depend on that CD2 is the bit to the left of CD1...
++		 */
++		if(events & SS_DETECT)
++			if(((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^
++				(pipr & M8XX_PCMCIA_CD1(i)))
++			{
++				events &= ~SS_DETECT;
++			}
++
++#ifdef PCMCIA_GLITCHY_CD
++		/*
++		 * I've experienced CD problems with my ADS board.
++		 * We make an extra check to see if there was a
++		 * real change of Card detection.
++		 */
++
++		if((events & SS_DETECT) &&
++		   ((pipr &
++		     (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) &&
++		   (s->state.Vcc | s->state.Vpp)) {
++			events &= ~SS_DETECT;
++			/*printk( "CD glitch workaround - CD = 0x%08x!\n",
++				(pipr & (M8XX_PCMCIA_CD2(i)
++					 | M8XX_PCMCIA_CD1(i))));*/
++		}
++#endif
++
++		/* call the handler */
++
++		dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, "
++			"pipr = 0x%08x\n",
++			i, events, pscr, pipr);
++
++		if(events) {
++			spin_lock(&pending_event_lock);
++			pending_events[i] |= events;
++			spin_unlock(&pending_event_lock);
++			/*
++			 * Turn off RDY_L bits in the PER mask on
++			 * CD interrupt receival.
++			 *
++			 * They can generate bad interrupts on the
++			 * ACS4,8,16,32.   - marcelo
++			 */
++			per &= ~M8XX_PCMCIA_RDY_L(0);
++			per &= ~M8XX_PCMCIA_RDY_L(1);
++
++			out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, per);
++
++			if (events)
++				pcmcia_parse_events(&socket[i].socket, events);
++		}
++	}
++
++	/* clear the interrupt sources */
++	out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, pscr);
++
++	dprintk("Interrupt done.\n");
++
++	return IRQ_HANDLED;
++}
++
++static u32 m8xx_get_graycode(u32 size)
++{
++	u32 k;
++
++	for(k = 0; k < M8XX_SIZES_NO; k++)
++		if(m8xx_size_to_gray[k] == size)
++			break;
++
++	if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
++		k = -1;
++
++	return k;
++}
++
++static u32 m8xx_get_speed(u32 ns, u32 is_io)
++{
++	u32 reg, clocks, psst, psl, psht;
++
++	if(!ns) {
++
++		/*
++		 * We get called with IO maps setup to 0ns
++		 * if not specified by the user.
++		 * They should be 255ns.
++		 */
++
++		if(is_io)
++			ns = 255;
++		else
++			ns = 100;  /* fast memory if 0 */
++	}
++
++	/*
++	 * In PSST, PSL, PSHT fields we tell the controller
++	 * timing parameters in CLKOUT clock cycles.
++	 * CLKOUT is the same as GCLK2_50.
++	 */
++
++/* how we want to adjust the timing - in percent */
++
++#define ADJ 180 /* 80 % longer accesstime - to be sure */
++
++	clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
++	clocks = (clocks * ADJ) / (100*1000);
++	if(clocks >= PCMCIA_BMT_LIMIT) {
++		printk( "Max access time limit reached\n");
++		clocks = PCMCIA_BMT_LIMIT-1;
++	}
++
++	psst = clocks / 7;          /* setup time */
++	psht = clocks / 7;          /* hold time */
++	psl  = (clocks * 5) / 7;    /* strobe length */
++
++	psst += clocks - (psst + psht + psl);
++
++	reg =  psst << 12;
++	reg |= psl  << 7;
++	reg |= psht << 16;
++
++	return reg;
++}
++
++static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
++{
++	int lsock = container_of(sock, struct socket_info, socket)->slot;
++	struct socket_info *s = &socket[lsock];
++	unsigned int pipr, reg;
++
++	pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
++
++	*value  = ((pipr & (M8XX_PCMCIA_CD1(lsock)
++			    | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
++	*value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0;
++
++	if (s->state.flags & SS_IOCARD)
++		*value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_STSCHG : 0;
++	else {
++		*value |= (pipr & M8XX_PCMCIA_RDY(lsock)) ? SS_READY : 0;
++		*value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_BATDEAD : 0;
++		*value |= (pipr & M8XX_PCMCIA_BVD2(lsock)) ? SS_BATWARN : 0;
++	}
++
++	if (s->state.Vcc | s->state.Vpp)
++		*value |= SS_POWERON;
++
++	/*
++	 * Voltage detection:
++	 * This driver only supports 16-Bit pc-cards.
++	 * Cardbus is not handled here.
++	 *
++	 * To determine what voltage to use we must read the VS1 and VS2 pin.
++	 * Depending on what socket type is present,
++	 * different combinations mean different things.
++	 *
++	 * Card Key  Socket Key   VS1   VS2   Card         Vcc for CIS parse
++	 *
++	 * 5V        5V, LV*      NC    NC    5V only       5V (if available)
++	 *
++	 * 5V        5V, LV*      GND   NC    5 or 3.3V     as low as possible
++	 *
++	 * 5V        5V, LV*      GND   GND   5, 3.3, x.xV  as low as possible
++	 *
++	 * LV*       5V            -     -    shall not fit into socket
++	 *
++	 * LV*       LV*          GND   NC    3.3V only     3.3V
++	 *
++	 * LV*       LV*          NC    GND   x.xV          x.xV (if avail.)
++	 *
++	 * LV*       LV*          GND   GND   3.3 or x.xV   as low as possible
++	 *
++	 * *LV means Low Voltage
++	 *
++	 *
++	 * That gives us the following table:
++	 *
++	 * Socket    VS1  VS2   Voltage
++	 *
++	 * 5V        NC   NC    5V
++	 * 5V        NC   GND   none (should not be possible)
++	 * 5V        GND  NC    >= 3.3V
++	 * 5V        GND  GND   >= x.xV
++	 *
++	 * LV        NC   NC    5V   (if available)
++	 * LV        NC   GND   x.xV (if available)
++	 * LV        GND  NC    3.3V
++	 * LV        GND  GND   >= x.xV
++	 *
++	 * So, how do I determine if I have a 5V or a LV
++	 * socket on my board?  Look at the socket!
++	 *
++	 *
++	 * Socket with 5V key:
++	 * ++--------------------------------------------+
++	 * ||                                            |
++	 * ||                                           ||
++	 * ||                                           ||
++	 * |                                             |
++	 * +---------------------------------------------+
++	 *
++	 * Socket with LV key:
++	 * ++--------------------------------------------+
++	 * ||                                            |
++	 * |                                            ||
++	 * |                                            ||
++	 * |                                             |
++	 * +---------------------------------------------+
++	 *
++	 *
++	 * With other words - LV only cards does not fit
++	 * into the 5V socket!
++	 */
++
++	/* read out VS1 and VS2 */
++
++	reg = (pipr & M8XX_PCMCIA_VS_MASK(lsock))
++		>> M8XX_PCMCIA_VS_SHIFT(lsock);
++
++	if(socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) {
++		switch(reg) {
++		case 1:
++			*value |= SS_3VCARD;
++			break; /* GND, NC - 3.3V only */
++		case 2:
++			*value |= SS_XVCARD;
++			break; /* NC. GND - x.xV only */
++		};
++	}
++
++	dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value);
++	return 0;
++}
++
++static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
++{
++	int lsock = container_of(sock, struct socket_info, socket)->slot;
++	*state = socket[lsock].state; /* copy the whole structure */
++
++	dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
++	      "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
++	      state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
++	return 0;
++}
++
++static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
++{
++	int lsock = container_of(sock, struct socket_info, socket)->slot;
++	struct socket_info *s = &socket[lsock];
++	struct event_table *e;
++	unsigned int reg;
++	unsigned long flags;
++
++	dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
++	      "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
++	      state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
++
++	/* First, set voltage - bail out if invalid */
++	if(voltage_set(lsock, state->Vcc, state->Vpp))
++		return -EINVAL;
++
++	/* Take care of reset... */
++	if(state->flags & SS_RESET)
++		out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) |  M8XX_PGCRX_CXRESET); /* active high */
++	else
++		out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET);
++
++	/* ... and output enable. */
++
++	/* The CxOE signal is connected to a 74541 on the ADS.
++	   I guess most other boards used the ADS as a reference.
++	   I tried to control the CxOE signal with SS_OUTPUT_ENA,
++	   but the reset signal seems connected via the 541.
++	   If the CxOE is left high are some signals tristated and
++	   no pullups are present -> the cards act wierd.
++	   So right now the buffers are enabled if the power is on. */
++
++	if(state->Vcc || state->Vpp)
++		out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE); /* active low */
++	else
++		out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE);
++
++	/*
++	 * We'd better turn off interrupts before
++	 * we mess with the events-table..
++	 */
++
++	spin_lock_irqsave(&events_lock, flags);
++
++	/*
++	 * Play around with the interrupt mask to be able to
++	 * give the events the generic pcmcia driver wants us to.
++	 */
++
++	e = &s->events[0];
++	reg = 0;
++
++	if(state->csc_mask & SS_DETECT) {
++		e->eventbit = SS_DETECT;
++		reg |= e->regbit = (M8XX_PCMCIA_CD2(lsock)
++				    | M8XX_PCMCIA_CD1(lsock));
++		e++;
++	}
++	if(state->flags & SS_IOCARD) {
++		/*
++		 * I/O card
++		 */
++		if(state->csc_mask & SS_STSCHG) {
++			e->eventbit = SS_STSCHG;
++			reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
++			e++;
++		}
++		/*
++		 * If io_irq is non-zero we should enable irq.
++		 */
++		if(state->io_irq) {
++			out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(state->io_irq) << 24);
++			/*
++			 * Strange thing here:
++			 * The manual does not tell us which interrupt
++			 * the sources generate.
++			 * Anyhow, I found out that RDY_L generates IREQLVL.
++			 *
++			 * We use level triggerd interrupts, and they don't
++			 * have to be cleared in PSCR in the interrupt handler.
++			 */
++			reg |= M8XX_PCMCIA_RDY_L(lsock);
++		}
++		else
++			out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff);
++	}
++	else {
++		/*
++		 * Memory card
++		 */
++		if(state->csc_mask & SS_BATDEAD) {
++			e->eventbit = SS_BATDEAD;
++			reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
++			e++;
++		}
++		if(state->csc_mask & SS_BATWARN) {
++			e->eventbit = SS_BATWARN;
++			reg |= e->regbit = M8XX_PCMCIA_BVD2(lsock);
++			e++;
++		}
++		/* What should I trigger on - low/high,raise,fall? */
++		if(state->csc_mask & SS_READY) {
++			e->eventbit = SS_READY;
++			reg |= e->regbit = 0; //??
++			e++;
++		}
++	}
++
++	e->regbit = 0;  /* terminate list */
++
++	/*
++	 * Clear the status changed .
++	 * Port A and Port B share the same port.
++	 * Writing ones will clear the bits.
++	 */
++
++	out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, reg);
++
++	/*
++	 * Write the mask.
++	 * Port A and Port B share the same port.
++	 * Need for read-modify-write.
++	 * Ones will enable the interrupt.
++	 */
++
++	/*
++	  reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
++	  & M8XX_PCMCIA_MASK(lsock);
++	*/
++
++	reg |= in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
++		(M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
++
++	out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, reg);
++
++	spin_unlock_irqrestore(&events_lock, flags);
++
++	/* copy the struct and modify the copy */
++
++	s->state = *state;
++
++	return 0;
++}
++
++static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
++{
++	int lsock = container_of(sock, struct socket_info, socket)->slot;
++
++	struct socket_info *s = &socket[lsock];
++	struct pcmcia_win *w;
++	unsigned int reg, winnr;
++
++#define M8XX_SIZE (io->stop - io->start + 1)
++#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
++
++	dprintk( "SetIOMap(%d, %d, %#2.2x, %d ns, "
++	      "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
++	      io->speed, io->start, io->stop);
++
++	if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
++	    || (io->stop > 0xffff) || (io->stop < io->start))
++		return -EINVAL;
++
++	if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
++		return -EINVAL;
++
++	if(io->flags & MAP_ACTIVE) {
++
++		dprintk( "io->flags & MAP_ACTIVE\n");
++
++		winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
++			+ (lsock * PCMCIA_IO_WIN_NO) + io->map;
++
++		/* setup registers */
++
++		w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
++		w += winnr;
++
++		out_be32(&w->or, 0); /* turn off window first */
++		out_be32(&w->br, M8XX_BASE);
++
++		reg <<= 27;
++  		reg |= M8XX_PCMCIA_POR_IO |(lsock << 2);
++
++		reg |= m8xx_get_speed(io->speed, 1);
++
++		if(io->flags & MAP_WRPROT)
++			reg |= M8XX_PCMCIA_POR_WRPROT;
++
++		/*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
++		if(io->flags & MAP_16BIT)
++			reg |= M8XX_PCMCIA_POR_16BIT;
++
++		if(io->flags & MAP_ACTIVE)
++			reg |= M8XX_PCMCIA_POR_VALID;
++
++		out_be32(&w->or, reg);
++
++		dprintk("Socket %u: Mapped io window %u at %#8.8x, "
++		      "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
++	} else {
++		/* shutdown IO window */
++		winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
++			+ (lsock * PCMCIA_IO_WIN_NO) + io->map;
++
++		/* setup registers */
++
++		w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
++		w += winnr;
++
++		out_be32(&w->or, 0); /* turn off window */
++		out_be32(&w->br, 0); /* turn off base address */
++
++		dprintk("Socket %u: Unmapped io window %u at %#8.8x, "
++			"OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
++	}
++
++	/* copy the struct and modify the copy */
++	s->io_win[io->map] = *io;
++	s->io_win[io->map].flags &= (MAP_WRPROT
++				     | MAP_16BIT
++				     | MAP_ACTIVE);
++	dprintk("SetIOMap exit\n");
++
++	return 0;
++}
++
++static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
++{
++	int lsock = container_of(sock, struct socket_info, socket)->slot;
++	struct socket_info *s = &socket[lsock];
++	struct pcmcia_win *w;
++	struct pccard_mem_map *old;
++	unsigned int reg, winnr;
++
++	dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, "
++	      "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
++	      mem->speed, mem->static_start, mem->card_start);
++
++	if ((mem->map >= PCMCIA_MEM_WIN_NO)
++//	    || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
++	    || (mem->card_start >= 0x04000000)
++	    || (mem->static_start & 0xfff)                /* 4KByte resolution */
++	    || (mem->card_start & 0xfff))
++		return -EINVAL;
++
++	if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
++		printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
++		return -EINVAL;
++	}
++	reg <<= 27;
++
++	winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
++
++	/* Setup the window in the pcmcia controller */
++
++	w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
++	w += winnr;
++
++	reg |= lsock << 2;
++
++	reg |= m8xx_get_speed(mem->speed, 0);
++
++	if(mem->flags & MAP_ATTRIB)
++		reg |=  M8XX_PCMCIA_POR_ATTRMEM;
++
++	if(mem->flags & MAP_WRPROT)
++		reg |= M8XX_PCMCIA_POR_WRPROT;
++
++	if(mem->flags & MAP_16BIT)
++		reg |= M8XX_PCMCIA_POR_16BIT;
++
++	if(mem->flags & MAP_ACTIVE)
++		reg |= M8XX_PCMCIA_POR_VALID;
++
++	out_be32(&w->or, reg);
++
++	dprintk("Socket %u: Mapped memory window %u at %#8.8x, "
++	      "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
++
++	if(mem->flags & MAP_ACTIVE) {
++		/* get the new base address */
++		mem->static_start = PCMCIA_MEM_WIN_BASE +
++			(PCMCIA_MEM_WIN_SIZE * winnr)
++			+ mem->card_start;
++	}
++
++	dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
++	      "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
++	      mem->speed, mem->static_start, mem->card_start);
++
++	/* copy the struct and modify the copy */
++
++	old = &s->mem_win[mem->map];
++
++	*old = *mem;
++	old->flags &= (MAP_ATTRIB
++		       | MAP_WRPROT
++		       | MAP_16BIT
++		       | MAP_ACTIVE);
++
++	return 0;
++}
++
++static int m8xx_sock_init(struct pcmcia_socket *sock)
++{
++	int i;
++	pccard_io_map io = { 0, 0, 0, 0, 1 };
++	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
++
++	dprintk( "sock_init(%d)\n", s);
++
++	m8xx_set_socket(sock, &dead_socket);
++	for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
++		io.map = i;
++		m8xx_set_io_map(sock, &io);
++	}
++	for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
++		mem.map = i;
++		m8xx_set_mem_map(sock, &mem);
++	}
++
++	return 0;
++
++}
++
++static int m8xx_suspend(struct pcmcia_socket *sock)
++{
++	return m8xx_set_socket(sock, &dead_socket);
++}
++
++static struct pccard_operations m8xx_services = {
++	.init	= m8xx_sock_init,
++	.suspend = m8xx_suspend,
++	.get_status = m8xx_get_status,
++	.get_socket = m8xx_get_socket,
++	.set_socket = m8xx_set_socket,
++	.set_io_map = m8xx_set_io_map,
++	.set_mem_map = m8xx_set_mem_map,
++};
++
++static int __init m8xx_init(void)
++{
++	struct pcmcia_win *w;
++	unsigned int i,m;
++
++	pcmcia_info("%s\n", version);
++
++	if (driver_register(&m8xx_driver))
++		return -1;
++
++	pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
++		    " with IRQ %u.\n", pcmcia_schlvl);
++
++	/* Configure Status change interrupt */
++
++	if(request_irq(pcmcia_schlvl, m8xx_interrupt, 0,
++			  "m8xx_pcmcia", NULL)) {
++		pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
++			     pcmcia_schlvl);
++		return -1;
++	}
++
++	w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
++
++	out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr,
++		M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
++
++	out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per,
++		in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
++		~(M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1)));
++
++/* connect interrupt and disable CxOE */
++
++	out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16));
++	out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16));
++
++/* intialize the fixed memory windows */
++
++	for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
++		for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
++			out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
++				(PCMCIA_MEM_WIN_SIZE
++				 * (m + i * PCMCIA_MEM_WIN_NO)));
++
++			out_be32(&w->or, 0);  /* set to not valid */
++
++			w++;
++		}
++	}
++
++/* turn off voltage */
++	voltage_set(0, 0, 0);
++	voltage_set(1, 0, 0);
++
++/* Enable external hardware */
++	hardware_enable(0);
++	hardware_enable(1);
++
++	platform_device_register(&m8xx_device);
++
++	for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) {
++		socket[i].slot = i;
++		socket[i].socket.owner = THIS_MODULE;
++		socket[i].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP;
++		socket[i].socket.irq_mask = 0x000;
++		socket[i].socket.map_size = 0x1000;
++		socket[i].socket.io_offset = 0;
++		socket[i].socket.pci_irq = i  ? 7 : 9;
++		socket[i].socket.ops = &m8xx_services;
++		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
++		socket[i].socket.cb_dev = NULL;
++		socket[i].socket.dev.dev = &m8xx_device.dev;
++	}
++
++	for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
++		pcmcia_register_socket(&socket[i].socket);
++
++	return 0;
++}
++
++static void __exit m8xx_exit(void)
++{
++	int i;
++
++	for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
++		pcmcia_unregister_socket(&socket[i].socket);
++
++	m8xx_shutdown();
++
++	platform_device_unregister(&m8xx_device);
++	driver_unregister(&m8xx_driver);
++}
++
++module_init(m8xx_init);
++module_exit(m8xx_exit);
+diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
+--- a/drivers/pcmcia/omap_cf.c
++++ b/drivers/pcmcia/omap_cf.c
+@@ -12,7 +12,7 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+@@ -329,27 +329,13 @@ static int __devexit omap_cf_remove(stru
+ 	return 0;
+ }
+ 
+-static int omap_cf_suspend(struct device *dev, pm_message_t mesg, u32 level)
+-{
+-	if (level != SUSPEND_SAVE_STATE)
+-		return 0;
+-	return pcmcia_socket_dev_suspend(dev, mesg);
+-}
+-
+-static int omap_cf_resume(struct device *dev, u32 level)
+-{
+-	if (level != RESUME_RESTORE_STATE)
+-		return 0;
+-	return pcmcia_socket_dev_resume(dev);
+-}
+-
+ static struct device_driver omap_cf_driver = {
+ 	.name		= (char *) driver_name,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= omap_cf_probe,
+ 	.remove		= __devexit_p(omap_cf_remove),
+-	.suspend 	= omap_cf_suspend,
+-	.resume 	= omap_cf_resume,
++	.suspend 	= pcmcia_socket_dev_suspend,
++	.resume 	= pcmcia_socket_dev_resume,
+ };
+ 
+ static int __init omap_cf_init(void)
+diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
+--- a/drivers/pcmcia/pxa2xx_base.c
++++ b/drivers/pcmcia/pxa2xx_base.c
+@@ -23,6 +23,7 @@
+ #include <linux/ioport.h>
+ #include <linux/kernel.h>
+ #include <linux/spinlock.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/io.h>
+@@ -205,32 +206,20 @@ int pxa2xx_drv_pcmcia_probe(struct devic
+ }
+ EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe);
+ 
+-static int pxa2xx_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level)
++static int pxa2xx_drv_pcmcia_resume(struct device *dev)
+ {
+-	int ret = 0;
+-	if (level == SUSPEND_SAVE_STATE)
+-		ret = pcmcia_socket_dev_suspend(dev, state);
+-	return ret;
+-}
++	struct pcmcia_low_level *ops = dev->platform_data;
++	int nr = ops ? ops->nr : 0;
+ 
+-static int pxa2xx_drv_pcmcia_resume(struct device *dev, u32 level)
+-{
+-	int ret = 0;
+-	if (level == RESUME_RESTORE_STATE)
+-	{
+-		struct pcmcia_low_level *ops = dev->platform_data;
+-		int nr = ops ? ops->nr : 0;
++	MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
+ 
+-		MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
+-		ret = pcmcia_socket_dev_resume(dev);
+-	}
+-	return ret;
++	return pcmcia_socket_dev_resume(dev);
+ }
+ 
+ static struct device_driver pxa2xx_pcmcia_driver = {
+ 	.probe		= pxa2xx_drv_pcmcia_probe,
+ 	.remove		= soc_common_drv_pcmcia_remove,
+-	.suspend 	= pxa2xx_drv_pcmcia_suspend,
++	.suspend 	= pcmcia_socket_dev_suspend,
+ 	.resume 	= pxa2xx_drv_pcmcia_resume,
+ 	.name		= "pxa2xx-pcmcia",
+ 	.bus		= &platform_bus_type,
+diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
+--- a/drivers/pcmcia/pxa2xx_mainstone.c
++++ b/drivers/pcmcia/pxa2xx_mainstone.c
+@@ -17,7 +17,7 @@
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ #include <pcmcia/ss.h>
+ 
+diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
+--- a/drivers/pcmcia/pxa2xx_sharpsl.c
++++ b/drivers/pcmcia/pxa2xx_sharpsl.c
+@@ -16,12 +16,17 @@
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
++#include <asm/mach-types.h>
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/hardware/scoop.h>
+-#include <asm/arch/pxa-regs.h>
++#ifdef CONFIG_SA1100_COLLIE
++#include <asm/arch-sa1100/collie.h>
++#else
++#include <asm/arch-pxa/pxa-regs.h>
++#endif
+ 
+ #include "soc_common.h"
+ 
+@@ -38,6 +43,7 @@ static int sharpsl_pcmcia_hw_init(struct
+ {
+ 	int ret;
+ 
++#ifndef CONFIG_SA1100_COLLIE
+ 	/*
+ 	 * Setup default state of GPIO outputs
+ 	 * before we enable them as outputs.
+@@ -60,6 +66,7 @@ static int sharpsl_pcmcia_hw_init(struct
+ 	pxa_gpio_mode(GPIO55_nPREG_MD);
+ 	pxa_gpio_mode(GPIO56_nPWAIT_MD);
+ 	pxa_gpio_mode(GPIO57_nIOIS16_MD);
++#endif
+ 
+ 	/* Register interrupts */
+ 	if (scoop_devs[skt->nr].cd_irq >= 0) {
+@@ -213,12 +220,20 @@ static void sharpsl_pcmcia_socket_init(s
+ 	write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0);
+ 	write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101);
+ 	scoop_devs[skt->nr].keep_vs = NO_KEEP_VS;
++
++	if (machine_is_collie())
++		/* We need to disable SS_OUTPUT_ENA here. */
++		write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080);
+ }
+ 
+ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+ {
+ 	/* CF_BUS_OFF */
+ 	sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]);
++
++	if (machine_is_collie())
++		/* We need to disable SS_OUTPUT_ENA here. */
++		write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080);
+ }
+ 
+ static struct pcmcia_low_level sharpsl_pcmcia_ops = {
+@@ -235,6 +250,19 @@ static struct pcmcia_low_level sharpsl_p
+ 
+ static struct platform_device *sharpsl_pcmcia_device;
+ 
++#ifdef CONFIG_SA1100_COLLIE
++int __init pcmcia_collie_init(struct device *dev)
++{
++       int ret = -ENODEV;
++
++       if (machine_is_collie())
++               ret = sa11xx_drv_pcmcia_probe(dev, &sharpsl_pcmcia_ops, 0, 1);
++
++       return ret;
++}
++
++#else
++
+ static int __init sharpsl_pcmcia_init(void)
+ {
+ 	int ret;
+@@ -269,6 +297,7 @@ static void __exit sharpsl_pcmcia_exit(v
+ 
+ fs_initcall(sharpsl_pcmcia_init);
+ module_exit(sharpsl_pcmcia_exit);
++#endif
+ 
+ MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
+--- a/drivers/pcmcia/rsrc_nonstatic.c
++++ b/drivers/pcmcia/rsrc_nonstatic.c
+@@ -779,7 +779,7 @@ static int nonstatic_autoadd_resources(s
+ 	if (!s->cb_dev || !s->cb_dev->bus)
+ 		return -ENODEV;
+ 
+-#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
++#if defined(CONFIG_X86)
+ 	/* If this is the root bus, the risk of hitting
+ 	 * some strange system devices which aren't protected
+ 	 * by either ACPI resource tables or properly requested
+@@ -994,7 +994,8 @@ static struct class_device_attribute *pc
+ 	NULL,
+ };
+ 
+-static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev)
++static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
++					   struct class_interface *class_intf)
+ {
+ 	struct pcmcia_socket *s = class_get_devdata(class_dev);
+ 	struct class_device_attribute **attr;
+@@ -1011,7 +1012,8 @@ static int __devinit pccard_sysfs_add_rs
+ 	return ret;
+ }
+ 
+-static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev)
++static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev,
++					       struct class_interface *class_intf)
+ {
+ 	struct pcmcia_socket *s = class_get_devdata(class_dev);
+ 	struct class_device_attribute **attr;
+diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
+--- a/drivers/pcmcia/sa1100_generic.c
++++ b/drivers/pcmcia/sa1100_generic.c
+@@ -33,13 +33,18 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/config.h>
++#include <linux/platform_device.h>
+ 
+ #include <pcmcia/cs_types.h>
+ #include <pcmcia/cs.h>
+ #include <pcmcia/ss.h>
+ 
++#include <asm/hardware/scoop.h>
++
+ #include "sa1100_generic.h"
+ 
++int __init pcmcia_collie_init(struct device *dev);
++
+ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
+ #ifdef CONFIG_SA1100_ASSABET
+ 	pcmcia_assabet_init,
+@@ -56,6 +61,9 @@ static int (*sa11x0_pcmcia_hw_init[])(st
+ #ifdef CONFIG_SA1100_SIMPAD
+ 	pcmcia_simpad_init,
+ #endif
++#ifdef CONFIG_SA1100_COLLIE
++       pcmcia_collie_init,
++#endif
+ };
+ 
+ static int sa11x0_drv_pcmcia_probe(struct device *dev)
+@@ -74,29 +82,13 @@ static int sa11x0_drv_pcmcia_probe(struc
+ 	return ret;
+ }
+ 
+-static int sa11x0_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level)
+-{
+-	int ret = 0;
+-	if (level == SUSPEND_SAVE_STATE)
+-		ret = pcmcia_socket_dev_suspend(dev, state);
+-	return ret;
+-}
+-
+-static int sa11x0_drv_pcmcia_resume(struct device *dev, u32 level)
+-{
+-	int ret = 0;
+-	if (level == RESUME_RESTORE_STATE)
+-		ret = pcmcia_socket_dev_resume(dev);
+-	return ret;
+-}
+-
+ static struct device_driver sa11x0_pcmcia_driver = {
+ 	.probe		= sa11x0_drv_pcmcia_probe,
+ 	.remove		= soc_common_drv_pcmcia_remove,
+ 	.name		= "sa11x0-pcmcia",
+ 	.bus		= &platform_bus_type,
+-	.suspend 	= sa11x0_drv_pcmcia_suspend,
+-	.resume 	= sa11x0_drv_pcmcia_resume,
++	.suspend 	= pcmcia_socket_dev_suspend,
++	.resume 	= pcmcia_socket_dev_resume,
+ };
+ 
+ /* sa11x0_pcmcia_init()
+diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
+--- a/drivers/pcmcia/sa1111_generic.c
++++ b/drivers/pcmcia/sa1111_generic.c
+@@ -122,7 +122,7 @@ void sa1111_pcmcia_socket_suspend(struct
+ 
+ static int pcmcia_probe(struct sa1111_dev *dev)
+ {
+-	char *base;
++	void __iomem *base;
+ 
+ 	if (!request_mem_region(dev->res.start, 512,
+ 				SA1111_DRIVER_NAME(dev)))
+diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
+--- a/drivers/pcmcia/socket_sysfs.c
++++ b/drivers/pcmcia/socket_sysfs.c
+@@ -341,7 +341,8 @@ static struct bin_attribute pccard_cis_a
+ 	.write = pccard_store_cis,
+ };
+ 
+-static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev)
++static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev,
++					     struct class_interface *class_intf)
+ {
+ 	struct class_device_attribute **attr;
+ 	int ret = 0;
+@@ -357,7 +358,8 @@ static int __devinit pccard_sysfs_add_so
+ 	return ret;
+ }
+ 
+-static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev)
++static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev,
++						 struct class_interface *class_intf)
+ {
+ 	struct class_device_attribute **attr;
+ 
+diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
+--- a/drivers/pcmcia/tcic.c
++++ b/drivers/pcmcia/tcic.c
+@@ -44,7 +44,7 @@
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+ #include <linux/workqueue.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/bitops.h>
+ 
+ #include <asm/io.h>
+@@ -372,27 +372,11 @@ static int __init get_tcic_id(void)
+ 
+ /*====================================================================*/
+ 
+-static int tcic_drv_suspend(struct device *dev, pm_message_t state, u32 level)
+-{
+-	int ret = 0;
+-	if (level == SUSPEND_SAVE_STATE)
+-		ret = pcmcia_socket_dev_suspend(dev, state);
+-	return ret;
+-}
+-
+-static int tcic_drv_resume(struct device *dev, u32 level)
+-{
+-	int ret = 0;
+-	if (level == RESUME_RESTORE_STATE)
+-		ret = pcmcia_socket_dev_resume(dev);
+-	return ret;
+-}
+-
+ static struct device_driver tcic_driver = {
+ 	.name = "tcic-pcmcia",
+ 	.bus = &platform_bus_type,
+-	.suspend = tcic_drv_suspend,
+-	.resume = tcic_drv_resume,
++	.suspend = pcmcia_socket_dev_suspend,
++	.resume = pcmcia_socket_dev_resume,
+ };
+ 
+ static struct platform_device tcic_device = {
+diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
+--- a/drivers/pcmcia/vrc4171_card.c
++++ b/drivers/pcmcia/vrc4171_card.c
+@@ -24,6 +24,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/sched.h>
+ #include <linux/types.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ 
+@@ -774,31 +775,11 @@ static int __devinit vrc4171_card_setup(
+ 
+ __setup("vrc4171_card=", vrc4171_card_setup);
+ 
+-static int vrc4171_card_suspend(struct device *dev, pm_message_t state, u32 level)
+-{
+-	int retval = 0;
+-
+-	if (level == SUSPEND_SAVE_STATE)
+-		retval = pcmcia_socket_dev_suspend(dev, state);
+-
+-	return retval;
+-}
+-
+-static int vrc4171_card_resume(struct device *dev, u32 level)
+-{
+-	int retval = 0;
+-
+-	if (level == RESUME_RESTORE_STATE)
+-		retval = pcmcia_socket_dev_resume(dev);
+-
+-	return retval;
+-}
+-
+ static struct device_driver vrc4171_card_driver = {
+ 	.name		= vrc4171_card_name,
+ 	.bus		= &platform_bus_type,
+-	.suspend	= vrc4171_card_suspend,
+-	.resume		= vrc4171_card_resume,
++	.suspend	= pcmcia_socket_dev_suspend,
++	.resume		= pcmcia_socket_dev_resume,
+ };
+ 
+ static int __devinit vrc4171_card_init(void)
+diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
+--- a/drivers/pcmcia/yenta_socket.c
++++ b/drivers/pcmcia/yenta_socket.c
+@@ -151,6 +151,40 @@ static void exca_writew(struct yenta_soc
+ 	readb(socket->base + 0x800 + reg + 1);
+ }
+ 
++static ssize_t show_yenta_registers(struct device *yentadev, struct device_attribute *attr, char *buf)
++{
++	struct pci_dev *dev = to_pci_dev(yentadev);
++	struct yenta_socket *socket = pci_get_drvdata(dev);
++	int offset = 0, i;
++
++	offset = snprintf(buf, PAGE_SIZE, "CB registers:");
++	for (i = 0; i < 0x24; i += 4) {
++		unsigned val;
++		if (!(i & 15))
++			offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n%02x:", i);
++		val = cb_readl(socket, i);
++		offset += snprintf(buf + offset, PAGE_SIZE - offset, " %08x", val);
++	}
++
++	offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n\nExCA registers:");
++	for (i = 0; i < 0x45; i++) {
++		unsigned char val;
++		if (!(i & 7)) {
++			if (i & 8) {
++				memcpy(buf + offset, " -", 2);
++				offset += 2;
++			} else
++				offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n%02x:", i);
++		}
++		val = exca_readb(socket, i);
++		offset += snprintf(buf + offset, PAGE_SIZE - offset, " %02x", val);
++	}
++	buf[offset++] = '\n';
++	return offset;
++}
++
++static DEVICE_ATTR(yenta_registers, S_IRUSR, show_yenta_registers, NULL);
++
+ /*
+  * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
+  * on what kind of card is inserted..
+@@ -765,6 +799,9 @@ static void yenta_close(struct pci_dev *
+ {
+ 	struct yenta_socket *sock = pci_get_drvdata(dev);
+ 
++	/* Remove the register attributes */
++	device_remove_file(&dev->dev, &dev_attr_yenta_registers);
++
+ 	/* we don't want a dying socket registered */
+ 	pcmcia_unregister_socket(&sock->socket);
+ 	
+@@ -1138,8 +1175,11 @@ static int __devinit yenta_probe (struct
+ 
+ 	/* Register it with the pcmcia layer.. */
+ 	ret = pcmcia_register_socket(&socket->socket);
+-	if (ret == 0)
++	if (ret == 0) {
++		/* Add the yenta register attributes */
++		device_create_file(&dev->dev, &dev_attr_yenta_registers);
+ 		goto out;
++	}
+ 
+  unmap:
+ 	iounmap(socket->base);
+diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
+--- a/drivers/pnp/manager.c
++++ b/drivers/pnp/manager.c
+@@ -12,6 +12,8 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/pnp.h>
++#include <linux/slab.h>
++#include <linux/bitmap.h>
+ #include "base.h"
+ 
+ DECLARE_MUTEX(pnp_res_mutex);
+diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
+--- a/drivers/pnp/pnpbios/rsparser.c
++++ b/drivers/pnp/pnpbios/rsparser.c
+@@ -7,6 +7,8 @@
+ #include <linux/ctype.h>
+ #include <linux/pnp.h>
+ #include <linux/pnpbios.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ #ifdef CONFIG_PCI
+ #include <linux/pci.h>
+diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
+--- a/drivers/s390/char/con3270.c
++++ b/drivers/s390/char/con3270.c
+@@ -213,6 +213,9 @@ con3270_update(struct con3270 *cp)
+ 	struct string *s, *n;
+ 	int rc;
+ 
++	if (cp->view.dev)
++		raw3270_activate_view(&cp->view);
++
+ 	wrq = xchg(&cp->write, 0);
+ 	if (!wrq) {
+ 		con3270_set_timer(cp, 1);
+@@ -489,8 +492,6 @@ con3270_write(struct console *co, const 
+ 	unsigned char c;
+ 
+ 	cp = condev;
+-	if (cp->view.dev)
+-		raw3270_activate_view(&cp->view);
+ 	spin_lock_irqsave(&cp->view.lock, flags);
+ 	while (count-- > 0) {
+ 		c = *str++;
+@@ -620,7 +621,7 @@ con3270_init(void)
+ 		     (void (*)(unsigned long)) con3270_read_tasklet,
+ 		     (unsigned long) condev->read);
+ 
+-	raw3270_add_view(&condev->view, &con3270_fn, 0);
++	raw3270_add_view(&condev->view, &con3270_fn, 1);
+ 
+ 	INIT_LIST_HEAD(&condev->freemem);
+ 	for (i = 0; i < CON3270_STRING_PAGES; i++) {
+diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
+--- a/drivers/s390/char/fs3270.c
++++ b/drivers/s390/char/fs3270.c
+@@ -33,8 +33,11 @@ struct fs3270 {
+ 	int read_command;		/* ccw command to use for reads. */
+ 	int write_command;		/* ccw command to use for writes. */
+ 	int attention;			/* Got attention. */
+-	struct raw3270_request *clear;	/* single clear request. */
+-	wait_queue_head_t attn_wait;	/* Attention wait queue. */
++	int active;			/* Fullscreen view is active. */
++	struct raw3270_request *init;	/* single init request. */
++	wait_queue_head_t wait;		/* Init & attention wait queue. */
++	struct idal_buffer *rdbuf;	/* full-screen-deactivate buffer */
++	size_t rdbuf_size;		/* size of data returned by RDBUF */
+ };
+ 
+ static void
+@@ -43,58 +46,172 @@ fs3270_wake_up(struct raw3270_request *r
+ 	wake_up((wait_queue_head_t *) data);
+ }
+ 
++static inline int
++fs3270_working(struct fs3270 *fp)
++{
++	/*
++	 * The fullscreen view is in working order if the view
++	 * has been activated AND the initial request is finished.
++	 */
++	return fp->active && raw3270_request_final(fp->init);
++}
++
+ static int
+ fs3270_do_io(struct raw3270_view *view, struct raw3270_request *rq)
+ {
+-	wait_queue_head_t wq;
++	struct fs3270 *fp;
+ 	int rc;
+ 
+-	init_waitqueue_head(&wq);
++	fp = (struct fs3270 *) view;
+ 	rq->callback = fs3270_wake_up;
+-	rq->callback_data = &wq;
+-	rc = raw3270_start(view, rq);
+-	if (rc)
+-		return rc;
+-	/* Started sucessfully. Now wait for completion. */
+-	wait_event(wq, raw3270_request_final(rq));
+-	return rq->rc;
++	rq->callback_data = &fp->wait;
++
++	do {
++		if (!fs3270_working(fp)) {
++			/* Fullscreen view isn't ready yet. */
++			rc = wait_event_interruptible(fp->wait,
++						      fs3270_working(fp));
++			if (rc != 0)
++				break;
++		}
++		rc = raw3270_start(view, rq);
++		if (rc == 0) {
++			/* Started sucessfully. Now wait for completion. */
++			wait_event(fp->wait, raw3270_request_final(rq));
++		}
++	} while (rc == -EACCES);
++	return rc;
+ }
+ 
++/*
++ * Switch to the fullscreen view.
++ */
+ static void
+ fs3270_reset_callback(struct raw3270_request *rq, void *data)
+ {
++	struct fs3270 *fp;
++
++	fp = (struct fs3270 *) rq->view;
+ 	raw3270_request_reset(rq);
++	wake_up(&fp->wait);
++}
++
++static void
++fs3270_restore_callback(struct raw3270_request *rq, void *data)
++{
++	struct fs3270 *fp;
++
++	fp = (struct fs3270 *) rq->view;
++	if (rq->rc != 0 || rq->rescnt != 0) {
++		if (fp->fs_pid)
++			kill_proc(fp->fs_pid, SIGHUP, 1);
++	}
++	fp->rdbuf_size = 0;
++	raw3270_request_reset(rq);
++	wake_up(&fp->wait);
+ }
+ 
+-/*
+- * Switch to the fullscreen view.
+- */
+ static int
+ fs3270_activate(struct raw3270_view *view)
+ {
+ 	struct fs3270 *fp;
++	char *cp;
++	int rc;
+ 
+ 	fp = (struct fs3270 *) view;
+-	raw3270_request_set_cmd(fp->clear, TC_EWRITEA);
+-	fp->clear->callback = fs3270_reset_callback;
+-	return raw3270_start(view, fp->clear);
++
++	/* If an old init command is still running just return. */
++	if (!raw3270_request_final(fp->init))
++		return 0;
++
++	if (fp->rdbuf_size == 0) {
++		/* No saved buffer. Just clear the screen. */
++		raw3270_request_set_cmd(fp->init, TC_EWRITEA);
++		fp->init->callback = fs3270_reset_callback;
++	} else {
++		/* Restore fullscreen buffer saved by fs3270_deactivate. */
++		raw3270_request_set_cmd(fp->init, TC_EWRITEA);
++		raw3270_request_set_idal(fp->init, fp->rdbuf);
++		fp->init->ccw.count = fp->rdbuf_size;
++		cp = fp->rdbuf->data[0];
++		cp[0] = TW_KR;
++		cp[1] = TO_SBA;
++		cp[2] = cp[6];
++		cp[3] = cp[7];
++		cp[4] = TO_IC;
++		cp[5] = TO_SBA;
++		cp[6] = 0x40;
++		cp[7] = 0x40;
++		fp->init->rescnt = 0;
++		fp->init->callback = fs3270_restore_callback;
++	}
++	rc = fp->init->rc = raw3270_start_locked(view, fp->init);
++	if (rc)
++		fp->init->callback(fp->init, NULL);
++	else
++		fp->active = 1;
++	return rc;
+ }
+ 
+ /*
+  * Shutdown fullscreen view.
+  */
+ static void
++fs3270_save_callback(struct raw3270_request *rq, void *data)
++{
++	struct fs3270 *fp;
++
++	fp = (struct fs3270 *) rq->view;
++
++	/* Correct idal buffer element 0 address. */
++	fp->rdbuf->data[0] -= 5;
++	fp->rdbuf->size += 5;
++
++	/*
++	 * If the rdbuf command failed or the idal buffer is
++	 * to small for the amount of data returned by the
++	 * rdbuf command, then we have no choice but to send
++	 * a SIGHUP to the application.
++	 */
++	if (rq->rc != 0 || rq->rescnt == 0) {
++		if (fp->fs_pid)
++			kill_proc(fp->fs_pid, SIGHUP, 1);
++		fp->rdbuf_size = 0;
++	} else
++		fp->rdbuf_size = fp->rdbuf->size - rq->rescnt;
++	raw3270_request_reset(rq);
++	wake_up(&fp->wait);
++}
++
++static void
+ fs3270_deactivate(struct raw3270_view *view)
+ {
+-	// FIXME: is this a good idea? The user program using fullscreen 3270
+-	// will die just because a console message appeared. On the other
+-	// hand the fullscreen device is unoperational now.
+ 	struct fs3270 *fp;
+ 
+ 	fp = (struct fs3270 *) view;
+-	if (fp->fs_pid != 0)
+-		kill_proc(fp->fs_pid, SIGHUP, 1);
+-	fp->fs_pid = 0;
++	fp->active = 0;
++
++	/* If an old init command is still running just return. */
++	if (!raw3270_request_final(fp->init))
++		return;
++
++	/* Prepare read-buffer request. */
++	raw3270_request_set_cmd(fp->init, TC_RDBUF);
++	/*
++	 * Hackish: skip first 5 bytes of the idal buffer to make
++	 * room for the TW_KR/TO_SBA/<address>/<address>/TO_IC sequence
++	 * in the activation command.
++	 */
++	fp->rdbuf->data[0] += 5;
++	fp->rdbuf->size -= 5;
++	raw3270_request_set_idal(fp->init, fp->rdbuf);
++	fp->init->rescnt = 0;
++	fp->init->callback = fs3270_save_callback;
++
++	/* Start I/O to read in the 3270 buffer. */
++	fp->init->rc = raw3270_start_locked(view, fp->init);
++	if (fp->init->rc)
++		fp->init->callback(fp->init, NULL);
+ }
+ 
+ static int
+@@ -103,7 +220,7 @@ fs3270_irq(struct fs3270 *fp, struct raw
+ 	/* Handle ATTN. Set indication and wake waiters for attention. */
+ 	if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
+ 		fp->attention = 1;
+-		wake_up(&fp->attn_wait);
++		wake_up(&fp->wait);
+ 	}
+ 
+ 	if (rq) {
+@@ -125,7 +242,7 @@ fs3270_read(struct file *filp, char *dat
+ 	struct fs3270 *fp;
+ 	struct raw3270_request *rq;
+ 	struct idal_buffer *ib;
+-	int rc;
++	ssize_t rc;
+ 	
+ 	if (count == 0 || count > 65535)
+ 		return -EINVAL;
+@@ -133,7 +250,7 @@ fs3270_read(struct file *filp, char *dat
+ 	if (!fp)
+ 		return -ENODEV;
+ 	ib = idal_buffer_alloc(count, 0);
+-	if (!ib)
++	if (IS_ERR(ib))
+ 		return -ENOMEM;
+ 	rq = raw3270_request_alloc(0);
+ 	if (!IS_ERR(rq)) {
+@@ -141,10 +258,19 @@ fs3270_read(struct file *filp, char *dat
+ 			fp->read_command = 6;
+ 		raw3270_request_set_cmd(rq, fp->read_command ? : 2);
+ 		raw3270_request_set_idal(rq, ib);
+-		wait_event(fp->attn_wait, fp->attention);
+-		rc = fs3270_do_io(&fp->view, rq);
+-		if (rc == 0 && idal_buffer_to_user(ib, data, count))
+-			rc = -EFAULT;
++		rc = wait_event_interruptible(fp->wait, fp->attention);
++		fp->attention = 0;
++		if (rc == 0) {
++			rc = fs3270_do_io(&fp->view, rq);
++			if (rc == 0) {
++				count -= rq->rescnt;
++				if (idal_buffer_to_user(ib, data, count) != 0)
++					rc = -EFAULT;
++				else
++					rc = count;
++
++			}
++		}
+ 		raw3270_request_free(rq);
+ 	} else
+ 		rc = PTR_ERR(rq);
+@@ -162,13 +288,13 @@ fs3270_write(struct file *filp, const ch
+ 	struct raw3270_request *rq;
+ 	struct idal_buffer *ib;
+ 	int write_command;
+-	int rc;
++	ssize_t rc;
+ 
+ 	fp = filp->private_data;
+ 	if (!fp)
+ 		return -ENODEV;
+ 	ib = idal_buffer_alloc(count, 0);
+-	if (!ib)
++	if (IS_ERR(ib))
+ 		return -ENOMEM;
+ 	rq = raw3270_request_alloc(0);
+ 	if (!IS_ERR(rq)) {
+@@ -179,6 +305,8 @@ fs3270_write(struct file *filp, const ch
+ 			raw3270_request_set_cmd(rq, write_command);
+ 			raw3270_request_set_idal(rq, ib);
+ 			rc = fs3270_do_io(&fp->view, rq);
++			if (rc == 0)
++				rc = count - rq->rescnt;
+ 		} else
+ 			rc = -EFAULT;
+ 		raw3270_request_free(rq);
+@@ -232,7 +360,7 @@ fs3270_ioctl(struct inode *inode, struct
+ }
+ 
+ /*
+- * Allocate tty3270 structure.
++ * Allocate fs3270 structure.
+  */
+ static struct fs3270 *
+ fs3270_alloc_view(void)
+@@ -243,8 +371,8 @@ fs3270_alloc_view(void)
+ 	if (!fp)
+ 		return ERR_PTR(-ENOMEM);
+ 	memset(fp, 0, sizeof(struct fs3270));
+-	fp->clear = raw3270_request_alloc(0);
+-	if (!IS_ERR(fp->clear)) {
++	fp->init = raw3270_request_alloc(0);
++	if (IS_ERR(fp->init)) {
+ 		kfree(fp);
+ 		return ERR_PTR(-ENOMEM);
+ 	}
+@@ -252,12 +380,17 @@ fs3270_alloc_view(void)
+ }
+ 
+ /*
+- * Free tty3270 structure.
++ * Free fs3270 structure.
+  */
+ static void
+ fs3270_free_view(struct raw3270_view *view)
+ {
+-	raw3270_request_free(((struct fs3270 *) view)->clear);
++	struct fs3270 *fp;
++
++	fp = (struct fs3270 *) view;
++	if (fp->rdbuf)
++		idal_buffer_free(fp->rdbuf);
++	raw3270_request_free(((struct fs3270 *) view)->init);
+ 	kfree(view);
+ }
+ 
+@@ -285,11 +418,20 @@ static int
+ fs3270_open(struct inode *inode, struct file *filp)
+ {
+ 	struct fs3270 *fp;
++	struct idal_buffer *ib;
+ 	int minor, rc;
+ 
+ 	if (imajor(filp->f_dentry->d_inode) != IBM_FS3270_MAJOR)
+ 		return -ENODEV;
+ 	minor = iminor(filp->f_dentry->d_inode);
++	/* Check for minor 0 multiplexer. */
++	if (minor == 0) {
++		if (!current->signal->tty)
++			return -ENODEV;
++		if (current->signal->tty->driver->major != IBM_TTY3270_MAJOR)
++			return -ENODEV;
++		minor = current->signal->tty->index + RAW3270_FIRSTMINOR;
++	}
+ 	/* Check if some other program is already using fullscreen mode. */
+ 	fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
+ 	if (!IS_ERR(fp)) {
+@@ -301,7 +443,7 @@ fs3270_open(struct inode *inode, struct 
+ 	if (IS_ERR(fp))
+ 		return PTR_ERR(fp);
+ 
+-	init_waitqueue_head(&fp->attn_wait);
++	init_waitqueue_head(&fp->wait);
+ 	fp->fs_pid = current->pid;
+ 	rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
+ 	if (rc) {
+@@ -309,8 +451,18 @@ fs3270_open(struct inode *inode, struct 
+ 		return rc;
+ 	}
+ 
++	/* Allocate idal-buffer. */
++	ib = idal_buffer_alloc(2*fp->view.rows*fp->view.cols + 5, 0);
++	if (IS_ERR(ib)) {
++		raw3270_put_view(&fp->view);
++		raw3270_del_view(&fp->view);
++		return PTR_ERR(fp);
++	}
++	fp->rdbuf = ib;
++
+ 	rc = raw3270_activate_view(&fp->view);
+ 	if (rc) {
++		raw3270_put_view(&fp->view);
+ 		raw3270_del_view(&fp->view);
+ 		return rc;
+ 	}
+@@ -329,8 +481,12 @@ fs3270_close(struct inode *inode, struct
+ 
+ 	fp = filp->private_data;
+ 	filp->private_data = 0;
+-	if (fp)
++	if (fp) {
++		fp->fs_pid = 0;
++		raw3270_reset(&fp->view);
++		raw3270_put_view(&fp->view);
+ 		raw3270_del_view(&fp->view);
++	}
+ 	return 0;
+ }
+ 
+diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
+--- a/drivers/s390/char/raw3270.c
++++ b/drivers/s390/char/raw3270.c
+@@ -25,6 +25,12 @@
+ 
+ #include "raw3270.h"
+ 
++#include <linux/major.h>
++#include <linux/kdev_t.h>
++#include <linux/device.h>
++
++struct class *class3270;
++
+ /* The main 3270 data structure. */
+ struct raw3270 {
+ 	struct list_head list;
+@@ -41,6 +47,8 @@ struct raw3270 {
+ 	struct timer_list timer;	/* Device timer. */
+ 
+ 	unsigned char *ascebc;		/* ascii -> ebcdic table */
++	struct class_device *clttydev;	/* 3270-class tty device ptr */
++	struct class_device *cltubdev;	/* 3270-class tub device ptr */
+ };
+ 
+ /* raw3270->flags */
+@@ -317,6 +325,22 @@ raw3270_start(struct raw3270_view *view,
+ }
+ 
+ int
++raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
++{
++	struct raw3270 *rp;
++	int rc;
++
++	rp = view->dev;
++	if (!rp || rp->view != view)
++		rc = -EACCES;
++	else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
++		rc = -ENODEV;
++	else
++		rc =  __raw3270_start(rp, view, rq);
++	return rc;
++}
++
++int
+ raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq)
+ {
+ 	struct raw3270 *rp;
+@@ -744,6 +768,22 @@ raw3270_reset_device(struct raw3270 *rp)
+ 	return rc;
+ }
+ 
++int
++raw3270_reset(struct raw3270_view *view)
++{
++	struct raw3270 *rp;
++	int rc;
++
++	rp = view->dev;
++	if (!rp || rp->view != view)
++		rc = -EACCES;
++	else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
++		rc = -ENODEV;
++	else
++		rc = raw3270_reset_device(view->dev);
++	return rc;
++}
++
+ /*
+  * Setup new 3270 device.
+  */
+@@ -774,11 +814,12 @@ raw3270_setup_device(struct ccw_device *
+ 
+ 	/*
+ 	 * Add device to list and find the smallest unused minor
+-	 * number for it.
++	 * number for it. Note: there is no device with minor 0,
++	 * see special case for fs3270.c:fs3270_open().
+ 	 */
+ 	down(&raw3270_sem);
+ 	/* Keep the list sorted. */
+-	minor = 0;
++	minor = RAW3270_FIRSTMINOR;
+ 	rp->minor = -1;
+ 	list_for_each(l, &raw3270_devices) {
+ 		tmp = list_entry(l, struct raw3270, list);
+@@ -789,7 +830,7 @@ raw3270_setup_device(struct ccw_device *
+ 		}
+ 		minor++;
+ 	}
+-	if (rp->minor == -1 && minor < RAW3270_MAXDEVS) {
++	if (rp->minor == -1 && minor < RAW3270_MAXDEVS + RAW3270_FIRSTMINOR) {
+ 		rp->minor = minor;
+ 		list_add_tail(&rp->list, &raw3270_devices);
+ 	}
+@@ -941,11 +982,12 @@ raw3270_deactivate_view(struct raw3270_v
+ 		list_add_tail(&view->list, &rp->view_list);
+ 		/* Try to activate another view. */
+ 		if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
+-			list_for_each_entry(view, &rp->view_list, list)
+-				if (view->fn->activate(view) == 0) {
+-					rp->view = view;
++			list_for_each_entry(view, &rp->view_list, list) {
++				rp->view = view;
++				if (view->fn->activate(view) == 0)
+ 					break;
+-				}
++				rp->view = 0;
++			}
+ 		}
+ 	}
+ 	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
+@@ -961,6 +1003,8 @@ raw3270_add_view(struct raw3270_view *vi
+ 	struct raw3270 *rp;
+ 	int rc;
+ 
++	if (minor <= 0)
++		return -ENODEV;
+ 	down(&raw3270_sem);
+ 	rc = -ENODEV;
+ 	list_for_each_entry(rp, &raw3270_devices, list) {
+@@ -976,7 +1020,7 @@ raw3270_add_view(struct raw3270_view *vi
+ 			view->cols = rp->cols;
+ 			view->ascebc = rp->ascebc;
+ 			spin_lock_init(&view->lock);
+-			list_add_tail(&view->list, &rp->view_list);
++			list_add(&view->list, &rp->view_list);
+ 			rc = 0;
+ 		}
+ 		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
+@@ -1039,7 +1083,7 @@ raw3270_del_view(struct raw3270_view *vi
+ 	if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
+ 		/* Try to activate another view. */
+ 		list_for_each_entry(nv, &rp->view_list, list) {
+-			if (nv->fn->activate(view) == 0) {
++			if (nv->fn->activate(nv) == 0) {
+ 				rp->view = nv;
+ 				break;
+ 			}
+@@ -1063,6 +1107,12 @@ raw3270_delete_device(struct raw3270 *rp
+ 
+ 	/* Remove from device chain. */
+ 	down(&raw3270_sem);
++	if (rp->clttydev)
++		class_device_destroy(class3270,
++				     MKDEV(IBM_TTY3270_MAJOR, rp->minor));
++	if (rp->cltubdev)
++		class_device_destroy(class3270,
++				     MKDEV(IBM_FS3270_MAJOR, rp->minor));
+ 	list_del_init(&rp->list);
+ 	up(&raw3270_sem);
+ 
+@@ -1129,6 +1179,16 @@ raw3270_create_attributes(struct raw3270
+ {
+ 	//FIXME: check return code
+ 	sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
++	rp->clttydev =
++		class_device_create(class3270,
++				    MKDEV(IBM_TTY3270_MAJOR, rp->minor),
++				    &rp->cdev->dev, "tty%s",
++				    rp->cdev->dev.bus_id);
++	rp->cltubdev =
++		class_device_create(class3270,
++				    MKDEV(IBM_FS3270_MAJOR, rp->minor),
++				    &rp->cdev->dev, "tub%s",
++				    rp->cdev->dev.bus_id);
+ }
+ 
+ /*
+@@ -1189,13 +1249,13 @@ raw3270_set_online (struct ccw_device *c
+ 		return PTR_ERR(rp);
+ 	rc = raw3270_reset_device(rp);
+ 	if (rc)
+-		return rc;
++		goto failure;
+ 	rc = raw3270_size_device(rp);
+ 	if (rc)
+-		return rc;
++		goto failure;
+ 	rc = raw3270_reset_device(rp);
+ 	if (rc)
+-		return rc;
++		goto failure;
+ 	raw3270_create_attributes(rp);
+ 	set_bit(RAW3270_FLAGS_READY, &rp->flags);
+ 	down(&raw3270_sem);
+@@ -1203,6 +1263,10 @@ raw3270_set_online (struct ccw_device *c
+ 		np->notifier(rp->minor, 1);
+ 	up(&raw3270_sem);
+ 	return 0;
++
++failure:
++	raw3270_delete_device(rp);
++	return rc;
+ }
+ 
+ /*
+@@ -1217,6 +1281,14 @@ raw3270_remove (struct ccw_device *cdev)
+ 	struct raw3270_notifier *np;
+ 
+ 	rp = cdev->dev.driver_data;
++	/*
++	 * _remove is the opposite of _probe; it's probe that
++	 * should set up rp.  raw3270_remove gets entered for
++	 * devices even if they haven't been varied online.
++	 * Thus, rp may validly be NULL here.
++	 */
++	if (rp == NULL)
++		return;
+ 	clear_bit(RAW3270_FLAGS_READY, &rp->flags);
+ 
+ 	sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group);
+@@ -1301,6 +1373,7 @@ raw3270_init(void)
+ 	if (rc == 0) {
+ 		/* Create attributes for early (= console) device. */
+ 		down(&raw3270_sem);
++		class3270 = class_create(THIS_MODULE, "3270");
+ 		list_for_each_entry(rp, &raw3270_devices, list) {
+ 			get_device(&rp->cdev->dev);
+ 			raw3270_create_attributes(rp);
+@@ -1314,6 +1387,7 @@ static void
+ raw3270_exit(void)
+ {
+ 	ccw_driver_unregister(&raw3270_ccw_driver);
++	class_destroy(class3270);
+ }
+ 
+ MODULE_LICENSE("GPL");
+@@ -1335,7 +1409,9 @@ EXPORT_SYMBOL(raw3270_find_view);
+ EXPORT_SYMBOL(raw3270_activate_view);
+ EXPORT_SYMBOL(raw3270_deactivate_view);
+ EXPORT_SYMBOL(raw3270_start);
++EXPORT_SYMBOL(raw3270_start_locked);
+ EXPORT_SYMBOL(raw3270_start_irq);
++EXPORT_SYMBOL(raw3270_reset);
+ EXPORT_SYMBOL(raw3270_register_notifier);
+ EXPORT_SYMBOL(raw3270_unregister_notifier);
+ EXPORT_SYMBOL(raw3270_wait_queue);
+diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
+--- a/drivers/s390/char/raw3270.h
++++ b/drivers/s390/char/raw3270.h
+@@ -21,6 +21,7 @@
+ 
+ /* Local Channel Commands */
+ #define TC_WRITE	0x01		/* Write */
++#define TC_RDBUF	0x02		/* Read Buffer */
+ #define TC_EWRITE	0x05		/* Erase write */
+ #define TC_READMOD	0x06		/* Read modified */
+ #define TC_EWRITEA	0x0d		/* Erase write alternate */
+@@ -76,7 +77,8 @@
+ #define TW_KR		0xc2		/* Keyboard restore */
+ #define TW_PLUSALARM	0x04		/* Add this bit for alarm */
+ 
+-#define RAW3270_MAXDEVS	256
++#define RAW3270_FIRSTMINOR	1	/* First minor number */
++#define RAW3270_MAXDEVS		255	/* Max number of 3270 devices */
+ 
+ /* For TUBGETMOD and TUBSETMOD. Should include. */
+ struct raw3270_iocb {
+@@ -166,7 +168,10 @@ void raw3270_del_view(struct raw3270_vie
+ void raw3270_deactivate_view(struct raw3270_view *);
+ struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
+ int raw3270_start(struct raw3270_view *, struct raw3270_request *);
++int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
+ int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
++int raw3270_reset(struct raw3270_view *);
++struct raw3270_view *raw3270_view(struct raw3270_view *);
+ 
+ /* Reference count inliner for view structures. */
+ static inline void
+diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
+--- a/drivers/s390/char/tape_class.c
++++ b/drivers/s390/char/tape_class.c
+@@ -72,6 +72,7 @@ struct tape_class_device *register_tape_
+ 
+ 	tcd->class_device = class_device_create(
+ 				tape_class,
++				NULL,
+ 				tcd->char_device->dev,
+ 				device,
+ 				"%s", tcd->device_name
+diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
+--- a/drivers/s390/char/tty3270.c
++++ b/drivers/s390/char/tty3270.c
+@@ -653,18 +653,12 @@ tty3270_activate(struct raw3270_view *vi
+ 	tp->update_flags = TTY_UPDATE_ALL;
+ 	tty3270_set_timer(tp, 1);
+ 	spin_unlock_irqrestore(&tp->view.lock, flags);
+-	start_tty(tp->tty);
+ 	return 0;
+ }
+ 
+ static void
+ tty3270_deactivate(struct raw3270_view *view)
+ {
+-	struct tty3270 *tp;
+-
+-	tp = (struct tty3270 *) view;
+-	if (tp && tp->tty)
+-		stop_tty(tp->tty);
+ }
+ 
+ static int
+@@ -716,13 +710,13 @@ tty3270_alloc_view(void)
+ 				  tp->freemem_pages[pages], PAGE_SIZE);
+ 	}
+ 	tp->write = raw3270_request_alloc(TTY3270_OUTPUT_BUFFER_SIZE);
+-	if (!tp->write)
++	if (IS_ERR(tp->write))
+ 		goto out_pages;
+ 	tp->read = raw3270_request_alloc(0);
+-	if (!tp->read)
++	if (IS_ERR(tp->read))
+ 		goto out_write;
+ 	tp->kreset = raw3270_request_alloc(1);
+-	if (!tp->kreset)
++	if (IS_ERR(tp->kreset))
+ 		goto out_read;
+ 	tp->kbd = kbd_alloc();
+ 	if (!tp->kbd)
+@@ -845,7 +839,8 @@ tty3270_del_views(void)
+ 	int i;
+ 
+ 	for (i = 0; i < tty3270_max_index; i++) {
+-		tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, i);
++		tp = (struct tty3270 *)
++			raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
+ 		if (!IS_ERR(tp))
+ 			raw3270_del_view(&tp->view);
+ 	}
+@@ -871,7 +866,9 @@ tty3270_open(struct tty_struct *tty, str
+ 	if (tty->count > 1)
+ 		return 0;
+ 	/* Check if the tty3270 is already there. */
+-	tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, tty->index);
++	tp = (struct tty3270 *)
++		raw3270_find_view(&tty3270_fn,
++				  tty->index + RAW3270_FIRSTMINOR);
+ 	if (!IS_ERR(tp)) {
+ 		tty->driver_data = tp;
+ 		tty->winsize.ws_row = tp->view.rows - 2;
+@@ -903,7 +900,8 @@ tty3270_open(struct tty_struct *tty, str
+ 		     (void (*)(unsigned long)) tty3270_read_tasklet,
+ 		     (unsigned long) tp->read);
+ 
+-	rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index);
++	rc = raw3270_add_view(&tp->view, &tty3270_fn,
++			      tty->index + RAW3270_FIRSTMINOR);
+ 	if (rc) {
+ 		tty3270_free_view(tp);
+ 		return rc;
+@@ -911,8 +909,8 @@ tty3270_open(struct tty_struct *tty, str
+ 
+ 	rc = tty3270_alloc_screen(tp);
+ 	if (rc) {
+-		raw3270_del_view(&tp->view);
+ 		raw3270_put_view(&tp->view);
++		raw3270_del_view(&tp->view);
+ 		return rc;
+ 	}
+ 
+@@ -1780,7 +1778,7 @@ tty3270_init(void)
+ 	struct tty_driver *driver;
+ 	int ret;
+ 
+-	driver = alloc_tty_driver(256);
++	driver = alloc_tty_driver(RAW3270_MAXDEVS);
+ 	if (!driver)
+ 		return -ENOMEM;
+ 
+@@ -1794,6 +1792,7 @@ tty3270_init(void)
+ 	driver->driver_name = "ttyTUB";
+ 	driver->name = "ttyTUB";
+ 	driver->major = IBM_TTY3270_MAJOR;
++	driver->minor_start = RAW3270_FIRSTMINOR;
+ 	driver->type = TTY_DRIVER_TYPE_SYSTEM;
+ 	driver->subtype = SYSTEM_TYPE_TTY;
+ 	driver->init_termios = tty_std_termios;
+diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
+--- a/drivers/s390/char/vmlogrdr.c
++++ b/drivers/s390/char/vmlogrdr.c
+@@ -788,6 +788,7 @@ vmlogrdr_register_device(struct vmlogrdr
+ 	}
+ 	priv->class_device = class_device_create(
+ 				vmlogrdr_class,
++				NULL,
+ 				MKDEV(vmlogrdr_major, priv->minor_num),
+ 				dev,
+ 				"%s", dev->bus_id );
+diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
+--- a/drivers/s390/cio/cmf.c
++++ b/drivers/s390/cio/cmf.c
+@@ -30,10 +30,13 @@
+ #include <linux/list.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
++#include <linux/slab.h>
++#include <linux/timex.h>	/* get_clock() */
+ 
+ #include <asm/ccwdev.h>
+ #include <asm/cio.h>
+ #include <asm/cmb.h>
++#include <asm/div64.h>
+ 
+ #include "cio.h"
+ #include "css.h"
+diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
+--- a/drivers/s390/cio/device.c
++++ b/drivers/s390/cio/device.c
+@@ -22,6 +22,7 @@
+ 
+ #include <asm/ccwdev.h>
+ #include <asm/cio.h>
++#include <asm/param.h>		/* HZ */
+ 
+ #include "cio.h"
+ #include "css.h"
+@@ -252,6 +253,23 @@ cutype_show (struct device *dev, struct 
+ }
+ 
+ static ssize_t
++modalias_show (struct device *dev, struct device_attribute *attr, char *buf)
++{
++	struct ccw_device *cdev = to_ccwdev(dev);
++	struct ccw_device_id *id = &(cdev->id);
++	int ret;
++
++	ret = sprintf(buf, "ccw:t%04Xm%02x",
++			id->cu_type, id->cu_model);
++	if (id->dev_type != 0)
++		ret += sprintf(buf + ret, "dt%04Xdm%02X\n",
++				id->dev_type, id->dev_model);
++	else
++		ret += sprintf(buf + ret, "dtdm\n");
++	return ret;
++}
++
++static ssize_t
+ online_show (struct device *dev, struct device_attribute *attr, char *buf)
+ {
+ 	struct ccw_device *cdev = to_ccwdev(dev);
+@@ -448,6 +466,7 @@ static DEVICE_ATTR(chpids, 0444, chpids_
+ static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);
+ static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);
+ static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);
++static DEVICE_ATTR(modalias, 0444, modalias_show, NULL);
+ static DEVICE_ATTR(online, 0644, online_show, online_store);
+ extern struct device_attribute dev_attr_cmb_enable;
+ static DEVICE_ATTR(availability, 0444, available_show, NULL);
+@@ -471,6 +490,7 @@ subchannel_add_files (struct device *dev
+ static struct attribute * ccwdev_attrs[] = {
+ 	&dev_attr_devtype.attr,
+ 	&dev_attr_cutype.attr,
++	&dev_attr_modalias.attr,
+ 	&dev_attr_online.attr,
+ 	&dev_attr_cmb_enable.attr,
+ 	&dev_attr_availability.attr,
+diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
+--- a/drivers/s390/cio/device_fsm.c
++++ b/drivers/s390/cio/device_fsm.c
+@@ -11,6 +11,8 @@
+ #include <linux/module.h>
+ #include <linux/config.h>
+ #include <linux/init.h>
++#include <linux/jiffies.h>
++#include <linux/string.h>
+ 
+ #include <asm/ccwdev.h>
+ #include <asm/cio.h>
+diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
+--- a/drivers/s390/net/fsm.c
++++ b/drivers/s390/net/fsm.c
+@@ -16,7 +16,7 @@ MODULE_LICENSE("GPL");
+ 
+ fsm_instance *
+ init_fsm(char *name, const char **state_names, const char **event_names, int nr_states,
+-		int nr_events, const fsm_node *tmpl, int tmpl_len, int order)
++		int nr_events, const fsm_node *tmpl, int tmpl_len, gfp_t order)
+ {
+ 	int i;
+ 	fsm_instance *this;
+diff --git a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
+--- a/drivers/s390/net/fsm.h
++++ b/drivers/s390/net/fsm.h
+@@ -110,7 +110,7 @@ extern fsm_instance *
+ init_fsm(char *name, const char **state_names,
+ 	 const char **event_names,
+ 	 int nr_states, int nr_events, const fsm_node *tmpl,
+-	 int tmpl_len, int order);
++	 int tmpl_len, gfp_t order);
+ 
+ /**
+  * Releases an FSM
+diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
+--- a/drivers/s390/net/qeth.h
++++ b/drivers/s390/net/qeth.h
+@@ -275,6 +275,10 @@ qeth_is_ipa_enabled(struct qeth_ipa_info
+ 	QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \
+ 	QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \
+ 	QETH_MAX_QUEUES,0x103}, \
++	{0x1731,0x06,0x1732,0x06,QETH_CARD_TYPE_OSN,0, \
++	QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \
++	QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \
++	QETH_MAX_QUEUES,0}, \
+ 	{0,0,0,0,0,0,0,0,0}}
+ 
+ #define QETH_REAL_CARD		1
+@@ -363,10 +367,22 @@ struct qeth_hdr_layer2 {
+ 	__u8 reserved2[16];
+ } __attribute__ ((packed));
+ 
++struct qeth_hdr_osn {
++	__u8 id;
++	__u8 reserved;
++	__u16 seq_no;
++	__u16 reserved2;
++	__u16 control_flags;
++	__u16 pdu_length;
++	__u8 reserved3[18];
++	__u32 ccid;
++} __attribute__ ((packed));
++					    
+ struct qeth_hdr {
+ 	union {
+ 		struct qeth_hdr_layer2 l2;
+ 		struct qeth_hdr_layer3 l3;
++		struct qeth_hdr_osn    osn;
+ 	} hdr;
+ } __attribute__ ((packed));
+ 
+@@ -413,6 +429,7 @@ enum qeth_header_ids {
+ 	QETH_HEADER_TYPE_LAYER3 = 0x01,
+ 	QETH_HEADER_TYPE_LAYER2 = 0x02,
+ 	QETH_HEADER_TYPE_TSO	= 0x03,
++	QETH_HEADER_TYPE_OSN    = 0x04,
+ };
+ /* flags for qeth_hdr.ext_flags */
+ #define QETH_HDR_EXT_VLAN_FRAME       0x01
+@@ -582,7 +599,6 @@ enum qeth_card_states {
+  * Protocol versions
+  */
+ enum qeth_prot_versions {
+-	QETH_PROT_SNA  = 0x0001,
+ 	QETH_PROT_IPV4 = 0x0004,
+ 	QETH_PROT_IPV6 = 0x0006,
+ };
+@@ -761,6 +777,11 @@ enum qeth_threads {
+ 	QETH_RECOVER_THREAD = 2,
+ };
+ 
++struct qeth_osn_info {
++	int (*assist_cb)(struct net_device *dev, void *data);
++	int (*data_cb)(struct sk_buff *skb);
++};
++
+ struct qeth_card {
+ 	struct list_head list;
+ 	enum qeth_card_states state;
+@@ -803,6 +824,7 @@ struct qeth_card {
+ 	int use_hard_stop;
+ 	int (*orig_hard_header)(struct sk_buff *,struct net_device *,
+ 				unsigned short,void *,void *,unsigned);
++	struct qeth_osn_info osn_info; 
+ };
+ 
+ struct qeth_card_list_struct {
+@@ -916,10 +938,12 @@ qeth_get_hlen(__u8 link_type)
+ static inline unsigned short
+ qeth_get_netdev_flags(struct qeth_card *card)
+ {
+-	if (card->options.layer2)
++	if (card->options.layer2 &&
++	   (card->info.type == QETH_CARD_TYPE_OSAE))
+ 		return 0;
+ 	switch (card->info.type) {
+ 	case QETH_CARD_TYPE_IQD:
++	case QETH_CARD_TYPE_OSN:	
+ 		return IFF_NOARP;
+ #ifdef CONFIG_QETH_IPV6
+ 	default:
+@@ -956,9 +980,10 @@ static inline int
+ qeth_get_max_mtu_for_card(int cardtype)
+ {
+ 	switch (cardtype) {
++		
+ 	case QETH_CARD_TYPE_UNKNOWN:
+-		return 61440;
+ 	case QETH_CARD_TYPE_OSAE:
++	case QETH_CARD_TYPE_OSN:
+ 		return 61440;
+ 	case QETH_CARD_TYPE_IQD:
+ 		return 57344;
+@@ -1004,6 +1029,7 @@ qeth_mtu_is_valid(struct qeth_card * car
+ 	case QETH_CARD_TYPE_IQD:
+ 		return ((mtu >= 576) &&
+ 			(mtu <= card->info.max_mtu + 4096 - 32));
++	case QETH_CARD_TYPE_OSN:
+ 	case QETH_CARD_TYPE_UNKNOWN:
+ 	default:
+ 		return 1;
+@@ -1015,6 +1041,7 @@ qeth_get_arphdr_type(int cardtype, int l
+ {
+ 	switch (cardtype) {
+ 	case QETH_CARD_TYPE_OSAE:
++	case QETH_CARD_TYPE_OSN:
+ 		switch (linktype) {
+ 		case QETH_LINK_TYPE_LANE_TR:
+ 		case QETH_LINK_TYPE_HSTR:
+@@ -1182,4 +1209,16 @@ qeth_fill_header(struct qeth_card *, str
+ extern void
+ qeth_flush_buffers(struct qeth_qdio_out_q *, int, int, int);
+ 
++extern int
++qeth_osn_assist(struct net_device *, void *, int);
++
++extern int
++qeth_osn_register(unsigned char *read_dev_no,
++                 struct net_device **,
++                 int (*assist_cb)(struct net_device *, void *),
++                 int (*data_cb)(struct sk_buff *));
++
++extern void
++qeth_osn_deregister(struct net_device *);
++		
+ #endif /* __QETH_H__ */
+diff --git a/drivers/s390/net/qeth_fs.h b/drivers/s390/net/qeth_fs.h
+--- a/drivers/s390/net/qeth_fs.h
++++ b/drivers/s390/net/qeth_fs.h
+@@ -12,7 +12,7 @@
+ #ifndef __QETH_FS_H__
+ #define __QETH_FS_H__
+ 
+-#define VERSION_QETH_FS_H "$Revision: 1.9 $"
++#define VERSION_QETH_FS_H "$Revision: 1.10 $"
+ 
+ extern const char *VERSION_QETH_PROC_C;
+ extern const char *VERSION_QETH_SYS_C;
+@@ -43,6 +43,12 @@ extern void
+ qeth_remove_device_attributes(struct device *dev);
+ 
+ extern int
++qeth_create_device_attributes_osn(struct device *dev);
++
++extern void
++qeth_remove_device_attributes_osn(struct device *dev);
++		    
++extern int
+ qeth_create_driver_attributes(void);
+ 
+ extern void
+@@ -108,6 +114,8 @@ qeth_get_cardname(struct qeth_card *card
+ 			return " OSD Express";
+ 		case QETH_CARD_TYPE_IQD:
+ 			return " HiperSockets";
++		case QETH_CARD_TYPE_OSN:
++			return " OSN QDIO";
+ 		default:
+ 			return " unknown";
+ 		}
+@@ -153,6 +161,8 @@ qeth_get_cardname_short(struct qeth_card
+ 			}
+ 		case QETH_CARD_TYPE_IQD:
+ 			return "HiperSockets";
++		case QETH_CARD_TYPE_OSN:
++			return "OSN";
+ 		default:
+ 			return "unknown";
+ 		}
+diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
+--- a/drivers/s390/net/qeth_main.c
++++ b/drivers/s390/net/qeth_main.c
+@@ -196,7 +196,6 @@ qeth_notifier_register(struct task_struc
+ {
+ 	struct qeth_notify_list_struct *n_entry;
+ 
+-
+ 	/*check first if entry already exists*/
+ 	spin_lock(&qeth_notify_lock);
+ 	list_for_each_entry(n_entry, &qeth_notify_list, list) {
+@@ -1024,7 +1023,10 @@ qeth_set_intial_options(struct qeth_card
+ 	card->options.fake_broadcast = 0;
+ 	card->options.add_hhlen = DEFAULT_ADD_HHLEN;
+ 	card->options.fake_ll = 0;
+-	card->options.layer2 = 0;
++	if (card->info.type == QETH_CARD_TYPE_OSN)
++		card->options.layer2 = 1;
++	else
++		card->options.layer2 = 0;
+ }
+ 
+ /**
+@@ -1113,19 +1115,20 @@ qeth_determine_card_type(struct qeth_car
+ 
+ 	QETH_DBF_TEXT(setup, 2, "detcdtyp");
+ 
++	card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
++	card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+ 	while (known_devices[i][4]) {
+ 		if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) &&
+ 		    (CARD_RDEV(card)->id.dev_model == known_devices[i][3])) {
+ 			card->info.type = known_devices[i][4];
++			card->qdio.no_out_queues = known_devices[i][8];
++			card->info.is_multicast_different = known_devices[i][9];
+ 			if (is_1920_device(card)) {
+ 				PRINT_INFO("Priority Queueing not able "
+ 					   "due to hardware limitations!\n");
+ 				card->qdio.no_out_queues = 1;
+ 				card->qdio.default_out_queue = 0;
+-			} else {
+-				card->qdio.no_out_queues = known_devices[i][8];
+-			}
+-			card->info.is_multicast_different = known_devices[i][9];
++			} 
+ 			return 0;
+ 		}
+ 		i++;
+@@ -1149,6 +1152,8 @@ qeth_probe_device(struct ccwgroup_device
+ 	if (!get_device(dev))
+ 		return -ENODEV;
+ 
++	QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id);
++	
+ 	card = qeth_alloc_card();
+ 	if (!card) {
+ 		put_device(dev);
+@@ -1158,28 +1163,27 @@ qeth_probe_device(struct ccwgroup_device
+ 	card->read.ccwdev  = gdev->cdev[0];
+ 	card->write.ccwdev = gdev->cdev[1];
+ 	card->data.ccwdev  = gdev->cdev[2];
+-
+-	if ((rc = qeth_setup_card(card))){
+-		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
+-		put_device(dev);
+-		qeth_free_card(card);
+-		return rc;
+-	}
+ 	gdev->dev.driver_data = card;
+ 	card->gdev = gdev;
+ 	gdev->cdev[0]->handler = qeth_irq;
+ 	gdev->cdev[1]->handler = qeth_irq;
+ 	gdev->cdev[2]->handler = qeth_irq;
+ 
+-	rc = qeth_create_device_attributes(dev);
+-	if (rc) {
++	if ((rc = qeth_determine_card_type(card))){
++		PRINT_WARN("%s: not a valid card type\n", __func__);
++		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
++		put_device(dev);
++		qeth_free_card(card);
++		return rc;
++	}			    
++	if ((rc = qeth_setup_card(card))){
++		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
+ 		put_device(dev);
+ 		qeth_free_card(card);
+ 		return rc;
+ 	}
+-	if ((rc = qeth_determine_card_type(card))){
+-		PRINT_WARN("%s: not a valid card type\n", __func__);
+-		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
++	rc = qeth_create_device_attributes(dev);
++	if (rc) {
+ 		put_device(dev);
+ 		qeth_free_card(card);
+ 		return rc;
+@@ -1660,6 +1664,8 @@ qeth_check_ipa_data(struct qeth_card *ca
+ 				netif_carrier_on(card->dev);
+ 				qeth_schedule_recovery(card);
+ 				return NULL;
++			case IPA_CMD_MODCCID:
++				return cmd;
+ 			case IPA_CMD_REGISTER_LOCAL_ADDR:
+ 				QETH_DBF_TEXT(trace,3, "irla");
+ 				break;
+@@ -1721,6 +1727,14 @@ qeth_send_control_data_cb(struct qeth_ch
+ 	cmd = qeth_check_ipa_data(card, iob);
+ 	if ((cmd == NULL) && (card->state != CARD_STATE_DOWN))
+ 		goto out;
++	/*in case of OSN : check if cmd is set */
++	if (card->info.type == QETH_CARD_TYPE_OSN &&
++	    cmd &&
++	    cmd->hdr.command != IPA_CMD_STARTLAN &&
++	    card->osn_info.assist_cb != NULL) {
++		card->osn_info.assist_cb(card->dev, cmd);
++		goto out;
++	}
+ 
+ 	spin_lock_irqsave(&card->lock, flags);
+ 	list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
+@@ -1737,8 +1751,7 @@ qeth_send_control_data_cb(struct qeth_ch
+ 					keep_reply = reply->callback(card,
+ 							reply,
+ 							(unsigned long)cmd);
+-				}
+-				else
++				} else
+ 					keep_reply = reply->callback(card,
+ 							reply,
+ 							(unsigned long)iob);
+@@ -1768,6 +1781,24 @@ out:
+ 	qeth_release_buffer(channel,iob);
+ }
+ 
++static inline void
++qeth_prepare_control_data(struct qeth_card *card, int len,
++struct qeth_cmd_buffer *iob)
++{
++	qeth_setup_ccw(&card->write,iob->data,len);
++	iob->callback = qeth_release_buffer;
++
++	memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
++	       &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
++	card->seqno.trans_hdr++;
++	memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
++	       &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
++	card->seqno.pdu_hdr++;
++	memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
++	       &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
++	QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
++}
++						    
+ static int
+ qeth_send_control_data(struct qeth_card *card, int len,
+ 		       struct qeth_cmd_buffer *iob,
+@@ -1778,24 +1809,11 @@ qeth_send_control_data(struct qeth_card 
+ {
+ 	int rc;
+ 	unsigned long flags;
+-	struct qeth_reply *reply;
++	struct qeth_reply *reply = NULL;
+ 	struct timer_list timer;
+ 
+ 	QETH_DBF_TEXT(trace, 2, "sendctl");
+ 
+-	qeth_setup_ccw(&card->write,iob->data,len);
+-
+-	memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
+-	       &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
+-	card->seqno.trans_hdr++;
+-
+-	memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
+-	       &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
+-	card->seqno.pdu_hdr++;
+-	memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
+-	       &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
+-	iob->callback = qeth_release_buffer;
+-
+ 	reply = qeth_alloc_reply(card);
+ 	if (!reply) {
+ 		PRINT_WARN("Could no alloc qeth_reply!\n");
+@@ -1810,10 +1828,6 @@ qeth_send_control_data(struct qeth_card 
+ 	init_timer(&timer);
+ 	timer.function = qeth_cmd_timeout;
+ 	timer.data = (unsigned long) reply;
+-	if (IS_IPA(iob->data))
+-		timer.expires = jiffies + QETH_IPA_TIMEOUT;
+-	else
+-		timer.expires = jiffies + QETH_TIMEOUT;
+ 	init_waitqueue_head(&reply->wait_q);
+ 	spin_lock_irqsave(&card->lock, flags);
+ 	list_add_tail(&reply->list, &card->cmd_waiter_list);
+@@ -1821,6 +1835,11 @@ qeth_send_control_data(struct qeth_card 
+ 	QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
+ 	wait_event(card->wait_q,
+ 		   atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
++	qeth_prepare_control_data(card, len, iob);
++	if (IS_IPA(iob->data))
++		timer.expires = jiffies + QETH_IPA_TIMEOUT;
++	else
++		timer.expires = jiffies + QETH_TIMEOUT;
+ 	QETH_DBF_TEXT(trace, 6, "noirqpnd");
+ 	spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
+ 	rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
+@@ -1848,6 +1867,62 @@ qeth_send_control_data(struct qeth_card 
+ }
+ 
+ static int
++qeth_osn_send_control_data(struct qeth_card *card, int len,
++			   struct qeth_cmd_buffer *iob)
++{
++	unsigned long flags;
++	int rc = 0;
++
++	QETH_DBF_TEXT(trace, 5, "osndctrd");
++
++	wait_event(card->wait_q,
++		   atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
++	qeth_prepare_control_data(card, len, iob);
++	QETH_DBF_TEXT(trace, 6, "osnoirqp");
++	spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
++	rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
++			      (addr_t) iob, 0, 0);
++	spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
++	if (rc){
++		PRINT_WARN("qeth_osn_send_control_data: "
++			   "ccw_device_start rc = %i\n", rc);
++		QETH_DBF_TEXT_(trace, 2, " err%d", rc);
++		qeth_release_buffer(iob->channel, iob);
++		atomic_set(&card->write.irq_pending, 0);
++		wake_up(&card->wait_q);
++	}
++	return rc;
++}					
++
++static inline void
++qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
++		     char prot_type)
++{
++	memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
++	memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
++	memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
++	       &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
++}
++
++static int
++qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
++		      int data_len)
++{
++	u16 s1, s2;
++
++QETH_DBF_TEXT(trace,4,"osndipa");
++
++	qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
++	s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
++	s2 = (u16)data_len;
++	memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
++	memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
++	memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
++	memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
++	return qeth_osn_send_control_data(card, s1, iob);
++}
++							    
++static int
+ qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
+ 		  int (*reply_cb)
+ 		  (struct qeth_card *,struct qeth_reply*, unsigned long),
+@@ -1858,17 +1933,14 @@ qeth_send_ipa_cmd(struct qeth_card *card
+ 
+ 	QETH_DBF_TEXT(trace,4,"sendipa");
+ 
+-	memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
+-
+ 	if (card->options.layer2)
+-		prot_type = QETH_PROT_LAYER2;
++		if (card->info.type == QETH_CARD_TYPE_OSN)
++			prot_type = QETH_PROT_OSN2;
++		else
++			prot_type = QETH_PROT_LAYER2;
+ 	else
+ 		prot_type = QETH_PROT_TCPIP;
+-
+-	memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
+-	memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
+-	       &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
+-
++	qeth_prepare_ipa_cmd(card,iob,prot_type);
+ 	rc = qeth_send_control_data(card, IPA_CMD_LENGTH, iob,
+ 				    reply_cb, reply_param);
+ 	return rc;
+@@ -2010,7 +2082,10 @@ qeth_ulp_enable(struct qeth_card *card)
+ 	*(QETH_ULP_ENABLE_LINKNUM(iob->data)) =
+ 		(__u8) card->info.portno;
+ 	if (card->options.layer2)
+-		prot_type = QETH_PROT_LAYER2;
++		if (card->info.type == QETH_CARD_TYPE_OSN)
++			prot_type = QETH_PROT_OSN2;
++		else
++			prot_type = QETH_PROT_LAYER2;
+ 	else
+ 		prot_type = QETH_PROT_TCPIP;
+ 
+@@ -2100,15 +2175,21 @@ qeth_check_for_inbound_error(struct qeth
+ }
+ 
+ static inline struct sk_buff *
+-qeth_get_skb(unsigned int length)
++qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
+ {
+ 	struct sk_buff* skb;
++	int add_len;
++
++	add_len = 0;
++	if (hdr->hdr.osn.id == QETH_HEADER_TYPE_OSN)
++		add_len = sizeof(struct qeth_hdr);
+ #ifdef CONFIG_QETH_VLAN
+-	if ((skb = dev_alloc_skb(length + VLAN_HLEN)))
+-		skb_reserve(skb, VLAN_HLEN);
+-#else
+-	skb = dev_alloc_skb(length);
++	else
++		add_len = VLAN_HLEN;
+ #endif
++	skb = dev_alloc_skb(length + add_len);
++	if (skb && add_len)
++		skb_reserve(skb, add_len);
+ 	return skb;
+ }
+ 
+@@ -2138,7 +2219,10 @@ qeth_get_next_skb(struct qeth_card *card
+ 
+ 	offset += sizeof(struct qeth_hdr);
+ 	if (card->options.layer2)
+-		skb_len = (*hdr)->hdr.l2.pkt_length;
++		if (card->info.type == QETH_CARD_TYPE_OSN)
++			skb_len = (*hdr)->hdr.osn.pdu_length;
++		else
++			skb_len = (*hdr)->hdr.l2.pkt_length;
+ 	else
+ 		skb_len = (*hdr)->hdr.l3.length;
+ 
+@@ -2146,15 +2230,15 @@ qeth_get_next_skb(struct qeth_card *card
+ 		return NULL;
+ 	if (card->options.fake_ll){
+ 		if(card->dev->type == ARPHRD_IEEE802_TR){
+-			if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR)))
++			if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR, *hdr)))
+ 				goto no_mem;
+ 			skb_reserve(skb,QETH_FAKE_LL_LEN_TR);
+ 		} else {
+-			if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH)))
++			if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH, *hdr)))
+ 				goto no_mem;
+ 			skb_reserve(skb,QETH_FAKE_LL_LEN_ETH);
+ 		}
+-	} else if (!(skb = qeth_get_skb(skb_len)))
++	} else if (!(skb = qeth_get_skb(skb_len, *hdr)))
+ 		goto no_mem;
+ 	data_ptr = element->addr + offset;
+ 	while (skb_len) {
+@@ -2453,8 +2537,12 @@ qeth_process_inbound_buffer(struct qeth_
+ 		skb->dev = card->dev;
+ 		if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
+ 			vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr);
+-		else
++		else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)     
+ 			qeth_rebuild_skb(card, skb, hdr);
++		else { /*in case of OSN*/
++			skb_push(skb, sizeof(struct qeth_hdr));
++			memcpy(skb->data, hdr, sizeof(struct qeth_hdr));
++		}
+ 		/* is device UP ? */
+ 		if (!(card->dev->flags & IFF_UP)){
+ 			dev_kfree_skb_any(skb);
+@@ -2465,7 +2553,10 @@ qeth_process_inbound_buffer(struct qeth_
+ 			vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
+ 		else
+ #endif
+-		rxrc = netif_rx(skb);
++		if (card->info.type == QETH_CARD_TYPE_OSN)
++			rxrc = card->osn_info.data_cb(skb);
++		else
++			rxrc = netif_rx(skb);
+ 		card->dev->last_rx = jiffies;
+ 		card->stats.rx_packets++;
+ 		card->stats.rx_bytes += skb->len;
+@@ -3150,8 +3241,6 @@ qeth_init_qdio_info(struct qeth_card *ca
+ 	INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
+ 	INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
+ 	/* outbound */
+-	card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
+-	card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+ }
+ 
+ static int
+@@ -3466,7 +3555,7 @@ qeth_mpc_initialize(struct qeth_card *ca
+ 
+ 	return 0;
+ out_qdio:
+-	qeth_qdio_clear_card(card, card->info.type==QETH_CARD_TYPE_OSAE);
++	qeth_qdio_clear_card(card, card->info.type!=QETH_CARD_TYPE_IQD);
+ 	return rc;
+ }
+ 
+@@ -3491,6 +3580,9 @@ qeth_get_netdevice(enum qeth_card_types 
+ 	case QETH_CARD_TYPE_IQD:
+ 		dev = alloc_netdev(0, "hsi%d", ether_setup);
+ 		break;
++	case QETH_CARD_TYPE_OSN:
++		dev = alloc_netdev(0, "osn%d", ether_setup);
++		break;
+ 	default:
+ 		dev = alloc_etherdev(0);
+ 	}
+@@ -3655,7 +3747,8 @@ qeth_open(struct net_device *dev)
+ 	if (card->state != CARD_STATE_SOFTSETUP)
+ 		return -ENODEV;
+ 
+-	if ( (card->options.layer2) &&
++	if ( (card->info.type != QETH_CARD_TYPE_OSN) &&
++	     (card->options.layer2) &&
+ 	     (!card->info.layer2_mac_registered)) {
+ 		QETH_DBF_TEXT(trace,4,"nomacadr");
+ 		return -EPERM;
+@@ -3693,6 +3786,9 @@ qeth_get_cast_type(struct qeth_card *car
+ {
+ 	int cast_type = RTN_UNSPEC;
+ 
++	if (card->info.type == QETH_CARD_TYPE_OSN)
++		return cast_type;
++
+ 	if (skb->dst && skb->dst->neighbour){
+ 		cast_type = skb->dst->neighbour->type;
+ 		if ((cast_type == RTN_BROADCAST) ||
+@@ -3782,13 +3878,16 @@ static inline int
+ qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
+ 		 struct qeth_hdr **hdr, int ipv)
+ {
+-	int rc;
++	int rc = 0;
+ #ifdef CONFIG_QETH_VLAN
+ 	u16 *tag;
+ #endif
+ 
+ 	QETH_DBF_TEXT(trace, 6, "prepskb");
+-
++	if (card->info.type == QETH_CARD_TYPE_OSN) {
++		*hdr = (struct qeth_hdr *)(*skb)->data;
++		return rc;
++	}
+         rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
+         if (rc)
+                 return rc;
+@@ -4291,8 +4390,14 @@ qeth_send_packet(struct qeth_card *card,
+ 			}
+ 		}
+ 	}
++	if ((card->info.type == QETH_CARD_TYPE_OSN) &&
++		(skb->protocol == htons(ETH_P_IPV6))) {
++		dev_kfree_skb_any(skb);
++		return 0;
++	}
+ 	cast_type = qeth_get_cast_type(card, skb);
+-	if ((cast_type == RTN_BROADCAST) && (card->info.broadcast_capable == 0)){
++	if ((cast_type == RTN_BROADCAST) && 
++	    (card->info.broadcast_capable == 0)){
+ 		card->stats.tx_dropped++;
+ 		card->stats.tx_errors++;
+ 		dev_kfree_skb_any(skb);
+@@ -4320,7 +4425,8 @@ qeth_send_packet(struct qeth_card *card,
+ 			QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc);
+ 			return rc;
+ 		}
+-		qeth_fill_header(card, hdr, skb, ipv, cast_type);
++		if (card->info.type != QETH_CARD_TYPE_OSN)
++			qeth_fill_header(card, hdr, skb, ipv, cast_type);
+ 	}
+ 
+ 	if (large_send == QETH_LARGE_SEND_EDDP) {
+@@ -4381,6 +4487,7 @@ qeth_mdio_read(struct net_device *dev, i
+ 	case MII_BMCR: /* Basic mode control register */
+ 		rc = BMCR_FULLDPLX;
+ 		if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH)&&
++		    (card->info.link_type != QETH_LINK_TYPE_OSN) &&
+ 		    (card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH))
+ 			rc |= BMCR_SPEED100;
+ 		break;
+@@ -5004,6 +5111,9 @@ qeth_do_ioctl(struct net_device *dev, st
+             (card->state != CARD_STATE_SOFTSETUP))
+ 		return -ENODEV;
+ 
++	if (card->info.type == QETH_CARD_TYPE_OSN)
++		return -EPERM;
++
+ 	switch (cmd){
+ 	case SIOC_QETH_ARP_SET_NO_ENTRIES:
+ 		if ( !capable(CAP_NET_ADMIN) ||
+@@ -5329,6 +5439,9 @@ qeth_set_multicast_list(struct net_devic
+ {
+ 	struct qeth_card *card = (struct qeth_card *) dev->priv;
+ 
++	if (card->info.type == QETH_CARD_TYPE_OSN)
++		return ;
++	 
+ 	QETH_DBF_TEXT(trace,3,"setmulti");
+ 	qeth_delete_mc_addresses(card);
+ 	qeth_add_multicast_ipv4(card);
+@@ -5370,6 +5483,94 @@ qeth_get_addr_buffer(enum qeth_prot_vers
+ 	return addr;
+ }
+ 
++int
++qeth_osn_assist(struct net_device *dev,
++		void *data,
++		int data_len)
++{
++	struct qeth_cmd_buffer *iob;
++	struct qeth_card *card;
++	int rc;
++	
++	QETH_DBF_TEXT(trace, 2, "osnsdmc");
++	if (!dev)
++		return -ENODEV;
++	card = (struct qeth_card *)dev->priv;
++	if (!card)
++		return -ENODEV;
++	if ((card->state != CARD_STATE_UP) &&
++	    (card->state != CARD_STATE_SOFTSETUP))
++		return -ENODEV;
++	iob = qeth_wait_for_buffer(&card->write);
++	memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
++	rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
++	return rc;
++}
++
++static struct net_device *
++qeth_netdev_by_devno(unsigned char *read_dev_no)
++{
++	struct qeth_card *card;
++	struct net_device *ndev;
++	unsigned char *readno;
++	__u16 temp_dev_no, card_dev_no;
++	char *endp;
++	unsigned long flags;
++
++	ndev = NULL;
++	memcpy(&temp_dev_no, read_dev_no, 2);
++	read_lock_irqsave(&qeth_card_list.rwlock, flags);
++	list_for_each_entry(card, &qeth_card_list.list, list) {
++		readno = CARD_RDEV_ID(card);
++		readno += (strlen(readno) - 4);
++		card_dev_no = simple_strtoul(readno, &endp, 16);
++		if (card_dev_no == temp_dev_no) {
++			ndev = card->dev;
++			break;
++		}
++	}
++	read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
++	return ndev;
++}
++
++int
++qeth_osn_register(unsigned char *read_dev_no,
++		  struct net_device **dev,
++		  int (*assist_cb)(struct net_device *, void *),
++		  int (*data_cb)(struct sk_buff *))
++{
++	struct qeth_card * card;
++
++	QETH_DBF_TEXT(trace, 2, "osnreg");
++	*dev = qeth_netdev_by_devno(read_dev_no);
++	if (*dev == NULL)
++		return -ENODEV;
++	card = (struct qeth_card *)(*dev)->priv;
++	if (!card)
++		return -ENODEV;
++	if ((assist_cb == NULL) || (data_cb == NULL))
++		return -EINVAL;
++	card->osn_info.assist_cb = assist_cb;
++	card->osn_info.data_cb = data_cb;
++	return 0;
++}
++
++void
++qeth_osn_deregister(struct net_device * dev)
++{
++	struct qeth_card *card;
++
++	QETH_DBF_TEXT(trace, 2, "osndereg");
++	if (!dev)
++		return;
++	card = (struct qeth_card *)dev->priv;
++	if (!card)
++		return;
++	card->osn_info.assist_cb = NULL;
++	card->osn_info.data_cb = NULL;
++	return;
++}
++					   
+ static void
+ qeth_delete_mc_addresses(struct qeth_card *card)
+ {
+@@ -5700,6 +5901,12 @@ qeth_layer2_set_mac_address(struct net_d
+ 		QETH_DBF_TEXT(trace, 3, "setmcLY3");
+ 		return -EOPNOTSUPP;
+ 	}
++	if (card->info.type == QETH_CARD_TYPE_OSN) {
++		PRINT_WARN("Setting MAC address on %s is not supported.\n",
++			   dev->name);
++		QETH_DBF_TEXT(trace, 3, "setmcOSN");
++		return -EOPNOTSUPP;
++	}
+ 	QETH_DBF_TEXT_(trace, 3, "%s", CARD_BUS_ID(card));
+ 	QETH_DBF_HEX(trace, 3, addr->sa_data, OSA_ADDR_LEN);
+ 	rc = qeth_layer2_send_delmac(card, &card->dev->dev_addr[0]);
+@@ -6076,9 +6283,8 @@ qeth_netdev_init(struct net_device *dev)
+ 			qeth_get_hlen(card->info.link_type) + card->options.add_hhlen;
+ 	dev->addr_len = OSA_ADDR_LEN;
+ 	dev->mtu = card->info.initial_mtu;
+-
+-	SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops);
+-
++	if (card->info.type != QETH_CARD_TYPE_OSN)
++		SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops);
+ 	SET_MODULE_OWNER(dev);
+ 	return 0;
+ }
+@@ -6095,6 +6301,7 @@ qeth_init_func_level(struct qeth_card *c
+ 					QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT;
+ 	} else {
+ 		if (card->info.type == QETH_CARD_TYPE_IQD)
++		/*FIXME:why do we have same values for  dis and ena for osae??? */
+ 			card->info.func_level =
+ 				QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
+ 		else
+@@ -6124,7 +6331,7 @@ retry:
+ 		ccw_device_set_online(CARD_WDEV(card));
+ 		ccw_device_set_online(CARD_DDEV(card));
+ 	}
+-	rc = qeth_qdio_clear_card(card,card->info.type==QETH_CARD_TYPE_OSAE);
++	rc = qeth_qdio_clear_card(card,card->info.type!=QETH_CARD_TYPE_IQD);
+ 	if (rc == -ERESTARTSYS) {
+ 		QETH_DBF_TEXT(setup, 2, "break1");
+ 		return rc;
+@@ -6176,8 +6383,8 @@ retry:
+ 	card->dev = qeth_get_netdevice(card->info.type,
+ 				       card->info.link_type);
+ 	if (!card->dev){
+-		qeth_qdio_clear_card(card, card->info.type ==
+-				     QETH_CARD_TYPE_OSAE);
++		qeth_qdio_clear_card(card, card->info.type !=
++				     QETH_CARD_TYPE_IQD);
+ 		rc = -ENODEV;
+ 		QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
+ 		goto out;
+@@ -7084,6 +7291,8 @@ qeth_softsetup_card(struct qeth_card *ca
+ 			return rc;
+ 	} else
+ 		card->lan_online = 1;
++	if (card->info.type==QETH_CARD_TYPE_OSN)
++		goto out;
+ 	if (card->options.layer2) {
+ 		card->dev->features |=
+ 			NETIF_F_HW_VLAN_FILTER |
+@@ -7255,7 +7464,8 @@ qeth_stop_card(struct qeth_card *card, i
+ 	if (card->read.state == CH_STATE_UP &&
+ 	    card->write.state == CH_STATE_UP &&
+ 	    (card->state == CARD_STATE_UP)) {
+-		if(recovery_mode) {
++		if (recovery_mode && 
++		    card->info.type != QETH_CARD_TYPE_OSN) {
+ 			qeth_stop(card->dev);
+ 		} else {
+ 			rtnl_lock();
+@@ -7437,7 +7647,8 @@ qeth_start_again(struct qeth_card *card,
+ {
+ 	QETH_DBF_TEXT(setup ,2, "startag");
+ 
+-	if(recovery_mode) {
++	if (recovery_mode && 
++	    card->info.type != QETH_CARD_TYPE_OSN) {
+ 		qeth_open(card->dev);
+ 	} else {
+ 		rtnl_lock();
+@@ -7469,33 +7680,36 @@ qeth_start_again(struct qeth_card *card,
+ static void qeth_make_parameters_consistent(struct qeth_card *card)
+ {
+ 
+-        if (card->options.layer2) {
+-                if (card->info.type == QETH_CARD_TYPE_IQD) {
+-                        PRINT_ERR("Device %s does not support " \
+-                                  "layer 2 functionality. "  \
+-                                  "Ignoring layer2 option.\n",CARD_BUS_ID(card));
+-                }
+-                IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
+-                                 "Routing options are");
++	if (card->options.layer2 == 0)
++		return;
++	if (card->info.type == QETH_CARD_TYPE_OSN)
++		return;
++	if (card->info.type == QETH_CARD_TYPE_IQD) {
++       		PRINT_ERR("Device %s does not support layer 2 functionality." \
++	               	  " Ignoring layer2 option.\n",CARD_BUS_ID(card));
++       		card->options.layer2 = 0;
++		return;
++	}
++       	IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
++               	         "Routing options are");
+ #ifdef CONFIG_QETH_IPV6
+-                IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
+-                                 "Routing options are");
++       	IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
++               	         "Routing options are");
+ #endif
+-                IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
+-                                QETH_CHECKSUM_DEFAULT,
+-                                "Checksumming options are");
+-                IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
+-                                 QETH_TR_BROADCAST_ALLRINGS,
+-                                 "Broadcast mode options are");
+-                IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
+-                                 QETH_TR_MACADDR_NONCANONICAL,
+-                                 "Canonical MAC addr options are");
+-                IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
+-				 "Broadcast faking options are");
+-                IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
+-                                 DEFAULT_ADD_HHLEN,"Option add_hhlen is");
+-                IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
+-        }
++       	IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
++                       	QETH_CHECKSUM_DEFAULT,
++               	        "Checksumming options are");
++       	IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
++                       	 QETH_TR_BROADCAST_ALLRINGS,
++               	         "Broadcast mode options are");
++       	IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
++                       	 QETH_TR_MACADDR_NONCANONICAL,
++               	         "Canonical MAC addr options are");
++       	IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
++			 "Broadcast faking options are");
++       	IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
++       	                 DEFAULT_ADD_HHLEN,"Option add_hhlen is");
++        IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
+ }
+ 
+ 
+@@ -7525,8 +7739,7 @@ __qeth_set_online(struct ccwgroup_device
+ 		return -EIO;
+ 	}
+ 
+-	if (card->options.layer2)
+-		qeth_make_parameters_consistent(card);
++	qeth_make_parameters_consistent(card);
+ 
+ 	if ((rc = qeth_hardsetup_card(card))){
+ 		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
+@@ -7585,6 +7798,7 @@ qeth_set_online(struct ccwgroup_device *
+ static struct ccw_device_id qeth_ids[] = {
+ 	{CCW_DEVICE(0x1731, 0x01), driver_info:QETH_CARD_TYPE_OSAE},
+ 	{CCW_DEVICE(0x1731, 0x05), driver_info:QETH_CARD_TYPE_IQD},
++	{CCW_DEVICE(0x1731, 0x06), driver_info:QETH_CARD_TYPE_OSN},
+ 	{},
+ };
+ MODULE_DEVICE_TABLE(ccw, qeth_ids);
+@@ -8329,6 +8543,9 @@ again:
+ 	printk("qeth: removed\n");
+ }
+ 
++EXPORT_SYMBOL(qeth_osn_register);
++EXPORT_SYMBOL(qeth_osn_deregister);
++EXPORT_SYMBOL(qeth_osn_assist);
+ module_init(qeth_init);
+ module_exit(qeth_exit);
+ MODULE_AUTHOR("Frank Pavlic <pavlic at de.ibm.com>");
+diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
+--- a/drivers/s390/net/qeth_mpc.c
++++ b/drivers/s390/net/qeth_mpc.c
+@@ -11,7 +11,7 @@
+ #include <asm/cio.h>
+ #include "qeth_mpc.h"
+ 
+-const char *VERSION_QETH_MPC_C = "$Revision: 1.11 $";
++const char *VERSION_QETH_MPC_C = "$Revision: 1.12 $";
+ 
+ unsigned char IDX_ACTIVATE_READ[]={
+ 	0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
+@@ -138,7 +138,9 @@ unsigned char IPA_PDU_HEADER[]={
+ 		sizeof(struct qeth_ipa_cmd)%256,
+ 	0x00,
+ 		sizeof(struct qeth_ipa_cmd)/256,
+-		sizeof(struct qeth_ipa_cmd),0x05, 0x77,0x77,0x77,0x77,
++		sizeof(struct qeth_ipa_cmd)%256,
++	0x05,
++	0x77,0x77,0x77,0x77,
+ 	0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
+ 	0x01,0x00,
+ 		sizeof(struct qeth_ipa_cmd)/256,
+diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
+--- a/drivers/s390/net/qeth_mpc.h
++++ b/drivers/s390/net/qeth_mpc.h
+@@ -46,13 +46,16 @@ extern unsigned char IPA_PDU_HEADER[];
+ /* IP Assist related definitions                                             */
+ /*****************************************************************************/
+ #define IPA_CMD_INITIATOR_HOST  0x00
+-#define IPA_CMD_INITIATOR_HYDRA 0x01
++#define IPA_CMD_INITIATOR_OSA   0x01
++#define IPA_CMD_INITIATOR_HOST_REPLY  0x80
++#define IPA_CMD_INITIATOR_OSA_REPLY   0x81
+ #define IPA_CMD_PRIM_VERSION_NO 0x01
+ 
+ enum qeth_card_types {
+ 	QETH_CARD_TYPE_UNKNOWN = 0,
+ 	QETH_CARD_TYPE_OSAE    = 10,
+ 	QETH_CARD_TYPE_IQD     = 1234,
++	QETH_CARD_TYPE_OSN     = 11,
+ };
+ 
+ #define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18
+@@ -61,6 +64,7 @@ enum qeth_link_types {
+ 	QETH_LINK_TYPE_FAST_ETH     = 0x01,
+ 	QETH_LINK_TYPE_HSTR         = 0x02,
+ 	QETH_LINK_TYPE_GBIT_ETH     = 0x03,
++	QETH_LINK_TYPE_OSN          = 0x04,
+ 	QETH_LINK_TYPE_10GBIT_ETH   = 0x10,
+ 	QETH_LINK_TYPE_LANE_ETH100  = 0x81,
+ 	QETH_LINK_TYPE_LANE_TR      = 0x82,
+@@ -111,6 +115,9 @@ enum qeth_ipa_cmds {
+ 	IPA_CMD_DELGMAC 	      = 0x24,
+ 	IPA_CMD_SETVLAN 	      = 0x25,
+ 	IPA_CMD_DELVLAN 	      = 0x26,
++	IPA_CMD_SETCCID               = 0x41,
++	IPA_CMD_DELCCID               = 0x42,
++	IPA_CMD_MODCCID               = 0x43,
+ 	IPA_CMD_SETIP                 = 0xb1,
+ 	IPA_CMD_DELIP                 = 0xb7,
+ 	IPA_CMD_QIPASSIST             = 0xb2,
+@@ -437,8 +444,9 @@ enum qeth_ipa_arp_return_codes {
+ #define QETH_ARP_DATA_SIZE 3968
+ #define QETH_ARP_CMD_LEN (QETH_ARP_DATA_SIZE + 8)
+ /* Helper functions */
+-#define IS_IPA_REPLY(cmd) (cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST)
+-
++#define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \
++			   (cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY))
++	
+ /*****************************************************************************/
+ /* END OF   IP Assist related definitions                                    */
+ /*****************************************************************************/
+@@ -483,6 +491,7 @@ extern unsigned char ULP_ENABLE[];
+ /* Layer 2 defintions */
+ #define QETH_PROT_LAYER2 0x08
+ #define QETH_PROT_TCPIP  0x03
++#define QETH_PROT_OSN2   0x0a     
+ #define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50)
+ #define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19)
+ 
+diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
+--- a/drivers/s390/net/qeth_sys.c
++++ b/drivers/s390/net/qeth_sys.c
+@@ -1,6 +1,6 @@
+ /*
+  *
+- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.54 $)
++ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.55 $)
+  *
+  * Linux on zSeries OSA Express and HiperSockets support
+  * This file contains code related to sysfs.
+@@ -20,7 +20,7 @@
+ #include "qeth_mpc.h"
+ #include "qeth_fs.h"
+ 
+-const char *VERSION_QETH_SYS_C = "$Revision: 1.54 $";
++const char *VERSION_QETH_SYS_C = "$Revision: 1.55 $";
+ 
+ /*****************************************************************************/
+ /*                                                                           */
+@@ -937,6 +937,19 @@ static struct attribute_group qeth_devic
+ 	.attrs = (struct attribute **)qeth_device_attrs,
+ };
+ 
++static struct device_attribute * qeth_osn_device_attrs[] = {
++	&dev_attr_state,
++	&dev_attr_chpid,
++	&dev_attr_if_name,
++	&dev_attr_card_type,
++	&dev_attr_buffer_count,
++	&dev_attr_recover,
++	NULL,
++};
++
++static struct attribute_group qeth_osn_device_attr_group = {
++	.attrs = (struct attribute **)qeth_osn_device_attrs,
++};
+ 
+ #define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store)			     \
+ struct device_attribute dev_attr_##_id = {				     \
+@@ -1667,7 +1680,12 @@ int
+ qeth_create_device_attributes(struct device *dev)
+ {
+ 	int ret;
++	struct qeth_card *card = dev->driver_data;
+ 
++	if (card->info.type == QETH_CARD_TYPE_OSN)
++		return sysfs_create_group(&dev->kobj,
++					  &qeth_osn_device_attr_group);
++   	
+ 	if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group)))
+ 		return ret;
+ 	if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group))){
+@@ -1693,6 +1711,12 @@ qeth_create_device_attributes(struct dev
+ void
+ qeth_remove_device_attributes(struct device *dev)
+ {
++	struct qeth_card *card = dev->driver_data;
++
++	if (card->info.type == QETH_CARD_TYPE_OSN)
++		return sysfs_remove_group(&dev->kobj,
++					  &qeth_osn_device_attr_group);
++		      
+ 	sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
+ 	sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
+ 	sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
+diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
+--- a/drivers/scsi/Kconfig
++++ b/drivers/scsi/Kconfig
+@@ -489,11 +489,11 @@ config SCSI_SATA_NV
+ 
+ 	  If unsure, say N.
+ 
+-config SCSI_SATA_PROMISE
+-	tristate "Promise SATA TX2/TX4 support"
++config SCSI_PDC_ADMA
++	tristate "Pacific Digital ADMA support"
+ 	depends on SCSI_SATA && PCI
+ 	help
+-	  This option enables support for Promise Serial ATA TX2/TX4.
++	  This option enables support for Pacific Digital ADMA controllers
+ 
+ 	  If unsure, say N.
+ 
+@@ -505,6 +505,14 @@ config SCSI_SATA_QSTOR
+ 
+ 	  If unsure, say N.
+ 
++config SCSI_SATA_PROMISE
++	tristate "Promise SATA TX2/TX4 support"
++	depends on SCSI_SATA && PCI
++	help
++	  This option enables support for Promise Serial ATA TX2/TX4.
++
++	  If unsure, say N.
++
+ config SCSI_SATA_SX4
+ 	tristate "Promise SATA SX4 support"
+ 	depends on SCSI_SATA && PCI && EXPERIMENTAL
+@@ -521,6 +529,14 @@ config SCSI_SATA_SIL
+ 
+ 	  If unsure, say N.
+ 
++config SCSI_SATA_SIL24
++	tristate "Silicon Image 3124/3132 SATA support"
++	depends on SCSI_SATA && PCI && EXPERIMENTAL
++	help
++	  This option enables support for Silicon Image 3124/3132 Serial ATA.
++
++	  If unsure, say N.
++
+ config SCSI_SATA_SIS
+ 	tristate "SiS 964/180 SATA support"
+ 	depends on SCSI_SATA && PCI && EXPERIMENTAL
+diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
+--- a/drivers/scsi/Makefile
++++ b/drivers/scsi/Makefile
+@@ -130,6 +130,7 @@ obj-$(CONFIG_SCSI_ATA_PIIX)	+= libata.o 
+ obj-$(CONFIG_SCSI_SATA_PROMISE)	+= libata.o sata_promise.o
+ obj-$(CONFIG_SCSI_SATA_QSTOR)	+= libata.o sata_qstor.o
+ obj-$(CONFIG_SCSI_SATA_SIL)	+= libata.o sata_sil.o
++obj-$(CONFIG_SCSI_SATA_SIL24)	+= libata.o sata_sil24.o
+ obj-$(CONFIG_SCSI_SATA_VIA)	+= libata.o sata_via.o
+ obj-$(CONFIG_SCSI_SATA_VITESSE)	+= libata.o sata_vsc.o
+ obj-$(CONFIG_SCSI_SATA_SIS)	+= libata.o sata_sis.o
+@@ -137,6 +138,7 @@ obj-$(CONFIG_SCSI_SATA_SX4)	+= libata.o 
+ obj-$(CONFIG_SCSI_SATA_NV)	+= libata.o sata_nv.o
+ obj-$(CONFIG_SCSI_SATA_ULI)	+= libata.o sata_uli.o
+ obj-$(CONFIG_SCSI_SATA_MV)	+= libata.o sata_mv.o
++obj-$(CONFIG_SCSI_PDC_ADMA)	+= libata.o pdc_adma.o
+ 
+ obj-$(CONFIG_ARM)		+= arm/
+ 
+diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
+--- a/drivers/scsi/ahci.c
++++ b/drivers/scsi/ahci.c
+@@ -41,6 +41,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
+ #include <linux/dma-mapping.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -192,7 +193,6 @@ static void ahci_port_stop(struct ata_po
+ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+ static void ahci_qc_prep(struct ata_queued_cmd *qc);
+ static u8 ahci_check_status(struct ata_port *ap);
+-static u8 ahci_check_err(struct ata_port *ap);
+ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+ static void ahci_remove_one (struct pci_dev *pdev);
+ 
+@@ -216,12 +216,11 @@ static Scsi_Host_Template ahci_sht = {
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations ahci_ops = {
++static const struct ata_port_operations ahci_ops = {
+ 	.port_disable		= ata_port_disable,
+ 
+ 	.check_status		= ahci_check_status,
+ 	.check_altstatus	= ahci_check_status,
+-	.check_err		= ahci_check_err,
+ 	.dev_select		= ata_noop_dev_select,
+ 
+ 	.tf_read		= ahci_tf_read,
+@@ -407,7 +406,7 @@ static u32 ahci_scr_read (struct ata_por
+ 		return 0xffffffffU;
+ 	}
+ 
+-	return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
++	return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+ 
+ 
+@@ -425,7 +424,7 @@ static void ahci_scr_write (struct ata_p
+ 		return;
+ 	}
+ 
+-	writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
++	writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+ 
+ static void ahci_phy_reset(struct ata_port *ap)
+@@ -453,18 +452,11 @@ static void ahci_phy_reset(struct ata_po
+ 
+ static u8 ahci_check_status(struct ata_port *ap)
+ {
+-	void *mmio = (void *) ap->ioaddr.cmd_addr;
++	void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ 
+ 	return readl(mmio + PORT_TFDATA) & 0xFF;
+ }
+ 
+-static u8 ahci_check_err(struct ata_port *ap)
+-{
+-	void *mmio = (void *) ap->ioaddr.cmd_addr;
+-
+-	return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF;
+-}
+-
+ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ 	struct ahci_port_priv *pp = ap->private_data;
+@@ -609,7 +601,7 @@ static void ahci_eng_timeout(struct ata_
+ 	 	 * not being called from the SCSI EH.
+ 	 	 */
+ 		qc->scsidone = scsi_finish_command;
+-		ata_qc_complete(qc, ATA_ERR);
++		ata_qc_complete(qc, AC_ERR_OTHER);
+ 	}
+ 
+ 	spin_unlock_irqrestore(&host_set->lock, flags);
+@@ -638,7 +630,7 @@ static inline int ahci_host_intr(struct 
+ 	if (status & PORT_IRQ_FATAL) {
+ 		ahci_intr_error(ap, status);
+ 		if (qc)
+-			ata_qc_complete(qc, ATA_ERR);
++			ata_qc_complete(qc, AC_ERR_OTHER);
+ 	}
+ 
+ 	return 1;
+@@ -672,17 +664,35 @@ static irqreturn_t ahci_interrupt (int i
+ 
+         for (i = 0; i < host_set->n_ports; i++) {
+ 		struct ata_port *ap;
+-		u32 tmp;
+ 
+-		VPRINTK("port %u\n", i);
++		if (!(irq_stat & (1 << i)))
++			continue;
++
+ 		ap = host_set->ports[i];
+-		tmp = irq_stat & (1 << i);
+-		if (tmp && ap) {
++		if (ap) {
+ 			struct ata_queued_cmd *qc;
+ 			qc = ata_qc_from_tag(ap, ap->active_tag);
+-			if (ahci_host_intr(ap, qc))
+-				irq_ack |= (1 << i);
++			if (!ahci_host_intr(ap, qc))
++				if (ata_ratelimit()) {
++					struct pci_dev *pdev =
++						to_pci_dev(ap->host_set->dev);
++					dev_printk(KERN_WARNING, &pdev->dev,
++					  "unhandled interrupt on port %u\n",
++					  i);
++				}
++
++			VPRINTK("port %u\n", i);
++		} else {
++			VPRINTK("port %u (no irq)\n", i);
++			if (ata_ratelimit()) {
++				struct pci_dev *pdev =
++					to_pci_dev(ap->host_set->dev);
++				dev_printk(KERN_WARNING, &pdev->dev,
++					"interrupt on disabled port %u\n", i);
++			}
+ 		}
++
++		irq_ack |= (1 << i);
+ 	}
+ 
+ 	if (irq_ack) {
+@@ -750,8 +760,8 @@ static int ahci_host_init(struct ata_pro
+ 
+ 	tmp = readl(mmio + HOST_CTL);
+ 	if (tmp & HOST_RESET) {
+-		printk(KERN_ERR DRV_NAME "(%s): controller reset failed (0x%x)\n",
+-			pci_name(pdev), tmp);
++		dev_printk(KERN_ERR, &pdev->dev,
++			   "controller reset failed (0x%x)\n", tmp);
+ 		return -EIO;
+ 	}
+ 
+@@ -779,22 +789,22 @@ static int ahci_host_init(struct ata_pro
+ 		if (rc) {
+ 			rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ 			if (rc) {
+-				printk(KERN_ERR DRV_NAME "(%s): 64-bit DMA enable failed\n",
+-					pci_name(pdev));
++				dev_printk(KERN_ERR, &pdev->dev,
++					   "64-bit DMA enable failed\n");
+ 				return rc;
+ 			}
+ 		}
+ 	} else {
+ 		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ 		if (rc) {
+-			printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
+-				pci_name(pdev));
++			dev_printk(KERN_ERR, &pdev->dev,
++				   "32-bit DMA enable failed\n");
+ 			return rc;
+ 		}
+ 		rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ 		if (rc) {
+-			printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
+-				pci_name(pdev));
++			dev_printk(KERN_ERR, &pdev->dev,
++				   "32-bit consistent DMA enable failed\n");
+ 			return rc;
+ 		}
+ 	}
+@@ -897,10 +907,10 @@ static void ahci_print_info(struct ata_p
+ 	else
+ 		scc_s = "unknown";
+ 
+-	printk(KERN_INFO DRV_NAME "(%s) AHCI %02x%02x.%02x%02x "
++	dev_printk(KERN_INFO, &pdev->dev,
++		"AHCI %02x%02x.%02x%02x "
+ 		"%u slots %u ports %s Gbps 0x%x impl %s mode\n"
+ 	       	,
+-	       	pci_name(pdev),
+ 
+ 	       	(vers >> 24) & 0xff,
+ 	       	(vers >> 16) & 0xff,
+@@ -913,11 +923,11 @@ static void ahci_print_info(struct ata_p
+ 		impl,
+ 		scc_s);
+ 
+-	printk(KERN_INFO DRV_NAME "(%s) flags: "
++	dev_printk(KERN_INFO, &pdev->dev,
++		"flags: "
+ 	       	"%s%s%s%s%s%s"
+ 	       	"%s%s%s%s%s%s%s\n"
+ 	       	,
+-	       	pci_name(pdev),
+ 
+ 		cap & (1 << 31) ? "64bit " : "",
+ 		cap & (1 << 30) ? "ncq " : "",
+@@ -950,7 +960,7 @@ static int ahci_init_one (struct pci_dev
+ 	VPRINTK("ENTER\n");
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+diff --git a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h
+--- a/drivers/scsi/arm/scsi.h
++++ b/drivers/scsi/arm/scsi.h
+@@ -10,6 +10,8 @@
+  *  Commonly used scsi driver functions.
+  */
+ 
++#include <linux/scatterlist.h>
++
+ #define BELT_AND_BRACES
+ 
+ /*
+@@ -22,9 +24,7 @@ static inline int copy_SCp_to_sg(struct 
+ 
+ 	BUG_ON(bufs + 1 > max);
+ 
+-	sg->page   = virt_to_page(SCp->ptr);
+-	sg->offset = offset_in_page(SCp->ptr);
+-	sg->length = SCp->this_residual;
++	sg_set_buf(sg, SCp->ptr, SCp->this_residual);
+ 
+ 	if (bufs)
+ 		memcpy(sg + 1, SCp->buffer + 1,
+diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
+--- a/drivers/scsi/ata_piix.c
++++ b/drivers/scsi/ata_piix.c
+@@ -45,6 +45,7 @@
+ #include <linux/init.h>
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -147,7 +148,7 @@ static Scsi_Host_Template piix_sht = {
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations piix_pata_ops = {
++static const struct ata_port_operations piix_pata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.set_piomode		= piix_set_piomode,
+ 	.set_dmamode		= piix_set_dmamode,
+@@ -177,7 +178,7 @@ static struct ata_port_operations piix_p
+ 	.host_stop		= ata_host_stop,
+ };
+ 
+-static struct ata_port_operations piix_sata_ops = {
++static const struct ata_port_operations piix_sata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 
+ 	.tf_load		= ata_tf_load,
+@@ -621,18 +622,19 @@ static int piix_init_one (struct pci_dev
+ {
+ 	static int printed_version;
+ 	struct ata_port_info *port_info[2];
+-	unsigned int combined = 0, n_ports = 1;
++	unsigned int combined = 0;
+ 	unsigned int pata_chan = 0, sata_chan = 0;
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev,
++			   "version " DRV_VERSION "\n");
+ 
+ 	/* no hotplugging support (FIXME) */
+ 	if (!in_module_init)
+ 		return -ENODEV;
+ 
+ 	port_info[0] = &piix_port_info[ent->driver_data];
+-	port_info[1] = NULL;
++	port_info[1] = &piix_port_info[ent->driver_data];
+ 
+ 	if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
+ 		u8 tmp;
+@@ -670,12 +672,13 @@ static int piix_init_one (struct pci_dev
+ 		port_info[sata_chan] = &piix_port_info[ent->driver_data];
+ 		port_info[sata_chan]->host_flags |= ATA_FLAG_SLAVE_POSS;
+ 		port_info[pata_chan] = &piix_port_info[ich5_pata];
+-		n_ports++;
+ 
+-		printk(KERN_WARNING DRV_NAME ": combined mode detected\n");
++		dev_printk(KERN_WARNING, &pdev->dev,
++			   "combined mode detected (p=%u, s=%u)\n",
++			   pata_chan, sata_chan);
+ 	}
+ 
+-	return ata_pci_init_one(pdev, port_info, n_ports);
++	return ata_pci_init_one(pdev, port_info, 2);
+ }
+ 
+ static int __init piix_init(void)
+diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
+--- a/drivers/scsi/ch.c
++++ b/drivers/scsi/ch.c
+@@ -936,7 +936,7 @@ static int ch_probe(struct device *dev)
+ 	if (init)
+ 		ch_init_elem(ch);
+ 
+-	class_device_create(ch_sysfs_class,
++	class_device_create(ch_sysfs_class, NULL,
+ 			    MKDEV(SCSI_CHANGER_MAJOR,ch->minor),
+ 			    dev, "s%s", ch->name);
+ 
+diff --git a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c
+--- a/drivers/scsi/dec_esp.c
++++ b/drivers/scsi/dec_esp.c
+@@ -228,7 +228,7 @@ static int dec_esp_detect(Scsi_Host_Temp
+ 			mem_start = get_tc_base_addr(slot);
+ 
+ 			/* Store base addr into esp struct */
+-			esp->slot = PHYSADDR(mem_start);
++			esp->slot = CPHYSADDR(mem_start);
+ 
+ 			esp->dregs = 0;
+ 			esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG);
+diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
+--- a/drivers/scsi/eata.c
++++ b/drivers/scsi/eata.c
+@@ -1357,7 +1357,7 @@ static int port_detect(unsigned long por
+ 
+ 	for (i = 0; i < shost->can_queue; i++) {
+ 		size_t sz = shost->sg_tablesize *sizeof(struct sg_list);
+-		unsigned int gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
++		gfp_t gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
+ 		ha->cp[i].sglist = kmalloc(sz, gfp_mask);
+ 		if (!ha->cp[i].sglist) {
+ 			printk
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -30,6 +30,7 @@
+ #include <linux/init.h>
+ #include <linux/completion.h>
+ #include <linux/transport_class.h>
++#include <linux/platform_device.h>
+ 
+ #include <scsi/scsi_device.h>
+ #include <scsi/scsi_host.h>
+@@ -287,7 +288,8 @@ static void scsi_host_dev_release(struct
+ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
+ {
+ 	struct Scsi_Host *shost;
+-	int gfp_mask = GFP_KERNEL, rval;
++	gfp_t gfp_mask = GFP_KERNEL;
++	int rval;
+ 
+ 	if (sht->unchecked_isa_dma && privsize)
+ 		gfp_mask |= __GFP_DMA;
+diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
+--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
++++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
+@@ -1543,13 +1543,16 @@ static struct vio_device_id ibmvscsi_dev
+ 	{"vscsi", "IBM,v-scsi"},
+ 	{ "", "" }
+ };
+-
+ MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);
++
+ static struct vio_driver ibmvscsi_driver = {
+-	.name = "ibmvscsi",
+ 	.id_table = ibmvscsi_device_table,
+ 	.probe = ibmvscsi_probe,
+-	.remove = ibmvscsi_remove
++	.remove = ibmvscsi_remove,
++	.driver = {
++		.name = "ibmvscsi",
++		.owner = THIS_MODULE,
++	}
+ };
+ 
+ int __init ibmvscsi_module_init(void)
+diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
+--- a/drivers/scsi/ide-scsi.c
++++ b/drivers/scsi/ide-scsi.c
+@@ -184,13 +184,16 @@ static void idescsi_input_buffers (ide_d
+ 			unsigned long flags;
+ 
+ 			local_irq_save(flags);
+-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
+-			drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
++			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
++					pc->sg->offset;
++			drive->hwif->atapi_input_bytes(drive,
++						buf + pc->b_count, count);
+ 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
+ 			local_irq_restore(flags);
+ 		} else {
+ 			buf = page_address(pc->sg->page) + pc->sg->offset;
+-			drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
++			drive->hwif->atapi_input_bytes(drive,
++						buf + pc->b_count, count);
+ 		}
+ 		bcount -= count; pc->b_count += count;
+ 		if (pc->b_count == pc->sg->length) {
+@@ -216,13 +219,16 @@ static void idescsi_output_buffers (ide_
+ 			unsigned long flags;
+ 
+ 			local_irq_save(flags);
+-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
+-			drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
++			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
++						pc->sg->offset;
++			drive->hwif->atapi_output_bytes(drive,
++						buf + pc->b_count, count);
+ 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
+ 			local_irq_restore(flags);
+ 		} else {
+ 			buf = page_address(pc->sg->page) + pc->sg->offset;
+-			drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
++			drive->hwif->atapi_output_bytes(drive,
++						buf + pc->b_count, count);
+ 		}
+ 		bcount -= count; pc->b_count += count;
+ 		if (pc->b_count == pc->sg->length) {
+diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -4944,6 +4944,7 @@ static int ipr_reset_restore_cfg_space(s
+ 	int rc;
+ 
+ 	ENTER;
++	pci_unblock_user_cfg_access(ioa_cfg->pdev);
+ 	rc = pci_restore_state(ioa_cfg->pdev);
+ 
+ 	if (rc != PCIBIOS_SUCCESSFUL) {
+@@ -4998,6 +4999,7 @@ static int ipr_reset_start_bist(struct i
+ 	int rc;
+ 
+ 	ENTER;
++	pci_block_user_cfg_access(ioa_cfg->pdev);
+ 	rc = pci_write_config_byte(ioa_cfg->pdev, PCI_BIST, PCI_BIST_START);
+ 
+ 	if (rc != PCIBIOS_SUCCESSFUL) {
+diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
+--- a/drivers/scsi/lasi700.c
++++ b/drivers/scsi/lasi700.c
+@@ -98,7 +98,7 @@ MODULE_DEVICE_TABLE(parisc, lasi700_ids)
+ static int __init
+ lasi700_probe(struct parisc_device *dev)
+ {
+-	unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET;
++	unsigned long base = dev->hpa.start + LASI_SCSI_CORE_OFFSET;
+ 	struct NCR_700_Host_Parameters *hostdata;
+ 	struct Scsi_Host *host;
+ 
+@@ -125,8 +125,6 @@ lasi700_probe(struct parisc_device *dev)
+ 		hostdata->dmode_extra = DMODE_FC2;
+ 	}
+ 
+-	NCR_700_set_mem_mapped(hostdata);
+-
+ 	host = NCR_700_detect(&lasi700_template, hostdata, &dev->dev);
+ 	if (!host)
+ 		goto out_kfree;
+@@ -168,7 +166,7 @@ lasi700_driver_remove(struct parisc_devi
+ }
+ 
+ static struct parisc_driver lasi700_driver = {
+-	.name =		"Lasi SCSI",
++	.name =		"lasi_scsi",
+ 	.id_table =	lasi700_ids,
+ 	.probe =	lasi700_probe,
+ 	.remove =	__devexit_p(lasi700_driver_remove),
+diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
+--- a/drivers/scsi/libata-core.c
++++ b/drivers/scsi/libata-core.c
+@@ -48,6 +48,8 @@
+ #include <linux/completion.h>
+ #include <linux/suspend.h>
+ #include <linux/workqueue.h>
++#include <linux/jiffies.h>
++#include <linux/scatterlist.h>
+ #include <scsi/scsi.h>
+ #include "scsi.h"
+ #include "scsi_priv.h"
+@@ -62,14 +64,15 @@
+ static unsigned int ata_busy_sleep (struct ata_port *ap,
+ 				    unsigned long tmout_pat,
+ 			    	    unsigned long tmout);
++static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev);
++static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev);
+ static void ata_set_mode(struct ata_port *ap);
+ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
+-static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift);
++static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift);
+ static int fgb(u32 bitmap);
+-static int ata_choose_xfer_mode(struct ata_port *ap,
++static int ata_choose_xfer_mode(const struct ata_port *ap,
+ 				u8 *xfer_mode_out,
+ 				unsigned int *xfer_shift_out);
+-static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
+ static void __ata_qc_complete(struct ata_queued_cmd *qc);
+ 
+ static unsigned int ata_unique_id = 1;
+@@ -85,7 +88,7 @@ MODULE_LICENSE("GPL");
+ MODULE_VERSION(DRV_VERSION);
+ 
+ /**
+- *	ata_tf_load - send taskfile registers to host controller
++ *	ata_tf_load_pio - send taskfile registers to host controller
+  *	@ap: Port to which output is sent
+  *	@tf: ATA taskfile register set
+  *
+@@ -95,7 +98,7 @@ MODULE_VERSION(DRV_VERSION);
+  *	Inherited from caller.
+  */
+ 
+-static void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+@@ -153,7 +156,7 @@ static void ata_tf_load_pio(struct ata_p
+  *	Inherited from caller.
+  */
+ 
+-static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+@@ -222,7 +225,7 @@ static void ata_tf_load_mmio(struct ata_
+  *	LOCKING:
+  *	Inherited from caller.
+  */
+-void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
++void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	if (ap->flags & ATA_FLAG_MMIO)
+ 		ata_tf_load_mmio(ap, tf);
+@@ -242,7 +245,7 @@ void ata_tf_load(struct ata_port *ap, st
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-static void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
+ 
+@@ -263,7 +266,7 @@ static void ata_exec_command_pio(struct 
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
++static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
+ 
+@@ -283,7 +286,7 @@ static void ata_exec_command_mmio(struct
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+  */
+-void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
++void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	if (ap->flags & ATA_FLAG_MMIO)
+ 		ata_exec_command_mmio(ap, tf);
+@@ -292,28 +295,6 @@ void ata_exec_command(struct ata_port *a
+ }
+ 
+ /**
+- *	ata_exec - issue ATA command to host controller
+- *	@ap: port to which command is being issued
+- *	@tf: ATA taskfile register set
+- *
+- *	Issues PIO/MMIO write to ATA command register, with proper
+- *	synchronization with interrupt handler / other threads.
+- *
+- *	LOCKING:
+- *	Obtains host_set lock.
+- */
+-
+-static inline void ata_exec(struct ata_port *ap, struct ata_taskfile *tf)
+-{
+-	unsigned long flags;
+-
+-	DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
+-	spin_lock_irqsave(&ap->host_set->lock, flags);
+-	ap->ops->exec_command(ap, tf);
+-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+-}
+-
+-/**
+  *	ata_tf_to_host - issue ATA taskfile to host controller
+  *	@ap: port to which command is being issued
+  *	@tf: ATA taskfile register set
+@@ -323,30 +304,11 @@ static inline void ata_exec(struct ata_p
+  *	other threads.
+  *
+  *	LOCKING:
+- *	Obtains host_set lock.
+- */
+-
+-static void ata_tf_to_host(struct ata_port *ap, struct ata_taskfile *tf)
+-{
+-	ap->ops->tf_load(ap, tf);
+-
+-	ata_exec(ap, tf);
+-}
+-
+-/**
+- *	ata_tf_to_host_nolock - issue ATA taskfile to host controller
+- *	@ap: port to which command is being issued
+- *	@tf: ATA taskfile register set
+- *
+- *	Issues ATA taskfile register set to ATA host controller,
+- *	with proper synchronization with interrupt handler and
+- *	other threads.
+- *
+- *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+  */
+ 
+-void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf)
++static inline void ata_tf_to_host(struct ata_port *ap,
++				  const struct ata_taskfile *tf)
+ {
+ 	ap->ops->tf_load(ap, tf);
+ 	ap->ops->exec_command(ap, tf);
+@@ -368,6 +330,8 @@ static void ata_tf_read_pio(struct ata_p
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 
++	tf->command = ata_check_status(ap);
++	tf->feature = inb(ioaddr->error_addr);
+ 	tf->nsect = inb(ioaddr->nsect_addr);
+ 	tf->lbal = inb(ioaddr->lbal_addr);
+ 	tf->lbam = inb(ioaddr->lbam_addr);
+@@ -400,6 +364,8 @@ static void ata_tf_read_mmio(struct ata_
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 
++	tf->command = ata_check_status(ap);
++	tf->feature = readb((void __iomem *)ioaddr->error_addr);
+ 	tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
+ 	tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
+ 	tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
+@@ -520,30 +486,6 @@ u8 ata_altstatus(struct ata_port *ap)
+ 
+ 
+ /**
+- *	ata_chk_err - Read device error reg
+- *	@ap: port where the device is
+- *
+- *	Reads ATA taskfile error register for
+- *	currently-selected device and return its value.
+- *
+- *	Note: may NOT be used as the check_err() entry in
+- *	ata_port_operations.
+- *
+- *	LOCKING:
+- *	Inherited from caller.
+- */
+-u8 ata_chk_err(struct ata_port *ap)
+-{
+-	if (ap->ops->check_err)
+-		return ap->ops->check_err(ap);
+-
+-	if (ap->flags & ATA_FLAG_MMIO) {
+-		return readb((void __iomem *) ap->ioaddr.error_addr);
+-	}
+-	return inb(ap->ioaddr.error_addr);
+-}
+-
+-/**
+  *	ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
+  *	@tf: Taskfile to convert
+  *	@fis: Buffer into which data will output
+@@ -556,7 +498,7 @@ u8 ata_chk_err(struct ata_port *ap)
+  *	Inherited from caller.
+  */
+ 
+-void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp)
++void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp)
+ {
+ 	fis[0] = 0x27;	/* Register - Host to Device FIS */
+ 	fis[1] = (pmp & 0xf) | (1 << 7); /* Port multiplier number,
+@@ -597,7 +539,7 @@ void ata_tf_to_fis(struct ata_taskfile *
+  *	Inherited from caller.
+  */
+ 
+-void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf)
++void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
+ {
+ 	tf->command	= fis[2];	/* status */
+ 	tf->feature	= fis[3];	/* error */
+@@ -615,79 +557,53 @@ void ata_tf_from_fis(u8 *fis, struct ata
+ 	tf->hob_nsect	= fis[13];
+ }
+ 
+-/**
+- *	ata_prot_to_cmd - determine which read/write opcodes to use
+- *	@protocol: ATA_PROT_xxx taskfile protocol
+- *	@lba48: true is lba48 is present
+- *
+- *	Given necessary input, determine which read/write commands
+- *	to use to transfer data.
+- *
+- *	LOCKING:
+- *	None.
+- */
+-static int ata_prot_to_cmd(int protocol, int lba48)
+-{
+-	int rcmd = 0, wcmd = 0;
+-
+-	switch (protocol) {
+-	case ATA_PROT_PIO:
+-		if (lba48) {
+-			rcmd = ATA_CMD_PIO_READ_EXT;
+-			wcmd = ATA_CMD_PIO_WRITE_EXT;
+-		} else {
+-			rcmd = ATA_CMD_PIO_READ;
+-			wcmd = ATA_CMD_PIO_WRITE;
+-		}
+-		break;
+-
+-	case ATA_PROT_DMA:
+-		if (lba48) {
+-			rcmd = ATA_CMD_READ_EXT;
+-			wcmd = ATA_CMD_WRITE_EXT;
+-		} else {
+-			rcmd = ATA_CMD_READ;
+-			wcmd = ATA_CMD_WRITE;
+-		}
+-		break;
+-
+-	default:
+-		return -1;
+-	}
+-
+-	return rcmd | (wcmd << 8);
+-}
++static const u8 ata_rw_cmds[] = {
++	/* pio multi */
++	ATA_CMD_READ_MULTI,
++	ATA_CMD_WRITE_MULTI,
++	ATA_CMD_READ_MULTI_EXT,
++	ATA_CMD_WRITE_MULTI_EXT,
++	/* pio */
++	ATA_CMD_PIO_READ,
++	ATA_CMD_PIO_WRITE,
++	ATA_CMD_PIO_READ_EXT,
++	ATA_CMD_PIO_WRITE_EXT,
++	/* dma */
++	ATA_CMD_READ,
++	ATA_CMD_WRITE,
++	ATA_CMD_READ_EXT,
++	ATA_CMD_WRITE_EXT
++};
+ 
+ /**
+- *	ata_dev_set_protocol - set taskfile protocol and r/w commands
+- *	@dev: device to examine and configure
++ *	ata_rwcmd_protocol - set taskfile r/w commands and protocol
++ *	@qc: command to examine and configure
+  *
+- *	Examine the device configuration, after we have
+- *	read the identify-device page and configured the
+- *	data transfer mode.  Set internal state related to
+- *	the ATA taskfile protocol (pio, pio mult, dma, etc.)
+- *	and calculate the proper read/write commands to use.
++ *	Examine the device configuration and tf->flags to calculate 
++ *	the proper read/write commands and protocol to use.
+  *
+  *	LOCKING:
+  *	caller.
+  */
+-static void ata_dev_set_protocol(struct ata_device *dev)
++void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
+ {
+-	int pio = (dev->flags & ATA_DFLAG_PIO);
+-	int lba48 = (dev->flags & ATA_DFLAG_LBA48);
+-	int proto, cmd;
+-
+-	if (pio)
+-		proto = dev->xfer_protocol = ATA_PROT_PIO;
+-	else
+-		proto = dev->xfer_protocol = ATA_PROT_DMA;
++	struct ata_taskfile *tf = &qc->tf;
++	struct ata_device *dev = qc->dev;
+ 
+-	cmd = ata_prot_to_cmd(proto, lba48);
+-	if (cmd < 0)
+-		BUG();
++	int index, lba48, write;
++ 
++	lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
++	write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
++
++	if (dev->flags & ATA_DFLAG_PIO) {
++		tf->protocol = ATA_PROT_PIO;
++		index = dev->multi_count ? 0 : 4;
++	} else {
++		tf->protocol = ATA_PROT_DMA;
++		index = 8;
++	}
+ 
+-	dev->read_cmd = cmd & 0xff;
+-	dev->write_cmd = (cmd >> 8) & 0xff;
++	tf->command = ata_rw_cmds[index + lba48 + write];
+ }
+ 
+ static const char * xfer_mode_str[] = {
+@@ -869,7 +785,7 @@ static unsigned int ata_devchk(struct at
+  *	the event of failure.
+  */
+ 
+-unsigned int ata_dev_classify(struct ata_taskfile *tf)
++unsigned int ata_dev_classify(const struct ata_taskfile *tf)
+ {
+ 	/* Apple's open source Darwin code hints that some devices only
+ 	 * put a proper signature into the LBA mid/high registers,
+@@ -921,8 +837,8 @@ static u8 ata_dev_try_classify(struct at
+ 
+ 	memset(&tf, 0, sizeof(tf));
+ 
+-	err = ata_chk_err(ap);
+ 	ap->ops->tf_read(ap, &tf);
++	err = tf.feature;
+ 
+ 	dev->class = ATA_DEV_NONE;
+ 
+@@ -961,7 +877,7 @@ static u8 ata_dev_try_classify(struct at
+  *	caller.
+  */
+ 
+-void ata_dev_id_string(u16 *id, unsigned char *s,
++void ata_dev_id_string(const u16 *id, unsigned char *s,
+ 		       unsigned int ofs, unsigned int len)
+ {
+ 	unsigned int c;
+@@ -1078,7 +994,7 @@ void ata_dev_select(struct ata_port *ap,
+  *	caller.
+  */
+ 
+-static inline void ata_dump_id(struct ata_device *dev)
++static inline void ata_dump_id(const struct ata_device *dev)
+ {
+ 	DPRINTK("49==0x%04x  "
+ 		"53==0x%04x  "
+@@ -1106,6 +1022,31 @@ static inline void ata_dump_id(struct at
+ 		dev->id[93]);
+ }
+ 
++/*
++ *	Compute the PIO modes available for this device. This is not as
++ *	trivial as it seems if we must consider early devices correctly.
++ *
++ *	FIXME: pre IDE drive timing (do we care ?). 
++ */
++
++static unsigned int ata_pio_modes(const struct ata_device *adev)
++{
++	u16 modes;
++
++	/* Usual case. Word 53 indicates word 88 is valid */
++	if (adev->id[ATA_ID_FIELD_VALID] & (1 << 2)) {
++		modes = adev->id[ATA_ID_PIO_MODES] & 0x03;
++		modes <<= 3;
++		modes |= 0x7;
++		return modes;
++	}
++
++	/* If word 88 isn't valid then Word 51 holds the PIO timing number
++	   for the maximum. Turn it into a mask and return it */
++	modes = (2 << (adev->id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
++	return modes;
++}
++
+ /**
+  *	ata_dev_identify - obtain IDENTIFY x DEVICE page
+  *	@ap: port on which device we wish to probe resides
+@@ -1131,10 +1072,9 @@ static inline void ata_dump_id(struct at
+ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
+ {
+ 	struct ata_device *dev = &ap->device[device];
+-	unsigned int i;
++	unsigned int major_version;
+ 	u16 tmp;
+ 	unsigned long xfer_modes;
+-	u8 status;
+ 	unsigned int using_edd;
+ 	DECLARE_COMPLETION(wait);
+ 	struct ata_queued_cmd *qc;
+@@ -1188,8 +1128,11 @@ retry:
+ 	else
+ 		wait_for_completion(&wait);
+ 
+-	status = ata_chk_status(ap);
+-	if (status & ATA_ERR) {
++	spin_lock_irqsave(&ap->host_set->lock, flags);
++	ap->ops->tf_read(ap, &qc->tf);
++	spin_unlock_irqrestore(&ap->host_set->lock, flags);
++
++	if (qc->tf.command & ATA_ERR) {
+ 		/*
+ 		 * arg!  EDD works for all test cases, but seems to return
+ 		 * the ATA signature for some ATAPI devices.  Until the
+@@ -1202,7 +1145,7 @@ retry:
+ 		 * to have this problem.
+ 		 */
+ 		if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) {
+-			u8 err = ata_chk_err(ap);
++			u8 err = qc->tf.feature;
+ 			if (err & ATA_ABORTED) {
+ 				dev->class = ATA_DEV_ATAPI;
+ 				qc->cursg = 0;
+@@ -1229,9 +1172,9 @@ retry:
+ 	 * common ATA, ATAPI feature tests
+ 	 */
+ 
+-	/* we require LBA and DMA support (bits 8 & 9 of word 49) */
+-	if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) {
+-		printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id);
++	/* we require DMA support (bits 8 of word 49) */
++	if (!ata_id_has_dma(dev->id)) {
++		printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
+ 		goto err_out_nosup;
+ 	}
+ 
+@@ -1239,10 +1182,8 @@ retry:
+ 	xfer_modes = dev->id[ATA_ID_UDMA_MODES];
+ 	if (!xfer_modes)
+ 		xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA;
+-	if (!xfer_modes) {
+-		xfer_modes = (dev->id[ATA_ID_PIO_MODES]) << (ATA_SHIFT_PIO + 3);
+-		xfer_modes |= (0x7 << ATA_SHIFT_PIO);
+-	}
++	if (!xfer_modes)
++		xfer_modes = ata_pio_modes(dev);
+ 
+ 	ata_dump_id(dev);
+ 
+@@ -1251,32 +1192,75 @@ retry:
+ 		if (!ata_id_is_ata(dev->id))	/* sanity check */
+ 			goto err_out_nosup;
+ 
++		/* get major version */
+ 		tmp = dev->id[ATA_ID_MAJOR_VER];
+-		for (i = 14; i >= 1; i--)
+-			if (tmp & (1 << i))
++		for (major_version = 14; major_version >= 1; major_version--)
++			if (tmp & (1 << major_version))
+ 				break;
+ 
+-		/* we require at least ATA-3 */
+-		if (i < 3) {
+-			printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id);
+-			goto err_out_nosup;
++		/*
++		 * The exact sequence expected by certain pre-ATA4 drives is:
++		 * SRST RESET
++		 * IDENTIFY
++		 * INITIALIZE DEVICE PARAMETERS
++		 * anything else..
++		 * Some drives were very specific about that exact sequence.
++		 */
++		if (major_version < 4 || (!ata_id_has_lba(dev->id))) {
++			ata_dev_init_params(ap, dev);
++
++			/* current CHS translation info (id[53-58]) might be
++			 * changed. reread the identify device info.
++			 */
++			ata_dev_reread_id(ap, dev);
+ 		}
+ 
+-		if (ata_id_has_lba48(dev->id)) {
+-			dev->flags |= ATA_DFLAG_LBA48;
+-			dev->n_sectors = ata_id_u64(dev->id, 100);
+-		} else {
+-			dev->n_sectors = ata_id_u32(dev->id, 60);
++		if (ata_id_has_lba(dev->id)) {
++			dev->flags |= ATA_DFLAG_LBA;
++
++			if (ata_id_has_lba48(dev->id)) {
++				dev->flags |= ATA_DFLAG_LBA48;
++				dev->n_sectors = ata_id_u64(dev->id, 100);
++			} else {
++				dev->n_sectors = ata_id_u32(dev->id, 60);
++			}
++
++			/* print device info to dmesg */
++			printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n",
++			       ap->id, device,
++			       major_version,
++			       ata_mode_string(xfer_modes),
++			       (unsigned long long)dev->n_sectors,
++			       dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA");
++		} else { 
++			/* CHS */
++
++			/* Default translation */
++			dev->cylinders	= dev->id[1];
++			dev->heads	= dev->id[3];
++			dev->sectors	= dev->id[6];
++			dev->n_sectors	= dev->cylinders * dev->heads * dev->sectors;
++
++			if (ata_id_current_chs_valid(dev->id)) {
++				/* Current CHS translation is valid. */
++				dev->cylinders = dev->id[54];
++				dev->heads     = dev->id[55];
++				dev->sectors   = dev->id[56];
++				
++				dev->n_sectors = ata_id_u32(dev->id, 57);
++			}
++
++			/* print device info to dmesg */
++			printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n",
++			       ap->id, device,
++			       major_version,
++			       ata_mode_string(xfer_modes),
++			       (unsigned long long)dev->n_sectors,
++			       (int)dev->cylinders, (int)dev->heads, (int)dev->sectors);
++
+ 		}
+ 
+ 		ap->host->max_cmd_len = 16;
+-
+-		/* print device info to dmesg */
+-		printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
+-		       ap->id, device,
+-		       ata_mode_string(xfer_modes),
+-		       (unsigned long long)dev->n_sectors,
+-		       dev->flags & ATA_DFLAG_LBA48 ? " lba48" : "");
+ 	}
+ 
+ 	/* ATAPI-specific feature tests */
+@@ -1310,7 +1294,7 @@ err_out:
+ }
+ 
+ 
+-static inline u8 ata_dev_knobble(struct ata_port *ap)
++static inline u8 ata_dev_knobble(const struct ata_port *ap)
+ {
+ 	return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
+ }
+@@ -1496,7 +1480,153 @@ void ata_port_disable(struct ata_port *a
+ 	ap->flags |= ATA_FLAG_PORT_DISABLED;
+ }
+ 
+-static struct {
++/*
++ * This mode timing computation functionality is ported over from
++ * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik
++ */
++/*
++ * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
++ * These were taken from ATA/ATAPI-6 standard, rev 0a, except
++ * for PIO 5, which is a nonstandard extension and UDMA6, which
++ * is currently supported only by Maxtor drives. 
++ */
++
++static const struct ata_timing ata_timing[] = {
++
++	{ XFER_UDMA_6,     0,   0,   0,   0,   0,   0,   0,  15 },
++	{ XFER_UDMA_5,     0,   0,   0,   0,   0,   0,   0,  20 },
++	{ XFER_UDMA_4,     0,   0,   0,   0,   0,   0,   0,  30 },
++	{ XFER_UDMA_3,     0,   0,   0,   0,   0,   0,   0,  45 },
++
++	{ XFER_UDMA_2,     0,   0,   0,   0,   0,   0,   0,  60 },
++	{ XFER_UDMA_1,     0,   0,   0,   0,   0,   0,   0,  80 },
++	{ XFER_UDMA_0,     0,   0,   0,   0,   0,   0,   0, 120 },
++
++/*	{ XFER_UDMA_SLOW,  0,   0,   0,   0,   0,   0,   0, 150 }, */
++                                          
++	{ XFER_MW_DMA_2,  25,   0,   0,   0,  70,  25, 120,   0 },
++	{ XFER_MW_DMA_1,  45,   0,   0,   0,  80,  50, 150,   0 },
++	{ XFER_MW_DMA_0,  60,   0,   0,   0, 215, 215, 480,   0 },
++                                          
++	{ XFER_SW_DMA_2,  60,   0,   0,   0, 120, 120, 240,   0 },
++	{ XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 480,   0 },
++	{ XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 960,   0 },
++
++/*	{ XFER_PIO_5,     20,  50,  30, 100,  50,  30, 100,   0 }, */
++	{ XFER_PIO_4,     25,  70,  25, 120,  70,  25, 120,   0 },
++	{ XFER_PIO_3,     30,  80,  70, 180,  80,  70, 180,   0 },
++
++	{ XFER_PIO_2,     30, 290,  40, 330, 100,  90, 240,   0 },
++	{ XFER_PIO_1,     50, 290,  93, 383, 125, 100, 383,   0 },
++	{ XFER_PIO_0,     70, 290, 240, 600, 165, 150, 600,   0 },
++
++/*	{ XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960,   0 }, */
++
++	{ 0xFF }
++};
++
++#define ENOUGH(v,unit)		(((v)-1)/(unit)+1)
++#define EZ(v,unit)		((v)?ENOUGH(v,unit):0)
++
++static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT)
++{
++	q->setup   = EZ(t->setup   * 1000,  T);
++	q->act8b   = EZ(t->act8b   * 1000,  T);
++	q->rec8b   = EZ(t->rec8b   * 1000,  T);
++	q->cyc8b   = EZ(t->cyc8b   * 1000,  T);
++	q->active  = EZ(t->active  * 1000,  T);
++	q->recover = EZ(t->recover * 1000,  T);
++	q->cycle   = EZ(t->cycle   * 1000,  T);
++	q->udma    = EZ(t->udma    * 1000, UT);
++}
++
++void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
++		      struct ata_timing *m, unsigned int what)
++{
++	if (what & ATA_TIMING_SETUP  ) m->setup   = max(a->setup,   b->setup);
++	if (what & ATA_TIMING_ACT8B  ) m->act8b   = max(a->act8b,   b->act8b);
++	if (what & ATA_TIMING_REC8B  ) m->rec8b   = max(a->rec8b,   b->rec8b);
++	if (what & ATA_TIMING_CYC8B  ) m->cyc8b   = max(a->cyc8b,   b->cyc8b);
++	if (what & ATA_TIMING_ACTIVE ) m->active  = max(a->active,  b->active);
++	if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover);
++	if (what & ATA_TIMING_CYCLE  ) m->cycle   = max(a->cycle,   b->cycle);
++	if (what & ATA_TIMING_UDMA   ) m->udma    = max(a->udma,    b->udma);
++}
++
++static const struct ata_timing* ata_timing_find_mode(unsigned short speed)
++{
++	const struct ata_timing *t;
++
++	for (t = ata_timing; t->mode != speed; t++)
++		if (t->mode == 0xFF)
++			return NULL;
++	return t; 
++}
++
++int ata_timing_compute(struct ata_device *adev, unsigned short speed,
++		       struct ata_timing *t, int T, int UT)
++{
++	const struct ata_timing *s;
++	struct ata_timing p;
++
++	/*
++	 * Find the mode. 
++	*/
++
++	if (!(s = ata_timing_find_mode(speed)))
++		return -EINVAL;
++
++	/*
++	 * If the drive is an EIDE drive, it can tell us it needs extended
++	 * PIO/MW_DMA cycle timing.
++	 */
++
++	if (adev->id[ATA_ID_FIELD_VALID] & 2) {	/* EIDE drive */
++		memset(&p, 0, sizeof(p));
++		if(speed >= XFER_PIO_0 && speed <= XFER_SW_DMA_0) {
++			if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO];
++					    else p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO_IORDY];
++		} else if(speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) {
++			p.cycle = adev->id[ATA_ID_EIDE_DMA_MIN];
++		}
++		ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B);
++	}
++
++	/*
++	 * Convert the timing to bus clock counts.
++	 */
++
++	ata_timing_quantize(s, t, T, UT);
++
++	/*
++	 * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
++	 * and some other commands. We have to ensure that the DMA cycle timing is
++	 * slower/equal than the fastest PIO timing.
++	 */
++
++	if (speed > XFER_PIO_4) {
++		ata_timing_compute(adev, adev->pio_mode, &p, T, UT);
++		ata_timing_merge(&p, t, t, ATA_TIMING_ALL);
++	}
++
++	/*
++	 * Lenghten active & recovery time so that cycle time is correct.
++	 */
++
++	if (t->act8b + t->rec8b < t->cyc8b) {
++		t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2;
++		t->rec8b = t->cyc8b - t->act8b;
++	}
++
++	if (t->active + t->recover < t->cycle) {
++		t->active += (t->cycle - (t->active + t->recover)) / 2;
++		t->recover = t->cycle - t->active;
++	}
++
++	return 0;
++}
++
++static const struct {
+ 	unsigned int shift;
+ 	u8 base;
+ } xfer_mode_classes[] = {
+@@ -1603,7 +1733,7 @@ static void ata_host_set_dma(struct ata_
+  */
+ static void ata_set_mode(struct ata_port *ap)
+ {
+-	unsigned int i, xfer_shift;
++	unsigned int xfer_shift;
+ 	u8 xfer_mode;
+ 	int rc;
+ 
+@@ -1632,11 +1762,6 @@ static void ata_set_mode(struct ata_port
+ 	if (ap->ops->post_set_mode)
+ 		ap->ops->post_set_mode(ap);
+ 
+-	for (i = 0; i < 2; i++) {
+-		struct ata_device *dev = &ap->device[i];
+-		ata_dev_set_protocol(dev);
+-	}
+-
+ 	return;
+ 
+ err_out:
+@@ -1746,12 +1871,14 @@ static void ata_bus_post_reset(struct at
+  *
+  *	LOCKING:
+  *	PCI/etc. bus probe sem.
++ *	Obtains host_set lock.
+  *
+  */
+ 
+ static unsigned int ata_bus_edd(struct ata_port *ap)
+ {
+ 	struct ata_taskfile tf;
++	unsigned long flags;
+ 
+ 	/* set up execute-device-diag (bus reset) taskfile */
+ 	/* also, take interrupts to a known state (disabled) */
+@@ -1762,7 +1889,9 @@ static unsigned int ata_bus_edd(struct a
+ 	tf.protocol = ATA_PROT_NODATA;
+ 
+ 	/* do bus reset */
++	spin_lock_irqsave(&ap->host_set->lock, flags);
+ 	ata_tf_to_host(ap, &tf);
++	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ 
+ 	/* spec says at least 2ms.  but who knows with those
+ 	 * crazy ATAPI devices...
+@@ -1910,7 +2039,8 @@ err_out:
+ 	DPRINTK("EXIT\n");
+ }
+ 
+-static void ata_pr_blacklisted(struct ata_port *ap, struct ata_device *dev)
++static void ata_pr_blacklisted(const struct ata_port *ap,
++			       const struct ata_device *dev)
+ {
+ 	printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n",
+ 		ap->id, dev->devno);
+@@ -1948,7 +2078,7 @@ static const char * ata_dma_blacklist []
+ 	"_NEC DV5800A",
+ };
+ 
+-static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev)
++static int ata_dma_blacklisted(const struct ata_device *dev)
+ {
+ 	unsigned char model_num[40];
+ 	char *s;
+@@ -1973,9 +2103,9 @@ static int ata_dma_blacklisted(struct at
+ 	return 0;
+ }
+ 
+-static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
++static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift)
+ {
+-	struct ata_device *master, *slave;
++	const struct ata_device *master, *slave;
+ 	unsigned int mask;
+ 
+ 	master = &ap->device[0];
+@@ -1987,14 +2117,14 @@ static unsigned int ata_get_mode_mask(st
+ 		mask = ap->udma_mask;
+ 		if (ata_dev_present(master)) {
+ 			mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
+-			if (ata_dma_blacklisted(ap, master)) {
++			if (ata_dma_blacklisted(master)) {
+ 				mask = 0;
+ 				ata_pr_blacklisted(ap, master);
+ 			}
+ 		}
+ 		if (ata_dev_present(slave)) {
+ 			mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
+-			if (ata_dma_blacklisted(ap, slave)) {
++			if (ata_dma_blacklisted(slave)) {
+ 				mask = 0;
+ 				ata_pr_blacklisted(ap, slave);
+ 			}
+@@ -2004,14 +2134,14 @@ static unsigned int ata_get_mode_mask(st
+ 		mask = ap->mwdma_mask;
+ 		if (ata_dev_present(master)) {
+ 			mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
+-			if (ata_dma_blacklisted(ap, master)) {
++			if (ata_dma_blacklisted(master)) {
+ 				mask = 0;
+ 				ata_pr_blacklisted(ap, master);
+ 			}
+ 		}
+ 		if (ata_dev_present(slave)) {
+ 			mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
+-			if (ata_dma_blacklisted(ap, slave)) {
++			if (ata_dma_blacklisted(slave)) {
+ 				mask = 0;
+ 				ata_pr_blacklisted(ap, slave);
+ 			}
+@@ -2075,7 +2205,7 @@ static int fgb(u32 bitmap)
+  *	Zero on success, negative on error.
+  */
+ 
+-static int ata_choose_xfer_mode(struct ata_port *ap,
++static int ata_choose_xfer_mode(const struct ata_port *ap,
+ 				u8 *xfer_mode_out,
+ 				unsigned int *xfer_shift_out)
+ {
+@@ -2144,6 +2274,110 @@ static void ata_dev_set_xfermode(struct 
+ }
+ 
+ /**
++ *	ata_dev_reread_id - Reread the device identify device info
++ *	@ap: port where the device is
++ *	@dev: device to reread the identify device info
++ *
++ *	LOCKING:
++ */
++
++static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
++{
++	DECLARE_COMPLETION(wait);
++	struct ata_queued_cmd *qc;
++	unsigned long flags;
++	int rc;
++
++	qc = ata_qc_new_init(ap, dev);
++	BUG_ON(qc == NULL);
++
++	ata_sg_init_one(qc, dev->id, sizeof(dev->id));
++	qc->dma_dir = DMA_FROM_DEVICE;
++
++	if (dev->class == ATA_DEV_ATA) {
++		qc->tf.command = ATA_CMD_ID_ATA;
++		DPRINTK("do ATA identify\n");
++	} else {
++		qc->tf.command = ATA_CMD_ID_ATAPI;
++		DPRINTK("do ATAPI identify\n");
++	}
++
++	qc->tf.flags |= ATA_TFLAG_DEVICE;
++	qc->tf.protocol = ATA_PROT_PIO;
++	qc->nsect = 1;
++
++	qc->waiting = &wait;
++	qc->complete_fn = ata_qc_complete_noop;
++
++	spin_lock_irqsave(&ap->host_set->lock, flags);
++	rc = ata_qc_issue(qc);
++	spin_unlock_irqrestore(&ap->host_set->lock, flags);
++
++	if (rc)
++		goto err_out;
++
++	wait_for_completion(&wait);
++
++	swap_buf_le16(dev->id, ATA_ID_WORDS);
++
++	ata_dump_id(dev);
++
++	DPRINTK("EXIT\n");
++
++	return;
++err_out:
++	ata_port_disable(ap);
++}
++
++/**
++ *	ata_dev_init_params - Issue INIT DEV PARAMS command
++ *	@ap: Port associated with device @dev
++ *	@dev: Device to which command will be sent
++ *
++ *	LOCKING:
++ */
++
++static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
++{
++	DECLARE_COMPLETION(wait);
++	struct ata_queued_cmd *qc;
++	int rc;
++	unsigned long flags;
++	u16 sectors = dev->id[6];
++	u16 heads   = dev->id[3];
++
++	/* Number of sectors per track 1-255. Number of heads 1-16 */
++	if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
++		return;
++
++	/* set up init dev params taskfile */
++	DPRINTK("init dev params \n");
++
++	qc = ata_qc_new_init(ap, dev);
++	BUG_ON(qc == NULL);
++
++	qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
++	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
++	qc->tf.protocol = ATA_PROT_NODATA;
++	qc->tf.nsect = sectors;
++	qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
++
++	qc->waiting = &wait;
++	qc->complete_fn = ata_qc_complete_noop;
++
++	spin_lock_irqsave(&ap->host_set->lock, flags);
++	rc = ata_qc_issue(qc);
++	spin_unlock_irqrestore(&ap->host_set->lock, flags);
++
++	if (rc)
++		ata_port_disable(ap);
++	else
++		wait_for_completion(&wait);
++
++	DPRINTK("EXIT\n");
++}
++
++/**
+  *	ata_sg_clean - Unmap DMA memory associated with command
+  *	@qc: Command containing DMA memory to be released
+  *
+@@ -2284,19 +2518,12 @@ void ata_qc_prep(struct ata_queued_cmd *
+ 
+ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
+ {
+-	struct scatterlist *sg;
+-
+ 	qc->flags |= ATA_QCFLAG_SINGLE;
+ 
+-	memset(&qc->sgent, 0, sizeof(qc->sgent));
+ 	qc->sg = &qc->sgent;
+ 	qc->n_elem = 1;
+ 	qc->buf_virt = buf;
+-
+-	sg = qc->sg;
+-	sg->page = virt_to_page(buf);
+-	sg->offset = (unsigned long) buf & ~PAGE_MASK;
+-	sg->length = buflen;
++	sg_init_one(qc->sg, buf, buflen);
+ }
+ 
+ /**
+@@ -2399,7 +2626,7 @@ static int ata_sg_setup(struct ata_queue
+  *	None.  (grabs host lock)
+  */
+ 
+-void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
++void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	unsigned long flags;
+@@ -2407,38 +2634,38 @@ void ata_poll_qc_complete(struct ata_que
+ 	spin_lock_irqsave(&ap->host_set->lock, flags);
+ 	ap->flags &= ~ATA_FLAG_NOINTR;
+ 	ata_irq_on(ap);
+-	ata_qc_complete(qc, drv_stat);
++	ata_qc_complete(qc, err_mask);
+ 	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ }
+ 
+ /**
+  *	ata_pio_poll -
+- *	@ap:
++ *	@ap: the target ata_port
+  *
+  *	LOCKING:
+  *	None.  (executing in kernel thread context)
+  *
+  *	RETURNS:
+- *
++ *	timeout value to use
+  */
+ 
+ static unsigned long ata_pio_poll(struct ata_port *ap)
+ {
+ 	u8 status;
+-	unsigned int poll_state = PIO_ST_UNKNOWN;
+-	unsigned int reg_state = PIO_ST_UNKNOWN;
+-	const unsigned int tmout_state = PIO_ST_TMOUT;
+-
+-	switch (ap->pio_task_state) {
+-	case PIO_ST:
+-	case PIO_ST_POLL:
+-		poll_state = PIO_ST_POLL;
+-		reg_state = PIO_ST;
++	unsigned int poll_state = HSM_ST_UNKNOWN;
++	unsigned int reg_state = HSM_ST_UNKNOWN;
++	const unsigned int tmout_state = HSM_ST_TMOUT;
++
++	switch (ap->hsm_task_state) {
++	case HSM_ST:
++	case HSM_ST_POLL:
++		poll_state = HSM_ST_POLL;
++		reg_state = HSM_ST;
+ 		break;
+-	case PIO_ST_LAST:
+-	case PIO_ST_LAST_POLL:
+-		poll_state = PIO_ST_LAST_POLL;
+-		reg_state = PIO_ST_LAST;
++	case HSM_ST_LAST:
++	case HSM_ST_LAST_POLL:
++		poll_state = HSM_ST_LAST_POLL;
++		reg_state = HSM_ST_LAST;
+ 		break;
+ 	default:
+ 		BUG();
+@@ -2448,20 +2675,20 @@ static unsigned long ata_pio_poll(struct
+ 	status = ata_chk_status(ap);
+ 	if (status & ATA_BUSY) {
+ 		if (time_after(jiffies, ap->pio_task_timeout)) {
+-			ap->pio_task_state = tmout_state;
++			ap->hsm_task_state = tmout_state;
+ 			return 0;
+ 		}
+-		ap->pio_task_state = poll_state;
++		ap->hsm_task_state = poll_state;
+ 		return ATA_SHORT_PAUSE;
+ 	}
+ 
+-	ap->pio_task_state = reg_state;
++	ap->hsm_task_state = reg_state;
+ 	return 0;
+ }
+ 
+ /**
+- *	ata_pio_complete -
+- *	@ap:
++ *	ata_pio_complete - check if drive is busy or idle
++ *	@ap: the target ata_port
+  *
+  *	LOCKING:
+  *	None.  (executing in kernel thread context)
+@@ -2480,14 +2707,14 @@ static int ata_pio_complete (struct ata_
+ 	 * we enter, BSY will be cleared in a chk-status or two.  If not,
+ 	 * the drive is probably seeking or something.  Snooze for a couple
+ 	 * msecs, then chk-status again.  If still busy, fall back to
+-	 * PIO_ST_POLL state.
++	 * HSM_ST_POLL state.
+ 	 */
+ 	drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
+ 	if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+ 		msleep(2);
+ 		drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
+ 		if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+-			ap->pio_task_state = PIO_ST_LAST_POLL;
++			ap->hsm_task_state = HSM_ST_LAST_POLL;
+ 			ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
+ 			return 0;
+ 		}
+@@ -2495,16 +2722,16 @@ static int ata_pio_complete (struct ata_
+ 
+ 	drv_stat = ata_wait_idle(ap);
+ 	if (!ata_ok(drv_stat)) {
+-		ap->pio_task_state = PIO_ST_ERR;
++		ap->hsm_task_state = HSM_ST_ERR;
+ 		return 0;
+ 	}
+ 
+ 	qc = ata_qc_from_tag(ap, ap->active_tag);
+ 	assert(qc != NULL);
+ 
+-	ap->pio_task_state = PIO_ST_IDLE;
++	ap->hsm_task_state = HSM_ST_IDLE;
+ 
+-	ata_poll_qc_complete(qc, drv_stat);
++	ata_poll_qc_complete(qc, 0);
+ 
+ 	/* another command may start at this point */
+ 
+@@ -2513,7 +2740,7 @@ static int ata_pio_complete (struct ata_
+ 
+ 
+ /**
+- *	swap_buf_le16 -
++ *	swap_buf_le16 - swap halves of 16-words in place
+  *	@buf:  Buffer to swap
+  *	@buf_words:  Number of 16-bit words in buffer.
+  *
+@@ -2522,6 +2749,7 @@ static int ata_pio_complete (struct ata_
+  *	vice-versa.
+  *
+  *	LOCKING:
++ *	Inherited from caller.
+  */
+ void swap_buf_le16(u16 *buf, unsigned int buf_words)
+ {
+@@ -2544,7 +2772,6 @@ void swap_buf_le16(u16 *buf, unsigned in
+  *
+  *	LOCKING:
+  *	Inherited from caller.
+- *
+  */
+ 
+ static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
+@@ -2590,7 +2817,6 @@ static void ata_mmio_data_xfer(struct at
+  *
+  *	LOCKING:
+  *	Inherited from caller.
+- *
+  */
+ 
+ static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf,
+@@ -2630,7 +2856,6 @@ static void ata_pio_data_xfer(struct ata
+  *
+  *	LOCKING:
+  *	Inherited from caller.
+- *
+  */
+ 
+ static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
+@@ -2662,7 +2887,7 @@ static void ata_pio_sector(struct ata_qu
+ 	unsigned char *buf;
+ 
+ 	if (qc->cursect == (qc->nsect - 1))
+-		ap->pio_task_state = PIO_ST_LAST;
++		ap->hsm_task_state = HSM_ST_LAST;
+ 
+ 	page = sg[qc->cursg].page;
+ 	offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
+@@ -2712,7 +2937,7 @@ static void __atapi_pio_bytes(struct ata
+ 	unsigned int offset, count;
+ 
+ 	if (qc->curbytes + bytes >= qc->nbytes)
+-		ap->pio_task_state = PIO_ST_LAST;
++		ap->hsm_task_state = HSM_ST_LAST;
+ 
+ next_sg:
+ 	if (unlikely(qc->cursg >= qc->n_elem)) {
+@@ -2734,7 +2959,7 @@ next_sg:
+ 		for (i = 0; i < words; i++)
+ 			ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write);
+ 
+-		ap->pio_task_state = PIO_ST_LAST;
++		ap->hsm_task_state = HSM_ST_LAST;
+ 		return;
+ 	}
+ 
+@@ -2783,7 +3008,6 @@ next_sg:
+  *
+  *	LOCKING:
+  *	Inherited from caller.
+- *
+  */
+ 
+ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
+@@ -2815,12 +3039,12 @@ static void atapi_pio_bytes(struct ata_q
+ err_out:
+ 	printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
+ 	      ap->id, dev->devno);
+-	ap->pio_task_state = PIO_ST_ERR;
++	ap->hsm_task_state = HSM_ST_ERR;
+ }
+ 
+ /**
+- *	ata_pio_sector -
+- *	@ap:
++ *	ata_pio_block - start PIO on a block
++ *	@ap: the target ata_port
+  *
+  *	LOCKING:
+  *	None.  (executing in kernel thread context)
+@@ -2832,19 +3056,19 @@ static void ata_pio_block(struct ata_por
+ 	u8 status;
+ 
+ 	/*
+-	 * This is purely hueristic.  This is a fast path.
++	 * This is purely heuristic.  This is a fast path.
+ 	 * Sometimes when we enter, BSY will be cleared in
+ 	 * a chk-status or two.  If not, the drive is probably seeking
+ 	 * or something.  Snooze for a couple msecs, then
+ 	 * chk-status again.  If still busy, fall back to
+-	 * PIO_ST_POLL state.
++	 * HSM_ST_POLL state.
+ 	 */
+ 	status = ata_busy_wait(ap, ATA_BUSY, 5);
+ 	if (status & ATA_BUSY) {
+ 		msleep(2);
+ 		status = ata_busy_wait(ap, ATA_BUSY, 10);
+ 		if (status & ATA_BUSY) {
+-			ap->pio_task_state = PIO_ST_POLL;
++			ap->hsm_task_state = HSM_ST_POLL;
+ 			ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
+ 			return;
+ 		}
+@@ -2856,7 +3080,7 @@ static void ata_pio_block(struct ata_por
+ 	if (is_atapi_taskfile(&qc->tf)) {
+ 		/* no more data to transfer or unsupported ATAPI command */
+ 		if ((status & ATA_DRQ) == 0) {
+-			ap->pio_task_state = PIO_ST_LAST;
++			ap->hsm_task_state = HSM_ST_LAST;
+ 			return;
+ 		}
+ 
+@@ -2864,7 +3088,7 @@ static void ata_pio_block(struct ata_por
+ 	} else {
+ 		/* handle BSY=0, DRQ=0 as error */
+ 		if ((status & ATA_DRQ) == 0) {
+-			ap->pio_task_state = PIO_ST_ERR;
++			ap->hsm_task_state = HSM_ST_ERR;
+ 			return;
+ 		}
+ 
+@@ -2875,18 +3099,15 @@ static void ata_pio_block(struct ata_por
+ static void ata_pio_error(struct ata_port *ap)
+ {
+ 	struct ata_queued_cmd *qc;
+-	u8 drv_stat;
++
++	printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
+ 
+ 	qc = ata_qc_from_tag(ap, ap->active_tag);
+ 	assert(qc != NULL);
+ 
+-	drv_stat = ata_chk_status(ap);
+-	printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
+-	       ap->id, drv_stat);
+-
+-	ap->pio_task_state = PIO_ST_IDLE;
++	ap->hsm_task_state = HSM_ST_IDLE;
+ 
+-	ata_poll_qc_complete(qc, drv_stat | ATA_ERR);
++	ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
+ }
+ 
+ static void ata_pio_task(void *_data)
+@@ -2899,25 +3120,25 @@ fsm_start:
+ 	timeout = 0;
+ 	qc_completed = 0;
+ 
+-	switch (ap->pio_task_state) {
+-	case PIO_ST_IDLE:
++	switch (ap->hsm_task_state) {
++	case HSM_ST_IDLE:
+ 		return;
+ 
+-	case PIO_ST:
++	case HSM_ST:
+ 		ata_pio_block(ap);
+ 		break;
+ 
+-	case PIO_ST_LAST:
++	case HSM_ST_LAST:
+ 		qc_completed = ata_pio_complete(ap);
+ 		break;
+ 
+-	case PIO_ST_POLL:
+-	case PIO_ST_LAST_POLL:
++	case HSM_ST_POLL:
++	case HSM_ST_LAST_POLL:
+ 		timeout = ata_pio_poll(ap);
+ 		break;
+ 
+-	case PIO_ST_TMOUT:
+-	case PIO_ST_ERR:
++	case HSM_ST_TMOUT:
++	case HSM_ST_ERR:
+ 		ata_pio_error(ap);
+ 		return;
+ 	}
+@@ -2928,52 +3149,6 @@ fsm_start:
+ 		goto fsm_start;
+ }
+ 
+-static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
+-				struct scsi_cmnd *cmd)
+-{
+-	DECLARE_COMPLETION(wait);
+-	struct ata_queued_cmd *qc;
+-	unsigned long flags;
+-	int rc;
+-
+-	DPRINTK("ATAPI request sense\n");
+-
+-	qc = ata_qc_new_init(ap, dev);
+-	BUG_ON(qc == NULL);
+-
+-	/* FIXME: is this needed? */
+-	memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+-
+-	ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
+-	qc->dma_dir = DMA_FROM_DEVICE;
+-
+-	memset(&qc->cdb, 0, ap->cdb_len);
+-	qc->cdb[0] = REQUEST_SENSE;
+-	qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
+-
+-	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+-	qc->tf.command = ATA_CMD_PACKET;
+-
+-	qc->tf.protocol = ATA_PROT_ATAPI;
+-	qc->tf.lbam = (8 * 1024) & 0xff;
+-	qc->tf.lbah = (8 * 1024) >> 8;
+-	qc->nbytes = SCSI_SENSE_BUFFERSIZE;
+-
+-	qc->waiting = &wait;
+-	qc->complete_fn = ata_qc_complete_noop;
+-
+-	spin_lock_irqsave(&ap->host_set->lock, flags);
+-	rc = ata_qc_issue(qc);
+-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+-
+-	if (rc)
+-		ata_port_disable(ap);
+-	else
+-		wait_for_completion(&wait);
+-
+-	DPRINTK("EXIT\n");
+-}
+-
+ /**
+  *	ata_qc_timeout - Handle timeout of queued command
+  *	@qc: Command that timed out
+@@ -3055,7 +3230,7 @@ static void ata_qc_timeout(struct ata_qu
+ 		       ap->id, qc->tf.command, drv_stat, host_stat);
+ 
+ 		/* complete taskfile transaction */
+-		ata_qc_complete(qc, drv_stat);
++		ata_qc_complete(qc, ac_err_mask(drv_stat));
+ 		break;
+ 	}
+ 
+@@ -3091,14 +3266,14 @@ void ata_eng_timeout(struct ata_port *ap
+ 	DPRINTK("ENTER\n");
+ 
+ 	qc = ata_qc_from_tag(ap, ap->active_tag);
+-	if (!qc) {
++	if (qc)
++		ata_qc_timeout(qc);
++	else {
+ 		printk(KERN_ERR "ata%u: BUG: timeout without command\n",
+ 		       ap->id);
+ 		goto out;
+ 	}
+ 
+-	ata_qc_timeout(qc);
+-
+ out:
+ 	DPRINTK("EXIT\n");
+ }
+@@ -3155,15 +3330,12 @@ struct ata_queued_cmd *ata_qc_new_init(s
+ 		qc->nbytes = qc->curbytes = 0;
+ 
+ 		ata_tf_init(ap, &qc->tf, dev->devno);
+-
+-		if (dev->flags & ATA_DFLAG_LBA48)
+-			qc->tf.flags |= ATA_TFLAG_LBA48;
+ 	}
+ 
+ 	return qc;
+ }
+ 
+-static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
++int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
+ {
+ 	return 0;
+ }
+@@ -3201,7 +3373,6 @@ static void __ata_qc_complete(struct ata
+  *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+- *
+  */
+ void ata_qc_free(struct ata_queued_cmd *qc)
+ {
+@@ -3221,10 +3392,9 @@ void ata_qc_free(struct ata_queued_cmd *
+  *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+- *
+  */
+ 
+-void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
++void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+ {
+ 	int rc;
+ 
+@@ -3241,7 +3411,7 @@ void ata_qc_complete(struct ata_queued_c
+ 	qc->flags &= ~ATA_QCFLAG_ACTIVE;
+ 
+ 	/* call completion callback */
+-	rc = qc->complete_fn(qc, drv_stat);
++	rc = qc->complete_fn(qc, err_mask);
+ 
+ 	/* if callback indicates not to complete command (non-zero),
+ 	 * return immediately
+@@ -3348,7 +3518,7 @@ int ata_qc_issue_prot(struct ata_queued_
+ 
+ 	switch (qc->tf.protocol) {
+ 	case ATA_PROT_NODATA:
+-		ata_tf_to_host_nolock(ap, &qc->tf);
++		ata_tf_to_host(ap, &qc->tf);
+ 		break;
+ 
+ 	case ATA_PROT_DMA:
+@@ -3359,20 +3529,20 @@ int ata_qc_issue_prot(struct ata_queued_
+ 
+ 	case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
+ 		ata_qc_set_polling(qc);
+-		ata_tf_to_host_nolock(ap, &qc->tf);
+-		ap->pio_task_state = PIO_ST;
++		ata_tf_to_host(ap, &qc->tf);
++		ap->hsm_task_state = HSM_ST;
+ 		queue_work(ata_wq, &ap->pio_task);
+ 		break;
+ 
+ 	case ATA_PROT_ATAPI:
+ 		ata_qc_set_polling(qc);
+-		ata_tf_to_host_nolock(ap, &qc->tf);
++		ata_tf_to_host(ap, &qc->tf);
+ 		queue_work(ata_wq, &ap->packet_task);
+ 		break;
+ 
+ 	case ATA_PROT_ATAPI_NODATA:
+ 		ap->flags |= ATA_FLAG_NOINTR;
+-		ata_tf_to_host_nolock(ap, &qc->tf);
++		ata_tf_to_host(ap, &qc->tf);
+ 		queue_work(ata_wq, &ap->packet_task);
+ 		break;
+ 
+@@ -3586,7 +3756,7 @@ u8 ata_bmdma_status(struct ata_port *ap)
+ 		void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
+ 		host_stat = readb(mmio + ATA_DMA_STATUS);
+ 	} else
+-	host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
++		host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ 	return host_stat;
+ }
+ 
+@@ -3679,7 +3849,7 @@ inline unsigned int ata_host_intr (struc
+ 		ap->ops->irq_clear(ap);
+ 
+ 		/* complete taskfile transaction */
+-		ata_qc_complete(qc, status);
++		ata_qc_complete(qc, ac_err_mask(status));
+ 		break;
+ 
+ 	default:
+@@ -3715,7 +3885,6 @@ idle_irq:
+  *
+  *	RETURNS:
+  *	IRQ_NONE or IRQ_HANDLED.
+- *
+  */
+ 
+ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+@@ -3775,7 +3944,7 @@ static void atapi_packet_task(void *_dat
+ 	/* sleep-wait for BSY to clear */
+ 	DPRINTK("busy wait\n");
+ 	if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
+-		goto err_out;
++		goto err_out_status;
+ 
+ 	/* make sure DRQ is set */
+ 	status = ata_chk_status(ap);
+@@ -3806,14 +3975,16 @@ static void atapi_packet_task(void *_dat
+ 		ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
+ 
+ 		/* PIO commands are handled by polling */
+-		ap->pio_task_state = PIO_ST;
++		ap->hsm_task_state = HSM_ST;
+ 		queue_work(ata_wq, &ap->pio_task);
+ 	}
+ 
+ 	return;
+ 
++err_out_status:
++	status = ata_chk_status(ap);
+ err_out:
+-	ata_poll_qc_complete(qc, ATA_ERR);
++	ata_poll_qc_complete(qc, __ac_err_mask(status));
+ }
+ 
+ 
+@@ -3827,6 +3998,7 @@ err_out:
+  *	May be used as the port_start() entry in ata_port_operations.
+  *
+  *	LOCKING:
++ *	Inherited from caller.
+  */
+ 
+ int ata_port_start (struct ata_port *ap)
+@@ -3852,6 +4024,7 @@ int ata_port_start (struct ata_port *ap)
+  *	May be used as the port_stop() entry in ata_port_operations.
+  *
+  *	LOCKING:
++ *	Inherited from caller.
+  */
+ 
+ void ata_port_stop (struct ata_port *ap)
+@@ -3874,6 +4047,7 @@ void ata_host_stop (struct ata_host_set 
+  *	@do_unregister: 1 if we fully unregister, 0 to just stop the port
+  *
+  *	LOCKING:
++ *	Inherited from caller.
+  */
+ 
+ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
+@@ -3901,12 +4075,11 @@ static void ata_host_remove(struct ata_p
+  *
+  *	LOCKING:
+  *	Inherited from caller.
+- *
+  */
+ 
+ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
+ 			  struct ata_host_set *host_set,
+-			  struct ata_probe_ent *ent, unsigned int port_no)
++			  const struct ata_probe_ent *ent, unsigned int port_no)
+ {
+ 	unsigned int i;
+ 
+@@ -3916,8 +4089,6 @@ static void ata_host_init(struct ata_por
+ 	host->unique_id = ata_unique_id++;
+ 	host->max_cmd_len = 12;
+ 
+-	scsi_assign_lock(host, &host_set->lock);
+-
+ 	ap->flags = ATA_FLAG_PORT_DISABLED;
+ 	ap->id = host->unique_id;
+ 	ap->host = host;
+@@ -3962,10 +4133,9 @@ static void ata_host_init(struct ata_por
+  *
+  *	RETURNS:
+  *	New ata_port on success, for NULL on error.
+- *
+  */
+ 
+-static struct ata_port * ata_host_add(struct ata_probe_ent *ent,
++static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
+ 				      struct ata_host_set *host_set,
+ 				      unsigned int port_no)
+ {
+@@ -4010,10 +4180,9 @@ err_out:
+  *
+  *	RETURNS:
+  *	Number of ports registered.  Zero on error (no ports registered).
+- *
+  */
+ 
+-int ata_device_add(struct ata_probe_ent *ent)
++int ata_device_add(const struct ata_probe_ent *ent)
+ {
+ 	unsigned int count = 0, i;
+ 	struct device *dev = ent->dev;
+@@ -4021,11 +4190,10 @@ int ata_device_add(struct ata_probe_ent 
+ 
+ 	DPRINTK("ENTER\n");
+ 	/* alloc a container for our list of ATA ports (buses) */
+-	host_set = kmalloc(sizeof(struct ata_host_set) +
++	host_set = kzalloc(sizeof(struct ata_host_set) +
+ 			   (ent->n_ports * sizeof(void *)), GFP_KERNEL);
+ 	if (!host_set)
+ 		return 0;
+-	memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)));
+ 	spin_lock_init(&host_set->lock);
+ 
+ 	host_set->dev = dev;
+@@ -4065,10 +4233,8 @@ int ata_device_add(struct ata_probe_ent 
+ 		count++;
+ 	}
+ 
+-	if (!count) {
+-		kfree(host_set);
+-		return 0;
+-	}
++	if (!count)
++		goto err_free_ret;
+ 
+ 	/* obtain irq, that is shared between channels */
+ 	if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
+@@ -4113,7 +4279,7 @@ int ata_device_add(struct ata_probe_ent 
+ 	for (i = 0; i < count; i++) {
+ 		struct ata_port *ap = host_set->ports[i];
+ 
+-		scsi_scan_host(ap->host);
++		ata_scsi_scan_host(ap);
+ 	}
+ 
+ 	dev_set_drvdata(dev, host_set);
+@@ -4126,6 +4292,7 @@ err_out:
+ 		ata_host_remove(host_set->ports[i], 1);
+ 		scsi_host_put(host_set->ports[i]->host);
+ 	}
++err_free_ret:
+ 	kfree(host_set);
+ 	VPRINTK("EXIT, returning 0\n");
+ 	return 0;
+@@ -4142,7 +4309,6 @@ err_out:
+  *	Inherited from calling layer (may sleep).
+  */
+ 
+-
+ void ata_host_set_remove(struct ata_host_set *host_set)
+ {
+ 	struct ata_port *ap;
+@@ -4232,19 +4398,17 @@ void ata_std_ports(struct ata_ioports *i
+ }
+ 
+ static struct ata_probe_ent *
+-ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
++ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
+ {
+ 	struct ata_probe_ent *probe_ent;
+ 
+-	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
++	probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
+ 	if (!probe_ent) {
+ 		printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
+ 		       kobject_name(&(dev->kobj)));
+ 		return NULL;
+ 	}
+ 
+-	memset(probe_ent, 0, sizeof(*probe_ent));
+-
+ 	INIT_LIST_HEAD(&probe_ent->node);
+ 	probe_ent->dev = dev;
+ 
+@@ -4273,85 +4437,86 @@ void ata_pci_host_stop (struct ata_host_
+  *	ata_pci_init_native_mode - Initialize native-mode driver
+  *	@pdev:  pci device to be initialized
+  *	@port:  array[2] of pointers to port info structures.
++ *	@ports: bitmap of ports present
+  *
+  *	Utility function which allocates and initializes an
+  *	ata_probe_ent structure for a standard dual-port
+  *	PIO-based IDE controller.  The returned ata_probe_ent
+  *	structure can be passed to ata_device_add().  The returned
+  *	ata_probe_ent structure should then be freed with kfree().
++ *
++ *	The caller need only pass the address of the primary port, the
++ *	secondary will be deduced automatically. If the device has non
++ *	standard secondary port mappings this function can be called twice,
++ *	once for each interface.
+  */
+ 
+ struct ata_probe_ent *
+-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
++ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
+ {
+ 	struct ata_probe_ent *probe_ent =
+ 		ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
++	int p = 0;
++
+ 	if (!probe_ent)
+ 		return NULL;
+ 
+-	probe_ent->n_ports = 2;
+ 	probe_ent->irq = pdev->irq;
+ 	probe_ent->irq_flags = SA_SHIRQ;
+ 
+-	probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
+-	probe_ent->port[0].altstatus_addr =
+-	probe_ent->port[0].ctl_addr =
+-		pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
+-	probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
+-
+-	probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
+-	probe_ent->port[1].altstatus_addr =
+-	probe_ent->port[1].ctl_addr =
+-		pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
+-	probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
+-
+-	ata_std_ports(&probe_ent->port[0]);
+-	ata_std_ports(&probe_ent->port[1]);
++	if (ports & ATA_PORT_PRIMARY) {
++		probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
++		probe_ent->port[p].altstatus_addr =
++		probe_ent->port[p].ctl_addr =
++			pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
++		probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4);
++		ata_std_ports(&probe_ent->port[p]);
++		p++;
++	}
++
++	if (ports & ATA_PORT_SECONDARY) {
++		probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
++		probe_ent->port[p].altstatus_addr =
++		probe_ent->port[p].ctl_addr =
++			pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
++		probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8;
++		ata_std_ports(&probe_ent->port[p]);
++		p++;
++	}
+ 
++	probe_ent->n_ports = p;
+ 	return probe_ent;
+ }
+ 
+-static struct ata_probe_ent *
+-ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
+-    struct ata_probe_ent **ppe2)
++static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num)
+ {
+-	struct ata_probe_ent *probe_ent, *probe_ent2;
++	struct ata_probe_ent *probe_ent;
+ 
+-	probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
++	probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
+ 	if (!probe_ent)
+ 		return NULL;
+-	probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]);
+-	if (!probe_ent2) {
+-		kfree(probe_ent);
+-		return NULL;
+-	}
+-
+-	probe_ent->n_ports = 1;
+-	probe_ent->irq = 14;
+ 
+-	probe_ent->hard_port_no = 0;
+ 	probe_ent->legacy_mode = 1;
++	probe_ent->n_ports = 1;
++	probe_ent->hard_port_no = port_num;
+ 
+-	probe_ent2->n_ports = 1;
+-	probe_ent2->irq = 15;
+-
+-	probe_ent2->hard_port_no = 1;
+-	probe_ent2->legacy_mode = 1;
+-
+-	probe_ent->port[0].cmd_addr = 0x1f0;
+-	probe_ent->port[0].altstatus_addr =
+-	probe_ent->port[0].ctl_addr = 0x3f6;
+-	probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
+-
+-	probe_ent2->port[0].cmd_addr = 0x170;
+-	probe_ent2->port[0].altstatus_addr =
+-	probe_ent2->port[0].ctl_addr = 0x376;
+-	probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
+-
++	switch(port_num)
++	{
++		case 0:
++			probe_ent->irq = 14;
++			probe_ent->port[0].cmd_addr = 0x1f0;
++			probe_ent->port[0].altstatus_addr =
++			probe_ent->port[0].ctl_addr = 0x3f6;
++			break;
++		case 1:
++			probe_ent->irq = 15;
++			probe_ent->port[0].cmd_addr = 0x170;
++			probe_ent->port[0].altstatus_addr =
++			probe_ent->port[0].ctl_addr = 0x376;
++			break;
++	}
++	probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num;
+ 	ata_std_ports(&probe_ent->port[0]);
+-	ata_std_ports(&probe_ent2->port[0]);
+-
+-	*ppe2 = probe_ent2;
+ 	return probe_ent;
+ }
+ 
+@@ -4374,13 +4539,12 @@ ata_pci_init_legacy_mode(struct pci_dev 
+  *
+  *	RETURNS:
+  *	Zero on success, negative on errno-based value on error.
+- *
+  */
+ 
+ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
+ 		      unsigned int n_ports)
+ {
+-	struct ata_probe_ent *probe_ent, *probe_ent2 = NULL;
++	struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
+ 	struct ata_port_info *port[2];
+ 	u8 tmp8, mask;
+ 	unsigned int legacy_mode = 0;
+@@ -4397,7 +4561,7 @@ int ata_pci_init_one (struct pci_dev *pd
+ 
+ 	if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
+ 	    && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+-		/* TODO: support transitioning to native mode? */
++		/* TODO: What if one channel is in native mode ... */
+ 		pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
+ 		mask = (1 << 2) | (1 << 0);
+ 		if ((tmp8 & mask) != mask)
+@@ -4405,11 +4569,20 @@ int ata_pci_init_one (struct pci_dev *pd
+ 	}
+ 
+ 	/* FIXME... */
+-	if ((!legacy_mode) && (n_ports > 1)) {
+-		printk(KERN_ERR "ata: BUG: native mode, n_ports > 1\n");
+-		return -EINVAL;
++	if ((!legacy_mode) && (n_ports > 2)) {
++		printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
++		n_ports = 2;
++		/* For now */
+ 	}
+ 
++	/* FIXME: Really for ATA it isn't safe because the device may be
++	   multi-purpose and we want to leave it alone if it was already
++	   enabled. Secondly for shared use as Arjan says we want refcounting
++	   
++	   Checking dev->is_enabled is insufficient as this is not set at
++	   boot for the primary video which is BIOS enabled
++         */
++         
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+ 		return rc;
+@@ -4420,6 +4593,7 @@ int ata_pci_init_one (struct pci_dev *pd
+ 		goto err_out;
+ 	}
+ 
++	/* FIXME: Should use platform specific mappers for legacy port ranges */
+ 	if (legacy_mode) {
+ 		if (!request_region(0x1f0, 8, "libata")) {
+ 			struct resource *conflict, res;
+@@ -4464,10 +4638,17 @@ int ata_pci_init_one (struct pci_dev *pd
+ 		goto err_out_regions;
+ 
+ 	if (legacy_mode) {
+-		probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2);
+-	} else
+-		probe_ent = ata_pci_init_native_mode(pdev, port);
+-	if (!probe_ent) {
++		if (legacy_mode & (1 << 0))
++			probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
++		if (legacy_mode & (1 << 1))
++			probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
++	} else {
++		if (n_ports == 2)
++			probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
++		else
++			probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
++	}
++	if (!probe_ent && !probe_ent2) {
+ 		rc = -ENOMEM;
+ 		goto err_out_regions;
+ 	}
+@@ -4505,7 +4686,7 @@ err_out:
+  *	@pdev: PCI device that was removed
+  *
+  *	PCI layer indicates to libata via this hook that
+- *	hot-unplug or module unload event has occured.
++ *	hot-unplug or module unload event has occurred.
+  *	Handle this by unregistering all objects associated
+  *	with this PCI device.  Free those objects.  Then finally
+  *	release PCI resources and disable device.
+@@ -4526,7 +4707,7 @@ void ata_pci_remove_one (struct pci_dev 
+ }
+ 
+ /* move to PCI subsystem */
+-int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits)
++int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
+ {
+ 	unsigned long tmp = 0;
+ 
+@@ -4579,6 +4760,27 @@ static void __exit ata_exit(void)
+ module_init(ata_init);
+ module_exit(ata_exit);
+ 
++static unsigned long ratelimit_time;
++static spinlock_t ata_ratelimit_lock = SPIN_LOCK_UNLOCKED;
++
++int ata_ratelimit(void)
++{
++	int rc;
++	unsigned long flags;
++
++	spin_lock_irqsave(&ata_ratelimit_lock, flags);
++
++	if (time_after(jiffies, ratelimit_time)) {
++		rc = 1;
++		ratelimit_time = jiffies + (HZ/5);
++	} else
++		rc = 0;
++
++	spin_unlock_irqrestore(&ata_ratelimit_lock, flags);
++
++	return rc;
++}
++
+ /*
+  * libata is essentially a library of internal helper functions for
+  * low-level ATA host controller drivers.  As such, the API/ABI is
+@@ -4603,7 +4805,6 @@ EXPORT_SYMBOL_GPL(ata_tf_to_fis);
+ EXPORT_SYMBOL_GPL(ata_tf_from_fis);
+ EXPORT_SYMBOL_GPL(ata_check_status);
+ EXPORT_SYMBOL_GPL(ata_altstatus);
+-EXPORT_SYMBOL_GPL(ata_chk_err);
+ EXPORT_SYMBOL_GPL(ata_exec_command);
+ EXPORT_SYMBOL_GPL(ata_port_start);
+ EXPORT_SYMBOL_GPL(ata_port_stop);
+@@ -4620,6 +4821,7 @@ EXPORT_SYMBOL_GPL(sata_phy_reset);
+ EXPORT_SYMBOL_GPL(__sata_phy_reset);
+ EXPORT_SYMBOL_GPL(ata_bus_reset);
+ EXPORT_SYMBOL_GPL(ata_port_disable);
++EXPORT_SYMBOL_GPL(ata_ratelimit);
+ EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
+ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
+ EXPORT_SYMBOL_GPL(ata_scsi_error);
+@@ -4631,6 +4833,9 @@ EXPORT_SYMBOL_GPL(ata_dev_id_string);
+ EXPORT_SYMBOL_GPL(ata_dev_config);
+ EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+ 
++EXPORT_SYMBOL_GPL(ata_timing_compute);
++EXPORT_SYMBOL_GPL(ata_timing_merge);
++
+ #ifdef CONFIG_PCI
+ EXPORT_SYMBOL_GPL(pci_test_config_bits);
+ EXPORT_SYMBOL_GPL(ata_pci_host_stop);
+diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
+--- a/drivers/scsi/libata-scsi.c
++++ b/drivers/scsi/libata-scsi.c
+@@ -39,16 +39,67 @@
+ #include <scsi/scsi.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
++#include <scsi/scsi_device.h>
+ #include <linux/libata.h>
++#include <linux/hdreg.h>
+ #include <asm/uaccess.h>
+ 
+ #include "libata.h"
+ 
+-typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd);
++#define SECTOR_SIZE	512
++
++typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
+ static struct ata_device *
+-ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev);
++ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
++
++#define RW_RECOVERY_MPAGE 0x1
++#define RW_RECOVERY_MPAGE_LEN 12
++#define CACHE_MPAGE 0x8
++#define CACHE_MPAGE_LEN 20
++#define CONTROL_MPAGE 0xa
++#define CONTROL_MPAGE_LEN 12
++#define ALL_MPAGES 0x3f
++#define ALL_SUB_MPAGES 0xff
++
++
++static const u8 def_rw_recovery_mpage[] = {
++	RW_RECOVERY_MPAGE,
++	RW_RECOVERY_MPAGE_LEN - 2,
++	(1 << 7) |	/* AWRE, sat-r06 say it shall be 0 */
++	    (1 << 6),	/* ARRE (auto read reallocation) */
++	0,		/* read retry count */
++	0, 0, 0, 0,
++	0,		/* write retry count */
++	0, 0, 0
++};
++
++static const u8 def_cache_mpage[CACHE_MPAGE_LEN] = {
++	CACHE_MPAGE,
++	CACHE_MPAGE_LEN - 2,
++	0,		/* contains WCE, needs to be 0 for logic */
++	0, 0, 0, 0, 0, 0, 0, 0, 0,
++	0,		/* contains DRA, needs to be 0 for logic */
++	0, 0, 0, 0, 0, 0, 0
++};
++
++static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
++	CONTROL_MPAGE,
++	CONTROL_MPAGE_LEN - 2,
++	2,	/* DSENSE=0, GLTSD=1 */
++	0,	/* [QAM+QERR may be 1, see 05-359r1] */
++	0, 0, 0, 0, 0xff, 0xff,
++	0, 30	/* extended self test time, see 05-359r1 */
++};
+ 
+ 
++static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
++				   void (*done)(struct scsi_cmnd *))
++{
++	ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0);
++	/* "Invalid field in cbd" */
++	done(cmd);
++}
++
+ /**
+  *	ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd.
+  *	@sdev: SCSI device for which BIOS geometry is to be determined
+@@ -78,6 +129,150 @@ int ata_std_bios_param(struct scsi_devic
+ 	return 0;
+ }
+ 
++/**
++ *	ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
++ *	@dev: Device to whom we are issuing command
++ *	@arg: User provided data for issuing command
++ *
++ *	LOCKING:
++ *	Defined by the SCSI layer.  We don't really care.
++ *
++ *	RETURNS:
++ *	Zero on success, negative errno on error.
++ */
++
++int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
++{
++	int rc = 0;
++	u8 scsi_cmd[MAX_COMMAND_SIZE];
++	u8 args[4], *argbuf = NULL;
++	int argsize = 0;
++	struct scsi_request *sreq;
++
++	if (NULL == (void *)arg)
++		return -EINVAL;
++
++	if (copy_from_user(args, arg, sizeof(args)))
++		return -EFAULT;
++
++	sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
++	if (!sreq)
++		return -EINTR;
++
++	memset(scsi_cmd, 0, sizeof(scsi_cmd));
++
++	if (args[3]) {
++		argsize = SECTOR_SIZE * args[3];
++		argbuf = kmalloc(argsize, GFP_KERNEL);
++		if (argbuf == NULL) {
++			rc = -ENOMEM;
++			goto error;
++		}
++
++		scsi_cmd[1]  = (4 << 1); /* PIO Data-in */
++		scsi_cmd[2]  = 0x0e;     /* no off.line or cc, read from dev,
++		                            block count in sector count field */
++		sreq->sr_data_direction = DMA_FROM_DEVICE;
++	} else {
++		scsi_cmd[1]  = (3 << 1); /* Non-data */
++		/* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
++		sreq->sr_data_direction = DMA_NONE;
++	}
++
++	scsi_cmd[0] = ATA_16;
++
++	scsi_cmd[4] = args[2];
++	if (args[0] == WIN_SMART) { /* hack -- ide driver does this too... */
++		scsi_cmd[6]  = args[3];
++		scsi_cmd[8]  = args[1];
++		scsi_cmd[10] = 0x4f;
++		scsi_cmd[12] = 0xc2;
++	} else {
++		scsi_cmd[6]  = args[1];
++	}
++	scsi_cmd[14] = args[0];
++
++	/* Good values for timeout and retries?  Values below
++	   from scsi_ioctl_send_command() for default case... */
++	scsi_wait_req(sreq, scsi_cmd, argbuf, argsize, (10*HZ), 5);
++
++	if (sreq->sr_result) {
++		rc = -EIO;
++		goto error;
++	}
++
++	/* Need code to retrieve data from check condition? */
++
++	if ((argbuf)
++	 && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize))
++		rc = -EFAULT;
++error:
++	scsi_release_request(sreq);
++
++	if (argbuf)
++		kfree(argbuf);
++
++	return rc;
++}
++
++/**
++ *	ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl
++ *	@dev: Device to whom we are issuing command
++ *	@arg: User provided data for issuing command
++ *
++ *	LOCKING:
++ *	Defined by the SCSI layer.  We don't really care.
++ *
++ *	RETURNS:
++ *	Zero on success, negative errno on error.
++ */
++int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
++{
++	int rc = 0;
++	u8 scsi_cmd[MAX_COMMAND_SIZE];
++	u8 args[7];
++	struct scsi_request *sreq;
++
++	if (NULL == (void *)arg)
++		return -EINVAL;
++
++	if (copy_from_user(args, arg, sizeof(args)))
++		return -EFAULT;
++
++	memset(scsi_cmd, 0, sizeof(scsi_cmd));
++	scsi_cmd[0]  = ATA_16;
++	scsi_cmd[1]  = (3 << 1); /* Non-data */
++	/* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
++	scsi_cmd[4]  = args[1];
++	scsi_cmd[6]  = args[2];
++	scsi_cmd[8]  = args[3];
++	scsi_cmd[10] = args[4];
++	scsi_cmd[12] = args[5];
++	scsi_cmd[14] = args[0];
++
++	sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
++	if (!sreq) {
++		rc = -EINTR;
++		goto error;
++	}
++
++	sreq->sr_data_direction = DMA_NONE;
++	/* Good values for timeout and retries?  Values below
++	   from scsi_ioctl_send_command() for default case... */
++	scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5);
++
++	if (sreq->sr_result) {
++		rc = -EIO;
++		goto error;
++	}
++
++	/* Need code to retrieve data from check condition? */
++
++error:
++	scsi_release_request(sreq);
++	return rc;
++}
++
+ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
+ {
+ 	struct ata_port *ap;
+@@ -107,6 +302,16 @@ int ata_scsi_ioctl(struct scsi_device *s
+ 			return -EINVAL;
+ 		return 0;
+ 
++	case HDIO_DRIVE_CMD:
++		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
++			return -EACCES;
++		return ata_cmd_ioctl(scsidev, arg);
++
++	case HDIO_DRIVE_TASK:
++		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
++			return -EACCES;
++		return ata_task_ioctl(scsidev, arg);
++
+ 	default:
+ 		rc = -ENOTTY;
+ 		break;
+@@ -165,24 +370,70 @@ struct ata_queued_cmd *ata_scsi_qc_new(s
+ }
+ 
+ /**
++ *	ata_dump_status - user friendly display of error info
++ *	@id: id of the port in question
++ *	@tf: ptr to filled out taskfile
++ *
++ *	Decode and dump the ATA error/status registers for the user so
++ *	that they have some idea what really happened at the non
++ *	make-believe layer.
++ *
++ *	LOCKING:
++ *	inherited from caller
++ */
++void ata_dump_status(unsigned id, struct ata_taskfile *tf)
++{
++	u8 stat = tf->command, err = tf->feature;
++
++	printk(KERN_WARNING "ata%u: status=0x%02x { ", id, stat);
++	if (stat & ATA_BUSY) {
++		printk("Busy }\n");	/* Data is not valid in this case */
++	} else {
++		if (stat & 0x40)	printk("DriveReady ");
++		if (stat & 0x20)	printk("DeviceFault ");
++		if (stat & 0x10)	printk("SeekComplete ");
++		if (stat & 0x08)	printk("DataRequest ");
++		if (stat & 0x04)	printk("CorrectedError ");
++		if (stat & 0x02)	printk("Index ");
++		if (stat & 0x01)	printk("Error ");
++		printk("}\n");
++
++		if (err) {
++			printk(KERN_WARNING "ata%u: error=0x%02x { ", id, err);
++			if (err & 0x04)		printk("DriveStatusError ");
++			if (err & 0x80) {
++				if (err & 0x04)	printk("BadCRC ");
++				else		printk("Sector ");
++			}
++			if (err & 0x40)		printk("UncorrectableError ");
++			if (err & 0x10)		printk("SectorIdNotFound ");
++			if (err & 0x02)		printk("TrackZeroNotFound ");
++			if (err & 0x01)		printk("AddrMarkNotFound ");
++			printk("}\n");
++		}
++	}
++}
++
++/**
+  *	ata_to_sense_error - convert ATA error to SCSI error
+- *	@qc: Command that we are erroring out
+  *	@drv_stat: value contained in ATA status register
++ *	@drv_err: value contained in ATA error register
++ *	@sk: the sense key we'll fill out
++ *	@asc: the additional sense code we'll fill out
++ *	@ascq: the additional sense code qualifier we'll fill out
+  *
+- *	Converts an ATA error into a SCSI error. While we are at it
+- *	we decode and dump the ATA error for the user so that they
+- *	have some idea what really happened at the non make-believe
+- *	layer.
++ *	Converts an ATA error into a SCSI error.  Fill out pointers to
++ *	SK, ASC, and ASCQ bytes for later use in fixed or descriptor
++ *	format sense blocks.
+  *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+  */
+-
+-void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
++void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, 
++			u8 *ascq)
+ {
+-	struct scsi_cmnd *cmd = qc->scsicmd;
+-	u8 err = 0;
+-	unsigned char *sb = cmd->sense_buffer;
++	int i;
++
+ 	/* Based on the 3ware driver translation table */
+ 	static unsigned char sense_table[][4] = {
+ 		/* BBD|ECC|ID|MAR */
+@@ -223,105 +474,192 @@ void ata_to_sense_error(struct ata_queue
+ 		{0x04, 		RECOVERED_ERROR, 0x11, 0x00},	// Recovered ECC error	  Medium error, recovered
+ 		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
+ 	};
+-	int i = 0;
+-
+-	cmd->result = SAM_STAT_CHECK_CONDITION;
+ 
+ 	/*
+ 	 *	Is this an error we can process/parse
+ 	 */
++	if (drv_stat & ATA_BUSY) {
++		drv_err = 0;	/* Ignore the err bits, they're invalid */
++	}
+ 
+-	if(drv_stat & ATA_ERR)
+-		/* Read the err bits */
+-		err = ata_chk_err(qc->ap);
+-
+-	/* Display the ATA level error info */
+-
+-	printk(KERN_WARNING "ata%u: status=0x%02x { ", qc->ap->id, drv_stat);
+-	if(drv_stat & 0x80)
+-	{
+-		printk("Busy ");
+-		err = 0;	/* Data is not valid in this case */
++	if (drv_err) {
++		/* Look for drv_err */
++		for (i = 0; sense_table[i][0] != 0xFF; i++) {
++			/* Look for best matches first */
++			if ((sense_table[i][0] & drv_err) == 
++			    sense_table[i][0]) {
++				*sk = sense_table[i][1];
++				*asc = sense_table[i][2];
++				*ascq = sense_table[i][3];
++				goto translate_done;
++			}
++		}
++		/* No immediate match */
++		printk(KERN_WARNING "ata%u: no sense translation for "
++		       "error 0x%02x\n", id, drv_err);
+ 	}
+-	else {
+-		if(drv_stat & 0x40)	printk("DriveReady ");
+-		if(drv_stat & 0x20)	printk("DeviceFault ");
+-		if(drv_stat & 0x10)	printk("SeekComplete ");
+-		if(drv_stat & 0x08)	printk("DataRequest ");
+-		if(drv_stat & 0x04)	printk("CorrectedError ");
+-		if(drv_stat & 0x02)	printk("Index ");
+-		if(drv_stat & 0x01)	printk("Error ");
+-	}
+-	printk("}\n");
+-
+-	if(err)
+-	{
+-		printk(KERN_WARNING "ata%u: error=0x%02x { ", qc->ap->id, err);
+-		if(err & 0x04)		printk("DriveStatusError ");
+-		if(err & 0x80)
+-		{
+-			if(err & 0x04)
+-				printk("BadCRC ");
+-			else
+-				printk("Sector ");
++
++	/* Fall back to interpreting status bits */
++	for (i = 0; stat_table[i][0] != 0xFF; i++) {
++		if (stat_table[i][0] & drv_stat) {
++			*sk = stat_table[i][1];
++			*asc = stat_table[i][2];
++			*ascq = stat_table[i][3];
++			goto translate_done;
+ 		}
+-		if(err & 0x40)		printk("UncorrectableError ");
+-		if(err & 0x10)		printk("SectorIdNotFound ");
+-		if(err & 0x02)		printk("TrackZeroNotFound ");
+-		if(err & 0x01)		printk("AddrMarkNotFound ");
+-		printk("}\n");
++	}
++	/* No error?  Undecoded? */
++	printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n", 
++	       id, drv_stat);
++
++	/* For our last chance pick, use medium read error because
++	 * it's much more common than an ATA drive telling you a write
++	 * has failed.
++	 */
++	*sk = MEDIUM_ERROR;
++	*asc = 0x11; /* "unrecovered read error" */
++	*ascq = 0x04; /*  "auto-reallocation failed" */
++
++ translate_done:
++	printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x to "
++	       "SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", id, drv_stat, drv_err,
++	       *sk, *asc, *ascq);
++	return;
++}
++
++/*
++ *	ata_gen_ata_desc_sense - Generate check condition sense block.
++ *	@qc: Command that completed.
++ *
++ *	This function is specific to the ATA descriptor format sense
++ *	block specified for the ATA pass through commands.  Regardless
++ *	of whether the command errored or not, return a sense
++ *	block. Copy all controller registers into the sense
++ *	block. Clear sense key, ASC & ASCQ if there is no error.
++ *
++ *	LOCKING:
++ *	spin_lock_irqsave(host_set lock)
++ */
++void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
++{
++	struct scsi_cmnd *cmd = qc->scsicmd;
++	struct ata_taskfile *tf = &qc->tf;
++	unsigned char *sb = cmd->sense_buffer;
++	unsigned char *desc = sb + 8;
++
++	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+ 
+-		/* Should we dump sector info here too ?? */
++	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
++
++	/*
++	 * Read the controller registers.
++	 */
++	assert(NULL != qc->ap->ops->tf_read);
++	qc->ap->ops->tf_read(qc->ap, tf);
++
++	/*
++	 * Use ata_to_sense_error() to map status register bits
++	 * onto sense key, asc & ascq.
++	 */
++	if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
++		ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
++				   &sb[1], &sb[2], &sb[3]);
++		sb[1] &= 0x0f;
+ 	}
+ 
++	/*
++	 * Sense data is current and format is descriptor.
++	 */
++	sb[0] = 0x72;
+ 
+-	/* Look for err */
+-	while(sense_table[i][0] != 0xFF)
+-	{
+-		/* Look for best matches first */
+-		if((sense_table[i][0] & err) == sense_table[i][0])
+-		{
+-			sb[0] = 0x70;
+-			sb[2] = sense_table[i][1];
+-			sb[7] = 0x0a;
+-			sb[12] = sense_table[i][2];
+-			sb[13] = sense_table[i][3];
+-			return;
+-		}
+-		i++;
++	desc[0] = 0x09;
++
++	/*
++	 * Set length of additional sense data.
++	 * Since we only populate descriptor 0, the total
++	 * length is the same (fixed) length as descriptor 0.
++	 */
++	desc[1] = sb[7] = 14;
++
++	/*
++	 * Copy registers into sense buffer.
++	 */
++	desc[2] = 0x00;
++	desc[3] = tf->feature;	/* == error reg */
++	desc[5] = tf->nsect;
++	desc[7] = tf->lbal;
++	desc[9] = tf->lbam;
++	desc[11] = tf->lbah;
++	desc[12] = tf->device;
++	desc[13] = tf->command; /* == status reg */
++
++	/*
++	 * Fill in Extend bit, and the high order bytes
++	 * if applicable.
++	 */
++	if (tf->flags & ATA_TFLAG_LBA48) {
++		desc[2] |= 0x01;
++		desc[4] = tf->hob_nsect;
++		desc[6] = tf->hob_lbal;
++		desc[8] = tf->hob_lbam;
++		desc[10] = tf->hob_lbah;
+ 	}
+-	/* No immediate match */
+-	if(err)
+-		printk(KERN_DEBUG "ata%u: no sense translation for 0x%02x\n", qc->ap->id, err);
++}
+ 
+-	i = 0;
+-	/* Fall back to interpreting status bits */
+-	while(stat_table[i][0] != 0xFF)
+-	{
+-		if(stat_table[i][0] & drv_stat)
+-		{
+-			sb[0] = 0x70;
+-			sb[2] = stat_table[i][1];
+-			sb[7] = 0x0a;
+-			sb[12] = stat_table[i][2];
+-			sb[13] = stat_table[i][3];
+-			return;
+-		}
+-		i++;
++/**
++ *	ata_gen_fixed_sense - generate a SCSI fixed sense block
++ *	@qc: Command that we are erroring out
++ *
++ *	Leverage ata_to_sense_error() to give us the codes.  Fit our
++ *	LBA in here if there's room.
++ *
++ *	LOCKING:
++ *	inherited from caller
++ */
++void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
++{
++	struct scsi_cmnd *cmd = qc->scsicmd;
++	struct ata_taskfile *tf = &qc->tf;
++	unsigned char *sb = cmd->sense_buffer;
++
++	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
++
++	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
++
++	/*
++	 * Read the controller registers.
++	 */
++	assert(NULL != qc->ap->ops->tf_read);
++	qc->ap->ops->tf_read(qc->ap, tf);
++
++	/*
++	 * Use ata_to_sense_error() to map status register bits
++	 * onto sense key, asc & ascq.
++	 */
++	if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
++		ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
++				   &sb[2], &sb[12], &sb[13]);
++		sb[2] &= 0x0f;
+ 	}
+-	/* No error ?? */
+-	printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat);
+-	/* additional-sense-code[-qualifier] */
+ 
+ 	sb[0] = 0x70;
+-	sb[2] = MEDIUM_ERROR;
+-	sb[7] = 0x0A;
+-	if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
+-		sb[12] = 0x11; /* "unrecovered read error" */
+-		sb[13] = 0x04;
+-	} else {
+-		sb[12] = 0x0C; /* "write error -             */
+-		sb[13] = 0x02; /*  auto-reallocation failed" */
++	sb[7] = 0x0a;
++
++	if (tf->flags & ATA_TFLAG_LBA48) {
++		/* TODO: find solution for LBA48 descriptors */
++	}
++
++	else if (tf->flags & ATA_TFLAG_LBA) {
++		/* A small (28b) LBA will fit in the 32b info field */
++		sb[0] |= 0x80;		/* set valid bit */
++		sb[3] = tf->device & 0x0f;
++		sb[4] = tf->lbah;
++		sb[5] = tf->lbam;
++		sb[6] = tf->lbal;
++	}
++
++	else {
++		/* TODO: C/H/S */
+ 	}
+ }
+ 
+@@ -420,7 +758,7 @@ int ata_scsi_error(struct Scsi_Host *hos
+  */
+ 
+ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
+-					     u8 *scsicmd)
++					     const u8 *scsicmd)
+ {
+ 	struct ata_taskfile *tf = &qc->tf;
+ 
+@@ -430,15 +768,26 @@ static unsigned int ata_scsi_start_stop_
+ 		;	/* ignore IMMED bit, violates sat-r05 */
+ 	}
+ 	if (scsicmd[4] & 0x2)
+-		return 1;	/* LOEJ bit set not supported */
++		goto invalid_fld;       /* LOEJ bit set not supported */
+ 	if (((scsicmd[4] >> 4) & 0xf) != 0)
+-		return 1;	/* power conditions not supported */
++		goto invalid_fld;       /* power conditions not supported */
+ 	if (scsicmd[4] & 0x1) {
+ 		tf->nsect = 1;	/* 1 sector, lba=0 */
+-		tf->lbah = 0x0;
+-		tf->lbam = 0x0;
+-		tf->lbal = 0x0;
+-		tf->device |= ATA_LBA;
++
++		if (qc->dev->flags & ATA_DFLAG_LBA) {
++			qc->tf.flags |= ATA_TFLAG_LBA;
++
++			tf->lbah = 0x0;
++			tf->lbam = 0x0;
++			tf->lbal = 0x0;
++			tf->device |= ATA_LBA;
++		} else {
++			/* CHS */
++			tf->lbal = 0x1; /* sect */
++			tf->lbam = 0x0; /* cyl low */
++			tf->lbah = 0x0; /* cyl high */
++		}
++
+ 		tf->command = ATA_CMD_VERIFY;	/* READ VERIFY */
+ 	} else {
+ 		tf->nsect = 0;	/* time period value (0 implies now) */
+@@ -453,6 +802,11 @@ static unsigned int ata_scsi_start_stop_
+ 	 */
+ 
+ 	return 0;
++
++invalid_fld:
++	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
++	/* "Invalid field in cbd" */
++	return 1;
+ }
+ 
+ 
+@@ -471,14 +825,14 @@ static unsigned int ata_scsi_start_stop_
+  *	Zero on success, non-zero on error.
+  */
+ 
+-static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
++static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+ {
+ 	struct ata_taskfile *tf = &qc->tf;
+ 
+ 	tf->flags |= ATA_TFLAG_DEVICE;
+ 	tf->protocol = ATA_PROT_NODATA;
+ 
+-	if ((tf->flags & ATA_TFLAG_LBA48) &&
++	if ((qc->dev->flags & ATA_DFLAG_LBA48) &&
+ 	    (ata_id_has_flush_ext(qc->dev->id)))
+ 		tf->command = ATA_CMD_FLUSH_EXT;
+ 	else
+@@ -488,6 +842,99 @@ static unsigned int ata_scsi_flush_xlat(
+ }
+ 
+ /**
++ *	scsi_6_lba_len - Get LBA and transfer length
++ *	@scsicmd: SCSI command to translate
++ *
++ *	Calculate LBA and transfer length for 6-byte commands.
++ *
++ *	RETURNS:
++ *	@plba: the LBA
++ *	@plen: the transfer length
++ */
++
++static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
++{
++	u64 lba = 0;
++	u32 len = 0;
++
++	VPRINTK("six-byte command\n");
++
++	lba |= ((u64)scsicmd[2]) << 8;
++	lba |= ((u64)scsicmd[3]);
++
++	len |= ((u32)scsicmd[4]);
++
++	*plba = lba;
++	*plen = len;
++}
++
++/**
++ *	scsi_10_lba_len - Get LBA and transfer length
++ *	@scsicmd: SCSI command to translate
++ *
++ *	Calculate LBA and transfer length for 10-byte commands.
++ *
++ *	RETURNS:
++ *	@plba: the LBA
++ *	@plen: the transfer length
++ */
++
++static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
++{
++	u64 lba = 0;
++	u32 len = 0;
++
++	VPRINTK("ten-byte command\n");
++
++	lba |= ((u64)scsicmd[2]) << 24;
++	lba |= ((u64)scsicmd[3]) << 16;
++	lba |= ((u64)scsicmd[4]) << 8;
++	lba |= ((u64)scsicmd[5]);
++
++	len |= ((u32)scsicmd[7]) << 8;
++	len |= ((u32)scsicmd[8]);
++
++	*plba = lba;
++	*plen = len;
++}
++
++/**
++ *	scsi_16_lba_len - Get LBA and transfer length
++ *	@scsicmd: SCSI command to translate
++ *
++ *	Calculate LBA and transfer length for 16-byte commands.
++ *
++ *	RETURNS:
++ *	@plba: the LBA
++ *	@plen: the transfer length
++ */
++
++static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
++{
++	u64 lba = 0;
++	u32 len = 0;
++
++	VPRINTK("sixteen-byte command\n");
++
++	lba |= ((u64)scsicmd[2]) << 56;
++	lba |= ((u64)scsicmd[3]) << 48;
++	lba |= ((u64)scsicmd[4]) << 40;
++	lba |= ((u64)scsicmd[5]) << 32;
++	lba |= ((u64)scsicmd[6]) << 24;
++	lba |= ((u64)scsicmd[7]) << 16;
++	lba |= ((u64)scsicmd[8]) << 8;
++	lba |= ((u64)scsicmd[9]);
++
++	len |= ((u32)scsicmd[10]) << 24;
++	len |= ((u32)scsicmd[11]) << 16;
++	len |= ((u32)scsicmd[12]) << 8;
++	len |= ((u32)scsicmd[13]);
++
++	*plba = lba;
++	*plen = len;
++}
++
++/**
+  *	ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
+  *	@qc: Storage for translated ATA taskfile
+  *	@scsicmd: SCSI command to translate
+@@ -501,82 +948,110 @@ static unsigned int ata_scsi_flush_xlat(
+  *	Zero on success, non-zero on error.
+  */
+ 
+-static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
++static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+ {
+ 	struct ata_taskfile *tf = &qc->tf;
+-	unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
++	struct ata_device *dev = qc->dev;
+ 	u64 dev_sectors = qc->dev->n_sectors;
+-	u64 sect = 0;
+-	u32 n_sect = 0;
++	u64 block;
++	u32 n_block;
+ 
+ 	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ 	tf->protocol = ATA_PROT_NODATA;
+-	tf->device |= ATA_LBA;
+-
+-	if (scsicmd[0] == VERIFY) {
+-		sect |= ((u64)scsicmd[2]) << 24;
+-		sect |= ((u64)scsicmd[3]) << 16;
+-		sect |= ((u64)scsicmd[4]) << 8;
+-		sect |= ((u64)scsicmd[5]);
+-
+-		n_sect |= ((u32)scsicmd[7]) << 8;
+-		n_sect |= ((u32)scsicmd[8]);
+-	}
+-
+-	else if (scsicmd[0] == VERIFY_16) {
+-		sect |= ((u64)scsicmd[2]) << 56;
+-		sect |= ((u64)scsicmd[3]) << 48;
+-		sect |= ((u64)scsicmd[4]) << 40;
+-		sect |= ((u64)scsicmd[5]) << 32;
+-		sect |= ((u64)scsicmd[6]) << 24;
+-		sect |= ((u64)scsicmd[7]) << 16;
+-		sect |= ((u64)scsicmd[8]) << 8;
+-		sect |= ((u64)scsicmd[9]);
+-
+-		n_sect |= ((u32)scsicmd[10]) << 24;
+-		n_sect |= ((u32)scsicmd[11]) << 16;
+-		n_sect |= ((u32)scsicmd[12]) << 8;
+-		n_sect |= ((u32)scsicmd[13]);
+-	}
+ 
++	if (scsicmd[0] == VERIFY)
++		scsi_10_lba_len(scsicmd, &block, &n_block);
++	else if (scsicmd[0] == VERIFY_16)
++		scsi_16_lba_len(scsicmd, &block, &n_block);
+ 	else
+-		return 1;
++		goto invalid_fld;
+ 
+-	if (!n_sect)
+-		return 1;
+-	if (sect >= dev_sectors)
+-		return 1;
+-	if ((sect + n_sect) > dev_sectors)
+-		return 1;
+-	if (lba48) {
+-		if (n_sect > (64 * 1024))
+-			return 1;
+-	} else {
+-		if (n_sect > 256)
+-			return 1;
+-	}
++	if (!n_block)
++		goto nothing_to_do;
++	if (block >= dev_sectors)
++		goto out_of_range;
++	if ((block + n_block) > dev_sectors)
++		goto out_of_range;
++
++	if (dev->flags & ATA_DFLAG_LBA) {
++		tf->flags |= ATA_TFLAG_LBA;
++
++		if (dev->flags & ATA_DFLAG_LBA48) {
++			if (n_block > (64 * 1024))
++				goto invalid_fld;
++
++			/* use LBA48 */
++			tf->flags |= ATA_TFLAG_LBA48;
++			tf->command = ATA_CMD_VERIFY_EXT;
++
++			tf->hob_nsect = (n_block >> 8) & 0xff;
++
++			tf->hob_lbah = (block >> 40) & 0xff;
++			tf->hob_lbam = (block >> 32) & 0xff;
++			tf->hob_lbal = (block >> 24) & 0xff;
++		} else {
++			if (n_block > 256)
++				goto invalid_fld;
+ 
+-	if (lba48) {
+-		tf->command = ATA_CMD_VERIFY_EXT;
++			/* use LBA28 */
++			tf->command = ATA_CMD_VERIFY;
+ 
+-		tf->hob_nsect = (n_sect >> 8) & 0xff;
++			tf->device |= (block >> 24) & 0xf;
++		}
+ 
+-		tf->hob_lbah = (sect >> 40) & 0xff;
+-		tf->hob_lbam = (sect >> 32) & 0xff;
+-		tf->hob_lbal = (sect >> 24) & 0xff;
++		tf->nsect = n_block & 0xff;
++
++		tf->lbah = (block >> 16) & 0xff;
++		tf->lbam = (block >> 8) & 0xff;
++		tf->lbal = block & 0xff;
++
++		tf->device |= ATA_LBA;
+ 	} else {
+-		tf->command = ATA_CMD_VERIFY;
++		/* CHS */
++		u32 sect, head, cyl, track;
++
++		if (n_block > 256)
++			goto invalid_fld;
+ 
+-		tf->device |= (sect >> 24) & 0xf;
++		/* Convert LBA to CHS */
++		track = (u32)block / dev->sectors;
++		cyl   = track / dev->heads;
++		head  = track % dev->heads;
++		sect  = (u32)block % dev->sectors + 1;
++
++		DPRINTK("block %u track %u cyl %u head %u sect %u\n",
++			(u32)block, track, cyl, head, sect);
++		
++		/* Check whether the converted CHS can fit. 
++		   Cylinder: 0-65535 
++		   Head: 0-15
++		   Sector: 1-255*/
++		if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) 
++			goto out_of_range;
++		
++		tf->command = ATA_CMD_VERIFY;
++		tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
++		tf->lbal = sect;
++		tf->lbam = cyl;
++		tf->lbah = cyl >> 8;
++		tf->device |= head;
+ 	}
+ 
+-	tf->nsect = n_sect & 0xff;
++	return 0;
+ 
+-	tf->lbah = (sect >> 16) & 0xff;
+-	tf->lbam = (sect >> 8) & 0xff;
+-	tf->lbal = sect & 0xff;
++invalid_fld:
++	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
++	/* "Invalid field in cbd" */
++	return 1;
+ 
+-	return 0;
++out_of_range:
++	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
++	/* "Logical Block Address out of range" */
++	return 1;
++
++nothing_to_do:
++	qc->scsicmd->result = SAM_STAT_GOOD;
++	return 1;
+ }
+ 
+ /**
+@@ -599,117 +1074,175 @@ static unsigned int ata_scsi_verify_xlat
+  *	Zero on success, non-zero on error.
+  */
+ 
+-static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
++static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+ {
+ 	struct ata_taskfile *tf = &qc->tf;
+-	unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
++	struct ata_device *dev = qc->dev;
++	u64 block;
++	u32 n_block;
+ 
+ 	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+-	tf->protocol = qc->dev->xfer_protocol;
+-	tf->device |= ATA_LBA;
+ 
+-	if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 ||
+-	    scsicmd[0] == READ_16) {
+-		tf->command = qc->dev->read_cmd;
+-	} else {
+-		tf->command = qc->dev->write_cmd;
++	if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
++	    scsicmd[0] == WRITE_16)
+ 		tf->flags |= ATA_TFLAG_WRITE;
++
++	/* Calculate the SCSI LBA and transfer length. */
++	switch (scsicmd[0]) {
++	case READ_10:
++	case WRITE_10:
++		scsi_10_lba_len(scsicmd, &block, &n_block);
++		break;
++	case READ_6:
++	case WRITE_6:
++		scsi_6_lba_len(scsicmd, &block, &n_block);
++
++		/* for 6-byte r/w commands, transfer length 0
++		 * means 256 blocks of data, not 0 block.
++		 */
++		if (!n_block)
++			n_block = 256;
++		break;
++	case READ_16:
++	case WRITE_16:
++		scsi_16_lba_len(scsicmd, &block, &n_block);
++		break;
++	default:
++		DPRINTK("no-byte command\n");
++		goto invalid_fld;
+ 	}
+ 
+-	if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
+-		if (lba48) {
+-			tf->hob_nsect = scsicmd[7];
+-			tf->hob_lbal = scsicmd[2];
++	/* Check and compose ATA command */
++	if (!n_block)
++		/* For 10-byte and 16-byte SCSI R/W commands, transfer
++		 * length 0 means transfer 0 block of data.
++		 * However, for ATA R/W commands, sector count 0 means
++		 * 256 or 65536 sectors, not 0 sectors as in SCSI.
++		 */
++		goto nothing_to_do;
+ 
+-			qc->nsect = ((unsigned int)scsicmd[7] << 8) |
+-					scsicmd[8];
+-		} else {
+-			/* if we don't support LBA48 addressing, the request
+-			 * -may- be too large. */
+-			if ((scsicmd[2] & 0xf0) || scsicmd[7])
+-				return 1;
++	if (dev->flags & ATA_DFLAG_LBA) {
++		tf->flags |= ATA_TFLAG_LBA;
+ 
+-			/* stores LBA27:24 in lower 4 bits of device reg */
+-			tf->device |= scsicmd[2];
++		if (dev->flags & ATA_DFLAG_LBA48) {
++			/* The request -may- be too large for LBA48. */
++			if ((block >> 48) || (n_block > 65536))
++				goto out_of_range;
+ 
+-			qc->nsect = scsicmd[8];
+-		}
++			/* use LBA48 */
++			tf->flags |= ATA_TFLAG_LBA48;
+ 
+-		tf->nsect = scsicmd[8];
+-		tf->lbal = scsicmd[5];
+-		tf->lbam = scsicmd[4];
+-		tf->lbah = scsicmd[3];
++			tf->hob_nsect = (n_block >> 8) & 0xff;
+ 
+-		VPRINTK("ten-byte command\n");
+-		if (qc->nsect == 0) /* we don't support length==0 cmds */
+-			return 1;
+-		return 0;
+-	}
++			tf->hob_lbah = (block >> 40) & 0xff;
++			tf->hob_lbam = (block >> 32) & 0xff;
++			tf->hob_lbal = (block >> 24) & 0xff;
++		} else { 
++			/* use LBA28 */
+ 
+-	if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
+-		qc->nsect = tf->nsect = scsicmd[4];
+-		if (!qc->nsect) {
+-			qc->nsect = 256;
+-			if (lba48)
+-				tf->hob_nsect = 1;
++			/* The request -may- be too large for LBA28. */
++			if ((block >> 28) || (n_block > 256))
++				goto out_of_range;
++
++			tf->device |= (block >> 24) & 0xf;
+ 		}
+ 
+-		tf->lbal = scsicmd[3];
+-		tf->lbam = scsicmd[2];
+-		tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */
++		ata_rwcmd_protocol(qc);
+ 
+-		VPRINTK("six-byte command\n");
+-		return 0;
+-	}
++		qc->nsect = n_block;
++		tf->nsect = n_block & 0xff;
+ 
+-	if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
+-		/* rule out impossible LBAs and sector counts */
+-		if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11])
+-			return 1;
+-
+-		if (lba48) {
+-			tf->hob_nsect = scsicmd[12];
+-			tf->hob_lbal = scsicmd[6];
+-			tf->hob_lbam = scsicmd[5];
+-			tf->hob_lbah = scsicmd[4];
++		tf->lbah = (block >> 16) & 0xff;
++		tf->lbam = (block >> 8) & 0xff;
++		tf->lbal = block & 0xff;
+ 
+-			qc->nsect = ((unsigned int)scsicmd[12] << 8) |
+-					scsicmd[13];
+-		} else {
+-			/* once again, filter out impossible non-zero values */
+-			if (scsicmd[4] || scsicmd[5] || scsicmd[12] ||
+-			    (scsicmd[6] & 0xf0))
+-				return 1;
+-
+-			/* stores LBA27:24 in lower 4 bits of device reg */
+-			tf->device |= scsicmd[6];
++		tf->device |= ATA_LBA;
++	} else { 
++		/* CHS */
++		u32 sect, head, cyl, track;
++
++		/* The request -may- be too large for CHS addressing. */
++		if ((block >> 28) || (n_block > 256))
++			goto out_of_range;
++
++		ata_rwcmd_protocol(qc);
++
++		/* Convert LBA to CHS */
++		track = (u32)block / dev->sectors;
++		cyl   = track / dev->heads;
++		head  = track % dev->heads;
++		sect  = (u32)block % dev->sectors + 1;
++
++		DPRINTK("block %u track %u cyl %u head %u sect %u\n",
++			(u32)block, track, cyl, head, sect);
++
++		/* Check whether the converted CHS can fit. 
++		   Cylinder: 0-65535 
++		   Head: 0-15
++		   Sector: 1-255*/
++		if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
++			goto out_of_range;
++
++		qc->nsect = n_block;
++		tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
++		tf->lbal = sect;
++		tf->lbam = cyl;
++		tf->lbah = cyl >> 8;
++		tf->device |= head;
++	}
+ 
+-			qc->nsect = scsicmd[13];
+-		}
++	return 0;
+ 
+-		tf->nsect = scsicmd[13];
+-		tf->lbal = scsicmd[9];
+-		tf->lbam = scsicmd[8];
+-		tf->lbah = scsicmd[7];
++invalid_fld:
++	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
++	/* "Invalid field in cbd" */
++	return 1;
+ 
+-		VPRINTK("sixteen-byte command\n");
+-		if (qc->nsect == 0) /* we don't support length==0 cmds */
+-			return 1;
+-		return 0;
+-	}
++out_of_range:
++	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
++	/* "Logical Block Address out of range" */
++	return 1;
+ 
+-	DPRINTK("no-byte command\n");
++nothing_to_do:
++	qc->scsicmd->result = SAM_STAT_GOOD;
+ 	return 1;
+ }
+ 
+-static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
++static int ata_scsi_qc_complete(struct ata_queued_cmd *qc,
++				unsigned int err_mask)
+ {
+ 	struct scsi_cmnd *cmd = qc->scsicmd;
++	u8 *cdb = cmd->cmnd;
++ 	int need_sense = (err_mask != 0);
+ 
+-	if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
+-		ata_to_sense_error(qc, drv_stat);
+-	else
+-		cmd->result = SAM_STAT_GOOD;
++	/* For ATA pass thru (SAT) commands, generate a sense block if
++	 * user mandated it or if there's an error.  Note that if we
++	 * generate because the user forced us to, a check condition
++	 * is generated and the ATA register values are returned
++	 * whether the command completed successfully or not. If there
++	 * was no error, SK, ASC and ASCQ will all be zero.
++	 */
++	if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
++ 	    ((cdb[2] & 0x20) || need_sense)) {
++ 		ata_gen_ata_desc_sense(qc);
++	} else {
++		if (!need_sense) {
++			cmd->result = SAM_STAT_GOOD;
++		} else {
++			/* TODO: decide which descriptor format to use
++			 * for 48b LBA devices and call that here
++			 * instead of the fixed desc, which is only
++			 * good for smaller LBA (and maybe CHS?)
++			 * devices.
++			 */
++			ata_gen_fixed_sense(qc);
++		}
++	}
++
++	if (need_sense) {
++		/* The ata_gen_..._sense routines fill in tf */
++		ata_dump_status(qc->ap->id, &qc->tf);
++	}
+ 
+ 	qc->scsidone(cmd);
+ 
+@@ -731,6 +1264,12 @@ static int ata_scsi_qc_complete(struct a
+  *	This function sets up an ata_queued_cmd structure for the
+  *	SCSI command, and sends that ata_queued_cmd to the hardware.
+  *
++ *	The xlat_func argument (actor) returns 0 if ready to execute
++ *	ATA command, else 1 to finish translation. If 1 is returned
++ *	then cmd->result (and possibly cmd->sense_buffer) are assumed
++ *	to be set reflecting an error condition or clean (early)
++ *	termination.
++ *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+  */
+@@ -747,7 +1286,7 @@ static void ata_scsi_translate(struct at
+ 
+ 	qc = ata_scsi_qc_new(ap, dev, cmd, done);
+ 	if (!qc)
+-		return;
++		goto err_mem;
+ 
+ 	/* data is present; dma-map it */
+ 	if (cmd->sc_data_direction == DMA_FROM_DEVICE ||
+@@ -755,7 +1294,7 @@ static void ata_scsi_translate(struct at
+ 		if (unlikely(cmd->request_bufflen < 1)) {
+ 			printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n",
+ 			       ap->id, dev->devno);
+-			goto err_out;
++			goto err_did;
+ 		}
+ 
+ 		if (cmd->use_sg)
+@@ -770,19 +1309,28 @@ static void ata_scsi_translate(struct at
+ 	qc->complete_fn = ata_scsi_qc_complete;
+ 
+ 	if (xlat_func(qc, scsicmd))
+-		goto err_out;
++		goto early_finish;
+ 
+ 	/* select device, send command to hardware */
+ 	if (ata_qc_issue(qc))
+-		goto err_out;
++		goto err_did;
+ 
+ 	VPRINTK("EXIT\n");
+ 	return;
+ 
+-err_out:
++early_finish:
++        ata_qc_free(qc);
++	done(cmd);
++	DPRINTK("EXIT - early finish (good or error)\n");
++	return;
++
++err_did:
+ 	ata_qc_free(qc);
+-	ata_bad_cdb(cmd, done);
+-	DPRINTK("EXIT - badcmd\n");
++err_mem:
++	cmd->result = (DID_ERROR << 16);
++	done(cmd);
++	DPRINTK("EXIT - internal\n");
++	return;
+ }
+ 
+ /**
+@@ -849,7 +1397,8 @@ static inline void ata_scsi_rbuf_put(str
+  *	Mapping the response buffer, calling the command's handler,
+  *	and handling the handler's return value.  This return value
+  *	indicates whether the handler wishes the SCSI command to be
+- *	completed successfully, or not.
++ *	completed successfully (0), or not (in which case cmd->result
++ *	and sense buffer are assumed to be set).
+  *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+@@ -868,12 +1417,9 @@ void ata_scsi_rbuf_fill(struct ata_scsi_
+ 	rc = actor(args, rbuf, buflen);
+ 	ata_scsi_rbuf_put(cmd, rbuf);
+ 
+-	if (rc)
+-		ata_bad_cdb(cmd, args->done);
+-	else {
++	if (rc == 0)
+ 		cmd->result = SAM_STAT_GOOD;
+-		args->done(cmd);
+-	}
++	args->done(cmd);
+ }
+ 
+ /**
+@@ -1087,13 +1633,9 @@ static void ata_msense_push(u8 **ptr_io,
+ static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
+ 				       const u8 *last)
+ {
+-	u8 page[] = {
+-		0x8,				/* page code */
+-		0x12,				/* page length */
+-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 10 zeroes */
+-		0, 0, 0, 0, 0, 0, 0, 0		/* 8 zeroes */
+-	};
++	u8 page[CACHE_MPAGE_LEN];
+ 
++	memcpy(page, def_cache_mpage, sizeof(page));
+ 	if (ata_id_wcache_enabled(id))
+ 		page[2] |= (1 << 2);	/* write cache enable */
+ 	if (!ata_id_rahead_enabled(id))
+@@ -1117,15 +1659,9 @@ static unsigned int ata_msense_caching(u
+ 
+ static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
+ {
+-	const u8 page[] = {0xa, 0xa, 6, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 30};
+-
+-	/* byte 2: set the descriptor format sense data bit (bit 2)
+-	 * since we need to support returning this format for SAT
+-	 * commands and any SCSI commands against a 48b LBA device.
+-	 */
+-
+-	ata_msense_push(ptr_io, last, page, sizeof(page));
+-	return sizeof(page);
++	ata_msense_push(ptr_io, last, def_control_mpage,
++			sizeof(def_control_mpage));
++	return sizeof(def_control_mpage);
+ }
+ 
+ /**
+@@ -1142,15 +1678,10 @@ static unsigned int ata_msense_ctl_mode(
+ 
+ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
+ {
+-	const u8 page[] = {
+-		0x1,			  /* page code */
+-		0xa,			  /* page length */
+-		(1 << 7) | (1 << 6),	  /* note auto r/w reallocation */
+-		0, 0, 0, 0, 0, 0, 0, 0, 0 /* 9 zeroes */
+-	};
+ 
+-	ata_msense_push(ptr_io, last, page, sizeof(page));
+-	return sizeof(page);
++	ata_msense_push(ptr_io, last, def_rw_recovery_mpage,
++			sizeof(def_rw_recovery_mpage));
++	return sizeof(def_rw_recovery_mpage);
+ }
+ 
+ /**
+@@ -1159,7 +1690,9 @@ static unsigned int ata_msense_rw_recove
+  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+  *	@buflen: Response buffer length.
+  *
+- *	Simulate MODE SENSE commands.
++ *	Simulate MODE SENSE commands. Assume this is invoked for direct
++ *	access devices (e.g. disks) only. There should be no block
++ *	descriptor for other device types.
+  *
+  *	LOCKING:
+  *	spin_lock_irqsave(host_set lock)
+@@ -1169,61 +1702,115 @@ unsigned int ata_scsiop_mode_sense(struc
+ 				  unsigned int buflen)
+ {
+ 	u8 *scsicmd = args->cmd->cmnd, *p, *last;
+-	unsigned int page_control, six_byte, output_len;
++	const u8 sat_blk_desc[] = {
++		0, 0, 0, 0,	/* number of blocks: sat unspecified */
++		0,
++		0, 0x2, 0x0	/* block length: 512 bytes */
++	};
++	u8 pg, spg;
++	unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen;
+ 
+ 	VPRINTK("ENTER\n");
+ 
+ 	six_byte = (scsicmd[0] == MODE_SENSE);
+-
+-	/* we only support saved and current values (which we treat
+-	 * in the same manner)
++	ebd = !(scsicmd[1] & 0x8);      /* dbd bit inverted == edb */
++	/*
++	 * LLBA bit in msense(10) ignored (compliant)
+ 	 */
++
+ 	page_control = scsicmd[2] >> 6;
+-	if ((page_control != 0) && (page_control != 3))
+-		return 1;
++	switch (page_control) {
++	case 0: /* current */
++		break;  /* supported */
++	case 3: /* saved */
++		goto saving_not_supp;
++	case 1: /* changeable */
++	case 2: /* defaults */
++	default:
++		goto invalid_fld;
++	}
+ 
+-	if (six_byte)
+-		output_len = 4;
+-	else
+-		output_len = 8;
++	if (six_byte) {
++		output_len = 4 + (ebd ? 8 : 0);
++		alloc_len = scsicmd[4];
++	} else {
++		output_len = 8 + (ebd ? 8 : 0);
++		alloc_len = (scsicmd[7] << 8) + scsicmd[8];
++	}
++	minlen = (alloc_len < buflen) ? alloc_len : buflen;
+ 
+ 	p = rbuf + output_len;
+-	last = rbuf + buflen - 1;
++	last = rbuf + minlen - 1;
++
++	pg = scsicmd[2] & 0x3f;
++	spg = scsicmd[3];
++	/*
++	 * No mode subpages supported (yet) but asking for _all_
++	 * subpages may be valid
++	 */
++	if (spg && (spg != ALL_SUB_MPAGES))
++		goto invalid_fld;
+ 
+-	switch(scsicmd[2] & 0x3f) {
+-	case 0x01:		/* r/w error recovery */
++	switch(pg) {
++	case RW_RECOVERY_MPAGE:
+ 		output_len += ata_msense_rw_recovery(&p, last);
+ 		break;
+ 
+-	case 0x08:		/* caching */
++	case CACHE_MPAGE:
+ 		output_len += ata_msense_caching(args->id, &p, last);
+ 		break;
+ 
+-	case 0x0a: {		/* control mode */
++	case CONTROL_MPAGE: {
+ 		output_len += ata_msense_ctl_mode(&p, last);
+ 		break;
+ 		}
+ 
+-	case 0x3f:		/* all pages */
++	case ALL_MPAGES:
+ 		output_len += ata_msense_rw_recovery(&p, last);
+ 		output_len += ata_msense_caching(args->id, &p, last);
+ 		output_len += ata_msense_ctl_mode(&p, last);
+ 		break;
+ 
+ 	default:		/* invalid page code */
+-		return 1;
++		goto invalid_fld;
+ 	}
+ 
++	if (minlen < 1)
++		return 0;
+ 	if (six_byte) {
+ 		output_len--;
+ 		rbuf[0] = output_len;
++		if (ebd) {
++			if (minlen > 3)
++				rbuf[3] = sizeof(sat_blk_desc);
++			if (minlen > 11)
++				memcpy(rbuf + 4, sat_blk_desc,
++				       sizeof(sat_blk_desc));
++		}
+ 	} else {
+ 		output_len -= 2;
+ 		rbuf[0] = output_len >> 8;
+-		rbuf[1] = output_len;
++		if (minlen > 1)
++			rbuf[1] = output_len;
++		if (ebd) {
++			if (minlen > 7)
++				rbuf[7] = sizeof(sat_blk_desc);
++			if (minlen > 15)
++				memcpy(rbuf + 8, sat_blk_desc,
++				       sizeof(sat_blk_desc));
++		}
+ 	}
+-
+ 	return 0;
++
++invalid_fld:
++	ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x24, 0x0);
++	/* "Invalid field in cbd" */
++	return 1;
++
++saving_not_supp:
++	ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x39, 0x0);
++	 /* "Saving parameters not supported" */
++	return 1;
+ }
+ 
+ /**
+@@ -1246,10 +1833,20 @@ unsigned int ata_scsiop_read_cap(struct 
+ 
+ 	VPRINTK("ENTER\n");
+ 
+-	if (ata_id_has_lba48(args->id))
+-		n_sectors = ata_id_u64(args->id, 100);
+-	else
+-		n_sectors = ata_id_u32(args->id, 60);
++	if (ata_id_has_lba(args->id)) {
++		if (ata_id_has_lba48(args->id))
++			n_sectors = ata_id_u64(args->id, 100);
++		else
++			n_sectors = ata_id_u32(args->id, 60);
++	} else {
++		/* CHS default translation */
++		n_sectors = args->id[1] * args->id[3] * args->id[6];
++
++		if (ata_id_current_chs_valid(args->id))
++			/* CHS current translation */
++			n_sectors = ata_id_u32(args->id, 57);
++	}
++
+ 	n_sectors--;		/* ATA TotalUserSectors - 1 */
+ 
+ 	if (args->cmd->cmnd[0] == READ_CAPACITY) {
+@@ -1313,6 +1910,34 @@ unsigned int ata_scsiop_report_luns(stru
+ }
+ 
+ /**
++ *	ata_scsi_set_sense - Set SCSI sense data and status
++ *	@cmd: SCSI request to be handled
++ *	@sk: SCSI-defined sense key
++ *	@asc: SCSI-defined additional sense code
++ *	@ascq: SCSI-defined additional sense code qualifier
++ *
++ *	Helper function that builds a valid fixed format, current
++ *	response code and the given sense key (sk), additional sense
++ *	code (asc) and additional sense code qualifier (ascq) with
++ *	a SCSI command status of %SAM_STAT_CHECK_CONDITION and
++ *	DRIVER_SENSE set in the upper bits of scsi_cmnd::result .
++ *
++ *	LOCKING:
++ *	Not required
++ */
++
++void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
++{
++	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
++
++	cmd->sense_buffer[0] = 0x70;	/* fixed format, current */
++	cmd->sense_buffer[2] = sk;
++	cmd->sense_buffer[7] = 18 - 8;	/* additional sense length */
++	cmd->sense_buffer[12] = asc;
++	cmd->sense_buffer[13] = ascq;
++}
++
++/**
+  *	ata_scsi_badcmd - End a SCSI request with an error
+  *	@cmd: SCSI request to be handled
+  *	@done: SCSI command completion function
+@@ -1330,30 +1955,89 @@ unsigned int ata_scsiop_report_luns(stru
+ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 asc, u8 ascq)
+ {
+ 	DPRINTK("ENTER\n");
+-	cmd->result = SAM_STAT_CHECK_CONDITION;
+-
+-	cmd->sense_buffer[0] = 0x70;
+-	cmd->sense_buffer[2] = ILLEGAL_REQUEST;
+-	cmd->sense_buffer[7] = 14 - 8;	/* addnl. sense len. FIXME: correct? */
+-	cmd->sense_buffer[12] = asc;
+-	cmd->sense_buffer[13] = ascq;
++	ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, asc, ascq);
+ 
+ 	done(cmd);
+ }
+ 
+-static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
++void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
++			 struct scsi_cmnd *cmd)
++{
++	DECLARE_COMPLETION(wait);
++	struct ata_queued_cmd *qc;
++	unsigned long flags;
++	int rc;
++
++	DPRINTK("ATAPI request sense\n");
++
++	qc = ata_qc_new_init(ap, dev);
++	BUG_ON(qc == NULL);
++
++	/* FIXME: is this needed? */
++	memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
++
++	ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
++	qc->dma_dir = DMA_FROM_DEVICE;
++
++	memset(&qc->cdb, 0, ap->cdb_len);
++	qc->cdb[0] = REQUEST_SENSE;
++	qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
++
++	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
++	qc->tf.command = ATA_CMD_PACKET;
++
++	qc->tf.protocol = ATA_PROT_ATAPI;
++	qc->tf.lbam = (8 * 1024) & 0xff;
++	qc->tf.lbah = (8 * 1024) >> 8;
++	qc->nbytes = SCSI_SENSE_BUFFERSIZE;
++
++	qc->waiting = &wait;
++	qc->complete_fn = ata_qc_complete_noop;
++
++	spin_lock_irqsave(&ap->host_set->lock, flags);
++	rc = ata_qc_issue(qc);
++	spin_unlock_irqrestore(&ap->host_set->lock, flags);
++
++	if (rc)
++		ata_port_disable(ap);
++	else
++		wait_for_completion(&wait);
++
++	DPRINTK("EXIT\n");
++}
++
++static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+ {
+ 	struct scsi_cmnd *cmd = qc->scsicmd;
+ 
+-	if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
++	VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
++
++	if (unlikely(err_mask & AC_ERR_DEV)) {
+ 		DPRINTK("request check condition\n");
+ 
++		/* FIXME: command completion with check condition
++		 * but no sense causes the error handler to run,
++		 * which then issues REQUEST SENSE, fills in the sense 
++		 * buffer, and completes the command (for the second
++		 * time).  We need to issue REQUEST SENSE some other
++		 * way, to avoid completing the command twice.
++		 */
+ 		cmd->result = SAM_STAT_CHECK_CONDITION;
+ 
+ 		qc->scsidone(cmd);
+ 
+ 		return 1;
+-	} else {
++	}
++
++	else if (unlikely(err_mask))
++		/* FIXME: not quite right; we don't want the
++		 * translation of taskfile registers into
++		 * a sense descriptors, since that's only
++		 * correct for ATA, not ATAPI
++		 */
++		ata_gen_ata_desc_sense(qc);
++
++	else {
+ 		u8 *scsicmd = cmd->cmnd;
+ 
+ 		if (scsicmd[0] == INQUIRY) {
+@@ -1361,15 +2045,30 @@ static int atapi_qc_complete(struct ata_
+ 			unsigned int buflen;
+ 
+ 			buflen = ata_scsi_rbuf_get(cmd, &buf);
+-			buf[2] = 0x5;
+-			buf[3] = (buf[3] & 0xf0) | 2;
++
++	/* ATAPI devices typically report zero for their SCSI version,
++	 * and sometimes deviate from the spec WRT response data
++	 * format.  If SCSI version is reported as zero like normal,
++	 * then we make the following fixups:  1) Fake MMC-5 version,
++	 * to indicate to the Linux scsi midlayer this is a modern
++	 * device.  2) Ensure response data format / ATAPI information
++	 * are always correct.
++	 */
++	/* FIXME: do we ever override EVPD pages and the like, with
++	 * this code?
++	 */
++			if (buf[2] == 0) {
++				buf[2] = 0x5;
++				buf[3] = 0x32;
++			}
++
+ 			ata_scsi_rbuf_put(cmd, buf);
+ 		}
++
+ 		cmd->result = SAM_STAT_GOOD;
+ 	}
+ 
+ 	qc->scsidone(cmd);
+-
+ 	return 0;
+ }
+ /**
+@@ -1384,7 +2083,7 @@ static int atapi_qc_complete(struct ata_
+  *	Zero on success, non-zero on failure.
+  */
+ 
+-static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
++static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+ {
+ 	struct scsi_cmnd *cmd = qc->scsicmd;
+ 	struct ata_device *dev = qc->dev;
+@@ -1453,7 +2152,7 @@ static unsigned int atapi_xlat(struct at
+  */
+ 
+ static struct ata_device *
+-ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev)
++ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
+ {
+ 	struct ata_device *dev;
+ 
+@@ -1478,6 +2177,143 @@ ata_scsi_find_dev(struct ata_port *ap, s
+ 	return dev;
+ }
+ 
++/*
++ *	ata_scsi_map_proto - Map pass-thru protocol value to taskfile value.
++ *	@byte1: Byte 1 from pass-thru CDB.
++ *
++ *	RETURNS:
++ *	ATA_PROT_UNKNOWN if mapping failed/unimplemented, protocol otherwise.
++ */
++static u8
++ata_scsi_map_proto(u8 byte1)
++{
++	switch((byte1 & 0x1e) >> 1) {
++		case 3:		/* Non-data */
++			return ATA_PROT_NODATA;
++
++		case 6:		/* DMA */
++			return ATA_PROT_DMA;
++
++		case 4:		/* PIO Data-in */
++		case 5:		/* PIO Data-out */
++			if (byte1 & 0xe0) {
++				return ATA_PROT_PIO_MULT;
++			}
++			return ATA_PROT_PIO;
++
++		case 10:	/* Device Reset */
++		case 0:		/* Hard Reset */
++		case 1:		/* SRST */
++		case 2:		/* Bus Idle */
++		case 7:		/* Packet */
++		case 8:		/* DMA Queued */
++		case 9:		/* Device Diagnostic */
++		case 11:	/* UDMA Data-in */
++		case 12:	/* UDMA Data-Out */
++		case 13:	/* FPDMA */
++		default:	/* Reserved */
++			break;
++	}
++
++	return ATA_PROT_UNKNOWN;
++}
++
++/**
++ *	ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
++ *	@qc: command structure to be initialized
++ *	@cmd: SCSI command to convert
++ *
++ *	Handles either 12 or 16-byte versions of the CDB.
++ *
++ *	RETURNS:
++ *	Zero on success, non-zero on failure.
++ */
++static unsigned int
++ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
++{
++	struct ata_taskfile *tf = &(qc->tf);
++	struct scsi_cmnd *cmd = qc->scsicmd;
++
++	if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
++		return 1;
++
++	/*
++	 * 12 and 16 byte CDBs use different offsets to
++	 * provide the various register values.
++	 */
++	if (scsicmd[0] == ATA_16) {
++		/*
++		 * 16-byte CDB - may contain extended commands.
++		 *
++		 * If that is the case, copy the upper byte register values.
++		 */
++		if (scsicmd[1] & 0x01) {
++			tf->hob_feature = scsicmd[3];
++			tf->hob_nsect = scsicmd[5];
++			tf->hob_lbal = scsicmd[7];
++			tf->hob_lbam = scsicmd[9];
++			tf->hob_lbah = scsicmd[11];
++			tf->flags |= ATA_TFLAG_LBA48;
++		} else
++			tf->flags &= ~ATA_TFLAG_LBA48;
++
++		/*
++		 * Always copy low byte, device and command registers.
++		 */
++		tf->feature = scsicmd[4];
++		tf->nsect = scsicmd[6];
++		tf->lbal = scsicmd[8];
++		tf->lbam = scsicmd[10];
++		tf->lbah = scsicmd[12];
++		tf->device = scsicmd[13];
++		tf->command = scsicmd[14];
++	} else {
++		/*
++		 * 12-byte CDB - incapable of extended commands.
++		 */
++		tf->flags &= ~ATA_TFLAG_LBA48;
++
++		tf->feature = scsicmd[3];
++		tf->nsect = scsicmd[4];
++		tf->lbal = scsicmd[5];
++		tf->lbam = scsicmd[6];
++		tf->lbah = scsicmd[7];
++		tf->device = scsicmd[8];
++		tf->command = scsicmd[9];
++	}
++
++	/*
++	 * Filter SET_FEATURES - XFER MODE command -- otherwise,
++	 * SET_FEATURES - XFER MODE must be preceded/succeeded
++	 * by an update to hardware-specific registers for each
++	 * controller (i.e. the reason for ->set_piomode(),
++	 * ->set_dmamode(), and ->post_set_mode() hooks).
++	 */
++	if ((tf->command == ATA_CMD_SET_FEATURES)
++	 && (tf->feature == SETFEATURES_XFER))
++		return 1;
++
++	/*
++	 * Set flags so that all registers will be written,
++	 * and pass on write indication (used for PIO/DMA
++	 * setup.)
++	 */
++	tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE);
++
++	if (cmd->sc_data_direction == DMA_TO_DEVICE)
++		tf->flags |= ATA_TFLAG_WRITE;
++
++	/*
++	 * Set transfer length.
++	 *
++	 * TODO: find out if we need to do more here to
++	 *       cover scatter/gather case.
++	 */
++	qc->nsect = cmd->bufflen / ATA_SECT_SIZE;
++
++	return 0;
++}
++
+ /**
+  *	ata_get_xlat_func - check if SCSI to ATA translation is possible
+  *	@dev: ATA device
+@@ -1510,6 +2346,11 @@ static inline ata_xlat_func_t ata_get_xl
+ 	case VERIFY:
+ 	case VERIFY_16:
+ 		return ata_scsi_verify_xlat;
++
++	case ATA_12:
++	case ATA_16:
++		return ata_scsi_pass_thru;
++
+ 	case START_STOP:
+ 		return ata_scsi_start_stop_xlat;
+ 	}
+@@ -1565,8 +2406,12 @@ int ata_scsi_queuecmd(struct scsi_cmnd *
+ 	struct ata_port *ap;
+ 	struct ata_device *dev;
+ 	struct scsi_device *scsidev = cmd->device;
++	struct Scsi_Host *shost = scsidev->host;
+ 
+-	ap = (struct ata_port *) &scsidev->host->hostdata[0];
++	ap = (struct ata_port *) &shost->hostdata[0];
++
++	spin_unlock(shost->host_lock);
++	spin_lock(&ap->host_set->lock);
+ 
+ 	ata_scsi_dump_cdb(ap, cmd);
+ 
+@@ -1589,6 +2434,8 @@ int ata_scsi_queuecmd(struct scsi_cmnd *
+ 		ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
+ 
+ out_unlock:
++	spin_unlock(&ap->host_set->lock);
++	spin_lock(shost->host_lock);
+ 	return 0;
+ }
+ 
+@@ -1610,7 +2457,7 @@ void ata_scsi_simulate(u16 *id,
+ 		      void (*done)(struct scsi_cmnd *))
+ {
+ 	struct ata_scsi_args args;
+-	u8 *scsicmd = cmd->cmnd;
++	const u8 *scsicmd = cmd->cmnd;
+ 
+ 	args.id = id;
+ 	args.cmd = cmd;
+@@ -1630,7 +2477,7 @@ void ata_scsi_simulate(u16 *id,
+ 
+ 		case INQUIRY:
+ 			if (scsicmd[1] & 2)	           /* is CmdDt set?  */
+-				ata_bad_cdb(cmd, done);
++				ata_scsi_invalid_field(cmd, done);
+ 			else if ((scsicmd[1] & 1) == 0)    /* is EVPD clear? */
+ 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
+ 			else if (scsicmd[2] == 0x00)
+@@ -1640,7 +2487,7 @@ void ata_scsi_simulate(u16 *id,
+ 			else if (scsicmd[2] == 0x83)
+ 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
+ 			else
+-				ata_bad_cdb(cmd, done);
++				ata_scsi_invalid_field(cmd, done);
+ 			break;
+ 
+ 		case MODE_SENSE:
+@@ -1650,7 +2497,7 @@ void ata_scsi_simulate(u16 *id,
+ 
+ 		case MODE_SELECT:	/* unconditionally return */
+ 		case MODE_SELECT_10:	/* bad-field-in-cdb */
+-			ata_bad_cdb(cmd, done);
++			ata_scsi_invalid_field(cmd, done);
+ 			break;
+ 
+ 		case READ_CAPACITY:
+@@ -1661,20 +2508,38 @@ void ata_scsi_simulate(u16 *id,
+ 			if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
+ 				ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
+ 			else
+-				ata_bad_cdb(cmd, done);
++				ata_scsi_invalid_field(cmd, done);
+ 			break;
+ 
+ 		case REPORT_LUNS:
+ 			ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns);
+ 			break;
+ 
+-		/* mandantory commands we haven't implemented yet */
++		/* mandatory commands we haven't implemented yet */
+ 		case REQUEST_SENSE:
+ 
+ 		/* all other commands */
+ 		default:
+-			ata_bad_scsiop(cmd, done);
++			ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0);
++			/* "Invalid command operation code" */
++			done(cmd);
+ 			break;
+ 	}
+ }
+ 
++void ata_scsi_scan_host(struct ata_port *ap)
++{
++	struct ata_device *dev;
++	unsigned int i;
++
++	if (ap->flags & ATA_FLAG_PORT_DISABLED)
++		return;
++
++	for (i = 0; i < ATA_MAX_DEVICES; i++) {
++		dev = &ap->device[i];
++
++		if (ata_dev_present(dev))
++			scsi_scan_target(&ap->host->shost_gendev, 0, i, 0, 0);
++	}
++}
++
+diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
+--- a/drivers/scsi/libata.h
++++ b/drivers/scsi/libata.h
+@@ -39,19 +39,24 @@ struct ata_scsi_args {
+ 
+ /* libata-core.c */
+ extern int atapi_enabled;
++extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask);
+ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
+ 				      struct ata_device *dev);
++extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
+ extern void ata_qc_free(struct ata_queued_cmd *qc);
+ extern int ata_qc_issue(struct ata_queued_cmd *qc);
+ extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
+ extern void ata_dev_select(struct ata_port *ap, unsigned int device,
+                            unsigned int wait, unsigned int can_sleep);
+-extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
+ extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
++extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
++extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
+ 
+ 
+ /* libata-scsi.c */
+-extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat);
++extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
++			 struct scsi_cmnd *cmd);
++extern void ata_scsi_scan_host(struct ata_port *ap);
+ extern int ata_scsi_error(struct Scsi_Host *host);
+ extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
+ 			       unsigned int buflen);
+@@ -76,18 +81,10 @@ extern unsigned int ata_scsiop_report_lu
+ extern void ata_scsi_badcmd(struct scsi_cmnd *cmd,
+ 			    void (*done)(struct scsi_cmnd *),
+ 			    u8 asc, u8 ascq);
++extern void ata_scsi_set_sense(struct scsi_cmnd *cmd,
++			       u8 sk, u8 asc, u8 ascq);
+ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
+                         unsigned int (*actor) (struct ata_scsi_args *args,
+                                            u8 *rbuf, unsigned int buflen));
+ 
+-static inline void ata_bad_scsiop(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+-{
+-	ata_scsi_badcmd(cmd, done, 0x20, 0x00);
+-}
+-
+-static inline void ata_bad_cdb(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+-{
+-	ata_scsi_badcmd(cmd, done, 0x24, 0x00);
+-}
+-
+ #endif /* __LIBATA_H__ */
+diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
+--- a/drivers/scsi/lpfc/lpfc_mem.c
++++ b/drivers/scsi/lpfc/lpfc_mem.c
+@@ -39,7 +39,7 @@
+ #define LPFC_MEM_POOL_SIZE      64      /* max elem in non-DMA safety pool */
+ 
+ static void *
+-lpfc_pool_kmalloc(unsigned int gfp_flags, void *data)
++lpfc_pool_kmalloc(gfp_t gfp_flags, void *data)
+ {
+ 	return kmalloc((unsigned long)data, gfp_flags);
+ }
+diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
+--- a/drivers/scsi/megaraid/megaraid_mbox.c
++++ b/drivers/scsi/megaraid/megaraid_mbox.c
+@@ -76,7 +76,7 @@ static void megaraid_exit(void);
+ 
+ static int megaraid_probe_one(struct pci_dev*, const struct pci_device_id *);
+ static void megaraid_detach_one(struct pci_dev *);
+-static void megaraid_mbox_shutdown(struct device *);
++static void megaraid_mbox_shutdown(struct pci_dev *);
+ 
+ static int megaraid_io_attach(adapter_t *);
+ static void megaraid_io_detach(adapter_t *);
+@@ -369,9 +369,7 @@ static struct pci_driver megaraid_pci_dr
+ 	.id_table	= pci_id_table_g,
+ 	.probe		= megaraid_probe_one,
+ 	.remove		= __devexit_p(megaraid_detach_one),
+-	.driver		= {
+-		.shutdown	= megaraid_mbox_shutdown,
+-	}
++	.shutdown	= megaraid_mbox_shutdown,
+ };
+ 
+ 
+@@ -673,9 +671,9 @@ megaraid_detach_one(struct pci_dev *pdev
+  * Shutdown notification, perform flush cache
+  */
+ static void
+-megaraid_mbox_shutdown(struct device *device)
++megaraid_mbox_shutdown(struct pci_dev *pdev)
+ {
+-	adapter_t		*adapter = pci_get_drvdata(to_pci_dev(device));
++	adapter_t		*adapter = pci_get_drvdata(pdev);
+ 	static int		counter;
+ 
+ 	if (!adapter) {
+diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
+--- a/drivers/scsi/mesh.c
++++ b/drivers/scsi/mesh.c
+@@ -730,7 +730,7 @@ static void start_phase(struct mesh_stat
+ 		 * issue a SEQ_MSGOUT to get the mesh to drop ACK.
+ 		 */
+ 		if ((in_8(&mr->bus_status0) & BS0_ATN) == 0) {
+-			dlog(ms, "bus0 was %.2x explictly asserting ATN", mr->bus_status0);
++			dlog(ms, "bus0 was %.2x explicitly asserting ATN", mr->bus_status0);
+ 			out_8(&mr->bus_status0, BS0_ATN); /* explicit ATN */
+ 			mesh_flush_io(mr);
+ 			udelay(1);
+diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
+--- a/drivers/scsi/osst.c
++++ b/drivers/scsi/osst.c
+@@ -5146,7 +5146,8 @@ static long osst_compat_ioctl(struct fil
+ /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
+ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
+ {
+-	int i, priority;
++	int i;
++	gfp_t priority;
+ 	struct osst_buffer *tb;
+ 
+ 	if (from_initialization)
+@@ -5178,7 +5179,8 @@ static struct osst_buffer * new_tape_buf
+ /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
+ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
+ {
+-	int segs, nbr, max_segs, b_size, priority, order, got;
++	int segs, nbr, max_segs, b_size, order, got;
++	gfp_t priority;
+ 
+ 	if (STbuffer->buffer_size >= OS_FRAME_SIZE)
+ 		return 1;
+@@ -5627,7 +5629,7 @@ static void osst_sysfs_add(dev_t dev, st
+ 
+ 	if (!osst_sysfs_valid) return;
+ 
+-	osst_class_member = class_device_create(osst_sysfs_class, dev, device, "%s", name);
++	osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
+ 	if (IS_ERR(osst_class_member)) {
+ 		printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
+ 		return;
+diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/scsi/pdc_adma.c
+@@ -0,0 +1,741 @@
++/*
++ *  pdc_adma.c - Pacific Digital Corporation ADMA
++ *
++ *  Maintained by:  Mark Lord <mlord at pobox.com>
++ *
++ *  Copyright 2005 Mark Lord
++ *
++ *  This program is free software; you can redistribute 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.*
++ *
++ *
++ *  Supports ATA disks in single-packet ADMA mode.
++ *  Uses PIO for everything else.
++ *
++ *  TODO:  Use ADMA transfers for ATAPI devices, when possible.
++ *  This requires careful attention to a number of quirks of the chip.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/blkdev.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/device.h>
++#include "scsi.h"
++#include <scsi/scsi_host.h>
++#include <asm/io.h>
++#include <linux/libata.h>
++
++#define DRV_NAME	"pdc_adma"
++#define DRV_VERSION	"0.03"
++
++/* macro to calculate base address for ATA regs */
++#define ADMA_ATA_REGS(base,port_no)	((base) + ((port_no) * 0x40))
++
++/* macro to calculate base address for ADMA regs */
++#define ADMA_REGS(base,port_no)	((base) + 0x80 + ((port_no) * 0x20))
++
++enum {
++	ADMA_PORTS		= 2,
++	ADMA_CPB_BYTES		= 40,
++	ADMA_PRD_BYTES		= LIBATA_MAX_PRD * 16,
++	ADMA_PKT_BYTES		= ADMA_CPB_BYTES + ADMA_PRD_BYTES,
++
++	ADMA_DMA_BOUNDARY	= 0xffffffff,
++
++	/* global register offsets */
++	ADMA_MODE_LOCK		= 0x00c7,
++
++	/* per-channel register offsets */
++	ADMA_CONTROL		= 0x0000, /* ADMA control */
++	ADMA_STATUS		= 0x0002, /* ADMA status */
++	ADMA_CPB_COUNT		= 0x0004, /* CPB count */
++	ADMA_CPB_CURRENT	= 0x000c, /* current CPB address */
++	ADMA_CPB_NEXT		= 0x000c, /* next CPB address */
++	ADMA_CPB_LOOKUP		= 0x0010, /* CPB lookup table */
++	ADMA_FIFO_IN		= 0x0014, /* input FIFO threshold */
++	ADMA_FIFO_OUT		= 0x0016, /* output FIFO threshold */
++
++	/* ADMA_CONTROL register bits */
++	aNIEN			= (1 << 8), /* irq mask: 1==masked */
++	aGO			= (1 << 7), /* packet trigger ("Go!") */
++	aRSTADM			= (1 << 5), /* ADMA logic reset */
++	aPIOMD4			= 0x0003,   /* PIO mode 4 */
++
++	/* ADMA_STATUS register bits */
++	aPSD			= (1 << 6),
++	aUIRQ			= (1 << 4),
++	aPERR			= (1 << 0),
++
++	/* CPB bits */
++	cDONE			= (1 << 0),
++	cVLD			= (1 << 0),
++	cDAT			= (1 << 2),
++	cIEN			= (1 << 3),
++
++	/* PRD bits */
++	pORD			= (1 << 4),
++	pDIRO			= (1 << 5),
++	pEND			= (1 << 7),
++
++	/* ATA register flags */
++	rIGN			= (1 << 5),
++	rEND			= (1 << 7),
++
++	/* ATA register addresses */
++	ADMA_REGS_CONTROL	= 0x0e,
++	ADMA_REGS_SECTOR_COUNT	= 0x12,
++	ADMA_REGS_LBA_LOW	= 0x13,
++	ADMA_REGS_LBA_MID	= 0x14,
++	ADMA_REGS_LBA_HIGH	= 0x15,
++	ADMA_REGS_DEVICE	= 0x16,
++	ADMA_REGS_COMMAND	= 0x17,
++
++	/* PCI device IDs */
++	board_1841_idx		= 0,	/* ADMA 2-port controller */
++};
++
++typedef enum { adma_state_idle, adma_state_pkt, adma_state_mmio } adma_state_t;
++
++struct adma_port_priv {
++	u8			*pkt;
++	dma_addr_t		pkt_dma;
++	adma_state_t		state;
++};
++
++static int adma_ata_init_one (struct pci_dev *pdev,
++				const struct pci_device_id *ent);
++static irqreturn_t adma_intr (int irq, void *dev_instance,
++				struct pt_regs *regs);
++static int adma_port_start(struct ata_port *ap);
++static void adma_host_stop(struct ata_host_set *host_set);
++static void adma_port_stop(struct ata_port *ap);
++static void adma_phy_reset(struct ata_port *ap);
++static void adma_qc_prep(struct ata_queued_cmd *qc);
++static int adma_qc_issue(struct ata_queued_cmd *qc);
++static int adma_check_atapi_dma(struct ata_queued_cmd *qc);
++static void adma_bmdma_stop(struct ata_queued_cmd *qc);
++static u8 adma_bmdma_status(struct ata_port *ap);
++static void adma_irq_clear(struct ata_port *ap);
++static void adma_eng_timeout(struct ata_port *ap);
++
++static Scsi_Host_Template adma_ata_sht = {
++	.module			= THIS_MODULE,
++	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
++	.queuecommand		= ata_scsi_queuecmd,
++	.eh_strategy_handler	= ata_scsi_error,
++	.can_queue		= ATA_DEF_QUEUE,
++	.this_id		= ATA_SHT_THIS_ID,
++	.sg_tablesize		= LIBATA_MAX_PRD,
++	.max_sectors		= ATA_MAX_SECTORS,
++	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
++	.emulated		= ATA_SHT_EMULATED,
++	.use_clustering		= ENABLE_CLUSTERING,
++	.proc_name		= DRV_NAME,
++	.dma_boundary		= ADMA_DMA_BOUNDARY,
++	.slave_configure	= ata_scsi_slave_config,
++	.bios_param		= ata_std_bios_param,
++};
++
++static const struct ata_port_operations adma_ata_ops = {
++	.port_disable		= ata_port_disable,
++	.tf_load		= ata_tf_load,
++	.tf_read		= ata_tf_read,
++	.check_status		= ata_check_status,
++	.check_atapi_dma	= adma_check_atapi_dma,
++	.exec_command		= ata_exec_command,
++	.dev_select		= ata_std_dev_select,
++	.phy_reset		= adma_phy_reset,
++	.qc_prep		= adma_qc_prep,
++	.qc_issue		= adma_qc_issue,
++	.eng_timeout		= adma_eng_timeout,
++	.irq_handler		= adma_intr,
++	.irq_clear		= adma_irq_clear,
++	.port_start		= adma_port_start,
++	.port_stop		= adma_port_stop,
++	.host_stop		= adma_host_stop,
++	.bmdma_stop		= adma_bmdma_stop,
++	.bmdma_status		= adma_bmdma_status,
++};
++
++static struct ata_port_info adma_port_info[] = {
++	/* board_1841_idx */
++	{
++		.sht		= &adma_ata_sht,
++		.host_flags	= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
++				  ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO,
++		.pio_mask	= 0x10, /* pio4 */
++		.udma_mask	= 0x1f, /* udma0-4 */
++		.port_ops	= &adma_ata_ops,
++	},
++};
++
++static struct pci_device_id adma_ata_pci_tbl[] = {
++	{ PCI_VENDOR_ID_PDC, 0x1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
++	  board_1841_idx },
++
++	{ }	/* terminate list */
++};
++
++static struct pci_driver adma_ata_pci_driver = {
++	.name			= DRV_NAME,
++	.id_table		= adma_ata_pci_tbl,
++	.probe			= adma_ata_init_one,
++	.remove			= ata_pci_remove_one,
++};
++
++static int adma_check_atapi_dma(struct ata_queued_cmd *qc)
++{
++	return 1;	/* ATAPI DMA not yet supported */
++}
++
++static void adma_bmdma_stop(struct ata_queued_cmd *qc)
++{
++	/* nothing */
++}
++
++static u8 adma_bmdma_status(struct ata_port *ap)
++{
++	return 0;
++}
++
++static void adma_irq_clear(struct ata_port *ap)
++{
++	/* nothing */
++}
++
++static void adma_reset_engine(void __iomem *chan)
++{
++	/* reset ADMA to idle state */
++	writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL);
++	udelay(2);
++	writew(aPIOMD4, chan + ADMA_CONTROL);
++	udelay(2);
++}
++
++static void adma_reinit_engine(struct ata_port *ap)
++{
++	struct adma_port_priv *pp = ap->private_data;
++	void __iomem *mmio_base = ap->host_set->mmio_base;
++	void __iomem *chan = ADMA_REGS(mmio_base, ap->port_no);
++
++	/* mask/clear ATA interrupts */
++	writeb(ATA_NIEN, (void __iomem *)ap->ioaddr.ctl_addr);
++	ata_check_status(ap);
++
++	/* reset the ADMA engine */
++	adma_reset_engine(chan);
++
++	/* set in-FIFO threshold to 0x100 */
++	writew(0x100, chan + ADMA_FIFO_IN);
++
++	/* set CPB pointer */
++	writel((u32)pp->pkt_dma, chan + ADMA_CPB_NEXT);
++
++	/* set out-FIFO threshold to 0x100 */
++	writew(0x100, chan + ADMA_FIFO_OUT);
++
++	/* set CPB count */
++	writew(1, chan + ADMA_CPB_COUNT);
++
++	/* read/discard ADMA status */
++	readb(chan + ADMA_STATUS);
++}
++
++static inline void adma_enter_reg_mode(struct ata_port *ap)
++{
++	void __iomem *chan = ADMA_REGS(ap->host_set->mmio_base, ap->port_no);
++
++	writew(aPIOMD4, chan + ADMA_CONTROL);
++	readb(chan + ADMA_STATUS);	/* flush */
++}
++
++static void adma_phy_reset(struct ata_port *ap)
++{
++	struct adma_port_priv *pp = ap->private_data;
++
++	pp->state = adma_state_idle;
++	adma_reinit_engine(ap);
++	ata_port_probe(ap);
++	ata_bus_reset(ap);
++}
++
++static void adma_eng_timeout(struct ata_port *ap)
++{
++	struct adma_port_priv *pp = ap->private_data;
++
++	if (pp->state != adma_state_idle) /* healthy paranoia */
++		pp->state = adma_state_mmio;
++	adma_reinit_engine(ap);
++	ata_eng_timeout(ap);
++}
++
++static int adma_fill_sg(struct ata_queued_cmd *qc)
++{
++	struct scatterlist *sg = qc->sg;
++	struct ata_port *ap = qc->ap;
++	struct adma_port_priv *pp = ap->private_data;
++	u8  *buf = pp->pkt;
++	int nelem, i = (2 + buf[3]) * 8;
++	u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0);
++
++	for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) {
++		u32 addr;
++		u32 len;
++
++		addr = (u32)sg_dma_address(sg);
++		*(__le32 *)(buf + i) = cpu_to_le32(addr);
++		i += 4;
++
++		len = sg_dma_len(sg) >> 3;
++		*(__le32 *)(buf + i) = cpu_to_le32(len);
++		i += 4;
++
++		if ((nelem + 1) == qc->n_elem)
++			pFLAGS |= pEND;
++		buf[i++] = pFLAGS;
++		buf[i++] = qc->dev->dma_mode & 0xf;
++		buf[i++] = 0;	/* pPKLW */
++		buf[i++] = 0;	/* reserved */
++
++		*(__le32 *)(buf + i)
++			= (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4);
++		i += 4;
++
++		VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", nelem,
++					(unsigned long)addr, len);
++	}
++	return i;
++}
++
++static void adma_qc_prep(struct ata_queued_cmd *qc)
++{
++	struct adma_port_priv *pp = qc->ap->private_data;
++	u8  *buf = pp->pkt;
++	u32 pkt_dma = (u32)pp->pkt_dma;
++	int i = 0;
++
++	VPRINTK("ENTER\n");
++
++	adma_enter_reg_mode(qc->ap);
++	if (qc->tf.protocol != ATA_PROT_DMA) {
++		ata_qc_prep(qc);
++		return;
++	}
++
++	buf[i++] = 0;	/* Response flags */
++	buf[i++] = 0;	/* reserved */
++	buf[i++] = cVLD | cDAT | cIEN;
++	i++;		/* cLEN, gets filled in below */
++
++	*(__le32 *)(buf+i) = cpu_to_le32(pkt_dma);	/* cNCPB */
++	i += 4;		/* cNCPB */
++	i += 4;		/* cPRD, gets filled in below */
++
++	buf[i++] = 0;	/* reserved */
++	buf[i++] = 0;	/* reserved */
++	buf[i++] = 0;	/* reserved */
++	buf[i++] = 0;	/* reserved */
++
++	/* ATA registers; must be a multiple of 4 */
++	buf[i++] = qc->tf.device;
++	buf[i++] = ADMA_REGS_DEVICE;
++	if ((qc->tf.flags & ATA_TFLAG_LBA48)) {
++		buf[i++] = qc->tf.hob_nsect;
++		buf[i++] = ADMA_REGS_SECTOR_COUNT;
++		buf[i++] = qc->tf.hob_lbal;
++		buf[i++] = ADMA_REGS_LBA_LOW;
++		buf[i++] = qc->tf.hob_lbam;
++		buf[i++] = ADMA_REGS_LBA_MID;
++		buf[i++] = qc->tf.hob_lbah;
++		buf[i++] = ADMA_REGS_LBA_HIGH;
++	}
++	buf[i++] = qc->tf.nsect;
++	buf[i++] = ADMA_REGS_SECTOR_COUNT;
++	buf[i++] = qc->tf.lbal;
++	buf[i++] = ADMA_REGS_LBA_LOW;
++	buf[i++] = qc->tf.lbam;
++	buf[i++] = ADMA_REGS_LBA_MID;
++	buf[i++] = qc->tf.lbah;
++	buf[i++] = ADMA_REGS_LBA_HIGH;
++	buf[i++] = 0;
++	buf[i++] = ADMA_REGS_CONTROL;
++	buf[i++] = rIGN;
++	buf[i++] = 0;
++	buf[i++] = qc->tf.command;
++	buf[i++] = ADMA_REGS_COMMAND | rEND;
++
++	buf[3] = (i >> 3) - 2;				/* cLEN */
++	*(__le32 *)(buf+8) = cpu_to_le32(pkt_dma + i);	/* cPRD */
++
++	i = adma_fill_sg(qc);
++	wmb();	/* flush PRDs and pkt to memory */
++#if 0
++	/* dump out CPB + PRDs for debug */
++	{
++		int j, len = 0;
++		static char obuf[2048];
++		for (j = 0; j < i; ++j) {
++			len += sprintf(obuf+len, "%02x ", buf[j]);
++			if ((j & 7) == 7) {
++				printk("%s\n", obuf);
++				len = 0;
++			}
++		}
++		if (len)
++			printk("%s\n", obuf);
++	}
++#endif
++}
++
++static inline void adma_packet_start(struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	void __iomem *chan = ADMA_REGS(ap->host_set->mmio_base, ap->port_no);
++
++	VPRINTK("ENTER, ap %p\n", ap);
++
++	/* fire up the ADMA engine */
++	writew(aPIOMD4 | aGO, chan + ADMA_CONTROL);
++}
++
++static int adma_qc_issue(struct ata_queued_cmd *qc)
++{
++	struct adma_port_priv *pp = qc->ap->private_data;
++
++	switch (qc->tf.protocol) {
++	case ATA_PROT_DMA:
++		pp->state = adma_state_pkt;
++		adma_packet_start(qc);
++		return 0;
++
++	case ATA_PROT_ATAPI_DMA:
++		BUG();
++		break;
++
++	default:
++		break;
++	}
++
++	pp->state = adma_state_mmio;
++	return ata_qc_issue_prot(qc);
++}
++
++static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
++{
++	unsigned int handled = 0, port_no;
++	u8 __iomem *mmio_base = host_set->mmio_base;
++
++	for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
++		struct ata_port *ap = host_set->ports[port_no];
++		struct adma_port_priv *pp;
++		struct ata_queued_cmd *qc;
++		void __iomem *chan = ADMA_REGS(mmio_base, port_no);
++		u8 status = readb(chan + ADMA_STATUS);
++
++		if (status == 0)
++			continue;
++		handled = 1;
++		adma_enter_reg_mode(ap);
++		if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))
++			continue;
++		pp = ap->private_data;
++		if (!pp || pp->state != adma_state_pkt)
++			continue;
++		qc = ata_qc_from_tag(ap, ap->active_tag);
++		if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
++			unsigned int err_mask = 0;
++
++			if ((status & (aPERR | aPSD | aUIRQ)))
++				err_mask = AC_ERR_OTHER;
++			else if (pp->pkt[0] != cDONE)
++				err_mask = AC_ERR_OTHER;
++
++			ata_qc_complete(qc, err_mask);
++		}
++	}
++	return handled;
++}
++
++static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
++{
++	unsigned int handled = 0, port_no;
++
++	for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
++		struct ata_port *ap;
++		ap = host_set->ports[port_no];
++		if (ap && (!(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)))) {
++			struct ata_queued_cmd *qc;
++			struct adma_port_priv *pp = ap->private_data;
++			if (!pp || pp->state != adma_state_mmio)
++				continue;
++			qc = ata_qc_from_tag(ap, ap->active_tag);
++			if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
++
++				/* check main status, clearing INTRQ */
++				u8 status = ata_check_status(ap);
++				if ((status & ATA_BUSY))
++					continue;
++				DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
++					ap->id, qc->tf.protocol, status);
++		
++				/* complete taskfile transaction */
++				pp->state = adma_state_idle;
++				ata_qc_complete(qc, ac_err_mask(status));
++				handled = 1;
++			}
++		}
++	}
++	return handled;
++}
++
++static irqreturn_t adma_intr(int irq, void *dev_instance, struct pt_regs *regs)
++{
++	struct ata_host_set *host_set = dev_instance;
++	unsigned int handled = 0;
++
++	VPRINTK("ENTER\n");
++
++	spin_lock(&host_set->lock);
++	handled  = adma_intr_pkt(host_set) | adma_intr_mmio(host_set);
++	spin_unlock(&host_set->lock);
++
++	VPRINTK("EXIT\n");
++
++	return IRQ_RETVAL(handled);
++}
++
++static void adma_ata_setup_port(struct ata_ioports *port, unsigned long base)
++{
++	port->cmd_addr		=
++	port->data_addr		= base + 0x000;
++	port->error_addr	=
++	port->feature_addr	= base + 0x004;
++	port->nsect_addr	= base + 0x008;
++	port->lbal_addr		= base + 0x00c;
++	port->lbam_addr		= base + 0x010;
++	port->lbah_addr		= base + 0x014;
++	port->device_addr	= base + 0x018;
++	port->status_addr	=
++	port->command_addr	= base + 0x01c;
++	port->altstatus_addr	=
++	port->ctl_addr		= base + 0x038;
++}
++
++static int adma_port_start(struct ata_port *ap)
++{
++	struct device *dev = ap->host_set->dev;
++	struct adma_port_priv *pp;
++	int rc;
++
++	rc = ata_port_start(ap);
++	if (rc)
++		return rc;
++	adma_enter_reg_mode(ap);
++	rc = -ENOMEM;
++	pp = kcalloc(1, sizeof(*pp), GFP_KERNEL);
++	if (!pp)
++		goto err_out;
++	pp->pkt = dma_alloc_coherent(dev, ADMA_PKT_BYTES, &pp->pkt_dma,
++								GFP_KERNEL);
++	if (!pp->pkt)
++		goto err_out_kfree;
++	/* paranoia? */
++	if ((pp->pkt_dma & 7) != 0) {
++		printk("bad alignment for pp->pkt_dma: %08x\n",
++						(u32)pp->pkt_dma);
++		dma_free_coherent(dev, ADMA_PKT_BYTES,
++						pp->pkt, pp->pkt_dma);
++		goto err_out_kfree;
++	}
++	memset(pp->pkt, 0, ADMA_PKT_BYTES);
++	ap->private_data = pp;
++	adma_reinit_engine(ap);
++	return 0;
++
++err_out_kfree:
++	kfree(pp);
++err_out:
++	ata_port_stop(ap);
++	return rc;
++}
++
++static void adma_port_stop(struct ata_port *ap)
++{
++	struct device *dev = ap->host_set->dev;
++	struct adma_port_priv *pp = ap->private_data;
++
++	adma_reset_engine(ADMA_REGS(ap->host_set->mmio_base, ap->port_no));
++	if (pp != NULL) {
++		ap->private_data = NULL;
++		if (pp->pkt != NULL)
++			dma_free_coherent(dev, ADMA_PKT_BYTES,
++					pp->pkt, pp->pkt_dma);
++		kfree(pp);
++	}
++	ata_port_stop(ap);
++}
++
++static void adma_host_stop(struct ata_host_set *host_set)
++{
++	unsigned int port_no;
++
++	for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
++		adma_reset_engine(ADMA_REGS(host_set->mmio_base, port_no));
++
++	ata_pci_host_stop(host_set);
++}
++
++static void adma_host_init(unsigned int chip_id,
++				struct ata_probe_ent *probe_ent)
++{
++	unsigned int port_no;
++	void __iomem *mmio_base = probe_ent->mmio_base;
++
++	/* enable/lock aGO operation */
++	writeb(7, mmio_base + ADMA_MODE_LOCK);
++
++	/* reset the ADMA logic */
++	for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
++		adma_reset_engine(ADMA_REGS(mmio_base, port_no));
++}
++
++static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
++{
++	int rc;
++
++	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
++	if (rc) {
++		dev_printk(KERN_ERR, &pdev->dev,
++			"32-bit DMA enable failed\n");
++		return rc;
++	}
++	rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
++	if (rc) {
++		dev_printk(KERN_ERR, &pdev->dev,
++			"32-bit consistent DMA enable failed\n");
++		return rc;
++	}
++	return 0;
++}
++
++static int adma_ata_init_one(struct pci_dev *pdev,
++				const struct pci_device_id *ent)
++{
++	static int printed_version;
++	struct ata_probe_ent *probe_ent = NULL;
++	void __iomem *mmio_base;
++	unsigned int board_idx = (unsigned int) ent->driver_data;
++	int rc, port_no;
++
++	if (!printed_version++)
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
++
++	rc = pci_enable_device(pdev);
++	if (rc)
++		return rc;
++
++	rc = pci_request_regions(pdev, DRV_NAME);
++	if (rc)
++		goto err_out;
++
++	if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) {
++		rc = -ENODEV;
++		goto err_out_regions;
++	}
++
++	mmio_base = pci_iomap(pdev, 4, 0);
++	if (mmio_base == NULL) {
++		rc = -ENOMEM;
++		goto err_out_regions;
++	}
++
++	rc = adma_set_dma_masks(pdev, mmio_base);
++	if (rc)
++		goto err_out_iounmap;
++
++	probe_ent = kcalloc(1, sizeof(*probe_ent), GFP_KERNEL);
++	if (probe_ent == NULL) {
++		rc = -ENOMEM;
++		goto err_out_iounmap;
++	}
++
++	probe_ent->dev = pci_dev_to_dev(pdev);
++	INIT_LIST_HEAD(&probe_ent->node);
++
++	probe_ent->sht		= adma_port_info[board_idx].sht;
++	probe_ent->host_flags	= adma_port_info[board_idx].host_flags;
++	probe_ent->pio_mask	= adma_port_info[board_idx].pio_mask;
++	probe_ent->mwdma_mask	= adma_port_info[board_idx].mwdma_mask;
++	probe_ent->udma_mask	= adma_port_info[board_idx].udma_mask;
++	probe_ent->port_ops	= adma_port_info[board_idx].port_ops;
++
++	probe_ent->irq		= pdev->irq;
++	probe_ent->irq_flags	= SA_SHIRQ;
++	probe_ent->mmio_base	= mmio_base;
++	probe_ent->n_ports	= ADMA_PORTS;
++
++	for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
++		adma_ata_setup_port(&probe_ent->port[port_no],
++			ADMA_ATA_REGS((unsigned long)mmio_base, port_no));
++	}
++
++	pci_set_master(pdev);
++
++	/* initialize adapter */
++	adma_host_init(board_idx, probe_ent);
++
++	rc = ata_device_add(probe_ent);
++	kfree(probe_ent);
++	if (rc != ADMA_PORTS)
++		goto err_out_iounmap;
++	return 0;
++
++err_out_iounmap:
++	pci_iounmap(pdev, mmio_base);
++err_out_regions:
++	pci_release_regions(pdev);
++err_out:
++	pci_disable_device(pdev);
++	return rc;
++}
++
++static int __init adma_ata_init(void)
++{
++	return pci_module_init(&adma_ata_pci_driver);
++}
++
++static void __exit adma_ata_exit(void)
++{
++	pci_unregister_driver(&adma_ata_pci_driver);
++}
++
++MODULE_AUTHOR("Mark Lord");
++MODULE_DESCRIPTION("Pacific Digital Corporation ADMA low-level driver");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(pci, adma_ata_pci_tbl);
++MODULE_VERSION(DRV_VERSION);
++
++module_init(adma_ata_init);
++module_exit(adma_ata_exit);
+diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
+--- a/drivers/scsi/sata_mv.c
++++ b/drivers/scsi/sata_mv.c
+@@ -29,13 +29,14 @@
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
+ #include <linux/dma-mapping.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+ #include <asm/io.h>
+ 
+ #define DRV_NAME	"sata_mv"
+-#define DRV_VERSION	"0.12"
++#define DRV_VERSION	"0.25"
+ 
+ enum {
+ 	/* BAR's are enumerated in terms of pci_resource_start() terms */
+@@ -55,31 +56,61 @@ enum {
+ 	MV_SATAHC_ARBTR_REG_SZ	= MV_MINOR_REG_AREA_SZ,		/* arbiter */
+ 	MV_PORT_REG_SZ		= MV_MINOR_REG_AREA_SZ,
+ 
+-	MV_Q_CT			= 32,
+-	MV_CRQB_SZ		= 32,
+-	MV_CRPB_SZ		= 8,
++	MV_USE_Q_DEPTH		= ATA_DEF_QUEUE,
+ 
+-	MV_DMA_BOUNDARY		= 0xffffffffU,
+-	SATAHC_MASK		= (~(MV_SATAHC_REG_SZ - 1)),
++	MV_MAX_Q_DEPTH		= 32,
++	MV_MAX_Q_DEPTH_MASK	= MV_MAX_Q_DEPTH - 1,
++
++	/* CRQB needs alignment on a 1KB boundary. Size == 1KB
++	 * CRPB needs alignment on a 256B boundary. Size == 256B
++	 * SG count of 176 leads to MV_PORT_PRIV_DMA_SZ == 4KB
++	 * ePRD (SG) entries need alignment on a 16B boundary. Size == 16B
++	 */
++	MV_CRQB_Q_SZ		= (32 * MV_MAX_Q_DEPTH),
++	MV_CRPB_Q_SZ		= (8 * MV_MAX_Q_DEPTH),
++	MV_MAX_SG_CT		= 176,
++	MV_SG_TBL_SZ		= (16 * MV_MAX_SG_CT),
++	MV_PORT_PRIV_DMA_SZ	= (MV_CRQB_Q_SZ + MV_CRPB_Q_SZ + MV_SG_TBL_SZ),
++
++	/* Our DMA boundary is determined by an ePRD being unable to handle
++	 * anything larger than 64KB
++	 */
++	MV_DMA_BOUNDARY		= 0xffffU,
+ 
+ 	MV_PORTS_PER_HC		= 4,
+ 	/* == (port / MV_PORTS_PER_HC) to determine HC from 0-7 port */
+ 	MV_PORT_HC_SHIFT	= 2,
+-	/* == (port % MV_PORTS_PER_HC) to determine port from 0-7 port */
++	/* == (port % MV_PORTS_PER_HC) to determine hard port from 0-7 port */
+ 	MV_PORT_MASK		= 3,
+ 
+ 	/* Host Flags */
+ 	MV_FLAG_DUAL_HC		= (1 << 30),  /* two SATA Host Controllers */
+ 	MV_FLAG_IRQ_COALESCE	= (1 << 29),  /* IRQ coalescing capability */
+-	MV_FLAG_BDMA		= (1 << 28),  /* Basic DMA */
++	MV_FLAG_GLBL_SFT_RST	= (1 << 28),  /* Global Soft Reset support */
++	MV_COMMON_FLAGS		= (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
++				   ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
++	MV_6XXX_FLAGS		= (MV_FLAG_IRQ_COALESCE | 
++				   MV_FLAG_GLBL_SFT_RST),
+ 
+ 	chip_504x		= 0,
+ 	chip_508x		= 1,
+ 	chip_604x		= 2,
+ 	chip_608x		= 3,
+ 
++	CRQB_FLAG_READ		= (1 << 0),
++	CRQB_TAG_SHIFT		= 1,
++	CRQB_CMD_ADDR_SHIFT	= 8,
++	CRQB_CMD_CS		= (0x2 << 11),
++	CRQB_CMD_LAST		= (1 << 15),
++
++	CRPB_FLAG_STATUS_SHIFT	= 8,
++
++	EPRD_FLAG_END_OF_TBL	= (1 << 31),
++
+ 	/* PCI interface registers */
+ 
++	PCI_COMMAND_OFS		= 0xc00,
++
+ 	PCI_MAIN_CMD_STS_OFS	= 0xd30,
+ 	STOP_PCI_MASTER		= (1 << 2),
+ 	PCI_MASTER_EMPTY	= (1 << 3),
+@@ -111,20 +142,13 @@ enum {
+ 	HC_CFG_OFS		= 0,
+ 
+ 	HC_IRQ_CAUSE_OFS	= 0x14,
+-	CRBP_DMA_DONE		= (1 << 0),	/* shift by port # */
++	CRPB_DMA_DONE		= (1 << 0),	/* shift by port # */
+ 	HC_IRQ_COAL		= (1 << 4),	/* IRQ coalescing */
+ 	DEV_IRQ			= (1 << 8),	/* shift by port # */
+ 
+ 	/* Shadow block registers */
+-	SHD_PIO_DATA_OFS	= 0x100,
+-	SHD_FEA_ERR_OFS		= 0x104,
+-	SHD_SECT_CNT_OFS	= 0x108,
+-	SHD_LBA_L_OFS		= 0x10C,
+-	SHD_LBA_M_OFS		= 0x110,
+-	SHD_LBA_H_OFS		= 0x114,
+-	SHD_DEV_HD_OFS		= 0x118,
+-	SHD_CMD_STA_OFS		= 0x11C,
+-	SHD_CTL_AST_OFS		= 0x120,
++	SHD_BLK_OFS		= 0x100,
++	SHD_CTL_AST_OFS		= 0x20,		/* ofs from SHD_BLK_OFS */
+ 
+ 	/* SATA registers */
+ 	SATA_STATUS_OFS		= 0x300,  /* ctrl, err regs follow status */
+@@ -132,6 +156,11 @@ enum {
+ 
+ 	/* Port registers */
+ 	EDMA_CFG_OFS		= 0,
++	EDMA_CFG_Q_DEPTH	= 0,			/* queueing disabled */
++	EDMA_CFG_NCQ		= (1 << 5),
++	EDMA_CFG_NCQ_GO_ON_ERR	= (1 << 14),		/* continue on error */
++	EDMA_CFG_RD_BRST_EXT	= (1 << 11),		/* read burst 512B */
++	EDMA_CFG_WR_BUFF_LEN	= (1 << 13),		/* write buffer 512B */
+ 
+ 	EDMA_ERR_IRQ_CAUSE_OFS	= 0x8,
+ 	EDMA_ERR_IRQ_MASK_OFS	= 0xc,
+@@ -161,33 +190,84 @@ enum {
+ 				   EDMA_ERR_LNK_DATA_TX | 
+ 				   EDMA_ERR_TRANS_PROTO),
+ 
++	EDMA_REQ_Q_BASE_HI_OFS	= 0x10,
++	EDMA_REQ_Q_IN_PTR_OFS	= 0x14,		/* also contains BASE_LO */
++	EDMA_REQ_Q_BASE_LO_MASK	= 0xfffffc00U,
++
++	EDMA_REQ_Q_OUT_PTR_OFS	= 0x18,
++	EDMA_REQ_Q_PTR_SHIFT	= 5,
++
++	EDMA_RSP_Q_BASE_HI_OFS	= 0x1c,
++	EDMA_RSP_Q_IN_PTR_OFS	= 0x20,
++	EDMA_RSP_Q_OUT_PTR_OFS	= 0x24,		/* also contains BASE_LO */
++	EDMA_RSP_Q_BASE_LO_MASK	= 0xffffff00U,
++	EDMA_RSP_Q_PTR_SHIFT	= 3,
++
+ 	EDMA_CMD_OFS		= 0x28,
+ 	EDMA_EN			= (1 << 0),
+ 	EDMA_DS			= (1 << 1),
+ 	ATA_RST			= (1 << 2),
+ 
+-	/* BDMA is 6xxx part only */
+-	BDMA_CMD_OFS		= 0x224,
+-	BDMA_START		= (1 << 0),
++	/* Host private flags (hp_flags) */
++	MV_HP_FLAG_MSI		= (1 << 0),
+ 
+-	MV_UNDEF		= 0,
++	/* Port private flags (pp_flags) */
++	MV_PP_FLAG_EDMA_EN	= (1 << 0),
++	MV_PP_FLAG_EDMA_DS_ACT	= (1 << 1),
+ };
+ 
+-struct mv_port_priv {
++/* Command ReQuest Block: 32B */
++struct mv_crqb {
++	u32			sg_addr;
++	u32			sg_addr_hi;
++	u16			ctrl_flags;
++	u16			ata_cmd[11];
++};
+ 
++/* Command ResPonse Block: 8B */
++struct mv_crpb {
++	u16			id;
++	u16			flags;
++	u32			tmstmp;
+ };
+ 
+-struct mv_host_priv {
++/* EDMA Physical Region Descriptor (ePRD); A.K.A. SG */
++struct mv_sg {
++	u32			addr;
++	u32			flags_size;
++	u32			addr_hi;
++	u32			reserved;
++};
+ 
++struct mv_port_priv {
++	struct mv_crqb		*crqb;
++	dma_addr_t		crqb_dma;
++	struct mv_crpb		*crpb;
++	dma_addr_t		crpb_dma;
++	struct mv_sg		*sg_tbl;
++	dma_addr_t		sg_tbl_dma;
++
++	unsigned		req_producer;		/* cp of req_in_ptr */
++	unsigned		rsp_consumer;		/* cp of rsp_out_ptr */
++	u32			pp_flags;
++};
++
++struct mv_host_priv {
++	u32			hp_flags;
+ };
+ 
+ static void mv_irq_clear(struct ata_port *ap);
+ static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
+ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
+ static void mv_phy_reset(struct ata_port *ap);
+-static int mv_master_reset(void __iomem *mmio_base);
++static void mv_host_stop(struct ata_host_set *host_set);
++static int mv_port_start(struct ata_port *ap);
++static void mv_port_stop(struct ata_port *ap);
++static void mv_qc_prep(struct ata_queued_cmd *qc);
++static int mv_qc_issue(struct ata_queued_cmd *qc);
+ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
+ 				struct pt_regs *regs);
++static void mv_eng_timeout(struct ata_port *ap);
+ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+ 
+ static Scsi_Host_Template mv_sht = {
+@@ -196,13 +276,13 @@ static Scsi_Host_Template mv_sht = {
+ 	.ioctl			= ata_scsi_ioctl,
+ 	.queuecommand		= ata_scsi_queuecmd,
+ 	.eh_strategy_handler	= ata_scsi_error,
+-	.can_queue		= ATA_DEF_QUEUE,
++	.can_queue		= MV_USE_Q_DEPTH,
+ 	.this_id		= ATA_SHT_THIS_ID,
+-	.sg_tablesize		= MV_UNDEF,
++	.sg_tablesize		= MV_MAX_SG_CT,
+ 	.max_sectors		= ATA_MAX_SECTORS,
+ 	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
+ 	.emulated		= ATA_SHT_EMULATED,
+-	.use_clustering		= MV_UNDEF,
++	.use_clustering		= ATA_SHT_USE_CLUSTERING,
+ 	.proc_name		= DRV_NAME,
+ 	.dma_boundary		= MV_DMA_BOUNDARY,
+ 	.slave_configure	= ata_scsi_slave_config,
+@@ -210,7 +290,7 @@ static Scsi_Host_Template mv_sht = {
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations mv_ops = {
++static const struct ata_port_operations mv_ops = {
+ 	.port_disable		= ata_port_disable,
+ 
+ 	.tf_load		= ata_tf_load,
+@@ -221,10 +301,10 @@ static struct ata_port_operations mv_ops
+ 
+ 	.phy_reset		= mv_phy_reset,
+ 
+-	.qc_prep		= ata_qc_prep,
+-	.qc_issue		= ata_qc_issue_prot,
++	.qc_prep		= mv_qc_prep,
++	.qc_issue		= mv_qc_issue,
+ 
+-	.eng_timeout		= ata_eng_timeout,
++	.eng_timeout		= mv_eng_timeout,
+ 
+ 	.irq_handler		= mv_interrupt,
+ 	.irq_clear		= mv_irq_clear,
+@@ -232,46 +312,39 @@ static struct ata_port_operations mv_ops
+ 	.scr_read		= mv_scr_read,
+ 	.scr_write		= mv_scr_write,
+ 
+-	.port_start		= ata_port_start,
+-	.port_stop		= ata_port_stop,
+-	.host_stop		= ata_host_stop,
++	.port_start		= mv_port_start,
++	.port_stop		= mv_port_stop,
++	.host_stop		= mv_host_stop,
+ };
+ 
+ static struct ata_port_info mv_port_info[] = {
+ 	{  /* chip_504x */
+ 		.sht		= &mv_sht,
+-		.host_flags	= (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+-				   ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
+-		.pio_mask	= 0x1f,	/* pio4-0 */
+-		.udma_mask	= 0,	/* 0x7f (udma6-0 disabled for now) */
++		.host_flags	= MV_COMMON_FLAGS,
++		.pio_mask	= 0x1f,	/* pio0-4 */
++		.udma_mask	= 0,	/* 0x7f (udma0-6 disabled for now) */
+ 		.port_ops	= &mv_ops,
+ 	},
+ 	{  /* chip_508x */
+ 		.sht		= &mv_sht,
+-		.host_flags	= (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+-				   ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 
+-				   MV_FLAG_DUAL_HC),
+-		.pio_mask	= 0x1f,	/* pio4-0 */
+-		.udma_mask	= 0,	/* 0x7f (udma6-0 disabled for now) */
++		.host_flags	= (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
++		.pio_mask	= 0x1f,	/* pio0-4 */
++		.udma_mask	= 0,	/* 0x7f (udma0-6 disabled for now) */
+ 		.port_ops	= &mv_ops,
+ 	},
+ 	{  /* chip_604x */
+ 		.sht		= &mv_sht,
+-		.host_flags	= (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+-				   ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 
+-				   MV_FLAG_IRQ_COALESCE | MV_FLAG_BDMA),
+-		.pio_mask	= 0x1f,	/* pio4-0 */
+-		.udma_mask	= 0,	/* 0x7f (udma6-0 disabled for now) */
++		.host_flags	= (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
++		.pio_mask	= 0x1f,	/* pio0-4 */
++		.udma_mask	= 0x7f,	/* udma0-6 */
+ 		.port_ops	= &mv_ops,
+ 	},
+ 	{  /* chip_608x */
+ 		.sht		= &mv_sht,
+-		.host_flags	= (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+-				   ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+-				   MV_FLAG_IRQ_COALESCE | MV_FLAG_DUAL_HC |
+-				   MV_FLAG_BDMA),
+-		.pio_mask	= 0x1f,	/* pio4-0 */
+-		.udma_mask	= 0,	/* 0x7f (udma6-0 disabled for now) */
++		.host_flags	= (MV_COMMON_FLAGS | MV_6XXX_FLAGS | 
++				   MV_FLAG_DUAL_HC),
++		.pio_mask	= 0x1f,	/* pio0-4 */
++		.udma_mask	= 0x7f,	/* udma0-6 */
+ 		.port_ops	= &mv_ops,
+ 	},
+ };
+@@ -306,12 +379,6 @@ static inline void writelfl(unsigned lon
+ 	(void) readl(addr);	/* flush to avoid PCI posted write */
+ }
+ 
+-static inline void __iomem *mv_port_addr_to_hc_base(void __iomem *port_mmio)
+-{
+-	return ((void __iomem *)((unsigned long)port_mmio & 
+-				 (unsigned long)SATAHC_MASK));
+-}
+-
+ static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc)
+ {
+ 	return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ));
+@@ -329,24 +396,150 @@ static inline void __iomem *mv_ap_base(s
+ 	return mv_port_base(ap->host_set->mmio_base, ap->port_no);
+ }
+ 
+-static inline int mv_get_hc_count(unsigned long flags)
++static inline int mv_get_hc_count(unsigned long hp_flags)
++{
++	return ((hp_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
++}
++
++static void mv_irq_clear(struct ata_port *ap)
+ {
+-	return ((flags & MV_FLAG_DUAL_HC) ? 2 : 1);
+ }
+ 
+-static inline int mv_is_edma_active(struct ata_port *ap)
++/**
++ *      mv_start_dma - Enable eDMA engine
++ *      @base: port base address
++ *      @pp: port private data
++ *
++ *      Verify the local cache of the eDMA state is accurate with an
++ *      assert.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp)
++{
++	if (!(MV_PP_FLAG_EDMA_EN & pp->pp_flags)) {
++		writelfl(EDMA_EN, base + EDMA_CMD_OFS);
++		pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
++	}
++	assert(EDMA_EN & readl(base + EDMA_CMD_OFS));
++}
++
++/**
++ *      mv_stop_dma - Disable eDMA engine
++ *      @ap: ATA channel to manipulate
++ *
++ *      Verify the local cache of the eDMA state is accurate with an
++ *      assert.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static void mv_stop_dma(struct ata_port *ap)
+ {
+ 	void __iomem *port_mmio = mv_ap_base(ap);
+-	return (EDMA_EN & readl(port_mmio + EDMA_CMD_OFS));
++	struct mv_port_priv *pp	= ap->private_data;
++	u32 reg;
++	int i;
++
++	if (MV_PP_FLAG_EDMA_EN & pp->pp_flags) {
++		/* Disable EDMA if active.   The disable bit auto clears.
++		 */
++		writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
++		pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
++	} else {
++		assert(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS)));
++  	}
++	
++	/* now properly wait for the eDMA to stop */
++	for (i = 1000; i > 0; i--) {
++		reg = readl(port_mmio + EDMA_CMD_OFS);
++		if (!(EDMA_EN & reg)) {
++			break;
++		}
++		udelay(100);
++	}
++
++	if (EDMA_EN & reg) {
++		printk(KERN_ERR "ata%u: Unable to stop eDMA\n", ap->id);
++		/* FIXME: Consider doing a reset here to recover */
++	}
+ }
+ 
+-static inline int mv_port_bdma_capable(struct ata_port *ap)
++#ifdef ATA_DEBUG
++static void mv_dump_mem(void __iomem *start, unsigned bytes)
+ {
+-	return (ap->flags & MV_FLAG_BDMA);
++	int b, w;
++	for (b = 0; b < bytes; ) {
++		DPRINTK("%p: ", start + b);
++		for (w = 0; b < bytes && w < 4; w++) {
++			printk("%08x ",readl(start + b));
++			b += sizeof(u32);
++		}
++		printk("\n");
++	}
+ }
++#endif
+ 
+-static void mv_irq_clear(struct ata_port *ap)
++static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes)
+ {
++#ifdef ATA_DEBUG
++	int b, w;
++	u32 dw;
++	for (b = 0; b < bytes; ) {
++		DPRINTK("%02x: ", b);
++		for (w = 0; b < bytes && w < 4; w++) {
++			(void) pci_read_config_dword(pdev,b,&dw);
++			printk("%08x ",dw);
++			b += sizeof(u32);
++		}
++		printk("\n");
++	}
++#endif
++}
++static void mv_dump_all_regs(void __iomem *mmio_base, int port,
++			     struct pci_dev *pdev)
++{
++#ifdef ATA_DEBUG
++	void __iomem *hc_base = mv_hc_base(mmio_base, 
++					   port >> MV_PORT_HC_SHIFT);
++	void __iomem *port_base;
++	int start_port, num_ports, p, start_hc, num_hcs, hc;
++
++	if (0 > port) {
++		start_hc = start_port = 0;
++		num_ports = 8;		/* shld be benign for 4 port devs */
++		num_hcs = 2;
++	} else {
++		start_hc = port >> MV_PORT_HC_SHIFT;
++		start_port = port;
++		num_ports = num_hcs = 1;
++	}
++	DPRINTK("All registers for port(s) %u-%u:\n", start_port, 
++		num_ports > 1 ? num_ports - 1 : start_port);
++
++	if (NULL != pdev) {
++		DPRINTK("PCI config space regs:\n");
++		mv_dump_pci_cfg(pdev, 0x68);
++	}
++	DPRINTK("PCI regs:\n");
++	mv_dump_mem(mmio_base+0xc00, 0x3c);
++	mv_dump_mem(mmio_base+0xd00, 0x34);
++	mv_dump_mem(mmio_base+0xf00, 0x4);
++	mv_dump_mem(mmio_base+0x1d00, 0x6c);
++	for (hc = start_hc; hc < start_hc + num_hcs; hc++) {
++		hc_base = mv_hc_base(mmio_base, port >> MV_PORT_HC_SHIFT);
++		DPRINTK("HC regs (HC %i):\n", hc);
++		mv_dump_mem(hc_base, 0x1c);
++	}
++	for (p = start_port; p < start_port + num_ports; p++) {
++		port_base = mv_port_base(mmio_base, p);
++		DPRINTK("EDMA regs (port %i):\n",p);
++		mv_dump_mem(port_base, 0x54);
++		DPRINTK("SATA regs (port %i):\n",p);
++		mv_dump_mem(port_base+0x300, 0x60);
++	}
++#endif
+ }
+ 
+ static unsigned int mv_scr_offset(unsigned int sc_reg_in)
+@@ -389,30 +582,37 @@ static void mv_scr_write(struct ata_port
+ 	}
+ }
+ 
+-static int mv_master_reset(void __iomem *mmio_base)
++/**
++ *      mv_global_soft_reset - Perform the 6xxx global soft reset
++ *      @mmio_base: base address of the HBA
++ *
++ *      This routine only applies to 6xxx parts.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static int mv_global_soft_reset(void __iomem *mmio_base)
+ {
+ 	void __iomem *reg = mmio_base + PCI_MAIN_CMD_STS_OFS;
+ 	int i, rc = 0;
+ 	u32 t;
+ 
+-	VPRINTK("ENTER\n");
+-
+ 	/* Following procedure defined in PCI "main command and status
+ 	 * register" table.
+ 	 */
+ 	t = readl(reg);
+ 	writel(t | STOP_PCI_MASTER, reg);
+ 
+-	for (i = 0; i < 100; i++) {
+-		msleep(10);
++	for (i = 0; i < 1000; i++) {
++		udelay(1);
+ 		t = readl(reg);
+ 		if (PCI_MASTER_EMPTY & t) {
+ 			break;
+ 		}
+ 	}
+ 	if (!(PCI_MASTER_EMPTY & t)) {
+-		printk(KERN_ERR DRV_NAME "PCI master won't flush\n");
+-		rc = 1;		/* broken HW? */
++		printk(KERN_ERR DRV_NAME ": PCI master won't flush\n");
++		rc = 1;
+ 		goto done;
+ 	}
+ 
+@@ -425,39 +625,399 @@ static int mv_master_reset(void __iomem 
+ 	} while (!(GLOB_SFT_RST & t) && (i-- > 0));
+ 
+ 	if (!(GLOB_SFT_RST & t)) {
+-		printk(KERN_ERR DRV_NAME "can't set global reset\n");
+-		rc = 1;		/* broken HW? */
++		printk(KERN_ERR DRV_NAME ": can't set global reset\n");
++		rc = 1;
+ 		goto done;
+ 	}
+ 
+-	/* clear reset */
++	/* clear reset and *reenable the PCI master* (not mentioned in spec) */
+ 	i = 5;
+ 	do {
+-		writel(t & ~GLOB_SFT_RST, reg);
++		writel(t & ~(GLOB_SFT_RST | STOP_PCI_MASTER), reg);
+ 		t = readl(reg);
+ 		udelay(1);
+ 	} while ((GLOB_SFT_RST & t) && (i-- > 0));
+ 
+ 	if (GLOB_SFT_RST & t) {
+-		printk(KERN_ERR DRV_NAME "can't clear global reset\n");
+-		rc = 1;		/* broken HW? */
++		printk(KERN_ERR DRV_NAME ": can't clear global reset\n");
++		rc = 1;
+ 	}
+-
+- done:
+-	VPRINTK("EXIT, rc = %i\n", rc);
++done:
+ 	return rc;
+ }
+ 
+-static void mv_err_intr(struct ata_port *ap)
++/**
++ *      mv_host_stop - Host specific cleanup/stop routine.
++ *      @host_set: host data structure
++ *
++ *      Disable ints, cleanup host memory, call general purpose
++ *      host_stop.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static void mv_host_stop(struct ata_host_set *host_set)
+ {
+-	void __iomem *port_mmio;
+-	u32 edma_err_cause, serr = 0;
++	struct mv_host_priv *hpriv = host_set->private_data;
++	struct pci_dev *pdev = to_pci_dev(host_set->dev);
++
++	if (hpriv->hp_flags & MV_HP_FLAG_MSI) {
++		pci_disable_msi(pdev);
++	} else {
++		pci_intx(pdev, 0);
++	}
++	kfree(hpriv);
++	ata_host_stop(host_set);
++}
++
++/**
++ *      mv_port_start - Port specific init/start routine.
++ *      @ap: ATA channel to manipulate
++ *
++ *      Allocate and point to DMA memory, init port private memory,
++ *      zero indices.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static int mv_port_start(struct ata_port *ap)
++{
++	struct device *dev = ap->host_set->dev;
++	struct mv_port_priv *pp;
++	void __iomem *port_mmio = mv_ap_base(ap);
++	void *mem;
++	dma_addr_t mem_dma;
++
++	pp = kmalloc(sizeof(*pp), GFP_KERNEL);
++	if (!pp) {
++		return -ENOMEM;
++	}
++	memset(pp, 0, sizeof(*pp));
++
++	mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, 
++				 GFP_KERNEL);
++	if (!mem) {
++		kfree(pp);
++		return -ENOMEM;
++	}
++	memset(mem, 0, MV_PORT_PRIV_DMA_SZ);
++
++	/* First item in chunk of DMA memory: 
++	 * 32-slot command request table (CRQB), 32 bytes each in size
++	 */
++	pp->crqb = mem;
++	pp->crqb_dma = mem_dma;
++	mem += MV_CRQB_Q_SZ;
++	mem_dma += MV_CRQB_Q_SZ;
++
++	/* Second item: 
++	 * 32-slot command response table (CRPB), 8 bytes each in size
++	 */
++	pp->crpb = mem;
++	pp->crpb_dma = mem_dma;
++	mem += MV_CRPB_Q_SZ;
++	mem_dma += MV_CRPB_Q_SZ;
++
++	/* Third item:
++	 * Table of scatter-gather descriptors (ePRD), 16 bytes each
++	 */
++	pp->sg_tbl = mem;
++	pp->sg_tbl_dma = mem_dma;
+ 
+-	/* bug here b/c we got an err int on a port we don't know about,
+-	 * so there's no way to clear it
++	writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT | 
++		 EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS);
++
++	writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
++	writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK, 
++		 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
++
++	writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
++	writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
++
++	writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
++	writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, 
++		 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
++
++	pp->req_producer = pp->rsp_consumer = 0;
++
++	/* Don't turn on EDMA here...do it before DMA commands only.  Else
++	 * we'll be unable to send non-data, PIO, etc due to restricted access
++	 * to shadow regs.
+ 	 */
+-	BUG_ON(NULL == ap);
+-	port_mmio = mv_ap_base(ap);
++	ap->private_data = pp;
++	return 0;
++}
++
++/**
++ *      mv_port_stop - Port specific cleanup/stop routine.
++ *      @ap: ATA channel to manipulate
++ *
++ *      Stop DMA, cleanup port memory.
++ *
++ *      LOCKING:
++ *      This routine uses the host_set lock to protect the DMA stop.
++ */
++static void mv_port_stop(struct ata_port *ap)
++{
++	struct device *dev = ap->host_set->dev;
++	struct mv_port_priv *pp = ap->private_data;
++	unsigned long flags;
++
++	spin_lock_irqsave(&ap->host_set->lock, flags);
++	mv_stop_dma(ap);
++	spin_unlock_irqrestore(&ap->host_set->lock, flags);
++
++	ap->private_data = NULL;
++	dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma);
++	kfree(pp);
++}
++
++/**
++ *      mv_fill_sg - Fill out the Marvell ePRD (scatter gather) entries
++ *      @qc: queued command whose SG list to source from
++ *
++ *      Populate the SG list and mark the last entry.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static void mv_fill_sg(struct ata_queued_cmd *qc)
++{
++	struct mv_port_priv *pp = qc->ap->private_data;
++	unsigned int i;
++
++	for (i = 0; i < qc->n_elem; i++) {
++		u32 sg_len;
++		dma_addr_t addr;
++
++		addr = sg_dma_address(&qc->sg[i]);
++		sg_len = sg_dma_len(&qc->sg[i]);
++
++		pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
++		pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
++		assert(0 == (sg_len & ~MV_DMA_BOUNDARY));
++		pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len);
++	}
++	if (0 < qc->n_elem) {
++		pp->sg_tbl[qc->n_elem - 1].flags_size |= 
++			cpu_to_le32(EPRD_FLAG_END_OF_TBL);
++	}
++}
++
++static inline unsigned mv_inc_q_index(unsigned *index)
++{
++	*index = (*index + 1) & MV_MAX_Q_DEPTH_MASK;
++	return *index;
++}
++
++static inline void mv_crqb_pack_cmd(u16 *cmdw, u8 data, u8 addr, unsigned last)
++{
++	*cmdw = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS |
++		(last ? CRQB_CMD_LAST : 0);
++}
++
++/**
++ *      mv_qc_prep - Host specific command preparation.
++ *      @qc: queued command to prepare
++ *
++ *      This routine simply redirects to the general purpose routine
++ *      if command is not DMA.  Else, it handles prep of the CRQB
++ *      (command request block), does some sanity checking, and calls
++ *      the SG load routine.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static void mv_qc_prep(struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	struct mv_port_priv *pp = ap->private_data;
++	u16 *cw;
++	struct ata_taskfile *tf;
++	u16 flags = 0;
++
++ 	if (ATA_PROT_DMA != qc->tf.protocol) {
++		return;
++	}
++
++	/* the req producer index should be the same as we remember it */
++	assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> 
++		 EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
++	       pp->req_producer);
++
++	/* Fill in command request block
++	 */
++	if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
++		flags |= CRQB_FLAG_READ;
++	}
++	assert(MV_MAX_Q_DEPTH > qc->tag);
++	flags |= qc->tag << CRQB_TAG_SHIFT;
++
++	pp->crqb[pp->req_producer].sg_addr = 
++		cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
++	pp->crqb[pp->req_producer].sg_addr_hi = 
++		cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16);
++	pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags);
++
++	cw = &pp->crqb[pp->req_producer].ata_cmd[0];
++	tf = &qc->tf;
++
++	/* Sadly, the CRQB cannot accomodate all registers--there are
++	 * only 11 bytes...so we must pick and choose required
++	 * registers based on the command.  So, we drop feature and
++	 * hob_feature for [RW] DMA commands, but they are needed for
++	 * NCQ.  NCQ will drop hob_nsect.
++	 */
++	switch (tf->command) {
++	case ATA_CMD_READ:
++	case ATA_CMD_READ_EXT:
++	case ATA_CMD_WRITE:
++	case ATA_CMD_WRITE_EXT:
++		mv_crqb_pack_cmd(cw++, tf->hob_nsect, ATA_REG_NSECT, 0);
++		break;
++#ifdef LIBATA_NCQ		/* FIXME: remove this line when NCQ added */
++	case ATA_CMD_FPDMA_READ:
++	case ATA_CMD_FPDMA_WRITE:
++		mv_crqb_pack_cmd(cw++, tf->hob_feature, ATA_REG_FEATURE, 0); 
++		mv_crqb_pack_cmd(cw++, tf->feature, ATA_REG_FEATURE, 0);
++		break;
++#endif				/* FIXME: remove this line when NCQ added */
++	default:
++		/* The only other commands EDMA supports in non-queued and
++		 * non-NCQ mode are: [RW] STREAM DMA and W DMA FUA EXT, none
++		 * of which are defined/used by Linux.  If we get here, this
++		 * driver needs work.
++		 *
++		 * FIXME: modify libata to give qc_prep a return value and
++		 * return error here.
++		 */
++		BUG_ON(tf->command);
++		break;
++	}
++	mv_crqb_pack_cmd(cw++, tf->nsect, ATA_REG_NSECT, 0);
++	mv_crqb_pack_cmd(cw++, tf->hob_lbal, ATA_REG_LBAL, 0);
++	mv_crqb_pack_cmd(cw++, tf->lbal, ATA_REG_LBAL, 0);
++	mv_crqb_pack_cmd(cw++, tf->hob_lbam, ATA_REG_LBAM, 0);
++	mv_crqb_pack_cmd(cw++, tf->lbam, ATA_REG_LBAM, 0);
++	mv_crqb_pack_cmd(cw++, tf->hob_lbah, ATA_REG_LBAH, 0);
++	mv_crqb_pack_cmd(cw++, tf->lbah, ATA_REG_LBAH, 0);
++	mv_crqb_pack_cmd(cw++, tf->device, ATA_REG_DEVICE, 0);
++	mv_crqb_pack_cmd(cw++, tf->command, ATA_REG_CMD, 1);	/* last */
++
++	if (!(qc->flags & ATA_QCFLAG_DMAMAP)) {
++		return;
++	}
++	mv_fill_sg(qc);
++}
++
++/**
++ *      mv_qc_issue - Initiate a command to the host
++ *      @qc: queued command to start
++ *
++ *      This routine simply redirects to the general purpose routine
++ *      if command is not DMA.  Else, it sanity checks our local
++ *      caches of the request producer/consumer indices then enables
++ *      DMA and bumps the request producer index.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static int mv_qc_issue(struct ata_queued_cmd *qc)
++{
++	void __iomem *port_mmio = mv_ap_base(qc->ap);
++	struct mv_port_priv *pp = qc->ap->private_data;
++	u32 in_ptr;
++
++	if (ATA_PROT_DMA != qc->tf.protocol) {
++		/* We're about to send a non-EDMA capable command to the
++		 * port.  Turn off EDMA so there won't be problems accessing
++		 * shadow block, etc registers.
++		 */
++		mv_stop_dma(qc->ap);
++		return ata_qc_issue_prot(qc);
++	}
++
++	in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
++
++	/* the req producer index should be the same as we remember it */
++	assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
++	       pp->req_producer);
++	/* until we do queuing, the queue should be empty at this point */
++	assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
++	       ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >> 
++		 EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
++
++	mv_inc_q_index(&pp->req_producer);	/* now incr producer index */
++
++	mv_start_dma(port_mmio, pp);
++
++	/* and write the request in pointer to kick the EDMA to life */
++	in_ptr &= EDMA_REQ_Q_BASE_LO_MASK;
++	in_ptr |= pp->req_producer << EDMA_REQ_Q_PTR_SHIFT;
++	writelfl(in_ptr, port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
++
++	return 0;
++}
++
++/**
++ *      mv_get_crpb_status - get status from most recently completed cmd
++ *      @ap: ATA channel to manipulate
++ *
++ *      This routine is for use when the port is in DMA mode, when it
++ *      will be using the CRPB (command response block) method of
++ *      returning command completion information.  We assert indices
++ *      are good, grab status, and bump the response consumer index to
++ *      prove that we're up to date.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static u8 mv_get_crpb_status(struct ata_port *ap)
++{
++	void __iomem *port_mmio = mv_ap_base(ap);
++	struct mv_port_priv *pp = ap->private_data;
++	u32 out_ptr;
++
++	out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
++
++	/* the response consumer index should be the same as we remember it */
++	assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == 
++	       pp->rsp_consumer);
++
++	/* increment our consumer index... */
++	pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer);
++	
++	/* and, until we do NCQ, there should only be 1 CRPB waiting */
++	assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >> 
++		 EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == 
++	       pp->rsp_consumer);
++
++	/* write out our inc'd consumer index so EDMA knows we're caught up */
++	out_ptr &= EDMA_RSP_Q_BASE_LO_MASK;
++	out_ptr |= pp->rsp_consumer << EDMA_RSP_Q_PTR_SHIFT;
++	writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
++
++	/* Return ATA status register for completed CRPB */
++	return (pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT);
++}
++
++/**
++ *      mv_err_intr - Handle error interrupts on the port
++ *      @ap: ATA channel to manipulate
++ *
++ *      In most cases, just clear the interrupt and move on.  However,
++ *      some cases require an eDMA reset, which is done right before
++ *      the COMRESET in mv_phy_reset().  The SERR case requires a
++ *      clear of pending errors in the SATA SERROR register.  Finally,
++ *      if the port disabled DMA, update our cached copy to match.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static void mv_err_intr(struct ata_port *ap)
++{
++	void __iomem *port_mmio = mv_ap_base(ap);
++	u32 edma_err_cause, serr = 0;
+ 
+ 	edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+ 
+@@ -465,8 +1025,12 @@ static void mv_err_intr(struct ata_port 
+ 		serr = scr_read(ap, SCR_ERROR);
+ 		scr_write_flush(ap, SCR_ERROR, serr);
+ 	}
+-	DPRINTK("port %u error; EDMA err cause: 0x%08x SERR: 0x%08x\n", 
+-		ap->port_no, edma_err_cause, serr);
++	if (EDMA_ERR_SELF_DIS & edma_err_cause) {
++		struct mv_port_priv *pp	= ap->private_data;
++		pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
++	}
++	DPRINTK(KERN_ERR "ata%u: port error; EDMA err cause: 0x%08x "
++		"SERR: 0x%08x\n", ap->id, edma_err_cause, serr);
+ 
+ 	/* Clear EDMA now that SERR cleanup done */
+ 	writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+@@ -477,7 +1041,21 @@ static void mv_err_intr(struct ata_port 
+ 	}
+ }
+ 
+-/* Handle any outstanding interrupts in a single SATAHC 
++/**
++ *      mv_host_intr - Handle all interrupts on the given host controller
++ *      @host_set: host specific structure
++ *      @relevant: port error bits relevant to this host controller
++ *      @hc: which host controller we're to look at
++ *
++ *      Read then write clear the HC interrupt status then walk each
++ *      port connected to the HC and see if it needs servicing.  Port
++ *      success ints are reported in the HC interrupt status reg, the
++ *      port error ints are reported in the higher level main
++ *      interrupt status register and thus are passed in via the
++ *      'relevant' argument.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
+  */
+ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
+ 			 unsigned int hc)
+@@ -487,8 +1065,9 @@ static void mv_host_intr(struct ata_host
+ 	struct ata_port *ap;
+ 	struct ata_queued_cmd *qc;
+ 	u32 hc_irq_cause;
+-	int shift, port, port0, hard_port;
+-	u8 ata_status;
++	int shift, port, port0, hard_port, handled;
++	unsigned int err_mask;
++	u8 ata_status = 0;
+ 
+ 	if (hc == 0) {
+ 		port0 = 0;
+@@ -499,7 +1078,7 @@ static void mv_host_intr(struct ata_host
+ 	/* we'll need the HC success int register in most cases */
+ 	hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
+ 	if (hc_irq_cause) {
+-		writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
++		writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+ 	}
+ 
+ 	VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
+@@ -508,54 +1087,70 @@ static void mv_host_intr(struct ata_host
+ 	for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) {
+ 		ap = host_set->ports[port];
+ 		hard_port = port & MV_PORT_MASK;	/* range 0-3 */
+-		ata_status = 0xffU;
++		handled = 0;	/* ensure ata_status is set if handled++ */
+ 
+-		if (((CRBP_DMA_DONE | DEV_IRQ) << hard_port) & hc_irq_cause) {
+-			BUG_ON(NULL == ap);
+-			/* rcv'd new resp, basic DMA complete, or ATA IRQ */
+-			/* This is needed to clear the ATA INTRQ.
+-			 * FIXME: don't read the status reg in EDMA mode!
++		if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) {
++			/* new CRPB on the queue; just one at a time until NCQ
++			 */
++			ata_status = mv_get_crpb_status(ap);
++			handled++;
++		} else if ((DEV_IRQ << hard_port) & hc_irq_cause) {
++			/* received ATA IRQ; read the status reg to clear INTRQ
+ 			 */
+ 			ata_status = readb((void __iomem *)
+ 					   ap->ioaddr.status_addr);
++			handled++;
+ 		}
+ 
+-		shift = port * 2;
++		err_mask = ac_err_mask(ata_status);
++
++		shift = port << 1;		/* (port * 2) */
+ 		if (port >= MV_PORTS_PER_HC) {
+ 			shift++;	/* skip bit 8 in the HC Main IRQ reg */
+ 		}
+ 		if ((PORT0_ERR << shift) & relevant) {
+ 			mv_err_intr(ap);
+-			/* FIXME: smart to OR in ATA_ERR? */
+-			ata_status = readb((void __iomem *)
+-					   ap->ioaddr.status_addr) | ATA_ERR;
++			err_mask |= AC_ERR_OTHER;
++			handled++;
+ 		}
+ 		
+-		if (ap) {
++		if (handled && ap) {
+ 			qc = ata_qc_from_tag(ap, ap->active_tag);
+ 			if (NULL != qc) {
+ 				VPRINTK("port %u IRQ found for qc, "
+ 					"ata_status 0x%x\n", port,ata_status);
+-				BUG_ON(0xffU == ata_status);
+ 				/* mark qc status appropriately */
+-				ata_qc_complete(qc, ata_status);
++				ata_qc_complete(qc, err_mask);
+ 			}
+ 		}
+ 	}
+ 	VPRINTK("EXIT\n");
+ }
+ 
++/**
++ *      mv_interrupt - 
++ *      @irq: unused
++ *      @dev_instance: private data; in this case the host structure
++ *      @regs: unused
++ *
++ *      Read the read only register to determine if any host
++ *      controllers have pending interrupts.  If so, call lower level
++ *      routine to handle.  Also check for PCI errors which are only
++ *      reported here.
++ *
++ *      LOCKING: 
++ *      This routine holds the host_set lock while processing pending
++ *      interrupts.
++ */
+ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
+ 				struct pt_regs *regs)
+ {
+ 	struct ata_host_set *host_set = dev_instance;
+ 	unsigned int hc, handled = 0, n_hcs;
+-	void __iomem *mmio;
++	void __iomem *mmio = host_set->mmio_base;
+ 	u32 irq_stat;
+ 
+-	mmio = host_set->mmio_base;
+ 	irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS);
+-	n_hcs = mv_get_hc_count(host_set->ports[0]->flags);
+ 
+ 	/* check the cases where we either have nothing pending or have read
+ 	 * a bogus register value which can indicate HW removal or PCI fault
+@@ -564,64 +1159,89 @@ static irqreturn_t mv_interrupt(int irq,
+ 		return IRQ_NONE;
+ 	}
+ 
++	n_hcs = mv_get_hc_count(host_set->ports[0]->flags);
+ 	spin_lock(&host_set->lock);
+ 
+ 	for (hc = 0; hc < n_hcs; hc++) {
+ 		u32 relevant = irq_stat & (HC0_IRQ_PEND << (hc * HC_SHIFT));
+ 		if (relevant) {
+ 			mv_host_intr(host_set, relevant, hc);
+-			handled = 1;
++			handled++;
+ 		}
+ 	}
+ 	if (PCI_ERR & irq_stat) {
+-		/* FIXME: these are all masked by default, but still need
+-		 * to recover from them properly.
+-		 */
+-	}
++		printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n",
++		       readl(mmio + PCI_IRQ_CAUSE_OFS));
++
++		DPRINTK("All regs @ PCI error\n");
++		mv_dump_all_regs(mmio, -1, to_pci_dev(host_set->dev));
+ 
++		writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
++		handled++;
++	}
+ 	spin_unlock(&host_set->lock);
+ 
+ 	return IRQ_RETVAL(handled);
+ }
+ 
++/**
++ *      mv_phy_reset - Perform eDMA reset followed by COMRESET
++ *      @ap: ATA channel to manipulate
++ *
++ *      Part of this is taken from __sata_phy_reset and modified to
++ *      not sleep since this routine gets called from interrupt level.
++ *
++ *      LOCKING:
++ *      Inherited from caller.  This is coded to safe to call at
++ *      interrupt level, i.e. it does not sleep.
++ */
+ static void mv_phy_reset(struct ata_port *ap)
+ {
+ 	void __iomem *port_mmio = mv_ap_base(ap);
+ 	struct ata_taskfile tf;
+ 	struct ata_device *dev = &ap->device[0];
+-	u32 edma = 0, bdma;
++	unsigned long timeout;
+ 
+ 	VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio);
+ 
+-	edma = readl(port_mmio + EDMA_CMD_OFS);
+-	if (EDMA_EN & edma) {
+-		/* disable EDMA if active */
+-		edma &= ~EDMA_EN;
+-		writelfl(edma | EDMA_DS, port_mmio + EDMA_CMD_OFS);
+-		udelay(1);
+-	} else if (mv_port_bdma_capable(ap) &&
+-		   (bdma = readl(port_mmio + BDMA_CMD_OFS)) & BDMA_START) {
+-		/* disable BDMA if active */
+-		writelfl(bdma & ~BDMA_START, port_mmio + BDMA_CMD_OFS);
+-	}
++	mv_stop_dma(ap);
+ 
+-	writelfl(edma | ATA_RST, port_mmio + EDMA_CMD_OFS);
++	writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
+ 	udelay(25);		/* allow reset propagation */
+ 
+ 	/* Spec never mentions clearing the bit.  Marvell's driver does
+ 	 * clear the bit, however.
+ 	 */
+-	writelfl(edma & ~ATA_RST, port_mmio + EDMA_CMD_OFS);
++	writelfl(0, port_mmio + EDMA_CMD_OFS);
+ 
+-	VPRINTK("Done.  Now calling __sata_phy_reset()\n");
++	VPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
++		"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
++		mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
+ 
+ 	/* proceed to init communications via the scr_control reg */
+-	__sata_phy_reset(ap);
++	scr_write_flush(ap, SCR_CONTROL, 0x301);
++	mdelay(1);
++	scr_write_flush(ap, SCR_CONTROL, 0x300);
++	timeout = jiffies + (HZ * 1);
++	do {
++		mdelay(10);
++		if ((scr_read(ap, SCR_STATUS) & 0xf) != 1)
++			break;
++	} while (time_before(jiffies, timeout));
+ 
+-	if (ap->flags & ATA_FLAG_PORT_DISABLED) {
+-		VPRINTK("Port disabled pre-sig.  Exiting.\n");
++	VPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
++		"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
++		mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
++
++	if (sata_dev_present(ap)) {
++		ata_port_probe(ap);
++	} else {
++		printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n",
++		       ap->id, scr_read(ap, SCR_STATUS));
++		ata_port_disable(ap);
+ 		return;
+ 	}
++	ap->cbl = ATA_CBL_SATA;
+ 
+ 	tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr);
+ 	tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr);
+@@ -636,37 +1256,118 @@ static void mv_phy_reset(struct ata_port
+ 	VPRINTK("EXIT\n");
+ }
+ 
+-static void mv_port_init(struct ata_ioports *port, unsigned long base)
++/**
++ *      mv_eng_timeout - Routine called by libata when SCSI times out I/O
++ *      @ap: ATA channel to manipulate
++ *
++ *      Intent is to clear all pending error conditions, reset the
++ *      chip/bus, fail the command, and move on.
++ *
++ *      LOCKING:
++ *      This routine holds the host_set lock while failing the command.
++ */
++static void mv_eng_timeout(struct ata_port *ap)
+ {
+-	/* PIO related setup */
+-	port->data_addr = base + SHD_PIO_DATA_OFS;
+-	port->error_addr = port->feature_addr = base + SHD_FEA_ERR_OFS;
+-	port->nsect_addr = base + SHD_SECT_CNT_OFS;
+-	port->lbal_addr = base + SHD_LBA_L_OFS;
+-	port->lbam_addr = base + SHD_LBA_M_OFS;
+-	port->lbah_addr = base + SHD_LBA_H_OFS;
+-	port->device_addr = base + SHD_DEV_HD_OFS;
+-	port->status_addr = port->command_addr = base + SHD_CMD_STA_OFS;
+-	port->altstatus_addr = port->ctl_addr = base + SHD_CTL_AST_OFS;
+-	/* unused */
++	struct ata_queued_cmd *qc;
++	unsigned long flags;
++
++	printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id);
++	DPRINTK("All regs @ start of eng_timeout\n");
++	mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no, 
++			 to_pci_dev(ap->host_set->dev));
++
++	qc = ata_qc_from_tag(ap, ap->active_tag);
++        printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n",
++	       ap->host_set->mmio_base, ap, qc, qc->scsicmd, 
++	       &qc->scsicmd->cmnd);
++
++	mv_err_intr(ap);
++	mv_phy_reset(ap);
++
++	if (!qc) {
++		printk(KERN_ERR "ata%u: BUG: timeout without command\n",
++		       ap->id);
++	} else {
++		/* hack alert!  We cannot use the supplied completion
++	 	 * function from inside the ->eh_strategy_handler() thread.
++	 	 * libata is the only user of ->eh_strategy_handler() in
++	 	 * any kernel, so the default scsi_done() assumes it is
++	 	 * not being called from the SCSI EH.
++	 	 */
++		spin_lock_irqsave(&ap->host_set->lock, flags);
++		qc->scsidone = scsi_finish_command;
++		ata_qc_complete(qc, AC_ERR_OTHER);
++		spin_unlock_irqrestore(&ap->host_set->lock, flags);
++	}
++}
++
++/**
++ *      mv_port_init - Perform some early initialization on a single port.
++ *      @port: libata data structure storing shadow register addresses
++ *      @port_mmio: base address of the port
++ *
++ *      Initialize shadow register mmio addresses, clear outstanding
++ *      interrupts on the port, and unmask interrupts for the future
++ *      start of the port.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static void mv_port_init(struct ata_ioports *port,  void __iomem *port_mmio)
++{
++	unsigned long shd_base = (unsigned long) port_mmio + SHD_BLK_OFS;
++	unsigned serr_ofs;
++
++	/* PIO related setup 
++	 */
++	port->data_addr = shd_base + (sizeof(u32) * ATA_REG_DATA);
++	port->error_addr = 
++		port->feature_addr = shd_base + (sizeof(u32) * ATA_REG_ERR);
++	port->nsect_addr = shd_base + (sizeof(u32) * ATA_REG_NSECT);
++	port->lbal_addr = shd_base + (sizeof(u32) * ATA_REG_LBAL);
++	port->lbam_addr = shd_base + (sizeof(u32) * ATA_REG_LBAM);
++	port->lbah_addr = shd_base + (sizeof(u32) * ATA_REG_LBAH);
++	port->device_addr = shd_base + (sizeof(u32) * ATA_REG_DEVICE);
++	port->status_addr = 
++		port->command_addr = shd_base + (sizeof(u32) * ATA_REG_STATUS);
++	/* special case: control/altstatus doesn't have ATA_REG_ address */
++	port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS;
++
++	/* unused: */
+ 	port->cmd_addr = port->bmdma_addr = port->scr_addr = 0;
+ 
++	/* Clear any currently outstanding port interrupt conditions */
++	serr_ofs = mv_scr_offset(SCR_ERROR);
++	writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs);
++	writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
++
+ 	/* unmask all EDMA error interrupts */
+-	writel(~0, (void __iomem *)base + EDMA_ERR_IRQ_MASK_OFS);
++	writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS);
+ 
+ 	VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n", 
+-		readl((void __iomem *)base + EDMA_CFG_OFS),
+-		readl((void __iomem *)base + EDMA_ERR_IRQ_CAUSE_OFS),
+-		readl((void __iomem *)base + EDMA_ERR_IRQ_MASK_OFS));
++		readl(port_mmio + EDMA_CFG_OFS),
++		readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS),
++		readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
+ }
+ 
++/**
++ *      mv_host_init - Perform some early initialization of the host.
++ *      @probe_ent: early data struct representing the host
++ *
++ *      If possible, do an early global reset of the host.  Then do
++ *      our port init and clear/unmask all/relevant host interrupts.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
+ static int mv_host_init(struct ata_probe_ent *probe_ent)
+ {
+ 	int rc = 0, n_hc, port, hc;
+ 	void __iomem *mmio = probe_ent->mmio_base;
+ 	void __iomem *port_mmio;
+ 
+-	if (mv_master_reset(probe_ent->mmio_base)) {
++	if ((MV_FLAG_GLBL_SFT_RST & probe_ent->host_flags) && 
++	    mv_global_soft_reset(probe_ent->mmio_base)) {
+ 		rc = 1;
+ 		goto done;
+ 	}
+@@ -676,17 +1377,27 @@ static int mv_host_init(struct ata_probe
+ 
+ 	for (port = 0; port < probe_ent->n_ports; port++) {
+ 		port_mmio = mv_port_base(mmio, port);
+-		mv_port_init(&probe_ent->port[port], (unsigned long)port_mmio);
++		mv_port_init(&probe_ent->port[port], port_mmio);
+ 	}
+ 
+ 	for (hc = 0; hc < n_hc; hc++) {
+-		VPRINTK("HC%i: HC config=0x%08x HC IRQ cause=0x%08x\n", hc,
+-			readl(mv_hc_base(mmio, hc) + HC_CFG_OFS),
+-			readl(mv_hc_base(mmio, hc) + HC_IRQ_CAUSE_OFS));
++		void __iomem *hc_mmio = mv_hc_base(mmio, hc);
++
++		VPRINTK("HC%i: HC config=0x%08x HC IRQ cause "
++			"(before clear)=0x%08x\n", hc,
++			readl(hc_mmio + HC_CFG_OFS),
++			readl(hc_mmio + HC_IRQ_CAUSE_OFS));
++
++		/* Clear any currently outstanding hc interrupt conditions */
++		writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
+ 	}
+ 
+-	writel(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
+-	writel(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
++	/* Clear any currently outstanding host interrupt conditions */
++	writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
++
++	/* and unmask interrupt generation for host regs */
++	writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
++	writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
+ 
+ 	VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x "
+ 		"PCI int cause/mask=0x%08x/0x%08x\n", 
+@@ -694,11 +1405,53 @@ static int mv_host_init(struct ata_probe
+ 		readl(mmio + HC_MAIN_IRQ_MASK_OFS),
+ 		readl(mmio + PCI_IRQ_CAUSE_OFS),
+ 		readl(mmio + PCI_IRQ_MASK_OFS));
+-
+- done:
++done:
+ 	return rc;
+ }
+ 
++/**
++ *      mv_print_info - Dump key info to kernel log for perusal.
++ *      @probe_ent: early data struct representing the host
++ *
++ *      FIXME: complete this.
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
++static void mv_print_info(struct ata_probe_ent *probe_ent)
++{
++	struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
++	struct mv_host_priv *hpriv = probe_ent->private_data;
++	u8 rev_id, scc;
++	const char *scc_s;
++
++	/* Use this to determine the HW stepping of the chip so we know
++	 * what errata to workaround
++	 */
++	pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
++
++	pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &scc);
++	if (scc == 0)
++		scc_s = "SCSI";
++	else if (scc == 0x01)
++		scc_s = "RAID";
++	else
++		scc_s = "unknown";
++
++	dev_printk(KERN_INFO, &pdev->dev,
++	       "%u slots %u ports %s mode IRQ via %s\n",
++	       (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports, 
++	       scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
++}
++
++/**
++ *      mv_init_one - handle a positive probe of a Marvell host
++ *      @pdev: PCI device found
++ *      @ent: PCI device ID entry for the matched host
++ *
++ *      LOCKING:
++ *      Inherited from caller.
++ */
+ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ 	static int printed_version = 0;
+@@ -706,15 +1459,10 @@ static int mv_init_one(struct pci_dev *p
+ 	struct mv_host_priv *hpriv;
+ 	unsigned int board_idx = (unsigned int)ent->driver_data;
+ 	void __iomem *mmio_base;
+-	int pci_dev_busy = 0;
+-	int rc;
++	int pci_dev_busy = 0, rc;
+ 
+-	if (!printed_version++) {
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+-	}
+-
+-	VPRINTK("ENTER for PCI Bus:Slot.Func=%u:%u.%u\n", pdev->bus->number,
+-		PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
++	if (!printed_version++)
++		dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	rc = pci_enable_device(pdev);
+ 	if (rc) {
+@@ -727,8 +1475,6 @@ static int mv_init_one(struct pci_dev *p
+ 		goto err_out;
+ 	}
+ 
+-	pci_intx(pdev, 1);
+-
+ 	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ 	if (probe_ent == NULL) {
+ 		rc = -ENOMEM;
+@@ -739,8 +1485,7 @@ static int mv_init_one(struct pci_dev *p
+ 	probe_ent->dev = pci_dev_to_dev(pdev);
+ 	INIT_LIST_HEAD(&probe_ent->node);
+ 
+-	mmio_base = ioremap_nocache(pci_resource_start(pdev, MV_PRIMARY_BAR),
+-				    pci_resource_len(pdev, MV_PRIMARY_BAR));
++	mmio_base = pci_iomap(pdev, MV_PRIMARY_BAR, 0);
+ 	if (mmio_base == NULL) {
+ 		rc = -ENOMEM;
+ 		goto err_out_free_ent;
+@@ -769,37 +1514,40 @@ static int mv_init_one(struct pci_dev *p
+ 	if (rc) {
+ 		goto err_out_hpriv;
+ 	}
+-/* 	mv_print_info(probe_ent); */
+ 
+-	{
+-		int b, w;
+-		u32 dw[4];	/* hold a line of 16b */
+-		VPRINTK("PCI config space:\n");
+-		for (b = 0; b < 0x40; ) {
+-			for (w = 0; w < 4; w++) {
+-				(void) pci_read_config_dword(pdev,b,&dw[w]);
+-				b += sizeof(*dw);
+-			}
+-			VPRINTK("%08x %08x %08x %08x\n",
+-				dw[0],dw[1],dw[2],dw[3]);
+-		}
++	/* Enable interrupts */
++	if (pci_enable_msi(pdev) == 0) {
++		hpriv->hp_flags |= MV_HP_FLAG_MSI;
++	} else {
++		pci_intx(pdev, 1);
+ 	}
+ 
+-	/* FIXME: check ata_device_add return value */
+-	ata_device_add(probe_ent);
+-	kfree(probe_ent);
++	mv_dump_pci_cfg(pdev, 0x68);
++	mv_print_info(probe_ent);
++
++	if (ata_device_add(probe_ent) == 0) {
++		rc = -ENODEV;		/* No devices discovered */
++		goto err_out_dev_add;
++	}
+ 
++	kfree(probe_ent);
+ 	return 0;
+ 
+- err_out_hpriv:
++err_out_dev_add:
++	if (MV_HP_FLAG_MSI & hpriv->hp_flags) {
++		pci_disable_msi(pdev);
++	} else {
++		pci_intx(pdev, 0);
++	}
++err_out_hpriv:
+ 	kfree(hpriv);
+- err_out_iounmap:
+-	iounmap(mmio_base);
+- err_out_free_ent:
++err_out_iounmap:
++	pci_iounmap(pdev, mmio_base);
++err_out_free_ent:
+ 	kfree(probe_ent);
+- err_out_regions:
++err_out_regions:
+ 	pci_release_regions(pdev);
+- err_out:
++err_out:
+ 	if (!pci_dev_busy) {
+ 		pci_disable_device(pdev);
+ 	}
+diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
+--- a/drivers/scsi/sata_nv.c
++++ b/drivers/scsi/sata_nv.c
+@@ -61,6 +61,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -238,7 +239,7 @@ static Scsi_Host_Template nv_sht = {
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations nv_ops = {
++static const struct ata_port_operations nv_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= ata_tf_load,
+ 	.tf_read		= ata_tf_read,
+@@ -331,7 +332,7 @@ static u32 nv_scr_read (struct ata_port 
+ 		return 0xffffffffU;
+ 
+ 	if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
+-		return readl((void*)ap->ioaddr.scr_addr + (sc_reg * 4));
++		return readl((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
+ 	else
+ 		return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+@@ -345,7 +346,7 @@ static void nv_scr_write (struct ata_por
+ 		return;
+ 
+ 	if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
+-		writel(val, (void*)ap->ioaddr.scr_addr + (sc_reg * 4));
++		writel(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
+ 	else
+ 		outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+@@ -383,7 +384,7 @@ static int nv_init_one (struct pci_dev *
+ 			return -ENODEV;
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+@@ -405,7 +406,7 @@ static int nv_init_one (struct pci_dev *
+ 	rc = -ENOMEM;
+ 
+ 	ppi = &nv_port_info;
+-	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
++	probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
+ 	if (!probe_ent)
+ 		goto err_out_regions;
+ 
+diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
+--- a/drivers/scsi/sata_promise.c
++++ b/drivers/scsi/sata_promise.c
+@@ -38,6 +38,7 @@
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -87,8 +88,8 @@ static void pdc_port_stop(struct ata_por
+ static void pdc_pata_phy_reset(struct ata_port *ap);
+ static void pdc_sata_phy_reset(struct ata_port *ap);
+ static void pdc_qc_prep(struct ata_queued_cmd *qc);
+-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
++static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
++static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
+ static void pdc_irq_clear(struct ata_port *ap);
+ static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
+ 
+@@ -113,7 +114,7 @@ static Scsi_Host_Template pdc_ata_sht = 
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations pdc_sata_ops = {
++static const struct ata_port_operations pdc_sata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= pdc_tf_load_mmio,
+ 	.tf_read		= ata_tf_read,
+@@ -136,7 +137,7 @@ static struct ata_port_operations pdc_sa
+ 	.host_stop		= ata_pci_host_stop,
+ };
+ 
+-static struct ata_port_operations pdc_pata_ops = {
++static const struct ata_port_operations pdc_pata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= pdc_tf_load_mmio,
+ 	.tf_read		= ata_tf_read,
+@@ -195,6 +196,8 @@ static struct ata_port_info pdc_port_inf
+ static struct pci_device_id pdc_ata_pci_tbl[] = {
+ 	{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 	  board_2037x },
++	{ PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
++	  board_2037x },
+ 	{ PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 	  board_2037x },
+ 	{ PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+@@ -207,6 +210,8 @@ static struct pci_device_id pdc_ata_pci_
+ 	  board_2037x },
+ 	{ PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 	  board_2037x },
++	{ PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
++	  board_2037x },
+ 
+ 	{ PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 	  board_20319 },
+@@ -324,7 +329,7 @@ static u32 pdc_sata_scr_read (struct ata
+ {
+ 	if (sc_reg > SCR_CONTROL)
+ 		return 0xffffffffU;
+-	return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
++	return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+ 
+ 
+@@ -333,7 +338,7 @@ static void pdc_sata_scr_write (struct a
+ {
+ 	if (sc_reg > SCR_CONTROL)
+ 		return;
+-	writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
++	writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+ 
+ static void pdc_qc_prep(struct ata_queued_cmd *qc)
+@@ -395,7 +400,8 @@ static void pdc_eng_timeout(struct ata_p
+ 	case ATA_PROT_DMA:
+ 	case ATA_PROT_NODATA:
+ 		printk(KERN_ERR "ata%u: command timeout\n", ap->id);
+-		ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
++		drv_stat = ata_wait_idle(ap);
++		ata_qc_complete(qc, __ac_err_mask(drv_stat));
+ 		break;
+ 
+ 	default:
+@@ -404,7 +410,7 @@ static void pdc_eng_timeout(struct ata_p
+ 		printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
+ 		       ap->id, qc->tf.command, drv_stat);
+ 
+-		ata_qc_complete(qc, drv_stat);
++		ata_qc_complete(qc, ac_err_mask(drv_stat));
+ 		break;
+ 	}
+ 
+@@ -416,33 +422,30 @@ out:
+ static inline unsigned int pdc_host_intr( struct ata_port *ap,
+                                           struct ata_queued_cmd *qc)
+ {
+-	u8 status;
+-	unsigned int handled = 0, have_err = 0;
++	unsigned int handled = 0, err_mask = 0;
+ 	u32 tmp;
+ 	void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
+ 
+ 	tmp = readl(mmio);
+ 	if (tmp & PDC_ERR_MASK) {
+-		have_err = 1;
++		err_mask = AC_ERR_DEV;
+ 		pdc_reset_port(ap);
+ 	}
+ 
+ 	switch (qc->tf.protocol) {
+ 	case ATA_PROT_DMA:
+ 	case ATA_PROT_NODATA:
+-		status = ata_wait_idle(ap);
+-		if (have_err)
+-			status |= ATA_ERR;
+-		ata_qc_complete(qc, status);
++		err_mask |= ac_err_mask(ata_wait_idle(ap));
++		ata_qc_complete(qc, err_mask);
+ 		handled = 1;
+ 		break;
+ 
+         default:
+-                ap->stats.idle_irq++;
+-                break;
++		ap->stats.idle_irq++;
++		break;
+         }
+ 
+-        return handled;
++	return handled;
+ }
+ 
+ static void pdc_irq_clear(struct ata_port *ap)
+@@ -523,8 +526,8 @@ static inline void pdc_packet_start(stru
+ 
+ 	pp->pkt[2] = seq;
+ 	wmb();			/* flush PRD, pkt writes */
+-	writel(pp->pkt_dma, (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+-	readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
++	writel(pp->pkt_dma, (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
++	readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
+ }
+ 
+ static int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
+@@ -546,7 +549,7 @@ static int pdc_qc_issue_prot(struct ata_
+ 	return ata_qc_issue_prot(qc);
+ }
+ 
+-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
++static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	WARN_ON (tf->protocol == ATA_PROT_DMA ||
+ 		 tf->protocol == ATA_PROT_NODATA);
+@@ -554,7 +557,7 @@ static void pdc_tf_load_mmio(struct ata_
+ }
+ 
+ 
+-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
++static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	WARN_ON (tf->protocol == ATA_PROT_DMA ||
+ 		 tf->protocol == ATA_PROT_NODATA);
+@@ -631,7 +634,7 @@ static int pdc_ata_init_one (struct pci_
+ 	int rc;
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	/*
+ 	 * If this driver happens to only be useful on Apple's K2, then
+diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
+--- a/drivers/scsi/sata_qstor.c
++++ b/drivers/scsi/sata_qstor.c
+@@ -35,6 +35,7 @@
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <asm/io.h>
+@@ -51,8 +52,6 @@ enum {
+ 	QS_PRD_BYTES		= QS_MAX_PRD * 16,
+ 	QS_PKT_BYTES		= QS_CPB_BYTES + QS_PRD_BYTES,
+ 
+-	QS_DMA_BOUNDARY		= ~0UL,
+-
+ 	/* global register offsets */
+ 	QS_HCF_CNFG3		= 0x0003, /* host configuration offset */
+ 	QS_HID_HPHY		= 0x0004, /* host physical interface info */
+@@ -101,6 +100,10 @@ enum {
+ 	board_2068_idx		= 0,	/* QStor 4-port SATA/RAID */
+ };
+ 
++enum {
++	QS_DMA_BOUNDARY		= ~0UL
++};
++
+ typedef enum { qs_state_idle, qs_state_pkt, qs_state_mmio } qs_state_t;
+ 
+ struct qs_port_priv {
+@@ -145,7 +148,7 @@ static Scsi_Host_Template qs_ata_sht = {
+ 	.bios_param		= ata_std_bios_param,
+ };
+ 
+-static struct ata_port_operations qs_ata_ops = {
++static const struct ata_port_operations qs_ata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= ata_tf_load,
+ 	.tf_read		= ata_tf_read,
+@@ -398,11 +401,12 @@ static inline unsigned int qs_intr_pkt(s
+ 				qc = ata_qc_from_tag(ap, ap->active_tag);
+ 				if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+ 					switch (sHST) {
+-					case 0: /* sucessful CPB */
++					case 0: /* successful CPB */
+ 					case 3: /* device error */
+ 						pp->state = qs_state_idle;
+ 						qs_enter_reg_mode(qc->ap);
+-						ata_qc_complete(qc, sDST);
++						ata_qc_complete(qc,
++							ac_err_mask(sDST));
+ 						break;
+ 					default:
+ 						break;
+@@ -431,7 +435,7 @@ static inline unsigned int qs_intr_mmio(
+ 			if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+ 
+ 				/* check main status, clearing INTRQ */
+-				u8 status = ata_chk_status(ap);
++				u8 status = ata_check_status(ap);
+ 				if ((status & ATA_BUSY))
+ 					continue;
+ 				DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
+@@ -439,7 +443,7 @@ static inline unsigned int qs_intr_mmio(
+ 
+ 				/* complete taskfile transaction */
+ 				pp->state = qs_state_idle;
+-				ata_qc_complete(qc, status);
++				ata_qc_complete(qc, ac_err_mask(status));
+ 				handled = 1;
+ 			}
+ 		}
+@@ -597,25 +601,22 @@ static int qs_set_dma_masks(struct pci_d
+ 		if (rc) {
+ 			rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ 			if (rc) {
+-				printk(KERN_ERR DRV_NAME
+-					"(%s): 64-bit DMA enable failed\n",
+-					pci_name(pdev));
++				dev_printk(KERN_ERR, &pdev->dev,
++					   "64-bit DMA enable failed\n");
+ 				return rc;
+ 			}
+ 		}
+ 	} else {
+ 		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ 		if (rc) {
+-			printk(KERN_ERR DRV_NAME
+-				"(%s): 32-bit DMA enable failed\n",
+-				pci_name(pdev));
++			dev_printk(KERN_ERR, &pdev->dev,
++				"32-bit DMA enable failed\n");
+ 			return rc;
+ 		}
+ 		rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ 		if (rc) {
+-			printk(KERN_ERR DRV_NAME
+-				"(%s): 32-bit consistent DMA enable failed\n",
+-				pci_name(pdev));
++			dev_printk(KERN_ERR, &pdev->dev,
++				"32-bit consistent DMA enable failed\n");
+ 			return rc;
+ 		}
+ 	}
+@@ -632,7 +633,7 @@ static int qs_ata_init_one(struct pci_de
+ 	int rc, port_no;
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
+--- a/drivers/scsi/sata_sil.c
++++ b/drivers/scsi/sata_sil.c
+@@ -41,6 +41,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -150,7 +151,7 @@ static Scsi_Host_Template sil_sht = {
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations sil_ops = {
++static const struct ata_port_operations sil_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.dev_config		= sil_dev_config,
+ 	.tf_load		= ata_tf_load,
+@@ -289,7 +290,7 @@ static inline unsigned long sil_scr_addr
+ 
+ static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
+ {
+-	void *mmio = (void *) sil_scr_addr(ap, sc_reg);
++	void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
+ 	if (mmio)
+ 		return readl(mmio);
+ 	return 0xffffffffU;
+@@ -297,7 +298,7 @@ static u32 sil_scr_read (struct ata_port
+ 
+ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
+ {
+-	void *mmio = (void *) sil_scr_addr(ap, sc_reg);
++	void *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
+ 	if (mmio)
+ 		writel(val, mmio);
+ }
+@@ -386,7 +387,7 @@ static int sil_init_one (struct pci_dev 
+ 	u8 cls;
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	/*
+ 	 * If this driver happens to only be useful on Apple's K2, then
+@@ -463,8 +464,8 @@ static int sil_init_one (struct pci_dev 
+ 			writeb(cls, mmio_base + SIL_FIFO_W3);
+ 		}
+ 	} else
+-		printk(KERN_WARNING DRV_NAME "(%s): cache line size not set.  Driver may not function\n",
+-			pci_name(pdev));
++		dev_printk(KERN_WARNING, &pdev->dev,
++			 "cache line size not set.  Driver may not function\n");
+ 
+ 	if (ent->driver_data == sil_3114) {
+ 		irq_mask = SIL_MASK_4PORT;
+diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/scsi/sata_sil24.c
+@@ -0,0 +1,871 @@
++/*
++ * sata_sil24.c - Driver for Silicon Image 3124/3132 SATA-2 controllers
++ *
++ * Copyright 2005  Tejun Heo
++ *
++ * Based on preview driver from Silicon Image.
++ *
++ * NOTE: No NCQ/ATAPI support yet.  The preview driver didn't support
++ * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
++ * those work.  Enabling those shouldn't be difficult.  Basic
++ * structure is all there (in libata-dev tree).  If you have any
++ * information about this hardware, please contact me or linux-ide.
++ * Info is needed on...
++ *
++ * - How to issue tagged commands and turn on sactive on issue accordingly.
++ * - Where to put an ATAPI command and how to tell the device to send it.
++ * - How to enable/use 64bit.
++ *
++ * This program is free software; you can redistribute 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/module.h>
++#include <linux/pci.h>
++#include <linux/blkdev.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/device.h>
++#include <scsi/scsi_host.h>
++#include "scsi.h"
++#include <linux/libata.h>
++#include <asm/io.h>
++
++#define DRV_NAME	"sata_sil24"
++#define DRV_VERSION	"0.22"	/* Silicon Image's preview driver was 0.10 */
++
++/*
++ * Port request block (PRB) 32 bytes
++ */
++struct sil24_prb {
++	u16	ctrl;
++	u16	prot;
++	u32	rx_cnt;
++	u8	fis[6 * 4];
++};
++
++/*
++ * Scatter gather entry (SGE) 16 bytes
++ */
++struct sil24_sge {
++	u64	addr;
++	u32	cnt;
++	u32	flags;
++};
++
++/*
++ * Port multiplier
++ */
++struct sil24_port_multiplier {
++	u32	diag;
++	u32	sactive;
++};
++
++enum {
++	/*
++	 * Global controller registers (128 bytes @ BAR0)
++	 */
++		/* 32 bit regs */
++	HOST_SLOT_STAT		= 0x00, /* 32 bit slot stat * 4 */
++	HOST_CTRL		= 0x40,
++	HOST_IRQ_STAT		= 0x44,
++	HOST_PHY_CFG		= 0x48,
++	HOST_BIST_CTRL		= 0x50,
++	HOST_BIST_PTRN		= 0x54,
++	HOST_BIST_STAT		= 0x58,
++	HOST_MEM_BIST_STAT	= 0x5c,
++	HOST_FLASH_CMD		= 0x70,
++		/* 8 bit regs */
++	HOST_FLASH_DATA		= 0x74,
++	HOST_TRANSITION_DETECT	= 0x75,
++	HOST_GPIO_CTRL		= 0x76,
++	HOST_I2C_ADDR		= 0x78, /* 32 bit */
++	HOST_I2C_DATA		= 0x7c,
++	HOST_I2C_XFER_CNT	= 0x7e,
++	HOST_I2C_CTRL		= 0x7f,
++
++	/* HOST_SLOT_STAT bits */
++	HOST_SSTAT_ATTN		= (1 << 31),
++
++	/*
++	 * Port registers
++	 * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2)
++	 */
++	PORT_REGS_SIZE		= 0x2000,
++	PORT_PRB		= 0x0000, /* (32 bytes PRB + 16 bytes SGEs * 6) * 31 (3968 bytes) */
++
++	PORT_PM			= 0x0f80, /* 8 bytes PM * 16 (128 bytes) */
++		/* 32 bit regs */
++	PORT_CTRL_STAT		= 0x1000, /* write: ctrl-set, read: stat */
++	PORT_CTRL_CLR		= 0x1004, /* write: ctrl-clear */
++	PORT_IRQ_STAT		= 0x1008, /* high: status, low: interrupt */
++	PORT_IRQ_ENABLE_SET	= 0x1010, /* write: enable-set */
++	PORT_IRQ_ENABLE_CLR	= 0x1014, /* write: enable-clear */
++	PORT_ACTIVATE_UPPER_ADDR= 0x101c,
++	PORT_EXEC_FIFO		= 0x1020, /* command execution fifo */
++	PORT_CMD_ERR		= 0x1024, /* command error number */
++	PORT_FIS_CFG		= 0x1028,
++	PORT_FIFO_THRES		= 0x102c,
++		/* 16 bit regs */
++	PORT_DECODE_ERR_CNT	= 0x1040,
++	PORT_DECODE_ERR_THRESH	= 0x1042,
++	PORT_CRC_ERR_CNT	= 0x1044,
++	PORT_CRC_ERR_THRESH	= 0x1046,
++	PORT_HSHK_ERR_CNT	= 0x1048,
++	PORT_HSHK_ERR_THRESH	= 0x104a,
++		/* 32 bit regs */
++	PORT_PHY_CFG		= 0x1050,
++	PORT_SLOT_STAT		= 0x1800,
++	PORT_CMD_ACTIVATE	= 0x1c00, /* 64 bit cmd activate * 31 (248 bytes) */
++	PORT_EXEC_DIAG		= 0x1e00, /* 32bit exec diag * 16 (64 bytes, 0-10 used on 3124) */
++	PORT_PSD_DIAG		= 0x1e40, /* 32bit psd diag * 16 (64 bytes, 0-8 used on 3124) */
++	PORT_SCONTROL		= 0x1f00,
++	PORT_SSTATUS		= 0x1f04,
++	PORT_SERROR		= 0x1f08,
++	PORT_SACTIVE		= 0x1f0c,
++
++	/* PORT_CTRL_STAT bits */
++	PORT_CS_PORT_RST	= (1 << 0), /* port reset */
++	PORT_CS_DEV_RST		= (1 << 1), /* device reset */
++	PORT_CS_INIT		= (1 << 2), /* port initialize */
++	PORT_CS_IRQ_WOC		= (1 << 3), /* interrupt write one to clear */
++	PORT_CS_RESUME		= (1 << 6), /* port resume */
++	PORT_CS_32BIT_ACTV	= (1 << 10), /* 32-bit activation */
++	PORT_CS_PM_EN		= (1 << 13), /* port multiplier enable */
++	PORT_CS_RDY		= (1 << 31), /* port ready to accept commands */
++
++	/* PORT_IRQ_STAT/ENABLE_SET/CLR */
++	/* bits[11:0] are masked */
++	PORT_IRQ_COMPLETE	= (1 << 0), /* command(s) completed */
++	PORT_IRQ_ERROR		= (1 << 1), /* command execution error */
++	PORT_IRQ_PORTRDY_CHG	= (1 << 2), /* port ready change */
++	PORT_IRQ_PWR_CHG	= (1 << 3), /* power management change */
++	PORT_IRQ_PHYRDY_CHG	= (1 << 4), /* PHY ready change */
++	PORT_IRQ_COMWAKE	= (1 << 5), /* COMWAKE received */
++	PORT_IRQ_UNK_FIS	= (1 << 6), /* Unknown FIS received */
++	PORT_IRQ_SDB_FIS	= (1 << 11), /* SDB FIS received */
++
++	/* bits[27:16] are unmasked (raw) */
++	PORT_IRQ_RAW_SHIFT	= 16,
++	PORT_IRQ_MASKED_MASK	= 0x7ff,
++	PORT_IRQ_RAW_MASK	= (0x7ff << PORT_IRQ_RAW_SHIFT),
++
++	/* ENABLE_SET/CLR specific, intr steering - 2 bit field */
++	PORT_IRQ_STEER_SHIFT	= 30,
++	PORT_IRQ_STEER_MASK	= (3 << PORT_IRQ_STEER_SHIFT),
++
++	/* PORT_CMD_ERR constants */
++	PORT_CERR_DEV		= 1, /* Error bit in D2H Register FIS */
++	PORT_CERR_SDB		= 2, /* Error bit in SDB FIS */
++	PORT_CERR_DATA		= 3, /* Error in data FIS not detected by dev */
++	PORT_CERR_SEND		= 4, /* Initial cmd FIS transmission failure */
++	PORT_CERR_INCONSISTENT	= 5, /* Protocol mismatch */
++	PORT_CERR_DIRECTION	= 6, /* Data direction mismatch */
++	PORT_CERR_UNDERRUN	= 7, /* Ran out of SGEs while writing */
++	PORT_CERR_OVERRUN	= 8, /* Ran out of SGEs while reading */
++	PORT_CERR_PKT_PROT	= 11, /* DIR invalid in 1st PIO setup of ATAPI */
++	PORT_CERR_SGT_BOUNDARY	= 16, /* PLD ecode 00 - SGT not on qword boundary */
++	PORT_CERR_SGT_TGTABRT	= 17, /* PLD ecode 01 - target abort */
++	PORT_CERR_SGT_MSTABRT	= 18, /* PLD ecode 10 - master abort */
++	PORT_CERR_SGT_PCIPERR	= 19, /* PLD ecode 11 - PCI parity err while fetching SGT */
++	PORT_CERR_CMD_BOUNDARY	= 24, /* ctrl[15:13] 001 - PRB not on qword boundary */
++	PORT_CERR_CMD_TGTABRT	= 25, /* ctrl[15:13] 010 - target abort */
++	PORT_CERR_CMD_MSTABRT	= 26, /* ctrl[15:13] 100 - master abort */
++	PORT_CERR_CMD_PCIPERR	= 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */
++	PORT_CERR_XFR_UNDEF	= 32, /* PSD ecode 00 - undefined */
++	PORT_CERR_XFR_TGTABRT	= 33, /* PSD ecode 01 - target abort */
++	PORT_CERR_XFR_MSGABRT	= 34, /* PSD ecode 10 - master abort */
++	PORT_CERR_XFR_PCIPERR	= 35, /* PSD ecode 11 - PCI prity err during transfer */
++	PORT_CERR_SENDSERVICE	= 36, /* FIS received while sending service */
++
++	/*
++	 * Other constants
++	 */
++	SGE_TRM			= (1 << 31), /* Last SGE in chain */
++	PRB_SOFT_RST		= (1 << 7),  /* Soft reset request (ign BSY?) */
++
++	/* board id */
++	BID_SIL3124		= 0,
++	BID_SIL3132		= 1,
++	BID_SIL3131		= 2,
++
++	IRQ_STAT_4PORTS		= 0xf,
++};
++
++struct sil24_cmd_block {
++	struct sil24_prb prb;
++	struct sil24_sge sge[LIBATA_MAX_PRD];
++};
++
++/*
++ * ap->private_data
++ *
++ * The preview driver always returned 0 for status.  We emulate it
++ * here from the previous interrupt.
++ */
++struct sil24_port_priv {
++	struct sil24_cmd_block *cmd_block;	/* 32 cmd blocks */
++	dma_addr_t cmd_block_dma;		/* DMA base addr for them */
++	struct ata_taskfile tf;			/* Cached taskfile registers */
++};
++
++/* ap->host_set->private_data */
++struct sil24_host_priv {
++	void __iomem *host_base;	/* global controller control (128 bytes @BAR0) */
++	void __iomem *port_base;	/* port registers (4 * 8192 bytes @BAR2) */
++};
++
++static u8 sil24_check_status(struct ata_port *ap);
++static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
++static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
++static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
++static void sil24_phy_reset(struct ata_port *ap);
++static void sil24_qc_prep(struct ata_queued_cmd *qc);
++static int sil24_qc_issue(struct ata_queued_cmd *qc);
++static void sil24_irq_clear(struct ata_port *ap);
++static void sil24_eng_timeout(struct ata_port *ap);
++static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
++static int sil24_port_start(struct ata_port *ap);
++static void sil24_port_stop(struct ata_port *ap);
++static void sil24_host_stop(struct ata_host_set *host_set);
++static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
++
++static struct pci_device_id sil24_pci_tbl[] = {
++	{ 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
++	{ 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 },
++	{ 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
++	{ 0x1095, 0x3531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
++	{ } /* terminate list */
++};
++
++static struct pci_driver sil24_pci_driver = {
++	.name			= DRV_NAME,
++	.id_table		= sil24_pci_tbl,
++	.probe			= sil24_init_one,
++	.remove			= ata_pci_remove_one, /* safe? */
++};
++
++static Scsi_Host_Template sil24_sht = {
++	.module			= THIS_MODULE,
++	.name			= DRV_NAME,
++	.ioctl			= ata_scsi_ioctl,
++	.queuecommand		= ata_scsi_queuecmd,
++	.eh_strategy_handler	= ata_scsi_error,
++	.can_queue		= ATA_DEF_QUEUE,
++	.this_id		= ATA_SHT_THIS_ID,
++	.sg_tablesize		= LIBATA_MAX_PRD,
++	.max_sectors		= ATA_MAX_SECTORS,
++	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
++	.emulated		= ATA_SHT_EMULATED,
++	.use_clustering		= ATA_SHT_USE_CLUSTERING,
++	.proc_name		= DRV_NAME,
++	.dma_boundary		= ATA_DMA_BOUNDARY,
++	.slave_configure	= ata_scsi_slave_config,
++	.bios_param		= ata_std_bios_param,
++	.ordered_flush		= 1, /* NCQ not supported yet */
++};
++
++static const struct ata_port_operations sil24_ops = {
++	.port_disable		= ata_port_disable,
++
++	.check_status		= sil24_check_status,
++	.check_altstatus	= sil24_check_status,
++	.dev_select		= ata_noop_dev_select,
++
++	.tf_read		= sil24_tf_read,
++
++	.phy_reset		= sil24_phy_reset,
++
++	.qc_prep		= sil24_qc_prep,
++	.qc_issue		= sil24_qc_issue,
++
++	.eng_timeout		= sil24_eng_timeout,
++
++	.irq_handler		= sil24_interrupt,
++	.irq_clear		= sil24_irq_clear,
++
++	.scr_read		= sil24_scr_read,
++	.scr_write		= sil24_scr_write,
++
++	.port_start		= sil24_port_start,
++	.port_stop		= sil24_port_stop,
++	.host_stop		= sil24_host_stop,
++};
++
++/*
++ * Use bits 30-31 of host_flags to encode available port numbers.
++ * Current maxium is 4.
++ */
++#define SIL24_NPORTS2FLAG(nports)	((((unsigned)(nports) - 1) & 0x3) << 30)
++#define SIL24_FLAG2NPORTS(flag)		((((flag) >> 30) & 0x3) + 1)
++
++static struct ata_port_info sil24_port_info[] = {
++	/* sil_3124 */
++	{
++		.sht		= &sil24_sht,
++		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
++				  ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
++				  ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
++		.pio_mask	= 0x1f,			/* pio0-4 */
++		.mwdma_mask	= 0x07,			/* mwdma0-2 */
++		.udma_mask	= 0x3f,			/* udma0-5 */
++		.port_ops	= &sil24_ops,
++	},
++	/* sil_3132 */ 
++	{
++		.sht		= &sil24_sht,
++		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
++				  ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
++				  ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
++		.pio_mask	= 0x1f,			/* pio0-4 */
++		.mwdma_mask	= 0x07,			/* mwdma0-2 */
++		.udma_mask	= 0x3f,			/* udma0-5 */
++		.port_ops	= &sil24_ops,
++	},
++	/* sil_3131/sil_3531 */
++	{
++		.sht		= &sil24_sht,
++		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
++				  ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
++				  ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
++		.pio_mask	= 0x1f,			/* pio0-4 */
++		.mwdma_mask	= 0x07,			/* mwdma0-2 */
++		.udma_mask	= 0x3f,			/* udma0-5 */
++		.port_ops	= &sil24_ops,
++	},
++};
++
++static inline void sil24_update_tf(struct ata_port *ap)
++{
++	struct sil24_port_priv *pp = ap->private_data;
++	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
++	struct sil24_prb __iomem *prb = port;
++	u8 fis[6 * 4];
++
++	memcpy_fromio(fis, prb->fis, 6 * 4);
++	ata_tf_from_fis(fis, &pp->tf);
++}
++
++static u8 sil24_check_status(struct ata_port *ap)
++{
++	struct sil24_port_priv *pp = ap->private_data;
++	return pp->tf.command;
++}
++
++static int sil24_scr_map[] = {
++	[SCR_CONTROL]	= 0,
++	[SCR_STATUS]	= 1,
++	[SCR_ERROR]	= 2,
++	[SCR_ACTIVE]	= 3,
++};
++
++static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
++{
++	void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
++	if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
++		void __iomem *addr;
++		addr = scr_addr + sil24_scr_map[sc_reg] * 4;
++		return readl(scr_addr + sil24_scr_map[sc_reg] * 4);
++	}
++	return 0xffffffffU;
++}
++
++static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
++{
++	void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
++	if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
++		void __iomem *addr;
++		addr = scr_addr + sil24_scr_map[sc_reg] * 4;
++		writel(val, scr_addr + sil24_scr_map[sc_reg] * 4);
++	}
++}
++
++static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
++{
++	struct sil24_port_priv *pp = ap->private_data;
++	*tf = pp->tf;
++}
++
++static void sil24_phy_reset(struct ata_port *ap)
++{
++	__sata_phy_reset(ap);
++	/*
++	 * No ATAPI yet.  Just unconditionally indicate ATA device.
++	 * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA
++	 * and libata core will ignore the device.
++	 */
++	if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
++		ap->device[0].class = ATA_DEV_ATA;
++}
++
++static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
++				 struct sil24_cmd_block *cb)
++{
++	struct scatterlist *sg = qc->sg;
++	struct sil24_sge *sge = cb->sge;
++	unsigned i;
++
++	for (i = 0; i < qc->n_elem; i++, sg++, sge++) {
++		sge->addr = cpu_to_le64(sg_dma_address(sg));
++		sge->cnt = cpu_to_le32(sg_dma_len(sg));
++		sge->flags = 0;
++		sge->flags = i < qc->n_elem - 1 ? 0 : cpu_to_le32(SGE_TRM);
++	}
++}
++
++static void sil24_qc_prep(struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	struct sil24_port_priv *pp = ap->private_data;
++	struct sil24_cmd_block *cb = pp->cmd_block + qc->tag;
++	struct sil24_prb *prb = &cb->prb;
++
++	switch (qc->tf.protocol) {
++	case ATA_PROT_PIO:
++	case ATA_PROT_DMA:
++	case ATA_PROT_NODATA:
++		break;
++	default:
++		/* ATAPI isn't supported yet */
++		BUG();
++	}
++
++	ata_tf_to_fis(&qc->tf, prb->fis, 0);
++
++	if (qc->flags & ATA_QCFLAG_DMAMAP)
++		sil24_fill_sg(qc, cb);
++}
++
++static int sil24_qc_issue(struct ata_queued_cmd *qc)
++{
++	struct ata_port *ap = qc->ap;
++	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
++	struct sil24_port_priv *pp = ap->private_data;
++	dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block);
++
++	writel((u32)paddr, port + PORT_CMD_ACTIVATE);
++	return 0;
++}
++
++static void sil24_irq_clear(struct ata_port *ap)
++{
++	/* unused */
++}
++
++static int __sil24_reset_controller(void __iomem *port)
++{
++	int cnt;
++	u32 tmp;
++
++	/* Reset controller state.  Is this correct? */
++	writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
++	readl(port + PORT_CTRL_STAT);	/* sync */
++
++	/* Max ~100ms */
++	for (cnt = 0; cnt < 1000; cnt++) {
++		udelay(100);
++		tmp = readl(port + PORT_CTRL_STAT);
++		if (!(tmp & PORT_CS_DEV_RST))
++			break;
++	}
++
++	if (tmp & PORT_CS_DEV_RST)
++		return -1;
++	return 0;
++}
++
++static void sil24_reset_controller(struct ata_port *ap)
++{
++	printk(KERN_NOTICE DRV_NAME
++	       " ata%u: resetting controller...\n", ap->id);
++	if (__sil24_reset_controller((void __iomem *)ap->ioaddr.cmd_addr))
++                printk(KERN_ERR DRV_NAME
++                       " ata%u: failed to reset controller\n", ap->id);
++}
++
++static void sil24_eng_timeout(struct ata_port *ap)
++{
++	struct ata_queued_cmd *qc;
++
++	qc = ata_qc_from_tag(ap, ap->active_tag);
++	if (!qc) {
++		printk(KERN_ERR "ata%u: BUG: timeout without command\n",
++		       ap->id);
++		return;
++	}
++
++	/*
++	 * hack alert!  We cannot use the supplied completion
++	 * function from inside the ->eh_strategy_handler() thread.
++	 * libata is the only user of ->eh_strategy_handler() in
++	 * any kernel, so the default scsi_done() assumes it is
++	 * not being called from the SCSI EH.
++	 */
++	printk(KERN_ERR "ata%u: command timeout\n", ap->id);
++	qc->scsidone = scsi_finish_command;
++	ata_qc_complete(qc, AC_ERR_OTHER);
++
++	sil24_reset_controller(ap);
++}
++
++static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
++{
++	struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
++	struct sil24_port_priv *pp = ap->private_data;
++	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
++	u32 irq_stat, cmd_err, sstatus, serror;
++	unsigned int err_mask;
++
++	irq_stat = readl(port + PORT_IRQ_STAT);
++	writel(irq_stat, port + PORT_IRQ_STAT);		/* clear irq */
++
++	if (!(irq_stat & PORT_IRQ_ERROR)) {
++		/* ignore non-completion, non-error irqs for now */
++		printk(KERN_WARNING DRV_NAME
++		       "ata%u: non-error exception irq (irq_stat %x)\n",
++		       ap->id, irq_stat);
++		return;
++	}
++
++	cmd_err = readl(port + PORT_CMD_ERR);
++	sstatus = readl(port + PORT_SSTATUS);
++	serror = readl(port + PORT_SERROR);
++	if (serror)
++		writel(serror, port + PORT_SERROR);
++
++	printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n"
++	       "  stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
++	       ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
++
++	if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
++		/*
++		 * Device is reporting error, tf registers are valid.
++		 */
++		sil24_update_tf(ap);
++		err_mask = ac_err_mask(pp->tf.command);
++	} else {
++		/*
++		 * Other errors.  libata currently doesn't have any
++		 * mechanism to report these errors.  Just turn on
++		 * ATA_ERR.
++		 */
++		err_mask = AC_ERR_OTHER;
++	}
++
++	if (qc)
++		ata_qc_complete(qc, err_mask);
++
++	sil24_reset_controller(ap);
++}
++
++static inline void sil24_host_intr(struct ata_port *ap)
++{
++	struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
++	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
++	u32 slot_stat;
++
++	slot_stat = readl(port + PORT_SLOT_STAT);
++	if (!(slot_stat & HOST_SSTAT_ATTN)) {
++		struct sil24_port_priv *pp = ap->private_data;
++		/*
++		 * !HOST_SSAT_ATTN guarantees successful completion,
++		 * so reading back tf registers is unnecessary for
++		 * most commands.  TODO: read tf registers for
++		 * commands which require these values on successful
++		 * completion (EXECUTE DEVICE DIAGNOSTIC, CHECK POWER,
++		 * DEVICE RESET and READ PORT MULTIPLIER (any more?).
++		 */
++		sil24_update_tf(ap);
++
++		if (qc)
++			ata_qc_complete(qc, ac_err_mask(pp->tf.command));
++	} else
++		sil24_error_intr(ap, slot_stat);
++}
++
++static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
++{
++	struct ata_host_set *host_set = dev_instance;
++	struct sil24_host_priv *hpriv = host_set->private_data;
++	unsigned handled = 0;
++	u32 status;
++	int i;
++
++	status = readl(hpriv->host_base + HOST_IRQ_STAT);
++
++	if (status == 0xffffffff) {
++		printk(KERN_ERR DRV_NAME ": IRQ status == 0xffffffff, "
++		       "PCI fault or device removal?\n");
++		goto out;
++	}
++
++	if (!(status & IRQ_STAT_4PORTS))
++		goto out;
++
++	spin_lock(&host_set->lock);
++
++	for (i = 0; i < host_set->n_ports; i++)
++		if (status & (1 << i)) {
++			struct ata_port *ap = host_set->ports[i];
++			if (ap && !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
++				sil24_host_intr(host_set->ports[i]);
++				handled++;
++			} else
++				printk(KERN_ERR DRV_NAME
++				       ": interrupt from disabled port %d\n", i);
++		}
++
++	spin_unlock(&host_set->lock);
++ out:
++	return IRQ_RETVAL(handled);
++}
++
++static int sil24_port_start(struct ata_port *ap)
++{
++	struct device *dev = ap->host_set->dev;
++	struct sil24_port_priv *pp;
++	struct sil24_cmd_block *cb;
++	size_t cb_size = sizeof(*cb);
++	dma_addr_t cb_dma;
++
++	pp = kmalloc(sizeof(*pp), GFP_KERNEL);
++	if (!pp)
++		return -ENOMEM;
++	memset(pp, 0, sizeof(*pp));
++
++	pp->tf.command = ATA_DRDY;
++
++	cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
++	if (!cb) {
++		kfree(pp);
++		return -ENOMEM;
++	}
++	memset(cb, 0, cb_size);
++
++	pp->cmd_block = cb;
++	pp->cmd_block_dma = cb_dma;
++
++	ap->private_data = pp;
++
++	return 0;
++}
++
++static void sil24_port_stop(struct ata_port *ap)
++{
++	struct device *dev = ap->host_set->dev;
++	struct sil24_port_priv *pp = ap->private_data;
++	size_t cb_size = sizeof(*pp->cmd_block);
++
++	dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
++	kfree(pp);
++}
++
++static void sil24_host_stop(struct ata_host_set *host_set)
++{
++	struct sil24_host_priv *hpriv = host_set->private_data;
++
++	iounmap(hpriv->host_base);
++	iounmap(hpriv->port_base);
++	kfree(hpriv);
++}
++
++static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
++{
++	static int printed_version = 0;
++	unsigned int board_id = (unsigned int)ent->driver_data;
++	struct ata_port_info *pinfo = &sil24_port_info[board_id];
++	struct ata_probe_ent *probe_ent = NULL;
++	struct sil24_host_priv *hpriv = NULL;
++	void __iomem *host_base = NULL;
++	void __iomem *port_base = NULL;
++	int i, rc;
++
++	if (!printed_version++)
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
++
++	rc = pci_enable_device(pdev);
++	if (rc)
++		return rc;
++
++	rc = pci_request_regions(pdev, DRV_NAME);
++	if (rc)
++		goto out_disable;
++
++	rc = -ENOMEM;
++	/* ioremap mmio registers */
++	host_base = ioremap(pci_resource_start(pdev, 0),
++			    pci_resource_len(pdev, 0));
++	if (!host_base)
++		goto out_free;
++	port_base = ioremap(pci_resource_start(pdev, 2),
++			    pci_resource_len(pdev, 2));
++	if (!port_base)
++		goto out_free;
++
++	/* allocate & init probe_ent and hpriv */
++	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
++	if (!probe_ent)
++		goto out_free;
++
++	hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
++	if (!hpriv)
++		goto out_free;
++
++	memset(probe_ent, 0, sizeof(*probe_ent));
++	probe_ent->dev = pci_dev_to_dev(pdev);
++	INIT_LIST_HEAD(&probe_ent->node);
++
++	probe_ent->sht		= pinfo->sht;
++	probe_ent->host_flags	= pinfo->host_flags;
++	probe_ent->pio_mask	= pinfo->pio_mask;
++	probe_ent->udma_mask	= pinfo->udma_mask;
++	probe_ent->port_ops	= pinfo->port_ops;
++	probe_ent->n_ports	= SIL24_FLAG2NPORTS(pinfo->host_flags);
++
++	probe_ent->irq = pdev->irq;
++	probe_ent->irq_flags = SA_SHIRQ;
++	probe_ent->mmio_base = port_base;
++	probe_ent->private_data = hpriv;
++
++	memset(hpriv, 0, sizeof(*hpriv));
++	hpriv->host_base = host_base;
++	hpriv->port_base = port_base;
++
++	/*
++	 * Configure the device
++	 */
++	/*
++	 * FIXME: This device is certainly 64-bit capable.  We just
++	 * don't know how to use it.  After fixing 32bit activation in
++	 * this function, enable 64bit masks here.
++	 */
++	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
++	if (rc) {
++		dev_printk(KERN_ERR, &pdev->dev,
++			   "32-bit DMA enable failed\n");
++		goto out_free;
++	}
++	rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
++	if (rc) {
++		dev_printk(KERN_ERR, &pdev->dev,
++			   "32-bit consistent DMA enable failed\n");
++		goto out_free;
++	}
++
++	/* GPIO off */
++	writel(0, host_base + HOST_FLASH_CMD);
++
++	/* Mask interrupts during initialization */
++	writel(0, host_base + HOST_CTRL);
++
++	for (i = 0; i < probe_ent->n_ports; i++) {
++		void __iomem *port = port_base + i * PORT_REGS_SIZE;
++		unsigned long portu = (unsigned long)port;
++		u32 tmp;
++		int cnt;
++
++		probe_ent->port[i].cmd_addr = portu + PORT_PRB;
++		probe_ent->port[i].scr_addr = portu + PORT_SCONTROL;
++
++		ata_std_ports(&probe_ent->port[i]);
++
++		/* Initial PHY setting */
++		writel(0x20c, port + PORT_PHY_CFG);
++
++		/* Clear port RST */
++		tmp = readl(port + PORT_CTRL_STAT);
++		if (tmp & PORT_CS_PORT_RST) {
++			writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
++			readl(port + PORT_CTRL_STAT);	/* sync */
++			for (cnt = 0; cnt < 10; cnt++) {
++				msleep(10);
++				tmp = readl(port + PORT_CTRL_STAT);
++				if (!(tmp & PORT_CS_PORT_RST))
++					break;
++			}
++			if (tmp & PORT_CS_PORT_RST)
++				dev_printk(KERN_ERR, &pdev->dev,
++				           "failed to clear port RST\n");
++		}
++
++		/* Zero error counters. */
++		writel(0x8000, port + PORT_DECODE_ERR_THRESH);
++		writel(0x8000, port + PORT_CRC_ERR_THRESH);
++		writel(0x8000, port + PORT_HSHK_ERR_THRESH);
++		writel(0x0000, port + PORT_DECODE_ERR_CNT);
++		writel(0x0000, port + PORT_CRC_ERR_CNT);
++		writel(0x0000, port + PORT_HSHK_ERR_CNT);
++
++		/* FIXME: 32bit activation? */
++		writel(0, port + PORT_ACTIVATE_UPPER_ADDR);
++		writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_STAT);
++
++		/* Configure interrupts */
++		writel(0xffff, port + PORT_IRQ_ENABLE_CLR);
++		writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | PORT_IRQ_SDB_FIS,
++		       port + PORT_IRQ_ENABLE_SET);
++
++		/* Clear interrupts */
++		writel(0x0fff0fff, port + PORT_IRQ_STAT);
++		writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
++
++		/* Clear port multiplier enable and resume bits */
++		writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
++
++		/* Reset itself */
++		if (__sil24_reset_controller(port))
++			dev_printk(KERN_ERR, &pdev->dev,
++			           "failed to reset controller\n");
++	}
++
++	/* Turn on interrupts */
++	writel(IRQ_STAT_4PORTS, host_base + HOST_CTRL);
++
++	pci_set_master(pdev);
++
++	/* FIXME: check ata_device_add return value */
++	ata_device_add(probe_ent);
++
++	kfree(probe_ent);
++	return 0;
++
++ out_free:
++	if (host_base)
++		iounmap(host_base);
++	if (port_base)
++		iounmap(port_base);
++	kfree(probe_ent);
++	kfree(hpriv);
++	pci_release_regions(pdev);
++ out_disable:
++	pci_disable_device(pdev);
++	return rc;
++}
++
++static int __init sil24_init(void)
++{
++	return pci_module_init(&sil24_pci_driver);
++}
++
++static void __exit sil24_exit(void)
++{
++	pci_unregister_driver(&sil24_pci_driver);
++}
++
++MODULE_AUTHOR("Tejun Heo");
++MODULE_DESCRIPTION("Silicon Image 3124/3132 SATA low-level driver");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(pci, sil24_pci_tbl);
++
++module_init(sil24_init);
++module_exit(sil24_exit);
+diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
+--- a/drivers/scsi/sata_sis.c
++++ b/drivers/scsi/sata_sis.c
+@@ -38,6 +38,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -102,7 +103,7 @@ static Scsi_Host_Template sis_sht = {
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations sis_ops = {
++static const struct ata_port_operations sis_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= ata_tf_load,
+ 	.tf_read		= ata_tf_read,
+@@ -237,6 +238,7 @@ static void sis_scr_write (struct ata_po
+ 
+ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
++	static int printed_version;
+ 	struct ata_probe_ent *probe_ent = NULL;
+ 	int rc;
+ 	u32 genctl;
+@@ -245,6 +247,9 @@ static int sis_init_one (struct pci_dev 
+ 	u8 pmr;
+ 	u8 port2_start;
+ 
++	if (!printed_version++)
++		dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
++
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+ 		return rc;
+@@ -263,7 +268,7 @@ static int sis_init_one (struct pci_dev 
+ 		goto err_out_regions;
+ 
+ 	ppi = &sis_port_info;
+-	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
++	probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
+ 	if (!probe_ent) {
+ 		rc = -ENOMEM;
+ 		goto err_out_regions;
+@@ -288,16 +293,18 @@ static int sis_init_one (struct pci_dev 
+ 	pci_read_config_byte(pdev, SIS_PMR, &pmr);
+ 	if (ent->device != 0x182) {
+ 		if ((pmr & SIS_PMR_COMBINED) == 0) {
+-			printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n");
++			dev_printk(KERN_INFO, &pdev->dev,
++				   "Detected SiS 180/181 chipset in SATA mode\n");
+ 			port2_start = 64;
+ 		}
+ 		else {
+-			printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n");
++			dev_printk(KERN_INFO, &pdev->dev,
++				   "Detected SiS 180/181 chipset in combined mode\n");
+ 			port2_start=0;
+ 		}
+ 	}
+ 	else {
+-		printk(KERN_INFO "sata_sis: Detected SiS 182 chipset\n");
++		dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182 chipset\n");
+ 		port2_start = 0x20;
+ 	}
+ 
+diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
+--- a/drivers/scsi/sata_svw.c
++++ b/drivers/scsi/sata_svw.c
+@@ -44,6 +44,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -84,6 +85,8 @@
+ /* Port stride */
+ #define K2_SATA_PORT_OFFSET		0x100
+ 
++static u8 k2_stat_check_status(struct ata_port *ap);
++
+ 
+ static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
+ {
+@@ -102,7 +105,7 @@ static void k2_sata_scr_write (struct at
+ }
+ 
+ 
+-static void k2_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
++static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+@@ -136,16 +139,24 @@ static void k2_sata_tf_load(struct ata_p
+ static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+-	u16 nsect, lbal, lbam, lbah;
++	u16 nsect, lbal, lbam, lbah, feature;
+ 
+-	nsect = tf->nsect = readw(ioaddr->nsect_addr);
+-	lbal = tf->lbal = readw(ioaddr->lbal_addr);
+-	lbam = tf->lbam = readw(ioaddr->lbam_addr);
+-	lbah = tf->lbah = readw(ioaddr->lbah_addr);
++	tf->command = k2_stat_check_status(ap);
+ 	tf->device = readw(ioaddr->device_addr);
++	feature = readw(ioaddr->error_addr);
++	nsect = readw(ioaddr->nsect_addr);
++	lbal = readw(ioaddr->lbal_addr);
++	lbam = readw(ioaddr->lbam_addr);
++	lbah = readw(ioaddr->lbah_addr);
++
++	tf->feature = feature;
++	tf->nsect = nsect;
++	tf->lbal = lbal;
++	tf->lbam = lbam;
++	tf->lbah = lbah;
+ 
+ 	if (tf->flags & ATA_TFLAG_LBA48) {
+-		tf->hob_feature = readw(ioaddr->error_addr) >> 8;
++		tf->hob_feature = feature >> 8;
+ 		tf->hob_nsect = nsect >> 8;
+ 		tf->hob_lbal = lbal >> 8;
+ 		tf->hob_lbam = lbam >> 8;
+@@ -297,7 +308,7 @@ static Scsi_Host_Template k2_sata_sht = 
+ };
+ 
+ 
+-static struct ata_port_operations k2_sata_ops = {
++static const struct ata_port_operations k2_sata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= k2_sata_tf_load,
+ 	.tf_read		= k2_sata_tf_read,
+@@ -352,7 +363,7 @@ static int k2_sata_init_one (struct pci_
+ 	int i;
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	/*
+ 	 * If this driver happens to only be useful on Apple's K2, then
+diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
+--- a/drivers/scsi/sata_sx4.c
++++ b/drivers/scsi/sata_sx4.c
+@@ -38,6 +38,7 @@
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -137,7 +138,7 @@ struct pdc_port_priv {
+ };
+ 
+ struct pdc_host_priv {
+-	void			*dimm_mmio;
++	void			__iomem *dimm_mmio;
+ 
+ 	unsigned int		doing_hdma;
+ 	unsigned int		hdma_prod;
+@@ -157,8 +158,8 @@ static void pdc_20621_phy_reset (struct 
+ static int pdc_port_start(struct ata_port *ap);
+ static void pdc_port_stop(struct ata_port *ap);
+ static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
+-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
++static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
++static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
+ static void pdc20621_host_stop(struct ata_host_set *host_set);
+ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
+ static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
+@@ -196,7 +197,7 @@ static Scsi_Host_Template pdc_sata_sht =
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations pdc_20621_ops = {
++static const struct ata_port_operations pdc_20621_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= pdc_tf_load_mmio,
+ 	.tf_read		= ata_tf_read,
+@@ -247,7 +248,7 @@ static void pdc20621_host_stop(struct at
+ {
+ 	struct pci_dev *pdev = to_pci_dev(host_set->dev);
+ 	struct pdc_host_priv *hpriv = host_set->private_data;
+-	void *dimm_mmio = hpriv->dimm_mmio;
++	void __iomem *dimm_mmio = hpriv->dimm_mmio;
+ 
+ 	pci_iounmap(pdev, dimm_mmio);
+ 	kfree(hpriv);
+@@ -669,8 +670,8 @@ static void pdc20621_packet_start(struct
+ 		readl(mmio + PDC_20621_SEQCTL + (seq * 4));	/* flush */
+ 
+ 		writel(port_ofs + PDC_DIMM_ATA_PKT,
+-		       (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+-		readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
++		       (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
++		readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ 		VPRINTK("submitted ofs 0x%x (%u), seq %u\n",
+ 			port_ofs + PDC_DIMM_ATA_PKT,
+ 			port_ofs + PDC_DIMM_ATA_PKT,
+@@ -718,7 +719,7 @@ static inline unsigned int pdc20621_host
+ 			VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
+ 				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
+ 			/* get drive status; clear intr; complete txn */
+-			ata_qc_complete(qc, ata_wait_idle(ap));
++			ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
+ 			pdc20621_pop_hdma(qc);
+ 		}
+ 
+@@ -747,8 +748,8 @@ static inline unsigned int pdc20621_host
+ 			writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
+ 			readl(mmio + PDC_20621_SEQCTL + (seq * 4));
+ 			writel(port_ofs + PDC_DIMM_ATA_PKT,
+-			       (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+-			readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
++			       (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
++			readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ 		}
+ 
+ 		/* step two - execute ATA command */
+@@ -756,7 +757,7 @@ static inline unsigned int pdc20621_host
+ 			VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
+ 				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
+ 			/* get drive status; clear intr; complete txn */
+-			ata_qc_complete(qc, ata_wait_idle(ap));
++			ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
+ 			pdc20621_pop_hdma(qc);
+ 		}
+ 		handled = 1;
+@@ -766,7 +767,7 @@ static inline unsigned int pdc20621_host
+ 
+ 		status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+ 		DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
+-		ata_qc_complete(qc, status);
++		ata_qc_complete(qc, ac_err_mask(status));
+ 		handled = 1;
+ 
+ 	} else {
+@@ -881,7 +882,7 @@ static void pdc_eng_timeout(struct ata_p
+ 	case ATA_PROT_DMA:
+ 	case ATA_PROT_NODATA:
+ 		printk(KERN_ERR "ata%u: command timeout\n", ap->id);
+-		ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
++		ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap)));
+ 		break;
+ 
+ 	default:
+@@ -890,7 +891,7 @@ static void pdc_eng_timeout(struct ata_p
+ 		printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
+ 		       ap->id, qc->tf.command, drv_stat);
+ 
+-		ata_qc_complete(qc, drv_stat);
++		ata_qc_complete(qc, ac_err_mask(drv_stat));
+ 		break;
+ 	}
+ 
+@@ -899,7 +900,7 @@ out:
+ 	DPRINTK("EXIT\n");
+ }
+ 
+-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
++static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	WARN_ON (tf->protocol == ATA_PROT_DMA ||
+ 		 tf->protocol == ATA_PROT_NODATA);
+@@ -907,7 +908,7 @@ static void pdc_tf_load_mmio(struct ata_
+ }
+ 
+ 
+-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
++static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	WARN_ON (tf->protocol == ATA_PROT_DMA ||
+ 		 tf->protocol == ATA_PROT_NODATA);
+@@ -1014,7 +1015,7 @@ static void pdc20621_put_to_dimm(struct 
+ 	idx++;
+ 	dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size :
+ 		(long) (window_size - offset);
+-	memcpy_toio((char *) (dimm_mmio + offset / 4), (char *) psource, dist);
++	memcpy_toio(dimm_mmio + offset / 4, psource, dist);
+ 	writel(0x01, mmio + PDC_GENERAL_CTLR);
+ 	readl(mmio + PDC_GENERAL_CTLR);
+ 
+@@ -1023,8 +1024,7 @@ static void pdc20621_put_to_dimm(struct 
+ 	for (; (long) size >= (long) window_size ;) {
+ 		writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR);
+ 		readl(mmio + PDC_DIMM_WINDOW_CTLR);
+-		memcpy_toio((char *) (dimm_mmio), (char *) psource,
+-			    window_size / 4);
++		memcpy_toio(dimm_mmio, psource, window_size / 4);
+ 		writel(0x01, mmio + PDC_GENERAL_CTLR);
+ 		readl(mmio + PDC_GENERAL_CTLR);
+ 		psource += window_size;
+@@ -1035,7 +1035,7 @@ static void pdc20621_put_to_dimm(struct 
+ 	if (size) {
+ 		writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR);
+ 		readl(mmio + PDC_DIMM_WINDOW_CTLR);
+-		memcpy_toio((char *) (dimm_mmio), (char *) psource, size / 4);
++		memcpy_toio(dimm_mmio, psource, size / 4);
+ 		writel(0x01, mmio + PDC_GENERAL_CTLR);
+ 		readl(mmio + PDC_GENERAL_CTLR);
+ 	}
+@@ -1386,7 +1386,7 @@ static int pdc_sata_init_one (struct pci
+ 	int rc;
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	/*
+ 	 * If this driver happens to only be useful on Apple's K2, then
+diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
+--- a/drivers/scsi/sata_uli.c
++++ b/drivers/scsi/sata_uli.c
+@@ -32,6 +32,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -90,7 +91,7 @@ static Scsi_Host_Template uli_sht = {
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations uli_ops = {
++static const struct ata_port_operations uli_ops = {
+ 	.port_disable		= ata_port_disable,
+ 
+ 	.tf_load		= ata_tf_load,
+@@ -178,12 +179,16 @@ static void uli_scr_write (struct ata_po
+ 
+ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
++	static int printed_version;
+ 	struct ata_probe_ent *probe_ent;
+ 	struct ata_port_info *ppi;
+ 	int rc;
+ 	unsigned int board_idx = (unsigned int) ent->driver_data;
+ 	int pci_dev_busy = 0;
+ 
++	if (!printed_version++)
++		dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
++
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+ 		return rc;
+@@ -202,7 +207,7 @@ static int uli_init_one (struct pci_dev 
+ 		goto err_out_regions;
+ 
+ 	ppi = &uli_port_info;
+-	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
++	probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
+ 	if (!probe_ent) {
+ 		rc = -ENOMEM;
+ 		goto err_out_regions;
+diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
+--- a/drivers/scsi/sata_via.c
++++ b/drivers/scsi/sata_via.c
+@@ -41,6 +41,7 @@
+ #include <linux/init.h>
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -109,7 +110,7 @@ static Scsi_Host_Template svia_sht = {
+ 	.ordered_flush		= 1,
+ };
+ 
+-static struct ata_port_operations svia_sata_ops = {
++static const struct ata_port_operations svia_sata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 
+ 	.tf_load		= ata_tf_load,
+@@ -212,7 +213,7 @@ static struct ata_probe_ent *vt6420_init
+ 	struct ata_probe_ent *probe_ent;
+ 	struct ata_port_info *ppi = &svia_port_info;
+ 
+-	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
++	probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
+ 	if (!probe_ent)
+ 		return NULL;
+ 
+@@ -259,15 +260,15 @@ static void svia_configure(struct pci_de
+ 	u8 tmp8;
+ 
+ 	pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
+-	printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
+-	       pci_name(pdev),
++	dev_printk(KERN_INFO, &pdev->dev, "routed to hard irq line %d\n",
+ 	       (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
+ 
+ 	/* make sure SATA channels are enabled */
+ 	pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
+ 	if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
+-		printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
+-		       pci_name(pdev), (int) tmp8);
++		dev_printk(KERN_DEBUG, &pdev->dev,
++			   "enabling SATA channels (0x%x)\n",
++		           (int) tmp8);
+ 		tmp8 |= ALL_PORTS;
+ 		pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
+ 	}
+@@ -275,8 +276,9 @@ static void svia_configure(struct pci_de
+ 	/* make sure interrupts for each channel sent to us */
+ 	pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
+ 	if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
+-		printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
+-		       pci_name(pdev), (int) tmp8);
++		dev_printk(KERN_DEBUG, &pdev->dev,
++			   "enabling SATA channel interrupts (0x%x)\n",
++		           (int) tmp8);
+ 		tmp8 |= ALL_PORTS;
+ 		pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
+ 	}
+@@ -284,8 +286,9 @@ static void svia_configure(struct pci_de
+ 	/* make sure native mode is enabled */
+ 	pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
+ 	if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
+-		printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
+-		       pci_name(pdev), (int) tmp8);
++		dev_printk(KERN_DEBUG, &pdev->dev,
++			   "enabling SATA channel native mode (0x%x)\n",
++		           (int) tmp8);
+ 		tmp8 |= NATIVE_MODE_ALL;
+ 		pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
+ 	}
+@@ -303,7 +306,7 @@ static int svia_init_one (struct pci_dev
+ 	u8 tmp8;
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+@@ -318,8 +321,9 @@ static int svia_init_one (struct pci_dev
+ 	if (board_id == vt6420) {
+ 		pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
+ 		if (tmp8 & SATA_2DEV) {
+-			printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
+-		       	pci_name(pdev), (int) tmp8);
++			dev_printk(KERN_ERR, &pdev->dev,
++				   "SATA master/slave not supported (0x%x)\n",
++		       		   (int) tmp8);
+ 			rc = -EIO;
+ 			goto err_out_regions;
+ 		}
+@@ -332,10 +336,11 @@ static int svia_init_one (struct pci_dev
+ 	for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
+ 		if ((pci_resource_start(pdev, i) == 0) ||
+ 		    (pci_resource_len(pdev, i) < bar_sizes[i])) {
+-			printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
+-			       pci_name(pdev), i,
+-			       pci_resource_start(pdev, i),
+-			       pci_resource_len(pdev, i));
++			dev_printk(KERN_ERR, &pdev->dev,
++				   "invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
++				   i,
++			           pci_resource_start(pdev, i),
++			           pci_resource_len(pdev, i));
+ 			rc = -ENODEV;
+ 			goto err_out_regions;
+ 		}
+@@ -353,8 +358,7 @@ static int svia_init_one (struct pci_dev
+ 		probe_ent = vt6421_init_probe_ent(pdev);
+ 
+ 	if (!probe_ent) {
+-		printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
+-		       pci_name(pdev));
++		dev_printk(KERN_ERR, &pdev->dev, "out of memory\n");
+ 		rc = -ENOMEM;
+ 		goto err_out_regions;
+ 	}
+diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
+--- a/drivers/scsi/sata_vsc.c
++++ b/drivers/scsi/sata_vsc.c
+@@ -42,6 +42,7 @@
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+ #include <linux/dma-mapping.h>
++#include <linux/device.h>
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include <linux/libata.h>
+@@ -86,7 +87,7 @@ static u32 vsc_sata_scr_read (struct ata
+ {
+ 	if (sc_reg > SCR_CONTROL)
+ 		return 0xffffffffU;
+-	return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
++	return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+ 
+ 
+@@ -95,16 +96,16 @@ static void vsc_sata_scr_write (struct a
+ {
+ 	if (sc_reg > SCR_CONTROL)
+ 		return;
+-	writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
++	writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ }
+ 
+ 
+ static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
+ {
+-	unsigned long mask_addr;
++	void __iomem *mask_addr;
+ 	u8 mask;
+ 
+-	mask_addr = (unsigned long) ap->host_set->mmio_base +
++	mask_addr = ap->host_set->mmio_base +
+ 		VSC_SATA_INT_MASK_OFFSET + ap->port_no;
+ 	mask = readb(mask_addr);
+ 	if (ctl & ATA_NIEN)
+@@ -115,7 +116,7 @@ static void vsc_intr_mask_update(struct 
+ }
+ 
+ 
+-static void vsc_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
++static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+ 	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+@@ -153,16 +154,24 @@ static void vsc_sata_tf_load(struct ata_
+ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ 	struct ata_ioports *ioaddr = &ap->ioaddr;
+-	u16 nsect, lbal, lbam, lbah;
++	u16 nsect, lbal, lbam, lbah, feature;
+ 
+-	nsect = tf->nsect = readw(ioaddr->nsect_addr);
+-	lbal = tf->lbal = readw(ioaddr->lbal_addr);
+-	lbam = tf->lbam = readw(ioaddr->lbam_addr);
+-	lbah = tf->lbah = readw(ioaddr->lbah_addr);
++	tf->command = ata_check_status(ap);
+ 	tf->device = readw(ioaddr->device_addr);
++	feature = readw(ioaddr->error_addr);
++	nsect = readw(ioaddr->nsect_addr);
++	lbal = readw(ioaddr->lbal_addr);
++	lbam = readw(ioaddr->lbam_addr);
++	lbah = readw(ioaddr->lbah_addr);
++
++	tf->feature = feature;
++	tf->nsect = nsect;
++	tf->lbal = lbal;
++	tf->lbam = lbam;
++	tf->lbah = lbah;
+ 
+ 	if (tf->flags & ATA_TFLAG_LBA48) {
+-		tf->hob_feature = readb(ioaddr->error_addr);
++		tf->hob_feature = feature >> 8;
+ 		tf->hob_nsect = nsect >> 8;
+ 		tf->hob_lbal = lbal >> 8;
+ 		tf->hob_lbam = lbam >> 8;
+@@ -231,7 +240,7 @@ static Scsi_Host_Template vsc_sata_sht =
+ };
+ 
+ 
+-static struct ata_port_operations vsc_sata_ops = {
++static const struct ata_port_operations vsc_sata_ops = {
+ 	.port_disable		= ata_port_disable,
+ 	.tf_load		= vsc_sata_tf_load,
+ 	.tf_read		= vsc_sata_tf_read,
+@@ -283,11 +292,11 @@ static int __devinit vsc_sata_init_one (
+ 	struct ata_probe_ent *probe_ent = NULL;
+ 	unsigned long base;
+ 	int pci_dev_busy = 0;
+-	void *mmio_base;
++	void __iomem *mmio_base;
+ 	int rc;
+ 
+ 	if (!printed_version++)
+-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ 
+ 	rc = pci_enable_device(pdev);
+ 	if (rc)
+diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
+--- a/drivers/scsi/scsi.c
++++ b/drivers/scsi/scsi.c
+@@ -130,7 +130,7 @@ EXPORT_SYMBOL(scsi_device_types);
+  * Returns:     Pointer to request block.
+  */
+ struct scsi_request *scsi_allocate_request(struct scsi_device *sdev,
+-					   int gfp_mask)
++					   gfp_t gfp_mask)
+ {
+ 	const int offset = ALIGN(sizeof(struct scsi_request), 4);
+ 	const int size = offset + sizeof(struct request);
+@@ -196,7 +196,7 @@ struct scsi_host_cmd_pool {
+ 	unsigned int	users;
+ 	char		*name;
+ 	unsigned int	slab_flags;
+-	unsigned int	gfp_mask;
++	gfp_t		gfp_mask;
+ };
+ 
+ static struct scsi_host_cmd_pool scsi_cmd_pool = {
+@@ -213,7 +213,7 @@ static struct scsi_host_cmd_pool scsi_cm
+ static DECLARE_MUTEX(host_cmd_pool_mutex);
+ 
+ static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
+-					    int gfp_mask)
++					    gfp_t gfp_mask)
+ {
+ 	struct scsi_cmnd *cmd;
+ 
+@@ -245,7 +245,7 @@ static struct scsi_cmnd *__scsi_get_comm
+  *
+  * Returns:	The allocated scsi command structure.
+  */
+-struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask)
++struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask)
+ {
+ 	struct scsi_cmnd *cmd;
+ 
+diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
+--- a/drivers/scsi/scsi_ioctl.c
++++ b/drivers/scsi/scsi_ioctl.c
+@@ -205,7 +205,8 @@ int scsi_ioctl_send_command(struct scsi_
+ 	unsigned int inlen, outlen, cmdlen;
+ 	unsigned int needed, buf_needed;
+ 	int timeout, retries, result;
+-	int data_direction, gfp_mask = GFP_KERNEL;
++	int data_direction;
++	gfp_t gfp_mask = GFP_KERNEL;
+ 
+ 	if (!sic)
+ 		return -EINVAL;
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -677,7 +677,7 @@ static struct scsi_cmnd *scsi_end_reques
+ 	return NULL;
+ }
+ 
+-static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, int gfp_mask)
++static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+ {
+ 	struct scsi_host_sg_pool *sgp;
+ 	struct scatterlist *sgl;
+diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
+--- a/drivers/scsi/scsi_transport_fc.c
++++ b/drivers/scsi/scsi_transport_fc.c
+@@ -26,6 +26,7 @@
+  */
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/sched.h>	/* workqueue stuff, HZ */
+ #include <scsi/scsi_device.h>
+ #include <scsi/scsi_host.h>
+ #include <scsi/scsi_transport.h>
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -19,6 +19,9 @@
+  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ #include <linux/module.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++
+ #include <scsi/scsi.h>
+ #include <scsi/scsi_host.h>
+ #include <scsi/scsi_device.h>
+diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -49,6 +49,7 @@ static int sg_version_num = 30533;	/* 2 
+ #include <linux/seq_file.h>
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
++#include <linux/scatterlist.h>
+ 
+ #include "scsi.h"
+ #include <scsi/scsi_dbg.h>
+@@ -104,8 +105,8 @@ static int sg_allow_dio = SG_ALLOW_DIO_D
+ 
+ #define SG_DEV_ARR_LUMP 32	/* amount to over allocate sg_dev_arr by */
+ 
+-static int sg_add(struct class_device *);
+-static void sg_remove(struct class_device *);
++static int sg_add(struct class_device *, struct class_interface *);
++static void sg_remove(struct class_device *, struct class_interface *);
+ 
+ static Scsi_Request *dummy_cmdp;	/* only used for sizeof */
+ 
+@@ -1506,7 +1507,7 @@ static int sg_alloc(struct gendisk *disk
+ }
+ 
+ static int
+-sg_add(struct class_device *cl_dev)
++sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
+ {
+ 	struct scsi_device *scsidp = to_scsi_device(cl_dev->dev);
+ 	struct gendisk *disk;
+@@ -1550,7 +1551,7 @@ sg_add(struct class_device *cl_dev)
+ 	if (sg_sysfs_valid) {
+ 		struct class_device * sg_class_member;
+ 
+-		sg_class_member = class_device_create(sg_sysfs_class,
++		sg_class_member = class_device_create(sg_sysfs_class, NULL,
+ 				MKDEV(SCSI_GENERIC_MAJOR, k), 
+ 				cl_dev->dev, "%s", 
+ 				disk->disk_name);
+@@ -1582,7 +1583,7 @@ out:
+ }
+ 
+ static void
+-sg_remove(struct class_device *cl_dev)
++sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
+ {
+ 	struct scsi_device *scsidp = to_scsi_device(cl_dev->dev);
+ 	Sg_device *sdp = NULL;
+@@ -1886,13 +1887,17 @@ st_unmap_user_pages(struct scatterlist *
+ 	int i;
+ 
+ 	for (i=0; i < nr_pages; i++) {
+-		if (dirtied && !PageReserved(sgl[i].page))
+-			SetPageDirty(sgl[i].page);
+-		/* unlock_page(sgl[i].page); */
++		struct page *page = sgl[i].page;
++
++		/* XXX: just for debug. Remove when PageReserved is removed */
++		BUG_ON(PageReserved(page));
++		if (dirtied)
++			SetPageDirty(page);
++		/* unlock_page(page); */
+ 		/* FIXME: cache flush missing for rw==READ
+ 		 * FIXME: call the correct reference counting function
+ 		 */
+-		page_cache_release(sgl[i].page);
++		page_cache_release(page);
+ 	}
+ 
+ 	return 0;
+@@ -1992,9 +1997,7 @@ sg_build_indirect(Sg_scatter_hold * schp
+ 				if (!p)
+ 					break;
+ 			}
+-			sclp->page = virt_to_page(p);
+-			sclp->offset = offset_in_page(p);
+-			sclp->length = ret_sz;
++			sg_set_buf(sclp, p, ret_sz);
+ 
+ 			SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
+ 					  k, sg_scatg2virt(sclp), ret_sz));
+@@ -2644,7 +2647,7 @@ static char *
+ sg_page_malloc(int rqSz, int lowDma, int *retSzp)
+ {
+ 	char *resp = NULL;
+-	int page_mask;
++	gfp_t page_mask;
+ 	int order, a_size;
+ 	int resSz = rqSz;
+ 
+diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
+--- a/drivers/scsi/st.c
++++ b/drivers/scsi/st.c
+@@ -3577,7 +3577,8 @@ static long st_compat_ioctl(struct file 
+ static struct st_buffer *
+  new_tape_buffer(int from_initialization, int need_dma, int max_sg)
+ {
+-	int i, priority, got = 0, segs = 0;
++	int i, got = 0, segs = 0;
++	gfp_t priority;
+ 	struct st_buffer *tb;
+ 
+ 	if (from_initialization)
+@@ -3610,7 +3611,8 @@ static struct st_buffer *
+ /* Try to allocate enough space in the tape buffer */
+ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
+ {
+-	int segs, nbr, max_segs, b_size, priority, order, got;
++	int segs, nbr, max_segs, b_size, order, got;
++	gfp_t priority;
+ 
+ 	if (new_size <= STbuffer->buffer_size)
+ 		return 1;
+@@ -4375,7 +4377,7 @@ static void do_create_class_files(struct
+ 		snprintf(name, 10, "%s%s%s", rew ? "n" : "",
+ 			 STp->disk->disk_name, st_formats[i]);
+ 		st_class_member =
+-			class_device_create(st_sysfs_class,
++			class_device_create(st_sysfs_class, NULL,
+ 					    MKDEV(SCSI_TAPE_MAJOR,
+ 						  TAPE_MINOR(dev_num, mode, rew)),
+ 					    &STp->device->sdev_gendev, "%s", name);
+@@ -4524,12 +4526,16 @@ static int sgl_unmap_user_pages(struct s
+ 	int i;
+ 
+ 	for (i=0; i < nr_pages; i++) {
+-		if (dirtied && !PageReserved(sgl[i].page))
+-			SetPageDirty(sgl[i].page);
++		struct page *page = sgl[i].page;
++
++		/* XXX: just for debug. Remove when PageReserved is removed */
++		BUG_ON(PageReserved(page));
++		if (dirtied)
++			SetPageDirty(page);
+ 		/* FIXME: cache flush missing for rw==READ
+ 		 * FIXME: call the correct reference counting function
+ 		 */
+-		page_cache_release(sgl[i].page);
++		page_cache_release(page);
+ 	}
+ 
+ 	return 0;
+diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
+--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
++++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
+@@ -37,6 +37,9 @@
+  * 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/slab.h>
++
+ #include "sym_glue.h"
+ #include "sym_nvram.h"
+ 
+diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
+--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
++++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
+@@ -37,6 +37,8 @@
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
++#include <linux/gfp.h>
++
+ #ifndef SYM_HIPD_H
+ #define SYM_HIPD_H
+ 
+diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
+--- a/drivers/scsi/zalon.c
++++ b/drivers/scsi/zalon.c
+@@ -88,7 +88,7 @@ zalon_probe(struct parisc_device *dev)
+ 	struct gsc_irq gsc_irq;
+ 	u32 zalon_vers;
+ 	int error = -ENODEV;
+-	void __iomem *zalon = ioremap(dev->hpa, 4096);
++	void __iomem *zalon = ioremap(dev->hpa.start, 4096);
+ 	void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET;
+ 	static int unit = 0;
+ 	struct Scsi_Host *host;
+@@ -127,7 +127,7 @@ zalon_probe(struct parisc_device *dev)
+ 	device.chip		= zalon720_chip;
+ 	device.host_id		= 7;
+ 	device.dev		= &dev->dev;
+-	device.slot.base	= dev->hpa + GSC_SCSI_ZALON_OFFSET;
++	device.slot.base	= dev->hpa.start + GSC_SCSI_ZALON_OFFSET;
+ 	device.slot.base_v	= io_port;
+ 	device.slot.irq		= dev->irq;
+ 	device.differential	= 2;
+diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
+--- a/drivers/serial/8250.c
++++ b/drivers/serial/8250.c
+@@ -33,7 +33,7 @@
+ #include <linux/sysrq.h>
+ #include <linux/mca.h>
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/tty.h>
+ #include <linux/tty_flip.h>
+ #include <linux/serial_reg.h>
+@@ -2358,13 +2358,10 @@ static int __devexit serial8250_remove(s
+ 	return 0;
+ }
+ 
+-static int serial8250_suspend(struct device *dev, pm_message_t state, u32 level)
++static int serial8250_suspend(struct device *dev, pm_message_t state)
+ {
+ 	int i;
+ 
+-	if (level != SUSPEND_DISABLE)
+-		return 0;
+-
+ 	for (i = 0; i < UART_NR; i++) {
+ 		struct uart_8250_port *up = &serial8250_ports[i];
+ 
+@@ -2375,13 +2372,10 @@ static int serial8250_suspend(struct dev
+ 	return 0;
+ }
+ 
+-static int serial8250_resume(struct device *dev, u32 level)
++static int serial8250_resume(struct device *dev)
+ {
+ 	int i;
+ 
+-	if (level != RESUME_ENABLE)
+-		return 0;
+-
+ 	for (i = 0; i < UART_NR; i++) {
+ 		struct uart_8250_port *up = &serial8250_ports[i];
+ 
+diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
+--- a/drivers/serial/8250_gsc.c
++++ b/drivers/serial/8250_gsc.c
+@@ -29,7 +29,6 @@
+ static int __init 
+ serial_init_chip(struct parisc_device *dev)
+ {
+-	static int serial_line_nr;
+ 	struct uart_port port;
+ 	unsigned long address;
+ 	int err;
+@@ -42,12 +41,13 @@ serial_init_chip(struct parisc_device *d
+ 		 */
+ 		if (parisc_parent(dev)->id.hw_type != HPHW_IOA) {
+ 			printk(KERN_INFO "Serial: device 0x%lx not configured.\n"
+-				"Enable support for Wax, Lasi, Asp or Dino.\n", dev->hpa);
++				"Enable support for Wax, Lasi, Asp or Dino.\n",
++				dev->hpa.start);
+ 		}
+ 		return -ENODEV;
+ 	}
+ 
+-	address = dev->hpa;
++	address = dev->hpa.start;
+ 	if (dev->id.sversion != 0x8d) {
+ 		address += 0x800;
+ 	}
+diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
+--- a/drivers/serial/amba-pl010.c
++++ b/drivers/serial/amba-pl010.c
+@@ -50,6 +50,7 @@
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
++#include <asm/hardware.h>
+ #include <asm/hardware/amba.h>
+ #include <asm/hardware/amba_serial.h>
+ 
+diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
+--- a/drivers/serial/amba-pl011.c
++++ b/drivers/serial/amba-pl011.c
+@@ -50,6 +50,7 @@
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
++#include <asm/sizes.h>
+ #include <asm/hardware/amba.h>
+ #include <asm/hardware/clock.h>
+ #include <asm/hardware/amba_serial.h>
+diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
+--- a/drivers/serial/clps711x.c
++++ b/drivers/serial/clps711x.c
+@@ -408,7 +408,11 @@ static struct uart_port clps711x_ports[U
+ 	{
+ 		.iobase		= SYSCON1,
+ 		.irq		= IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */
++#ifdef CONFIG_MP1000_90MHZ
++		.uartclk	= 4515840,
++#else
+ 		.uartclk	= 3686400,
++#endif
+ 		.fifosize	= 16,
+ 		.ops		= &clps711x_pops,
+ 		.line		= 0,
+@@ -417,7 +421,11 @@ static struct uart_port clps711x_ports[U
+ 	{
+ 		.iobase		= SYSCON2,
+ 		.irq		= IRQ_UTXINT2, /* IRQ_URXINT2 */
++#ifdef CONFIG_MP1000_90MHZ
++		.uartclk	= 4515840,
++#else
+ 		.uartclk	= 3686400,
++#endif
+ 		.fifosize	= 16,
+ 		.ops		= &clps711x_pops,
+ 		.line		= 1,
+@@ -551,6 +559,7 @@ console_initcall(clps711xuart_console_in
+ static struct uart_driver clps711x_reg = {
+ 	.driver_name		= "ttyCL",
+ 	.dev_name		= "ttyCL",
++	.devfs_name		= "ttyCL",
+ 	.major			= SERIAL_CLPS711X_MAJOR,
+ 	.minor			= SERIAL_CLPS711X_MINOR,
+ 	.nr			= UART_NR,
+diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
+--- a/drivers/serial/imx.c
++++ b/drivers/serial/imx.c
+@@ -36,7 +36,7 @@
+ #include <linux/init.h>
+ #include <linux/console.h>
+ #include <linux/sysrq.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/tty.h>
+ #include <linux/tty_flip.h>
+ #include <linux/serial_core.h>
+@@ -921,21 +921,21 @@ static struct uart_driver imx_reg = {
+ 	.cons           = IMX_CONSOLE,
+ };
+ 
+-static int serial_imx_suspend(struct device *_dev, pm_message_t state, u32 level)
++static int serial_imx_suspend(struct device *_dev, pm_message_t state)
+ {
+         struct imx_port *sport = dev_get_drvdata(_dev);
+ 
+-        if (sport && level == SUSPEND_DISABLE)
++        if (sport)
+                 uart_suspend_port(&imx_reg, &sport->port);
+ 
+         return 0;
+ }
+ 
+-static int serial_imx_resume(struct device *_dev, u32 level)
++static int serial_imx_resume(struct device *_dev)
+ {
+         struct imx_port *sport = dev_get_drvdata(_dev);
+ 
+-        if (sport && level == RESUME_ENABLE)
++        if (sport)
+                 uart_resume_port(&imx_reg, &sport->port);
+ 
+         return 0;
+@@ -995,6 +995,7 @@ static int __init imx_serial_init(void)
+ static void __exit imx_serial_exit(void)
+ {
+ 	uart_unregister_driver(&imx_reg);
++	driver_unregister(&serial_imx_driver);
+ }
+ 
+ module_init(imx_serial_init);
+diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
+--- a/drivers/serial/ioc4_serial.c
++++ b/drivers/serial/ioc4_serial.c
+@@ -308,6 +308,8 @@ struct ioc4_serial {
+ typedef void ioc4_intr_func_f(void *, uint32_t);
+ typedef ioc4_intr_func_f *ioc4_intr_func_t;
+ 
++static unsigned int Num_of_ioc4_cards;
++
+ /* defining this will get you LOTS of great debug info */
+ //#define DEBUG_INTERRUPTS
+ #define DPRINT_CONFIG(_x...)	;
+@@ -317,7 +319,8 @@ typedef ioc4_intr_func_f *ioc4_intr_func
+ #define WAKEUP_CHARS	256
+ 
+ /* number of characters we want to transmit to the lower level at a time */
+-#define IOC4_MAX_CHARS	128
++#define IOC4_MAX_CHARS	256
++#define IOC4_FIFO_CHARS	255
+ 
+ /* Device name we're using */
+ #define DEVICE_NAME	"ttyIOC"
+@@ -1038,6 +1041,7 @@ static int inline ioc4_attach_local(stru
+ 			return -ENOMEM;
+ 		}
+ 		memset(port, 0, sizeof(struct ioc4_port));
++		spin_lock_init(&port->ip_lock);
+ 
+ 		/* we need to remember the previous ones, to point back to
+ 		 * them farther down - setting up the ring buffers.
+@@ -1691,12 +1695,14 @@ ioc4_change_speed(struct uart_port *the_
+ 		baud = 9600;
+ 
+ 	if (!the_port->fifosize)
+-		the_port->fifosize = IOC4_MAX_CHARS;
++		the_port->fifosize = IOC4_FIFO_CHARS;
+ 	the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10));
+ 	the_port->timeout += HZ / 50;	/* Add .02 seconds of slop */
+ 
+ 	the_port->ignore_status_mask = N_ALL_INPUT;
+ 
++	info->tty->low_latency = 1;
++
+ 	if (I_IGNPAR(info->tty))
+ 		the_port->ignore_status_mask &= ~(N_PARITY_ERROR
+ 						| N_FRAMING_ERROR);
+@@ -1742,7 +1748,6 @@ ioc4_change_speed(struct uart_port *the_
+  */
+ static inline int ic4_startup_local(struct uart_port *the_port)
+ {
+-	int retval = 0;
+ 	struct ioc4_port *port;
+ 	struct uart_info *info;
+ 
+@@ -1754,9 +1759,6 @@ static inline int ic4_startup_local(stru
+ 		return -1;
+ 
+ 	info = the_port->info;
+-	if (info->flags & UIF_INITIALIZED) {
+-		return retval;
+-	}
+ 
+ 	if (info->tty) {
+ 		set_bit(TTY_IO_ERROR, &info->tty->flags);
+@@ -1775,7 +1777,6 @@ static inline int ic4_startup_local(stru
+ 	/* set the speed of the serial port */
+ 	ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
+ 
+-	info->flags |= UIF_INITIALIZED;
+ 	return 0;
+ }
+ 
+@@ -1785,9 +1786,13 @@ static inline int ic4_startup_local(stru
+  */
+ static void ioc4_cb_output_lowat(struct ioc4_port *port)
+ {
++	unsigned long pflags;
++
+ 	/* ip_lock is set on the call here */
+ 	if (port->ip_port) {
++		spin_lock_irqsave(&port->ip_port->lock, pflags);
+ 		transmit_chars(port->ip_port);
++		spin_unlock_irqrestore(&port->ip_port->lock, pflags);
+ 	}
+ }
+ 
+@@ -2064,8 +2069,7 @@ static inline int do_read(struct uart_po
+ 	 * available data as long as it returns some.
+ 	 */
+ 	/* Re-arm the timer */
+-	writel(port->ip_rx_cons | IOC4_SRCIR_ARM,
+-			&port->ip_serial_regs->srcir);
++	writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
+ 
+ 	prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
+ 	cons_ptr = port->ip_rx_cons;
+@@ -2299,6 +2303,7 @@ static inline int do_read(struct uart_po
+ 	}
+ 	return total;
+ }
++
+ /**
+  * receive_chars - upper level read. Called with ip_lock.
+  * @the_port: port to read from
+@@ -2307,9 +2312,11 @@ static void receive_chars(struct uart_po
+ {
+ 	struct tty_struct *tty;
+ 	unsigned char ch[IOC4_MAX_CHARS];
+-	int read_count, request_count;
++	int read_count, request_count = IOC4_MAX_CHARS;
+ 	struct uart_icount *icount;
+ 	struct uart_info *info = the_port->info;
++	int flip = 0;
++	unsigned long pflags;
+ 
+ 	/* Make sure all the pointers are "good" ones */
+ 	if (!info)
+@@ -2317,16 +2324,17 @@ static void receive_chars(struct uart_po
+ 	if (!info->tty)
+ 		return;
+ 
++	spin_lock_irqsave(&the_port->lock, pflags);
+ 	tty = info->tty;
+ 
+-	request_count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
++	if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count)
++		request_count = TTY_FLIPBUF_SIZE - tty->flip.count;
+ 
+ 	if (request_count > 0) {
+-		if (request_count > IOC4_MAX_CHARS - 2)
+-			request_count = IOC4_MAX_CHARS - 2;
+ 		icount = &the_port->icount;
+ 		read_count = do_read(the_port, ch, request_count);
+ 		if (read_count > 0) {
++			flip = 1;
+ 			memcpy(tty->flip.char_buf_ptr, ch, read_count);
+ 			memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count);
+ 			tty->flip.char_buf_ptr += read_count;
+@@ -2335,7 +2343,11 @@ static void receive_chars(struct uart_po
+ 			icount->rx += read_count;
+ 		}
+ 	}
+-	tty_flip_buffer_push(tty);
++
++	spin_unlock_irqrestore(&the_port->lock, pflags);
++
++	if (flip)
++		tty_flip_buffer_push(tty);
+ }
+ 
+ /**
+@@ -2393,18 +2405,14 @@ static void ic4_shutdown(struct uart_por
+ 
+ 	info = the_port->info;
+ 
+-	if (!(info->flags & UIF_INITIALIZED))
+-		return;
+-
+ 	wake_up_interruptible(&info->delta_msr_wait);
+ 
+ 	if (info->tty)
+ 		set_bit(TTY_IO_ERROR, &info->tty->flags);
+ 
+-	spin_lock_irqsave(&port->ip_lock, port_flags);
++	spin_lock_irqsave(&the_port->lock, port_flags);
+ 	set_notification(port, N_ALL, 0);
+-	info->flags &= ~UIF_INITIALIZED;
+-	spin_unlock_irqrestore(&port->ip_lock, port_flags);
++	spin_unlock_irqrestore(&the_port->lock, port_flags);
+ }
+ 
+ /**
+@@ -2463,12 +2471,10 @@ static unsigned int ic4_get_mctrl(struct
+ static void ic4_start_tx(struct uart_port *the_port)
+ {
+ 	struct ioc4_port *port = get_ioc4_port(the_port);
+-	unsigned long flags;
+ 
+ 	if (port) {
+-		spin_lock_irqsave(&port->ip_lock, flags);
+-		transmit_chars(the_port);
+-		spin_unlock_irqrestore(&port->ip_lock, flags);
++		set_notification(port, N_OUTPUT_LOWAT, 1);
++		enable_intrs(port, port->ip_hooks->intr_tx_mt);
+ 	}
+ }
+ 
+@@ -2510,9 +2516,9 @@ static int ic4_startup(struct uart_port 
+ 	}
+ 
+ 	/* Start up the serial port */
+-	spin_lock_irqsave(&port->ip_lock, port_flags);
++	spin_lock_irqsave(&the_port->lock, port_flags);
+ 	retval = ic4_startup_local(the_port);
+-	spin_unlock_irqrestore(&port->ip_lock, port_flags);
++	spin_unlock_irqrestore(&the_port->lock, port_flags);
+ 	return retval;
+ }
+ 
+@@ -2527,12 +2533,11 @@ static void
+ ic4_set_termios(struct uart_port *the_port,
+ 		struct termios *termios, struct termios *old_termios)
+ {
+-	struct ioc4_port *port = get_ioc4_port(the_port);
+ 	unsigned long port_flags;
+ 
+-	spin_lock_irqsave(&port->ip_lock, port_flags);
++	spin_lock_irqsave(&the_port->lock, port_flags);
+ 	ioc4_change_speed(the_port, termios, old_termios);
+-	spin_unlock_irqrestore(&port->ip_lock, port_flags);
++	spin_unlock_irqrestore(&the_port->lock, port_flags);
+ }
+ 
+ /**
+@@ -2607,24 +2612,25 @@ ioc4_serial_core_attach(struct pci_dev *
+ 				__FUNCTION__, (void *)the_port,
+ 				(void *)port));
+ 
+-		spin_lock_init(&the_port->lock);
+ 		/* membase, iobase and mapbase just need to be non-0 */
+ 		the_port->membase = (unsigned char __iomem *)1;
+-		the_port->line = the_port->iobase = ii;
++		the_port->iobase = (pdev->bus->number << 16) |  ii;
++		the_port->line = (Num_of_ioc4_cards << 2) | ii;
+ 		the_port->mapbase = 1;
+ 		the_port->type = PORT_16550A;
+-		the_port->fifosize = IOC4_MAX_CHARS;
++		the_port->fifosize = IOC4_FIFO_CHARS;
+ 		the_port->ops = &ioc4_ops;
+ 		the_port->irq = control->ic_irq;
+ 		the_port->dev = &pdev->dev;
++		spin_lock_init(&the_port->lock);
+ 		if (uart_add_one_port(&ioc4_uart, the_port) < 0) {
+ 			printk(KERN_WARNING
+-				       "%s: unable to add port %d\n",
+-				       __FUNCTION__, the_port->line);
++		           "%s: unable to add port %d bus %d\n",
++			       __FUNCTION__, the_port->line, pdev->bus->number);
+ 		} else {
+ 			DPRINT_CONFIG(
+-				    ("IOC4 serial driver port %d irq = %d\n",
+-				       the_port->line, the_port->irq));
++			    ("IOC4 serial port %d irq = %d, bus %d\n",
++			       the_port->line, the_port->irq, pdev->bus->number));
+ 		}
+ 		/* all ports are rs232 for now */
+ 		ioc4_set_proto(port, PROTO_RS232);
+@@ -2734,6 +2740,8 @@ ioc4_serial_attach_one(struct ioc4_drive
+ 	if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
+ 		goto out4;
+ 
++	Num_of_ioc4_cards++;
++
+ 	return ret;
+ 
+ 	/* error exits that give back resources */
+diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
+--- a/drivers/serial/mpc52xx_uart.c
++++ b/drivers/serial/mpc52xx_uart.c
+@@ -45,7 +45,7 @@
+  */
+ 
+ #include <linux/config.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <linux/tty.h>
+ #include <linux/serial.h>
+@@ -781,22 +781,22 @@ mpc52xx_uart_remove(struct device *dev)
+ 
+ #ifdef CONFIG_PM
+ static int
+-mpc52xx_uart_suspend(struct device *dev, pm_message_t state, u32 level)
++mpc52xx_uart_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+ 
+-	if (sport && level == SUSPEND_DISABLE)
++	if (sport)
+ 		uart_suspend_port(&mpc52xx_uart_driver, port);
+ 
+ 	return 0;
+ }
+ 
+ static int
+-mpc52xx_uart_resume(struct device *dev, u32 level)
++mpc52xx_uart_resume(struct device *dev)
+ {
+ 	struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+ 
+-	if (port && level == RESUME_ENABLE)
++	if (port)
+ 		uart_resume_port(&mpc52xx_uart_driver, port);
+ 
+ 	return 0;
+diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
+--- a/drivers/serial/mpsc.c
++++ b/drivers/serial/mpsc.c
+@@ -52,6 +52,8 @@
+  * 4) AFAICT, hardware flow control isn't supported by the controller --MAG.
+  */
+ 
++#include <linux/platform_device.h>
++
+ #include "mpsc.h"
+ 
+ /*
+@@ -1100,6 +1102,8 @@ mpsc_start_rx(struct mpsc_port_info *pi)
+ {
+ 	pr_debug("mpsc_start_rx[%d]: Starting...\n", pi->port.line);
+ 
++	/* Issue a Receive Abort to clear any receive errors */
++	writel(MPSC_CHR_2_RA, pi->mpsc_base + MPSC_CHR_2);
+ 	if (pi->rcv_data) {
+ 		mpsc_enter_hunt(pi);
+ 		mpsc_sdma_cmd(pi, SDMA_SDCM_ERD);
+diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
+--- a/drivers/serial/mux.c
++++ b/drivers/serial/mux.c
+@@ -27,6 +27,7 @@
+ #include <linux/delay.h> /* for udelay */
+ #include <linux/device.h>
+ #include <asm/io.h>
++#include <asm/irq.h>
+ #include <asm/parisc-device.h>
+ 
+ #ifdef CONFIG_MAGIC_SYSRQ
+@@ -444,7 +445,7 @@ static int __init mux_probe(struct paris
+ 	unsigned long bytecnt;
+ 	struct uart_port *port;
+ 
+-	status = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 32);
++	status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32);
+ 	if(status != PDC_OK) {
+ 		printk(KERN_ERR "Serial mux: Unable to read IODC.\n");
+ 		return 1;
+@@ -469,16 +470,18 @@ static int __init mux_probe(struct paris
+ 	for(i = 0; i < ports; ++i, ++port_cnt) {
+ 		port = &mux_ports[port_cnt];
+ 		port->iobase	= 0;
+-		port->mapbase	= dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET);
++		port->mapbase	= dev->hpa.start + MUX_OFFSET +
++						(i * MUX_LINE_OFFSET);
+ 		port->membase	= ioremap(port->mapbase, MUX_LINE_OFFSET);
+ 		port->iotype	= SERIAL_IO_MEM;
+ 		port->type	= PORT_MUX;
+-		port->irq	= SERIAL_IRQ_NONE;
++		port->irq	= NO_IRQ;
+ 		port->uartclk	= 0;
+ 		port->fifosize	= MUX_FIFO_SIZE;
+ 		port->ops	= &mux_pops;
+ 		port->flags	= UPF_BOOT_AUTOCONF;
+ 		port->line	= port_cnt;
++		spin_lock_init(&port->lock);
+ 		status = uart_add_one_port(&mux_driver, port);
+ 		BUG_ON(status);
+ 	}
+@@ -497,7 +500,7 @@ static struct parisc_device_id mux_tbl[]
+ MODULE_DEVICE_TABLE(parisc, mux_tbl);
+ 
+ static struct parisc_driver serial_mux_driver = {
+-	.name =		"Serial MUX",
++	.name =		"serial_mux",
+ 	.id_table =	mux_tbl,
+ 	.probe =	mux_probe,
+ };
+diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
+--- a/drivers/serial/pxa.c
++++ b/drivers/serial/pxa.c
+@@ -39,7 +39,7 @@
+ #include <linux/circ_buf.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/tty.h>
+ #include <linux/tty_flip.h>
+ #include <linux/serial_core.h>
+@@ -358,6 +358,9 @@ static int serial_pxa_startup(struct uar
+ 	unsigned long flags;
+ 	int retval;
+ 
++	if (port->line == 3) /* HWUART */
++		up->mcr |= UART_MCR_AFE;
++	else
+ 	up->mcr = 0;
+ 
+ 	/*
+@@ -481,8 +484,10 @@ serial_pxa_set_termios(struct uart_port 
+ 
+ 	if ((up->port.uartclk / quot) < (2400 * 16))
+ 		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1;
+-	else
++	else if ((up->port.uartclk / quot) < (230400 * 16))
+ 		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8;
++	else
++		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32;
+ 
+ 	/*
+ 	 * Ok, we're now changing the port state.  Do it with
+@@ -772,6 +777,20 @@ static struct uart_pxa_port serial_pxa_p
+ 		.ops		= &serial_pxa_pops,
+ 		.line		= 2,
+ 	},
++  }, {  /* HWUART */
++	.name	= "HWUART",
++	.cken	= CKEN4_HWUART,
++	.port = {
++		.type		= PORT_PXA,
++		.iotype		= UPIO_MEM,
++		.membase	= (void *)&HWUART,
++		.mapbase	= __PREG(HWUART),
++		.irq		= IRQ_HWUART,
++		.uartclk	= 921600 * 16,
++		.fifosize	= 64,
++		.ops		= &serial_pxa_pops,
++		.line		= 3,
++	},
+   }
+ };
+ 
+@@ -786,21 +805,21 @@ static struct uart_driver serial_pxa_reg
+ 	.cons		= PXA_CONSOLE,
+ };
+ 
+-static int serial_pxa_suspend(struct device *_dev, pm_message_t state, u32 level)
++static int serial_pxa_suspend(struct device *_dev, pm_message_t state)
+ {
+         struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+ 
+-        if (sport && level == SUSPEND_DISABLE)
++        if (sport)
+                 uart_suspend_port(&serial_pxa_reg, &sport->port);
+ 
+         return 0;
+ }
+ 
+-static int serial_pxa_resume(struct device *_dev, u32 level)
++static int serial_pxa_resume(struct device *_dev)
+ {
+         struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+ 
+-        if (sport && level == RESUME_ENABLE)
++        if (sport)
+                 uart_resume_port(&serial_pxa_reg, &sport->port);
+ 
+         return 0;
+diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
+--- a/drivers/serial/s3c2410.c
++++ b/drivers/serial/s3c2410.c
+@@ -63,7 +63,7 @@
+ 
+ #include <linux/module.h>
+ #include <linux/ioport.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/init.h>
+ #include <linux/sysrq.h>
+ #include <linux/console.h>
+@@ -1134,23 +1134,22 @@ static int s3c24xx_serial_remove(struct 
+ 
+ #ifdef CONFIG_PM
+ 
+-static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state,
+-				  u32 level)
++static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct uart_port *port = s3c24xx_dev_to_port(dev);
+ 
+-	if (port && level == SUSPEND_DISABLE)
++	if (port)
+ 		uart_suspend_port(&s3c24xx_uart_drv, port);
+ 
+ 	return 0;
+ }
+ 
+-static int s3c24xx_serial_resume(struct device *dev, u32 level)
++static int s3c24xx_serial_resume(struct device *dev)
+ {
+ 	struct uart_port *port = s3c24xx_dev_to_port(dev);
+ 	struct s3c24xx_uart_port *ourport = to_ourport(port);
+ 
+-	if (port && level == RESUME_ENABLE) {
++	if (port) {
+ 		clk_enable(ourport->clk);
+ 		s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
+ 		clk_disable(ourport->clk);
+diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
+--- a/drivers/serial/sa1100.c
++++ b/drivers/serial/sa1100.c
+@@ -35,7 +35,7 @@
+ #include <linux/init.h>
+ #include <linux/console.h>
+ #include <linux/sysrq.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/tty.h>
+ #include <linux/tty_flip.h>
+ #include <linux/serial_core.h>
+@@ -834,21 +834,21 @@ static struct uart_driver sa1100_reg = {
+ 	.cons			= SA1100_CONSOLE,
+ };
+ 
+-static int sa1100_serial_suspend(struct device *_dev, pm_message_t state, u32 level)
++static int sa1100_serial_suspend(struct device *_dev, pm_message_t state)
+ {
+ 	struct sa1100_port *sport = dev_get_drvdata(_dev);
+ 
+-	if (sport && level == SUSPEND_DISABLE)
++	if (sport)
+ 		uart_suspend_port(&sa1100_reg, &sport->port);
+ 
+ 	return 0;
+ }
+ 
+-static int sa1100_serial_resume(struct device *_dev, u32 level)
++static int sa1100_serial_resume(struct device *_dev)
+ {
+ 	struct sa1100_port *sport = dev_get_drvdata(_dev);
+ 
+-	if (sport && level == RESUME_ENABLE)
++	if (sport)
+ 		uart_resume_port(&sa1100_reg, &sport->port);
+ 
+ 	return 0;
+diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
+--- a/drivers/serial/serial_core.c
++++ b/drivers/serial/serial_core.c
+@@ -147,8 +147,7 @@ static int uart_startup(struct uart_stat
+ 	 * once we have successfully opened the port.  Also set
+ 	 * up the tty->alt_speed kludge
+ 	 */
+-	if (info->tty)
+-		set_bit(TTY_IO_ERROR, &info->tty->flags);
++	set_bit(TTY_IO_ERROR, &info->tty->flags);
+ 
+ 	if (port->type == PORT_UNKNOWN)
+ 		return 0;
+@@ -1968,7 +1967,9 @@ uart_report_port(struct uart_driver *drv
+ 		break;
+ 	}
+ 
+-	printk(KERN_INFO "%s%d at %s (irq = %d) is a %s\n",
++	printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n",
++	       port->dev ? port->dev->bus_id : "",
++	       port->dev ? ": " : "",
+ 	       drv->dev_name, port->line, address, port->irq, uart_type(port));
+ }
+ 
+diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
+--- a/drivers/serial/vr41xx_siu.c
++++ b/drivers/serial/vr41xx_siu.c
+@@ -26,7 +26,7 @@
+ #endif
+ 
+ #include <linux/console.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/err.h>
+ #include <linux/ioport.h>
+ #include <linux/init.h>
+@@ -976,14 +976,11 @@ static int siu_remove(struct device *dev
+ 	return 0;
+ }
+ 
+-static int siu_suspend(struct device *dev, pm_message_t state, u32 level)
++static int siu_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct uart_port *port;
+ 	int i;
+ 
+-	if (level != SUSPEND_DISABLE)
+-		return 0;
+-
+ 	for (i = 0; i < siu_uart_driver.nr; i++) {
+ 		port = &siu_uart_ports[i];
+ 		if ((port->type == PORT_VR41XX_SIU ||
+@@ -995,14 +992,11 @@ static int siu_suspend(struct device *de
+ 	return 0;
+ }
+ 
+-static int siu_resume(struct device *dev, u32 level)
++static int siu_resume(struct device *dev)
+ {
+ 	struct uart_port *port;
+ 	int i;
+ 
+-	if (level != RESUME_ENABLE)
+-		return 0;
+-
+ 	for (i = 0; i < siu_uart_driver.nr; i++) {
+ 		port = &siu_uart_ports[i];
+ 		if ((port->type == PORT_VR41XX_SIU ||
+diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
+--- a/drivers/sh/superhyway/superhyway.c
++++ b/drivers/sh/superhyway/superhyway.c
+@@ -16,6 +16,8 @@
+ #include <linux/types.h>
+ #include <linux/list.h>
+ #include <linux/superhyway.h>
++#include <linux/string.h>
++#include <linux/slab.h>
+ 
+ static int superhyway_devices;
+ 
+diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
+--- a/drivers/tc/tc.c
++++ b/drivers/tc/tc.c
+@@ -8,33 +8,31 @@
+  * for more details.
+  *
+  * Copyright (c) Harald Koerfgen, 1998
+- * Copyright (c) 2001, 2003  Maciej W. Rozycki
++ * Copyright (c) 2001, 2003, 2005  Maciej W. Rozycki
+  */
+-#include <linux/string.h>
+ #include <linux/init.h>
+-#include <linux/ioport.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/string.h>
++#include <linux/types.h>
+ 
+ #include <asm/addrspace.h>
++#include <asm/bug.h>
+ #include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/paccess.h>
++
+ #include <asm/dec/machtype.h>
+ #include <asm/dec/prom.h>
+ #include <asm/dec/tcinfo.h>
+ #include <asm/dec/tcmodule.h>
+ #include <asm/dec/interrupts.h>
+-#include <asm/paccess.h>
+-#include <asm/ptrace.h>
+-
+-#define TC_DEBUG
+ 
+ MODULE_LICENSE("GPL");
+ slot_info tc_bus[MAX_SLOT];
+ static int num_tcslots;
+ static tcinfo *info;
+ 
+-unsigned long system_base;
+-
+ /*
+  * Interface to the world. Read comment in include/asm-mips/tc.h.
+  */
+@@ -97,13 +95,16 @@ unsigned long get_tc_speed(void)
+ static void __init tc_probe(unsigned long startaddr, unsigned long size,
+ 			    int slots)
+ {
++	unsigned long slotaddr;
+ 	int i, slot, err;
+ 	long offset;
+-	unsigned char pattern[4];
+-	unsigned char *module;
++	u8 pattern[4];
++	volatile u8 *module;
+ 
+ 	for (slot = 0; slot < slots; slot++) {
+-		module = (char *)(startaddr + slot * size);
++		slotaddr = startaddr + slot * size;
++		module = ioremap_nocache(slotaddr, size);
++		BUG_ON(!module);
+ 
+ 		offset = OLDCARD;
+ 
+@@ -112,8 +113,10 @@ static void __init tc_probe(unsigned lon
+ 		err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
+ 		err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
+ 		err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
+-		if (err)
++		if (err) {
++			iounmap(module);
+ 			continue;
++		}
+ 
+ 		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
+ 		    pattern[2] != 0xaa || pattern[3] != 0xff) {
+@@ -124,16 +127,20 @@ static void __init tc_probe(unsigned lon
+ 			err |= get_dbe(pattern[1], module + TC_PATTERN1);
+ 			err |= get_dbe(pattern[2], module + TC_PATTERN2);
+ 			err |= get_dbe(pattern[3], module + TC_PATTERN3);
+-			if (err)
++			if (err) {
++				iounmap(module);
+ 				continue;
++			}
+ 		}
+ 
+ 		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
+-		    pattern[2] != 0xaa || pattern[3] != 0xff)
++		    pattern[2] != 0xaa || pattern[3] != 0xff) {
++			iounmap(module);
+ 			continue;
++		}
+ 
+-		tc_bus[slot].base_addr = (unsigned long)module;
+-		for(i = 0; i < 8; i++) {
++		tc_bus[slot].base_addr = slotaddr;
++		for (i = 0; i < 8; i++) {
+ 			tc_bus[slot].firmware[i] =
+ 				module[TC_FIRM_VER + offset + 4 * i];
+ 			tc_bus[slot].vendor[i] =
+@@ -171,13 +178,15 @@ static void __init tc_probe(unsigned lon
+ 			tc_bus[slot].interrupt = -1;
+ 			break;
+ 		}
++
++		iounmap(module);
+ 	}
+ }
+ 
+ /*
+  * the main entry
+  */
+-void __init tc_init(void)
++static int __init tc_init(void)
+ {
+ 	int tc_clock;
+ 	int i;
+@@ -185,7 +194,7 @@ void __init tc_init(void)
+ 	unsigned long slot_size;
+ 
+ 	if (!TURBOCHANNEL)
+-		return;
++		return 0;
+ 
+ 	for (i = 0; i < MAX_SLOT; i++) {
+ 		tc_bus[i].base_addr = 0;
+@@ -196,8 +205,8 @@ void __init tc_init(void)
+ 		tc_bus[i].flags = FREE;
+ 	}
+ 
+-	info = (tcinfo *) rex_gettcinfo();
+-	slot0addr = (unsigned long)KSEG1ADDR(rex_slot_address(0));
++	info = rex_gettcinfo();
++	slot0addr = CPHYSADDR((long)rex_slot_address(0));
+ 
+ 	switch (mips_machtype) {
+ 	case MACH_DS5000_200:
+@@ -216,37 +225,24 @@ void __init tc_init(void)
+ 
+ 	tc_clock = 10000 / info->clk_period;
+ 
+-	if (TURBOCHANNEL && info->slot_size && slot0addr) {
+-		printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision,
+-			tc_clock / 10, tc_clock % 10);
+-		printk("(with%s parity)\n", info->parity ? "" : "out");
++	if (info->slot_size && slot0addr) {
++		pr_info("TURBOchannel rev. %d at %d.%d MHz (with%s parity)\n",
++			info->revision, tc_clock / 10, tc_clock % 10,
++			info->parity ? "" : "out");
+ 
+ 		slot_size = info->slot_size << 20;
+ 
+ 		tc_probe(slot0addr, slot_size, num_tcslots);
+ 
+-  		/*
+-  		 * All TURBOchannel DECstations have the onboard devices
+- 		 * where the (num_tcslots + 0 or 1 on DS5k/xx) Option Module
+- 		 * would be.
+- 		 */
+- 		if(mips_machtype == MACH_DS5000_XX)
+- 			i = 1;
+-		else
+- 			i = 0;
+-
+- 	        system_base = slot0addr + slot_size * (num_tcslots + i);
+-
+-#ifdef TC_DEBUG
+-		for (i = 0; i < num_tcslots; i++)
+-			if (tc_bus[i].base_addr) {
+-				printk("    slot %d: ", i);
+-				printk("%s %s %s\n", tc_bus[i].vendor,
+-					tc_bus[i].name, tc_bus[i].firmware);
+-			}
+-#endif
+-		ioport_resource.end = KSEG2 - 1;
++		for (i = 0; i < num_tcslots; i++) {
++			if (!tc_bus[i].base_addr)
++				continue;
++			pr_info("    slot %d: %s %s %s\n", i, tc_bus[i].vendor,
++				tc_bus[i].name, tc_bus[i].firmware);
++		}
+ 	}
++
++	return 0;
+ }
+ 
+ subsys_initcall(tc_init);
+@@ -257,4 +253,3 @@ EXPORT_SYMBOL(release_tc_card);
+ EXPORT_SYMBOL(get_tc_base_addr);
+ EXPORT_SYMBOL(get_tc_irq_nr);
+ EXPORT_SYMBOL(get_tc_speed);
+-EXPORT_SYMBOL(system_base);
+diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
+--- a/drivers/tc/zs.c
++++ b/drivers/tc/zs.c
+@@ -65,14 +65,14 @@
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ #include <asm/bootinfo.h>
+-#include <asm/dec/serial.h>
+ 
+-#ifdef CONFIG_MACH_DECSTATION
+ #include <asm/dec/interrupts.h>
++#include <asm/dec/ioasic_addrs.h>
+ #include <asm/dec/machtype.h>
++#include <asm/dec/serial.h>
++#include <asm/dec/system.h>
+ #include <asm/dec/tc.h>
+-#include <asm/dec/ioasic_addrs.h>
+-#endif
++
+ #ifdef CONFIG_KGDB
+ #include <asm/kgdb.h>
+ #endif
+@@ -192,18 +192,6 @@ static void probe_sccs(void);
+ static void change_speed(struct dec_serial *info);
+ static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+ 
+-/*
+- * tmp_buf is used as a temporary buffer by serial_write.  We need to
+- * lock it in case the copy_from_user blocks while swapping in a page,
+- * and some other program tries to do a serial write at the same time.
+- * Since the lock will only come under contention when the system is
+- * swapping and available memory is low, it makes sense to share one
+- * buffer across all the serial ports, since it significantly saves
+- * memory if large numbers of serial ports are open.
+- */
+-static unsigned char tmp_buf[4096]; /* This is cheating */
+-static DECLARE_MUTEX(tmp_buf_sem);
+-
+ static inline int serial_paranoia_check(struct dec_serial *info,
+ 					char *name, const char *routine)
+ {
+@@ -1628,30 +1616,22 @@ static void __init probe_sccs(void)
+ 		return;
+ 	}
+ 
+-	/*
+-	 * When serial console is activated, tc_init has not been called yet
+-	 * and system_base is undefined. Unfortunately we have to hardcode
+-	 * system_base for this case :-(. HK
+-	 */
+ 	switch(mips_machtype) {
+ #ifdef CONFIG_MACH_DECSTATION
+ 	case MACH_DS5000_2X0:
+ 	case MACH_DS5900:
+-		system_base = KSEG1ADDR(0x1f800000);
+ 		n_chips = 2;
+ 		zs_parms = &ds_parms;
+ 		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
+ 		zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
+ 		break;
+ 	case MACH_DS5000_1XX:
+-		system_base = KSEG1ADDR(0x1c000000);
+ 		n_chips = 2;
+ 		zs_parms = &ds_parms;
+ 		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
+ 		zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
+ 		break;
+ 	case MACH_DS5000_XX:
+-		system_base = KSEG1ADDR(0x1c000000);
+ 		n_chips = 1;
+ 		zs_parms = &ds_parms;
+ 		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
+@@ -1673,10 +1653,10 @@ static void __init probe_sccs(void)
+ 			 * The sccs reside on the high byte of the 16 bit IOBUS
+ 			 */
+ 			zs_channels[n_channels].control =
+-				(volatile unsigned char *)system_base +
++				(volatile void *)CKSEG1ADDR(dec_kn_slot_base +
+ 			  (0 == chip ? zs_parms->scc0 : zs_parms->scc1) +
+ 			  (0 == channel ? zs_parms->channel_a_offset :
+-			                  zs_parms->channel_b_offset);
++			                  zs_parms->channel_b_offset));
+ 			zs_channels[n_channels].data =
+ 				zs_channels[n_channels].control + 4;
+ 
+diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
+--- a/drivers/usb/Makefile
++++ b/drivers/usb/Makefile
+@@ -8,6 +8,7 @@ obj-$(CONFIG_USB)		+= core/
+ 
+ obj-$(CONFIG_USB_MON)		+= mon/
+ 
++obj-$(CONFIG_PCI)		+= host/
+ obj-$(CONFIG_USB_EHCI_HCD)	+= host/
+ obj-$(CONFIG_USB_ISP116X_HCD)	+= host/
+ obj-$(CONFIG_USB_OHCI_HCD)	+= host/
+@@ -17,7 +18,6 @@ obj-$(CONFIG_ETRAX_USB_HOST)	+= host/
+ 
+ obj-$(CONFIG_USB_ACM)		+= class/
+ obj-$(CONFIG_USB_AUDIO)		+= class/
+-obj-$(CONFIG_USB_BLUETOOTH_TTY)	+= class/
+ obj-$(CONFIG_USB_MIDI)		+= class/
+ obj-$(CONFIG_USB_PRINTER)	+= class/
+ 
+diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
+--- a/drivers/usb/class/Kconfig
++++ b/drivers/usb/class/Kconfig
+@@ -28,29 +28,6 @@ config USB_AUDIO
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called audio.
+ 
+-comment "USB Bluetooth TTY can only be used with disabled Bluetooth subsystem"
+-	depends on USB && BT
+-
+-config USB_BLUETOOTH_TTY
+-	tristate "USB Bluetooth TTY support"
+-	depends on USB && BT=n
+-	---help---
+-	  This driver implements a nonstandard tty interface to a Bluetooth
+-	  device that can be used only by specialized Bluetooth HCI software.
+-
+-	  Say Y here if you want to use OpenBT Bluetooth stack (available
+-	  at <http://developer.axis.com/software>), or other TTY based
+-	  Bluetooth stacks, and want to connect a USB Bluetooth device
+-	  to your computer's USB port.
+-
+-	  Do *not* enable this driver if you want to use generic Linux
+-	  Bluetooth support.
+-
+-	  If in doubt, say N here.
+-
+-	  To compile this driver as a module, choose M here: the
+-	  module will be called bluetty.
+-
+ config USB_MIDI
+ 	tristate "USB MIDI support"
+ 	depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
+diff --git a/drivers/usb/class/Makefile b/drivers/usb/class/Makefile
+--- a/drivers/usb/class/Makefile
++++ b/drivers/usb/class/Makefile
+@@ -5,6 +5,5 @@
+ 
+ obj-$(CONFIG_USB_ACM)		+= cdc-acm.o
+ obj-$(CONFIG_USB_AUDIO)		+= audio.o
+-obj-$(CONFIG_USB_BLUETOOTH_TTY)	+= bluetty.o
+ obj-$(CONFIG_USB_MIDI)		+= usb-midi.o
+ obj-$(CONFIG_USB_PRINTER)	+= usblp.o
+diff --git a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c
+deleted file mode 100644
+--- a/drivers/usb/class/bluetty.c
++++ /dev/null
+@@ -1,1279 +0,0 @@
+-/*
+- * bluetty.c   Version 0.13
+- *
+- * Copyright (C) 2000, 2001 Greg Kroah-Hartman	<greg at kroah.com>
+- * Copyright (C) 2000 Mark Douglas Corner	<mcorner at umich.edu>
+- *
+- * USB Bluetooth TTY driver, based on the Bluetooth Spec version 1.0B
+- * 
+- * (2001/11/30) Version 0.13 gkh
+- *	- added locking patch from Masoodur Rahman <rmasoodu at in.ibm.com>
+- *	- removed active variable, as open_count will do.
+- *
+- * (2001/07/09) Version 0.12 gkh
+- *	- removed in_interrupt() call, as it doesn't make sense to do 
+- *	  that anymore.
+- *
+- * (2001/06/05) Version 0.11 gkh
+- *	- Fixed problem with read urb status saying that we have shutdown,
+- *	  and that we shouldn't resubmit the urb.  Patch from unknown.
+- *
+- * (2001/05/28) Version 0.10 gkh
+- *	- Fixed problem with using data from userspace in the bluetooth_write
+- *	  function as found by the CHECKER project.
+- *	- Added a buffer to the write_urb_pool which reduces the number of
+- *	  buffers being created and destroyed for ever write.  Also cleans
+- *	  up the logic a bit.
+- *	- Added a buffer to the control_urb_pool which fixes a memory leak
+- *	  when the device is removed from the system.
+- *
+- * (2001/05/28) Version 0.9 gkh
+- *	Fixed problem with bluetooth==NULL for bluetooth_read_bulk_callback
+- *	which was found by both the CHECKER project and Mikko Rahkonen.
+- *
+- * (08/04/2001) gb
+- *	Identify version on module load.
+- *
+- * (2001/03/10) Version 0.8 gkh
+- *	Fixed problem with not unlinking interrupt urb on device close
+- *	and resubmitting the read urb on error with bluetooth struct.
+- *	Thanks to Narayan Mohanram <narayan at RovingNetworks.com> for the
+- *	fixes.
+- *
+- * (11/29/2000) Version 0.7 gkh
+- *	Fixed problem with overrunning the tty flip buffer.
+- *	Removed unneeded NULL pointer initialization.
+- *
+- * (10/05/2000) Version 0.6 gkh
+- *	Fixed bug with urb->dev not being set properly, now that the usb
+- *	core needs it.
+- *	Got a real major id number and name.
+- *
+- * (08/06/2000) Version 0.5 gkh
+- *	Fixed problem of not resubmitting the bulk read urb if there is
+- *	an error in the callback.  Ericsson devices seem to need this.
+- *
+- * (07/11/2000) Version 0.4 gkh
+- *	Fixed bug in disconnect for when we call tty_hangup
+- *	Fixed bug in bluetooth_ctrl_msg where the bluetooth struct was not
+- *	getting attached to the control urb properly.
+- *	Fixed bug in bluetooth_write where we pay attention to the result
+- *	of bluetooth_ctrl_msg.
+- *
+- * (08/03/2000) Version 0.3 gkh mdc
+- *	Merged in Mark's changes to make the driver play nice with the Axis
+- *	stack.
+- *	Made the write bulk use an urb pool to enable larger transfers with
+- *	fewer calls to the driver.
+- *	Fixed off by one bug in acl pkt receive
+- *	Made packet counters specific to each bluetooth device 
+- *	Added checks for zero length callbacks
+- *	Added buffers for int and bulk packets.  Had to do this otherwise 
+- *	packet types could intermingle.
+- *	Made a control urb pool for the control messages.
+- *
+- * (07/11/2000) Version 0.2 gkh
+- *	Fixed a small bug found by Nils Faerber in the usb_bluetooth_probe 
+- *	function.
+- *
+- * (07/09/2000) Version 0.1 gkh
+- *	Initial release. Has support for sending ACL data (which is really just
+- *	a HCI frame.) Raw HCI commands and HCI events are not supported.
+- *	A ioctl will probably be needed for the HCI commands and events in the
+- *	future. All isoch endpoints are ignored at this time also.
+- *	This driver should work for all currently shipping USB Bluetooth 
+- *	devices at this time :)
+- * 
+- */
+-
+-/*
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the 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/errno.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <linux/tty.h>
+-#include <linux/tty_driver.h>
+-#include <linux/tty_flip.h>
+-#include <linux/module.h>
+-#include <asm/uaccess.h>
+-
+-#define DEBUG
+-#include <linux/usb.h>
+-
+-/*
+- * Version Information
+- */
+-#define DRIVER_VERSION "v0.13"
+-#define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner"
+-#define DRIVER_DESC "USB Bluetooth tty driver"
+-
+-/* define this if you have hardware that is not good */
+-/*#define	BTBUGGYHARDWARE */
+-
+-/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
+-#define WIRELESS_CLASS_CODE			0xe0
+-#define RF_SUBCLASS_CODE			0x01
+-#define BLUETOOTH_PROGRAMMING_PROTOCOL_CODE	0x01
+-
+-
+-#define BLUETOOTH_TTY_MAJOR	216	/* real device node major id */
+-#define BLUETOOTH_TTY_MINORS	256	/* whole lotta bluetooth devices */
+-
+-#define USB_BLUETOOTH_MAGIC	0x6d02	/* magic number for bluetooth struct */
+-
+-#define BLUETOOTH_CONTROL_REQUEST_TYPE	0x20
+-
+-/* Bluetooth packet types */
+-#define CMD_PKT			0x01
+-#define ACL_PKT			0x02
+-#define SCO_PKT			0x03
+-#define EVENT_PKT		0x04
+-#define ERROR_PKT		0x05
+-#define NEG_PKT			0x06
+-
+-/* Message sizes */
+-#define MAX_EVENT_SIZE		0xFF
+-#define EVENT_HDR_SIZE		3	/* 2 for the header + 1 for the type indicator */
+-#define EVENT_BUFFER_SIZE	(MAX_EVENT_SIZE + EVENT_HDR_SIZE)
+-
+-#define MAX_ACL_SIZE		0xFFFF
+-#define ACL_HDR_SIZE		5	/* 4 for the header + 1 for the type indicator */
+-#define ACL_BUFFER_SIZE		(MAX_ACL_SIZE + ACL_HDR_SIZE)
+-
+-/* parity check flag */
+-#define RELEVANT_IFLAG(iflag)	(iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+-
+-#define CHAR2INT16(c1,c0)	(((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff))
+-
+-#define NUM_BULK_URBS		24
+-#define NUM_CONTROL_URBS	16
+-
+-struct usb_bluetooth {
+-	int			magic;
+-	struct usb_device *	dev;
+-	struct tty_driver *	tty_driver;	/* the tty_driver for this device */
+-	struct tty_struct *	tty;		/* the corresponding tty for this port */
+-
+-	unsigned char		minor;		/* the starting minor number for this device */
+-	int			throttle;	/* throttled by tty layer */
+-	int			open_count;
+-	
+-	__u8			control_out_bInterfaceNum;
+-	struct urb *		control_urb_pool[NUM_CONTROL_URBS];
+-	struct usb_ctrlrequest	dr[NUM_CONTROL_URBS];
+-
+-	unsigned char *		interrupt_in_buffer;
+-	struct urb *		interrupt_in_urb;
+-	__u8			interrupt_in_endpointAddress;
+-	__u8			interrupt_in_interval;
+-	int			interrupt_in_buffer_size;
+-
+-	unsigned char *		bulk_in_buffer;
+-	struct urb *		read_urb;
+-	__u8			bulk_in_endpointAddress;
+-	int			bulk_in_buffer_size;
+-
+-	int			bulk_out_buffer_size;
+-	__u8			bulk_out_endpointAddress;
+-
+-	wait_queue_head_t	write_wait;
+-
+-	struct work_struct			work;	/* work queue entry for line discipline waking up */
+-	
+-	unsigned int		int_packet_pos;
+-	unsigned char		int_buffer[EVENT_BUFFER_SIZE];
+-	unsigned int		bulk_packet_pos;
+-	unsigned char		bulk_buffer[ACL_BUFFER_SIZE];	/* 64k preallocated, fix? */
+-	struct semaphore	lock;
+-};
+-
+-
+-/* local function prototypes */
+-static int  bluetooth_open		(struct tty_struct *tty, struct file *filp);
+-static void bluetooth_close		(struct tty_struct *tty, struct file *filp);
+-static int  bluetooth_write		(struct tty_struct *tty, const unsigned char *buf, int count);
+-static int  bluetooth_write_room	(struct tty_struct *tty);
+-static int  bluetooth_chars_in_buffer	(struct tty_struct *tty);
+-static void bluetooth_throttle		(struct tty_struct *tty);
+-static void bluetooth_unthrottle	(struct tty_struct *tty);
+-static int  bluetooth_ioctl		(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
+-static void bluetooth_set_termios	(struct tty_struct *tty, struct termios *old);
+-
+-static void bluetooth_int_callback		(struct urb *urb, struct pt_regs *regs);
+-static void bluetooth_ctrl_callback		(struct urb *urb, struct pt_regs *regs);
+-static void bluetooth_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);
+-static void bluetooth_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);
+-
+-static int usb_bluetooth_probe (struct usb_interface *intf, 
+-				const struct usb_device_id *id);
+-static void usb_bluetooth_disconnect	(struct usb_interface *intf);
+-
+-
+-static struct usb_device_id usb_bluetooth_ids [] = {
+-	{ USB_DEVICE_INFO(WIRELESS_CLASS_CODE, RF_SUBCLASS_CODE, BLUETOOTH_PROGRAMMING_PROTOCOL_CODE) },
+-	{ }						/* Terminating entry */
+-};
+-
+-MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
+-
+-static struct usb_driver usb_bluetooth_driver = {
+-	.owner =	THIS_MODULE,
+-	.name =		"bluetty",
+-	.probe =	usb_bluetooth_probe,
+-	.disconnect =	usb_bluetooth_disconnect,
+-	.id_table =	usb_bluetooth_ids,
+-};
+-
+-static struct tty_driver	*bluetooth_tty_driver;
+-static struct usb_bluetooth	*bluetooth_table[BLUETOOTH_TTY_MINORS];
+-
+-
+-static inline int bluetooth_paranoia_check (struct usb_bluetooth *bluetooth, const char *function)
+-{
+-	if (!bluetooth) {
+-		dbg("%s - bluetooth == NULL", function);
+-		return -1;
+-	}
+-	if (bluetooth->magic != USB_BLUETOOTH_MAGIC) {
+-		dbg("%s - bad magic number for bluetooth", function);
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-
+-static inline struct usb_bluetooth* get_usb_bluetooth (struct usb_bluetooth *bluetooth, const char *function)
+-{
+-	if (!bluetooth || 
+-	    bluetooth_paranoia_check (bluetooth, function)) { 
+-		/* then say that we don't have a valid usb_bluetooth thing, which will
+-		 * end up generating -ENODEV return values */
+-		return NULL;
+-	}
+-
+-	return bluetooth;
+-}
+-
+-
+-static inline struct usb_bluetooth *get_bluetooth_by_index (int index)
+-{
+-	return bluetooth_table[index];
+-}
+-
+-
+-static int bluetooth_ctrl_msg (struct usb_bluetooth *bluetooth, int request, int value, const unsigned char *buf, int len)
+-{
+-	struct urb *urb = NULL;
+-	struct usb_ctrlrequest *dr = NULL;
+-	int i;
+-	int status;
+-
+-	dbg ("%s", __FUNCTION__);
+-
+-	/* try to find a free urb in our list */
+-	for (i = 0; i < NUM_CONTROL_URBS; ++i) {
+-		if (bluetooth->control_urb_pool[i]->status != -EINPROGRESS) {
+-			urb = bluetooth->control_urb_pool[i];
+-			dr = &bluetooth->dr[i];
+-			break;
+-		}
+-	}
+-	if (urb == NULL) {
+-		dbg ("%s - no free urbs", __FUNCTION__);
+-		return -ENOMEM;
+-	}
+-
+-	/* keep increasing the urb transfer buffer to fit the size of the message */
+-	if (urb->transfer_buffer == NULL) {
+-		urb->transfer_buffer = kmalloc (len, GFP_KERNEL);
+-		if (urb->transfer_buffer == NULL) {
+-			err ("%s - out of memory", __FUNCTION__);
+-			return -ENOMEM;
+-		}
+-	}
+-	if (urb->transfer_buffer_length < len) {
+-		kfree(urb->transfer_buffer);
+-		urb->transfer_buffer = kmalloc (len, GFP_KERNEL);
+-		if (urb->transfer_buffer == NULL) {
+-			err ("%s - out of memory", __FUNCTION__);
+-			return -ENOMEM;
+-		}
+-	}
+-	memcpy (urb->transfer_buffer, buf, len);
+-
+-	dr->bRequestType= BLUETOOTH_CONTROL_REQUEST_TYPE;
+-	dr->bRequest = request;
+-	dr->wValue = cpu_to_le16((u16) value);
+-	dr->wIndex = cpu_to_le16((u16) bluetooth->control_out_bInterfaceNum);
+-	dr->wLength = cpu_to_le16((u16) len);
+-	
+-	usb_fill_control_urb (urb, bluetooth->dev, usb_sndctrlpipe(bluetooth->dev, 0),
+-			  (unsigned char*)dr, urb->transfer_buffer, len, bluetooth_ctrl_callback, bluetooth);
+-
+-	/* send it down the pipe */
+-	status = usb_submit_urb(urb, GFP_KERNEL);
+-	if (status)
+-		dbg("%s - usb_submit_urb(control) failed with status = %d", __FUNCTION__, status);
+-	
+-	return status;
+-}
+-
+-
+-
+-
+-
+-/*****************************************************************************
+- * Driver tty interface functions
+- *****************************************************************************/
+-static int bluetooth_open (struct tty_struct *tty, struct file * filp)
+-{
+-	struct usb_bluetooth *bluetooth;
+-	int result;
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	/* initialize the pointer incase something fails */
+-	tty->driver_data = NULL;
+-
+-	/* get the bluetooth object associated with this tty pointer */
+-	bluetooth = get_bluetooth_by_index (tty->index);
+-
+-	if (bluetooth_paranoia_check (bluetooth, __FUNCTION__)) {
+-		return -ENODEV;
+-	}
+-
+-	down (&bluetooth->lock);
+- 
+-	++bluetooth->open_count;
+-	if (bluetooth->open_count == 1) {
+-		/* set up our structure making the tty driver remember our object, and us it */
+-		tty->driver_data = bluetooth;
+-		bluetooth->tty = tty;
+-
+-		/* force low_latency on so that our tty_push actually forces the data through, 
+-	 	* otherwise it is scheduled, and with high data rates (like with OHCI) data
+-	 	* can get lost. */
+-		bluetooth->tty->low_latency = 1;
+-	
+-		/* Reset the packet position counters */
+-		bluetooth->int_packet_pos = 0;
+-		bluetooth->bulk_packet_pos = 0;
+-
+-#ifndef BTBUGGYHARDWARE
+-		/* Start reading from the device */
+-		usb_fill_bulk_urb (bluetooth->read_urb, bluetooth->dev, 
+-			       usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
+-			       bluetooth->bulk_in_buffer,
+-			       bluetooth->bulk_in_buffer_size,
+-			       bluetooth_read_bulk_callback, bluetooth);
+-		result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
+-		if (result)
+-			dbg("%s - usb_submit_urb(read bulk) failed with status %d", __FUNCTION__, result);
+-#endif
+-		usb_fill_int_urb (bluetooth->interrupt_in_urb, bluetooth->dev,
+-			      usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress),
+-			      bluetooth->interrupt_in_buffer,
+-			      bluetooth->interrupt_in_buffer_size,
+-			      bluetooth_int_callback, bluetooth,
+-			      bluetooth->interrupt_in_interval);
+-		result = usb_submit_urb(bluetooth->interrupt_in_urb, GFP_KERNEL);
+-		if (result)
+-			dbg("%s - usb_submit_urb(interrupt in) failed with status %d", __FUNCTION__, result);
+-	}
+-	
+-	up(&bluetooth->lock);
+-
+-	return 0;
+-}
+-
+-
+-static void bluetooth_close (struct tty_struct *tty, struct file * filp)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+-
+-	if (!bluetooth) {
+-		return;
+-	}
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth->open_count) {
+-		dbg ("%s - device not opened", __FUNCTION__);
+-		return;
+-	}
+-
+-	down (&bluetooth->lock);
+- 
+-	--bluetooth->open_count;
+-	if (bluetooth->open_count <= 0) {
+-		bluetooth->open_count = 0;
+-
+-		/* shutdown any in-flight urbs that we know about */
+-		usb_kill_urb (bluetooth->read_urb);
+-		usb_kill_urb (bluetooth->interrupt_in_urb);
+-	}
+-	up(&bluetooth->lock);
+-}
+-
+-
+-static int bluetooth_write (struct tty_struct * tty, const unsigned char *buf, int count)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+-	struct urb *urb = NULL;
+-	unsigned char *temp_buffer = NULL;
+-	const unsigned char *current_buffer;
+-	unsigned char *urb_buffer;
+-	int i;
+-	int retval = 0;
+-
+-	if (!bluetooth) {
+-		return -ENODEV;
+-	}
+-
+-	dbg("%s - %d byte(s)", __FUNCTION__, count);
+-
+-	if (!bluetooth->open_count) {
+-		dbg ("%s - device not opened", __FUNCTION__);
+-		return -EINVAL;
+-	}
+-
+-	if (count == 0) {
+-		dbg("%s - write request of 0 bytes", __FUNCTION__);
+-		return 0;
+-	}
+-	if (count == 1) {
+-		dbg("%s - write request only included type %d", __FUNCTION__, buf[0]);
+-		return 1;
+-	}
+-
+-#ifdef DEBUG
+-	printk (KERN_DEBUG __FILE__ ": %s - length = %d, data = ", __FUNCTION__, count);
+-	for (i = 0; i < count; ++i) {
+-		printk ("%.2x ", buf[i]);
+-	}
+-	printk ("\n");
+-#endif
+-
+-	current_buffer = buf;
+-
+-	switch (*current_buffer) {
+-		/* First byte indicates the type of packet */
+-		case CMD_PKT:
+-			/* dbg("%s- Send cmd_pkt len:%d", __FUNCTION__, count);*/
+-
+-			retval = bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, &current_buffer[1], count-1);
+-			if (retval) {
+-				goto exit;
+-			}
+-			retval = count;
+-			break;
+-
+-		case ACL_PKT:
+-			++current_buffer;
+-			--count;
+-
+-			urb_buffer = kmalloc (count, GFP_ATOMIC);
+-			if (!urb_buffer) {
+-				dev_err(&bluetooth->dev->dev, "out of memory\n");
+-				retval = -ENOMEM;
+-				goto exit;
+-			}
+-
+-			urb = usb_alloc_urb(0, GFP_ATOMIC);
+-			if (!urb) {
+-				dev_err(&bluetooth->dev->dev, "no more free urbs\n");
+-				kfree(urb_buffer);
+-				retval = -ENOMEM;
+-				goto exit;
+-			}
+-			memcpy (urb_buffer, current_buffer, count);
+-
+-			/* build up our urb */
+-			usb_fill_bulk_urb(urb, bluetooth->dev, 
+-					  usb_sndbulkpipe(bluetooth->dev,
+-						  	  bluetooth->bulk_out_endpointAddress),
+-					  urb_buffer,
+-					  count,
+-					  bluetooth_write_bulk_callback,
+-					  bluetooth);
+-
+-
+-			/* send it down the pipe */
+-			retval = usb_submit_urb(urb, GFP_KERNEL);
+-			if (retval) {
+-				dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, retval);
+-				goto exit;
+-			}
+-
+-			/* we are done with this urb, so let the host driver
+-			 * really free it when it is finished with it */
+-			usb_free_urb (urb);
+-			retval = count + 1;
+-			break;
+-		
+-		default :
+-			dbg("%s - unsupported (at this time) write type", __FUNCTION__);
+-			retval = -EINVAL;
+-			break;
+-	}
+-
+-exit:
+-	kfree(temp_buffer);
+-
+-	return retval;
+-} 
+-
+-
+-static int bluetooth_write_room (struct tty_struct *tty) 
+-{
+-	dbg("%s", __FUNCTION__);
+-
+-	/*
+-	 * We really can take anything the user throws at us
+-	 * but let's pick a nice big number to tell the tty
+-	 * layer that we have lots of free space
+-	 */
+-	return 2048;
+-}
+-
+-
+-static int bluetooth_chars_in_buffer (struct tty_struct *tty) 
+-{
+-	dbg("%s", __FUNCTION__);
+-
+-	/* 
+-	 * We can't really account for how much data we
+-	 * have sent out, but hasn't made it through to the
+-	 * device, so just tell the tty layer that everything
+-	 * is flushed.
+-	 */
+-	return 0;
+-}
+-
+-
+-static void bluetooth_throttle (struct tty_struct * tty)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+-
+-	if (!bluetooth) {
+-		return;
+-	}
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth->open_count) {
+-		dbg ("%s - device not open", __FUNCTION__);
+-		return;
+-	}
+-	
+-	dbg("%s unsupported (at this time)", __FUNCTION__);
+-
+-	return;
+-}
+-
+-
+-static void bluetooth_unthrottle (struct tty_struct * tty)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+-
+-	if (!bluetooth) {
+-		return;
+-	}
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth->open_count) {
+-		dbg ("%s - device not open", __FUNCTION__);
+-		return;
+-	}
+-
+-	dbg("%s unsupported (at this time)", __FUNCTION__);
+-}
+-
+-
+-static int bluetooth_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+-
+-	if (!bluetooth) {
+-		return -ENODEV;
+-	}
+-
+-	dbg("%s - cmd 0x%.4x", __FUNCTION__, cmd);
+-
+-	if (!bluetooth->open_count) {
+-		dbg ("%s - device not open", __FUNCTION__);
+-		return -ENODEV;
+-	}
+-
+-	/* FIXME!!! */
+-	return -ENOIOCTLCMD;
+-}
+-
+-
+-static void bluetooth_set_termios (struct tty_struct *tty, struct termios * old)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+-
+-	if (!bluetooth) {
+-		return;
+-	}
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth->open_count) {
+-		dbg ("%s - device not open", __FUNCTION__);
+-		return;
+-	}
+-
+-	/* FIXME!!! */
+-
+-	return;
+-}
+-
+-
+-#ifdef BTBUGGYHARDWARE
+-void btusb_enable_bulk_read(struct tty_struct *tty){
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+-	int result;
+-
+-	if (!bluetooth) {
+-		return;
+-	}
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth->open_count) {
+-		dbg ("%s - device not open", __FUNCTION__);
+-		return;
+-	}
+-
+-	if (bluetooth->read_urb) {
+-		usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, 
+-			      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
+-			      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
+-			      bluetooth_read_bulk_callback, bluetooth);
+-		result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
+-		if (result)
+-			err ("%s - failed submitting read urb, error %d", __FUNCTION__, result);
+-	}
+-}
+-
+-void btusb_disable_bulk_read(struct tty_struct *tty){
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+-
+-	if (!bluetooth) {
+-		return;
+-	}
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth->open_count) {
+-		dbg ("%s - device not open", __FUNCTION__);
+-		return;
+-	}
+-
+-	if ((bluetooth->read_urb) && (bluetooth->read_urb->actual_length))
+-		usb_kill_urb(bluetooth->read_urb);
+-}
+-#endif
+-
+-
+-/*****************************************************************************
+- * urb callback functions
+- *****************************************************************************/
+-
+-
+-static void bluetooth_int_callback (struct urb *urb, struct pt_regs *regs)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
+-	unsigned char *data = urb->transfer_buffer;
+-	unsigned int i;
+-	unsigned int count = urb->actual_length;
+-	unsigned int packet_size;
+-	int status;
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth) {
+-		dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__);
+-		return;
+-	}
+-
+-	switch (urb->status) {
+-	case 0:
+-		/* success */
+-		break;
+-	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;
+-	}
+-
+-	if (!count) {
+-		dbg("%s - zero length int", __FUNCTION__);
+-		goto exit;
+-	}
+-
+-
+-#ifdef DEBUG
+-	if (count) {
+-		printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, count);
+-		for (i = 0; i < count; ++i) {
+-			printk ("%.2x ", data[i]);
+-		}
+-		printk ("\n");
+-	}
+-#endif
+-
+-#ifdef BTBUGGYHARDWARE
+-	if ((count >= 2) && (data[0] == 0xFF) && (data[1] == 0x00)) {
+-		data += 2;
+-		count -= 2;
+-	}
+-	if (count == 0) {
+-		urb->actual_length = 0;
+-		goto exit;
+-	}
+-#endif
+-	/* We add  a packet type identifier to the beginning of each
+-	   HCI frame.  This makes the data in the tty look like a
+-	   serial USB devices.  Each HCI frame can be broken across
+-	   multiple URBs so we buffer them until we have a full hci
+-	   packet */
+-
+-	if (!bluetooth->int_packet_pos) {
+-		bluetooth->int_buffer[0] = EVENT_PKT;
+-		bluetooth->int_packet_pos++;
+-	}
+-	
+-	if (bluetooth->int_packet_pos + count > EVENT_BUFFER_SIZE) {
+-		err("%s - exceeded EVENT_BUFFER_SIZE", __FUNCTION__);
+-		bluetooth->int_packet_pos = 0;
+-		goto exit;
+-	}
+-
+-	memcpy (&bluetooth->int_buffer[bluetooth->int_packet_pos],
+-		urb->transfer_buffer, count);
+-	bluetooth->int_packet_pos += count;
+-	urb->actual_length = 0;
+-
+-	if (bluetooth->int_packet_pos >= EVENT_HDR_SIZE)
+-		packet_size = bluetooth->int_buffer[2];
+-	else
+-		goto exit;
+-
+-	if (packet_size + EVENT_HDR_SIZE < bluetooth->int_packet_pos) {
+-		err("%s - packet was too long", __FUNCTION__);
+-		bluetooth->int_packet_pos = 0;
+-		goto exit;
+-	}
+-
+-	if (packet_size + EVENT_HDR_SIZE == bluetooth->int_packet_pos) {
+-		for (i = 0; i < bluetooth->int_packet_pos; ++i) {
+-			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them */
+-			if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) {
+-				tty_flip_buffer_push(bluetooth->tty);
+-			}
+-			tty_insert_flip_char(bluetooth->tty, bluetooth->int_buffer[i], 0);
+-		}
+-		tty_flip_buffer_push(bluetooth->tty);
+-
+-		bluetooth->int_packet_pos = 0;
+-	}
+-
+-exit:
+-	status = usb_submit_urb (urb, GFP_ATOMIC);
+-	if (status)
+-		err ("%s - usb_submit_urb failed with result %d",
+-		     __FUNCTION__, status);
+-}
+-
+-
+-static void bluetooth_ctrl_callback (struct urb *urb, struct pt_regs *regs)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth) {
+-		dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__);
+-		return;
+-	}
+-
+-	if (urb->status) {
+-		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+-		return;
+-	}
+-}
+-
+-
+-static void bluetooth_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
+-	unsigned char *data = urb->transfer_buffer;
+-	unsigned int count = urb->actual_length;
+-	unsigned int i;
+-	unsigned int packet_size;
+-	int result;
+-
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth) {
+-		dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__);
+-		return;
+-	}
+-
+-	if (urb->status) {
+-		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+-		if (urb->status == -ENOENT) {                   
+-			dbg("%s - URB canceled, won't reschedule", __FUNCTION__);
+-			return;
+-		}
+-		goto exit;
+-	}
+-
+-	if (!count) {
+-		dbg("%s - zero length read bulk", __FUNCTION__);
+-		goto exit;
+-	}
+-
+-#ifdef DEBUG
+-	if (count) {
+-		printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, count);
+-		for (i = 0; i < count; ++i) {
+-			printk ("%.2x ", data[i]);
+-		}
+-		printk ("\n");
+-	}
+-#endif
+-#ifdef BTBUGGYHARDWARE
+-	if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00)
+-	    && (data[2] == 0x00) && (data[3] == 0x00)) {
+-		urb->actual_length = 0;
+-		usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, 
+-			      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
+-			      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
+-			      bluetooth_read_bulk_callback, bluetooth);
+-		result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
+-		if (result)
+-			err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
+-
+-		return;
+-	}
+-#endif
+-	/* We add  a packet type identifier to the beginning of each
+-	   HCI frame.  This makes the data in the tty look like a
+-	   serial USB devices.  Each HCI frame can be broken across
+-	   multiple URBs so we buffer them until we have a full hci
+-	   packet */
+-	
+-	if (!bluetooth->bulk_packet_pos) {
+-		bluetooth->bulk_buffer[0] = ACL_PKT;
+-		bluetooth->bulk_packet_pos++;
+-	}
+-
+-	if (bluetooth->bulk_packet_pos + count > ACL_BUFFER_SIZE) {
+-		err("%s - exceeded ACL_BUFFER_SIZE", __FUNCTION__);
+-		bluetooth->bulk_packet_pos = 0;
+-		goto exit;
+-	}
+-
+-	memcpy (&bluetooth->bulk_buffer[bluetooth->bulk_packet_pos],
+-		urb->transfer_buffer, count);
+-	bluetooth->bulk_packet_pos += count;
+-	urb->actual_length = 0;
+-
+-	if (bluetooth->bulk_packet_pos >= ACL_HDR_SIZE) {
+-		packet_size = CHAR2INT16(bluetooth->bulk_buffer[4],bluetooth->bulk_buffer[3]);
+-	} else {
+-		goto exit;
+-	}
+-
+-	if (packet_size + ACL_HDR_SIZE < bluetooth->bulk_packet_pos) {
+-		err("%s - packet was too long", __FUNCTION__);
+-		bluetooth->bulk_packet_pos = 0;
+-		goto exit;
+-	}
+-
+-	if (packet_size + ACL_HDR_SIZE == bluetooth->bulk_packet_pos) {
+-		for (i = 0; i < bluetooth->bulk_packet_pos; ++i) {
+-			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+-			if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) {
+-				tty_flip_buffer_push(bluetooth->tty);
+-			}
+-			tty_insert_flip_char(bluetooth->tty, bluetooth->bulk_buffer[i], 0);
+-		}
+-		tty_flip_buffer_push(bluetooth->tty);
+-		bluetooth->bulk_packet_pos = 0;
+-	}	
+-
+-exit:
+-	if (!bluetooth || !bluetooth->open_count)
+-		return;
+-
+-	usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, 
+-		      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
+-		      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
+-		      bluetooth_read_bulk_callback, bluetooth);
+-	result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
+-	if (result)
+-		err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
+-
+-	return;
+-}
+-
+-
+-static void bluetooth_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	/* free up the transfer buffer, as usb_free_urb() does not do this */
+-	kfree(urb->transfer_buffer);
+-
+-	if (!bluetooth) {
+-		dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__);
+-		return;
+-	}
+-
+-	if (urb->status) {
+-		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+-		return;
+-	}
+-
+-	/* wake up our little function to let the tty layer know that something happened */
+-	schedule_work(&bluetooth->work);
+-}
+-
+-
+-static void bluetooth_softint(void *private)
+-{
+-	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)private, __FUNCTION__);
+-
+-	dbg("%s", __FUNCTION__);
+-
+-	if (!bluetooth)
+-		return;
+-
+-	tty_wakeup(bluetooth->tty);
+-}
+-
+-
+-static int usb_bluetooth_probe (struct usb_interface *intf, 
+-				const struct usb_device_id *id)
+-{
+-	struct usb_device *dev = interface_to_usbdev (intf);
+-	struct usb_bluetooth *bluetooth = NULL;
+-	struct usb_host_interface *interface;
+-	struct usb_endpoint_descriptor *endpoint;
+-	struct usb_endpoint_descriptor *interrupt_in_endpoint[8];
+-	struct usb_endpoint_descriptor *bulk_in_endpoint[8];
+-	struct usb_endpoint_descriptor *bulk_out_endpoint[8];
+-	int control_out_endpoint;
+-
+-	int minor;
+-	int buffer_size;
+-	int i;
+-	int num_interrupt_in = 0;
+-	int num_bulk_in = 0;
+-	int num_bulk_out = 0;
+-
+-	interface = intf->cur_altsetting;
+-	control_out_endpoint = interface->desc.bInterfaceNumber;
+-
+-	/* find the endpoints that we need */
+-	for (i = 0; i < interface->desc.bNumEndpoints; ++i) {
+-		endpoint = &interface->endpoint[i].desc;
+-
+-		if ((endpoint->bEndpointAddress & 0x80) &&
+-		    ((endpoint->bmAttributes & 3) == 0x02)) {
+-			/* we found a bulk in endpoint */
+-			dbg("found bulk in");
+-			bulk_in_endpoint[num_bulk_in] = endpoint;
+-			++num_bulk_in;
+-		}
+-
+-		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
+-		    ((endpoint->bmAttributes & 3) == 0x02)) {
+-			/* we found a bulk out endpoint */
+-			dbg("found bulk out");
+-			bulk_out_endpoint[num_bulk_out] = endpoint;
+-			++num_bulk_out;
+-		}
+-
+-		if ((endpoint->bEndpointAddress & 0x80) &&
+-		    ((endpoint->bmAttributes & 3) == 0x03)) {
+-			/* we found a interrupt in endpoint */
+-			dbg("found interrupt in");
+-			interrupt_in_endpoint[num_interrupt_in] = endpoint;
+-			++num_interrupt_in;
+-		}
+-	}
+-
+-	/* according to the spec, we can only have 1 bulk_in, 1 bulk_out, and 1 interrupt_in endpoints */
+-	if ((num_bulk_in != 1) ||
+-	    (num_bulk_out != 1) ||
+-	    (num_interrupt_in != 1)) {
+-		dbg ("%s - improper number of endpoints. Bluetooth driver not bound.", __FUNCTION__);
+-		return -EIO;
+-	}
+-
+-	info("USB Bluetooth converter detected");
+-
+-	for (minor = 0; minor < BLUETOOTH_TTY_MINORS && bluetooth_table[minor]; ++minor)
+-		;
+-	if (bluetooth_table[minor]) {
+-		err("No more free Bluetooth devices");
+-		return -ENODEV;
+-	}
+-
+-	if (!(bluetooth = kmalloc(sizeof(struct usb_bluetooth), GFP_KERNEL))) {
+-		err("Out of memory");
+-		return -ENOMEM;
+-	}
+-
+-	memset(bluetooth, 0, sizeof(struct usb_bluetooth));
+-
+-	bluetooth->magic = USB_BLUETOOTH_MAGIC;
+-	bluetooth->dev = dev;
+-	bluetooth->minor = minor;
+-	INIT_WORK(&bluetooth->work, bluetooth_softint, bluetooth);
+-	init_MUTEX(&bluetooth->lock);
+-
+-	/* record the interface number for the control out */
+-	bluetooth->control_out_bInterfaceNum = control_out_endpoint;
+-	
+-	/* create our control out urb pool */ 
+-	for (i = 0; i < NUM_CONTROL_URBS; ++i) {
+-		struct urb  *urb = usb_alloc_urb(0, GFP_KERNEL);
+-		if (urb == NULL) {
+-			err("No free urbs available");
+-			goto probe_error;
+-		}
+-		urb->transfer_buffer = NULL;
+-		bluetooth->control_urb_pool[i] = urb;
+-	}
+-
+-	/* set up the endpoint information */
+-	endpoint = bulk_in_endpoint[0];
+-	bluetooth->read_urb = usb_alloc_urb (0, GFP_KERNEL);
+-	if (!bluetooth->read_urb) {
+-		err("No free urbs available");
+-		goto probe_error;
+-	}
+-	bluetooth->bulk_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+-	bluetooth->bulk_in_endpointAddress = endpoint->bEndpointAddress;
+-	bluetooth->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+-	if (!bluetooth->bulk_in_buffer) {
+-		err("Couldn't allocate bulk_in_buffer");
+-		goto probe_error;
+-	}
+-	usb_fill_bulk_urb(bluetooth->read_urb, dev, usb_rcvbulkpipe(dev, endpoint->bEndpointAddress),
+-		      bluetooth->bulk_in_buffer, buffer_size, bluetooth_read_bulk_callback, bluetooth);
+-
+-	endpoint = bulk_out_endpoint[0];
+-	bluetooth->bulk_out_endpointAddress = endpoint->bEndpointAddress;
+-	bluetooth->bulk_out_buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2;
+-
+-	endpoint = interrupt_in_endpoint[0];
+-	bluetooth->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+-	if (!bluetooth->interrupt_in_urb) {
+-		err("No free urbs available");
+-		goto probe_error;
+-	}
+-	bluetooth->interrupt_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+-	bluetooth->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
+-	bluetooth->interrupt_in_interval = endpoint->bInterval;
+-	bluetooth->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+-	if (!bluetooth->interrupt_in_buffer) {
+-		err("Couldn't allocate interrupt_in_buffer");
+-		goto probe_error;
+-	}
+-	usb_fill_int_urb(bluetooth->interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
+-		     bluetooth->interrupt_in_buffer, buffer_size, bluetooth_int_callback,
+-		     bluetooth, endpoint->bInterval);
+-
+-	/* initialize the devfs nodes for this device and let the user know what bluetooths we are bound to */
+-	tty_register_device (bluetooth_tty_driver, minor, &intf->dev);
+-	info("Bluetooth converter now attached to ttyUB%d (or usb/ttub/%d for devfs)", minor, minor);
+-
+-	bluetooth_table[minor] = bluetooth;
+-
+-	/* success */
+-	usb_set_intfdata (intf, bluetooth);
+-	return 0;
+-
+-probe_error:
+-	if (bluetooth->read_urb)
+-		usb_free_urb (bluetooth->read_urb);
+-	if (bluetooth->bulk_in_buffer)
+-		kfree (bluetooth->bulk_in_buffer);
+-	if (bluetooth->interrupt_in_urb)
+-		usb_free_urb (bluetooth->interrupt_in_urb);
+-	if (bluetooth->interrupt_in_buffer)
+-		kfree (bluetooth->interrupt_in_buffer);
+-	for (i = 0; i < NUM_CONTROL_URBS; ++i) 
+-		if (bluetooth->control_urb_pool[i]) {
+-			if (bluetooth->control_urb_pool[i]->transfer_buffer)
+-				kfree (bluetooth->control_urb_pool[i]->transfer_buffer);
+-			usb_free_urb (bluetooth->control_urb_pool[i]);
+-		}
+-
+-	bluetooth_table[minor] = NULL;
+-
+-	/* free up any memory that we allocated */
+-	kfree (bluetooth);
+-	return -EIO;
+-}
+-
+-
+-static void usb_bluetooth_disconnect(struct usb_interface *intf)
+-{
+-	struct usb_bluetooth *bluetooth = usb_get_intfdata (intf);
+-	int i;
+-
+-	usb_set_intfdata (intf, NULL);
+-	if (bluetooth) {
+-		if ((bluetooth->open_count) && (bluetooth->tty))
+-			tty_hangup(bluetooth->tty);
+-
+-		bluetooth->open_count = 0;
+-
+-		if (bluetooth->read_urb) {
+-			usb_kill_urb (bluetooth->read_urb);
+-			usb_free_urb (bluetooth->read_urb);
+-		}
+-		if (bluetooth->bulk_in_buffer)
+-			kfree (bluetooth->bulk_in_buffer);
+-
+-		if (bluetooth->interrupt_in_urb) {
+-			usb_kill_urb (bluetooth->interrupt_in_urb);
+-			usb_free_urb (bluetooth->interrupt_in_urb);
+-		}
+-		if (bluetooth->interrupt_in_buffer)
+-			kfree (bluetooth->interrupt_in_buffer);
+-
+-		tty_unregister_device (bluetooth_tty_driver, bluetooth->minor);
+-
+-		for (i = 0; i < NUM_CONTROL_URBS; ++i) {
+-			if (bluetooth->control_urb_pool[i]) {
+-				usb_kill_urb (bluetooth->control_urb_pool[i]);
+-				if (bluetooth->control_urb_pool[i]->transfer_buffer)
+-					kfree (bluetooth->control_urb_pool[i]->transfer_buffer);
+-				usb_free_urb (bluetooth->control_urb_pool[i]);
+-			}
+-		}
+-		
+-		info("Bluetooth converter now disconnected from ttyUB%d", bluetooth->minor);
+-
+-		bluetooth_table[bluetooth->minor] = NULL;
+-
+-		/* free up any memory that we allocated */
+-		kfree (bluetooth);
+-	} else {
+-		info("device disconnected");
+-	}
+-}
+-
+-static struct tty_operations bluetooth_ops = {
+-	.open =			bluetooth_open,
+-	.close =		bluetooth_close,
+-	.write =		bluetooth_write,
+-	.write_room =		bluetooth_write_room,
+-	.ioctl =		bluetooth_ioctl,
+-	.set_termios =		bluetooth_set_termios,
+-	.throttle =		bluetooth_throttle,
+-	.unthrottle =		bluetooth_unthrottle,
+-	.chars_in_buffer =	bluetooth_chars_in_buffer,
+-};
+-
+-static int usb_bluetooth_init(void)
+-{
+-	int i;
+-	int result;
+-
+-	/* Initialize our global data */
+-	for (i = 0; i < BLUETOOTH_TTY_MINORS; ++i) {
+-		bluetooth_table[i] = NULL;
+-	}
+-
+-	info ("USB Bluetooth support registered");
+-
+-	bluetooth_tty_driver = alloc_tty_driver(BLUETOOTH_TTY_MINORS);
+-	if (!bluetooth_tty_driver)
+-		return -ENOMEM;
+-
+-	bluetooth_tty_driver->owner = THIS_MODULE;
+-	bluetooth_tty_driver->driver_name = "usb-bluetooth";
+-	bluetooth_tty_driver->name = "ttyUB";
+-	bluetooth_tty_driver->devfs_name = "usb/ttub/";
+-	bluetooth_tty_driver->major = BLUETOOTH_TTY_MAJOR;
+-	bluetooth_tty_driver->minor_start = 0;
+-	bluetooth_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+-	bluetooth_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+-	bluetooth_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+-	bluetooth_tty_driver->init_termios = tty_std_termios;
+-	bluetooth_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+-	tty_set_operations(bluetooth_tty_driver, &bluetooth_ops);
+-	if (tty_register_driver (bluetooth_tty_driver)) {
+-		err("%s - failed to register tty driver", __FUNCTION__);
+-		put_tty_driver(bluetooth_tty_driver);
+-		return -1;
+-	}
+-
+-	/* register the USB driver */
+-	result = usb_register(&usb_bluetooth_driver);
+-	if (result < 0) {
+-		tty_unregister_driver(bluetooth_tty_driver);
+-		put_tty_driver(bluetooth_tty_driver);
+-		err("usb_register failed for the USB bluetooth driver. Error number %d", result);
+-		return -1;
+-	}
+-
+-	info(DRIVER_DESC " " DRIVER_VERSION);
+-
+-	return 0;
+-}
+-
+-
+-static void usb_bluetooth_exit(void)
+-{
+-	usb_deregister(&usb_bluetooth_driver);
+-	tty_unregister_driver(bluetooth_tty_driver);
+-	put_tty_driver(bluetooth_tty_driver);
+-}
+-
+-
+-module_init(usb_bluetooth_init);
+-module_exit(usb_bluetooth_exit);
+-
+-/* Module information */
+-MODULE_AUTHOR( DRIVER_AUTHOR );
+-MODULE_DESCRIPTION( DRIVER_DESC );
+-MODULE_LICENSE("GPL");
+-
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -827,11 +827,10 @@ skip_normal_probe:
+ 		return -ENODEV;
+ 	}
+ 
+-	if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
+-		dev_dbg(&intf->dev, "out of memory (acm kmalloc)\n");
++	if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) {
++		dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n");
+ 		goto alloc_fail;
+ 	}
+-	memset(acm, 0, sizeof(struct acm));
+ 
+ 	ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
+ 	readsize = le16_to_cpu(epread->wMaxPacketSize);
+diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
+--- a/drivers/usb/class/usblp.c
++++ b/drivers/usb/class/usblp.c
+@@ -844,9 +844,8 @@ static struct file_operations usblp_fops
+ };
+ 
+ static struct usb_class_driver usblp_class = {
+-	.name =		"usb/lp%d",
++	.name =		"lp%d",
+ 	.fops =		&usblp_fops,
+-	.mode =		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ 	.minor_base =	USBLP_MINOR_BASE,
+ };
+ 
+diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
+--- a/drivers/usb/core/Kconfig
++++ b/drivers/usb/core/Kconfig
+@@ -61,14 +61,17 @@ config USB_DYNAMIC_MINORS
+ 	  If you are unsure about this, say N here.
+ 
+ config USB_SUSPEND
+-	bool "USB suspend/resume (EXPERIMENTAL)"
++	bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)"
+ 	depends on USB && PM && EXPERIMENTAL
+ 	help
+ 	  If you say Y here, you can use driver calls or the sysfs
+ 	  "power/state" file to suspend or resume individual USB
+-	  peripherals.  There are many related features, such as
+-	  remote wakeup and driver-specific suspend processing, that
+-	  may not yet work as expected.
++	  peripherals.
++
++	  Also, USB "remote wakeup" signaling is supported, whereby some
++	  USB devices (like keyboards and network adapters) can wake up
++	  their parent hub.  That wakeup cascades up the USB tree, and
++	  could wake the system from states like suspend-to-RAM.
+ 
+ 	  If you are unsure about this, say N here.
+ 
+diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
+--- a/drivers/usb/core/Makefile
++++ b/drivers/usb/core/Makefile
+@@ -3,7 +3,7 @@
+ #
+ 
+ usbcore-objs	:= usb.o hub.o hcd.o urb.o message.o \
+-			config.o file.o buffer.o sysfs.o devio.o
++			config.o file.o buffer.o sysfs.o devio.o notify.o
+ 
+ ifeq ($(CONFIG_PCI),y)
+ 	usbcore-objs	+= hcd-pci.o
+diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
+--- a/drivers/usb/core/buffer.c
++++ b/drivers/usb/core/buffer.c
+@@ -106,7 +106,7 @@ void hcd_buffer_destroy (struct usb_hcd 
+ void *hcd_buffer_alloc (
+ 	struct usb_bus 		*bus,
+ 	size_t			size,
+-	unsigned		mem_flags,
++	gfp_t			mem_flags,
+ 	dma_addr_t		*dma
+ )
+ {
+diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -112,8 +112,12 @@ void usb_release_interface_cache(struct 
+ 	struct usb_interface_cache *intfc = ref_to_usb_interface_cache(ref);
+ 	int j;
+ 
+-	for (j = 0; j < intfc->num_altsetting; j++)
+-		kfree(intfc->altsetting[j].endpoint);
++	for (j = 0; j < intfc->num_altsetting; j++) {
++		struct usb_host_interface *alt = &intfc->altsetting[j];
++
++		kfree(alt->endpoint);
++		kfree(alt->string);
++	}
+ 	kfree(intfc);
+ }
+ 
+@@ -188,10 +192,9 @@ static int usb_parse_interface(struct de
+ 	}
+ 
+ 	len = sizeof(struct usb_host_endpoint) * num_ep;
+-	alt->endpoint = kmalloc(len, GFP_KERNEL);
++	alt->endpoint = kzalloc(len, GFP_KERNEL);
+ 	if (!alt->endpoint)
+ 		return -ENOMEM;
+-	memset(alt->endpoint, 0, len);
+ 
+ 	/* Parse all the endpoint descriptors */
+ 	n = 0;
+@@ -353,10 +356,9 @@ static int usb_parse_configuration(struc
+ 		}
+ 
+ 		len = sizeof(*intfc) + sizeof(struct usb_host_interface) * j;
+-		config->intf_cache[i] = intfc = kmalloc(len, GFP_KERNEL);
++		config->intf_cache[i] = intfc = kzalloc(len, GFP_KERNEL);
+ 		if (!intfc)
+ 			return -ENOMEM;
+-		memset(intfc, 0, len);
+ 		kref_init(&intfc->ref);
+ 	}
+ 
+@@ -422,8 +424,6 @@ void usb_destroy_configuration(struct us
+ 		struct usb_host_config *cf = &dev->config[c];
+ 
+ 		kfree(cf->string);
+-		cf->string = NULL;
+-
+ 		for (i = 0; i < cf->desc.bNumInterfaces; i++) {
+ 			if (cf->intf_cache[i])
+ 				kref_put(&cf->intf_cache[i]->ref, 
+@@ -459,16 +459,14 @@ int usb_get_configuration(struct usb_dev
+ 	}
+ 
+ 	length = ncfg * sizeof(struct usb_host_config);
+-	dev->config = kmalloc(length, GFP_KERNEL);
++	dev->config = kzalloc(length, GFP_KERNEL);
+ 	if (!dev->config)
+ 		goto err2;
+-	memset(dev->config, 0, length);
+ 
+ 	length = ncfg * sizeof(char *);
+-	dev->rawdescriptors = kmalloc(length, GFP_KERNEL);
++	dev->rawdescriptors = kzalloc(length, GFP_KERNEL);
+ 	if (!dev->rawdescriptors)
+ 		goto err2;
+-	memset(dev->rawdescriptors, 0, length);
+ 
+ 	buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
+ 	if (!buffer)
+diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -46,6 +46,7 @@
+ #include <linux/usb.h>
+ #include <linux/usbdevice_fs.h>
+ #include <linux/cdev.h>
++#include <linux/notifier.h>
+ #include <asm/uaccess.h>
+ #include <asm/byteorder.h>
+ #include <linux/moduleparam.h>
+@@ -209,10 +210,10 @@ err:
+ static struct async *alloc_async(unsigned int numisoframes)
+ {
+         unsigned int assize = sizeof(struct async) + numisoframes * sizeof(struct usb_iso_packet_descriptor);
+-        struct async *as = kmalloc(assize, GFP_KERNEL);
++        struct async *as = kzalloc(assize, GFP_KERNEL);
++
+         if (!as)
+                 return NULL;
+-        memset(as, 0, assize);
+ 	as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL);
+ 	if (!as->urb) {
+ 		kfree(as);
+@@ -279,6 +280,28 @@ static inline struct async *async_getpen
+         return NULL;
+ }
+ 
++static void snoop_urb(struct urb *urb, void __user *userurb)
++{
++	int j;
++	unsigned char *data = urb->transfer_buffer;
++
++	if (!usbfs_snoop)
++		return;
++
++	if (urb->pipe & USB_DIR_IN)
++		dev_info(&urb->dev->dev, "direction=IN\n");
++	else
++		dev_info(&urb->dev->dev, "direction=OUT\n");
++	dev_info(&urb->dev->dev, "userurb=%p\n", userurb);
++	dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n",
++		 urb->transfer_buffer_length);
++	dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length);
++	dev_info(&urb->dev->dev, "data: ");
++	for (j = 0; j < urb->transfer_buffer_length; ++j)
++		printk ("%02x ", data[j]);
++	printk("\n");
++}
++
+ static void async_completed(struct urb *urb, struct pt_regs *regs)
+ {
+         struct async *as = (struct async *)urb->context;
+@@ -296,7 +319,9 @@ static void async_completed(struct urb *
+ 		kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, 
+ 				      as->euid);
+ 	}
+-        wake_up(&ps->wait);
++	snoop(&urb->dev->dev, "urb complete\n");
++	snoop_urb(urb, as->userurb);
++	wake_up(&ps->wait);
+ }
+ 
+ static void destroy_async (struct dev_state *ps, struct list_head *list)
+@@ -493,6 +518,23 @@ static int check_ctrlrecip(struct dev_st
+ 	return ret;
+ }
+ 
++static struct usb_device *usbdev_lookup_minor(int minor)
++{
++	struct class_device *class_dev;
++	struct usb_device *dev = NULL;
++
++	down(&usb_device_class->sem);
++	list_for_each_entry(class_dev, &usb_device_class->children, node) {
++		if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
++			dev = class_dev->class_data;
++			break;
++		}
++	}
++	up(&usb_device_class->sem);
++
++	return dev;
++};
++
+ /*
+  * file operations
+  */
+@@ -601,7 +643,7 @@ static int proc_control(struct dev_state
+ 			if (usbfs_snoop) {
+ 				dev_info(&dev->dev, "control read: data ");
+ 				for (j = 0; j < i; ++j)
+-					printk ("%02x ", (unsigned char)(tbuf)[j]);
++					printk("%02x ", (unsigned char)(tbuf)[j]);
+ 				printk("\n");
+ 			}
+ 			if (copy_to_user(ctrl.data, tbuf, i)) {
+@@ -624,7 +666,7 @@ static int proc_control(struct dev_state
+ 		if (usbfs_snoop) {
+ 			dev_info(&dev->dev, "control write: data: ");
+ 			for (j = 0; j < ctrl.wLength; ++j)
+-				printk ("%02x ", (unsigned char)(tbuf)[j]);
++				printk("%02x ", (unsigned char)(tbuf)[j]);
+ 			printk("\n");
+ 		}
+ 		usb_unlock_device(dev);
+@@ -649,7 +691,7 @@ static int proc_bulk(struct dev_state *p
+ 	unsigned int tmo, len1, pipe;
+ 	int len2;
+ 	unsigned char *tbuf;
+-	int i, ret;
++	int i, j, ret;
+ 
+ 	if (copy_from_user(&bulk, arg, sizeof(bulk)))
+ 		return -EFAULT;
+@@ -674,10 +716,18 @@ static int proc_bulk(struct dev_state *p
+ 			kfree(tbuf);
+ 			return -EINVAL;
+ 		}
++		snoop(&dev->dev, "bulk read: len=0x%02x timeout=%04d\n",
++			bulk.len, bulk.timeout);
+ 		usb_unlock_device(dev);
+ 		i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
+ 		usb_lock_device(dev);
+ 		if (!i && len2) {
++			if (usbfs_snoop) {
++				dev_info(&dev->dev, "bulk read: data ");
++				for (j = 0; j < len2; ++j)
++					printk("%02x ", (unsigned char)(tbuf)[j]);
++				printk("\n");
++			}
+ 			if (copy_to_user(bulk.data, tbuf, len2)) {
+ 				kfree(tbuf);
+ 				return -EFAULT;
+@@ -690,6 +740,14 @@ static int proc_bulk(struct dev_state *p
+ 				return -EFAULT;
+ 			}
+ 		}
++		snoop(&dev->dev, "bulk write: len=0x%02x timeout=%04d\n",
++			bulk.len, bulk.timeout);
++		if (usbfs_snoop) {
++			dev_info(&dev->dev, "bulk write: data: ");
++			for (j = 0; j < len1; ++j)
++				printk("%02x ", (unsigned char)(tbuf)[j]);
++			printk("\n");
++		}
+ 		usb_unlock_device(dev);
+ 		i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
+ 		usb_lock_device(dev);
+@@ -835,7 +893,6 @@ static int proc_setconfig(struct dev_sta
+ 	return status;
+ }
+ 
+-
+ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
+ 			     struct usbdevfs_iso_packet_desc __user *iso_frame_desc,
+ 			     void __user *arg)
+@@ -896,6 +953,7 @@ static int proc_do_submiturb(struct dev_
+ 			kfree(dr);
+ 			return -EFAULT;
+ 		}
++		snoop(&ps->dev->dev, "control urb\n");
+ 		break;
+ 
+ 	case USBDEVFS_URB_TYPE_BULK:
+@@ -910,6 +968,7 @@ static int proc_do_submiturb(struct dev_
+ 			return -EINVAL;
+ 		if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length))
+ 			return -EFAULT;
++		snoop(&ps->dev->dev, "bulk urb\n");
+ 		break;
+ 
+ 	case USBDEVFS_URB_TYPE_ISO:
+@@ -939,6 +998,7 @@ static int proc_do_submiturb(struct dev_
+ 			return -EINVAL;
+ 		}
+ 		uurb->buffer_length = totlen;
++		snoop(&ps->dev->dev, "iso urb\n");
+ 		break;
+ 
+ 	case USBDEVFS_URB_TYPE_INTERRUPT:
+@@ -954,6 +1014,7 @@ static int proc_do_submiturb(struct dev_
+ 			return -EINVAL;
+ 		if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length))
+ 			return -EFAULT;
++		snoop(&ps->dev->dev, "interrupt urb\n");
+ 		break;
+ 
+ 	default:
+@@ -1003,6 +1064,8 @@ static int proc_do_submiturb(struct dev_
+ 			return -EFAULT;
+ 		}
+ 	}
++	snoop(&as->urb->dev->dev, "submit urb\n");
++	snoop_urb(as->urb, as->userurb);
+         async_newpending(as);
+         if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) {
+ 		dev_printk(KERN_DEBUG, &ps->dev->dev, "usbfs: usb_submit_urb returned %d\n", ret);
+@@ -1238,23 +1301,20 @@ static int proc_releaseinterface(struct 
+ 	return 0;
+ }
+ 
+-static int proc_ioctl (struct dev_state *ps, void __user *arg)
++static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
+ {
+-	struct usbdevfs_ioctl	ctrl;
+ 	int			size;
+ 	void			*buf = NULL;
+ 	int			retval = 0;
+ 	struct usb_interface    *intf = NULL;
+ 	struct usb_driver       *driver = NULL;
+ 
+-	/* get input parameters and alloc buffer */
+-	if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
+-		return -EFAULT;
+-	if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) {
++	/* alloc buffer */
++	if ((size = _IOC_SIZE (ctl->ioctl_code)) > 0) {
+ 		if ((buf = kmalloc (size, GFP_KERNEL)) == NULL)
+ 			return -ENOMEM;
+-		if ((_IOC_DIR(ctrl.ioctl_code) & _IOC_WRITE)) {
+-			if (copy_from_user (buf, ctrl.data, size)) {
++		if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) {
++			if (copy_from_user (buf, ctl->data, size)) {
+ 				kfree(buf);
+ 				return -EFAULT;
+ 			}
+@@ -1270,9 +1330,9 @@ static int proc_ioctl (struct dev_state 
+ 
+ 	if (ps->dev->state != USB_STATE_CONFIGURED)
+ 		retval = -EHOSTUNREACH;
+-	else if (!(intf = usb_ifnum_to_if (ps->dev, ctrl.ifno)))
++	else if (!(intf = usb_ifnum_to_if (ps->dev, ctl->ifno)))
+                retval = -EINVAL;
+-	else switch (ctrl.ioctl_code) {
++	else switch (ctl->ioctl_code) {
+ 
+ 	/* disconnect kernel driver from interface */
+ 	case USBDEVFS_DISCONNECT:
+@@ -1304,7 +1364,7 @@ static int proc_ioctl (struct dev_state 
+ 		if (driver == NULL || driver->ioctl == NULL) {
+ 			retval = -ENOTTY;
+ 		} else {
+-			retval = driver->ioctl (intf, ctrl.ioctl_code, buf);
++			retval = driver->ioctl (intf, ctl->ioctl_code, buf);
+ 			if (retval == -ENOIOCTLCMD)
+ 				retval = -ENOTTY;
+ 		}
+@@ -1313,15 +1373,42 @@ static int proc_ioctl (struct dev_state 
+ 
+ 	/* cleanup and return */
+ 	if (retval >= 0
+-			&& (_IOC_DIR (ctrl.ioctl_code) & _IOC_READ) != 0
++			&& (_IOC_DIR (ctl->ioctl_code) & _IOC_READ) != 0
+ 			&& size > 0
+-			&& copy_to_user (ctrl.data, buf, size) != 0)
++			&& copy_to_user (ctl->data, buf, size) != 0)
+ 		retval = -EFAULT;
+ 
+ 	kfree(buf);
+ 	return retval;
+ }
+ 
++static int proc_ioctl_default(struct dev_state *ps, void __user *arg)
++{
++	struct usbdevfs_ioctl	ctrl;
++
++	if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
++		return -EFAULT;
++	return proc_ioctl(ps, &ctrl);
++}
++
++#ifdef CONFIG_COMPAT
++static int proc_ioctl_compat(struct dev_state *ps, void __user *arg)
++{
++	struct usbdevfs_ioctl32 __user *uioc;
++	struct usbdevfs_ioctl ctrl;
++	u32 udata;
++
++	uioc = compat_ptr(arg);
++	if (get_user(ctrl.ifno, &uioc->ifno) ||
++	    get_user(ctrl.ioctl_code, &uioc->ioctl_code) ||
++	    __get_user(udata, &uioc->data))
++		return -EFAULT;
++	ctrl.data = compat_ptr(udata);
++
++	return proc_ioctl(ps, &ctrl);
++}
++#endif
++
+ /*
+  * NOTE:  All requests here that have interface numbers as parameters
+  * are assuming that somehow the configuration has been prevented from
+@@ -1422,6 +1509,10 @@ static int usbdev_ioctl(struct inode *in
+ 		ret = proc_reapurbnonblock_compat(ps, p);
+ 		break;
+ 
++	case USBDEVFS_IOCTL32:
++		snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
++		ret = proc_ioctl_compat(ps, p);
++		break;
+ #endif
+ 
+ 	case USBDEVFS_DISCARDURB:
+@@ -1456,7 +1547,7 @@ static int usbdev_ioctl(struct inode *in
+ 
+ 	case USBDEVFS_IOCTL:
+ 		snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
+-		ret = proc_ioctl(ps, p);
++		ret = proc_ioctl_default(ps, p);
+ 		break;
+ 	}
+ 	usb_unlock_device(dev);
+@@ -1488,39 +1579,40 @@ struct file_operations usbfs_device_file
+ 	.release =	usbdev_release,
+ };
+ 
+-struct usb_device *usbdev_lookup_minor(int minor)
+-{
+-	struct class_device *class_dev;
+-	struct usb_device *dev = NULL;
+-
+-	down(&usb_device_class->sem);
+-	list_for_each_entry(class_dev, &usb_device_class->children, node) {
+-		if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
+-			dev = class_dev->class_data;
+-			break;
+-		}
+-	}
+-	up(&usb_device_class->sem);
+-
+-	return dev;
+-};
+-
+-void usbdev_add(struct usb_device *dev)
++static void usbdev_add(struct usb_device *dev)
+ {
+ 	int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
+ 
+-	dev->class_dev = class_device_create(usb_device_class,
++	dev->class_dev = class_device_create(usb_device_class, NULL,
+ 				MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
+ 				"usbdev%d.%d", dev->bus->busnum, dev->devnum);
+ 
+ 	dev->class_dev->class_data = dev;
+ }
+ 
+-void usbdev_remove(struct usb_device *dev)
++static void usbdev_remove(struct usb_device *dev)
+ {
+ 	class_device_unregister(dev->class_dev);
+ }
+ 
++static int usbdev_notify(struct notifier_block *self, unsigned long action,
++			 void *dev)
++{
++	switch (action) {
++	case USB_DEVICE_ADD:
++		usbdev_add(dev);
++		break;
++	case USB_DEVICE_REMOVE:
++		usbdev_remove(dev);
++		break;
++	}
++	return NOTIFY_OK;
++}
++
++static struct notifier_block usbdev_nb = {
++	.notifier_call = 	usbdev_notify,
++};
++
+ static struct cdev usb_device_cdev = {
+ 	.kobj   = {.name = "usb_device", },
+ 	.owner  = THIS_MODULE,
+@@ -1540,24 +1632,32 @@ int __init usbdev_init(void)
+ 	retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
+ 	if (retval) {
+ 		err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
+-		unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+-		goto out;
++		goto error_cdev;
+ 	}
+ 	usb_device_class = class_create(THIS_MODULE, "usb_device");
+ 	if (IS_ERR(usb_device_class)) {
+ 		err("unable to register usb_device class");
+ 		retval = PTR_ERR(usb_device_class);
+-		usb_device_class = NULL;
+-		cdev_del(&usb_device_cdev);
+-		unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
++		goto error_class;
+ 	}
+ 
++	usb_register_notify(&usbdev_nb);
++
+ out:
+ 	return retval;
++
++error_class:
++	usb_device_class = NULL;
++	cdev_del(&usb_device_cdev);
++
++error_cdev:
++	unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
++	goto out;
+ }
+ 
+ void usbdev_cleanup(void)
+ {
++	usb_unregister_notify(&usbdev_nb);
+ 	class_destroy(usb_device_class);
+ 	cdev_del(&usb_device_cdev);
+ 	unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
+--- a/drivers/usb/core/file.c
++++ b/drivers/usb/core/file.c
+@@ -17,7 +17,6 @@
+ 
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/devfs_fs_kernel.h>
+ #include <linux/spinlock.h>
+ #include <linux/errno.h>
+ 
+@@ -88,8 +87,6 @@ int usb_major_init(void)
+ 		goto out;
+ 	}
+ 
+-	devfs_mk_dir("usb");
+-
+ out:
+ 	return error;
+ }
+@@ -97,7 +94,6 @@ out:
+ void usb_major_cleanup(void)
+ {
+ 	class_destroy(usb_class);
+-	devfs_remove("usb");
+ 	unregister_chrdev(USB_MAJOR, "usb");
+ }
+ 
+@@ -112,8 +108,7 @@ void usb_major_cleanup(void)
+  * enabled, the minor number will be based on the next available free minor,
+  * starting at the class_driver->minor_base.
+  *
+- * This function also creates the devfs file for the usb device, if devfs
+- * is enabled, and creates a usb class device in the sysfs tree.
++ * This function also creates a usb class device in the sysfs tree.
+  *
+  * usb_deregister_dev() must be called when the driver is done with
+  * the minor numbers given out by this function.
+@@ -162,22 +157,20 @@ int usb_register_dev(struct usb_interfac
+ 
+ 	intf->minor = minor;
+ 
+-	/* handle the devfs registration */
+-	snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base);
+-	devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name);
+-
+ 	/* create a usb class device for this usb interface */
++	snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base);
+ 	temp = strrchr(name, '/');
+ 	if (temp && (temp[1] != 0x00))
+ 		++temp;
+ 	else
+ 		temp = name;
+-	intf->class_dev = class_device_create(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp);
++	intf->class_dev = class_device_create(usb_class, NULL,
++					      MKDEV(USB_MAJOR, minor),
++					      &intf->dev, "%s", temp);
+ 	if (IS_ERR(intf->class_dev)) {
+ 		spin_lock (&minor_lock);
+ 		usb_minors[intf->minor] = NULL;
+ 		spin_unlock (&minor_lock);
+-		devfs_remove (name);
+ 		retval = PTR_ERR(intf->class_dev);
+ 	}
+ exit:
+@@ -195,9 +188,8 @@ EXPORT_SYMBOL(usb_register_dev);
+  * call to usb_register_dev() (usually when the device is disconnected
+  * from the system.)
+  *
+- * This function also cleans up the devfs file for the usb device, if devfs
+- * is enabled, and removes the usb class device from the sysfs tree.
+- * 
++ * This function also removes the usb class device from the sysfs tree.
++ *
+  * This should be called by all drivers that use the USB major number.
+  */
+ void usb_deregister_dev(struct usb_interface *intf,
+@@ -220,7 +212,6 @@ void usb_deregister_dev(struct usb_inter
+ 	spin_unlock (&minor_lock);
+ 
+ 	snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
+-	devfs_remove (name);
+ 	class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor));
+ 	intf->class_dev = NULL;
+ 	intf->minor = -1;
+diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
+--- a/drivers/usb/core/hcd-pci.c
++++ b/drivers/usb/core/hcd-pci.c
+@@ -30,6 +30,8 @@
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <linux/usb.h>
++
++#include "usb.h"
+ #include "hcd.h"
+ 
+ 
+@@ -197,6 +199,26 @@ int usb_hcd_pci_suspend (struct pci_dev 
+ 
+ 	hcd = pci_get_drvdata(dev);
+ 
++	/* Root hub suspend should have stopped all downstream traffic,
++	 * and all bus master traffic.  And done so for both the interface
++	 * and the stub usb_device (which we check here).  But maybe it
++	 * didn't; writing sysfs power/state files ignores such rules...
++	 *
++	 * We must ignore the FREEZE vs SUSPEND distinction here, because
++	 * otherwise the swsusp will save (and restore) garbage state.
++	 */
++	if (hcd->self.root_hub->dev.power.power_state.event == PM_EVENT_ON)
++		return -EBUSY;
++
++	if (hcd->driver->suspend) {
++		retval = hcd->driver->suspend(hcd, message);
++		if (retval) {
++			dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n",
++				retval);
++			goto done;
++		}
++	}
++
+ 	/* FIXME until the generic PM interfaces change a lot more, this
+ 	 * can't use PCI D1 and D2 states.  For example, the confusion
+ 	 * between messages and states will need to vanish, and messages
+@@ -215,31 +237,13 @@ int usb_hcd_pci_suspend (struct pci_dev 
+ 	 */
+ 	has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM);
+ 
+-	switch (hcd->state) {
+-
+-	/* entry if root hub wasn't yet suspended ... from sysfs,
+-	 * without autosuspend, or if USB_SUSPEND isn't configured.
++	/* Downstream ports from this root hub should already be quiesced, so
++	 * there will be no DMA activity.  Now we can shut down the upstream
++	 * link (except maybe for PME# resume signaling) and enter some PCI
++	 * low power state, if the hardware allows.
+ 	 */
+-	case HC_STATE_RUNNING:
+-		hcd->state = HC_STATE_QUIESCING;
+-		retval = hcd->driver->suspend (hcd, message);
+-		if (retval) {
+-			dev_dbg (hcd->self.controller, 
+-					"suspend fail, retval %d\n",
+-					retval);
+-			break;
+-		}
+-		hcd->state = HC_STATE_SUSPENDED;
+-		/* FALLTHROUGH */
++	if (hcd->state == HC_STATE_SUSPENDED) {
+ 
+-	/* entry with CONFIG_USB_SUSPEND, or hcds that autosuspend: the
+-	 * controller and/or root hub will already have been suspended,
+-	 * but it won't be ready for a PCI resume call.
+-	 *
+-	 * FIXME only CONFIG_USB_SUSPEND guarantees hub_suspend() will
+-	 * have been called, otherwise root hub timers still run ...
+-	 */
+-	case HC_STATE_SUSPENDED:
+ 		/* no DMA or IRQs except when HC is active */
+ 		if (dev->current_state == PCI_D0) {
+ 			pci_save_state (dev);
+@@ -248,7 +252,7 @@ int usb_hcd_pci_suspend (struct pci_dev 
+ 
+ 		if (!has_pci_pm) {
+ 			dev_dbg (hcd->self.controller, "--> PCI D0/legacy\n");
+-			break;
++			goto done;
+ 		}
+ 
+ 		/* NOTE:  dev->current_state becomes nonzero only here, and
+@@ -259,28 +263,29 @@ int usb_hcd_pci_suspend (struct pci_dev 
+ 		retval = pci_set_power_state (dev, PCI_D3hot);
+ 		if (retval == 0) {
+ 			dev_dbg (hcd->self.controller, "--> PCI D3\n");
+-			retval = pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
+-			if (retval)
+-				break;
+-			retval = pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
+-		} else if (retval < 0) {
++
++			/* Ignore these return values.  We rely on pci code to
++			 * reject requests the hardware can't implement, rather
++			 * than coding the same thing.
++			 */
++			(void) pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
++			(void) pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
++		} else {
+ 			dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n",
+ 					retval);
+ 			(void) usb_hcd_pci_resume (dev);
+-			break;
+ 		}
+-		break;
+-	default:
++
++	} else {
+ 		dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n",
+ 			hcd->state);
+ 		WARN_ON(1);
+ 		retval = -EINVAL;
+-		break;
+ 	}
+ 
+-	/* update power_state **ONLY** to make sysfs happier */
++done:
+ 	if (retval == 0)
+-		dev->dev.power.power_state = message;
++		dev->dev.power.power_state = PMSG_SUSPEND;
+ 	return retval;
+ }
+ EXPORT_SYMBOL (usb_hcd_pci_suspend);
+@@ -336,20 +341,9 @@ int usb_hcd_pci_resume (struct pci_dev *
+ 				dev->current_state);
+ 		}
+ #endif
+-		retval = pci_enable_wake (dev, dev->current_state, 0);
+-		if (retval) {
+-			dev_err(hcd->self.controller,
+-				"can't enable_wake to %d, %d!\n",
+-				dev->current_state, retval);
+-			return retval;
+-		}
+-		retval = pci_enable_wake (dev, PCI_D3cold, 0);
+-		if (retval) {
+-			dev_err(hcd->self.controller,
+-				"can't enable_wake to %d, %d!\n",
+-				PCI_D3cold, retval);
+-			return retval;
+-		}
++		/* yes, ignore these results too... */
++		(void) pci_enable_wake (dev, dev->current_state, 0);
++		(void) pci_enable_wake (dev, PCI_D3cold, 0);
+ 	} else {
+ 		/* Same basic cases: clean (powered/not), dirty */
+ 		dev_dbg(hcd->self.controller, "PCI legacy resume\n");
+@@ -371,17 +365,17 @@ int usb_hcd_pci_resume (struct pci_dev *
+ 
+ 	dev->dev.power.power_state = PMSG_ON;
+ 
+-	hcd->state = HC_STATE_RESUMING;
+ 	hcd->saw_irq = 0;
+ 
+-	retval = hcd->driver->resume (hcd);
+-	if (!HC_IS_RUNNING (hcd->state)) {
+-		dev_dbg (hcd->self.controller, 
+-				"resume fail, retval %d\n", retval);
+-		usb_hc_died (hcd);
++	if (hcd->driver->resume) {
++		retval = hcd->driver->resume(hcd);
++		if (retval) {
++			dev_err (hcd->self.controller,
++				"PCI post-resume error %d!\n", retval);
++			usb_hc_died (hcd);
++		}
+ 	}
+ 
+-	retval = pci_enable_device(dev);
+ 	return retval;
+ }
+ EXPORT_SYMBOL (usb_hcd_pci_resume);
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -130,7 +130,7 @@ static const u8 usb2_rh_dev_descriptor [
+ 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
+ 	0x00,	    /*  __u8  bDeviceSubClass; */
+ 	0x01,       /*  __u8  bDeviceProtocol; [ usb 2.0 single TT ]*/
+-	0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
++	0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */
+ 
+ 	0x00, 0x00, /*  __le16 idVendor; */
+  	0x00, 0x00, /*  __le16 idProduct; */
+@@ -153,7 +153,7 @@ static const u8 usb11_rh_dev_descriptor 
+ 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
+ 	0x00,	    /*  __u8  bDeviceSubClass; */
+ 	0x00,       /*  __u8  bDeviceProtocol; [ low/full speeds only ] */
+-	0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
++	0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */
+ 
+ 	0x00, 0x00, /*  __le16 idVendor; */
+  	0x00, 0x00, /*  __le16 idProduct; */
+@@ -458,22 +458,18 @@ static int rh_call_control (struct usb_h
+ 
+ 	default:
+ 		/* non-generic request */
+-		if (HC_IS_SUSPENDED (hcd->state))
+-			status = -EAGAIN;
+-		else {
+-			switch (typeReq) {
+-			case GetHubStatus:
+-			case GetPortStatus:
+-				len = 4;
+-				break;
+-			case GetHubDescriptor:
+-				len = sizeof (struct usb_hub_descriptor);
+-				break;
+-			}
+-			status = hcd->driver->hub_control (hcd,
+-				typeReq, wValue, wIndex,
+-				tbuf, wLength);
++		switch (typeReq) {
++		case GetHubStatus:
++		case GetPortStatus:
++			len = 4;
++			break;
++		case GetHubDescriptor:
++			len = sizeof (struct usb_hub_descriptor);
++			break;
+ 		}
++		status = hcd->driver->hub_control (hcd,
++			typeReq, wValue, wIndex,
++			tbuf, wLength);
+ 		break;
+ error:
+ 		/* "protocol stall" on error */
+@@ -487,7 +483,7 @@ error:
+ 				"CTRL: TypeReq=0x%x val=0x%x "
+ 				"idx=0x%x len=%d ==> %d\n",
+ 				typeReq, wValue, wIndex,
+-				wLength, urb->status);
++				wLength, status);
+ 		}
+ 	}
+ 	if (len) {
+@@ -748,10 +744,9 @@ struct usb_bus *usb_alloc_bus (struct us
+ {
+ 	struct usb_bus *bus;
+ 
+-	bus = kmalloc (sizeof *bus, GFP_KERNEL);
++	bus = kzalloc (sizeof *bus, GFP_KERNEL);
+ 	if (!bus)
+ 		return NULL;
+-	memset(bus, 0, sizeof(struct usb_bus));
+ 	usb_bus_init (bus);
+ 	bus->op = op;
+ 	return bus;
+@@ -782,7 +777,8 @@ static int usb_register_bus(struct usb_b
+ 		return -E2BIG;
+ 	}
+ 
+-	bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb_host%d", busnum);
++	bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0),
++					     bus->controller, "usb_host%d", busnum);
+ 	if (IS_ERR(bus->class_dev)) {
+ 		clear_bit(busnum, busmap.busmap);
+ 		up(&usb_bus_list_lock);
+@@ -795,8 +791,7 @@ static int usb_register_bus(struct usb_b
+ 	list_add (&bus->bus_list, &usb_bus_list);
+ 	up (&usb_bus_list_lock);
+ 
+-	usbfs_add_bus (bus);
+-	usbmon_notify_bus_add (bus);
++	usb_notify_add_bus(bus);
+ 
+ 	dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum);
+ 	return 0;
+@@ -823,8 +818,7 @@ static void usb_deregister_bus (struct u
+ 	list_del (&bus->bus_list);
+ 	up (&usb_bus_list_lock);
+ 
+-	usbmon_notify_bus_remove (bus);
+-	usbfs_remove_bus (bus);
++	usb_notify_remove_bus(bus);
+ 
+ 	clear_bit (bus->busnum, busmap.busmap);
+ 
+@@ -1112,7 +1106,7 @@ static void urb_unlink (struct urb *urb)
+  * expects usb_submit_urb() to have sanity checked and conditioned all
+  * inputs in the urb
+  */
+-static int hcd_submit_urb (struct urb *urb, unsigned mem_flags)
++static int hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
+ {
+ 	int			status;
+ 	struct usb_hcd		*hcd = urb->dev->bus->hcpriv;
+@@ -1142,10 +1136,20 @@ static int hcd_submit_urb (struct urb *u
+ 	else switch (hcd->state) {
+ 	case HC_STATE_RUNNING:
+ 	case HC_STATE_RESUMING:
++doit:
+ 		usb_get_dev (urb->dev);
+ 		list_add_tail (&urb->urb_list, &ep->urb_list);
+ 		status = 0;
+ 		break;
++	case HC_STATE_SUSPENDED:
++		/* HC upstream links (register access, wakeup signaling) can work
++		 * even when the downstream links (and DMA etc) are quiesced; let
++		 * usbcore talk to the root hub.
++		 */
++		if (hcd->self.controller->power.power_state.event == PM_EVENT_ON
++				&& urb->dev->parent == NULL)
++			goto doit;
++		/* FALL THROUGH */
+ 	default:
+ 		status = -ESHUTDOWN;
+ 		break;
+@@ -1293,12 +1297,6 @@ static int hcd_unlink_urb (struct urb *u
+ 		goto done;
+ 	}
+ 
+-	/* running ~= hc unlink handshake works (irq, timer, etc)
+-	 * halted ~= no unlink handshake is needed
+-	 * suspended, resuming == should never happen
+-	 */
+-	WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT);
+-
+ 	/* insist the urb is still queued */
+ 	list_for_each(tmp, &ep->urb_list) {
+ 		if (tmp == &urb->urb_list)
+@@ -1430,28 +1428,92 @@ rescan:
+ 
+ /*-------------------------------------------------------------------------*/
+ 
+-#ifdef	CONFIG_USB_SUSPEND
++#ifdef	CONFIG_PM
+ 
+-static int hcd_hub_suspend (struct usb_bus *bus)
++int hcd_bus_suspend (struct usb_bus *bus)
+ {
+ 	struct usb_hcd		*hcd;
++	int			status;
+ 
+ 	hcd = container_of (bus, struct usb_hcd, self);
+-	if (hcd->driver->hub_suspend)
+-		return hcd->driver->hub_suspend (hcd);
+-	return 0;
++	if (!hcd->driver->bus_suspend)
++		return -ENOENT;
++	hcd->state = HC_STATE_QUIESCING;
++	status = hcd->driver->bus_suspend (hcd);
++	if (status == 0)
++		hcd->state = HC_STATE_SUSPENDED;
++	else
++		dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n",
++				"suspend", status);
++	return status;
+ }
+ 
+-static int hcd_hub_resume (struct usb_bus *bus)
++int hcd_bus_resume (struct usb_bus *bus)
+ {
+ 	struct usb_hcd		*hcd;
++	int			status;
+ 
+ 	hcd = container_of (bus, struct usb_hcd, self);
+-	if (hcd->driver->hub_resume)
+-		return hcd->driver->hub_resume (hcd);
+-	return 0;
++	if (!hcd->driver->bus_resume)
++		return -ENOENT;
++	if (hcd->state == HC_STATE_RUNNING)
++		return 0;
++	hcd->state = HC_STATE_RESUMING;
++	status = hcd->driver->bus_resume (hcd);
++	if (status == 0)
++		hcd->state = HC_STATE_RUNNING;
++	else {
++		dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n",
++				"resume", status);
++		usb_hc_died(hcd);
++	}
++	return status;
+ }
+ 
++/*
++ * usb_hcd_suspend_root_hub - HCD autosuspends downstream ports
++ * @hcd: host controller for this root hub
++ *
++ * This call arranges that usb_hcd_resume_root_hub() is safe to call later;
++ * that the HCD's root hub polling is deactivated; and that the root's hub
++ * driver is suspended.  HCDs may call this to autosuspend when their root
++ * hub's downstream ports are all inactive:  unpowered, disconnected,
++ * disabled, or suspended.
++ *
++ * The HCD will autoresume on device connect change detection (using SRP
++ * or a D+/D- pullup).  The HCD also autoresumes on remote wakeup signaling
++ * from any ports that are suspended (if that is enabled).  In most cases,
++ * overcurrent signaling (on powered ports) will also start autoresume.
++ *
++ * Always called with IRQs blocked.
++ */
++void usb_hcd_suspend_root_hub (struct usb_hcd *hcd)
++{
++	struct urb	*urb;
++
++	spin_lock (&hcd_root_hub_lock);
++	usb_suspend_root_hub (hcd->self.root_hub);
++
++	/* force status urb to complete/unlink while suspended */
++	if (hcd->status_urb) {
++		urb = hcd->status_urb;
++		urb->status = -ECONNRESET;
++		urb->hcpriv = NULL;
++		urb->actual_length = 0;
++
++		del_timer (&hcd->rh_timer);
++		hcd->poll_pending = 0;
++		hcd->status_urb = NULL;
++	} else
++		urb = NULL;
++	spin_unlock (&hcd_root_hub_lock);
++	hcd->state = HC_STATE_SUSPENDED;
++
++	if (urb)
++		usb_hcd_giveback_urb (hcd, urb, NULL);
++}
++EXPORT_SYMBOL_GPL(usb_hcd_suspend_root_hub);
++
+ /**
+  * usb_hcd_resume_root_hub - called by HCD to resume its root hub 
+  * @hcd: host controller for this root hub
+@@ -1459,7 +1521,7 @@ static int hcd_hub_resume (struct usb_bu
+  * The USB host controller calls this function when its root hub is
+  * suspended (with the remote wakeup feature enabled) and a remote
+  * wakeup request is received.  It queues a request for khubd to
+- * resume the root hub.
++ * resume the root hub (that is, manage its downstream ports again).
+  */
+ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
+ {
+@@ -1470,13 +1532,9 @@ void usb_hcd_resume_root_hub (struct usb
+ 		usb_resume_root_hub (hcd->self.root_hub);
+ 	spin_unlock_irqrestore (&hcd_root_hub_lock, flags);
+ }
++EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
+ 
+-#else
+-void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
+-{
+-}
+ #endif
+-EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
+ 
+ /*-------------------------------------------------------------------------*/
+ 
+@@ -1529,10 +1587,6 @@ static struct usb_operations usb_hcd_ope
+ 	.buffer_alloc =		hcd_buffer_alloc,
+ 	.buffer_free =		hcd_buffer_free,
+ 	.disable =		hcd_endpoint_disable,
+-#ifdef	CONFIG_USB_SUSPEND
+-	.hub_suspend =		hcd_hub_suspend,
+-	.hub_resume =		hcd_hub_resume,
+-#endif
+ };
+ 
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
+--- a/drivers/usb/core/hcd.h
++++ b/drivers/usb/core/hcd.h
+@@ -142,22 +142,18 @@ struct hcd_timeout {	/* timeouts we allo
+ 
+ struct usb_operations {
+ 	int (*get_frame_number) (struct usb_device *usb_dev);
+-	int (*submit_urb) (struct urb *urb, unsigned mem_flags);
++	int (*submit_urb) (struct urb *urb, gfp_t mem_flags);
+ 	int (*unlink_urb) (struct urb *urb, int status);
+ 
+ 	/* allocate dma-consistent buffer for URB_DMA_NOMAPPING */
+ 	void *(*buffer_alloc)(struct usb_bus *bus, size_t size,
+-			unsigned mem_flags,
++			gfp_t mem_flags,
+ 			dma_addr_t *dma);
+ 	void (*buffer_free)(struct usb_bus *bus, size_t size,
+ 			void *addr, dma_addr_t dma);
+ 
+ 	void (*disable)(struct usb_device *udev,
+ 			struct usb_host_endpoint *ep);
+-
+-	/* global suspend/resume of bus */
+-	int (*hub_suspend)(struct usb_bus *);
+-	int (*hub_resume)(struct usb_bus *);
+ };
+ 
+ /* each driver provides one of these, and hardware init support */
+@@ -182,12 +178,12 @@ struct hc_driver {
+ 	int	(*start) (struct usb_hcd *hcd);
+ 
+ 	/* NOTE:  these suspend/resume calls relate to the HC as
+-	 * a whole, not just the root hub; they're for bus glue.
++	 * a whole, not just the root hub; they're for PCI bus glue.
+ 	 */
+-	/* called after all devices were suspended */
++	/* called after suspending the hub, before entering D3 etc */
+ 	int	(*suspend) (struct usb_hcd *hcd, pm_message_t message);
+ 
+-	/* called before any devices get resumed */
++	/* called after entering D0 (etc), before resuming the hub */
+ 	int	(*resume) (struct usb_hcd *hcd);
+ 
+ 	/* cleanly make HCD stop writing memory and doing I/O */
+@@ -200,7 +196,7 @@ struct hc_driver {
+ 	int	(*urb_enqueue) (struct usb_hcd *hcd,
+ 					struct usb_host_endpoint *ep,
+ 					struct urb *urb,
+-					unsigned mem_flags);
++					gfp_t mem_flags);
+ 	int	(*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
+ 
+ 	/* hw synch, freeing endpoint resources that urb_dequeue can't */
+@@ -212,8 +208,8 @@ struct hc_driver {
+ 	int		(*hub_control) (struct usb_hcd *hcd,
+ 				u16 typeReq, u16 wValue, u16 wIndex,
+ 				char *buf, u16 wLength);
+-	int		(*hub_suspend)(struct usb_hcd *);
+-	int		(*hub_resume)(struct usb_hcd *);
++	int		(*bus_suspend)(struct usb_hcd *);
++	int		(*bus_resume)(struct usb_hcd *);
+ 	int		(*start_port_reset)(struct usb_hcd *, unsigned port_num);
+ 	void		(*hub_irq_enable)(struct usb_hcd *);
+ 		/* Needed only if port-change IRQs are level-triggered */
+@@ -247,7 +243,7 @@ int hcd_buffer_create (struct usb_hcd *h
+ void hcd_buffer_destroy (struct usb_hcd *hcd);
+ 
+ void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
+-	unsigned mem_flags, dma_addr_t *dma);
++	gfp_t mem_flags, dma_addr_t *dma);
+ void hcd_buffer_free (struct usb_bus *bus, size_t size,
+ 	void *addr, dma_addr_t dma);
+ 
+@@ -355,8 +351,6 @@ extern long usb_calc_bus_time (int speed
+ 
+ extern struct usb_bus *usb_alloc_bus (struct usb_operations *);
+ 
+-extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
+-
+ extern void usb_set_device_state(struct usb_device *udev,
+ 		enum usb_device_state new_state);
+ 
+@@ -378,6 +372,33 @@ extern int usb_find_interface_driver (st
+ 
+ #define usb_endpoint_out(ep_dir)	(!((ep_dir) & USB_DIR_IN))
+ 
++#ifdef CONFIG_PM
++extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd);
++extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
++extern int hcd_bus_suspend (struct usb_bus *bus);
++extern int hcd_bus_resume (struct usb_bus *bus);
++#else
++static inline void usb_hcd_suspend_root_hub(struct usb_hcd *hcd)
++{
++	return;
++}
++
++static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
++{
++	return;
++}
++
++static inline int hcd_bus_suspend(struct usb_bus *bus)
++{
++	return 0;
++}
++
++static inline int hcd_bus_resume (struct usb_bus *bus)
++{
++	return 0;
++}
++#endif /* CONFIG_PM */
++
+ /*
+  * USB device fs stuff
+  */
+@@ -388,23 +409,13 @@ extern int usb_find_interface_driver (st
+  * these are expected to be called from the USB core/hub thread
+  * with the kernel lock held
+  */
+-extern void usbfs_add_bus(struct usb_bus *bus);
+-extern void usbfs_remove_bus(struct usb_bus *bus);
+-extern void usbfs_add_device(struct usb_device *dev);
+-extern void usbfs_remove_device(struct usb_device *dev);
+ extern void usbfs_update_special (void);
+-
+ extern int usbfs_init(void);
+ extern void usbfs_cleanup(void);
+ 
+ #else /* CONFIG_USB_DEVICEFS */
+ 
+-static inline void usbfs_add_bus(struct usb_bus *bus) {}
+-static inline void usbfs_remove_bus(struct usb_bus *bus) {}
+-static inline void usbfs_add_device(struct usb_device *dev) {}
+-static inline void usbfs_remove_device(struct usb_device *dev) {}
+ static inline void usbfs_update_special (void) {}
+-
+ static inline int usbfs_init(void) { return 0; }
+ static inline void usbfs_cleanup(void) { }
+ 
+@@ -419,8 +430,6 @@ struct usb_mon_operations {
+ 	void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err);
+ 	void (*urb_complete)(struct usb_bus *bus, struct urb *urb);
+ 	/* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */
+-	void (*bus_add)(struct usb_bus *bus);
+-	void (*bus_remove)(struct usb_bus *bus);
+ };
+ 
+ extern struct usb_mon_operations *mon_ops;
+@@ -443,18 +452,6 @@ static inline void usbmon_urb_complete(s
+ 	if (bus->monitored)
+ 		(*mon_ops->urb_complete)(bus, urb);
+ }
+- 
+-static inline void usbmon_notify_bus_add(struct usb_bus *bus)
+-{
+-	if (mon_ops)
+-		(*mon_ops->bus_add)(bus);
+-}
+-
+-static inline void usbmon_notify_bus_remove(struct usb_bus *bus)
+-{
+-	if (mon_ops)
+-		(*mon_ops->bus_remove)(bus);
+-}
+ 
+ int usb_mon_register(struct usb_mon_operations *ops);
+ void usb_mon_deregister(void);
+@@ -465,8 +462,6 @@ static inline void usbmon_urb_submit(str
+ static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
+     int error) {}
+ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {}
+-static inline void usbmon_notify_bus_add(struct usb_bus *bus) {}
+-static inline void usbmon_notify_bus_remove(struct usb_bus *bus) {}
+ 
+ #endif /* CONFIG_USB_MON */
+ 
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -436,9 +436,10 @@ static void hub_power_on(struct usb_hub 
+ {
+ 	int port1;
+ 	unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
++	u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
+ 
+ 	/* if hub supports power switching, enable power on each port */
+-	if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) {
++	if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) {
+ 		dev_dbg(hub->intfdev, "enabling power on all ports\n");
+ 		for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++)
+ 			set_port_feature(hub->hdev, port1,
+@@ -449,10 +450,18 @@ static void hub_power_on(struct usb_hub 
+ 	msleep(max(pgood_delay, (unsigned) 100));
+ }
+ 
+-static void hub_quiesce(struct usb_hub *hub)
++static inline void __hub_quiesce(struct usb_hub *hub)
+ {
+-	/* stop khubd and related activity */
++	/* (nonblocking) khubd and related activity won't re-trigger */
+ 	hub->quiescing = 1;
++	hub->activating = 0;
++	hub->resume_root_hub = 0;
++}
++
++static void hub_quiesce(struct usb_hub *hub)
++{
++	/* (blocking) stop khubd and related activity */
++	__hub_quiesce(hub);
+ 	usb_kill_urb(hub->urb);
+ 	if (hub->has_indicators)
+ 		cancel_delayed_work(&hub->leds);
+@@ -466,6 +475,7 @@ static void hub_activate(struct usb_hub 
+ 
+ 	hub->quiescing = 0;
+ 	hub->activating = 1;
++	hub->resume_root_hub = 0;
+ 	status = usb_submit_urb(hub->urb, GFP_NOIO);
+ 	if (status < 0)
+ 		dev_err(hub->intfdev, "activate --> %d\n", status);
+@@ -516,6 +526,7 @@ static int hub_configure(struct usb_hub 
+ 	struct usb_device *hdev = hub->hdev;
+ 	struct device *hub_dev = hub->intfdev;
+ 	u16 hubstatus, hubchange;
++	u16 wHubCharacteristics;
+ 	unsigned int pipe;
+ 	int maxp, ret;
+ 	char *message;
+@@ -561,9 +572,9 @@ static int hub_configure(struct usb_hub 
+ 	dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild,
+ 		(hdev->maxchild == 1) ? "" : "s");
+ 
+-	le16_to_cpus(&hub->descriptor->wHubCharacteristics);
++	wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
+ 
+-	if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND) {
++	if (wHubCharacteristics & HUB_CHAR_COMPOUND) {
+ 		int	i;
+ 		char	portstr [USB_MAXCHILDREN + 1];
+ 
+@@ -576,7 +587,7 @@ static int hub_configure(struct usb_hub 
+ 	} else
+ 		dev_dbg(hub_dev, "standalone hub\n");
+ 
+-	switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) {
++	switch (wHubCharacteristics & HUB_CHAR_LPSM) {
+ 		case 0x00:
+ 			dev_dbg(hub_dev, "ganged power switching\n");
+ 			break;
+@@ -589,7 +600,7 @@ static int hub_configure(struct usb_hub 
+ 			break;
+ 	}
+ 
+-	switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) {
++	switch (wHubCharacteristics & HUB_CHAR_OCPM) {
+ 		case 0x00:
+ 			dev_dbg(hub_dev, "global over-current protection\n");
+ 			break;
+@@ -629,7 +640,7 @@ static int hub_configure(struct usb_hub 
+ 	}
+ 
+ 	/* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
+-	switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) {
++	switch (wHubCharacteristics & HUB_CHAR_TTTT) {
+ 		case HUB_TTTT_8_BITS:
+ 			if (hdev->descriptor.bDeviceProtocol != 0) {
+ 				hub->tt.think_time = 666;
+@@ -659,7 +670,7 @@ static int hub_configure(struct usb_hub 
+ 	}
+ 
+ 	/* probe() zeroes hub->indicator[] */
+-	if (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND) {
++	if (wHubCharacteristics & HUB_CHAR_PORTIND) {
+ 		hub->has_indicators = 1;
+ 		dev_dbg(hub_dev, "Port indicators are supported\n");
+ 	}
+@@ -704,7 +715,7 @@ static int hub_configure(struct usb_hub 
+ 			(hubstatus & HUB_STATUS_LOCAL_POWER)
+ 			? "lost (inactive)" : "good");
+ 
+-	if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) == 0)
++	if ((wHubCharacteristics & HUB_CHAR_OCPM) == 0)
+ 		dev_dbg(hub_dev, "%sover-current condition exists\n",
+ 			(hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
+ 
+@@ -854,14 +865,12 @@ descriptor_error:
+ 	/* We found a hub */
+ 	dev_info (&intf->dev, "USB hub found\n");
+ 
+-	hub = kmalloc(sizeof(*hub), GFP_KERNEL);
++	hub = kzalloc(sizeof(*hub), GFP_KERNEL);
+ 	if (!hub) {
+ 		dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n");
+ 		return -ENOMEM;
+ 	}
+ 
+-	memset(hub, 0, sizeof(*hub));
+-
+ 	INIT_LIST_HEAD(&hub->event_list);
+ 	hub->intfdev = &intf->dev;
+ 	hub->hdev = hdev;
+@@ -1020,9 +1029,15 @@ void usb_set_device_state(struct usb_dev
+ 	spin_lock_irqsave(&device_state_lock, flags);
+ 	if (udev->state == USB_STATE_NOTATTACHED)
+ 		;	/* do nothing */
+-	else if (new_state != USB_STATE_NOTATTACHED)
++	else if (new_state != USB_STATE_NOTATTACHED) {
+ 		udev->state = new_state;
+-	else
++		if (new_state == USB_STATE_CONFIGURED)
++			device_init_wakeup(&udev->dev,
++				(udev->actconfig->desc.bmAttributes
++				 & USB_CONFIG_ATT_WAKEUP));
++		else if (new_state != USB_STATE_SUSPENDED)
++			device_init_wakeup(&udev->dev, 0);
++	} else
+ 		recursively_mark_NOTATTACHED(udev);
+ 	spin_unlock_irqrestore(&device_state_lock, flags);
+ }
+@@ -1111,14 +1126,14 @@ void usb_disconnect(struct usb_device **
+ 	 */
+ 	usb_disable_device(udev, 0);
+ 
++	usb_notify_remove_device(udev);
++
+ 	/* Free the device number, remove the /proc/bus/usb entry and
+ 	 * the sysfs attributes, and delete the parent's children[]
+ 	 * (or root_hub) pointer.
+ 	 */
+ 	dev_dbg (&udev->dev, "unregistering device\n");
+ 	release_address(udev);
+-	usbfs_remove_device(udev);
+-	usbdev_remove(udev);
+ 	usb_remove_sysfs_dev_files(udev);
+ 
+ 	/* Avoid races with recursively_mark_NOTATTACHED() */
+@@ -1189,21 +1204,6 @@ static inline void show_string(struct us
+ {}
+ #endif
+ 
+-static void get_string(struct usb_device *udev, char **string, int index)
+-{
+-	char *buf;
+-
+-	if (!index)
+-		return;
+-	buf = kmalloc(256, GFP_KERNEL);
+-	if (!buf)
+-		return;
+-	if (usb_string(udev, index, buf, 256) > 0)
+-		*string = buf;
+-	else
+-		kfree(buf);
+-}
+-
+ 
+ #ifdef	CONFIG_USB_OTG
+ #include "otg_whitelist.h"
+@@ -1242,9 +1242,10 @@ int usb_new_device(struct usb_device *ud
+ 	}
+ 
+ 	/* read the standard strings and cache them if present */
+-	get_string(udev, &udev->product, udev->descriptor.iProduct);
+-	get_string(udev, &udev->manufacturer, udev->descriptor.iManufacturer);
+-	get_string(udev, &udev->serial, udev->descriptor.iSerialNumber);
++	udev->product = usb_cache_string(udev, udev->descriptor.iProduct);
++	udev->manufacturer = usb_cache_string(udev,
++			udev->descriptor.iManufacturer);
++	udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
+ 
+ 	/* Tell the world! */
+ 	dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, "
+@@ -1316,11 +1317,9 @@ int usb_new_device(struct usb_device *ud
+ 		 * (Includes HNP test device.)
+ 		 */
+ 		if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
+-			static int __usb_suspend_device (struct usb_device *,
+-						int port1, pm_message_t state);
+-			err = __usb_suspend_device(udev,
+-					udev->bus->otg_port,
+-					PMSG_SUSPEND);
++			static int __usb_suspend_device(struct usb_device *,
++						int port1);
++			err = __usb_suspend_device(udev, udev->bus->otg_port);
+ 			if (err < 0)
+ 				dev_dbg(&udev->dev, "HNP fail, %d\n", err);
+ 		}
+@@ -1356,10 +1355,8 @@ int usb_new_device(struct usb_device *ud
+ 	}
+ 
+ 	/* USB device state == configured ... usable */
++	usb_notify_add_device(udev);
+ 
+-	/* add a /proc/bus/usb entry */
+-	usbdev_add(udev);
+-	usbfs_add_device(udev);
+ 	return 0;
+ 
+ fail:
+@@ -1510,7 +1507,7 @@ static void hub_port_logical_disconnect(
+ 	/* FIXME let caller ask to power down the port:
+ 	 *  - some devices won't enumerate without a VBUS power cycle
+ 	 *  - SRP saves power that way
+-	 *  - usb_suspend_device(dev, PMSG_SUSPEND)
++	 *  - ... new call, TBD ...
+ 	 * That's easy if this hub can switch power per-port, and
+ 	 * khubd reactivates the port later (timer, SRP, etc).
+ 	 * Powerdown must be optional, because of reset/DFU.
+@@ -1546,11 +1543,7 @@ static int hub_port_suspend(struct usb_h
+ 	 * NOTE:  OTG devices may issue remote wakeup (or SRP) even when
+ 	 * we don't explicitly enable it here.
+ 	 */
+-	if (udev->actconfig
+-			// && FIXME (remote wakeup enabled on this bus)
+-			// ... currently assuming it's always appropriate
+-			&& (udev->actconfig->desc.bmAttributes
+-				& USB_CONFIG_ATT_WAKEUP) != 0) {
++	if (device_may_wakeup(&udev->dev)) {
+ 		status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ 				USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
+ 				USB_DEVICE_REMOTE_WAKEUP, 0,
+@@ -1596,11 +1589,14 @@ static int hub_port_suspend(struct usb_h
+  * Other than re-initializing the hub (plug/unplug, except for root hubs),
+  * Linux (2.6) currently has NO mechanisms to initiate that:  no khubd
+  * timer, no SRP, no requests through sysfs.
++ *
++ * If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when
++ * the root hub for their bus goes into global suspend ... so we don't
++ * (falsely) update the device power state to say it suspended.
+  */
+-static int __usb_suspend_device (struct usb_device *udev, int port1,
+-				 pm_message_t state)
++static int __usb_suspend_device (struct usb_device *udev, int port1)
+ {
+-	int	status;
++	int	status = 0;
+ 
+ 	/* caller owns the udev device lock */
+ 	if (port1 < 0)
+@@ -1611,95 +1607,39 @@ static int __usb_suspend_device (struct 
+ 		return 0;
+ 	}
+ 
+-	/* suspend interface drivers; if this is a hub, it
+-	 * suspends the child devices
+-	 */
++	/* all interfaces must already be suspended */
+ 	if (udev->actconfig) {
+ 		int	i;
+ 
+ 		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+ 			struct usb_interface	*intf;
+-			struct usb_driver	*driver;
+ 
+ 			intf = udev->actconfig->interface[i];
+-			if (state.event <= intf->dev.power.power_state.event)
+-				continue;
+-			if (!intf->dev.driver)
+-				continue;
+-			driver = to_usb_driver(intf->dev.driver);
+-
+-			if (driver->suspend) {
+-				status = driver->suspend(intf, state);
+-				if (intf->dev.power.power_state.event != state.event
+-						|| status)
+-					dev_err(&intf->dev,
+-						"suspend %d fail, code %d\n",
+-						state.event, status);
+-			}
+-
+-			/* only drivers with suspend() can ever resume();
+-			 * and after power loss, even they won't.
+-			 * bus_rescan_devices() can rebind drivers later.
+-			 *
+-			 * FIXME the PM core self-deadlocks when unbinding
+-			 * drivers during suspend/resume ... everything grabs
+-			 * dpm_sem (not a spinlock, ugh).  we want to unbind,
+-			 * since we know every driver's probe/disconnect works
+-			 * even for drivers that can't suspend.
+-			 */
+-			if (!driver->suspend || state.event > PM_EVENT_FREEZE) {
+-#if 1
+-				dev_warn(&intf->dev, "resume is unsafe!\n");
+-#else
+-				down_write(&usb_bus_type.rwsem);
+-				device_release_driver(&intf->dev);
+-				up_write(&usb_bus_type.rwsem);
+-#endif
++			if (is_active(intf)) {
++				dev_dbg(&intf->dev, "nyet suspended\n");
++				return -EBUSY;
+ 			}
+ 		}
+ 	}
+ 
+-	/*
+-	 * FIXME this needs port power off call paths too, to help force
+-	 * USB into the "generic" PM model.  At least for devices on
+-	 * ports that aren't using ganged switching (usually root hubs).
+-	 *
+-	 * NOTE: SRP-capable links should adopt more aggressive poweroff
+-	 * policies (when HNP doesn't apply) once we have mechanisms to
+-	 * turn power back on!  (Likely not before 2.7...)
+-	 */
+-	if (state.event > PM_EVENT_FREEZE) {
+-		dev_warn(&udev->dev, "no poweroff yet, suspending instead\n");
+-	}
+-
+-	/* "global suspend" of the HC-to-USB interface (root hub), or
+-	 * "selective suspend" of just one hub-device link.
++	/* we only change a device's upstream USB link.
++	 * root hubs have no upstream USB link.
+ 	 */
+-	if (!udev->parent) {
+-		struct usb_bus	*bus = udev->bus;
+-		if (bus && bus->op->hub_suspend) {
+-			status = bus->op->hub_suspend (bus);
+-			if (status == 0) {
+-				dev_dbg(&udev->dev, "usb suspend\n");
+-				usb_set_device_state(udev,
+-						USB_STATE_SUSPENDED);
+-			}
+-		} else
+-			status = -EOPNOTSUPP;
+-	} else
++	if (udev->parent)
+ 		status = hub_port_suspend(hdev_to_hub(udev->parent), port1,
+ 				udev);
+ 
+ 	if (status == 0)
+-		udev->dev.power.power_state = state;
++		udev->dev.power.power_state = PMSG_SUSPEND;
+ 	return status;
+ }
+ 
+-/**
++#endif
++
++/*
+  * usb_suspend_device - suspend a usb device
+  * @udev: device that's no longer in active use
+- * @state: PMSG_SUSPEND to suspend
+- * Context: must be able to sleep; device not locked
++ * Context: must be able to sleep; device not locked; pm locks held
+  *
+  * Suspends a USB device that isn't in active use, conserving power.
+  * Devices may wake out of a suspend, if anything important happens,
+@@ -1707,37 +1647,50 @@ static int __usb_suspend_device (struct 
+  * suspend by the host, using usb_resume_device().  It's also routine
+  * to disconnect devices while they are suspended.
+  *
++ * This only affects the USB hardware for a device; its interfaces
++ * (and, for hubs, child devices) must already have been suspended.
++ *
+  * Suspending OTG devices may trigger HNP, if that's been enabled
+  * between a pair of dual-role devices.  That will change roles, such
+  * as from A-Host to A-Peripheral or from B-Host back to B-Peripheral.
+  *
+  * Returns 0 on success, else negative errno.
+  */
+-int usb_suspend_device(struct usb_device *udev, pm_message_t state)
++int usb_suspend_device(struct usb_device *udev)
+ {
++#ifdef	CONFIG_USB_SUSPEND
+ 	int	port1, status;
+ 
+ 	port1 = locktree(udev);
+ 	if (port1 < 0)
+ 		return port1;
+ 
+-	status = __usb_suspend_device(udev, port1, state);
++	status = __usb_suspend_device(udev, port1);
+ 	usb_unlock_device(udev);
+ 	return status;
++#else
++	/* NOTE:  udev->state unchanged, it's not lying ... */
++	udev->dev.power.power_state = PMSG_SUSPEND;
++	return 0;
++#endif
+ }
++EXPORT_SYMBOL_GPL(usb_suspend_device);
+ 
+ /*
++ * If the USB "suspend" state is in use (rather than "global suspend"),
++ * many devices will be individually taken out of suspend state using
++ * special" resume" signaling.  These routines kick in shortly after
+  * hardware resume signaling is finished, either because of selective
+  * resume (by host) or remote wakeup (by device) ... now see what changed
+  * in the tree that's rooted at this device.
+  */
+-static int finish_port_resume(struct usb_device *udev)
++static int finish_device_resume(struct usb_device *udev)
+ {
+ 	int	status;
+ 	u16	devstatus;
+ 
+ 	/* caller owns the udev device lock */
+-	dev_dbg(&udev->dev, "usb resume\n");
++	dev_dbg(&udev->dev, "finish resume\n");
+ 
+ 	/* usb ch9 identifies four variants of SUSPENDED, based on what
+ 	 * state the device resumes to.  Linux currently won't see the
+@@ -1747,7 +1700,6 @@ static int finish_port_resume(struct usb
+ 	usb_set_device_state(udev, udev->actconfig
+ 			? USB_STATE_CONFIGURED
+ 			: USB_STATE_ADDRESS);
+-	udev->dev.power.power_state = PMSG_ON;
+ 
+  	/* 10.5.4.5 says be sure devices in the tree are still there.
+  	 * For now let's assume the device didn't go crazy on resume,
+@@ -1760,9 +1712,11 @@ static int finish_port_resume(struct usb
+ 			status);
+ 	else if (udev->actconfig) {
+ 		unsigned	i;
++		int		(*resume)(struct device *);
+ 
+ 		le16_to_cpus(&devstatus);
+-		if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
++		if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)
++				&& udev->parent) {
+ 			status = usb_control_msg(udev,
+ 					usb_sndctrlpipe(udev, 0),
+ 					USB_REQ_CLEAR_FEATURE,
+@@ -1778,33 +1732,11 @@ static int finish_port_resume(struct usb
+ 		}
+ 
+ 		/* resume interface drivers; if this is a hub, it
+-		 * resumes the child devices
++		 * may have a child resume event to deal with soon
+ 		 */
+-		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+-			struct usb_interface	*intf;
+-			struct usb_driver	*driver;
+-
+-			intf = udev->actconfig->interface[i];
+-			if (intf->dev.power.power_state.event == PM_EVENT_ON)
+-				continue;
+-			if (!intf->dev.driver) {
+-				/* FIXME maybe force to alt 0 */
+-				continue;
+-			}
+-			driver = to_usb_driver(intf->dev.driver);
+-
+-			/* bus_rescan_devices() may rebind drivers */
+-			if (!driver->resume)
+-				continue;
+-
+-			/* can we do better than just logging errors? */
+-			status = driver->resume(intf);
+-			if (intf->dev.power.power_state.event != PM_EVENT_ON
+-					|| status)
+-				dev_dbg(&intf->dev,
+-					"resume fail, state %d code %d\n",
+-					intf->dev.power.power_state.event, status);
+-		}
++		resume = udev->dev.bus->resume;
++		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++)
++			(void) resume(&udev->actconfig->interface[i]->dev);
+ 		status = 0;
+ 
+ 	} else if (udev->devnum <= 0) {
+@@ -1814,6 +1746,8 @@ static int finish_port_resume(struct usb
+ 	return status;
+ }
+ 
++#ifdef	CONFIG_USB_SUSPEND
++
+ static int
+ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
+ {
+@@ -1859,7 +1793,7 @@ hub_port_resume(struct usb_hub *hub, int
+ 			/* TRSMRCY = 10 msec */
+ 			msleep(10);
+ 			if (udev)
+-				status = finish_port_resume(udev);
++				status = finish_device_resume(udev);
+ 		}
+ 	}
+ 	if (status < 0)
+@@ -1868,12 +1802,12 @@ hub_port_resume(struct usb_hub *hub, int
+ 	return status;
+ }
+ 
+-static int hub_resume (struct usb_interface *intf);
++#endif
+ 
+-/**
++/*
+  * usb_resume_device - re-activate a suspended usb device
+  * @udev: device to re-activate
+- * Context: must be able to sleep; device not locked
++ * Context: must be able to sleep; device not locked; pm locks held
+  *
+  * This will re-activate the suspended device, increasing power usage
+  * while letting drivers communicate again with its endpoints.
+@@ -1891,35 +1825,22 @@ int usb_resume_device(struct usb_device 
+ 	if (port1 < 0)
+ 		return port1;
+ 
+-	/* "global resume" of the HC-to-USB interface (root hub), or
+-	 * selective resume of one hub-to-device port
+-	 */
+-	if (!udev->parent) {
+-		struct usb_bus	*bus = udev->bus;
+-		if (bus && bus->op->hub_resume) {
+-			status = bus->op->hub_resume (bus);
++#ifdef	CONFIG_USB_SUSPEND
++	/* selective resume of one downstream hub-to-device port */
++	if (udev->parent) {
++		if (udev->state == USB_STATE_SUSPENDED) {
++			// NOTE swsusp may bork us, device state being wrong...
++			// NOTE this fails if parent is also suspended...
++			status = hub_port_resume(hdev_to_hub(udev->parent),
++					port1, udev);
+ 		} else
+-			status = -EOPNOTSUPP;
+-		if (status == 0) {
+-			dev_dbg(&udev->dev, "usb resume\n");
+-			/* TRSMRCY = 10 msec */
+-			msleep(10);
+-			usb_set_device_state (udev, USB_STATE_CONFIGURED);
+-			udev->dev.power.power_state = PMSG_ON;
+-			status = hub_resume (udev
+-					->actconfig->interface[0]);
+-		}
+-	} else if (udev->state == USB_STATE_SUSPENDED) {
+-		// NOTE this fails if parent is also suspended...
+-		status = hub_port_resume(hdev_to_hub(udev->parent),
+-				port1, udev);
+-	} else {
+-		status = 0;
+-	}
+-	if (status < 0) {
++			status = 0;
++	} else
++#endif
++		status = finish_device_resume(udev);
++	if (status < 0)
+ 		dev_dbg(&udev->dev, "can't resume, status %d\n",
+ 			status);
+-	}
+ 
+ 	usb_unlock_device(udev);
+ 
+@@ -1936,6 +1857,8 @@ static int remote_wakeup(struct usb_devi
+ {
+ 	int	status = 0;
+ 
++#ifdef	CONFIG_USB_SUSPEND
++
+ 	/* don't repeat RESUME sequence if this device
+ 	 * was already woken up by some other task
+ 	 */
+@@ -1944,38 +1867,52 @@ static int remote_wakeup(struct usb_devi
+ 		dev_dbg(&udev->dev, "RESUME (wakeup)\n");
+ 		/* TRSMRCY = 10 msec */
+ 		msleep(10);
+-		status = finish_port_resume(udev);
++		status = finish_device_resume(udev);
+ 	}
+ 	up(&udev->serialize);
++#endif
+ 	return status;
+ }
+ 
+-static int hub_suspend(struct usb_interface *intf, pm_message_t state)
++static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
+ {
+ 	struct usb_hub		*hub = usb_get_intfdata (intf);
+ 	struct usb_device	*hdev = hub->hdev;
+ 	unsigned		port1;
+-	int			status;
+-
+-	/* stop khubd and related activity */
+-	hub_quiesce(hub);
+ 
+-	/* then suspend every port */
++	/* fail if children aren't already suspended */
+ 	for (port1 = 1; port1 <= hdev->maxchild; port1++) {
+ 		struct usb_device	*udev;
+ 
+ 		udev = hdev->children [port1-1];
+-		if (!udev)
+-			continue;
+-		down(&udev->serialize);
+-		status = __usb_suspend_device(udev, port1, state);
+-		up(&udev->serialize);
+-		if (status < 0)
+-			dev_dbg(&intf->dev, "suspend port %d --> %d\n",
+-				port1, status);
++		if (udev && (udev->dev.power.power_state.event
++					== PM_EVENT_ON
++#ifdef	CONFIG_USB_SUSPEND
++				|| udev->state != USB_STATE_SUSPENDED
++#endif
++				)) {
++			dev_dbg(&intf->dev, "port %d nyet suspended\n", port1);
++			return -EBUSY;
++		}
+ 	}
+ 
+-	intf->dev.power.power_state = state;
++	/* "global suspend" of the downstream HC-to-USB interface */
++	if (!hdev->parent) {
++		struct usb_bus	*bus = hdev->bus;
++		if (bus) {
++			int	status = hcd_bus_suspend (bus);
++
++			if (status != 0) {
++				dev_dbg(&hdev->dev, "'global' suspend %d\n",
++					status);
++				return status;
++			}
++		} else
++			return -EOPNOTSUPP;
++	}
++
++	/* stop khubd and related activity */
++	hub_quiesce(hub);
+ 	return 0;
+ }
+ 
+@@ -1983,11 +1920,35 @@ static int hub_resume(struct usb_interfa
+ {
+ 	struct usb_device	*hdev = interface_to_usbdev(intf);
+ 	struct usb_hub		*hub = usb_get_intfdata (intf);
+-	unsigned		port1;
+ 	int			status;
+ 
+-	if (intf->dev.power.power_state.event == PM_EVENT_ON)
+-		return 0;
++	/* "global resume" of the downstream HC-to-USB interface */
++	if (!hdev->parent) {
++		struct usb_bus	*bus = hdev->bus;
++		if (bus) {
++			status = hcd_bus_resume (bus);
++			if (status) {
++				dev_dbg(&intf->dev, "'global' resume %d\n",
++					status);
++				return status;
++			}
++		} else
++			return -EOPNOTSUPP;
++		if (status == 0) {
++			/* TRSMRCY = 10 msec */
++			msleep(10);
++		}
++	}
++
++	hub_activate(hub);
++
++	/* REVISIT:  this recursion probably shouldn't exist.  Remove
++	 * this code sometime, after retesting with different root and
++	 * external hubs.
++	 */
++#ifdef	CONFIG_USB_SUSPEND
++	{
++	unsigned		port1;
+ 
+ 	for (port1 = 1; port1 <= hdev->maxchild; port1++) {
+ 		struct usb_device	*udev;
+@@ -2013,7 +1974,7 @@ static int hub_resume(struct usb_interfa
+ 		if (portstat & USB_PORT_STAT_SUSPEND)
+ 			status = hub_port_resume(hub, port1, udev);
+ 		else {
+-			status = finish_port_resume(udev);
++			status = finish_device_resume(udev);
+ 			if (status < 0) {
+ 				dev_dbg(&intf->dev, "resume port %d --> %d\n",
+ 					port1, status);
+@@ -2022,43 +1983,31 @@ static int hub_resume(struct usb_interfa
+ 		}
+ 		up(&udev->serialize);
+ 	}
+-	intf->dev.power.power_state = PMSG_ON;
+-
+-	hub->resume_root_hub = 0;
+-	hub_activate(hub);
++	}
++#endif
+ 	return 0;
+ }
+ 
+-void usb_resume_root_hub(struct usb_device *hdev)
++void usb_suspend_root_hub(struct usb_device *hdev)
+ {
+ 	struct usb_hub *hub = hdev_to_hub(hdev);
+ 
+-	hub->resume_root_hub = 1;
+-	kick_khubd(hub);
++	/* This also makes any led blinker stop retriggering.  We're called
++	 * from irq, so the blinker might still be scheduled.  Caller promises
++	 * that the root hub status URB will be canceled.
++	 */
++	__hub_quiesce(hub);
++	mark_quiesced(to_usb_interface(hub->intfdev));
+ }
+ 
+-#else	/* !CONFIG_USB_SUSPEND */
+-
+-int usb_suspend_device(struct usb_device *udev, pm_message_t state)
++void usb_resume_root_hub(struct usb_device *hdev)
+ {
+-	return 0;
+-}
++	struct usb_hub *hub = hdev_to_hub(hdev);
+ 
+-int usb_resume_device(struct usb_device *udev)
+-{
+-	return 0;
++	hub->resume_root_hub = 1;
++	kick_khubd(hub);
+ }
+ 
+-#define	hub_suspend		NULL
+-#define	hub_resume		NULL
+-#define	remote_wakeup(x)	0
+-
+-#endif	/* CONFIG_USB_SUSPEND */
+-
+-EXPORT_SYMBOL(usb_suspend_device);
+-EXPORT_SYMBOL(usb_resume_device);
+-
+-
+ 
+ /* USB 2.0 spec, 7.1.7.3 / fig 7-29:
+  *
+@@ -2467,6 +2416,7 @@ static void hub_port_connect_change(stru
+ {
+ 	struct usb_device *hdev = hub->hdev;
+ 	struct device *hub_dev = hub->intfdev;
++	u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
+ 	int status, i;
+  
+ 	dev_dbg (hub_dev,
+@@ -2504,8 +2454,7 @@ static void hub_port_connect_change(stru
+ 	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
+ 
+ 		/* maybe switch power back on (e.g. root hub was reset) */
+-		if ((hub->descriptor->wHubCharacteristics
+-					& HUB_CHAR_LPSM) < 2
++		if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
+ 				&& !(portstatus & (1 << USB_PORT_FEAT_POWER)))
+ 			set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+  
+@@ -2684,21 +2633,28 @@ static void hub_events(void)
+ 		intf = to_usb_interface(hub->intfdev);
+ 		hub_dev = &intf->dev;
+ 
+-		dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
++		i = hub->resume_root_hub;
++
++		dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x%s\n",
+ 				hdev->state, hub->descriptor
+ 					? hub->descriptor->bNbrPorts
+ 					: 0,
+ 				/* NOTE: expects max 15 ports... */
+ 				(u16) hub->change_bits[0],
+-				(u16) hub->event_bits[0]);
++				(u16) hub->event_bits[0],
++				i ? ", resume root" : "");
+ 
+ 		usb_get_intf(intf);
+-		i = hub->resume_root_hub;
+ 		spin_unlock_irq(&hub_event_lock);
+ 
+-		/* Is this is a root hub wanting to be resumed? */
+-		if (i)
+-			usb_resume_device(hdev);
++		/* Is this is a root hub wanting to reactivate the downstream
++		 * ports?  If so, be sure the interface resumes even if its
++		 * stub "device" node was never suspended.
++		 */
++		if (i) {
++			dpm_runtime_resume(&hdev->dev);
++			dpm_runtime_resume(&intf->dev);
++		}
+ 
+ 		/* Lock the device, then check to see if we were
+ 		 * disconnected while waiting for the lock to succeed. */
+diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
+--- a/drivers/usb/core/hub.h
++++ b/drivers/usb/core/hub.h
+@@ -131,7 +131,7 @@ struct usb_hub_descriptor {
+ 	__u8  bDescLength;
+ 	__u8  bDescriptorType;
+ 	__u8  bNbrPorts;
+-	__u16 wHubCharacteristics;
++	__le16 wHubCharacteristics;
+ 	__u8  bPwrOn2PwrGood;
+ 	__u8  bHubContrCurrent;
+ 	    	/* add 1 bit for hub status change; round to bytes */
+diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
+--- a/drivers/usb/core/inode.c
++++ b/drivers/usb/core/inode.c
+@@ -39,6 +39,7 @@
+ #include <linux/usbdevice_fs.h>
+ #include <linux/smp_lock.h>
+ #include <linux/parser.h>
++#include <linux/notifier.h>
+ #include <asm/byteorder.h>
+ #include "usb.h"
+ #include "hcd.h"
+@@ -619,7 +620,7 @@ void usbfs_update_special (void)
+ 	}
+ }
+ 
+-void usbfs_add_bus(struct usb_bus *bus)
++static void usbfs_add_bus(struct usb_bus *bus)
+ {
+ 	struct dentry *parent;
+ 	char name[8];
+@@ -642,12 +643,9 @@ void usbfs_add_bus(struct usb_bus *bus)
+ 		err ("error creating usbfs bus entry");
+ 		return;
+ 	}
+-
+-	usbfs_update_special();
+-	usbfs_conn_disc_event();
+ }
+ 
+-void usbfs_remove_bus(struct usb_bus *bus)
++static void usbfs_remove_bus(struct usb_bus *bus)
+ {
+ 	if (bus->usbfs_dentry) {
+ 		fs_remove_file (bus->usbfs_dentry);
+@@ -659,12 +657,9 @@ void usbfs_remove_bus(struct usb_bus *bu
+ 		remove_special_files();
+ 		num_buses = 0;
+ 	}
+-
+-	usbfs_update_special();
+-	usbfs_conn_disc_event();
+ }
+ 
+-void usbfs_add_device(struct usb_device *dev)
++static void usbfs_add_device(struct usb_device *dev)
+ {
+ 	char name[8];
+ 	int i;
+@@ -690,12 +685,9 @@ void usbfs_add_device(struct usb_device 
+ 	}
+ 	if (dev->usbfs_dentry->d_inode)
+ 		dev->usbfs_dentry->d_inode->i_size = i_size;
+-
+-	usbfs_update_special();
+-	usbfs_conn_disc_event();
+ }
+ 
+-void usbfs_remove_device(struct usb_device *dev)
++static void usbfs_remove_device(struct usb_device *dev)
+ {
+ 	struct dev_state *ds;
+ 	struct siginfo sinfo;
+@@ -716,10 +708,33 @@ void usbfs_remove_device(struct usb_devi
+ 			kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid);
+ 		}
+ 	}
++}
++
++static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
++{
++	switch (action) {
++	case USB_DEVICE_ADD:
++		usbfs_add_device(dev);
++		break;
++	case USB_DEVICE_REMOVE:
++		usbfs_remove_device(dev);
++		break;
++	case USB_BUS_ADD:
++		usbfs_add_bus(dev);
++		break;
++	case USB_BUS_REMOVE:
++		usbfs_remove_bus(dev);
++	}
++
+ 	usbfs_update_special();
+ 	usbfs_conn_disc_event();
++	return NOTIFY_OK;
+ }
+ 
++static struct notifier_block usbfs_nb = {
++	.notifier_call = 	usbfs_notify,
++};
++
+ /* --------------------------------------------------------------------- */
+ 
+ static struct proc_dir_entry *usbdir = NULL;
+@@ -732,6 +747,8 @@ int __init usbfs_init(void)
+ 	if (retval)
+ 		return retval;
+ 
++	usb_register_notify(&usbfs_nb);
++
+ 	/* create mount point for usbfs */
+ 	usbdir = proc_mkdir("usb", proc_bus);
+ 
+@@ -740,6 +757,7 @@ int __init usbfs_init(void)
+ 
+ void usbfs_cleanup(void)
+ {
++	usb_unregister_notify(&usbfs_nb);
+ 	unregister_filesystem(&usb_fs_type);
+ 	if (usbdir)
+ 		remove_proc_entry("usb", proc_bus);
+diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -187,21 +187,37 @@ int usb_control_msg(struct usb_device *d
+  *      If a thread in your driver uses this call, make sure your disconnect()
+  *      method can wait for it to complete.  Since you don't have a handle on
+  *      the URB used, you can't cancel the request.
++ *
++ *	Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT
++ *	ioctl, users are forced to abuse this routine by using it to submit
++ *	URBs for interrupt endpoints.  We will take the liberty of creating
++ *	an interrupt URB (with the default interval) if the target is an
++ *	interrupt endpoint.
+  */
+ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, 
+ 			void *data, int len, int *actual_length, int timeout)
+ {
+ 	struct urb *urb;
++	struct usb_host_endpoint *ep;
+ 
+-	if (len < 0)
++	ep = (usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out)
++			[usb_pipeendpoint(pipe)];
++	if (!ep || len < 0)
+ 		return -EINVAL;
+ 
+-	urb=usb_alloc_urb(0, GFP_KERNEL);
++	urb = usb_alloc_urb(0, GFP_KERNEL);
+ 	if (!urb)
+ 		return -ENOMEM;
+ 
+-	usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
+-			  usb_api_blocking_completion, NULL);
++	if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
++			USB_ENDPOINT_XFER_INT) {
++		pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
++		usb_fill_int_urb(urb, usb_dev, pipe, data, len,
++				usb_api_blocking_completion, NULL,
++				ep->desc.bInterval);
++	} else
++		usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
++				usb_api_blocking_completion, NULL);
+ 
+ 	return usb_start_wait_urb(urb, timeout, actual_length);
+ }
+@@ -321,7 +337,7 @@ int usb_sg_init (
+ 	struct scatterlist	*sg,
+ 	int			nents,
+ 	size_t			length,
+-	unsigned		mem_flags
++	gfp_t			mem_flags
+ )
+ {
+ 	int			i;
+@@ -771,6 +787,31 @@ int usb_string(struct usb_device *dev, i
+ 	return err;
+ }
+ 
++/**
++ * usb_cache_string - read a string descriptor and cache it for later use
++ * @udev: the device whose string descriptor is being read
++ * @index: the descriptor index
++ *
++ * Returns a pointer to a kmalloc'ed buffer containing the descriptor string,
++ * or NULL if the index is 0 or the string could not be read.
++ */
++char *usb_cache_string(struct usb_device *udev, int index)
++{
++	char *buf;
++	char *smallbuf = NULL;
++	int len;
++
++	if (index > 0 && (buf = kmalloc(256, GFP_KERNEL)) != NULL) {
++		if ((len = usb_string(udev, index, buf, 256)) > 0) {
++			if ((smallbuf = kmalloc(++len, GFP_KERNEL)) == NULL)
++				return buf;
++			memcpy(smallbuf, buf, len);
++		}
++		kfree(buf);
++	}
++	return smallbuf;
++}
++
+ /*
+  * usb_get_device_descriptor - (re)reads the device descriptor (usbcore)
+  * @dev: the device whose device descriptor is being updated
+@@ -992,8 +1033,6 @@ void usb_disable_device(struct usb_devic
+ 			dev_dbg (&dev->dev, "unregistering interface %s\n",
+ 				interface->dev.bus_id);
+ 			usb_remove_sysfs_intf_files(interface);
+-			kfree(interface->cur_altsetting->string);
+-			interface->cur_altsetting->string = NULL;
+ 			device_del (&interface->dev);
+ 		}
+ 
+@@ -1133,6 +1172,8 @@ int usb_set_interface(struct usb_device 
+ 	 */
+ 
+ 	/* prevent submissions using previous endpoint settings */
++	if (device_is_registered(&iface->dev))
++		usb_remove_sysfs_intf_files(iface);
+ 	usb_disable_interface(dev, iface);
+ 
+ 	iface->cur_altsetting = alt;
+@@ -1168,6 +1209,8 @@ int usb_set_interface(struct usb_device 
+ 	 * (Likewise, EP0 never "halts" on well designed devices.)
+ 	 */
+ 	usb_enable_interface(dev, iface);
++	if (device_is_registered(&iface->dev))
++		usb_create_sysfs_intf_files(iface);
+ 
+ 	return 0;
+ }
+@@ -1217,10 +1260,8 @@ int usb_reset_configuration(struct usb_d
+ 			USB_REQ_SET_CONFIGURATION, 0,
+ 			config->desc.bConfigurationValue, 0,
+ 			NULL, 0, USB_CTRL_SET_TIMEOUT);
+-	if (retval < 0) {
+-		usb_set_device_state(dev, USB_STATE_ADDRESS);
++	if (retval < 0)
+ 		return retval;
+-	}
+ 
+ 	dev->toggle[0] = dev->toggle[1] = 0;
+ 
+@@ -1229,6 +1270,8 @@ int usb_reset_configuration(struct usb_d
+ 		struct usb_interface *intf = config->interface[i];
+ 		struct usb_host_interface *alt;
+ 
++		if (device_is_registered(&intf->dev))
++			usb_remove_sysfs_intf_files(intf);
+ 		alt = usb_altnum_to_altsetting(intf, 0);
+ 
+ 		/* No altsetting 0?  We'll assume the first altsetting.
+@@ -1241,6 +1284,8 @@ int usb_reset_configuration(struct usb_d
+ 
+ 		intf->cur_altsetting = alt;
+ 		usb_enable_interface(dev, intf);
++		if (device_is_registered(&intf->dev))
++			usb_create_sysfs_intf_files(intf);
+ 	}
+ 	return 0;
+ }
+@@ -1328,7 +1373,7 @@ int usb_set_configuration(struct usb_dev
+ 		}
+ 
+ 		for (; n < nintf; ++n) {
+-			new_interfaces[n] = kmalloc(
++			new_interfaces[n] = kzalloc(
+ 					sizeof(struct usb_interface),
+ 					GFP_KERNEL);
+ 			if (!new_interfaces[n]) {
+@@ -1369,7 +1414,6 @@ free_interfaces:
+ 			struct usb_host_interface *alt;
+ 
+ 			cp->interface[i] = intf = new_interfaces[i];
+-			memset(intf, 0, sizeof(*intf));
+ 			intfc = cp->intf_cache[i];
+ 			intf->altsetting = intfc->altsetting;
+ 			intf->num_altsetting = intfc->num_altsetting;
+@@ -1393,6 +1437,7 @@ free_interfaces:
+ 			intf->dev.dma_mask = dev->dev.dma_mask;
+ 			intf->dev.release = release_interface;
+ 			device_initialize (&intf->dev);
++			mark_quiesced(intf);
+ 			sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
+ 				 dev->bus->busnum, dev->devpath,
+ 				 configuration,
+@@ -1400,12 +1445,9 @@ free_interfaces:
+ 		}
+ 		kfree(new_interfaces);
+ 
+-		if ((cp->desc.iConfiguration) &&
+-		    (cp->string == NULL)) {
+-			cp->string = kmalloc(256, GFP_KERNEL);
+-			if (cp->string)
+-				usb_string(dev, cp->desc.iConfiguration, cp->string, 256);
+-		}
++		if (cp->string == NULL)
++			cp->string = usb_cache_string(dev,
++					cp->desc.iConfiguration);
+ 
+ 		/* Now that all the interfaces are set up, register them
+ 		 * to trigger binding of drivers to interfaces.  probe()
+@@ -1415,13 +1457,12 @@ free_interfaces:
+ 		 */
+ 		for (i = 0; i < nintf; ++i) {
+ 			struct usb_interface *intf = cp->interface[i];
+-			struct usb_interface_descriptor *desc;
++			struct usb_host_interface *alt = intf->cur_altsetting;
+ 
+-			desc = &intf->altsetting [0].desc;
+ 			dev_dbg (&dev->dev,
+ 				"adding %s (config #%d, interface %d)\n",
+ 				intf->dev.bus_id, configuration,
+-				desc->bInterfaceNumber);
++				alt->desc.bInterfaceNumber);
+ 			ret = device_add (&intf->dev);
+ 			if (ret != 0) {
+ 				dev_err(&dev->dev,
+@@ -1430,13 +1471,6 @@ free_interfaces:
+ 					ret);
+ 				continue;
+ 			}
+-			if ((intf->cur_altsetting->desc.iInterface) &&
+-			    (intf->cur_altsetting->string == NULL)) {
+-				intf->cur_altsetting->string = kmalloc(256, GFP_KERNEL);
+-				if (intf->cur_altsetting->string)
+-					usb_string(dev, intf->cur_altsetting->desc.iInterface,
+-						   intf->cur_altsetting->string, 256);
+-			}
+ 			usb_create_sysfs_intf_files (intf);
+ 		}
+ 	}
+diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/usb/core/notify.c
+@@ -0,0 +1,120 @@
++/*
++ * All the USB notify logic
++ *
++ * (C) Copyright 2005 Greg Kroah-Hartman <gregkh at suse.de>
++ *
++ * notifier functions originally based on those in kernel/sys.c
++ * but fixed up to not be so broken.
++ *
++ */
++
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/notifier.h>
++#ifdef CONFIG_USB_DEBUG
++	#define DEBUG
++#else
++	#undef DEBUG
++#endif
++#include <linux/usb.h>
++
++#include "usb.h"
++
++
++static struct notifier_block *usb_notifier_list;
++static DECLARE_MUTEX(usb_notifier_lock);
++
++static void usb_notifier_chain_register(struct notifier_block **list,
++					struct notifier_block *n)
++{
++	down(&usb_notifier_lock);
++	while (*list) {
++		if (n->priority > (*list)->priority)
++			break;
++		list = &((*list)->next);
++	}
++	n->next = *list;
++	*list = n;
++	up(&usb_notifier_lock);
++}
++
++static void usb_notifier_chain_unregister(struct notifier_block **nl,
++				   struct notifier_block *n)
++{
++	down(&usb_notifier_lock);
++	while ((*nl)!=NULL) {
++		if ((*nl)==n) {
++			*nl = n->next;
++			goto exit;
++		}
++		nl=&((*nl)->next);
++	}
++exit:
++	up(&usb_notifier_lock);
++}
++
++static int usb_notifier_call_chain(struct notifier_block **n,
++				   unsigned long val, void *v)
++{
++	int ret=NOTIFY_DONE;
++	struct notifier_block *nb = *n;
++
++	down(&usb_notifier_lock);
++	while (nb) {
++		ret = nb->notifier_call(nb,val,v);
++		if (ret&NOTIFY_STOP_MASK) {
++			goto exit;
++		}
++		nb = nb->next;
++	}
++exit:
++	up(&usb_notifier_lock);
++	return ret;
++}
++
++/**
++ * usb_register_notify - register a notifier callback whenever a usb change happens
++ * @nb: pointer to the notifier block for the callback events.
++ *
++ * These changes are either USB devices or busses being added or removed.
++ */
++void usb_register_notify(struct notifier_block *nb)
++{
++	usb_notifier_chain_register(&usb_notifier_list, nb);
++}
++EXPORT_SYMBOL_GPL(usb_register_notify);
++
++/**
++ * usb_unregister_notify - unregister a notifier callback
++ * @nb: pointer to the notifier block for the callback events.
++ *
++ * usb_register_notifier() must have been previously called for this function
++ * to work properly.
++ */
++void usb_unregister_notify(struct notifier_block *nb)
++{
++	usb_notifier_chain_unregister(&usb_notifier_list, nb);
++}
++EXPORT_SYMBOL_GPL(usb_unregister_notify);
++
++
++void usb_notify_add_device(struct usb_device *udev)
++{
++	usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev);
++}
++
++void usb_notify_remove_device(struct usb_device *udev)
++{
++	usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev);
++}
++
++void usb_notify_add_bus(struct usb_bus *ubus)
++{
++	usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus);
++}
++
++void usb_notify_remove_bus(struct usb_bus *ubus)
++{
++	usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus);
++}
+diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
+--- a/drivers/usb/core/sysfs.c
++++ b/drivers/usb/core/sysfs.c
+@@ -22,9 +22,207 @@
+ 
+ #include "usb.h"
+ 
++/* endpoint stuff */
++struct ep_object {
++	struct usb_endpoint_descriptor *desc;
++	struct usb_device *udev;
++	struct kobject kobj;
++};
++#define to_ep_object(_kobj) \
++	container_of(_kobj, struct ep_object, kobj)
++
++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 EP_ATTR(_name)						\
++struct ep_attribute ep_##_name = {				\
++	.attr = {.name = #_name, .owner = THIS_MODULE,		\
++			.mode = S_IRUGO},			\
++	.show = show_ep_##_name}
++
++#define usb_ep_attr(field, format_string)			\
++static ssize_t show_ep_##field(struct usb_device *udev,		\
++		struct usb_endpoint_descriptor *desc, 		\
++		char *buf)					\
++{								\
++	return sprintf(buf, format_string, desc->field);	\
++}								\
++static EP_ATTR(field);
++
++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 usb_device *udev,
++		struct usb_endpoint_descriptor *desc, char *buf)
++{
++	return sprintf(buf, "%04x\n",
++			le16_to_cpu(desc->wMaxPacketSize) & 0x07ff);
++}
++static EP_ATTR(wMaxPacketSize);
++
++static ssize_t show_ep_type(struct usb_device *udev,
++		struct usb_endpoint_descriptor *desc, char *buf)
++{
++	char *type = "unknown";
++
++	switch (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 EP_ATTR(type);
++
++static ssize_t show_ep_interval(struct usb_device *udev,
++		struct usb_endpoint_descriptor *desc, char *buf)
++{
++	char unit;
++	unsigned interval = 0;
++	unsigned in;
++
++	in = (desc->bEndpointAddress & USB_DIR_IN);
++
++	switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
++	case USB_ENDPOINT_XFER_CONTROL:
++		if (udev->speed == USB_SPEED_HIGH) 	/* uframes per NAK */
++			interval = desc->bInterval;
++		break;
++	case USB_ENDPOINT_XFER_ISOC:
++		interval = 1 << (desc->bInterval - 1);
++		break;
++	case USB_ENDPOINT_XFER_BULK:
++		if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */
++			interval = desc->bInterval;
++		break;
++	case USB_ENDPOINT_XFER_INT:
++		if (udev->speed == USB_SPEED_HIGH)
++			interval = 1 << (desc->bInterval - 1);
++		else
++			interval = desc->bInterval;
++		break;
++	}
++	interval *= (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 EP_ATTR(interval);
++
++static ssize_t show_ep_direction(struct usb_device *udev,
++		struct usb_endpoint_descriptor *desc, char *buf)
++{
++	char *direction;
++
++	if ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
++			USB_ENDPOINT_XFER_CONTROL)
++		direction = "both";
++	else if (desc->bEndpointAddress & USB_DIR_IN)
++		direction = "in";
++	else
++		direction = "out";
++	return sprintf(buf, "%s\n", direction);
++}
++static EP_ATTR(direction);
++
++static struct attribute *ep_attrs[] = {
++	&ep_bLength.attr,
++	&ep_bEndpointAddress.attr,
++	&ep_bmAttributes.attr,
++	&ep_bInterval.attr,
++	&ep_wMaxPacketSize.attr,
++	&ep_type.attr,
++	&ep_interval.attr,
++	&ep_direction.attr,
++	NULL,
++};
++
++static void ep_object_release(struct kobject *kobj)
++{
++	kfree(to_ep_object(kobj));
++}
++
++static ssize_t ep_object_show(struct kobject *kobj, struct attribute *attr,
++		char *buf)
++{
++	struct ep_object *ep_obj = to_ep_object(kobj);
++	struct ep_attribute *ep_attr = to_ep_attribute(attr);
++
++	return (ep_attr->show)(ep_obj->udev, ep_obj->desc, buf);
++}
++
++static struct sysfs_ops ep_object_sysfs_ops = {
++	.show =			ep_object_show,
++};
++
++static struct kobj_type ep_object_ktype = {
++	.release =		ep_object_release,
++	.sysfs_ops =		&ep_object_sysfs_ops,
++	.default_attrs =	ep_attrs,
++};
++
++static void usb_create_ep_files(struct kobject *parent,
++		struct usb_host_endpoint *endpoint,
++		struct usb_device *udev)
++{
++	struct ep_object *ep_obj;
++	struct kobject *kobj;
++
++	ep_obj = kzalloc(sizeof(struct ep_object), GFP_KERNEL);
++	if (!ep_obj)
++		return;
++
++	ep_obj->desc = &endpoint->desc;
++	ep_obj->udev = udev;
++
++	kobj = &ep_obj->kobj;
++	kobject_set_name(kobj, "ep_%02x", endpoint->desc.bEndpointAddress);
++	kobj->parent = parent;
++	kobj->ktype = &ep_object_ktype;
++
++	/* Don't use kobject_register, because it generates a hotplug event */
++	kobject_init(kobj);
++	if (kobject_add(kobj) == 0)
++		endpoint->kobj = kobj;
++	else
++		kobject_put(kobj);
++}
++
++static void usb_remove_ep_files(struct usb_host_endpoint *endpoint)
++{
++
++	if (endpoint->kobj) {
++		kobject_del(endpoint->kobj);
++		kobject_put(endpoint->kobj);
++		endpoint->kobj = NULL;
++	}
++}
++
+ /* Active configuration fields */
+ #define usb_actconfig_show(field, multiplier, format_string)		\
+-static ssize_t  show_##field (struct device *dev, struct device_attribute *attr, char *buf)		\
++static ssize_t  show_##field (struct device *dev,			\
++		struct device_attribute *attr, char *buf)		\
+ {									\
+ 	struct usb_device *udev;					\
+ 	struct usb_host_config *actconfig;				\
+@@ -46,22 +244,17 @@ usb_actconfig_attr (bNumInterfaces, 1, "
+ usb_actconfig_attr (bmAttributes, 1, "%2x\n")
+ usb_actconfig_attr (bMaxPower, 2, "%3dmA\n")
+ 
+-static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf)
++static ssize_t show_configuration_string(struct device *dev,
++		struct device_attribute *attr, char *buf)
+ {
+ 	struct usb_device *udev;
+ 	struct usb_host_config *actconfig;
+-	int len;
+ 
+ 	udev = to_usb_device (dev);
+ 	actconfig = udev->actconfig;
+ 	if ((!actconfig) || (!actconfig->string))
+ 		return 0;
+-	len = sprintf(buf, actconfig->string, PAGE_SIZE);
+-	if (len < 0)
+-		return 0;
+-	buf[len] = '\n';
+-	buf[len+1] = 0;
+-	return len+1;
++	return sprintf(buf, "%s\n", actconfig->string);
+ }
+ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL);
+ 
+@@ -69,7 +262,8 @@ static DEVICE_ATTR(configuration, S_IRUG
+ usb_actconfig_show(bConfigurationValue, 1, "%u\n");
+ 
+ static ssize_t
+-set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++set_bConfigurationValue (struct device *dev, struct device_attribute *attr,
++		const char *buf, size_t count)
+ {
+ 	struct usb_device	*udev = udev = to_usb_device (dev);
+ 	int			config, value;
+@@ -87,18 +281,13 @@ static DEVICE_ATTR(bConfigurationValue, 
+ 
+ /* String fields */
+ #define usb_string_attr(name)						\
+-static ssize_t  show_##name(struct device *dev, struct device_attribute *attr, char *buf)		\
++static ssize_t  show_##name(struct device *dev,				\
++		struct device_attribute *attr, char *buf)		\
+ {									\
+ 	struct usb_device *udev;					\
+-	int len;							\
+ 									\
+ 	udev = to_usb_device (dev);					\
+-	len = snprintf(buf, 256, "%s", udev->name);			\
+-	if (len < 0)							\
+-		return 0;						\
+-	buf[len] = '\n';						\
+-	buf[len+1] = 0;							\
+-	return len+1;							\
++	return sprintf(buf, "%s\n", udev->name);			\
+ }									\
+ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
+ 
+@@ -167,7 +356,8 @@ static DEVICE_ATTR(maxchild, S_IRUGO, sh
+ /* Descriptor fields */
+ #define usb_descriptor_attr_le16(field, format_string)			\
+ static ssize_t								\
+-show_##field (struct device *dev, struct device_attribute *attr, char *buf)				\
++show_##field (struct device *dev, struct device_attribute *attr,	\
++		char *buf)						\
+ {									\
+ 	struct usb_device *udev;					\
+ 									\
+@@ -183,7 +373,8 @@ usb_descriptor_attr_le16(bcdDevice, "%04
+ 
+ #define usb_descriptor_attr(field, format_string)			\
+ static ssize_t								\
+-show_##field (struct device *dev, struct device_attribute *attr, char *buf)				\
++show_##field (struct device *dev, struct device_attribute *attr,	\
++		char *buf)						\
+ {									\
+ 	struct usb_device *udev;					\
+ 									\
+@@ -236,19 +427,21 @@ void usb_create_sysfs_dev_files (struct 
+ 	if (udev->serial)
+ 		device_create_file (dev, &dev_attr_serial);
+ 	device_create_file (dev, &dev_attr_configuration);
++	usb_create_ep_files(&dev->kobj, &udev->ep0, udev);
+ }
+ 
+ void usb_remove_sysfs_dev_files (struct usb_device *udev)
+ {
+ 	struct device *dev = &udev->dev;
+ 
++	usb_remove_ep_files(&udev->ep0);
+ 	sysfs_remove_group(&dev->kobj, &dev_attr_grp);
+ 
+-	if (udev->descriptor.iManufacturer)
++	if (udev->manufacturer)
+ 		device_remove_file(dev, &dev_attr_manufacturer);
+-	if (udev->descriptor.iProduct)
++	if (udev->product)
+ 		device_remove_file(dev, &dev_attr_product);
+-	if (udev->descriptor.iSerialNumber)
++	if (udev->serial)
+ 		device_remove_file(dev, &dev_attr_serial);
+ 	device_remove_file (dev, &dev_attr_configuration);
+ }
+@@ -256,11 +449,13 @@ void usb_remove_sysfs_dev_files (struct 
+ /* Interface fields */
+ #define usb_intf_attr(field, format_string)				\
+ static ssize_t								\
+-show_##field (struct device *dev, struct device_attribute *attr, char *buf)				\
++show_##field (struct device *dev, struct device_attribute *attr,	\
++		char *buf)						\
+ {									\
+ 	struct usb_interface *intf = to_usb_interface (dev);		\
+ 									\
+-	return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \
++	return sprintf (buf, format_string,				\
++			intf->cur_altsetting->desc.field); 		\
+ }									\
+ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+ 
+@@ -271,7 +466,8 @@ usb_intf_attr (bInterfaceClass, "%02x\n"
+ usb_intf_attr (bInterfaceSubClass, "%02x\n")
+ usb_intf_attr (bInterfaceProtocol, "%02x\n")
+ 
+-static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf)
++static ssize_t show_interface_string(struct device *dev,
++		struct device_attribute *attr, char *buf)
+ {
+ 	struct usb_interface *intf;
+ 	struct usb_device *udev;
+@@ -288,34 +484,28 @@ static ssize_t show_interface_string(str
+ }
+ static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL);
+ 
+-static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
++static ssize_t show_modalias(struct device *dev,
++		struct device_attribute *attr, char *buf)
+ {
+ 	struct usb_interface *intf;
+ 	struct usb_device *udev;
+-	int len;
++	struct usb_host_interface *alt;
+ 
+ 	intf = to_usb_interface(dev);
+ 	udev = interface_to_usbdev(intf);
++	alt = intf->cur_altsetting;
+ 
+-	len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic",
+-			       le16_to_cpu(udev->descriptor.idVendor),
+-			       le16_to_cpu(udev->descriptor.idProduct),
+-			       le16_to_cpu(udev->descriptor.bcdDevice),
+-			       udev->descriptor.bDeviceClass,
+-			       udev->descriptor.bDeviceSubClass,
+-			       udev->descriptor.bDeviceProtocol);
+-	buf += len;
+-
+-	if (udev->descriptor.bDeviceClass == 0) {
+-		struct usb_host_interface *alt = intf->cur_altsetting;
+-
+-		return len + sprintf(buf, "%02Xisc%02Xip%02X\n",
+-			       alt->desc.bInterfaceClass,
+-			       alt->desc.bInterfaceSubClass,
+-			       alt->desc.bInterfaceProtocol);
+- 	} else {
+-		return len + sprintf(buf, "*isc*ip*\n");
+-	}
++	return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X"
++			"ic%02Xisc%02Xip%02X\n",
++			le16_to_cpu(udev->descriptor.idVendor),
++			le16_to_cpu(udev->descriptor.idProduct),
++			le16_to_cpu(udev->descriptor.bcdDevice),
++			udev->descriptor.bDeviceClass,
++			udev->descriptor.bDeviceSubClass,
++			udev->descriptor.bDeviceProtocol,
++			alt->desc.bInterfaceClass,
++			alt->desc.bInterfaceSubClass,
++			alt->desc.bInterfaceProtocol);
+ }
+ static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
+ 
+@@ -333,20 +523,47 @@ static struct attribute_group intf_attr_
+ 	.attrs = intf_attrs,
+ };
+ 
++static inline void usb_create_intf_ep_files(struct usb_interface *intf,
++		struct usb_device *udev)
++{
++	struct usb_host_interface *iface_desc;
++	int i;
++
++	iface_desc = intf->cur_altsetting;
++	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
++		usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i],
++				udev);
++}
++
++static inline void usb_remove_intf_ep_files(struct usb_interface *intf)
++{
++	struct usb_host_interface *iface_desc;
++	int i;
++
++	iface_desc = intf->cur_altsetting;
++	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
++		usb_remove_ep_files(&iface_desc->endpoint[i]);
++}
++
+ void usb_create_sysfs_intf_files (struct usb_interface *intf)
+ {
++	struct usb_device *udev = interface_to_usbdev(intf);
++	struct usb_host_interface *alt = intf->cur_altsetting;
++
+ 	sysfs_create_group(&intf->dev.kobj, &intf_attr_grp);
+ 
+-	if (intf->cur_altsetting->string)
++	if (alt->string == NULL)
++		alt->string = usb_cache_string(udev, alt->desc.iInterface);
++	if (alt->string)
+ 		device_create_file(&intf->dev, &dev_attr_interface);
+-		
++	usb_create_intf_ep_files(intf, udev);
+ }
+ 
+ void usb_remove_sysfs_intf_files (struct usb_interface *intf)
+ {
++	usb_remove_intf_ep_files(intf);
+ 	sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
+ 
+ 	if (intf->cur_altsetting->string)
+ 		device_remove_file(&intf->dev, &dev_attr_interface);
+-
+ }
+diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
+--- a/drivers/usb/core/urb.c
++++ b/drivers/usb/core/urb.c
+@@ -60,7 +60,7 @@ void usb_init_urb(struct urb *urb)
+  *
+  * The driver must call usb_free_urb() when it is finished with the urb.
+  */
+-struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags)
++struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
+ {
+ 	struct urb *urb;
+ 
+@@ -224,7 +224,7 @@ struct urb * usb_get_urb(struct urb *urb
+  *      GFP_NOIO, unless b) or c) apply
+  *
+  */
+-int usb_submit_urb(struct urb *urb, unsigned mem_flags)
++int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
+ {
+ 	int			pipe, temp, max;
+ 	struct usb_device	*dev;
+@@ -237,7 +237,8 @@ int usb_submit_urb(struct urb *urb, unsi
+ 	    (dev->state < USB_STATE_DEFAULT) ||
+ 	    (!dev->bus) || (dev->devnum <= 0))
+ 		return -ENODEV;
+-	if (dev->state == USB_STATE_SUSPENDED)
++	if (dev->bus->controller->power.power_state.event != PM_EVENT_ON
++			|| dev->state == USB_STATE_SUSPENDED)
+ 		return -EHOSTUNREACH;
+ 	if (!(op = dev->bus->op) || !op->submit_urb)
+ 		return -ENODEV;
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -107,10 +107,19 @@ static int usb_probe_interface(struct de
+ 	id = usb_match_id (intf, driver->id_table);
+ 	if (id) {
+ 		dev_dbg (dev, "%s - got id\n", __FUNCTION__);
++
++		/* Interface "power state" doesn't correspond to any hardware
++		 * state whatsoever.  We use it to record when it's bound to
++		 * a driver that may start I/0:  it's not frozen/quiesced.
++		 */
++		mark_active(intf);
+ 		intf->condition = USB_INTERFACE_BINDING;
+ 		error = driver->probe (intf, id);
+-		intf->condition = error ? USB_INTERFACE_UNBOUND :
+-				USB_INTERFACE_BOUND;
++		if (error) {
++			mark_quiesced(intf);
++			intf->condition = USB_INTERFACE_UNBOUND;
++		} else
++			intf->condition = USB_INTERFACE_BOUND;
+ 	}
+ 
+ 	return error;
+@@ -136,6 +145,7 @@ static int usb_unbind_interface(struct d
+ 			0);
+ 	usb_set_intfdata(intf, NULL);
+ 	intf->condition = USB_INTERFACE_UNBOUND;
++	mark_quiesced(intf);
+ 
+ 	return 0;
+ }
+@@ -299,6 +309,7 @@ int usb_driver_claim_interface(struct us
+ 	dev->driver = &driver->driver;
+ 	usb_set_intfdata(iface, priv);
+ 	iface->condition = USB_INTERFACE_BOUND;
++	mark_active(iface);
+ 
+ 	/* if interface was already added, bind now; else let
+ 	 * the future device_add() bind it, bypassing probe()
+@@ -345,6 +356,7 @@ void usb_driver_release_interface(struct
+ 	dev->driver = NULL;
+ 	usb_set_intfdata(iface, NULL);
+ 	iface->condition = USB_INTERFACE_UNBOUND;
++	mark_quiesced(iface);
+ }
+ 
+ /**
+@@ -557,6 +569,7 @@ static int usb_hotplug (struct device *d
+ {
+ 	struct usb_interface *intf;
+ 	struct usb_device *usb_dev;
++	struct usb_host_interface *alt;
+ 	int i = 0;
+ 	int length = 0;
+ 
+@@ -573,7 +586,8 @@ static int usb_hotplug (struct device *d
+ 
+ 	intf = to_usb_interface(dev);
+ 	usb_dev = interface_to_usbdev (intf);
+-	
++	alt = intf->cur_altsetting;
++
+ 	if (usb_dev->devnum < 0) {
+ 		pr_debug ("usb %s: already deleted?\n", dev->bus_id);
+ 		return -ENODEV;
+@@ -615,46 +629,27 @@ static int usb_hotplug (struct device *d
+ 				usb_dev->descriptor.bDeviceProtocol))
+ 		return -ENOMEM;
+ 
+-	if (usb_dev->descriptor.bDeviceClass == 0) {
+-		struct usb_host_interface *alt = intf->cur_altsetting;
++	if (add_hotplug_env_var(envp, num_envp, &i,
++				buffer, buffer_size, &length,
++				"INTERFACE=%d/%d/%d",
++				alt->desc.bInterfaceClass,
++				alt->desc.bInterfaceSubClass,
++				alt->desc.bInterfaceProtocol))
++		return -ENOMEM;
+ 
+-		/* 2.4 only exposed interface zero.  in 2.5, hotplug
+-		 * agents are called for all interfaces, and can use
+-		 * $DEVPATH/bInterfaceNumber if necessary.
+-		 */
+-		if (add_hotplug_env_var(envp, num_envp, &i,
+-					buffer, buffer_size, &length,
+-					"INTERFACE=%d/%d/%d",
+-					alt->desc.bInterfaceClass,
+-					alt->desc.bInterfaceSubClass,
+-					alt->desc.bInterfaceProtocol))
+-			return -ENOMEM;
+-
+-		if (add_hotplug_env_var(envp, num_envp, &i,
+-					buffer, buffer_size, &length,
+-					"MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+-					le16_to_cpu(usb_dev->descriptor.idVendor),
+-					le16_to_cpu(usb_dev->descriptor.idProduct),
+-					le16_to_cpu(usb_dev->descriptor.bcdDevice),
+-					usb_dev->descriptor.bDeviceClass,
+-					usb_dev->descriptor.bDeviceSubClass,
+-					usb_dev->descriptor.bDeviceProtocol,
+-					alt->desc.bInterfaceClass,
+-					alt->desc.bInterfaceSubClass,
+-					alt->desc.bInterfaceProtocol))
+-			return -ENOMEM;
+- 	} else {
+-		if (add_hotplug_env_var(envp, num_envp, &i,
+-					buffer, buffer_size, &length,
+-					"MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*",
+-					le16_to_cpu(usb_dev->descriptor.idVendor),
+-					le16_to_cpu(usb_dev->descriptor.idProduct),
+-					le16_to_cpu(usb_dev->descriptor.bcdDevice),
+-					usb_dev->descriptor.bDeviceClass,
+-					usb_dev->descriptor.bDeviceSubClass,
+-					usb_dev->descriptor.bDeviceProtocol))
+-			return -ENOMEM;
+-	}
++	if (add_hotplug_env_var(envp, num_envp, &i,
++				buffer, buffer_size, &length,
++				"MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
++				le16_to_cpu(usb_dev->descriptor.idVendor),
++				le16_to_cpu(usb_dev->descriptor.idProduct),
++				le16_to_cpu(usb_dev->descriptor.bcdDevice),
++				usb_dev->descriptor.bDeviceClass,
++				usb_dev->descriptor.bDeviceSubClass,
++				usb_dev->descriptor.bDeviceProtocol,
++				alt->desc.bInterfaceClass,
++				alt->desc.bInterfaceSubClass,
++				alt->desc.bInterfaceProtocol))
++		return -ENOMEM;
+ 
+ 	envp[i] = NULL;
+ 
+@@ -709,12 +704,10 @@ usb_alloc_dev(struct usb_device *parent,
+ {
+ 	struct usb_device *dev;
+ 
+-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
++	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ 	if (!dev)
+ 		return NULL;
+ 
+-	memset(dev, 0, sizeof(*dev));
+-
+ 	bus = usb_bus_get(bus);
+ 	if (!bus) {
+ 		kfree(dev);
+@@ -1147,7 +1140,7 @@ int __usb_get_extra_descriptor(char *buf
+ void *usb_buffer_alloc (
+ 	struct usb_device *dev,
+ 	size_t size,
+-	unsigned mem_flags,
++	gfp_t mem_flags,
+ 	dma_addr_t *dma
+ )
+ {
+@@ -1402,13 +1395,30 @@ void usb_buffer_unmap_sg (struct usb_dev
+ 			usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ }
+ 
+-static int usb_generic_suspend(struct device *dev, pm_message_t message)
++static int verify_suspended(struct device *dev, void *unused)
+ {
+-	struct usb_interface *intf;
+-	struct usb_driver *driver;
++	return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0;
++}
+ 
+-	if (dev->driver == &usb_generic_driver)
+-		return usb_suspend_device (to_usb_device(dev), message);
++static int usb_generic_suspend(struct device *dev, pm_message_t message)
++{
++	struct usb_interface	*intf;
++	struct usb_driver	*driver;
++	int			status;
++
++	/* USB devices enter SUSPEND state through their hubs, but can be
++	 * marked for FREEZE as soon as their children are already idled.
++	 * But those semantics are useless, so we equate the two (sigh).
++	 */
++	if (dev->driver == &usb_generic_driver) {
++		if (dev->power.power_state.event == message.event)
++			return 0;
++		/* we need to rule out bogus requests through sysfs */
++		status = device_for_each_child(dev, NULL, verify_suspended);
++		if (status)
++			return status;
++ 		return usb_suspend_device (to_usb_device(dev));
++	}
+ 
+ 	if ((dev->driver == NULL) ||
+ 	    (dev->driver_data == &usb_generic_driver_data))
+@@ -1417,23 +1427,44 @@ static int usb_generic_suspend(struct de
+ 	intf = to_usb_interface(dev);
+ 	driver = to_usb_driver(dev->driver);
+ 
+-	/* there's only one USB suspend state */
+-	if (intf->dev.power.power_state.event)
++	/* with no hardware, USB interfaces only use FREEZE and ON states */
++	if (!is_active(intf))
+ 		return 0;
+ 
+-	if (driver->suspend)
+-		return driver->suspend(intf, message);
+-	return 0;
++	if (driver->suspend && driver->resume) {
++		status = driver->suspend(intf, message);
++		if (status)
++			dev_err(dev, "%s error %d\n", "suspend", status);
++		else
++			mark_quiesced(intf);
++	} else {
++		// FIXME else if there's no suspend method, disconnect...
++		dev_warn(dev, "no %s?\n", "suspend");
++		status = 0;
++	}
++	return status;
+ }
+ 
+ static int usb_generic_resume(struct device *dev)
+ {
+-	struct usb_interface *intf;
+-	struct usb_driver *driver;
++	struct usb_interface	*intf;
++	struct usb_driver	*driver;
++	struct usb_device	*udev;
++	int			status;
+ 
+-	/* devices resume through their hub */
+-	if (dev->driver == &usb_generic_driver)
++	if (dev->power.power_state.event == PM_EVENT_ON)
++		return 0;
++
++	/* mark things as "on" immediately, no matter what errors crop up */
++	dev->power.power_state.event = PM_EVENT_ON;
++
++	/* devices resume through their hubs */
++	if (dev->driver == &usb_generic_driver) {
++		udev = to_usb_device(dev);
++		if (udev->state == USB_STATE_NOTATTACHED)
++			return 0;
+ 		return usb_resume_device (to_usb_device(dev));
++	}
+ 
+ 	if ((dev->driver == NULL) ||
+ 	    (dev->driver_data == &usb_generic_driver_data))
+@@ -1442,8 +1473,22 @@ static int usb_generic_resume(struct dev
+ 	intf = to_usb_interface(dev);
+ 	driver = to_usb_driver(dev->driver);
+ 
+-	if (driver->resume)
+-		return driver->resume(intf);
++	udev = interface_to_usbdev(intf);
++	if (udev->state == USB_STATE_NOTATTACHED)
++		return 0;
++
++	/* if driver was suspended, it has a resume method;
++	 * however, sysfs can wrongly mark things as suspended
++	 * (on the "no suspend method" FIXME path above)
++	 */
++	if (driver->resume) {
++		status = driver->resume(intf);
++		if (status) {
++			dev_err(dev, "%s error %d\n", "resume", status);
++			mark_quiesced(intf);
++		}
++	} else
++		dev_warn(dev, "no %s?\n", "resume");
+ 	return 0;
+ }
+ 
+diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
+--- a/drivers/usb/core/usb.h
++++ b/drivers/usb/core/usb.h
+@@ -13,12 +13,14 @@ extern void usb_disable_device (struct u
+ 
+ extern int usb_get_device_descriptor(struct usb_device *dev,
+ 		unsigned int size);
++extern char *usb_cache_string(struct usb_device *udev, int index);
+ extern int usb_set_configuration(struct usb_device *dev, int configuration);
+ 
+ extern void usb_lock_all_devices(void);
+ extern void usb_unlock_all_devices(void);
+ 
+ extern void usb_kick_khubd(struct usb_device *dev);
++extern void usb_suspend_root_hub(struct usb_device *hdev);
+ extern void usb_resume_root_hub(struct usb_device *dev);
+ 
+ extern int  usb_hub_init(void);
+@@ -28,6 +30,28 @@ extern void usb_major_cleanup(void);
+ extern int usb_host_init(void);
+ extern void usb_host_cleanup(void);
+ 
++extern int usb_suspend_device(struct usb_device *dev);
++extern int usb_resume_device(struct usb_device *dev);
++
++
++/* Interfaces and their "power state" are owned by usbcore */
++
++static inline void mark_active(struct usb_interface *f)
++{
++	f->dev.power.power_state.event = PM_EVENT_ON;
++}
++
++static inline void mark_quiesced(struct usb_interface *f)
++{
++	f->dev.power.power_state.event = PM_EVENT_FREEZE;
++}
++
++static inline int is_active(struct usb_interface *f)
++{
++	return f->dev.power.power_state.event == PM_EVENT_ON;
++}
++
++
+ /* for labeling diagnostics */
+ extern const char *usbcore_name;
+ 
+@@ -39,9 +63,6 @@ extern void usbfs_conn_disc_event(void);
+ 
+ extern int usbdev_init(void);
+ extern void usbdev_cleanup(void);
+-extern void usbdev_add(struct usb_device *dev);
+-extern void usbdev_remove(struct usb_device *dev);
+-extern struct usb_device *usbdev_lookup_minor(int minor);
+ 
+ struct dev_state {
+ 	struct list_head list;      /* state list */
+@@ -58,3 +79,9 @@ struct dev_state {
+ 	unsigned long ifclaimed;
+ };
+ 
++/* internal notify stuff */
++extern void usb_notify_add_device(struct usb_device *udev);
++extern void usb_notify_remove_device(struct usb_device *udev);
++extern void usb_notify_add_bus(struct usb_bus *ubus);
++extern void usb_notify_remove_bus(struct usb_bus *ubus);
++
+diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
+--- a/drivers/usb/gadget/dummy_hcd.c
++++ b/drivers/usb/gadget/dummy_hcd.c
+@@ -50,7 +50,7 @@
+ #include <linux/list.h>
+ #include <linux/interrupt.h>
+ #include <linux/version.h>
+-
++#include <linux/platform_device.h>
+ #include <linux/usb.h>
+ #include <linux/usb_gadget.h>
+ 
+@@ -470,7 +470,7 @@ static int dummy_disable (struct usb_ep 
+ }
+ 
+ static struct usb_request *
+-dummy_alloc_request (struct usb_ep *_ep, unsigned mem_flags)
++dummy_alloc_request (struct usb_ep *_ep, gfp_t mem_flags)
+ {
+ 	struct dummy_ep		*ep;
+ 	struct dummy_request	*req;
+@@ -507,7 +507,7 @@ dummy_alloc_buffer (
+ 	struct usb_ep *_ep,
+ 	unsigned bytes,
+ 	dma_addr_t *dma,
+-	unsigned mem_flags
++	gfp_t mem_flags
+ ) {
+ 	char			*retval;
+ 	struct dummy_ep		*ep;
+@@ -541,7 +541,7 @@ fifo_complete (struct usb_ep *ep, struct
+ 
+ static int
+ dummy_queue (struct usb_ep *_ep, struct usb_request *_req,
+-		unsigned mem_flags)
++		gfp_t mem_flags)
+ {
+ 	struct dummy_ep		*ep;
+ 	struct dummy_request	*req;
+@@ -935,14 +935,10 @@ static int dummy_udc_remove (struct devi
+ 	return 0;
+ }
+ 
+-static int dummy_udc_suspend (struct device *dev, pm_message_t state,
+-		u32 level)
++static int dummy_udc_suspend (struct device *dev, pm_message_t state)
+ {
+ 	struct dummy	*dum = dev_get_drvdata(dev);
+ 
+-	if (level != SUSPEND_DISABLE)
+-		return 0;
+-
+ 	dev_dbg (dev, "%s\n", __FUNCTION__);
+ 	spin_lock_irq (&dum->lock);
+ 	dum->udc_suspended = 1;
+@@ -954,13 +950,10 @@ static int dummy_udc_suspend (struct dev
+ 	return 0;
+ }
+ 
+-static int dummy_udc_resume (struct device *dev, u32 level)
++static int dummy_udc_resume (struct device *dev)
+ {
+ 	struct dummy	*dum = dev_get_drvdata(dev);
+ 
+-	if (level != RESUME_ENABLE)
+-		return 0;
+-
+ 	dev_dbg (dev, "%s\n", __FUNCTION__);
+ 	spin_lock_irq (&dum->lock);
+ 	dum->udc_suspended = 0;
+@@ -974,6 +967,7 @@ static int dummy_udc_resume (struct devi
+ 
+ static struct device_driver dummy_udc_driver = {
+ 	.name		= (char *) gadget_name,
++	.owner		= THIS_MODULE,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= dummy_udc_probe,
+ 	.remove		= dummy_udc_remove,
+@@ -999,7 +993,7 @@ static int dummy_urb_enqueue (
+ 	struct usb_hcd			*hcd,
+ 	struct usb_host_endpoint	*ep,
+ 	struct urb			*urb,
+-	unsigned			mem_flags
++	gfp_t				mem_flags
+ ) {
+ 	struct dummy	*dum;
+ 	struct urbp	*urbp;
+@@ -1758,7 +1752,7 @@ static int dummy_hub_control (
+ 	return retval;
+ }
+ 
+-static int dummy_hub_suspend (struct usb_hcd *hcd)
++static int dummy_bus_suspend (struct usb_hcd *hcd)
+ {
+ 	struct dummy *dum = hcd_to_dummy (hcd);
+ 
+@@ -1769,7 +1763,7 @@ static int dummy_hub_suspend (struct usb
+ 	return 0;
+ }
+ 
+-static int dummy_hub_resume (struct usb_hcd *hcd)
++static int dummy_bus_resume (struct usb_hcd *hcd)
+ {
+ 	struct dummy *dum = hcd_to_dummy (hcd);
+ 
+@@ -1901,8 +1895,8 @@ static const struct hc_driver dummy_hcd 
+ 
+ 	.hub_status_data = 	dummy_hub_status,
+ 	.hub_control = 		dummy_hub_control,
+-	.hub_suspend =		dummy_hub_suspend,
+-	.hub_resume =		dummy_hub_resume,
++	.bus_suspend =		dummy_bus_suspend,
++	.bus_resume =		dummy_bus_resume,
+ };
+ 
+ static int dummy_hcd_probe (struct device *dev)
+@@ -1936,52 +1930,32 @@ static int dummy_hcd_remove (struct devi
+ 	return 0;
+ }
+ 
+-static int dummy_hcd_suspend (struct device *dev, pm_message_t state,
+-		u32 level)
++static int dummy_hcd_suspend (struct device *dev, pm_message_t state)
+ {
+ 	struct usb_hcd		*hcd;
+ 
+-	if (level != SUSPEND_DISABLE)
+-		return 0;
+-
+ 	dev_dbg (dev, "%s\n", __FUNCTION__);
+ 	hcd = dev_get_drvdata (dev);
+ 
+-#ifndef CONFIG_USB_SUSPEND
+-	/* Otherwise this would never happen */
+-	usb_lock_device (hcd->self.root_hub);
+-	dummy_hub_suspend (hcd);
+-	usb_unlock_device (hcd->self.root_hub);
+-#endif
+-
+ 	hcd->state = HC_STATE_SUSPENDED;
+ 	return 0;
+ }
+ 
+-static int dummy_hcd_resume (struct device *dev, u32 level)
++static int dummy_hcd_resume (struct device *dev)
+ {
+ 	struct usb_hcd		*hcd;
+ 
+-	if (level != RESUME_ENABLE)
+-		return 0;
+-
+ 	dev_dbg (dev, "%s\n", __FUNCTION__);
+ 	hcd = dev_get_drvdata (dev);
+ 	hcd->state = HC_STATE_RUNNING;
+ 
+-#ifndef CONFIG_USB_SUSPEND
+-	/* Otherwise this would never happen */
+-	usb_lock_device (hcd->self.root_hub);
+-	dummy_hub_resume (hcd);
+-	usb_unlock_device (hcd->self.root_hub);
+-#endif
+-
+ 	usb_hcd_poll_rh_status (hcd);
+ 	return 0;
+ }
+ 
+ static struct device_driver dummy_hcd_driver = {
+ 	.name		= (char *) driver_name,
++	.owner		= THIS_MODULE,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= dummy_hcd_probe,
+ 	.remove		= dummy_hcd_remove,
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -945,11 +945,11 @@ config_buf (enum usb_device_speed speed,
+ 
+ /*-------------------------------------------------------------------------*/
+ 
+-static void eth_start (struct eth_dev *dev, unsigned gfp_flags);
+-static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags);
++static void eth_start (struct eth_dev *dev, gfp_t gfp_flags);
++static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags);
+ 
+ static int
+-set_ether_config (struct eth_dev *dev, unsigned gfp_flags)
++set_ether_config (struct eth_dev *dev, gfp_t gfp_flags)
+ {
+ 	int					result = 0;
+ 	struct usb_gadget			*gadget = dev->gadget;
+@@ -1081,7 +1081,7 @@ static void eth_reset_config (struct eth
+  * that returns config descriptors, and altsetting code.
+  */
+ static int
+-eth_set_config (struct eth_dev *dev, unsigned number, unsigned gfp_flags)
++eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags)
+ {
+ 	int			result = 0;
+ 	struct usb_gadget	*gadget = dev->gadget;
+@@ -1598,7 +1598,7 @@ static void defer_kevent (struct eth_dev
+ static void rx_complete (struct usb_ep *ep, struct usb_request *req);
+ 
+ static int
+-rx_submit (struct eth_dev *dev, struct usb_request *req, unsigned gfp_flags)
++rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
+ {
+ 	struct sk_buff		*skb;
+ 	int			retval = -ENOMEM;
+@@ -1724,7 +1724,7 @@ clean:
+ }
+ 
+ static int prealloc (struct list_head *list, struct usb_ep *ep,
+-			unsigned n, unsigned gfp_flags)
++			unsigned n, gfp_t gfp_flags)
+ {
+ 	unsigned		i;
+ 	struct usb_request	*req;
+@@ -1763,7 +1763,7 @@ extra:
+ 	return 0;
+ }
+ 
+-static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags)
++static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags)
+ {
+ 	int status;
+ 
+@@ -1779,7 +1779,7 @@ fail:
+ 	return status;
+ }
+ 
+-static void rx_fill (struct eth_dev *dev, unsigned gfp_flags)
++static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags)
+ {
+ 	struct usb_request	*req;
+ 	unsigned long		flags;
+@@ -1962,7 +1962,7 @@ drop:
+  * normally just one notification will be queued.
+  */
+ 
+-static struct usb_request *eth_req_alloc (struct usb_ep *, unsigned, unsigned);
++static struct usb_request *eth_req_alloc (struct usb_ep *, unsigned, gfp_t);
+ static void eth_req_free (struct usb_ep *ep, struct usb_request *req);
+ 
+ static void
+@@ -2024,7 +2024,7 @@ static int rndis_control_ack (struct net
+ 
+ #endif	/* RNDIS */
+ 
+-static void eth_start (struct eth_dev *dev, unsigned gfp_flags)
++static void eth_start (struct eth_dev *dev, gfp_t gfp_flags)
+ {
+ 	DEBUG (dev, "%s\n", __FUNCTION__);
+ 
+@@ -2092,7 +2092,7 @@ static int eth_stop (struct net_device *
+ /*-------------------------------------------------------------------------*/
+ 
+ static struct usb_request *
+-eth_req_alloc (struct usb_ep *ep, unsigned size, unsigned gfp_flags)
++eth_req_alloc (struct usb_ep *ep, unsigned size, gfp_t gfp_flags)
+ {
+ 	struct usb_request	*req;
+ 
+@@ -2533,6 +2533,7 @@ static struct usb_gadget_driver eth_driv
+ 
+ 	.driver 	= {
+ 		.name		= (char *) shortname,
++		.owner		= THIS_MODULE,
+ 		// .shutdown = ...
+ 		// .suspend = ...
+ 		// .resume = ...
+diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
+--- a/drivers/usb/gadget/file_storage.c
++++ b/drivers/usb/gadget/file_storage.c
+@@ -224,6 +224,7 @@
+ #include <linux/fs.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
++#include <linux/kthread.h>
+ #include <linux/limits.h>
+ #include <linux/list.h>
+ #include <linux/module.h>
+@@ -669,7 +670,6 @@ struct fsg_dev {
+ 	wait_queue_head_t	thread_wqh;
+ 	int			thread_wakeup_needed;
+ 	struct completion	thread_notifier;
+-	int			thread_pid;
+ 	struct task_struct	*thread_task;
+ 	sigset_t		thread_signal_mask;
+ 
+@@ -1084,7 +1084,6 @@ static void wakeup_thread(struct fsg_dev
+ static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
+ {
+ 	unsigned long		flags;
+-	struct task_struct	*thread_task;
+ 
+ 	/* Do nothing if a higher-priority exception is already in progress.
+ 	 * If a lower-or-equal priority exception is in progress, preempt it
+@@ -1093,9 +1092,9 @@ static void raise_exception(struct fsg_d
+ 	if (fsg->state <= new_state) {
+ 		fsg->exception_req_tag = fsg->ep0_req_tag;
+ 		fsg->state = new_state;
+-		thread_task = fsg->thread_task;
+-		if (thread_task)
+-			send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task);
++		if (fsg->thread_task)
++			send_sig_info(SIGUSR1, SEND_SIG_FORCED,
++					fsg->thread_task);
+ 	}
+ 	spin_unlock_irqrestore(&fsg->lock, flags);
+ }
+@@ -3383,11 +3382,6 @@ static int fsg_main_thread(void *fsg_)
+ {
+ 	struct fsg_dev		*fsg = (struct fsg_dev *) fsg_;
+ 
+-	fsg->thread_task = current;
+-
+-	/* Release all our userspace resources */
+-	daemonize("file-storage-gadget");
+-
+ 	/* Allow the thread to be killed by a signal, but set the signal mask
+ 	 * to block everything but INT, TERM, KILL, and USR1. */
+ 	siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) |
+@@ -3400,9 +3394,6 @@ static int fsg_main_thread(void *fsg_)
+ 	 * that expects a __user pointer and it will work okay. */
+ 	set_fs(get_ds());
+ 
+-	/* Wait for the gadget registration to finish up */
+-	wait_for_completion(&fsg->thread_notifier);
+-
+ 	/* The main loop */
+ 	while (fsg->state != FSG_STATE_TERMINATED) {
+ 		if (exception_in_progress(fsg) || signal_pending(current)) {
+@@ -3440,8 +3431,9 @@ static int fsg_main_thread(void *fsg_)
+ 		spin_unlock_irq(&fsg->lock);
+ 		}
+ 
++	spin_lock_irq(&fsg->lock);
+ 	fsg->thread_task = NULL;
+-	flush_signals(current);
++	spin_unlock_irq(&fsg->lock);
+ 
+ 	/* In case we are exiting because of a signal, unregister the
+ 	 * gadget driver and close the backing file. */
+@@ -3831,12 +3823,11 @@ static int __init fsg_bind(struct usb_ga
+ 
+ 	/* Create the LUNs, open their backing files, and register the
+ 	 * LUN devices in sysfs. */
+-	fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL);
++	fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL);
+ 	if (!fsg->luns) {
+ 		rc = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset(fsg->luns, 0, i * sizeof(struct lun));
+ 	fsg->nluns = i;
+ 
+ 	for (i = 0; i < fsg->nluns; ++i) {
+@@ -3959,10 +3950,12 @@ static int __init fsg_bind(struct usb_ga
+ 		sprintf(&serial[i], "%02X", c);
+ 	}
+ 
+-	if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS |
+-			CLONE_FILES))) < 0)
++	fsg->thread_task = kthread_create(fsg_main_thread, fsg,
++			"file-storage-gadget");
++	if (IS_ERR(fsg->thread_task)) {
++		rc = PTR_ERR(fsg->thread_task);
+ 		goto out;
+-	fsg->thread_pid = rc;
++	}
+ 
+ 	INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+ 	INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
+@@ -3994,7 +3987,12 @@ static int __init fsg_bind(struct usb_ga
+ 	DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
+ 			mod_data.removable, mod_data.can_stall,
+ 			mod_data.buflen);
+-	DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid);
++	DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid);
++
++	set_bit(REGISTERED, &fsg->atomic_bitflags);
++
++	/* Tell the thread to start working */
++	wake_up_process(fsg->thread_task);
+ 	return 0;
+ 
+ autoconf_fail:
+@@ -4046,6 +4044,7 @@ static struct usb_gadget_driver		fsg_dri
+ 
+ 	.driver		= {
+ 		.name		= (char *) shortname,
++		.owner		= THIS_MODULE,
+ 		// .release = ...
+ 		// .suspend = ...
+ 		// .resume = ...
+@@ -4057,10 +4056,9 @@ static int __init fsg_alloc(void)
+ {
+ 	struct fsg_dev		*fsg;
+ 
+-	fsg = kmalloc(sizeof *fsg, GFP_KERNEL);
++	fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
+ 	if (!fsg)
+ 		return -ENOMEM;
+-	memset(fsg, 0, sizeof *fsg);
+ 	spin_lock_init(&fsg->lock);
+ 	init_rwsem(&fsg->filesem);
+ 	init_waitqueue_head(&fsg->thread_wqh);
+@@ -4086,15 +4084,9 @@ static int __init fsg_init(void)
+ 	if ((rc = fsg_alloc()) != 0)
+ 		return rc;
+ 	fsg = the_fsg;
+-	if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) {
++	if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
+ 		fsg_free(fsg);
+-		return rc;
+-	}
+-	set_bit(REGISTERED, &fsg->atomic_bitflags);
+-
+-	/* Tell the thread to start working */
+-	complete(&fsg->thread_notifier);
+-	return 0;
++	return rc;
+ }
+ module_init(fsg_init);
+ 
+diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
+--- a/drivers/usb/gadget/goku_udc.c
++++ b/drivers/usb/gadget/goku_udc.c
+@@ -269,7 +269,7 @@ static int goku_ep_disable(struct usb_ep
+ /*-------------------------------------------------------------------------*/
+ 
+ static struct usb_request *
+-goku_alloc_request(struct usb_ep *_ep, unsigned gfp_flags)
++goku_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
+ {
+ 	struct goku_request	*req;
+ 
+@@ -327,7 +327,7 @@ goku_free_request(struct usb_ep *_ep, st
+  */
+ static void *
+ goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
+-			dma_addr_t *dma, unsigned gfp_flags)
++			dma_addr_t *dma, gfp_t gfp_flags)
+ {
+ 	void		*retval;
+ 	struct goku_ep	*ep;
+@@ -789,7 +789,7 @@ finished:
+ /*-------------------------------------------------------------------------*/
+ 
+ static int
+-goku_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
++goku_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+ {
+ 	struct goku_request	*req;
+ 	struct goku_ep		*ep;
+@@ -1970,6 +1970,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
+ static struct pci_driver goku_pci_driver = {
+ 	.name =		(char *) driver_name,
+ 	.id_table =	pci_ids,
++	.owner =	THIS_MODULE,
+ 
+ 	.probe =	goku_probe,
+ 	.remove =	goku_remove,
+diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
+--- a/drivers/usb/gadget/lh7a40x_udc.c
++++ b/drivers/usb/gadget/lh7a40x_udc.c
+@@ -21,6 +21,8 @@
+  *
+  */
+ 
++#include <linux/platform_device.h>
++
+ #include "lh7a40x_udc.h"
+ 
+ //#define DEBUG printk
+@@ -71,13 +73,13 @@ static char *state_names[] = {
+ static int lh7a40x_ep_enable(struct usb_ep *ep,
+ 			     const struct usb_endpoint_descriptor *);
+ static int lh7a40x_ep_disable(struct usb_ep *ep);
+-static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, int);
++static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, gfp_t);
+ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *);
+ static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned, dma_addr_t *,
+-				  int);
++				  gfp_t);
+ static void lh7a40x_free_buffer(struct usb_ep *ep, void *, dma_addr_t,
+ 				unsigned);
+-static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, int);
++static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t);
+ static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *);
+ static int lh7a40x_set_halt(struct usb_ep *ep, int);
+ static int lh7a40x_fifo_status(struct usb_ep *ep);
+@@ -1106,7 +1108,7 @@ static int lh7a40x_ep_disable(struct usb
+ }
+ 
+ static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep,
+-						 unsigned gfp_flags)
++						 gfp_t gfp_flags)
+ {
+ 	struct lh7a40x_request *req;
+ 
+@@ -1134,7 +1136,7 @@ static void lh7a40x_free_request(struct 
+ }
+ 
+ static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes,
+-				  dma_addr_t * dma, unsigned gfp_flags)
++				  dma_addr_t * dma, gfp_t gfp_flags)
+ {
+ 	char *retval;
+ 
+@@ -1158,7 +1160,7 @@ static void lh7a40x_free_buffer(struct u
+  *  NOTE: Sets INDEX register
+  */
+ static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req,
+-			 unsigned gfp_flags)
++			 gfp_t gfp_flags)
+ {
+ 	struct lh7a40x_request *req;
+ 	struct lh7a40x_ep *ep;
+@@ -2140,6 +2142,7 @@ static int lh7a40x_udc_remove(struct dev
+ 
+ static struct device_driver udc_driver = {
+ 	.name = (char *)driver_name,
++	.owner = THIS_MODULE,
+ 	.bus = &platform_bus_type,
+ 	.probe = lh7a40x_udc_probe,
+ 	.remove = lh7a40x_udc_remove
+diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
+--- a/drivers/usb/gadget/net2280.c
++++ b/drivers/usb/gadget/net2280.c
+@@ -376,7 +376,7 @@ static int net2280_disable (struct usb_e
+ /*-------------------------------------------------------------------------*/
+ 
+ static struct usb_request *
+-net2280_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
++net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
+ {
+ 	struct net2280_ep	*ep;
+ 	struct net2280_request	*req;
+@@ -463,7 +463,7 @@ net2280_alloc_buffer (
+ 	struct usb_ep		*_ep,
+ 	unsigned		bytes,
+ 	dma_addr_t		*dma,
+-	unsigned		gfp_flags
++	gfp_t			gfp_flags
+ )
+ {
+ 	void			*retval;
+@@ -897,7 +897,7 @@ done (struct net2280_ep *ep, struct net2
+ /*-------------------------------------------------------------------------*/
+ 
+ static int
+-net2280_queue (struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
++net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+ {
+ 	struct net2280_request	*req;
+ 	struct net2280_ep	*ep;
+@@ -2948,6 +2948,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
+ static struct pci_driver net2280_pci_driver = {
+ 	.name =		(char *) driver_name,
+ 	.id_table =	pci_ids,
++	.owner =	THIS_MODULE,
+ 
+ 	.probe =	net2280_probe,
+ 	.remove =	net2280_remove,
+diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
+--- a/drivers/usb/gadget/omap_udc.c
++++ b/drivers/usb/gadget/omap_udc.c
+@@ -38,7 +38,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/mm.h>
+ #include <linux/moduleparam.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/usb_ch9.h>
+ #include <linux/usb_gadget.h>
+ #include <linux/usb_otg.h>
+@@ -269,7 +269,7 @@ static int omap_ep_disable(struct usb_ep
+ /*-------------------------------------------------------------------------*/
+ 
+ static struct usb_request *
+-omap_alloc_request(struct usb_ep *ep, unsigned gfp_flags)
++omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
+ {
+ 	struct omap_req	*req;
+ 
+@@ -298,7 +298,7 @@ omap_alloc_buffer(
+ 	struct usb_ep	*_ep,
+ 	unsigned	bytes,
+ 	dma_addr_t	*dma,
+-	unsigned	gfp_flags
++	gfp_t		gfp_flags
+ )
+ {
+ 	void		*retval;
+@@ -691,7 +691,7 @@ static void next_out_dma(struct omap_ep 
+ }
+ 
+ static void
+-finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status)
++finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one)
+ {
+ 	u16	count;
+ 
+@@ -699,6 +699,8 @@ finish_out_dma(struct omap_ep *ep, struc
+ 		ep->dma_counter = (u16) (req->req.dma + req->req.actual);
+ 	count = dma_dest_len(ep, req->req.dma + req->req.actual);
+ 	count += req->req.actual;
++	if (one)
++		count--;
+ 	if (count <= req->req.length)
+ 		req->req.actual = count;
+ 
+@@ -747,7 +749,7 @@ static void dma_irq(struct omap_udc *udc
+ 		if (!list_empty(&ep->queue)) {
+ 			req = container_of(ep->queue.next,
+ 					struct omap_req, queue);
+-			finish_out_dma(ep, req, 0);
++			finish_out_dma(ep, req, 0, dman_stat & UDC_DMA_RX_SB);
+ 		}
+ 		UDC_IRQ_SRC_REG = UDC_RXN_EOT;
+ 
+@@ -925,7 +927,7 @@ static void dma_channel_release(struct o
+ 		while (UDC_RXDMA_CFG_REG & mask)
+ 			udelay(10);
+ 		if (req)
+-			finish_out_dma(ep, req, -ECONNRESET);
++			finish_out_dma(ep, req, -ECONNRESET, 0);
+ 	}
+ 	omap_free_dma(ep->lch);
+ 	ep->dma_channel = 0;
+@@ -937,7 +939,7 @@ static void dma_channel_release(struct o
+ /*-------------------------------------------------------------------------*/
+ 
+ static int
+-omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
++omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+ {
+ 	struct omap_ep	*ep = container_of(_ep, struct omap_ep, ep);
+ 	struct omap_req	*req = container_of(_req, struct omap_req, req);
+@@ -1786,8 +1788,12 @@ static void devstate_irq(struct omap_udc
+ 					udc->driver->suspend(&udc->gadget);
+ 					spin_lock(&udc->lock);
+ 				}
++				if (udc->transceiver)
++					otg_set_suspend(udc->transceiver, 1);
+ 			} else {
+ 				VDBG("resume\n");
++				if (udc->transceiver)
++					otg_set_suspend(udc->transceiver, 0);
+ 				if (udc->gadget.speed == USB_SPEED_FULL
+ 						&& udc->driver->resume) {
+ 					spin_unlock(&udc->lock);
+@@ -2909,12 +2915,10 @@ static int __exit omap_udc_remove(struct
+  * may involve talking to an external transceiver (e.g. isp1301).
+  */
+ 
+-static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level)
++static int omap_udc_suspend(struct device *dev, pm_message_t message)
+ {
+ 	u32	devstat;
+ 
+-	if (level != SUSPEND_POWER_DOWN)
+-		return 0;
+ 	devstat = UDC_DEVSTAT_REG;
+ 
+ 	/* we're requesting 48 MHz clock if the pullup is enabled
+@@ -2931,11 +2935,8 @@ static int omap_udc_suspend(struct devic
+ 	return 0;
+ }
+ 
+-static int omap_udc_resume(struct device *dev, u32 level)
++static int omap_udc_resume(struct device *dev)
+ {
+-	if (level != RESUME_POWER_ON)
+-		return 0;
+-
+ 	DBG("resume + wakeup/SRP\n");
+ 	omap_pullup(&udc->gadget, 1);
+ 
+@@ -2948,6 +2949,7 @@ static int omap_udc_resume(struct device
+ 
+ static struct device_driver udc_driver = {
+ 	.name		= (char *) driver_name,
++	.owner		= THIS_MODULE,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= omap_udc_probe,
+ 	.remove		= __exit_p(omap_udc_remove),
+diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
+--- a/drivers/usb/gadget/pxa2xx_udc.c
++++ b/drivers/usb/gadget/pxa2xx_udc.c
+@@ -43,7 +43,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/proc_fs.h>
+ #include <linux/mm.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ 
+ #include <asm/byteorder.h>
+@@ -332,7 +332,7 @@ static int pxa2xx_ep_disable (struct usb
+  * 	pxa2xx_ep_alloc_request - allocate a request data structure
+  */
+ static struct usb_request *
+-pxa2xx_ep_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
++pxa2xx_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
+ {
+ 	struct pxa2xx_request *req;
+ 
+@@ -367,7 +367,7 @@ pxa2xx_ep_free_request (struct usb_ep *_
+  */
+ static void *
+ pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
+-	dma_addr_t *dma, unsigned gfp_flags)
++	dma_addr_t *dma, gfp_t gfp_flags)
+ {
+ 	char			*retval;
+ 
+@@ -422,7 +422,7 @@ static inline void ep0_idle (struct pxa2
+ }
+ 
+ static int
+-write_packet(volatile unsigned long *uddr, struct pxa2xx_request *req, unsigned max)
++write_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max)
+ {
+ 	u8		*buf;
+ 	unsigned	length, count;
+@@ -874,7 +874,7 @@ done:
+ /*-------------------------------------------------------------------------*/
+ 
+ static int
+-pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
++pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+ {
+ 	struct pxa2xx_request	*req;
+ 	struct pxa2xx_ep	*ep;
+@@ -2602,24 +2602,23 @@ static int __exit pxa2xx_udc_remove(stru
+  * VBUS IRQs should probably be ignored so that the PXA device just acts
+  * "dead" to USB hosts until system resume.
+  */
+-static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state, u32 level)
++static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct pxa2xx_udc	*udc = dev_get_drvdata(dev);
+ 
+-	if (level == SUSPEND_POWER_DOWN) {
+-		if (!udc->mach->udc_command)
+-			WARN("USB host won't detect disconnect!\n");
+-		pullup(udc, 0);
+-	}
++	if (!udc->mach->udc_command)
++		WARN("USB host won't detect disconnect!\n");
++	pullup(udc, 0);
++
+ 	return 0;
+ }
+ 
+-static int pxa2xx_udc_resume(struct device *dev, u32 level)
++static int pxa2xx_udc_resume(struct device *dev)
+ {
+ 	struct pxa2xx_udc	*udc = dev_get_drvdata(dev);
+ 
+-	if (level == RESUME_POWER_ON)
+-		pullup(udc, 1);
++	pullup(udc, 1);
++
+ 	return 0;
+ }
+ 
+@@ -2632,6 +2631,7 @@ static int pxa2xx_udc_resume(struct devi
+ 
+ static struct device_driver udc_driver = {
+ 	.name		= "pxa2xx-udc",
++	.owner		= THIS_MODULE,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= pxa2xx_udc_probe,
+ 	.shutdown	= pxa2xx_udc_shutdown,
+diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
+--- a/drivers/usb/gadget/pxa2xx_udc.h
++++ b/drivers/usb/gadget/pxa2xx_udc.h
+@@ -69,11 +69,11 @@ struct pxa2xx_ep {
+ 	 * UDDR = UDC Endpoint Data Register (the fifo)
+ 	 * DRCM = DMA Request Channel Map
+ 	 */
+-	volatile unsigned long			*reg_udccs;
+-	volatile unsigned long			*reg_ubcr;
+-	volatile unsigned long			*reg_uddr;
++	volatile u32				*reg_udccs;
++	volatile u32				*reg_ubcr;
++	volatile u32				*reg_uddr;
+ #ifdef USE_DMA
+-	volatile unsigned long			*reg_drcmr;
++	volatile u32			*reg_drcmr;
+ #define	drcmr(n)  .reg_drcmr = & DRCMR ## n ,
+ #else
+ #define	drcmr(n)  
+diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
+--- a/drivers/usb/gadget/serial.c
++++ b/drivers/usb/gadget/serial.c
+@@ -300,18 +300,18 @@ static int gs_build_config_buf(u8 *buf, 
+ 		u8 type, unsigned int index, int is_otg);
+ 
+ static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
+-	unsigned kmalloc_flags);
++	gfp_t kmalloc_flags);
+ static void gs_free_req(struct usb_ep *ep, struct usb_request *req);
+ 
+ static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len,
+-	unsigned kmalloc_flags);
++	gfp_t kmalloc_flags);
+ static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req);
+ 
+-static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags);
++static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags);
+ static void gs_free_ports(struct gs_dev *dev);
+ 
+ /* circular buffer */
+-static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags);
++static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags);
+ static void gs_buf_free(struct gs_buf *gb);
+ static void gs_buf_clear(struct gs_buf *gb);
+ static unsigned int gs_buf_data_avail(struct gs_buf *gb);
+@@ -2091,7 +2091,7 @@ static int gs_build_config_buf(u8 *buf, 
+  * usb_request or NULL if there is an error.
+  */
+ static struct usb_request *
+-gs_alloc_req(struct usb_ep *ep, unsigned int len, unsigned kmalloc_flags)
++gs_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t kmalloc_flags)
+ {
+ 	struct usb_request *req;
+ 
+@@ -2132,7 +2132,7 @@ static void gs_free_req(struct usb_ep *e
+  * endpoint, buffer len, and kmalloc flags.
+  */
+ static struct gs_req_entry *
+-gs_alloc_req_entry(struct usb_ep *ep, unsigned len, unsigned kmalloc_flags)
++gs_alloc_req_entry(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
+ {
+ 	struct gs_req_entry	*req;
+ 
+@@ -2173,7 +2173,7 @@ static void gs_free_req_entry(struct usb
+  *
+  * The device lock is normally held when calling this function.
+  */
+-static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags)
++static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags)
+ {
+ 	int i;
+ 	struct gs_port *port;
+@@ -2255,7 +2255,7 @@ static void gs_free_ports(struct gs_dev 
+  *
+  * Allocate a circular buffer and all associated memory.
+  */
+-static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags)
++static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
+ {
+ 	struct gs_buf *gb;
+ 
+diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
+--- a/drivers/usb/gadget/zero.c
++++ b/drivers/usb/gadget/zero.c
+@@ -612,7 +612,7 @@ static void source_sink_complete (struct
+ }
+ 
+ static struct usb_request *
+-source_sink_start_ep (struct usb_ep *ep, unsigned gfp_flags)
++source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags)
+ {
+ 	struct usb_request	*req;
+ 	int			status;
+@@ -640,7 +640,7 @@ source_sink_start_ep (struct usb_ep *ep,
+ }
+ 
+ static int
+-set_source_sink_config (struct zero_dev *dev, unsigned gfp_flags)
++set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags)
+ {
+ 	int			result = 0;
+ 	struct usb_ep		*ep;
+@@ -744,7 +744,7 @@ static void loopback_complete (struct us
+ }
+ 
+ static int
+-set_loopback_config (struct zero_dev *dev, unsigned gfp_flags)
++set_loopback_config (struct zero_dev *dev, gfp_t gfp_flags)
+ {
+ 	int			result = 0;
+ 	struct usb_ep		*ep;
+@@ -845,7 +845,7 @@ static void zero_reset_config (struct ze
+  * by limiting configuration choices (like the pxa2xx).
+  */
+ static int
+-zero_set_config (struct zero_dev *dev, unsigned number, unsigned gfp_flags)
++zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags)
+ {
+ 	int			result = 0;
+ 	struct usb_gadget	*gadget = dev->gadget;
+@@ -1302,6 +1302,7 @@ static struct usb_gadget_driver zero_dri
+ 
+ 	.driver 	= {
+ 		.name		= (char *) shortname,
++		.owner		= THIS_MODULE,
+ 		// .shutdown = ...
+ 		// .suspend = ...
+ 		// .resume = ...
+diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
+--- a/drivers/usb/host/Makefile
++++ b/drivers/usb/host/Makefile
+@@ -1,8 +1,9 @@
+ #
+-# Makefile for USB Host Controller Driver
+-# framework and drivers
++# Makefile for USB Host Controller Drivers
+ #
+ 
++obj-$(CONFIG_PCI)		+= pci-quirks.o
++
+ obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
+ obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
+ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -182,6 +182,9 @@ static int ehci_halt (struct ehci_hcd *e
+ {
+ 	u32	temp = readl (&ehci->regs->status);
+ 
++	/* disable any irqs left enabled by previous code */
++	writel (0, &ehci->regs->intr_enable);
++
+ 	if ((temp & STS_HALT) != 0)
+ 		return 0;
+ 
+@@ -297,50 +300,17 @@ static void ehci_watchdog (unsigned long
+ 	spin_unlock_irqrestore (&ehci->lock, flags);
+ }
+ 
+-#ifdef	CONFIG_PCI
+-
+-/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/...
+- * off the controller (maybe it can boot from highspeed USB disks).
++/* Reboot notifiers kick in for silicon on any bus (not just pci, etc).
++ * This forcibly disables dma and IRQs, helping kexec and other cases
++ * where the next system software may expect clean state.
+  */
+-static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap)
+-{
+-	struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
+-
+-	/* always say Linux will own the hardware */
+-	pci_write_config_byte(pdev, where + 3, 1);
+-
+-	/* maybe wait a while for BIOS to respond */
+-	if (cap & (1 << 16)) {
+-		int msec = 5000;
+-
+-		do {
+-			msleep(10);
+-			msec -= 10;
+-			pci_read_config_dword(pdev, where, &cap);
+-		} while ((cap & (1 << 16)) && msec);
+-		if (cap & (1 << 16)) {
+-			ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n",
+-				where, cap);
+-			// some BIOS versions seem buggy...
+-			// return 1;
+-			ehci_warn (ehci, "continuing after BIOS bug...\n");
+-			/* disable all SMIs, and clear "BIOS owns" flag */
+-			pci_write_config_dword(pdev, where + 4, 0);
+-			pci_write_config_byte(pdev, where + 2, 0);
+-		} else
+-			ehci_dbg(ehci, "BIOS handoff succeeded\n");
+-	}
+-	return 0;
+-}
+-
+-#endif
+-
+ static int
+ ehci_reboot (struct notifier_block *self, unsigned long code, void *null)
+ {
+ 	struct ehci_hcd		*ehci;
+ 
+ 	ehci = container_of (self, struct ehci_hcd, reboot_notifier);
++	(void) ehci_halt (ehci);
+ 
+ 	/* make BIOS/etc use companion controller during reboot */
+ 	writel (0, &ehci->regs->configured_flag);
+@@ -363,156 +333,90 @@ static void ehci_port_power (struct ehci
+ 	msleep(20);
+ }
+ 
++/*-------------------------------------------------------------------------*/
++
++/*
++ * ehci_work is called from some interrupts, timers, and so on.
++ * it calls driver completion functions, after dropping ehci->lock.
++ */
++static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
++{
++	timer_action_done (ehci, TIMER_IO_WATCHDOG);
++	if (ehci->reclaim_ready)
++		end_unlink_async (ehci, regs);
++
++	/* another CPU may drop ehci->lock during a schedule scan while
++	 * it reports urb completions.  this flag guards against bogus
++	 * attempts at re-entrant schedule scanning.
++	 */
++	if (ehci->scanning)
++		return;
++	ehci->scanning = 1;
++	scan_async (ehci, regs);
++	if (ehci->next_uframe != -1)
++		scan_periodic (ehci, regs);
++	ehci->scanning = 0;
+ 
+-/* called by khubd or root hub init threads */
++	/* the IO watchdog guards against hardware or driver bugs that
++	 * misplace IRQs, and should let us run completely without IRQs.
++	 * such lossage has been observed on both VT6202 and VT8235.
++	 */
++	if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) &&
++			(ehci->async->qh_next.ptr != NULL ||
++			 ehci->periodic_sched != 0))
++		timer_action (ehci, TIMER_IO_WATCHDOG);
++}
+ 
+-static int ehci_hc_reset (struct usb_hcd *hcd)
++static void ehci_stop (struct usb_hcd *hcd)
+ {
+ 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+-	u32			temp;
+-	unsigned		count = 256/4;
+ 
+-	spin_lock_init (&ehci->lock);
++	ehci_dbg (ehci, "stop\n");
+ 
+-	ehci->caps = hcd->regs;
+-	ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase));
+-	dbg_hcs_params (ehci, "reset");
+-	dbg_hcc_params (ehci, "reset");
+-
+-	/* cache this readonly data; minimize chip reads */
+-	ehci->hcs_params = readl (&ehci->caps->hcs_params);
+-
+-#ifdef	CONFIG_PCI
+-	if (hcd->self.controller->bus == &pci_bus_type) {
+-		struct pci_dev	*pdev = to_pci_dev(hcd->self.controller);
+-
+-		switch (pdev->vendor) {
+-		case PCI_VENDOR_ID_TDI:
+-			if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
+-				ehci->is_tdi_rh_tt = 1;
+-				tdi_reset (ehci);
+-			}
+-			break;
+-		case PCI_VENDOR_ID_AMD:
+-			/* AMD8111 EHCI doesn't work, according to AMD errata */
+-			if (pdev->device == 0x7463) {
+-				ehci_info (ehci, "ignoring AMD8111 (errata)\n");
+-				return -EIO;
+-			}
+-			break;
+-		case PCI_VENDOR_ID_NVIDIA:
+-			/* NVidia reports that certain chips don't handle
+-			 * QH, ITD, or SITD addresses above 2GB.  (But TD,
+-			 * data buffer, and periodic schedule are normal.)
+-			 */
+-			switch (pdev->device) {
+-			case 0x003c:	/* MCP04 */
+-			case 0x005b:	/* CK804 */
+-			case 0x00d8:	/* CK8 */
+-			case 0x00e8:	/* CK8S */
+-				if (pci_set_consistent_dma_mask(pdev,
+-							DMA_31BIT_MASK) < 0)
+-					ehci_warn (ehci, "can't enable NVidia "
+-						"workaround for >2GB RAM\n");
+-				break;
+-			}
+-			break;
+-		}
++	/* Turn off port power on all root hub ports. */
++	ehci_port_power (ehci, 0);
+ 
+-		/* optional debug port, normally in the first BAR */
+-		temp = pci_find_capability (pdev, 0x0a);
+-		if (temp) {
+-			pci_read_config_dword(pdev, temp, &temp);
+-			temp >>= 16;
+-			if ((temp & (3 << 13)) == (1 << 13)) {
+-				temp &= 0x1fff;
+-				ehci->debug = hcd->regs + temp;
+-				temp = readl (&ehci->debug->control);
+-				ehci_info (ehci, "debug port %d%s\n",
+-					HCS_DEBUG_PORT(ehci->hcs_params),
+-					(temp & DBGP_ENABLED)
+-						? " IN USE"
+-						: "");
+-				if (!(temp & DBGP_ENABLED))
+-					ehci->debug = NULL;
+-			}
+-		}
++	/* no more interrupts ... */
++	del_timer_sync (&ehci->watchdog);
+ 
+-		temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
+-	} else
+-		temp = 0;
+-
+-	/* EHCI 0.96 and later may have "extended capabilities" */
+-	while (temp && count--) {
+-		u32		cap;
+-
+-		pci_read_config_dword (to_pci_dev(hcd->self.controller),
+-				temp, &cap);
+-		ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp);
+-		switch (cap & 0xff) {
+-		case 1:			/* BIOS/SMM/... handoff */
+-			if (bios_handoff (ehci, temp, cap) != 0)
+-				return -EOPNOTSUPP;
+-			break;
+-		case 0:			/* illegal reserved capability */
+-			ehci_warn (ehci, "illegal capability!\n");
+-			cap = 0;
+-			/* FALLTHROUGH */
+-		default:		/* unknown */
+-			break;
+-		}
+-		temp = (cap >> 8) & 0xff;
+-	}
+-	if (!count) {
+-		ehci_err (ehci, "bogus capabilities ... PCI problems!\n");
+-		return -EIO;
+-	}
+-	if (ehci_is_TDI(ehci))
+-		ehci_reset (ehci);
+-#endif
++	spin_lock_irq(&ehci->lock);
++	if (HC_IS_RUNNING (hcd->state))
++		ehci_quiesce (ehci);
+ 
+-	ehci_port_power (ehci, 0);
++	ehci_reset (ehci);
++	writel (0, &ehci->regs->intr_enable);
++	spin_unlock_irq(&ehci->lock);
+ 
+-	/* at least the Genesys GL880S needs fixup here */
+-	temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
+-	temp &= 0x0f;
+-	if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
+-		ehci_dbg (ehci, "bogus port configuration: "
+-			"cc=%d x pcc=%d < ports=%d\n",
+-			HCS_N_CC(ehci->hcs_params),
+-			HCS_N_PCC(ehci->hcs_params),
+-			HCS_N_PORTS(ehci->hcs_params));
+-
+-#ifdef	CONFIG_PCI
+-		if (hcd->self.controller->bus == &pci_bus_type) {
+-			struct pci_dev	*pdev;
+-
+-			pdev = to_pci_dev(hcd->self.controller);
+-			switch (pdev->vendor) {
+-			case 0x17a0:		/* GENESYS */
+-				/* GL880S: should be PORTS=2 */
+-				temp |= (ehci->hcs_params & ~0xf);
+-				ehci->hcs_params = temp;
+-				break;
+-			case PCI_VENDOR_ID_NVIDIA:
+-				/* NF4: should be PCC=10 */
+-				break;
+-			}
+-		}
++	/* let companion controllers work when we aren't */
++	writel (0, &ehci->regs->configured_flag);
++	unregister_reboot_notifier (&ehci->reboot_notifier);
++
++	remove_debug_files (ehci);
++
++	/* root hub is shut down separately (first, when possible) */
++	spin_lock_irq (&ehci->lock);
++	if (ehci->async)
++		ehci_work (ehci, NULL);
++	spin_unlock_irq (&ehci->lock);
++	ehci_mem_cleanup (ehci);
++
++#ifdef	EHCI_STATS
++	ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
++		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
++		ehci->stats.lost_iaa);
++	ehci_dbg (ehci, "complete %ld unlink %ld\n",
++		ehci->stats.complete, ehci->stats.unlink);
+ #endif
+-	}
+ 
+-	/* force HC to halt state */
+-	return ehci_halt (ehci);
++	dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status));
+ }
+ 
+-static int ehci_start (struct usb_hcd *hcd)
++static int ehci_run (struct usb_hcd *hcd)
+ {
+ 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+ 	u32			temp;
+ 	int			retval;
+ 	u32			hcc_params;
+-	u8                      sbrn = 0;
+ 	int			first;
+ 
+ 	/* skip some things on restart paths */
+@@ -551,27 +455,6 @@ static int ehci_start (struct usb_hcd *h
+ 	}
+ 	writel (ehci->periodic_dma, &ehci->regs->frame_list);
+ 
+-#ifdef	CONFIG_PCI
+-	if (hcd->self.controller->bus == &pci_bus_type) {
+-		struct pci_dev		*pdev;
+-		u16			port_wake;
+-
+-		pdev = to_pci_dev(hcd->self.controller);
+-
+-		/* Serial Bus Release Number is at PCI 0x60 offset */
+-		pci_read_config_byte(pdev, 0x60, &sbrn);
+-
+-		/* port wake capability, reported by boot firmware */
+-		pci_read_config_word(pdev, 0x62, &port_wake);
+-		hcd->can_wakeup = (port_wake & 1) != 0;
+-
+-		/* help hc dma work well with cachelines */
+-		retval = pci_set_mwi(pdev);
+-		if (retval)
+-			ehci_dbg(ehci, "unable to enable MWI - not fatal.\n");
+-	}
+-#endif
+-
+ 	/*
+ 	 * dedicate a qh for the async ring head, since we couldn't unlink
+ 	 * a 'real' qh without stopping the async schedule [4.8].  use it
+@@ -667,7 +550,7 @@ static int ehci_start (struct usb_hcd *h
+ 	temp = HC_VERSION(readl (&ehci->caps->hc_capbase));
+ 	ehci_info (ehci,
+ 		"USB %x.%x %s, EHCI %x.%02x, driver %s\n",
+-		((sbrn & 0xf0)>>4), (sbrn & 0x0f),
++		((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
+ 		first ? "initialized" : "restarted",
+ 		temp >> 8, temp & 0xff, DRIVER_VERSION);
+ 
+@@ -679,188 +562,6 @@ static int ehci_start (struct usb_hcd *h
+ 	return 0;
+ }
+ 
+-/* always called by thread; normally rmmod */
+-
+-static void ehci_stop (struct usb_hcd *hcd)
+-{
+-	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+-
+-	ehci_dbg (ehci, "stop\n");
+-
+-	/* Turn off port power on all root hub ports. */
+-	ehci_port_power (ehci, 0);
+-
+-	/* no more interrupts ... */
+-	del_timer_sync (&ehci->watchdog);
+-
+-	spin_lock_irq(&ehci->lock);
+-	if (HC_IS_RUNNING (hcd->state))
+-		ehci_quiesce (ehci);
+-
+-	ehci_reset (ehci);
+-	writel (0, &ehci->regs->intr_enable);
+-	spin_unlock_irq(&ehci->lock);
+-
+-	/* let companion controllers work when we aren't */
+-	writel (0, &ehci->regs->configured_flag);
+-	unregister_reboot_notifier (&ehci->reboot_notifier);
+-
+-	remove_debug_files (ehci);
+-
+-	/* root hub is shut down separately (first, when possible) */
+-	spin_lock_irq (&ehci->lock);
+-	if (ehci->async)
+-		ehci_work (ehci, NULL);
+-	spin_unlock_irq (&ehci->lock);
+-	ehci_mem_cleanup (ehci);
+-
+-#ifdef	EHCI_STATS
+-	ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
+-		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
+-		ehci->stats.lost_iaa);
+-	ehci_dbg (ehci, "complete %ld unlink %ld\n",
+-		ehci->stats.complete, ehci->stats.unlink);
+-#endif
+-
+-	dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status));
+-}
+-
+-static int ehci_get_frame (struct usb_hcd *hcd)
+-{
+-	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+-	return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size;
+-}
+-
+-/*-------------------------------------------------------------------------*/
+-
+-#ifdef	CONFIG_PM
+-
+-/* suspend/resume, section 4.3 */
+-
+-/* These routines rely on the bus (pci, platform, etc)
+- * to handle powerdown and wakeup, and currently also on
+- * transceivers that don't need any software attention to set up
+- * the right sort of wakeup.  
+- */
+-
+-static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message)
+-{
+-	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+-
+-	if (time_before (jiffies, ehci->next_statechange))
+-		msleep (100);
+-
+-#ifdef	CONFIG_USB_SUSPEND
+-	(void) usb_suspend_device (hcd->self.root_hub, message);
+-#else
+-	usb_lock_device (hcd->self.root_hub);
+-	(void) ehci_hub_suspend (hcd);
+-	usb_unlock_device (hcd->self.root_hub);
+-#endif
+-
+-	// save (PCI) FLADJ in case of Vaux power loss
+-	// ... we'd only use it to handle clock skew
+-
+-	return 0;
+-}
+-
+-static int ehci_resume (struct usb_hcd *hcd)
+-{
+-	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+-	unsigned		port;
+-	struct usb_device	*root = hcd->self.root_hub;
+-	int			retval = -EINVAL;
+-
+-	// maybe restore (PCI) FLADJ
+-
+-	if (time_before (jiffies, ehci->next_statechange))
+-		msleep (100);
+-
+-	/* If any port is suspended (or owned by the companion),
+-	 * we know we can/must resume the HC (and mustn't reset it).
+-	 */
+-	for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) {
+-		u32	status;
+-		port--;
+-		status = readl (&ehci->regs->port_status [port]);
+-		if (!(status & PORT_POWER))
+-			continue;
+-		if (status & (PORT_SUSPEND | PORT_OWNER)) {
+-			down (&hcd->self.root_hub->serialize);
+-			retval = ehci_hub_resume (hcd);
+-			up (&hcd->self.root_hub->serialize);
+-			break;
+-		}
+-		if (!root->children [port])
+-			continue;
+-		dbg_port (ehci, __FUNCTION__, port + 1, status);
+-		usb_set_device_state (root->children[port],
+-					USB_STATE_NOTATTACHED);
+-	}
+-
+-	/* Else reset, to cope with power loss or flush-to-storage
+-	 * style "resume" having activated BIOS during reboot.
+-	 */
+-	if (port == 0) {
+-		(void) ehci_halt (ehci);
+-		(void) ehci_reset (ehci);
+-		(void) ehci_hc_reset (hcd);
+-
+-		/* emptying the schedule aborts any urbs */
+-		spin_lock_irq (&ehci->lock);
+-		if (ehci->reclaim)
+-			ehci->reclaim_ready = 1;
+-		ehci_work (ehci, NULL);
+-		spin_unlock_irq (&ehci->lock);
+-
+-		/* restart; khubd will disconnect devices */
+-		retval = ehci_start (hcd);
+-
+-		/* here we "know" root ports should always stay powered;
+-		 * but some controllers may lose all power.
+-		 */
+-		ehci_port_power (ehci, 1);
+-	}
+-
+-	return retval;
+-}
+-
+-#endif
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * ehci_work is called from some interrupts, timers, and so on.
+- * it calls driver completion functions, after dropping ehci->lock.
+- */
+-static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
+-{
+-	timer_action_done (ehci, TIMER_IO_WATCHDOG);
+-	if (ehci->reclaim_ready)
+-		end_unlink_async (ehci, regs);
+-
+-	/* another CPU may drop ehci->lock during a schedule scan while
+-	 * it reports urb completions.  this flag guards against bogus
+-	 * attempts at re-entrant schedule scanning.
+-	 */
+-	if (ehci->scanning)
+-		return;
+-	ehci->scanning = 1;
+-	scan_async (ehci, regs);
+-	if (ehci->next_uframe != -1)
+-		scan_periodic (ehci, regs);
+-	ehci->scanning = 0;
+-
+-	/* the IO watchdog guards against hardware or driver bugs that
+-	 * misplace IRQs, and should let us run completely without IRQs.
+-	 * such lossage has been observed on both VT6202 and VT8235. 
+-	 */
+-	if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) &&
+-			(ehci->async->qh_next.ptr != NULL ||
+-			 ehci->periodic_sched != 0))
+-		timer_action (ehci, TIMER_IO_WATCHDOG);
+-}
+-
+ /*-------------------------------------------------------------------------*/
+ 
+ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
+@@ -983,7 +684,7 @@ static int ehci_urb_enqueue (
+ 	struct usb_hcd	*hcd,
+ 	struct usb_host_endpoint *ep,
+ 	struct urb	*urb,
+-	unsigned	mem_flags
++	gfp_t		mem_flags
+ ) {
+ 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+ 	struct list_head	qtd_list;
+@@ -1171,106 +872,24 @@ done:
+ 	return;
+ }
+ 
+-/*-------------------------------------------------------------------------*/
+-
+-static const struct hc_driver ehci_driver = {
+-	.description =		hcd_name,
+-	.product_desc =		"EHCI Host Controller",
+-	.hcd_priv_size =	sizeof(struct ehci_hcd),
+-
+-	/*
+-	 * generic hardware linkage
+-	 */
+-	.irq =			ehci_irq,
+-	.flags =		HCD_MEMORY | HCD_USB2,
+-
+-	/*
+-	 * basic lifecycle operations
+-	 */
+-	.reset =		ehci_hc_reset,
+-	.start =		ehci_start,
+-#ifdef	CONFIG_PM
+-	.suspend =		ehci_suspend,
+-	.resume =		ehci_resume,
+-#endif
+-	.stop =			ehci_stop,
+-
+-	/*
+-	 * managing i/o requests and associated device resources
+-	 */
+-	.urb_enqueue =		ehci_urb_enqueue,
+-	.urb_dequeue =		ehci_urb_dequeue,
+-	.endpoint_disable =	ehci_endpoint_disable,
+-
+-	/*
+-	 * scheduling support
+-	 */
+-	.get_frame_number =	ehci_get_frame,
+-
+-	/*
+-	 * root hub support
+-	 */
+-	.hub_status_data =	ehci_hub_status_data,
+-	.hub_control =		ehci_hub_control,
+-	.hub_suspend =		ehci_hub_suspend,
+-	.hub_resume =		ehci_hub_resume,
+-};
++static int ehci_get_frame (struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size;
++}
+ 
+ /*-------------------------------------------------------------------------*/
+ 
+-/* EHCI 1.0 doesn't require PCI */
+-
+-#ifdef	CONFIG_PCI
+-
+-/* PCI driver selection metadata; PCI hotplugging uses this */
+-static const struct pci_device_id pci_ids [] = { {
+-	/* handle any USB 2.0 EHCI controller */
+-	PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0),
+-	.driver_data =	(unsigned long) &ehci_driver,
+-	},
+-	{ /* end: all zeroes */ }
+-};
+-MODULE_DEVICE_TABLE (pci, pci_ids);
+-
+-/* pci driver glue; this is a "new style" PCI driver module */
+-static struct pci_driver ehci_pci_driver = {
+-	.name =		(char *) hcd_name,
+-	.id_table =	pci_ids,
+-
+-	.probe =	usb_hcd_pci_probe,
+-	.remove =	usb_hcd_pci_remove,
+-
+-#ifdef	CONFIG_PM
+-	.suspend =	usb_hcd_pci_suspend,
+-	.resume =	usb_hcd_pci_resume,
+-#endif
+-};
+-
+-#endif	/* PCI */
+-
+-
+ #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
+ 
+ MODULE_DESCRIPTION (DRIVER_INFO);
+ MODULE_AUTHOR (DRIVER_AUTHOR);
+ MODULE_LICENSE ("GPL");
+ 
+-static int __init init (void) 
+-{
+-	if (usb_disabled())
+-		return -ENODEV;
+-
+-	pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
+-		hcd_name,
+-		sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
+-		sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
+-
+-	return pci_register_driver (&ehci_pci_driver);
+-}
+-module_init (init);
++#ifdef CONFIG_PCI
++#include "ehci-pci.c"
++#endif
+ 
+-static void __exit cleanup (void) 
+-{	
+-	pci_unregister_driver (&ehci_pci_driver);
+-}
+-module_exit (cleanup);
++#if !defined(CONFIG_PCI)
++#error "missing bus glue for ehci-hcd"
++#endif
+diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -30,7 +30,7 @@
+ 
+ #ifdef	CONFIG_PM
+ 
+-static int ehci_hub_suspend (struct usb_hcd *hcd)
++static int ehci_bus_suspend (struct usb_hcd *hcd)
+ {
+ 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+ 	int			port;
+@@ -83,7 +83,7 @@ static int ehci_hub_suspend (struct usb_
+ 
+ 
+ /* caller has locked the root hub, and should reset/reinit on error */
+-static int ehci_hub_resume (struct usb_hcd *hcd)
++static int ehci_bus_resume (struct usb_hcd *hcd)
+ {
+ 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+ 	u32			temp;
+@@ -159,8 +159,8 @@ static int ehci_hub_resume (struct usb_h
+ 
+ #else
+ 
+-#define ehci_hub_suspend	NULL
+-#define ehci_hub_resume		NULL
++#define ehci_bus_suspend	NULL
++#define ehci_bus_resume		NULL
+ 
+ #endif	/* CONFIG_PM */
+ 
+diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
+--- a/drivers/usb/host/ehci-mem.c
++++ b/drivers/usb/host/ehci-mem.c
+@@ -45,7 +45,7 @@ static inline void ehci_qtd_init (struct
+ 	INIT_LIST_HEAD (&qtd->qtd_list);
+ }
+ 
+-static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags)
++static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags)
+ {
+ 	struct ehci_qtd		*qtd;
+ 	dma_addr_t		dma;
+@@ -79,7 +79,7 @@ static void qh_destroy (struct kref *kre
+ 	dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+ }
+ 
+-static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
++static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
+ {
+ 	struct ehci_qh		*qh;
+ 	dma_addr_t		dma;
+@@ -161,7 +161,7 @@ static void ehci_mem_cleanup (struct ehc
+ }
+ 
+ /* remember to add cleanup code (above) if you add anything here */
+-static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
++static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
+ {
+ 	int i;
+ 
+diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/usb/host/ehci-pci.c
+@@ -0,0 +1,415 @@
++/*
++ * EHCI HCD (Host Controller Driver) PCI Bus Glue.
++ *
++ * Copyright (c) 2000-2004 by David Brownell
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software Foundation,
++ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef CONFIG_PCI
++#error "This file is PCI bus glue.  CONFIG_PCI must be defined."
++#endif
++
++/*-------------------------------------------------------------------------*/
++
++/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/...
++ * off the controller (maybe it can boot from highspeed USB disks).
++ */
++static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap)
++{
++	struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
++
++	/* always say Linux will own the hardware */
++	pci_write_config_byte(pdev, where + 3, 1);
++
++	/* maybe wait a while for BIOS to respond */
++	if (cap & (1 << 16)) {
++		int msec = 5000;
++
++		do {
++			msleep(10);
++			msec -= 10;
++			pci_read_config_dword(pdev, where, &cap);
++		} while ((cap & (1 << 16)) && msec);
++		if (cap & (1 << 16)) {
++			ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n",
++				where, cap);
++			// some BIOS versions seem buggy...
++			// return 1;
++			ehci_warn (ehci, "continuing after BIOS bug...\n");
++			/* disable all SMIs, and clear "BIOS owns" flag */
++			pci_write_config_dword(pdev, where + 4, 0);
++			pci_write_config_byte(pdev, where + 2, 0);
++		} else
++			ehci_dbg(ehci, "BIOS handoff succeeded\n");
++	}
++	return 0;
++}
++
++/* called by khubd or root hub init threads */
++static int ehci_pci_reset (struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	u32			temp;
++	unsigned		count = 256/4;
++
++	spin_lock_init (&ehci->lock);
++
++	ehci->caps = hcd->regs;
++	ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase));
++	dbg_hcs_params (ehci, "reset");
++	dbg_hcc_params (ehci, "reset");
++
++	/* cache this readonly data; minimize chip reads */
++	ehci->hcs_params = readl (&ehci->caps->hcs_params);
++
++	if (hcd->self.controller->bus == &pci_bus_type) {
++		struct pci_dev	*pdev = to_pci_dev(hcd->self.controller);
++
++		switch (pdev->vendor) {
++		case PCI_VENDOR_ID_TDI:
++			if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
++				ehci->is_tdi_rh_tt = 1;
++				tdi_reset (ehci);
++			}
++			break;
++		case PCI_VENDOR_ID_AMD:
++			/* AMD8111 EHCI doesn't work, according to AMD errata */
++			if (pdev->device == 0x7463) {
++				ehci_info (ehci, "ignoring AMD8111 (errata)\n");
++				return -EIO;
++			}
++			break;
++		case PCI_VENDOR_ID_NVIDIA:
++			/* NVidia reports that certain chips don't handle
++			 * QH, ITD, or SITD addresses above 2GB.  (But TD,
++			 * data buffer, and periodic schedule are normal.)
++			 */
++			switch (pdev->device) {
++			case 0x003c:	/* MCP04 */
++			case 0x005b:	/* CK804 */
++			case 0x00d8:	/* CK8 */
++			case 0x00e8:	/* CK8S */
++				if (pci_set_consistent_dma_mask(pdev,
++							DMA_31BIT_MASK) < 0)
++					ehci_warn (ehci, "can't enable NVidia "
++						"workaround for >2GB RAM\n");
++				break;
++			}
++			break;
++		}
++
++		/* optional debug port, normally in the first BAR */
++		temp = pci_find_capability (pdev, 0x0a);
++		if (temp) {
++			pci_read_config_dword(pdev, temp, &temp);
++			temp >>= 16;
++			if ((temp & (3 << 13)) == (1 << 13)) {
++				temp &= 0x1fff;
++				ehci->debug = hcd->regs + temp;
++				temp = readl (&ehci->debug->control);
++				ehci_info (ehci, "debug port %d%s\n",
++					HCS_DEBUG_PORT(ehci->hcs_params),
++					(temp & DBGP_ENABLED)
++						? " IN USE"
++						: "");
++				if (!(temp & DBGP_ENABLED))
++					ehci->debug = NULL;
++			}
++		}
++
++		temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
++	} else
++		temp = 0;
++
++	/* EHCI 0.96 and later may have "extended capabilities" */
++	while (temp && count--) {
++		u32		cap;
++
++		pci_read_config_dword (to_pci_dev(hcd->self.controller),
++				temp, &cap);
++		ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp);
++		switch (cap & 0xff) {
++		case 1:			/* BIOS/SMM/... handoff */
++			if (bios_handoff (ehci, temp, cap) != 0)
++				return -EOPNOTSUPP;
++			break;
++		case 0:			/* illegal reserved capability */
++			ehci_warn (ehci, "illegal capability!\n");
++			cap = 0;
++			/* FALLTHROUGH */
++		default:		/* unknown */
++			break;
++		}
++		temp = (cap >> 8) & 0xff;
++	}
++	if (!count) {
++		ehci_err (ehci, "bogus capabilities ... PCI problems!\n");
++		return -EIO;
++	}
++	if (ehci_is_TDI(ehci))
++		ehci_reset (ehci);
++
++	ehci_port_power (ehci, 0);
++
++	/* at least the Genesys GL880S needs fixup here */
++	temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
++	temp &= 0x0f;
++	if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
++		ehci_dbg (ehci, "bogus port configuration: "
++			"cc=%d x pcc=%d < ports=%d\n",
++			HCS_N_CC(ehci->hcs_params),
++			HCS_N_PCC(ehci->hcs_params),
++			HCS_N_PORTS(ehci->hcs_params));
++
++		if (hcd->self.controller->bus == &pci_bus_type) {
++			struct pci_dev	*pdev;
++
++			pdev = to_pci_dev(hcd->self.controller);
++			switch (pdev->vendor) {
++			case 0x17a0:		/* GENESYS */
++				/* GL880S: should be PORTS=2 */
++				temp |= (ehci->hcs_params & ~0xf);
++				ehci->hcs_params = temp;
++				break;
++			case PCI_VENDOR_ID_NVIDIA:
++				/* NF4: should be PCC=10 */
++				break;
++			}
++		}
++	}
++
++	/* force HC to halt state */
++	return ehci_halt (ehci);
++}
++
++static int ehci_pci_start (struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	int result = 0;
++
++	if (hcd->self.controller->bus == &pci_bus_type) {
++		struct pci_dev		*pdev;
++		u16			port_wake;
++
++		pdev = to_pci_dev(hcd->self.controller);
++
++		/* Serial Bus Release Number is at PCI 0x60 offset */
++		pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
++
++		/* port wake capability, reported by boot firmware */
++		pci_read_config_word(pdev, 0x62, &port_wake);
++		hcd->can_wakeup = (port_wake & 1) != 0;
++
++		/* help hc dma work well with cachelines */
++		result = pci_set_mwi(pdev);
++		if (result)
++			ehci_dbg(ehci, "unable to enable MWI - not fatal.\n");
++	}
++
++	return ehci_run (hcd);
++}
++
++/* always called by thread; normally rmmod */
++
++static void ehci_pci_stop (struct usb_hcd *hcd)
++{
++	ehci_stop (hcd);
++}
++
++/*-------------------------------------------------------------------------*/
++
++#ifdef	CONFIG_PM
++
++/* suspend/resume, section 4.3 */
++
++/* These routines rely on the bus (pci, platform, etc)
++ * to handle powerdown and wakeup, and currently also on
++ * transceivers that don't need any software attention to set up
++ * the right sort of wakeup.
++ */
++
++static int ehci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++
++	if (time_before (jiffies, ehci->next_statechange))
++		msleep (100);
++
++#ifdef	CONFIG_USB_SUSPEND
++	(void) usb_suspend_device (hcd->self.root_hub);
++#else
++	usb_lock_device (hcd->self.root_hub);
++	(void) ehci_bus_suspend (hcd);
++	usb_unlock_device (hcd->self.root_hub);
++#endif
++
++	// save (PCI) FLADJ in case of Vaux power loss
++	// ... we'd only use it to handle clock skew
++
++	return 0;
++}
++
++static int ehci_pci_resume (struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	unsigned		port;
++	struct usb_device	*root = hcd->self.root_hub;
++	int			retval = -EINVAL;
++
++	// maybe restore (PCI) FLADJ
++
++	if (time_before (jiffies, ehci->next_statechange))
++		msleep (100);
++
++	/* If any port is suspended (or owned by the companion),
++	 * we know we can/must resume the HC (and mustn't reset it).
++	 */
++	for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) {
++		u32	status;
++		port--;
++		status = readl (&ehci->regs->port_status [port]);
++		if (!(status & PORT_POWER))
++			continue;
++		if (status & (PORT_SUSPEND | PORT_OWNER)) {
++			down (&hcd->self.root_hub->serialize);
++			retval = ehci_bus_resume (hcd);
++			up (&hcd->self.root_hub->serialize);
++			break;
++		}
++		if (!root->children [port])
++			continue;
++		dbg_port (ehci, __FUNCTION__, port + 1, status);
++		usb_set_device_state (root->children[port],
++					USB_STATE_NOTATTACHED);
++	}
++
++	/* Else reset, to cope with power loss or flush-to-storage
++	 * style "resume" having activated BIOS during reboot.
++	 */
++	if (port == 0) {
++		(void) ehci_halt (ehci);
++		(void) ehci_reset (ehci);
++		(void) ehci_pci_reset (hcd);
++
++		/* emptying the schedule aborts any urbs */
++		spin_lock_irq (&ehci->lock);
++		if (ehci->reclaim)
++			ehci->reclaim_ready = 1;
++		ehci_work (ehci, NULL);
++		spin_unlock_irq (&ehci->lock);
++
++		/* restart; khubd will disconnect devices */
++		retval = ehci_run (hcd);
++
++		/* here we "know" root ports should always stay powered;
++		 * but some controllers may lose all power.
++		 */
++		ehci_port_power (ehci, 1);
++	}
++
++	return retval;
++}
++#endif
++
++static const struct hc_driver ehci_pci_hc_driver = {
++	.description =		hcd_name,
++	.product_desc =		"EHCI Host Controller",
++	.hcd_priv_size =	sizeof(struct ehci_hcd),
++
++	/*
++	 * generic hardware linkage
++	 */
++	.irq =			ehci_irq,
++	.flags =		HCD_MEMORY | HCD_USB2,
++
++	/*
++	 * basic lifecycle operations
++	 */
++	.reset =		ehci_pci_reset,
++	.start =		ehci_pci_start,
++#ifdef	CONFIG_PM
++	.suspend =		ehci_pci_suspend,
++	.resume =		ehci_pci_resume,
++#endif
++	.stop =			ehci_pci_stop,
++
++	/*
++	 * managing i/o requests and associated device resources
++	 */
++	.urb_enqueue =		ehci_urb_enqueue,
++	.urb_dequeue =		ehci_urb_dequeue,
++	.endpoint_disable =	ehci_endpoint_disable,
++
++	/*
++	 * scheduling support
++	 */
++	.get_frame_number =	ehci_get_frame,
++
++	/*
++	 * root hub support
++	 */
++	.hub_status_data =	ehci_hub_status_data,
++	.hub_control =		ehci_hub_control,
++	.bus_suspend =		ehci_bus_suspend,
++	.bus_resume =		ehci_bus_resume,
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* PCI driver selection metadata; PCI hotplugging uses this */
++static const struct pci_device_id pci_ids [] = { {
++	/* handle any USB 2.0 EHCI controller */
++	PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0),
++	.driver_data =	(unsigned long) &ehci_pci_hc_driver,
++	},
++	{ /* end: all zeroes */ }
++};
++MODULE_DEVICE_TABLE (pci, pci_ids);
++
++/* pci driver glue; this is a "new style" PCI driver module */
++static struct pci_driver ehci_pci_driver = {
++	.name =		(char *) hcd_name,
++	.id_table =	pci_ids,
++	.owner = 	THIS_MODULE,
++
++	.probe =	usb_hcd_pci_probe,
++	.remove =	usb_hcd_pci_remove,
++
++#ifdef	CONFIG_PM
++	.suspend =	usb_hcd_pci_suspend,
++	.resume =	usb_hcd_pci_resume,
++#endif
++};
++
++static int __init ehci_hcd_pci_init (void)
++{
++	if (usb_disabled())
++		return -ENODEV;
++
++	pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
++		hcd_name,
++		sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
++		sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
++
++	return pci_register_driver (&ehci_pci_driver);
++}
++module_init (ehci_hcd_pci_init);
++
++static void __exit ehci_hcd_pci_cleanup (void)
++{
++	pci_unregister_driver (&ehci_pci_driver);
++}
++module_exit (ehci_hcd_pci_cleanup);
+diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -477,7 +477,7 @@ qh_urb_transaction (
+ 	struct ehci_hcd		*ehci,
+ 	struct urb		*urb,
+ 	struct list_head	*head,
+-	int			flags
++	gfp_t			flags
+ ) {
+ 	struct ehci_qtd		*qtd, *qtd_prev;
+ 	dma_addr_t		buf;
+@@ -629,7 +629,7 @@ static struct ehci_qh *
+ qh_make (
+ 	struct ehci_hcd		*ehci,
+ 	struct urb		*urb,
+-	int			flags
++	gfp_t			flags
+ ) {
+ 	struct ehci_qh		*qh = ehci_qh_alloc (ehci, flags);
+ 	u32			info1 = 0, info2 = 0;
+@@ -906,7 +906,7 @@ submit_async (
+ 	struct usb_host_endpoint *ep,
+ 	struct urb		*urb,
+ 	struct list_head	*qtd_list,
+-	unsigned		mem_flags
++	gfp_t			mem_flags
+ ) {
+ 	struct ehci_qtd		*qtd;
+ 	int			epnum;
+diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -589,7 +589,7 @@ static int intr_submit (
+ 	struct usb_host_endpoint *ep,
+ 	struct urb		*urb,
+ 	struct list_head	*qtd_list,
+-	unsigned		mem_flags
++	gfp_t			mem_flags
+ ) {
+ 	unsigned		epnum;
+ 	unsigned long		flags;
+@@ -634,7 +634,7 @@ done:
+ /* ehci_iso_stream ops work with both ITD and SITD */
+ 
+ static struct ehci_iso_stream *
+-iso_stream_alloc (unsigned mem_flags)
++iso_stream_alloc (gfp_t mem_flags)
+ {
+ 	struct ehci_iso_stream *stream;
+ 
+@@ -851,7 +851,7 @@ iso_stream_find (struct ehci_hcd *ehci, 
+ /* ehci_iso_sched ops can be ITD-only or SITD-only */
+ 
+ static struct ehci_iso_sched *
+-iso_sched_alloc (unsigned packets, unsigned mem_flags)
++iso_sched_alloc (unsigned packets, gfp_t mem_flags)
+ {
+ 	struct ehci_iso_sched	*iso_sched;
+ 	int			size = sizeof *iso_sched;
+@@ -924,7 +924,7 @@ itd_urb_transaction (
+ 	struct ehci_iso_stream	*stream,
+ 	struct ehci_hcd		*ehci,
+ 	struct urb		*urb,
+-	unsigned		mem_flags
++	gfp_t			mem_flags
+ )
+ {
+ 	struct ehci_itd		*itd;
+@@ -1418,7 +1418,7 @@ itd_complete (
+ /*-------------------------------------------------------------------------*/
+ 
+ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
+-	unsigned mem_flags)
++	gfp_t mem_flags)
+ {
+ 	int			status = -EINVAL;
+ 	unsigned long		flags;
+@@ -1529,7 +1529,7 @@ sitd_urb_transaction (
+ 	struct ehci_iso_stream	*stream,
+ 	struct ehci_hcd		*ehci,
+ 	struct urb		*urb,
+-	unsigned		mem_flags
++	gfp_t			mem_flags
+ )
+ {
+ 	struct ehci_sitd	*sitd;
+@@ -1779,7 +1779,7 @@ sitd_complete (
+ 
+ 
+ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
+-	unsigned mem_flags)
++	gfp_t mem_flags)
+ {
+ 	int			status = -EINVAL;
+ 	unsigned long		flags;
+diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -97,6 +97,7 @@ struct ehci_hcd {			/* one per controlle
+ #else
+ #	define COUNT(x) do {} while (0)
+ #endif
++	u8			sbrn;		/* packed release number */
+ };
+ 
+ /* convert between an HCD pointer and the corresponding EHCI_HCD */ 
+diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
+--- a/drivers/usb/host/isp116x-hcd.c
++++ b/drivers/usb/host/isp116x-hcd.c
+@@ -70,6 +70,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/usb.h>
+ #include <linux/usb_isp116x.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -638,7 +639,7 @@ static irqreturn_t isp116x_irq(struct us
+ 				  + msecs_to_jiffies(20) + 1);
+ 		if (intstat & HCINT_RD) {
+ 			DBG("---- remote wakeup\n");
+-			schedule_work(&isp116x->rh_resume);
++			usb_hcd_resume_root_hub(hcd);
+ 			ret = IRQ_HANDLED;
+ 		}
+ 		irqstat &= ~HCuPINT_OPR;
+@@ -694,7 +695,7 @@ static int balance(struct isp116x *isp11
+ 
+ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
+ 			       struct usb_host_endpoint *hep, struct urb *urb,
+-			       unsigned mem_flags)
++			       gfp_t mem_flags)
+ {
+ 	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+ 	struct usb_device *udev = urb->dev;
+@@ -1160,7 +1161,7 @@ static int isp116x_hub_control(struct us
+ 
+ #ifdef	CONFIG_PM
+ 
+-static int isp116x_hub_suspend(struct usb_hcd *hcd)
++static int isp116x_bus_suspend(struct usb_hcd *hcd)
+ {
+ 	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+ 	unsigned long flags;
+@@ -1200,7 +1201,7 @@ static int isp116x_hub_suspend(struct us
+ 	return ret;
+ }
+ 
+-static int isp116x_hub_resume(struct usb_hcd *hcd)
++static int isp116x_bus_resume(struct usb_hcd *hcd)
+ {
+ 	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+ 	u32 val;
+@@ -1263,21 +1264,11 @@ static int isp116x_hub_resume(struct usb
+ 	return 0;
+ }
+ 
+-static void isp116x_rh_resume(void *_hcd)
+-{
+-	struct usb_hcd *hcd = _hcd;
+-
+-	usb_resume_device(hcd->self.root_hub);
+-}
+ 
+ #else
+ 
+-#define	isp116x_hub_suspend	NULL
+-#define	isp116x_hub_resume	NULL
+-
+-static void isp116x_rh_resume(void *_hcd)
+-{
+-}
++#define	isp116x_bus_suspend	NULL
++#define	isp116x_bus_resume	NULL
+ 
+ #endif
+ 
+@@ -1636,8 +1627,8 @@ static struct hc_driver isp116x_hc_drive
+ 
+ 	.hub_status_data = isp116x_hub_status_data,
+ 	.hub_control = isp116x_hub_control,
+-	.hub_suspend = isp116x_hub_suspend,
+-	.hub_resume = isp116x_hub_resume,
++	.bus_suspend = isp116x_bus_suspend,
++	.bus_resume = isp116x_bus_resume,
+ };
+ 
+ /*----------------------------------------------------------------*/
+@@ -1732,7 +1723,6 @@ static int __init isp116x_probe(struct d
+ 	isp116x->addr_reg = addr_reg;
+ 	spin_lock_init(&isp116x->lock);
+ 	INIT_LIST_HEAD(&isp116x->async);
+-	INIT_WORK(&isp116x->rh_resume, isp116x_rh_resume, hcd);
+ 	isp116x->board = dev->platform_data;
+ 
+ 	if (!isp116x->board) {
+@@ -1774,22 +1764,13 @@ static int __init isp116x_probe(struct d
+ /*
+   Suspend of platform device
+ */
+-static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase)
++static int isp116x_suspend(struct device *dev, pm_message_t state)
+ {
+ 	int ret = 0;
+-	struct usb_hcd *hcd = dev_get_drvdata(dev);
+ 
+-	VDBG("%s: state %x, phase %x\n", __func__, state, phase);
++	VDBG("%s: state %x\n", __func__, state);
+ 
+-	if (phase != SUSPEND_DISABLE && phase != SUSPEND_POWER_DOWN)
+-		return 0;
+-
+-	ret = usb_suspend_device(hcd->self.root_hub, state);
+-	if (!ret) {
+-		dev->power.power_state = state;
+-		INFO("%s suspended\n", hcd_name);
+-	} else
+-		ERR("%s suspend failed\n", hcd_name);
++	dev->power.power_state = state;
+ 
+ 	return ret;
+ }
+@@ -1797,21 +1778,14 @@ static int isp116x_suspend(struct device
+ /*
+   Resume platform device
+ */
+-static int isp116x_resume(struct device *dev, u32 phase)
++static int isp116x_resume(struct device *dev)
+ {
+ 	int ret = 0;
+-	struct usb_hcd *hcd = dev_get_drvdata(dev);
+ 
+-	VDBG("%s:  state %x, phase %x\n", __func__, dev->power.power_state,
+-	     phase);
+-	if (phase != RESUME_POWER_ON)
+-		return 0;
++	VDBG("%s:  state %x\n", __func__, dev->power.power_state);
++
++	dev->power.power_state = PMSG_ON;
+ 
+-	ret = usb_resume_device(hcd->self.root_hub);
+-	if (!ret) {
+-		dev->power.power_state = PMSG_ON;
+-		VDBG("%s resumed\n", (char *)hcd_name);
+-	}
+ 	return ret;
+ }
+ 
+diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
+--- a/drivers/usb/host/isp116x.h
++++ b/drivers/usb/host/isp116x.h
+@@ -253,7 +253,6 @@ static const int cc_to_error[16] = {
+ 
+ struct isp116x {
+ 	spinlock_t lock;
+-	struct work_struct rh_resume;
+ 
+ 	void __iomem *addr_reg;
+ 	void __iomem *data_reg;
+diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
+--- a/drivers/usb/host/ohci-au1xxx.c
++++ b/drivers/usb/host/ohci-au1xxx.c
+@@ -18,6 +18,8 @@
+  * This file is licenced under the GPL.
+  */
+ 
++#include <linux/platform_device.h>
++
+ #include <asm/mach-au1x00/au1000.h>
+ 
+ #define USBH_ENABLE_BE (1<<0)
+@@ -214,6 +216,11 @@ static const struct hc_driver ohci_au1xx
+ 	 */
+ 	.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,
+ };
+ 
+ /*-------------------------------------------------------------------------*/
+@@ -259,6 +266,7 @@ static int ohci_hcd_au1xxx_drv_resume(st
+ 
+ static struct device_driver ohci_hcd_au1xxx_driver = {
+ 	.name		= "au1xxx-ohci",
++	.owner		= THIS_MODULE,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= ohci_hcd_au1xxx_drv_probe,
+ 	.remove		= ohci_hcd_au1xxx_drv_remove,
+diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
+--- a/drivers/usb/host/ohci-dbg.c
++++ b/drivers/usb/host/ohci-dbg.c
+@@ -193,10 +193,6 @@ ohci_dump_status (struct ohci_hcd *contr
+ 
+ 	maybe_print_eds (controller, "donehead",
+ 			ohci_readl (controller, &regs->donehead), next, size);
+-
+-	/* broken fminterval means traffic won't flow! */ 
+-	ohci_dbg (controller, "fminterval %08x\n", 
+-			ohci_readl (controller, &regs->fminterval));
+ }
+ 
+ #define dbg_port_sw(hc,num,value,next,size) \
+diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -180,7 +180,7 @@ static int ohci_urb_enqueue (
+ 	struct usb_hcd	*hcd,
+ 	struct usb_host_endpoint *ep,
+ 	struct urb	*urb,
+-	unsigned	mem_flags
++	gfp_t		mem_flags
+ ) {
+ 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+ 	struct ed	*ed;
+@@ -723,7 +723,7 @@ static irqreturn_t ohci_irq (struct usb_
+ 		ohci_vdbg (ohci, "resume detect\n");
+ 		ohci_writel (ohci, OHCI_INTR_RD, &regs->intrstatus);
+ 		if (hcd->state != HC_STATE_QUIESCING)
+-			schedule_work(&ohci->rh_resume);
++			usb_hcd_resume_root_hub(hcd);
+ 	}
+ 
+ 	if (ints & OHCI_INTR_WDH) {
+@@ -791,7 +791,7 @@ static void ohci_stop (struct usb_hcd *h
+ 
+ /* must not be called from interrupt context */
+ 
+-#if	defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM)
++#ifdef	CONFIG_PM
+ 
+ static int ohci_restart (struct ohci_hcd *ohci)
+ {
+diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
+--- a/drivers/usb/host/ohci-hub.c
++++ b/drivers/usb/host/ohci-hub.c
+@@ -36,7 +36,7 @@
+ 
+ /*-------------------------------------------------------------------------*/
+ 
+-#if	defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM)
++#ifdef	CONFIG_PM
+ 
+ #define OHCI_SCHED_ENABLES \
+ 	(OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
+@@ -45,7 +45,7 @@ static void dl_done_list (struct ohci_hc
+ static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *);
+ static int ohci_restart (struct ohci_hcd *ohci);
+ 
+-static int ohci_hub_suspend (struct usb_hcd *hcd)
++static int ohci_bus_suspend (struct usb_hcd *hcd)
+ {
+ 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
+ 	int			status = 0;
+@@ -73,7 +73,6 @@ static int ohci_hub_suspend (struct usb_
+ 	ohci_dbg (ohci, "suspend root hub\n");
+ 
+ 	/* First stop any processing */
+-	hcd->state = HC_STATE_QUIESCING;
+ 	if (ohci->hc_control & OHCI_SCHED_ENABLES) {
+ 		int		limit;
+ 
+@@ -108,7 +107,9 @@ static int ohci_hub_suspend (struct usb_
+ 	else
+ 		ohci->hc_control &= ~OHCI_CTRL_RWE;
+ 
+-	/* Suspend hub */
++	/* Suspend hub ... this is the "global (to this bus) suspend" mode,
++	 * which doesn't imply ports will first be individually suspended.
++	 */
+ 	ohci->hc_control &= ~OHCI_CTRL_HCFS;
+ 	ohci->hc_control |= OHCI_USB_SUSPEND;
+ 	ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
+@@ -118,8 +119,9 @@ static int ohci_hub_suspend (struct usb_
+ 	ohci->next_statechange = jiffies + msecs_to_jiffies (5);
+ 
+ done:
++	/* external suspend vs self autosuspend ... same effect */
+ 	if (status == 0)
+-		hcd->state = HC_STATE_SUSPENDED;
++		usb_hcd_suspend_root_hub(hcd);
+ 	spin_unlock_irqrestore (&ohci->lock, flags);
+ 	return status;
+ }
+@@ -133,7 +135,7 @@ static inline struct ed *find_head (stru
+ }
+ 
+ /* caller has locked the root hub */
+-static int ohci_hub_resume (struct usb_hcd *hcd)
++static int ohci_bus_resume (struct usb_hcd *hcd)
+ {
+ 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
+ 	u32			temp, enables;
+@@ -146,7 +148,7 @@ static int ohci_hub_resume (struct usb_h
+ 	ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
+ 
+ 	if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
+-		/* this can happen after suspend-to-disk */
++		/* this can happen after resuming a swsusp snapshot */
+ 		if (hcd->state == HC_STATE_RESUMING) {
+ 			ohci_dbg (ohci, "BIOS/SMM active, control %03x\n",
+ 					ohci->hc_control);
+@@ -169,11 +171,12 @@ static int ohci_hub_resume (struct usb_h
+ 		ohci_info (ohci, "wakeup\n");
+ 		break;
+ 	case OHCI_USB_OPER:
+-		ohci_dbg (ohci, "already resumed\n");
+-		status = 0;
++		/* this can happen after resuming a swsusp snapshot */
++		ohci_dbg (ohci, "snapshot resume? reinit\n");
++		status = -EBUSY;
+ 		break;
+ 	default:		/* RESET, we lost power */
+-		ohci_dbg (ohci, "root hub hardware reset\n");
++		ohci_dbg (ohci, "lost power\n");
+ 		status = -EBUSY;
+ 	}
+ 	spin_unlock_irq (&ohci->lock);
+@@ -198,8 +201,7 @@ static int ohci_hub_resume (struct usb_h
+ 	}
+ 
+ 	/* Some controllers (lucent erratum) need extra-long delays */
+-	hcd->state = HC_STATE_RESUMING;
+-	mdelay (20 /* usb 11.5.1.10 */ + 15);
++	msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1);
+ 
+ 	temp = ohci_readl (ohci, &ohci->regs->control);
+ 	temp &= OHCI_CTRL_HCFS;
+@@ -273,28 +275,10 @@ static int ohci_hub_resume (struct usb_h
+ 		(void) ohci_readl (ohci, &ohci->regs->control);
+ 	}
+ 
+-	hcd->state = HC_STATE_RUNNING;
+ 	return 0;
+ }
+ 
+-static void ohci_rh_resume (void *_hcd)
+-{
+-	struct usb_hcd	*hcd = _hcd;
+-
+-	usb_lock_device (hcd->self.root_hub);
+-	(void) ohci_hub_resume (hcd);
+-	usb_unlock_device (hcd->self.root_hub);
+-}
+-
+-#else
+-
+-static void ohci_rh_resume (void *_hcd)
+-{
+-	struct ohci_hcd	*ohci = hcd_to_ohci (_hcd);
+-	ohci_dbg(ohci, "rh_resume ??\n");
+-}
+-
+-#endif	/* CONFIG_USB_SUSPEND || CONFIG_PM */
++#endif	/* CONFIG_PM */
+ 
+ /*-------------------------------------------------------------------------*/
+ 
+@@ -367,7 +351,6 @@ done:
+ #ifdef CONFIG_PM
+ 	/* save power by suspending idle root hubs;
+ 	 * INTR_RD wakes us when there's work
+-	 * NOTE: if we can do this, we don't need a root hub timer!
+ 	 */
+ 	if (can_suspend
+ 			&& !changed
+@@ -379,8 +362,7 @@ done:
+ 			&& usb_trylock_device (hcd->self.root_hub)
+ 			) {
+ 		ohci_vdbg (ohci, "autosuspend\n");
+-		(void) ohci_hub_suspend (hcd);
+-		hcd->state = HC_STATE_RUNNING;
++		(void) ohci_bus_suspend (hcd);
+ 		usb_unlock_device (hcd->self.root_hub);
+ 	}
+ #endif
+@@ -554,7 +536,7 @@ static int ohci_hub_control (
+ 			temp = RH_PS_POCI;
+ 			if ((ohci->hc_control & OHCI_CTRL_HCFS)
+ 					!= OHCI_USB_OPER)
+-				schedule_work (&ohci->rh_resume);
++				usb_hcd_resume_root_hub(hcd);
+ 			break;
+ 		case USB_PORT_FEAT_C_SUSPEND:
+ 			temp = RH_PS_PSSC;
+diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
+--- a/drivers/usb/host/ohci-lh7a404.c
++++ b/drivers/usb/host/ohci-lh7a404.c
+@@ -16,6 +16,8 @@
+  * This file is licenced under the GPL.
+  */
+ 
++#include <linux/platform_device.h>
++
+ #include <asm/hardware.h>
+ 
+ 
+@@ -193,6 +195,11 @@ static const struct hc_driver ohci_lh7a4
+ 	 */
+ 	.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,
+ };
+ 
+ /*-------------------------------------------------------------------------*/
+@@ -239,6 +246,7 @@ static int ohci_hcd_lh7a404_drv_resume(s
+ 
+ static struct device_driver ohci_hcd_lh7a404_driver = {
+ 	.name		= "lh7a404-ohci",
++	.owner		= THIS_MODULE,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= ohci_hcd_lh7a404_drv_probe,
+ 	.remove		= ohci_hcd_lh7a404_drv_remove,
+diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
+--- a/drivers/usb/host/ohci-mem.c
++++ b/drivers/usb/host/ohci-mem.c
+@@ -28,7 +28,6 @@ static void ohci_hcd_init (struct ohci_h
+ 	ohci->next_statechange = jiffies;
+ 	spin_lock_init (&ohci->lock);
+ 	INIT_LIST_HEAD (&ohci->pending);
+-	INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci));
+ 	ohci->reboot_notifier.notifier_call = ohci_reboot;
+ }
+ 
+@@ -84,7 +83,7 @@ dma_to_td (struct ohci_hcd *hc, dma_addr
+ 
+ /* TDs ... */
+ static struct td *
+-td_alloc (struct ohci_hcd *hc, unsigned mem_flags)
++td_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
+ {
+ 	dma_addr_t	dma;
+ 	struct td	*td;
+@@ -118,7 +117,7 @@ td_free (struct ohci_hcd *hc, struct td 
+ 
+ /* EDs ... */
+ static struct ed *
+-ed_alloc (struct ohci_hcd *hc, unsigned mem_flags)
++ed_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
+ {
+ 	dma_addr_t	dma;
+ 	struct ed	*ed;
+diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
+--- a/drivers/usb/host/ohci-omap.c
++++ b/drivers/usb/host/ohci-omap.c
+@@ -14,6 +14,10 @@
+  * This file is licenced under the GPL.
+  */
+ 
++#include <linux/signal.h>	/* SA_INTERRUPT */
++#include <linux/jiffies.h>
++#include <linux/platform_device.h>
++
+ #include <asm/hardware.h>
+ #include <asm/io.h>
+ #include <asm/mach-types.h>
+@@ -420,9 +424,9 @@ static const struct hc_driver ohci_omap_
+ 	 */
+ 	.hub_status_data =	ohci_hub_status_data,
+ 	.hub_control =		ohci_hub_control,
+-#ifdef	CONFIG_USB_SUSPEND
+-	.hub_suspend =		ohci_hub_suspend,
+-	.hub_resume =		ohci_hub_resume,
++#ifdef	CONFIG_PM
++	.bus_suspend =		ohci_bus_suspend,
++	.bus_resume =		ohci_bus_resume,
+ #endif
+ 	.start_port_reset =	ohci_start_port_reset,
+ };
+@@ -455,50 +459,32 @@ static int ohci_hcd_omap_drv_remove(stru
+ 
+ #ifdef	CONFIG_PM
+ 
+-static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level)
++static int ohci_omap_suspend(struct device *dev, pm_message_t message)
+ {
+ 	struct ohci_hcd	*ohci = hcd_to_ohci(dev_get_drvdata(dev));
+-	int		status = -EINVAL;
+ 
+-	if (level != SUSPEND_POWER_DOWN)
+-		return 0;
++	if (time_before(jiffies, ohci->next_statechange))
++		msleep(5);
++	ohci->next_statechange = jiffies;
+ 
+-	down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+-	status = ohci_hub_suspend(ohci_to_hcd(ohci));
+-	if (status == 0) {
+-		omap_ohci_clock_power(0);
+-		ohci_to_hcd(ohci)->self.root_hub->state =
+-			USB_STATE_SUSPENDED;
+-		ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
+-		dev->power.power_state = PMSG_SUSPEND;
+-	}
+-	up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+-	return status;
++	omap_ohci_clock_power(0);
++	ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
++	dev->power.power_state = PMSG_SUSPEND;
++	return 0;
+ }
+ 
+-static int ohci_omap_resume(struct device *dev, u32 level)
++static int ohci_omap_resume(struct device *dev)
+ {
+ 	struct ohci_hcd	*ohci = hcd_to_ohci(dev_get_drvdata(dev));
+-	int		status = 0;
+-
+-	if (level != RESUME_POWER_ON)
+-		return 0;
+ 
+ 	if (time_before(jiffies, ohci->next_statechange))
+ 		msleep(5);
+ 	ohci->next_statechange = jiffies;
++
+ 	omap_ohci_clock_power(1);
+-#ifdef	CONFIG_USB_SUSPEND
+-	/* get extra cleanup even if remote wakeup isn't in use */
+-	status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
+-#else
+-	down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+-	status = ohci_hub_resume(ohci_to_hcd(ohci));
+-	up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+-#endif
+-	if (status == 0)
+-		dev->power.power_state = PMSG_ON;
+-	return status;
++	dev->power.power_state = PMSG_ON;
++	usb_hcd_resume_root_hub(dev_get_drvdata(dev));
++	return 0;
+ }
+ 
+ #endif
+@@ -510,6 +496,7 @@ static int ohci_omap_resume(struct devic
+  */
+ static struct device_driver ohci_hcd_omap_driver = {
+ 	.name		= "ohci",
++	.owner		= THIS_MODULE,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= ohci_hcd_omap_drv_probe,
+ 	.remove		= ohci_hcd_omap_drv_remove,
+diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
+--- a/drivers/usb/host/ohci-pci.c
++++ b/drivers/usb/host/ohci-pci.c
+@@ -14,6 +14,8 @@
+  * This file is licenced under the GPL.
+  */
+  
++#include <linux/jiffies.h>
++
+ #ifdef CONFIG_PPC_PMAC
+ #include <asm/machdep.h>
+ #include <asm/pmac_feature.h>
+@@ -112,23 +114,13 @@ ohci_pci_start (struct usb_hcd *hcd)
+ 
+ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
+ {
+-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
+-
+-	/* suspend root hub, hoping it keeps power during suspend */
+-	if (time_before (jiffies, ohci->next_statechange))
+-		msleep (100);
+-
+-#ifdef	CONFIG_USB_SUSPEND
+-	(void) usb_suspend_device (hcd->self.root_hub, message);
+-#else
+-	usb_lock_device (hcd->self.root_hub);
+-	(void) ohci_hub_suspend (hcd);
+-	usb_unlock_device (hcd->self.root_hub);
+-#endif
++	/* root hub was already suspended */
+ 
+-	/* let things settle down a bit */
+-	msleep (100);
+-	
++	/* FIXME these PMAC things get called in the wrong places.  ASIC
++	 * clocks should be turned off AFTER entering D3, and on BEFORE
++	 * trying to enter D0.  Evidently the PCI layer doesn't currently
++	 * provide the right sort of platform hooks for this ...
++	 */
+ #ifdef CONFIG_PPC_PMAC
+ 	if (_machine == _MACH_Pmac) {
+ 	   	struct device_node	*of_node;
+@@ -145,9 +137,6 @@ static int ohci_pci_suspend (struct usb_
+ 
+ static int ohci_pci_resume (struct usb_hcd *hcd)
+ {
+-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
+-	int			retval = 0;
+-
+ #ifdef CONFIG_PPC_PMAC
+ 	if (_machine == _MACH_Pmac) {
+ 		struct device_node *of_node;
+@@ -159,19 +148,8 @@ static int ohci_pci_resume (struct usb_h
+ 	}
+ #endif /* CONFIG_PPC_PMAC */
+ 
+-	/* resume root hub */
+-	if (time_before (jiffies, ohci->next_statechange))
+-		msleep (100);
+-#ifdef	CONFIG_USB_SUSPEND
+-	/* get extra cleanup even if remote wakeup isn't in use */
+-	retval = usb_resume_device (hcd->self.root_hub);
+-#else
+-	usb_lock_device (hcd->self.root_hub);
+-	retval = ohci_hub_resume (hcd);
+-	usb_unlock_device (hcd->self.root_hub);
+-#endif
+-
+-	return retval;
++	usb_hcd_resume_root_hub(hcd);
++	return 0;
+ }
+ 
+ #endif	/* CONFIG_PM */
+@@ -218,9 +196,9 @@ static const struct hc_driver ohci_pci_h
+ 	 */
+ 	.hub_status_data =	ohci_hub_status_data,
+ 	.hub_control =		ohci_hub_control,
+-#ifdef	CONFIG_USB_SUSPEND
+-	.hub_suspend =		ohci_hub_suspend,
+-	.hub_resume =		ohci_hub_resume,
++#ifdef	CONFIG_PM
++	.bus_suspend =		ohci_bus_suspend,
++	.bus_resume =		ohci_bus_resume,
+ #endif
+ 	.start_port_reset =	ohci_start_port_reset,
+ };
+@@ -240,6 +218,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
+ static struct pci_driver ohci_pci_driver = {
+ 	.name =		(char *) hcd_name,
+ 	.id_table =	pci_ids,
++	.owner =	THIS_MODULE,
+ 
+ 	.probe =	usb_hcd_pci_probe,
+ 	.remove =	usb_hcd_pci_remove,
+diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
+--- a/drivers/usb/host/ohci-ppc-soc.c
++++ b/drivers/usb/host/ohci-ppc-soc.c
+@@ -14,6 +14,8 @@
+  * This file is licenced under the GPL.
+  */
+ 
++#include <linux/platform_device.h>
++
+ /* configure so an HC device and id are always provided */
+ /* always called with process context; sleeping is OK */
+ 
+@@ -163,9 +165,9 @@ static const struct hc_driver ohci_ppc_s
+ 	 */
+ 	.hub_status_data =	ohci_hub_status_data,
+ 	.hub_control =		ohci_hub_control,
+-#ifdef	CONFIG_USB_SUSPEND
+-	.hub_suspend =		ohci_hub_suspend,
+-	.hub_resume =		ohci_hub_resume,
++#ifdef	CONFIG_PM
++	.bus_suspend =		ohci_bus_suspend,
++	.bus_resume =		ohci_bus_resume,
+ #endif
+ 	.start_port_reset =	ohci_start_port_reset,
+ };
+@@ -193,10 +195,11 @@ static int ohci_hcd_ppc_soc_drv_remove(s
+ 
+ static struct device_driver ohci_hcd_ppc_soc_driver = {
+ 	.name		= "ppc-soc-ohci",
++	.owner		= THIS_MODULE,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= ohci_hcd_ppc_soc_drv_probe,
+ 	.remove		= ohci_hcd_ppc_soc_drv_remove,
+-#if	defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM)
++#ifdef	CONFIG_PM
+ 	/*.suspend	= ohci_hcd_ppc_soc_drv_suspend,*/
+ 	/*.resume	= ohci_hcd_ppc_soc_drv_resume,*/
+ #endif
+diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
+--- a/drivers/usb/host/ohci-pxa27x.c
++++ b/drivers/usb/host/ohci-pxa27x.c
+@@ -20,6 +20,9 @@
+  */
+ 
+ #include <linux/device.h>
++#include <linux/signal.h>
++#include <linux/platform_device.h>
++
+ #include <asm/mach-types.h>
+ #include <asm/hardware.h>
+ #include <asm/arch/pxa-regs.h>
+@@ -278,10 +281,11 @@ static const struct hc_driver ohci_pxa27
+ 	 */
+ 	.hub_status_data =	ohci_hub_status_data,
+ 	.hub_control =		ohci_hub_control,
+-#ifdef  CONFIG_USB_SUSPEND
+-	.hub_suspend =		ohci_hub_suspend,
+-	.hub_resume =		ohci_hub_resume,
++#ifdef  CONFIG_PM
++	.bus_suspend =		ohci_bus_suspend,
++	.bus_resume =		ohci_bus_resume,
+ #endif
++	.start_port_reset =	ohci_start_port_reset,
+ };
+ 
+ /*-------------------------------------------------------------------------*/
+@@ -309,7 +313,7 @@ static int ohci_hcd_pxa27x_drv_remove(st
+ 	return 0;
+ }
+ 
+-static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state, u32 level)
++static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state)
+ {
+ //	struct platform_device *pdev = to_platform_device(dev);
+ //	struct usb_hcd *hcd = dev_get_drvdata(dev);
+@@ -318,7 +322,7 @@ static int ohci_hcd_pxa27x_drv_suspend(s
+ 	return 0;
+ }
+ 
+-static int ohci_hcd_pxa27x_drv_resume(struct device *dev, u32 level)
++static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
+ {
+ //	struct platform_device *pdev = to_platform_device(dev);
+ //	struct usb_hcd *hcd = dev_get_drvdata(dev);
+diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
+--- a/drivers/usb/host/ohci-s3c2410.c
++++ b/drivers/usb/host/ohci-s3c2410.c
+@@ -19,6 +19,8 @@
+  * This file is licenced under the GPL.
+ */
+ 
++#include <linux/platform_device.h>
++
+ #include <asm/hardware.h>
+ #include <asm/hardware/clock.h>
+ #include <asm/arch/usb-control.h>
+@@ -448,11 +450,11 @@ static const struct hc_driver ohci_s3c24
+ 	 */
+ 	.hub_status_data =	ohci_s3c2410_hub_status_data,
+ 	.hub_control =		ohci_s3c2410_hub_control,
+-
+-#if defined(CONFIG_USB_SUSPEND) && 0
+-	.hub_suspend =		ohci_hub_suspend,
+-	.hub_resume =		ohci_hub_resume,
++#ifdef	CONFIG_PM
++	.bus_suspend =		ohci_bus_suspend,
++	.bus_resume =		ohci_bus_resume,
+ #endif
++	.start_port_reset =	ohci_start_port_reset,
+ };
+ 
+ /* device driver */
+@@ -474,6 +476,7 @@ static int ohci_hcd_s3c2410_drv_remove(s
+ 
+ static struct device_driver ohci_hcd_s3c2410_driver = {
+ 	.name		= "s3c2410-ohci",
++	.owner		= THIS_MODULE,
+ 	.bus		= &platform_bus_type,
+ 	.probe		= ohci_hcd_s3c2410_drv_probe,
+ 	.remove		= ohci_hcd_s3c2410_drv_remove,
+diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
+--- a/drivers/usb/host/ohci-sa1111.c
++++ b/drivers/usb/host/ohci-sa1111.c
+@@ -235,10 +235,11 @@ static const struct hc_driver ohci_sa111
+ 	 */
+ 	.hub_status_data =	ohci_hub_status_data,
+ 	.hub_control =		ohci_hub_control,
+-#ifdef	CONFIG_USB_SUSPEND
+-	.hub_suspend =		ohci_hub_suspend,
+-	.hub_resume =		ohci_hub_resume,
++#ifdef	CONFIG_PM
++	.bus_suspend =		ohci_bus_suspend,
++	.bus_resume =		ohci_bus_resume,
+ #endif
++	.start_port_reset =	ohci_start_port_reset,
+ };
+ 
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
+--- a/drivers/usb/host/ohci.h
++++ b/drivers/usb/host/ohci.h
+@@ -389,7 +389,6 @@ struct ohci_hcd {
+ 	unsigned long		next_statechange;	/* suspend/resume */
+ 	u32			fminterval;		/* saved register */
+ 
+-	struct work_struct	rh_resume;
+ 	struct notifier_block	reboot_notifier;
+ 
+ 	unsigned long		flags;		/* for HC bugs */
+diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/usb/host/pci-quirks.c
+@@ -0,0 +1,319 @@
++/*
++ * This file contains code to reset and initialize USB host controllers.
++ * Some of it includes work-arounds for PCI hardware and BIOS quirks.
++ * It may need to run early during booting -- before USB would normally
++ * initialize -- to ensure that Linux doesn't use any legacy modes.
++ *
++ *  Copyright (c) 1999 Martin Mares <mj at ucw.cz>
++ *  (and others)
++ */
++
++#include <linux/config.h>
++#ifdef CONFIG_USB_DEBUG
++#define DEBUG
++#else
++#undef DEBUG
++#endif
++
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/acpi.h>
++
++
++#define UHCI_USBLEGSUP		0xc0		/* legacy support */
++#define UHCI_USBCMD		0		/* command register */
++#define UHCI_USBINTR		4		/* interrupt register */
++#define UHCI_USBLEGSUP_RWC	0x8f00		/* the R/WC bits */
++#define UHCI_USBLEGSUP_RO	0x5040		/* R/O and reserved bits */
++#define UHCI_USBCMD_RUN		0x0001		/* RUN/STOP bit */
++#define UHCI_USBCMD_HCRESET	0x0002		/* Host Controller reset */
++#define UHCI_USBCMD_EGSM	0x0008		/* Global Suspend Mode */
++#define UHCI_USBCMD_CONFIGURE	0x0040		/* Config Flag */
++#define UHCI_USBINTR_RESUME	0x0002		/* Resume interrupt enable */
++
++#define OHCI_CONTROL		0x04
++#define OHCI_CMDSTATUS		0x08
++#define OHCI_INTRSTATUS		0x0c
++#define OHCI_INTRENABLE		0x10
++#define OHCI_INTRDISABLE	0x14
++#define OHCI_OCR		(1 << 3)	/* ownership change request */
++#define OHCI_CTRL_RWC		(1 << 9)	/* remote wakeup connected */
++#define OHCI_CTRL_IR		(1 << 8)	/* interrupt routing */
++#define OHCI_INTR_OC		(1 << 30)	/* ownership change */
++
++#define EHCI_HCC_PARAMS		0x08		/* extended capabilities */
++#define EHCI_USBCMD		0		/* command register */
++#define EHCI_USBCMD_RUN		(1 << 0)	/* RUN/STOP bit */
++#define EHCI_USBSTS		4		/* status register */
++#define EHCI_USBSTS_HALTED	(1 << 12)	/* HCHalted bit */
++#define EHCI_USBINTR		8		/* interrupt register */
++#define EHCI_USBLEGSUP		0		/* legacy support register */
++#define EHCI_USBLEGSUP_BIOS	(1 << 16)	/* BIOS semaphore */
++#define EHCI_USBLEGSUP_OS	(1 << 24)	/* OS semaphore */
++#define EHCI_USBLEGCTLSTS	4		/* legacy control/status */
++#define EHCI_USBLEGCTLSTS_SOOE	(1 << 13)	/* SMI on ownership change */
++
++
++/*
++ * Make sure the controller is completely inactive, unable to
++ * generate interrupts or do DMA.
++ */
++void uhci_reset_hc(struct pci_dev *pdev, unsigned long base)
++{
++	/* Turn off PIRQ enable and SMI enable.  (This also turns off the
++	 * BIOS's USB Legacy Support.)  Turn off all the R/WC bits too.
++	 */
++	pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC);
++
++	/* Reset the HC - this will force us to get a
++	 * new notification of any already connected
++	 * ports due to the virtual disconnect that it
++	 * implies.
++	 */
++	outw(UHCI_USBCMD_HCRESET, base + UHCI_USBCMD);
++	mb();
++	udelay(5);
++	if (inw(base + UHCI_USBCMD) & UHCI_USBCMD_HCRESET)
++		dev_warn(&pdev->dev, "HCRESET not completed yet!\n");
++
++	/* Just to be safe, disable interrupt requests and
++	 * make sure the controller is stopped.
++	 */
++	outw(0, base + UHCI_USBINTR);
++	outw(0, base + UHCI_USBCMD);
++}
++EXPORT_SYMBOL_GPL(uhci_reset_hc);
++
++/*
++ * Initialize a controller that was newly discovered or has just been
++ * resumed.  In either case we can't be sure of its previous state.
++ *
++ * Returns: 1 if the controller was reset, 0 otherwise.
++ */
++int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
++{
++	u16 legsup;
++	unsigned int cmd, intr;
++
++	/*
++	 * When restarting a suspended controller, we expect all the
++	 * settings to be the same as we left them:
++	 *
++	 *	PIRQ and SMI disabled, no R/W bits set in USBLEGSUP;
++	 *	Controller is stopped and configured with EGSM set;
++	 *	No interrupts enabled except possibly Resume Detect.
++	 *
++	 * If any of these conditions are violated we do a complete reset.
++	 */
++	pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup);
++	if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) {
++		dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n",
++				__FUNCTION__, legsup);
++		goto reset_needed;
++	}
++
++	cmd = inw(base + UHCI_USBCMD);
++	if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) ||
++			!(cmd & UHCI_USBCMD_EGSM)) {
++		dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n",
++				__FUNCTION__, cmd);
++		goto reset_needed;
++	}
++
++	intr = inw(base + UHCI_USBINTR);
++	if (intr & (~UHCI_USBINTR_RESUME)) {
++		dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n",
++				__FUNCTION__, intr);
++		goto reset_needed;
++	}
++	return 0;
++
++reset_needed:
++	dev_dbg(&pdev->dev, "Performing full reset\n");
++	uhci_reset_hc(pdev, base);
++	return 1;
++}
++EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
++
++static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
++{
++	u16 cmd;
++	return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
++}
++
++#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
++#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
++
++static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
++{
++	unsigned long base = 0;
++	int i;
++
++	if (!pio_enabled(pdev))
++		return;
++
++	for (i = 0; i < PCI_ROM_RESOURCE; i++)
++		if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
++			base = pci_resource_start(pdev, i);
++			break;
++		}
++
++	if (base)
++		uhci_check_and_reset_hc(pdev, base);
++}
++
++static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
++{
++	return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
++}
++
++static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
++{
++	void __iomem *base;
++	int wait_time;
++	u32 control;
++
++	if (!mmio_resource_enabled(pdev, 0))
++		return;
++
++	base = ioremap_nocache(pci_resource_start(pdev, 0),
++				     pci_resource_len(pdev, 0));
++	if (base == NULL) return;
++
++/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
++#ifndef __hppa__
++	control = readl(base + OHCI_CONTROL);
++	if (control & OHCI_CTRL_IR) {
++		wait_time = 500; /* arbitrary; 5 seconds */
++		writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
++		writel(OHCI_OCR, base + OHCI_CMDSTATUS);
++		while (wait_time > 0 &&
++				readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
++			wait_time -= 10;
++			msleep(10);
++		}
++		if (wait_time <= 0)
++			printk(KERN_WARNING "%s %s: early BIOS handoff "
++					"failed (BIOS bug ?)\n",
++					pdev->dev.bus_id, "OHCI");
++
++		/* reset controller, preserving RWC */
++		writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL);
++	}
++#endif
++
++	/*
++	 * disable interrupts
++	 */
++	writel(~(u32)0, base + OHCI_INTRDISABLE);
++	writel(~(u32)0, base + OHCI_INTRSTATUS);
++
++	iounmap(base);
++}
++
++static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
++{
++	int wait_time, delta;
++	void __iomem *base, *op_reg_base;
++	u32 hcc_params, val, temp;
++	u8 cap_length;
++
++	if (!mmio_resource_enabled(pdev, 0))
++		return;
++
++	base = ioremap_nocache(pci_resource_start(pdev, 0),
++				pci_resource_len(pdev, 0));
++	if (base == NULL) return;
++
++	cap_length = readb(base);
++	op_reg_base = base + cap_length;
++	hcc_params = readl(base + EHCI_HCC_PARAMS);
++	hcc_params = (hcc_params >> 8) & 0xff;
++	if (hcc_params) {
++		pci_read_config_dword(pdev,
++					hcc_params + EHCI_USBLEGSUP,
++					&val);
++		if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) {
++			/*
++			 * Ok, BIOS is in smm mode, try to hand off...
++			 */
++			pci_read_config_dword(pdev,
++						hcc_params + EHCI_USBLEGCTLSTS,
++						&temp);
++			pci_write_config_dword(pdev,
++						hcc_params + EHCI_USBLEGCTLSTS,
++						temp | EHCI_USBLEGCTLSTS_SOOE);
++			val |= EHCI_USBLEGSUP_OS;
++			pci_write_config_dword(pdev,
++						hcc_params + EHCI_USBLEGSUP,
++						val);
++
++			wait_time = 500;
++			do {
++				msleep(10);
++				wait_time -= 10;
++				pci_read_config_dword(pdev,
++						hcc_params + EHCI_USBLEGSUP,
++						&val);
++			} while (wait_time && (val & EHCI_USBLEGSUP_BIOS));
++			if (!wait_time) {
++				/*
++				 * well, possibly buggy BIOS...
++				 */
++				printk(KERN_WARNING "%s %s: early BIOS handoff "
++						"failed (BIOS bug ?)\n",
++					pdev->dev.bus_id, "EHCI");
++				pci_write_config_dword(pdev,
++						hcc_params + EHCI_USBLEGSUP,
++						EHCI_USBLEGSUP_OS);
++				pci_write_config_dword(pdev,
++						hcc_params + EHCI_USBLEGCTLSTS,
++						0);
++			}
++		}
++	}
++
++	/*
++	 * halt EHCI & disable its interrupts in any case
++	 */
++	val = readl(op_reg_base + EHCI_USBSTS);
++	if ((val & EHCI_USBSTS_HALTED) == 0) {
++		val = readl(op_reg_base + EHCI_USBCMD);
++		val &= ~EHCI_USBCMD_RUN;
++		writel(val, op_reg_base + EHCI_USBCMD);
++
++		wait_time = 2000;
++		delta = 100;
++		do {
++			writel(0x3f, op_reg_base + EHCI_USBSTS);
++			udelay(delta);
++			wait_time -= delta;
++			val = readl(op_reg_base + EHCI_USBSTS);
++			if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
++				break;
++			}
++		} while (wait_time > 0);
++	}
++	writel(0, op_reg_base + EHCI_USBINTR);
++	writel(0x3f, op_reg_base + EHCI_USBSTS);
++
++	iounmap(base);
++
++	return;
++}
++
++
++
++static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
++{
++	if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
++		quirk_usb_handoff_uhci(pdev);
++	else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
++		quirk_usb_handoff_ohci(pdev);
++	else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI)
++		quirk_usb_disable_ehci(pdev);
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
+diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
+--- a/drivers/usb/host/sl811-hcd.c
++++ b/drivers/usb/host/sl811-hcd.c
+@@ -54,6 +54,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/usb.h>
+ #include <linux/usb_sl811.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -818,7 +819,7 @@ static int sl811h_urb_enqueue(
+ 	struct usb_hcd		*hcd,
+ 	struct usb_host_endpoint *hep,
+ 	struct urb		*urb,
+-	unsigned		mem_flags
++	gfp_t			mem_flags
+ ) {
+ 	struct sl811		*sl811 = hcd_to_sl811(hcd);
+ 	struct usb_device	*udev = urb->dev;
+@@ -1363,7 +1364,7 @@ error:
+ #ifdef	CONFIG_PM
+ 
+ static int
+-sl811h_hub_suspend(struct usb_hcd *hcd)
++sl811h_bus_suspend(struct usb_hcd *hcd)
+ {
+ 	// SOFs off
+ 	DBG("%s\n", __FUNCTION__);
+@@ -1371,7 +1372,7 @@ sl811h_hub_suspend(struct usb_hcd *hcd)
+ }
+ 
+ static int
+-sl811h_hub_resume(struct usb_hcd *hcd)
++sl811h_bus_resume(struct usb_hcd *hcd)
+ {
+ 	// SOFs on
+ 	DBG("%s\n", __FUNCTION__);
+@@ -1380,8 +1381,8 @@ sl811h_hub_resume(struct usb_hcd *hcd)
+ 
+ #else
+ 
+-#define	sl811h_hub_suspend	NULL
+-#define	sl811h_hub_resume	NULL
++#define	sl811h_bus_suspend	NULL
++#define	sl811h_bus_resume	NULL
+ 
+ #endif
+ 
+@@ -1623,8 +1624,8 @@ static struct hc_driver sl811h_hc_driver
+ 	 */
+ 	.hub_status_data =	sl811h_hub_status_data,
+ 	.hub_control =		sl811h_hub_control,
+-	.hub_suspend =		sl811h_hub_suspend,
+-	.hub_resume =		sl811h_hub_resume,
++	.bus_suspend =		sl811h_bus_suspend,
++	.bus_resume =		sl811h_bus_resume,
+ };
+ 
+ /*-------------------------------------------------------------------------*/
+@@ -1784,17 +1785,14 @@ sl811h_probe(struct device *dev)
+  */
+ 
+ static int
+-sl811h_suspend(struct device *dev, pm_message_t state, u32 phase)
++sl811h_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct usb_hcd	*hcd = dev_get_drvdata(dev);
+ 	struct sl811	*sl811 = hcd_to_sl811(hcd);
+ 	int		retval = 0;
+ 
+-	if (phase != SUSPEND_POWER_DOWN)
+-		return retval;
+-
+ 	if (state.event == PM_EVENT_FREEZE)
+-		retval = sl811h_hub_suspend(hcd);
++		retval = sl811h_bus_suspend(hcd);
+ 	else if (state.event == PM_EVENT_SUSPEND)
+ 		port_power(sl811, 0);
+ 	if (retval == 0)
+@@ -1803,14 +1801,11 @@ sl811h_suspend(struct device *dev, pm_me
+ }
+ 
+ static int
+-sl811h_resume(struct device *dev, u32 phase)
++sl811h_resume(struct device *dev)
+ {
+ 	struct usb_hcd	*hcd = dev_get_drvdata(dev);
+ 	struct sl811	*sl811 = hcd_to_sl811(hcd);
+ 
+-	if (phase != RESUME_POWER_ON)
+-		return 0;
+-
+ 	/* with no "check to see if VBUS is still powered" board hook,
+ 	 * let's assume it'd only be powered to enable remote wakeup.
+ 	 */
+@@ -1822,7 +1817,7 @@ sl811h_resume(struct device *dev, u32 ph
+ 	}
+ 
+ 	dev->power.power_state = PMSG_ON;
+-	return sl811h_hub_resume(hcd);
++	return sl811h_bus_resume(hcd);
+ }
+ 
+ #else
+@@ -1837,6 +1832,7 @@ sl811h_resume(struct device *dev, u32 ph
+ struct device_driver sl811h_driver = {
+ 	.name =		(char *) hcd_name,
+ 	.bus =		&platform_bus_type,
++	.owner =	THIS_MODULE,
+ 
+ 	.probe =	sl811h_probe,
+ 	.remove =	__devexit_p(sl811h_remove),
+diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
+--- a/drivers/usb/host/sl811_cs.c
++++ b/drivers/usb/host/sl811_cs.c
+@@ -19,6 +19,7 @@
+ #include <linux/string.h>
+ #include <linux/timer.h>
+ #include <linux/ioport.h>
++#include <linux/platform_device.h>
+ 
+ #include <pcmcia/cs_types.h>
+ #include <pcmcia/cs.h>
+diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
+--- a/drivers/usb/host/uhci-debug.c
++++ b/drivers/usb/host/uhci-debug.c
+@@ -348,7 +348,6 @@ static int uhci_show_urbp(struct uhci_hc
+ 
+ 	if (urbp->urb->status != -EINPROGRESS)
+ 		out += sprintf(out, "Status=%d ", urbp->urb->status);
+-	//out += sprintf(out, "Inserttime=%lx ",urbp->inserttime);
+ 	//out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime);
+ 
+ 	count = 0;
+@@ -446,11 +445,11 @@ static int uhci_sprint_schedule(struct u
+ 	out += sprintf(out, "Frame List\n");
+ 	for (i = 0; i < UHCI_NUMFRAMES; ++i) {
+ 		int shown = 0;
+-		td = uhci->fl->frame_cpu[i];
++		td = uhci->frame_cpu[i];
+ 		if (!td)
+ 			continue;
+ 
+-		if (td->dma_handle != (dma_addr_t)uhci->fl->frame[i]) {
++		if (td->dma_handle != (dma_addr_t)uhci->frame[i]) {
+ 			show_frame_num();
+ 			out += sprintf(out, "    frame list does not match td->dma_handle!\n");
+ 		}
+diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
+--- a/drivers/usb/host/uhci-hcd.c
++++ b/drivers/usb/host/uhci-hcd.c
+@@ -101,37 +101,16 @@ static void uhci_get_current_frame_numbe
+ #include "uhci-q.c"
+ #include "uhci-hub.c"
+ 
++extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
++extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
++
+ /*
+- * Make sure the controller is completely inactive, unable to
+- * generate interrupts or do DMA.
++ * Finish up a host controller reset and update the recorded state.
+  */
+-static void reset_hc(struct uhci_hcd *uhci)
++static void finish_reset(struct uhci_hcd *uhci)
+ {
+ 	int port;
+ 
+-	/* Turn off PIRQ enable and SMI enable.  (This also turns off the
+-	 * BIOS's USB Legacy Support.)  Turn off all the R/WC bits too.
+-	 */
+-	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+-			USBLEGSUP_RWC);
+-
+-	/* Reset the HC - this will force us to get a
+-	 * new notification of any already connected
+-	 * ports due to the virtual disconnect that it
+-	 * implies.
+-	 */
+-	outw(USBCMD_HCRESET, uhci->io_addr + USBCMD);
+-	mb();
+-	udelay(5);
+-	if (inw(uhci->io_addr + USBCMD) & USBCMD_HCRESET)
+-		dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n");
+-
+-	/* Just to be safe, disable interrupt requests and
+-	 * make sure the controller is stopped.
+-	 */
+-	outw(0, uhci->io_addr + USBINTR);
+-	outw(0, uhci->io_addr + USBCMD);
+-
+ 	/* HCRESET doesn't affect the Suspend, Reset, and Resume Detect
+ 	 * bits in the port status and control registers.
+ 	 * We have to clear them by hand.
+@@ -153,7 +132,8 @@ static void reset_hc(struct uhci_hcd *uh
+  */
+ static void hc_died(struct uhci_hcd *uhci)
+ {
+-	reset_hc(uhci);
++	uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr);
++	finish_reset(uhci);
+ 	uhci->hc_inaccessible = 1;
+ }
+ 
+@@ -163,44 +143,8 @@ static void hc_died(struct uhci_hcd *uhc
+  */
+ static void check_and_reset_hc(struct uhci_hcd *uhci)
+ {
+-	u16 legsup;
+-	unsigned int cmd, intr;
+-
+-	/*
+-	 * When restarting a suspended controller, we expect all the
+-	 * settings to be the same as we left them:
+-	 *
+-	 *	PIRQ and SMI disabled, no R/W bits set in USBLEGSUP;
+-	 *	Controller is stopped and configured with EGSM set;
+-	 *	No interrupts enabled except possibly Resume Detect.
+-	 *
+-	 * If any of these conditions are violated we do a complete reset.
+-	 */
+-	pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup);
+-	if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) {
+-		dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n",
+-				__FUNCTION__, legsup);
+-		goto reset_needed;
+-	}
+-
+-	cmd = inw(uhci->io_addr + USBCMD);
+-	if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) {
+-		dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n",
+-				__FUNCTION__, cmd);
+-		goto reset_needed;
+-	}
+-
+-	intr = inw(uhci->io_addr + USBINTR);
+-	if (intr & (~USBINTR_RESUME)) {
+-		dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n",
+-				__FUNCTION__, intr);
+-		goto reset_needed;
+-	}
+-	return;
+-
+-reset_needed:
+-	dev_dbg(uhci_dev(uhci), "Performing full reset\n");
+-	reset_hc(uhci);
++	if (uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr))
++		finish_reset(uhci);
+ }
+ 
+ /*
+@@ -212,13 +156,13 @@ static void configure_hc(struct uhci_hcd
+ 	outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF);
+ 
+ 	/* Store the frame list base address */
+-	outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD);
++	outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD);
+ 
+ 	/* Set the current frame number */
+ 	outw(uhci->frame_number, uhci->io_addr + USBFRNUM);
+ 
+-	/* Mark controller as running before we enable interrupts */
+-	uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
++	/* Mark controller as not halted before we enable interrupts */
++	uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED;
+ 	mb();
+ 
+ 	/* Enable PIRQ */
+@@ -319,6 +263,7 @@ __acquires(uhci->lock)
+ 
+ static void start_rh(struct uhci_hcd *uhci)
+ {
++	uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
+ 	uhci->is_stopped = 0;
+ 	smp_wmb();
+ 
+@@ -437,36 +382,21 @@ static void release_uhci(struct uhci_hcd
+ 	int i;
+ 
+ 	for (i = 0; i < UHCI_NUM_SKELQH; i++)
+-		if (uhci->skelqh[i]) {
+-			uhci_free_qh(uhci, uhci->skelqh[i]);
+-			uhci->skelqh[i] = NULL;
+-		}
++		uhci_free_qh(uhci, uhci->skelqh[i]);
+ 
+-	if (uhci->term_td) {
+-		uhci_free_td(uhci, uhci->term_td);
+-		uhci->term_td = NULL;
+-	}
++	uhci_free_td(uhci, uhci->term_td);
+ 
+-	if (uhci->qh_pool) {
+-		dma_pool_destroy(uhci->qh_pool);
+-		uhci->qh_pool = NULL;
+-	}
++	dma_pool_destroy(uhci->qh_pool);
+ 
+-	if (uhci->td_pool) {
+-		dma_pool_destroy(uhci->td_pool);
+-		uhci->td_pool = NULL;
+-	}
++	dma_pool_destroy(uhci->td_pool);
+ 
+-	if (uhci->fl) {
+-		dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
+-				uhci->fl, uhci->fl->dma_handle);
+-		uhci->fl = NULL;
+-	}
++	kfree(uhci->frame_cpu);
+ 
+-	if (uhci->dentry) {
+-		debugfs_remove(uhci->dentry);
+-		uhci->dentry = NULL;
+-	}
++	dma_free_coherent(uhci_dev(uhci),
++			UHCI_NUMFRAMES * sizeof(*uhci->frame),
++			uhci->frame, uhci->frame_dma_handle);
++
++	debugfs_remove(uhci->dentry);
+ }
+ 
+ static int uhci_reset(struct usb_hcd *hcd)
+@@ -545,7 +475,6 @@ static int uhci_start(struct usb_hcd *hc
+ 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+ 	int retval = -EBUSY;
+ 	int i;
+-	dma_addr_t dma_handle;
+ 	struct dentry *dentry;
+ 
+ 	hcd->uses_new_polling = 1;
+@@ -579,17 +508,23 @@ static int uhci_start(struct usb_hcd *hc
+ 
+ 	init_waitqueue_head(&uhci->waitqh);
+ 
+-	uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
+-			&dma_handle, 0);
+-	if (!uhci->fl) {
++	uhci->frame = dma_alloc_coherent(uhci_dev(uhci),
++			UHCI_NUMFRAMES * sizeof(*uhci->frame),
++			&uhci->frame_dma_handle, 0);
++	if (!uhci->frame) {
+ 		dev_err(uhci_dev(uhci), "unable to allocate "
+ 				"consistent memory for frame list\n");
+-		goto err_alloc_fl;
++		goto err_alloc_frame;
+ 	}
++	memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame));
+ 
+-	memset((void *)uhci->fl, 0, sizeof(*uhci->fl));
+-
+-	uhci->fl->dma_handle = dma_handle;
++	uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu),
++			GFP_KERNEL);
++	if (!uhci->frame_cpu) {
++		dev_err(uhci_dev(uhci), "unable to allocate "
++				"memory for frame pointers\n");
++		goto err_alloc_frame_cpu;
++	}
+ 
+ 	uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci),
+ 			sizeof(struct uhci_td), 16, 0);
+@@ -672,7 +607,7 @@ static int uhci_start(struct usb_hcd *hc
+ 			irq = 7;
+ 
+ 		/* Only place we don't use the frame list routines */
+-		uhci->fl->frame[i] = UHCI_PTR_QH |
++		uhci->frame[i] = UHCI_PTR_QH |
+ 				cpu_to_le32(uhci->skelqh[irq]->dma_handle);
+ 	}
+ 
+@@ -690,31 +625,29 @@ static int uhci_start(struct usb_hcd *hc
+  * error exits:
+  */
+ err_alloc_skelqh:
+-	for (i = 0; i < UHCI_NUM_SKELQH; i++)
+-		if (uhci->skelqh[i]) {
++	for (i = 0; i < UHCI_NUM_SKELQH; i++) {
++		if (uhci->skelqh[i])
+ 			uhci_free_qh(uhci, uhci->skelqh[i]);
+-			uhci->skelqh[i] = NULL;
+-		}
++	}
+ 
+ 	uhci_free_td(uhci, uhci->term_td);
+-	uhci->term_td = NULL;
+ 
+ err_alloc_term_td:
+ 	dma_pool_destroy(uhci->qh_pool);
+-	uhci->qh_pool = NULL;
+ 
+ err_create_qh_pool:
+ 	dma_pool_destroy(uhci->td_pool);
+-	uhci->td_pool = NULL;
+ 
+ err_create_td_pool:
+-	dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
+-			uhci->fl, uhci->fl->dma_handle);
+-	uhci->fl = NULL;
++	kfree(uhci->frame_cpu);
++
++err_alloc_frame_cpu:
++	dma_free_coherent(uhci_dev(uhci),
++			UHCI_NUMFRAMES * sizeof(*uhci->frame),
++			uhci->frame, uhci->frame_dma_handle);
+ 
+-err_alloc_fl:
++err_alloc_frame:
+ 	debugfs_remove(uhci->dentry);
+-	uhci->dentry = NULL;
+ 
+ err_create_debug_entry:
+ 	return retval;
+@@ -726,7 +659,7 @@ static void uhci_stop(struct usb_hcd *hc
+ 
+ 	spin_lock_irq(&uhci->lock);
+ 	if (!uhci->hc_inaccessible)
+-		reset_hc(uhci);
++		hc_died(uhci);
+ 	uhci_scan_schedule(uhci, NULL);
+ 	spin_unlock_irq(&uhci->lock);
+ 
+@@ -774,14 +707,8 @@ static int uhci_suspend(struct usb_hcd *
+ 	if (uhci->hc_inaccessible)	/* Dead or already suspended */
+ 		goto done;
+ 
+-#ifndef CONFIG_USB_SUSPEND
+-	/* Otherwise this would never happen */
+-	suspend_rh(uhci, UHCI_RH_SUSPENDED);
+-#endif
+-
+ 	if (uhci->rh_state > UHCI_RH_SUSPENDED) {
+ 		dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n");
+-		hcd->state = HC_STATE_RUNNING;
+ 		rc = -EBUSY;
+ 		goto done;
+ 	};
+@@ -820,10 +747,6 @@ static int uhci_resume(struct usb_hcd *h
+ 	check_and_reset_hc(uhci);
+ 	configure_hc(uhci);
+ 
+-#ifndef CONFIG_USB_SUSPEND
+-	/* Otherwise this would never happen */
+-	wakeup_rh(uhci);
+-#endif
+ 	if (uhci->rh_state == UHCI_RH_RESET)
+ 		suspend_rh(uhci, UHCI_RH_SUSPENDED);
+ 
+@@ -881,8 +804,8 @@ static const struct hc_driver uhci_drive
+ #ifdef CONFIG_PM
+ 	.suspend =		uhci_suspend,
+ 	.resume =		uhci_resume,
+-	.hub_suspend =		uhci_rh_suspend,
+-	.hub_resume =		uhci_rh_resume,
++	.bus_suspend =		uhci_rh_suspend,
++	.bus_resume =		uhci_rh_resume,
+ #endif
+ 	.stop =			uhci_stop,
+ 
+@@ -908,6 +831,7 @@ MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
+ static struct pci_driver uhci_pci_driver = {
+ 	.name =		(char *)hcd_name,
+ 	.id_table =	uhci_pci_ids,
++	.owner =	THIS_MODULE,
+ 
+ 	.probe =	usb_hcd_pci_probe,
+ 	.remove =	usb_hcd_pci_remove,
+diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
+--- a/drivers/usb/host/uhci-hcd.h
++++ b/drivers/usb/host/uhci-hcd.h
+@@ -7,6 +7,7 @@
+ #define usb_packetid(pipe)	(usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT)
+ #define PIPE_DEVEP_MASK		0x0007ff00
+ 
++
+ /*
+  * Universal Host Controller Interface data structures and defines
+  */
+@@ -82,15 +83,10 @@
+ #define UHCI_MAX_SOF_NUMBER	2047	/* in an SOF packet */
+ #define CAN_SCHEDULE_FRAMES	1000	/* how far future frames can be scheduled */
+ 
+-struct uhci_frame_list {
+-	__le32 frame[UHCI_NUMFRAMES];
+-
+-	void *frame_cpu[UHCI_NUMFRAMES];
+-
+-	dma_addr_t dma_handle;
+-};
+ 
+-struct urb_priv;
++/*
++ *	Queue Headers
++ */
+ 
+ /*
+  * One role of a QH is to hold a queue of TDs for some endpoint.  Each QH is
+@@ -116,13 +112,13 @@ struct uhci_qh {
+ 
+ 	struct urb_priv *urbp;
+ 
+-	struct list_head list;		/* P: uhci->frame_list_lock */
+-	struct list_head remove_list;	/* P: uhci->remove_list_lock */
++	struct list_head list;
++	struct list_head remove_list;
+ } __attribute__((aligned(16)));
+ 
+ /*
+  * We need a special accessor for the element pointer because it is
+- * subject to asynchronous updates by the controller
++ * subject to asynchronous updates by the controller.
+  */
+ static __le32 inline qh_element(struct uhci_qh *qh) {
+ 	__le32 element = qh->element;
+@@ -131,6 +127,11 @@ static __le32 inline qh_element(struct u
+ 	return element;
+ }
+ 
++
++/*
++ *	Transfer Descriptors
++ */
++
+ /*
+  * for TD <status>:
+  */
+@@ -183,17 +184,10 @@ static __le32 inline qh_element(struct u
+  *
+  * That's silly, the hardware doesn't care. The hardware only cares that
+  * the hardware words are 16-byte aligned, and we can have any amount of
+- * sw space after the TD entry as far as I can tell.
+- *
+- * But let's just go with the documentation, at least for 32-bit machines.
+- * On 64-bit machines we probably want to take advantage of the fact that
+- * hw doesn't really care about the size of the sw-only area.
+- *
+- * Alas, not anymore, we have more than 4 words for software, woops.
+- * Everything still works tho, surprise! -jerdfelt
++ * sw space after the TD entry.
+  *
+  * td->link points to either another TD (not necessarily for the same urb or
+- * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs)
++ * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs).
+  */
+ struct uhci_td {
+ 	/* Hardware fields */
+@@ -205,18 +199,16 @@ struct uhci_td {
+ 	/* Software fields */
+ 	dma_addr_t dma_handle;
+ 
+-	struct urb *urb;
+-
+-	struct list_head list;		/* P: urb->lock */
+-	struct list_head remove_list;	/* P: uhci->td_remove_list_lock */
++	struct list_head list;
++	struct list_head remove_list;
+ 
+ 	int frame;			/* for iso: what frame? */
+-	struct list_head fl_list;	/* P: uhci->frame_list_lock */
++	struct list_head fl_list;
+ } __attribute__((aligned(16)));
+ 
+ /*
+  * We need a special accessor for the control/status word because it is
+- * subject to asynchronous updates by the controller
++ * subject to asynchronous updates by the controller.
+  */
+ static u32 inline td_status(struct uhci_td *td) {
+ 	__le32 status = td->status;
+@@ -227,6 +219,10 @@ static u32 inline td_status(struct uhci_
+ 
+ 
+ /*
++ *	Skeleton Queue Headers
++ */
++
++/*
+  * The UHCI driver places Interrupt, Control and Bulk into QH's both
+  * to group together TD's for one transfer, and also to faciliate queuing
+  * of URB's. To make it easy to insert entries into the schedule, we have
+@@ -256,15 +252,15 @@ static u32 inline td_status(struct uhci_
+  *
+  * The terminating QH is used for 2 reasons:
+  * - To place a terminating TD which is used to workaround a PIIX bug
+- *   (see Intel errata for explanation)
++ *   (see Intel errata for explanation), and
+  * - To loop back to the full-speed control queue for full-speed bandwidth
+- *   reclamation
++ *   reclamation.
+  *
+  * Isochronous transfers are stored before the start of the skeleton
+  * schedule and don't use QH's. While the UHCI spec doesn't forbid the
+- * use of QH's for Isochronous, it doesn't use them either. Since we don't
+- * need to use them either, we follow the spec diagrams in hope that it'll
+- * be more compatible with future UHCI implementations.
++ * use of QH's for Isochronous, it doesn't use them either. And the spec
++ * says that queues never advance on an error completion status, which
++ * makes them totally unsuitable for Isochronous transfers.
+  */
+ 
+ #define UHCI_NUM_SKELQH		12
+@@ -314,8 +310,13 @@ static inline int __interval_to_skel(int
+ 	return 0;				/* int128 for 128-255 ms (Max.) */
+ }
+ 
++
++/*
++ *	The UHCI controller and root hub
++ */
++
+ /*
+- * States for the root hub.
++ * States for the root hub:
+  *
+  * To prevent "bouncing" in the presence of electrical noise,
+  * when there are no devices attached we delay for 1 second in the
+@@ -326,7 +327,7 @@ static inline int __interval_to_skel(int
+  */
+ enum uhci_rh_state {
+ 	/* In the following states the HC must be halted.
+-	 * These two must come first */
++	 * These two must come first. */
+ 	UHCI_RH_RESET,
+ 	UHCI_RH_SUSPENDED,
+ 
+@@ -338,13 +339,13 @@ enum uhci_rh_state {
+ 	UHCI_RH_SUSPENDING,
+ 
+ 	/* In the following states it's an error if the HC is halted.
+-	 * These two must come last */
++	 * These two must come last. */
+ 	UHCI_RH_RUNNING,		/* The normal state */
+ 	UHCI_RH_RUNNING_NODEVS,		/* Running with no devices attached */
+ };
+ 
+ /*
+- * This describes the full uhci information.
++ * The full UHCI controller information:
+  */
+ struct uhci_hcd {
+ 
+@@ -361,7 +362,11 @@ struct uhci_hcd {
+ 	struct uhci_qh *skelqh[UHCI_NUM_SKELQH];	/* Skeleton QH's */
+ 
+ 	spinlock_t lock;
+-	struct uhci_frame_list *fl;		/* P: uhci->lock */
++
++	dma_addr_t frame_dma_handle;		/* Hardware frame list */
++	__le32 *frame;
++	void **frame_cpu;			/* CPU's frame list */
++
+ 	int fsbr;				/* Full-speed bandwidth reclamation */
+ 	unsigned long fsbrtimeout;		/* FSBR delay */
+ 
+@@ -385,22 +390,22 @@ struct uhci_hcd {
+ 	unsigned long ports_timeout;		/* Time to stop signalling */
+ 
+ 	/* Main list of URB's currently controlled by this HC */
+-	struct list_head urb_list;		/* P: uhci->lock */
++	struct list_head urb_list;
+ 
+ 	/* List of QH's that are done, but waiting to be unlinked (race) */
+-	struct list_head qh_remove_list;	/* P: uhci->lock */
++	struct list_head qh_remove_list;
+ 	unsigned int qh_remove_age;		/* Age in frames */
+ 
+ 	/* List of TD's that are done, but waiting to be freed (race) */
+-	struct list_head td_remove_list;	/* P: uhci->lock */
++	struct list_head td_remove_list;
+ 	unsigned int td_remove_age;		/* Age in frames */
+ 
+ 	/* List of asynchronously unlinked URB's */
+-	struct list_head urb_remove_list;	/* P: uhci->lock */
++	struct list_head urb_remove_list;
+ 	unsigned int urb_remove_age;		/* Age in frames */
+ 
+ 	/* List of URB's awaiting completion callback */
+-	struct list_head complete_list;		/* P: uhci->lock */
++	struct list_head complete_list;
+ 
+ 	int rh_numports;			/* Number of root-hub ports */
+ 
+@@ -419,13 +424,17 @@ static inline struct usb_hcd *uhci_to_hc
+ 
+ #define uhci_dev(u)	(uhci_to_hcd(u)->self.controller)
+ 
++
++/*
++ *	Private per-URB data
++ */
+ struct urb_priv {
+ 	struct list_head urb_list;
+ 
+ 	struct urb *urb;
+ 
+ 	struct uhci_qh *qh;		/* QH for this URB */
+-	struct list_head td_list;	/* P: urb->lock */
++	struct list_head td_list;
+ 
+ 	unsigned fsbr : 1;		/* URB turned on FSBR */
+ 	unsigned fsbr_timeout : 1;	/* URB timed out on FSBR */
+@@ -434,12 +443,12 @@ struct urb_priv {
+ 						/*  a control transfer, retrigger */
+ 						/*  the status phase */
+ 
+-	unsigned long inserttime;	/* In jiffies */
+ 	unsigned long fsbrtime;		/* In jiffies */
+ 
+-	struct list_head queue_list;	/* P: uhci->frame_list_lock */
++	struct list_head queue_list;
+ };
+ 
++
+ /*
+  * Locking in uhci.c
+  *
+@@ -459,6 +468,5 @@ struct urb_priv {
+ 
+ #define PCI_VENDOR_ID_GENESYS		0x17a0
+ #define PCI_DEVICE_ID_GL880S_UHCI	0x8083
+-#define PCI_DEVICE_ID_GL880S_EHCI	0x8084
+ 
+ #endif
+diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
+--- a/drivers/usb/host/uhci-q.c
++++ b/drivers/usb/host/uhci-q.c
+@@ -89,10 +89,10 @@ static void uhci_insert_td_frame_list(st
+ 	td->frame = framenum;
+ 
+ 	/* Is there a TD already mapped there? */
+-	if (uhci->fl->frame_cpu[framenum]) {
++	if (uhci->frame_cpu[framenum]) {
+ 		struct uhci_td *ftd, *ltd;
+ 
+-		ftd = uhci->fl->frame_cpu[framenum];
++		ftd = uhci->frame_cpu[framenum];
+ 		ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);
+ 
+ 		list_add_tail(&td->fl_list, &ftd->fl_list);
+@@ -101,29 +101,32 @@ static void uhci_insert_td_frame_list(st
+ 		wmb();
+ 		ltd->link = cpu_to_le32(td->dma_handle);
+ 	} else {
+-		td->link = uhci->fl->frame[framenum];
++		td->link = uhci->frame[framenum];
+ 		wmb();
+-		uhci->fl->frame[framenum] = cpu_to_le32(td->dma_handle);
+-		uhci->fl->frame_cpu[framenum] = td;
++		uhci->frame[framenum] = cpu_to_le32(td->dma_handle);
++		uhci->frame_cpu[framenum] = td;
+ 	}
+ }
+ 
+-static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td)
++static inline void uhci_remove_td_frame_list(struct uhci_hcd *uhci,
++		struct uhci_td *td)
+ {
+ 	/* If it's not inserted, don't remove it */
+-	if (td->frame == -1 && list_empty(&td->fl_list))
++	if (td->frame == -1) {
++		WARN_ON(!list_empty(&td->fl_list));
+ 		return;
++	}
+ 
+-	if (td->frame != -1 && uhci->fl->frame_cpu[td->frame] == td) {
++	if (uhci->frame_cpu[td->frame] == td) {
+ 		if (list_empty(&td->fl_list)) {
+-			uhci->fl->frame[td->frame] = td->link;
+-			uhci->fl->frame_cpu[td->frame] = NULL;
++			uhci->frame[td->frame] = td->link;
++			uhci->frame_cpu[td->frame] = NULL;
+ 		} else {
+ 			struct uhci_td *ntd;
+ 
+ 			ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);
+-			uhci->fl->frame[td->frame] = cpu_to_le32(ntd->dma_handle);
+-			uhci->fl->frame_cpu[td->frame] = ntd;
++			uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle);
++			uhci->frame_cpu[td->frame] = ntd;
+ 		}
+ 	} else {
+ 		struct uhci_td *ptd;
+@@ -132,13 +135,20 @@ static void uhci_remove_td(struct uhci_h
+ 		ptd->link = td->link;
+ 	}
+ 
+-	wmb();
+-	td->link = UHCI_PTR_TERM;
+-
+ 	list_del_init(&td->fl_list);
+ 	td->frame = -1;
+ }
+ 
++static void unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
++{
++	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
++	struct uhci_td *td;
++
++	list_for_each_entry(td, &urbp->td_list, list)
++		uhci_remove_td_frame_list(uhci, td);
++	wmb();
++}
++
+ /*
+  * Inserts a td list into qh.
+  */
+@@ -443,7 +453,6 @@ static struct urb_priv *uhci_alloc_urb_p
+ 
+ 	memset((void *)urbp, 0, sizeof(*urbp));
+ 
+-	urbp->inserttime = jiffies;
+ 	urbp->fsbrtime = jiffies;
+ 	urbp->urb = urb;
+ 	
+@@ -462,8 +471,6 @@ static void uhci_add_td_to_urb(struct ur
+ {
+ 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
+ 
+-	td->urb = urb;
+-
+ 	list_add_tail(&td->list, &urbp->td_list);
+ }
+ 
+@@ -473,8 +480,6 @@ static void uhci_remove_td_from_urb(stru
+ 		return;
+ 
+ 	list_del_init(&td->list);
+-
+-	td->urb = NULL;
+ }
+ 
+ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
+@@ -503,7 +508,6 @@ static void uhci_destroy_urb_priv(struct
+ 
+ 	list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
+ 		uhci_remove_td_from_urb(td);
+-		uhci_remove_td(uhci, td);
+ 		list_add(&td->remove_list, &uhci->td_remove_list);
+ 	}
+ 
+@@ -1073,6 +1077,7 @@ static int uhci_submit_isochronous(struc
+ 	struct uhci_td *td;
+ 	int i, ret, frame;
+ 	int status, destination;
++	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
+ 
+ 	status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
+ 	destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
+@@ -1081,11 +1086,7 @@ static int uhci_submit_isochronous(struc
+ 	if (ret)
+ 		return ret;
+ 
+-	frame = urb->start_frame;
+-	for (i = 0; i < urb->number_of_packets; i++, frame += urb->interval) {
+-		if (!urb->iso_frame_desc[i].length)
+-			continue;
+-
++	for (i = 0; i < urb->number_of_packets; i++) {
+ 		td = uhci_alloc_td(uhci);
+ 		if (!td)
+ 			return -ENOMEM;
+@@ -1096,8 +1097,12 @@ static int uhci_submit_isochronous(struc
+ 
+ 		if (i + 1 >= urb->number_of_packets)
+ 			td->status |= cpu_to_le32(TD_CTRL_IOC);
++	}
+ 
++	frame = urb->start_frame;
++	list_for_each_entry(td, &urbp->td_list, list) {
+ 		uhci_insert_td_frame_list(uhci, td, frame);
++		frame += urb->interval;
+ 	}
+ 
+ 	return -EINPROGRESS;
+@@ -1110,7 +1115,7 @@ static int uhci_result_isochronous(struc
+ 	int status;
+ 	int i, ret = 0;
+ 
+-	urb->actual_length = 0;
++	urb->actual_length = urb->error_count = 0;
+ 
+ 	i = 0;
+ 	list_for_each_entry(td, &urbp->td_list, list) {
+@@ -1134,6 +1139,7 @@ static int uhci_result_isochronous(struc
+ 
+ 		i++;
+ 	}
++	unlink_isochronous_tds(uhci, urb);
+ 
+ 	return ret;
+ }
+@@ -1164,7 +1170,7 @@ static struct urb *uhci_find_urb_ep(stru
+ 
+ static int uhci_urb_enqueue(struct usb_hcd *hcd,
+ 		struct usb_host_endpoint *ep,
+-		struct urb *urb, unsigned mem_flags)
++		struct urb *urb, gfp_t mem_flags)
+ {
+ 	int ret;
+ 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+@@ -1366,6 +1372,8 @@ static int uhci_urb_dequeue(struct usb_h
+ 		goto done;
+ 	list_del_init(&urbp->urb_list);
+ 
++	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
++		unlink_isochronous_tds(uhci, urb);
+ 	uhci_unlink_generic(uhci, urb);
+ 
+ 	uhci_get_current_frame_number(uhci);
+diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
+--- a/drivers/usb/image/mdc800.c
++++ b/drivers/usb/image/mdc800.c
+@@ -425,9 +425,8 @@ static void mdc800_usb_download_notify (
+ static struct usb_driver mdc800_usb_driver;
+ static struct file_operations mdc800_device_ops;
+ static struct usb_class_driver mdc800_class = {
+-	.name =		"usb/mdc800%d",
++	.name =		"mdc800%d",
+ 	.fops =		&mdc800_device_ops,
+-	.mode =		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ 	.minor_base =	MDC800_DEVICE_MINOR_BASE,
+ };
+ 
+@@ -976,13 +975,13 @@ static struct usb_driver mdc800_usb_driv
+ 	Init and Cleanup this driver (Main Functions)
+ *************************************************************************/
+ 
+-#define try(A)           if (!(A)) goto cleanup_on_fail;
+-
+ static int __init usb_mdc800_init (void)
+ {
+ 	int retval = -ENODEV;
+ 	/* Allocate Memory */
+-	try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL));
++	mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL);
++	if (!mdc800)
++		goto cleanup_on_fail;
+ 
+ 	memset(mdc800, 0, sizeof(struct mdc800_data));
+ 	mdc800->dev = NULL;
+@@ -998,13 +997,25 @@ static int __init usb_mdc800_init (void)
+ 	mdc800->downloaded = 0;
+ 	mdc800->written = 0;
+ 
+-	try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL));
+-	try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL));
+-	try (mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL));
+-
+-	try (mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL));
+-	try (mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL));
+-	try (mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL));
++	mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL);
++	if (!mdc800->irq_urb_buffer)
++		goto cleanup_on_fail;
++	mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL);
++	if (!mdc800->write_urb_buffer)
++		goto cleanup_on_fail;
++	mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL);
++	if (!mdc800->download_urb_buffer)
++		goto cleanup_on_fail;
++
++	mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL);
++	if (!mdc800->irq_urb)
++		goto cleanup_on_fail;
++	mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL);
++	if (!mdc800->download_urb)
++		goto cleanup_on_fail;
++	mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL);
++	if (!mdc800->write_urb)
++		goto cleanup_on_fail;
+ 
+ 	/* Register the driver */
+ 	retval = usb_register(&mdc800_usb_driver);
+diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
+--- a/drivers/usb/image/microtek.c
++++ b/drivers/usb/image/microtek.c
+@@ -773,11 +773,10 @@ static int mts_usb_probe(struct usb_inte
+ 	}
+ 	
+ 	
+-	new_desc = kmalloc(sizeof(struct mts_desc), GFP_KERNEL);
++	new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL);
+ 	if (!new_desc)
+ 		goto out;
+ 
+-	memset(new_desc, 0, sizeof(*new_desc));
+ 	new_desc->urb = usb_alloc_urb(0, GFP_KERNEL);
+ 	if (!new_desc->urb)
+ 		goto out_kfree;
+diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
+--- a/drivers/usb/input/acecad.c
++++ b/drivers/usb/input/acecad.c
+@@ -53,7 +53,7 @@ struct usb_acecad {
+ 	char name[128];
+ 	char phys[64];
+ 	struct usb_device *usbdev;
+-	struct input_dev dev;
++	struct input_dev *input;
+ 	struct urb *irq;
+ 
+ 	signed char *data;
+@@ -64,7 +64,7 @@ static void usb_acecad_irq(struct urb *u
+ {
+ 	struct usb_acecad *acecad = urb->context;
+ 	unsigned char *data = acecad->data;
+-	struct input_dev *dev = &acecad->dev;
++	struct input_dev *dev = acecad->input;
+ 	int prox, status;
+ 
+ 	switch (urb->status) {
+@@ -135,8 +135,8 @@ static int usb_acecad_probe(struct usb_i
+ 	struct usb_host_interface *interface = intf->cur_altsetting;
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct usb_acecad *acecad;
++	struct input_dev *input_dev;
+ 	int pipe, maxp;
+-	char path[64];
+ 
+ 	if (interface->desc.bNumEndpoints != 1)
+ 		return -ENODEV;
+@@ -153,8 +153,9 @@ static int usb_acecad_probe(struct usb_i
+ 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+ 
+ 	acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL);
+-	if (!acecad)
+-		return -ENOMEM;
++	input_dev = input_allocate_device();
++	if (!acecad || !input_dev)
++		goto fail1;
+ 
+ 	acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
+ 	if (!acecad->data)
+@@ -164,6 +165,9 @@ static int usb_acecad_probe(struct usb_i
+ 	if (!acecad->irq)
+ 		goto fail2;
+ 
++	acecad->usbdev = dev;
++	acecad->input = input_dev;
++
+ 	if (dev->manufacturer)
+ 		strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name));
+ 
+@@ -173,48 +177,48 @@ static int usb_acecad_probe(struct usb_i
+ 		strlcat(acecad->name, dev->product, sizeof(acecad->name));
+ 	}
+ 
+-	usb_make_path(dev, path, sizeof(path));
+-	snprintf(acecad->phys, sizeof(acecad->phys), "%s/input0", path);
++	usb_make_path(dev, acecad->phys, sizeof(acecad->phys));
++	strlcat(acecad->phys, "/input0", sizeof(acecad->phys));
+ 
+-	acecad->usbdev = dev;
+-
+-	acecad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-	acecad->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+-	acecad->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+-	acecad->dev.keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
++	input_dev->name = acecad->name;
++	input_dev->phys = acecad->phys;
++	usb_to_input_id(dev, &input_dev->id);
++	input_dev->cdev.dev = &intf->dev;
++	input_dev->private = acecad;
++
++	input_dev->open = usb_acecad_open;
++	input_dev->close = usb_acecad_close;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
++	input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
++	input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
+ 
+ 	switch (id->driver_info) {
+ 		case 0:
+-			acecad->dev.absmax[ABS_X] = 5000;
+-			acecad->dev.absmax[ABS_Y] = 3750;
+-			acecad->dev.absmax[ABS_PRESSURE] = 512;
++			input_dev->absmax[ABS_X] = 5000;
++			input_dev->absmax[ABS_Y] = 3750;
++			input_dev->absmax[ABS_PRESSURE] = 512;
+ 			if (!strlen(acecad->name))
+ 				snprintf(acecad->name, sizeof(acecad->name),
+ 					"USB Acecad Flair Tablet %04x:%04x",
+-					dev->descriptor.idVendor, dev->descriptor.idProduct);
++					le16_to_cpu(dev->descriptor.idVendor),
++					le16_to_cpu(dev->descriptor.idProduct));
+ 			break;
+ 		case 1:
+-			acecad->dev.absmax[ABS_X] = 3000;
+-			acecad->dev.absmax[ABS_Y] = 2250;
+-			acecad->dev.absmax[ABS_PRESSURE] = 1024;
++			input_dev->absmax[ABS_X] = 3000;
++			input_dev->absmax[ABS_Y] = 2250;
++			input_dev->absmax[ABS_PRESSURE] = 1024;
+ 			if (!strlen(acecad->name))
+ 				snprintf(acecad->name, sizeof(acecad->name),
+ 					"USB Acecad 302 Tablet %04x:%04x",
+-					dev->descriptor.idVendor, dev->descriptor.idProduct);
++					le16_to_cpu(dev->descriptor.idVendor),
++					le16_to_cpu(dev->descriptor.idProduct));
+ 			break;
+ 	}
+ 
+-	acecad->dev.absfuzz[ABS_X] = 4;
+-	acecad->dev.absfuzz[ABS_Y] = 4;
+-
+-	acecad->dev.private = acecad;
+-	acecad->dev.open = usb_acecad_open;
+-	acecad->dev.close = usb_acecad_close;
+-
+-	acecad->dev.name = acecad->name;
+-	acecad->dev.phys = acecad->phys;
+-	usb_to_input_id(dev, &acecad->dev.id);
+-	acecad->dev.dev = &intf->dev;
++	input_dev->absfuzz[ABS_X] = 4;
++	input_dev->absfuzz[ABS_Y] = 4;
+ 
+ 	usb_fill_int_urb(acecad->irq, dev, pipe,
+ 			acecad->data, maxp > 8 ? 8 : maxp,
+@@ -222,17 +226,15 @@ static int usb_acecad_probe(struct usb_i
+ 	acecad->irq->transfer_dma = acecad->data_dma;
+ 	acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ 
+-	input_register_device(&acecad->dev);
+-
+-	printk(KERN_INFO "input: %s with packet size %d on %s\n",
+-		acecad->name, maxp, path);
++	input_register_device(acecad->input);
+ 
+ 	usb_set_intfdata(intf, acecad);
+ 
+ 	return 0;
+ 
+  fail2:	usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
+- fail1:	kfree(acecad);
++ fail1: input_free_device(input_dev);
++	kfree(acecad);
+ 	return -ENOMEM;
+ }
+ 
+@@ -243,7 +245,7 @@ static void usb_acecad_disconnect(struct
+ 	usb_set_intfdata(intf, NULL);
+ 	if (acecad) {
+ 		usb_kill_urb(acecad->irq);
+-		input_unregister_device(&acecad->dev);
++		input_unregister_device(acecad->input);
+ 		usb_free_urb(acecad->irq);
+ 		usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
+ 		kfree(acecad);
+diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
+--- a/drivers/usb/input/aiptek.c
++++ b/drivers/usb/input/aiptek.c
+@@ -317,7 +317,7 @@ struct aiptek_settings {
+ };
+ 
+ struct aiptek {
+-	struct input_dev inputdev;		/* input device struct           */
++	struct input_dev *inputdev;		/* input device struct           */
+ 	struct usb_device *usbdev;		/* usb device struct             */
+ 	struct urb *urb;			/* urb for incoming reports      */
+ 	dma_addr_t data_dma;			/* our dma stuffage              */
+@@ -402,7 +402,7 @@ static void aiptek_irq(struct urb *urb, 
+ {
+ 	struct aiptek *aiptek = urb->context;
+ 	unsigned char *data = aiptek->data;
+-	struct input_dev *inputdev = &aiptek->inputdev;
++	struct input_dev *inputdev = aiptek->inputdev;
+ 	int jitterable = 0;
+ 	int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck;
+ 
+@@ -955,20 +955,20 @@ static int aiptek_program_tablet(struct 
+ 	/* Query getXextension */
+ 	if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
+ 		return ret;
+-	aiptek->inputdev.absmin[ABS_X] = 0;
+-	aiptek->inputdev.absmax[ABS_X] = ret - 1;
++	aiptek->inputdev->absmin[ABS_X] = 0;
++	aiptek->inputdev->absmax[ABS_X] = ret - 1;
+ 
+ 	/* Query getYextension */
+ 	if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)
+ 		return ret;
+-	aiptek->inputdev.absmin[ABS_Y] = 0;
+-	aiptek->inputdev.absmax[ABS_Y] = ret - 1;
++	aiptek->inputdev->absmin[ABS_Y] = 0;
++	aiptek->inputdev->absmax[ABS_Y] = ret - 1;
+ 
+ 	/* Query getPressureLevels */
+ 	if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)
+ 		return ret;
+-	aiptek->inputdev.absmin[ABS_PRESSURE] = 0;
+-	aiptek->inputdev.absmax[ABS_PRESSURE] = ret - 1;
++	aiptek->inputdev->absmin[ABS_PRESSURE] = 0;
++	aiptek->inputdev->absmax[ABS_PRESSURE] = ret - 1;
+ 
+ 	/* Depending on whether we are in absolute or relative mode, we will
+ 	 * do a switchToTablet(absolute) or switchToMouse(relative) command.
+@@ -1025,8 +1025,8 @@ static ssize_t show_tabletSize(struct de
+ 		return 0;
+ 
+ 	return snprintf(buf, PAGE_SIZE, "%dx%d\n",
+-			aiptek->inputdev.absmax[ABS_X] + 1,
+-			aiptek->inputdev.absmax[ABS_Y] + 1);
++			aiptek->inputdev->absmax[ABS_X] + 1,
++			aiptek->inputdev->absmax[ABS_Y] + 1);
+ }
+ 
+ /* These structs define the sysfs files, param #1 is the name of the
+@@ -1048,7 +1048,7 @@ static ssize_t show_tabletProductId(stru
+ 		return 0;
+ 
+ 	return snprintf(buf, PAGE_SIZE, "0x%04x\n",
+-			aiptek->inputdev.id.product);
++			aiptek->inputdev->id.product);
+ }
+ 
+ static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
+@@ -1063,7 +1063,7 @@ static ssize_t show_tabletVendorId(struc
+ 	if (aiptek == NULL)
+ 		return 0;
+ 
+-	return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev.id.vendor);
++	return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor);
+ }
+ 
+ static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
+@@ -1977,7 +1977,6 @@ aiptek_probe(struct usb_interface *intf,
+ 	struct input_dev *inputdev;
+ 	struct input_handle *inputhandle;
+ 	struct list_head *node, *next;
+-	char path[64 + 1];
+ 	int i;
+ 	int speeds[] = { 0,
+ 		AIPTEK_PROGRAMMABLE_DELAY_50,
+@@ -1996,24 +1995,26 @@ aiptek_probe(struct usb_interface *intf,
+ 	 */
+ 	speeds[0] = programmableDelay;
+ 
+-	if ((aiptek = kmalloc(sizeof(struct aiptek), GFP_KERNEL)) == NULL)
+-		return -ENOMEM;
+-	memset(aiptek, 0, sizeof(struct aiptek));
++	aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
++	inputdev = input_allocate_device();
++	if (!aiptek || !inputdev)
++		goto fail1;
+ 
+ 	aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
+ 					SLAB_ATOMIC, &aiptek->data_dma);
+-	if (aiptek->data == NULL) {
+-		kfree(aiptek);
+-		return -ENOMEM;
+-	}
++	if (!aiptek->data)
++		goto fail1;
+ 
+ 	aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
+-	if (aiptek->urb == NULL) {
+-		usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
+-				aiptek->data_dma);
+-		kfree(aiptek);
+-		return -ENOMEM;
+-	}
++	if (!aiptek->urb)
++		goto fail2;
++
++	aiptek->inputdev = inputdev;
++	aiptek->usbdev = usbdev;
++	aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
++	aiptek->inDelay = 0;
++	aiptek->endDelay = 0;
++	aiptek->previousJitterable = 0;
+ 
+ 	/* Set up the curSettings struct. Said struct contains the current
+ 	 * programmable parameters. The newSetting struct contains changes
+@@ -2036,31 +2037,48 @@ aiptek_probe(struct usb_interface *intf,
+ 
+ 	/* Both structs should have equivalent settings
+ 	 */
+-	memcpy(&aiptek->newSetting, &aiptek->curSetting,
+-	       sizeof(struct aiptek_settings));
++	aiptek->newSetting = aiptek->curSetting;
++
++	/* Determine the usb devices' physical path.
++	 * Asketh not why we always pretend we're using "../input0",
++	 * but I suspect this will have to be refactored one
++	 * day if a single USB device can be a keyboard & a mouse
++	 * & a tablet, and the inputX number actually will tell
++	 * us something...
++	 */
++	usb_make_path(usbdev, aiptek->features.usbPath,
++			sizeof(aiptek->features.usbPath));
++	strlcat(aiptek->features.usbPath, "/input0",
++		sizeof(aiptek->features.usbPath));
++
++	/* Set up client data, pointers to open and close routines
++	 * for the input device.
++	 */
++	inputdev->name = "Aiptek";
++	inputdev->phys = aiptek->features.usbPath;
++	usb_to_input_id(usbdev, &inputdev->id);
++	inputdev->cdev.dev = &intf->dev;
++	inputdev->private = aiptek;
++	inputdev->open = aiptek_open;
++	inputdev->close = aiptek_close;
+ 
+ 	/* Now program the capacities of the tablet, in terms of being
+ 	 * an input device.
+ 	 */
+-	aiptek->inputdev.evbit[0] |= BIT(EV_KEY)
++	inputdev->evbit[0] |= BIT(EV_KEY)
+ 	    | BIT(EV_ABS)
+ 	    | BIT(EV_REL)
+ 	    | BIT(EV_MSC);
+ 
+-	aiptek->inputdev.absbit[0] |=
+-	    (BIT(ABS_X) |
+-	     BIT(ABS_Y) |
+-	     BIT(ABS_PRESSURE) |
+-	     BIT(ABS_TILT_X) |
+-	     BIT(ABS_TILT_Y) | BIT(ABS_WHEEL) | BIT(ABS_MISC));
++	inputdev->absbit[0] |= BIT(ABS_MISC);
+ 
+-	aiptek->inputdev.relbit[0] |=
++	inputdev->relbit[0] |=
+ 	    (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC));
+ 
+-	aiptek->inputdev.keybit[LONG(BTN_LEFT)] |=
++	inputdev->keybit[LONG(BTN_LEFT)] |=
+ 	    (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE));
+ 
+-	aiptek->inputdev.keybit[LONG(BTN_DIGI)] |=
++	inputdev->keybit[LONG(BTN_DIGI)] |=
+ 	    (BIT(BTN_TOOL_PEN) |
+ 	     BIT(BTN_TOOL_RUBBER) |
+ 	     BIT(BTN_TOOL_PENCIL) |
+@@ -2070,70 +2088,26 @@ aiptek_probe(struct usb_interface *intf,
+ 	     BIT(BTN_TOOL_LENS) |
+ 	     BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2));
+ 
+-	aiptek->inputdev.mscbit[0] = BIT(MSC_SERIAL);
++	inputdev->mscbit[0] = BIT(MSC_SERIAL);
+ 
+ 	/* Programming the tablet macro keys needs to be done with a for loop
+ 	 * as the keycodes are discontiguous.
+ 	 */
+ 	for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i)
+-		set_bit(macroKeyEvents[i], aiptek->inputdev.keybit);
+-
+-	/* Set up client data, pointers to open and close routines
+-	 * for the input device.
+-	 */
+-	aiptek->inputdev.private = aiptek;
+-	aiptek->inputdev.open = aiptek_open;
+-	aiptek->inputdev.close = aiptek_close;
++		set_bit(macroKeyEvents[i], inputdev->keybit);
+ 
+-	/* Determine the usb devices' physical path.
+-	 * Asketh not why we always pretend we're using "../input0",
+-	 * but I suspect this will have to be refactored one
+-	 * day if a single USB device can be a keyboard & a mouse
+-	 * & a tablet, and the inputX number actually will tell
+-	 * us something...
+-	 */
+-	if (usb_make_path(usbdev, path, 64) > 0)
+-		sprintf(aiptek->features.usbPath, "%s/input0", path);
+-
+-	/* Program the input device coordinate capacities. We do not yet
++	/*
++	 * Program the input device coordinate capacities. We do not yet
+ 	 * know what maximum X, Y, and Z values are, so we're putting fake
+ 	 * values in. Later, we'll ask the tablet to put in the correct
+ 	 * values.
+ 	 */
+-	aiptek->inputdev.absmin[ABS_X] = 0;
+-	aiptek->inputdev.absmax[ABS_X] = 2999;
+-	aiptek->inputdev.absmin[ABS_Y] = 0;
+-	aiptek->inputdev.absmax[ABS_Y] = 2249;
+-	aiptek->inputdev.absmin[ABS_PRESSURE] = 0;
+-	aiptek->inputdev.absmax[ABS_PRESSURE] = 511;
+-	aiptek->inputdev.absmin[ABS_TILT_X] = AIPTEK_TILT_MIN;
+-	aiptek->inputdev.absmax[ABS_TILT_X] = AIPTEK_TILT_MAX;
+-	aiptek->inputdev.absmin[ABS_TILT_Y] = AIPTEK_TILT_MIN;
+-	aiptek->inputdev.absmax[ABS_TILT_Y] = AIPTEK_TILT_MAX;
+-	aiptek->inputdev.absmin[ABS_WHEEL] = AIPTEK_WHEEL_MIN;
+-	aiptek->inputdev.absmax[ABS_WHEEL] = AIPTEK_WHEEL_MAX - 1;
+-	aiptek->inputdev.absfuzz[ABS_X] = 0;
+-	aiptek->inputdev.absfuzz[ABS_Y] = 0;
+-	aiptek->inputdev.absfuzz[ABS_PRESSURE] = 0;
+-	aiptek->inputdev.absfuzz[ABS_TILT_X] = 0;
+-	aiptek->inputdev.absfuzz[ABS_TILT_Y] = 0;
+-	aiptek->inputdev.absfuzz[ABS_WHEEL] = 0;
+-	aiptek->inputdev.absflat[ABS_X] = 0;
+-	aiptek->inputdev.absflat[ABS_Y] = 0;
+-	aiptek->inputdev.absflat[ABS_PRESSURE] = 0;
+-	aiptek->inputdev.absflat[ABS_TILT_X] = 0;
+-	aiptek->inputdev.absflat[ABS_TILT_Y] = 0;
+-	aiptek->inputdev.absflat[ABS_WHEEL] = 0;
+-	aiptek->inputdev.name = "Aiptek";
+-	aiptek->inputdev.phys = aiptek->features.usbPath;
+-	usb_to_input_id(usbdev, &aiptek->inputdev.id);
+-	aiptek->inputdev.dev = &intf->dev;
+-
+-	aiptek->usbdev = usbdev;
+-	aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
+-	aiptek->inDelay = 0;
+-	aiptek->endDelay = 0;
+-	aiptek->previousJitterable = 0;
++	input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0);
++	input_set_abs_params(inputdev, ABS_X, 0, 2249, 0, 0);
++	input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0);
++	input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
++	input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
++	input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
+ 
+ 	endpoint = &intf->altsetting[0].endpoint[0].desc;
+ 
+@@ -2150,28 +2124,6 @@ aiptek_probe(struct usb_interface *intf,
+ 	aiptek->urb->transfer_dma = aiptek->data_dma;
+ 	aiptek->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ 
+-	/* Register the tablet as an Input Device
+-	 */
+-	input_register_device(&aiptek->inputdev);
+-
+-	/* We now will look for the evdev device which is mapped to
+-	 * the tablet. The partial name is kept in the link list of
+-	 * input_handles associated with this input device.
+-	 * What identifies an evdev input_handler is that it begins
+-	 * with 'event', continues with a digit, and that in turn
+-	 * is mapped to /{devfs}/input/eventN.
+-	 */
+-	inputdev = &aiptek->inputdev;
+-	list_for_each_safe(node, next, &inputdev->h_list) {
+-		inputhandle = to_handle(node);
+-		if (strncmp(inputhandle->name, "event", 5) == 0) {
+-			strcpy(aiptek->features.inputPath, inputhandle->name);
+-			break;
+-		}
+-	}
+-
+-	info("input: Aiptek on %s (%s)\n", path, aiptek->features.inputPath);
+-
+ 	/* Program the tablet. This sets the tablet up in the mode
+ 	 * specified in newSetting, and also queries the tablet's
+ 	 * physical capacities.
+@@ -2186,13 +2138,32 @@ aiptek_probe(struct usb_interface *intf,
+ 	for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) {
+ 		aiptek->curSetting.programmableDelay = speeds[i];
+ 		(void)aiptek_program_tablet(aiptek);
+-		if (aiptek->inputdev.absmax[ABS_X] > 0) {
++		if (aiptek->inputdev->absmax[ABS_X] > 0) {
+ 			info("input: Aiptek using %d ms programming speed\n",
+ 			     aiptek->curSetting.programmableDelay);
+ 			break;
+ 		}
+ 	}
+ 
++	/* Register the tablet as an Input Device
++	 */
++	input_register_device(aiptek->inputdev);
++
++	/* We now will look for the evdev device which is mapped to
++	 * the tablet. The partial name is kept in the link list of
++	 * input_handles associated with this input device.
++	 * What identifies an evdev input_handler is that it begins
++	 * with 'event', continues with a digit, and that in turn
++	 * is mapped to input/eventN.
++	 */
++	list_for_each_safe(node, next, &inputdev->h_list) {
++		inputhandle = to_handle(node);
++		if (strncmp(inputhandle->name, "event", 5) == 0) {
++			strcpy(aiptek->features.inputPath, inputhandle->name);
++			break;
++		}
++	}
++
+ 	/* Associate this driver's struct with the usb interface.
+ 	 */
+ 	usb_set_intfdata(intf, aiptek);
+@@ -2207,6 +2178,12 @@ aiptek_probe(struct usb_interface *intf,
+ 		info("aiptek: error loading 'evdev' module");
+ 
+ 	return 0;
++
++fail2:	usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
++			aiptek->data_dma);
++fail1:	input_free_device(inputdev);
++	kfree(aiptek);
++	return -ENOMEM;
+ }
+ 
+ /* Forward declaration */
+@@ -2234,7 +2211,7 @@ static void aiptek_disconnect(struct usb
+ 		/* Free & unhook everything from the system.
+ 		 */
+ 		usb_kill_urb(aiptek->urb);
+-		input_unregister_device(&aiptek->inputdev);
++		input_unregister_device(aiptek->inputdev);
+ 		aiptek_delete_files(&intf->dev);
+ 		usb_free_urb(aiptek->urb);
+ 		usb_buffer_free(interface_to_usbdev(intf),
+diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
+--- a/drivers/usb/input/appletouch.c
++++ b/drivers/usb/input/appletouch.c
+@@ -39,7 +39,7 @@
+ #define APPLE_VENDOR_ID		0x05AC
+ 
+ #define ATP_DEVICE(prod)					\
+-	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |   		\
++	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |		\
+ 		       USB_DEVICE_ID_MATCH_INT_CLASS |		\
+ 		       USB_DEVICE_ID_MATCH_INT_PROTOCOL,	\
+ 	.idVendor = APPLE_VENDOR_ID,				\
+@@ -78,9 +78,9 @@ MODULE_DEVICE_TABLE (usb, atp_table);
+  * We try to keep the touchpad aspect ratio while still doing only simple
+  * arithmetics.
+  * The factors below give coordinates like:
+- * 	0 <= x <  960 on 12" and 15" Powerbooks
+- * 	0 <= x < 1600 on 17" Powerbooks
+- * 	0 <= y <  646
++ *	0 <= x <  960 on 12" and 15" Powerbooks
++ *	0 <= x < 1600 on 17" Powerbooks
++ *	0 <= y <  646
+  */
+ #define ATP_XFACT	64
+ #define ATP_YFACT	43
+@@ -93,11 +93,12 @@ MODULE_DEVICE_TABLE (usb, atp_table);
+ 
+ /* Structure to hold all of our device specific stuff */
+ struct atp {
++	char			phys[64];
+ 	struct usb_device *	udev;		/* usb device */
+ 	struct urb *		urb;		/* usb request block */
+ 	signed char *		data;		/* transferred data */
+ 	int			open;		/* non-zero if opened */
+-	struct input_dev	input;		/* input dev */
++	struct input_dev	*input;		/* input dev */
+ 	int			valid;		/* are the sensors valid ? */
+ 	int			x_old;		/* last reported x/y, */
+ 	int			y_old;		/* used for smoothing */
+@@ -114,11 +115,11 @@ struct atp {
+ 		int i;							\
+ 		printk("appletouch: %s %lld", msg, (long long)jiffies); \
+ 		for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++)	\
+-			printk(" %02x", tab[i]); 			\
+-		printk("\n"); 						\
++			printk(" %02x", tab[i]);			\
++		printk("\n");						\
+ 	}
+ 
+-#define dprintk(format, a...) 						\
++#define dprintk(format, a...)						\
+ 	do {								\
+ 		if (debug) printk(format, ##a);				\
+ 	} while (0)
+@@ -219,8 +220,8 @@ static void atp_complete(struct urb* urb
+ 		for (i = 16; i < ATP_XSENSORS; i++)
+ 			if (dev->xy_cur[i]) {
+ 				printk("appletouch: 17\" model detected.\n");
+-				input_set_abs_params(&dev->input, ABS_X, 0,
+-				     		     (ATP_XSENSORS - 1) *
++				input_set_abs_params(dev->input, ABS_X, 0,
++						     (ATP_XSENSORS - 1) *
+ 						     ATP_XFACT - 1,
+ 						     ATP_FUZZ, 0);
+ 				break;
+@@ -260,12 +261,12 @@ static void atp_complete(struct urb* urb
+ 				       "Xz: %3d Yz: %3d\n",
+ 				       x, y, x_z, y_z);
+ 
+-			input_report_key(&dev->input, BTN_TOUCH, 1);
+-			input_report_abs(&dev->input, ABS_X, x);
+-			input_report_abs(&dev->input, ABS_Y, y);
+-			input_report_abs(&dev->input, ABS_PRESSURE,
++			input_report_key(dev->input, BTN_TOUCH, 1);
++			input_report_abs(dev->input, ABS_X, x);
++			input_report_abs(dev->input, ABS_Y, y);
++			input_report_abs(dev->input, ABS_PRESSURE,
+ 					 min(ATP_PRESSURE, x_z + y_z));
+-			atp_report_fingers(&dev->input, max(x_f, y_f));
++			atp_report_fingers(dev->input, max(x_f, y_f));
+ 		}
+ 		dev->x_old = x;
+ 		dev->y_old = y;
+@@ -273,17 +274,17 @@ static void atp_complete(struct urb* urb
+ 	else if (!x && !y) {
+ 
+ 		dev->x_old = dev->y_old = -1;
+-		input_report_key(&dev->input, BTN_TOUCH, 0);
+-		input_report_abs(&dev->input, ABS_PRESSURE, 0);
+-		atp_report_fingers(&dev->input, 0);
++		input_report_key(dev->input, BTN_TOUCH, 0);
++		input_report_abs(dev->input, ABS_PRESSURE, 0);
++		atp_report_fingers(dev->input, 0);
+ 
+ 		/* reset the accumulator on release */
+ 		memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
+ 	}
+ 
+-	input_report_key(&dev->input, BTN_LEFT, !!dev->data[80]);
++	input_report_key(dev->input, BTN_LEFT, !!dev->data[80]);
+ 
+-	input_sync(&dev->input);
++	input_sync(dev->input);
+ 
+ exit:
+ 	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
+@@ -314,21 +315,14 @@ static void atp_close(struct input_dev *
+ 
+ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
+ {
+-	struct atp *dev = NULL;
++	struct atp *dev;
++	struct input_dev *input_dev;
++	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;
+ 
+-	/* allocate memory for our device state and initialize it */
+-	dev = kmalloc(sizeof(struct atp), GFP_KERNEL);
+-	if (dev == NULL) {
+-		err("Out of memory");
+-		goto err_kmalloc;
+-	}
+-	memset(dev, 0, sizeof(struct atp));
+-
+-	dev->udev = interface_to_usbdev(iface);
+ 
+ 	/* set up the endpoint information */
+ 	/* use only the first interrupt-in endpoint */
+@@ -345,70 +339,82 @@ static int atp_probe(struct usb_interfac
+ 		}
+ 	}
+ 	if (!int_in_endpointAddr) {
+-		retval = -EIO;
+ 		err("Could not find int-in endpoint");
+-		goto err_endpoint;
++		return -EIO;
+ 	}
+ 
+-	/* save our data pointer in this interface device */
+-	usb_set_intfdata(iface, dev);
++	/* allocate memory for our device state and initialize it */
++	dev = kzalloc(sizeof(struct atp), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!dev || !input_dev) {
++		err("Out of memory");
++		goto err_free_devs;
++	}
++
++	dev->udev = udev;
++	dev->input = input_dev;
+ 
+ 	dev->urb = usb_alloc_urb(0, GFP_KERNEL);
+ 	if (!dev->urb) {
+ 		retval = -ENOMEM;
+-		goto err_usballoc;
++		goto err_free_devs;
+ 	}
++
+ 	dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
+ 				     &dev->urb->transfer_dma);
+ 	if (!dev->data) {
+ 		retval = -ENOMEM;
+-		goto err_usbbufalloc;
++		goto err_free_urb;
+ 	}
+-	usb_fill_int_urb(dev->urb, dev->udev,
+-			 usb_rcvintpipe(dev->udev, int_in_endpointAddr),
++
++	usb_fill_int_urb(dev->urb, udev,
++			 usb_rcvintpipe(udev, int_in_endpointAddr),
+ 			 dev->data, ATP_DATASIZE, atp_complete, dev, 1);
+ 
+-	init_input_dev(&dev->input);
+-	dev->input.name = "appletouch";
+-	dev->input.dev = &iface->dev;
+-	dev->input.private = dev;
+-	dev->input.open = atp_open;
+-	dev->input.close = atp_close;
++	usb_make_path(udev, dev->phys, sizeof(dev->phys));
++	strlcat(dev->phys, "/input0", sizeof(dev->phys));
+ 
+-	usb_to_input_id(dev->udev, &dev->input.id);
++	input_dev->name = "appletouch";
++	input_dev->phys = dev->phys;
++	usb_to_input_id(dev->udev, &input_dev->id);
++	input_dev->cdev.dev = &iface->dev;
++
++	input_dev->private = dev;
++	input_dev->open = atp_open;
++	input_dev->close = atp_close;
+ 
+-	set_bit(EV_ABS, dev->input.evbit);
++	set_bit(EV_ABS, input_dev->evbit);
+ 
+ 	/*
+ 	 * 12" and 15" Powerbooks only have 16 x sensors,
+ 	 * 17" models are detected later.
+ 	 */
+-	input_set_abs_params(&dev->input, ABS_X, 0,
++	input_set_abs_params(input_dev, ABS_X, 0,
+ 			     (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
+-	input_set_abs_params(&dev->input, ABS_Y, 0,
++	input_set_abs_params(input_dev, ABS_Y, 0,
+ 			     (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
+-	input_set_abs_params(&dev->input, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
++	input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
+ 
+-	set_bit(EV_KEY, dev->input.evbit);
+-	set_bit(BTN_TOUCH, dev->input.keybit);
+-	set_bit(BTN_TOOL_FINGER, dev->input.keybit);
+-	set_bit(BTN_TOOL_DOUBLETAP, dev->input.keybit);
+-	set_bit(BTN_TOOL_TRIPLETAP, dev->input.keybit);
+-	set_bit(BTN_LEFT, dev->input.keybit);
++	set_bit(EV_KEY, input_dev->evbit);
++	set_bit(BTN_TOUCH, input_dev->keybit);
++	set_bit(BTN_TOOL_FINGER, input_dev->keybit);
++	set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
++	set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
++	set_bit(BTN_LEFT, input_dev->keybit);
+ 
+-	input_register_device(&dev->input);
++	input_register_device(dev->input);
+ 
+-	printk(KERN_INFO "input: appletouch connected\n");
++	/* save our data pointer in this interface device */
++	usb_set_intfdata(iface, dev);
+ 
+ 	return 0;
+ 
+-err_usbbufalloc:
++ err_free_urb:
+ 	usb_free_urb(dev->urb);
+-err_usballoc:
++ err_free_devs:
+ 	usb_set_intfdata(iface, NULL);
+-err_endpoint:
+ 	kfree(dev);
+-err_kmalloc:
++	input_free_device(input_dev);
+ 	return retval;
+ }
+ 
+@@ -419,7 +425,7 @@ static void atp_disconnect(struct usb_in
+ 	usb_set_intfdata(iface, NULL);
+ 	if (dev) {
+ 		usb_kill_urb(dev->urb);
+-		input_unregister_device(&dev->input);
++		input_unregister_device(dev->input);
+ 		usb_free_urb(dev->urb);
+ 		usb_buffer_free(dev->udev, ATP_DATASIZE,
+ 				dev->data, dev->urb->transfer_dma);
+diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
+--- a/drivers/usb/input/ati_remote.c
++++ b/drivers/usb/input/ati_remote.c
+@@ -112,7 +112,6 @@
+ 
+ #define NAME_BUFSIZE      80    /* size of product name, path buffers */
+ #define DATA_BUFSIZE      63    /* size of URB data buffers */
+-#define ATI_INPUTNUM      1     /* Which input device to register as */
+ 
+ static unsigned long channel_mask;
+ module_param(channel_mask, ulong, 0444);
+@@ -162,7 +161,7 @@ static char accel[] = { 1, 2, 4, 6, 9, 1
+ static DECLARE_MUTEX(disconnect_sem);
+ 
+ struct ati_remote {
+-	struct input_dev idev;
++	struct input_dev *idev;
+ 	struct usb_device *udev;
+ 	struct usb_interface *interface;
+ 
+@@ -198,15 +197,13 @@ struct ati_remote {
+ #define KIND_ACCEL      7   /* Directional keypad - left, right, up, down.*/
+ 
+ /* Translation table from hardware messages to input events. */
+-static struct
+-{
++static struct {
+ 	short kind;
+ 	unsigned char data1, data2;
+ 	int type;
+ 	unsigned int code;
+ 	int value;
+-}  ati_remote_tbl[] =
+-{
++}  ati_remote_tbl[] = {
+ 	/* Directional control pad axes */
+ 	{KIND_ACCEL,   0x35, 0x70, EV_REL, REL_X, -1},	 /* left */
+ 	{KIND_ACCEL,   0x36, 0x71, EV_REL, REL_X, 1},    /* right */
+@@ -286,7 +283,6 @@ static struct
+ 
+ /* Local function prototypes */
+ static void ati_remote_dump		(unsigned char *data, unsigned int actual_length);
+-static void ati_remote_delete		(struct ati_remote *dev);
+ static int ati_remote_open		(struct input_dev *inputdev);
+ static void ati_remote_close		(struct input_dev *inputdev);
+ static int ati_remote_sendpacket	(struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
+@@ -428,7 +424,7 @@ static void ati_remote_input_report(stru
+ {
+ 	struct ati_remote *ati_remote = urb->context;
+ 	unsigned char *data= ati_remote->inbuf;
+-	struct input_dev *dev = &ati_remote->idev;
++	struct input_dev *dev = ati_remote->idev;
+ 	int index, acc;
+ 	int remote_num;
+ 
+@@ -587,38 +583,55 @@ static void ati_remote_irq_in(struct urb
+ }
+ 
+ /*
+- *	ati_remote_delete
++ *	ati_remote_alloc_buffers
+  */
+-static void ati_remote_delete(struct ati_remote *ati_remote)
++static int ati_remote_alloc_buffers(struct usb_device *udev,
++				    struct ati_remote *ati_remote)
+ {
+-	if (ati_remote->irq_urb)
+-		usb_kill_urb(ati_remote->irq_urb);
++	ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
++					     &ati_remote->inbuf_dma);
++	if (!ati_remote->inbuf)
++		return -1;
+ 
+-	if (ati_remote->out_urb)
+-		usb_kill_urb(ati_remote->out_urb);
++	ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
++					      &ati_remote->outbuf_dma);
++	if (!ati_remote->outbuf)
++		return -1;
+ 
+-	input_unregister_device(&ati_remote->idev);
++	ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
++	if (!ati_remote->irq_urb)
++		return -1;
+ 
+-	if (ati_remote->inbuf)
+-		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+-				ati_remote->inbuf, ati_remote->inbuf_dma);
++	ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
++	if (!ati_remote->out_urb)
++		return -1;
+ 
+-	if (ati_remote->outbuf)
+-		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+-				ati_remote->outbuf, ati_remote->outbuf_dma);
++	return 0;
++}
+ 
++/*
++ *	ati_remote_free_buffers
++ */
++static void ati_remote_free_buffers(struct ati_remote *ati_remote)
++{
+ 	if (ati_remote->irq_urb)
+ 		usb_free_urb(ati_remote->irq_urb);
+ 
+ 	if (ati_remote->out_urb)
+ 		usb_free_urb(ati_remote->out_urb);
+ 
+-	kfree(ati_remote);
++	if (ati_remote->inbuf)
++		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
++				ati_remote->inbuf, ati_remote->inbuf_dma);
++
++	if (ati_remote->outbuf)
++		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
++				ati_remote->inbuf, ati_remote->outbuf_dma);
+ }
+ 
+ static void ati_remote_input_init(struct ati_remote *ati_remote)
+ {
+-	struct input_dev *idev = &(ati_remote->idev);
++	struct input_dev *idev = ati_remote->idev;
+ 	int i;
+ 
+ 	idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+@@ -637,7 +650,7 @@ static void ati_remote_input_init(struct
+ 	idev->phys = ati_remote->phys;
+ 
+ 	usb_to_input_id(ati_remote->udev, &idev->id);
+-	idev->dev = &ati_remote->udev->dev;
++	idev->cdev.dev = &ati_remote->udev->dev;
+ }
+ 
+ static int ati_remote_initialize(struct ati_remote *ati_remote)
+@@ -674,7 +687,7 @@ static int ati_remote_initialize(struct 
+ 	    (ati_remote_sendpacket(ati_remote, 0x8007, init2))) {
+ 		dev_err(&ati_remote->interface->dev,
+ 			 "Initializing ati_remote hardware failed.\n");
+-		return 1;
++		return -EIO;
+ 	}
+ 
+ 	return 0;
+@@ -686,95 +699,83 @@ static int ati_remote_initialize(struct 
+ static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id)
+ {
+ 	struct usb_device *udev = interface_to_usbdev(interface);
+-	struct ati_remote *ati_remote = NULL;
+-	struct usb_host_interface *iface_host;
+-	int retval = -ENOMEM;
+-	char path[64];
+-
+-	/* Allocate and clear an ati_remote struct */
+-	if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL)))
+-		return -ENOMEM;
+-	memset(ati_remote, 0x00, sizeof (struct ati_remote));
++	struct usb_host_interface *iface_host = interface->cur_altsetting;
++	struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
++	struct ati_remote *ati_remote;
++	struct input_dev *input_dev;
++	int err = -ENOMEM;
+ 
+-	iface_host = interface->cur_altsetting;
+ 	if (iface_host->desc.bNumEndpoints != 2) {
+ 		err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__);
+-		retval = -ENODEV;
+-		goto error;
++		return -ENODEV;
+ 	}
+ 
+-	ati_remote->endpoint_in = &(iface_host->endpoint[0].desc);
+-	ati_remote->endpoint_out = &(iface_host->endpoint[1].desc);
+-	ati_remote->udev = udev;
+-	ati_remote->interface = interface;
++	endpoint_in = &iface_host->endpoint[0].desc;
++	endpoint_out = &iface_host->endpoint[1].desc;
+ 
+-	if (!(ati_remote->endpoint_in->bEndpointAddress & 0x80)) {
++	if (!(endpoint_in->bEndpointAddress & USB_DIR_IN)) {
+ 		err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__);
+-		retval = -ENODEV;
+-		goto error;
++		return -ENODEV;
+ 	}
+-	if ((ati_remote->endpoint_in->bmAttributes & 3) != 3) {
++	if ((endpoint_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
+ 		err("%s: Unexpected endpoint_in->bmAttributes\n", __FUNCTION__);
+-		retval = -ENODEV;
+-		goto error;
++		return -ENODEV;
+ 	}
+-	if (le16_to_cpu(ati_remote->endpoint_in->wMaxPacketSize) == 0) {
++	if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
+ 		err("%s: endpoint_in message size==0? \n", __FUNCTION__);
+-		retval = -ENODEV;
+-		goto error;
++		return -ENODEV;
+ 	}
+ 
++	ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!ati_remote || !input_dev)
++		goto fail1;
++
+ 	/* Allocate URB buffers, URBs */
+-	ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+-					     &ati_remote->inbuf_dma);
+-	if (!ati_remote->inbuf)
+-		goto error;
++	if (ati_remote_alloc_buffers(udev, ati_remote))
++		goto fail2;
+ 
+-	ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+-					      &ati_remote->outbuf_dma);
+-	if (!ati_remote->outbuf)
+-		goto error;
++	ati_remote->endpoint_in = endpoint_in;
++	ati_remote->endpoint_out = endpoint_out;
++	ati_remote->udev = udev;
++	ati_remote->idev = input_dev;
++	ati_remote->interface = interface;
+ 
+-	ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
+-	if (!ati_remote->irq_urb)
+-		goto error;
++	usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys));
++	strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
+ 
+-	ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
+-	if (!ati_remote->out_urb)
+-		goto error;
+-
+-	usb_make_path(udev, path, NAME_BUFSIZE);
+-	sprintf(ati_remote->phys, "%s/input%d", path, ATI_INPUTNUM);
+ 	if (udev->manufacturer)
+-		strcat(ati_remote->name, udev->manufacturer);
++		strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name));
+ 
+ 	if (udev->product)
+-		sprintf(ati_remote->name, "%s %s", ati_remote->name, udev->product);
++		snprintf(ati_remote->name, sizeof(ati_remote->name),
++			 "%s %s", ati_remote->name, udev->product);
+ 
+ 	if (!strlen(ati_remote->name))
+-		sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)",
++		snprintf(ati_remote->name, sizeof(ati_remote->name),
++			DRIVER_DESC "(%04x,%04x)",
+ 			le16_to_cpu(ati_remote->udev->descriptor.idVendor),
+ 			le16_to_cpu(ati_remote->udev->descriptor.idProduct));
+ 
++	ati_remote_input_init(ati_remote);
++
+ 	/* Device Hardware Initialization - fills in ati_remote->idev from udev. */
+-	retval = ati_remote_initialize(ati_remote);
+-	if (retval)
+-		goto error;
++	err = ati_remote_initialize(ati_remote);
++	if (err)
++		goto fail3;
+ 
+ 	/* Set up and register input device */
+-	ati_remote_input_init(ati_remote);
+-	input_register_device(&ati_remote->idev);
+-
+-	dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n",
+-		 ati_remote->name, path);
++	input_register_device(ati_remote->idev);
+ 
+ 	usb_set_intfdata(interface, ati_remote);
++	return 0;
+ 
+-error:
+-	if (retval)
+-		ati_remote_delete(ati_remote);
+-
+-	return retval;
++fail3:	usb_kill_urb(ati_remote->irq_urb);
++	usb_kill_urb(ati_remote->out_urb);
++fail2:	ati_remote_free_buffers(ati_remote);
++fail1:	input_free_device(input_dev);
++	kfree(ati_remote);
++	return err;
+ }
+ 
+ /*
+@@ -791,7 +792,11 @@ static void ati_remote_disconnect(struct
+ 		return;
+ 	}
+ 
+-	ati_remote_delete(ati_remote);
++	usb_kill_urb(ati_remote->irq_urb);
++	usb_kill_urb(ati_remote->out_urb);
++	input_unregister_device(ati_remote->idev);
++	ati_remote_free_buffers(ati_remote);
++	kfree(ati_remote);
+ }
+ 
+ /*
+diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
+--- a/drivers/usb/input/hid-core.c
++++ b/drivers/usb/input/hid-core.c
+@@ -1619,8 +1619,8 @@ static struct hid_device *usb_hid_config
+ 	struct hid_descriptor *hdesc;
+ 	struct hid_device *hid;
+ 	unsigned quirks = 0, rsize = 0;
+-	char *buf, *rdesc;
+-	int n, insize = 0;
++	char *rdesc;
++	int n, len, insize = 0;
+ 
+ 	for (n = 0; hid_blacklist[n].idVendor; n++)
+ 		if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
+@@ -1630,10 +1630,11 @@ static struct hid_device *usb_hid_config
+ 	if (quirks & HID_QUIRK_IGNORE)
+ 		return NULL;
+ 
+-	if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) ||
+-		usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
+-			dbg("class descriptor not present\n");
+-			return NULL;
++	if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
++	    (!interface->desc.bNumEndpoints ||
++	     usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
++		dbg("class descriptor not present\n");
++		return NULL;
+ 	}
+ 
+ 	for (n = 0; n < hdesc->bNumDescriptors; n++)
+@@ -1749,38 +1750,43 @@ static struct hid_device *usb_hid_config
+ 
+ 	hid->name[0] = 0;
+ 
+-	if (!(buf = kmalloc(64, GFP_KERNEL)))
+-		goto fail;
++	if (dev->manufacturer)
++		strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
++
++	if (dev->product) {
++		if (dev->manufacturer)
++			strlcat(hid->name, " ", sizeof(hid->name));
++		strlcat(hid->name, dev->product, sizeof(hid->name));
++	}
+ 
+-	if (dev->manufacturer) {
+-		strcat(hid->name, dev->manufacturer);
+-		if (dev->product)
+-			snprintf(hid->name, 64, "%s %s", hid->name, dev->product);
+-	} else if (dev->product) {
+-			snprintf(hid->name, 128, "%s", dev->product);
+-	} else
+-		snprintf(hid->name, 128, "%04x:%04x",
+-			le16_to_cpu(dev->descriptor.idVendor),
+-			le16_to_cpu(dev->descriptor.idProduct));
+-
+-	usb_make_path(dev, buf, 64);
+-	snprintf(hid->phys, 64, "%s/input%d", buf,
+-			intf->altsetting[0].desc.bInterfaceNumber);
++	if (!strlen(hid->name))
++		snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
++			 le16_to_cpu(dev->descriptor.idVendor),
++			 le16_to_cpu(dev->descriptor.idProduct));
++
++	usb_make_path(dev, hid->phys, sizeof(hid->phys));
++	strlcat(hid->phys, "/input", sizeof(hid->phys));
++	len = strlen(hid->phys);
++	if (len < sizeof(hid->phys) - 1)
++		snprintf(hid->phys + len, sizeof(hid->phys) - len,
++			 "%d", intf->altsetting[0].desc.bInterfaceNumber);
+ 
+ 	if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
+ 		hid->uniq[0] = 0;
+ 
+-	kfree(buf);
+-
+ 	hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
+ 	if (!hid->urbctrl)
+ 		goto fail;
++
+ 	usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,
+ 			     hid->ctrlbuf, 1, hid_ctrl, hid);
+ 	hid->urbctrl->setup_dma = hid->cr_dma;
+ 	hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
+ 	hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
+ 
++	/* May be needed for some devices */
++	usb_clear_halt(hid->dev, hid->urbin->pipe);
++
+ 	return hid;
+ 
+ fail:
+@@ -1884,7 +1890,6 @@ static int hid_suspend(struct usb_interf
+ 	struct hid_device *hid = usb_get_intfdata (intf);
+ 
+ 	usb_kill_urb(hid->urbin);
+-	intf->dev.power.power_state = PMSG_SUSPEND;
+ 	dev_dbg(&intf->dev, "suspend\n");
+ 	return 0;
+ }
+@@ -1894,7 +1899,6 @@ static int hid_resume(struct usb_interfa
+ 	struct hid_device *hid = usb_get_intfdata (intf);
+ 	int status;
+ 
+-	intf->dev.power.power_state = PMSG_ON;
+ 	if (hid->open)
+ 		status = usb_submit_urb(hid->urbin, GFP_NOIO);
+ 	else
+diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
+--- a/drivers/usb/input/hid-input.c
++++ b/drivers/usb/input/hid-input.c
+@@ -76,8 +76,8 @@ static struct {
+ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
+ 				     struct hid_usage *usage)
+ {
+-	struct input_dev *input = &hidinput->input;
+-	struct hid_device *device = hidinput->input.private;
++	struct input_dev *input = hidinput->input;
++	struct hid_device *device = input->private;
+ 	int max = 0, code;
+ 	unsigned long *bit = NULL;
+ 
+@@ -461,7 +461,8 @@ void hidinput_hid_event(struct hid_devic
+ 
+ 	if (!field->hidinput)
+ 		return;
+-	input = &field->hidinput->input;
++
++	input = field->hidinput->input;
+ 
+ 	input_regs(input, regs);
+ 
+@@ -533,13 +534,10 @@ void hidinput_hid_event(struct hid_devic
+ 
+ void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
+ {
+-	struct list_head *lh;
+ 	struct hid_input *hidinput;
+ 
+-	list_for_each (lh, &hid->inputs) {
+-		hidinput = list_entry(lh, struct hid_input, list);
+-		input_sync(&hidinput->input);
+-	}
++	list_for_each_entry(hidinput, &hid->inputs, list)
++		input_sync(hidinput->input);
+ }
+ 
+ static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
+@@ -604,6 +602,7 @@ int hidinput_connect(struct hid_device *
+ 	struct usb_device *dev = hid->dev;
+ 	struct hid_report *report;
+ 	struct hid_input *hidinput = NULL;
++	struct input_dev *input_dev;
+ 	int i, j, k;
+ 
+ 	INIT_LIST_HEAD(&hid->inputs);
+@@ -624,25 +623,28 @@ int hidinput_connect(struct hid_device *
+ 				continue;
+ 
+ 			if (!hidinput) {
+-				hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL);
+-				if (!hidinput) {
++				hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
++				input_dev = input_allocate_device();
++				if (!hidinput || !input_dev) {
++					kfree(hidinput);
++					input_free_device(input_dev);
+ 					err("Out of memory during hid input probe");
+ 					return -1;
+ 				}
+-				memset(hidinput, 0, sizeof(*hidinput));
+ 
+-				list_add_tail(&hidinput->list, &hid->inputs);
++				input_dev->private = hid;
++				input_dev->event = hidinput_input_event;
++				input_dev->open = hidinput_open;
++				input_dev->close = hidinput_close;
++
++				input_dev->name = hid->name;
++				input_dev->phys = hid->phys;
++				input_dev->uniq = hid->uniq;
++				usb_to_input_id(dev, &input_dev->id);
++				input_dev->cdev.dev = &hid->intf->dev;
+ 
+-				hidinput->input.private = hid;
+-				hidinput->input.event = hidinput_input_event;
+-				hidinput->input.open = hidinput_open;
+-				hidinput->input.close = hidinput_close;
+-
+-				hidinput->input.name = hid->name;
+-				hidinput->input.phys = hid->phys;
+-				hidinput->input.uniq = hid->uniq;
+-				usb_to_input_id(dev, &hidinput->input.id);
+-				hidinput->input.dev = &hid->intf->dev;
++				hidinput->input = input_dev;
++				list_add_tail(&hidinput->list, &hid->inputs);
+ 			}
+ 
+ 			for (i = 0; i < report->maxfield; i++)
+@@ -657,7 +659,7 @@ int hidinput_connect(struct hid_device *
+ 				 * UGCI) cram a lot of unrelated inputs into the
+ 				 * same interface. */
+ 				hidinput->report = report;
+-				input_register_device(&hidinput->input);
++				input_register_device(hidinput->input);
+ 				hidinput = NULL;
+ 			}
+ 		}
+@@ -667,7 +669,7 @@ int hidinput_connect(struct hid_device *
+ 	 * only useful in this case, and not for multi-input quirks. */
+ 	if (hidinput) {
+ 		hid_ff_init(hid);
+-		input_register_device(&hidinput->input);
++		input_register_device(hidinput->input);
+ 	}
+ 
+ 	return 0;
+@@ -675,13 +677,11 @@ int hidinput_connect(struct hid_device *
+ 
+ void hidinput_disconnect(struct hid_device *hid)
+ {
+-	struct list_head *lh, *next;
+-	struct hid_input *hidinput;
++	struct hid_input *hidinput, *next;
+ 
+-	list_for_each_safe(lh, next, &hid->inputs) {
+-		hidinput = list_entry(lh, struct hid_input, list);
+-		input_unregister_device(&hidinput->input);
++	list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
+ 		list_del(&hidinput->list);
++		input_unregister_device(hidinput->input);
+ 		kfree(hidinput);
+ 	}
+ }
+diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
+--- a/drivers/usb/input/hid-lgff.c
++++ b/drivers/usb/input/hid-lgff.c
+@@ -255,22 +255,19 @@ static void hid_lgff_input_init(struct h
+ 	u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
+ 	u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
+ 	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
++	struct input_dev *input_dev = hidinput->input;
+ 
+ 	while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
+ 		dev++;
+ 
+-	ff = dev->ff;
++	for (ff = dev->ff; *ff >= 0; ff++)
++		set_bit(*ff, input_dev->ffbit);
+ 
+-	while (*ff >= 0) {
+-		set_bit(*ff, hidinput->input.ffbit);
+-		++ff;
+-	}
+-
+-	hidinput->input.upload_effect = hid_lgff_upload_effect;
+-	hidinput->input.flush = hid_lgff_flush;
++	input_dev->upload_effect = hid_lgff_upload_effect;
++	input_dev->flush = hid_lgff_flush;
+ 
+-	set_bit(EV_FF, hidinput->input.evbit);
+-	hidinput->input.ff_effects_max = LGFF_EFFECTS;
++	set_bit(EV_FF, input_dev->evbit);
++	input_dev->ff_effects_max = LGFF_EFFECTS;
+ }
+ 
+ static void hid_lgff_exit(struct hid_device* hid)
+diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c
+--- a/drivers/usb/input/hid-tmff.c
++++ b/drivers/usb/input/hid-tmff.c
+@@ -111,6 +111,7 @@ int hid_tmff_init(struct hid_device *hid
+ 	struct tmff_device *private;
+ 	struct list_head *pos;
+ 	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
++	struct input_dev *input_dev = hidinput->input;
+ 
+ 	private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
+ 	if (!private)
+@@ -155,7 +156,7 @@ int hid_tmff_init(struct hid_device *hid
+ 					private->report = report;
+ 					private->rumble = field;
+ 
+-					set_bit(FF_RUMBLE, hidinput->input.ffbit);
++					set_bit(FF_RUMBLE, input_dev->ffbit);
+ 					break;
+ 
+ 				default:
+@@ -164,11 +165,11 @@ int hid_tmff_init(struct hid_device *hid
+ 			}
+ 
+ 			/* Fallthrough to here only when a valid usage is found */
+-			hidinput->input.upload_effect = hid_tmff_upload_effect;
+-			hidinput->input.flush = hid_tmff_flush;
++			input_dev->upload_effect = hid_tmff_upload_effect;
++			input_dev->flush = hid_tmff_flush;
+ 
+-			set_bit(EV_FF, hidinput->input.evbit);
+-			hidinput->input.ff_effects_max = TMFF_EFFECTS;
++			set_bit(EV_FF, input_dev->evbit);
++			input_dev->ff_effects_max = TMFF_EFFECTS;
+ 		}
+ 	}
+ 
+diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
+--- a/drivers/usb/input/hid.h
++++ b/drivers/usb/input/hid.h
+@@ -371,7 +371,7 @@ struct hid_control_fifo {
+ struct hid_input {
+ 	struct list_head list;
+ 	struct hid_report *report;
+-	struct input_dev input;
++	struct input_dev *input;
+ };
+ 
+ struct hid_device {							/* device report descriptor */
+diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
+--- a/drivers/usb/input/hiddev.c
++++ b/drivers/usb/input/hiddev.c
+@@ -732,9 +732,8 @@ static struct file_operations hiddev_fop
+ };
+ 
+ static struct usb_class_driver hiddev_class = {
+-	.name =		"usb/hid/hiddev%d",
++	.name =		"hiddev%d",
+ 	.fops =		&hiddev_fops,
+-	.mode =		S_IFCHR | S_IRUGO | S_IWUSR,
+ 	.minor_base =	HIDDEV_MINOR_BASE,
+ };
+ 
+diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
+--- a/drivers/usb/input/itmtouch.c
++++ b/drivers/usb/input/itmtouch.c
+@@ -73,7 +73,7 @@ MODULE_LICENSE( DRIVER_LICENSE );
+ 
+ struct itmtouch_dev {
+ 	struct usb_device	*usbdev; /* usb device */
+-	struct input_dev	inputdev; /* input device */
++	struct input_dev	*inputdev; /* input device */
+ 	struct urb		*readurb; /* urb */
+ 	char			rbuf[ITM_BUFSIZE]; /* data */
+ 	int			users;
+@@ -88,9 +88,9 @@ static struct usb_device_id itmtouch_ids
+ 
+ static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
+ {
+-	struct itmtouch_dev * itmtouch = urb->context;
++	struct itmtouch_dev *itmtouch = urb->context;
+ 	unsigned char *data = urb->transfer_buffer;
+-	struct input_dev *dev = &itmtouch->inputdev;
++	struct input_dev *dev = itmtouch->inputdev;
+ 	int retval;
+ 
+ 	switch (urb->status) {
+@@ -156,49 +156,62 @@ static void itmtouch_close(struct input_
+ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id)
+ {
+ 	struct itmtouch_dev *itmtouch;
++	struct input_dev *input_dev;
+ 	struct usb_host_interface *interface;
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct usb_device *udev = interface_to_usbdev(intf);
+ 	unsigned int pipe;
+ 	unsigned int maxp;
+-	char path[PATH_SIZE];
+ 
+ 	interface = intf->cur_altsetting;
+ 	endpoint = &interface->endpoint[0].desc;
+ 
+-	if (!(itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL))) {
++	itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!itmtouch || !input_dev) {
+ 		err("%s - Out of memory.", __FUNCTION__);
+-		return -ENOMEM;
++		goto fail;
+ 	}
+ 
+ 	itmtouch->usbdev = udev;
++	itmtouch->inputdev = input_dev;
+ 
+-	itmtouch->inputdev.private = itmtouch;
+-	itmtouch->inputdev.open = itmtouch_open;
+-	itmtouch->inputdev.close = itmtouch_close;
+-
+-	usb_make_path(udev, path, PATH_SIZE);
+-
+-	itmtouch->inputdev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-	itmtouch->inputdev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+-	itmtouch->inputdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+-
+-	itmtouch->inputdev.name = itmtouch->name;
+-	itmtouch->inputdev.phys = itmtouch->phys;
+-	usb_to_input_id(udev, &itmtouch->inputdev.id);
+-	itmtouch->inputdev.dev = &intf->dev;
++	if (udev->manufacturer)
++		strlcpy(itmtouch->name, udev->manufacturer, sizeof(itmtouch->name));
++
++	if (udev->product) {
++		if (udev->manufacturer)
++			strlcat(itmtouch->name, " ", sizeof(itmtouch->name));
++		strlcat(itmtouch->name, udev->product, sizeof(itmtouch->name));
++	}
+ 
+ 	if (!strlen(itmtouch->name))
+ 		sprintf(itmtouch->name, "USB ITM touchscreen");
+ 
++	usb_make_path(udev, itmtouch->phys, sizeof(itmtouch->phys));
++	strlcpy(itmtouch->phys, "/input0", sizeof(itmtouch->phys));
++
++	input_dev->name = itmtouch->name;
++	input_dev->phys = itmtouch->phys;
++	usb_to_input_id(udev, &input_dev->id);
++	input_dev->cdev.dev = &intf->dev;
++	input_dev->private = itmtouch;
++
++	input_dev->open = itmtouch_open;
++	input_dev->close = itmtouch_close;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
++	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++
+ 	/* device limits */
+ 	/* as specified by the ITM datasheet, X and Y are 12bit,
+ 	 * Z (pressure) is 8 bit. However, the fields are defined up
+ 	 * to 14 bits for future possible expansion.
+ 	 */
+-	input_set_abs_params(&itmtouch->inputdev, ABS_X, 0, 0x0FFF, 2, 0);
+-	input_set_abs_params(&itmtouch->inputdev, ABS_Y, 0, 0x0FFF, 2, 0);
+-	input_set_abs_params(&itmtouch->inputdev, ABS_PRESSURE, 0, 0xFF, 2, 0);
++	input_set_abs_params(input_dev, ABS_X, 0, 0x0FFF, 2, 0);
++	input_set_abs_params(input_dev, ABS_Y, 0, 0x0FFF, 2, 0);
++	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFF, 2, 0);
+ 
+ 	/* initialise the URB so we can read from the transport stream */
+ 	pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress);
+@@ -208,22 +221,23 @@ static int itmtouch_probe(struct usb_int
+ 		maxp = ITM_BUFSIZE;
+ 
+ 	itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL);
+-
+ 	if (!itmtouch->readurb) {
+ 		dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__);
+-		kfree(itmtouch);
+-		return -ENOMEM;
++		goto fail;
+ 	}
+ 
+ 	usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf,
+ 			 maxp, itmtouch_irq, itmtouch, endpoint->bInterval);
+ 
+-	input_register_device(&itmtouch->inputdev);
++	input_register_device(itmtouch->inputdev);
+ 
+-	printk(KERN_INFO "itmtouch: %s registered on %s\n", itmtouch->name, path);
+ 	usb_set_intfdata(intf, itmtouch);
+ 
+ 	return 0;
++
++ fail:	input_free_device(input_dev);
++	kfree(itmtouch);
++	return -ENOMEM;
+ }
+ 
+ static void itmtouch_disconnect(struct usb_interface *intf)
+@@ -233,7 +247,7 @@ static void itmtouch_disconnect(struct u
+ 	usb_set_intfdata(intf, NULL);
+ 
+ 	if (itmtouch) {
+-		input_unregister_device(&itmtouch->inputdev);
++		input_unregister_device(itmtouch->inputdev);
+ 		usb_kill_urb(itmtouch->readurb);
+ 		usb_free_urb(itmtouch->readurb);
+ 		kfree(itmtouch);
+diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
+--- a/drivers/usb/input/kbtab.c
++++ b/drivers/usb/input/kbtab.c
+@@ -34,7 +34,7 @@ MODULE_PARM_DESC(kb_pressure_click, "pre
+ struct kbtab {
+ 	signed char *data;
+ 	dma_addr_t data_dma;
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct usb_device *usbdev;
+ 	struct urb *irq;
+ 	int x, y;
+@@ -48,7 +48,7 @@ static void kbtab_irq(struct urb *urb, s
+ {
+ 	struct kbtab *kbtab = urb->context;
+ 	unsigned char *data = kbtab->data;
+-	struct input_dev *dev = &kbtab->dev;
++	struct input_dev *dev = kbtab->dev;
+ 	int retval;
+ 
+ 	switch (urb->status) {
+@@ -124,53 +124,43 @@ static int kbtab_probe(struct usb_interf
+ 	struct usb_device *dev = interface_to_usbdev(intf);
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct kbtab *kbtab;
+-	char path[64];
++	struct input_dev *input_dev;
+ 
+-	if (!(kbtab = kmalloc(sizeof(struct kbtab), GFP_KERNEL)))
+-		return -ENOMEM;
+-	memset(kbtab, 0, sizeof(struct kbtab));
++	kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!kbtab || !input_dev)
++		goto fail1;
+ 
+ 	kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma);
+-	if (!kbtab->data) {
+-		kfree(kbtab);
+-		return -ENOMEM;
+-	}
++	if (!kbtab->data)
++		goto fail1;
+ 
+ 	kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
+-	if (!kbtab->irq) {
+-		usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
+-		kfree(kbtab);
+-		return -ENOMEM;
+-	}
+-
+-	kbtab->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
+-	kbtab->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+-
+-	kbtab->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+-
+-	kbtab->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
+-
+-	kbtab->dev.mscbit[0] |= BIT(MSC_SERIAL);
++	if (!kbtab->irq)
++		goto fail2;
+ 
+-	kbtab->dev.absmax[ABS_X] = 0x2000;
+-	kbtab->dev.absmax[ABS_Y] = 0x1750;
+-	kbtab->dev.absmax[ABS_PRESSURE] = 0xff;
+-
+-	kbtab->dev.absfuzz[ABS_X] = 4;
+-	kbtab->dev.absfuzz[ABS_Y] = 4;
+-
+-	kbtab->dev.private = kbtab;
+-	kbtab->dev.open = kbtab_open;
+-	kbtab->dev.close = kbtab_close;
++	kbtab->usbdev = dev;
++	kbtab->dev = input_dev;
+ 
+-	usb_make_path(dev, path, 64);
+-	sprintf(kbtab->phys, "%s/input0", path);
++	usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
++	strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));
+ 
+-	kbtab->dev.name = "KB Gear Tablet";
+-	kbtab->dev.phys = kbtab->phys;
+-	usb_to_input_id(dev, &kbtab->dev.id);
+-	kbtab->dev.dev = &intf->dev;
+-	kbtab->usbdev = dev;
++	input_dev->name = "KB Gear Tablet";
++	input_dev->phys = kbtab->phys;
++	usb_to_input_id(dev, &input_dev->id);
++	input_dev->cdev.dev = &intf->dev;
++	input_dev->private = kbtab;
++
++	input_dev->open = kbtab_open;
++	input_dev->close = kbtab_close;
++
++	input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
++	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
++	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
++	input_dev->mscbit[0] |= BIT(MSC_SERIAL);
++	input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
++	input_set_abs_params(input_dev, ABS_X, 0, 0x1750, 4, 0);
++	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
+ 
+ 	endpoint = &intf->cur_altsetting->endpoint[0].desc;
+ 
+@@ -181,23 +171,25 @@ static int kbtab_probe(struct usb_interf
+ 	kbtab->irq->transfer_dma = kbtab->data_dma;
+ 	kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ 
+-	input_register_device(&kbtab->dev);
+-
+-	printk(KERN_INFO "input: KB Gear Tablet on %s\n",  path);
++	input_register_device(kbtab->dev);
+ 
+ 	usb_set_intfdata(intf, kbtab);
+-
+ 	return 0;
++
++fail2:	usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
++fail1:	input_free_device(input_dev);
++	kfree(kbtab);
++	return -ENOMEM;
+ }
+ 
+ static void kbtab_disconnect(struct usb_interface *intf)
+ {
+-	struct kbtab *kbtab = usb_get_intfdata (intf);
++	struct kbtab *kbtab = usb_get_intfdata(intf);
+ 
+ 	usb_set_intfdata(intf, NULL);
+ 	if (kbtab) {
+ 		usb_kill_urb(kbtab->irq);
+-		input_unregister_device(&kbtab->dev);
++		input_unregister_device(kbtab->dev);
+ 		usb_free_urb(kbtab->irq);
+ 		usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
+ 		kfree(kbtab);
+diff --git a/drivers/usb/input/map_to_7segment.h b/drivers/usb/input/map_to_7segment.h
+--- a/drivers/usb/input/map_to_7segment.h
++++ b/drivers/usb/input/map_to_7segment.h
+@@ -79,7 +79,7 @@ struct seg7_conversion_map {
+ 
+ static inline int map_to_seg7(struct seg7_conversion_map *map, int c)
+ {
+-	return c & 0x7f ? map->table[c] : -EINVAL;
++	return c >= 0 && c < sizeof(map->table) ? map->table[c] : -EINVAL;
+ }
+ 
+ #define SEG7_CONVERSION_MAP(_name, _map)	\
+diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
+--- a/drivers/usb/input/mtouchusb.c
++++ b/drivers/usb/input/mtouchusb.c
+@@ -98,7 +98,7 @@ struct mtouch_usb {
+ 	dma_addr_t data_dma;
+ 	struct urb *irq;
+ 	struct usb_device *udev;
+-	struct input_dev input;
++	struct input_dev *input;
+ 	char name[128];
+ 	char phys[64];
+ };
+@@ -135,14 +135,14 @@ static void mtouchusb_irq(struct urb *ur
+ 		goto exit;
+ 	}
+ 
+-	input_regs(&mtouch->input, regs);
+-	input_report_key(&mtouch->input, BTN_TOUCH,
++	input_regs(mtouch->input, regs);
++	input_report_key(mtouch->input, BTN_TOUCH,
+ 			 MTOUCHUSB_GET_TOUCHED(mtouch->data));
+-	input_report_abs(&mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
+-	input_report_abs(&mtouch->input, ABS_Y,
++	input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
++	input_report_abs(mtouch->input, ABS_Y,
+ 			 (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC)
+ 			 - MTOUCHUSB_GET_YC(mtouch->data));
+-	input_sync(&mtouch->input);
++	input_sync(mtouch->input);
+ 
+ exit:
+ 	retval = usb_submit_urb(urb, GFP_ATOMIC);
+@@ -195,10 +195,10 @@ static void mtouchusb_free_buffers(struc
+ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+ {
+ 	struct mtouch_usb *mtouch;
++	struct input_dev *input_dev;
+ 	struct usb_host_interface *interface;
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct usb_device *udev = interface_to_usbdev(intf);
+-	char path[64];
+ 	int nRet;
+ 
+ 	dbg("%s - called", __FUNCTION__);
+@@ -209,57 +209,55 @@ static int mtouchusb_probe(struct usb_in
+ 	dbg("%s - setting endpoint", __FUNCTION__);
+ 	endpoint = &interface->endpoint[0].desc;
+ 
+-	if (!(mtouch = kmalloc(sizeof(struct mtouch_usb), GFP_KERNEL))) {
++	mtouch = kzalloc(sizeof(struct mtouch_usb), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!mtouch || !input_dev) {
+ 		err("%s - Out of memory.", __FUNCTION__);
+-		return -ENOMEM;
++		goto fail1;
+ 	}
+ 
+-	memset(mtouch, 0, sizeof(struct mtouch_usb));
+-	mtouch->udev = udev;
+-
+ 	dbg("%s - allocating buffers", __FUNCTION__);
+-	if (mtouchusb_alloc_buffers(udev, mtouch)) {
+-		mtouchusb_free_buffers(udev, mtouch);
+-		kfree(mtouch);
+-		return -ENOMEM;
+-	}
++	if (mtouchusb_alloc_buffers(udev, mtouch))
++		goto fail2;
+ 
+-	mtouch->input.private = mtouch;
+-	mtouch->input.open = mtouchusb_open;
+-	mtouch->input.close = mtouchusb_close;
+-
+-	usb_make_path(udev, path, 64);
+-	sprintf(mtouch->phys, "%s/input0", path);
+-
+-	mtouch->input.name = mtouch->name;
+-	mtouch->input.phys = mtouch->phys;
+-	usb_to_input_id(udev, &mtouch->input.id);
+-	mtouch->input.dev = &intf->dev;
+-
+-	mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-	mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+-	mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+-
+-	/* Used to Scale Compensated Data and Flip Y */
+-	mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC;
+-	mtouch->input.absmax[ABS_X] = raw_coordinates ?
+-					MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC;
+-	mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ;
+-	mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT;
+-	mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC;
+-	mtouch->input.absmax[ABS_Y] = raw_coordinates ?
+-					MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC;
+-	mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ;
+-	mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT;
++	mtouch->udev = udev;
++	mtouch->input = input_dev;
+ 
+ 	if (udev->manufacturer)
+-		strcat(mtouch->name, udev->manufacturer);
+-	if (udev->product)
+-		sprintf(mtouch->name, "%s %s", mtouch->name, udev->product);
++		strlcpy(mtouch->name, udev->manufacturer, sizeof(mtouch->name));
++
++	if (udev->product) {
++		if (udev->manufacturer)
++			strlcat(mtouch->name, " ", sizeof(mtouch->name));
++		strlcat(mtouch->name, udev->product, sizeof(mtouch->name));
++	}
+ 
+ 	if (!strlen(mtouch->name))
+-		sprintf(mtouch->name, "USB Touchscreen %04x:%04x",
+-			mtouch->input.id.vendor, mtouch->input.id.product);
++		snprintf(mtouch->name, sizeof(mtouch->name),
++			"USB Touchscreen %04x:%04x",
++			le16_to_cpu(udev->descriptor.idVendor),
++			le16_to_cpu(udev->descriptor.idProduct));
++
++	usb_make_path(udev, mtouch->phys, sizeof(mtouch->phys));
++	strlcpy(mtouch->phys, "/input0", sizeof(mtouch->phys));
++
++	input_dev->name = mtouch->name;
++	input_dev->phys = mtouch->phys;
++	usb_to_input_id(udev, &input_dev->id);
++	input_dev->cdev.dev = &intf->dev;
++	input_dev->private = mtouch;
++
++	input_dev->open = mtouchusb_open;
++	input_dev->close = mtouchusb_close;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++	input_set_abs_params(input_dev, ABS_X, MTOUCHUSB_MIN_XC,
++		raw_coordinates ? MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC,
++				MTOUCHUSB_XC_FUZZ, MTOUCHUSB_XC_FLAT);
++	input_set_abs_params(input_dev, ABS_Y, MTOUCHUSB_MIN_YC,
++		raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC,
++		MTOUCHUSB_YC_FUZZ, MTOUCHUSB_YC_FLAT);
+ 
+ 	nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
+ 			       MTOUCHUSB_RESET,
+@@ -272,9 +270,7 @@ static int mtouchusb_probe(struct usb_in
+ 	mtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
+ 	if (!mtouch->irq) {
+ 		dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__);
+-		mtouchusb_free_buffers(udev, mtouch);
+-		kfree(mtouch);
+-		return -ENOMEM;
++		goto fail2;
+ 	}
+ 
+ 	dbg("%s - usb_fill_int_urb", __FUNCTION__);
+@@ -284,7 +280,7 @@ static int mtouchusb_probe(struct usb_in
+ 			 mtouchusb_irq, mtouch, endpoint->bInterval);
+ 
+ 	dbg("%s - input_register_device", __FUNCTION__);
+-	input_register_device(&mtouch->input);
++	input_register_device(mtouch->input);
+ 
+ 	nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
+ 			       MTOUCHUSB_ASYNC_REPORT,
+@@ -293,10 +289,13 @@ static int mtouchusb_probe(struct usb_in
+ 	dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
+ 	    __FUNCTION__, nRet);
+ 
+-	printk(KERN_INFO "input: %s on %s\n", mtouch->name, path);
+ 	usb_set_intfdata(intf, mtouch);
+-
+ 	return 0;
++
++fail2:	mtouchusb_free_buffers(udev, mtouch);
++fail1:	input_free_device(input_dev);
++	kfree(mtouch);
++	return -ENOMEM;
+ }
+ 
+ static void mtouchusb_disconnect(struct usb_interface *intf)
+@@ -308,7 +307,7 @@ static void mtouchusb_disconnect(struct 
+ 	if (mtouch) {
+ 		dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__);
+ 		usb_kill_urb(mtouch->irq);
+-		input_unregister_device(&mtouch->input);
++		input_unregister_device(mtouch->input);
+ 		usb_free_urb(mtouch->irq);
+ 		mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch);
+ 		kfree(mtouch);
+diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
+--- a/drivers/usb/input/pid.c
++++ b/drivers/usb/input/pid.c
+@@ -198,7 +198,7 @@ static int hid_pid_upload_effect(struct 
+ 		}
+ 
+ 		effect->id = id;
+-		dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d\n.", id);
++		dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d.\n", id);
+ 		pid_private->effects[id].owner = current->pid;
+ 		pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
+ 		spin_unlock_irqrestore(&pid_private->lock, flags);
+@@ -262,6 +262,7 @@ int hid_pid_init(struct hid_device *hid)
+ {
+ 	struct hid_ff_pid *private;
+ 	struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
++	struct input_dev *input_dev = hidinput->input;
+ 
+ 	private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
+ 	if (!private)
+@@ -281,11 +282,12 @@ int hid_pid_init(struct hid_device *hid)
+ 	usb_fill_control_urb(private->urbffout, hid->dev, 0,
+ 			     (void *)&private->ffcr, private->ctrl_buffer, 8,
+ 			     hid_pid_ctrl_out, hid);
+-	hidinput->input.upload_effect = hid_pid_upload_effect;
+-	hidinput->input.flush = hid_pid_flush;
+-	hidinput->input.ff_effects_max = 8;	// A random default
+-	set_bit(EV_FF, hidinput->input.evbit);
+-	set_bit(EV_FF_STATUS, hidinput->input.evbit);
++
++	input_dev->upload_effect = hid_pid_upload_effect;
++	input_dev->flush = hid_pid_flush;
++	input_dev->ff_effects_max = 8;	// A random default
++	set_bit(EV_FF, input_dev->evbit);
++	set_bit(EV_FF_STATUS, input_dev->evbit);
+ 
+ 	spin_lock_init(&private->lock);
+ 
+diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
+--- a/drivers/usb/input/powermate.c
++++ b/drivers/usb/input/powermate.c
+@@ -68,7 +68,7 @@ struct powermate_device {
+ 	struct usb_ctrlrequest *configcr;
+ 	dma_addr_t configcr_dma;
+ 	struct usb_device *udev;
+-	struct input_dev input;
++	struct input_dev *input;
+ 	spinlock_t lock;
+ 	int static_brightness;
+ 	int pulse_speed;
+@@ -106,10 +106,10 @@ static void powermate_irq(struct urb *ur
+ 	}
+ 
+ 	/* handle updates to device state */
+-	input_regs(&pm->input, regs);
+-	input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01);
+-	input_report_rel(&pm->input, REL_DIAL, pm->data[1]);
+-	input_sync(&pm->input);
++	input_regs(pm->input, regs);
++	input_report_key(pm->input, BTN_0, pm->data[0] & 0x01);
++	input_report_rel(pm->input, REL_DIAL, pm->data[1]);
++	input_sync(pm->input);
+ 
+ exit:
+ 	retval = usb_submit_urb (urb, GFP_ATOMIC);
+@@ -153,10 +153,10 @@ static void powermate_sync_state(struct 
+ 
+ 		   Only values of 'arg' quite close to 255 are particularly useful/spectacular.
+ 		*/
+-		if (pm->pulse_speed < 255){
++		if (pm->pulse_speed < 255) {
+ 			op = 0;                   // divide
+ 			arg = 255 - pm->pulse_speed;
+-		} else if (pm->pulse_speed > 255){
++		} else if (pm->pulse_speed > 255) {
+ 			op = 2;                   // multiply
+ 			arg = pm->pulse_speed - 255;
+ 		} else {
+@@ -166,11 +166,11 @@ static void powermate_sync_state(struct 
+ 		pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE );
+ 		pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op );
+ 		pm->requires_update &= ~UPDATE_PULSE_MODE;
+-	}else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){
++	} else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS) {
+ 		pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
+ 		pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
+ 		pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
+-	}else{
++	} else {
+ 		printk(KERN_ERR "powermate: unknown update required");
+ 		pm->requires_update = 0; /* fudge the bug */
+ 		return;
+@@ -228,19 +228,19 @@ static void powermate_pulse_led(struct p
+ 	spin_lock_irqsave(&pm->lock, flags);
+ 
+ 	/* mark state updates which are required */
+-	if (static_brightness != pm->static_brightness){
++	if (static_brightness != pm->static_brightness) {
+ 		pm->static_brightness = static_brightness;
+ 		pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;
+ 	}
+-	if (pulse_asleep != pm->pulse_asleep){
++	if (pulse_asleep != pm->pulse_asleep) {
+ 		pm->pulse_asleep = pulse_asleep;
+ 		pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS);
+ 	}
+-	if (pulse_awake != pm->pulse_awake){
++	if (pulse_awake != pm->pulse_awake) {
+ 		pm->pulse_awake = pulse_awake;
+ 		pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS);
+ 	}
+-	if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table){
++	if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table) {
+ 		pm->pulse_speed = pulse_speed;
+ 		pm->pulse_table = pulse_table;
+ 		pm->requires_update |= UPDATE_PULSE_MODE;
+@@ -283,6 +283,7 @@ static int powermate_alloc_buffers(struc
+ 				    SLAB_ATOMIC, &pm->data_dma);
+ 	if (!pm->data)
+ 		return -1;
++
+ 	pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
+ 					SLAB_ATOMIC, &pm->configcr_dma);
+ 	if (!pm->configcr)
+@@ -308,8 +309,9 @@ static int powermate_probe(struct usb_in
+ 	struct usb_host_interface *interface;
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct powermate_device *pm;
++	struct input_dev *input_dev;
+ 	int pipe, maxp;
+-	char path[64];
++	int err = -ENOMEM;
+ 
+ 	interface = intf->cur_altsetting;
+ 	endpoint = &interface->endpoint[0].desc;
+@@ -323,42 +325,61 @@ static int powermate_probe(struct usb_in
+ 		0, interface->desc.bInterfaceNumber, NULL, 0,
+ 		USB_CTRL_SET_TIMEOUT);
+ 
+-	if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL)))
+-		return -ENOMEM;
+-
+-	memset(pm, 0, sizeof(struct powermate_device));
+-	pm->udev = udev;
++	pm = kzalloc(sizeof(struct powermate_device), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!pm || !input_dev)
++		goto fail1;
+ 
+-	if (powermate_alloc_buffers(udev, pm)) {
+-		powermate_free_buffers(udev, pm);
+-		kfree(pm);
+-		return -ENOMEM;
+-	}
++	if (powermate_alloc_buffers(udev, pm))
++		goto fail2;
+ 
+ 	pm->irq = usb_alloc_urb(0, GFP_KERNEL);
+-	if (!pm->irq) {
+-		powermate_free_buffers(udev, pm);
+-		kfree(pm);
+-		return -ENOMEM;
+-	}
++	if (!pm->irq)
++		goto fail2;
+ 
+ 	pm->config = usb_alloc_urb(0, GFP_KERNEL);
+-	if (!pm->config) {
+-		usb_free_urb(pm->irq);
+-		powermate_free_buffers(udev, pm);
+-		kfree(pm);
+-		return -ENOMEM;
+-	}
++	if (!pm->config)
++		goto fail3;
++
++	pm->udev = udev;
++	pm->input = input_dev;
++
++	usb_make_path(udev, pm->phys, sizeof(pm->phys));
++	strlcpy(pm->phys, "/input0", sizeof(pm->phys));
+ 
+ 	spin_lock_init(&pm->lock);
+-	init_input_dev(&pm->input);
++
++	switch (le16_to_cpu(udev->descriptor.idProduct)) {
++	case POWERMATE_PRODUCT_NEW:
++		input_dev->name = pm_name_powermate;
++		break;
++	case POWERMATE_PRODUCT_OLD:
++		input_dev->name = pm_name_soundknob;
++		break;
++	default:
++		input_dev->name = pm_name_soundknob;
++		printk(KERN_WARNING "powermate: unknown product id %04x\n",
++		       le16_to_cpu(udev->descriptor.idProduct));
++	}
++
++	input_dev->phys = pm->phys;
++	usb_to_input_id(udev, &input_dev->id);
++	input_dev->cdev.dev = &intf->dev;
++	input_dev->private = pm;
++
++	input_dev->event = powermate_input_event;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
++	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
++	input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
++	input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
+ 
+ 	/* get a handle to the interrupt data pipe */
+ 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+ 	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+ 
+-	if(maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX){
+-		printk("powermate: Expected payload of %d--%d bytes, found %d bytes!\n",
++	if (maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX) {
++		printk(KERN_WARNING "powermate: Expected payload of %d--%d bytes, found %d bytes!\n",
+ 			POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp);
+ 		maxp = POWERMATE_PAYLOAD_SIZE_MAX;
+ 	}
+@@ -371,35 +392,11 @@ static int powermate_probe(struct usb_in
+ 
+ 	/* register our interrupt URB with the USB system */
+ 	if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
+-		powermate_free_buffers(udev, pm);
+-		kfree(pm);
+-		return -EIO; /* failure */
++		err = -EIO;
++		goto fail4;
+ 	}
+ 
+-	switch (le16_to_cpu(udev->descriptor.idProduct)) {
+-	case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break;
+-	case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break;
+-	default:
+-		pm->input.name = pm_name_soundknob;
+-		printk(KERN_WARNING "powermate: unknown product id %04x\n",
+-		       le16_to_cpu(udev->descriptor.idProduct));
+-	}
+-
+-	pm->input.private = pm;
+-	pm->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
+-	pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
+-	pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
+-	pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
+-	usb_to_input_id(udev, &pm->input.id);
+-	pm->input.event = powermate_input_event;
+-	pm->input.dev = &intf->dev;
+-	pm->input.phys = pm->phys;
+-
+-	input_register_device(&pm->input);
+-
+-	usb_make_path(udev, path, 64);
+-	snprintf(pm->phys, 64, "%s/input0", path);
+-	printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.phys);
++	input_register_device(pm->input);
+ 
+ 	/* force an update of everything */
+ 	pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
+@@ -407,6 +404,13 @@ static int powermate_probe(struct usb_in
+ 
+ 	usb_set_intfdata(intf, pm);
+ 	return 0;
++
++fail4:	usb_free_urb(pm->config);
++fail3:	usb_free_urb(pm->irq);
++fail2:	powermate_free_buffers(udev, pm);
++fail1:	input_free_device(input_dev);
++	kfree(pm);
++	return err;
+ }
+ 
+ /* Called when a USB device we've accepted ownership of is removed */
+@@ -418,7 +422,7 @@ static void powermate_disconnect(struct 
+ 	if (pm) {
+ 		pm->requires_update = 0;
+ 		usb_kill_urb(pm->irq);
+-		input_unregister_device(&pm->input);
++		input_unregister_device(pm->input);
+ 		usb_free_urb(pm->irq);
+ 		usb_free_urb(pm->config);
+ 		powermate_free_buffers(interface_to_usbdev(intf), pm);
+diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
+--- a/drivers/usb/input/touchkitusb.c
++++ b/drivers/usb/input/touchkitusb.c
+@@ -68,14 +68,16 @@ struct touchkit_usb {
+ 	dma_addr_t data_dma;
+ 	struct urb *irq;
+ 	struct usb_device *udev;
+-	struct input_dev input;
++	struct input_dev *input;
+ 	char name[128];
+ 	char phys[64];
+ };
+ 
+ static struct usb_device_id touchkit_devices[] = {
+ 	{USB_DEVICE(0x3823, 0x0001)},
++	{USB_DEVICE(0x0123, 0x0001)},
+ 	{USB_DEVICE(0x0eef, 0x0001)},
++	{USB_DEVICE(0x0eef, 0x0002)},
+ 	{}
+ };
+ 
+@@ -115,12 +117,12 @@ static void touchkit_irq(struct urb *urb
+ 		y = TOUCHKIT_GET_Y(touchkit->data);
+ 	}
+ 
+-	input_regs(&touchkit->input, regs);
+-	input_report_key(&touchkit->input, BTN_TOUCH,
++	input_regs(touchkit->input, regs);
++	input_report_key(touchkit->input, BTN_TOUCH,
+ 	                 TOUCHKIT_GET_TOUCHED(touchkit->data));
+-	input_report_abs(&touchkit->input, ABS_X, x);
+-	input_report_abs(&touchkit->input, ABS_Y, y);
+-	input_sync(&touchkit->input);
++	input_report_abs(touchkit->input, ABS_X, x);
++	input_report_abs(touchkit->input, ABS_Y, y);
++	input_sync(touchkit->input);
+ 
+ exit:
+ 	retval = usb_submit_urb(urb, GFP_ATOMIC);
+@@ -171,87 +173,81 @@ static void touchkit_free_buffers(struct
+ static int touchkit_probe(struct usb_interface *intf,
+ 			  const struct usb_device_id *id)
+ {
+-	int ret;
+ 	struct touchkit_usb *touchkit;
++	struct input_dev *input_dev;
+ 	struct usb_host_interface *interface;
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct usb_device *udev = interface_to_usbdev(intf);
+-	char path[64];
+ 
+ 	interface = intf->cur_altsetting;
+ 	endpoint = &interface->endpoint[0].desc;
+ 
+-	touchkit = kmalloc(sizeof(struct touchkit_usb), GFP_KERNEL);
+-	if (!touchkit)
+-		return -ENOMEM;
+-
+-	memset(touchkit, 0, sizeof(struct touchkit_usb));
+-	touchkit->udev = udev;
+-
+-	if (touchkit_alloc_buffers(udev, touchkit)) {
+-		ret = -ENOMEM;
++	touchkit = kzalloc(sizeof(struct touchkit_usb), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!touchkit || !input_dev)
+ 		goto out_free;
+-	}
+ 
+-	touchkit->input.private = touchkit;
+-	touchkit->input.open = touchkit_open;
+-	touchkit->input.close = touchkit_close;
+-
+-	usb_make_path(udev, path, 64);
+-	sprintf(touchkit->phys, "%s/input0", path);
+-
+-	touchkit->input.name = touchkit->name;
+-	touchkit->input.phys = touchkit->phys;
+-	usb_to_input_id(udev, &touchkit->input.id);
+-	touchkit->input.dev = &intf->dev;
+-
+-	touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-	touchkit->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+-	touchkit->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+-
+-	/* Used to Scale Compensated Data */
+-	touchkit->input.absmin[ABS_X] = TOUCHKIT_MIN_XC;
+-	touchkit->input.absmax[ABS_X] = TOUCHKIT_MAX_XC;
+-	touchkit->input.absfuzz[ABS_X] = TOUCHKIT_XC_FUZZ;
+-	touchkit->input.absflat[ABS_X] = TOUCHKIT_XC_FLAT;
+-	touchkit->input.absmin[ABS_Y] = TOUCHKIT_MIN_YC;
+-	touchkit->input.absmax[ABS_Y] = TOUCHKIT_MAX_YC;
+-	touchkit->input.absfuzz[ABS_Y] = TOUCHKIT_YC_FUZZ;
+-	touchkit->input.absflat[ABS_Y] = TOUCHKIT_YC_FLAT;
+-
+-	if (udev->manufacturer)
+-		strcat(touchkit->name, udev->manufacturer);
+-	if (udev->product)
+-		sprintf(touchkit->name, "%s %s", touchkit->name, udev->product);
+-
+-	if (!strlen(touchkit->name))
+-		sprintf(touchkit->name, "USB Touchscreen %04x:%04x",
+-		        touchkit->input.id.vendor, touchkit->input.id.product);
++	if (touchkit_alloc_buffers(udev, touchkit))
++		goto out_free;
+ 
+ 	touchkit->irq = usb_alloc_urb(0, GFP_KERNEL);
+ 	if (!touchkit->irq) {
+ 		dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__);
+-		ret = -ENOMEM;
+ 		goto out_free_buffers;
+ 	}
+ 
++	touchkit->udev = udev;
++	touchkit->input = input_dev;
++
++	if (udev->manufacturer)
++		strlcpy(touchkit->name, udev->manufacturer, sizeof(touchkit->name));
++
++	if (udev->product) {
++		if (udev->manufacturer)
++			strlcat(touchkit->name, " ", sizeof(touchkit->name));
++		strlcat(touchkit->name, udev->product, sizeof(touchkit->name));
++	}
++
++	if (!strlen(touchkit->name))
++		snprintf(touchkit->name, sizeof(touchkit->name),
++			"USB Touchscreen %04x:%04x",
++			 le16_to_cpu(udev->descriptor.idVendor),
++			 le16_to_cpu(udev->descriptor.idProduct));
++
++	usb_make_path(udev, touchkit->phys, sizeof(touchkit->phys));
++	strlcpy(touchkit->phys, "/input0", sizeof(touchkit->phys));
++
++	input_dev->name = touchkit->name;
++	input_dev->phys = touchkit->phys;
++	usb_to_input_id(udev, &input_dev->id);
++	input_dev->cdev.dev = &intf->dev;
++	input_dev->private = touchkit;
++	input_dev->open = touchkit_open;
++	input_dev->close = touchkit_close;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++	input_set_abs_params(input_dev, ABS_X, TOUCHKIT_MIN_XC, TOUCHKIT_MAX_XC,
++				TOUCHKIT_XC_FUZZ, TOUCHKIT_XC_FLAT);
++	input_set_abs_params(input_dev, ABS_Y, TOUCHKIT_MIN_YC, TOUCHKIT_MAX_YC,
++				TOUCHKIT_YC_FUZZ, TOUCHKIT_YC_FLAT);
++
+ 	usb_fill_int_urb(touchkit->irq, touchkit->udev,
+-	                 usb_rcvintpipe(touchkit->udev, 0x81),
+-	                 touchkit->data, TOUCHKIT_REPORT_DATA_SIZE,
+-	                 touchkit_irq, touchkit, endpoint->bInterval);
++			 usb_rcvintpipe(touchkit->udev, 0x81),
++			 touchkit->data, TOUCHKIT_REPORT_DATA_SIZE,
++			 touchkit_irq, touchkit, endpoint->bInterval);
+ 
+-	input_register_device(&touchkit->input);
++	input_register_device(touchkit->input);
+ 
+-	printk(KERN_INFO "input: %s on %s\n", touchkit->name, path);
+ 	usb_set_intfdata(intf, touchkit);
+-
+ 	return 0;
+ 
+ out_free_buffers:
+ 	touchkit_free_buffers(udev, touchkit);
+ out_free:
++	input_free_device(input_dev);
+ 	kfree(touchkit);
+-	return ret;
++	return -ENOMEM;
+ }
+ 
+ static void touchkit_disconnect(struct usb_interface *intf)
+@@ -265,8 +261,8 @@ static void touchkit_disconnect(struct u
+ 
+ 	dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__);
+ 	usb_set_intfdata(intf, NULL);
+-	input_unregister_device(&touchkit->input);
+ 	usb_kill_urb(touchkit->irq);
++	input_unregister_device(touchkit->input);
+ 	usb_free_urb(touchkit->irq);
+ 	touchkit_free_buffers(interface_to_usbdev(intf), touchkit);
+ 	kfree(touchkit);
+diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
+--- a/drivers/usb/input/usbkbd.c
++++ b/drivers/usb/input/usbkbd.c
+@@ -66,7 +66,7 @@ static unsigned char usb_kbd_keycode[256
+ };
+ 
+ struct usb_kbd {
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct usb_device *usbdev;
+ 	unsigned char old[8];
+ 	struct urb *irq, *led;
+@@ -99,29 +99,29 @@ static void usb_kbd_irq(struct urb *urb,
+ 		goto resubmit;
+ 	}
+ 
+-	input_regs(&kbd->dev, regs);
++	input_regs(kbd->dev, regs);
+ 
+ 	for (i = 0; i < 8; i++)
+-		input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
++		input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
+ 
+ 	for (i = 2; i < 8; i++) {
+ 
+ 		if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
+ 			if (usb_kbd_keycode[kbd->old[i]])
+-				input_report_key(&kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
++				input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
+ 			else
+ 				info("Unknown key (scancode %#x) released.", kbd->old[i]);
+ 		}
+ 
+ 		if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
+ 			if (usb_kbd_keycode[kbd->new[i]])
+-				input_report_key(&kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
++				input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
+ 			else
+ 				info("Unknown key (scancode %#x) pressed.", kbd->new[i]);
+ 		}
+ 	}
+ 
+-	input_sync(&kbd->dev);
++	input_sync(kbd->dev);
+ 
+ 	memcpy(kbd->old, kbd->new, 8);
+ 
+@@ -227,12 +227,12 @@ static void usb_kbd_free_mem(struct usb_
+ static int usb_kbd_probe(struct usb_interface *iface,
+ 			 const struct usb_device_id *id)
+ {
+-	struct usb_device * dev = interface_to_usbdev(iface);
++	struct usb_device *dev = interface_to_usbdev(iface);
+ 	struct usb_host_interface *interface;
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct usb_kbd *kbd;
++	struct input_dev *input_dev;
+ 	int i, pipe, maxp;
+-	char path[64];
+ 
+ 	interface = iface->cur_altsetting;
+ 
+@@ -240,37 +240,59 @@ static int usb_kbd_probe(struct usb_inte
+ 		return -ENODEV;
+ 
+ 	endpoint = &interface->endpoint[0].desc;
+-	if (!(endpoint->bEndpointAddress & 0x80))
++	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
+ 		return -ENODEV;
+-	if ((endpoint->bmAttributes & 3) != 3)
++	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+ 		return -ENODEV;
+ 
+ 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
+ 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+ 
+-	if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL)))
+-		return -ENOMEM;
+-	memset(kbd, 0, sizeof(struct usb_kbd));
++	kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!kbd || !input_dev)
++		goto fail1;
+ 
+-	if (usb_kbd_alloc_mem(dev, kbd)) {
+-		usb_kbd_free_mem(dev, kbd);
+-		kfree(kbd);
+-		return -ENOMEM;
+-	}
++	if (usb_kbd_alloc_mem(dev, kbd))
++		goto fail2;
+ 
+ 	kbd->usbdev = dev;
++	kbd->dev = input_dev;
++
++	if (dev->manufacturer)
++		strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
++
++	if (dev->product) {
++		if (dev->manufacturer)
++			strlcat(kbd->name, " ", sizeof(kbd->name));
++		strlcat(kbd->name, dev->product, sizeof(kbd->name));
++	}
++
++	if (!strlen(kbd->name))
++		snprintf(kbd->name, sizeof(kbd->name),
++			 "USB HIDBP Keyboard %04x:%04x",
++			 le16_to_cpu(dev->descriptor.idVendor),
++			 le16_to_cpu(dev->descriptor.idProduct));
++
++	usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
++	strlcpy(kbd->phys, "/input0", sizeof(kbd->phys));
++
++	input_dev->name = kbd->name;
++	input_dev->phys = kbd->phys;
++	usb_to_input_id(dev, &input_dev->id);
++	input_dev->cdev.dev = &iface->dev;
++	input_dev->private = kbd;
+ 
+-	kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+-	kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
++	input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
+ 
+ 	for (i = 0; i < 255; i++)
+-		set_bit(usb_kbd_keycode[i], kbd->dev.keybit);
+-	clear_bit(0, kbd->dev.keybit);
++		set_bit(usb_kbd_keycode[i], input_dev->keybit);
++	clear_bit(0, input_dev->keybit);
+ 
+-	kbd->dev.private = kbd;
+-	kbd->dev.event = usb_kbd_event;
+-	kbd->dev.open = usb_kbd_open;
+-	kbd->dev.close = usb_kbd_close;
++	input_dev->event = usb_kbd_event;
++	input_dev->open = usb_kbd_open;
++	input_dev->close = usb_kbd_close;
+ 
+ 	usb_fill_int_urb(kbd->irq, dev, pipe,
+ 			 kbd->new, (maxp > 8 ? 8 : maxp),
+@@ -284,37 +306,22 @@ static int usb_kbd_probe(struct usb_inte
+ 	kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
+ 	kbd->cr->wLength = cpu_to_le16(1);
+ 
+-	usb_make_path(dev, path, 64);
+-	sprintf(kbd->phys, "%s/input0", path);
+-
+-	kbd->dev.name = kbd->name;
+-	kbd->dev.phys = kbd->phys;
+-	usb_to_input_id(dev, &kbd->dev.id);
+-	kbd->dev.dev = &iface->dev;
+-
+-	if (dev->manufacturer)
+-		strcat(kbd->name, dev->manufacturer);
+-	if (dev->product)
+-		sprintf(kbd->name, "%s %s", kbd->name, dev->product);
+-
+-	if (!strlen(kbd->name))
+-		sprintf(kbd->name, "USB HIDBP Keyboard %04x:%04x",
+-			kbd->dev.id.vendor, kbd->dev.id.product);
+-
+ 	usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0),
+ 			     (void *) kbd->cr, kbd->leds, 1,
+ 			     usb_kbd_led, kbd);
+ 	kbd->led->setup_dma = kbd->cr_dma;
+ 	kbd->led->transfer_dma = kbd->leds_dma;
+-	kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
+-				| URB_NO_SETUP_DMA_MAP);
++	kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
+ 
+-	input_register_device(&kbd->dev);
+-
+-	printk(KERN_INFO "input: %s on %s\n", kbd->name, path);
++	input_register_device(kbd->dev);
+ 
+ 	usb_set_intfdata(iface, kbd);
+ 	return 0;
++
++fail2:	usb_kbd_free_mem(dev, kbd);
++fail1:	input_free_device(input_dev);
++	kfree(kbd);
++	return -ENOMEM;
+ }
+ 
+ static void usb_kbd_disconnect(struct usb_interface *intf)
+@@ -324,7 +331,7 @@ static void usb_kbd_disconnect(struct us
+ 	usb_set_intfdata(intf, NULL);
+ 	if (kbd) {
+ 		usb_kill_urb(kbd->irq);
+-		input_unregister_device(&kbd->dev);
++		input_unregister_device(kbd->dev);
+ 		usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
+ 		kfree(kbd);
+ 	}
+diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
+--- a/drivers/usb/input/usbmouse.c
++++ b/drivers/usb/input/usbmouse.c
+@@ -50,7 +50,7 @@ struct usb_mouse {
+ 	char name[128];
+ 	char phys[64];
+ 	struct usb_device *usbdev;
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct urb *irq;
+ 
+ 	signed char *data;
+@@ -61,7 +61,7 @@ static void usb_mouse_irq(struct urb *ur
+ {
+ 	struct usb_mouse *mouse = urb->context;
+ 	signed char *data = mouse->data;
+-	struct input_dev *dev = &mouse->dev;
++	struct input_dev *dev = mouse->dev;
+ 	int status;
+ 
+ 	switch (urb->status) {
+@@ -115,14 +115,14 @@ static void usb_mouse_close(struct input
+ 	usb_kill_urb(mouse->irq);
+ }
+ 
+-static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id)
++static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
+ {
+-	struct usb_device * dev = interface_to_usbdev(intf);
++	struct usb_device *dev = interface_to_usbdev(intf);
+ 	struct usb_host_interface *interface;
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct usb_mouse *mouse;
++	struct input_dev *input_dev;
+ 	int pipe, maxp;
+-	char path[64];
+ 
+ 	interface = intf->cur_altsetting;
+ 
+@@ -130,59 +130,62 @@ static int usb_mouse_probe(struct usb_in
+ 		return -ENODEV;
+ 
+ 	endpoint = &interface->endpoint[0].desc;
+-	if (!(endpoint->bEndpointAddress & 0x80))
++	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
+ 		return -ENODEV;
+-	if ((endpoint->bmAttributes & 3) != 3)
++	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+ 		return -ENODEV;
+ 
+ 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
+ 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+ 
+-	if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL)))
+-		return -ENOMEM;
+-	memset(mouse, 0, sizeof(struct usb_mouse));
++	mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!mouse || !input_dev)
++		goto fail1;
+ 
+ 	mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
+-	if (!mouse->data) {
+-		kfree(mouse);
+-		return -ENOMEM;
+-	}
++	if (!mouse->data)
++		goto fail1;
+ 
+ 	mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
+-	if (!mouse->irq) {
+-		usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
+-		kfree(mouse);
+-		return -ENODEV;
+-	}
++	if (!mouse->irq)
++		goto fail2;
+ 
+ 	mouse->usbdev = dev;
+-
+-	mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+-	mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+-	mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+-	mouse->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
+-	mouse->dev.relbit[0] |= BIT(REL_WHEEL);
+-
+-	mouse->dev.private = mouse;
+-	mouse->dev.open = usb_mouse_open;
+-	mouse->dev.close = usb_mouse_close;
+-
+-	usb_make_path(dev, path, 64);
+-	sprintf(mouse->phys, "%s/input0", path);
+-
+-	mouse->dev.name = mouse->name;
+-	mouse->dev.phys = mouse->phys;
+-	usb_to_input_id(dev, &mouse->dev.id);
+-	mouse->dev.dev = &intf->dev;
++	mouse->dev = input_dev;
+ 
+ 	if (dev->manufacturer)
+-		strcat(mouse->name, dev->manufacturer);
+-	if (dev->product)
+-		sprintf(mouse->name, "%s %s", mouse->name, dev->product);
++		strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
++
++	if (dev->product) {
++		if (dev->manufacturer)
++			strlcat(mouse->name, " ", sizeof(mouse->name));
++		strlcat(mouse->name, dev->product, sizeof(mouse->name));
++	}
+ 
+ 	if (!strlen(mouse->name))
+-		sprintf(mouse->name, "USB HIDBP Mouse %04x:%04x",
+-			mouse->dev.id.vendor, mouse->dev.id.product);
++		snprintf(mouse->name, sizeof(mouse->name),
++			 "USB HIDBP Mouse %04x:%04x",
++			 le16_to_cpu(dev->descriptor.idVendor),
++			 le16_to_cpu(dev->descriptor.idProduct));
++
++	usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
++	strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
++
++	input_dev->name = mouse->name;
++	input_dev->phys = mouse->phys;
++	usb_to_input_id(dev, &input_dev->id);
++	input_dev->cdev.dev = &intf->dev;
++
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
++	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
++	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
++	input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
++	input_dev->relbit[0] |= BIT(REL_WHEEL);
++
++	input_dev->private = mouse;
++	input_dev->open = usb_mouse_open;
++	input_dev->close = usb_mouse_close;
+ 
+ 	usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
+ 			 (maxp > 8 ? 8 : maxp),
+@@ -190,11 +193,15 @@ static int usb_mouse_probe(struct usb_in
+ 	mouse->irq->transfer_dma = mouse->data_dma;
+ 	mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ 
+-	input_register_device(&mouse->dev);
+-	printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
++	input_register_device(mouse->dev);
+ 
+ 	usb_set_intfdata(intf, mouse);
+ 	return 0;
++
++fail2:	usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
++fail1:	input_free_device(input_dev);
++	kfree(mouse);
++	return -ENOMEM;
+ }
+ 
+ static void usb_mouse_disconnect(struct usb_interface *intf)
+@@ -204,7 +211,7 @@ static void usb_mouse_disconnect(struct 
+ 	usb_set_intfdata(intf, NULL);
+ 	if (mouse) {
+ 		usb_kill_urb(mouse->irq);
+-		input_unregister_device(&mouse->dev);
++		input_unregister_device(mouse->dev);
+ 		usb_free_urb(mouse->irq);
+ 		usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
+ 		kfree(mouse);
+diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
+--- a/drivers/usb/input/wacom.c
++++ b/drivers/usb/input/wacom.c
+@@ -111,7 +111,7 @@ struct wacom_features {
+ struct wacom {
+ 	signed char *data;
+ 	dma_addr_t data_dma;
+-	struct input_dev dev;
++	struct input_dev *dev;
+ 	struct usb_device *usbdev;
+ 	struct urb *irq;
+ 	struct wacom_features *features;
+@@ -135,7 +135,7 @@ static void wacom_pl_irq(struct urb *urb
+ {
+ 	struct wacom *wacom = urb->context;
+ 	unsigned char *data = wacom->data;
+-	struct input_dev *dev = &wacom->dev;
++	struct input_dev *dev = wacom->dev;
+ 	int prox, pressure;
+ 	int retval;
+ 
+@@ -225,7 +225,7 @@ static void wacom_ptu_irq(struct urb *ur
+ {
+ 	struct wacom *wacom = urb->context;
+ 	unsigned char *data = wacom->data;
+-	struct input_dev *dev = &wacom->dev;
++	struct input_dev *dev = wacom->dev;
+ 	int retval;
+ 
+ 	switch (urb->status) {
+@@ -275,7 +275,7 @@ static void wacom_penpartner_irq(struct 
+ {
+ 	struct wacom *wacom = urb->context;
+ 	unsigned char *data = wacom->data;
+-	struct input_dev *dev = &wacom->dev;
++	struct input_dev *dev = wacom->dev;
+ 	int retval;
+ 
+ 	switch (urb->status) {
+@@ -318,7 +318,7 @@ static void wacom_graphire_irq(struct ur
+ {
+ 	struct wacom *wacom = urb->context;
+ 	unsigned char *data = wacom->data;
+-	struct input_dev *dev = &wacom->dev;
++	struct input_dev *dev = wacom->dev;
+ 	int x, y;
+ 	int retval;
+ 
+@@ -397,7 +397,7 @@ static int wacom_intuos_inout(struct urb
+ {
+ 	struct wacom *wacom = urb->context;
+ 	unsigned char *data = wacom->data;
+-	struct input_dev *dev = &wacom->dev;
++	struct input_dev *dev = wacom->dev;
+ 	int idx;
+ 
+ 	/* tool number */
+@@ -479,7 +479,7 @@ static void wacom_intuos_general(struct 
+ {
+ 	struct wacom *wacom = urb->context;
+ 	unsigned char *data = wacom->data;
+-	struct input_dev *dev = &wacom->dev;
++	struct input_dev *dev = wacom->dev;
+ 	unsigned int t;
+ 
+ 	/* general pen packet */
+@@ -509,7 +509,7 @@ static void wacom_intuos_irq(struct urb 
+ {
+ 	struct wacom *wacom = urb->context;
+ 	unsigned char *data = wacom->data;
+-	struct input_dev *dev = &wacom->dev;
++	struct input_dev *dev = wacom->dev;
+ 	unsigned int t;
+ 	int idx;
+ 	int retval;
+@@ -738,95 +738,83 @@ static int wacom_probe(struct usb_interf
+ {
+ 	struct usb_device *dev = interface_to_usbdev(intf);
+ 	struct usb_endpoint_descriptor *endpoint;
+-	char rep_data[2] = {0x02, 0x02};
+ 	struct wacom *wacom;
+-	char path[64];
++	struct input_dev *input_dev;
++	char rep_data[2] = {0x02, 0x02};
+ 
+-	if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL)))
+-		return -ENOMEM;
+-	memset(wacom, 0, sizeof(struct wacom));
++	wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!wacom || !input_dev)
++		goto fail1;
+ 
+ 	wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
+-	if (!wacom->data) {
+-		kfree(wacom);
+-		return -ENOMEM;
+-	}
++	if (!wacom->data)
++		goto fail1;
+ 
+ 	wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
+-	if (!wacom->irq) {
+-		usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
+-		kfree(wacom);
+-		return -ENOMEM;
+-	}
++	if (!wacom->irq)
++		goto fail2;
++
++	wacom->usbdev = dev;
++	wacom->dev = input_dev;
++	usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
++	strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
+ 
+ 	wacom->features = wacom_features + (id - wacom_ids);
++	if (wacom->features->pktlen > 10)
++		BUG();
+ 
+-	wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
+-	wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+-	wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
++	input_dev->name = wacom->features->name;
++	usb_to_input_id(dev, &input_dev->id);
++
++	input_dev->cdev.dev = &intf->dev;
++	input_dev->private = wacom;
++	input_dev->open = wacom_open;
++	input_dev->close = wacom_close;
++
++	input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
++	input_set_abs_params(input_dev, ABS_X, 0, wacom->features->y_max, 4, 0);
++	input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0);
++	input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0);
+ 
+ 	switch (wacom->features->type) {
+ 		case GRAPHIRE:
+-			wacom->dev.evbit[0] |= BIT(EV_REL);
+-			wacom->dev.relbit[0] |= BIT(REL_WHEEL);
+-			wacom->dev.absbit[0] |= BIT(ABS_DISTANCE);
+-			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+-			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
++			input_dev->evbit[0] |= BIT(EV_REL);
++			input_dev->relbit[0] |= BIT(REL_WHEEL);
++			input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
++			input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
++			input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
+ 			break;
+ 
+ 		case INTUOS3:
+ 		case CINTIQ:
+-			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
+-			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
+-			wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY);
++			input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
++			input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
++			input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
++			input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
+ 			/* fall through */
+ 
+ 		case INTUOS:
+-			wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
+-			wacom->dev.mscbit[0] |= BIT(MSC_SERIAL);
+-			wacom->dev.relbit[0] |= BIT(REL_WHEEL);
+-			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
+-			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE)	| BIT(BTN_TOOL_BRUSH)
++			input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
++			input_dev->mscbit[0] |= BIT(MSC_SERIAL);
++			input_dev->relbit[0] |= BIT(REL_WHEEL);
++			input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
++			input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE)	| BIT(BTN_TOOL_BRUSH)
+ 							  | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
+-			wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE);
++			input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
++			input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
++			input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
++			input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
++			input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
++			input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
+ 			break;
+ 
+ 		case PL:
+-			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
++			input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
+ 			break;
+ 	}
+ 
+-	wacom->dev.absmax[ABS_X] = wacom->features->x_max;
+-	wacom->dev.absmax[ABS_Y] = wacom->features->y_max;
+-	wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max;
+-	wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max;
+-	wacom->dev.absmax[ABS_TILT_X] = 127;
+-	wacom->dev.absmax[ABS_TILT_Y] = 127;
+-	wacom->dev.absmax[ABS_WHEEL] = 1023;
+-
+-	wacom->dev.absmax[ABS_RX] = 4097;
+-	wacom->dev.absmax[ABS_RY] = 4097;
+-	wacom->dev.absmin[ABS_RZ] = -900;
+-	wacom->dev.absmax[ABS_RZ] = 899;
+-	wacom->dev.absmin[ABS_THROTTLE] = -1023;
+-	wacom->dev.absmax[ABS_THROTTLE] = 1023;
+-
+-	wacom->dev.absfuzz[ABS_X] = 4;
+-	wacom->dev.absfuzz[ABS_Y] = 4;
+-
+-	wacom->dev.private = wacom;
+-	wacom->dev.open = wacom_open;
+-	wacom->dev.close = wacom_close;
+-
+-	usb_make_path(dev, path, 64);
+-	sprintf(wacom->phys, "%s/input0", path);
+-
+-	wacom->dev.name = wacom->features->name;
+-	wacom->dev.phys = wacom->phys;
+-	usb_to_input_id(dev, &wacom->dev.id);
+-	wacom->dev.dev = &intf->dev;
+-	wacom->usbdev = dev;
+-
+ 	endpoint = &intf->cur_altsetting->endpoint[0].desc;
+ 
+ 	if (wacom->features->pktlen > 10)
+@@ -839,18 +827,20 @@ static int wacom_probe(struct usb_interf
+ 	wacom->irq->transfer_dma = wacom->data_dma;
+ 	wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ 
+-	input_register_device(&wacom->dev);
++	input_register_device(wacom->dev);
+ 
+ 	/* ask the tablet to report tablet data */
+ 	usb_set_report(intf, 3, 2, rep_data, 2);
+ 	/* repeat once (not sure why the first call often fails) */
+ 	usb_set_report(intf, 3, 2, rep_data, 2);
+ 
+-	printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path);
+-
+ 	usb_set_intfdata(intf, wacom);
+-
+ 	return 0;
++
++fail2:	usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
++fail1:	input_free_device(input_dev);
++	kfree(wacom);
++	return -ENOMEM;
+ }
+ 
+ static void wacom_disconnect(struct usb_interface *intf)
+@@ -860,7 +850,7 @@ static void wacom_disconnect(struct usb_
+ 	usb_set_intfdata(intf, NULL);
+ 	if (wacom) {
+ 		usb_kill_urb(wacom->irq);
+-		input_unregister_device(&wacom->dev);
++		input_unregister_device(wacom->dev);
+ 		usb_free_urb(wacom->irq);
+ 		usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma);
+ 		kfree(wacom);
+diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
+--- a/drivers/usb/input/xpad.c
++++ b/drivers/usb/input/xpad.c
+@@ -103,7 +103,7 @@ static struct usb_device_id xpad_table [
+ MODULE_DEVICE_TABLE (usb, xpad_table);
+ 
+ struct usb_xpad {
+-	struct input_dev dev;			/* input device interface */
++	struct input_dev *dev;			/* input device interface */
+ 	struct usb_device *udev;		/* usb device */
+ 
+ 	struct urb *irq_in;			/* urb for interrupt in report */
+@@ -125,7 +125,7 @@ struct usb_xpad {
+ 
+ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs)
+ {
+-	struct input_dev *dev = &xpad->dev;
++	struct input_dev *dev = xpad->dev;
+ 
+ 	input_regs(dev, regs);
+ 
+@@ -214,9 +214,9 @@ static void xpad_close (struct input_dev
+ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
+ {
+ 	struct usb_device *udev = interface_to_usbdev (intf);
+-	struct usb_xpad *xpad = NULL;
++	struct usb_xpad *xpad;
++	struct input_dev *input_dev;
+ 	struct usb_endpoint_descriptor *ep_irq_in;
+-	char path[64];
+ 	int i;
+ 
+ 	for (i = 0; xpad_device[i].idVendor; i++) {
+@@ -225,89 +225,80 @@ static int xpad_probe(struct usb_interfa
+ 			break;
+ 	}
+ 
+-	if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) {
+-		err("cannot allocate memory for new pad");
+-		return -ENOMEM;
+-	}
+-	memset(xpad, 0, sizeof(struct usb_xpad));
++	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!xpad || !input_dev)
++		goto fail1;
+ 
+ 	xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
+ 				       SLAB_ATOMIC, &xpad->idata_dma);
+-	if (!xpad->idata) {
+-		kfree(xpad);
+-		return -ENOMEM;
+-	}
++	if (!xpad->idata)
++		goto fail1;
+ 
+ 	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
+-        if (!xpad->irq_in) {
+-		err("cannot allocate memory for new pad irq urb");
+-		usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
+-                kfree(xpad);
+-		return -ENOMEM;
+-        }
+-
+-	ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
+-
+-	usb_fill_int_urb(xpad->irq_in, udev,
+-			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
+-			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
+-			 xpad, ep_irq_in->bInterval);
+-	xpad->irq_in->transfer_dma = xpad->idata_dma;
+-	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++	if (!xpad->irq_in)
++		goto fail2;
+ 
+ 	xpad->udev = udev;
++	xpad->dev = input_dev;
++	usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
++	strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
++
++	input_dev->name = xpad_device[i].name;
++	input_dev->phys = xpad->phys;
++	usb_to_input_id(udev, &input_dev->id);
++	input_dev->cdev.dev = &intf->dev;
++	input_dev->private = xpad;
++	input_dev->open = xpad_open;
++	input_dev->close = xpad_close;
+ 
+-	usb_to_input_id(udev, &xpad->dev.id);
+-	xpad->dev.dev = &intf->dev;
+-	xpad->dev.private = xpad;
+-	xpad->dev.name = xpad_device[i].name;
+-	xpad->dev.phys = xpad->phys;
+-	xpad->dev.open = xpad_open;
+-	xpad->dev.close = xpad_close;
+-
+-	usb_make_path(udev, path, 64);
+-	snprintf(xpad->phys, 64,  "%s/input0", path);
+-
+-	xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ 
+ 	for (i = 0; xpad_btn[i] >= 0; i++)
+-		set_bit(xpad_btn[i], xpad->dev.keybit);
++		set_bit(xpad_btn[i], input_dev->keybit);
+ 
+ 	for (i = 0; xpad_abs[i] >= 0; i++) {
+ 
+ 		signed short t = xpad_abs[i];
+ 
+-		set_bit(t, xpad->dev.absbit);
++		set_bit(t, input_dev->absbit);
+ 
+ 		switch (t) {
+ 			case ABS_X:
+ 			case ABS_Y:
+ 			case ABS_RX:
+ 			case ABS_RY:	/* the two sticks */
+-				xpad->dev.absmax[t] =  32767;
+-				xpad->dev.absmin[t] = -32768;
+-				xpad->dev.absflat[t] = 128;
+-				xpad->dev.absfuzz[t] = 16;
++				input_set_abs_params(input_dev, t, -32768, 32767, 16, 128);
+ 				break;
+ 			case ABS_Z:
+ 			case ABS_RZ:	/* the triggers */
+-				xpad->dev.absmax[t] = 255;
+-				xpad->dev.absmin[t] = 0;
++				input_set_abs_params(input_dev, t, 0, 255, 0, 0);
+ 				break;
+ 			case ABS_HAT0X:
+ 			case ABS_HAT0Y:	/* the d-pad */
+-				xpad->dev.absmax[t] =  1;
+-				xpad->dev.absmin[t] = -1;
++				input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+ 				break;
+ 		}
+ 	}
+ 
+-	input_register_device(&xpad->dev);
++	ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
++	usb_fill_int_urb(xpad->irq_in, udev,
++			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
++			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
++			 xpad, ep_irq_in->bInterval);
++	xpad->irq_in->transfer_dma = xpad->idata_dma;
++	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ 
+-	printk(KERN_INFO "input: %s on %s", xpad->dev.name, path);
++	input_register_device(xpad->dev);
+ 
+ 	usb_set_intfdata(intf, xpad);
+ 	return 0;
++
++fail2:	usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
++fail1:	input_free_device(input_dev);
++	kfree(xpad);
++	return -ENOMEM;
++
+ }
+ 
+ static void xpad_disconnect(struct usb_interface *intf)
+@@ -317,7 +308,7 @@ static void xpad_disconnect(struct usb_i
+ 	usb_set_intfdata(intf, NULL);
+ 	if (xpad) {
+ 		usb_kill_urb(xpad->irq_in);
+-		input_unregister_device(&xpad->dev);
++		input_unregister_device(xpad->dev);
+ 		usb_free_urb(xpad->irq_in);
+ 		usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
+ 		kfree(xpad);
+diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
+--- a/drivers/usb/input/yealink.c
++++ b/drivers/usb/input/yealink.c
+@@ -54,6 +54,7 @@
+ #include <linux/module.h>
+ #include <linux/rwsem.h>
+ #include <linux/usb.h>
++#include <linux/usb_input.h>
+ 
+ #include "map_to_7segment.h"
+ #include "yealink.h"
+@@ -101,12 +102,12 @@ static const struct lcd_segment_map {
+ };
+ 
+ struct yealink_dev {
+-	struct input_dev idev;		/* input device */
++	struct input_dev *idev;		/* input device */
+ 	struct usb_device *udev;	/* usb device */
+ 
+ 	/* irq input channel */
+ 	struct yld_ctl_packet	*irq_data;
+-	dma_addr_t 		irq_dma;
++	dma_addr_t		irq_dma;
+ 	struct urb		*urb_irq;
+ 
+ 	/* control output channel */
+@@ -237,7 +238,7 @@ static int map_p1k_to_key(int scancode)
+  */
+ static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs)
+ {
+-	struct input_dev *idev = &yld->idev;
++	struct input_dev *idev = yld->idev;
+ 
+ 	input_regs(idev, regs);
+ 	if (yld->key_code >= 0) {
+@@ -809,8 +810,12 @@ static int usb_cleanup(struct yealink_de
+ 	}
+         if (yld->urb_ctl)
+ 		usb_free_urb(yld->urb_ctl);
+-        if (yld->idev.dev)
+-		input_unregister_device(&yld->idev);
++        if (yld->idev) {
++		if (err)
++			input_free_device(yld->idev);
++		else
++			input_unregister_device(yld->idev);
++	}
+ 	if (yld->ctl_req)
+ 		usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
+ 				yld->ctl_req, yld->ctl_req_dma);
+@@ -857,7 +862,7 @@ static int usb_probe(struct usb_interfac
+ 	struct usb_host_interface *interface;
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct yealink_dev *yld;
+-	char path[64];
++	struct input_dev *input_dev;
+ 	int ret, pipe, i;
+ 
+ 	i = usb_match(udev);
+@@ -866,17 +871,21 @@ static int usb_probe(struct usb_interfac
+ 
+ 	interface = intf->cur_altsetting;
+ 	endpoint = &interface->endpoint[0].desc;
+-	if (!(endpoint->bEndpointAddress & 0x80))
++	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
+ 		return -EIO;
+-	if ((endpoint->bmAttributes & 3) != 3)
++	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+ 		return -EIO;
+ 
+-	if ((yld = kmalloc(sizeof(struct yealink_dev), GFP_KERNEL)) == NULL)
++	yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL);
++	if (!yld)
+ 		return -ENOMEM;
+ 
+-	memset(yld, 0, sizeof(*yld));
+ 	yld->udev = udev;
+ 
++	yld->idev = input_dev = input_allocate_device();
++	if (!input_dev)
++		return usb_cleanup(yld, -ENOMEM);
++
+ 	/* allocate usb buffers */
+ 	yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
+ 					SLAB_ATOMIC, &yld->irq_dma);
+@@ -935,42 +944,37 @@ static int usb_probe(struct usb_interfac
+ 	yld->urb_ctl->dev = udev;
+ 
+ 	/* find out the physical bus location */
+-	if (usb_make_path(udev, path, sizeof(path)) > 0)
+-		snprintf(yld->phys, sizeof(yld->phys)-1,  "%s/input0", path);
++	usb_make_path(udev, yld->phys, sizeof(yld->phys));
++	strlcat(yld->phys,  "/input0", sizeof(yld->phys));
+ 
+ 	/* register settings for the input device */
+-	init_input_dev(&yld->idev);
+-	yld->idev.private	= yld;
+-	yld->idev.id.bustype	= BUS_USB;
+-	yld->idev.id.vendor	= le16_to_cpu(udev->descriptor.idVendor);
+-	yld->idev.id.product	= le16_to_cpu(udev->descriptor.idProduct);
+-	yld->idev.id.version	= le16_to_cpu(udev->descriptor.bcdDevice);
+-	yld->idev.dev		= &intf->dev;
+-	yld->idev.name		= yld_device[i].name;
+-	yld->idev.phys		= yld->phys;
+-	/* yld->idev.event		= input_ev;	TODO */
+-	yld->idev.open		= input_open;
+-	yld->idev.close		= input_close;
++	input_dev->name = yld_device[i].name;
++	input_dev->phys = yld->phys;
++	usb_to_input_id(udev, &input_dev->id);
++	input_dev->cdev.dev = &intf->dev;
++
++	input_dev->private = yld;
++	input_dev->open = input_open;
++	input_dev->close = input_close;
++	/* input_dev->event = input_ev;	TODO */
+ 
+ 	/* register available key events */
+-	yld->idev.evbit[0] = BIT(EV_KEY);
++	input_dev->evbit[0] = BIT(EV_KEY);
+ 	for (i = 0; i < 256; i++) {
+ 		int k = map_p1k_to_key(i);
+ 		if (k >= 0) {
+-			set_bit(k & 0xff, yld->idev.keybit);
++			set_bit(k & 0xff, input_dev->keybit);
+ 			if (k >> 8)
+-				set_bit(k >> 8, yld->idev.keybit);
++				set_bit(k >> 8, input_dev->keybit);
+ 		}
+ 	}
+ 
+-	printk(KERN_INFO "input: %s on %s\n", yld->idev.name, path);
+-
+-	input_register_device(&yld->idev);
++	input_register_device(yld->idev);
+ 
+ 	usb_set_intfdata(intf, yld);
+ 
+ 	/* clear visible elements */
+-	for (i=0; i<ARRAY_SIZE(lcdMap); i++)
++	for (i = 0; i < ARRAY_SIZE(lcdMap); i++)
+ 		setChar(yld, i, ' ');
+ 
+ 	/* display driver version on LCD line 3 */
+diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
+--- a/drivers/usb/media/konicawc.c
++++ b/drivers/usb/media/konicawc.c
+@@ -119,7 +119,7 @@ struct konicawc {
+ 	int yplanesz;		/* Number of bytes in the Y plane */
+ 	unsigned int buttonsts:1;
+ #ifdef CONFIG_INPUT
+-	struct input_dev input;
++	struct input_dev *input;
+ 	char input_physname[64];
+ #endif
+ };
+@@ -218,6 +218,57 @@ static void konicawc_adjust_picture(stru
+ 	konicawc_camera_on(uvd);
+ }
+ 
++#ifdef CONFIG_INPUT
++
++static void konicawc_register_input(struct konicawc *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("Not enough memory for camera's input device\n");
++		return;
++	}
++
++	input_dev->name = "Konicawc snapshot 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 konicawc_unregister_input(struct konicawc *cam)
++{
++	if (cam->input) {
++		input_unregister_device(cam->input);
++		cam->input = NULL;
++	}
++}
++
++static void konicawc_report_buttonstat(struct konicawc *cam)
++{
++	if (cam->input) {
++		input_report_key(cam->input, BTN_0, cam->buttonsts);
++		input_sync(cam->input);
++	}
++}
++
++#else
++
++static inline void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) { }
++static inline void konicawc_unregister_input(struct konicawc *cam) { }
++static inline void konicawc_report_buttonstat(struct konicawc *cam) { }
++
++#endif /* CONFIG_INPUT */
+ 
+ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct urb *stsurb)
+ {
+@@ -273,10 +324,7 @@ static int konicawc_compress_iso(struct 
+ 		if(button != cam->buttonsts) {
+ 			DEBUG(2, "button: %sclicked", button ? "" : "un");
+ 			cam->buttonsts = button;
+-#ifdef CONFIG_INPUT
+-			input_report_key(&cam->input, BTN_0, cam->buttonsts);
+-			input_sync(&cam->input);
+-#endif
++			konicawc_report_buttonstat(cam);
+ 		}
+ 
+ 		if(sts == 0x01) { /* drop frame */
+@@ -645,9 +693,9 @@ static int konicawc_set_video_mode(struc
+ 	RingQueue_Flush(&uvd->dp);
+ 	cam->lastframe = -2;
+ 	if(uvd->curframe != -1) {
+-	  uvd->frame[uvd->curframe].curline = 0;
+-	  uvd->frame[uvd->curframe].seqRead_Length = 0;
+-	  uvd->frame[uvd->curframe].seqRead_Index = 0;
++		uvd->frame[uvd->curframe].curline = 0;
++		uvd->frame[uvd->curframe].seqRead_Length = 0;
++		uvd->frame[uvd->curframe].seqRead_Index = 0;
+ 	}
+ 
+ 	konicawc_start_data(uvd);
+@@ -718,7 +766,6 @@ static void konicawc_configure_video(str
+ 	DEBUG(1, "setting initial values");
+ }
+ 
+-
+ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid)
+ {
+ 	struct usb_device *dev = interface_to_usbdev(intf);
+@@ -839,21 +886,8 @@ static int konicawc_probe(struct usb_int
+ 			err("usbvideo_RegisterVideoDevice() failed.");
+ 			uvd = NULL;
+ 		}
+-#ifdef CONFIG_INPUT
+-		/* Register input device for button */
+-		memset(&cam->input, 0, sizeof(struct input_dev));
+-		cam->input.name = "Konicawc snapshot button";
+-		cam->input.private = cam;
+-		cam->input.evbit[0] = BIT(EV_KEY);
+-		cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
+-		usb_to_input_id(dev, &cam->input.id);
+-		input_register_device(&cam->input);
+-		
+-		usb_make_path(dev, cam->input_physname, 56);
+-		strcat(cam->input_physname, "/input0");
+-		cam->input.phys = cam->input_physname;
+-		info("konicawc: %s on %s\n", cam->input.name, cam->input.phys);
+-#endif
++
++		konicawc_register_input(cam, dev);
+ 	}
+ 
+ 	if (uvd) {
+@@ -869,10 +903,9 @@ static void konicawc_free_uvd(struct uvd
+ 	int i;
+ 	struct konicawc *cam = (struct konicawc *)uvd->user_data;
+ 
+-#ifdef CONFIG_INPUT
+-	input_unregister_device(&cam->input);
+-#endif
+-	for (i=0; i < USBVIDEO_NUMSBUF; i++) {
++	konicawc_unregister_input(cam);
++
++	for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
+ 		usb_free_urb(cam->sts_urb[i]);
+ 		cam->sts_urb[i] = NULL;
+ 	}
+diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
+--- a/drivers/usb/misc/auerswald.c
++++ b/drivers/usb/misc/auerswald.c
+@@ -1873,9 +1873,8 @@ static struct file_operations auerswald_
+ };
+ 
+ static struct usb_class_driver auerswald_class = {
+-	.name =		"usb/auer%d",
++	.name =		"auer%d",
+ 	.fops =		&auerswald_fops,
+-	.mode =		S_IFCHR | S_IRUGO | S_IWUGO,
+ 	.minor_base =	AUER_MINOR_BASE,
+ };
+ 
+diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
+--- a/drivers/usb/misc/idmouse.c
++++ b/drivers/usb/misc/idmouse.c
+@@ -105,11 +105,10 @@ static struct file_operations idmouse_fo
+ 	.release = idmouse_release,
+ };
+ 
+-/* class driver information for devfs */
++/* class driver information */
+ static struct usb_class_driver idmouse_class = {
+-	.name = "usb/idmouse%d",
++	.name = "idmouse%d",
+ 	.fops = &idmouse_fops,
+-	.mode = S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, /* filemode (char, 444) */
+ 	.minor_base = USB_IDMOUSE_MINOR_BASE,
+ };
+ 
+@@ -320,20 +319,8 @@ static ssize_t idmouse_read(struct file 
+ 		return -ENODEV;
+ 	}
+ 
+-	if (*ppos >= IMGSIZE) {
+-		up (&dev->sem);
+-		return 0;
+-	}
+-
+-	count = min ((loff_t)count, IMGSIZE - (*ppos));
+-
+-	if (copy_to_user (buffer, dev->bulk_in_buffer + *ppos, count)) {
+-		result = -EFAULT;
+-	} else {
+-		result = count;
+-		*ppos += count;
+-	}
+-
++	result = simple_read_from_buffer(buffer, count, ppos,
++					dev->bulk_in_buffer, IMGSIZE);
+ 	/* unlock the device */
+ 	up(&dev->sem);
+ 	return result;
+diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -271,12 +271,11 @@ static struct file_operations tower_fops
+ 
+ /*
+  * usb class driver info in order to get a minor number from the usb core,
+- * and to have the device registered with devfs and the driver core
++ * and to have the device registered with the driver core
+  */
+ static struct usb_class_driver tower_class = {
+-	.name =		"usb/legousbtower%d",
++	.name =		"legousbtower%d",
+ 	.fops =		&tower_fops,
+-	.mode =		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
+ 	.minor_base =	LEGO_USB_TOWER_MINOR_BASE,
+ };
+ 
+diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
+--- a/drivers/usb/misc/rio500.c
++++ b/drivers/usb/misc/rio500.c
+@@ -443,9 +443,8 @@ file_operations usb_rio_fops = {
+ };
+ 
+ static struct usb_class_driver usb_rio_class = {
+-	.name =		"usb/rio500%d",
++	.name =		"rio500%d",
+ 	.fops =		&usb_rio_fops,
+-	.mode =		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ 	.minor_base =	RIO_MINOR,
+ };
+ 
+diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
+--- a/drivers/usb/misc/sisusbvga/sisusb.c
++++ b/drivers/usb/misc/sisusbvga/sisusb.c
+@@ -2440,7 +2440,7 @@ int
+ sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init)
+ {
+ 	int ret = 0, slot = sisusb->font_slot, i;
+-	struct font_desc *myfont;
++	const struct font_desc *myfont;
+ 	u8 *tempbuf;
+ 	u16 *tempbufb;
+ 	size_t written;
+@@ -3239,12 +3239,7 @@ static struct file_operations usb_sisusb
+ };
+ 
+ static struct usb_class_driver usb_sisusb_class = {
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
+-	.name =		"usb/sisusbvga%d",
+-	.mode =		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+-#else
+ 	.name =		"sisusbvga%d",
+-#endif
+ 	.fops =		&usb_sisusb_fops,
+ 	.minor_base =	SISUSB_MINOR
+ };
+diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
+--- a/drivers/usb/misc/usblcd.c
++++ b/drivers/usb/misc/usblcd.c
+@@ -251,13 +251,12 @@ static struct file_operations lcd_fops =
+ };
+ 
+ /*
+- *  * usb class driver info in order to get a minor number from the usb core,
+- *   * and to have the device registered with devfs and the driver core
+- *    */
++ * usb class driver info in order to get a minor number from the usb core,
++ * and to have the device registered with the driver core
++ */
+ static struct usb_class_driver lcd_class = {
+-        .name =         "usb/lcd%d",
++        .name =         "lcd%d",
+         .fops =         &lcd_fops,
+-        .mode =         S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
+         .minor_base =   USBLCD_MINOR,
+ };
+ 
+diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
+--- a/drivers/usb/misc/usbtest.c
++++ b/drivers/usb/misc/usbtest.c
+@@ -9,7 +9,7 @@
+ #include <linux/mm.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+-#include <asm/scatterlist.h>
++#include <linux/scatterlist.h>
+ 
+ #include <linux/usb.h>
+ 
+@@ -381,7 +381,6 @@ alloc_sglist (int nents, int max, int va
+ 	sg = kmalloc (nents * sizeof *sg, SLAB_KERNEL);
+ 	if (!sg)
+ 		return NULL;
+-	memset (sg, 0, nents * sizeof *sg);
+ 
+ 	for (i = 0; i < nents; i++) {
+ 		char		*buf;
+@@ -394,9 +393,7 @@ alloc_sglist (int nents, int max, int va
+ 		memset (buf, 0, size);
+ 
+ 		/* kmalloc pages are always physically contiguous! */
+-		sg [i].page = virt_to_page (buf);
+-		sg [i].offset = offset_in_page (buf);
+-		sg [i].length = size;
++		sg_init_one(&sg[i], buf, size);
+ 
+ 		if (vary) {
+ 			size += vary;
+@@ -983,6 +980,7 @@ test_ctrl_queue (struct usbtest_dev *dev
+ 		reqp->number = i % NUM_SUBCASES;
+ 		reqp->expected = expected;
+ 		u->setup_packet = (char *) &reqp->setup;
++		u->transfer_flags |= URB_NO_SETUP_DMA_MAP;
+ 
+ 		u->context = &context;
+ 		u->complete = ctrl_complete;
+@@ -1948,21 +1946,11 @@ usbtest_probe (struct usb_interface *int
+ 
+ static int usbtest_suspend (struct usb_interface *intf, pm_message_t message)
+ {
+-	struct usbtest_dev	*dev = usb_get_intfdata (intf);
+-
+-	down (&dev->sem);
+-	intf->dev.power.power_state = PMSG_SUSPEND;
+-	up (&dev->sem);
+ 	return 0;
+ }
+ 
+ static int usbtest_resume (struct usb_interface *intf)
+ {
+-	struct usbtest_dev	*dev = usb_get_intfdata (intf);
+-
+-	down (&dev->sem);
+-	intf->dev.power.power_state = PMSG_ON;
+-	up (&dev->sem);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
+--- a/drivers/usb/misc/uss720.c
++++ b/drivers/usb/misc/uss720.c
+@@ -137,7 +137,7 @@ static void async_complete(struct urb *u
+ 
+ static struct uss720_async_request *submit_async_request(struct parport_uss720_private *priv,
+ 							 __u8 request, __u8 requesttype, __u16 value, __u16 index,
+-							 unsigned int mem_flags)
++							 gfp_t mem_flags)
+ {
+ 	struct usb_device *usbdev;
+ 	struct uss720_async_request *rq;
+@@ -204,7 +204,7 @@ static unsigned int kill_all_async_reque
+ 
+ /* --------------------------------------------------------------------- */
+ 
+-static int get_1284_register(struct parport *pp, unsigned char reg, unsigned char *val, unsigned int mem_flags)
++static int get_1284_register(struct parport *pp, unsigned char reg, unsigned char *val, gfp_t mem_flags)
+ {
+ 	struct parport_uss720_private *priv;
+ 	struct uss720_async_request *rq;
+@@ -238,7 +238,7 @@ static int get_1284_register(struct parp
+ 	return -EIO;
+ }
+ 
+-static int set_1284_register(struct parport *pp, unsigned char reg, unsigned char val, unsigned int mem_flags)
++static int set_1284_register(struct parport *pp, unsigned char reg, unsigned char val, gfp_t mem_flags)
+ {
+ 	struct parport_uss720_private *priv;
+ 	struct uss720_async_request *rq;
+diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
+--- a/drivers/usb/mon/mon_main.c
++++ b/drivers/usb/mon/mon_main.c
+@@ -11,6 +11,7 @@
+ #include <linux/usb.h>
+ #include <linux/debugfs.h>
+ #include <linux/smp_lock.h>
++#include <linux/notifier.h>
+ 
+ #include "usb_mon.h"
+ #include "../core/hcd.h"
+@@ -205,6 +206,23 @@ static void mon_bus_remove(struct usb_bu
+ 	up(&mon_lock);
+ }
+ 
++static int mon_notify(struct notifier_block *self, unsigned long action,
++		      void *dev)
++{
++	switch (action) {
++	case USB_BUS_ADD:
++		mon_bus_add(dev);
++		break;
++	case USB_BUS_REMOVE:
++		mon_bus_remove(dev);
++	}
++	return NOTIFY_OK;
++}
++
++static struct notifier_block mon_nb = {
++	.notifier_call = 	mon_notify,
++};
++
+ /*
+  * Ops
+  */
+@@ -212,8 +230,6 @@ static struct usb_mon_operations mon_ops
+ 	.urb_submit =	mon_submit,
+ 	.urb_submit_error = mon_submit_error,
+ 	.urb_complete =	mon_complete,
+-	.bus_add =	mon_bus_add,
+-	.bus_remove =	mon_bus_remove,
+ };
+ 
+ /*
+@@ -329,6 +345,8 @@ static int __init mon_init(void)
+ 	}
+ 	// MOD_INC_USE_COUNT(which_module?);
+ 
++	usb_register_notify(&mon_nb);
++
+ 	down(&usb_bus_list_lock);
+ 	list_for_each_entry (ubus, &usb_bus_list, bus_list) {
+ 		mon_bus_init(mondir, ubus);
+@@ -342,6 +360,7 @@ static void __exit mon_exit(void)
+ 	struct mon_bus *mbus;
+ 	struct list_head *p;
+ 
++	usb_unregister_notify(&mon_nb);
+ 	usb_mon_deregister();
+ 
+ 	down(&mon_lock);
+diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
+--- a/drivers/usb/net/Kconfig
++++ b/drivers/usb/net/Kconfig
+@@ -294,7 +294,7 @@ config USB_NET_ZAURUS
+ 	  This also supports some related device firmware, as used in some
+ 	  PDAs from Olympus and some cell phones from Motorola.
+ 
+-	  If you install an alternate ROM image, such as the Linux 2.6 based
++	  If you install an alternate image, such as the Linux 2.6 based
+ 	  versions of OpenZaurus, you should no longer need to support this
+ 	  protocol.  Only the "eth-fd" or "net_fd" drivers in these devices
+ 	  really need this non-conformant variant of CDC Ethernet (or in
+diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
+--- a/drivers/usb/net/asix.c
++++ b/drivers/usb/net/asix.c
+@@ -753,7 +753,7 @@ static int ax88772_rx_fixup(struct usbne
+ }
+ 
+ static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+-					unsigned flags)
++					gfp_t flags)
+ {
+ 	int padlen;
+ 	int headroom = skb_headroom(skb);
+diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
+--- a/drivers/usb/net/gl620a.c
++++ b/drivers/usb/net/gl620a.c
+@@ -301,7 +301,7 @@ static int genelink_rx_fixup(struct usbn
+ }
+ 
+ static struct sk_buff *
+-genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
++genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+ {
+ 	int 	padlen;
+ 	int	length = skb->len;
+diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
+--- a/drivers/usb/net/kaweth.c
++++ b/drivers/usb/net/kaweth.c
+@@ -469,7 +469,7 @@ static int kaweth_reset(struct kaweth_de
+ 				0,
+ 				KAWETH_CONTROL_TIMEOUT);
+ 
+-	udelay(10000);
++	mdelay(10);
+ 
+ 	kaweth_dbg("kaweth_reset() returns %d.",result);
+ 
+@@ -477,13 +477,13 @@ static int kaweth_reset(struct kaweth_de
+ }
+ 
+ static void kaweth_usb_receive(struct urb *, struct pt_regs *regs);
+-static int kaweth_resubmit_rx_urb(struct kaweth_device *, unsigned);
++static int kaweth_resubmit_rx_urb(struct kaweth_device *, gfp_t);
+ 
+ /****************************************************************
+ 	int_callback
+ *****************************************************************/
+ 
+-static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, int mf)
++static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf)
+ {
+ 	int status;
+ 
+@@ -550,7 +550,7 @@ static void kaweth_resubmit_tl(void *d)
+  *     kaweth_resubmit_rx_urb
+  ****************************************************************/
+ static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
+-						unsigned mem_flags)
++						gfp_t mem_flags)
+ {
+ 	int result;
+ 
+diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c
+--- a/drivers/usb/net/net1080.c
++++ b/drivers/usb/net/net1080.c
+@@ -500,7 +500,7 @@ static int net1080_rx_fixup(struct usbne
+ }
+ 
+ static struct sk_buff *
+-net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
++net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+ {
+ 	int			padlen;
+ 	struct sk_buff		*skb2;
+diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
+--- a/drivers/usb/net/pegasus.c
++++ b/drivers/usb/net/pegasus.c
+@@ -1384,7 +1384,6 @@ static int pegasus_suspend (struct usb_i
+ 		usb_kill_urb(pegasus->rx_urb);
+ 		usb_kill_urb(pegasus->intr_urb);
+ 	}
+-	intf->dev.power.power_state = PMSG_SUSPEND;
+ 	return 0;
+ }
+ 
+@@ -1392,7 +1391,6 @@ static int pegasus_resume (struct usb_in
+ {
+ 	struct pegasus *pegasus = usb_get_intfdata(intf);
+ 
+-	intf->dev.power.power_state = PMSG_ON;
+ 	netif_device_attach (pegasus->net);
+ 	if (netif_running(pegasus->net)) {
+ 		pegasus->rx_urb->status = 0;
+diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
+--- a/drivers/usb/net/pegasus.h
++++ b/drivers/usb/net/pegasus.h
+@@ -181,6 +181,8 @@ PEGASUS_DEV( "Accton USB 10/100 Ethernet
+ 		DEFAULT_GPIO_RESET )
+ PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
+ 		DEFAULT_GPIO_RESET | PEGASUS_II )
++PEGASUS_DEV( "Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004,
++		DEFAULT_GPIO_RESET | PEGASUS_II )
+ PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
+ 		VENDOR_ADMTEK, 0x8511,
+ 		DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
+diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
+--- a/drivers/usb/net/rndis_host.c
++++ b/drivers/usb/net/rndis_host.c
+@@ -517,7 +517,7 @@ static int rndis_rx_fixup(struct usbnet 
+ }
+ 
+ static struct sk_buff *
+-rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
++rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+ {
+ 	struct rndis_data_hdr	*hdr;
+ 	struct sk_buff		*skb2;
+diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
+--- a/drivers/usb/net/rtl8150.c
++++ b/drivers/usb/net/rtl8150.c
+@@ -909,6 +909,7 @@ static void rtl8150_disconnect(struct us
+ 	usb_set_intfdata(intf, NULL);
+ 	if (dev) {
+ 		set_bit(RTL8150_UNPLUG, &dev->flags);
++		tasklet_disable(&dev->tl);
+ 		unregister_netdev(dev->netdev);
+ 		unlink_all_urbs(dev);
+ 		free_all_urbs(dev);
+diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
+--- a/drivers/usb/net/usbnet.c
++++ b/drivers/usb/net/usbnet.c
+@@ -288,7 +288,7 @@ EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
+ 
+ static void rx_complete (struct urb *urb, struct pt_regs *regs);
+ 
+-static void rx_submit (struct usbnet *dev, struct urb *urb, unsigned flags)
++static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
+ {
+ 	struct sk_buff		*skb;
+ 	struct skb_data		*entry;
+@@ -1185,7 +1185,6 @@ int usbnet_suspend (struct usb_interface
+ 	netif_device_detach (dev->net);
+ 	(void) unlink_urbs (dev, &dev->rxq);
+ 	(void) unlink_urbs (dev, &dev->txq);
+-	intf->dev.power.power_state = PMSG_SUSPEND;
+ 	return 0;
+ }
+ EXPORT_SYMBOL_GPL(usbnet_suspend);
+@@ -1194,7 +1193,6 @@ int usbnet_resume (struct usb_interface 
+ {
+ 	struct usbnet		*dev = usb_get_intfdata(intf);
+ 
+-	intf->dev.power.power_state = PMSG_ON;
+ 	netif_device_attach (dev->net);
+ 	tasklet_schedule (&dev->bh);
+ 	return 0;
+diff --git a/drivers/usb/net/usbnet.h b/drivers/usb/net/usbnet.h
+--- a/drivers/usb/net/usbnet.h
++++ b/drivers/usb/net/usbnet.h
+@@ -107,7 +107,7 @@ struct driver_info {
+ 
+ 	/* fixup tx packet (add framing) */
+ 	struct sk_buff	*(*tx_fixup)(struct usbnet *dev,
+-				struct sk_buff *skb, unsigned flags);
++				struct sk_buff *skb, gfp_t flags);
+ 
+ 	/* for new devices, use the descriptor-reading code instead */
+ 	int		in;		/* rx endpoint */
+diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c
+--- a/drivers/usb/net/zaurus.c
++++ b/drivers/usb/net/zaurus.c
+@@ -62,7 +62,7 @@
+  */
+ 
+ static struct sk_buff *
+-zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
++zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+ {
+ 	int			padlen;
+ 	struct sk_buff		*skb2;
+diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
+--- a/drivers/usb/net/zd1201.c
++++ b/drivers/usb/net/zd1201.c
+@@ -521,7 +521,7 @@ static int zd1201_setconfig(struct zd120
+ 	int reqlen;
+ 	char seq=0;
+ 	struct urb *urb;
+-	unsigned int gfp_mask = wait ? GFP_NOIO : GFP_ATOMIC;
++	gfp_t gfp_mask = wait ? GFP_NOIO : GFP_ATOMIC;
+ 
+ 	len += 4;			/* first 4 are for header */
+ 
+diff --git a/drivers/usb/serial/ChangeLog.old b/drivers/usb/serial/ChangeLog.old
+new file mode 100644
+--- /dev/null
++++ b/drivers/usb/serial/ChangeLog.old
+@@ -0,0 +1,730 @@
++This is the contents of some of the drivers/usb/serial/ files that had  old
++changelog comments.  They were quite old, and out of date, and we don't keep
++them anymore, so I've put them here, away from the source files, in case
++people still care to see them.
++
++- Greg Kroah-Hartman <greg at kroah.com> October 20, 2005
++
++-----------------------------------------------------------------------
++usb-serial.h Change Log comments:
++
++ (03/26/2002) gkh
++	removed the port->tty check from port_paranoia_check() due to serial
++	consoles not having a tty device assigned to them.
++
++ (12/03/2001) gkh
++	removed active from the port structure.
++	added documentation to the usb_serial_device_type structure
++
++ (10/10/2001) gkh
++	added vendor and product to serial structure.  Needed to determine device
++	owner when the device is disconnected.
++
++ (05/30/2001) gkh
++	added sem to port structure and removed port_lock
++
++ (10/05/2000) gkh
++	Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help
++	fix bug with urb->dev not being set properly, now that the usb core
++	needs it.
++
++ (09/11/2000) gkh
++	Added usb_serial_debug_data function to help get rid of #DEBUG in the
++	drivers.
++
++ (08/28/2000) gkh
++	Added port_lock to port structure.
++
++ (08/08/2000) gkh
++	Added open_count to port structure.
++
++ (07/23/2000) gkh
++	Added bulk_out_endpointAddress to port structure.
++
++ (07/19/2000) gkh, pberger, and borchers
++	Modifications to allow usb-serial drivers to be modules.
++
++-----------------------------------------------------------------------
++usb-serial.c Change Log comments:
++
++ (12/10/2002) gkh
++	Split the ports off into their own struct device, and added a
++	usb-serial bus driver.
++
++ (11/19/2002) gkh
++	removed a few #ifdefs for the generic code and cleaned up the failure
++	logic in initialization.
++
++ (10/02/2002) gkh
++	moved the console code to console.c and out of this file.
++
++ (06/05/2002) gkh
++	moved location of startup() call in serial_probe() until after all
++	of the port information and endpoints are initialized.  This makes
++	things easier for some drivers.
++
++ (04/10/2002) gkh
++	added serial_read_proc function which creates a
++	/proc/tty/driver/usb-serial file.
++
++ (03/27/2002) gkh
++	Got USB serial console code working properly and merged into the main
++	version of the tree.  Thanks to Randy Dunlap for the initial version
++	of this code, and for pushing me to finish it up.
++	The USB serial console works with any usb serial driver device.
++
++ (03/21/2002) gkh
++	Moved all manipulation of port->open_count into the core.  Now the
++	individual driver's open and close functions are called only when the
++	first open() and last close() is called.  Making the drivers a bit
++	smaller and simpler.
++	Fixed a bug if a driver didn't have the owner field set.
++
++ (02/26/2002) gkh
++	Moved all locking into the main serial_* functions, instead of having
++	the individual drivers have to grab the port semaphore.  This should
++	reduce races.
++	Reworked the MOD_INC logic a bit to always increment and decrement, even
++	if the generic driver is being used.
++
++ (10/10/2001) gkh
++	usb_serial_disconnect() now sets the serial->dev pointer is to NULL to
++	help prevent child drivers from accessing the device since it is now
++	gone.
++
++ (09/13/2001) gkh
++	Moved generic driver initialize after we have registered with the USB
++	core.  Thanks to Randy Dunlap for pointing this problem out.
++
++ (07/03/2001) gkh
++	Fixed module paramater size.  Thanks to John Brockmeyer for the pointer.
++	Fixed vendor and product getting defined through the MODULE_PARM macro
++	if the Generic driver wasn't compiled in.
++	Fixed problem with generic_shutdown() not being called for drivers that
++	don't have a shutdown() function.
++
++ (06/06/2001) gkh
++	added evil hack that is needed for the prolific pl2303 device due to the
++	crazy way its endpoints are set up.
++
++ (05/30/2001) gkh
++	switched from using spinlock to a semaphore, which fixes lots of problems.
++
++ (04/08/2001) gb
++	Identify version on module load.
++
++ 2001_02_05 gkh
++	Fixed buffer overflows bug with the generic serial driver.  Thanks to
++	Todd Squires <squirest at ct0.com> for fixing this.
++
++ (01/10/2001) gkh
++	Fixed bug where the generic serial adaptor grabbed _any_ device that was
++	offered to it.
++
++ (12/12/2000) gkh
++	Removed MOD_INC and MOD_DEC from poll and disconnect functions, and
++	moved them to the serial_open and serial_close functions.
++	Also fixed bug with there not being a MOD_DEC for the generic driver
++	(thanks to Gary Brubaker for finding this.)
++
++ (11/29/2000) gkh
++	Small NULL pointer initialization cleanup which saves a bit of disk image
++
++ (11/01/2000) Adam J. Richter
++	instead of using idVendor/idProduct pairs, usb serial drivers
++	now identify their hardware interest with usb_device_id tables,
++	which they usually have anyhow for use with MODULE_DEVICE_TABLE.
++
++ (10/05/2000) gkh
++	Fixed bug with urb->dev not being set properly, now that the usb
++	core needs it.
++
++ (09/11/2000) gkh
++	Removed DEBUG #ifdefs with call to usb_serial_debug_data
++
++ (08/28/2000) gkh
++	Added port_lock to port structure.
++	Added locks for SMP safeness to generic driver
++	Fixed the ability to open a generic device's port more than once.
++
++ (07/23/2000) gkh
++	Added bulk_out_endpointAddress to port structure.
++
++ (07/19/2000) gkh, pberger, and borchers
++	Modifications to allow usb-serial drivers to be modules.
++
++ (07/03/2000) gkh
++	Added more debugging to serial_ioctl call
++
++ (06/25/2000) gkh
++	Changed generic_write_bulk_callback to not call wake_up_interruptible
++	directly, but to have port_softint do it at a safer time.
++
++ (06/23/2000) gkh
++	Cleaned up debugging statements in a quest to find UHCI timeout bug.
++
++ (05/22/2000) gkh
++	Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be
++	removed from the individual device source files.
++
++ (05/03/2000) gkh
++	Added the Digi Acceleport driver from Al Borchers and Peter Berger.
++
++ (05/02/2000) gkh
++	Changed devfs and tty register code to work properly now. This was based on
++	the ACM driver changes by Vojtech Pavlik.
++
++ (04/27/2000) Ryan VanderBijl
++ 	Put calls to *_paranoia_checks into one function.
++
++ (04/23/2000) gkh
++	Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports.
++	Moved when the startup code printed out the devices that are supported.
++
++ (04/19/2000) gkh
++	Added driver for ZyXEL omni.net lcd plus ISDN TA
++	Made startup info message specify which drivers were compiled in.
++
++ (04/03/2000) gkh
++	Changed the probe process to remove the module unload races.
++	Changed where the tty layer gets initialized to have devfs work nicer.
++	Added initial devfs support.
++
++ (03/26/2000) gkh
++	Split driver up into device specific pieces.
++
++ (03/19/2000) gkh
++	Fixed oops that could happen when device was removed while a program
++	was talking to the device.
++	Removed the static urbs and now all urbs are created and destroyed
++	dynamically.
++	Reworked the internal interface. Now everything is based on the
++	usb_serial_port structure instead of the larger usb_serial structure.
++	This fixes the bug that a multiport device could not have more than
++	one port open at one time.
++
++ (03/17/2000) gkh
++	Added config option for debugging messages.
++	Added patch for keyspan pda from Brian Warner.
++
++ (03/06/2000) gkh
++	Added the keyspan pda code from Brian Warner <warner at lothar.com>
++	Moved a bunch of the port specific stuff into its own structure. This
++	is in anticipation of the true multiport devices (there's a bug if you
++	try to access more than one port of any multiport device right now)
++
++ (02/21/2000) gkh
++	Made it so that any serial devices only have to specify which functions
++	they want to overload from the generic function calls (great,
++	inheritance in C, in a driver, just what I wanted...)
++	Added support for set_termios and ioctl function calls. No drivers take
++	advantage of this yet.
++	Removed the #ifdef MODULE, now there is no module specific code.
++	Cleaned up a few comments in usb-serial.h that were wrong (thanks again
++	to Miles Lott).
++	Small fix to get_free_serial.
++
++ (02/14/2000) gkh
++	Removed the Belkin and Peracom functionality from the driver due to
++	the lack of support from the vendor, and me not wanting people to
++	accidenatly buy the device, expecting it to work with Linux.
++	Added read_bulk_callback and write_bulk_callback to the type structure
++	for the needs of the FTDI and WhiteHEAT driver.
++	Changed all reverences to FTDI to FTDI_SIO at the request of Bill
++	Ryder.
++	Changed the output urb size back to the max endpoint size to make
++	the ftdi_sio driver have it easier, and due to the fact that it didn't
++	really increase the speed any.
++
++ (02/11/2000) gkh
++	Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a
++	patch from Miles Lott (milos at insync.net).
++	Fixed bug with not restoring the minor range that a device grabs, if
++	the startup function fails (thanks Miles for finding this).
++
++ (02/05/2000) gkh
++	Added initial framework for the Keyspan PDA serial converter so that
++	Brian Warner has a place to put his code.
++	Made the ezusb specific functions generic enough that different
++	devices can use them (whiteheat and keyspan_pda both need them).
++	Split out a whole bunch of structure and other stuff to a separate
++	usb-serial.h file.
++	Made the Visor connection messages a little more understandable, now
++	that Miles Lott (milos at insync.net) has gotten the Generic channel to
++	work. Also made them always show up in the log file.
++
++ (01/25/2000) gkh
++	Added initial framework for FTDI serial converter so that Bill Ryder
++	has a place to put his code.
++	Added the vendor specific info from Handspring. Now we can print out
++	informational debug messages as well as understand what is happening.
++
++ (01/23/2000) gkh
++	Fixed problem of crash when trying to open a port that didn't have a
++	device assigned to it. Made the minor node finding a little smarter,
++	now it looks to find a continuous space for the new device.
++
++ (01/21/2000) gkh
++	Fixed bug in visor_startup with patch from Miles Lott (milos at insync.net)
++	Fixed get_serial_by_minor which was all messed up for multi port
++	devices. Fixed multi port problem for generic devices. Now the number
++	of ports is determined by the number of bulk out endpoints for the
++	generic device.
++
++ (01/19/2000) gkh
++	Removed lots of cruft that was around from the old (pre urb) driver
++	interface.
++	Made the serial_table dynamic. This should save lots of memory when
++	the number of minor nodes goes up to 256.
++	Added initial support for devices that have more than one port.
++	Added more debugging comments for the Visor, and added a needed
++	set_configuration call.
++
++ (01/17/2000) gkh
++	Fixed the WhiteHEAT firmware (my processing tool had a bug)
++	and added new debug loader firmware for it.
++	Removed the put_char function as it isn't really needed.
++	Added visor startup commands as found by the Win98 dump.
++
++ (01/13/2000) gkh
++	Fixed the vendor id for the generic driver to the one I meant it to be.
++
++ (01/12/2000) gkh
++	Forget the version numbering...that's pretty useless...
++	Made the driver able to be compiled so that the user can select which
++	converter they want to use. This allows people who only want the Visor
++	support to not pay the memory size price of the WhiteHEAT.
++	Fixed bug where the generic driver (idVendor=0000 and idProduct=0000)
++	grabbed the root hub. Not good.
++
++ version 0.4.0 (01/10/2000) gkh
++	Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT
++	device. Added startup function to allow firmware to be downloaded to
++	a device if it needs to be.
++	Added firmware download logic to the WhiteHEAT device.
++	Started to add #defines to split up the different drivers for potential
++	configuration option.
++
++ version 0.3.1 (12/30/99) gkh
++      Fixed problems with urb for bulk out.
++      Added initial support for multiple sets of endpoints. This enables
++      the Handspring Visor to be attached successfully. Only the first
++      bulk in / bulk out endpoint pair is being used right now.
++
++ version 0.3.0 (12/27/99) gkh
++	Added initial support for the Handspring Visor based on a patch from
++	Miles Lott (milos at sneety.insync.net)
++	Cleaned up the code a bunch and converted over to using urbs only.
++
++ version 0.2.3 (12/21/99) gkh
++	Added initial support for the Connect Tech WhiteHEAT converter.
++	Incremented the number of ports in expectation of getting the
++	WhiteHEAT to work properly (4 ports per connection).
++	Added notification on insertion and removal of what port the
++	device is/was connected to (and what kind of device it was).
++
++ version 0.2.2 (12/16/99) gkh
++	Changed major number to the new allocated number. We're legal now!
++
++ version 0.2.1 (12/14/99) gkh
++	Fixed bug that happens when device node is opened when there isn't a
++	device attached to it. Thanks to marek at webdesign.no for noticing this.
++
++ version 0.2.0 (11/10/99) gkh
++	Split up internals to make it easier to add different types of serial
++	converters to the code.
++	Added a "generic" driver that gets it's vendor and product id
++	from when the module is loaded. Thanks to David E. Nelson (dnelson at jump.net)
++	for the idea and sample code (from the usb scanner driver.)
++	Cleared up any licensing questions by releasing it under the GNU GPL.
++
++ version 0.1.2 (10/25/99) gkh
++ 	Fixed bug in detecting device.
++
++ version 0.1.1 (10/05/99) gkh
++ 	Changed the major number to not conflict with anything else.
++
++ version 0.1 (09/28/99) gkh
++ 	Can recognize the two different devices and start up a read from
++	device when asked to. Writes also work. No control signals yet, this
++	all is vendor specific data (i.e. no spec), also no control for
++	different baud rates or other bit settings.
++	Currently we are using the same devid as the acm driver. This needs
++	to change.
++
++-----------------------------------------------------------------------
++visor.c Change Log comments:
++
++ (06/03/2003) Judd Montgomery <judd at jpilot.org>
++     Added support for module parameter options for untested/unknown
++     devices.
++
++ (03/09/2003) gkh
++	Added support for the Sony Clie NZ90V device.  Thanks to Martin Brachtl
++	<brachtl at redgrep.cz> for the information.
++
++ (03/05/2003) gkh
++	Think Treo support is now working.
++
++ (04/03/2002) gkh
++	Added support for the Sony OS 4.1 devices.  Thanks to Hiroyuki ARAKI
++	<hiro at zob.ne.jp> for the information.
++
++ (03/27/2002) gkh
++	Removed assumptions that port->tty was always valid (is not true
++	for usb serial console devices.)
++
++ (03/23/2002) gkh
++	Added support for the Palm i705 device, thanks to Thomas Riemer
++	<tom at netmech.com> for the information.
++
++ (03/21/2002) gkh
++	Added support for the Palm m130 device, thanks to Udo Eisenbarth
++	<udo.eisenbarth at web.de> for the information.
++
++ (02/27/2002) gkh
++	Reworked the urb handling logic.  We have no more pool, but dynamically
++	allocate the urb and the transfer buffer on the fly.  In testing this
++	does not incure any measurable overhead.  This also relies on the fact
++	that we have proper reference counting logic for urbs.
++
++ (02/21/2002) SilaS
++  Added initial support for the Palm m515 devices.
++
++ (02/14/2002) gkh
++	Added support for the Clie S-360 device.
++
++ (12/18/2001) gkh
++	Added better Clie support for 3.5 devices.  Thanks to Geoffrey Levand
++	for the patch.
++
++ (11/11/2001) gkh
++	Added support for the m125 devices, and added check to prevent oopses
++	for Clié devices that lie about the number of ports they have.
++
++ (08/30/2001) gkh
++	Added support for the Clie devices, both the 3.5 and 4.0 os versions.
++	Many thanks to Daniel Burke, and Bryan Payne for helping with this.
++
++ (08/23/2001) gkh
++	fixed a few potential bugs pointed out by Oliver Neukum.
++
++ (05/30/2001) gkh
++	switched from using spinlock to a semaphore, which fixes lots of problems.
++
++ (05/28/2000) gkh
++	Added initial support for the Palm m500 and Palm m505 devices.
++
++ (04/08/2001) gb
++	Identify version on module load.
++
++ (01/21/2000) gkh
++	Added write_room and chars_in_buffer, as they were previously using the
++	generic driver versions which is all wrong now that we are using an urb
++	pool.  Thanks to Wolfgang Grandegger for pointing this out to me.
++	Removed count assignment in the write function, which was not needed anymore
++	either.  Thanks to Al Borchers for pointing this out.
++
++ (12/12/2000) gkh
++	Moved MOD_DEC to end of visor_close to be nicer, as the final write
++	message can sleep.
++
++ (11/12/2000) gkh
++	Fixed bug with data being dropped on the floor by forcing tty->low_latency
++	to be on.  Hopefully this fixes the OHCI issue!
++
++ (11/01/2000) Adam J. Richter
++	usb_device_id table support
++
++ (10/05/2000) gkh
++	Fixed bug with urb->dev not being set properly, now that the usb
++	core needs it.
++
++ (09/11/2000) gkh
++	Got rid of always calling kmalloc for every urb we wrote out to the
++	device.
++	Added visor_read_callback so we can keep track of bytes in and out for
++	those people who like to know the speed of their device.
++	Removed DEBUG #ifdefs with call to usb_serial_debug_data
++
++ (09/06/2000) gkh
++	Fixed oops in visor_exit.  Need to uncomment usb_unlink_urb call _after_
++	the host controller drivers set urb->dev = NULL when the urb is finished.
++
++ (08/28/2000) gkh
++	Added locks for SMP safeness.
++
++ (08/08/2000) gkh
++	Fixed endian problem in visor_startup.
++	Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
++	than once.
++
++ (07/23/2000) gkh
++	Added pool of write urbs to speed up transfers to the visor.
++
++ (07/19/2000) gkh
++	Added module_init and module_exit functions to handle the fact that this
++	driver is a loadable module now.
++
++ (07/03/2000) gkh
++	Added visor_set_ioctl and visor_set_termios functions (they don't do much
++	of anything, but are good for debugging.)
++
++ (06/25/2000) gkh
++	Fixed bug in visor_unthrottle that should help with the disconnect in PPP
++	bug that people have been reporting.
++
++ (06/23/2000) gkh
++	Cleaned up debugging statements in a quest to find UHCI timeout bug.
++
++ (04/27/2000) Ryan VanderBijl
++ 	Fixed memory leak in visor_close
++
++ (03/26/2000) gkh
++	Split driver up into device specific pieces.
++
++-----------------------------------------------------------------------
++pl2303.c Change Log comments:
++
++ 2002_Mar_26 gkh
++	allowed driver to work properly if there is no tty assigned to a port
++	(this happens for serial console devices.)
++
++ 2001_Oct_06 gkh
++	Added RTS and DTR line control.  Thanks to joe at bndlg.de for parts of it.
++
++ 2001_Sep_19 gkh
++	Added break support.
++
++ 2001_Aug_30 gkh
++	fixed oops in write_bulk_callback.
++
++ 2001_Aug_28 gkh
++	reworked buffer logic to be like other usb-serial drivers.  Hopefully
++	removing some reported problems.
++
++ 2001_Jun_06 gkh
++	finished porting to 2.4 format.
++
++
++-----------------------------------------------------------------------
++io_edgeport.c Change Log comments:
++
++ 2003_04_03 al borchers
++  - fixed a bug (that shows up with dosemu) where the tty struct is
++    used in a callback after it has been freed
++
++ 2.3 2002_03_08 greg kroah-hartman
++	- fixed bug when multiple devices were attached at the same time.
++
++ 2.2 2001_11_14 greg kroah-hartman
++	- fixed bug in edge_close that kept the port from being used more
++	  than once.
++	- fixed memory leak on device removal.
++	- fixed potential double free of memory when command urb submitting
++	  failed.
++	- other small cleanups when the device is removed
++
++ 2.1 2001_07_09 greg kroah-hartman
++	- added support for TIOCMBIS and TIOCMBIC.
++
++     (04/08/2001) gb
++	- Identify version on module load.
++
++ 2.0 2001_03_05 greg kroah-hartman
++	- reworked entire driver to fit properly in with the other usb-serial
++	  drivers.  Occasional oopses still happen, but it's a good start.
++
++ 1.2.3 (02/23/2001) greg kroah-hartman
++	- changed device table to work properly for 2.4.x final format.
++	- fixed problem with dropping data at high data rates.
++
++ 1.2.2 (11/27/2000) greg kroah-hartman
++	- cleaned up more NTisms.
++	- Added device table for 2.4.0-test11
++
++ 1.2.1 (11/08/2000) greg kroah-hartman
++	- Started to clean up NTisms.
++	- Fixed problem with dev field of urb for kernels >= 2.4.0-test9
++
++ 1.2 (10/17/2000) David Iacovelli
++ 	Remove all EPIC code and GPL source
++  Fix RELEVANT_IFLAG macro to include flow control
++  changes port configuration changes.
++  Fix redefinition of SERIAL_MAGIC
++  Change all timeout values to 5 seconds
++  Tried to fix the UHCI multiple urb submission, but failed miserably.
++  it seems to work fine with OHCI.
++  ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must
++    find a way to work arount this UHCI bug )
++
++ 1.1 (10/11/2000) David Iacovelli
++  Fix XON/XOFF flow control to support both IXON and IXOFF
++
++ 0.9.27 (06/30/2000) David Iacovelli
++  Added transmit queue and now allocate urb for command writes.
++
++ 0.9.26 (06/29/2000) David Iacovelli
++  Add support for 80251 based edgeport
++
++ 0.9.25 (06/27/2000) David Iacovelli
++  Do not close the port if it has multiple opens.
++
++ 0.9.24 (05/26/2000) David Iacovelli
++  Add IOCTLs to support RXTX and JAVA POS
++  and first cut at running BlackBox Demo
++
++ 0.9.23 (05/24/2000) David Iacovelli
++  Add IOCTLs to support RXTX and JAVA POS
++
++ 0.9.22 (05/23/2000) David Iacovelli
++  fixed bug in enumeration.  If epconfig turns on mapping by
++  path after a device is already plugged in, we now update
++  the mapping correctly
++
++ 0.9.21 (05/16/2000) David Iacovelli
++  Added BlockUntilChaseResp() to also wait for txcredits
++  Updated the way we allocate and handle write URBs
++	Add debug code to dump buffers
++
++ 0.9.20 (05/01/2000) David Iacovelli
++	change driver to use usb/tts/
++
++ 0.9.19 (05/01/2000) David Iacovelli
++  Update code to compile if DEBUG is off
++
++ 0.9.18 (04/28/2000) David Iacovelli
++  cleanup and test tty_register with devfs
++
++ 0.9.17 (04/27/2000) greg kroah-hartman
++ 	changed tty_register around to be like the way it
++ 	was before, but now it works properly with devfs.
++
++ 0.9.16 (04/26/2000) david iacovelli
++  Fixed bug in GetProductInfo()
++
++ 0.9.15 (04/25/2000) david iacovelli
++	Updated enumeration
++
++ 0.9.14 (04/24/2000) david iacovelli
++  Removed all config/status IOCTLS and
++  converted to using /proc/edgeport
++  still playing with devfs
++
++ 0.9.13 (04/24/2000) david iacovelli
++  Removed configuration based on ttyUSB0
++  Added support for configuration using /prod/edgeport
++  first attempt at using devfs (not working yet!)
++  Added IOCTL to GetProductInfo()
++  Added support for custom baud rates
++	Add support for random port numbers
++
++ 0.9.12 (04/18/2000) david iacovelli
++	added additional configuration IOCTLs
++  use ttyUSB0 for configuration
++
++ 0.9.11 (04/17/2000) greg kroah-hartman
++	fixed module initialization race conditions.
++	made all urbs dynamically allocated.
++	made driver devfs compatible. now it only registers the tty device
++	when the device is actually plugged in.
++
++ 0.9.10 (04/13/2000) greg kroah-hartman
++	added proc interface framework.
++
++ 0.9.9 (04/13/2000) david iacovelli
++	added enumeration code and ioctls to configure the device
++
++ 0.9.8 (04/12/2000) david iacovelli
++  Change interrupt read start when device is plugged in
++  and stop when device is removed
++	process interrupt reads when all ports are closed
++  (keep value of rxBytesAvail consistent with the edgeport)
++  set the USB_BULK_QUEUE flag so that we can shove a bunch
++  of urbs at once down the pipe
++
++ 0.9.7 (04/10/2000) david iacovelli
++ 	start to add enumeration code.
++  generate serial number for epic devices
++  add support for kdb
++
++ 0.9.6 (03/30/2000) david iacovelli
++  add IOCTL to get string, manufacture, and boot descriptors
++
++ 0.9.5 (03/14/2000) greg kroah-hartman
++	more error checking added to SerialOpen to try to fix UHCI open problem
++
++ 0.9.4 (03/09/2000) greg kroah-hartman
++	added more error checking to handle oops when data is hanging
++	around and tty is abruptly closed.
++
++ 0.9.3 (03/09/2000) david iacovelli
++	Add epic support for xon/xoff chars
++	play with performance
++
++ 0.9.2 (03/08/2000) greg kroah-hartman
++	changed most "info" calls to "dbg"
++	implemented flow control properly in the termios call
++
++ 0.9.1 (03/08/2000) david iacovelli
++	added EPIC support
++	enabled bootloader update
++
++ 0.9 (03/08/2000) greg kroah-hartman
++	Release to IO networks.
++	Integrated changes that David made
++  made getting urbs for writing SMP safe
++
++ 0.8 (03/07/2000) greg kroah-hartman
++	Release to IO networks.
++	Fixed problems that were seen in code by David.
++  Now both Edgeport/4 and Edgeport/2 works properly.
++  Changed most of the functions to use port instead of serial.
++
++ 0.7 (02/27/2000) greg kroah-hartman
++	Milestone 3 release.
++	Release to IO Networks
++	ioctl for waiting on line change implemented.
++	ioctl for getting statistics implemented.
++	multiport support working.
++	lsr and msr registers are now handled properly.
++	change break now hooked up and working.
++	support for all known Edgeport devices.
++
++ 0.6 (02/22/2000) greg kroah-hartman
++	Release to IO networks.
++	CHASE is implemented correctly when port is closed.
++	SerialOpen now blocks correctly until port is fully opened.
++
++ 0.5 (02/20/2000) greg kroah-hartman
++	Release to IO networks.
++	Known problems:
++		modem status register changes are not sent on to the user
++		CHASE is not implemented when the port is closed.
++
++ 0.4 (02/16/2000) greg kroah-hartman
++	Second cut at the CeBit demo.
++	Doesn't leak memory on every write to the port
++	Still small leaks on startup.
++	Added support for Edgeport/2 and Edgeport/8
++
++ 0.3 (02/15/2000) greg kroah-hartman
++	CeBit demo release.
++	Force the line settings to 4800, 8, 1, e for the demo.
++	Warning! This version leaks memory like crazy!
++
++ 0.2 (01/30/2000) greg kroah-hartman
++	Milestone 1 release.
++	Device is found by USB subsystem, enumerated, fimware is downloaded
++	and the descriptors are printed to the debug log, config is set, and
++	green light starts to blink. Open port works, and data can be sent
++	and received at the default settings of the UART. Loopback connector
++	and debug log confirms this.
++
++ 0.1 (01/23/2000) greg kroah-hartman
++	Initial release to help IO Networks try to set up their test system.
++	Edgeport4 is recognized, firmware is downloaded, config is set so
++	device blinks green light every 3 sec. Port is bound, but opening,
++	closing, and sending data do not work properly.
++
++
+diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
+--- a/drivers/usb/serial/Kconfig
++++ b/drivers/usb/serial/Kconfig
+@@ -394,6 +394,15 @@ config USB_SERIAL_MCT_U232
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called mct_u232.
+ 
++config USB_SERIAL_NOKIA_DKU2
++	tristate "USB Nokia DKU2 Driver"
++	depends on USB_SERIAL
++	help
++	  Say Y here if you want to use a Nokia DKU2 device.
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called nokia_dku2.
++
+ config USB_SERIAL_PL2303
+ 	tristate "USB Prolific 2303 Single Port Serial Driver"
+ 	depends on USB_SERIAL
+diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
+--- a/drivers/usb/serial/Makefile
++++ b/drivers/usb/serial/Makefile
+@@ -31,6 +31,7 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA)		+=
+ obj-$(CONFIG_USB_SERIAL_KLSI)			+= kl5kusb105.o
+ obj-$(CONFIG_USB_SERIAL_KOBIL_SCT)		+= kobil_sct.o
+ obj-$(CONFIG_USB_SERIAL_MCT_U232)		+= mct_u232.o
++obj-$(CONFIG_USB_SERIAL_NOKIA_DKU2)		+= nokia_dku2.o
+ obj-$(CONFIG_USB_SERIAL_OMNINET)		+= omninet.o
+ obj-$(CONFIG_USB_SERIAL_OPTION)			+= option.o
+ obj-$(CONFIG_USB_SERIAL_PL2303)			+= pl2303.o
+diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
+--- a/drivers/usb/serial/airprime.c
++++ b/drivers/usb/serial/airprime.c
+@@ -30,9 +30,11 @@ static struct usb_driver airprime_driver
+ 	.id_table =	id_table,
+ };
+ 
+-static struct usb_serial_device_type airprime_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"airprime",
++static struct usb_serial_driver airprime_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"airprime",
++	},
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		NUM_DONT_CARE,
+diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
+--- a/drivers/usb/serial/belkin_sa.c
++++ b/drivers/usb/serial/belkin_sa.c
+@@ -121,10 +121,12 @@ static struct usb_driver belkin_driver =
+ };
+ 
+ /* All of the device info needed for the serial converters */
+-static struct usb_serial_device_type belkin_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Belkin / Peracom / GoHubs USB Serial Adapter",
+-	.short_name =		"belkin",
++static struct usb_serial_driver belkin_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"belkin",
++	},
++	.description =		"Belkin / Peracom / GoHubs USB Serial Adapter",
+ 	.id_table =		id_table_combined,
+ 	.num_interrupt_in =	1,
+ 	.num_bulk_in =		1,
+diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
+--- a/drivers/usb/serial/bus.c
++++ b/drivers/usb/serial/bus.c
+@@ -18,7 +18,7 @@
+ 
+ static int usb_serial_device_match (struct device *dev, struct device_driver *drv)
+ {
+-	struct usb_serial_device_type *driver;
++	struct usb_serial_driver *driver;
+ 	const struct usb_serial_port *port;
+ 
+ 	/*
+@@ -44,7 +44,7 @@ struct bus_type usb_serial_bus_type = {
+ 
+ static int usb_serial_device_probe (struct device *dev)
+ {
+-	struct usb_serial_device_type *driver;
++	struct usb_serial_driver *driver;
+ 	struct usb_serial_port *port;
+ 	int retval = 0;
+ 	int minor;
+@@ -57,13 +57,13 @@ static int usb_serial_device_probe (stru
+ 
+ 	driver = port->serial->type;
+ 	if (driver->port_probe) {
+-		if (!try_module_get(driver->owner)) {
++		if (!try_module_get(driver->driver.owner)) {
+ 			dev_err(dev, "module get failed, exiting\n");
+ 			retval = -EIO;
+ 			goto exit;
+ 		}
+ 		retval = driver->port_probe (port);
+-		module_put(driver->owner);
++		module_put(driver->driver.owner);
+ 		if (retval)
+ 			goto exit;
+ 	}
+@@ -72,7 +72,7 @@ static int usb_serial_device_probe (stru
+ 	tty_register_device (usb_serial_tty_driver, minor, dev);
+ 	dev_info(&port->serial->dev->dev, 
+ 		 "%s converter now attached to ttyUSB%d\n",
+-		 driver->name, minor);
++		 driver->description, minor);
+ 
+ exit:
+ 	return retval;
+@@ -80,7 +80,7 @@ exit:
+ 
+ static int usb_serial_device_remove (struct device *dev)
+ {
+-	struct usb_serial_device_type *driver;
++	struct usb_serial_driver *driver;
+ 	struct usb_serial_port *port;
+ 	int retval = 0;
+ 	int minor;
+@@ -92,43 +92,38 @@ static int usb_serial_device_remove (str
+ 
+ 	driver = port->serial->type;
+ 	if (driver->port_remove) {
+-		if (!try_module_get(driver->owner)) {
++		if (!try_module_get(driver->driver.owner)) {
+ 			dev_err(dev, "module get failed, exiting\n");
+ 			retval = -EIO;
+ 			goto exit;
+ 		}
+ 		retval = driver->port_remove (port);
+-		module_put(driver->owner);
++		module_put(driver->driver.owner);
+ 	}
+ exit:
+ 	minor = port->number;
+ 	tty_unregister_device (usb_serial_tty_driver, minor);
+ 	dev_info(dev, "%s converter now disconnected from ttyUSB%d\n",
+-		 driver->name, minor);
++		 driver->description, minor);
+ 
+ 	return retval;
+ }
+ 
+-int usb_serial_bus_register(struct usb_serial_device_type *device)
++int usb_serial_bus_register(struct usb_serial_driver *driver)
+ {
+ 	int retval;
+ 
+-	if (device->short_name)
+-		device->driver.name = (char *)device->short_name;
+-	else
+-		device->driver.name = (char *)device->name;
+-	device->driver.bus = &usb_serial_bus_type;
+-	device->driver.probe = usb_serial_device_probe;
+-	device->driver.remove = usb_serial_device_remove;
+-	device->driver.owner = device->owner;
++	driver->driver.bus = &usb_serial_bus_type;
++	driver->driver.probe = usb_serial_device_probe;
++	driver->driver.remove = usb_serial_device_remove;
+ 
+-	retval = driver_register(&device->driver);
++	retval = driver_register(&driver->driver);
+ 
+ 	return retval;
+ }
+ 
+-void usb_serial_bus_deregister(struct usb_serial_device_type *device)
++void usb_serial_bus_deregister(struct usb_serial_driver *driver)
+ {
+-	driver_unregister (&device->driver);
++	driver_unregister(&driver->driver);
+ }
+ 
+diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
+--- a/drivers/usb/serial/cp2101.c
++++ b/drivers/usb/serial/cp2101.c
+@@ -67,15 +67,17 @@ MODULE_DEVICE_TABLE (usb, id_table);
+ 
+ static struct usb_driver cp2101_driver = {
+ 	.owner		= THIS_MODULE,
+-	.name		= "CP2101",
++	.name		= "cp2101",
+ 	.probe		= usb_serial_probe,
+ 	.disconnect	= usb_serial_disconnect,
+ 	.id_table	= id_table,
+ };
+ 
+-static struct usb_serial_device_type cp2101_device = {
+-	.owner			= THIS_MODULE,
+-	.name			= "CP2101",
++static struct usb_serial_driver cp2101_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name = 	"cp2101",
++	},
+ 	.id_table		= id_table,
+ 	.num_interrupt_in	= 0,
+ 	.num_bulk_in		= 0,
+diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
+--- a/drivers/usb/serial/cyberjack.c
++++ b/drivers/usb/serial/cyberjack.c
+@@ -83,10 +83,12 @@ static struct usb_driver cyberjack_drive
+ 	.id_table =	id_table,
+ };
+ 
+-static struct usb_serial_device_type cyberjack_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Reiner SCT Cyberjack USB card reader",
+-	.short_name =		"cyberjack",
++static struct usb_serial_driver cyberjack_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"cyberjack",
++	},
++	.description =		"Reiner SCT Cyberjack USB card reader",
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	1,
+ 	.num_bulk_in =		1,
+diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
+--- a/drivers/usb/serial/cypress_m8.c
++++ b/drivers/usb/serial/cypress_m8.c
+@@ -176,10 +176,12 @@ static unsigned int	  cypress_buf_put(st
+ static unsigned int	  cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count);
+ 
+ 
+-static struct usb_serial_device_type cypress_earthmate_device = {
+-	.owner =			THIS_MODULE,
+-	.name =				"DeLorme Earthmate USB",
+-	.short_name =			"earthmate",
++static struct usb_serial_driver cypress_earthmate_device = {
++	.driver = {
++		.owner =		THIS_MODULE,
++		.name =			"earthmate",
++	},
++	.description =			"DeLorme Earthmate USB",
+ 	.id_table =			id_table_earthmate,
+ 	.num_interrupt_in = 		1,
+ 	.num_interrupt_out =		1,
+@@ -203,10 +205,12 @@ static struct usb_serial_device_type cyp
+ 	.write_int_callback =		cypress_write_int_callback,
+ };
+ 
+-static struct usb_serial_device_type cypress_hidcom_device = {
+-	.owner =			THIS_MODULE,
+-	.name =				"HID->COM RS232 Adapter",
+-	.short_name =			"cyphidcom",
++static struct usb_serial_driver cypress_hidcom_device = {
++	.driver = {
++		.owner =		THIS_MODULE,
++		.name =			"cyphidcom",
++	},
++	.description =			"HID->COM RS232 Adapter",
+ 	.id_table =			id_table_cyphidcomrs232,
+ 	.num_interrupt_in =		1,
+ 	.num_interrupt_out =		1,
+diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
+--- a/drivers/usb/serial/digi_acceleport.c
++++ b/drivers/usb/serial/digi_acceleport.c
+@@ -503,10 +503,12 @@ static struct usb_driver digi_driver = {
+ 
+ /* device info needed for the Digi serial converter */
+ 
+-static struct usb_serial_device_type digi_acceleport_2_device = {
+-	.owner =			THIS_MODULE,
+-	.name =				"Digi 2 port USB adapter",
+-	.short_name =			"digi_2",
++static struct usb_serial_driver digi_acceleport_2_device = {
++	.driver = {
++		.owner =		THIS_MODULE,
++		.name =			"digi_2",
++	},
++	.description =			"Digi 2 port USB adapter",
+ 	.id_table =			id_table_2,
+ 	.num_interrupt_in =		0,
+ 	.num_bulk_in =			4,
+@@ -530,10 +532,12 @@ static struct usb_serial_device_type dig
+ 	.shutdown =			digi_shutdown,
+ };
+ 
+-static struct usb_serial_device_type digi_acceleport_4_device = {
+-	.owner =			THIS_MODULE,
+-	.name =				"Digi 4 port USB adapter",
+-	.short_name =			"digi_4",
++static struct usb_serial_driver digi_acceleport_4_device = {
++	.driver = {
++		.owner =		THIS_MODULE,
++		.name =			"digi_4",
++	},
++	.description =			"Digi 4 port USB adapter",
+ 	.id_table =			id_table_4,
+ 	.num_interrupt_in =		0,
+ 	.num_bulk_in =			5,
+diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
+--- a/drivers/usb/serial/empeg.c
++++ b/drivers/usb/serial/empeg.c
+@@ -112,9 +112,11 @@ static struct usb_driver empeg_driver = 
+ 	.id_table =	id_table,
+ };
+ 
+-static struct usb_serial_device_type empeg_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Empeg",
++static struct usb_serial_driver empeg_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"empeg",
++	},
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	0,
+ 	.num_bulk_in =		1,
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -411,6 +411,8 @@ static struct usb_device_id id_table_com
+ 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
+ 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) },
+ 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) },
++	{ USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) },
++	{ USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) },
+ 	/*
+ 	 * These will probably use user-space drivers.  Uncomment them if
+ 	 * you need them or use the user-specified vendor/product module
+@@ -428,7 +430,6 @@ static struct usb_device_id id_table_com
+ 	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */
+ 	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */
+ 	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */
+-	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, */
+ 	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */
+ 	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */
+ 	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */
+@@ -471,6 +472,9 @@ static struct usb_device_id id_table_com
+ 	{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
+ 	{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
+ 	{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
++	{ USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
++	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
++	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
+ 	{ },					/* Optional parameter entry */
+ 	{ }					/* Terminating entry */
+ };
+@@ -558,10 +562,12 @@ static unsigned short int ftdi_232am_bau
+ static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base);
+ static __u32 ftdi_232bm_baud_to_divisor (int baud);
+ 
+-static struct usb_serial_device_type ftdi_sio_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"FTDI USB Serial Device",
+-	.short_name =		"ftdi_sio",
++static struct usb_serial_driver ftdi_sio_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"ftdi_sio",
++	},
++	.description =		"FTDI USB Serial Device",
+ 	.id_table =		id_table_combined,
+ 	.num_interrupt_in =	0,
+ 	.num_bulk_in =		1,
+diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
+--- a/drivers/usb/serial/ftdi_sio.h
++++ b/drivers/usb/serial/ftdi_sio.h
+@@ -199,6 +199,19 @@
+ #define FTDI_PIEGROUP_PID	0xF208	/* Product Id */
+ 
+ /*
++ * Definitions for Artemis astronomical USB based cameras
++ * Check it at http://www.artemisccd.co.uk/
++ */
++#define FTDI_ARTEMIS_PID	0xDF28	/* All Artemis Cameras */
++
++/*
++ * Definitions for ATIK Instruments astronomical USB based cameras
++ * Check it at http://www.atik-instruments.com/
++ */
++#define FTDI_ATIK_ATK16_PID	0xDF30	/* ATIK ATK-16 Camera */
++#define FTDI_ATIK_ATK16HR_PID	0xDF31	/* ATIK ATK-16HR Camera */
++
++/*
+  * Protego product ids
+  */
+ #define PROTEGO_SPECIAL_1	0xFC70	/* special/unknown device */
+@@ -329,6 +342,9 @@
+ #define EVOLUTION_VID		0xDEEE	/* Vendor ID */
+ #define EVOLUTION_ER1_PID	0x0300	/* ER1 Control Module */
+ 
++/* Pyramid Computer GmbH */
++#define FTDI_PYRAMID_PID	0xE6C8	/* Pyramid Appliance Display */
++
+ /* Commands */
+ #define FTDI_SIO_RESET 		0 /* Reset the port */
+ #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
+diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
+--- a/drivers/usb/serial/garmin_gps.c
++++ b/drivers/usb/serial/garmin_gps.c
+@@ -1468,16 +1468,13 @@ static void garmin_shutdown (struct usb_
+ }
+ 
+ 
+-
+-
+-
+-
+-
+ /* All of the device info needed */
+-static struct usb_serial_device_type garmin_device = {
+-	.owner               = THIS_MODULE,
+-	.name                = "Garmin GPS usb/tty",
+-	.short_name          = "garmin_gps",
++static struct usb_serial_driver garmin_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"garmin_gps",
++	},
++	.description =		"Garmin GPS usb/tty",
+ 	.id_table            = id_table,
+ 	.num_interrupt_in    = 1,
+ 	.num_bulk_in         = 1,
+diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
+--- a/drivers/usb/serial/generic.c
++++ b/drivers/usb/serial/generic.c
+@@ -36,10 +36,11 @@ MODULE_PARM_DESC(product, "User specifie
+ static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */
+ 
+ /* All of the device info needed for the Generic Serial Converter */
+-struct usb_serial_device_type usb_serial_generic_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Generic",
+-	.short_name =		"generic",
++struct usb_serial_driver usb_serial_generic_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"generic",
++	},
+ 	.id_table =		generic_device_ids,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		NUM_DONT_CARE,
+diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c
+--- a/drivers/usb/serial/hp4x.c
++++ b/drivers/usb/serial/hp4x.c
+@@ -38,15 +38,17 @@ MODULE_DEVICE_TABLE(usb, id_table);
+ 
+ static struct usb_driver hp49gp_driver = {
+ 	.owner =	THIS_MODULE,
+-	.name =		"HP4X",
++	.name =		"hp4X",
+ 	.probe =	usb_serial_probe,
+ 	.disconnect =	usb_serial_disconnect,
+ 	.id_table =	id_table,
+ };
+ 
+-static struct usb_serial_device_type hp49gp_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"HP4X",
++static struct usb_serial_driver hp49gp_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"hp4X",
++	},
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		NUM_DONT_CARE,
+diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -27,225 +27,6 @@
+  * Networks technical support, or Peter Berger <pberger at brimson.com>,
+  * or Al Borchers <alborchers at steinerpoint.com>.
+  *
+- * Version history:
+- * 
+- * 2003_04_03 al borchers
+- *  - fixed a bug (that shows up with dosemu) where the tty struct is
+- *    used in a callback after it has been freed
+- *
+- * 2.3 2002_03_08 greg kroah-hartman
+- *	- fixed bug when multiple devices were attached at the same time.
+- *
+- * 2.2 2001_11_14 greg kroah-hartman
+- *	- fixed bug in edge_close that kept the port from being used more
+- *	  than once.
+- *	- fixed memory leak on device removal.
+- *	- fixed potential double free of memory when command urb submitting
+- *	  failed.
+- *	- other small cleanups when the device is removed
+- *	
+- * 2.1 2001_07_09 greg kroah-hartman
+- *	- added support for TIOCMBIS and TIOCMBIC.
+- *
+- *     (04/08/2001) gb
+- *	- Identify version on module load.
+- *
+- * 2.0 2001_03_05 greg kroah-hartman
+- *	- reworked entire driver to fit properly in with the other usb-serial
+- *	  drivers.  Occasional oopses still happen, but it's a good start.
+- *
+- * 1.2.3 (02/23/2001) greg kroah-hartman
+- *	- changed device table to work properly for 2.4.x final format.
+- *	- fixed problem with dropping data at high data rates.
+- *
+- * 1.2.2 (11/27/2000) greg kroah-hartman
+- *	- cleaned up more NTisms.
+- *	- Added device table for 2.4.0-test11
+- *
+- * 1.2.1 (11/08/2000) greg kroah-hartman
+- *	- Started to clean up NTisms.
+- *	- Fixed problem with dev field of urb for kernels >= 2.4.0-test9
+- *
+- * 1.2 (10/17/2000) David Iacovelli
+- * 	Remove all EPIC code and GPL source
+- *  Fix RELEVANT_IFLAG macro to include flow control 
+- *  changes port configuration changes.
+- *  Fix redefinition of SERIAL_MAGIC
+- *  Change all timeout values to 5 seconds
+- *  Tried to fix the UHCI multiple urb submission, but failed miserably.
+- *  it seems to work fine with OHCI.
+- *  ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must 
+- *    find a way to work arount this UHCI bug )
+- *
+- * 1.1 (10/11/2000) David Iacovelli
+- *  Fix XON/XOFF flow control to support both IXON and IXOFF
+- *
+- * 0.9.27 (06/30/2000) David Iacovelli
+- *  Added transmit queue and now allocate urb for command writes.
+- *
+- * 0.9.26 (06/29/2000) David Iacovelli
+- *  Add support for 80251 based edgeport
+- *
+- * 0.9.25 (06/27/2000) David Iacovelli
+- *  Do not close the port if it has multiple opens.
+- *
+- * 0.9.24 (05/26/2000) David Iacovelli
+- *  Add IOCTLs to support RXTX and JAVA POS 
+- *  and first cut at running BlackBox Demo
+- *
+- * 0.9.23 (05/24/2000) David Iacovelli
+- *  Add IOCTLs to support RXTX and JAVA POS
+- *
+- * 0.9.22 (05/23/2000) David Iacovelli
+- *  fixed bug in enumeration.  If epconfig turns on mapping by
+- *  path after a device is already plugged in, we now update
+- *  the mapping correctly
+- *
+- * 0.9.21 (05/16/2000) David Iacovelli
+- *  Added BlockUntilChaseResp() to also wait for txcredits
+- *  Updated the way we allocate and handle write URBs 
+- *	Add debug code to dump buffers
+- *
+- * 0.9.20 (05/01/2000) David Iacovelli
+- *	change driver to use usb/tts/
+- *
+- * 0.9.19 (05/01/2000) David Iacovelli
+- *  Update code to compile if DEBUG is off
+- *
+- * 0.9.18 (04/28/2000) David Iacovelli
+- *  cleanup and test tty_register with devfs
+- *
+- * 0.9.17 (04/27/2000) greg kroah-hartman
+- * 	changed tty_register around to be like the way it
+- * 	was before, but now it works properly with devfs.
+- *
+- * 0.9.16 (04/26/2000) david iacovelli
+- *  Fixed bug in GetProductInfo()
+- *
+- * 0.9.15 (04/25/2000) david iacovelli
+- *	Updated enumeration
+- *
+- * 0.9.14 (04/24/2000) david iacovelli
+- *  Removed all config/status IOCTLS and 
+- *  converted to using /proc/edgeport
+- *  still playing with devfs
+- *
+- * 0.9.13 (04/24/2000) david iacovelli
+- *  Removed configuration based on ttyUSB0
+- *  Added support for configuration using /prod/edgeport
+- *  first attempt at using devfs (not working yet!)
+- *  Added IOCTL to GetProductInfo()
+- *  Added support for custom baud rates
+- *	Add support for random port numbers
+- *
+- * 0.9.12 (04/18/2000) david iacovelli
+- *	added additional configuration IOCTLs
+- *  use ttyUSB0 for configuration
+- *
+- * 0.9.11 (04/17/2000) greg kroah-hartman
+- *	fixed module initialization race conditions.
+- *	made all urbs dynamically allocated.
+- *	made driver devfs compatible. now it only registers the tty device
+- *	when the device is actually plugged in.
+- *
+- * 0.9.10 (04/13/2000) greg kroah-hartman
+- *	added proc interface framework.
+- *
+- * 0.9.9 (04/13/2000) david iacovelli
+- *	added enumeration code and ioctls to configure the device
+- *
+- * 0.9.8 (04/12/2000) david iacovelli
+- *  Change interrupt read start when device is plugged in
+- *  and stop when device is removed
+- *	process interrupt reads when all ports are closed 
+- *  (keep value of rxBytesAvail consistent with the edgeport)
+- *  set the USB_BULK_QUEUE flag so that we can shove a bunch 
+- *  of urbs at once down the pipe 
+- *
+- * 0.9.7 (04/10/2000) david iacovelli
+- * 	start to add enumeration code.
+- *  generate serial number for epic devices
+- *  add support for kdb
+- *
+- * 0.9.6 (03/30/2000) david iacovelli
+- *  add IOCTL to get string, manufacture, and boot descriptors
+- *
+- * 0.9.5 (03/14/2000) greg kroah-hartman
+- *	more error checking added to SerialOpen to try to fix UHCI open problem
+- *
+- * 0.9.4 (03/09/2000) greg kroah-hartman
+- *	added more error checking to handle oops when data is hanging
+- *	around and tty is abruptly closed.
+- *
+- * 0.9.3 (03/09/2000) david iacovelli
+- *	Add epic support for xon/xoff chars
+- *	play with performance
+- *
+- * 0.9.2 (03/08/2000) greg kroah-hartman
+- *	changed most "info" calls to "dbg"
+- *	implemented flow control properly in the termios call
+- *
+- * 0.9.1 (03/08/2000) david iacovelli
+- *	added EPIC support
+- *	enabled bootloader update
+- *
+- * 0.9 (03/08/2000) greg kroah-hartman
+- *	Release to IO networks.
+- *	Integrated changes that David made
+- *  made getting urbs for writing SMP safe
+- *
+- * 0.8 (03/07/2000) greg kroah-hartman
+- *	Release to IO networks.
+- *	Fixed problems that were seen in code by David.
+- *  Now both Edgeport/4 and Edgeport/2 works properly.
+- *  Changed most of the functions to use port instead of serial.
+- *
+- * 0.7 (02/27/2000) greg kroah-hartman
+- *	Milestone 3 release.
+- *	Release to IO Networks
+- *	ioctl for waiting on line change implemented.
+- *	ioctl for getting statistics implemented.
+- *	multiport support working.
+- *	lsr and msr registers are now handled properly.
+- *	change break now hooked up and working.
+- *	support for all known Edgeport devices.
+- *
+- * 0.6 (02/22/2000) greg kroah-hartman
+- *	Release to IO networks.
+- *	CHASE is implemented correctly when port is closed.
+- *	SerialOpen now blocks correctly until port is fully opened.
+- *
+- * 0.5 (02/20/2000) greg kroah-hartman
+- *	Release to IO networks.
+- *	Known problems:
+- *		modem status register changes are not sent on to the user
+- *		CHASE is not implemented when the port is closed.
+- *
+- * 0.4 (02/16/2000) greg kroah-hartman
+- *	Second cut at the CeBit demo.
+- *	Doesn't leak memory on every write to the port
+- *	Still small leaks on startup.
+- *	Added support for Edgeport/2 and Edgeport/8
+- *
+- * 0.3 (02/15/2000) greg kroah-hartman
+- *	CeBit demo release.
+- *	Force the line settings to 4800, 8, 1, e for the demo.
+- *	Warning! This version leaks memory like crazy!
+- *
+- * 0.2 (01/30/2000) greg kroah-hartman
+- *	Milestone 1 release.
+- *	Device is found by USB subsystem, enumerated, fimware is downloaded
+- *	and the descriptors are printed to the debug log, config is set, and
+- *	green light starts to blink. Open port works, and data can be sent
+- *	and received at the default settings of the UART. Loopback connector
+- *	and debug log confirms this.
+- * 
+- * 0.1 (01/23/2000) greg kroah-hartman
+- *	Initial release to help IO Networks try to set up their test system. 
+- *	Edgeport4 is recognized, firmware is downloaded, config is set so 
+- *	device blinks green light every 3 sec. Port is bound, but opening,
+- *	closing, and sending data do not work properly.
+- * 
+  */
+ 
+ #include <linux/config.h>
+diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h
+--- a/drivers/usb/serial/io_tables.h
++++ b/drivers/usb/serial/io_tables.h
+@@ -75,10 +75,12 @@ static struct usb_device_id id_table_com
+ 
+ MODULE_DEVICE_TABLE (usb, id_table_combined);
+ 
+-static struct usb_serial_device_type edgeport_2port_device = {
+-	.owner			= THIS_MODULE,
+-	.name			= "Edgeport 2 port adapter",
+-	.short_name		= "edgeport_2",
++static struct usb_serial_driver edgeport_2port_device = {
++	.driver = {
++		.owner		= THIS_MODULE,
++		.name		= "edgeport_2",
++	},
++	.description		= "Edgeport 2 port adapter",
+ 	.id_table		= edgeport_2port_id_table,
+ 	.num_interrupt_in	= 1,
+ 	.num_bulk_in		= 1,
+@@ -103,10 +105,12 @@ static struct usb_serial_device_type edg
+ 	.write_bulk_callback	= edge_bulk_out_data_callback,
+ };
+ 
+-static struct usb_serial_device_type edgeport_4port_device = {
+-	.owner			= THIS_MODULE,
+-	.name			= "Edgeport 4 port adapter",
+-	.short_name		= "edgeport_4",
++static struct usb_serial_driver edgeport_4port_device = {
++	.driver = {
++		.owner		= THIS_MODULE,
++		.name		= "edgeport_4",
++	},
++	.description		= "Edgeport 4 port adapter",
+ 	.id_table		= edgeport_4port_id_table,
+ 	.num_interrupt_in	= 1,
+ 	.num_bulk_in		= 1,
+@@ -131,10 +135,12 @@ static struct usb_serial_device_type edg
+ 	.write_bulk_callback	= edge_bulk_out_data_callback,
+ };
+ 
+-static struct usb_serial_device_type edgeport_8port_device = {
+-	.owner			= THIS_MODULE,
+-	.name			= "Edgeport 8 port adapter",
+-	.short_name		= "edgeport_8",
++static struct usb_serial_driver edgeport_8port_device = {
++	.driver = {
++		.owner		= THIS_MODULE,
++		.name		= "edgeport_8",
++	},
++	.description		= "Edgeport 8 port adapter",
+ 	.id_table		= edgeport_8port_id_table,
+ 	.num_interrupt_in	= 1,
+ 	.num_bulk_in		= 1,
+diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -2982,10 +2982,12 @@ static unsigned int edge_buf_get(struct 
+ }
+ 
+ 
+-static struct usb_serial_device_type edgeport_1port_device = {
+-	.owner			= THIS_MODULE,
+-	.name			= "Edgeport TI 1 port adapter",
+-	.short_name		= "edgeport_ti_1",
++static struct usb_serial_driver edgeport_1port_device = {
++	.driver = {
++		.owner		= THIS_MODULE,
++		.name		= "edgeport_ti_1",
++	},
++	.description		= "Edgeport TI 1 port adapter",
+ 	.id_table		= edgeport_1port_id_table,
+ 	.num_interrupt_in	= 1,
+ 	.num_bulk_in		= 1,
+@@ -3010,10 +3012,12 @@ static struct usb_serial_device_type edg
+ 	.write_bulk_callback	= edge_bulk_out_callback,
+ };
+ 
+-static struct usb_serial_device_type edgeport_2port_device = {
+-	.owner			= THIS_MODULE,
+-	.name			= "Edgeport TI 2 port adapter",
+-	.short_name		= "edgeport_ti_2",
++static struct usb_serial_driver edgeport_2port_device = {
++	.driver = {
++		.owner		= THIS_MODULE,
++		.name		= "edgeport_ti_2",
++	},
++	.description		= "Edgeport TI 2 port adapter",
+ 	.id_table		= edgeport_2port_id_table,
+ 	.num_interrupt_in	= 1,
+ 	.num_bulk_in		= 2,
+diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
+--- a/drivers/usb/serial/ipaq.c
++++ b/drivers/usb/serial/ipaq.c
+@@ -92,24 +92,7 @@ static void ipaq_destroy_lists(struct us
+ static struct usb_device_id ipaq_id_table [] = {
+ 	/* The first entry is a placeholder for the insmod-specified device */
+ 	{ USB_DEVICE(0x049F, 0x0003) },
+-	{ USB_DEVICE(0x1690, 0x0601) }, /* Askey USB Sync */
+-	{ USB_DEVICE(0x0960, 0x0065) }, /* BCOM USB Sync 0065 */
+-	{ USB_DEVICE(0x0960, 0x0066) }, /* BCOM USB Sync 0066 */
+-	{ USB_DEVICE(0x0960, 0x0067) }, /* BCOM USB Sync 0067 */
+-	{ USB_DEVICE(0x07CF, 0x2001) }, /* CASIO USB Sync 2001 */
+-	{ USB_DEVICE(0x07CF, 0x2002) }, /* CASIO USB Sync 2002 */
+-	{ USB_DEVICE(0x07CF, 0x2003) }, /* CASIO USB Sync 2003 */
+-	{ USB_DEVICE(0x049F, 0x0003) }, /* Compaq iPAQ USB Sync */
+-	{ USB_DEVICE(0x049F, 0x0032) }, /* Compaq iPAQ USB Sync */
+-	{ USB_DEVICE(0x413C, 0x4001) }, /* Dell Axim USB Sync */
+-	{ USB_DEVICE(0x413C, 0x4002) }, /* Dell Axim USB Sync */
+-	{ USB_DEVICE(0x413C, 0x4003) }, /* Dell Axim USB Sync */
+-	{ USB_DEVICE(0x413C, 0x4004) }, /* Dell Axim USB Sync */
+-	{ USB_DEVICE(0x413C, 0x4005) }, /* Dell Axim USB Sync */
+-	{ USB_DEVICE(0x413C, 0x4006) }, /* Dell Axim USB Sync */
+-	{ USB_DEVICE(0x413C, 0x4007) }, /* Dell Axim USB Sync */
+-	{ USB_DEVICE(0x413C, 0x4008) }, /* Dell Axim USB Sync */
+-	{ USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */
++	{ USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */
+ 	{ USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */
+ 	{ USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */
+ 	{ USB_DEVICE(0x03F0, 0x1216) }, /* HP USB Sync 1612 */
+@@ -125,7 +108,13 @@ static struct usb_device_id ipaq_id_tabl
+ 	{ USB_DEVICE(0x03F0, 0x5016) }, /* HP USB Sync 1650 */
+ 	{ USB_DEVICE(0x03F0, 0x5116) }, /* HP USB Sync 1651 */
+ 	{ USB_DEVICE(0x03F0, 0x5216) }, /* HP USB Sync 1652 */
+-	{ USB_DEVICE(0x094B, 0x0001) }, /* Linkup Systems USB Sync */
++	{ USB_DEVICE(0x0409, 0x00D5) }, /* NEC USB Sync */
++	{ USB_DEVICE(0x0409, 0x00D6) }, /* NEC USB Sync */
++	{ USB_DEVICE(0x0409, 0x00D7) }, /* NEC USB Sync */
++	{ USB_DEVICE(0x0409, 0x8024) }, /* NEC USB Sync */
++	{ USB_DEVICE(0x0409, 0x8025) }, /* NEC USB Sync */
++	{ USB_DEVICE(0x043E, 0x9C01) }, /* LGE USB Sync */
++	{ USB_DEVICE(0x045E, 0x00CE) }, /* Microsoft USB Sync */
+ 	{ USB_DEVICE(0x045E, 0x0400) }, /* Windows Powered Pocket PC 2002 */
+ 	{ USB_DEVICE(0x045E, 0x0401) }, /* Windows Powered Pocket PC 2002 */
+ 	{ USB_DEVICE(0x045E, 0x0402) }, /* Windows Powered Pocket PC 2002 */
+@@ -251,17 +240,81 @@ static struct usb_device_id ipaq_id_tabl
+ 	{ USB_DEVICE(0x045E, 0x04E8) }, /* Windows Powered Smartphone 2003 */
+ 	{ USB_DEVICE(0x045E, 0x04E9) }, /* Windows Powered Smartphone 2003 */
+ 	{ USB_DEVICE(0x045E, 0x04EA) }, /* Windows Powered Smartphone 2003 */
+-	{ USB_DEVICE(0x0961, 0x0010) }, /* Portatec USB Sync */
+-	{ USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */
+-	{ USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */
++	{ USB_DEVICE(0x049F, 0x0003) }, /* Compaq iPAQ USB Sync */
++	{ USB_DEVICE(0x049F, 0x0032) }, /* Compaq iPAQ USB Sync */
++	{ USB_DEVICE(0x04A4, 0x0014) }, /* Hitachi USB Sync */
++	{ USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */
++	{ USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */
++	{ USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */
++	{ USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
++	{ USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
++	{ USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
++	{ USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */
++	{ USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */
++	{ USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
++	{ USB_DEVICE(0x04E8, 0x5F03) }, /* Samsung NEXiO USB Sync */
++	{ USB_DEVICE(0x04E8, 0x5F04) }, /* Samsung NEXiO USB Sync */
++	{ USB_DEVICE(0x04E8, 0x6611) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x04E8, 0x6613) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x04E8, 0x6615) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x04E8, 0x6617) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x04E8, 0x6619) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x04E8, 0x661B) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x04E8, 0x662E) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x04E8, 0x6630) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x04E8, 0x6632) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x04f1, 0x3011) }, /* JVC USB Sync */
++	{ USB_DEVICE(0x04F1, 0x3012) }, /* JVC USB Sync */
++	{ USB_DEVICE(0x0502, 0x1631) }, /* c10 Series */
++	{ USB_DEVICE(0x0502, 0x1632) }, /* c20 Series */
++	{ USB_DEVICE(0x0502, 0x16E1) }, /* Acer n10 Handheld USB Sync */
++	{ USB_DEVICE(0x0502, 0x16E2) }, /* Acer n20 Handheld USB Sync */
++	{ USB_DEVICE(0x0502, 0x16E3) }, /* Acer n30 Handheld USB Sync */
++	{ USB_DEVICE(0x0536, 0x01A0) }, /* HHP PDT */
++	{ USB_DEVICE(0x0543, 0x0ED9) }, /* ViewSonic Color Pocket PC V35 */
++	{ USB_DEVICE(0x0543, 0x1527) }, /* ViewSonic Color Pocket PC V36 */
++	{ USB_DEVICE(0x0543, 0x1529) }, /* ViewSonic Color Pocket PC V37 */
++	{ USB_DEVICE(0x0543, 0x152B) }, /* ViewSonic Color Pocket PC V38 */
++	{ USB_DEVICE(0x0543, 0x152E) }, /* ViewSonic Pocket PC */
++	{ USB_DEVICE(0x0543, 0x1921) }, /* ViewSonic Communicator Pocket PC */
++	{ USB_DEVICE(0x0543, 0x1922) }, /* ViewSonic Smartphone */
++	{ USB_DEVICE(0x0543, 0x1923) }, /* ViewSonic Pocket PC V30 */
++	{ USB_DEVICE(0x05E0, 0x2000) }, /* Symbol USB Sync */
++	{ USB_DEVICE(0x05E0, 0x2001) }, /* Symbol USB Sync 0x2001 */
++	{ USB_DEVICE(0x05E0, 0x2002) }, /* Symbol USB Sync 0x2002 */
++	{ USB_DEVICE(0x05E0, 0x2003) }, /* Symbol USB Sync 0x2003 */
++	{ USB_DEVICE(0x05E0, 0x2004) }, /* Symbol USB Sync 0x2004 */
++	{ USB_DEVICE(0x05E0, 0x2005) }, /* Symbol USB Sync 0x2005 */
++	{ USB_DEVICE(0x05E0, 0x2006) }, /* Symbol USB Sync 0x2006 */
++	{ USB_DEVICE(0x05E0, 0x2007) }, /* Symbol USB Sync 0x2007 */
++	{ USB_DEVICE(0x05E0, 0x2008) }, /* Symbol USB Sync 0x2008 */
++	{ USB_DEVICE(0x05E0, 0x2009) }, /* Symbol USB Sync 0x2009 */
++	{ USB_DEVICE(0x05E0, 0x200A) }, /* Symbol USB Sync 0x200A */
++	{ USB_DEVICE(0x067E, 0x1001) }, /* Intermec Mobile Computer */
++	{ USB_DEVICE(0x07CF, 0x2001) }, /* CASIO USB Sync 2001 */
++	{ USB_DEVICE(0x07CF, 0x2002) }, /* CASIO USB Sync 2002 */
++	{ USB_DEVICE(0x07CF, 0x2003) }, /* CASIO USB Sync 2003 */
+ 	{ USB_DEVICE(0x0930, 0x0700) }, /* TOSHIBA USB Sync 0700 */
+ 	{ USB_DEVICE(0x0930, 0x0705) }, /* TOSHIBA Pocket PC e310 */
++	{ USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */
+ 	{ USB_DEVICE(0x0930, 0x0707) }, /* TOSHIBA Pocket PC e330 Series */
+ 	{ USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */
+-	{ USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */
+ 	{ USB_DEVICE(0x0930, 0x0709) }, /* TOSHIBA Pocket PC e750 Series */
+ 	{ USB_DEVICE(0x0930, 0x070A) }, /* TOSHIBA Pocket PC e400 Series */
+ 	{ USB_DEVICE(0x0930, 0x070B) }, /* TOSHIBA Pocket PC e800 Series */
++	{ USB_DEVICE(0x094B, 0x0001) }, /* Linkup Systems USB Sync */
++	{ USB_DEVICE(0x0960, 0x0065) }, /* BCOM USB Sync 0065 */
++	{ USB_DEVICE(0x0960, 0x0066) }, /* BCOM USB Sync 0066 */
++	{ USB_DEVICE(0x0960, 0x0067) }, /* BCOM USB Sync 0067 */
++	{ USB_DEVICE(0x0961, 0x0010) }, /* Portatec USB Sync */
++	{ USB_DEVICE(0x099E, 0x0052) }, /* Trimble GeoExplorer */
++	{ USB_DEVICE(0x099E, 0x4000) }, /* TDS Data Collector */
++	{ USB_DEVICE(0x0B05, 0x4200) }, /* ASUS USB Sync */
++	{ USB_DEVICE(0x0B05, 0x4201) }, /* ASUS USB Sync */
++	{ USB_DEVICE(0x0B05, 0x4202) }, /* ASUS USB Sync */
++	{ USB_DEVICE(0x0B05, 0x420F) }, /* ASUS USB Sync */
++	{ USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */
++	{ USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */
+ 	{ USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */
+ 	{ USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */
+ 	{ USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */
+@@ -422,116 +475,67 @@ static struct usb_device_id ipaq_id_tabl
+ 	{ USB_DEVICE(0x0BB4, 0x0A9D) }, /* SmartPhone USB Sync */
+ 	{ USB_DEVICE(0x0BB4, 0x0A9E) }, /* SmartPhone USB Sync */
+ 	{ USB_DEVICE(0x0BB4, 0x0A9F) }, /* SmartPhone USB Sync */
+-	{ USB_DEVICE(0x0409, 0x00D5) }, /* NEC USB Sync */
+-	{ USB_DEVICE(0x0409, 0x00D6) }, /* NEC USB Sync */
+-	{ USB_DEVICE(0x0409, 0x00D7) }, /* NEC USB Sync */
+-	{ USB_DEVICE(0x0409, 0x8024) }, /* NEC USB Sync */
+-	{ USB_DEVICE(0x0409, 0x8025) }, /* NEC USB Sync */
+-	{ USB_DEVICE(0x04A4, 0x0014) }, /* Hitachi USB Sync */
+ 	{ USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */
+-	{ USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */
+-	{ USB_DEVICE(0x0502, 0x16E1) }, /* Acer n10 Handheld USB Sync */
+-	{ USB_DEVICE(0x0502, 0x16E3) }, /* Acer n30 Handheld USB Sync */
+-	{ USB_DEVICE(0x0502, 0x16E2) }, /* Acer n20 Handheld USB Sync */
+-	{ USB_DEVICE(0x0502, 0x1631) }, /* c10 Series */
+-	{ USB_DEVICE(0x0502, 0x1632) }, /* c20 Series */
+-	{ USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */
+-	{ USB_DEVICE(0x0B05, 0x420F) }, /* ASUS USB Sync */
+-	{ USB_DEVICE(0x0B05, 0x4200) }, /* ASUS USB Sync */
+-	{ USB_DEVICE(0x0B05, 0x4201) }, /* ASUS USB Sync */
+-	{ USB_DEVICE(0x0B05, 0x4202) }, /* ASUS USB Sync */
+-	{ USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */
++	{ USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */
+ 	{ USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */
+-	{ USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */
+-	{ USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */
+-	{ USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */
++	{ USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */
++	{ USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */
++	{ USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */
++	{ USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */
++	{ USB_DEVICE(0x0FB8, 0x3002) }, /* Wistron USB Sync */
++	{ USB_DEVICE(0x0FB8, 0x3003) }, /* Wistron USB Sync */
++	{ USB_DEVICE(0x0FB8, 0x4001) }, /* Wistron USB Sync */
++	{ USB_DEVICE(0x1066, 0x00CE) }, /* E-TEN USB Sync */
+ 	{ USB_DEVICE(0x1066, 0x0300) }, /* E-TEN P3XX Pocket PC */
+ 	{ USB_DEVICE(0x1066, 0x0500) }, /* E-TEN P5XX Pocket PC */
+ 	{ USB_DEVICE(0x1066, 0x0600) }, /* E-TEN P6XX Pocket PC */
+ 	{ USB_DEVICE(0x1066, 0x0700) }, /* E-TEN P7XX Pocket PC */
+-	{ USB_DEVICE(0x1066, 0x00CE) }, /* E-TEN USB Sync */
+-	{ USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */
+-	{ USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
+-	{ USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
+-	{ USB_DEVICE(0x067E, 0x1001) }, /* Intermec Mobile Computer */
+-	{ USB_DEVICE(0x04f1, 0x3011) }, /* JVC USB Sync */
+-	{ USB_DEVICE(0x04F1, 0x3012) }, /* JVC USB Sync */
+-	{ USB_DEVICE(0x3708, 0x20CE) }, /* Legend USB Sync */
+-	{ USB_DEVICE(0x3708, 0x21CE) }, /* Lenovo USB Sync */
+-	{ USB_DEVICE(0x043E, 0x9C01) }, /* LGE USB Sync */
+-	{ USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
+-	{ USB_DEVICE(0x3340, 0x0B1C) }, /* Generic PPC StrongARM */
+-	{ USB_DEVICE(0x3340, 0x0E3A) }, /* Generic PPC USB Sync */
+-	{ USB_DEVICE(0x3340, 0x0F3A) }, /* Generic SmartPhone USB Sync */
+-	{ USB_DEVICE(0x3340, 0x0F1C) }, /* Itautec USB Sync */
+-	{ USB_DEVICE(0x3340, 0x1326) }, /* Itautec USB Sync */
+-	{ USB_DEVICE(0x3340, 0x3326) }, /* MEDION Winodws Moble USB Sync */
++	{ USB_DEVICE(0x1114, 0x0001) }, /* Psion Teklogix Sync 753x */
++	{ USB_DEVICE(0x1114, 0x0004) }, /* Psion Teklogix Sync netBookPro */
++	{ USB_DEVICE(0x1114, 0x0006) }, /* Psion Teklogix Sync 7525 */
++	{ USB_DEVICE(0x1182, 0x1388) }, /* VES USB Sync */
++	{ USB_DEVICE(0x11D9, 0x1002) }, /* Rugged Pocket PC 2003 */
++	{ USB_DEVICE(0x11D9, 0x1003) }, /* Rugged Pocket PC 2003 */
++	{ USB_DEVICE(0x1231, 0xCE01) }, /* USB Sync 03 */
++	{ USB_DEVICE(0x1231, 0xCE02) }, /* USB Sync 03 */
++	{ USB_DEVICE(0x1690, 0x0601) }, /* Askey USB Sync */
++	{ USB_DEVICE(0x22B8, 0x4204) }, /* Motorola MPx200 Smartphone */
++	{ USB_DEVICE(0x22B8, 0x4214) }, /* Motorola MPc GSM */
++	{ USB_DEVICE(0x22B8, 0x4224) }, /* Motorola MPx220 Smartphone */
++	{ USB_DEVICE(0x22B8, 0x4234) }, /* Motorola MPc CDMA */
++	{ USB_DEVICE(0x22B8, 0x4244) }, /* Motorola MPx100 Smartphone */
++	{ USB_DEVICE(0x3340, 0x011C) }, /* Mio DigiWalker PPC StrongARM */
+ 	{ USB_DEVICE(0x3340, 0x0326) }, /* Mio DigiWalker 338 */
+ 	{ USB_DEVICE(0x3340, 0x0426) }, /* Mio DigiWalker 338 */
+-	{ USB_DEVICE(0x3340, 0x011C) }, /* Mio DigiWalker PPC StrongARM */
+-	{ USB_DEVICE(0x3340, 0x053A) }, /* Mio DigiWalker SmartPhone USB Sync */
+ 	{ USB_DEVICE(0x3340, 0x043A) }, /* Mio DigiWalker USB Sync */
+-	{ USB_DEVICE(0x3340, 0x071C) }, /* MiTAC USB Sync */
+ 	{ USB_DEVICE(0x3340, 0x051C) }, /* MiTAC USB Sync 528 */
+-	{ USB_DEVICE(0x3340, 0x2326) }, /* Vobis USB Sync */
++	{ USB_DEVICE(0x3340, 0x053A) }, /* Mio DigiWalker SmartPhone USB Sync */
++	{ USB_DEVICE(0x3340, 0x071C) }, /* MiTAC USB Sync */
++	{ USB_DEVICE(0x3340, 0x0B1C) }, /* Generic PPC StrongARM */
++	{ USB_DEVICE(0x3340, 0x0E3A) }, /* Generic PPC USB Sync */
++	{ USB_DEVICE(0x3340, 0x0F1C) }, /* Itautec USB Sync */
++	{ USB_DEVICE(0x3340, 0x0F3A) }, /* Generic SmartPhone USB Sync */
++	{ USB_DEVICE(0x3340, 0x1326) }, /* Itautec USB Sync */
+ 	{ USB_DEVICE(0x3340, 0x191C) }, /* YAKUMO USB Sync */
++	{ USB_DEVICE(0x3340, 0x2326) }, /* Vobis USB Sync */
++	{ USB_DEVICE(0x3340, 0x3326) }, /* MEDION Winodws Moble USB Sync */
++	{ USB_DEVICE(0x3708, 0x20CE) }, /* Legend USB Sync */
++	{ USB_DEVICE(0x3708, 0x21CE) }, /* Lenovo USB Sync */
+ 	{ USB_DEVICE(0x4113, 0x0210) }, /* Mobile Media Technology USB Sync */
+ 	{ USB_DEVICE(0x4113, 0x0211) }, /* Mobile Media Technology USB Sync */
+ 	{ USB_DEVICE(0x4113, 0x0400) }, /* Mobile Media Technology USB Sync */
+ 	{ USB_DEVICE(0x4113, 0x0410) }, /* Mobile Media Technology USB Sync */
+-	{ USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */
+-	{ USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */
+-	{ USB_DEVICE(0x04E8, 0x6611) }, /* Samsung MITs USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x6613) }, /* Samsung MITs USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x6615) }, /* Samsung MITs USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x6617) }, /* Samsung MITs USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x6619) }, /* Samsung MITs USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x661B) }, /* Samsung MITs USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x5F03) }, /* Samsung NEXiO USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x5F04) }, /* Samsung NEXiO USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x662E) }, /* Samsung MITs USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x6630) }, /* Samsung MITs USB Sync */
+-	{ USB_DEVICE(0x04E8, 0x6632) }, /* Samsung MITs USB Sync */
++	{ USB_DEVICE(0x413C, 0x4001) }, /* Dell Axim USB Sync */
++	{ USB_DEVICE(0x413C, 0x4002) }, /* Dell Axim USB Sync */
++	{ USB_DEVICE(0x413C, 0x4003) }, /* Dell Axim USB Sync */
++	{ USB_DEVICE(0x413C, 0x4004) }, /* Dell Axim USB Sync */
++	{ USB_DEVICE(0x413C, 0x4005) }, /* Dell Axim USB Sync */
++	{ USB_DEVICE(0x413C, 0x4006) }, /* Dell Axim USB Sync */
++	{ USB_DEVICE(0x413C, 0x4007) }, /* Dell Axim USB Sync */
++	{ USB_DEVICE(0x413C, 0x4008) }, /* Dell Axim USB Sync */
++	{ USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */
+ 	{ USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */
+-	{ USB_DEVICE(0x05E0, 0x2000) }, /* Symbol USB Sync */
+-	{ USB_DEVICE(0x05E0, 0x2001) }, /* Symbol USB Sync 0x2001 */
+-	{ USB_DEVICE(0x05E0, 0x2002) }, /* Symbol USB Sync 0x2002 */
+-	{ USB_DEVICE(0x05E0, 0x2003) }, /* Symbol USB Sync 0x2003 */
+-	{ USB_DEVICE(0x05E0, 0x2004) }, /* Symbol USB Sync 0x2004 */
+-	{ USB_DEVICE(0x05E0, 0x2005) }, /* Symbol USB Sync 0x2005 */
+-	{ USB_DEVICE(0x05E0, 0x2006) }, /* Symbol USB Sync 0x2006 */
+-	{ USB_DEVICE(0x05E0, 0x2007) }, /* Symbol USB Sync 0x2007 */
+-	{ USB_DEVICE(0x05E0, 0x2008) }, /* Symbol USB Sync 0x2008 */
+-	{ USB_DEVICE(0x05E0, 0x2009) }, /* Symbol USB Sync 0x2009 */
+-	{ USB_DEVICE(0x05E0, 0x200A) }, /* Symbol USB Sync 0x200A */
+-	{ USB_DEVICE(0x1182, 0x1388) }, /* VES USB Sync */
+-	{ USB_DEVICE(0x0543, 0x0ED9) }, /* ViewSonic Color Pocket PC V35 */
+-	{ USB_DEVICE(0x0543, 0x1527) }, /* ViewSonic Color Pocket PC V36 */
+-	{ USB_DEVICE(0x0543, 0x1529) }, /* ViewSonic Color Pocket PC V37 */
+-	{ USB_DEVICE(0x0543, 0x152B) }, /* ViewSonic Color Pocket PC V38 */
+-	{ USB_DEVICE(0x0543, 0x152E) }, /* ViewSonic Pocket PC */
+-	{ USB_DEVICE(0x0543, 0x1921) }, /* ViewSonic Communicator Pocket PC */
+-	{ USB_DEVICE(0x0543, 0x1922) }, /* ViewSonic Smartphone */
+-	{ USB_DEVICE(0x0543, 0x1923) }, /* ViewSonic Pocket PC V30 */
+-	{ USB_DEVICE(0x0536, 0x01A0) }, /* HHP PDT */
+-	{ USB_DEVICE(0x099E, 0x0052) }, /* Trimble GeoExplorer */
+-	{ USB_DEVICE(0x099E, 0x4000) }, /* TDS Data Collector */
+-	{ USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */
+-	{ USB_DEVICE(0x0FB8, 0x3002) }, /* Wistron USB Sync */
+-	{ USB_DEVICE(0x0FB8, 0x3003) }, /* Wistron USB Sync */
+-	{ USB_DEVICE(0x0FB8, 0x4001) }, /* Wistron USB Sync */
+-	{ USB_DEVICE(0x11D9, 0x1003) }, /* Rugged Pocket PC 2003 */
+-	{ USB_DEVICE(0x11D9, 0x1002) }, /* Rugged Pocket PC 2003 */
+-	{ USB_DEVICE(0x22B8, 0x4204) }, /* Motorola MPx200 Smartphone */
+-	{ USB_DEVICE(0x22B8, 0x4214) }, /* Motorola MPc GSM */
+-	{ USB_DEVICE(0x22B8, 0x4224) }, /* Motorola MPx220 Smartphone */
+-	{ USB_DEVICE(0x22B8, 0x4234) }, /* Motorola MPc CDMA */
+-	{ USB_DEVICE(0x22B8, 0x4244) }, /* Motorola MPx100 Smartphone */
+-	{ USB_DEVICE(0x1231, 0xCE01) }, /* USB Sync 03 */
+-	{ USB_DEVICE(0x1231, 0xCE02) }, /* USB Sync 03 */
++	{ USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */
+ 	{ }                             /* Terminating entry */
+ };
+ 
+@@ -547,9 +551,12 @@ static struct usb_driver ipaq_driver = {
+ 
+ 
+ /* All of the device info needed for the Compaq iPAQ */
+-static struct usb_serial_device_type ipaq_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"PocketPC PDA",
++static struct usb_serial_driver ipaq_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"ipaq",
++	},
++	.description =		"PocketPC PDA",
+ 	.id_table =		ipaq_id_table,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		1,
+diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
+--- a/drivers/usb/serial/ipw.c
++++ b/drivers/usb/serial/ipw.c
+@@ -443,10 +443,12 @@ static int ipw_disconnect(struct usb_ser
+ 	return 0;
+ }
+ 
+-static struct usb_serial_device_type ipw_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"IPWireless converter",
+-	.short_name =		"ipw",
++static struct usb_serial_driver ipw_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"ipw",
++	},
++	.description =		"IPWireless converter",
+ 	.id_table =		usb_ipw_ids,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		1,
+diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
+--- a/drivers/usb/serial/ir-usb.c
++++ b/drivers/usb/serial/ir-usb.c
+@@ -133,9 +133,12 @@ static struct usb_driver ir_driver = {
+ };
+ 
+ 
+-static struct usb_serial_device_type ir_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"IR Dongle",
++static struct usb_serial_driver ir_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"ir-usb",
++	},
++	.description =		"IR Dongle",
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	1,
+ 	.num_bulk_in =		1,
+diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
+--- a/drivers/usb/serial/kl5kusb105.c
++++ b/drivers/usb/serial/kl5kusb105.c
+@@ -123,10 +123,12 @@ static struct usb_driver kl5kusb105d_dri
+ 	.id_table =	id_table,
+ };
+ 
+-static struct usb_serial_device_type kl5kusb105d_device = {
+-	.owner =             THIS_MODULE,
+-	.name =		     "KL5KUSB105D / PalmConnect",
+-	.short_name =	     "kl5kusb105d",
++static struct usb_serial_driver kl5kusb105d_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"kl5kusb105d",
++	},
++	.description =	     "KL5KUSB105D / PalmConnect",
+ 	.id_table =	     id_table,
+ 	.num_interrupt_in =  1,
+ 	.num_bulk_in =	     1,
+diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
+--- a/drivers/usb/serial/kobil_sct.c
++++ b/drivers/usb/serial/kobil_sct.c
+@@ -105,9 +105,12 @@ static struct usb_driver kobil_driver = 
+ };
+ 
+ 
+-static struct usb_serial_device_type kobil_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"KOBIL USB smart card terminal",
++static struct usb_serial_driver kobil_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"kobil",
++	},
++	.description =		"KOBIL USB smart card terminal",
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		0,
+diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
+--- a/drivers/usb/serial/mct_u232.c
++++ b/drivers/usb/serial/mct_u232.c
+@@ -132,10 +132,12 @@ static struct usb_driver mct_u232_driver
+ 	.id_table =	id_table_combined,
+ };
+ 
+-static struct usb_serial_device_type mct_u232_device = {
+-	.owner =	     THIS_MODULE,
+-	.name =		     "MCT U232",
+-	.short_name =	     "mct_u232",
++static struct usb_serial_driver mct_u232_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"mct_u232",
++	},
++	.description =	     "MCT U232",
+ 	.id_table =	     id_table_combined,
+ 	.num_interrupt_in =  2,
+ 	.num_bulk_in =	     0,
+diff --git a/drivers/usb/serial/nokia_dku2.c b/drivers/usb/serial/nokia_dku2.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/usb/serial/nokia_dku2.c
+@@ -0,0 +1,142 @@
++/*
++ *  Nokia DKU2 USB driver
++ *
++ *  Copyright (C) 2004
++ *  Author: C Kemp
++ *
++ *  This program is largely derived from work by the linux-usb group
++ *  and associated source files.  Please see the usb/serial files for
++ *  individual credits and copyrights.
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License as published by
++ *  the Free Software Foundation; either version 2 of the License, or
++ *  (at your option) any later version.
++ *
++ *  20.09.2005 - Matthias Blaesing <matthias.blaesing at rwth-aachen.de>
++ *  Added short name to device structure to make driver load into kernel 2.6.13
++ *
++ *  20.09.2005 - Matthias Blaesing <matthias.blaesing at rwth-aachen.de>
++ *  Added usb_deregister to exit code - to allow remove and reinsert of module
++ */
++
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/tty.h>
++#include <linux/tty_driver.h>
++#include <linux/tty_flip.h>
++#include <linux/module.h>
++#include <linux/usb.h>
++#include "usb-serial.h"
++
++
++#define NOKIA_VENDOR_ID		0x0421
++#define NOKIA7600_PRODUCT_ID	0x0400
++#define NOKIA6230_PRODUCT_ID	0x040f
++#define NOKIA6170_PRODUCT_ID	0x0416
++#define NOKIA6670_PRODUCT_ID	0x041d
++#define NOKIA6680_PRODUCT_ID	0x041e
++#define NOKIA6230i_PRODUCT_ID	0x0428
++
++#define NOKIA_AT_PORT	0x82
++#define NOKIA_FBUS_PORT	0x86
++
++/*
++ * Version Information
++ */
++#define DRIVER_VERSION	"v0.2"
++#define DRIVER_AUTHOR	"C Kemp"
++#define DRIVER_DESC	"Nokia DKU2 Driver"
++
++static struct usb_device_id id_table [] = {
++	{ USB_DEVICE(NOKIA_VENDOR_ID, NOKIA7600_PRODUCT_ID) },
++	{ USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230_PRODUCT_ID) },
++	{ USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6170_PRODUCT_ID) },
++	{ USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6670_PRODUCT_ID) },
++	{ USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6680_PRODUCT_ID) },
++	{ USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230i_PRODUCT_ID) },
++	{ }			/* Terminating entry */
++};
++MODULE_DEVICE_TABLE(usb, id_table);
++
++/* The only thing which makes this device different from a generic
++ * device is that we have to set an alternative configuration to make
++ * the relevant endpoints available. In 2.6 this is really easy... */
++static int nokia_probe(struct usb_serial *serial,
++		       const struct usb_device_id *id)
++{
++	int retval = -ENODEV;
++
++	if (serial->interface->altsetting[0].endpoint[0].desc.bEndpointAddress == NOKIA_AT_PORT) {
++		/* the AT port */
++		dev_info(&serial->dev->dev, "Nokia AT Port:\n");
++		retval = 0;
++	} else if (serial->interface->num_altsetting == 2 &&
++		   serial->interface->altsetting[1].endpoint[0].desc.bEndpointAddress == NOKIA_FBUS_PORT) {
++		/* the FBUS port */
++		dev_info(&serial->dev->dev, "Nokia FBUS Port:\n");
++		usb_set_interface(serial->dev, 10, 1);
++		retval = 0;
++	}
++
++	return retval;
++}
++
++static struct usb_driver nokia_driver = {
++	.owner =	THIS_MODULE,
++	.name =		"nokia_dku2",
++	.probe =	usb_serial_probe,
++	.disconnect =	usb_serial_disconnect,
++	.id_table =	id_table,
++};
++
++static struct usb_serial_driver nokia_serial_driver = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name = 	"nokia_dku2",
++	},
++	.description =		"Nokia 7600/6230(i)/6170/66x0 DKU2 driver",
++	.id_table =		id_table,
++	.num_interrupt_in =	1,
++	.num_bulk_in =		1,
++	.num_bulk_out =		1,
++	.num_ports =		1,
++	.probe =		nokia_probe,
++};
++
++static int __init nokia_init(void)
++{
++        int retval;
++
++	retval = usb_serial_register(&nokia_serial_driver);
++	if (retval)
++		return retval;
++
++	retval = usb_register(&nokia_driver);
++	if (retval) {
++	        usb_serial_deregister(&nokia_serial_driver);
++		return retval;
++	}
++
++	info(DRIVER_VERSION " " DRIVER_AUTHOR);
++	info(DRIVER_DESC);
++
++	return retval;
++}
++
++static void __exit nokia_exit(void)
++{
++	usb_deregister(&nokia_driver);
++	usb_serial_deregister(&nokia_serial_driver);
++}
++
++module_init(nokia_init);
++module_exit(nokia_exit);
++
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
+--- a/drivers/usb/serial/omninet.c
++++ b/drivers/usb/serial/omninet.c
+@@ -88,10 +88,12 @@ static struct usb_driver omninet_driver 
+ };
+ 
+ 
+-static struct usb_serial_device_type zyxel_omninet_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"ZyXEL - omni.net lcd plus usb",
+-	.short_name =		"omninet",
++static struct usb_serial_driver zyxel_omninet_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"omninet",
++	},
++	.description =		"ZyXEL - omni.net lcd plus usb",
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	1,
+ 	.num_bulk_in =		1,
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -105,10 +105,12 @@ static struct usb_driver option_driver =
+ /* The card has three separate interfaces, wich the serial driver
+  * recognizes separately, thus num_port=1.
+  */
+-static struct usb_serial_device_type option_3port_device = {
+-	.owner             = THIS_MODULE,
+-	.name              = "Option 3G data card",
+-	.short_name        = "option",
++static struct usb_serial_driver option_3port_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"option",
++	},
++	.description       = "Option 3G data card",
+ 	.id_table          = option_ids,
+ 	.num_interrupt_in  = NUM_DONT_CARE,
+ 	.num_bulk_in       = NUM_DONT_CARE,
+diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
+--- a/drivers/usb/serial/pl2303.c
++++ b/drivers/usb/serial/pl2303.c
+@@ -8,31 +8,10 @@
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+- *	the Free Software Foundation; either version 2 of the License, or
+- *	(at your option) any later version.
++ *	the Free Software Foundation; either version 2 of the License.
+  *
+  * See Documentation/usb/usb-serial.txt for more information on using this driver
+  *
+- * 2002_Mar_26 gkh
+- *	allowed driver to work properly if there is no tty assigned to a port
+- *	(this happens for serial console devices.)
+- *
+- * 2001_Oct_06 gkh
+- *	Added RTS and DTR line control.  Thanks to joe at bndlg.de for parts of it.
+- *
+- * 2001_Sep_19 gkh
+- *	Added break support.
+- *
+- * 2001_Aug_30 gkh
+- *	fixed oops in write_bulk_callback.
+- *
+- * 2001_Aug_28 gkh
+- *	reworked buffer logic to be like other usb-serial drivers.  Hopefully
+- *	removing some reported problems.
+- *
+- * 2001_Jun_06 gkh
+- *	finished porting to 2.4 format.
+- * 
+  */
+ 
+ #include <linux/config.h>
+@@ -55,7 +34,6 @@
+ /*
+  * Version Information
+  */
+-#define DRIVER_VERSION "v0.12"
+ #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
+ 
+ static int debug;
+@@ -175,9 +153,11 @@ static unsigned int pl2303_buf_get(struc
+ 
+ 
+ /* All of the device info needed for the PL2303 SIO serial converter */
+-static struct usb_serial_device_type pl2303_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"PL-2303",
++static struct usb_serial_driver pl2303_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"pl2303",
++	},
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		1,
+@@ -1195,7 +1175,7 @@ static int __init pl2303_init (void)
+ 	retval = usb_register(&pl2303_driver);
+ 	if (retval)
+ 		goto failed_usb_register;
+-	info(DRIVER_DESC " " DRIVER_VERSION);
++	info(DRIVER_DESC);
+ 	return 0;
+ failed_usb_register:
+ 	usb_serial_deregister(&pl2303_device);
+@@ -1215,7 +1195,6 @@ module_init(pl2303_init);
+ module_exit(pl2303_exit);
+ 
+ MODULE_DESCRIPTION(DRIVER_DESC);
+-MODULE_VERSION(DRIVER_VERSION);
+ MODULE_LICENSE("GPL");
+ 
+ module_param(debug, bool, S_IRUGO | S_IWUSR);
+diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
+--- a/drivers/usb/serial/safe_serial.c
++++ b/drivers/usb/serial/safe_serial.c
+@@ -92,7 +92,7 @@ MODULE_DESCRIPTION (DRIVER_DESC);
+ MODULE_LICENSE("GPL");
+ 
+ #if defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) && !defined(CONFIG_USBD_SAFE_SERIAL_PRODUCT)
+-#abort "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT"
++#error "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT"
+ #endif
+ 
+ #if ! defined(CONFIG_USBD_SAFE_SERIAL_VENDOR)
+@@ -397,9 +397,11 @@ static int safe_startup (struct usb_seri
+ 	return 0;
+ }
+ 
+-static struct usb_serial_device_type safe_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Safe",
++static struct usb_serial_driver safe_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"safe_serial",
++	},
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		NUM_DONT_CARE,
+diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -255,9 +255,12 @@ static struct usb_driver ti_usb_driver =
+ 	.id_table		= ti_id_table_combined,
+ };
+ 
+-static struct usb_serial_device_type ti_1port_device = {
+-	.owner			= THIS_MODULE,
+-	.name			= "TI USB 3410 1 port adapter",
++static struct usb_serial_driver ti_1port_device = {
++	.driver = {
++		.owner		= THIS_MODULE,
++		.name		= "ti_usb_3410_5052_1",
++	},
++	.description		= "TI USB 3410 1 port adapter",
+ 	.id_table		= ti_id_table_3410,
+ 	.num_interrupt_in	= 1,
+ 	.num_bulk_in		= 1,
+@@ -282,9 +285,12 @@ static struct usb_serial_device_type ti_
+ 	.write_bulk_callback	= ti_bulk_out_callback,
+ };
+ 
+-static struct usb_serial_device_type ti_2port_device = {
+-	.owner			= THIS_MODULE,
+-	.name			= "TI USB 5052 2 port adapter",
++static struct usb_serial_driver ti_2port_device = {
++	.driver = {
++		.owner		= THIS_MODULE,
++		.name		= "ti_usb_3410_5052_2",
++	},
++	.description		= "TI USB 5052 2 port adapter",
+ 	.id_table		= ti_id_table_5052,
+ 	.num_interrupt_in	= 1,
+ 	.num_bulk_in		= 2,
+diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -1,7 +1,7 @@
+ /*
+  * USB Serial Converter driver
+  *
+- * Copyright (C) 1999 - 2004 Greg Kroah-Hartman (greg at kroah.com)
++ * Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg at kroah.com)
+  * Copyright (C) 2000 Peter Berger (pberger at brimson.com)
+  * Copyright (C) 2000 Al Borchers (borchers at steinerpoint.com)
+  *
+@@ -9,316 +9,11 @@
+  *	modify it under the terms of the GNU General Public License version
+  *	2 as published by the Free Software Foundation.
+  *
+- * This driver was originally based on the ACM driver by Armin Fuerst (which was 
++ * This driver was originally based on the ACM driver by Armin Fuerst (which was
+  * based on a driver by Brad Keryan)
+  *
+  * See Documentation/usb/usb-serial.txt for more information on using this driver
+  *
+- * (12/10/2002) gkh
+- *	Split the ports off into their own struct device, and added a
+- *	usb-serial bus driver.
+- *
+- * (11/19/2002) gkh
+- *	removed a few #ifdefs for the generic code and cleaned up the failure
+- *	logic in initialization.
+- *
+- * (10/02/2002) gkh
+- *	moved the console code to console.c and out of this file.
+- *
+- * (06/05/2002) gkh
+- *	moved location of startup() call in serial_probe() until after all
+- *	of the port information and endpoints are initialized.  This makes
+- *	things easier for some drivers.
+- *
+- * (04/10/2002) gkh
+- *	added serial_read_proc function which creates a
+- *	/proc/tty/driver/usb-serial file.
+- *
+- * (03/27/2002) gkh
+- *	Got USB serial console code working properly and merged into the main
+- *	version of the tree.  Thanks to Randy Dunlap for the initial version
+- *	of this code, and for pushing me to finish it up.
+- *	The USB serial console works with any usb serial driver device.
+- *
+- * (03/21/2002) gkh
+- *	Moved all manipulation of port->open_count into the core.  Now the
+- *	individual driver's open and close functions are called only when the
+- *	first open() and last close() is called.  Making the drivers a bit
+- *	smaller and simpler.
+- *	Fixed a bug if a driver didn't have the owner field set.
+- *
+- * (02/26/2002) gkh
+- *	Moved all locking into the main serial_* functions, instead of having 
+- *	the individual drivers have to grab the port semaphore.  This should
+- *	reduce races.
+- *	Reworked the MOD_INC logic a bit to always increment and decrement, even
+- *	if the generic driver is being used.
+- *
+- * (10/10/2001) gkh
+- *	usb_serial_disconnect() now sets the serial->dev pointer is to NULL to
+- *	help prevent child drivers from accessing the device since it is now
+- *	gone.
+- *
+- * (09/13/2001) gkh
+- *	Moved generic driver initialize after we have registered with the USB
+- *	core.  Thanks to Randy Dunlap for pointing this problem out.
+- *
+- * (07/03/2001) gkh
+- *	Fixed module paramater size.  Thanks to John Brockmeyer for the pointer.
+- *	Fixed vendor and product getting defined through the MODULE_PARM macro
+- *	if the Generic driver wasn't compiled in.
+- *	Fixed problem with generic_shutdown() not being called for drivers that
+- *	don't have a shutdown() function.
+- *
+- * (06/06/2001) gkh
+- *	added evil hack that is needed for the prolific pl2303 device due to the
+- *	crazy way its endpoints are set up.
+- *
+- * (05/30/2001) gkh
+- *	switched from using spinlock to a semaphore, which fixes lots of problems.
+- *
+- * (04/08/2001) gb
+- *	Identify version on module load.
+- *
+- * 2001_02_05 gkh
+- *	Fixed buffer overflows bug with the generic serial driver.  Thanks to
+- *	Todd Squires <squirest at ct0.com> for fixing this.
+- *
+- * (01/10/2001) gkh
+- *	Fixed bug where the generic serial adaptor grabbed _any_ device that was
+- *	offered to it.
+- *
+- * (12/12/2000) gkh
+- *	Removed MOD_INC and MOD_DEC from poll and disconnect functions, and
+- *	moved them to the serial_open and serial_close functions.
+- *	Also fixed bug with there not being a MOD_DEC for the generic driver
+- *	(thanks to Gary Brubaker for finding this.)
+- *
+- * (11/29/2000) gkh
+- *	Small NULL pointer initialization cleanup which saves a bit of disk image
+- *
+- * (11/01/2000) Adam J. Richter
+- *	instead of using idVendor/idProduct pairs, usb serial drivers
+- *	now identify their hardware interest with usb_device_id tables,
+- *	which they usually have anyhow for use with MODULE_DEVICE_TABLE.
+- *
+- * (10/05/2000) gkh
+- *	Fixed bug with urb->dev not being set properly, now that the usb
+- *	core needs it.
+- * 
+- * (09/11/2000) gkh
+- *	Removed DEBUG #ifdefs with call to usb_serial_debug_data
+- *
+- * (08/28/2000) gkh
+- *	Added port_lock to port structure.
+- *	Added locks for SMP safeness to generic driver
+- *	Fixed the ability to open a generic device's port more than once.
+- *
+- * (07/23/2000) gkh
+- *	Added bulk_out_endpointAddress to port structure.
+- *
+- * (07/19/2000) gkh, pberger, and borchers
+- *	Modifications to allow usb-serial drivers to be modules.
+- *
+- * (07/03/2000) gkh
+- *	Added more debugging to serial_ioctl call
+- * 
+- * (06/25/2000) gkh
+- *	Changed generic_write_bulk_callback to not call wake_up_interruptible
+- *	directly, but to have port_softint do it at a safer time.
+- *
+- * (06/23/2000) gkh
+- *	Cleaned up debugging statements in a quest to find UHCI timeout bug.
+- *
+- * (05/22/2000) gkh
+- *	Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be 
+- *	removed from the individual device source files.
+- *
+- * (05/03/2000) gkh
+- *	Added the Digi Acceleport driver from Al Borchers and Peter Berger.
+- * 
+- * (05/02/2000) gkh
+- *	Changed devfs and tty register code to work properly now. This was based on
+- *	the ACM driver changes by Vojtech Pavlik.
+- *
+- * (04/27/2000) Ryan VanderBijl
+- * 	Put calls to *_paranoia_checks into one function.
+- * 
+- * (04/23/2000) gkh
+- *	Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports.
+- *	Moved when the startup code printed out the devices that are supported.
+- *
+- * (04/19/2000) gkh
+- *	Added driver for ZyXEL omni.net lcd plus ISDN TA
+- *	Made startup info message specify which drivers were compiled in.
+- *
+- * (04/03/2000) gkh
+- *	Changed the probe process to remove the module unload races.
+- *	Changed where the tty layer gets initialized to have devfs work nicer.
+- *	Added initial devfs support.
+- *
+- * (03/26/2000) gkh
+- *	Split driver up into device specific pieces.
+- * 
+- * (03/19/2000) gkh
+- *	Fixed oops that could happen when device was removed while a program
+- *	was talking to the device.
+- *	Removed the static urbs and now all urbs are created and destroyed
+- *	dynamically.
+- *	Reworked the internal interface. Now everything is based on the 
+- *	usb_serial_port structure instead of the larger usb_serial structure.
+- *	This fixes the bug that a multiport device could not have more than
+- *	one port open at one time.
+- *
+- * (03/17/2000) gkh
+- *	Added config option for debugging messages.
+- *	Added patch for keyspan pda from Brian Warner.
+- *
+- * (03/06/2000) gkh
+- *	Added the keyspan pda code from Brian Warner <warner at lothar.com>
+- *	Moved a bunch of the port specific stuff into its own structure. This
+- *	is in anticipation of the true multiport devices (there's a bug if you
+- *	try to access more than one port of any multiport device right now)
+- *
+- * (02/21/2000) gkh
+- *	Made it so that any serial devices only have to specify which functions
+- *	they want to overload from the generic function calls (great, 
+- *	inheritance in C, in a driver, just what I wanted...)
+- *	Added support for set_termios and ioctl function calls. No drivers take
+- *	advantage of this yet.
+- *	Removed the #ifdef MODULE, now there is no module specific code.
+- *	Cleaned up a few comments in usb-serial.h that were wrong (thanks again
+- *	to Miles Lott).
+- *	Small fix to get_free_serial.
+- *
+- * (02/14/2000) gkh
+- *	Removed the Belkin and Peracom functionality from the driver due to
+- *	the lack of support from the vendor, and me not wanting people to 
+- *	accidenatly buy the device, expecting it to work with Linux.
+- *	Added read_bulk_callback and write_bulk_callback to the type structure
+- *	for the needs of the FTDI and WhiteHEAT driver.
+- *	Changed all reverences to FTDI to FTDI_SIO at the request of Bill
+- *	Ryder.
+- *	Changed the output urb size back to the max endpoint size to make
+- *	the ftdi_sio driver have it easier, and due to the fact that it didn't
+- *	really increase the speed any.
+- *
+- * (02/11/2000) gkh
+- *	Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a
+- *	patch from Miles Lott (milos at insync.net).
+- *	Fixed bug with not restoring the minor range that a device grabs, if
+- *	the startup function fails (thanks Miles for finding this).
+- *
+- * (02/05/2000) gkh
+- *	Added initial framework for the Keyspan PDA serial converter so that
+- *	Brian Warner has a place to put his code.
+- *	Made the ezusb specific functions generic enough that different
+- *	devices can use them (whiteheat and keyspan_pda both need them).
+- *	Split out a whole bunch of structure and other stuff to a separate
+- *	usb-serial.h file.
+- *	Made the Visor connection messages a little more understandable, now
+- *	that Miles Lott (milos at insync.net) has gotten the Generic channel to
+- *	work. Also made them always show up in the log file.
+- * 
+- * (01/25/2000) gkh
+- *	Added initial framework for FTDI serial converter so that Bill Ryder
+- *	has a place to put his code.
+- *	Added the vendor specific info from Handspring. Now we can print out
+- *	informational debug messages as well as understand what is happening.
+- *
+- * (01/23/2000) gkh
+- *	Fixed problem of crash when trying to open a port that didn't have a
+- *	device assigned to it. Made the minor node finding a little smarter,
+- *	now it looks to find a continuous space for the new device.
+- *
+- * (01/21/2000) gkh
+- *	Fixed bug in visor_startup with patch from Miles Lott (milos at insync.net)
+- *	Fixed get_serial_by_minor which was all messed up for multi port 
+- *	devices. Fixed multi port problem for generic devices. Now the number
+- *	of ports is determined by the number of bulk out endpoints for the
+- *	generic device.
+- *
+- * (01/19/2000) gkh
+- *	Removed lots of cruft that was around from the old (pre urb) driver 
+- *	interface.
+- *	Made the serial_table dynamic. This should save lots of memory when
+- *	the number of minor nodes goes up to 256.
+- *	Added initial support for devices that have more than one port. 
+- *	Added more debugging comments for the Visor, and added a needed 
+- *	set_configuration call.
+- *
+- * (01/17/2000) gkh
+- *	Fixed the WhiteHEAT firmware (my processing tool had a bug)
+- *	and added new debug loader firmware for it.
+- *	Removed the put_char function as it isn't really needed.
+- *	Added visor startup commands as found by the Win98 dump.
+- * 
+- * (01/13/2000) gkh
+- *	Fixed the vendor id for the generic driver to the one I meant it to be.
+- *
+- * (01/12/2000) gkh
+- *	Forget the version numbering...that's pretty useless...
+- *	Made the driver able to be compiled so that the user can select which
+- *	converter they want to use. This allows people who only want the Visor
+- *	support to not pay the memory size price of the WhiteHEAT.
+- *	Fixed bug where the generic driver (idVendor=0000 and idProduct=0000)
+- *	grabbed the root hub. Not good.
+- * 
+- * version 0.4.0 (01/10/2000) gkh
+- *	Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT
+- *	device. Added startup function to allow firmware to be downloaded to
+- *	a device if it needs to be.
+- *	Added firmware download logic to the WhiteHEAT device.
+- *	Started to add #defines to split up the different drivers for potential
+- *	configuration option.
+- *	
+- * version 0.3.1 (12/30/99) gkh
+- *      Fixed problems with urb for bulk out.
+- *      Added initial support for multiple sets of endpoints. This enables
+- *      the Handspring Visor to be attached successfully. Only the first
+- *      bulk in / bulk out endpoint pair is being used right now.
+- *
+- * version 0.3.0 (12/27/99) gkh
+- *	Added initial support for the Handspring Visor based on a patch from
+- *	Miles Lott (milos at sneety.insync.net)
+- *	Cleaned up the code a bunch and converted over to using urbs only.
+- *
+- * version 0.2.3 (12/21/99) gkh
+- *	Added initial support for the Connect Tech WhiteHEAT converter.
+- *	Incremented the number of ports in expectation of getting the
+- *	WhiteHEAT to work properly (4 ports per connection).
+- *	Added notification on insertion and removal of what port the
+- *	device is/was connected to (and what kind of device it was).
+- *
+- * version 0.2.2 (12/16/99) gkh
+- *	Changed major number to the new allocated number. We're legal now!
+- *
+- * version 0.2.1 (12/14/99) gkh
+- *	Fixed bug that happens when device node is opened when there isn't a
+- *	device attached to it. Thanks to marek at webdesign.no for noticing this.
+- *
+- * version 0.2.0 (11/10/99) gkh
+- *	Split up internals to make it easier to add different types of serial 
+- *	converters to the code.
+- *	Added a "generic" driver that gets it's vendor and product id
+- *	from when the module is loaded. Thanks to David E. Nelson (dnelson at jump.net)
+- *	for the idea and sample code (from the usb scanner driver.)
+- *	Cleared up any licensing questions by releasing it under the GNU GPL.
+- *
+- * version 0.1.2 (10/25/99) gkh
+- * 	Fixed bug in detecting device.
+- *
+- * version 0.1.1 (10/05/99) gkh
+- * 	Changed the major number to not conflict with anything else.
+- *
+- * version 0.1 (09/28/99) gkh
+- * 	Can recognize the two different devices and start up a read from
+- *	device when asked to. Writes also work. No control signals yet, this
+- *	all is vendor specific data (i.e. no spec), also no control for
+- *	different baud rates or other bit settings.
+- *	Currently we are using the same devid as the acm driver. This needs
+- *	to change.
+- * 
+  */
+ 
+ #include <linux/config.h>
+@@ -342,7 +37,6 @@
+ /*
+  * Version Information
+  */
+-#define DRIVER_VERSION "v2.0"
+ #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg at kroah.com, http://www.kroah.com/linux/"
+ #define DRIVER_DESC "USB Serial Driver core"
+ 
+@@ -427,7 +121,7 @@ static void destroy_serial(struct kref *
+ 
+ 	serial = to_usb_serial(kref);
+ 
+-	dbg ("%s - %s", __FUNCTION__, serial->type->name);
++	dbg("%s - %s", __FUNCTION__, serial->type->description);
+ 
+ 	serial->type->shutdown(serial);
+ 
+@@ -507,7 +201,7 @@ static int serial_open (struct tty_struc
+ 		/* lock this module before we call it
+ 		 * this may fail, which means we must bail out,
+ 		 * safe because we are called with BKL held */
+-		if (!try_module_get(serial->type->owner)) {
++		if (!try_module_get(serial->type->driver.owner)) {
+ 			retval = -ENODEV;
+ 			goto bailout_kref_put;
+ 		}
+@@ -522,7 +216,7 @@ static int serial_open (struct tty_struc
+ 	return 0;
+ 
+ bailout_module_put:
+-	module_put(serial->type->owner);
++	module_put(serial->type->driver.owner);
+ bailout_kref_put:
+ 	kref_put(&serial->kref, destroy_serial);
+ 	port->open_count = 0;
+@@ -553,7 +247,7 @@ static void serial_close(struct tty_stru
+ 			port->tty = NULL;
+ 		}
+ 
+-		module_put(port->serial->type->owner);
++		module_put(port->serial->type->driver.owner);
+ 	}
+ 
+ 	kref_put(&port->serial->kref, destroy_serial);
+@@ -711,16 +405,16 @@ static int serial_read_proc (char *page,
+ 	char tmp[40];
+ 
+ 	dbg("%s", __FUNCTION__);
+-	length += sprintf (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION);
++	length += sprintf (page, "usbserinfo:1.0 driver:2.0\n");
+ 	for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
+ 		serial = usb_serial_get_by_index(i);
+ 		if (serial == NULL)
+ 			continue;
+ 
+ 		length += sprintf (page+length, "%d:", i);
+-		if (serial->type->owner)
+-			length += sprintf (page+length, " module:%s", module_name(serial->type->owner));
+-		length += sprintf (page+length, " name:\"%s\"", serial->type->name);
++		if (serial->type->driver.owner)
++			length += sprintf (page+length, " module:%s", module_name(serial->type->driver.owner));
++		length += sprintf (page+length, " name:\"%s\"", serial->type->description);
+ 		length += sprintf (page+length, " vendor:%04x product:%04x", 
+ 				   le16_to_cpu(serial->dev->descriptor.idVendor), 
+ 				   le16_to_cpu(serial->dev->descriptor.idProduct));
+@@ -823,7 +517,7 @@ static void port_release(struct device *
+ 
+ static struct usb_serial * create_serial (struct usb_device *dev, 
+ 					  struct usb_interface *interface,
+-					  struct usb_serial_device_type *type)
++					  struct usb_serial_driver *driver)
+ {
+ 	struct usb_serial *serial;
+ 
+@@ -834,22 +528,22 @@ static struct usb_serial * create_serial
+ 	}
+ 	memset (serial, 0, sizeof(*serial));
+ 	serial->dev = usb_get_dev(dev);
+-	serial->type = type;
++	serial->type = driver;
+ 	serial->interface = interface;
+ 	kref_init(&serial->kref);
+ 
+ 	return serial;
+ }
+ 
+-static struct usb_serial_device_type *search_serial_device(struct usb_interface *iface)
++static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
+ {
+ 	struct list_head *p;
+ 	const struct usb_device_id *id;
+-	struct usb_serial_device_type *t;
++	struct usb_serial_driver *t;
+ 
+ 	/* List trough know devices and see if the usb id matches */
+ 	list_for_each(p, &usb_serial_driver_list) {
+-		t = list_entry(p, struct usb_serial_device_type, driver_list);
++		t = list_entry(p, struct usb_serial_driver, driver_list);
+ 		id = usb_match_id(iface, t->id_table);
+ 		if (id != NULL) {
+ 			dbg("descriptor matches");
+@@ -872,7 +566,7 @@ int usb_serial_probe(struct usb_interfac
+ 	struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS];
+ 	struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
+ 	struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
+-	struct usb_serial_device_type *type = NULL;
++	struct usb_serial_driver *type = NULL;
+ 	int retval;
+ 	int minor;
+ 	int buffer_size;
+@@ -900,7 +594,7 @@ int usb_serial_probe(struct usb_interfac
+ 	if (type->probe) {
+ 		const struct usb_device_id *id;
+ 
+-		if (!try_module_get(type->owner)) {
++		if (!try_module_get(type->driver.owner)) {
+ 			dev_err(&interface->dev, "module get failed, exiting\n");
+ 			kfree (serial);
+ 			return -EIO;
+@@ -908,7 +602,7 @@ int usb_serial_probe(struct usb_interfac
+ 
+ 		id = usb_match_id(interface, type->id_table);
+ 		retval = type->probe(serial, id);
+-		module_put(type->owner);
++		module_put(type->driver.owner);
+ 
+ 		if (retval) {
+ 			dbg ("sub driver rejected device");
+@@ -992,7 +686,7 @@ int usb_serial_probe(struct usb_interfac
+ #endif
+ 
+ 	/* found all that we need */
+-	dev_info(&interface->dev, "%s converter detected\n", type->name);
++	dev_info(&interface->dev, "%s converter detected\n", type->description);
+ 
+ #ifdef CONFIG_USB_SERIAL_GENERIC
+ 	if (type == &usb_serial_generic_device) {
+@@ -1007,13 +701,13 @@ int usb_serial_probe(struct usb_interfac
+ 	if (!num_ports) {
+ 		/* if this device type has a calc_num_ports function, call it */
+ 		if (type->calc_num_ports) {
+-			if (!try_module_get(type->owner)) {
++			if (!try_module_get(type->driver.owner)) {
+ 				dev_err(&interface->dev, "module get failed, exiting\n");
+ 				kfree (serial);
+ 				return -EIO;
+ 			}
+ 			num_ports = type->calc_num_ports (serial);
+-			module_put(type->owner);
++			module_put(type->driver.owner);
+ 		}
+ 		if (!num_ports)
+ 			num_ports = type->num_ports;
+@@ -1158,12 +852,12 @@ int usb_serial_probe(struct usb_interfac
+ 	
+ 	/* if this device type has an attach function, call it */
+ 	if (type->attach) {
+-		if (!try_module_get(type->owner)) {
++		if (!try_module_get(type->driver.owner)) {
+ 			dev_err(&interface->dev, "module get failed, exiting\n");
+ 			goto probe_error;
+ 		}
+ 		retval = type->attach (serial);
+-		module_put(type->owner);
++		module_put(type->driver.owner);
+ 		if (retval < 0)
+ 			goto probe_error;
+ 		if (retval > 0) {
+@@ -1330,7 +1024,7 @@ static int __init usb_serial_init(void)
+ 		goto exit_generic;
+ 	}
+ 
+-	info(DRIVER_DESC " " DRIVER_VERSION);
++	info(DRIVER_DESC);
+ 
+ 	return result;
+ 
+@@ -1375,7 +1069,7 @@ module_exit(usb_serial_exit);
+ 			}						\
+ 	} while (0)
+ 
+-static void fixup_generic(struct usb_serial_device_type *device)
++static void fixup_generic(struct usb_serial_driver *device)
+ {
+ 	set_to_generic_if_null(device, open);
+ 	set_to_generic_if_null(device, write);
+@@ -1387,30 +1081,33 @@ static void fixup_generic(struct usb_ser
+ 	set_to_generic_if_null(device, shutdown);
+ }
+ 
+-int usb_serial_register(struct usb_serial_device_type *new_device)
++int usb_serial_register(struct usb_serial_driver *driver)
+ {
+ 	int retval;
+ 
+-	fixup_generic(new_device);
++	fixup_generic(driver);
++
++	if (!driver->description)
++		driver->description = driver->driver.name;
+ 
+ 	/* Add this device to our list of devices */
+-	list_add(&new_device->driver_list, &usb_serial_driver_list);
++	list_add(&driver->driver_list, &usb_serial_driver_list);
+ 
+-	retval = usb_serial_bus_register(new_device);
++	retval = usb_serial_bus_register(driver);
+ 	if (retval) {
+-		err("problem %d when registering driver %s", retval, new_device->name);
+-		list_del(&new_device->driver_list);
++		err("problem %d when registering driver %s", retval, driver->description);
++		list_del(&driver->driver_list);
+ 	}
+ 	else
+-		info("USB Serial support registered for %s", new_device->name);
++		info("USB Serial support registered for %s", driver->description);
+ 
+ 	return retval;
+ }
+ 
+ 
+-void usb_serial_deregister(struct usb_serial_device_type *device)
++void usb_serial_deregister(struct usb_serial_driver *device)
+ {
+-	info("USB Serial deregistering driver %s", device->name);
++	info("USB Serial deregistering driver %s", device->description);
+ 	list_del(&device->driver_list);
+ 	usb_serial_bus_deregister(device);
+ }
+@@ -1429,7 +1126,6 @@ EXPORT_SYMBOL_GPL(usb_serial_port_softin
+ /* Module information */
+ MODULE_AUTHOR( DRIVER_AUTHOR );
+ MODULE_DESCRIPTION( DRIVER_DESC );
+-MODULE_VERSION( DRIVER_VERSION );
+ MODULE_LICENSE("GPL");
+ 
+ module_param(debug, bool, S_IRUGO | S_IWUSR);
+diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
+--- a/drivers/usb/serial/usb-serial.h
++++ b/drivers/usb/serial/usb-serial.h
+@@ -1,53 +1,13 @@
+ /*
+  * USB Serial Converter driver
+  *
+- *	Copyright (C) 1999 - 2004
++ *	Copyright (C) 1999 - 2005
+  *	    Greg Kroah-Hartman (greg at 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; either version 2 of the License, or
+- *	(at your option) any later version.
++ *	the Free Software Foundation; either version 2 of the License.
+  *
+- * See Documentation/usb/usb-serial.txt for more information on using this driver
+- *
+- * (03/26/2002) gkh
+- *	removed the port->tty check from port_paranoia_check() due to serial
+- *	consoles not having a tty device assigned to them.
+- *
+- * (12/03/2001) gkh
+- *	removed active from the port structure.
+- *	added documentation to the usb_serial_device_type structure
+- *
+- * (10/10/2001) gkh
+- *	added vendor and product to serial structure.  Needed to determine device
+- *	owner when the device is disconnected.
+- *
+- * (05/30/2001) gkh
+- *	added sem to port structure and removed port_lock
+- *
+- * (10/05/2000) gkh
+- *	Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help
+- *	fix bug with urb->dev not being set properly, now that the usb core
+- *	needs it.
+- * 
+- * (09/11/2000) gkh
+- *	Added usb_serial_debug_data function to help get rid of #DEBUG in the
+- *	drivers.
+- *
+- * (08/28/2000) gkh
+- *	Added port_lock to port structure.
+- *
+- * (08/08/2000) gkh
+- *	Added open_count to port structure.
+- *
+- * (07/23/2000) gkh
+- *	Added bulk_out_endpointAddress to port structure.
+- *
+- * (07/19/2000) gkh, pberger, and borchers
+- *	Modifications to allow usb-serial drivers to be modules.
+- *
+- * 
+  */
+ 
+ 
+@@ -143,7 +103,7 @@ static inline void usb_set_serial_port_d
+ /**
+  * 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_device_type 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
+@@ -159,7 +119,7 @@ static inline void usb_set_serial_port_d
+  */
+ struct usb_serial {
+ 	struct usb_device *		dev;
+-	struct usb_serial_device_type *	type;
++	struct usb_serial_driver *	type;
+ 	struct usb_interface *		interface;
+ 	unsigned char			minor;
+ 	unsigned char			num_ports;
+@@ -188,13 +148,9 @@ static inline void usb_set_serial_data (
+ }
+ 
+ /**
+- * usb_serial_device_type - a structure that defines a usb serial device
+- * @owner: pointer to the module that owns this device.
+- * @name: pointer to a string that describes this device.  This string used
++ * 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.
+- * @short_name: a pointer to a string that describes this device in
+- *	KOBJ_NAME_LEN characters or less.  This is used for the sysfs interface
+- *	to describe the driver.
+  * @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
+@@ -221,16 +177,19 @@ static inline void usb_set_serial_data (
+  * @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 device.  It provides all of
++ * 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_device_type {
+-	struct module *owner;
+-	char	*name;
+-	char	*short_name;
++struct usb_serial_driver {
++	const char *description;
+ 	const struct usb_device_id *id_table;
+ 	char	num_interrupt_in;
+ 	char	num_interrupt_out;
+@@ -269,10 +228,10 @@ struct usb_serial_device_type {
+ 	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_device_type, driver)
++#define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver)
+ 
+-extern int  usb_serial_register(struct usb_serial_device_type *new_device);
+-extern void usb_serial_deregister(struct usb_serial_device_type *device);
++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(void *private);
+ 
+ extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
+@@ -303,10 +262,10 @@ extern void usb_serial_generic_shutdown 
+ extern int usb_serial_generic_register (int debug);
+ extern void usb_serial_generic_deregister (void);
+ 
+-extern int usb_serial_bus_register (struct usb_serial_device_type *device);
+-extern void usb_serial_bus_deregister (struct usb_serial_device_type *device);
++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_device_type usb_serial_generic_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;
+ 
+diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
+--- a/drivers/usb/serial/visor.c
++++ b/drivers/usb/serial/visor.c
+@@ -7,139 +7,10 @@
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+- *	the Free Software Foundation; either version 2 of the License, or
+- *	(at your option) any later version.
++ *	the Free Software Foundation; either version 2 of the License.
+  *
+  * See Documentation/usb/usb-serial.txt for more information on using this driver
+  *
+- * (06/03/2003) Judd Montgomery <judd at jpilot.org>
+- *     Added support for module parameter options for untested/unknown
+- *     devices.
+- *
+- * (03/09/2003) gkh
+- *	Added support for the Sony Clie NZ90V device.  Thanks to Martin Brachtl
+- *	<brachtl at redgrep.cz> for the information.
+- *
+- * (03/05/2003) gkh
+- *	Think Treo support is now working.
+- *
+- * (04/03/2002) gkh
+- *	Added support for the Sony OS 4.1 devices.  Thanks to Hiroyuki ARAKI
+- *	<hiro at zob.ne.jp> for the information.
+- *
+- * (03/27/2002) gkh
+- *	Removed assumptions that port->tty was always valid (is not true
+- *	for usb serial console devices.)
+- *
+- * (03/23/2002) gkh
+- *	Added support for the Palm i705 device, thanks to Thomas Riemer
+- *	<tom at netmech.com> for the information.
+- *
+- * (03/21/2002) gkh
+- *	Added support for the Palm m130 device, thanks to Udo Eisenbarth
+- *	<udo.eisenbarth at web.de> for the information.
+- *
+- * (02/27/2002) gkh
+- *	Reworked the urb handling logic.  We have no more pool, but dynamically
+- *	allocate the urb and the transfer buffer on the fly.  In testing this
+- *	does not incure any measurable overhead.  This also relies on the fact
+- *	that we have proper reference counting logic for urbs.
+- *
+- * (02/21/2002) SilaS
+- *  Added initial support for the Palm m515 devices.
+- *
+- * (02/14/2002) gkh
+- *	Added support for the Clie S-360 device.
+- *
+- * (12/18/2001) gkh
+- *	Added better Clie support for 3.5 devices.  Thanks to Geoffrey Levand
+- *	for the patch.
+- *
+- * (11/11/2001) gkh
+- *	Added support for the m125 devices, and added check to prevent oopses
+- *	for Clié devices that lie about the number of ports they have.
+- *
+- * (08/30/2001) gkh
+- *	Added support for the Clie devices, both the 3.5 and 4.0 os versions.
+- *	Many thanks to Daniel Burke, and Bryan Payne for helping with this.
+- *
+- * (08/23/2001) gkh
+- *	fixed a few potential bugs pointed out by Oliver Neukum.
+- *
+- * (05/30/2001) gkh
+- *	switched from using spinlock to a semaphore, which fixes lots of problems.
+- *
+- * (05/28/2000) gkh
+- *	Added initial support for the Palm m500 and Palm m505 devices.
+- *
+- * (04/08/2001) gb
+- *	Identify version on module load.
+- *
+- * (01/21/2000) gkh
+- *	Added write_room and chars_in_buffer, as they were previously using the
+- *	generic driver versions which is all wrong now that we are using an urb
+- *	pool.  Thanks to Wolfgang Grandegger for pointing this out to me.
+- *	Removed count assignment in the write function, which was not needed anymore
+- *	either.  Thanks to Al Borchers for pointing this out.
+- *
+- * (12/12/2000) gkh
+- *	Moved MOD_DEC to end of visor_close to be nicer, as the final write 
+- *	message can sleep.
+- * 
+- * (11/12/2000) gkh
+- *	Fixed bug with data being dropped on the floor by forcing tty->low_latency
+- *	to be on.  Hopefully this fixes the OHCI issue!
+- *
+- * (11/01/2000) Adam J. Richter
+- *	usb_device_id table support
+- * 
+- * (10/05/2000) gkh
+- *	Fixed bug with urb->dev not being set properly, now that the usb
+- *	core needs it.
+- * 
+- * (09/11/2000) gkh
+- *	Got rid of always calling kmalloc for every urb we wrote out to the
+- *	device.
+- *	Added visor_read_callback so we can keep track of bytes in and out for
+- *	those people who like to know the speed of their device.
+- *	Removed DEBUG #ifdefs with call to usb_serial_debug_data
+- *
+- * (09/06/2000) gkh
+- *	Fixed oops in visor_exit.  Need to uncomment usb_unlink_urb call _after_
+- *	the host controller drivers set urb->dev = NULL when the urb is finished.
+- *
+- * (08/28/2000) gkh
+- *	Added locks for SMP safeness.
+- *
+- * (08/08/2000) gkh
+- *	Fixed endian problem in visor_startup.
+- *	Fixed MOD_INC and MOD_DEC logic and the ability to open a port more 
+- *	than once.
+- * 
+- * (07/23/2000) gkh
+- *	Added pool of write urbs to speed up transfers to the visor.
+- * 
+- * (07/19/2000) gkh
+- *	Added module_init and module_exit functions to handle the fact that this
+- *	driver is a loadable module now.
+- *
+- * (07/03/2000) gkh
+- *	Added visor_set_ioctl and visor_set_termios functions (they don't do much
+- *	of anything, but are good for debugging.)
+- * 
+- * (06/25/2000) gkh
+- *	Fixed bug in visor_unthrottle that should help with the disconnect in PPP
+- *	bug that people have been reporting.
+- *
+- * (06/23/2000) gkh
+- *	Cleaned up debugging statements in a quest to find UHCI timeout bug.
+- *
+- * (04/27/2000) Ryan VanderBijl
+- * 	Fixed memory leak in visor_close
+- *
+- * (03/26/2000) gkh
+- *	Split driver up into device specific pieces.
+- * 
+  */
+ 
+ #include <linux/config.h>
+@@ -161,7 +32,6 @@
+ /*
+  * Version Information
+  */
+-#define DRIVER_VERSION "v2.1"
+ #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg at kroah.com>"
+ #define DRIVER_DESC "USB HandSpring Visor / Palm OS driver"
+ 
+@@ -311,10 +181,12 @@ static struct usb_driver visor_driver = 
+ };
+ 
+ /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
+-static struct usb_serial_device_type handspring_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Handspring Visor / Palm OS",
+-	.short_name =		"visor",
++static struct usb_serial_driver handspring_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"visor",
++	},
++	.description =		"Handspring Visor / Palm OS",
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		2,
+@@ -339,10 +211,12 @@ static struct usb_serial_device_type han
+ };
+ 
+ /* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */
+-static struct usb_serial_device_type clie_5_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Sony Clie 5.0",
+-	.short_name =		"clie_5",
++static struct usb_serial_driver clie_5_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"clie_5",
++	},
++	.description =		"Sony Clie 5.0",
+ 	.id_table =		clie_id_5_table,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		2,
+@@ -367,10 +241,12 @@ static struct usb_serial_device_type cli
+ };
+ 
+ /* device info for the Sony Clie OS version 3.5 */
+-static struct usb_serial_device_type clie_3_5_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Sony Clie 3.5",
+-	.short_name =		"clie_3.5",
++static struct usb_serial_driver clie_3_5_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"clie_3.5",
++	},
++	.description =		"Sony Clie 3.5",
+ 	.id_table =		clie_id_3_5_table,
+ 	.num_interrupt_in =	0,
+ 	.num_bulk_in =		1,
+@@ -782,7 +658,7 @@ static int palm_os_3_probe (struct usb_s
+ 					break;
+ 			}
+ 			dev_info(dev, "%s: port %d, is for %s use\n",
+-				serial->type->name,
++				serial->type->description,
+ 				connection_info->connections[i].port, string);
+ 		}
+ 	}
+@@ -791,11 +667,11 @@ static int palm_os_3_probe (struct usb_s
+ 	*/
+ 	if (num_ports == 0 || num_ports > 2) {
+ 		dev_warn (dev, "%s: No valid connect info available\n",
+-			serial->type->name);
++			serial->type->description);
+ 		num_ports = 2;
+ 	}
+   
+-	dev_info(dev, "%s: Number of ports: %d\n", serial->type->name,
++	dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,
+ 		num_ports);
+ 
+ 	/*
+@@ -1125,7 +1001,7 @@ static int __init visor_init (void)
+ 	retval = usb_register(&visor_driver);
+ 	if (retval) 
+ 		goto failed_usb_register;
+-	info(DRIVER_DESC " " DRIVER_VERSION);
++	info(DRIVER_DESC);
+ 
+ 	return 0;
+ failed_usb_register:
+diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
+--- a/drivers/usb/serial/whiteheat.c
++++ b/drivers/usb/serial/whiteheat.c
+@@ -156,10 +156,12 @@ static void whiteheat_unthrottle	(struct
+ static void whiteheat_read_callback	(struct urb *urb, struct pt_regs *regs);
+ static void whiteheat_write_callback	(struct urb *urb, struct pt_regs *regs);
+ 
+-static struct usb_serial_device_type whiteheat_fake_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Connect Tech - WhiteHEAT - (prerenumeration)",
+-	.short_name =		"whiteheatnofirm",
++static struct usb_serial_driver whiteheat_fake_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"whiteheatnofirm",
++	},
++	.description =		"Connect Tech - WhiteHEAT - (prerenumeration)",
+ 	.id_table =		id_table_prerenumeration,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		NUM_DONT_CARE,
+@@ -169,10 +171,12 @@ static struct usb_serial_device_type whi
+ 	.attach =		whiteheat_firmware_attach,
+ };
+ 
+-static struct usb_serial_device_type whiteheat_device = {
+-	.owner =		THIS_MODULE,
+-	.name =			"Connect Tech - WhiteHEAT",
+-	.short_name =		"whiteheat",
++static struct usb_serial_driver whiteheat_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"whiteheat",
++	},
++	.description =		"Connect Tech - WhiteHEAT",
+ 	.id_table =		id_table_std,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		NUM_DONT_CARE,
+@@ -382,10 +386,10 @@ static int whiteheat_attach (struct usb_
+ 	usb_clear_halt(serial->dev, pipe);
+ 	ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS);
+ 	if (ret) {
+-		err("%s: Couldn't send command [%d]", serial->type->name, ret);
++		err("%s: Couldn't send command [%d]", serial->type->description, ret);
+ 		goto no_firmware;
+ 	} else if (alen != sizeof(command)) {
+-		err("%s: Send command incomplete [%d]", serial->type->name, alen);
++		err("%s: Send command incomplete [%d]", serial->type->description, alen);
+ 		goto no_firmware;
+ 	}
+ 
+@@ -394,19 +398,19 @@ static int whiteheat_attach (struct usb_
+ 	usb_clear_halt(serial->dev, pipe);
+ 	ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
+ 	if (ret) {
+-		err("%s: Couldn't get results [%d]", serial->type->name, ret);
++		err("%s: Couldn't get results [%d]", serial->type->description, ret);
+ 		goto no_firmware;
+ 	} else if (alen != sizeof(result)) {
+-		err("%s: Get results incomplete [%d]", serial->type->name, alen);
++		err("%s: Get results incomplete [%d]", serial->type->description, alen);
+ 		goto no_firmware;
+ 	} else if (result[0] != command[0]) {
+-		err("%s: Command failed [%d]", serial->type->name, result[0]);
++		err("%s: Command failed [%d]", serial->type->description, result[0]);
+ 		goto no_firmware;
+ 	}
+ 
+ 	hw_info = (struct whiteheat_hw_info *)&result[1];
+ 
+-	info("%s: Driver %s: Firmware v%d.%02d", serial->type->name,
++	info("%s: Driver %s: Firmware v%d.%02d", serial->type->description,
+ 	     DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);
+ 
+ 	for (i = 0; i < serial->num_ports; i++) {
+@@ -414,7 +418,7 @@ static int whiteheat_attach (struct usb_
+ 
+ 		info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
+ 		if (info == NULL) {
+-			err("%s: Out of memory for port structures\n", serial->type->name);
++			err("%s: Out of memory for port structures\n", serial->type->description);
+ 			goto no_private;
+ 		}
+ 
+@@ -484,7 +488,7 @@ static int whiteheat_attach (struct usb_
+ 
+ 	command_info = (struct whiteheat_command_private *)kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
+ 	if (command_info == NULL) {
+-		err("%s: Out of memory for port structures\n", serial->type->name);
++		err("%s: Out of memory for port structures\n", serial->type->description);
+ 		goto no_command_private;
+ 	}
+ 
+@@ -501,9 +505,9 @@ static int whiteheat_attach (struct usb_
+ 
+ no_firmware:
+ 	/* Firmware likely not running */
+-	err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name);
+-	err("%s: If the firmware is not running (status led not blinking)\n", serial->type->name);
+-	err("%s: please contact support at connecttech.com\n", serial->type->name);
++	err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->description);
++	err("%s: If the firmware is not running (status led not blinking)\n", serial->type->description);
++	err("%s: please contact support at connecttech.com\n", serial->type->description);
+ 	return -ENODEV;
+ 
+ no_command_private:
+diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
+--- a/drivers/usb/storage/Kconfig
++++ b/drivers/usb/storage/Kconfig
+@@ -2,7 +2,8 @@
+ # USB Storage driver configuration
+ #
+ 
+-comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information"
++comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'"
++comment "may also be needed; see USB_STORAGE Help for more information"
+ 	depends on USB
+ 
+ config USB_STORAGE
+diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
+--- a/drivers/usb/storage/onetouch.c
++++ b/drivers/usb/storage/onetouch.c
+@@ -5,7 +5,7 @@
+  *	Copyright (c) 2005 Nick Sillik <n.sillik at temple.edu>
+  *
+  * Initial work by:
+- * 	Copyright (c) 2003 Erik Thyren <erth7411 at student.uu.se>
++ *	Copyright (c) 2003 Erik Thyren <erth7411 at student.uu.se>
+  *
+  * Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann)
+  *
+@@ -46,7 +46,7 @@ void onetouch_release_input(void *onetou
+ struct usb_onetouch {
+ 	char name[128];
+ 	char phys[64];
+-	struct input_dev dev;	/* input device interface */
++	struct input_dev *dev;	/* input device interface */
+ 	struct usb_device *udev;	/* usb device */
+ 
+ 	struct urb *irq;	/* urb for interrupt in report */
+@@ -58,7 +58,7 @@ static void usb_onetouch_irq(struct urb 
+ {
+ 	struct usb_onetouch *onetouch = urb->context;
+ 	signed char *data = onetouch->data;
+-	struct input_dev *dev = &onetouch->dev;
++	struct input_dev *dev = onetouch->dev;
+ 	int status;
+ 
+ 	switch (urb->status) {
+@@ -74,11 +74,9 @@ static void usb_onetouch_irq(struct urb 
+ 	}
+ 
+ 	input_regs(dev, regs);
+-
+-	input_report_key(&onetouch->dev, ONETOUCH_BUTTON,
+-			 data[0] & 0x02);
+-
++	input_report_key(dev, ONETOUCH_BUTTON, data[0] & 0x02);
+ 	input_sync(dev);
++
+ resubmit:
+ 	status = usb_submit_urb (urb, SLAB_ATOMIC);
+ 	if (status)
+@@ -113,8 +111,8 @@ int onetouch_connect_input(struct us_dat
+ 	struct usb_host_interface *interface;
+ 	struct usb_endpoint_descriptor *endpoint;
+ 	struct usb_onetouch *onetouch;
++	struct input_dev *input_dev;
+ 	int pipe, maxp;
+-	char path[64];
+ 
+ 	interface = ss->pusb_intf->cur_altsetting;
+ 
+@@ -122,62 +120,62 @@ int onetouch_connect_input(struct us_dat
+ 		return -ENODEV;
+ 
+ 	endpoint = &interface->endpoint[2].desc;
+-	if(!(endpoint->bEndpointAddress & USB_DIR_IN))
++	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
+ 		return -ENODEV;
+-	if((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
++	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ 			!= USB_ENDPOINT_XFER_INT)
+ 		return -ENODEV;
+ 
+ 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+ 	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+ 
+-	if (!(onetouch = kcalloc(1, sizeof(struct usb_onetouch), GFP_KERNEL)))
+-		return -ENOMEM;
++	onetouch = kzalloc(sizeof(struct usb_onetouch), GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!onetouch || !input_dev)
++		goto fail1;
+ 
+ 	onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
+ 					  SLAB_ATOMIC, &onetouch->data_dma);
+-	if (!onetouch->data){
+-		kfree(onetouch);
+-		return -ENOMEM;
+-	}
++	if (!onetouch->data)
++		goto fail1;
+ 
+ 	onetouch->irq = usb_alloc_urb(0, GFP_KERNEL);
+-	if (!onetouch->irq){
+-		kfree(onetouch);
+-		usb_buffer_free(udev, ONETOUCH_PKT_LEN,
+-				onetouch->data, onetouch->data_dma);
+-		return -ENODEV;
+-	}
+-
++	if (!onetouch->irq)
++		goto fail2;
+ 
+ 	onetouch->udev = udev;
+-
+-	set_bit(EV_KEY, onetouch->dev.evbit);
+-	set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit);
+-	clear_bit(0, onetouch->dev.keybit);
+-
+-	onetouch->dev.private = onetouch;
+-	onetouch->dev.open = usb_onetouch_open;
+-	onetouch->dev.close = usb_onetouch_close;
+-
+-	usb_make_path(udev, path, sizeof(path));
+-	sprintf(onetouch->phys, "%s/input0", path);
+-
+-	onetouch->dev.name = onetouch->name;
+-	onetouch->dev.phys = onetouch->phys;
+-
+-	usb_to_input_id(udev, &onetouch->dev.id);
+-
+-	onetouch->dev.dev = &udev->dev;
++	onetouch->dev = input_dev;
+ 
+ 	if (udev->manufacturer)
+-		strcat(onetouch->name, udev->manufacturer);
+-	if (udev->product)
+-		sprintf(onetouch->name, "%s %s", onetouch->name,
+-			udev->product);
++		strlcpy(onetouch->name, udev->manufacturer,
++			sizeof(onetouch->name));
++	if (udev->product) {
++		if (udev->manufacturer)
++			strlcat(onetouch->name, " ", sizeof(onetouch->name));
++		strlcat(onetouch->name, udev->product, sizeof(onetouch->name));
++	}
++
+ 	if (!strlen(onetouch->name))
+-		sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x",
+-			onetouch->dev.id.vendor, onetouch->dev.id.product);
++		snprintf(onetouch->name, sizeof(onetouch->name),
++			 "Maxtor Onetouch %04x:%04x",
++			 le16_to_cpu(udev->descriptor.idVendor),
++			 le16_to_cpu(udev->descriptor.idProduct));
++
++	usb_make_path(udev, onetouch->phys, sizeof(onetouch->phys));
++	strlcat(onetouch->phys, "/input0", sizeof(onetouch->phys));
++
++	input_dev->name = onetouch->name;
++	input_dev->phys = onetouch->phys;
++	usb_to_input_id(udev, &input_dev->id);
++	input_dev->cdev.dev = &udev->dev;
++
++	set_bit(EV_KEY, input_dev->evbit);
++	set_bit(ONETOUCH_BUTTON, input_dev->keybit);
++	clear_bit(0, input_dev->keybit);
++
++	input_dev->private = onetouch;
++	input_dev->open = usb_onetouch_open;
++	input_dev->close = usb_onetouch_close;
+ 
+ 	usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data,
+ 			 (maxp > 8 ? 8 : maxp),
+@@ -188,10 +186,15 @@ int onetouch_connect_input(struct us_dat
+ 	ss->extra_destructor = onetouch_release_input;
+ 	ss->extra = onetouch;
+ 
+-	input_register_device(&onetouch->dev);
+-	printk(KERN_INFO "usb-input: %s on %s\n", onetouch->dev.name, path);
++	input_register_device(onetouch->dev);
+ 
+ 	return 0;
++
++ fail2:	usb_buffer_free(udev, ONETOUCH_PKT_LEN,
++			onetouch->data, onetouch->data_dma);
++ fail1:	kfree(onetouch);
++	input_free_device(input_dev);
++	return -ENOMEM;
+ }
+ 
+ void onetouch_release_input(void *onetouch_)
+@@ -200,11 +203,9 @@ void onetouch_release_input(void *onetou
+ 
+ 	if (onetouch) {
+ 		usb_kill_urb(onetouch->irq);
+-		input_unregister_device(&onetouch->dev);
++		input_unregister_device(onetouch->dev);
+ 		usb_free_urb(onetouch->irq);
+ 		usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
+ 				onetouch->data, onetouch->data_dma);
+-		printk(KERN_INFO "usb-input: deregistering %s\n",
+-				onetouch->dev.name);
+ 	}
+ }
+diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
+--- a/drivers/usb/storage/shuttle_usbat.c
++++ b/drivers/usb/storage/shuttle_usbat.c
+@@ -1,4 +1,4 @@
+-/* Driver for SCM Microsystems USB-ATAPI cable
++/* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
+  *
+  * $Id: shuttle_usbat.c,v 1.17 2002/04/22 03:39:43 mdharm Exp $
+  *
+@@ -67,10 +67,10 @@ static int usbat_flash_transport(struct 
+ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us);
+ 
+ /*
+- * Convenience function to produce an ATAPI read/write sectors command
++ * Convenience function to produce an ATA read/write sectors command
+  * Use cmd=0x20 for read, cmd=0x30 for write
+  */
+-static void usbat_pack_atapi_sector_cmd(unsigned char *buf,
++static void usbat_pack_ata_sector_cmd(unsigned char *buf,
+ 					unsigned char thistime,
+ 					u32 sector, unsigned char cmd)
+ {
+@@ -196,10 +196,12 @@ static int usbat_check_status(struct us_
+ 	if (rc != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_FAILED;
+ 
+-	if (*reply & 0x01 && *reply != 0x51) // error/check condition (0x51 is ok)
++	/* error/check condition (0x51 is ok) */
++	if (*reply & 0x01 && *reply != 0x51)
+ 		return USB_STOR_TRANSPORT_FAILED;
+ 
+-	if (*reply & 0x20) // device fault
++	/* device fault */
++	if (*reply & 0x20)
+ 		return USB_STOR_TRANSPORT_FAILED;
+ 
+ 	return USB_STOR_TRANSPORT_GOOD;
+@@ -222,29 +224,39 @@ static int usbat_set_shuttle_features(st
+ 	command[0] = 0x40;
+ 	command[1] = USBAT_CMD_SET_FEAT;
+ 
+-	// The only bit relevant to ATA access is bit 6
+-	// which defines 8 bit data access (set) or 16 bit (unset)
++	/*
++	 * The only bit relevant to ATA access is bit 6
++	 * which defines 8 bit data access (set) or 16 bit (unset)
++	 */
+ 	command[2] = epp_control;
+ 
+-	// If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1,
+-	// ET1 and ET2 define an external event to be checked for on event of a
+-	// _read_blocks or _write_blocks operation. The read/write will not take
+-	// place unless the defined trigger signal is active.
++	/*
++	 * If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1,
++	 * ET1 and ET2 define an external event to be checked for on event of a
++	 * _read_blocks or _write_blocks operation. The read/write will not take
++	 * place unless the defined trigger signal is active.
++	 */
+ 	command[3] = external_trigger;
+ 
+-	// The resultant byte of the mask operation (see mask_byte) is compared for
+-	// equivalence with this test pattern. If equal, the read/write will take
+-	// place.
++	/*
++	 * The resultant byte of the mask operation (see mask_byte) is compared for
++	 * equivalence with this test pattern. If equal, the read/write will take
++	 * place.
++	 */
+ 	command[4] = test_pattern;
+ 
+-	// This value is logically ANDed with the status register field specified
+-	// in the read/write command.
++	/*
++	 * This value is logically ANDed with the status register field specified
++	 * in the read/write command.
++	 */
+ 	command[5] = mask_byte;
+ 
+-	// If ALQ is set in the qualifier, this field contains the address of the
+-	// registers where the byte count should be read for transferring the data.
+-	// If ALQ is not set, then this field contains the number of bytes to be
+-	// transferred.
++	/*
++	 * If ALQ is set in the qualifier, this field contains the address of the
++	 * registers where the byte count should be read for transferring the data.
++	 * If ALQ is not set, then this field contains the number of bytes to be
++	 * transferred.
++	 */
+ 	command[6] = subcountL;
+ 	command[7] = subcountH;
+ 
+@@ -273,26 +285,26 @@ static int usbat_wait_not_busy(struct us
+ 
+ 		if (result!=USB_STOR_XFER_GOOD)
+ 			return USB_STOR_TRANSPORT_ERROR;
+-		if (*status & 0x01) { // check condition
++		if (*status & 0x01) { /* check condition */
+ 			result = usbat_read(us, USBAT_ATA, 0x10, status);
+ 			return USB_STOR_TRANSPORT_FAILED;
+ 		}
+-		if (*status & 0x20) // device fault
++		if (*status & 0x20) /* device fault */
+ 			return USB_STOR_TRANSPORT_FAILED;
+ 
+-		if ((*status & 0x80)==0x00) { // not busy
++		if ((*status & 0x80)==0x00) { /* not busy */
+ 			US_DEBUGP("Waited not busy for %d steps\n", i);
+ 			return USB_STOR_TRANSPORT_GOOD;
+ 		}
+ 
+ 		if (i<500)
+-			msleep(10); // 5 seconds
++			msleep(10); /* 5 seconds */
+ 		else if (i<700)
+-			msleep(50); // 10 seconds
++			msleep(50); /* 10 seconds */
+ 		else if (i<1200)
+-			msleep(100); // 50 seconds
++			msleep(100); /* 50 seconds */
+ 		else
+-			msleep(1000); // X minutes
++			msleep(1000); /* X minutes */
+ 	}
+ 
+ 	US_DEBUGP("Waited not busy for %d minutes, timing out.\n",
+@@ -412,9 +424,12 @@ static int usbat_hp8200e_rw_block_test(s
+ 
+ 		if (i==0) {
+ 			cmdlen = 16;
+-			// Write to multiple registers
+-			// Not really sure the 0x07, 0x17, 0xfc, 0xe7 is necessary here,
+-			// but that's what came out of the trace every single time.
++			/*
++			 * Write to multiple registers
++			 * Not really sure the 0x07, 0x17, 0xfc, 0xe7 is
++			 * necessary here, but that's what came out of the
++			 * trace every single time.
++			 */
+ 			command[0] = 0x40;
+ 			command[1] = access | USBAT_CMD_WRITE_REGS;
+ 			command[2] = 0x07;
+@@ -426,7 +441,7 @@ static int usbat_hp8200e_rw_block_test(s
+ 		} else
+ 			cmdlen = 8;
+ 
+-		// Conditionally read or write blocks
++		/* Conditionally read or write blocks */
+ 		command[cmdlen-8] = (direction==DMA_TO_DEVICE ? 0x40 : 0xC0);
+ 		command[cmdlen-7] = access |
+ 				(direction==DMA_TO_DEVICE ?
+@@ -456,11 +471,6 @@ static int usbat_hp8200e_rw_block_test(s
+ 
+ 		}
+ 
+-
+-		//US_DEBUGP("Transfer %s %d bytes, sg buffers %d\n",
+-		//	direction == DMA_TO_DEVICE ? "out" : "in",
+-		//	len, use_sg);
+-
+ 		result = usb_stor_bulk_transfer_sg(us,
+ 			pipe, content, len, use_sg, NULL);
+ 
+@@ -508,9 +518,9 @@ static int usbat_hp8200e_rw_block_test(s
+ 
+ 			if (result!=USB_STOR_XFER_GOOD)
+ 				return USB_STOR_TRANSPORT_ERROR;
+-			if (*status & 0x01) // check condition
++			if (*status & 0x01) /* check condition */
+ 				return USB_STOR_TRANSPORT_FAILED;
+-			if (*status & 0x20) // device fault
++			if (*status & 0x20) /* device fault */
+ 				return USB_STOR_TRANSPORT_FAILED;
+ 
+ 			US_DEBUGP("Redoing %s\n",
+@@ -547,32 +557,32 @@ static int usbat_multiple_write(struct u
+ 
+ 	BUG_ON(num_registers > US_IOBUF_SIZE/2);
+ 
+-	// Write to multiple registers, ATA access
++	/* Write to multiple registers, ATA access */
+ 	command[0] = 0x40;
+ 	command[1] = USBAT_ATA | USBAT_CMD_WRITE_REGS;
+ 
+-	// No relevance
++	/* No relevance */
+ 	command[2] = 0;
+ 	command[3] = 0;
+ 	command[4] = 0;
+ 	command[5] = 0;
+ 
+-	// Number of bytes to be transferred (incl. addresses and data)
++	/* Number of bytes to be transferred (incl. addresses and data) */
+ 	command[6] = LSB_of(num_registers*2);
+ 	command[7] = MSB_of(num_registers*2);
+ 
+-	// The setup command
++	/* The setup command */
+ 	result = usbat_execute_command(us, command, 8);
+ 	if (result != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_ERROR;
+ 
+-	// Create the reg/data, reg/data sequence
++	/* Create the reg/data, reg/data sequence */
+ 	for (i=0; i<num_registers; i++) {
+ 		data[i<<1] = registers[i];
+ 		data[1+(i<<1)] = data_out[i];
+ 	}
+ 
+-	// Send the data
++	/* Send the data */
+ 	result = usbat_bulk_write(us, data, num_registers*2);
+ 	if (result != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_ERROR;
+@@ -606,17 +616,17 @@ static int usbat_read_blocks(struct us_d
+ 	command[1] = USBAT_ATA | USBAT_CMD_COND_READ_BLOCK;
+ 	command[2] = USBAT_ATA_DATA;
+ 	command[3] = USBAT_ATA_STATUS;
+-	command[4] = 0xFD; // Timeout (ms);
++	command[4] = 0xFD; /* Timeout (ms); */
+ 	command[5] = USBAT_QUAL_FCQ;
+ 	command[6] = LSB_of(len);
+ 	command[7] = MSB_of(len);
+ 
+-	// Multiple block read setup command
++	/* Multiple block read setup command */
+ 	result = usbat_execute_command(us, command, 8);
+ 	if (result != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_FAILED;
+ 	
+-	// Read the blocks we just asked for
++	/* Read the blocks we just asked for */
+ 	result = usbat_bulk_read(us, buffer, len);
+ 	if (result != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_FAILED;
+@@ -647,17 +657,17 @@ static int usbat_write_blocks(struct us_
+ 	command[1] = USBAT_ATA | USBAT_CMD_COND_WRITE_BLOCK;
+ 	command[2] = USBAT_ATA_DATA;
+ 	command[3] = USBAT_ATA_STATUS;
+-	command[4] = 0xFD; // Timeout (ms)
++	command[4] = 0xFD; /* Timeout (ms) */
+ 	command[5] = USBAT_QUAL_FCQ;
+ 	command[6] = LSB_of(len);
+ 	command[7] = MSB_of(len);
+ 
+-	// Multiple block write setup command
++	/* Multiple block write setup command */
+ 	result = usbat_execute_command(us, command, 8);
+ 	if (result != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_FAILED;
+ 	
+-	// Write the data
++	/* Write the data */
+ 	result = usbat_bulk_write(us, buffer, len);
+ 	if (result != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_FAILED;
+@@ -711,16 +721,20 @@ static int usbat_device_reset(struct us_
+ {
+ 	int rc;
+ 
+-	// Reset peripheral, enable peripheral control signals
+-	// (bring reset signal up)
++	/*
++	 * Reset peripheral, enable peripheral control signals
++	 * (bring reset signal up)
++	 */
+ 	rc = usbat_write_user_io(us,
+ 							 USBAT_UIO_DRVRST | USBAT_UIO_OE1 | USBAT_UIO_OE0,
+ 							 USBAT_UIO_EPAD | USBAT_UIO_1);
+ 	if (rc != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_ERROR;
+ 			
+-	// Enable peripheral control signals
+-	// (bring reset signal down)
++	/*
++	 * Enable peripheral control signals
++	 * (bring reset signal down)
++	 */
+ 	rc = usbat_write_user_io(us,
+ 							 USBAT_UIO_OE1  | USBAT_UIO_OE0,
+ 							 USBAT_UIO_EPAD | USBAT_UIO_1);
+@@ -737,7 +751,7 @@ static int usbat_device_enable_cdt(struc
+ {
+ 	int rc;
+ 
+-	// Enable peripheral control signals and card detect
++	/* Enable peripheral control signals and card detect */
+ 	rc = usbat_write_user_io(us,
+ 							 USBAT_UIO_ACKD | USBAT_UIO_OE1  | USBAT_UIO_OE0,
+ 							 USBAT_UIO_EPAD | USBAT_UIO_1);
+@@ -786,7 +800,7 @@ static int usbat_flash_check_media(struc
+ 	if (rc != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_ERROR;
+ 
+-	// Check for media existence
++	/* Check for media existence */
+ 	rc = usbat_flash_check_media_present(uio);
+ 	if (rc == USBAT_FLASH_MEDIA_NONE) {
+ 		info->sense_key = 0x02;
+@@ -795,11 +809,11 @@ static int usbat_flash_check_media(struc
+ 		return USB_STOR_TRANSPORT_FAILED;
+ 	}
+ 
+-	// Check for media change
++	/* Check for media change */
+ 	rc = usbat_flash_check_media_changed(uio);
+ 	if (rc == USBAT_FLASH_MEDIA_CHANGED) {
+ 
+-		// Reset and re-enable card detect
++		/* Reset and re-enable card detect */
+ 		rc = usbat_device_reset(us);
+ 		if (rc != USB_STOR_TRANSPORT_GOOD)
+ 			return rc;
+@@ -855,15 +869,15 @@ static int usbat_identify_device(struct 
+  	if (rc != USB_STOR_XFER_GOOD)
+  		return USB_STOR_TRANSPORT_ERROR;
+ 
+-	// Check for error bit
+-	if (status & 0x01) {
+-		 // Device is a CompactFlash reader/writer
+-		US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
+-		info->devicetype = USBAT_DEV_FLASH;
+-	} else {
+-		// Device is HP 8200
++	/* Check for error bit, or if the command 'fell through' */
++	if (status == 0xA1 || !(status & 0x01)) {
++		/* Device is HP 8200 */
+ 		US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n");
+ 		info->devicetype = USBAT_DEV_HP8200;
++	} else {
++		/* Device is a CompactFlash reader/writer */
++		US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
++		info->devicetype = USBAT_DEV_FLASH;
+ 	}
+ 
+ 	return USB_STOR_TRANSPORT_GOOD;
+@@ -916,7 +930,7 @@ static int usbat_flash_get_sector_count(
+ 	if (!reply)
+ 		return USB_STOR_TRANSPORT_ERROR;
+ 
+-	// ATAPI command : IDENTIFY DEVICE
++	/* ATA command : IDENTIFY DEVICE */
+ 	rc = usbat_multiple_write(us, registers, command, 3);
+ 	if (rc != USB_STOR_XFER_GOOD) {
+ 		US_DEBUGP("usbat_flash_get_sector_count: Gah! identify_device failed\n");
+@@ -924,7 +938,7 @@ static int usbat_flash_get_sector_count(
+ 		goto leave;
+ 	}
+ 
+-	// Read device status
++	/* Read device status */
+ 	if (usbat_get_status(us, &status) != USB_STOR_XFER_GOOD) {
+ 		rc = USB_STOR_TRANSPORT_ERROR;
+ 		goto leave;
+@@ -932,7 +946,7 @@ static int usbat_flash_get_sector_count(
+ 
+ 	msleep(100);
+ 
+-	// Read the device identification data
++	/* Read the device identification data */
+ 	rc = usbat_read_block(us, reply, 512);
+ 	if (rc != USB_STOR_TRANSPORT_GOOD)
+ 		goto leave;
+@@ -977,19 +991,23 @@ static int usbat_flash_read_data(struct 
+ 	if (result != USB_STOR_TRANSPORT_GOOD)
+ 		return result;
+ 
+-	// we're working in LBA mode.  according to the ATA spec,
+-	// we can support up to 28-bit addressing.  I don't know if Jumpshot
+-	// supports beyond 24-bit addressing.  It's kind of hard to test
+-	// since it requires > 8GB CF card.
++	/*
++	 * we're working in LBA mode.  according to the ATA spec,
++	 * we can support up to 28-bit addressing.  I don't know if Jumpshot
++	 * supports beyond 24-bit addressing.  It's kind of hard to test
++	 * since it requires > 8GB CF card.
++	 */
+ 
+ 	if (sector > 0x0FFFFFFF)
+ 		return USB_STOR_TRANSPORT_ERROR;
+ 
+ 	totallen = sectors * info->ssize;
+ 
+-	// Since we don't read more than 64 KB at a time, we have to create
+-	// a bounce buffer and move the data a piece at a time between the
+-	// bounce buffer and the actual transfer buffer.
++	/*
++	 * Since we don't read more than 64 KB at a time, we have to create
++	 * a bounce buffer and move the data a piece at a time between the
++	 * bounce buffer and the actual transfer buffer.
++	 */
+ 
+ 	alloclen = min(totallen, 65536u);
+ 	buffer = kmalloc(alloclen, GFP_NOIO);
+@@ -997,27 +1015,29 @@ static int usbat_flash_read_data(struct 
+ 		return USB_STOR_TRANSPORT_ERROR;
+ 
+ 	do {
+-		// loop, never allocate or transfer more than 64k at once
+-		// (min(128k, 255*info->ssize) is the real limit)
++		/*
++		 * loop, never allocate or transfer more than 64k at once
++		 * (min(128k, 255*info->ssize) is the real limit)
++		 */
+ 		len = min(totallen, alloclen);
+ 		thistime = (len / info->ssize) & 0xff;
+  
+-		// ATAPI command 0x20 (READ SECTORS)
+-		usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x20);
++		/* ATA command 0x20 (READ SECTORS) */
++		usbat_pack_ata_sector_cmd(command, thistime, sector, 0x20);
+ 
+-		// Write/execute ATAPI read command
++		/* Write/execute ATA read command */
+ 		result = usbat_multiple_write(us, registers, command, 7);
+ 		if (result != USB_STOR_TRANSPORT_GOOD)
+ 			goto leave;
+ 
+-		// Read the data we just requested
++		/* Read the data we just requested */
+ 		result = usbat_read_blocks(us, buffer, len);
+ 		if (result != USB_STOR_TRANSPORT_GOOD)
+ 			goto leave;
+   	 
+ 		US_DEBUGP("usbat_flash_read_data:  %d bytes\n", len);
+ 	
+-		// Store the data in the transfer buffer
++		/* Store the data in the transfer buffer */
+ 		usb_stor_access_xfer_buf(buffer, len, us->srb,
+ 					 &sg_idx, &sg_offset, TO_XFER_BUF);
+ 
+@@ -1061,19 +1081,23 @@ static int usbat_flash_write_data(struct
+ 	if (result != USB_STOR_TRANSPORT_GOOD)
+ 		return result;
+ 
+-	// we're working in LBA mode.  according to the ATA spec,
+-	// we can support up to 28-bit addressing.  I don't know if Jumpshot
+-	// supports beyond 24-bit addressing.  It's kind of hard to test
+-	// since it requires > 8GB CF card.
++	/*
++	 * we're working in LBA mode.  according to the ATA spec,
++	 * we can support up to 28-bit addressing.  I don't know if the device
++	 * supports beyond 24-bit addressing.  It's kind of hard to test
++	 * since it requires > 8GB media.
++	 */
+ 
+ 	if (sector > 0x0FFFFFFF)
+ 		return USB_STOR_TRANSPORT_ERROR;
+ 
+ 	totallen = sectors * info->ssize;
+ 
+-	// Since we don't write more than 64 KB at a time, we have to create
+-	// a bounce buffer and move the data a piece at a time between the
+-	// bounce buffer and the actual transfer buffer.
++	/*
++	 * Since we don't write more than 64 KB at a time, we have to create
++	 * a bounce buffer and move the data a piece at a time between the
++	 * bounce buffer and the actual transfer buffer.
++	 */
+ 
+ 	alloclen = min(totallen, 65536u);
+ 	buffer = kmalloc(alloclen, GFP_NOIO);
+@@ -1081,24 +1105,26 @@ static int usbat_flash_write_data(struct
+ 		return USB_STOR_TRANSPORT_ERROR;
+ 
+ 	do {
+-		// loop, never allocate or transfer more than 64k at once
+-		// (min(128k, 255*info->ssize) is the real limit)
++		/*
++		 * loop, never allocate or transfer more than 64k at once
++		 * (min(128k, 255*info->ssize) is the real limit)
++		 */
+ 		len = min(totallen, alloclen);
+ 		thistime = (len / info->ssize) & 0xff;
+ 
+-		// Get the data from the transfer buffer
++		/* Get the data from the transfer buffer */
+ 		usb_stor_access_xfer_buf(buffer, len, us->srb,
+ 					 &sg_idx, &sg_offset, FROM_XFER_BUF);
+ 
+-		// ATAPI command 0x30 (WRITE SECTORS)
+-		usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x30);		
++		/* ATA command 0x30 (WRITE SECTORS) */
++		usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30);
+ 
+-		// Write/execute ATAPI write command
++		/* Write/execute ATA write command */
+ 		result = usbat_multiple_write(us, registers, command, 7);
+ 		if (result != USB_STOR_TRANSPORT_GOOD)
+ 			goto leave;
+ 
+-		// Write the data
++		/* Write the data */
+ 		result = usbat_write_blocks(us, buffer, len);
+ 		if (result != USB_STOR_TRANSPORT_GOOD)
+ 			goto leave;
+@@ -1169,42 +1195,44 @@ static int usbat_hp8200e_handle_read10(s
+ 			srb->transfersize);
+ 	}
+ 
+-	// Since we only read in one block at a time, we have to create
+-	// a bounce buffer and move the data a piece at a time between the
+-	// bounce buffer and the actual transfer buffer.
++	/*
++	 * Since we only read in one block at a time, we have to create
++	 * a bounce buffer and move the data a piece at a time between the
++	 * bounce buffer and the actual transfer buffer.
++	 */
+ 
+ 	len = (65535/srb->transfersize) * srb->transfersize;
+ 	US_DEBUGP("Max read is %d bytes\n", len);
+ 	len = min(len, srb->request_bufflen);
+ 	buffer = kmalloc(len, GFP_NOIO);
+-	if (buffer == NULL) // bloody hell!
++	if (buffer == NULL) /* bloody hell! */
+ 		return USB_STOR_TRANSPORT_FAILED;
+ 	sector = short_pack(data[7+3], data[7+2]);
+ 	sector <<= 16;
+ 	sector |= short_pack(data[7+5], data[7+4]);
+ 	transferred = 0;
+ 
+-	sg_segment = 0; // for keeping track of where we are in
+-	sg_offset = 0;  // the scatter/gather list
++	sg_segment = 0; /* for keeping track of where we are in */
++	sg_offset = 0;  /* the scatter/gather list */
+ 
+ 	while (transferred != srb->request_bufflen) {
+ 
+ 		if (len > srb->request_bufflen - transferred)
+ 			len = srb->request_bufflen - transferred;
+ 
+-		data[3] = len&0xFF; 	  // (cylL) = expected length (L)
+-		data[4] = (len>>8)&0xFF;  // (cylH) = expected length (H)
++		data[3] = len&0xFF; 	  /* (cylL) = expected length (L) */
++		data[4] = (len>>8)&0xFF;  /* (cylH) = expected length (H) */
+ 
+-		// Fix up the SCSI command sector and num sectors
++		/* Fix up the SCSI command sector and num sectors */
+ 
+-		data[7+2] = MSB_of(sector>>16); // SCSI command sector
++		data[7+2] = MSB_of(sector>>16); /* SCSI command sector */
+ 		data[7+3] = LSB_of(sector>>16);
+ 		data[7+4] = MSB_of(sector&0xFFFF);
+ 		data[7+5] = LSB_of(sector&0xFFFF);
+ 		if (data[7+0] == GPCMD_READ_CD)
+ 			data[7+6] = 0;
+-		data[7+7] = MSB_of(len / srb->transfersize); // SCSI command
+-		data[7+8] = LSB_of(len / srb->transfersize); // num sectors
++		data[7+7] = MSB_of(len / srb->transfersize); /* SCSI command */
++		data[7+8] = LSB_of(len / srb->transfersize); /* num sectors */
+ 
+ 		result = usbat_hp8200e_rw_block_test(us, USBAT_ATA, 
+ 			registers, data, 19,
+@@ -1217,16 +1245,16 @@ static int usbat_hp8200e_handle_read10(s
+ 		if (result != USB_STOR_TRANSPORT_GOOD)
+ 			break;
+ 
+-		// Store the data in the transfer buffer
++		/* Store the data in the transfer buffer */
+ 		usb_stor_access_xfer_buf(buffer, len, srb,
+ 				 &sg_segment, &sg_offset, TO_XFER_BUF);
+ 
+-		// Update the amount transferred and the sector number
++		/* Update the amount transferred and the sector number */
+ 
+ 		transferred += len;
+ 		sector += len / srb->transfersize;
+ 
+-	} // while transferred != srb->request_bufflen
++	} /* while transferred != srb->request_bufflen */
+ 
+ 	kfree(buffer);
+ 	return result;
+@@ -1237,7 +1265,7 @@ static int usbat_select_and_test_registe
+ 	int selector;
+ 	unsigned char *status = us->iobuf;
+ 
+-	// try device = master, then device = slave.
++	/* try device = master, then device = slave. */
+ 	for (selector = 0xA0; selector <= 0xB0; selector += 0x10) {
+ 		if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) !=
+ 				USB_STOR_XFER_GOOD)
+@@ -1298,7 +1326,7 @@ int init_usbat(struct us_data *us)
+ 	memset(us->extra, 0, sizeof(struct usbat_info));
+ 	info = (struct usbat_info *) (us->extra);
+ 
+-	// Enable peripheral control signals
++	/* Enable peripheral control signals */
+ 	rc = usbat_write_user_io(us,
+ 				 USBAT_UIO_OE1 | USBAT_UIO_OE0,
+ 				 USBAT_UIO_EPAD | USBAT_UIO_1);
+@@ -1337,7 +1365,7 @@ int init_usbat(struct us_data *us)
+ 
+ 	US_DEBUGP("INIT 5\n");
+ 
+-	// Enable peripheral control signals and card detect
++	/* Enable peripheral control signals and card detect */
+ 	rc = usbat_device_enable_cdt(us);
+ 	if (rc != USB_STOR_TRANSPORT_GOOD)
+ 		return rc;
+@@ -1364,7 +1392,7 @@ int init_usbat(struct us_data *us)
+ 
+ 	US_DEBUGP("INIT 9\n");
+ 
+-	// At this point, we need to detect which device we are using
++	/* At this point, we need to detect which device we are using */
+ 	if (usbat_set_transport(us, info))
+ 		return USB_STOR_TRANSPORT_ERROR;
+ 
+@@ -1414,10 +1442,10 @@ static int usbat_hp8200e_transport(struc
+ 	data[0] = 0x00;
+ 	data[1] = 0x00;
+ 	data[2] = 0x00;
+-	data[3] = len&0xFF; 		// (cylL) = expected length (L)
+-	data[4] = (len>>8)&0xFF; 	// (cylH) = expected length (H)
+-	data[5] = 0xB0; 		// (device sel) = slave
+-	data[6] = 0xA0; 		// (command) = ATA PACKET COMMAND
++	data[3] = len&0xFF; 		/* (cylL) = expected length (L) */
++	data[4] = (len>>8)&0xFF; 	/* (cylH) = expected length (H) */
++	data[5] = 0xB0; 		/* (device sel) = slave */
++	data[6] = 0xA0; 		/* (command) = ATA PACKET COMMAND */
+ 
+ 	for (i=7; i<19; i++) {
+ 		registers[i] = 0x10;
+@@ -1466,13 +1494,15 @@ static int usbat_hp8200e_transport(struc
+ 		return result;
+ 	}
+ 
+-	// Write the 12-byte command header.
+-
+-	// If the command is BLANK then set the timer for 75 minutes.
+-	// Otherwise set it for 10 minutes.
+-
+-	// NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW
+-	// AT SPEED 4 IS UNRELIABLE!!!
++	/*
++	 * Write the 12-byte command header.
++	 *
++	 * If the command is BLANK then set the timer for 75 minutes.
++	 * Otherwise set it for 10 minutes.
++	 *
++	 * NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW
++	 * AT SPEED 4 IS UNRELIABLE!!!
++	 */
+ 
+ 	if ( (result = usbat_write_block(us, 
+ 			USBAT_ATA, srb->cmnd, 12,
+@@ -1481,19 +1511,18 @@ static int usbat_hp8200e_transport(struc
+ 		return result;
+ 	}
+ 
+-	// If there is response data to be read in 
+-	// then do it here.
++	/* If there is response data to be read in then do it here. */
+ 
+ 	if (len != 0 && (srb->sc_data_direction == DMA_FROM_DEVICE)) {
+ 
+-		// How many bytes to read in? Check cylL register
++		/* How many bytes to read in? Check cylL register */
+ 
+ 		if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != 
+ 		    	USB_STOR_XFER_GOOD) {
+ 			return USB_STOR_TRANSPORT_ERROR;
+ 		}
+ 
+-		if (len > 0xFF) { // need to read cylH also
++		if (len > 0xFF) { /* need to read cylH also */
+ 			len = *status;
+ 			if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) !=
+ 				    USB_STOR_XFER_GOOD) {
+@@ -1556,13 +1585,16 @@ static int usbat_flash_transport(struct 
+ 		if (rc != USB_STOR_TRANSPORT_GOOD)
+ 			return rc;
+ 
+-		info->ssize = 0x200;  // hard coded 512 byte sectors as per ATA spec
++		/* hard coded 512 byte sectors as per ATA spec */
++		info->ssize = 0x200;
+ 		US_DEBUGP("usbat_flash_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n",
+ 			  info->sectors, info->ssize);
+ 
+-		// build the reply
+-		// note: must return the sector number of the last sector,
+-		// *not* the total number of sectors
++		/*
++		 * build the reply
++		 * note: must return the sector number of the last sector,
++		 * *not* the total number of sectors
++		 */
+ 		((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);
+ 		((__be32 *) ptr)[1] = cpu_to_be32(info->ssize);
+ 		usb_stor_set_xfer_buf(ptr, 8, srb);
+@@ -1586,7 +1618,9 @@ static int usbat_flash_transport(struct 
+ 	}
+ 
+ 	if (srb->cmnd[0] == READ_12) {
+-		// I don't think we'll ever see a READ_12 but support it anyway...
++		/*
++		 * I don't think we'll ever see a READ_12 but support it anyway
++		 */
+ 		block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
+ 		        ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
+ 
+@@ -1608,7 +1642,9 @@ static int usbat_flash_transport(struct 
+ 	}
+ 
+ 	if (srb->cmnd[0] == WRITE_12) {
+-		// I don't think we'll ever see a WRITE_12 but support it anyway...
++		/*
++		 * I don't think we'll ever see a WRITE_12 but support it anyway
++		 */
+ 		block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
+ 		        ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));
+ 
+@@ -1645,8 +1681,10 @@ static int usbat_flash_transport(struct 
+ 	}
+ 
+ 	if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
+-		// sure.  whatever.  not like we can stop the user from popping
+-		// the media out of the device (no locking doors, etc)
++		/*
++		 * sure.  whatever.  not like we can stop the user from popping
++		 * the media out of the device (no locking doors, etc)
++		 */
+ 		return USB_STOR_TRANSPORT_GOOD;
+ 	}
+ 
+diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h
+--- a/drivers/usb/storage/shuttle_usbat.h
++++ b/drivers/usb/storage/shuttle_usbat.h
+@@ -55,8 +55,8 @@
+ #define USBAT_UIO_WRITE	0
+ 
+ /* Qualifier bits */
+-#define USBAT_QUAL_FCQ	0x20 // full compare
+-#define USBAT_QUAL_ALQ	0x10 // auto load subcount
++#define USBAT_QUAL_FCQ	0x20	/* full compare */
++#define USBAT_QUAL_ALQ	0x10	/* auto load subcount */
+ 
+ /* USBAT Flash Media status types */
+ #define USBAT_FLASH_MEDIA_NONE	0
+@@ -67,39 +67,39 @@
+ #define USBAT_FLASH_MEDIA_CHANGED	1
+ 
+ /* USBAT ATA registers */
+-#define USBAT_ATA_DATA      0x10  // read/write data (R/W)
+-#define USBAT_ATA_FEATURES  0x11  // set features (W)
+-#define USBAT_ATA_ERROR     0x11  // error (R)
+-#define USBAT_ATA_SECCNT    0x12  // sector count (R/W)
+-#define USBAT_ATA_SECNUM    0x13  // sector number (R/W)
+-#define USBAT_ATA_LBA_ME    0x14  // cylinder low (R/W)
+-#define USBAT_ATA_LBA_HI    0x15  // cylinder high (R/W)
+-#define USBAT_ATA_DEVICE    0x16  // head/device selection (R/W)
+-#define USBAT_ATA_STATUS    0x17  // device status (R)
+-#define USBAT_ATA_CMD       0x17  // device command (W)
+-#define USBAT_ATA_ALTSTATUS 0x0E  // status (no clear IRQ) (R)
++#define USBAT_ATA_DATA      0x10  /* read/write data (R/W) */
++#define USBAT_ATA_FEATURES  0x11  /* set features (W) */
++#define USBAT_ATA_ERROR     0x11  /* error (R) */
++#define USBAT_ATA_SECCNT    0x12  /* sector count (R/W) */
++#define USBAT_ATA_SECNUM    0x13  /* sector number (R/W) */
++#define USBAT_ATA_LBA_ME    0x14  /* cylinder low (R/W) */
++#define USBAT_ATA_LBA_HI    0x15  /* cylinder high (R/W) */
++#define USBAT_ATA_DEVICE    0x16  /* head/device selection (R/W) */
++#define USBAT_ATA_STATUS    0x17  /* device status (R) */
++#define USBAT_ATA_CMD       0x17  /* device command (W) */
++#define USBAT_ATA_ALTSTATUS 0x0E  /* status (no clear IRQ) (R) */
+ 
+ /* USBAT User I/O Data registers */
+-#define USBAT_UIO_EPAD		0x80 // Enable Peripheral Control Signals
+-#define USBAT_UIO_CDT		0x40 // Card Detect (Read Only)
+-				     // CDT = ACKD & !UI1 & !UI0
+-#define USBAT_UIO_1		0x20 // I/O 1
+-#define USBAT_UIO_0		0x10 // I/O 0
+-#define USBAT_UIO_EPP_ATA	0x08 // 1=EPP mode, 0=ATA mode
+-#define USBAT_UIO_UI1		0x04 // Input 1
+-#define USBAT_UIO_UI0		0x02 // Input 0
+-#define USBAT_UIO_INTR_ACK	0x01 // Interrupt (ATA & ISA)/Acknowledge (EPP)
++#define USBAT_UIO_EPAD		0x80 /* Enable Peripheral Control Signals */
++#define USBAT_UIO_CDT		0x40 /* Card Detect (Read Only) */
++				     /* CDT = ACKD & !UI1 & !UI0 */
++#define USBAT_UIO_1		0x20 /* I/O 1 */
++#define USBAT_UIO_0		0x10 /* I/O 0 */
++#define USBAT_UIO_EPP_ATA	0x08 /* 1=EPP mode, 0=ATA mode */
++#define USBAT_UIO_UI1		0x04 /* Input 1 */
++#define USBAT_UIO_UI0		0x02 /* Input 0 */
++#define USBAT_UIO_INTR_ACK	0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */
+ 
+ /* USBAT User I/O Enable registers */
+-#define USBAT_UIO_DRVRST	0x80 // Reset Peripheral
+-#define USBAT_UIO_ACKD		0x40 // Enable Card Detect
+-#define USBAT_UIO_OE1		0x20 // I/O 1 set=output/clr=input
+-				     // If ACKD=1, set OE1 to 1 also.
+-#define USBAT_UIO_OE0		0x10 // I/O 0 set=output/clr=input
+-#define USBAT_UIO_ADPRST	0x01 // Reset SCM chip
++#define USBAT_UIO_DRVRST	0x80 /* Reset Peripheral */
++#define USBAT_UIO_ACKD		0x40 /* Enable Card Detect */
++#define USBAT_UIO_OE1		0x20 /* I/O 1 set=output/clr=input */
++				     /* If ACKD=1, set OE1 to 1 also. */
++#define USBAT_UIO_OE0		0x10 /* I/O 0 set=output/clr=input */
++#define USBAT_UIO_ADPRST	0x01 /* Reset SCM chip */
+ 
+ /* USBAT Features */
+-#define USBAT_FEAT_ETEN	0x80 // External trigger enable
++#define USBAT_FEAT_ETEN	0x80	/* External trigger enable */
+ #define USBAT_FEAT_U1	0x08
+ #define USBAT_FEAT_U0	0x04
+ #define USBAT_FEAT_ET1	0x02
+@@ -112,12 +112,12 @@ struct usbat_info {
+ 	int devicetype;
+ 
+ 	/* Used for Flash readers only */
+-	unsigned long sectors;     // total sector count
+-	unsigned long ssize;       // sector size in bytes
++	unsigned long sectors;     /* total sector count */
++	unsigned long ssize;       /* sector size in bytes */
+ 
+ 	unsigned char sense_key;
+-	unsigned long sense_asc;   // additional sense code
+-	unsigned long sense_ascq;  // additional sense code qualifier
++	unsigned long sense_asc;   /* additional sense code */
++	unsigned long sense_ascq;  /* additional sense code qualifier */
+ };
+ 
+ #endif
+diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
+--- a/drivers/usb/storage/transport.c
++++ b/drivers/usb/storage/transport.c
+@@ -636,11 +636,11 @@ void usb_stor_invoke_transport(struct sc
+ 
+ 		/* use the new buffer we have */
+ 		old_request_buffer = srb->request_buffer;
+-		srb->request_buffer = srb->sense_buffer;
++		srb->request_buffer = us->sensebuf;
+ 
+ 		/* set the buffer length for transfer */
+ 		old_request_bufflen = srb->request_bufflen;
+-		srb->request_bufflen = 18;
++		srb->request_bufflen = US_SENSE_SIZE;
+ 
+ 		/* set up for no scatter-gather use */
+ 		old_sg = srb->use_sg;
+@@ -652,6 +652,7 @@ void usb_stor_invoke_transport(struct sc
+ 		temp_result = us->transport(us->srb, us);
+ 
+ 		/* let's clean up right away */
++		memcpy(srb->sense_buffer, us->sensebuf, US_SENSE_SIZE);
+ 		srb->resid = old_resid;
+ 		srb->request_buffer = old_request_buffer;
+ 		srb->request_bufflen = old_request_bufflen;
+@@ -923,6 +924,7 @@ int usb_stor_Bulk_max_lun(struct us_data
+ 	int result;
+ 
+ 	/* issue the command */
++	us->iobuf[0] = 0;
+ 	result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
+ 				 US_BULK_GET_MAX_LUN, 
+ 				 USB_DIR_IN | USB_TYPE_CLASS | 
+diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
+--- a/drivers/usb/storage/transport.h
++++ b/drivers/usb/storage/transport.h
+@@ -50,7 +50,7 @@
+ #define US_PR_CB	0x01		/* Control/Bulk w/o interrupt */
+ #define US_PR_BULK	0x50		/* bulk only */
+ #ifdef CONFIG_USB_STORAGE_USBAT
+-#define US_PR_SCM_ATAPI	0x80		/* SCM-ATAPI bridge */
++#define US_PR_USBAT	0x80		/* SCM-ATAPI bridge */
+ #endif
+ #ifdef CONFIG_USB_STORAGE_SDDR09
+ #define US_PR_EUSB_SDDR09	0x81	/* SCM-SCSI bridge for SDDR-09 */
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -71,12 +71,12 @@ UNUSUAL_DEV(  0x03f0, 0x0107, 0x0200, 0x
+ UNUSUAL_DEV(  0x03f0, 0x0207, 0x0001, 0x0001, 
+ 		"HP",
+ 		"CD-Writer+ 8200e",
+-		US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), 
++		US_SC_8070, US_PR_USBAT, init_usbat, 0),
+ 
+ UNUSUAL_DEV(  0x03f0, 0x0307, 0x0001, 0x0001, 
+ 		"HP",
+ 		"CD-Writer+ CD-4e",
+-		US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), 
++		US_SC_8070, US_PR_USBAT, init_usbat, 0),
+ #endif
+ 
+ /* Patch submitted by Mihnea-Costin Grigore <mihnea at zulu.ro> */
+@@ -106,6 +106,13 @@ UNUSUAL_DEV(  0x0411, 0x001c, 0x0113, 0x
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_FIX_INQUIRY ),
+ 
++/* Reported by Stefan Werner <dustbln at gmx.de> */
++UNUSUAL_DEV(  0x0419, 0xaaf6, 0x0100, 0x0100,
++		"TrekStor",
++		"i.Beat Joy 2.0",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		US_FL_IGNORE_RESIDUE ),
++
+ /* Reported by Olaf Hering <olh at suse.de> from novell bug #105878 */
+ UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
+ 		"SMSC",
+@@ -244,6 +251,13 @@ UNUSUAL_DEV(  0x04da, 0x2372, 0x0000, 0x
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ),
+ 
++/* Reported by Simeon Simeonov <simeonov_2000 at yahoo.com> */
++UNUSUAL_DEV(  0x04da, 0x2373, 0x0000, 0x9999,
++		"LEICA",
++		"D-LUX Camera",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ),
++
+ /* Most of the following entries were developed with the help of
+  * Shuttle/SCM directly.
+  */
+@@ -333,9 +347,9 @@ UNUSUAL_DEV(  0x04fc, 0x80c2, 0x0100, 0x
+ 
+ #ifdef CONFIG_USB_STORAGE_USBAT
+ UNUSUAL_DEV(  0x04e6, 0x1010, 0x0000, 0x9999,
+-		"SCM",
+-		"SCM USBAT-02",
+-		US_SC_SCSI, US_PR_SCM_ATAPI, init_usbat,
++		"Shuttle/SCM",
++		"USBAT-02",
++		US_SC_SCSI, US_PR_USBAT, init_usbat,
+ 		US_FL_SINGLE_LUN),
+ #endif
+ 
+@@ -598,6 +612,16 @@ UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_FIX_CAPACITY ),
+ 
++/*
++ * Reported by Tyson Vinson <lornoss at gmail.com>
++ * This particular productId is the iPod Nano
++ */
++UNUSUAL_DEV( 0x05ac, 0x120a, 0x0000, 0x9999,
++		"Apple",
++		"iPod",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		US_FL_FIX_CAPACITY ),
++
+ #ifdef CONFIG_USB_STORAGE_JUMPSHOT
+ UNUSUAL_DEV(  0x05dc, 0x0001, 0x0000, 0x0001,
+ 		"Lexar",
+@@ -702,6 +726,14 @@ UNUSUAL_DEV(  0x0781, 0x0001, 0x0200, 0x
+ 		US_SC_SCSI, US_PR_CB, NULL,
+ 		US_FL_SINGLE_LUN ),
+ 
++#ifdef CONFIG_USB_STORAGE_USBAT
++UNUSUAL_DEV(  0x0781, 0x0005, 0x0005, 0x0005,
++		"Sandisk",
++		"ImageMate SDDR-05b",
++		US_SC_SCSI, US_PR_USBAT, init_usbat,
++		US_FL_SINGLE_LUN ),
++#endif
++
+ UNUSUAL_DEV(  0x0781, 0x0100, 0x0100, 0x0100,
+ 		"Sandisk",
+ 		"ImageMate SDDR-12",
+@@ -724,7 +756,7 @@ UNUSUAL_DEV(  0x07ab, 0xfc01, 0x0000, 0x
+ #endif
+ 
+ /* Reported by Eero Volotinen <eero at ping-viini.org> */
+-UNUSUAL_DEV(  0x07ab, 0xfccd, 0x0406, 0x0406,
++UNUSUAL_DEV(  0x07ab, 0xfccd, 0x0000, 0x9999,
+ 		"Freecom Technologies",
+ 		"FHD-Classic",
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
+--- a/drivers/usb/storage/usb.c
++++ b/drivers/usb/storage/usb.c
+@@ -54,6 +54,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/slab.h>
++#include <linux/kthread.h>
+ 
+ #include <scsi/scsi.h>
+ #include <scsi/scsi_cmnd.h>
+@@ -111,11 +112,6 @@ static atomic_t total_threads = ATOMIC_I
+ static DECLARE_COMPLETION(threads_gone);
+ 
+ 
+-static int storage_probe(struct usb_interface *iface,
+-			 const struct usb_device_id *id);
+-
+-static void storage_disconnect(struct usb_interface *iface);
+-
+ /* The entries in this table, except for final ones here
+  * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
+  * line for line with the entries of us_unsuaul_dev_list[].
+@@ -233,13 +229,40 @@ static struct us_unusual_dev us_unusual_
+ 	{ NULL }
+ };
+ 
+-static struct usb_driver usb_storage_driver = {
+-	.owner =	THIS_MODULE,
+-	.name =		"usb-storage",
+-	.probe =	storage_probe,
+-	.disconnect =	storage_disconnect,
+-	.id_table =	storage_usb_ids,
+-};
++
++#ifdef CONFIG_PM	/* Minimal support for suspend and resume */
++
++static int storage_suspend(struct usb_interface *iface, pm_message_t message)
++{
++	struct us_data *us = usb_get_intfdata(iface);
++
++	/* Wait until no command is running */
++	down(&us->dev_semaphore);
++
++	US_DEBUGP("%s\n", __FUNCTION__);
++	iface->dev.power.power_state.event = message.event;
++
++	/* When runtime PM is working, we'll set a flag to indicate
++	 * whether we should autoresume when a SCSI request arrives. */
++
++	up(&us->dev_semaphore);
++	return 0;
++}
++
++static int storage_resume(struct usb_interface *iface)
++{
++	struct us_data *us = usb_get_intfdata(iface);
++
++	down(&us->dev_semaphore);
++
++	US_DEBUGP("%s\n", __FUNCTION__);
++	iface->dev.power.power_state.event = PM_EVENT_ON;
++
++	up(&us->dev_semaphore);
++	return 0;
++}
++
++#endif /* CONFIG_PM */
+ 
+ /*
+  * fill_inquiry_response takes an unsigned char array (which must
+@@ -288,22 +311,7 @@ static int usb_stor_control_thread(void 
+ 	struct us_data *us = (struct us_data *)__us;
+ 	struct Scsi_Host *host = us_to_host(us);
+ 
+-	lock_kernel();
+-
+-	/*
+-	 * This thread doesn't need any user-level access,
+-	 * so get rid of all our resources.
+-	 */
+-	daemonize("usb-storage");
+ 	current->flags |= PF_NOFREEZE;
+-	unlock_kernel();
+-
+-	/* acquire a reference to the host, so it won't be deallocated
+-	 * until we're ready to exit */
+-	scsi_host_get(host);
+-
+-	/* signal that we've started the thread */
+-	complete(&(us->notify));
+ 
+ 	for(;;) {
+ 		US_DEBUGP("*** thread sleeping.\n");
+@@ -467,6 +475,12 @@ static int associate_dev(struct us_data 
+ 		US_DEBUGP("I/O buffer allocation failed\n");
+ 		return -ENOMEM;
+ 	}
++
++	us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL);
++	if (!us->sensebuf) {
++		US_DEBUGP("Sense buffer allocation failed\n");
++		return -ENOMEM;
++	}
+ 	return 0;
+ }
+ 
+@@ -555,8 +569,8 @@ static int get_transport(struct us_data 
+ 		break;
+ 
+ #ifdef CONFIG_USB_STORAGE_USBAT
+-	case US_PR_SCM_ATAPI:
+-		us->transport_name = "SCM/ATAPI";
++	case US_PR_USBAT:
++		us->transport_name = "Shuttle USBAT";
+ 		us->transport = usbat_transport;
+ 		us->transport_reset = usb_stor_CB_reset;
+ 		us->max_lun = 1;
+@@ -740,6 +754,7 @@ static int get_pipes(struct us_data *us)
+ static int usb_stor_acquire_resources(struct us_data *us)
+ {
+ 	int p;
++	struct task_struct *th;
+ 
+ 	us->current_urb = usb_alloc_urb(0, GFP_KERNEL);
+ 	if (!us->current_urb) {
+@@ -747,38 +762,28 @@ static int usb_stor_acquire_resources(st
+ 		return -ENOMEM;
+ 	}
+ 
+-	/* Lock the device while we carry out the next two operations */
+-	down(&us->dev_semaphore);
+-
+-	/* For bulk-only devices, determine the max LUN value */
+-	if (us->protocol == US_PR_BULK) {
+-		p = usb_stor_Bulk_max_lun(us);
+-		if (p < 0) {
+-			up(&us->dev_semaphore);
+-			return p;
+-		}
+-		us->max_lun = p;
+-	}
+-
+ 	/* Just before we start our control thread, initialize
+ 	 * the device if it needs initialization */
+-	if (us->unusual_dev->initFunction)
+-		us->unusual_dev->initFunction(us);
+-
+-	up(&us->dev_semaphore);
++	if (us->unusual_dev->initFunction) {
++		p = us->unusual_dev->initFunction(us);
++		if (p)
++			return p;
++	}
+ 
+ 	/* Start up our control thread */
+-	p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
+-	if (p < 0) {
++	th = kthread_create(usb_stor_control_thread, us, "usb-storage");
++	if (IS_ERR(th)) {
+ 		printk(KERN_WARNING USB_STORAGE 
+ 		       "Unable to start control thread\n");
+-		return p;
++		return PTR_ERR(th);
+ 	}
+-	us->pid = p;
+-	atomic_inc(&total_threads);
+ 
+-	/* Wait for the thread to start */
+-	wait_for_completion(&(us->notify));
++	/* Take a reference to the host for the control thread and
++	 * count it among all the threads we have launched.  Then
++	 * start it up. */
++	scsi_host_get(us_to_host(us));
++	atomic_inc(&total_threads);
++	wake_up_process(th);
+ 
+ 	return 0;
+ }
+@@ -812,6 +817,8 @@ static void dissociate_dev(struct us_dat
+ {
+ 	US_DEBUGP("-- %s\n", __FUNCTION__);
+ 
++	kfree(us->sensebuf);
++
+ 	/* Free the device-related DMA-mapped buffers */
+ 	if (us->cr)
+ 		usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
+@@ -872,21 +879,6 @@ static int usb_stor_scan_thread(void * _
+ {
+ 	struct us_data *us = (struct us_data *)__us;
+ 
+-	/*
+-	 * This thread doesn't need any user-level access,
+-	 * so get rid of all our resources.
+-	 */
+-	lock_kernel();
+-	daemonize("usb-stor-scan");
+-	unlock_kernel();
+-
+-	/* Acquire a reference to the host, so it won't be deallocated
+-	 * until we're ready to exit */
+-	scsi_host_get(us_to_host(us));
+-
+-	/* Signal that we've started the thread */
+-	complete(&(us->notify));
+-
+ 	printk(KERN_DEBUG
+ 		"usb-storage: device found at %d\n", us->pusb_dev->devnum);
+ 
+@@ -904,6 +896,14 @@ retry:
+ 
+ 	/* If the device is still connected, perform the scanning */
+ 	if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
++
++		/* For bulk-only devices, determine the max LUN value */
++		if (us->protocol == US_PR_BULK &&
++				!(us->flags & US_FL_SINGLE_LUN)) {
++			down(&us->dev_semaphore);
++			us->max_lun = usb_stor_Bulk_max_lun(us);
++			up(&us->dev_semaphore);
++		}
+ 		scsi_scan_host(us_to_host(us));
+ 		printk(KERN_DEBUG "usb-storage: device scan complete\n");
+ 
+@@ -923,6 +923,7 @@ static int storage_probe(struct usb_inte
+ 	struct us_data *us;
+ 	const int id_index = id - storage_usb_ids; 
+ 	int result;
++	struct task_struct *th;
+ 
+ 	US_DEBUGP("USB Mass Storage device detected\n");
+ 
+@@ -1003,17 +1004,21 @@ static int storage_probe(struct usb_inte
+ 	}
+ 
+ 	/* Start up the thread for delayed SCSI-device scanning */
+-	result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM);
+-	if (result < 0) {
++	th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan");
++	if (IS_ERR(th)) {
+ 		printk(KERN_WARNING USB_STORAGE 
+ 		       "Unable to start the device-scanning thread\n");
+ 		quiesce_and_remove_host(us);
++		result = PTR_ERR(th);
+ 		goto BadDevice;
+ 	}
+-	atomic_inc(&total_threads);
+ 
+-	/* Wait for the thread to start */
+-	wait_for_completion(&(us->notify));
++	/* Take a reference to the host for the scanning thread and
++	 * count it among all the threads we have launched.  Then
++	 * start it up. */
++	scsi_host_get(us_to_host(us));
++	atomic_inc(&total_threads);
++	wake_up_process(th);
+ 
+ 	return 0;
+ 
+@@ -1038,6 +1043,18 @@ static void storage_disconnect(struct us
+  * Initialization and registration
+  ***********************************************************************/
+ 
++static struct usb_driver usb_storage_driver = {
++	.owner =	THIS_MODULE,
++	.name =		"usb-storage",
++	.probe =	storage_probe,
++	.disconnect =	storage_disconnect,
++#ifdef CONFIG_PM
++	.suspend =	storage_suspend,
++	.resume =	storage_resume,
++#endif
++	.id_table =	storage_usb_ids,
++};
++
+ static int __init usb_stor_init(void)
+ {
+ 	int retval;
+diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
+--- a/drivers/usb/storage/usb.h
++++ b/drivers/usb/storage/usb.h
+@@ -117,6 +117,7 @@ enum { US_DO_ALL_FLAGS };
+  */
+ 
+ #define US_IOBUF_SIZE		64	/* Size of the DMA-mapped I/O buffer */
++#define US_SENSE_SIZE		18	/* Size of the autosense data buffer */
+ 
+ typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
+ typedef int (*trans_reset)(struct us_data*);
+@@ -160,14 +161,12 @@ struct us_data {
+ 	struct scsi_cmnd	*srb;		 /* current srb		*/
+ 	unsigned int		tag;		 /* current dCBWTag	*/
+ 
+-	/* thread information */
+-	int			pid;		 /* control thread	 */
+-
+ 	/* control and bulk communications data */
+ 	struct urb		*current_urb;	 /* USB requests	 */
+ 	struct usb_ctrlrequest	*cr;		 /* control requests	 */
+ 	struct usb_sg_request	current_sg;	 /* scatter-gather req.  */
+ 	unsigned char		*iobuf;		 /* I/O buffer		 */
++	unsigned char		*sensebuf;	 /* sense data buffer	 */
+ 	dma_addr_t		cr_dma;		 /* buffer DMA addresses */
+ 	dma_addr_t		iobuf_dma;
+ 
+diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
+--- a/drivers/usb/usb-skeleton.c
++++ b/drivers/usb/usb-skeleton.c
+@@ -223,9 +223,8 @@ static struct file_operations skel_fops 
+  * and to have the device registered with devfs and the driver core
+  */
+ static struct usb_class_driver skel_class = {
+-	.name =		"usb/skel%d",
++	.name =		"skel%d",
+ 	.fops =		&skel_fops,
+-	.mode =		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
+ 	.minor_base =	USB_SKEL_MINOR_BASE,
+ };
+ 
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -494,7 +494,7 @@ config FB_TGA
+ 
+ config FB_VESA
+ 	bool "VESA VGA graphics support"
+-	depends on (FB = y) && (X86 || X86_64)
++	depends on (FB = y) && X86
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+@@ -712,7 +712,7 @@ config FB_RIVA_DEBUG
+ 
+ config FB_I810
+ 	tristate "Intel 810/815 support (EXPERIMENTAL)"
+-	depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
++	depends on FB && EXPERIMENTAL && PCI && X86_32
+ 	select AGP
+ 	select AGP_INTEL
+ 	select FB_MODE_HELPERS
+@@ -761,7 +761,7 @@ config FB_I810_I2C
+ 
+ config FB_INTEL
+ 	tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
+-	depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
++	depends on FB && EXPERIMENTAL && PCI && X86_32
+ 	select AGP
+ 	select AGP_INTEL
+ 	select FB_MODE_HELPERS
+@@ -1376,7 +1376,7 @@ config FB_HIT
+ 
+ config FB_PMAG_AA
+ 	bool "PMAG-AA TURBOchannel framebuffer support"
+-	depends on (FB = y) && MACH_DECSTATION && TC
++	depends on (FB = y) && TC
+  	select FB_CFB_FILLRECT
+  	select FB_CFB_COPYAREA
+  	select FB_CFB_IMAGEBLIT
+@@ -1387,7 +1387,7 @@ config FB_PMAG_AA
+ 
+ config FB_PMAG_BA
+ 	bool "PMAG-BA TURBOchannel framebuffer support"
+-	depends on (FB = y) && MACH_DECSTATION && TC
++	depends on (FB = y) && TC
+  	select FB_CFB_FILLRECT
+  	select FB_CFB_COPYAREA
+  	select FB_CFB_IMAGEBLIT
+@@ -1398,7 +1398,7 @@ config FB_PMAG_BA
+ 
+ config FB_PMAGB_B
+ 	bool "PMAGB-B TURBOchannel framebuffer support"
+-	depends on (FB = y) && MACH_DECSTATION && TC
++	depends on (FB = y) && TC
+  	select FB_CFB_FILLRECT
+  	select FB_CFB_COPYAREA
+  	select FB_CFB_IMAGEBLIT
+@@ -1410,7 +1410,7 @@ config FB_PMAGB_B
+ 
+ config FB_MAXINE
+ 	bool "Maxine (Personal DECstation) onboard framebuffer support"
+-	depends on (FB = y) && MACH_DECSTATION && TC
++	depends on (FB = y) && MACH_DECSTATION
+  	select FB_CFB_FILLRECT
+  	select FB_CFB_COPYAREA
+  	select FB_CFB_IMAGEBLIT
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -86,7 +86,7 @@ obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o
+ obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o
+ obj-$(CONFIG_FB_PXA)		  += pxafb.o
+ obj-$(CONFIG_FB_W100)		  += w100fb.o
+-obj-$(CONFIG_FB_AU1100)		  += au1100fb.o fbgen.o
++obj-$(CONFIG_FB_AU1100)		  += au1100fb.o
+ obj-$(CONFIG_FB_PMAG_AA)	  += pmag-aa-fb.o
+ obj-$(CONFIG_FB_PMAG_BA)	  += pmag-ba-fb.o
+ obj-$(CONFIG_FB_PMAGB_B)	  += pmagb-b-fb.o
+diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
+--- a/drivers/video/acornfb.c
++++ b/drivers/video/acornfb.c
+@@ -26,7 +26,7 @@
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/fb.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ 
+ #include <asm/hardware.h>
+diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
+--- a/drivers/video/amba-clcd.c
++++ b/drivers/video/amba-clcd.c
+@@ -22,6 +22,7 @@
+ #include <linux/ioport.h>
+ #include <linux/list.h>
+ 
++#include <asm/sizes.h>
+ #include <asm/hardware/amba.h>
+ #include <asm/hardware/clock.h>
+ 
+diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
+--- a/drivers/video/arcfb.c
++++ b/drivers/video/arcfb.c
+@@ -47,6 +47,7 @@
+ #include <linux/fb.h>
+ #include <linux/init.h>
+ #include <linux/arcfb.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/uaccess.h>
+ 
+diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
+--- a/drivers/video/au1100fb.c
++++ b/drivers/video/au1100fb.c
+@@ -2,6 +2,11 @@
+  * BRIEF MODULE DESCRIPTION
+  *	Au1100 LCD Driver.
+  *
++ * Rewritten for 2.6 by Embedded Alley Solutions
++ * 	<source at embeddedalley.com>, based on submissions by
++ *  	Karl Lessard <klessard at sunrisetelecom.com>
++ *  	<c.pellegrin at exadron.com>
++ *
+  * Copyright 2002 MontaVista Software
+  * Author: MontaVista Software, Inc.
+  *		ppopov at mvista.com or source at mvista.com
+@@ -33,298 +38,253 @@
+  *  with this program; if not, write  to the Free Software Foundation, Inc.,
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+-
++#include <linux/config.h>
+ #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/delay.h>
+ #include <linux/fb.h>
+ #include <linux/init.h>
+-#include <linux/pci.h>
++#include <linux/interrupt.h>
++#include <linux/ctype.h>
++#include <linux/dma-mapping.h>
+ 
+-#include <asm/au1000.h>
+-#include <asm/pb1100.h>
+-#include "au1100fb.h"
++#include <asm/mach-au1x00/au1000.h>
+ 
+-#include <video/fbcon.h>
+-#include <video/fbcon-mfb.h>
+-#include <video/fbcon-cfb2.h>
+-#include <video/fbcon-cfb4.h>
+-#include <video/fbcon-cfb8.h>
+-#include <video/fbcon-cfb16.h>
++#define DEBUG 0
++
++#include "au1100fb.h"
+ 
+ /*
+  * Sanity check. If this is a new Au1100 based board, search for
+  * the PB1100 ifdefs to make sure you modify the code accordingly.
+  */
+-#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_HYDROGEN3)
++#if defined(CONFIG_MIPS_PB1100)
++  #include <asm/mach-pb1x00/pb1100.h>
++#elif defined(CONFIG_MIPS_DB1100)
++  #include <asm/mach-db1x00/db1x00.h>
+ #else
+-error Unknown Au1100 board
++  #error "Unknown Au1100 board, Au1100 FB driver not supported"
+ #endif
+ 
+-#define CMAPSIZE 16
++#define DRIVER_NAME "au1100fb"
++#define DRIVER_DESC "LCD controller driver for AU1100 processors"
+ 
+-static int my_lcd_index; /* default is zero */
+-struct known_lcd_panels *p_lcd;
+-AU1100_LCD *p_lcd_reg = (AU1100_LCD *)AU1100_LCD_ADDR;
+-
+-struct au1100fb_info {
+-	struct fb_info_gen gen;
+-	unsigned long fb_virt_start;
+-	unsigned long fb_size;
+-	unsigned long fb_phys;
+-	int mmaped;
+-	int nohwcursor;
++#define to_au1100fb_device(_info) \
++	  (_info ? container_of(_info, struct au1100fb_device, info) : NULL);
+ 
+-	struct { unsigned red, green, blue, pad; } palette[256];
++/* Bitfields format supported by the controller. Note that the order of formats
++ * SHOULD be the same as in the LCD_CONTROL_SBPPF field, so we can retrieve the
++ * right pixel format by doing rgb_bitfields[LCD_CONTROL_SBPPF_XXX >> LCD_CONTROL_SBPPF]
++ */
++struct fb_bitfield rgb_bitfields[][4] =
++{
++  	/*     Red, 	   Green, 	 Blue, 	     Transp   */
++	{ { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
++	{ { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
++	{ { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
++	{ { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
++	{ { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
+ 
+-#if defined(FBCON_HAS_CFB16)
+-	u16 fbcon_cmap16[16];
+-#endif
++	/* The last is used to describe 12bpp format */
++	{ { 8, 4, 0 },  { 4, 4, 0 }, { 0, 4, 0 }, { 0, 0, 0 } },
+ };
+ 
+-
+-struct au1100fb_par {
+-        struct fb_var_screeninfo var;
+-
+-	int line_length;  // in bytes
+-	int cmap_len;     // color-map length
++static struct fb_fix_screeninfo au1100fb_fix __initdata = {
++	.id		= "AU1100 FB",
++	.xpanstep 	= 1,
++	.ypanstep 	= 1,
++	.type		= FB_TYPE_PACKED_PIXELS,
++	.accel		= FB_ACCEL_NONE,
+ };
+ 
+-
+-static struct au1100fb_info fb_info;
+-static struct au1100fb_par current_par;
+-static struct display disp;
+-
+-int au1100fb_init(void);
+-void au1100fb_setup(char *options, int *ints);
+-static int au1100fb_mmap(struct fb_info *fb, struct file *file,
+-		struct vm_area_struct *vma);
+-static int au1100_blank(int blank_mode, struct fb_info_gen *info);
+-static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+-			  u_long arg, int con, struct fb_info *info);
+-
+-void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
+-
+-static struct fb_ops au1100fb_ops = {
+-	.owner		= THIS_MODULE,
+-	.fb_get_fix	= fbgen_get_fix,
+-	.fb_get_var	= fbgen_get_var,
+-	.fb_set_var	= fbgen_set_var,
+-	.fb_get_cmap	= fbgen_get_cmap,
+-	.fb_set_cmap	= fbgen_set_cmap,
+-	.fb_pan_display	= fbgen_pan_display,
+-        .fb_ioctl	= au1100fb_ioctl,
+-	.fb_mmap	= au1100fb_mmap,
++static struct fb_var_screeninfo au1100fb_var __initdata = {
++	.activate	= FB_ACTIVATE_NOW,
++	.height		= -1,
++	.width		= -1,
++	.vmode		= FB_VMODE_NONINTERLACED,
+ };
+ 
+-static void au1100_detect(void)
+-{
+-	/*
+-	 *  This function should detect the current video mode settings
+-	 *  and store it as the default video mode
+-	 */
++static struct au1100fb_drv_info drv_info;
+ 
+-	/*
+-	 * Yeh, well, we're not going to change any settings so we're
+-	 * always stuck with the default ...
++/*
++ * Set hardware with var settings. This will enable the controller with a specific
++ * mode, normally validated with the fb_check_var method
+ 	 */
+-
+-}
+-
+-static int au1100_encode_fix(struct fb_fix_screeninfo *fix,
+-		const void *_par, struct fb_info_gen *_info)
++int au1100fb_setmode(struct au1100fb_device *fbdev)
+ {
+-        struct au1100fb_info *info = (struct au1100fb_info *) _info;
+-        struct au1100fb_par *par = (struct au1100fb_par *) _par;
+-	struct fb_var_screeninfo *var = &par->var;
+-
+-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+-
+-	fix->smem_start = info->fb_phys;
+-	fix->smem_len = info->fb_size;
+-	fix->type = FB_TYPE_PACKED_PIXELS;
+-	fix->type_aux = 0;
+-        fix->visual = (var->bits_per_pixel == 8) ?
+-	       	FB_VISUAL_PSEUDOCOLOR	: FB_VISUAL_TRUECOLOR;
+-	fix->ywrapstep = 0;
+-	fix->xpanstep = 1;
+-	fix->ypanstep = 1;
+-	fix->line_length = current_par.line_length;
+-	return 0;
+-}
+-
+-static void set_color_bitfields(struct fb_var_screeninfo *var)
+-{
+-	switch (var->bits_per_pixel) {
+-	case 8:
+-		var->red.offset = 0;
+-		var->red.length = 8;
+-		var->green.offset = 0;
+-		var->green.length = 8;
+-		var->blue.offset = 0;
+-		var->blue.length = 8;
+-		var->transp.offset = 0;
+-		var->transp.length = 0;
+-		break;
+-	case 16:	/* RGB 565 */
+-		var->red.offset = 11;
+-		var->red.length = 5;
+-		var->green.offset = 5;
+-		var->green.length = 6;
+-		var->blue.offset = 0;
+-		var->blue.length = 5;
+-		var->transp.offset = 0;
+-		var->transp.length = 0;
+-		break;
+-	}
++	struct fb_info *info = &fbdev->info;
++	u32 words;
++	int index;
+ 
+-	var->red.msb_right = 0;
+-	var->green.msb_right = 0;
+-	var->blue.msb_right = 0;
+-	var->transp.msb_right = 0;
+-}
+-
+-static int au1100_decode_var(const struct fb_var_screeninfo *var,
+-		void *_par, struct fb_info_gen *_info)
+-{
+-
+-	struct au1100fb_par *par = (struct au1100fb_par *)_par;
+-
+-	/*
+-	 * Don't allow setting any of these yet: xres and yres don't
+-	 * make sense for LCD panels.
+-	 */
+-	if (var->xres != p_lcd->xres ||
+-	    var->yres != p_lcd->yres ||
+-	    var->xres != p_lcd->xres ||
+-	    var->yres != p_lcd->yres) {
++	if (!fbdev)
+ 		return -EINVAL;
++
++	/* Update var-dependent FB info */
++	if (panel_is_active(fbdev->panel) || panel_is_color(fbdev->panel)) {
++		if (info->var.bits_per_pixel <= 8) {
++			/* palettized */
++			info->var.red.offset    = 0;
++			info->var.red.length    = info->var.bits_per_pixel;
++			info->var.red.msb_right = 0;
++
++			info->var.green.offset  = 0;
++			info->var.green.length  = info->var.bits_per_pixel;
++			info->var.green.msb_right = 0;
++
++			info->var.blue.offset   = 0;
++			info->var.blue.length   = info->var.bits_per_pixel;
++			info->var.blue.msb_right = 0;
++
++			info->var.transp.offset = 0;
++			info->var.transp.length = 0;
++			info->var.transp.msb_right = 0;
++
++			info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
++			info->fix.line_length = info->var.xres_virtual /
++							(8/info->var.bits_per_pixel);
++		} else {
++			/* non-palettized */
++			index = (fbdev->panel->control_base & LCD_CONTROL_SBPPF_MASK) >> LCD_CONTROL_SBPPF_BIT;
++			info->var.red = rgb_bitfields[index][0];
++			info->var.green = rgb_bitfields[index][1];
++			info->var.blue = rgb_bitfields[index][2];
++			info->var.transp = rgb_bitfields[index][3];
++
++			info->fix.visual = FB_VISUAL_TRUECOLOR;
++			info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */
++	}
++	} else {
++		/* mono */
++		info->fix.visual = FB_VISUAL_MONO10;
++		info->fix.line_length = info->var.xres_virtual / 8;
++	}
++
++	info->screen_size = info->fix.line_length * info->var.yres_virtual;
++
++	/* Determine BPP mode and format */
++	fbdev->regs->lcd_control = fbdev->panel->control_base |
++			    ((info->var.rotate/90) << LCD_CONTROL_SM_BIT);
++
++	fbdev->regs->lcd_intenable = 0;
++	fbdev->regs->lcd_intstatus = 0;
++
++	fbdev->regs->lcd_horztiming = fbdev->panel->horztiming;
++
++	fbdev->regs->lcd_verttiming = fbdev->panel->verttiming;
++
++	fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base;
++
++	fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys);
++
++	if (panel_is_dual(fbdev->panel)) {
++		/* Second panel display seconf half of screen if possible,
++		 * otherwise display the same as the first panel */
++		if (info->var.yres_virtual >= (info->var.yres << 1)) {
++			fbdev->regs->lcd_dmaaddr1 = LCD_DMA_SA_N(fbdev->fb_phys +
++							  (info->fix.line_length *
++						          (info->var.yres_virtual >> 1)));
++		} else {
++			fbdev->regs->lcd_dmaaddr1 = LCD_DMA_SA_N(fbdev->fb_phys);
++		}
+ 	}
+-	if(var->bits_per_pixel != p_lcd->bpp) {
+-		return -EINVAL;
++
++	words = info->fix.line_length / sizeof(u32);
++	if (!info->var.rotate || (info->var.rotate == 180)) {
++		words *= info->var.yres_virtual;
++		if (info->var.rotate /* 180 */) {
++			words -= (words % 8); /* should be divisable by 8 */
++		}
+ 	}
++	fbdev->regs->lcd_words = LCD_WRD_WRDS_N(words);
+ 
+-	memset(par, 0, sizeof(struct au1100fb_par));
+-	par->var = *var;
++	fbdev->regs->lcd_pwmdiv = 0;
++	fbdev->regs->lcd_pwmhi = 0;
+ 
+-	/* FIXME */
+-	switch (var->bits_per_pixel) {
+-		case 8:
+-			par->var.bits_per_pixel = 8;
+-			break;
+-		case 16:
+-			par->var.bits_per_pixel = 16;
+-			break;
+-		default:
+-			printk("color depth %d bpp not supported\n",
+-					var->bits_per_pixel);
+-			return -EINVAL;
++	/* Resume controller */
++	fbdev->regs->lcd_control |= LCD_CONTROL_GO;
+ 
+-	}
+-	set_color_bitfields(&par->var);
+-	par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;
+ 	return 0;
+ }
+ 
+-static int au1100_encode_var(struct fb_var_screeninfo *var,
+-		const void *par, struct fb_info_gen *_info)
++/* fb_setcolreg
++ * Set color in LCD palette.
++ */
++int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
+ {
++	struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
++	u32 *palette = fbdev->regs->lcd_pallettebase;
++	u32 value;
+ 
+-	*var = ((struct au1100fb_par *)par)->var;
+-	return 0;
+-}
+-
+-static void
+-au1100_get_par(void *_par, struct fb_info_gen *_info)
+-{
+-	*(struct au1100fb_par *)_par = current_par;
+-}
++	if (regno > (AU1100_LCD_NBR_PALETTE_ENTRIES - 1))
++		return -EINVAL;
+ 
+-static void au1100_set_par(const void *par, struct fb_info_gen *info)
+-{
+-	/* nothing to do: we don't change any settings */
+-}
++	if (fbi->var.grayscale) {
++		/* Convert color to grayscale */
++		red = green = blue =
++			(19595 * red + 38470 * green + 7471 * blue) >> 16;
++	}
+ 
+-static int au1100_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+-			 unsigned *blue, unsigned *transp,
+-			 struct fb_info *info)
+-{
++	if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
++		/* Place color in the pseudopalette */
++		if (regno > 16)
++			return -EINVAL;
+ 
+-	struct au1100fb_info* i = (struct au1100fb_info*)info;
++		palette = (u32*)fbi->pseudo_palette;
+ 
+-	if (regno > 255)
+-		return 1;
++		red   >>= (16 - fbi->var.red.length);
++		green >>= (16 - fbi->var.green.length);
++		blue  >>= (16 - fbi->var.blue.length);
++
++		value = (red   << fbi->var.red.offset) 	|
++			(green << fbi->var.green.offset)|
++			(blue  << fbi->var.blue.offset);
++		value &= 0xFFFF;
++
++	} else if (panel_is_active(fbdev->panel)) {
++		/* COLOR TFT PALLETTIZED (use RGB 565) */
++		value = (red & 0xF800)|((green >> 5) & 0x07E0)|((blue >> 11) & 0x001F);
++		value &= 0xFFFF;
++
++	} else if (panel_is_color(fbdev->panel)) {
++		/* COLOR STN MODE */
++		value = (((panel_swap_rgb(fbdev->panel) ? blue : red) >> 12) & 0x000F) |
++			((green >> 8) & 0x00F0) |
++			(((panel_swap_rgb(fbdev->panel) ? red : blue) >> 4) & 0x0F00);
++		value &= 0xFFF;
++	} else {
++		/* MONOCHROME MODE */
++		value = (green >> 12) & 0x000F;
++		value &= 0xF;
++	}
+ 
+-	*red    = i->palette[regno].red;
+-	*green  = i->palette[regno].green;
+-	*blue   = i->palette[regno].blue;
+-	*transp = 0;
++	palette[regno] = value;
+ 
+ 	return 0;
+ }
+ 
+-static int au1100_setcolreg(unsigned regno, unsigned red, unsigned green,
+-			 unsigned blue, unsigned transp,
+-			 struct fb_info *info)
++/* fb_blank
++ * Blank the screen. Depending on the mode, the screen will be
++ * activated with the backlight color, or desactivated
++ */
++int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
+ {
+-	struct au1100fb_info* i = (struct au1100fb_info *)info;
+-	u32 rgbcol;
+-
+-	if (regno > 255)
+-		return 1;
+-
+-	i->palette[regno].red    = red;
+-	i->palette[regno].green  = green;
+-	i->palette[regno].blue   = blue;
+-
+-	switch(p_lcd->bpp) {
+-#ifdef FBCON_HAS_CFB8
+-	case 8:
+-		red >>= 10;
+-		green >>= 10;
+-		blue >>= 10;
+-		p_lcd_reg->lcd_pallettebase[regno] = (blue&0x1f) |
+-			((green&0x3f)<<5) | ((red&0x1f)<<11);
+-		break;
+-#endif
+-#ifdef FBCON_HAS_CFB16
+-	case 16:
+-		i->fbcon_cmap16[regno] =
+-			((red & 0xf800) >> 0) |
+-			((green & 0xfc00) >> 5) |
+-			((blue & 0xf800) >> 11);
+-		break;
+-#endif
+-	default:
+-		break;
+-	}
+-
+-	return 0;
+-}
+-
++	struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+ 
+-static int  au1100_blank(int blank_mode, struct fb_info_gen *_info)
+-{
++	print_dbg("fb_blank %d %p", blank_mode, fbi);
+ 
+ 	switch (blank_mode) {
++
+ 	case VESA_NO_BLANKING:
+-		/* turn on panel */
+-		//printk("turn on panel\n");
++			/* Turn on panel */
++			fbdev->regs->lcd_control |= LCD_CONTROL_GO;
+ #ifdef CONFIG_MIPS_PB1100
+-		p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
+-		au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight,
++			if (drv_info.panel_idx == 1) {
++				au_writew(au_readw(PB1100_G_CONTROL)
++					  | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
+ 			PB1100_G_CONTROL);
+-#endif
+-#ifdef CONFIG_MIPS_HYDROGEN3
+-		/*  Turn controller & power supply on,  GPIO213 */
+-		au_writel(0x20002000, 0xB1700008);
+-		au_writel(0x00040000, 0xB1900108);
+-		au_writel(0x01000100, 0xB1700008);
++			}
+ #endif
+ 		au_sync();
+ 		break;
+@@ -332,12 +292,14 @@ static int  au1100_blank(int blank_mode,
+ 	case VESA_VSYNC_SUSPEND:
+ 	case VESA_HSYNC_SUSPEND:
+ 	case VESA_POWERDOWN:
+-		/* turn off panel */
+-		//printk("turn off panel\n");
++			/* Turn off panel */
++			fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
+ #ifdef CONFIG_MIPS_PB1100
+-		au_writew(au_readw(PB1100_G_CONTROL) & ~p_lcd->mode_backlight,
++			if (drv_info.panel_idx == 1) {
++				au_writew(au_readw(PB1100_G_CONTROL)
++				  	  & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
+ 			PB1100_G_CONTROL);
+-		p_lcd_reg->lcd_control &= ~LCD_CONTROL_GO;
++			}
+ #endif
+ 		au_sync();
+ 		break;
+@@ -348,49 +310,87 @@ static int  au1100_blank(int blank_mode,
+ 	return 0;
+ }
+ 
+-static void au1100_set_disp(const void *unused, struct display *disp,
+-			 struct fb_info_gen *info)
++/* fb_pan_display
++ * Pan display in x and/or y as specified
++ */
++int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
+ {
+-	disp->screen_base = (char *)fb_info.fb_virt_start;
++	struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
++	int dy;
+ 
+-	switch (disp->var.bits_per_pixel) {
+-#ifdef FBCON_HAS_CFB8
+-	case 8:
+-		disp->dispsw = &fbcon_cfb8;
+-		if (fb_info.nohwcursor)
+-			fbcon_cfb8.cursor = au1100_nocursor;
+-		break;
+-#endif
+-#ifdef FBCON_HAS_CFB16
+-	case 16:
+-		disp->dispsw = &fbcon_cfb16;
+-		disp->dispsw_data = fb_info.fbcon_cmap16;
+-		if (fb_info.nohwcursor)
+-			fbcon_cfb16.cursor = au1100_nocursor;
+-		break;
+-#endif
+-	default:
+-		disp->dispsw = &fbcon_dummy;
+-		disp->dispsw_data = NULL;
+-		break;
++	print_dbg("fb_pan_display %p %p", var, fbi);
++
++	if (!var || !fbdev) {
++		return -EINVAL;
++	}
++
++	if (var->xoffset - fbi->var.xoffset) {
++		/* No support for X panning for now! */
++		return -EINVAL;
++	}
++
++	print_dbg("fb_pan_display 2 %p %p", var, fbi);
++	dy = var->yoffset - fbi->var.yoffset;
++	if (dy) {
++
++		u32 dmaaddr;
++
++		print_dbg("Panning screen of %d lines", dy);
++
++		dmaaddr = fbdev->regs->lcd_dmaaddr0;
++		dmaaddr += (fbi->fix.line_length * dy);
++
++		/* TODO: Wait for current frame to finished */
++		fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(dmaaddr);
++
++		if (panel_is_dual(fbdev->panel)) {
++			dmaaddr = fbdev->regs->lcd_dmaaddr1;
++			dmaaddr += (fbi->fix.line_length * dy);
++			fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(dmaaddr);
++	}
++	}
++	print_dbg("fb_pan_display 3 %p %p", var, fbi);
++
++	return 0;
++}
++
++/* fb_rotate
++ * Rotate the display of this angle. This doesn't seems to be used by the core,
++ * but as our hardware supports it, so why not implementing it...
++ */
++void au1100fb_fb_rotate(struct fb_info *fbi, int angle)
++{
++	struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
++
++	print_dbg("fb_rotate %p %d", fbi, angle);
++
++	if (fbdev && (angle > 0) && !(angle % 90)) {
++
++		fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
++
++		fbdev->regs->lcd_control &= ~(LCD_CONTROL_SM_MASK);
++		fbdev->regs->lcd_control |= ((angle/90) << LCD_CONTROL_SM_BIT);
++
++		fbdev->regs->lcd_control |= LCD_CONTROL_GO;
+ 	}
+ }
+ 
+-static int
+-au1100fb_mmap(struct fb_info *_fb,
+-	     struct file *file,
+-	     struct vm_area_struct *vma)
++/* fb_mmap
++ * Map video memory in user space. We don't use the generic fb_mmap method mainly
++ * to allow the use of the TLB streaming flag (CCA=6)
++ */
++int au1100fb_fb_mmap(struct fb_info *fbi, struct file *file, struct vm_area_struct *vma)
+ {
++	struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+ 	unsigned int len;
+ 	unsigned long start=0, off;
+-	struct au1100fb_info *fb = (struct au1100fb_info *)_fb;
+ 
+ 	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
+ 		return -EINVAL;
+ 	}
+ 
+-	start = fb_info.fb_phys & PAGE_MASK;
+-	len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info.fb_size);
++	start = fbdev->fb_phys & PAGE_MASK;
++	len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
+ 
+ 	off = vma->vm_pgoff << PAGE_SHIFT;
+ 
+@@ -401,276 +401,309 @@ au1100fb_mmap(struct fb_info *_fb,
+ 	off += start;
+ 	vma->vm_pgoff = off >> PAGE_SHIFT;
+ 
+-	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+-	//pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
++	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ 	pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
+ 
+-	/* This is an IO map - tell maydump to skip this VMA */
+ 	vma->vm_flags |= VM_IO;
+ 
+-	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
++	if (io_remap_page_range(vma, vma->vm_start, off,
+ 				vma->vm_end - vma->vm_start,
+ 				vma->vm_page_prot)) {
+ 		return -EAGAIN;
+ 	}
+ 
+-	fb->mmaped = 1;
+ 	return 0;
+ }
+ 
+-int au1100_pan_display(const struct fb_var_screeninfo *var,
+-		       struct fb_info_gen *info)
++static struct fb_ops au1100fb_ops =
+ {
+-	return 0;
+-}
++	.owner			= THIS_MODULE,
++	.fb_setcolreg		= au1100fb_fb_setcolreg,
++	.fb_blank		= au1100fb_fb_blank,
++	.fb_pan_display		= au1100fb_fb_pan_display,
++	.fb_fillrect		= cfb_fillrect,
++	.fb_copyarea		= cfb_copyarea,
++	.fb_imageblit		= cfb_imageblit,
++	.fb_rotate		= au1100fb_fb_rotate,
++	.fb_mmap		= au1100fb_fb_mmap,
++};
+ 
+-static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+-			  u_long arg, int con, struct fb_info *info)
+-{
+-	/* nothing to do yet */
+-	return -EINVAL;
+-}
+ 
+-static struct fbgen_hwswitch au1100_switch = {
+-	au1100_detect,
+-	au1100_encode_fix,
+-	au1100_decode_var,
+-	au1100_encode_var,
+-	au1100_get_par,
+-	au1100_set_par,
+-	au1100_getcolreg,
+-	au1100_setcolreg,
+-	au1100_pan_display,
+-	au1100_blank,
+-	au1100_set_disp
+-};
++/*-------------------------------------------------------------------------*/
+ 
++/* AU1100 LCD controller device driver */
+ 
+-int au1100_setmode(void)
++int au1100fb_drv_probe(struct device *dev)
+ {
+-	int words;
++	struct au1100fb_device *fbdev = NULL;
++	struct resource *regs_res;
++	unsigned long page;
++	u32 sys_clksrc;
+ 
+-	/* FIXME Need to accomodate for swivel mode and 12bpp, <8bpp*/
+-	switch (p_lcd->mode_control & LCD_CONTROL_SM)
+-	{
+-		case LCD_CONTROL_SM_0:
+-		case LCD_CONTROL_SM_180:
+-		words = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 32;
+-			break;
+-		case LCD_CONTROL_SM_90:
+-		case LCD_CONTROL_SM_270:
+-			/* is this correct? */
+-		words = (p_lcd->xres * p_lcd->bpp) / 8;
+-			break;
+-		default:
+-			printk("mode_control reg not initialized\n");
++	if (!dev)
+ 			return -EINVAL;
++
++	/* Allocate new device private */
++	if (!(fbdev = kmalloc(sizeof(struct au1100fb_device), GFP_KERNEL))) {
++		print_err("fail to allocate device private record");
++		return -ENOMEM;
+ 	}
++	memset((void*)fbdev, 0, sizeof(struct au1100fb_device));
+ 
+-	/*
+-	 * Setup LCD controller
+-	 */
++	fbdev->panel = &known_lcd_panels[drv_info.panel_idx];
+ 
+-	p_lcd_reg->lcd_control = p_lcd->mode_control;
+-	p_lcd_reg->lcd_intstatus = 0;
+-	p_lcd_reg->lcd_intenable = 0;
+-	p_lcd_reg->lcd_horztiming = p_lcd->mode_horztiming;
+-	p_lcd_reg->lcd_verttiming = p_lcd->mode_verttiming;
+-	p_lcd_reg->lcd_clkcontrol = p_lcd->mode_clkcontrol;
+-	p_lcd_reg->lcd_words = words - 1;
+-	p_lcd_reg->lcd_dmaaddr0 = fb_info.fb_phys;
++	dev_set_drvdata(dev, (void*)fbdev);
+ 
+-	/* turn on panel */
+-#ifdef CONFIG_MIPS_PB1100
+-	au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight,
+-			PB1100_G_CONTROL);
+-#endif
+-#ifdef CONFIG_MIPS_HYDROGEN3
+-	/*  Turn controller & power supply on,  GPIO213 */
+-	au_writel(0x20002000, 0xB1700008);
+-	au_writel(0x00040000, 0xB1900108);
+-	au_writel(0x01000100, 0xB1700008);
+-#endif
++	/* Allocate region for our registers and map them */
++	if (!(regs_res = platform_get_resource(to_platform_device(dev),
++					IORESOURCE_MEM, 0))) {
++		print_err("fail to retrieve registers resource");
++		return -EFAULT;
++	}
+ 
+-	p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
++	au1100fb_fix.mmio_start = regs_res->start;
++	au1100fb_fix.mmio_len = regs_res->end - regs_res->start + 1;
+ 
+-	return 0;
+-}
++	if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len,
++				DRIVER_NAME)) {
++		print_err("fail to lock memory region at 0x%08x",
++				au1100fb_fix.mmio_start);
++		return -EBUSY;
++	}
+ 
++	fbdev->regs = (struct au1100fb_regs*)KSEG1ADDR(au1100fb_fix.mmio_start);
+ 
+-int __init au1100fb_init(void)
+-{
+-	uint32 sys_clksrc;
+-	unsigned long page;
++	print_dbg("Register memory map at %p", fbdev->regs);
++	print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len);
+ 
+-	/*
+-	* Get the panel information/display mode and update the registry
+-	*/
+-	p_lcd = &panels[my_lcd_index];
+-
+-	switch (p_lcd->mode_control & LCD_CONTROL_SM)
+-	{
+-		case LCD_CONTROL_SM_0:
+-		case LCD_CONTROL_SM_180:
+-		p_lcd->xres =
+-			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
+-		p_lcd->yres =
+-			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
+-			break;
+-		case LCD_CONTROL_SM_90:
+-		case LCD_CONTROL_SM_270:
+-		p_lcd->yres =
+-			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
+-		p_lcd->xres =
+-			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
+-			break;
+-	}
+ 
+-	/*
+-	 * Panel dimensions x bpp must be divisible by 32
+-	 */
+-	if (((p_lcd->yres * p_lcd->bpp) % 32) != 0)
+-		printk("VERT %% 32\n");
+-	if (((p_lcd->xres * p_lcd->bpp) % 32) != 0)
+-		printk("HORZ %% 32\n");
+ 
+-	/*
+-	 * Allocate LCD framebuffer from system memory
+-	 */
+-	fb_info.fb_size = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 8;
++	/* Allocate the framebuffer to the maximum screen size * nbr of video buffers */
++	fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
++		  	(fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
+ 
+-	current_par.var.xres = p_lcd->xres;
+-	current_par.var.xres_virtual = p_lcd->xres;
+-	current_par.var.yres = p_lcd->yres;
+-	current_par.var.yres_virtual = p_lcd->yres;
+-	current_par.var.bits_per_pixel = p_lcd->bpp;
+-
+-	/* FIX!!! only works for 8/16 bpp */
+-	current_par.line_length = p_lcd->xres * p_lcd->bpp / 8; /* in bytes */
+-	fb_info.fb_virt_start = (unsigned long )
+-		__get_free_pages(GFP_ATOMIC | GFP_DMA,
+-				get_order(fb_info.fb_size + 0x1000));
+-	if (!fb_info.fb_virt_start) {
+-		printk("Unable to allocate fb memory\n");
++	fbdev->fb_mem = dma_alloc_coherent(dev, PAGE_ALIGN(fbdev->fb_len),
++					&fbdev->fb_phys, GFP_KERNEL);
++	if (!fbdev->fb_mem) {
++		print_err("fail to allocate frambuffer (size: %dK))",
++			  fbdev->fb_len / 1024);
+ 		return -ENOMEM;
+ 	}
+-	fb_info.fb_phys = virt_to_bus((void *)fb_info.fb_virt_start);
++
++	au1100fb_fix.smem_start = fbdev->fb_phys;
++	au1100fb_fix.smem_len = fbdev->fb_len;
+ 
+ 	/*
+ 	 * Set page reserved so that mmap will work. This is necessary
+ 	 * since we'll be remapping normal memory.
+ 	 */
+-	for (page = fb_info.fb_virt_start;
+-	     page < PAGE_ALIGN(fb_info.fb_virt_start + fb_info.fb_size);
++	for (page = (unsigned long)fbdev->fb_mem;
++	     page < PAGE_ALIGN((unsigned long)fbdev->fb_mem + fbdev->fb_len);
+ 	     page += PAGE_SIZE) {
++#if CONFIG_DMA_NONCOHERENT
++		SetPageReserved(virt_to_page(CAC_ADDR(page)));
++#else
+ 		SetPageReserved(virt_to_page(page));
++#endif
+ 	}
+ 
+-	memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);
++	print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
++	print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
+ 
+-	/* set freqctrl now to allow more time to stabilize */
+-	/* zero-out out LCD bits */
+-	sys_clksrc = au_readl(SYS_CLKSRC) & ~0x000003e0;
+-	sys_clksrc |= p_lcd->mode_toyclksrc;
+-	au_writel(sys_clksrc, SYS_CLKSRC);
+-
+-	/* FIXME add check to make sure auxpll is what is expected! */
+-	au1100_setmode();
+-
+-	fb_info.gen.parsize = sizeof(struct au1100fb_par);
+-	fb_info.gen.fbhw = &au1100_switch;
+-
+-	strcpy(fb_info.gen.info.modename, "Au1100 LCD");
+-	fb_info.gen.info.changevar = NULL;
+-	fb_info.gen.info.node = -1;
+-
+-	fb_info.gen.info.fbops = &au1100fb_ops;
+-	fb_info.gen.info.disp = &disp;
+-	fb_info.gen.info.switch_con = &fbgen_switch;
+-	fb_info.gen.info.updatevar = &fbgen_update_var;
+-	fb_info.gen.info.blank = &fbgen_blank;
+-	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+-
+-	/* This should give a reasonable default video mode */
+-	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+-	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+-	fbgen_set_disp(-1, &fb_info.gen);
+-	fbgen_install_cmap(0, &fb_info.gen);
+-	if (register_framebuffer(&fb_info.gen.info) < 0)
+-		return -EINVAL;
+-	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+-			GET_FB_IDX(fb_info.gen.info.node),
+-			fb_info.gen.info.modename);
++	/* Setup LCD clock to AUX (48 MHz) */
++	sys_clksrc = au_readl(SYS_CLKSRC) & ~(SYS_CS_ML_MASK | SYS_CS_DL | SYS_CS_CL);
++	au_writel((sys_clksrc | (1 << SYS_CS_ML_BIT)), SYS_CLKSRC);
++
++	/* load the panel info into the var struct */
++	au1100fb_var.bits_per_pixel = fbdev->panel->bpp;
++	au1100fb_var.xres = fbdev->panel->xres;
++	au1100fb_var.xres_virtual = au1100fb_var.xres;
++	au1100fb_var.yres = fbdev->panel->yres;
++	au1100fb_var.yres_virtual = au1100fb_var.yres;
++
++	fbdev->info.screen_base = fbdev->fb_mem;
++	fbdev->info.fbops = &au1100fb_ops;
++	fbdev->info.fix = au1100fb_fix;
++
++	if (!(fbdev->info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL))) {
++		return -ENOMEM;
++	}
++	memset(fbdev->info.pseudo_palette, 0, sizeof(u32) * 16);
++
++	if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
++		print_err("Fail to allocate colormap (%d entries)",
++			   AU1100_LCD_NBR_PALETTE_ENTRIES);
++		kfree(fbdev->info.pseudo_palette);
++		return -EFAULT;
++	}
++
++	fbdev->info.var = au1100fb_var;
++
++	/* Set h/w registers */
++	au1100fb_setmode(fbdev);
++
++	/* Register new framebuffer */
++	if (register_framebuffer(&fbdev->info) < 0) {
++		print_err("cannot register new framebuffer");
++		goto failed;
++	}
+ 
+ 	return 0;
+-}
+ 
++failed:
++	if (fbdev->regs) {
++		release_mem_region(fbdev->regs_phys, fbdev->regs_len);
++	}
++	if (fbdev->fb_mem) {
++		dma_free_noncoherent(dev, fbdev->fb_len, fbdev->fb_mem, fbdev->fb_phys);
++	}
++	if (fbdev->info.cmap.len != 0) {
++		fb_dealloc_cmap(&fbdev->info.cmap);
++	}
++	kfree(fbdev);
++	dev_set_drvdata(dev, NULL);
++
++	return 0;
++}
+ 
+-void au1100fb_cleanup(struct fb_info *info)
++int au1100fb_drv_remove(struct device *dev)
+ {
+-	unregister_framebuffer(info);
++	struct au1100fb_device *fbdev = NULL;
++
++	if (!dev)
++		return -ENODEV;
++
++	fbdev = (struct au1100fb_device*) dev_get_drvdata(dev);
++
++#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
++	au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
++#endif
++	fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
++
++	/* Clean up all probe data */
++	unregister_framebuffer(&fbdev->info);
++
++	release_mem_region(fbdev->regs_phys, fbdev->regs_len);
++
++	dma_free_coherent(dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem, fbdev->fb_phys);
++
++	fb_dealloc_cmap(&fbdev->info.cmap);
++	kfree(fbdev->info.pseudo_palette);
++	kfree((void*)fbdev);
++
++	return 0;
+ }
+ 
++int au1100fb_drv_suspend(struct device *dev, u32 state, u32 level)
++{
++	/* TODO */
++	return 0;
++}
+ 
+-void au1100fb_setup(char *options, int *ints)
++int au1100fb_drv_resume(struct device *dev, u32 level)
+ {
+-	char* this_opt;
+-	int i;
+-	int num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);
++	/* TODO */
++	return 0;
++}
++
++static struct device_driver au1100fb_driver = {
++	.name		= "au1100-lcd",
++	.bus		= &platform_bus_type,
++
++	.probe		= au1100fb_drv_probe,
++        .remove		= au1100fb_drv_remove,
++	.suspend	= au1100fb_drv_suspend,
++        .resume		= au1100fb_drv_resume,
++};
+ 
++/*-------------------------------------------------------------------------*/
+ 
+-	if (!options || !*options)
+-		return;
++/* Kernel driver */
+ 
+-	for(this_opt=strtok(options, ","); this_opt;
+-	    this_opt=strtok(NULL, ",")) {
+-		if (!strncmp(this_opt, "panel:", 6)) {
+-#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100)
+-			/* Read Pb1100 Switch S10 ? */
+-			if (!strncmp(this_opt+6, "s10", 3))
+-			{
+-				int panel;
+-				panel = *(volatile int *)0xAE000008; /* BCSR SWITCHES */
+-				panel >>= 8;
+-				panel &= 0x0F;
+-				if (panel >= num_panels) panel = 0;
+-				my_lcd_index = panel;
++int au1100fb_setup(char *options)
++{
++	char* this_opt;
++	int num_panels = ARRAY_SIZE(known_lcd_panels);
++	char* mode = NULL;
++	int panel_idx = 0;
++
++	if (num_panels <= 0) {
++		print_err("No LCD panels supported by driver!");
++		return -EFAULT;
+ 			}
+-			else
+-#endif
+-			/* Get the panel name, everything else if fixed */
+-			for (i=0; i<num_panels; i++) {
+-				if (!strncmp(this_opt+6, panels[i].panel_name,
++
++	if (options) {
++		while ((this_opt = strsep(&options,",")) != NULL) {
++			/* Panel option */
++		if (!strncmp(this_opt, "panel:", 6)) {
++				int i;
++				this_opt += 6;
++				for (i = 0; i < num_panels; i++) {
++					if (!strncmp(this_opt,
++					      	     known_lcd_panels[i].name,
+ 							strlen(this_opt))) {
+-					my_lcd_index = i;
++						panel_idx = i;
+ 					break;
+ 				}
+ 			}
++				if (i >= num_panels) {
++ 					print_warn("Panel %s not supported!", this_opt);
++				}
++			}
++			/* Mode option (only option that start with digit) */
++			else if (isdigit(this_opt[0])) {
++				mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL);
++				strncpy(mode, this_opt, strlen(this_opt) + 1);
++			}
++			/* Unsupported option */
++			else {
++				print_warn("Unsupported option \"%s\"", this_opt);
+ 		}
+-		else if (!strncmp(this_opt, "nohwcursor", 10)) {
+-			printk("nohwcursor\n");
+-			fb_info.nohwcursor = 1;
+ 		}
+ 	}
+ 
+-	printk("au1100fb: Panel %d %s\n", my_lcd_index,
+-		panels[my_lcd_index].panel_name);
+-}
++	drv_info.panel_idx = panel_idx;
++	drv_info.opt_mode = mode;
+ 
++	print_info("Panel=%s Mode=%s",
++			known_lcd_panels[drv_info.panel_idx].name,
++		      	drv_info.opt_mode ? drv_info.opt_mode : "default");
+ 
++	return 0;
++}
+ 
+-#ifdef MODULE
+-MODULE_LICENSE("GPL");
+-int init_module(void)
++int __init au1100fb_init(void)
+ {
+-	return au1100fb_init();
++	char* options;
++	int ret;
++
++	print_info("" DRIVER_DESC "");
++
++	memset(&drv_info, 0, sizeof(drv_info));
++
++	if (fb_get_options(DRIVER_NAME, &options))
++		return -ENODEV;
++
++	/* Setup driver with options */
++	ret = au1100fb_setup(options);
++	if (ret < 0) {
++		print_err("Fail to setup driver");
++		return ret;
++	}
++
++	return driver_register(&au1100fb_driver);
+ }
+ 
+-void cleanup_module(void)
++void __exit au1100fb_cleanup(void)
+ {
+-	au1100fb_cleanup(void);
++	driver_unregister(&au1100fb_driver);
++
++	if (drv_info.opt_mode)
++		kfree(drv_info.opt_mode);
+ }
+ 
+-MODULE_AUTHOR("Pete Popov <ppopov at mvista.com>");
+-MODULE_DESCRIPTION("Au1100 LCD framebuffer device driver");
+-#endif /* MODULE */
++module_init(au1100fb_init);
++module_exit(au1100fb_cleanup);
++
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/video/au1100fb.h b/drivers/video/au1100fb.h
+--- a/drivers/video/au1100fb.h
++++ b/drivers/video/au1100fb.h
+@@ -30,352 +30,352 @@
+ #ifndef _AU1100LCD_H
+ #define _AU1100LCD_H
+ 
++#include <asm/mach-au1x00/au1000.h>
++
++#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
++#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
++#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
++
++#if DEBUG
++#define print_dbg(f, arg...) printk(__FILE__ ": " f "\n", ## arg)
++#else
++#define print_dbg(f, arg...) do {} while (0)
++#endif
++
++#if defined(__BIG_ENDIAN)
++#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
++#else
++#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
++#endif
++#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
++
+ /********************************************************************/
+-#define uint32 unsigned long
+-typedef volatile struct
+-{
+-	uint32	lcd_control;
+-	uint32	lcd_intstatus;
+-	uint32	lcd_intenable;
+-	uint32	lcd_horztiming;
+-	uint32	lcd_verttiming;
+-	uint32	lcd_clkcontrol;
+-	uint32	lcd_dmaaddr0;
+-	uint32	lcd_dmaaddr1;
+-	uint32	lcd_words;
+-	uint32	lcd_pwmdiv;
+-	uint32	lcd_pwmhi;
+-	uint32	reserved[(0x0400-0x002C)/4];
+-	uint32	lcd_pallettebase[256];
+ 
+-} AU1100_LCD;
++/* LCD controller restrictions */
++#define AU1100_LCD_MAX_XRES	800
++#define AU1100_LCD_MAX_YRES	600
++#define AU1100_LCD_MAX_BPP	16
++#define AU1100_LCD_MAX_CLK	48000000
++#define AU1100_LCD_NBR_PALETTE_ENTRIES 256
++
++/* Default number of visible screen buffer to allocate */
++#define AU1100FB_NBR_VIDEO_BUFFERS 4
+ 
+ /********************************************************************/
+ 
+-#define AU1100_LCD_ADDR		0xB5000000
++struct au1100fb_panel
++{
++	const char name[25];		/* Full name <vendor>_<model> */
+ 
+-/*
+- * Register bit definitions
+- */
++	u32   	control_base;		/* Mode-independent control values */
++	u32	clkcontrol_base;	/* Panel pixclock preferences */
+ 
+-/* lcd_control */
+-#define LCD_CONTROL_SBPPF		(7<<18)
+-#define LCD_CONTROL_SBPPF_655	(0<<18)
+-#define LCD_CONTROL_SBPPF_565	(1<<18)
+-#define LCD_CONTROL_SBPPF_556	(2<<18)
+-#define LCD_CONTROL_SBPPF_1555	(3<<18)
+-#define LCD_CONTROL_SBPPF_5551	(4<<18)
+-#define LCD_CONTROL_WP			(1<<17)
+-#define LCD_CONTROL_WD			(1<<16)
+-#define LCD_CONTROL_C			(1<<15)
+-#define LCD_CONTROL_SM			(3<<13)
+-#define LCD_CONTROL_SM_0		(0<<13)
+-#define LCD_CONTROL_SM_90		(1<<13)
+-#define LCD_CONTROL_SM_180		(2<<13)
+-#define LCD_CONTROL_SM_270		(3<<13)
+-#define LCD_CONTROL_DB			(1<<12)
+-#define LCD_CONTROL_CCO			(1<<11)
+-#define LCD_CONTROL_DP			(1<<10)
+-#define LCD_CONTROL_PO			(3<<8)
+-#define LCD_CONTROL_PO_00		(0<<8)
+-#define LCD_CONTROL_PO_01		(1<<8)
+-#define LCD_CONTROL_PO_10		(2<<8)
+-#define LCD_CONTROL_PO_11		(3<<8)
+-#define LCD_CONTROL_MPI			(1<<7)
+-#define LCD_CONTROL_PT			(1<<6)
+-#define LCD_CONTROL_PC			(1<<5)
+-#define LCD_CONTROL_BPP			(7<<1)
+-#define LCD_CONTROL_BPP_1		(0<<1)
+-#define LCD_CONTROL_BPP_2		(1<<1)
+-#define LCD_CONTROL_BPP_4		(2<<1)
+-#define LCD_CONTROL_BPP_8		(3<<1)
+-#define LCD_CONTROL_BPP_12		(4<<1)
+-#define LCD_CONTROL_BPP_16		(5<<1)
+-#define LCD_CONTROL_GO			(1<<0)
+-
+-/* lcd_intstatus, lcd_intenable */
+-#define LCD_INT_SD				(1<<7)
+-#define LCD_INT_OF				(1<<6)
+-#define LCD_INT_UF				(1<<5)
+-#define LCD_INT_SA				(1<<3)
+-#define LCD_INT_SS				(1<<2)
+-#define LCD_INT_S1				(1<<1)
+-#define LCD_INT_S0				(1<<0)
+-
+-/* lcd_horztiming */
+-#define LCD_HORZTIMING_HN2		(255<<24)
+-#define LCD_HORZTIMING_HN2_N(N)	(((N)-1)<<24)
+-#define LCD_HORZTIMING_HN1		(255<<16)
+-#define LCD_HORZTIMING_HN1_N(N)	(((N)-1)<<16)
+-#define LCD_HORZTIMING_HPW		(63<<10)
+-#define LCD_HORZTIMING_HPW_N(N)	(((N)-1)<<10)
+-#define LCD_HORZTIMING_PPL		(1023<<0)
+-#define LCD_HORZTIMING_PPL_N(N)	(((N)-1)<<0)
+-
+-/* lcd_verttiming */
+-#define LCD_VERTTIMING_VN2		(255<<24)
+-#define LCD_VERTTIMING_VN2_N(N)	(((N)-1)<<24)
+-#define LCD_VERTTIMING_VN1		(255<<16)
+-#define LCD_VERTTIMING_VN1_N(N)	(((N)-1)<<16)
+-#define LCD_VERTTIMING_VPW		(63<<10)
+-#define LCD_VERTTIMING_VPW_N(N)	(((N)-1)<<10)
+-#define LCD_VERTTIMING_LPP		(1023<<0)
+-#define LCD_VERTTIMING_LPP_N(N)	(((N)-1)<<0)
+-
+-/* lcd_clkcontrol */
+-#define LCD_CLKCONTROL_IB		(1<<18)
+-#define LCD_CLKCONTROL_IC		(1<<17)
+-#define LCD_CLKCONTROL_IH		(1<<16)
+-#define LCD_CLKCONTROL_IV		(1<<15)
+-#define LCD_CLKCONTROL_BF		(31<<10)
+-#define LCD_CLKCONTROL_BF_N(N)	(((N)-1)<<10)
+-#define LCD_CLKCONTROL_PCD		(1023<<0)
+-#define LCD_CLKCONTROL_PCD_N(N)	((N)<<0)
+-
+-/* lcd_pwmdiv */
+-#define LCD_PWMDIV_EN			(1<<12)
+-#define LCD_PWMDIV_PWMDIV		(2047<<0)
+-#define LCD_PWMDIV_PWMDIV_N(N)	(((N)-1)<<0)
+-
+-/* lcd_pwmhi */
+-#define LCD_PWMHI_PWMHI1		(2047<<12)
+-#define LCD_PWMHI_PWMHI1_N(N)	((N)<<12)
+-#define LCD_PWMHI_PWMHI0		(2047<<0)
+-#define LCD_PWMHI_PWMHI0_N(N)	((N)<<0)
+-
+-/* lcd_pallettebase - MONOCHROME */
+-#define LCD_PALLETTE_MONO_MI		(15<<0)
+-#define LCD_PALLETTE_MONO_MI_N(N)	((N)<<0)
+-
+-/* lcd_pallettebase - COLOR */
+-#define LCD_PALLETTE_COLOR_BI		(15<<8)
+-#define LCD_PALLETTE_COLOR_BI_N(N)	((N)<<8)
+-#define LCD_PALLETTE_COLOR_GI		(15<<4)
+-#define LCD_PALLETTE_COLOR_GI_N(N)	((N)<<4)
+-#define LCD_PALLETTE_COLOR_RI		(15<<0)
+-#define LCD_PALLETTE_COLOR_RI_N(N)	((N)<<0)
+-
+-/* lcd_palletebase - COLOR TFT PALLETIZED */
+-#define LCD_PALLETTE_TFT_DC			(65535<<0)
+-#define LCD_PALLETTE_TFT_DC_N(N)	((N)<<0)
++	u32	horztiming;
++	u32	verttiming;
+ 
+-/********************************************************************/
++	u32	xres;		/* Maximum horizontal resolution */
++	u32 	yres;		/* Maximum vertical resolution */
++	u32 	bpp;		/* Maximum depth supported */
++};
+ 
+-struct known_lcd_panels
++struct au1100fb_regs
+ {
+-	uint32 xres;
+-	uint32 yres;
+-	uint32 bpp;
+-	unsigned char  panel_name[256];
+-	uint32 mode_control;
+-	uint32 mode_horztiming;
+-	uint32 mode_verttiming;
+-	uint32 mode_clkcontrol;
+-	uint32 mode_pwmdiv;
+-	uint32 mode_pwmhi;
+-	uint32 mode_toyclksrc;
+-	uint32 mode_backlight;
++	u32  lcd_control;
++	u32  lcd_intstatus;
++	u32  lcd_intenable;
++	u32  lcd_horztiming;
++	u32  lcd_verttiming;
++	u32  lcd_clkcontrol;
++	u32  lcd_dmaaddr0;
++	u32  lcd_dmaaddr1;
++	u32  lcd_words;
++	u32  lcd_pwmdiv;
++	u32  lcd_pwmhi;
++	u32  reserved[(0x0400-0x002C)/4];
++	u32  lcd_pallettebase[256];
++};
++
++struct au1100fb_device {
++
++	struct fb_info info;			/* FB driver info record */
++
++	struct au1100fb_panel 	*panel;		/* Panel connected to this device */
+ 
++	struct au1100fb_regs* 	regs;		/* Registers memory map */
++	size_t       		regs_len;
++	unsigned int 		regs_phys;
++
++	unsigned char* 		fb_mem;		/* FrameBuffer memory map */
++	size_t	      		fb_len;
++	dma_addr_t    		fb_phys;
+ };
+ 
+-#if defined(__BIG_ENDIAN)
+-#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_11
+-#else
+-#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_00
+-#endif
++/********************************************************************/
+ 
+-/*
+- * The fb driver assumes that AUX PLL is at 48MHz.  That can
+- * cover up to 800x600 resolution; if you need higher resolution,
+- * you should modify the driver as needed, not just this structure.
++#define LCD_CONTROL                (AU1100_LCD_BASE + 0x0)
++  #define LCD_CONTROL_SBB_BIT      21
++  #define LCD_CONTROL_SBB_MASK     (0x3 << LCD_CONTROL_SBB_BIT)
++    #define LCD_CONTROL_SBB_1        (0 << LCD_CONTROL_SBB_BIT)
++    #define LCD_CONTROL_SBB_2        (1 << LCD_CONTROL_SBB_BIT)
++    #define LCD_CONTROL_SBB_3        (2 << LCD_CONTROL_SBB_BIT)
++    #define LCD_CONTROL_SBB_4        (3 << LCD_CONTROL_SBB_BIT)
++  #define LCD_CONTROL_SBPPF_BIT    18
++  #define LCD_CONTROL_SBPPF_MASK   (0x7 << LCD_CONTROL_SBPPF_BIT)
++    #define LCD_CONTROL_SBPPF_655    (0 << LCD_CONTROL_SBPPF_BIT)
++    #define LCD_CONTROL_SBPPF_565    (1 << LCD_CONTROL_SBPPF_BIT)
++    #define LCD_CONTROL_SBPPF_556    (2 << LCD_CONTROL_SBPPF_BIT)
++    #define LCD_CONTROL_SBPPF_1555   (3 << LCD_CONTROL_SBPPF_BIT)
++    #define LCD_CONTROL_SBPPF_5551   (4 << LCD_CONTROL_SBPPF_BIT)
++  #define LCD_CONTROL_WP           (1<<17)
++  #define LCD_CONTROL_WD           (1<<16)
++  #define LCD_CONTROL_C            (1<<15)
++  #define LCD_CONTROL_SM_BIT       13
++  #define LCD_CONTROL_SM_MASK      (0x3 << LCD_CONTROL_SM_BIT)
++    #define LCD_CONTROL_SM_0         (0 << LCD_CONTROL_SM_BIT)
++    #define LCD_CONTROL_SM_90        (1 << LCD_CONTROL_SM_BIT)
++    #define LCD_CONTROL_SM_180       (2 << LCD_CONTROL_SM_BIT)
++    #define LCD_CONTROL_SM_270       (3 << LCD_CONTROL_SM_BIT)
++  #define LCD_CONTROL_DB           (1<<12)
++  #define LCD_CONTROL_CCO          (1<<11)
++  #define LCD_CONTROL_DP           (1<<10)
++  #define LCD_CONTROL_PO_BIT       8
++  #define LCD_CONTROL_PO_MASK      (0x3 << LCD_CONTROL_PO_BIT)
++    #define LCD_CONTROL_PO_00        (0 << LCD_CONTROL_PO_BIT)
++    #define LCD_CONTROL_PO_01        (1 << LCD_CONTROL_PO_BIT)
++    #define LCD_CONTROL_PO_10        (2 << LCD_CONTROL_PO_BIT)
++    #define LCD_CONTROL_PO_11        (3 << LCD_CONTROL_PO_BIT)
++  #define LCD_CONTROL_MPI          (1<<7)
++  #define LCD_CONTROL_PT           (1<<6)
++  #define LCD_CONTROL_PC           (1<<5)
++  #define LCD_CONTROL_BPP_BIT      1
++  #define LCD_CONTROL_BPP_MASK     (0x7 << LCD_CONTROL_BPP_BIT)
++    #define LCD_CONTROL_BPP_1        (0 << LCD_CONTROL_BPP_BIT)
++    #define LCD_CONTROL_BPP_2        (1 << LCD_CONTROL_BPP_BIT)
++    #define LCD_CONTROL_BPP_4        (2 << LCD_CONTROL_BPP_BIT)
++    #define LCD_CONTROL_BPP_8        (3 << LCD_CONTROL_BPP_BIT)
++    #define LCD_CONTROL_BPP_12       (4 << LCD_CONTROL_BPP_BIT)
++    #define LCD_CONTROL_BPP_16       (5 << LCD_CONTROL_BPP_BIT)
++  #define LCD_CONTROL_GO           (1<<0)
++
++#define LCD_INTSTATUS              (AU1100_LCD_BASE + 0x4)
++#define LCD_INTENABLE              (AU1100_LCD_BASE + 0x8)
++  #define LCD_INT_SD               (1<<7)
++  #define LCD_INT_OF               (1<<6)
++  #define LCD_INT_UF               (1<<5)
++  #define LCD_INT_SA               (1<<3)
++  #define LCD_INT_SS               (1<<2)
++  #define LCD_INT_S1               (1<<1)
++  #define LCD_INT_S0               (1<<0)
++
++#define LCD_HORZTIMING             (AU1100_LCD_BASE + 0xC)
++  #define LCD_HORZTIMING_HN2_BIT   24
++  #define LCD_HORZTIMING_HN2_MASK  (0xFF << LCD_HORZTIMING_HN2_BIT)
++  #define LCD_HORZTIMING_HN2_N(N)  ((((N)-1) << LCD_HORZTIMING_HN2_BIT) & LCD_HORZTIMING_HN2_MASK)
++  #define LCD_HORZTIMING_HN1_BIT   16
++  #define LCD_HORZTIMING_HN1_MASK  (0xFF << LCD_HORZTIMING_HN1_BIT)
++  #define LCD_HORZTIMING_HN1_N(N)  ((((N)-1) << LCD_HORZTIMING_HN1_BIT) & LCD_HORZTIMING_HN1_MASK)
++  #define LCD_HORZTIMING_HPW_BIT   10
++  #define LCD_HORZTIMING_HPW_MASK  (0x3F << LCD_HORZTIMING_HPW_BIT)
++  #define LCD_HORZTIMING_HPW_N(N)  ((((N)-1) << LCD_HORZTIMING_HPW_BIT) & LCD_HORZTIMING_HPW_MASK)
++  #define LCD_HORZTIMING_PPL_BIT   0
++  #define LCD_HORZTIMING_PPL_MASK  (0x3FF << LCD_HORZTIMING_PPL_BIT)
++  #define LCD_HORZTIMING_PPL_N(N)  ((((N)-1) << LCD_HORZTIMING_PPL_BIT) & LCD_HORZTIMING_PPL_MASK)
++
++#define LCD_VERTTIMING             (AU1100_LCD_BASE + 0x10)
++  #define LCD_VERTTIMING_VN2_BIT   24
++  #define LCD_VERTTIMING_VN2_MASK  (0xFF << LCD_VERTTIMING_VN2_BIT)
++  #define LCD_VERTTIMING_VN2_N(N)  ((((N)-1) << LCD_VERTTIMING_VN2_BIT) & LCD_VERTTIMING_VN2_MASK)
++  #define LCD_VERTTIMING_VN1_BIT   16
++  #define LCD_VERTTIMING_VN1_MASK  (0xFF << LCD_VERTTIMING_VN1_BIT)
++  #define LCD_VERTTIMING_VN1_N(N)  ((((N)-1) << LCD_VERTTIMING_VN1_BIT) & LCD_VERTTIMING_VN1_MASK)
++  #define LCD_VERTTIMING_VPW_BIT   10
++  #define LCD_VERTTIMING_VPW_MASK  (0x3F << LCD_VERTTIMING_VPW_BIT)
++  #define LCD_VERTTIMING_VPW_N(N)  ((((N)-1) << LCD_VERTTIMING_VPW_BIT) & LCD_VERTTIMING_VPW_MASK)
++  #define LCD_VERTTIMING_LPP_BIT   0
++  #define LCD_VERTTIMING_LPP_MASK  (0x3FF << LCD_VERTTIMING_LPP_BIT)
++  #define LCD_VERTTIMING_LPP_N(N)  ((((N)-1) << LCD_VERTTIMING_LPP_BIT) & LCD_VERTTIMING_LPP_MASK)
++
++#define LCD_CLKCONTROL             (AU1100_LCD_BASE + 0x14)
++  #define LCD_CLKCONTROL_IB        (1<<18)
++  #define LCD_CLKCONTROL_IC        (1<<17)
++  #define LCD_CLKCONTROL_IH        (1<<16)
++  #define LCD_CLKCONTROL_IV        (1<<15)
++  #define LCD_CLKCONTROL_BF_BIT    10
++  #define LCD_CLKCONTROL_BF_MASK   (0x1F << LCD_CLKCONTROL_BF_BIT)
++  #define LCD_CLKCONTROL_BF_N(N)   ((((N)-1) << LCD_CLKCONTROL_BF_BIT) & LCD_CLKCONTROL_BF_MASK)
++  #define LCD_CLKCONTROL_PCD_BIT   0
++  #define LCD_CLKCONTROL_PCD_MASK  (0x3FF << LCD_CLKCONTROL_PCD_BIT)
++  #define LCD_CLKCONTROL_PCD_N(N)  (((N) << LCD_CLKCONTROL_PCD_BIT) & LCD_CLKCONTROL_PCD_MASK)
++
++#define LCD_DMAADDR0               (AU1100_LCD_BASE + 0x18)
++#define LCD_DMAADDR1               (AU1100_LCD_BASE + 0x1C)
++  #define LCD_DMA_SA_BIT           5
++  #define LCD_DMA_SA_MASK          (0x7FFFFFF << LCD_DMA_SA_BIT)
++  #define LCD_DMA_SA_N(N)          ((N) & LCD_DMA_SA_MASK)
++
++#define LCD_WORDS                  (AU1100_LCD_BASE + 0x20)
++  #define LCD_WRD_WRDS_BIT         0
++  #define LCD_WRD_WRDS_MASK        (0xFFFFFFFF << LCD_WRD_WRDS_BIT)
++  #define LCD_WRD_WRDS_N(N)        ((((N)-1) << LCD_WRD_WRDS_BIT) & LCD_WRD_WRDS_MASK)
++
++#define LCD_PWMDIV                 (AU1100_LCD_BASE + 0x24)
++  #define LCD_PWMDIV_EN            (1<<12)
++  #define LCD_PWMDIV_PWMDIV_BIT    0
++  #define LCD_PWMDIV_PWMDIV_MASK   (0xFFF << LCD_PWMDIV_PWMDIV_BIT)
++  #define LCD_PWMDIV_PWMDIV_N(N)   ((((N)-1) << LCD_PWMDIV_PWMDIV_BIT) & LCD_PWMDIV_PWMDIV_MASK)
++
++#define LCD_PWMHI                  (AU1100_LCD_BASE + 0x28)
++  #define LCD_PWMHI_PWMHI1_BIT     12
++  #define LCD_PWMHI_PWMHI1_MASK    (0xFFF << LCD_PWMHI_PWMHI1_BIT)
++  #define LCD_PWMHI_PWMHI1_N(N)    (((N) << LCD_PWMHI_PWMHI1_BIT) & LCD_PWMHI_PWMHI1_MASK)
++  #define LCD_PWMHI_PWMHI0_BIT     0
++  #define LCD_PWMHI_PWMHI0_MASK    (0xFFF << LCD_PWMHI_PWMHI0_BIT)
++  #define LCD_PWMHI_PWMHI0_N(N)    (((N) << LCD_PWMHI_PWMHI0_BIT) & LCD_PWMHI_PWMHI0_MASK)
++
++#define LCD_PALLETTEBASE                (AU1100_LCD_BASE + 0x400)
++  #define LCD_PALLETTE_MONO_MI_BIT      0
++  #define LCD_PALLETTE_MONO_MI_MASK     (0xF << LCD_PALLETTE_MONO_MI_BIT)
++  #define LCD_PALLETTE_MONO_MI_N(N)     (((N)<< LCD_PALLETTE_MONO_MI_BIT) & LCD_PALLETTE_MONO_MI_MASK)
++
++  #define LCD_PALLETTE_COLOR_RI_BIT     8
++  #define LCD_PALLETTE_COLOR_RI_MASK    (0xF << LCD_PALLETTE_COLOR_RI_BIT)
++  #define LCD_PALLETTE_COLOR_RI_N(N)    (((N)<< LCD_PALLETTE_COLOR_RI_BIT) & LCD_PALLETTE_COLOR_RI_MASK)
++  #define LCD_PALLETTE_COLOR_GI_BIT     4
++  #define LCD_PALLETTE_COLOR_GI_MASK    (0xF << LCD_PALLETTE_COLOR_GI_BIT)
++  #define LCD_PALLETTE_COLOR_GI_N(N)    (((N)<< LCD_PALLETTE_COLOR_GI_BIT) & LCD_PALLETTE_COLOR_GI_MASK)
++  #define LCD_PALLETTE_COLOR_BI_BIT     0
++  #define LCD_PALLETTE_COLOR_BI_MASK    (0xF << LCD_PALLETTE_COLOR_BI_BIT)
++  #define LCD_PALLETTE_COLOR_BI_N(N)    (((N)<< LCD_PALLETTE_COLOR_BI_BIT) & LCD_PALLETTE_COLOR_BI_MASK)
++
++  #define LCD_PALLETTE_TFT_DC_BIT       0
++  #define LCD_PALLETTE_TFT_DC_MASK      (0xFFFF << LCD_PALLETTE_TFT_DC_BIT)
++  #define LCD_PALLETTE_TFT_DC_N(N)      (((N)<< LCD_PALLETTE_TFT_DC_BIT) & LCD_PALLETTE_TFT_DC_MASK)
++
++/********************************************************************/
++
++/* List of panels known to work with the AU1100 LCD controller.
++ * To add a new panel, enter the same specifications as the
++ * Generic_TFT one, and MAKE SURE that it doesn't conflicts
++ * with the controller restrictions. Restrictions are:
++ *
++ * STN color panels: max_bpp <= 12
++ * STN mono panels: max_bpp <= 4
++ * TFT panels: max_bpp <= 16
++ * max_xres <= 800
++ * max_yres <= 600
+  */
+-struct known_lcd_panels panels[] =
++static struct au1100fb_panel known_lcd_panels[] =
+ {
+-	{ /* 0: Pb1100 LCDA: Sharp 320x240 TFT panel */
+-		320, /* xres */
+-		240, /* yres */
+-		16,  /* bpp  */
+-
+-		"Sharp_320x240_16",
+-		/* mode_control */
++	/* 800x600x16bpp CRT */
++	[0] = {
++		.name = "CRT_800x600_16",
++		.xres = 800,
++		.yres = 600,
++		.bpp = 16,
++		.control_base =	0x0004886A |
++			LCD_CONTROL_DEFAULT_PO | LCD_CONTROL_DEFAULT_SBPPF |
++			LCD_CONTROL_BPP_16,
++		.clkcontrol_base = 0x00020000,
++		.horztiming = 0x005aff1f,
++		.verttiming = 0x16000e57,
++	},
++	/* just the standard LCD */
++	[1] = {
++		.name = "WWPC LCD",
++		.xres = 240,
++		.yres = 320,
++		.bpp = 16,
++		.control_base = 0x0006806A,
++		.horztiming = 0x0A1010EF,
++		.verttiming = 0x0301013F,
++		.clkcontrol_base = 0x00018001,
++	},
++	/* Sharp 320x240 TFT panel */
++	[2] = {
++		.name = "Sharp_LQ038Q5DR01",
++		.xres = 320,
++		.yres = 240,
++		.bpp = 16,
++		.control_base =
+ 		( LCD_CONTROL_SBPPF_565
+-		/*LCD_CONTROL_WP*/
+-		/*LCD_CONTROL_WD*/
+ 		| LCD_CONTROL_C
+ 		| LCD_CONTROL_SM_0
+-		/*LCD_CONTROL_DB*/
+-		/*LCD_CONTROL_CCO*/
+-		/*LCD_CONTROL_DP*/
+-		| LCD_DEFAULT_PIX_FORMAT
+-		/*LCD_CONTROL_MPI*/
++			| LCD_CONTROL_DEFAULT_PO
+ 		| LCD_CONTROL_PT
+ 		| LCD_CONTROL_PC
+ 		| LCD_CONTROL_BPP_16 ),
+-
+-		/* mode_horztiming */
++		.horztiming =
+ 		( LCD_HORZTIMING_HN2_N(8)
+ 		| LCD_HORZTIMING_HN1_N(60)
+ 		| LCD_HORZTIMING_HPW_N(12)
+ 		| LCD_HORZTIMING_PPL_N(320) ),
+-
+-		/* mode_verttiming */
++		.verttiming =
+ 		( LCD_VERTTIMING_VN2_N(5)
+ 		| LCD_VERTTIMING_VN1_N(17)
+ 		| LCD_VERTTIMING_VPW_N(1)
+ 		| LCD_VERTTIMING_LPP_N(240) ),
+-
+-		/* mode_clkcontrol */
+-		( 0
+-		/*LCD_CLKCONTROL_IB*/
+-		/*LCD_CLKCONTROL_IC*/
+-		/*LCD_CLKCONTROL_IH*/
+-		/*LCD_CLKCONTROL_IV*/
+-		| LCD_CLKCONTROL_PCD_N(1) ),
+-
+-		/* mode_pwmdiv */
+-		0,
+-
+-		/* mode_pwmhi */
+-		0,
+-
+-		/* mode_toyclksrc */
+-		((1<<7) | (1<<6) | (1<<5)),
+-
+-		/* mode_backlight */
+-		6
++		.clkcontrol_base = LCD_CLKCONTROL_PCD_N(1),
+ 	},
+ 
+-	{ /* 1: Pb1100 LCDC 640x480 TFT panel */
+-		640, /* xres */
+-		480, /* yres */
+-		16,  /* bpp  */
+-
+-		"Generic_640x480_16",
+-
+-		/* mode_control */
+-		0x004806a | LCD_DEFAULT_PIX_FORMAT,
+-
+-		/* mode_horztiming */
+-		0x3434d67f,
+-
+-		/* mode_verttiming */
+-		0x0e0e39df,
+-
+-		/* mode_clkcontrol */
+-		( 0
+-		/*LCD_CLKCONTROL_IB*/
+-		/*LCD_CLKCONTROL_IC*/
+-		/*LCD_CLKCONTROL_IH*/
+-		/*LCD_CLKCONTROL_IV*/
+-		| LCD_CLKCONTROL_PCD_N(1) ),
+-
+-		/* mode_pwmdiv */
+-		0,
+-
+-		/* mode_pwmhi */
+-		0,
+-
+-		/* mode_toyclksrc */
+-		((1<<7) | (1<<6) | (0<<5)),
+-
+-		/* mode_backlight */
+-		7
++	/* Hitachi SP14Q005 and possibly others */
++	[3] = {
++		.name = "Hitachi_SP14Qxxx",
++		.xres = 320,
++		.yres = 240,
++		.bpp = 4,
++		.control_base =
++			( LCD_CONTROL_C
++			| LCD_CONTROL_BPP_4 ),
++		.horztiming =
++			( LCD_HORZTIMING_HN2_N(1)
++			| LCD_HORZTIMING_HN1_N(1)
++			| LCD_HORZTIMING_HPW_N(1)
++			| LCD_HORZTIMING_PPL_N(320) ),
++		.verttiming =
++			( LCD_VERTTIMING_VN2_N(1)
++			| LCD_VERTTIMING_VN1_N(1)
++			| LCD_VERTTIMING_VPW_N(1)
++			| LCD_VERTTIMING_LPP_N(240) ),
++		.clkcontrol_base = LCD_CLKCONTROL_PCD_N(4),
+ 	},
+ 
+-	{ /* 2: Pb1100 LCDB 640x480 PrimeView TFT panel */
+-		640, /* xres */
+-		480, /* yres */
+-		16,  /* bpp  */
+-
+-		"PrimeView_640x480_16",
+-
+-		/* mode_control */
+-		0x0004886a | LCD_DEFAULT_PIX_FORMAT,
+-
+-		/* mode_horztiming */
+-		0x0e4bfe7f,
+-
+-		/* mode_verttiming */
+-		0x210805df,
+-
+-		/* mode_clkcontrol */
+-		0x00038001,
+-
+-		/* mode_pwmdiv */
+-		0,
+-
+-		/* mode_pwmhi */
+-		0,
+-
+-		/* mode_toyclksrc */
+-		((1<<7) | (1<<6) | (0<<5)),
+-
+-		/* mode_backlight */
+-		7
++	/* Generic 640x480 TFT panel */
++	[4] = {
++		.name = "TFT_640x480_16",
++		.xres = 640,
++		.yres = 480,
++		.bpp = 16,
++		.control_base = 0x004806a | LCD_CONTROL_DEFAULT_PO,
++		.horztiming = 0x3434d67f,
++		.verttiming = 0x0e0e39df,
++		.clkcontrol_base = LCD_CLKCONTROL_PCD_N(1),
+ 	},
+ 
+-	{ /* 3: Pb1100 800x600x16bpp NEON CRT */
+-		800, /* xres */
+-		600, /* yres */
+-		16,  /* bpp */
+-
+-		"NEON_800x600_16",
+-
+-		/* mode_control */
+-		0x0004886A | LCD_DEFAULT_PIX_FORMAT,
+-
+-		/* mode_horztiming */
+-		0x005AFF1F,
+-
+-		/* mode_verttiming */
+-		0x16000E57,
+-
+-		/* mode_clkcontrol */
+-		0x00020000,
+-
+-		/* mode_pwmdiv */
+-		0,
+-
+-		/* mode_pwmhi */
+-		0,
+-
+-		/* mode_toyclksrc */
+-		((1<<7) | (1<<6) | (0<<5)),
+-
+-		/* mode_backlight */
+-		7
++	 /* Pb1100 LCDB 640x480 PrimeView TFT panel */
++	[5] = {
++		.name = "PrimeView_640x480_16",
++		.xres = 640,
++		.yres = 480,
++		.bpp = 16,
++		.control_base = 0x0004886a | LCD_CONTROL_DEFAULT_PO,
++		.horztiming = 0x0e4bfe7f,
++		.verttiming = 0x210805df,
++		.clkcontrol_base = 0x00038001,
+ 	},
++};
+ 
+-	{ /* 4: Pb1100 640x480x16bpp NEON CRT */
+-		640, /* xres */
+-		480, /* yres */
+-		16,  /* bpp */
+-
+-		"NEON_640x480_16",
+-
+-		/* mode_control */
+-		0x0004886A | LCD_DEFAULT_PIX_FORMAT,
+-
+-		/* mode_horztiming */
+-		0x0052E27F,
+-
+-		/* mode_verttiming */
+-		0x18000DDF,
+-
+-		/* mode_clkcontrol */
+-		0x00020000,
++struct au1100fb_drv_info {
++	int	panel_idx;
++	char 	*opt_mode;
++};
+ 
+-		/* mode_pwmdiv */
+-		0,
++/********************************************************************/
+ 
+-		/* mode_pwmhi */
+-		0,
++/* Inline helpers */
+ 
+-		/* mode_toyclksrc */
+-		((1<<7) | (1<<6) | (0<<5)),
++#define panel_is_dual(panel)  (panel->control_base & LCD_CONTROL_DP)
++#define panel_is_active(panel)(panel->control_base & LCD_CONTROL_PT)
++#define panel_is_color(panel) (panel->control_base & LCD_CONTROL_PC)
++#define panel_swap_rgb(panel) (panel->control_base & LCD_CONTROL_CCO)
+ 
+-		/* mode_backlight */
+-		7
+-	},
+-};
+ #endif /* _AU1100LCD_H */
+diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
+--- a/drivers/video/backlight/corgi_bl.c
++++ b/drivers/video/backlight/corgi_bl.c
+@@ -14,7 +14,7 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/spinlock.h>
+ #include <linux/fb.h>
+ #include <linux/backlight.h>
+@@ -73,17 +73,15 @@ static void corgibl_blank(int blank)
+ }
+ 
+ #ifdef CONFIG_PM
+-static int corgibl_suspend(struct device *dev, pm_message_t state, u32 level)
++static int corgibl_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_POWER_DOWN)
+-		corgibl_blank(FB_BLANK_POWERDOWN);
++	corgibl_blank(FB_BLANK_POWERDOWN);
+ 	return 0;
+ }
+ 
+-static int corgibl_resume(struct device *dev, u32 level)
++static int corgibl_resume(struct device *dev)
+ {
+-	if (level == RESUME_POWER_ON)
+-		corgibl_blank(FB_BLANK_UNBLANK);
++	corgibl_blank(FB_BLANK_UNBLANK);
+ 	return 0;
+ }
+ #else
+diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
+--- a/drivers/video/cirrusfb.c
++++ b/drivers/video/cirrusfb.c
+@@ -275,20 +275,20 @@ static const struct cirrusfb_board_info_
+ 
+ #ifdef CONFIG_PCI
+ #define CHIP(id, btype) \
+-	{ PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_##id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
++	{ PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
+ 
+ static struct pci_device_id cirrusfb_pci_table[] = {
+-	CHIP( CIRRUS_5436,	BT_ALPINE ),
+-	CHIP( CIRRUS_5434_8,	BT_ALPINE ),
+-	CHIP( CIRRUS_5434_4,	BT_ALPINE ),
+-	CHIP( CIRRUS_5430,	BT_ALPINE ), /* GD-5440 has identical id */
+-	CHIP( CIRRUS_7543,	BT_ALPINE ),
+-	CHIP( CIRRUS_7548,	BT_ALPINE ),
+-	CHIP( CIRRUS_5480,	BT_GD5480 ), /* MacPicasso probably */
+-	CHIP( CIRRUS_5446,	BT_PICASSO4 ), /* Picasso 4 is a GD5446 */
+-	CHIP( CIRRUS_5462,	BT_LAGUNA ), /* CL Laguna */
+-	CHIP( CIRRUS_5464,	BT_LAGUNA ), /* CL Laguna 3D */
+-	CHIP( CIRRUS_5465,	BT_LAGUNA ), /* CL Laguna 3DA*/
++	CHIP( PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE ),
++	CHIP( PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE ),
++	CHIP( PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE ),
++	CHIP( PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE ), /* GD-5440 is same id */
++	CHIP( PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE ),
++	CHIP( PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE ),
++	CHIP( PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480 ), /* MacPicasso likely */
++	CHIP( PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is 5446 */
++	CHIP( PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */
++	CHIP( PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */
++	CHIP( PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/
+ 	{ 0, }
+ };
+ MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
+diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
+--- a/drivers/video/console/Kconfig
++++ b/drivers/video/console/Kconfig
+@@ -28,7 +28,7 @@ config VGA_CONSOLE
+ 
+ config VIDEO_SELECT
+ 	bool "Video mode selection support"
+-	depends on  (X86 || X86_64) && VGA_CONSOLE
++	depends on  X86 && VGA_CONSOLE
+ 	---help---
+ 	  This enables support for text mode selection on kernel startup. If
+ 	  you want to take advantage of some high-resolution text mode your
+@@ -110,7 +110,7 @@ config STI_CONSOLE
+ 
+ config FONTS
+ 	bool "Select compiled-in fonts"
+-	depends on FRAMEBUFFER_CONSOLE
++	depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
+ 	help
+ 	  Say Y here if you would like to use fonts other than the default
+ 	  your frame buffer console usually use.
+@@ -123,7 +123,7 @@ config FONTS
+ 
+ config FONT_8x8
+ 	bool "VGA 8x8 font" if FONTS
+-	depends on FRAMEBUFFER_CONSOLE
++	depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
+ 	default y if !SPARC32 && !SPARC64 && !FONTS
+ 	help
+ 	  This is the "high resolution" font for the VGA frame buffer (the one
+@@ -137,7 +137,7 @@ config FONT_8x8
+ 
+ config FONT_8x16
+ 	bool "VGA 8x16 font" if FONTS
+-	depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || USB_SISUSBVGA_CON
++	depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || STI_CONSOLE || USB_SISUSBVGA_CON 
+ 	default y if !SPARC32 && !SPARC64 && !FONTS
+ 	help
+ 	  This is the "high resolution" font for the VGA frame buffer (the one
+@@ -147,7 +147,7 @@ config FONT_8x16
+ 
+ config FONT_6x11
+ 	bool "Mac console 6x11 font (not supported by all drivers)" if FONTS
+-	depends on FRAMEBUFFER_CONSOLE
++	depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
+ 	default y if !SPARC32 && !SPARC64 && !FONTS && MAC
+ 	help
+ 	  Small console font with Macintosh-style high-half glyphs.  Some Mac
+diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
+--- a/drivers/video/console/newport_con.c
++++ b/drivers/video/console/newport_con.c
+@@ -32,7 +32,6 @@
+ #include <linux/font.h>
+ 
+ 
+-extern struct font_desc font_vga_8x16;
+ extern unsigned long sgi_gfxaddr;
+ 
+ #define FONT_DATA ((unsigned char *)font_vga_8x16.data)
+diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
+--- a/drivers/video/console/sticore.c
++++ b/drivers/video/console/sticore.c
+@@ -511,12 +511,12 @@ sti_select_fbfont( struct sti_cooked_rom
+ 	struct sti_cooked_font *cooked_font;
+ 	
+ 	if (!fbfont_name || !strlen(fbfont_name))
+-	    return NULL;
++		return NULL;
+ 	fbfont = find_font(fbfont_name);
+ 	if (!fbfont)
+-	    fbfont = get_default_font(1024,768);
++		fbfont = get_default_font(1024,768);
+ 	if (!fbfont)
+-	    return NULL;
++		return NULL;
+ 
+ 	DPRINTK((KERN_DEBUG "selected %dx%d fb-font %s\n",
+ 			fbfont->width, fbfont->height, fbfont->name));
+@@ -527,7 +527,7 @@ sti_select_fbfont( struct sti_cooked_rom
+ 
+ 	nf = kmalloc(size, GFP_KERNEL);
+ 	if (!nf)
+-	    return NULL;
++		return NULL;
+ 	memset(nf, 0, size);
+ 
+ 	nf->first_char = 0;
+@@ -546,8 +546,8 @@ sti_select_fbfont( struct sti_cooked_rom
+ 
+ 	cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL);
+ 	if (!cooked_font) {
+-	    kfree(nf);
+-	    return NULL;
++		kfree(nf);
++		return NULL;
+ 	}
+ 	
+ 	cooked_font->raw = nf;
+@@ -595,7 +595,7 @@ sti_select_font(struct sti_cooked_rom *r
+ static void __init 
+ sti_dump_rom(struct sti_rom *rom)
+ {
+-        printk(KERN_INFO "    id %04x-%04x, conforms to spec rev. %d.%02x\n",
++	printk(KERN_INFO "    id %04x-%04x, conforms to spec rev. %d.%02x\n",
+ 		rom->graphics_id[0], 
+ 		rom->graphics_id[1],
+ 		rom->revno[0] >> 4, 
+@@ -651,15 +651,16 @@ sti_search_font(struct sti_cooked_rom *r
+ 	struct sti_cooked_font *font;
+ 	int i = 0;
+ 	
+-	for(font = rom->font_start; font; font = font->next_font, i++) {
+-	    if((font->raw->width == width) && (font->raw->height == height))
++	for (font = rom->font_start; font; font = font->next_font, i++) {
++		if ((font->raw->width == width) &&
++		    (font->raw->height == height))
+ 			return i;
+ 	}
+ 	return 0;
+ }
+ 
+-#define BMODE_RELOCATE(offset)        offset = (offset) / 4;
+-#define BMODE_LAST_ADDR_OFFS          0x50
++#define BMODE_RELOCATE(offset)		offset = (offset) / 4;
++#define BMODE_LAST_ADDR_OFFS		0x50
+ 
+ static void * __init
+ sti_bmode_font_raw(struct sti_cooked_font *f)
+@@ -700,35 +701,35 @@ sti_get_bmode_rom (unsigned long address
+ {
+ 	struct sti_rom *raw;
+ 	u32 size;
+-        struct sti_rom_font *raw_font, *font_start;
+-    
++	struct sti_rom_font *raw_font, *font_start;
++
+ 	sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size);
+-    
+-        size = (size+3) / 4;
++
++	size = (size+3) / 4;
+ 	raw = kmalloc(size, GFP_KERNEL);
+ 	if (raw) {
+-	    sti_bmode_rom_copy(address, size, raw);
+-	    memmove (&raw->res004, &raw->type[0], 0x3c);
+-    	    raw->type[3] = raw->res004;
+-
+-	    BMODE_RELOCATE (raw->region_list);
+-	    BMODE_RELOCATE (raw->font_start);
+-
+-	    BMODE_RELOCATE (raw->init_graph);
+-	    BMODE_RELOCATE (raw->state_mgmt);
+-	    BMODE_RELOCATE (raw->font_unpmv);
+-	    BMODE_RELOCATE (raw->block_move);
+-	    BMODE_RELOCATE (raw->inq_conf);
++		sti_bmode_rom_copy(address, size, raw);
++		memmove (&raw->res004, &raw->type[0], 0x3c);
++		raw->type[3] = raw->res004;
++
++		BMODE_RELOCATE (raw->region_list);
++		BMODE_RELOCATE (raw->font_start);
++
++		BMODE_RELOCATE (raw->init_graph);
++		BMODE_RELOCATE (raw->state_mgmt);
++		BMODE_RELOCATE (raw->font_unpmv);
++		BMODE_RELOCATE (raw->block_move);
++		BMODE_RELOCATE (raw->inq_conf);
+ 
+-	    raw_font = ((void *)raw) + raw->font_start;
+-	    font_start = raw_font;
++		raw_font = ((void *)raw) + raw->font_start;
++		font_start = raw_font;
+ 		
+-	    while (raw_font->next_font) {
+-		    BMODE_RELOCATE (raw_font->next_font);
+-		    raw_font = ((void *)font_start) + raw_font->next_font;
+-	    }
++		while (raw_font->next_font) {
++			BMODE_RELOCATE (raw_font->next_font);
++			raw_font = ((void *)font_start) + raw_font->next_font;
++		}
+ 	}
+-        return raw;
++	return raw;
+ }
+ 
+ struct sti_rom * __init
+@@ -736,15 +737,15 @@ sti_get_wmode_rom (unsigned long address
+ {
+ 	struct sti_rom *raw;
+ 	unsigned long size;
+-    
++
+ 	/* read the ROM size directly from the struct in ROM */ 
+ 	size = gsc_readl(address + offsetof(struct sti_rom,last_addr));
+ 
+ 	raw = kmalloc(size, GFP_KERNEL);
+-	if(raw)
+-	        sti_rom_copy(address, size, raw);
++	if (raw)
++		sti_rom_copy(address, size, raw);
+ 
+-        return raw;
++	return raw;
+ }
+ 
+ int __init
+@@ -757,14 +758,14 @@ sti_read_rom(int wordmode, struct sti_st
+ 	if (!cooked)
+ 		goto out_err;
+ 
+-        if (wordmode)
+-                raw = sti_get_wmode_rom (address);
+-        else
+-	        raw = sti_get_bmode_rom (address);
+-
+-        if (!raw)
+-	        goto out_err;
+-    
++	if (wordmode)
++		raw = sti_get_wmode_rom (address);
++	else
++		raw = sti_get_bmode_rom (address);
++
++	if (!raw)
++		goto out_err;
++
+ 	if (!sti_cook_fonts(cooked, raw)) {
+ 		printk(KERN_ERR "No font found for STI at %08lx\n", address);
+ 		goto out_err;
+@@ -787,7 +788,7 @@ sti_read_rom(int wordmode, struct sti_st
+ 	sti->font_width = sti->font->raw->width;
+ 	sti->font_height = sti->font->raw->height;
+ 	if (!wordmode)
+-	        sti->font->raw = sti_bmode_font_raw(sti->font);
++		sti->font->raw = sti_bmode_font_raw(sti->font);
+ 
+ 	sti->sti_mem_request = raw->sti_mem_req;
+ 	sti->graphics_id[0] = raw->graphics_id[0];
+@@ -811,16 +812,16 @@ sti_try_rom_generic(unsigned long addres
+ 	u32 sig;
+ 
+ 	if (num_sti_roms >= MAX_STI_ROMS) {
+-	    printk(KERN_WARNING "maximum number of STI ROMS reached !\n");
+-	    return NULL;
++		printk(KERN_WARNING "maximum number of STI ROMS reached !\n");
++		return NULL;
+ 	}
+ 	
+ 	sti = kmalloc(sizeof(*sti), GFP_KERNEL);
+ 	if (!sti) {
+-	    printk(KERN_ERR "Not enough memory !\n");
+-	    return NULL;
++		printk(KERN_ERR "Not enough memory !\n");
++		return NULL;
+ 	}
+-		    
++
+ 	memset(sti, 0, sizeof(*sti));
+ 	spin_lock_init(&sti->lock);
+ 
+@@ -932,28 +933,21 @@ static void __init sticore_check_for_def
+  */
+ static int __init sticore_pa_init(struct parisc_device *dev)
+ {
+-	unsigned long rom = 0;
+ 	char pa_path[21];
+ 	struct sti_struct *sti = NULL;
+-	
+-	if(dev->num_addrs) {
+-		rom = dev->addr[0];
+-	}
+-	if (!rom) {
+-		rom = dev->hpa;
+-		DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
+-		sti = sti_try_rom_generic(rom, dev->hpa, NULL);
+-		rom = PAGE0->proc_sti;
+-	}
+-	if (!sti) {
+-		DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
+-		sti = sti_try_rom_generic(rom, dev->hpa, NULL);
+-	}
++	int hpa = dev->hpa.start;
++
++	if (dev->num_addrs && dev->addr[0])
++		sti = sti_try_rom_generic(dev->addr[0], hpa, NULL);
++	if (!sti)
++		sti = sti_try_rom_generic(hpa, hpa, NULL);
++	if (!sti)
++		sti = sti_try_rom_generic(PAGE0->proc_sti, hpa, NULL);
+ 	if (!sti)
+ 		return 1;
+-	
++
+ 	print_pa_hwpath(dev, pa_path);
+-	sticore_check_for_default_sti (sti, pa_path);
++	sticore_check_for_default_sti(sti, pa_path);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -579,6 +579,7 @@ static void vga_set_palette(struct vc_da
+ {
+ 	int i, j;
+ 
++	vga_w(state.vgabase, VGA_PEL_MSK, 0xff);
+ 	for (i = j = 0; i < 16; i++) {
+ 		vga_w(state.vgabase, VGA_PEL_IW, table[i]);
+ 		vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
+@@ -721,6 +722,7 @@ static void vga_pal_blank(struct vgastat
+ {
+ 	int i;
+ 
++	vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
+ 	for (i = 0; i < 16; i++) {
+ 		vga_w(state->vgabase, VGA_PEL_IW, i);
+ 		vga_w(state->vgabase, VGA_PEL_D, 0);
+diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
+--- a/drivers/video/dnfb.c
++++ b/drivers/video/dnfb.c
+@@ -6,6 +6,8 @@
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/platform_device.h>
++
+ #include <asm/setup.h>
+ #include <asm/system.h>
+ #include <asm/irq.h>
+diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
+--- a/drivers/video/epson1355fb.c
++++ b/drivers/video/epson1355fb.c
+@@ -54,6 +54,8 @@
+ #include <linux/fb.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
++#include <linux/platform_device.h>
++
+ #include <asm/types.h>
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
+--- a/drivers/video/fbmem.c
++++ b/drivers/video/fbmem.c
+@@ -918,7 +918,7 @@ fb_mmap(struct file *file, struct vm_are
+ 	}
+ #endif
+ #elif defined(__powerpc__)
+-	vma->vm_page_prot = phys_mem_access_prot(file, off,
++	vma->vm_page_prot = phys_mem_access_prot(file, off >> PAGE_SHIFT,
+ 						 vma->vm_end - vma->vm_start,
+ 						 vma->vm_page_prot);
+ #elif defined(__alpha__)
+@@ -1031,7 +1031,7 @@ register_framebuffer(struct fb_info *fb_
+ 			break;
+ 	fb_info->node = i;
+ 
+-	fb_info->class_device = class_device_create(fb_class, MKDEV(FB_MAJOR, i),
++	fb_info->class_device = class_device_create(fb_class, NULL, MKDEV(FB_MAJOR, i),
+ 				    fb_info->device, "fb%d", i);
+ 	if (IS_ERR(fb_info->class_device)) {
+ 		/* Not fatal */
+diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
+--- a/drivers/video/gbefb.c
++++ b/drivers/video/gbefb.c
+@@ -11,7 +11,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/delay.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/errno.h>
+ #include <linux/fb.h>
+@@ -1126,7 +1126,7 @@ static int __init gbefb_probe(struct dev
+ 	gbefb_setup(options);
+ #endif
+ 
+-	if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
++	if (!request_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
+ 		printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
+ 		ret = -EBUSY;
+ 		goto out_release_framebuffer;
+@@ -1152,12 +1152,24 @@ static int __init gbefb_probe(struct dev
+ 	if (gbe_mem_phys) {
+ 		/* memory was allocated at boot time */
+ 		gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
++		if (!gbe_mem) {
++			printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
++			ret = -ENOMEM;
++			goto out_tiles_free;
++		}
++
+ 		gbe_dma_addr = 0;
+ 	} else {
+ 		/* try to allocate memory with the classical allocator
+ 		 * this has high chance to fail on low memory machines */
+ 		gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
+ 					     GFP_KERNEL);
++		if (!gbe_mem) {
++			printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
++			ret = -ENOMEM;
++			goto out_tiles_free;
++		}
++
+ 		gbe_mem_phys = (unsigned long) gbe_dma_addr;
+ 	}
+ 
+@@ -1165,12 +1177,6 @@ static int __init gbefb_probe(struct dev
+ 	mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
+ #endif
+ 
+-	if (!gbe_mem) {
+-		printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
+-		ret = -ENXIO;
+-		goto out_tiles_free;
+-	}
+-
+ 	/* map framebuffer memory into tiles table */
+ 	for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
+ 		gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
+diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
+--- a/drivers/video/imxfb.c
++++ b/drivers/video/imxfb.c
+@@ -31,7 +31,7 @@
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+ #include <linux/cpufreq.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ 
+ #include <asm/hardware.h>
+@@ -424,23 +424,21 @@ static void imxfb_setup_gpio(struct imxf
+  * Power management hooks.  Note that we won't be called from IRQ context,
+  * unlike the blank functions above, so we may sleep.
+  */
+-static int imxfb_suspend(struct device *dev, pm_message_t state, u32 level)
++static int imxfb_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct imxfb_info *fbi = dev_get_drvdata(dev);
+ 	pr_debug("%s\n",__FUNCTION__);
+ 
+-	if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
+-		imxfb_disable_controller(fbi);
++	imxfb_disable_controller(fbi);
+ 	return 0;
+ }
+ 
+-static int imxfb_resume(struct device *dev, u32 level)
++static int imxfb_resume(struct device *dev)
+ {
+ 	struct imxfb_info *fbi = dev_get_drvdata(dev);
+ 	pr_debug("%s\n",__FUNCTION__);
+ 
+-	if (level == RESUME_ENABLE)
+-		imxfb_enable_controller(fbi);
++	imxfb_enable_controller(fbi);
+ 	return 0;
+ }
+ #else
+diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
+--- a/drivers/video/pxafb.c
++++ b/drivers/video/pxafb.c
+@@ -36,7 +36,7 @@
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+ #include <linux/cpufreq.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ 
+ #include <asm/hardware.h>
+@@ -981,21 +981,19 @@ pxafb_freq_policy(struct notifier_block 
+  * Power management hooks.  Note that we won't be called from IRQ context,
+  * unlike the blank functions above, so we may sleep.
+  */
+-static int pxafb_suspend(struct device *dev, pm_message_t state, u32 level)
++static int pxafb_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct pxafb_info *fbi = dev_get_drvdata(dev);
+ 
+-	if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
+-		set_ctrlr_state(fbi, C_DISABLE_PM);
++	set_ctrlr_state(fbi, C_DISABLE_PM);
+ 	return 0;
+ }
+ 
+-static int pxafb_resume(struct device *dev, u32 level)
++static int pxafb_resume(struct device *dev)
+ {
+ 	struct pxafb_info *fbi = dev_get_drvdata(dev);
+ 
+-	if (level == RESUME_ENABLE)
+-		set_ctrlr_state(fbi, C_ENABLE_PM);
++	set_ctrlr_state(fbi, C_ENABLE_PM);
+ 	return 0;
+ }
+ #else
+diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
+--- a/drivers/video/q40fb.c
++++ b/drivers/video/q40fb.c
+@@ -18,6 +18,7 @@
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/setup.h>
+diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
+--- a/drivers/video/s1d13xxxfb.c
++++ b/drivers/video/s1d13xxxfb.c
+@@ -30,7 +30,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/delay.h>
+ 
+ #include <linux/types.h>
+@@ -655,7 +655,7 @@ bail:
+ }
+ 
+ #ifdef CONFIG_PM
+-static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state, u32 level)
++static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct fb_info *info = dev_get_drvdata(dev);
+ 	struct s1d13xxxfb_par *s1dfb = info->par;
+@@ -702,15 +702,12 @@ static int s1d13xxxfb_suspend(struct dev
+ 		return 0;
+ }
+ 
+-static int s1d13xxxfb_resume(struct device *dev, u32 level)
++static int s1d13xxxfb_resume(struct device *dev)
+ {
+ 	struct fb_info *info = dev_get_drvdata(dev);
+ 	struct s1d13xxxfb_par *s1dfb = info->par;
+ 	struct s1d13xxxfb_pdata *pdata = NULL;
+ 
+-	if (level != RESUME_ENABLE)
+-		return 0;
+-
+ 	/* awaken the chip */
+ 	s1d13xxxfb_writereg(s1dfb, S1DREG_PS_CNF, 0x10);
+ 
+diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
+--- a/drivers/video/s3c2410fb.c
++++ b/drivers/video/s3c2410fb.c
+@@ -86,6 +86,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/workqueue.h>
+ #include <linux/wait.h>
++#include <linux/platform_device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+@@ -847,37 +848,32 @@ static int s3c2410fb_remove(struct devic
+ 
+ /* suspend and resume support for the lcd controller */
+ 
+-static int s3c2410fb_suspend(struct device *dev, pm_message_t state, u32 level)
++static int s3c2410fb_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct fb_info	   *fbinfo = dev_get_drvdata(dev);
+ 	struct s3c2410fb_info *info = fbinfo->par;
+ 
+-	if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) {
+-		s3c2410fb_stop_lcd();
++	s3c2410fb_stop_lcd();
+ 
+-		/* sleep before disabling the clock, we need to ensure
+-		 * the LCD DMA engine is not going to get back on the bus
+-		 * before the clock goes off again (bjd) */
++	/* sleep before disabling the clock, we need to ensure
++	 * the LCD DMA engine is not going to get back on the bus
++	 * before the clock goes off again (bjd) */
+ 
+-		msleep(1);
+-		clk_disable(info->clk);
+-	}
++	msleep(1);
++	clk_disable(info->clk);
+ 
+ 	return 0;
+ }
+ 
+-static int s3c2410fb_resume(struct device *dev, u32 level)
++static int s3c2410fb_resume(struct device *dev)
+ {
+ 	struct fb_info	   *fbinfo = dev_get_drvdata(dev);
+ 	struct s3c2410fb_info *info = fbinfo->par;
+ 
+-	if (level == RESUME_ENABLE) {
+-		clk_enable(info->clk);
+-		msleep(1);
+-
+-		s3c2410fb_init_registers(info);
++	clk_enable(info->clk);
++	msleep(1);
+ 
+-	}
++	s3c2410fb_init_registers(info);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
+--- a/drivers/video/sa1100fb.c
++++ b/drivers/video/sa1100fb.c
+@@ -173,7 +173,7 @@
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+ #include <linux/cpufreq.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ 
+ #include <asm/hardware.h>
+@@ -1309,21 +1309,19 @@ sa1100fb_freq_policy(struct notifier_blo
+  * Power management hooks.  Note that we won't be called from IRQ context,
+  * unlike the blank functions above, so we may sleep.
+  */
+-static int sa1100fb_suspend(struct device *dev, pm_message_t state, u32 level)
++static int sa1100fb_suspend(struct device *dev, pm_message_t state)
+ {
+ 	struct sa1100fb_info *fbi = dev_get_drvdata(dev);
+ 
+-	if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
+-		set_ctrlr_state(fbi, C_DISABLE_PM);
++	set_ctrlr_state(fbi, C_DISABLE_PM);
+ 	return 0;
+ }
+ 
+-static int sa1100fb_resume(struct device *dev, u32 level)
++static int sa1100fb_resume(struct device *dev)
+ {
+ 	struct sa1100fb_info *fbi = dev_get_drvdata(dev);
+ 
+-	if (level == RESUME_ENABLE)
+-		set_ctrlr_state(fbi, C_ENABLE_PM);
++	set_ctrlr_state(fbi, C_ENABLE_PM);
+ 	return 0;
+ }
+ #else
+diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
+--- a/drivers/video/sgivwfb.c
++++ b/drivers/video/sgivwfb.c
+@@ -18,6 +18,8 @@
+ #include <linux/fb.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
++#include <linux/platform_device.h>
++
+ #include <asm/io.h>
+ #include <asm/mtrr.h>
+ 
+diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
+--- a/drivers/video/vesafb.c
++++ b/drivers/video/vesafb.c
+@@ -19,6 +19,8 @@
+ #include <linux/fb.h>
+ #include <linux/ioport.h>
+ #include <linux/init.h>
++#include <linux/platform_device.h>
++
+ #include <video/vga.h>
+ #include <asm/io.h>
+ #include <asm/mtrr.h>
+diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
+--- a/drivers/video/vfb.c
++++ b/drivers/video/vfb.c
+@@ -20,6 +20,8 @@
+ #include <linux/vmalloc.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
++#include <linux/platform_device.h>
++
+ #include <asm/uaccess.h>
+ #include <linux/fb.h>
+ #include <linux/init.h>
+diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
+--- a/drivers/video/w100fb.c
++++ b/drivers/video/w100fb.c
+@@ -25,7 +25,7 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/string.h>
+ #include <linux/vmalloc.h>
+ #include <asm/io.h>
+@@ -438,36 +438,34 @@ static void w100fb_restore_vidmem(struct
+ 	}
+ }
+ 
+-static int w100fb_suspend(struct device *dev, pm_message_t state, uint32_t level)
++static int w100fb_suspend(struct device *dev, pm_message_t state)
+ {
+-	if (level == SUSPEND_POWER_DOWN) {
+-		struct fb_info *info = dev_get_drvdata(dev);
+-		struct w100fb_par *par=info->par;
+-		struct w100_tg_info *tg = par->mach->tg;
+-
+-		w100fb_save_vidmem(par);
+-		if(tg && tg->suspend)
+-			tg->suspend(par);
+-		w100_suspend(W100_SUSPEND_ALL);
+-		par->blanked = 1;
+-	}
++	struct fb_info *info = dev_get_drvdata(dev);
++	struct w100fb_par *par=info->par;
++	struct w100_tg_info *tg = par->mach->tg;
++
++	w100fb_save_vidmem(par);
++	if(tg && tg->suspend)
++		tg->suspend(par);
++	w100_suspend(W100_SUSPEND_ALL);
++	par->blanked = 1;
++
+ 	return 0;
+ }
+ 
+-static int w100fb_resume(struct device *dev, uint32_t level)
++static int w100fb_resume(struct device *dev)
+ {
+-	if (level == RESUME_POWER_ON) {
+-		struct fb_info *info = dev_get_drvdata(dev);
+-		struct w100fb_par *par=info->par;
+-		struct w100_tg_info *tg = par->mach->tg;
++	struct fb_info *info = dev_get_drvdata(dev);
++	struct w100fb_par *par=info->par;
++	struct w100_tg_info *tg = par->mach->tg;
++
++	w100_hw_init(par);
++	w100fb_activate_var(par);
++	w100fb_restore_vidmem(par);
++	if(tg && tg->resume)
++		tg->resume(par);
++	par->blanked = 0;
+ 
+-		w100_hw_init(par);
+-		w100fb_activate_var(par);
+-		w100fb_restore_vidmem(par);
+-		if(tg && tg->resume)
+-			tg->resume(par);
+-		par->blanked = 0;
+-	}
+ 	return 0;
+ }
+ #else
+diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
+--- a/drivers/w1/w1_family.c
++++ b/drivers/w1/w1_family.c
+@@ -21,6 +21,7 @@
+ 
+ #include <linux/spinlock.h>
+ #include <linux/list.h>
++#include <linux/sched.h>	/* schedule_timeout() */
+ #include <linux/delay.h>
+ 
+ #include "w1_family.h"
+diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
+--- a/drivers/zorro/zorro-sysfs.c
++++ b/drivers/zorro/zorro-sysfs.c
+@@ -14,6 +14,7 @@
+ #include <linux/kernel.h>
+ #include <linux/zorro.h>
+ #include <linux/stat.h>
++#include <linux/string.h>
+ 
+ #include "zorro.h"
+ 
+diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
+--- a/drivers/zorro/zorro.c
++++ b/drivers/zorro/zorro.c
+@@ -16,6 +16,8 @@
+ #include <linux/init.h>
+ #include <linux/zorro.h>
+ #include <linux/bitops.h>
++#include <linux/string.h>
++
+ #include <asm/setup.h>
+ #include <asm/amigahw.h>
+ 
+diff --git a/fs/Kconfig b/fs/Kconfig
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -810,7 +810,7 @@ config TMPFS
+ 
+ config HUGETLBFS
+ 	bool "HugeTLB file system support"
+-	depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || X86_64 || BROKEN
++	depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
+ 
+ config HUGETLB_PAGE
+ 	def_bool HUGETLBFS
+diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
+--- a/fs/Kconfig.binfmt
++++ b/fs/Kconfig.binfmt
+@@ -57,7 +57,7 @@ config BINFMT_SHARED_FLAT
+ 
+ config BINFMT_AOUT
+ 	tristate "Kernel support for a.out and ECOFF binaries"
+-	depends on (X86 && !X86_64) || ALPHA || ARM || M68K || SPARC32
++	depends on X86_32 || ALPHA || ARM || M68K || SPARC32
+ 	---help---
+ 	  A.out (Assembler.OUTput) is a set of formats for libraries and
+ 	  executables used in the earliest versions of UNIX.  Linux used
+diff --git a/fs/afs/file.c b/fs/afs/file.c
+--- a/fs/afs/file.c
++++ b/fs/afs/file.c
+@@ -29,7 +29,7 @@ static int afs_file_release(struct inode
+ 
+ static int afs_file_readpage(struct file *file, struct page *page);
+ static int afs_file_invalidatepage(struct page *page, unsigned long offset);
+-static int afs_file_releasepage(struct page *page, int gfp_flags);
++static int afs_file_releasepage(struct page *page, gfp_t gfp_flags);
+ 
+ static ssize_t afs_file_write(struct file *file, const char __user *buf,
+ 			      size_t size, loff_t *off);
+@@ -279,7 +279,7 @@ static int afs_file_invalidatepage(struc
+ /*
+  * release a page and cleanup its private data
+  */
+-static int afs_file_releasepage(struct page *page, int gfp_flags)
++static int afs_file_releasepage(struct page *page, gfp_t gfp_flags)
+ {
+ 	struct cachefs_page *pageio;
+ 
+@@ -291,8 +291,8 @@ static int afs_file_releasepage(struct p
+ 		cachefs_uncache_page(vnode->cache, page);
+ #endif
+ 
+-		pageio = (struct cachefs_page *) page->private;
+-		page->private = 0;
++		pageio = (struct cachefs_page *) page_private(page);
++		set_page_private(page, 0);
+ 		ClearPagePrivate(page);
+ 
+ 		if (pageio)
+diff --git a/fs/attr.c b/fs/attr.c
+--- a/fs/attr.c
++++ b/fs/attr.c
+@@ -117,9 +117,6 @@ int notify_change(struct dentry * dentry
+ 	struct timespec now;
+ 	unsigned int ia_valid = attr->ia_valid;
+ 
+-	if (!inode)
+-		BUG();
+-
+ 	mode = inode->i_mode;
+ 	now = current_fs_time(inode->i_sb);
+ 
+diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
+--- a/fs/binfmt_aout.c
++++ b/fs/binfmt_aout.c
+@@ -318,7 +318,6 @@ static int load_aout_binary(struct linux
+ 	current->mm->free_area_cache = current->mm->mmap_base;
+ 	current->mm->cached_hole_size = 0;
+ 
+-	set_mm_counter(current->mm, rss, 0);
+ 	current->mm->mmap = NULL;
+ 	compute_creds(bprm);
+  	current->flags &= ~PF_FORKNOEXEC;
+diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
+--- a/fs/binfmt_elf.c
++++ b/fs/binfmt_elf.c
+@@ -773,7 +773,6 @@ static int load_elf_binary(struct linux_
+ 
+ 	/* Do this so that we can load the interpreter, if need be.  We will
+ 	   change some of these later */
+-	set_mm_counter(current->mm, rss, 0);
+ 	current->mm->free_area_cache = current->mm->mmap_base;
+ 	current->mm->cached_hole_size = 0;
+ 	retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),
+@@ -1503,9 +1502,7 @@ static int elf_core_dump(long signr, str
+ 	fill_psinfo(psinfo, current->group_leader, current->mm);
+ 	fill_note(notes +1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
+ 	
+-	fill_note(notes +2, "CORE", NT_TASKSTRUCT, sizeof(*current), current);
+-  
+-	numnote = 3;
++	numnote = 2;
+ 
+ 	auxv = (elf_addr_t *) current->mm->saved_auxv;
+ 
+diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
+--- a/fs/binfmt_elf_fdpic.c
++++ b/fs/binfmt_elf_fdpic.c
+@@ -294,14 +294,7 @@ static int load_elf_fdpic_binary(struct 
+ 				  &interp_params,
+ 				  &current->mm->start_stack,
+ 				  &current->mm->start_brk);
+-#endif
+-
+-	/* do this so that we can load the interpreter, if need be
+-	 * - we will change some of these later
+-	 */
+-	set_mm_counter(current->mm, rss, 0);
+ 
+-#ifdef CONFIG_MMU
+ 	retval = setup_arg_pages(bprm, current->mm->start_stack, executable_stack);
+ 	if (retval < 0) {
+ 		send_sig(SIGKILL, current, 0);
+diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
+--- a/fs/binfmt_flat.c
++++ b/fs/binfmt_flat.c
+@@ -650,7 +650,6 @@ static int load_flat_file(struct linux_b
+ 		current->mm->start_brk = datapos + data_len + bss_len;
+ 		current->mm->brk = (current->mm->start_brk + 3) & ~3;
+ 		current->mm->context.end_brk = memp + ksize((void *) memp) - stack_len;
+-		set_mm_counter(current->mm, rss, 0);
+ 	}
+ 
+ 	if (flags & FLAT_FLAG_KTRACE)
+diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
+--- a/fs/binfmt_som.c
++++ b/fs/binfmt_som.c
+@@ -259,7 +259,6 @@ load_som_binary(struct linux_binprm * bp
+ 	create_som_tables(bprm);
+ 
+ 	current->mm->start_stack = bprm->p;
+-	set_mm_counter(current->mm, rss, 0);
+ 
+ #if 0
+ 	printk("(start_brk) %08lx\n" , (unsigned long) current->mm->start_brk);
+diff --git a/fs/bio.c b/fs/bio.c
+--- a/fs/bio.c
++++ b/fs/bio.c
+@@ -778,7 +778,7 @@ static int bio_map_kern_endio(struct bio
+ 
+ 
+ static struct bio *__bio_map_kern(request_queue_t *q, void *data,
+-				  unsigned int len, unsigned int gfp_mask)
++				  unsigned int len, gfp_t gfp_mask)
+ {
+ 	unsigned long kaddr = (unsigned long)data;
+ 	unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+@@ -825,7 +825,7 @@ static struct bio *__bio_map_kern(reques
+  *	device. Returns an error pointer in case of error.
+  */
+ struct bio *bio_map_kern(request_queue_t *q, void *data, unsigned int len,
+-			 unsigned int gfp_mask)
++			 gfp_t gfp_mask)
+ {
+ 	struct bio *bio;
+ 
+diff --git a/fs/buffer.c b/fs/buffer.c
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -96,7 +96,7 @@ static void
+ __clear_page_buffers(struct page *page)
+ {
+ 	ClearPagePrivate(page);
+-	page->private = 0;
++	set_page_private(page, 0);
+ 	page_cache_release(page);
+ }
+ 
+@@ -502,7 +502,7 @@ static void free_more_memory(void)
+ 	yield();
+ 
+ 	for_each_pgdat(pgdat) {
+-		zones = pgdat->node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones;
++		zones = pgdat->node_zonelists[gfp_zone(GFP_NOFS)].zones;
+ 		if (*zones)
+ 			try_to_free_pages(zones, GFP_NOFS);
+ 	}
+@@ -1478,8 +1478,10 @@ EXPORT_SYMBOL(__getblk);
+ void __breadahead(struct block_device *bdev, sector_t block, int size)
+ {
+ 	struct buffer_head *bh = __getblk(bdev, block, size);
+-	ll_rw_block(READA, 1, &bh);
+-	brelse(bh);
++	if (likely(bh)) {
++		ll_rw_block(READA, 1, &bh);
++		brelse(bh);
++	}
+ }
+ EXPORT_SYMBOL(__breadahead);
+ 
+@@ -1497,7 +1499,7 @@ __bread(struct block_device *bdev, secto
+ {
+ 	struct buffer_head *bh = __getblk(bdev, block, size);
+ 
+-	if (!buffer_uptodate(bh))
++	if (likely(bh) && !buffer_uptodate(bh))
+ 		bh = __bread_slow(bh);
+ 	return bh;
+ }
+@@ -1571,7 +1573,7 @@ static inline void discard_buffer(struct
+  *
+  * NOTE: @gfp_mask may go away, and this function may become non-blocking.
+  */
+-int try_to_release_page(struct page *page, int gfp_mask)
++int try_to_release_page(struct page *page, gfp_t gfp_mask)
+ {
+ 	struct address_space * const mapping = page->mapping;
+ 
+@@ -1637,6 +1639,15 @@ out:
+ }
+ EXPORT_SYMBOL(block_invalidatepage);
+ 
++int do_invalidatepage(struct page *page, unsigned long offset)
++{
++	int (*invalidatepage)(struct page *, unsigned long);
++	invalidatepage = page->mapping->a_ops->invalidatepage;
++	if (invalidatepage == NULL)
++		invalidatepage = block_invalidatepage;
++	return (*invalidatepage)(page, offset);
++}
++
+ /*
+  * We attach and possibly dirty the buffers atomically wrt
+  * __set_page_dirty_buffers() via private_lock.  try_to_free_buffers
+@@ -2696,7 +2707,7 @@ int block_write_full_page(struct page *p
+ 		 * they may have been added in ext3_writepage().  Make them
+ 		 * freeable here, so the page does not leak.
+ 		 */
+-		block_invalidatepage(page, 0);
++		do_invalidatepage(page, 0);
+ 		unlock_page(page);
+ 		return 0; /* don't care */
+ 	}
+diff --git a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS
+--- a/fs/cifs/AUTHORS
++++ b/fs/cifs/AUTHORS
+@@ -32,6 +32,10 @@ Domen Puncer
+ Jesper Juhl (in particular for lots of whitespace/formatting cleanup)
+ Vince Negri and Dave Stahl (for finding an important caching bug)
+ Adrian Bunk (kcalloc cleanups)
++Miklos Szeredi 
++Kazeon team for various fixes especially for 2.4 version.
++Asser Ferno (Change Notify support)
++Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup
+ 
+ Test case and Bug Report contributors
+ -------------------------------------
+diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
+--- a/fs/cifs/CHANGES
++++ b/fs/cifs/CHANGES
+@@ -1,8 +1,52 @@
++Version 1.39
++------------
++Defer close of a file handle slightly if pending writes depend on that file handle
++(this reduces the EBADF bad file handle errors that can be logged under heavy
++stress on writes).
++
++Version 1.38
++------------
++Fix tcp socket retransmission timeouts (e.g. on ENOSPACE from the socket)
++to be smaller at first (but increasing) so large write performance performance
++over GigE is better.  Do not hang thread on illegal byte range lock response
++from Windows (Windows can send an RFC1001 size which does not match smb size) by
++allowing an SMBs TCP length to be up to a few bytes longer than it should be.
++wsize and rsize can now be larger than negotiated buffer size if server
++supports large readx/writex, even when directio mount flag not specified.
++Write size will in many cases now be 16K instead of 4K which greatly helps
++file copy performance on lightly loaded networks.  Fix oops in dnotify
++when experimental config flag enabled. Make cifsFYI more granular.
++
++Version 1.37
++------------
++Fix readdir caching when unlink removes file in current search buffer,
++and this is followed by a rewind search to just before the deleted entry.
++Do not attempt to set ctime unless atime and/or mtime change requested
++(most servers throw it away anyway). Fix length check of received smbs
++to be more accurate. Fix big endian problem with mapchars mount option,
++and with a field returned by statfs.
++
++Version 1.36
++------------
++Add support for mounting to older pre-CIFS servers such as Windows9x and ME.
++For these older servers, add option for passing netbios name of server in
++on mount (servernetbiosname).  Add suspend support for power management, to
++avoid cifsd thread preventing software suspend from working.
++Add mount option for disabling the default behavior of sending byte range lock
++requests to the server (necessary for certain applications which break with
++mandatory lock behavior such as Evolution), and also mount option for
++requesting case insensitive matching for path based requests (requesting
++case sensitive is the default).
++
+ Version 1.35
+ ------------
+ Add writepage performance improvements.  Fix path name conversions
+ for long filenames on mounts which were done with "mapchars" mount option
+-specified.
++specified.  Ensure multiplex ids do not collide.  Fix case in which 
++rmmod can oops if done soon after last unmount.  Fix truncated
++search (readdir) output when resume filename was a long filename.
++Fix filename conversion when mapchars mount option was specified and
++filename was a long filename.
+ 
+ Version 1.34
+ ------------
+@@ -11,7 +55,7 @@ Do not oops if root user kills cifs oplo
+ kills the cifsd thread (NB: killing the cifs kernel threads is not
+ recommended, unmount and rmmod cifs will kill them when they are
+ no longer needed).  Fix readdir to ASCII servers (ie older servers
+-which do not support Unicode) and also require asterik.
++which do not support Unicode) and also require asterisk.
+ Fix out of memory case in which data could be written one page
+ off in the page cache.
+ 
+@@ -101,7 +145,7 @@ improperly zeroed buffer in CIFS Unix ex
+ 
+ Version 1.25
+ ------------
+-Fix internationlization problem in cifs readdir with filenames that map to 
++Fix internationalization problem in cifs readdir with filenames that map to 
+ longer UTF8 strings than the string on the wire was in Unicode.  Add workaround
+ for readdir to netapp servers. Fix search rewind (seek into readdir to return 
+ non-consecutive entries).  Do not do readdir when server negotiates 
+@@ -276,7 +320,7 @@ Fix caching problem when files opened by
+ page cache could contain stale data, and write through did
+ not occur often enough while file was still open when read ahead
+ (read oplock) not allowed.  Treat "sep=" when first mount option
+-as an overrride of comma as the default separator between mount
++as an override of comma as the default separator between mount
+ options. 
+ 
+ Version 1.01
+@@ -286,7 +330,7 @@ Allow passwords longer than 16 bytes. Al
+ Version 1.00
+ ------------
+ Gracefully clean up failed mounts when attempting to mount to servers such as
+-Windows 98 that terminate tcp sessions during prototocol negotiation.  Handle
++Windows 98 that terminate tcp sessions during protocol negotiation.  Handle
+ embedded commas in mount parsing of passwords.
+ 
+ Version 0.99
+@@ -295,7 +339,7 @@ Invalidate local inode cached pages on o
+ instance is closed so that the client does not continue using stale local
+ copy rather than later modified server copy of file.  Do not reconnect
+ when server drops the tcp session prematurely before negotiate
+-protocol response.  Fix oops in roepen_file when dentry freed.  Allow
++protocol response.  Fix oops in reopen_file when dentry freed.  Allow
+ the support for CIFS Unix Extensions to be disabled via proc interface.
+ 
+ Version 0.98
+@@ -637,7 +681,7 @@ versions of 2.4 kernel (now builds and w
+ Version 0.41
+ ------------
+ Various minor fixes for Connectathon Posix "basic" file i/o test suite.  Directory caching fixed so hardlinked
+-files now return the correct rumber of links on fstat as they are repeatedly linked and unlinked.
++files now return the correct number of links on fstat as they are repeatedly linked and unlinked.
+ 
+ Version 0.40
+ ------------
+@@ -704,7 +748,7 @@ session) 
+ and cleaned them up and made them more consistent with other cifs functions. 
+ 
+ 7) Server support for Unix extensions is now fully detected and FindFirst is implemented both ways 
+-(with or without Unix exentions) but FindNext and QueryPathInfo with the Unix extensions are not completed,
++(with or without Unix extensions) but FindNext and QueryPathInfo with the Unix extensions are not completed,
+ nor is the symlink support using the Unix extensions
+ 
+ 8) Started adding the readlink and follow_link code 
+diff --git a/fs/cifs/README b/fs/cifs/README
+--- a/fs/cifs/README
++++ b/fs/cifs/README
+@@ -294,8 +294,10 @@ A partial list of the supported mount op
+ 		during the local client kernel build will be used.
+ 		If server does not support Unicode, this parameter is
+ 		unused.
+-  rsize		default read size
+-  wsize		default write size
++  rsize		default read size (usually 16K)
++  wsize		default write size (usually 16K, 32K is often better over GigE)
++		maximum wsize currently allowed by CIFS is 57344 (14 4096 byte
++		pages)
+   rw		mount the network share read-write (note that the
+ 		server may still consider the share read-only)
+   ro		mount network share read-only
+@@ -407,6 +409,13 @@ A partial list of the supported mount op
+ 		This has no effect if the server does not support
+ 		Unicode on the wire.
+  nomapchars     Do not translate any of these seven characters (default).
++ nocase         Request case insensitive path name matching (case
++		sensitive is the default if the server suports it).
++ nobrl          Do not send byte range lock requests to the server.
++		This is necessary for certain applications that break
++		with cifs style mandatory byte range locks (and most
++		cifs servers do not yet support requesting advisory
++		byte range locks).
+  remount        remount the share (often used to change from ro to rw mounts
+ 	        or vice versa)
+ 		
+@@ -473,9 +482,16 @@ These experimental features and tracing 
+ kernel, e.g.  insmod cifs).  To enable a feature set it to 1 e.g.  to enable 
+ tracing to the kernel message log type: 
+ 
+-	echo 1 > /proc/fs/cifs/cifsFYI
++	echo 7 > /proc/fs/cifs/cifsFYI
+ 	
+-and for more extensive tracing including the start of smb requests and responses
++cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel
++logging of various informational messages.  2 enables logging of non-zero
++SMB return codes while 4 enables logging of requests that take longer
++than one second to complete (except for byte range lock requests). 
++Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the
++source code (typically by setting it in the beginning of cifsglob.h),
++and setting it to seven enables all three.  Finally, tracing
++the start of smb requests and responses can be enabled via:
+ 
+ 	echo 1 > /proc/fs/cifs/traceSMB
+ 
+diff --git a/fs/cifs/TODO b/fs/cifs/TODO
+--- a/fs/cifs/TODO
++++ b/fs/cifs/TODO
+@@ -1,4 +1,4 @@
+-version 1.34 April 29, 2005
++version 1.37 October 9, 2005
+ 
+ A Partial List of Missing Features
+ ==================================
+@@ -7,14 +7,14 @@ Contributions are welcome.  There are pl
+ for visible, important contributions to this module.  Here
+ is a partial list of the known problems and missing features:
+ 
+-a) Support for SecurityDescriptors for chmod/chgrp/chown so
+-these can be supported for Windows servers
++a) Support for SecurityDescriptors(Windows/CIFS ACLs) for chmod/chgrp/chown
++so that these operations can be supported to Windows servers
+ 
+-b) Better pam/winbind integration (e.g. to handle uid mapping
+-better)
++b) Mapping POSIX ACLs (and eventually NFSv4 ACLs) to CIFS
++SecurityDescriptors
+ 
+-c) multi-user mounts - multiplexed sessionsetups over single vc
+-(ie tcp session) - more testing needed
++c) Better pam/winbind integration (e.g. to handle uid mapping
++better)
+ 
+ d) Kerberos/SPNEGO session setup support - (started)
+ 
+@@ -29,12 +29,17 @@ f) Directory entry caching relies on a 1
+ using FindNotify or equivalent.  - (started)
+ 
+ g) A few byte range testcases fail due to POSIX vs. Windows/CIFS
+-style byte range lock differences
++style byte range lock differences.  Save byte range locks so
++reconnect can replay them.  
+ 
+-h) quota support
++h) Support unlock all (unlock 0,MAX_OFFSET)
++by unlocking all known byte range locks that we locked on the file.
+ 
+-j) finish writepages support (multi-page write behind for improved
+-performance) and syncpage
++i) quota support (needs minor kernel change since quota calls
++to make it to network filesystems or deviceless filesystems)
++
++j) investigate sync behavior (including syncpage) and check  
++for proper behavior of intr/nointr
+ 
+ k) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
+ extra copy in/out of the socket buffers in some cases.
+@@ -57,20 +62,18 @@ p) Add support for storing symlink and f
+ in the Extended Attribute format their SFU clients would recognize.
+ 
+ q) Finish fcntl D_NOTIFY support so kde and gnome file list windows
+-will autorefresh (started)
++will autorefresh (partially complete by Asser). Needs minor kernel
++vfs change to support removing D_NOTIFY on a file.   
+ 
+ r) Add GUI tool to configure /proc/fs/cifs settings and for display of
+ the CIFS statistics (started)
+ 
+-q) implement support for security and trusted categories of xattrs
++s) implement support for security and trusted categories of xattrs
+ (requires minor protocol extension) to enable better support for SELINUX
+ 
+-r) Implement O_DIRECT flag on open (already supported on mount)
+-
+-s) Allow remapping of last remaining character (\) to +0xF000 which
+-(this character is valid for POSIX but not for Windows)
++t) Implement O_DIRECT flag on open (already supported on mount)
+ 
+-t) Create UID mapping facility so server UIDs can be mapped on a per
++u) Create UID mapping facility so server UIDs can be mapped on a per
+ mount or a per server basis to client UIDs or nobody if no mapping
+ exists.  This is helpful when Unix extensions are negotiated to
+ allow better permission checking when UIDs differ on the server
+@@ -78,6 +81,17 @@ and client.  Add new protocol request to
+ standard for asking the server for the corresponding name of a
+ particular uid.
+ 
++v) Add support for CIFS Unix and also the newer POSIX extensions to the
++server side for Samba 4.
++
++w) Finish up the dos time conversion routines needed to return old server
++time to the client (default time, of now or time 0 is used now for these 
++very old servers)
++
++x) Add support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers)
++
++y) Finish testing of Windows 9x/Windows ME server support (started).
++
+ KNOWN BUGS (updated April 29, 2005)
+ ====================================
+ See http://bugzilla.samba.org - search on product "CifsVFS" for
+diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
+--- a/fs/cifs/asn1.c
++++ b/fs/cifs/asn1.c
+@@ -191,7 +191,8 @@ asn1_header_decode(struct asn1_ctx *ctx,
+ 		   unsigned char **eoc,
+ 		   unsigned int *cls, unsigned int *con, unsigned int *tag)
+ {
+-	unsigned int def, len;
++	unsigned int def = 0; 
++	unsigned int len = 0;
+ 
+ 	if (!asn1_id_decode(ctx, cls, con, tag))
+ 		return 0;
+diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -81,6 +81,8 @@ cifs_debug_data_read(char *buf, char **b
+ 	buf += length;
+ 	length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION);
+ 	buf += length;
++	length = sprintf(buf,"Active VFS Requests: %d\n", GlobalTotalActiveXid);
++	buf += length;
+ 	length = sprintf(buf, "Servers:");
+ 	buf += length;
+ 
+@@ -97,7 +99,7 @@ cifs_debug_data_read(char *buf, char **b
+ 		} else {
+ 			length =
+ 			    sprintf(buf,
+-				    "\n%d) Name: %s  Domain: %s Mounts: %d ServerOS: %s  \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\t",
++				    "\n%d) Name: %s  Domain: %s Mounts: %d OS: %s  \n\tNOS: %s\tCapability: 0x%x\n\tSMB session status: %d\t",
+ 				i, ses->serverName, ses->serverDomain,
+ 				atomic_read(&ses->inUse),
+ 				ses->serverOS, ses->serverNOS,
+@@ -105,12 +107,18 @@ cifs_debug_data_read(char *buf, char **b
+ 			buf += length;
+ 		}
+ 		if(ses->server) {
+-			buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d",
++			buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d",
+ 				ses->server->tcpStatus,
+ 				atomic_read(&ses->server->socketUseCount),
+ 				ses->server->secMode,
+ 				atomic_read(&ses->server->inFlight));
+-			
++
++#ifdef CONFIG_CIFS_STATS2
++			buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d",
++				atomic_read(&ses->server->inSend), 
++				atomic_read(&ses->server->num_waiters));
++#endif
++
+ 			length = sprintf(buf, "\nMIDs:\n");
+ 			buf += length;
+ 
+@@ -149,7 +157,7 @@ cifs_debug_data_read(char *buf, char **b
+ 		dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
+ 		length =
+ 		    sprintf(buf,
+-			    "\n%d) %s Uses: %d Type: %s Characteristics: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
++			    "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
+ 			    i, tcon->treeName,
+ 			    atomic_read(&tcon->useCount),
+ 			    tcon->nativeFileSystem,
+@@ -195,6 +203,49 @@ cifs_debug_data_read(char *buf, char **b
+ }
+ 
+ #ifdef CONFIG_CIFS_STATS
++
++static int
++cifs_stats_write(struct file *file, const char __user *buffer,
++               unsigned long count, void *data)
++{
++        char c;
++        int rc;
++	struct list_head *tmp;
++	struct cifsTconInfo *tcon;
++
++        rc = get_user(c, buffer);
++        if (rc)
++                return rc;
++
++        if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
++		read_lock(&GlobalSMBSeslock);
++		list_for_each(tmp, &GlobalTreeConnectionList) {
++			tcon = list_entry(tmp, struct cifsTconInfo,
++					cifsConnectionList);
++			atomic_set(&tcon->num_smbs_sent, 0);
++			atomic_set(&tcon->num_writes, 0);
++			atomic_set(&tcon->num_reads, 0);
++			atomic_set(&tcon->num_oplock_brks, 0);
++			atomic_set(&tcon->num_opens, 0);
++			atomic_set(&tcon->num_closes, 0);
++			atomic_set(&tcon->num_deletes, 0);
++			atomic_set(&tcon->num_mkdirs, 0);
++			atomic_set(&tcon->num_rmdirs, 0);
++			atomic_set(&tcon->num_renames, 0);
++			atomic_set(&tcon->num_t2renames, 0);
++			atomic_set(&tcon->num_ffirst, 0);
++			atomic_set(&tcon->num_fnext, 0);
++			atomic_set(&tcon->num_fclose, 0);
++			atomic_set(&tcon->num_hardlinks, 0);
++			atomic_set(&tcon->num_symlinks, 0);
++			atomic_set(&tcon->num_locks, 0);
++		}
++		read_unlock(&GlobalSMBSeslock);
++	}
++
++        return count;
++}
++
+ static int
+ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
+ 		  int count, int *eof, void *data)
+@@ -254,35 +305,51 @@ cifs_stats_read(char *buf, char **beginB
+ 			buf += sprintf(buf, "\tDISCONNECTED ");
+ 			length += 14;
+ 		}
+-		item_length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d",
++		item_length = sprintf(buf, "\nSMBs: %d Oplock Breaks: %d",
+ 			atomic_read(&tcon->num_smbs_sent),
+ 			atomic_read(&tcon->num_oplock_brks));
+ 		buf += item_length;
+ 		length += item_length;
+-		item_length = sprintf(buf,"\nReads: %d Bytes %lld",
++		item_length = sprintf(buf, "\nReads:  %d Bytes: %lld",
+ 			atomic_read(&tcon->num_reads),
+ 			(long long)(tcon->bytes_read));
+ 		buf += item_length;
+ 		length += item_length;
+-		item_length = sprintf(buf,"\nWrites: %d Bytes: %lld",
++		item_length = sprintf(buf, "\nWrites: %d Bytes: %lld",
+ 			atomic_read(&tcon->num_writes),
+ 			(long long)(tcon->bytes_written));
++                buf += item_length;
++                length += item_length;
++                item_length = sprintf(buf, 
++			"\nLocks: %d HardLinks: %d Symlinks: %d",
++                        atomic_read(&tcon->num_locks),
++			atomic_read(&tcon->num_hardlinks),
++			atomic_read(&tcon->num_symlinks));
++                buf += item_length;
++                length += item_length;
++
++		item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d",
++			atomic_read(&tcon->num_opens),
++			atomic_read(&tcon->num_closes),
++			atomic_read(&tcon->num_deletes));
+ 		buf += item_length;
+ 		length += item_length;
+-		item_length = sprintf(buf,
+-			"\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
+-			atomic_read(&tcon->num_opens),
+-			atomic_read(&tcon->num_deletes),
++		item_length = sprintf(buf, "\nMkdirs: %d Rmdirs: %d",
+ 			atomic_read(&tcon->num_mkdirs),
+ 			atomic_read(&tcon->num_rmdirs));
+ 		buf += item_length;
+ 		length += item_length;
+-		item_length = sprintf(buf,
+-			"\nRenames: %d T2 Renames %d",
++		item_length = sprintf(buf, "\nRenames: %d T2 Renames %d",
+ 			atomic_read(&tcon->num_renames),
+ 			atomic_read(&tcon->num_t2renames));
+ 		buf += item_length;
+ 		length += item_length;
++		item_length = sprintf(buf, "\nFindFirst: %d FNext %d FClose %d",
++			atomic_read(&tcon->num_ffirst),
++			atomic_read(&tcon->num_fnext),
++			atomic_read(&tcon->num_fclose));
++		buf += item_length;
++		length += item_length;
+ 	}
+ 	read_unlock(&GlobalSMBSeslock);
+ 
+@@ -341,8 +408,10 @@ cifs_proc_init(void)
+ 				cifs_debug_data_read, NULL);
+ 
+ #ifdef CONFIG_CIFS_STATS
+-	create_proc_read_entry("Stats", 0, proc_fs_cifs,
++	pde = create_proc_read_entry("Stats", 0, proc_fs_cifs,
+ 				cifs_stats_read, NULL);
++	if (pde)
++		pde->write_proc = cifs_stats_write;
+ #endif
+ 	pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
+ 				cifsFYI_read, NULL);
+@@ -360,7 +429,7 @@ cifs_proc_init(void)
+ 	if (pde)
+ 		pde->write_proc = oplockEnabled_write;
+ 
+-	pde = create_proc_read_entry("ReenableOldCifsReaddirCode", 0, proc_fs_cifs,
++	pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs,
+ 				quotaEnabled_read, NULL);
+ 	if (pde)
+ 		pde->write_proc = quotaEnabled_write;
+@@ -419,7 +488,7 @@ cifs_proc_clean(void)
+ 	remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
+ 	remove_proc_entry("PacketSigningEnabled",proc_fs_cifs);
+ 	remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
+-	remove_proc_entry("ReenableOldCifsReaddirCode",proc_fs_cifs);
++	remove_proc_entry("Experimental",proc_fs_cifs);
+ 	remove_proc_entry("LookupCacheEnabled",proc_fs_cifs);
+ 	remove_proc_entry("cifs", proc_root_fs);
+ }
+@@ -459,6 +528,8 @@ cifsFYI_write(struct file *file, const c
+ 		cifsFYI = 0;
+ 	else if (c == '1' || c == 'y' || c == 'Y')
+ 		cifsFYI = 1;
++	else if((c > '1') && (c <= '9'))
++		cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
+ 
+ 	return count;
+ }
+diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
+--- a/fs/cifs/cifs_debug.h
++++ b/fs/cifs/cifs_debug.h
+@@ -26,6 +26,9 @@
+ void cifs_dump_mem(char *label, void *data, int length);
+ extern int traceSMB;		/* flag which enables the function below */
+ void dump_smb(struct smb_hdr *, int);
++#define CIFS_INFO	0x01
++#define CIFS_RC  	0x02
++#define CIFS_TIMER	0x04
+ 
+ /*
+  *	debug ON
+@@ -36,7 +39,7 @@ void dump_smb(struct smb_hdr *, int);
+ 
+ /* information message: e.g., configuration, major event */
+ extern int cifsFYI;
+-#define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
++#define cifsfyi(format,arg...) if (cifsFYI & CIFS_INFO) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
+ 
+ #define cFYI(button,prspec) if (button) cifsfyi prspec
+ 
+diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
+--- a/fs/cifs/cifs_fs_sb.h
++++ b/fs/cifs/cifs_fs_sb.h
+@@ -24,6 +24,9 @@
+ #define CIFS_MOUNT_DIRECT_IO    8 /* do not write nor read through page cache */
+ #define CIFS_MOUNT_NO_XATTR  0x10 /* if set - disable xattr support */
+ #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
++#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */
++#define CIFS_MOUNT_UNX_EMUL    0x80 /* Network compat with SFUnix emulation */
++#define CIFS_MOUNT_NO_BRL	0x100 /* No sending byte range locks to srv */
+ 
+ struct cifs_sb_info {
+ 	struct cifsTconInfo *tcon;	/* primary mount */
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -59,6 +59,8 @@ unsigned int ntlmv2_support = 0;
+ unsigned int sign_CIFS_PDUs = 1;
+ extern struct task_struct * oplockThread; /* remove sparse warning */
+ struct task_struct * oplockThread = NULL;
++extern struct task_struct * dnotifyThread; /* remove sparse warning */
++struct task_struct * dnotifyThread = NULL;
+ unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
+ module_param(CIFSMaxBufSize, int, 0);
+ MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
+@@ -73,6 +75,7 @@ module_param(cifs_max_pending, int, 0);
+ MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
+ 
+ static DECLARE_COMPLETION(cifs_oplock_exited);
++static DECLARE_COMPLETION(cifs_dnotify_exited);
+ 
+ extern mempool_t *cifs_sm_req_poolp;
+ extern mempool_t *cifs_req_poolp;
+@@ -202,6 +205,10 @@ cifs_statfs(struct super_block *sb, stru
+ #endif /* CIFS_EXPERIMENTAL */
+ 	rc = CIFSSMBQFSInfo(xid, pTcon, buf);
+ 
++	/* Old Windows servers do not support level 103, retry with level 
++	   one if old server failed the previous call */ 
++	if(rc)
++		rc = SMBOldQFSInfo(xid, pTcon, buf);
+ 	/*     
+ 	   int f_type;
+ 	   __fsid_t f_fsid;
+@@ -253,7 +260,7 @@ cifs_alloc_inode(struct super_block *sb)
+ 	cifs_inode->clientCanCacheAll = FALSE;
+ 	cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE;
+ 	cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
+-
++	cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;
+ 	INIT_LIST_HEAD(&cifs_inode->openFileList);
+ 	return &cifs_inode->vfs_inode;
+ }
+@@ -398,6 +405,34 @@ static struct quotactl_ops cifs_quotactl
+ };
+ #endif
+ 
++static void cifs_umount_begin(struct super_block * sblock)
++{
++	struct cifs_sb_info *cifs_sb;
++	struct cifsTconInfo * tcon;
++
++	cifs_sb = CIFS_SB(sblock);
++	if(cifs_sb == NULL)
++		return;
++
++	tcon = cifs_sb->tcon;
++	if(tcon == NULL)
++		return;
++	down(&tcon->tconSem);
++	if (atomic_read(&tcon->useCount) == 1)
++		tcon->tidStatus = CifsExiting;
++	up(&tcon->tconSem);
++
++	if(tcon->ses && tcon->ses->server)
++	{
++		cERROR(1,("wake up tasks now - umount begin not complete"));
++		wake_up_all(&tcon->ses->server->request_q);
++	}
++/* BB FIXME - finish add checks for tidStatus BB */
++
++	return;
++}
++	
++
+ static int cifs_remount(struct super_block *sb, int *flags, char *data)
+ {
+ 	*flags |= MS_NODIRATIME;
+@@ -415,7 +450,7 @@ struct super_operations cifs_super_ops =
+    unless later we add lazy close of inodes or unless the kernel forgets to call
+    us with the same number of releases (closes) as opens */
+ 	.show_options = cifs_show_options,
+-/*    .umount_begin   = cifs_umount_begin, *//* consider adding in the future */
++/*	.umount_begin   = cifs_umount_begin, */ /* BB finish in the future */
+ 	.remount_fs = cifs_remount,
+ };
+ 
+@@ -783,9 +818,7 @@ static int cifs_oplock_thread(void * dum
+ 	do {
+ 		if (try_to_freeze()) 
+ 			continue;
+-		set_current_state(TASK_INTERRUPTIBLE);
+ 		
+-		schedule_timeout(1*HZ);  
+ 		spin_lock(&GlobalMid_Lock);
+ 		if(list_empty(&GlobalOplock_Q)) {
+ 			spin_unlock(&GlobalMid_Lock);
+@@ -834,10 +867,27 @@ static int cifs_oplock_thread(void * dum
+ 				}
+ 			} else
+ 				spin_unlock(&GlobalMid_Lock);
++			set_current_state(TASK_INTERRUPTIBLE);
++			schedule_timeout(1);  /* yield in case q were corrupt */
+ 		}
+ 	} while(!signal_pending(current));
+-	complete_and_exit (&cifs_oplock_exited, 0);
+ 	oplockThread = NULL;
++	complete_and_exit (&cifs_oplock_exited, 0);
++}
++
++static int cifs_dnotify_thread(void * dummyarg)
++{
++	daemonize("cifsdnotifyd");
++	allow_signal(SIGTERM);
++
++	dnotifyThread = current;
++	do {
++		if(try_to_freeze())
++			continue;
++		set_current_state(TASK_INTERRUPTIBLE);
++		schedule_timeout(39*HZ);
++	} while(!signal_pending(current));
++	complete_and_exit (&cifs_dnotify_exited, 0);
+ }
+ 
+ static int __init
+@@ -851,6 +901,10 @@ init_cifs(void)
+ 	INIT_LIST_HEAD(&GlobalSMBSessionList);
+ 	INIT_LIST_HEAD(&GlobalTreeConnectionList);
+ 	INIT_LIST_HEAD(&GlobalOplock_Q);
++#ifdef CONFIG_CIFS_EXPERIMENTAL
++	INIT_LIST_HEAD(&GlobalDnotifyReqList);
++	INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
++#endif	
+ /*
+  *  Initialize Global counters
+  */
+@@ -886,10 +940,16 @@ init_cifs(void)
+ 				if (!rc) {                
+ 					rc = (int)kernel_thread(cifs_oplock_thread, NULL, 
+ 						CLONE_FS | CLONE_FILES | CLONE_VM);
+-					if(rc > 0)
+-						return 0;
+-					else 
++					if(rc > 0) {
++						rc = (int)kernel_thread(cifs_dnotify_thread, NULL,
++							CLONE_FS | CLONE_FILES | CLONE_VM);
++						if(rc > 0)
++							return 0;
++						else
++							cERROR(1,("error %d create dnotify thread", rc));
++					} else {
+ 						cERROR(1,("error %d create oplock thread",rc));
++					}
+ 				}
+ 				cifs_destroy_request_bufs();
+ 			}
+@@ -918,6 +978,10 @@ exit_cifs(void)
+ 		send_sig(SIGTERM, oplockThread, 1);
+ 		wait_for_completion(&cifs_oplock_exited);
+ 	}
++	if(dnotifyThread) {
++		send_sig(SIGTERM, dnotifyThread, 1);
++		wait_for_completion(&cifs_dnotify_exited);
++	}
+ }
+ 
+ MODULE_AUTHOR("Steve French <sfrench at us.ibm.com>");
+diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
+--- a/fs/cifs/cifsfs.h
++++ b/fs/cifs/cifsfs.h
+@@ -81,6 +81,7 @@ extern int cifs_dir_notify(struct file *
+ 
+ /* Functions related to dir entries */
+ extern struct dentry_operations cifs_dentry_ops;
++extern struct dentry_operations cifs_ci_dentry_ops;
+ 
+ /* Functions related to symlinks */
+ extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
+@@ -96,5 +97,5 @@ extern ssize_t	cifs_getxattr(struct dent
+ extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
+ extern int cifs_ioctl (struct inode * inode, struct file * filep,
+ 		       unsigned int command, unsigned long arg);
+-#define CIFS_VERSION   "1.35"
++#define CIFS_VERSION   "1.39"
+ #endif				/* _CIFSFS_H */
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -110,8 +110,9 @@ enum protocolEnum {
+  */
+ 
+ struct TCP_Server_Info {
+-	char server_Name[SERVER_NAME_LEN_WITH_NULL];	/* 15 chars + X'20'in 16th */
+-	char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];	/* Unicode version of server_Name */
++	/* 15 character server name + 0x20 16th byte indicating type = srv */
++	char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
++	char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
+ 	struct socket *ssocket;
+ 	union {
+ 		struct sockaddr_in sockAddr;
+@@ -122,13 +123,17 @@ struct TCP_Server_Info {
+ 	struct list_head pending_mid_q;
+ 	void *Server_NlsInfo;	/* BB - placeholder for future NLS info  */
+ 	unsigned short server_codepage;	/* codepage for the server    */
+-	unsigned long ip_address;	/* IP addr for the server if known     */
++	unsigned long ip_address;	/* IP addr for the server if known */
+ 	enum protocolEnum protocolType;	
+ 	char versionMajor;
+ 	char versionMinor;
+ 	unsigned svlocal:1;	/* local server or remote */
+ 	atomic_t socketUseCount; /* number of open cifs sessions on socket */
+ 	atomic_t inFlight;  /* number of requests on the wire to server */
++#ifdef CONFIG_CIFS_STATS2
++	atomic_t inSend; /* requests trying to send */
++	atomic_t num_waiters;   /* blocked waiting to get in sendrecv */
++#endif
+ 	enum statusEnum tcpStatus; /* what we think the status is */
+ 	struct semaphore tcpSem;
+ 	struct task_struct *tsk;
+@@ -147,8 +152,10 @@ struct TCP_Server_Info {
+ 	/* (returned on Negotiate */
+ 	int capabilities; /* allow selective disabling of caps by smb sess */
+ 	__u16 timeZone;
++	__u16 CurrentMid;         /* multiplex id - rotating counter */
+ 	char cryptKey[CIFS_CRYPTO_KEY_SIZE];
+-	char workstation_RFC1001_name[16]; /* 16th byte is always zero */
++	/* 16th byte of RFC1001 workstation name is always null */
++	char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
+ 	__u32 sequence_number; /* needed for CIFS PDU signature */
+ 	char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16]; 
+ };
+@@ -214,19 +221,41 @@ struct cifsTconInfo {
+ 	atomic_t num_reads;
+ 	atomic_t num_oplock_brks;
+ 	atomic_t num_opens;
++	atomic_t num_closes;
+ 	atomic_t num_deletes;
+ 	atomic_t num_mkdirs;
+ 	atomic_t num_rmdirs;
+ 	atomic_t num_renames;
+ 	atomic_t num_t2renames;
++	atomic_t num_ffirst;
++	atomic_t num_fnext;
++	atomic_t num_fclose;
++	atomic_t num_hardlinks;
++	atomic_t num_symlinks;
++	atomic_t num_locks;
++#ifdef CONFIG_CIFS_STATS2
++	unsigned long long time_writes;
++	unsigned long long time_reads;
++	unsigned long long time_opens;
++	unsigned long long time_deletes;
++	unsigned long long time_closes;
++	unsigned long long time_mkdirs;
++	unsigned long long time_rmdirs;
++	unsigned long long time_renames;
++	unsigned long long time_t2renames;
++	unsigned long long time_ffirst;
++	unsigned long long time_fnext;
++	unsigned long long time_fclose;
++#endif /* CONFIG_CIFS_STATS2 */
+ 	__u64    bytes_read;
+ 	__u64    bytes_written;
+ 	spinlock_t stat_lock;
+-#endif
++#endif /* CONFIG_CIFS_STATS */
+ 	FILE_SYSTEM_DEVICE_INFO fsDevInfo;
+ 	FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo;	/* ok if file system name truncated */
+ 	FILE_SYSTEM_UNIX_INFO fsUnixInfo;
+ 	unsigned retry:1;
++	unsigned nocase:1;
+ 	/* BB add field for back pointer to sb struct? */
+ };
+ 
+@@ -270,6 +299,7 @@ struct cifsFileInfo {
+ 	struct inode * pInode; /* needed for oplock break */
+ 	unsigned closePend:1;	/* file is marked to close */
+ 	unsigned invalidHandle:1;  /* file closed via session abend */
++	atomic_t wrtPending;   /* handle in use - defer close */
+ 	struct semaphore fh_sem; /* prevents reopen race after dead ses*/
+ 	char * search_resume_name; /* BB removeme BB */
+ 	unsigned int resume_name_length; /* BB removeme - field renamed and moved BB */
+@@ -306,6 +336,41 @@ CIFS_SB(struct super_block *sb)
+ 	return sb->s_fs_info;
+ }
+ 
++static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
++{
++	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
++		return '/';
++	else
++		return '\\';
++}
++
++#ifdef CONFIG_CIFS_STATS
++#define cifs_stats_inc atomic_inc
++
++static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon,
++					    unsigned int bytes)
++{
++	if (bytes) {
++		spin_lock(&tcon->stat_lock);
++		tcon->bytes_written += bytes;
++		spin_unlock(&tcon->stat_lock);
++	}
++}
++
++static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon,
++					 unsigned int bytes)
++{
++	spin_lock(&tcon->stat_lock);
++	tcon->bytes_read += bytes;
++	spin_unlock(&tcon->stat_lock);
++}
++#else
++
++#define  cifs_stats_inc(field) do {} while(0)
++#define  cifs_stats_bytes_written(tcon, bytes) do {} while(0)
++#define  cifs_stats_bytes_read(tcon, bytes) do {} while(0)
++
++#endif
+ 
+ /* one of these for every pending CIFS request to the server */
+ struct mid_q_entry {
+@@ -313,7 +378,11 @@ struct mid_q_entry {
+ 	__u16 mid;		/* multiplex id */
+ 	__u16 pid;		/* process id */
+ 	__u32 sequence_number;  /* for CIFS signing */
+-	struct timeval when_sent;	/* time when smb sent */
++	unsigned long when_alloc;  /* when mid was created */
++#ifdef CONFIG_CIFS_STATS2
++	unsigned long when_sent; /* time when smb send finished */
++	unsigned long when_received; /* when demux complete (taken off wire) */
++#endif
+ 	struct cifsSesInfo *ses;	/* smb was sent to this server */
+ 	struct task_struct *tsk;	/* task waiting for response */
+ 	struct smb_hdr *resp_buf;	/* response buffer */
+@@ -331,6 +400,20 @@ struct oplock_q_entry {
+ 	__u16 netfid;
+ };
+ 
++/* for pending dnotify requests */
++struct dir_notify_req {
++       struct list_head lhead;
++       __le16 Pid;
++       __le16 PidHigh;
++       __u16 Mid;
++       __u16 Tid;
++       __u16 Uid;
++       __u16 netfid;
++       __u32 filter; /* CompletionFilter (for multishot) */
++       int multishot;
++       struct file * pfile;
++};
++
+ #define   MID_FREE 0
+ #define   MID_REQUEST_ALLOCATED 1
+ #define   MID_REQUEST_SUBMITTED 2
+@@ -399,6 +482,9 @@ GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;
+ 
+ GLOBAL_EXTERN struct list_head GlobalOplock_Q;
+ 
++GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */
++GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; /* Dir notify response queue */
++
+ /*
+  * Global transaction id (XID) information
+  */
+diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
+--- a/fs/cifs/cifspdu.h
++++ b/fs/cifs/cifspdu.h
+@@ -36,9 +36,11 @@
+ #define SMB_COM_CLOSE                 0x04 /* triv req/rsp, timestamp ignored */
+ #define SMB_COM_DELETE                0x06 /* trivial response */
+ #define SMB_COM_RENAME                0x07 /* trivial response */
++#define SMB_COM_QUERY_INFORMATION     0x08 /* aka getattr */
+ #define SMB_COM_SETATTR               0x09 /* trivial response */
+ #define SMB_COM_LOCKING_ANDX          0x24 /* trivial response */
+ #define SMB_COM_COPY                  0x29 /* trivial rsp, fail filename ignrd*/
++#define SMB_COM_OPEN_ANDX             0x2D /* Legacy open for old servers */
+ #define SMB_COM_READ_ANDX             0x2E
+ #define SMB_COM_WRITE_ANDX            0x2F
+ #define SMB_COM_TRANSACTION2          0x32
+@@ -52,6 +54,7 @@
+ #define SMB_COM_NT_TRANSACT           0xA0
+ #define SMB_COM_NT_TRANSACT_SECONDARY 0xA1
+ #define SMB_COM_NT_CREATE_ANDX        0xA2
++#define SMB_COM_NT_CANCEL             0xA4 /* no response */
+ #define SMB_COM_NT_RENAME             0xA5 /* trivial response */
+ 
+ /* Transact2 subcommand codes */
+@@ -59,6 +62,7 @@
+ #define TRANS2_FIND_FIRST             0x01
+ #define TRANS2_FIND_NEXT              0x02
+ #define TRANS2_QUERY_FS_INFORMATION   0x03
++#define TRANS2_SET_FS_INFORMATION     0x04
+ #define TRANS2_QUERY_PATH_INFORMATION 0x05
+ #define TRANS2_SET_PATH_INFORMATION   0x06
+ #define TRANS2_QUERY_FILE_INFORMATION 0x07
+@@ -76,7 +80,7 @@
+ #define NT_TRANSACT_GET_USER_QUOTA    0x07
+ #define NT_TRANSACT_SET_USER_QUOTA    0x08
+ 
+-#define MAX_CIFS_HDR_SIZE 256	/* chained NTCreateXReadX will probably be biggest */
++#define MAX_CIFS_HDR_SIZE 256	/* is future chained NTCreateXReadX bigger? */
+ 
+ /* internal cifs vfs structures */
+ /*****************************************************************
+@@ -129,10 +133,11 @@
+ /*
+  * SMB flag definitions 
+  */
+-#define SMBFLG_EXTD_LOCK 0x01	/* server supports lock-read write-unlock primitives */
++#define SMBFLG_EXTD_LOCK 0x01	/* server supports lock-read write-unlock smb */
+ #define SMBFLG_RCV_POSTED 0x02	/* obsolete */
+ #define SMBFLG_RSVD 0x04
+-#define SMBFLG_CASELESS 0x08	/* all pathnames treated as caseless (off implies case sensitive file handling requested) */
++#define SMBFLG_CASELESS 0x08	/* all pathnames treated as caseless (off
++				implies case sensitive file handling request) */
+ #define SMBFLG_CANONICAL_PATH_FORMAT 0x10	/* obsolete */
+ #define SMBFLG_OLD_OPLOCK 0x20	/* obsolete */
+ #define SMBFLG_OLD_OPLOCK_NOTIFY 0x40	/* obsolete */
+@@ -141,7 +146,8 @@
+ /*
+  * SMB flag2 definitions 
+  */
+-#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1)	/* can send long (non-8.3) path names in response */
++#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1)	/* can send long (non-8.3) 
++						   path names in response */
+ #define SMBFLG2_KNOWS_EAS cpu_to_le16(2)
+ #define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4)
+ #define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40)
+@@ -160,32 +166,32 @@
+  * file and can have any suitable combination of the following values:
+  */
+ 
+-#define FILE_READ_DATA        0x00000001	/* Data can be read from the file   */
+-#define FILE_WRITE_DATA       0x00000002	/* Data can be written to the file  */
+-#define FILE_APPEND_DATA      0x00000004	/* Data can be appended to the file */
+-#define FILE_READ_EA          0x00000008	/* Extended attributes associated   */
+-					 /* with the file can be read        */
+-#define FILE_WRITE_EA         0x00000010	/* Extended attributes associated   */
+-					 /* with the file can be written     */
+-#define FILE_EXECUTE          0x00000020	/*Data can be read into memory from */
+-					 /* the file using system paging I/O */
++#define FILE_READ_DATA        0x00000001  /* Data can be read from the file   */
++#define FILE_WRITE_DATA       0x00000002  /* Data can be written to the file  */
++#define FILE_APPEND_DATA      0x00000004  /* Data can be appended to the file */
++#define FILE_READ_EA          0x00000008  /* Extended attributes associated   */
++					  /* with the file can be read        */
++#define FILE_WRITE_EA         0x00000010  /* Extended attributes associated   */
++					  /* with the file can be written     */
++#define FILE_EXECUTE          0x00000020  /*Data can be read into memory from */
++					  /* the file using system paging I/O */
+ #define FILE_DELETE_CHILD     0x00000040
+-#define FILE_READ_ATTRIBUTES  0x00000080	/* Attributes associated with the   */
+-					 /* file can be read                 */
+-#define FILE_WRITE_ATTRIBUTES 0x00000100	/* Attributes associated with the   */
+-					 /* file can be written              */
+-#define DELETE                0x00010000	/* The file can be deleted          */
+-#define READ_CONTROL          0x00020000	/* The access control list and      */
+-					 /* ownership associated with the    */
+-					 /* file can be read                 */
+-#define WRITE_DAC             0x00040000	/* The access control list and      */
+-					 /* ownership associated with the    */
+-					 /* file can be written.             */
+-#define WRITE_OWNER           0x00080000	/* Ownership information associated */
+-					 /* with the file can be written     */
+-#define SYNCHRONIZE           0x00100000	/* The file handle can waited on to */
+-					 /* synchronize with the completion  */
+-					 /* of an input/output request       */
++#define FILE_READ_ATTRIBUTES  0x00000080  /* Attributes associated with the   */
++					  /* file can be read                 */
++#define FILE_WRITE_ATTRIBUTES 0x00000100  /* Attributes associated with the   */
++					  /* file can be written              */
++#define DELETE                0x00010000  /* The file can be deleted          */
++#define READ_CONTROL          0x00020000  /* The access control list and      */
++					  /* ownership associated with the    */
++					  /* file can be read                 */
++#define WRITE_DAC             0x00040000  /* The access control list and      */
++					  /* ownership associated with the    */
++					  /* file can be written.             */
++#define WRITE_OWNER           0x00080000  /* Ownership information associated */
++					  /* with the file can be written     */
++#define SYNCHRONIZE           0x00100000  /* The file handle can waited on to */
++					  /* synchronize with the completion  */
++					  /* of an input/output request       */
+ #define GENERIC_ALL           0x10000000
+ #define GENERIC_EXECUTE       0x20000000
+ #define GENERIC_WRITE         0x40000000
+@@ -193,7 +199,7 @@
+ 					 /* In summary - Relevant file       */
+ 					 /* access flags from CIFS are       */
+ 					 /* file_read_data, file_write_data  */
+-					 /* file_execute, file_read_attributes */
++					 /* file_execute, file_read_attributes*/
+ 					 /* write_dac, and delete.           */
+ 
+ /*
+@@ -238,7 +244,8 @@
+ #define ATTR_SPARSE    0x0200
+ #define ATTR_REPARSE   0x0400
+ #define ATTR_COMPRESSED 0x0800
+-#define ATTR_OFFLINE    0x1000	/* ie file not immediately available - offline storage */
++#define ATTR_OFFLINE    0x1000	/* ie file not immediately available - 
++					on offline storage */
+ #define ATTR_NOT_CONTENT_INDEXED 0x2000
+ #define ATTR_ENCRYPTED  0x4000
+ #define ATTR_POSIX_SEMANTICS 0x01000000
+@@ -267,10 +274,18 @@
+ /* CreateOptions */
+ #define CREATE_NOT_FILE		0x00000001	/* if set must not be file */
+ #define CREATE_WRITE_THROUGH	0x00000002
+-#define CREATE_NOT_DIR		0x00000040	/* if set must not be directory */
++#define CREATE_SEQUENTIAL       0x00000004
++#define CREATE_SYNC_ALERT       0x00000010
++#define CREATE_ASYNC_ALERT      0x00000020
++#define CREATE_NOT_DIR		0x00000040    /* if set must not be directory */
++#define CREATE_NO_EA_KNOWLEDGE  0x00000200
++#define CREATE_EIGHT_DOT_THREE  0x00000400
+ #define CREATE_RANDOM_ACCESS	0x00000800
+ #define CREATE_DELETE_ON_CLOSE	0x00001000
++#define CREATE_OPEN_BY_ID       0x00002000
+ #define OPEN_REPARSE_POINT	0x00200000
++#define CREATE_OPTIONS_MASK     0x007FFFFF 
++#define CREATE_OPTION_SPECIAL   0x20000000   /* system. NB not sent over wire */
+ 
+ /* ImpersonationLevel flags */
+ #define SECURITY_ANONYMOUS      0
+@@ -297,10 +312,10 @@
+ #define GETU16(var)  (*((__u16 *)var))	/* BB check for endian issues */
+ #define GETU32(var)  (*((__u32 *)var))	/* BB check for endian issues */
+ 
+-#pragma pack(1)
+-
+ struct smb_hdr {
+-	__u32 smb_buf_length;	/* big endian on wire *//* BB length is only two or three bytes - with one or two byte type preceding it but that is always zero - we could mask the type byte off just in case BB */
++	__u32 smb_buf_length;	/* big endian on wire *//* BB length is only two
++		or three bytes - with one or two byte type preceding it that are
++		zero - we could mask the type byte off just in case BB */
+ 	__u8 Protocol[4];
+ 	__u8 Command;
+ 	union {
+@@ -308,9 +323,9 @@ struct smb_hdr {
+ 			__u8 ErrorClass;
+ 			__u8 Reserved;
+ 			__le16 Error;
+-		} DosError;
++		} __attribute__((packed)) DosError;
+ 		__le32 CifsError;
+-	} Status;
++	} __attribute__((packed)) Status;
+ 	__u8 Flags;
+ 	__le16 Flags2;		/* note: le */
+ 	__le16 PidHigh;
+@@ -318,16 +333,16 @@ struct smb_hdr {
+ 		struct {
+ 			__le32 SequenceNumber;  /* le */
+ 			__u32 Reserved; /* zero */
+-		} Sequence;
++		} __attribute__((packed)) Sequence;
+ 		__u8 SecuritySignature[8];	/* le */
+-	} Signature;
++	} __attribute__((packed)) Signature;
+ 	__u8 pad[2];
+ 	__u16 Tid;
+ 	__le16 Pid;
+ 	__u16 Uid;
+ 	__u16 Mid;
+ 	__u8 WordCount;
+-};
++} __attribute__((packed));
+ /* given a pointer to an smb_hdr retrieve the value of byte count */
+ #define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
+ #define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
+@@ -379,7 +394,7 @@ typedef struct negotiate_req {
+ 	struct smb_hdr hdr;	/* wct = 0 */
+ 	__le16 ByteCount;
+ 	unsigned char DialectsArray[1];
+-} NEGOTIATE_REQ;
++} __attribute__((packed)) NEGOTIATE_REQ;
+ 
+ typedef struct negotiate_rsp {
+ 	struct smb_hdr hdr;	/* wct = 17 */
+@@ -397,16 +412,16 @@ typedef struct negotiate_rsp {
+ 	__u8 EncryptionKeyLength;
+ 	__u16 ByteCount;
+ 	union {
+-		unsigned char EncryptionKey[1];	/* if cap extended security is off */
++		unsigned char EncryptionKey[1];	/* cap extended security off */
+ 		/* followed by Domain name - if extended security is off */
+ 		/* followed by 16 bytes of server GUID */
+-		/* followed by security blob if cap_extended_security negotiated */
++		/* then security blob if cap_extended_security negotiated */
+ 		struct {
+ 			unsigned char GUID[16];
+ 			unsigned char SecurityBlob[1];
+-		} extended_response;
+-	} u;
+-} NEGOTIATE_RSP;
++		} __attribute__((packed)) extended_response;
++	} __attribute__((packed)) u;
++} __attribute__((packed)) NEGOTIATE_RSP;
+ 
+ /* SecurityMode bits */
+ #define SECMODE_USER          0x01	/* off indicates share level security */
+@@ -452,7 +467,8 @@ typedef union smb_com_session_setup_andx
+ 		unsigned char SecurityBlob[1];	/* followed by */
+ 		/* STRING NativeOS */
+ 		/* STRING NativeLanMan */
+-	} req;			/* NTLM request format (with extended security */
++	} __attribute__((packed)) req;	/* NTLM request format (with 
++					extended security */
+ 
+ 	struct {		/* request format */
+ 		struct smb_hdr hdr;	/* wct = 13 */
+@@ -463,18 +479,19 @@ typedef union smb_com_session_setup_andx
+ 		__le16 MaxMpxCount;
+ 		__le16 VcNumber;
+ 		__u32 SessionKey;
+-		__le16 CaseInsensitivePasswordLength;	/* ASCII password length */
+-		__le16 CaseSensitivePasswordLength;	/* Unicode password length */
++		__le16 CaseInsensitivePasswordLength; /* ASCII password len */
++		__le16 CaseSensitivePasswordLength; /* Unicode password length*/
+ 		__u32 Reserved;	/* see below */
+ 		__le32 Capabilities;
+ 		__le16 ByteCount;
+-		unsigned char CaseInsensitivePassword[1];	/* followed by: */
++		unsigned char CaseInsensitivePassword[1];     /* followed by: */
+ 		/* unsigned char * CaseSensitivePassword; */
+ 		/* STRING AccountName */
+ 		/* STRING PrimaryDomain */
+ 		/* STRING NativeOS */
+ 		/* STRING NativeLanMan */
+-	} req_no_secext;	/* NTLM request format (without extended security */
++	} __attribute__((packed)) req_no_secext; /* NTLM request format (without
++							extended security */
+ 
+ 	struct {		/* default (NTLM) response format */
+ 		struct smb_hdr hdr;	/* wct = 4 */
+@@ -488,7 +505,7 @@ typedef union smb_com_session_setup_andx
+ /*      unsigned char  * NativeOS;      */
+ /*	unsigned char  * NativeLanMan;  */
+ /*      unsigned char  * PrimaryDomain; */
+-	} resp;			/* NTLM response format (with or without extended security */
++	} __attribute__((packed)) resp;			/* NTLM response format (with or without extended security */
+ 
+ 	struct {		/* request format */
+ 		struct smb_hdr hdr;	/* wct = 10 */
+@@ -507,7 +524,7 @@ typedef union smb_com_session_setup_andx
+ 		/* STRING PrimaryDomain */
+ 		/* STRING NativeOS */
+ 		/* STRING NativeLanMan */
+-	} old_req;		/* pre-NTLM (LANMAN2.1) request format */
++	} __attribute__((packed)) old_req;		/* pre-NTLM (LANMAN2.1) request format */
+ 
+ 	struct {		/* default (NTLM) response format */
+ 		struct smb_hdr hdr;	/* wct = 3 */
+@@ -519,8 +536,8 @@ typedef union smb_com_session_setup_andx
+ 		unsigned char NativeOS[1];	/* followed by */
+ /*	unsigned char * NativeLanMan; */
+ /*      unsigned char * PrimaryDomain; */
+-	} old_resp;		/* pre-NTLM (LANMAN2.1) response format */
+-} SESSION_SETUP_ANDX;
++	} __attribute__((packed)) old_resp;		/* pre-NTLM (LANMAN2.1) response format */
++} __attribute__((packed)) SESSION_SETUP_ANDX;
+ 
+ #define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux"
+ 
+@@ -530,7 +547,8 @@ typedef union smb_com_session_setup_andx
+ #define CAP_NT_SMBS            0x00000010
+ #define CAP_STATUS32           0x00000040
+ #define CAP_LEVEL_II_OPLOCKS   0x00000080
+-#define CAP_NT_FIND            0x00000200	/* reserved should be zero (presumably because NT_SMBs implies the same thing) */
++#define CAP_NT_FIND            0x00000200	/* reserved should be zero 
++				(because NT_SMBs implies the same thing?) */
+ #define CAP_BULK_TRANSFER      0x20000000
+ #define CAP_EXTENDED_SECURITY  0x80000000
+ 
+@@ -548,7 +566,7 @@ typedef struct smb_com_tconx_req {
+ 	unsigned char Password[1];	/* followed by */
+ /* STRING Path    *//* \\server\share name */
+ 	/* STRING Service */
+-} TCONX_REQ;
++} __attribute__((packed)) TCONX_REQ;
+ 
+ typedef struct smb_com_tconx_rsp {
+ 	struct smb_hdr hdr;	/* wct = 3 *//* note that Win2000 has sent wct=7 in some cases on responses. Four unspecified words followed OptionalSupport */
+@@ -559,13 +577,14 @@ typedef struct smb_com_tconx_rsp {
+ 	__u16 ByteCount;
+ 	unsigned char Service[1];	/* always ASCII, not Unicode */
+ 	/* STRING NativeFileSystem */
+-} TCONX_RSP;
++} __attribute__((packed)) TCONX_RSP;
+ 
+ /* tree connect Flags */
+ #define DISCONNECT_TID          0x0001
+ #define TCON_EXTENDED_SECINFO   0x0008
+ /* OptionalSupport bits */
+-#define SMB_SUPPORT_SEARCH_BITS 0x0001	/* must have bits (exclusive searches suppt. */
++#define SMB_SUPPORT_SEARCH_BITS 0x0001	/* "must have" directory search bits
++					 (exclusive searches supported) */
+ #define SMB_SHARE_IS_IN_DFS     0x0002
+ 
+ typedef struct smb_com_logoff_andx_req {
+@@ -574,7 +593,7 @@ typedef struct smb_com_logoff_andx_req {
+ 	__u8 AndXReserved;
+ 	__u16 AndXOffset;
+ 	__u16 ByteCount;
+-} LOGOFF_ANDX_REQ;
++} __attribute__((packed)) LOGOFF_ANDX_REQ;
+ 
+ typedef struct smb_com_logoff_andx_rsp {
+ 	struct smb_hdr hdr;	/* wct = 2 */
+@@ -582,38 +601,39 @@ typedef struct smb_com_logoff_andx_rsp {
+ 	__u8 AndXReserved;
+ 	__u16 AndXOffset;
+ 	__u16 ByteCount;
+-} LOGOFF_ANDX_RSP;
++} __attribute__((packed)) LOGOFF_ANDX_RSP;
+ 
+ typedef union smb_com_tree_disconnect {	/* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */
+ 	struct {
+ 		struct smb_hdr hdr;	/* wct = 0 */
+ 		__u16 ByteCount;	/* bcc = 0 */
+-	} req;
++	} __attribute__((packed)) req;
+ 	struct {
+ 		struct smb_hdr hdr;	/* wct = 0 */
+ 		__u16 ByteCount;	/* bcc = 0 */
+-	} resp;
+-} TREE_DISCONNECT;
++	} __attribute__((packed)) resp;
++} __attribute__((packed)) TREE_DISCONNECT;
+ 
+ typedef struct smb_com_close_req {
+ 	struct smb_hdr hdr;	/* wct = 3 */
+ 	__u16 FileID;
+ 	__u32 LastWriteTime;	/* should be zero */
+ 	__u16 ByteCount;	/* 0 */
+-} CLOSE_REQ;
++} __attribute__((packed)) CLOSE_REQ;
+ 
+ typedef struct smb_com_close_rsp {
+ 	struct smb_hdr hdr;	/* wct = 0 */
+ 	__u16 ByteCount;	/* bct = 0 */
+-} CLOSE_RSP;
++} __attribute__((packed)) CLOSE_RSP;
+ 
+ typedef struct smb_com_findclose_req {
+ 	struct smb_hdr hdr; /* wct = 1 */
+ 	__u16 FileID;
+ 	__u16 ByteCount;    /* 0 */
+-} FINDCLOSE_REQ;
++} __attribute__((packed)) FINDCLOSE_REQ;
+ 
+ /* OpenFlags */
++#define REQ_MORE_INFO      0x00000001  /* legacy (OPEN_AND_X) only */
+ #define REQ_OPLOCK         0x00000002
+ #define REQ_BATCHOPLOCK    0x00000004
+ #define REQ_OPENDIRONLY    0x00000008
+@@ -637,7 +657,7 @@ typedef struct smb_com_open_req {	/* als
+ 	__u8 SecurityFlags;
+ 	__le16 ByteCount;
+ 	char fileName[1];
+-} OPEN_REQ;
++} __attribute__((packed)) OPEN_REQ;
+ 
+ /* open response: oplock levels */
+ #define OPLOCK_NONE  	 0
+@@ -667,7 +687,63 @@ typedef struct smb_com_open_rsp {
+ 	__le16 DeviceState;
+ 	__u8 DirectoryFlag;
+ 	__u16 ByteCount;	/* bct = 0 */
+-} OPEN_RSP;
++} __attribute__((packed)) OPEN_RSP;
++
++/* format of legacy open request */
++typedef struct smb_com_openx_req {
++	struct smb_hdr	hdr;	/* wct = 15 */
++	__u8 AndXCommand;
++	__u8 AndXReserved;
++	__le16 AndXOffset;
++	__le16 OpenFlags;
++	__le16 Mode;
++	__le16 Sattr; /* search attributes */
++	__le16 FileAttributes;  /* dos attrs */
++	__le32 CreateTime; /* os2 format */
++	__le16 OpenFunction;
++	__le32 EndOfFile;
++	__le32 Timeout;
++	__le32 Reserved;
++	__le16  ByteCount;  /* file name follows */
++	char   fileName[1];
++} __attribute__((packed)) OPENX_REQ;
++
++typedef struct smb_com_openx_rsp {
++	struct smb_hdr	hdr;	/* wct = 15 */
++	__u8 AndXCommand;
++	__u8 AndXReserved;
++	__le16 AndXOffset;
++	__u16  Fid;
++	__le16 FileAttributes;
++	__le32 LastWriteTime; /* os2 format */
++	__le32 EndOfFile;
++	__le16 Access;
++	__le16 FileType;
++	__le16 IPCState;
++	__le16 Action;
++	__u32  FileId;
++	__u16  Reserved;
++	__u16  ByteCount;
++} __attribute__((packed)) OPENX_RSP; 
++
++/* Legacy write request for older servers */
++typedef struct smb_com_writex_req {
++        struct smb_hdr hdr;     /* wct = 12 */
++        __u8 AndXCommand;
++        __u8 AndXReserved;
++        __le16 AndXOffset;
++        __u16 Fid;
++        __le32 OffsetLow;
++        __u32 Reserved; /* Timeout */
++        __le16 WriteMode; /* 1 = write through */
++        __le16 Remaining;
++        __le16 Reserved2;
++        __le16 DataLengthLow;
++        __le16 DataOffset;
++        __le16 ByteCount;
++        __u8 Pad;               /* BB check for whether padded to DWORD boundary and optimum performance here */
++        char Data[0];
++} __attribute__((packed)) WRITEX_REQ;
+ 
+ typedef struct smb_com_write_req {
+ 	struct smb_hdr hdr;	/* wct = 14 */
+@@ -686,7 +762,7 @@ typedef struct smb_com_write_req {
+ 	__le16 ByteCount;
+ 	__u8 Pad;		/* BB check for whether padded to DWORD boundary and optimum performance here */
+ 	char Data[0];
+-} WRITE_REQ;
++} __attribute__((packed)) WRITE_REQ;
+ 
+ typedef struct smb_com_write_rsp {
+ 	struct smb_hdr hdr;	/* wct = 6 */
+@@ -698,7 +774,22 @@ typedef struct smb_com_write_rsp {
+ 	__le16 CountHigh;
+ 	__u16  Reserved;
+ 	__u16 ByteCount;
+-} WRITE_RSP;
++} __attribute__((packed)) WRITE_RSP;
++
++/* legacy read request for older servers */
++typedef struct smb_com_readx_req {
++        struct smb_hdr hdr;     /* wct = 10 */
++        __u8 AndXCommand;
++        __u8 AndXReserved;
++        __le16 AndXOffset;
++        __u16 Fid;
++        __le32 OffsetLow;
++        __le16 MaxCount;
++        __le16 MinCount;                /* obsolete */
++        __le32 Reserved;
++        __le16 Remaining;
++        __le16 ByteCount;
++} __attribute__((packed)) READX_REQ;
+ 
+ typedef struct smb_com_read_req {
+ 	struct smb_hdr hdr;	/* wct = 12 */
+@@ -713,7 +804,7 @@ typedef struct smb_com_read_req {
+ 	__le16 Remaining;
+ 	__le32 OffsetHigh;
+ 	__le16 ByteCount;
+-} READ_REQ;
++} __attribute__((packed)) READ_REQ;
+ 
+ typedef struct smb_com_read_rsp {
+ 	struct smb_hdr hdr;	/* wct = 12 */
+@@ -730,7 +821,7 @@ typedef struct smb_com_read_rsp {
+ 	__u16 ByteCount;
+ 	__u8 Pad;		/* BB check for whether padded to DWORD boundary and optimum performance here */
+ 	char Data[1];
+-} READ_RSP;
++} __attribute__((packed)) READ_RSP;
+ 
+ typedef struct locking_andx_range {
+ 	__le16 Pid;
+@@ -739,7 +830,7 @@ typedef struct locking_andx_range {
+ 	__le32 OffsetLow;
+ 	__le32 LengthHigh;
+ 	__le32 LengthLow;
+-} LOCKING_ANDX_RANGE;
++} __attribute__((packed)) LOCKING_ANDX_RANGE;
+ 
+ #define LOCKING_ANDX_SHARED_LOCK     0x01
+ #define LOCKING_ANDX_OPLOCK_RELEASE  0x02
+@@ -760,7 +851,7 @@ typedef struct smb_com_lock_req {
+ 	__le16 NumberOfLocks;
+ 	__le16 ByteCount;
+ 	LOCKING_ANDX_RANGE Locks[1];
+-} LOCK_REQ;
++} __attribute__((packed)) LOCK_REQ;
+ 
+ 
+ typedef struct cifs_posix_lock {
+@@ -770,7 +861,7 @@ typedef struct cifs_posix_lock {
+ 	__le64	start;
+ 	__le64	length;
+ 	/* BB what about additional owner info to identify network client */
+-} CIFS_POSIX_LOCK;
++} __attribute__((packed)) CIFS_POSIX_LOCK;
+ 
+ typedef struct smb_com_lock_rsp {
+ 	struct smb_hdr hdr;	/* wct = 2 */
+@@ -778,7 +869,7 @@ typedef struct smb_com_lock_rsp {
+ 	__u8 AndXReserved;
+ 	__le16 AndXOffset;
+ 	__u16 ByteCount;
+-} LOCK_RSP;
++} __attribute__((packed)) LOCK_RSP;
+ 
+ typedef struct smb_com_rename_req {
+ 	struct smb_hdr hdr;	/* wct = 1 */
+@@ -788,7 +879,7 @@ typedef struct smb_com_rename_req {
+ 	unsigned char OldFileName[1];
+ 	/* followed by __u8 BufferFormat2 */
+ 	/* followed by NewFileName */
+-} RENAME_REQ;
++} __attribute__((packed)) RENAME_REQ;
+ 
+ 	/* copy request flags */
+ #define COPY_MUST_BE_FILE      0x0001
+@@ -808,7 +899,7 @@ typedef struct smb_com_copy_req {
+ 	unsigned char OldFileName[1];
+ 	/* followed by __u8 BufferFormat2 */
+ 	/* followed by NewFileName string */
+-} COPY_REQ;
++} __attribute__((packed)) COPY_REQ;
+ 
+ typedef struct smb_com_copy_rsp {
+ 	struct smb_hdr hdr;     /* wct = 1 */
+@@ -816,7 +907,7 @@ typedef struct smb_com_copy_rsp {
+ 	__u16 ByteCount;    /* may be zero */
+ 	__u8 BufferFormat;  /* 0x04 - only present if errored file follows */
+ 	unsigned char ErrorFileName[1]; /* only present if error in copy */
+-} COPY_RSP;
++} __attribute__((packed)) COPY_RSP;
+ 
+ #define CREATE_HARD_LINK		0x103
+ #define MOVEFILE_COPY_ALLOWED		0x0002
+@@ -832,12 +923,12 @@ typedef struct smb_com_nt_rename_req {	/
+ 	unsigned char OldFileName[1];
+ 	/* followed by __u8 BufferFormat2 */
+ 	/* followed by NewFileName */
+-} NT_RENAME_REQ;
++} __attribute__((packed)) NT_RENAME_REQ;
+ 
+ typedef struct smb_com_rename_rsp {
+ 	struct smb_hdr hdr;	/* wct = 0 */
+ 	__u16 ByteCount;	/* bct = 0 */
+-} RENAME_RSP;
++} __attribute__((packed)) RENAME_RSP;
+ 
+ typedef struct smb_com_delete_file_req {
+ 	struct smb_hdr hdr;	/* wct = 1 */
+@@ -845,36 +936,52 @@ typedef struct smb_com_delete_file_req {
+ 	__le16 ByteCount;
+ 	__u8 BufferFormat;	/* 4 = ASCII */
+ 	unsigned char fileName[1];
+-} DELETE_FILE_REQ;
++} __attribute__((packed)) DELETE_FILE_REQ;
+ 
+ typedef struct smb_com_delete_file_rsp {
+ 	struct smb_hdr hdr;	/* wct = 0 */
+ 	__u16 ByteCount;	/* bct = 0 */
+-} DELETE_FILE_RSP;
++} __attribute__((packed)) DELETE_FILE_RSP;
+ 
+ typedef struct smb_com_delete_directory_req {
+ 	struct smb_hdr hdr;	/* wct = 0 */
+ 	__le16 ByteCount;
+ 	__u8 BufferFormat;	/* 4 = ASCII */
+ 	unsigned char DirName[1];
+-} DELETE_DIRECTORY_REQ;
++} __attribute__((packed)) DELETE_DIRECTORY_REQ;
+ 
+ typedef struct smb_com_delete_directory_rsp {
+ 	struct smb_hdr hdr;	/* wct = 0 */
+ 	__u16 ByteCount;	/* bct = 0 */
+-} DELETE_DIRECTORY_RSP;
++} __attribute__((packed)) DELETE_DIRECTORY_RSP;
+ 
+ typedef struct smb_com_create_directory_req {
+ 	struct smb_hdr hdr;	/* wct = 0 */
+ 	__le16 ByteCount;
+ 	__u8 BufferFormat;	/* 4 = ASCII */
+ 	unsigned char DirName[1];
+-} CREATE_DIRECTORY_REQ;
++} __attribute__((packed)) CREATE_DIRECTORY_REQ;
+ 
+ typedef struct smb_com_create_directory_rsp {
+ 	struct smb_hdr hdr;	/* wct = 0 */
+ 	__u16 ByteCount;	/* bct = 0 */
+-} CREATE_DIRECTORY_RSP;
++} __attribute__((packed)) CREATE_DIRECTORY_RSP;
++
++typedef struct smb_com_query_information_req {
++	struct smb_hdr hdr;     /* wct = 0 */
++	__le16 ByteCount;	/* 1 + namelen + 1 */
++	__u8 BufferFormat;      /* 4 = ASCII */
++	unsigned char FileName[1];
++} __attribute__((packed)) QUERY_INFORMATION_REQ;
++
++typedef struct smb_com_query_information_rsp {
++	struct smb_hdr hdr;     /* wct = 10 */
++	__le16 attr;
++	__le32  last_write_time;
++	__le32 size;
++	__u16  reserved[5];
++	__le16 ByteCount;	/* bcc = 0 */
++} __attribute__((packed)) QUERY_INFORMATION_RSP;
+ 
+ typedef struct smb_com_setattr_req {
+ 	struct smb_hdr hdr; /* wct = 8 */
+@@ -885,12 +992,12 @@ typedef struct smb_com_setattr_req {
+ 	__u16  ByteCount;
+ 	__u8   BufferFormat; /* 4 = ASCII */
+ 	unsigned char fileName[1];
+-} SETATTR_REQ;
++} __attribute__((packed)) SETATTR_REQ;
+ 
+ typedef struct smb_com_setattr_rsp {
+ 	struct smb_hdr hdr;     /* wct = 0 */
+ 	__u16 ByteCount;        /* bct = 0 */
+-} SETATTR_RSP;
++} __attribute__((packed)) SETATTR_RSP;
+ 
+ /* empty wct response to setattr */
+ 
+@@ -920,7 +1027,7 @@ typedef struct smb_com_transaction_ioctl
+ 	__le16 ByteCount;
+ 	__u8 Pad[3];
+ 	__u8 Data[1];
+-} TRANSACT_IOCTL_REQ;
++} __attribute__((packed)) TRANSACT_IOCTL_REQ;
+ 
+ typedef struct smb_com_transaction_ioctl_rsp {
+ 	struct smb_hdr hdr;	/* wct = 19 */
+@@ -937,7 +1044,7 @@ typedef struct smb_com_transaction_ioctl
+ 	__le16 ReturnedDataLen;
+ 	__u16 ByteCount;
+ 	__u8 Pad[3];
+-} TRANSACT_IOCTL_RSP;
++} __attribute__((packed)) TRANSACT_IOCTL_RSP;
+ 
+ typedef struct smb_com_transaction_change_notify_req {
+ 	struct smb_hdr hdr;     /* wct = 23 */
+@@ -961,7 +1068,7 @@ typedef struct smb_com_transaction_chang
+ 	__le16 ByteCount;
+ /* __u8 Pad[3];*/
+ /*	__u8 Data[1];*/
+-} TRANSACT_CHANGE_NOTIFY_REQ;
++} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ;
+ 
+ typedef struct smb_com_transaction_change_notify_rsp {
+ 	struct smb_hdr hdr;	/* wct = 18 */
+@@ -977,7 +1084,7 @@ typedef struct smb_com_transaction_chang
+ 	__u8 SetupCount;   /* 0 */
+ 	__u16 ByteCount;
+ 	/* __u8 Pad[3]; */
+-} TRANSACT_CHANGE_NOTIFY_RSP;
++} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_RSP;
+ /* Completion Filter flags for Notify */
+ #define FILE_NOTIFY_CHANGE_FILE_NAME    0x00000001
+ #define FILE_NOTIFY_CHANGE_DIR_NAME     0x00000002
+@@ -1008,7 +1115,7 @@ struct file_notify_information {
+ 	__le32 Action;
+ 	__le32 FileNameLength;
+ 	__u8  FileName[0];
+-}; 
++} __attribute__((packed)); 
+ 
+ struct reparse_data {
+ 	__u32	ReparseTag;
+@@ -1019,7 +1126,7 @@ struct reparse_data {
+ 	__u16	TargetNameOffset;
+ 	__u16	TargetNameLen;
+ 	char	LinkNamesBuf[1];
+-};
++} __attribute__((packed));
+ 
+ struct cifs_quota_data {
+ 	__u32	rsrvd1;  /* 0 */
+@@ -1029,7 +1136,7 @@ struct cifs_quota_data {
+ 	__u64	soft_limit;
+ 	__u64	hard_limit;
+ 	char	sid[1];  /* variable size? */
+-};
++} __attribute__((packed));
+ 
+ /* quota sub commands */
+ #define QUOTA_LIST_CONTINUE	    0
+@@ -1055,12 +1162,12 @@ struct trans2_req {
+ 	__u8 Reserved3;
+ 	__le16 SubCommand; /* 1st setup word - SetupCount words follow */
+ 	__le16 ByteCount;
+-};
++} __attribute__((packed));
+ 
+ struct smb_t2_req {
+ 	struct smb_hdr hdr;
+ 	struct trans2_req t2_req;
+-};
++} __attribute__((packed));
+ 
+ struct trans2_resp {
+ 	/* struct smb_hdr hdr precedes. Note wct = 10 + setup count */
+@@ -1079,12 +1186,12 @@ struct trans2_resp {
+ 	__u16 ByteCount;
+ 	__u16 Reserved2;*/	
+ 	/* data area follows */
+-};
++} __attribute__((packed));
+ 
+ struct smb_t2_rsp {
+ 	struct smb_hdr hdr;
+ 	struct trans2_resp t2_rsp;
+-};
++} __attribute__((packed));
+ 
+ /* PathInfo/FileInfo infolevels */
+ #define SMB_INFO_STANDARD                   1
+@@ -1171,14 +1278,14 @@ typedef struct smb_com_transaction2_qpi_
+ 	__le16 InformationLevel;
+ 	__u32 Reserved4;
+ 	char FileName[1];
+-} TRANSACTION2_QPI_REQ;
++} __attribute__((packed)) TRANSACTION2_QPI_REQ;
+ 
+ typedef struct smb_com_transaction2_qpi_rsp {
+ 	struct smb_hdr hdr;	/* wct = 10 + SetupCount */
+ 	struct trans2_resp t2;
+ 	__u16 ByteCount;
+ 	__u16 Reserved2;	/* parameter word reserved - present for infolevels > 100 */
+-} TRANSACTION2_QPI_RSP;
++} __attribute__((packed)) TRANSACTION2_QPI_RSP;
+ 
+ typedef struct smb_com_transaction2_spi_req {
+ 	struct smb_hdr hdr;	/* wct = 15 */
+@@ -1204,21 +1311,21 @@ typedef struct smb_com_transaction2_spi_
+ 	__le16 InformationLevel;
+ 	__u32 Reserved4;
+ 	char FileName[1];
+-} TRANSACTION2_SPI_REQ;
++} __attribute__((packed)) TRANSACTION2_SPI_REQ;
+ 
+ typedef struct smb_com_transaction2_spi_rsp {
+ 	struct smb_hdr hdr;	/* wct = 10 + SetupCount */
+ 	struct trans2_resp t2;
+ 	__u16 ByteCount;
+ 	__u16 Reserved2;	/* parameter word reserved - present for infolevels > 100 */
+-} TRANSACTION2_SPI_RSP;
++} __attribute__((packed)) TRANSACTION2_SPI_RSP;
+ 
+ struct set_file_rename {
+ 	__le32 overwrite;   /* 1 = overwrite dest */
+ 	__u32 root_fid;   /* zero */
+ 	__le32 target_name_len;
+ 	char  target_name[0];  /* Must be unicode */
+-};
++} __attribute__((packed));
+ 
+ struct smb_com_transaction2_sfi_req {
+ 	struct smb_hdr hdr;	/* wct = 15 */
+@@ -1244,7 +1351,7 @@ struct smb_com_transaction2_sfi_req {
+ 	__u16 Fid;
+ 	__le16 InformationLevel;
+ 	__u16 Reserved4;	
+-};
++} __attribute__((packed));
+ 
+ struct smb_com_transaction2_sfi_rsp {
+ 	struct smb_hdr hdr;	/* wct = 10 + SetupCount */
+@@ -1252,7 +1359,7 @@ struct smb_com_transaction2_sfi_rsp {
+ 	__u16 ByteCount;
+ 	__u16 Reserved2;	/* parameter word reserved - 
+ 					present for infolevels > 100 */
+-};
++} __attribute__((packed));
+ 
+ struct smb_t2_qfi_req {
+         struct	smb_hdr hdr;
+@@ -1260,7 +1367,7 @@ struct smb_t2_qfi_req {
+ 	__u8	Pad;
+ 	__u16	Fid;
+ 	__le16	InformationLevel;
+-};
++} __attribute__((packed));
+ 
+ struct smb_t2_qfi_rsp {
+         struct smb_hdr hdr;     /* wct = 10 + SetupCount */
+@@ -1268,7 +1375,7 @@ struct smb_t2_qfi_rsp {
+         __u16 ByteCount;
+         __u16 Reserved2;        /* parameter word reserved - 
+ 					present for infolevels > 100 */
+-};
++} __attribute__((packed));
+ 
+ /*
+  * Flags on T2 FINDFIRST and FINDNEXT 
+@@ -1310,13 +1417,13 @@ typedef struct smb_com_transaction2_ffir
+ 	__le16 InformationLevel;
+ 	__le32 SearchStorageType;
+ 	char FileName[1];
+-} TRANSACTION2_FFIRST_REQ;
++} __attribute__((packed)) TRANSACTION2_FFIRST_REQ;
+ 
+ typedef struct smb_com_transaction2_ffirst_rsp {
+ 	struct smb_hdr hdr;	/* wct = 10 */
+ 	struct trans2_resp t2;
+ 	__u16 ByteCount;
+-} TRANSACTION2_FFIRST_RSP;
++} __attribute__((packed)) TRANSACTION2_FFIRST_RSP;
+ 
+ typedef struct smb_com_transaction2_ffirst_rsp_parms {
+ 	__u16 SearchHandle;
+@@ -1324,7 +1431,7 @@ typedef struct smb_com_transaction2_ffir
+ 	__le16 EndofSearch;
+ 	__le16 EAErrorOffset;
+ 	__le16 LastNameOffset;
+-} T2_FFIRST_RSP_PARMS;
++} __attribute__((packed)) T2_FFIRST_RSP_PARMS;
+ 
+ typedef struct smb_com_transaction2_fnext_req {
+ 	struct smb_hdr hdr;	/* wct = 15 */
+@@ -1352,20 +1459,20 @@ typedef struct smb_com_transaction2_fnex
+ 	__u32 ResumeKey;
+ 	__le16 SearchFlags;
+ 	char ResumeFileName[1];
+-} TRANSACTION2_FNEXT_REQ;
++} __attribute__((packed)) TRANSACTION2_FNEXT_REQ;
+ 
+ typedef struct smb_com_transaction2_fnext_rsp {
+ 	struct smb_hdr hdr;	/* wct = 10 */
+ 	struct trans2_resp t2;
+ 	__u16 ByteCount;
+-} TRANSACTION2_FNEXT_RSP;
++} __attribute__((packed)) TRANSACTION2_FNEXT_RSP;
+ 
+ typedef struct smb_com_transaction2_fnext_rsp_parms {
+ 	__le16 SearchCount;
+ 	__le16 EndofSearch;
+ 	__le16 EAErrorOffset;
+ 	__le16 LastNameOffset;
+-} T2_FNEXT_RSP_PARMS;
++} __attribute__((packed)) T2_FNEXT_RSP_PARMS;
+ 
+ /* QFSInfo Levels */
+ #define SMB_INFO_ALLOCATION         1
+@@ -1402,14 +1509,51 @@ typedef struct smb_com_transaction2_qfsi
+ 	__le16 ByteCount;
+ 	__u8 Pad;
+ 	__le16 InformationLevel;
+-} TRANSACTION2_QFSI_REQ;
++} __attribute__((packed)) TRANSACTION2_QFSI_REQ;
+ 
+ typedef struct smb_com_transaction_qfsi_rsp {
+ 	struct smb_hdr hdr;	/* wct = 10 + SetupCount */
+ 	struct trans2_resp t2;
+ 	__u16 ByteCount;
+ 	__u8 Pad;		/* may be three bytes *//* followed by data area */
+-} TRANSACTION2_QFSI_RSP;
++} __attribute__((packed)) TRANSACTION2_QFSI_RSP;
++
++
++/* SETFSInfo Levels */
++#define SMB_SET_CIFS_UNIX_INFO    0x200
++typedef struct smb_com_transaction2_setfsi_req {
++	struct smb_hdr hdr;	/* wct = 15 */
++	__le16 TotalParameterCount;
++	__le16 TotalDataCount;
++	__le16 MaxParameterCount;
++	__le16 MaxDataCount;
++	__u8 MaxSetupCount;
++	__u8 Reserved;
++	__le16 Flags;
++	__le32 Timeout;
++	__u16 Reserved2;
++	__le16 ParameterCount;	/* 4 */
++	__le16 ParameterOffset;
++	__le16 DataCount;	/* 12 */
++	__le16 DataOffset;
++	__u8 SetupCount;	/* one */
++	__u8 Reserved3;
++	__le16 SubCommand;	/* TRANS2_SET_FS_INFORMATION */
++	__le16 ByteCount;
++	__u8 Pad;
++	__u16 FileNum;		/* Parameters start. */
++	__le16 InformationLevel;/* Parameters end. */
++	__le16 ClientUnixMajor; /* Data start. */
++	__le16 ClientUnixMinor;
++	__le64 ClientUnixCap;   /* Data end */
++} __attribute__((packed)) TRANSACTION2_SETFSI_REQ;
++
++typedef struct smb_com_transaction2_setfsi_rsp {
++	struct smb_hdr hdr;	/* wct = 10 */
++	struct trans2_resp t2;
++	__u16 ByteCount;
++} __attribute__((packed)) TRANSACTION2_SETFSI_RSP;
++
+ 
+ typedef struct smb_com_transaction2_get_dfs_refer_req {
+ 	struct smb_hdr hdr;	/* wct = 15 */
+@@ -1433,7 +1577,7 @@ typedef struct smb_com_transaction2_get_
+ 	__u8 Pad[3];		/* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */
+ 	__le16 MaxReferralLevel;
+ 	char RequestFileName[1];
+-} TRANSACTION2_GET_DFS_REFER_REQ;
++} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ;
+ 
+ typedef struct dfs_referral_level_3 {
+ 	__le16 VersionNumber;
+@@ -1445,7 +1589,7 @@ typedef struct dfs_referral_level_3 {
+ 	__le16 DfsPathOffset;
+ 	__le16 DfsAlternatePathOffset;
+ 	__le16 NetworkAddressOffset;
+-} REFERRAL3;
++} __attribute__((packed)) REFERRAL3;
+ 
+ typedef struct smb_com_transaction_get_dfs_refer_rsp {
+ 	struct smb_hdr hdr;	/* wct = 10 */
+@@ -1458,7 +1602,7 @@ typedef struct smb_com_transaction_get_d
+ 	__u16 Pad2;
+ 	REFERRAL3 referrals[1];	/* array of level 3 dfs_referral structures */
+ 	/* followed by the strings pointed to by the referral structures */
+-} TRANSACTION2_GET_DFS_REFER_RSP;
++} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_RSP;
+ 
+ /* DFS Flags */
+ #define DFSREF_REFERRAL_SERVER  0x0001
+@@ -1512,7 +1656,7 @@ struct serverInfo {
+ 	unsigned char versionMinor;
+ 	unsigned long type;
+ 	unsigned int commentOffset;
+-};
++} __attribute__((packed));
+ 
+ /*
+  * The following structure is the format of the data returned on a NetShareEnum
+@@ -1524,39 +1668,55 @@ struct shareInfo {
+ 	char pad;
+ 	unsigned short type;
+ 	unsigned int commentOffset;
+-};
++} __attribute__((packed));
+ 
+ struct aliasInfo {
+ 	char aliasName[9];
+ 	char pad;
+ 	unsigned int commentOffset;
+ 	unsigned char type[2];
+-};
++} __attribute__((packed));
+ 
+ struct aliasInfo92 {
+ 	int aliasNameOffset;
+ 	int serverNameOffset;
+ 	int shareNameOffset;
+-};
++} __attribute__((packed));
+ 
+ typedef struct {
+ 	__le64 TotalAllocationUnits;
+ 	__le64 FreeAllocationUnits;
+ 	__le32 SectorsPerAllocationUnit;
+ 	__le32 BytesPerSector;
+-} FILE_SYSTEM_INFO;		/* size info, level 0x103 */
++} __attribute__((packed)) FILE_SYSTEM_INFO;		/* size info, level 0x103 */
++
++typedef struct {
++	__le32 fsid;
++	__le32 SectorsPerAllocationUnit;
++	__le32 TotalAllocationUnits;
++	__le32 FreeAllocationUnits;
++	__le16  BytesPerSector;
++} __attribute__((packed)) FILE_SYSTEM_ALLOC_INFO;
+ 
+ typedef struct {
+ 	__le16 MajorVersionNumber;
+ 	__le16 MinorVersionNumber;
+ 	__le64 Capability;
+-} FILE_SYSTEM_UNIX_INFO;	/* Unix extensions info, level 0x200 */
++} __attribute__((packed)) FILE_SYSTEM_UNIX_INFO;	/* Unix extensions info, level 0x200 */
++
++/* Version numbers for CIFS UNIX major and minor. */
++#define CIFS_UNIX_MAJOR_VERSION 1
++#define CIFS_UNIX_MINOR_VERSION 0
++
+ /* Linux/Unix extensions capability flags */
+ #define CIFS_UNIX_FCNTL_CAP             0x00000001 /* support for fcntl locks */
+ #define CIFS_UNIX_POSIX_ACL_CAP         0x00000002 /* support getfacl/setfacl */
+ #define CIFS_UNIX_XATTR_CAP             0x00000004 /* support new namespace   */
+ #define CIFS_UNIX_EXTATTR_CAP           0x00000008 /* support chattr/chflag   */
++#define CIFS_UNIX_POSIX_PATHNAMES_CAP   0x00000010 /* Use POSIX pathnames on the wire. */
++
+ #define CIFS_POSIX_EXTENSIONS           0x00000010 /* support for new QFSInfo */
++
+ typedef struct {
+ 	/* For undefined recommended transfer size return -1 in that field */
+ 	__le32 OptimalTransferSize;  /* bsize on some os, iosize on other os */
+@@ -1577,7 +1737,7 @@ typedef struct {
+ 	__le64 FileSysIdentifier;   /* fsid */
+ 	/* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */
+ 	/* NB flags can come from FILE_SYSTEM_DEVICE_INFO call   */
+-} FILE_SYSTEM_POSIX_INFO;
++} __attribute__((packed)) FILE_SYSTEM_POSIX_INFO;
+ 
+ /* DeviceType Flags */
+ #define FILE_DEVICE_CD_ROM              0x00000002
+@@ -1602,14 +1762,14 @@ typedef struct {
+ typedef struct {
+ 	__le32 DeviceType;
+ 	__le32 DeviceCharacteristics;
+-} FILE_SYSTEM_DEVICE_INFO;	/* device info, level 0x104 */
++} __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO;	/* device info, level 0x104 */
+ 
+ typedef struct {
+ 	__le32 Attributes;
+ 	__le32 MaxPathNameComponentLength;
+ 	__le32 FileSystemNameLen;
+ 	char FileSystemName[52]; /* do not really need to save this - so potentially get only subset of name */
+-} FILE_SYSTEM_ATTRIBUTE_INFO;
++} __attribute__((packed)) FILE_SYSTEM_ATTRIBUTE_INFO;
+ 
+ /******************************************************************************/
+ /* QueryFileInfo/QueryPathinfo (also for SetPath/SetFile) data buffer formats */
+@@ -1636,7 +1796,7 @@ typedef struct { /* data block encoding 
+ 	__le32 AlignmentRequirement;
+ 	__le32 FileNameLength;
+ 	char FileName[1];
+-} FILE_ALL_INFO;		/* level 0x107 QPathInfo */
++} __attribute__((packed)) FILE_ALL_INFO;		/* level 0x107 QPathInfo */
+ 
+ /* defines for enumerating possible values of the Unix type field below */
+ #define UNIX_FILE      0
+@@ -1660,11 +1820,11 @@ typedef struct {
+ 	__u64 UniqueId;
+ 	__le64 Permissions;
+ 	__le64 Nlinks;
+-} FILE_UNIX_BASIC_INFO;		/* level 0x200 QPathInfo */
++} __attribute__((packed)) FILE_UNIX_BASIC_INFO;		/* level 0x200 QPathInfo */
+ 
+ typedef struct {
+ 	char LinkDest[1];
+-} FILE_UNIX_LINK_INFO;		/* level 0x201 QPathInfo */
++} __attribute__((packed)) FILE_UNIX_LINK_INFO;		/* level 0x201 QPathInfo */
+ 
+ /* The following three structures are needed only for
+ 	setting time to NT4 and some older servers via
+@@ -1673,13 +1833,13 @@ typedef struct {
+ 	__u16 Day:5;
+ 	__u16 Month:4;
+ 	__u16 Year:7;
+-} SMB_DATE;
++} __attribute__((packed)) SMB_DATE;
+ 
+ typedef struct {
+ 	__u16 TwoSeconds:5;
+ 	__u16 Minutes:6;
+ 	__u16 Hours:5;
+-} SMB_TIME;
++} __attribute__((packed)) SMB_TIME;
+ 
+ typedef struct {
+ 	__le16 CreationDate; /* SMB Date see above */
+@@ -1692,7 +1852,7 @@ typedef struct {
+ 	__le32 AllocationSize;
+ 	__le16 Attributes; /* verify not u32 */
+ 	__le32 EASize;
+-} FILE_INFO_STANDARD;  /* level 1 SetPath/FileInfo */
++} __attribute__((packed)) FILE_INFO_STANDARD;  /* level 1 SetPath/FileInfo */
+ 
+ typedef struct {
+ 	__le64 CreationTime;
+@@ -1701,19 +1861,19 @@ typedef struct {
+ 	__le64 ChangeTime;
+ 	__le32 Attributes;
+ 	__u32 Pad;
+-} FILE_BASIC_INFO;		/* size info, level 0x101 */
++} __attribute__((packed)) FILE_BASIC_INFO;		/* size info, level 0x101 */
+ 
+ struct file_allocation_info {
+ 	__le64 AllocationSize; /* Note old Samba srvr rounds this up too much */
+-};	/* size used on disk, level 0x103 for set, 0x105 for query */
++} __attribute__((packed));	/* size used on disk, level 0x103 for set, 0x105 for query */
+ 
+ struct file_end_of_file_info {
+ 	__le64 FileSize;		/* offset to end of file */
+-};	/* size info, level 0x104 for set, 0x106 for query */
++} __attribute__((packed));	/* size info, level 0x104 for set, 0x106 for query */
+ 
+ struct file_alt_name_info {
+ 	__u8   alt_name[1];
+-};      /* level 0x0108 */
++} __attribute__((packed));      /* level 0x0108 */
+ 
+ struct file_stream_info {
+ 	__le32 number_of_streams;  /* BB check sizes and verify location */
+@@ -1730,7 +1890,7 @@ struct file_compression_info {
+ 	__u8   ch_shift;
+ 	__u8   cl_shift;
+ 	__u8   pad[3];
+-};      /* level 0x10b */
++} __attribute__((packed));      /* level 0x10b */
+ 
+ /* POSIX ACL set/query path info structures */
+ #define CIFS_ACL_VERSION 1
+@@ -1738,7 +1898,7 @@ struct cifs_posix_ace { /* access contro
+ 	__u8  cifs_e_tag;
+ 	__u8  cifs_e_perm;
+ 	__le64 cifs_uid; /* or gid */
+-}; 
++} __attribute__((packed)); 
+ 
+ struct cifs_posix_acl { /* access conrol list  (ACL) */
+ 	__le16	version;
+@@ -1747,7 +1907,7 @@ struct cifs_posix_acl { /* access conrol
+ 	struct cifs_posix_ace ace_array[0];
+ 	/* followed by
+ 	struct cifs_posix_ace default_ace_arraay[] */
+-};  /* level 0x204 */
++} __attribute__((packed));  /* level 0x204 */
+ 
+ /* types of access control entries already defined in posix_acl.h */
+ /* #define CIFS_POSIX_ACL_USER_OBJ	 0x01
+@@ -1766,15 +1926,15 @@ struct cifs_posix_acl { /* access conrol
+ 
+ struct file_internal_info {
+ 	__u64  UniqueId; /* inode number */
+-};      /* level 0x3ee */
++} __attribute__((packed));      /* level 0x3ee */
+ struct file_mode_info {
+ 	__le32	Mode;
+-};      /* level 0x3f8 */
++} __attribute__((packed));      /* level 0x3f8 */
+ 
+ struct file_attrib_tag {
+ 	__le32 Attribute;
+ 	__le32 ReparseTag;
+-};      /* level 0x40b */
++} __attribute__((packed));      /* level 0x40b */
+ 
+ 
+ /********************************************************/
+@@ -1798,7 +1958,7 @@ typedef struct {
+ 	__le64 Permissions;
+ 	__le64 Nlinks;
+ 	char FileName[1];
+-} FILE_UNIX_INFO; /* level 0x202 */
++} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */
+ 
+ typedef struct {
+ 	__le32 NextEntryOffset;
+@@ -1812,7 +1972,7 @@ typedef struct {
+ 	__le32 ExtFileAttributes;
+ 	__le32 FileNameLength;
+ 	char FileName[1];
+-} FILE_DIRECTORY_INFO;   /* level 0x101 FF response data area */
++} __attribute__((packed)) FILE_DIRECTORY_INFO;   /* level 0x101 FF response data area */
+ 
+ typedef struct {
+ 	__le32 NextEntryOffset;
+@@ -1827,7 +1987,7 @@ typedef struct {
+ 	__le32 FileNameLength;
+ 	__le32 EaSize; /* length of the xattrs */
+ 	char FileName[1];
+-} FILE_FULL_DIRECTORY_INFO;   /* level 0x102 FF response data area */
++} __attribute__((packed)) FILE_FULL_DIRECTORY_INFO;   /* level 0x102 FF response data area */
+ 
+ typedef struct {
+ 	__le32 NextEntryOffset;
+@@ -1844,7 +2004,7 @@ typedef struct {
+ 	__le32 Reserved;
+ 	__u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/
+ 	char FileName[1];
+-} SEARCH_ID_FULL_DIR_INFO;   /* level 0x105 FF response data area */
++} __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO;   /* level 0x105 FF response data area */
+ 
+ typedef struct {
+ 	__le32 NextEntryOffset;
+@@ -1862,18 +2022,18 @@ typedef struct {
+ 	__u8   Reserved;
+ 	__u8   ShortName[12];
+ 	char FileName[1];
+-} FILE_BOTH_DIRECTORY_INFO;   /* level 0x104 FF response data area */
++} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO;   /* level 0x104 FF response data area */
+ 
+ 
+ struct gea {
+ 	unsigned char name_len;
+ 	char name[1];
+-};
++} __attribute__((packed));
+ 
+ struct gealist {
+ 	unsigned long list_len;
+ 	struct gea list[1];
+-};
++} __attribute__((packed));
+ 
+ struct fea {
+ 	unsigned char EA_flags;
+@@ -1881,21 +2041,21 @@ struct fea {
+ 	__le16 value_len;
+ 	char name[1];
+ 	/* optionally followed by value */
+-};
++} __attribute__((packed));
+ /* flags for _FEA.fEA */
+ #define FEA_NEEDEA         0x80	/* need EA bit */
+ 
+ struct fealist {
+ 	__le32 list_len;
+ 	struct fea list[1];
+-};
++} __attribute__((packed));
+ 
+ /* used to hold an arbitrary blob of data */
+ struct data_blob {
+ 	__u8 *data;
+ 	size_t length;
+ 	void (*free) (struct data_blob * data_blob);
+-};
++} __attribute__((packed));
+ 
+ 
+ #ifdef CONFIG_CIFS_POSIX
+@@ -1907,18 +2067,17 @@ struct data_blob {
+ 	perhaps add a CreateDevice - to create Pipes and other special .inodes
+ 	Also note POSIX open flags
+ 	2) Close - to return the last write time to do cache across close more safely
+-	3) PosixQFSInfo - to return statfs info
+-	4) FindFirst return unique inode number - what about resume key, two forms short (matches readdir) and full (enough info to cache inodes)
+-	5) Mkdir - set mode
++	3) FindFirst return unique inode number - what about resume key, two 
++	forms short (matches readdir) and full (enough info to cache inodes)
++	4) Mkdir - set mode
+ 	
+ 	And under consideration: 
+-	6) FindClose2 (return nanosecond timestamp ??)
+-	7) Use nanosecond timestamps throughout all time fields if 
++	5) FindClose2 (return nanosecond timestamp ??)
++	6) Use nanosecond timestamps throughout all time fields if 
+ 	   corresponding attribute flag is set
+-	8) sendfile - handle based copy
+-	9) Direct i/o
+-	10) "POSIX ACL" support
+-	11) Misc fcntls?
++	7) sendfile - handle based copy
++	8) Direct i/o
++	9) Misc fcntls?
+ 	
+ 	what about fixing 64 bit alignment
+ 	
+@@ -1974,7 +2133,7 @@ struct data_blob {
+ 	
+  */
+ 
+-/* xsymlink is a symlink format that can be used
++/* xsymlink is a symlink format (used by MacOS) that can be used
+    to save symlink info in a regular file when 
+    mounted to operating systems that do not
+    support the cifs Unix extensions or EAs (for xattr
+@@ -1999,7 +2158,7 @@ struct xsymlink {
+ 	char cr2;        /* \n */
+ /* if room left, then end with \n then 0x20s by convention but not required */
+ 	char path[1024];  
+-};
++} __attribute__((packed));
+ 
+ typedef struct file_xattr_info {
+ 	/* BB do we need another field for flags? BB */
+@@ -2007,7 +2166,7 @@ typedef struct file_xattr_info {
+ 	__u32 xattr_value_len;
+ 	char  xattr_name[0];
+ 	/* followed by xattr_value[xattr_value_len], no pad */
+-} FILE_XATTR_INFO;	/* extended attribute, info level 0x205 */
++} __attribute__((packed)) FILE_XATTR_INFO;	/* extended attribute, info level 0x205 */
+ 
+ 
+ /* flags for chattr command */
+@@ -2033,10 +2192,8 @@ typedef struct file_xattr_info {
+ typedef struct file_chattr_info {
+ 	__le64	mask; /* list of all possible attribute bits */
+ 	__le64	mode; /* list of actual attribute bits on this inode */
+-} FILE_CHATTR_INFO;  /* ext attributes (chattr, chflags) level 0x206 */
++} __attribute__((packed)) FILE_CHATTR_INFO;  /* ext attributes (chattr, chflags) level 0x206 */
+ 
+ #endif 
+ 
+-#pragma pack()			/* resume default structure packing */
+-
+ #endif				/* _CIFSPDU_H */
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -47,19 +47,24 @@ extern int SendReceive(const unsigned in
+ 			struct smb_hdr * /* input */ ,
+ 			struct smb_hdr * /* out */ ,
+ 			int * /* bytes returned */ , const int long_op);
++extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
++			struct kvec *, int /* nvec */,
++			int * /* bytes returned */ , const int long_op);
+ extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
+ extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
+ extern int is_valid_oplock_break(struct smb_hdr *smb);
+ extern int is_size_safe_to_change(struct cifsInodeInfo *);
++extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
+ extern unsigned int smbCalcSize(struct smb_hdr *ptr);
++extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
+ extern int decode_negTokenInit(unsigned char *security_blob, int length,
+ 			enum securityEnum *secType);
+ extern int cifs_inet_pton(int, char * source, void *dst);
+ extern int map_smb_to_linux_error(struct smb_hdr *smb);
+ extern void header_assemble(struct smb_hdr *, char /* command */ ,
+-			const struct cifsTconInfo *, int /* specifies length
+-			    of fixed section (word count) in two byte units */
+-			);
++			    const struct cifsTconInfo *, int /* length of
++			    fixed section (word count) in two byte units */);
++extern __u16 GetNextMid(struct TCP_Server_Info *server);
+ extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 
+ 						 struct cifsTconInfo *);
+ extern void DeleteOplockQEntry(struct oplock_q_entry *);
+@@ -89,7 +94,7 @@ extern int CIFSTCon(unsigned int xid, st
+ 
+ extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
+             const char *searchName, const struct nls_table *nls_codepage,
+-            __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map);
++            __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map, const char dirsep);
+ 
+ extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
+             __u16 searchHandle, struct cifs_search_info * psrch_inf);
+@@ -101,6 +106,10 @@ extern int CIFSSMBQPathInfo(const int xi
+ 			const unsigned char *searchName,
+ 			FILE_ALL_INFO * findData,
+ 			const struct nls_table *nls_codepage, int remap);
++extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
++                        const unsigned char *searchName,
++                        FILE_ALL_INFO * findData,
++                        const struct nls_table *nls_codepage, int remap);
+ 
+ extern int CIFSSMBUnixQPathInfo(const int xid,
+ 			struct cifsTconInfo *tcon,
+@@ -125,6 +134,11 @@ extern int get_dfs_path(int xid, struct 
+ 			int remap);
+ extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
+ 			struct kstatfs *FSData);
++extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon,
++			struct kstatfs *FSData);
++extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
++			__u64 cap);
++
+ extern int CIFSSMBQFSAttributeInfo(const int xid,
+ 			struct cifsTconInfo *tcon);
+ extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon);
+@@ -207,6 +221,11 @@ extern int CIFSSMBOpen(const int xid, st
+ 			const int access_flags, const int omode,
+ 			__u16 * netfid, int *pOplock, FILE_ALL_INFO *,
+ 			const struct nls_table *nls_codepage, int remap);
++extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
++			const char *fileName, const int disposition,
++			const int access_flags, const int omode,
++			__u16 * netfid, int *pOplock, FILE_ALL_INFO *,
++			const struct nls_table *nls_codepage, int remap);
+ extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
+ 			const int smb_file_id);
+ 
+@@ -222,7 +241,7 @@ extern int CIFSSMBWrite(const int xid, s
+ extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
+ 			const int netfid, const unsigned int count,
+ 			const __u64 offset, unsigned int *nbytes, 
+-			const char __user *buf,const int long_op);
++			struct kvec *iov, const int nvec, const int long_op);
+ extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
+ 			const unsigned char *searchName, __u64 * inode_number,
+ 			const struct nls_table *nls_codepage, 
+@@ -264,7 +283,8 @@ extern int CIFSSMBCopy(int xid,
+ 			int remap_special_chars);
+ extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 
+ 			const int notify_subdirs,const __u16 netfid,
+-			__u32 filter, const struct nls_table *nls_codepage);
++			__u32 filter, struct file * file, int multishot, 
++			const struct nls_table *nls_codepage);
+ extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
+ 			const unsigned char *searchName, char * EAData,
+ 			size_t bufsize, const struct nls_table *nls_codepage,
+diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -125,6 +125,9 @@ small_smb_init(int smb_command, int wct,
+ 				rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon
+ 					, nls_codepage);
+ 				up(&tcon->ses->sesSem);
++				/* BB FIXME add code to check if wsize needs
++				   update due to negotiated smb buffer size
++				   shrinking */
+ 				if(rc == 0)
+ 					atomic_inc(&tconInfoReconnectCount);
+ 
+@@ -166,11 +169,9 @@ small_smb_init(int smb_command, int wct,
+ 
+ 	header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct);
+ 
+-#ifdef CONFIG_CIFS_STATS
+-        if(tcon != NULL) {
+-                atomic_inc(&tcon->num_smbs_sent);
+-        }
+-#endif /* CONFIG_CIFS_STATS */
++        if(tcon != NULL)
++                cifs_stats_inc(&tcon->num_smbs_sent);
++
+ 	return rc;
+ }  
+ 
+@@ -222,6 +223,9 @@ smb_init(int smb_command, int wct, struc
+ 				rc = CIFSTCon(0, tcon->ses, tcon->treeName,
+ 					      tcon, nls_codepage);
+ 				up(&tcon->ses->sesSem);
++				/* BB FIXME add code to check if wsize needs
++				update due to negotiated smb buffer size
++				shrinking */
+ 				if(rc == 0)
+ 					atomic_inc(&tconInfoReconnectCount);
+ 
+@@ -269,11 +273,9 @@ smb_init(int smb_command, int wct, struc
+ 	header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
+ 			wct /*wct */ );
+ 
+-#ifdef CONFIG_CIFS_STATS
+-        if(tcon != NULL) {
+-                atomic_inc(&tcon->num_smbs_sent);
+-        }
+-#endif /* CONFIG_CIFS_STATS */
++        if(tcon != NULL)
++                cifs_stats_inc(&tcon->num_smbs_sent);
++
+ 	return rc;
+ }
+ 
+@@ -330,7 +332,7 @@ CIFSSMBNegotiate(unsigned int xid, struc
+ 		      (void **) &pSMB, (void **) &pSMBr);
+ 	if (rc)
+ 		return rc;
+-
++	pSMB->hdr.Mid = GetNextMid(server);
+ 	pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
+ 	if (extended_security)
+ 		pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+@@ -422,8 +424,8 @@ CIFSSMBNegotiate(unsigned int xid, struc
+ 		}
+ 				
+ 	}
+-	if (pSMB)
+-		cifs_buf_release(pSMB);
++	
++	cifs_buf_release(pSMB);
+ 	return rc;
+ }
+ 
+@@ -518,6 +520,8 @@ CIFSSMBLogoff(const int xid, struct cifs
+ 	smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
+ 	
+ 	if(ses->server) {
++		pSMB->hdr.Mid = GetNextMid(ses->server);
++
+ 		if(ses->server->secMode & 
+ 		   (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+ 			pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+@@ -537,9 +541,8 @@ CIFSSMBLogoff(const int xid, struct cifs
+ 			rc = -ESHUTDOWN;
+ 		}
+ 	}
+-	if (pSMB)
+-		cifs_small_buf_release(pSMB);
+ 	up(&ses->sesSem);
++	cifs_small_buf_release(pSMB);
+ 
+ 	/* if session dead then we do not need to do ulogoff,
+ 		since server closed smb session, no sense reporting 
+@@ -583,14 +586,10 @@ DelFileRetry:
+ 	pSMB->ByteCount = cpu_to_le16(name_len + 1);
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_deletes);
+ 	if (rc) {
+ 		cFYI(1, ("Error in RMFile = %d", rc));
+ 	} 
+-#ifdef CONFIG_CIFS_STATS
+-        else {
+-		atomic_inc(&tcon->num_deletes);
+-        }
+-#endif
+ 
+ 	cifs_buf_release(pSMB);
+ 	if (rc == -EAGAIN)
+@@ -632,14 +631,10 @@ RmDirRetry:
+ 	pSMB->ByteCount = cpu_to_le16(name_len + 1);
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_rmdirs);
+ 	if (rc) {
+ 		cFYI(1, ("Error in RMDir = %d", rc));
+ 	}
+-#ifdef CONFIG_CIFS_STATS
+-        else {
+-		atomic_inc(&tcon->num_rmdirs);
+-        }
+-#endif
+ 
+ 	cifs_buf_release(pSMB);
+ 	if (rc == -EAGAIN)
+@@ -680,20 +675,161 @@ MkDirRetry:
+ 	pSMB->ByteCount = cpu_to_le16(name_len + 1);
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_mkdirs);
+ 	if (rc) {
+ 		cFYI(1, ("Error in Mkdir = %d", rc));
+ 	}
+-#ifdef CONFIG_CIFS_STATS
+-        else {
+-		atomic_inc(&tcon->num_mkdirs);
+-        }
+-#endif
++
+ 	cifs_buf_release(pSMB);
+ 	if (rc == -EAGAIN)
+ 		goto MkDirRetry;
+ 	return rc;
+ }
+ 
++static __u16 convert_disposition(int disposition)
++{
++	__u16 ofun = 0;
++
++	switch (disposition) {
++		case FILE_SUPERSEDE:
++			ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
++			break;
++		case FILE_OPEN:
++			ofun = SMBOPEN_OAPPEND;
++			break;
++		case FILE_CREATE:
++			ofun = SMBOPEN_OCREATE;
++			break;
++		case FILE_OPEN_IF:
++			ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
++			break;
++		case FILE_OVERWRITE:
++			ofun = SMBOPEN_OTRUNC;
++			break;
++		case FILE_OVERWRITE_IF:
++			ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
++			break;
++		default:
++			cFYI(1,("unknown disposition %d",disposition));
++			ofun =  SMBOPEN_OAPPEND; /* regular open */
++	}
++	return ofun;
++}
++
++int
++SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
++	    const char *fileName, const int openDisposition,
++	    const int access_flags, const int create_options, __u16 * netfid,
++            int *pOplock, FILE_ALL_INFO * pfile_info,
++	    const struct nls_table *nls_codepage, int remap)
++{
++	int rc = -EACCES;
++	OPENX_REQ *pSMB = NULL;
++	OPENX_RSP *pSMBr = NULL;
++	int bytes_returned;
++	int name_len;
++	__u16 count;
++
++OldOpenRetry:
++	rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
++		      (void **) &pSMBr);
++	if (rc)
++		return rc;
++
++	pSMB->AndXCommand = 0xFF;       /* none */
++
++	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
++		count = 1;      /* account for one byte pad to word boundary */
++		name_len =
++		   cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
++				    fileName, PATH_MAX, nls_codepage, remap);
++		name_len++;     /* trailing null */
++		name_len *= 2;
++	} else {                /* BB improve check for buffer overruns BB */
++		count = 0;      /* no pad */
++		name_len = strnlen(fileName, PATH_MAX);
++		name_len++;     /* trailing null */
++		strncpy(pSMB->fileName, fileName, name_len);
++	}
++	if (*pOplock & REQ_OPLOCK)
++		pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
++	else if (*pOplock & REQ_BATCHOPLOCK) {
++		pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
++	}
++	pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
++	/* BB fixme add conversion for access_flags to bits 0 - 2 of mode */
++	/* 0 = read
++	   1 = write
++	   2 = rw
++	   3 = execute
++        */
++	pSMB->Mode = cpu_to_le16(2);
++	pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
++	/* set file as system file if special file such
++	   as fifo and server expecting SFU style and
++	   no Unix extensions */
++
++        if(create_options & CREATE_OPTION_SPECIAL)
++                pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
++        else
++                pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */
++
++	/* if ((omode & S_IWUGO) == 0)
++		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
++	/*  Above line causes problems due to vfs splitting create into two
++	    pieces - need to set mode after file created not while it is
++	    being created */
++
++	/* BB FIXME BB */
++/*	pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */
++	/* BB FIXME END BB */
++
++	pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
++	pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
++	count += name_len;
++	pSMB->hdr.smb_buf_length += count;
++
++	pSMB->ByteCount = cpu_to_le16(count);
++	/* long_op set to 1 to allow for oplock break timeouts */
++	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
++		         (struct smb_hdr *) pSMBr, &bytes_returned, 1);
++	cifs_stats_inc(&tcon->num_opens);
++	if (rc) {
++		cFYI(1, ("Error in Open = %d", rc));
++	} else {
++	/* BB verify if wct == 15 */
++
++/*		*pOplock = pSMBr->OplockLevel; */  /* BB take from action field BB */
++
++		*netfid = pSMBr->Fid;   /* cifs fid stays in le */
++		/* Let caller know file was created so we can set the mode. */
++		/* Do we care about the CreateAction in any other cases? */
++	/* BB FIXME BB */
++/*		if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
++			*pOplock |= CIFS_CREATE_ACTION; */
++	/* BB FIXME END */
++
++		if(pfile_info) {
++			pfile_info->CreationTime = 0; /* BB convert CreateTime*/
++			pfile_info->LastAccessTime = 0; /* BB fixme */
++			pfile_info->LastWriteTime = 0; /* BB fixme */
++			pfile_info->ChangeTime = 0;  /* BB fixme */
++			pfile_info->Attributes =
++				cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes)); 
++			/* the file_info buf is endian converted by caller */
++			pfile_info->AllocationSize =
++				cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
++			pfile_info->EndOfFile = pfile_info->AllocationSize;
++			pfile_info->NumberOfLinks = cpu_to_le32(1);
++		}
++	}
++
++	cifs_buf_release(pSMB);
++	if (rc == -EAGAIN)
++		goto OldOpenRetry;
++	return rc;
++}
++
+ int
+ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
+ 	    const char *fileName, const int openDisposition,
+@@ -738,7 +874,13 @@ openRetry:
+ 	}
+ 	pSMB->DesiredAccess = cpu_to_le32(access_flags);
+ 	pSMB->AllocationSize = 0;
+-	pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
++	/* set file as system file if special file such
++	   as fifo and server expecting SFU style and
++	   no Unix extensions */
++	if(create_options & CREATE_OPTION_SPECIAL)
++		pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
++	else
++		pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
+ 	/* XP does not handle ATTR_POSIX_SEMANTICS */
+ 	/* but it helps speed up case sensitive checks for other
+ 	servers such as Samba */
+@@ -752,7 +894,7 @@ openRetry:
+ 		being created */
+ 	pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
+ 	pSMB->CreateDisposition = cpu_to_le32(openDisposition);
+-	pSMB->CreateOptions = cpu_to_le32(create_options);
++	pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
+ 	/* BB Expirement with various impersonation levels and verify */
+ 	pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
+ 	pSMB->SecurityFlags =
+@@ -765,6 +907,7 @@ openRetry:
+ 	/* long_op set to 1 to allow for oplock break timeouts */
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 1);
++	cifs_stats_inc(&tcon->num_opens);
+ 	if (rc) {
+ 		cFYI(1, ("Error in Open = %d", rc));
+ 	} else {
+@@ -782,11 +925,8 @@ openRetry:
+ 		    pfile_info->EndOfFile = pSMBr->EndOfFile;
+ 		    pfile_info->NumberOfLinks = cpu_to_le32(1);
+ 		}
+-
+-#ifdef CONFIG_CIFS_STATS
+-		atomic_inc(&tcon->num_opens);
+-#endif
+ 	}
++
+ 	cifs_buf_release(pSMB);
+ 	if (rc == -EAGAIN)
+ 		goto openRetry;
+@@ -807,11 +947,16 @@ CIFSSMBRead(const int xid, struct cifsTc
+ 	READ_RSP *pSMBr = NULL;
+ 	char *pReadData = NULL;
+ 	int bytes_returned;
++	int wct;
+ 
+ 	cFYI(1,("Reading %d bytes on fid %d",count,netfid));
++	if(tcon->ses->capabilities & CAP_LARGE_FILES)
++		wct = 12;
++	else
++		wct = 10; /* old style read */
+ 
+ 	*nbytes = 0;
+-	rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB,
++	rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB,
+ 		      (void **) &pSMBr);
+ 	if (rc)
+ 		return rc;
+@@ -823,14 +968,26 @@ CIFSSMBRead(const int xid, struct cifsTc
+ 	pSMB->AndXCommand = 0xFF;	/* none */
+ 	pSMB->Fid = netfid;
+ 	pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
+-	pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
++	if(wct == 12)
++		pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
++        else if((lseek >> 32) > 0) /* can not handle this big offset for old */
++                return -EIO;
++
+ 	pSMB->Remaining = 0;
+ 	pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
+ 	pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
+-	pSMB->ByteCount = 0;  /* no need to do le conversion since it is 0 */
+-
++	if(wct == 12)
++		pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
++	else {
++		/* old style read */
++		struct smb_com_readx_req * pSMBW = 
++			(struct smb_com_readx_req *)pSMB;
++		pSMBW->ByteCount = 0;	
++	}
++	
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_reads);
+ 	if (rc) {
+ 		cERROR(1, ("Send error in read = %d", rc));
+ 	} else {
+@@ -876,12 +1033,20 @@ CIFSSMBWrite(const int xid, struct cifsT
+ 	int rc = -EACCES;
+ 	WRITE_REQ *pSMB = NULL;
+ 	WRITE_RSP *pSMBr = NULL;
+-	int bytes_returned;
++	int bytes_returned, wct;
+ 	__u32 bytes_sent;
+ 	__u16 byte_count;
+ 
+ 	/* cFYI(1,("write at %lld %d bytes",offset,count));*/
+-	rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB,
++	if(tcon->ses == NULL)
++		return -ECONNABORTED;
++
++	if(tcon->ses->capabilities & CAP_LARGE_FILES)
++		wct = 14;
++	else
++		wct = 12;
++
++	rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
+ 		      (void **) &pSMBr);
+ 	if (rc)
+ 		return rc;
+@@ -892,7 +1057,11 @@ CIFSSMBWrite(const int xid, struct cifsT
+ 	pSMB->AndXCommand = 0xFF;	/* none */
+ 	pSMB->Fid = netfid;
+ 	pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
+-	pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
++	if(wct == 14) 
++		pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
++	else if((offset >> 32) > 0) /* can not handle this big offset for old */
++		return -EIO;
++	
+ 	pSMB->Reserved = 0xFFFFFFFF;
+ 	pSMB->WriteMode = 0;
+ 	pSMB->Remaining = 0;
+@@ -911,7 +1080,7 @@ CIFSSMBWrite(const int xid, struct cifsT
+ 	if (bytes_sent > count)
+ 		bytes_sent = count;
+ 	pSMB->DataOffset =
+-	    cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
++		cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
+ 	if(buf)
+ 	    memcpy(pSMB->Data,buf,bytes_sent);
+ 	else if(ubuf) {
+@@ -919,20 +1088,31 @@ CIFSSMBWrite(const int xid, struct cifsT
+ 			cifs_buf_release(pSMB);
+ 			return -EFAULT;
+ 		}
+-	} else {
++	} else if (count != 0) {
+ 		/* No buffer */
+ 		cifs_buf_release(pSMB);
+ 		return -EINVAL;
++	} /* else setting file size with write of zero bytes */
++	if(wct == 14)
++		byte_count = bytes_sent + 1; /* pad */
++	else /* wct == 12 */ {
++		byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
+ 	}
+-
+-	byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */
+ 	pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
+ 	pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
+-	pSMB->hdr.smb_buf_length += bytes_sent+1;
+-	pSMB->ByteCount = cpu_to_le16(byte_count);
++	pSMB->hdr.smb_buf_length += byte_count;
++
++	if(wct == 14)
++		pSMB->ByteCount = cpu_to_le16(byte_count);
++	else { /* old style write has byte count 4 bytes earlier so 4 bytes pad  */
++		struct smb_com_writex_req * pSMBW = 
++			(struct smb_com_writex_req *)pSMB;
++		pSMBW->ByteCount = cpu_to_le16(byte_count);
++	}
+ 
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
++	cifs_stats_inc(&tcon->num_writes);
+ 	if (rc) {
+ 		cFYI(1, ("Send error in write = %d", rc));
+ 		*nbytes = 0;
+@@ -951,56 +1131,72 @@ CIFSSMBWrite(const int xid, struct cifsT
+ }
+ 
+ #ifdef CONFIG_CIFS_EXPERIMENTAL
+-int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
++int
++CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
+ 	     const int netfid, const unsigned int count,
+-	     const __u64 offset, unsigned int *nbytes, const char __user *buf,
+-	     const int long_op)
++	     const __u64 offset, unsigned int *nbytes, struct kvec *iov,
++	     int n_vec, const int long_op)
+ {
+ 	int rc = -EACCES;
+ 	WRITE_REQ *pSMB = NULL;
+-	WRITE_RSP *pSMBr = NULL;
+-	/*int bytes_returned;*/
+-	unsigned bytes_sent;
+-	__u16 byte_count;
++	int bytes_returned, wct;
++	int smb_hdr_len;
+ 
+-	rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB);
+-    
++	cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
++	if(tcon->ses->capabilities & CAP_LARGE_FILES)
++		wct = 14;
++	else
++		wct = 12;
++	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
+ 	if (rc)
+ 		return rc;
+-	
+-	pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */
+-
+ 	/* tcon and ses pointer are checked in smb_init */
+ 	if (tcon->ses->server == NULL)
+ 		return -ECONNABORTED;
+ 
+-	pSMB->AndXCommand = 0xFF; /* none */
++	pSMB->AndXCommand = 0xFF;	/* none */
+ 	pSMB->Fid = netfid;
+ 	pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
+-	pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
++	if(wct == 14)
++		pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
++	else if((offset >> 32) > 0) /* can not handle this big offset for old */
++		return -EIO;
+ 	pSMB->Reserved = 0xFFFFFFFF;
+ 	pSMB->WriteMode = 0;
+ 	pSMB->Remaining = 0;
+-	bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF;
+-	if (bytes_sent > count)
+-		bytes_sent = count;
+-	pSMB->DataLengthHigh = 0;
++
+ 	pSMB->DataOffset =
+ 	    cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
+ 
+-	byte_count = bytes_sent + 1 /* pad */ ;
+-	pSMB->DataLengthLow = cpu_to_le16(bytes_sent);
+-	pSMB->DataLengthHigh = 0;
+-	pSMB->hdr.smb_buf_length += byte_count;
+-	pSMB->ByteCount = cpu_to_le16(byte_count);
+-
+-/*	rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-			 (struct smb_hdr *) pSMBr, buf, buflen, &bytes_returned, long_op); */  /* BB fixme BB */
++	pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
++	pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
++	smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
++	if(wct == 14)
++		pSMB->hdr.smb_buf_length += count+1;
++	else /* wct == 12 */
++		pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */ 
++	if(wct == 14)
++		pSMB->ByteCount = cpu_to_le16(count + 1);
++	else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
++		struct smb_com_writex_req * pSMBW =
++				(struct smb_com_writex_req *)pSMB;
++		pSMBW->ByteCount = cpu_to_le16(count + 5);
++	}
++	iov[0].iov_base = pSMB;
++	iov[0].iov_len = smb_hdr_len + 4;
++
++	rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned,
++			  long_op);
++	cifs_stats_inc(&tcon->num_writes);
+ 	if (rc) {
+-		cFYI(1, ("Send error in write2 (large write) = %d", rc));
++		cFYI(1, ("Send error Write2 = %d", rc));
+ 		*nbytes = 0;
+-	} else
+-		*nbytes = le16_to_cpu(pSMBr->Count);
++	} else {
++		WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
++		*nbytes = le16_to_cpu(pSMBr->CountHigh);
++		*nbytes = (*nbytes) << 16;
++		*nbytes += le16_to_cpu(pSMBr->Count);
++	}
+ 
+ 	cifs_small_buf_release(pSMB);
+ 
+@@ -1009,6 +1205,8 @@ int CIFSSMBWrite2(const int xid, struct 
+ 
+ 	return rc;
+ }
++
++
+ #endif /* CIFS_EXPERIMENTAL */
+ 
+ int
+@@ -1065,7 +1263,7 @@ CIFSSMBLock(const int xid, struct cifsTc
+ 
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
+-
++	cifs_stats_inc(&tcon->num_locks);
+ 	if (rc) {
+ 		cFYI(1, ("Send error in Lock = %d", rc));
+ 	}
+@@ -1099,6 +1297,7 @@ CIFSSMBClose(const int xid, struct cifsT
+ 	pSMB->ByteCount = 0;
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_closes);
+ 	if (rc) {
+ 		if(rc!=-EINTR) {
+ 			/* EINTR is expected when user ctl-c to kill app */
+@@ -1171,16 +1370,11 @@ renameRetry:
+ 
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_renames);
+ 	if (rc) {
+ 		cFYI(1, ("Send error in rename = %d", rc));
+ 	} 
+ 
+-#ifdef CONFIG_CIFS_STATS
+-	  else {
+-		atomic_inc(&tcon->num_renames);
+-	}
+-#endif
+-
+ 	cifs_buf_release(pSMB);
+ 
+ 	if (rc == -EAGAIN)
+@@ -1255,14 +1449,11 @@ int CIFSSMBRenameOpenFile(const int xid,
+ 	pSMB->ByteCount = cpu_to_le16(byte_count);
+ 	rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
+                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&pTcon->num_t2renames);
+ 	if (rc) {
+ 		cFYI(1,("Send error in Rename (by file handle) = %d", rc));
+ 	}
+-#ifdef CONFIG_CIFS_STATS
+-	  else {
+-		atomic_inc(&pTcon->num_t2renames);
+-	}
+-#endif
++
+ 	cifs_buf_release(pSMB);
+ 
+ 	/* Note: On -EAGAIN error only caller can retry on handle based calls
+@@ -1416,6 +1607,7 @@ createSymLinkRetry:
+ 	pSMB->ByteCount = cpu_to_le16(byte_count);
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_symlinks);
+ 	if (rc) {
+ 		cFYI(1,
+ 		     ("Send error in SetPathInfo (create symlink) = %d",
+@@ -1505,6 +1697,7 @@ createHardLinkRetry:
+ 	pSMB->ByteCount = cpu_to_le16(byte_count);
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_hardlinks);
+ 	if (rc) {
+ 		cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc));
+ 	}
+@@ -1575,6 +1768,7 @@ winCreateHardLinkRetry:
+ 
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_hardlinks);
+ 	if (rc) {
+ 		cFYI(1, ("Send error in hard link (NT rename) = %d", rc));
+ 	}
+@@ -1775,8 +1969,7 @@ CIFSSMBQueryReparseLinkInfo(const int xi
+ 		}
+ 	}
+ qreparse_out:
+-	if (pSMB)
+-		cifs_buf_release(pSMB);
++	cifs_buf_release(pSMB);
+ 
+ 	/* Note: On -EAGAIN error only caller can retry on handle based calls
+ 		since file handle passed in no longer valid */
+@@ -2165,6 +2358,67 @@ GetExtAttrOut:
+ 
+ #endif /* CONFIG_POSIX */
+ 
++/* Legacy Query Path Information call for lookup to old servers such
++   as Win9x/WinME */
++int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
++                 const unsigned char *searchName,
++                 FILE_ALL_INFO * pFinfo,
++                 const struct nls_table *nls_codepage, int remap)
++{
++	QUERY_INFORMATION_REQ * pSMB;
++	QUERY_INFORMATION_RSP * pSMBr;
++	int rc = 0;
++	int bytes_returned;
++	int name_len;
++
++	cFYI(1, ("In SMBQPath path %s", searchName)); 
++QInfRetry:
++	rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
++                      (void **) &pSMBr);
++	if (rc)
++		return rc;
++
++	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
++		name_len =
++                    cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
++                                     PATH_MAX, nls_codepage, remap);
++		name_len++;     /* trailing null */
++		name_len *= 2;
++	} else {               
++		name_len = strnlen(searchName, PATH_MAX);
++		name_len++;     /* trailing null */
++		strncpy(pSMB->FileName, searchName, name_len);
++	}
++	pSMB->BufferFormat = 0x04;
++	name_len++; /* account for buffer type byte */	
++	pSMB->hdr.smb_buf_length += (__u16) name_len;
++	pSMB->ByteCount = cpu_to_le16(name_len);
++
++	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
++                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	if (rc) {
++		cFYI(1, ("Send error in QueryInfo = %d", rc));
++	} else if (pFinfo) {            /* decode response */
++		memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
++		pFinfo->AllocationSize =
++			cpu_to_le64(le32_to_cpu(pSMBr->size));
++		pFinfo->EndOfFile = pFinfo->AllocationSize;
++		pFinfo->Attributes =
++			cpu_to_le32(le16_to_cpu(pSMBr->attr));
++	} else
++		rc = -EIO; /* bad buffer passed in */
++
++	cifs_buf_release(pSMB);
++
++	if (rc == -EAGAIN)
++		goto QInfRetry;
++
++	return rc;
++}
++
++
++
++
+ int
+ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
+ 		 const unsigned char *searchName,
+@@ -2396,7 +2650,7 @@ findUniqueRetry:
+ 	if (rc) {
+ 		cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
+ 	} else {		/* decode response */
+-
++		cifs_stats_inc(&tcon->num_ffirst);
+ 		/* BB fill in */
+ 	}
+ 
+@@ -2414,7 +2668,7 @@ CIFSFindFirst(const int xid, struct cifs
+ 	      const char *searchName, 
+ 	      const struct nls_table *nls_codepage,
+ 	      __u16 *	pnetfid,
+-	      struct cifs_search_info * psrch_inf, int remap)
++	      struct cifs_search_info * psrch_inf, int remap, const char dirsep)
+ {
+ /* level 257 SMB_ */
+ 	TRANSACTION2_FFIRST_REQ *pSMB = NULL;
+@@ -2441,7 +2695,7 @@ findFirstRetry:
+ 		it got remapped to 0xF03A as if it were part of the
+ 		directory name instead of a wildcard */
+ 		name_len *= 2;
+-		pSMB->FileName[name_len] = '\\';
++		pSMB->FileName[name_len] = dirsep;
+ 		pSMB->FileName[name_len+1] = 0;
+ 		pSMB->FileName[name_len+2] = '*';
+ 		pSMB->FileName[name_len+3] = 0;
+@@ -2455,7 +2709,7 @@ findFirstRetry:
+ 		if(name_len > buffersize-header)
+ 			free buffer exit; BB */
+ 		strncpy(pSMB->FileName, searchName, name_len);
+-		pSMB->FileName[name_len] = '\\';
++		pSMB->FileName[name_len] = dirsep;
+ 		pSMB->FileName[name_len+1] = '*';
+ 		pSMB->FileName[name_len+2] = 0;
+ 		name_len += 3;
+@@ -2496,6 +2750,7 @@ findFirstRetry:
+ 
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	cifs_stats_inc(&tcon->num_ffirst);
+ 
+ 	if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
+ 		/* BB Add code to handle unsupported level rc */
+@@ -2617,7 +2872,7 @@ int CIFSFindNext(const int xid, struct c
+                                                                                               
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+-                                                                                              
++	cifs_stats_inc(&tcon->num_fnext);
+ 	if (rc) {
+ 		if (rc == -EBADF) {
+ 			psrch_inf->endOfSearch = TRUE;
+@@ -2694,6 +2949,7 @@ CIFSFindClose(const int xid, struct cifs
+ 	if (rc) {
+ 		cERROR(1, ("Send error in FindClose = %d", rc));
+ 	}
++	cifs_stats_inc(&tcon->num_fclose);
+ 	cifs_small_buf_release(pSMB);
+ 
+ 	/* Since session is dead, search handle closed on server already */
+@@ -2827,7 +3083,10 @@ getDFSRetry:
+ 		      (void **) &pSMBr);
+ 	if (rc)
+ 		return rc;
+-
++	
++	/* server pointer checked in called function, 
++	but should never be null here anyway */
++	pSMB->hdr.Mid = GetNextMid(ses->server);
+ 	pSMB->hdr.Tid = ses->ipc_tid;
+ 	pSMB->hdr.Uid = ses->Suid;
+ 	if (ses->capabilities & CAP_STATUS32) {
+@@ -2968,6 +3227,92 @@ GetDFSRefExit:
+ 	return rc;
+ }
+ 
++/* Query File System Info such as free space to old servers such as Win 9x */
++int
++SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
++{
++/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
++	TRANSACTION2_QFSI_REQ *pSMB = NULL;
++	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
++	FILE_SYSTEM_ALLOC_INFO *response_data;
++	int rc = 0;
++	int bytes_returned = 0;
++	__u16 params, byte_count;
++
++	cFYI(1, ("OldQFSInfo"));
++oldQFSInfoRetry:
++	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
++		(void **) &pSMBr);
++	if (rc)
++		return rc;
++	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
++		      (void **) &pSMBr);
++	if (rc)
++		return rc;
++
++	params = 2;     /* level */
++	pSMB->TotalDataCount = 0;
++	pSMB->MaxParameterCount = cpu_to_le16(2);
++	pSMB->MaxDataCount = cpu_to_le16(1000);
++	pSMB->MaxSetupCount = 0;
++	pSMB->Reserved = 0;
++	pSMB->Flags = 0;
++	pSMB->Timeout = 0;
++	pSMB->Reserved2 = 0;
++	byte_count = params + 1 /* pad */ ;
++	pSMB->TotalParameterCount = cpu_to_le16(params);
++	pSMB->ParameterCount = pSMB->TotalParameterCount;
++	pSMB->ParameterOffset = cpu_to_le16(offsetof(
++	struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
++	pSMB->DataCount = 0;
++	pSMB->DataOffset = 0;
++	pSMB->SetupCount = 1;
++	pSMB->Reserved3 = 0;
++	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
++	pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
++	pSMB->hdr.smb_buf_length += byte_count;
++	pSMB->ByteCount = cpu_to_le16(byte_count);
++
++	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
++		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	if (rc) {
++		cFYI(1, ("Send error in QFSInfo = %d", rc));
++	} else {                /* decode response */
++		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
++
++		if (rc || (pSMBr->ByteCount < 18))
++			rc = -EIO;      /* bad smb */
++		else {
++			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
++			cFYI(1,("qfsinf resp BCC: %d  Offset %d",
++				 pSMBr->ByteCount, data_offset));
++
++			response_data =
++				(FILE_SYSTEM_ALLOC_INFO *) 
++				(((char *) &pSMBr->hdr.Protocol) + data_offset);
++			FSData->f_bsize =
++				le16_to_cpu(response_data->BytesPerSector) *
++				le32_to_cpu(response_data->
++					SectorsPerAllocationUnit);
++			FSData->f_blocks =
++				le32_to_cpu(response_data->TotalAllocationUnits);
++			FSData->f_bfree = FSData->f_bavail =
++				le32_to_cpu(response_data->FreeAllocationUnits);
++			cFYI(1,
++			     ("Blocks: %lld  Free: %lld Block size %ld",
++			      (unsigned long long)FSData->f_blocks,
++			      (unsigned long long)FSData->f_bfree,
++			      FSData->f_bsize));
++		}
++	}
++	cifs_buf_release(pSMB);
++
++	if (rc == -EAGAIN)
++		goto oldQFSInfoRetry;
++
++	return rc;
++}
++
+ int
+ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
+ {
+@@ -2989,7 +3334,7 @@ QFSInfoRetry:
+ 	params = 2;	/* level */
+ 	pSMB->TotalDataCount = 0;
+ 	pSMB->MaxParameterCount = cpu_to_le16(2);
+-	pSMB->MaxDataCount = cpu_to_le16(1000);	/* BB find exact max SMB PDU from sess structure BB */
++	pSMB->MaxDataCount = cpu_to_le16(1000);
+ 	pSMB->MaxSetupCount = 0;
+ 	pSMB->Reserved = 0;
+ 	pSMB->Flags = 0;
+@@ -3012,17 +3357,14 @@ QFSInfoRetry:
+ 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ 	if (rc) {
+-		cERROR(1, ("Send error in QFSInfo = %d", rc));
++		cFYI(1, ("Send error in QFSInfo = %d", rc));
+ 	} else {		/* decode response */
+                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+ 
+-		if (rc || (pSMBr->ByteCount < 24)) /* BB alsO CHEck enough total bytes returned */
++		if (rc || (pSMBr->ByteCount < 24))
+ 			rc = -EIO;	/* bad smb */
+ 		else {
+ 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+-			cFYI(1,
+-				("Decoding qfsinfo response.  BCC: %d  Offset %d",
+-				pSMBr->ByteCount, data_offset));
+ 
+ 			response_data =
+ 			    (FILE_SYSTEM_INFO
+@@ -3257,6 +3599,77 @@ QFSUnixRetry:
+ 	return rc;
+ }
+ 
++int
++CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
++{
++/* level 0x200  SMB_SET_CIFS_UNIX_INFO */
++	TRANSACTION2_SETFSI_REQ *pSMB = NULL;
++	TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
++	int rc = 0;
++	int bytes_returned = 0;
++	__u16 params, param_offset, offset, byte_count;
++
++	cFYI(1, ("In SETFSUnixInfo"));
++SETFSUnixRetry:
++	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
++		      (void **) &pSMBr);
++	if (rc)
++		return rc;
++
++	params = 4;	/* 2 bytes zero followed by info level. */
++	pSMB->MaxSetupCount = 0;
++	pSMB->Reserved = 0;
++	pSMB->Flags = 0;
++	pSMB->Timeout = 0;
++	pSMB->Reserved2 = 0;
++	param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4;
++	offset = param_offset + params;
++
++	pSMB->MaxParameterCount = cpu_to_le16(4);
++	pSMB->MaxDataCount = cpu_to_le16(100);	/* BB find exact max SMB PDU from sess structure BB */
++	pSMB->SetupCount = 1;
++	pSMB->Reserved3 = 0;
++	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
++	byte_count = 1 /* pad */ + params + 12;
++
++	pSMB->DataCount = cpu_to_le16(12);
++	pSMB->ParameterCount = cpu_to_le16(params);
++	pSMB->TotalDataCount = pSMB->DataCount;
++	pSMB->TotalParameterCount = pSMB->ParameterCount;
++	pSMB->ParameterOffset = cpu_to_le16(param_offset);
++	pSMB->DataOffset = cpu_to_le16(offset);
++
++	/* Params. */
++	pSMB->FileNum = 0;
++	pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
++
++	/* Data. */
++	pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
++	pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
++	pSMB->ClientUnixCap = cpu_to_le64(cap);
++
++	pSMB->hdr.smb_buf_length += byte_count;
++	pSMB->ByteCount = cpu_to_le16(byte_count);
++
++	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
++			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	if (rc) {
++		cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
++	} else {		/* decode response */
++		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
++		if (rc) {
++			rc = -EIO;	/* bad smb */
++		}
++	}
++	cifs_buf_release(pSMB);
++
++	if (rc == -EAGAIN)
++		goto SETFSUnixRetry;
++
++	return rc;
++}
++
++
+ 
+ int
+ CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
+@@ -3321,16 +3734,16 @@ QFSPosixRetry:
+ 					le64_to_cpu(response_data->TotalBlocks);
+ 			FSData->f_bfree =
+ 			    le64_to_cpu(response_data->BlocksAvail);
+-			if(response_data->UserBlocksAvail == -1) {
++			if(response_data->UserBlocksAvail == cpu_to_le64(-1)) {
+ 				FSData->f_bavail = FSData->f_bfree;
+ 			} else {
+ 				FSData->f_bavail =
+ 					le64_to_cpu(response_data->UserBlocksAvail);
+ 			}
+-			if(response_data->TotalFileNodes != -1)
++			if(response_data->TotalFileNodes != cpu_to_le64(-1))
+ 				FSData->f_files =
+ 					le64_to_cpu(response_data->TotalFileNodes);
+-			if(response_data->FreeFileNodes != -1)
++			if(response_data->FreeFileNodes != cpu_to_le64(-1))
+ 				FSData->f_ffree =
+ 					le64_to_cpu(response_data->FreeFileNodes);
+ 		}
+@@ -3376,7 +3789,7 @@ SetEOFRetry:
+ 				     PATH_MAX, nls_codepage, remap);
+ 		name_len++;	/* trailing null */
+ 		name_len *= 2;
+-	} else {		/* BB improve the check for buffer overruns BB */
++	} else {	/* BB improve the check for buffer overruns BB */
+ 		name_len = strnlen(fileName, PATH_MAX);
+ 		name_len++;	/* trailing null */
+ 		strncpy(pSMB->FileName, fileName, name_len);
+@@ -3384,7 +3797,7 @@ SetEOFRetry:
+ 	params = 6 + name_len;
+ 	data_count = sizeof (struct file_end_of_file_info);
+ 	pSMB->MaxParameterCount = cpu_to_le16(2);
+-	pSMB->MaxDataCount = cpu_to_le16(1000);	/* BB find max SMB size from sess */
++	pSMB->MaxDataCount = cpu_to_le16(4100);
+ 	pSMB->MaxSetupCount = 0;
+ 	pSMB->Reserved = 0;
+ 	pSMB->Flags = 0;
+@@ -3766,7 +4179,7 @@ setPermsRetry:
+ 				     PATH_MAX, nls_codepage, remap);
+ 		name_len++;	/* trailing null */
+ 		name_len *= 2;
+-	} else {		/* BB improve the check for buffer overruns BB */
++	} else {	/* BB improve the check for buffer overruns BB */
+ 		name_len = strnlen(fileName, PATH_MAX);
+ 		name_len++;	/* trailing null */
+ 		strncpy(pSMB->FileName, fileName, name_len);
+@@ -3839,12 +4252,14 @@ setPermsRetry:
+ }
+ 
+ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 
+-			const int notify_subdirs, const __u16 netfid,
+-			__u32 filter, const struct nls_table *nls_codepage)
++		  const int notify_subdirs, const __u16 netfid,
++		  __u32 filter, struct file * pfile, int multishot, 
++		  const struct nls_table *nls_codepage)
+ {
+ 	int rc = 0;
+ 	struct smb_com_transaction_change_notify_req * pSMB = NULL;
+ 	struct smb_com_transaction_change_notify_rsp * pSMBr = NULL;
++	struct dir_notify_req *dnotify_req;
+ 	int bytes_returned;
+ 
+ 	cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid));
+@@ -3877,6 +4292,28 @@ int CIFSSMBNotify(const int xid, struct 
+ 			(struct smb_hdr *) pSMBr, &bytes_returned, -1);
+ 	if (rc) {
+ 		cFYI(1, ("Error in Notify = %d", rc));
++	} else {
++		/* Add file to outstanding requests */
++		/* BB change to kmem cache alloc */	
++		dnotify_req = (struct dir_notify_req *) kmalloc(
++						sizeof(struct dir_notify_req),
++						 GFP_KERNEL);
++		if(dnotify_req) {
++			dnotify_req->Pid = pSMB->hdr.Pid;
++			dnotify_req->PidHigh = pSMB->hdr.PidHigh;
++			dnotify_req->Mid = pSMB->hdr.Mid;
++			dnotify_req->Tid = pSMB->hdr.Tid;
++			dnotify_req->Uid = pSMB->hdr.Uid;
++			dnotify_req->netfid = netfid;
++			dnotify_req->pfile = pfile;
++			dnotify_req->filter = filter;
++			dnotify_req->multishot = multishot;
++			spin_lock(&GlobalMid_Lock);
++			list_add_tail(&dnotify_req->lhead, 
++					&GlobalDnotifyReqList);
++			spin_unlock(&GlobalMid_Lock);
++		} else 
++			rc = -ENOMEM;
+ 	}
+ 	cifs_buf_release(pSMB);
+ 	return rc;	
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -29,6 +29,8 @@
+ #include <linux/utsname.h>
+ #include <linux/mempool.h>
+ #include <linux/delay.h>
++#include <linux/completion.h>
++#include <linux/pagevec.h>
+ #include <asm/uaccess.h>
+ #include <asm/processor.h>
+ #include "cifspdu.h"
+@@ -44,6 +46,8 @@
+ #define CIFS_PORT 445
+ #define RFC1001_PORT 139
+ 
++static DECLARE_COMPLETION(cifsd_complete);
++
+ extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
+ 		       unsigned char *p24);
+ extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
+@@ -60,6 +64,7 @@ struct smb_vol {
+ 	char *in6_addr;  /* ipv6 address as human readable form of in6_addr */
+ 	char *iocharset;  /* local code page for mapping to and from Unicode */
+ 	char source_rfc1001_name[16]; /* netbios name of client */
++	char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
+ 	uid_t linux_uid;
+ 	gid_t linux_gid;
+ 	mode_t file_mode;
+@@ -74,6 +79,10 @@ struct smb_vol {
+ 	unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
+ 	unsigned direct_io:1;
+ 	unsigned remap:1;   /* set to remap seven reserved chars in filenames */
++	unsigned posix_paths:1;   /* unset to not ask for posix pathnames. */
++	unsigned sfu_emul:1;
++	unsigned nocase;     /* request case insensitive filenames */
++	unsigned nobrl;      /* disable sending byte range locks to srv */
+ 	unsigned int rsize;
+ 	unsigned int wsize;
+ 	unsigned int sockopt;
+@@ -82,7 +91,8 @@ struct smb_vol {
+ 
+ static int ipv4_connect(struct sockaddr_in *psin_server, 
+ 			struct socket **csocket,
+-			char * netb_name);
++			char * netb_name,
++			char * server_netb_name);
+ static int ipv6_connect(struct sockaddr_in6 *psin_server, 
+ 			struct socket **csocket);
+ 
+@@ -175,9 +185,11 @@ cifs_reconnect(struct TCP_Server_Info *s
+ 		} else {
+ 			rc = ipv4_connect(&server->addr.sockAddr, 
+ 					&server->ssocket,
+-					server->workstation_RFC1001_name);
++					server->workstation_RFC1001_name,
++					server->server_RFC1001_name);
+ 		}
+ 		if(rc) {
++			cFYI(1,("reconnect error %d",rc));
+ 			msleep(3000);
+ 		} else {
+ 			atomic_inc(&tcpSesReconnectCount);
+@@ -293,12 +305,12 @@ static int coalesce_t2(struct smb_hdr * 
+ 	byte_count += total_in_buf2;
+ 	BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
+ 
+-	byte_count = be32_to_cpu(pTargetSMB->smb_buf_length);
++	byte_count = pTargetSMB->smb_buf_length;
+ 	byte_count += total_in_buf2;
+ 
+ 	/* BB also add check that we are not beyond maximum buffer size */
+ 		
+-	pTargetSMB->smb_buf_length = cpu_to_be32(byte_count);
++	pTargetSMB->smb_buf_length = byte_count;
+ 
+ 	if(remaining == total_in_buf2) {
+ 		cFYI(1,("found the last secondary response"));
+@@ -323,7 +335,7 @@ cifs_demultiplex_thread(struct TCP_Serve
+ 	struct cifsSesInfo *ses;
+ 	struct task_struct *task_to_wake = NULL;
+ 	struct mid_q_entry *mid_entry;
+-	char *temp;
++	char temp;
+ 	int isLargeBuf = FALSE;
+ 	int isMultiRsp;
+ 	int reconnect;
+@@ -337,6 +349,7 @@ cifs_demultiplex_thread(struct TCP_Serve
+ 	atomic_inc(&tcpSesAllocCount);
+ 	length = tcpSesAllocCount.counter;
+ 	write_unlock(&GlobalSMBSeslock);
++	complete(&cifsd_complete);
+ 	if(length  > 1) {
+ 		mempool_resize(cifs_req_poolp,
+ 			length + cifs_min_rcv,
+@@ -424,22 +437,32 @@ cifs_demultiplex_thread(struct TCP_Serve
+ 			continue;
+ 		}
+ 
+-		/* the right amount was read from socket - 4 bytes */
++		/* The right amount was read from socket - 4 bytes */
++		/* so we can now interpret the length field */
+ 
++		/* the first byte big endian of the length field,
++		is actually not part of the length but the type
++		with the most common, zero, as regular data */
++		temp = *((char *) smb_buffer);
++
++		/* Note that FC 1001 length is big endian on the wire, 
++		but we convert it here so it is always manipulated
++		as host byte order */
+ 		pdu_length = ntohl(smb_buffer->smb_buf_length);
+-		cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4));
++		smb_buffer->smb_buf_length = pdu_length;
++
++		cFYI(1,("rfc1002 length 0x%x)", pdu_length+4));
+ 
+-		temp = (char *) smb_buffer;
+-		if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
++		if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
+ 			continue; 
+-		} else if (temp[0] == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
++		} else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
+ 			cFYI(1,("Good RFC 1002 session rsp"));
+ 			continue;
+-		} else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
++		} else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
+ 			/* we get this from Windows 98 instead of 
+ 			   an error on SMB negprot response */
+ 			cFYI(1,("Negative RFC1002 Session Response Error 0x%x)",
+-				temp[4]));
++				pdu_length));
+ 			if(server->tcpStatus == CifsNew) {
+ 				/* if nack on negprot (rather than 
+ 				ret of smb negprot error) reconnecting
+@@ -461,9 +484,10 @@ cifs_demultiplex_thread(struct TCP_Serve
+ 				wake_up(&server->response_q);
+ 				continue;
+ 			}
+-		} else if (temp[0] != (char) 0) {
++		} else if (temp != (char) 0) {
+ 			cERROR(1,("Unknown RFC 1002 frame"));
+-			cifs_dump_mem(" Received Data: ", temp, length);
++			cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
++				      length);
+ 			cifs_reconnect(server);
+ 			csocket = server->ssocket;
+ 			continue;
+@@ -533,7 +557,7 @@ cifs_demultiplex_thread(struct TCP_Serve
+ 
+ 		dump_smb(smb_buffer, length);
+ 		if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) {
+-			cERROR(1, ("Bad SMB Received "));
++			cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
+ 			continue;
+ 		}
+ 
+@@ -581,6 +605,9 @@ cifs_demultiplex_thread(struct TCP_Serve
+ multi_t2_fnd:
+ 				task_to_wake = mid_entry->tsk;
+ 				mid_entry->midState = MID_RESPONSE_RECEIVED;
++#ifdef CONFIG_CIFS_STATS2
++				mid_entry->when_received = jiffies;
++#endif
+ 				break;
+ 			}
+ 		}
+@@ -598,7 +625,8 @@ multi_t2_fnd:
+ 		} else if ((is_valid_oplock_break(smb_buffer) == FALSE)
+ 		    && (isMultiRsp == FALSE)) {                          
+ 			cERROR(1, ("No task to wake, unknown frame rcvd!"));
+-			cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));
++			cifs_dump_mem("Received Data is: ",(char *)smb_buffer,
++				      sizeof(struct smb_hdr));
+ 		}
+ 	} /* end while !EXITING */
+ 
+@@ -676,7 +704,7 @@ multi_t2_fnd:
+ 		msleep(125);
+ 	}
+ 
+-	if (list_empty(&server->pending_mid_q)) {
++	if (!list_empty(&server->pending_mid_q)) {
+ 		/* mpx threads have not exited yet give them 
+ 		at least the smb send timeout time for long ops */
+ 		/* due to delays on oplock break requests, we need
+@@ -713,7 +741,7 @@ multi_t2_fnd:
+ 			GFP_KERNEL);
+ 	}
+ 	
+-	msleep(250);
++	complete_and_exit(&cifsd_complete, 0);
+ 	return 0;
+ }
+ 
+@@ -737,7 +765,9 @@ cifs_parse_mount_options(char *options, 
+ 			toupper(system_utsname.nodename[i]);
+ 	}
+ 	vol->source_rfc1001_name[15] = 0;
+-
++	/* null target name indicates to use *SMBSERVR default called name
++	   if we end up sending RFC1001 session initialize */
++	vol->target_rfc1001_name[0] = 0;
+ 	vol->linux_uid = current->uid;	/* current->euid instead? */
+ 	vol->linux_gid = current->gid;
+ 	vol->dir_mode = S_IRWXUGO;
+@@ -747,6 +777,9 @@ cifs_parse_mount_options(char *options, 
+ 	/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
+ 	vol->rw = TRUE;
+ 
++	/* default is always to request posix paths. */
++	vol->posix_paths = 1;
++
+ 	if (!options)
+ 		return 1;
+ 
+@@ -987,7 +1020,31 @@ cifs_parse_mount_options(char *options, 
+ 				/* The string has 16th byte zero still from
+ 				set at top of the function  */
+ 				if((i==15) && (value[i] != 0))
+-					printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n");
++					printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
++			}
++		} else if (strnicmp(data, "servern", 7) == 0) {
++			/* servernetbiosname specified override *SMBSERVER */
++			if (!value || !*value || (*value == ' ')) {
++				cFYI(1,("empty server netbiosname specified"));
++			} else {
++				/* last byte, type, is 0x20 for servr type */
++				memset(vol->target_rfc1001_name,0x20,16);
++
++				for(i=0;i<15;i++) {
++				/* BB are there cases in which a comma can be
++				   valid in this workstation netbios name (and need
++				   special handling)? */
++
++				/* user or mount helper must uppercase netbiosname */
++					if (value[i]==0)
++						break;
++					else
++						vol->target_rfc1001_name[i] = value[i];
++				}
++				/* The string has 16th byte zero still from
++				   set at top of the function  */
++				if((i==15) && (value[i] != 0))
++					printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
+ 			}
+ 		} else if (strnicmp(data, "credentials", 4) == 0) {
+ 			/* ignore */
+@@ -1025,6 +1082,27 @@ cifs_parse_mount_options(char *options, 
+ 			vol->remap = 1;
+ 		} else if (strnicmp(data, "nomapchars", 10) == 0) {
+ 			vol->remap = 0;
++                } else if (strnicmp(data, "sfu", 3) == 0) {
++                        vol->sfu_emul = 1;
++                } else if (strnicmp(data, "nosfu", 5) == 0) {
++                        vol->sfu_emul = 0;
++		} else if (strnicmp(data, "posixpaths", 10) == 0) {
++			vol->posix_paths = 1;
++		} else if (strnicmp(data, "noposixpaths", 12) == 0) {
++			vol->posix_paths = 0;
++                } else if ((strnicmp(data, "nocase", 6) == 0) ||
++			   (strnicmp(data, "ignorecase", 10)  == 0)) {
++                        vol->nocase = 1;
++		} else if (strnicmp(data, "brl", 3) == 0) {
++			vol->nobrl =  0;
++		} else if ((strnicmp(data, "nobrl", 5) == 0) || 
++			   (strnicmp(data, "nolock", 6) == 0)) {
++			vol->nobrl =  1;
++			/* turn off mandatory locking in mode
++			if remote locking is turned off since the
++			local vfs will do advisory */
++			if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
++				vol->file_mode = S_IALLUGO;
+ 		} else if (strnicmp(data, "setuids", 7) == 0) {
+ 			vol->setuids = 1;
+ 		} else if (strnicmp(data, "nosetuids", 9) == 0) {
+@@ -1244,7 +1322,7 @@ static void rfc1002mangle(char * target,
+ 
+ static int
+ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 
+-			 char * netbios_name)
++	     char * netbios_name, char * target_name)
+ {
+ 	int rc = 0;
+ 	int connected = 0;
+@@ -1309,10 +1387,16 @@ ipv4_connect(struct sockaddr_in *psin_se
+ 	/* Eventually check for other socket options to change from 
+ 		the default. sock_setsockopt not used because it expects 
+ 		user space buffer */
++	 cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf,
++		 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
+ 	(*csocket)->sk->sk_rcvtimeo = 7 * HZ;
++	/* make the bufsizes depend on wsize/rsize and max requests */
++	if((*csocket)->sk->sk_sndbuf < (200 * 1024))
++		(*csocket)->sk->sk_sndbuf = 200 * 1024;
++	if((*csocket)->sk->sk_rcvbuf < (140 * 1024))
++		(*csocket)->sk->sk_rcvbuf = 140 * 1024;
+ 
+ 	/* send RFC1001 sessinit */
+-
+ 	if(psin_server->sin_port == htons(RFC1001_PORT)) {
+ 		/* some servers require RFC1001 sessinit before sending
+ 		negprot - BB check reconnection in case where second 
+@@ -1322,8 +1406,14 @@ ipv4_connect(struct sockaddr_in *psin_se
+ 		ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL);
+ 		if(ses_init_buf) {
+ 			ses_init_buf->trailer.session_req.called_len = 32;
+-			rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
+-				DEFAULT_CIFS_CALLED_NAME,16);
++			if(target_name && (target_name[0] != 0)) {
++				rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
++					target_name, 16);
++			} else {
++				rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
++					DEFAULT_CIFS_CALLED_NAME,16);
++			}
++
+ 			ses_init_buf->trailer.session_req.calling_len = 32;
+ 			/* calling name ends in null (byte 16) from old smb
+ 			convention. */
+@@ -1556,7 +1646,9 @@ cifs_mount(struct super_block *sb, struc
+ 			sin_server.sin_port = htons(volume_info.port);
+ 		else
+ 			sin_server.sin_port = 0;
+-		rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name);
++		rc = ipv4_connect(&sin_server,&csocket,
++				  volume_info.source_rfc1001_name,
++				  volume_info.target_rfc1001_name);
+ 		if (rc < 0) {
+ 			cERROR(1,
+ 			       ("Error connecting to IPv4 socket. Aborting operation"));
+@@ -1606,9 +1698,11 @@ cifs_mount(struct super_block *sb, struc
+ 					kfree(volume_info.password);
+ 				FreeXid(xid);
+ 				return rc;
+-			} else
+-				rc = 0;
++			}
++			wait_for_completion(&cifsd_complete);
++			rc = 0;
+ 			memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
++			memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16);
+ 			srvTcp->sequence_number = 0;
+ 		}
+ 	}
+@@ -1653,17 +1747,27 @@ cifs_mount(struct super_block *sb, struc
+     
+ 	/* search for existing tcon to this server share */
+ 	if (!rc) {
+-		if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
++		if(volume_info.rsize > CIFSMaxBufSize) {
++			cERROR(1,("rsize %d too large, using MaxBufSize",
++				volume_info.rsize));
++			cifs_sb->rsize = CIFSMaxBufSize;
++		} else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
+ 			cifs_sb->rsize = volume_info.rsize;
+-		else
+-			cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */
+-		if((volume_info.wsize) && (volume_info.wsize <= CIFSMaxBufSize))
++		else /* default */
++			cifs_sb->rsize = CIFSMaxBufSize;
++
++		if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
++			cERROR(1,("wsize %d too large using 4096 instead",
++				  volume_info.wsize));
++			cifs_sb->wsize = 4096;
++		} else if(volume_info.wsize)
+ 			cifs_sb->wsize = volume_info.wsize;
+ 		else
+ 			cifs_sb->wsize = CIFSMaxBufSize; /* default */
+ 		if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
+-			cifs_sb->rsize = PAGE_CACHE_SIZE;
+-			cERROR(1,("Attempt to set readsize for mount to less than one page (4096)"));
++			cifs_sb->rsize = PAGE_CACHE_SIZE; 
++			/* Windows ME does this */
++			cFYI(1,("Attempt to set readsize for mount to less than one page (4096)"));
+ 		}
+ 		cifs_sb->mnt_uid = volume_info.linux_uid;
+ 		cifs_sb->mnt_gid = volume_info.linux_gid;
+@@ -1681,8 +1785,13 @@ cifs_mount(struct super_block *sb, struc
+ 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
+ 		if(volume_info.no_xattr)
+ 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
++		if(volume_info.sfu_emul)
++			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
++		if(volume_info.nobrl)
++			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
++
+ 		if(volume_info.direct_io) {
+-			cERROR(1,("mounting share using direct i/o"));
++			cFYI(1,("mounting share using direct i/o"));
+ 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
+ 		}
+ 
+@@ -1696,6 +1805,7 @@ cifs_mount(struct super_block *sb, struc
+ 			   to the same server share the last value passed in 
+ 			   for the retry flag is used */
+ 			tcon->retry = volume_info.retry;
++			tcon->nocase = volume_info.nocase;
+ 		} else {
+ 			tcon = tconInfoAlloc();
+ 			if (tcon == NULL)
+@@ -1724,6 +1834,7 @@ cifs_mount(struct super_block *sb, struc
+ 				if (!rc) {
+ 					atomic_inc(&pSesInfo->inUse);
+ 					tcon->retry = volume_info.retry;
++					tcon->nocase = volume_info.nocase;
+ 				}
+ 			}
+ 		}
+@@ -1745,8 +1856,10 @@ cifs_mount(struct super_block *sb, struc
+ 			spin_lock(&GlobalMid_Lock);
+ 			srvTcp->tcpStatus = CifsExiting;
+ 			spin_unlock(&GlobalMid_Lock);
+-			if(srvTcp->tsk)
++			if(srvTcp->tsk) {
+ 				send_sig(SIGKILL,srvTcp->tsk,1);
++				wait_for_completion(&cifsd_complete);
++			}
+ 		}
+ 		 /* If find_unc succeeded then rc == 0 so we can not end */
+ 		if (tcon)  /* up accidently freeing someone elses tcon struct */
+@@ -1759,8 +1872,10 @@ cifs_mount(struct super_block *sb, struc
+ 					temp_rc = CIFSSMBLogoff(xid, pSesInfo);
+ 					/* if the socketUseCount is now zero */
+ 					if((temp_rc == -ESHUTDOWN) &&
+-					   (pSesInfo->server->tsk))
++					   (pSesInfo->server->tsk)) {
+ 						send_sig(SIGKILL,pSesInfo->server->tsk,1);
++						wait_for_completion(&cifsd_complete);
++					}
+ 				} else
+ 					cFYI(1, ("No session or bad tcon"));
+ 				sesInfoFree(pSesInfo);
+@@ -1783,8 +1898,27 @@ cifs_mount(struct super_block *sb, struc
+ 						cFYI(1,("server negotiated posix acl support"));
+ 						sb->s_flags |= MS_POSIXACL;
+ 				}
++
++				/* Try and negotiate POSIX pathnames if we can. */
++				if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP &
++				    le64_to_cpu(tcon->fsUnixInfo.Capability))) {
++					if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP))  {
++						cFYI(1,("negotiated posix pathnames support"));
++						cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
++					} else {
++						cFYI(1,("posix pathnames support requested but not supported"));
++					}
++				}
+ 			}
+ 		}
++		if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
++			cifs_sb->wsize = min(cifs_sb->wsize,
++					     (tcon->ses->server->maxBuf -
++					      MAX_CIFS_HDR_SIZE));
++		if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
++                        cifs_sb->rsize = min(cifs_sb->rsize,
++                                             (tcon->ses->server->maxBuf -
++                                              MAX_CIFS_HDR_SIZE));
+ 	}
+ 
+ 	/* volume_info.password is freed above when existing session found
+@@ -1832,6 +1966,7 @@ CIFSSessSetup(unsigned int xid, struct c
+ 	header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
+ 			NULL /* no tCon exists yet */ , 13 /* wct */ );
+ 
++	smb_buffer->Mid = GetNextMid(ses->server);
+ 	pSMB->req_no_secext.AndXCommand = 0xFF;
+ 	pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
+ 	pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
+@@ -2107,6 +2242,8 @@ CIFSSpnegoSessSetup(unsigned int xid, st
+ 	/* send SMBsessionSetup here */
+ 	header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
+ 			NULL /* no tCon exists yet */ , 12 /* wct */ );
++
++	smb_buffer->Mid = GetNextMid(ses->server);
+ 	pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
+ 	pSMB->req.AndXCommand = 0xFF;
+ 	pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
+@@ -2373,6 +2510,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned i
+ 	/* send SMBsessionSetup here */
+ 	header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
+ 			NULL /* no tCon exists yet */ , 12 /* wct */ );
++
++	smb_buffer->Mid = GetNextMid(ses->server);
+ 	pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
+ 	pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
+ 
+@@ -2715,6 +2854,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xi
+ 	/* send SMBsessionSetup here */
+ 	header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
+ 			NULL /* no tCon exists yet */ , 12 /* wct */ );
++
++	smb_buffer->Mid = GetNextMid(ses->server);
+ 	pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
+ 	pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
+ 	pSMB->req.AndXCommand = 0xFF;
+@@ -3086,6 +3227,8 @@ CIFSTCon(unsigned int xid, struct cifsSe
+ 
+ 	header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
+ 			NULL /*no tid */ , 4 /*wct */ );
++
++	smb_buffer->Mid = GetNextMid(ses->server);
+ 	smb_buffer->Uid = ses->Suid;
+ 	pSMB = (TCONX_REQ *) smb_buffer;
+ 	pSMBr = (TCONX_RSP *) smb_buffer_response;
+@@ -3207,8 +3350,10 @@ cifs_umount(struct super_block *sb, stru
+ 				return 0;
+ 			} else if (rc == -ESHUTDOWN) {
+ 				cFYI(1,("Waking up socket by sending it signal"));
+-				if(cifsd_task)
++				if(cifsd_task) {
+ 					send_sig(SIGKILL,cifsd_task,1);
++					wait_for_completion(&cifsd_complete);
++				}
+ 				rc = 0;
+ 			} /* else - we have an smb session
+ 				left on this socket do not kill cifsd */
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -48,6 +48,7 @@ build_path_from_dentry(struct dentry *di
+ 	struct dentry *temp;
+ 	int namelen = 0;
+ 	char *full_path;
++	char dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
+ 
+ 	if(direntry == NULL)
+ 		return NULL;  /* not much we can do if dentry is freed and
+@@ -74,7 +75,7 @@ cifs_bp_rename_retry:
+ 		if (namelen < 0) {
+ 			break;
+ 		} else {
+-			full_path[namelen] = '\\';
++			full_path[namelen] = dirsep;
+ 			strncpy(full_path + namelen + 1, temp->d_name.name,
+ 				temp->d_name.len);
+ 			cFYI(0, (" name: %s ", full_path + namelen));
+@@ -183,6 +184,13 @@ cifs_create(struct inode *inode, struct 
+ 			 desiredAccess, CREATE_NOT_DIR,
+ 			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
+ 			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
++	if(rc == -EIO) {
++		/* old server, retry the open legacy style */
++		rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
++			desiredAccess, CREATE_NOT_DIR,
++			&fileHandle, &oplock, buf, cifs_sb->local_nls,
++			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
++	} 
+ 	if (rc) {
+ 		cFYI(1, ("cifs_create returned 0x%x ", rc));
+ 	} else {
+@@ -208,7 +216,7 @@ cifs_create(struct inode *inode, struct 
+ 						CIFS_MOUNT_MAP_SPECIAL_CHR);
+ 			}
+ 		else {
+-			/* BB implement via Windows security descriptors */
++			/* BB implement mode setting via Windows security descriptors */
+ 			/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
+ 			/* could set r/o dos attribute if mode & 0222 == 0 */
+ 		}
+@@ -225,10 +233,14 @@ cifs_create(struct inode *inode, struct 
+ 		}
+ 
+ 		if (rc != 0) {
+-			cFYI(1,("Create worked but get_inode_info failed with rc = %d",
++			cFYI(1,
++			     ("Create worked but get_inode_info failed rc = %d",
+ 			      rc));
+ 		} else {
+-			direntry->d_op = &cifs_dentry_ops;
++			if (pTcon->nocase)
++				direntry->d_op = &cifs_ci_dentry_ops;
++			else
++				direntry->d_op = &cifs_dentry_ops;
+ 			d_instantiate(direntry, newinode);
+ 		}
+ 		if((nd->flags & LOOKUP_OPEN) == FALSE) {
+@@ -302,8 +314,7 @@ int cifs_mknod(struct inode *inode, stru
+ 	up(&direntry->d_sb->s_vfs_rename_sem);
+ 	if(full_path == NULL)
+ 		rc = -ENOMEM;
+-	
+-	if (full_path && (pTcon->ses->capabilities & CAP_UNIX)) {
++	else if (pTcon->ses->capabilities & CAP_UNIX) {
+ 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+ 			rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
+ 				mode,(__u64)current->euid,(__u64)current->egid,
+@@ -321,10 +332,49 @@ int cifs_mknod(struct inode *inode, stru
+ 		if(!rc) {
+ 			rc = cifs_get_inode_info_unix(&newinode, full_path,
+ 						inode->i_sb,xid);
+-			direntry->d_op = &cifs_dentry_ops;
++			if (pTcon->nocase)
++				direntry->d_op = &cifs_ci_dentry_ops;
++			else
++				direntry->d_op = &cifs_dentry_ops;
+ 			if(rc == 0)
+ 				d_instantiate(direntry, newinode);
+ 		}
++	} else {
++		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
++			int oplock = 0;
++			u16 fileHandle;
++			FILE_ALL_INFO * buf;
++
++			cFYI(1,("sfu compat create special file"));
++
++			buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
++			if(buf == NULL) {
++				kfree(full_path);
++				FreeXid(xid);
++				return -ENOMEM;
++			}
++
++			rc = CIFSSMBOpen(xid, pTcon, full_path,
++					 FILE_CREATE, /* fail if exists */
++					 GENERIC_WRITE /* BB would 
++					  WRITE_OWNER | WRITE_DAC be better? */,
++					 /* Create a file and set the
++					    file attribute to SYSTEM */
++					 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
++					 &fileHandle, &oplock, buf,
++					 cifs_sb->local_nls,
++					 cifs_sb->mnt_cifs_flags & 
++					    CIFS_MOUNT_MAP_SPECIAL_CHR);
++
++			if(!rc) {
++				/* BB Do not bother to decode buf since no
++				   local inode yet to put timestamps in */
++				CIFSSMBClose(xid, pTcon, fileHandle);
++				d_drop(direntry);
++			}
++			kfree(buf);
++			/* add code here to set EAs */
++		}
+ 	}
+ 
+ 	kfree(full_path);
+@@ -381,7 +431,10 @@ cifs_lookup(struct inode *parent_dir_ino
+ 					 parent_dir_inode->i_sb,xid);
+ 
+ 	if ((rc == 0) && (newInode != NULL)) {
+-		direntry->d_op = &cifs_dentry_ops;
++		if (pTcon->nocase)
++			direntry->d_op = &cifs_ci_dentry_ops;
++		else
++			direntry->d_op = &cifs_dentry_ops;
+ 		d_add(direntry, newInode);
+ 
+ 		/* since paths are not looked up by component - the parent directories are presumed to be good here */
+@@ -440,3 +493,42 @@ struct dentry_operations cifs_dentry_ops
+ /* d_delete:       cifs_d_delete,       *//* not needed except for debugging */
+ 	/* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */
+ };
++
++static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
++{
++	struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
++	unsigned long hash;
++	int i;
++
++	hash = init_name_hash();
++	for (i = 0; i < q->len; i++)
++		hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
++					 hash);
++	q->hash = end_name_hash(hash);
++
++	return 0;
++}
++
++static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
++			   struct qstr *b)
++{
++	struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
++
++	if ((a->len == b->len) &&
++	    (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) {
++		/*
++		 * To preserve case, don't let an existing negative dentry's
++		 * case take precedence.  If a is not a negative dentry, this
++		 * should have no side effects
++		 */
++		memcpy((unsigned char *)a->name, b->name, a->len);
++		return 0;
++	}
++	return 1;
++}
++
++struct dentry_operations cifs_ci_dentry_ops = {
++	.d_revalidate = cifs_d_revalidate,
++	.d_hash = cifs_ci_hash,
++	.d_compare = cifs_ci_compare,
++};
+diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
+--- a/fs/cifs/fcntl.c
++++ b/fs/cifs/fcntl.c
+@@ -78,6 +78,10 @@ int cifs_dir_notify(struct file * file, 
+ 	__u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
+ 	__u16 netfid;
+ 
++
++	if(experimEnabled == 0)
++		return 0;
++
+ 	xid = GetXid();
+ 	cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+ 	pTcon = cifs_sb->tcon;
+@@ -100,8 +104,10 @@ int cifs_dir_notify(struct file * file, 
+ 		} else {
+ 			filter = convert_to_cifs_notify_flags(arg);
+ 			if(filter != 0) {
+-				rc = CIFSSMBNotify(xid, pTcon, 0 /* no subdirs */, netfid, 
+-					filter, cifs_sb->local_nls);
++				rc = CIFSSMBNotify(xid, pTcon, 
++					0 /* no subdirs */, netfid,
++					filter, file, arg & DN_MULTISHOT,
++					cifs_sb->local_nls);
+ 			} else {
+ 				rc = -EINVAL;
+ 			}
+@@ -109,7 +115,7 @@ int cifs_dir_notify(struct file * file, 
+ 			it would close automatically but may be a way
+ 			to do it easily when inode freed or when
+ 			notify info is cleared/changed */
+-            cERROR(1,("notify rc %d",rc));
++			cFYI(1,("notify rc %d",rc));
+ 		}
+ 	}
+ 	
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -21,11 +21,15 @@
+  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+  */
+ #include <linux/fs.h>
++#include <linux/backing-dev.h>
+ #include <linux/stat.h>
+ #include <linux/fcntl.h>
++#include <linux/mpage.h>
+ #include <linux/pagemap.h>
+ #include <linux/pagevec.h>
+ #include <linux/smp_lock.h>
++#include <linux/writeback.h>
++#include <linux/delay.h>
+ #include <asm/div64.h>
+ #include "cifsfs.h"
+ #include "cifspdu.h"
+@@ -47,6 +51,11 @@ static inline struct cifsFileInfo *cifs_
+ 	private_data->pInode = inode;
+ 	private_data->invalidHandle = FALSE;
+ 	private_data->closePend = FALSE;
++	/* we have to track num writers to the inode, since writepages
++	does not tell us which handle the write is for so there can
++	be a close (overlapping with write) of the filehandle that
++	cifs_writepages chose to use */
++	atomic_set(&private_data->wrtPending,0); 
+ 
+ 	return private_data;
+ }
+@@ -256,6 +265,13 @@ int cifs_open(struct inode *inode, struc
+ 			 CREATE_NOT_DIR, &netfid, &oplock, buf,
+ 			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
+ 				 & CIFS_MOUNT_MAP_SPECIAL_CHR);
++	if (rc == -EIO) {
++		/* Old server, try legacy style OpenX */
++		rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
++			desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
++			cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
++				& CIFS_MOUNT_MAP_SPECIAL_CHR);
++	}
+ 	if (rc) {
+ 		cFYI(1, ("cifs_open returned 0x%x ", rc));
+ 		goto out;
+@@ -463,6 +479,20 @@ int cifs_close(struct inode *inode, stru
+ 			/* no sense reconnecting to close a file that is
+ 			   already closed */
+ 			if (pTcon->tidStatus != CifsNeedReconnect) {
++				int timeout = 2;
++				while((atomic_read(&pSMBFile->wrtPending) != 0)
++					 && (timeout < 1000) ) {
++					/* Give write a better chance to get to
++					server ahead of the close.  We do not
++					want to add a wait_q here as it would
++					increase the memory utilization as
++					the struct would be in each open file,
++					but this should give enough time to 
++					clear the socket */
++					cERROR(1,("close with pending writes"));
++					msleep(timeout);
++					timeout *= 4;
++				} 
+ 				write_unlock(&file->f_owner.lock);
+ 				rc = CIFSSMBClose(xid, pTcon,
+ 						  pSMBFile->netfid);
+@@ -744,14 +774,7 @@ ssize_t cifs_user_write(struct file *fil
+ 				    15 seconds is plenty */
+ 	}
+ 
+-#ifdef CONFIG_CIFS_STATS
+-	if (total_written > 0) {
+-		atomic_inc(&pTcon->num_writes);
+-		spin_lock(&pTcon->stat_lock);
+-		pTcon->bytes_written += total_written;
+-		spin_unlock(&pTcon->stat_lock);
+-	}
+-#endif		
++	cifs_stats_bytes_written(pTcon, total_written);
+ 
+ 	/* since the write may have blocked check these pointers again */
+ 	if (file->f_dentry) {
+@@ -791,9 +814,8 @@ static ssize_t cifs_write(struct file *f
+ 
+ 	pTcon = cifs_sb->tcon;
+ 
+-	/* cFYI(1,
+-	   (" write %d bytes to offset %lld of %s", write_size,
+-	   *poffset, file->f_dentry->d_name.name)); */
++	cFYI(1,("write %zd bytes to offset %lld of %s", write_size,
++	   *poffset, file->f_dentry->d_name.name));
+ 
+ 	if (file->private_data == NULL)
+ 		return -EBADF;
+@@ -846,7 +868,26 @@ static ssize_t cifs_write(struct file *f
+ 				if (rc != 0)
+ 					break;
+ 			}
+-
++#ifdef CONFIG_CIFS_EXPERIMENTAL
++			/* BB FIXME We can not sign across two buffers yet */
++			if((experimEnabled) && ((pTcon->ses->server->secMode & 
++			 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) {
++				struct kvec iov[2];
++				unsigned int len;
++
++				len = min((size_t)cifs_sb->wsize,
++					  write_size - total_written);
++				/* iov[0] is reserved for smb header */
++				iov[1].iov_base = (char *)write_data +
++						  total_written;
++				iov[1].iov_len = len;
++				rc = CIFSSMBWrite2(xid, pTcon,
++						open_file->netfid, len,
++						*poffset, &bytes_written,
++						iov, 1, long_op);
++			} else
++			/* BB FIXME fixup indentation of line below */
++#endif			
+ 			rc = CIFSSMBWrite(xid, pTcon,
+ 				 open_file->netfid,
+ 				 min_t(const int, cifs_sb->wsize, 
+@@ -867,14 +908,7 @@ static ssize_t cifs_write(struct file *f
+ 				    15 seconds is plenty */
+ 	}
+ 
+-#ifdef CONFIG_CIFS_STATS
+-	if (total_written > 0) {
+-		atomic_inc(&pTcon->num_writes);
+-		spin_lock(&pTcon->stat_lock);
+-		pTcon->bytes_written += total_written;
+-		spin_unlock(&pTcon->stat_lock);
+-	}
+-#endif		
++	cifs_stats_bytes_written(pTcon, total_written);
+ 
+ 	/* since the write may have blocked check these pointers again */
+ 	if (file->f_dentry) {
+@@ -893,6 +927,43 @@ static ssize_t cifs_write(struct file *f
+ 	return total_written;
+ }
+ 
++struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
++{
++	struct cifsFileInfo *open_file;
++	int rc;
++
++	read_lock(&GlobalSMBSeslock);
++	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
++		if (open_file->closePend)
++			continue;
++		if (open_file->pfile &&
++		    ((open_file->pfile->f_flags & O_RDWR) ||
++		     (open_file->pfile->f_flags & O_WRONLY))) {
++			atomic_inc(&open_file->wrtPending);
++			read_unlock(&GlobalSMBSeslock);
++			if((open_file->invalidHandle) && 
++			   (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
++				rc = cifs_reopen_file(&cifs_inode->vfs_inode, 
++						      open_file->pfile, FALSE);
++				/* if it fails, try another handle - might be */
++				/* dangerous to hold up writepages with retry */
++				if(rc) {
++					cFYI(1,("failed on reopen file in wp"));
++					read_lock(&GlobalSMBSeslock);
++					/* can not use this handle, no write
++					pending on this one after all */
++					atomic_dec
++					     (&open_file->wrtPending);
++					continue;
++				}
++			}
++			return open_file;
++		}
++	}
++	read_unlock(&GlobalSMBSeslock);
++	return NULL;
++}
++
+ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
+ {
+ 	struct address_space *mapping = page->mapping;
+@@ -903,10 +974,7 @@ static int cifs_partialpagewrite(struct 
+ 	struct cifs_sb_info *cifs_sb;
+ 	struct cifsTconInfo *pTcon;
+ 	struct inode *inode;
+-	struct cifsInodeInfo *cifsInode;
+-	struct cifsFileInfo *open_file = NULL;
+-	struct list_head *tmp;
+-	struct list_head *tmp1;
++	struct cifsFileInfo *open_file;
+ 
+ 	if (!mapping || !mapping->host)
+ 		return -EFAULT;
+@@ -934,49 +1002,20 @@ static int cifs_partialpagewrite(struct 
+ 	if (mapping->host->i_size - offset < (loff_t)to)
+ 		to = (unsigned)(mapping->host->i_size - offset); 
+ 
+-	cifsInode = CIFS_I(mapping->host);
+-	read_lock(&GlobalSMBSeslock); 
+-	/* BB we should start at the end */
+-	list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {            
+-		open_file = list_entry(tmp, struct cifsFileInfo, flist);
+-		if (open_file->closePend)
+-			continue;
+-		/* We check if file is open for writing first */
+-		if ((open_file->pfile) && 
+-		   ((open_file->pfile->f_flags & O_RDWR) || 
+-			(open_file->pfile->f_flags & O_WRONLY))) {
+-			read_unlock(&GlobalSMBSeslock);
+-			bytes_written = cifs_write(open_file->pfile,
+-						write_data, to-from,
+-						&offset);
+-			read_lock(&GlobalSMBSeslock);
++	open_file = find_writable_file(CIFS_I(mapping->host));
++	if (open_file) {
++		bytes_written = cifs_write(open_file->pfile, write_data,
++					   to-from, &offset);
++		atomic_dec(&open_file->wrtPending);
+ 		/* Does mm or vfs already set times? */
+-			inode->i_atime = 
+-			inode->i_mtime = current_fs_time(inode->i_sb);
+-			if ((bytes_written > 0) && (offset)) {
+-				rc = 0;
+-			} else if (bytes_written < 0) {
+-				if (rc == -EBADF) {
+-				/* have seen a case in which kernel seemed to
+-				   have closed/freed a file even with writes
+-				   active so we might as well see if there are
+-				   other file structs to try for the same
+-				   inode before giving up */
+-					continue;
+-				} else
+-					rc = bytes_written;
+-			}
+-			break;  /* now that we found a valid file handle and
+-				   tried to write to it we are done, no sense
+-				   continuing to loop looking for another */
+-		}
+-		if (tmp->next == NULL) {
+-			cFYI(1, ("File instance %p removed", tmp));
+-			break;
++		inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
++		if ((bytes_written > 0) && (offset)) {
++			rc = 0;
++		} else if (bytes_written < 0) {
++			if (rc != -EBADF)
++				rc = bytes_written;
+ 		}
+-	}
+-	read_unlock(&GlobalSMBSeslock);
+-	if (open_file == NULL) {
++	} else {
+ 		cFYI(1, ("No writeable filehandles for inode"));
+ 		rc = -EIO;
+ 	}
+@@ -985,20 +1024,207 @@ static int cifs_partialpagewrite(struct 
+ 	return rc;
+ }
+ 
+-#if 0
++#ifdef CONFIG_CIFS_EXPERIMENTAL
+ static int cifs_writepages(struct address_space *mapping,
+-	struct writeback_control *wbc)
++			   struct writeback_control *wbc)
+ {
+-	int rc = -EFAULT;
++	struct backing_dev_info *bdi = mapping->backing_dev_info;
++	unsigned int bytes_to_write;
++	unsigned int bytes_written;
++	struct cifs_sb_info *cifs_sb;
++	int done = 0;
++	pgoff_t end = -1;
++	pgoff_t index;
++	int is_range = 0;
++	struct kvec iov[32];
++	int len;
++	int n_iov = 0;
++	pgoff_t next;
++	int nr_pages;
++	__u64 offset = 0;
++	struct cifsFileInfo *open_file;
++	struct page *page;
++	struct pagevec pvec;
++	int rc = 0;
++	int scanned = 0;
+ 	int xid;
+ 
++	cifs_sb = CIFS_SB(mapping->host->i_sb);
++	
++	/*
++	 * If wsize is smaller that the page cache size, default to writing
++	 * one page at a time via cifs_writepage
++	 */
++	if (cifs_sb->wsize < PAGE_CACHE_SIZE)
++		return generic_writepages(mapping, wbc);
++
++	/* BB FIXME we do not have code to sign across multiple buffers yet,
++	   so go to older writepage style write which we can sign if needed */
++	if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
++		if(cifs_sb->tcon->ses->server->secMode &
++                          (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
++			return generic_writepages(mapping, wbc);
++
++	/*
++	 * BB: Is this meaningful for a non-block-device file system?
++	 * If it is, we should test it again after we do I/O
++	 */
++	if (wbc->nonblocking && bdi_write_congested(bdi)) {
++		wbc->encountered_congestion = 1;
++		return 0;
++	}
++
+ 	xid = GetXid();
+ 
+-	/* Find contiguous pages then iterate through repeating
+-	   call 16K write then Setpageuptodate or if LARGE_WRITE_X
+-	   support then send larger writes via kevec so as to eliminate
+-	   a memcpy */
++	pagevec_init(&pvec, 0);
++	if (wbc->sync_mode == WB_SYNC_NONE)
++		index = mapping->writeback_index; /* Start from prev offset */
++	else {
++		index = 0;
++		scanned = 1;
++	}
++	if (wbc->start || wbc->end) {
++		index = wbc->start >> PAGE_CACHE_SHIFT;
++		end = wbc->end >> PAGE_CACHE_SHIFT;
++		is_range = 1;
++		scanned = 1;
++	}
++retry:
++	while (!done && (index <= end) &&
++	       (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
++			PAGECACHE_TAG_DIRTY,
++			min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) {
++		int first;
++		unsigned int i;
++
++		first = -1;
++		next = 0;
++		n_iov = 0;
++		bytes_to_write = 0;
++
++		for (i = 0; i < nr_pages; i++) {
++			page = pvec.pages[i];
++			/*
++			 * At this point we hold neither mapping->tree_lock nor
++			 * lock on the page itself: the page may be truncated or
++			 * invalidated (changing page->mapping to NULL), or even
++			 * swizzled back from swapper_space to tmpfs file
++			 * mapping
++			 */
++
++			if (first < 0)
++				lock_page(page);
++			else if (TestSetPageLocked(page))
++				break;
++
++			if (unlikely(page->mapping != mapping)) {
++				unlock_page(page);
++				break;
++			}
++
++			if (unlikely(is_range) && (page->index > end)) {
++				done = 1;
++				unlock_page(page);
++				break;
++			}
++
++			if (next && (page->index != next)) {
++				/* Not next consecutive page */
++				unlock_page(page);
++				break;
++			}
++
++			if (wbc->sync_mode != WB_SYNC_NONE)
++				wait_on_page_writeback(page);
++
++			if (PageWriteback(page) ||
++					!test_clear_page_dirty(page)) {
++				unlock_page(page);
++				break;
++			}
++
++			if (page_offset(page) >= mapping->host->i_size) {
++				done = 1;
++				unlock_page(page);
++				break;
++			}
++
++			/*
++			 * BB can we get rid of this?  pages are held by pvec
++			 */
++			page_cache_get(page);
++
++			len = min(mapping->host->i_size - page_offset(page),
++				  (loff_t)PAGE_CACHE_SIZE);
++
++			/* reserve iov[0] for the smb header */
++			n_iov++;
++			iov[n_iov].iov_base = kmap(page);
++			iov[n_iov].iov_len = len;
++			bytes_to_write += len;
++
++			if (first < 0) {
++				first = i;
++				offset = page_offset(page);
++			}
++			next = page->index + 1;
++			if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)
++				break;
++		}
++		if (n_iov) {
++			/* Search for a writable handle every time we call
++			 * CIFSSMBWrite2.  We can't rely on the last handle
++			 * we used to still be valid
++			 */
++			open_file = find_writable_file(CIFS_I(mapping->host));
++			if (!open_file) {
++				cERROR(1, ("No writable handles for inode"));
++				rc = -EBADF;
++			} else {
++				rc = CIFSSMBWrite2(xid, cifs_sb->tcon,
++						   open_file->netfid,
++						   bytes_to_write, offset,
++						   &bytes_written, iov, n_iov,
++						   1);
++				atomic_dec(&open_file->wrtPending);
++				if (rc || bytes_written < bytes_to_write) {
++					cERROR(1,("Write2 ret %d, written = %d",
++						  rc, bytes_written));
++					/* BB what if continued retry is
++					   requested via mount flags? */
++					set_bit(AS_EIO, &mapping->flags);
++					SetPageError(page);
++				} else {
++					cifs_stats_bytes_written(cifs_sb->tcon,
++								 bytes_written);
++				}
++			}
++			for (i = 0; i < n_iov; i++) {
++				page = pvec.pages[first + i];
++				kunmap(page);
++				unlock_page(page);
++				page_cache_release(page);
++			}
++			if ((wbc->nr_to_write -= n_iov) <= 0)
++				done = 1;
++			index = next;
++		}
++		pagevec_release(&pvec);
++	}
++	if (!scanned && !done) {
++		/*
++		 * We hit the last page and there is more work to be done: wrap
++		 * back to the start of the file
++		 */
++		scanned = 1;
++		index = 0;
++		goto retry;
++	}
++	if (!is_range)
++		mapping->writeback_index = index;
++
+ 	FreeXid(xid);
++
+ 	return rc;
+ }
+ #endif
+@@ -1207,12 +1433,10 @@ ssize_t cifs_user_read(struct file *file
+ 				if (rc != 0)
+ 					break;
+ 			}
+-
+ 			rc = CIFSSMBRead(xid, pTcon,
+-				 open_file->netfid,
+-				 current_read_size, *poffset,
+-				 &bytes_read, &smb_read_data);
+-
++					open_file->netfid,
++					current_read_size, *poffset,
++					&bytes_read, &smb_read_data);
+ 			pSMBr = (struct smb_com_read_rsp *)smb_read_data;
+ 			if (copy_to_user(current_offset, 
+ 					 smb_read_data + 4 /* RFC1001 hdr */
+@@ -1235,12 +1459,7 @@ ssize_t cifs_user_read(struct file *file
+ 				return rc;
+ 			}
+ 		} else {
+-#ifdef CONFIG_CIFS_STATS
+-			atomic_inc(&pTcon->num_reads);
+-			spin_lock(&pTcon->stat_lock);
+-			pTcon->bytes_read += total_read;
+-			spin_unlock(&pTcon->stat_lock);
+-#endif
++			cifs_stats_bytes_read(pTcon, bytes_read);
+ 			*poffset += bytes_read;
+ 		}
+ 	}
+@@ -1280,6 +1499,13 @@ static ssize_t cifs_read(struct file *fi
+ 	     total_read += bytes_read, current_offset += bytes_read) {
+ 		current_read_size = min_t(const int, read_size - total_read,
+ 					  cifs_sb->rsize);
++		/* For windows me and 9x we do not want to request more
++		than it negotiated since it will refuse the read then */
++		if((pTcon->ses) && 
++			!(pTcon->ses->capabilities & CAP_LARGE_FILES)) {
++			current_read_size = min_t(const int, current_read_size,
++					pTcon->ses->server->maxBuf - 128);
++		}
+ 		rc = -EAGAIN;
+ 		while (rc == -EAGAIN) {
+ 			if ((open_file->invalidHandle) && 
+@@ -1289,11 +1515,10 @@ static ssize_t cifs_read(struct file *fi
+ 				if (rc != 0)
+ 					break;
+ 			}
+-
+ 			rc = CIFSSMBRead(xid, pTcon,
+-				 open_file->netfid,
+-				 current_read_size, *poffset,
+-				 &bytes_read, &current_offset);
++					open_file->netfid,
++					current_read_size, *poffset,
++					&bytes_read, &current_offset);
+ 		}
+ 		if (rc || (bytes_read == 0)) {
+ 			if (total_read) {
+@@ -1303,12 +1528,7 @@ static ssize_t cifs_read(struct file *fi
+ 				return rc;
+ 			}
+ 		} else {
+-#ifdef CONFIG_CIFS_STATS
+-			atomic_inc(&pTcon->num_reads);
+-			spin_lock(&pTcon->stat_lock);
+-			pTcon->bytes_read += total_read;
+-			spin_unlock(&pTcon->stat_lock);
+-#endif
++			cifs_stats_bytes_read(pTcon, total_read);
+ 			*poffset += bytes_read;
+ 		}
+ 	}
+@@ -1452,10 +1672,11 @@ static int cifs_readpages(struct file *f
+ 			}
+ 
+ 			rc = CIFSSMBRead(xid, pTcon,
+-				open_file->netfid,
+-				read_size, offset,
+-				&bytes_read, &smb_read_data);
+-			/* BB need to check return code here */
++					open_file->netfid,
++					read_size, offset,
++					&bytes_read, &smb_read_data);
++
++			/* BB more RC checks ? */
+ 			if (rc== -EAGAIN) {
+ 				if (smb_read_data) {
+ 					cifs_buf_release(smb_read_data);
+@@ -1480,12 +1701,7 @@ static int cifs_readpages(struct file *f
+ 				le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
+ 
+ 			i +=  bytes_read >> PAGE_CACHE_SHIFT;
+-#ifdef CONFIG_CIFS_STATS
+-			atomic_inc(&pTcon->num_reads);
+-			spin_lock(&pTcon->stat_lock);
+-			pTcon->bytes_read += bytes_read;
+-			spin_unlock(&pTcon->stat_lock);
+-#endif
++			cifs_stats_bytes_read(pTcon, bytes_read);
+ 			if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
+ 				i++; /* account for partial page */
+ 
+@@ -1603,40 +1819,21 @@ static int cifs_readpage(struct file *fi
+    page caching in the current Linux kernel design */
+ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode)
+ {
+-	struct list_head *tmp;
+-	struct list_head *tmp1;
+ 	struct cifsFileInfo *open_file = NULL;
+-	int rc = TRUE;
+ 
+-	if (cifsInode == NULL)
+-		return rc;
+-
+-	read_lock(&GlobalSMBSeslock); 
+-	list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {            
+-		open_file = list_entry(tmp, struct cifsFileInfo, flist);
+-		if (open_file == NULL)
+-			break;
+-		if (open_file->closePend)
+-			continue;
+-	/* We check if file is open for writing,   
+-	   BB we could supplement this with a check to see if file size
+-	   changes have been flushed to server - ie inode metadata dirty */
+-		if ((open_file->pfile) && 
+-		    ((open_file->pfile->f_flags & O_RDWR) || 
+-		    (open_file->pfile->f_flags & O_WRONLY))) {
+-			rc = FALSE;
+-			break;
+-		}
+-		if (tmp->next == NULL) {
+-			cFYI(1, ("File instance %p removed", tmp));
+-			break;
+-		}
+-	}
+-	read_unlock(&GlobalSMBSeslock);
+-	return rc;
++	if (cifsInode)
++		open_file =  find_writable_file(cifsInode);
++ 
++	if(open_file) {
++		/* there is not actually a write pending so let
++		this handle go free and allow it to
++		be closable if needed */
++		atomic_dec(&open_file->wrtPending);
++		return 0;
++	} else
++		return 1;
+ }
+ 
+-
+ static int cifs_prepare_write(struct file *file, struct page *page,
+ 	unsigned from, unsigned to)
+ {
+@@ -1676,6 +1873,9 @@ struct address_space_operations cifs_add
+ 	.readpage = cifs_readpage,
+ 	.readpages = cifs_readpages,
+ 	.writepage = cifs_writepage,
++#ifdef CONFIG_CIFS_EXPERIMENTAL
++	.writepages = cifs_writepages,
++#endif
+ 	.prepare_write = cifs_prepare_write,
+ 	.commit_write = cifs_commit_write,
+ 	.set_page_dirty = __set_page_dirty_nobuffers,
+diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -166,7 +166,13 @@ int cifs_get_inode_info_unix(struct inod
+ 				inode->i_fop = &cifs_file_direct_ops;
+ 			else
+ 				inode->i_fop = &cifs_file_ops;
++			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
++				inode->i_fop->lock = NULL;
+ 			inode->i_data.a_ops = &cifs_addr_ops;
++			/* check if server can support readpages */
++			if(pTcon->ses->server->maxBuf < 
++			    4096 + MAX_CIFS_HDR_SIZE)
++				inode->i_data.a_ops->readpages = NULL;
+ 		} else if (S_ISDIR(inode->i_mode)) {
+ 			cFYI(1, (" Directory inode"));
+ 			inode->i_op = &cifs_dir_inode_ops;
+@@ -213,8 +219,18 @@ int cifs_get_inode_info(struct inode **p
+ 		pfindData = (FILE_ALL_INFO *)buf;
+ 		/* could do find first instead but this returns more info */
+ 		rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
+-			      cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 
++			      cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
+ 				CIFS_MOUNT_MAP_SPECIAL_CHR);
++		/* BB optimize code so we do not make the above call
++		when server claims no NT SMB support and the above call
++		failed at least once - set flag in tcon or mount */
++		if((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
++			rc = SMBQueryInformation(xid, pTcon, search_path,
++					pfindData, cifs_sb->local_nls, 
++					cifs_sb->mnt_cifs_flags &
++					  CIFS_MOUNT_MAP_SPECIAL_CHR);
++		}
++		
+ 	}
+ 	/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
+ 	if (rc) {
+@@ -320,6 +336,16 @@ int cifs_get_inode_info(struct inode **p
+ 		   on dirs */
+ 			inode->i_mode = cifs_sb->mnt_dir_mode;
+ 			inode->i_mode |= S_IFDIR;
++		} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
++			   (cifsInfo->cifsAttrs & ATTR_SYSTEM) &&
++			   /* No need to le64 convert size of zero */
++			   (pfindData->EndOfFile == 0)) {
++			inode->i_mode = cifs_sb->mnt_file_mode;
++			inode->i_mode |= S_IFIFO;
++/* BB Finish for SFU style symlinks and devies */
++/*		} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
++			   (cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */
++
+ 		} else {
+ 			inode->i_mode |= S_IFREG;
+ 			/* treat the dos attribute of read-only as read-only
+@@ -359,7 +385,12 @@ int cifs_get_inode_info(struct inode **p
+ 				inode->i_fop = &cifs_file_direct_ops;
+ 			else
+ 				inode->i_fop = &cifs_file_ops;
++			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
++				inode->i_fop->lock = NULL;
+ 			inode->i_data.a_ops = &cifs_addr_ops;
++			if(pTcon->ses->server->maxBuf < 
++			     4096 + MAX_CIFS_HDR_SIZE)
++				inode->i_data.a_ops->readpages = NULL;
+ 		} else if (S_ISDIR(inode->i_mode)) {
+ 			cFYI(1, (" Directory inode "));
+ 			inode->i_op = &cifs_dir_inode_ops;
+@@ -577,7 +608,10 @@ int cifs_mkdir(struct inode *inode, stru
+ 			rc = cifs_get_inode_info(&newinode, full_path, NULL,
+ 						 inode->i_sb,xid);
+ 
+-		direntry->d_op = &cifs_dentry_ops;
++		if (pTcon->nocase)
++			direntry->d_op = &cifs_ci_dentry_ops;
++		else
++			direntry->d_op = &cifs_dentry_ops;
+ 		d_instantiate(direntry, newinode);
+ 		if (direntry->d_inode)
+ 			direntry->d_inode->i_nlink = 2;
+@@ -928,7 +962,6 @@ int cifs_setattr(struct dentry *direntry
+ 	struct cifsTconInfo *pTcon;
+ 	char *full_path = NULL;
+ 	int rc = -EACCES;
+-	int found = FALSE;
+ 	struct cifsFileInfo *open_file = NULL;
+ 	FILE_BASIC_INFO time_buf;
+ 	int set_time = FALSE;
+@@ -936,7 +969,6 @@ int cifs_setattr(struct dentry *direntry
+ 	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
+ 	__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
+ 	struct cifsInodeInfo *cifsInode;
+-	struct list_head *tmp;
+ 
+ 	xid = GetXid();
+ 
+@@ -961,7 +993,6 @@ int cifs_setattr(struct dentry *direntry
+ 	filemap_fdatawait(direntry->d_inode->i_mapping);
+ 
+ 	if (attrs->ia_valid & ATTR_SIZE) {
+-		read_lock(&GlobalSMBSeslock);
+ 		/* To avoid spurious oplock breaks from server, in the case of
+ 		   inodes that we already have open, avoid doing path based
+ 		   setting of file size if we can do it by handle.
+@@ -969,40 +1000,23 @@ int cifs_setattr(struct dentry *direntry
+ 		   when the local oplock break takes longer to flush
+ 		   writebehind data than the SMB timeout for the SetPathInfo
+ 		   request would allow */
+-		list_for_each(tmp, &cifsInode->openFileList) {
+-			open_file = list_entry(tmp, struct cifsFileInfo,
+-					       flist);
+-			/* We check if file is open for writing first */
+-			if ((open_file->pfile) &&
+-			    ((open_file->pfile->f_flags & O_RDWR) ||
+-			    (open_file->pfile->f_flags & O_WRONLY))) {
+-				if (open_file->invalidHandle == FALSE) {
+-					/* we found a valid, writeable network
+-					   file handle to use to try to set the
+-					   file size */
+-					__u16 nfid = open_file->netfid;
+-					__u32 npid = open_file->pid;
+-					read_unlock(&GlobalSMBSeslock);
+-					found = TRUE;
+-					rc = CIFSSMBSetFileSize(xid, pTcon,
+-						attrs->ia_size, nfid, npid,
+-						FALSE);
+-					cFYI(1, ("SetFileSize by handle "
+-						 "(setattrs) rc = %d", rc));
+-					/* Do not need reopen and retry on
+-					   EAGAIN since we will retry by
+-					   pathname below */
+-
+-					/* now that we found one valid file
+-					   handle no sense continuing to loop
+-					   trying others, so break here */
+-					break;
+-				}
++		open_file = find_writable_file(cifsInode);
++		if (open_file) {
++			__u16 nfid = open_file->netfid;
++			__u32 npid = open_file->pid;
++			rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
++						nfid, npid, FALSE);
++			atomic_dec(&open_file->wrtPending);
++			cFYI(1,("SetFSize for attrs rc = %d", rc));
++			if(rc == -EINVAL) {
++				int bytes_written;
++				rc = CIFSSMBWrite(xid, pTcon,
++						  nfid, 0, attrs->ia_size,
++						  &bytes_written, NULL, NULL,
++						  1 /* 45 seconds */);
++				cFYI(1,("Wrt seteof rc %d", rc));
+ 			}
+ 		}
+-		if (found == FALSE)
+-			read_unlock(&GlobalSMBSeslock);
+-
+ 		if (rc != 0) {
+ 			/* Set file size by pathname rather than by handle
+ 			   either because no valid, writeable file handle for
+@@ -1013,7 +1027,30 @@ int cifs_setattr(struct dentry *direntry
+ 					   cifs_sb->local_nls, 
+ 					   cifs_sb->mnt_cifs_flags &
+ 						CIFS_MOUNT_MAP_SPECIAL_CHR);
+-			cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc));
++			cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
++			if(rc == -EINVAL) {
++				__u16 netfid;
++				int oplock = FALSE;
++
++				rc = SMBLegacyOpen(xid, pTcon, full_path,
++					FILE_OPEN,
++					SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
++					CREATE_NOT_DIR, &netfid, &oplock,
++					NULL, cifs_sb->local_nls,
++					cifs_sb->mnt_cifs_flags &
++						CIFS_MOUNT_MAP_SPECIAL_CHR);
++				if (rc==0) {
++					int bytes_written;
++					rc = CIFSSMBWrite(xid, pTcon,
++							netfid, 0,
++							attrs->ia_size,
++							&bytes_written, NULL,
++							NULL, 1 /* 45 sec */);
++					cFYI(1,("wrt seteof rc %d",rc));
++					CIFSSMBClose(xid, pTcon, netfid);
++				}
++
++			}
+ 		}
+ 
+ 		/* Server is ok setting allocation size implicitly - no need
+@@ -1026,24 +1063,22 @@ int cifs_setattr(struct dentry *direntry
+ 			rc = vmtruncate(direntry->d_inode, attrs->ia_size);
+ 			cifs_truncate_page(direntry->d_inode->i_mapping,
+ 					   direntry->d_inode->i_size);
+-		}
++		} else 
++			goto cifs_setattr_exit;
+ 	}
+ 	if (attrs->ia_valid & ATTR_UID) {
+-		cFYI(1, (" CIFS - UID changed to %d", attrs->ia_uid));
++		cFYI(1, ("UID changed to %d", attrs->ia_uid));
+ 		uid = attrs->ia_uid;
+-		/* entry->uid = cpu_to_le16(attr->ia_uid); */
+ 	}
+ 	if (attrs->ia_valid & ATTR_GID) {
+-		cFYI(1, (" CIFS - GID changed to %d", attrs->ia_gid));
++		cFYI(1, ("GID changed to %d", attrs->ia_gid));
+ 		gid = attrs->ia_gid;
+-		/* entry->gid = cpu_to_le16(attr->ia_gid); */
+ 	}
+ 
+ 	time_buf.Attributes = 0;
+ 	if (attrs->ia_valid & ATTR_MODE) {
+-		cFYI(1, (" CIFS - Mode changed to 0x%x", attrs->ia_mode));
++		cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
+ 		mode = attrs->ia_mode;
+-		/* entry->mode = cpu_to_le16(attr->ia_mode); */
+ 	}
+ 
+ 	if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
+@@ -1083,18 +1118,24 @@ int cifs_setattr(struct dentry *direntry
+ 		    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
+ 	} else
+ 		time_buf.LastWriteTime = 0;
+-
+-	if (attrs->ia_valid & ATTR_CTIME) {
++	/* Do not set ctime explicitly unless other time
++	   stamps are changed explicitly (i.e. by utime()
++	   since we would then have a mix of client and
++	   server times */
++	   
++	if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
+ 		set_time = TRUE;
+-		cFYI(1, (" CIFS - CTIME changed ")); /* BB probably no need */
++		/* Although Samba throws this field away
++		it may be useful to Windows - but we do
++		not want to set ctime unless some other
++		timestamp is changing */
++		cFYI(1, ("CIFS - CTIME changed "));
+ 		time_buf.ChangeTime =
+ 		    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
+ 	} else
+ 		time_buf.ChangeTime = 0;
+ 
+ 	if (set_time || time_buf.Attributes) {
+-		/* BB what if setting one attribute fails (such as size) but
+-		   time setting works? */
+ 		time_buf.CreationTime = 0;	/* do not change */
+ 		/* In the future we should experiment - try setting timestamps
+ 		   via Handle (SetFileInfo) instead of by path */
+@@ -1133,12 +1174,21 @@ int cifs_setattr(struct dentry *direntry
+         	        		&time_buf, cifs_sb->local_nls); */
+ 			}
+ 		}
++		/* Even if error on time set, no sense failing the call if
++		the server would set the time to a reasonable value anyway,
++		and this check ensures that we are not being called from
++		sys_utimes in which case we ought to fail the call back to
++		the user when the server rejects the call */
++		if((rc) && (attrs->ia_valid &&
++			 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
++			rc = 0;
+ 	}
+ 
+ 	/* do not need local check to inode_check_ok since the server does
+ 	   that */
+ 	if (!rc)
+ 		rc = inode_setattr(direntry->d_inode, attrs);
++cifs_setattr_exit:
+ 	kfree(full_path);
+ 	FreeXid(xid);
+ 	return rc;
+diff --git a/fs/cifs/link.c b/fs/cifs/link.c
+--- a/fs/cifs/link.c
++++ b/fs/cifs/link.c
+@@ -198,7 +198,10 @@ cifs_symlink(struct inode *inode, struct
+ 			     ("Create symlink worked but get_inode_info failed with rc = %d ",
+ 			      rc));
+ 		} else {
+-			direntry->d_op = &cifs_dentry_ops;
++			if (pTcon->nocase)
++				direntry->d_op = &cifs_ci_dentry_ops;
++			else
++				direntry->d_op = &cifs_dentry_ops;
+ 			d_instantiate(direntry, newinode);
+ 		}
+ 	}
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -34,8 +34,6 @@ extern mempool_t *cifs_sm_req_poolp;
+ extern mempool_t *cifs_req_poolp;
+ extern struct task_struct * oplockThread;
+ 
+-static __u16 GlobalMid;		/* multiplex id - rotating counter */
+-
+ /* The xid serves as a useful identifier for each incoming vfs request, 
+    in a similar way to the mid which is useful to track each sent smb, 
+    and CurrentXid can also provide a running counter (although it 
+@@ -51,6 +49,8 @@ _GetXid(void)
+ 	GlobalTotalActiveXid++;
+ 	if (GlobalTotalActiveXid > GlobalMaxActiveXid)
+ 		GlobalMaxActiveXid = GlobalTotalActiveXid;	/* keep high water mark for number of simultaneous vfs ops in our filesystem */
++	if(GlobalTotalActiveXid > 65000)
++		cFYI(1,("warning: more than 65000 requests active"));
+ 	xid = GlobalCurrentXid++;
+ 	spin_unlock(&GlobalMid_Lock);
+ 	return xid;
+@@ -218,6 +218,76 @@ cifs_small_buf_release(void *buf_to_free
+ 	return;
+ }
+ 
++/* 
++	Find a free multiplex id (SMB mid). Otherwise there could be
++	mid collisions which might cause problems, demultiplexing the
++	wrong response to this request. Multiplex ids could collide if
++	one of a series requests takes much longer than the others, or
++	if a very large number of long lived requests (byte range
++	locks or FindNotify requests) are pending.  No more than
++	64K-1 requests can be outstanding at one time.  If no 
++	mids are available, return zero.  A future optimization
++	could make the combination of mids and uid the key we use
++	to demultiplex on (rather than mid alone).  
++	In addition to the above check, the cifs demultiplex
++	code already used the command code as a secondary
++	check of the frame and if signing is negotiated the
++	response would be discarded if the mid were the same
++	but the signature was wrong.  Since the mid is not put in the
++	pending queue until later (when it is about to be dispatched)
++	we do have to limit the number of outstanding requests 
++	to somewhat less than 64K-1 although it is hard to imagine
++	so many threads being in the vfs at one time.
++*/
++__u16 GetNextMid(struct TCP_Server_Info *server)
++{
++	__u16 mid = 0;
++	__u16 last_mid;
++	int   collision;  
++
++	if(server == NULL)
++		return mid;
++
++	spin_lock(&GlobalMid_Lock);
++	last_mid = server->CurrentMid; /* we do not want to loop forever */
++	server->CurrentMid++;
++	/* This nested loop looks more expensive than it is.
++	In practice the list of pending requests is short, 
++	fewer than 50, and the mids are likely to be unique
++	on the first pass through the loop unless some request
++	takes longer than the 64 thousand requests before it
++	(and it would also have to have been a request that
++	 did not time out) */
++	while(server->CurrentMid != last_mid) {
++		struct list_head *tmp;
++		struct mid_q_entry *mid_entry;
++
++		collision = 0;
++		if(server->CurrentMid == 0)
++			server->CurrentMid++;
++
++		list_for_each(tmp, &server->pending_mid_q) {
++			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
++
++			if ((mid_entry->mid == server->CurrentMid) &&
++			    (mid_entry->midState == MID_REQUEST_SUBMITTED)) {
++				/* This mid is in use, try a different one */
++				collision = 1;
++				break;
++			}
++		}
++		if(collision == 0) {
++			mid = server->CurrentMid;
++			break;
++		}
++		server->CurrentMid++;
++	}
++	spin_unlock(&GlobalMid_Lock);
++	return mid;
++}
++
++/* NB: MID can not be set if treeCon not passed in, in that
++   case it is responsbility of caller to set the mid */
+ void
+ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
+ 		const struct cifsTconInfo *treeCon, int word_count
+@@ -233,7 +303,8 @@ header_assemble(struct smb_hdr *buffer, 
+ 	    (2 * word_count) + sizeof (struct smb_hdr) -
+ 	    4 /*  RFC 1001 length field does not count */  +
+ 	    2 /* for bcc field itself */ ;
+-	/* Note that this is the only network field that has to be converted to big endian and it is done just before we send it */
++	/* Note that this is the only network field that has to be converted
++	   to big endian and it is done just before we send it */
+ 
+ 	buffer->Protocol[0] = 0xFF;
+ 	buffer->Protocol[1] = 'S';
+@@ -245,8 +316,6 @@ header_assemble(struct smb_hdr *buffer, 
+ 	buffer->Pid = cpu_to_le16((__u16)current->tgid);
+ 	buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16));
+ 	spin_lock(&GlobalMid_Lock);
+-	GlobalMid++;
+-	buffer->Mid = GlobalMid;
+ 	spin_unlock(&GlobalMid_Lock);
+ 	if (treeCon) {
+ 		buffer->Tid = treeCon->tid;
+@@ -256,8 +325,9 @@ header_assemble(struct smb_hdr *buffer, 
+ 			if (treeCon->ses->capabilities & CAP_STATUS32) {
+ 				buffer->Flags2 |= SMBFLG2_ERR_STATUS;
+ 			}
+-
+-			buffer->Uid = treeCon->ses->Suid;	/* always in LE format */
++			/* Uid is not converted */
++			buffer->Uid = treeCon->ses->Suid;
++			buffer->Mid = GetNextMid(treeCon->ses->server);
+ 			if(multiuser_mount != 0) {
+ 		/* For the multiuser case, there are few obvious technically  */
+ 		/* possible mechanisms to match the local linux user (uid)    */
+@@ -305,6 +375,8 @@ header_assemble(struct smb_hdr *buffer, 
+ 		}
+ 		if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
+ 			buffer->Flags2 |= SMBFLG2_DFS;
++		if (treeCon->nocase)
++			buffer->Flags  |= SMBFLG_CASELESS;
+ 		if((treeCon->ses) && (treeCon->ses->server))
+ 			if(treeCon->ses->server->secMode & 
+ 			  (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+@@ -347,7 +419,8 @@ checkSMBhdr(struct smb_hdr *smb, __u16 m
+ int
+ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
+ {
+-	__u32 len = be32_to_cpu(smb->smb_buf_length);
++	__u32 len = smb->smb_buf_length;
++	__u32 clc_len;  /* calculated length */
+ 	cFYI(0,
+ 	     ("Entering checkSMB with Length: %x, smb_buf_length: %x ",
+ 	      length, len));
+@@ -368,23 +441,29 @@ checkSMB(struct smb_hdr *smb, __u16 mid,
+ 			cERROR(1,
+ 			       ("smb_buf_length greater than MaxBufSize"));
+ 		cERROR(1,
+-		       ("bad smb detected. Illegal length. The mid=%d",
++		       ("bad smb detected. Illegal length. mid=%d",
+ 			smb->Mid));
+ 		return 1;
+ 	}
+ 
+ 	if (checkSMBhdr(smb, mid))
+ 		return 1;
+-
+-	if ((4 + len != smbCalcSize(smb))
++	clc_len = smbCalcSize_LE(smb);
++	if ((4 + len != clc_len)
+ 	    || (4 + len != (unsigned int)length)) {
+-		return 0;
+-	} else {
+-		cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb)));
+-		cERROR(1,
+-		       ("bad smb size detected. The Mid=%d", smb->Mid));
+-		return 1;
++		cERROR(1, ("Calculated size 0x%x vs actual length 0x%x",
++				clc_len, 4 + len));
++		cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid));
++		/* Windows XP can return a few bytes too much, presumably
++		an illegal pad, at the end of byte range lock responses 
++		so we allow for up to eight byte pad, as long as actual
++		received length is as long or longer than calculated length */
++		if((4+len > clc_len) && (len <= clc_len + 3))
++			return 0;
++		else
++			return 1;
+ 	}
++	return 0;
+ }
+ int
+ is_valid_oplock_break(struct smb_hdr *buf)
+@@ -448,9 +527,7 @@ is_valid_oplock_break(struct smb_hdr *bu
+ 	list_for_each(tmp, &GlobalTreeConnectionList) {
+ 		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+ 		if (tcon->tid == buf->Tid) {
+-#ifdef CONFIG_CIFS_STATS
+-			atomic_inc(&tcon->num_oplock_brks);
+-#endif
++			cifs_stats_inc(&tcon->num_oplock_brks);
+ 			list_for_each(tmp1,&tcon->openFileList){
+ 				netfile = list_entry(tmp1,struct cifsFileInfo,
+ 						     tlist);
+@@ -603,6 +680,7 @@ cifsConvertToUCS(__le16 * target, const 
+ 	int i,j,charlen;
+ 	int len_remaining = maxlen;
+ 	char src_char;
++	__u16 temp;
+ 
+ 	if(!mapChars) 
+ 		return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp);
+@@ -639,13 +717,14 @@ cifsConvertToUCS(__le16 * target, const 
+ 				break;*/
+ 			default:
+ 				charlen = cp->char2uni(source+i,
+-					len_remaining, target+j);
++					len_remaining, &temp);
+ 				/* if no match, use question mark, which
+ 				at least in some cases servers as wild card */
+ 				if(charlen < 1) {
+ 					target[j] = cpu_to_le16(0x003f);
+ 					charlen = 1;
+-				}
++				} else
++					target[j] = cpu_to_le16(temp);
+ 				len_remaining -= charlen;
+ 				/* character may take more than one byte in the
+ 				   the source string, but will take exactly two
+diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
+--- a/fs/cifs/netmisc.c
++++ b/fs/cifs/netmisc.c
+@@ -133,7 +133,6 @@ static const struct smb_to_posix_error m
+ int
+ cifs_inet_pton(int address_family, char *cp,void *dst)
+ {
+-	struct in_addr address;
+ 	int value;
+ 	int digit;
+ 	int i;
+@@ -190,8 +189,7 @@ cifs_inet_pton(int address_family, char 
+ 	if (value > addr_class_max[end - bytes])
+ 		return 0;
+ 
+-	address.s_addr = *((__be32 *) bytes) | htonl(value);
+-	*((__be32 *)dst) = address.s_addr;
++	*((__be32 *)dst) = *((__be32 *) bytes) | htonl(value);
+ 	return 1; /* success */
+ }
+ 
+@@ -815,7 +813,7 @@ map_smb_to_linux_error(struct smb_hdr *s
+ 	if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
+ 		/* translate the newer STATUS codes to old style errors and then to POSIX errors */
+ 		__u32 err = le32_to_cpu(smb->Status.CifsError);
+-		if(cifsFYI)
++		if(cifsFYI & CIFS_RC)
+ 			cifs_print_status(err);
+ 		ntstatus_to_dos(err, &smberrclass, &smberrcode);
+ 	} else {
+@@ -870,7 +868,14 @@ unsigned int
+ smbCalcSize(struct smb_hdr *ptr)
+ {
+ 	return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
+-		BCC(ptr));
++		2 /* size of the bcc field */ + BCC(ptr));
++}
++
++unsigned int
++smbCalcSize_LE(struct smb_hdr *ptr)
++{
++	return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
++		2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr)));
+ }
+ 
+ /* The following are taken from fs/ntfs/util.c */
+diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
+--- a/fs/cifs/ntlmssp.h
++++ b/fs/cifs/ntlmssp.h
+@@ -19,8 +19,6 @@
+  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
+  */
+ 
+-#pragma pack(1)
+-
+ #define NTLMSSP_SIGNATURE "NTLMSSP"
+ /* Message Types */
+ #define NtLmNegotiate     cpu_to_le32(1)
+@@ -63,7 +61,7 @@ typedef struct _SECURITY_BUFFER {
+ 	__le16 Length;
+ 	__le16 MaximumLength;
+ 	__le32 Buffer;		/* offset to buffer */
+-} SECURITY_BUFFER;
++} __attribute__((packed)) SECURITY_BUFFER;
+ 
+ typedef struct _NEGOTIATE_MESSAGE {
+ 	__u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
+@@ -73,7 +71,7 @@ typedef struct _NEGOTIATE_MESSAGE {
+ 	SECURITY_BUFFER WorkstationName;	/* RFC 1001 and ASCII */
+ 	char DomainString[0];
+ 	/* followed by WorkstationString */
+-} NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
++} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
+ 
+ typedef struct _CHALLENGE_MESSAGE {
+ 	__u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
+@@ -83,7 +81,7 @@ typedef struct _CHALLENGE_MESSAGE {
+ 	__u8 Challenge[CIFS_CRYPTO_KEY_SIZE];
+ 	__u8 Reserved[8];
+ 	SECURITY_BUFFER TargetInfoArray;
+-} CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
++} __attribute__((packed)) CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
+ 
+ typedef struct _AUTHENTICATE_MESSAGE {
+ 	__u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
+@@ -96,6 +94,4 @@ typedef struct _AUTHENTICATE_MESSAGE {
+ 	SECURITY_BUFFER SessionKey;
+ 	__le32 NegotiateFlags;
+ 	char UserString[0];
+-} AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
+-
+-#pragma pack()			/* resume default structure packing */
++} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
+diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -91,7 +91,10 @@ static int construct_dentry(struct qstr 
+ 		}
+ 
+ 		*ptmp_inode = new_inode(file->f_dentry->d_sb);
+-		tmp_dentry->d_op = &cifs_dentry_ops;
++		if (pTcon->nocase)
++			tmp_dentry->d_op = &cifs_ci_dentry_ops;
++		else
++			tmp_dentry->d_op = &cifs_dentry_ops;
+ 		if(*ptmp_inode == NULL)
+ 			return rc;
+ 		rc = 1;
+@@ -148,6 +151,13 @@ static void fill_in_inode(struct inode *
+ 			tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
+ 		}
+ 		tmp_inode->i_mode |= S_IFDIR;
++	} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 
++		   (attr & ATTR_SYSTEM) && (end_of_file == 0)) {
++		*pobject_type = DT_FIFO;
++		tmp_inode->i_mode |= S_IFIFO;
++/* BB Finish for SFU style symlinks and devies */
++/*	} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
++		(attr & ATTR_SYSTEM) && ) { */
+ /* we no longer mark these because we could not follow them */
+ /*        } else if (attr & ATTR_REPARSE) {
+                 *pobject_type = DT_LNK;
+@@ -187,11 +197,17 @@ static void fill_in_inode(struct inode *
+ 			tmp_inode->i_fop = &cifs_file_direct_ops;
+ 		else
+ 			tmp_inode->i_fop = &cifs_file_ops;
++		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
++			tmp_inode->i_fop->lock = NULL;
+ 		tmp_inode->i_data.a_ops = &cifs_addr_ops;
+-
++		if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
++		   (cifs_sb->tcon->ses->server->maxBuf <
++			4096 + MAX_CIFS_HDR_SIZE))
++			tmp_inode->i_data.a_ops->readpages = NULL;
+ 		if(isNewInode)
+-			return; /* No sense invalidating pages for new inode since we
+-					   have not started caching readahead file data yet */
++			return; /* No sense invalidating pages for new inode
++				   since have not started caching readahead file
++				   data yet */
+ 
+ 		if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
+ 			(local_size == tmp_inode->i_size)) {
+@@ -290,7 +306,13 @@ static void unix_fill_in_inode(struct in
+ 			tmp_inode->i_fop = &cifs_file_direct_ops;
+ 		else
+ 			tmp_inode->i_fop = &cifs_file_ops;
++		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
++			tmp_inode->i_fop->lock = NULL;
+ 		tmp_inode->i_data.a_ops = &cifs_addr_ops;
++		if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
++		   (cifs_sb->tcon->ses->server->maxBuf < 
++			4096 + MAX_CIFS_HDR_SIZE))
++			tmp_inode->i_data.a_ops->readpages = NULL;
+ 
+ 		if(isNewInode)
+ 			return; /* No sense invalidating pages for new inode since we
+@@ -374,7 +396,8 @@ ffirst_retry:
+ 
+ 	rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls,
+ 		&cifsFile->netfid, &cifsFile->srch_inf,
+-		cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
++		cifs_sb->mnt_cifs_flags & 
++			CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
+ 	if(rc == 0)
+ 		cifsFile->invalidHandle = FALSE;
+ 	if((rc == -EOPNOTSUPP) && 
+@@ -491,6 +514,30 @@ static int cifs_entry_is_dot(char *curre
+ 	return rc;
+ }
+ 
++/* Check if directory that we are searching has changed so we can decide
++   whether we can use the cached search results from the previous search */
++static int is_dir_changed(struct file * file)
++{
++	struct inode * inode;
++	struct cifsInodeInfo *cifsInfo;
++
++	if(file->f_dentry == NULL)
++		return 0;
++
++	inode = file->f_dentry->d_inode;
++
++	if(inode == NULL)
++		return 0;
++
++	cifsInfo = CIFS_I(inode);
++
++	if(cifsInfo->time == 0)
++		return 1; /* directory was changed, perhaps due to unlink */
++	else
++		return 0;
++
++}
++
+ /* find the corresponding entry in the search */
+ /* Note that the SMB server returns search entries for . and .. which
+    complicates logic here if we choose to parse for them and we do not
+@@ -507,7 +554,8 @@ static int find_cifs_entry(const int xid
+ 	struct cifsFileInfo * cifsFile = file->private_data;
+ 	/* check if index in the buffer */
+ 	
+-	if((cifsFile == NULL) || (ppCurrentEntry == NULL) || (num_to_ret == NULL))
++	if((cifsFile == NULL) || (ppCurrentEntry == NULL) || 
++	   (num_to_ret == NULL))
+ 		return -ENOENT;
+ 	
+ 	*ppCurrentEntry = NULL;
+@@ -515,7 +563,9 @@ static int find_cifs_entry(const int xid
+ 		cifsFile->srch_inf.index_of_last_entry - 
+ 			cifsFile->srch_inf.entries_in_buffer;
+ /*	dump_cifs_file_struct(file, "In fce ");*/
+-	if(index_to_find < first_entry_in_buffer) {
++	if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 
++	     is_dir_changed(file)) || 
++	   (index_to_find < first_entry_in_buffer)) {
+ 		/* close and restart search */
+ 		cFYI(1,("search backing up - close and restart search"));
+ 		cifsFile->invalidHandle = TRUE;
+@@ -536,7 +586,8 @@ static int find_cifs_entry(const int xid
+ 	while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && 
+ 	      (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){
+ 	 	cFYI(1,("calling findnext2"));
+-		rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, &cifsFile->srch_inf);
++		rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, 
++				  &cifsFile->srch_inf);
+ 		if(rc)
+ 			return -ENOENT;
+ 	}
+@@ -548,14 +599,13 @@ static int find_cifs_entry(const int xid
+ 		char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 
+ 			smbCalcSize((struct smb_hdr *)
+ 				cifsFile->srch_inf.ntwrk_buf_start);
+-/*	dump_cifs_file_struct(file,"found entry in fce "); */
+ 		first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
+ 					- cifsFile->srch_inf.entries_in_buffer;
+ 		pos_in_buf = index_to_find - first_entry_in_buffer;
+ 		cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 
+ 		current_entry = cifsFile->srch_inf.srch_entries_start;
+ 		for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
+-			/* go entry to next entry figuring out which we need to start with */
++			/* go entry by entry figuring out which is first */
+ 			/* if( . or ..)
+ 				skip */
+ 			rc = cifs_entry_is_dot(current_entry,cifsFile);
+@@ -582,11 +632,10 @@ static int find_cifs_entry(const int xid
+ 	}
+ 
+ 	if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
+-		cFYI(1,("can not return entries when pos_in_buf beyond last entry"));
++		cFYI(1,("can not return entries pos_in_buf beyond last entry"));
+ 		*num_to_ret = 0;
+ 	} else
+ 		*num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
+-/*	dump_cifs_file_struct(file, "end fce ");*/
+ 
+ 	return rc;
+ }
+@@ -721,7 +770,8 @@ static int cifs_filldir(char *pfindEntry
+ 			      (FILE_DIRECTORY_INFO *)pfindEntry,&obj_type, rc);
+ 	}
+ 	
+-	rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,tmp_inode->i_ino,obj_type);
++	rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,
++		     tmp_inode->i_ino,obj_type);
+ 	if(rc) {
+ 		cFYI(1,("filldir rc = %d",rc));
+ 	}
+@@ -805,15 +855,12 @@ int cifs_readdir(struct file *file, void
+ 		FreeXid(xid);
+ 		return -EIO;
+ 	}
+-/*	dump_cifs_file_struct(file, "Begin rdir "); */
+ 
+ 	cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+ 	pTcon = cifs_sb->tcon;
+ 	if(pTcon == NULL)
+ 		return -EINVAL;
+ 
+-/*	cFYI(1,("readdir2 pos: %lld",file->f_pos)); */
+-
+ 	switch ((int) file->f_pos) {
+ 	case 0:
+ 		/*if (filldir(direntry, ".", 1, file->f_pos,
+@@ -866,7 +913,6 @@ int cifs_readdir(struct file *file, void
+ 		cifsFile->search_resume_name = NULL; */
+ 
+ 		/* BB account for . and .. in f_pos as special case */
+-		/* dump_cifs_file_struct(file, "rdir after default ");*/
+ 
+ 		rc = find_cifs_entry(xid,pTcon, file,
+ 				&current_entry,&num_to_fill);
+@@ -906,14 +952,14 @@ int cifs_readdir(struct file *file, void
+ 				cifs_save_resume_key(current_entry,cifsFile);
+ 				break;
+ 			} else 
+-				current_entry = nxt_dir_entry(current_entry,end_of_smb);
++				current_entry = nxt_dir_entry(current_entry,
++							      end_of_smb);
+ 		}
+ 		kfree(tmp_buf);
+ 		break;
+ 	} /* end switch */
+ 
+ rddir2_exit:
+-	/* dump_cifs_file_struct(file, "end rdir ");  */
+ 	FreeXid(xid);
+ 	return rc;
+ }
+diff --git a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h
+--- a/fs/cifs/rfc1002pdu.h
++++ b/fs/cifs/rfc1002pdu.h
+@@ -21,8 +21,6 @@
+  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
+  */
+ 
+-#pragma pack(1)
+-
+ /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */
+ 
+ 	/* RFC 1002 session packet types */
+@@ -48,17 +46,17 @@ struct rfc1002_session_packet {
+ 			__u8 calling_len;
+ 			__u8 calling_name[32];
+ 			__u8 scope2; /* null */
+-		} session_req;
++		} __attribute__((packed)) session_req;
+ 		struct {
+ 			__u32 retarget_ip_addr;
+ 			__u16 port;
+-		} retarget_resp;
++		} __attribute__((packed)) retarget_resp;
+ 		__u8 neg_ses_resp_error_code;
+ 		/* POSITIVE_SESSION_RESPONSE packet does not include trailer.
+ 		SESSION_KEEP_ALIVE packet also does not include a trailer.
+ 		Trailer for the SESSION_MESSAGE packet is SMB/CIFS header */
+-	} trailer;
+-};
++	} __attribute__((packed)) trailer;
++} __attribute__((packed));
+ 
+ /* Negative Session Response error codes */
+ #define RFC1002_NOT_LISTENING_CALLED  0x80 /* not listening on called name */
+@@ -74,6 +72,3 @@ server netbios name). Currently server n
+ (tcp name) or ip address or an /etc/hosts equivalent mapping to ip address.*/
+ 
+ #define DEFAULT_CIFS_CALLED_NAME  "*SMBSERVER      "
+-
+-#pragma pack()		/* resume default structure packing */
+-                                                             
+diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
+--- a/fs/cifs/transport.c
++++ b/fs/cifs/transport.c
+@@ -49,7 +49,8 @@ AllocMidQEntry(struct smb_hdr *smb_buffe
+ 		return NULL;
+ 	}
+ 	
+-	temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,SLAB_KERNEL | SLAB_NOFS);
++	temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,
++						    SLAB_KERNEL | SLAB_NOFS);
+ 	if (temp == NULL)
+ 		return temp;
+ 	else {
+@@ -58,7 +59,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffe
+ 		temp->pid = current->pid;
+ 		temp->command = smb_buffer->Command;
+ 		cFYI(1, ("For smb_command %d", temp->command));
+-		do_gettimeofday(&temp->when_sent);
++	/*	do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
++		/* when mid allocated can be before when sent */
++		temp->when_alloc = jiffies;
+ 		temp->ses = ses;
+ 		temp->tsk = current;
+ 	}
+@@ -74,6 +77,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffe
+ static void
+ DeleteMidQEntry(struct mid_q_entry *midEntry)
+ {
++#ifdef CONFIG_CIFS_STATS2
++	unsigned long now;
++#endif
+ 	spin_lock(&GlobalMid_Lock);
+ 	midEntry->midState = MID_FREE;
+ 	list_del(&midEntry->qhead);
+@@ -83,6 +89,22 @@ DeleteMidQEntry(struct mid_q_entry *midE
+ 		cifs_buf_release(midEntry->resp_buf);
+ 	else
+ 		cifs_small_buf_release(midEntry->resp_buf);
++#ifdef CONFIG_CIFS_STATS2
++	now = jiffies;
++	/* commands taking longer than one second are indications that
++	   something is wrong, unless it is quite a slow link or server */
++	if((now - midEntry->when_alloc) > HZ) {
++		if((cifsFYI & CIFS_TIMER) && 
++		   (midEntry->command != SMB_COM_LOCKING_ANDX)) {
++			printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
++			       midEntry->command, midEntry->mid);
++			printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
++			       now - midEntry->when_alloc,
++			       now - midEntry->when_sent,
++			       now - midEntry->when_received);
++		}
++	}
++#endif
+ 	mempool_free(midEntry, cifs_mid_poolp);
+ }
+ 
+@@ -146,32 +168,37 @@ smb_send(struct socket *ssocket, struct 
+ 	   Flags2 is converted in SendReceive */
+ 
+ 	smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
+-	cFYI(1, ("Sending smb of length %d ", smb_buf_length));
++	cFYI(1, ("Sending smb of length %d", smb_buf_length));
+ 	dump_smb(smb_buffer, len);
+ 
+ 	while (len > 0) {
+ 		rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len);
+ 		if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
+ 			i++;
+-			if(i > 60) {
++		/* smaller timeout here than send2 since smaller size */
++		/* Although it may not be required, this also is smaller 
++		   oplock break time */  
++			if(i > 12) {
+ 				cERROR(1,
+-				   ("sends on sock %p stuck for 30 seconds",
++				   ("sends on sock %p stuck for 7 seconds",
+ 				    ssocket));
+ 				rc = -EAGAIN;
+ 				break;
+ 			}
+-			msleep(500);
++			msleep(1 << i);
+ 			continue;
+ 		}
+ 		if (rc < 0) 
+ 			break;
++		else
++			i = 0; /* reset i after each successful send */
+ 		iov.iov_base += rc;
+ 		iov.iov_len -= rc;
+ 		len -= rc;
+ 	}
+ 
+ 	if (rc < 0) {
+-		cERROR(1,("Error %d sending data on socket to server.", rc));
++		cERROR(1,("Error %d sending data on socket to server", rc));
+ 	} else {
+ 		rc = 0;
+ 	}
+@@ -179,26 +206,21 @@ smb_send(struct socket *ssocket, struct 
+ 	return rc;
+ }
+ 
+-#ifdef CIFS_EXPERIMENTAL
+-/* BB finish off this function, adding support for writing set of pages as iovec */
+-/* and also adding support for operations that need to parse the response smb    */
+-
+-int
+-smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer,
+-	 unsigned int smb_buf_length, struct kvec * write_vector 
+-	  /* page list */, struct sockaddr *sin)
++#ifdef CONFIG_CIFS_EXPERIMENTAL
++static int
++smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
++	  struct sockaddr *sin)
+ {
+ 	int rc = 0;
+ 	int i = 0;
+ 	struct msghdr smb_msg;
+-	number_of_pages += 1; /* account for SMB header */
+-	struct kvec * piov  = kmalloc(number_of_pages * sizeof(struct kvec));
+-	unsigned len = smb_buf_length + 4;
+-
++	struct smb_hdr *smb_buffer = iov[0].iov_base;
++	unsigned int len = iov[0].iov_len;
++	unsigned int total_len;
++	int first_vec = 0;
++	
+ 	if(ssocket == NULL)
+ 		return -ENOTSOCK; /* BB eventually add reconnect code here */
+-	iov.iov_base = smb_buffer;
+-	iov.iov_len = len;
+ 
+ 	smb_msg.msg_name = sin;
+ 	smb_msg.msg_namelen = sizeof (struct sockaddr);
+@@ -211,49 +233,80 @@ smb_sendv(struct socket *ssocket, struct
+ 	   cifssmb.c and RFC1001 len is converted to bigendian in smb_send 
+ 	   Flags2 is converted in SendReceive */
+ 
++
++	total_len = 0;
++	for (i = 0; i < n_vec; i++)
++		total_len += iov[i].iov_len;
++
+ 	smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
+-	cFYI(1, ("Sending smb of length %d ", smb_buf_length));
++	cFYI(1, ("Sending smb:  total_len %d", total_len));
+ 	dump_smb(smb_buffer, len);
+ 
+-	while (len > 0) {
+-		rc = kernel_sendmsg(ssocket, &smb_msg, &iov, number_of_pages, 
+-				    len);
++	while (total_len) {
++		rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
++				    n_vec - first_vec, total_len);
+ 		if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
+ 			i++;
+-			if(i > 60) {
++			if(i >= 14) {
+ 				cERROR(1,
+-				   ("sends on sock %p stuck for 30 seconds",
++				   ("sends on sock %p stuck for 15 seconds",
+ 				    ssocket));
+ 				rc = -EAGAIN;
+ 				break;
+ 			}
+-			msleep(500);
++			msleep(1 << i);
+ 			continue;
+ 		}
+ 		if (rc < 0) 
+ 			break;
+-		iov.iov_base += rc;
+-		iov.iov_len -= rc;
+-		len -= rc;
++
++		if (rc >= total_len) {
++			WARN_ON(rc > total_len);
++			break;
++		}
++		if(rc == 0) {
++			/* should never happen, letting socket clear before
++			   retrying is our only obvious option here */
++			cERROR(1,("tcp sent no data"));
++			msleep(500);
++			continue;
++		}
++		total_len -= rc;
++		/* the line below resets i */
++		for (i = first_vec; i < n_vec; i++) {
++			if (iov[i].iov_len) {
++				if (rc > iov[i].iov_len) {
++					rc -= iov[i].iov_len;
++					iov[i].iov_len = 0;
++				} else {
++					iov[i].iov_base += rc;
++					iov[i].iov_len -= rc;
++					first_vec = i;
++					break;
++				}
++			}
++		}
++		i = 0; /* in case we get ENOSPC on the next send */
+ 	}
+ 
+ 	if (rc < 0) {
+-		cERROR(1,("Error %d sending data on socket to server.", rc));
+-	} else {
++		cERROR(1,("Error %d sending data on socket to server", rc));
++	} else
+ 		rc = 0;
+-	}
+ 
+ 	return rc;
+ }
+ 
+-
+ int
+-CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
+-	    struct smb_hdr *in_buf, struct kvec * write_vector /* page list */, int *pbytes_returned, const int long_op)
++SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 
++	     struct kvec *iov, int n_vec, int *pbytes_returned,
++	     const int long_op)
+ {
+ 	int rc = 0;
+-	unsigned long timeout = 15 * HZ;
+-	struct mid_q_entry *midQ = NULL;
++	unsigned int receive_len;
++	unsigned long timeout;
++	struct mid_q_entry *midQ;
++	struct smb_hdr *in_buf = iov[0].iov_base;
+ 
+ 	if (ses == NULL) {
+ 		cERROR(1,("Null smb session"));
+@@ -263,14 +316,8 @@ CIFSSendRcv(const unsigned int xid, stru
+ 		cERROR(1,("Null tcp session"));
+ 		return -EIO;
+ 	}
+-	if(pbytes_returned == NULL)
+-		return -EIO;
+-	else
+-		*pbytes_returned = 0;
+ 
+-  
+-
+-	if(ses->server->tcpStatus == CIFS_EXITING)
++	if(ses->server->tcpStatus == CifsExiting)
+ 		return -ENOENT;
+ 
+ 	/* Ensure that we do not send more than 50 overlapping requests 
+@@ -282,11 +329,18 @@ CIFSSendRcv(const unsigned int xid, stru
+ 	} else {
+ 		spin_lock(&GlobalMid_Lock); 
+ 		while(1) {        
+-			if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){
++			if(atomic_read(&ses->server->inFlight) >= 
++					cifs_max_pending){
+ 				spin_unlock(&GlobalMid_Lock);
++#ifdef CONFIG_CIFS_STATS2
++				atomic_inc(&ses->server->num_waiters);
++#endif
+ 				wait_event(ses->server->request_q,
+ 					atomic_read(&ses->server->inFlight)
+ 					 < cifs_max_pending);
++#ifdef CONFIG_CIFS_STATS2
++				atomic_dec(&ses->server->num_waiters);
++#endif
+ 				spin_lock(&GlobalMid_Lock);
+ 			} else {
+ 				if(ses->server->tcpStatus == CifsExiting) {
+@@ -314,17 +368,17 @@ CIFSSendRcv(const unsigned int xid, stru
+ 
+ 	if (ses->server->tcpStatus == CifsExiting) {
+ 		rc = -ENOENT;
+-		goto cifs_out_label;
++		goto out_unlock2;
+ 	} else if (ses->server->tcpStatus == CifsNeedReconnect) {
+ 		cFYI(1,("tcp session dead - return to caller to retry"));
+ 		rc = -EAGAIN;
+-		goto cifs_out_label;
++		goto out_unlock2;
+ 	} else if (ses->status != CifsGood) {
+ 		/* check if SMB session is bad because we are setting it up */
+ 		if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 
+ 			(in_buf->Command != SMB_COM_NEGOTIATE)) {
+ 			rc = -EAGAIN;
+-			goto cifs_out_label;
++			goto out_unlock2;
+ 		} /* else ok - we are setting up session */
+ 	}
+ 	midQ = AllocMidQEntry(in_buf, ses);
+@@ -338,51 +392,162 @@ CIFSSendRcv(const unsigned int xid, stru
+ 		return -ENOMEM;
+ 	}
+ 
+-	if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
+-		up(&ses->server->tcpSem);
+-		cERROR(1,
+-		       ("Illegal length, greater than maximum frame, %d ",
+-			in_buf->smb_buf_length));
++/* BB FIXME */
++/* 	rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */
++
++	midQ->midState = MID_REQUEST_SUBMITTED;
++#ifdef CONFIG_CIFS_STATS2
++	atomic_inc(&ses->server->inSend);
++#endif
++	rc = smb_send2(ses->server->ssocket, iov, n_vec,
++		      (struct sockaddr *) &(ses->server->addr.sockAddr));
++#ifdef CONFIG_CIFS_STATS2
++	atomic_dec(&ses->server->inSend);
++	midQ->when_sent = jiffies;
++#endif
++	if(rc < 0) {
+ 		DeleteMidQEntry(midQ);
++		up(&ses->server->tcpSem);
+ 		/* If not lock req, update # of requests on wire to server */
+ 		if(long_op < 3) {
+ 			atomic_dec(&ses->server->inFlight); 
+ 			wake_up(&ses->server->request_q);
+ 		}
+-		return -EIO;
++		return rc;
++	} else
++		up(&ses->server->tcpSem);
++	if (long_op == -1)
++		goto cifs_no_response_exit2;
++	else if (long_op == 2) /* writes past end of file can take loong time */
++		timeout = 180 * HZ;
++	else if (long_op == 1)
++		timeout = 45 * HZ; /* should be greater than 
++			servers oplock break timeout (about 43 seconds) */
++	else if (long_op > 2) {
++		timeout = MAX_SCHEDULE_TIMEOUT;
++	} else
++		timeout = 15 * HZ;
++	/* wait for 15 seconds or until woken up due to response arriving or 
++	   due to last connection to this server being unmounted */
++	if (signal_pending(current)) {
++		/* if signal pending do not hold up user for full smb timeout
++		but we still give response a change to complete */
++		timeout = 2 * HZ;
++	}   
++
++	/* No user interrupts in wait - wreaks havoc with performance */
++	if(timeout != MAX_SCHEDULE_TIMEOUT) {
++		timeout += jiffies;
++		wait_event(ses->server->response_q,
++			(!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
++			time_after(jiffies, timeout) || 
++			((ses->server->tcpStatus != CifsGood) &&
++			 (ses->server->tcpStatus != CifsNew)));
++	} else {
++		wait_event(ses->server->response_q,
++			(!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
++			((ses->server->tcpStatus != CifsGood) &&
++			 (ses->server->tcpStatus != CifsNew)));
+ 	}
+ 
+-	/* BB can we sign efficiently in this path? */
+-	rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
++	spin_lock(&GlobalMid_Lock);
++	if (midQ->resp_buf) {
++		spin_unlock(&GlobalMid_Lock);
++		receive_len = midQ->resp_buf->smb_buf_length;
++	} else {
++		cERROR(1,("No response to cmd %d mid %d",
++			midQ->command, midQ->mid));
++		if(midQ->midState == MID_REQUEST_SUBMITTED) {
++			if(ses->server->tcpStatus == CifsExiting)
++				rc = -EHOSTDOWN;
++			else {
++				ses->server->tcpStatus = CifsNeedReconnect;
++				midQ->midState = MID_RETRY_NEEDED;
++			}
++		}
+ 
+-	midQ->midState = MID_REQUEST_SUBMITTED;
+-/*	rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
+-		       piovec, 
+-		       (struct sockaddr *) &(ses->server->addr.sockAddr));*/
+-	if(rc < 0) {
++		if (rc != -EHOSTDOWN) {
++			if(midQ->midState == MID_RETRY_NEEDED) {
++				rc = -EAGAIN;
++				cFYI(1,("marking request for retry"));
++			} else {
++				rc = -EIO;
++			}
++		}
++		spin_unlock(&GlobalMid_Lock);
+ 		DeleteMidQEntry(midQ);
+-		up(&ses->server->tcpSem);
+ 		/* If not lock req, update # of requests on wire to server */
+ 		if(long_op < 3) {
+ 			atomic_dec(&ses->server->inFlight); 
+ 			wake_up(&ses->server->request_q);
+ 		}
+ 		return rc;
+-	} else
+-		up(&ses->server->tcpSem);
+-cifs_out_label:
+-	if(midQ)
+-	        DeleteMidQEntry(midQ);
+-                                                                                                                           
++	}
++  
++	if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
++		cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
++			receive_len, xid));
++		rc = -EIO;
++	} else {		/* rcvd frame is ok */
++
++		if (midQ->resp_buf && 
++			(midQ->midState == MID_RESPONSE_RECEIVED)) {
++			in_buf->smb_buf_length = receive_len;
++			/* BB verify that length would not overrun small buf */
++			memcpy((char *)in_buf + 4,
++			       (char *)midQ->resp_buf + 4,
++			       receive_len);
++
++			dump_smb(in_buf, 80);
++			/* convert the length into a more usable form */
++			if((receive_len > 24) &&
++			   (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
++					SECMODE_SIGN_ENABLED))) {
++				rc = cifs_verify_signature(in_buf,
++						ses->server->mac_signing_key,
++						midQ->sequence_number+1);
++				if(rc) {
++					cERROR(1,("Unexpected SMB signature"));
++					/* BB FIXME add code to kill session */
++				}
++			}
++
++			*pbytes_returned = in_buf->smb_buf_length;
++
++			/* BB special case reconnect tid and uid here? */
++			rc = map_smb_to_linux_error(in_buf);
++
++			/* convert ByteCount if necessary */
++			if (receive_len >=
++			    sizeof (struct smb_hdr) -
++			    4 /* do not count RFC1001 header */  +
++			    (2 * in_buf->WordCount) + 2 /* bcc */ )
++				BCC(in_buf) = le16_to_cpu(BCC(in_buf));
++		} else {
++			rc = -EIO;
++			cFYI(1,("Bad MID state?"));
++		}
++	}
++cifs_no_response_exit2:
++	DeleteMidQEntry(midQ);
++
+ 	if(long_op < 3) {
+-		atomic_dec(&ses->server->inFlight);
++		atomic_dec(&ses->server->inFlight); 
+ 		wake_up(&ses->server->request_q);
+ 	}
+ 
+ 	return rc;
+-}
+ 
++out_unlock2:
++	up(&ses->server->tcpSem);
++	/* If not lock req, update # of requests on wire to server */
++	if(long_op < 3) {
++		atomic_dec(&ses->server->inFlight); 
++		wake_up(&ses->server->request_q);
++	}
+ 
++	return rc;
++}
+ #endif /* CIFS_EXPERIMENTAL */
+ 
+ int
+@@ -419,9 +584,15 @@ SendReceive(const unsigned int xid, stru
+ 			if(atomic_read(&ses->server->inFlight) >= 
+ 					cifs_max_pending){
+ 				spin_unlock(&GlobalMid_Lock);
++#ifdef CONFIG_CIFS_STATS2
++				atomic_inc(&ses->server->num_waiters);
++#endif
+ 				wait_event(ses->server->request_q,
+ 					atomic_read(&ses->server->inFlight)
+ 					 < cifs_max_pending);
++#ifdef CONFIG_CIFS_STATS2
++				atomic_dec(&ses->server->num_waiters);
++#endif
+ 				spin_lock(&GlobalMid_Lock);
+ 			} else {
+ 				if(ses->server->tcpStatus == CifsExiting) {
+@@ -490,8 +661,15 @@ SendReceive(const unsigned int xid, stru
+ 	rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
+ 
+ 	midQ->midState = MID_REQUEST_SUBMITTED;
++#ifdef CONFIG_CIFS_STATS2
++	atomic_inc(&ses->server->inSend);
++#endif
+ 	rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
+ 		      (struct sockaddr *) &(ses->server->addr.sockAddr));
++#ifdef CONFIG_CIFS_STATS2
++	atomic_dec(&ses->server->inSend);
++	midQ->when_sent = jiffies;
++#endif
+ 	if(rc < 0) {
+ 		DeleteMidQEntry(midQ);
+ 		up(&ses->server->tcpSem);
+@@ -506,7 +684,7 @@ SendReceive(const unsigned int xid, stru
+ 	if (long_op == -1)
+ 		goto cifs_no_response_exit;
+ 	else if (long_op == 2) /* writes past end of file can take loong time */
+-		timeout = 300 * HZ;
++		timeout = 180 * HZ;
+ 	else if (long_op == 1)
+ 		timeout = 45 * HZ; /* should be greater than 
+ 			servers oplock break timeout (about 43 seconds) */
+@@ -540,9 +718,10 @@ SendReceive(const unsigned int xid, stru
+ 	spin_lock(&GlobalMid_Lock);
+ 	if (midQ->resp_buf) {
+ 		spin_unlock(&GlobalMid_Lock);
+-		receive_len = be32_to_cpu(*(__be32 *)midQ->resp_buf);
++		receive_len = midQ->resp_buf->smb_buf_length;
+ 	} else {
+-		cERROR(1,("No response buffer"));
++		cERROR(1,("No response for cmd %d mid %d",
++			  midQ->command, midQ->mid));
+ 		if(midQ->midState == MID_REQUEST_SUBMITTED) {
+ 			if(ses->server->tcpStatus == CifsExiting)
+ 				rc = -EHOSTDOWN;
+@@ -610,7 +789,7 @@ SendReceive(const unsigned int xid, stru
+ 				BCC(out_buf) = le16_to_cpu(BCC(out_buf));
+ 		} else {
+ 			rc = -EIO;
+-			cFYI(1,("Bad MID state? "));
++			cERROR(1,("Bad MID state? "));
+ 		}
+ 	}
+ cifs_no_response_exit:
+diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
+--- a/fs/coda/psdev.c
++++ b/fs/coda/psdev.c
+@@ -370,8 +370,8 @@ static int init_coda_psdev(void)
+ 	}		
+ 	devfs_mk_dir ("coda");
+ 	for (i = 0; i < MAX_CODADEVS; i++) {
+-		class_device_create(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i),
+-				NULL, "cfs%d", i);
++		class_device_create(coda_psdev_class, NULL,
++				MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i);
+ 		err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i),
+ 				S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i);
+ 		if (err)
+diff --git a/fs/compat.c b/fs/compat.c
+--- a/fs/compat.c
++++ b/fs/compat.c
+@@ -1490,7 +1490,6 @@ int compat_do_execve(char * filename,
+ 		/* execve success */
+ 		security_bprm_free(bprm);
+ 		acct_update_integrals(current);
+-		update_mem_hiwater(current);
+ 		kfree(bprm);
+ 		return retval;
+ 	}
+diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
+--- a/fs/compat_ioctl.c
++++ b/fs/compat_ioctl.c
+@@ -3046,10 +3046,15 @@ HANDLE_IOCTL(RAW_GETBIND, raw_ioctl)
+ /* Serial */
+ HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
+ HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
++#ifdef TIOCGLTC
++COMPATIBLE_IOCTL(TIOCGLTC)
++COMPATIBLE_IOCTL(TIOCSLTC)
++#endif
+ /* Usbdevfs */
+ HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
+ HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
+ HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
++COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
+ /* i2c */
+ HANDLE_IOCTL(I2C_FUNCS, w_long)
+ HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
+diff --git a/fs/dcache.c b/fs/dcache.c
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -689,7 +689,7 @@ void shrink_dcache_anon(struct hlist_hea
+  *
+  * In this case we return -1 to tell the caller that we baled.
+  */
+-static int shrink_dcache_memory(int nr, unsigned int gfp_mask)
++static int shrink_dcache_memory(int nr, gfp_t gfp_mask)
+ {
+ 	if (nr) {
+ 		if (!(gfp_mask & __GFP_FS))
+diff --git a/fs/direct-io.c b/fs/direct-io.c
+--- a/fs/direct-io.c
++++ b/fs/direct-io.c
+@@ -162,6 +162,7 @@ static int dio_refill_pages(struct dio *
+ 	up_read(&current->mm->mmap_sem);
+ 
+ 	if (ret < 0 && dio->blocks_available && (dio->rw == WRITE)) {
++		struct page *page = ZERO_PAGE(dio->curr_user_address);
+ 		/*
+ 		 * A memory fault, but the filesystem has some outstanding
+ 		 * mapped blocks.  We need to use those blocks up to avoid
+@@ -169,7 +170,8 @@ static int dio_refill_pages(struct dio *
+ 		 */
+ 		if (dio->page_errors == 0)
+ 			dio->page_errors = ret;
+-		dio->pages[0] = ZERO_PAGE(dio->curr_user_address);
++		page_cache_get(page);
++		dio->pages[0] = page;
+ 		dio->head = 0;
+ 		dio->tail = 1;
+ 		ret = 0;
+diff --git a/fs/dquot.c b/fs/dquot.c
+--- a/fs/dquot.c
++++ b/fs/dquot.c
+@@ -500,7 +500,7 @@ static void prune_dqcache(int count)
+  * more memory
+  */
+ 
+-static int shrink_dqcache_memory(int nr, unsigned int gfp_mask)
++static int shrink_dqcache_memory(int nr, gfp_t gfp_mask)
+ {
+ 	if (nr) {
+ 		spin_lock(&dq_list_lock);
+@@ -662,7 +662,7 @@ static void add_dquot_ref(struct super_b
+ restart:
+ 	file_list_lock();
+ 	list_for_each(p, &sb->s_files) {
+-		struct file *filp = list_entry(p, struct file, f_list);
++		struct file *filp = list_entry(p, struct file, f_u.fu_list);
+ 		struct inode *inode = filp->f_dentry->d_inode;
+ 		if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
+ 			struct dentry *dentry = dget(filp->f_dentry);
+diff --git a/fs/exec.c b/fs/exec.c
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -126,8 +126,7 @@ asmlinkage long sys_uselib(const char __
+ 	struct nameidata nd;
+ 	int error;
+ 
+-	nd.intent.open.flags = FMODE_READ;
+-	error = __user_walk(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
++	error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ);
+ 	if (error)
+ 		goto out;
+ 
+@@ -139,7 +138,7 @@ asmlinkage long sys_uselib(const char __
+ 	if (error)
+ 		goto exit;
+ 
+-	file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++	file = nameidata_to_filp(&nd, O_RDONLY);
+ 	error = PTR_ERR(file);
+ 	if (IS_ERR(file))
+ 		goto out;
+@@ -167,6 +166,7 @@ asmlinkage long sys_uselib(const char __
+ out:
+   	return error;
+ exit:
++	release_open_intent(&nd);
+ 	path_release(&nd);
+ 	goto out;
+ }
+@@ -309,40 +309,36 @@ void install_arg_page(struct vm_area_str
+ 	pud_t * pud;
+ 	pmd_t * pmd;
+ 	pte_t * pte;
++	spinlock_t *ptl;
+ 
+ 	if (unlikely(anon_vma_prepare(vma)))
+-		goto out_sig;
++		goto out;
+ 
+ 	flush_dcache_page(page);
+ 	pgd = pgd_offset(mm, address);
+-
+-	spin_lock(&mm->page_table_lock);
+ 	pud = pud_alloc(mm, pgd, address);
+ 	if (!pud)
+ 		goto out;
+ 	pmd = pmd_alloc(mm, pud, address);
+ 	if (!pmd)
+ 		goto out;
+-	pte = pte_alloc_map(mm, pmd, address);
++	pte = pte_alloc_map_lock(mm, pmd, address, &ptl);
+ 	if (!pte)
+ 		goto out;
+ 	if (!pte_none(*pte)) {
+-		pte_unmap(pte);
++		pte_unmap_unlock(pte, ptl);
+ 		goto out;
+ 	}
+-	inc_mm_counter(mm, rss);
++	inc_mm_counter(mm, anon_rss);
+ 	lru_cache_add_active(page);
+ 	set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
+ 					page, vma->vm_page_prot))));
+ 	page_add_anon_rmap(page, vma, address);
+-	pte_unmap(pte);
+-	spin_unlock(&mm->page_table_lock);
++	pte_unmap_unlock(pte, ptl);
+ 
+ 	/* no need for flush_tlb */
+ 	return;
+ out:
+-	spin_unlock(&mm->page_table_lock);
+-out_sig:
+ 	__free_page(page);
+ 	force_sig(SIGKILL, current);
+ }
+@@ -490,8 +486,7 @@ struct file *open_exec(const char *name)
+ 	int err;
+ 	struct file *file;
+ 
+-	nd.intent.open.flags = FMODE_READ;
+-	err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
++	err = path_lookup_open(name, LOOKUP_FOLLOW, &nd, FMODE_READ);
+ 	file = ERR_PTR(err);
+ 
+ 	if (!err) {
+@@ -504,7 +499,7 @@ struct file *open_exec(const char *name)
+ 				err = -EACCES;
+ 			file = ERR_PTR(err);
+ 			if (!err) {
+-				file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++				file = nameidata_to_filp(&nd, O_RDONLY);
+ 				if (!IS_ERR(file)) {
+ 					err = deny_write_access(file);
+ 					if (err) {
+@@ -516,6 +511,7 @@ out:
+ 				return file;
+ 			}
+ 		}
++		release_open_intent(&nd);
+ 		path_release(&nd);
+ 	}
+ 	goto out;
+@@ -634,10 +630,9 @@ static inline int de_thread(struct task_
+ 	/*
+ 	 * Account for the thread group leader hanging around:
+ 	 */
+-	count = 2;
+-	if (thread_group_leader(current))
+-		count = 1;
+-	else {
++	count = 1;
++	if (!thread_group_leader(current)) {
++		count = 2;
+ 		/*
+ 		 * The SIGALRM timer survives the exec, but needs to point
+ 		 * at us as the new group leader now.  We have a race with
+@@ -646,8 +641,10 @@ static inline int de_thread(struct task_
+ 		 * before we can safely let the old group leader die.
+ 		 */
+ 		sig->real_timer.data = (unsigned long)current;
++		spin_unlock_irq(lock);
+ 		if (del_timer_sync(&sig->real_timer))
+ 			add_timer(&sig->real_timer);
++		spin_lock_irq(lock);
+ 	}
+ 	while (atomic_read(&sig->count) > count) {
+ 		sig->group_exit_task = current;
+@@ -659,7 +656,6 @@ static inline int de_thread(struct task_
+ 	}
+ 	sig->group_exit_task = NULL;
+ 	sig->notify_count = 0;
+-	sig->real_timer.data = (unsigned long)current;
+ 	spin_unlock_irq(lock);
+ 
+ 	/*
+@@ -1207,7 +1203,6 @@ int do_execve(char * filename,
+ 		/* execve success */
+ 		security_bprm_free(bprm);
+ 		acct_update_integrals(current);
+-		update_mem_hiwater(current);
+ 		kfree(bprm);
+ 		return retval;
+ 	}
+@@ -1422,19 +1417,16 @@ static void zap_threads (struct mm_struc
+ static void coredump_wait(struct mm_struct *mm)
+ {
+ 	DECLARE_COMPLETION(startup_done);
++	int core_waiters;
+ 
+-	mm->core_waiters++; /* let other threads block */
+ 	mm->core_startup_done = &startup_done;
+ 
+-	/* give other threads a chance to run: */
+-	yield();
+-
+ 	zap_threads(mm);
+-	if (--mm->core_waiters) {
+-		up_write(&mm->mmap_sem);
++	core_waiters = mm->core_waiters;
++	up_write(&mm->mmap_sem);
++
++	if (core_waiters)
+ 		wait_for_completion(&startup_done);
+-	} else
+-		up_write(&mm->mmap_sem);
+ 	BUG_ON(mm->core_waiters);
+ }
+ 
+@@ -1468,11 +1460,21 @@ int do_coredump(long signr, int exit_cod
+ 		current->fsuid = 0;	/* Dump root private */
+ 	}
+ 	mm->dumpable = 0;
+-	init_completion(&mm->core_done);
++
++	retval = -EAGAIN;
+ 	spin_lock_irq(&current->sighand->siglock);
+-	current->signal->flags = SIGNAL_GROUP_EXIT;
+-	current->signal->group_exit_code = exit_code;
++	if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
++		current->signal->flags = SIGNAL_GROUP_EXIT;
++		current->signal->group_exit_code = exit_code;
++		retval = 0;
++	}
+ 	spin_unlock_irq(&current->sighand->siglock);
++	if (retval) {
++		up_write(&mm->mmap_sem);
++		goto fail;
++	}
++
++	init_completion(&mm->core_done);
+ 	coredump_wait(mm);
+ 
+ 	/*
+diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
+--- a/fs/ext2/inode.c
++++ b/fs/ext2/inode.c
+@@ -440,6 +440,10 @@ static int ext2_alloc_branch(struct inod
+ 		 * the pointer to new one, then send parent to disk.
+ 		 */
+ 		bh = sb_getblk(inode->i_sb, parent);
++		if (!bh) {
++			err = -EIO;
++			break;
++		}
+ 		lock_buffer(bh);
+ 		memset(bh->b_data, 0, blocksize);
+ 		branch[n].bh = bh;
+diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
+--- a/fs/ext3/balloc.c
++++ b/fs/ext3/balloc.c
+@@ -20,6 +20,8 @@
+ #include <linux/quotaops.h>
+ #include <linux/buffer_head.h>
+ 
++#include "bitmap.h"
++
+ /*
+  * balloc.c contains the blocks allocation and deallocation routines
+  */
+@@ -1010,7 +1012,7 @@ retry:
+  * allocation within the reservation window.
+  *
+  * This will avoid keeping on searching the reservation list again and
+- * again when someboday is looking for a free block (without
++ * again when somebody is looking for a free block (without
+  * reservation), and there are lots of free blocks, but they are all
+  * being reserved.
+  *
+@@ -1416,12 +1418,12 @@ unsigned long ext3_count_free_blocks(str
+ 	unsigned long bitmap_count, x;
+ 	struct buffer_head *bitmap_bh = NULL;
+ 
+-	lock_super(sb);
+ 	es = EXT3_SB(sb)->s_es;
+ 	desc_count = 0;
+ 	bitmap_count = 0;
+ 	gdp = NULL;
+ 
++	smp_rmb();
+ 	for (i = 0; i < ngroups; i++) {
+ 		gdp = ext3_get_group_desc(sb, i, NULL);
+ 		if (!gdp)
+@@ -1440,7 +1442,6 @@ unsigned long ext3_count_free_blocks(str
+ 	brelse(bitmap_bh);
+ 	printk("ext3_count_free_blocks: stored = %u, computed = %lu, %lu\n",
+ 	       le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count);
+-	unlock_super(sb);
+ 	return bitmap_count;
+ #else
+ 	desc_count = 0;
+diff --git a/fs/ext3/bitmap.c b/fs/ext3/bitmap.c
+--- a/fs/ext3/bitmap.c
++++ b/fs/ext3/bitmap.c
+@@ -8,7 +8,7 @@
+  */
+ 
+ #include <linux/buffer_head.h>
+-
++#include "bitmap.h"
+ 
+ static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
+ 
+diff --git a/fs/ext3/bitmap.h b/fs/ext3/bitmap.h
+new file mode 100644
+--- /dev/null
++++ b/fs/ext3/bitmap.h
+@@ -0,0 +1,8 @@
++/*  linux/fs/ext3/bitmap.c
++ *
++ * Copyright (C) 2005 Simtec Electronics
++ *	Ben Dooks <ben at simtec.co.uk>
++ *
++*/
++
++extern unsigned long ext3_count_free (struct buffer_head *, unsigned int );
+diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
+--- a/fs/ext3/ialloc.c
++++ b/fs/ext3/ialloc.c
+@@ -26,6 +26,7 @@
+ 
+ #include <asm/byteorder.h>
+ 
++#include "bitmap.h"
+ #include "xattr.h"
+ #include "acl.h"
+ 
+@@ -704,7 +705,6 @@ unsigned long ext3_count_free_inodes (st
+ 	unsigned long bitmap_count, x;
+ 	struct buffer_head *bitmap_bh = NULL;
+ 
+-	lock_super (sb);
+ 	es = EXT3_SB(sb)->s_es;
+ 	desc_count = 0;
+ 	bitmap_count = 0;
+@@ -727,7 +727,6 @@ unsigned long ext3_count_free_inodes (st
+ 	brelse(bitmap_bh);
+ 	printk("ext3_count_free_inodes: stored = %u, computed = %lu, %lu\n",
+ 		le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count);
+-	unlock_super(sb);
+ 	return desc_count;
+ #else
+ 	desc_count = 0;
+diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
+--- a/fs/ext3/inode.c
++++ b/fs/ext3/inode.c
+@@ -491,7 +491,7 @@ static unsigned long ext3_find_goal(stru
+  *	the same format as ext3_get_branch() would do. We are calling it after
+  *	we had read the existing part of chain and partial points to the last
+  *	triple of that (one with zero ->key). Upon the exit we have the same
+- *	picture as after the successful ext3_get_block(), excpet that in one
++ *	picture as after the successful ext3_get_block(), except that in one
+  *	place chain is disconnected - *branch->p is still zero (we did not
+  *	set the last link), but branch->key contains the number that should
+  *	be placed into *branch->p to fill that gap.
+@@ -523,7 +523,6 @@ static int ext3_alloc_branch(handle_t *h
+ 			if (!nr)
+ 				break;
+ 			branch[n].key = cpu_to_le32(nr);
+-			keys = n+1;
+ 
+ 			/*
+ 			 * Get buffer_head for parent block, zero it out
+@@ -531,6 +530,9 @@ static int ext3_alloc_branch(handle_t *h
+ 			 * parent to disk.  
+ 			 */
+ 			bh = sb_getblk(inode->i_sb, parent);
++			if (!bh)
++				break;
++			keys = n+1;
+ 			branch[n].bh = bh;
+ 			lock_buffer(bh);
+ 			BUFFER_TRACE(bh, "call get_create_access");
+@@ -864,6 +866,10 @@ struct buffer_head *ext3_getblk(handle_t
+ 	if (!*errp && buffer_mapped(&dummy)) {
+ 		struct buffer_head *bh;
+ 		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
++		if (!bh) {
++			*errp = -EIO;
++			goto err;
++		}
+ 		if (buffer_new(&dummy)) {
+ 			J_ASSERT(create != 0);
+ 			J_ASSERT(handle != 0);
+@@ -896,6 +902,7 @@ struct buffer_head *ext3_getblk(handle_t
+ 		}
+ 		return bh;
+ 	}
++err:
+ 	return NULL;
+ }
+ 
+@@ -1434,7 +1441,7 @@ static int ext3_invalidatepage(struct pa
+ 	return journal_invalidatepage(journal, page, offset);
+ }
+ 
+-static int ext3_releasepage(struct page *page, int wait)
++static int ext3_releasepage(struct page *page, gfp_t wait)
+ {
+ 	journal_t *journal = EXT3_JOURNAL(page->mapping->host);
+ 
+diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
+--- a/fs/ext3/namei.c
++++ b/fs/ext3/namei.c
+@@ -36,6 +36,8 @@
+ #include <linux/quotaops.h>
+ #include <linux/buffer_head.h>
+ #include <linux/smp_lock.h>
++
++#include "namei.h"
+ #include "xattr.h"
+ #include "acl.h"
+ 
+diff --git a/fs/ext3/namei.h b/fs/ext3/namei.h
+new file mode 100644
+--- /dev/null
++++ b/fs/ext3/namei.h
+@@ -0,0 +1,8 @@
++/*  linux/fs/ext3/namei.h
++ *
++ * Copyright (C) 2005 Simtec Electronics
++ *	Ben Dooks <ben at simtec.co.uk>
++ *
++*/
++
++extern struct dentry *ext3_get_parent(struct dentry *child);
+diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
+--- a/fs/ext3/resize.c
++++ b/fs/ext3/resize.c
+@@ -118,6 +118,8 @@ static struct buffer_head *bclean(handle
+ 	int err;
+ 
+ 	bh = sb_getblk(sb, blk);
++	if (!bh)
++		return ERR_PTR(-EIO);
+ 	if ((err = ext3_journal_get_write_access(handle, bh))) {
+ 		brelse(bh);
+ 		bh = ERR_PTR(err);
+@@ -202,6 +204,10 @@ static int setup_new_group_blocks(struct
+ 		ext3_debug("update backup group %#04lx (+%d)\n", block, bit);
+ 
+ 		gdb = sb_getblk(sb, block);
++		if (!gdb) {
++			err = -EIO;
++			goto exit_bh;
++		}
+ 		if ((err = ext3_journal_get_write_access(handle, gdb))) {
+ 			brelse(gdb);
+ 			goto exit_bh;
+@@ -643,6 +649,10 @@ static void update_backups(struct super_
+ 			break;
+ 
+ 		bh = sb_getblk(sb, group * bpg + blk_off);
++		if (!bh) {
++			err = -EIO;
++			break;
++		}
+ 		ext3_debug("update metadata backup %#04lx\n",
+ 			  (unsigned long)bh->b_blocknr);
+ 		if ((err = ext3_journal_get_write_access(handle, bh)))
+diff --git a/fs/ext3/super.c b/fs/ext3/super.c
+--- a/fs/ext3/super.c
++++ b/fs/ext3/super.c
+@@ -36,9 +36,12 @@
+ #include <linux/namei.h>
+ #include <linux/quotaops.h>
+ #include <linux/seq_file.h>
++
+ #include <asm/uaccess.h>
++
+ #include "xattr.h"
+ #include "acl.h"
++#include "namei.h"
+ 
+ static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+ static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
+@@ -510,19 +513,11 @@ static void ext3_clear_inode(struct inod
+ 	kfree(rsv);
+ }
+ 
+-static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
++static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb)
+ {
+-	struct super_block *sb = vfs->mnt_sb;
++#if defined(CONFIG_QUOTA)
+ 	struct ext3_sb_info *sbi = EXT3_SB(sb);
+ 
+-	if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
+-		seq_puts(seq, ",data=journal");
+-	else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA)
+-		seq_puts(seq, ",data=ordered");
+-	else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
+-		seq_puts(seq, ",data=writeback");
+-
+-#if defined(CONFIG_QUOTA)
+ 	if (sbi->s_jquota_fmt)
+ 		seq_printf(seq, ",jqfmt=%s",
+ 		(sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0");
+@@ -539,6 +534,20 @@ static int ext3_show_options(struct seq_
+ 	if (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)
+ 		seq_puts(seq, ",grpquota");
+ #endif
++}
++
++static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
++{
++	struct super_block *sb = vfs->mnt_sb;
++
++	if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
++		seq_puts(seq, ",data=journal");
++	else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA)
++		seq_puts(seq, ",data=ordered");
++	else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
++		seq_puts(seq, ",data=writeback");
++
++	ext3_show_quota_options(seq, sb);
+ 
+ 	return 0;
+ }
+@@ -609,7 +618,6 @@ static struct super_operations ext3_sops
+ #endif
+ };
+ 
+-struct dentry *ext3_get_parent(struct dentry *child);
+ static struct export_operations ext3_export_ops = {
+ 	.get_parent = ext3_get_parent,
+ };
+diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
+--- a/fs/ext3/xattr.c
++++ b/fs/ext3/xattr.c
+@@ -210,7 +210,7 @@ ext3_xattr_find_entry(struct ext3_xattr_
+ 	return cmp ? -ENODATA : 0;
+ }
+ 
+-int
++static int
+ ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
+ 		     void *buffer, size_t buffer_size)
+ {
+@@ -354,7 +354,7 @@ ext3_xattr_list_entries(struct inode *in
+ 	return buffer_size - rest;
+ }
+ 
+-int
++static int
+ ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
+ {
+ 	struct buffer_head *bh = NULL;
+@@ -626,7 +626,7 @@ struct ext3_xattr_block_find {
+ 	struct buffer_head *bh;
+ };
+ 
+-int
++static int
+ ext3_xattr_block_find(struct inode *inode, struct ext3_xattr_info *i,
+ 		      struct ext3_xattr_block_find *bs)
+ {
+@@ -859,7 +859,7 @@ struct ext3_xattr_ibody_find {
+ 	struct ext3_iloc iloc;
+ };
+ 
+-int
++static int
+ ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i,
+ 		      struct ext3_xattr_ibody_find *is)
+ {
+diff --git a/fs/fat/dir.c b/fs/fat/dir.c
+--- a/fs/fat/dir.c
++++ b/fs/fat/dir.c
+@@ -222,6 +222,80 @@ fat_shortname2uni(struct nls_table *nls,
+ 	return len;
+ }
+ 
++enum { PARSE_INVALID = 1, PARSE_NOT_LONGNAME, PARSE_EOF, };
++
++/**
++ * fat_parse_long - Parse extended directory entry.
++ *
++ * This function returns zero on success, negative value on error, or one of
++ * the following:
++ *
++ * %PARSE_INVALID - Directory entry is invalid.
++ * %PARSE_NOT_LONGNAME - Directory entry does not contain longname.
++ * %PARSE_EOF - Directory has no more entries.
++ */
++static int fat_parse_long(struct inode *dir, loff_t *pos,
++			  struct buffer_head **bh, struct msdos_dir_entry **de,
++			  wchar_t **unicode, unsigned char *nr_slots)
++{
++	struct msdos_dir_slot *ds;
++	unsigned char id, slot, slots, alias_checksum;
++
++	if (!*unicode) {
++		*unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
++		if (!*unicode) {
++			brelse(*bh);
++			return -ENOMEM;
++		}
++	}
++parse_long:
++	slots = 0;
++	ds = (struct msdos_dir_slot *)*de;
++	id = ds->id;
++	if (!(id & 0x40))
++		return PARSE_INVALID;
++	slots = id & ~0x40;
++	if (slots > 20 || !slots)	/* ceil(256 * 2 / 26) */
++		return PARSE_INVALID;
++	*nr_slots = slots;
++	alias_checksum = ds->alias_checksum;
++
++	slot = slots;
++	while (1) {
++		int offset;
++
++		slot--;
++		offset = slot * 13;
++		fat16_towchar(*unicode + offset, ds->name0_4, 5);
++		fat16_towchar(*unicode + offset + 5, ds->name5_10, 6);
++		fat16_towchar(*unicode + offset + 11, ds->name11_12, 2);
++
++		if (ds->id & 0x40)
++			(*unicode)[offset + 13] = 0;
++		if (fat_get_entry(dir, pos, bh, de) < 0)
++			return PARSE_EOF;
++		if (slot == 0)
++			break;
++		ds = (struct msdos_dir_slot *)*de;
++		if (ds->attr != ATTR_EXT)
++			return PARSE_NOT_LONGNAME;
++		if ((ds->id & ~0x40) != slot)
++			goto parse_long;
++		if (ds->alias_checksum != alias_checksum)
++			goto parse_long;
++	}
++	if ((*de)->name[0] == DELETED_FLAG)
++		return PARSE_INVALID;
++	if ((*de)->attr == ATTR_EXT)
++		goto parse_long;
++	if (IS_FREE((*de)->name) || ((*de)->attr & ATTR_VOLUME))
++		return PARSE_INVALID;
++	if (fat_checksum((*de)->name) != alias_checksum)
++		*nr_slots = 0;
++
++	return 0;
++}
++
+ /*
+  * Return values: negative -> error, 0 -> not found, positive -> found,
+  * value is the total amount of slots, including the shortname entry.
+@@ -259,68 +333,16 @@ parse_record:
+ 		if (de->attr != ATTR_EXT && IS_FREE(de->name))
+ 			continue;
+ 		if (de->attr == ATTR_EXT) {
+-			struct msdos_dir_slot *ds;
+-			unsigned char id;
+-			unsigned char slot;
+-			unsigned char slots;
+-			unsigned char sum;
+-			unsigned char alias_checksum;
+-
+-			if (!unicode) {
+-				unicode = (wchar_t *)
+-					__get_free_page(GFP_KERNEL);
+-				if (!unicode) {
+-					brelse(bh);
+-					return -ENOMEM;
+-				}
+-			}
+-parse_long:
+-			slots = 0;
+-			ds = (struct msdos_dir_slot *) de;
+-			id = ds->id;
+-			if (!(id & 0x40))
+-				continue;
+-			slots = id & ~0x40;
+-			if (slots > 20 || !slots)	/* ceil(256 * 2 / 26) */
+-				continue;
+-			nr_slots = slots;
+-			alias_checksum = ds->alias_checksum;
+-
+-			slot = slots;
+-			while (1) {
+-				int offset;
+-
+-				slot--;
+-				offset = slot * 13;
+-				fat16_towchar(unicode + offset, ds->name0_4, 5);
+-				fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
+-				fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
+-
+-				if (ds->id & 0x40) {
+-					unicode[offset + 13] = 0;
+-				}
+-				if (fat_get_entry(inode, &cpos, &bh, &de) < 0)
+-					goto EODir;
+-				if (slot == 0)
+-					break;
+-				ds = (struct msdos_dir_slot *) de;
+-				if (ds->attr !=  ATTR_EXT)
+-					goto parse_record;
+-				if ((ds->id & ~0x40) != slot)
+-					goto parse_long;
+-				if (ds->alias_checksum != alias_checksum)
+-					goto parse_long;
+-			}
+-			if (de->name[0] == DELETED_FLAG)
+-				continue;
+-			if (de->attr ==  ATTR_EXT)
+-				goto parse_long;
+-			if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
++			int status = fat_parse_long(inode, &cpos, &bh, &de,
++						    &unicode, &nr_slots);
++			if (status < 0)
++				return status;
++			else if (status == PARSE_INVALID)
+ 				continue;
+-			for (sum = 0, i = 0; i < 11; i++)
+-				sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
+-			if (sum != alias_checksum)
+-				nr_slots = 0;
++			else if (status == PARSE_NOT_LONGNAME)
++				goto parse_record;
++			else if (status == PARSE_EOF)
++				goto EODir;
+ 		}
+ 
+ 		memcpy(work, de->name, sizeof(de->name));
+@@ -408,8 +430,8 @@ struct fat_ioctl_filldir_callback {
+ 	int short_len;
+ };
+ 
+-static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
+-			filldir_t filldir, int short_only, int both)
++static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
++			 filldir_t filldir, int short_only, int both)
+ {
+ 	struct super_block *sb = inode->i_sb;
+ 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
+@@ -458,9 +480,10 @@ static int fat_readdirx(struct inode *in
+ 
+ 	bh = NULL;
+ GetNew:
+-	long_slots = 0;
+ 	if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
+ 		goto EODir;
++parse_record:
++	long_slots = 0;
+ 	/* Check for long filename entry */
+ 	if (isvfat) {
+ 		if (de->name[0] == DELETED_FLAG)
+@@ -475,69 +498,18 @@ GetNew:
+ 	}
+ 
+ 	if (isvfat && de->attr == ATTR_EXT) {
+-		struct msdos_dir_slot *ds;
+-		unsigned char id;
+-		unsigned char slot;
+-		unsigned char slots;
+-		unsigned char sum;
+-		unsigned char alias_checksum;
+-
+-		if (!unicode) {
+-			unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
+-			if (!unicode) {
+-				filp->f_pos = cpos;
+-				brelse(bh);
+-				ret = -ENOMEM;
+-				goto out;
+-			}
+-		}
+-ParseLong:
+-		slots = 0;
+-		ds = (struct msdos_dir_slot *) de;
+-		id = ds->id;
+-		if (!(id & 0x40))
+-			goto RecEnd;
+-		slots = id & ~0x40;
+-		if (slots > 20 || !slots)	/* ceil(256 * 2 / 26) */
+-			goto RecEnd;
+-		long_slots = slots;
+-		alias_checksum = ds->alias_checksum;
+-
+-		slot = slots;
+-		while (1) {
+-			int offset;
+-
+-			slot--;
+-			offset = slot * 13;
+-			fat16_towchar(unicode + offset, ds->name0_4, 5);
+-			fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
+-			fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
+-
+-			if (ds->id & 0x40) {
+-				unicode[offset + 13] = 0;
+-			}
+-			if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
+-				goto EODir;
+-			if (slot == 0)
+-				break;
+-			ds = (struct msdos_dir_slot *) de;
+-			if (ds->attr !=  ATTR_EXT)
+-				goto RecEnd;	/* XXX */
+-			if ((ds->id & ~0x40) != slot)
+-				goto ParseLong;
+-			if (ds->alias_checksum != alias_checksum)
+-				goto ParseLong;
+-		}
+-		if (de->name[0] == DELETED_FLAG)
++		int status = fat_parse_long(inode, &cpos, &bh, &de,
++					    &unicode, &long_slots);
++		if (status < 0) {
++			filp->f_pos = cpos;
++			ret = status;
++			goto out;
++		} else if (status == PARSE_INVALID)
+ 			goto RecEnd;
+-		if (de->attr ==  ATTR_EXT)
+-			goto ParseLong;
+-		if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
+-			goto RecEnd;
+-		for (sum = 0, i = 0; i < 11; i++)
+-			sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
+-		if (sum != alias_checksum)
+-			long_slots = 0;
++		else if (status == PARSE_NOT_LONGNAME)
++			goto parse_record;
++		else if (status == PARSE_EOF)
++			goto EODir;
+ 	}
+ 
+ 	if (sbi->options.dotsOK) {
+@@ -671,7 +643,7 @@ out:
+ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ {
+ 	struct inode *inode = filp->f_dentry->d_inode;
+-	return fat_readdirx(inode, filp, dirent, filldir, 0, 0);
++	return __fat_readdir(inode, filp, dirent, filldir, 0, 0);
+ }
+ 
+ static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
+@@ -760,8 +732,8 @@ static int fat_dir_ioctl(struct inode * 
+ 	down(&inode->i_sem);
+ 	ret = -ENOENT;
+ 	if (!IS_DEADDIR(inode)) {
+-		ret = fat_readdirx(inode, filp, &buf, fat_ioctl_filldir,
+-				   short_only, both);
++		ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir,
++				    short_only, both);
+ 	}
+ 	up(&inode->i_sem);
+ 	if (ret >= 0)
+diff --git a/fs/file_table.c b/fs/file_table.c
+--- a/fs/file_table.c
++++ b/fs/file_table.c
+@@ -56,13 +56,13 @@ void filp_dtor(void * objp, struct kmem_
+ 
+ static inline void file_free_rcu(struct rcu_head *head)
+ {
+-	struct file *f =  container_of(head, struct file, f_rcuhead);
++	struct file *f =  container_of(head, struct file, f_u.fu_rcuhead);
+ 	kmem_cache_free(filp_cachep, f);
+ }
+ 
+ static inline void file_free(struct file *f)
+ {
+-	call_rcu(&f->f_rcuhead, file_free_rcu);
++	call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
+ }
+ 
+ /* Find an unused file structure and return a pointer to it.
+@@ -95,7 +95,7 @@ struct file *get_empty_filp(void)
+ 	f->f_gid = current->fsgid;
+ 	rwlock_init(&f->f_owner.lock);
+ 	/* f->f_version: 0 */
+-	INIT_LIST_HEAD(&f->f_list);
++	INIT_LIST_HEAD(&f->f_u.fu_list);
+ 	return f;
+ 
+ over:
+@@ -225,15 +225,15 @@ void file_move(struct file *file, struct
+ 	if (!list)
+ 		return;
+ 	file_list_lock();
+-	list_move(&file->f_list, list);
++	list_move(&file->f_u.fu_list, list);
+ 	file_list_unlock();
+ }
+ 
+ void file_kill(struct file *file)
+ {
+-	if (!list_empty(&file->f_list)) {
++	if (!list_empty(&file->f_u.fu_list)) {
+ 		file_list_lock();
+-		list_del_init(&file->f_list);
++		list_del_init(&file->f_u.fu_list);
+ 		file_list_unlock();
+ 	}
+ }
+@@ -245,7 +245,7 @@ int fs_may_remount_ro(struct super_block
+ 	/* Check that no files are currently opened for writing. */
+ 	file_list_lock();
+ 	list_for_each(p, &sb->s_files) {
+-		struct file *file = list_entry(p, struct file, f_list);
++		struct file *file = list_entry(p, struct file, f_u.fu_list);
+ 		struct inode *inode = file->f_dentry->d_inode;
+ 
+ 		/* File with pending delete? */
+diff --git a/fs/filesystems.c b/fs/filesystems.c
+--- a/fs/filesystems.c
++++ b/fs/filesystems.c
+@@ -12,6 +12,7 @@
+ #include <linux/kmod.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
++#include <linux/sched.h>	/* for 'current' */
+ #include <asm/uaccess.h>
+ 
+ /*
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -230,7 +230,6 @@ __sync_single_inode(struct inode *inode,
+ 			 * The inode is clean, unused
+ 			 */
+ 			list_move(&inode->i_list, &inode_unused);
+-			inodes_stat.nr_unused++;
+ 		}
+ 	}
+ 	wake_up_inode(inode);
+@@ -238,14 +237,20 @@ __sync_single_inode(struct inode *inode,
+ }
+ 
+ /*
+- * Write out an inode's dirty pages.  Called under inode_lock.
++ * Write out an inode's dirty pages.  Called under inode_lock.  Either the
++ * caller has ref on the inode (either via __iget or via syscall against an fd)
++ * or the inode has I_WILL_FREE set (via generic_forget_inode)
+  */
+ static int
+-__writeback_single_inode(struct inode *inode,
+-			struct writeback_control *wbc)
++__writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
+ {
+ 	wait_queue_head_t *wqh;
+ 
++	if (!atomic_read(&inode->i_count))
++		WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING)));
++	else
++		WARN_ON(inode->i_state & I_WILL_FREE);
++
+ 	if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
+ 		list_move(&inode->i_list, &inode->i_sb->s_dirty);
+ 		return 0;
+@@ -259,11 +264,9 @@ __writeback_single_inode(struct inode *i
+ 
+ 		wqh = bit_waitqueue(&inode->i_state, __I_LOCK);
+ 		do {
+-			__iget(inode);
+ 			spin_unlock(&inode_lock);
+ 			__wait_on_bit(wqh, &wq, inode_wait,
+ 							TASK_UNINTERRUPTIBLE);
+-			iput(inode);
+ 			spin_lock(&inode_lock);
+ 		} while (inode->i_state & I_LOCK);
+ 	}
+@@ -541,14 +544,15 @@ void sync_inodes(int wait)
+ }
+ 
+ /**
+- *	write_inode_now	-	write an inode to disk
+- *	@inode: inode to write to disk
+- *	@sync: whether the write should be synchronous or not
++ * write_inode_now	-	write an inode to disk
++ * @inode: inode to write to disk
++ * @sync: whether the write should be synchronous or not
++ *
++ * This function commits an inode to disk immediately if it is dirty. This is
++ * primarily needed by knfsd.
+  *
+- *	This function commits an inode to disk immediately if it is
+- *	dirty. This is primarily needed by knfsd.
++ * The caller must either have a ref on the inode or must have set I_WILL_FREE.
+  */
+- 
+ int write_inode_now(struct inode *inode, int sync)
+ {
+ 	int ret;
+diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -151,9 +151,9 @@ void fuse_release_background(struct fuse
+ /*
+  * This function is called when a request is finished.  Either a reply
+  * has arrived or it was interrupted (and not yet sent) or some error
+- * occured during communication with userspace, or the device file was
+- * closed.  It decreases the referece count for the request.  In case
+- * of a background request the referece to the stored objects are
++ * occurred during communication with userspace, or the device file was
++ * closed.  It decreases the reference count for the request.  In case
++ * of a background request the reference to the stored objects are
+  * released.  The requester thread is woken up (if still waiting), and
+  * finally the request is either freed or put on the unused_list
+  *
+diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -741,13 +741,14 @@ static struct dentry *fuse_lookup(struct
+ 	if (inode && S_ISDIR(inode->i_mode)) {
+ 		/* Don't allow creating an alias to a directory  */
+ 		struct dentry *alias = d_find_alias(inode);
+-		if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
++		if (alias) {
+ 			dput(alias);
+ 			iput(inode);
+ 			return ERR_PTR(-EIO);
+ 		}
+ 	}
+-	return d_splice_alias(inode, entry);
++	d_add(entry, inode);
++	return NULL;
+ }
+ 
+ static int fuse_setxattr(struct dentry *entry, const char *name,
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -349,22 +349,22 @@ int fuse_fsync_common(struct file *file,
+ 		      int isdir);
+ 
+ /**
+- * Initialise file operations on a regular file
++ * Initialize file operations on a regular file
+  */
+ void fuse_init_file_inode(struct inode *inode);
+ 
+ /**
+- * Initialise inode operations on regular files and special files
++ * Initialize inode operations on regular files and special files
+  */
+ void fuse_init_common(struct inode *inode);
+ 
+ /**
+- * Initialise inode and file operations on a directory
++ * Initialize inode and file operations on a directory
+  */
+ void fuse_init_dir(struct inode *inode);
+ 
+ /**
+- * Initialise inode operations on a symlink
++ * Initialize inode operations on a symlink
+  */
+ void fuse_init_symlink(struct inode *inode);
+ 
+@@ -411,7 +411,7 @@ struct fuse_req *fuse_get_request(struct
+ 
+ /**
+  * Decrement reference count of a request.  If count goes to zero put
+- * on unused list (preallocated) or free reqest (not preallocated).
++ * on unused list (preallocated) or free request (not preallocated).
+  */
+ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
+ 
+@@ -431,7 +431,7 @@ void request_send_noreply(struct fuse_co
+ void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
+ 
+ /**
+- * Release inodes and file assiciated with background request
++ * Release inodes and file associated with background request
+  */
+ void fuse_release_background(struct fuse_req *req);
+ 
+diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
+--- a/fs/hfs/inode.c
++++ b/fs/hfs/inode.c
+@@ -46,7 +46,7 @@ static sector_t hfs_bmap(struct address_
+ 	return generic_block_bmap(mapping, block, hfs_get_block);
+ }
+ 
+-static int hfs_releasepage(struct page *page, int mask)
++static int hfs_releasepage(struct page *page, gfp_t mask)
+ {
+ 	struct inode *inode = page->mapping->host;
+ 	struct super_block *sb = inode->i_sb;
+diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
+--- a/fs/hfsplus/inode.c
++++ b/fs/hfsplus/inode.c
+@@ -40,7 +40,7 @@ static sector_t hfsplus_bmap(struct addr
+ 	return generic_block_bmap(mapping, block, hfsplus_get_block);
+ }
+ 
+-static int hfsplus_releasepage(struct page *page, int mask)
++static int hfsplus_releasepage(struct page *page, gfp_t mask)
+ {
+ 	struct inode *inode = page->mapping->host;
+ 	struct super_block *sb = inode->i_sb;
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -45,10 +45,58 @@ static struct backing_dev_info hugetlbfs
+ 
+ int sysctl_hugetlb_shm_group;
+ 
++static void huge_pagevec_release(struct pagevec *pvec)
++{
++	int i;
++
++	for (i = 0; i < pagevec_count(pvec); ++i)
++		put_page(pvec->pages[i]);
++
++	pagevec_reinit(pvec);
++}
++
++/*
++ * huge_pages_needed tries to determine the number of new huge pages that
++ * will be required to fully populate this VMA.  This will be equal to
++ * the size of the VMA in huge pages minus the number of huge pages
++ * (covered by this VMA) that are found in the page cache.
++ *
++ * Result is in bytes to be compatible with is_hugepage_mem_enough()
++ */
++unsigned long
++huge_pages_needed(struct address_space *mapping, struct vm_area_struct *vma)
++{
++	int i;
++	struct pagevec pvec;
++	unsigned long start = vma->vm_start;
++	unsigned long end = vma->vm_end;
++	unsigned long hugepages = (end - start) >> HPAGE_SHIFT;
++	pgoff_t next = vma->vm_pgoff;
++	pgoff_t endpg = next + ((end - start) >> PAGE_SHIFT);
++
++	pagevec_init(&pvec, 0);
++	while (next < endpg) {
++		if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE))
++			break;
++		for (i = 0; i < pagevec_count(&pvec); i++) {
++			struct page *page = pvec.pages[i];
++			if (page->index > next)
++				next = page->index;
++			if (page->index >= endpg)
++				break;
++			next++;
++			hugepages--;
++		}
++		huge_pagevec_release(&pvec);
++	}
++	return hugepages << HPAGE_SHIFT;
++}
++
+ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+ {
+ 	struct inode *inode = file->f_dentry->d_inode;
+ 	struct address_space *mapping = inode->i_mapping;
++	unsigned long bytes;
+ 	loff_t len, vma_len;
+ 	int ret;
+ 
+@@ -67,6 +115,10 @@ static int hugetlbfs_file_mmap(struct fi
+ 	if (vma->vm_end - vma->vm_start < HPAGE_SIZE)
+ 		return -EINVAL;
+ 
++	bytes = huge_pages_needed(mapping, vma);
++	if (!is_hugepage_mem_enough(bytes))
++		return -ENOMEM;
++
+ 	vma_len = (loff_t)(vma->vm_end - vma->vm_start);
+ 
+ 	down(&inode->i_sem);
+@@ -79,10 +131,8 @@ static int hugetlbfs_file_mmap(struct fi
+ 	if (!(vma->vm_flags & VM_WRITE) && len > inode->i_size)
+ 		goto out;
+ 
+-	ret = hugetlb_prefault(mapping, vma);
+-	if (ret)
+-		goto out;
+-
++	ret = 0;
++	hugetlb_prefault_arch_hook(vma->vm_mm);
+ 	if (inode->i_size < len)
+ 		inode->i_size = len;
+ out:
+@@ -92,7 +142,7 @@ out:
+ }
+ 
+ /*
+- * Called under down_write(mmap_sem), page_table_lock is not held
++ * Called under down_write(mmap_sem).
+  */
+ 
+ #ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+@@ -171,16 +221,6 @@ static int hugetlbfs_commit_write(struct
+ 	return -EINVAL;
+ }
+ 
+-static void huge_pagevec_release(struct pagevec *pvec)
+-{
+-	int i;
+-
+-	for (i = 0; i < pagevec_count(pvec); ++i)
+-		put_page(pvec->pages[i]);
+-
+-	pagevec_reinit(pvec);
+-}
+-
+ static void truncate_huge_page(struct page *page)
+ {
+ 	clear_page_dirty(page);
+@@ -224,52 +264,35 @@ static void truncate_hugepages(struct ad
+ 
+ static void hugetlbfs_delete_inode(struct inode *inode)
+ {
+-	struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
+-
+-	hlist_del_init(&inode->i_hash);
+-	list_del_init(&inode->i_list);
+-	list_del_init(&inode->i_sb_list);
+-	inode->i_state |= I_FREEING;
+-	inodes_stat.nr_inodes--;
+-	spin_unlock(&inode_lock);
+-
+ 	if (inode->i_data.nrpages)
+ 		truncate_hugepages(&inode->i_data, 0);
+-
+-	security_inode_delete(inode);
+-
+-	if (sbinfo->free_inodes >= 0) {
+-		spin_lock(&sbinfo->stat_lock);
+-		sbinfo->free_inodes++;
+-		spin_unlock(&sbinfo->stat_lock);
+-	}
+-
+ 	clear_inode(inode);
+-	destroy_inode(inode);
+ }
+ 
+ static void hugetlbfs_forget_inode(struct inode *inode)
+ {
+-	struct super_block *super_block = inode->i_sb;
+-	struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(super_block);
+-
+-	if (hlist_unhashed(&inode->i_hash))
+-		goto out_truncate;
++	struct super_block *sb = inode->i_sb;
+ 
+-	if (!(inode->i_state & (I_DIRTY|I_LOCK))) {
+-		list_del(&inode->i_list);
+-		list_add(&inode->i_list, &inode_unused);
+-	}
+-	inodes_stat.nr_unused++;
+-	if (!super_block || (super_block->s_flags & MS_ACTIVE)) {
++	if (!hlist_unhashed(&inode->i_hash)) {
++		if (!(inode->i_state & (I_DIRTY|I_LOCK)))
++			list_move(&inode->i_list, &inode_unused);
++		inodes_stat.nr_unused++;
++		if (!sb || (sb->s_flags & MS_ACTIVE)) {
++			spin_unlock(&inode_lock);
++			return;
++		}
++		inode->i_state |= I_WILL_FREE;
+ 		spin_unlock(&inode_lock);
+-		return;
++		/*
++		 * write_inode_now is a noop as we set BDI_CAP_NO_WRITEBACK
++		 * in our backing_dev_info.
++		 */
++		write_inode_now(inode, 1);
++		spin_lock(&inode_lock);
++		inode->i_state &= ~I_WILL_FREE;
++		inodes_stat.nr_unused--;
++		hlist_del_init(&inode->i_hash);
+ 	}
+-
+-	/* write_inode_now() ? */
+-	inodes_stat.nr_unused--;
+-	hlist_del_init(&inode->i_hash);
+-out_truncate:
+ 	list_del_init(&inode->i_list);
+ 	list_del_init(&inode->i_sb_list);
+ 	inode->i_state |= I_FREEING;
+@@ -277,13 +300,6 @@ out_truncate:
+ 	spin_unlock(&inode_lock);
+ 	if (inode->i_data.nrpages)
+ 		truncate_hugepages(&inode->i_data, 0);
+-
+-	if (sbinfo->free_inodes >= 0) {
+-		spin_lock(&sbinfo->stat_lock);
+-		sbinfo->free_inodes++;
+-		spin_unlock(&sbinfo->stat_lock);
+-	}
+-
+ 	clear_inode(inode);
+ 	destroy_inode(inode);
+ }
+@@ -291,7 +307,7 @@ out_truncate:
+ static void hugetlbfs_drop_inode(struct inode *inode)
+ {
+ 	if (!inode->i_nlink)
+-		hugetlbfs_delete_inode(inode);
++		generic_delete_inode(inode);
+ 	else
+ 		hugetlbfs_forget_inode(inode);
+ }
+@@ -308,7 +324,6 @@ hugetlb_vmtruncate_list(struct prio_tree
+ 
+ 	vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) {
+ 		unsigned long h_vm_pgoff;
+-		unsigned long v_length;
+ 		unsigned long v_offset;
+ 
+ 		h_vm_pgoff = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT);
+@@ -319,11 +334,8 @@ hugetlb_vmtruncate_list(struct prio_tree
+ 		if (h_vm_pgoff >= h_pgoff)
+ 			v_offset = 0;
+ 
+-		v_length = vma->vm_end - vma->vm_start;
+-
+-		zap_hugepage_range(vma,
+-				vma->vm_start + v_offset,
+-				v_length - v_offset);
++		unmap_hugepage_range(vma,
++				vma->vm_start + v_offset, vma->vm_end);
+ 	}
+ }
+ 
+@@ -379,17 +391,6 @@ static struct inode *hugetlbfs_get_inode
+ 					gid_t gid, int mode, dev_t dev)
+ {
+ 	struct inode *inode;
+-	struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
+-
+-	if (sbinfo->free_inodes >= 0) {
+-		spin_lock(&sbinfo->stat_lock);
+-		if (!sbinfo->free_inodes) {
+-			spin_unlock(&sbinfo->stat_lock);
+-			return NULL;
+-		}
+-		sbinfo->free_inodes--;
+-		spin_unlock(&sbinfo->stat_lock);
+-	}
+ 
+ 	inode = new_inode(sb);
+ 	if (inode) {
+@@ -531,29 +532,51 @@ static void hugetlbfs_put_super(struct s
+ 	}
+ }
+ 
++static inline int hugetlbfs_dec_free_inodes(struct hugetlbfs_sb_info *sbinfo)
++{
++	if (sbinfo->free_inodes >= 0) {
++		spin_lock(&sbinfo->stat_lock);
++		if (unlikely(!sbinfo->free_inodes)) {
++			spin_unlock(&sbinfo->stat_lock);
++			return 0;
++		}
++		sbinfo->free_inodes--;
++		spin_unlock(&sbinfo->stat_lock);
++	}
++
++	return 1;
++}
++
++static void hugetlbfs_inc_free_inodes(struct hugetlbfs_sb_info *sbinfo)
++{
++	if (sbinfo->free_inodes >= 0) {
++		spin_lock(&sbinfo->stat_lock);
++		sbinfo->free_inodes++;
++		spin_unlock(&sbinfo->stat_lock);
++	}
++}
++
++
+ static kmem_cache_t *hugetlbfs_inode_cachep;
+ 
+ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
+ {
++	struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
+ 	struct hugetlbfs_inode_info *p;
+ 
++	if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo)))
++		return NULL;
+ 	p = kmem_cache_alloc(hugetlbfs_inode_cachep, SLAB_KERNEL);
+-	if (!p)
++	if (unlikely(!p)) {
++		hugetlbfs_inc_free_inodes(sbinfo);
+ 		return NULL;
++	}
+ 	return &p->vfs_inode;
+ }
+ 
+-static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
+-{
+-	struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
+-
+-	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+-	    SLAB_CTOR_CONSTRUCTOR)
+-		inode_init_once(&ei->vfs_inode);
+-}
+-
+ static void hugetlbfs_destroy_inode(struct inode *inode)
+ {
++	hugetlbfs_inc_free_inodes(HUGETLBFS_SB(inode->i_sb));
+ 	mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy);
+ 	kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
+ }
+@@ -565,6 +588,16 @@ static struct address_space_operations h
+ 	.set_page_dirty	= hugetlbfs_set_page_dirty,
+ };
+ 
++
++static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
++{
++	struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
++
++	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
++	    SLAB_CTOR_CONSTRUCTOR)
++		inode_init_once(&ei->vfs_inode);
++}
++
+ struct file_operations hugetlbfs_file_operations = {
+ 	.mmap			= hugetlbfs_file_mmap,
+ 	.fsync			= simple_sync_file,
+@@ -592,6 +625,7 @@ static struct super_operations hugetlbfs
+ 	.alloc_inode    = hugetlbfs_alloc_inode,
+ 	.destroy_inode  = hugetlbfs_destroy_inode,
+ 	.statfs		= hugetlbfs_statfs,
++	.delete_inode	= hugetlbfs_delete_inode,
+ 	.drop_inode	= hugetlbfs_drop_inode,
+ 	.put_super	= hugetlbfs_put_super,
+ };
+diff --git a/fs/inode.c b/fs/inode.c
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -475,7 +475,7 @@ static void prune_icache(int nr_to_scan)
+  * This function is passed the number of inodes to scan, and it returns the
+  * total number of remaining possibly-reclaimable inodes.
+  */
+-static int shrink_icache_memory(int nr, unsigned int gfp_mask)
++static int shrink_icache_memory(int nr, gfp_t gfp_mask)
+ {
+ 	if (nr) {
+ 		/*
+@@ -1088,6 +1088,7 @@ static void generic_forget_inode(struct 
+ 	if (inode->i_data.nrpages)
+ 		truncate_inode_pages(&inode->i_data, 0);
+ 	clear_inode(inode);
++	wake_up_inode(inode);
+ 	destroy_inode(inode);
+ }
+ 
+diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
+--- a/fs/jbd/journal.c
++++ b/fs/jbd/journal.c
+@@ -1606,7 +1606,7 @@ int journal_blocks_per_page(struct inode
+  * Simple support for retrying memory allocations.  Introduced to help to
+  * debug different VM deadlock avoidance strategies. 
+  */
+-void * __jbd_kmalloc (const char *where, size_t size, int flags, int retry)
++void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
+ {
+ 	return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
+ }
+diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
+--- a/fs/jbd/transaction.c
++++ b/fs/jbd/transaction.c
+@@ -1621,7 +1621,7 @@ out:
+  * while the data is part of a transaction.  Yes?
+  */
+ int journal_try_to_free_buffers(journal_t *journal, 
+-				struct page *page, int unused_gfp_mask)
++				struct page *page, gfp_t unused_gfp_mask)
+ {
+ 	struct buffer_head *head;
+ 	struct buffer_head *bh;
+diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
+--- a/fs/jffs2/background.c
++++ b/fs/jffs2/background.c
+@@ -15,6 +15,7 @@
+ #include <linux/jffs2.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/completion.h>
++#include <linux/sched.h>
+ #include "nodelist.h"
+ 
+ 
+diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
+--- a/fs/jffs2/wbuf.c
++++ b/fs/jffs2/wbuf.c
+@@ -18,6 +18,8 @@
+ #include <linux/mtd/mtd.h>
+ #include <linux/crc32.h>
+ #include <linux/mtd/nand.h>
++#include <linux/jiffies.h>
++
+ #include "nodelist.h"
+ 
+ /* For testing write failures */
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -74,7 +74,7 @@
+ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+ 			int nblocks);
+ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval);
+-static void dbBackSplit(dmtree_t * tp, int leafno);
++static int dbBackSplit(dmtree_t * tp, int leafno);
+ static int dbJoin(dmtree_t * tp, int leafno, int newval);
+ static void dbAdjTree(dmtree_t * tp, int leafno, int newval);
+ static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc,
+@@ -305,7 +305,6 @@ int dbSync(struct inode *ipbmap)
+ 	filemap_fdatawrite(ipbmap->i_mapping);
+ 	filemap_fdatawait(ipbmap->i_mapping);
+ 
+-	ipbmap->i_state |= I_DIRTY;
+ 	diWriteSpecial(ipbmap, 0);
+ 
+ 	return (0);
+@@ -2467,7 +2466,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, i
+ 		 * that it is at the front of a binary buddy system.
+ 		 */
+ 		if (oldval == NOFREE) {
+-			dbBackSplit((dmtree_t *) dcp, leafno);
++			rc = dbBackSplit((dmtree_t *) dcp, leafno);
++			if (rc)
++				return rc;
+ 			oldval = dcp->stree[ti];
+ 		}
+ 		dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval);
+@@ -2627,7 +2628,7 @@ static void dbSplit(dmtree_t * tp, int l
+  *
+  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
+  */
+-static void dbBackSplit(dmtree_t * tp, int leafno)
++static int dbBackSplit(dmtree_t * tp, int leafno)
+ {
+ 	int budsz, bud, w, bsz, size;
+ 	int cursz;
+@@ -2662,7 +2663,10 @@ static void dbBackSplit(dmtree_t * tp, i
+ 		 */
+ 		for (w = leafno, bsz = budsz;; bsz <<= 1,
+ 		     w = (w < bud) ? w : bud) {
+-			assert(bsz < le32_to_cpu(tp->dmt_nleafs));
++			if (bsz >= le32_to_cpu(tp->dmt_nleafs)) {
++				jfs_err("JFS: block map error in dbBackSplit");
++				return -EIO;
++			}
+ 
+ 			/* determine the buddy.
+ 			 */
+@@ -2681,7 +2685,11 @@ static void dbBackSplit(dmtree_t * tp, i
+ 		}
+ 	}
+ 
+-	assert(leaf[leafno] == size);
++	if (leaf[leafno] != size) {
++		jfs_err("JFS: wrong leaf value in dbBackSplit");
++		return -EIO;
++	}
++	return 0;
+ }
+ 
+ 
+diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
+--- a/fs/jfs/jfs_imap.c
++++ b/fs/jfs/jfs_imap.c
+@@ -57,6 +57,12 @@
+ #include "jfs_debug.h"
+ 
+ /*
++ * __mark_inode_dirty expects inodes to be hashed.  Since we don't want
++ * special inodes in the fileset inode space, we hash them to a dummy head
++ */
++static HLIST_HEAD(aggregate_hash);
++
++/*
+  * imap locks
+  */
+ /* iag free list lock */
+@@ -491,6 +497,8 @@ struct inode *diReadSpecial(struct super
+ 	/* release the page */
+ 	release_metapage(mp);
+ 
++	hlist_add_head(&ip->i_hash, &aggregate_hash);
++
+ 	return (ip);
+ }
+ 
+@@ -514,8 +522,6 @@ void diWriteSpecial(struct inode *ip, in
+ 	ino_t inum = ip->i_ino;
+ 	struct metapage *mp;
+ 
+-	ip->i_state &= ~I_DIRTY;
+-
+ 	if (secondary)
+ 		address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
+ 	else
+diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
+--- a/fs/jfs/jfs_metapage.c
++++ b/fs/jfs/jfs_metapage.c
+@@ -86,7 +86,7 @@ struct meta_anchor {
+ 	atomic_t io_count;
+ 	struct metapage *mp[MPS_PER_PAGE];
+ };
+-#define mp_anchor(page) ((struct meta_anchor *)page->private)
++#define mp_anchor(page) ((struct meta_anchor *)page_private(page))
+ 
+ static inline struct metapage *page_to_mp(struct page *page, uint offset)
+ {
+@@ -108,7 +108,7 @@ static inline int insert_metapage(struct
+ 		if (!a)
+ 			return -ENOMEM;
+ 		memset(a, 0, sizeof(struct meta_anchor));
+-		page->private = (unsigned long)a;
++		set_page_private(page, (unsigned long)a);
+ 		SetPagePrivate(page);
+ 		kmap(page);
+ 	}
+@@ -136,7 +136,7 @@ static inline void remove_metapage(struc
+ 	a->mp[index] = NULL;
+ 	if (--a->mp_count == 0) {
+ 		kfree(a);
+-		page->private = 0;
++		set_page_private(page, 0);
+ 		ClearPagePrivate(page);
+ 		kunmap(page);
+ 	}
+@@ -156,13 +156,13 @@ static inline void dec_io(struct page *p
+ #else
+ static inline struct metapage *page_to_mp(struct page *page, uint offset)
+ {
+-	return PagePrivate(page) ? (struct metapage *)page->private : NULL;
++	return PagePrivate(page) ? (struct metapage *)page_private(page) : NULL;
+ }
+ 
+ static inline int insert_metapage(struct page *page, struct metapage *mp)
+ {
+ 	if (mp) {
+-		page->private = (unsigned long)mp;
++		set_page_private(page, (unsigned long)mp);
+ 		SetPagePrivate(page);
+ 		kmap(page);
+ 	}
+@@ -171,7 +171,7 @@ static inline int insert_metapage(struct
+ 
+ static inline void remove_metapage(struct page *page, struct metapage *mp)
+ {
+-	page->private = 0;
++	set_page_private(page, 0);
+ 	ClearPagePrivate(page);
+ 	kunmap(page);
+ }
+@@ -198,7 +198,7 @@ static void init_once(void *foo, kmem_ca
+ 	}
+ }
+ 
+-static inline struct metapage *alloc_metapage(unsigned int gfp_mask)
++static inline struct metapage *alloc_metapage(gfp_t gfp_mask)
+ {
+ 	return mempool_alloc(metapage_mempool, gfp_mask);
+ }
+@@ -395,6 +395,12 @@ static int metapage_writepage(struct pag
+ 
+ 		if (mp->nohomeok && !test_bit(META_forcewrite, &mp->flag)) {
+ 			redirty = 1;
++			/*
++			 * Make sure this page isn't blocked indefinitely.
++			 * If the journal isn't undergoing I/O, push it
++			 */
++			if (mp->log && !(mp->log->cflag & logGC_PAGEOUT))
++				jfs_flush_journal(mp->log, 0);
+ 			continue;
+ 		}
+ 
+@@ -534,7 +540,7 @@ add_failed:
+ 	return -EIO;
+ }
+ 
+-static int metapage_releasepage(struct page *page, int gfp_mask)
++static int metapage_releasepage(struct page *page, gfp_t gfp_mask)
+ {
+ 	struct metapage *mp;
+ 	int busy = 0;
+diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
+--- a/fs/jfs/jfs_txnmgr.c
++++ b/fs/jfs/jfs_txnmgr.c
+@@ -2396,7 +2396,6 @@ static void txUpdateMap(struct tblock * 
+ 	 */
+ 	if (tblk->xflag & COMMIT_CREATE) {
+ 		diUpdatePMap(ipimap, tblk->ino, FALSE, tblk);
+-		ipimap->i_state |= I_DIRTY;
+ 		/* update persistent block allocation map
+ 		 * for the allocation of inode extent;
+ 		 */
+@@ -2407,7 +2406,6 @@ static void txUpdateMap(struct tblock * 
+ 	} else if (tblk->xflag & COMMIT_DELETE) {
+ 		ip = tblk->u.ip;
+ 		diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
+-		ipimap->i_state |= I_DIRTY;
+ 		iput(ip);
+ 	}
+ }
+diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
+--- a/fs/jfs/jfs_xtree.c
++++ b/fs/jfs/jfs_xtree.c
+@@ -3516,16 +3516,10 @@ s64 xtTruncate(tid_t tid, struct inode *
+ 	/* process entries backward from last index */
+ 	index = le16_to_cpu(p->header.nextindex) - 1;
+ 
+-	if (p->header.flag & BT_INTERNAL)
+-		goto getChild;
+-
+-	/*
+-	 *      leaf page
+-	 */
+ 
+-	/* Since this is the rightmost leaf, and we may have already freed
+-	 * a page that was formerly to the right, let's make sure that the
+-	 * next pointer is zero.
++	/* Since this is the rightmost page at this level, and we may have
++	 * already freed a page that was formerly to the right, let's make
++	 * sure that the next pointer is zero.
+ 	 */
+ 	if (p->header.next) {
+ 		if (log)
+@@ -3539,6 +3533,12 @@ s64 xtTruncate(tid_t tid, struct inode *
+ 		p->header.next = 0;
+ 	}
+ 
++	if (p->header.flag & BT_INTERNAL)
++		goto getChild;
++
++	/*
++	 *      leaf page
++	 */
+ 	freed = 0;
+ 
+ 	/* does region covered by leaf page precede Teof ? */
+diff --git a/fs/jfs/super.c b/fs/jfs/super.c
+--- a/fs/jfs/super.c
++++ b/fs/jfs/super.c
+@@ -442,6 +442,7 @@ static int jfs_fill_super(struct super_b
+ 	inode->i_nlink = 1;
+ 	inode->i_size = sb->s_bdev->bd_inode->i_size;
+ 	inode->i_mapping->a_ops = &jfs_metapage_aops;
++	insert_inode_hash(inode);
+ 	mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
+ 
+ 	sbi->direct_inode = inode;
+diff --git a/fs/lockd/host.c b/fs/lockd/host.c
+--- a/fs/lockd/host.c
++++ b/fs/lockd/host.c
+@@ -173,11 +173,10 @@ nlm_bind_host(struct nlm_host *host)
+ 
+ 	/* If we've already created an RPC client, check whether
+ 	 * RPC rebind is required
+-	 * Note: why keep rebinding if we're on a tcp connection?
+ 	 */
+ 	if ((clnt = host->h_rpcclnt) != NULL) {
+ 		xprt = clnt->cl_xprt;
+-		if (!xprt->stream && time_after_eq(jiffies, host->h_nextrebind)) {
++		if (time_after_eq(jiffies, host->h_nextrebind)) {
+ 			clnt->cl_port = 0;
+ 			host->h_nextrebind = jiffies + NLM_HOST_REBIND;
+ 			dprintk("lockd: next rebind in %ld jiffies\n",
+@@ -189,7 +188,6 @@ nlm_bind_host(struct nlm_host *host)
+ 			goto forgetit;
+ 
+ 		xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout);
+-		xprt->nocong = 1;	/* No congestion control for NLM */
+ 		xprt->resvport = 1;	/* NLM requires a reserved port */
+ 
+ 		/* Existing NLM servers accept AUTH_UNIX only */
+diff --git a/fs/locks.c b/fs/locks.c
+--- a/fs/locks.c
++++ b/fs/locks.c
+@@ -316,21 +316,22 @@ static int flock_to_posix_lock(struct fi
+ 	/* POSIX-1996 leaves the case l->l_len < 0 undefined;
+ 	   POSIX-2001 defines it. */
+ 	start += l->l_start;
+-	end = start + l->l_len - 1;
+-	if (l->l_len < 0) {
++	if (start < 0)
++		return -EINVAL;
++	fl->fl_end = OFFSET_MAX;
++	if (l->l_len > 0) {
++		end = start + l->l_len - 1;
++		fl->fl_end = end;
++	} else if (l->l_len < 0) {
+ 		end = start - 1;
++		fl->fl_end = end;
+ 		start += l->l_len;
++		if (start < 0)
++			return -EINVAL;
+ 	}
+-
+-	if (start < 0)
+-		return -EINVAL;
+-	if (l->l_len > 0 && end < 0)
+-		return -EOVERFLOW;
+-
+ 	fl->fl_start = start;	/* we record the absolute position */
+-	fl->fl_end = end;
+-	if (l->l_len == 0)
+-		fl->fl_end = OFFSET_MAX;
++	if (fl->fl_end < fl->fl_start)
++		return -EOVERFLOW;
+ 	
+ 	fl->fl_owner = current->files;
+ 	fl->fl_pid = current->tgid;
+@@ -362,14 +363,21 @@ static int flock64_to_posix_lock(struct 
+ 		return -EINVAL;
+ 	}
+ 
+-	if (((start += l->l_start) < 0) || (l->l_len < 0))
++	start += l->l_start;
++	if (start < 0)
+ 		return -EINVAL;
+-	fl->fl_end = start + l->l_len - 1;
+-	if (l->l_len > 0 && fl->fl_end < 0)
+-		return -EOVERFLOW;
++	fl->fl_end = OFFSET_MAX;
++	if (l->l_len > 0) {
++		fl->fl_end = start + l->l_len - 1;
++	} else if (l->l_len < 0) {
++		fl->fl_end = start - 1;
++		start += l->l_len;
++		if (start < 0)
++			return -EINVAL;
++	}
+ 	fl->fl_start = start;	/* we record the absolute position */
+-	if (l->l_len == 0)
+-		fl->fl_end = OFFSET_MAX;
++	if (fl->fl_end < fl->fl_start)
++		return -EOVERFLOW;
+ 	
+ 	fl->fl_owner = current->files;
+ 	fl->fl_pid = current->tgid;
+@@ -829,12 +837,16 @@ static int __posix_lock_file(struct inod
+ 		/* Detect adjacent or overlapping regions (if same lock type)
+ 		 */
+ 		if (request->fl_type == fl->fl_type) {
++			/* In all comparisons of start vs end, use
++			 * "start - 1" rather than "end + 1". If end
++			 * is OFFSET_MAX, end + 1 will become negative.
++			 */
+ 			if (fl->fl_end < request->fl_start - 1)
+ 				goto next_lock;
+ 			/* If the next lock in the list has entirely bigger
+ 			 * addresses than the new one, insert the lock here.
+ 			 */
+-			if (fl->fl_start > request->fl_end + 1)
++			if (fl->fl_start - 1 > request->fl_end)
+ 				break;
+ 
+ 			/* If we come here, the new and old lock are of the
+diff --git a/fs/mbcache.c b/fs/mbcache.c
+--- a/fs/mbcache.c
++++ b/fs/mbcache.c
+@@ -116,7 +116,7 @@ mb_cache_indexes(struct mb_cache *cache)
+  * What the mbcache registers as to get shrunk dynamically.
+  */
+ 
+-static int mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask);
++static int mb_cache_shrink_fn(int nr_to_scan, gfp_t gfp_mask);
+ 
+ 
+ static inline int
+@@ -140,7 +140,7 @@ __mb_cache_entry_unhash(struct mb_cache_
+ 
+ 
+ static inline void
+-__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
++__mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask)
+ {
+ 	struct mb_cache *cache = ce->e_cache;
+ 
+@@ -193,7 +193,7 @@ forget:
+  * Returns the number of objects which are present in the cache.
+  */
+ static int
+-mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask)
++mb_cache_shrink_fn(int nr_to_scan, gfp_t gfp_mask)
+ {
+ 	LIST_HEAD(free_list);
+ 	struct list_head *l, *ltmp;
+diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
+--- a/fs/msdos/namei.c
++++ b/fs/msdos/namei.c
+@@ -454,10 +454,10 @@ static int do_msdos_rename(struct inode 
+ {
+ 	struct buffer_head *dotdot_bh;
+ 	struct msdos_dir_entry *dotdot_de;
+-	loff_t dotdot_i_pos;
+ 	struct inode *old_inode, *new_inode;
+ 	struct fat_slot_info old_sinfo, sinfo;
+ 	struct timespec ts;
++	loff_t dotdot_i_pos, new_i_pos;
+ 	int err, old_attrs, is_dir, update_dotdot, corrupt = 0;
+ 
+ 	old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
+@@ -516,28 +516,24 @@ static int do_msdos_rename(struct inode 
+ 	if (new_inode) {
+ 		if (err)
+ 			goto out;
+-		if (MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
+-			/* WTF??? Cry and fail. */
+-			printk(KERN_WARNING "msdos_rename: fs corrupted\n");
+-			goto out;
+-		}
+-
+ 		if (is_dir) {
+ 			err = fat_dir_empty(new_inode);
+ 			if (err)
+ 				goto out;
+ 		}
++		new_i_pos = MSDOS_I(new_inode)->i_pos;
+ 		fat_detach(new_inode);
+ 	} else {
+ 		err = msdos_add_entry(new_dir, new_name, is_dir, is_hid, 0,
+ 				      &ts, &sinfo);
+ 		if (err)
+ 			goto out;
++		new_i_pos = sinfo.i_pos;
+ 	}
+ 	new_dir->i_version++;
+ 
+ 	fat_detach(old_inode);
+-	fat_attach(old_inode, sinfo.i_pos);
++	fat_attach(old_inode, new_i_pos);
+ 	if (is_hid)
+ 		MSDOS_I(old_inode)->i_attrs |= ATTR_HIDDEN;
+ 	else
+@@ -604,7 +600,7 @@ error_inode:
+ 	fat_attach(old_inode, old_sinfo.i_pos);
+ 	MSDOS_I(old_inode)->i_attrs = old_attrs;
+ 	if (new_inode) {
+-		fat_attach(new_inode, sinfo.i_pos);
++		fat_attach(new_inode, new_i_pos);
+ 		if (corrupt)
+ 			corrupt |= fat_sync_inode(new_inode);
+ 	} else {
+diff --git a/fs/namei.c b/fs/namei.c
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -28,6 +28,7 @@
+ #include <linux/syscalls.h>
+ #include <linux/mount.h>
+ #include <linux/audit.h>
++#include <linux/file.h>
+ #include <asm/namei.h>
+ #include <asm/uaccess.h>
+ 
+@@ -317,6 +318,18 @@ void path_release_on_umount(struct namei
+ 	mntput_no_expire(nd->mnt);
+ }
+ 
++/**
++ * release_open_intent - free up open intent resources
++ * @nd: pointer to nameidata
++ */
++void release_open_intent(struct nameidata *nd)
++{
++	if (nd->intent.open.file->f_dentry == NULL)
++		put_filp(nd->intent.open.file);
++	else
++		fput(nd->intent.open.file);
++}
++
+ /*
+  * Internal lookup() using the new generic dcache.
+  * SMP-safe
+@@ -750,6 +763,7 @@ static fastcall int __link_path_walk(con
+ 		struct qstr this;
+ 		unsigned int c;
+ 
++		nd->flags |= LOOKUP_CONTINUE;
+ 		err = exec_permission_lite(inode, nd);
+ 		if (err == -EAGAIN) { 
+ 			err = permission(inode, MAY_EXEC, nd);
+@@ -802,7 +816,6 @@ static fastcall int __link_path_walk(con
+ 			if (err < 0)
+ 				break;
+ 		}
+-		nd->flags |= LOOKUP_CONTINUE;
+ 		/* This does the actual lookups.. */
+ 		err = do_lookup(nd, &this, &next);
+ 		if (err)
+@@ -1052,6 +1065,70 @@ out:
+ 	return retval;
+ }
+ 
++static int __path_lookup_intent_open(const char *name, unsigned int lookup_flags,
++		struct nameidata *nd, int open_flags, int create_mode)
++{
++	struct file *filp = get_empty_filp();
++	int err;
++
++	if (filp == NULL)
++		return -ENFILE;
++	nd->intent.open.file = filp;
++	nd->intent.open.flags = open_flags;
++	nd->intent.open.create_mode = create_mode;
++	err = path_lookup(name, lookup_flags|LOOKUP_OPEN, nd);
++	if (IS_ERR(nd->intent.open.file)) {
++		if (err == 0) {
++			err = PTR_ERR(nd->intent.open.file);
++			path_release(nd);
++		}
++	} else if (err != 0)
++		release_open_intent(nd);
++	return err;
++}
++
++/**
++ * path_lookup_open - lookup a file path with open intent
++ * @name: pointer to file name
++ * @lookup_flags: lookup intent flags
++ * @nd: pointer to nameidata
++ * @open_flags: open intent flags
++ */
++int path_lookup_open(const char *name, unsigned int lookup_flags,
++		struct nameidata *nd, int open_flags)
++{
++	return __path_lookup_intent_open(name, lookup_flags, nd,
++			open_flags, 0);
++}
++
++/**
++ * path_lookup_create - lookup a file path with open + create intent
++ * @name: pointer to file name
++ * @lookup_flags: lookup intent flags
++ * @nd: pointer to nameidata
++ * @open_flags: open intent flags
++ * @create_mode: create intent flags
++ */
++int path_lookup_create(const char *name, unsigned int lookup_flags,
++		struct nameidata *nd, int open_flags, int create_mode)
++{
++	return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd,
++			open_flags, create_mode);
++}
++
++int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags,
++		struct nameidata *nd, int open_flags)
++{
++	char *tmp = getname(name);
++	int err = PTR_ERR(tmp);
++
++	if (!IS_ERR(tmp)) {
++		err = __path_lookup_intent_open(tmp, lookup_flags, nd, open_flags, 0);
++		putname(tmp);
++	}
++	return err;
++}
++
+ /*
+  * Restricted form of lookup. Doesn't follow links, single-component only,
+  * needs parent already locked. Doesn't follow mounts.
+@@ -1234,9 +1311,6 @@ static inline int may_create(struct inod
+ }
+ 
+ /* 
+- * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
+- * reasons.
+- *
+  * O_DIRECTORY translates into forcing a directory lookup.
+  */
+ static inline int lookup_flags(unsigned int f)
+@@ -1246,9 +1320,6 @@ static inline int lookup_flags(unsigned 
+ 	if (f & O_NOFOLLOW)
+ 		retval &= ~LOOKUP_FOLLOW;
+ 	
+-	if ((f & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
+-		retval &= ~LOOKUP_FOLLOW;
+-	
+ 	if (f & O_DIRECTORY)
+ 		retval |= LOOKUP_DIRECTORY;
+ 
+@@ -1416,27 +1487,27 @@ int may_open(struct nameidata *nd, int a
+  */
+ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
+ {
+-	int acc_mode, error = 0;
++	int acc_mode, error;
+ 	struct path path;
+ 	struct dentry *dir;
+ 	int count = 0;
+ 
+ 	acc_mode = ACC_MODE(flag);
+ 
++	/* O_TRUNC implies we need access checks for write permissions */
++	if (flag & O_TRUNC)
++		acc_mode |= MAY_WRITE;
++
+ 	/* Allow the LSM permission hook to distinguish append 
+ 	   access from general write access. */
+ 	if (flag & O_APPEND)
+ 		acc_mode |= MAY_APPEND;
+ 
+-	/* Fill in the open() intent data */
+-	nd->intent.open.flags = flag;
+-	nd->intent.open.create_mode = mode;
+-
+ 	/*
+ 	 * The simplest case - just a plain lookup.
+ 	 */
+ 	if (!(flag & O_CREAT)) {
+-		error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);
++		error = path_lookup_open(pathname, lookup_flags(flag), nd, flag);
+ 		if (error)
+ 			return error;
+ 		goto ok;
+@@ -1445,7 +1516,7 @@ int open_namei(const char * pathname, in
+ 	/*
+ 	 * Create - we need to know the parent.
+ 	 */
+-	error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd);
++	error = path_lookup_create(pathname, LOOKUP_PARENT, nd, flag, mode);
+ 	if (error)
+ 		return error;
+ 
+@@ -1520,6 +1591,8 @@ ok:
+ exit_dput:
+ 	dput_path(&path, nd);
+ exit:
++	if (!IS_ERR(nd->intent.open.file))
++		release_open_intent(nd);
+ 	path_release(nd);
+ 	return error;
+ 
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -142,7 +142,7 @@ static void nfs_msync_inode(struct inode
+ /*
+  * Basic procedure for returning a delegation to the server
+  */
+-int nfs_inode_return_delegation(struct inode *inode)
++int __nfs_inode_return_delegation(struct inode *inode)
+ {
+ 	struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state;
+ 	struct nfs_inode *nfsi = NFS_I(inode);
+diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
+--- a/fs/nfs/delegation.h
++++ b/fs/nfs/delegation.h
+@@ -25,7 +25,7 @@ struct nfs_delegation {
+ 
+ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
+ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
+-int nfs_inode_return_delegation(struct inode *inode);
++int __nfs_inode_return_delegation(struct inode *inode);
+ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
+ 
+ struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle);
+@@ -47,11 +47,25 @@ static inline int nfs_have_delegation(st
+ 		return 1;
+ 	return 0;
+ }
++
++static inline int nfs_inode_return_delegation(struct inode *inode)
++{
++	int err = 0;
++
++	if (NFS_I(inode)->delegation != NULL)
++		err = __nfs_inode_return_delegation(inode);
++	return err;
++}
+ #else
+ static inline int nfs_have_delegation(struct inode *inode, int flags)
+ {
+ 	return 0;
+ }
++
++static inline int nfs_inode_return_delegation(struct inode *inode)
++{
++	return 0;
++}
+ #endif
+ 
+ #endif
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -532,6 +532,7 @@ static int nfs_readdir(struct file *filp
+ 	my_entry.eof = 0;
+ 	my_entry.fh = &fh;
+ 	my_entry.fattr = &fattr;
++	nfs_fattr_init(&fattr);
+ 	desc->entry = &my_entry;
+ 
+ 	while(!desc->entry->eof) {
+@@ -565,8 +566,6 @@ static int nfs_readdir(struct file *filp
+ 		}
+ 	}
+ 	unlock_kernel();
+-	if (desc->error < 0)
+-		return desc->error;
+ 	if (res < 0)
+ 		return res;
+ 	return 0;
+@@ -803,6 +802,7 @@ static int nfs_dentry_delete(struct dent
+  */
+ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
+ {
++	nfs_inode_return_delegation(inode);
+ 	if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
+ 		lock_kernel();
+ 		inode->i_nlink--;
+@@ -853,12 +853,6 @@ static struct dentry *nfs_lookup(struct 
+ 	dentry->d_op = NFS_PROTO(dir)->dentry_ops;
+ 
+ 	lock_kernel();
+-	/* Revalidate parent directory attribute cache */
+-	error = nfs_revalidate_inode(NFS_SERVER(dir), dir);
+-	if (error < 0) {
+-		res = ERR_PTR(error);
+-		goto out_unlock;
+-	}
+ 
+ 	/* If we're doing an exclusive create, optimize away the lookup */
+ 	if (nfs_is_exclusive_create(dir, nd))
+@@ -916,7 +910,6 @@ static int is_atomic_open(struct inode *
+ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+ {
+ 	struct dentry *res = NULL;
+-	struct inode *inode = NULL;
+ 	int error;
+ 
+ 	/* Check that we are indeed trying to open this file */
+@@ -930,8 +923,10 @@ static struct dentry *nfs_atomic_lookup(
+ 	dentry->d_op = NFS_PROTO(dir)->dentry_ops;
+ 
+ 	/* Let vfs_create() deal with O_EXCL */
+-	if (nd->intent.open.flags & O_EXCL)
+-		goto no_entry;
++	if (nd->intent.open.flags & O_EXCL) {
++		d_add(dentry, NULL);
++		goto out;
++	}
+ 
+ 	/* Open the file on the server */
+ 	lock_kernel();
+@@ -945,32 +940,30 @@ static struct dentry *nfs_atomic_lookup(
+ 
+ 	if (nd->intent.open.flags & O_CREAT) {
+ 		nfs_begin_data_update(dir);
+-		inode = nfs4_atomic_open(dir, dentry, nd);
++		res = nfs4_atomic_open(dir, dentry, nd);
+ 		nfs_end_data_update(dir);
+ 	} else
+-		inode = nfs4_atomic_open(dir, dentry, nd);
++		res = nfs4_atomic_open(dir, dentry, nd);
+ 	unlock_kernel();
+-	if (IS_ERR(inode)) {
+-		error = PTR_ERR(inode);
++	if (IS_ERR(res)) {
++		error = PTR_ERR(res);
+ 		switch (error) {
+ 			/* Make a negative dentry */
+ 			case -ENOENT:
+-				inode = NULL;
+-				break;
++				res = NULL;
++				goto out;
+ 			/* This turned out not to be a regular file */
++			case -EISDIR:
++			case -ENOTDIR:
++				goto no_open;
+ 			case -ELOOP:
+ 				if (!(nd->intent.open.flags & O_NOFOLLOW))
+ 					goto no_open;
+-			/* case -EISDIR: */
+ 			/* case -EINVAL: */
+ 			default:
+-				res = ERR_PTR(error);
+ 				goto out;
+ 		}
+-	}
+-no_entry:
+-	res = d_add_unique(dentry, inode);
+-	if (res != NULL)
++	} else if (res != NULL)
+ 		dentry = res;
+ 	nfs_renew_times(dentry);
+ 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+@@ -1014,7 +1007,7 @@ static int nfs_open_revalidate(struct de
+ 	 */
+ 	lock_kernel();
+ 	verifier = nfs_save_change_attribute(dir);
+-	ret = nfs4_open_revalidate(dir, dentry, openflags);
++	ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
+ 	if (!ret)
+ 		nfs_set_verifier(dentry, verifier);
+ 	unlock_kernel();
+@@ -1137,7 +1130,7 @@ static int nfs_create(struct inode *dir,
+ 
+ 	lock_kernel();
+ 	nfs_begin_data_update(dir);
+-	error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
++	error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd);
+ 	nfs_end_data_update(dir);
+ 	if (error != 0)
+ 		goto out_err;
+@@ -1332,6 +1325,7 @@ static int nfs_safe_remove(struct dentry
+ 
+ 	nfs_begin_data_update(dir);
+ 	if (inode != NULL) {
++		nfs_inode_return_delegation(inode);
+ 		nfs_begin_data_update(inode);
+ 		error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
+ 		/* The VFS may want to delete this inode */
+@@ -1438,17 +1432,14 @@ nfs_link(struct dentry *old_dentry, stru
+ 		old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
+ 		dentry->d_parent->d_name.name, dentry->d_name.name);
+ 
+-	/*
+-	 * Drop the dentry in advance to force a new lookup.
+-	 * Since nfs_proc_link doesn't return a file handle,
+-	 * we can't use the existing dentry.
+-	 */
+ 	lock_kernel();
+-	d_drop(dentry);
+-
+ 	nfs_begin_data_update(dir);
+ 	nfs_begin_data_update(inode);
+ 	error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
++	if (error == 0) {
++		atomic_inc(&inode->i_count);
++		d_instantiate(dentry, inode);
++	}
+ 	nfs_end_data_update(inode);
+ 	nfs_end_data_update(dir);
+ 	unlock_kernel();
+@@ -1512,9 +1503,11 @@ static int nfs_rename(struct inode *old_
+ 	 */
+ 	if (!new_inode)
+ 		goto go_ahead;
+-	if (S_ISDIR(new_inode->i_mode))
+-		goto out;
+-	else if (atomic_read(&new_dentry->d_count) > 2) {
++	if (S_ISDIR(new_inode->i_mode)) {
++		error = -EISDIR;
++		if (!S_ISDIR(old_inode->i_mode))
++			goto out;
++	} else if (atomic_read(&new_dentry->d_count) > 2) {
+ 		int err;
+ 		/* copy the target dentry's name */
+ 		dentry = d_alloc(new_dentry->d_parent,
+@@ -1539,7 +1532,8 @@ static int nfs_rename(struct inode *old_
+ #endif
+ 			goto out;
+ 		}
+-	}
++	} else
++		new_inode->i_nlink--;
+ 
+ go_ahead:
+ 	/*
+@@ -1549,6 +1543,7 @@ go_ahead:
+ 		nfs_wb_all(old_inode);
+ 		shrink_dcache_parent(old_dentry);
+ 	}
++	nfs_inode_return_delegation(old_inode);
+ 
+ 	if (new_inode)
+ 		d_delete(new_dentry);
+diff --git a/fs/nfs/file.c b/fs/nfs/file.c
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -205,8 +205,8 @@ nfs_file_flush(struct file *file)
+ 	if (!status) {
+ 		status = ctx->error;
+ 		ctx->error = 0;
+-		if (!status && !nfs_have_delegation(inode, FMODE_READ))
+-			__nfs_revalidate_inode(NFS_SERVER(inode), inode);
++		if (!status)
++			nfs_revalidate_inode(NFS_SERVER(inode), inode);
+ 	}
+ 	unlock_kernel();
+ 	return status;
+@@ -376,22 +376,31 @@ out_swapfile:
+ 
+ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
+ {
++	struct file_lock *cfl;
+ 	struct inode *inode = filp->f_mapping->host;
+ 	int status = 0;
+ 
+ 	lock_kernel();
+-	/* Use local locking if mounted with "-onolock" */
+-	if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
+-		status = NFS_PROTO(inode)->lock(filp, cmd, fl);
+-	else {
+-		struct file_lock *cfl = posix_test_lock(filp, fl);
+-
+-		fl->fl_type = F_UNLCK;
+-		if (cfl != NULL)
+-			memcpy(fl, cfl, sizeof(*fl));
++	/* Try local locking first */
++	cfl = posix_test_lock(filp, fl);
++	if (cfl != NULL) {
++		locks_copy_lock(fl, cfl);
++		goto out;
+ 	}
++
++	if (nfs_have_delegation(inode, FMODE_READ))
++		goto out_noconflict;
++
++	if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)
++		goto out_noconflict;
++
++	status = NFS_PROTO(inode)->lock(filp, cmd, fl);
++out:
+ 	unlock_kernel();
+ 	return status;
++out_noconflict:
++	fl->fl_type = F_UNLCK;
++	goto out;
+ }
+ 
+ static int do_vfs_lock(struct file *file, struct file_lock *fl)
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -358,6 +358,35 @@ out_no_root:
+ 	return no_root_error;
+ }
+ 
++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.
+  */
+@@ -367,22 +396,12 @@ nfs_create_client(struct nfs_server *ser
+ 	struct rpc_timeout	timeparms;
+ 	struct rpc_xprt		*xprt = NULL;
+ 	struct rpc_clnt		*clnt = NULL;
+-	int			tcp   = (data->flags & NFS_MOUNT_TCP);
++	int			proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
+ 
+-	/* Initialize timeout values */
+-	timeparms.to_initval = data->timeo * HZ / 10;
+-	timeparms.to_retries = data->retrans;
+-	timeparms.to_maxval  = tcp ? RPC_MAX_TCP_TIMEOUT : RPC_MAX_UDP_TIMEOUT;
+-	timeparms.to_exponential = 1;
+-
+-	if (!timeparms.to_initval)
+-		timeparms.to_initval = (tcp ? 600 : 11) * HZ / 10;
+-	if (!timeparms.to_retries)
+-		timeparms.to_retries = 5;
++	nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans);
+ 
+ 	/* create transport and client */
+-	xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
+-				 &server->addr, &timeparms);
++	xprt = xprt_create_proto(proto, &server->addr, &timeparms);
+ 	if (IS_ERR(xprt)) {
+ 		dprintk("%s: cannot create RPC transport. Error = %ld\n",
+ 				__FUNCTION__, PTR_ERR(xprt));
+@@ -576,7 +595,6 @@ static int nfs_show_options(struct seq_f
+ 		{ NFS_MOUNT_SOFT, ",soft", ",hard" },
+ 		{ NFS_MOUNT_INTR, ",intr", "" },
+ 		{ NFS_MOUNT_POSIX, ",posix", "" },
+-		{ NFS_MOUNT_TCP, ",tcp", ",udp" },
+ 		{ NFS_MOUNT_NOCTO, ",nocto", "" },
+ 		{ NFS_MOUNT_NOAC, ",noac", "" },
+ 		{ NFS_MOUNT_NONLM, ",nolock", ",lock" },
+@@ -585,6 +603,8 @@ static int nfs_show_options(struct seq_f
+ 	};
+ 	struct proc_nfs_info *nfs_infop;
+ 	struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
++	char buf[12];
++	char *proto;
+ 
+ 	seq_printf(m, ",v%d", nfss->rpc_ops->version);
+ 	seq_printf(m, ",rsize=%d", nfss->rsize);
+@@ -603,6 +623,18 @@ static int nfs_show_options(struct seq_f
+ 		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_puts(m, ",addr=");
+ 	seq_escape(m, nfss->hostname, " \t\n\\");
+ 	return 0;
+@@ -753,7 +785,8 @@ nfs_fhget(struct super_block *sb, struct
+ 		else
+ 			init_special_inode(inode, inode->i_mode, fattr->rdev);
+ 
+-		nfsi->read_cache_jiffies = fattr->timestamp;
++		nfsi->read_cache_jiffies = fattr->time_start;
++		nfsi->last_updated = jiffies;
+ 		inode->i_atime = fattr->atime;
+ 		inode->i_mtime = fattr->mtime;
+ 		inode->i_ctime = fattr->ctime;
+@@ -821,6 +854,11 @@ nfs_setattr(struct dentry *dentry, struc
+ 			filemap_fdatawait(inode->i_mapping);
+ 		nfs_wb_all(inode);
+ 	}
++	/*
++	 * Return any delegations if we're going to change ACLs
++	 */
++	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
++		nfs_inode_return_delegation(inode);
+ 	error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr);
+ 	if (error == 0)
+ 		nfs_refresh_inode(inode, &fattr);
+@@ -1019,15 +1057,11 @@ int nfs_open(struct inode *inode, struct
+ 	ctx->mode = filp->f_mode;
+ 	nfs_file_set_open_context(filp, ctx);
+ 	put_nfs_open_context(ctx);
+-	if ((filp->f_mode & FMODE_WRITE) != 0)
+-		nfs_begin_data_update(inode);
+ 	return 0;
+ }
+ 
+ int nfs_release(struct inode *inode, struct file *filp)
+ {
+-	if ((filp->f_mode & FMODE_WRITE) != 0)
+-		nfs_end_data_update(inode);
+ 	nfs_file_clear_open_context(filp);
+ 	return 0;
+ }
+@@ -1083,14 +1117,15 @@ __nfs_revalidate_inode(struct nfs_server
+ 		goto out;
+ 	}
+ 
++	spin_lock(&inode->i_lock);
+ 	status = nfs_update_inode(inode, &fattr, verifier);
+ 	if (status) {
++		spin_unlock(&inode->i_lock);
+ 		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
+ 			 inode->i_sb->s_id,
+ 			 (long long)NFS_FILEID(inode), status);
+ 		goto out;
+ 	}
+-	spin_lock(&inode->i_lock);
+ 	cache_validity = nfsi->cache_validity;
+ 	nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
+ 
+@@ -1098,7 +1133,7 @@ __nfs_revalidate_inode(struct nfs_server
+ 	 * We may need to keep the attributes marked as invalid if
+ 	 * we raced with nfs_end_attr_update().
+ 	 */
+-	if (verifier == nfsi->cache_change_attribute)
++	if (time_after_eq(verifier, nfsi->cache_change_attribute))
+ 		nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
+ 	spin_unlock(&inode->i_lock);
+ 
+@@ -1165,7 +1200,7 @@ void nfs_revalidate_mapping(struct inode
+ 		if (S_ISDIR(inode->i_mode)) {
+ 			memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
+ 			/* This ensures we revalidate child dentries */
+-			nfsi->cache_change_attribute++;
++			nfsi->cache_change_attribute = jiffies;
+ 		}
+ 		spin_unlock(&inode->i_lock);
+ 
+@@ -1197,20 +1232,19 @@ void nfs_end_data_update(struct inode *i
+ 	struct nfs_inode *nfsi = NFS_I(inode);
+ 
+ 	if (!nfs_have_delegation(inode, FMODE_READ)) {
+-		/* Mark the attribute cache for revalidation */
+-		spin_lock(&inode->i_lock);
+-		nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+-		/* Directories and symlinks: invalidate page cache too */
+-		if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
++		/* Directories and symlinks: invalidate page cache */
++		if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) {
++			spin_lock(&inode->i_lock);
+ 			nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+-		spin_unlock(&inode->i_lock);
++			spin_unlock(&inode->i_lock);
++		}
+ 	}
+-	nfsi->cache_change_attribute ++;
++	nfsi->cache_change_attribute = jiffies;
+ 	atomic_dec(&nfsi->data_updates);
+ }
+ 
+ /**
+- * nfs_refresh_inode - verify consistency of the inode attribute cache
++ * nfs_check_inode_attributes - verify consistency of the inode attribute cache
+  * @inode - pointer to inode
+  * @fattr - updated attributes
+  *
+@@ -1218,13 +1252,12 @@ void nfs_end_data_update(struct inode *i
+  * so that fattr carries weak cache consistency data, then it may
+  * also update the ctime/mtime/change_attribute.
+  */
+-int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
++static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fattr)
+ {
+ 	struct nfs_inode *nfsi = NFS_I(inode);
+ 	loff_t cur_size, new_isize;
+ 	int data_unstable;
+ 
+-	spin_lock(&inode->i_lock);
+ 
+ 	/* Are we in the process of updating data on the server? */
+ 	data_unstable = nfs_caches_unstable(inode);
+@@ -1241,14 +1274,12 @@ int nfs_refresh_inode(struct inode *inod
+ 	}
+ 
+ 	if ((fattr->valid & NFS_ATTR_FATTR) == 0) {
+-		spin_unlock(&inode->i_lock);
+ 		return 0;
+ 	}
+ 
+ 	/* Has the inode gone and changed behind our back? */
+ 	if (nfsi->fileid != fattr->fileid
+ 			|| (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
+-		spin_unlock(&inode->i_lock);
+ 		return -EIO;
+ 	}
+ 
+@@ -1288,11 +1319,67 @@ int nfs_refresh_inode(struct inode *inod
+ 	if (!timespec_equal(&inode->i_atime, &fattr->atime))
+ 		nfsi->cache_validity |= NFS_INO_INVALID_ATIME;
+ 
+-	nfsi->read_cache_jiffies = fattr->timestamp;
+-	spin_unlock(&inode->i_lock);
++	nfsi->read_cache_jiffies = fattr->time_start;
+ 	return 0;
+ }
+ 
++/**
++ * nfs_refresh_inode - try to update the inode attribute cache
++ * @inode - pointer to inode
++ * @fattr - updated attributes
++ *
++ * Check that an RPC call that returned attributes has not overlapped with
++ * other recent updates of the inode metadata, then decide whether it is
++ * safe to do a full update of the inode attributes, or whether just to
++ * call nfs_check_inode_attributes.
++ */
++int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
++{
++	struct nfs_inode *nfsi = NFS_I(inode);
++	int status;
++
++	if ((fattr->valid & NFS_ATTR_FATTR) == 0)
++		return 0;
++	spin_lock(&inode->i_lock);
++	nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
++	if (nfs_verify_change_attribute(inode, fattr->time_start))
++		nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
++	if (time_after(fattr->time_start, nfsi->last_updated))
++		status = nfs_update_inode(inode, fattr, fattr->time_start);
++	else
++		status = nfs_check_inode_attributes(inode, fattr);
++
++	spin_unlock(&inode->i_lock);
++	return status;
++}
++
++/**
++ * nfs_post_op_update_inode - try to update the inode attribute cache
++ * @inode - pointer to inode
++ * @fattr - updated attributes
++ *
++ * After an operation that has changed the inode metadata, mark the
++ * attribute cache as being invalid, then try to update it.
++ */
++int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
++{
++	struct nfs_inode *nfsi = NFS_I(inode);
++	int status = 0;
++
++	spin_lock(&inode->i_lock);
++	if (unlikely((fattr->valid & NFS_ATTR_FATTR) == 0)) {
++		nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
++		goto out;
++	}
++	status = nfs_update_inode(inode, fattr, fattr->time_start);
++	if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute))
++		nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
++	nfsi->cache_change_attribute = jiffies;
++out:
++	spin_unlock(&inode->i_lock);
++	return status;
++}
++
+ /*
+  * Many nfs protocol calls return the new file attributes after
+  * an operation.  Here we update the inode to reflect the state
+@@ -1328,20 +1415,17 @@ static int nfs_update_inode(struct inode
+ 		goto out_err;
+ 	}
+ 
+-	spin_lock(&inode->i_lock);
+-
+ 	/*
+ 	 * Make sure the inode's type hasn't changed.
+ 	 */
+-	if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
+-		spin_unlock(&inode->i_lock);
++	if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
+ 		goto out_changed;
+-	}
+ 
+ 	/*
+ 	 * Update the read time so we don't revalidate too often.
+ 	 */
+-	nfsi->read_cache_jiffies = fattr->timestamp;
++	nfsi->read_cache_jiffies = fattr->time_start;
++	nfsi->last_updated = jiffies;
+ 
+ 	/* Are we racing with known updates of the metadata on the server? */
+ 	data_unstable = ! (nfs_verify_change_attribute(inode, verifier) ||
+@@ -1354,7 +1438,7 @@ static int nfs_update_inode(struct inode
+ 		/* Do we perhaps have any outstanding writes? */
+ 		if (nfsi->npages == 0) {
+ 			/* No, but did we race with nfs_end_data_update()? */
+-			if (verifier  ==  nfsi->cache_change_attribute) {
++			if (time_after_eq(verifier,  nfsi->cache_change_attribute)) {
+ 				inode->i_size = new_isize;
+ 				invalid |= NFS_INO_INVALID_DATA;
+ 			}
+@@ -1430,7 +1514,6 @@ static int nfs_update_inode(struct inode
+ 	if (!nfs_have_delegation(inode, FMODE_READ))
+ 		nfsi->cache_validity |= invalid;
+ 
+-	spin_unlock(&inode->i_lock);
+ 	return 0;
+  out_changed:
+ 	/*
+@@ -1639,8 +1722,7 @@ static void nfs4_clear_inode(struct inod
+ 	struct nfs_inode *nfsi = NFS_I(inode);
+ 
+ 	/* If we are holding a delegation, return it! */
+-	if (nfsi->delegation != NULL)
+-		nfs_inode_return_delegation(inode);
++	nfs_inode_return_delegation(inode);
+ 	/* First call standard NFS clear_inode() code */
+ 	nfs_clear_inode(inode);
+ 	/* Now clear out any remaining state */
+@@ -1669,7 +1751,7 @@ static int nfs4_fill_super(struct super_
+ 	struct rpc_clnt *clnt = NULL;
+ 	struct rpc_timeout timeparms;
+ 	rpc_authflavor_t authflavour;
+-	int proto, err = -EIO;
++	int err = -EIO;
+ 
+ 	sb->s_blocksize_bits = 0;
+ 	sb->s_blocksize = 0;
+@@ -1687,30 +1769,8 @@ static int nfs4_fill_super(struct super_
+ 	server->acdirmax = data->acdirmax*HZ;
+ 
+ 	server->rpc_ops = &nfs_v4_clientops;
+-	/* Initialize timeout values */
+-
+-	timeparms.to_initval = data->timeo * HZ / 10;
+-	timeparms.to_retries = data->retrans;
+-	timeparms.to_exponential = 1;
+-	if (!timeparms.to_retries)
+-		timeparms.to_retries = 5;
+ 
+-	proto = data->proto;
+-	/* Which IP protocol do we use? */
+-	switch (proto) {
+-	case IPPROTO_TCP:
+-		timeparms.to_maxval  = RPC_MAX_TCP_TIMEOUT;
+-		if (!timeparms.to_initval)
+-			timeparms.to_initval = 600 * HZ / 10;
+-		break;
+-	case IPPROTO_UDP:
+-		timeparms.to_maxval  = RPC_MAX_UDP_TIMEOUT;
+-		if (!timeparms.to_initval)
+-			timeparms.to_initval = 11 * HZ / 10;
+-		break;
+-	default:
+-		return -EINVAL;
+-	}
++	nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans);
+ 
+ 	clp = nfs4_get_client(&server->addr.sin_addr);
+ 	if (!clp) {
+@@ -1735,7 +1795,7 @@ static int nfs4_fill_super(struct super_
+ 
+ 	down_write(&clp->cl_sem);
+ 	if (IS_ERR(clp->cl_rpcclient)) {
+-		xprt = xprt_create_proto(proto, &server->addr, &timeparms);
++		xprt = xprt_create_proto(data->proto, &server->addr, &timeparms);
+ 		if (IS_ERR(xprt)) {
+ 			up_write(&clp->cl_sem);
+ 			err = PTR_ERR(xprt);
+diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
+--- a/fs/nfs/nfs2xdr.c
++++ b/fs/nfs/nfs2xdr.c
+@@ -143,7 +143,6 @@ xdr_decode_fattr(u32 *p, struct nfs_fatt
+ 		fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
+ 		fattr->rdev = 0;
+ 	}
+-	fattr->timestamp = jiffies;
+ 	return p;
+ }
+ 
+diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
+--- a/fs/nfs/nfs3proc.c
++++ b/fs/nfs/nfs3proc.c
+@@ -78,7 +78,7 @@ nfs3_proc_get_root(struct nfs_server *se
+ 	int	status;
+ 
+ 	dprintk("%s: call  fsinfo\n", __FUNCTION__);
+-	info->fattr->valid = 0;
++	nfs_fattr_init(info->fattr);
+ 	status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
+ 	dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status);
+ 	if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
+@@ -98,7 +98,7 @@ nfs3_proc_getattr(struct nfs_server *ser
+ 	int	status;
+ 
+ 	dprintk("NFS call  getattr\n");
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call(server->client, NFS3PROC_GETATTR,
+ 			  fhandle, fattr, 0);
+ 	dprintk("NFS reply getattr: %d\n", status);
+@@ -117,7 +117,7 @@ nfs3_proc_setattr(struct dentry *dentry,
+ 	int	status;
+ 
+ 	dprintk("NFS call  setattr\n");
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_SETATTR, &arg, fattr, 0);
+ 	if (status == 0)
+ 		nfs_setattr_update_inode(inode, sattr);
+@@ -143,8 +143,8 @@ nfs3_proc_lookup(struct inode *dir, stru
+ 	int			status;
+ 
+ 	dprintk("NFS call  lookup %s\n", name->name);
+-	dir_attr.valid = 0;
+-	fattr->valid = 0;
++	nfs_fattr_init(&dir_attr);
++	nfs_fattr_init(fattr);
+ 	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_LOOKUP, &arg, &res, 0);
+ 	if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR))
+ 		status = rpc_call(NFS_CLIENT(dir), NFS3PROC_GETATTR,
+@@ -174,7 +174,6 @@ static int nfs3_proc_access(struct inode
+ 	int status;
+ 
+ 	dprintk("NFS call  access\n");
+-	fattr.valid = 0;
+ 
+ 	if (mode & MAY_READ)
+ 		arg.access |= NFS3_ACCESS_READ;
+@@ -189,6 +188,7 @@ static int nfs3_proc_access(struct inode
+ 		if (mode & MAY_EXEC)
+ 			arg.access |= NFS3_ACCESS_EXECUTE;
+ 	}
++	nfs_fattr_init(&fattr);
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ 	nfs_refresh_inode(inode, &fattr);
+ 	if (status == 0) {
+@@ -217,7 +217,7 @@ static int nfs3_proc_readlink(struct ino
+ 	int			status;
+ 
+ 	dprintk("NFS call  readlink\n");
+-	fattr.valid = 0;
++	nfs_fattr_init(&fattr);
+ 	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_READLINK,
+ 			  &args, &fattr, 0);
+ 	nfs_refresh_inode(inode, &fattr);
+@@ -240,7 +240,7 @@ static int nfs3_proc_read(struct nfs_rea
+ 
+ 	dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
+ 			(long long) rdata->args.offset);
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+ 	if (status >= 0)
+ 		nfs_refresh_inode(inode, fattr);
+@@ -263,10 +263,10 @@ static int nfs3_proc_write(struct nfs_wr
+ 
+ 	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
+ 			(long long) wdata->args.offset);
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
+ 	if (status >= 0)
+-		nfs_refresh_inode(inode, fattr);
++		nfs_post_op_update_inode(inode, fattr);
+ 	dprintk("NFS reply write: %d\n", status);
+ 	return status < 0? status : wdata->res.count;
+ }
+@@ -285,10 +285,10 @@ static int nfs3_proc_commit(struct nfs_w
+ 
+ 	dprintk("NFS call  commit %d @ %Ld\n", cdata->args.count,
+ 			(long long) cdata->args.offset);
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ 	if (status >= 0)
+-		nfs_refresh_inode(inode, fattr);
++		nfs_post_op_update_inode(inode, fattr);
+ 	dprintk("NFS reply commit: %d\n", status);
+ 	return status;
+ }
+@@ -299,7 +299,7 @@ static int nfs3_proc_commit(struct nfs_w
+  */
+ static int
+ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+-		 int flags)
++		 int flags, struct nameidata *nd)
+ {
+ 	struct nfs_fh		fhandle;
+ 	struct nfs_fattr	fattr;
+@@ -329,10 +329,10 @@ nfs3_proc_create(struct inode *dir, stru
+ 	sattr->ia_mode &= ~current->fs->umask;
+ 
+ again:
+-	dir_attr.valid = 0;
+-	fattr.valid = 0;
++	nfs_fattr_init(&dir_attr);
++	nfs_fattr_init(&fattr);
+ 	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_CREATE, &arg, &res, 0);
+-	nfs_refresh_inode(dir, &dir_attr);
++	nfs_post_op_update_inode(dir, &dir_attr);
+ 
+ 	/* If the server doesn't support the exclusive creation semantics,
+ 	 * try again with simple 'guarded' mode. */
+@@ -401,9 +401,9 @@ nfs3_proc_remove(struct inode *dir, stru
+ 	int			status;
+ 
+ 	dprintk("NFS call  remove %s\n", name->name);
+-	dir_attr.valid = 0;
++	nfs_fattr_init(&dir_attr);
+ 	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+-	nfs_refresh_inode(dir, &dir_attr);
++	nfs_post_op_update_inode(dir, &dir_attr);
+ 	dprintk("NFS reply remove: %d\n", status);
+ 	return status;
+ }
+@@ -422,7 +422,7 @@ nfs3_proc_unlink_setup(struct rpc_messag
+ 	ptr->arg.fh = NFS_FH(dir->d_inode);
+ 	ptr->arg.name = name->name;
+ 	ptr->arg.len = name->len;
+-	ptr->res.valid = 0;
++	nfs_fattr_init(&ptr->res);
+ 	msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
+ 	msg->rpc_argp = &ptr->arg;
+ 	msg->rpc_resp = &ptr->res;
+@@ -439,7 +439,7 @@ nfs3_proc_unlink_done(struct dentry *dir
+ 		return 1;
+ 	if (msg->rpc_argp) {
+ 		dir_attr = (struct nfs_fattr*)msg->rpc_resp;
+-		nfs_refresh_inode(dir->d_inode, dir_attr);
++		nfs_post_op_update_inode(dir->d_inode, dir_attr);
+ 		kfree(msg->rpc_argp);
+ 	}
+ 	return 0;
+@@ -465,11 +465,11 @@ nfs3_proc_rename(struct inode *old_dir, 
+ 	int			status;
+ 
+ 	dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
+-	old_dir_attr.valid = 0;
+-	new_dir_attr.valid = 0;
++	nfs_fattr_init(&old_dir_attr);
++	nfs_fattr_init(&new_dir_attr);
+ 	status = rpc_call(NFS_CLIENT(old_dir), NFS3PROC_RENAME, &arg, &res, 0);
+-	nfs_refresh_inode(old_dir, &old_dir_attr);
+-	nfs_refresh_inode(new_dir, &new_dir_attr);
++	nfs_post_op_update_inode(old_dir, &old_dir_attr);
++	nfs_post_op_update_inode(new_dir, &new_dir_attr);
+ 	dprintk("NFS reply rename: %d\n", status);
+ 	return status;
+ }
+@@ -491,11 +491,11 @@ nfs3_proc_link(struct inode *inode, stru
+ 	int			status;
+ 
+ 	dprintk("NFS call  link %s\n", name->name);
+-	dir_attr.valid = 0;
+-	fattr.valid = 0;
++	nfs_fattr_init(&dir_attr);
++	nfs_fattr_init(&fattr);
+ 	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_LINK, &arg, &res, 0);
+-	nfs_refresh_inode(dir, &dir_attr);
+-	nfs_refresh_inode(inode, &fattr);
++	nfs_post_op_update_inode(dir, &dir_attr);
++	nfs_post_op_update_inode(inode, &fattr);
+ 	dprintk("NFS reply link: %d\n", status);
+ 	return status;
+ }
+@@ -524,10 +524,10 @@ nfs3_proc_symlink(struct inode *dir, str
+ 	if (path->len > NFS3_MAXPATHLEN)
+ 		return -ENAMETOOLONG;
+ 	dprintk("NFS call  symlink %s -> %s\n", name->name, path->name);
+-	dir_attr.valid = 0;
+-	fattr->valid = 0;
++	nfs_fattr_init(&dir_attr);
++	nfs_fattr_init(fattr);
+ 	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SYMLINK, &arg, &res, 0);
+-	nfs_refresh_inode(dir, &dir_attr);
++	nfs_post_op_update_inode(dir, &dir_attr);
+ 	dprintk("NFS reply symlink: %d\n", status);
+ 	return status;
+ }
+@@ -552,13 +552,13 @@ nfs3_proc_mkdir(struct inode *dir, struc
+ 	int status;
+ 
+ 	dprintk("NFS call  mkdir %s\n", dentry->d_name.name);
+-	dir_attr.valid = 0;
+-	fattr.valid = 0;
+ 
+ 	sattr->ia_mode &= ~current->fs->umask;
+ 
++	nfs_fattr_init(&dir_attr);
++	nfs_fattr_init(&fattr);
+ 	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
+-	nfs_refresh_inode(dir, &dir_attr);
++	nfs_post_op_update_inode(dir, &dir_attr);
+ 	if (status != 0)
+ 		goto out;
+ 	status = nfs_instantiate(dentry, &fhandle, &fattr);
+@@ -582,9 +582,9 @@ nfs3_proc_rmdir(struct inode *dir, struc
+ 	int			status;
+ 
+ 	dprintk("NFS call  rmdir %s\n", name->name);
+-	dir_attr.valid = 0;
++	nfs_fattr_init(&dir_attr);
+ 	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_RMDIR, &arg, &dir_attr, 0);
+-	nfs_refresh_inode(dir, &dir_attr);
++	nfs_post_op_update_inode(dir, &dir_attr);
+ 	dprintk("NFS reply rmdir: %d\n", status);
+ 	return status;
+ }
+@@ -634,7 +634,7 @@ nfs3_proc_readdir(struct dentry *dentry,
+ 	dprintk("NFS call  readdir%s %d\n",
+ 			plus? "plus" : "", (unsigned int) cookie);
+ 
+-	dir_attr.valid = 0;
++	nfs_fattr_init(&dir_attr);
+ 	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ 	nfs_refresh_inode(dir, &dir_attr);
+ 	dprintk("NFS reply readdir: %d\n", status);
+@@ -676,10 +676,10 @@ nfs3_proc_mknod(struct inode *dir, struc
+ 
+ 	sattr->ia_mode &= ~current->fs->umask;
+ 
+-	dir_attr.valid = 0;
+-	fattr.valid = 0;
++	nfs_fattr_init(&dir_attr);
++	nfs_fattr_init(&fattr);
+ 	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
+-	nfs_refresh_inode(dir, &dir_attr);
++	nfs_post_op_update_inode(dir, &dir_attr);
+ 	if (status != 0)
+ 		goto out;
+ 	status = nfs_instantiate(dentry, &fh, &fattr);
+@@ -698,7 +698,7 @@ nfs3_proc_statfs(struct nfs_server *serv
+ 	int	status;
+ 
+ 	dprintk("NFS call  fsstat\n");
+-	stat->fattr->valid = 0;
++	nfs_fattr_init(stat->fattr);
+ 	status = rpc_call(server->client, NFS3PROC_FSSTAT, fhandle, stat, 0);
+ 	dprintk("NFS reply statfs: %d\n", status);
+ 	return status;
+@@ -711,7 +711,7 @@ nfs3_proc_fsinfo(struct nfs_server *serv
+ 	int	status;
+ 
+ 	dprintk("NFS call  fsinfo\n");
+-	info->fattr->valid = 0;
++	nfs_fattr_init(info->fattr);
+ 	status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
+ 	dprintk("NFS reply fsinfo: %d\n", status);
+ 	return status;
+@@ -724,7 +724,7 @@ nfs3_proc_pathconf(struct nfs_server *se
+ 	int	status;
+ 
+ 	dprintk("NFS call  pathconf\n");
+-	info->fattr->valid = 0;
++	nfs_fattr_init(info->fattr);
+ 	status = rpc_call(server->client, NFS3PROC_PATHCONF, fhandle, info, 0);
+ 	dprintk("NFS reply pathconf: %d\n", status);
+ 	return status;
+@@ -735,7 +735,7 @@ extern u32 *nfs3_decode_dirent(u32 *, st
+ static void
+ nfs3_read_done(struct rpc_task *task)
+ {
+-	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
++	struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
+ 
+ 	if (nfs3_async_handle_jukebox(task))
+ 		return;
+@@ -775,7 +775,7 @@ nfs3_write_done(struct rpc_task *task)
+ 		return;
+ 	data = (struct nfs_write_data *)task->tk_calldata;
+ 	if (task->tk_status >= 0)
+-		nfs_refresh_inode(data->inode, data->res.fattr);
++		nfs_post_op_update_inode(data->inode, data->res.fattr);
+ 	nfs_writeback_done(task);
+ }
+ 
+@@ -819,7 +819,7 @@ nfs3_commit_done(struct rpc_task *task)
+ 		return;
+ 	data = (struct nfs_write_data *)task->tk_calldata;
+ 	if (task->tk_status >= 0)
+-		nfs_refresh_inode(data->inode, data->res.fattr);
++		nfs_post_op_update_inode(data->inode, data->res.fattr);
+ 	nfs_commit_done(task);
+ }
+ 
+diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
+--- a/fs/nfs/nfs3xdr.c
++++ b/fs/nfs/nfs3xdr.c
+@@ -174,7 +174,6 @@ xdr_decode_fattr(u32 *p, struct nfs_fatt
+ 
+ 	/* Update the mode bits */
+ 	fattr->valid |= (NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3);
+-	fattr->timestamp = jiffies;
+ 	return p;
+ }
+ 
+diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
+--- a/fs/nfs/nfs4_fs.h
++++ b/fs/nfs/nfs4_fs.h
+@@ -93,25 +93,50 @@ struct nfs4_client {
+ };
+ 
+ /*
++ * struct rpc_sequence ensures that RPC calls are sent in the exact
++ * order that they appear on the list.
++ */
++struct rpc_sequence {
++	struct rpc_wait_queue	wait;	/* RPC call delay queue */
++	spinlock_t lock;		/* Protects the list */
++	struct list_head list;		/* Defines sequence of RPC calls */
++};
++
++#define NFS_SEQID_CONFIRMED 1
++struct nfs_seqid_counter {
++	struct rpc_sequence *sequence;
++	int flags;
++	u32 counter;
++};
++
++struct nfs_seqid {
++	struct nfs_seqid_counter *sequence;
++	struct list_head list;
++};
++
++static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status)
++{
++	if (seqid_mutating_err(-status))
++		seqid->flags |= NFS_SEQID_CONFIRMED;
++}
++
++/*
+  * NFS4 state_owners and lock_owners are simply labels for ordered
+  * sequences of RPC calls. Their sole purpose is to provide once-only
+  * semantics by allowing the server to identify replayed requests.
+- *
+- * The ->so_sema is held during all state_owner seqid-mutating operations:
+- * OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize
+- * so_seqid.
+  */
+ struct nfs4_state_owner {
++	spinlock_t	     so_lock;
+ 	struct list_head     so_list;	 /* per-clientid list of state_owners */
+ 	struct nfs4_client   *so_client;
+ 	u32                  so_id;      /* 32-bit identifier, unique */
+-	struct semaphore     so_sema;
+-	u32                  so_seqid;   /* protected by so_sema */
+ 	atomic_t	     so_count;
+ 
+ 	struct rpc_cred	     *so_cred;	 /* Associated cred */
+ 	struct list_head     so_states;
+ 	struct list_head     so_delegations;
++	struct nfs_seqid_counter so_seqid;
++	struct rpc_sequence  so_sequence;
+ };
+ 
+ /*
+@@ -132,7 +157,7 @@ struct nfs4_lock_state {
+ 	fl_owner_t		ls_owner;	/* POSIX lock owner */
+ #define NFS_LOCK_INITIALIZED 1
+ 	int			ls_flags;
+-	u32			ls_seqid;
++	struct nfs_seqid_counter	ls_seqid;
+ 	u32			ls_id;
+ 	nfs4_stateid		ls_stateid;
+ 	atomic_t		ls_count;
+@@ -153,7 +178,6 @@ struct nfs4_state {
+ 	struct inode *inode;		/* Pointer to the inode */
+ 
+ 	unsigned long flags;		/* Do we hold any locks? */
+-	struct semaphore lock_sema;	/* Serializes file locking operations */
+ 	spinlock_t state_lock;		/* Protects the lock_states list */
+ 
+ 	nfs4_stateid stateid;
+@@ -191,8 +215,8 @@ extern int nfs4_proc_setclientid_confirm
+ extern int nfs4_proc_async_renew(struct nfs4_client *);
+ extern int nfs4_proc_renew(struct nfs4_client *);
+ extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
+-extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
+-extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
++extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
++extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
+ 
+ extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
+ extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
+@@ -224,12 +248,17 @@ extern struct nfs4_state * nfs4_get_open
+ extern void nfs4_put_open_state(struct nfs4_state *);
+ extern void nfs4_close_state(struct nfs4_state *, mode_t);
+ extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
+-extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
+ extern void nfs4_schedule_state_recovery(struct nfs4_client *);
++extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
+ extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
+-extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
+ extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
+ 
++extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter);
++extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
++extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
++extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
++extern void nfs_free_seqid(struct nfs_seqid *seqid);
++
+ extern const nfs4_stateid zero_stateid;
+ 
+ /* nfs4xdr.c */
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -47,6 +47,7 @@
+ #include <linux/nfs_page.h>
+ #include <linux/smp_lock.h>
+ #include <linux/namei.h>
++#include <linux/mount.h>
+ 
+ #include "nfs4_fs.h"
+ #include "delegation.h"
+@@ -56,10 +57,11 @@
+ #define NFS4_POLL_RETRY_MIN	(1*HZ)
+ #define NFS4_POLL_RETRY_MAX	(15*HZ)
+ 
++static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid);
+ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
+-static int nfs4_async_handle_error(struct rpc_task *, struct nfs_server *);
++static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
+ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
+-static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
++static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
+ extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
+ extern struct rpc_procinfo nfs4_procedures[];
+ 
+@@ -185,8 +187,26 @@ static void update_changeattr(struct ino
+ {
+ 	struct nfs_inode *nfsi = NFS_I(inode);
+ 
++	spin_lock(&inode->i_lock);
++	nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+ 	if (cinfo->before == nfsi->change_attr && cinfo->atomic)
+ 		nfsi->change_attr = cinfo->after;
++	spin_unlock(&inode->i_lock);
++}
++
++/* Helper for asynchronous RPC calls */
++static int nfs4_call_async(struct rpc_clnt *clnt, rpc_action tk_begin,
++		rpc_action tk_exit, void *calldata)
++{
++	struct rpc_task *task;
++
++	if (!(task = rpc_new_task(clnt, tk_exit, RPC_TASK_ASYNC)))
++		return -ENOMEM;
++
++	task->tk_calldata = calldata;
++	task->tk_action = tk_begin;
++	rpc_execute(task);
++	return 0;
+ }
+ 
+ static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags)
+@@ -195,6 +215,7 @@ static void update_open_stateid(struct n
+ 
+ 	open_flags &= (FMODE_READ|FMODE_WRITE);
+ 	/* Protect against nfs4_find_state() */
++	spin_lock(&state->owner->so_lock);
+ 	spin_lock(&inode->i_lock);
+ 	state->state |= open_flags;
+ 	/* NB! List reordering - see the reclaim code for why.  */
+@@ -204,12 +225,12 @@ static void update_open_stateid(struct n
+ 		state->nreaders++;
+ 	memcpy(&state->stateid, stateid, sizeof(state->stateid));
+ 	spin_unlock(&inode->i_lock);
++	spin_unlock(&state->owner->so_lock);
+ }
+ 
+ /*
+  * OPEN_RECLAIM:
+  * 	reclaim state on the server after a reboot.
+- * 	Assumes caller is holding the sp->so_sem
+  */
+ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
+ {
+@@ -218,7 +239,6 @@ static int _nfs4_open_reclaim(struct nfs
+ 	struct nfs_delegation *delegation = NFS_I(inode)->delegation;
+ 	struct nfs_openargs o_arg = {
+ 		.fh = NFS_FH(inode),
+-		.seqid = sp->so_seqid,
+ 		.id = sp->so_id,
+ 		.open_flags = state->state,
+ 		.clientid = server->nfs4_state->cl_clientid,
+@@ -245,8 +265,13 @@ static int _nfs4_open_reclaim(struct nfs
+ 		}
+ 		o_arg.u.delegation_type = delegation->type;
+ 	}
++	o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
++	if (o_arg.seqid == NULL)
++		return -ENOMEM;
+ 	status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+-	nfs4_increment_seqid(status, sp);
++	/* Confirm the sequence as being established */
++	nfs_confirm_seqid(&sp->so_seqid, status);
++	nfs_increment_open_seqid(status, o_arg.seqid);
+ 	if (status == 0) {
+ 		memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid));
+ 		if (o_res.delegation_type != 0) {
+@@ -256,6 +281,7 @@ static int _nfs4_open_reclaim(struct nfs
+ 				nfs_async_inode_return_delegation(inode, &o_res.stateid);
+ 		}
+ 	}
++	nfs_free_seqid(o_arg.seqid);
+ 	clear_bit(NFS_DELEGATED_STATE, &state->flags);
+ 	/* Ensure we update the inode attributes */
+ 	NFS_CACHEINV(inode);
+@@ -302,23 +328,35 @@ static int _nfs4_open_delegation_recall(
+ 	};
+ 	int status = 0;
+ 
+-	down(&sp->so_sema);
+ 	if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
+ 		goto out;
+ 	if (state->state == 0)
+ 		goto out;
+-	arg.seqid = sp->so_seqid;
++	arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
++	status = -ENOMEM;
++	if (arg.seqid == NULL)
++		goto out;
+ 	arg.open_flags = state->state;
+ 	memcpy(arg.u.delegation.data, state->stateid.data, sizeof(arg.u.delegation.data));
+ 	status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+-	nfs4_increment_seqid(status, sp);
++	nfs_increment_open_seqid(status, arg.seqid);
++	if (status != 0)
++		goto out_free;
++	if(res.rflags & NFS4_OPEN_RESULT_CONFIRM) {
++		status = _nfs4_proc_open_confirm(server->client, NFS_FH(inode),
++				sp, &res.stateid, arg.seqid);
++		if (status != 0)
++			goto out_free;
++	}
++	nfs_confirm_seqid(&sp->so_seqid, 0);
+ 	if (status >= 0) {
+ 		memcpy(state->stateid.data, res.stateid.data,
+ 				sizeof(state->stateid.data));
+ 		clear_bit(NFS_DELEGATED_STATE, &state->flags);
+ 	}
++out_free:
++	nfs_free_seqid(arg.seqid);
+ out:
+-	up(&sp->so_sema);
+ 	dput(parent);
+ 	return status;
+ }
+@@ -345,11 +383,11 @@ int nfs4_open_delegation_recall(struct d
+ 	return err;
+ }
+ 
+-static inline int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid)
++static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid)
+ {
+ 	struct nfs_open_confirmargs arg = {
+ 		.fh             = fh,
+-		.seqid          = sp->so_seqid,
++		.seqid          = seqid,
+ 		.stateid	= *stateid,
+ 	};
+ 	struct nfs_open_confirmres res;
+@@ -362,7 +400,9 @@ static inline int _nfs4_proc_open_confir
+ 	int status;
+ 
+ 	status = rpc_call_sync(clnt, &msg, RPC_TASK_NOINTR);
+-	nfs4_increment_seqid(status, sp);
++	/* Confirm the sequence as being established */
++	nfs_confirm_seqid(&sp->so_seqid, status);
++	nfs_increment_open_seqid(status, seqid);
+ 	if (status >= 0)
+ 		memcpy(stateid, &res.stateid, sizeof(*stateid));
+ 	return status;
+@@ -380,21 +420,41 @@ static int _nfs4_proc_open(struct inode 
+ 	int status;
+ 
+ 	/* Update sequence id. The caller must serialize! */
+-	o_arg->seqid = sp->so_seqid;
+ 	o_arg->id = sp->so_id;
+ 	o_arg->clientid = sp->so_client->cl_clientid;
+ 
+ 	status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+-	nfs4_increment_seqid(status, sp);
++	if (status == 0) {
++		/* OPEN on anything except a regular file is disallowed in NFSv4 */
++		switch (o_res->f_attr->mode & S_IFMT) {
++			case S_IFREG:
++				break;
++			case S_IFLNK:
++				status = -ELOOP;
++				break;
++			case S_IFDIR:
++				status = -EISDIR;
++				break;
++			default:
++				status = -ENOTDIR;
++		}
++	}
++
++	nfs_increment_open_seqid(status, o_arg->seqid);
+ 	if (status != 0)
+ 		goto out;
+-	update_changeattr(dir, &o_res->cinfo);
++	if (o_arg->open_flags & O_CREAT) {
++		update_changeattr(dir, &o_res->cinfo);
++		nfs_post_op_update_inode(dir, o_res->dir_attr);
++	} else
++		nfs_refresh_inode(dir, o_res->dir_attr);
+ 	if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
+ 		status = _nfs4_proc_open_confirm(server->client, &o_res->fh,
+-				sp, &o_res->stateid);
++				sp, &o_res->stateid, o_arg->seqid);
+ 		if (status != 0)
+ 			goto out;
+ 	}
++	nfs_confirm_seqid(&sp->so_seqid, 0);
+ 	if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
+ 		status = server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
+ out:
+@@ -441,9 +501,7 @@ static int _nfs4_open_expired(struct nfs
+ 	struct inode *inode = state->inode;
+ 	struct nfs_server *server = NFS_SERVER(dir);
+ 	struct nfs_delegation *delegation = NFS_I(inode)->delegation;
+-	struct nfs_fattr        f_attr = {
+-		.valid = 0,
+-	};
++	struct nfs_fattr f_attr, dir_attr;
+ 	struct nfs_openargs o_arg = {
+ 		.fh = NFS_FH(dir),
+ 		.open_flags = state->state,
+@@ -453,6 +511,7 @@ static int _nfs4_open_expired(struct nfs
+ 	};
+ 	struct nfs_openres o_res = {
+ 		.f_attr = &f_attr,
++		.dir_attr = &dir_attr,
+ 		.server = server,
+ 	};
+ 	int status = 0;
+@@ -465,6 +524,12 @@ static int _nfs4_open_expired(struct nfs
+ 		set_bit(NFS_DELEGATED_STATE, &state->flags);
+ 		goto out;
+ 	}
++	o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
++	status = -ENOMEM;
++	if (o_arg.seqid == NULL)
++		goto out;
++	nfs_fattr_init(&f_attr);
++	nfs_fattr_init(&dir_attr);
+ 	status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
+ 	if (status != 0)
+ 		goto out_nodeleg;
+@@ -490,6 +555,7 @@ static int _nfs4_open_expired(struct nfs
+ 			nfs_inode_reclaim_delegation(inode, sp->so_cred, &o_res);
+ 	}
+ out_nodeleg:
++	nfs_free_seqid(o_arg.seqid);
+ 	clear_bit(NFS_DELEGATED_STATE, &state->flags);
+ out:
+ 	dput(parent);
+@@ -564,7 +630,6 @@ static int _nfs4_open_delegated(struct i
+ 		dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
+ 		goto out_err;
+ 	}
+-	down(&sp->so_sema);
+ 	state = nfs4_get_open_state(inode, sp);
+ 	if (state == NULL)
+ 		goto out_err;
+@@ -589,7 +654,6 @@ static int _nfs4_open_delegated(struct i
+ 	set_bit(NFS_DELEGATED_STATE, &state->flags);
+ 	update_open_stateid(state, &delegation->stateid, open_flags);
+ out_ok:
+-	up(&sp->so_sema);
+ 	nfs4_put_state_owner(sp);
+ 	up_read(&nfsi->rwsem);
+ 	up_read(&clp->cl_sem);
+@@ -600,11 +664,12 @@ out_err:
+ 	if (sp != NULL) {
+ 		if (state != NULL)
+ 			nfs4_put_open_state(state);
+-		up(&sp->so_sema);
+ 		nfs4_put_state_owner(sp);
+ 	}
+ 	up_read(&nfsi->rwsem);
+ 	up_read(&clp->cl_sem);
++	if (err != -EACCES)
++		nfs_inode_return_delegation(inode);
+ 	return err;
+ }
+ 
+@@ -635,9 +700,7 @@ static int _nfs4_do_open(struct inode *d
+ 	struct nfs4_client *clp = server->nfs4_state;
+ 	struct inode *inode = NULL;
+ 	int                     status;
+-	struct nfs_fattr        f_attr = {
+-		.valid          = 0,
+-	};
++	struct nfs_fattr f_attr, dir_attr;
+ 	struct nfs_openargs o_arg = {
+ 		.fh             = NFS_FH(dir),
+ 		.open_flags	= flags,
+@@ -648,6 +711,7 @@ static int _nfs4_do_open(struct inode *d
+ 	};
+ 	struct nfs_openres o_res = {
+ 		.f_attr         = &f_attr,
++		.dir_attr	= &dir_attr,
+ 		.server         = server,
+ 	};
+ 
+@@ -665,8 +729,12 @@ static int _nfs4_do_open(struct inode *d
+ 	} else
+ 		o_arg.u.attrs = sattr;
+ 	/* Serialization for the sequence id */
+-	down(&sp->so_sema);
+ 
++	o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
++	if (o_arg.seqid == NULL)
++		return -ENOMEM;
++	nfs_fattr_init(&f_attr);
++	nfs_fattr_init(&dir_attr);
+ 	status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
+ 	if (status != 0)
+ 		goto out_err;
+@@ -681,7 +749,7 @@ static int _nfs4_do_open(struct inode *d
+ 	update_open_stateid(state, &o_res.stateid, flags);
+ 	if (o_res.delegation_type != 0)
+ 		nfs_inode_set_delegation(inode, cred, &o_res);
+-	up(&sp->so_sema);
++	nfs_free_seqid(o_arg.seqid);
+ 	nfs4_put_state_owner(sp);
+ 	up_read(&clp->cl_sem);
+ 	*res = state;
+@@ -690,7 +758,7 @@ out_err:
+ 	if (sp != NULL) {
+ 		if (state != NULL)
+ 			nfs4_put_open_state(state);
+-		up(&sp->so_sema);
++		nfs_free_seqid(o_arg.seqid);
+ 		nfs4_put_state_owner(sp);
+ 	}
+ 	/* Note: clp->cl_sem must be released before nfs4_put_open_state()! */
+@@ -718,7 +786,7 @@ static struct nfs4_state *nfs4_do_open(s
+ 		 * It is actually a sign of a bug on the client or on the server.
+ 		 *
+ 		 * If we receive a BAD_SEQID error in the particular case of
+-		 * doing an OPEN, we assume that nfs4_increment_seqid() will
++		 * doing an OPEN, we assume that nfs_increment_open_seqid() will
+ 		 * have unhashed the old state_owner for us, and that we can
+ 		 * therefore safely retry using a new one. We should still warn
+ 		 * the user though...
+@@ -728,6 +796,16 @@ static struct nfs4_state *nfs4_do_open(s
+ 			exception.retry = 1;
+ 			continue;
+ 		}
++		/*
++		 * BAD_STATEID on OPEN means that the server cancelled our
++		 * state before it received the OPEN_CONFIRM.
++		 * Recover by retrying the request as per the discussion
++		 * on Page 181 of RFC3530.
++		 */
++		if (status == -NFS4ERR_BAD_STATEID) {
++			exception.retry = 1;
++			continue;
++		}
+ 		res = ERR_PTR(nfs4_handle_exception(NFS_SERVER(dir),
+ 					status, &exception));
+ 	} while (exception.retry);
+@@ -755,7 +833,7 @@ static int _nfs4_do_setattr(struct nfs_s
+         };
+ 	int status;
+ 
+-        fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 
+ 	if (state != NULL) {
+ 		msg.rpc_cred = state->owner->so_cred;
+@@ -787,19 +865,30 @@ struct nfs4_closedata {
+ 	struct nfs4_state *state;
+ 	struct nfs_closeargs arg;
+ 	struct nfs_closeres res;
++	struct nfs_fattr fattr;
+ };
+ 
++static void nfs4_free_closedata(struct nfs4_closedata *calldata)
++{
++	struct nfs4_state *state = calldata->state;
++	struct nfs4_state_owner *sp = state->owner;
++
++	nfs4_put_open_state(calldata->state);
++	nfs_free_seqid(calldata->arg.seqid);
++	nfs4_put_state_owner(sp);
++	kfree(calldata);
++}
++
+ static void nfs4_close_done(struct rpc_task *task)
+ {
+ 	struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata;
+ 	struct nfs4_state *state = calldata->state;
+-	struct nfs4_state_owner *sp = state->owner;
+ 	struct nfs_server *server = NFS_SERVER(calldata->inode);
+ 
+         /* hmm. we are done with the inode, and in the process of freeing
+ 	 * the state_owner. we keep this around to process errors
+ 	 */
+-	nfs4_increment_seqid(task->tk_status, sp);
++	nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid);
+ 	switch (task->tk_status) {
+ 		case 0:
+ 			memcpy(&state->stateid, &calldata->res.stateid,
+@@ -816,25 +905,49 @@ static void nfs4_close_done(struct rpc_t
+ 				return;
+ 			}
+ 	}
++	nfs_refresh_inode(calldata->inode, calldata->res.fattr);
+ 	state->state = calldata->arg.open_flags;
+-	nfs4_put_open_state(state);
+-	up(&sp->so_sema);
+-	nfs4_put_state_owner(sp);
+-	up_read(&server->nfs4_state->cl_sem);
+-	kfree(calldata);
++	nfs4_free_closedata(calldata);
+ }
+ 
+-static inline int nfs4_close_call(struct rpc_clnt *clnt, struct nfs4_closedata *calldata)
++static void nfs4_close_begin(struct rpc_task *task)
+ {
++	struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata;
++	struct nfs4_state *state = calldata->state;
+ 	struct rpc_message msg = {
+ 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE],
+ 		.rpc_argp = &calldata->arg,
+ 		.rpc_resp = &calldata->res,
+-		.rpc_cred = calldata->state->owner->so_cred,
++		.rpc_cred = state->owner->so_cred,
+ 	};
+-	if (calldata->arg.open_flags != 0)
++	int mode = 0;
++	int status;
++
++	status = nfs_wait_on_sequence(calldata->arg.seqid, task);
++	if (status != 0)
++		return;
++	/* Don't reorder reads */
++	smp_rmb();
++	/* Recalculate the new open mode in case someone reopened the file
++	 * while we were waiting in line to be scheduled.
++	 */
++	if (state->nreaders != 0)
++		mode |= FMODE_READ;
++	if (state->nwriters != 0)
++		mode |= FMODE_WRITE;
++	if (test_bit(NFS_DELEGATED_STATE, &state->flags))
++		state->state = mode;
++	if (mode == state->state) {
++		nfs4_free_closedata(calldata);
++		task->tk_exit = NULL;
++		rpc_exit(task, 0);
++		return;
++	}
++	nfs_fattr_init(calldata->res.fattr);
++	if (mode != 0)
+ 		msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
+-	return rpc_call_async(clnt, &msg, 0, nfs4_close_done, calldata);
++	calldata->arg.open_flags = mode;
++	rpc_call_setup(task, &msg, 0);
+ }
+ 
+ /* 
+@@ -850,40 +963,57 @@ static inline int nfs4_close_call(struct
+  */
+ int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode) 
+ {
++	struct nfs_server *server = NFS_SERVER(inode);
+ 	struct nfs4_closedata *calldata;
+-	int status;
++	int status = -ENOMEM;
+ 
+-	/* Tell caller we're done */
+-	if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+-		state->state = mode;
+-		return 0;
+-	}
+-	calldata = (struct nfs4_closedata *)kmalloc(sizeof(*calldata), GFP_KERNEL);
++	calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
+ 	if (calldata == NULL)
+-		return -ENOMEM;
++		goto out;
+ 	calldata->inode = inode;
+ 	calldata->state = state;
+ 	calldata->arg.fh = NFS_FH(inode);
++	calldata->arg.stateid = &state->stateid;
+ 	/* Serialization for the sequence id */
+-	calldata->arg.seqid = state->owner->so_seqid;
+-	calldata->arg.open_flags = mode;
+-	memcpy(&calldata->arg.stateid, &state->stateid,
+-			sizeof(calldata->arg.stateid));
+-	status = nfs4_close_call(NFS_SERVER(inode)->client, calldata);
+-	/*
+-	 * Return -EINPROGRESS on success in order to indicate to the
+-	 * caller that an asynchronous RPC call has been launched, and
+-	 * that it will release the semaphores on completion.
+-	 */
+-	return (status == 0) ? -EINPROGRESS : status;
++	calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
++	if (calldata->arg.seqid == NULL)
++		goto out_free_calldata;
++	calldata->arg.bitmask = server->attr_bitmask;
++	calldata->res.fattr = &calldata->fattr;
++	calldata->res.server = server;
++
++	status = nfs4_call_async(server->client, nfs4_close_begin,
++			nfs4_close_done, calldata);
++	if (status == 0)
++		goto out;
++
++	nfs_free_seqid(calldata->arg.seqid);
++out_free_calldata:
++	kfree(calldata);
++out:
++	return status;
++}
++
++static void nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state)
++{
++	struct file *filp;
++
++	filp = lookup_instantiate_filp(nd, dentry, NULL);
++	if (!IS_ERR(filp)) {
++		struct nfs_open_context *ctx;
++		ctx = (struct nfs_open_context *)filp->private_data;
++		ctx->state = state;
++	} else
++		nfs4_close_state(state, nd->intent.open.flags);
+ }
+ 
+-struct inode *
++struct dentry *
+ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+ {
+ 	struct iattr attr;
+ 	struct rpc_cred *cred;
+ 	struct nfs4_state *state;
++	struct dentry *res;
+ 
+ 	if (nd->flags & LOOKUP_CREATE) {
+ 		attr.ia_mode = nd->intent.open.create_mode;
+@@ -897,16 +1027,23 @@ nfs4_atomic_open(struct inode *dir, stru
+ 
+ 	cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
+ 	if (IS_ERR(cred))
+-		return (struct inode *)cred;
++		return (struct dentry *)cred;
+ 	state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred);
+ 	put_rpccred(cred);
+-	if (IS_ERR(state))
+-		return (struct inode *)state;
+-	return state->inode;
++	if (IS_ERR(state)) {
++		if (PTR_ERR(state) == -ENOENT)
++			d_add(dentry, NULL);
++		return (struct dentry *)state;
++	}
++	res = d_add_unique(dentry, state->inode);
++	if (res != NULL)
++		dentry = res;
++	nfs4_intent_set_file(nd, dentry, state);
++	return res;
+ }
+ 
+ int
+-nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags)
++nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
+ {
+ 	struct rpc_cred *cred;
+ 	struct nfs4_state *state;
+@@ -919,18 +1056,30 @@ nfs4_open_revalidate(struct inode *dir, 
+ 	if (IS_ERR(state))
+ 		state = nfs4_do_open(dir, dentry, openflags, NULL, cred);
+ 	put_rpccred(cred);
+-	if (state == ERR_PTR(-ENOENT) && dentry->d_inode == 0)
+-		return 1;
+-	if (IS_ERR(state))
+-		return 0;
++	if (IS_ERR(state)) {
++		switch (PTR_ERR(state)) {
++			case -EPERM:
++			case -EACCES:
++			case -EDQUOT:
++			case -ENOSPC:
++			case -EROFS:
++				lookup_instantiate_filp(nd, (struct dentry *)state, NULL);
++				return 1;
++			case -ENOENT:
++				if (dentry->d_inode == NULL)
++					return 1;
++		}
++		goto out_drop;
++	}
+ 	inode = state->inode;
++	iput(inode);
+ 	if (inode == dentry->d_inode) {
+-		iput(inode);
++		nfs4_intent_set_file(nd, dentry, state);
+ 		return 1;
+ 	}
+-	d_drop(dentry);
+ 	nfs4_close_state(state, openflags);
+-	iput(inode);
++out_drop:
++	d_drop(dentry);
+ 	return 0;
+ }
+ 
+@@ -974,13 +1123,12 @@ static int nfs4_server_capabilities(stru
+ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
+ 		struct nfs_fsinfo *info)
+ {
+-	struct nfs_fattr *	fattr = info->fattr;
+ 	struct nfs4_lookup_root_arg args = {
+ 		.bitmask = nfs4_fattr_bitmap,
+ 	};
+ 	struct nfs4_lookup_res res = {
+ 		.server = server,
+-		.fattr = fattr,
++		.fattr = info->fattr,
+ 		.fh = fhandle,
+ 	};
+ 	struct rpc_message msg = {
+@@ -988,7 +1136,7 @@ static int _nfs4_lookup_root(struct nfs_
+ 		.rpc_argp = &args,
+ 		.rpc_resp = &res,
+ 	};
+-	fattr->valid = 0;
++	nfs_fattr_init(info->fattr);
+ 	return rpc_call_sync(server->client, &msg, 0);
+ }
+ 
+@@ -1051,7 +1199,7 @@ static int nfs4_proc_get_root(struct nfs
+ 		q.len = p - q.name;
+ 
+ 		do {
+-			fattr->valid = 0;
++			nfs_fattr_init(fattr);
+ 			status = nfs4_handle_exception(server,
+ 					rpc_call_sync(server->client, &msg, 0),
+ 					&exception);
+@@ -1088,7 +1236,7 @@ static int _nfs4_proc_getattr(struct nfs
+ 		.rpc_resp = &res,
+ 	};
+ 	
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	return rpc_call_sync(server->client, &msg, 0);
+ }
+ 
+@@ -1130,7 +1278,7 @@ nfs4_proc_setattr(struct dentry *dentry,
+ 	struct nfs4_state *state;
+ 	int status;
+ 
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	
+ 	cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
+ 	if (IS_ERR(cred))
+@@ -1176,7 +1324,7 @@ static int _nfs4_proc_lookup(struct inod
+ 		.rpc_resp = &res,
+ 	};
+ 	
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	
+ 	dprintk("NFS call  lookup %s\n", name->name);
+ 	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+@@ -1325,7 +1473,7 @@ static int _nfs4_proc_read(struct nfs_re
+ 	dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
+ 			(long long) rdata->args.offset);
+ 
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call_sync(server->client, &msg, flags);
+ 	if (!status)
+ 		renew_lease(server, timestamp);
+@@ -1362,7 +1510,7 @@ static int _nfs4_proc_write(struct nfs_w
+ 	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
+ 			(long long) wdata->args.offset);
+ 
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call_sync(server->client, &msg, rpcflags);
+ 	dprintk("NFS reply write: %d\n", status);
+ 	return status;
+@@ -1396,7 +1544,7 @@ static int _nfs4_proc_commit(struct nfs_
+ 	dprintk("NFS call  commit %d @ %Ld\n", cdata->args.count,
+ 			(long long) cdata->args.offset);
+ 
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call_sync(server->client, &msg, 0);
+ 	dprintk("NFS reply commit: %d\n", status);
+ 	return status;
+@@ -1431,7 +1579,7 @@ static int nfs4_proc_commit(struct nfs_w
+ 
+ static int
+ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+-                 int flags)
++                 int flags, struct nameidata *nd)
+ {
+ 	struct nfs4_state *state;
+ 	struct rpc_cred *cred;
+@@ -1453,24 +1601,30 @@ nfs4_proc_create(struct inode *dir, stru
+ 		struct nfs_fattr fattr;
+ 		status = nfs4_do_setattr(NFS_SERVER(dir), &fattr,
+ 		                     NFS_FH(state->inode), sattr, state);
+-		if (status == 0) {
++		if (status == 0)
+ 			nfs_setattr_update_inode(state->inode, sattr);
+-			goto out;
+-		}
+-	} else if (flags != 0)
+-		goto out;
+-	nfs4_close_state(state, flags);
++	}
++	if (status == 0 && nd != NULL && (nd->flags & LOOKUP_OPEN))
++		nfs4_intent_set_file(nd, dentry, state);
++	else
++		nfs4_close_state(state, flags);
+ out:
+ 	return status;
+ }
+ 
+ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
+ {
++	struct nfs_server *server = NFS_SERVER(dir);
+ 	struct nfs4_remove_arg args = {
+ 		.fh = NFS_FH(dir),
+ 		.name = name,
++		.bitmask = server->attr_bitmask,
++	};
++	struct nfs_fattr dir_attr;
++	struct nfs4_remove_res	res = {
++		.server = server,
++		.dir_attr = &dir_attr,
+ 	};
+-	struct nfs4_change_info	res;
+ 	struct rpc_message msg = {
+ 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_REMOVE],
+ 		.rpc_argp	= &args,
+@@ -1478,9 +1632,12 @@ static int _nfs4_proc_remove(struct inod
+ 	};
+ 	int			status;
+ 
+-	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+-	if (status == 0)
+-		update_changeattr(dir, &res);
++	nfs_fattr_init(res.dir_attr);
++	status = rpc_call_sync(server->client, &msg, 0);
++	if (status == 0) {
++		update_changeattr(dir, &res.cinfo);
++		nfs_post_op_update_inode(dir, res.dir_attr);
++	}
+ 	return status;
+ }
+ 
+@@ -1498,12 +1655,14 @@ static int nfs4_proc_remove(struct inode
+ 
+ struct unlink_desc {
+ 	struct nfs4_remove_arg	args;
+-	struct nfs4_change_info	res;
++	struct nfs4_remove_res	res;
++	struct nfs_fattr dir_attr;
+ };
+ 
+ static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir,
+ 		struct qstr *name)
+ {
++	struct nfs_server *server = NFS_SERVER(dir->d_inode);
+ 	struct unlink_desc *up;
+ 
+ 	up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL);
+@@ -1512,6 +1671,9 @@ static int nfs4_proc_unlink_setup(struct
+ 	
+ 	up->args.fh = NFS_FH(dir->d_inode);
+ 	up->args.name = name;
++	up->args.bitmask = server->attr_bitmask;
++	up->res.server = server;
++	up->res.dir_attr = &up->dir_attr;
+ 	
+ 	msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
+ 	msg->rpc_argp = &up->args;
+@@ -1526,7 +1688,8 @@ static int nfs4_proc_unlink_done(struct 
+ 	
+ 	if (msg->rpc_resp != NULL) {
+ 		up = container_of(msg->rpc_resp, struct unlink_desc, res);
+-		update_changeattr(dir->d_inode, &up->res);
++		update_changeattr(dir->d_inode, &up->res.cinfo);
++		nfs_post_op_update_inode(dir->d_inode, up->res.dir_attr);
+ 		kfree(up);
+ 		msg->rpc_resp = NULL;
+ 		msg->rpc_argp = NULL;
+@@ -1537,13 +1700,20 @@ static int nfs4_proc_unlink_done(struct 
+ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
+ 		struct inode *new_dir, struct qstr *new_name)
+ {
++	struct nfs_server *server = NFS_SERVER(old_dir);
+ 	struct nfs4_rename_arg arg = {
+ 		.old_dir = NFS_FH(old_dir),
+ 		.new_dir = NFS_FH(new_dir),
+ 		.old_name = old_name,
+ 		.new_name = new_name,
++		.bitmask = server->attr_bitmask,
++	};
++	struct nfs_fattr old_fattr, new_fattr;
++	struct nfs4_rename_res res = {
++		.server = server,
++		.old_fattr = &old_fattr,
++		.new_fattr = &new_fattr,
+ 	};
+-	struct nfs4_rename_res res = { };
+ 	struct rpc_message msg = {
+ 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME],
+ 		.rpc_argp = &arg,
+@@ -1551,11 +1721,15 @@ static int _nfs4_proc_rename(struct inod
+ 	};
+ 	int			status;
+ 	
+-	status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
++	nfs_fattr_init(res.old_fattr);
++	nfs_fattr_init(res.new_fattr);
++	status = rpc_call_sync(server->client, &msg, 0);
+ 
+ 	if (!status) {
+ 		update_changeattr(old_dir, &res.old_cinfo);
++		nfs_post_op_update_inode(old_dir, res.old_fattr);
+ 		update_changeattr(new_dir, &res.new_cinfo);
++		nfs_post_op_update_inode(new_dir, res.new_fattr);
+ 	}
+ 	return status;
+ }
+@@ -1576,22 +1750,34 @@ static int nfs4_proc_rename(struct inode
+ 
+ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
+ {
++	struct nfs_server *server = NFS_SERVER(inode);
+ 	struct nfs4_link_arg arg = {
+ 		.fh     = NFS_FH(inode),
+ 		.dir_fh = NFS_FH(dir),
+ 		.name   = name,
++		.bitmask = server->attr_bitmask,
++	};
++	struct nfs_fattr fattr, dir_attr;
++	struct nfs4_link_res res = {
++		.server = server,
++		.fattr = &fattr,
++		.dir_attr = &dir_attr,
+ 	};
+-	struct nfs4_change_info	cinfo = { };
+ 	struct rpc_message msg = {
+ 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
+ 		.rpc_argp = &arg,
+-		.rpc_resp = &cinfo,
++		.rpc_resp = &res,
+ 	};
+ 	int			status;
+ 
+-	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+-	if (!status)
+-		update_changeattr(dir, &cinfo);
++	nfs_fattr_init(res.fattr);
++	nfs_fattr_init(res.dir_attr);
++	status = rpc_call_sync(server->client, &msg, 0);
++	if (!status) {
++		update_changeattr(dir, &res.cinfo);
++		nfs_post_op_update_inode(dir, res.dir_attr);
++		nfs_refresh_inode(inode, res.fattr);
++	}
+ 
+ 	return status;
+ }
+@@ -1613,6 +1799,7 @@ static int _nfs4_proc_symlink(struct ino
+ 		struct nfs_fattr *fattr)
+ {
+ 	struct nfs_server *server = NFS_SERVER(dir);
++	struct nfs_fattr dir_fattr;
+ 	struct nfs4_create_arg arg = {
+ 		.dir_fh = NFS_FH(dir),
+ 		.server = server,
+@@ -1625,6 +1812,7 @@ static int _nfs4_proc_symlink(struct ino
+ 		.server = server,
+ 		.fh = fhandle,
+ 		.fattr = fattr,
++		.dir_fattr = &dir_fattr,
+ 	};
+ 	struct rpc_message msg = {
+ 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK],
+@@ -1636,11 +1824,13 @@ static int _nfs4_proc_symlink(struct ino
+ 	if (path->len > NFS4_MAXPATHLEN)
+ 		return -ENAMETOOLONG;
+ 	arg.u.symlink = path;
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
++	nfs_fattr_init(&dir_fattr);
+ 	
+ 	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ 	if (!status)
+ 		update_changeattr(dir, &res.dir_cinfo);
++	nfs_post_op_update_inode(dir, res.dir_fattr);
+ 	return status;
+ }
+ 
+@@ -1664,7 +1854,7 @@ static int _nfs4_proc_mkdir(struct inode
+ {
+ 	struct nfs_server *server = NFS_SERVER(dir);
+ 	struct nfs_fh fhandle;
+-	struct nfs_fattr fattr;
++	struct nfs_fattr fattr, dir_fattr;
+ 	struct nfs4_create_arg arg = {
+ 		.dir_fh = NFS_FH(dir),
+ 		.server = server,
+@@ -1677,6 +1867,7 @@ static int _nfs4_proc_mkdir(struct inode
+ 		.server = server,
+ 		.fh = &fhandle,
+ 		.fattr = &fattr,
++		.dir_fattr = &dir_fattr,
+ 	};
+ 	struct rpc_message msg = {
+ 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE],
+@@ -1685,11 +1876,13 @@ static int _nfs4_proc_mkdir(struct inode
+ 	};
+ 	int			status;
+ 
+-	fattr.valid = 0;
++	nfs_fattr_init(&fattr);
++	nfs_fattr_init(&dir_fattr);
+ 	
+ 	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ 	if (!status) {
+ 		update_changeattr(dir, &res.dir_cinfo);
++		nfs_post_op_update_inode(dir, res.dir_fattr);
+ 		status = nfs_instantiate(dentry, &fhandle, &fattr);
+ 	}
+ 	return status;
+@@ -1762,7 +1955,7 @@ static int _nfs4_proc_mknod(struct inode
+ {
+ 	struct nfs_server *server = NFS_SERVER(dir);
+ 	struct nfs_fh fh;
+-	struct nfs_fattr fattr;
++	struct nfs_fattr fattr, dir_fattr;
+ 	struct nfs4_create_arg arg = {
+ 		.dir_fh = NFS_FH(dir),
+ 		.server = server,
+@@ -1774,6 +1967,7 @@ static int _nfs4_proc_mknod(struct inode
+ 		.server = server,
+ 		.fh = &fh,
+ 		.fattr = &fattr,
++		.dir_fattr = &dir_fattr,
+ 	};
+ 	struct rpc_message msg = {
+ 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE],
+@@ -1783,7 +1977,8 @@ static int _nfs4_proc_mknod(struct inode
+ 	int			status;
+ 	int                     mode = sattr->ia_mode;
+ 
+-	fattr.valid = 0;
++	nfs_fattr_init(&fattr);
++	nfs_fattr_init(&dir_fattr);
+ 
+ 	BUG_ON(!(sattr->ia_valid & ATTR_MODE));
+ 	BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode));
+@@ -1805,6 +2000,7 @@ static int _nfs4_proc_mknod(struct inode
+ 	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ 	if (status == 0) {
+ 		update_changeattr(dir, &res.dir_cinfo);
++		nfs_post_op_update_inode(dir, res.dir_fattr);
+ 		status = nfs_instantiate(dentry, &fh, &fattr);
+ 	}
+ 	return status;
+@@ -1836,7 +2032,7 @@ static int _nfs4_proc_statfs(struct nfs_
+ 		.rpc_resp = fsstat,
+ 	};
+ 
+-	fsstat->fattr->valid = 0;
++	nfs_fattr_init(fsstat->fattr);
+ 	return rpc_call_sync(server->client, &msg, 0);
+ }
+ 
+@@ -1883,7 +2079,7 @@ static int nfs4_do_fsinfo(struct nfs_ser
+ 
+ static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
+ {
+-	fsinfo->fattr->valid = 0;
++	nfs_fattr_init(fsinfo->fattr);
+ 	return nfs4_do_fsinfo(server, fhandle, fsinfo);
+ }
+ 
+@@ -1906,7 +2102,7 @@ static int _nfs4_proc_pathconf(struct nf
+ 		return 0;
+ 	}
+ 
+-	pathconf->fattr->valid = 0;
++	nfs_fattr_init(pathconf->fattr);
+ 	return rpc_call_sync(server->client, &msg, 0);
+ }
+ 
+@@ -1973,8 +2169,10 @@ nfs4_write_done(struct rpc_task *task)
+ 		rpc_restart_call(task);
+ 		return;
+ 	}
+-	if (task->tk_status >= 0)
++	if (task->tk_status >= 0) {
+ 		renew_lease(NFS_SERVER(inode), data->timestamp);
++		nfs_post_op_update_inode(inode, data->res.fattr);
++	}
+ 	/* Call back common NFS writeback processing */
+ 	nfs_writeback_done(task);
+ }
+@@ -1990,6 +2188,7 @@ nfs4_proc_write_setup(struct nfs_write_d
+ 		.rpc_cred = data->cred,
+ 	};
+ 	struct inode *inode = data->inode;
++	struct nfs_server *server = NFS_SERVER(inode);
+ 	int stable;
+ 	int flags;
+ 	
+@@ -2001,6 +2200,8 @@ nfs4_proc_write_setup(struct nfs_write_d
+ 	} else
+ 		stable = NFS_UNSTABLE;
+ 	data->args.stable = stable;
++	data->args.bitmask = server->attr_bitmask;
++	data->res.server = server;
+ 
+ 	data->timestamp   = jiffies;
+ 
+@@ -2022,6 +2223,8 @@ nfs4_commit_done(struct rpc_task *task)
+ 		rpc_restart_call(task);
+ 		return;
+ 	}
++	if (task->tk_status >= 0)
++		nfs_post_op_update_inode(inode, data->res.fattr);
+ 	/* Call back common NFS writeback processing */
+ 	nfs_commit_done(task);
+ }
+@@ -2037,8 +2240,12 @@ nfs4_proc_commit_setup(struct nfs_write_
+ 		.rpc_cred = data->cred,
+ 	};	
+ 	struct inode *inode = data->inode;
++	struct nfs_server *server = NFS_SERVER(inode);
+ 	int flags;
+ 	
++	data->args.bitmask = server->attr_bitmask;
++	data->res.server = server;
++
+ 	/* Set the initial flags for the task.  */
+ 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
+ 
+@@ -2106,65 +2313,6 @@ nfs4_proc_renew(struct nfs4_client *clp)
+ 	return 0;
+ }
+ 
+-/*
+- * We will need to arrange for the VFS layer to provide an atomic open.
+- * Until then, this open method is prone to inefficiency and race conditions
+- * due to the lookup, potential create, and open VFS calls from sys_open()
+- * placed on the wire.
+- */
+-static int
+-nfs4_proc_file_open(struct inode *inode, struct file *filp)
+-{
+-	struct dentry *dentry = filp->f_dentry;
+-	struct nfs_open_context *ctx;
+-	struct nfs4_state *state = NULL;
+-	struct rpc_cred *cred;
+-	int status = -ENOMEM;
+-
+-	dprintk("nfs4_proc_file_open: starting on (%.*s/%.*s)\n",
+-	                       (int)dentry->d_parent->d_name.len,
+-	                       dentry->d_parent->d_name.name,
+-	                       (int)dentry->d_name.len, dentry->d_name.name);
+-
+-
+-	/* Find our open stateid */
+-	cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
+-	if (IS_ERR(cred))
+-		return PTR_ERR(cred);
+-	ctx = alloc_nfs_open_context(dentry, cred);
+-	put_rpccred(cred);
+-	if (unlikely(ctx == NULL))
+-		return -ENOMEM;
+-	status = -EIO; /* ERACE actually */
+-	state = nfs4_find_state(inode, cred, filp->f_mode);
+-	if (unlikely(state == NULL))
+-		goto no_state;
+-	ctx->state = state;
+-	nfs4_close_state(state, filp->f_mode);
+-	ctx->mode = filp->f_mode;
+-	nfs_file_set_open_context(filp, ctx);
+-	put_nfs_open_context(ctx);
+-	if (filp->f_mode & FMODE_WRITE)
+-		nfs_begin_data_update(inode);
+-	return 0;
+-no_state:
+-	printk(KERN_WARNING "NFS: v4 raced in function %s\n", __FUNCTION__);
+-	put_nfs_open_context(ctx);
+-	return status;
+-}
+-
+-/*
+- * Release our state
+- */
+-static int
+-nfs4_proc_file_release(struct inode *inode, struct file *filp)
+-{
+-	if (filp->f_mode & FMODE_WRITE)
+-		nfs_end_data_update(inode);
+-	nfs_file_clear_open_context(filp);
+-	return 0;
+-}
+-
+ static inline int nfs4_server_supports_acls(struct nfs_server *server)
+ {
+ 	return (server->caps & NFS_CAP_ACLS)
+@@ -2285,7 +2433,7 @@ static inline ssize_t nfs4_get_acl_uncac
+ 			return -ENOMEM;
+ 		args.acl_pages[0] = localpage;
+ 		args.acl_pgbase = 0;
+-		args.acl_len = PAGE_SIZE;
++		resp_len = args.acl_len = PAGE_SIZE;
+ 	} else {
+ 		resp_buf = buf;
+ 		buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
+@@ -2345,6 +2493,7 @@ static int nfs4_proc_set_acl(struct inod
+ 
+ 	if (!nfs4_server_supports_acls(server))
+ 		return -EOPNOTSUPP;
++	nfs_inode_return_delegation(inode);
+ 	buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
+ 	ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0);
+ 	if (ret == 0)
+@@ -2353,7 +2502,7 @@ static int nfs4_proc_set_acl(struct inod
+ }
+ 
+ static int
+-nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server)
++nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
+ {
+ 	struct nfs4_client *clp = server->nfs4_state;
+ 
+@@ -2431,7 +2580,7 @@ static int nfs4_delay(struct rpc_clnt *c
+ /* This is the error handling routine for processes that are allowed
+  * to sleep.
+  */
+-int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
++int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
+ {
+ 	struct nfs4_client *clp = server->nfs4_state;
+ 	int ret = errorcode;
+@@ -2632,7 +2781,6 @@ static int _nfs4_proc_getlk(struct nfs4_
+ 
+ 	down_read(&clp->cl_sem);
+ 	nlo.clientid = clp->cl_clientid;
+-	down(&state->lock_sema);
+ 	status = nfs4_set_lock_state(state, request);
+ 	if (status != 0)
+ 		goto out;
+@@ -2659,7 +2807,6 @@ static int _nfs4_proc_getlk(struct nfs4_
+ 		status = 0;
+ 	}
+ out:
+-	up(&state->lock_sema);
+ 	up_read(&clp->cl_sem);
+ 	return status;
+ }
+@@ -2696,67 +2843,125 @@ static int do_vfs_lock(struct file *file
+ 	return res;
+ }
+ 
+-static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
++struct nfs4_unlockdata {
++	struct nfs_lockargs arg;
++	struct nfs_locku_opargs luargs;
++	struct nfs_lockres res;
++	struct nfs4_lock_state *lsp;
++	struct nfs_open_context *ctx;
++	atomic_t refcount;
++	struct completion completion;
++};
++
++static void nfs4_locku_release_calldata(struct nfs4_unlockdata *calldata)
+ {
+-	struct inode *inode = state->inode;
+-	struct nfs_server *server = NFS_SERVER(inode);
+-	struct nfs4_client *clp = server->nfs4_state;
+-	struct nfs_lockargs arg = {
+-		.fh = NFS_FH(inode),
+-		.type = nfs4_lck_type(cmd, request),
+-		.offset = request->fl_start,
+-		.length = nfs4_lck_length(request),
+-	};
+-	struct nfs_lockres res = {
+-		.server = server,
+-	};
++	if (atomic_dec_and_test(&calldata->refcount)) {
++		nfs_free_seqid(calldata->luargs.seqid);
++		nfs4_put_lock_state(calldata->lsp);
++		put_nfs_open_context(calldata->ctx);
++		kfree(calldata);
++	}
++}
++
++static void nfs4_locku_complete(struct nfs4_unlockdata *calldata)
++{
++	complete(&calldata->completion);
++	nfs4_locku_release_calldata(calldata);
++}
++
++static void nfs4_locku_done(struct rpc_task *task)
++{
++	struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata;
++
++	nfs_increment_lock_seqid(task->tk_status, calldata->luargs.seqid);
++	switch (task->tk_status) {
++		case 0:
++			memcpy(calldata->lsp->ls_stateid.data,
++					calldata->res.u.stateid.data,
++					sizeof(calldata->lsp->ls_stateid.data));
++			break;
++		case -NFS4ERR_STALE_STATEID:
++		case -NFS4ERR_EXPIRED:
++			nfs4_schedule_state_recovery(calldata->res.server->nfs4_state);
++			break;
++		default:
++			if (nfs4_async_handle_error(task, calldata->res.server) == -EAGAIN) {
++				rpc_restart_call(task);
++				return;
++			}
++	}
++	nfs4_locku_complete(calldata);
++}
++
++static void nfs4_locku_begin(struct rpc_task *task)
++{
++	struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata;
+ 	struct rpc_message msg = {
+ 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_LOCKU],
+-		.rpc_argp       = &arg,
+-		.rpc_resp       = &res,
+-		.rpc_cred	= state->owner->so_cred,
++		.rpc_argp       = &calldata->arg,
++		.rpc_resp       = &calldata->res,
++		.rpc_cred	= calldata->lsp->ls_state->owner->so_cred,
+ 	};
++	int status;
++
++	status = nfs_wait_on_sequence(calldata->luargs.seqid, task);
++	if (status != 0)
++		return;
++	if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) {
++		nfs4_locku_complete(calldata);
++		task->tk_exit = NULL;
++		rpc_exit(task, 0);
++		return;
++	}
++	rpc_call_setup(task, &msg, 0);
++}
++
++static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
++{
++	struct nfs4_unlockdata *calldata;
++	struct inode *inode = state->inode;
++	struct nfs_server *server = NFS_SERVER(inode);
+ 	struct nfs4_lock_state *lsp;
+-	struct nfs_locku_opargs luargs;
+ 	int status;
+-			
+-	down_read(&clp->cl_sem);
+-	down(&state->lock_sema);
++
+ 	status = nfs4_set_lock_state(state, request);
+ 	if (status != 0)
+-		goto out;
++		return status;
+ 	lsp = request->fl_u.nfs4_fl.owner;
+ 	/* We might have lost the locks! */
+ 	if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0)
+-		goto out;
+-	luargs.seqid = lsp->ls_seqid;
+-	memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid));
+-	arg.u.locku = &luargs;
+-	status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+-	nfs4_increment_lock_seqid(status, lsp);
++		return 0;
++	calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
++	if (calldata == NULL)
++		return -ENOMEM;
++	calldata->luargs.seqid = nfs_alloc_seqid(&lsp->ls_seqid);
++	if (calldata->luargs.seqid == NULL) {
++		kfree(calldata);
++		return -ENOMEM;
++	}
++	calldata->luargs.stateid = &lsp->ls_stateid;
++	calldata->arg.fh = NFS_FH(inode);
++	calldata->arg.type = nfs4_lck_type(cmd, request);
++	calldata->arg.offset = request->fl_start;
++	calldata->arg.length = nfs4_lck_length(request);
++	calldata->arg.u.locku = &calldata->luargs;
++	calldata->res.server = server;
++	calldata->lsp = lsp;
++	atomic_inc(&lsp->ls_count);
+ 
+-	if (status == 0)
+-		memcpy(&lsp->ls_stateid,  &res.u.stateid, 
+-				sizeof(lsp->ls_stateid));
+-out:
+-	up(&state->lock_sema);
+-	if (status == 0)
+-		do_vfs_lock(request->fl_file, request);
+-	up_read(&clp->cl_sem);
+-	return status;
+-}
++	/* Ensure we don't close file until we're done freeing locks! */
++	calldata->ctx = get_nfs_open_context((struct nfs_open_context*)request->fl_file->private_data);
+ 
+-static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
+-{
+-	struct nfs4_exception exception = { };
+-	int err;
++	atomic_set(&calldata->refcount, 2);
++	init_completion(&calldata->completion);
+ 
+-	do {
+-		err = nfs4_handle_exception(NFS_SERVER(state->inode),
+-				_nfs4_proc_unlck(state, cmd, request),
+-				&exception);
+-	} while (exception.retry);
+-	return err;
++	status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_locku_begin,
++			nfs4_locku_done, calldata);
++	if (status == 0)
++		wait_for_completion_interruptible(&calldata->completion);
++	do_vfs_lock(request->fl_file, request);
++	nfs4_locku_release_calldata(calldata);
++	return status;
+ }
+ 
+ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *request, int reclaim)
+@@ -2764,11 +2969,23 @@ static int _nfs4_do_setlk(struct nfs4_st
+ 	struct inode *inode = state->inode;
+ 	struct nfs_server *server = NFS_SERVER(inode);
+ 	struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
++	struct nfs_lock_opargs largs = {
++		.lock_stateid = &lsp->ls_stateid,
++		.open_stateid = &state->stateid,
++		.lock_owner = {
++			.clientid = server->nfs4_state->cl_clientid,
++			.id = lsp->ls_id,
++		},
++		.reclaim = reclaim,
++	};
+ 	struct nfs_lockargs arg = {
+ 		.fh = NFS_FH(inode),
+ 		.type = nfs4_lck_type(cmd, request),
+ 		.offset = request->fl_start,
+ 		.length = nfs4_lck_length(request),
++		.u = {
++			.lock = &largs,
++		},
+ 	};
+ 	struct nfs_lockres res = {
+ 		.server = server,
+@@ -2779,53 +2996,39 @@ static int _nfs4_do_setlk(struct nfs4_st
+ 		.rpc_resp       = &res,
+ 		.rpc_cred	= state->owner->so_cred,
+ 	};
+-	struct nfs_lock_opargs largs = {
+-		.reclaim = reclaim,
+-		.new_lock_owner = 0,
+-	};
+-	int status;
++	int status = -ENOMEM;
+ 
+-	if (!(lsp->ls_flags & NFS_LOCK_INITIALIZED)) {
++	largs.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
++	if (largs.lock_seqid == NULL)
++		return -ENOMEM;
++	if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) {
+ 		struct nfs4_state_owner *owner = state->owner;
+-		struct nfs_open_to_lock otl = {
+-			.lock_owner = {
+-				.clientid = server->nfs4_state->cl_clientid,
+-			},
+-		};
+-
+-		otl.lock_seqid = lsp->ls_seqid;
+-		otl.lock_owner.id = lsp->ls_id;
+-		memcpy(&otl.open_stateid, &state->stateid, sizeof(otl.open_stateid));
+-		largs.u.open_lock = &otl;
++
++		largs.open_seqid = nfs_alloc_seqid(&owner->so_seqid);
++		if (largs.open_seqid == NULL)
++			goto out;
+ 		largs.new_lock_owner = 1;
+-		arg.u.lock = &largs;
+-		down(&owner->so_sema);
+-		otl.open_seqid = owner->so_seqid;
+ 		status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+-		/* increment open_owner seqid on success, and 
+-		* seqid mutating errors */
+-		nfs4_increment_seqid(status, owner);
+-		up(&owner->so_sema);
+-		if (status == 0) {
+-			lsp->ls_flags |= NFS_LOCK_INITIALIZED;
+-			lsp->ls_seqid++;
++		/* increment open seqid on success, and seqid mutating errors */
++		if (largs.new_lock_owner != 0) {
++			nfs_increment_open_seqid(status, largs.open_seqid);
++			if (status == 0)
++				nfs_confirm_seqid(&lsp->ls_seqid, 0);
+ 		}
+-	} else {
+-		struct nfs_exist_lock el = {
+-			.seqid = lsp->ls_seqid,
+-		};
+-		memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid));
+-		largs.u.exist_lock = &el;
+-		arg.u.lock = &largs;
++		nfs_free_seqid(largs.open_seqid);
++	} else
+ 		status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+-		/* increment seqid on success, and * seqid mutating errors*/
+-		nfs4_increment_lock_seqid(status, lsp);
+-	}
++	/* increment lock seqid on success, and seqid mutating errors*/
++	nfs_increment_lock_seqid(status, largs.lock_seqid);
+ 	/* save the returned stateid. */
+-	if (status == 0)
+-		memcpy(&lsp->ls_stateid, &res.u.stateid, sizeof(nfs4_stateid));
+-	else if (status == -NFS4ERR_DENIED)
++	if (status == 0) {
++		memcpy(lsp->ls_stateid.data, res.u.stateid.data,
++				sizeof(lsp->ls_stateid.data));
++		lsp->ls_flags |= NFS_LOCK_INITIALIZED;
++	} else if (status == -NFS4ERR_DENIED)
+ 		status = -EAGAIN;
++out:
++	nfs_free_seqid(largs.lock_seqid);
+ 	return status;
+ }
+ 
+@@ -2865,11 +3068,9 @@ static int _nfs4_proc_setlk(struct nfs4_
+ 	int status;
+ 
+ 	down_read(&clp->cl_sem);
+-	down(&state->lock_sema);
+ 	status = nfs4_set_lock_state(state, request);
+ 	if (status == 0)
+ 		status = _nfs4_do_setlk(state, cmd, request, 0);
+-	up(&state->lock_sema);
+ 	if (status == 0) {
+ 		/* Note: we always want to sleep here! */
+ 		request->fl_flags |= FL_SLEEP;
+@@ -3024,8 +3225,8 @@ struct nfs_rpc_ops	nfs_v4_clientops = {
+ 	.read_setup	= nfs4_proc_read_setup,
+ 	.write_setup	= nfs4_proc_write_setup,
+ 	.commit_setup	= nfs4_proc_commit_setup,
+-	.file_open      = nfs4_proc_file_open,
+-	.file_release   = nfs4_proc_file_release,
++	.file_open      = nfs_open,
++	.file_release   = nfs_release,
+ 	.lock		= nfs4_proc_lock,
+ 	.clear_acl_cache = nfs4_zap_acl_attr,
+ };
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -264,13 +264,16 @@ nfs4_alloc_state_owner(void)
+ {
+ 	struct nfs4_state_owner *sp;
+ 
+-	sp = kmalloc(sizeof(*sp),GFP_KERNEL);
++	sp = kzalloc(sizeof(*sp),GFP_KERNEL);
+ 	if (!sp)
+ 		return NULL;
+-	init_MUTEX(&sp->so_sema);
+-	sp->so_seqid = 0;                 /* arbitrary */
++	spin_lock_init(&sp->so_lock);
+ 	INIT_LIST_HEAD(&sp->so_states);
+ 	INIT_LIST_HEAD(&sp->so_delegations);
++	rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue");
++	sp->so_seqid.sequence = &sp->so_sequence;
++	spin_lock_init(&sp->so_sequence.lock);
++	INIT_LIST_HEAD(&sp->so_sequence.list);
+ 	atomic_set(&sp->so_count, 1);
+ 	return sp;
+ }
+@@ -359,7 +362,6 @@ nfs4_alloc_open_state(void)
+ 	memset(state->stateid.data, 0, sizeof(state->stateid.data));
+ 	atomic_set(&state->count, 1);
+ 	INIT_LIST_HEAD(&state->lock_states);
+-	init_MUTEX(&state->lock_sema);
+ 	spin_lock_init(&state->state_lock);
+ 	return state;
+ }
+@@ -437,21 +439,23 @@ nfs4_get_open_state(struct inode *inode,
+ 	if (state)
+ 		goto out;
+ 	new = nfs4_alloc_open_state();
++	spin_lock(&owner->so_lock);
+ 	spin_lock(&inode->i_lock);
+ 	state = __nfs4_find_state_byowner(inode, owner);
+ 	if (state == NULL && new != NULL) {
+ 		state = new;
+-		/* Caller *must* be holding owner->so_sem */
+-		/* Note: The reclaim code dictates that we add stateless
+-		 * and read-only stateids to the end of the list */
+-		list_add_tail(&state->open_states, &owner->so_states);
+ 		state->owner = owner;
+ 		atomic_inc(&owner->so_count);
+ 		list_add(&state->inode_states, &nfsi->open_states);
+ 		state->inode = igrab(inode);
+ 		spin_unlock(&inode->i_lock);
++		/* Note: The reclaim code dictates that we add stateless
++		 * and read-only stateids to the end of the list */
++		list_add_tail(&state->open_states, &owner->so_states);
++		spin_unlock(&owner->so_lock);
+ 	} else {
+ 		spin_unlock(&inode->i_lock);
++		spin_unlock(&owner->so_lock);
+ 		if (new)
+ 			nfs4_free_open_state(new);
+ 	}
+@@ -461,19 +465,21 @@ out:
+ 
+ /*
+  * Beware! Caller must be holding exactly one
+- * reference to clp->cl_sem and owner->so_sema!
++ * reference to clp->cl_sem!
+  */
+ void nfs4_put_open_state(struct nfs4_state *state)
+ {
+ 	struct inode *inode = state->inode;
+ 	struct nfs4_state_owner *owner = state->owner;
+ 
+-	if (!atomic_dec_and_lock(&state->count, &inode->i_lock))
++	if (!atomic_dec_and_lock(&state->count, &owner->so_lock))
+ 		return;
++	spin_lock(&inode->i_lock);
+ 	if (!list_empty(&state->inode_states))
+ 		list_del(&state->inode_states);
+-	spin_unlock(&inode->i_lock);
+ 	list_del(&state->open_states);
++	spin_unlock(&inode->i_lock);
++	spin_unlock(&owner->so_lock);
+ 	iput(inode);
+ 	BUG_ON (state->state != 0);
+ 	nfs4_free_open_state(state);
+@@ -481,20 +487,17 @@ void nfs4_put_open_state(struct nfs4_sta
+ }
+ 
+ /*
+- * Beware! Caller must be holding no references to clp->cl_sem!
+- * of owner->so_sema!
++ * Close the current file.
+  */
+ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
+ {
+ 	struct inode *inode = state->inode;
+ 	struct nfs4_state_owner *owner = state->owner;
+-	struct nfs4_client *clp = owner->so_client;
+ 	int newstate;
+ 
+ 	atomic_inc(&owner->so_count);
+-	down_read(&clp->cl_sem);
+-	down(&owner->so_sema);
+ 	/* Protect against nfs4_find_state() */
++	spin_lock(&owner->so_lock);
+ 	spin_lock(&inode->i_lock);
+ 	if (mode & FMODE_READ)
+ 		state->nreaders--;
+@@ -507,6 +510,7 @@ void nfs4_close_state(struct nfs4_state 
+ 		list_move_tail(&state->open_states, &owner->so_states);
+ 	}
+ 	spin_unlock(&inode->i_lock);
++	spin_unlock(&owner->so_lock);
+ 	newstate = 0;
+ 	if (state->state != 0) {
+ 		if (state->nreaders)
+@@ -515,14 +519,16 @@ void nfs4_close_state(struct nfs4_state 
+ 			newstate |= FMODE_WRITE;
+ 		if (state->state == newstate)
+ 			goto out;
+-		if (nfs4_do_close(inode, state, newstate) == -EINPROGRESS)
++		if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
++			state->state = newstate;
++			goto out;
++		}
++		if (nfs4_do_close(inode, state, newstate) == 0)
+ 			return;
+ 	}
+ out:
+ 	nfs4_put_open_state(state);
+-	up(&owner->so_sema);
+ 	nfs4_put_state_owner(owner);
+-	up_read(&clp->cl_sem);
+ }
+ 
+ /*
+@@ -546,19 +552,16 @@ __nfs4_find_lock_state(struct nfs4_state
+  * Return a compatible lock_state. If no initialized lock_state structure
+  * exists, return an uninitialized one.
+  *
+- * The caller must be holding state->lock_sema
+  */
+ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
+ {
+ 	struct nfs4_lock_state *lsp;
+ 	struct nfs4_client *clp = state->owner->so_client;
+ 
+-	lsp = kmalloc(sizeof(*lsp), GFP_KERNEL);
++	lsp = kzalloc(sizeof(*lsp), GFP_KERNEL);
+ 	if (lsp == NULL)
+ 		return NULL;
+-	lsp->ls_flags = 0;
+-	lsp->ls_seqid = 0;	/* arbitrary */
+-	memset(lsp->ls_stateid.data, 0, sizeof(lsp->ls_stateid.data));
++	lsp->ls_seqid.sequence = &state->owner->so_sequence;
+ 	atomic_set(&lsp->ls_count, 1);
+ 	lsp->ls_owner = fl_owner;
+ 	spin_lock(&clp->cl_lock);
+@@ -572,7 +575,7 @@ static struct nfs4_lock_state *nfs4_allo
+  * Return a compatible lock_state. If no initialized lock_state structure
+  * exists, return an uninitialized one.
+  *
+- * The caller must be holding state->lock_sema and clp->cl_sem
++ * The caller must be holding clp->cl_sem
+  */
+ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
+ {
+@@ -605,7 +608,7 @@ static struct nfs4_lock_state *nfs4_get_
+  * Release reference to lock_state, and free it if we see that
+  * it is no longer in use
+  */
+-static void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
++void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
+ {
+ 	struct nfs4_state *state;
+ 
+@@ -673,29 +676,94 @@ void nfs4_copy_stateid(nfs4_stateid *dst
+ 	nfs4_put_lock_state(lsp);
+ }
+ 
+-/*
+-* Called with state->lock_sema and clp->cl_sem held.
+-*/
+-void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *lsp)
+-{
+-	if (status == NFS_OK || seqid_mutating_err(-status))
+-		lsp->ls_seqid++;
++struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
++{
++	struct nfs_seqid *new;
++
++	new = kmalloc(sizeof(*new), GFP_KERNEL);
++	if (new != NULL) {
++		new->sequence = counter;
++		INIT_LIST_HEAD(&new->list);
++	}
++	return new;
++}
++
++void nfs_free_seqid(struct nfs_seqid *seqid)
++{
++	struct rpc_sequence *sequence = seqid->sequence->sequence;
++
++	if (!list_empty(&seqid->list)) {
++		spin_lock(&sequence->lock);
++		list_del(&seqid->list);
++		spin_unlock(&sequence->lock);
++	}
++	rpc_wake_up_next(&sequence->wait);
++	kfree(seqid);
+ }
+ 
+ /*
+-* Called with sp->so_sema and clp->cl_sem held.
+-*
+-* Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or
+-* failed with a seqid incrementing error -
+-* see comments nfs_fs.h:seqid_mutating_error()
+-*/
+-void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp)
+-{
+-	if (status == NFS_OK || seqid_mutating_err(-status))
+-		sp->so_seqid++;
+-	/* If the server returns BAD_SEQID, unhash state_owner here */
+-	if (status == -NFS4ERR_BAD_SEQID)
++ * Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or
++ * failed with a seqid incrementing error -
++ * see comments nfs_fs.h:seqid_mutating_error()
++ */
++static inline void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
++{
++	switch (status) {
++		case 0:
++			break;
++		case -NFS4ERR_BAD_SEQID:
++		case -NFS4ERR_STALE_CLIENTID:
++		case -NFS4ERR_STALE_STATEID:
++		case -NFS4ERR_BAD_STATEID:
++		case -NFS4ERR_BADXDR:
++		case -NFS4ERR_RESOURCE:
++		case -NFS4ERR_NOFILEHANDLE:
++			/* Non-seqid mutating errors */
++			return;
++	};
++	/*
++	 * Note: no locking needed as we are guaranteed to be first
++	 * on the sequence list
++	 */
++	seqid->sequence->counter++;
++}
++
++void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
++{
++	if (status == -NFS4ERR_BAD_SEQID) {
++		struct nfs4_state_owner *sp = container_of(seqid->sequence,
++				struct nfs4_state_owner, so_seqid);
+ 		nfs4_drop_state_owner(sp);
++	}
++	return nfs_increment_seqid(status, seqid);
++}
++
++/*
++ * Increment the seqid if the LOCK/LOCKU succeeded, or
++ * failed with a seqid incrementing error -
++ * see comments nfs_fs.h:seqid_mutating_error()
++ */
++void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
++{
++	return nfs_increment_seqid(status, seqid);
++}
++
++int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
++{
++	struct rpc_sequence *sequence = seqid->sequence->sequence;
++	int status = 0;
++
++	if (sequence->list.next == &seqid->list)
++		goto out;
++	spin_lock(&sequence->lock);
++	if (!list_empty(&sequence->list)) {
++		rpc_sleep_on(&sequence->wait, task, NULL, NULL);
++		status = -EAGAIN;
++	} else
++		list_add(&seqid->list, &sequence->list);
++	spin_unlock(&sequence->lock);
++out:
++	return status;
+ }
+ 
+ static int reclaimer(void *);
+@@ -791,8 +859,6 @@ static int nfs4_reclaim_open_state(struc
+ 		if (state->state == 0)
+ 			continue;
+ 		status = ops->recover_open(sp, state);
+-		list_for_each_entry(lock, &state->lock_states, ls_locks)
+-			lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
+ 		if (status >= 0) {
+ 			status = nfs4_reclaim_locks(ops, state);
+ 			if (status < 0)
+@@ -831,6 +897,28 @@ out_err:
+ 	return status;
+ }
+ 
++static void nfs4_state_mark_reclaim(struct nfs4_client *clp)
++{
++	struct nfs4_state_owner *sp;
++	struct nfs4_state *state;
++	struct nfs4_lock_state *lock;
++
++	/* Reset all sequence ids to zero */
++	list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
++		sp->so_seqid.counter = 0;
++		sp->so_seqid.flags = 0;
++		spin_lock(&sp->so_lock);
++		list_for_each_entry(state, &sp->so_states, open_states) {
++			list_for_each_entry(lock, &state->lock_states, ls_locks) {
++				lock->ls_seqid.counter = 0;
++				lock->ls_seqid.flags = 0;
++				lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
++			}
++		}
++		spin_unlock(&sp->so_lock);
++	}
++}
++
+ static int reclaimer(void *ptr)
+ {
+ 	struct reclaimer_args *args = (struct reclaimer_args *)ptr;
+@@ -864,6 +952,7 @@ restart_loop:
+ 		default:
+ 			ops = &nfs4_network_partition_recovery_ops;
+ 	};
++	nfs4_state_mark_reclaim(clp);
+ 	status = __nfs4_init_client(clp);
+ 	if (status)
+ 		goto out_error;
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -95,6 +95,8 @@ static int nfs_stat_to_errno(int);
+ #define decode_getattr_maxsz    (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
+ #define encode_savefh_maxsz     (op_encode_hdr_maxsz)
+ #define decode_savefh_maxsz     (op_decode_hdr_maxsz)
++#define encode_restorefh_maxsz  (op_encode_hdr_maxsz)
++#define decode_restorefh_maxsz  (op_decode_hdr_maxsz)
+ #define encode_fsinfo_maxsz	(op_encode_hdr_maxsz + 2)
+ #define decode_fsinfo_maxsz	(op_decode_hdr_maxsz + 11)
+ #define encode_renew_maxsz	(op_encode_hdr_maxsz + 3)
+@@ -157,16 +159,20 @@ static int nfs_stat_to_errno(int);
+ 				op_decode_hdr_maxsz + 2)
+ #define NFS4_enc_write_sz	(compound_encode_hdr_maxsz + \
+ 				encode_putfh_maxsz + \
+-				op_encode_hdr_maxsz + 8)
++				op_encode_hdr_maxsz + 8 + \
++				encode_getattr_maxsz)
+ #define NFS4_dec_write_sz	(compound_decode_hdr_maxsz + \
+ 				decode_putfh_maxsz + \
+-				op_decode_hdr_maxsz + 4)
++				op_decode_hdr_maxsz + 4 + \
++				decode_getattr_maxsz)
+ #define NFS4_enc_commit_sz	(compound_encode_hdr_maxsz + \
+ 				encode_putfh_maxsz + \
+-				op_encode_hdr_maxsz + 3)
++				op_encode_hdr_maxsz + 3 + \
++				encode_getattr_maxsz)
+ #define NFS4_dec_commit_sz	(compound_decode_hdr_maxsz + \
+ 				decode_putfh_maxsz + \
+-				op_decode_hdr_maxsz + 2)
++				op_decode_hdr_maxsz + 2 + \
++				decode_getattr_maxsz)
+ #define NFS4_enc_open_sz        (compound_encode_hdr_maxsz + \
+                                 encode_putfh_maxsz + \
+                                 op_encode_hdr_maxsz + \
+@@ -196,17 +202,21 @@ static int nfs_stat_to_errno(int);
+ #define NFS4_enc_open_downgrade_sz \
+ 				(compound_encode_hdr_maxsz + \
+                                 encode_putfh_maxsz + \
+-                                op_encode_hdr_maxsz + 7)
++                                op_encode_hdr_maxsz + 7 + \
++				encode_getattr_maxsz)
+ #define NFS4_dec_open_downgrade_sz \
+ 				(compound_decode_hdr_maxsz + \
+                                 decode_putfh_maxsz + \
+-                                op_decode_hdr_maxsz + 4)
++                                op_decode_hdr_maxsz + 4 + \
++				decode_getattr_maxsz)
+ #define NFS4_enc_close_sz       (compound_encode_hdr_maxsz + \
+                                 encode_putfh_maxsz + \
+-                                op_encode_hdr_maxsz + 5)
++                                op_encode_hdr_maxsz + 5 + \
++				encode_getattr_maxsz)
+ #define NFS4_dec_close_sz       (compound_decode_hdr_maxsz + \
+                                 decode_putfh_maxsz + \
+-                                op_decode_hdr_maxsz + 4)
++                                op_decode_hdr_maxsz + 4 + \
++				decode_getattr_maxsz)
+ #define NFS4_enc_setattr_sz     (compound_encode_hdr_maxsz + \
+                                 encode_putfh_maxsz + \
+                                 op_encode_hdr_maxsz + 4 + \
+@@ -300,30 +310,44 @@ static int nfs_stat_to_errno(int);
+ 				decode_getfh_maxsz)
+ #define NFS4_enc_remove_sz	(compound_encode_hdr_maxsz + \
+ 				encode_putfh_maxsz + \
+-				encode_remove_maxsz)
++				encode_remove_maxsz + \
++				encode_getattr_maxsz)
+ #define NFS4_dec_remove_sz	(compound_decode_hdr_maxsz + \
+ 				decode_putfh_maxsz + \
+-				op_decode_hdr_maxsz + 5)
++				op_decode_hdr_maxsz + 5 + \
++				decode_getattr_maxsz)
+ #define NFS4_enc_rename_sz	(compound_encode_hdr_maxsz + \
+ 				encode_putfh_maxsz + \
+ 				encode_savefh_maxsz + \
+ 				encode_putfh_maxsz + \
+-				encode_rename_maxsz)
++				encode_rename_maxsz + \
++				encode_getattr_maxsz + \
++				encode_restorefh_maxsz + \
++				encode_getattr_maxsz)
+ #define NFS4_dec_rename_sz	(compound_decode_hdr_maxsz + \
+ 				decode_putfh_maxsz + \
+ 				decode_savefh_maxsz + \
+ 				decode_putfh_maxsz + \
+-				decode_rename_maxsz)
++				decode_rename_maxsz + \
++				decode_getattr_maxsz + \
++				decode_restorefh_maxsz + \
++				decode_getattr_maxsz)
+ #define NFS4_enc_link_sz	(compound_encode_hdr_maxsz + \
+ 				encode_putfh_maxsz + \
+ 				encode_savefh_maxsz + \
+ 				encode_putfh_maxsz + \
+-				encode_link_maxsz)
++				encode_link_maxsz + \
++				decode_getattr_maxsz + \
++				encode_restorefh_maxsz + \
++				decode_getattr_maxsz)
+ #define NFS4_dec_link_sz	(compound_decode_hdr_maxsz + \
+ 				decode_putfh_maxsz + \
+ 				decode_savefh_maxsz + \
+ 				decode_putfh_maxsz + \
+-				decode_link_maxsz)
++				decode_link_maxsz + \
++				decode_getattr_maxsz + \
++				decode_restorefh_maxsz + \
++				decode_getattr_maxsz)
+ #define NFS4_enc_symlink_sz	(compound_encode_hdr_maxsz + \
+ 				encode_putfh_maxsz + \
+ 				encode_symlink_maxsz + \
+@@ -336,14 +360,20 @@ static int nfs_stat_to_errno(int);
+ 				decode_getfh_maxsz)
+ #define NFS4_enc_create_sz	(compound_encode_hdr_maxsz + \
+ 				encode_putfh_maxsz + \
++				encode_savefh_maxsz + \
+ 				encode_create_maxsz + \
++				encode_getfh_maxsz + \
+ 				encode_getattr_maxsz + \
+-				encode_getfh_maxsz)
++				encode_restorefh_maxsz + \
++				encode_getattr_maxsz)
+ #define NFS4_dec_create_sz	(compound_decode_hdr_maxsz + \
+ 				decode_putfh_maxsz + \
++				decode_savefh_maxsz + \
+ 				decode_create_maxsz + \
++				decode_getfh_maxsz + \
+ 				decode_getattr_maxsz + \
+-				decode_getfh_maxsz)
++				decode_restorefh_maxsz + \
++				decode_getattr_maxsz)
+ #define NFS4_enc_pathconf_sz	(compound_encode_hdr_maxsz + \
+ 				encode_putfh_maxsz + \
+ 				encode_getattr_maxsz)
+@@ -602,10 +632,10 @@ static int encode_close(struct xdr_strea
+ {
+ 	uint32_t *p;
+ 
+-	RESERVE_SPACE(8+sizeof(arg->stateid.data));
++	RESERVE_SPACE(8+sizeof(arg->stateid->data));
+ 	WRITE32(OP_CLOSE);
+-	WRITE32(arg->seqid);
+-	WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
++	WRITE32(arg->seqid->sequence->counter);
++	WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
+ 	
+ 	return 0;
+ }
+@@ -729,22 +759,18 @@ static int encode_lock(struct xdr_stream
+ 	WRITE64(arg->length);
+ 	WRITE32(opargs->new_lock_owner);
+ 	if (opargs->new_lock_owner){
+-		struct nfs_open_to_lock *ol = opargs->u.open_lock;
+-
+ 		RESERVE_SPACE(40);
+-		WRITE32(ol->open_seqid);
+-		WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid));
+-		WRITE32(ol->lock_seqid);
+-		WRITE64(ol->lock_owner.clientid);
++		WRITE32(opargs->open_seqid->sequence->counter);
++		WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data));
++		WRITE32(opargs->lock_seqid->sequence->counter);
++		WRITE64(opargs->lock_owner.clientid);
+ 		WRITE32(4);
+-		WRITE32(ol->lock_owner.id);
++		WRITE32(opargs->lock_owner.id);
+ 	}
+ 	else {
+-		struct nfs_exist_lock *el = opargs->u.exist_lock;
+-
+ 		RESERVE_SPACE(20);
+-		WRITEMEM(&el->stateid, sizeof(el->stateid));
+-		WRITE32(el->seqid);
++		WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data));
++		WRITE32(opargs->lock_seqid->sequence->counter);
+ 	}
+ 
+ 	return 0;
+@@ -775,8 +801,8 @@ static int encode_locku(struct xdr_strea
+ 	RESERVE_SPACE(44);
+ 	WRITE32(OP_LOCKU);
+ 	WRITE32(arg->type);
+-	WRITE32(opargs->seqid);
+-	WRITEMEM(&opargs->stateid, sizeof(opargs->stateid));
++	WRITE32(opargs->seqid->sequence->counter);
++	WRITEMEM(opargs->stateid->data, sizeof(opargs->stateid->data));
+ 	WRITE64(arg->offset);
+ 	WRITE64(arg->length);
+ 
+@@ -826,7 +852,7 @@ static inline void encode_openhdr(struct
+  */
+ 	RESERVE_SPACE(8);
+ 	WRITE32(OP_OPEN);
+-	WRITE32(arg->seqid);
++	WRITE32(arg->seqid->sequence->counter);
+ 	encode_share_access(xdr, arg->open_flags);
+ 	RESERVE_SPACE(16);
+ 	WRITE64(arg->clientid);
+@@ -941,7 +967,7 @@ static int encode_open_confirm(struct xd
+ 	RESERVE_SPACE(8+sizeof(arg->stateid.data));
+ 	WRITE32(OP_OPEN_CONFIRM);
+ 	WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
+-	WRITE32(arg->seqid);
++	WRITE32(arg->seqid->sequence->counter);
+ 
+ 	return 0;
+ }
+@@ -950,10 +976,10 @@ static int encode_open_downgrade(struct 
+ {
+ 	uint32_t *p;
+ 
+-	RESERVE_SPACE(8+sizeof(arg->stateid.data));
++	RESERVE_SPACE(8+sizeof(arg->stateid->data));
+ 	WRITE32(OP_OPEN_DOWNGRADE);
+-	WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
+-	WRITE32(arg->seqid);
++	WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
++	WRITE32(arg->seqid->sequence->counter);
+ 	encode_share_access(xdr, arg->open_flags);
+ 	return 0;
+ }
+@@ -1117,6 +1143,17 @@ static int encode_renew(struct xdr_strea
+ }
+ 
+ static int
++encode_restorefh(struct xdr_stream *xdr)
++{
++	uint32_t *p;
++
++	RESERVE_SPACE(4);
++	WRITE32(OP_RESTOREFH);
++
++	return 0;
++}
++
++static int
+ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
+ {
+ 	uint32_t *p;
+@@ -1296,14 +1333,18 @@ static int nfs4_xdr_enc_remove(struct rp
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr = {
+-		.nops = 2,
++		.nops = 3,
+ 	};
+ 	int status;
+ 
+ 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ 	encode_compound_hdr(&xdr, &hdr);
+-	if ((status = encode_putfh(&xdr, args->fh)) == 0)
+-		status = encode_remove(&xdr, args->name);
++	if ((status = encode_putfh(&xdr, args->fh)) != 0)
++		goto out;
++	if ((status = encode_remove(&xdr, args->name)) != 0)
++		goto out;
++	status = encode_getfattr(&xdr, args->bitmask);
++out:
+ 	return status;
+ }
+ 
+@@ -1314,7 +1355,7 @@ static int nfs4_xdr_enc_rename(struct rp
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr = {
+-		.nops = 4,
++		.nops = 7,
+ 	};
+ 	int status;
+ 
+@@ -1326,7 +1367,13 @@ static int nfs4_xdr_enc_rename(struct rp
+ 		goto out;
+ 	if ((status = encode_putfh(&xdr, args->new_dir)) != 0)
+ 		goto out;
+-	status = encode_rename(&xdr, args->old_name, args->new_name);
++	if ((status = encode_rename(&xdr, args->old_name, args->new_name)) != 0)
++		goto out;
++	if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
++		goto out;
++	if ((status = encode_restorefh(&xdr)) != 0)
++		goto out;
++	status = encode_getfattr(&xdr, args->bitmask);
+ out:
+ 	return status;
+ }
+@@ -1338,7 +1385,7 @@ static int nfs4_xdr_enc_link(struct rpc_
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr = {
+-		.nops = 4,
++		.nops = 7,
+ 	};
+ 	int status;
+ 
+@@ -1350,7 +1397,13 @@ static int nfs4_xdr_enc_link(struct rpc_
+ 		goto out;
+ 	if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
+ 		goto out;
+-	status = encode_link(&xdr, args->name);
++	if ((status = encode_link(&xdr, args->name)) != 0)
++		goto out;
++	if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
++		goto out;
++	if ((status = encode_restorefh(&xdr)) != 0)
++		goto out;
++	status = encode_getfattr(&xdr, args->bitmask);
+ out:
+ 	return status;
+ }
+@@ -1362,7 +1415,7 @@ static int nfs4_xdr_enc_create(struct rp
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr = {
+-		.nops = 4,
++		.nops = 7,
+ 	};
+ 	int status;
+ 
+@@ -1370,10 +1423,16 @@ static int nfs4_xdr_enc_create(struct rp
+ 	encode_compound_hdr(&xdr, &hdr);
+ 	if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
+ 		goto out;
++	if ((status = encode_savefh(&xdr)) != 0)
++		goto out;
+ 	if ((status = encode_create(&xdr, args)) != 0)
+ 		goto out;
+ 	if ((status = encode_getfh(&xdr)) != 0)
+ 		goto out;
++	if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
++		goto out;
++	if ((status = encode_restorefh(&xdr)) != 0)
++		goto out;
+ 	status = encode_getfattr(&xdr, args->bitmask);
+ out:
+ 	return status;
+@@ -1412,7 +1471,7 @@ static int nfs4_xdr_enc_close(struct rpc
+ {
+         struct xdr_stream xdr;
+         struct compound_hdr hdr = {
+-                .nops   = 2,
++                .nops   = 3,
+         };
+         int status;
+ 
+@@ -1422,6 +1481,9 @@ static int nfs4_xdr_enc_close(struct rpc
+         if(status)
+                 goto out;
+         status = encode_close(&xdr, args);
++	if (status != 0)
++		goto out;
++	status = encode_getfattr(&xdr, args->bitmask);
+ out:
+         return status;
+ }
+@@ -1433,15 +1495,21 @@ static int nfs4_xdr_enc_open(struct rpc_
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr = {
+-		.nops = 4,
++		.nops = 7,
+ 	};
+ 	int status;
+ 
++	status = nfs_wait_on_sequence(args->seqid, req->rq_task);
++	if (status != 0)
++		goto out;
+ 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ 	encode_compound_hdr(&xdr, &hdr);
+ 	status = encode_putfh(&xdr, args->fh);
+ 	if (status)
+ 		goto out;
++	status = encode_savefh(&xdr);
++	if (status)
++		goto out;
+ 	status = encode_open(&xdr, args);
+ 	if (status)
+ 		goto out;
+@@ -1449,6 +1517,12 @@ static int nfs4_xdr_enc_open(struct rpc_
+ 	if (status)
+ 		goto out;
+ 	status = encode_getfattr(&xdr, args->bitmask);
++	if (status)
++		goto out;
++	status = encode_restorefh(&xdr);
++	if (status)
++		goto out;
++	status = encode_getfattr(&xdr, args->bitmask);
+ out:
+ 	return status;
+ }
+@@ -1464,6 +1538,9 @@ static int nfs4_xdr_enc_open_confirm(str
+ 	};
+ 	int status;
+ 
++	status = nfs_wait_on_sequence(args->seqid, req->rq_task);
++	if (status != 0)
++		goto out;
+ 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ 	encode_compound_hdr(&xdr, &hdr);
+ 	status = encode_putfh(&xdr, args->fh);
+@@ -1485,6 +1562,9 @@ static int nfs4_xdr_enc_open_noattr(stru
+ 	};
+ 	int status;
+ 
++	status = nfs_wait_on_sequence(args->seqid, req->rq_task);
++	if (status != 0)
++		goto out;
+ 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ 	encode_compound_hdr(&xdr, &hdr);
+ 	status = encode_putfh(&xdr, args->fh);
+@@ -1502,7 +1582,7 @@ static int nfs4_xdr_enc_open_downgrade(s
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr = {
+-		.nops	= 2,
++		.nops	= 3,
+ 	};
+ 	int status;
+ 
+@@ -1512,6 +1592,9 @@ static int nfs4_xdr_enc_open_downgrade(s
+ 	if (status)
+ 		goto out;
+ 	status = encode_open_downgrade(&xdr, args);
++	if (status != 0)
++		goto out;
++	status = encode_getfattr(&xdr, args->bitmask);
+ out:
+ 	return status;
+ }
+@@ -1525,8 +1608,15 @@ static int nfs4_xdr_enc_lock(struct rpc_
+ 	struct compound_hdr hdr = {
+ 		.nops   = 2,
+ 	};
++	struct nfs_lock_opargs *opargs = args->u.lock;
+ 	int status;
+ 
++	status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task);
++	if (status != 0)
++		goto out;
++	/* Do we need to do an open_to_lock_owner? */
++	if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)
++		opargs->new_lock_owner = 0;
+ 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ 	encode_compound_hdr(&xdr, &hdr);
+ 	status = encode_putfh(&xdr, args->fh);
+@@ -1713,7 +1803,7 @@ static int nfs4_xdr_enc_write(struct rpc
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr = {
+-		.nops = 2,
++		.nops = 3,
+ 	};
+ 	int status;
+ 
+@@ -1723,6 +1813,9 @@ static int nfs4_xdr_enc_write(struct rpc
+ 	if (status)
+ 		goto out;
+ 	status = encode_write(&xdr, args);
++	if (status)
++		goto out;
++	status = encode_getfattr(&xdr, args->bitmask);
+ out:
+ 	return status;
+ }
+@@ -1734,7 +1827,7 @@ static int nfs4_xdr_enc_commit(struct rp
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr = {
+-		.nops = 2,
++		.nops = 3,
+ 	};
+ 	int status;
+ 
+@@ -1744,6 +1837,9 @@ static int nfs4_xdr_enc_commit(struct rp
+ 	if (status)
+ 		goto out;
+ 	status = encode_commit(&xdr, args);
++	if (status)
++		goto out;
++	status = encode_getfattr(&xdr, args->bitmask);
+ out:
+ 	return status;
+ }
+@@ -2670,8 +2766,7 @@ static int decode_server_caps(struct xdr
+ 		goto xdr_error;
+ 	status = verify_attr_len(xdr, savep, attrlen);
+ xdr_error:
+-	if (status != 0)
+-		printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
++	dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
+ 	return status;
+ }
+ 	
+@@ -2704,8 +2799,7 @@ static int decode_statfs(struct xdr_stre
+ 
+ 	status = verify_attr_len(xdr, savep, attrlen);
+ xdr_error:
+-	if (status != 0)
+-		printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
++	dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
+ 	return status;
+ }
+ 
+@@ -2730,8 +2824,7 @@ static int decode_pathconf(struct xdr_st
+ 
+ 	status = verify_attr_len(xdr, savep, attrlen);
+ xdr_error:
+-	if (status != 0)
+-		printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
++	dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
+ 	return status;
+ }
+ 
+@@ -2787,13 +2880,10 @@ static int decode_getfattr(struct xdr_st
+ 		goto xdr_error;
+ 	if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0)
+ 		goto xdr_error;
+-	if ((status = verify_attr_len(xdr, savep, attrlen)) == 0) {
++	if ((status = verify_attr_len(xdr, savep, attrlen)) == 0)
+ 		fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4;
+-		fattr->timestamp = jiffies;
+-	}
+ xdr_error:
+-	if (status != 0)
+-		printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
++	dprintk("%s: xdr returned %d\n", __FUNCTION__, -status);
+ 	return status;
+ }
+ 
+@@ -2826,8 +2916,7 @@ static int decode_fsinfo(struct xdr_stre
+ 
+ 	status = verify_attr_len(xdr, savep, attrlen);
+ xdr_error:
+-	if (status != 0)
+-		printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
++	dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
+ 	return status;
+ }
+ 
+@@ -2890,8 +2979,8 @@ static int decode_lock(struct xdr_stream
+ 
+ 	status = decode_op_hdr(xdr, OP_LOCK);
+ 	if (status == 0) {
+-		READ_BUF(sizeof(nfs4_stateid));
+-		COPYMEM(&res->u.stateid, sizeof(res->u.stateid));
++		READ_BUF(sizeof(res->u.stateid.data));
++		COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
+ 	} else if (status == -NFS4ERR_DENIED)
+ 		return decode_lock_denied(xdr, &res->u.denied);
+ 	return status;
+@@ -2913,8 +3002,8 @@ static int decode_locku(struct xdr_strea
+ 
+ 	status = decode_op_hdr(xdr, OP_LOCKU);
+ 	if (status == 0) {
+-		READ_BUF(sizeof(nfs4_stateid));
+-		COPYMEM(&res->u.stateid, sizeof(res->u.stateid));
++		READ_BUF(sizeof(res->u.stateid.data));
++		COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
+ 	}
+ 	return status;
+ }
+@@ -2994,7 +3083,7 @@ static int decode_open(struct xdr_stream
+         p += bmlen;
+ 	return decode_delegation(xdr, res);
+ xdr_error:
+-	printk(KERN_NOTICE "%s: xdr error!\n", __FUNCTION__);
++	dprintk("%s: Bitmap too large! Length = %u\n", __FUNCTION__, bmlen);
+ 	return -EIO;
+ }
+ 
+@@ -3208,6 +3297,12 @@ static int decode_renew(struct xdr_strea
+ 	return decode_op_hdr(xdr, OP_RENEW);
+ }
+ 
++static int
++decode_restorefh(struct xdr_stream *xdr)
++{
++	return decode_op_hdr(xdr, OP_RESTOREFH);
++}
++
+ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
+ 		size_t *acl_len)
+ {
+@@ -3243,7 +3338,8 @@ static int decode_getacl(struct xdr_stre
+ 		if (attrlen <= *acl_len)
+ 			xdr_read_pages(xdr, attrlen);
+ 		*acl_len = attrlen;
+-	}
++	} else
++		status = -EOPNOTSUPP;
+ 
+ out:
+ 	return status;
+@@ -3352,6 +3448,9 @@ static int nfs4_xdr_dec_open_downgrade(s
+         if (status)
+                 goto out;
+         status = decode_open_downgrade(&xdr, res);
++	if (status != 0)
++		goto out;
++	decode_getfattr(&xdr, res->fattr, res->server);
+ out:
+         return status;
+ }
+@@ -3424,7 +3523,7 @@ out:
+ /*
+  * Decode REMOVE response
+  */
+-static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo)
++static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_remove_res *res)
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr;
+@@ -3433,8 +3532,11 @@ static int nfs4_xdr_dec_remove(struct rp
+ 	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ 	if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ 		goto out;
+-	if ((status = decode_putfh(&xdr)) == 0)
+-		status = decode_remove(&xdr, cinfo);
++	if ((status = decode_putfh(&xdr)) != 0)
++		goto out;
++	if ((status = decode_remove(&xdr, &res->cinfo)) != 0)
++		goto out;
++	decode_getfattr(&xdr, res->dir_attr, res->server);
+ out:
+ 	return status;
+ }
+@@ -3457,7 +3559,14 @@ static int nfs4_xdr_dec_rename(struct rp
+ 		goto out;
+ 	if ((status = decode_putfh(&xdr)) != 0)
+ 		goto out;
+-	status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo);
++	if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0)
++		goto out;
++	/* Current FH is target directory */
++	if (decode_getfattr(&xdr, res->new_fattr, res->server) != 0)
++		goto out;
++	if ((status = decode_restorefh(&xdr)) != 0)
++		goto out;
++	decode_getfattr(&xdr, res->old_fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -3465,7 +3574,7 @@ out:
+ /*
+  * Decode LINK response
+  */
+-static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo)
++static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_link_res *res)
+ {
+ 	struct xdr_stream xdr;
+ 	struct compound_hdr hdr;
+@@ -3480,7 +3589,17 @@ static int nfs4_xdr_dec_link(struct rpc_
+ 		goto out;
+ 	if ((status = decode_putfh(&xdr)) != 0)
+ 		goto out;
+-	status = decode_link(&xdr, cinfo);
++	if ((status = decode_link(&xdr, &res->cinfo)) != 0)
++		goto out;
++	/*
++	 * Note order: OP_LINK leaves the directory as the current
++	 *             filehandle.
++	 */
++	if (decode_getfattr(&xdr, res->dir_attr, res->server) != 0)
++		goto out;
++	if ((status = decode_restorefh(&xdr)) != 0)
++		goto out;
++	decode_getfattr(&xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -3499,13 +3618,17 @@ static int nfs4_xdr_dec_create(struct rp
+ 		goto out;
+ 	if ((status = decode_putfh(&xdr)) != 0)
+ 		goto out;
++	if ((status = decode_savefh(&xdr)) != 0)
++		goto out;
+ 	if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0)
+ 		goto out;
+ 	if ((status = decode_getfh(&xdr, res->fh)) != 0)
+ 		goto out;
+-	status = decode_getfattr(&xdr, res->fattr, res->server);
+-	if (status == NFS4ERR_DELAY)
+-		status = 0;
++	if (decode_getfattr(&xdr, res->fattr, res->server) != 0)
++		goto out;
++	if ((status = decode_restorefh(&xdr)) != 0)
++		goto out;
++	decode_getfattr(&xdr, res->dir_fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -3623,6 +3746,15 @@ static int nfs4_xdr_dec_close(struct rpc
+         if (status)
+                 goto out;
+         status = decode_close(&xdr, res);
++	if (status != 0)
++		goto out;
++	/*
++	 * Note: Server may do delete on close for this file
++	 * 	in which case the getattr call will fail with
++	 * 	an ESTALE error. Shouldn't be a problem,
++	 * 	though, since fattr->valid will remain unset.
++	 */
++	decode_getfattr(&xdr, res->fattr, res->server);
+ out:
+         return status;
+ }
+@@ -3643,15 +3775,20 @@ static int nfs4_xdr_dec_open(struct rpc_
+         status = decode_putfh(&xdr);
+         if (status)
+                 goto out;
++        status = decode_savefh(&xdr);
++	if (status)
++		goto out;
+         status = decode_open(&xdr, res);
+         if (status)
+                 goto out;
+ 	status = decode_getfh(&xdr, &res->fh);
+         if (status)
+ 		goto out;
+-	status = decode_getfattr(&xdr, res->f_attr, res->server);
+-	if (status == NFS4ERR_DELAY)
+-		status = 0;
++	if (decode_getfattr(&xdr, res->f_attr, res->server) != 0)
++		goto out;
++	if ((status = decode_restorefh(&xdr)) != 0)
++		goto out;
++	decode_getfattr(&xdr, res->dir_attr, res->server);
+ out:
+         return status;
+ }
+@@ -3869,6 +4006,9 @@ static int nfs4_xdr_dec_write(struct rpc
+ 	if (status)
+ 		goto out;
+ 	status = decode_write(&xdr, res);
++	if (status)
++		goto out;
++	decode_getfattr(&xdr, res->fattr, res->server);
+ 	if (!status)
+ 		status = res->count;
+ out:
+@@ -3892,6 +4032,9 @@ static int nfs4_xdr_dec_commit(struct rp
+ 	if (status)
+ 		goto out;
+ 	status = decode_commit(&xdr, res);
++	if (status)
++		goto out;
++	decode_getfattr(&xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
+--- a/fs/nfs/proc.c
++++ b/fs/nfs/proc.c
+@@ -61,7 +61,7 @@ nfs_proc_get_root(struct nfs_server *ser
+ 	int status;
+ 
+ 	dprintk("%s: call getattr\n", __FUNCTION__);
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call(server->client_sys, NFSPROC_GETATTR, fhandle, fattr, 0);
+ 	dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
+ 	if (status)
+@@ -93,7 +93,7 @@ nfs_proc_getattr(struct nfs_server *serv
+ 	int	status;
+ 
+ 	dprintk("NFS call  getattr\n");
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call(server->client, NFSPROC_GETATTR,
+ 				fhandle, fattr, 0);
+ 	dprintk("NFS reply getattr: %d\n", status);
+@@ -112,7 +112,7 @@ nfs_proc_setattr(struct dentry *dentry, 
+ 	int	status;
+ 
+ 	dprintk("NFS call  setattr\n");
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0);
+ 	if (status == 0)
+ 		nfs_setattr_update_inode(inode, sattr);
+@@ -136,7 +136,7 @@ nfs_proc_lookup(struct inode *dir, struc
+ 	int			status;
+ 
+ 	dprintk("NFS call  lookup %s\n", name->name);
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call(NFS_CLIENT(dir), NFSPROC_LOOKUP, &arg, &res, 0);
+ 	dprintk("NFS reply lookup: %d\n", status);
+ 	return status;
+@@ -174,7 +174,7 @@ static int nfs_proc_read(struct nfs_read
+ 
+ 	dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
+ 			(long long) rdata->args.offset);
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+ 	if (status >= 0) {
+ 		nfs_refresh_inode(inode, fattr);
+@@ -203,10 +203,10 @@ static int nfs_proc_write(struct nfs_wri
+ 
+ 	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
+ 			(long long) wdata->args.offset);
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+ 	if (status >= 0) {
+-		nfs_refresh_inode(inode, fattr);
++		nfs_post_op_update_inode(inode, fattr);
+ 		wdata->res.count = wdata->args.count;
+ 		wdata->verf.committed = NFS_FILE_SYNC;
+ 	}
+@@ -216,7 +216,7 @@ static int nfs_proc_write(struct nfs_wri
+ 
+ static int
+ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+-		int flags)
++		int flags, struct nameidata *nd)
+ {
+ 	struct nfs_fh		fhandle;
+ 	struct nfs_fattr	fattr;
+@@ -232,7 +232,7 @@ nfs_proc_create(struct inode *dir, struc
+ 	};
+ 	int			status;
+ 
+-	fattr.valid = 0;
++	nfs_fattr_init(&fattr);
+ 	dprintk("NFS call  create %s\n", dentry->d_name.name);
+ 	status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
+ 	if (status == 0)
+@@ -273,12 +273,13 @@ nfs_proc_mknod(struct inode *dir, struct
+ 		sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */
+ 	}
+ 
+-	fattr.valid = 0;
++	nfs_fattr_init(&fattr);
+ 	status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
++	nfs_mark_for_revalidate(dir);
+ 
+ 	if (status == -EINVAL && S_ISFIFO(mode)) {
+ 		sattr->ia_mode = mode;
+-		fattr.valid = 0;
++		nfs_fattr_init(&fattr);
+ 		status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
+ 	}
+ 	if (status == 0)
+@@ -305,6 +306,7 @@ nfs_proc_remove(struct inode *dir, struc
+ 
+ 	dprintk("NFS call  remove %s\n", name->name);
+ 	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
++	nfs_mark_for_revalidate(dir);
+ 
+ 	dprintk("NFS reply remove: %d\n", status);
+ 	return status;
+@@ -331,8 +333,10 @@ nfs_proc_unlink_done(struct dentry *dir,
+ {
+ 	struct rpc_message *msg = &task->tk_msg;
+ 	
+-	if (msg->rpc_argp)
++	if (msg->rpc_argp) {
++		nfs_mark_for_revalidate(dir->d_inode);
+ 		kfree(msg->rpc_argp);
++	}
+ 	return 0;
+ }
+ 
+@@ -352,6 +356,8 @@ nfs_proc_rename(struct inode *old_dir, s
+ 
+ 	dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
+ 	status = rpc_call(NFS_CLIENT(old_dir), NFSPROC_RENAME, &arg, NULL, 0);
++	nfs_mark_for_revalidate(old_dir);
++	nfs_mark_for_revalidate(new_dir);
+ 	dprintk("NFS reply rename: %d\n", status);
+ 	return status;
+ }
+@@ -369,6 +375,7 @@ nfs_proc_link(struct inode *inode, struc
+ 
+ 	dprintk("NFS call  link %s\n", name->name);
+ 	status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0);
++	nfs_mark_for_revalidate(dir);
+ 	dprintk("NFS reply link: %d\n", status);
+ 	return status;
+ }
+@@ -391,9 +398,10 @@ nfs_proc_symlink(struct inode *dir, stru
+ 	if (path->len > NFS2_MAXPATHLEN)
+ 		return -ENAMETOOLONG;
+ 	dprintk("NFS call  symlink %s -> %s\n", name->name, path->name);
+-	fattr->valid = 0;
++	nfs_fattr_init(fattr);
+ 	fhandle->size = 0;
+ 	status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0);
++	nfs_mark_for_revalidate(dir);
+ 	dprintk("NFS reply symlink: %d\n", status);
+ 	return status;
+ }
+@@ -416,8 +424,9 @@ nfs_proc_mkdir(struct inode *dir, struct
+ 	int			status;
+ 
+ 	dprintk("NFS call  mkdir %s\n", dentry->d_name.name);
+-	fattr.valid = 0;
++	nfs_fattr_init(&fattr);
+ 	status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0);
++	nfs_mark_for_revalidate(dir);
+ 	if (status == 0)
+ 		status = nfs_instantiate(dentry, &fhandle, &fattr);
+ 	dprintk("NFS reply mkdir: %d\n", status);
+@@ -436,6 +445,7 @@ nfs_proc_rmdir(struct inode *dir, struct
+ 
+ 	dprintk("NFS call  rmdir %s\n", name->name);
+ 	status = rpc_call(NFS_CLIENT(dir), NFSPROC_RMDIR, &arg, NULL, 0);
++	nfs_mark_for_revalidate(dir);
+ 	dprintk("NFS reply rmdir: %d\n", status);
+ 	return status;
+ }
+@@ -484,7 +494,7 @@ nfs_proc_statfs(struct nfs_server *serve
+ 	int	status;
+ 
+ 	dprintk("NFS call  statfs\n");
+-	stat->fattr->valid = 0;
++	nfs_fattr_init(stat->fattr);
+ 	status = rpc_call(server->client, NFSPROC_STATFS, fhandle, &fsinfo, 0);
+ 	dprintk("NFS reply statfs: %d\n", status);
+ 	if (status)
+@@ -507,7 +517,7 @@ nfs_proc_fsinfo(struct nfs_server *serve
+ 	int	status;
+ 
+ 	dprintk("NFS call  fsinfo\n");
+-	info->fattr->valid = 0;
++	nfs_fattr_init(info->fattr);
+ 	status = rpc_call(server->client, NFSPROC_STATFS, fhandle, &fsinfo, 0);
+ 	dprintk("NFS reply fsinfo: %d\n", status);
+ 	if (status)
+@@ -579,7 +589,7 @@ nfs_write_done(struct rpc_task *task)
+ 	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+ 
+ 	if (task->tk_status >= 0)
+-		nfs_refresh_inode(data->inode, data->res.fattr);
++		nfs_post_op_update_inode(data->inode, data->res.fattr);
+ 	nfs_writeback_done(task);
+ }
+ 
+diff --git a/fs/nfs/read.c b/fs/nfs/read.c
+--- a/fs/nfs/read.c
++++ b/fs/nfs/read.c
+@@ -215,6 +215,7 @@ static void nfs_read_rpcsetup(struct nfs
+ 	data->res.fattr   = &data->fattr;
+ 	data->res.count   = count;
+ 	data->res.eof     = 0;
++	nfs_fattr_init(&data->fattr);
+ 
+ 	NFS_PROTO(inode)->read_setup(data);
+ 
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -870,6 +870,7 @@ static void nfs_write_rpcsetup(struct nf
+ 	data->res.fattr   = &data->fattr;
+ 	data->res.count   = count;
+ 	data->res.verf    = &data->verf;
++	nfs_fattr_init(&data->fattr);
+ 
+ 	NFS_PROTO(inode)->write_setup(data, how);
+ 
+@@ -1237,6 +1238,7 @@ static void nfs_commit_rpcsetup(struct l
+ 	data->res.count   = 0;
+ 	data->res.fattr   = &data->fattr;
+ 	data->res.verf    = &data->verf;
++	nfs_fattr_init(&data->fattr);
+ 	
+ 	NFS_PROTO(inode)->commit_setup(data, how);
+ 
+diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
+--- a/fs/ntfs/ChangeLog
++++ b/fs/ntfs/ChangeLog
+@@ -1,18 +1,15 @@
+ ToDo/Notes:
+ 	- Find and fix bugs.
+-	- In between ntfs_prepare/commit_write, need exclusion between
+-	  simultaneous file extensions.  This is given to us by holding i_sem
+-	  on the inode.  The only places in the kernel when a file is resized
+-	  are prepare/commit write and truncate for both of which i_sem is
+-	  held.  Just have to be careful in readpage/writepage and all other
+-	  helpers not running under i_sem that we play nice...
+-	  Also need to be careful with initialized_size extention in
+-	  ntfs_prepare_write. Basically, just be _very_ careful in this code...
+-	  UPDATE: The only things that need to be checked are read/writepage
+-	  which do not hold i_sem.  Note writepage cannot change i_size but it
+-	  needs to cope with a concurrent i_size change, just like readpage.
+-	  Also both need to cope with concurrent changes to the other sizes,
+-	  i.e. initialized/allocated/compressed size, as well.
++	- The only places in the kernel where a file is resized are
++	  ntfs_file_write*() and ntfs_truncate() for both of which i_sem is
++	  held.  Just have to be careful in read-/writepage and other helpers
++	  not running under i_sem that we play nice...  Also need to be careful
++	  with initialized_size extension in ntfs_file_write*() and writepage.
++	  UPDATE: The only things that need to be checked are the compressed
++	  write and the other attribute resize/write cases like index
++	  attributes, etc.  For now none of these are implemented so are safe.
++	- Implement filling in of holes in aops.c::ntfs_writepage() and its
++	  helpers.
+ 	- Implement mft.c::sync_mft_mirror_umount().  We currently will just
+ 	  leave the volume dirty on umount if the final iput(vol->mft_ino)
+ 	  causes a write of any mirrored mft records due to the mft mirror
+@@ -22,6 +19,68 @@ ToDo/Notes:
+ 	- Enable the code for setting the NT4 compatibility flag when we start
+ 	  making NTFS 1.2 specific modifications.
+ 
++2.1.25 - (Almost) fully implement write(2) and truncate(2).
++
++	- Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and
++	  {__,}ntfs_cluster_free() to also take an optional attribute search
++	  context as argument.  This allows calling these functions with the
++	  mft record mapped.  Update all callers.
++	- Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock()
++	  error handling by passing in the active search context when calling
++	  ntfs_cluster_free().
++	- Change ntfs_cluster_alloc() to take an extra boolean parameter
++	  specifying whether the cluster are being allocated to extend an
++	  attribute or to fill a hole.
++	- Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc()
++	  with @is_extension set to TRUE and remove the runlist terminator
++	  fixup code as this is now done by ntfs_cluster_alloc().
++	- Change ntfs_attr_make_non_resident to take the attribute value size
++	  as an extra parameter.  This is needed since we need to know the size
++	  before we can map the mft record and our callers always know it.  The
++	  reason we cannot simply read the size from the vfs inode i_size is
++	  that this is not necessarily uptodate.  This happens when
++	  ntfs_attr_make_non_resident() is called in the ->truncate call path.
++	- Fix ntfs_attr_make_non_resident() to update the vfs inode i_blocks
++	  which is zero for a resident attribute but should no longer be zero
++	  once the attribute is non-resident as it then has real clusters
++	  allocated.
++	- Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to
++	  extend the allocation of an attributes.  Optionally, the data size,
++	  but not the initialized size can be extended, too.
++	- Implement fs/ntfs/inode.[hc]::ntfs_truncate().  It only supports
++	  uncompressed and unencrypted files and it never creates sparse files
++	  at least for the moment (making a file sparse requires us to modify
++	  its directory entries and we do not support directory operations at
++	  the moment).  Also, support for highly fragmented files, i.e. ones
++	  whose data attribute is split across multiple extents, is severly
++	  limited.  When such a case is encountered, EOPNOTSUPP is returned.
++	- Enable ATTR_SIZE attribute changes in ntfs_setattr().  This completes
++	  the initial implementation of file truncation.  Now both open(2)ing
++	  a file with the O_TRUNC flag and the {,f}truncate(2) system calls
++	  will resize a file appropriately.  The limitations are that only
++	  uncompressed and unencrypted files are supported.  Also, there is
++	  only very limited support for highly fragmented files (the ones whose
++	  $DATA attribute is split into multiple attribute extents).
++	- In attrib.c::ntfs_attr_set() call balance_dirty_pages_ratelimited()
++	  and cond_resched() in the main loop as we could be dirtying a lot of
++	  pages and this ensures we play nice with the VM and the system as a
++	  whole.
++	- Implement file operations ->write, ->aio_write, ->writev for regular
++	  files.  This replaces the old use of generic_file_write(), et al and
++	  the address space operations ->prepare_write and ->commit_write.
++	  This means that both sparse and non-sparse (unencrypted and
++	  uncompressed) files can now be extended using the normal write(2)
++	  code path.  There are two limitations at present and these are that
++	  we never create sparse files and that we only have limited support
++	  for highly fragmented files, i.e. ones whose data attribute is split
++	  across multiple extents.   When such a case is encountered,
++	  EOPNOTSUPP is returned.
++	- $EA attributes can be both resident and non-resident.
++	- Use %z for size_t to fix compilation warnings.  (Andrew Morton)
++	- Fix compilation warnings with gcc-4.0.2 on SUSE 10.0.
++	- Document extended attribute ($EA) NEED_EA flag.  (Based on libntfs
++	  patch by Yura Pakhuchiy.)
++
+ 2.1.24 - Lots of bug fixes and support more clean journal states.
+ 
+ 	- Support journals ($LogFile) which have been modified by chkdsk.  This
+diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
+--- a/fs/ntfs/Makefile
++++ b/fs/ntfs/Makefile
+@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o c
+ 	     index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
+ 	     unistr.o upcase.o
+ 
+-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24\"
++EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25\"
+ 
+ ifeq ($(CONFIG_NTFS_DEBUG),y)
+ EXTRA_CFLAGS += -DDEBUG
+diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
+--- a/fs/ntfs/aops.c
++++ b/fs/ntfs/aops.c
+@@ -1391,8 +1391,7 @@ retry_writepage:
+ 		if (NInoEncrypted(ni)) {
+ 			unlock_page(page);
+ 			BUG_ON(ni->type != AT_DATA);
+-			ntfs_debug("Denying write access to encrypted "
+-					"file.");
++			ntfs_debug("Denying write access to encrypted file.");
+ 			return -EACCES;
+ 		}
+ 		/* Compressed data streams are handled in compress.c. */
+@@ -1508,8 +1507,8 @@ retry_writepage:
+ 	/* Zero out of bounds area in the page cache page. */
+ 	memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
+ 	kunmap_atomic(kaddr, KM_USER0);
+-	flush_dcache_mft_record_page(ctx->ntfs_ino);
+ 	flush_dcache_page(page);
++	flush_dcache_mft_record_page(ctx->ntfs_ino);
+ 	/* We are done with the page. */
+ 	end_page_writeback(page);
+ 	/* Finally, mark the mft record dirty, so it gets written back. */
+@@ -1542,830 +1541,6 @@ err_out:
+ 	return err;
+ }
+ 
+-/**
+- * ntfs_prepare_nonresident_write -
+- *
+- */
+-static int ntfs_prepare_nonresident_write(struct page *page,
+-		unsigned from, unsigned to)
+-{
+-	VCN vcn;
+-	LCN lcn;
+-	s64 initialized_size;
+-	loff_t i_size;
+-	sector_t block, ablock, iblock;
+-	struct inode *vi;
+-	ntfs_inode *ni;
+-	ntfs_volume *vol;
+-	runlist_element *rl;
+-	struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
+-	unsigned long flags;
+-	unsigned int vcn_ofs, block_start, block_end, blocksize;
+-	int err;
+-	BOOL is_retry;
+-	unsigned char blocksize_bits;
+-
+-	vi = page->mapping->host;
+-	ni = NTFS_I(vi);
+-	vol = ni->vol;
+-
+-	ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
+-			"0x%lx, from = %u, to = %u.", ni->mft_no, ni->type,
+-			page->index, from, to);
+-
+-	BUG_ON(!NInoNonResident(ni));
+-
+-	blocksize_bits = vi->i_blkbits;
+-	blocksize = 1 << blocksize_bits;
+-
+-	/*
+-	 * create_empty_buffers() will create uptodate/dirty buffers if the
+-	 * page is uptodate/dirty.
+-	 */
+-	if (!page_has_buffers(page))
+-		create_empty_buffers(page, blocksize, 0);
+-	bh = head = page_buffers(page);
+-	if (unlikely(!bh))
+-		return -ENOMEM;
+-
+-	/* The first block in the page. */
+-	block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
+-
+-	read_lock_irqsave(&ni->size_lock, flags);
+-	/*
+-	 * The first out of bounds block for the allocated size.  No need to
+-	 * round up as allocated_size is in multiples of cluster size and the
+-	 * minimum cluster size is 512 bytes, which is equal to the smallest
+-	 * blocksize.
+-	 */
+-	ablock = ni->allocated_size >> blocksize_bits;
+-	i_size = i_size_read(vi);
+-	initialized_size = ni->initialized_size;
+-	read_unlock_irqrestore(&ni->size_lock, flags);
+-
+-	/* The last (fully or partially) initialized block. */
+-	iblock = initialized_size >> blocksize_bits;
+-
+-	/* Loop through all the buffers in the page. */
+-	block_start = 0;
+-	rl = NULL;
+-	err = 0;
+-	do {
+-		block_end = block_start + blocksize;
+-		/*
+-		 * If buffer @bh is outside the write, just mark it uptodate
+-		 * if the page is uptodate and continue with the next buffer.
+-		 */
+-		if (block_end <= from || block_start >= to) {
+-			if (PageUptodate(page)) {
+-				if (!buffer_uptodate(bh))
+-					set_buffer_uptodate(bh);
+-			}
+-			continue;
+-		}
+-		/*
+-		 * @bh is at least partially being written to.
+-		 * Make sure it is not marked as new.
+-		 */
+-		//if (buffer_new(bh))
+-		//	clear_buffer_new(bh);
+-
+-		if (block >= ablock) {
+-			// TODO: block is above allocated_size, need to
+-			// allocate it. Best done in one go to accommodate not
+-			// only block but all above blocks up to and including:
+-			// ((page->index << PAGE_CACHE_SHIFT) + to + blocksize
+-			// - 1) >> blobksize_bits. Obviously will need to round
+-			// up to next cluster boundary, too. This should be
+-			// done with a helper function, so it can be reused.
+-			ntfs_error(vol->sb, "Writing beyond allocated size "
+-					"is not supported yet. Sorry.");
+-			err = -EOPNOTSUPP;
+-			goto err_out;
+-			// Need to update ablock.
+-			// Need to set_buffer_new() on all block bhs that are
+-			// newly allocated.
+-		}
+-		/*
+-		 * Now we have enough allocated size to fulfill the whole
+-		 * request, i.e. block < ablock is true.
+-		 */
+-		if (unlikely((block >= iblock) &&
+-				(initialized_size < i_size))) {
+-			/*
+-			 * If this page is fully outside initialized size, zero
+-			 * out all pages between the current initialized size
+-			 * and the current page. Just use ntfs_readpage() to do
+-			 * the zeroing transparently.
+-			 */
+-			if (block > iblock) {
+-				// TODO:
+-				// For each page do:
+-				// - read_cache_page()
+-				// Again for each page do:
+-				// - wait_on_page_locked()
+-				// - Check (PageUptodate(page) &&
+-				//			!PageError(page))
+-				// Update initialized size in the attribute and
+-				// in the inode.
+-				// Again, for each page do:
+-				//	__set_page_dirty_buffers();
+-				// page_cache_release()
+-				// We don't need to wait on the writes.
+-				// Update iblock.
+-			}
+-			/*
+-			 * The current page straddles initialized size. Zero
+-			 * all non-uptodate buffers and set them uptodate (and
+-			 * dirty?). Note, there aren't any non-uptodate buffers
+-			 * if the page is uptodate.
+-			 * FIXME: For an uptodate page, the buffers may need to
+-			 * be written out because they were not initialized on
+-			 * disk before.
+-			 */
+-			if (!PageUptodate(page)) {
+-				// TODO:
+-				// Zero any non-uptodate buffers up to i_size.
+-				// Set them uptodate and dirty.
+-			}
+-			// TODO:
+-			// Update initialized size in the attribute and in the
+-			// inode (up to i_size).
+-			// Update iblock.
+-			// FIXME: This is inefficient. Try to batch the two
+-			// size changes to happen in one go.
+-			ntfs_error(vol->sb, "Writing beyond initialized size "
+-					"is not supported yet. Sorry.");
+-			err = -EOPNOTSUPP;
+-			goto err_out;
+-			// Do NOT set_buffer_new() BUT DO clear buffer range
+-			// outside write request range.
+-			// set_buffer_uptodate() on complete buffers as well as
+-			// set_buffer_dirty().
+-		}
+-
+-		/* Need to map unmapped buffers. */
+-		if (!buffer_mapped(bh)) {
+-			/* Unmapped buffer. Need to map it. */
+-			bh->b_bdev = vol->sb->s_bdev;
+-
+-			/* Convert block into corresponding vcn and offset. */
+-			vcn = (VCN)block << blocksize_bits >>
+-					vol->cluster_size_bits;
+-			vcn_ofs = ((VCN)block << blocksize_bits) &
+-					vol->cluster_size_mask;
+-
+-			is_retry = FALSE;
+-			if (!rl) {
+-lock_retry_remap:
+-				down_read(&ni->runlist.lock);
+-				rl = ni->runlist.rl;
+-			}
+-			if (likely(rl != NULL)) {
+-				/* Seek to element containing target vcn. */
+-				while (rl->length && rl[1].vcn <= vcn)
+-					rl++;
+-				lcn = ntfs_rl_vcn_to_lcn(rl, vcn);
+-			} else
+-				lcn = LCN_RL_NOT_MAPPED;
+-			if (unlikely(lcn < 0)) {
+-				/*
+-				 * We extended the attribute allocation above.
+-				 * If we hit an ENOENT here it means that the
+-				 * allocation was insufficient which is a bug.
+-				 */
+-				BUG_ON(lcn == LCN_ENOENT);
+-
+-				/* It is a hole, need to instantiate it. */
+-				if (lcn == LCN_HOLE) {
+-					// TODO: Instantiate the hole.
+-					// clear_buffer_new(bh);
+-					// unmap_underlying_metadata(bh->b_bdev,
+-					//		bh->b_blocknr);
+-					// For non-uptodate buffers, need to
+-					// zero out the region outside the
+-					// request in this bh or all bhs,
+-					// depending on what we implemented
+-					// above.
+-					// Need to flush_dcache_page().
+-					// Or could use set_buffer_new()
+-					// instead?
+-					ntfs_error(vol->sb, "Writing into "
+-							"sparse regions is "
+-							"not supported yet. "
+-							"Sorry.");
+-					err = -EOPNOTSUPP;
+-					if (!rl)
+-						up_read(&ni->runlist.lock);
+-					goto err_out;
+-				} else if (!is_retry &&
+-						lcn == LCN_RL_NOT_MAPPED) {
+-					is_retry = TRUE;
+-					/*
+-					 * Attempt to map runlist, dropping
+-					 * lock for the duration.
+-					 */
+-					up_read(&ni->runlist.lock);
+-					err = ntfs_map_runlist(ni, vcn);
+-					if (likely(!err))
+-						goto lock_retry_remap;
+-					rl = NULL;
+-				} else if (!rl)
+-					up_read(&ni->runlist.lock);
+-				/*
+-				 * Failed to map the buffer, even after
+-				 * retrying.
+-				 */
+-				if (!err)
+-					err = -EIO;
+-				bh->b_blocknr = -1;
+-				ntfs_error(vol->sb, "Failed to write to inode "
+-						"0x%lx, attribute type 0x%x, "
+-						"vcn 0x%llx, offset 0x%x "
+-						"because its location on disk "
+-						"could not be determined%s "
+-						"(error code %i).",
+-						ni->mft_no, ni->type,
+-						(unsigned long long)vcn,
+-						vcn_ofs, is_retry ? " even "
+-						"after retrying" : "", err);
+-				goto err_out;
+-			}
+-			/* We now have a successful remap, i.e. lcn >= 0. */
+-
+-			/* Setup buffer head to correct block. */
+-			bh->b_blocknr = ((lcn << vol->cluster_size_bits)
+-					+ vcn_ofs) >> blocksize_bits;
+-			set_buffer_mapped(bh);
+-
+-			// FIXME: Something analogous to this is needed for
+-			// each newly allocated block, i.e. BH_New.
+-			// FIXME: Might need to take this out of the
+-			// if (!buffer_mapped(bh)) {}, depending on how we
+-			// implement things during the allocated_size and
+-			// initialized_size extension code above.
+-			if (buffer_new(bh)) {
+-				clear_buffer_new(bh);
+-				unmap_underlying_metadata(bh->b_bdev,
+-						bh->b_blocknr);
+-				if (PageUptodate(page)) {
+-					set_buffer_uptodate(bh);
+-					continue;
+-				}
+-				/*
+-				 * Page is _not_ uptodate, zero surrounding
+-				 * region. NOTE: This is how we decide if to
+-				 * zero or not!
+-				 */
+-				if (block_end > to || block_start < from) {
+-					void *kaddr;
+-
+-					kaddr = kmap_atomic(page, KM_USER0);
+-					if (block_end > to)
+-						memset(kaddr + to, 0,
+-								block_end - to);
+-					if (block_start < from)
+-						memset(kaddr + block_start, 0,
+-								from -
+-								block_start);
+-					flush_dcache_page(page);
+-					kunmap_atomic(kaddr, KM_USER0);
+-				}
+-				continue;
+-			}
+-		}
+-		/* @bh is mapped, set it uptodate if the page is uptodate. */
+-		if (PageUptodate(page)) {
+-			if (!buffer_uptodate(bh))
+-				set_buffer_uptodate(bh);
+-			continue;
+-		}
+-		/*
+-		 * The page is not uptodate. The buffer is mapped. If it is not
+-		 * uptodate, and it is only partially being written to, we need
+-		 * to read the buffer in before the write, i.e. right now.
+-		 */
+-		if (!buffer_uptodate(bh) &&
+-				(block_start < from || block_end > to)) {
+-			ll_rw_block(READ, 1, &bh);
+-			*wait_bh++ = bh;
+-		}
+-	} while (block++, block_start = block_end,
+-			(bh = bh->b_this_page) != head);
+-
+-	/* Release the lock if we took it. */
+-	if (rl) {
+-		up_read(&ni->runlist.lock);
+-		rl = NULL;
+-	}
+-
+-	/* If we issued read requests, let them complete. */
+-	while (wait_bh > wait) {
+-		wait_on_buffer(*--wait_bh);
+-		if (!buffer_uptodate(*wait_bh))
+-			return -EIO;
+-	}
+-
+-	ntfs_debug("Done.");
+-	return 0;
+-err_out:
+-	/*
+-	 * Zero out any newly allocated blocks to avoid exposing stale data.
+-	 * If BH_New is set, we know that the block was newly allocated in the
+-	 * above loop.
+-	 * FIXME: What about initialized_size increments? Have we done all the
+-	 * required zeroing above? If not this error handling is broken, and
+-	 * in particular the if (block_end <= from) check is completely bogus.
+-	 */
+-	bh = head;
+-	block_start = 0;
+-	is_retry = FALSE;
+-	do {
+-		block_end = block_start + blocksize;
+-		if (block_end <= from)
+-			continue;
+-		if (block_start >= to)
+-			break;
+-		if (buffer_new(bh)) {
+-			void *kaddr;
+-
+-			clear_buffer_new(bh);
+-			kaddr = kmap_atomic(page, KM_USER0);
+-			memset(kaddr + block_start, 0, bh->b_size);
+-			kunmap_atomic(kaddr, KM_USER0);
+-			set_buffer_uptodate(bh);
+-			mark_buffer_dirty(bh);
+-			is_retry = TRUE;
+-		}
+-	} while (block_start = block_end, (bh = bh->b_this_page) != head);
+-	if (is_retry)
+-		flush_dcache_page(page);
+-	if (rl)
+-		up_read(&ni->runlist.lock);
+-	return err;
+-}
+-
+-/**
+- * ntfs_prepare_write - prepare a page for receiving data
+- *
+- * This is called from generic_file_write() with i_sem held on the inode
+- * (@page->mapping->host).  The @page is locked but not kmap()ped.  The source
+- * data has not yet been copied into the @page.
+- *
+- * Need to extend the attribute/fill in holes if necessary, create blocks and
+- * make partially overwritten blocks uptodate,
+- *
+- * i_size is not to be modified yet.
+- *
+- * Return 0 on success or -errno on error.
+- *
+- * Should be using block_prepare_write() [support for sparse files] or
+- * cont_prepare_write() [no support for sparse files].  Cannot do that due to
+- * ntfs specifics but can look at them for implementation guidance.
+- *
+- * Note: In the range, @from is inclusive and @to is exclusive, i.e. @from is
+- * the first byte in the page that will be written to and @to is the first byte
+- * after the last byte that will be written to.
+- */
+-static int ntfs_prepare_write(struct file *file, struct page *page,
+-		unsigned from, unsigned to)
+-{
+-	s64 new_size;
+-	loff_t i_size;
+-	struct inode *vi = page->mapping->host;
+-	ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);
+-	ntfs_volume *vol = ni->vol;
+-	ntfs_attr_search_ctx *ctx = NULL;
+-	MFT_RECORD *m = NULL;
+-	ATTR_RECORD *a;
+-	u8 *kaddr;
+-	u32 attr_len;
+-	int err;
+-
+-	ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
+-			"0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
+-			page->index, from, to);
+-	BUG_ON(!PageLocked(page));
+-	BUG_ON(from > PAGE_CACHE_SIZE);
+-	BUG_ON(to > PAGE_CACHE_SIZE);
+-	BUG_ON(from > to);
+-	BUG_ON(NInoMstProtected(ni));
+-	/*
+-	 * If a previous ntfs_truncate() failed, repeat it and abort if it
+-	 * fails again.
+-	 */
+-	if (unlikely(NInoTruncateFailed(ni))) {
+-		down_write(&vi->i_alloc_sem);
+-		err = ntfs_truncate(vi);
+-		up_write(&vi->i_alloc_sem);
+-		if (err || NInoTruncateFailed(ni)) {
+-			if (!err)
+-				err = -EIO;
+-			goto err_out;
+-		}
+-	}
+-	/* If the attribute is not resident, deal with it elsewhere. */
+-	if (NInoNonResident(ni)) {
+-		/*
+-		 * Only unnamed $DATA attributes can be compressed, encrypted,
+-		 * and/or sparse.
+-		 */
+-		if (ni->type == AT_DATA && !ni->name_len) {
+-			/* If file is encrypted, deny access, just like NT4. */
+-			if (NInoEncrypted(ni)) {
+-				ntfs_debug("Denying write access to encrypted "
+-						"file.");
+-				return -EACCES;
+-			}
+-			/* Compressed data streams are handled in compress.c. */
+-			if (NInoCompressed(ni)) {
+-				// TODO: Implement and replace this check with
+-				// return ntfs_write_compressed_block(page);
+-				ntfs_error(vi->i_sb, "Writing to compressed "
+-						"files is not supported yet. "
+-						"Sorry.");
+-				return -EOPNOTSUPP;
+-			}
+-			// TODO: Implement and remove this check.
+-			if (NInoSparse(ni)) {
+-				ntfs_error(vi->i_sb, "Writing to sparse files "
+-						"is not supported yet. Sorry.");
+-				return -EOPNOTSUPP;
+-			}
+-		}
+-		/* Normal data stream. */
+-		return ntfs_prepare_nonresident_write(page, from, to);
+-	}
+-	/*
+-	 * Attribute is resident, implying it is not compressed, encrypted, or
+-	 * sparse.
+-	 */
+-	BUG_ON(page_has_buffers(page));
+-	new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
+-	/* If we do not need to resize the attribute allocation we are done. */
+-	if (new_size <= i_size_read(vi))
+-		goto done;
+-	/* Map, pin, and lock the (base) mft record. */
+-	if (!NInoAttr(ni))
+-		base_ni = ni;
+-	else
+-		base_ni = ni->ext.base_ntfs_ino;
+-	m = map_mft_record(base_ni);
+-	if (IS_ERR(m)) {
+-		err = PTR_ERR(m);
+-		m = NULL;
+-		ctx = NULL;
+-		goto err_out;
+-	}
+-	ctx = ntfs_attr_get_search_ctx(base_ni, m);
+-	if (unlikely(!ctx)) {
+-		err = -ENOMEM;
+-		goto err_out;
+-	}
+-	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+-			CASE_SENSITIVE, 0, NULL, 0, ctx);
+-	if (unlikely(err)) {
+-		if (err == -ENOENT)
+-			err = -EIO;
+-		goto err_out;
+-	}
+-	m = ctx->mrec;
+-	a = ctx->attr;
+-	/* The total length of the attribute value. */
+-	attr_len = le32_to_cpu(a->data.resident.value_length);
+-	/* Fix an eventual previous failure of ntfs_commit_write(). */
+-	i_size = i_size_read(vi);
+-	if (unlikely(attr_len > i_size)) {
+-		attr_len = i_size;
+-		a->data.resident.value_length = cpu_to_le32(attr_len);
+-	}
+-	/* If we do not need to resize the attribute allocation we are done. */
+-	if (new_size <= attr_len)
+-		goto done_unm;
+-	/* Check if new size is allowed in $AttrDef. */
+-	err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
+-	if (unlikely(err)) {
+-		if (err == -ERANGE) {
+-			ntfs_error(vol->sb, "Write would cause the inode "
+-					"0x%lx to exceed the maximum size for "
+-					"its attribute type (0x%x).  Aborting "
+-					"write.", vi->i_ino,
+-					le32_to_cpu(ni->type));
+-		} else {
+-			ntfs_error(vol->sb, "Inode 0x%lx has unknown "
+-					"attribute type 0x%x.  Aborting "
+-					"write.", vi->i_ino,
+-					le32_to_cpu(ni->type));
+-			err = -EIO;
+-		}
+-		goto err_out2;
+-	}
+-	/*
+-	 * Extend the attribute record to be able to store the new attribute
+-	 * size.
+-	 */
+-	if (new_size >= vol->mft_record_size || ntfs_attr_record_resize(m, a,
+-			le16_to_cpu(a->data.resident.value_offset) +
+-			new_size)) {
+-		/* Not enough space in the mft record. */
+-		ntfs_error(vol->sb, "Not enough space in the mft record for "
+-				"the resized attribute value.  This is not "
+-				"supported yet.  Aborting write.");
+-		err = -EOPNOTSUPP;
+-		goto err_out2;
+-	}
+-	/*
+-	 * We have enough space in the mft record to fit the write.  This
+-	 * implies the attribute is smaller than the mft record and hence the
+-	 * attribute must be in a single page and hence page->index must be 0.
+-	 */
+-	BUG_ON(page->index);
+-	/*
+-	 * If the beginning of the write is past the old size, enlarge the
+-	 * attribute value up to the beginning of the write and fill it with
+-	 * zeroes.
+-	 */
+-	if (from > attr_len) {
+-		memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
+-				attr_len, 0, from - attr_len);
+-		a->data.resident.value_length = cpu_to_le32(from);
+-		/* Zero the corresponding area in the page as well. */
+-		if (PageUptodate(page)) {
+-			kaddr = kmap_atomic(page, KM_USER0);
+-			memset(kaddr + attr_len, 0, from - attr_len);
+-			kunmap_atomic(kaddr, KM_USER0);
+-			flush_dcache_page(page);
+-		}
+-	}
+-	flush_dcache_mft_record_page(ctx->ntfs_ino);
+-	mark_mft_record_dirty(ctx->ntfs_ino);
+-done_unm:
+-	ntfs_attr_put_search_ctx(ctx);
+-	unmap_mft_record(base_ni);
+-	/*
+-	 * Because resident attributes are handled by memcpy() to/from the
+-	 * corresponding MFT record, and because this form of i/o is byte
+-	 * aligned rather than block aligned, there is no need to bring the
+-	 * page uptodate here as in the non-resident case where we need to
+-	 * bring the buffers straddled by the write uptodate before
+-	 * generic_file_write() does the copying from userspace.
+-	 *
+-	 * We thus defer the uptodate bringing of the page region outside the
+-	 * region written to to ntfs_commit_write(), which makes the code
+-	 * simpler and saves one atomic kmap which is good.
+-	 */
+-done:
+-	ntfs_debug("Done.");
+-	return 0;
+-err_out:
+-	if (err == -ENOMEM)
+-		ntfs_warning(vi->i_sb, "Error allocating memory required to "
+-				"prepare the write.");
+-	else {
+-		ntfs_error(vi->i_sb, "Resident attribute prepare write failed "
+-				"with error %i.", err);
+-		NVolSetErrors(vol);
+-		make_bad_inode(vi);
+-	}
+-err_out2:
+-	if (ctx)
+-		ntfs_attr_put_search_ctx(ctx);
+-	if (m)
+-		unmap_mft_record(base_ni);
+-	return err;
+-}
+-
+-/**
+- * ntfs_commit_nonresident_write -
+- *
+- */
+-static int ntfs_commit_nonresident_write(struct page *page,
+-		unsigned from, unsigned to)
+-{
+-	s64 pos = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
+-	struct inode *vi = page->mapping->host;
+-	struct buffer_head *bh, *head;
+-	unsigned int block_start, block_end, blocksize;
+-	BOOL partial;
+-
+-	ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
+-			"0x%lx, from = %u, to = %u.", vi->i_ino,
+-			NTFS_I(vi)->type, page->index, from, to);
+-	blocksize = 1 << vi->i_blkbits;
+-
+-	// FIXME: We need a whole slew of special cases in here for compressed
+-	// files for example...
+-	// For now, we know ntfs_prepare_write() would have failed so we can't
+-	// get here in any of the cases which we have to special case, so we
+-	// are just a ripped off, unrolled generic_commit_write().
+-
+-	bh = head = page_buffers(page);
+-	block_start = 0;
+-	partial = FALSE;
+-	do {
+-		block_end = block_start + blocksize;
+-		if (block_end <= from || block_start >= to) {
+-			if (!buffer_uptodate(bh))
+-				partial = TRUE;
+-		} else {
+-			set_buffer_uptodate(bh);
+-			mark_buffer_dirty(bh);
+-		}
+-	} while (block_start = block_end, (bh = bh->b_this_page) != head);
+-	/*
+-	 * If this is a partial write which happened to make all buffers
+-	 * uptodate then we can optimize away a bogus ->readpage() for the next
+-	 * read().  Here we 'discover' whether the page went uptodate as a
+-	 * result of this (potentially partial) write.
+-	 */
+-	if (!partial)
+-		SetPageUptodate(page);
+-	/*
+-	 * Not convinced about this at all.  See disparity comment above.  For
+-	 * now we know ntfs_prepare_write() would have failed in the write
+-	 * exceeds i_size case, so this will never trigger which is fine.
+-	 */
+-	if (pos > i_size_read(vi)) {
+-		ntfs_error(vi->i_sb, "Writing beyond the existing file size is "
+-				"not supported yet.  Sorry.");
+-		return -EOPNOTSUPP;
+-		// vi->i_size = pos;
+-		// mark_inode_dirty(vi);
+-	}
+-	ntfs_debug("Done.");
+-	return 0;
+-}
+-
+-/**
+- * ntfs_commit_write - commit the received data
+- *
+- * This is called from generic_file_write() with i_sem held on the inode
+- * (@page->mapping->host).  The @page is locked but not kmap()ped.  The source
+- * data has already been copied into the @page.  ntfs_prepare_write() has been
+- * called before the data copied and it returned success so we can take the
+- * results of various BUG checks and some error handling for granted.
+- *
+- * Need to mark modified blocks dirty so they get written out later when
+- * ntfs_writepage() is invoked by the VM.
+- *
+- * Return 0 on success or -errno on error.
+- *
+- * Should be using generic_commit_write().  This marks buffers uptodate and
+- * dirty, sets the page uptodate if all buffers in the page are uptodate, and
+- * updates i_size if the end of io is beyond i_size.  In that case, it also
+- * marks the inode dirty.
+- *
+- * Cannot use generic_commit_write() due to ntfs specialities but can look at
+- * it for implementation guidance.
+- *
+- * If things have gone as outlined in ntfs_prepare_write(), then we do not
+- * need to do any page content modifications here at all, except in the write
+- * to resident attribute case, where we need to do the uptodate bringing here
+- * which we combine with the copying into the mft record which means we save
+- * one atomic kmap.
+- */
+-static int ntfs_commit_write(struct file *file, struct page *page,
+-		unsigned from, unsigned to)
+-{
+-	struct inode *vi = page->mapping->host;
+-	ntfs_inode *base_ni, *ni = NTFS_I(vi);
+-	char *kaddr, *kattr;
+-	ntfs_attr_search_ctx *ctx;
+-	MFT_RECORD *m;
+-	ATTR_RECORD *a;
+-	u32 attr_len;
+-	int err;
+-
+-	ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
+-			"0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
+-			page->index, from, to);
+-	/* If the attribute is not resident, deal with it elsewhere. */
+-	if (NInoNonResident(ni)) {
+-		/* Only unnamed $DATA attributes can be compressed/encrypted. */
+-		if (ni->type == AT_DATA && !ni->name_len) {
+-			/* Encrypted files need separate handling. */
+-			if (NInoEncrypted(ni)) {
+-				// We never get here at present!
+-				BUG();
+-			}
+-			/* Compressed data streams are handled in compress.c. */
+-			if (NInoCompressed(ni)) {
+-				// TODO: Implement this!
+-				// return ntfs_write_compressed_block(page);
+-				// We never get here at present!
+-				BUG();
+-			}
+-		}
+-		/* Normal data stream. */
+-		return ntfs_commit_nonresident_write(page, from, to);
+-	}
+-	/*
+-	 * Attribute is resident, implying it is not compressed, encrypted, or
+-	 * sparse.
+-	 */
+-	if (!NInoAttr(ni))
+-		base_ni = ni;
+-	else
+-		base_ni = ni->ext.base_ntfs_ino;
+-	/* Map, pin, and lock the mft record. */
+-	m = map_mft_record(base_ni);
+-	if (IS_ERR(m)) {
+-		err = PTR_ERR(m);
+-		m = NULL;
+-		ctx = NULL;
+-		goto err_out;
+-	}
+-	ctx = ntfs_attr_get_search_ctx(base_ni, m);
+-	if (unlikely(!ctx)) {
+-		err = -ENOMEM;
+-		goto err_out;
+-	}
+-	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+-			CASE_SENSITIVE, 0, NULL, 0, ctx);
+-	if (unlikely(err)) {
+-		if (err == -ENOENT)
+-			err = -EIO;
+-		goto err_out;
+-	}
+-	a = ctx->attr;
+-	/* The total length of the attribute value. */
+-	attr_len = le32_to_cpu(a->data.resident.value_length);
+-	BUG_ON(from > attr_len);
+-	kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
+-	kaddr = kmap_atomic(page, KM_USER0);
+-	/* Copy the received data from the page to the mft record. */
+-	memcpy(kattr + from, kaddr + from, to - from);
+-	/* Update the attribute length if necessary. */
+-	if (to > attr_len) {
+-		attr_len = to;
+-		a->data.resident.value_length = cpu_to_le32(attr_len);
+-	}
+-	/*
+-	 * If the page is not uptodate, bring the out of bounds area(s)
+-	 * uptodate by copying data from the mft record to the page.
+-	 */
+-	if (!PageUptodate(page)) {
+-		if (from > 0)
+-			memcpy(kaddr, kattr, from);
+-		if (to < attr_len)
+-			memcpy(kaddr + to, kattr + to, attr_len - to);
+-		/* Zero the region outside the end of the attribute value. */
+-		if (attr_len < PAGE_CACHE_SIZE)
+-			memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
+-		/*
+-		 * The probability of not having done any of the above is
+-		 * extremely small, so we just flush unconditionally.
+-		 */
+-		flush_dcache_page(page);
+-		SetPageUptodate(page);
+-	}
+-	kunmap_atomic(kaddr, KM_USER0);
+-	/* Update i_size if necessary. */
+-	if (i_size_read(vi) < attr_len) {
+-		unsigned long flags;
+-
+-		write_lock_irqsave(&ni->size_lock, flags);
+-		ni->allocated_size = ni->initialized_size = attr_len;
+-		i_size_write(vi, attr_len);
+-		write_unlock_irqrestore(&ni->size_lock, flags);
+-	}
+-	/* Mark the mft record dirty, so it gets written back. */
+-	flush_dcache_mft_record_page(ctx->ntfs_ino);
+-	mark_mft_record_dirty(ctx->ntfs_ino);
+-	ntfs_attr_put_search_ctx(ctx);
+-	unmap_mft_record(base_ni);
+-	ntfs_debug("Done.");
+-	return 0;
+-err_out:
+-	if (err == -ENOMEM) {
+-		ntfs_warning(vi->i_sb, "Error allocating memory required to "
+-				"commit the write.");
+-		if (PageUptodate(page)) {
+-			ntfs_warning(vi->i_sb, "Page is uptodate, setting "
+-					"dirty so the write will be retried "
+-					"later on by the VM.");
+-			/*
+-			 * Put the page on mapping->dirty_pages, but leave its
+-			 * buffers' dirty state as-is.
+-			 */
+-			__set_page_dirty_nobuffers(page);
+-			err = 0;
+-		} else
+-			ntfs_error(vi->i_sb, "Page is not uptodate.  Written "
+-					"data has been lost.");
+-	} else {
+-		ntfs_error(vi->i_sb, "Resident attribute commit write failed "
+-				"with error %i.", err);
+-		NVolSetErrors(ni->vol);
+-		make_bad_inode(vi);
+-	}
+-	if (ctx)
+-		ntfs_attr_put_search_ctx(ctx);
+-	if (m)
+-		unmap_mft_record(base_ni);
+-	return err;
+-}
+-
+ #endif	/* NTFS_RW */
+ 
+ /**
+@@ -2377,9 +1552,6 @@ struct address_space_operations ntfs_aop
+ 						   disk request queue. */
+ #ifdef NTFS_RW
+ 	.writepage	= ntfs_writepage,	/* Write dirty page to disk. */
+-	.prepare_write	= ntfs_prepare_write,	/* Prepare page and buffers
+-						   ready to receive data. */
+-	.commit_write	= ntfs_commit_write,	/* Commit received data. */
+ #endif /* NTFS_RW */
+ };
+ 
+diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
+--- a/fs/ntfs/attrib.c
++++ b/fs/ntfs/attrib.c
+@@ -21,7 +21,9 @@
+  */
+ 
+ #include <linux/buffer_head.h>
++#include <linux/sched.h>
+ #include <linux/swap.h>
++#include <linux/writeback.h>
+ 
+ #include "attrib.h"
+ #include "debug.h"
+@@ -36,9 +38,27 @@
+  * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode
+  * @ni:		ntfs inode for which to map (part of) a runlist
+  * @vcn:	map runlist part containing this vcn
++ * @ctx:	active attribute search context if present or NULL if not
+  *
+  * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
+  *
++ * If @ctx is specified, it is an active search context of @ni and its base mft
++ * record.  This is needed when ntfs_map_runlist_nolock() encounters unmapped
++ * runlist fragments and allows their mapping.  If you do not have the mft
++ * record mapped, you can specify @ctx as NULL and ntfs_map_runlist_nolock()
++ * will perform the necessary mapping and unmapping.
++ *
++ * Note, ntfs_map_runlist_nolock() saves the state of @ctx on entry and
++ * restores it before returning.  Thus, @ctx will be left pointing to the same
++ * attribute on return as on entry.  However, the actual pointers in @ctx may
++ * point to different memory locations on return, so you must remember to reset
++ * any cached pointers from the @ctx, i.e. after the call to
++ * ntfs_map_runlist_nolock(), you will probably want to do:
++ *	m = ctx->mrec;
++ *	a = ctx->attr;
++ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
++ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
++ *
+  * Return 0 on success and -errno on error.  There is one special error code
+  * which is not an error as such.  This is -ENOENT.  It means that @vcn is out
+  * of bounds of the runlist.
+@@ -46,19 +66,32 @@
+  * Note the runlist can be NULL after this function returns if @vcn is zero and
+  * the attribute has zero allocated size, i.e. there simply is no runlist.
+  *
+- * Locking: - The runlist must be locked for writing.
+- *	    - This function modifies the runlist.
++ * WARNING: If @ctx is supplied, regardless of whether success or failure is
++ *	    returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
++ *	    is no longer valid, i.e. you need to either call
++ *	    ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
++ *	    In that case PTR_ERR(@ctx->mrec) will give you the error code for
++ *	    why the mapping of the old inode failed.
++ *
++ * Locking: - The runlist described by @ni must be locked for writing on entry
++ *	      and is locked on return.  Note the runlist will be modified.
++ *	    - If @ctx is NULL, the base mft record of @ni must not be mapped on
++ *	      entry and it will be left unmapped on return.
++ *	    - If @ctx is not NULL, the base mft record must be mapped on entry
++ *	      and it will be left mapped on return.
+  */
+-int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
++int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
+ {
+ 	VCN end_vcn;
++	unsigned long flags;
+ 	ntfs_inode *base_ni;
+ 	MFT_RECORD *m;
+ 	ATTR_RECORD *a;
+-	ntfs_attr_search_ctx *ctx;
+ 	runlist_element *rl;
+-	unsigned long flags;
++	struct page *put_this_page = NULL;
+ 	int err = 0;
++	BOOL ctx_is_temporary, ctx_needs_reset;
++	ntfs_attr_search_ctx old_ctx = { NULL, };
+ 
+ 	ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
+ 			(unsigned long long)vcn);
+@@ -66,20 +99,77 @@ int ntfs_map_runlist_nolock(ntfs_inode *
+ 		base_ni = ni;
+ 	else
+ 		base_ni = ni->ext.base_ntfs_ino;
+-	m = map_mft_record(base_ni);
+-	if (IS_ERR(m))
+-		return PTR_ERR(m);
+-	ctx = ntfs_attr_get_search_ctx(base_ni, m);
+-	if (unlikely(!ctx)) {
+-		err = -ENOMEM;
+-		goto err_out;
++	if (!ctx) {
++		ctx_is_temporary = ctx_needs_reset = TRUE;
++		m = map_mft_record(base_ni);
++		if (IS_ERR(m))
++			return PTR_ERR(m);
++		ctx = ntfs_attr_get_search_ctx(base_ni, m);
++		if (unlikely(!ctx)) {
++			err = -ENOMEM;
++			goto err_out;
++		}
++	} else {
++		VCN allocated_size_vcn;
++
++		BUG_ON(IS_ERR(ctx->mrec));
++		a = ctx->attr;
++		BUG_ON(!a->non_resident);
++		ctx_is_temporary = FALSE;
++		end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
++		read_lock_irqsave(&ni->size_lock, flags);
++		allocated_size_vcn = ni->allocated_size >>
++				ni->vol->cluster_size_bits;
++		read_unlock_irqrestore(&ni->size_lock, flags);
++		if (!a->data.non_resident.lowest_vcn && end_vcn <= 0)
++			end_vcn = allocated_size_vcn - 1;
++		/*
++		 * If we already have the attribute extent containing @vcn in
++		 * @ctx, no need to look it up again.  We slightly cheat in
++		 * that if vcn exceeds the allocated size, we will refuse to
++		 * map the runlist below, so there is definitely no need to get
++		 * the right attribute extent.
++		 */
++		if (vcn >= allocated_size_vcn || (a->type == ni->type &&
++				a->name_length == ni->name_len &&
++				!memcmp((u8*)a + le16_to_cpu(a->name_offset),
++				ni->name, ni->name_len) &&
++				sle64_to_cpu(a->data.non_resident.lowest_vcn)
++				<= vcn && end_vcn >= vcn))
++			ctx_needs_reset = FALSE;
++		else {
++			/* Save the old search context. */
++			old_ctx = *ctx;
++			/*
++			 * If the currently mapped (extent) inode is not the
++			 * base inode we will unmap it when we reinitialize the
++			 * search context which means we need to get a
++			 * reference to the page containing the mapped mft
++			 * record so we do not accidentally drop changes to the
++			 * mft record when it has not been marked dirty yet.
++			 */
++			if (old_ctx.base_ntfs_ino && old_ctx.ntfs_ino !=
++					old_ctx.base_ntfs_ino) {
++				put_this_page = old_ctx.ntfs_ino->page;
++				page_cache_get(put_this_page);
++			}
++			/*
++			 * Reinitialize the search context so we can lookup the
++			 * needed attribute extent.
++			 */
++			ntfs_attr_reinit_search_ctx(ctx);
++			ctx_needs_reset = TRUE;
++		}
+ 	}
+-	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+-			CASE_SENSITIVE, vcn, NULL, 0, ctx);
+-	if (unlikely(err)) {
+-		if (err == -ENOENT)
+-			err = -EIO;
+-		goto err_out;
++	if (ctx_needs_reset) {
++		err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++				CASE_SENSITIVE, vcn, NULL, 0, ctx);
++		if (unlikely(err)) {
++			if (err == -ENOENT)
++				err = -EIO;
++			goto err_out;
++		}
++		BUG_ON(!ctx->attr->non_resident);
+ 	}
+ 	a = ctx->attr;
+ 	/*
+@@ -89,11 +179,9 @@ int ntfs_map_runlist_nolock(ntfs_inode *
+ 	 * ntfs_mapping_pairs_decompress() fails.
+ 	 */
+ 	end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
+-	if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) {
+-		read_lock_irqsave(&ni->size_lock, flags);
+-		end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
+-		read_unlock_irqrestore(&ni->size_lock, flags);
+-	}
++	if (!a->data.non_resident.lowest_vcn && end_vcn == 1)
++		end_vcn = sle64_to_cpu(a->data.non_resident.allocated_size) >>
++				ni->vol->cluster_size_bits;
+ 	if (unlikely(vcn >= end_vcn)) {
+ 		err = -ENOENT;
+ 		goto err_out;
+@@ -104,9 +192,93 @@ int ntfs_map_runlist_nolock(ntfs_inode *
+ 	else
+ 		ni->runlist.rl = rl;
+ err_out:
+-	if (likely(ctx))
+-		ntfs_attr_put_search_ctx(ctx);
+-	unmap_mft_record(base_ni);
++	if (ctx_is_temporary) {
++		if (likely(ctx))
++			ntfs_attr_put_search_ctx(ctx);
++		unmap_mft_record(base_ni);
++	} else if (ctx_needs_reset) {
++		/*
++		 * If there is no attribute list, restoring the search context
++		 * is acomplished simply by copying the saved context back over
++		 * the caller supplied context.  If there is an attribute list,
++		 * things are more complicated as we need to deal with mapping
++		 * of mft records and resulting potential changes in pointers.
++		 */
++		if (NInoAttrList(base_ni)) {
++			/*
++			 * If the currently mapped (extent) inode is not the
++			 * one we had before, we need to unmap it and map the
++			 * old one.
++			 */
++			if (ctx->ntfs_ino != old_ctx.ntfs_ino) {
++				/*
++				 * If the currently mapped inode is not the
++				 * base inode, unmap it.
++				 */
++				if (ctx->base_ntfs_ino && ctx->ntfs_ino !=
++						ctx->base_ntfs_ino) {
++					unmap_extent_mft_record(ctx->ntfs_ino);
++					ctx->mrec = ctx->base_mrec;
++					BUG_ON(!ctx->mrec);
++				}
++				/*
++				 * If the old mapped inode is not the base
++				 * inode, map it.
++				 */
++				if (old_ctx.base_ntfs_ino &&
++						old_ctx.ntfs_ino !=
++						old_ctx.base_ntfs_ino) {
++retry_map:
++					ctx->mrec = map_mft_record(
++							old_ctx.ntfs_ino);
++					/*
++					 * Something bad has happened.  If out
++					 * of memory retry till it succeeds.
++					 * Any other errors are fatal and we
++					 * return the error code in ctx->mrec.
++					 * Let the caller deal with it...  We
++					 * just need to fudge things so the
++					 * caller can reinit and/or put the
++					 * search context safely.
++					 */
++					if (IS_ERR(ctx->mrec)) {
++						if (PTR_ERR(ctx->mrec) ==
++								-ENOMEM) {
++							schedule();
++							goto retry_map;
++						} else
++							old_ctx.ntfs_ino =
++								old_ctx.
++								base_ntfs_ino;
++					}
++				}
++			}
++			/* Update the changed pointers in the saved context. */
++			if (ctx->mrec != old_ctx.mrec) {
++				if (!IS_ERR(ctx->mrec))
++					old_ctx.attr = (ATTR_RECORD*)(
++							(u8*)ctx->mrec +
++							((u8*)old_ctx.attr -
++							(u8*)old_ctx.mrec));
++				old_ctx.mrec = ctx->mrec;
++			}
++		}
++		/* Restore the search context to the saved one. */
++		*ctx = old_ctx;
++		/*
++		 * We drop the reference on the page we took earlier.  In the
++		 * case that IS_ERR(ctx->mrec) is true this means we might lose
++		 * some changes to the mft record that had been made between
++		 * the last time it was marked dirty/written out and now.  This
++		 * at this stage is not a problem as the mapping error is fatal
++		 * enough that the mft record cannot be written out anyway and
++		 * the caller is very likely to shutdown the whole inode
++		 * immediately and mark the volume dirty for chkdsk to pick up
++		 * the pieces anyway.
++		 */
++		if (put_this_page)
++			page_cache_release(put_this_page);
++	}
+ 	return err;
+ }
+ 
+@@ -122,8 +294,8 @@ err_out:
+  * of bounds of the runlist.
+  *
+  * Locking: - The runlist must be unlocked on entry and is unlocked on return.
+- *	    - This function takes the runlist lock for writing and modifies the
+- *	      runlist.
++ *	    - This function takes the runlist lock for writing and may modify
++ *	      the runlist.
+  */
+ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
+ {
+@@ -133,7 +305,7 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN
+ 	/* Make sure someone else didn't do the work while we were sleeping. */
+ 	if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
+ 			LCN_RL_NOT_MAPPED))
+-		err = ntfs_map_runlist_nolock(ni, vcn);
++		err = ntfs_map_runlist_nolock(ni, vcn, NULL);
+ 	up_write(&ni->runlist.lock);
+ 	return err;
+ }
+@@ -212,7 +384,7 @@ retry_remap:
+ 				goto retry_remap;
+ 			}
+ 		}
+-		err = ntfs_map_runlist_nolock(ni, vcn);
++		err = ntfs_map_runlist_nolock(ni, vcn, NULL);
+ 		if (!write_locked) {
+ 			up_write(&ni->runlist.lock);
+ 			down_read(&ni->runlist.lock);
+@@ -236,9 +408,9 @@ retry_remap:
+ 
+ /**
+  * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode
+- * @ni:			ntfs inode describing the runlist to search
+- * @vcn:		vcn to find
+- * @write_locked:	true if the runlist is locked for writing
++ * @ni:		ntfs inode describing the runlist to search
++ * @vcn:	vcn to find
++ * @ctx:	active attribute search context if present or NULL if not
+  *
+  * Find the virtual cluster number @vcn in the runlist described by the ntfs
+  * inode @ni and return the address of the runlist element containing the @vcn.
+@@ -246,9 +418,22 @@ retry_remap:
+  * If the @vcn is not mapped yet, the attempt is made to map the attribute
+  * extent containing the @vcn and the vcn to lcn conversion is retried.
+  *
+- * If @write_locked is true the caller has locked the runlist for writing and
+- * if false for reading.
+- *
++ * If @ctx is specified, it is an active search context of @ni and its base mft
++ * record.  This is needed when ntfs_attr_find_vcn_nolock() encounters unmapped
++ * runlist fragments and allows their mapping.  If you do not have the mft
++ * record mapped, you can specify @ctx as NULL and ntfs_attr_find_vcn_nolock()
++ * will perform the necessary mapping and unmapping.
++ *
++ * Note, ntfs_attr_find_vcn_nolock() saves the state of @ctx on entry and
++ * restores it before returning.  Thus, @ctx will be left pointing to the same
++ * attribute on return as on entry.  However, the actual pointers in @ctx may
++ * point to different memory locations on return, so you must remember to reset
++ * any cached pointers from the @ctx, i.e. after the call to
++ * ntfs_attr_find_vcn_nolock(), you will probably want to do:
++ *	m = ctx->mrec;
++ *	a = ctx->attr;
++ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
++ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
+  * Note you need to distinguish between the lcn of the returned runlist element
+  * being >= 0 and LCN_HOLE.  In the later case you have to return zeroes on
+  * read and allocate clusters on write.
+@@ -263,22 +448,31 @@ retry_remap:
+  *	-ENOMEM - Not enough memory to map runlist.
+  *	-EIO	- Critical error (runlist/file is corrupt, i/o error, etc).
+  *
+- * Locking: - The runlist must be locked on entry and is left locked on return.
+- *	    - If @write_locked is FALSE, i.e. the runlist is locked for reading,
+- *	      the lock may be dropped inside the function so you cannot rely on
+- *	      the runlist still being the same when this function returns.
++ * WARNING: If @ctx is supplied, regardless of whether success or failure is
++ *	    returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
++ *	    is no longer valid, i.e. you need to either call
++ *	    ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
++ *	    In that case PTR_ERR(@ctx->mrec) will give you the error code for
++ *	    why the mapping of the old inode failed.
++ *
++ * Locking: - The runlist described by @ni must be locked for writing on entry
++ *	      and is locked on return.  Note the runlist may be modified when
++ *	      needed runlist fragments need to be mapped.
++ *	    - If @ctx is NULL, the base mft record of @ni must not be mapped on
++ *	      entry and it will be left unmapped on return.
++ *	    - If @ctx is not NULL, the base mft record must be mapped on entry
++ *	      and it will be left mapped on return.
+  */
+ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
+-		const BOOL write_locked)
++		ntfs_attr_search_ctx *ctx)
+ {
+ 	unsigned long flags;
+ 	runlist_element *rl;
+ 	int err = 0;
+ 	BOOL is_retry = FALSE;
+ 
+-	ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
+-			ni->mft_no, (unsigned long long)vcn,
+-			write_locked ? "write" : "read");
++	ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.",
++			ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out");
+ 	BUG_ON(!ni);
+ 	BUG_ON(!NInoNonResident(ni));
+ 	BUG_ON(vcn < 0);
+@@ -312,33 +506,22 @@ retry_remap:
+ 	}
+ 	if (!err && !is_retry) {
+ 		/*
+-		 * The @vcn is in an unmapped region, map the runlist and
+-		 * retry.
++		 * If the search context is invalid we cannot map the unmapped
++		 * region.
+ 		 */
+-		if (!write_locked) {
+-			up_read(&ni->runlist.lock);
+-			down_write(&ni->runlist.lock);
+-			if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
+-					LCN_RL_NOT_MAPPED)) {
+-				up_write(&ni->runlist.lock);
+-				down_read(&ni->runlist.lock);
++		if (IS_ERR(ctx->mrec))
++			err = PTR_ERR(ctx->mrec);
++		else {
++			/*
++			 * The @vcn is in an unmapped region, map the runlist
++			 * and retry.
++			 */
++			err = ntfs_map_runlist_nolock(ni, vcn, ctx);
++			if (likely(!err)) {
++				is_retry = TRUE;
+ 				goto retry_remap;
+ 			}
+ 		}
+-		err = ntfs_map_runlist_nolock(ni, vcn);
+-		if (!write_locked) {
+-			up_write(&ni->runlist.lock);
+-			down_read(&ni->runlist.lock);
+-		}
+-		if (likely(!err)) {
+-			is_retry = TRUE;
+-			goto retry_remap;
+-		}
+-		/*
+-		 * -EINVAL coming from a failed mapping attempt is equivalent
+-		 * to i/o error for us as it should not happen in our code
+-		 * paths.
+-		 */
+ 		if (err == -EINVAL)
+ 			err = -EIO;
+ 	} else if (!err)
+@@ -1011,6 +1194,7 @@ int ntfs_attr_lookup(const ATTR_TYPE typ
+ 	ntfs_inode *base_ni;
+ 
+ 	ntfs_debug("Entering.");
++	BUG_ON(IS_ERR(ctx->mrec));
+ 	if (ctx->base_ntfs_ino)
+ 		base_ni = ctx->base_ntfs_ino;
+ 	else
+@@ -1227,7 +1411,7 @@ int ntfs_attr_can_be_non_resident(const 
+  */
+ int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
+ {
+-	if (type == AT_INDEX_ALLOCATION || type == AT_EA)
++	if (type == AT_INDEX_ALLOCATION)
+ 		return -EPERM;
+ 	return 0;
+ }
+@@ -1319,10 +1503,17 @@ int ntfs_resident_attr_value_resize(MFT_
+ /**
+  * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
+  * @ni:		ntfs inode describing the attribute to convert
++ * @data_size:	size of the resident data to copy to the non-resident attribute
+  *
+  * Convert the resident ntfs attribute described by the ntfs inode @ni to a
+  * non-resident one.
+  *
++ * @data_size must be equal to the attribute value size.  This is needed since
++ * we need to know the size before we can map the mft record and our callers
++ * always know it.  The reason we cannot simply read the size from the vfs
++ * inode i_size is that this is not necessarily uptodate.  This happens when
++ * ntfs_attr_make_non_resident() is called in the ->truncate call path(s).
++ *
+  * Return 0 on success and -errno on error.  The following error return codes
+  * are defined:
+  *	-EPERM	- The attribute is not allowed to be non-resident.
+@@ -1343,7 +1534,7 @@ int ntfs_resident_attr_value_resize(MFT_
+  *
+  * Locking: - The caller must hold i_sem on the inode.
+  */
+-int ntfs_attr_make_non_resident(ntfs_inode *ni)
++int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
+ {
+ 	s64 new_size;
+ 	struct inode *vi = VFS_I(ni);
+@@ -1381,11 +1572,9 @@ int ntfs_attr_make_non_resident(ntfs_ino
+ 	 * The size needs to be aligned to a cluster boundary for allocation
+ 	 * purposes.
+ 	 */
+-	new_size = (i_size_read(vi) + vol->cluster_size - 1) &
++	new_size = (data_size + vol->cluster_size - 1) &
+ 			~(vol->cluster_size - 1);
+ 	if (new_size > 0) {
+-		runlist_element *rl2;
+-
+ 		/*
+ 		 * Will need the page later and since the page lock nests
+ 		 * outside all ntfs locks, we need to get the page now.
+@@ -1396,7 +1585,7 @@ int ntfs_attr_make_non_resident(ntfs_ino
+ 			return -ENOMEM;
+ 		/* Start by allocating clusters to hold the attribute value. */
+ 		rl = ntfs_cluster_alloc(vol, 0, new_size >>
+-				vol->cluster_size_bits, -1, DATA_ZONE);
++				vol->cluster_size_bits, -1, DATA_ZONE, TRUE);
+ 		if (IS_ERR(rl)) {
+ 			err = PTR_ERR(rl);
+ 			ntfs_debug("Failed to allocate cluster%s, error code "
+@@ -1405,12 +1594,6 @@ int ntfs_attr_make_non_resident(ntfs_ino
+ 					err);
+ 			goto page_err_out;
+ 		}
+-		/* Change the runlist terminator to LCN_ENOENT. */
+-		rl2 = rl;
+-		while (rl2->length)
+-			rl2++;
+-		BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);
+-		rl2->lcn = LCN_ENOENT;
+ 	} else {
+ 		rl = NULL;
+ 		page = NULL;
+@@ -1473,7 +1656,7 @@ int ntfs_attr_make_non_resident(ntfs_ino
+ 	 * attribute value.
+ 	 */
+ 	attr_size = le32_to_cpu(a->data.resident.value_length);
+-	BUG_ON(attr_size != i_size_read(vi));
++	BUG_ON(attr_size != data_size);
+ 	if (page && !PageUptodate(page)) {
+ 		kaddr = kmap_atomic(page, KM_USER0);
+ 		memcpy(kaddr, (u8*)a +
+@@ -1538,7 +1721,9 @@ int ntfs_attr_make_non_resident(ntfs_ino
+ 				ffs(ni->itype.compressed.block_size) - 1;
+ 		ni->itype.compressed.block_clusters = 1U <<
+ 				a->data.non_resident.compression_unit;
+-	}
++		vi->i_blocks = ni->itype.compressed.size >> 9;
++	} else
++		vi->i_blocks = ni->allocated_size >> 9;
+ 	write_unlock_irqrestore(&ni->size_lock, flags);
+ 	/*
+ 	 * This needs to be last since the address space operations ->readpage
+@@ -1652,6 +1837,640 @@ page_err_out:
+ }
+ 
+ /**
++ * ntfs_attr_extend_allocation - extend the allocated space of an attribute
++ * @ni:			ntfs inode of the attribute whose allocation to extend
++ * @new_alloc_size:	new size in bytes to which to extend the allocation to
++ * @new_data_size:	new size in bytes to which to extend the data to
++ * @data_start:		beginning of region which is required to be non-sparse
++ *
++ * Extend the allocated space of an attribute described by the ntfs inode @ni
++ * to @new_alloc_size bytes.  If @data_start is -1, the whole extension may be
++ * implemented as a hole in the file (as long as both the volume and the ntfs
++ * inode @ni have sparse support enabled).  If @data_start is >= 0, then the
++ * region between the old allocated size and @data_start - 1 may be made sparse
++ * but the regions between @data_start and @new_alloc_size must be backed by
++ * actual clusters.
++ *
++ * If @new_data_size is -1, it is ignored.  If it is >= 0, then the data size
++ * of the attribute is extended to @new_data_size.  Note that the i_size of the
++ * vfs inode is not updated.  Only the data size in the base attribute record
++ * is updated.  The caller has to update i_size separately if this is required.
++ * WARNING: It is a BUG() for @new_data_size to be smaller than the old data
++ * size as well as for @new_data_size to be greater than @new_alloc_size.
++ *
++ * For resident attributes this involves resizing the attribute record and if
++ * necessary moving it and/or other attributes into extent mft records and/or
++ * converting the attribute to a non-resident attribute which in turn involves
++ * extending the allocation of a non-resident attribute as described below.
++ *
++ * For non-resident attributes this involves allocating clusters in the data
++ * zone on the volume (except for regions that are being made sparse) and
++ * extending the run list to describe the allocated clusters as well as
++ * updating the mapping pairs array of the attribute.  This in turn involves
++ * resizing the attribute record and if necessary moving it and/or other
++ * attributes into extent mft records and/or splitting the attribute record
++ * into multiple extent attribute records.
++ *
++ * Also, the attribute list attribute is updated if present and in some of the
++ * above cases (the ones where extent mft records/attributes come into play),
++ * an attribute list attribute is created if not already present.
++ *
++ * Return the new allocated size on success and -errno on error.  In the case
++ * that an error is encountered but a partial extension at least up to
++ * @data_start (if present) is possible, the allocation is partially extended
++ * and this is returned.  This means the caller must check the returned size to
++ * determine if the extension was partial.  If @data_start is -1 then partial
++ * allocations are not performed.
++ *
++ * WARNING: Do not call ntfs_attr_extend_allocation() for $MFT/$DATA.
++ *
++ * Locking: This function takes the runlist lock of @ni for writing as well as
++ * locking the mft record of the base ntfs inode.  These locks are maintained
++ * throughout execution of the function.  These locks are required so that the
++ * attribute can be resized safely and so that it can for example be converted
++ * from resident to non-resident safely.
++ *
++ * TODO: At present attribute list attribute handling is not implemented.
++ *
++ * TODO: At present it is not safe to call this function for anything other
++ * than the $DATA attribute(s) of an uncompressed and unencrypted file.
++ */
++s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size,
++		const s64 new_data_size, const s64 data_start)
++{
++	VCN vcn;
++	s64 ll, allocated_size, start = data_start;
++	struct inode *vi = VFS_I(ni);
++	ntfs_volume *vol = ni->vol;
++	ntfs_inode *base_ni;
++	MFT_RECORD *m;
++	ATTR_RECORD *a;
++	ntfs_attr_search_ctx *ctx;
++	runlist_element *rl, *rl2;
++	unsigned long flags;
++	int err, mp_size;
++	u32 attr_len = 0; /* Silence stupid gcc warning. */
++	BOOL mp_rebuilt;
++
++#ifdef NTFS_DEBUG
++	read_lock_irqsave(&ni->size_lock, flags);
++	allocated_size = ni->allocated_size;
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
++			"old_allocated_size 0x%llx, "
++			"new_allocated_size 0x%llx, new_data_size 0x%llx, "
++			"data_start 0x%llx.", vi->i_ino,
++			(unsigned)le32_to_cpu(ni->type),
++			(unsigned long long)allocated_size,
++			(unsigned long long)new_alloc_size,
++			(unsigned long long)new_data_size,
++			(unsigned long long)start);
++#endif
++retry_extend:
++	/*
++	 * For non-resident attributes, @start and @new_size need to be aligned
++	 * to cluster boundaries for allocation purposes.
++	 */
++	if (NInoNonResident(ni)) {
++		if (start > 0)
++			start &= ~(s64)vol->cluster_size_mask;
++		new_alloc_size = (new_alloc_size + vol->cluster_size - 1) &
++				~(s64)vol->cluster_size_mask;
++	}
++	BUG_ON(new_data_size >= 0 && new_data_size > new_alloc_size);
++	/* Check if new size is allowed in $AttrDef. */
++	err = ntfs_attr_size_bounds_check(vol, ni->type, new_alloc_size);
++	if (unlikely(err)) {
++		/* Only emit errors when the write will fail completely. */
++		read_lock_irqsave(&ni->size_lock, flags);
++		allocated_size = ni->allocated_size;
++		read_unlock_irqrestore(&ni->size_lock, flags);
++		if (start < 0 || start >= allocated_size) {
++			if (err == -ERANGE) {
++				ntfs_error(vol->sb, "Cannot extend allocation "
++						"of inode 0x%lx, attribute "
++						"type 0x%x, because the new "
++						"allocation would exceed the "
++						"maximum allowed size for "
++						"this attribute type.",
++						vi->i_ino, (unsigned)
++						le32_to_cpu(ni->type));
++			} else {
++				ntfs_error(vol->sb, "Cannot extend allocation "
++						"of inode 0x%lx, attribute "
++						"type 0x%x, because this "
++						"attribute type is not "
++						"defined on the NTFS volume.  "
++						"Possible corruption!  You "
++						"should run chkdsk!",
++						vi->i_ino, (unsigned)
++						le32_to_cpu(ni->type));
++			}
++		}
++		/* Translate error code to be POSIX conformant for write(2). */
++		if (err == -ERANGE)
++			err = -EFBIG;
++		else
++			err = -EIO;
++		return err;
++	}
++	if (!NInoAttr(ni))
++		base_ni = ni;
++	else
++		base_ni = ni->ext.base_ntfs_ino;
++	/*
++	 * We will be modifying both the runlist (if non-resident) and the mft
++	 * record so lock them both down.
++	 */
++	down_write(&ni->runlist.lock);
++	m = map_mft_record(base_ni);
++	if (IS_ERR(m)) {
++		err = PTR_ERR(m);
++		m = NULL;
++		ctx = NULL;
++		goto err_out;
++	}
++	ctx = ntfs_attr_get_search_ctx(base_ni, m);
++	if (unlikely(!ctx)) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++	read_lock_irqsave(&ni->size_lock, flags);
++	allocated_size = ni->allocated_size;
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	/*
++	 * If non-resident, seek to the last extent.  If resident, there is
++	 * only one extent, so seek to that.
++	 */
++	vcn = NInoNonResident(ni) ? allocated_size >> vol->cluster_size_bits :
++			0;
++	/*
++	 * Abort if someone did the work whilst we waited for the locks.  If we
++	 * just converted the attribute from resident to non-resident it is
++	 * likely that exactly this has happened already.  We cannot quite
++	 * abort if we need to update the data size.
++	 */
++	if (unlikely(new_alloc_size <= allocated_size)) {
++		ntfs_debug("Allocated size already exceeds requested size.");
++		new_alloc_size = allocated_size;
++		if (new_data_size < 0)
++			goto done;
++		/*
++		 * We want the first attribute extent so that we can update the
++		 * data size.
++		 */
++		vcn = 0;
++	}
++	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++			CASE_SENSITIVE, vcn, NULL, 0, ctx);
++	if (unlikely(err)) {
++		if (err == -ENOENT)
++			err = -EIO;
++		goto err_out;
++	}
++	m = ctx->mrec;
++	a = ctx->attr;
++	/* Use goto to reduce indentation. */
++	if (a->non_resident)
++		goto do_non_resident_extend;
++	BUG_ON(NInoNonResident(ni));
++	/* The total length of the attribute value. */
++	attr_len = le32_to_cpu(a->data.resident.value_length);
++	/*
++	 * Extend the attribute record to be able to store the new attribute
++	 * size.  ntfs_attr_record_resize() will not do anything if the size is
++	 * not changing.
++	 */
++	if (new_alloc_size < vol->mft_record_size &&
++			!ntfs_attr_record_resize(m, a,
++			le16_to_cpu(a->data.resident.value_offset) +
++			new_alloc_size)) {
++		/* The resize succeeded! */
++		write_lock_irqsave(&ni->size_lock, flags);
++		ni->allocated_size = le32_to_cpu(a->length) -
++				le16_to_cpu(a->data.resident.value_offset);
++		write_unlock_irqrestore(&ni->size_lock, flags);
++		if (new_data_size >= 0) {
++			BUG_ON(new_data_size < attr_len);
++			a->data.resident.value_length =
++					cpu_to_le32((u32)new_data_size);
++		}
++		goto flush_done;
++	}
++	/*
++	 * We have to drop all the locks so we can call
++	 * ntfs_attr_make_non_resident().  This could be optimised by try-
++	 * locking the first page cache page and only if that fails dropping
++	 * the locks, locking the page, and redoing all the locking and
++	 * lookups.  While this would be a huge optimisation, it is not worth
++	 * it as this is definitely a slow code path.
++	 */
++	ntfs_attr_put_search_ctx(ctx);
++	unmap_mft_record(base_ni);
++	up_write(&ni->runlist.lock);
++	/*
++	 * Not enough space in the mft record, try to make the attribute
++	 * non-resident and if successful restart the extension process.
++	 */
++	err = ntfs_attr_make_non_resident(ni, attr_len);
++	if (likely(!err))
++		goto retry_extend;
++	/*
++	 * Could not make non-resident.  If this is due to this not being
++	 * permitted for this attribute type or there not being enough space,
++	 * try to make other attributes non-resident.  Otherwise fail.
++	 */
++	if (unlikely(err != -EPERM && err != -ENOSPC)) {
++		/* Only emit errors when the write will fail completely. */
++		read_lock_irqsave(&ni->size_lock, flags);
++		allocated_size = ni->allocated_size;
++		read_unlock_irqrestore(&ni->size_lock, flags);
++		if (start < 0 || start >= allocated_size)
++			ntfs_error(vol->sb, "Cannot extend allocation of "
++					"inode 0x%lx, attribute type 0x%x, "
++					"because the conversion from resident "
++					"to non-resident attribute failed "
++					"with error code %i.", vi->i_ino,
++					(unsigned)le32_to_cpu(ni->type), err);
++		if (err != -ENOMEM)
++			err = -EIO;
++		goto conv_err_out;
++	}
++	/* TODO: Not implemented from here, abort. */
++	read_lock_irqsave(&ni->size_lock, flags);
++	allocated_size = ni->allocated_size;
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	if (start < 0 || start >= allocated_size) {
++		if (err == -ENOSPC)
++			ntfs_error(vol->sb, "Not enough space in the mft "
++					"record/on disk for the non-resident "
++					"attribute value.  This case is not "
++					"implemented yet.");
++		else /* if (err == -EPERM) */
++			ntfs_error(vol->sb, "This attribute type may not be "
++					"non-resident.  This case is not "
++					"implemented yet.");
++	}
++	err = -EOPNOTSUPP;
++	goto conv_err_out;
++#if 0
++	// TODO: Attempt to make other attributes non-resident.
++	if (!err)
++		goto do_resident_extend;
++	/*
++	 * Both the attribute list attribute and the standard information
++	 * attribute must remain in the base inode.  Thus, if this is one of
++	 * these attributes, we have to try to move other attributes out into
++	 * extent mft records instead.
++	 */
++	if (ni->type == AT_ATTRIBUTE_LIST ||
++			ni->type == AT_STANDARD_INFORMATION) {
++		// TODO: Attempt to move other attributes into extent mft
++		// records.
++		err = -EOPNOTSUPP;
++		if (!err)
++			goto do_resident_extend;
++		goto err_out;
++	}
++	// TODO: Attempt to move this attribute to an extent mft record, but
++	// only if it is not already the only attribute in an mft record in
++	// which case there would be nothing to gain.
++	err = -EOPNOTSUPP;
++	if (!err)
++		goto do_resident_extend;
++	/* There is nothing we can do to make enough space. )-: */
++	goto err_out;
++#endif
++do_non_resident_extend:
++	BUG_ON(!NInoNonResident(ni));
++	if (new_alloc_size == allocated_size) {
++		BUG_ON(vcn);
++		goto alloc_done;
++	}
++	/*
++	 * If the data starts after the end of the old allocation, this is a
++	 * $DATA attribute and sparse attributes are enabled on the volume and
++	 * for this inode, then create a sparse region between the old
++	 * allocated size and the start of the data.  Otherwise simply proceed
++	 * with filling the whole space between the old allocated size and the
++	 * new allocated size with clusters.
++	 */
++	if ((start >= 0 && start <= allocated_size) || ni->type != AT_DATA ||
++			!NVolSparseEnabled(vol) || NInoSparseDisabled(ni))
++		goto skip_sparse;
++	// TODO: This is not implemented yet.  We just fill in with real
++	// clusters for now...
++	ntfs_debug("Inserting holes is not-implemented yet.  Falling back to "
++			"allocating real clusters instead.");
++skip_sparse:
++	rl = ni->runlist.rl;
++	if (likely(rl)) {
++		/* Seek to the end of the runlist. */
++		while (rl->length)
++			rl++;
++	}
++	/* If this attribute extent is not mapped, map it now. */
++	if (unlikely(!rl || rl->lcn == LCN_RL_NOT_MAPPED ||
++			(rl->lcn == LCN_ENOENT && rl > ni->runlist.rl &&
++			(rl-1)->lcn == LCN_RL_NOT_MAPPED))) {
++		if (!rl && !allocated_size)
++			goto first_alloc;
++		rl = ntfs_mapping_pairs_decompress(vol, a, ni->runlist.rl);
++		if (IS_ERR(rl)) {
++			err = PTR_ERR(rl);
++			if (start < 0 || start >= allocated_size)
++				ntfs_error(vol->sb, "Cannot extend allocation "
++						"of inode 0x%lx, attribute "
++						"type 0x%x, because the "
++						"mapping of a runlist "
++						"fragment failed with error "
++						"code %i.", vi->i_ino,
++						(unsigned)le32_to_cpu(ni->type),
++						err);
++			if (err != -ENOMEM)
++				err = -EIO;
++			goto err_out;
++		}
++		ni->runlist.rl = rl;
++		/* Seek to the end of the runlist. */
++		while (rl->length)
++			rl++;
++	}
++	/*
++	 * We now know the runlist of the last extent is mapped and @rl is at
++	 * the end of the runlist.  We want to begin allocating clusters
++	 * starting at the last allocated cluster to reduce fragmentation.  If
++	 * there are no valid LCNs in the attribute we let the cluster
++	 * allocator choose the starting cluster.
++	 */
++	/* If the last LCN is a hole or simillar seek back to last real LCN. */
++	while (rl->lcn < 0 && rl > ni->runlist.rl)
++		rl--;
++first_alloc:
++	// FIXME: Need to implement partial allocations so at least part of the
++	// write can be performed when start >= 0.  (Needed for POSIX write(2)
++	// conformance.)
++	rl2 = ntfs_cluster_alloc(vol, allocated_size >> vol->cluster_size_bits,
++			(new_alloc_size - allocated_size) >>
++			vol->cluster_size_bits, (rl && (rl->lcn >= 0)) ?
++			rl->lcn + rl->length : -1, DATA_ZONE, TRUE);
++	if (IS_ERR(rl2)) {
++		err = PTR_ERR(rl2);
++		if (start < 0 || start >= allocated_size)
++			ntfs_error(vol->sb, "Cannot extend allocation of "
++					"inode 0x%lx, attribute type 0x%x, "
++					"because the allocation of clusters "
++					"failed with error code %i.", vi->i_ino,
++					(unsigned)le32_to_cpu(ni->type), err);
++		if (err != -ENOMEM && err != -ENOSPC)
++			err = -EIO;
++		goto err_out;
++	}
++	rl = ntfs_runlists_merge(ni->runlist.rl, rl2);
++	if (IS_ERR(rl)) {
++		err = PTR_ERR(rl);
++		if (start < 0 || start >= allocated_size)
++			ntfs_error(vol->sb, "Cannot extend allocation of "
++					"inode 0x%lx, attribute type 0x%x, "
++					"because the runlist merge failed "
++					"with error code %i.", vi->i_ino,
++					(unsigned)le32_to_cpu(ni->type), err);
++		if (err != -ENOMEM)
++			err = -EIO;
++		if (ntfs_cluster_free_from_rl(vol, rl2)) {
++			ntfs_error(vol->sb, "Failed to release allocated "
++					"cluster(s) in error code path.  Run "
++					"chkdsk to recover the lost "
++					"cluster(s).");
++			NVolSetErrors(vol);
++		}
++		ntfs_free(rl2);
++		goto err_out;
++	}
++	ni->runlist.rl = rl;
++	ntfs_debug("Allocated 0x%llx clusters.", (long long)(new_alloc_size -
++			allocated_size) >> vol->cluster_size_bits);
++	/* Find the runlist element with which the attribute extent starts. */
++	ll = sle64_to_cpu(a->data.non_resident.lowest_vcn);
++	rl2 = ntfs_rl_find_vcn_nolock(rl, ll);
++	BUG_ON(!rl2);
++	BUG_ON(!rl2->length);
++	BUG_ON(rl2->lcn < LCN_HOLE);
++	mp_rebuilt = FALSE;
++	/* Get the size for the new mapping pairs array for this extent. */
++	mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);
++	if (unlikely(mp_size <= 0)) {
++		err = mp_size;
++		if (start < 0 || start >= allocated_size)
++			ntfs_error(vol->sb, "Cannot extend allocation of "
++					"inode 0x%lx, attribute type 0x%x, "
++					"because determining the size for the "
++					"mapping pairs failed with error code "
++					"%i.", vi->i_ino,
++					(unsigned)le32_to_cpu(ni->type), err);
++		err = -EIO;
++		goto undo_alloc;
++	}
++	/* Extend the attribute record to fit the bigger mapping pairs array. */
++	attr_len = le32_to_cpu(a->length);
++	err = ntfs_attr_record_resize(m, a, mp_size +
++			le16_to_cpu(a->data.non_resident.mapping_pairs_offset));
++	if (unlikely(err)) {
++		BUG_ON(err != -ENOSPC);
++		// TODO: Deal with this by moving this extent to a new mft
++		// record or by starting a new extent in a new mft record,
++		// possibly by extending this extent partially and filling it
++		// and creating a new extent for the remainder, or by making
++		// other attributes non-resident and/or by moving other
++		// attributes out of this mft record.
++		if (start < 0 || start >= allocated_size)
++			ntfs_error(vol->sb, "Not enough space in the mft "
++					"record for the extended attribute "
++					"record.  This case is not "
++					"implemented yet.");
++		err = -EOPNOTSUPP;
++		goto undo_alloc;
++	}
++	mp_rebuilt = TRUE;
++	/* Generate the mapping pairs array directly into the attr record. */
++	err = ntfs_mapping_pairs_build(vol, (u8*)a +
++			le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
++			mp_size, rl2, ll, -1, NULL);
++	if (unlikely(err)) {
++		if (start < 0 || start >= allocated_size)
++			ntfs_error(vol->sb, "Cannot extend allocation of "
++					"inode 0x%lx, attribute type 0x%x, "
++					"because building the mapping pairs "
++					"failed with error code %i.", vi->i_ino,
++					(unsigned)le32_to_cpu(ni->type), err);
++		err = -EIO;
++		goto undo_alloc;
++	}
++	/* Update the highest_vcn. */
++	a->data.non_resident.highest_vcn = cpu_to_sle64((new_alloc_size >>
++			vol->cluster_size_bits) - 1);
++	/*
++	 * We now have extended the allocated size of the attribute.  Reflect
++	 * this in the ntfs_inode structure and the attribute record.
++	 */
++	if (a->data.non_resident.lowest_vcn) {
++		/*
++		 * We are not in the first attribute extent, switch to it, but
++		 * first ensure the changes will make it to disk later.
++		 */
++		flush_dcache_mft_record_page(ctx->ntfs_ino);
++		mark_mft_record_dirty(ctx->ntfs_ino);
++		ntfs_attr_reinit_search_ctx(ctx);
++		err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++				CASE_SENSITIVE, 0, NULL, 0, ctx);
++		if (unlikely(err))
++			goto restore_undo_alloc;
++		/* @m is not used any more so no need to set it. */
++		a = ctx->attr;
++	}
++	write_lock_irqsave(&ni->size_lock, flags);
++	ni->allocated_size = new_alloc_size;
++	a->data.non_resident.allocated_size = cpu_to_sle64(new_alloc_size);
++	/*
++	 * FIXME: This would fail if @ni is a directory, $MFT, or an index,
++	 * since those can have sparse/compressed set.  For example can be
++	 * set compressed even though it is not compressed itself and in that
++	 * case the bit means that files are to be created compressed in the
++	 * directory...  At present this is ok as this code is only called for
++	 * regular files, and only for their $DATA attribute(s).
++	 * FIXME: The calculation is wrong if we created a hole above.  For now
++	 * it does not matter as we never create holes.
++	 */
++	if (NInoSparse(ni) || NInoCompressed(ni)) {
++		ni->itype.compressed.size += new_alloc_size - allocated_size;
++		a->data.non_resident.compressed_size =
++				cpu_to_sle64(ni->itype.compressed.size);
++		vi->i_blocks = ni->itype.compressed.size >> 9;
++	} else
++		vi->i_blocks = new_alloc_size >> 9;
++	write_unlock_irqrestore(&ni->size_lock, flags);
++alloc_done:
++	if (new_data_size >= 0) {
++		BUG_ON(new_data_size <
++				sle64_to_cpu(a->data.non_resident.data_size));
++		a->data.non_resident.data_size = cpu_to_sle64(new_data_size);
++	}
++flush_done:
++	/* Ensure the changes make it to disk. */
++	flush_dcache_mft_record_page(ctx->ntfs_ino);
++	mark_mft_record_dirty(ctx->ntfs_ino);
++done:
++	ntfs_attr_put_search_ctx(ctx);
++	unmap_mft_record(base_ni);
++	up_write(&ni->runlist.lock);
++	ntfs_debug("Done, new_allocated_size 0x%llx.",
++			(unsigned long long)new_alloc_size);
++	return new_alloc_size;
++restore_undo_alloc:
++	if (start < 0 || start >= allocated_size)
++		ntfs_error(vol->sb, "Cannot complete extension of allocation "
++				"of inode 0x%lx, attribute type 0x%x, because "
++				"lookup of first attribute extent failed with "
++				"error code %i.", vi->i_ino,
++				(unsigned)le32_to_cpu(ni->type), err);
++	if (err == -ENOENT)
++		err = -EIO;
++	ntfs_attr_reinit_search_ctx(ctx);
++	if (ntfs_attr_lookup(ni->type, ni->name, ni->name_len, CASE_SENSITIVE,
++			allocated_size >> vol->cluster_size_bits, NULL, 0,
++			ctx)) {
++		ntfs_error(vol->sb, "Failed to find last attribute extent of "
++				"attribute in error code path.  Run chkdsk to "
++				"recover.");
++		write_lock_irqsave(&ni->size_lock, flags);
++		ni->allocated_size = new_alloc_size;
++		/*
++		 * FIXME: This would fail if @ni is a directory...  See above.
++		 * FIXME: The calculation is wrong if we created a hole above.
++		 * For now it does not matter as we never create holes.
++		 */
++		if (NInoSparse(ni) || NInoCompressed(ni)) {
++			ni->itype.compressed.size += new_alloc_size -
++					allocated_size;
++			vi->i_blocks = ni->itype.compressed.size >> 9;
++		} else
++			vi->i_blocks = new_alloc_size >> 9;
++		write_unlock_irqrestore(&ni->size_lock, flags);
++		ntfs_attr_put_search_ctx(ctx);
++		unmap_mft_record(base_ni);
++		up_write(&ni->runlist.lock);
++		/*
++		 * The only thing that is now wrong is the allocated size of the
++		 * base attribute extent which chkdsk should be able to fix.
++		 */
++		NVolSetErrors(vol);
++		return err;
++	}
++	ctx->attr->data.non_resident.highest_vcn = cpu_to_sle64(
++			(allocated_size >> vol->cluster_size_bits) - 1);
++undo_alloc:
++	ll = allocated_size >> vol->cluster_size_bits;
++	if (ntfs_cluster_free(ni, ll, -1, ctx) < 0) {
++		ntfs_error(vol->sb, "Failed to release allocated cluster(s) "
++				"in error code path.  Run chkdsk to recover "
++				"the lost cluster(s).");
++		NVolSetErrors(vol);
++	}
++	m = ctx->mrec;
++	a = ctx->attr;
++	/*
++	 * If the runlist truncation fails and/or the search context is no
++	 * longer valid, we cannot resize the attribute record or build the
++	 * mapping pairs array thus we mark the inode bad so that no access to
++	 * the freed clusters can happen.
++	 */
++	if (ntfs_rl_truncate_nolock(vol, &ni->runlist, ll) || IS_ERR(m)) {
++		ntfs_error(vol->sb, "Failed to %s in error code path.  Run "
++				"chkdsk to recover.", IS_ERR(m) ?
++				"restore attribute search context" :
++				"truncate attribute runlist");
++		make_bad_inode(vi);
++		make_bad_inode(VFS_I(base_ni));
++		NVolSetErrors(vol);
++	} else if (mp_rebuilt) {
++		if (ntfs_attr_record_resize(m, a, attr_len)) {
++			ntfs_error(vol->sb, "Failed to restore attribute "
++					"record in error code path.  Run "
++					"chkdsk to recover.");
++			make_bad_inode(vi);
++			make_bad_inode(VFS_I(base_ni));
++			NVolSetErrors(vol);
++		} else /* if (success) */ {
++			if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
++					a->data.non_resident.
++					mapping_pairs_offset), attr_len -
++					le16_to_cpu(a->data.non_resident.
++					mapping_pairs_offset), rl2, ll, -1,
++					NULL)) {
++				ntfs_error(vol->sb, "Failed to restore "
++						"mapping pairs array in error "
++						"code path.  Run chkdsk to "
++						"recover.");
++				make_bad_inode(vi);
++				make_bad_inode(VFS_I(base_ni));
++				NVolSetErrors(vol);
++			}
++			flush_dcache_mft_record_page(ctx->ntfs_ino);
++			mark_mft_record_dirty(ctx->ntfs_ino);
++		}
++	}
++err_out:
++	if (ctx)
++		ntfs_attr_put_search_ctx(ctx);
++	if (m)
++		unmap_mft_record(base_ni);
++	up_write(&ni->runlist.lock);
++conv_err_out:
++	ntfs_debug("Failed.  Returning error code %i.", err);
++	return err;
++}
++
++/**
+  * ntfs_attr_set - fill (a part of) an attribute with a byte
+  * @ni:		ntfs inode describing the attribute to fill
+  * @ofs:	offset inside the attribute at which to start to fill
+@@ -1773,6 +2592,8 @@ int ntfs_attr_set(ntfs_inode *ni, const 
+ 		/* Finally unlock and release the page. */
+ 		unlock_page(page);
+ 		page_cache_release(page);
++		balance_dirty_pages_ratelimited(mapping);
++		cond_resched();
+ 	}
+ 	/* If there is a last partial page, need to do it the slow way. */
+ 	if (end_ofs) {
+diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h
+--- a/fs/ntfs/attrib.h
++++ b/fs/ntfs/attrib.h
+@@ -60,14 +60,15 @@ typedef struct {
+ 	ATTR_RECORD *base_attr;
+ } ntfs_attr_search_ctx;
+ 
+-extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn);
++extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn,
++		ntfs_attr_search_ctx *ctx);
+ extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn);
+ 
+ extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
+ 		const BOOL write_locked);
+ 
+ extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni,
+-		const VCN vcn, const BOOL write_locked);
++		const VCN vcn, ntfs_attr_search_ctx *ctx);
+ 
+ int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
+ 		const u32 name_len, const IGNORE_CASE_BOOL ic,
+@@ -102,7 +103,10 @@ extern int ntfs_attr_record_resize(MFT_R
+ extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
+ 		const u32 new_size);
+ 
+-extern int ntfs_attr_make_non_resident(ntfs_inode *ni);
++extern int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size);
++
++extern s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size,
++		const s64 new_data_size, const s64 data_start);
+ 
+ extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt,
+ 		const u8 val);
+diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
+--- a/fs/ntfs/file.c
++++ b/fs/ntfs/file.c
+@@ -19,11 +19,24 @@
+  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
+-#include <linux/pagemap.h>
+ #include <linux/buffer_head.h>
++#include <linux/pagemap.h>
++#include <linux/pagevec.h>
++#include <linux/sched.h>
++#include <linux/swap.h>
++#include <linux/uio.h>
++#include <linux/writeback.h>
+ 
++#include <asm/page.h>
++#include <asm/uaccess.h>
++
++#include "attrib.h"
++#include "bitmap.h"
+ #include "inode.h"
+ #include "debug.h"
++#include "lcnalloc.h"
++#include "malloc.h"
++#include "mft.h"
+ #include "ntfs.h"
+ 
+ /**
+@@ -56,6 +69,2185 @@ static int ntfs_file_open(struct inode *
+ #ifdef NTFS_RW
+ 
+ /**
++ * ntfs_attr_extend_initialized - extend the initialized size of an attribute
++ * @ni:			ntfs inode of the attribute to extend
++ * @new_init_size:	requested new initialized size in bytes
++ * @cached_page:	store any allocated but unused page here
++ * @lru_pvec:		lru-buffering pagevec of the caller
++ *
++ * Extend the initialized size of an attribute described by the ntfs inode @ni
++ * to @new_init_size bytes.  This involves zeroing any non-sparse space between
++ * the old initialized size and @new_init_size both in the page cache and on
++ * disk (if relevant complete pages are already uptodate in the page cache then
++ * these are simply marked dirty).
++ *
++ * As a side-effect, the file size (vfs inode->i_size) may be incremented as,
++ * in the resident attribute case, it is tied to the initialized size and, in
++ * the non-resident attribute case, it may not fall below the initialized size.
++ *
++ * Note that if the attribute is resident, we do not need to touch the page
++ * cache at all.  This is because if the page cache page is not uptodate we
++ * bring it uptodate later, when doing the write to the mft record since we
++ * then already have the page mapped.  And if the page is uptodate, the
++ * non-initialized region will already have been zeroed when the page was
++ * brought uptodate and the region may in fact already have been overwritten
++ * with new data via mmap() based writes, so we cannot just zero it.  And since
++ * POSIX specifies that the behaviour of resizing a file whilst it is mmap()ped
++ * is unspecified, we choose not to do zeroing and thus we do not need to touch
++ * the page at all.  For a more detailed explanation see ntfs_truncate() in
++ * fs/ntfs/inode.c.
++ *
++ * @cached_page and @lru_pvec are just optimizations for dealing with multiple
++ * pages.
++ *
++ * Return 0 on success and -errno on error.  In the case that an error is
++ * encountered it is possible that the initialized size will already have been
++ * incremented some way towards @new_init_size but it is guaranteed that if
++ * this is the case, the necessary zeroing will also have happened and that all
++ * metadata is self-consistent.
++ *
++ * Locking: i_sem on the vfs inode corrseponsind to the ntfs inode @ni must be
++ *	    held by the caller.
++ */
++static int ntfs_attr_extend_initialized(ntfs_inode *ni, const s64 new_init_size,
++		struct page **cached_page, struct pagevec *lru_pvec)
++{
++	s64 old_init_size;
++	loff_t old_i_size;
++	pgoff_t index, end_index;
++	unsigned long flags;
++	struct inode *vi = VFS_I(ni);
++	ntfs_inode *base_ni;
++	MFT_RECORD *m = NULL;
++	ATTR_RECORD *a;
++	ntfs_attr_search_ctx *ctx = NULL;
++	struct address_space *mapping;
++	struct page *page = NULL;
++	u8 *kattr;
++	int err;
++	u32 attr_len;
++
++	read_lock_irqsave(&ni->size_lock, flags);
++	old_init_size = ni->initialized_size;
++	old_i_size = i_size_read(vi);
++	BUG_ON(new_init_size > ni->allocated_size);
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
++			"old_initialized_size 0x%llx, "
++			"new_initialized_size 0x%llx, i_size 0x%llx.",
++			vi->i_ino, (unsigned)le32_to_cpu(ni->type),
++			(unsigned long long)old_init_size,
++			(unsigned long long)new_init_size, old_i_size);
++	if (!NInoAttr(ni))
++		base_ni = ni;
++	else
++		base_ni = ni->ext.base_ntfs_ino;
++	/* Use goto to reduce indentation and we need the label below anyway. */
++	if (NInoNonResident(ni))
++		goto do_non_resident_extend;
++	BUG_ON(old_init_size != old_i_size);
++	m = map_mft_record(base_ni);
++	if (IS_ERR(m)) {
++		err = PTR_ERR(m);
++		m = NULL;
++		goto err_out;
++	}
++	ctx = ntfs_attr_get_search_ctx(base_ni, m);
++	if (unlikely(!ctx)) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++			CASE_SENSITIVE, 0, NULL, 0, ctx);
++	if (unlikely(err)) {
++		if (err == -ENOENT)
++			err = -EIO;
++		goto err_out;
++	}
++	m = ctx->mrec;
++	a = ctx->attr;
++	BUG_ON(a->non_resident);
++	/* The total length of the attribute value. */
++	attr_len = le32_to_cpu(a->data.resident.value_length);
++	BUG_ON(old_i_size != (loff_t)attr_len);
++	/*
++	 * Do the zeroing in the mft record and update the attribute size in
++	 * the mft record.
++	 */
++	kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
++	memset(kattr + attr_len, 0, new_init_size - attr_len);
++	a->data.resident.value_length = cpu_to_le32((u32)new_init_size);
++	/* Finally, update the sizes in the vfs and ntfs inodes. */
++	write_lock_irqsave(&ni->size_lock, flags);
++	i_size_write(vi, new_init_size);
++	ni->initialized_size = new_init_size;
++	write_unlock_irqrestore(&ni->size_lock, flags);
++	goto done;
++do_non_resident_extend:
++	/*
++	 * If the new initialized size @new_init_size exceeds the current file
++	 * size (vfs inode->i_size), we need to extend the file size to the
++	 * new initialized size.
++	 */
++	if (new_init_size > old_i_size) {
++		m = map_mft_record(base_ni);
++		if (IS_ERR(m)) {
++			err = PTR_ERR(m);
++			m = NULL;
++			goto err_out;
++		}
++		ctx = ntfs_attr_get_search_ctx(base_ni, m);
++		if (unlikely(!ctx)) {
++			err = -ENOMEM;
++			goto err_out;
++		}
++		err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++				CASE_SENSITIVE, 0, NULL, 0, ctx);
++		if (unlikely(err)) {
++			if (err == -ENOENT)
++				err = -EIO;
++			goto err_out;
++		}
++		m = ctx->mrec;
++		a = ctx->attr;
++		BUG_ON(!a->non_resident);
++		BUG_ON(old_i_size != (loff_t)
++				sle64_to_cpu(a->data.non_resident.data_size));
++		a->data.non_resident.data_size = cpu_to_sle64(new_init_size);
++		flush_dcache_mft_record_page(ctx->ntfs_ino);
++		mark_mft_record_dirty(ctx->ntfs_ino);
++		/* Update the file size in the vfs inode. */
++		i_size_write(vi, new_init_size);
++		ntfs_attr_put_search_ctx(ctx);
++		ctx = NULL;
++		unmap_mft_record(base_ni);
++		m = NULL;
++	}
++	mapping = vi->i_mapping;
++	index = old_init_size >> PAGE_CACHE_SHIFT;
++	end_index = (new_init_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
++	do {
++		/*
++		 * Read the page.  If the page is not present, this will zero
++		 * the uninitialized regions for us.
++		 */
++		page = read_cache_page(mapping, index,
++				(filler_t*)mapping->a_ops->readpage, NULL);
++		if (IS_ERR(page)) {
++			err = PTR_ERR(page);
++			goto init_err_out;
++		}
++		wait_on_page_locked(page);
++		if (unlikely(!PageUptodate(page) || PageError(page))) {
++			page_cache_release(page);
++			err = -EIO;
++			goto init_err_out;
++		}
++		/*
++		 * Update the initialized size in the ntfs inode.  This is
++		 * enough to make ntfs_writepage() work.
++		 */
++		write_lock_irqsave(&ni->size_lock, flags);
++		ni->initialized_size = (index + 1) << PAGE_CACHE_SHIFT;
++		if (ni->initialized_size > new_init_size)
++			ni->initialized_size = new_init_size;
++		write_unlock_irqrestore(&ni->size_lock, flags);
++		/* Set the page dirty so it gets written out. */
++		set_page_dirty(page);
++		page_cache_release(page);
++		/*
++		 * Play nice with the vm and the rest of the system.  This is
++		 * very much needed as we can potentially be modifying the
++		 * initialised size from a very small value to a really huge
++		 * value, e.g.
++		 *	f = open(somefile, O_TRUNC);
++		 *	truncate(f, 10GiB);
++		 *	seek(f, 10GiB);
++		 *	write(f, 1);
++		 * And this would mean we would be marking dirty hundreds of
++		 * thousands of pages or as in the above example more than
++		 * two and a half million pages!
++		 *
++		 * TODO: For sparse pages could optimize this workload by using
++		 * the FsMisc / MiscFs page bit as a "PageIsSparse" bit.  This
++		 * would be set in readpage for sparse pages and here we would
++		 * not need to mark dirty any pages which have this bit set.
++		 * The only caveat is that we have to clear the bit everywhere
++		 * where we allocate any clusters that lie in the page or that
++		 * contain the page.
++		 *
++		 * TODO: An even greater optimization would be for us to only
++		 * call readpage() on pages which are not in sparse regions as
++		 * determined from the runlist.  This would greatly reduce the
++		 * number of pages we read and make dirty in the case of sparse
++		 * files.
++		 */
++		balance_dirty_pages_ratelimited(mapping);
++		cond_resched();
++	} while (++index < end_index);
++	read_lock_irqsave(&ni->size_lock, flags);
++	BUG_ON(ni->initialized_size != new_init_size);
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	/* Now bring in sync the initialized_size in the mft record. */
++	m = map_mft_record(base_ni);
++	if (IS_ERR(m)) {
++		err = PTR_ERR(m);
++		m = NULL;
++		goto init_err_out;
++	}
++	ctx = ntfs_attr_get_search_ctx(base_ni, m);
++	if (unlikely(!ctx)) {
++		err = -ENOMEM;
++		goto init_err_out;
++	}
++	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++			CASE_SENSITIVE, 0, NULL, 0, ctx);
++	if (unlikely(err)) {
++		if (err == -ENOENT)
++			err = -EIO;
++		goto init_err_out;
++	}
++	m = ctx->mrec;
++	a = ctx->attr;
++	BUG_ON(!a->non_resident);
++	a->data.non_resident.initialized_size = cpu_to_sle64(new_init_size);
++done:
++	flush_dcache_mft_record_page(ctx->ntfs_ino);
++	mark_mft_record_dirty(ctx->ntfs_ino);
++	if (ctx)
++		ntfs_attr_put_search_ctx(ctx);
++	if (m)
++		unmap_mft_record(base_ni);
++	ntfs_debug("Done, initialized_size 0x%llx, i_size 0x%llx.",
++			(unsigned long long)new_init_size, i_size_read(vi));
++	return 0;
++init_err_out:
++	write_lock_irqsave(&ni->size_lock, flags);
++	ni->initialized_size = old_init_size;
++	write_unlock_irqrestore(&ni->size_lock, flags);
++err_out:
++	if (ctx)
++		ntfs_attr_put_search_ctx(ctx);
++	if (m)
++		unmap_mft_record(base_ni);
++	ntfs_debug("Failed.  Returning error code %i.", err);
++	return err;
++}
++
++/**
++ * ntfs_fault_in_pages_readable -
++ *
++ * Fault a number of userspace pages into pagetables.
++ *
++ * Unlike include/linux/pagemap.h::fault_in_pages_readable(), this one copes
++ * with more than two userspace pages as well as handling the single page case
++ * elegantly.
++ *
++ * If you find this difficult to understand, then think of the while loop being
++ * the following code, except that we do without the integer variable ret:
++ *
++ *	do {
++ *		ret = __get_user(c, uaddr);
++ *		uaddr += PAGE_SIZE;
++ *	} while (!ret && uaddr < end);
++ *
++ * Note, the final __get_user() may well run out-of-bounds of the user buffer,
++ * but _not_ out-of-bounds of the page the user buffer belongs to, and since
++ * this is only a read and not a write, and since it is still in the same page,
++ * it should not matter and this makes the code much simpler.
++ */
++static inline void ntfs_fault_in_pages_readable(const char __user *uaddr,
++		int bytes)
++{
++	const char __user *end;
++	volatile char c;
++
++	/* Set @end to the first byte outside the last page we care about. */
++	end = (const char __user*)PAGE_ALIGN((ptrdiff_t __user)uaddr + bytes);
++
++	while (!__get_user(c, uaddr) && (uaddr += PAGE_SIZE, uaddr < end))
++		;
++}
++
++/**
++ * ntfs_fault_in_pages_readable_iovec -
++ *
++ * Same as ntfs_fault_in_pages_readable() but operates on an array of iovecs.
++ */
++static inline void ntfs_fault_in_pages_readable_iovec(const struct iovec *iov,
++		size_t iov_ofs, int bytes)
++{
++	do {
++		const char __user *buf;
++		unsigned len;
++
++		buf = iov->iov_base + iov_ofs;
++		len = iov->iov_len - iov_ofs;
++		if (len > bytes)
++			len = bytes;
++		ntfs_fault_in_pages_readable(buf, len);
++		bytes -= len;
++		iov++;
++		iov_ofs = 0;
++	} while (bytes);
++}
++
++/**
++ * __ntfs_grab_cache_pages - obtain a number of locked pages
++ * @mapping:	address space mapping from which to obtain page cache pages
++ * @index:	starting index in @mapping at which to begin obtaining pages
++ * @nr_pages:	number of page cache pages to obtain
++ * @pages:	array of pages in which to return the obtained page cache pages
++ * @cached_page: allocated but as yet unused page
++ * @lru_pvec:	lru-buffering pagevec of caller
++ *
++ * Obtain @nr_pages locked page cache pages from the mapping @maping and
++ * starting at index @index.
++ *
++ * If a page is newly created, increment its refcount and add it to the
++ * caller's lru-buffering pagevec @lru_pvec.
++ *
++ * This is the same as mm/filemap.c::__grab_cache_page(), except that @nr_pages
++ * are obtained at once instead of just one page and that 0 is returned on
++ * success and -errno on error.
++ *
++ * Note, the page locks are obtained in ascending page index order.
++ */
++static inline int __ntfs_grab_cache_pages(struct address_space *mapping,
++		pgoff_t index, const unsigned nr_pages, struct page **pages,
++		struct page **cached_page, struct pagevec *lru_pvec)
++{
++	int err, nr;
++
++	BUG_ON(!nr_pages);
++	err = nr = 0;
++	do {
++		pages[nr] = find_lock_page(mapping, index);
++		if (!pages[nr]) {
++			if (!*cached_page) {
++				*cached_page = page_cache_alloc(mapping);
++				if (unlikely(!*cached_page)) {
++					err = -ENOMEM;
++					goto err_out;
++				}
++			}
++			err = add_to_page_cache(*cached_page, mapping, index,
++					GFP_KERNEL);
++			if (unlikely(err)) {
++				if (err == -EEXIST)
++					continue;
++				goto err_out;
++			}
++			pages[nr] = *cached_page;
++			page_cache_get(*cached_page);
++			if (unlikely(!pagevec_add(lru_pvec, *cached_page)))
++				__pagevec_lru_add(lru_pvec);
++			*cached_page = NULL;
++		}
++		index++;
++		nr++;
++	} while (nr < nr_pages);
++out:
++	return err;
++err_out:
++	while (nr > 0) {
++		unlock_page(pages[--nr]);
++		page_cache_release(pages[nr]);
++	}
++	goto out;
++}
++
++static inline int ntfs_submit_bh_for_read(struct buffer_head *bh)
++{
++	lock_buffer(bh);
++	get_bh(bh);
++	bh->b_end_io = end_buffer_read_sync;
++	return submit_bh(READ, bh);
++}
++
++/**
++ * ntfs_prepare_pages_for_non_resident_write - prepare pages for receiving data
++ * @pages:	array of destination pages
++ * @nr_pages:	number of pages in @pages
++ * @pos:	byte position in file at which the write begins
++ * @bytes:	number of bytes to be written
++ *
++ * This is called for non-resident attributes from ntfs_file_buffered_write()
++ * with i_sem held on the inode (@pages[0]->mapping->host).  There are
++ * @nr_pages pages in @pages which are locked but not kmap()ped.  The source
++ * data has not yet been copied into the @pages.
++ * 
++ * Need to fill any holes with actual clusters, allocate buffers if necessary,
++ * ensure all the buffers are mapped, and bring uptodate any buffers that are
++ * only partially being written to.
++ *
++ * If @nr_pages is greater than one, we are guaranteed that the cluster size is
++ * greater than PAGE_CACHE_SIZE, that all pages in @pages are entirely inside
++ * the same cluster and that they are the entirety of that cluster, and that
++ * the cluster is sparse, i.e. we need to allocate a cluster to fill the hole.
++ *
++ * i_size is not to be modified yet.
++ *
++ * Return 0 on success or -errno on error.
++ */
++static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
++		unsigned nr_pages, s64 pos, size_t bytes)
++{
++	VCN vcn, highest_vcn = 0, cpos, cend, bh_cpos, bh_cend;
++	LCN lcn;
++	s64 bh_pos, vcn_len, end, initialized_size;
++	sector_t lcn_block;
++	struct page *page;
++	struct inode *vi;
++	ntfs_inode *ni, *base_ni = NULL;
++	ntfs_volume *vol;
++	runlist_element *rl, *rl2;
++	struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
++	ntfs_attr_search_ctx *ctx = NULL;
++	MFT_RECORD *m = NULL;
++	ATTR_RECORD *a = NULL;
++	unsigned long flags;
++	u32 attr_rec_len = 0;
++	unsigned blocksize, u;
++	int err, mp_size;
++	BOOL rl_write_locked, was_hole, is_retry;
++	unsigned char blocksize_bits;
++	struct {
++		u8 runlist_merged:1;
++		u8 mft_attr_mapped:1;
++		u8 mp_rebuilt:1;
++		u8 attr_switched:1;
++	} status = { 0, 0, 0, 0 };
++
++	BUG_ON(!nr_pages);
++	BUG_ON(!pages);
++	BUG_ON(!*pages);
++	vi = pages[0]->mapping->host;
++	ni = NTFS_I(vi);
++	vol = ni->vol;
++	ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page "
++			"index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.",
++			vi->i_ino, ni->type, pages[0]->index, nr_pages,
++			(long long)pos, bytes);
++	blocksize_bits = vi->i_blkbits;
++	blocksize = 1 << blocksize_bits;
++	u = 0;
++	do {
++		struct page *page = pages[u];
++		/*
++		 * create_empty_buffers() will create uptodate/dirty buffers if
++		 * the page is uptodate/dirty.
++		 */
++		if (!page_has_buffers(page)) {
++			create_empty_buffers(page, blocksize, 0);
++			if (unlikely(!page_has_buffers(page)))
++				return -ENOMEM;
++		}
++	} while (++u < nr_pages);
++	rl_write_locked = FALSE;
++	rl = NULL;
++	err = 0;
++	vcn = lcn = -1;
++	vcn_len = 0;
++	lcn_block = -1;
++	was_hole = FALSE;
++	cpos = pos >> vol->cluster_size_bits;
++	end = pos + bytes;
++	cend = (end + vol->cluster_size - 1) >> vol->cluster_size_bits;
++	/*
++	 * Loop over each page and for each page over each buffer.  Use goto to
++	 * reduce indentation.
++	 */
++	u = 0;
++do_next_page:
++	page = pages[u];
++	bh_pos = (s64)page->index << PAGE_CACHE_SHIFT;
++	bh = head = page_buffers(page);
++	do {
++		VCN cdelta;
++		s64 bh_end;
++		unsigned bh_cofs;
++
++		/* Clear buffer_new on all buffers to reinitialise state. */
++		if (buffer_new(bh))
++			clear_buffer_new(bh);
++		bh_end = bh_pos + blocksize;
++		bh_cpos = bh_pos >> vol->cluster_size_bits;
++		bh_cofs = bh_pos & vol->cluster_size_mask;
++		if (buffer_mapped(bh)) {
++			/*
++			 * The buffer is already mapped.  If it is uptodate,
++			 * ignore it.
++			 */
++			if (buffer_uptodate(bh))
++				continue;
++			/*
++			 * The buffer is not uptodate.  If the page is uptodate
++			 * set the buffer uptodate and otherwise ignore it.
++			 */
++			if (PageUptodate(page)) {
++				set_buffer_uptodate(bh);
++				continue;
++			}
++			/*
++			 * Neither the page nor the buffer are uptodate.  If
++			 * the buffer is only partially being written to, we
++			 * need to read it in before the write, i.e. now.
++			 */
++			if ((bh_pos < pos && bh_end > pos) ||
++					(bh_pos < end && bh_end > end)) {
++				/*
++				 * If the buffer is fully or partially within
++				 * the initialized size, do an actual read.
++				 * Otherwise, simply zero the buffer.
++				 */
++				read_lock_irqsave(&ni->size_lock, flags);
++				initialized_size = ni->initialized_size;
++				read_unlock_irqrestore(&ni->size_lock, flags);
++				if (bh_pos < initialized_size) {
++					ntfs_submit_bh_for_read(bh);
++					*wait_bh++ = bh;
++				} else {
++					u8 *kaddr = kmap_atomic(page, KM_USER0);
++					memset(kaddr + bh_offset(bh), 0,
++							blocksize);
++					kunmap_atomic(kaddr, KM_USER0);
++					flush_dcache_page(page);
++					set_buffer_uptodate(bh);
++				}
++			}
++			continue;
++		}
++		/* Unmapped buffer.  Need to map it. */
++		bh->b_bdev = vol->sb->s_bdev;
++		/*
++		 * If the current buffer is in the same clusters as the map
++		 * cache, there is no need to check the runlist again.  The
++		 * map cache is made up of @vcn, which is the first cached file
++		 * cluster, @vcn_len which is the number of cached file
++		 * clusters, @lcn is the device cluster corresponding to @vcn,
++		 * and @lcn_block is the block number corresponding to @lcn.
++		 */
++		cdelta = bh_cpos - vcn;
++		if (likely(!cdelta || (cdelta > 0 && cdelta < vcn_len))) {
++map_buffer_cached:
++			BUG_ON(lcn < 0);
++			bh->b_blocknr = lcn_block +
++					(cdelta << (vol->cluster_size_bits -
++					blocksize_bits)) +
++					(bh_cofs >> blocksize_bits);
++			set_buffer_mapped(bh);
++			/*
++			 * If the page is uptodate so is the buffer.  If the
++			 * buffer is fully outside the write, we ignore it if
++			 * it was already allocated and we mark it dirty so it
++			 * gets written out if we allocated it.  On the other
++			 * hand, if we allocated the buffer but we are not
++			 * marking it dirty we set buffer_new so we can do
++			 * error recovery.
++			 */
++			if (PageUptodate(page)) {
++				if (!buffer_uptodate(bh))
++					set_buffer_uptodate(bh);
++				if (unlikely(was_hole)) {
++					/* We allocated the buffer. */
++					unmap_underlying_metadata(bh->b_bdev,
++							bh->b_blocknr);
++					if (bh_end <= pos || bh_pos >= end)
++						mark_buffer_dirty(bh);
++					else
++						set_buffer_new(bh);
++				}
++				continue;
++			}
++			/* Page is _not_ uptodate. */
++			if (likely(!was_hole)) {
++				/*
++				 * Buffer was already allocated.  If it is not
++				 * uptodate and is only partially being written
++				 * to, we need to read it in before the write,
++				 * i.e. now.
++				 */
++				if (!buffer_uptodate(bh) && bh_pos < end &&
++						bh_end > pos &&
++						(bh_pos < pos ||
++						bh_end > end)) {
++					/*
++					 * If the buffer is fully or partially
++					 * within the initialized size, do an
++					 * actual read.  Otherwise, simply zero
++					 * the buffer.
++					 */
++					read_lock_irqsave(&ni->size_lock,
++							flags);
++					initialized_size = ni->initialized_size;
++					read_unlock_irqrestore(&ni->size_lock,
++							flags);
++					if (bh_pos < initialized_size) {
++						ntfs_submit_bh_for_read(bh);
++						*wait_bh++ = bh;
++					} else {
++						u8 *kaddr = kmap_atomic(page,
++								KM_USER0);
++						memset(kaddr + bh_offset(bh),
++								0, blocksize);
++						kunmap_atomic(kaddr, KM_USER0);
++						flush_dcache_page(page);
++						set_buffer_uptodate(bh);
++					}
++				}
++				continue;
++			}
++			/* We allocated the buffer. */
++			unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
++			/*
++			 * If the buffer is fully outside the write, zero it,
++			 * set it uptodate, and mark it dirty so it gets
++			 * written out.  If it is partially being written to,
++			 * zero region surrounding the write but leave it to
++			 * commit write to do anything else.  Finally, if the
++			 * buffer is fully being overwritten, do nothing.
++			 */
++			if (bh_end <= pos || bh_pos >= end) {
++				if (!buffer_uptodate(bh)) {
++					u8 *kaddr = kmap_atomic(page, KM_USER0);
++					memset(kaddr + bh_offset(bh), 0,
++							blocksize);
++					kunmap_atomic(kaddr, KM_USER0);
++					flush_dcache_page(page);
++					set_buffer_uptodate(bh);
++				}
++				mark_buffer_dirty(bh);
++				continue;
++			}
++			set_buffer_new(bh);
++			if (!buffer_uptodate(bh) &&
++					(bh_pos < pos || bh_end > end)) {
++				u8 *kaddr;
++				unsigned pofs;
++					
++				kaddr = kmap_atomic(page, KM_USER0);
++				if (bh_pos < pos) {
++					pofs = bh_pos & ~PAGE_CACHE_MASK;
++					memset(kaddr + pofs, 0, pos - bh_pos);
++				}
++				if (bh_end > end) {
++					pofs = end & ~PAGE_CACHE_MASK;
++					memset(kaddr + pofs, 0, bh_end - end);
++				}
++				kunmap_atomic(kaddr, KM_USER0);
++				flush_dcache_page(page);
++			}
++			continue;
++		}
++		/*
++		 * Slow path: this is the first buffer in the cluster.  If it
++		 * is outside allocated size and is not uptodate, zero it and
++		 * set it uptodate.
++		 */
++		read_lock_irqsave(&ni->size_lock, flags);
++		initialized_size = ni->allocated_size;
++		read_unlock_irqrestore(&ni->size_lock, flags);
++		if (bh_pos > initialized_size) {
++			if (PageUptodate(page)) {
++				if (!buffer_uptodate(bh))
++					set_buffer_uptodate(bh);
++			} else if (!buffer_uptodate(bh)) {
++				u8 *kaddr = kmap_atomic(page, KM_USER0);
++				memset(kaddr + bh_offset(bh), 0, blocksize);
++				kunmap_atomic(kaddr, KM_USER0);
++				flush_dcache_page(page);
++				set_buffer_uptodate(bh);
++			}
++			continue;
++		}
++		is_retry = FALSE;
++		if (!rl) {
++			down_read(&ni->runlist.lock);
++retry_remap:
++			rl = ni->runlist.rl;
++		}
++		if (likely(rl != NULL)) {
++			/* Seek to element containing target cluster. */
++			while (rl->length && rl[1].vcn <= bh_cpos)
++				rl++;
++			lcn = ntfs_rl_vcn_to_lcn(rl, bh_cpos);
++			if (likely(lcn >= 0)) {
++				/*
++				 * Successful remap, setup the map cache and
++				 * use that to deal with the buffer.
++				 */
++				was_hole = FALSE;
++				vcn = bh_cpos;
++				vcn_len = rl[1].vcn - vcn;
++				lcn_block = lcn << (vol->cluster_size_bits -
++						blocksize_bits);
++				cdelta = 0;
++				/*
++				 * If the number of remaining clusters touched
++				 * by the write is smaller or equal to the
++				 * number of cached clusters, unlock the
++				 * runlist as the map cache will be used from
++				 * now on.
++				 */
++				if (likely(vcn + vcn_len >= cend)) {
++					if (rl_write_locked) {
++						up_write(&ni->runlist.lock);
++						rl_write_locked = FALSE;
++					} else
++						up_read(&ni->runlist.lock);
++					rl = NULL;
++				}
++				goto map_buffer_cached;
++			}
++		} else
++			lcn = LCN_RL_NOT_MAPPED;
++		/*
++		 * If it is not a hole and not out of bounds, the runlist is
++		 * probably unmapped so try to map it now.
++		 */
++		if (unlikely(lcn != LCN_HOLE && lcn != LCN_ENOENT)) {
++			if (likely(!is_retry && lcn == LCN_RL_NOT_MAPPED)) {
++				/* Attempt to map runlist. */
++				if (!rl_write_locked) {
++					/*
++					 * We need the runlist locked for
++					 * writing, so if it is locked for
++					 * reading relock it now and retry in
++					 * case it changed whilst we dropped
++					 * the lock.
++					 */
++					up_read(&ni->runlist.lock);
++					down_write(&ni->runlist.lock);
++					rl_write_locked = TRUE;
++					goto retry_remap;
++				}
++				err = ntfs_map_runlist_nolock(ni, bh_cpos,
++						NULL);
++				if (likely(!err)) {
++					is_retry = TRUE;
++					goto retry_remap;
++				}
++				/*
++				 * If @vcn is out of bounds, pretend @lcn is
++				 * LCN_ENOENT.  As long as the buffer is out
++				 * of bounds this will work fine.
++				 */
++				if (err == -ENOENT) {
++					lcn = LCN_ENOENT;
++					err = 0;
++					goto rl_not_mapped_enoent;
++				}
++			} else
++				err = -EIO;
++			/* Failed to map the buffer, even after retrying. */
++			bh->b_blocknr = -1;
++			ntfs_error(vol->sb, "Failed to write to inode 0x%lx, "
++					"attribute type 0x%x, vcn 0x%llx, "
++					"vcn offset 0x%x, because its "
++					"location on disk could not be "
++					"determined%s (error code %i).",
++					ni->mft_no, ni->type,
++					(unsigned long long)bh_cpos,
++					(unsigned)bh_pos &
++					vol->cluster_size_mask,
++					is_retry ? " even after retrying" : "",
++					err);
++			break;
++		}
++rl_not_mapped_enoent:
++		/*
++		 * The buffer is in a hole or out of bounds.  We need to fill
++		 * the hole, unless the buffer is in a cluster which is not
++		 * touched by the write, in which case we just leave the buffer
++		 * unmapped.  This can only happen when the cluster size is
++		 * less than the page cache size.
++		 */
++		if (unlikely(vol->cluster_size < PAGE_CACHE_SIZE)) {
++			bh_cend = (bh_end + vol->cluster_size - 1) >>
++					vol->cluster_size_bits;
++			if ((bh_cend <= cpos || bh_cpos >= cend)) {
++				bh->b_blocknr = -1;
++				/*
++				 * If the buffer is uptodate we skip it.  If it
++				 * is not but the page is uptodate, we can set
++				 * the buffer uptodate.  If the page is not
++				 * uptodate, we can clear the buffer and set it
++				 * uptodate.  Whether this is worthwhile is
++				 * debatable and this could be removed.
++				 */
++				if (PageUptodate(page)) {
++					if (!buffer_uptodate(bh))
++						set_buffer_uptodate(bh);
++				} else if (!buffer_uptodate(bh)) {
++					u8 *kaddr = kmap_atomic(page, KM_USER0);
++					memset(kaddr + bh_offset(bh), 0,
++							blocksize);
++					kunmap_atomic(kaddr, KM_USER0);
++					flush_dcache_page(page);
++					set_buffer_uptodate(bh);
++				}
++				continue;
++			}
++		}
++		/*
++		 * Out of bounds buffer is invalid if it was not really out of
++		 * bounds.
++		 */
++		BUG_ON(lcn != LCN_HOLE);
++		/*
++		 * We need the runlist locked for writing, so if it is locked
++		 * for reading relock it now and retry in case it changed
++		 * whilst we dropped the lock.
++		 */
++		BUG_ON(!rl);
++		if (!rl_write_locked) {
++			up_read(&ni->runlist.lock);
++			down_write(&ni->runlist.lock);
++			rl_write_locked = TRUE;
++			goto retry_remap;
++		}
++		/* Find the previous last allocated cluster. */
++		BUG_ON(rl->lcn != LCN_HOLE);
++		lcn = -1;
++		rl2 = rl;
++		while (--rl2 >= ni->runlist.rl) {
++			if (rl2->lcn >= 0) {
++				lcn = rl2->lcn + rl2->length;
++				break;
++			}
++		}
++		rl2 = ntfs_cluster_alloc(vol, bh_cpos, 1, lcn, DATA_ZONE,
++				FALSE);
++		if (IS_ERR(rl2)) {
++			err = PTR_ERR(rl2);
++			ntfs_debug("Failed to allocate cluster, error code %i.",
++					err);
++			break;
++		}
++		lcn = rl2->lcn;
++		rl = ntfs_runlists_merge(ni->runlist.rl, rl2);
++		if (IS_ERR(rl)) {
++			err = PTR_ERR(rl);
++			if (err != -ENOMEM)
++				err = -EIO;
++			if (ntfs_cluster_free_from_rl(vol, rl2)) {
++				ntfs_error(vol->sb, "Failed to release "
++						"allocated cluster in error "
++						"code path.  Run chkdsk to "
++						"recover the lost cluster.");
++				NVolSetErrors(vol);
++			}
++			ntfs_free(rl2);
++			break;
++		}
++		ni->runlist.rl = rl;
++		status.runlist_merged = 1;
++		ntfs_debug("Allocated cluster, lcn 0x%llx.", lcn);
++		/* Map and lock the mft record and get the attribute record. */
++		if (!NInoAttr(ni))
++			base_ni = ni;
++		else
++			base_ni = ni->ext.base_ntfs_ino;
++		m = map_mft_record(base_ni);
++		if (IS_ERR(m)) {
++			err = PTR_ERR(m);
++			break;
++		}
++		ctx = ntfs_attr_get_search_ctx(base_ni, m);
++		if (unlikely(!ctx)) {
++			err = -ENOMEM;
++			unmap_mft_record(base_ni);
++			break;
++		}
++		status.mft_attr_mapped = 1;
++		err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++				CASE_SENSITIVE, bh_cpos, NULL, 0, ctx);
++		if (unlikely(err)) {
++			if (err == -ENOENT)
++				err = -EIO;
++			break;
++		}
++		m = ctx->mrec;
++		a = ctx->attr;
++		/*
++		 * Find the runlist element with which the attribute extent
++		 * starts.  Note, we cannot use the _attr_ version because we
++		 * have mapped the mft record.  That is ok because we know the
++		 * runlist fragment must be mapped already to have ever gotten
++		 * here, so we can just use the _rl_ version.
++		 */
++		vcn = sle64_to_cpu(a->data.non_resident.lowest_vcn);
++		rl2 = ntfs_rl_find_vcn_nolock(rl, vcn);
++		BUG_ON(!rl2);
++		BUG_ON(!rl2->length);
++		BUG_ON(rl2->lcn < LCN_HOLE);
++		highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
++		/*
++		 * If @highest_vcn is zero, calculate the real highest_vcn
++		 * (which can really be zero).
++		 */
++		if (!highest_vcn)
++			highest_vcn = (sle64_to_cpu(
++					a->data.non_resident.allocated_size) >>
++					vol->cluster_size_bits) - 1;
++		/*
++		 * Determine the size of the mapping pairs array for the new
++		 * extent, i.e. the old extent with the hole filled.
++		 */
++		mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, vcn,
++				highest_vcn);
++		if (unlikely(mp_size <= 0)) {
++			if (!(err = mp_size))
++				err = -EIO;
++			ntfs_debug("Failed to get size for mapping pairs "
++					"array, error code %i.", err);
++			break;
++		}
++		/*
++		 * Resize the attribute record to fit the new mapping pairs
++		 * array.
++		 */
++		attr_rec_len = le32_to_cpu(a->length);
++		err = ntfs_attr_record_resize(m, a, mp_size + le16_to_cpu(
++				a->data.non_resident.mapping_pairs_offset));
++		if (unlikely(err)) {
++			BUG_ON(err != -ENOSPC);
++			// TODO: Deal with this by using the current attribute
++			// and fill it with as much of the mapping pairs
++			// array as possible.  Then loop over each attribute
++			// extent rewriting the mapping pairs arrays as we go
++			// along and if when we reach the end we have not
++			// enough space, try to resize the last attribute
++			// extent and if even that fails, add a new attribute
++			// extent.
++			// We could also try to resize at each step in the hope
++			// that we will not need to rewrite every single extent.
++			// Note, we may need to decompress some extents to fill
++			// the runlist as we are walking the extents...
++			ntfs_error(vol->sb, "Not enough space in the mft "
++					"record for the extended attribute "
++					"record.  This case is not "
++					"implemented yet.");
++			err = -EOPNOTSUPP;
++			break ;
++		}
++		status.mp_rebuilt = 1;
++		/*
++		 * Generate the mapping pairs array directly into the attribute
++		 * record.
++		 */
++		err = ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
++				a->data.non_resident.mapping_pairs_offset),
++				mp_size, rl2, vcn, highest_vcn, NULL);
++		if (unlikely(err)) {
++			ntfs_error(vol->sb, "Cannot fill hole in inode 0x%lx, "
++					"attribute type 0x%x, because building "
++					"the mapping pairs failed with error "
++					"code %i.", vi->i_ino,
++					(unsigned)le32_to_cpu(ni->type), err);
++			err = -EIO;
++			break;
++		}
++		/* Update the highest_vcn but only if it was not set. */
++		if (unlikely(!a->data.non_resident.highest_vcn))
++			a->data.non_resident.highest_vcn =
++					cpu_to_sle64(highest_vcn);
++		/*
++		 * If the attribute is sparse/compressed, update the compressed
++		 * size in the ntfs_inode structure and the attribute record.
++		 */
++		if (likely(NInoSparse(ni) || NInoCompressed(ni))) {
++			/*
++			 * If we are not in the first attribute extent, switch
++			 * to it, but first ensure the changes will make it to
++			 * disk later.
++			 */
++			if (a->data.non_resident.lowest_vcn) {
++				flush_dcache_mft_record_page(ctx->ntfs_ino);
++				mark_mft_record_dirty(ctx->ntfs_ino);
++				ntfs_attr_reinit_search_ctx(ctx);
++				err = ntfs_attr_lookup(ni->type, ni->name,
++						ni->name_len, CASE_SENSITIVE,
++						0, NULL, 0, ctx);
++				if (unlikely(err)) {
++					status.attr_switched = 1;
++					break;
++				}
++				/* @m is not used any more so do not set it. */
++				a = ctx->attr;
++			}
++			write_lock_irqsave(&ni->size_lock, flags);
++			ni->itype.compressed.size += vol->cluster_size;
++			a->data.non_resident.compressed_size =
++					cpu_to_sle64(ni->itype.compressed.size);
++			write_unlock_irqrestore(&ni->size_lock, flags);
++		}
++		/* Ensure the changes make it to disk. */
++		flush_dcache_mft_record_page(ctx->ntfs_ino);
++		mark_mft_record_dirty(ctx->ntfs_ino);
++		ntfs_attr_put_search_ctx(ctx);
++		unmap_mft_record(base_ni);
++		/* Successfully filled the hole. */
++		status.runlist_merged = 0;
++		status.mft_attr_mapped = 0;
++		status.mp_rebuilt = 0;
++		/* Setup the map cache and use that to deal with the buffer. */
++		was_hole = TRUE;
++		vcn = bh_cpos;
++		vcn_len = 1;
++		lcn_block = lcn << (vol->cluster_size_bits - blocksize_bits);
++		cdelta = 0;
++		/*
++		 * If the number of remaining clusters in the @pages is smaller
++		 * or equal to the number of cached clusters, unlock the
++		 * runlist as the map cache will be used from now on.
++		 */
++		if (likely(vcn + vcn_len >= cend)) {
++			up_write(&ni->runlist.lock);
++			rl_write_locked = FALSE;
++			rl = NULL;
++		}
++		goto map_buffer_cached;
++	} while (bh_pos += blocksize, (bh = bh->b_this_page) != head);
++	/* If there are no errors, do the next page. */
++	if (likely(!err && ++u < nr_pages))
++		goto do_next_page;
++	/* If there are no errors, release the runlist lock if we took it. */
++	if (likely(!err)) {
++		if (unlikely(rl_write_locked)) {
++			up_write(&ni->runlist.lock);
++			rl_write_locked = FALSE;
++		} else if (unlikely(rl))
++			up_read(&ni->runlist.lock);
++		rl = NULL;
++	}
++	/* If we issued read requests, let them complete. */
++	read_lock_irqsave(&ni->size_lock, flags);
++	initialized_size = ni->initialized_size;
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	while (wait_bh > wait) {
++		bh = *--wait_bh;
++		wait_on_buffer(bh);
++		if (likely(buffer_uptodate(bh))) {
++			page = bh->b_page;
++			bh_pos = ((s64)page->index << PAGE_CACHE_SHIFT) +
++					bh_offset(bh);
++			/*
++			 * If the buffer overflows the initialized size, need
++			 * to zero the overflowing region.
++			 */
++			if (unlikely(bh_pos + blocksize > initialized_size)) {
++				u8 *kaddr;
++				int ofs = 0;
++
++				if (likely(bh_pos < initialized_size))
++					ofs = initialized_size - bh_pos;
++				kaddr = kmap_atomic(page, KM_USER0);
++				memset(kaddr + bh_offset(bh) + ofs, 0,
++						blocksize - ofs);
++				kunmap_atomic(kaddr, KM_USER0);
++				flush_dcache_page(page);
++			}
++		} else /* if (unlikely(!buffer_uptodate(bh))) */
++			err = -EIO;
++	}
++	if (likely(!err)) {
++		/* Clear buffer_new on all buffers. */
++		u = 0;
++		do {
++			bh = head = page_buffers(pages[u]);
++			do {
++				if (buffer_new(bh))
++					clear_buffer_new(bh);
++			} while ((bh = bh->b_this_page) != head);
++		} while (++u < nr_pages);
++		ntfs_debug("Done.");
++		return err;
++	}
++	if (status.attr_switched) {
++		/* Get back to the attribute extent we modified. */
++		ntfs_attr_reinit_search_ctx(ctx);
++		if (ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++				CASE_SENSITIVE, bh_cpos, NULL, 0, ctx)) {
++			ntfs_error(vol->sb, "Failed to find required "
++					"attribute extent of attribute in "
++					"error code path.  Run chkdsk to "
++					"recover.");
++			write_lock_irqsave(&ni->size_lock, flags);
++			ni->itype.compressed.size += vol->cluster_size;
++			write_unlock_irqrestore(&ni->size_lock, flags);
++			flush_dcache_mft_record_page(ctx->ntfs_ino);
++			mark_mft_record_dirty(ctx->ntfs_ino);
++			/*
++			 * The only thing that is now wrong is the compressed
++			 * size of the base attribute extent which chkdsk
++			 * should be able to fix.
++			 */
++			NVolSetErrors(vol);
++		} else {
++			m = ctx->mrec;
++			a = ctx->attr;
++			status.attr_switched = 0;
++		}
++	}
++	/*
++	 * If the runlist has been modified, need to restore it by punching a
++	 * hole into it and we then need to deallocate the on-disk cluster as
++	 * well.  Note, we only modify the runlist if we are able to generate a
++	 * new mapping pairs array, i.e. only when the mapped attribute extent
++	 * is not switched.
++	 */
++	if (status.runlist_merged && !status.attr_switched) {
++		BUG_ON(!rl_write_locked);
++		/* Make the file cluster we allocated sparse in the runlist. */
++		if (ntfs_rl_punch_nolock(vol, &ni->runlist, bh_cpos, 1)) {
++			ntfs_error(vol->sb, "Failed to punch hole into "
++					"attribute runlist in error code "
++					"path.  Run chkdsk to recover the "
++					"lost cluster.");
++			make_bad_inode(vi);
++			make_bad_inode(VFS_I(base_ni));
++			NVolSetErrors(vol);
++		} else /* if (success) */ {
++			status.runlist_merged = 0;
++			/*
++			 * Deallocate the on-disk cluster we allocated but only
++			 * if we succeeded in punching its vcn out of the
++			 * runlist.
++			 */
++			down_write(&vol->lcnbmp_lock);
++			if (ntfs_bitmap_clear_bit(vol->lcnbmp_ino, lcn)) {
++				ntfs_error(vol->sb, "Failed to release "
++						"allocated cluster in error "
++						"code path.  Run chkdsk to "
++						"recover the lost cluster.");
++				NVolSetErrors(vol);
++			}
++			up_write(&vol->lcnbmp_lock);
++		}
++	}
++	/*
++	 * Resize the attribute record to its old size and rebuild the mapping
++	 * pairs array.  Note, we only can do this if the runlist has been
++	 * restored to its old state which also implies that the mapped
++	 * attribute extent is not switched.
++	 */
++	if (status.mp_rebuilt && !status.runlist_merged) {
++		if (ntfs_attr_record_resize(m, a, attr_rec_len)) {
++			ntfs_error(vol->sb, "Failed to restore attribute "
++					"record in error code path.  Run "
++					"chkdsk to recover.");
++			make_bad_inode(vi);
++			make_bad_inode(VFS_I(base_ni));
++			NVolSetErrors(vol);
++		} else /* if (success) */ {
++			if (ntfs_mapping_pairs_build(vol, (u8*)a +
++					le16_to_cpu(a->data.non_resident.
++					mapping_pairs_offset), attr_rec_len -
++					le16_to_cpu(a->data.non_resident.
++					mapping_pairs_offset), ni->runlist.rl,
++					vcn, highest_vcn, NULL)) {
++				ntfs_error(vol->sb, "Failed to restore "
++						"mapping pairs array in error "
++						"code path.  Run chkdsk to "
++						"recover.");
++				make_bad_inode(vi);
++				make_bad_inode(VFS_I(base_ni));
++				NVolSetErrors(vol);
++			}
++			flush_dcache_mft_record_page(ctx->ntfs_ino);
++			mark_mft_record_dirty(ctx->ntfs_ino);
++		}
++	}
++	/* Release the mft record and the attribute. */
++	if (status.mft_attr_mapped) {
++		ntfs_attr_put_search_ctx(ctx);
++		unmap_mft_record(base_ni);
++	}
++	/* Release the runlist lock. */
++	if (rl_write_locked)
++		up_write(&ni->runlist.lock);
++	else if (rl)
++		up_read(&ni->runlist.lock);
++	/*
++	 * Zero out any newly allocated blocks to avoid exposing stale data.
++	 * If BH_New is set, we know that the block was newly allocated above
++	 * and that it has not been fully zeroed and marked dirty yet.
++	 */
++	nr_pages = u;
++	u = 0;
++	end = bh_cpos << vol->cluster_size_bits;
++	do {
++		page = pages[u];
++		bh = head = page_buffers(page);
++		do {
++			if (u == nr_pages &&
++					((s64)page->index << PAGE_CACHE_SHIFT) +
++					bh_offset(bh) >= end)
++				break;
++			if (!buffer_new(bh))
++				continue;
++			clear_buffer_new(bh);
++			if (!buffer_uptodate(bh)) {
++				if (PageUptodate(page))
++					set_buffer_uptodate(bh);
++				else {
++					u8 *kaddr = kmap_atomic(page, KM_USER0);
++					memset(kaddr + bh_offset(bh), 0,
++							blocksize);
++					kunmap_atomic(kaddr, KM_USER0);
++					flush_dcache_page(page);
++					set_buffer_uptodate(bh);
++				}
++			}
++			mark_buffer_dirty(bh);
++		} while ((bh = bh->b_this_page) != head);
++	} while (++u <= nr_pages);
++	ntfs_error(vol->sb, "Failed.  Returning error code %i.", err);
++	return err;
++}
++
++/*
++ * Copy as much as we can into the pages and return the number of bytes which
++ * were sucessfully copied.  If a fault is encountered then clear the pages
++ * out to (ofs + bytes) and return the number of bytes which were copied.
++ */
++static inline size_t ntfs_copy_from_user(struct page **pages,
++		unsigned nr_pages, unsigned ofs, const char __user *buf,
++		size_t bytes)
++{
++	struct page **last_page = pages + nr_pages;
++	char *kaddr;
++	size_t total = 0;
++	unsigned len;
++	int left;
++
++	do {
++		len = PAGE_CACHE_SIZE - ofs;
++		if (len > bytes)
++			len = bytes;
++		kaddr = kmap_atomic(*pages, KM_USER0);
++		left = __copy_from_user_inatomic(kaddr + ofs, buf, len);
++		kunmap_atomic(kaddr, KM_USER0);
++		if (unlikely(left)) {
++			/* Do it the slow way. */
++			kaddr = kmap(*pages);
++			left = __copy_from_user(kaddr + ofs, buf, len);
++			kunmap(*pages);
++			if (unlikely(left))
++				goto err_out;
++		}
++		total += len;
++		bytes -= len;
++		if (!bytes)
++			break;
++		buf += len;
++		ofs = 0;
++	} while (++pages < last_page);
++out:
++	return total;
++err_out:
++	total += len - left;
++	/* Zero the rest of the target like __copy_from_user(). */
++	while (++pages < last_page) {
++		bytes -= len;
++		if (!bytes)
++			break;
++		len = PAGE_CACHE_SIZE;
++		if (len > bytes)
++			len = bytes;
++		kaddr = kmap_atomic(*pages, KM_USER0);
++		memset(kaddr, 0, len);
++		kunmap_atomic(kaddr, KM_USER0);
++	}
++	goto out;
++}
++
++static size_t __ntfs_copy_from_user_iovec(char *vaddr,
++		const struct iovec *iov, size_t iov_ofs, size_t bytes)
++{
++	size_t total = 0;
++
++	while (1) {
++		const char __user *buf = iov->iov_base + iov_ofs;
++		unsigned len;
++		size_t left;
++
++		len = iov->iov_len - iov_ofs;
++		if (len > bytes)
++			len = bytes;
++		left = __copy_from_user_inatomic(vaddr, buf, len);
++		total += len;
++		bytes -= len;
++		vaddr += len;
++		if (unlikely(left)) {
++			/*
++			 * Zero the rest of the target like __copy_from_user().
++			 */
++			memset(vaddr, 0, bytes);
++			total -= left;
++			break;
++		}
++		if (!bytes)
++			break;
++		iov++;
++		iov_ofs = 0;
++	}
++	return total;
++}
++
++static inline void ntfs_set_next_iovec(const struct iovec **iovp,
++		size_t *iov_ofsp, size_t bytes)
++{
++	const struct iovec *iov = *iovp;
++	size_t iov_ofs = *iov_ofsp;
++
++	while (bytes) {
++		unsigned len;
++
++		len = iov->iov_len - iov_ofs;
++		if (len > bytes)
++			len = bytes;
++		bytes -= len;
++		iov_ofs += len;
++		if (iov->iov_len == iov_ofs) {
++			iov++;
++			iov_ofs = 0;
++		}
++	}
++	*iovp = iov;
++	*iov_ofsp = iov_ofs;
++}
++
++/*
++ * This has the same side-effects and return value as ntfs_copy_from_user().
++ * The difference is that on a fault we need to memset the remainder of the
++ * pages (out to offset + bytes), to emulate ntfs_copy_from_user()'s
++ * single-segment behaviour.
++ *
++ * We call the same helper (__ntfs_copy_from_user_iovec()) both when atomic and
++ * when not atomic.  This is ok because __ntfs_copy_from_user_iovec() calls
++ * __copy_from_user_inatomic() and it is ok to call this when non-atomic.  In
++ * fact, the only difference between __copy_from_user_inatomic() and
++ * __copy_from_user() is that the latter calls might_sleep().  And on many
++ * architectures __copy_from_user_inatomic() is just defined to
++ * __copy_from_user() so it makes no difference at all on those architectures.
++ */
++static inline size_t ntfs_copy_from_user_iovec(struct page **pages,
++		unsigned nr_pages, unsigned ofs, const struct iovec **iov,
++		size_t *iov_ofs, size_t bytes)
++{
++	struct page **last_page = pages + nr_pages;
++	char *kaddr;
++	size_t copied, len, total = 0;
++
++	do {
++		len = PAGE_CACHE_SIZE - ofs;
++		if (len > bytes)
++			len = bytes;
++		kaddr = kmap_atomic(*pages, KM_USER0);
++		copied = __ntfs_copy_from_user_iovec(kaddr + ofs,
++				*iov, *iov_ofs, len);
++		kunmap_atomic(kaddr, KM_USER0);
++		if (unlikely(copied != len)) {
++			/* Do it the slow way. */
++			kaddr = kmap(*pages);
++			copied = __ntfs_copy_from_user_iovec(kaddr + ofs,
++					*iov, *iov_ofs, len);
++			kunmap(*pages);
++			if (unlikely(copied != len))
++				goto err_out;
++		}
++		total += len;
++		bytes -= len;
++		if (!bytes)
++			break;
++		ntfs_set_next_iovec(iov, iov_ofs, len);
++		ofs = 0;
++	} while (++pages < last_page);
++out:
++	return total;
++err_out:
++	total += copied;
++	/* Zero the rest of the target like __copy_from_user(). */
++	while (++pages < last_page) {
++		bytes -= len;
++		if (!bytes)
++			break;
++		len = PAGE_CACHE_SIZE;
++		if (len > bytes)
++			len = bytes;
++		kaddr = kmap_atomic(*pages, KM_USER0);
++		memset(kaddr, 0, len);
++		kunmap_atomic(kaddr, KM_USER0);
++	}
++	goto out;
++}
++
++static inline void ntfs_flush_dcache_pages(struct page **pages,
++		unsigned nr_pages)
++{
++	BUG_ON(!nr_pages);
++	do {
++		/*
++		 * Warning: Do not do the decrement at the same time as the
++		 * call because flush_dcache_page() is a NULL macro on i386
++		 * and hence the decrement never happens.
++		 */
++		flush_dcache_page(pages[nr_pages]);
++	} while (--nr_pages > 0);
++}
++
++/**
++ * ntfs_commit_pages_after_non_resident_write - commit the received data
++ * @pages:	array of destination pages
++ * @nr_pages:	number of pages in @pages
++ * @pos:	byte position in file at which the write begins
++ * @bytes:	number of bytes to be written
++ *
++ * See description of ntfs_commit_pages_after_write(), below.
++ */
++static inline int ntfs_commit_pages_after_non_resident_write(
++		struct page **pages, const unsigned nr_pages,
++		s64 pos, size_t bytes)
++{
++	s64 end, initialized_size;
++	struct inode *vi;
++	ntfs_inode *ni, *base_ni;
++	struct buffer_head *bh, *head;
++	ntfs_attr_search_ctx *ctx;
++	MFT_RECORD *m;
++	ATTR_RECORD *a;
++	unsigned long flags;
++	unsigned blocksize, u;
++	int err;
++
++	vi = pages[0]->mapping->host;
++	ni = NTFS_I(vi);
++	blocksize = 1 << vi->i_blkbits;
++	end = pos + bytes;
++	u = 0;
++	do {
++		s64 bh_pos;
++		struct page *page;
++		BOOL partial;
++
++		page = pages[u];
++		bh_pos = (s64)page->index << PAGE_CACHE_SHIFT;
++		bh = head = page_buffers(page);
++		partial = FALSE;
++		do {
++			s64 bh_end;
++
++			bh_end = bh_pos + blocksize;
++			if (bh_end <= pos || bh_pos >= end) {
++				if (!buffer_uptodate(bh))
++					partial = TRUE;
++			} else {
++				set_buffer_uptodate(bh);
++				mark_buffer_dirty(bh);
++			}
++		} while (bh_pos += blocksize, (bh = bh->b_this_page) != head);
++		/*
++		 * If all buffers are now uptodate but the page is not, set the
++		 * page uptodate.
++		 */
++		if (!partial && !PageUptodate(page))
++			SetPageUptodate(page);
++	} while (++u < nr_pages);
++	/*
++	 * Finally, if we do not need to update initialized_size or i_size we
++	 * are finished.
++	 */
++	read_lock_irqsave(&ni->size_lock, flags);
++	initialized_size = ni->initialized_size;
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	if (end <= initialized_size) {
++		ntfs_debug("Done.");
++		return 0;
++	}
++	/*
++	 * Update initialized_size/i_size as appropriate, both in the inode and
++	 * the mft record.
++	 */
++	if (!NInoAttr(ni))
++		base_ni = ni;
++	else
++		base_ni = ni->ext.base_ntfs_ino;
++	/* Map, pin, and lock the mft record. */
++	m = map_mft_record(base_ni);
++	if (IS_ERR(m)) {
++		err = PTR_ERR(m);
++		m = NULL;
++		ctx = NULL;
++		goto err_out;
++	}
++	BUG_ON(!NInoNonResident(ni));
++	ctx = ntfs_attr_get_search_ctx(base_ni, m);
++	if (unlikely(!ctx)) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++			CASE_SENSITIVE, 0, NULL, 0, ctx);
++	if (unlikely(err)) {
++		if (err == -ENOENT)
++			err = -EIO;
++		goto err_out;
++	}
++	a = ctx->attr;
++	BUG_ON(!a->non_resident);
++	write_lock_irqsave(&ni->size_lock, flags);
++	BUG_ON(end > ni->allocated_size);
++	ni->initialized_size = end;
++	a->data.non_resident.initialized_size = cpu_to_sle64(end);
++	if (end > i_size_read(vi)) {
++		i_size_write(vi, end);
++		a->data.non_resident.data_size =
++				a->data.non_resident.initialized_size;
++	}
++	write_unlock_irqrestore(&ni->size_lock, flags);
++	/* Mark the mft record dirty, so it gets written back. */
++	flush_dcache_mft_record_page(ctx->ntfs_ino);
++	mark_mft_record_dirty(ctx->ntfs_ino);
++	ntfs_attr_put_search_ctx(ctx);
++	unmap_mft_record(base_ni);
++	ntfs_debug("Done.");
++	return 0;
++err_out:
++	if (ctx)
++		ntfs_attr_put_search_ctx(ctx);
++	if (m)
++		unmap_mft_record(base_ni);
++	ntfs_error(vi->i_sb, "Failed to update initialized_size/i_size (error "
++			"code %i).", err);
++	if (err != -ENOMEM) {
++		NVolSetErrors(ni->vol);
++		make_bad_inode(VFS_I(base_ni));
++		make_bad_inode(vi);
++	}
++	return err;
++}
++
++/**
++ * ntfs_commit_pages_after_write - commit the received data
++ * @pages:	array of destination pages
++ * @nr_pages:	number of pages in @pages
++ * @pos:	byte position in file at which the write begins
++ * @bytes:	number of bytes to be written
++ *
++ * This is called from ntfs_file_buffered_write() with i_sem held on the inode
++ * (@pages[0]->mapping->host).  There are @nr_pages pages in @pages which are
++ * locked but not kmap()ped.  The source data has already been copied into the
++ * @page.  ntfs_prepare_pages_for_non_resident_write() has been called before
++ * the data was copied (for non-resident attributes only) and it returned
++ * success.
++ *
++ * Need to set uptodate and mark dirty all buffers within the boundary of the
++ * write.  If all buffers in a page are uptodate we set the page uptodate, too.
++ *
++ * Setting the buffers dirty ensures that they get written out later when
++ * ntfs_writepage() is invoked by the VM.
++ *
++ * Finally, we need to update i_size and initialized_size as appropriate both
++ * in the inode and the mft record.
++ *
++ * This is modelled after fs/buffer.c::generic_commit_write(), which marks
++ * buffers uptodate and dirty, sets the page uptodate if all buffers in the
++ * page are uptodate, and updates i_size if the end of io is beyond i_size.  In
++ * that case, it also marks the inode dirty.
++ *
++ * If things have gone as outlined in
++ * ntfs_prepare_pages_for_non_resident_write(), we do not need to do any page
++ * content modifications here for non-resident attributes.  For resident
++ * attributes we need to do the uptodate bringing here which we combine with
++ * the copying into the mft record which means we save one atomic kmap.
++ *
++ * Return 0 on success or -errno on error.
++ */
++static int ntfs_commit_pages_after_write(struct page **pages,
++		const unsigned nr_pages, s64 pos, size_t bytes)
++{
++	s64 end, initialized_size;
++	loff_t i_size;
++	struct inode *vi;
++	ntfs_inode *ni, *base_ni;
++	struct page *page;
++	ntfs_attr_search_ctx *ctx;
++	MFT_RECORD *m;
++	ATTR_RECORD *a;
++	char *kattr, *kaddr;
++	unsigned long flags;
++	u32 attr_len;
++	int err;
++
++	BUG_ON(!nr_pages);
++	BUG_ON(!pages);
++	page = pages[0];
++	BUG_ON(!page);
++	vi = page->mapping->host;
++	ni = NTFS_I(vi);
++	ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page "
++			"index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.",
++			vi->i_ino, ni->type, page->index, nr_pages,
++			(long long)pos, bytes);
++	if (NInoNonResident(ni))
++		return ntfs_commit_pages_after_non_resident_write(pages,
++				nr_pages, pos, bytes);
++	BUG_ON(nr_pages > 1);
++	/*
++	 * Attribute is resident, implying it is not compressed, encrypted, or
++	 * sparse.
++	 */
++	if (!NInoAttr(ni))
++		base_ni = ni;
++	else
++		base_ni = ni->ext.base_ntfs_ino;
++	BUG_ON(NInoNonResident(ni));
++	/* Map, pin, and lock the mft record. */
++	m = map_mft_record(base_ni);
++	if (IS_ERR(m)) {
++		err = PTR_ERR(m);
++		m = NULL;
++		ctx = NULL;
++		goto err_out;
++	}
++	ctx = ntfs_attr_get_search_ctx(base_ni, m);
++	if (unlikely(!ctx)) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
++			CASE_SENSITIVE, 0, NULL, 0, ctx);
++	if (unlikely(err)) {
++		if (err == -ENOENT)
++			err = -EIO;
++		goto err_out;
++	}
++	a = ctx->attr;
++	BUG_ON(a->non_resident);
++	/* The total length of the attribute value. */
++	attr_len = le32_to_cpu(a->data.resident.value_length);
++	i_size = i_size_read(vi);
++	BUG_ON(attr_len != i_size);
++	BUG_ON(pos > attr_len);
++	end = pos + bytes;
++	BUG_ON(end > le32_to_cpu(a->length) -
++			le16_to_cpu(a->data.resident.value_offset));
++	kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
++	kaddr = kmap_atomic(page, KM_USER0);
++	/* Copy the received data from the page to the mft record. */
++	memcpy(kattr + pos, kaddr + pos, bytes);
++	/* Update the attribute length if necessary. */
++	if (end > attr_len) {
++		attr_len = end;
++		a->data.resident.value_length = cpu_to_le32(attr_len);
++	}
++	/*
++	 * If the page is not uptodate, bring the out of bounds area(s)
++	 * uptodate by copying data from the mft record to the page.
++	 */
++	if (!PageUptodate(page)) {
++		if (pos > 0)
++			memcpy(kaddr, kattr, pos);
++		if (end < attr_len)
++			memcpy(kaddr + end, kattr + end, attr_len - end);
++		/* Zero the region outside the end of the attribute value. */
++		memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
++		flush_dcache_page(page);
++		SetPageUptodate(page);
++	}
++	kunmap_atomic(kaddr, KM_USER0);
++	/* Update initialized_size/i_size if necessary. */
++	read_lock_irqsave(&ni->size_lock, flags);
++	initialized_size = ni->initialized_size;
++	BUG_ON(end > ni->allocated_size);
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	BUG_ON(initialized_size != i_size);
++	if (end > initialized_size) {
++		unsigned long flags;
++
++		write_lock_irqsave(&ni->size_lock, flags);
++		ni->initialized_size = end;
++		i_size_write(vi, end);
++		write_unlock_irqrestore(&ni->size_lock, flags);
++	}
++	/* Mark the mft record dirty, so it gets written back. */
++	flush_dcache_mft_record_page(ctx->ntfs_ino);
++	mark_mft_record_dirty(ctx->ntfs_ino);
++	ntfs_attr_put_search_ctx(ctx);
++	unmap_mft_record(base_ni);
++	ntfs_debug("Done.");
++	return 0;
++err_out:
++	if (err == -ENOMEM) {
++		ntfs_warning(vi->i_sb, "Error allocating memory required to "
++				"commit the write.");
++		if (PageUptodate(page)) {
++			ntfs_warning(vi->i_sb, "Page is uptodate, setting "
++					"dirty so the write will be retried "
++					"later on by the VM.");
++			/*
++			 * Put the page on mapping->dirty_pages, but leave its
++			 * buffers' dirty state as-is.
++			 */
++			__set_page_dirty_nobuffers(page);
++			err = 0;
++		} else
++			ntfs_error(vi->i_sb, "Page is not uptodate.  Written "
++					"data has been lost.");
++	} else {
++		ntfs_error(vi->i_sb, "Resident attribute commit write failed "
++				"with error %i.", err);
++		NVolSetErrors(ni->vol);
++		make_bad_inode(VFS_I(base_ni));
++		make_bad_inode(vi);
++	}
++	if (ctx)
++		ntfs_attr_put_search_ctx(ctx);
++	if (m)
++		unmap_mft_record(base_ni);
++	return err;
++}
++
++/**
++ * ntfs_file_buffered_write -
++ *
++ * Locking: The vfs is holding ->i_sem on the inode.
++ */
++static ssize_t ntfs_file_buffered_write(struct kiocb *iocb,
++		const struct iovec *iov, unsigned long nr_segs,
++		loff_t pos, loff_t *ppos, size_t count)
++{
++	struct file *file = iocb->ki_filp;
++	struct address_space *mapping = file->f_mapping;
++	struct inode *vi = mapping->host;
++	ntfs_inode *ni = NTFS_I(vi);
++	ntfs_volume *vol = ni->vol;
++	struct page *pages[NTFS_MAX_PAGES_PER_CLUSTER];
++	struct page *cached_page = NULL;
++	char __user *buf = NULL;
++	s64 end, ll;
++	VCN last_vcn;
++	LCN lcn;
++	unsigned long flags;
++	size_t bytes, iov_ofs = 0;	/* Offset in the current iovec. */
++	ssize_t status, written;
++	unsigned nr_pages;
++	int err;
++	struct pagevec lru_pvec;
++
++	ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
++			"pos 0x%llx, count 0x%lx.",
++			vi->i_ino, (unsigned)le32_to_cpu(ni->type),
++			(unsigned long long)pos, (unsigned long)count);
++	if (unlikely(!count))
++		return 0;
++	BUG_ON(NInoMstProtected(ni));
++	/*
++	 * If the attribute is not an index root and it is encrypted or
++	 * compressed, we cannot write to it yet.  Note we need to check for
++	 * AT_INDEX_ALLOCATION since this is the type of both directory and
++	 * index inodes.
++	 */
++	if (ni->type != AT_INDEX_ALLOCATION) {
++		/* If file is encrypted, deny access, just like NT4. */
++		if (NInoEncrypted(ni)) {
++			/*
++			 * Reminder for later: Encrypted files are _always_
++			 * non-resident so that the content can always be
++			 * encrypted.
++			 */
++			ntfs_debug("Denying write access to encrypted file.");
++			return -EACCES;
++		}
++		if (NInoCompressed(ni)) {
++			/* Only unnamed $DATA attribute can be compressed. */
++			BUG_ON(ni->type != AT_DATA);
++			BUG_ON(ni->name_len);
++			/*
++			 * Reminder for later: If resident, the data is not
++			 * actually compressed.  Only on the switch to non-
++			 * resident does compression kick in.  This is in
++			 * contrast to encrypted files (see above).
++			 */
++			ntfs_error(vi->i_sb, "Writing to compressed files is "
++					"not implemented yet.  Sorry.");
++			return -EOPNOTSUPP;
++		}
++	}
++	/*
++	 * If a previous ntfs_truncate() failed, repeat it and abort if it
++	 * fails again.
++	 */
++	if (unlikely(NInoTruncateFailed(ni))) {
++		down_write(&vi->i_alloc_sem);
++		err = ntfs_truncate(vi);
++		up_write(&vi->i_alloc_sem);
++		if (err || NInoTruncateFailed(ni)) {
++			if (!err)
++				err = -EIO;
++			ntfs_error(vol->sb, "Cannot perform write to inode "
++					"0x%lx, attribute type 0x%x, because "
++					"ntfs_truncate() failed (error code "
++					"%i).", vi->i_ino,
++					(unsigned)le32_to_cpu(ni->type), err);
++			return err;
++		}
++	}
++	/* The first byte after the write. */
++	end = pos + count;
++	/*
++	 * If the write goes beyond the allocated size, extend the allocation
++	 * to cover the whole of the write, rounded up to the nearest cluster.
++	 */
++	read_lock_irqsave(&ni->size_lock, flags);
++	ll = ni->allocated_size;
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	if (end > ll) {
++		/* Extend the allocation without changing the data size. */
++		ll = ntfs_attr_extend_allocation(ni, end, -1, pos);
++		if (likely(ll >= 0)) {
++			BUG_ON(pos >= ll);
++			/* If the extension was partial truncate the write. */
++			if (end > ll) {
++				ntfs_debug("Truncating write to inode 0x%lx, "
++						"attribute type 0x%x, because "
++						"the allocation was only "
++						"partially extended.",
++						vi->i_ino, (unsigned)
++						le32_to_cpu(ni->type));
++				end = ll;
++				count = ll - pos;
++			}
++		} else {
++			err = ll;
++			read_lock_irqsave(&ni->size_lock, flags);
++			ll = ni->allocated_size;
++			read_unlock_irqrestore(&ni->size_lock, flags);
++			/* Perform a partial write if possible or fail. */
++			if (pos < ll) {
++				ntfs_debug("Truncating write to inode 0x%lx, "
++						"attribute type 0x%x, because "
++						"extending the allocation "
++						"failed (error code %i).",
++						vi->i_ino, (unsigned)
++						le32_to_cpu(ni->type), err);
++				end = ll;
++				count = ll - pos;
++			} else {
++				ntfs_error(vol->sb, "Cannot perform write to "
++						"inode 0x%lx, attribute type "
++						"0x%x, because extending the "
++						"allocation failed (error "
++						"code %i).", vi->i_ino,
++						(unsigned)
++						le32_to_cpu(ni->type), err);
++				return err;
++			}
++		}
++	}
++	pagevec_init(&lru_pvec, 0);
++	written = 0;
++	/*
++	 * If the write starts beyond the initialized size, extend it up to the
++	 * beginning of the write and initialize all non-sparse space between
++	 * the old initialized size and the new one.  This automatically also
++	 * increments the vfs inode->i_size to keep it above or equal to the
++	 * initialized_size.
++	 */
++	read_lock_irqsave(&ni->size_lock, flags);
++	ll = ni->initialized_size;
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	if (pos > ll) {
++		err = ntfs_attr_extend_initialized(ni, pos, &cached_page,
++				&lru_pvec);
++		if (err < 0) {
++			ntfs_error(vol->sb, "Cannot perform write to inode "
++					"0x%lx, attribute type 0x%x, because "
++					"extending the initialized size "
++					"failed (error code %i).", vi->i_ino,
++					(unsigned)le32_to_cpu(ni->type), err);
++			status = err;
++			goto err_out;
++		}
++	}
++	/*
++	 * Determine the number of pages per cluster for non-resident
++	 * attributes.
++	 */
++	nr_pages = 1;
++	if (vol->cluster_size > PAGE_CACHE_SIZE && NInoNonResident(ni))
++		nr_pages = vol->cluster_size >> PAGE_CACHE_SHIFT;
++	/* Finally, perform the actual write. */
++	last_vcn = -1;
++	if (likely(nr_segs == 1))
++		buf = iov->iov_base;
++	do {
++		VCN vcn;
++		pgoff_t idx, start_idx;
++		unsigned ofs, do_pages, u;
++		size_t copied;
++
++		start_idx = idx = pos >> PAGE_CACHE_SHIFT;
++		ofs = pos & ~PAGE_CACHE_MASK;
++		bytes = PAGE_CACHE_SIZE - ofs;
++		do_pages = 1;
++		if (nr_pages > 1) {
++			vcn = pos >> vol->cluster_size_bits;
++			if (vcn != last_vcn) {
++				last_vcn = vcn;
++				/*
++				 * Get the lcn of the vcn the write is in.  If
++				 * it is a hole, need to lock down all pages in
++				 * the cluster.
++				 */
++				down_read(&ni->runlist.lock);
++				lcn = ntfs_attr_vcn_to_lcn_nolock(ni, pos >>
++						vol->cluster_size_bits, FALSE);
++				up_read(&ni->runlist.lock);
++				if (unlikely(lcn < LCN_HOLE)) {
++					status = -EIO;
++					if (lcn == LCN_ENOMEM)
++						status = -ENOMEM;
++					else
++						ntfs_error(vol->sb, "Cannot "
++							"perform write to "
++							"inode 0x%lx, "
++							"attribute type 0x%x, "
++							"because the attribute "
++							"is corrupt.",
++							vi->i_ino, (unsigned)
++							le32_to_cpu(ni->type));
++					break;
++				}
++				if (lcn == LCN_HOLE) {
++					start_idx = (pos & ~(s64)
++							vol->cluster_size_mask)
++							>> PAGE_CACHE_SHIFT;
++					bytes = vol->cluster_size - (pos &
++							vol->cluster_size_mask);
++					do_pages = nr_pages;
++				}
++			}
++		}
++		if (bytes > count)
++			bytes = count;
++		/*
++		 * Bring in the user page(s) that we will copy from _first_.
++		 * Otherwise there is a nasty deadlock on copying from the same
++		 * page(s) as we are writing to, without it/them being marked
++		 * up-to-date.  Note, at present there is nothing to stop the
++		 * pages being swapped out between us bringing them into memory
++		 * and doing the actual copying.
++		 */
++		if (likely(nr_segs == 1))
++			ntfs_fault_in_pages_readable(buf, bytes);
++		else
++			ntfs_fault_in_pages_readable_iovec(iov, iov_ofs, bytes);
++		/* Get and lock @do_pages starting at index @start_idx. */
++		status = __ntfs_grab_cache_pages(mapping, start_idx, do_pages,
++				pages, &cached_page, &lru_pvec);
++		if (unlikely(status))
++			break;
++		/*
++		 * For non-resident attributes, we need to fill any holes with
++		 * actual clusters and ensure all bufferes are mapped.  We also
++		 * need to bring uptodate any buffers that are only partially
++		 * being written to.
++		 */
++		if (NInoNonResident(ni)) {
++			status = ntfs_prepare_pages_for_non_resident_write(
++					pages, do_pages, pos, bytes);
++			if (unlikely(status)) {
++				loff_t i_size;
++
++				do {
++					unlock_page(pages[--do_pages]);
++					page_cache_release(pages[do_pages]);
++				} while (do_pages);
++				/*
++				 * The write preparation may have instantiated
++				 * allocated space outside i_size.  Trim this
++				 * off again.  We can ignore any errors in this
++				 * case as we will just be waisting a bit of
++				 * allocated space, which is not a disaster.
++				 */
++				i_size = i_size_read(vi);
++				if (pos + bytes > i_size)
++					vmtruncate(vi, i_size);
++				break;
++			}
++		}
++		u = (pos >> PAGE_CACHE_SHIFT) - pages[0]->index;
++		if (likely(nr_segs == 1)) {
++			copied = ntfs_copy_from_user(pages + u, do_pages - u,
++					ofs, buf, bytes);
++			buf += copied;
++		} else
++			copied = ntfs_copy_from_user_iovec(pages + u,
++					do_pages - u, ofs, &iov, &iov_ofs,
++					bytes);
++		ntfs_flush_dcache_pages(pages + u, do_pages - u);
++		status = ntfs_commit_pages_after_write(pages, do_pages, pos,
++				bytes);
++		if (likely(!status)) {
++			written += copied;
++			count -= copied;
++			pos += copied;
++			if (unlikely(copied != bytes))
++				status = -EFAULT;
++		}
++		do {
++			unlock_page(pages[--do_pages]);
++			mark_page_accessed(pages[do_pages]);
++			page_cache_release(pages[do_pages]);
++		} while (do_pages);
++		if (unlikely(status))
++			break;
++		balance_dirty_pages_ratelimited(mapping);
++		cond_resched();
++	} while (count);
++err_out:
++	*ppos = pos;
++	if (cached_page)
++		page_cache_release(cached_page);
++	/* For now, when the user asks for O_SYNC, we actually give O_DSYNC. */
++	if (likely(!status)) {
++		if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(vi))) {
++			if (!mapping->a_ops->writepage || !is_sync_kiocb(iocb))
++				status = generic_osync_inode(vi, mapping,
++						OSYNC_METADATA|OSYNC_DATA);
++		}
++  	}
++	pagevec_lru_add(&lru_pvec);
++	ntfs_debug("Done.  Returning %s (written 0x%lx, status %li).",
++			written ? "written" : "status", (unsigned long)written,
++			(long)status);
++	return written ? written : status;
++}
++
++/**
++ * ntfs_file_aio_write_nolock -
++ */
++static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb,
++		const struct iovec *iov, unsigned long nr_segs, loff_t *ppos)
++{
++	struct file *file = iocb->ki_filp;
++	struct address_space *mapping = file->f_mapping;
++	struct inode *inode = mapping->host;
++	loff_t pos;
++	unsigned long seg;
++	size_t count;		/* after file limit checks */
++	ssize_t written, err;
++
++	count = 0;
++	for (seg = 0; seg < nr_segs; seg++) {
++		const struct iovec *iv = &iov[seg];
++		/*
++		 * If any segment has a negative length, or the cumulative
++		 * length ever wraps negative then return -EINVAL.
++		 */
++		count += iv->iov_len;
++		if (unlikely((ssize_t)(count|iv->iov_len) < 0))
++			return -EINVAL;
++		if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
++			continue;
++		if (!seg)
++			return -EFAULT;
++		nr_segs = seg;
++		count -= iv->iov_len;	/* This segment is no good */
++		break;
++	}
++	pos = *ppos;
++	vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
++	/* We can write back this queue in page reclaim. */
++	current->backing_dev_info = mapping->backing_dev_info;
++	written = 0;
++	err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
++	if (err)
++		goto out;
++	if (!count)
++		goto out;
++	err = remove_suid(file->f_dentry);
++	if (err)
++		goto out;
++	inode_update_time(inode, 1);
++	written = ntfs_file_buffered_write(iocb, iov, nr_segs, pos, ppos,
++			count);
++out:
++	current->backing_dev_info = NULL;
++	return written ? written : err;
++}
++
++/**
++ * ntfs_file_aio_write -
++ */
++static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const char __user *buf,
++		size_t count, loff_t pos)
++{
++	struct file *file = iocb->ki_filp;
++	struct address_space *mapping = file->f_mapping;
++	struct inode *inode = mapping->host;
++	ssize_t ret;
++	struct iovec local_iov = { .iov_base = (void __user *)buf,
++				   .iov_len = count };
++
++	BUG_ON(iocb->ki_pos != pos);
++
++	down(&inode->i_sem);
++	ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
++	up(&inode->i_sem);
++	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++		int err = sync_page_range(inode, mapping, pos, ret);
++		if (err < 0)
++			ret = err;
++	}
++	return ret;
++}
++
++/**
++ * ntfs_file_writev -
++ *
++ * Basically the same as generic_file_writev() except that it ends up calling
++ * ntfs_file_aio_write_nolock() instead of __generic_file_aio_write_nolock().
++ */
++static ssize_t ntfs_file_writev(struct file *file, const struct iovec *iov,
++		unsigned long nr_segs, loff_t *ppos)
++{
++	struct address_space *mapping = file->f_mapping;
++	struct inode *inode = mapping->host;
++	struct kiocb kiocb;
++	ssize_t ret;
++
++	down(&inode->i_sem);
++	init_sync_kiocb(&kiocb, file);
++	ret = ntfs_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
++	if (ret == -EIOCBQUEUED)
++		ret = wait_on_sync_kiocb(&kiocb);
++	up(&inode->i_sem);
++	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++		int err = sync_page_range(inode, mapping, *ppos - ret, ret);
++		if (err < 0)
++			ret = err;
++	}
++	return ret;
++}
++
++/**
++ * ntfs_file_write - simple wrapper for ntfs_file_writev()
++ */
++static ssize_t ntfs_file_write(struct file *file, const char __user *buf,
++		size_t count, loff_t *ppos)
++{
++	struct iovec local_iov = { .iov_base = (void __user *)buf,
++				   .iov_len = count };
++
++	return ntfs_file_writev(file, &local_iov, 1, ppos);
++}
++
++/**
+  * ntfs_file_fsync - sync a file to disk
+  * @filp:	file to be synced
+  * @dentry:	dentry describing the file to sync
+@@ -113,39 +2305,39 @@ static int ntfs_file_fsync(struct file *
+ #endif /* NTFS_RW */
+ 
+ struct file_operations ntfs_file_ops = {
+-	.llseek		= generic_file_llseek,	  /* Seek inside file. */
+-	.read		= generic_file_read,	  /* Read from file. */
+-	.aio_read	= generic_file_aio_read,  /* Async read from file. */
+-	.readv		= generic_file_readv,	  /* Read from file. */
++	.llseek		= generic_file_llseek,	 /* Seek inside file. */
++	.read		= generic_file_read,	 /* Read from file. */
++	.aio_read	= generic_file_aio_read, /* Async read from file. */
++	.readv		= generic_file_readv,	 /* Read from file. */
+ #ifdef NTFS_RW
+-	.write		= generic_file_write,	  /* Write to file. */
+-	.aio_write	= generic_file_aio_write, /* Async write to file. */
+-	.writev		= generic_file_writev,	  /* Write to file. */
+-	/*.release	= ,*/			  /* Last file is closed.  See
+-						     fs/ext2/file.c::
+-						     ext2_release_file() for
+-						     how to use this to discard
+-						     preallocated space for
+-						     write opened files. */
+-	.fsync		= ntfs_file_fsync,	  /* Sync a file to disk. */
+-	/*.aio_fsync	= ,*/			  /* Sync all outstanding async
+-						     i/o operations on a
+-						     kiocb. */
++	.write		= ntfs_file_write,	 /* Write to file. */
++	.aio_write	= ntfs_file_aio_write,	 /* Async write to file. */
++	.writev		= ntfs_file_writev,	 /* Write to file. */
++	/*.release	= ,*/			 /* Last file is closed.  See
++						    fs/ext2/file.c::
++						    ext2_release_file() for
++						    how to use this to discard
++						    preallocated space for
++						    write opened files. */
++	.fsync		= ntfs_file_fsync,	 /* Sync a file to disk. */
++	/*.aio_fsync	= ,*/			 /* Sync all outstanding async
++						    i/o operations on a
++						    kiocb. */
+ #endif /* NTFS_RW */
+-	/*.ioctl	= ,*/			  /* Perform function on the
+-						     mounted filesystem. */
+-	.mmap		= generic_file_mmap,	  /* Mmap file. */
+-	.open		= ntfs_file_open,	  /* Open file. */
+-	.sendfile	= generic_file_sendfile,  /* Zero-copy data send with
+-						     the data source being on
+-						     the ntfs partition.  We
+-						     do not need to care about
+-						     the data destination. */
+-	/*.sendpage	= ,*/			  /* Zero-copy data send with
+-						     the data destination being
+-						     on the ntfs partition.  We
+-						     do not need to care about
+-						     the data source. */
++	/*.ioctl	= ,*/			 /* Perform function on the
++						    mounted filesystem. */
++	.mmap		= generic_file_mmap,	 /* Mmap file. */
++	.open		= ntfs_file_open,	 /* Open file. */
++	.sendfile	= generic_file_sendfile, /* Zero-copy data send with
++						    the data source being on
++						    the ntfs partition.  We do
++						    not need to care about the
++						    data destination. */
++	/*.sendpage	= ,*/			 /* Zero-copy data send with
++						    the data destination being
++						    on the ntfs partition.  We
++						    do not need to care about
++						    the data source. */
+ };
+ 
+ struct inode_operations ntfs_file_inode_ops = {
+diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
+--- a/fs/ntfs/inode.c
++++ b/fs/ntfs/inode.c
+@@ -30,6 +30,7 @@
+ #include "debug.h"
+ #include "inode.h"
+ #include "attrib.h"
++#include "lcnalloc.h"
+ #include "malloc.h"
+ #include "mft.h"
+ #include "time.h"
+@@ -2291,11 +2292,16 @@ int ntfs_show_options(struct seq_file *s
+ 
+ #ifdef NTFS_RW
+ 
++static const char *es = "  Leaving inconsistent metadata.  Unmount and run "
++		"chkdsk.";
++
+ /**
+  * ntfs_truncate - called when the i_size of an ntfs inode is changed
+  * @vi:		inode for which the i_size was changed
+  *
+- * We do not support i_size changes yet.
++ * We only support i_size changes for normal files at present, i.e. not
++ * compressed and not encrypted.  This is enforced in ntfs_setattr(), see
++ * below.
+  *
+  * The kernel guarantees that @vi is a regular file (S_ISREG() is true) and
+  * that the change is allowed.
+@@ -2306,80 +2312,499 @@ int ntfs_show_options(struct seq_file *s
+  * Returns 0 on success or -errno on error.
+  *
+  * Called with ->i_sem held.  In all but one case ->i_alloc_sem is held for
+- * writing.  The only case where ->i_alloc_sem is not held is
++ * writing.  The only case in the kernel where ->i_alloc_sem is not held is
+  * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called
+- * with the current i_size as the offset which means that it is a noop as far
+- * as ntfs_truncate() is concerned.
++ * with the current i_size as the offset.  The analogous place in NTFS is in
++ * fs/ntfs/file.c::ntfs_file_buffered_write() where we call vmtruncate() again
++ * without holding ->i_alloc_sem.
+  */
+ int ntfs_truncate(struct inode *vi)
+ {
+-	ntfs_inode *ni = NTFS_I(vi);
++	s64 new_size, old_size, nr_freed, new_alloc_size, old_alloc_size;
++	VCN highest_vcn;
++	unsigned long flags;
++	ntfs_inode *base_ni, *ni = NTFS_I(vi);
+ 	ntfs_volume *vol = ni->vol;
+ 	ntfs_attr_search_ctx *ctx;
+ 	MFT_RECORD *m;
+ 	ATTR_RECORD *a;
+ 	const char *te = "  Leaving file length out of sync with i_size.";
+-	int err;
++	int err, mp_size, size_change, alloc_change;
++	u32 attr_len;
+ 
+ 	ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
+ 	BUG_ON(NInoAttr(ni));
++	BUG_ON(S_ISDIR(vi->i_mode));
++	BUG_ON(NInoMstProtected(ni));
+ 	BUG_ON(ni->nr_extents < 0);
+-	m = map_mft_record(ni);
++retry_truncate:
++	/*
++	 * Lock the runlist for writing and map the mft record to ensure it is
++	 * safe to mess with the attribute runlist and sizes.
++	 */
++	down_write(&ni->runlist.lock);
++	if (!NInoAttr(ni))
++		base_ni = ni;
++	else
++		base_ni = ni->ext.base_ntfs_ino;
++	m = map_mft_record(base_ni);
+ 	if (IS_ERR(m)) {
+ 		err = PTR_ERR(m);
+ 		ntfs_error(vi->i_sb, "Failed to map mft record for inode 0x%lx "
+ 				"(error code %d).%s", vi->i_ino, err, te);
+ 		ctx = NULL;
+ 		m = NULL;
+-		goto err_out;
++		goto old_bad_out;
+ 	}
+-	ctx = ntfs_attr_get_search_ctx(ni, m);
++	ctx = ntfs_attr_get_search_ctx(base_ni, m);
+ 	if (unlikely(!ctx)) {
+ 		ntfs_error(vi->i_sb, "Failed to allocate a search context for "
+ 				"inode 0x%lx (not enough memory).%s",
+ 				vi->i_ino, te);
+ 		err = -ENOMEM;
+-		goto err_out;
++		goto old_bad_out;
+ 	}
+ 	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ 			CASE_SENSITIVE, 0, NULL, 0, ctx);
+ 	if (unlikely(err)) {
+-		if (err == -ENOENT)
++		if (err == -ENOENT) {
+ 			ntfs_error(vi->i_sb, "Open attribute is missing from "
+ 					"mft record.  Inode 0x%lx is corrupt.  "
+-					"Run chkdsk.", vi->i_ino);
+-		else
++					"Run chkdsk.%s", vi->i_ino, te);
++			err = -EIO;
++		} else
+ 			ntfs_error(vi->i_sb, "Failed to lookup attribute in "
+-					"inode 0x%lx (error code %d).",
+-					vi->i_ino, err);
+-		goto err_out;
++					"inode 0x%lx (error code %d).%s",
++					vi->i_ino, err, te);
++		goto old_bad_out;
+ 	}
++	m = ctx->mrec;
+ 	a = ctx->attr;
+-	/* If the size has not changed there is nothing to do. */
+-	if (ntfs_attr_size(a) == i_size_read(vi))
+-		goto done;
+-	// TODO: Implement the truncate...
+-	ntfs_error(vi->i_sb, "Inode size has changed but this is not "
+-			"implemented yet.  Resetting inode size to old value. "
+-			" This is most likely a bug in the ntfs driver!");
+-	i_size_write(vi, ntfs_attr_size(a)); 
+-done:
++	/*
++	 * The i_size of the vfs inode is the new size for the attribute value.
++	 */
++	new_size = i_size_read(vi);
++	/* The current size of the attribute value is the old size. */
++	old_size = ntfs_attr_size(a);
++	/* Calculate the new allocated size. */
++	if (NInoNonResident(ni))
++		new_alloc_size = (new_size + vol->cluster_size - 1) &
++				~(s64)vol->cluster_size_mask;
++	else
++		new_alloc_size = (new_size + 7) & ~7;
++	/* The current allocated size is the old allocated size. */
++	read_lock_irqsave(&ni->size_lock, flags);
++	old_alloc_size = ni->allocated_size;
++	read_unlock_irqrestore(&ni->size_lock, flags);
++	/*
++	 * The change in the file size.  This will be 0 if no change, >0 if the
++	 * size is growing, and <0 if the size is shrinking.
++	 */
++	size_change = -1;
++	if (new_size - old_size >= 0) {
++		size_change = 1;
++		if (new_size == old_size)
++			size_change = 0;
++	}
++	/* As above for the allocated size. */
++	alloc_change = -1;
++	if (new_alloc_size - old_alloc_size >= 0) {
++		alloc_change = 1;
++		if (new_alloc_size == old_alloc_size)
++			alloc_change = 0;
++	}
++	/*
++	 * If neither the size nor the allocation are being changed there is
++	 * nothing to do.
++	 */
++	if (!size_change && !alloc_change)
++		goto unm_done;
++	/* If the size is changing, check if new size is allowed in $AttrDef. */
++	if (size_change) {
++		err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
++		if (unlikely(err)) {
++			if (err == -ERANGE) {
++				ntfs_error(vol->sb, "Truncate would cause the "
++						"inode 0x%lx to %simum size "
++						"for its attribute type "
++						"(0x%x).  Aborting truncate.",
++						vi->i_ino,
++						new_size > old_size ? "exceed "
++						"the max" : "go under the min",
++						le32_to_cpu(ni->type));
++				err = -EFBIG;
++			} else {
++				ntfs_error(vol->sb, "Inode 0x%lx has unknown "
++						"attribute type 0x%x.  "
++						"Aborting truncate.",
++						vi->i_ino,
++						le32_to_cpu(ni->type));
++				err = -EIO;
++			}
++			/* Reset the vfs inode size to the old size. */
++			i_size_write(vi, old_size);
++			goto err_out;
++		}
++	}
++	if (NInoCompressed(ni) || NInoEncrypted(ni)) {
++		ntfs_warning(vi->i_sb, "Changes in inode size are not "
++				"supported yet for %s files, ignoring.",
++				NInoCompressed(ni) ? "compressed" :
++				"encrypted");
++		err = -EOPNOTSUPP;
++		goto bad_out;
++	}
++	if (a->non_resident)
++		goto do_non_resident_truncate;
++	BUG_ON(NInoNonResident(ni));
++	/* Resize the attribute record to best fit the new attribute size. */
++	if (new_size < vol->mft_record_size &&
++			!ntfs_resident_attr_value_resize(m, a, new_size)) {
++		unsigned long flags;
++
++		/* The resize succeeded! */
++		flush_dcache_mft_record_page(ctx->ntfs_ino);
++		mark_mft_record_dirty(ctx->ntfs_ino);
++		write_lock_irqsave(&ni->size_lock, flags);
++		/* Update the sizes in the ntfs inode and all is done. */
++		ni->allocated_size = le32_to_cpu(a->length) -
++				le16_to_cpu(a->data.resident.value_offset);
++		/*
++		 * Note ntfs_resident_attr_value_resize() has already done any
++		 * necessary data clearing in the attribute record.  When the
++		 * file is being shrunk vmtruncate() will already have cleared
++		 * the top part of the last partial page, i.e. since this is
++		 * the resident case this is the page with index 0.  However,
++		 * when the file is being expanded, the page cache page data
++		 * between the old data_size, i.e. old_size, and the new_size
++		 * has not been zeroed.  Fortunately, we do not need to zero it
++		 * either since on one hand it will either already be zero due
++		 * to both readpage and writepage clearing partial page data
++		 * beyond i_size in which case there is nothing to do or in the
++		 * case of the file being mmap()ped at the same time, POSIX
++		 * specifies that the behaviour is unspecified thus we do not
++		 * have to do anything.  This means that in our implementation
++		 * in the rare case that the file is mmap()ped and a write
++		 * occured into the mmap()ped region just beyond the file size
++		 * and writepage has not yet been called to write out the page
++		 * (which would clear the area beyond the file size) and we now
++		 * extend the file size to incorporate this dirty region
++		 * outside the file size, a write of the page would result in
++		 * this data being written to disk instead of being cleared.
++		 * Given both POSIX and the Linux mmap(2) man page specify that
++		 * this corner case is undefined, we choose to leave it like
++		 * that as this is much simpler for us as we cannot lock the
++		 * relevant page now since we are holding too many ntfs locks
++		 * which would result in a lock reversal deadlock.
++		 */
++		ni->initialized_size = new_size;
++		write_unlock_irqrestore(&ni->size_lock, flags);
++		goto unm_done;
++	}
++	/* If the above resize failed, this must be an attribute extension. */
++	BUG_ON(size_change < 0);
++	/*
++	 * We have to drop all the locks so we can call
++	 * ntfs_attr_make_non_resident().  This could be optimised by try-
++	 * locking the first page cache page and only if that fails dropping
++	 * the locks, locking the page, and redoing all the locking and
++	 * lookups.  While this would be a huge optimisation, it is not worth
++	 * it as this is definitely a slow code path as it only ever can happen
++	 * once for any given file.
++	 */
+ 	ntfs_attr_put_search_ctx(ctx);
+-	unmap_mft_record(ni);
+-	NInoClearTruncateFailed(ni);
+-	ntfs_debug("Done.");
+-	return 0;
+-err_out:
+-	if (err != -ENOMEM) {
++	unmap_mft_record(base_ni);
++	up_write(&ni->runlist.lock);
++	/*
++	 * Not enough space in the mft record, try to make the attribute
++	 * non-resident and if successful restart the truncation process.
++	 */
++	err = ntfs_attr_make_non_resident(ni, old_size);
++	if (likely(!err))
++		goto retry_truncate;
++	/*
++	 * Could not make non-resident.  If this is due to this not being
++	 * permitted for this attribute type or there not being enough space,
++	 * try to make other attributes non-resident.  Otherwise fail.
++	 */
++	if (unlikely(err != -EPERM && err != -ENOSPC)) {
++		ntfs_error(vol->sb, "Cannot truncate inode 0x%lx, attribute "
++				"type 0x%x, because the conversion from "
++				"resident to non-resident attribute failed "
++				"with error code %i.", vi->i_ino,
++				(unsigned)le32_to_cpu(ni->type), err);
++		if (err != -ENOMEM)
++			err = -EIO;
++		goto conv_err_out;
++	}
++	/* TODO: Not implemented from here, abort. */
++	if (err == -ENOSPC)
++		ntfs_error(vol->sb, "Not enough space in the mft record/on "
++				"disk for the non-resident attribute value.  "
++				"This case is not implemented yet.");
++	else /* if (err == -EPERM) */
++		ntfs_error(vol->sb, "This attribute type may not be "
++				"non-resident.  This case is not implemented "
++				"yet.");
++	err = -EOPNOTSUPP;
++	goto conv_err_out;
++#if 0
++	// TODO: Attempt to make other attributes non-resident.
++	if (!err)
++		goto do_resident_extend;
++	/*
++	 * Both the attribute list attribute and the standard information
++	 * attribute must remain in the base inode.  Thus, if this is one of
++	 * these attributes, we have to try to move other attributes out into
++	 * extent mft records instead.
++	 */
++	if (ni->type == AT_ATTRIBUTE_LIST ||
++			ni->type == AT_STANDARD_INFORMATION) {
++		// TODO: Attempt to move other attributes into extent mft
++		// records.
++		err = -EOPNOTSUPP;
++		if (!err)
++			goto do_resident_extend;
++		goto err_out;
++	}
++	// TODO: Attempt to move this attribute to an extent mft record, but
++	// only if it is not already the only attribute in an mft record in
++	// which case there would be nothing to gain.
++	err = -EOPNOTSUPP;
++	if (!err)
++		goto do_resident_extend;
++	/* There is nothing we can do to make enough space. )-: */
++	goto err_out;
++#endif
++do_non_resident_truncate:
++	BUG_ON(!NInoNonResident(ni));
++	if (alloc_change < 0) {
++		highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
++		if (highest_vcn > 0 &&
++				old_alloc_size >> vol->cluster_size_bits >
++				highest_vcn + 1) {
++			/*
++			 * This attribute has multiple extents.  Not yet
++			 * supported.
++			 */
++			ntfs_error(vol->sb, "Cannot truncate inode 0x%lx, "
++					"attribute type 0x%x, because the "
++					"attribute is highly fragmented (it "
++					"consists of multiple extents) and "
++					"this case is not implemented yet.",
++					vi->i_ino,
++					(unsigned)le32_to_cpu(ni->type));
++			err = -EOPNOTSUPP;
++			goto bad_out;
++		}
++	}
++	/*
++	 * If the size is shrinking, need to reduce the initialized_size and
++	 * the data_size before reducing the allocation.
++	 */
++	if (size_change < 0) {
++		/*
++		 * Make the valid size smaller (i_size is already up-to-date).
++		 */
++		write_lock_irqsave(&ni->size_lock, flags);
++		if (new_size < ni->initialized_size) {
++			ni->initialized_size = new_size;
++			a->data.non_resident.initialized_size =
++					cpu_to_sle64(new_size);
++		}
++		a->data.non_resident.data_size = cpu_to_sle64(new_size);
++		write_unlock_irqrestore(&ni->size_lock, flags);
++		flush_dcache_mft_record_page(ctx->ntfs_ino);
++		mark_mft_record_dirty(ctx->ntfs_ino);
++		/* If the allocated size is not changing, we are done. */
++		if (!alloc_change)
++			goto unm_done;
++		/*
++		 * If the size is shrinking it makes no sense for the
++		 * allocation to be growing.
++		 */
++		BUG_ON(alloc_change > 0);
++	} else /* if (size_change >= 0) */ {
++		/*
++		 * The file size is growing or staying the same but the
++		 * allocation can be shrinking, growing or staying the same.
++		 */
++		if (alloc_change > 0) {
++			/*
++			 * We need to extend the allocation and possibly update
++			 * the data size.  If we are updating the data size,
++			 * since we are not touching the initialized_size we do
++			 * not need to worry about the actual data on disk.
++			 * And as far as the page cache is concerned, there
++			 * will be no pages beyond the old data size and any
++			 * partial region in the last page between the old and
++			 * new data size (or the end of the page if the new
++			 * data size is outside the page) does not need to be
++			 * modified as explained above for the resident
++			 * attribute truncate case.  To do this, we simply drop
++			 * the locks we hold and leave all the work to our
++			 * friendly helper ntfs_attr_extend_allocation().
++			 */
++			ntfs_attr_put_search_ctx(ctx);
++			unmap_mft_record(base_ni);
++			up_write(&ni->runlist.lock);
++			err = ntfs_attr_extend_allocation(ni, new_size,
++					size_change > 0 ? new_size : -1, -1);
++			/*
++			 * ntfs_attr_extend_allocation() will have done error
++			 * output already.
++			 */
++			goto done;
++		}
++		if (!alloc_change)
++			goto alloc_done;
++	}
++	/* alloc_change < 0 */
++	/* Free the clusters. */
++	nr_freed = ntfs_cluster_free(ni, new_alloc_size >>
++			vol->cluster_size_bits, -1, ctx);
++	m = ctx->mrec;
++	a = ctx->attr;
++	if (unlikely(nr_freed < 0)) {
++		ntfs_error(vol->sb, "Failed to release cluster(s) (error code "
++				"%lli).  Unmount and run chkdsk to recover "
++				"the lost cluster(s).", (long long)nr_freed);
+ 		NVolSetErrors(vol);
++		nr_freed = 0;
++	}
++	/* Truncate the runlist. */
++	err = ntfs_rl_truncate_nolock(vol, &ni->runlist,
++			new_alloc_size >> vol->cluster_size_bits);
++	/*
++	 * If the runlist truncation failed and/or the search context is no
++	 * longer valid, we cannot resize the attribute record or build the
++	 * mapping pairs array thus we mark the inode bad so that no access to
++	 * the freed clusters can happen.
++	 */
++	if (unlikely(err || IS_ERR(m))) {
++		ntfs_error(vol->sb, "Failed to %s (error code %li).%s",
++				IS_ERR(m) ?
++				"restore attribute search context" :
++				"truncate attribute runlist",
++				IS_ERR(m) ? PTR_ERR(m) : err, es);
++		err = -EIO;
++		goto bad_out;
++	}
++	/* Get the size for the shrunk mapping pairs array for the runlist. */
++	mp_size = ntfs_get_size_for_mapping_pairs(vol, ni->runlist.rl, 0, -1);
++	if (unlikely(mp_size <= 0)) {
++		ntfs_error(vol->sb, "Cannot shrink allocation of inode 0x%lx, "
++				"attribute type 0x%x, because determining the "
++				"size for the mapping pairs failed with error "
++				"code %i.%s", vi->i_ino,
++				(unsigned)le32_to_cpu(ni->type), mp_size, es);
++		err = -EIO;
++		goto bad_out;
++	}
++	/*
++	 * Shrink the attribute record for the new mapping pairs array.  Note,
++	 * this cannot fail since we are making the attribute smaller thus by
++	 * definition there is enough space to do so.
++	 */
++	attr_len = le32_to_cpu(a->length);
++	err = ntfs_attr_record_resize(m, a, mp_size +
++			le16_to_cpu(a->data.non_resident.mapping_pairs_offset));
++	BUG_ON(err);
++	/*
++	 * Generate the mapping pairs array directly into the attribute record.
++	 */
++	err = ntfs_mapping_pairs_build(vol, (u8*)a +
++			le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
++			mp_size, ni->runlist.rl, 0, -1, NULL);
++	if (unlikely(err)) {
++		ntfs_error(vol->sb, "Cannot shrink allocation of inode 0x%lx, "
++				"attribute type 0x%x, because building the "
++				"mapping pairs failed with error code %i.%s",
++				vi->i_ino, (unsigned)le32_to_cpu(ni->type),
++				err, es);
++		err = -EIO;
++		goto bad_out;
++	}
++	/* Update the allocated/compressed size as well as the highest vcn. */
++	a->data.non_resident.highest_vcn = cpu_to_sle64((new_alloc_size >>
++			vol->cluster_size_bits) - 1);
++	write_lock_irqsave(&ni->size_lock, flags);
++	ni->allocated_size = new_alloc_size;
++	a->data.non_resident.allocated_size = cpu_to_sle64(new_alloc_size);
++	if (NInoSparse(ni) || NInoCompressed(ni)) {
++		if (nr_freed) {
++			ni->itype.compressed.size -= nr_freed <<
++					vol->cluster_size_bits;
++			BUG_ON(ni->itype.compressed.size < 0);
++			a->data.non_resident.compressed_size = cpu_to_sle64(
++					ni->itype.compressed.size);
++			vi->i_blocks = ni->itype.compressed.size >> 9;
++		}
++	} else
++		vi->i_blocks = new_alloc_size >> 9;
++	write_unlock_irqrestore(&ni->size_lock, flags);
++	/*
++	 * We have shrunk the allocation.  If this is a shrinking truncate we
++	 * have already dealt with the initialized_size and the data_size above
++	 * and we are done.  If the truncate is only changing the allocation
++	 * and not the data_size, we are also done.  If this is an extending
++	 * truncate, need to extend the data_size now which is ensured by the
++	 * fact that @size_change is positive.
++	 */
++alloc_done:
++	/*
++	 * If the size is growing, need to update it now.  If it is shrinking,
++	 * we have already updated it above (before the allocation change).
++	 */
++	if (size_change > 0)
++		a->data.non_resident.data_size = cpu_to_sle64(new_size);
++	/* Ensure the modified mft record is written out. */
++	flush_dcache_mft_record_page(ctx->ntfs_ino);
++	mark_mft_record_dirty(ctx->ntfs_ino);
++unm_done:
++	ntfs_attr_put_search_ctx(ctx);
++	unmap_mft_record(base_ni);
++	up_write(&ni->runlist.lock);
++done:
++	/* Update the mtime and ctime on the base inode. */
++	inode_update_time(VFS_I(base_ni), 1);
++	if (likely(!err)) {
++		NInoClearTruncateFailed(ni);
++		ntfs_debug("Done.");
++	}
++	return err;
++old_bad_out:
++	old_size = -1;
++bad_out:
++	if (err != -ENOMEM && err != -EOPNOTSUPP) {
+ 		make_bad_inode(vi);
++		make_bad_inode(VFS_I(base_ni));
++		NVolSetErrors(vol);
+ 	}
++	if (err != -EOPNOTSUPP)
++		NInoSetTruncateFailed(ni);
++	else if (old_size >= 0)
++		i_size_write(vi, old_size);
++err_out:
+ 	if (ctx)
+ 		ntfs_attr_put_search_ctx(ctx);
+ 	if (m)
+-		unmap_mft_record(ni);
+-	NInoSetTruncateFailed(ni);
++		unmap_mft_record(base_ni);
++	up_write(&ni->runlist.lock);
++out:
++	ntfs_debug("Failed.  Returning error code %i.", err);
+ 	return err;
++conv_err_out:
++	if (err != -ENOMEM && err != -EOPNOTSUPP) {
++		make_bad_inode(vi);
++		make_bad_inode(VFS_I(base_ni));
++		NVolSetErrors(vol);
++	}
++	if (err != -EOPNOTSUPP)
++		NInoSetTruncateFailed(ni);
++	else
++		i_size_write(vi, old_size);
++	goto out;
+ }
+ 
+ /**
+@@ -2420,8 +2845,7 @@ int ntfs_setattr(struct dentry *dentry, 
+ 
+ 	err = inode_change_ok(vi, attr);
+ 	if (err)
+-		return err;
+-
++		goto out;
+ 	/* We do not support NTFS ACLs yet. */
+ 	if (ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE)) {
+ 		ntfs_warning(vi->i_sb, "Changes in user/group/mode are not "
+@@ -2429,14 +2853,22 @@ int ntfs_setattr(struct dentry *dentry, 
+ 		err = -EOPNOTSUPP;
+ 		goto out;
+ 	}
+-
+ 	if (ia_valid & ATTR_SIZE) {
+ 		if (attr->ia_size != i_size_read(vi)) {
+-			ntfs_warning(vi->i_sb, "Changes in inode size are not "
+-					"supported yet, ignoring.");
+-			err = -EOPNOTSUPP;
+-			// TODO: Implement...
+-			// err = vmtruncate(vi, attr->ia_size);
++			ntfs_inode *ni = NTFS_I(vi);
++			/*
++			 * FIXME: For now we do not support resizing of
++			 * compressed or encrypted files yet.
++			 */
++			if (NInoCompressed(ni) || NInoEncrypted(ni)) {
++				ntfs_warning(vi->i_sb, "Changes in inode size "
++						"are not supported yet for "
++						"%s files, ignoring.",
++						NInoCompressed(ni) ?
++						"compressed" : "encrypted");
++				err = -EOPNOTSUPP;
++			} else
++				err = vmtruncate(vi, attr->ia_size);
+ 			if (err || ia_valid == ATTR_SIZE)
+ 				goto out;
+ 		} else {
+diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
+--- a/fs/ntfs/layout.h
++++ b/fs/ntfs/layout.h
+@@ -1021,10 +1021,17 @@ enum {
+ 	FILE_NAME_POSIX		= 0x00,
+ 	/* This is the largest namespace. It is case sensitive and allows all
+ 	   Unicode characters except for: '\0' and '/'.  Beware that in
+-	   WinNT/2k files which eg have the same name except for their case
+-	   will not be distinguished by the standard utilities and thus a "del
+-	   filename" will delete both "filename" and "fileName" without
+-	   warning. */
++	   WinNT/2k/2003 by default files which eg have the same name except
++	   for their case will not be distinguished by the standard utilities
++	   and thus a "del filename" will delete both "filename" and "fileName"
++	   without warning.  However if for example Services For Unix (SFU) are
++	   installed and the case sensitive option was enabled at installation
++	   time, then you can create/access/delete such files.
++	   Note that even SFU places restrictions on the filenames beyond the
++	   '\0' and '/' and in particular the following set of characters is
++	   not allowed: '"', '/', '<', '>', '\'.  All other characters,
++	   including the ones no allowed in WIN32 namespace are allowed.
++	   Tested with SFU 3.5 (this is now free) running on Windows XP. */
+ 	FILE_NAME_WIN32		= 0x01,
+ 	/* The standard WinNT/2k NTFS long filenames. Case insensitive.  All
+ 	   Unicode chars except: '\0', '"', '*', '/', ':', '<', '>', '?', '\',
+@@ -2367,7 +2374,9 @@ typedef struct {
+  * Extended attribute flags (8-bit).
+  */
+ enum {
+-	NEED_EA	= 0x80
++	NEED_EA	= 0x80		/* If set the file to which the EA belongs
++				   cannot be interpreted without understanding
++				   the associates extended attributes. */
+ } __attribute__ ((__packed__));
+ 
+ typedef u8 EA_FLAGS;
+@@ -2375,20 +2384,20 @@ typedef u8 EA_FLAGS;
+ /*
+  * Attribute: Extended attribute (EA) (0xe0).
+  *
+- * NOTE: Always non-resident. (Is this true?)
++ * NOTE: Can be resident or non-resident.
+  *
+  * Like the attribute list and the index buffer list, the EA attribute value is
+  * a sequence of EA_ATTR variable length records.
+- *
+- * FIXME: It appears weird that the EA name is not unicode. Is it true?
+  */
+ typedef struct {
+ 	le32 next_entry_offset;	/* Offset to the next EA_ATTR. */
+ 	EA_FLAGS flags;		/* Flags describing the EA. */
+-	u8 ea_name_length;	/* Length of the name of the EA in bytes. */
++	u8 ea_name_length;	/* Length of the name of the EA in bytes
++				   excluding the '\0' byte terminator. */
+ 	le16 ea_value_length;	/* Byte size of the EA's value. */
+-	u8 ea_name[0];		/* Name of the EA. */
+-	u8 ea_value[0];		/* The value of the EA. Immediately follows
++	u8 ea_name[0];		/* Name of the EA.  Note this is ASCII, not
++				   Unicode and it is zero terminated. */
++	u8 ea_value[0];		/* The value of the EA.  Immediately follows
+ 				   the name. */
+ } __attribute__ ((__packed__)) EA_ATTR;
+ 
+diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
+--- a/fs/ntfs/lcnalloc.c
++++ b/fs/ntfs/lcnalloc.c
+@@ -76,6 +76,7 @@ int ntfs_cluster_free_from_rl_nolock(ntf
+  * @count:	number of clusters to allocate
+  * @start_lcn:	starting lcn at which to allocate the clusters (or -1 if none)
+  * @zone:	zone from which to allocate the clusters
++ * @is_extension:	if TRUE, this is an attribute extension
+  *
+  * Allocate @count clusters preferably starting at cluster @start_lcn or at the
+  * current allocator position if @start_lcn is -1, on the mounted ntfs volume
+@@ -86,6 +87,13 @@ int ntfs_cluster_free_from_rl_nolock(ntf
+  * @start_vcn specifies the vcn of the first allocated cluster.  This makes
+  * merging the resulting runlist with the old runlist easier.
+  *
++ * If @is_extension is TRUE, the caller is allocating clusters to extend an
++ * attribute and if it is FALSE, the caller is allocating clusters to fill a
++ * hole in an attribute.  Practically the difference is that if @is_extension
++ * is TRUE the returned runlist will be terminated with LCN_ENOENT and if
++ * @is_extension is FALSE the runlist will be terminated with
++ * LCN_RL_NOT_MAPPED.
++ *
+  * You need to check the return value with IS_ERR().  If this is false, the
+  * function was successful and the return value is a runlist describing the
+  * allocated cluster(s).  If IS_ERR() is true, the function failed and
+@@ -137,7 +145,8 @@ int ntfs_cluster_free_from_rl_nolock(ntf
+  */
+ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
+ 		const s64 count, const LCN start_lcn,
+-		const NTFS_CLUSTER_ALLOCATION_ZONES zone)
++		const NTFS_CLUSTER_ALLOCATION_ZONES zone,
++		const BOOL is_extension)
+ {
+ 	LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;
+ 	LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size;
+@@ -310,7 +319,7 @@ runlist_element *ntfs_cluster_alloc(ntfs
+ 				continue;
+ 			}
+ 			bit = 1 << (lcn & 7);
+-			ntfs_debug("bit %i.", bit);
++			ntfs_debug("bit 0x%x.", bit);
+ 			/* If the bit is already set, go onto the next one. */
+ 			if (*byte & bit) {
+ 				lcn++;
+@@ -729,7 +738,7 @@ out:
+ 	/* Add runlist terminator element. */
+ 	if (likely(rl)) {
+ 		rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length;
+-		rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
++		rl[rlpos].lcn = is_extension ? LCN_ENOENT : LCN_RL_NOT_MAPPED;
+ 		rl[rlpos].length = 0;
+ 	}
+ 	if (likely(page && !IS_ERR(page))) {
+@@ -782,6 +791,7 @@ out:
+  * @ni:		ntfs inode whose runlist describes the clusters to free
+  * @start_vcn:	vcn in the runlist of @ni at which to start freeing clusters
+  * @count:	number of clusters to free or -1 for all clusters
++ * @ctx:	active attribute search context if present or NULL if not
+  * @is_rollback:	true if this is a rollback operation
+  *
+  * Free @count clusters starting at the cluster @start_vcn in the runlist
+@@ -791,15 +801,39 @@ out:
+  * deallocated.  Thus, to completely free all clusters in a runlist, use
+  * @start_vcn = 0 and @count = -1.
+  *
++ * If @ctx is specified, it is an active search context of @ni and its base mft
++ * record.  This is needed when __ntfs_cluster_free() encounters unmapped
++ * runlist fragments and allows their mapping.  If you do not have the mft
++ * record mapped, you can specify @ctx as NULL and __ntfs_cluster_free() will
++ * perform the necessary mapping and unmapping.
++ *
++ * Note, __ntfs_cluster_free() saves the state of @ctx on entry and restores it
++ * before returning.  Thus, @ctx will be left pointing to the same attribute on
++ * return as on entry.  However, the actual pointers in @ctx may point to
++ * different memory locations on return, so you must remember to reset any
++ * cached pointers from the @ctx, i.e. after the call to __ntfs_cluster_free(),
++ * you will probably want to do:
++ *	m = ctx->mrec;
++ *	a = ctx->attr;
++ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
++ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
++ *
+  * @is_rollback should always be FALSE, it is for internal use to rollback
+  * errors.  You probably want to use ntfs_cluster_free() instead.
+  *
+- * Note, ntfs_cluster_free() does not modify the runlist at all, so the caller
+- * has to deal with it later.
++ * Note, __ntfs_cluster_free() does not modify the runlist, so you have to
++ * remove from the runlist or mark sparse the freed runs later.
+  *
+  * Return the number of deallocated clusters (not counting sparse ones) on
+  * success and -errno on error.
+  *
++ * WARNING: If @ctx is supplied, regardless of whether success or failure is
++ *	    returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
++ *	    is no longer valid, i.e. you need to either call
++ *	    ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
++ *	    In that case PTR_ERR(@ctx->mrec) will give you the error code for
++ *	    why the mapping of the old inode failed.
++ *
+  * Locking: - The runlist described by @ni must be locked for writing on entry
+  *	      and is locked on return.  Note the runlist may be modified when
+  *	      needed runlist fragments need to be mapped.
+@@ -807,9 +841,13 @@ out:
+  *	      on return.
+  *	    - This function takes the volume lcn bitmap lock for writing and
+  *	      modifies the bitmap contents.
++ *	    - If @ctx is NULL, the base mft record of @ni must not be mapped on
++ *	      entry and it will be left unmapped on return.
++ *	    - If @ctx is not NULL, the base mft record must be mapped on entry
++ *	      and it will be left mapped on return.
+  */
+ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
+-		const BOOL is_rollback)
++		ntfs_attr_search_ctx *ctx, const BOOL is_rollback)
+ {
+ 	s64 delta, to_free, total_freed, real_freed;
+ 	ntfs_volume *vol;
+@@ -839,7 +877,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, 
+ 
+ 	total_freed = real_freed = 0;
+ 
+-	rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, TRUE);
++	rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, ctx);
+ 	if (IS_ERR(rl)) {
+ 		if (!is_rollback)
+ 			ntfs_error(vol->sb, "Failed to find first runlist "
+@@ -893,7 +931,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, 
+ 
+ 			/* Attempt to map runlist. */
+ 			vcn = rl->vcn;
+-			rl = ntfs_attr_find_vcn_nolock(ni, vcn, TRUE);
++			rl = ntfs_attr_find_vcn_nolock(ni, vcn, ctx);
+ 			if (IS_ERR(rl)) {
+ 				err = PTR_ERR(rl);
+ 				if (!is_rollback)
+@@ -961,7 +999,7 @@ err_out:
+ 	 * If rollback fails, set the volume errors flag, emit an error
+ 	 * message, and return the error code.
+ 	 */
+-	delta = __ntfs_cluster_free(ni, start_vcn, total_freed, TRUE);
++	delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, TRUE);
+ 	if (delta < 0) {
+ 		ntfs_error(vol->sb, "Failed to rollback (error %i).  Leaving "
+ 				"inconsistent metadata!  Unmount and run "
+diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h
+--- a/fs/ntfs/lcnalloc.h
++++ b/fs/ntfs/lcnalloc.h
+@@ -27,6 +27,7 @@
+ 
+ #include <linux/fs.h>
+ 
++#include "attrib.h"
+ #include "types.h"
+ #include "inode.h"
+ #include "runlist.h"
+@@ -41,16 +42,18 @@ typedef enum {
+ 
+ extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol,
+ 		const VCN start_vcn, const s64 count, const LCN start_lcn,
+-		const NTFS_CLUSTER_ALLOCATION_ZONES zone);
++		const NTFS_CLUSTER_ALLOCATION_ZONES zone,
++		const BOOL is_extension);
+ 
+ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
+-		s64 count, const BOOL is_rollback);
++		s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback);
+ 
+ /**
+  * ntfs_cluster_free - free clusters on an ntfs volume
+  * @ni:		ntfs inode whose runlist describes the clusters to free
+  * @start_vcn:	vcn in the runlist of @ni at which to start freeing clusters
+  * @count:	number of clusters to free or -1 for all clusters
++ * @ctx:	active attribute search context if present or NULL if not
+  *
+  * Free @count clusters starting at the cluster @start_vcn in the runlist
+  * described by the ntfs inode @ni.
+@@ -59,12 +62,36 @@ extern s64 __ntfs_cluster_free(ntfs_inod
+  * deallocated.  Thus, to completely free all clusters in a runlist, use
+  * @start_vcn = 0 and @count = -1.
+  *
+- * Note, ntfs_cluster_free() does not modify the runlist at all, so the caller
+- * has to deal with it later.
++ * If @ctx is specified, it is an active search context of @ni and its base mft
++ * record.  This is needed when ntfs_cluster_free() encounters unmapped runlist
++ * fragments and allows their mapping.  If you do not have the mft record
++ * mapped, you can specify @ctx as NULL and ntfs_cluster_free() will perform
++ * the necessary mapping and unmapping.
++ *
++ * Note, ntfs_cluster_free() saves the state of @ctx on entry and restores it
++ * before returning.  Thus, @ctx will be left pointing to the same attribute on
++ * return as on entry.  However, the actual pointers in @ctx may point to
++ * different memory locations on return, so you must remember to reset any
++ * cached pointers from the @ctx, i.e. after the call to ntfs_cluster_free(),
++ * you will probably want to do:
++ *	m = ctx->mrec;
++ *	a = ctx->attr;
++ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
++ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
++ *
++ * Note, ntfs_cluster_free() does not modify the runlist, so you have to remove
++ * from the runlist or mark sparse the freed runs later.
+  *
+  * Return the number of deallocated clusters (not counting sparse ones) on
+  * success and -errno on error.
+  *
++ * WARNING: If @ctx is supplied, regardless of whether success or failure is
++ *	    returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
++ *	    is no longer valid, i.e. you need to either call
++ *	    ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
++ *	    In that case PTR_ERR(@ctx->mrec) will give you the error code for
++ *	    why the mapping of the old inode failed.
++ *
+  * Locking: - The runlist described by @ni must be locked for writing on entry
+  *	      and is locked on return.  Note the runlist may be modified when
+  *	      needed runlist fragments need to be mapped.
+@@ -72,11 +99,15 @@ extern s64 __ntfs_cluster_free(ntfs_inod
+  *	      on return.
+  *	    - This function takes the volume lcn bitmap lock for writing and
+  *	      modifies the bitmap contents.
++ *	    - If @ctx is NULL, the base mft record of @ni must not be mapped on
++ *	      entry and it will be left unmapped on return.
++ *	    - If @ctx is not NULL, the base mft record must be mapped on entry
++ *	      and it will be left mapped on return.
+  */
+ static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
+-		s64 count)
++		s64 count, ntfs_attr_search_ctx *ctx)
+ {
+-	return __ntfs_cluster_free(ni, start_vcn, count, FALSE);
++	return __ntfs_cluster_free(ni, start_vcn, count, ctx, FALSE);
+ }
+ 
+ extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
+diff --git a/fs/ntfs/malloc.h b/fs/ntfs/malloc.h
+--- a/fs/ntfs/malloc.h
++++ b/fs/ntfs/malloc.h
+@@ -39,8 +39,7 @@
+  * If there was insufficient memory to complete the request, return NULL.
+  * Depending on @gfp_mask the allocation may be guaranteed to succeed.
+  */
+-static inline void *__ntfs_malloc(unsigned long size,
+-		gfp_t gfp_mask)
++static inline void *__ntfs_malloc(unsigned long size, gfp_t gfp_mask)
+ {
+ 	if (likely(size <= PAGE_SIZE)) {
+ 		BUG_ON(!size);
+diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
+--- a/fs/ntfs/mft.c
++++ b/fs/ntfs/mft.c
+@@ -49,7 +49,8 @@ static inline MFT_RECORD *map_mft_record
+ 	ntfs_volume *vol = ni->vol;
+ 	struct inode *mft_vi = vol->mft_ino;
+ 	struct page *page;
+-	unsigned long index, ofs, end_index;
++	unsigned long index, end_index;
++	unsigned ofs;
+ 
+ 	BUG_ON(ni->page);
+ 	/*
+@@ -1308,7 +1309,7 @@ static int ntfs_mft_bitmap_extend_alloca
+ 	ll = mftbmp_ni->allocated_size;
+ 	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
+ 	rl = ntfs_attr_find_vcn_nolock(mftbmp_ni,
+-			(ll - 1) >> vol->cluster_size_bits, TRUE);
++			(ll - 1) >> vol->cluster_size_bits, NULL);
+ 	if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
+ 		up_write(&mftbmp_ni->runlist.lock);
+ 		ntfs_error(vol->sb, "Failed to determine last allocated "
+@@ -1354,7 +1355,8 @@ static int ntfs_mft_bitmap_extend_alloca
+ 		up_write(&vol->lcnbmp_lock);
+ 		ntfs_unmap_page(page);
+ 		/* Allocate a cluster from the DATA_ZONE. */
+-		rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE);
++		rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE,
++				TRUE);
+ 		if (IS_ERR(rl2)) {
+ 			up_write(&mftbmp_ni->runlist.lock);
+ 			ntfs_error(vol->sb, "Failed to allocate a cluster for "
+@@ -1738,7 +1740,7 @@ static int ntfs_mft_data_extend_allocati
+ 	ll = mft_ni->allocated_size;
+ 	read_unlock_irqrestore(&mft_ni->size_lock, flags);
+ 	rl = ntfs_attr_find_vcn_nolock(mft_ni,
+-			(ll - 1) >> vol->cluster_size_bits, TRUE);
++			(ll - 1) >> vol->cluster_size_bits, NULL);
+ 	if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
+ 		up_write(&mft_ni->runlist.lock);
+ 		ntfs_error(vol->sb, "Failed to determine last allocated "
+@@ -1779,7 +1781,8 @@ static int ntfs_mft_data_extend_allocati
+ 			nr > min_nr ? "default" : "minimal", (long long)nr);
+ 	old_last_vcn = rl[1].vcn;
+ 	do {
+-		rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE);
++		rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE,
++				TRUE);
+ 		if (likely(!IS_ERR(rl2)))
+ 			break;
+ 		if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) {
+@@ -1951,20 +1954,21 @@ restore_undo_alloc:
+ 		NVolSetErrors(vol);
+ 		return ret;
+ 	}
+-	a = ctx->attr;
+-	a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1);
++	ctx->attr->data.non_resident.highest_vcn =
++			cpu_to_sle64(old_last_vcn - 1);
+ undo_alloc:
+-	if (ntfs_cluster_free(mft_ni, old_last_vcn, -1) < 0) {
++	if (ntfs_cluster_free(mft_ni, old_last_vcn, -1, ctx) < 0) {
+ 		ntfs_error(vol->sb, "Failed to free clusters from mft data "
+ 				"attribute.%s", es);
+ 		NVolSetErrors(vol);
+ 	}
++	a = ctx->attr;
+ 	if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) {
+ 		ntfs_error(vol->sb, "Failed to truncate mft data attribute "
+ 				"runlist.%s", es);
+ 		NVolSetErrors(vol);
+ 	}
+-	if (mp_rebuilt) {
++	if (mp_rebuilt && !IS_ERR(ctx->mrec)) {
+ 		if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
+ 				a->data.non_resident.mapping_pairs_offset),
+ 				old_alen - le16_to_cpu(
+@@ -1981,6 +1985,10 @@ undo_alloc:
+ 		}
+ 		flush_dcache_mft_record_page(ctx->ntfs_ino);
+ 		mark_mft_record_dirty(ctx->ntfs_ino);
++	} else if (IS_ERR(ctx->mrec)) {
++		ntfs_error(vol->sb, "Failed to restore attribute search "
++				"context.%s", es);
++		NVolSetErrors(vol);
+ 	}
+ 	if (ctx)
+ 		ntfs_attr_put_search_ctx(ctx);
+diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
+--- a/fs/ntfs/super.c
++++ b/fs/ntfs/super.c
+@@ -1447,7 +1447,7 @@ not_enabled:
+ 	if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) {
+ 		ntfs_error(vol->sb, "Found corrupt $UsnJrnl/$DATA/$Max "
+ 				"attribute (size is 0x%llx but should be at "
+-				"least 0x%x bytes).", i_size_read(tmp_ino),
++				"least 0x%zx bytes).", i_size_read(tmp_ino),
+ 				sizeof(USN_HEADER));
+ 		return FALSE;
+ 	}
+diff --git a/fs/open.c b/fs/open.c
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -739,7 +739,8 @@ asmlinkage long sys_fchown(unsigned int 
+ }
+ 
+ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
+-					int flags, struct file *f)
++					int flags, struct file *f,
++					int (*open)(struct inode *, struct file *))
+ {
+ 	struct inode *inode;
+ 	int error;
+@@ -761,11 +762,14 @@ static struct file *__dentry_open(struct
+ 	f->f_op = fops_get(inode->i_fop);
+ 	file_move(f, &inode->i_sb->s_files);
+ 
+-	if (f->f_op && f->f_op->open) {
+-		error = f->f_op->open(inode,f);
++	if (!open && f->f_op)
++		open = f->f_op->open;
++	if (open) {
++		error = open(inode, f);
+ 		if (error)
+ 			goto cleanup_all;
+ 	}
++
+ 	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+ 
+ 	file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
+@@ -814,28 +818,75 @@ struct file *filp_open(const char * file
+ {
+ 	int namei_flags, error;
+ 	struct nameidata nd;
+-	struct file *f;
+ 
+ 	namei_flags = flags;
+ 	if ((namei_flags+1) & O_ACCMODE)
+ 		namei_flags++;
+-	if (namei_flags & O_TRUNC)
+-		namei_flags |= 2;
+-
+-	error = -ENFILE;
+-	f = get_empty_filp();
+-	if (f == NULL)
+-		return ERR_PTR(error);
+ 
+ 	error = open_namei(filename, namei_flags, mode, &nd);
+ 	if (!error)
+-		return __dentry_open(nd.dentry, nd.mnt, flags, f);
++		return nameidata_to_filp(&nd, flags);
+ 
+-	put_filp(f);
+ 	return ERR_PTR(error);
+ }
+ EXPORT_SYMBOL(filp_open);
+ 
++/**
++ * lookup_instantiate_filp - instantiates the open intent filp
++ * @nd: pointer to nameidata
++ * @dentry: pointer to dentry
++ * @open: open callback
++ *
++ * Helper for filesystems that want to use lookup open intents and pass back
++ * a fully instantiated struct file to the caller.
++ * This function is meant to be called from within a filesystem's
++ * lookup method.
++ * Note that in case of error, nd->intent.open.file is destroyed, but the
++ * path information remains valid.
++ * If the open callback is set to NULL, then the standard f_op->open()
++ * filesystem callback is substituted.
++ */
++struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
++		int (*open)(struct inode *, struct file *))
++{
++	if (IS_ERR(nd->intent.open.file))
++		goto out;
++	if (IS_ERR(dentry))
++		goto out_err;
++	nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt),
++					     nd->intent.open.flags - 1,
++					     nd->intent.open.file,
++					     open);
++out:
++	return nd->intent.open.file;
++out_err:
++	release_open_intent(nd);
++	nd->intent.open.file = (struct file *)dentry;
++	goto out;
++}
++EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
++
++/**
++ * nameidata_to_filp - convert a nameidata to an open filp.
++ * @nd: pointer to nameidata
++ * @flags: open flags
++ *
++ * Note that this function destroys the original nameidata
++ */
++struct file *nameidata_to_filp(struct nameidata *nd, int flags)
++{
++	struct file *filp;
++
++	/* Pick up the filp from the open intent */
++	filp = nd->intent.open.file;
++	/* Has the filesystem initialised the file for us? */
++	if (filp->f_dentry == NULL)
++		filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
++	else
++		path_release(nd);
++	return filp;
++}
++
+ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
+ {
+ 	int error;
+@@ -846,7 +897,7 @@ struct file *dentry_open(struct dentry *
+ 	if (f == NULL)
+ 		return ERR_PTR(error);
+ 
+-	return __dentry_open(dentry, mnt, flags, f);
++	return __dentry_open(dentry, mnt, flags, f, NULL);
+ }
+ EXPORT_SYMBOL(dentry_open);
+ 
+diff --git a/fs/partitions/check.c b/fs/partitions/check.c
+--- a/fs/partitions/check.c
++++ b/fs/partitions/check.c
+@@ -192,6 +192,7 @@ check_partition(struct gendisk *hd, stru
+ struct part_attribute {
+ 	struct attribute attr;
+ 	ssize_t (*show)(struct hd_struct *,char *);
++	ssize_t (*store)(struct hd_struct *,const char *, size_t);
+ };
+ 
+ static ssize_t 
+@@ -201,14 +202,33 @@ part_attr_show(struct kobject * kobj, st
+ 	struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
+ 	ssize_t ret = 0;
+ 	if (part_attr->show)
+-		ret = part_attr->show(p,page);
++		ret = part_attr->show(p, page);
++	return ret;
++}
++static ssize_t
++part_attr_store(struct kobject * kobj, struct attribute * attr,
++		const char *page, size_t count)
++{
++	struct hd_struct * p = container_of(kobj,struct hd_struct,kobj);
++	struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
++	ssize_t ret = 0;
++
++	if (part_attr->store)
++		ret = part_attr->store(p, page, count);
+ 	return ret;
+ }
+ 
+ static struct sysfs_ops part_sysfs_ops = {
+ 	.show	=	part_attr_show,
++	.store	=	part_attr_store,
+ };
+ 
++static ssize_t part_uevent_store(struct hd_struct * p,
++				 const char *page, size_t count)
++{
++	kobject_hotplug(&p->kobj, KOBJ_ADD);
++	return count;
++}
+ static ssize_t part_dev_read(struct hd_struct * p, char *page)
+ {
+ 	struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj);
+@@ -229,6 +249,10 @@ static ssize_t part_stat_read(struct hd_
+ 		       p->reads, (unsigned long long)p->read_sectors,
+ 		       p->writes, (unsigned long long)p->write_sectors);
+ }
++static struct part_attribute part_attr_uevent = {
++	.attr = {.name = "uevent", .mode = S_IWUSR },
++	.store	= part_uevent_store
++};
+ static struct part_attribute part_attr_dev = {
+ 	.attr = {.name = "dev", .mode = S_IRUGO },
+ 	.show	= part_dev_read
+@@ -247,6 +271,7 @@ static struct part_attribute part_attr_s
+ };
+ 
+ static struct attribute * default_attrs[] = {
++	&part_attr_uevent.attr,
+ 	&part_attr_dev.attr,
+ 	&part_attr_start.attr,
+ 	&part_attr_size.attr,
+@@ -430,7 +455,7 @@ void del_gendisk(struct gendisk *disk)
+ 	disk->flags &= ~GENHD_FL_UP;
+ 	unlink_gendisk(disk);
+ 	disk_stat_set_all(disk, 0);
+-	disk->stamp = disk->stamp_idle = 0;
++	disk->stamp = 0;
+ 
+ 	devfs_remove_disk(disk);
+ 
+diff --git a/fs/proc/array.c b/fs/proc/array.c
+--- a/fs/proc/array.c
++++ b/fs/proc/array.c
+@@ -438,7 +438,7 @@ static int do_task_stat(struct task_stru
+ 		jiffies_to_clock_t(it_real_value),
+ 		start_time,
+ 		vsize,
+-		mm ? get_mm_counter(mm, rss) : 0, /* you might want to shift this left 3 */
++		mm ? get_mm_rss(mm) : 0,
+ 	        rsslim,
+ 		mm ? mm->start_code : 0,
+ 		mm ? mm->end_code : 0,
+diff --git a/fs/proc/generic.c b/fs/proc/generic.c
+--- a/fs/proc/generic.c
++++ b/fs/proc/generic.c
+@@ -533,7 +533,7 @@ static void proc_kill_inodes(struct proc
+ 	 */
+ 	file_list_lock();
+ 	list_for_each(p, &sb->s_files) {
+-		struct file * filp = list_entry(p, struct file, f_list);
++		struct file * filp = list_entry(p, struct file, f_u.fu_list);
+ 		struct dentry * dentry = filp->f_dentry;
+ 		struct inode * inode;
+ 		struct file_operations *fops;
+diff --git a/fs/proc/inode.c b/fs/proc/inode.c
+--- a/fs/proc/inode.c
++++ b/fs/proc/inode.c
+@@ -156,10 +156,13 @@ struct inode *proc_get_inode(struct supe
+ 
+ 	WARN_ON(de && de->deleted);
+ 
++	if (de != NULL && !try_module_get(de->owner))
++		goto out_mod;
++
+ 	inode = iget(sb, ino);
+ 	if (!inode)
+-		goto out_fail;
+-	
++		goto out_ino;
++
+ 	PROC_I(inode)->pde = de;
+ 	if (de) {
+ 		if (de->mode) {
+@@ -171,20 +174,20 @@ struct inode *proc_get_inode(struct supe
+ 			inode->i_size = de->size;
+ 		if (de->nlink)
+ 			inode->i_nlink = de->nlink;
+-		if (!try_module_get(de->owner))
+-			goto out_fail;
+ 		if (de->proc_iops)
+ 			inode->i_op = de->proc_iops;
+ 		if (de->proc_fops)
+ 			inode->i_fop = de->proc_fops;
+ 	}
+ 
+-out:
+ 	return inode;
+ 
+-out_fail:
++out_ino:
++	if (de != NULL)
++		module_put(de->owner);
++out_mod:
+ 	de_put(de);
+-	goto out;
++	return NULL;
+ }			
+ 
+ int proc_fill_super(struct super_block *s, void *data, int silent)
+diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
+--- a/fs/proc/proc_misc.c
++++ b/fs/proc/proc_misc.c
+@@ -629,12 +629,4 @@ void __init proc_misc_init(void)
+ 	if (entry)
+ 		entry->proc_fops = &proc_sysrq_trigger_operations;
+ #endif
+-#ifdef CONFIG_PPC32
+-	{
+-		extern struct file_operations ppc_htab_operations;
+-		entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL);
+-		if (entry)
+-			entry->proc_fops = &ppc_htab_operations;
+-	}
+-#endif
+ }
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -14,22 +14,41 @@
+ char *task_mem(struct mm_struct *mm, char *buffer)
+ {
+ 	unsigned long data, text, lib;
++	unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
++
++	/*
++	 * Note: to minimize their overhead, mm maintains hiwater_vm and
++	 * hiwater_rss only when about to *lower* total_vm or rss.  Any
++	 * collector of these hiwater stats must therefore get total_vm
++	 * and rss too, which will usually be the higher.  Barriers? not
++	 * worth the effort, such snapshots can always be inconsistent.
++	 */
++	hiwater_vm = total_vm = mm->total_vm;
++	if (hiwater_vm < mm->hiwater_vm)
++		hiwater_vm = mm->hiwater_vm;
++	hiwater_rss = total_rss = get_mm_rss(mm);
++	if (hiwater_rss < mm->hiwater_rss)
++		hiwater_rss = mm->hiwater_rss;
+ 
+ 	data = mm->total_vm - mm->shared_vm - mm->stack_vm;
+ 	text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
+ 	lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text;
+ 	buffer += sprintf(buffer,
++		"VmPeak:\t%8lu kB\n"
+ 		"VmSize:\t%8lu kB\n"
+ 		"VmLck:\t%8lu kB\n"
++		"VmHWM:\t%8lu kB\n"
+ 		"VmRSS:\t%8lu kB\n"
+ 		"VmData:\t%8lu kB\n"
+ 		"VmStk:\t%8lu kB\n"
+ 		"VmExe:\t%8lu kB\n"
+ 		"VmLib:\t%8lu kB\n"
+ 		"VmPTE:\t%8lu kB\n",
+-		(mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
++		hiwater_vm << (PAGE_SHIFT-10),
++		(total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
+ 		mm->locked_vm << (PAGE_SHIFT-10),
+-		get_mm_counter(mm, rss) << (PAGE_SHIFT-10),
++		hiwater_rss << (PAGE_SHIFT-10),
++		total_rss << (PAGE_SHIFT-10),
+ 		data << (PAGE_SHIFT-10),
+ 		mm->stack_vm << (PAGE_SHIFT-10), text, lib,
+ 		(PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
+@@ -44,13 +63,11 @@ unsigned long task_vsize(struct mm_struc
+ int task_statm(struct mm_struct *mm, int *shared, int *text,
+ 	       int *data, int *resident)
+ {
+-	int rss = get_mm_counter(mm, rss);
+-
+-	*shared = rss - get_mm_counter(mm, anon_rss);
++	*shared = get_mm_counter(mm, file_rss);
+ 	*text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK))
+ 								>> PAGE_SHIFT;
+ 	*data = mm->total_vm - mm->shared_vm;
+-	*resident = rss;
++	*resident = *shared + get_mm_counter(mm, anon_rss);
+ 	return mm->total_vm;
+ }
+ 
+@@ -186,13 +203,14 @@ static void smaps_pte_range(struct vm_ar
+ 				struct mem_size_stats *mss)
+ {
+ 	pte_t *pte, ptent;
++	spinlock_t *ptl;
+ 	unsigned long pfn;
+ 	struct page *page;
+ 
+-	pte = pte_offset_map(pmd, addr);
++	pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+ 	do {
+ 		ptent = *pte;
+-		if (pte_none(ptent) || !pte_present(ptent))
++		if (!pte_present(ptent))
+ 			continue;
+ 
+ 		mss->resident += PAGE_SIZE;
+@@ -213,8 +231,8 @@ static void smaps_pte_range(struct vm_ar
+ 				mss->private_clean += PAGE_SIZE;
+ 		}
+ 	} while (pte++, addr += PAGE_SIZE, addr != end);
+-	pte_unmap(pte - 1);
+-	cond_resched_lock(&vma->vm_mm->page_table_lock);
++	pte_unmap_unlock(pte - 1, ptl);
++	cond_resched();
+ }
+ 
+ static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud,
+@@ -268,17 +286,11 @@ static inline void smaps_pgd_range(struc
+ static int show_smap(struct seq_file *m, void *v)
+ {
+ 	struct vm_area_struct *vma = v;
+-	struct mm_struct *mm = vma->vm_mm;
+ 	struct mem_size_stats mss;
+ 
+ 	memset(&mss, 0, sizeof mss);
+-
+-	if (mm) {
+-		spin_lock(&mm->page_table_lock);
++	if (vma->vm_mm)
+ 		smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss);
+-		spin_unlock(&mm->page_table_lock);
+-	}
+-
+ 	return show_map_internal(m, v, &mss);
+ }
+ 
+@@ -407,7 +419,6 @@ static struct numa_maps *get_numa_maps(c
+ 	for_each_node(i)
+ 		md->node[i] =0;
+ 
+-	spin_lock(&mm->page_table_lock);
+  	for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
+ 		page = follow_page(mm, vaddr, 0);
+ 		if (page) {
+@@ -422,8 +433,8 @@ static struct numa_maps *get_numa_maps(c
+ 				md->anon++;
+ 			md->node[page_to_nid(page)]++;
+ 		}
++		cond_resched();
+ 	}
+-	spin_unlock(&mm->page_table_lock);
+ 	return md;
+ }
+ 
+@@ -469,7 +480,7 @@ static int show_numa_map(struct seq_file
+ 		seq_printf(m, " interleave={");
+ 		first = 1;
+ 		for_each_node(n) {
+-			if (test_bit(n, pol->v.nodes)) {
++			if (node_isset(n, pol->v.nodes)) {
+ 				if (!first)
+ 					seq_putc(m,',');
+ 				else
+diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
+--- a/fs/reiserfs/fix_node.c
++++ b/fs/reiserfs/fix_node.c
+@@ -2022,7 +2022,7 @@ static int get_neighbors(struct tree_bal
+ }
+ 
+ #ifdef CONFIG_REISERFS_CHECK
+-void *reiserfs_kmalloc(size_t size, int flags, struct super_block *s)
++void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s)
+ {
+ 	void *vp;
+ 	static size_t malloced;
+diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
+--- a/fs/reiserfs/inode.c
++++ b/fs/reiserfs/inode.c
+@@ -2842,7 +2842,7 @@ static int reiserfs_set_page_dirty(struc
+  * even in -o notail mode, we can't be sure an old mount without -o notail
+  * didn't create files with tails.
+  */
+-static int reiserfs_releasepage(struct page *page, int unused_gfp_flags)
++static int reiserfs_releasepage(struct page *page, gfp_t unused_gfp_flags)
+ {
+ 	struct inode *inode = page->mapping->host;
+ 	struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
+diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
+--- a/fs/reiserfs/super.c
++++ b/fs/reiserfs/super.c
+@@ -1024,12 +1024,8 @@ static int reiserfs_parse_options(struct
+ 				strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg);
+ 				*mount_options |= 1 << REISERFS_QUOTA;
+ 			} else {
+-				if (REISERFS_SB(s)->s_qf_names[qtype]) {
+-					kfree(REISERFS_SB(s)->
+-					      s_qf_names[qtype]);
+-					REISERFS_SB(s)->s_qf_names[qtype] =
+-					    NULL;
+-				}
++				kfree(REISERFS_SB(s)->s_qf_names[qtype]);
++				REISERFS_SB(s)->s_qf_names[qtype] = NULL;
+ 			}
+ 		}
+ 		if (c == 'f') {
+@@ -1158,11 +1154,10 @@ static int reiserfs_remount(struct super
+ 	if (!reiserfs_parse_options
+ 	    (s, arg, &mount_options, &blocks, NULL, &commit_max_age)) {
+ #ifdef CONFIG_QUOTA
+-		for (i = 0; i < MAXQUOTAS; i++)
+-			if (REISERFS_SB(s)->s_qf_names[i]) {
+-				kfree(REISERFS_SB(s)->s_qf_names[i]);
+-				REISERFS_SB(s)->s_qf_names[i] = NULL;
+-			}
++		for (i = 0; i < MAXQUOTAS; i++) {
++			kfree(REISERFS_SB(s)->s_qf_names[i]);
++			REISERFS_SB(s)->s_qf_names[i] = NULL;
++		}
+ #endif
+ 		return -EINVAL;
+ 	}
+@@ -1940,13 +1935,11 @@ static int reiserfs_fill_super(struct su
+ 		brelse(SB_BUFFER_WITH_SB(s));
+ #ifdef CONFIG_QUOTA
+ 	for (j = 0; j < MAXQUOTAS; j++) {
+-		if (sbi->s_qf_names[j])
+-			kfree(sbi->s_qf_names[j]);
++		kfree(sbi->s_qf_names[j]);
++		sbi->s_qf_names[j] = NULL;
+ 	}
+ #endif
+-	if (sbi != NULL) {
+-		kfree(sbi);
+-	}
++	kfree(sbi);
+ 
+ 	s->s_fs_info = NULL;
+ 	return errval;
+diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
+--- a/fs/reiserfs/xattr.c
++++ b/fs/reiserfs/xattr.c
+@@ -453,7 +453,7 @@ static struct page *reiserfs_get_page(st
+ 	struct page *page;
+ 	/* We can deadlock if we try to free dentries,
+ 	   and an unlink/rmdir has just occured - GFP_NOFS avoids this */
+-	mapping->flags = (mapping->flags & ~__GFP_BITS_MASK) | GFP_NOFS;
++	mapping_set_gfp_mask(mapping, GFP_NOFS);
+ 	page = read_cache_page(mapping, n,
+ 			       (filler_t *) mapping->a_ops->readpage, NULL);
+ 	if (!IS_ERR(page)) {
+diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
+--- a/fs/reiserfs/xattr_acl.c
++++ b/fs/reiserfs/xattr_acl.c
+@@ -296,8 +296,7 @@ reiserfs_set_acl(struct inode *inode, in
+ 		}
+ 	}
+ 
+-	if (value)
+-		kfree(value);
++	kfree(value);
+ 
+ 	if (!error) {
+ 		/* Release the old one */
+diff --git a/fs/super.c b/fs/super.c
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -513,7 +513,7 @@ static void mark_files_ro(struct super_b
+ 	struct file *f;
+ 
+ 	file_list_lock();
+-	list_for_each_entry(f, &sb->s_files, f_list) {
++	list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
+ 		if (S_ISREG(f->f_dentry->d_inode->i_mode) && file_count(f))
+ 			f->f_mode &= ~FMODE_WRITE;
+ 	}
+diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
+--- a/fs/vfat/namei.c
++++ b/fs/vfat/namei.c
+@@ -621,8 +621,7 @@ static int vfat_build_slots(struct inode
+ 	}
+ 
+ 	/* build the entry of long file name */
+-	for (cksum = i = 0; i < 11; i++)
+-		cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
++	cksum = fat_checksum(msdos_name);
+ 
+ 	*nr_slots = usize / 13;
+ 	for (ps = slots, i = *nr_slots; i > 0; i--, ps++) {
+@@ -888,10 +887,10 @@ static int vfat_rename(struct inode *old
+ {
+ 	struct buffer_head *dotdot_bh;
+ 	struct msdos_dir_entry *dotdot_de;
+-	loff_t dotdot_i_pos;
+ 	struct inode *old_inode, *new_inode;
+ 	struct fat_slot_info old_sinfo, sinfo;
+ 	struct timespec ts;
++	loff_t dotdot_i_pos, new_i_pos;
+ 	int err, is_dir, update_dotdot, corrupt = 0;
+ 
+ 	old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
+@@ -914,31 +913,24 @@ static int vfat_rename(struct inode *old
+ 
+ 	ts = CURRENT_TIME_SEC;
+ 	if (new_inode) {
+-		err = vfat_find(new_dir, &new_dentry->d_name, &sinfo);
+-		if (err)
+-			goto out;
+-		if (MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
+-			/* WTF??? Cry and fail. */
+-			printk(KERN_WARNING "vfat_rename: fs corrupted\n");
+-			goto out;
+-		}
+-
+ 		if (is_dir) {
+ 			err = fat_dir_empty(new_inode);
+ 			if (err)
+ 				goto out;
+ 		}
++		new_i_pos = MSDOS_I(new_inode)->i_pos;
+ 		fat_detach(new_inode);
+ 	} else {
+ 		err = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir, 0,
+ 				     &ts, &sinfo);
+ 		if (err)
+ 			goto out;
++		new_i_pos = sinfo.i_pos;
+ 	}
+ 	new_dir->i_version++;
+ 
+ 	fat_detach(old_inode);
+-	fat_attach(old_inode, sinfo.i_pos);
++	fat_attach(old_inode, new_i_pos);
+ 	if (IS_DIRSYNC(new_dir)) {
+ 		err = fat_sync_inode(old_inode);
+ 		if (err)
+@@ -1002,7 +994,7 @@ error_inode:
+ 	fat_detach(old_inode);
+ 	fat_attach(old_inode, old_sinfo.i_pos);
+ 	if (new_inode) {
+-		fat_attach(new_inode, sinfo.i_pos);
++		fat_attach(new_inode, new_i_pos);
+ 		if (corrupt)
+ 			corrupt |= fat_sync_inode(new_inode);
+ 	} else {
+diff --git a/fs/xattr.c b/fs/xattr.c
+--- a/fs/xattr.c
++++ b/fs/xattr.c
+@@ -143,7 +143,7 @@ getxattr(struct dentry *d, char __user *
+ 	if (size) {
+ 		if (size > XATTR_SIZE_MAX)
+ 			size = XATTR_SIZE_MAX;
+-		kvalue = kmalloc(size, GFP_KERNEL);
++		kvalue = kzalloc(size, GFP_KERNEL);
+ 		if (!kvalue)
+ 			return -ENOMEM;
+ 	}
+@@ -154,11 +154,15 @@ getxattr(struct dentry *d, char __user *
+ 	error = -EOPNOTSUPP;
+ 	if (d->d_inode->i_op && d->d_inode->i_op->getxattr)
+ 		error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
+-	else if (!strncmp(kname, XATTR_SECURITY_PREFIX,
+-			  sizeof XATTR_SECURITY_PREFIX - 1)) {
++
++	if (!strncmp(kname, XATTR_SECURITY_PREFIX,
++		     sizeof XATTR_SECURITY_PREFIX - 1)) {
+ 		const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
+-		error = security_inode_getsecurity(d->d_inode, suffix, kvalue,
+-						   size);
++		int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue,
++						    size, error);
++		/* Security module active: overwrite error value */
++		if (rv != -EOPNOTSUPP)
++			error = rv;
+ 	}
+ 	if (error > 0) {
+ 		if (size && copy_to_user(value, kvalue, error))
+diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c
+--- a/fs/xfs/linux-2.6/kmem.c
++++ b/fs/xfs/linux-2.6/kmem.c
+@@ -45,11 +45,11 @@
+ 
+ 
+ void *
+-kmem_alloc(size_t size, gfp_t flags)
++kmem_alloc(size_t size, unsigned int __nocast flags)
+ {
+-	int		retries = 0;
+-	unsigned int	lflags = kmem_flags_convert(flags);
+-	void		*ptr;
++	int	retries = 0;
++	gfp_t	lflags = kmem_flags_convert(flags);
++	void	*ptr;
+ 
+ 	do {
+ 		if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS)
+@@ -67,7 +67,7 @@ kmem_alloc(size_t size, gfp_t flags)
+ }
+ 
+ void *
+-kmem_zalloc(size_t size, gfp_t flags)
++kmem_zalloc(size_t size, unsigned int __nocast flags)
+ {
+ 	void	*ptr;
+ 
+@@ -90,7 +90,7 @@ kmem_free(void *ptr, size_t size)
+ 
+ void *
+ kmem_realloc(void *ptr, size_t newsize, size_t oldsize,
+-	     gfp_t flags)
++	     unsigned int __nocast flags)
+ {
+ 	void	*new;
+ 
+@@ -105,11 +105,11 @@ kmem_realloc(void *ptr, size_t newsize, 
+ }
+ 
+ void *
+-kmem_zone_alloc(kmem_zone_t *zone, gfp_t flags)
++kmem_zone_alloc(kmem_zone_t *zone, unsigned int __nocast flags)
+ {
+-	int		retries = 0;
+-	unsigned int	lflags = kmem_flags_convert(flags);
+-	void		*ptr;
++	int	retries = 0;
++	gfp_t	lflags = kmem_flags_convert(flags);
++	void	*ptr;
+ 
+ 	do {
+ 		ptr = kmem_cache_alloc(zone, lflags);
+@@ -124,7 +124,7 @@ kmem_zone_alloc(kmem_zone_t *zone, gfp_t
+ }
+ 
+ void *
+-kmem_zone_zalloc(kmem_zone_t *zone, gfp_t flags)
++kmem_zone_zalloc(kmem_zone_t *zone, unsigned int __nocast flags)
+ {
+ 	void	*ptr;
+ 
+diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
+--- a/fs/xfs/linux-2.6/kmem.h
++++ b/fs/xfs/linux-2.6/kmem.h
+@@ -81,9 +81,9 @@ typedef unsigned long xfs_pflags_t;
+ 	*(NSTATEP) = *(OSTATEP);	\
+ } while (0)
+ 
+-static __inline unsigned int kmem_flags_convert(gfp_t flags)
++static __inline gfp_t kmem_flags_convert(unsigned int __nocast flags)
+ {
+-	unsigned int	lflags = __GFP_NOWARN;	/* we'll report problems, if need be */
++	gfp_t lflags = __GFP_NOWARN;	/* we'll report problems, if need be */
+ 
+ #ifdef DEBUG
+ 	if (unlikely(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL))) {
+@@ -125,16 +125,16 @@ kmem_zone_destroy(kmem_zone_t *zone)
+ 		BUG();
+ }
+ 
+-extern void	    *kmem_zone_zalloc(kmem_zone_t *, gfp_t);
+-extern void	    *kmem_zone_alloc(kmem_zone_t *, gfp_t);
++extern void	    *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);
++extern void	    *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
+ 
+-extern void	    *kmem_alloc(size_t, gfp_t);
+-extern void	    *kmem_realloc(void *, size_t, size_t, gfp_t);
+-extern void	    *kmem_zalloc(size_t, gfp_t);
++extern void	    *kmem_alloc(size_t, unsigned int __nocast);
++extern void	    *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
++extern void	    *kmem_zalloc(size_t, unsigned int __nocast);
+ extern void         kmem_free(void *, size_t);
+ 
+ typedef struct shrinker *kmem_shaker_t;
+-typedef int (*kmem_shake_func_t)(int, unsigned int);
++typedef int (*kmem_shake_func_t)(int, gfp_t);
+ 
+ static __inline kmem_shaker_t
+ kmem_shake_register(kmem_shake_func_t sfunc)
+@@ -149,7 +149,7 @@ kmem_shake_deregister(kmem_shaker_t shri
+ }
+ 
+ static __inline int
+-kmem_shake_allow(unsigned int gfp_mask)
++kmem_shake_allow(gfp_t gfp_mask)
+ {
+ 	return (gfp_mask & __GFP_WAIT);
+ }
+diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
+--- a/fs/xfs/linux-2.6/xfs_aops.c
++++ b/fs/xfs/linux-2.6/xfs_aops.c
+@@ -1296,7 +1296,7 @@ linvfs_invalidate_page(
+ STATIC int
+ linvfs_release_page(
+ 	struct page		*page,
+-	int			gfp_mask)
++	gfp_t			gfp_mask)
+ {
+ 	struct inode		*inode = page->mapping->host;
+ 	int			dirty, delalloc, unmapped, unwritten;
+diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
+--- a/fs/xfs/linux-2.6/xfs_buf.c
++++ b/fs/xfs/linux-2.6/xfs_buf.c
+@@ -64,7 +64,7 @@
+ 
+ STATIC kmem_cache_t *pagebuf_zone;
+ STATIC kmem_shaker_t pagebuf_shake;
+-STATIC int xfsbufd_wakeup(int, unsigned int);
++STATIC int xfsbufd_wakeup(int, gfp_t);
+ STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
+ 
+ STATIC struct workqueue_struct *xfslogd_workqueue;
+@@ -181,8 +181,9 @@ set_page_region(
+ 	size_t		offset,
+ 	size_t		length)
+ {
+-	page->private |= page_region_mask(offset, length);
+-	if (page->private == ~0UL)
++	set_page_private(page,
++		page_private(page) | page_region_mask(offset, length));
++	if (page_private(page) == ~0UL)
+ 		SetPageUptodate(page);
+ }
+ 
+@@ -194,7 +195,7 @@ test_page_region(
+ {
+ 	unsigned long	mask = page_region_mask(offset, length);
+ 
+-	return (mask && (page->private & mask) == mask);
++	return (mask && (page_private(page) & mask) == mask);
+ }
+ 
+ /*
+@@ -383,7 +384,7 @@ _pagebuf_lookup_pages(
+ 	size_t			blocksize = bp->pb_target->pbr_bsize;
+ 	size_t			size = bp->pb_count_desired;
+ 	size_t			nbytes, offset;
+-	int			gfp_mask = pb_to_gfp(flags);
++	gfp_t			gfp_mask = pb_to_gfp(flags);
+ 	unsigned short		page_count, i;
+ 	pgoff_t			first;
+ 	loff_t			end;
+@@ -1749,8 +1750,8 @@ STATIC int xfsbufd_force_sleep;
+ 
+ STATIC int
+ xfsbufd_wakeup(
+-	int			priority,
+-	unsigned int		mask)
++	int		priority,
++	gfp_t		mask)
+ {
+ 	if (xfsbufd_force_sleep)
+ 		return 0;
+diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h
+--- a/include/asm-alpha/barrier.h
++++ b/include/asm-alpha/barrier.h
+@@ -1,6 +1,8 @@
+ #ifndef __BARRIER_H
+ #define __BARRIER_H
+ 
++#include <asm/compiler.h>
++
+ #define mb() \
+ __asm__ __volatile__("mb": : :"memory")
+ 
+diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
+--- a/include/asm-alpha/dma-mapping.h
++++ b/include/asm-alpha/dma-mapping.h
+@@ -31,7 +31,7 @@
+ #else	/* no PCI - no IOMMU. */
+ 
+ void *dma_alloc_coherent(struct device *dev, size_t size,
+-			 dma_addr_t *dma_handle, int gfp);
++			 dma_addr_t *dma_handle, gfp_t gfp);
+ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ 	       enum dma_data_direction direction);
+ 
+diff --git a/include/asm-alpha/rwsem.h b/include/asm-alpha/rwsem.h
+--- a/include/asm-alpha/rwsem.h
++++ b/include/asm-alpha/rwsem.h
+@@ -262,5 +262,10 @@ static inline long rwsem_atomic_update(l
+ #endif
+ }
+ 
++static inline int rwsem_is_locked(struct rw_semaphore *sem)
++{
++	return (sem->count != 0);
++}
++
+ #endif /* __KERNEL__ */
+ #endif /* _ALPHA_RWSEM_H */
+diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h
+--- a/include/asm-alpha/semaphore.h
++++ b/include/asm-alpha/semaphore.h
+@@ -26,9 +26,6 @@ struct semaphore {
+   	.wait	= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait),	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name)			\
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count)		\
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h
+--- a/include/asm-arm/arch-aaec2000/aaec2000.h
++++ b/include/asm-arm/arch-aaec2000/aaec2000.h
+@@ -17,6 +17,16 @@
+ #error You must include hardware.h not this file
+ #endif /* __ASM_ARCH_HARDWARE_H */
+ 
++/* Chip selects */
++#define AAEC_CS0	0x00000000
++#define AAEC_CS1	0x10000000
++#define AAEC_CS2	0x20000000
++#define AAEC_CS3	0x30000000
++
++/* Flash */
++#define AAEC_FLASH_BASE	AAEC_CS0
++#define AAEC_FLASH_SIZE	SZ_64M
++
+ /* Interrupt controller */
+ #define IRQ_BASE	__REG(0x80000500)
+ #define IRQ_INTSR	__REG(0x80000500)	/* Int Status Register */
+@@ -148,4 +158,50 @@
+ #define POWER_STFCLR	__REG(0x8000041c) /* NbFlg, RSTFlg, PFFlg, CLDFlg Clear */
+ #define POWER_CLKSET	__REG(0x80000420) /* Clock Speed Control */
+ 
++/* GPIO Registers */
++#define AAEC_GPIO_PHYS	0x80000e00
++
++#define AAEC_GPIO_PADR		__REG(AAEC_GPIO_PHYS + 0x00)
++#define AAEC_GPIO_PBDR		__REG(AAEC_GPIO_PHYS + 0x04)
++#define AAEC_GPIO_PCDR		__REG(AAEC_GPIO_PHYS + 0x08)
++#define AAEC_GPIO_PDDR		__REG(AAEC_GPIO_PHYS + 0x0c)
++#define AAEC_GPIO_PADDR		__REG(AAEC_GPIO_PHYS + 0x10)
++#define AAEC_GPIO_PBDDR		__REG(AAEC_GPIO_PHYS + 0x14)
++#define AAEC_GPIO_PCDDR		__REG(AAEC_GPIO_PHYS + 0x18)
++#define AAEC_GPIO_PDDDR		__REG(AAEC_GPIO_PHYS + 0x1c)
++#define AAEC_GPIO_PEDR		__REG(AAEC_GPIO_PHYS + 0x20)
++#define AAEC_GPIO_PEDDR		__REG(AAEC_GPIO_PHYS + 0x24)
++#define AAEC_GPIO_KSCAN		__REG(AAEC_GPIO_PHYS + 0x28)
++#define AAEC_GPIO_PINMUX	__REG(AAEC_GPIO_PHYS + 0x2c)
++#define AAEC_GPIO_PFDR		__REG(AAEC_GPIO_PHYS + 0x30)
++#define AAEC_GPIO_PFDDR		__REG(AAEC_GPIO_PHYS + 0x34)
++#define AAEC_GPIO_PGDR		__REG(AAEC_GPIO_PHYS + 0x38)
++#define AAEC_GPIO_PGDDR		__REG(AAEC_GPIO_PHYS + 0x3c)
++#define AAEC_GPIO_PHDR		__REG(AAEC_GPIO_PHYS + 0x40)
++#define AAEC_GPIO_PHDDR		__REG(AAEC_GPIO_PHYS + 0x44)
++#define AAEC_GPIO_RAZ		__REG(AAEC_GPIO_PHYS + 0x48)
++#define AAEC_GPIO_INTTYPE1	__REG(AAEC_GPIO_PHYS + 0x4c)
++#define AAEC_GPIO_INTTYPE2	__REG(AAEC_GPIO_PHYS + 0x50)
++#define AAEC_GPIO_FEOI		__REG(AAEC_GPIO_PHYS + 0x54)
++#define AAEC_GPIO_INTEN		__REG(AAEC_GPIO_PHYS + 0x58)
++#define AAEC_GPIO_INTSTATUS	__REG(AAEC_GPIO_PHYS + 0x5c)
++#define AAEC_GPIO_RAWINTSTATUS	__REG(AAEC_GPIO_PHYS + 0x60)
++#define AAEC_GPIO_DB		__REG(AAEC_GPIO_PHYS + 0x64)
++#define AAEC_GPIO_PAPINDR	__REG(AAEC_GPIO_PHYS + 0x68)
++#define AAEC_GPIO_PBPINDR	__REG(AAEC_GPIO_PHYS + 0x6c)
++#define AAEC_GPIO_PCPINDR	__REG(AAEC_GPIO_PHYS + 0x70)
++#define AAEC_GPIO_PDPINDR	__REG(AAEC_GPIO_PHYS + 0x74)
++#define AAEC_GPIO_PEPINDR	__REG(AAEC_GPIO_PHYS + 0x78)
++#define AAEC_GPIO_PFPINDR	__REG(AAEC_GPIO_PHYS + 0x7c)
++#define AAEC_GPIO_PGPINDR	__REG(AAEC_GPIO_PHYS + 0x80)
++#define AAEC_GPIO_PHPINDR	__REG(AAEC_GPIO_PHYS + 0x84)
++
++#define AAEC_GPIO_PINMUX_PE0CON		(1 << 0)
++#define AAEC_GPIO_PINMUX_PD0CON		(1 << 1)
++#define AAEC_GPIO_PINMUX_CODECON	(1 << 2)
++#define AAEC_GPIO_PINMUX_UART3CON	(1 << 3)
++
++/* LCD Controller */
++#define AAEC_CLCD_PHYS	0x80003000
++
+ #endif /* __ARM_ARCH_AAEC2000_H */
+diff --git a/include/asm-arm/arch-aaec2000/aaed2000.h b/include/asm-arm/arch-aaec2000/aaed2000.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-aaec2000/aaed2000.h
+@@ -0,0 +1,40 @@
++/*
++ *  linux/include/asm-arm/arch-aaec2000/aaed2000.h
++ *
++ *  AAED-2000 specific bits definition
++ *
++ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
++ *
++ *  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_AAED2000_H
++#define __ASM_ARCH_AAED2000_H
++
++/* External GPIOs. */
++
++#define EXT_GPIO_PBASE	AAEC_CS3
++#define EXT_GPIO_VBASE	0xf8100000
++#define EXT_GPIO_LENGTH	0x00001000
++
++#define __ext_gpio_p2v(x)	((x) - EXT_GPIO_PBASE + EXT_GPIO_VBASE)
++#define __ext_gpio_v2p(x)	((x) + EXT_GPIO_PBASE - EXT_GPIO_VBASE)
++
++#define __EXT_GPIO_REG(x)	(*((volatile u32 *)__ext_gpio_p2v(x)))
++#define __EXT_GPIO_PREG(x)	(__ext_gpio_v2p((u32)&(x)))
++
++#define AAED_EXT_GPIO	__EXT_GPIO_REG(EXT_GPIO_PBASE)
++
++#define AAED_EGPIO_KBD_SCAN	0x00003fff /* Keyboard scan data */
++#define AAED_EGPIO_PWR_INT	0x00008fff /* Smart battery charger interrupt */
++#define AAED_EGPIO_SWITCHED	0x000f0000 /* DIP Switches */
++#define AAED_EGPIO_USB_VBUS	0x00400000 /* USB Vbus sense */
++#define AAED_EGPIO_LCD_PWR_EN	0x02000000 /* LCD and backlight PWR enable */
++#define AAED_EGPIO_nLED0	0x20000000 /* LED 0 */
++#define AAED_EGPIO_nLED1	0x20000000 /* LED 1 */
++#define AAED_EGPIO_nLED2	0x20000000 /* LED 2 */
++
++
++#endif /* __ARM_ARCH_AAED2000_H */
+diff --git a/include/asm-arm/arch-aaec2000/hardware.h b/include/asm-arm/arch-aaec2000/hardware.h
+--- a/include/asm-arm/arch-aaec2000/hardware.h
++++ b/include/asm-arm/arch-aaec2000/hardware.h
+@@ -11,7 +11,8 @@
+ #ifndef __ASM_ARCH_HARDWARE_H
+ #define __ASM_ARCH_HARDWARE_H
+ 
+-#include <linux/config.h>
++#include <asm/sizes.h>
++#include <asm/arch/aaec2000.h>
+ 
+ /* The kernel is loaded at physical address 0xf8000000.
+  * We map the IO space a bit after
+diff --git a/include/asm-arm/arch-aaec2000/io.h b/include/asm-arm/arch-aaec2000/io.h
+--- a/include/asm-arm/arch-aaec2000/io.h
++++ b/include/asm-arm/arch-aaec2000/io.h
+@@ -6,6 +6,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ /*
+diff --git a/include/asm-arm/arch-aaec2000/memory.h b/include/asm-arm/arch-aaec2000/memory.h
+--- a/include/asm-arm/arch-aaec2000/memory.h
++++ b/include/asm-arm/arch-aaec2000/memory.h
+@@ -13,7 +13,7 @@
+ 
+ #include <linux/config.h>
+ 
+-#define PHYS_OFFSET	(0xf0000000UL)
++#define PHYS_OFFSET	UL(0xf0000000)
+ 
+ #define __virt_to_bus(x)	__virt_to_phys(x)
+ #define __bus_to_virt(x)	__phys_to_virt(x)
+diff --git a/include/asm-arm/arch-cl7500/io.h b/include/asm-arm/arch-cl7500/io.h
+--- a/include/asm-arm/arch-cl7500/io.h
++++ b/include/asm-arm/arch-cl7500/io.h
+@@ -10,6 +10,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ /*
+diff --git a/include/asm-arm/arch-cl7500/memory.h b/include/asm-arm/arch-cl7500/memory.h
+--- a/include/asm-arm/arch-cl7500/memory.h
++++ b/include/asm-arm/arch-cl7500/memory.h
+@@ -17,7 +17,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0x10000000UL)
++#define PHYS_OFFSET	UL(0x10000000)
+ 
+ /*
+  * These are exactly the same on the RiscPC as the
+diff --git a/include/asm-arm/arch-clps711x/hardware.h b/include/asm-arm/arch-clps711x/hardware.h
+--- a/include/asm-arm/arch-clps711x/hardware.h
++++ b/include/asm-arm/arch-clps711x/hardware.h
+@@ -235,4 +235,121 @@
+ #define CEIVA_PB0_BLK_BTN	(1<<0)
+ #endif // #if defined (CONFIG_ARCH_CEIVA)
+ 
++#if defined (CONFIG_MACH_MP1000)
++/* NOR FLASH */
++#define MP1000_NIO_BASE		0xf9000000	/* virtual */
++#define MP1000_NIO_START	CS0_PHYS_BASE	/* physical */
++#define MP1000_NIO_SIZE		0x00400000
++
++/* DSP Interface */
++#define MP1000_DSP_BASE		0xfa000000	/* virtual */
++#define MP1000_DSP_START	CS1_PHYS_BASE	/* physical */
++#define MP1000_DSP_SIZE		0x00100000
++
++/* LCD, DAA/DSP, RTC, DAA RW Reg all in CS2 */
++#define MP1000_LIO_BASE		0xfb000000	/* virtual */
++#define MP1000_LIO_START	CS2_PHYS_BASE	/* physical */
++#define MP1000_LIO_SIZE		0x00100000
++
++/* NAND FLASH */
++#define MP1000_FIO_BASE		0xfc000000	/* virtual */
++#define MP1000_FIO_START	CS3_PHYS_BASE	/* physical */
++#define MP1000_FIO_SIZE		0x00800000
++
++/* Ethernet */
++#define MP1000_EIO_BASE		0xfd000000	/* virtual 	*/
++#define MP1000_EIO_START	CS4_PHYS_BASE	/* physical 	*/
++#define MP1000_EIO_SIZE		0x00100000
++
++#define	MP1000_LCD_OFFSET	0x00000000	/* LCD offset in CS2 */
++#define	MP1000_DDD_OFFSET	0x00001000	/* DAA/DAI/DSP sft reset offst*/
++#define	MP1000_RTC_OFFSET	0x00002000	/* RTC offset in CS2 */
++#define	MP1000_DAA_OFFSET	0x00003000	/* DAA RW reg offset in CS2 */
++
++/* IDE */
++#define MP1000_IDE_BASE		0xfe000000      /* virtual */
++#define MP1000_IDE_START	CS5_PHYS_BASE      /* physical */
++#define MP1000_IDE_SIZE		0x00100000      /* actually it's only 0x1000 */
++
++#define IRQ_HARDDISK IRQ_EINT2
++
++/*
++ * IDE registers definition
++ */
++
++#define IDE_CONTROL_BASE		(MP1000_IDE_BASE + 0x1000)
++#define IDE_BASE_OFF			(MP1000_IDE_BASE)
++
++#define IDE_WRITE_DEVICE_DATA		(IDE_BASE_OFF + 0x0)
++#define IDE_FEATURES_REGISTER		(IDE_BASE_OFF + 0x2)
++#define IDE_SECTOR_COUNT_REGISTER	(IDE_BASE_OFF + 0x4)
++#define IDE_SECTOR_NUMBER_REGISTER	(IDE_BASE_OFF + 0x6)
++#define IDE_CYLINDER_LOW_REGISTER	(IDE_BASE_OFF + 0x8)
++#define IDE_CYLINDER_HIGH_REGISTER	(IDE_BASE_OFF + 0xa)
++#define IDE_DEVICE_HEAD_REGISTER	(IDE_BASE_OFF + 0xc)
++#define IDE_COMMAND_DATA_REGISTER	(IDE_BASE_OFF + 0xe)
++#define IDE_DEVICE_CONTROL_REGISTER	(IDE_CONTROL_BASE + 0xc)
++
++#define IDE_IRQ                      IRQ_EINT2
++
++
++#define RTC_PORT(x)	(MP1000_LIO_BASE+0x2000 + (x*2))
++#define RTC_ALWAYS_BCD	0
++
++/*
++// Definitions of the bit fields in the HwPortA register for the
++// MP1000 board.
++*/
++#define HwPortAKeyboardRow1                     0x00000001
++#define HwPortAKeyboardRow2                     0x00000002
++#define HwPortAKeyboardRow3                     0x00000004
++#define HwPortAKeyboardRow4                     0x00000008
++#define HwPortAKeyboardRow5                     0x00000010
++#define HwPortAKeyboardRow6                     0x00000020
++#define HwPortALCDEnable                        0x00000040
++#define HwPortAOffhook	                        0x00000080
++
++/*
++// Definitions of the bit fields in the HwPortB register for the
++// MP1000 board.
++*/
++#define HwPortBL3Mode                           0x00000001
++#define HwPortBL3Clk                            0x00000002
++#define HwPortBSClk                             0x00000001
++#define HwPortBSData                            0x00000002
++#define HwPortBL3Data                           0x00000004
++#define HwPortBMute                             0x00000008
++#define HwPortBQD0                              0x00000010
++#define HwPortBQD1                              0x00000020
++#define HwPortBQD2                              0x00000040
++#define HwPortBQD3                              0x00000080
++
++/*
++// Definitions of the bit fields in the HwPortD register for the
++// MP1000 board.
++*/
++#define HwPortDLED1                             0x00000001
++#define HwPortDLED2                             0x00000002
++#define HwPortDLED3                             0x00000004
++#define HwPortDLED4                             0x00000008
++#define HwPortDLED5                             0x00000010
++#define HwPortDEECS                             0x00000020
++#define HwPortBRTS                              0x00000040
++#define HwPortBRI                               0x00000080
++
++
++/*
++// Definitions of the bit fields in the HwPortE register for the
++// MP1000 board.
++*/
++
++#define HwPortECLE                              0x00000001
++#define HwPortESepromDOut                       0x00000001
++#define HwPortEALE                              0x00000002
++#define HwPortESepromDIn                        0x00000002
++#define HwPortENANDCS                           0x00000004
++#define HwPortESepromCLK                        0x00000004
++
++#endif // #if defined (CONFIG_MACH_MP1000)
++
+ #endif
+diff --git a/include/asm-arm/arch-clps711x/io.h b/include/asm-arm/arch-clps711x/io.h
+--- a/include/asm-arm/arch-clps711x/io.h
++++ b/include/asm-arm/arch-clps711x/io.h
+@@ -20,6 +20,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ #define __io(a)			((void __iomem *)(a))
+diff --git a/include/asm-arm/arch-clps711x/memory.h b/include/asm-arm/arch-clps711x/memory.h
+--- a/include/asm-arm/arch-clps711x/memory.h
++++ b/include/asm-arm/arch-clps711x/memory.h
+@@ -25,7 +25,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0xc0000000UL)
++#define PHYS_OFFSET	UL(0xc0000000)
+ 
+ /*
+  * Virtual view <-> DMA view memory address translations
+diff --git a/include/asm-arm/arch-clps711x/mp1000-seprom.h b/include/asm-arm/arch-clps711x/mp1000-seprom.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-clps711x/mp1000-seprom.h
+@@ -0,0 +1,77 @@
++#ifndef MP1000_SEPROM_H
++#define MP1000_SEPROM_H
++
++/*
++ * mp1000-seprom.h
++ *
++ *
++ *  This file contains the Serial EEPROM definitions for the MP1000 board
++ *
++ *  Copyright (C) 2005 Comdial 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
++ *
++ */
++
++#define COMMAND_ERASE		(0x1C0)
++#define COMMAND_ERASE_ALL	(0x120)
++#define COMMAND_WRITE_DISABLE	(0x100)
++#define COMMAND_WRITE_ENABLE	(0x130)
++#define COMMAND_READ		(0x180)
++#define COMMAND_WRITE		(0x140)
++#define COMMAND_WRITE_ALL	(0x110)
++
++//
++// Serial EEPROM data format
++//
++
++#define PACKED __attribute__ ((packed))
++
++typedef struct _EEPROM {
++	union {
++		unsigned char eprom_byte_data[128];
++		unsigned short eprom_short_data[64];
++		struct {
++			unsigned char version PACKED;	// EEPROM Version "1" for now
++			unsigned char box_id PACKED; 	// Box ID (Standalone, SOHO, embedded, etc)
++			unsigned char major_hw_version PACKED;	// Major Hardware version (Hex)
++			unsigned char minor_hw_version PACKED;	// Minor Hardware Version (Hex)
++			unsigned char mfg_id[3] PACKED;	// Manufacturer ID (3 character Alphabetic)
++			unsigned char mfg_serial_number[10] PACKED;	// Manufacturer Serial number
++			unsigned char mfg_date[3] PACKED;	// Date of Mfg (Formatted YY:MM:DD)
++			unsigned char country PACKED;	// Country of deployment
++			unsigned char mac_Address[6] PACKED;	// MAC Address
++			unsigned char oem_string[20] PACKED;	// OEM ID string
++			unsigned short feature_bits1 PACKED;	// Feature Bits 1
++			unsigned short feature_bits2 PACKED;	// Feature Bits 2
++			unsigned char filler[75] PACKED;		// Unused/Undefined	“0” initialized
++			unsigned short checksum PACKED;		// byte accumulated short checksum
++		} eprom_struct;
++	} variant;
++}  eeprom_struct;
++
++/* These settings must be mutually exclusive */
++#define	FEATURE_BITS1_DRAMSIZE_16MEG	0x0001  /* 0 signifies 4 MEG system */
++#define	FEATURE_BITS1_DRAMSIZE_8MEG	0x0002  /* 1 in bit 1 = 8MEG system */
++#define	FEATURE_BITS1_DRAMSIZE_64MEG	0x0004  /* 1 in bit 2 = 64MEG system */
++
++#define FEATURE_BITS1_CPUIS90MEG     0x0010
++
++extern void seprom_init(void);
++extern eeprom_struct* get_seprom_ptr(void);
++extern unsigned char* get_eeprom_mac_address(void);
++
++#endif /* MP1000_SEPROM_H */
++
+diff --git a/include/asm-arm/arch-ebsa110/memory.h b/include/asm-arm/arch-ebsa110/memory.h
+--- a/include/asm-arm/arch-ebsa110/memory.h
++++ b/include/asm-arm/arch-ebsa110/memory.h
+@@ -19,7 +19,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0x00000000UL)
++#define PHYS_OFFSET	UL(0x00000000)
+ 
+ /*
+  * We keep this 1:1 so that we don't interfere
+diff --git a/include/asm-arm/arch-ebsa285/io.h b/include/asm-arm/arch-ebsa285/io.h
+--- a/include/asm-arm/arch-ebsa285/io.h
++++ b/include/asm-arm/arch-ebsa285/io.h
+@@ -14,6 +14,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffff
+ 
+ /*
+diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h
+--- a/include/asm-arm/arch-ebsa285/memory.h
++++ b/include/asm-arm/arch-ebsa285/memory.h
+@@ -46,14 +46,14 @@ extern unsigned long __bus_to_virt(unsig
+ #if defined(CONFIG_ARCH_FOOTBRIDGE)
+ 
+ /* Task size and page offset at 3GB */
+-#define TASK_SIZE		(0xbf000000UL)
+-#define PAGE_OFFSET		(0xc0000000UL)
++#define TASK_SIZE		UL(0xbf000000)
++#define PAGE_OFFSET		UL(0xc0000000)
+ 
+ #elif defined(CONFIG_ARCH_CO285)
+ 
+ /* Task size and page offset at 1.5GB */
+-#define TASK_SIZE		(0x5f000000UL)
+-#define PAGE_OFFSET		(0x60000000UL)
++#define TASK_SIZE		UL(0x5f000000)
++#define PAGE_OFFSET		UL(0x60000000)
+ 
+ #else
+ 
+@@ -64,7 +64,7 @@ extern unsigned long __bus_to_virt(unsig
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET		(0x00000000UL)
++#define PHYS_OFFSET		UL(0x00000000)
+ 
+ /*
+  * This decides where the kernel will search for a free chunk of vm
+diff --git a/include/asm-arm/arch-epxa10db/io.h b/include/asm-arm/arch-epxa10db/io.h
+--- a/include/asm-arm/arch-epxa10db/io.h
++++ b/include/asm-arm/arch-epxa10db/io.h
+@@ -20,6 +20,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffff
+ 
+ 
+diff --git a/include/asm-arm/arch-epxa10db/memory.h b/include/asm-arm/arch-epxa10db/memory.h
+--- a/include/asm-arm/arch-epxa10db/memory.h
++++ b/include/asm-arm/arch-epxa10db/memory.h
+@@ -23,7 +23,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0x00000000UL)
++#define PHYS_OFFSET	UL(0x00000000)
+ 
+ /*
+  * Virtual view <-> DMA view memory address translations
+diff --git a/include/asm-arm/arch-h720x/io.h b/include/asm-arm/arch-h720x/io.h
+--- a/include/asm-arm/arch-h720x/io.h
++++ b/include/asm-arm/arch-h720x/io.h
+@@ -14,7 +14,7 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
+-#include <asm/arch/hardware.h>
++#include <asm/hardware.h>
+ 
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+diff --git a/include/asm-arm/arch-h720x/memory.h b/include/asm-arm/arch-h720x/memory.h
+--- a/include/asm-arm/arch-h720x/memory.h
++++ b/include/asm-arm/arch-h720x/memory.h
+@@ -11,7 +11,7 @@
+  * Page offset:
+  *    ( 0xc0000000UL )
+  */
+-#define PHYS_OFFSET	(0x40000000UL)
++#define PHYS_OFFSET	UL(0x40000000)
+ 
+ /*
+  * Virtual view <-> DMA view memory address translations
+diff --git a/include/asm-arm/arch-imx/io.h b/include/asm-arm/arch-imx/io.h
+--- a/include/asm-arm/arch-imx/io.h
++++ b/include/asm-arm/arch-imx/io.h
+@@ -20,6 +20,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ #define __io(a)		((void __iomem *)(a))
+diff --git a/include/asm-arm/arch-imx/memory.h b/include/asm-arm/arch-imx/memory.h
+--- a/include/asm-arm/arch-imx/memory.h
++++ b/include/asm-arm/arch-imx/memory.h
+@@ -21,7 +21,7 @@
+ #ifndef __ASM_ARCH_MMU_H
+ #define __ASM_ARCH_MMU_H
+ 
+-#define PHYS_OFFSET	(0x08000000UL)
++#define PHYS_OFFSET	UL(0x08000000)
+ 
+ /*
+  * Virtual view <-> DMA view memory address translations
+diff --git a/include/asm-arm/arch-integrator/hardware.h b/include/asm-arm/arch-integrator/hardware.h
+--- a/include/asm-arm/arch-integrator/hardware.h
++++ b/include/asm-arm/arch-integrator/hardware.h
+@@ -33,15 +33,6 @@
+ #define IO_SIZE			0x0B000000                 // How much?
+ #define IO_START		INTEGRATOR_HDR_BASE        // PA of IO
+ 
+-/*
+- * Similar to above, but for PCI addresses (memory, IO, Config and the
+- * V3 chip itself).  WARNING: this has to mirror definitions in platform.h
+- */
+-#define PCI_MEMORY_VADDR        0xe8000000
+-#define PCI_CONFIG_VADDR        0xec000000
+-#define PCI_V3_VADDR            0xed000000
+-#define PCI_IO_VADDR            0xee000000
+-
+ #define PCIO_BASE		PCI_IO_VADDR
+ #define PCIMEM_BASE		PCI_MEMORY_VADDR
+ 
+diff --git a/include/asm-arm/arch-integrator/io.h b/include/asm-arm/arch-integrator/io.h
+--- a/include/asm-arm/arch-integrator/io.h
++++ b/include/asm-arm/arch-integrator/io.h
+@@ -22,6 +22,14 @@
+ 
+ #define IO_SPACE_LIMIT 0xffff
+ 
++/*
++ * WARNING: this has to mirror definitions in platform.h
++ */
++#define PCI_MEMORY_VADDR        0xe8000000
++#define PCI_CONFIG_VADDR        0xec000000
++#define PCI_V3_VADDR            0xed000000
++#define PCI_IO_VADDR            0xee000000
++
+ #define __io(a)			((void __iomem *)(PCI_IO_VADDR + (a)))
+ #define __mem_pci(a)		(a)
+ #define __mem_isa(a)		((a) + PCI_MEMORY_VADDR)
+diff --git a/include/asm-arm/arch-integrator/memory.h b/include/asm-arm/arch-integrator/memory.h
+--- a/include/asm-arm/arch-integrator/memory.h
++++ b/include/asm-arm/arch-integrator/memory.h
+@@ -23,8 +23,8 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0x00000000UL)
+-#define BUS_OFFSET	(0x80000000UL)
++#define PHYS_OFFSET	UL(0x00000000)
++#define BUS_OFFSET	UL(0x80000000)
+ 
+ /*
+  * Virtual view <-> DMA view memory address translations
+diff --git a/include/asm-arm/arch-iop3xx/io.h b/include/asm-arm/arch-iop3xx/io.h
+--- a/include/asm-arm/arch-iop3xx/io.h
++++ b/include/asm-arm/arch-iop3xx/io.h
+@@ -11,6 +11,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ #define __io(p)			((void __iomem *)(p))
+diff --git a/include/asm-arm/arch-iop3xx/memory.h b/include/asm-arm/arch-iop3xx/memory.h
+--- a/include/asm-arm/arch-iop3xx/memory.h
++++ b/include/asm-arm/arch-iop3xx/memory.h
+@@ -12,9 +12,9 @@
+  * Physical DRAM offset.
+  */
+ #ifndef CONFIG_ARCH_IOP331
+-#define PHYS_OFFSET	(0xa0000000UL)
++#define PHYS_OFFSET	UL(0xa0000000)
+ #else
+-#define PHYS_OFFSET	(0x00000000UL)
++#define PHYS_OFFSET	UL(0x00000000)
+ #endif
+ 
+ /*
+diff --git a/include/asm-arm/arch-ixp2000/enp2611.h b/include/asm-arm/arch-ixp2000/enp2611.h
+--- a/include/asm-arm/arch-ixp2000/enp2611.h
++++ b/include/asm-arm/arch-ixp2000/enp2611.h
+@@ -21,8 +21,20 @@
+ #ifndef __ENP2611_H
+ #define __ENP2611_H
+ 
+-#define ENP2611_GPIO_SCL	0x07
+-#define ENP2611_GPIO_SDA	0x06
++#define ENP2611_CALEB_PHYS_BASE		0xc5000000
++#define ENP2611_CALEB_VIRT_BASE		0xfe000000
++#define ENP2611_CALEB_SIZE		0x00100000
++
++#define ENP2611_PM3386_0_PHYS_BASE	0xc6000000
++#define ENP2611_PM3386_0_VIRT_BASE	0xfe100000
++#define ENP2611_PM3386_0_SIZE		0x00100000
++
++#define ENP2611_PM3386_1_PHYS_BASE	0xc6400000
++#define ENP2611_PM3386_1_VIRT_BASE	0xfe200000
++#define ENP2611_PM3386_1_SIZE		0x00100000
++
++#define ENP2611_GPIO_SCL		7
++#define ENP2611_GPIO_SDA		6
+ 
+ 
+ #endif
+diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
+--- a/include/asm-arm/arch-ixp2000/io.h
++++ b/include/asm-arm/arch-ixp2000/io.h
+@@ -15,6 +15,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT		0xffffffff
+ #define __mem_pci(a)		(a)
+ 
+diff --git a/include/asm-arm/arch-ixp2000/ixdp2x01.h b/include/asm-arm/arch-ixp2000/ixdp2x01.h
+--- a/include/asm-arm/arch-ixp2000/ixdp2x01.h
++++ b/include/asm-arm/arch-ixp2000/ixdp2x01.h
+@@ -22,7 +22,7 @@
+ #define	IXDP2X01_CPLD_REGION_SIZE	0x00100000
+ 
+ #define IXDP2X01_CPLD_VIRT_REG(reg) (volatile unsigned long*)(IXDP2X01_VIRT_CPLD_BASE | reg)
+-#define IXDP2X01_CPLD_PHYS_REG(reg) (volatile u32*)(IXDP2X01_PHYS_CPLD_BASE | reg)
++#define IXDP2X01_CPLD_PHYS_REG(reg) (IXDP2X01_PHYS_CPLD_BASE | reg)
+ 
+ #define IXDP2X01_UART1_VIRT_BASE	IXDP2X01_CPLD_VIRT_REG(0x40)
+ #define IXDP2X01_UART1_PHYS_BASE	IXDP2X01_CPLD_PHYS_REG(0x40)
+diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+--- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h
++++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+@@ -59,14 +59,15 @@
+ #define	IXP2000_CAP_SIZE		0x00100000
+ 
+ /*
+- * Addresses for specific on-chip peripherals
++ * Addresses for specific on-chip peripherals.
+  */
+ #define	IXP2000_SLOWPORT_CSR_VIRT_BASE	0xfef80000
+ #define	IXP2000_GLOBAL_REG_VIRT_BASE	0xfef04000
+ #define	IXP2000_UART_PHYS_BASE		0xc0030000
+ #define	IXP2000_UART_VIRT_BASE		0xfef30000
+ #define	IXP2000_TIMER_VIRT_BASE		0xfef20000
+-#define	IXP2000_GPIO_VIRT_BASE		0Xfef10000
++#define	IXP2000_UENGINE_CSR_VIRT_BASE	0xfef18000
++#define	IXP2000_GPIO_VIRT_BASE		0xfef10000
+ 
+ /*
+  * Devices outside of the 0xc0000000 -> 0xc0100000 range.  The virtual
+@@ -252,7 +253,7 @@
+ #define IXP2000_PCI_XSCALE_INT_ENABLE	IXP2000_PCI_CSR(0x15C)
+ 
+ #define IXP2000_PCICNTL_PNR		(1<<17)	/* PCI not Reset bit of PCI_CONTROL */
+-#define IXP2000_PCICNTL_PCF		(1<<28)	/* PCI Centrolfunction bit */
++#define IXP2000_PCICNTL_PCF		(1<<28)	/* PCI Central function bit */
+ #define IXP2000_XSCALE_INT		(1<<1)	/* Interrupt from XScale to PCI */
+ 
+ /* These are from the IRQ register in the PCI ISR register */
+@@ -392,4 +393,47 @@
+ #define	WDT_RESET_ENABLE		0x01000000
+ 
+ 
++/*
++ * MSF registers.  The IXP2400 and IXP2800 have somewhat different MSF
++ * units, but the registers that differ between the two don't overlap,
++ * so we can have one register list for both.
++ */
++#define IXP2000_MSF_REG(x)			((volatile unsigned long*)(IXP2000_MSF_VIRT_BASE + (x)))
++#define IXP2000_MSF_RX_CONTROL			IXP2000_MSF_REG(0x0000)
++#define IXP2000_MSF_TX_CONTROL			IXP2000_MSF_REG(0x0004)
++#define IXP2000_MSF_INTERRUPT_STATUS		IXP2000_MSF_REG(0x0008)
++#define IXP2000_MSF_INTERRUPT_ENABLE		IXP2000_MSF_REG(0x000c)
++#define IXP2000_MSF_CSIX_TYPE_MAP		IXP2000_MSF_REG(0x0010)
++#define IXP2000_MSF_FC_EGRESS_STATUS		IXP2000_MSF_REG(0x0014)
++#define IXP2000_MSF_FC_INGRESS_STATUS		IXP2000_MSF_REG(0x0018)
++#define IXP2000_MSF_HWM_CONTROL			IXP2000_MSF_REG(0x0024)
++#define IXP2000_MSF_FC_STATUS_OVERRIDE		IXP2000_MSF_REG(0x0028)
++#define IXP2000_MSF_CLOCK_CONTROL		IXP2000_MSF_REG(0x002c)
++#define IXP2000_MSF_RX_PORT_MAP			IXP2000_MSF_REG(0x0040)
++#define IXP2000_MSF_RBUF_ELEMENT_DONE		IXP2000_MSF_REG(0x0044)
++#define IXP2000_MSF_RX_MPHY_POLL_LIMIT		IXP2000_MSF_REG(0x0048)
++#define IXP2000_MSF_RX_CALENDAR_LENGTH		IXP2000_MSF_REG(0x0048)
++#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_0	IXP2000_MSF_REG(0x0050)
++#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_1	IXP2000_MSF_REG(0x0054)
++#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_2	IXP2000_MSF_REG(0x0058)
++#define IXP2000_MSF_TX_SEQUENCE_0		IXP2000_MSF_REG(0x0060)
++#define IXP2000_MSF_TX_SEQUENCE_1		IXP2000_MSF_REG(0x0064)
++#define IXP2000_MSF_TX_SEQUENCE_2		IXP2000_MSF_REG(0x0068)
++#define IXP2000_MSF_TX_MPHY_POLL_LIMIT		IXP2000_MSF_REG(0x0070)
++#define IXP2000_MSF_TX_CALENDAR_LENGTH		IXP2000_MSF_REG(0x0070)
++#define IXP2000_MSF_RX_UP_CONTROL_0		IXP2000_MSF_REG(0x0080)
++#define IXP2000_MSF_RX_UP_CONTROL_1		IXP2000_MSF_REG(0x0084)
++#define IXP2000_MSF_RX_UP_CONTROL_2		IXP2000_MSF_REG(0x0088)
++#define IXP2000_MSF_RX_UP_CONTROL_3		IXP2000_MSF_REG(0x008c)
++#define IXP2000_MSF_TX_UP_CONTROL_0		IXP2000_MSF_REG(0x0090)
++#define IXP2000_MSF_TX_UP_CONTROL_1		IXP2000_MSF_REG(0x0094)
++#define IXP2000_MSF_TX_UP_CONTROL_2		IXP2000_MSF_REG(0x0098)
++#define IXP2000_MSF_TX_UP_CONTROL_3		IXP2000_MSF_REG(0x009c)
++#define IXP2000_MSF_TRAIN_DATA			IXP2000_MSF_REG(0x00a0)
++#define IXP2000_MSF_TRAIN_CALENDAR		IXP2000_MSF_REG(0x00a4)
++#define IXP2000_MSF_TRAIN_FLOW_CONTROL		IXP2000_MSF_REG(0x00a8)
++#define IXP2000_MSF_TX_CALENDAR_0		IXP2000_MSF_REG(0x1000)
++#define IXP2000_MSF_RX_PORT_CALENDAR_STATUS	IXP2000_MSF_REG(0x1400)
++
++
+ #endif				/* _IXP2000_H_ */
+diff --git a/include/asm-arm/arch-ixp2000/memory.h b/include/asm-arm/arch-ixp2000/memory.h
+--- a/include/asm-arm/arch-ixp2000/memory.h
++++ b/include/asm-arm/arch-ixp2000/memory.h
+@@ -13,7 +13,7 @@
+ #ifndef __ASM_ARCH_MEMORY_H
+ #define __ASM_ARCH_MEMORY_H
+ 
+-#define PHYS_OFFSET	(0x00000000UL)
++#define PHYS_OFFSET	UL(0x00000000)
+ 
+ /*
+  * Virtual view <-> DMA view memory address translations
+diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h
+--- a/include/asm-arm/arch-ixp2000/platform.h
++++ b/include/asm-arm/arch-ixp2000/platform.h
+@@ -15,40 +15,40 @@
+ 
+ #ifndef __ASSEMBLY__
+ 
++static inline unsigned long ixp2000_reg_read(volatile void *reg)
++{
++	return *((volatile unsigned long *)reg);
++}
++
++static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
++{
++	*((volatile unsigned long *)reg) = val;
++}
++
+ /*
+- * The IXP2400 B0 silicon contains an erratum (#66) that causes writes
+- * to on-chip I/O register to not complete fully. What this means is
+- * that if you have a write to on-chip I/O followed by a back-to-back
+- * read or write, the first write will happen twice. OR...if it's
+- * not a back-to-back transaction, the read or write will generate
+- * incorrect data.
+- *
+- * The official work around for this is to set the on-chip I/O regions
+- * as XCB=101 and then force a read-back from the register.
++ * On the IXP2400, we can't use XCB=000 due to chip bugs.  We use
++ * XCB=101 instead, but that makes all I/O accesses bufferable.  This
++ * is not a problem in general, but we do have to be slightly more
++ * careful because I/O writes are no longer automatically flushed out
++ * of the write buffer.
+  *
++ * In cases where we want to make sure that a write has been flushed
++ * out of the write buffer before we proceed, for example when masking
++ * a device interrupt before re-enabling IRQs in CPSR, we can use this
++ * function, ixp2000_reg_wrb, which performs a write, a readback, and
++ * issues a dummy instruction dependent on the value of the readback
++ * (mov rX, rX) to make sure that the readback has completed before we
++ * continue.
+  */
+-#if defined(CONFIG_ARCH_ENP2611) || defined(CONFIG_ARCH_IXDP2400) || defined(CONFIG_ARCH_IXDP2401)
+-
+-#include <asm/system.h>		/* Pickup local_irq_ functions */
+-
+-static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
++static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
+ {
+ 	unsigned long dummy;
+-	unsigned long flags;
+ 
+-	local_irq_save(flags);
+ 	*((volatile unsigned long *)reg) = val;
+-	barrier();
++
+ 	dummy = *((volatile unsigned long *)reg);
+-	local_irq_restore(flags);
+-}
+-#else
+-static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
+-{
+-	*((volatile unsigned long *)reg) = val;
++	__asm__ __volatile__("mov %0, %0" : "+r" (dummy));
+ }
+-#endif	/* IXDP2400 || IXDP2401 */
+-#define ixp2000_reg_read(reg)	(*((volatile unsigned long *)reg))
+ 
+ /*
+  * Boards may multiplex different devices on the 2nd channel of 
+diff --git a/include/asm-arm/arch-ixp2000/system.h b/include/asm-arm/arch-ixp2000/system.h
+--- a/include/asm-arm/arch-ixp2000/system.h
++++ b/include/asm-arm/arch-ixp2000/system.h
+@@ -26,29 +26,24 @@ static inline void arch_reset(char mode)
+ 	 * RedBoot bank.
+ 	 */
+ 	if (machine_is_ixdp2401()) {
+-		*IXDP2X01_CPLD_FLASH_REG = ((0 >> IXDP2X01_FLASH_WINDOW_BITS)
+-						| IXDP2X01_CPLD_FLASH_INTERN);
+-		*IXDP2X01_CPLD_RESET_REG = 0xffffffff;
++		ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG,
++					((0 >> IXDP2X01_FLASH_WINDOW_BITS)
++						| IXDP2X01_CPLD_FLASH_INTERN));
++		ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0xffffffff);
+ 	}
+ 
+ 	/*
+ 	 * On IXDP2801 we need to write this magic sequence to the CPLD
+ 	 * to cause a complete reset of the CPU and all external devices
+-	 * and moves the flash bank register back to 0.
++	 * and move the flash bank register back to 0.
+ 	 */
+ 	if (machine_is_ixdp2801()) {
+ 		unsigned long reset_reg = *IXDP2X01_CPLD_RESET_REG;
++
+ 		reset_reg = 0x55AA0000 | (reset_reg & 0x0000FFFF);
+-		*IXDP2X01_CPLD_RESET_REG = reset_reg;
+-		mb();
+-		*IXDP2X01_CPLD_RESET_REG = 0x80000000;
++		ixp2000_reg_write(IXDP2X01_CPLD_RESET_REG, reset_reg);
++		ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0x80000000);
+ 	}
+ 
+-	/*
+-	 * We do a reset all if we are PCI master. We could be a slave and we
+-	 * don't want to do anything funky on the PCI bus.
+-	 */
+-	if (*IXP2000_STRAP_OPTIONS & CFG_PCI_BOOT_HOST) {
+-		*(IXP2000_RESET0) |= (RSTALL);
+-	}
++	ixp2000_reg_wrb(IXP2000_RESET0, RSTALL);
+ }
+diff --git a/include/asm-arm/arch-ixp2000/uengine.h b/include/asm-arm/arch-ixp2000/uengine.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-ixp2000/uengine.h
+@@ -0,0 +1,62 @@
++/*
++ * Generic library functions for the microengines found on the Intel
++ * IXP2000 series of network processors.
++ *
++ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh at wantstofly.org>
++ * Dedicated to Marija Kulikova.
++ *
++ * This program 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.
++ */
++
++#ifndef __IXP2000_UENGINE_H
++#define __IXP2000_UENGINE_H
++
++extern u32 ixp2000_uengine_mask;
++
++struct ixp2000_uengine_code
++{
++	u32	cpu_model_bitmask;
++	u8	cpu_min_revision;
++	u8	cpu_max_revision;
++
++	u32	uengine_parameters;
++
++	struct ixp2000_reg_value {
++		int	reg;
++		u32	value;
++	} *initial_reg_values;
++
++	int	num_insns;
++	u8	*insns;
++};
++
++u32 ixp2000_uengine_csr_read(int uengine, int offset);
++void ixp2000_uengine_csr_write(int uengine, int offset, u32 value);
++void ixp2000_uengine_reset(u32 uengine_mask);
++void ixp2000_uengine_set_mode(int uengine, u32 mode);
++void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns);
++void ixp2000_uengine_init_context(int uengine, int context, int pc);
++void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask);
++void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask);
++int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c);
++
++#define IXP2000_UENGINE_8_CONTEXTS		0x00000000
++#define IXP2000_UENGINE_4_CONTEXTS		0x80000000
++#define IXP2000_UENGINE_PRN_UPDATE_EVERY	0x40000000
++#define IXP2000_UENGINE_PRN_UPDATE_ON_ACCESS	0x00000000
++#define IXP2000_UENGINE_NN_FROM_SELF		0x00100000
++#define IXP2000_UENGINE_NN_FROM_PREVIOUS	0x00000000
++#define IXP2000_UENGINE_ASSERT_EMPTY_AT_3	0x000c0000
++#define IXP2000_UENGINE_ASSERT_EMPTY_AT_2	0x00080000
++#define IXP2000_UENGINE_ASSERT_EMPTY_AT_1	0x00040000
++#define IXP2000_UENGINE_ASSERT_EMPTY_AT_0	0x00000000
++#define IXP2000_UENGINE_LM_ADDR1_GLOBAL		0x00020000
++#define IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT	0x00000000
++#define IXP2000_UENGINE_LM_ADDR0_GLOBAL		0x00010000
++#define IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT	0x00000000
++
++
++#endif
+diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
+--- a/include/asm-arm/arch-ixp4xx/io.h
++++ b/include/asm-arm/arch-ixp4xx/io.h
+@@ -113,7 +113,7 @@ __ixp4xx_writeb(u8 value, u32 addr)
+ }
+ 
+ static inline void
+-__ixp4xx_writesb(u32 bus_addr, u8 *vaddr, int count)
++__ixp4xx_writesb(u32 bus_addr, const u8 *vaddr, int count)
+ {
+ 	while (count--)
+ 		writeb(*vaddr++, bus_addr);
+@@ -136,7 +136,7 @@ __ixp4xx_writew(u16 value, u32 addr)
+ }
+ 
+ static inline void
+-__ixp4xx_writesw(u32 bus_addr, u16 *vaddr, int count)
++__ixp4xx_writesw(u32 bus_addr, const u16 *vaddr, int count)
+ {
+ 	while (count--)
+ 		writew(*vaddr++, bus_addr);
+@@ -154,7 +154,7 @@ __ixp4xx_writel(u32 value, u32 addr)
+ }
+ 
+ static inline void
+-__ixp4xx_writesl(u32 bus_addr, u32 *vaddr, int count)
++__ixp4xx_writesl(u32 bus_addr, const u32 *vaddr, int count)
+ {
+ 	while (count--)
+ 		writel(*vaddr++, bus_addr);
+diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
+--- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
++++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
+@@ -36,11 +36,11 @@
+  *
+  * 0x6000000	0x00004000	ioremap'd	QMgr
+  *
+- * 0xC0000000	0x00001000	0xffbfe000	PCI CFG 
++ * 0xC0000000	0x00001000	0xffbff000	PCI CFG
+  *
+- * 0xC4000000	0x00001000	0xffbfd000	EXP CFG 
++ * 0xC4000000	0x00001000	0xffbfe000	EXP CFG
+  *
+- * 0xC8000000	0x0000C000	0xffbf2000	On-Chip Peripherals
++ * 0xC8000000	0x00013000	0xffbeb000	On-Chip Peripherals
+  */
+ 
+ /*
+@@ -52,22 +52,22 @@
+  * Expansion BUS Configuration registers
+  */
+ #define IXP4XX_EXP_CFG_BASE_PHYS	(0xC4000000)
+-#define IXP4XX_EXP_CFG_BASE_VIRT	(0xFFBFD000)
++#define IXP4XX_EXP_CFG_BASE_VIRT	(0xFFBFE000)
+ #define IXP4XX_EXP_CFG_REGION_SIZE	(0x00001000)
+ 
+ /*
+  * PCI Config registers
+  */
+ #define IXP4XX_PCI_CFG_BASE_PHYS	(0xC0000000)
+-#define	IXP4XX_PCI_CFG_BASE_VIRT	(0xFFBFE000)
++#define	IXP4XX_PCI_CFG_BASE_VIRT	(0xFFBFF000)
+ #define IXP4XX_PCI_CFG_REGION_SIZE	(0x00001000)
+ 
+ /*
+  * Peripheral space
+  */
+ #define IXP4XX_PERIPHERAL_BASE_PHYS	(0xC8000000)
+-#define IXP4XX_PERIPHERAL_BASE_VIRT	(0xFFBF2000)
+-#define IXP4XX_PERIPHERAL_REGION_SIZE	(0x0000C000)
++#define IXP4XX_PERIPHERAL_BASE_VIRT	(0xFFBEB000)
++#define IXP4XX_PERIPHERAL_REGION_SIZE	(0x00013000)
+ 
+ /*
+  * Debug UART
+@@ -115,25 +115,48 @@
+ /*
+  * Peripheral Space Register Region Base Addresses
+  */
+-#define IXP4XX_UART1_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
+-#define IXP4XX_UART2_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
+-#define IXP4XX_PMU_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
+-#define IXP4XX_INTC_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
+-#define IXP4XX_GPIO_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
+-#define IXP4XX_TIMER_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
+-#define IXP4XX_EthA_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
+-#define IXP4XX_EthB_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
+-#define IXP4XX_USB_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
+-
+-#define IXP4XX_UART1_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
+-#define IXP4XX_UART2_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
+-#define IXP4XX_PMU_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
+-#define IXP4XX_INTC_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
+-#define IXP4XX_GPIO_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
+-#define IXP4XX_TIMER_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
+-#define IXP4XX_EthA_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
+-#define IXP4XX_EthB_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
+-#define IXP4XX_USB_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
++#define IXP4XX_UART1_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
++#define IXP4XX_UART2_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
++#define IXP4XX_PMU_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
++#define IXP4XX_INTC_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
++#define IXP4XX_GPIO_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
++#define IXP4XX_TIMER_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
++#define IXP4XX_NPEA_BASE_PHYS   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
++#define IXP4XX_NPEB_BASE_PHYS   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
++#define IXP4XX_NPEC_BASE_PHYS   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
++#define IXP4XX_EthB_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
++#define IXP4XX_EthC_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
++#define IXP4XX_USB_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
++/* ixp46X only */
++#define IXP4XX_EthA_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000)
++#define IXP4XX_EthB1_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000)
++#define IXP4XX_EthB2_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000)
++#define IXP4XX_EthB3_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000)
++#define IXP4XX_TIMESYNC_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000)
++#define IXP4XX_I2C_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000)
++#define IXP4XX_SSP_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
++
++
++#define IXP4XX_UART1_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
++#define IXP4XX_UART2_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
++#define IXP4XX_PMU_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
++#define IXP4XX_INTC_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
++#define IXP4XX_GPIO_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
++#define IXP4XX_TIMER_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
++#define IXP4XX_NPEA_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
++#define IXP4XX_NPEB_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
++#define IXP4XX_NPEC_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
++#define IXP4XX_EthB_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
++#define IXP4XX_EthC_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
++#define IXP4XX_USB_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
++/* ixp46X only */
++#define IXP4XX_EthA_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000)
++#define IXP4XX_EthB1_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000)
++#define IXP4XX_EthB2_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000)
++#define IXP4XX_EthB3_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000)
++#define IXP4XX_TIMESYNC_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000)
++#define IXP4XX_I2C_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
++#define IXP4XX_SSP_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
+ 
+ /*
+  * Constants to make it easy to access  Interrupt Controller registers
+diff --git a/include/asm-arm/arch-ixp4xx/memory.h b/include/asm-arm/arch-ixp4xx/memory.h
+--- a/include/asm-arm/arch-ixp4xx/memory.h
++++ b/include/asm-arm/arch-ixp4xx/memory.h
+@@ -12,7 +12,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0x00000000UL)
++#define PHYS_OFFSET	UL(0x00000000)
+ 
+ #ifndef __ASSEMBLY__
+ 
+diff --git a/include/asm-arm/arch-l7200/io.h b/include/asm-arm/arch-l7200/io.h
+--- a/include/asm-arm/arch-l7200/io.h
++++ b/include/asm-arm/arch-l7200/io.h
+@@ -10,7 +10,7 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
+-#include <asm/arch/hardware.h>
++#include <asm/hardware.h>
+ 
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+diff --git a/include/asm-arm/arch-l7200/memory.h b/include/asm-arm/arch-l7200/memory.h
+--- a/include/asm-arm/arch-l7200/memory.h
++++ b/include/asm-arm/arch-l7200/memory.h
+@@ -15,7 +15,7 @@
+ /*
+  * Physical DRAM offset on the L7200 SDB.
+  */
+-#define PHYS_OFFSET     (0xf0000000UL)
++#define PHYS_OFFSET     UL(0xf0000000)
+ 
+ #define __virt_to_bus(x) __virt_to_phys(x)
+ #define __bus_to_virt(x) __phys_to_virt(x)
+diff --git a/include/asm-arm/arch-lh7a40x/io.h b/include/asm-arm/arch-lh7a40x/io.h
+--- a/include/asm-arm/arch-lh7a40x/io.h
++++ b/include/asm-arm/arch-lh7a40x/io.h
+@@ -11,6 +11,8 @@
+ #ifndef __ASM_ARCH_IO_H
+ #define __ASM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ /* No ISA or PCI bus on this machine. */
+diff --git a/include/asm-arm/arch-lh7a40x/memory.h b/include/asm-arm/arch-lh7a40x/memory.h
+--- a/include/asm-arm/arch-lh7a40x/memory.h
++++ b/include/asm-arm/arch-lh7a40x/memory.h
+@@ -17,7 +17,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0xc0000000UL)
++#define PHYS_OFFSET	UL(0xc0000000)
+ 
+ /*
+  * Virtual view <-> DMA view memory address translations
+diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h
+--- a/include/asm-arm/arch-omap/io.h
++++ b/include/asm-arm/arch-omap/io.h
+@@ -34,6 +34,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ /*
+diff --git a/include/asm-arm/arch-omap/memory.h b/include/asm-arm/arch-omap/memory.h
+--- a/include/asm-arm/arch-omap/memory.h
++++ b/include/asm-arm/arch-omap/memory.h
+@@ -37,9 +37,9 @@
+  * Physical DRAM offset.
+  */
+ #if defined(CONFIG_ARCH_OMAP1)
+-#define PHYS_OFFSET		(0x10000000UL)
++#define PHYS_OFFSET		UL(0x10000000)
+ #elif defined(CONFIG_ARCH_OMAP2)
+-#define PHYS_OFFSET		(0x80000000UL)
++#define PHYS_OFFSET		UL(0x80000000)
+ #endif
+ 
+ /*
+@@ -66,7 +66,7 @@
+ /*
+  * OMAP-1510 Local Bus address offset
+  */
+-#define OMAP1510_LB_OFFSET	(0x30000000UL)
++#define OMAP1510_LB_OFFSET	UL(0x30000000)
+ 
+ #define virt_to_lbus(x)		((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET)
+ #define lbus_to_virt(x)		((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
+diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h
+--- a/include/asm-arm/arch-pxa/hardware.h
++++ b/include/asm-arm/arch-pxa/hardware.h
+@@ -44,12 +44,12 @@
+ 
+ #ifndef __ASSEMBLY__
+ 
+-# define __REG(x)	(*((volatile unsigned long *)io_p2v(x)))
++# define __REG(x)	(*((volatile u32 *)io_p2v(x)))
+ 
+ /* With indexed regs we don't want to feed the index through io_p2v()
+    especially if it is a variable, otherwise horrible code will result. */
+ # define __REG2(x,y)	\
+-	(*(volatile unsigned long *)((unsigned long)&__REG(x) + (y)))
++	(*(volatile u32 *)((u32)&__REG(x) + (y)))
+ 
+ # define __PREG(x)	(io_v2p((u32)&(x)))
+ 
+diff --git a/include/asm-arm/arch-pxa/io.h b/include/asm-arm/arch-pxa/io.h
+--- a/include/asm-arm/arch-pxa/io.h
++++ b/include/asm-arm/arch-pxa/io.h
+@@ -6,6 +6,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ /*
+diff --git a/include/asm-arm/arch-pxa/irda.h b/include/asm-arm/arch-pxa/irda.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-pxa/irda.h
+@@ -0,0 +1,17 @@
++#ifndef ASMARM_ARCH_IRDA_H
++#define ASMARM_ARCH_IRDA_H
++
++/* board specific transceiver capabilities */
++
++#define IR_OFF		1
++#define IR_SIRMODE	2
++#define IR_FIRMODE	4
++
++struct pxaficp_platform_data {
++	int transceiver_cap;
++	void (*transceiver_mode)(struct device *dev, int mode);
++};
++
++extern void pxa_set_ficp_info(struct pxaficp_platform_data *info);
++
++#endif
+diff --git a/include/asm-arm/arch-pxa/memory.h b/include/asm-arm/arch-pxa/memory.h
+--- a/include/asm-arm/arch-pxa/memory.h
++++ b/include/asm-arm/arch-pxa/memory.h
+@@ -15,7 +15,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0xa0000000UL)
++#define PHYS_OFFSET	UL(0xa0000000)
+ 
+ /*
+  * Virtual view <-> DMA view memory address translations
+diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
+--- a/include/asm-arm/arch-pxa/pxa-regs.h
++++ b/include/asm-arm/arch-pxa/pxa-regs.h
+@@ -326,6 +326,25 @@
+ #define STDLL		__REG(0x40700000)  /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+ #define STDLH		__REG(0x40700004)  /* Divisor Latch High Register (DLAB = 1) (read/write) */
+ 
++/* Hardware UART (HWUART) */
++#define HWUART		HWRBR
++#define HWRBR		__REG(0x41600000)  /* Receive Buffer Register (read only) */
++#define HWTHR		__REG(0x41600000)  /* Transmit Holding Register (write only) */
++#define HWIER		__REG(0x41600004)  /* Interrupt Enable Register (read/write) */
++#define HWIIR		__REG(0x41600008)  /* Interrupt ID Register (read only) */
++#define HWFCR		__REG(0x41600008)  /* FIFO Control Register (write only) */
++#define HWLCR		__REG(0x4160000C)  /* Line Control Register (read/write) */
++#define HWMCR		__REG(0x41600010)  /* Modem Control Register (read/write) */
++#define HWLSR		__REG(0x41600014)  /* Line Status Register (read only) */
++#define HWMSR		__REG(0x41600018)  /* Modem Status Register (read only) */
++#define HWSPR		__REG(0x4160001C)  /* Scratch Pad Register (read/write) */
++#define HWISR		__REG(0x41600020)  /* Infrared Selection Register (read/write) */
++#define HWFOR		__REG(0x41600024)  /* Receive FIFO Occupancy Register (read only) */
++#define HWABR		__REG(0x41600028)  /* Auto-Baud Control Register (read/write) */
++#define HWACR		__REG(0x4160002C)  /* Auto-Baud Count Register (read only) */
++#define HWDLL		__REG(0x41600000)  /* Divisor Latch Low Register (DLAB = 1) (read/write) */
++#define HWDLH		__REG(0x41600004)  /* Divisor Latch High Register (DLAB = 1) (read/write) */
++
+ #define IER_DMAE	(1 << 7)	/* DMA Requests Enable */
+ #define IER_UUE		(1 << 6)	/* UART Unit Enable */
+ #define IER_NRZE	(1 << 5)	/* NRZ coding Enable */
+@@ -1013,14 +1032,12 @@
+ #define ICCR0_LBM	(1 << 1)	/* Loopback mode */
+ #define ICCR0_ITR	(1 << 0)	/* IrDA transmission */
+ 
+-#ifdef CONFIG_PXA27x
+ #define ICCR2_RXP       (1 << 3)	/* Receive Pin Polarity select */
+ #define ICCR2_TXP       (1 << 2)	/* Transmit Pin Polarity select */
+ #define ICCR2_TRIG	(3 << 0)	/* Receive FIFO Trigger threshold */
+ #define ICCR2_TRIG_8    (0 << 0)	/* 	>= 8 bytes */
+ #define ICCR2_TRIG_16   (1 << 0)	/*	>= 16 bytes */
+ #define ICCR2_TRIG_32   (2 << 0)	/*	>= 32 bytes */
+-#endif
+ 
+ #ifdef CONFIG_PXA27x
+ #define ICSR0_EOC	(1 << 6)	/* DMA End of Descriptor Chain */
+@@ -1250,9 +1267,13 @@
+ #define GPIO40_FFDTR		40	/* FFUART data terminal Ready */
+ #define GPIO41_FFRTS		41	/* FFUART request to send */
+ #define GPIO42_BTRXD		42	/* BTUART receive data */
++#define GPIO42_HWRXD		42	/* HWUART receive data */
+ #define GPIO43_BTTXD		43	/* BTUART transmit data */
++#define GPIO43_HWTXD		43	/* HWUART transmit data */
+ #define GPIO44_BTCTS		44	/* BTUART clear to send */
++#define GPIO44_HWCTS		44	/* HWUART clear to send */
+ #define GPIO45_BTRTS		45	/* BTUART request to send */
++#define GPIO45_HWRTS		45	/* HWUART request to send */
+ #define GPIO45_AC97_SYSCLK	45	/* AC97 System Clock */
+ #define GPIO46_ICPRXD		46	/* ICP receive data */
+ #define GPIO46_STRXD		46	/* STD_UART receive data */
+@@ -1378,17 +1399,26 @@
+ #define GPIO40_FFDTR_MD		(40 | GPIO_ALT_FN_2_OUT)
+ #define GPIO41_FFRTS_MD		(41 | GPIO_ALT_FN_2_OUT)
+ #define GPIO42_BTRXD_MD		(42 | GPIO_ALT_FN_1_IN)
++#define GPIO42_HWRXD_MD		(42 | GPIO_ALT_FN_3_IN)
+ #define GPIO43_BTTXD_MD		(43 | GPIO_ALT_FN_2_OUT)
++#define GPIO43_HWTXD_MD		(43 | GPIO_ALT_FN_3_OUT)
+ #define GPIO44_BTCTS_MD		(44 | GPIO_ALT_FN_1_IN)
++#define GPIO44_HWCTS_MD		(44 | GPIO_ALT_FN_3_IN)
+ #define GPIO45_BTRTS_MD		(45 | GPIO_ALT_FN_2_OUT)
++#define GPIO45_HWRTS_MD		(45 | GPIO_ALT_FN_3_OUT)
+ #define GPIO45_SYSCLK_AC97_MD		(45 | GPIO_ALT_FN_1_OUT)
+ #define GPIO46_ICPRXD_MD	(46 | GPIO_ALT_FN_1_IN)
+ #define GPIO46_STRXD_MD		(46 | GPIO_ALT_FN_2_IN)
+ #define GPIO47_ICPTXD_MD	(47 | GPIO_ALT_FN_2_OUT)
+ #define GPIO47_STTXD_MD		(47 | GPIO_ALT_FN_1_OUT)
+ #define GPIO48_nPOE_MD		(48 | GPIO_ALT_FN_2_OUT)
++#define GPIO48_HWTXD_MD         (48 | GPIO_ALT_FN_1_OUT)
++#define GPIO48_nPOE_MD          (48 | GPIO_ALT_FN_2_OUT)
++#define GPIO49_HWRXD_MD		(49 | GPIO_ALT_FN_1_IN)
+ #define GPIO49_nPWE_MD		(49 | GPIO_ALT_FN_2_OUT)
+ #define GPIO50_nPIOR_MD		(50 | GPIO_ALT_FN_2_OUT)
++#define GPIO50_HWCTS_MD         (50 | GPIO_ALT_FN_1_IN)
++#define GPIO51_HWRTS_MD         (51 | GPIO_ALT_FN_1_OUT)
+ #define GPIO51_nPIOW_MD		(51 | GPIO_ALT_FN_2_OUT)
+ #define GPIO52_nPCE_1_MD	(52 | GPIO_ALT_FN_2_OUT)
+ #define GPIO53_nPCE_2_MD	(53 | GPIO_ALT_FN_2_OUT)
+@@ -1763,6 +1793,7 @@
+ #define CKEN7_BTUART	(1 << 7)	/* BTUART Unit Clock Enable */
+ #define CKEN6_FFUART	(1 << 6)	/* FFUART Unit Clock Enable */
+ #define CKEN5_STUART	(1 << 5)	/* STUART Unit Clock Enable */
++#define CKEN4_HWUART	(1 << 4)	/* HWUART Unit Clock Enable */
+ #define CKEN4_SSP3	(1 << 4)	/* SSP3 Unit Clock Enable */
+ #define CKEN3_SSP	(1 << 3)	/* SSP Unit Clock Enable */
+ #define CKEN3_SSP2	(1 << 3)	/* SSP2 Unit Clock Enable */
+@@ -2282,4 +2313,11 @@
+ 
+ #endif
+ 
++/* PWRMODE register M field values */
++
++#define PWRMODE_IDLE		0x1
++#define PWRMODE_STANDBY		0x2
++#define PWRMODE_SLEEP		0x3
++#define PWRMODE_DEEPSLEEP	0x7
++
+ #endif
+diff --git a/include/asm-arm/arch-pxa/uncompress.h b/include/asm-arm/arch-pxa/uncompress.h
+--- a/include/asm-arm/arch-pxa/uncompress.h
++++ b/include/asm-arm/arch-pxa/uncompress.h
+@@ -12,6 +12,7 @@
+ #define FFUART		((volatile unsigned long *)0x40100000)
+ #define BTUART		((volatile unsigned long *)0x40200000)
+ #define STUART		((volatile unsigned long *)0x40700000)
++#define HWUART		((volatile unsigned long *)0x41600000)
+ 
+ #define UART		FFUART
+ 
+diff --git a/include/asm-arm/arch-realview/debug-macro.S b/include/asm-arm/arch-realview/debug-macro.S
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/debug-macro.S
+@@ -0,0 +1,38 @@
++/* linux/include/asm-arm/arch-realview/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 <asm/hardware/amba_serial.h>
++
++		.macro	addruart,rx
++		mrc	p15, 0, \rx, c1, c0
++		tst	\rx, #1			@ MMU enabled?
++		moveq	\rx,      #0x10000000
++		movne	\rx,      #0xf1000000	@ virtual base
++		orr	\rx, \rx, #0x00009000
++		.endm
++
++		.macro	senduart,rd,rx
++		strb	\rd, [\rx, #UART01x_DR]
++		.endm
++
++		.macro	waituart,rd,rx
++1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
++		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
++		bne	1001b
++		.endm
++
++		.macro	busyuart,rd,rx
++1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
++		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
++		bne	1001b
++		.endm
+diff --git a/include/asm-arm/arch-realview/dma.h b/include/asm-arm/arch-realview/dma.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/dma.h
+@@ -0,0 +1,27 @@
++/*
++ *  linux/include/asm-arm/arch-realview/dma.h
++ *
++ *  Copyright (C) 2003 ARM Limited.
++ *  Copyright (C) 1997,1998 Russell King
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You 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_DMA_H
++#define __ASM_ARCH_DMA_H
++
++#define MAX_DMA_ADDRESS		0xffffffff
++#define MAX_DMA_CHANNELS	0
++
++#endif /* _ASM_ARCH_DMA_H */
+diff --git a/include/asm-arm/arch-realview/entry-macro.S b/include/asm-arm/arch-realview/entry-macro.S
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/entry-macro.S
+@@ -0,0 +1,49 @@
++/*
++ * include/asm-arm/arch-realview/entry-macro.S
++ *
++ * Low-level IRQ helper macros for RealView platforms
++ *
++ * This file is licensed under  the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++
++#include <asm/hardware/gic.h>
++
++		.macro	disable_fiq
++		.endm
++
++		/*
++		 * The interrupt numbering scheme is defined in the
++		 * interrupt controller spec.  To wit:
++		 *
++		 * Interrupts 0-15 are IPI
++		 * 16-28 are reserved
++		 * 29-31 are local.  We allow 30 to be used for the watchdog.
++		 * 32-1020 are global
++		 * 1021-1022 are reserved
++		 * 1023 is "spurious" (no interrupt)
++		 *
++		 * For now, we ignore all local interrupts so only return an interrupt if it's
++		 * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
++		 *
++		 * A simple read from the controller will tell us the number of the highest
++                 * priority enabled interrupt.  We then just need to check whether it is in the
++		 * valid range for an IRQ (30-1020 inclusive).
++		 */
++
++		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
++
++		ldr     \base, =IO_ADDRESS(REALVIEW_GIC_CPU_BASE)
++		ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
++
++		ldr	\tmp, =1021
++
++		bic     \irqnr, \irqstat, #0x1c00
++
++		cmp     \irqnr, #29
++		cmpcc	\irqnr, \irqnr
++		cmpne	\irqnr, \tmp
++		cmpcs	\irqnr, \irqnr
++
++		.endm
+diff --git a/include/asm-arm/arch-realview/hardware.h b/include/asm-arm/arch-realview/hardware.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/hardware.h
+@@ -0,0 +1,31 @@
++/*
++ *  linux/include/asm-arm/arch-realview/hardware.h
++ *
++ *  This file contains the hardware definitions of the RealView boards.
++ *
++ *  Copyright (C) 2003 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
++ */
++#ifndef __ASM_ARCH_HARDWARE_H
++#define __ASM_ARCH_HARDWARE_H
++
++#include <asm/sizes.h>
++#include <asm/arch/platform.h>
++
++/* macro to get at IO space when running virtually */
++#define IO_ADDRESS(x)		(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
++
++#endif
+diff --git a/include/asm-arm/arch-realview/io.h b/include/asm-arm/arch-realview/io.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/io.h
+@@ -0,0 +1,34 @@
++/*
++ *  linux/include/asm-arm/arch-realview/io.h
++ *
++ *  Copyright (C) 2003 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
++ */
++#ifndef __ASM_ARM_ARCH_IO_H
++#define __ASM_ARM_ARCH_IO_H
++
++#define IO_SPACE_LIMIT 0xffffffff
++
++static inline void __iomem *__io(unsigned long addr)
++{
++	return (void __iomem *)addr;
++}
++
++#define __io(a)			__io(a)
++#define __mem_pci(a)		(a)
++#define __mem_isa(a)		(a)
++
++#endif
+diff --git a/include/asm-arm/arch-realview/irqs.h b/include/asm-arm/arch-realview/irqs.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/irqs.h
+@@ -0,0 +1,103 @@
++/*
++ *  linux/include/asm-arm/arch-realview/irqs.h
++ *
++ *  Copyright (C) 2003 ARM Limited
++ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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/arch/platform.h>
++
++/* 
++ *  IRQ interrupts definitions are the same the INT definitions
++ *  held within platform.h
++ */
++#define IRQ_GIC_START		32
++#define IRQ_WDOGINT		(IRQ_GIC_START + INT_WDOGINT)
++#define IRQ_SOFTINT		(IRQ_GIC_START + INT_SOFTINT)
++#define IRQ_COMMRx		(IRQ_GIC_START + INT_COMMRx)
++#define IRQ_COMMTx		(IRQ_GIC_START + INT_COMMTx)
++#define IRQ_TIMERINT0_1		(IRQ_GIC_START + INT_TIMERINT0_1)
++#define IRQ_TIMERINT2_3		(IRQ_GIC_START + INT_TIMERINT2_3)
++#define IRQ_GPIOINT0		(IRQ_GIC_START + INT_GPIOINT0)
++#define IRQ_GPIOINT1		(IRQ_GIC_START + INT_GPIOINT1)
++#define IRQ_GPIOINT2		(IRQ_GIC_START + INT_GPIOINT2)
++#define IRQ_GPIOINT3		(IRQ_GIC_START + INT_GPIOINT3)
++#define IRQ_RTCINT		(IRQ_GIC_START + INT_RTCINT)
++#define IRQ_SSPINT		(IRQ_GIC_START + INT_SSPINT)
++#define IRQ_UARTINT0		(IRQ_GIC_START + INT_UARTINT0)
++#define IRQ_UARTINT1		(IRQ_GIC_START + INT_UARTINT1)
++#define IRQ_UARTINT2		(IRQ_GIC_START + INT_UARTINT2)
++#define IRQ_UART3		(IRQ_GIC_START + INT_UARTINT3)
++#define IRQ_SCIINT		(IRQ_GIC_START + INT_SCIINT)
++#define IRQ_CLCDINT		(IRQ_GIC_START + INT_CLCDINT)
++#define IRQ_DMAINT		(IRQ_GIC_START + INT_DMAINT)
++#define IRQ_PWRFAILINT 		(IRQ_GIC_START + INT_PWRFAILINT)
++#define IRQ_MBXINT		(IRQ_GIC_START + INT_MBXINT)
++#define IRQ_GNDINT		(IRQ_GIC_START + INT_GNDINT)
++#define IRQ_MMCI0B 		(IRQ_GIC_START + INT_MMCI0B)
++#define IRQ_MMCI1B 		(IRQ_GIC_START + INT_MMCI1B)
++#define IRQ_KMI0		(IRQ_GIC_START + INT_KMI0)
++#define IRQ_KMI1		(IRQ_GIC_START + INT_KMI1)
++#define IRQ_SCI3		(IRQ_GIC_START + INT_SCI3)
++#define IRQ_CLCD		(IRQ_GIC_START + INT_CLCD)
++#define IRQ_TOUCH		(IRQ_GIC_START + INT_TOUCH)
++#define IRQ_KEYPAD 		(IRQ_GIC_START + INT_KEYPAD)
++#define IRQ_DoC			(IRQ_GIC_START + INT_DoC)
++#define IRQ_MMCI0A 		(IRQ_GIC_START + INT_MMCI0A)
++#define IRQ_MMCI1A 		(IRQ_GIC_START + INT_MMCI1A)
++#define IRQ_AACI		(IRQ_GIC_START + INT_AACI)
++#define IRQ_ETH			(IRQ_GIC_START + INT_ETH)
++#define IRQ_USB			(IRQ_GIC_START + INT_USB)
++
++#define IRQMASK_WDOGINT		INTMASK_WDOGINT
++#define IRQMASK_SOFTINT		INTMASK_SOFTINT
++#define IRQMASK_COMMRx 		INTMASK_COMMRx
++#define IRQMASK_COMMTx 		INTMASK_COMMTx
++#define IRQMASK_TIMERINT0_1	INTMASK_TIMERINT0_1
++#define IRQMASK_TIMERINT2_3	INTMASK_TIMERINT2_3
++#define IRQMASK_GPIOINT0	INTMASK_GPIOINT0
++#define IRQMASK_GPIOINT1	INTMASK_GPIOINT1
++#define IRQMASK_GPIOINT2	INTMASK_GPIOINT2
++#define IRQMASK_GPIOINT3	INTMASK_GPIOINT3
++#define IRQMASK_RTCINT 		INTMASK_RTCINT
++#define IRQMASK_SSPINT 		INTMASK_SSPINT
++#define IRQMASK_UARTINT0	INTMASK_UARTINT0
++#define IRQMASK_UARTINT1	INTMASK_UARTINT1
++#define IRQMASK_UARTINT2	INTMASK_UARTINT2
++#define IRQMASK_SCIINT 		INTMASK_SCIINT
++#define IRQMASK_CLCDINT		INTMASK_CLCDINT
++#define IRQMASK_DMAINT 		INTMASK_DMAINT
++#define IRQMASK_PWRFAILINT	INTMASK_PWRFAILINT
++#define IRQMASK_MBXINT 		INTMASK_MBXINT
++#define IRQMASK_GNDINT 		INTMASK_GNDINT
++#define IRQMASK_MMCI0B		INTMASK_MMCI0B
++#define IRQMASK_MMCI1B		INTMASK_MMCI1B
++#define IRQMASK_KMI0		INTMASK_KMI0
++#define IRQMASK_KMI1		INTMASK_KMI1
++#define IRQMASK_SCI3		INTMASK_SCI3
++#define IRQMASK_UART3		INTMASK_UART3
++#define IRQMASK_CLCD		INTMASK_CLCD
++#define IRQMASK_TOUCH		INTMASK_TOUCH
++#define IRQMASK_KEYPAD		INTMASK_KEYPAD
++#define IRQMASK_DoC		INTMASK_DoC
++#define IRQMASK_MMCI0A		INTMASK_MMCI0A
++#define IRQMASK_MMCI1A		INTMASK_MMCI1A
++#define IRQMASK_AACI		INTMASK_AACI
++#define IRQMASK_ETH		INTMASK_ETH
++#define IRQMASK_USB		INTMASK_USB
++
++#define NR_IRQS			(IRQ_GIC_START + 64)
+diff --git a/include/asm-arm/arch-realview/memory.h b/include/asm-arm/arch-realview/memory.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/memory.h
+@@ -0,0 +1,38 @@
++/*
++ *  linux/include/asm-arm/arch-realview/memory.h
++ *
++ *  Copyright (C) 2003 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
++ */
++#ifndef __ASM_ARCH_MEMORY_H
++#define __ASM_ARCH_MEMORY_H
++
++/*
++ * Physical DRAM offset.
++ */
++#define PHYS_OFFSET		(0x00000000UL)
++
++/*
++ * 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)	((x) - PAGE_OFFSET)
++#define __bus_to_virt(x)	((x) + PAGE_OFFSET)
++
++#endif
+diff --git a/include/asm-arm/arch-realview/param.h b/include/asm-arm/arch-realview/param.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/param.h
+@@ -0,0 +1,19 @@
++/*
++ *  linux/include/asm-arm/arch-realview/param.h
++ *
++ *  Copyright (C) 2002 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
++ */
+diff --git a/include/asm-arm/arch-realview/platform.h b/include/asm-arm/arch-realview/platform.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/platform.h
+@@ -0,0 +1,395 @@
++/*
++ * linux/include/asm-arm/arch-realview/platform.h
++ *
++ * Copyright (c) ARM Limited 2003.  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
++ */
++
++#ifndef __address_h
++#define __address_h                     1
++
++/*
++ * Memory definitions
++ */
++#define REALVIEW_BOOT_ROM_LO          0x30000000		/* DoC Base (64Mb)...*/
++#define REALVIEW_BOOT_ROM_HI          0x30000000
++#define REALVIEW_BOOT_ROM_BASE        REALVIEW_BOOT_ROM_HI	 /*  Normal position */
++#define REALVIEW_BOOT_ROM_SIZE        SZ_64M
++
++#define REALVIEW_SSRAM_BASE           /* REALVIEW_SSMC_BASE ? */
++#define REALVIEW_SSRAM_SIZE           SZ_2M
++
++#define REALVIEW_FLASH_BASE           0x40000000
++#define REALVIEW_FLASH_SIZE           SZ_64M
++
++/* 
++ *  SDRAM
++ */
++#define REALVIEW_SDRAM_BASE           0x00000000
++
++/* 
++ *  Logic expansion modules
++ * 
++ */
++
++
++/* ------------------------------------------------------------------------
++ *  RealView Registers
++ * ------------------------------------------------------------------------
++ * 
++ */
++#define REALVIEW_SYS_ID_OFFSET               0x00
++#define REALVIEW_SYS_SW_OFFSET               0x04
++#define REALVIEW_SYS_LED_OFFSET              0x08
++#define REALVIEW_SYS_OSC0_OFFSET             0x0C
++
++#define REALVIEW_SYS_OSC1_OFFSET             0x10
++#define REALVIEW_SYS_OSC2_OFFSET             0x14
++#define REALVIEW_SYS_OSC3_OFFSET             0x18
++#define REALVIEW_SYS_OSC4_OFFSET             0x1C	/* OSC1 for RealView/AB */
++
++#define REALVIEW_SYS_LOCK_OFFSET             0x20
++#define REALVIEW_SYS_100HZ_OFFSET            0x24
++#define REALVIEW_SYS_CFGDATA1_OFFSET         0x28
++#define REALVIEW_SYS_CFGDATA2_OFFSET         0x2C
++#define REALVIEW_SYS_FLAGS_OFFSET            0x30
++#define REALVIEW_SYS_FLAGSSET_OFFSET         0x30
++#define REALVIEW_SYS_FLAGSCLR_OFFSET         0x34
++#define REALVIEW_SYS_NVFLAGS_OFFSET          0x38
++#define REALVIEW_SYS_NVFLAGSSET_OFFSET       0x38
++#define REALVIEW_SYS_NVFLAGSCLR_OFFSET       0x3C
++#define REALVIEW_SYS_RESETCTL_OFFSET         0x40
++#define REALVIEW_SYS_PCICTL_OFFSET           0x44
++#define REALVIEW_SYS_MCI_OFFSET              0x48
++#define REALVIEW_SYS_FLASH_OFFSET            0x4C
++#define REALVIEW_SYS_CLCD_OFFSET             0x50
++#define REALVIEW_SYS_CLCDSER_OFFSET          0x54
++#define REALVIEW_SYS_BOOTCS_OFFSET           0x58
++#define REALVIEW_SYS_24MHz_OFFSET            0x5C
++#define REALVIEW_SYS_MISC_OFFSET             0x60
++#define REALVIEW_SYS_IOSEL_OFFSET            0x70
++#define REALVIEW_SYS_TEST_OSC0_OFFSET        0x80
++#define REALVIEW_SYS_TEST_OSC1_OFFSET        0x84
++#define REALVIEW_SYS_TEST_OSC2_OFFSET        0x88
++#define REALVIEW_SYS_TEST_OSC3_OFFSET        0x8C
++#define REALVIEW_SYS_TEST_OSC4_OFFSET        0x90
++
++#define REALVIEW_SYS_BASE                    0x10000000
++#define REALVIEW_SYS_ID                      (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET)
++#define REALVIEW_SYS_SW                      (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET)
++#define REALVIEW_SYS_LED                     (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET)
++#define REALVIEW_SYS_OSC0                    (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET)
++#define REALVIEW_SYS_OSC1                    (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET)
++
++#define REALVIEW_SYS_LOCK                    (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET)
++#define REALVIEW_SYS_100HZ                   (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET)
++#define REALVIEW_SYS_CFGDATA1                (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET)
++#define REALVIEW_SYS_CFGDATA2                (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET)
++#define REALVIEW_SYS_FLAGS                   (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET)
++#define REALVIEW_SYS_FLAGSSET                (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET)
++#define REALVIEW_SYS_FLAGSCLR                (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET)
++#define REALVIEW_SYS_NVFLAGS                 (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET)
++#define REALVIEW_SYS_NVFLAGSSET              (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET)
++#define REALVIEW_SYS_NVFLAGSCLR              (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET)
++#define REALVIEW_SYS_RESETCTL                (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET)
++#define REALVIEW_SYS_PCICTL                  (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET)
++#define REALVIEW_SYS_MCI                     (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET)
++#define REALVIEW_SYS_FLASH                   (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET)
++#define REALVIEW_SYS_CLCD                    (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET)
++#define REALVIEW_SYS_CLCDSER                 (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET)
++#define REALVIEW_SYS_BOOTCS                  (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET)
++#define REALVIEW_SYS_24MHz                   (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET)
++#define REALVIEW_SYS_MISC                    (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET)
++#define REALVIEW_SYS_IOSEL                   (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET)
++#define REALVIEW_SYS_TEST_OSC0               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET)
++#define REALVIEW_SYS_TEST_OSC1               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET)
++#define REALVIEW_SYS_TEST_OSC2               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET)
++#define REALVIEW_SYS_TEST_OSC3               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
++#define REALVIEW_SYS_TEST_OSC4               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
++
++/* 
++ * Values for REALVIEW_SYS_RESET_CTRL
++ */
++#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR    0x01
++#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT   0x02
++#define REALVIEW_SYS_CTRL_RESET_DLLRESET     0x03
++#define REALVIEW_SYS_CTRL_RESET_PLLRESET     0x04
++#define REALVIEW_SYS_CTRL_RESET_POR          0x05
++#define REALVIEW_SYS_CTRL_RESET_DoC          0x06
++
++#define REALVIEW_SYS_CTRL_LED         (1 << 0)
++
++
++/* ------------------------------------------------------------------------
++ *  RealView control registers
++ * ------------------------------------------------------------------------
++ */
++
++/* 
++ * REALVIEW_IDFIELD
++ *
++ * 31:24 = manufacturer (0x41 = ARM)
++ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
++ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
++ * 11:4  = build value
++ * 3:0   = revision number (0x1 = rev B (AHB))
++ */
++
++/*
++ * REALVIEW_SYS_LOCK
++ *     control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, 
++ *     SYS_CLD, SYS_BOOTCS
++ */
++#define REALVIEW_SYS_LOCK_LOCKED    (1 << 16)
++#define REALVIEW_SYS_LOCKVAL_MASK	0xFFFF		/* write 0xA05F to enable write access */
++
++/*
++ * REALVIEW_SYS_FLASH
++ */
++#define REALVIEW_FLASHPROG_FLVPPEN	(1 << 0)	/* Enable writing to flash */
++
++/*
++ * REALVIEW_INTREG
++ *     - used to acknowledge and control MMCI and UART interrupts 
++ */
++#define REALVIEW_INTREG_WPROT        0x00    /* MMC protection status (no interrupt generated) */
++#define REALVIEW_INTREG_RI0          0x01    /* Ring indicator UART0 is asserted,              */
++#define REALVIEW_INTREG_CARDIN       0x08    /* MMCI card in detect                            */
++                                                /* write 1 to acknowledge and clear               */
++#define REALVIEW_INTREG_RI1          0x02    /* Ring indicator UART1 is asserted,              */
++#define REALVIEW_INTREG_CARDINSERT   0x03    /* Signal insertion of MMC card                   */
++
++/*
++ * REALVIEW peripheral addresses
++ */
++#define REALVIEW_SCTL_BASE            0x10001000	/* System controller */
++#define REALVIEW_I2C_BASE             0x10002000	/* I2C control */
++	/* Reserved 0x10003000 */
++#define REALVIEW_AACI_BASE            0x10004000	/* Audio */
++#define REALVIEW_MMCI0_BASE           0x10005000	/* MMC interface */
++#define REALVIEW_KMI0_BASE            0x10006000	/* KMI interface */
++#define REALVIEW_KMI1_BASE            0x10007000	/* KMI 2nd interface */
++#define REALVIEW_CHAR_LCD_BASE        0x10008000	/* Character LCD */
++#define REALVIEW_UART0_BASE           0x10009000	/* UART 0 */
++#define REALVIEW_UART1_BASE           0x1000A000	/* UART 1 */
++#define REALVIEW_UART2_BASE           0x1000B000	/* UART 2 */
++#define REALVIEW_UART3_BASE           0x1000C000	/* UART 3 */
++#define REALVIEW_SSP_BASE             0x1000D000	/* Synchronous Serial Port */
++#define REALVIEW_SCI_BASE             0x1000E000	/* Smart card controller */
++	/* Reserved 0x1000F000 */
++#define REALVIEW_WATCHDOG_BASE        0x10010000	/* watchdog interface */
++#define REALVIEW_TIMER0_1_BASE        0x10011000	/* Timer 0 and 1 */
++#define REALVIEW_TIMER2_3_BASE        0x10012000	/* Timer 2 and 3 */
++#define REALVIEW_GPIO0_BASE           0x10013000	/* GPIO port 0 */
++#define REALVIEW_GPIO1_BASE           0x10014000	/* GPIO port 1 */
++#define REALVIEW_GPIO2_BASE           0x10015000	/* GPIO port 2 */
++	/* Reserved 0x10016000 */
++#define REALVIEW_RTC_BASE             0x10017000	/* Real Time Clock */
++#define REALVIEW_DMC_BASE             0x10018000	/* DMC configuration */
++#define REALVIEW_PCI_CORE_BASE        0x10019000	/* PCI configuration */
++	/* Reserved 0x1001A000 - 0x1001FFFF */
++#define REALVIEW_CLCD_BASE            0x10020000	/* CLCD */
++#define REALVIEW_DMAC_BASE            0x10030000	/* DMA controller */
++#define REALVIEW_GIC_CPU_BASE         0x10040000	/* Generic interrupt controller CPU interface */
++#define REALVIEW_GIC_DIST_BASE        0x10041000	/* Generic interrupt controller distributor */
++#define REALVIEW_SMC_BASE             0x10080000	/* SMC */
++	/* Reserved 0x10090000 - 0x100EFFFF */
++
++#define REALVIEW_ETH_BASE             0x4E000000	/* Ethernet */
++
++/* PCI space */
++#define REALVIEW_PCI_BASE             0x41000000	/* PCI Interface */
++#define REALVIEW_PCI_CFG_BASE	      0x42000000
++#define REALVIEW_PCI_MEM_BASE0        0x44000000
++#define REALVIEW_PCI_MEM_BASE1        0x50000000
++#define REALVIEW_PCI_MEM_BASE2        0x60000000
++/* Sizes of above maps */
++#define REALVIEW_PCI_BASE_SIZE	       0x01000000
++#define REALVIEW_PCI_CFG_BASE_SIZE    0x02000000
++#define REALVIEW_PCI_MEM_BASE0_SIZE   0x0c000000	/* 32Mb */
++#define REALVIEW_PCI_MEM_BASE1_SIZE   0x10000000	/* 256Mb */
++#define REALVIEW_PCI_MEM_BASE2_SIZE   0x10000000	/* 256Mb */
++
++#define REALVIEW_SDRAM67_BASE         0x70000000	/* SDRAM banks 6 and 7 */
++#define REALVIEW_LT_BASE              0x80000000	/* Logic Tile expansion */
++
++/*
++ * Disk on Chip
++ */
++#define REALVIEW_DOC_BASE             0x2C000000
++#define REALVIEW_DOC_SIZE             (16 << 20)
++#define REALVIEW_DOC_PAGE_SIZE        512
++#define REALVIEW_DOC_TOTAL_PAGES     (DOC_SIZE / PAGE_SIZE)
++
++#define ERASE_UNIT_PAGES    32
++#define START_PAGE          0x80
++
++/* 
++ *  LED settings, bits [7:0]
++ */
++#define REALVIEW_SYS_LED0             (1 << 0)
++#define REALVIEW_SYS_LED1             (1 << 1)
++#define REALVIEW_SYS_LED2             (1 << 2)
++#define REALVIEW_SYS_LED3             (1 << 3)
++#define REALVIEW_SYS_LED4             (1 << 4)
++#define REALVIEW_SYS_LED5             (1 << 5)
++#define REALVIEW_SYS_LED6             (1 << 6)
++#define REALVIEW_SYS_LED7             (1 << 7)
++
++#define ALL_LEDS                  0xFF
++
++#define LED_BANK                  REALVIEW_SYS_LED
++
++/* 
++ * Control registers
++ */
++#define REALVIEW_IDFIELD_OFFSET	0x0	/* RealView build information */
++#define REALVIEW_FLASHPROG_OFFSET	0x4	/* Flash devices */
++#define REALVIEW_INTREG_OFFSET		0x8	/* Interrupt control */
++#define REALVIEW_DECODE_OFFSET		0xC	/* Fitted logic modules */
++
++/* ------------------------------------------------------------------------
++ *  Interrupts - bit assignment (primary)
++ * ------------------------------------------------------------------------
++ */
++#define INT_WDOGINT			0	/* Watchdog timer */
++#define INT_SOFTINT			1	/* Software interrupt */
++#define INT_COMMRx			2	/* Debug Comm Rx interrupt */
++#define INT_COMMTx			3	/* Debug Comm Tx interrupt */
++#define INT_TIMERINT0_1			4	/* Timer 0 and 1 */
++#define INT_TIMERINT2_3			5	/* Timer 2 and 3 */
++#define INT_GPIOINT0			6	/* GPIO 0 */
++#define INT_GPIOINT1			7	/* GPIO 1 */
++#define INT_GPIOINT2			8	/* GPIO 2 */
++/* 9 reserved */
++#define INT_RTCINT			10	/* Real Time Clock */
++#define INT_SSPINT			11	/* Synchronous Serial Port */
++#define INT_UARTINT0			12	/* UART 0 on development chip */
++#define INT_UARTINT1			13	/* UART 1 on development chip */
++#define INT_UARTINT2			14	/* UART 2 on development chip */
++#define INT_UARTINT3			15	/* UART 3 on development chip */
++#define INT_SCIINT			16	/* Smart Card Interface */
++#define INT_MMCI0A			17	/* Multimedia Card 0A */
++#define INT_MMCI0B			18	/* Multimedia Card 0B */
++#define INT_AACI			19	/* Audio Codec */
++#define INT_KMI0			20	/* Keyboard/Mouse port 0 */
++#define INT_KMI1			21	/* Keyboard/Mouse port 1 */
++#define INT_CHARLCD			22	/* Character LCD */
++#define INT_CLCDINT			23	/* CLCD controller */
++#define INT_DMAINT			24	/* DMA controller */
++#define INT_PWRFAILINT			25	/* Power failure */
++#define INT_PISMO			26
++#define INT_DoC				27	/* Disk on Chip memory controller */
++#define INT_ETH				28	/* Ethernet controller */
++#define INT_USB				29	/* USB controller */
++#define INT_TSPENINT			30	/* Touchscreen pen */
++#define INT_TSKPADINT			31	/* Touchscreen keypad */
++
++/* 
++ *  Interrupt bit positions
++ * 
++ */
++#define INTMASK_WDOGINT			(1 << INT_WDOGINT)
++#define INTMASK_SOFTINT			(1 << INT_SOFTINT)
++#define INTMASK_COMMRx			(1 << INT_COMMRx)
++#define INTMASK_COMMTx			(1 << INT_COMMTx)
++#define INTMASK_TIMERINT0_1		(1 << INT_TIMERINT0_1)
++#define INTMASK_TIMERINT2_3		(1 << INT_TIMERINT2_3)
++#define INTMASK_GPIOINT0		(1 << INT_GPIOINT0)
++#define INTMASK_GPIOINT1		(1 << INT_GPIOINT1)
++#define INTMASK_GPIOINT2		(1 << INT_GPIOINT2)
++#define INTMASK_RTCINT			(1 << INT_RTCINT)
++#define INTMASK_SSPINT			(1 << INT_SSPINT)
++#define INTMASK_UARTINT0		(1 << INT_UARTINT0)
++#define INTMASK_UARTINT1		(1 << INT_UARTINT1)
++#define INTMASK_UARTINT2		(1 << INT_UARTINT2)
++#define INTMASK_UARTINT3		(1 << INT_UARTINT3)
++#define INTMASK_SCIINT			(1 << INT_SCIINT)
++#define INTMASK_MMCI0A			(1 << INT_MMCI0A)
++#define INTMASK_MMCI0B			(1 << INT_MMCI0B)
++#define INTMASK_AACI			(1 << INT_AACI)
++#define INTMASK_KMI0			(1 << INT_KMI0)
++#define INTMASK_KMI1			(1 << INT_KMI1)
++#define INTMASK_CHARLCD			(1 << INT_CHARLCD)
++#define INTMASK_CLCDINT			(1 << INT_CLCDINT)
++#define INTMASK_DMAINT			(1 << INT_DMAINT)
++#define INTMASK_PWRFAILINT		(1 << INT_PWRFAILINT)
++#define INTMASK_PISMO			(1 << INT_PISMO)
++#define INTMASK_DoC			(1 << INT_DoC)
++#define INTMASK_ETH			(1 << INT_ETH)
++#define INTMASK_USB			(1 << INT_USB)
++#define INTMASK_TSPENINT		(1 << INT_TSPENINT)
++#define INTMASK_TSKPADINT		(1 << INT_TSKPADINT)
++
++#define MAXIRQNUM                       31
++#define MAXFIQNUM                       31
++#define MAXSWINUM                       31
++
++/* 
++ *  Application Flash
++ * 
++ */
++#define FLASH_BASE                      REALVIEW_FLASH_BASE
++#define FLASH_SIZE                      REALVIEW_FLASH_SIZE
++#define FLASH_END                       (FLASH_BASE + FLASH_SIZE - 1)
++#define FLASH_BLOCK_SIZE                SZ_128K
++
++/* 
++ *  Boot Flash
++ * 
++ */
++#define EPROM_BASE                      REALVIEW_BOOT_ROM_HI
++#define EPROM_SIZE                      REALVIEW_BOOT_ROM_SIZE
++#define EPROM_END                       (EPROM_BASE + EPROM_SIZE - 1)
++
++/* 
++ *  Clean base - dummy
++ * 
++ */
++#define CLEAN_BASE                      EPROM_BASE
++
++/*
++ * System controller bit assignment
++ */
++#define REALVIEW_REFCLK	0
++#define REALVIEW_TIMCLK	1
++
++#define REALVIEW_TIMER1_EnSel	15
++#define REALVIEW_TIMER2_EnSel	17
++#define REALVIEW_TIMER3_EnSel	19
++#define REALVIEW_TIMER4_EnSel	21
++
++
++#define MAX_TIMER                       2
++#define MAX_PERIOD                      699050
++#define TICKS_PER_uSEC                  1
++
++/* 
++ *  These are useconds NOT ticks.  
++ * 
++ */
++#define mSEC_1                          1000
++#define mSEC_5                          (mSEC_1 * 5)
++#define mSEC_10                         (mSEC_1 * 10)
++#define mSEC_25                         (mSEC_1 * 25)
++#define SEC_1                           (mSEC_1 * 1000)
++
++#define REALVIEW_CSR_BASE             0x10000000
++#define REALVIEW_CSR_SIZE             0x10000000
++
++#endif
++
++/* 	END */
+diff --git a/include/asm-arm/arch-realview/system.h b/include/asm-arm/arch-realview/system.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/system.h
+@@ -0,0 +1,51 @@
++/*
++ *  linux/include/asm-arm/arch-realview/system.h
++ *
++ *  Copyright (C) 2003 ARM Limited
++ *  Copyright (C) 2000 Deep Blue Solutions Ltd
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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 inline void arch_idle(void)
++{
++	/*
++	 * This should do all the clock switching
++	 * and wait for interrupt tricks
++	 */
++	cpu_do_idle();
++}
++
++static inline void arch_reset(char mode)
++{
++	unsigned int hdr_ctrl =	(IO_ADDRESS(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET);
++	unsigned int val;
++
++	/*
++	 * To reset, we hit the on-board reset register
++	 * in the system FPGA
++	 */
++	val = __raw_readl(hdr_ctrl);
++	val |= REALVIEW_SYS_CTRL_RESET_CONFIGCLR;
++	__raw_writel(val, hdr_ctrl);
++}
++
++#endif
+diff --git a/include/asm-arm/arch-realview/timex.h b/include/asm-arm/arch-realview/timex.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/timex.h
+@@ -0,0 +1,23 @@
++/*
++ *  linux/include/asm-arm/arch-realview/timex.h
++ *
++ *  RealView architecture timex specifications
++ *
++ *  Copyright (C) 2003 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 CLOCK_TICK_RATE		(50000000 / 16)
+diff --git a/include/asm-arm/arch-realview/uncompress.h b/include/asm-arm/arch-realview/uncompress.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/uncompress.h
+@@ -0,0 +1,54 @@
++/*
++ *  linux/include/asm-arm/arch-realview/uncompress.h
++ *
++ *  Copyright (C) 2003 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
++ */
++#include <asm/hardware.h>
++
++#define AMBA_UART_DR	(*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x00))
++#define AMBA_UART_LCRH	(*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x2c))
++#define AMBA_UART_CR	(*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x30))
++#define AMBA_UART_FR	(*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x18))
++
++/*
++ * This does not append a newline
++ */
++static void putstr(const char *s)
++{
++	while (*s) {
++		while (AMBA_UART_FR & (1 << 5))
++			barrier();
++
++		AMBA_UART_DR = *s;
++
++		if (*s == '\n') {
++			while (AMBA_UART_FR & (1 << 5))
++				barrier();
++
++			AMBA_UART_DR = '\r';
++		}
++		s++;
++	}
++	while (AMBA_UART_FR & (1 << 3))
++		barrier();
++}
++
++/*
++ * nothing to do
++ */
++#define arch_decomp_setup()
++#define arch_decomp_wdog()
+diff --git a/include/asm-arm/arch-realview/vmalloc.h b/include/asm-arm/arch-realview/vmalloc.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-arm/arch-realview/vmalloc.h
+@@ -0,0 +1,21 @@
++/*
++ *  linux/include/asm-arm/arch-realview/vmalloc.h
++ *
++ *  Copyright (C) 2003 ARM Limited
++ *  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 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 VMALLOC_END		(PAGE_OFFSET + 0x18000000)
+diff --git a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h
+--- a/include/asm-arm/arch-rpc/io.h
++++ b/include/asm-arm/arch-rpc/io.h
+@@ -13,6 +13,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ /*
+diff --git a/include/asm-arm/arch-rpc/memory.h b/include/asm-arm/arch-rpc/memory.h
+--- a/include/asm-arm/arch-rpc/memory.h
++++ b/include/asm-arm/arch-rpc/memory.h
+@@ -21,7 +21,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0x10000000UL)
++#define PHYS_OFFSET	UL(0x10000000)
+ 
+ /*
+  * These are exactly the same on the RiscPC as the
+diff --git a/include/asm-arm/arch-s3c2410/fb.h b/include/asm-arm/arch-s3c2410/fb.h
+--- a/include/asm-arm/arch-s3c2410/fb.h
++++ b/include/asm-arm/arch-s3c2410/fb.h
+@@ -13,6 +13,7 @@
+  *	07-Sep-2004	RTP	Created file
+  *	03-Nov-2004	BJD	Updated and minor cleanups
+  *	03-Aug-2005     RTP     Renamed to fb.h
++ *	26-Oct-2005	BJD	Changed name of platdata init
+ */
+ 
+ #ifndef __ASM_ARM_FB_H
+@@ -64,6 +65,6 @@ struct s3c2410fb_mach_info {
+ 	unsigned long	lpcsel;
+ };
+ 
+-void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info);
++extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *);
+ 
+ #endif /* __ASM_ARM_FB_H */
+diff --git a/include/asm-arm/arch-s3c2410/io.h b/include/asm-arm/arch-s3c2410/io.h
+--- a/include/asm-arm/arch-s3c2410/io.h
++++ b/include/asm-arm/arch-s3c2410/io.h
+@@ -15,6 +15,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ /*
+diff --git a/include/asm-arm/arch-s3c2410/memory.h b/include/asm-arm/arch-s3c2410/memory.h
+--- a/include/asm-arm/arch-s3c2410/memory.h
++++ b/include/asm-arm/arch-s3c2410/memory.h
+@@ -28,9 +28,9 @@
+  * and at 0x0C000000 for S3C2400
+  */
+ #ifdef CONFIG_CPU_S3C2400
+-#define PHYS_OFFSET	(0x0C000000UL)
++#define PHYS_OFFSET	UL(0x0C000000)
+ #else
+-#define PHYS_OFFSET	(0x30000000UL)
++#define PHYS_OFFSET	UL(0x30000000)
+ #endif
+ 
+ /*
+diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
+--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
++++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
+@@ -20,6 +20,7 @@
+  *    18-11-2004     BJD     Added S3C2440 AC97 controls
+  *    10-Mar-2005    LCVR    Changed S3C2410_VA to S3C24XX_VA
+  *    28-Mar-2005    LCVR    Fixed definition of GPB10
++ *    26-Oct-2005    BJD     Added generic configuration types
+ */
+ 
+ 
+@@ -43,6 +44,11 @@
+ /* general configuration options */
+ 
+ #define S3C2410_GPIO_LEAVE   (0xFFFFFFFF)
++#define S3C2410_GPIO_INPUT   (0xFFFFFFF0)
++#define S3C2410_GPIO_OUTPUT  (0xFFFFFFF1)
++#define S3C2410_GPIO_IRQ     (0xFFFFFFF2)	/* not available for all */
++#define S3C2410_GPIO_SFN2    (0xFFFFFFF2)	/* not available on A */
++#define S3C2410_GPIO_SFN3    (0xFFFFFFF3)	/* not available on A */
+ 
+ /* configure GPIO ports A..G */
+ 
+diff --git a/include/asm-arm/arch-s3c2410/regs-iis.h b/include/asm-arm/arch-s3c2410/regs-iis.h
+--- a/include/asm-arm/arch-s3c2410/regs-iis.h
++++ b/include/asm-arm/arch-s3c2410/regs-iis.h
+@@ -55,6 +55,7 @@
+ #define S3C2410_IISMOD_16FS	  (0<<0)
+ #define S3C2410_IISMOD_32FS	  (1<<0)
+ #define S3C2410_IISMOD_48FS	  (2<<0)
++#define S3C2410_IISMOD_FS_MASK	  (3<<0)
+ 
+ #define S3C2410_IISPSR		(0x08)
+ #define S3C2410_IISPSR_INTMASK	(31<<5)
+diff --git a/include/asm-arm/arch-sa1100/hardware.h b/include/asm-arm/arch-sa1100/hardware.h
+--- a/include/asm-arm/arch-sa1100/hardware.h
++++ b/include/asm-arm/arch-sa1100/hardware.h
+@@ -22,13 +22,6 @@
+ 
+ 
+ /*
+- * We requires absolute addresses i.e. (PCMCIA_IO_0_BASE + 0x3f8) for 
+- * in*()/out*() macros to be usable for all cases.
+- */
+-#define PCIO_BASE		0
+-
+-
+-/*
+  * SA1100 internal I/O mappings
+  *
+  * We have the following mapping:
+diff --git a/include/asm-arm/arch-sa1100/io.h b/include/asm-arm/arch-sa1100/io.h
+--- a/include/asm-arm/arch-sa1100/io.h
++++ b/include/asm-arm/arch-sa1100/io.h
+@@ -10,13 +10,19 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ /*
+  * We don't actually have real ISA nor PCI buses, but there is so many 
+  * drivers out there that might just work if we fake them...
+  */
+-#define __io(a)			((void __iomem *)(PCIO_BASE + (a)))
++static inline void __iomem *__io(unsigned long addr)
++{
++	return (void __iomem *)addr;
++}
++#define __io(a)			__io(a)
+ #define __mem_pci(a)		(a)
+ #define __mem_isa(a)		(a)
+ 
+diff --git a/include/asm-arm/arch-sa1100/memory.h b/include/asm-arm/arch-sa1100/memory.h
+--- a/include/asm-arm/arch-sa1100/memory.h
++++ b/include/asm-arm/arch-sa1100/memory.h
+@@ -13,7 +13,7 @@
+ /*
+  * Physical DRAM offset is 0xc0000000 on the SA1100
+  */
+-#define PHYS_OFFSET	(0xc0000000UL)
++#define PHYS_OFFSET	UL(0xc0000000)
+ 
+ #ifndef __ASSEMBLY__
+ 
+diff --git a/include/asm-arm/arch-sa1100/system.h b/include/asm-arm/arch-sa1100/system.h
+--- a/include/asm-arm/arch-sa1100/system.h
++++ b/include/asm-arm/arch-sa1100/system.h
+@@ -4,6 +4,7 @@
+  * Copyright (c) 1999 Nicolas Pitre <nico at cam.org>
+  */
+ #include <linux/config.h>
++#include <asm/hardware.h>
+ 
+ static inline void arch_idle(void)
+ {
+diff --git a/include/asm-arm/arch-shark/io.h b/include/asm-arm/arch-shark/io.h
+--- a/include/asm-arm/arch-shark/io.h
++++ b/include/asm-arm/arch-shark/io.h
+@@ -11,6 +11,8 @@
+ #ifndef __ASM_ARM_ARCH_IO_H
+ #define __ASM_ARM_ARCH_IO_H
+ 
++#include <asm/hardware.h>
++
+ #define IO_SPACE_LIMIT 0xffffffff
+ 
+ /*
+diff --git a/include/asm-arm/arch-shark/memory.h b/include/asm-arm/arch-shark/memory.h
+--- a/include/asm-arm/arch-shark/memory.h
++++ b/include/asm-arm/arch-shark/memory.h
+@@ -15,7 +15,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET     (0x08000000UL)
++#define PHYS_OFFSET     UL(0x08000000)
+ 
+ #ifndef __ASSEMBLY__
+ 
+diff --git a/include/asm-arm/arch-versatile/memory.h b/include/asm-arm/arch-versatile/memory.h
+--- a/include/asm-arm/arch-versatile/memory.h
++++ b/include/asm-arm/arch-versatile/memory.h
+@@ -23,7 +23,7 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PHYS_OFFSET	(0x00000000UL)
++#define PHYS_OFFSET	UL(0x00000000)
+ 
+ /*
+  * Virtual view <-> DMA view memory address translations
+diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
+--- a/include/asm-arm/dma-mapping.h
++++ b/include/asm-arm/dma-mapping.h
+@@ -70,7 +70,7 @@ static inline int dma_mapping_error(dma_
+  * device-viewed address.
+  */
+ extern void *
+-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp);
++dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
+ 
+ /**
+  * dma_free_coherent - free memory allocated by dma_alloc_coherent
+@@ -117,7 +117,7 @@ int dma_mmap_coherent(struct device *dev
+  * device-viewed address.
+  */
+ extern void *
+-dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, int gfp);
++dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
+ 
+ #define dma_free_writecombine(dev,size,cpu_addr,handle) \
+ 	dma_free_coherent(dev,size,cpu_addr,handle)
+diff --git a/include/asm-arm/hardware/amba_clcd.h b/include/asm-arm/hardware/amba_clcd.h
+--- a/include/asm-arm/hardware/amba_clcd.h
++++ b/include/asm-arm/hardware/amba_clcd.h
+@@ -22,7 +22,7 @@
+ #define CLCD_UBAS 		0x00000010
+ #define CLCD_LBAS 		0x00000014
+ 
+-#ifndef CONFIG_ARCH_VERSATILE
++#if !defined(CONFIG_ARCH_VERSATILE) && !defined(CONFIG_ARCH_REALVIEW)
+ #define CLCD_IENB 		0x00000018
+ #define CLCD_CNTL 		0x0000001c
+ #else
+diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
+--- a/include/asm-arm/io.h
++++ b/include/asm-arm/io.h
+@@ -26,7 +26,6 @@
+ #include <linux/types.h>
+ #include <asm/byteorder.h>
+ #include <asm/memory.h>
+-#include <asm/arch/hardware.h>
+ 
+ /*
+  * ISA I/O bus memory addresses are 1:1 with the physical address.
+diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
+--- a/include/asm-arm/mach/arch.h
++++ b/include/asm-arm/mach/arch.h
+@@ -48,10 +48,11 @@ struct machine_desc {
+  * Set of macros to define architecture features.  This is built into
+  * a table by the linker.
+  */
+-#define MACHINE_START(_type,_name)		\
+-const struct machine_desc __mach_desc_##_type	\
++#define MACHINE_START(_type,_name)			\
++static const struct machine_desc __mach_desc_##_type	\
++ __attribute_used__					\
+  __attribute__((__section__(".arch.info.init"))) = {	\
+-	.nr		= MACH_TYPE_##_type,	\
++	.nr		= MACH_TYPE_##_type,		\
+ 	.name		= _name,
+ 
+ #define MACHINE_END				\
+diff --git a/include/asm-arm/mach/flash.h b/include/asm-arm/mach/flash.h
+--- a/include/asm-arm/mach/flash.h
++++ b/include/asm-arm/mach/flash.h
+@@ -14,6 +14,7 @@ struct mtd_partition;
+ 
+ /*
+  * map_name:	the map probe function name
++ * name:	flash device name (eg, as used with mtdparts=)
+  * width:	width of mapped device
+  * init:	method called at driver/device initialisation
+  * exit:	method called at driver/device removal
+@@ -23,6 +24,7 @@ struct mtd_partition;
+  */
+ struct flash_platform_data {
+ 	const char	*map_name;
++	const char	*name;
+ 	unsigned int	width;
+ 	int		(*init)(void);
+ 	void		(*exit)(void);
+diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h
+--- a/include/asm-arm/mach/map.h
++++ b/include/asm-arm/mach/map.h
+@@ -11,7 +11,7 @@
+  */
+ struct map_desc {
+ 	unsigned long virtual;
+-	unsigned long physical;
++	unsigned long pfn;
+ 	unsigned long length;
+ 	unsigned int type;
+ };
+@@ -27,6 +27,9 @@ struct meminfo;
+ #define MT_ROM			6
+ #define MT_IXP2000_DEVICE	7
+ 
++#define	__phys_to_pfn(paddr)	((paddr) >> PAGE_SHIFT)
++#define	__pfn_to_phys(pfn)	((pfn) << PAGE_SHIFT)
++
+ extern void create_memmap_holes(struct meminfo *);
+ extern void memtable_init(struct meminfo *);
+ extern void iotable_init(struct map_desc *, int);
+diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
+--- a/include/asm-arm/memory.h
++++ b/include/asm-arm/memory.h
+@@ -12,6 +12,16 @@
+ #ifndef __ASM_ARM_MEMORY_H
+ #define __ASM_ARM_MEMORY_H
+ 
++/*
++ * Allow for constants defined here to be used from assembly code
++ * by prepending the UL suffix only with actual C code compilation.
++ */
++#ifndef __ASSEMBLY__
++#define UL(x) (x##UL)
++#else
++#define UL(x) (x)
++#endif
++
+ #include <linux/config.h>
+ #include <linux/compiler.h>
+ #include <asm/arch/memory.h>
+@@ -21,20 +31,20 @@
+  * TASK_SIZE - the maximum size of a user space task.
+  * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
+  */
+-#define TASK_SIZE		(0xbf000000UL)
+-#define TASK_UNMAPPED_BASE	(0x40000000UL)
++#define TASK_SIZE		UL(0xbf000000)
++#define TASK_UNMAPPED_BASE	UL(0x40000000)
+ #endif
+ 
+ /*
+  * The maximum size of a 26-bit user space task.
+  */
+-#define TASK_SIZE_26		(0x04000000UL)
++#define TASK_SIZE_26		UL(0x04000000)
+ 
+ /*
+  * Page offset: 3GB
+  */
+ #ifndef PAGE_OFFSET
+-#define PAGE_OFFSET		(0xc0000000UL)
++#define PAGE_OFFSET		UL(0xc0000000)
+ #endif
+ 
+ /*
+@@ -58,6 +68,13 @@
+ #error Top of user space clashes with start of module space
+ #endif
+ 
++/*
++ * The XIP kernel gets mapped at the bottom of the module vm area.
++ * Since we use sections to map it, this macro replaces the physical address
++ * with its virtual address while keeping offset from the base section.
++ */
++#define XIP_VIRT_ADDR(physaddr)  (MODULE_START + ((physaddr) & 0x000fffff))
++
+ #ifndef __ASSEMBLY__
+ 
+ /*
+diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
+--- a/include/asm-arm/pgtable.h
++++ b/include/asm-arm/pgtable.h
+@@ -397,9 +397,6 @@ static inline pte_t *pmd_page_kernel(pmd
+ #define pgd_clear(pgdp)		do { } while (0)
+ #define set_pgd(pgd,pgdp)	do { } while (0)
+ 
+-#define page_pte_prot(page,prot)	mk_pte(page, prot)
+-#define page_pte(page)		mk_pte(page, __pgprot(0))
+-
+ /* to find an entry in a page-table-directory */
+ #define pgd_index(addr)		((addr) >> PGDIR_SHIFT)
+ 
+diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h
+--- a/include/asm-arm/semaphore.h
++++ b/include/asm-arm/semaphore.h
+@@ -24,8 +24,6 @@ struct semaphore {
+ 	.wait	= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait),	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) __SEMAPHORE_INIT(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count)	\
+ 	struct semaphore name = __SEMAPHORE_INIT(name,count)
+ 
+diff --git a/include/asm-arm/tlb.h b/include/asm-arm/tlb.h
+--- a/include/asm-arm/tlb.h
++++ b/include/asm-arm/tlb.h
+@@ -27,11 +27,7 @@
+  */
+ struct mmu_gather {
+ 	struct mm_struct	*mm;
+-	unsigned int		freed;
+ 	unsigned int		fullmm;
+-
+-	unsigned int		flushes;
+-	unsigned int		avoided_flushes;
+ };
+ 
+ DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+@@ -39,11 +35,9 @@ DECLARE_PER_CPU(struct mmu_gather, mmu_g
+ static inline struct mmu_gather *
+ tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+ {
+-	int cpu = smp_processor_id();
+-	struct mmu_gather *tlb = &per_cpu(mmu_gathers, cpu);
++	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+ 
+ 	tlb->mm = mm;
+-	tlb->freed = 0;
+ 	tlb->fullmm = full_mm_flush;
+ 
+ 	return tlb;
+@@ -52,24 +46,13 @@ tlb_gather_mmu(struct mm_struct *mm, uns
+ static inline void
+ tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+ {
+-	struct mm_struct *mm = tlb->mm;
+-	unsigned long freed = tlb->freed;
+-	int rss = get_mm_counter(mm, rss);
+-
+-	if (rss < freed)
+-		freed = rss;
+-	add_mm_counter(mm, rss, -freed);
+-
+ 	if (tlb->fullmm)
+-		flush_tlb_mm(mm);
++		flush_tlb_mm(tlb->mm);
+ 
+ 	/* keep the page table cache within bounds */
+ 	check_pgt_cache();
+-}
+ 
+-static inline unsigned int tlb_is_full_mm(struct mmu_gather *tlb)
+-{
+-	return tlb->fullmm;
++	put_cpu_var(mmu_gathers);
+ }
+ 
+ #define tlb_remove_tlb_entry(tlb,ptep,address)	do { } while (0)
+diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
+--- a/include/asm-arm/unistd.h
++++ b/include/asm-arm/unistd.h
+@@ -544,7 +544,6 @@ asmlinkage int sys_clone(unsigned long c
+ asmlinkage int sys_fork(struct pt_regs *regs);
+ asmlinkage int sys_vfork(struct pt_regs *regs);
+ asmlinkage int sys_pipe(unsigned long *fildes);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				const struct sigaction __user *act,
+diff --git a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
+--- a/include/asm-arm26/pgtable.h
++++ b/include/asm-arm26/pgtable.h
+@@ -98,8 +98,6 @@ extern struct page *empty_zero_page;
+ #define pfn_pte(pfn,prot)	(__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+ #define pages_to_mb(x)		((x) >> (20 - PAGE_SHIFT))
+ #define mk_pte(page,prot)	pfn_pte(page_to_pfn(page),prot)
+-#define page_pte_prot(page,prot)	mk_pte(page, prot)
+-#define page_pte(page)		mk_pte(page, __pgprot(0))
+ 
+ /*
+  * Terminology: PGD = Page Directory, PMD = Page Middle Directory,
+diff --git a/include/asm-arm26/semaphore.h b/include/asm-arm26/semaphore.h
+--- a/include/asm-arm26/semaphore.h
++++ b/include/asm-arm26/semaphore.h
+@@ -25,9 +25,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait),	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INIT(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count)	\
+ 	struct semaphore name = __SEMAPHORE_INIT(name,count)
+ 
+diff --git a/include/asm-arm26/tlb.h b/include/asm-arm26/tlb.h
+--- a/include/asm-arm26/tlb.h
++++ b/include/asm-arm26/tlb.h
+@@ -10,24 +10,20 @@
+  */
+ struct mmu_gather {
+         struct mm_struct        *mm;
+-        unsigned int            freed;
+-	unsigned int            fullmm;
+-
+-        unsigned int            flushes;
+-        unsigned int            avoided_flushes;
++        unsigned int            need_flush;
++        unsigned int            fullmm;
+ };
+ 
+-extern struct mmu_gather mmu_gathers[NR_CPUS];
++DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+ 
+ static inline struct mmu_gather *
+ tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+ {
+-        int cpu = smp_processor_id();
+-        struct mmu_gather *tlb = &mmu_gathers[cpu];
++        struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+ 
+         tlb->mm = mm;
+-        tlb->freed = 0;
+-	tlb->fullmm = full_mm_flush;
++        tlb->need_flush = 0;
++        tlb->fullmm = full_mm_flush;
+ 
+         return tlb;
+ }
+@@ -35,30 +31,13 @@ tlb_gather_mmu(struct mm_struct *mm, uns
+ static inline void
+ tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+ {
+-        struct mm_struct *mm = tlb->mm;
+-        unsigned long freed = tlb->freed;
+-        int rss = get_mm_counter(mm, rss);
+-
+-        if (rss < freed)
+-                freed = rss;
+-        add_mm_counter(mm, rss, -freed);
+-
+-        if (freed) {
+-                flush_tlb_mm(mm);
+-                tlb->flushes++;
+-        } else {
+-                tlb->avoided_flushes++;
+-        }
++        if (tlb->need_flush)
++                flush_tlb_mm(tlb->mm);
+ 
+         /* keep the page table cache within bounds */
+         check_pgt_cache();
+-}
+ 
+-
+-static inline unsigned int
+-tlb_is_full_mm(struct mmu_gather *tlb)
+-{
+-     return tlb->fullmm;
++        put_cpu_var(mmu_gathers);
+ }
+ 
+ #define tlb_remove_tlb_entry(tlb,ptep,address)  do { } while (0)
+@@ -71,7 +50,13 @@ tlb_is_full_mm(struct mmu_gather *tlb)
+         } while (0)
+ #define tlb_end_vma(tlb,vma)                    do { } while (0)
+ 
+-#define tlb_remove_page(tlb,page)       free_page_and_swap_cache(page)
++static inline void
++tlb_remove_page(struct mmu_gather *tlb, struct page *page)
++{
++        tlb->need_flush = 1;
++        free_page_and_swap_cache(page);
++}
++
+ #define pte_free_tlb(tlb,ptep)          pte_free(ptep)
+ #define pmd_free_tlb(tlb,pmdp)          pmd_free(pmdp)
+ 
+diff --git a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h
+--- a/include/asm-arm26/unistd.h
++++ b/include/asm-arm26/unistd.h
+@@ -480,7 +480,6 @@ asmlinkage int sys_clone(unsigned long c
+ asmlinkage int sys_fork(struct pt_regs *regs);
+ asmlinkage int sys_vfork(struct pt_regs *regs);
+ asmlinkage int sys_pipe(unsigned long *fildes);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				const struct sigaction __user *act,
+diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
+--- a/include/asm-cris/dma-mapping.h
++++ b/include/asm-cris/dma-mapping.h
+@@ -15,14 +15,14 @@
+ 
+ #ifdef CONFIG_PCI
+ void *dma_alloc_coherent(struct device *dev, size_t size,
+-			   dma_addr_t *dma_handle, int flag);
++			   dma_addr_t *dma_handle, gfp_t flag);
+ 
+ void dma_free_coherent(struct device *dev, size_t size,
+ 			 void *vaddr, dma_addr_t dma_handle);
+ #else
+ static inline void *
+ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+-                   int flag)
++                   gfp_t flag)
+ {
+         BUG();
+         return NULL;
+diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h
+--- a/include/asm-cris/semaphore.h
++++ b/include/asm-cris/semaphore.h
+@@ -33,9 +33,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-        __SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+         struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h
+--- a/include/asm-cris/unistd.h
++++ b/include/asm-cris/unistd.h
+@@ -367,7 +367,6 @@ asmlinkage int sys_fork(long r10, long r
+ asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
+ 			long mof, long srp, struct pt_regs *regs);
+ asmlinkage int sys_pipe(unsigned long __user *fildes);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				const struct sigaction __user *act,
+diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
+--- a/include/asm-frv/dma-mapping.h
++++ b/include/asm-frv/dma-mapping.h
+@@ -13,7 +13,7 @@
+ extern unsigned long __nongprelbss dma_coherent_mem_start;
+ extern unsigned long __nongprelbss dma_coherent_mem_end;
+ 
+-void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int gfp);
++void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
+ void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
+ 
+ /*
+diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h
+--- a/include/asm-frv/pci.h
++++ b/include/asm-frv/pci.h
+@@ -32,7 +32,7 @@ extern void pcibios_set_master(struct pc
+ extern void pcibios_penalize_isa_irq(int irq);
+ 
+ #ifdef CONFIG_MMU
+-extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
++extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
+ extern void consistent_free(void *vaddr);
+ extern void consistent_sync(void *vaddr, size_t size, int direction);
+ extern void consistent_sync_page(struct page *page, unsigned long offset,
+diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
+--- a/include/asm-frv/pgtable.h
++++ b/include/asm-frv/pgtable.h
+@@ -436,8 +436,6 @@ static inline pte_t pte_modify(pte_t pte
+ 	return pte;
+ }
+ 
+-#define page_pte(page)	page_pte_prot((page), __pgprot(0))
+-
+ /* to find an entry in a page-table-directory. */
+ #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+ #define pgd_index_k(addr) pgd_index(addr)
+diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h
+--- a/include/asm-frv/semaphore.h
++++ b/include/asm-frv/semaphore.h
+@@ -47,9 +47,6 @@ struct semaphore {
+ #define __SEMAPHORE_INITIALIZER(name,count) \
+ { count, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __SEM_DEBUG_INIT(name) }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-generic/4level-fixup.h b/include/asm-generic/4level-fixup.h
+--- a/include/asm-generic/4level-fixup.h
++++ b/include/asm-generic/4level-fixup.h
+@@ -10,14 +10,9 @@
+ 
+ #define pud_t				pgd_t
+ 
+-#define pmd_alloc(mm, pud, address)			\
+-({	pmd_t *ret;					\
+-	if (pgd_none(*pud))				\
+- 		ret = __pmd_alloc(mm, pud, address);	\
+- 	else						\
+-		ret = pmd_offset(pud, address);		\
+- 	ret;						\
+-})
++#define pmd_alloc(mm, pud, address) \
++	((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \
++ 		NULL: pmd_offset(pud, address))
+ 
+ #define pud_alloc(mm, pgd, address)	(pgd)
+ #define pud_offset(pgd, start)		(pgd)
+diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h
+--- a/include/asm-generic/dma-mapping-broken.h
++++ b/include/asm-generic/dma-mapping-broken.h
+@@ -6,7 +6,7 @@
+ 
+ static inline void *
+ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+-		   int flag)
++		   gfp_t flag)
+ {
+ 	BUG();
+ 	return NULL;
+diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
+--- a/include/asm-generic/pgtable.h
++++ b/include/asm-generic/pgtable.h
+@@ -8,7 +8,7 @@
+  *  - update the page tables
+  *  - inform the TLB about the new one
+  *
+- * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock.
++ * We hold the mm semaphore for reading, and the pte lock.
+  *
+  * Note: the old pte is known to not be writable, so we don't need to
+  * worry about dirty bits etc getting lost.
+diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
+--- a/include/asm-generic/tlb.h
++++ b/include/asm-generic/tlb.h
+@@ -35,16 +35,13 @@
+ #endif
+ 
+ /* struct mmu_gather is an opaque type used by the mm code for passing around
+- * any data needed by arch specific code for tlb_remove_page.  This structure
+- * can be per-CPU or per-MM as the page table lock is held for the duration of
+- * TLB shootdown.
++ * any data needed by arch specific code for tlb_remove_page.
+  */
+ struct mmu_gather {
+ 	struct mm_struct	*mm;
+ 	unsigned int		nr;	/* set to ~0U means fast mode */
+ 	unsigned int		need_flush;/* Really unmapped some ptes? */
+ 	unsigned int		fullmm; /* non-zero means full mm flush */
+-	unsigned long		freed;
+ 	struct page *		pages[FREE_PTE_NR];
+ };
+ 
+@@ -57,7 +54,7 @@ DECLARE_PER_CPU(struct mmu_gather, mmu_g
+ static inline struct mmu_gather *
+ tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+ {
+-	struct mmu_gather *tlb = &per_cpu(mmu_gathers, smp_processor_id());
++	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+ 
+ 	tlb->mm = mm;
+ 
+@@ -65,7 +62,6 @@ tlb_gather_mmu(struct mm_struct *mm, uns
+ 	tlb->nr = num_online_cpus() > 1 ? 0U : ~0U;
+ 
+ 	tlb->fullmm = full_mm_flush;
+-	tlb->freed = 0;
+ 
+ 	return tlb;
+ }
+@@ -85,28 +81,17 @@ tlb_flush_mmu(struct mmu_gather *tlb, un
+ 
+ /* tlb_finish_mmu
+  *	Called at the end of the shootdown operation to free up any resources
+- *	that were required.  The page table lock is still held at this point.
++ *	that were required.
+  */
+ static inline void
+ tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+ {
+-	int freed = tlb->freed;
+-	struct mm_struct *mm = tlb->mm;
+-	int rss = get_mm_counter(mm, rss);
+-
+-	if (rss < freed)
+-		freed = rss;
+-	add_mm_counter(mm, rss, -freed);
+ 	tlb_flush_mmu(tlb, start, end);
+ 
+ 	/* keep the page table cache within bounds */
+ 	check_pgt_cache();
+-}
+ 
+-static inline unsigned int
+-tlb_is_full_mm(struct mmu_gather *tlb)
+-{
+-	return tlb->fullmm;
++	put_cpu_var(mmu_gathers);
+ }
+ 
+ /* tlb_remove_page
+diff --git a/include/asm-h8300/semaphore.h b/include/asm-h8300/semaphore.h
+--- a/include/asm-h8300/semaphore.h
++++ b/include/asm-h8300/semaphore.h
+@@ -35,9 +35,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h
+--- a/include/asm-h8300/unistd.h
++++ b/include/asm-h8300/unistd.h
+@@ -528,7 +528,6 @@ asmlinkage long sys_mmap2(unsigned long 
+ asmlinkage int sys_execve(char *name, char **argv, char **envp,
+ 			int dummy, ...);
+ asmlinkage int sys_pipe(unsigned long *fildes);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				const struct sigaction __user *act,
+diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h
+--- a/include/asm-i386/desc.h
++++ b/include/asm-i386/desc.h
+@@ -17,6 +17,8 @@
+ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
+ DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
+ 
++#define get_cpu_gdt_table(_cpu) (per_cpu(cpu_gdt_table,_cpu))
++
+ DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
+ 
+ struct Xgt_desc_struct {
+@@ -60,7 +62,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
+ 
+ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
+ {
+-	_set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[entry], (int)addr,
++	_set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
+ 		offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
+ }
+ 
+@@ -68,7 +70,7 @@ static inline void __set_tss_desc(unsign
+ 
+ static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
+ {
+-	_set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
++	_set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
+ }
+ 
+ #define LDT_entry_a(info) \
+@@ -109,7 +111,7 @@ static inline void write_ldt_entry(void 
+ 
+ static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
+ {
+-#define C(i) per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
++#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
+ 	C(0); C(1); C(2);
+ #undef C
+ }
+diff --git a/include/asm-i386/mach-es7000/mach_mpparse.h b/include/asm-i386/mach-es7000/mach_mpparse.h
+--- a/include/asm-i386/mach-es7000/mach_mpparse.h
++++ b/include/asm-i386/mach-es7000/mach_mpparse.h
+@@ -16,7 +16,7 @@ static inline void mpc_oem_pci_bus(struc
+ 
+ extern int parse_unisys_oem (char *oemptr);
+ extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
+-extern void setup_unisys();
++extern void setup_unisys(void);
+ 
+ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
+ 		char *productid)
+diff --git a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h
+--- a/include/asm-i386/mach-summit/mach_mpparse.h
++++ b/include/asm-i386/mach-summit/mach_mpparse.h
+@@ -22,7 +22,6 @@ static inline void mpc_oem_pci_bus(struc
+ {
+ }
+ 
+-extern int usb_early_handoff;
+ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, 
+ 		char *productid)
+ {
+@@ -32,7 +31,6 @@ static inline int mps_oem_check(struct m
+ 			 || !strncmp(productid, "RUTHLESS SMP", 12))){
+ 		use_cyclone = 1; /*enable cyclone-timer*/
+ 		setup_summit();
+-		usb_early_handoff = 1;
+ 		return 1;
+ 	}
+ 	return 0;
+@@ -46,7 +44,6 @@ static inline int acpi_madt_oem_check(ch
+ 	     || !strncmp(oem_table_id, "EXA", 3))){
+ 		use_cyclone = 1; /*enable cyclone-timer*/
+ 		setup_summit();
+-		usb_early_handoff = 1;
+ 		return 1;
+ 	}
+ 	return 0;
+diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
+--- a/include/asm-i386/mmzone.h
++++ b/include/asm-i386/mmzone.h
+@@ -88,12 +88,6 @@ static inline int pfn_to_nid(unsigned lo
+ 	__pgdat->node_start_pfn + __pgdat->node_spanned_pages;		\
+ })
+ 
+-#define local_mapnr(kvaddr)						\
+-({									\
+-	unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT;		\
+-	(__pfn - node_start_pfn(pfn_to_nid(__pfn)));			\
+-})
+-
+ /* XXX: FIXME -- wli */
+ #define kern_addr_valid(kaddr)	(0)
+ 
+diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
+--- a/include/asm-i386/pgtable-2level.h
++++ b/include/asm-i386/pgtable-2level.h
+@@ -26,11 +26,6 @@
+ #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+ #define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+ 
+-#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+-
+-#define pmd_page_kernel(pmd) \
+-((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+-
+ /*
+  * All present user pages are user-executable:
+  */
+diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
+--- a/include/asm-i386/pgtable-3level.h
++++ b/include/asm-i386/pgtable-3level.h
+@@ -74,11 +74,6 @@ static inline void set_pte(pte_t *ptep, 
+  */
+ static inline void pud_clear (pud_t * pud) { }
+ 
+-#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+-
+-#define pmd_page_kernel(pmd) \
+-((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+-
+ #define pud_page(pud) \
+ ((struct page *) __va(pud_val(pud) & PAGE_MASK))
+ 
+diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
+--- a/include/asm-i386/pgtable.h
++++ b/include/asm-i386/pgtable.h
+@@ -203,7 +203,8 @@ extern unsigned long pg0[];
+ #define pte_present(x)	((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
+ #define pte_clear(mm,addr,xp)	do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
+ 
+-#define pmd_none(x)	(!pmd_val(x))
++/* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
++#define pmd_none(x)	(!(unsigned long)pmd_val(x))
+ #define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
+ #define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
+ #define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
+@@ -322,8 +323,6 @@ static inline pte_t pte_modify(pte_t pte
+ 	return pte;
+ }
+ 
+-#define page_pte(page) page_pte_prot(page, __pgprot(0))
+-
+ #define pmd_large(pmd) \
+ ((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
+ 
+@@ -368,6 +367,11 @@ static inline pte_t pte_modify(pte_t pte
+ #define pte_offset_kernel(dir, address) \
+ 	((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
+ 
++#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
++
++#define pmd_page_kernel(pmd) \
++		((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
++
+ /*
+  * Helper function that returns the kernel pagetable entry controlling
+  * the virtual address 'address'. NULL means no pagetable entry present.
+diff --git a/include/asm-i386/rwsem.h b/include/asm-i386/rwsem.h
+--- a/include/asm-i386/rwsem.h
++++ b/include/asm-i386/rwsem.h
+@@ -284,5 +284,10 @@ LOCK_PREFIX	"xadd %0,(%2)"
+ 	return tmp+delta;
+ }
+ 
++static inline int rwsem_is_locked(struct rw_semaphore *sem)
++{
++	return (sem->count != 0);
++}
++
+ #endif /* __KERNEL__ */
+ #endif /* _I386_RWSEM_H */
+diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h
+--- a/include/asm-i386/semaphore.h
++++ b/include/asm-i386/semaphore.h
+@@ -55,9 +55,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
+--- a/include/asm-i386/system.h
++++ b/include/asm-i386/system.h
+@@ -167,6 +167,8 @@ struct __xchg_dummy { unsigned long a[10
+ #define __xg(x) ((struct __xchg_dummy *)(x))
+ 
+ 
++#ifdef CONFIG_X86_CMPXCHG64
++
+ /*
+  * The semantics of XCHGCMP8B are a bit strange, this is why
+  * there is a loop and the loading of %%eax and %%edx has to
+@@ -221,6 +223,8 @@ static inline void __set_64bit_var (unsi
+  __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
+  __set_64bit(ptr, ll_low(value), ll_high(value)) )
+ 
++#endif
++
+ /*
+  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+  * Note 2: xchg has side effect, so that attribute volatile is necessary,
+@@ -259,7 +263,6 @@ static inline unsigned long __xchg(unsig
+ 
+ #ifdef CONFIG_X86_CMPXCHG
+ #define __HAVE_ARCH_CMPXCHG 1
+-#endif
+ 
+ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ 				      unsigned long new, int size)
+@@ -275,13 +278,13 @@ static inline unsigned long __cmpxchg(vo
+ 	case 2:
+ 		__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+ 				     : "=a"(prev)
+-				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
++				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ 				     : "memory");
+ 		return prev;
+ 	case 4:
+ 		__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
+ 				     : "=a"(prev)
+-				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
++				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ 				     : "memory");
+ 		return prev;
+ 	}
+@@ -291,6 +294,30 @@ static inline unsigned long __cmpxchg(vo
+ #define cmpxchg(ptr,o,n)\
+ 	((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+ 					(unsigned long)(n),sizeof(*(ptr))))
++
++#endif
++
++#ifdef CONFIG_X86_CMPXCHG64
++
++static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old,
++				      unsigned long long new)
++{
++	unsigned long long prev;
++	__asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
++			     : "=A"(prev)
++			     : "b"((unsigned long)new),
++			       "c"((unsigned long)(new >> 32)),
++			       "m"(*__xg(ptr)),
++			       "0"(old)
++			     : "memory");
++	return prev;
++}
++
++#define cmpxchg64(ptr,o,n)\
++	((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\
++					(unsigned long long)(n)))
++
++#endif
+     
+ #ifdef __KERNEL__
+ struct alt_instr { 
+diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
+--- a/include/asm-i386/unistd.h
++++ b/include/asm-i386/unistd.h
+@@ -448,7 +448,6 @@ asmlinkage int sys_clone(struct pt_regs 
+ asmlinkage int sys_fork(struct pt_regs regs);
+ asmlinkage int sys_vfork(struct pt_regs regs);
+ asmlinkage int sys_pipe(unsigned long __user *fildes);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ asmlinkage long sys_iopl(unsigned long unused);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
+--- a/include/asm-ia64/machvec.h
++++ b/include/asm-ia64/machvec.h
+@@ -26,7 +26,7 @@ typedef void ia64_mv_cpu_init_t (void);
+ typedef void ia64_mv_irq_init_t (void);
+ typedef void ia64_mv_send_ipi_t (int, int, int, int);
+ typedef void ia64_mv_timer_interrupt_t (int, void *, struct pt_regs *);
+-typedef void ia64_mv_global_tlb_purge_t (unsigned long, unsigned long, unsigned long);
++typedef void ia64_mv_global_tlb_purge_t (struct mm_struct *, unsigned long, unsigned long, unsigned long);
+ typedef void ia64_mv_tlb_migrate_finish_t (struct mm_struct *);
+ typedef unsigned int ia64_mv_local_vector_to_irq (u8);
+ typedef char *ia64_mv_pci_get_legacy_mem_t (struct pci_bus *);
+@@ -37,7 +37,7 @@ typedef int ia64_mv_pci_legacy_write_t (
+ 
+ /* DMA-mapping interface: */
+ typedef void ia64_mv_dma_init (void);
+-typedef void *ia64_mv_dma_alloc_coherent (struct device *, size_t, dma_addr_t *, int);
++typedef void *ia64_mv_dma_alloc_coherent (struct device *, size_t, dma_addr_t *, gfp_t);
+ typedef void ia64_mv_dma_free_coherent (struct device *, size_t, void *, dma_addr_t);
+ typedef dma_addr_t ia64_mv_dma_map_single (struct device *, void *, size_t, int);
+ typedef void ia64_mv_dma_unmap_single (struct device *, dma_addr_t, size_t, int);
+diff --git a/include/asm-ia64/machvec_hpzx1.h b/include/asm-ia64/machvec_hpzx1.h
+--- a/include/asm-ia64/machvec_hpzx1.h
++++ b/include/asm-ia64/machvec_hpzx1.h
+@@ -1,8 +1,7 @@
+ #ifndef _ASM_IA64_MACHVEC_HPZX1_h
+ #define _ASM_IA64_MACHVEC_HPZX1_h
+ 
+-extern ia64_mv_setup_t dig_setup;
+-extern ia64_mv_setup_t			sba_setup;
++extern ia64_mv_setup_t			dig_setup;
+ extern ia64_mv_dma_alloc_coherent	sba_alloc_coherent;
+ extern ia64_mv_dma_free_coherent	sba_free_coherent;
+ extern ia64_mv_dma_map_single		sba_map_single;
+@@ -19,15 +18,15 @@ extern ia64_mv_dma_mapping_error	sba_dma
+  * platform's machvec structure.  When compiling a non-generic kernel,
+  * the macros are used directly.
+  */
+-#define platform_name			"hpzx1"
+-#define platform_setup			sba_setup
+-#define platform_dma_init		machvec_noop
+-#define platform_dma_alloc_coherent	sba_alloc_coherent
+-#define platform_dma_free_coherent	sba_free_coherent
+-#define platform_dma_map_single		sba_map_single
+-#define platform_dma_unmap_single	sba_unmap_single
+-#define platform_dma_map_sg		sba_map_sg
+-#define platform_dma_unmap_sg		sba_unmap_sg
++#define platform_name				"hpzx1"
++#define platform_setup				dig_setup
++#define platform_dma_init			machvec_noop
++#define platform_dma_alloc_coherent		sba_alloc_coherent
++#define platform_dma_free_coherent		sba_free_coherent
++#define platform_dma_map_single			sba_map_single
++#define platform_dma_unmap_single		sba_unmap_single
++#define platform_dma_map_sg			sba_map_sg
++#define platform_dma_unmap_sg			sba_unmap_sg
+ #define platform_dma_sync_single_for_cpu	machvec_dma_sync_single
+ #define platform_dma_sync_sg_for_cpu		machvec_dma_sync_sg
+ #define platform_dma_sync_single_for_device	machvec_dma_sync_single
+diff --git a/include/asm-ia64/machvec_hpzx1_swiotlb.h b/include/asm-ia64/machvec_hpzx1_swiotlb.h
+--- a/include/asm-ia64/machvec_hpzx1_swiotlb.h
++++ b/include/asm-ia64/machvec_hpzx1_swiotlb.h
+@@ -2,7 +2,6 @@
+ #define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
+ 
+ extern ia64_mv_setup_t				dig_setup;
+-extern ia64_mv_dma_init				hwsw_init;
+ extern ia64_mv_dma_alloc_coherent		hwsw_alloc_coherent;
+ extern ia64_mv_dma_free_coherent		hwsw_free_coherent;
+ extern ia64_mv_dma_map_single			hwsw_map_single;
+@@ -26,7 +25,7 @@ extern ia64_mv_dma_sync_sg_for_device		h
+ #define platform_name				"hpzx1_swiotlb"
+ 
+ #define platform_setup				dig_setup
+-#define platform_dma_init			hwsw_init
++#define platform_dma_init			machvec_noop
+ #define platform_dma_alloc_coherent		hwsw_alloc_coherent
+ #define platform_dma_free_coherent		hwsw_free_coherent
+ #define platform_dma_map_single			hwsw_map_single
+diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
+--- a/include/asm-ia64/meminit.h
++++ b/include/asm-ia64/meminit.h
+@@ -16,10 +16,11 @@
+  * 	- initrd (optional)
+  * 	- command line string
+  * 	- kernel code & data
++ * 	- Kernel memory map built from EFI memory map
+  *
+  * More could be added if necessary
+  */
+-#define IA64_MAX_RSVD_REGIONS 5
++#define IA64_MAX_RSVD_REGIONS 6
+ 
+ struct rsvd_region {
+ 	unsigned long start;	/* virtual address of beginning of element */
+@@ -33,6 +34,7 @@ extern void find_memory (void);
+ extern void reserve_memory (void);
+ extern void find_initrd (void);
+ extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
++extern void efi_memmap_init(unsigned long *, unsigned long *);
+ 
+ /*
+  * For rounding an address to the next IA64_GRANULE_SIZE or order
+@@ -41,7 +43,7 @@ extern int filter_rsvd_memory (unsigned 
+ #define GRANULEROUNDUP(n)	(((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
+ #define ORDERROUNDDOWN(n)	((n) & ~((PAGE_SIZE<<MAX_ORDER)-1))
+ 
+-#ifdef CONFIG_DISCONTIGMEM
++#ifdef CONFIG_NUMA
+   extern void call_pernode_memory (unsigned long start, unsigned long len, void *func);
+ #else
+ # define call_pernode_memory(start, len, func)	(*func)(start, len, 0)
+diff --git a/include/asm-ia64/mmzone.h b/include/asm-ia64/mmzone.h
+--- a/include/asm-ia64/mmzone.h
++++ b/include/asm-ia64/mmzone.h
+@@ -15,7 +15,7 @@
+ #include <asm/page.h>
+ #include <asm/meminit.h>
+ 
+-#ifdef CONFIG_DISCONTIGMEM
++#ifdef CONFIG_NUMA
+ 
+ static inline int pfn_to_nid(unsigned long pfn)
+ {
+@@ -31,6 +31,10 @@ static inline int pfn_to_nid(unsigned lo
+ #endif
+ }
+ 
++#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
++extern int early_pfn_to_nid(unsigned long pfn);
++#endif
++
+ #ifdef CONFIG_IA64_DIG /* DIG systems are small */
+ # define MAX_PHYSNODE_ID	8
+ # define NR_NODE_MEMBLKS	(MAX_NUMNODES * 8)
+@@ -39,8 +43,8 @@ static inline int pfn_to_nid(unsigned lo
+ # define NR_NODE_MEMBLKS	(MAX_NUMNODES * 4)
+ #endif
+ 
+-#else /* CONFIG_DISCONTIGMEM */
++#else /* CONFIG_NUMA */
+ # define NR_NODE_MEMBLKS	(MAX_NUMNODES * 4)
+-#endif /* CONFIG_DISCONTIGMEM */
++#endif /* CONFIG_NUMA */
+ 
+ #endif /* _ASM_IA64_MMZONE_H */
+diff --git a/include/asm-ia64/nodedata.h b/include/asm-ia64/nodedata.h
+--- a/include/asm-ia64/nodedata.h
++++ b/include/asm-ia64/nodedata.h
+@@ -17,7 +17,7 @@
+ #include <asm/percpu.h>
+ #include <asm/mmzone.h>
+ 
+-#ifdef CONFIG_DISCONTIGMEM
++#ifdef CONFIG_NUMA
+ 
+ /*
+  * Node Data. One of these structures is located on each node of a NUMA system.
+@@ -47,6 +47,6 @@ struct ia64_node_data {
+  */
+ #define NODE_DATA(nid)		(local_node_data->pg_data_ptrs[nid])
+ 
+-#endif /* CONFIG_DISCONTIGMEM */
++#endif /* CONFIG_NUMA */
+ 
+ #endif /* _ASM_IA64_NODEDATA_H */
+diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h
+--- a/include/asm-ia64/page.h
++++ b/include/asm-ia64/page.h
+@@ -102,15 +102,15 @@ do {						\
+ 
+ #ifdef CONFIG_VIRTUAL_MEM_MAP
+ extern int ia64_pfn_valid (unsigned long pfn);
+-#else
++#elif defined(CONFIG_FLATMEM)
+ # define ia64_pfn_valid(pfn) 1
+ #endif
+ 
+-#ifndef CONFIG_DISCONTIGMEM
++#ifdef CONFIG_FLATMEM
+ # define pfn_valid(pfn)		(((pfn) < max_mapnr) && ia64_pfn_valid(pfn))
+ # define page_to_pfn(page)	((unsigned long) (page - mem_map))
+ # define pfn_to_page(pfn)	(mem_map + (pfn))
+-#else
++#elif defined(CONFIG_DISCONTIGMEM)
+ extern struct page *vmem_map;
+ extern unsigned long max_low_pfn;
+ # define pfn_valid(pfn)		(((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
+diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
+--- a/include/asm-ia64/pgtable.h
++++ b/include/asm-ia64/pgtable.h
+@@ -236,9 +236,6 @@ ia64_phys_addr_valid (unsigned long addr
+ #define pte_modify(_pte, newprot) \
+ 	(__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
+ 
+-#define page_pte_prot(page,prot)	mk_pte(page, prot)
+-#define page_pte(page)			page_pte_prot(page, __pgprot(0))
+-
+ #define pte_none(pte) 			(!pte_val(pte))
+ #define pte_present(pte)		(pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
+ #define pte_clear(mm,addr,pte)		(pte_val(*(pte)) = 0UL)
+diff --git a/include/asm-ia64/rwsem.h b/include/asm-ia64/rwsem.h
+--- a/include/asm-ia64/rwsem.h
++++ b/include/asm-ia64/rwsem.h
+@@ -186,4 +186,9 @@ __downgrade_write (struct rw_semaphore *
+ #define rwsem_atomic_add(delta, sem)	atomic64_add(delta, (atomic64_t *)(&(sem)->count))
+ #define rwsem_atomic_update(delta, sem)	atomic64_add_return(delta, (atomic64_t *)(&(sem)->count))
+ 
++static inline int rwsem_is_locked(struct rw_semaphore *sem)
++{
++	return (sem->count != 0);
++}
++
+ #endif /* _ASM_IA64_RWSEM_H */
+diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h
+--- a/include/asm-ia64/semaphore.h
++++ b/include/asm-ia64/semaphore.h
+@@ -24,8 +24,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name)	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count)					\
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name, count)
+ 
+diff --git a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h
+--- a/include/asm-ia64/sn/arch.h
++++ b/include/asm-ia64/sn/arch.h
+@@ -18,6 +18,32 @@
+ #include <asm/sn/sn_cpuid.h>
+ 
+ /*
++ * This is the maximum number of NUMALINK nodes that can be part of a single
++ * SSI kernel. This number includes C-brick, M-bricks, and TIOs. Nodes in
++ * remote partitions are NOT included in this number.
++ * The number of compact nodes cannot exceed size of a coherency domain.
++ * The purpose of this define is to specify a node count that includes
++ * all C/M/TIO nodes in an SSI system.
++ *
++ * SGI system can currently support up to 256 C/M nodes plus additional TIO nodes.
++ *
++ * 	Note: ACPI20 has an architectural limit of 256 nodes. When we upgrade
++ * 	to ACPI3.0, this limit will be removed. The notion of "compact nodes"
++ * 	should be deleted and TIOs should be included in MAX_NUMNODES.
++ */
++#define MAX_COMPACT_NODES	512
++
++/*
++ * Maximum number of nodes in all partitions and in all coherency domains.
++ * This is the total number of nodes accessible in the numalink fabric. It
++ * includes all C & M bricks, plus all TIOs.
++ *
++ * This value is also the value of the maximum number of NASIDs in the numalink
++ * fabric.
++ */
++#define MAX_NUMALINK_NODES	16384
++
++/*
+  * The following defines attributes of the HUB chip. These attributes are
+  * frequently referenced. They are kept in the per-cpu data areas of each cpu.
+  * They are kept together in a struct to minimize cache misses.
+@@ -41,15 +67,6 @@ DECLARE_PER_CPU(struct sn_hub_info_s, __
+ 
+ 
+ /*
+- * This is the maximum number of nodes that can be part of a kernel.
+- * Effectively, it's the maximum number of compact node ids (cnodeid_t).
+- * This is not necessarily the same as MAX_NASIDS.
+- */
+-#define MAX_COMPACT_NODES	2048
+-#define CPUS_PER_NODE		4
+-
+-
+-/*
+  * Compact node ID to nasid mappings kept in the per-cpu data areas of each
+  * cpu.
+  */
+@@ -57,7 +74,6 @@ DECLARE_PER_CPU(short, __sn_cnodeid_to_n
+ #define sn_cnodeid_to_nasid	(&__get_cpu_var(__sn_cnodeid_to_nasid[0]))
+ 
+ 
+-
+ extern u8 sn_partition_id;
+ extern u8 sn_system_size;
+ extern u8 sn_sharing_domain_size;
+diff --git a/include/asm-ia64/sn/io.h b/include/asm-ia64/sn/io.h
+--- a/include/asm-ia64/sn/io.h
++++ b/include/asm-ia64/sn/io.h
+@@ -14,7 +14,7 @@
+ extern void * sn_io_addr(unsigned long port) __attribute_const__; /* Forward definition */
+ extern void __sn_mmiowb(void); /* Forward definition */
+ 
+-extern int numionodes;
++extern int num_cnodes;
+ 
+ #define __sn_mf_a()   ia64_mfa()
+ 
+@@ -36,6 +36,15 @@ extern void sn_dma_flush(unsigned long);
+ #define __sn_readq_relaxed ___sn_readq_relaxed
+ 
+ /*
++ * Convenience macros for setting/clearing bits using the above accessors
++ */
++
++#define __sn_setq_relaxed(addr, val) \
++	writeq((__sn_readq_relaxed(addr) | (val)), (addr))
++#define __sn_clrq_relaxed(addr, val) \
++	writeq((__sn_readq_relaxed(addr) & ~(val)), (addr))
++
++/*
+  * The following routines are SN Platform specific, called when
+  * a reference is made to inX/outX set macros.  SN Platform
+  * inX set of macros ensures that Posted DMA writes on the
+diff --git a/include/asm-ia64/sn/klconfig.h b/include/asm-ia64/sn/klconfig.h
+--- a/include/asm-ia64/sn/klconfig.h
++++ b/include/asm-ia64/sn/klconfig.h
+@@ -208,19 +208,6 @@ typedef struct lboard_s {
+ 	klconf_off_t	brd_next_same;    /* Next BOARD with same nasid */
+ } lboard_t;
+ 
+-#define KLCF_NUM_COMPS(_brd)	((_brd)->brd_numcompts)
+-#define NODE_OFFSET_TO_KLINFO(n,off)    ((klinfo_t*) TO_NODE_CAC(n,off))
+-#define KLCF_NEXT(_brd)         \
+-        ((_brd)->brd_next_same ?     \
+-         (NODE_OFFSET_TO_LBOARD((_brd)->brd_next_same_host, (_brd)->brd_next_same)): NULL)
+-#define KLCF_NEXT_ANY(_brd)         \
+-        ((_brd)->brd_next_any ?     \
+-         (NODE_OFFSET_TO_LBOARD(NASID_GET(_brd), (_brd)->brd_next_any)): NULL)
+-#define KLCF_COMP(_brd, _ndx)   \
+-                ((((_brd)->brd_compts[(_ndx)]) == 0) ? 0 : \
+-			(NODE_OFFSET_TO_KLINFO(NASID_GET(_brd), (_brd)->brd_compts[(_ndx)])))
+-
+-
+ /*
+  * Generic info structure. This stores common info about a 
+  * component.
+@@ -249,24 +236,11 @@ typedef struct klinfo_s {               
+ } klinfo_t ;
+ 
+ 
+-static inline lboard_t *find_lboard_any(lboard_t * start, unsigned char brd_type)
++static inline lboard_t *find_lboard_next(lboard_t * brd)
+ {
+-        /* Search all boards stored on this node. */
+-
+-        while (start) {
+-                if (start->brd_type == brd_type)
+-                        return start;
+-                start = KLCF_NEXT_ANY(start);
+-        }
+-        /* Didn't find it. */
+-        return (lboard_t *) NULL;
++	if (brd && brd->brd_next_any)
++		return NODE_OFFSET_TO_LBOARD(NASID_GET(brd), brd->brd_next_any);
++        return NULL;
+ }
+ 
+-
+-/* external declarations of Linux kernel functions. */
+-
+-extern lboard_t *root_lboard[];
+-extern klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char type);
+-extern klinfo_t *find_first_component(lboard_t *brd, unsigned char type);
+-
+ #endif /* _ASM_IA64_SN_KLCONFIG_H */
+diff --git a/include/asm-ia64/sn/l1.h b/include/asm-ia64/sn/l1.h
+--- a/include/asm-ia64/sn/l1.h
++++ b/include/asm-ia64/sn/l1.h
+@@ -35,4 +35,16 @@
+ #define L1_BRICKTYPE_ATHENA	0x2b            /* + */
+ #define L1_BRICKTYPE_DAYTONA	0x7a            /* z */
+ 
++/* board type response codes */
++#define L1_BOARDTYPE_IP69       0x0100          /* CA */
++#define L1_BOARDTYPE_IP63       0x0200          /* CB */
++#define L1_BOARDTYPE_BASEIO     0x0300          /* IB */
++#define L1_BOARDTYPE_PCIE2SLOT  0x0400          /* IC */
++#define L1_BOARDTYPE_PCIX3SLOT  0x0500          /* ID */
++#define L1_BOARDTYPE_PCIXPCIE4SLOT 0x0600       /* IE */
++#define L1_BOARDTYPE_ABACUS     0x0700          /* AB */
++#define L1_BOARDTYPE_DAYTONA    0x0800          /* AD */
++#define L1_BOARDTYPE_INVAL      (-1)            /* invalid brick type */
++
++
+ #endif /* _ASM_IA64_SN_L1_H */
+diff --git a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h
+--- a/include/asm-ia64/sn/nodepda.h
++++ b/include/asm-ia64/sn/nodepda.h
+@@ -55,7 +55,6 @@ struct nodepda_s {
+ 	 */
+ 	struct phys_cpuid	phys_cpuid[NR_CPUS];
+ 	spinlock_t		ptc_lock ____cacheline_aligned_in_smp;
+-	spinlock_t		bist_lock;
+ };
+ 
+ typedef struct nodepda_s nodepda_t;
+diff --git a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
+--- a/include/asm-ia64/sn/sn_cpuid.h
++++ b/include/asm-ia64/sn/sn_cpuid.h
+@@ -105,7 +105,6 @@ extern short physical_node_map[];	/* ind
+ #define cpuid_to_nasid(cpuid)		(sn_nodepda->phys_cpuid[cpuid].nasid)
+ #define cpuid_to_subnode(cpuid)		(sn_nodepda->phys_cpuid[cpuid].subnode)
+ #define cpuid_to_slice(cpuid)		(sn_nodepda->phys_cpuid[cpuid].slice)
+-#define cpuid_to_cnodeid(cpuid)		(physical_node_map[cpuid_to_nasid(cpuid)])
+ 
+ 
+ /*
+@@ -113,8 +112,6 @@ extern short physical_node_map[];	/* ind
+  * of potentially large tables.
+  */
+ extern int nasid_slice_to_cpuid(int, int);
+-#define nasid_slice_to_cpu_physical_id(nasid, slice)			\
+-	cpu_physical_id(nasid_slice_to_cpuid(nasid, slice))
+ 
+ /*
+  * cnodeid_to_nasid - convert a cnodeid to a NASID
+diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
+--- a/include/asm-ia64/sn/sn_sal.h
++++ b/include/asm-ia64/sn/sn_sal.h
+@@ -47,6 +47,7 @@
+ #define  SN_SAL_CONSOLE_PUTB			   0x02000028
+ #define  SN_SAL_CONSOLE_XMIT_CHARS		   0x0200002a
+ #define  SN_SAL_CONSOLE_READC			   0x0200002b
++#define  SN_SAL_SYSCTL_OP			   0x02000030
+ #define  SN_SAL_SYSCTL_MODID_GET	           0x02000031
+ #define  SN_SAL_SYSCTL_GET                         0x02000032
+ #define  SN_SAL_SYSCTL_IOBRICK_MODULE_GET          0x02000033
+@@ -67,7 +68,7 @@
+ #define  SN_SAL_IOIF_INTERRUPT			   0x0200004a
+ #define  SN_SAL_HWPERF_OP			   0x02000050   // lock
+ #define  SN_SAL_IOIF_ERROR_INTERRUPT		   0x02000051
+-
++#define  SN_SAL_IOIF_PCI_SAFE			   0x02000052
+ #define  SN_SAL_IOIF_SLOT_ENABLE		   0x02000053
+ #define  SN_SAL_IOIF_SLOT_DISABLE		   0x02000054
+ #define  SN_SAL_IOIF_GET_HUBDEV_INFO		   0x02000055
+@@ -101,6 +102,13 @@
+ #define SAL_INTR_FREE		2
+ 
+ /*
++ * operations available on the generic SN_SAL_SYSCTL_OP
++ * runtime service
++ */
++#define SAL_SYSCTL_OP_IOBOARD		0x0001  /*  retrieve board type */
++#define SAL_SYSCTL_OP_TIO_JLCK_RST      0x0002  /* issue TIO clock reset */
++
++/*
+  * IRouter (i.e. generalized system controller) operations
+  */
+ #define SAL_IROUTER_OPEN	0	/* open a subchannel */
+@@ -198,26 +206,16 @@ ia64_sn_get_master_baseio_nasid(void)
+ 	return ret_stuff.v0;
+ }
+ 
+-static inline char *
++static inline void *
+ ia64_sn_get_klconfig_addr(nasid_t nasid)
+ {
+ 	struct ia64_sal_retval ret_stuff;
+-	int cnodeid;
+ 
+-	cnodeid = nasid_to_cnodeid(nasid);
+ 	ret_stuff.status = 0;
+ 	ret_stuff.v0 = 0;
+ 	ret_stuff.v1 = 0;
+ 	ret_stuff.v2 = 0;
+ 	SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
+-
+-	/*
+-	 * We should panic if a valid cnode nasid does not produce
+-	 * a klconfig address.
+-	 */
+-	if (ret_stuff.status != 0) {
+-		panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status);
+-	}
+ 	return ret_stuff.v0 ? __va(ret_stuff.v0) : NULL;
+ }
+ 
+@@ -694,12 +692,10 @@ sn_change_memprotect(u64 paddr, u64 len,
+ 	unsigned long irq_flags;
+ 
+ 	cnodeid = nasid_to_cnodeid(get_node_number(paddr));
+-	// spin_lock(&NODEPDA(cnodeid)->bist_lock);
+ 	local_irq_save(irq_flags);
+ 	ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len,
+ 				(u64)nasid_array, perms, 0, 0, 0);
+ 	local_irq_restore(irq_flags);
+-	// spin_unlock(&NODEPDA(cnodeid)->bist_lock);
+ 	return ret_stuff.status;
+ }
+ #define SN_MEMPROT_ACCESS_CLASS_0		0x14a080
+@@ -873,6 +869,41 @@ ia64_sn_sysctl_event_init(nasid_t nasid)
+         return (int) rv.v0;
+ }
+ 
++/*
++ * Ask the system controller on the specified nasid to reset
++ * the CX corelet clock.  Only valid on TIO nodes.
++ */
++static inline int
++ia64_sn_sysctl_tio_clock_reset(nasid_t nasid)
++{
++	struct ia64_sal_retval rv;
++	SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_TIO_JLCK_RST,
++			nasid, 0, 0, 0, 0, 0);
++	if (rv.status != 0)
++		return (int)rv.status;
++	if (rv.v0 != 0)
++		return (int)rv.v0;
++
++	return 0;
++}
++
++/*
++ * Get the associated ioboard type for a given nasid.
++ */
++static inline int
++ia64_sn_sysctl_ioboard_get(nasid_t nasid)
++{
++        struct ia64_sal_retval rv;
++        SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_IOBOARD,
++                        nasid, 0, 0, 0, 0, 0);
++        if (rv.v0 != 0)
++                return (int)rv.v0;
++        if (rv.v1 != 0)
++                return (int)rv.v1;
++
++        return 0;
++}
++
+ /**
+  * ia64_sn_get_fit_compt - read a FIT entry from the PROM header
+  * @nasid: NASID of node to read
+diff --git a/include/asm-ia64/sn/tioca_provider.h b/include/asm-ia64/sn/tioca_provider.h
+--- a/include/asm-ia64/sn/tioca_provider.h
++++ b/include/asm-ia64/sn/tioca_provider.h
+@@ -182,11 +182,11 @@ tioca_tlbflush(struct tioca_kernel *tioc
+ 			 * touch every CL aligned GART entry.
+ 			 */
+ 
+-			ca_base->ca_control2 &= ~(CA_GART_MEM_PARAM);
+-			ca_base->ca_control2 |= CA_GART_FLUSH_TLB;
+-			ca_base->ca_control2 |=
+-			    (0x2ull << CA_GART_MEM_PARAM_SHFT);
+-			tmp = ca_base->ca_control2;
++			__sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
++			__sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
++			__sn_setq_relaxed(&ca_base->ca_control2,
++			    (0x2ull << CA_GART_MEM_PARAM_SHFT));
++			tmp = __sn_readq_relaxed(&ca_base->ca_control2);
+ 		}
+ 
+ 		return;
+@@ -196,8 +196,8 @@ tioca_tlbflush(struct tioca_kernel *tioc
+ 	 * Gart in uncached mode ... need an explicit flush.
+ 	 */
+ 
+-	ca_base->ca_control2 |= CA_GART_FLUSH_TLB;
+-	tmp = ca_base->ca_control2;
++	__sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
++	tmp = __sn_readq_relaxed(&ca_base->ca_control2);
+ }
+ 
+ extern uint32_t	tioca_gart_found;
+diff --git a/include/asm-ia64/sn/tiocx.h b/include/asm-ia64/sn/tiocx.h
+--- a/include/asm-ia64/sn/tiocx.h
++++ b/include/asm-ia64/sn/tiocx.h
+@@ -19,6 +19,7 @@ struct cx_id_s {
+ 
+ struct cx_dev {
+ 	struct cx_id_s cx_id;
++	int bt;				/* board/blade type */
+ 	void *soft;			/* driver specific */
+ 	struct hubdev_info *hubdev;
+ 	struct device dev;
+@@ -59,7 +60,7 @@ struct cx_drv {
+ extern struct sn_irq_info *tiocx_irq_alloc(nasid_t, int, int, nasid_t, int);
+ extern void tiocx_irq_free(struct sn_irq_info *);
+ extern int cx_device_unregister(struct cx_dev *);
+-extern int cx_device_register(nasid_t, int, int, struct hubdev_info *);
++extern int cx_device_register(nasid_t, int, int, struct hubdev_info *, int);
+ extern int cx_driver_unregister(struct cx_drv *);
+ extern int cx_driver_register(struct cx_drv *);
+ extern uint64_t tiocx_dma_addr(uint64_t addr);
+diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h
+--- a/include/asm-ia64/sn/xp.h
++++ b/include/asm-ia64/sn/xp.h
+@@ -49,7 +49,7 @@
+  * C-brick nasids, thus the need for bitmaps which don't account for
+  * odd-numbered (non C-brick) nasids.
+  */
+-#define XP_MAX_PHYSNODE_ID	(MAX_PHYSNODE_ID / 2)
++#define XP_MAX_PHYSNODE_ID	(MAX_NUMALINK_NODES / 2)
+ #define XP_NASID_MASK_BYTES	((XP_MAX_PHYSNODE_ID + 7) / 8)
+ #define XP_NASID_MASK_WORDS	((XP_MAX_PHYSNODE_ID + 63) / 64)
+ 
+@@ -217,7 +217,17 @@ enum xpc_retval {
+ 	xpcInvalidPartid,	/* 42: invalid partition ID */
+ 	xpcLocalPartid,		/* 43: local partition ID */
+ 
+-	xpcUnknownReason	/* 44: unknown reason -- must be last in list */
++	xpcOtherGoingDown,	/* 44: other side going down, reason unknown */
++	xpcSystemGoingDown,	/* 45: system is going down, reason unknown */
++	xpcSystemHalt,		/* 46: system is being halted */
++	xpcSystemReboot,	/* 47: system is being rebooted */
++	xpcSystemPoweroff,	/* 48: system is being powered off */
++
++	xpcDisconnecting,	/* 49: channel disconnecting (closing) */
++
++	xpcOpenCloseError,	/* 50: channel open/close protocol error */
++
++	xpcUnknownReason	/* 51: unknown reason -- must be last in list */
+ };
+ 
+ 
+@@ -342,7 +352,7 @@ typedef void (*xpc_notify_func)(enum xpc
+  *
+  * The 'func' field points to the function to call when aynchronous
+  * notification is required for such events as: a connection established/lost,
+- * or an incomming message received, or an error condition encountered. A
++ * or an incoming message received, or an error condition encountered. A
+  * non-NULL 'func' field indicates that there is an active registration for
+  * the channel.
+  */
+diff --git a/include/asm-ia64/sparsemem.h b/include/asm-ia64/sparsemem.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-ia64/sparsemem.h
+@@ -0,0 +1,20 @@
++#ifndef _ASM_IA64_SPARSEMEM_H
++#define _ASM_IA64_SPARSEMEM_H
++
++#ifdef CONFIG_SPARSEMEM
++/*
++ * SECTION_SIZE_BITS            2^N: how big each section will be
++ * MAX_PHYSMEM_BITS             2^N: how much memory we can have in that space
++ */
++
++#define SECTION_SIZE_BITS	(30)
++#define MAX_PHYSMEM_BITS	(50)
++#ifdef CONFIG_FORCE_MAX_ZONEORDER
++#if ((CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS)
++#undef SECTION_SIZE_BITS
++#define SECTION_SIZE_BITS (CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT)
++#endif
++#endif
++
++#endif /* CONFIG_SPARSEMEM */
++#endif /* _ASM_IA64_SPARSEMEM_H */
+diff --git a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h
+--- a/include/asm-ia64/tlb.h
++++ b/include/asm-ia64/tlb.h
+@@ -60,7 +60,6 @@ struct mmu_gather {
+ 	unsigned int		nr;		/* == ~0U => fast mode */
+ 	unsigned char		fullmm;		/* non-zero means full mm flush */
+ 	unsigned char		need_flush;	/* really unmapped some PTEs? */
+-	unsigned long		freed;		/* number of pages freed */
+ 	unsigned long		start_addr;
+ 	unsigned long		end_addr;
+ 	struct page 		*pages[FREE_PTE_NR];
+@@ -129,7 +128,7 @@ ia64_tlb_flush_mmu (struct mmu_gather *t
+ static inline struct mmu_gather *
+ tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush)
+ {
+-	struct mmu_gather *tlb = &__get_cpu_var(mmu_gathers);
++	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+ 
+ 	tlb->mm = mm;
+ 	/*
+@@ -147,25 +146,17 @@ tlb_gather_mmu (struct mm_struct *mm, un
+ 	 */
+ 	tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
+ 	tlb->fullmm = full_mm_flush;
+-	tlb->freed = 0;
+ 	tlb->start_addr = ~0UL;
+ 	return tlb;
+ }
+ 
+ /*
+  * Called at the end of the shootdown operation to free up any resources that were
+- * collected.  The page table lock is still held at this point.
++ * collected.
+  */
+ static inline void
+ tlb_finish_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
+ {
+-	unsigned long freed = tlb->freed;
+-	struct mm_struct *mm = tlb->mm;
+-	unsigned long rss = get_mm_counter(mm, rss);
+-
+-	if (rss < freed)
+-		freed = rss;
+-	add_mm_counter(mm, rss, -freed);
+ 	/*
+ 	 * Note: tlb->nr may be 0 at this point, so we can't rely on tlb->start_addr and
+ 	 * tlb->end_addr.
+@@ -174,12 +165,8 @@ tlb_finish_mmu (struct mmu_gather *tlb, 
+ 
+ 	/* keep the page table cache within bounds */
+ 	check_pgt_cache();
+-}
+ 
+-static inline unsigned int
+-tlb_is_full_mm(struct mmu_gather *tlb)
+-{
+-     return tlb->fullmm;
++	put_cpu_var(mmu_gathers);
+ }
+ 
+ /*
+diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
+--- a/include/asm-ia64/unistd.h
++++ b/include/asm-ia64/unistd.h
+@@ -383,8 +383,6 @@ struct sigaction;
+ long sys_execve(char __user *filename, char __user * __user *argv,
+ 			   char __user * __user *envp, struct pt_regs *regs);
+ asmlinkage long sys_pipe(void);
+-asmlinkage long sys_ptrace(long request, pid_t pid,
+-			   unsigned long addr, unsigned long data);
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				 const struct sigaction __user *act,
+ 				 struct sigaction __user *oact,
+diff --git a/include/asm-m32r/dma-mapping.h b/include/asm-m32r/dma-mapping.h
+--- a/include/asm-m32r/dma-mapping.h
++++ b/include/asm-m32r/dma-mapping.h
+@@ -8,7 +8,7 @@
+ 
+ static inline void *
+ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+-		   int flag)
++		   gfp_t flag)
+ {
+ 	return (void *)NULL;
+ }
+diff --git a/include/asm-m32r/mmzone.h b/include/asm-m32r/mmzone.h
+--- a/include/asm-m32r/mmzone.h
++++ b/include/asm-m32r/mmzone.h
+@@ -21,12 +21,6 @@ extern struct pglist_data *node_data[];
+ 	__pgdat->node_start_pfn + __pgdat->node_spanned_pages - 1;	\
+ })
+ 
+-#define local_mapnr(kvaddr)						\
+-({									\
+-	unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT;		\
+-	(__pfn - node_start_pfn(pfn_to_nid(__pfn)));			\
+-})
+-
+ #define pfn_to_page(pfn)						\
+ ({									\
+ 	unsigned long __pfn = pfn;					\
+diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
+--- a/include/asm-m32r/pgtable.h
++++ b/include/asm-m32r/pgtable.h
+@@ -324,8 +324,6 @@ static inline pte_t pte_modify(pte_t pte
+ 	return pte;
+ }
+ 
+-#define page_pte(page)	page_pte_prot(page, __pgprot(0))
+-
+ /*
+  * Conversion functions: convert a page and protection to a page entry,
+  * and a page entry and page directory to the page they refer to.
+diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h
+--- a/include/asm-m32r/semaphore.h
++++ b/include/asm-m32r/semaphore.h
+@@ -32,9 +32,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
+--- a/include/asm-m32r/thread_info.h
++++ b/include/asm-m32r/thread_info.h
+@@ -95,7 +95,7 @@ static inline struct thread_info *curren
+ }
+ 
+ /* thread information allocation */
+-#if CONFIG_DEBUG_STACK_USAGE
++#ifdef CONFIG_DEBUG_STACK_USAGE
+ #define alloc_thread_info(tsk)					\
+ 	({							\
+ 		struct thread_info *ret;			\
+diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
+--- a/include/asm-m32r/unistd.h
++++ b/include/asm-m32r/unistd.h
+@@ -452,7 +452,6 @@ asmlinkage int sys_clone(struct pt_regs 
+ asmlinkage int sys_fork(struct pt_regs regs);
+ asmlinkage int sys_vfork(struct pt_regs regs);
+ asmlinkage int sys_pipe(unsigned long __user *fildes);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				 const struct sigaction __user *act,
+diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h
+--- a/include/asm-m68k/semaphore.h
++++ b/include/asm-m68k/semaphore.h
+@@ -36,9 +36,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-m68k/sun3xflop.h b/include/asm-m68k/sun3xflop.h
+--- a/include/asm-m68k/sun3xflop.h
++++ b/include/asm-m68k/sun3xflop.h
+@@ -27,10 +27,8 @@
+ 
+ /* We don't need no stinkin' I/O port allocation crap. */
+ #undef release_region
+-#undef check_region
+ #undef request_region
+ #define release_region(X, Y)	do { } while(0)
+-#define check_region(X, Y)	(0)
+ #define request_region(X, Y, Z)	(1)
+ 
+ struct sun3xflop_private {
+diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
+--- a/include/asm-m68k/unistd.h
++++ b/include/asm-m68k/unistd.h
+@@ -444,7 +444,6 @@ asmlinkage long sys_mmap2(
+ 			unsigned long fd, unsigned long pgoff);
+ asmlinkage int sys_execve(char *name, char **argv, char **envp);
+ asmlinkage int sys_pipe(unsigned long *fildes);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ struct pt_regs;
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+diff --git a/include/asm-m68knommu/anchor.h b/include/asm-m68knommu/anchor.h
+--- a/include/asm-m68knommu/anchor.h
++++ b/include/asm-m68knommu/anchor.h
+@@ -14,7 +14,7 @@
+ /*
+  *	Define basic addressing info.
+  */
+-#if defined(CONFIG_MOTOROLA) && defined(CONFIG_M5407)
++#if defined(CONFIG_M5407C3)
+ #define	COMEM_BASE	0xFFFF0000	/* Base of CO-MEM address space */
+ #define	COMEM_IRQ	25		/* IRQ of anchor part */
+ #else
+@@ -96,7 +96,7 @@
+  *	The PCI bus will be limited in what slots will actually be used.
+  *	Define valid device numbers for different boards.
+  */
+-#if defined(CONFIG_MOTOROLA) && defined(CONFIG_M5407)
++#if defined(CONFIG_M5407C3)
+ #define	COMEM_MINDEV	14		/* Minimum valid DEVICE */
+ #define	COMEM_MAXDEV	14		/* Maximum valid DEVICE */
+ #define	COMEM_BRIDGEDEV	15		/* Slot bridge is in */
+diff --git a/include/asm-m68knommu/asm-offsets.h b/include/asm-m68knommu/asm-offsets.h
+deleted file mode 100644
+--- a/include/asm-m68knommu/asm-offsets.h
++++ /dev/null
+@@ -1,49 +0,0 @@
+-#ifndef __ASM_OFFSETS_H__
+-#define __ASM_OFFSETS_H__
+-/*
+- * DO NOT MODIFY.
+- *
+- * This file was generated by arch/m68knommu/Makefile
+- *
+- */
+-
+-#define TASK_STATE 0 /* offsetof(struct task_struct, state) */
+-#define TASK_FLAGS 12 /* offsetof(struct task_struct, flags) */
+-#define TASK_PTRACE 16 /* offsetof(struct task_struct, ptrace) */
+-#define TASK_BLOCKED 922 /* offsetof(struct task_struct, blocked) */
+-#define TASK_THREAD 772 /* offsetof(struct task_struct, thread) */
+-#define TASK_THREAD_INFO 4 /* offsetof(struct task_struct, thread_info) */
+-#define TASK_MM 92 /* offsetof(struct task_struct, mm) */
+-#define TASK_ACTIVE_MM 96 /* offsetof(struct task_struct, active_mm) */
+-#define CPUSTAT_SOFTIRQ_PENDING 0 /* offsetof(irq_cpustat_t, __softirq_pending) */
+-#define THREAD_KSP 0 /* offsetof(struct thread_struct, ksp) */
+-#define THREAD_USP 4 /* offsetof(struct thread_struct, usp) */
+-#define THREAD_SR 8 /* offsetof(struct thread_struct, sr) */
+-#define THREAD_FS 10 /* offsetof(struct thread_struct, fs) */
+-#define THREAD_CRP 12 /* offsetof(struct thread_struct, crp) */
+-#define THREAD_ESP0 20 /* offsetof(struct thread_struct, esp0) */
+-#define THREAD_FPREG 24 /* offsetof(struct thread_struct, fp) */
+-#define THREAD_FPCNTL 120 /* offsetof(struct thread_struct, fpcntl) */
+-#define THREAD_FPSTATE 132 /* offsetof(struct thread_struct, fpstate) */
+-#define PT_D0 32 /* offsetof(struct pt_regs, d0) */
+-#define PT_ORIG_D0 36 /* offsetof(struct pt_regs, orig_d0) */
+-#define PT_D1 0 /* offsetof(struct pt_regs, d1) */
+-#define PT_D2 4 /* offsetof(struct pt_regs, d2) */
+-#define PT_D3 8 /* offsetof(struct pt_regs, d3) */
+-#define PT_D4 12 /* offsetof(struct pt_regs, d4) */
+-#define PT_D5 16 /* offsetof(struct pt_regs, d5) */
+-#define PT_A0 20 /* offsetof(struct pt_regs, a0) */
+-#define PT_A1 24 /* offsetof(struct pt_regs, a1) */
+-#define PT_A2 28 /* offsetof(struct pt_regs, a2) */
+-#define PT_PC 48 /* offsetof(struct pt_regs, pc) */
+-#define PT_SR 46 /* offsetof(struct pt_regs, sr) */
+-#define PT_VECTOR 52 /* offsetof(struct pt_regs, pc) + 4 */
+-#define STAT_IRQ 5140 /* offsetof(struct kernel_stat, irqs) */
+-#define SIGSEGV 11 /* SIGSEGV */
+-#define SEGV_MAPERR 196609 /* SEGV_MAPERR */
+-#define SIGTRAP 5 /* SIGTRAP */
+-#define TRAP_TRACE 196610 /* TRAP_TRACE */
+-#define PT_PTRACED 1 /* PT_PTRACED */
+-#define PT_DTRACE 2 /* PT_DTRACE */
+-
+-#endif
+diff --git a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h
+--- a/include/asm-m68knommu/atomic.h
++++ b/include/asm-m68knommu/atomic.h
+@@ -100,7 +100,7 @@ static __inline__ void atomic_set_mask(u
+ #define smp_mb__before_atomic_inc()    barrier()
+ #define smp_mb__after_atomic_inc() barrier()
+ 
+-extern __inline__ int atomic_add_return(int i, atomic_t * v)
++static inline int atomic_add_return(int i, atomic_t * v)
+ {
+ 	unsigned long temp, flags;
+ 
+@@ -115,7 +115,7 @@ extern __inline__ int atomic_add_return(
+ 
+ #define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
+ 
+-extern __inline__ int atomic_sub_return(int i, atomic_t * v)
++static inline int atomic_sub_return(int i, atomic_t * v)
+ {
+ 	unsigned long temp, flags;
+ 
+diff --git a/include/asm-m68knommu/coldfire.h b/include/asm-m68knommu/coldfire.h
+--- a/include/asm-m68knommu/coldfire.h
++++ b/include/asm-m68knommu/coldfire.h
+@@ -20,9 +20,14 @@
+  */
+ #define	MCF_MBAR	0x10000000
+ #define	MCF_MBAR2	0x80000000
++#if defined(CONFIG_M520x)
++#define	MCF_IPSBAR	0xFC000000
++#else
+ #define	MCF_IPSBAR	0x40000000
++#endif
+ 
+-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
++#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
++    defined(CONFIG_M520x)
+ #undef MCF_MBAR
+ #define	MCF_MBAR	MCF_IPSBAR
+ #endif
+@@ -78,7 +83,8 @@
+  *	One some ColdFire family members the bus clock (used by internal
+  *	peripherals) is not the same as the CPU clock.
+  */
+-#if defined(CONFIG_M523x) || defined(CONFIG_M5249) || defined(CONFIG_M527x)
++#if defined(CONFIG_M523x) || defined(CONFIG_M5249) || defined(CONFIG_M527x) || \
++    defined(CONFIG_M520x)
+ #define	MCF_BUSCLK	(MCF_CLK / 2)
+ #else
+ #define	MCF_BUSCLK	MCF_CLK
+diff --git a/include/asm-m68knommu/delay.h b/include/asm-m68knommu/delay.h
+--- a/include/asm-m68knommu/delay.h
++++ b/include/asm-m68knommu/delay.h
+@@ -8,7 +8,7 @@
+ 
+ #include <asm/param.h>
+ 
+-extern __inline__ void __delay(unsigned long loops)
++static inline void __delay(unsigned long loops)
+ {
+ #if defined(CONFIG_COLDFIRE)
+ 	/* The coldfire runs this loop at significantly different speeds
+@@ -48,7 +48,7 @@ extern __inline__ void __delay(unsigned 
+ 
+ extern unsigned long loops_per_jiffy;
+ 
+-extern __inline__ void _udelay(unsigned long usecs)
++static inline void _udelay(unsigned long usecs)
+ {
+ #if defined(CONFIG_M68328) || defined(CONFIG_M68EZ328) || \
+     defined(CONFIG_M68VZ328) || defined(CONFIG_M68360) || \
+diff --git a/include/asm-m68knommu/ide.h b/include/asm-m68knommu/ide.h
+deleted file mode 100644
+--- a/include/asm-m68knommu/ide.h
++++ /dev/null
+@@ -1,444 +0,0 @@
+-/****************************************************************************/
+-/*
+- *  linux/include/asm-m68knommu/ide.h
+- *
+- *  Copyright (C) 1994-1996  Linus Torvalds & authors
+- *	Copyright (C) 2001       Lineo Inc., davidm at uclinux.org
+- */
+-/****************************************************************************/
+-#ifndef _M68KNOMMU_IDE_H
+-#define _M68KNOMMU_IDE_H
+-
+-#ifdef __KERNEL__
+-/****************************************************************************/
+-
+-#include <linux/config.h>
+-#include <linux/interrupt.h>
+-
+-#include <asm/setup.h>
+-#include <asm/io.h>
+-#include <asm/irq.h>
+-
+-/****************************************************************************/
+-/*
+- *	some coldfire specifics
+- */
+-
+-#ifdef CONFIG_COLDFIRE
+-#include <asm/coldfire.h>
+-#include <asm/mcfsim.h>
+-
+-/*
+- *	Save some space,  only have 1 interface
+- */
+-#define MAX_HWIFS		  1	/* we only have one interface for now */
+-
+-#ifdef CONFIG_SECUREEDGEMP3
+-#define	MCFSIM_LOCALCS	  MCFSIM_CSCR4
+-#else
+-#define	MCFSIM_LOCALCS	  MCFSIM_CSCR6
+-#endif
+-
+-#endif /* CONFIG_COLDFIRE */
+-
+-/****************************************************************************/
+-/*
+- *	Fix up things that may not have been provided
+- */
+-
+-#ifndef MAX_HWIFS
+-#define MAX_HWIFS	4	/* same as the other archs */
+-#endif
+-
+-#undef SUPPORT_SLOW_DATA_PORTS
+-#define SUPPORT_SLOW_DATA_PORTS 0
+-
+-#undef SUPPORT_VLB_SYNC
+-#define SUPPORT_VLB_SYNC 0
+-
+-/* this definition is used only on startup .. */
+-#undef HD_DATA
+-#define HD_DATA NULL
+-
+-#define	DBGIDE(fmt,a...)
+-// #define	DBGIDE(fmt,a...) printk(fmt, ##a)
+-#define IDE_INLINE __inline__
+-// #define IDE_INLINE
+-
+-/****************************************************************************/
+-
+-typedef union {
+-	unsigned all			: 8;	/* all of the bits together */
+-	struct {
+-		unsigned bit7		: 1;	/* always 1 */
+-		unsigned lba		: 1;	/* using LBA instead of CHS */
+-		unsigned bit5		: 1;	/* always 1 */
+-		unsigned unit		: 1;	/* drive select number, 0 or 1 */
+-		unsigned head		: 4;	/* always zeros here */
+-	} b;
+-} select_t;
+-
+-/*
+- *	our list of ports/irq's for different boards
+- */
+-
+-static struct m68k_ide_defaults {
+-	ide_ioreg_t	base;
+-	int			irq;
+-} m68k_ide_defaults[MAX_HWIFS] = {
+-#if defined(CONFIG_SECUREEDGEMP3)
+-	{ ((ide_ioreg_t)0x30800000), 29 },
+-#elif defined(CONFIG_eLIA)
+-	{ ((ide_ioreg_t)0x30c00000), 29 },
+-#else
+-	{ ((ide_ioreg_t)0x0), 0 }
+-#endif
+-};
+-
+-/****************************************************************************/
+-
+-static IDE_INLINE int ide_default_irq(ide_ioreg_t base)
+-{
+-	int i;
+-
+-	for (i = 0; i < MAX_HWIFS; i++)
+-		if (m68k_ide_defaults[i].base == base)
+-			return(m68k_ide_defaults[i].irq);
+-	return 0;
+-}
+-
+-static IDE_INLINE ide_ioreg_t ide_default_io_base(int index)
+-{
+-	if (index >= 0 && index < MAX_HWIFS)
+-		return(m68k_ide_defaults[index].base);
+-	return 0;
+-}
+-
+-
+-/*
+- * Set up a hw structure for a specified data port, control port and IRQ.
+- * This should follow whatever the default interface uses.
+- */
+-static IDE_INLINE void ide_init_hwif_ports(
+-	hw_regs_t *hw,
+-	ide_ioreg_t data_port,
+-	ide_ioreg_t ctrl_port,
+-	int *irq)
+-{
+-	ide_ioreg_t reg = data_port;
+-	int i;
+-
+-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+-		hw->io_ports[i] = reg;
+-		reg += 1;
+-	}
+-	if (ctrl_port) {
+-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+-	} else {
+-		hw->io_ports[IDE_CONTROL_OFFSET] = data_port + 0xe;
+-	}
+-}
+-
+-#define ide_init_default_irq(base)	ide_default_irq(base)
+-
+-static IDE_INLINE int
+-ide_request_irq(
+-	unsigned int irq,
+-	void (*handler)(int, void *, struct pt_regs *),
+-	unsigned long flags,
+-	const char *device,
+-	void *dev_id)
+-{
+-#ifdef CONFIG_COLDFIRE
+-	mcf_autovector(irq);
+-#endif
+-	return(request_irq(irq, handler, flags, device, dev_id));
+-}
+-
+-
+-static IDE_INLINE void
+-ide_free_irq(unsigned int irq, void *dev_id)
+-{
+-	free_irq(irq, dev_id);
+-}
+-
+-
+-static IDE_INLINE int
+-ide_check_region(ide_ioreg_t from, unsigned int extent)
+-{
+-	return 0;
+-}
+-
+-
+-static IDE_INLINE void
+-ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
+-{
+-}
+-
+-
+-static IDE_INLINE void
+-ide_release_region(ide_ioreg_t from, unsigned int extent)
+-{
+-}
+-
+-
+-static IDE_INLINE void
+-ide_fix_driveid(struct hd_driveid *id)
+-{
+-#ifdef CONFIG_COLDFIRE
+-	int i, n;
+-	unsigned short *wp = (unsigned short *) id;
+-	int avoid[] = {49, 51, 52, 59, -1 }; /* do not swap these words */
+-
+-	/* Need to byte swap shorts,  but not char fields */
+-	for (i = n = 0; i < sizeof(*id) / sizeof(*wp); i++, wp++) {
+-		if (avoid[n] == i) {
+-			n++;
+-			continue;
+-		}
+-		*wp = ((*wp & 0xff) << 8) | ((*wp >> 8) & 0xff);
+-	}
+-	/* have to word swap the one 32 bit field */
+-	id->lba_capacity = ((id->lba_capacity & 0xffff) << 16) |
+-				((id->lba_capacity >> 16) & 0xffff);
+-#endif
+-}
+-
+-
+-static IDE_INLINE void
+-ide_release_lock (int *ide_lock)
+-{
+-}
+-
+-
+-static IDE_INLINE void
+-ide_get_lock(
+-	int *ide_lock,
+-	void (*handler)(int, void *, struct pt_regs *),
+-	void *data)
+-{
+-}
+-
+-
+-#define ide_ack_intr(hwif) \
+-	((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
+-#define	ide__sti()	__sti()
+-
+-/****************************************************************************/
+-/*
+- *	System specific IO requirements
+- */
+-
+-#ifdef CONFIG_COLDFIRE
+-
+-#ifdef CONFIG_SECUREEDGEMP3
+-
+-/* Replace standard IO functions for funky mapping of MP3 board */
+-#undef outb
+-#undef outb_p
+-#undef inb
+-#undef inb_p
+-
+-#define outb(v, a)          ide_outb(v, (unsigned long) (a))
+-#define outb_p(v, a)        ide_outb(v, (unsigned long) (a))
+-#define inb(a)              ide_inb((unsigned long) (a))
+-#define inb_p(a)            ide_inb((unsigned long) (a))
+-
+-#define ADDR8_PTR(addr)		(((addr) & 0x1) ? (0x8000 + (addr) - 1) : (addr))
+-#define ADDR16_PTR(addr)	(addr)
+-#define ADDR32_PTR(addr)	(addr)
+-#define SWAP8(w)			((((w) & 0xffff) << 8) | (((w) & 0xffff) >> 8))
+-#define SWAP16(w)			(w)
+-#define SWAP32(w)			(w)
+-
+-
+-static IDE_INLINE void
+-ide_outb(unsigned int val, unsigned int addr)
+-{
+-	volatile unsigned short	*rp;
+-
+-	DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
+-	rp = (volatile unsigned short *) ADDR8_PTR(addr);
+-	*rp = SWAP8(val);
+-}
+-
+-
+-static IDE_INLINE int
+-ide_inb(unsigned int addr)
+-{
+-	volatile unsigned short	*rp, val;
+-
+-	DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
+-	rp = (volatile unsigned short *) ADDR8_PTR(addr);
+-	val = *rp;
+-	return(SWAP8(val));
+-}
+-
+-
+-static IDE_INLINE void
+-ide_outw(unsigned int val, unsigned int addr)
+-{
+-	volatile unsigned short	*rp;
+-
+-	DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
+-	rp = (volatile unsigned short *) ADDR16_PTR(addr);
+-	*rp = SWAP16(val);
+-}
+-
+-static IDE_INLINE void
+-ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
+-{
+-	volatile unsigned short	*rp, val;
+-	unsigned short   	*buf;
+-
+-	DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
+-	buf = (unsigned short *) vbuf;
+-	rp = (volatile unsigned short *) ADDR16_PTR(addr);
+-	for (; (len > 0); len--) {
+-		val = *buf++;
+-		*rp = SWAP16(val);
+-	}
+-}
+-
+-static IDE_INLINE int
+-ide_inw(unsigned int addr)
+-{
+-	volatile unsigned short *rp, val;
+-
+-	DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
+-	rp = (volatile unsigned short *) ADDR16_PTR(addr);
+-	val = *rp;
+-	return(SWAP16(val));
+-}
+-
+-static IDE_INLINE void
+-ide_insw(unsigned int addr, void *vbuf, unsigned long len)
+-{
+-	volatile unsigned short *rp;
+-	unsigned short          w, *buf;
+-
+-	DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
+-	buf = (unsigned short *) vbuf;
+-	rp = (volatile unsigned short *) ADDR16_PTR(addr);
+-	for (; (len > 0); len--) {
+-		w = *rp;
+-		*buf++ = SWAP16(w);
+-	}
+-}
+-
+-static IDE_INLINE void
+-ide_insl(unsigned int addr, void *vbuf, unsigned long len)
+-{
+-	volatile unsigned long *rp;
+-	unsigned long          w, *buf;
+-
+-	DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
+-	buf = (unsigned long *) vbuf;
+-	rp = (volatile unsigned long *) ADDR32_PTR(addr);
+-	for (; (len > 0); len--) {
+-		w = *rp;
+-		*buf++ = SWAP32(w);
+-	}
+-}
+-
+-static IDE_INLINE void
+-ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
+-{
+-	volatile unsigned long	*rp, val;
+-	unsigned long   	*buf;
+-
+-	DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
+-	buf = (unsigned long *) vbuf;
+-	rp = (volatile unsigned long *) ADDR32_PTR(addr);
+-	for (; (len > 0); len--) {
+-		val = *buf++;
+-		*rp = SWAP32(val);
+-	}
+-}
+-
+-#elif CONFIG_eLIA
+-
+-/* 8/16 bit acesses are controlled by flicking bits in the CS register */
+-#define	ACCESS_MODE_16BIT()	\
+-	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0080
+-#define	ACCESS_MODE_8BIT()	\
+-	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0040
+-
+-
+-static IDE_INLINE void
+-ide_outw(unsigned int val, unsigned int addr)
+-{
+-	ACCESS_MODE_16BIT();
+-	outw(val, addr);
+-	ACCESS_MODE_8BIT();
+-}
+-
+-static IDE_INLINE void
+-ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
+-{
+-	ACCESS_MODE_16BIT();
+-	outsw(addr, vbuf, len);
+-	ACCESS_MODE_8BIT();
+-}
+-
+-static IDE_INLINE int
+-ide_inw(unsigned int addr)
+-{
+-	int ret;
+-
+-	ACCESS_MODE_16BIT();
+-	ret = inw(addr);
+-	ACCESS_MODE_8BIT();
+-	return(ret);
+-}
+-
+-static IDE_INLINE void
+-ide_insw(unsigned int addr, void *vbuf, unsigned long len)
+-{
+-	ACCESS_MODE_16BIT();
+-	insw(addr, vbuf, len);
+-	ACCESS_MODE_8BIT();
+-}
+-
+-static IDE_INLINE void
+-ide_insl(unsigned int addr, void *vbuf, unsigned long len)
+-{
+-	ACCESS_MODE_16BIT();
+-	insl(addr, vbuf, len);
+-	ACCESS_MODE_8BIT();
+-}
+-
+-static IDE_INLINE void
+-ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
+-{
+-	ACCESS_MODE_16BIT();
+-	outsl(addr, vbuf, len);
+-	ACCESS_MODE_8BIT();
+-}
+-
+-#endif /* CONFIG_SECUREEDGEMP3 */
+-
+-#undef outw
+-#undef outw_p
+-#undef outsw
+-#undef inw
+-#undef inw_p
+-#undef insw
+-#undef insl
+-#undef outsl
+-
+-#define	outw(v, a)	     ide_outw(v, (unsigned long) (a))
+-#define	outw_p(v, a)     ide_outw(v, (unsigned long) (a))
+-#define outsw(a, b, n)   ide_outsw((unsigned long) (a), b, n)
+-#define	inw(a)	         ide_inw((unsigned long) (a))
+-#define	inw_p(a)	     ide_inw((unsigned long) (a))
+-#define insw(a, b, n)    ide_insw((unsigned long) (a), b, n)
+-#define insl(a, b, n)    ide_insl((unsigned long) (a), b, n)
+-#define outsl(a, b, n)   ide_outsl((unsigned long) (a), b, n)
+-
+-#endif CONFIG_COLDFIRE
+-
+-/****************************************************************************/
+-#endif /* __KERNEL__ */
+-#endif /* _M68KNOMMU_IDE_H */
+-/****************************************************************************/
+diff --git a/include/asm-m68knommu/io.h b/include/asm-m68knommu/io.h
+--- a/include/asm-m68knommu/io.h
++++ b/include/asm-m68knommu/io.h
+@@ -147,19 +147,19 @@ static inline void io_insl(unsigned int 
+ extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+ extern void __iounmap(void *addr, unsigned long size);
+ 
+-extern inline void *ioremap(unsigned long physaddr, unsigned long size)
++static inline void *ioremap(unsigned long physaddr, unsigned long size)
+ {
+ 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+ }
+-extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
++static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+ {
+ 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+ }
+-extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
++static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+ {
+ 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+ }
+-extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
++static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+ {
+ 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+ }
+diff --git a/include/asm-m68knommu/m520xsim.h b/include/asm-m68knommu/m520xsim.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-m68knommu/m520xsim.h
+@@ -0,0 +1,54 @@
++/****************************************************************************/
++
++/*
++ *  m520xsim.h -- ColdFire 5207/5208 System Integration Module support.
++ *
++ *  (C) Copyright 2005, Intec Automation (mike at steroidmicros.com)
++ */
++
++/****************************************************************************/
++#ifndef m520xsim_h
++#define m520xsim_h
++/****************************************************************************/
++
++#include <linux/config.h>
++
++/*
++ *  Define the 5282 SIM register set addresses.
++ */
++#define MCFICM_INTC0        0x48000     /* Base for Interrupt Ctrl 0 */
++#define MCFINTC_IPRH        0x00        /* Interrupt pending 32-63 */
++#define MCFINTC_IPRL        0x04        /* Interrupt pending 1-31 */
++#define MCFINTC_IMRH        0x08        /* Interrupt mask 32-63 */
++#define MCFINTC_IMRL        0x0c        /* Interrupt mask 1-31 */
++#define MCFINTC_INTFRCH     0x10        /* Interrupt force 32-63 */
++#define MCFINTC_INTFRCL     0x14        /* Interrupt force 1-31 */
++#define MCFINTC_ICR0        0x40        /* Base ICR register */
++
++#define MCFINT_VECBASE      64
++#define MCFINT_UART0        26          /* Interrupt number for UART0 */
++#define MCFINT_UART1        27          /* Interrupt number for UART1 */
++#define MCFINT_UART2        28          /* Interrupt number for UART2 */
++#define MCFINT_QSPI         31          /* Interrupt number for QSPI */
++#define MCFINT_PIT1         4           /* Interrupt number for PIT1 (PIT0 in processor) */
++
++
++#define MCF_GPIO_PAR_UART                   (0xA4036)
++#define MCF_GPIO_PAR_FECI2C                 (0xA4033)
++#define MCF_GPIO_PAR_FEC                    (0xA4038)
++
++#define MCF_GPIO_PAR_UART_PAR_URXD0         (0x0001)
++#define MCF_GPIO_PAR_UART_PAR_UTXD0         (0x0002)
++
++#define MCF_GPIO_PAR_UART_PAR_URXD1         (0x0040)
++#define MCF_GPIO_PAR_UART_PAR_UTXD1         (0x0080)
++
++#define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2   (0x02)
++#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2   (0x04)
++
++#define ICR_INTRCONF		0x05
++#define MCFPIT_IMR		MCFINTC_IMRL
++#define MCFPIT_IMR_IBIT	(1 << MCFINT_PIT1)
++
++/****************************************************************************/
++#endif  /* m520xsim_h */
+diff --git a/include/asm-m68knommu/mcfcache.h b/include/asm-m68knommu/mcfcache.h
+--- a/include/asm-m68knommu/mcfcache.h
++++ b/include/asm-m68knommu/mcfcache.h
+@@ -117,6 +117,20 @@
+ .endm
+ #endif /* CONFIG_M5407 */
+ 
++#if defined(CONFIG_M520x)
++.macro CACHE_ENABLE
++	move.l	#0x01000000,%d0		/* invalidate whole cache */
++	movec	%d0,%CACR
++	nop
++	move.l	#0x0000c000,%d0		/* set SDRAM cached (write-thru) */
++	movec	%d0,%ACR0
++	move.l	#0x00000000,%d0		/* no other regions cached */
++	movec	%d0,%ACR1
++	move.l	#0x80400000,%d0		/* enable 8K instruction cache */
++	movec	%d0,%CACR
++	nop
++.endm
++#endif /* CONFIG_M520x */
+ 
+ /****************************************************************************/
+ #endif	/* __M68KNOMMU_MCFCACHE_H */
+diff --git a/include/asm-m68knommu/mcfne.h b/include/asm-m68knommu/mcfne.h
+--- a/include/asm-m68knommu/mcfne.h
++++ b/include/asm-m68knommu/mcfne.h
+@@ -35,7 +35,7 @@
+  *	Define the basic hardware resources of NE2000 boards.
+  */
+ 
+-#if defined(CONFIG_M5206) && defined(CONFIG_ARNEWSH)
++#if defined(CONFIG_ARN5206)
+ #define NE2000_ADDR		0x40000300
+ #define NE2000_ODDOFFSET	0x00010000
+ #define	NE2000_IRQ_VECTOR	0xf0
+@@ -44,7 +44,7 @@
+ #define	NE2000_BYTE		volatile unsigned short
+ #endif
+ 
+-#if defined(CONFIG_M5206e) && defined(CONFIG_MOTOROLA)
++#if defined(CONFIG_M5206eC3)
+ #define	NE2000_ADDR		0x40000300
+ #define	NE2000_ODDOFFSET	0x00010000
+ #define	NE2000_IRQ_VECTOR	0x1c
+@@ -61,7 +61,7 @@
+ #define	NE2000_BYTE		volatile unsigned char
+ #endif
+ 
+-#if defined(CONFIG_M5206e) && defined(CONFIG_CFV240)
++#if defined(CONFIG_CFV240)
+ #define NE2000_ADDR             0x40010000
+ #define NE2000_ADDR1            0x40010001
+ #define NE2000_ODDOFFSET        0x00000000
+@@ -72,7 +72,7 @@
+ #define	NE2000_BYTE		volatile unsigned char
+ #endif
+ 
+-#if defined(CONFIG_M5307) && defined(CONFIG_MOTOROLA)
++#if defined(CONFIG_M5307C3)
+ #define NE2000_ADDR		0x40000300
+ #define NE2000_ODDOFFSET	0x00010000
+ #define NE2000_IRQ_VECTOR	0x1b
+@@ -114,7 +114,7 @@
+ #define	RSWAP(w)		(((w) << 8) | ((w) >> 8))
+ #endif
+ 
+-#if defined(CONFIG_M5307) && defined(CONFIG_ARNEWSH)
++#if defined(CONFIG_ARN5307)
+ #define NE2000_ADDR		0xfe600300
+ #define NE2000_ODDOFFSET	0x00010000
+ #define NE2000_IRQ_VECTOR	0x1b
+@@ -123,7 +123,7 @@
+ #define	NE2000_BYTE		volatile unsigned short
+ #endif
+ 
+-#if defined(CONFIG_M5407)
++#if defined(CONFIG_M5407C3)
+ #define NE2000_ADDR		0x40000300
+ #define NE2000_ODDOFFSET	0x00010000
+ #define NE2000_IRQ_VECTOR	0x1b
+@@ -264,7 +264,7 @@ void ne2000_outsw(unsigned int addr, con
+  *	Minor differences between the different board types.
+  */
+ 
+-#if defined(CONFIG_M5206) && defined(CONFIG_ARNEWSH)
++#if defined(CONFIG_ARN5206)
+ void ne2000_irqsetup(int irq)
+ {
+ 	volatile unsigned char  *icrp;
+@@ -275,7 +275,7 @@ void ne2000_irqsetup(int irq)
+ }
+ #endif
+ 
+-#if defined(CONFIG_M5206e) && defined(CONFIG_MOTOROLA)
++#if defined(CONFIG_M5206eC3)
+ void ne2000_irqsetup(int irq)
+ {
+ 	volatile unsigned char  *icrp;
+@@ -286,7 +286,7 @@ void ne2000_irqsetup(int irq)
+ }
+ #endif
+ 
+-#if defined(CONFIG_M5206e) && defined(CONFIG_CFV240)
++#if defined(CONFIG_CFV240)
+ void ne2000_irqsetup(int irq)
+ {
+ 	volatile unsigned char  *icrp;
+diff --git a/include/asm-m68knommu/mcfpit.h b/include/asm-m68knommu/mcfpit.h
+--- a/include/asm-m68knommu/mcfpit.h
++++ b/include/asm-m68knommu/mcfpit.h
+@@ -14,13 +14,17 @@
+ #include <linux/config.h>
+ 
+ /*
+- *	Get address specific defines for the 5270/5271 and 5280/5282.
++ *	Get address specific defines for the 5270/5271, 5280/5282, and 5208.
+  */
++#if defined(CONFIG_M520x)
++#define	MCFPIT_BASE1		0x00080000	/* Base address of TIMER1 */
++#define	MCFPIT_BASE2		0x00084000	/* Base address of TIMER2 */
++#else
+ #define	MCFPIT_BASE1		0x00150000	/* Base address of TIMER1 */
+ #define	MCFPIT_BASE2		0x00160000	/* Base address of TIMER2 */
+ #define	MCFPIT_BASE3		0x00170000	/* Base address of TIMER3 */
+ #define	MCFPIT_BASE4		0x00180000	/* Base address of TIMER4 */
+-
++#endif
+ 
+ /*
+  *	Define the PIT timer register set addresses.
+diff --git a/include/asm-m68knommu/mcfsim.h b/include/asm-m68knommu/mcfsim.h
+--- a/include/asm-m68knommu/mcfsim.h
++++ b/include/asm-m68knommu/mcfsim.h
+@@ -22,6 +22,8 @@
+ #include <asm/m5204sim.h>
+ #elif defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+ #include <asm/m5206sim.h>
++#elif defined(CONFIG_M520x)
++#include <asm/m520xsim.h>
+ #elif defined(CONFIG_M523x)
+ #include <asm/m523xsim.h>
+ #elif defined(CONFIG_M5249)
+@@ -99,6 +101,19 @@
+ #define	MCFSIM_IMR_MASKALL	0x3ffe		/* All intr sources */
+ #endif
+ 
++/*
++ *	PIT interrupt settings, if not found in mXXXXsim.h file.
++ */
++#ifndef	ICR_INTRCONF
++#define	ICR_INTRCONF		0x2b            /* PIT1 level 5, priority 3 */
++#endif
++#ifndef	MCFPIT_IMR
++#define	MCFPIT_IMR		MCFINTC_IMRH
++#endif
++#ifndef	MCFPIT_IMR_IBIT
++#define	MCFPIT_IMR_IBIT		(1 << (MCFINT_PIT1 - 32))
++#endif
++
+ 
+ #ifndef __ASSEMBLY__
+ /*
+diff --git a/include/asm-m68knommu/mcfuart.h b/include/asm-m68knommu/mcfuart.h
+--- a/include/asm-m68knommu/mcfuart.h
++++ b/include/asm-m68knommu/mcfuart.h
+@@ -41,6 +41,10 @@
+ #define MCFUART_BASE1		0x1c0           /* Base address of UART1 */
+ #define MCFUART_BASE2		0x200           /* Base address of UART2 */
+ #endif
++#elif defined(CONFIG_M520x)
++#define MCFUART_BASE1		0x60000		/* Base address of UART1 */
++#define MCFUART_BASE2		0x64000		/* Base address of UART2 */
++#define MCFUART_BASE3		0x68000		/* Base address of UART2 */
+ #endif
+ 
+ 
+diff --git a/include/asm-m68knommu/mcfwdebug.h b/include/asm-m68knommu/mcfwdebug.h
+--- a/include/asm-m68knommu/mcfwdebug.h
++++ b/include/asm-m68knommu/mcfwdebug.h
+@@ -90,7 +90,7 @@
+  * that the debug module instructions (2 longs) must be long word aligned and
+  * some pointer fiddling is performed to ensure this.
+  */
+-extern inline void wdebug(int reg, unsigned long data) {
++static inline void wdebug(int reg, unsigned long data) {
+ 	unsigned short dbg_spc[6];
+ 	unsigned short *dbg;
+ 
+diff --git a/include/asm-m68knommu/mmu_context.h b/include/asm-m68knommu/mmu_context.h
+--- a/include/asm-m68knommu/mmu_context.h
++++ b/include/asm-m68knommu/mmu_context.h
+@@ -10,7 +10,7 @@ static inline void enter_lazy_tlb(struct
+ {
+ }
+ 
+-extern inline int
++static inline int
+ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+ {
+ 	// mm->context = virt_to_phys(mm->pgd);
+@@ -25,7 +25,7 @@ static inline void switch_mm(struct mm_s
+ 
+ #define deactivate_mm(tsk,mm)	do { } while (0)
+ 
+-extern inline void activate_mm(struct mm_struct *prev_mm,
++static inline void activate_mm(struct mm_struct *prev_mm,
+ 			       struct mm_struct *next_mm)
+ {
+ }
+diff --git a/include/asm-m68knommu/processor.h b/include/asm-m68knommu/processor.h
+--- a/include/asm-m68knommu/processor.h
++++ b/include/asm-m68knommu/processor.h
+@@ -21,7 +21,7 @@
+ #include <asm/ptrace.h>
+ #include <asm/current.h>
+ 
+-extern inline unsigned long rdusp(void)
++static inline unsigned long rdusp(void)
+ {
+ #ifdef CONFIG_COLDFIRE
+ 	extern unsigned int sw_usp;
+@@ -33,7 +33,7 @@ extern inline unsigned long rdusp(void)
+ #endif
+ }
+ 
+-extern inline void wrusp(unsigned long usp)
++static inline void wrusp(unsigned long usp)
+ {
+ #ifdef CONFIG_COLDFIRE
+ 	extern unsigned int sw_usp;
+diff --git a/include/asm-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h
+--- a/include/asm-m68knommu/semaphore.h
++++ b/include/asm-m68knommu/semaphore.h
+@@ -35,16 +35,13 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+ #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+ #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+ 
+-extern inline void sema_init (struct semaphore *sem, int val)
++static inline void sema_init (struct semaphore *sem, int val)
+ {
+ 	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
+ }
+@@ -76,7 +73,7 @@ extern spinlock_t semaphore_wake_lock;
+  * "down_failed" is a special asm handler that calls the C
+  * routine that actually waits. See arch/m68k/lib/semaphore.S
+  */
+-extern inline void down(struct semaphore * sem)
++static inline void down(struct semaphore * sem)
+ {
+ 	might_sleep();
+ 	__asm__ __volatile__(
+@@ -91,7 +88,7 @@ extern inline void down(struct semaphore
+ 		: "cc", "%a0", "%a1", "memory");
+ }
+ 
+-extern inline int down_interruptible(struct semaphore * sem)
++static inline int down_interruptible(struct semaphore * sem)
+ {
+ 	int ret;
+ 
+@@ -110,7 +107,7 @@ extern inline int down_interruptible(str
+ 	return(ret);
+ }
+ 
+-extern inline int down_trylock(struct semaphore * sem)
++static inline int down_trylock(struct semaphore * sem)
+ {
+ 	register struct semaphore *sem1 __asm__ ("%a1") = sem;
+ 	register int result __asm__ ("%d0");
+@@ -138,7 +135,7 @@ extern inline int down_trylock(struct se
+  * The default case (no contention) will result in NO
+  * jumps for both down() and up().
+  */
+-extern inline void up(struct semaphore * sem)
++static inline void up(struct semaphore * sem)
+ {
+ 	__asm__ __volatile__(
+ 		"| atomic up operation\n\t"
+diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
+--- a/include/asm-m68knommu/system.h
++++ b/include/asm-m68knommu/system.h
+@@ -312,6 +312,19 @@ cmpxchg(volatile int *p, int old, int ne
+ 	moveb #0x80, (%a0);		\
+ 	");				\
+ })
++#elif defined(CONFIG_M520x)
++	/*
++	 * The MCF5208 has a bit (SOFTRST) in memory (Reset Control Register 
++	 * RCR), that when set, resets the MCF5208.
++	 */
++#define HARD_RESET_NOW() 		\
++({					\
++	unsigned char volatile *reset;	\
++	asm("move.w     #0x2700, %sr");	\
++	reset = ((volatile unsigned short *)(MCF_IPSBAR + 0xA0000));	\
++	while(1)			\
++		*reset |= 0x80;		\
++})
+ #else
+ #define HARD_RESET_NOW() ({		\
+         asm("				\
+diff --git a/include/asm-m68knommu/tlbflush.h b/include/asm-m68knommu/tlbflush.h
+--- a/include/asm-m68knommu/tlbflush.h
++++ b/include/asm-m68knommu/tlbflush.h
+@@ -47,12 +47,12 @@ static inline void flush_tlb_range(struc
+ 	BUG();
+ }
+ 
+-extern inline void flush_tlb_kernel_page(unsigned long addr)
++static inline void flush_tlb_kernel_page(unsigned long addr)
+ {
+ 	BUG();
+ }
+ 
+-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
++static inline void flush_tlb_pgtables(struct mm_struct *mm,
+ 				      unsigned long start, unsigned long end)
+ {
+ 	BUG();
+diff --git a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h
+--- a/include/asm-m68knommu/unistd.h
++++ b/include/asm-m68knommu/unistd.h
+@@ -504,7 +504,6 @@ asmlinkage long sys_mmap2(unsigned long 
+ 			unsigned long fd, unsigned long pgoff);
+ asmlinkage int sys_execve(char *name, char **argv, char **envp);
+ asmlinkage int sys_pipe(unsigned long *fildes);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ struct pt_regs;
+ int sys_request_irq(unsigned int,
+ 			irqreturn_t (*)(int, void *, struct pt_regs *),
+diff --git a/include/asm-mips/abi.h b/include/asm-mips/abi.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/abi.h
+@@ -0,0 +1,25 @@
++/*
++ * 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 by Ralf Baechle
++ * Copyright (C) 2005 MIPS Technologies, Inc.
++ */
++#ifndef _ASM_ABI_H
++#define _ASM_ABI_H
++
++#include <asm/signal.h>
++#include <asm/siginfo.h>
++
++struct mips_abi {
++	int (* const do_signal)(sigset_t *oldset, struct pt_regs *regs);
++	int (* const setup_frame)(struct k_sigaction * ka,
++	                          struct pt_regs *regs, int signr,
++	                          sigset_t *set);
++	int (* const setup_rt_frame)(struct k_sigaction * ka,
++	                       struct pt_regs *regs, int signr,
++	                       sigset_t *set, siginfo_t *info);
++};
++
++#endif /* _ASM_ABI_H */
+diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h
+--- a/include/asm-mips/addrspace.h
++++ b/include/asm-mips/addrspace.h
+@@ -20,10 +20,12 @@
+ #define _ATYPE_
+ #define _ATYPE32_
+ #define _ATYPE64_
++#define _LLCONST_(x)	x
+ #else
+ #define _ATYPE_		__PTRDIFF_TYPE__
+ #define _ATYPE32_	int
+ #define _ATYPE64_	long long
++#define _LLCONST_(x)	x ## LL
+ #endif
+ 
+ /*
+@@ -45,8 +47,9 @@
+ /*
+  * Returns the physical address of a CKSEGx / XKPHYS address
+  */
+-#define CPHYSADDR(a)		((_ACAST32_ (a)) & 0x1fffffff)
+-#define XPHYSADDR(a)            ((_ACAST64_ (a)) & 0x000000ffffffffff)
++#define CPHYSADDR(a)		((_ACAST32_(a)) & 0x1fffffff)
++#define XPHYSADDR(a)            ((_ACAST64_(a)) &			\
++				 _LLCONST_(0x000000ffffffffff))
+ 
+ #ifdef CONFIG_64BIT
+ 
+@@ -55,14 +58,14 @@
+  * The compatibility segments use the full 64-bit sign extended value.  Note
+  * the R8000 doesn't have them so don't reference these in generic MIPS code.
+  */
+-#define XKUSEG			0x0000000000000000
+-#define XKSSEG			0x4000000000000000
+-#define XKPHYS			0x8000000000000000
+-#define XKSEG			0xc000000000000000
+-#define CKSEG0			0xffffffff80000000
+-#define CKSEG1			0xffffffffa0000000
+-#define CKSSEG			0xffffffffc0000000
+-#define CKSEG3			0xffffffffe0000000
++#define XKUSEG			_LLCONST_(0x0000000000000000)
++#define XKSSEG			_LLCONST_(0x4000000000000000)
++#define XKPHYS			_LLCONST_(0x8000000000000000)
++#define XKSEG			_LLCONST_(0xc000000000000000)
++#define CKSEG0			_LLCONST_(0xffffffff80000000)
++#define CKSEG1			_LLCONST_(0xffffffffa0000000)
++#define CKSSEG			_LLCONST_(0xffffffffc0000000)
++#define CKSEG3			_LLCONST_(0xffffffffe0000000)
+ 
+ #define CKSEG0ADDR(a)		(CPHYSADDR(a) | CKSEG0)
+ #define CKSEG1ADDR(a)		(CPHYSADDR(a) | CKSEG1)
+@@ -120,7 +123,8 @@
+ #define PHYS_TO_XKSEG_UNCACHED(p)	PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p))
+ #define PHYS_TO_XKSEG_CACHED(p)		PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p))
+ #define XKPHYS_TO_PHYS(p)		((p) & TO_PHYS_MASK)
+-#define PHYS_TO_XKPHYS(cm,a)		(0x8000000000000000 | ((cm)<<59) | (a))
++#define PHYS_TO_XKPHYS(cm,a)		(_LLCONST_(0x8000000000000000) | \
++					 ((cm)<<59) | (a))
+ 
+ #if defined (CONFIG_CPU_R4300)						\
+     || defined (CONFIG_CPU_R4X00)					\
+@@ -128,46 +132,56 @@
+     || defined (CONFIG_CPU_NEVADA)					\
+     || defined (CONFIG_CPU_TX49XX)					\
+     || defined (CONFIG_CPU_MIPS64)
+-#define	KUSIZE			0x0000010000000000	/* 2^^40 */
+-#define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
+-#define	K0SIZE			0x0000001000000000	/* 2^^36 */
+-#define	K1SIZE			0x0000001000000000	/* 2^^36 */
+-#define	K2SIZE			0x000000ff80000000
+-#define	KSEGSIZE		0x000000ff80000000	/* max syssegsz */
+-#define TO_PHYS_MASK		0x0000000fffffffff	/* 2^^36 - 1 */
++#define KUSIZE		_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define KUSIZE_64	_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define K0SIZE		_LLCONST_(0x0000001000000000)	/* 2^^36 */
++#define K1SIZE		_LLCONST_(0x0000001000000000)	/* 2^^36 */
++#define K2SIZE		_LLCONST_(0x000000ff80000000)
++#define KSEGSIZE	_LLCONST_(0x000000ff80000000)	/* max syssegsz */
++#define TO_PHYS_MASK	_LLCONST_(0x0000000fffffffff)	/* 2^^36 - 1 */
+ #endif
+ 
+ #if defined (CONFIG_CPU_R8000)
+ /* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */
+-#define	KUSIZE			0x0000010000000000	/* 2^^40 */
+-#define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
+-#define	K0SIZE			0x0000010000000000	/* 2^^40 */
+-#define	K1SIZE			0x0000010000000000	/* 2^^40 */
+-#define	K2SIZE			0x0001000000000000
+-#define	KSEGSIZE		0x0000010000000000	/* max syssegsz */
+-#define TO_PHYS_MASK		0x000000ffffffffff	/* 2^^40 - 1 */
++#define KUSIZE		_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define KUSIZE_64	_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define K0SIZE		_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define K1SIZE		_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define K2SIZE		_LLCONST_(0x0001000000000000)
++#define KSEGSIZE	_LLCONST_(0x0000010000000000)	/* max syssegsz */
++#define TO_PHYS_MASK	_LLCONST_(0x000000ffffffffff)	/* 2^^40 - 1 */
+ #endif
+ 
+ #if defined (CONFIG_CPU_R10000)
+-#define	KUSIZE			0x0000010000000000	/* 2^^40 */
+-#define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
+-#define	K0SIZE			0x0000010000000000	/* 2^^40 */
+-#define	K1SIZE			0x0000010000000000	/* 2^^40 */
+-#define	K2SIZE			0x00000fff80000000
+-#define	KSEGSIZE		0x00000fff80000000	/* max syssegsz */
+-#define TO_PHYS_MASK		0x000000ffffffffff	/* 2^^40 - 1 */
++#define KUSIZE		_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define KUSIZE_64	_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define K0SIZE		_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define K1SIZE		_LLCONST_(0x0000010000000000)	/* 2^^40 */
++#define K2SIZE		_LLCONST_(0x00000fff80000000)
++#define KSEGSIZE	_LLCONST_(0x00000fff80000000)	/* max syssegsz */
++#define TO_PHYS_MASK	_LLCONST_(0x000000ffffffffff)	/* 2^^40 - 1 */
++#endif
++
++#if defined(CONFIG_CPU_SB1) || defined(CONFIG_CPU_SB1A)
++#define KUSIZE		_LLCONST_(0x0000100000000000)	/* 2^^44 */
++#define KUSIZE_64	_LLCONST_(0x0000100000000000)	/* 2^^44 */
++#define K0SIZE		_LLCONST_(0x0000100000000000)	/* 2^^44 */
++#define K1SIZE		_LLCONST_(0x0000100000000000)	/* 2^^44 */
++#define K2SIZE		_LLCONST_(0x0000ffff80000000)
++#define KSEGSIZE	_LLCONST_(0x0000ffff80000000)	/* max syssegsz */
++#define TO_PHYS_MASK	_LLCONST_(0x00000fffffffffff)	/* 2^^44 - 1 */
+ #endif
+ 
+ /*
+  * Further names for SGI source compatibility.  These are stolen from
+  * IRIX's <sys/mips_addrspace.h>.
+  */
+-#define KUBASE			0
+-#define KUSIZE_32		0x0000000080000000	/* KUSIZE
++#define KUBASE		_LLCONST_(0)
++#define KUSIZE_32	_LLCONST_(0x0000000080000000)	/* KUSIZE
+ 							   for a 32 bit proc */
+-#define K0BASE_EXL_WR		0xa800000000000000	/* exclusive on write */
+-#define K0BASE_NONCOH		0x9800000000000000	/* noncoherent */
+-#define K0BASE_EXL		0xa000000000000000	/* exclusive */
++#define K0BASE_EXL_WR	_LLCONST_(0xa800000000000000)	/* exclusive on write */
++#define K0BASE_NONCOH	_LLCONST_(0x9800000000000000)	/* noncoherent */
++#define K0BASE_EXL	_LLCONST_(0xa000000000000000)	/* exclusive */
+ 
+ #ifndef CONFIG_CPU_R8000
+ 
+@@ -176,7 +190,7 @@
+  * in order to catch bugs in the source code.
+  */
+ 
+-#define COMPAT_K1BASE32		0xffffffffa0000000
++#define COMPAT_K1BASE32		_LLCONST_(0xffffffffa0000000)
+ #define PHYS_TO_COMPATK1(x)	((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
+ 
+ #endif
+diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h
+--- a/include/asm-mips/asm.h
++++ b/include/asm-mips/asm.h
+@@ -107,6 +107,7 @@ symbol		=	value
+ /*
+  * Print formatted string
+  */
++#ifdef CONFIG_PRINTK
+ #define PRINT(string)                                   \
+ 		.set	push;				\
+ 		.set	reorder;                        \
+@@ -114,6 +115,9 @@ symbol		=	value
+ 		jal	printk;                         \
+ 		.set	pop;				\
+ 		TEXT(string)
++#else
++#define PRINT(string)
++#endif
+ 
+ #define	TEXT(msg)                                       \
+ 		.pushsection .data;			\
+diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
+--- a/include/asm-mips/atomic.h
++++ b/include/asm-mips/atomic.h
+@@ -62,20 +62,24 @@ static __inline__ void atomic_add(int i,
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%0, %1		# atomic_add		\n"
+ 		"	addu	%0, %2					\n"
+ 		"	sc	%0, %1					\n"
+ 		"	beqzl	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter));
+ 	} else if (cpu_has_llsc) {
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%0, %1		# atomic_add		\n"
+ 		"	addu	%0, %2					\n"
+ 		"	sc	%0, %1					\n"
+ 		"	beqz	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter));
+ 	} else {
+@@ -100,20 +104,24 @@ static __inline__ void atomic_sub(int i,
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%0, %1		# atomic_sub		\n"
+ 		"	subu	%0, %2					\n"
+ 		"	sc	%0, %1					\n"
+ 		"	beqzl	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter));
+ 	} else if (cpu_has_llsc) {
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%0, %1		# atomic_sub		\n"
+ 		"	subu	%0, %2					\n"
+ 		"	sc	%0, %1					\n"
+ 		"	beqz	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter));
+ 	} else {
+@@ -136,12 +144,14 @@ static __inline__ int atomic_add_return(
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%1, %2		# atomic_add_return	\n"
+ 		"	addu	%0, %1, %3				\n"
+ 		"	sc	%0, %2					\n"
+ 		"	beqzl	%0, 1b					\n"
+ 		"	addu	%0, %1, %3				\n"
+ 		"	sync						\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -149,12 +159,14 @@ static __inline__ int atomic_add_return(
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%1, %2		# atomic_add_return	\n"
+ 		"	addu	%0, %1, %3				\n"
+ 		"	sc	%0, %2					\n"
+ 		"	beqz	%0, 1b					\n"
+ 		"	addu	%0, %1, %3				\n"
+ 		"	sync						\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -179,12 +191,14 @@ static __inline__ int atomic_sub_return(
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%1, %2		# atomic_sub_return	\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	sc	%0, %2					\n"
+ 		"	beqzl	%0, 1b					\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	sync						\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -192,12 +206,14 @@ static __inline__ int atomic_sub_return(
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%1, %2		# atomic_sub_return	\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	sc	%0, %2					\n"
+ 		"	beqz	%0, 1b					\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	sync						\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -229,6 +245,7 @@ static __inline__ int atomic_sub_if_posi
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%1, %2		# atomic_sub_if_positive\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	bltz	%0, 1f					\n"
+@@ -236,6 +253,7 @@ static __inline__ int atomic_sub_if_posi
+ 		"	beqzl	%0, 1b					\n"
+ 		"	sync						\n"
+ 		"1:							\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -243,6 +261,7 @@ static __inline__ int atomic_sub_if_posi
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%1, %2		# atomic_sub_if_positive\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	bltz	%0, 1f					\n"
+@@ -250,6 +269,7 @@ static __inline__ int atomic_sub_if_posi
+ 		"	beqz	%0, 1b					\n"
+ 		"	sync						\n"
+ 		"1:							\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -367,20 +387,24 @@ static __inline__ void atomic64_add(long
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%0, %1		# atomic64_add		\n"
+ 		"	addu	%0, %2					\n"
+ 		"	scd	%0, %1					\n"
+ 		"	beqzl	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter));
+ 	} else if (cpu_has_llsc) {
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%0, %1		# atomic64_add		\n"
+ 		"	addu	%0, %2					\n"
+ 		"	scd	%0, %1					\n"
+ 		"	beqz	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter));
+ 	} else {
+@@ -405,20 +429,24 @@ static __inline__ void atomic64_sub(long
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%0, %1		# atomic64_sub		\n"
+ 		"	subu	%0, %2					\n"
+ 		"	scd	%0, %1					\n"
+ 		"	beqzl	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter));
+ 	} else if (cpu_has_llsc) {
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%0, %1		# atomic64_sub		\n"
+ 		"	subu	%0, %2					\n"
+ 		"	scd	%0, %1					\n"
+ 		"	beqz	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter));
+ 	} else {
+@@ -441,12 +469,14 @@ static __inline__ long atomic64_add_retu
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%1, %2		# atomic64_add_return	\n"
+ 		"	addu	%0, %1, %3				\n"
+ 		"	scd	%0, %2					\n"
+ 		"	beqzl	%0, 1b					\n"
+ 		"	addu	%0, %1, %3				\n"
+ 		"	sync						\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -454,12 +484,14 @@ static __inline__ long atomic64_add_retu
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%1, %2		# atomic64_add_return	\n"
+ 		"	addu	%0, %1, %3				\n"
+ 		"	scd	%0, %2					\n"
+ 		"	beqz	%0, 1b					\n"
+ 		"	addu	%0, %1, %3				\n"
+ 		"	sync						\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -484,12 +516,14 @@ static __inline__ long atomic64_sub_retu
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%1, %2		# atomic64_sub_return	\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	scd	%0, %2					\n"
+ 		"	beqzl	%0, 1b					\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	sync						\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -497,12 +531,14 @@ static __inline__ long atomic64_sub_retu
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%1, %2		# atomic64_sub_return	\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	scd	%0, %2					\n"
+ 		"	beqz	%0, 1b					\n"
+ 		"	subu	%0, %1, %3				\n"
+ 		"	sync						\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -534,6 +570,7 @@ static __inline__ long atomic64_sub_if_p
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%1, %2		# atomic64_sub_if_positive\n"
+ 		"	dsubu	%0, %1, %3				\n"
+ 		"	bltz	%0, 1f					\n"
+@@ -541,6 +578,7 @@ static __inline__ long atomic64_sub_if_p
+ 		"	beqzl	%0, 1b					\n"
+ 		"	sync						\n"
+ 		"1:							\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+@@ -548,6 +586,7 @@ static __inline__ long atomic64_sub_if_p
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%1, %2		# atomic64_sub_if_positive\n"
+ 		"	dsubu	%0, %1, %3				\n"
+ 		"	bltz	%0, 1f					\n"
+@@ -555,6 +594,7 @@ static __inline__ long atomic64_sub_if_p
+ 		"	beqz	%0, 1b					\n"
+ 		"	sync						\n"
+ 		"1:							\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ 		: "Ir" (i), "m" (v->counter)
+ 		: "memory");
+diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
+--- a/include/asm-mips/bitops.h
++++ b/include/asm-mips/bitops.h
+@@ -12,20 +12,21 @@
+ #include <linux/config.h>
+ #include <linux/compiler.h>
+ #include <linux/types.h>
++#include <asm/bug.h>
+ #include <asm/byteorder.h>		/* sigh ... */
+ #include <asm/cpu-features.h>
+ 
+ #if (_MIPS_SZLONG == 32)
+ #define SZLONG_LOG 5
+ #define SZLONG_MASK 31UL
+-#define __LL	"ll	"
+-#define __SC	"sc	"
++#define __LL		"ll	"
++#define __SC		"sc	"
+ #define cpu_to_lelongp(x) cpu_to_le32p((__u32 *) (x))
+ #elif (_MIPS_SZLONG == 64)
+ #define SZLONG_LOG 6
+ #define SZLONG_MASK 63UL
+-#define __LL	"lld	"
+-#define __SC	"scd	"
++#define __LL		"lld	"
++#define __SC		"scd	"
+ #define cpu_to_lelongp(x) cpu_to_le64p((__u64 *) (x))
+ #endif
+ 
+@@ -72,18 +73,22 @@ static inline void set_bit(unsigned long
+ 
+ 	if (cpu_has_llsc && R10000_LLSC_WAR) {
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	" __LL "%0, %1			# set_bit	\n"
+ 		"	or	%0, %2					\n"
+-		"	"__SC	"%0, %1					\n"
++		"	" __SC	"%0, %1					\n"
+ 		"	beqzl	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (*m)
+ 		: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
+ 	} else if (cpu_has_llsc) {
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	" __LL "%0, %1			# set_bit	\n"
+ 		"	or	%0, %2					\n"
+-		"	"__SC	"%0, %1					\n"
++		"	" __SC	"%0, %1					\n"
+ 		"	beqz	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (*m)
+ 		: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
+ 	} else {
+@@ -132,18 +137,22 @@ static inline void clear_bit(unsigned lo
+ 
+ 	if (cpu_has_llsc && R10000_LLSC_WAR) {
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	" __LL "%0, %1			# clear_bit	\n"
+ 		"	and	%0, %2					\n"
+ 		"	" __SC "%0, %1					\n"
+ 		"	beqzl	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (*m)
+ 		: "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
+ 	} else if (cpu_has_llsc) {
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	" __LL "%0, %1			# clear_bit	\n"
+ 		"	and	%0, %2					\n"
+ 		"	" __SC "%0, %1					\n"
+ 		"	beqz	%0, 1b					\n"
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (*m)
+ 		: "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
+ 	} else {
+@@ -191,10 +200,12 @@ static inline void change_bit(unsigned l
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3				\n"
+ 		"1:	" __LL "%0, %1		# change_bit	\n"
+ 		"	xor	%0, %2				\n"
+-		"	"__SC	"%0, %1				\n"
++		"	" __SC	"%0, %1				\n"
+ 		"	beqzl	%0, 1b				\n"
++		"	.set	mips0				\n"
+ 		: "=&r" (temp), "=m" (*m)
+ 		: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
+ 	} else if (cpu_has_llsc) {
+@@ -202,10 +213,12 @@ static inline void change_bit(unsigned l
+ 		unsigned long temp;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3				\n"
+ 		"1:	" __LL "%0, %1		# change_bit	\n"
+ 		"	xor	%0, %2				\n"
+-		"	"__SC	"%0, %1				\n"
++		"	" __SC	"%0, %1				\n"
+ 		"	beqz	%0, 1b				\n"
++		"	.set	mips0				\n"
+ 		: "=&r" (temp), "=m" (*m)
+ 		: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
+ 	} else {
+@@ -253,14 +266,16 @@ static inline int test_and_set_bit(unsig
+ 		unsigned long temp, res;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
+ 		"	or	%2, %0, %3				\n"
+ 		"	" __SC	"%2, %1					\n"
+ 		"	beqzl	%2, 1b					\n"
+ 		"	and	%2, %0, %3				\n"
+ #ifdef CONFIG_SMP
+-		"sync							\n"
++		"	sync						\n"
+ #endif
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (*m), "=&r" (res)
+ 		: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
+ 		: "memory");
+@@ -271,16 +286,18 @@ static inline int test_and_set_bit(unsig
+ 		unsigned long temp, res;
+ 
+ 		__asm__ __volatile__(
+-		"	.set	noreorder	# test_and_set_bit	\n"
+-		"1:	" __LL "%0, %1					\n"
++		"	.set	push					\n"
++		"	.set	noreorder				\n"
++		"	.set	mips3					\n"
++		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
+ 		"	or	%2, %0, %3				\n"
+ 		"	" __SC	"%2, %1					\n"
+ 		"	beqz	%2, 1b					\n"
+ 		"	 and	%2, %0, %3				\n"
+ #ifdef CONFIG_SMP
+-		"sync							\n"
++		"	sync						\n"
+ #endif
+-		".set\treorder"
++		"	.set	pop					\n"
+ 		: "=&r" (temp), "=m" (*m), "=&r" (res)
+ 		: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
+ 		: "memory");
+@@ -343,15 +360,17 @@ static inline int test_and_clear_bit(uns
+ 		unsigned long temp, res;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
+ 		"	or	%2, %0, %3				\n"
+ 		"	xor	%2, %3					\n"
+-			__SC 	"%2, %1					\n"
++		"	" __SC 	"%2, %1					\n"
+ 		"	beqzl	%2, 1b					\n"
+ 		"	and	%2, %0, %3				\n"
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (*m), "=&r" (res)
+ 		: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
+ 		: "memory");
+@@ -362,17 +381,19 @@ static inline int test_and_clear_bit(uns
+ 		unsigned long temp, res;
+ 
+ 		__asm__ __volatile__(
+-		"	.set	noreorder	# test_and_clear_bit	\n"
+-		"1:	" __LL	"%0, %1					\n"
++		"	.set	push					\n"
++		"	.set	noreorder				\n"
++		"	.set	mips3					\n"
++		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
+ 		"	or	%2, %0, %3				\n"
+ 		"	xor	%2, %3					\n"
+-			__SC 	"%2, %1					\n"
++		"	" __SC 	"%2, %1					\n"
+ 		"	beqz	%2, 1b					\n"
+ 		"	 and	%2, %0, %3				\n"
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
+-		"	.set	reorder					\n"
++		"	.set	pop					\n"
+ 		: "=&r" (temp), "=m" (*m), "=&r" (res)
+ 		: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
+ 		: "memory");
+@@ -435,14 +456,16 @@ static inline int test_and_change_bit(un
+ 		unsigned long temp, res;
+ 
+ 		__asm__ __volatile__(
+-		"1:	" __LL	" %0, %1	# test_and_change_bit	\n"
++		"	.set	mips3					\n"
++		"1:	" __LL	"%0, %1		# test_and_change_bit	\n"
+ 		"	xor	%2, %0, %3				\n"
+-		"	"__SC	"%2, %1					\n"
++		"	" __SC	"%2, %1					\n"
+ 		"	beqzl	%2, 1b					\n"
+ 		"	and	%2, %0, %3				\n"
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
++		"	.set	mips0					\n"
+ 		: "=&r" (temp), "=m" (*m), "=&r" (res)
+ 		: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
+ 		: "memory");
+@@ -453,16 +476,18 @@ static inline int test_and_change_bit(un
+ 		unsigned long temp, res;
+ 
+ 		__asm__ __volatile__(
+-		"	.set	noreorder	# test_and_change_bit	\n"
+-		"1:	" __LL	" %0, %1				\n"
++		"	.set	push					\n"
++		"	.set	noreorder				\n"
++		"	.set	mips3					\n"
++		"1:	" __LL	"%0, %1		# test_and_change_bit	\n"
+ 		"	xor	%2, %0, %3				\n"
+-		"	"__SC	"\t%2, %1				\n"
++		"	" __SC	"\t%2, %1				\n"
+ 		"	beqz	%2, 1b					\n"
+ 		"	 and	%2, %0, %3				\n"
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
+-		"	.set	reorder					\n"
++		"	.set	pop					\n"
+ 		: "=&r" (temp), "=m" (*m), "=&r" (res)
+ 		: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
+ 		: "memory");
+@@ -523,22 +548,60 @@ static inline int test_bit(unsigned long
+ }
+ 
+ /*
+- * ffz - find first zero in word.
++ * Return the bit position (0..63) of the most significant 1 bit in a word
++ * Returns -1 if no 1 bit exists
++ */
++static inline int __ilog2(unsigned long x)
++{
++	int lz;
++
++	if (sizeof(x) == 4) {
++		__asm__ (
++		"	.set	push					\n"
++		"	.set	mips32					\n"
++		"	clz	%0, %1					\n"
++		"	.set	pop					\n"
++		: "=r" (lz)
++		: "r" (x));
++
++		return 31 - lz;
++	}
++
++	BUG_ON(sizeof(x) != 8);
++
++	__asm__ (
++	"	.set	push						\n"
++	"	.set	mips64						\n"
++	"	dclz	%0, %1						\n"
++	"	.set	pop						\n"
++	: "=r" (lz)
++	: "r" (x));
++
++	return 63 - lz;
++}
++
++/*
++ * __ffs - find first bit in word.
+  * @word: The word to search
+  *
+- * Undefined if no zero exists, so code should check against ~0UL first.
++ * Returns 0..SZLONG-1
++ * Undefined if no bit exists, so code should check against 0 first.
+  */
+-static inline unsigned long ffz(unsigned long word)
++static inline unsigned long __ffs(unsigned long word)
+ {
++#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
++	return __ilog2(word & -word);
++#else
+ 	int b = 0, s;
+ 
+-	word = ~word;
+ #ifdef CONFIG_32BIT
+ 	s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s;
+ 	s =  8; if (word << 24 != 0) s = 0; b += s; word >>= s;
+ 	s =  4; if (word << 28 != 0) s = 0; b += s; word >>= s;
+ 	s =  2; if (word << 30 != 0) s = 0; b += s; word >>= s;
+ 	s =  1; if (word << 31 != 0) s = 0; b += s;
++
++	return b;
+ #endif
+ #ifdef CONFIG_64BIT
+ 	s = 32; if (word << 32 != 0) s = 0; b += s; word >>= s;
+@@ -547,27 +610,92 @@ static inline unsigned long ffz(unsigned
+ 	s =  4; if (word << 60 != 0) s = 0; b += s; word >>= s;
+ 	s =  2; if (word << 62 != 0) s = 0; b += s; word >>= s;
+ 	s =  1; if (word << 63 != 0) s = 0; b += s;
+-#endif
+ 
+ 	return b;
++#endif
++#endif
+ }
+ 
+ /*
+- * __ffs - find first bit in word.
++ * ffs - find first bit set.
+  * @word: The word to search
+  *
+- * Undefined if no bit exists, so code should check against 0 first.
++ * Returns 1..SZLONG
++ * Returns 0 if no bit exists
+  */
+-static inline unsigned long __ffs(unsigned long word)
++
++static inline unsigned long ffs(unsigned long word)
++{
++	if (!word)
++		return 0;
++
++	return __ffs(word) + 1;
++}
++
++/*
++ * ffz - find first zero in word.
++ * @word: The word to search
++ *
++ * Undefined if no zero exists, so code should check against ~0UL first.
++ */
++static inline unsigned long ffz(unsigned long word)
++{
++	return __ffs (~word);
++}
++
++/*
++ * flz - find last zero in word.
++ * @word: The word to search
++ *
++ * Returns 0..SZLONG-1
++ * Undefined if no zero exists, so code should check against ~0UL first.
++ */
++static inline unsigned long flz(unsigned long word)
+ {
+-	return ffz(~word);
++#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
++	return __ilog2(~word);
++#else
++#ifdef CONFIG_32BIT
++	int r = 31, s;
++	word = ~word;
++	s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s;
++	s = 8;  if ((word & 0xff000000)) s = 0; r -= s; word <<= s;
++	s = 4;  if ((word & 0xf0000000)) s = 0; r -= s; word <<= s;
++	s = 2;  if ((word & 0xc0000000)) s = 0; r -= s; word <<= s;
++	s = 1;  if ((word & 0x80000000)) s = 0; r -= s;
++
++	return r;
++#endif
++#ifdef CONFIG_64BIT
++	int r = 63, s;
++	word = ~word;
++	s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s;
++	s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s;
++	s = 8;  if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s;
++	s = 4;  if ((word & 0xf000000000000000UL)) s = 0; r -= s; word <<= s;
++	s = 2;  if ((word & 0xc000000000000000UL)) s = 0; r -= s; word <<= s;
++	s = 1;  if ((word & 0x8000000000000000UL)) s = 0; r -= s;
++
++	return r;
++#endif
++#endif
+ }
+ 
+ /*
+- * fls: find last bit set.
++ * fls - find last bit set.
++ * @word: The word to search
++ *
++ * Returns 1..SZLONG
++ * Returns 0 if no bit exists
+  */
++static inline unsigned long fls(unsigned long word)
++{
++	if (word == 0)
++		return 0;
++
++	return flz(~word) + 1;
++}
+ 
+-#define fls(x) generic_fls(x)
+ 
+ /*
+  * find_next_zero_bit - find the first zero bit in a memory region
+@@ -704,17 +832,6 @@ static inline int sched_find_first_bit(c
+ }
+ 
+ /*
+- * ffs - find first bit set
+- * @x: the word to search
+- *
+- * This is defined the same way as
+- * the libc and compiler builtin ffs routines, therefore
+- * differs in spirit from the above ffz (man ffs).
+- */
+-
+-#define ffs(x) generic_ffs(x)
+-
+-/*
+  * hweightN - returns the hamming weight of a N-bit word
+  * @x: the word to weigh
+  *
+diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
+--- a/include/asm-mips/bootinfo.h
++++ b/include/asm-mips/bootinfo.h
+@@ -77,6 +77,7 @@
+ #define  MACH_SGI_IP27		1	/* Origin 200, Origin 2000, Onyx 2 */
+ #define  MACH_SGI_IP28		2	/* Indigo2 Impact		*/
+ #define  MACH_SGI_IP32		3	/* O2				*/
++#define  MACH_SGI_IP30		4	/* Octane, Octane2              */
+ 
+ /*
+  * Valid machtype for group COBALT
+@@ -136,6 +137,7 @@
+ #define MACH_GROUP_PHILIPS     14
+ #define  MACH_PHILIPS_NINO	0	/* Nino */
+ #define  MACH_PHILIPS_VELO	1	/* Velo */
++#define  MACH_PHILIPS_JBS	2	/* JBS */
+ 
+ /*
+  * Valid machtype for group Globespan
+@@ -159,6 +161,7 @@
+ #define  MACH_TOSHIBA_JMR3927	3	/* JMR-TX3927 CPU/IO board */
+ #define  MACH_TOSHIBA_RBTX4927	4
+ #define  MACH_TOSHIBA_RBTX4937	5
++#define  MACH_TOSHIBA_RBTX4938	6
+ 
+ #define GROUP_TOSHIBA_NAMES	{ "Pallas", "TopasCE", "JMR", "JMR TX3927", \
+ 				  "RBTX4927", "RBTX4937" }
+@@ -177,6 +180,8 @@
+ #define  MACH_MTX1		7       /* 4G MTX-1 Au1500-based board */
+ #define  MACH_PB1550		8       /* Au1550-based eval board */
+ #define  MACH_DB1550		9       /* Au1550-based eval board */
++#define  MACH_PB1200		10       /* Au1200-based eval board */
++#define  MACH_DB1200		11       /* Au1200-based eval board */
+ 
+ /*
+  * Valid machtype for group NEC_VR41XX
+diff --git a/include/asm-mips/break.h b/include/asm-mips/break.h
+--- a/include/asm-mips/break.h
++++ b/include/asm-mips/break.h
+@@ -28,6 +28,7 @@
+ #define BRK_NORLD	10	/* No rld found - not used by Linux/MIPS */
+ #define _BRK_THREADBP	11	/* For threads, user bp (used by debuggers) */
+ #define BRK_BUG		512	/* Used by BUG() */
++#define BRK_KDB		513	/* Used in KDB_ENTER() */
+ #define BRK_MULOVF	1023	/* Multiply overflow */
+ 
+ #endif /* __ASM_BREAK_H */
+diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h
+--- a/include/asm-mips/bug.h
++++ b/include/asm-mips/bug.h
+@@ -1,16 +1,21 @@
+ #ifndef __ASM_BUG_H
+ #define __ASM_BUG_H
+ 
+-#include <asm/break.h>
++#include <linux/config.h>
+ 
+ #ifdef CONFIG_BUG
+-#define HAVE_ARCH_BUG
++
++#include <asm/break.h>
++
+ #define BUG()								\
+ do {									\
+ 	__asm__ __volatile__("break %0" : : "i" (BRK_BUG));		\
+ } while (0)
++
++#define HAVE_ARCH_BUG
++
+ #endif
+ 
+ #include <asm-generic/bug.h>
+ 
+-#endif
++#endif /* __ASM_BUG_H */
+diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h
+--- a/include/asm-mips/bugs.h
++++ b/include/asm-mips/bugs.h
+@@ -8,12 +8,18 @@
+ #define _ASM_BUGS_H
+ 
+ #include <linux/config.h>
++#include <linux/delay.h>
++#include <asm/cpu.h>
++#include <asm/cpu-info.h>
+ 
+ extern void check_bugs32(void);
+ extern void check_bugs64(void);
+ 
+ static inline void check_bugs(void)
+ {
++	unsigned int cpu = smp_processor_id();
++
++	cpu_data[cpu].udelay_val = loops_per_jiffy;
+ 	check_bugs32();
+ #ifdef CONFIG_64BIT
+ 	check_bugs64();
+diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h
+--- a/include/asm-mips/cache.h
++++ b/include/asm-mips/cache.h
+@@ -10,6 +10,7 @@
+ #define _ASM_CACHE_H
+ 
+ #include <linux/config.h>
++#include <kmalloc.h>
+ 
+ #define L1_CACHE_SHIFT		CONFIG_MIPS_L1_CACHE_SHIFT
+ #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+@@ -18,6 +19,4 @@
+ #define SMP_CACHE_SHIFT		L1_CACHE_SHIFT
+ #define SMP_CACHE_BYTES		L1_CACHE_BYTES
+ 
+-#define ARCH_KMALLOC_MINALIGN	8
+-
+ #endif /* _ASM_CACHE_H */
+diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
+--- a/include/asm-mips/cacheflush.h
++++ b/include/asm-mips/cacheflush.h
+@@ -49,17 +49,29 @@ static inline void flush_dcache_page(str
+ 
+ extern void (*flush_icache_page)(struct vm_area_struct *vma,
+ 	struct page *page);
+-extern void (*flush_icache_range)(unsigned long start, unsigned long end);
++extern void (*flush_icache_range)(unsigned long __user start,
++	unsigned long __user end);
+ #define flush_cache_vmap(start, end)		flush_cache_all()
+ #define flush_cache_vunmap(start, end)		flush_cache_all()
+ 
+-#define copy_to_user_page(vma, page, vaddr, dst, src, len)		\
+-do {									\
+-	memcpy(dst, (void *) src, len);					\
+-	flush_icache_page(vma, page);					\
+-} while (0)
+-#define copy_from_user_page(vma, page, vaddr, dst, src, len)		\
+-	memcpy(dst, src, len)
++static inline void copy_to_user_page(struct vm_area_struct *vma,
++	struct page *page, unsigned long vaddr, void *dst, const void *src,
++	unsigned long len)
++{
++	if (cpu_has_dc_aliases)
++		flush_cache_page(vma, vaddr, page_to_pfn(page));
++	memcpy(dst, src, len);
++	flush_icache_page(vma, page);
++}
++
++static inline void copy_from_user_page(struct vm_area_struct *vma,
++	struct page *page, unsigned long vaddr, void *dst, const void *src,
++	unsigned long len)
++{
++	if (cpu_has_dc_aliases)
++		flush_cache_page(vma, vaddr, page_to_pfn(page));
++	memcpy(dst, src, len);
++}
+ 
+ extern void (*flush_cache_sigtramp)(unsigned long addr);
+ extern void (*flush_icache_all)(void);
+@@ -78,4 +90,7 @@ extern void (*flush_data_cache_page)(uns
+ #define ClearPageDcacheDirty(page)	\
+ 	clear_bit(PG_dcache_dirty, &(page)->flags)
+ 
++/* Run kernel code uncached, useful for cache probing functions. */
++unsigned long __init run_uncached(void *func);
++
+ #endif /* _ASM_CACHEFLUSH_H */
+diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
+--- a/include/asm-mips/checksum.h
++++ b/include/asm-mips/checksum.h
+@@ -34,8 +34,9 @@ unsigned int csum_partial(const unsigned
+  * this is a new version of the above that records errors it finds in *errp,
+  * but continues and zeros the rest of the buffer.
+  */
+-unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
+-                                         unsigned int sum, int *errp);
++unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
++					 unsigned char *dst, int len,
++					 unsigned int sum, int *errp);
+ 
+ /*
+  * Copy and checksum to user
+@@ -70,14 +71,15 @@ unsigned int csum_partial_copy_nocheck(c
+ static inline unsigned short int csum_fold(unsigned int sum)
+ {
+ 	__asm__(
+-	".set\tnoat\t\t\t# csum_fold\n\t"
+-	"sll\t$1,%0,16\n\t"
+-	"addu\t%0,$1\n\t"
+-	"sltu\t$1,%0,$1\n\t"
+-	"srl\t%0,%0,16\n\t"
+-	"addu\t%0,$1\n\t"
+-	"xori\t%0,0xffff\n\t"
+-	".set\tat"
++	"	.set	push		# csum_fold\n"
++	"	.set	noat		\n"
++	"	sll	$1, %0, 16	\n"
++	"	addu	%0, $1		\n"
++	"	sltu	$1, %0, $1	\n"
++	"	srl	%0, %0, 16	\n"
++	"	addu	%0, $1		\n"
++	"	xori	%0, 0xffff	\n"
++	"	.set	pop"
+ 	: "=r" (sum)
+ 	: "0" (sum));
+ 
+@@ -127,29 +129,30 @@ static inline unsigned int csum_tcpudp_n
+ 	unsigned int sum)
+ {
+ 	__asm__(
+-	".set\tnoat\t\t\t# csum_tcpudp_nofold\n\t"
++	"	.set	push		# csum_tcpudp_nofold\n"
++	"	.set	noat		\n"
+ #ifdef CONFIG_32BIT
+-	"addu\t%0, %2\n\t"
+-	"sltu\t$1, %0, %2\n\t"
+-	"addu\t%0, $1\n\t"
+-
+-	"addu\t%0, %3\n\t"
+-	"sltu\t$1, %0, %3\n\t"
+-	"addu\t%0, $1\n\t"
+-
+-	"addu\t%0, %4\n\t"
+-	"sltu\t$1, %0, %4\n\t"
+-	"addu\t%0, $1\n\t"
++	"	addu	%0, %2		\n"
++	"	sltu	$1, %0, %2	\n"
++	"	addu	%0, $1		\n"
++
++	"	addu	%0, %3		\n"
++	"	sltu	$1, %0, %3	\n"
++	"	addu	%0, $1		\n"
++
++	"	addu	%0, %4		\n"
++	"	sltu	$1, %0, %4	\n"
++	"	addu	%0, $1		\n"
+ #endif
+ #ifdef CONFIG_64BIT
+-	"daddu\t%0, %2\n\t"
+-	"daddu\t%0, %3\n\t"
+-	"daddu\t%0, %4\n\t"
+-	"dsll32\t$1, %0, 0\n\t"
+-	"daddu\t%0, $1\n\t"
+-	"dsrl32\t%0, %0, 0\n\t"
++	"	daddu	%0, %2		\n"
++	"	daddu	%0, %3		\n"
++	"	daddu	%0, %4		\n"
++	"	dsll32	$1, %0, 0	\n"
++	"	daddu	%0, $1		\n"
++	"	dsra32	%0, %0, 0	\n"
+ #endif
+-	".set\tat"
++	"	.set	pop"
+ 	: "=r" (sum)
+ 	: "0" (daddr), "r"(saddr),
+ #ifdef __MIPSEL__
+@@ -192,57 +195,57 @@ static __inline__ unsigned short int csu
+ 						     unsigned int sum)
+ {
+ 	__asm__(
+-	".set\tpush\t\t\t# csum_ipv6_magic\n\t"
+-	".set\tnoreorder\n\t"
+-	".set\tnoat\n\t"
+-	"addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t"
+-	"sltu\t$1, %0, %5\n\t"
+-	"addu\t%0, $1\n\t"
+-
+-	"addu\t%0, %6\t\t\t# csum\n\t"
+-	"sltu\t$1, %0, %6\n\t"
+-	"lw\t%1, 0(%2)\t\t\t# four words source address\n\t"
+-	"addu\t%0, $1\n\t"
+-	"addu\t%0, %1\n\t"
+-	"sltu\t$1, %0, %1\n\t"
+-
+-	"lw\t%1, 4(%2)\n\t"
+-	"addu\t%0, $1\n\t"
+-	"addu\t%0, %1\n\t"
+-	"sltu\t$1, %0, %1\n\t"
+-
+-	"lw\t%1, 8(%2)\n\t"
+-	"addu\t%0, $1\n\t"
+-	"addu\t%0, %1\n\t"
+-	"sltu\t$1, %0, %1\n\t"
+-
+-	"lw\t%1, 12(%2)\n\t"
+-	"addu\t%0, $1\n\t"
+-	"addu\t%0, %1\n\t"
+-	"sltu\t$1, %0, %1\n\t"
+-
+-	"lw\t%1, 0(%3)\n\t"
+-	"addu\t%0, $1\n\t"
+-	"addu\t%0, %1\n\t"
+-	"sltu\t$1, %0, %1\n\t"
+-
+-	"lw\t%1, 4(%3)\n\t"
+-	"addu\t%0, $1\n\t"
+-	"addu\t%0, %1\n\t"
+-	"sltu\t$1, %0, %1\n\t"
+-
+-	"lw\t%1, 8(%3)\n\t"
+-	"addu\t%0, $1\n\t"
+-	"addu\t%0, %1\n\t"
+-	"sltu\t$1, %0, %1\n\t"
+-
+-	"lw\t%1, 12(%3)\n\t"
+-	"addu\t%0, $1\n\t"
+-	"addu\t%0, %1\n\t"
+-	"sltu\t$1, %0, %1\n\t"
++	"	.set	push		# csum_ipv6_magic\n"
++	"	.set	noreorder	\n"
++	"	.set	noat		\n"
++	"	addu	%0, %5		# proto (long in network byte order)\n"
++	"	sltu	$1, %0, %5	\n"
++	"	addu	%0, $1		\n"
++
++	"	addu	%0, %6		# csum\n"
++	"	sltu	$1, %0, %6	\n"
++	"	lw	%1, 0(%2)	# four words source address\n"
++	"	addu	%0, $1		\n"
++	"	addu	%0, %1		\n"
++	"	sltu	$1, %0, %1	\n"
++
++	"	lw	%1, 4(%2)	\n"
++	"	addu	%0, $1		\n"
++	"	addu	%0, %1		\n"
++	"	sltu	$1, %0, %1	\n"
++
++	"	lw	%1, 8(%2)	\n"
++	"	addu	%0, $1		\n"
++	"	addu	%0, %1		\n"
++	"	sltu	$1, %0, %1	\n"
++
++	"	lw	%1, 12(%2)	\n"
++	"	addu	%0, $1		\n"
++	"	addu	%0, %1		\n"
++	"	sltu	$1, %0, %1	\n"
++
++	"	lw	%1, 0(%3)	\n"
++	"	addu	%0, $1		\n"
++	"	addu	%0, %1		\n"
++	"	sltu	$1, %0, %1	\n"
++
++	"	lw	%1, 4(%3)	\n"
++	"	addu	%0, $1		\n"
++	"	addu	%0, %1		\n"
++	"	sltu	$1, %0, %1	\n"
++
++	"	lw	%1, 8(%3)	\n"
++	"	addu	%0, $1		\n"
++	"	addu	%0, %1		\n"
++	"	sltu	$1, %0, %1	\n"
++
++	"	lw	%1, 12(%3)	\n"
++	"	addu	%0, $1		\n"
++	"	addu	%0, %1		\n"
++	"	sltu	$1, %0, %1	\n"
+ 
+-	"addu\t%0, $1\t\t\t# Add final carry\n\t"
+-	".set\tpop"
++	"	addu	%0, $1		# Add final carry\n"
++	"	.set	pop"
+ 	: "=r" (sum), "=r" (proto)
+ 	: "r" (saddr), "r" (daddr),
+ 	  "0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
+diff --git a/include/asm-mips/cobalt/cobalt.h b/include/asm-mips/cobalt/cobalt.h
+--- a/include/asm-mips/cobalt/cobalt.h
++++ b/include/asm-mips/cobalt/cobalt.h
+@@ -19,18 +19,23 @@
+  *     9  - PCI
+  *    14  - IDE0
+  *    15  - IDE1
+- *
++ */
++#define COBALT_QUBE_SLOT_IRQ	9
++
++/*
+  * CPU IRQs  are 16 ... 23
+  */
+-#define COBALT_TIMER_IRQ	18
+-#define COBALT_SCC_IRQ          19		/* pre-production has 85C30 */
+-#define COBALT_RAQ_SCSI_IRQ	19
+-#define COBALT_ETH0_IRQ		19
+-#define COBALT_ETH1_IRQ		20
+-#define COBALT_SERIAL_IRQ	21
+-#define COBALT_SCSI_IRQ         21
+-#define COBALT_VIA_IRQ		22		/* Chained to VIA ISA bridge */
+-#define COBALT_QUBE_SLOT_IRQ	23
++#define COBALT_CPU_IRQ		16
++
++#define COBALT_GALILEO_IRQ	(COBALT_CPU_IRQ + 2)
++#define COBALT_SCC_IRQ          (COBALT_CPU_IRQ + 3)	/* pre-production has 85C30 */
++#define COBALT_RAQ_SCSI_IRQ	(COBALT_CPU_IRQ + 3)
++#define COBALT_ETH0_IRQ		(COBALT_CPU_IRQ + 3)
++#define COBALT_QUBE1_ETH0_IRQ	(COBALT_CPU_IRQ + 4)
++#define COBALT_ETH1_IRQ		(COBALT_CPU_IRQ + 4)
++#define COBALT_SERIAL_IRQ	(COBALT_CPU_IRQ + 5)
++#define COBALT_SCSI_IRQ         (COBALT_CPU_IRQ + 5)
++#define COBALT_VIA_IRQ		(COBALT_CPU_IRQ + 6)	/* Chained to VIA ISA bridge */
+ 
+ /*
+  * PCI configuration space manifest constants.  These are wired into
+@@ -69,16 +74,21 @@
+  * Most of this really should go into a separate GT64111 header file.
+  */
+ #define GT64111_IO_BASE		0x10000000UL
++#define GT64111_IO_END		0x11ffffffUL
++#define GT64111_MEM_BASE	0x12000000UL
++#define GT64111_MEM_END		0x13ffffffUL
+ #define GT64111_BASE		0x14000000UL
+-#define GALILEO_REG(ofs)	(KSEG0 + GT64111_BASE + (unsigned long)(ofs))
++#define GALILEO_REG(ofs)	CKSEG1ADDR(GT64111_BASE + (unsigned long)(ofs))
+ 
+ #define GALILEO_INL(port)	(*(volatile unsigned int *) GALILEO_REG(port))
+ #define GALILEO_OUTL(val, port)						\
+ do {									\
+-	*(volatile unsigned int *) GALILEO_REG(port) = (port);		\
++	*(volatile unsigned int *) GALILEO_REG(port) = (val);		\
+ } while (0)
+ 
+-#define GALILEO_T0EXP		0x0100
++#define GALILEO_INTR_T0EXP	(1 << 8)
++#define GALILEO_INTR_RETRY_CTR	(1 << 20)
++
+ #define GALILEO_ENTC0		0x01
+ #define GALILEO_SELTC0		0x02
+ 
+@@ -86,5 +96,21 @@ do {									\
+ 	GALILEO_OUTL((0x80000000 | (PCI_SLOT (devfn) << 11) |		\
+ 		(PCI_FUNC (devfn) << 8) | (where)), GT_PCI0_CFGADDR_OFS)
+ 
++#define COBALT_LED_PORT		(*(volatile unsigned char *) CKSEG1ADDR(0x1c000000))
++# define COBALT_LED_BAR_LEFT	(1 << 0)	/* Qube */
++# define COBALT_LED_BAR_RIGHT	(1 << 1)	/* Qube */
++# define COBALT_LED_WEB		(1 << 2)	/* RaQ */
++# define COBALT_LED_POWER_OFF	(1 << 3)	/* RaQ */
++# define COBALT_LED_RESET	0x0f
++
++#define COBALT_KEY_PORT		((~*(volatile unsigned int *) CKSEG1ADDR(0x1d000000) >> 24) & COBALT_KEY_MASK)
++# define COBALT_KEY_CLEAR	(1 << 1)
++# define COBALT_KEY_LEFT	(1 << 2)
++# define COBALT_KEY_UP		(1 << 3)
++# define COBALT_KEY_DOWN	(1 << 4)
++# define COBALT_KEY_RIGHT	(1 << 5)
++# define COBALT_KEY_ENTER	(1 << 6)
++# define COBALT_KEY_SELECT	(1 << 7)
++# define COBALT_KEY_MASK	0xfe
+ 
+ #endif /* __ASM_COBALT_H */
+diff --git a/include/asm-mips/cobalt/mach-gt64120.h b/include/asm-mips/cobalt/mach-gt64120.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/cobalt/mach-gt64120.h
+@@ -0,0 +1 @@
++/* there's something here ... in the dark */
+diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h
+--- a/include/asm-mips/compat.h
++++ b/include/asm-mips/compat.h
+@@ -15,10 +15,10 @@ typedef s32		compat_clock_t;
+ typedef s32		compat_suseconds_t;
+ 
+ typedef s32		compat_pid_t;
+-typedef u32		__compat_uid_t;
+-typedef u32		__compat_gid_t;
+-typedef u32		__compat_uid32_t;
+-typedef u32		__compat_gid32_t;
++typedef s32		__compat_uid_t;
++typedef s32		__compat_gid_t;
++typedef __compat_uid_t	__compat_uid32_t;
++typedef __compat_gid_t	__compat_gid32_t;
+ typedef u32		compat_mode_t;
+ typedef u32		compat_ino_t;
+ typedef u32		compat_dev_t;
+@@ -54,8 +54,8 @@ struct compat_stat {
+ 	compat_ino_t	st_ino;
+ 	compat_mode_t	st_mode;
+ 	compat_nlink_t	st_nlink;
+-	__compat_uid32_t	st_uid;
+-	__compat_gid32_t	st_gid;
++	__compat_uid_t	st_uid;
++	__compat_gid_t	st_gid;
+ 	compat_dev_t	st_rdev;
+ 	s32		st_pad2[2];
+ 	compat_off_t	st_size;
+diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
+--- a/include/asm-mips/cpu-features.h
++++ b/include/asm-mips/cpu-features.h
+@@ -4,6 +4,7 @@
+  * for more details.
+  *
+  * Copyright (C) 2003, 2004 Ralf Baechle
++ * Copyright (C) 2004  Maciej W. Rozycki
+  */
+ #ifndef __ASM_CPU_FEATURES_H
+ #define __ASM_CPU_FEATURES_H
+@@ -24,8 +25,19 @@
+ #ifndef cpu_has_4kex
+ #define cpu_has_4kex		(cpu_data[0].options & MIPS_CPU_4KEX)
+ #endif
+-#ifndef cpu_has_4ktlb
+-#define cpu_has_4ktlb		(cpu_data[0].options & MIPS_CPU_4KTLB)
++#ifndef cpu_has_3k_cache
++#define cpu_has_3k_cache	(cpu_data[0].options & MIPS_CPU_3K_CACHE)
++#endif
++#define cpu_has_6k_cache	0
++#define cpu_has_8k_cache	0
++#ifndef cpu_has_4k_cache
++#define cpu_has_4k_cache	(cpu_data[0].options & MIPS_CPU_4K_CACHE)
++#endif
++#ifndef cpu_has_tx39_cache
++#define cpu_has_tx39_cache	(cpu_data[0].options & MIPS_CPU_TX39_CACHE)
++#endif
++#ifndef cpu_has_sb1_cache
++#define cpu_has_sb1_cache	(cpu_data[0].options & MIPS_CPU_SB1_CACHE)
+ #endif
+ #ifndef cpu_has_fpu
+ #define cpu_has_fpu		(cpu_data[0].options & MIPS_CPU_FPU)
+@@ -39,9 +51,6 @@
+ #ifndef cpu_has_watch
+ #define cpu_has_watch		(cpu_data[0].options & MIPS_CPU_WATCH)
+ #endif
+-#ifndef cpu_has_mips16
+-#define cpu_has_mips16		(cpu_data[0].options & MIPS_CPU_MIPS16)
+-#endif
+ #ifndef cpu_has_divec
+ #define cpu_has_divec		(cpu_data[0].options & MIPS_CPU_DIVEC)
+ #endif
+@@ -66,6 +75,18 @@
+ #ifndef cpu_has_llsc
+ #define cpu_has_llsc		(cpu_data[0].options & MIPS_CPU_LLSC)
+ #endif
++#ifndef cpu_has_mips16
++#define cpu_has_mips16		(cpu_data[0].ases & MIPS_ASE_MIPS16)
++#endif
++#ifndef cpu_has_mdmx
++#define cpu_has_mdmx           (cpu_data[0].ases & MIPS_ASE_MDMX)
++#endif
++#ifndef cpu_has_mips3d
++#define cpu_has_mips3d         (cpu_data[0].ases & MIPS_ASE_MIPS3D)
++#endif
++#ifndef cpu_has_smartmips
++#define cpu_has_smartmips      (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
++#endif
+ #ifndef cpu_has_vtag_icache
+ #define cpu_has_vtag_icache	(cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
+ #endif
+@@ -95,15 +116,16 @@
+ #endif
+ #endif
+ 
+-/*
+- * Certain CPUs may throw bizarre exceptions if not the whole cacheline
+- * contains valid instructions.  For these we ensure proper alignment of
+- * signal trampolines and pad them to the size of a full cache lines with
+- * nops.  This is also used in structure definitions so can't be a test macro
+- * like the others.
+- */
+-#ifndef PLAT_TRAMPOLINE_STUFF_LINE
+-#define PLAT_TRAMPOLINE_STUFF_LINE	0UL
++#ifndef cpu_has_dsp
++#define cpu_has_dsp		(cpu_data[0].ases & MIPS_ASE_DSP)
++#endif
++
++#ifdef CONFIG_MIPS_MT
++#ifndef cpu_has_mipsmt
++# define cpu_has_mipsmt		(cpu_data[0].ases & MIPS_ASE_MIPSMT)
++#endif
++#else
++# define cpu_has_mipsmt		0
+ #endif
+ 
+ #ifdef CONFIG_32BIT
+@@ -142,6 +164,22 @@
+ # endif
+ #endif
+ 
++#ifdef CONFIG_CPU_MIPSR2
++# if defined(CONFIG_CPU_MIPSR2_IRQ_VI) && !defined(cpu_has_vint)
++#  define cpu_has_vint		(cpu_data[0].options & MIPS_CPU_VINT)
++# else
++#  define cpu_has_vint			0
++# endif
++# if defined(CONFIG_CPU_MIPSR2_IRQ_EI) && !defined(cpu_has_veic)
++#  define cpu_has_veic		(cpu_data[0].options & MIPS_CPU_VEIC)
++# else
++#  define cpu_has_veic			0
++# endif
++#else
++# define cpu_has_vint			0
++# define cpu_has_veic			0
++#endif
++
+ #ifndef cpu_has_subset_pcaches
+ #define cpu_has_subset_pcaches	(cpu_data[0].options & MIPS_CPU_SUBSET_CACHES)
+ #endif
+diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
+--- a/include/asm-mips/cpu-info.h
++++ b/include/asm-mips/cpu-info.h
+@@ -7,6 +7,7 @@
+  * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle
+  * Copyright (C) 1996 Paul M. Antoine
+  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
++ * Copyright (C) 2004  Maciej W. Rozycki
+  */
+ #ifndef __ASM_CPU_INFO_H
+ #define __ASM_CPU_INFO_H
+@@ -61,6 +62,7 @@ struct cpuinfo_mips {
+ 	 * Capability and feature descriptor structure for MIPS CPU
+ 	 */
+ 	unsigned long		options;
++	unsigned long		ases;
+ 	unsigned int		processor_id;
+ 	unsigned int		fpu_id;
+ 	unsigned int		cputype;
+diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
+--- a/include/asm-mips/cpu.h
++++ b/include/asm-mips/cpu.h
+@@ -3,6 +3,7 @@
+  *        various MIPS cpu types.
+  *
+  * Copyright (C) 1996 David S. Miller (dm at engr.sgi.com)
++ * Copyright (C) 2004  Maciej W. Rozycki
+  */
+ #ifndef _ASM_CPU_H
+ #define _ASM_CPU_H
+@@ -22,12 +23,17 @@
+    spec.
+ */
+ 
+-#define PRID_COMP_LEGACY       0x000000
+-#define PRID_COMP_MIPS         0x010000
+-#define PRID_COMP_BROADCOM     0x020000
+-#define PRID_COMP_ALCHEMY      0x030000
+-#define PRID_COMP_SIBYTE       0x040000
+-#define PRID_COMP_SANDCRAFT    0x050000
++#define PRID_COMP_LEGACY	0x000000
++#define PRID_COMP_MIPS		0x010000
++#define PRID_COMP_BROADCOM	0x020000
++#define PRID_COMP_ALCHEMY	0x030000
++#define PRID_COMP_SIBYTE	0x040000
++#define PRID_COMP_SANDCRAFT	0x050000
++#define PRID_COMP_PHILIPS	0x060000
++#define PRID_COMP_TOSHIBA	0x070000
++#define PRID_COMP_LSI		0x080000
++#define PRID_COMP_LEXRA		0x0b0000
++
+ 
+ /*
+  * Assigned values for the product ID register.  In order to detect a
+@@ -46,6 +52,7 @@
+ #define PRID_IMP_VR41XX		0x0c00
+ #define PRID_IMP_R12000		0x0e00
+ #define PRID_IMP_R8000		0x1000
++#define PRID_IMP_PR4450		0x1200
+ #define PRID_IMP_R4600		0x2000
+ #define PRID_IMP_R4700		0x2100
+ #define PRID_IMP_TX39		0x2200
+@@ -60,6 +67,13 @@
+ #define PRID_IMP_RM9000		0x3400
+ #define PRID_IMP_R5432		0x5400
+ #define PRID_IMP_R5500		0x5500
++
++#define PRID_IMP_UNKNOWN	0xff00
++
++/*
++ * These are the PRID's for when 23:16 == PRID_COMP_MIPS
++ */
++
+ #define PRID_IMP_4KC		0x8000
+ #define PRID_IMP_5KC		0x8100
+ #define PRID_IMP_20KC		0x8200
+@@ -71,14 +85,15 @@
+ #define PRID_IMP_4KEMPR2	0x9100
+ #define PRID_IMP_4KSD		0x9200
+ #define PRID_IMP_24K		0x9300
+-
+-#define PRID_IMP_UNKNOWN	0xff00
++#define PRID_IMP_34K		0x9500
++#define PRID_IMP_24KE		0x9600
+ 
+ /*
+  * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
+  */
+ 
+ #define PRID_IMP_SB1            0x0100
++#define PRID_IMP_SB1A           0x1100
+ 
+ /*
+  * These are the PRID's for when 23:16 == PRID_COMP_SANDCRAFT
+@@ -177,7 +192,11 @@
+ #define CPU_VR4133		56
+ #define CPU_AU1550		57
+ #define CPU_24K			58
+-#define CPU_LAST		58
++#define CPU_AU1200		59
++#define CPU_34K			60
++#define CPU_PR4450		61
++#define CPU_SB1A		62
++#define CPU_LAST		62
+ 
+ /*
+  * ISA Level encodings
+@@ -200,23 +219,37 @@
+  * CPU Option encodings
+  */
+ #define MIPS_CPU_TLB		0x00000001 /* CPU has TLB */
+-/* Leave a spare bit for variant MMU types... */
+-#define MIPS_CPU_4KEX		0x00000004 /* "R4K" exception model */
+-#define MIPS_CPU_4KTLB		0x00000008 /* "R4K" TLB handler */
+-#define MIPS_CPU_FPU		0x00000010 /* CPU has FPU */
+-#define MIPS_CPU_32FPR		0x00000020 /* 32 dbl. prec. FP registers */
+-#define MIPS_CPU_COUNTER	0x00000040 /* Cycle count/compare */
+-#define MIPS_CPU_WATCH		0x00000080 /* watchpoint registers */
+-#define MIPS_CPU_MIPS16		0x00000100 /* code compression */
+-#define MIPS_CPU_DIVEC		0x00000200 /* dedicated interrupt vector */
+-#define MIPS_CPU_VCE		0x00000400 /* virt. coherence conflict possible */
+-#define MIPS_CPU_CACHE_CDEX_P	0x00000800 /* Create_Dirty_Exclusive CACHE op */
+-#define MIPS_CPU_CACHE_CDEX_S	0x00001000 /* ... same for seconary cache ... */
+-#define MIPS_CPU_MCHECK		0x00002000 /* Machine check exception */
+-#define MIPS_CPU_EJTAG		0x00004000 /* EJTAG exception */
+-#define MIPS_CPU_NOFPUEX	0x00008000 /* no FPU exception */
+-#define MIPS_CPU_LLSC		0x00010000 /* CPU has ll/sc instructions */
+-#define MIPS_CPU_SUBSET_CACHES	0x00020000 /* P-cache subset enforced */
+-#define MIPS_CPU_PREFETCH	0x00040000 /* CPU has usable prefetch */
++#define MIPS_CPU_4KEX		0x00000002 /* "R4K" exception model */
++#define MIPS_CPU_3K_CACHE	0x00000004 /* R3000-style caches */
++#define MIPS_CPU_4K_CACHE	0x00000008 /* R4000-style caches */
++#define MIPS_CPU_TX39_CACHE	0x00000010 /* TX3900-style caches */
++#define MIPS_CPU_SB1_CACHE	0x00000020 /* SB1-style caches */
++#define MIPS_CPU_FPU		0x00000040 /* CPU has FPU */
++#define MIPS_CPU_32FPR		0x00000080 /* 32 dbl. prec. FP registers */
++#define MIPS_CPU_COUNTER	0x00000100 /* Cycle count/compare */
++#define MIPS_CPU_WATCH		0x00000200 /* watchpoint registers */
++#define MIPS_CPU_DIVEC		0x00000400 /* dedicated interrupt vector */
++#define MIPS_CPU_VCE		0x00000800 /* virt. coherence conflict possible */
++#define MIPS_CPU_CACHE_CDEX_P	0x00001000 /* Create_Dirty_Exclusive CACHE op */
++#define MIPS_CPU_CACHE_CDEX_S	0x00002000 /* ... same for seconary cache ... */
++#define MIPS_CPU_MCHECK		0x00004000 /* Machine check exception */
++#define MIPS_CPU_EJTAG		0x00008000 /* EJTAG exception */
++#define MIPS_CPU_NOFPUEX	0x00010000 /* no FPU exception */
++#define MIPS_CPU_LLSC		0x00020000 /* CPU has ll/sc instructions */
++#define MIPS_CPU_SUBSET_CACHES	0x00040000 /* P-cache subset enforced */
++#define MIPS_CPU_PREFETCH	0x00080000 /* CPU has usable prefetch */
++#define MIPS_CPU_VINT		0x00100000 /* CPU supports MIPSR2 vectored interrupts */
++#define MIPS_CPU_VEIC		0x00200000 /* CPU supports MIPSR2 external interrupt controller mode */
++
++/*
++ * CPU ASE encodings
++ */
++#define MIPS_ASE_MIPS16		0x00000001 /* code compression */
++#define MIPS_ASE_MDMX		0x00000002 /* MIPS digital media extension */
++#define MIPS_ASE_MIPS3D		0x00000004 /* MIPS-3D */
++#define MIPS_ASE_SMARTMIPS	0x00000008 /* SmartMIPS */
++#define MIPS_ASE_DSP		0x00000010 /* Signal Processing ASE */
++#define MIPS_ASE_MIPSMT		0x00000020 /* CPU supports MIPS MT */
++
+ 
+ #endif /* _ASM_CPU_H */
+diff --git a/include/asm-mips/dec/ecc.h b/include/asm-mips/dec/ecc.h
+--- a/include/asm-mips/dec/ecc.h
++++ b/include/asm-mips/dec/ecc.h
+@@ -49,7 +49,8 @@ struct pt_regs;
+ 
+ extern void dec_ecc_be_init(void);
+ extern int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup);
+-extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs);
++extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id,
++					struct pt_regs *regs);
+ #endif
+ 
+ #endif /* __ASM_MIPS_DEC_ECC_H */
+diff --git a/include/asm-mips/dec/ioasic_addrs.h b/include/asm-mips/dec/ioasic_addrs.h
+--- a/include/asm-mips/dec/ioasic_addrs.h
++++ b/include/asm-mips/dec/ioasic_addrs.h
+@@ -45,7 +45,8 @@
+ 
+ 
+ /*
+- * Offsets for I/O ASIC registers (relative to (system_base + IOASIC_IOCTL)).
++ * Offsets for I/O ASIC registers
++ * (relative to (dec_kn_slot_base + IOASIC_IOCTL)).
+  */
+ 					/* all systems */
+ #define IO_REG_SCSI_DMA_P	0x00	/* SCSI DMA Pointer */
+diff --git a/include/asm-mips/dec/kn01.h b/include/asm-mips/dec/kn01.h
+--- a/include/asm-mips/dec/kn01.h
++++ b/include/asm-mips/dec/kn01.h
+@@ -8,14 +8,12 @@
+  *
+  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
+  * are by courtesy of Chris Fraser.
+- * Copyright (C) 2002, 2003  Maciej W. Rozycki
++ * Copyright (C) 2002, 2003, 2005  Maciej W. Rozycki
+  */
+ #ifndef __ASM_MIPS_DEC_KN01_H
+ #define __ASM_MIPS_DEC_KN01_H
+ 
+-#include <asm/addrspace.h>
+-
+-#define KN01_SLOT_BASE	KSEG1ADDR(0x10000000)
++#define KN01_SLOT_BASE	0x10000000
+ #define KN01_SLOT_SIZE	0x01000000
+ 
+ /*
+@@ -41,17 +39,9 @@
+ 
+ 
+ /*
+- * Some port addresses...
+- */
+-#define KN01_LANCE_BASE (KN01_SLOT_BASE + KN01_LANCE)	/* 0xB8000000 */
+-#define KN01_DZ11_BASE	(KN01_SLOT_BASE + KN01_DZ11)	/* 0xBC000000 */
+-#define KN01_RTC_BASE	(KN01_SLOT_BASE + KN01_RTC)	/* 0xBD000000 */
+-
+-
+-/*
+  * Frame buffer memory address.
+  */
+-#define KN01_VFB_MEM	KSEG1ADDR(0x0fc00000)
++#define KN01_VFB_MEM	0x0fc00000
+ 
+ /*
+  * CPU interrupt bits.
+@@ -80,4 +70,22 @@
+ #define KN01_CSR_VRGTRB		(1<<0)	/* red DAC voltage over blue (r/o) */
+ #define KN01_CSR_LEDS		(0xff<<0) /* ~diagnostic LEDs (w/o) */
+ 
++
++#ifndef __ASSEMBLY__
++
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++
++struct pt_regs;
++
++extern u16 cached_kn01_csr;
++extern spinlock_t kn01_lock;
++
++extern void dec_kn01_be_init(void);
++extern int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup);
++extern irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id,
++					 struct pt_regs *regs);
++#endif
++
+ #endif /* __ASM_MIPS_DEC_KN01_H */
+diff --git a/include/asm-mips/dec/kn02.h b/include/asm-mips/dec/kn02.h
+--- a/include/asm-mips/dec/kn02.h
++++ b/include/asm-mips/dec/kn02.h
+@@ -8,21 +8,12 @@
+  *
+  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
+  * are by courtesy of Chris Fraser.
+- * Copyright (C) 2002, 2003  Maciej W. Rozycki
++ * Copyright (C) 2002, 2003, 2005  Maciej W. Rozycki
+  */
+ #ifndef __ASM_MIPS_DEC_KN02_H
+ #define __ASM_MIPS_DEC_KN02_H
+ 
+-#ifndef __ASSEMBLY__
+-#include <linux/spinlock.h>
+-#include <linux/types.h>
+-#endif
+-
+-#include <asm/addrspace.h>
+-#include <asm/dec/ecc.h>
+-
+-
+-#define KN02_SLOT_BASE	KSEG1ADDR(0x1fc00000)
++#define KN02_SLOT_BASE	0x1fc00000
+ #define KN02_SLOT_SIZE	0x00080000
+ 
+ /*
+@@ -39,22 +30,14 @@
+ 
+ 
+ /*
+- * Some port addresses...
+- */
+-#define KN02_DZ11_BASE	(KN02_SLOT_BASE + KN02_DZ11)	/* DZ11 */
+-#define KN02_RTC_BASE	(KN02_SLOT_BASE + KN02_RTC)	/* RTC */
+-#define KN02_CSR_BASE	(KN02_SLOT_BASE + KN02_CSR)	/* CSR */
+-
+-
+-/*
+  * System Control & Status Register bits.
+  */
+ #define KN02_CSR_RES_28		(0xf<<28)	/* unused */
+ #define KN02_CSR_PSU		(1<<27)		/* power supply unit warning */
+ #define KN02_CSR_NVRAM		(1<<26)		/* ~NVRAM clear jumper */
+ #define KN02_CSR_REFEVEN	(1<<25)		/* mem refresh bank toggle */
+-#define KN03_CSR_NRMOD		(1<<24)		/* ~NRMOD manufact. jumper */
+-#define KN03_CSR_IOINTEN	(0xff<<16)	/* IRQ mask bits */
++#define KN02_CSR_NRMOD		(1<<24)		/* ~NRMOD manufact. jumper */
++#define KN02_CSR_IOINTEN	(0xff<<16)	/* IRQ mask bits */
+ #define KN02_CSR_DIAGCHK	(1<<15)		/* diagn/norml ECC reads */
+ #define KN02_CSR_DIAGGEN	(1<<14)		/* diagn/norml ECC writes */
+ #define KN02_CSR_CORRECT	(1<<13)		/* ECC correct/check */
+@@ -63,8 +46,8 @@
+ #define KN02_CSR_BNK32M		(1<<10)		/* 32M/8M stride */
+ #define KN02_CSR_DIAGDN		(1<<9)		/* DIAGDN manufact. jumper */
+ #define KN02_CSR_BAUD38		(1<<8)		/* DZ11 38/19kbps ext. rate */
+-#define KN03_CSR_IOINT		(0xff<<0)	/* IRQ status bits (r/o) */
+-#define KN03_CSR_LEDS		(0xff<<0)	/* ~diagnostic LEDs (w/o) */
++#define KN02_CSR_IOINT		(0xff<<0)	/* IRQ status bits (r/o) */
++#define KN02_CSR_LEDS		(0xff<<0)	/* ~diagnostic LEDs (w/o) */
+ 
+ 
+ /*
+@@ -98,6 +81,10 @@
+ 
+ 
+ #ifndef __ASSEMBLY__
++
++#include <linux/spinlock.h>
++#include <linux/types.h>
++
+ extern u32 cached_kn02_csr;
+ extern spinlock_t kn02_lock;
+ extern void init_kn02_irqs(int base);
+diff --git a/include/asm-mips/dec/kn02xa.h b/include/asm-mips/dec/kn02xa.h
+--- a/include/asm-mips/dec/kn02xa.h
++++ b/include/asm-mips/dec/kn02xa.h
+@@ -9,7 +9,7 @@
+  *
+  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
+  * are by courtesy of Chris Fraser.
+- * Copyright (C) 2000, 2002, 2003  Maciej W. Rozycki
++ * Copyright (C) 2000, 2002, 2003, 2005  Maciej W. Rozycki
+  *
+  * These are addresses which have to be known early in the boot process.
+  * For other addresses refer to tc.h, ioasic_addrs.h and friends.
+@@ -17,31 +17,23 @@
+ #ifndef __ASM_MIPS_DEC_KN02XA_H
+ #define __ASM_MIPS_DEC_KN02XA_H
+ 
+-#include <asm/addrspace.h>
+ #include <asm/dec/ioasic_addrs.h>
+ 
+-#define KN02XA_SLOT_BASE	KSEG1ADDR(0x1c000000)
+-
+-/*
+- * Some port addresses...
+- */
+-#define KN02XA_IOASIC_BASE    (KN02XA_SLOT_BASE + IOASIC_IOCTL)	/* I/O ASIC */
+-#define KN02XA_RTC_BASE		(KN02XA_SLOT_BASE + IOASIC_TOY)	/* RTC */
+-
++#define KN02XA_SLOT_BASE	0x1c000000
+ 
+ /*
+  * Memory control ASIC registers.
+  */
+-#define KN02XA_MER	KSEG1ADDR(0x0c400000)	/* memory error register */
+-#define KN02XA_MSR	KSEG1ADDR(0x0c800000)	/* memory size register */
++#define KN02XA_MER		0x0c400000	/* memory error register */
++#define KN02XA_MSR		0x0c800000	/* memory size register */
+ 
+ /*
+  * CPU control ASIC registers.
+  */
+-#define KN02XA_MEM_CONF	KSEG1ADDR(0x0e000000)	/* write timeout config */
+-#define KN02XA_EAR	KSEG1ADDR(0x0e000004)	/* error address register */
+-#define KN02XA_BOOT0	KSEG1ADDR(0x0e000008)	/* boot 0 register */
+-#define KN02XA_MEM_INTR	KSEG1ADDR(0x0e00000c)	/* write err IRQ stat & ack */
++#define KN02XA_MEM_CONF		0x0e000000	/* write timeout config */
++#define KN02XA_EAR		0x0e000004	/* error address register */
++#define KN02XA_BOOT0		0x0e000008	/* boot 0 register */
++#define KN02XA_MEM_INTR		0x0e00000c	/* write err IRQ stat & ack */
+ 
+ /*
+  * Memory Error Register bits, common definitions.
+@@ -52,8 +44,13 @@
+ #define KN02XA_MER_PAGERR	(1<<16)		/* 2k page boundary error */
+ #define KN02XA_MER_TRANSERR	(1<<15)		/* transfer length error */
+ #define KN02XA_MER_PARDIS	(1<<14)		/* parity error disable */
+-#define KN02XA_MER_RES_12	(0x3<<12)	/* unused */
+-#define KN02XA_MER_BYTERR	(0xf<<8)	/* byte lane error bitmask */
++#define KN02XA_MER_SIZE		(1<<13)		/* r/o mirror of MSR_SIZE */
++#define KN02XA_MER_RES_12	(1<<12)		/* unused */
++#define KN02XA_MER_BYTERR	(0xf<<8)	/* byte lane error bitmask: */
++#define KN02XA_MER_BYTERR_3	(0x8<<8)	/* byte lane #3 */
++#define KN02XA_MER_BYTERR_2	(0x4<<8)	/* byte lane #2 */
++#define KN02XA_MER_BYTERR_1	(0x2<<8)	/* byte lane #1 */
++#define KN02XA_MER_BYTERR_0	(0x1<<8)	/* byte lane #0 */
+ #define KN02XA_MER_RES_0	(0xff<<0)	/* unused */
+ 
+ /*
+@@ -72,4 +69,17 @@
+ #define KN02XA_EAR_ADDRESS	(0x7ffffff<<2)	/* address involved */
+ #define KN02XA_EAR_RES_0	(0x3<<0)	/* unused */
+ 
++
++#ifndef __ASSEMBLY__
++
++#include <linux/interrupt.h>
++
++struct pt_regs;
++
++extern void dec_kn02xa_be_init(void);
++extern int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup);
++extern irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id,
++					   struct pt_regs *regs);
++#endif
++
+ #endif /* __ASM_MIPS_DEC_KN02XA_H */
+diff --git a/include/asm-mips/dec/kn03.h b/include/asm-mips/dec/kn03.h
+--- a/include/asm-mips/dec/kn03.h
++++ b/include/asm-mips/dec/kn03.h
+@@ -10,24 +10,15 @@
+  *
+  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
+  * are by courtesy of Chris Fraser.
+- * Copyright (C) 2000, 2002, 2003  Maciej W. Rozycki
++ * Copyright (C) 2000, 2002, 2003, 2005  Maciej W. Rozycki
+  */
+ #ifndef __ASM_MIPS_DEC_KN03_H
+ #define __ASM_MIPS_DEC_KN03_H
+ 
+-#include <asm/addrspace.h>
+ #include <asm/dec/ecc.h>
+ #include <asm/dec/ioasic_addrs.h>
+ 
+-#define KN03_SLOT_BASE	KSEG1ADDR(0x1f800000)
+-
+-/*
+- * Some port addresses...
+- */
+-#define KN03_IOASIC_BASE	(KN03_SLOT_BASE + IOASIC_IOCTL)	/* I/O ASIC */
+-#define KN03_RTC_BASE		(KN03_SLOT_BASE + IOASIC_TOY)	/* RTC */
+-#define KN03_MCR_BASE		(KN03_SLOT_BASE + IOASIC_MCR)	/* MCR */
+-
++#define KN03_SLOT_BASE		0x1f800000
+ 
+ /*
+  * CPU interrupt bits.
+diff --git a/include/asm-mips/dec/kn05.h b/include/asm-mips/dec/kn05.h
+--- a/include/asm-mips/dec/kn05.h
++++ b/include/asm-mips/dec/kn05.h
+@@ -1,10 +1,12 @@
+ /*
+  *	include/asm-mips/dec/kn05.h
+  *
+- *	DECstation 5000/260 (4max+ or KN05) and DECsystem 5900/260
++ *	DECstation/DECsystem 5000/260 (4max+ or KN05), 5000/150 (4min
++ *	or KN04-BA), Personal DECstation/DECsystem 5000/50 (4maxine or
++ *	KN04-CA) and DECsystem 5900/260 (KN05) R4k CPU card MB ASIC
+  *	definitions.
+  *
+- *	Copyright (C) 2002, 2003  Maciej W. Rozycki
++ *	Copyright (C) 2002, 2003, 2005  Maciej W. Rozycki
+  *
+  *	This program is free software; you can redistribute it and/or
+  *	modify it under the terms of the GNU General Public License
+@@ -13,8 +15,8 @@
+  *
+  *	WARNING!  All this information is pure guesswork based on the
+  *	ROM.  It is provided here in hope it will give someone some
+- *	food for thought.  No documentation for the KN05 module has
+- *	been located so far.
++ *	food for thought.  No documentation for the KN05 nor the KN04
++ *	module has been located so far.
+  */
+ #ifndef __ASM_MIPS_DEC_KN05_H
+ #define __ASM_MIPS_DEC_KN05_H
+@@ -24,48 +26,50 @@
+ /*
+  * The oncard MB (Memory Buffer) ASIC provides an additional address
+  * decoder.  Certain address ranges within the "high" 16 slots are
+- * passed to the I/O ASIC's decoder like with the KN03.  Others are
+- * handled locally.  "Low" slots are always passed.
++ * passed to the I/O ASIC's decoder like with the KN03 or KN02-BA/CA.
++ * Others are handled locally.  "Low" slots are always passed.
+  */
+-#define KN05_MB_ROM	(16*IOASIC_SLOT_SIZE)	/* KN05 card ROM */
+-#define KN05_IOCTL	(17*IOASIC_SLOT_SIZE)	/* I/O ASIC */
+-#define KN05_ESAR	(18*IOASIC_SLOT_SIZE)	/* LANCE MAC address chip */
+-#define KN05_LANCE	(19*IOASIC_SLOT_SIZE)	/* LANCE Ethernet */
+-#define KN05_MB_INT	(20*IOASIC_SLOT_SIZE)	/* MB interrupt register */
+-#define KN05_MB_EA	(21*IOASIC_SLOT_SIZE)	/* MB error address? */
+-#define KN05_MB_EC	(22*IOASIC_SLOT_SIZE)	/* MB error ??? */
+-#define KN05_MB_CSR	(23*IOASIC_SLOT_SIZE)	/* MB control & status */
+-#define KN05_RES_24	(24*IOASIC_SLOT_SIZE)	/* unused? */
+-#define KN05_RES_25	(25*IOASIC_SLOT_SIZE)	/* unused? */
+-#define KN05_RES_26	(26*IOASIC_SLOT_SIZE)	/* unused? */
+-#define KN05_RES_27	(27*IOASIC_SLOT_SIZE)	/* unused? */
+-#define KN05_SCSI	(28*IOASIC_SLOT_SIZE)	/* ASC SCSI */
+-#define KN05_RES_29	(29*IOASIC_SLOT_SIZE)	/* unused? */
+-#define KN05_RES_30	(30*IOASIC_SLOT_SIZE)	/* unused? */
+-#define KN05_RES_31	(31*IOASIC_SLOT_SIZE)	/* unused? */
++#define KN4K_SLOT_BASE	0x1fc00000
++
++#define KN4K_MB_ROM	(0*IOASIC_SLOT_SIZE)	/* KN05/KN04 card ROM */
++#define KN4K_IOCTL	(1*IOASIC_SLOT_SIZE)	/* I/O ASIC */
++#define KN4K_ESAR	(2*IOASIC_SLOT_SIZE)	/* LANCE MAC address chip */
++#define KN4K_LANCE	(3*IOASIC_SLOT_SIZE)	/* LANCE Ethernet */
++#define KN4K_MB_INT	(4*IOASIC_SLOT_SIZE)	/* MB interrupt register */
++#define KN4K_MB_EA	(5*IOASIC_SLOT_SIZE)	/* MB error address? */
++#define KN4K_MB_EC	(6*IOASIC_SLOT_SIZE)	/* MB error ??? */
++#define KN4K_MB_CSR	(7*IOASIC_SLOT_SIZE)	/* MB control & status */
++#define KN4K_RES_08	(8*IOASIC_SLOT_SIZE)	/* unused? */
++#define KN4K_RES_09	(9*IOASIC_SLOT_SIZE)	/* unused? */
++#define KN4K_RES_10	(10*IOASIC_SLOT_SIZE)	/* unused? */
++#define KN4K_RES_11	(11*IOASIC_SLOT_SIZE)	/* unused? */
++#define KN4K_SCSI	(12*IOASIC_SLOT_SIZE)	/* ASC SCSI */
++#define KN4K_RES_13	(13*IOASIC_SLOT_SIZE)	/* unused? */
++#define KN4K_RES_14	(14*IOASIC_SLOT_SIZE)	/* unused? */
++#define KN4K_RES_15	(15*IOASIC_SLOT_SIZE)	/* unused? */
+ 
+ /*
+  * Bits for the MB interrupt register.
+  * The register appears read-only.
+  */
+-#define KN05_MB_INT_TC		(1<<0)		/* TURBOchannel? */
+-#define KN05_MB_INT_RTC		(1<<1)		/* RTC? */
+-#define KN05_MB_INT_MT		(1<<3)		/* ??? */
++#define KN4K_MB_INT_TC		(1<<0)		/* TURBOchannel? */
++#define KN4K_MB_INT_RTC		(1<<1)		/* RTC? */
++#define KN4K_MB_INT_MT		(1<<3)		/* ??? */
+ 
+ /*
+  * Bits for the MB control & status register.
+  * Set to 0x00bf8001 on my system by the ROM.
+  */
+-#define KN05_MB_CSR_PF		(1<<0)		/* PreFetching enable? */
+-#define KN05_MB_CSR_F		(1<<1)		/* ??? */
+-#define KN05_MB_CSR_ECC		(0xff<<2)	/* ??? */
+-#define KN05_MB_CSR_OD		(1<<10)		/* ??? */
+-#define KN05_MB_CSR_CP		(1<<11)		/* ??? */
+-#define KN05_MB_CSR_UNC		(1<<12)		/* ??? */
+-#define KN05_MB_CSR_IM		(1<<13)		/* ??? */
+-#define KN05_MB_CSR_NC		(1<<14)		/* ??? */
+-#define KN05_MB_CSR_EE		(1<<15)		/* (bus) Exception Enable? */
+-#define KN05_MB_CSR_MSK		(0x1f<<16)	/* ??? */
+-#define KN05_MB_CSR_FW		(1<<21)		/* ??? */
++#define KN4K_MB_CSR_PF		(1<<0)		/* PreFetching enable? */
++#define KN4K_MB_CSR_F		(1<<1)		/* ??? */
++#define KN4K_MB_CSR_ECC		(0xff<<2)	/* ??? */
++#define KN4K_MB_CSR_OD		(1<<10)		/* ??? */
++#define KN4K_MB_CSR_CP		(1<<11)		/* ??? */
++#define KN4K_MB_CSR_UNC		(1<<12)		/* ??? */
++#define KN4K_MB_CSR_IM		(1<<13)		/* ??? */
++#define KN4K_MB_CSR_NC		(1<<14)		/* ??? */
++#define KN4K_MB_CSR_EE		(1<<15)		/* (bus) Exception Enable? */
++#define KN4K_MB_CSR_MSK		(0x1f<<16)	/* ??? */
++#define KN4K_MB_CSR_FW		(1<<21)		/* ??? */
+ 
+ #endif /* __ASM_MIPS_DEC_KN05_H */
+diff --git a/include/asm-mips/dec/prom.h b/include/asm-mips/dec/prom.h
+--- a/include/asm-mips/dec/prom.h
++++ b/include/asm-mips/dec/prom.h
+@@ -24,7 +24,7 @@
+  * PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's.
+  * Many of these will work for MIPSen as well!
+  */
+-#define VEC_RESET		(u64 *)KSEG1ADDR(0x1fc00000)
++#define VEC_RESET		(u64 *)CKSEG1ADDR(0x1fc00000)
+ 							/* Prom base address */
+ 
+ #define PMAX_PROM_ENTRY(x)	(VEC_RESET + (x))	/* Prom jump table */
+@@ -111,19 +111,21 @@ extern int (*__pmax_close)(int);
+  * On MIPS64 we have to call PROM functions via a helper
+  * dispatcher to accomodate ABI incompatibilities.
+  */
+-#define __DEC_PROM_O32 __attribute__((alias("call_o32")))
++#define __DEC_PROM_O32(fun, arg) fun arg __asm__(#fun); \
++				 __asm__(#fun " = call_o32")
+ 
+-int _rex_bootinit(int (*)(void)) __DEC_PROM_O32;
+-int _rex_bootread(int (*)(void)) __DEC_PROM_O32;
+-int _rex_getbitmap(int (*)(memmap *), memmap *) __DEC_PROM_O32;
+-unsigned long *_rex_slot_address(unsigned long *(*)(int), int) __DEC_PROM_O32;
+-void *_rex_gettcinfo(void *(*)(void)) __DEC_PROM_O32;
+-int _rex_getsysid(int (*)(void)) __DEC_PROM_O32;
+-void _rex_clear_cache(void (*)(void)) __DEC_PROM_O32;
+-
+-int _prom_getchar(int (*)(void)) __DEC_PROM_O32;
+-char *_prom_getenv(char *(*)(char *), char *) __DEC_PROM_O32;
+-int _prom_printf(int (*)(char *, ...), char *, ...) __DEC_PROM_O32;
++int __DEC_PROM_O32(_rex_bootinit, (int (*)(void)));
++int __DEC_PROM_O32(_rex_bootread, (int (*)(void)));
++int __DEC_PROM_O32(_rex_getbitmap, (int (*)(memmap *), memmap *));
++unsigned long *__DEC_PROM_O32(_rex_slot_address,
++			     (unsigned long *(*)(int), int));
++void *__DEC_PROM_O32(_rex_gettcinfo, (void *(*)(void)));
++int __DEC_PROM_O32(_rex_getsysid, (int (*)(void)));
++void __DEC_PROM_O32(_rex_clear_cache, (void (*)(void)));
++
++int __DEC_PROM_O32(_prom_getchar, (int (*)(void)));
++char *__DEC_PROM_O32(_prom_getenv, (char *(*)(char *), char *));
++int __DEC_PROM_O32(_prom_printf, (int (*)(char *, ...), char *, ...));
+ 
+ 
+ #define rex_bootinit()		_rex_bootinit(__rex_bootinit)
+diff --git a/include/asm-mips/dec/system.h b/include/asm-mips/dec/system.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/dec/system.h
+@@ -0,0 +1,18 @@
++/*
++ *	include/asm-mips/dec/system.h
++ *
++ *	Generic DECstation/DECsystem bits.
++ *
++ *	Copyright (C) 2005  Maciej W. Rozycki
++ *
++ *	This program is free software; you can redistribute it and/or
++ *	modify it under the terms of the 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_DEC_SYSTEM_H
++#define __ASM_DEC_SYSTEM_H
++
++extern unsigned long dec_kn_slot_base, dec_kn_slot_size;
++
++#endif /* __ASM_DEC_SYSTEM_H */
+diff --git a/include/asm-mips/dec/tc.h b/include/asm-mips/dec/tc.h
+--- a/include/asm-mips/dec/tc.h
++++ b/include/asm-mips/dec/tc.h
+@@ -7,10 +7,8 @@
+  *
+  * Copyright (c) 1998 Harald Koerfgen
+  */
+-#ifndef ASM_TC_H
+-#define ASM_TC_H
+-
+-extern unsigned long system_base;
++#ifndef __ASM_DEC_TC_H
++#define __ASM_DEC_TC_H
+ 
+ /*
+  * Search for a TURBOchannel Option Module
+@@ -36,8 +34,8 @@ extern unsigned long get_tc_base_addr(in
+  */
+ extern unsigned long get_tc_irq_nr(int);
+ /*
+- * Return TURBOchannel clock frequency in hz
++ * Return TURBOchannel clock frequency in Hz
+  */
+ extern unsigned long get_tc_speed(void);
+ 
+-#endif
++#endif /* __ASM_DEC_TC_H */
+diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h
+--- a/include/asm-mips/delay.h
++++ b/include/asm-mips/delay.h
+@@ -12,11 +12,9 @@
+ 
+ #include <linux/config.h>
+ #include <linux/param.h>
+-
++#include <linux/smp.h>
+ #include <asm/compiler.h>
+ 
+-extern unsigned long loops_per_jiffy;
+-
+ static inline void __delay(unsigned long loops)
+ {
+ 	if (sizeof(long) == 4)
+@@ -82,11 +80,7 @@ static inline void __udelay(unsigned lon
+ 	__delay(usecs);
+ }
+ 
+-#ifdef CONFIG_SMP
+ #define __udelay_val cpu_data[smp_processor_id()].udelay_val
+-#else
+-#define __udelay_val loops_per_jiffy
+-#endif
+ 
+ #define udelay(usecs) __udelay((usecs),__udelay_val)
+ 
+diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h
+--- a/include/asm-mips/dma-mapping.h
++++ b/include/asm-mips/dma-mapping.h
+@@ -5,13 +5,13 @@
+ #include <asm/cache.h>
+ 
+ void *dma_alloc_noncoherent(struct device *dev, size_t size,
+-			   dma_addr_t *dma_handle, int flag);
++			   dma_addr_t *dma_handle, gfp_t flag);
+ 
+ void dma_free_noncoherent(struct device *dev, size_t size,
+ 			 void *vaddr, dma_addr_t dma_handle);
+ 
+ void *dma_alloc_coherent(struct device *dev, size_t size,
+-			   dma_addr_t *dma_handle, int flag);
++			   dma_addr_t *dma_handle, gfp_t flag);
+ 
+ void dma_free_coherent(struct device *dev, size_t size,
+ 			 void *vaddr, dma_addr_t dma_handle);
+diff --git a/include/asm-mips/dsp.h b/include/asm-mips/dsp.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/dsp.h
+@@ -0,0 +1,83 @@
++/*
++ * Copyright (C) 2005 Mips Technologies
++ * Author: Chris Dearman, chris at mips.com derived from fpu.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.
++ */
++#ifndef _ASM_DSP_H
++#define _ASM_DSP_H
++
++#include <asm/cpu.h>
++#include <asm/cpu-features.h>
++#include <asm/hazards.h>
++#include <asm/mipsregs.h>
++
++#define DSP_DEFAULT	0x00000000
++#define DSP_MASK	0x1f
++
++#define __enable_dsp_hazard()						\
++do {									\
++	asm("_ehb");							\
++} while (0)
++
++static inline void __init_dsp(void)
++{
++	mthi1(0);
++	mtlo1(0);
++	mthi2(0);
++	mtlo2(0);
++	mthi3(0);
++	mtlo3(0);
++	wrdsp(DSP_DEFAULT, DSP_MASK);
++}
++
++static inline void init_dsp(void)
++{
++	if (cpu_has_dsp)
++		__init_dsp();
++}
++
++#define __save_dsp(tsk)							\
++do {									\
++	tsk->thread.dsp.dspr[0] = mfhi1();				\
++	tsk->thread.dsp.dspr[1] = mflo1();				\
++	tsk->thread.dsp.dspr[2] = mfhi2();				\
++	tsk->thread.dsp.dspr[3] = mflo2();				\
++	tsk->thread.dsp.dspr[4] = mfhi3();				\
++	tsk->thread.dsp.dspr[5] = mflo3();				\
++} while (0)
++
++#define save_dsp(tsk)							\
++do {									\
++	if (cpu_has_dsp)						\
++		__save_dsp(tsk);					\
++} while (0)
++
++#define __restore_dsp(tsk)						\
++do {									\
++	mthi1(tsk->thread.dsp.dspr[0]);					\
++	mtlo1(tsk->thread.dsp.dspr[1]);					\
++	mthi2(tsk->thread.dsp.dspr[2]);					\
++	mtlo2(tsk->thread.dsp.dspr[3]);					\
++	mthi3(tsk->thread.dsp.dspr[4]);					\
++	mtlo3(tsk->thread.dsp.dspr[5]);					\
++} while (0)
++
++#define restore_dsp(tsk)						\
++do {									\
++	if (cpu_has_dsp)						\
++		__restore_dsp(tsk);					\
++} while (0)
++
++#define __get_dsp_regs(tsk)						\
++({									\
++	if (tsk == current)						\
++		__save_dsp(current);					\
++									\
++	tsk->thread.dsp.dspr;						\
++})
++
++#endif /* _ASM_DSP_H */
+diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h
+--- a/include/asm-mips/elf.h
++++ b/include/asm-mips/elf.h
+@@ -2,6 +2,8 @@
+  * 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.
++ *
++ * Much of this is taken from binutils and GNU libc ...
+  */
+ #ifndef _ASM_ELF_H
+ #define _ASM_ELF_H
+@@ -17,6 +19,8 @@
+ #define EF_MIPS_ARCH_5		0x40000000	/* -mips5 code.  */
+ #define EF_MIPS_ARCH_32		0x50000000	/* MIPS32 code.  */
+ #define EF_MIPS_ARCH_64		0x60000000	/* MIPS64 code.  */
++#define EF_MIPS_ARCH_32R2	0x70000000	/* MIPS32 R2 code.  */
++#define EF_MIPS_ARCH_64R2	0x80000000	/* MIPS64 R2 code.  */
+ 
+ /* The ABI of a file. */
+ #define EF_MIPS_ABI_O32		0x00001000	/* O32 ABI.  */
+@@ -105,7 +109,11 @@
+ #define R_MIPS_LOVENDOR		100
+ #define R_MIPS_HIVENDOR		127
+ 
+-#define SHN_MIPS_ACCOMON	0xff00
++#define SHN_MIPS_ACCOMON	0xff00		/* Allocated common symbols */
++#define SHN_MIPS_TEXT		0xff01		/* Allocated test symbols.  */
++#define SHN_MIPS_DATA		0xff02		/* Allocated data symbols.  */
++#define SHN_MIPS_SCOMMON	0xff03		/* Small common symbols */
++#define SHN_MIPS_SUNDEFINED	0xff04		/* Small undefined symbols */
+ 
+ #define SHT_MIPS_LIST		0x70000000
+ #define SHT_MIPS_CONFLICT	0x70000002
+@@ -193,50 +201,92 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
+ 
+ #ifdef __KERNEL__
+ 
++struct mips_abi;
++
++extern struct mips_abi mips_abi;
++extern struct mips_abi mips_abi_32;
++extern struct mips_abi mips_abi_n32;
++
+ #ifdef CONFIG_32BIT
+ 
+-#define SET_PERSONALITY(ex, ibcs2)			\
+-do {							\
+-	if (ibcs2)					\
+-		set_personality(PER_SVR4);		\
+-	set_personality(PER_LINUX);			\
++#define SET_PERSONALITY(ex, ibcs2)					\
++do {									\
++	if (ibcs2)							\
++		set_personality(PER_SVR4);				\
++	set_personality(PER_LINUX);					\
++									\
++	current->thread.abi = &mips_abi;				\
+ } while (0)
+ 
+ #endif /* CONFIG_32BIT */
+ 
+ #ifdef CONFIG_64BIT
+ 
+-#define SET_PERSONALITY(ex, ibcs2)				\
+-do {	current->thread.mflags &= ~MF_ABI_MASK;			\
+-	if ((ex).e_ident[EI_CLASS] == ELFCLASS32) {		\
+-		if ((((ex).e_flags & EF_MIPS_ABI2) != 0) &&	\
+-		     ((ex).e_flags & EF_MIPS_ABI) == 0)		\
+-			current->thread.mflags |= MF_N32;	\
+-		else						\
+-			current->thread.mflags |= MF_O32;	\
+-	} else							\
+-		current->thread.mflags |= MF_N64;		\
+-	if (ibcs2)						\
+-		set_personality(PER_SVR4);			\
+-	else if (current->personality != PER_LINUX32)		\
+-		set_personality(PER_LINUX);			\
++#ifdef CONFIG_MIPS32_N32
++#define __SET_PERSONALITY32_N32()					\
++	do {								\
++		current->thread.mflags |= MF_N32;			\
++		current->thread.abi = &mips_abi_n32;			\
++	} while (0)
++#else
++#define __SET_PERSONALITY32_N32()					\
++	do { } while (0)
++#endif
++
++#ifdef CONFIG_MIPS32_O32
++#define __SET_PERSONALITY32_O32()					\
++	do {								\
++		current->thread.mflags |= MF_O32;			\
++		current->thread.abi = &mips_abi_32;			\
++	} while (0)
++#else
++#define __SET_PERSONALITY32_O32()					\
++	do { } while (0)
++#endif
++
++#ifdef CONFIG_MIPS32_COMPAT
++#define __SET_PERSONALITY32(ex)						\
++do {									\
++	if ((((ex).e_flags & EF_MIPS_ABI2) != 0) &&			\
++	     ((ex).e_flags & EF_MIPS_ABI) == 0)				\
++		__SET_PERSONALITY32_N32();				\
++	else								\
++		__SET_PERSONALITY32_O32();				\
++} while (0)
++#else
++#define __SET_PERSONALITY32(ex)	do { } while (0)
++#endif
++
++#define SET_PERSONALITY(ex, ibcs2)					\
++do {									\
++	current->thread.mflags &= ~MF_ABI_MASK;				\
++	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)			\
++		__SET_PERSONALITY32(ex);				\
++	else {								\
++		current->thread.mflags |= MF_N64;			\
++		current->thread.abi = &mips_abi;			\
++	}								\
++									\
++	if (ibcs2)							\
++		set_personality(PER_SVR4);				\
++	else if (current->personality != PER_LINUX32)			\
++		set_personality(PER_LINUX);				\
+ } while (0)
+ 
+ #endif /* CONFIG_64BIT */
+ 
+ extern void dump_regs(elf_greg_t *, struct pt_regs *regs);
++extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
+ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
+ 
+ #define ELF_CORE_COPY_REGS(elf_regs, regs)			\
+ 	dump_regs((elf_greg_t *)&(elf_regs), regs);
++#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
+ #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs)			\
+ 	dump_task_fpu(tsk, elf_fpregs)
+ 
+ #endif /* __KERNEL__ */
+ 
+-/* This one accepts IRIX binaries.  */
+-#define irix_elf_check_arch(hdr)	((hdr)->e_flags & RHF_SGI_ONLY)
+-
+ #define USE_ELF_CORE_DUMP
+ #define ELF_EXEC_PAGESIZE	PAGE_SIZE
+ 
+diff --git a/include/asm-mips/errno.h b/include/asm-mips/errno.h
+--- a/include/asm-mips/errno.h
++++ b/include/asm-mips/errno.h
+@@ -119,6 +119,10 @@
+ #define	EOWNERDEAD	165	/* Owner died */
+ #define	ENOTRECOVERABLE	166	/* State not recoverable */
+ 
++/* for robust mutexes */
++#define	EOWNERDEAD	165	/* Owner died */
++#define	ENOTRECOVERABLE	166	/* State not recoverable */
++
+ #define EDQUOT		1133	/* Quota exceeded */
+ 
+ #ifdef __KERNEL__
+diff --git a/include/asm-mips/fcntl.h b/include/asm-mips/fcntl.h
+--- a/include/asm-mips/fcntl.h
++++ b/include/asm-mips/fcntl.h
+@@ -3,11 +3,13 @@
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
+- * Copyright (C) 1995, 96, 97, 98, 99, 2003 Ralf Baechle
++ * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle
+  */
+ #ifndef _ASM_FCNTL_H
+ #define _ASM_FCNTL_H
+ 
++#include <linux/config.h>
++
+ #define O_APPEND	0x0008
+ #define O_SYNC		0x0010
+ #define O_NONBLOCK	0x0080
+@@ -40,13 +42,13 @@
+  * contain all the same fields as struct flock.
+  */
+ 
+-#ifndef __mips64
++#ifdef CONFIG_32BIT
+ 
+ struct flock {
+ 	short	l_type;
+ 	short	l_whence;
+-	__kernel_off_t l_start;
+-	__kernel_off_t l_len;
++	off_t	l_start;
++	off_t	l_len;
+ 	long	l_sysid;
+ 	__kernel_pid_t l_pid;
+ 	long	pad[4];
+@@ -54,13 +56,8 @@ struct flock {
+ 
+ #define HAVE_ARCH_STRUCT_FLOCK
+ 
+-#endif
++#endif /* CONFIG_32BIT */
+ 
+ #include <asm-generic/fcntl.h>
+ 
+-typedef struct flock flock_t;
+-#ifndef __mips64
+-typedef struct flock64 flock64_t;
+-#endif
+-
+ #endif /* _ASM_FCNTL_H */
+diff --git a/include/asm-mips/fixmap.h b/include/asm-mips/fixmap.h
+--- a/include/asm-mips/fixmap.h
++++ b/include/asm-mips/fixmap.h
+@@ -107,4 +107,11 @@ static inline unsigned long virt_to_fix(
+ 	return __virt_to_fix(vaddr);
+ }
+ 
++/*
++ * Called from pgtable_init()
++ */
++extern void fixrange_init(unsigned long start, unsigned long end,
++        pgd_t *pgd_base);
++
++
+ #endif
+diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
+--- a/include/asm-mips/fpu.h
++++ b/include/asm-mips/fpu.h
+@@ -80,9 +80,14 @@ do {									\
+ 
+ #define clear_fpu_owner()	clear_thread_flag(TIF_USEDFPU)
+ 
++static inline int __is_fpu_owner(void)
++{
++	return test_thread_flag(TIF_USEDFPU);
++}
++
+ static inline int is_fpu_owner(void)
+ {
+-	return cpu_has_fpu && test_thread_flag(TIF_USEDFPU);
++	return cpu_has_fpu && __is_fpu_owner();
+ }
+ 
+ static inline void own_fpu(void)
+@@ -127,7 +132,7 @@ static inline void restore_fp(struct tas
+ static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
+ {
+ 	if (cpu_has_fpu) {
+-		if ((tsk == current) && is_fpu_owner())
++		if ((tsk == current) && __is_fpu_owner())
+ 			_save_fp(current);
+ 		return tsk->thread.fpu.hard.fpr;
+ 	}
+diff --git a/include/asm-mips/fpu_emulator.h b/include/asm-mips/fpu_emulator.h
+--- a/include/asm-mips/fpu_emulator.h
++++ b/include/asm-mips/fpu_emulator.h
+@@ -23,16 +23,15 @@
+ #ifndef _ASM_FPU_EMULATOR_H
+ #define _ASM_FPU_EMULATOR_H
+ 
+-struct mips_fpu_emulator_private {
+-	unsigned int eir;
+-	struct {
+-		unsigned int emulated;
+-		unsigned int loads;
+-		unsigned int stores;
+-		unsigned int cp1ops;
+-		unsigned int cp1xops;
+-		unsigned int errors;
+-	} stats;
++struct mips_fpu_emulator_stats {
++	unsigned int emulated;
++	unsigned int loads;
++	unsigned int stores;
++	unsigned int cp1ops;
++	unsigned int cp1xops;
++	unsigned int errors;
+ };
+ 
++extern struct mips_fpu_emulator_stats fpuemustats;
++
+ #endif /* _ASM_FPU_EMULATOR_H */
+diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h
+--- a/include/asm-mips/futex.h
++++ b/include/asm-mips/futex.h
+@@ -3,10 +3,45 @@
+ 
+ #ifdef __KERNEL__
+ 
++#include <linux/config.h>
+ #include <linux/futex.h>
+ #include <asm/errno.h>
+ #include <asm/uaccess.h>
+ 
++#ifdef CONFIG_SMP
++#define __FUTEX_SMP_SYNC "	sync					\n"
++#else
++#define __FUTEX_SMP_SYNC
++#endif
++
++#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)		\
++{									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	.set	mips3					\n"	\
++	"1:	ll	%1, (%3)	# __futex_atomic_op1	\n"	\
++	"	.set	mips0					\n"	\
++	"	" insn	"					\n"	\
++	"	.set	mips3					\n"	\
++	"2:	sc	$1, (%3)				\n"	\
++	"	beqzl	$1, 1b					\n"	\
++	__FUTEX_SMP_SYNC						\
++	"3:							\n"	\
++	"	.set	pop					\n"	\
++	"	.set	mips0					\n"	\
++	"	.section .fixup,\"ax\"				\n"	\
++	"4:	li	%0, %5					\n"	\
++	"	j	2b					\n"	\
++	"	.previous					\n"	\
++	"	.section __ex_table,\"a\"			\n"	\
++	"	"__UA_ADDR "\t1b, 4b				\n"	\
++	"	"__UA_ADDR "\t2b, 4b				\n"	\
++	"	.previous					\n"	\
++	: "=r" (ret), "=r" (oldval)					\
++	: "0" (0), "r" (uaddr), "Jr" (oparg), "i" (-EFAULT));		\
++}
++
+ static inline int
+ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
+ {
+@@ -25,10 +60,25 @@ futex_atomic_op_inuser (int encoded_op, 
+ 
+ 	switch (op) {
+ 	case FUTEX_OP_SET:
++		__futex_atomic_op("move	$1, %z4", ret, oldval, uaddr, oparg);
++		break;
++
+ 	case FUTEX_OP_ADD:
++		__futex_atomic_op("addu	$1, %1, %z4",
++		                  ret, oldval, uaddr, oparg);
++		break;
+ 	case FUTEX_OP_OR:
++		__futex_atomic_op("or	$1, %1, %z4",
++		                  ret, oldval, uaddr, oparg);
++		break;
+ 	case FUTEX_OP_ANDN:
++		__futex_atomic_op("and	$1, %1, %z4",
++		                  ret, oldval, uaddr, ~oparg);
++		break;
+ 	case FUTEX_OP_XOR:
++		__futex_atomic_op("xor	$1, %1, %z4",
++		                  ret, oldval, uaddr, oparg);
++		break;
+ 	default:
+ 		ret = -ENOSYS;
+ 	}
+diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h
+--- a/include/asm-mips/hazards.h
++++ b/include/asm-mips/hazards.h
+@@ -74,7 +74,8 @@
+ #define irq_disable_hazard
+ 	_ehb
+ 
+-#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
++#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \
++      defined(CONFIG_CPU_SB1)
+ 
+ /*
+  * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
+@@ -107,6 +108,7 @@ __asm__(
+ 	"	.endm						\n\t");
+ 
+ #ifdef CONFIG_CPU_RM9000
++
+ /*
+  * RM9000 hazards.  When the JTLB is updated by tlbwi or tlbwr, a subsequent
+  * use of the JTLB for instructions should not occur for 4 cpu cycles and use
+@@ -124,6 +126,9 @@ __asm__(
+ 		".set\tmips32\n\t"					\
+ 		"_ssnop; _ssnop; _ssnop; _ssnop\n\t"			\
+ 		".set\tmips0")
++
++#define back_to_back_c0_hazard()	do { } while (0)
++
+ #else
+ 
+ /*
+@@ -144,15 +149,13 @@ __asm__(
+ #endif
+ 
+ /*
+- * mtc0->mfc0 hazard
+- * The 24K has a 2 cycle mtc0/mfc0 execution hazard.
+- * It is a MIPS32R2 processor so ehb will clear the hazard.
++ * Interrupt enable/disable hazards
++ * Some processors have hazards when modifying
++ * the status register to change the interrupt state
+  */
+ 
+ #ifdef CONFIG_CPU_MIPSR2
+-/*
+- * Use a macro for ehb unless explicit support for MIPSR2 is enabled
+- */
++
+ __asm__(
+ 	"	.macro\tirq_enable_hazard			\n\t"
+ 	"	_ehb						\n\t"
+@@ -160,17 +163,26 @@ __asm__(
+ 	"							\n\t"
+ 	"	.macro\tirq_disable_hazard			\n\t"
+ 	"	_ehb						\n\t"
++	"	.endm						\n\t"
++	"							\n\t"
++	"	.macro\tback_to_back_c0_hazard			\n\t"
++	"	_ehb						\n\t"
+ 	"	.endm");
+ 
+ #define irq_enable_hazard()						\
+ 	__asm__ __volatile__(						\
+-	"_ehb\t\t\t\t# irq_enable_hazard")
++	"irq_enable_hazard")
+ 
+ #define irq_disable_hazard()						\
+ 	__asm__ __volatile__(						\
+-	"_ehb\t\t\t\t# irq_disable_hazard")
++	"irq_disable_hazard")
+ 
+-#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
++#define back_to_back_c0_hazard()					\
++	__asm__ __volatile__(						\
++	"back_to_back_c0_hazard")
++
++#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \
++      defined(CONFIG_CPU_SB1)
+ 
+ /*
+  * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
+@@ -186,6 +198,8 @@ __asm__(
+ #define irq_enable_hazard()	do { } while (0)
+ #define irq_disable_hazard()	do { } while (0)
+ 
++#define back_to_back_c0_hazard()	do { } while (0)
++
+ #else
+ 
+ /*
+@@ -208,8 +222,30 @@ __asm__(
+ #define irq_enable_hazard()	do { } while (0)
+ #define irq_disable_hazard()						\
+ 	__asm__ __volatile__(						\
+-	"_ssnop; _ssnop; _ssnop;\t\t# irq_disable_hazard")
++	"irq_disable_hazard")
+ 
++#define back_to_back_c0_hazard()					\
++	__asm__ __volatile__(						\
++	"	.set noreorder				\n"		\
++	"	nop; nop; nop				\n"		\
++	"	.set reorder				\n")
++
++#endif
++
++#ifdef CONFIG_CPU_MIPSR2
++#define instruction_hazard()						\
++do {									\
++__label__ __next;							\
++	__asm__ __volatile__(						\
++	"	jr.hb	%0					\n"	\
++	:								\
++	: "r" (&&__next));						\
++__next:									\
++	;								\
++} while (0)
++
++#else
++#define instruction_hazard() do { } while (0)
+ #endif
+ 
+ #endif /* __ASSEMBLY__ */
+diff --git a/include/asm-mips/highmem.h b/include/asm-mips/highmem.h
+--- a/include/asm-mips/highmem.h
++++ b/include/asm-mips/highmem.h
+@@ -75,6 +75,7 @@ static inline void *kmap_atomic(struct p
+ }
+ 
+ static inline void kunmap_atomic(void *kvaddr, enum km_type type) { }
++#define kmap_atomic_pfn(pfn, idx)	page_address(pfn_to_page(pfn))
+ 
+ #define kmap_atomic_to_page(ptr) virt_to_page(ptr)
+ 
+@@ -86,6 +87,7 @@ extern void *__kmap(struct page *page);
+ extern void __kunmap(struct page *page);
+ extern void *__kmap_atomic(struct page *page, enum km_type type);
+ extern void __kunmap_atomic(void *kvaddr, enum km_type type);
++extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
+ extern struct page *__kmap_atomic_to_page(void *ptr);
+ 
+ #define kmap			__kmap
+diff --git a/include/asm-mips/inst.h b/include/asm-mips/inst.h
+--- a/include/asm-mips/inst.h
++++ b/include/asm-mips/inst.h
+@@ -28,7 +28,7 @@ enum major_op {
+ 	sdl_op, sdr_op, swr_op, cache_op,
+ 	ll_op, lwc1_op, lwc2_op, pref_op,
+ 	lld_op, ldc1_op, ldc2_op, ld_op,
+-	sc_op, swc1_op, swc2_op, major_3b_op, /* Opcode 0x3b is unused */
++	sc_op, swc1_op, swc2_op, rdhwr_op,
+ 	scd_op, sdc1_op, sdc2_op, sd_op
+ };
+ 
+@@ -62,10 +62,10 @@ enum rt_op {
+ 	spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07,
+ 	tgei_op, tgeiu_op, tlti_op, tltiu_op,
+ 	teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op,
+-	bltzal_op, bgezal_op, bltzall_op, bgezall_op
+-	/*
+-	 * The others (0x14 - 0x1f) are unused.
+- 	 */
++	bltzal_op, bgezal_op, bltzall_op, bgezall_op,
++	rt_op_0x14, rt_op_0x15, rt_op_0x16, rt_op_0x17,
++	rt_op_0x18, rt_op_0x19, rt_op_0x1a, rt_op_0x1b,
++	bposge32_op, rt_op_0x1d, rt_op_0x1e, rt_op_0x1f
+ };
+ 
+ /*
+diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h
+--- a/include/asm-mips/interrupt.h
++++ b/include/asm-mips/interrupt.h
+@@ -11,20 +11,25 @@
+ #ifndef _ASM_INTERRUPT_H
+ #define _ASM_INTERRUPT_H
+ 
++#include <linux/config.h>
+ #include <asm/hazards.h>
+ 
+ __asm__ (
+-	".macro\tlocal_irq_enable\n\t"
+-	".set\tpush\n\t"
+-	".set\treorder\n\t"
+-	".set\tnoat\n\t"
+-	"mfc0\t$1,$12\n\t"
+-	"ori\t$1,0x1f\n\t"
+-	"xori\t$1,0x1e\n\t"
+-	"mtc0\t$1,$12\n\t"
+-	"irq_enable_hazard\n\t"
+-	".set\tpop\n\t"
+-	".endm");
++	"	.macro	local_irq_enable				\n"
++	"	.set	push						\n"
++	"	.set	reorder						\n"
++	"	.set	noat						\n"
++#ifdef 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 local_irq_enable(void)
+ {
+@@ -43,17 +48,21 @@ static inline void local_irq_enable(void
+  * no nops at all.
+  */
+ __asm__ (
+-	".macro\tlocal_irq_disable\n\t"
+-	".set\tpush\n\t"
+-	".set\tnoat\n\t"
+-	"mfc0\t$1,$12\n\t"
+-	"ori\t$1,1\n\t"
+-	"xori\t$1,1\n\t"
+-	".set\tnoreorder\n\t"
+-	"mtc0\t$1,$12\n\t"
+-	"irq_disable_hazard\n\t"
+-	".set\tpop\n\t"
+-	".endm");
++	"	.macro	local_irq_disable\n"
++	"	.set	push						\n"
++	"	.set	noat						\n"
++#ifdef CONFIG_CPU_MIPSR2
++	"	di							\n"
++#else
++	"	mfc0	$1,$12						\n"
++	"	ori	$1,1						\n"
++	"	xori	$1,1						\n"
++	"	.set	noreorder					\n"
++	"	mtc0	$1,$12						\n"
++#endif
++	"	irq_disable_hazard					\n"
++	"	.set	pop						\n"
++	"	.endm							\n");
+ 
+ static inline void local_irq_disable(void)
+ {
+@@ -65,12 +74,12 @@ static inline void local_irq_disable(voi
+ }
+ 
+ __asm__ (
+-	".macro\tlocal_save_flags flags\n\t"
+-	".set\tpush\n\t"
+-	".set\treorder\n\t"
+-	"mfc0\t\\flags, $12\n\t"
+-	".set\tpop\n\t"
+-	".endm");
++	"	.macro	local_save_flags flags				\n"
++	"	.set	push						\n"
++	"	.set	reorder						\n"
++	"	mfc0	\\flags, $12					\n"
++	"	.set	pop						\n"
++	"	.endm							\n");
+ 
+ #define local_save_flags(x)						\
+ __asm__ __volatile__(							\
+@@ -78,18 +87,22 @@ __asm__ __volatile__(							\
+ 	: "=r" (x))
+ 
+ __asm__ (
+-	".macro\tlocal_irq_save result\n\t"
+-	".set\tpush\n\t"
+-	".set\treorder\n\t"
+-	".set\tnoat\n\t"
+-	"mfc0\t\\result, $12\n\t"
+-	"ori\t$1, \\result, 1\n\t"
+-	"xori\t$1, 1\n\t"
+-	".set\tnoreorder\n\t"
+-	"mtc0\t$1, $12\n\t"
+-	"irq_disable_hazard\n\t"
+-	".set\tpop\n\t"
+-	".endm");
++	"	.macro	local_irq_save result				\n"
++	"	.set	push						\n"
++	"	.set	reorder						\n"
++	"	.set	noat						\n"
++#ifdef CONFIG_CPU_MIPSR2
++	"	di	\\result					\n"
++#else
++	"	mfc0	\\result, $12					\n"
++	"	ori	$1, \\result, 1					\n"
++	"	xori	$1, 1						\n"
++	"	.set	noreorder					\n"
++	"	mtc0	$1, $12						\n"
++#endif
++	"	irq_disable_hazard					\n"
++	"	.set	pop						\n"
++	"	.endm							\n");
+ 
+ #define local_irq_save(x)						\
+ __asm__ __volatile__(							\
+@@ -99,19 +112,37 @@ __asm__ __volatile__(							\
+ 	: "memory")
+ 
+ __asm__ (
+-	".macro\tlocal_irq_restore flags\n\t"
+-	".set\tnoreorder\n\t"
+-	".set\tnoat\n\t"
+-	"mfc0\t$1, $12\n\t"
+-	"andi\t\\flags, 1\n\t"
+-	"ori\t$1, 1\n\t"
+-	"xori\t$1, 1\n\t"
+-	"or\t\\flags, $1\n\t"
+-	"mtc0\t\\flags, $12\n\t"
+-	"irq_disable_hazard\n\t"
+-	".set\tat\n\t"
+-	".set\treorder\n\t"
+-	".endm");
++	"	.macro	local_irq_restore flags				\n"
++	"	.set	noreorder					\n"
++	"	.set	noat						\n"
++#if 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, 1						\n"
++	"	xori	$1, 1						\n"
++	"	or	\\flags, $1					\n"
++	"	mtc0	\\flags, $12					\n"
++#endif
++	"	irq_disable_hazard					\n"
++	"	.set	at						\n"
++	"	.set	reorder						\n"
++	"	.endm							\n");
+ 
+ #define local_irq_restore(flags)					\
+ do {									\
+diff --git a/include/asm-mips/inventory.h b/include/asm-mips/inventory.h
+--- a/include/asm-mips/inventory.h
++++ b/include/asm-mips/inventory.h
+@@ -4,6 +4,8 @@
+ #ifndef __ASM_INVENTORY_H
+ #define __ASM_INVENTORY_H
+ 
++#include <linux/compiler.h>
++
+ typedef struct inventory_s {
+ 	struct inventory_s *inv_next;
+ 	int    inv_class;
+@@ -14,7 +16,9 @@ typedef struct inventory_s {
+ } inventory_t;
+ 
+ extern int inventory_items;
+-void add_to_inventory (int class, int type, int controller, int unit, int state);
+-int dump_inventory_to_user (void *userbuf, int size);
++
++extern void add_to_inventory (int class, int type, int controller, int unit, int state);
++extern int dump_inventory_to_user (void __user *userbuf, int size);
++extern int __init init_inventory(void);
+ 
+ #endif /* __ASM_INVENTORY_H */
+diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
+--- a/include/asm-mips/io.h
++++ b/include/asm-mips/io.h
+@@ -25,7 +25,9 @@
+ #include <asm/page.h>
+ #include <asm/pgtable-bits.h>
+ #include <asm/processor.h>
++#include <asm/string.h>
+ 
++#include <ioremap.h>
+ #include <mangle-port.h>
+ 
+ /*
+@@ -34,7 +36,7 @@
+ #undef CONF_SLOWDOWN_IO
+ 
+ /*
+- * Raw operations are never swapped in software.  Otoh values that raw
++ * Raw operations are never swapped in software.  OTOH values that raw
+  * operations are working on may or may not have been swapped by the bus
+  * hardware.  An example use would be for flash memory that's used for
+  * execute in place.
+@@ -43,45 +45,53 @@
+ # define __raw_ioswabw(x)	(x)
+ # define __raw_ioswabl(x)	(x)
+ # define __raw_ioswabq(x)	(x)
++# define ____raw_ioswabq(x)	(x)
+ 
+ /*
+  * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
+  * less sane hardware forces software to fiddle with this...
++ *
++ * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
++ * you can't have the numerical value of data and byte addresses within
++ * multibyte quantities both preserved at the same time.  Hence two
++ * variations of functions: non-prefixed ones that preserve the value
++ * and prefixed ones that preserve byte addresses.  The latters are
++ * typically used for moving raw data between a peripheral and memory (cf.
++ * string I/O functions), hence the "mem_" prefix.
+  */
+ #if defined(CONFIG_SWAP_IO_SPACE)
+ 
+ # define ioswabb(x)		(x)
++# define mem_ioswabb(x)		(x)
+ # ifdef CONFIG_SGI_IP22
+ /*
+  * IP22 seems braindead enough to swap 16bits values in hardware, but
+  * not 32bits.  Go figure... Can't tell without documentation.
+  */
+ #  define ioswabw(x)		(x)
++#  define mem_ioswabw(x)	le16_to_cpu(x)
+ # else
+ #  define ioswabw(x)		le16_to_cpu(x)
++#  define mem_ioswabw(x)	(x)
+ # endif
+ # define ioswabl(x)		le32_to_cpu(x)
++# define mem_ioswabl(x)		(x)
+ # define ioswabq(x)		le64_to_cpu(x)
++# define mem_ioswabq(x)		(x)
+ 
+ #else
+ 
+ # define ioswabb(x)		(x)
++# define mem_ioswabb(x)		(x)
+ # define ioswabw(x)		(x)
++# define mem_ioswabw(x)		cpu_to_le16(x)
+ # define ioswabl(x)		(x)
++# define mem_ioswabl(x)		cpu_to_le32(x)
+ # define ioswabq(x)		(x)
++# define mem_ioswabq(x)		cpu_to_le32(x)
+ 
+ #endif
+ 
+-/*
+- * Native bus accesses never swapped.
+- */
+-#define bus_ioswabb(x)		(x)
+-#define bus_ioswabw(x)		(x)
+-#define bus_ioswabl(x)		(x)
+-#define bus_ioswabq(x)		(x)
+-
+-#define __bus_ioswabq		bus_ioswabq
+-
+ #define IO_SPACE_LIMIT 0xffff
+ 
+ /*
+@@ -194,12 +204,14 @@ extern unsigned long isa_slot_offset;
+  */
+ #define page_to_phys(page)	((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
+ 
+-extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags);
++extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags);
+ extern void __iounmap(volatile void __iomem *addr);
+ 
+-static inline void * __ioremap_mode(phys_t offset, unsigned long size,
++static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
+ 	unsigned long flags)
+ {
++#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
++
+ 	if (cpu_has_64bit_addresses) {
+ 		u64 base = UNCAC_BASE;
+ 
+@@ -209,10 +221,30 @@ static inline void * __ioremap_mode(phys
+ 		 */
+ 		if (flags == _CACHE_UNCACHED)
+ 			base = (u64) IO_BASE;
+-		return (void *) (unsigned long) (base + offset);
++		return (void __iomem *) (unsigned long) (base + offset);
++	} else if (__builtin_constant_p(offset) &&
++		   __builtin_constant_p(size) && __builtin_constant_p(flags)) {
++		phys_t phys_addr, last_addr;
++
++		phys_addr = fixup_bigphys_addr(offset, size);
++
++		/* Don't allow wraparound or zero size. */
++		last_addr = phys_addr + size - 1;
++		if (!size || last_addr < phys_addr)
++			return NULL;
++
++		/*
++		 * Map uncached objects in the low 512MB of address
++		 * space using KSEG1.
++		 */
++		if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
++		    flags == _CACHE_UNCACHED)
++			return (void __iomem *)CKSEG1ADDR(phys_addr);
+ 	}
+ 
+ 	return __ioremap(offset, size, flags);
++
++#undef __IS_LOW512
+ }
+ 
+ /*
+@@ -264,12 +296,16 @@ static inline void * __ioremap_mode(phys
+ 
+ static inline void iounmap(volatile void __iomem *addr)
+ {
+-	if (cpu_has_64bit_addresses)
++#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
++
++	if (cpu_has_64bit_addresses ||
++	    (__builtin_constant_p(addr) && __IS_KSEG1(addr)))
+ 		return;
+ 
+ 	__iounmap(addr);
+-}
+ 
++#undef __IS_KSEG1
++}
+ 
+ #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq)			\
+ 									\
+@@ -319,7 +355,8 @@ static inline type pfx##read##bwlq(volat
+ 	else if (cpu_has_64bits) {					\
+ 		unsigned long __flags;					\
+ 									\
+-		local_irq_save(__flags);				\
++		if (irq)						\
++			local_irq_save(__flags);			\
+ 		__asm__ __volatile__(					\
+ 			".set	mips3"		"\t\t# __readq"	"\n\t"	\
+ 			"ld	%L0, %1"			"\n\t"	\
+@@ -328,7 +365,8 @@ static inline type pfx##read##bwlq(volat
+ 			".set	mips0"				"\n"	\
+ 			: "=r" (__val)					\
+ 			: "m" (*__mem));				\
+-		local_irq_restore(__flags);				\
++		if (irq)						\
++			local_irq_restore(__flags);			\
+ 	} else {							\
+ 		__val = 0;						\
+ 		BUG();							\
+@@ -349,11 +387,11 @@ static inline void pfx##out##bwlq##p(typ
+ 									\
+ 	__val = pfx##ioswab##bwlq(val);					\
+ 									\
+-	if (sizeof(type) != sizeof(u64)) {				\
+-		*__addr = __val;					\
+-		slow;							\
+-	} else								\
+-		BUILD_BUG();						\
++	/* Really, we want this to be atomic */				\
++	BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long));		\
++									\
++	*__addr = __val;						\
++	slow;								\
+ }									\
+ 									\
+ static inline type pfx##in##bwlq##p(unsigned long port)			\
+@@ -364,13 +402,10 @@ static inline type pfx##in##bwlq##p(unsi
+ 	port = __swizzle_addr_##bwlq(port);				\
+ 	__addr = (void *)(mips_io_port_base + port);			\
+ 									\
+-	if (sizeof(type) != sizeof(u64)) {				\
+-		__val = *__addr;					\
+-		slow;							\
+-	} else {							\
+-		__val = 0;						\
+-		BUILD_BUG();						\
+-	}								\
++	BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long));		\
++									\
++	__val = *__addr;						\
++	slow;								\
+ 									\
+ 	return pfx##ioswab##bwlq(__val);				\
+ }
+@@ -379,27 +414,35 @@ static inline type pfx##in##bwlq##p(unsi
+ 									\
+ __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
+ 
+-#define __BUILD_IOPORT_PFX(bus, bwlq, type)				\
+-									\
+-__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,)				\
+-__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
+-
+-#define BUILDIO(bwlq, type)						\
++#define BUILDIO_MEM(bwlq, type)						\
+ 									\
+-__BUILD_MEMORY_PFX(, bwlq, type)					\
+ __BUILD_MEMORY_PFX(__raw_, bwlq, type)					\
+-__BUILD_MEMORY_PFX(bus_, bwlq, type)					\
+-__BUILD_IOPORT_PFX(, bwlq, type)					\
+-__BUILD_IOPORT_PFX(__raw_, bwlq, type)
++__BUILD_MEMORY_PFX(, bwlq, type)					\
++__BUILD_MEMORY_PFX(mem_, bwlq, type)					\
++
++BUILDIO_MEM(b, u8)
++BUILDIO_MEM(w, u16)
++BUILDIO_MEM(l, u32)
++BUILDIO_MEM(q, u64)
++
++#define __BUILD_IOPORT_PFX(bus, bwlq, type)				\
++	__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,)			\
++	__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
++
++#define BUILDIO_IOPORT(bwlq, type)					\
++	__BUILD_IOPORT_PFX(, bwlq, type)				\
++	__BUILD_IOPORT_PFX(mem_, bwlq, type)
++
++BUILDIO_IOPORT(b, u8)
++BUILDIO_IOPORT(w, u16)
++BUILDIO_IOPORT(l, u32)
++#ifdef CONFIG_64BIT
++BUILDIO_IOPORT(q, u64)
++#endif
+ 
+ #define __BUILDIO(bwlq, type)						\
+ 									\
+-__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0)
+-
+-BUILDIO(b, u8)
+-BUILDIO(w, u16)
+-BUILDIO(l, u32)
+-BUILDIO(q, u64)
++__BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0)
+ 
+ __BUILDIO(q, u64)
+ 
+@@ -422,7 +465,7 @@ static inline void writes##bwlq(volatile
+ 	volatile type *__addr = addr;					\
+ 									\
+ 	while (count--) {						\
+-		__raw_write##bwlq(*__addr, mem);			\
++		mem_write##bwlq(*__addr, mem);				\
+ 		__addr++;						\
+ 	}								\
+ }									\
+@@ -433,20 +476,20 @@ static inline void reads##bwlq(volatile 
+ 	volatile type *__addr = addr;					\
+ 									\
+ 	while (count--) {						\
+-		*__addr = __raw_read##bwlq(mem);			\
++		*__addr = mem_read##bwlq(mem);				\
+ 		__addr++;						\
+ 	}								\
+ }
+ 
+ #define __BUILD_IOPORT_STRING(bwlq, type)				\
+ 									\
+-static inline void outs##bwlq(unsigned long port, void *addr,		\
++static inline void outs##bwlq(unsigned long port, const void *addr,	\
+ 			      unsigned int count)			\
+ {									\
+-	volatile type *__addr = addr;					\
++	const volatile type *__addr = addr;				\
+ 									\
+ 	while (count--) {						\
+-		__raw_out##bwlq(*__addr, port);				\
++		mem_out##bwlq(*__addr, port);				\
+ 		__addr++;						\
+ 	}								\
+ }									\
+@@ -457,7 +500,7 @@ static inline void ins##bwlq(unsigned lo
+ 	volatile type *__addr = addr;					\
+ 									\
+ 	while (count--) {						\
+-		*__addr = __raw_in##bwlq(port);				\
++		*__addr = mem_in##bwlq(port);				\
+ 		__addr++;						\
+ 	}								\
+ }
+@@ -470,15 +513,26 @@ __BUILD_IOPORT_STRING(bwlq, type)
+ BUILDSTRING(b, u8)
+ BUILDSTRING(w, u16)
+ BUILDSTRING(l, u32)
++#ifdef CONFIG_64BIT
+ BUILDSTRING(q, u64)
++#endif
+ 
+ 
+ /* Depends on MIPS II instruction set */
+ #define mmiowb() asm volatile ("sync" ::: "memory")
+ 
+-#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+-#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+-#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
++static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
++{
++	memset((void __force *) addr, val, count);
++}
++static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
++{
++	memcpy(dst, (void __force *) src, count);
++}
++static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
++{
++	memcpy((void __force *) dst, src, count);
++}
+ 
+ /*
+  * Memory Mapped I/O
+diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
+--- a/include/asm-mips/irq.h
++++ b/include/asm-mips/irq.h
+@@ -24,11 +24,9 @@ static inline int irq_canonicalize(int i
+ 
+ struct pt_regs;
+ 
+-#ifdef CONFIG_PREEMPT
+-
+ extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs);
+ 
+-#else
++#ifdef CONFIG_PREEMPT
+ 
+ /*
+  * do_IRQ handles all normal device IRQ's (the special
+diff --git a/include/asm-mips/jmr3927/jmr3927.h b/include/asm-mips/jmr3927/jmr3927.h
+--- a/include/asm-mips/jmr3927/jmr3927.h
++++ b/include/asm-mips/jmr3927/jmr3927.h
+@@ -202,20 +202,6 @@ static inline int jmr3927_have_isac(void
+ #endif /* !__ASSEMBLY__ */
+ 
+ /*
+- * UART defines for serial.h
+- */
+-
+-/* use Pre-scaler T0 (1/2) */
+-#define JMR3927_BASE_BAUD (JMR3927_IMCLK / 2 / 16)
+-
+-#define UART0_ADDR   0xfffef300
+-#define UART1_ADDR   0xfffef400
+-#define UART0_INT    JMR3927_IRQ_IRC_SIO0
+-#define UART1_INT    JMR3927_IRQ_IRC_SIO1
+-#define UART0_FLAGS  ASYNC_BOOT_AUTOCONF
+-#define UART1_FLAGS  0
+-
+-/*
+  * IRQ mappings
+  */
+ 
+diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
+--- a/include/asm-mips/mach-au1x00/au1000.h
++++ b/include/asm-mips/mach-au1x00/au1000.h
+@@ -60,59 +60,36 @@ void static inline au_sync_delay(int ms)
+ 	mdelay(ms);
+ }
+ 
+-void static inline au_writeb(u8 val, int reg)
++void static inline au_writeb(u8 val, unsigned long reg)
+ {
+ 	*(volatile u8 *)(reg) = val;
+ }
+ 
+-void static inline au_writew(u16 val, int reg)
++void static inline au_writew(u16 val, unsigned long reg)
+ {
+ 	*(volatile u16 *)(reg) = val;
+ }
+ 
+-void static inline au_writel(u32 val, int reg)
++void static inline au_writel(u32 val, unsigned long reg)
+ {
+ 	*(volatile u32 *)(reg) = val;
+ }
+ 
+-static inline u8 au_readb(unsigned long port)
++static inline u8 au_readb(unsigned long reg)
+ {
+-	return (*(volatile u8 *)port);
++	return (*(volatile u8 *)reg);
+ }
+ 
+-static inline u16 au_readw(unsigned long port)
++static inline u16 au_readw(unsigned long reg)
+ {
+-	return (*(volatile u16 *)port);
++	return (*(volatile u16 *)reg);
+ }
+ 
+-static inline u32 au_readl(unsigned long port)
++static inline u32 au_readl(unsigned long reg)
+ {
+-	return (*(volatile u32 *)port);
++	return (*(volatile u32 *)reg);
+ }
+ 
+-/* These next three functions should be a generic part of the MIPS
+- * kernel (with the 'au_' removed from the name) and selected for
+- * processors that support the instructions.
+- * Taken from PPC tree.  -- Dan
+- */
+-/* Return the bit position of the most significant 1 bit in a word */
+-static __inline__ int __ilog2(unsigned int x)
+-{
+-	int lz;
+-
+-	asm volatile (
+-		".set\tnoreorder\n\t"
+-		".set\tnoat\n\t"
+-		".set\tmips32\n\t"
+-		"clz\t%0,%1\n\t"
+-		".set\tmips0\n\t"
+-		".set\tat\n\t"
+-		".set\treorder"
+-		: "=r" (lz)
+-		: "r" (x));
+-
+-	return 31 - lz;
+-}
+ 
+ static __inline__ int au_ffz(unsigned int x)
+ {
+@@ -162,28 +139,293 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+ #endif
+ 
+-/* SDRAM Controller */
++/*
++ * SDRAM Register Offsets
++ */
+ #if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
+-#define MEM_SDMODE0                0xB4000000
+-#define MEM_SDMODE1                0xB4000004
+-#define MEM_SDMODE2                0xB4000008
+-
+-#define MEM_SDADDR0                0xB400000C
+-#define MEM_SDADDR1                0xB4000010
+-#define MEM_SDADDR2                0xB4000014
+-
+-#define MEM_SDREFCFG               0xB4000018
+-#define MEM_SDPRECMD               0xB400001C
+-#define MEM_SDAUTOREF              0xB4000020
+-
+-#define MEM_SDWRMD0                0xB4000024
+-#define MEM_SDWRMD1                0xB4000028
+-#define MEM_SDWRMD2                0xB400002C
++#define MEM_SDMODE0		(0x0000)
++#define MEM_SDMODE1		(0x0004)
++#define MEM_SDMODE2		(0x0008)
++#define MEM_SDADDR0		(0x000C)
++#define MEM_SDADDR1		(0x0010)
++#define MEM_SDADDR2		(0x0014)
++#define MEM_SDREFCFG	(0x0018)
++#define MEM_SDPRECMD	(0x001C)
++#define MEM_SDAUTOREF	(0x0020)
++#define MEM_SDWRMD0		(0x0024)
++#define MEM_SDWRMD1		(0x0028)
++#define MEM_SDWRMD2		(0x002C)
++#define MEM_SDSLEEP		(0x0030)
++#define MEM_SDSMCKE		(0x0034)
++
++/*
++ * MEM_SDMODE register content definitions
++ */
++#define MEM_SDMODE_F		(1<<22)
++#define MEM_SDMODE_SR		(1<<21)
++#define MEM_SDMODE_BS		(1<<20)
++#define MEM_SDMODE_RS		(3<<18)
++#define MEM_SDMODE_CS		(7<<15)
++#define MEM_SDMODE_TRAS		(15<<11)
++#define MEM_SDMODE_TMRD		(3<<9)
++#define MEM_SDMODE_TWR		(3<<7)
++#define MEM_SDMODE_TRP		(3<<5)
++#define MEM_SDMODE_TRCD		(3<<3)
++#define MEM_SDMODE_TCL		(7<<0)
++
++#define MEM_SDMODE_BS_2Bank	(0<<20)
++#define MEM_SDMODE_BS_4Bank	(1<<20)
++#define MEM_SDMODE_RS_11Row	(0<<18)
++#define MEM_SDMODE_RS_12Row	(1<<18)
++#define MEM_SDMODE_RS_13Row	(2<<18)
++#define MEM_SDMODE_RS_N(N)	((N)<<18)
++#define MEM_SDMODE_CS_7Col	(0<<15)
++#define MEM_SDMODE_CS_8Col	(1<<15)
++#define MEM_SDMODE_CS_9Col	(2<<15)
++#define MEM_SDMODE_CS_10Col	(3<<15)
++#define MEM_SDMODE_CS_11Col	(4<<15)
++#define MEM_SDMODE_CS_N(N)		((N)<<15)
++#define MEM_SDMODE_TRAS_N(N)	((N)<<11)
++#define MEM_SDMODE_TMRD_N(N)	((N)<<9)
++#define MEM_SDMODE_TWR_N(N)		((N)<<7)
++#define MEM_SDMODE_TRP_N(N)		((N)<<5)
++#define MEM_SDMODE_TRCD_N(N)	((N)<<3)
++#define MEM_SDMODE_TCL_N(N)		((N)<<0)
++
++/*
++ * MEM_SDADDR register contents definitions
++ */
++#define MEM_SDADDR_E			(1<<20)
++#define MEM_SDADDR_CSBA			(0x03FF<<10)
++#define MEM_SDADDR_CSMASK		(0x03FF<<0)
++#define MEM_SDADDR_CSBA_N(N)	((N)&(0x03FF<<22)>>12)
++#define MEM_SDADDR_CSMASK_N(N)	((N)&(0x03FF<<22)>>22)
+ 
+-#define MEM_SDSLEEP                0xB4000030
+-#define MEM_SDSMCKE                0xB4000034
++/*
++ * MEM_SDREFCFG register content definitions
++ */
++#define MEM_SDREFCFG_TRC		(15<<28)
++#define MEM_SDREFCFG_TRPM		(3<<26)
++#define MEM_SDREFCFG_E			(1<<25)
++#define MEM_SDREFCFG_RE			(0x1ffffff<<0)
++#define MEM_SDREFCFG_TRC_N(N)	((N)<<MEM_SDREFCFG_TRC)
++#define MEM_SDREFCFG_TRPM_N(N)	((N)<<MEM_SDREFCFG_TRPM)
++#define MEM_SDREFCFG_REF_N(N)	(N)
+ #endif
+ 
++/***********************************************************************/
++
++/*
++ * Au1550 SDRAM Register Offsets
++ */
++
++/***********************************************************************/
++
++#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
++#define MEM_SDMODE0		(0x0800)
++#define MEM_SDMODE1		(0x0808)
++#define MEM_SDMODE2		(0x0810)
++#define MEM_SDADDR0		(0x0820)
++#define MEM_SDADDR1		(0x0828)
++#define MEM_SDADDR2		(0x0830)
++#define MEM_SDCONFIGA	(0x0840)
++#define MEM_SDCONFIGB	(0x0848)
++#define MEM_SDSTAT		(0x0850)
++#define MEM_SDERRADDR	(0x0858)
++#define MEM_SDSTRIDE0	(0x0860)
++#define MEM_SDSTRIDE1	(0x0868)
++#define MEM_SDSTRIDE2	(0x0870)
++#define MEM_SDWRMD0		(0x0880)
++#define MEM_SDWRMD1		(0x0888)
++#define MEM_SDWRMD2		(0x0890)
++#define MEM_SDPRECMD	(0x08C0)
++#define MEM_SDAUTOREF	(0x08C8)
++#define MEM_SDSREF		(0x08D0)
++#define MEM_SDSLEEP		MEM_SDSREF
++
++#endif
++
++/*
++ * Physical base addresses for integrated peripherals
++ */
++
++#ifdef CONFIG_SOC_AU1000
++#define	MEM_PHYS_ADDR		0x14000000
++#define	STATIC_MEM_PHYS_ADDR	0x14001000
++#define	DMA0_PHYS_ADDR		0x14002000
++#define	DMA1_PHYS_ADDR		0x14002100
++#define	DMA2_PHYS_ADDR		0x14002200
++#define	DMA3_PHYS_ADDR		0x14002300
++#define	DMA4_PHYS_ADDR		0x14002400
++#define	DMA5_PHYS_ADDR		0x14002500
++#define	DMA6_PHYS_ADDR		0x14002600
++#define	DMA7_PHYS_ADDR		0x14002700
++#define	IC0_PHYS_ADDR		0x10400000
++#define	IC1_PHYS_ADDR		0x11800000
++#define	AC97_PHYS_ADDR		0x10000000
++#define	USBH_PHYS_ADDR		0x10100000
++#define	USBD_PHYS_ADDR		0x10200000
++#define	IRDA_PHYS_ADDR		0x10300000
++#define	MAC0_PHYS_ADDR		0x10500000
++#define	MAC1_PHYS_ADDR		0x10510000
++#define	MACEN_PHYS_ADDR		0x10520000
++#define	MACDMA0_PHYS_ADDR	0x14004000
++#define	MACDMA1_PHYS_ADDR	0x14004200
++#define	I2S_PHYS_ADDR		0x11000000
++#define	UART0_PHYS_ADDR		0x11100000
++#define	UART1_PHYS_ADDR		0x11200000
++#define	UART2_PHYS_ADDR		0x11300000
++#define	UART3_PHYS_ADDR		0x11400000
++#define	SSI0_PHYS_ADDR		0x11600000
++#define	SSI1_PHYS_ADDR		0x11680000
++#define	SYS_PHYS_ADDR		0x11900000
++#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#endif
++
++/********************************************************************/
++
++#ifdef CONFIG_SOC_AU1500
++#define	MEM_PHYS_ADDR		0x14000000
++#define	STATIC_MEM_PHYS_ADDR	0x14001000
++#define	DMA0_PHYS_ADDR		0x14002000
++#define	DMA1_PHYS_ADDR		0x14002100
++#define	DMA2_PHYS_ADDR		0x14002200
++#define	DMA3_PHYS_ADDR		0x14002300
++#define	DMA4_PHYS_ADDR		0x14002400
++#define	DMA5_PHYS_ADDR		0x14002500
++#define	DMA6_PHYS_ADDR		0x14002600
++#define	DMA7_PHYS_ADDR		0x14002700
++#define	IC0_PHYS_ADDR		0x10400000
++#define	IC1_PHYS_ADDR		0x11800000
++#define	AC97_PHYS_ADDR		0x10000000
++#define	USBH_PHYS_ADDR		0x10100000
++#define	USBD_PHYS_ADDR		0x10200000
++#define PCI_PHYS_ADDR		0x14005000
++#define	MAC0_PHYS_ADDR		0x11500000
++#define	MAC1_PHYS_ADDR		0x11510000
++#define	MACEN_PHYS_ADDR		0x11520000
++#define	MACDMA0_PHYS_ADDR	0x14004000
++#define	MACDMA1_PHYS_ADDR	0x14004200
++#define	I2S_PHYS_ADDR		0x11000000
++#define	UART0_PHYS_ADDR		0x11100000
++#define	UART3_PHYS_ADDR		0x11400000
++#define GPIO2_PHYS_ADDR		0x11700000
++#define	SYS_PHYS_ADDR		0x11900000
++#define PCI_MEM_PHYS_ADDR     0x400000000ULL
++#define PCI_IO_PHYS_ADDR      0x500000000ULL
++#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
++#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
++#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#endif
++
++/********************************************************************/
++
++#ifdef CONFIG_SOC_AU1100
++#define	MEM_PHYS_ADDR		0x14000000
++#define	STATIC_MEM_PHYS_ADDR	0x14001000
++#define	DMA0_PHYS_ADDR		0x14002000
++#define	DMA1_PHYS_ADDR		0x14002100
++#define	DMA2_PHYS_ADDR		0x14002200
++#define	DMA3_PHYS_ADDR		0x14002300
++#define	DMA4_PHYS_ADDR		0x14002400
++#define	DMA5_PHYS_ADDR		0x14002500
++#define	DMA6_PHYS_ADDR		0x14002600
++#define	DMA7_PHYS_ADDR		0x14002700
++#define	IC0_PHYS_ADDR		0x10400000
++#define SD0_PHYS_ADDR		0x10600000
++#define SD1_PHYS_ADDR		0x10680000
++#define	IC1_PHYS_ADDR		0x11800000
++#define	AC97_PHYS_ADDR		0x10000000
++#define	USBH_PHYS_ADDR		0x10100000
++#define	USBD_PHYS_ADDR		0x10200000
++#define	IRDA_PHYS_ADDR		0x10300000
++#define	MAC0_PHYS_ADDR		0x10500000
++#define	MACEN_PHYS_ADDR		0x10520000
++#define	MACDMA0_PHYS_ADDR	0x14004000
++#define	MACDMA1_PHYS_ADDR	0x14004200
++#define	I2S_PHYS_ADDR		0x11000000
++#define	UART0_PHYS_ADDR		0x11100000
++#define	UART1_PHYS_ADDR		0x11200000
++#define	UART3_PHYS_ADDR		0x11400000
++#define	SSI0_PHYS_ADDR		0x11600000
++#define	SSI1_PHYS_ADDR		0x11680000
++#define GPIO2_PHYS_ADDR		0x11700000
++#define	SYS_PHYS_ADDR		0x11900000
++#define LCD_PHYS_ADDR		0x15000000
++#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#endif
++
++/***********************************************************************/
++
++#ifdef CONFIG_SOC_AU1550
++#define	MEM_PHYS_ADDR		0x14000000
++#define	STATIC_MEM_PHYS_ADDR	0x14001000
++#define	IC0_PHYS_ADDR		0x10400000
++#define	IC1_PHYS_ADDR		0x11800000
++#define	USBH_PHYS_ADDR		0x14020000
++#define	USBD_PHYS_ADDR		0x10200000
++#define PCI_PHYS_ADDR		0x14005000
++#define	MAC0_PHYS_ADDR		0x10500000
++#define	MAC1_PHYS_ADDR		0x10510000
++#define	MACEN_PHYS_ADDR		0x10520000
++#define	MACDMA0_PHYS_ADDR	0x14004000
++#define	MACDMA1_PHYS_ADDR	0x14004200
++#define	UART0_PHYS_ADDR		0x11100000
++#define	UART1_PHYS_ADDR		0x11200000
++#define	UART3_PHYS_ADDR		0x11400000
++#define GPIO2_PHYS_ADDR		0x11700000
++#define	SYS_PHYS_ADDR		0x11900000
++#define	DDMA_PHYS_ADDR		0x14002000
++#define PE_PHYS_ADDR		0x14008000
++#define PSC0_PHYS_ADDR	 	0x11A00000
++#define PSC1_PHYS_ADDR	 	0x11B00000
++#define PSC2_PHYS_ADDR	 	0x10A00000
++#define PSC3_PHYS_ADDR	 	0x10B00000
++#define PCI_MEM_PHYS_ADDR     0x400000000ULL
++#define PCI_IO_PHYS_ADDR      0x500000000ULL
++#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
++#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
++#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#endif
++
++/***********************************************************************/
++
++#ifdef CONFIG_SOC_AU1200
++#define	MEM_PHYS_ADDR		0x14000000
++#define	STATIC_MEM_PHYS_ADDR	0x14001000
++#define AES_PHYS_ADDR		0x10300000
++#define CIM_PHYS_ADDR		0x14004000
++#define	IC0_PHYS_ADDR		0x10400000
++#define	IC1_PHYS_ADDR		0x11800000
++#define USBM_PHYS_ADDR		0x14020000
++#define	USBH_PHYS_ADDR		0x14020100
++#define	UART0_PHYS_ADDR		0x11100000
++#define	UART1_PHYS_ADDR		0x11200000
++#define GPIO2_PHYS_ADDR		0x11700000
++#define	SYS_PHYS_ADDR		0x11900000
++#define	DDMA_PHYS_ADDR		0x14002000
++#define PSC0_PHYS_ADDR	 	0x11A00000
++#define PSC1_PHYS_ADDR	 	0x11B00000
++#define SD0_PHYS_ADDR		0x10600000
++#define SD1_PHYS_ADDR		0x10680000
++#define LCD_PHYS_ADDR		0x15000000
++#define SWCNT_PHYS_ADDR		0x1110010C
++#define MAEFE_PHYS_ADDR		0x14012000
++#define MAEBE_PHYS_ADDR		0x14010000
++#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#endif
++
++
+ /* Static Bus Controller */
+ #define MEM_STCFG0                 0xB4001000
+ #define MEM_STTIME0                0xB4001004
+@@ -369,7 +611,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1000_MAC0_ENABLE       0xB0520000
+ #define AU1000_MAC1_ENABLE       0xB0520004
+ #define NUM_ETH_INTERFACES 2
+-#endif // CONFIG_SOC_AU1000
++#endif /* CONFIG_SOC_AU1000 */
+ 
+ /* Au1500 */
+ #ifdef CONFIG_SOC_AU1500
+@@ -429,6 +671,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1500_GPIO_207           62
+ #define AU1500_GPIO_208_215       63
+ 
++/* shortcuts */
++#define INTA AU1000_PCI_INTA
++#define INTB AU1000_PCI_INTB
++#define INTC AU1000_PCI_INTC
++#define INTD AU1000_PCI_INTD
++
+ #define UART0_ADDR                0xB1100000
+ #define UART3_ADDR                0xB1400000
+ 
+@@ -440,7 +688,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1500_MAC0_ENABLE       0xB1520000
+ #define AU1500_MAC1_ENABLE       0xB1520004
+ #define NUM_ETH_INTERFACES 2
+-#endif // CONFIG_SOC_AU1500
++#endif /* CONFIG_SOC_AU1500 */
+ 
+ /* Au1100 */
+ #ifdef CONFIG_SOC_AU1100
+@@ -485,6 +733,22 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1000_GPIO_13            45
+ #define AU1000_GPIO_14            46
+ #define AU1000_GPIO_15            47
++#define AU1000_GPIO_16            48
++#define AU1000_GPIO_17            49
++#define AU1000_GPIO_18            50
++#define AU1000_GPIO_19            51
++#define AU1000_GPIO_20            52
++#define AU1000_GPIO_21            53
++#define AU1000_GPIO_22            54
++#define AU1000_GPIO_23            55
++#define AU1000_GPIO_24            56
++#define AU1000_GPIO_25            57
++#define AU1000_GPIO_26            58
++#define AU1000_GPIO_27            59
++#define AU1000_GPIO_28            60
++#define AU1000_GPIO_29            61
++#define AU1000_GPIO_30            62
++#define AU1000_GPIO_31            63
+ 
+ #define UART0_ADDR                0xB1100000
+ #define UART1_ADDR                0xB1200000
+@@ -496,7 +760,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1100_ETH0_BASE	  0xB0500000
+ #define AU1100_MAC0_ENABLE       0xB0520000
+ #define NUM_ETH_INTERFACES 1
+-#endif // CONFIG_SOC_AU1100
++#endif /* CONFIG_SOC_AU1100 */
+ 
+ #ifdef CONFIG_SOC_AU1550
+ #define AU1550_UART0_INT          0
+@@ -513,14 +777,14 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1550_PSC1_INT           11
+ #define AU1550_PSC2_INT           12
+ #define AU1550_PSC3_INT           13
+-#define AU1550_TOY_INT			  14
+-#define AU1550_TOY_MATCH0_INT     15
+-#define AU1550_TOY_MATCH1_INT     16
+-#define AU1550_TOY_MATCH2_INT     17
+-#define AU1550_RTC_INT            18
+-#define AU1550_RTC_MATCH0_INT     19
+-#define AU1550_RTC_MATCH1_INT     20
+-#define AU1550_RTC_MATCH2_INT     21
++#define AU1000_TOY_INT			  14
++#define AU1000_TOY_MATCH0_INT     15
++#define AU1000_TOY_MATCH1_INT     16
++#define AU1000_TOY_MATCH2_INT     17
++#define AU1000_RTC_INT            18
++#define AU1000_RTC_MATCH0_INT     19
++#define AU1000_RTC_MATCH1_INT     20
++#define AU1000_RTC_MATCH2_INT     21
+ #define AU1550_NAND_INT           23
+ #define AU1550_USB_DEV_REQ_INT    24
+ #define AU1550_USB_DEV_SUS_INT    25
+@@ -563,6 +827,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1500_GPIO_207           62
+ #define AU1500_GPIO_208_218       63	// Logical or of GPIO208:218
+ 
++/* shortcuts */
++#define INTA AU1550_PCI_INTA
++#define INTB AU1550_PCI_INTB
++#define INTC AU1550_PCI_INTC
++#define INTD AU1550_PCI_INTD
++
+ #define UART0_ADDR                0xB1100000
+ #define UART1_ADDR                0xB1200000
+ #define UART3_ADDR                0xB1400000
+@@ -575,7 +845,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1550_MAC0_ENABLE       0xB0520000
+ #define AU1550_MAC1_ENABLE       0xB0520004
+ #define NUM_ETH_INTERFACES 2
+-#endif // CONFIG_SOC_AU1550
++#endif /* CONFIG_SOC_AU1550 */
+ 
+ #ifdef CONFIG_SOC_AU1200
+ #define AU1200_UART0_INT          0
+@@ -592,14 +862,14 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1200_PSC1_INT           11
+ #define AU1200_AES_INT            12
+ #define AU1200_CAMERA_INT         13
+-#define AU1200_TOY_INT			  14
+-#define AU1200_TOY_MATCH0_INT     15
+-#define AU1200_TOY_MATCH1_INT     16
+-#define AU1200_TOY_MATCH2_INT     17
+-#define AU1200_RTC_INT            18
+-#define AU1200_RTC_MATCH0_INT     19
+-#define AU1200_RTC_MATCH1_INT     20
+-#define AU1200_RTC_MATCH2_INT     21
++#define AU1000_TOY_INT			  14
++#define AU1000_TOY_MATCH0_INT     15
++#define AU1000_TOY_MATCH1_INT     16
++#define AU1000_TOY_MATCH2_INT     17
++#define AU1000_RTC_INT            18
++#define AU1000_RTC_MATCH0_INT     19
++#define AU1000_RTC_MATCH1_INT     20
++#define AU1000_RTC_MATCH2_INT     21
+ #define AU1200_NAND_INT           23
+ #define AU1200_GPIO_204           24
+ #define AU1200_GPIO_205           25
+@@ -607,6 +877,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define AU1200_GPIO_207           27
+ #define AU1200_GPIO_208_215       28 // Logical OR of 208:215
+ #define AU1200_USB_INT            29
++#define AU1000_USB_HOST_INT		  AU1200_USB_INT
+ #define AU1200_LCD_INT            30
+ #define AU1200_MAE_BOTH_INT       31
+ #define AU1000_GPIO_0             32
+@@ -645,20 +916,36 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define UART0_ADDR                0xB1100000
+ #define UART1_ADDR                0xB1200000
+ 
+-#define USB_OHCI_BASE             0x14020000 // phys addr for ioremap
+-#define USB_HOST_CONFIG           0xB4027ffc
++#define USB_UOC_BASE              0x14020020
++#define USB_UOC_LEN               0x20
++#define USB_OHCI_BASE             0x14020100
++#define USB_OHCI_LEN              0x100
++#define USB_EHCI_BASE             0x14020200
++#define USB_EHCI_LEN              0x100
++#define USB_UDC_BASE              0x14022000
++#define USB_UDC_LEN               0x2000
++#define USB_MSR_BASE			  0xB4020000
++#define USB_MSR_MCFG              4
++#define USBMSRMCFG_OMEMEN         0
++#define USBMSRMCFG_OBMEN          1
++#define USBMSRMCFG_EMEMEN         2
++#define USBMSRMCFG_EBMEN          3
++#define USBMSRMCFG_DMEMEN         4
++#define USBMSRMCFG_DBMEN          5
++#define USBMSRMCFG_GMEMEN         6
++#define USBMSRMCFG_OHCCLKEN       16
++#define USBMSRMCFG_EHCCLKEN       17
++#define USBMSRMCFG_UDCCLKEN       18
++#define USBMSRMCFG_PHYPLLEN       19
++#define USBMSRMCFG_RDCOMB         30
++#define USBMSRMCFG_PFEN           31
+ 
+-// these are here for prototyping on au1550 (do not exist on au1200)
+-#define AU1200_ETH0_BASE      0xB0500000
+-#define AU1200_ETH1_BASE      0xB0510000
+-#define AU1200_MAC0_ENABLE       0xB0520000
+-#define AU1200_MAC1_ENABLE       0xB0520004
+-#define NUM_ETH_INTERFACES 2
+-#endif // CONFIG_SOC_AU1200
++#endif /* CONFIG_SOC_AU1200 */
+ 
+ #define AU1000_LAST_INTC0_INT     31
++#define AU1000_LAST_INTC1_INT     63
+ #define AU1000_MAX_INTR           63
+-
++#define INTX    		0xFF /* not valid */
+ 
+ /* Programmable Counters 0 and 1 */
+ #define SYS_BASE                   0xB1900000
+@@ -730,6 +1017,8 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+   #define I2S_CONTROL_D         (1<<1)
+   #define I2S_CONTROL_CE        (1<<0)
+ 
++#ifndef CONFIG_SOC_AU1200
++
+ /* USB Host Controller */
+ #define USB_OHCI_LEN              0x00100000
+ 
+@@ -775,6 +1064,8 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+   #define USBDEV_ENABLE (1<<1)
+   #define USBDEV_CE     (1<<0)
+ 
++#endif /* !CONFIG_SOC_AU1200 */
++
+ /* Ethernet Controllers  */
+ 
+ /* 4 byte offsets from AU1000_ETH_BASE */
+@@ -1173,6 +1464,37 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+   #define SYS_PF_PSC1_S1		(1 << 1)
+   #define SYS_PF_MUST_BE_SET		((1 << 5) | (1 << 2))
+ 
++/* Au1200 Only */
++#ifdef CONFIG_SOC_AU1200
++#define SYS_PINFUNC_DMA		(1<<31)
++#define SYS_PINFUNC_S0A		(1<<30)
++#define SYS_PINFUNC_S1A		(1<<29)
++#define SYS_PINFUNC_LP0		(1<<28)
++#define SYS_PINFUNC_LP1		(1<<27)
++#define SYS_PINFUNC_LD16	(1<<26)
++#define SYS_PINFUNC_LD8		(1<<25)
++#define SYS_PINFUNC_LD1		(1<<24)
++#define SYS_PINFUNC_LD0		(1<<23)
++#define SYS_PINFUNC_P1A		(3<<21)
++#define SYS_PINFUNC_P1B		(1<<20)
++#define SYS_PINFUNC_FS3		(1<<19)
++#define SYS_PINFUNC_P0A		(3<<17)
++#define SYS_PINFUNC_CS		(1<<16)
++#define SYS_PINFUNC_CIM		(1<<15)
++#define SYS_PINFUNC_P1C		(1<<14)
++#define SYS_PINFUNC_U1T		(1<<12)
++#define SYS_PINFUNC_U1R		(1<<11)
++#define SYS_PINFUNC_EX1		(1<<10)
++#define SYS_PINFUNC_EX0		(1<<9)
++#define SYS_PINFUNC_U0R		(1<<8)
++#define SYS_PINFUNC_MC		(1<<7)
++#define SYS_PINFUNC_S0B		(1<<6)
++#define SYS_PINFUNC_S0C		(1<<5)
++#define SYS_PINFUNC_P0B		(1<<4)
++#define SYS_PINFUNC_U0T		(1<<3)
++#define SYS_PINFUNC_S1B		(1<<2)
++#endif
++
+ #define SYS_TRIOUTRD              0xB1900100
+ #define SYS_TRIOUTCLR             0xB1900100
+ #define SYS_OUTPUTRD              0xB1900108
+@@ -1239,6 +1561,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+   #define SYS_CS_MI2_MASK           (0x7<<SYS_CS_MI2_BIT)
+   #define SYS_CS_DI2                (1<<16)
+   #define SYS_CS_CI2                (1<<15)
++#ifdef CONFIG_SOC_AU1100
++  #define SYS_CS_ML_BIT             7
++  #define SYS_CS_ML_MASK            (0x7<<SYS_CS_ML_BIT)
++  #define SYS_CS_DL                 (1<<6)
++  #define SYS_CS_CL                 (1<<5)
++#else
+   #define SYS_CS_MUH_BIT            12
+   #define SYS_CS_MUH_MASK           (0x7<<SYS_CS_MUH_BIT)
+   #define SYS_CS_DUH                (1<<11)
+@@ -1247,6 +1575,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+   #define SYS_CS_MUD_MASK           (0x7<<SYS_CS_MUD_BIT)
+   #define SYS_CS_DUD                (1<<6)
+   #define SYS_CS_CUD                (1<<5)
++#endif
+   #define SYS_CS_MIR_BIT            2
+   #define SYS_CS_MIR_MASK           (0x7<<SYS_CS_MIR_BIT)
+   #define SYS_CS_DIR                (1<<1)
+@@ -1300,7 +1629,6 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ #define SD1_XMIT_FIFO	0xB0680000
+ #define SD1_RECV_FIFO	0xB0680004
+ 
+-
+ #if defined (CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
+ /* Au1500 PCI Controller */
+ #define Au1500_CFG_BASE           0xB4005000 // virtual, kseg0 addr
+@@ -1363,36 +1691,77 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
+ 		      _ctl_; })
+ 
+ 
+-#else /* Au1000 and Au1100 */
++#else /* Au1000 and Au1100 and Au1200 */
+ 
+ /* don't allow any legacy ports probing */
+-#define IOPORT_RESOURCE_START 0x10000000;
++#define IOPORT_RESOURCE_START 0x10000000
+ #define IOPORT_RESOURCE_END   0xffffffff
+ #define IOMEM_RESOURCE_START  0x10000000
+ #define IOMEM_RESOURCE_END    0xffffffff
+ 
+-#ifdef CONFIG_MIPS_PB1000
+-#define PCI_IO_START      0x10000000
+-#define PCI_IO_END        0x1000ffff
+-#define PCI_MEM_START     0x18000000
+-#define PCI_MEM_END       0x18ffffff
+-#define PCI_FIRST_DEVFN   0
+-#define PCI_LAST_DEVFN    1
+-#else
+-/* no PCI bus controller */
+ #define PCI_IO_START    0
+ #define PCI_IO_END      0
+ #define PCI_MEM_START   0
+ #define PCI_MEM_END     0
+ #define PCI_FIRST_DEVFN 0
+ #define PCI_LAST_DEVFN  0
+-#endif
+ 
+ #endif
+ 
++#ifndef _LANGUAGE_ASSEMBLY
++typedef volatile struct
++{
++	/* 0x0000 */ u32 toytrim;
++	/* 0x0004 */ u32 toywrite;
++	/* 0x0008 */ u32 toymatch0;
++	/* 0x000C */ u32 toymatch1;
++	/* 0x0010 */ u32 toymatch2;
++	/* 0x0014 */ u32 cntrctrl;
++	/* 0x0018 */ u32 scratch0;
++	/* 0x001C */ u32 scratch1;
++	/* 0x0020 */ u32 freqctrl0;
++	/* 0x0024 */ u32 freqctrl1;
++	/* 0x0028 */ u32 clksrc;
++	/* 0x002C */ u32 pinfunc;
++	/* 0x0030 */ u32 reserved0;
++	/* 0x0034 */ u32 wakemsk;
++	/* 0x0038 */ u32 endian;
++	/* 0x003C */ u32 powerctrl;
++	/* 0x0040 */ u32 toyread;
++	/* 0x0044 */ u32 rtctrim;
++	/* 0x0048 */ u32 rtcwrite;
++	/* 0x004C */ u32 rtcmatch0;
++	/* 0x0050 */ u32 rtcmatch1;
++	/* 0x0054 */ u32 rtcmatch2;
++	/* 0x0058 */ u32 rtcread;
++	/* 0x005C */ u32 wakesrc;
++	/* 0x0060 */ u32 cpupll;
++	/* 0x0064 */ u32 auxpll;
++	/* 0x0068 */ u32 reserved1;
++	/* 0x006C */ u32 reserved2;
++	/* 0x0070 */ u32 reserved3;
++	/* 0x0074 */ u32 reserved4;
++	/* 0x0078 */ u32 slppwr;
++	/* 0x007C */ u32 sleep;
++	/* 0x0080 */ u32 reserved5[32];
++	/* 0x0100 */ u32 trioutrd;
++#define trioutclr trioutrd
++	/* 0x0104 */ u32 reserved6;
++	/* 0x0108 */ u32 outputrd;
++#define outputset outputrd
++	/* 0x010C */ u32 outputclr;
++	/* 0x0110 */ u32 pinstaterd;
++#define pininputen pinstaterd
++
++} AU1X00_SYS;
++
++static AU1X00_SYS* const sys  = (AU1X00_SYS *)SYS_BASE;
++
++#endif
+ /* Processor information base on prid.
+  * Copied from PowerPC.
+  */
++#ifndef _LANGUAGE_ASSEMBLY
+ struct cpu_spec {
+ 	/* CPU is matched via (PRID & prid_mask) == prid_value */
+ 	unsigned int	prid_mask;
+@@ -1406,3 +1775,6 @@ struct cpu_spec {
+ extern struct cpu_spec		cpu_specs[];
+ extern struct cpu_spec		*cur_cpu_spec[];
+ #endif
++
++#endif
++
+diff --git a/include/asm-mips/mach-au1x00/au1xxx.h b/include/asm-mips/mach-au1x00/au1xxx.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-au1x00/au1xxx.h
+@@ -0,0 +1,44 @@
++/*
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the 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  SOFTWARE  IS PROVIDED   ``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 AUTHOR  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.
++ *
++ *  You 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 _AU1XXX_H_
++#define _AU1XXX_H_
++
++#include <linux/config.h>
++
++#include <asm/mach-au1x00/au1000.h>
++
++#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
++#include <asm/mach-db1x00/db1x00.h>
++
++#elif defined(CONFIG_MIPS_PB1550)
++#include <asm/mach-pb1x00/pb1550.h>
++
++#elif defined(CONFIG_MIPS_PB1200)
++#include <asm/mach-pb1x00/pb1200.h>
++
++#elif defined(CONFIG_MIPS_DB1200)
++#include <asm/mach-db1x00/db1200.h>
++
++#endif
++
++#endif /* _AU1XXX_H_ */
+diff --git a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
+--- a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
++++ b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
+@@ -45,7 +45,7 @@
+ #define DDMA_GLOBAL_BASE	0xb4003000
+ #define DDMA_CHANNEL_BASE	0xb4002000
+ 
+-typedef struct dbdma_global {
++typedef volatile struct dbdma_global {
+ 	u32	ddma_config;
+ 	u32	ddma_intstat;
+ 	u32	ddma_throttle;
+@@ -62,7 +62,7 @@ typedef struct dbdma_global {
+ 
+ /* The structure of a DMA Channel.
+ */
+-typedef struct au1xxx_dma_channel {
++typedef volatile struct au1xxx_dma_channel {
+ 	u32	ddma_cfg;	/* See below */
+ 	u32	ddma_desptr;	/* 32-byte aligned pointer to descriptor */
+ 	u32	ddma_statptr;	/* word aligned pointer to status word */
+@@ -98,7 +98,7 @@ typedef struct au1xxx_dma_channel {
+ /* "Standard" DDMA Descriptor.
+  * Must be 32-byte aligned.
+  */
+-typedef struct au1xxx_ddma_desc {
++typedef volatile struct au1xxx_ddma_desc {
+ 	u32	dscr_cmd0;		/* See below */
+ 	u32	dscr_cmd1;		/* See below */
+ 	u32	dscr_source0;		/* source phys address */
+@@ -107,6 +107,12 @@ typedef struct au1xxx_ddma_desc {
+ 	u32	dscr_dest1;		/* See below */
+ 	u32	dscr_stat;		/* completion status */
+ 	u32	dscr_nxtptr;		/* Next descriptor pointer (mostly) */
++	/* First 32bytes are HW specific!!!
++	   Lets have some SW data following.. make sure its 32bytes
++	 */
++	u32	sw_status;
++	u32 	sw_context;
++	u32	sw_reserved[6];
+ } au1x_ddma_desc_t;
+ 
+ #define DSCR_CMD0_V		(1 << 31)	/* Descriptor valid */
+@@ -125,8 +131,11 @@ typedef struct au1xxx_ddma_desc {
+ #define DSCR_CMD0_CV		(0x1 << 2)	/* Clear Valid when done */
+ #define DSCR_CMD0_ST_MASK	(0x3 << 0)	/* Status instruction */
+ 
++#define SW_STATUS_INUSE		(1<<0)
++
+ /* Command 0 device IDs.
+ */
++#ifdef CONFIG_SOC_AU1550
+ #define DSCR_CMD0_UART0_TX	0
+ #define DSCR_CMD0_UART0_RX	1
+ #define DSCR_CMD0_UART3_TX	2
+@@ -155,9 +164,45 @@ typedef struct au1xxx_ddma_desc {
+ #define DSCR_CMD0_MAC0_TX	25
+ #define DSCR_CMD0_MAC1_RX	26
+ #define DSCR_CMD0_MAC1_TX	27
++#endif /* CONFIG_SOC_AU1550 */
++
++#ifdef CONFIG_SOC_AU1200
++#define DSCR_CMD0_UART0_TX	0
++#define DSCR_CMD0_UART0_RX	1
++#define DSCR_CMD0_UART1_TX	2
++#define DSCR_CMD0_UART1_RX	3
++#define DSCR_CMD0_DMA_REQ0	4
++#define DSCR_CMD0_DMA_REQ1	5
++#define DSCR_CMD0_MAE_BE	6
++#define DSCR_CMD0_MAE_FE	7
++#define DSCR_CMD0_SDMS_TX0	8
++#define DSCR_CMD0_SDMS_RX0	9
++#define DSCR_CMD0_SDMS_TX1	10
++#define DSCR_CMD0_SDMS_RX1	11
++#define DSCR_CMD0_AES_TX	13
++#define DSCR_CMD0_AES_RX	12
++#define DSCR_CMD0_PSC0_TX	14
++#define DSCR_CMD0_PSC0_RX	15
++#define DSCR_CMD0_PSC1_TX	16
++#define DSCR_CMD0_PSC1_RX	17
++#define DSCR_CMD0_CIM_RXA	18
++#define DSCR_CMD0_CIM_RXB	19
++#define DSCR_CMD0_CIM_RXC	20
++#define DSCR_CMD0_MAE_BOTH	21
++#define DSCR_CMD0_LCD		22
++#define DSCR_CMD0_NAND_FLASH	23
++#define DSCR_CMD0_PSC0_SYNC	24
++#define DSCR_CMD0_PSC1_SYNC	25
++#define DSCR_CMD0_CIM_SYNC	26
++#endif /* CONFIG_SOC_AU1200 */
++
+ #define DSCR_CMD0_THROTTLE	30
+ #define DSCR_CMD0_ALWAYS	31
+ #define DSCR_NDEV_IDS		32
++/* THis macro is used to find/create custom device types */
++#define DSCR_DEV2CUSTOM_ID(x,d)	(((((x)&0xFFFF)<<8)|0x32000000)|((d)&0xFF))
++#define DSCR_CUSTOM2DEV_ID(x)	((x)&0xFF)
++
+ 
+ #define DSCR_CMD0_SID(x)	(((x) & 0x1f) << 25)
+ #define DSCR_CMD0_DID(x)	(((x) & 0x1f) << 20)
+@@ -246,6 +291,43 @@ typedef struct au1xxx_ddma_desc {
+ */
+ #define NUM_DBDMA_CHANS	16
+ 
++/*
++ * Ddma API definitions
++ * FIXME: may not fit to this header file
++ */
++typedef struct dbdma_device_table {
++	u32		dev_id;
++	u32		dev_flags;
++	u32		dev_tsize;
++	u32		dev_devwidth;
++	u32		dev_physaddr;		/* If FIFO */
++	u32		dev_intlevel;
++	u32		dev_intpolarity;
++} dbdev_tab_t;
++
++
++typedef struct dbdma_chan_config {
++	spinlock_t      lock;
++
++	u32			chan_flags;
++	u32			chan_index;
++	dbdev_tab_t		*chan_src;
++	dbdev_tab_t		*chan_dest;
++	au1x_dma_chan_t		*chan_ptr;
++	au1x_ddma_desc_t	*chan_desc_base;
++	au1x_ddma_desc_t	*get_ptr, *put_ptr, *cur_ptr;
++	void			*chan_callparam;
++	void (*chan_callback)(int, void *, struct pt_regs *);
++} chan_tab_t;
++
++#define DEV_FLAGS_INUSE		(1 << 0)
++#define DEV_FLAGS_ANYUSE	(1 << 1)
++#define DEV_FLAGS_OUT		(1 << 2)
++#define DEV_FLAGS_IN		(1 << 3)
++#define DEV_FLAGS_BURSTABLE (1 << 4)
++#define DEV_FLAGS_SYNC		(1 << 5)
++/* end Ddma API definitions */
++
+ /* External functions for drivers to use.
+ */
+ /* Use this to allocate a dbdma channel.  The device ids are one of the
+@@ -258,18 +340,6 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u
+ 
+ #define DBDMA_MEM_CHAN	DSCR_CMD0_ALWAYS
+ 
+-/* ACK!  These should be in a board specific description file.
+-*/
+-#ifdef CONFIG_MIPS_PB1550
+-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+-#endif
+-#ifdef CONFIG_MIPS_DB1550
+-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+-#endif
+-
+-
+ /* Set the device width of a in/out fifo.
+ */
+ u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
+@@ -280,8 +350,8 @@ u32 au1xxx_dbdma_ring_alloc(u32 chanid, 
+ 
+ /* Put buffers on source/destination descriptors.
+ */
+-u32 au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes);
+-u32 au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes);
++u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags);
++u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags);
+ 
+ /* Get a buffer from the destination descriptor.
+ */
+@@ -295,5 +365,29 @@ u32 au1xxx_get_dma_residue(u32 chanid);
+ void au1xxx_dbdma_chan_free(u32 chanid);
+ void au1xxx_dbdma_dump(u32 chanid);
+ 
++u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr );
++
++u32 au1xxx_ddma_add_device( dbdev_tab_t *dev );
++void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
++
++/*
++ 	Some compatibilty macros --
++		Needed to make changes to API without breaking existing drivers
++*/
++#define	au1xxx_dbdma_put_source(chanid,buf,nbytes)_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
++#define	au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
++#define	put_source_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags)
++
++
++#define au1xxx_dbdma_put_dest(chanid,buf,nbytes) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
++#define	au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
++#define	put_dest_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags)
++
++/*
++ *	Flags for the put_source/put_dest functions.
++ */
++#define DDMA_FLAGS_IE	(1<<0)
++#define DDMA_FLAGS_NOIE (1<<1)
++
+ #endif /* _LANGUAGE_ASSEMBLY */
+ #endif /* _AU1000_DBDMA_H_ */
+diff --git a/include/asm-mips/mach-au1x00/au1xxx_gpio.h b/include/asm-mips/mach-au1x00/au1xxx_gpio.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-au1x00/au1xxx_gpio.h
+@@ -0,0 +1,20 @@
++#ifndef __AU1XXX_GPIO_H
++#define __AU1XXX_GPIO_H
++
++void au1xxx_gpio1_set_inputs(void);
++void au1xxx_gpio_tristate(int signal);
++void au1xxx_gpio_write(int signal, int value);
++int  au1xxx_gpio_read(int signal);
++
++typedef volatile struct
++{
++	u32 dir;
++	u32 reserved;
++	u32 output;
++	u32 pinstate;
++	u32 inten;
++	u32 enable;
++
++} AU1X00_GPIO2;
++
++#endif //__AU1XXX_GPIO_H
+diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
+@@ -0,0 +1,301 @@
++/*
++ * include/asm-mips/mach-au1x00/au1xxx_ide.h  version 01.30.00   Aug. 02 2005
++ *
++ * BRIEF MODULE DESCRIPTION
++ * AMD Alchemy Au1xxx IDE interface routines over the Static Bus
++ *
++ * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
++ *
++ * This program is free software; you can redistribute it and/or modify it under
++ * the terms of the 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 SOFTWARE IS PROVIDED ``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 AUTHOR
++ * 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.
++ *
++ * You 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.
++ *
++ * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
++ *       Interface and Linux Device Driver" Application Note.
++ */
++#include <linux/config.h>
++
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++        #define DMA_WAIT_TIMEOUT        100
++        #define NUM_DESCRIPTORS         PRD_ENTRIES
++#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
++        #define NUM_DESCRIPTORS         2
++#endif
++
++#ifndef AU1XXX_ATA_RQSIZE
++        #define AU1XXX_ATA_RQSIZE       128
++#endif
++
++/* Disable Burstable-Support for DBDMA */
++#ifndef CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
++        #define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON  0
++#endif
++
++#ifdef CONFIG_PM
++/*
++* This will enable the device to be powered up when write() or read()
++* is called. If this is not defined, the driver will return -EBUSY.
++*/
++#define WAKE_ON_ACCESS 1
++
++typedef struct
++{
++        spinlock_t         lock;       /* Used to block on state transitions */
++        au1xxx_power_dev_t *dev;       /* Power Managers device structure */
++        unsigned	   stopped;    /* USed to signaling device is stopped */
++} pm_state;
++#endif
++
++
++typedef struct
++{
++        u32                     tx_dev_id, rx_dev_id, target_dev_id;
++        u32                     tx_chan, rx_chan;
++        void                    *tx_desc_head, *rx_desc_head;
++        ide_hwif_t              *hwif;
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++        ide_drive_t             *drive;
++        u8                      white_list, black_list;
++        struct dbdma_cmd        *dma_table_cpu;
++        dma_addr_t              dma_table_dma;
++        struct scatterlist      *sg_table;
++        int                     sg_nents;
++        int                     sg_dma_direction;
++#endif
++        struct device           *dev;
++	int			irq;
++	u32			regbase;
++#ifdef CONFIG_PM
++        pm_state                pm;
++#endif
++} _auide_hwif;
++
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++struct drive_list_entry {
++        const char * id_model;
++        const char * id_firmware;
++};
++
++/* HD white list */
++static const struct drive_list_entry dma_white_list [] = {
++/*
++ * Hitachi
++ */
++        { "HITACHI_DK14FA-20"    ,       "ALL"           },
++        { "HTS726060M9AT00"      ,       "ALL"           },
++/*
++ * Maxtor
++ */
++        { "Maxtor 6E040L0"      ,       "ALL"           },
++        { "Maxtor 6Y080P0"      ,       "ALL"           },
++        { "Maxtor 6Y160P0"      ,       "ALL"           },
++/*
++ * Seagate
++ */
++        { "ST3120026A"          ,       "ALL"           },
++        { "ST320014A"           ,       "ALL"           },
++        { "ST94011A"            ,       "ALL"           },
++        { "ST340016A"           ,       "ALL"           },
++/*
++ * Western Digital
++ */
++        { "WDC WD400UE-00HCT0"  ,       "ALL"           },
++        { "WDC WD400JB-00JJC0"  ,       "ALL"           },
++        { NULL                  ,       NULL            }
++};
++
++/* HD black list */
++static const struct drive_list_entry dma_black_list [] = {
++/*
++ * Western Digital
++ */
++        { "WDC WD100EB-00CGH0"  ,       "ALL"           },
++        { "WDC WD200BB-00AUA1"  ,       "ALL"           },
++        { "WDC AC24300L"        ,       "ALL"           },
++        { NULL                  ,       NULL            }
++};
++#endif
++
++/* function prototyping */
++u8 auide_inb(unsigned long port);
++u16 auide_inw(unsigned long port);
++u32 auide_inl(unsigned long port);
++void auide_insw(unsigned long port, void *addr, u32 count);
++void auide_insl(unsigned long port, void *addr, u32 count);
++void auide_outb(u8 addr, unsigned long port);
++void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port);
++void auide_outw(u16 addr, unsigned long port);
++void auide_outl(u32 addr, unsigned long port);
++void auide_outsw(unsigned long port, void *addr, u32 count);
++void auide_outsl(unsigned long port, void *addr, u32 count);
++static void auide_tune_drive(ide_drive_t *drive, byte pio);
++static int auide_tune_chipset (ide_drive_t *drive, u8 speed);
++static int auide_ddma_init( _auide_hwif *auide );
++static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif);
++int __init auide_probe(void);
++
++#ifdef CONFIG_PM
++        int au1200ide_pm_callback( au1xxx_power_dev_t *dev,
++                                   au1xxx_request_t request, void *data);
++        static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev );
++        static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev );
++        static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev );
++        static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev );
++        static int au1xxxide_pm_access( au1xxx_power_dev_t *dev );
++        static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev );
++        static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev );
++#endif
++
++
++/*
++ * Multi-Word DMA + DbDMA functions
++ */
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++
++        static int in_drive_list(struct hd_driveid *id,
++                                 const struct drive_list_entry *drive_table);
++        static int auide_build_sglist(ide_drive_t *drive,  struct request *rq);
++        static int auide_build_dmatable(ide_drive_t *drive);
++        static int auide_dma_end(ide_drive_t *drive);
++        static void auide_dma_start(ide_drive_t *drive );
++        ide_startstop_t auide_dma_intr (ide_drive_t *drive);
++        static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command);
++        static int auide_dma_setup(ide_drive_t *drive);
++        static int auide_dma_check(ide_drive_t *drive);
++        static int auide_dma_test_irq(ide_drive_t *drive);
++        static int auide_dma_host_off(ide_drive_t *drive);
++        static int auide_dma_host_on(ide_drive_t *drive);
++        static int auide_dma_lostirq(ide_drive_t *drive);
++        static int auide_dma_on(ide_drive_t *drive);
++        static void auide_ddma_tx_callback(int irq, void *param,
++                                           struct pt_regs *regs);
++        static void auide_ddma_rx_callback(int irq, void *param,
++                                           struct pt_regs *regs);
++        static int auide_dma_off_quietly(ide_drive_t *drive);
++        static int auide_dma_timeout(ide_drive_t *drive);
++
++#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
++
++/*******************************************************************************
++* PIO Mode timing calculation :                                                *
++*                                                                              *
++* Static Bus Spec   ATA Spec                                                   *
++*      Tcsoe      =   t1                                                       *
++*      Toecs      =   t9                                                       *
++*      Twcs       =   t9                                                       *
++*      Tcsh       =   t2i | t2                                                 *
++*      Tcsoff     =   t2i | t2                                                 *
++*      Twp        =   t2                                                       *
++*      Tcsw       =   t1                                                       *
++*      Tpm        =   0                                                        *
++*      Ta         =   t1+t2                                                    *
++*******************************************************************************/
++
++#define TCSOE_MASK            (0x07<<29)
++#define TOECS_MASK            (0x07<<26)
++#define TWCS_MASK             (0x07<<28)
++#define TCSH_MASK             (0x0F<<24)
++#define TCSOFF_MASK           (0x07<<20)
++#define TWP_MASK              (0x3F<<14)
++#define TCSW_MASK             (0x0F<<10)
++#define TPM_MASK              (0x0F<<6)
++#define TA_MASK               (0x3F<<0)
++#define TS_MASK               (1<<8)
++
++/* Timing parameters PIO mode 0 */
++#define SBC_IDE_PIO0_TCSOE    (0x04<<29)
++#define SBC_IDE_PIO0_TOECS    (0x01<<26)
++#define SBC_IDE_PIO0_TWCS     (0x02<<28)
++#define SBC_IDE_PIO0_TCSH     (0x08<<24)
++#define SBC_IDE_PIO0_TCSOFF   (0x07<<20)
++#define SBC_IDE_PIO0_TWP      (0x10<<14)
++#define SBC_IDE_PIO0_TCSW     (0x04<<10)
++#define SBC_IDE_PIO0_TPM      (0x0<<6)
++#define SBC_IDE_PIO0_TA       (0x15<<0)
++/* Timing parameters PIO mode 1 */
++#define SBC_IDE_PIO1_TCSOE    (0x03<<29)
++#define SBC_IDE_PIO1_TOECS    (0x01<<26)
++#define SBC_IDE_PIO1_TWCS     (0x01<<28)
++#define SBC_IDE_PIO1_TCSH     (0x06<<24)
++#define SBC_IDE_PIO1_TCSOFF   (0x06<<20)
++#define SBC_IDE_PIO1_TWP      (0x08<<14)
++#define SBC_IDE_PIO1_TCSW     (0x03<<10)
++#define SBC_IDE_PIO1_TPM      (0x00<<6)
++#define SBC_IDE_PIO1_TA       (0x0B<<0)
++/* Timing parameters PIO mode 2 */
++#define SBC_IDE_PIO2_TCSOE    (0x05<<29)
++#define SBC_IDE_PIO2_TOECS    (0x01<<26)
++#define SBC_IDE_PIO2_TWCS     (0x01<<28)
++#define SBC_IDE_PIO2_TCSH     (0x07<<24)
++#define SBC_IDE_PIO2_TCSOFF   (0x07<<20)
++#define SBC_IDE_PIO2_TWP      (0x1F<<14)
++#define SBC_IDE_PIO2_TCSW     (0x05<<10)
++#define SBC_IDE_PIO2_TPM      (0x00<<6)
++#define SBC_IDE_PIO2_TA       (0x22<<0)
++/* Timing parameters PIO mode 3 */
++#define SBC_IDE_PIO3_TCSOE    (0x05<<29)
++#define SBC_IDE_PIO3_TOECS    (0x01<<26)
++#define SBC_IDE_PIO3_TWCS     (0x01<<28)
++#define SBC_IDE_PIO3_TCSH     (0x0D<<24)
++#define SBC_IDE_PIO3_TCSOFF   (0x0D<<20)
++#define SBC_IDE_PIO3_TWP      (0x15<<14)
++#define SBC_IDE_PIO3_TCSW     (0x05<<10)
++#define SBC_IDE_PIO3_TPM      (0x00<<6)
++#define SBC_IDE_PIO3_TA       (0x1A<<0)
++/* Timing parameters PIO mode 4 */
++#define SBC_IDE_PIO4_TCSOE    (0x04<<29)
++#define SBC_IDE_PIO4_TOECS    (0x01<<26)
++#define SBC_IDE_PIO4_TWCS     (0x01<<28)
++#define SBC_IDE_PIO4_TCSH     (0x04<<24)
++#define SBC_IDE_PIO4_TCSOFF   (0x04<<20)
++#define SBC_IDE_PIO4_TWP      (0x0D<<14)
++#define SBC_IDE_PIO4_TCSW     (0x03<<10)
++#define SBC_IDE_PIO4_TPM      (0x00<<6)
++#define SBC_IDE_PIO4_TA       (0x12<<0)
++/* Timing parameters MDMA mode 0 */
++#define SBC_IDE_MDMA0_TCSOE   (0x03<<29)
++#define SBC_IDE_MDMA0_TOECS   (0x01<<26)
++#define SBC_IDE_MDMA0_TWCS    (0x01<<28)
++#define SBC_IDE_MDMA0_TCSH    (0x07<<24)
++#define SBC_IDE_MDMA0_TCSOFF  (0x07<<20)
++#define SBC_IDE_MDMA0_TWP     (0x0C<<14)
++#define SBC_IDE_MDMA0_TCSW    (0x03<<10)
++#define SBC_IDE_MDMA0_TPM     (0x00<<6)
++#define SBC_IDE_MDMA0_TA      (0x0F<<0)
++/* Timing parameters MDMA mode 1 */
++#define SBC_IDE_MDMA1_TCSOE   (0x05<<29)
++#define SBC_IDE_MDMA1_TOECS   (0x01<<26)
++#define SBC_IDE_MDMA1_TWCS    (0x01<<28)
++#define SBC_IDE_MDMA1_TCSH    (0x05<<24)
++#define SBC_IDE_MDMA1_TCSOFF  (0x05<<20)
++#define SBC_IDE_MDMA1_TWP     (0x0F<<14)
++#define SBC_IDE_MDMA1_TCSW    (0x05<<10)
++#define SBC_IDE_MDMA1_TPM     (0x00<<6)
++#define SBC_IDE_MDMA1_TA      (0x15<<0)
++/* Timing parameters MDMA mode 2 */
++#define SBC_IDE_MDMA2_TCSOE   (0x04<<29)
++#define SBC_IDE_MDMA2_TOECS   (0x01<<26)
++#define SBC_IDE_MDMA2_TWCS    (0x01<<28)
++#define SBC_IDE_MDMA2_TCSH    (0x04<<24)
++#define SBC_IDE_MDMA2_TCSOFF  (0x04<<20)
++#define SBC_IDE_MDMA2_TWP     (0x0D<<14)
++#define SBC_IDE_MDMA2_TCSW    (0x04<<10)
++#define SBC_IDE_MDMA2_TPM     (0x00<<6)
++#define SBC_IDE_MDMA2_TA      (0x12<<0)
++
+diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h
+--- a/include/asm-mips/mach-au1x00/au1xxx_psc.h
++++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h
+@@ -33,6 +33,8 @@
+ #ifndef _AU1000_PSC_H_
+ #define _AU1000_PSC_H_
+ 
++#include <linux/config.h>
++
+ /* The PSC base addresses.  */
+ #ifdef CONFIG_SOC_AU1550
+ #define PSC0_BASE_ADDR		0xb1a00000
+diff --git a/include/asm-mips/mach-au1x00/ioremap.h b/include/asm-mips/mach-au1x00/ioremap.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-au1x00/ioremap.h
+@@ -0,0 +1,32 @@
++/*
++ *	include/asm-mips/mach-au1x00/ioremap.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.
++ */
++#ifndef __ASM_MACH_AU1X00_IOREMAP_H
++#define __ASM_MACH_AU1X00_IOREMAP_H
++
++#include <linux/config.h>
++#include <linux/types.h>
++
++#ifdef CONFIG_64BIT_PHYS_ADDR
++extern phys_t __fixup_bigphys_addr(phys_t, phys_t);
++#else
++static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
++{
++	return phys_addr;
++}
++#endif
++
++/*
++ * Allow physical addresses to be fixed up to help 36-bit peripherals.
++ */
++static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
++{
++	return __fixup_bigphys_addr(phys_addr, size);
++}
++
++#endif /* __ASM_MACH_AU1X00_IOREMAP_H */
+diff --git a/include/asm-mips/mach-db1x00/db1200.h b/include/asm-mips/mach-db1x00/db1200.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-db1x00/db1200.h
+@@ -0,0 +1,224 @@
++/*
++ * AMD Alchemy DB1200 Referrence Board
++ * Board Registers defines.
++ *
++ * ########################################################################
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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_DB1200_H
++#define __ASM_DB1200_H
++
++#include <linux/types.h>
++
++// This is defined in au1000.h with bogus value
++#undef AU1X00_EXTERNAL_INT
++
++#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
++#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
++#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
++#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
++
++/* SPI and SMB are muxed on the Pb1200 board.
++   Refer to board documentation.
++ */
++#define SPI_PSC_BASE        PSC0_BASE_ADDR
++#define SMBUS_PSC_BASE      PSC0_BASE_ADDR
++/* AC97 and I2S are muxed on the Pb1200 board.
++   Refer to board documentation.
++ */
++#define AC97_PSC_BASE       PSC1_BASE_ADDR
++#define I2S_PSC_BASE		PSC1_BASE_ADDR
++
++#define BCSR_KSEG1_ADDR 0xB9800000
++
++typedef volatile struct
++{
++	/*00*/	u16 whoami;
++		u16 reserved0;
++	/*04*/	u16 status;
++		u16 reserved1;
++	/*08*/	u16 switches;
++		u16 reserved2;
++	/*0C*/	u16 resets;
++		u16 reserved3;
++
++	/*10*/	u16 pcmcia;
++		u16 reserved4;
++	/*14*/	u16 board;
++		u16 reserved5;
++	/*18*/	u16 disk_leds;
++		u16 reserved6;
++	/*1C*/	u16 system;
++		u16 reserved7;
++
++	/*20*/	u16 intclr;
++		u16 reserved8;
++	/*24*/	u16 intset;
++		u16 reserved9;
++	/*28*/	u16 intclr_mask;
++		u16 reserved10;
++	/*2C*/	u16 intset_mask;
++		u16 reserved11;
++
++	/*30*/	u16 sig_status;
++		u16 reserved12;
++	/*34*/	u16 int_status;
++		u16 reserved13;
++	/*38*/	u16 reserved14;
++		u16 reserved15;
++	/*3C*/	u16 reserved16;
++		u16 reserved17;
++
++} BCSR;
++
++static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++
++/*
++ * Register bit definitions for the BCSRs
++ */
++#define BCSR_WHOAMI_DCID	0x000F
++#define BCSR_WHOAMI_CPLD	0x00F0
++#define BCSR_WHOAMI_BOARD	0x0F00
++
++#define BCSR_STATUS_PCMCIA0VS	0x0003
++#define BCSR_STATUS_PCMCIA1VS	0x000C
++#define BCSR_STATUS_SWAPBOOT	0x0040
++#define BCSR_STATUS_FLASHBUSY	0x0100
++#define BCSR_STATUS_IDECBLID	0x0200
++#define BCSR_STATUS_SD0WP		0x0400
++#define BCSR_STATUS_U0RXD		0x1000
++#define BCSR_STATUS_U1RXD		0x2000
++
++#define BCSR_SWITCHES_OCTAL	0x00FF
++#define BCSR_SWITCHES_DIP_1	0x0080
++#define BCSR_SWITCHES_DIP_2	0x0040
++#define BCSR_SWITCHES_DIP_3	0x0020
++#define BCSR_SWITCHES_DIP_4	0x0010
++#define BCSR_SWITCHES_DIP_5	0x0008
++#define BCSR_SWITCHES_DIP_6	0x0004
++#define BCSR_SWITCHES_DIP_7	0x0002
++#define BCSR_SWITCHES_DIP_8	0x0001
++#define BCSR_SWITCHES_ROTARY	0x0F00
++
++#define BCSR_RESETS_ETH		0x0001
++#define BCSR_RESETS_CAMERA	0x0002
++#define BCSR_RESETS_DC		0x0004
++#define BCSR_RESETS_IDE		0x0008
++#define BCSR_RESETS_TV		0x0010
++/* not resets but in the same register */
++#define BCSR_RESETS_PWMR1mUX 0x0800
++#define BCSR_RESETS_PCS0MUX	0x1000
++#define BCSR_RESETS_PCS1MUX	0x2000
++#define BCSR_RESETS_SPISEL	0x4000
++
++#define BCSR_PCMCIA_PC0VPP	0x0003
++#define BCSR_PCMCIA_PC0VCC	0x000C
++#define BCSR_PCMCIA_PC0DRVEN	0x0010
++#define BCSR_PCMCIA_PC0RST	0x0080
++#define BCSR_PCMCIA_PC1VPP	0x0300
++#define BCSR_PCMCIA_PC1VCC	0x0C00
++#define BCSR_PCMCIA_PC1DRVEN	0x1000
++#define BCSR_PCMCIA_PC1RST	0x8000
++
++#define BCSR_BOARD_LCDVEE	0x0001
++#define BCSR_BOARD_LCDVDD	0x0002
++#define BCSR_BOARD_LCDBL	0x0004
++#define BCSR_BOARD_CAMSNAP	0x0010
++#define BCSR_BOARD_CAMPWR	0x0020
++#define BCSR_BOARD_SD0PWR	0x0040
++
++#define BCSR_LEDS_DECIMALS	0x0003
++#define BCSR_LEDS_LED0		0x0100
++#define BCSR_LEDS_LED1		0x0200
++#define BCSR_LEDS_LED2		0x0400
++#define BCSR_LEDS_LED3		0x0800
++
++#define BCSR_SYSTEM_POWEROFF	0x4000
++#define BCSR_SYSTEM_RESET	0x8000
++
++/* Bit positions for the different interrupt sources */
++#define BCSR_INT_IDE		0x0001
++#define BCSR_INT_ETH		0x0002
++#define BCSR_INT_PC0		0x0004
++#define BCSR_INT_PC0STSCHG	0x0008
++#define BCSR_INT_PC1		0x0010
++#define BCSR_INT_PC1STSCHG	0x0020
++#define BCSR_INT_DC			0x0040
++#define BCSR_INT_FLASHBUSY	0x0080
++#define BCSR_INT_PC0INSERT	0x0100
++#define BCSR_INT_PC0EJECT	0x0200
++#define BCSR_INT_PC1INSERT	0x0400
++#define BCSR_INT_PC1EJECT	0x0800
++#define BCSR_INT_SD0INSERT	0x1000
++#define BCSR_INT_SD0EJECT	0x2000
++
++#define AU1XXX_SMC91111_PHYS_ADDR	(0x19000300)
++#define AU1XXX_SMC91111_IRQ			DB1200_ETH_INT
++
++#define AU1XXX_ATA_PHYS_ADDR		(0x18800000)
++#define AU1XXX_ATA_PHYS_LEN			(0x100)
++#define AU1XXX_ATA_REG_OFFSET	(5)
++#define AU1XXX_ATA_INT			DB1200_IDE_INT
++#define AU1XXX_ATA_DDMA_REQ		DSCR_CMD0_DMA_REQ1;
++#define AU1XXX_ATA_RQSIZE		128
++
++#define NAND_PHYS_ADDR   0x20000000
++
++/*
++ *	External Interrupts for Pb1200 as of 8/6/2004.
++ *   Bit positions in the CPLD registers can be calculated by taking
++ *   the interrupt define and subtracting the DB1200_INT_BEGIN value.
++ *    *example: IDE bis pos is  = 64 - 64
++                ETH bit pos is  = 65 - 64
++ */
++#define DB1200_INT_BEGIN		(AU1000_LAST_INTC1_INT + 1)
++#define DB1200_IDE_INT			(DB1200_INT_BEGIN + 0)
++#define DB1200_ETH_INT			(DB1200_INT_BEGIN + 1)
++#define DB1200_PC0_INT			(DB1200_INT_BEGIN + 2)
++#define DB1200_PC0_STSCHG_INT	(DB1200_INT_BEGIN + 3)
++#define DB1200_PC1_INT			(DB1200_INT_BEGIN + 4)
++#define DB1200_PC1_STSCHG_INT	(DB1200_INT_BEGIN + 5)
++#define DB1200_DC_INT			(DB1200_INT_BEGIN + 6)
++#define DB1200_FLASHBUSY_INT	(DB1200_INT_BEGIN + 7)
++#define DB1200_PC0_INSERT_INT	(DB1200_INT_BEGIN + 8)
++#define DB1200_PC0_EJECT_INT	(DB1200_INT_BEGIN + 9)
++#define DB1200_PC1_INSERT_INT	(DB1200_INT_BEGIN + 10)
++#define DB1200_PC1_EJECT_INT	(DB1200_INT_BEGIN + 11)
++#define DB1200_SD0_INSERT_INT	(DB1200_INT_BEGIN + 12)
++#define DB1200_SD0_EJECT_INT	(DB1200_INT_BEGIN + 13)
++
++#define DB1200_INT_END			(DB1200_INT_BEGIN + 15)
++
++/* For drivers/pcmcia/au1000_db1x00.c */
++
++/* PCMCIA Db1x00 specific defines */
++
++#define PCMCIA_MAX_SOCK 1
++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
++
++/* VPP/VCC */
++#define SET_VCC_VPP(VCC, VPP, SLOT)\
++	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
++
++#define BOARD_PC0_INT DB1200_PC0_INT
++#define BOARD_PC1_INT DB1200_PC1_INT
++#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
++
++#endif /* __ASM_DB1200_H */
++
+diff --git a/include/asm-mips/mach-dec/mc146818rtc.h b/include/asm-mips/mach-dec/mc146818rtc.h
+--- a/include/asm-mips/mach-dec/mc146818rtc.h
++++ b/include/asm-mips/mach-dec/mc146818rtc.h
+@@ -3,7 +3,7 @@
+  *
+  * Copyright (C) 1998, 2001 by Ralf Baechle
+  * Copyright (C) 1998 by Harald Koerfgen
+- * Copyright (C) 2002  Maciej W. Rozycki
++ * Copyright (C) 2002, 2005  Maciej W. Rozycki
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -14,23 +14,18 @@
+ #define __ASM_MIPS_DEC_RTC_DEC_H
+ 
+ #include <linux/types.h>
+-
+ #include <asm/addrspace.h>
++#include <asm/dec/system.h>
+ 
+ extern volatile u8 *dec_rtc_base;
+-extern unsigned long dec_kn_slot_size;
+ 
+-#define RTC_PORT(x)	CPHYSADDR(dec_rtc_base)
++#define RTC_PORT(x)	CPHYSADDR((long)dec_rtc_base)
+ #define RTC_IO_EXTENT	dec_kn_slot_size
+ #define RTC_IOMAPPED	0
+ #undef RTC_IRQ
+ 
+ #define RTC_DEC_YEAR	0x3f	/* Where we store the real year on DECs.  */
+ 
+-#include <linux/mc146818rtc.h>
+-#include <linux/module.h>
+-#include <linux/types.h>
+-
+ static inline unsigned char CMOS_READ(unsigned long addr)
+ {
+ 	return dec_rtc_base[addr * 4];
+diff --git a/include/asm-mips/mach-generic/cpu-feature-overrides.h b/include/asm-mips/mach-generic/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-generic/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-generic/cpu-feature-overrides.h
+@@ -8,6 +8,6 @@
+ #ifndef __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H
+ #define __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H
+ 
+-/* Intensionally empty file ...  */
++/* Intentionally empty file ...  */
+ 
+ #endif /* __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H */
+diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h
+--- a/include/asm-mips/mach-generic/ide.h
++++ b/include/asm-mips/mach-generic/ide.h
+@@ -18,6 +18,7 @@
+ #include <linux/config.h>
+ #include <linux/pci.h>
+ #include <linux/stddef.h>
++#include <asm/processor.h>
+ 
+ #ifndef MAX_HWIFS
+ # ifdef CONFIG_BLK_DEV_IDEPCI
+@@ -104,15 +105,71 @@ static __inline__ unsigned long ide_defa
+ 
+ /* MIPS port and memory-mapped I/O string operations.  */
+ 
+-#define __ide_insw	insw
+-#define __ide_insl	insl
+-#define __ide_outsw	outsw
+-#define __ide_outsl	outsl
+-
+-#define __ide_mm_insw	readsw
+-#define __ide_mm_insl	readsl
+-#define __ide_mm_outsw	writesw
+-#define __ide_mm_outsl	writesl
++static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size)
++{
++	if (cpu_has_dc_aliases) {
++		unsigned long end = addr + size;
++		for (; addr < end; addr += PAGE_SIZE)
++			flush_dcache_page(virt_to_page(addr));
++	}
++}
++
++static inline void __ide_insw(unsigned long port, void *addr,
++	unsigned int count)
++{
++	insw(port, addr, count);
++	__ide_flush_dcache_range((unsigned long)addr, count * 2);
++}
++
++static inline void __ide_insl(unsigned long port, void *addr, unsigned int count)
++{
++	insl(port, addr, count);
++	__ide_flush_dcache_range((unsigned long)addr, count * 4);
++}
++
++static inline void __ide_outsw(unsigned long port, const void *addr,
++	unsigned long count)
++{
++	outsw(port, addr, count);
++	__ide_flush_dcache_range((unsigned long)addr, count * 2);
++}
++
++static inline void __ide_outsl(unsigned long port, const void *addr,
++	unsigned long count)
++{
++	outsl(port, addr, count);
++	__ide_flush_dcache_range((unsigned long)addr, count * 4);
++}
++
++static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count)
++{
++	readsw(port, addr, count);
++	__ide_flush_dcache_range((unsigned long)addr, count * 2);
++}
++
++static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count)
++{
++	readsl(port, addr, count);
++	__ide_flush_dcache_range((unsigned long)addr, count * 4);
++}
++
++static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count)
++{
++	writesw(port, addr, count);
++	__ide_flush_dcache_range((unsigned long)addr, count * 2);
++}
++
++static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count)
++{
++	writesl(port, addr, count);
++	__ide_flush_dcache_range((unsigned long)addr, count * 4);
++}
++
++/* ide_insw calls insw, not __ide_insw.  Why? */
++#undef insw
++#undef insl
++#define insw(port, addr, count) __ide_insw(port, addr, count)
++#define insl(port, addr, count) __ide_insl(port, addr, count)
+ 
+ #endif /* __KERNEL__ */
+ 
+diff --git a/include/asm-mips/mach-generic/ioremap.h b/include/asm-mips/mach-generic/ioremap.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-generic/ioremap.h
+@@ -0,0 +1,23 @@
++/*
++ *	include/asm-mips/mach-generic/ioremap.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.
++ */
++#ifndef __ASM_MACH_GENERIC_IOREMAP_H
++#define __ASM_MACH_GENERIC_IOREMAP_H
++
++#include <linux/types.h>
++
++/*
++ * Allow physical addresses to be fixed up to help peripherals located
++ * outside the low 32-bit range -- generic pass-through version.
++ */
++static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
++{
++	return phys_addr;
++}
++
++#endif /* __ASM_MACH_GENERIC_IOREMAP_H */
+diff --git a/include/asm-mips/mach-generic/kernel-entry-init.h b/include/asm-mips/mach-generic/kernel-entry-init.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-generic/kernel-entry-init.h
+@@ -0,0 +1,25 @@
++/*
++ * 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 Embedded Alley Solutions, Inc
++ * Copyright (C) 2005 Ralf Baechle (ralf at linux-mips.org)
++ */
++#ifndef __ASM_MACH_GENERIC_KERNEL_ENTRY_H
++#define __ASM_MACH_GENERIC_KERNEL_ENTRY_H
++
++/* Intentionally empty macro, used in head.S. Override in
++ * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
++ */
++.macro	kernel_entry_setup
++.endm
++
++/*
++ * Do SMP slave processor setup necessary before we can savely execute C code.
++ */
++	.macro	smp_slave_setup
++	.endm
++
++
++#endif /* __ASM_MACH_GENERIC_KERNEL_ENTRY_H */
+diff --git a/include/asm-mips/mach-generic/kmalloc.h b/include/asm-mips/mach-generic/kmalloc.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-generic/kmalloc.h
+@@ -0,0 +1,13 @@
++#ifndef __ASM_MACH_GENERIC_KMALLOC_H
++#define __ASM_MACH_GENERIC_KMALLOC_H
++
++#include <linux/config.h>
++
++#ifndef CONFIG_DMA_COHERENT
++/*
++ * Total overkill for most systems but need as a safe default.
++ */
++#define ARCH_KMALLOC_MINALIGN	128
++#endif
++
++#endif /* __ASM_MACH_GENERIC_KMALLOC_H */
+diff --git a/include/asm-mips/mach-generic/spaces.h b/include/asm-mips/mach-generic/spaces.h
+--- a/include/asm-mips/mach-generic/spaces.h
++++ b/include/asm-mips/mach-generic/spaces.h
+@@ -55,13 +55,13 @@
+ #endif
+ 
+ #ifdef CONFIG_DMA_NONCOHERENT
+-#define CAC_BASE		0x9800000000000000
++#define CAC_BASE		0x9800000000000000UL
+ #else
+-#define CAC_BASE		0xa800000000000000
++#define CAC_BASE		0xa800000000000000UL
+ #endif
+-#define IO_BASE			0x9000000000000000
+-#define UNCAC_BASE		0x9000000000000000
+-#define MAP_BASE		0xc000000000000000
++#define IO_BASE			0x9000000000000000UL
++#define UNCAC_BASE		0x9000000000000000UL
++#define MAP_BASE		0xc000000000000000UL
+ 
+ #define TO_PHYS(x)		(             ((x) & TO_PHYS_MASK))
+ #define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
+diff --git a/include/asm-mips/mach-ip22/cpu-feature-overrides.h b/include/asm-mips/mach-ip22/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-ip22/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-ip22/cpu-feature-overrides.h
+@@ -11,6 +11,12 @@
+ /*
+  * IP22 with a variety of processors so we can't use defaults for everything.
+  */
++#define cpu_has_tlb		1
++#define cpu_has_4kex		1
++#define cpu_has_4kcache		1
++#define cpu_has_fpu		1
++#define cpu_has_32fpr		1
++#define cpu_has_counter		1
+ #define cpu_has_mips16		0
+ #define cpu_has_divec		0
+ #define cpu_has_cache_cdex_p	1
+@@ -23,6 +29,8 @@
+ #define cpu_has_dc_aliases	(PAGE_SIZE < 0x4000)
+ #define cpu_has_ic_fills_f_dc	0
+ 
++#define cpu_has_dsp		0
++
+ #define cpu_has_nofpuex		0
+ #define cpu_has_64bits		1
+ 
+diff --git a/include/asm-mips/mach-ip22/spaces.h b/include/asm-mips/mach-ip22/spaces.h
+--- a/include/asm-mips/mach-ip22/spaces.h
++++ b/include/asm-mips/mach-ip22/spaces.h
+@@ -44,7 +44,7 @@
+ #define CAC_BASE		0xffffffff80000000
+ #define IO_BASE			0xffffffffa0000000
+ #define UNCAC_BASE		0xffffffffa0000000
+-#define MAP_BASE		0xffffffffc0000000
++#define MAP_BASE		0xc000000000000000
+ 
+ #define TO_PHYS(x)		(             ((x) & TO_PHYS_MASK))
+ #define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
+diff --git a/include/asm-mips/mach-ip27/cpu-feature-overrides.h b/include/asm-mips/mach-ip27/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-ip27/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-ip27/cpu-feature-overrides.h
+@@ -25,6 +25,7 @@
+ #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	1
+ 
+ #define cpu_has_nofpuex		0
+diff --git a/include/asm-mips/mach-ip27/kernel-entry-init.h b/include/asm-mips/mach-ip27/kernel-entry-init.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-ip27/kernel-entry-init.h
+@@ -0,0 +1,52 @@
++/*
++ * 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) 2000 Silicon Graphics, Inc.
++ * Copyright (C) 2005 Ralf Baechle <ralf at linux-mips.org>
++ */
++#ifndef __ASM_MACH_IP27_KERNEL_ENTRY_H
++#define __ASM_MACH_IP27_KERNEL_ENTRY_H
++
++#include <asm/sn/addrs.h>
++#include <asm/sn/sn0/hubni.h>
++#include <asm/sn/klkernvars.h>
++
++/*
++ * Returns the local nasid into res.
++ */
++	.macro GET_NASID_ASM res
++	dli	\res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
++	ld	\res, (\res)
++	and	\res, NSRI_NODEID_MASK
++	dsrl	\res, NSRI_NODEID_SHFT
++	.endm
++
++/*
++ * Intentionally empty macro, used in head.S. Override in
++ * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
++ */
++	.macro	kernel_entry_setup
++	GET_NASID_ASM	t1
++	move		t2, t1			# text and data are here
++	MAPPED_KERNEL_SETUP_TLB
++	.endm
++
++/*
++ * Do SMP slave processor setup necessary before we can savely execute C code.
++ */
++	.macro	smp_slave_setup
++	GET_NASID_ASM	t1
++	dli	t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
++		    KLDIR_OFF_POINTER + CAC_BASE
++	dsll	t1, NASID_SHFT
++	or	t0, t0, t1
++	ld	t0, 0(t0)			# t0 points to kern_vars struct
++	lh	t1, KV_RO_NASID_OFFSET(t0)
++	lh	t2, KV_RW_NASID_OFFSET(t0)
++	MAPPED_KERNEL_SETUP_TLB
++	ARC64_TWIDDLE_PC
++	.endm
++
++#endif /* __ASM_MACH_IP27_KERNEL_ENTRY_H */
+diff --git a/include/asm-mips/mach-ip27/kmalloc.h b/include/asm-mips/mach-ip27/kmalloc.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-ip27/kmalloc.h
+@@ -0,0 +1,8 @@
++#ifndef __ASM_MACH_IP27_KMALLOC_H
++#define __ASM_MACH_IP27_KMALLOC_H
++
++/*
++ * All happy, no need to define ARCH_KMALLOC_MINALIGN
++ */
++
++#endif /* __ASM_MACH_IP27_KMALLOC_H */
+diff --git a/include/asm-mips/mach-ip27/mmzone.h b/include/asm-mips/mach-ip27/mmzone.h
+--- a/include/asm-mips/mach-ip27/mmzone.h
++++ b/include/asm-mips/mach-ip27/mmzone.h
+@@ -10,7 +10,6 @@
+ #define LEVELS_PER_SLICE        128
+ 
+ struct slice_data {
+-	unsigned long irq_alloc_mask[2];
+ 	unsigned long irq_enable_mask[2];
+ 	int level_to_irq[LEVELS_PER_SLICE];
+ };
+@@ -20,6 +19,7 @@ struct hub_data {
+ 	DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW);
+ 	cpumask_t	h_cpus;
+ 	unsigned long slice_map;
++	unsigned long irq_alloc_mask[2];
+ 	struct slice_data slice[2];
+ };
+ 
+diff --git a/include/asm-mips/mach-ip27/spaces.h b/include/asm-mips/mach-ip27/spaces.h
+--- a/include/asm-mips/mach-ip27/spaces.h
++++ b/include/asm-mips/mach-ip27/spaces.h
+@@ -20,6 +20,7 @@
+ #define IO_BASE			0x9200000000000000
+ #define MSPEC_BASE		0x9400000000000000
+ #define UNCAC_BASE		0x9600000000000000
++#define MAP_BASE		0xc000000000000000
+ 
+ #define TO_PHYS(x)		(             ((x) & TO_PHYS_MASK))
+ #define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
+diff --git a/include/asm-mips/mach-ip27/topology.h b/include/asm-mips/mach-ip27/topology.h
+--- a/include/asm-mips/mach-ip27/topology.h
++++ b/include/asm-mips/mach-ip27/topology.h
+@@ -9,6 +9,9 @@
+ #define parent_node(node)	(node)
+ #define node_to_cpumask(node)	(hub_data(node)->h_cpus)
+ #define node_to_first_cpu(node)	(first_cpu(node_to_cpumask(node)))
++struct pci_bus;
++extern int pcibus_to_node(struct pci_bus *);
++
+ #define pcibus_to_cpumask(bus)	(cpu_online_map)
+ 
+ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
+diff --git a/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-ip32/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
+@@ -37,5 +37,6 @@
+ #define cpu_has_ejtag		0
+ #define cpu_has_vtag_icache	0
+ #define cpu_has_ic_fills_f_dc	0
++#define cpu_has_dsp		0
+ 
+ #endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */
+diff --git a/include/asm-mips/mach-ip32/kmalloc.h b/include/asm-mips/mach-ip32/kmalloc.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-ip32/kmalloc.h
+@@ -0,0 +1,12 @@
++#ifndef __ASM_MACH_IP32_KMALLOC_H
++#define __ASM_MACH_IP32_KMALLOC_H
++
++#include <linux/config.h>
++
++#if defined(CONFIG_CPU_R5000) || defined (CONFIG_CPU_RM7000)
++#define ARCH_KMALLOC_MINALIGN	32
++#else
++#define ARCH_KMALLOC_MINALIGN	128
++#endif
++
++#endif /* __ASM_MACH_IP32_KMALLOC_H */
+diff --git a/include/asm-mips/mach-ip32/spaces.h b/include/asm-mips/mach-ip32/spaces.h
+--- a/include/asm-mips/mach-ip32/spaces.h
++++ b/include/asm-mips/mach-ip32/spaces.h
+@@ -19,10 +19,10 @@
+ #define HIGHMEM_START		(1UL << 59UL)
+ #endif
+ 
+-#define CAC_BASE		0x9800000000000000
+-#define IO_BASE			0x9000000000000000
+-#define UNCAC_BASE		0x9000000000000000
+-#define MAP_BASE		0xc000000000000000
++#define CAC_BASE		0x9800000000000000UL
++#define IO_BASE			0x9000000000000000UL
++#define UNCAC_BASE		0x9000000000000000UL
++#define MAP_BASE		0xc000000000000000UL
+ 
+ #define TO_PHYS(x)		(             ((x) & TO_PHYS_MASK))
+ #define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
+diff --git a/include/asm-mips/mach-ja/cpu-feature-overrides.h b/include/asm-mips/mach-ja/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-ja/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-ja/cpu-feature-overrides.h
+@@ -25,6 +25,7 @@
+ #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
+@@ -36,10 +37,4 @@
+ #define cpu_icache_line_size()	32
+ #define cpu_scache_line_size()	32
+ 
+-/*
+- * On the RM9000 we need to ensure that I-cache lines being fetches only
+- * contain valid instructions are funny things will happen.
+- */
+-#define PLAT_TRAMPOLINE_STUFF_LINE	32UL
+-
+ #endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
+diff --git a/include/asm-mips/mach-mips/cpu-feature-overrides.h b/include/asm-mips/mach-mips/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-mips/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-mips/cpu-feature-overrides.h
+@@ -17,7 +17,7 @@
+ #ifdef CONFIG_CPU_MIPS32
+ #define cpu_has_tlb		1
+ #define cpu_has_4kex		1
+-#define cpu_has_4ktlb		1
++#define cpu_has_4kcache		1
+ /* #define cpu_has_fpu		? */
+ /* #define cpu_has_32fpr	? */
+ #define cpu_has_counter		1
+@@ -37,12 +37,13 @@
+ /* #define cpu_has_64bits	? */
+ /* #define cpu_has_64bit_zero_reg ? */
+ /* #define cpu_has_subset_pcaches ? */
++#define cpu_icache_snoops_remote_store 1
+ #endif
+ 
+ #ifdef CONFIG_CPU_MIPS64
+ #define cpu_has_tlb		1
+ #define cpu_has_4kex		1
+-#define cpu_has_4ktlb		1
++#define cpu_has_4kcache		1
+ /* #define cpu_has_fpu		? */
+ /* #define cpu_has_32fpr	? */
+ #define cpu_has_counter		1
+@@ -62,6 +63,7 @@
+ /* #define cpu_has_64bits	? */
+ /* #define cpu_has_64bit_zero_reg ? */
+ /* #define cpu_has_subset_pcaches ? */
++#define cpu_icache_snoops_remote_store 1
+ #endif
+ 
+ #endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
+diff --git a/include/asm-mips/mach-mips/irq.h b/include/asm-mips/mach-mips/irq.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-mips/irq.h
+@@ -0,0 +1,14 @@
++#ifndef __ASM_MACH_MIPS_IRQ_H
++#define __ASM_MACH_MIPS_IRQ_H
++
++#include <linux/config.h>
++
++#define NR_IRQS	256
++
++#ifdef CONFIG_SMP
++
++#define ARCH_HAS_IRQ_PER_CPU
++
++#endif
++
++#endif /* __ASM_MACH_MIPS_IRQ_H */
+diff --git a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
+@@ -28,6 +28,7 @@
+ #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
+@@ -39,10 +40,4 @@
+ #define cpu_icache_line_size()	32
+ #define cpu_scache_line_size()	32
+ 
+-/*
+- * On the RM9000 we need to ensure that I-cache lines being fetches only
+- * contain valid instructions are funny things will happen.
+- */
+-#define PLAT_TRAMPOLINE_STUFF_LINE	32UL
+-
+ #endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
+diff --git a/include/asm-mips/mach-pb1x00/pb1200.h b/include/asm-mips/mach-pb1x00/pb1200.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-pb1x00/pb1200.h
+@@ -0,0 +1,252 @@
++/*
++ * AMD Alchemy PB1200 Referrence Board
++ * Board Registers defines.
++ *
++ * ########################################################################
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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_PB1200_H
++#define __ASM_PB1200_H
++
++#include <linux/types.h>
++
++// This is defined in au1000.h with bogus value
++#undef AU1X00_EXTERNAL_INT
++
++#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
++#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
++#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
++#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
++
++/* SPI and SMB are muxed on the Pb1200 board.
++   Refer to board documentation.
++ */
++#define SPI_PSC_BASE        PSC0_BASE_ADDR
++#define SMBUS_PSC_BASE      PSC0_BASE_ADDR
++/* AC97 and I2S are muxed on the Pb1200 board.
++   Refer to board documentation.
++ */
++#define AC97_PSC_BASE       PSC1_BASE_ADDR
++#define I2S_PSC_BASE		PSC1_BASE_ADDR
++
++#define BCSR_KSEG1_ADDR 0xAD800000
++
++typedef volatile struct
++{
++	/*00*/	u16 whoami;
++		u16 reserved0;
++	/*04*/	u16 status;
++		u16 reserved1;
++	/*08*/	u16 switches;
++		u16 reserved2;
++	/*0C*/	u16 resets;
++		u16 reserved3;
++
++	/*10*/	u16 pcmcia;
++		u16 reserved4;
++	/*14*/	u16 board;
++		u16 reserved5;
++	/*18*/	u16 disk_leds;
++		u16 reserved6;
++	/*1C*/	u16 system;
++		u16 reserved7;
++
++	/*20*/	u16 intclr;
++		u16 reserved8;
++	/*24*/	u16 intset;
++		u16 reserved9;
++	/*28*/	u16 intclr_mask;
++		u16 reserved10;
++	/*2C*/	u16 intset_mask;
++		u16 reserved11;
++
++	/*30*/	u16 sig_status;
++		u16 reserved12;
++	/*34*/	u16 int_status;
++		u16 reserved13;
++	/*38*/	u16 reserved14;
++		u16 reserved15;
++	/*3C*/	u16 reserved16;
++		u16 reserved17;
++
++} BCSR;
++
++static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++
++/*
++ * Register bit definitions for the BCSRs
++ */
++#define BCSR_WHOAMI_DCID	0x000F
++#define BCSR_WHOAMI_CPLD	0x00F0
++#define BCSR_WHOAMI_BOARD	0x0F00
++
++#define BCSR_STATUS_PCMCIA0VS	0x0003
++#define BCSR_STATUS_PCMCIA1VS	0x000C
++#define BCSR_STATUS_SWAPBOOT	0x0040
++#define BCSR_STATUS_FLASHBUSY	0x0100
++#define BCSR_STATUS_IDECBLID	0x0200
++#define BCSR_STATUS_SD0WP		0x0400
++#define BCSR_STATUS_SD1WP		0x0800
++#define BCSR_STATUS_U0RXD		0x1000
++#define BCSR_STATUS_U1RXD		0x2000
++
++#define BCSR_SWITCHES_OCTAL	0x00FF
++#define BCSR_SWITCHES_DIP_1	0x0080
++#define BCSR_SWITCHES_DIP_2	0x0040
++#define BCSR_SWITCHES_DIP_3	0x0020
++#define BCSR_SWITCHES_DIP_4	0x0010
++#define BCSR_SWITCHES_DIP_5	0x0008
++#define BCSR_SWITCHES_DIP_6	0x0004
++#define BCSR_SWITCHES_DIP_7	0x0002
++#define BCSR_SWITCHES_DIP_8	0x0001
++#define BCSR_SWITCHES_ROTARY	0x0F00
++
++#define BCSR_RESETS_ETH		0x0001
++#define BCSR_RESETS_CAMERA	0x0002
++#define BCSR_RESETS_DC		0x0004
++#define BCSR_RESETS_IDE		0x0008
++/* not resets but in the same register */
++#define BCSR_RESETS_WSCFSM  0x0800
++#define BCSR_RESETS_PCS0MUX	0x1000
++#define BCSR_RESETS_PCS1MUX	0x2000
++#define BCSR_RESETS_SPISEL	0x4000
++#define BCSR_RESETS_SD1MUX  0x8000
++
++#define BCSR_PCMCIA_PC0VPP	0x0003
++#define BCSR_PCMCIA_PC0VCC	0x000C
++#define BCSR_PCMCIA_PC0DRVEN	0x0010
++#define BCSR_PCMCIA_PC0RST	0x0080
++#define BCSR_PCMCIA_PC1VPP	0x0300
++#define BCSR_PCMCIA_PC1VCC	0x0C00
++#define BCSR_PCMCIA_PC1DRVEN	0x1000
++#define BCSR_PCMCIA_PC1RST	0x8000
++
++#define BCSR_BOARD_LCDVEE	0x0001
++#define BCSR_BOARD_LCDVDD	0x0002
++#define BCSR_BOARD_LCDBL	0x0004
++#define BCSR_BOARD_CAMSNAP	0x0010
++#define BCSR_BOARD_CAMPWR	0x0020
++#define BCSR_BOARD_SD0PWR	0x0040
++#define BCSR_BOARD_SD1PWR	0x0080
++
++#define BCSR_LEDS_DECIMALS	0x00FF
++#define BCSR_LEDS_LED0		0x0100
++#define BCSR_LEDS_LED1		0x0200
++#define BCSR_LEDS_LED2		0x0400
++#define BCSR_LEDS_LED3		0x0800
++
++#define BCSR_SYSTEM_VDDI	0x001F
++#define BCSR_SYSTEM_POWEROFF	0x4000
++#define BCSR_SYSTEM_RESET	0x8000
++
++/* Bit positions for the different interrupt sources */
++#define BCSR_INT_IDE		0x0001
++#define BCSR_INT_ETH		0x0002
++#define BCSR_INT_PC0		0x0004
++#define BCSR_INT_PC0STSCHG	0x0008
++#define BCSR_INT_PC1		0x0010
++#define BCSR_INT_PC1STSCHG	0x0020
++#define BCSR_INT_DC			0x0040
++#define BCSR_INT_FLASHBUSY	0x0080
++#define BCSR_INT_PC0INSERT	0x0100
++#define BCSR_INT_PC0EJECT	0x0200
++#define BCSR_INT_PC1INSERT	0x0400
++#define BCSR_INT_PC1EJECT	0x0800
++#define BCSR_INT_SD0INSERT	0x1000
++#define BCSR_INT_SD0EJECT	0x2000
++#define BCSR_INT_SD1INSERT	0x4000
++#define BCSR_INT_SD1EJECT	0x8000
++
++/* PCMCIA Db1x00 specific defines */
++#define PCMCIA_MAX_SOCK 1
++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
++
++/* VPP/VCC */
++#define SET_VCC_VPP(VCC, VPP, SLOT)\
++	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
++
++#define AU1XXX_SMC91111_PHYS_ADDR	(0x0D000300)
++#define AU1XXX_SMC91111_IRQ			PB1200_ETH_INT
++
++#define AU1XXX_ATA_PHYS_ADDR		(0x0C800000)
++#define AU1XXX_ATA_PHYS_LEN			(0x100)
++#define AU1XXX_ATA_REG_OFFSET	(5)
++#define AU1XXX_ATA_INT			PB1200_IDE_INT
++#define AU1XXX_ATA_DDMA_REQ		DSCR_CMD0_DMA_REQ1;
++#define AU1XXX_ATA_RQSIZE		128
++
++#define NAND_PHYS_ADDR   0x1C000000
++
++/* Timing values as described in databook, * ns value stripped of
++ * lower 2 bits.
++ * These defines are here rather than an SOC1200 generic file because
++ * the parts chosen on another board may be different and may require
++ * different timings.
++ */
++#define NAND_T_H			(18 >> 2)
++#define NAND_T_PUL			(30 >> 2)
++#define NAND_T_SU			(30 >> 2)
++#define NAND_T_WH			(30 >> 2)
++
++/* Bitfield shift amounts */
++#define NAND_T_H_SHIFT		0
++#define NAND_T_PUL_SHIFT	4
++#define NAND_T_SU_SHIFT		8
++#define NAND_T_WH_SHIFT		12
++
++#define NAND_TIMING	((NAND_T_H   & 0xF)	<< NAND_T_H_SHIFT)   | \
++			((NAND_T_PUL & 0xF)	<< NAND_T_PUL_SHIFT) | \
++			((NAND_T_SU  & 0xF)	<< NAND_T_SU_SHIFT)  | \
++			((NAND_T_WH  & 0xF)	<< NAND_T_WH_SHIFT)
++
++
++/*
++ *	External Interrupts for Pb1200 as of 8/6/2004.
++ *   Bit positions in the CPLD registers can be calculated by taking
++ *   the interrupt define and subtracting the PB1200_INT_BEGIN value.
++ *    *example: IDE bis pos is  = 64 - 64
++                ETH bit pos is  = 65 - 64
++ */
++#define PB1200_INT_BEGIN		(AU1000_LAST_INTC1_INT + 1)
++#define PB1200_IDE_INT			(PB1200_INT_BEGIN + 0)
++#define PB1200_ETH_INT			(PB1200_INT_BEGIN + 1)
++#define PB1200_PC0_INT			(PB1200_INT_BEGIN + 2)
++#define PB1200_PC0_STSCHG_INT	(PB1200_INT_BEGIN + 3)
++#define PB1200_PC1_INT			(PB1200_INT_BEGIN + 4)
++#define PB1200_PC1_STSCHG_INT	(PB1200_INT_BEGIN + 5)
++#define PB1200_DC_INT			(PB1200_INT_BEGIN + 6)
++#define PB1200_FLASHBUSY_INT	(PB1200_INT_BEGIN + 7)
++#define PB1200_PC0_INSERT_INT	(PB1200_INT_BEGIN + 8)
++#define PB1200_PC0_EJECT_INT	(PB1200_INT_BEGIN + 9)
++#define PB1200_PC1_INSERT_INT	(PB1200_INT_BEGIN + 10)
++#define PB1200_PC1_EJECT_INT	(PB1200_INT_BEGIN + 11)
++#define PB1200_SD0_INSERT_INT	(PB1200_INT_BEGIN + 12)
++#define PB1200_SD0_EJECT_INT	(PB1200_INT_BEGIN + 13)
++#define PB1200_SD1_INSERT_INT	(PB1200_INT_BEGIN + 14)
++#define PB1200_SD1_EJECT_INT	(PB1200_INT_BEGIN + 15)
++
++#define PB1200_INT_END			(PB1200_INT_BEGIN + 15)
++
++/* For drivers/pcmcia/au1000_db1x00.c */
++#define BOARD_PC0_INT PB1200_PC0_INT
++#define BOARD_PC1_INT PB1200_PC1_INT
++#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
++
++#endif /* __ASM_PB1200_H */
++
+diff --git a/include/asm-mips/mach-pnx8550/cm.h b/include/asm-mips/mach-pnx8550/cm.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-pnx8550/cm.h
+@@ -0,0 +1,43 @@
++/*
++ *
++ * BRIEF MODULE DESCRIPTION
++ *   Clock module specific definitions
++ *
++ * Author: source at mvista.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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 __PNX8550_CM_H
++#define __PNX8550_CM_H
++
++#define PNX8550_CM_BASE	0xBBE47000
++
++#define PNX8550_CM_PLL0_CTL    *(volatile unsigned long *)(PNX8550_CM_BASE + 0x000)
++#define PNX8550_CM_PLL1_CTL    *(volatile unsigned long *)(PNX8550_CM_BASE + 0x004)
++#define PNX8550_CM_PLL2_CTL    *(volatile unsigned long *)(PNX8550_CM_BASE + 0x008)
++#define PNX8550_CM_PLL3_CTL    *(volatile unsigned long *)(PNX8550_CM_BASE + 0x00C)
++
++// Table not complete.....
++
++#define PNX8550_CM_PLL_BLOCKED_MASK     0x80000000
++#define PNX8550_CM_PLL_LOCK_MASK        0x40000000
++#define PNX8550_CM_PLL_CURRENT_ADJ_MASK 0x3c000000
++#define PNX8550_CM_PLL_N_MASK           0x01ff0000
++#define PNX8550_CM_PLL_M_MASK           0x00003f00
++#define PNX8550_CM_PLL_P_MASK           0x0000000c
++#define PNX8550_CM_PLL_PD_MASK          0x00000002
++
++
++#endif
+diff --git a/include/asm-mips/mach-pnx8550/glb.h b/include/asm-mips/mach-pnx8550/glb.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-pnx8550/glb.h
+@@ -0,0 +1,86 @@
++/*
++ *
++ * BRIEF MODULE DESCRIPTION
++ *   PNX8550 global definitions
++ *
++ * Author: source at mvista.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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 __PNX8550_GLB_H
++#define __PNX8550_GLB_H
++
++#define PNX8550_GLB1_BASE	0xBBE63000
++#define PNX8550_GLB2_BASE	0xBBE4d000
++#define PNX8550_RESET_BASE      0xBBE60000
++
++/* PCI Inta Output Enable Registers */
++#define PNX8550_GLB2_ENAB_INTA_O	*(volatile unsigned long *)(PNX8550_GLB2_BASE + 0x050)
++
++/* Bit 1:Enable DAC Powerdown
++     0:DACs are enabled and are working normally
++     1:DACs are powerdown
++*/
++#define PNX8550_GLB_DAC_PD      0x2
++/*   Bit 0:Enable of PCI inta output
++     0 = Disable PCI inta output
++     1 = Enable PCI inta output
++*/
++#define PNX8550_GLB_ENABLE_INTA_O 0x1
++
++/* PCI Direct Mappings */
++#define PNX8550_PCIMEM	        0x12000000
++#define PNX8550_PCIMEM_SIZE	0x08000000
++#define PNX8550_PCIIO	        0x1c000000
++#define PNX8550_PCIIO_SIZE	0x02000000	/* 32M */
++
++#define PNX8550_PORT_BASE	KSEG1
++
++// GPIO def
++#define PNX8550_GPIO_BASE	0x1Be00000
++
++#define PNX8550_GPIO_DIRQ0	 (PNX8550_GPIO_BASE + 0x104500)
++#define PNX8550_GPIO_MC1         (PNX8550_GPIO_BASE + 0x104004)
++#define PNX8550_GPIO_MC_31_BIT   30
++#define PNX8550_GPIO_MC_30_BIT   28
++#define PNX8550_GPIO_MC_29_BIT   26
++#define PNX8550_GPIO_MC_28_BIT   24
++#define PNX8550_GPIO_MC_27_BIT   22
++#define PNX8550_GPIO_MC_26_BIT   20
++#define PNX8550_GPIO_MC_25_BIT   18
++#define PNX8550_GPIO_MC_24_BIT   16
++#define PNX8550_GPIO_MC_23_BIT   14
++#define PNX8550_GPIO_MC_22_BIT   12
++#define PNX8550_GPIO_MC_21_BIT   10
++#define PNX8550_GPIO_MC_20_BIT   8
++#define PNX8550_GPIO_MC_19_BIT   6
++#define PNX8550_GPIO_MC_18_BIT   4
++#define PNX8550_GPIO_MC_17_BIT   2
++#define PNX8550_GPIO_MC_16_BIT   0
++
++#define PNX8550_GPIO_MODE_PRIMOP    0x1
++#define PNX8550_GPIO_MODE_NO_OPENDR 0x2
++#define PNX8550_GPIO_MODE_OPENDR    0x3
++
++// RESET module
++#define PNX8550_RST_CTL             *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x0)
++#define PNX8550_RST_CAUSE           *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x4)
++#define PNX8550_RST_EN_WATCHDOG     *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x8)
++
++#define PNX8550_RST_REL_MIPS_RST_N     0x8
++#define PNX8550_RST_DO_SW_RST          0x4
++#define PNX8550_RST_REL_SYS_RST_OUT    0x2
++#define PNX8550_RST_ASSERT_SYS_RST_OUT 0x1
++#endif
+diff --git a/include/asm-mips/mach-pnx8550/int.h b/include/asm-mips/mach-pnx8550/int.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-pnx8550/int.h
+@@ -0,0 +1,140 @@
++/*
++ *
++ * BRIEF MODULE DESCRIPTION
++ *   Interrupt specific definitions
++ *
++ * Author: source at mvista.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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 __PNX8550_INT_H
++#define __PNX8550_INT_H
++
++#define PNX8550_GIC_BASE	0xBBE3E000
++
++#define PNX8550_GIC_PRIMASK_0	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0x000)
++#define PNX8550_GIC_PRIMASK_1	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0x004)
++#define PNX8550_GIC_VECTOR_0	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0x100)
++#define PNX8550_GIC_VECTOR_1	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0x104)
++#define PNX8550_GIC_PEND_1_31	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0x200)
++#define PNX8550_GIC_PEND_32_63	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0x204)
++#define PNX8550_GIC_PEND_64_70	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0x208)
++#define PNX8550_GIC_FEATURES	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0x300)
++#define PNX8550_GIC_REQ(x)	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0x400 + (x)*4)
++#define PNX8550_GIC_MOD_ID	*(volatile unsigned long *)(PNX8550_GIC_BASE + 0xFFC)
++
++// cp0 is two software + six hw exceptions
++#define PNX8550_INT_CP0_TOTINT	8
++#define PNX8550_INT_CP0_MIN	0
++#define PNX8550_INT_CP0_MAX	(PNX8550_INT_CP0_MIN + PNX8550_INT_CP0_TOTINT - 1)
++
++#define MIPS_CPU_GIC_IRQ        2
++#define MIPS_CPU_TIMER_IRQ      7
++
++// GIC are 71 exceptions connected to cp0's first hardware exception
++#define PNX8550_INT_GIC_TOTINT	71
++#define PNX8550_INT_GIC_MIN	(PNX8550_INT_CP0_MAX+1)
++#define PNX8550_INT_GIC_MAX	(PNX8550_INT_GIC_MIN + PNX8550_INT_GIC_TOTINT - 1)
++
++#define PNX8550_INT_UNDEF              (PNX8550_INT_GIC_MIN+0)
++#define PNX8550_INT_IPC_TARGET0_MIPS   (PNX8550_INT_GIC_MIN+1)
++#define PNX8550_INT_IPC_TARGET1_TM32_1 (PNX8550_INT_GIC_MIN+2)
++#define PNX8550_INT_IPC_TARGET1_TM32_2 (PNX8550_INT_GIC_MIN+3)
++#define PNX8550_INT_RESERVED_4         (PNX8550_INT_GIC_MIN+4)
++#define PNX8550_INT_USB                (PNX8550_INT_GIC_MIN+5)
++#define PNX8550_INT_GPIO_EQ1           (PNX8550_INT_GIC_MIN+6)
++#define PNX8550_INT_GPIO_EQ2           (PNX8550_INT_GIC_MIN+7)
++#define PNX8550_INT_GPIO_EQ3           (PNX8550_INT_GIC_MIN+8)
++#define PNX8550_INT_GPIO_EQ4           (PNX8550_INT_GIC_MIN+9)
++
++#define PNX8550_INT_GPIO_EQ5           (PNX8550_INT_GIC_MIN+10)
++#define PNX8550_INT_GPIO_EQ6           (PNX8550_INT_GIC_MIN+11)
++#define PNX8550_INT_RESERVED_12        (PNX8550_INT_GIC_MIN+12)
++#define PNX8550_INT_QVCP1              (PNX8550_INT_GIC_MIN+13)
++#define PNX8550_INT_QVCP2              (PNX8550_INT_GIC_MIN+14)
++#define PNX8550_INT_I2C1               (PNX8550_INT_GIC_MIN+15)
++#define PNX8550_INT_I2C2               (PNX8550_INT_GIC_MIN+16)
++#define PNX8550_INT_ISO_UART1          (PNX8550_INT_GIC_MIN+17)
++#define PNX8550_INT_ISO_UART2          (PNX8550_INT_GIC_MIN+18)
++#define PNX8550_INT_UART1              (PNX8550_INT_GIC_MIN+19)
++
++#define PNX8550_INT_UART2              (PNX8550_INT_GIC_MIN+20)
++#define PNX8550_INT_QNTR               (PNX8550_INT_GIC_MIN+21)
++#define PNX8550_INT_RESERVED22         (PNX8550_INT_GIC_MIN+22)
++#define PNX8550_INT_T_DSC              (PNX8550_INT_GIC_MIN+23)
++#define PNX8550_INT_M_DSC              (PNX8550_INT_GIC_MIN+24)
++#define PNX8550_INT_RESERVED25         (PNX8550_INT_GIC_MIN+25)
++#define PNX8550_INT_2D_DRAW_ENG        (PNX8550_INT_GIC_MIN+26)
++#define PNX8550_INT_MEM_BASED_SCALAR1  (PNX8550_INT_GIC_MIN+27)
++#define PNX8550_INT_VIDEO_MPEG         (PNX8550_INT_GIC_MIN+28)
++#define PNX8550_INT_VIDEO_INPUT_P1     (PNX8550_INT_GIC_MIN+29)
++
++#define PNX8550_INT_VIDEO_INPUT_P2     (PNX8550_INT_GIC_MIN+30)
++#define PNX8550_INT_SPDI1              (PNX8550_INT_GIC_MIN+31)
++#define PNX8550_INT_SPDO               (PNX8550_INT_GIC_MIN+32)
++#define PNX8550_INT_AUDIO_INPUT1       (PNX8550_INT_GIC_MIN+33)
++#define PNX8550_INT_AUDIO_OUTPUT1      (PNX8550_INT_GIC_MIN+34)
++#define PNX8550_INT_AUDIO_INPUT2       (PNX8550_INT_GIC_MIN+35)
++#define PNX8550_INT_AUDIO_OUTPUT2      (PNX8550_INT_GIC_MIN+36)
++#define PNX8550_INT_MEMBASED_SCALAR2   (PNX8550_INT_GIC_MIN+37)
++#define PNX8550_INT_VPK                (PNX8550_INT_GIC_MIN+38)
++#define PNX8550_INT_MPEG1_MIPS         (PNX8550_INT_GIC_MIN+39)
++
++#define PNX8550_INT_MPEG1_TM           (PNX8550_INT_GIC_MIN+40)
++#define PNX8550_INT_MPEG2_MIPS         (PNX8550_INT_GIC_MIN+41)
++#define PNX8550_INT_MPEG2_TM           (PNX8550_INT_GIC_MIN+42)
++#define PNX8550_INT_TS_DMA             (PNX8550_INT_GIC_MIN+43)
++#define PNX8550_INT_EDMA               (PNX8550_INT_GIC_MIN+44)
++#define PNX8550_INT_TM_DEBUG1          (PNX8550_INT_GIC_MIN+45)
++#define PNX8550_INT_TM_DEBUG2          (PNX8550_INT_GIC_MIN+46)
++#define PNX8550_INT_PCI_INTA           (PNX8550_INT_GIC_MIN+47)
++#define PNX8550_INT_CLOCK_MODULE       (PNX8550_INT_GIC_MIN+48)
++#define PNX8550_INT_PCI_XIO_INTA_PCI   (PNX8550_INT_GIC_MIN+49)
++
++#define PNX8550_INT_PCI_XIO_INTB_DMA   (PNX8550_INT_GIC_MIN+50)
++#define PNX8550_INT_PCI_XIO_INTC_GPPM  (PNX8550_INT_GIC_MIN+51)
++#define PNX8550_INT_PCI_XIO_INTD_GPXIO (PNX8550_INT_GIC_MIN+52)
++#define PNX8550_INT_DVD_CSS            (PNX8550_INT_GIC_MIN+53)
++#define PNX8550_INT_VLD                (PNX8550_INT_GIC_MIN+54)
++#define PNX8550_INT_GPIO_TSU_7_0       (PNX8550_INT_GIC_MIN+55)
++#define PNX8550_INT_GPIO_TSU_15_8      (PNX8550_INT_GIC_MIN+56)
++#define PNX8550_INT_GPIO_CTU_IR        (PNX8550_INT_GIC_MIN+57)
++#define PNX8550_INT_GPIO0              (PNX8550_INT_GIC_MIN+58)
++#define PNX8550_INT_GPIO1              (PNX8550_INT_GIC_MIN+59)
++
++#define PNX8550_INT_GPIO2              (PNX8550_INT_GIC_MIN+60)
++#define PNX8550_INT_GPIO3              (PNX8550_INT_GIC_MIN+61)
++#define PNX8550_INT_GPIO4              (PNX8550_INT_GIC_MIN+62)
++#define PNX8550_INT_GPIO5              (PNX8550_INT_GIC_MIN+63)
++#define PNX8550_INT_GPIO6              (PNX8550_INT_GIC_MIN+64)
++#define PNX8550_INT_GPIO7              (PNX8550_INT_GIC_MIN+65)
++#define PNX8550_INT_PMAN_SECURITY      (PNX8550_INT_GIC_MIN+66)
++#define PNX8550_INT_I2C3               (PNX8550_INT_GIC_MIN+67)
++#define PNX8550_INT_RESERVED_68        (PNX8550_INT_GIC_MIN+68)
++#define PNX8550_INT_SPDI2              (PNX8550_INT_GIC_MIN+69)
++
++#define PNX8550_INT_I2C4               (PNX8550_INT_GIC_MIN+70)
++
++// Timer are 3 exceptions connected to cp0's 7th hardware exception
++#define PNX8550_INT_TIMER_TOTINT       3
++#define PNX8550_INT_TIMER_MIN	       (PNX8550_INT_GIC_MAX+1)
++#define PNX8550_INT_TIMER_MAX          (PNX8550_INT_TIMER_MIN + PNX8550_INT_TIMER_TOTINT - 1)
++
++#define PNX8550_INT_TIMER1             (PNX8550_INT_TIMER_MIN+0)
++#define PNX8550_INT_TIMER2             (PNX8550_INT_TIMER_MIN+1)
++#define PNX8550_INT_TIMER3             (PNX8550_INT_TIMER_MIN+2)
++#define PNX8550_INT_WATCHDOG           PNX8550_INT_TIMER3
++
++#endif
+diff --git a/include/asm-mips/mach-pnx8550/kernel-entry-init.h b/include/asm-mips/mach-pnx8550/kernel-entry-init.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-pnx8550/kernel-entry-init.h
+@@ -0,0 +1,262 @@
++/*
++ * 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 Embedded Alley Solutions, Inc
++ */
++#ifndef __ASM_MACH_KERNEL_ENTRY_INIT_H
++#define __ASM_MACH_KERNEL_ENTRY_INIT_H
++
++#include <asm/cacheops.h>
++#include <asm/addrspace.h>
++
++#define CO_CONFIGPR_VALID  0x3F1F41FF    /* valid bits to write to ConfigPR */
++#define HAZARD_CP0 nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;
++#define CACHE_OPC      0xBC000000  /* MIPS cache instruction opcode */
++#define ICACHE_LINE_SIZE        32      /* Instruction cache line size bytes */
++#define DCACHE_LINE_SIZE        32      /* Data cache line size in bytes */
++
++#define ICACHE_SET_COUNT        256     /* Instruction cache set count */
++#define DCACHE_SET_COUNT        128     /* Data cache set count */
++
++#define ICACHE_SET_SIZE         (ICACHE_SET_COUNT * ICACHE_LINE_SIZE)
++#define DCACHE_SET_SIZE         (DCACHE_SET_COUNT * DCACHE_LINE_SIZE)
++
++	.macro	kernel_entry_setup
++	.set	push
++	.set	noreorder
++	/*
++	 * PNX8550 entry point, when running a non compressed
++	 * kernel. When loading a zImage, the head.S code in
++	 * arch/mips/zboot/pnx8550 will init the caches and,
++	 * decompress the kernel, and branch to kernel_entry.
++		 */
++cache_begin:	li	t0, (1<<28)
++	mtc0	t0, CP0_STATUS /* cp0 usable */
++	HAZARD_CP0
++
++	mtc0 	zero, CP0_CAUSE
++	HAZARD_CP0
++
++
++	/* Set static virtual to phys address translation and TLB disabled */
++	mfc0 	t0, CP0_CONFIG, 7
++	HAZARD_CP0
++
++	and t0,~((1<<19) | (1<<20))     /* TLB/MAP cleared */
++	mtc0	t0, CP0_CONFIG, 7
++	HAZARD_CP0
++
++	/* CPU boots with kseg0 cache algo set to 0x2 -- uncached */
++
++	init_icache
++	nop
++	init_dcache
++	nop
++
++	cachePr4450ICReset
++	nop
++
++	cachePr4450DCReset
++	nop
++
++	/* read ConfigPR into t0 */
++	mfc0	t0, CP0_CONFIG, 7
++	HAZARD_CP0
++
++	/*  enable the TLB */
++	or      t0, (1<<19)
++
++	/* disable the ICACHE: at least 10x slower */
++	/* or      t0, (1<<26) */
++
++	/* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set  */
++	/* or      t0, (1<<27) */
++
++	and	t0, CO_CONFIGPR_VALID
++
++	/* enable TLB. */
++	mtc0	t0, CP0_CONFIG, 7
++	HAZARD_CP0
++cache_end:
++	/* Setup CMEM_0 to MMIO address space, 2MB */
++	lui    t0, 0x1BE0
++	addi   t0, t0, 0x3
++	mtc0   $8, $22, 4
++	nop
++
++	/* Setup CMEM_1, 128MB */
++	lui    t0, 0x1000
++	addi   t0, t0, 0xf
++	mtc0   $8, $22, 5
++	nop
++
++
++	/* Setup CMEM_2, 32MB */
++	lui    t0, 0x1C00
++	addi   t0, t0, 0xb
++	mtc0   $8, $22, 6
++	nop
++
++	/* Setup CMEM_3, 0MB */
++	lui    t0, 0x0
++	addi   t0, t0, 0x0
++	mtc0   $8, $22, 7
++	nop
++
++	/* Enable cache */
++	mfc0	t0, CP0_CONFIG
++	HAZARD_CP0
++	and	t0, t0, 0xFFFFFFF8
++	or	t0, t0, 3
++	mtc0	t0, CP0_CONFIG
++	HAZARD_CP0
++	.set	pop
++	.endm
++
++	.macro	init_icache
++	.set	push
++	.set	noreorder
++
++	/* Get Cache Configuration */
++	mfc0	t3, CP0_CONFIG, 1
++	HAZARD_CP0
++
++	/* get cache Line size */
++
++	srl   t1, t3, 19   /* C0_CONFIGPR_IL_SHIFT */
++	andi  t1, t1, 0x7  /* C0_CONFIGPR_IL_MASK */
++	beq   t1, zero, pr4450_instr_cache_invalidated /* if zero instruction cache is absent */
++	nop
++	addiu t0, t1, 1
++	ori   t1, zero, 1
++	sllv  t1, t1, t0
++
++	/* get max cache Index */
++	srl   t2, t3, 22  /* C0_CONFIGPR_IS_SHIFT */
++	andi  t2, t2, 0x7 /* C0_CONFIGPR_IS_MASK */
++	addiu t0, t2, 6
++	ori   t2, zero, 1
++	sllv  t2, t2, t0
++
++	/* get max cache way */
++	srl   t3, t3, 16  /* C0_CONFIGPR_IA_SHIFT */
++	andi  t3, t3, 0x7 /* C0_CONFIGPR_IA_MASK */
++	addiu t3, t3, 1
++
++	/* total no of cache lines */
++	multu t2, t3             /* max index * max way */
++	mflo  t2
++	addiu t2, t2, -1
++
++	move  t0, zero
++pr4450_next_instruction_cache_set:
++	cache  Index_Invalidate_I, 0(t0)
++	addu  t0, t0, t1         /* add bytes in a line */
++	bne   t2, zero, pr4450_next_instruction_cache_set
++	addiu t2, t2, -1   /* reduce no of lines to invalidate by one */
++pr4450_instr_cache_invalidated:
++	.set	pop
++	.endm
++
++	.macro	init_dcache
++	.set	push
++	.set	noreorder
++	move t1, zero
++
++	/* Store Tag Information */
++	mtc0	zero, CP0_TAGLO, 0
++	HAZARD_CP0
++
++	mtc0	zero, CP0_TAGHI, 0
++	HAZARD_CP0
++
++	/* Cache size is 16384 = 512 lines x 32 bytes per line */
++	or       t2, zero, (128*4)-1  /* 512 lines  */
++	/* Invalidate all lines */
++2:
++	cache Index_Store_Tag_D, 0(t1)
++	addiu    t2, t2, -1
++	bne      t2, zero, 2b
++	addiu    t1, t1, 32        /* 32 bytes in a line */
++	.set pop
++	.endm
++
++	.macro	cachePr4450ICReset
++	.set	push
++	.set	noreorder
++
++	/* Save CP0 status reg on entry; */
++	/* disable interrupts during cache reset */
++	mfc0    t0, CP0_STATUS      /* T0 = interrupt status on entry */
++	HAZARD_CP0
++
++	mtc0    zero, CP0_STATUS   /* disable CPU interrupts */
++	HAZARD_CP0
++
++	or      t1, zero, zero              /* T1 = starting cache index (0) */
++	ori     t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */
++
++	icache_invd_loop:
++	/* 9 == register t1 */
++	.word   (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
++		(0 * ICACHE_SET_SIZE))  /* invalidate inst cache WAY0 */
++	.word   (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
++		(1 * ICACHE_SET_SIZE))  /* invalidate inst cache WAY1 */
++
++	addiu   t1, t1, ICACHE_LINE_SIZE    /* T1 = next cache line index */
++	bne     t2, zero, icache_invd_loop /* T2 = 0 if all sets invalidated */
++	addiu   t2, t2, -1        /* decrement T2 set cnt (delay slot) */
++
++	/* Initialize the latches in the instruction cache tag */
++	/* that drive the way selection tri-state bus drivers, by doing a */
++	/* dummy load while the instruction cache is still disabled. */
++	/* TODO: Is this needed ? */
++	la      t1, KSEG0            /* T1 = cached memory base address */
++	lw      zero, 0x0000(t1)      /* (dummy read of first memory word) */
++
++	mtc0    t0, CP0_STATUS        /* restore interrupt status on entry */
++	HAZARD_CP0
++	.set	pop
++	.endm
++
++	.macro	cachePr4450DCReset
++	.set	push
++	.set	noreorder
++	mfc0    t0, CP0_STATUS           /* T0 = interrupt status on entry */
++	HAZARD_CP0
++	mtc0    zero, CP0_STATUS         /* disable CPU interrupts */
++	HAZARD_CP0
++
++	/* Writeback/invalidate entire data cache sets/ways/lines */
++	or      t1, zero, zero              /* T1 = starting cache index (0) */
++	ori     t2, zero, (DCACHE_SET_COUNT - 1) /* T2 = data cache set cnt - 1 */
++
++	dcache_wbinvd_loop:
++	/* 9 == register t1 */
++	.word   (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
++		(0 * DCACHE_SET_SIZE))  /* writeback/invalidate WAY0 */
++	.word   (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
++		(1 * DCACHE_SET_SIZE))  /* writeback/invalidate WAY1 */
++	.word   (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
++		(2 * DCACHE_SET_SIZE))  /* writeback/invalidate WAY2 */
++	.word   (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
++		(3 * DCACHE_SET_SIZE))  /* writeback/invalidate WAY3 */
++
++	addiu   t1, t1, DCACHE_LINE_SIZE  /* T1 = next data cache line index */
++	bne     t2, zero, dcache_wbinvd_loop /* T2 = 0 when wbinvd entire cache */
++	addiu   t2, t2, -1          /* decrement T2 set cnt (delay slot) */
++
++	/* Initialize the latches in the data cache tag that drive the way
++	selection tri-state bus drivers, by doing a dummy load while the
++	data cache is still in the disabled mode.  TODO: Is this needed ? */
++	la      t1, KSEG0            /* T1 = cached memory base address */
++	lw      zero, 0x0000(t1)      /* (dummy read of first memory word) */
++
++	mtc0    t0, CP0_STATUS       /* restore interrupt status on entry */
++	HAZARD_CP0
++	.set	pop
++	.endm
++
++#endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */
+diff --git a/include/asm-mips/mach-pnx8550/nand.h b/include/asm-mips/mach-pnx8550/nand.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-pnx8550/nand.h
+@@ -0,0 +1,121 @@
++#ifndef __PNX8550_NAND_H
++#define __PNX8550_NAND_H
++
++#define PNX8550_NAND_BASE_ADDR   0x10000000
++#define PNX8550_PCIXIO_BASE	 0xBBE40000
++
++#define PNX8550_DMA_EXT_ADDR     *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x800)
++#define PNX8550_DMA_INT_ADDR     *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x804)
++#define PNX8550_DMA_TRANS_SIZE   *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x808)
++#define PNX8550_DMA_CTRL         *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x80c)
++#define PNX8550_XIO_SEL0         *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x814)
++#define PNX8550_GPXIO_ADDR       *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x820)
++#define PNX8550_GPXIO_WR         *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x824)
++#define PNX8550_GPXIO_RD         *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x828)
++#define PNX8550_GPXIO_CTRL       *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x82C)
++#define PNX8550_XIO_FLASH_CTRL   *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x830)
++#define PNX8550_GPXIO_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb0)
++#define PNX8550_GPXIO_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb4)
++#define PNX8550_GPXIO_INT_CLEAR  *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb8)
++#define PNX8550_DMA_INT_STATUS   *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd0)
++#define PNX8550_DMA_INT_ENABLE   *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd4)
++#define PNX8550_DMA_INT_CLEAR    *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd8)
++
++#define PNX8550_XIO_SEL0_EN_16BIT    0x00800000
++#define PNX8550_XIO_SEL0_USE_ACK     0x00400000
++#define PNX8550_XIO_SEL0_REN_HIGH    0x00100000
++#define PNX8550_XIO_SEL0_REN_LOW     0x00040000
++#define PNX8550_XIO_SEL0_WEN_HIGH    0x00010000
++#define PNX8550_XIO_SEL0_WEN_LOW     0x00004000
++#define PNX8550_XIO_SEL0_WAIT        0x00000200
++#define PNX8550_XIO_SEL0_OFFSET      0x00000020
++#define PNX8550_XIO_SEL0_TYPE_68360  0x00000000
++#define PNX8550_XIO_SEL0_TYPE_NOR    0x00000008
++#define PNX8550_XIO_SEL0_TYPE_NAND   0x00000010
++#define PNX8550_XIO_SEL0_TYPE_IDE    0x00000018
++#define PNX8550_XIO_SEL0_SIZE_8MB    0x00000000
++#define PNX8550_XIO_SEL0_SIZE_16MB   0x00000002
++#define PNX8550_XIO_SEL0_SIZE_32MB   0x00000004
++#define PNX8550_XIO_SEL0_SIZE_64MB   0x00000006
++#define PNX8550_XIO_SEL0_ENAB        0x00000001
++
++#define PNX8550_SEL0_DEFAULT ((PNX8550_XIO_SEL0_EN_16BIT)  | \
++                              (PNX8550_XIO_SEL0_REN_HIGH*0)| \
++	                      (PNX8550_XIO_SEL0_REN_LOW*2) | \
++	                      (PNX8550_XIO_SEL0_WEN_HIGH*0)| \
++                              (PNX8550_XIO_SEL0_WEN_LOW*2) | \
++	                      (PNX8550_XIO_SEL0_WAIT*4)    | \
++			      (PNX8550_XIO_SEL0_OFFSET*0)  | \
++			      (PNX8550_XIO_SEL0_TYPE_NAND) | \
++			      (PNX8550_XIO_SEL0_SIZE_32MB) | \
++			      (PNX8550_XIO_SEL0_ENAB))
++
++#define PNX8550_GPXIO_PENDING        0x00000200
++#define PNX8550_GPXIO_DONE           0x00000100
++#define PNX8550_GPXIO_CLR_DONE       0x00000080
++#define PNX8550_GPXIO_INIT           0x00000040
++#define PNX8550_GPXIO_READ_CMD       0x00000010
++#define PNX8550_GPXIO_BEN            0x0000000F
++
++#define PNX8550_XIO_FLASH_64MB       0x00200000
++#define PNX8550_XIO_FLASH_INC_DATA   0x00100000
++#define PNX8550_XIO_FLASH_CMD_PH     0x000C0000
++#define PNX8550_XIO_FLASH_CMD_PH2    0x00080000
++#define PNX8550_XIO_FLASH_CMD_PH1    0x00040000
++#define PNX8550_XIO_FLASH_CMD_PH0    0x00000000
++#define PNX8550_XIO_FLASH_ADR_PH     0x00030000
++#define PNX8550_XIO_FLASH_ADR_PH3    0x00030000
++#define PNX8550_XIO_FLASH_ADR_PH2    0x00020000
++#define PNX8550_XIO_FLASH_ADR_PH1    0x00010000
++#define PNX8550_XIO_FLASH_ADR_PH0    0x00000000
++#define PNX8550_XIO_FLASH_CMD_B(x)   ((x<<8) & 0x0000FF00)
++#define PNX8550_XIO_FLASH_CMD_A(x)   (x & 0x000000FF)
++
++#define PNX8550_XIO_INT_ACK          0x00004000
++#define PNX8550_XIO_INT_COMPL        0x00002000
++#define PNX8550_XIO_INT_NONSUP       0x00000200
++#define PNX8550_XIO_INT_ABORT        0x00000004
++
++#define PNX8550_DMA_CTRL_SINGLE_DATA 0x00000400
++#define PNX8550_DMA_CTRL_SND2XIO     0x00000200
++#define PNX8550_DMA_CTRL_FIX_ADDR    0x00000100
++#define PNX8550_DMA_CTRL_BURST_8     0x00000000
++#define PNX8550_DMA_CTRL_BURST_16    0x00000020
++#define PNX8550_DMA_CTRL_BURST_32    0x00000040
++#define PNX8550_DMA_CTRL_BURST_64    0x00000060
++#define PNX8550_DMA_CTRL_BURST_128   0x00000080
++#define PNX8550_DMA_CTRL_BURST_256   0x000000A0
++#define PNX8550_DMA_CTRL_BURST_512   0x000000C0
++#define PNX8550_DMA_CTRL_BURST_NORES 0x000000E0
++#define PNX8550_DMA_CTRL_INIT_DMA    0x00000010
++#define PNX8550_DMA_CTRL_CMD_TYPE    0x0000000F
++
++/* see PCI system arch, page 100 for the full list: */
++#define PNX8550_DMA_CTRL_PCI_CMD_READ    0x00000006
++#define PNX8550_DMA_CTRL_PCI_CMD_WRITE   0x00000007
++
++#define PNX8550_DMA_INT_STAT_ACK_DONE	(1<<14)
++#define PNX8550_DMA_INT_STAT_DMA_DONE	(1<<12)
++#define PNX8550_DMA_INT_STAT_DMA_ERR	(1<<9)
++#define PNX8550_DMA_INT_STAT_PERR5	(1<<5)
++#define PNX8550_DMA_INT_STAT_PERR4	(1<<4)
++#define PNX8550_DMA_INT_STAT_M_ABORT	(1<<2)
++#define PNX8550_DMA_INT_STAT_T_ABORT	(1<<1)
++
++#define PNX8550_DMA_INT_EN_ACK_DONE	(1<<14)
++#define PNX8550_DMA_INT_EN_DMA_DONE	(1<<12)
++#define PNX8550_DMA_INT_EN_DMA_ERR	(1<<9)
++#define PNX8550_DMA_INT_EN_PERR5	(1<<5)
++#define PNX8550_DMA_INT_EN_PERR4	(1<<4)
++#define PNX8550_DMA_INT_EN_M_ABORT	(1<<2)
++#define PNX8550_DMA_INT_EN_T_ABORT	(1<<1)
++
++#define PNX8550_DMA_INT_CLR_ACK_DONE	(1<<14)
++#define PNX8550_DMA_INT_CLR_DMA_DONE	(1<<12)
++#define PNX8550_DMA_INT_CLR_DMA_ERR	(1<<9)
++#define PNX8550_DMA_INT_CLR_PERR5	(1<<5)
++#define PNX8550_DMA_INT_CLR_PERR4	(1<<4)
++#define PNX8550_DMA_INT_CLR_M_ABORT	(1<<2)
++#define PNX8550_DMA_INT_CLR_T_ABORT	(1<<1)
++
++#endif
+diff --git a/include/asm-mips/mach-pnx8550/pci.h b/include/asm-mips/mach-pnx8550/pci.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-pnx8550/pci.h
+@@ -0,0 +1,185 @@
++/*
++ *
++ * BRIEF MODULE DESCRIPTION
++ * PCI specific definitions
++ *
++ * Author: source at mvista.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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 __PNX8550_PCI_H
++#define __PNX8550_PCI_H
++
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++
++#define PCI_ACCESS_READ  0
++#define PCI_ACCESS_WRITE 1
++
++#define PCI_CMD_IOR                     0x20
++#define PCI_CMD_IOW                     0x30
++#define PCI_CMD_CONFIG_READ             0xa0
++#define PCI_CMD_CONFIG_WRITE            0xb0
++
++#define PCI_IO_TIMEOUT                  1000
++#define PCI_IO_RETRY			5
++/* Timeout for IO and CFG accesses.
++   This is in 1/1024 th of a jiffie(=10ms)
++   i.e. approx 10us */
++#define PCI_IO_JIFFIES_TIMEOUT          40
++#define PCI_IO_JIFFIES_SHIFT            10
++
++#define PCI_BYTE_ENABLE_MASK		0x0000000f
++#define PCI_CFG_BUS_SHIFT               16
++#define PCI_CFG_FUNC_SHIFT              8
++#define PCI_CFG_REG_SHIFT               2
++
++#define PCI_BASE                  0x1be00000
++#define PCI_SETUP                 0x00040010
++#define PCI_DIS_REQGNT           (1<<30)
++#define PCI_DIS_REQGNTA          (1<<29)
++#define PCI_DIS_REQGNTB          (1<<28)
++#define PCI_D2_SUPPORT           (1<<27)
++#define PCI_D1_SUPPORT           (1<<26)
++#define PCI_EN_TA                (1<<24)
++#define PCI_EN_PCI2MMI           (1<<23)
++#define PCI_EN_XIO               (1<<22)
++#define PCI_BASE18_PREF          (1<<21)
++#define SIZE_16M                 0x3
++#define SIZE_32M                 0x4
++#define SIZE_64M                 0x5
++#define SIZE_128M                0x6
++#define PCI_SETUP_BASE18_SIZE(X) (X<<18)
++#define PCI_SETUP_BASE18_EN      (1<<17)
++#define PCI_SETUP_BASE14_PREF    (1<<16)
++#define PCI_SETUP_BASE14_SIZE(X) (X<<12)
++#define PCI_SETUP_BASE14_EN      (1<<11)
++#define PCI_SETUP_BASE10_PREF    (1<<10)
++#define PCI_SETUP_BASE10_SIZE(X) (X<<7)
++#define PCI_SETUP_CFGMANAGE_EN   (1<<1)
++#define PCI_SETUP_PCIARB_EN      (1<<0)
++
++#define PCI_CTRL                  0x040014
++#define PCI_SWPB_DCS_PCI         (1<<16)
++#define PCI_SWPB_PCI_PCI         (1<<15)
++#define PCI_SWPB_PCI_DCS         (1<<14)
++#define PCI_REG_WR_POST          (1<<13)
++#define PCI_XIO_WR_POST          (1<<12)
++#define PCI_PCI2_WR_POST         (1<<13)
++#define PCI_PCI1_WR_POST         (1<<12)
++#define PCI_SERR_SEEN            (1<<11)
++#define PCI_B10_SPEC_RD          (1<<6)
++#define PCI_B14_SPEC_RD          (1<<5)
++#define PCI_B18_SPEC_RD          (1<<4)
++#define PCI_B10_NOSUBWORD        (1<<3)
++#define PCI_B14_NOSUBWORD        (1<<2)
++#define PCI_B18_NOSUBWORD        (1<<1)
++#define PCI_RETRY_TMREN          (1<<0)
++
++#define PCI_BASE1_LO              0x040018
++#define PCI_BASE1_HI              0x04001C
++#define PCI_BASE2_LO              0x040020
++#define PCI_BASE2_HI              0x040024
++#define PCI_RDLIFETIM             0x040028
++#define PCI_GPPM_ADDR             0x04002C
++#define PCI_GPPM_WDAT             0x040030
++#define PCI_GPPM_RDAT             0x040034
++#define PCI_GPPM_CTRL             0x040038
++#define GPPM_DONE                (1<<10)
++#define INIT_PCI_CYCLE           (1<<9)
++#define GPPM_CMD(X)              (((X)&0xf)<<4)
++#define GPPM_BYTEEN(X)           ((X)&0xf)
++#define PCI_UNLOCKREG             0x04003C
++#define UNLOCK_SSID(X)           (((X)&0xff)<<8)
++#define UNLOCK_SETUP(X)          (((X)&0xff)<<0)
++#define UNLOCK_MAGIC             0xCA
++#define PCI_DEV_VEND_ID           0x040040
++#define DEVICE_ID(X)             (((X)>>16)&0xffff)
++#define VENDOR_ID(X)             (((X)&0xffff))
++#define PCI_CFG_CMDSTAT           0x040044
++#define PCI_CFG_STATUS(X)            (((X)>>16)&0xffff)
++#define PCI_CFG_COMMAND(X)           ((X)&0xffff)
++#define PCI_CLASS_REV             0x040048
++#define PCI_CLASSCODE(X)         (((X)>>8)&0xffffff)
++#define PCI_REVID(X)             ((X)&0xff)
++#define PCI_LAT_TMR     0x04004c
++#define PCI_BASE10      0x040050
++#define PCI_BASE14      0x040054
++#define PCI_BASE18      0x040058
++#define PCI_SUBSYS_ID   0x04006c
++#define PCI_CAP_PTR     0x040074
++#define PCI_CFG_MISC    0x04007c
++#define PCI_PMC         0x040080
++#define PCI_PWR_STATE   0x040084
++#define PCI_IO          0x040088
++#define PCI_SLVTUNING   0x04008C
++#define PCI_DMATUNING   0x040090
++#define PCI_DMAEADDR    0x040800
++#define PCI_DMAIADDR    0x040804
++#define PCI_DMALEN      0x040808
++#define PCI_DMACTRL     0x04080C
++#define PCI_XIOCTRL     0x040810
++#define PCI_SEL0PROF    0x040814
++#define PCI_SEL1PROF    0x040818
++#define PCI_SEL2PROF    0x04081C
++#define PCI_GPXIOADDR   0x040820
++#define PCI_NANDCTRLS   0x400830
++#define PCI_SEL3PROF    0x040834
++#define PCI_SEL4PROF    0x040838
++#define PCI_GPXIO_STAT  0x040FB0
++#define PCI_GPXIO_IMASK 0x040FB4
++#define PCI_GPXIO_ICLR  0x040FB8
++#define PCI_GPXIO_ISET  0x040FBC
++#define PCI_GPPM_STATUS 0x040FC0
++#define GPPM_DONE      (1<<10)
++#define GPPM_ERR       (1<<9)
++#define GPPM_MPAR_ERR  (1<<8)
++#define GPPM_PAR_ERR   (1<<7)
++#define GPPM_R_MABORT  (1<<2)
++#define GPPM_R_TABORT  (1<<1)
++#define PCI_GPPM_IMASK  0x040FC4
++#define PCI_GPPM_ICLR   0x040FC8
++#define PCI_GPPM_ISET   0x040FCC
++#define PCI_DMA_STATUS  0x040FD0
++#define PCI_DMA_IMASK   0x040FD4
++#define PCI_DMA_ICLR    0x040FD8
++#define PCI_DMA_ISET    0x040FDC
++#define PCI_ISTATUS     0x040FE0
++#define PCI_IMASK       0x040FE4
++#define PCI_ICLR        0x040FE8
++#define PCI_ISET        0x040FEC
++#define PCI_MOD_ID      0x040FFC
++
++/*
++ *  PCI configuration cycle AD bus definition
++ */
++/* Type 0 */
++#define PCI_CFG_TYPE0_REG_SHF           0
++#define PCI_CFG_TYPE0_FUNC_SHF          8
++
++/* Type 1 */
++#define PCI_CFG_TYPE1_REG_SHF           0
++#define PCI_CFG_TYPE1_FUNC_SHF          8
++#define PCI_CFG_TYPE1_DEV_SHF           11
++#define PCI_CFG_TYPE1_BUS_SHF           16
++
++/*
++ *  Ethernet device DP83816 definition
++ */
++#define DP83816_IRQ_ETHER               66
++
++#endif
+diff --git a/include/asm-mips/mach-pnx8550/uart.h b/include/asm-mips/mach-pnx8550/uart.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-pnx8550/uart.h
+@@ -0,0 +1,16 @@
++#ifndef __IP3106_UART_H
++#define __IP3106_UART_H
++
++#include <int.h>
++
++/* early macros for kgdb use. fixme: clean this up */
++
++#define UART_BASE		0xbbe4a000	/* PNX8550 */
++
++#define PNX8550_UART_PORT0	(UART_BASE)
++#define PNX8550_UART_PORT1	(UART_BASE + 0x1000)
++
++#define PNX8550_UART_INT(x)		(PNX8550_INT_GIC_MIN+19+x)
++#define IRQ_TO_UART(x)			(x-PNX8550_INT_GIC_MIN-19)
++
++#endif
+diff --git a/include/asm-mips/mach-pnx8550/usb.h b/include/asm-mips/mach-pnx8550/usb.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-pnx8550/usb.h
+@@ -0,0 +1,32 @@
++/*
++ *
++ * BRIEF MODULE DESCRIPTION
++ *  USB specific definitions
++ *
++ * Author: source at mvista.com
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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 __PNX8550_USB_H
++#define __PNX8550_USB_H
++
++/*
++ * USB Host controller
++ */
++
++#define PNX8550_USB_OHCI_OP_BASE	0x1be48000
++#define PNX8550_USB_OHCI_OP_LEN	        0x1000
++
++#endif
+diff --git a/include/asm-mips/mach-rm200/cpu-feature-overrides.h b/include/asm-mips/mach-rm200/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-rm200/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-rm200/cpu-feature-overrides.h
+@@ -14,7 +14,7 @@
+ 
+ #define cpu_has_tlb		1
+ #define cpu_has_4kex		1
+-#define cpu_has_4ktlb		1
++#define cpu_has_4kcache		1
+ #define cpu_has_fpu		1
+ #define cpu_has_32fpr		1
+ #define cpu_has_counter		1
+@@ -31,6 +31,7 @@
+ #define cpu_has_vtag_icache	0
+ #define cpu_has_dc_aliases	(PAGE_SIZE < 0x4000)
+ #define cpu_has_ic_fills_f_dc	0
++#define cpu_has_dsp		0
+ #define cpu_has_nofpuex		0
+ #define cpu_has_64bits		1
+ 
+diff --git a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
+@@ -25,6 +25,7 @@
+ #define cpu_has_vtag_icache	1
+ #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
+diff --git a/include/asm-mips/mach-sim/cpu-feature-overrides.h b/include/asm-mips/mach-sim/cpu-feature-overrides.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mach-sim/cpu-feature-overrides.h
+@@ -0,0 +1,66 @@
++/*
++ * 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, 2004 Chris Dearman
++ */
++#ifndef __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
++#define __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
++
++#include <linux/config.h>
++
++/*
++ * CPU feature overrides for MIPS boards
++ */
++#ifdef CONFIG_CPU_MIPS32
++#define cpu_has_tlb		1
++#define cpu_has_4kex		1
++#define cpu_has_4kcache		1
++#define cpu_has_fpu		0
++/* #define cpu_has_32fpr	? */
++#define cpu_has_counter		1
++/* #define cpu_has_watch	? */
++#define cpu_has_divec		1
++#define cpu_has_vce		0
++/* #define cpu_has_cache_cdex_p	? */
++/* #define cpu_has_cache_cdex_s	? */
++/* #define cpu_has_prefetch	? */
++#define cpu_has_mcheck		1
++/* #define cpu_has_ejtag	? */
++#define cpu_has_llsc		1
++/* #define cpu_has_vtag_icache	? */
++/* #define cpu_has_dc_aliases	? */
++/* #define cpu_has_ic_fills_f_dc ? */
++#define cpu_has_nofpuex		0
++/* #define cpu_has_64bits	? */
++/* #define cpu_has_64bit_zero_reg ? */
++/* #define cpu_has_subset_pcaches ? */
++#endif
++
++#ifdef CONFIG_CPU_MIPS64
++#define cpu_has_tlb		1
++#define cpu_has_4kex		1
++#define cpu_has_4kcache		1
++/* #define cpu_has_fpu		? */
++/* #define cpu_has_32fpr	? */
++#define cpu_has_counter		1
++/* #define cpu_has_watch	? */
++#define cpu_has_divec		1
++#define cpu_has_vce		0
++/* #define cpu_has_cache_cdex_p	? */
++/* #define cpu_has_cache_cdex_s	? */
++/* #define cpu_has_prefetch	? */
++#define cpu_has_mcheck		1
++/* #define cpu_has_ejtag	? */
++#define cpu_has_llsc		1
++/* #define cpu_has_vtag_icache	? */
++/* #define cpu_has_dc_aliases	? */
++/* #define cpu_has_ic_fills_f_dc ? */
++#define cpu_has_nofpuex		0
++/* #define cpu_has_64bits	? */
++/* #define cpu_has_64bit_zero_reg ? */
++/* #define cpu_has_subset_pcaches ? */
++#endif
++
++#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
+diff --git a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
+--- a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
++++ b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
+@@ -25,6 +25,7 @@
+ #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
+@@ -36,10 +37,4 @@
+ #define cpu_icache_line_size()	32
+ #define cpu_scache_line_size()	32
+ 
+-/*
+- * On the RM9000 we need to ensure that I-cache lines being fetches only
+- * contain valid instructions are funny things will happen.
+- */
+-#define PLAT_TRAMPOLINE_STUFF_LINE	32UL
+-
+ #endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */
+diff --git a/include/asm-mips/mips-boards/generic.h b/include/asm-mips/mips-boards/generic.h
+--- a/include/asm-mips/mips-boards/generic.h
++++ b/include/asm-mips/mips-boards/generic.h
+@@ -66,6 +66,7 @@
+ #define MIPS_REVISION_CORID_CORE_EMUL      6
+ #define MIPS_REVISION_CORID_CORE_FPGA2     7
+ #define MIPS_REVISION_CORID_CORE_FPGAR2    8
++#define MIPS_REVISION_CORID_CORE_FPGA3     9
+ 
+ /**** Artificial corid defines ****/
+ /*
+@@ -79,4 +80,10 @@
+ 
+ extern unsigned int mips_revision_corid;
+ 
++#ifdef CONFIG_PCI
++extern void mips_pcibios_init(void);
++#else
++#define mips_pcibios_init() do { } while (0)
++#endif
++
+ #endif  /* __ASM_MIPS_BOARDS_GENERIC_H */
+diff --git a/include/asm-mips/mips-boards/maltaint.h b/include/asm-mips/mips-boards/maltaint.h
+--- a/include/asm-mips/mips-boards/maltaint.h
++++ b/include/asm-mips/mips-boards/maltaint.h
+@@ -25,9 +25,63 @@
+ #ifndef _MIPS_MALTAINT_H
+ #define _MIPS_MALTAINT_H
+ 
+-/* Number of IRQ supported on hw interrupt 0. */
+-#define MALTAINT_END      16
++/*
++ * Interrupts 0..15 are used for Malta ISA compatible interrupts
++ */
++#define MALTA_INT_BASE		0
+ 
++/*
++ * Interrupts 16..23 are used for Malta CPU interrupts (nonEIC mode)
++ */
++#define MIPSCPU_INT_BASE	16
++
++/* CPU interrupt offsets */
++#define MIPSCPU_INT_SW0		0
++#define MIPSCPU_INT_SW1		1
++#define MIPSCPU_INT_MB0		2
++#define MIPSCPU_INT_I8259A	MIPSCPU_INT_MB0
++#define MIPSCPU_INT_MB1		3
++#define MIPSCPU_INT_SMI		MIPSCPU_INT_MB1
++#define MIPSCPU_INT_MB2		4
++#define MIPSCPU_INT_MB3		5
++#define MIPSCPU_INT_COREHI	MIPSCPU_INT_MB3
++#define MIPSCPU_INT_MB4		6
++#define MIPSCPU_INT_CORELO	MIPSCPU_INT_MB4
++#define MIPSCPU_INT_CPUCTR	7
++
++/*
++ * Interrupts 64..127 are used for Soc-it Classic interrupts
++ */
++#define MSC01C_INT_BASE		64
++
++/* SOC-it Classic interrupt offsets */
++#define MSC01C_INT_TMR		0
++#define MSC01C_INT_PCI		1
++
++/*
++ * Interrupts 64..127 are used for Soc-it EIC interrupts
++ */
++#define MSC01E_INT_BASE		64
++
++/* SOC-it EIC interrupt offsets */
++#define MSC01E_INT_SW0		1
++#define MSC01E_INT_SW1		2
++#define MSC01E_INT_MB0		3
++#define MSC01E_INT_I8259A	MSC01E_INT_MB0
++#define MSC01E_INT_MB1		4
++#define MSC01E_INT_SMI		MSC01E_INT_MB1
++#define MSC01E_INT_MB2		5
++#define MSC01E_INT_MB3		6
++#define MSC01E_INT_COREHI	MSC01E_INT_MB3
++#define MSC01E_INT_MB4		7
++#define MSC01E_INT_CORELO	MSC01E_INT_MB4
++#define MSC01E_INT_TMR		8
++#define MSC01E_INT_PCI		9
++#define MSC01E_INT_PERFCTR	10
++#define MSC01E_INT_CPUCTR	11
++
++#ifndef __ASSEMBLY__
+ extern void maltaint_init(void);
++#endif
+ 
+ #endif /* !(_MIPS_MALTAINT_H) */
+diff --git a/include/asm-mips/mips-boards/msc01_pci.h b/include/asm-mips/mips-boards/msc01_pci.h
+--- a/include/asm-mips/mips-boards/msc01_pci.h
++++ b/include/asm-mips/mips-boards/msc01_pci.h
+@@ -1,8 +1,9 @@
+ /*
+  * PCI Register definitions for the MIPS System Controller.
+  *
+- * Carsten Langgaard, carstenl at mips.com
+- * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
++ * Copyright (C) 2002, 2005  MIPS Technologies, Inc.  All rights reserved.
++ *	Authors: Carsten Langgaard <carstenl at mips.com>
++ *		 Maciej W. Rozycki <macro at mips.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
+@@ -29,22 +30,22 @@
+ #define MSC01_PCI_CFGADDR_OFS		0x0610
+ #define MSC01_PCI_CFGDATA_OFS		0x0618
+ #define MSC01_PCI_IACK_OFS		0x0620
+-#define MSC01_PCI_HEAD0_OFS		0x2000  /* DevID, VendorID */
+-#define MSC01_PCI_HEAD1_OFS		0x2008  /* Status, Command */
+-#define MSC01_PCI_HEAD2_OFS		0x2010  /* Class code, RevID */
+-#define MSC01_PCI_HEAD3_OFS		0x2018  /* bist, header, latency */
+-#define MSC01_PCI_HEAD4_OFS		0x2020  /* BAR 0 */
+-#define MSC01_PCI_HEAD5_OFS		0x2028  /* BAR 1 */
+-#define MSC01_PCI_HEAD6_OFS		0x2030  /* BAR 2 */
+-#define MSC01_PCI_HEAD7_OFS		0x2038  /* BAR 3 */
+-#define MSC01_PCI_HEAD8_OFS		0x2040  /* BAR 4 */
+-#define MSC01_PCI_HEAD9_OFS		0x2048  /* BAR 5 */
+-#define MSC01_PCI_HEAD10_OFS		0x2050  /* CardBus CIS Ptr */
+-#define MSC01_PCI_HEAD11_OFS		0x2058  /* SubSystem ID, -VendorID */
+-#define MSC01_PCI_HEAD12_OFS		0x2060  /* ROM BAR */
+-#define MSC01_PCI_HEAD13_OFS		0x2068  /* Capabilities ptr */
+-#define MSC01_PCI_HEAD14_OFS		0x2070  /* reserved */
+-#define MSC01_PCI_HEAD15_OFS		0x2078  /* Maxl, ming, intpin, int */
++#define MSC01_PCI_HEAD0_OFS		0x2000	/* DevID, VendorID */
++#define MSC01_PCI_HEAD1_OFS		0x2008	/* Status, Command */
++#define MSC01_PCI_HEAD2_OFS		0x2010	/* Class code, RevID */
++#define MSC01_PCI_HEAD3_OFS		0x2018	/* bist, header, latency */
++#define MSC01_PCI_HEAD4_OFS		0x2020	/* BAR 0 */
++#define MSC01_PCI_HEAD5_OFS		0x2028	/* BAR 1 */
++#define MSC01_PCI_HEAD6_OFS		0x2030	/* BAR 2 */
++#define MSC01_PCI_HEAD7_OFS		0x2038	/* BAR 3 */
++#define MSC01_PCI_HEAD8_OFS		0x2040	/* BAR 4 */
++#define MSC01_PCI_HEAD9_OFS		0x2048	/* BAR 5 */
++#define MSC01_PCI_HEAD10_OFS		0x2050	/* CardBus CIS Ptr */
++#define MSC01_PCI_HEAD11_OFS		0x2058	/* SubSystem ID, -VendorID */
++#define MSC01_PCI_HEAD12_OFS		0x2060	/* ROM BAR */
++#define MSC01_PCI_HEAD13_OFS		0x2068	/* Capabilities ptr */
++#define MSC01_PCI_HEAD14_OFS		0x2070	/* reserved */
++#define MSC01_PCI_HEAD15_OFS		0x2078	/* Maxl, ming, intpin, int */
+ #define MSC01_PCI_BAR0_OFS		0x2220
+ #define MSC01_PCI_CFG_OFS		0x2380
+ #define MSC01_PCI_SWAP_OFS		0x2388
+@@ -86,73 +87,73 @@
+ #define MSC01_PCI_P2SCMAPL_MAP_SHF	24
+ #define MSC01_PCI_P2SCMAPL_MAP_MSK	0xff000000
+ 
+-#define MSC01_PCI_INTCFG_RST_SHF        10
+-#define MSC01_PCI_INTCFG_RST_MSK        0x00000400
+-#define MSC01_PCI_INTCFG_RST_BIT        0x00000400
+-#define MSC01_PCI_INTCFG_MWE_SHF        9
+-#define MSC01_PCI_INTCFG_MWE_MSK        0x00000200
+-#define MSC01_PCI_INTCFG_MWE_BIT        0x00000200
+-#define MSC01_PCI_INTCFG_DTO_SHF        8
+-#define MSC01_PCI_INTCFG_DTO_MSK        0x00000100
+-#define MSC01_PCI_INTCFG_DTO_BIT        0x00000100
+-#define MSC01_PCI_INTCFG_MA_SHF         7
+-#define MSC01_PCI_INTCFG_MA_MSK         0x00000080
+-#define MSC01_PCI_INTCFG_MA_BIT         0x00000080
+-#define MSC01_PCI_INTCFG_TA_SHF         6
+-#define MSC01_PCI_INTCFG_TA_MSK         0x00000040
+-#define MSC01_PCI_INTCFG_TA_BIT         0x00000040
+-#define MSC01_PCI_INTCFG_RTY_SHF        5
+-#define MSC01_PCI_INTCFG_RTY_MSK        0x00000020
+-#define MSC01_PCI_INTCFG_RTY_BIT        0x00000020
+-#define MSC01_PCI_INTCFG_MWP_SHF        4
+-#define MSC01_PCI_INTCFG_MWP_MSK        0x00000010
+-#define MSC01_PCI_INTCFG_MWP_BIT        0x00000010
+-#define MSC01_PCI_INTCFG_MRP_SHF        3
+-#define MSC01_PCI_INTCFG_MRP_MSK        0x00000008
+-#define MSC01_PCI_INTCFG_MRP_BIT        0x00000008
+-#define MSC01_PCI_INTCFG_SWP_SHF        2
+-#define MSC01_PCI_INTCFG_SWP_MSK        0x00000004
+-#define MSC01_PCI_INTCFG_SWP_BIT        0x00000004
+-#define MSC01_PCI_INTCFG_SRP_SHF        1
+-#define MSC01_PCI_INTCFG_SRP_MSK        0x00000002
+-#define MSC01_PCI_INTCFG_SRP_BIT        0x00000002
+-#define MSC01_PCI_INTCFG_SE_SHF         0
+-#define MSC01_PCI_INTCFG_SE_MSK         0x00000001
+-#define MSC01_PCI_INTCFG_SE_BIT         0x00000001
+-
+-#define MSC01_PCI_INTSTAT_RST_SHF       10
+-#define MSC01_PCI_INTSTAT_RST_MSK       0x00000400
+-#define MSC01_PCI_INTSTAT_RST_BIT       0x00000400
+-#define MSC01_PCI_INTSTAT_MWE_SHF       9
+-#define MSC01_PCI_INTSTAT_MWE_MSK       0x00000200
+-#define MSC01_PCI_INTSTAT_MWE_BIT       0x00000200
+-#define MSC01_PCI_INTSTAT_DTO_SHF       8
+-#define MSC01_PCI_INTSTAT_DTO_MSK       0x00000100
+-#define MSC01_PCI_INTSTAT_DTO_BIT       0x00000100
+-#define MSC01_PCI_INTSTAT_MA_SHF        7
+-#define MSC01_PCI_INTSTAT_MA_MSK        0x00000080
+-#define MSC01_PCI_INTSTAT_MA_BIT        0x00000080
+-#define MSC01_PCI_INTSTAT_TA_SHF        6
+-#define MSC01_PCI_INTSTAT_TA_MSK        0x00000040
+-#define MSC01_PCI_INTSTAT_TA_BIT        0x00000040
+-#define MSC01_PCI_INTSTAT_RTY_SHF       5
+-#define MSC01_PCI_INTSTAT_RTY_MSK       0x00000020
+-#define MSC01_PCI_INTSTAT_RTY_BIT       0x00000020
+-#define MSC01_PCI_INTSTAT_MWP_SHF       4
+-#define MSC01_PCI_INTSTAT_MWP_MSK       0x00000010
+-#define MSC01_PCI_INTSTAT_MWP_BIT       0x00000010
+-#define MSC01_PCI_INTSTAT_MRP_SHF       3
+-#define MSC01_PCI_INTSTAT_MRP_MSK       0x00000008
+-#define MSC01_PCI_INTSTAT_MRP_BIT       0x00000008
+-#define MSC01_PCI_INTSTAT_SWP_SHF       2
+-#define MSC01_PCI_INTSTAT_SWP_MSK       0x00000004
+-#define MSC01_PCI_INTSTAT_SWP_BIT       0x00000004
+-#define MSC01_PCI_INTSTAT_SRP_SHF       1
+-#define MSC01_PCI_INTSTAT_SRP_MSK       0x00000002
+-#define MSC01_PCI_INTSTAT_SRP_BIT       0x00000002
+-#define MSC01_PCI_INTSTAT_SE_SHF        0
+-#define MSC01_PCI_INTSTAT_SE_MSK        0x00000001
+-#define MSC01_PCI_INTSTAT_SE_BIT        0x00000001
++#define MSC01_PCI_INTCFG_RST_SHF	10
++#define MSC01_PCI_INTCFG_RST_MSK	0x00000400
++#define MSC01_PCI_INTCFG_RST_BIT	0x00000400
++#define MSC01_PCI_INTCFG_MWE_SHF	9
++#define MSC01_PCI_INTCFG_MWE_MSK	0x00000200
++#define MSC01_PCI_INTCFG_MWE_BIT	0x00000200
++#define MSC01_PCI_INTCFG_DTO_SHF	8
++#define MSC01_PCI_INTCFG_DTO_MSK	0x00000100
++#define MSC01_PCI_INTCFG_DTO_BIT	0x00000100
++#define MSC01_PCI_INTCFG_MA_SHF		7
++#define MSC01_PCI_INTCFG_MA_MSK		0x00000080
++#define MSC01_PCI_INTCFG_MA_BIT		0x00000080
++#define MSC01_PCI_INTCFG_TA_SHF		6
++#define MSC01_PCI_INTCFG_TA_MSK		0x00000040
++#define MSC01_PCI_INTCFG_TA_BIT		0x00000040
++#define MSC01_PCI_INTCFG_RTY_SHF	5
++#define MSC01_PCI_INTCFG_RTY_MSK	0x00000020
++#define MSC01_PCI_INTCFG_RTY_BIT	0x00000020
++#define MSC01_PCI_INTCFG_MWP_SHF	4
++#define MSC01_PCI_INTCFG_MWP_MSK	0x00000010
++#define MSC01_PCI_INTCFG_MWP_BIT	0x00000010
++#define MSC01_PCI_INTCFG_MRP_SHF	3
++#define MSC01_PCI_INTCFG_MRP_MSK	0x00000008
++#define MSC01_PCI_INTCFG_MRP_BIT	0x00000008
++#define MSC01_PCI_INTCFG_SWP_SHF	2
++#define MSC01_PCI_INTCFG_SWP_MSK	0x00000004
++#define MSC01_PCI_INTCFG_SWP_BIT	0x00000004
++#define MSC01_PCI_INTCFG_SRP_SHF	1
++#define MSC01_PCI_INTCFG_SRP_MSK	0x00000002
++#define MSC01_PCI_INTCFG_SRP_BIT	0x00000002
++#define MSC01_PCI_INTCFG_SE_SHF		0
++#define MSC01_PCI_INTCFG_SE_MSK		0x00000001
++#define MSC01_PCI_INTCFG_SE_BIT		0x00000001
++
++#define MSC01_PCI_INTSTAT_RST_SHF	10
++#define MSC01_PCI_INTSTAT_RST_MSK	0x00000400
++#define MSC01_PCI_INTSTAT_RST_BIT	0x00000400
++#define MSC01_PCI_INTSTAT_MWE_SHF	9
++#define MSC01_PCI_INTSTAT_MWE_MSK	0x00000200
++#define MSC01_PCI_INTSTAT_MWE_BIT	0x00000200
++#define MSC01_PCI_INTSTAT_DTO_SHF	8
++#define MSC01_PCI_INTSTAT_DTO_MSK	0x00000100
++#define MSC01_PCI_INTSTAT_DTO_BIT	0x00000100
++#define MSC01_PCI_INTSTAT_MA_SHF	7
++#define MSC01_PCI_INTSTAT_MA_MSK	0x00000080
++#define MSC01_PCI_INTSTAT_MA_BIT	0x00000080
++#define MSC01_PCI_INTSTAT_TA_SHF	6
++#define MSC01_PCI_INTSTAT_TA_MSK	0x00000040
++#define MSC01_PCI_INTSTAT_TA_BIT	0x00000040
++#define MSC01_PCI_INTSTAT_RTY_SHF	5
++#define MSC01_PCI_INTSTAT_RTY_MSK	0x00000020
++#define MSC01_PCI_INTSTAT_RTY_BIT	0x00000020
++#define MSC01_PCI_INTSTAT_MWP_SHF	4
++#define MSC01_PCI_INTSTAT_MWP_MSK	0x00000010
++#define MSC01_PCI_INTSTAT_MWP_BIT	0x00000010
++#define MSC01_PCI_INTSTAT_MRP_SHF	3
++#define MSC01_PCI_INTSTAT_MRP_MSK	0x00000008
++#define MSC01_PCI_INTSTAT_MRP_BIT	0x00000008
++#define MSC01_PCI_INTSTAT_SWP_SHF	2
++#define MSC01_PCI_INTSTAT_SWP_MSK	0x00000004
++#define MSC01_PCI_INTSTAT_SWP_BIT	0x00000004
++#define MSC01_PCI_INTSTAT_SRP_SHF	1
++#define MSC01_PCI_INTSTAT_SRP_MSK	0x00000002
++#define MSC01_PCI_INTSTAT_SRP_BIT	0x00000002
++#define MSC01_PCI_INTSTAT_SE_SHF	0
++#define MSC01_PCI_INTSTAT_SE_MSK	0x00000001
++#define MSC01_PCI_INTSTAT_SE_BIT	0x00000001
+ 
+ #define MSC01_PCI_CFGADDR_BNUM_SHF	16
+ #define MSC01_PCI_CFGADDR_BNUM_MSK	0x00ff0000
+@@ -167,29 +168,29 @@
+ #define MSC01_PCI_CFGDATA_DATA_MSK	0xffffffff
+ 
+ /* The defines below are ONLY valid for a MEM bar! */
+-#define MSC01_PCI_BAR0_SIZE_SHF	        4
+-#define MSC01_PCI_BAR0_SIZE_MSK	        0xfffffff0
+-#define MSC01_PCI_BAR0_P_SHF	        3
+-#define MSC01_PCI_BAR0_P_MSK	        0x00000008
+-#define MSC01_PCI_BAR0_P_BIT	        MSC01_PCI_BAR0_P_MSK
+-#define MSC01_PCI_BAR0_D_SHF	        1
+-#define MSC01_PCI_BAR0_D_MSK	        0x00000006
+-#define MSC01_PCI_BAR0_T_SHF	        0
+-#define MSC01_PCI_BAR0_T_MSK	        0x00000001
+-#define MSC01_PCI_BAR0_T_BIT	        MSC01_PCI_BAR0_T_MSK
+-
+-
+-#define MSC01_PCI_CFG_RA_SHF	        17
+-#define MSC01_PCI_CFG_RA_MSK	        0x00020000
+-#define MSC01_PCI_CFG_RA_BIT	        MSC01_PCI_CFG_RA_MSK
+-#define MSC01_PCI_CFG_G_SHF	        16
+-#define MSC01_PCI_CFG_G_MSK	        0x00010000
+-#define MSC01_PCI_CFG_G_BIT	        MSC01_PCI_CFG_G_MSK
+-#define MSC01_PCI_CFG_EN_SHF	        15
+-#define MSC01_PCI_CFG_EN_MSK	        0x00008000
+-#define MSC01_PCI_CFG_EN_BIT	        MSC01_PCI_CFG_EN_MSK
+-#define MSC01_PCI_CFG_MAXRTRY_SHF       0
+-#define MSC01_PCI_CFG_MAXRTRY_MSK       0x000000ff
++#define MSC01_PCI_BAR0_SIZE_SHF		4
++#define MSC01_PCI_BAR0_SIZE_MSK		0xfffffff0
++#define MSC01_PCI_BAR0_P_SHF		3
++#define MSC01_PCI_BAR0_P_MSK		0x00000008
++#define MSC01_PCI_BAR0_P_BIT		MSC01_PCI_BAR0_P_MSK
++#define MSC01_PCI_BAR0_D_SHF		1
++#define MSC01_PCI_BAR0_D_MSK		0x00000006
++#define MSC01_PCI_BAR0_T_SHF		0
++#define MSC01_PCI_BAR0_T_MSK		0x00000001
++#define MSC01_PCI_BAR0_T_BIT		MSC01_PCI_BAR0_T_MSK
++
++
++#define MSC01_PCI_CFG_RA_SHF		17
++#define MSC01_PCI_CFG_RA_MSK		0x00020000
++#define MSC01_PCI_CFG_RA_BIT		MSC01_PCI_CFG_RA_MSK
++#define MSC01_PCI_CFG_G_SHF		16
++#define MSC01_PCI_CFG_G_MSK		0x00010000
++#define MSC01_PCI_CFG_G_BIT		MSC01_PCI_CFG_G_MSK
++#define MSC01_PCI_CFG_EN_SHF		15
++#define MSC01_PCI_CFG_EN_MSK		0x00008000
++#define MSC01_PCI_CFG_EN_BIT		MSC01_PCI_CFG_EN_MSK
++#define MSC01_PCI_CFG_MAXRTRY_SHF	0
++#define MSC01_PCI_CFG_MAXRTRY_MSK	0x00000fff
+ 
+ #define MSC01_PCI_SWAP_IO_SHF		18
+ #define MSC01_PCI_SWAP_IO_MSK		0x000c0000
+@@ -206,7 +207,7 @@
+  * FIXME - are these macros specific to Malta and co or to the MSC?  If the
+  * latter, they should be moved elsewhere.
+  */
+-#define MIPS_MSC01_PCI_REG_BASE	0x1bd00000
++#define MIPS_MSC01_PCI_REG_BASE		0x1bd00000
+ 
+ extern unsigned long _pcictrl_msc;
+ 
+@@ -219,19 +220,19 @@ extern unsigned long _pcictrl_msc;
+  * Registers absolute addresses
+  */
+ 
+-#define MSC01_PCI_ID            (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS)
+-#define MSC01_PCI_SC2PMBASL     (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS)
+-#define MSC01_PCI_SC2PMMSKL     (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS)
+-#define MSC01_PCI_SC2PMMAPL     (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS)
+-#define MSC01_PCI_SC2PIOBASL    (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS)
+-#define MSC01_PCI_SC2PIOMSKL    (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS)
+-#define MSC01_PCI_SC2PIOMAPL    (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS)
+-#define MSC01_PCI_P2SCMSKL      (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS)
+-#define MSC01_PCI_P2SCMAPL      (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS)
+-#define MSC01_PCI_INTCFG        (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS)
+-#define MSC01_PCI_INTSTAT       (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS)
+-#define MSC01_PCI_CFGADDR       (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS)
+-#define MSC01_PCI_CFGDATA       (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS)
++#define MSC01_PCI_ID		(MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS)
++#define MSC01_PCI_SC2PMBASL	(MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS)
++#define MSC01_PCI_SC2PMMSKL	(MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS)
++#define MSC01_PCI_SC2PMMAPL	(MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS)
++#define MSC01_PCI_SC2PIOBASL	(MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS)
++#define MSC01_PCI_SC2PIOMSKL	(MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS)
++#define MSC01_PCI_SC2PIOMAPL	(MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS)
++#define MSC01_PCI_P2SCMSKL	(MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS)
++#define MSC01_PCI_P2SCMAPL	(MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS)
++#define MSC01_PCI_INTCFG	(MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS)
++#define MSC01_PCI_INTSTAT	(MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS)
++#define MSC01_PCI_CFGADDR	(MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS)
++#define MSC01_PCI_CFGDATA	(MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS)
+ #define MSC01_PCI_IACK		(MSC01_PCI_REG_BASE + MSC01_PCI_IACK_OFS)
+ #define MSC01_PCI_HEAD0		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD0_OFS)
+ #define MSC01_PCI_HEAD1		(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD1_OFS)
+@@ -248,7 +249,7 @@ extern unsigned long _pcictrl_msc;
+ #define MSC01_PCI_HEAD12	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+ #define MSC01_PCI_HEAD13	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+ #define MSC01_PCI_HEAD14	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+-#define MSC01_PCI_HEAD15        (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
++#define MSC01_PCI_HEAD15	(MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+ #define MSC01_PCI_BAR0		(MSC01_PCI_REG_BASE + MSC01_PCI_BAR0_OFS)
+ #define MSC01_PCI_CFG		(MSC01_PCI_REG_BASE + MSC01_PCI_CFG_OFS)
+ #define MSC01_PCI_SWAP		(MSC01_PCI_REG_BASE + MSC01_PCI_SWAP_OFS)
+diff --git a/include/asm-mips/mips-boards/sim.h b/include/asm-mips/mips-boards/sim.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mips-boards/sim.h
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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_MIPS_BOARDS_SIM_H
++#define _ASM_MIPS_BOARDS_SIM_H
++
++#define STATS_ON        1
++#define STATS_OFF       2
++#define STATS_CLEAR     3
++#define STATS_DUMP      4
++#define TRACE_ON		5
++#define TRACE_OFF       6
++
++
++#define simcfg(code)						\
++({					   \
++	__asm__  __volatile__( \
++        "sltiu $0,$0, %0" \
++		::"i"(code)					\
++		); \
++})
++
++
++
++#endif
+diff --git a/include/asm-mips/mips-boards/simint.h b/include/asm-mips/mips-boards/simint.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mips-boards/simint.h
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ *  This program is free software; you can distribute 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 it will be useful, but WITHOUT
++ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ *  for more details.
++ *
++ *  You 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 _MIPS_SIMINT_H
++#define _MIPS_SIMINT_H
++
++
++#define SIM_INT_BASE		0
++#define MIPSCPU_INT_MB0		2
++#define MIPSCPU_INT_BASE	16
++#define MIPS_CPU_TIMER_IRQ	7
++
++
++#define MIPSCPU_INT_CPUCTR	7
++
++#define MSC01E_INT_BASE		64
++
++#define MIPSCPU_INT_CPUCTR	7
++#define MSC01E_INT_CPUCTR	11
++
++#endif
+diff --git a/include/asm-mips/mipsmtregs.h b/include/asm-mips/mipsmtregs.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/mipsmtregs.h
+@@ -0,0 +1,391 @@
++/*
++ * MT regs definitions, follows on from mipsregs.h
++ * Copyright (C) 2004 - 2005 MIPS Technologies, Inc.  All rights reserved.
++ * Elizabeth Clarke et. al.
++ *
++ */
++#ifndef _ASM_MIPSMTREGS_H
++#define _ASM_MIPSMTREGS_H
++
++#include <asm/mipsregs.h>
++#include <asm/war.h>
++
++#ifndef __ASSEMBLY__
++
++/*
++ * C macros
++ */
++
++#define read_c0_mvpcontrol()		__read_32bit_c0_register($0, 1)
++#define write_c0_mvpcontrol(val)	__write_32bit_c0_register($0, 1, val)
++
++#define read_c0_mvpconf0()		__read_32bit_c0_register($0, 2)
++#define read_c0_mvpconf1()		__read_32bit_c0_register($0, 3)
++
++#define read_c0_vpecontrol()		__read_32bit_c0_register($1, 1)
++#define write_c0_vpecontrol(val)	__write_32bit_c0_register($1, 1, val)
++
++#define read_c0_vpeconf0()		__read_32bit_c0_register($1, 2)
++#define write_c0_vpeconf0(val)		__write_32bit_c0_register($1, 2, val)
++
++#define read_c0_tcstatus()		__read_32bit_c0_register($2, 1)
++#define write_c0_tcstatus(val)		__write_32bit_c0_register($2, 1, val)
++
++#define read_c0_tcbind()		__read_32bit_c0_register($2, 2)
++
++#define read_c0_tccontext()		__read_32bit_c0_register($2, 5)
++#define write_c0_tccontext(val)		__write_32bit_c0_register($2, 5, val)
++
++#else /* Assembly */
++/*
++ * Macros for use in assembly language code
++ */
++
++#define CP0_MVPCONTROL		$0,1
++#define CP0_MVPCONF0		$0,2
++#define CP0_MVPCONF1		$0,3
++#define CP0_VPECONTROL		$1,1
++#define CP0_VPECONF0		$1,2
++#define CP0_VPECONF1		$1,3
++#define CP0_YQMASK		$1,4
++#define CP0_VPESCHEDULE	$1,5
++#define CP0_VPESCHEFBK		$1,6
++#define CP0_TCSTATUS		$2,1
++#define CP0_TCBIND		$2,2
++#define CP0_TCRESTART		$2,3
++#define CP0_TCHALT		$2,4
++#define CP0_TCCONTEXT		$2,5
++#define CP0_TCSCHEDULE		$2,6
++#define CP0_TCSCHEFBK		$2,7
++#define CP0_SRSCONF0		$6,1
++#define CP0_SRSCONF1		$6,2
++#define CP0_SRSCONF2		$6,3
++#define CP0_SRSCONF3		$6,4
++#define CP0_SRSCONF4		$6,5
++
++#endif
++
++/* MVPControl fields */
++#define MVPCONTROL_EVP		(_ULCAST_(1))
++
++#define MVPCONTROL_VPC_SHIFT	1
++#define MVPCONTROL_VPC		(_ULCAST_(1) << MVPCONTROL_VPC_SHIFT)
++
++#define MVPCONTROL_STLB_SHIFT	2
++#define MVPCONTROL_STLB		(_ULCAST_(1) << MVPCONTROL_STLB_SHIFT)
++
++
++/* MVPConf0 fields */
++#define MVPCONF0_PTC_SHIFT	0
++#define MVPCONF0_PTC		( _ULCAST_(0xff))
++#define MVPCONF0_PVPE_SHIFT	10
++#define MVPCONF0_PVPE		( _ULCAST_(0xf) << MVPCONF0_PVPE_SHIFT)
++#define MVPCONF0_TCA_SHIFT	15
++#define MVPCONF0_TCA		( _ULCAST_(1) << MVPCONF0_TCA_SHIFT)
++#define MVPCONF0_PTLBE_SHIFT	16
++#define MVPCONF0_PTLBE		(_ULCAST_(0x3ff) << MVPCONF0_PTLBE_SHIFT)
++#define MVPCONF0_TLBS_SHIFT	29
++#define MVPCONF0_TLBS		(_ULCAST_(1) << MVPCONF0_TLBS_SHIFT)
++#define MVPCONF0_M_SHIFT	31
++#define MVPCONF0_M		(_ULCAST_(0x1) << MVPCONF0_M_SHIFT)
++
++
++/* config3 fields */
++#define CONFIG3_MT_SHIFT	2
++#define CONFIG3_MT		(_ULCAST_(1) << CONFIG3_MT_SHIFT)
++
++
++/* VPEControl fields (per VPE) */
++#define VPECONTROL_TARGTC	(_ULCAST_(0xff))
++
++#define VPECONTROL_TE_SHIFT	15
++#define VPECONTROL_TE		(_ULCAST_(1) << VPECONTROL_TE_SHIFT)
++#define VPECONTROL_EXCPT_SHIFT	16
++#define VPECONTROL_EXCPT	(_ULCAST_(0x7) << VPECONTROL_EXCPT_SHIFT)
++
++/* Thread Exception Codes for EXCPT field */
++#define THREX_TU		0
++#define THREX_TO		1
++#define THREX_IYQ		2
++#define THREX_GSX		3
++#define THREX_YSCH		4
++#define THREX_GSSCH		5
++
++#define VPECONTROL_GSI_SHIFT	20
++#define VPECONTROL_GSI		(_ULCAST_(1) << VPECONTROL_GSI_SHIFT)
++#define VPECONTROL_YSI_SHIFT	21
++#define VPECONTROL_YSI		(_ULCAST_(1) << VPECONTROL_YSI_SHIFT)
++
++/* VPEConf0 fields (per VPE) */
++#define VPECONF0_VPA_SHIFT	0
++#define VPECONF0_VPA		(_ULCAST_(1) << VPECONF0_VPA_SHIFT)
++#define VPECONF0_MVP_SHIFT	1
++#define VPECONF0_MVP		(_ULCAST_(1) << VPECONF0_MVP_SHIFT)
++#define VPECONF0_XTC_SHIFT	21
++#define VPECONF0_XTC		(_ULCAST_(0xff) << VPECONF0_XTC_SHIFT)
++
++/* TCStatus fields (per TC) */
++#define TCSTATUS_TASID		(_ULCAST_(0xff))
++#define TCSTATUS_IXMT_SHIFT	10
++#define TCSTATUS_IXMT		(_ULCAST_(1) << TCSTATUS_IXMT_SHIFT)
++#define TCSTATUS_TKSU_SHIFT	11
++#define TCSTATUS_TKSU		(_ULCAST_(3) << TCSTATUS_TKSU_SHIFT)
++#define TCSTATUS_A_SHIFT	13
++#define TCSTATUS_A		(_ULCAST_(1) << TCSTATUS_A_SHIFT)
++#define TCSTATUS_DA_SHIFT	15
++#define TCSTATUS_DA		(_ULCAST_(1) << TCSTATUS_DA_SHIFT)
++#define TCSTATUS_DT_SHIFT	20
++#define TCSTATUS_DT		(_ULCAST_(1) << TCSTATUS_DT_SHIFT)
++#define TCSTATUS_TDS_SHIFT	21
++#define TCSTATUS_TDS		(_ULCAST_(1) << TCSTATUS_TDS_SHIFT)
++#define TCSTATUS_TSST_SHIFT	22
++#define TCSTATUS_TSST		(_ULCAST_(1) << TCSTATUS_TSST_SHIFT)
++#define TCSTATUS_RNST_SHIFT	23
++#define TCSTATUS_RNST		(_ULCAST_(3) << TCSTATUS_RNST_SHIFT)
++/* Codes for RNST */
++#define TC_RUNNING		0
++#define TC_WAITING		1
++#define TC_YIELDING		2
++#define TC_GATED		3
++
++#define TCSTATUS_TMX_SHIFT	27
++#define TCSTATUS_TMX		(_ULCAST_(1) << TCSTATUS_TMX_SHIFT)
++/* TCStatus TCU bits can use same definitions/offsets as CU bits in Status */
++
++/* TCBind */
++#define TCBIND_CURVPE_SHIFT	0
++#define TCBIND_CURVPE		(_ULCAST_(0xf))
++
++#define TCBIND_CURTC_SHIFT	21
++
++#define TCBIND_CURTC		(_ULCAST_(0xff) << TCBIND_CURTC_SHIFT)
++
++/* TCHalt */
++#define TCHALT_H		(_ULCAST_(1))
++
++#ifndef __ASSEMBLY__
++
++extern void mips_mt_regdump(void);
++
++static inline unsigned int dvpe(void)
++{
++	int res = 0;
++
++	__asm__ __volatile__(
++	"	.set	push						\n"
++	"	.set	noreorder					\n"
++	"	.set	noat						\n"
++	"	.set	mips32r2					\n"
++	"	.word	0x41610001		# dvpe $1		\n"
++	"	move	%0, $1						\n"
++	"	ehb							\n"
++	"	.set	pop						\n"
++	: "=r" (res));
++
++	instruction_hazard();
++
++	return res;
++}
++
++static inline void __raw_evpe(void)
++{
++	__asm__ __volatile__(
++	"	.set	push						\n"
++	"	.set	noreorder					\n"
++	"	.set	noat						\n"
++	"	.set	mips32r2					\n"
++	"	.word	0x41600021		# evpe			\n"
++	"	ehb							\n"
++	"	.set	pop						\n");
++}
++
++/* Enable multiMT if previous suggested it should be.
++   EMT_ENABLE to force */
++
++#define EVPE_ENABLE MVPCONTROL_EVP
++
++static inline void evpe(int previous)
++{
++	if ((previous & MVPCONTROL_EVP))
++		__raw_evpe();
++}
++
++static inline unsigned int dmt(void)
++{
++	int res;
++
++	__asm__ __volatile__(
++	"	.set	push						\n"
++	"	.set	mips32r2					\n"
++	"	.set	noat						\n"
++	"	.word	0x41610BC1			# dmt $1	\n"
++	"	ehb							\n"
++	"	move	%0, $1						\n"
++	"	.set	pop						\n"
++	: "=r" (res));
++
++	instruction_hazard();
++
++	return res;
++}
++
++static inline void __raw_emt(void)
++{
++	__asm__ __volatile__(
++	"	.set	noreorder					\n"
++	"	.set	mips32r2					\n"
++	"	emt							\n"
++	"	ehb							\n"
++	"	.set	mips0						\n"
++	"	.set	reorder");
++}
++
++/* enable multiVPE if previous suggested it should be.
++   EVPE_ENABLE to force */
++
++#define EMT_ENABLE VPECONTROL_TE
++
++static inline void emt(int previous)
++{
++	if ((previous & EMT_ENABLE))
++		__raw_emt();
++}
++
++static inline void ehb(void)
++{
++	__asm__ __volatile__(
++	"	.set	mips32r2				\n"
++	"	ehb						\n"
++	"	.set	mips0					\n");
++}
++
++#define mftc0(rt,sel)							\
++({									\
++	 unsigned long  __res;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	mips32r2				\n"	\
++	"	.set	noat					\n"	\
++	"	# mftc0	$1, $" #rt ", " #sel "			\n"	\
++	"	.word	0x41000800 | (" #rt " << 16) | " #sel "	\n"	\
++	"	move	%0, $1					\n"	\
++	"	.set	pop					\n"	\
++	: "=r" (__res));						\
++									\
++	__res;								\
++})
++
++#define mftgpr(rt)							\
++({									\
++	unsigned long __res;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	mips32r2				\n"	\
++	"	mftgpr	%0," #rt "				\n"	\
++	"	.set	pop					\n"	\
++	: "=r" (__res));						\
++									\
++	__res;								\
++})
++
++#define mftr(rt,u,sel)							\
++({									\
++	unsigned long __res;						\
++									\
++	__asm__ __volatile__(						\
++	".set noat\n\t"							\
++	"mftr\t%0, " #rt ", " #u ", " #sel "\n\t"			\
++	".set at\n\t"							\
++	: "=r" (__res));						\
++									\
++	__res;								\
++})
++
++#define mttgpr(rd,v)							\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	mips32r2				\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mttgpr $1, " #rd "				\n"	\
++	"	.word	0x41810020 | (" #rd " << 11)		\n"	\
++	"	.set	pop					\n"	\
++	: : "r" (v));							\
++} while (0)
++
++#define mttc0(rd,sel,v)							\
++({									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	mips32r2				\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mttc0 %0," #rd ", " #sel "			\n"	\
++	"	.word	0x41810000 | (" #rd " << 11) | " #sel "	\n"	\
++	"	.set	pop					\n"	\
++	:								\
++	: "r" (v));							\
++})
++
++
++#define mttr(rd,u,sel,v)						\
++({									\
++	__asm__ __volatile__(						\
++	"mttr	%0," #rd ", " #u ", " #sel				\
++	: : "r" (v));							\
++})
++
++
++#define settc(tc)							\
++do {									\
++	write_c0_vpecontrol((read_c0_vpecontrol()&~VPECONTROL_TARGTC) | (tc)); \
++	ehb();								\
++} while (0)
++
++
++/* you *must* set the target tc (settc) before trying to use these */
++#define read_vpe_c0_vpecontrol()	mftc0(1, 1)
++#define write_vpe_c0_vpecontrol(val)	mttc0(1, 1, val)
++#define read_vpe_c0_vpeconf0()		mftc0(1, 2)
++#define write_vpe_c0_vpeconf0(val)	mttc0(1, 2, val)
++#define read_vpe_c0_status()		mftc0(12, 0)
++#define write_vpe_c0_status(val)	mttc0(12, 0, val)
++#define read_vpe_c0_cause()		mftc0(13, 0)
++#define write_vpe_c0_cause(val)		mttc0(13, 0, val)
++#define read_vpe_c0_config()		mftc0(16, 0)
++#define write_vpe_c0_config(val)	mttc0(16, 0, val)
++#define read_vpe_c0_config1()		mftc0(16, 1)
++#define write_vpe_c0_config1(val)	mttc0(16, 1, val)
++#define read_vpe_c0_config7()		mftc0(16, 7)
++#define write_vpe_c0_config7(val)	mttc0(16, 7, val)
++#define read_vpe_c0_ebase()		mftc0(15,1)
++#define write_vpe_c0_ebase(val)		mttc0(15, 1, val)
++#define write_vpe_c0_compare(val)	mttc0(11, 0, val)
++
++
++/* TC */
++#define read_tc_c0_tcstatus()		mftc0(2, 1)
++#define write_tc_c0_tcstatus(val)	mttc0(2,1,val)
++#define read_tc_c0_tcbind()		mftc0(2, 2)
++#define write_tc_c0_tcbind(val)		mttc0(2,2,val)
++#define read_tc_c0_tcrestart()		mftc0(2, 3)
++#define write_tc_c0_tcrestart(val)	mttc0(2,3,val)
++#define read_tc_c0_tchalt()		mftc0(2, 4)
++#define write_tc_c0_tchalt(val)		mttc0(2,4,val)
++#define read_tc_c0_tccontext()		mftc0(2, 5)
++#define write_tc_c0_tccontext(val)	mttc0(2,5,val)
++
++/* GPR */
++#define read_tc_gpr_sp()		mftgpr(29)
++#define write_tc_gpr_sp(val)		mttgpr(29, val)
++#define read_tc_gpr_gp()		mftgpr(28)
++#define write_tc_gpr_gp(val)		mttgpr(28, val)
++
++__BUILD_SET_C0(mvpcontrol)
++
++#endif /* Not __ASSEMBLY__ */
++
++#endif
+diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
+--- a/include/asm-mips/mipsregs.h
++++ b/include/asm-mips/mipsregs.h
+@@ -8,7 +8,7 @@
+  * Modified for further R[236]000 support by Paul M. Antoine, 1996.
+  * Kevin D. Kissell, kevink at mips.com and Carsten Langgaard, carstenl at mips.com
+  * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+- * Copyright (C) 2003  Maciej W. Rozycki
++ * Copyright (C) 2003, 2004  Maciej W. Rozycki
+  */
+ #ifndef _ASM_MIPSREGS_H
+ #define _ASM_MIPSREGS_H
+@@ -96,6 +96,16 @@
+ #define CP0_S1_INTCONTROL $20
+ 
+ /*
++ * Coprocessor 0 Set 2 register names
++ */
++#define CP0_S2_SRSCTL	  $12	/* MIPSR2 */
++
++/*
++ * Coprocessor 0 Set 3 register names
++ */
++#define CP0_S3_SRSMAP	  $12	/* MIPSR2 */
++
++/*
+  *  TX39 Series
+  */
+ #define CP0_TX39_CACHE	$7
+@@ -281,6 +291,11 @@
+ #define ST0_DL			(_ULCAST_(1) << 24)
+ 
+ /*
++ * Enable the MIPS DSP ASE
++ */
++#define ST0_MX			0x01000000
++
++/*
+  * Bitfields in the TX39 family CP0 Configuration Register 3
+  */
+ #define TX39_CONF_ICS_SHIFT	19
+@@ -433,6 +448,14 @@
+ #define R5K_CONF_SE		(_ULCAST_(1) << 12)
+ #define R5K_CONF_SS		(_ULCAST_(3) << 20)
+ 
++/* Bits specific to the RM7000.  */
++#define RM7K_CONF_SE		(_ULCAST_(1) <<  3)
++#define RM7K_CONF_TE		(_ULCAST_(1) << 12)
++#define RM7K_CONF_CLK		(_ULCAST_(1) << 16)
++#define RM7K_CONF_TC		(_ULCAST_(1) << 17)
++#define RM7K_CONF_SI		(_ULCAST_(3) << 20)
++#define RM7K_CONF_SC		(_ULCAST_(1) << 31)
++
+ /* Bits specific to the R10000.  */
+ #define R10K_CONF_DN		(_ULCAST_(3) <<  3)
+ #define R10K_CONF_CT		(_ULCAST_(1) <<  5)
+@@ -475,6 +498,53 @@
+ #define MIPS_CONF_M		(_ULCAST_(1) << 31)
+ 
+ /*
++ * Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above.
++ */
++#define MIPS_CONF1_FP		(_ULCAST_(1) <<  0)
++#define MIPS_CONF1_EP		(_ULCAST_(1) <<  1)
++#define MIPS_CONF1_CA		(_ULCAST_(1) <<  2)
++#define MIPS_CONF1_WR		(_ULCAST_(1) <<  3)
++#define MIPS_CONF1_PC		(_ULCAST_(1) <<  4)
++#define MIPS_CONF1_MD		(_ULCAST_(1) <<  5)
++#define MIPS_CONF1_C2		(_ULCAST_(1) <<  6)
++#define MIPS_CONF1_DA		(_ULCAST_(7) <<  7)
++#define MIPS_CONF1_DL		(_ULCAST_(7) << 10)
++#define MIPS_CONF1_DS		(_ULCAST_(7) << 13)
++#define MIPS_CONF1_IA		(_ULCAST_(7) << 16)
++#define MIPS_CONF1_IL		(_ULCAST_(7) << 19)
++#define MIPS_CONF1_IS		(_ULCAST_(7) << 22)
++#define MIPS_CONF1_TLBS		(_ULCAST_(63)<< 25)
++
++#define MIPS_CONF2_SA		(_ULCAST_(15)<<  0)
++#define MIPS_CONF2_SL		(_ULCAST_(15)<<  4)
++#define MIPS_CONF2_SS		(_ULCAST_(15)<<  8)
++#define MIPS_CONF2_SU		(_ULCAST_(15)<< 12)
++#define MIPS_CONF2_TA		(_ULCAST_(15)<< 16)
++#define MIPS_CONF2_TL		(_ULCAST_(15)<< 20)
++#define MIPS_CONF2_TS		(_ULCAST_(15)<< 24)
++#define MIPS_CONF2_TU		(_ULCAST_(7) << 28)
++
++#define MIPS_CONF3_TL		(_ULCAST_(1) <<  0)
++#define MIPS_CONF3_SM		(_ULCAST_(1) <<  1)
++#define MIPS_CONF3_MT		(_ULCAST_(1) <<  2)
++#define MIPS_CONF3_SP		(_ULCAST_(1) <<  4)
++#define MIPS_CONF3_VINT		(_ULCAST_(1) <<  5)
++#define MIPS_CONF3_VEIC		(_ULCAST_(1) <<  6)
++#define MIPS_CONF3_LPA		(_ULCAST_(1) <<  7)
++#define MIPS_CONF3_DSP		(_ULCAST_(1) << 10)
++
++/*
++ * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
++ */
++#define MIPS_FPIR_S		(_ULCAST_(1) << 16)
++#define MIPS_FPIR_D		(_ULCAST_(1) << 17)
++#define MIPS_FPIR_PS		(_ULCAST_(1) << 18)
++#define MIPS_FPIR_3D		(_ULCAST_(1) << 19)
++#define MIPS_FPIR_W		(_ULCAST_(1) << 20)
++#define MIPS_FPIR_L		(_ULCAST_(1) << 21)
++#define MIPS_FPIR_F64		(_ULCAST_(1) << 22)
++
++/*
+  * R10000 performance counter definitions.
+  *
+  * FIXME: The R10000 performance counter opens a nice way to implement CPU
+@@ -621,13 +691,13 @@ do {									\
+ 	if (sel == 0)							\
+ 		__asm__ __volatile__(					\
+ 			"mtc0\t%z0, " #register "\n\t"			\
+-			: : "Jr" ((unsigned int)value));		\
++			: : "Jr" ((unsigned int)(value)));		\
+ 	else								\
+ 		__asm__ __volatile__(					\
+ 			".set\tmips32\n\t"				\
+ 			"mtc0\t%z0, " #register ", " #sel "\n\t"	\
+ 			".set\tmips0"					\
+-			: : "Jr" ((unsigned int)value));		\
++			: : "Jr" ((unsigned int)(value)));		\
+ } while (0)
+ 
+ #define __write_64bit_c0_register(register, sel, value)			\
+@@ -676,7 +746,7 @@ do {									\
+ do {									\
+ 	__asm__ __volatile__(						\
+ 		"ctc0\t%z0, " #register "\n\t"				\
+-		: : "Jr" ((unsigned int)value));			\
++		: : "Jr" ((unsigned int)(value)));			\
+ } while (0)
+ 
+ /*
+@@ -769,12 +839,24 @@ do {									\
+ #define read_c0_count()		__read_32bit_c0_register($9, 0)
+ #define write_c0_count(val)	__write_32bit_c0_register($9, 0, val)
+ 
++#define read_c0_count2()	__read_32bit_c0_register($9, 6) /* pnx8550 */
++#define write_c0_count2(val)	__write_32bit_c0_register($9, 6, val)
++
++#define read_c0_count3()	__read_32bit_c0_register($9, 7) /* pnx8550 */
++#define write_c0_count3(val)	__write_32bit_c0_register($9, 7, val)
++
+ #define read_c0_entryhi()	__read_ulong_c0_register($10, 0)
+ #define write_c0_entryhi(val)	__write_ulong_c0_register($10, 0, val)
+ 
+ #define read_c0_compare()	__read_32bit_c0_register($11, 0)
+ #define write_c0_compare(val)	__write_32bit_c0_register($11, 0, val)
+ 
++#define read_c0_compare2()	__read_32bit_c0_register($11, 6) /* pnx8550 */
++#define write_c0_compare2(val)	__write_32bit_c0_register($11, 6, val)
++
++#define read_c0_compare3()	__read_32bit_c0_register($11, 7) /* pnx8550 */
++#define write_c0_compare3(val)	__write_32bit_c0_register($11, 7, val)
++
+ #define read_c0_status()	__read_32bit_c0_register($12, 0)
+ #define write_c0_status(val)	__write_32bit_c0_register($12, 0, val)
+ 
+@@ -790,10 +872,18 @@ do {									\
+ #define read_c0_config1()	__read_32bit_c0_register($16, 1)
+ #define read_c0_config2()	__read_32bit_c0_register($16, 2)
+ #define read_c0_config3()	__read_32bit_c0_register($16, 3)
++#define read_c0_config4()	__read_32bit_c0_register($16, 4)
++#define read_c0_config5()	__read_32bit_c0_register($16, 5)
++#define read_c0_config6()	__read_32bit_c0_register($16, 6)
++#define read_c0_config7()	__read_32bit_c0_register($16, 7)
+ #define write_c0_config(val)	__write_32bit_c0_register($16, 0, val)
+ #define write_c0_config1(val)	__write_32bit_c0_register($16, 1, val)
+ #define write_c0_config2(val)	__write_32bit_c0_register($16, 2, val)
+ #define write_c0_config3(val)	__write_32bit_c0_register($16, 3, val)
++#define write_c0_config4(val)	__write_32bit_c0_register($16, 4, val)
++#define write_c0_config5(val)	__write_32bit_c0_register($16, 5, val)
++#define write_c0_config6(val)	__write_32bit_c0_register($16, 6, val)
++#define write_c0_config7(val)	__write_32bit_c0_register($16, 7, val)
+ 
+ /*
+  * The WatchLo register.  There may be upto 8 of them.
+@@ -917,6 +1007,22 @@ do {									\
+ #define read_c0_errorepc()	__read_ulong_c0_register($30, 0)
+ #define write_c0_errorepc(val)	__write_ulong_c0_register($30, 0, val)
+ 
++/* MIPSR2 */
++#define read_c0_hwrena()	__read_32bit_c0_register($7,0)
++#define write_c0_hwrena(val)	__write_32bit_c0_register($7, 0, val)
++
++#define read_c0_intctl()	__read_32bit_c0_register($12, 1)
++#define write_c0_intctl(val)	__write_32bit_c0_register($12, 1, val)
++
++#define read_c0_srsctl()	__read_32bit_c0_register($12, 2)
++#define write_c0_srsctl(val)	__write_32bit_c0_register($12, 2, val)
++
++#define read_c0_srsmap()	__read_32bit_c0_register($12, 3)
++#define write_c0_srsmap(val)	__write_32bit_c0_register($12, 3, val)
++
++#define read_c0_ebase()		__read_32bit_c0_register($15,1)
++#define write_c0_ebase(val)	__write_32bit_c0_register($15, 1, val)
++
+ /*
+  * Macros to access the floating point coprocessor control registers
+  */
+@@ -930,6 +1036,284 @@ do {									\
+         : "=r" (__res));                                        \
+         __res;})
+ 
++#define rddsp(mask)							\
++({									\
++	unsigned int __res;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push				\n"		\
++	"	.set	noat				\n"		\
++	"	# rddsp $1, %x1				\n"		\
++	"	.word	0x7c000cb8 | (%x1 << 16)	\n"		\
++	"	move	%0, $1				\n"		\
++	"	.set	pop				\n"		\
++	: "=r" (__res)							\
++	: "i" (mask));							\
++	__res;								\
++})
++
++#define wrdsp(val, mask)						\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# wrdsp $1, %x1					\n"	\
++	"	.word	0x7c2004f8 | (%x1 << 15)		\n"	\
++	"	.set	pop					\n"	\
++        :								\
++	: "r" (val), "i" (mask));					\
++} while (0)
++
++#if 0	/* Need DSP ASE capable assembler ... */
++#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
++#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
++#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
++#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
++
++#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
++#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
++#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
++#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
++
++#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
++#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
++#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
++#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
++
++#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
++#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
++#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
++#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
++
++#else
++
++#define mfhi0()								\
++({									\
++	unsigned long __treg;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push			\n"			\
++	"	.set	noat			\n"			\
++	"	# mfhi	%0, $ac0		\n"			\
++	"	.word	0x00000810		\n"			\
++	"	move	%0, $1			\n"			\
++	"	.set	pop			\n"			\
++	: "=r" (__treg));						\
++	__treg;								\
++})
++
++#define mfhi1()								\
++({									\
++	unsigned long __treg;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push			\n"			\
++	"	.set	noat			\n"			\
++	"	# mfhi	%0, $ac1		\n"			\
++	"	.word	0x00200810		\n"			\
++	"	move	%0, $1			\n"			\
++	"	.set	pop			\n"			\
++	: "=r" (__treg));						\
++	__treg;								\
++})
++
++#define mfhi2()								\
++({									\
++	unsigned long __treg;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push			\n"			\
++	"	.set	noat			\n"			\
++	"	# mfhi	%0, $ac2		\n"			\
++	"	.word	0x00400810		\n"			\
++	"	move	%0, $1			\n"			\
++	"	.set	pop			\n"			\
++	: "=r" (__treg));						\
++	__treg;								\
++})
++
++#define mfhi3()								\
++({									\
++	unsigned long __treg;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push			\n"			\
++	"	.set	noat			\n"			\
++	"	# mfhi	%0, $ac3		\n"			\
++	"	.word	0x00600810		\n"			\
++	"	move	%0, $1			\n"			\
++	"	.set	pop			\n"			\
++	: "=r" (__treg));						\
++	__treg;								\
++})
++
++#define mflo0()								\
++({									\
++	unsigned long __treg;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push			\n"			\
++	"	.set	noat			\n"			\
++	"	# mflo	%0, $ac0		\n"			\
++	"	.word	0x00000812		\n"			\
++	"	move	%0, $1			\n"			\
++	"	.set	pop			\n"			\
++	: "=r" (__treg));						\
++	__treg;								\
++})
++
++#define mflo1()								\
++({									\
++	unsigned long __treg;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push			\n"			\
++	"	.set	noat			\n"			\
++	"	# mflo	%0, $ac1		\n"			\
++	"	.word	0x00200812		\n"			\
++	"	move	%0, $1			\n"			\
++	"	.set	pop			\n"			\
++	: "=r" (__treg));						\
++	__treg;								\
++})
++
++#define mflo2()								\
++({									\
++	unsigned long __treg;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push			\n"			\
++	"	.set	noat			\n"			\
++	"	# mflo	%0, $ac2		\n"			\
++	"	.word	0x00400812		\n"			\
++	"	move	%0, $1			\n"			\
++	"	.set	pop			\n"			\
++	: "=r" (__treg));						\
++	__treg;								\
++})
++
++#define mflo3()								\
++({									\
++	unsigned long __treg;						\
++									\
++	__asm__ __volatile__(						\
++	"	.set	push			\n"			\
++	"	.set	noat			\n"			\
++	"	# mflo	%0, $ac3		\n"			\
++	"	.word	0x00600812		\n"			\
++	"	move	%0, $1			\n"			\
++	"	.set	pop			\n"			\
++	: "=r" (__treg));						\
++	__treg;								\
++})
++
++#define mthi0(x)							\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mthi	$1, $ac0				\n"	\
++	"	.word	0x00200011				\n"	\
++	"	.set	pop					\n"	\
++	:								\
++	: "r" (x));							\
++} while (0)
++
++#define mthi1(x)							\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mthi	$1, $ac1				\n"	\
++	"	.word	0x00200811				\n"	\
++	"	.set	pop					\n"	\
++	:								\
++	: "r" (x));							\
++} while (0)
++
++#define mthi2(x)							\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mthi	$1, $ac2				\n"	\
++	"	.word	0x00201011				\n"	\
++	"	.set	pop					\n"	\
++	:								\
++	: "r" (x));							\
++} while (0)
++
++#define mthi3(x)							\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mthi	$1, $ac3				\n"	\
++	"	.word	0x00201811				\n"	\
++	"	.set	pop					\n"	\
++	:								\
++	: "r" (x));							\
++} while (0)
++
++#define mtlo0(x)							\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mtlo	$1, $ac0				\n"	\
++	"	.word	0x00200013				\n"	\
++	"	.set	pop					\n"	\
++	:								\
++	: "r" (x));							\
++} while (0)
++
++#define mtlo1(x)							\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mtlo	$1, $ac1				\n"	\
++	"	.word	0x00200813				\n"	\
++	"	.set	pop					\n"	\
++	:								\
++	: "r" (x));							\
++} while (0)
++
++#define mtlo2(x)							\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mtlo	$1, $ac2				\n"	\
++	"	.word	0x00201013				\n"	\
++	"	.set	pop					\n"	\
++	:								\
++	: "r" (x));							\
++} while (0)
++
++#define mtlo3(x)							\
++do {									\
++	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
++	"	.set	noat					\n"	\
++	"	move	$1, %0					\n"	\
++	"	# mtlo	$1, $ac3				\n"	\
++	"	.word	0x00201813				\n"	\
++	"	.set	pop					\n"	\
++	:								\
++	: "r" (x));							\
++} while (0)
++
++#endif
++
+ /*
+  * TLB operations.
+  *
+@@ -1012,6 +1396,8 @@ __BUILD_SET_C0(status)
+ __BUILD_SET_C0(cause)
+ __BUILD_SET_C0(config)
+ __BUILD_SET_C0(intcontrol)
++__BUILD_SET_C0(intctl)
++__BUILD_SET_C0(srsmap)
+ 
+ #endif /* !__ASSEMBLY__ */
+ 
+diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h
+--- a/include/asm-mips/mmu_context.h
++++ b/include/asm-mips/mmu_context.h
+@@ -30,7 +30,7 @@ extern unsigned long pgd_current[];
+ 
+ #ifdef CONFIG_32BIT
+ #define TLBMISS_HANDLER_SETUP()						\
+-	write_c0_context((unsigned long) smp_processor_id() << 23);	\
++	write_c0_context((unsigned long) smp_processor_id() << 25);	\
+ 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+ #endif
+ #if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
+@@ -40,7 +40,7 @@ extern unsigned long pgd_current[];
+ #endif
+ #if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+ #define TLBMISS_HANDLER_SETUP()						\
+-	write_c0_context((unsigned long) smp_processor_id() << 23);	\
++	write_c0_context((unsigned long) smp_processor_id() << 26);	\
+ 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+ #endif
+ 
+diff --git a/include/asm-mips/mmzone.h b/include/asm-mips/mmzone.h
+--- a/include/asm-mips/mmzone.h
++++ b/include/asm-mips/mmzone.h
+@@ -5,6 +5,7 @@
+ #ifndef _ASM_MMZONE_H_
+ #define _ASM_MMZONE_H_
+ 
++#include <linux/config.h>
+ #include <asm/page.h>
+ #include <mmzone.h>
+ 
+diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h
+--- a/include/asm-mips/module.h
++++ b/include/asm-mips/module.h
+@@ -14,15 +14,23 @@ struct mod_arch_specific {
+ 
+ typedef uint8_t Elf64_Byte;		/* Type for a 8-bit quantity.  */
+ 
+-typedef struct
+-{
+-  Elf64_Addr r_offset;			/* Address of relocation.  */
+-  Elf64_Word r_sym;			/* Symbol index.  */
+-  Elf64_Byte r_ssym;			/* Special symbol.  */
+-  Elf64_Byte r_type3;			/* Third relocation.  */
+-  Elf64_Byte r_type2;			/* Second relocation.  */
+-  Elf64_Byte r_type;			/* First relocation.  */
+-  Elf64_Sxword r_addend;		/* Addend.  */
++typedef struct {
++	Elf64_Addr r_offset;			/* Address of relocation.  */
++	Elf64_Word r_sym;			/* Symbol index.  */
++	Elf64_Byte r_ssym;			/* Special symbol.  */
++	Elf64_Byte r_type3;			/* Third relocation.  */
++	Elf64_Byte r_type2;			/* Second relocation.  */
++	Elf64_Byte r_type;			/* First relocation.  */
++} Elf64_Mips_Rel;
++
++typedef struct {
++	Elf64_Addr r_offset;			/* Address of relocation.  */
++	Elf64_Word r_sym;			/* Symbol index.  */
++	Elf64_Byte r_ssym;			/* Special symbol.  */
++	Elf64_Byte r_type3;			/* Third relocation.  */
++	Elf64_Byte r_type2;			/* Second relocation.  */
++	Elf64_Byte r_type;			/* First relocation.  */
++	Elf64_Sxword r_addend;			/* Addend.  */
+ } Elf64_Mips_Rela;
+ 
+ #ifdef CONFIG_32BIT
+@@ -30,6 +38,13 @@ typedef struct
+ #define Elf_Shdr	Elf32_Shdr
+ #define Elf_Sym		Elf32_Sym
+ #define Elf_Ehdr	Elf32_Ehdr
++#define Elf_Addr	Elf32_Addr
++
++#define Elf_Mips_Rel	Elf32_Rel
++#define Elf_Mips_Rela	Elf32_Rela
++
++#define ELF_MIPS_R_SYM(rel) ELF32_R_SYM(rel.r_info)
++#define ELF_MIPS_R_TYPE(rel) ELF32_R_TYPE(rel.r_info)
+ 
+ #endif
+ 
+@@ -38,6 +53,13 @@ typedef struct
+ #define Elf_Shdr	Elf64_Shdr
+ #define Elf_Sym		Elf64_Sym
+ #define Elf_Ehdr	Elf64_Ehdr
++#define Elf_Addr	Elf64_Addr
++
++#define Elf_Mips_Rel	Elf64_Mips_Rel
++#define Elf_Mips_Rela	Elf64_Mips_Rela
++
++#define ELF_MIPS_R_SYM(rel) (rel.r_sym)
++#define ELF_MIPS_R_TYPE(rel) (rel.r_type)
+ 
+ #endif
+ 
+@@ -53,4 +75,54 @@ search_module_dbetables(unsigned long ad
+ }
+ #endif
+ 
++#ifdef CONFIG_CPU_MIPS32_R1
++#define MODULE_PROC_FAMILY "MIPS32_R1"
++#elif defined CONFIG_CPU_MIPS32_R2
++#define MODULE_PROC_FAMILY "MIPS32_R2"
++#elif defined CONFIG_CPU_MIPS64_R1
++#define MODULE_PROC_FAMILY "MIPS64_R1"
++#elif defined CONFIG_CPU_MIPS64_R2
++#define MODULE_PROC_FAMILY "MIPS64_R2"
++#elif defined CONFIG_CPU_R3000
++#define MODULE_PROC_FAMILY "R3000"
++#elif defined CONFIG_CPU_TX39XX
++#define MODULE_PROC_FAMILY "TX39XX"
++#elif defined CONFIG_CPU_VR41XX
++#define MODULE_PROC_FAMILY "VR41XX"
++#elif defined CONFIG_CPU_R4300
++#define MODULE_PROC_FAMILY "R4300"
++#elif defined CONFIG_CPU_R4X00
++#define MODULE_PROC_FAMILY "R4X00"
++#elif defined CONFIG_CPU_TX49XX
++#define MODULE_PROC_FAMILY "TX49XX"
++#elif defined CONFIG_CPU_R5000
++#define MODULE_PROC_FAMILY "R5000"
++#elif defined CONFIG_CPU_R5432
++#define MODULE_PROC_FAMILY "R5432"
++#elif defined CONFIG_CPU_R6000
++#define MODULE_PROC_FAMILY "R6000"
++#elif defined CONFIG_CPU_NEVADA
++#define MODULE_PROC_FAMILY "NEVADA"
++#elif defined CONFIG_CPU_R8000
++#define MODULE_PROC_FAMILY "R8000"
++#elif defined CONFIG_CPU_R10000
++#define MODULE_PROC_FAMILY "R10000"
++#elif defined CONFIG_CPU_RM7000
++#define MODULE_PROC_FAMILY "RM7000"
++#elif defined CONFIG_CPU_RM9000
++#define MODULE_PROC_FAMILY "RM9000"
++#elif defined CONFIG_CPU_SB1
++#define MODULE_PROC_FAMILY "SB1"
++#else
++#error MODULE_PROC_FAMILY undefined for your processor configuration
++#endif
++
++#ifdef CONFIG_32BIT
++#define MODULE_KERNEL_TYPE "32BIT "
++#elif defined CONFIG_64BIT
++#define MODULE_KERNEL_TYPE "64BIT "
++#endif
++
++#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_KERNEL_TYPE
++
+ #endif /* _ASM_MODULE_H */
+diff --git a/include/asm-mips/paccess.h b/include/asm-mips/paccess.h
+--- a/include/asm-mips/paccess.h
++++ b/include/asm-mips/paccess.h
+@@ -52,7 +52,7 @@ struct __large_pstruct { unsigned long b
+ })
+ 
+ #define __get_dbe_asm(insn)						\
+-({									\
++{									\
+ 	__asm__ __volatile__(						\
+ 	"1:\t" insn "\t%1,%2\n\t"					\
+ 	"move\t%0,$0\n"							\
+@@ -67,7 +67,7 @@ struct __large_pstruct { unsigned long b
+ 	".previous"							\
+ 	:"=r" (__gu_err), "=r" (__gu_val)				\
+ 	:"o" (__mp(__gu_addr)), "i" (-EFAULT));				\
+-})
++}
+ 
+ extern void __get_dbe_unknown(void);
+ 
+@@ -90,7 +90,7 @@ extern void __get_dbe_unknown(void);
+ })
+ 
+ #define __put_dbe_asm(insn)						\
+-({									\
++{									\
+ 	__asm__ __volatile__(						\
+ 	"1:\t" insn "\t%1,%2\n\t"					\
+ 	"move\t%0,$0\n"							\
+@@ -104,7 +104,7 @@ extern void __get_dbe_unknown(void);
+ 	".previous"							\
+ 	: "=r" (__pu_err)						\
+ 	: "r" (__pu_val), "o" (__mp(__pu_addr)), "i" (-EFAULT));	\
+-})
++}
+ 
+ extern void __put_dbe_unknown(void);
+ 
+diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
+--- a/include/asm-mips/page.h
++++ b/include/asm-mips/page.h
+@@ -87,22 +87,48 @@ static inline void copy_user_page(void *
+ typedef struct { unsigned long pte; } pte_t;
+ #define pte_val(x)	((x).pte)
+ #endif
++#define __pte(x)	((pte_t) { (x) } )
+ 
+-typedef struct { unsigned long pmd; } pmd_t;
+-typedef struct { unsigned long pgd; } pgd_t;
+-typedef struct { unsigned long pgprot; } pgprot_t;
++/*
++ * For 3-level pagetables we defines these ourselves, for 2-level the
++ * definitions are supplied by <asm-generic/pgtable-nopmd.h>.
++ */
++#ifdef CONFIG_64BIT
+ 
++typedef struct { unsigned long pmd; } pmd_t;
+ #define pmd_val(x)	((x).pmd)
+-#define pgd_val(x)	((x).pgd)
+-#define pgprot_val(x)	((x).pgprot)
++#define __pmd(x)	((pmd_t) { (x) } )
+ 
+-#define ptep_buddy(x)	((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
++#endif
+ 
+-#define __pte(x)	((pte_t) { (x) } )
+-#define __pmd(x)	((pmd_t) { (x) } )
++/*
++ * Right now we don't support 4-level pagetables, so all pud-related
++ * definitions come from <asm-generic/pgtable-nopud.h>.
++ */
++
++/*
++ * Finall the top of the hierarchy, the pgd
++ */
++typedef struct { unsigned long pgd; } pgd_t;
++#define pgd_val(x)	((x).pgd)
+ #define __pgd(x)	((pgd_t) { (x) } )
++
++/*
++ * Manipulate page protection bits
++ */
++typedef struct { unsigned long pgprot; } pgprot_t;
++#define pgprot_val(x)	((x).pgprot)
+ #define __pgprot(x)	((pgprot_t) { (x) } )
+ 
++/*
++ * On R4000-style MMUs where a TLB entry is mapping a adjacent even / odd
++ * pair of pages we only have a single global bit per pair of pages.  When
++ * writing to the TLB make sure we always have the bit set for both pages
++ * or none.  This macro is used to access the `buddy' of the pte we're just
++ * working on.
++ */
++#define ptep_buddy(x)	((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
++
+ #endif /* !__ASSEMBLY__ */
+ 
+ /* to align the pointer to the (next) page boundary */
+diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h
+--- a/include/asm-mips/pci.h
++++ b/include/asm-mips/pci.h
+@@ -40,6 +40,11 @@ struct pci_controller {
+ 	unsigned int need_domain_info;
+ 
+ 	int iommu;
++
++	/* Optional access methods for reading/writing the bus number
++	   of the PCI controller */
++	int (*get_busno)(void);
++	void (*set_busno)(int busno);
+ };
+ 
+ /*
+@@ -142,8 +147,22 @@ static inline void pci_dma_burst_advice(
+ 
+ extern void pcibios_resource_to_bus(struct pci_dev *dev,
+ 	struct pci_bus_region *region, struct resource *res);
+-extern void pcibios_bus_to_resource(struct pci_dev *dev,
+-	struct resource *res, struct pci_bus_region *region);
++
++extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
++				    struct pci_bus_region *region);
++
++static inline struct resource *
++pcibios_select_root(struct pci_dev *pdev, struct resource *res)
++{
++	struct resource *root = NULL;
++
++	if (res->flags & IORESOURCE_IO)
++		root = &ioport_resource;
++	if (res->flags & IORESOURCE_MEM)
++		root = &iomem_resource;
++
++	return root;
++}
+ 
+ #ifdef CONFIG_PCI_DOMAINS
+ 
+@@ -169,17 +188,4 @@ static inline void pcibios_add_platform_
+ /* Do platform specific device initialization at pci_enable_device() time */
+ extern int pcibios_plat_dev_init(struct pci_dev *dev);
+ 
+-static inline struct resource *
+-pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+-{
+-	struct resource *root = NULL;
+-
+-	if (res->flags & IORESOURCE_IO)
+-		root = &ioport_resource;
+-	if (res->flags & IORESOURCE_MEM)
+-		root = &iomem_resource;
+-
+-	return root;
+-}
+-
+ #endif /* _ASM_PCI_H */
+diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h
+--- a/include/asm-mips/pgalloc.h
++++ b/include/asm-mips/pgalloc.h
+@@ -26,10 +26,22 @@ static inline void pmd_populate(struct m
+ }
+ 
+ /*
++ * Initialize a new pmd table with invalid pointers.
++ */
++extern void pmd_init(unsigned long page, unsigned long pagetable);
++
++#ifdef CONFIG_64BIT
++
++static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
++{
++	set_pud(pud, __pud((unsigned long)pmd));
++}
++#endif
++
++/*
+  * Initialize a new pgd / pmd table with invalid pointers.
+  */
+ extern void pgd_init(unsigned long page);
+-extern void pmd_init(unsigned long page, unsigned long pagetable);
+ 
+ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+@@ -86,21 +98,18 @@ static inline void pte_free(struct page 
+ #define __pte_free_tlb(tlb,pte)		tlb_remove_page((tlb),(pte))
+ 
+ #ifdef CONFIG_32BIT
+-#define pgd_populate(mm, pmd, pte)	BUG()
+ 
+ /*
+  * allocating and freeing a pmd is trivial: the 1-entry pmd is
+  * inside the pgd, so has no extra memory associated with it.
+  */
+-#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *)2); })
+ #define pmd_free(x)			do { } while (0)
+ #define __pmd_free_tlb(tlb,x)		do { } while (0)
++
+ #endif
+ 
+ #ifdef CONFIG_64BIT
+ 
+-#define pgd_populate(mm, pgd, pmd)	set_pgd(pgd, __pgd(pmd))
+-
+ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+ {
+ 	pmd_t *pmd;
+diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h
+--- a/include/asm-mips/pgtable-32.h
++++ b/include/asm-mips/pgtable-32.h
+@@ -17,6 +17,8 @@
+ #include <asm/cachectl.h>
+ #include <asm/fixmap.h>
+ 
++#include <asm-generic/pgtable-nopmd.h>
++
+ /*
+  * - add_wired_entry() add a fixed TLB entry, and move wired register
+  */
+@@ -41,42 +43,38 @@ extern int add_temporary_entry(unsigned 
+  * works even with the cache aliasing problem the R4k and above have.
+  */
+ 
+-/* 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 */
+ #ifdef CONFIG_64BIT_PHYS_ADDR
+-#define PMD_SHIFT	21
++#define PGDIR_SHIFT	21
+ #else
+-#define PMD_SHIFT	22
++#define PGDIR_SHIFT	22
+ #endif
+-#define PMD_SIZE	(1UL << PMD_SHIFT)
+-#define PMD_MASK	(~(PMD_SIZE-1))
+-
+-/* PGDIR_SHIFT determines what a third-level page table entry can map */
+-#define PGDIR_SHIFT	PMD_SHIFT
+ #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+ #define PGDIR_MASK	(~(PGDIR_SIZE-1))
+ 
+ /*
+  * Entries per page directory level: we use two-level, so
+- * we don't really have any PMD directory physically.
++ * we don't really have any PUD/PMD directory physically.
+  */
+ #ifdef CONFIG_64BIT_PHYS_ADDR
+ #define PGD_ORDER	1
+-#define PMD_ORDER	0
++#define PUD_ORDER	aieeee_attempt_to_allocate_pud
++#define PMD_ORDER	1
+ #define PTE_ORDER	0
+ #else
+ #define PGD_ORDER	0
+-#define PMD_ORDER	0
++#define PUD_ORDER	aieeee_attempt_to_allocate_pud
++#define PMD_ORDER	1
+ #define PTE_ORDER	0
+ #endif
+ 
+ #define PTRS_PER_PGD	((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
+-#define PTRS_PER_PMD	1
+ #define PTRS_PER_PTE	((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
+ 
+ #define USER_PTRS_PER_PGD	(0x80000000UL/PGDIR_SIZE)
+ #define FIRST_USER_ADDRESS	0
+ 
+-#define VMALLOC_START     KSEG2
++#define VMALLOC_START     MAP_BASE
+ 
+ #ifdef CONFIG_HIGHMEM
+ # define VMALLOC_END	(PKMAP_BASE-2*PAGE_SIZE)
+@@ -91,8 +89,6 @@ extern int add_temporary_entry(unsigned 
+ #define pte_ERROR(e) \
+ 	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+ #endif
+-#define pmd_ERROR(e) \
+-	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+ #define pgd_ERROR(e) \
+ 	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+ 
+@@ -120,17 +116,7 @@ static inline void pmd_clear(pmd_t *pmdp
+ 	pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
+ }
+ 
+-/*
+- * The "pgd_xxx()" functions here are trivial for a folded two-level
+- * setup: the pgd is never bad, and a pmd always exists (as it's folded
+- * into the pgd entry)
+- */
+-static inline int pgd_none(pgd_t pgd)		{ return 0; }
+-static inline int pgd_bad(pgd_t pgd)		{ return 0; }
+-static inline int pgd_present(pgd_t pgd)	{ return 1; }
+-static inline void pgd_clear(pgd_t *pgdp)	{ }
+-
+-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
++#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+ #define pte_page(x)		pfn_to_page(pte_pfn(x))
+ #define pte_pfn(x)		((unsigned long)((x).pte_high >> 6))
+ static inline pte_t
+@@ -151,27 +137,22 @@ pfn_pte(unsigned long pfn, pgprot_t prot
+ #define pfn_pte(pfn, prot)	__pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
+ #else
+ #define pte_pfn(x)		((unsigned long)((x).pte >> PAGE_SHIFT))
+-#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
++#define pfn_pte(pfn, prot)	__pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
+ #endif
+-#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
++#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) */
+ 
+ #define __pgd_offset(address)	pgd_index(address)
++#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+ #define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+ 
+ /* to find an entry in a kernel page-table-directory */
+ #define pgd_offset_k(address) pgd_offset(&init_mm, address)
+ 
+-#define pgd_index(address)	((address) >> PGDIR_SHIFT)
++#define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+ 
+ /* to find an entry in a page-table-directory */
+ #define pgd_offset(mm,addr)	((mm)->pgd + pgd_index(addr))
+ 
+-/* Find an entry in the second-level page table.. */
+-static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
+-{
+-	return (pmd_t *) dir;
+-}
+-
+ /* Find an entry in the third-level page table.. */
+ #define __pte_offset(address)						\
+ 	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+@@ -221,7 +202,7 @@ static inline pmd_t *pmd_offset(pgd_t *d
+  */
+ #define PTE_FILE_MAX_BITS	27
+ 
+-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
++#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+ 	/* fixme */
+ #define pte_to_pgoff(_pte) (((_pte).pte_high >> 6) + ((_pte).pte_high & 0x3f))
+ #define pgoff_to_pte(off) \
+diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h
+--- a/include/asm-mips/pgtable-64.h
++++ b/include/asm-mips/pgtable-64.h
+@@ -16,13 +16,15 @@
+ #include <asm/page.h>
+ #include <asm/cachectl.h>
+ 
++#include <asm-generic/pgtable-nopud.h>
++
+ /*
+  * Each address space has 2 4K pages as its page directory, giving 1024
+  * (== PTRS_PER_PGD) 8 byte pointers to pmd tables. Each pmd table is a
+- * pair of 4K pages, giving 1024 (== PTRS_PER_PMD) 8 byte pointers to
+- * page tables. Each page table is a single 4K page, giving 512 (==
+- * PTRS_PER_PTE) 8 byte ptes. Each pgde is initialized to point to
+- * invalid_pmd_table, each pmde is initialized to point to
++ * single 4K page, giving 512 (== PTRS_PER_PMD) 8 byte pointers to page
++ * tables. Each page table is also a single 4K page, giving 512 (==
++ * PTRS_PER_PTE) 8 byte ptes. Each pud entry is initialized to point to
++ * invalid_pmd_table, each pmd entry is initialized to point to
+  * invalid_pte_table, each pte is initialized to 0. When memory is low,
+  * and a pmd table or a page table allocation fails, empty_bad_pmd_table
+  * and empty_bad_page_table is returned back to higher layer code, so
+@@ -36,17 +38,17 @@
+  */
+ 
+ /* PMD_SHIFT determines the size of the area a second-level page table can map */
+-#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - 3))
++#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3))
+ #define PMD_SIZE	(1UL << PMD_SHIFT)
+ #define PMD_MASK	(~(PMD_SIZE-1))
+ 
+ /* PGDIR_SHIFT determines what a third-level page table entry can map */
+-#define PGDIR_SHIFT	(PMD_SHIFT + (PAGE_SHIFT + 1 - 3))
++#define PGDIR_SHIFT	(PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3))
+ #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+ #define PGDIR_MASK	(~(PGDIR_SIZE-1))
+ 
+ /*
+- * For 4kB page size we use a 3 level page tree and a 8kB pmd and pgds which
++ * For 4kB page size we use a 3 level page tree and an 8kB pud, which
+  * permits us mapping 40 bits of virtual address space.
+  *
+  * We used to implement 41 bits by having an order 1 pmd level but that seemed
+@@ -57,7 +59,7 @@
+  * two levels would be easy to implement.
+  *
+  * For 16kB page size we use a 2 level page tree which permits a total of
+- * 36 bits of virtual address space.  We could add a third leve. but it seems
++ * 36 bits of virtual address space.  We could add a third level but it seems
+  * like at the moment there's no need for this.
+  *
+  * For 64kB page size we use a 2 level page table tree for a total of 42 bits
+@@ -65,21 +67,25 @@
+  */
+ #ifdef CONFIG_PAGE_SIZE_4KB
+ #define PGD_ORDER		1
++#define PUD_ORDER		aieeee_attempt_to_allocate_pud
+ #define PMD_ORDER		0
+ #define PTE_ORDER		0
+ #endif
+ #ifdef CONFIG_PAGE_SIZE_8KB
+ #define PGD_ORDER		0
++#define PUD_ORDER		aieeee_attempt_to_allocate_pud
+ #define PMD_ORDER		0
+ #define PTE_ORDER		0
+ #endif
+ #ifdef CONFIG_PAGE_SIZE_16KB
+ #define PGD_ORDER		0
++#define PUD_ORDER		aieeee_attempt_to_allocate_pud
+ #define PMD_ORDER		0
+ #define PTE_ORDER		0
+ #endif
+ #ifdef CONFIG_PAGE_SIZE_64KB
+ #define PGD_ORDER		0
++#define PUD_ORDER		aieeee_attempt_to_allocate_pud
+ #define PMD_ORDER		0
+ #define PTE_ORDER		0
+ #endif
+@@ -91,7 +97,7 @@
+ #define USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
+ #define FIRST_USER_ADDRESS	0
+ 
+-#define VMALLOC_START		XKSEG
++#define VMALLOC_START		MAP_BASE
+ #define VMALLOC_END	\
+ 	(VMALLOC_START + PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE)
+ 
+@@ -102,13 +108,13 @@
+ #define pgd_ERROR(e) \
+ 	printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
+ 
+-extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
+-extern pte_t empty_bad_page_table[PAGE_SIZE/sizeof(pte_t)];
+-extern pmd_t invalid_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];
+-extern pmd_t empty_bad_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];
++extern pte_t invalid_pte_table[PTRS_PER_PTE];
++extern pte_t empty_bad_page_table[PTRS_PER_PTE];
++extern pmd_t invalid_pmd_table[PTRS_PER_PMD];
++extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];
+ 
+ /*
+- * Empty pmd entries point to the invalid_pte_table.
++ * Empty pgd/pmd entries point to the invalid_pte_table.
+  */
+ static inline int pmd_none(pmd_t pmd)
+ {
+@@ -128,26 +134,30 @@ static inline void pmd_clear(pmd_t *pmdp
+ }
+ 
+ /*
+- * Empty pgd entries point to the invalid_pmd_table.
++ * Empty pud entries point to the invalid_pmd_table.
+  */
+-static inline int pgd_none(pgd_t pgd)
++static inline int pud_none(pud_t pud)
+ {
+-	return pgd_val(pgd) == (unsigned long) invalid_pmd_table;
++	return pud_val(pud) == (unsigned long) invalid_pmd_table;
+ }
+ 
+-#define pgd_bad(pgd)		(pgd_val(pgd) &~ PAGE_MASK)
++static inline int pud_bad(pud_t pud)
++{
++	return pud_val(pud) & ~PAGE_MASK;
++}
+ 
+-static inline int pgd_present(pgd_t pgd)
++static inline int pud_present(pud_t pud)
+ {
+-	return pgd_val(pgd) != (unsigned long) invalid_pmd_table;
++	return pud_val(pud) != (unsigned long) invalid_pmd_table;
+ }
+ 
+-static inline void pgd_clear(pgd_t *pgdp)
++static inline void pud_clear(pud_t *pudp)
+ {
+-	pgd_val(*pgdp) = ((unsigned long) invalid_pmd_table);
++	pud_val(*pudp) = ((unsigned long) invalid_pmd_table);
+ }
+ 
+-#define pte_page(x)		pfn_to_page((unsigned long)((pte_val(x) >> PAGE_SHIFT)))
++#define pte_page(x)		pfn_to_page(pte_pfn(x))
++
+ #ifdef CONFIG_CPU_VR41XX
+ #define pte_pfn(x)		((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
+ #define pfn_pte(pfn, prot)	__pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
+@@ -157,26 +167,27 @@ static inline void pgd_clear(pgd_t *pgdp
+ #endif
+ 
+ #define __pgd_offset(address)	pgd_index(address)
+-#define page_pte(page) page_pte_prot(page, __pgprot(0))
++#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
++#define __pmd_offset(address)	pmd_index(address)
+ 
+ /* to find an entry in a kernel page-table-directory */
+ #define pgd_offset_k(address) pgd_offset(&init_mm, 0)
+ 
+-#define pgd_index(address)		((address) >> PGDIR_SHIFT)
++#define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
++#define pmd_index(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+ 
+ /* to find an entry in a page-table-directory */
+ #define pgd_offset(mm,addr)	((mm)->pgd + pgd_index(addr))
+ 
+-static inline unsigned long pgd_page(pgd_t pgd)
++static inline unsigned long pud_page(pud_t pud)
+ {
+-	return pgd_val(pgd);
++	return pud_val(pud);
+ }
+ 
+ /* Find an entry in the second-level page table.. */
+-static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
++static inline pmd_t *pmd_offset(pud_t * pud, unsigned long address)
+ {
+-	return (pmd_t *) pgd_page(*dir) +
+-	       ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
++	return (pmd_t *) pud_page(*pud) + pmd_index(address);
+ }
+ 
+ /* Find an entry in the third-level page table.. */
+diff --git a/include/asm-mips/pgtable-bits.h b/include/asm-mips/pgtable-bits.h
+--- a/include/asm-mips/pgtable-bits.h
++++ b/include/asm-mips/pgtable-bits.h
+@@ -33,7 +33,7 @@
+  * unpredictable things.  The code (when it is written) to deal with
+  * this problem will be in the update_mmu_cache() code for the r4k.
+  */
+-#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
++#if defined(CONFIG_CPU_MIPS32_R1) && defined(CONFIG_64BIT_PHYS_ADDR)
+ 
+ #define _PAGE_PRESENT               (1<<6)  /* implemented in software */
+ #define _PAGE_READ                  (1<<7)  /* implemented in software */
+@@ -123,7 +123,7 @@
+ 
+ #endif
+ #endif
+-#endif /* defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR) */
++#endif /* defined(CONFIG_CPU_MIPS32_R1) && defined(CONFIG_64BIT_PHYS_ADDR) */
+ 
+ #define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
+ #define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
+@@ -140,7 +140,7 @@
+ #define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_COW
+ #endif
+ 
+-#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
++#if defined(CONFIG_CPU_MIPS32_R1) && defined(CONFIG_64BIT_PHYS_ADDR)
+ #define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 3)
+ #else
+ #define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 9)
+diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
+--- a/include/asm-mips/pgtable.h
++++ b/include/asm-mips/pgtable.h
+@@ -8,8 +8,6 @@
+ #ifndef _ASM_PGTABLE_H
+ #define _ASM_PGTABLE_H
+ 
+-#include <asm-generic/4level-fixup.h>
+-
+ #include <linux/config.h>
+ #ifdef CONFIG_32BIT
+ #include <asm/pgtable-32.h>
+@@ -18,6 +16,7 @@
+ #include <asm/pgtable-64.h>
+ #endif
+ 
++#include <asm/io.h>
+ #include <asm/pgtable-bits.h>
+ 
+ #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
+@@ -76,7 +75,6 @@ extern void paging_init(void);
+  * Conversion functions: convert a page and protection to a page entry,
+  * and a page entry and page directory to the page they refer to.
+  */
+-#define page_pte(page)		page_pte_prot(page, __pgprot(0))
+ #define pmd_phys(pmd)		(pmd_val(pmd) - PAGE_OFFSET)
+ #define pmd_page(pmd)		(pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
+ #define pmd_page_kernel(pmd)	pmd_val(pmd)
+@@ -84,7 +82,7 @@ extern void paging_init(void);
+ #define pte_none(pte)		(!(pte_val(pte) & ~_PAGE_GLOBAL))
+ #define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
+ 
+-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
++#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+ static inline void set_pte(pte_t *ptep, pte_t pte)
+ {
+ 	ptep->pte_high = pte.pte_high;
+@@ -148,11 +146,18 @@ static inline void pte_clear(struct mm_s
+ #endif
+ 
+ /*
+- * (pmds are folded into pgds so this doesn't get actually called,
++ * (pmds are folded into puds so this doesn't get actually called,
+  * but the define is needed for a generic inline function.)
+  */
+ #define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0)
+-#define set_pgd(pgdptr, pgdval) do { *(pgdptr) = (pgdval); } while(0)
++
++#ifdef CONFIG_64BIT
++/*
++ * (puds are folded into pgds so this doesn't get actually called,
++ * but the define is needed for a generic inline function.)
++ */
++#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)
++#endif
+ 
+ #define PGD_T_LOG2	ffz(~sizeof(pgd_t))
+ #define PMD_T_LOG2	ffz(~sizeof(pmd_t))
+@@ -165,7 +170,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD
+  * Undefined behaviour if not..
+  */
+ static inline int pte_user(pte_t pte)	{ BUG(); return 0; }
+-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
++#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+ static inline int pte_read(pte_t pte)	{ return (pte).pte_low & _PAGE_READ; }
+ static inline int pte_write(pte_t pte)	{ return (pte).pte_low & _PAGE_WRITE; }
+ static inline int pte_dirty(pte_t pte)	{ return (pte).pte_low & _PAGE_MODIFIED; }
+@@ -324,7 +329,7 @@ static inline pgprot_t pgprot_noncached(
+  */
+ #define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
+ 
+-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
++#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ {
+ 	pte.pte_low &= _PAGE_CHG_MASK;
+@@ -357,7 +362,6 @@ static inline void update_mmu_cache(stru
+ #endif
+ 
+ #ifdef CONFIG_64BIT_PHYS_ADDR
+-extern phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size);
+ extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
+ 
+ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+@@ -367,7 +371,7 @@ static inline int io_remap_pfn_range(str
+ 		pgprot_t prot)
+ {
+ 	phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
+-	return remap_pfn_range(vma, vaddr, pfn, size, prot);
++	return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
+ }
+ #else
+ #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
+diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h
+--- a/include/asm-mips/processor.h
++++ b/include/asm-mips/processor.h
+@@ -96,12 +96,26 @@ union mips_fpu_union {
+ 	{{0,},} \
+ }
+ 
++#define NUM_DSP_REGS   6
++
++typedef __u32 dspreg_t;
++
++struct mips_dsp_state {
++	dspreg_t        dspr[NUM_DSP_REGS];
++	unsigned int    dspcontrol;
++	unsigned short	used_dsp;
++};
++
++#define INIT_DSP {{0,},}
++
+ typedef struct {
+ 	unsigned long seg;
+ } mm_segment_t;
+ 
+ #define ARCH_MIN_TASKALIGN	8
+ 
++struct mips_abi;
++
+ /*
+  * If you change thread_struct remember to change the #defines below too!
+  */
+@@ -117,6 +131,9 @@ struct thread_struct {
+ 	/* Saved fpu/fpu emulator stuff. */
+ 	union mips_fpu_union fpu;
+ 
++	/* Saved state of the DSP ASE, if available. */
++	struct mips_dsp_state dsp;
++
+ 	/* Other stuff associated with the thread. */
+ 	unsigned long cp0_badvaddr;	/* Last user fault */
+ 	unsigned long cp0_baduaddr;	/* Last kernel fault accessing USEG */
+@@ -129,6 +146,7 @@ struct thread_struct {
+ 	unsigned long mflags;
+ 	unsigned long irix_trampoline;  /* Wheee... */
+ 	unsigned long irix_oldctx;
++	struct mips_abi *abi;
+ };
+ 
+ #define MF_ABI_MASK	(MF_32BIT_REGS | MF_32BIT_ADDR)
+@@ -151,6 +169,10 @@ struct thread_struct {
+ 	 */ \
+ 	INIT_FPU, \
+ 	/* \
++	 * saved dsp/dsp emulator stuff \
++	 */ \
++	INIT_DSP, \
++	/* \
+ 	 * Other stuff associated with the process \
+ 	 */ \
+ 	0, 0, 0, 0, \
+diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
+--- a/include/asm-mips/ptrace.h
++++ b/include/asm-mips/ptrace.h
+@@ -22,6 +22,8 @@
+ #define MMLO		68
+ #define FPC_CSR		69
+ #define FPC_EIR		70
++#define DSP_BASE	71		/* 3 more hi / lo register pairs */
++#define DSP_CONTROL	77
+ 
+ /*
+  * This struct defines the way the registers are stored on the stack during a
+@@ -38,18 +40,18 @@ struct pt_regs {
+ 
+ 	/* Saved special registers. */
+ 	unsigned long cp0_status;
+-	unsigned long lo;
+ 	unsigned long hi;
++	unsigned long lo;
+ 	unsigned long cp0_badvaddr;
+ 	unsigned long cp0_cause;
+ 	unsigned long cp0_epc;
+ };
+ 
+ /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+-/* #define PTRACE_GETREGS		12 */
+-/* #define PTRACE_SETREGS		13 */
+-/* #define PTRACE_GETFPREGS		14 */
+-/* #define PTRACE_SETFPREGS		15 */
++#define PTRACE_GETREGS		12
++#define PTRACE_SETREGS		13
++#define PTRACE_GETFPREGS		14
++#define PTRACE_SETFPREGS		15
+ /* #define PTRACE_GETFPXREGS		18 */
+ /* #define PTRACE_SETFPXREGS		19 */
+ 
+@@ -58,6 +60,13 @@ struct pt_regs {
+ #define PTRACE_GET_THREAD_AREA	25
+ #define PTRACE_SET_THREAD_AREA	26
+ 
++/* Calls to trace a 64bit program from a 32bit program.  */
++#define PTRACE_PEEKTEXT_3264	0xc0
++#define PTRACE_PEEKDATA_3264	0xc1
++#define PTRACE_POKETEXT_3264	0xc2
++#define PTRACE_POKEDATA_3264	0xc3
++#define PTRACE_GET_THREAD_AREA_3264	0xc4
++
+ #ifdef __KERNEL__
+ 
+ #include <linux/linkage.h>
+diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
+--- a/include/asm-mips/r4kcache.h
++++ b/include/asm-mips/r4kcache.h
+@@ -21,7 +21,7 @@
+  *
+  *  - The MIPS32 and MIPS64 specs permit an implementation to directly derive
+  *    the index bits from the virtual address.  This breaks with tradition
+- *    set by the R4000.  To keep unpleassant surprises from happening we pick
++ *    set by the R4000.  To keep unpleasant surprises from happening we pick
+  *    an address in KSEG0 / CKSEG0.
+  *  - We need a properly sign extended address for 64-bit code.  To get away
+  *    without ifdefs we let the compiler do it by a type cast.
+@@ -30,11 +30,11 @@
+ 
+ #define cache_op(op,addr)						\
+ 	__asm__ __volatile__(						\
++	"	.set	push					\n"	\
+ 	"	.set	noreorder				\n"	\
+ 	"	.set	mips3\n\t				\n"	\
+ 	"	cache	%0, %1					\n"	\
+-	"	.set	mips0					\n"	\
+-	"	.set	reorder"					\
++	"	.set	pop					\n"	\
+ 	:								\
+ 	: "i" (op), "m" (*(unsigned char *)(addr)))
+ 
+@@ -84,14 +84,14 @@ static inline void flush_scache_line(uns
+ static inline void protected_flush_icache_line(unsigned long addr)
+ {
+ 	__asm__ __volatile__(
+-		".set noreorder\n\t"
+-		".set mips3\n"
+-		"1:\tcache %0,(%1)\n"
+-		"2:\t.set mips0\n\t"
+-		".set reorder\n\t"
+-		".section\t__ex_table,\"a\"\n\t"
+-		STR(PTR)"\t1b,2b\n\t"
+-		".previous"
++		"	.set	push			\n"
++		"	.set	noreorder		\n"
++		"	.set	mips3			\n"
++		"1:	cache	%0, (%1)		\n"
++		"2:	.set	pop			\n"
++		"	.section __ex_table,\"a\"	\n"
++		"	"STR(PTR)" 1b, 2b		\n"
++		"	.previous"
+ 		:
+ 		: "i" (Hit_Invalidate_I), "r" (addr));
+ }
+@@ -100,19 +100,19 @@ static inline void protected_flush_icach
+  * R10000 / R12000 hazard - these processors don't support the Hit_Writeback_D
+  * cacheop so we use Hit_Writeback_Inv_D which is supported by all R4000-style
+  * caches.  We're talking about one cacheline unnecessarily getting invalidated
+- * here so the penaltiy isn't overly hard.
++ * here so the penalty isn't overly hard.
+  */
+ static inline void protected_writeback_dcache_line(unsigned long addr)
+ {
+ 	__asm__ __volatile__(
+-		".set noreorder\n\t"
+-		".set mips3\n"
+-		"1:\tcache %0,(%1)\n"
+-		"2:\t.set mips0\n\t"
+-		".set reorder\n\t"
+-		".section\t__ex_table,\"a\"\n\t"
+-		STR(PTR)"\t1b,2b\n\t"
+-		".previous"
++		"	.set	push			\n"
++		"	.set	noreorder		\n"
++		"	.set	mips3			\n"
++		"1:	cache	%0, (%1)		\n"
++		"2:	.set	pop			\n"
++		"	.section __ex_table,\"a\"	\n"
++		"	"STR(PTR)" 1b, 2b		\n"
++		"	.previous"
+ 		:
+ 		: "i" (Hit_Writeback_Inv_D), "r" (addr));
+ }
+@@ -120,14 +120,14 @@ static inline void protected_writeback_d
+ static inline void protected_writeback_scache_line(unsigned long addr)
+ {
+ 	__asm__ __volatile__(
+-		".set noreorder\n\t"
+-		".set mips3\n"
+-		"1:\tcache %0,(%1)\n"
+-		"2:\t.set mips0\n\t"
+-		".set reorder\n\t"
+-		".section\t__ex_table,\"a\"\n\t"
+-		STR(PTR)"\t1b,2b\n\t"
+-		".previous"
++		"	.set	push			\n"
++		"	.set	noreorder		\n"
++		"	.set	mips3			\n"
++		"1:	cache	%0, (%1)		\n"
++		"2:	.set	pop			\n"
++		"	.section __ex_table,\"a\"	\n"
++		"	"STR(PTR)" 1b, 2b		\n"
++		"	.previous"
+ 		:
+ 		: "i" (Hit_Writeback_Inv_SD), "r" (addr));
+ }
+@@ -142,6 +142,7 @@ static inline void invalidate_tcache_pag
+ 
+ #define cache16_unroll32(base,op)					\
+ 	__asm__ __volatile__(						\
++	"	.set push					\n"	\
+ 	"	.set noreorder					\n"	\
+ 	"	.set mips3					\n"	\
+ 	"	cache %1, 0x000(%0); cache %1, 0x010(%0)	\n"	\
+@@ -160,8 +161,7 @@ static inline void invalidate_tcache_pag
+ 	"	cache %1, 0x1a0(%0); cache %1, 0x1b0(%0)	\n"	\
+ 	"	cache %1, 0x1c0(%0); cache %1, 0x1d0(%0)	\n"	\
+ 	"	cache %1, 0x1e0(%0); cache %1, 0x1f0(%0)	\n"	\
+-	"	.set mips0					\n"	\
+-	"	.set reorder					\n"	\
++	"	.set pop					\n"	\
+ 		:							\
+ 		: "r" (base),						\
+ 		  "i" (op));
+@@ -285,6 +285,7 @@ static inline void blast_scache16_page_i
+ 
+ #define cache32_unroll32(base,op)					\
+ 	__asm__ __volatile__(						\
++	"	.set push					\n"	\
+ 	"	.set noreorder					\n"	\
+ 	"	.set mips3					\n"	\
+ 	"	cache %1, 0x000(%0); cache %1, 0x020(%0)	\n"	\
+@@ -303,8 +304,7 @@ static inline void blast_scache16_page_i
+ 	"	cache %1, 0x340(%0); cache %1, 0x360(%0)	\n"	\
+ 	"	cache %1, 0x380(%0); cache %1, 0x3a0(%0)	\n"	\
+ 	"	cache %1, 0x3c0(%0); cache %1, 0x3e0(%0)	\n"	\
+-	"	.set mips0					\n"	\
+-	"	.set reorder					\n"	\
++	"	.set pop					\n"	\
+ 		:							\
+ 		: "r" (base),						\
+ 		  "i" (op));
+@@ -428,6 +428,7 @@ static inline void blast_scache32_page_i
+ 
+ #define cache64_unroll32(base,op)					\
+ 	__asm__ __volatile__(						\
++	"	.set push					\n"	\
+ 	"	.set noreorder					\n"	\
+ 	"	.set mips3					\n"	\
+ 	"	cache %1, 0x000(%0); cache %1, 0x040(%0)	\n"	\
+@@ -446,8 +447,7 @@ static inline void blast_scache32_page_i
+ 	"	cache %1, 0x680(%0); cache %1, 0x6c0(%0)	\n"	\
+ 	"	cache %1, 0x700(%0); cache %1, 0x740(%0)	\n"	\
+ 	"	cache %1, 0x780(%0); cache %1, 0x7c0(%0)	\n"	\
+-	"	.set mips0					\n"	\
+-	"	.set reorder					\n"	\
++	"	.set pop					\n"	\
+ 		:							\
+ 		: "r" (base),						\
+ 		  "i" (op));
+@@ -532,6 +532,7 @@ static inline void blast_scache64_page_i
+ 
+ #define cache128_unroll32(base,op)					\
+ 	__asm__ __volatile__(						\
++	"	.set push					\n"	\
+ 	"	.set noreorder					\n"	\
+ 	"	.set mips3					\n"	\
+ 	"	cache %1, 0x000(%0); cache %1, 0x080(%0)	\n"	\
+@@ -550,8 +551,7 @@ static inline void blast_scache64_page_i
+ 	"	cache %1, 0xd00(%0); cache %1, 0xd80(%0)	\n"	\
+ 	"	cache %1, 0xe00(%0); cache %1, 0xe80(%0)	\n"	\
+ 	"	cache %1, 0xf00(%0); cache %1, 0xf80(%0)	\n"	\
+-	"	.set mips0					\n"	\
+-	"	.set reorder					\n"	\
++	"	.set pop					\n"	\
+ 		:							\
+ 		: "r" (base),						\
+ 		  "i" (op));
+diff --git a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h
+--- a/include/asm-mips/rtc.h
++++ b/include/asm-mips/rtc.h
+@@ -14,7 +14,9 @@
+ 
+ #ifdef __KERNEL__
+ 
++#include <linux/spinlock.h>
+ #include <linux/rtc.h>
++#include <asm/time.h>
+ 
+ #define RTC_PIE 0x40            /* periodic interrupt enable */
+ #define RTC_AIE 0x20            /* alarm interrupt enable */
+@@ -27,11 +29,52 @@
+ #define RTC_24H 0x02            /* 24 hour mode - else hours bit 7 means pm */
+ #define RTC_DST_EN 0x01         /* auto switch DST - works f. USA only */
+ 
+-unsigned int get_rtc_time(struct rtc_time *time);
+-int set_rtc_time(struct rtc_time *time);
+-unsigned int get_rtc_ss(void);
+-int get_rtc_pll(struct rtc_pll_info *pll);
+-int set_rtc_pll(struct rtc_pll_info *pll);
++static DEFINE_SPINLOCK(mips_rtc_lock);
+ 
++static inline unsigned int get_rtc_time(struct rtc_time *time)
++{
++	unsigned long nowtime;
++
++	spin_lock(&mips_rtc_lock);
++	nowtime = rtc_get_time();
++	to_tm(nowtime, time);
++	time->tm_year -= 1900;
++	spin_unlock(&mips_rtc_lock);
++
++	return RTC_24H;
++}
++
++static inline int set_rtc_time(struct rtc_time *time)
++{
++	unsigned long nowtime;
++	int ret;
++
++	spin_lock(&mips_rtc_lock);
++	nowtime = mktime(time->tm_year+1900, time->tm_mon+1,
++			time->tm_mday, time->tm_hour, time->tm_min,
++			time->tm_sec);
++	ret = rtc_set_time(nowtime);
++	spin_unlock(&mips_rtc_lock);
++
++	return ret;
++}
++
++static inline unsigned int get_rtc_ss(void)
++{
++	struct rtc_time h;
++
++	get_rtc_time(&h);
++	return h.tm_sec;
++}
++
++static inline int get_rtc_pll(struct rtc_pll_info *pll)
++{
++	return -EINVAL;
++}
++
++static inline int set_rtc_pll(struct rtc_pll_info *pll)
++{
++	return -EINVAL;
++}
+ #endif
+ #endif
+diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/rtlx.h
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
++ *
++ */
++
++#ifndef _RTLX_H
++#define _RTLX_H_
++
++#define LX_NODE_BASE 10
++
++#define MIPSCPU_INT_BASE       16
++#define MIPS_CPU_RTLX_IRQ 0
++
++#define RTLX_VERSION 1
++#define RTLX_xID 0x12345600
++#define RTLX_ID (RTLX_xID | RTLX_VERSION)
++#define RTLX_CHANNELS 8
++
++enum rtlx_state {
++	RTLX_STATE_UNUSED = 0,
++	RTLX_STATE_INITIALISED,
++	RTLX_STATE_REMOTE_READY,
++	RTLX_STATE_OPENED
++};
++
++#define RTLX_BUFFER_SIZE 1024
++/* each channel supports read and write.
++   linux (vpe0) reads lx_buffer  and writes rt_buffer
++   SP (vpe1) reads rt_buffer and writes lx_buffer
++*/
++typedef struct rtlx_channel {
++	enum rtlx_state rt_state;
++	enum rtlx_state lx_state;
++
++	int buffer_size;
++
++	/* read and write indexes per buffer */
++	int rt_write, rt_read;
++	char *rt_buffer;
++
++	int lx_write, lx_read;
++	char *lx_buffer;
++
++	void *queues;
++
++} rtlx_channel_t;
++
++typedef struct rtlx_info {
++	unsigned long id;
++	enum rtlx_state state;
++
++	struct rtlx_channel channel[RTLX_CHANNELS];
++
++} rtlx_info_t;
++
++#endif
+diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h
+--- a/include/asm-mips/semaphore.h
++++ b/include/asm-mips/semaphore.h
+@@ -45,9 +45,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name, 1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name, count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
+--- a/include/asm-mips/serial.h
++++ b/include/asm-mips/serial.h
+@@ -52,16 +52,6 @@
+ #define JAZZ_SERIAL_PORT_DEFNS
+ #endif
+ 
+-#ifdef CONFIG_MIPS_COBALT
+-#include <asm/cobalt/cobalt.h>
+-#define COBALT_BASE_BAUD  (18432000 / 16)
+-#define COBALT_SERIAL_PORT_DEFNS		\
+-	/* UART CLK   PORT  IRQ  FLAGS    */ 		\
+-	{ 0, COBALT_BASE_BAUD, 0xc800000, COBALT_SERIAL_IRQ, STD_COM_FLAGS },   /* ttyS0 */
+-#else
+-#define COBALT_SERIAL_PORT_DEFNS
+-#endif
+-
+ /*
+  * Both Galileo boards have the same UART mappings.
+  */
+@@ -113,17 +103,6 @@
+ #define IVR_SERIAL_PORT_DEFNS
+ #endif
+ 
+-#ifdef CONFIG_TOSHIBA_JMR3927
+-#include <asm/jmr3927/jmr3927.h>
+-#define TXX927_SERIAL_PORT_DEFNS                              \
+-    { .baud_base = JMR3927_BASE_BAUD, .port = UART0_ADDR, .irq = UART0_INT,  \
+-      .flags = UART0_FLAGS, .type = 1 },                        \
+-    { .baud_base = JMR3927_BASE_BAUD, .port = UART1_ADDR, .irq = UART1_INT,  \
+-      .flags = UART1_FLAGS, .type = 1 },
+-#else
+-#define TXX927_SERIAL_PORT_DEFNS
+-#endif
+-
+ #ifdef CONFIG_SERIAL_AU1X00
+ #include <asm/mach-au1x00/au1000.h>
+ #ifdef CONFIG_SOC_AU1000
+@@ -227,9 +206,9 @@
+ #define JAGUAR_ATX_SERIAL1_BASE	0xfd000023L
+ 
+ #define _JAGUAR_ATX_SERIAL_INIT(int, base)				\
+-	{ baud_base: JAGUAR_ATX_BASE_BAUD, irq: int,			\
+-	  flags: (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),		\
+-	  iomem_base: (u8 *) base, iomem_reg_shift: 2,			\
++	{ .baud_base = JAGUAR_ATX_BASE_BAUD, irq: int,			\
++	  .flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),		\
++	  .iomem_base = (u8 *) base, iomem_reg_shift: 2,			\
+ 	  io_type: SERIAL_IO_MEM }
+ #define MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS				\
+ 	_JAGUAR_ATX_SERIAL_INIT(JAGUAR_ATX_SERIAL1_IRQ, JAGUAR_ATX_SERIAL1_BASE)
+@@ -243,9 +222,9 @@
+ #define OCELOT_3_SERIAL_BASE	(signed)0xfd000020
+ 
+ #define _OCELOT_3_SERIAL_INIT(int, base)				\
+-	{ baud_base: OCELOT_3_BASE_BAUD, irq: int, 			\
+-	  flags: STD_COM_FLAGS,						\
+-	  iomem_base: (u8 *) base, iomem_reg_shift: 2,			\
++	{ .baud_base = OCELOT_3_BASE_BAUD, irq: int, 			\
++	  .flags = STD_COM_FLAGS,						\
++	  .iomem_base = (u8 *) base, iomem_reg_shift: 2,			\
+ 	  io_type: SERIAL_IO_MEM }
+ 
+ #define MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS				\
+@@ -342,7 +321,6 @@
+ #endif /* CONFIG_SGI_IP32 */
+ 
+ #define SERIAL_PORT_DFNS				\
+-	COBALT_SERIAL_PORT_DEFNS			\
+ 	DDB5477_SERIAL_PORT_DEFNS			\
+ 	EV96100_SERIAL_PORT_DEFNS			\
+ 	IP32_SERIAL_PORT_DEFNS                          \
+@@ -354,7 +332,6 @@
+ 	MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS		\
+ 	MOMENCO_OCELOT_SERIAL_PORT_DEFNS		\
+ 	MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS		\
+-	TXX927_SERIAL_PORT_DEFNS                        \
+ 	AU1000_SERIAL_PORT_DEFNS
+ 
+ #endif /* _ASM_SERIAL_H */
+diff --git a/include/asm-mips/sgi/hpc3.h b/include/asm-mips/sgi/hpc3.h
+--- a/include/asm-mips/sgi/hpc3.h
++++ b/include/asm-mips/sgi/hpc3.h
+@@ -128,26 +128,26 @@ struct hpc3_ethregs {
+ 	volatile u32 rx_gfptr;	/* current GIO fifo ptr */
+ 	volatile u32 rx_dfptr;	/* current device fifo ptr */
+ 	u32 _unused1;		/* padding */
+-	volatile u32 rx_reset;	/* reset register */
+-#define HPC3_ERXRST_CRESET 0x1	/* Reset dma channel and external controller */
+-#define HPC3_ERXRST_CLRIRQ 0x2	/* Clear channel interrupt */
+-#define HPC3_ERXRST_LBACK  0x4	/* Enable diagnostic loopback mode of Seeq8003 */
+-
+-	volatile u32 rx_dconfig;	/* DMA configuration register */
+-#define HPC3_ERXDCFG_D1    0x0000f /* Cycles to spend in D1 state for PIO */
+-#define HPC3_ERXDCFG_D2    0x000f0 /* Cycles to spend in D2 state for PIO */
+-#define HPC3_ERXDCFG_D3    0x00f00 /* Cycles to spend in D3 state for PIO */
+-#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
+-#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
+-#define HPC3_ERXDCFG_FEOP  0x04000 /* Bad packet marker timeout enable */
+-#define HPC3_ERXDCFG_FIRQ  0x08000 /* Another bad packet timeout enable */
+-#define HPC3_ERXDCFG_PTO   0x30000 /* Programmed timeout value for above two */
+-
+-	volatile u32 rx_pconfig;	/* PIO configuration register */
+-#define HPC3_ERXPCFG_P1    0x000f /* Cycles to spend in P1 state for PIO */
+-#define HPC3_ERXPCFG_P2    0x00f0 /* Cycles to spend in P2 state for PIO */
+-#define HPC3_ERXPCFG_P3    0x0f00 /* Cycles to spend in P3 state for PIO */
+-#define HPC3_ERXPCFG_TST   0x1000 /* Diagnistic ram test feature bit */
++	volatile u32 reset;	/* reset register */
++#define HPC3_ERST_CRESET 0x1	/* Reset dma channel and external controller */
++#define HPC3_ERST_CLRIRQ 0x2	/* Clear channel interrupt */
++#define HPC3_ERST_LBACK  0x4	/* Enable diagnostic loopback mode of Seeq8003 */
++
++	volatile u32 dconfig;    /* DMA configuration register */
++#define HPC3_EDCFG_D1    0x0000f /* Cycles to spend in D1 state for PIO */
++#define HPC3_EDCFG_D2    0x000f0 /* Cycles to spend in D2 state for PIO */
++#define HPC3_EDCFG_D3    0x00f00 /* Cycles to spend in D3 state for PIO */
++#define HPC3_EDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
++#define HPC3_EDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
++#define HPC3_EDCFG_FEOP  0x04000 /* Bad packet marker timeout enable */
++#define HPC3_EDCFG_FIRQ  0x08000 /* Another bad packet timeout enable */
++#define HPC3_EDCFG_PTO   0x30000 /* Programmed timeout value for above two */
++
++	volatile u32 pconfig;   /* PIO configuration register */
++#define HPC3_EPCFG_P1    0x000f /* Cycles to spend in P1 state for PIO */
++#define HPC3_EPCFG_P2    0x00f0 /* Cycles to spend in P2 state for PIO */
++#define HPC3_EPCFG_P3    0x0f00 /* Cycles to spend in P3 state for PIO */
++#define HPC3_EPCFG_TST   0x1000 /* Diagnistic ram test feature bit */
+ 
+ 	u32 _unused2[0x1000/4 - 8];	/* padding */
+ 
+diff --git a/include/asm-mips/sibyte/bcm1480_int.h b/include/asm-mips/sibyte/bcm1480_int.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/sibyte/bcm1480_int.h
+@@ -0,0 +1,310 @@
++/*  *********************************************************************
++    *  BCM1280/BCM1480 Board Support Package
++    *
++    *  Interrupt Mapper definitions		File: bcm1480_int.h
++    *
++    *  This module contains constants for manipulating the
++    *  BCM1255/BCM1280/BCM1455/BCM1480's interrupt mapper and
++    *  definitions for the interrupt sources.
++    *
++    *  BCM1480 specification level: 1X55_1X80-UM100-D4 (11/24/03)
++    *
++    *********************************************************************
++    *
++    *  Copyright 2000,2001,2002,2003
++    *  Broadcom 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
++    ********************************************************************* */
++
++
++#ifndef _BCM1480_INT_H
++#define _BCM1480_INT_H
++
++#include "sb1250_defs.h"
++
++/*  *********************************************************************
++    *  Interrupt Mapper Constants
++    ********************************************************************* */
++
++/*
++ * The interrupt mapper deals with 128-bit logical registers that are
++ * implemented as pairs of 64-bit registers, with the "low" 64 bits in
++ * a register that has an address 0x1000 higher(!) than the
++ * corresponding "high" register.
++ *
++ * For appropriate registers, bit 0 of the "high" register is a
++ * cascade bit that summarizes (as a bit-OR) the 64 bits of the "low"
++ * register.
++ */
++
++/*
++ * This entire file uses _BCM1480_ in all the symbols because it is
++ * entirely BCM1480 specific.
++ */
++
++/*
++ * Interrupt sources (Table 22)
++ */
++
++#define K_BCM1480_INT_SOURCES               128
++
++#define _BCM1480_INT_HIGH(k)   (k)
++#define _BCM1480_INT_LOW(k)    ((k)+64)
++
++#define K_BCM1480_INT_ADDR_TRAP             _BCM1480_INT_HIGH(1)
++#define K_BCM1480_INT_GPIO_0                _BCM1480_INT_HIGH(4)
++#define K_BCM1480_INT_GPIO_1                _BCM1480_INT_HIGH(5)
++#define K_BCM1480_INT_GPIO_2                _BCM1480_INT_HIGH(6)
++#define K_BCM1480_INT_GPIO_3                _BCM1480_INT_HIGH(7)
++#define K_BCM1480_INT_PCI_INTA              _BCM1480_INT_HIGH(8)
++#define K_BCM1480_INT_PCI_INTB              _BCM1480_INT_HIGH(9)
++#define K_BCM1480_INT_PCI_INTC              _BCM1480_INT_HIGH(10)
++#define K_BCM1480_INT_PCI_INTD              _BCM1480_INT_HIGH(11)
++#define K_BCM1480_INT_CYCLE_CP0             _BCM1480_INT_HIGH(12)
++#define K_BCM1480_INT_CYCLE_CP1             _BCM1480_INT_HIGH(13)
++#define K_BCM1480_INT_CYCLE_CP2             _BCM1480_INT_HIGH(14)
++#define K_BCM1480_INT_CYCLE_CP3             _BCM1480_INT_HIGH(15)
++#define K_BCM1480_INT_TIMER_0               _BCM1480_INT_HIGH(20)
++#define K_BCM1480_INT_TIMER_1               _BCM1480_INT_HIGH(21)
++#define K_BCM1480_INT_TIMER_2               _BCM1480_INT_HIGH(22)
++#define K_BCM1480_INT_TIMER_3               _BCM1480_INT_HIGH(23)
++#define K_BCM1480_INT_DM_CH_0               _BCM1480_INT_HIGH(28)
++#define K_BCM1480_INT_DM_CH_1               _BCM1480_INT_HIGH(29)
++#define K_BCM1480_INT_DM_CH_2               _BCM1480_INT_HIGH(30)
++#define K_BCM1480_INT_DM_CH_3               _BCM1480_INT_HIGH(31)
++#define K_BCM1480_INT_MAC_0                 _BCM1480_INT_HIGH(36)
++#define K_BCM1480_INT_MAC_0_CH1             _BCM1480_INT_HIGH(37)
++#define K_BCM1480_INT_MAC_1                 _BCM1480_INT_HIGH(38)
++#define K_BCM1480_INT_MAC_1_CH1             _BCM1480_INT_HIGH(39)
++#define K_BCM1480_INT_MAC_2                 _BCM1480_INT_HIGH(40)
++#define K_BCM1480_INT_MAC_2_CH1             _BCM1480_INT_HIGH(41)
++#define K_BCM1480_INT_MAC_3                 _BCM1480_INT_HIGH(42)
++#define K_BCM1480_INT_MAC_3_CH1             _BCM1480_INT_HIGH(43)
++#define K_BCM1480_INT_PMI_LOW               _BCM1480_INT_HIGH(52)
++#define K_BCM1480_INT_PMI_HIGH              _BCM1480_INT_HIGH(53)
++#define K_BCM1480_INT_PMO_LOW               _BCM1480_INT_HIGH(54)
++#define K_BCM1480_INT_PMO_HIGH              _BCM1480_INT_HIGH(55)
++#define K_BCM1480_INT_MBOX_0_0              _BCM1480_INT_HIGH(56)
++#define K_BCM1480_INT_MBOX_0_1              _BCM1480_INT_HIGH(57)
++#define K_BCM1480_INT_MBOX_0_2              _BCM1480_INT_HIGH(58)
++#define K_BCM1480_INT_MBOX_0_3              _BCM1480_INT_HIGH(59)
++#define K_BCM1480_INT_MBOX_1_0              _BCM1480_INT_HIGH(60)
++#define K_BCM1480_INT_MBOX_1_1              _BCM1480_INT_HIGH(61)
++#define K_BCM1480_INT_MBOX_1_2              _BCM1480_INT_HIGH(62)
++#define K_BCM1480_INT_MBOX_1_3              _BCM1480_INT_HIGH(63)
++
++#define K_BCM1480_INT_BAD_ECC               _BCM1480_INT_LOW(1)
++#define K_BCM1480_INT_COR_ECC               _BCM1480_INT_LOW(2)
++#define K_BCM1480_INT_IO_BUS                _BCM1480_INT_LOW(3)
++#define K_BCM1480_INT_PERF_CNT              _BCM1480_INT_LOW(4)
++#define K_BCM1480_INT_SW_PERF_CNT           _BCM1480_INT_LOW(5)
++#define K_BCM1480_INT_TRACE_FREEZE          _BCM1480_INT_LOW(6)
++#define K_BCM1480_INT_SW_TRACE_FREEZE       _BCM1480_INT_LOW(7)
++#define K_BCM1480_INT_WATCHDOG_TIMER_0      _BCM1480_INT_LOW(8)
++#define K_BCM1480_INT_WATCHDOG_TIMER_1      _BCM1480_INT_LOW(9)
++#define K_BCM1480_INT_WATCHDOG_TIMER_2      _BCM1480_INT_LOW(10)
++#define K_BCM1480_INT_WATCHDOG_TIMER_3      _BCM1480_INT_LOW(11)
++#define K_BCM1480_INT_PCI_ERROR             _BCM1480_INT_LOW(16)
++#define K_BCM1480_INT_PCI_RESET             _BCM1480_INT_LOW(17)
++#define K_BCM1480_INT_NODE_CONTROLLER       _BCM1480_INT_LOW(18)
++#define K_BCM1480_INT_HOST_BRIDGE           _BCM1480_INT_LOW(19)
++#define K_BCM1480_INT_PORT_0_FATAL          _BCM1480_INT_LOW(20)
++#define K_BCM1480_INT_PORT_0_NONFATAL       _BCM1480_INT_LOW(21)
++#define K_BCM1480_INT_PORT_1_FATAL          _BCM1480_INT_LOW(22)
++#define K_BCM1480_INT_PORT_1_NONFATAL       _BCM1480_INT_LOW(23)
++#define K_BCM1480_INT_PORT_2_FATAL          _BCM1480_INT_LOW(24)
++#define K_BCM1480_INT_PORT_2_NONFATAL       _BCM1480_INT_LOW(25)
++#define K_BCM1480_INT_LDT_SMI               _BCM1480_INT_LOW(32)
++#define K_BCM1480_INT_LDT_NMI               _BCM1480_INT_LOW(33)
++#define K_BCM1480_INT_LDT_INIT              _BCM1480_INT_LOW(34)
++#define K_BCM1480_INT_LDT_STARTUP           _BCM1480_INT_LOW(35)
++#define K_BCM1480_INT_LDT_EXT               _BCM1480_INT_LOW(36)
++#define K_BCM1480_INT_SMB_0                 _BCM1480_INT_LOW(40)
++#define K_BCM1480_INT_SMB_1                 _BCM1480_INT_LOW(41)
++#define K_BCM1480_INT_PCMCIA                _BCM1480_INT_LOW(42)
++#define K_BCM1480_INT_UART_0                _BCM1480_INT_LOW(44)
++#define K_BCM1480_INT_UART_1                _BCM1480_INT_LOW(45)
++#define K_BCM1480_INT_UART_2                _BCM1480_INT_LOW(46)
++#define K_BCM1480_INT_UART_3                _BCM1480_INT_LOW(47)
++#define K_BCM1480_INT_GPIO_4                _BCM1480_INT_LOW(52)
++#define K_BCM1480_INT_GPIO_5                _BCM1480_INT_LOW(53)
++#define K_BCM1480_INT_GPIO_6                _BCM1480_INT_LOW(54)
++#define K_BCM1480_INT_GPIO_7                _BCM1480_INT_LOW(55)
++#define K_BCM1480_INT_GPIO_8                _BCM1480_INT_LOW(56)
++#define K_BCM1480_INT_GPIO_9                _BCM1480_INT_LOW(57)
++#define K_BCM1480_INT_GPIO_10               _BCM1480_INT_LOW(58)
++#define K_BCM1480_INT_GPIO_11               _BCM1480_INT_LOW(59)
++#define K_BCM1480_INT_GPIO_12               _BCM1480_INT_LOW(60)
++#define K_BCM1480_INT_GPIO_13               _BCM1480_INT_LOW(61)
++#define K_BCM1480_INT_GPIO_14               _BCM1480_INT_LOW(62)
++#define K_BCM1480_INT_GPIO_15               _BCM1480_INT_LOW(63)
++
++/*
++ * Mask values for each interrupt
++ */
++
++#define _BCM1480_INT_MASK1(n)               _SB_MAKEMASK1(((n) & 0x3F))
++#define _BCM1480_INT_OFFSET(n)              (((n) & 0x40) << 6)
++
++#define M_BCM1480_INT_CASCADE               _BCM1480_INT_MASK1(_BCM1480_INT_HIGH(0))
++
++#define M_BCM1480_INT_ADDR_TRAP             _BCM1480_INT_MASK1(K_BCM1480_INT_ADDR_TRAP)
++#define M_BCM1480_INT_GPIO_0                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_0)
++#define M_BCM1480_INT_GPIO_1                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_1)
++#define M_BCM1480_INT_GPIO_2                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_2)
++#define M_BCM1480_INT_GPIO_3                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_3)
++#define M_BCM1480_INT_PCI_INTA              _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTA)
++#define M_BCM1480_INT_PCI_INTB              _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTB)
++#define M_BCM1480_INT_PCI_INTC              _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTC)
++#define M_BCM1480_INT_PCI_INTD              _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTD)
++#define M_BCM1480_INT_CYCLE_CP0             _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP0)
++#define M_BCM1480_INT_CYCLE_CP1             _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP1)
++#define M_BCM1480_INT_CYCLE_CP2             _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP2)
++#define M_BCM1480_INT_CYCLE_CP3             _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP3)
++#define M_BCM1480_INT_TIMER_0               _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_0)
++#define M_BCM1480_INT_TIMER_1               _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_1)
++#define M_BCM1480_INT_TIMER_2               _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_2)
++#define M_BCM1480_INT_TIMER_3               _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_3)
++#define M_BCM1480_INT_DM_CH_0               _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_0)
++#define M_BCM1480_INT_DM_CH_1               _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_1)
++#define M_BCM1480_INT_DM_CH_2               _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_2)
++#define M_BCM1480_INT_DM_CH_3               _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_3)
++#define M_BCM1480_INT_MAC_0                 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_0)
++#define M_BCM1480_INT_MAC_0_CH1             _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_0_CH1)
++#define M_BCM1480_INT_MAC_1                 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_1)
++#define M_BCM1480_INT_MAC_1_CH1             _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_1_CH1)
++#define M_BCM1480_INT_MAC_2                 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_2)
++#define M_BCM1480_INT_MAC_2_CH1             _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_2_CH1)
++#define M_BCM1480_INT_MAC_3                 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_3)
++#define M_BCM1480_INT_MAC_3_CH1             _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_3_CH1)
++#define M_BCM1480_INT_PMI_LOW               _BCM1480_INT_MASK1(K_BCM1480_INT_PMI_LOW)
++#define M_BCM1480_INT_PMI_HIGH              _BCM1480_INT_MASK1(K_BCM1480_INT_PMI_HIGH)
++#define M_BCM1480_INT_PMO_LOW               _BCM1480_INT_MASK1(K_BCM1480_INT_PMO_LOW)
++#define M_BCM1480_INT_PMO_HIGH              _BCM1480_INT_MASK1(K_BCM1480_INT_PMO_HIGH)
++#define M_BCM1480_INT_MBOX_0_0              _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_0)
++#define M_BCM1480_INT_MBOX_0_1              _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_1)
++#define M_BCM1480_INT_MBOX_0_2              _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_2)
++#define M_BCM1480_INT_MBOX_0_3              _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_3)
++#define M_BCM1480_INT_MBOX_1_0              _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_0)
++#define M_BCM1480_INT_MBOX_1_1              _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_1)
++#define M_BCM1480_INT_MBOX_1_2              _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_2)
++#define M_BCM1480_INT_MBOX_1_3              _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_3)
++#define M_BCM1480_INT_BAD_ECC               _BCM1480_INT_MASK1(K_BCM1480_INT_BAD_ECC)
++#define M_BCM1480_INT_COR_ECC               _BCM1480_INT_MASK1(K_BCM1480_INT_COR_ECC)
++#define M_BCM1480_INT_IO_BUS                _BCM1480_INT_MASK1(K_BCM1480_INT_IO_BUS)
++#define M_BCM1480_INT_PERF_CNT              _BCM1480_INT_MASK1(K_BCM1480_INT_PERF_CNT)
++#define M_BCM1480_INT_SW_PERF_CNT           _BCM1480_INT_MASK1(K_BCM1480_INT_SW_PERF_CNT)
++#define M_BCM1480_INT_TRACE_FREEZE          _BCM1480_INT_MASK1(K_BCM1480_INT_TRACE_FREEZE)
++#define M_BCM1480_INT_SW_TRACE_FREEZE       _BCM1480_INT_MASK1(K_BCM1480_INT_SW_TRACE_FREEZE)
++#define M_BCM1480_INT_WATCHDOG_TIMER_0      _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_0)
++#define M_BCM1480_INT_WATCHDOG_TIMER_1      _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_1)
++#define M_BCM1480_INT_WATCHDOG_TIMER_2      _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_2)
++#define M_BCM1480_INT_WATCHDOG_TIMER_3      _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_3)
++#define M_BCM1480_INT_PCI_ERROR             _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_ERROR)
++#define M_BCM1480_INT_PCI_RESET             _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_RESET)
++#define M_BCM1480_INT_NODE_CONTROLLER       _BCM1480_INT_MASK1(K_BCM1480_INT_NODE_CONTROLLER)
++#define M_BCM1480_INT_HOST_BRIDGE           _BCM1480_INT_MASK1(K_BCM1480_INT_HOST_BRIDGE)
++#define M_BCM1480_INT_PORT_0_FATAL          _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_0_FATAL)
++#define M_BCM1480_INT_PORT_0_NONFATAL       _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_0_NONFATAL)
++#define M_BCM1480_INT_PORT_1_FATAL          _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_1_FATAL)
++#define M_BCM1480_INT_PORT_1_NONFATAL       _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_1_NONFATAL)
++#define M_BCM1480_INT_PORT_2_FATAL          _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_2_FATAL)
++#define M_BCM1480_INT_PORT_2_NONFATAL       _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_2_NONFATAL)
++#define M_BCM1480_INT_LDT_SMI               _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_SMI)
++#define M_BCM1480_INT_LDT_NMI               _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_NMI)
++#define M_BCM1480_INT_LDT_INIT              _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_INIT)
++#define M_BCM1480_INT_LDT_STARTUP           _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_STARTUP)
++#define M_BCM1480_INT_LDT_EXT               _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_EXT)
++#define M_BCM1480_INT_SMB_0                 _BCM1480_INT_MASK1(K_BCM1480_INT_SMB_0)
++#define M_BCM1480_INT_SMB_1                 _BCM1480_INT_MASK1(K_BCM1480_INT_SMB_1)
++#define M_BCM1480_INT_PCMCIA                _BCM1480_INT_MASK1(K_BCM1480_INT_PCMCIA)
++#define M_BCM1480_INT_UART_0                _BCM1480_INT_MASK1(K_BCM1480_INT_UART_0)
++#define M_BCM1480_INT_UART_1                _BCM1480_INT_MASK1(K_BCM1480_INT_UART_1)
++#define M_BCM1480_INT_UART_2                _BCM1480_INT_MASK1(K_BCM1480_INT_UART_2)
++#define M_BCM1480_INT_UART_3                _BCM1480_INT_MASK1(K_BCM1480_INT_UART_3)
++#define M_BCM1480_INT_GPIO_4                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_4)
++#define M_BCM1480_INT_GPIO_5                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_5)
++#define M_BCM1480_INT_GPIO_6                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_6)
++#define M_BCM1480_INT_GPIO_7                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_7)
++#define M_BCM1480_INT_GPIO_8                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_8)
++#define M_BCM1480_INT_GPIO_9                _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_9)
++#define M_BCM1480_INT_GPIO_10               _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_10)
++#define M_BCM1480_INT_GPIO_11               _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_11)
++#define M_BCM1480_INT_GPIO_12               _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_12)
++#define M_BCM1480_INT_GPIO_13               _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_13)
++#define M_BCM1480_INT_GPIO_14               _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_14)
++#define M_BCM1480_INT_GPIO_15               _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_15)
++
++/*
++ * Interrupt mappings (Table 18)
++ */
++
++#define K_BCM1480_INT_MAP_I0    0		/* interrupt pins on processor */
++#define K_BCM1480_INT_MAP_I1    1
++#define K_BCM1480_INT_MAP_I2    2
++#define K_BCM1480_INT_MAP_I3    3
++#define K_BCM1480_INT_MAP_I4    4
++#define K_BCM1480_INT_MAP_I5    5
++#define K_BCM1480_INT_MAP_NMI   6		/* nonmaskable */
++#define K_BCM1480_INT_MAP_DINT  7		/* debug interrupt */
++
++/*
++ * Interrupt LDT Set Register (Table 19)
++ */
++
++#define S_BCM1480_INT_HT_INTMSG             0
++#define M_BCM1480_INT_HT_INTMSG             _SB_MAKEMASK(3,S_BCM1480_INT_HT_INTMSG)
++#define V_BCM1480_INT_HT_INTMSG(x)          _SB_MAKEVALUE(x,S_BCM1480_INT_HT_INTMSG)
++#define G_BCM1480_INT_HT_INTMSG(x)          _SB_GETVALUE(x,S_BCM1480_INT_HT_INTMSG,M_BCM1480_INT_HT_INTMSG)
++
++#define K_BCM1480_INT_HT_INTMSG_FIXED       0
++#define K_BCM1480_INT_HT_INTMSG_ARBITRATED  1
++#define K_BCM1480_INT_HT_INTMSG_SMI         2
++#define K_BCM1480_INT_HT_INTMSG_NMI         3
++#define K_BCM1480_INT_HT_INTMSG_INIT        4
++#define K_BCM1480_INT_HT_INTMSG_STARTUP     5
++#define K_BCM1480_INT_HT_INTMSG_EXTINT      6
++#define K_BCM1480_INT_HT_INTMSG_RESERVED    7
++
++#define M_BCM1480_INT_HT_TRIGGERMODE        _SB_MAKEMASK1(3)
++#define V_BCM1480_INT_HT_EDGETRIGGER        0
++#define V_BCM1480_INT_HT_LEVELTRIGGER       M_BCM1480_INT_HT_TRIGGERMODE
++
++#define M_BCM1480_INT_HT_DESTMODE           _SB_MAKEMASK1(4)
++#define V_BCM1480_INT_HT_PHYSICALDEST       0
++#define V_BCM1480_INT_HT_LOGICALDEST        M_BCM1480_INT_HT_DESTMODE
++
++#define S_BCM1480_INT_HT_INTDEST            5
++#define M_BCM1480_INT_HT_INTDEST            _SB_MAKEMASK(8,S_BCM1480_INT_HT_INTDEST)
++#define V_BCM1480_INT_HT_INTDEST(x)         _SB_MAKEVALUE(x,S_BCM1480_INT_HT_INTDEST)
++#define G_BCM1480_INT_HT_INTDEST(x)         _SB_GETVALUE(x,S_BCM1480_INT_HT_INTDEST,M_BCM1480_INT_HT_INTDEST)
++
++#define S_BCM1480_INT_HT_VECTOR             13
++#define M_BCM1480_INT_HT_VECTOR             _SB_MAKEMASK(8,S_BCM1480_INT_HT_VECTOR)
++#define V_BCM1480_INT_HT_VECTOR(x)          _SB_MAKEVALUE(x,S_BCM1480_INT_HT_VECTOR)
++#define G_BCM1480_INT_HT_VECTOR(x)          _SB_GETVALUE(x,S_BCM1480_INT_HT_VECTOR,M_BCM1480_INT_HT_VECTOR)
++
++/*
++ * Vector prefix (Table 4-7)
++ */
++
++#define M_BCM1480_HTVECT_RAISE_INTLDT_HIGH  0x00
++#define M_BCM1480_HTVECT_RAISE_MBOX_0       0x40
++#define M_BCM1480_HTVECT_RAISE_INTLDT_LO    0x80
++#define M_BCM1480_HTVECT_RAISE_MBOX_1       0xC0
++
++#endif /* _BCM1480_INT_H */
+diff --git a/include/asm-mips/sibyte/bcm1480_l2c.h b/include/asm-mips/sibyte/bcm1480_l2c.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/sibyte/bcm1480_l2c.h
+@@ -0,0 +1,176 @@
++/*  *********************************************************************
++    *  BCM1280/BCM1480 Board Support Package
++    *
++    *  L2 Cache constants and macros		File: bcm1480_l2c.h
++    *
++    *  This module contains constants useful for manipulating the
++    *  level 2 cache.
++    *
++    *  BCM1400 specification level:  1280-UM100-D2 (11/14/03)
++    *
++    *********************************************************************
++    *
++    *  Copyright 2000,2001,2002,2003
++    *  Broadcom 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
++    ********************************************************************* */
++
++
++#ifndef _BCM1480_L2C_H
++#define _BCM1480_L2C_H
++
++#include "sb1250_defs.h"
++
++/*
++ * Format of level 2 cache management address (Table 55)
++ */
++
++#define S_BCM1480_L2C_MGMT_INDEX            5
++#define M_BCM1480_L2C_MGMT_INDEX            _SB_MAKEMASK(12,S_BCM1480_L2C_MGMT_INDEX)
++#define V_BCM1480_L2C_MGMT_INDEX(x)         _SB_MAKEVALUE(x,S_BCM1480_L2C_MGMT_INDEX)
++#define G_BCM1480_L2C_MGMT_INDEX(x)         _SB_GETVALUE(x,S_BCM1480_L2C_MGMT_INDEX,M_BCM1480_L2C_MGMT_INDEX)
++
++#define S_BCM1480_L2C_MGMT_WAY              17
++#define M_BCM1480_L2C_MGMT_WAY              _SB_MAKEMASK(3,S_BCM1480_L2C_MGMT_WAY)
++#define V_BCM1480_L2C_MGMT_WAY(x)           _SB_MAKEVALUE(x,S_BCM1480_L2C_MGMT_WAY)
++#define G_BCM1480_L2C_MGMT_WAY(x)           _SB_GETVALUE(x,S_BCM1480_L2C_MGMT_WAY,M_BCM1480_L2C_MGMT_WAY)
++
++#define M_BCM1480_L2C_MGMT_DIRTY            _SB_MAKEMASK1(20)
++#define M_BCM1480_L2C_MGMT_VALID            _SB_MAKEMASK1(21)
++
++#define S_BCM1480_L2C_MGMT_ECC_DIAG         22
++#define M_BCM1480_L2C_MGMT_ECC_DIAG         _SB_MAKEMASK(2,S_BCM1480_L2C_MGMT_ECC_DIAG)
++#define V_BCM1480_L2C_MGMT_ECC_DIAG(x)      _SB_MAKEVALUE(x,S_BCM1480_L2C_MGMT_ECC_DIAG)
++#define G_BCM1480_L2C_MGMT_ECC_DIAG(x)      _SB_GETVALUE(x,S_BCM1480_L2C_MGMT_ECC_DIAG,M_BCM1480_L2C_MGMT_ECC_DIAG)
++
++#define A_BCM1480_L2C_MGMT_TAG_BASE         0x00D0000000
++
++#define BCM1480_L2C_ENTRIES_PER_WAY         4096
++#define BCM1480_L2C_NUM_WAYS                8
++
++
++/*
++ * Level 2 Cache Tag register (Table 59)
++ */
++
++#define S_BCM1480_L2C_TAG_MBZ               0
++#define M_BCM1480_L2C_TAG_MBZ               _SB_MAKEMASK(5,S_BCM1480_L2C_TAG_MBZ)
++
++#define S_BCM1480_L2C_TAG_INDEX             5
++#define M_BCM1480_L2C_TAG_INDEX             _SB_MAKEMASK(12,S_BCM1480_L2C_TAG_INDEX)
++#define V_BCM1480_L2C_TAG_INDEX(x)          _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_INDEX)
++#define G_BCM1480_L2C_TAG_INDEX(x)          _SB_GETVALUE(x,S_BCM1480_L2C_TAG_INDEX,M_BCM1480_L2C_TAG_INDEX)
++
++/* Note that index bit 16 is also tag bit 40 */
++#define S_BCM1480_L2C_TAG_TAG               17
++#define M_BCM1480_L2C_TAG_TAG               _SB_MAKEMASK(23,S_BCM1480_L2C_TAG_TAG)
++#define V_BCM1480_L2C_TAG_TAG(x)            _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_TAG)
++#define G_BCM1480_L2C_TAG_TAG(x)            _SB_GETVALUE(x,S_BCM1480_L2C_TAG_TAG,M_BCM1480_L2C_TAG_TAG)
++
++#define S_BCM1480_L2C_TAG_ECC               40
++#define M_BCM1480_L2C_TAG_ECC               _SB_MAKEMASK(6,S_BCM1480_L2C_TAG_ECC)
++#define V_BCM1480_L2C_TAG_ECC(x)            _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_ECC)
++#define G_BCM1480_L2C_TAG_ECC(x)            _SB_GETVALUE(x,S_BCM1480_L2C_TAG_ECC,M_BCM1480_L2C_TAG_ECC)
++
++#define S_BCM1480_L2C_TAG_WAY               46
++#define M_BCM1480_L2C_TAG_WAY               _SB_MAKEMASK(3,S_BCM1480_L2C_TAG_WAY)
++#define V_BCM1480_L2C_TAG_WAY(x)            _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_WAY)
++#define G_BCM1480_L2C_TAG_WAY(x)            _SB_GETVALUE(x,S_BCM1480_L2C_TAG_WAY,M_BCM1480_L2C_TAG_WAY)
++
++#define M_BCM1480_L2C_TAG_DIRTY             _SB_MAKEMASK1(49)
++#define M_BCM1480_L2C_TAG_VALID             _SB_MAKEMASK1(50)
++
++#define S_BCM1480_L2C_DATA_ECC              51
++#define M_BCM1480_L2C_DATA_ECC              _SB_MAKEMASK(10,S_BCM1480_L2C_DATA_ECC)
++#define V_BCM1480_L2C_DATA_ECC(x)           _SB_MAKEVALUE(x,S_BCM1480_L2C_DATA_ECC)
++#define G_BCM1480_L2C_DATA_ECC(x)           _SB_GETVALUE(x,S_BCM1480_L2C_DATA_ECC,M_BCM1480_L2C_DATA_ECC)
++
++
++/*
++ * L2 Misc0 Value Register (Table 60)
++ */
++
++#define S_BCM1480_L2C_MISC0_WAY_REMOTE      0
++#define M_BCM1480_L2C_MISC0_WAY_REMOTE      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC0_WAY_REMOTE)
++#define G_BCM1480_L2C_MISC0_WAY_REMOTE(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_WAY_REMOTE,M_BCM1480_L2C_MISC0_WAY_REMOTE)
++
++#define S_BCM1480_L2C_MISC0_WAY_LOCAL       8
++#define M_BCM1480_L2C_MISC0_WAY_LOCAL       _SB_MAKEMASK(8,S_BCM1480_L2C_MISC0_WAY_LOCAL)
++#define G_BCM1480_L2C_MISC0_WAY_LOCAL(x)    _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_WAY_LOCAL,M_BCM1480_L2C_MISC0_WAY_LOCAL)
++
++#define S_BCM1480_L2C_MISC0_WAY_ENABLE      16
++#define M_BCM1480_L2C_MISC0_WAY_ENABLE      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC0_WAY_ENABLE)
++#define G_BCM1480_L2C_MISC0_WAY_ENABLE(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_WAY_ENABLE,M_BCM1480_L2C_MISC0_WAY_ENABLE)
++
++#define S_BCM1480_L2C_MISC0_CACHE_DISABLE   24
++#define M_BCM1480_L2C_MISC0_CACHE_DISABLE   _SB_MAKEMASK(2,S_BCM1480_L2C_MISC0_CACHE_DISABLE)
++#define G_BCM1480_L2C_MISC0_CACHE_DISABLE(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_CACHE_DISABLE,M_BCM1480_L2C_MISC0_CACHE_DISABLE)
++
++#define S_BCM1480_L2C_MISC0_CACHE_QUAD      26
++#define M_BCM1480_L2C_MISC0_CACHE_QUAD      _SB_MAKEMASK(2,S_BCM1480_L2C_MISC0_CACHE_QUAD)
++#define G_BCM1480_L2C_MISC0_CACHE_QUAD(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_CACHE_QUAD,M_BCM1480_L2C_MISC0_CACHE_QUAD)
++
++#define S_BCM1480_L2C_MISC0_MC_PRIORITY      30
++#define M_BCM1480_L2C_MISC0_MC_PRIORITY      _SB_MAKEMASK1(S_BCM1480_L2C_MISC0_MC_PRIORITY)
++
++#define S_BCM1480_L2C_MISC0_ECC_CLEANUP      31
++#define M_BCM1480_L2C_MISC0_ECC_CLEANUP      _SB_MAKEMASK1(S_BCM1480_L2C_MISC0_ECC_CLEANUP)
++
++
++/*
++ * L2 Misc1 Value Register (Table 60)
++ */
++
++#define S_BCM1480_L2C_MISC1_WAY_AGENT_0      0
++#define M_BCM1480_L2C_MISC1_WAY_AGENT_0      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_0)
++#define G_BCM1480_L2C_MISC1_WAY_AGENT_0(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_0,M_BCM1480_L2C_MISC1_WAY_AGENT_0)
++
++#define S_BCM1480_L2C_MISC1_WAY_AGENT_1      8
++#define M_BCM1480_L2C_MISC1_WAY_AGENT_1      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_1)
++#define G_BCM1480_L2C_MISC1_WAY_AGENT_1(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_1,M_BCM1480_L2C_MISC1_WAY_AGENT_1)
++
++#define S_BCM1480_L2C_MISC1_WAY_AGENT_2      16
++#define M_BCM1480_L2C_MISC1_WAY_AGENT_2      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_2)
++#define G_BCM1480_L2C_MISC1_WAY_AGENT_2(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_2,M_BCM1480_L2C_MISC1_WAY_AGENT_2)
++
++#define S_BCM1480_L2C_MISC1_WAY_AGENT_3      24
++#define M_BCM1480_L2C_MISC1_WAY_AGENT_3      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_3)
++#define G_BCM1480_L2C_MISC1_WAY_AGENT_3(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_3,M_BCM1480_L2C_MISC1_WAY_AGENT_3)
++
++#define S_BCM1480_L2C_MISC1_WAY_AGENT_4      32
++#define M_BCM1480_L2C_MISC1_WAY_AGENT_4      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_4)
++#define G_BCM1480_L2C_MISC1_WAY_AGENT_4(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_4,M_BCM1480_L2C_MISC1_WAY_AGENT_4)
++
++
++/*
++ * L2 Misc2 Value Register (Table 60)
++ */
++
++#define S_BCM1480_L2C_MISC2_WAY_AGENT_8      0
++#define M_BCM1480_L2C_MISC2_WAY_AGENT_8      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC2_WAY_AGENT_8)
++#define G_BCM1480_L2C_MISC2_WAY_AGENT_8(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC2_WAY_AGENT_8,M_BCM1480_L2C_MISC2_WAY_AGENT_8)
++
++#define S_BCM1480_L2C_MISC2_WAY_AGENT_9      8
++#define M_BCM1480_L2C_MISC2_WAY_AGENT_9      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC2_WAY_AGENT_9)
++#define G_BCM1480_L2C_MISC2_WAY_AGENT_9(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC2_WAY_AGENT_9,M_BCM1480_L2C_MISC2_WAY_AGENT_9)
++
++#define S_BCM1480_L2C_MISC2_WAY_AGENT_A      16
++#define M_BCM1480_L2C_MISC2_WAY_AGENT_A      _SB_MAKEMASK(8,S_BCM1480_L2C_MISC2_WAY_AGENT_A)
++#define G_BCM1480_L2C_MISC2_WAY_AGENT_A(x)   _SB_GETVALUE(x,S_BCM1480_L2C_MISC2_WAY_AGENT_A,M_BCM1480_L2C_MISC2_WAY_AGENT_A)
++
++
++#endif /* _BCM1480_L2C_H */
+diff --git a/include/asm-mips/sibyte/bcm1480_mc.h b/include/asm-mips/sibyte/bcm1480_mc.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/sibyte/bcm1480_mc.h
+@@ -0,0 +1,962 @@
++/*  *********************************************************************
++    *  BCM1280/BCM1480 Board Support Package
++    *
++    *  Memory Controller constants              File: bcm1480_mc.h
++    *
++    *  This module contains constants and macros useful for
++    *  programming the memory controller.
++    *
++    *  BCM1400 specification level:  1280-UM100-D1 (11/14/03 Review Copy)
++    *
++    *********************************************************************
++    *
++    *  Copyright 2000,2001,2002,2003
++    *  Broadcom 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
++    ********************************************************************* */
++
++
++#ifndef _BCM1480_MC_H
++#define _BCM1480_MC_H
++
++#include "sb1250_defs.h"
++
++/*
++ * Memory Channel Configuration Register (Table 81)
++ */
++
++#define S_BCM1480_MC_INTLV0                 0
++#define M_BCM1480_MC_INTLV0                 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV0)
++#define V_BCM1480_MC_INTLV0(x)              _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV0)
++#define G_BCM1480_MC_INTLV0(x)              _SB_GETVALUE(x,S_BCM1480_MC_INTLV0,M_BCM1480_MC_INTLV0)
++#define V_BCM1480_MC_INTLV0_DEFAULT         V_BCM1480_MC_INTLV0(0)
++
++#define S_BCM1480_MC_INTLV1                 8
++#define M_BCM1480_MC_INTLV1                 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV1)
++#define V_BCM1480_MC_INTLV1(x)              _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV1)
++#define G_BCM1480_MC_INTLV1(x)              _SB_GETVALUE(x,S_BCM1480_MC_INTLV1,M_BCM1480_MC_INTLV1)
++#define V_BCM1480_MC_INTLV1_DEFAULT         V_BCM1480_MC_INTLV1(0)
++
++#define S_BCM1480_MC_INTLV2                 16
++#define M_BCM1480_MC_INTLV2                 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV2)
++#define V_BCM1480_MC_INTLV2(x)              _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV2)
++#define G_BCM1480_MC_INTLV2(x)              _SB_GETVALUE(x,S_BCM1480_MC_INTLV2,M_BCM1480_MC_INTLV2)
++#define V_BCM1480_MC_INTLV2_DEFAULT         V_BCM1480_MC_INTLV2(0)
++
++#define S_BCM1480_MC_CS_MODE                32
++#define M_BCM1480_MC_CS_MODE                _SB_MAKEMASK(8,S_BCM1480_MC_CS_MODE)
++#define V_BCM1480_MC_CS_MODE(x)             _SB_MAKEVALUE(x,S_BCM1480_MC_CS_MODE)
++#define G_BCM1480_MC_CS_MODE(x)             _SB_GETVALUE(x,S_BCM1480_MC_CS_MODE,M_BCM1480_MC_CS_MODE)
++#define V_BCM1480_MC_CS_MODE_DEFAULT        V_BCM1480_MC_CS_MODE(0)
++
++#define V_BCM1480_MC_CONFIG_DEFAULT         (V_BCM1480_MC_INTLV0_DEFAULT  | \
++                                     V_BCM1480_MC_INTLV1_DEFAULT  | \
++                                     V_BCM1480_MC_INTLV2_DEFAULT  | \
++				     V_BCM1480_MC_CS_MODE_DEFAULT)
++
++#define K_BCM1480_MC_CS01_MODE		    0x03
++#define K_BCM1480_MC_CS02_MODE		    0x05
++#define K_BCM1480_MC_CS0123_MODE	    0x0F
++#define K_BCM1480_MC_CS0246_MODE	    0x55
++#define K_BCM1480_MC_CS0145_MODE	    0x33
++#define K_BCM1480_MC_CS0167_MODE	    0xC3
++#define K_BCM1480_MC_CSFULL_MODE	    0xFF
++
++/*
++ * Chip Select Start Address Register (Table 82)
++ */
++
++#define S_BCM1480_MC_CS0_START              0
++#define M_BCM1480_MC_CS0_START              _SB_MAKEMASK(12,S_BCM1480_MC_CS0_START)
++#define V_BCM1480_MC_CS0_START(x)           _SB_MAKEVALUE(x,S_BCM1480_MC_CS0_START)
++#define G_BCM1480_MC_CS0_START(x)           _SB_GETVALUE(x,S_BCM1480_MC_CS0_START,M_BCM1480_MC_CS0_START)
++
++#define S_BCM1480_MC_CS1_START              16
++#define M_BCM1480_MC_CS1_START              _SB_MAKEMASK(12,S_BCM1480_MC_CS1_START)
++#define V_BCM1480_MC_CS1_START(x)           _SB_MAKEVALUE(x,S_BCM1480_MC_CS1_START)
++#define G_BCM1480_MC_CS1_START(x)           _SB_GETVALUE(x,S_BCM1480_MC_CS1_START,M_BCM1480_MC_CS1_START)
++
++#define S_BCM1480_MC_CS2_START              32
++#define M_BCM1480_MC_CS2_START              _SB_MAKEMASK(12,S_BCM1480_MC_CS2_START)
++#define V_BCM1480_MC_CS2_START(x)           _SB_MAKEVALUE(x,S_BCM1480_MC_CS2_START)
++#define G_BCM1480_MC_CS2_START(x)           _SB_GETVALUE(x,S_BCM1480_MC_CS2_START,M_BCM1480_MC_CS2_START)
++
++#define S_BCM1480_MC_CS3_START              48
++#define M_BCM1480_MC_CS3_START              _SB_MAKEMASK(12,S_BCM1480_MC_CS3_START)
++#define V_BCM1480_MC_CS3_START(x)           _SB_MAKEVALUE(x,S_BCM1480_MC_CS3_START)
++#define G_BCM1480_MC_CS3_START(x)           _SB_GETVALUE(x,S_BCM1480_MC_CS3_START,M_BCM1480_MC_CS3_START)
++
++/*
++ * Chip Select End Address Register (Table 83)
++ */
++
++#define S_BCM1480_MC_CS0_END                0
++#define M_BCM1480_MC_CS0_END                _SB_MAKEMASK(12,S_BCM1480_MC_CS0_END)
++#define V_BCM1480_MC_CS0_END(x)             _SB_MAKEVALUE(x,S_BCM1480_MC_CS0_END)
++#define G_BCM1480_MC_CS0_END(x)             _SB_GETVALUE(x,S_BCM1480_MC_CS0_END,M_BCM1480_MC_CS0_END)
++
++#define S_BCM1480_MC_CS1_END                16
++#define M_BCM1480_MC_CS1_END                _SB_MAKEMASK(12,S_BCM1480_MC_CS1_END)
++#define V_BCM1480_MC_CS1_END(x)             _SB_MAKEVALUE(x,S_BCM1480_MC_CS1_END)
++#define G_BCM1480_MC_CS1_END(x)             _SB_GETVALUE(x,S_BCM1480_MC_CS1_END,M_BCM1480_MC_CS1_END)
++
++#define S_BCM1480_MC_CS2_END                32
++#define M_BCM1480_MC_CS2_END                _SB_MAKEMASK(12,S_BCM1480_MC_CS2_END)
++#define V_BCM1480_MC_CS2_END(x)             _SB_MAKEVALUE(x,S_BCM1480_MC_CS2_END)
++#define G_BCM1480_MC_CS2_END(x)             _SB_GETVALUE(x,S_BCM1480_MC_CS2_END,M_BCM1480_MC_CS2_END)
++
++#define S_BCM1480_MC_CS3_END                48
++#define M_BCM1480_MC_CS3_END                _SB_MAKEMASK(12,S_BCM1480_MC_CS3_END)
++#define V_BCM1480_MC_CS3_END(x)             _SB_MAKEVALUE(x,S_BCM1480_MC_CS3_END)
++#define G_BCM1480_MC_CS3_END(x)             _SB_GETVALUE(x,S_BCM1480_MC_CS3_END,M_BCM1480_MC_CS3_END)
++
++/*
++ * Row Address Bit Select Register 0 (Table 84)
++ */
++
++#define S_BCM1480_MC_ROW00                  0
++#define M_BCM1480_MC_ROW00                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW00)
++#define V_BCM1480_MC_ROW00(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW00)
++#define G_BCM1480_MC_ROW00(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW00,M_BCM1480_MC_ROW00)
++
++#define S_BCM1480_MC_ROW01                  8
++#define M_BCM1480_MC_ROW01                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW01)
++#define V_BCM1480_MC_ROW01(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW01)
++#define G_BCM1480_MC_ROW01(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW01,M_BCM1480_MC_ROW01)
++
++#define S_BCM1480_MC_ROW02                  16
++#define M_BCM1480_MC_ROW02                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW02)
++#define V_BCM1480_MC_ROW02(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW02)
++#define G_BCM1480_MC_ROW02(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW02,M_BCM1480_MC_ROW02)
++
++#define S_BCM1480_MC_ROW03                  24
++#define M_BCM1480_MC_ROW03                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW03)
++#define V_BCM1480_MC_ROW03(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW03)
++#define G_BCM1480_MC_ROW03(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW03,M_BCM1480_MC_ROW03)
++
++#define S_BCM1480_MC_ROW04                  32
++#define M_BCM1480_MC_ROW04                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW04)
++#define V_BCM1480_MC_ROW04(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW04)
++#define G_BCM1480_MC_ROW04(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW04,M_BCM1480_MC_ROW04)
++
++#define S_BCM1480_MC_ROW05                  40
++#define M_BCM1480_MC_ROW05                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW05)
++#define V_BCM1480_MC_ROW05(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW05)
++#define G_BCM1480_MC_ROW05(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW05,M_BCM1480_MC_ROW05)
++
++#define S_BCM1480_MC_ROW06                  48
++#define M_BCM1480_MC_ROW06                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW06)
++#define V_BCM1480_MC_ROW06(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW06)
++#define G_BCM1480_MC_ROW06(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW06,M_BCM1480_MC_ROW06)
++
++#define S_BCM1480_MC_ROW07                  56
++#define M_BCM1480_MC_ROW07                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW07)
++#define V_BCM1480_MC_ROW07(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW07)
++#define G_BCM1480_MC_ROW07(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW07,M_BCM1480_MC_ROW07)
++
++/*
++ * Row Address Bit Select Register 1 (Table 85)
++ */
++
++#define S_BCM1480_MC_ROW08                  0
++#define M_BCM1480_MC_ROW08                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW08)
++#define V_BCM1480_MC_ROW08(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW08)
++#define G_BCM1480_MC_ROW08(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW08,M_BCM1480_MC_ROW08)
++
++#define S_BCM1480_MC_ROW09                  8
++#define M_BCM1480_MC_ROW09                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW09)
++#define V_BCM1480_MC_ROW09(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW09)
++#define G_BCM1480_MC_ROW09(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW09,M_BCM1480_MC_ROW09)
++
++#define S_BCM1480_MC_ROW10                  16
++#define M_BCM1480_MC_ROW10                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW10)
++#define V_BCM1480_MC_ROW10(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW10)
++#define G_BCM1480_MC_ROW10(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW10,M_BCM1480_MC_ROW10)
++
++#define S_BCM1480_MC_ROW11                  24
++#define M_BCM1480_MC_ROW11                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW11)
++#define V_BCM1480_MC_ROW11(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW11)
++#define G_BCM1480_MC_ROW11(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW11,M_BCM1480_MC_ROW11)
++
++#define S_BCM1480_MC_ROW12                  32
++#define M_BCM1480_MC_ROW12                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW12)
++#define V_BCM1480_MC_ROW12(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW12)
++#define G_BCM1480_MC_ROW12(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW12,M_BCM1480_MC_ROW12)
++
++#define S_BCM1480_MC_ROW13                  40
++#define M_BCM1480_MC_ROW13                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW13)
++#define V_BCM1480_MC_ROW13(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW13)
++#define G_BCM1480_MC_ROW13(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW13,M_BCM1480_MC_ROW13)
++
++#define S_BCM1480_MC_ROW14                  48
++#define M_BCM1480_MC_ROW14                  _SB_MAKEMASK(6,S_BCM1480_MC_ROW14)
++#define V_BCM1480_MC_ROW14(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_ROW14)
++#define G_BCM1480_MC_ROW14(x)               _SB_GETVALUE(x,S_BCM1480_MC_ROW14,M_BCM1480_MC_ROW14)
++
++#define K_BCM1480_MC_ROWX_BIT_SPACING  	    8
++
++/*
++ * Column Address Bit Select Register 0 (Table 86)
++ */
++
++#define S_BCM1480_MC_COL00                  0
++#define M_BCM1480_MC_COL00                  _SB_MAKEMASK(6,S_BCM1480_MC_COL00)
++#define V_BCM1480_MC_COL00(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL00)
++#define G_BCM1480_MC_COL00(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL00,M_BCM1480_MC_COL00)
++
++#define S_BCM1480_MC_COL01                  8
++#define M_BCM1480_MC_COL01                  _SB_MAKEMASK(6,S_BCM1480_MC_COL01)
++#define V_BCM1480_MC_COL01(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL01)
++#define G_BCM1480_MC_COL01(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL01,M_BCM1480_MC_COL01)
++
++#define S_BCM1480_MC_COL02                  16
++#define M_BCM1480_MC_COL02                  _SB_MAKEMASK(6,S_BCM1480_MC_COL02)
++#define V_BCM1480_MC_COL02(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL02)
++#define G_BCM1480_MC_COL02(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL02,M_BCM1480_MC_COL02)
++
++#define S_BCM1480_MC_COL03                  24
++#define M_BCM1480_MC_COL03                  _SB_MAKEMASK(6,S_BCM1480_MC_COL03)
++#define V_BCM1480_MC_COL03(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL03)
++#define G_BCM1480_MC_COL03(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL03,M_BCM1480_MC_COL03)
++
++#define S_BCM1480_MC_COL04                  32
++#define M_BCM1480_MC_COL04                  _SB_MAKEMASK(6,S_BCM1480_MC_COL04)
++#define V_BCM1480_MC_COL04(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL04)
++#define G_BCM1480_MC_COL04(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL04,M_BCM1480_MC_COL04)
++
++#define S_BCM1480_MC_COL05                  40
++#define M_BCM1480_MC_COL05                  _SB_MAKEMASK(6,S_BCM1480_MC_COL05)
++#define V_BCM1480_MC_COL05(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL05)
++#define G_BCM1480_MC_COL05(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL05,M_BCM1480_MC_COL05)
++
++#define S_BCM1480_MC_COL06                  48
++#define M_BCM1480_MC_COL06                  _SB_MAKEMASK(6,S_BCM1480_MC_COL06)
++#define V_BCM1480_MC_COL06(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL06)
++#define G_BCM1480_MC_COL06(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL06,M_BCM1480_MC_COL06)
++
++#define S_BCM1480_MC_COL07                  56
++#define M_BCM1480_MC_COL07                  _SB_MAKEMASK(6,S_BCM1480_MC_COL07)
++#define V_BCM1480_MC_COL07(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL07)
++#define G_BCM1480_MC_COL07(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL07,M_BCM1480_MC_COL07)
++
++/*
++ * Column Address Bit Select Register 1 (Table 87)
++ */
++
++#define S_BCM1480_MC_COL08                  0
++#define M_BCM1480_MC_COL08                  _SB_MAKEMASK(6,S_BCM1480_MC_COL08)
++#define V_BCM1480_MC_COL08(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL08)
++#define G_BCM1480_MC_COL08(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL08,M_BCM1480_MC_COL08)
++
++#define S_BCM1480_MC_COL09                  8
++#define M_BCM1480_MC_COL09                  _SB_MAKEMASK(6,S_BCM1480_MC_COL09)
++#define V_BCM1480_MC_COL09(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL09)
++#define G_BCM1480_MC_COL09(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL09,M_BCM1480_MC_COL09)
++
++#define S_BCM1480_MC_COL10                  16   /* not a valid position, must be prog as 0 */
++
++#define S_BCM1480_MC_COL11                  24
++#define M_BCM1480_MC_COL11                  _SB_MAKEMASK(6,S_BCM1480_MC_COL11)
++#define V_BCM1480_MC_COL11(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL11)
++#define G_BCM1480_MC_COL11(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL11,M_BCM1480_MC_COL11)
++
++#define S_BCM1480_MC_COL12                  32
++#define M_BCM1480_MC_COL12                  _SB_MAKEMASK(6,S_BCM1480_MC_COL12)
++#define V_BCM1480_MC_COL12(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL12)
++#define G_BCM1480_MC_COL12(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL12,M_BCM1480_MC_COL12)
++
++#define S_BCM1480_MC_COL13                  40
++#define M_BCM1480_MC_COL13                  _SB_MAKEMASK(6,S_BCM1480_MC_COL13)
++#define V_BCM1480_MC_COL13(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL13)
++#define G_BCM1480_MC_COL13(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL13,M_BCM1480_MC_COL13)
++
++#define S_BCM1480_MC_COL14                  48
++#define M_BCM1480_MC_COL14                  _SB_MAKEMASK(6,S_BCM1480_MC_COL14)
++#define V_BCM1480_MC_COL14(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_COL14)
++#define G_BCM1480_MC_COL14(x)               _SB_GETVALUE(x,S_BCM1480_MC_COL14,M_BCM1480_MC_COL14)
++
++#define K_BCM1480_MC_COLX_BIT_SPACING  	    8
++
++/*
++ * CS0 and CS1 Bank Address Bit Select Register (Table 88)
++ */
++
++#define S_BCM1480_MC_CS01_BANK0             0
++#define M_BCM1480_MC_CS01_BANK0             _SB_MAKEMASK(6,S_BCM1480_MC_CS01_BANK0)
++#define V_BCM1480_MC_CS01_BANK0(x)          _SB_MAKEVALUE(x,S_BCM1480_MC_CS01_BANK0)
++#define G_BCM1480_MC_CS01_BANK0(x)          _SB_GETVALUE(x,S_BCM1480_MC_CS01_BANK0,M_BCM1480_MC_CS01_BANK0)
++
++#define S_BCM1480_MC_CS01_BANK1             8
++#define M_BCM1480_MC_CS01_BANK1             _SB_MAKEMASK(6,S_BCM1480_MC_CS01_BANK1)
++#define V_BCM1480_MC_CS01_BANK1(x)          _SB_MAKEVALUE(x,S_BCM1480_MC_CS01_BANK1)
++#define G_BCM1480_MC_CS01_BANK1(x)          _SB_GETVALUE(x,S_BCM1480_MC_CS01_BANK1,M_BCM1480_MC_CS01_BANK1)
++
++#define S_BCM1480_MC_CS01_BANK2             16
++#define M_BCM1480_MC_CS01_BANK2             _SB_MAKEMASK(6,S_BCM1480_MC_CS01_BANK2)
++#define V_BCM1480_MC_CS01_BANK2(x)          _SB_MAKEVALUE(x,S_BCM1480_MC_CS01_BANK2)
++#define G_BCM1480_MC_CS01_BANK2(x)          _SB_GETVALUE(x,S_BCM1480_MC_CS01_BANK2,M_BCM1480_MC_CS01_BANK2)
++
++/*
++ * CS2 and CS3 Bank Address Bit Select Register (Table 89)
++ */
++
++#define S_BCM1480_MC_CS23_BANK0             0
++#define M_BCM1480_MC_CS23_BANK0             _SB_MAKEMASK(6,S_BCM1480_MC_CS23_BANK0)
++#define V_BCM1480_MC_CS23_BANK0(x)          _SB_MAKEVALUE(x,S_BCM1480_MC_CS23_BANK0)
++#define G_BCM1480_MC_CS23_BANK0(x)          _SB_GETVALUE(x,S_BCM1480_MC_CS23_BANK0,M_BCM1480_MC_CS23_BANK0)
++
++#define S_BCM1480_MC_CS23_BANK1             8
++#define M_BCM1480_MC_CS23_BANK1             _SB_MAKEMASK(6,S_BCM1480_MC_CS23_BANK1)
++#define V_BCM1480_MC_CS23_BANK1(x)          _SB_MAKEVALUE(x,S_BCM1480_MC_CS23_BANK1)
++#define G_BCM1480_MC_CS23_BANK1(x)          _SB_GETVALUE(x,S_BCM1480_MC_CS23_BANK1,M_BCM1480_MC_CS23_BANK1)
++
++#define S_BCM1480_MC_CS23_BANK2             16
++#define M_BCM1480_MC_CS23_BANK2             _SB_MAKEMASK(6,S_BCM1480_MC_CS23_BANK2)
++#define V_BCM1480_MC_CS23_BANK2(x)          _SB_MAKEVALUE(x,S_BCM1480_MC_CS23_BANK2)
++#define G_BCM1480_MC_CS23_BANK2(x)          _SB_GETVALUE(x,S_BCM1480_MC_CS23_BANK2,M_BCM1480_MC_CS23_BANK2)
++
++#define K_BCM1480_MC_CSXX_BANKX_BIT_SPACING  8
++
++/*
++ * DRAM Command Register (Table 90)
++ */
++
++#define S_BCM1480_MC_COMMAND                0
++#define M_BCM1480_MC_COMMAND                _SB_MAKEMASK(4,S_BCM1480_MC_COMMAND)
++#define V_BCM1480_MC_COMMAND(x)             _SB_MAKEVALUE(x,S_BCM1480_MC_COMMAND)
++#define G_BCM1480_MC_COMMAND(x)             _SB_GETVALUE(x,S_BCM1480_MC_COMMAND,M_BCM1480_MC_COMMAND)
++
++#define K_BCM1480_MC_COMMAND_EMRS           0
++#define K_BCM1480_MC_COMMAND_MRS            1
++#define K_BCM1480_MC_COMMAND_PRE            2
++#define K_BCM1480_MC_COMMAND_AR             3
++#define K_BCM1480_MC_COMMAND_SETRFSH        4
++#define K_BCM1480_MC_COMMAND_CLRRFSH        5
++#define K_BCM1480_MC_COMMAND_SETPWRDN       6
++#define K_BCM1480_MC_COMMAND_CLRPWRDN       7
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define K_BCM1480_MC_COMMAND_EMRS2	    8
++#define K_BCM1480_MC_COMMAND_EMRS3	    9
++#define K_BCM1480_MC_COMMAND_ENABLE_MCLK    10
++#define K_BCM1480_MC_COMMAND_DISABLE_MCLK   11
++#endif
++
++#define V_BCM1480_MC_COMMAND_EMRS           V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS)
++#define V_BCM1480_MC_COMMAND_MRS            V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_MRS)
++#define V_BCM1480_MC_COMMAND_PRE            V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_PRE)
++#define V_BCM1480_MC_COMMAND_AR             V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_AR)
++#define V_BCM1480_MC_COMMAND_SETRFSH        V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_SETRFSH)
++#define V_BCM1480_MC_COMMAND_CLRRFSH        V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_CLRRFSH)
++#define V_BCM1480_MC_COMMAND_SETPWRDN       V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_SETPWRDN)
++#define V_BCM1480_MC_COMMAND_CLRPWRDN       V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_CLRPWRDN)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define V_BCM1480_MC_COMMAND_EMRS2          V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS2)
++#define V_BCM1480_MC_COMMAND_EMRS3          V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS3)
++#define V_BCM1480_MC_COMMAND_ENABLE_MCLK    V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_ENABLE_MCLK)
++#define V_BCM1480_MC_COMMAND_DISABLE_MCLK   V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_DISABLE_MCLK)
++#endif
++
++#define S_BCM1480_MC_CS0		    4
++#define M_BCM1480_MC_CS0                    _SB_MAKEMASK1(4)
++#define M_BCM1480_MC_CS1                    _SB_MAKEMASK1(5)
++#define M_BCM1480_MC_CS2                    _SB_MAKEMASK1(6)
++#define M_BCM1480_MC_CS3                    _SB_MAKEMASK1(7)
++#define M_BCM1480_MC_CS4                    _SB_MAKEMASK1(8)
++#define M_BCM1480_MC_CS5                    _SB_MAKEMASK1(9)
++#define M_BCM1480_MC_CS6                    _SB_MAKEMASK1(10)
++#define M_BCM1480_MC_CS7                    _SB_MAKEMASK1(11)
++
++#define M_BCM1480_MC_CMD_ACTIVE             _SB_MAKEMASK1(16)
++
++/*
++ * DRAM Mode Register (Table 91)
++ */
++
++#define S_BCM1480_MC_EMODE                  0
++#define M_BCM1480_MC_EMODE                  _SB_MAKEMASK(15,S_BCM1480_MC_EMODE)
++#define V_BCM1480_MC_EMODE(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_EMODE)
++#define G_BCM1480_MC_EMODE(x)               _SB_GETVALUE(x,S_BCM1480_MC_EMODE,M_BCM1480_MC_EMODE)
++#define V_BCM1480_MC_EMODE_DEFAULT          V_BCM1480_MC_EMODE(0)
++
++#define S_BCM1480_MC_MODE                   16
++#define M_BCM1480_MC_MODE                   _SB_MAKEMASK(15,S_BCM1480_MC_MODE)
++#define V_BCM1480_MC_MODE(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_MODE)
++#define G_BCM1480_MC_MODE(x)                _SB_GETVALUE(x,S_BCM1480_MC_MODE,M_BCM1480_MC_MODE)
++#define V_BCM1480_MC_MODE_DEFAULT           V_BCM1480_MC_MODE(0)
++
++#define S_BCM1480_MC_DRAM_TYPE              32
++#define M_BCM1480_MC_DRAM_TYPE              _SB_MAKEMASK(4,S_BCM1480_MC_DRAM_TYPE)
++#define V_BCM1480_MC_DRAM_TYPE(x)           _SB_MAKEVALUE(x,S_BCM1480_MC_DRAM_TYPE)
++#define G_BCM1480_MC_DRAM_TYPE(x)           _SB_GETVALUE(x,S_BCM1480_MC_DRAM_TYPE,M_BCM1480_MC_DRAM_TYPE)
++
++#define K_BCM1480_MC_DRAM_TYPE_JEDEC        0
++#define K_BCM1480_MC_DRAM_TYPE_FCRAM        1
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define K_BCM1480_MC_DRAM_TYPE_DDR2	    2
++#endif
++
++#define V_BCM1480_MC_DRAM_TYPE_JEDEC        V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_JEDEC)
++#define V_BCM1480_MC_DRAM_TYPE_FCRAM        V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_FCRAM)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define V_BCM1480_MC_DRAM_TYPE_DDR2	    V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_DDR2)
++#endif
++
++#define M_BCM1480_MC_GANGED                 _SB_MAKEMASK1(36)
++#define M_BCM1480_MC_BY9_INTF               _SB_MAKEMASK1(37)
++#define M_BCM1480_MC_FORCE_ECC64            _SB_MAKEMASK1(38)
++#define M_BCM1480_MC_ECC_DISABLE            _SB_MAKEMASK1(39)
++
++#define S_BCM1480_MC_PG_POLICY              40
++#define M_BCM1480_MC_PG_POLICY              _SB_MAKEMASK(2,S_BCM1480_MC_PG_POLICY)
++#define V_BCM1480_MC_PG_POLICY(x)           _SB_MAKEVALUE(x,S_BCM1480_MC_PG_POLICY)
++#define G_BCM1480_MC_PG_POLICY(x)           _SB_GETVALUE(x,S_BCM1480_MC_PG_POLICY,M_BCM1480_MC_PG_POLICY)
++
++#define K_BCM1480_MC_PG_POLICY_CLOSED       0
++#define K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK 1
++
++#define V_BCM1480_MC_PG_POLICY_CLOSED       V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CLOSED)
++#define V_BCM1480_MC_PG_POLICY_CAS_TIME_CHK V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define M_BCM1480_MC_2T_CMD		    _SB_MAKEMASK1(42)
++#define M_BCM1480_MC_ECC_COR_DIS	    _SB_MAKEMASK1(43)
++#endif
++
++#define V_BCM1480_MC_DRAMMODE_DEFAULT	V_BCM1480_MC_EMODE_DEFAULT | V_BCM1480_MC_MODE_DEFAULT | V_BCM1480_MC_DRAM_TYPE_JEDEC | \
++                                V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK)
++
++/*
++ * Memory Clock Configuration Register (Table 92)
++ */
++
++#define S_BCM1480_MC_CLK_RATIO              0
++#define M_BCM1480_MC_CLK_RATIO              _SB_MAKEMASK(6,S_BCM1480_MC_CLK_RATIO)
++#define V_BCM1480_MC_CLK_RATIO(x)           _SB_MAKEVALUE(x,S_BCM1480_MC_CLK_RATIO)
++#define G_BCM1480_MC_CLK_RATIO(x)           _SB_GETVALUE(x,S_BCM1480_MC_CLK_RATIO,M_BCM1480_MC_CLK_RATIO)
++
++#define V_BCM1480_MC_CLK_RATIO_DEFAULT      V_BCM1480_MC_CLK_RATIO(10)
++
++#define S_BCM1480_MC_REF_RATE               8
++#define M_BCM1480_MC_REF_RATE               _SB_MAKEMASK(8,S_BCM1480_MC_REF_RATE)
++#define V_BCM1480_MC_REF_RATE(x)            _SB_MAKEVALUE(x,S_BCM1480_MC_REF_RATE)
++#define G_BCM1480_MC_REF_RATE(x)            _SB_GETVALUE(x,S_BCM1480_MC_REF_RATE,M_BCM1480_MC_REF_RATE)
++
++#define K_BCM1480_MC_REF_RATE_100MHz        0x31
++#define K_BCM1480_MC_REF_RATE_200MHz        0x62
++#define K_BCM1480_MC_REF_RATE_400MHz        0xC4
++
++#define V_BCM1480_MC_REF_RATE_100MHz        V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_100MHz)
++#define V_BCM1480_MC_REF_RATE_200MHz        V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_200MHz)
++#define V_BCM1480_MC_REF_RATE_400MHz        V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_400MHz)
++#define V_BCM1480_MC_REF_RATE_DEFAULT       V_BCM1480_MC_REF_RATE_400MHz
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define M_BCM1480_MC_AUTO_REF_DIS	    _SB_MAKEMASK1(16)
++#endif
++
++/*
++ * ODT Register (Table 99)
++ */
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define M_BCM1480_MC_RD_ODT0_CS0	    _SB_MAKEMASK1(0)
++#define M_BCM1480_MC_RD_ODT0_CS2	    _SB_MAKEMASK1(1)
++#define M_BCM1480_MC_RD_ODT0_CS4	    _SB_MAKEMASK1(2)
++#define M_BCM1480_MC_RD_ODT0_CS6	    _SB_MAKEMASK1(3)
++#define M_BCM1480_MC_WR_ODT0_CS0	    _SB_MAKEMASK1(4)
++#define M_BCM1480_MC_WR_ODT0_CS2	    _SB_MAKEMASK1(5)
++#define M_BCM1480_MC_WR_ODT0_CS4	    _SB_MAKEMASK1(6)
++#define M_BCM1480_MC_WR_ODT0_CS6	    _SB_MAKEMASK1(7)
++#define M_BCM1480_MC_RD_ODT2_CS0	    _SB_MAKEMASK1(8)
++#define M_BCM1480_MC_RD_ODT2_CS2	    _SB_MAKEMASK1(9)
++#define M_BCM1480_MC_RD_ODT2_CS4	    _SB_MAKEMASK1(10)
++#define M_BCM1480_MC_RD_ODT2_CS6	    _SB_MAKEMASK1(11)
++#define M_BCM1480_MC_WR_ODT2_CS0	    _SB_MAKEMASK1(12)
++#define M_BCM1480_MC_WR_ODT2_CS2	    _SB_MAKEMASK1(13)
++#define M_BCM1480_MC_WR_ODT2_CS4	    _SB_MAKEMASK1(14)
++#define M_BCM1480_MC_WR_ODT2_CS6	    _SB_MAKEMASK1(15)
++#define M_BCM1480_MC_RD_ODT4_CS0	    _SB_MAKEMASK1(16)
++#define M_BCM1480_MC_RD_ODT4_CS2	    _SB_MAKEMASK1(17)
++#define M_BCM1480_MC_RD_ODT4_CS4	    _SB_MAKEMASK1(18)
++#define M_BCM1480_MC_RD_ODT4_CS6	    _SB_MAKEMASK1(19)
++#define M_BCM1480_MC_WR_ODT4_CS0	    _SB_MAKEMASK1(20)
++#define M_BCM1480_MC_WR_ODT4_CS2	    _SB_MAKEMASK1(21)
++#define M_BCM1480_MC_WR_ODT4_CS4	    _SB_MAKEMASK1(22)
++#define M_BCM1480_MC_WR_ODT4_CS6	    _SB_MAKEMASK1(23)
++#define M_BCM1480_MC_RD_ODT6_CS0	    _SB_MAKEMASK1(24)
++#define M_BCM1480_MC_RD_ODT6_CS2	    _SB_MAKEMASK1(25)
++#define M_BCM1480_MC_RD_ODT6_CS4	    _SB_MAKEMASK1(26)
++#define M_BCM1480_MC_RD_ODT6_CS6	    _SB_MAKEMASK1(27)
++#define M_BCM1480_MC_WR_ODT6_CS0	    _SB_MAKEMASK1(28)
++#define M_BCM1480_MC_WR_ODT6_CS2	    _SB_MAKEMASK1(29)
++#define M_BCM1480_MC_WR_ODT6_CS4	    _SB_MAKEMASK1(30)
++#define M_BCM1480_MC_WR_ODT6_CS6	    _SB_MAKEMASK1(31)
++
++#define M_BCM1480_MC_CS_ODD_ODT_EN	    _SB_MAKEMASK1(32)
++#endif
++
++/*
++ * Memory DLL Configuration Register (Table 93)
++ */
++
++#define S_BCM1480_MC_ADDR_COARSE_ADJ         0
++#define M_BCM1480_MC_ADDR_COARSE_ADJ         _SB_MAKEMASK(6,S_BCM1480_MC_ADDR_COARSE_ADJ)
++#define V_BCM1480_MC_ADDR_COARSE_ADJ(x)      _SB_MAKEVALUE(x,S_BCM1480_MC_ADDR_COARSE_ADJ)
++#define G_BCM1480_MC_ADDR_COARSE_ADJ(x)      _SB_GETVALUE(x,S_BCM1480_MC_ADDR_COARSE_ADJ,M_BCM1480_MC_ADDR_COARSE_ADJ)
++#define V_BCM1480_MC_ADDR_COARSE_ADJ_DEFAULT V_BCM1480_MC_ADDR_COARSE_ADJ(0x0)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define S_BCM1480_MC_ADDR_FREQ_RANGE	    	8
++#define M_BCM1480_MC_ADDR_FREQ_RANGE	    	_SB_MAKEMASK(4,S_BCM1480_MC_ADDR_FREQ_RANGE)
++#define V_BCM1480_MC_ADDR_FREQ_RANGE(x)     	_SB_MAKEVALUE(x,S_BCM1480_MC_ADDR_FREQ_RANGE)
++#define G_BCM1480_MC_ADDR_FREQ_RANGE(x)     	_SB_GETVALUE(x,S_BCM1480_MC_ADDR_FREQ_RANGE,M_BCM1480_MC_ADDR_FREQ_RANGE)
++#define V_BCM1480_MC_ADDR_FREQ_RANGE_DEFAULT 	V_BCM1480_MC_ADDR_FREQ_RANGE(0x4)
++#endif
++
++#define S_BCM1480_MC_ADDR_FINE_ADJ          8
++#define M_BCM1480_MC_ADDR_FINE_ADJ          _SB_MAKEMASK(4,S_BCM1480_MC_ADDR_FINE_ADJ)
++#define V_BCM1480_MC_ADDR_FINE_ADJ(x)       _SB_MAKEVALUE(x,S_BCM1480_MC_ADDR_FINE_ADJ)
++#define G_BCM1480_MC_ADDR_FINE_ADJ(x)       _SB_GETVALUE(x,S_BCM1480_MC_ADDR_FINE_ADJ,M_BCM1480_MC_ADDR_FINE_ADJ)
++#define V_BCM1480_MC_ADDR_FINE_ADJ_DEFAULT  V_BCM1480_MC_ADDR_FINE_ADJ(0x8)
++
++#define S_BCM1480_MC_DQI_COARSE_ADJ         16
++#define M_BCM1480_MC_DQI_COARSE_ADJ         _SB_MAKEMASK(6,S_BCM1480_MC_DQI_COARSE_ADJ)
++#define V_BCM1480_MC_DQI_COARSE_ADJ(x)      _SB_MAKEVALUE(x,S_BCM1480_MC_DQI_COARSE_ADJ)
++#define G_BCM1480_MC_DQI_COARSE_ADJ(x)      _SB_GETVALUE(x,S_BCM1480_MC_DQI_COARSE_ADJ,M_BCM1480_MC_DQI_COARSE_ADJ)
++#define V_BCM1480_MC_DQI_COARSE_ADJ_DEFAULT V_BCM1480_MC_DQI_COARSE_ADJ(0x0)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define S_BCM1480_MC_DQI_FREQ_RANGE	    	24
++#define M_BCM1480_MC_DQI_FREQ_RANGE	    	_SB_MAKEMASK(4,S_BCM1480_MC_DQI_FREQ_RANGE)
++#define V_BCM1480_MC_DQI_FREQ_RANGE(x)     	_SB_MAKEVALUE(x,S_BCM1480_MC_DQI_FREQ_RANGE)
++#define G_BCM1480_MC_DQI_FREQ_RANGE(x)     	_SB_GETVALUE(x,S_BCM1480_MC_DQI_FREQ_RANGE,M_BCM1480_MC_DQI_FREQ_RANGE)
++#define V_BCM1480_MC_DQI_FREQ_RANGE_DEFAULT 	V_BCM1480_MC_DQI_FREQ_RANGE(0x4)
++#endif
++
++#define S_BCM1480_MC_DQI_FINE_ADJ           24
++#define M_BCM1480_MC_DQI_FINE_ADJ           _SB_MAKEMASK(4,S_BCM1480_MC_DQI_FINE_ADJ)
++#define V_BCM1480_MC_DQI_FINE_ADJ(x)        _SB_MAKEVALUE(x,S_BCM1480_MC_DQI_FINE_ADJ)
++#define G_BCM1480_MC_DQI_FINE_ADJ(x)        _SB_GETVALUE(x,S_BCM1480_MC_DQI_FINE_ADJ,M_BCM1480_MC_DQI_FINE_ADJ)
++#define V_BCM1480_MC_DQI_FINE_ADJ_DEFAULT   V_BCM1480_MC_DQI_FINE_ADJ(0x8)
++
++#define S_BCM1480_MC_DQO_COARSE_ADJ         32
++#define M_BCM1480_MC_DQO_COARSE_ADJ         _SB_MAKEMASK(6,S_BCM1480_MC_DQO_COARSE_ADJ)
++#define V_BCM1480_MC_DQO_COARSE_ADJ(x)      _SB_MAKEVALUE(x,S_BCM1480_MC_DQO_COARSE_ADJ)
++#define G_BCM1480_MC_DQO_COARSE_ADJ(x)      _SB_GETVALUE(x,S_BCM1480_MC_DQO_COARSE_ADJ,M_BCM1480_MC_DQO_COARSE_ADJ)
++#define V_BCM1480_MC_DQO_COARSE_ADJ_DEFAULT V_BCM1480_MC_DQO_COARSE_ADJ(0x0)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define S_BCM1480_MC_DQO_FREQ_RANGE	    	40
++#define M_BCM1480_MC_DQO_FREQ_RANGE	    	_SB_MAKEMASK(4,S_BCM1480_MC_DQO_FREQ_RANGE)
++#define V_BCM1480_MC_DQO_FREQ_RANGE(x)     	_SB_MAKEVALUE(x,S_BCM1480_MC_DQO_FREQ_RANGE)
++#define G_BCM1480_MC_DQO_FREQ_RANGE(x)     	_SB_GETVALUE(x,S_BCM1480_MC_DQO_FREQ_RANGE,M_BCM1480_MC_DQO_FREQ_RANGE)
++#define V_BCM1480_MC_DQO_FREQ_RANGE_DEFAULT 	V_BCM1480_MC_DQO_FREQ_RANGE(0x4)
++#endif
++
++#define S_BCM1480_MC_DQO_FINE_ADJ           40
++#define M_BCM1480_MC_DQO_FINE_ADJ           _SB_MAKEMASK(4,S_BCM1480_MC_DQO_FINE_ADJ)
++#define V_BCM1480_MC_DQO_FINE_ADJ(x)        _SB_MAKEVALUE(x,S_BCM1480_MC_DQO_FINE_ADJ)
++#define G_BCM1480_MC_DQO_FINE_ADJ(x)        _SB_GETVALUE(x,S_BCM1480_MC_DQO_FINE_ADJ,M_BCM1480_MC_DQO_FINE_ADJ)
++#define V_BCM1480_MC_DQO_FINE_ADJ_DEFAULT   V_BCM1480_MC_DQO_FINE_ADJ(0x8)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define S_BCM1480_MC_DLL_PDSEL            44
++#define M_BCM1480_MC_DLL_PDSEL            _SB_MAKEMASK(2,S_BCM1480_MC_DLL_PDSEL)
++#define V_BCM1480_MC_DLL_PDSEL(x)         _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_PDSEL)
++#define G_BCM1480_MC_DLL_PDSEL(x)         _SB_GETVALUE(x,S_BCM1480_MC_DLL_PDSEL,M_BCM1480_MC_DLL_PDSEL)
++#define V_BCM1480_MC_DLL_DEFAULT_PDSEL    V_BCM1480_MC_DLL_PDSEL(0x0)
++
++#define	M_BCM1480_MC_DLL_REGBYPASS        _SB_MAKEMASK1(46)
++#define	M_BCM1480_MC_DQO_SHIFT            _SB_MAKEMASK1(47)
++#endif
++
++#define S_BCM1480_MC_DLL_DEFAULT            48
++#define M_BCM1480_MC_DLL_DEFAULT            _SB_MAKEMASK(6,S_BCM1480_MC_DLL_DEFAULT)
++#define V_BCM1480_MC_DLL_DEFAULT(x)         _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_DEFAULT)
++#define G_BCM1480_MC_DLL_DEFAULT(x)         _SB_GETVALUE(x,S_BCM1480_MC_DLL_DEFAULT,M_BCM1480_MC_DLL_DEFAULT)
++#define V_BCM1480_MC_DLL_DEFAULT_DEFAULT    V_BCM1480_MC_DLL_DEFAULT(0x10)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define S_BCM1480_MC_DLL_REGCTRL	  54
++#define M_BCM1480_MC_DLL_REGCTRL       	  _SB_MAKEMASK(2,S_BCM1480_MC_DLL_REGCTRL)
++#define V_BCM1480_MC_DLL_REGCTRL(x)       _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_REGCTRL)
++#define G_BCM1480_MC_DLL_REGCTRL(x)       _SB_GETVALUE(x,S_BCM1480_MC_DLL_REGCTRL,M_BCM1480_MC_DLL_REGCTRL)
++#define V_BCM1480_MC_DLL_DEFAULT_REGCTRL  V_BCM1480_MC_DLL_REGCTRL(0x0)
++#endif
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define S_BCM1480_MC_DLL_FREQ_RANGE	    	56
++#define M_BCM1480_MC_DLL_FREQ_RANGE	    	_SB_MAKEMASK(4,S_BCM1480_MC_DLL_FREQ_RANGE)
++#define V_BCM1480_MC_DLL_FREQ_RANGE(x)     	_SB_MAKEVALUE(x,S_BCM1480_MC_DLL_FREQ_RANGE)
++#define G_BCM1480_MC_DLL_FREQ_RANGE(x)     	_SB_GETVALUE(x,S_BCM1480_MC_DLL_FREQ_RANGE,M_BCM1480_MC_DLL_FREQ_RANGE)
++#define V_BCM1480_MC_DLL_FREQ_RANGE_DEFAULT 	V_BCM1480_MC_DLL_FREQ_RANGE(0x4)
++#endif
++
++#define S_BCM1480_MC_DLL_STEP_SIZE          56
++#define M_BCM1480_MC_DLL_STEP_SIZE          _SB_MAKEMASK(4,S_BCM1480_MC_DLL_STEP_SIZE)
++#define V_BCM1480_MC_DLL_STEP_SIZE(x)       _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_STEP_SIZE)
++#define G_BCM1480_MC_DLL_STEP_SIZE(x)       _SB_GETVALUE(x,S_BCM1480_MC_DLL_STEP_SIZE,M_BCM1480_MC_DLL_STEP_SIZE)
++#define V_BCM1480_MC_DLL_STEP_SIZE_DEFAULT  V_BCM1480_MC_DLL_STEP_SIZE(0x8)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define S_BCM1480_MC_DLL_BGCTRL	  60
++#define M_BCM1480_MC_DLL_BGCTRL       	  _SB_MAKEMASK(2,S_BCM1480_MC_DLL_BGCTRL)
++#define V_BCM1480_MC_DLL_BGCTRL(x)       _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_BGCTRL)
++#define G_BCM1480_MC_DLL_BGCTRL(x)       _SB_GETVALUE(x,S_BCM1480_MC_DLL_BGCTRL,M_BCM1480_MC_DLL_BGCTRL)
++#define V_BCM1480_MC_DLL_DEFAULT_BGCTRL  V_BCM1480_MC_DLL_BGCTRL(0x0)
++#endif
++
++#define	M_BCM1480_MC_DLL_BYPASS		    _SB_MAKEMASK1(63)
++
++/*
++ * Memory Drive Configuration Register (Table 94)
++ */
++
++#define S_BCM1480_MC_RTT_BYP_PULLDOWN       0
++#define M_BCM1480_MC_RTT_BYP_PULLDOWN       _SB_MAKEMASK(3,S_BCM1480_MC_RTT_BYP_PULLDOWN)
++#define V_BCM1480_MC_RTT_BYP_PULLDOWN(x)    _SB_MAKEVALUE(x,S_BCM1480_MC_RTT_BYP_PULLDOWN)
++#define G_BCM1480_MC_RTT_BYP_PULLDOWN(x)    _SB_GETVALUE(x,S_BCM1480_MC_RTT_BYP_PULLDOWN,M_BCM1480_MC_RTT_BYP_PULLDOWN)
++
++#define S_BCM1480_MC_RTT_BYP_PULLUP         6
++#define M_BCM1480_MC_RTT_BYP_PULLUP         _SB_MAKEMASK(3,S_BCM1480_MC_RTT_BYP_PULLUP)
++#define V_BCM1480_MC_RTT_BYP_PULLUP(x)      _SB_MAKEVALUE(x,S_BCM1480_MC_RTT_BYP_PULLUP)
++#define G_BCM1480_MC_RTT_BYP_PULLUP(x)      _SB_GETVALUE(x,S_BCM1480_MC_RTT_BYP_PULLUP,M_BCM1480_MC_RTT_BYP_PULLUP)
++
++#define M_BCM1480_MC_RTT_BYPASS             _SB_MAKEMASK1(8)
++#define M_BCM1480_MC_RTT_COMP_MOV_AVG       _SB_MAKEMASK1(9)
++
++#define S_BCM1480_MC_PVT_BYP_C1_PULLDOWN    10
++#define M_BCM1480_MC_PVT_BYP_C1_PULLDOWN    _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
++#define V_BCM1480_MC_PVT_BYP_C1_PULLDOWN(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
++#define G_BCM1480_MC_PVT_BYP_C1_PULLDOWN(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLDOWN,M_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
++
++#define S_BCM1480_MC_PVT_BYP_C1_PULLUP      15
++#define M_BCM1480_MC_PVT_BYP_C1_PULLUP      _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C1_PULLUP)
++#define V_BCM1480_MC_PVT_BYP_C1_PULLUP(x)   _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLUP)
++#define G_BCM1480_MC_PVT_BYP_C1_PULLUP(x)   _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLUP,M_BCM1480_MC_PVT_BYP_C1_PULLUP)
++
++#define S_BCM1480_MC_PVT_BYP_C2_PULLDOWN    20
++#define M_BCM1480_MC_PVT_BYP_C2_PULLDOWN    _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
++#define V_BCM1480_MC_PVT_BYP_C2_PULLDOWN(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
++#define G_BCM1480_MC_PVT_BYP_C2_PULLDOWN(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLDOWN,M_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
++
++#define S_BCM1480_MC_PVT_BYP_C2_PULLUP      25
++#define M_BCM1480_MC_PVT_BYP_C2_PULLUP      _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C2_PULLUP)
++#define V_BCM1480_MC_PVT_BYP_C2_PULLUP(x)   _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLUP)
++#define G_BCM1480_MC_PVT_BYP_C2_PULLUP(x)   _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLUP,M_BCM1480_MC_PVT_BYP_C2_PULLUP)
++
++#define M_BCM1480_MC_PVT_BYPASS             _SB_MAKEMASK1(30)
++#define M_BCM1480_MC_PVT_COMP_MOV_AVG       _SB_MAKEMASK1(31)
++
++#define M_BCM1480_MC_CLK_CLASS              _SB_MAKEMASK1(34)
++#define M_BCM1480_MC_DATA_CLASS             _SB_MAKEMASK1(35)
++#define M_BCM1480_MC_ADDR_CLASS             _SB_MAKEMASK1(36)
++
++#define M_BCM1480_MC_DQ_ODT_75              _SB_MAKEMASK1(37)
++#define M_BCM1480_MC_DQ_ODT_150             _SB_MAKEMASK1(38)
++#define M_BCM1480_MC_DQS_ODT_75             _SB_MAKEMASK1(39)
++#define M_BCM1480_MC_DQS_ODT_150            _SB_MAKEMASK1(40)
++#define M_BCM1480_MC_DQS_DIFF               _SB_MAKEMASK1(41)
++
++/*
++ * ECC Test Data Register (Table 95)
++ */
++
++#define S_BCM1480_MC_DATA_INVERT            0
++#define M_DATA_ECC_INVERT           _SB_MAKEMASK(64,S_BCM1480_MC_ECC_INVERT)
++
++/*
++ * ECC Test ECC Register (Table 96)
++ */
++
++#define S_BCM1480_MC_ECC_INVERT             0
++#define M_BCM1480_MC_ECC_INVERT             _SB_MAKEMASK(8,S_BCM1480_MC_ECC_INVERT)
++
++/*
++ * SDRAM Timing Register  (Table 97)
++ */
++
++#define S_BCM1480_MC_tRCD                   0
++#define M_BCM1480_MC_tRCD                   _SB_MAKEMASK(4,S_BCM1480_MC_tRCD)
++#define V_BCM1480_MC_tRCD(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tRCD)
++#define G_BCM1480_MC_tRCD(x)                _SB_GETVALUE(x,S_BCM1480_MC_tRCD,M_BCM1480_MC_tRCD)
++#define K_BCM1480_MC_tRCD_DEFAULT           3
++#define V_BCM1480_MC_tRCD_DEFAULT           V_BCM1480_MC_tRCD(K_BCM1480_MC_tRCD_DEFAULT)
++
++#define S_BCM1480_MC_tCL                    4
++#define M_BCM1480_MC_tCL                    _SB_MAKEMASK(4,S_BCM1480_MC_tCL)
++#define V_BCM1480_MC_tCL(x)                 _SB_MAKEVALUE(x,S_BCM1480_MC_tCL)
++#define G_BCM1480_MC_tCL(x)                 _SB_GETVALUE(x,S_BCM1480_MC_tCL,M_BCM1480_MC_tCL)
++#define K_BCM1480_MC_tCL_DEFAULT            2
++#define V_BCM1480_MC_tCL_DEFAULT            V_BCM1480_MC_tCL(K_BCM1480_MC_tCL_DEFAULT)
++
++#define M_BCM1480_MC_tCrDh                  _SB_MAKEMASK1(8)
++
++#define S_BCM1480_MC_tWR                    9
++#define M_BCM1480_MC_tWR                    _SB_MAKEMASK(3,S_BCM1480_MC_tWR)
++#define V_BCM1480_MC_tWR(x)                 _SB_MAKEVALUE(x,S_BCM1480_MC_tWR)
++#define G_BCM1480_MC_tWR(x)                 _SB_GETVALUE(x,S_BCM1480_MC_tWR,M_BCM1480_MC_tWR)
++#define K_BCM1480_MC_tWR_DEFAULT            2
++#define V_BCM1480_MC_tWR_DEFAULT            V_BCM1480_MC_tWR(K_BCM1480_MC_tWR_DEFAULT)
++
++#define S_BCM1480_MC_tCwD                   12
++#define M_BCM1480_MC_tCwD                   _SB_MAKEMASK(4,S_BCM1480_MC_tCwD)
++#define V_BCM1480_MC_tCwD(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tCwD)
++#define G_BCM1480_MC_tCwD(x)                _SB_GETVALUE(x,S_BCM1480_MC_tCwD,M_BCM1480_MC_tCwD)
++#define K_BCM1480_MC_tCwD_DEFAULT           1
++#define V_BCM1480_MC_tCwD_DEFAULT           V_BCM1480_MC_tCwD(K_BCM1480_MC_tCwD_DEFAULT)
++
++#define S_BCM1480_MC_tRP                    16
++#define M_BCM1480_MC_tRP                    _SB_MAKEMASK(4,S_BCM1480_MC_tRP)
++#define V_BCM1480_MC_tRP(x)                 _SB_MAKEVALUE(x,S_BCM1480_MC_tRP)
++#define G_BCM1480_MC_tRP(x)                 _SB_GETVALUE(x,S_BCM1480_MC_tRP,M_BCM1480_MC_tRP)
++#define K_BCM1480_MC_tRP_DEFAULT            4
++#define V_BCM1480_MC_tRP_DEFAULT            V_BCM1480_MC_tRP(K_BCM1480_MC_tRP_DEFAULT)
++
++#define S_BCM1480_MC_tRRD                   20
++#define M_BCM1480_MC_tRRD                   _SB_MAKEMASK(4,S_BCM1480_MC_tRRD)
++#define V_BCM1480_MC_tRRD(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tRRD)
++#define G_BCM1480_MC_tRRD(x)                _SB_GETVALUE(x,S_BCM1480_MC_tRRD,M_BCM1480_MC_tRRD)
++#define K_BCM1480_MC_tRRD_DEFAULT           2
++#define V_BCM1480_MC_tRRD_DEFAULT           V_BCM1480_MC_tRRD(K_BCM1480_MC_tRRD_DEFAULT)
++
++#define S_BCM1480_MC_tRCw                   24
++#define M_BCM1480_MC_tRCw                   _SB_MAKEMASK(5,S_BCM1480_MC_tRCw)
++#define V_BCM1480_MC_tRCw(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tRCw)
++#define G_BCM1480_MC_tRCw(x)                _SB_GETVALUE(x,S_BCM1480_MC_tRCw,M_BCM1480_MC_tRCw)
++#define K_BCM1480_MC_tRCw_DEFAULT           10
++#define V_BCM1480_MC_tRCw_DEFAULT           V_BCM1480_MC_tRCw(K_BCM1480_MC_tRCw_DEFAULT)
++
++#define S_BCM1480_MC_tRCr                   32
++#define M_BCM1480_MC_tRCr                   _SB_MAKEMASK(5,S_BCM1480_MC_tRCr)
++#define V_BCM1480_MC_tRCr(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tRCr)
++#define G_BCM1480_MC_tRCr(x)                _SB_GETVALUE(x,S_BCM1480_MC_tRCr,M_BCM1480_MC_tRCr)
++#define K_BCM1480_MC_tRCr_DEFAULT           9
++#define V_BCM1480_MC_tRCr_DEFAULT           V_BCM1480_MC_tRCr(K_BCM1480_MC_tRCr_DEFAULT)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define S_BCM1480_MC_tFAW                   40
++#define M_BCM1480_MC_tFAW                   _SB_MAKEMASK(6,S_BCM1480_MC_tFAW)
++#define V_BCM1480_MC_tFAW(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tFAW)
++#define G_BCM1480_MC_tFAW(x)                _SB_GETVALUE(x,S_BCM1480_MC_tFAW,M_BCM1480_MC_tFAW)
++#define K_BCM1480_MC_tFAW_DEFAULT           0
++#define V_BCM1480_MC_tFAW_DEFAULT           V_BCM1480_MC_tFAW(K_BCM1480_MC_tFAW_DEFAULT)
++#endif
++
++#define S_BCM1480_MC_tRFC                   48
++#define M_BCM1480_MC_tRFC                   _SB_MAKEMASK(7,S_BCM1480_MC_tRFC)
++#define V_BCM1480_MC_tRFC(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tRFC)
++#define G_BCM1480_MC_tRFC(x)                _SB_GETVALUE(x,S_BCM1480_MC_tRFC,M_BCM1480_MC_tRFC)
++#define K_BCM1480_MC_tRFC_DEFAULT           12
++#define V_BCM1480_MC_tRFC_DEFAULT           V_BCM1480_MC_tRFC(K_BCM1480_MC_tRFC_DEFAULT)
++
++#define S_BCM1480_MC_tFIFO                  56
++#define M_BCM1480_MC_tFIFO                  _SB_MAKEMASK(2,S_BCM1480_MC_tFIFO)
++#define V_BCM1480_MC_tFIFO(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_tFIFO)
++#define G_BCM1480_MC_tFIFO(x)               _SB_GETVALUE(x,S_BCM1480_MC_tFIFO,M_BCM1480_MC_tFIFO)
++#define K_BCM1480_MC_tFIFO_DEFAULT          0
++#define V_BCM1480_MC_tFIFO_DEFAULT          V_BCM1480_MC_tFIFO(K_BCM1480_MC_tFIFO_DEFAULT)
++
++#define S_BCM1480_MC_tW2R                  58
++#define M_BCM1480_MC_tW2R                  _SB_MAKEMASK(2,S_BCM1480_MC_tW2R)
++#define V_BCM1480_MC_tW2R(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_tW2R)
++#define G_BCM1480_MC_tW2R(x)               _SB_GETVALUE(x,S_BCM1480_MC_tW2R,M_BCM1480_MC_tW2R)
++#define K_BCM1480_MC_tW2R_DEFAULT          1
++#define V_BCM1480_MC_tW2R_DEFAULT          V_BCM1480_MC_tW2R(K_BCM1480_MC_tW2R_DEFAULT)
++
++#define S_BCM1480_MC_tR2W                  60
++#define M_BCM1480_MC_tR2W                  _SB_MAKEMASK(2,S_BCM1480_MC_tR2W)
++#define V_BCM1480_MC_tR2W(x)               _SB_MAKEVALUE(x,S_BCM1480_MC_tR2W)
++#define G_BCM1480_MC_tR2W(x)               _SB_GETVALUE(x,S_BCM1480_MC_tR2W,M_BCM1480_MC_tR2W)
++#define K_BCM1480_MC_tR2W_DEFAULT          0
++#define V_BCM1480_MC_tR2W_DEFAULT          V_BCM1480_MC_tR2W(K_BCM1480_MC_tR2W_DEFAULT)
++
++#define M_BCM1480_MC_tR2R		    _SB_MAKEMASK1(62)
++
++#define V_BCM1480_MC_TIMING_DEFAULT         (M_BCM1480_MC_tR2R | \
++                                     V_BCM1480_MC_tFIFO_DEFAULT | \
++                                     V_BCM1480_MC_tR2W_DEFAULT | \
++                                     V_BCM1480_MC_tW2R_DEFAULT | \
++                                     V_BCM1480_MC_tRFC_DEFAULT | \
++                                     V_BCM1480_MC_tRCr_DEFAULT | \
++                                     V_BCM1480_MC_tRCw_DEFAULT | \
++                                     V_BCM1480_MC_tRRD_DEFAULT | \
++                                     V_BCM1480_MC_tRP_DEFAULT | \
++                                     V_BCM1480_MC_tCwD_DEFAULT | \
++                                     V_BCM1480_MC_tWR_DEFAULT | \
++                                     M_BCM1480_MC_tCrDh | \
++                                     V_BCM1480_MC_tCL_DEFAULT | \
++                                     V_BCM1480_MC_tRCD_DEFAULT)
++
++/*
++ * SDRAM Timing Register 2
++ */
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++
++#define S_BCM1480_MC_tAL                   0
++#define M_BCM1480_MC_tAL                   _SB_MAKEMASK(4,S_BCM1480_MC_tAL)
++#define V_BCM1480_MC_tAL(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tAL)
++#define G_BCM1480_MC_tAL(x)                _SB_GETVALUE(x,S_BCM1480_MC_tAL,M_BCM1480_MC_tAL)
++#define K_BCM1480_MC_tAL_DEFAULT           0
++#define V_BCM1480_MC_tAL_DEFAULT           V_BCM1480_MC_tAL(K_BCM1480_MC_tAL_DEFAULT)
++
++#define S_BCM1480_MC_tRTP                   4
++#define M_BCM1480_MC_tRTP                   _SB_MAKEMASK(3,S_BCM1480_MC_tRTP)
++#define V_BCM1480_MC_tRTP(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tRTP)
++#define G_BCM1480_MC_tRTP(x)                _SB_GETVALUE(x,S_BCM1480_MC_tRTP,M_BCM1480_MC_tRTP)
++#define K_BCM1480_MC_tRTP_DEFAULT           2
++#define V_BCM1480_MC_tRTP_DEFAULT           V_BCM1480_MC_tRTP(K_BCM1480_MC_tRTP_DEFAULT)
++
++#define S_BCM1480_MC_tW2W                   8
++#define M_BCM1480_MC_tW2W                   _SB_MAKEMASK(2,S_BCM1480_MC_tW2W)
++#define V_BCM1480_MC_tW2W(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tW2W)
++#define G_BCM1480_MC_tW2W(x)                _SB_GETVALUE(x,S_BCM1480_MC_tW2W,M_BCM1480_MC_tW2W)
++#define K_BCM1480_MC_tW2W_DEFAULT           0
++#define V_BCM1480_MC_tW2W_DEFAULT           V_BCM1480_MC_tW2W(K_BCM1480_MC_tW2W_DEFAULT)
++
++#define S_BCM1480_MC_tRAP                   12
++#define M_BCM1480_MC_tRAP                  _SB_MAKEMASK(4,S_BCM1480_MC_tRAP)
++#define V_BCM1480_MC_tRAP(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_tRAP)
++#define G_BCM1480_MC_tRAP(x)                _SB_GETVALUE(x,S_BCM1480_MC_tRAP,M_BCM1480_MC_tRAP)
++#define K_BCM1480_MC_tRAP_DEFAULT           0
++#define V_BCM1480_MC_tRAP_DEFAULT           V_BCM1480_MC_tRAP(K_BCM1480_MC_tRAP_DEFAULT)
++
++#endif
++
++
++
++/*
++ * Global Registers: single instances per BCM1480
++ */
++
++/*
++ * Global Configuration Register (Table 99)
++ */
++
++#define S_BCM1480_MC_BLK_SET_MARK           8
++#define M_BCM1480_MC_BLK_SET_MARK           _SB_MAKEMASK(4,S_BCM1480_MC_BLK_SET_MARK)
++#define V_BCM1480_MC_BLK_SET_MARK(x)        _SB_MAKEVALUE(x,S_BCM1480_MC_BLK_SET_MARK)
++#define G_BCM1480_MC_BLK_SET_MARK(x)        _SB_GETVALUE(x,S_BCM1480_MC_BLK_SET_MARK,M_BCM1480_MC_BLK_SET_MARK)
++
++#define S_BCM1480_MC_BLK_CLR_MARK           12
++#define M_BCM1480_MC_BLK_CLR_MARK           _SB_MAKEMASK(4,S_BCM1480_MC_BLK_CLR_MARK)
++#define V_BCM1480_MC_BLK_CLR_MARK(x)        _SB_MAKEVALUE(x,S_BCM1480_MC_BLK_CLR_MARK)
++#define G_BCM1480_MC_BLK_CLR_MARK(x)        _SB_GETVALUE(x,S_BCM1480_MC_BLK_CLR_MARK,M_BCM1480_MC_BLK_CLR_MARK)
++
++#define M_BCM1480_MC_PKT_PRIORITY           _SB_MAKEMASK1(16)
++
++#define S_BCM1480_MC_MAX_AGE                20
++#define M_BCM1480_MC_MAX_AGE                _SB_MAKEMASK(4,S_BCM1480_MC_MAX_AGE)
++#define V_BCM1480_MC_MAX_AGE(x)             _SB_MAKEVALUE(x,S_BCM1480_MC_MAX_AGE)
++#define G_BCM1480_MC_MAX_AGE(x)             _SB_GETVALUE(x,S_BCM1480_MC_MAX_AGE,M_BCM1480_MC_MAX_AGE)
++
++#define M_BCM1480_MC_BERR_DISABLE           _SB_MAKEMASK1(29)
++#define M_BCM1480_MC_FORCE_SEQ              _SB_MAKEMASK1(30)
++#define M_BCM1480_MC_VGEN                   _SB_MAKEMASK1(32)
++
++#define S_BCM1480_MC_SLEW                   33
++#define M_BCM1480_MC_SLEW                   _SB_MAKEMASK(2,S_BCM1480_MC_SLEW)
++#define V_BCM1480_MC_SLEW(x)                _SB_MAKEVALUE(x,S_BCM1480_MC_SLEW)
++#define G_BCM1480_MC_SLEW(x)                _SB_GETVALUE(x,S_BCM1480_MC_SLEW,M_BCM1480_MC_SLEW)
++
++#define M_BCM1480_MC_SSTL_VOLTAGE           _SB_MAKEMASK1(35)
++
++/*
++ * Global Channel Interleave Register (Table 100)
++ */
++
++#define S_BCM1480_MC_INTLV0                 0
++#define M_BCM1480_MC_INTLV0                 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV0)
++#define V_BCM1480_MC_INTLV0(x)              _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV0)
++#define G_BCM1480_MC_INTLV0(x)              _SB_GETVALUE(x,S_BCM1480_MC_INTLV0,M_BCM1480_MC_INTLV0)
++
++#define S_BCM1480_MC_INTLV1                 8
++#define M_BCM1480_MC_INTLV1                 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV1)
++#define V_BCM1480_MC_INTLV1(x)              _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV1)
++#define G_BCM1480_MC_INTLV1(x)              _SB_GETVALUE(x,S_BCM1480_MC_INTLV1,M_BCM1480_MC_INTLV1)
++
++#define S_BCM1480_MC_INTLV_MODE             16
++#define M_BCM1480_MC_INTLV_MODE             _SB_MAKEMASK(3,S_BCM1480_MC_INTLV_MODE)
++#define V_BCM1480_MC_INTLV_MODE(x)          _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV_MODE)
++#define G_BCM1480_MC_INTLV_MODE(x)          _SB_GETVALUE(x,S_BCM1480_MC_INTLV_MODE,M_BCM1480_MC_INTLV_MODE)
++
++#define K_BCM1480_MC_INTLV_MODE_NONE        0x0
++#define K_BCM1480_MC_INTLV_MODE_01          0x1
++#define K_BCM1480_MC_INTLV_MODE_23          0x2
++#define K_BCM1480_MC_INTLV_MODE_01_23       0x3
++#define K_BCM1480_MC_INTLV_MODE_0123        0x4
++
++#define V_BCM1480_MC_INTLV_MODE_NONE        V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_NONE)
++#define V_BCM1480_MC_INTLV_MODE_01          V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_01)
++#define V_BCM1480_MC_INTLV_MODE_23          V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_23)
++#define V_BCM1480_MC_INTLV_MODE_01_23       V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_01_23)
++#define V_BCM1480_MC_INTLV_MODE_0123        V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_0123)
++
++/*
++ * ECC Status Register
++ */
++
++#define S_BCM1480_MC_ECC_ERR_ADDR           0
++#define M_BCM1480_MC_ECC_ERR_ADDR           _SB_MAKEMASK(37,S_BCM1480_MC_ECC_ERR_ADDR)
++#define V_BCM1480_MC_ECC_ERR_ADDR(x)        _SB_MAKEVALUE(x,S_BCM1480_MC_ECC_ERR_ADDR)
++#define G_BCM1480_MC_ECC_ERR_ADDR(x)        _SB_GETVALUE(x,S_BCM1480_MC_ECC_ERR_ADDR,M_BCM1480_MC_ECC_ERR_ADDR)
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define M_BCM1480_MC_ECC_ERR_RMW            _SB_MAKEMASK1(60)
++#endif
++
++#define M_BCM1480_MC_ECC_MULT_ERR_DET       _SB_MAKEMASK1(61)
++#define M_BCM1480_MC_ECC_UERR_DET           _SB_MAKEMASK1(62)
++#define M_BCM1480_MC_ECC_CERR_DET           _SB_MAKEMASK1(63)
++
++/*
++ * Global ECC Address Register (Table 102)
++ */
++
++#define S_BCM1480_MC_ECC_CORR_ADDR          0
++#define M_BCM1480_MC_ECC_CORR_ADDR          _SB_MAKEMASK(37,S_BCM1480_MC_ECC_CORR_ADDR)
++#define V_BCM1480_MC_ECC_CORR_ADDR(x)       _SB_MAKEVALUE(x,S_BCM1480_MC_ECC_CORR_ADDR)
++#define G_BCM1480_MC_ECC_CORR_ADDR(x)       _SB_GETVALUE(x,S_BCM1480_MC_ECC_CORR_ADDR,M_BCM1480_MC_ECC_CORR_ADDR)
++
++/*
++ * Global ECC Correction Register (Table 103)
++ */
++
++#define S_BCM1480_MC_ECC_CORRECT            0
++#define M_BCM1480_MC_ECC_CORRECT            _SB_MAKEMASK(64,S_BCM1480_MC_ECC_CORRECT)
++#define V_BCM1480_MC_ECC_CORRECT(x)         _SB_MAKEVALUE(x,S_BCM1480_MC_ECC_CORRECT)
++#define G_BCM1480_MC_ECC_CORRECT(x)         _SB_GETVALUE(x,S_BCM1480_MC_ECC_CORRECT,M_BCM1480_MC_ECC_CORRECT)
++
++/*
++ * Global ECC Performance Counters Control Register (Table 104)
++ */
++
++#define S_BCM1480_MC_CHANNEL_SELECT         0
++#define M_BCM1480_MC_CHANNEL_SELECT         _SB_MAKEMASK(4,S_BCM1480_MC_CHANNEL_SELECT)
++#define V_BCM1480_MC_CHANNEL_SELECT(x)      _SB_MAKEVALUE(x,S_BCM1480_MC_CHANNEL_SELECT)
++#define G_BCM1480_MC_CHANNEL_SELECT(x)      _SB_GETVALUE(x,S_BCM1480_MC_CHANNEL_SELECT,M_BCM1480_MC_CHANNEL_SELECT)
++#define K_BCM1480_MC_CHANNEL_SELECT_0       0x1
++#define K_BCM1480_MC_CHANNEL_SELECT_1       0x2
++#define K_BCM1480_MC_CHANNEL_SELECT_2       0x4
++#define K_BCM1480_MC_CHANNEL_SELECT_3       0x8
++
++#endif /* _BCM1480_MC_H */
+diff --git a/include/asm-mips/sibyte/bcm1480_regs.h b/include/asm-mips/sibyte/bcm1480_regs.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/sibyte/bcm1480_regs.h
+@@ -0,0 +1,869 @@
++/*  *********************************************************************
++    *  BCM1255/BCM1280/BCM1455/BCM1480 Board Support Package
++    *
++    *  Register Definitions                     File: bcm1480_regs.h
++    *
++    *  This module contains the addresses of the on-chip peripherals
++    *  on the BCM1280 and BCM1480.
++    *
++    *  BCM1480 specification level:  1X55_1X80-UM100-D4 (11/24/03)
++    *
++    *********************************************************************
++    *
++    *  Copyright 2000,2001,2002,2003
++    *  Broadcom 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
++    ********************************************************************* */
++
++#ifndef _BCM1480_REGS_H
++#define _BCM1480_REGS_H
++
++#include "sb1250_defs.h"
++
++/*  *********************************************************************
++    *  Pull in the BCM1250's registers since a great deal of the 1480's
++    *  functions are the same as the BCM1250.
++    ********************************************************************* */
++
++#include "sb1250_regs.h"
++
++
++/*  *********************************************************************
++    *  Some general notes:
++    *
++    *  Register addresses are grouped by function and follow the order
++    *  of the User Manual.
++    *
++    *  For the most part, when there is more than one peripheral
++    *  of the same type on the SOC, the constants below will be
++    *  offsets from the base of each peripheral.  For example,
++    *  the MAC registers are described as offsets from the first
++    *  MAC register, and there will be a MAC_REGISTER() macro
++    *  to calculate the base address of a given MAC.
++    *
++    *  The information in this file is based on the BCM1X55/BCM1X80
++    *  User Manual, Document 1X55_1X80-UM100-R, 22/12/03.
++    *
++    *  This file is basically a "what's new" header file.  Since the
++    *  BCM1250 and the new BCM1480 (and derivatives) share many common
++    *  features, this file contains only what's new or changed from
++    *  the 1250.  (above, you can see that we include the 1250 symbols
++    *  to get the base functionality).
++    *
++    *  In software, be sure to use the correct symbols, particularly
++    *  for blocks that are different between the two chip families.
++    *  All BCM1480-specific symbols have _BCM1480_ in their names,
++    *  and all BCM1250-specific and "base" functions that are common in
++    *  both chips have no special names (this is for compatibility with
++    *  older include files).  Therefore, if you're working with the
++    *  SCD, which is very different on each chip, A_SCD_xxx implies
++    *  the BCM1250 version and A_BCM1480_SCD_xxx implies the BCM1480
++    *  version.
++    ********************************************************************* */
++
++
++/*  *********************************************************************
++    * Memory Controller Registers (Section 6)
++    ********************************************************************* */
++
++#define A_BCM1480_MC_BASE_0                 0x0010050000
++#define A_BCM1480_MC_BASE_1                 0x0010051000
++#define A_BCM1480_MC_BASE_2                 0x0010052000
++#define A_BCM1480_MC_BASE_3                 0x0010053000
++#define BCM1480_MC_REGISTER_SPACING         0x1000
++
++#define A_BCM1480_MC_BASE(ctlid)            (A_BCM1480_MC_BASE_0+(ctlid)*BCM1480_MC_REGISTER_SPACING)
++#define A_BCM1480_MC_REGISTER(ctlid,reg)    (A_BCM1480_MC_BASE(ctlid)+(reg))
++
++#define R_BCM1480_MC_CONFIG                 0x0000000100
++#define R_BCM1480_MC_CS_START               0x0000000120
++#define R_BCM1480_MC_CS_END                 0x0000000140
++#define S_BCM1480_MC_CS_STARTEND            24
++
++#define R_BCM1480_MC_CS01_ROW0              0x0000000180
++#define R_BCM1480_MC_CS01_ROW1              0x00000001A0
++#define R_BCM1480_MC_CS23_ROW0              0x0000000200
++#define R_BCM1480_MC_CS23_ROW1              0x0000000220
++#define R_BCM1480_MC_CS01_COL0              0x0000000280
++#define R_BCM1480_MC_CS01_COL1              0x00000002A0
++#define R_BCM1480_MC_CS23_COL0              0x0000000300
++#define R_BCM1480_MC_CS23_COL1              0x0000000320
++
++#define R_BCM1480_MC_CSX_BASE               0x0000000180
++#define R_BCM1480_MC_CSX_ROW0               0x0000000000   /* relative to CSX_BASE */
++#define R_BCM1480_MC_CSX_ROW1               0x0000000020   /* relative to CSX_BASE */
++#define R_BCM1480_MC_CSX_COL0               0x0000000100   /* relative to CSX_BASE */
++#define R_BCM1480_MC_CSX_COL1               0x0000000120   /* relative to CSX_BASE */
++#define BCM1480_MC_CSX_SPACING              0x0000000080   /* CS23 relative to CS01 */
++
++#define R_BCM1480_MC_CS01_BA                0x0000000380
++#define R_BCM1480_MC_CS23_BA                0x00000003A0
++#define R_BCM1480_MC_DRAMCMD                0x0000000400
++#define R_BCM1480_MC_DRAMMODE               0x0000000420
++#define R_BCM1480_MC_CLOCK_CFG              0x0000000440
++#define R_BCM1480_MC_MCLK_CFG               R_BCM1480_MC_CLOCK_CFG
++#define R_BCM1480_MC_TEST_DATA              0x0000000480
++#define R_BCM1480_MC_TEST_ECC               0x00000004A0
++#define R_BCM1480_MC_TIMING1                0x00000004C0
++#define R_BCM1480_MC_TIMING2                0x00000004E0
++#define R_BCM1480_MC_DLL_CFG                0x0000000500
++#define R_BCM1480_MC_DRIVE_CFG              0x0000000520
++
++#if SIBYTE_HDR_FEATURE(1480, PASS2)
++#define R_BCM1480_MC_ODT		    0x0000000460
++#define R_BCM1480_MC_ECC_STATUS		    0x0000000540
++#endif
++
++/* Global registers (single instance) */
++#define A_BCM1480_MC_GLB_CONFIG             0x0010054100
++#define A_BCM1480_MC_GLB_INTLV              0x0010054120
++#define A_BCM1480_MC_GLB_ECC_STATUS         0x0010054140
++#define A_BCM1480_MC_GLB_ECC_ADDR           0x0010054160
++#define A_BCM1480_MC_GLB_ECC_CORRECT        0x0010054180
++#define A_BCM1480_MC_GLB_PERF_CNT_CONTROL   0x00100541A0
++
++/*  *********************************************************************
++    * L2 Cache Control Registers (Section 5)
++    ********************************************************************* */
++
++#define A_BCM1480_L2_BASE                   0x0010040000
++
++#define A_BCM1480_L2_READ_TAG               0x0010040018
++#define A_BCM1480_L2_ECC_TAG                0x0010040038
++#define A_BCM1480_L2_MISC0_VALUE            0x0010040058
++#define A_BCM1480_L2_MISC1_VALUE            0x0010040078
++#define A_BCM1480_L2_MISC2_VALUE            0x0010040098
++#define A_BCM1480_L2_MISC_CONFIG            0x0010040040	/* x040 */
++#define A_BCM1480_L2_CACHE_DISABLE          0x0010040060	/* x060 */
++#define A_BCM1480_L2_MAKECACHEDISABLE(x)    (A_BCM1480_L2_CACHE_DISABLE | (((x)&0xF) << 12))
++#define A_BCM1480_L2_WAY_ENABLE_3_0         0x0010040080	/* x080 */
++#define A_BCM1480_L2_WAY_ENABLE_7_4         0x00100400A0	/* x0A0 */
++#define A_BCM1480_L2_MAKE_WAY_ENABLE_LO(x)  (A_BCM1480_L2_WAY_ENABLE_3_0 | (((x)&0xF) << 12))
++#define A_BCM1480_L2_MAKE_WAY_ENABLE_HI(x)  (A_BCM1480_L2_WAY_ENABLE_7_4 | (((x)&0xF) << 12))
++#define A_BCM1480_L2_MAKE_WAY_DISABLE_LO(x)  (A_BCM1480_L2_WAY_ENABLE_3_0 | (((~x)&0xF) << 12))
++#define A_BCM1480_L2_MAKE_WAY_DISABLE_HI(x)  (A_BCM1480_L2_WAY_ENABLE_7_4 | (((~x)&0xF) << 12))
++#define A_BCM1480_L2_WAY_LOCAL_3_0          0x0010040100	/* x100 */
++#define A_BCM1480_L2_WAY_LOCAL_7_4          0x0010040120	/* x120 */
++#define A_BCM1480_L2_WAY_REMOTE_3_0         0x0010040140	/* x140 */
++#define A_BCM1480_L2_WAY_REMOTE_7_4         0x0010040160	/* x160 */
++#define A_BCM1480_L2_WAY_AGENT_3_0          0x00100400C0	/* xxC0 */
++#define A_BCM1480_L2_WAY_AGENT_7_4          0x00100400E0	/* xxE0 */
++#define A_BCM1480_L2_WAY_ENABLE(A, banks)   (A | (((~(banks))&0x0F) << 8))
++#define A_BCM1480_L2_BANK_BASE              0x00D0300000
++#define A_BCM1480_L2_BANK_ADDRESS(b)        (A_BCM1480_L2_BANK_BASE | (((b)&0x7)<<17))
++#define A_BCM1480_L2_MGMT_TAG_BASE          0x00D0000000
++
++
++/*  *********************************************************************
++    * PCI-X Interface Registers (Section 7)
++    ********************************************************************* */
++
++#define A_BCM1480_PCI_BASE                  0x0010061400
++
++#define A_BCM1480_PCI_RESET                 0x0010061400
++#define A_BCM1480_PCI_DLL                   0x0010061500
++
++#define A_BCM1480_PCI_TYPE00_HEADER         0x002E000000
++
++/*  *********************************************************************
++    * Ethernet MAC Registers (Section 11) and DMA Registers (Section 10.6)
++    ********************************************************************* */
++
++/* No register changes with Rev.C BCM1250, but one additional MAC */
++
++#define A_BCM1480_MAC_BASE_2        0x0010066000
++
++#ifndef A_MAC_BASE_2
++#define A_MAC_BASE_2                A_BCM1480_MAC_BASE_2
++#endif
++
++#define A_BCM1480_MAC_BASE_3        0x0010067000
++#define A_MAC_BASE_3                A_BCM1480_MAC_BASE_3
++
++#define R_BCM1480_MAC_DMA_OODPKTLOST        0x00000038
++
++#ifndef R_MAC_DMA_OODPKTLOST
++#define R_MAC_DMA_OODPKTLOST        R_BCM1480_MAC_DMA_OODPKTLOST
++#endif
++
++
++/*  *********************************************************************
++    * DUART Registers (Section 14)
++    ********************************************************************* */
++
++/* No significant differences from BCM1250, two DUARTs */
++
++/*  Conventions, per user manual:
++ *     DUART    generic, channels A,B,C,D
++ *     DUART0   implementing channels A,B
++ *     DUART1   inplementing channels C,D
++ */
++
++#define BCM1480_DUART_NUM_PORTS           4
++
++#define A_BCM1480_DUART0                    0x0010060000
++#define A_BCM1480_DUART1                    0x0010060400
++#define A_BCM1480_DUART(chan)               ((((chan)&2) == 0)? A_BCM1480_DUART0 : A_BCM1480_DUART1)
++
++#define BCM1480_DUART_CHANREG_SPACING       0x100
++#define A_BCM1480_DUART_CHANREG(chan,reg)   (A_BCM1480_DUART(chan) \
++                                     + BCM1480_DUART_CHANREG_SPACING*((chan)&1) \
++                                     + (reg))
++#define R_BCM1480_DUART_CHANREG(chan,reg)   (BCM1480_DUART_CHANREG_SPACING*((chan)&1) + (reg))
++
++#define R_BCM1480_DUART_IMRREG(chan)	    (R_DUART_IMR_A + ((chan)&1)*DUART_IMRISR_SPACING)
++#define R_BCM1480_DUART_ISRREG(chan)	    (R_DUART_ISR_A + ((chan)&1)*DUART_IMRISR_SPACING)
++
++#define A_BCM1480_DUART_IMRREG(chan)	    (A_BCM1480_DUART(chan) + R_BCM1480_DUART_IMRREG(chan))
++#define A_BCM1480_DUART_ISRREG(chan)	    (A_BCM1480_DUART(chan) + R_BCM1480_DUART_ISRREG(chan))
++
++/*
++ * These constants are the absolute addresses.
++ */
++
++#define A_BCM1480_DUART_MODE_REG_1_C        0x0010060400
++#define A_BCM1480_DUART_MODE_REG_2_C        0x0010060410
++#define A_BCM1480_DUART_STATUS_C            0x0010060420
++#define A_BCM1480_DUART_CLK_SEL_C           0x0010060430
++#define A_BCM1480_DUART_FULL_CTL_C          0x0010060440
++#define A_BCM1480_DUART_CMD_C               0x0010060450
++#define A_BCM1480_DUART_RX_HOLD_C           0x0010060460
++#define A_BCM1480_DUART_TX_HOLD_C           0x0010060470
++#define A_BCM1480_DUART_OPCR_C              0x0010060480
++#define A_BCM1480_DUART_AUX_CTRL_C          0x0010060490
++
++#define A_BCM1480_DUART_MODE_REG_1_D        0x0010060500
++#define A_BCM1480_DUART_MODE_REG_2_D        0x0010060510
++#define A_BCM1480_DUART_STATUS_D            0x0010060520
++#define A_BCM1480_DUART_CLK_SEL_D           0x0010060530
++#define A_BCM1480_DUART_FULL_CTL_D          0x0010060540
++#define A_BCM1480_DUART_CMD_D               0x0010060550
++#define A_BCM1480_DUART_RX_HOLD_D           0x0010060560
++#define A_BCM1480_DUART_TX_HOLD_D           0x0010060570
++#define A_BCM1480_DUART_OPCR_D              0x0010060580
++#define A_BCM1480_DUART_AUX_CTRL_D          0x0010060590
++
++#define A_BCM1480_DUART_INPORT_CHNG_CD      0x0010060600
++#define A_BCM1480_DUART_AUX_CTRL_CD         0x0010060610
++#define A_BCM1480_DUART_ISR_C               0x0010060620
++#define A_BCM1480_DUART_IMR_C               0x0010060630
++#define A_BCM1480_DUART_ISR_D               0x0010060640
++#define A_BCM1480_DUART_IMR_D               0x0010060650
++#define A_BCM1480_DUART_OUT_PORT_CD         0x0010060660
++#define A_BCM1480_DUART_OPCR_CD             0x0010060670
++#define A_BCM1480_DUART_IN_PORT_CD          0x0010060680
++#define A_BCM1480_DUART_ISR_CD              0x0010060690
++#define A_BCM1480_DUART_IMR_CD              0x00100606A0
++#define A_BCM1480_DUART_SET_OPR_CD          0x00100606B0
++#define A_BCM1480_DUART_CLEAR_OPR_CD        0x00100606C0
++#define A_BCM1480_DUART_INPORT_CHNG_C       0x00100606D0
++#define A_BCM1480_DUART_INPORT_CHNG_D       0x00100606E0
++
++
++/*  *********************************************************************
++    * Generic Bus Registers (Section 15) and PCMCIA Registers (Section 16)
++    ********************************************************************* */
++
++#define A_BCM1480_IO_PCMCIA_CFG_B	0x0010061A58
++#define A_BCM1480_IO_PCMCIA_STATUS_B	0x0010061A68
++
++/*  *********************************************************************
++    * GPIO Registers (Section 17)
++    ********************************************************************* */
++
++/* One additional GPIO register, placed _before_ the BCM1250's GPIO block base */
++
++#define A_BCM1480_GPIO_INT_ADD_TYPE         0x0010061A78
++#define R_BCM1480_GPIO_INT_ADD_TYPE         (-8)
++
++#define A_GPIO_INT_ADD_TYPE	A_BCM1480_GPIO_INT_ADD_TYPE
++#define R_GPIO_INT_ADD_TYPE	R_BCM1480_GPIO_INT_ADD_TYPE
++
++/*  *********************************************************************
++    * SMBus Registers (Section 18)
++    ********************************************************************* */
++
++/* No changes from BCM1250 */
++
++/*  *********************************************************************
++    * Timer Registers (Sections 4.6)
++    ********************************************************************* */
++
++/* BCM1480 has two additional watchdogs */
++
++/* Watchdog timers */
++
++#define A_BCM1480_SCD_WDOG_2                0x0010022050
++#define A_BCM1480_SCD_WDOG_3                0x0010022150
++
++#define BCM1480_SCD_NUM_WDOGS               4
++
++#define A_BCM1480_SCD_WDOG_BASE(w)       (A_BCM1480_SCD_WDOG_0+((w)&2)*0x1000 + ((w)&1)*0x100)
++#define A_BCM1480_SCD_WDOG_REGISTER(w,r) (A_BCM1480_SCD_WDOG_BASE(w) + (r))
++
++#define A_BCM1480_SCD_WDOG_INIT_2       0x0010022050
++#define A_BCM1480_SCD_WDOG_CNT_2        0x0010022058
++#define A_BCM1480_SCD_WDOG_CFG_2        0x0010022060
++
++#define A_BCM1480_SCD_WDOG_INIT_3       0x0010022150
++#define A_BCM1480_SCD_WDOG_CNT_3        0x0010022158
++#define A_BCM1480_SCD_WDOG_CFG_3        0x0010022160
++
++/* BCM1480 has two additional compare registers */
++
++#define A_BCM1480_SCD_ZBBUS_CYCLE_COUNT		A_SCD_ZBBUS_CYCLE_COUNT
++#define A_BCM1480_SCD_ZBBUS_CYCLE_CP_BASE       0x0010020C00
++#define A_BCM1480_SCD_ZBBUS_CYCLE_CP0           A_SCD_ZBBUS_CYCLE_CP0
++#define A_BCM1480_SCD_ZBBUS_CYCLE_CP1           A_SCD_ZBBUS_CYCLE_CP1
++#define A_BCM1480_SCD_ZBBUS_CYCLE_CP2           0x0010020C10
++#define A_BCM1480_SCD_ZBBUS_CYCLE_CP3           0x0010020C18
++
++/*  *********************************************************************
++    * System Control Registers (Section 4.2)
++    ********************************************************************* */
++
++/* Scratch register in different place */
++
++#define A_BCM1480_SCD_SCRATCH	 	0x100200A0
++
++/*  *********************************************************************
++    * System Address Trap Registers (Section 4.9)
++    ********************************************************************* */
++
++/* No changes from BCM1250 */
++
++/*  *********************************************************************
++    * System Interrupt Mapper Registers (Sections 4.3-4.5)
++    ********************************************************************* */
++
++#define A_BCM1480_IMR_CPU0_BASE             0x0010020000
++#define A_BCM1480_IMR_CPU1_BASE             0x0010022000
++#define A_BCM1480_IMR_CPU2_BASE             0x0010024000
++#define A_BCM1480_IMR_CPU3_BASE             0x0010026000
++#define BCM1480_IMR_REGISTER_SPACING        0x2000
++#define BCM1480_IMR_REGISTER_SPACING_SHIFT  13
++
++#define A_BCM1480_IMR_MAPPER(cpu)       (A_BCM1480_IMR_CPU0_BASE+(cpu)*BCM1480_IMR_REGISTER_SPACING)
++#define A_BCM1480_IMR_REGISTER(cpu,reg) (A_BCM1480_IMR_MAPPER(cpu)+(reg))
++
++/* Most IMR registers are 128 bits, implemented as non-contiguous
++   64-bit registers high (_H) and low (_L) */
++#define BCM1480_IMR_HL_SPACING                  0x1000
++
++#define R_BCM1480_IMR_INTERRUPT_DIAG_H          0x0010
++#define R_BCM1480_IMR_LDT_INTERRUPT_H           0x0018
++#define R_BCM1480_IMR_LDT_INTERRUPT_CLR_H       0x0020
++#define R_BCM1480_IMR_INTERRUPT_MASK_H          0x0028
++#define R_BCM1480_IMR_INTERRUPT_TRACE_H         0x0038
++#define R_BCM1480_IMR_INTERRUPT_SOURCE_STATUS_H 0x0040
++#define R_BCM1480_IMR_LDT_INTERRUPT_SET         0x0048
++#define R_BCM1480_IMR_MAILBOX_0_CPU             0x00C0
++#define R_BCM1480_IMR_MAILBOX_0_SET_CPU         0x00C8
++#define R_BCM1480_IMR_MAILBOX_0_CLR_CPU         0x00D0
++#define R_BCM1480_IMR_MAILBOX_1_CPU             0x00E0
++#define R_BCM1480_IMR_MAILBOX_1_SET_CPU         0x00E8
++#define R_BCM1480_IMR_MAILBOX_1_CLR_CPU         0x00F0
++#define R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H   0x0100
++#define BCM1480_IMR_INTERRUPT_STATUS_COUNT      8
++#define R_BCM1480_IMR_INTERRUPT_MAP_BASE_H      0x0200
++#define BCM1480_IMR_INTERRUPT_MAP_COUNT         64
++
++#define R_BCM1480_IMR_INTERRUPT_DIAG_L          0x1010
++#define R_BCM1480_IMR_LDT_INTERRUPT_L           0x1018
++#define R_BCM1480_IMR_LDT_INTERRUPT_CLR_L       0x1020
++#define R_BCM1480_IMR_INTERRUPT_MASK_L          0x1028
++#define R_BCM1480_IMR_INTERRUPT_TRACE_L         0x1038
++#define R_BCM1480_IMR_INTERRUPT_SOURCE_STATUS_L 0x1040
++#define R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L   0x1100
++#define R_BCM1480_IMR_INTERRUPT_MAP_BASE_L      0x1200
++
++#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU0_BASE   0x0010028000
++#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU1_BASE   0x0010028100
++#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU2_BASE   0x0010028200
++#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU3_BASE   0x0010028300
++#define BCM1480_IMR_ALIAS_MAILBOX_SPACING       0100
++
++#define A_BCM1480_IMR_ALIAS_MAILBOX(cpu)     (A_BCM1480_IMR_ALIAS_MAILBOX_CPU0_BASE + \
++                                        (cpu)*BCM1480_IMR_ALIAS_MAILBOX_SPACING)
++#define A_BCM1480_IMR_ALIAS_MAILBOX_REGISTER(cpu,reg) (A_BCM1480_IMR_ALIAS_MAILBOX(cpu)+(reg))
++
++#define R_BCM1480_IMR_ALIAS_MAILBOX_0           0x0000		/* 0x0x0 */
++#define R_BCM1480_IMR_ALIAS_MAILBOX_0_SET       0x0008		/* 0x0x8 */
++
++/*  *********************************************************************
++    * System Performance Counter Registers (Section 4.7)
++    ********************************************************************* */
++
++/* BCM1480 has four more performance counter registers, and two control
++   registers. */
++
++#define A_BCM1480_SCD_PERF_CNT_BASE         0x00100204C0
++
++#define A_BCM1480_SCD_PERF_CNT_CFG0         0x00100204C0
++#define A_BCM1480_SCD_PERF_CNT_CFG_0        A_BCM1480_SCD_PERF_CNT_CFG0
++#define A_BCM1480_SCD_PERF_CNT_CFG1         0x00100204C8
++#define A_BCM1480_SCD_PERF_CNT_CFG_1        A_BCM1480_SCD_PERF_CNT_CFG1
++
++#define A_BCM1480_SCD_PERF_CNT_0            A_SCD_PERF_CNT_0
++#define A_BCM1480_SCD_PERF_CNT_1            A_SCD_PERF_CNT_1
++#define A_BCM1480_SCD_PERF_CNT_2            A_SCD_PERF_CNT_2
++#define A_BCM1480_SCD_PERF_CNT_3            A_SCD_PERF_CNT_3
++
++#define A_BCM1480_SCD_PERF_CNT_4            0x00100204F0
++#define A_BCM1480_SCD_PERF_CNT_5            0x00100204F8
++#define A_BCM1480_SCD_PERF_CNT_6            0x0010020500
++#define A_BCM1480_SCD_PERF_CNT_7            0x0010020508
++
++/*  *********************************************************************
++    * System Bus Watcher Registers (Section 4.8)
++    ********************************************************************* */
++
++
++/* Same as 1250 except BUS_ERR_STATUS_DEBUG is in a different place. */
++
++#define A_BCM1480_BUS_ERR_STATUS_DEBUG      0x00100208D8
++
++/*  *********************************************************************
++    * System Debug Controller Registers (Section 19)
++    ********************************************************************* */
++
++/* Same as 1250 */
++
++/*  *********************************************************************
++    * System Trace Unit Registers (Sections 4.10)
++    ********************************************************************* */
++
++/* Same as 1250 */
++
++/*  *********************************************************************
++    * Data Mover DMA Registers (Section 10.7)
++    ********************************************************************* */
++
++/* Same as 1250 */
++
++
++/*  *********************************************************************
++    * HyperTransport Interface Registers (Section 8)
++    ********************************************************************* */
++
++#define BCM1480_HT_NUM_PORTS		   3
++#define BCM1480_HT_PORT_SPACING		   0x800
++#define A_BCM1480_HT_PORT_HEADER(x)	   (A_BCM1480_HT_PORT0_HEADER + ((x)*BCM1480_HT_PORT_SPACING))
++
++#define A_BCM1480_HT_PORT0_HEADER          0x00FE000000
++#define A_BCM1480_HT_PORT1_HEADER          0x00FE000800
++#define A_BCM1480_HT_PORT2_HEADER          0x00FE001000
++#define A_BCM1480_HT_TYPE00_HEADER         0x00FE002000
++
++
++/*  *********************************************************************
++    * Node Controller Registers (Section 9)
++    ********************************************************************* */
++
++#define A_BCM1480_NC_BASE                   0x00DFBD0000
++
++#define A_BCM1480_NC_RLD_FIELD              0x00DFBD0000
++#define A_BCM1480_NC_RLD_TRIGGER            0x00DFBD0020
++#define A_BCM1480_NC_RLD_BAD_ERROR          0x00DFBD0040
++#define A_BCM1480_NC_RLD_COR_ERROR          0x00DFBD0060
++#define A_BCM1480_NC_RLD_ECC_STATUS         0x00DFBD0080
++#define A_BCM1480_NC_RLD_WAY_ENABLE         0x00DFBD00A0
++#define A_BCM1480_NC_RLD_RANDOM_LFSR        0x00DFBD00C0
++
++#define A_BCM1480_NC_INTERRUPT_STATUS       0x00DFBD00E0
++#define A_BCM1480_NC_INTERRUPT_ENABLE       0x00DFBD0100
++#define A_BCM1480_NC_TIMEOUT_COUNTER        0x00DFBD0120
++#define A_BCM1480_NC_TIMEOUT_COUNTER_SEL    0x00DFBD0140
++
++#define A_BCM1480_NC_CREDIT_STATUS_REG0     0x00DFBD0200
++#define A_BCM1480_NC_CREDIT_STATUS_REG1     0x00DFBD0220
++#define A_BCM1480_NC_CREDIT_STATUS_REG2     0x00DFBD0240
++#define A_BCM1480_NC_CREDIT_STATUS_REG3     0x00DFBD0260
++#define A_BCM1480_NC_CREDIT_STATUS_REG4     0x00DFBD0280
++#define A_BCM1480_NC_CREDIT_STATUS_REG5     0x00DFBD02A0
++#define A_BCM1480_NC_CREDIT_STATUS_REG6     0x00DFBD02C0
++#define A_BCM1480_NC_CREDIT_STATUS_REG7     0x00DFBD02E0
++#define A_BCM1480_NC_CREDIT_STATUS_REG8     0x00DFBD0300
++#define A_BCM1480_NC_CREDIT_STATUS_REG9     0x00DFBD0320
++#define A_BCM1480_NC_CREDIT_STATUS_REG10    0x00DFBE0000
++#define A_BCM1480_NC_CREDIT_STATUS_REG11    0x00DFBE0020
++#define A_BCM1480_NC_CREDIT_STATUS_REG12    0x00DFBE0040
++
++#define A_BCM1480_NC_SR_TIMEOUT_COUNTER     0x00DFBE0060
++#define A_BCM1480_NC_SR_TIMEOUT_COUNTER_SEL 0x00DFBE0080
++
++
++/*  *********************************************************************
++    * H&R Block Configuration Registers (Section 12.4)
++    ********************************************************************* */
++
++#define A_BCM1480_HR_BASE_0                 0x00DF820000
++#define A_BCM1480_HR_BASE_1                 0x00DF8A0000
++#define A_BCM1480_HR_BASE_2                 0x00DF920000
++#define BCM1480_HR_REGISTER_SPACING         0x80000
++
++#define A_BCM1480_HR_BASE(idx)              (A_BCM1480_HR_BASE_0 + ((idx)*BCM1480_HR_REGISTER_SPACING))
++#define A_BCM1480_HR_REGISTER(idx,reg)      (A_BCM1480_HR_BASE(idx) + (reg))
++
++#define R_BCM1480_HR_CFG                    0x0000000000
++
++#define R_BCM1480_HR_MAPPING		    0x0000010010
++
++#define BCM1480_HR_RULE_SPACING             0x0000000010
++#define BCM1480_HR_NUM_RULES                16
++#define BCM1480_HR_OP_OFFSET                0x0000000100
++#define BCM1480_HR_TYPE_OFFSET              0x0000000108
++#define R_BCM1480_HR_RULE_OP(idx)           (BCM1480_HR_OP_OFFSET + ((idx)*BCM1480_HR_RULE_SPACING))
++#define R_BCM1480_HR_RULE_TYPE(idx)         (BCM1480_HR_TYPE_OFFSET + ((idx)*BCM1480_HR_RULE_SPACING))
++
++#define BCM1480_HR_LEAF_SPACING             0x0000000010
++#define BCM1480_HR_NUM_LEAVES               10
++#define BCM1480_HR_LEAF_OFFSET              0x0000000300
++#define R_BCM1480_HR_HA_LEAF0(idx)          (BCM1480_HR_LEAF_OFFSET + ((idx)*BCM1480_HR_LEAF_SPACING))
++
++#define R_BCM1480_HR_EX_LEAF0               0x00000003A0
++
++#define BCM1480_HR_PATH_SPACING             0x0000000010
++#define BCM1480_HR_NUM_PATHS                16
++#define BCM1480_HR_PATH_OFFSET              0x0000000600
++#define R_BCM1480_HR_PATH(idx)              (BCM1480_HR_PATH_OFFSET + ((idx)*BCM1480_HR_PATH_SPACING))
++
++#define R_BCM1480_HR_PATH_DEFAULT           0x0000000700
++
++#define BCM1480_HR_ROUTE_SPACING            8
++#define BCM1480_HR_NUM_ROUTES               512
++#define BCM1480_HR_ROUTE_OFFSET             0x0000001000
++#define R_BCM1480_HR_RT_WORD(idx)           (BCM1480_HR_ROUTE_OFFSET + ((idx)*BCM1480_HR_ROUTE_SPACING))
++
++
++/* checked to here - ehs */
++/*  *********************************************************************
++    * Packet Manager DMA Registers (Section 12.5)
++    ********************************************************************* */
++
++#define A_BCM1480_PM_BASE                   0x0010056000
++
++#define A_BCM1480_PMI_LCL_0                 0x0010058000
++#define A_BCM1480_PMO_LCL_0                 0x001005C000
++#define A_BCM1480_PMI_OFFSET_0              (A_BCM1480_PMI_LCL_0 - A_BCM1480_PM_BASE)
++#define A_BCM1480_PMO_OFFSET_0              (A_BCM1480_PMO_LCL_0 - A_BCM1480_PM_BASE)
++
++#define BCM1480_PM_LCL_REGISTER_SPACING     0x100
++#define BCM1480_PM_NUM_CHANNELS             32
++
++#define A_BCM1480_PMI_LCL_BASE(idx)             (A_BCM1480_PMI_LCL_0 + ((idx)*BCM1480_PM_LCL_REGISTER_SPACING))
++#define A_BCM1480_PMI_LCL_REGISTER(idx,reg)     (A_BCM1480_PMI_LCL_BASE(idx) + (reg))
++#define A_BCM1480_PMO_LCL_BASE(idx)             (A_BCM1480_PMO_LCL_0 + ((idx)*BCM1480_PM_LCL_REGISTER_SPACING))
++#define A_BCM1480_PMO_LCL_REGISTER(idx,reg)     (A_BCM1480_PMO_LCL_BASE(idx) + (reg))
++
++#define BCM1480_PM_INT_PACKING              8
++#define BCM1480_PM_INT_FUNCTION_SPACING     0x40
++#define BCM1480_PM_INT_NUM_FUNCTIONS        3
++
++/*
++ * DMA channel registers relative to A_BCM1480_PMI_LCL_BASE(n) and A_BCM1480_PMO_LCL_BASE(n)
++ */
++
++#define R_BCM1480_PM_BASE_SIZE              0x0000000000
++#define R_BCM1480_PM_CNT                    0x0000000008
++#define R_BCM1480_PM_PFCNT                  0x0000000010
++#define R_BCM1480_PM_LAST                   0x0000000018
++#define R_BCM1480_PM_PFINDX                 0x0000000020
++#define R_BCM1480_PM_INT_WMK                0x0000000028
++#define R_BCM1480_PM_CONFIG0                0x0000000030
++#define R_BCM1480_PM_LOCALDEBUG             0x0000000078
++#define R_BCM1480_PM_CACHEABILITY           0x0000000080   /* PMI only */
++#define R_BCM1480_PM_INT_CNFG               0x0000000088
++#define R_BCM1480_PM_DESC_MERGE_TIMER       0x0000000090
++#define R_BCM1480_PM_LOCALDEBUG_PIB         0x00000000F8   /* PMI only */
++#define R_BCM1480_PM_LOCALDEBUG_POB         0x00000000F8   /* PMO only */
++
++/*
++ * Global Registers (Not Channelized)
++ */
++
++#define A_BCM1480_PMI_GLB_0                 0x0010056000
++#define A_BCM1480_PMO_GLB_0                 0x0010057000
++
++/*
++ * PM to TX Mapping Register relative to A_BCM1480_PMI_GLB_0 and A_BCM1480_PMO_GLB_0
++ */
++
++#define R_BCM1480_PM_PMO_MAPPING            0x00000008C8   /* PMO only */
++
++#define A_BCM1480_PM_PMO_MAPPING	(A_BCM1480_PMO_GLB_0 + R_BCM1480_PM_PMO_MAPPING)
++
++/*
++ * Interrupt mapping registers
++ */
++
++
++#define A_BCM1480_PMI_INT_0                 0x0010056800
++#define A_BCM1480_PMI_INT(q)                (A_BCM1480_PMI_INT_0 + ((q>>8)<<8))
++#define A_BCM1480_PMI_INT_OFFSET_0          (A_BCM1480_PMI_INT_0 - A_BCM1480_PM_BASE)
++#define A_BCM1480_PMO_INT_0                 0x0010057800
++#define A_BCM1480_PMO_INT(q)                (A_BCM1480_PMO_INT_0 + ((q>>8)<<8))
++#define A_BCM1480_PMO_INT_OFFSET_0          (A_BCM1480_PMO_INT_0 - A_BCM1480_PM_BASE)
++
++/*
++ * Interrupt registers relative to A_BCM1480_PMI_INT_0 and A_BCM1480_PMO_INT_0
++ */
++
++#define R_BCM1480_PM_INT_ST                 0x0000000000
++#define R_BCM1480_PM_INT_MSK                0x0000000040
++#define R_BCM1480_PM_INT_CLR                0x0000000080
++#define R_BCM1480_PM_MRGD_INT               0x00000000C0
++
++/*
++ * Debug registers (global)
++ */
++
++#define A_BCM1480_PM_GLOBALDEBUGMODE_PMI    0x0010056000
++#define A_BCM1480_PM_GLOBALDEBUG_PID        0x00100567F8
++#define A_BCM1480_PM_GLOBALDEBUG_PIB        0x0010056FF8
++#define A_BCM1480_PM_GLOBALDEBUGMODE_PMO    0x0010057000
++#define A_BCM1480_PM_GLOBALDEBUG_POD        0x00100577F8
++#define A_BCM1480_PM_GLOBALDEBUG_POB        0x0010057FF8
++
++/*  *********************************************************************
++    *  Switch performance counters
++    ********************************************************************* */
++
++#define A_BCM1480_SWPERF_CFG	0xdfb91800
++#define A_BCM1480_SWPERF_CNT0	0xdfb91880
++#define A_BCM1480_SWPERF_CNT1	0xdfb91888
++#define A_BCM1480_SWPERF_CNT2	0xdfb91890
++#define A_BCM1480_SWPERF_CNT3	0xdfb91898
++
++
++/*  *********************************************************************
++    *  Switch Trace Unit
++    ********************************************************************* */
++
++#define A_BCM1480_SWTRC_MATCH_CONTROL_0		0xDFB91000
++#define A_BCM1480_SWTRC_MATCH_DATA_VALUE_0	0xDFB91100
++#define A_BCM1480_SWTRC_MATCH_DATA_MASK_0	0xDFB91108
++#define A_BCM1480_SWTRC_MATCH_TAG_VALUE_0	0xDFB91200
++#define A_BCM1480_SWTRC_MATCH_TAG_MAKS_0	0xDFB91208
++#define A_BCM1480_SWTRC_EVENT_0			0xDFB91300
++#define A_BCM1480_SWTRC_SEQUENCE_0		0xDFB91400
++
++#define A_BCM1480_SWTRC_CFG			0xDFB91500
++#define A_BCM1480_SWTRC_READ			0xDFB91508
++
++#define A_BCM1480_SWDEBUG_SCHEDSTOP		0xDFB92000
++
++#define A_BCM1480_SWTRC_MATCH_CONTROL(x) (A_BCM1480_SWTRC_MATCH_CONTROL_0 + ((x)*8))
++#define A_BCM1480_SWTRC_EVENT(x) (A_BCM1480_SWTRC_EVENT_0 + ((x)*8))
++#define A_BCM1480_SWTRC_SEQUENCE(x) (A_BCM1480_SWTRC_SEQUENCE_0 + ((x)*8))
++
++#define A_BCM1480_SWTRC_MATCH_DATA_VALUE(x) (A_BCM1480_SWTRC_MATCH_DATA_VALUE_0 + ((x)*16))
++#define A_BCM1480_SWTRC_MATCH_DATA_MASK(x) (A_BCM1480_SWTRC_MATCH_DATA_MASK_0 + ((x)*16))
++#define A_BCM1480_SWTRC_MATCH_TAG_VALUE(x) (A_BCM1480_SWTRC_MATCH_TAG_VALUE_0 + ((x)*16))
++#define A_BCM1480_SWTRC_MATCH_TAG_MASK(x) (A_BCM1480_SWTRC_MATCH_TAG_MASK_0 + ((x)*16))
++
++
++
++/*  *********************************************************************
++    *  High-Speed Port Registers (Section 13)
++    ********************************************************************* */
++
++#define A_BCM1480_HSP_BASE_0                0x00DF810000
++#define A_BCM1480_HSP_BASE_1                0x00DF890000
++#define A_BCM1480_HSP_BASE_2                0x00DF910000
++#define BCM1480_HSP_REGISTER_SPACING        0x80000
++
++#define A_BCM1480_HSP_BASE(idx)             (A_BCM1480_HSP_BASE_0 + ((idx)*BCM1480_HSP_REGISTER_SPACING))
++#define A_BCM1480_HSP_REGISTER(idx,reg)     (A_BCM1480_HSP_BASE(idx) + (reg))
++
++#define R_BCM1480_HSP_RX_SPI4_CFG_0           0x0000000000
++#define R_BCM1480_HSP_RX_SPI4_CFG_1           0x0000000008
++#define R_BCM1480_HSP_RX_SPI4_DESKEW_OVERRIDE 0x0000000010
++#define R_BCM1480_HSP_RX_SPI4_DESKEW_DATAPATH 0x0000000018
++#define R_BCM1480_HSP_RX_SPI4_PORT_INT_EN     0x0000000020
++#define R_BCM1480_HSP_RX_SPI4_PORT_INT_STATUS 0x0000000028
++
++#define R_BCM1480_HSP_RX_SPI4_CALENDAR_0      0x0000000200
++#define R_BCM1480_HSP_RX_SPI4_CALENDAR_1      0x0000000208
++
++#define R_BCM1480_HSP_RX_PLL_CNFG             0x0000000800
++#define R_BCM1480_HSP_RX_CALIBRATION          0x0000000808
++#define R_BCM1480_HSP_RX_TEST                 0x0000000810
++#define R_BCM1480_HSP_RX_DIAG_DETAILS         0x0000000818
++#define R_BCM1480_HSP_RX_DIAG_CRC_0           0x0000000820
++#define R_BCM1480_HSP_RX_DIAG_CRC_1           0x0000000828
++#define R_BCM1480_HSP_RX_DIAG_HTCMD           0x0000000830
++#define R_BCM1480_HSP_RX_DIAG_PKTCTL          0x0000000838
++
++#define R_BCM1480_HSP_RX_VIS_FLCTRL_COUNTER   0x0000000870
++
++#define R_BCM1480_HSP_RX_PKT_RAMALLOC_0       0x0000020020
++#define R_BCM1480_HSP_RX_PKT_RAMALLOC_1       0x0000020028
++#define R_BCM1480_HSP_RX_PKT_RAMALLOC_2       0x0000020030
++#define R_BCM1480_HSP_RX_PKT_RAMALLOC_3       0x0000020038
++#define R_BCM1480_HSP_RX_PKT_RAMALLOC_4       0x0000020040
++#define R_BCM1480_HSP_RX_PKT_RAMALLOC_5       0x0000020048
++#define R_BCM1480_HSP_RX_PKT_RAMALLOC_6       0x0000020050
++#define R_BCM1480_HSP_RX_PKT_RAMALLOC_7       0x0000020058
++#define R_BCM1480_HSP_RX_PKT_RAMALLOC(idx)    (R_BCM1480_HSP_RX_PKT_RAMALLOC_0 + 8*(idx))
++
++/* XXX Following registers were shuffled.  Renamed/renumbered per errata. */
++#define R_BCM1480_HSP_RX_HT_RAMALLOC_0      0x0000020078
++#define R_BCM1480_HSP_RX_HT_RAMALLOC_1      0x0000020080
++#define R_BCM1480_HSP_RX_HT_RAMALLOC_2      0x0000020088
++#define R_BCM1480_HSP_RX_HT_RAMALLOC_3      0x0000020090
++#define R_BCM1480_HSP_RX_HT_RAMALLOC_4      0x0000020098
++#define R_BCM1480_HSP_RX_HT_RAMALLOC_5      0x00000200A0
++
++#define R_BCM1480_HSP_RX_SPI_WATERMARK_0      0x00000200B0
++#define R_BCM1480_HSP_RX_SPI_WATERMARK_1      0x00000200B8
++#define R_BCM1480_HSP_RX_SPI_WATERMARK_2      0x00000200C0
++#define R_BCM1480_HSP_RX_SPI_WATERMARK_3      0x00000200C8
++#define R_BCM1480_HSP_RX_SPI_WATERMARK_4      0x00000200D0
++#define R_BCM1480_HSP_RX_SPI_WATERMARK_5      0x00000200D8
++#define R_BCM1480_HSP_RX_SPI_WATERMARK_6      0x00000200E0
++#define R_BCM1480_HSP_RX_SPI_WATERMARK_7      0x00000200E8
++#define R_BCM1480_HSP_RX_SPI_WATERMARK(idx)   (R_BCM1480_HSP_RX_SPI_WATERMARK_0 + 8*(idx))
++
++#define R_BCM1480_HSP_RX_VIS_CMDQ_0           0x00000200F0
++#define R_BCM1480_HSP_RX_VIS_CMDQ_1           0x00000200F8
++#define R_BCM1480_HSP_RX_VIS_CMDQ_2           0x0000020100
++#define R_BCM1480_HSP_RX_RAM_READCTL          0x0000020108
++#define R_BCM1480_HSP_RX_RAM_READWINDOW       0x0000020110
++#define R_BCM1480_HSP_RX_RF_READCTL           0x0000020118
++#define R_BCM1480_HSP_RX_RF_READWINDOW        0x0000020120
++
++#define R_BCM1480_HSP_TX_SPI4_CFG_0           0x0000040000
++#define R_BCM1480_HSP_TX_SPI4_CFG_1           0x0000040008
++#define R_BCM1480_HSP_TX_SPI4_TRAINING_FMT    0x0000040010
++
++#define R_BCM1480_HSP_TX_PKT_RAMALLOC_0       0x0000040020
++#define R_BCM1480_HSP_TX_PKT_RAMALLOC_1       0x0000040028
++#define R_BCM1480_HSP_TX_PKT_RAMALLOC_2       0x0000040030
++#define R_BCM1480_HSP_TX_PKT_RAMALLOC_3       0x0000040038
++#define R_BCM1480_HSP_TX_PKT_RAMALLOC_4       0x0000040040
++#define R_BCM1480_HSP_TX_PKT_RAMALLOC_5       0x0000040048
++#define R_BCM1480_HSP_TX_PKT_RAMALLOC_6       0x0000040050
++#define R_BCM1480_HSP_TX_PKT_RAMALLOC_7       0x0000040058
++#define R_BCM1480_HSP_TX_PKT_RAMALLOC(idx)    (R_BCM1480_HSP_TX_PKT_RAMALLOC_0 + 8*(idx))
++#define R_BCM1480_HSP_TX_NPC_RAMALLOC         0x0000040078
++#define R_BCM1480_HSP_TX_RSP_RAMALLOC         0x0000040080
++#define R_BCM1480_HSP_TX_PC_RAMALLOC          0x0000040088
++#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_0      0x0000040090
++#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_1      0x0000040098
++#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_2      0x00000400A0
++
++#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_0      0x00000400B0
++#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_1      0x00000400B8
++#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_2      0x00000400C0
++#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_3      0x00000400C8
++#define R_BCM1480_HSP_TX_PKT_RXPHITCNT(idx)   (R_BCM1480_HSP_TX_PKT_RXPHITCNT_0 + 8*(idx))
++#define R_BCM1480_HSP_TX_HTIO_RXPHITCNT       0x00000400D0
++#define R_BCM1480_HSP_TX_HTCC_RXPHITCNT       0x00000400D8
++
++#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_0      0x00000400E0
++#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_1      0x00000400E8
++#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_2      0x00000400F0
++#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_3      0x00000400F8
++#define R_BCM1480_HSP_TX_PKT_TXPHITCNT(idx)   (R_BCM1480_HSP_TX_PKT_TXPHITCNT_0 + 8*(idx))
++#define R_BCM1480_HSP_TX_HTIO_TXPHITCNT       0x0000040100
++#define R_BCM1480_HSP_TX_HTCC_TXPHITCNT       0x0000040108
++
++#define R_BCM1480_HSP_TX_SPI4_CALENDAR_0      0x0000040200
++#define R_BCM1480_HSP_TX_SPI4_CALENDAR_1      0x0000040208
++
++#define R_BCM1480_HSP_TX_PLL_CNFG             0x0000040800
++#define R_BCM1480_HSP_TX_CALIBRATION          0x0000040808
++#define R_BCM1480_HSP_TX_TEST                 0x0000040810
++
++#define R_BCM1480_HSP_TX_VIS_CMDQ_0           0x0000040840
++#define R_BCM1480_HSP_TX_VIS_CMDQ_1           0x0000040848
++#define R_BCM1480_HSP_TX_VIS_CMDQ_2           0x0000040850
++#define R_BCM1480_HSP_TX_RAM_READCTL          0x0000040860
++#define R_BCM1480_HSP_TX_RAM_READWINDOW       0x0000040868
++#define R_BCM1480_HSP_TX_RF_READCTL           0x0000040870
++#define R_BCM1480_HSP_TX_RF_READWINDOW        0x0000040878
++
++#define R_BCM1480_HSP_TX_SPI4_PORT_INT_STATUS 0x0000040880
++#define R_BCM1480_HSP_TX_SPI4_PORT_INT_EN     0x0000040888
++
++#define R_BCM1480_HSP_TX_NEXT_ADDR_BASE 0x000040400
++#define R_BCM1480_HSP_TX_NEXT_ADDR_REGISTER(x)  (R_BCM1480_HSP_TX_NEXT_ADDR_BASE+ 8*(x))
++
++
++
++/*  *********************************************************************
++    *  Physical Address Map (Table 10 and Figure 7)
++    ********************************************************************* */
++
++#define A_BCM1480_PHYS_MEMORY_0                 _SB_MAKE64(0x0000000000)
++#define A_BCM1480_PHYS_MEMORY_SIZE              _SB_MAKE64((256*1024*1024))
++#define A_BCM1480_PHYS_SYSTEM_CTL               _SB_MAKE64(0x0010000000)
++#define A_BCM1480_PHYS_IO_SYSTEM                _SB_MAKE64(0x0010060000)
++#define A_BCM1480_PHYS_GENBUS                   _SB_MAKE64(0x0010090000)
++#define A_BCM1480_PHYS_GENBUS_END               _SB_MAKE64(0x0028000000)
++#define A_BCM1480_PHYS_PCI_MISC_MATCH_BYTES     _SB_MAKE64(0x0028000000)
++#define A_BCM1480_PHYS_PCI_IACK_MATCH_BYTES     _SB_MAKE64(0x0029000000)
++#define A_BCM1480_PHYS_PCI_IO_MATCH_BYTES       _SB_MAKE64(0x002C000000)
++#define A_BCM1480_PHYS_PCI_CFG_MATCH_BYTES      _SB_MAKE64(0x002E000000)
++#define A_BCM1480_PHYS_PCI_OMAP_MATCH_BYTES     _SB_MAKE64(0x002F000000)
++#define A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES      _SB_MAKE64(0x0030000000)
++#define A_BCM1480_PHYS_HT_MEM_MATCH_BYTES       _SB_MAKE64(0x0040000000)
++#define A_BCM1480_PHYS_HT_MEM_MATCH_BITS        _SB_MAKE64(0x0060000000)
++#define A_BCM1480_PHYS_MEMORY_1                 _SB_MAKE64(0x0080000000)
++#define A_BCM1480_PHYS_MEMORY_2                 _SB_MAKE64(0x0090000000)
++#define A_BCM1480_PHYS_PCI_MISC_MATCH_BITS      _SB_MAKE64(0x00A8000000)
++#define A_BCM1480_PHYS_PCI_IACK_MATCH_BITS      _SB_MAKE64(0x00A9000000)
++#define A_BCM1480_PHYS_PCI_IO_MATCH_BITS        _SB_MAKE64(0x00AC000000)
++#define A_BCM1480_PHYS_PCI_CFG_MATCH_BITS       _SB_MAKE64(0x00AE000000)
++#define A_BCM1480_PHYS_PCI_OMAP_MATCH_BITS      _SB_MAKE64(0x00AF000000)
++#define A_BCM1480_PHYS_PCI_MEM_MATCH_BITS       _SB_MAKE64(0x00B0000000)
++#define A_BCM1480_PHYS_MEMORY_3                 _SB_MAKE64(0x00C0000000)
++#define A_BCM1480_PHYS_L2_CACHE_TEST            _SB_MAKE64(0x00D0000000)
++#define A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES   _SB_MAKE64(0x00D8000000)
++#define A_BCM1480_PHYS_HT_IO_MATCH_BYTES        _SB_MAKE64(0x00DC000000)
++#define A_BCM1480_PHYS_HT_CFG_MATCH_BYTES       _SB_MAKE64(0x00DE000000)
++#define A_BCM1480_PHYS_HS_SUBSYS                _SB_MAKE64(0x00DF000000)
++#define A_BCM1480_PHYS_HT_SPECIAL_MATCH_BITS    _SB_MAKE64(0x00F8000000)
++#define A_BCM1480_PHYS_HT_IO_MATCH_BITS         _SB_MAKE64(0x00FC000000)
++#define A_BCM1480_PHYS_HT_CFG_MATCH_BITS        _SB_MAKE64(0x00FE000000)
++#define A_BCM1480_PHYS_MEMORY_EXP               _SB_MAKE64(0x0100000000)
++#define A_BCM1480_PHYS_MEMORY_EXP_SIZE          _SB_MAKE64((508*1024*1024*1024))
++#define A_BCM1480_PHYS_PCI_UPPER                _SB_MAKE64(0x1000000000)
++#define A_BCM1480_PHYS_HT_UPPER_MATCH_BYTES     _SB_MAKE64(0x2000000000)
++#define A_BCM1480_PHYS_HT_UPPER_MATCH_BITS      _SB_MAKE64(0x3000000000)
++#define A_BCM1480_PHYS_HT_NODE_ALIAS            _SB_MAKE64(0x4000000000)
++#define A_BCM1480_PHYS_HT_FULLACCESS            _SB_MAKE64(0xF000000000)
++
++
++/*  *********************************************************************
++    *  L2 Cache as RAM (Table 54)
++    ********************************************************************* */
++
++#define A_BCM1480_PHYS_L2CACHE_WAY_SIZE         _SB_MAKE64(0x0000020000)
++#define BCM1480_PHYS_L2CACHE_NUM_WAYS           8
++#define A_BCM1480_PHYS_L2CACHE_TOTAL_SIZE       _SB_MAKE64(0x0000100000)
++#define A_BCM1480_PHYS_L2CACHE_WAY0             _SB_MAKE64(0x00D0300000)
++#define A_BCM1480_PHYS_L2CACHE_WAY1             _SB_MAKE64(0x00D0320000)
++#define A_BCM1480_PHYS_L2CACHE_WAY2             _SB_MAKE64(0x00D0340000)
++#define A_BCM1480_PHYS_L2CACHE_WAY3             _SB_MAKE64(0x00D0360000)
++#define A_BCM1480_PHYS_L2CACHE_WAY4             _SB_MAKE64(0x00D0380000)
++#define A_BCM1480_PHYS_L2CACHE_WAY5             _SB_MAKE64(0x00D03A0000)
++#define A_BCM1480_PHYS_L2CACHE_WAY6             _SB_MAKE64(0x00D03C0000)
++#define A_BCM1480_PHYS_L2CACHE_WAY7             _SB_MAKE64(0x00D03E0000)
++
++#endif /* _BCM1480_REGS_H */
+diff --git a/include/asm-mips/sibyte/bcm1480_scd.h b/include/asm-mips/sibyte/bcm1480_scd.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/sibyte/bcm1480_scd.h
+@@ -0,0 +1,436 @@
++/*  *********************************************************************
++    *  BCM1280/BCM1400 Board Support Package
++    *
++    *  SCD Constants and Macros                     File: bcm1480_scd.h
++    *
++    *  This module contains constants and macros useful for
++    *  manipulating the System Control and Debug module.
++    *
++    *  BCM1400 specification level: 1X55_1X80-UM100-R (12/18/03)
++    *
++    *********************************************************************
++    *
++    *  Copyright 2000,2001,2002,2003
++    *  Broadcom 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
++    ********************************************************************* */
++
++#ifndef _BCM1480_SCD_H
++#define _BCM1480_SCD_H
++
++#include "sb1250_defs.h"
++
++/*  *********************************************************************
++    *  Pull in the BCM1250's SCD since lots of stuff is the same.
++    ********************************************************************* */
++
++#include "sb1250_scd.h"
++
++/*  *********************************************************************
++    *  Some general notes:
++    *
++    *  This file is basically a "what's new" header file.  Since the
++    *  BCM1250 and the new BCM1480 (and derivatives) share many common
++    *  features, this file contains only what's new or changed from
++    *  the 1250.  (above, you can see that we include the 1250 symbols
++    *  to get the base functionality).
++    *
++    *  In software, be sure to use the correct symbols, particularly
++    *  for blocks that are different between the two chip families.
++    *  All BCM1480-specific symbols have _BCM1480_ in their names,
++    *  and all BCM1250-specific and "base" functions that are common in
++    *  both chips have no special names (this is for compatibility with
++    *  older include files).  Therefore, if you're working with the
++    *  SCD, which is very different on each chip, A_SCD_xxx implies
++    *  the BCM1250 version and A_BCM1480_SCD_xxx implies the BCM1480
++    *  version.
++    ********************************************************************* */
++
++/*  *********************************************************************
++    *  System control/debug registers
++    ********************************************************************* */
++
++/*
++ * System Identification and Revision Register (Table 12)
++ * Register: SCD_SYSTEM_REVISION
++ * This register is field compatible with the 1250.
++ */
++
++/*
++ * New part definitions
++ */
++
++#define K_SYS_PART_BCM1480          0x1406
++#define K_SYS_PART_BCM1280          0x1206
++#define K_SYS_PART_BCM1455          0x1407
++#define K_SYS_PART_BCM1255          0x1257
++
++/*
++ * Manufacturing Information Register (Table 14)
++ * Register: SCD_SYSTEM_MANUF
++ */
++
++/*
++ * System Configuration Register (Table 15)
++ * Register: SCD_SYSTEM_CFG
++ * Entire register is different from 1250, all new constants below
++ */
++
++#define M_BCM1480_SYS_RESERVED0             _SB_MAKEMASK1(0)
++#define M_BCM1480_SYS_HT_MINRSTCNT          _SB_MAKEMASK1(1)
++#define M_BCM1480_SYS_RESERVED2             _SB_MAKEMASK1(2)
++#define M_BCM1480_SYS_RESERVED3             _SB_MAKEMASK1(3)
++#define M_BCM1480_SYS_RESERVED4             _SB_MAKEMASK1(4)
++#define M_BCM1480_SYS_IOB_DIV               _SB_MAKEMASK1(5)
++
++#define S_BCM1480_SYS_PLL_DIV               _SB_MAKE64(6)
++#define M_BCM1480_SYS_PLL_DIV               _SB_MAKEMASK(5,S_BCM1480_SYS_PLL_DIV)
++#define V_BCM1480_SYS_PLL_DIV(x)            _SB_MAKEVALUE(x,S_BCM1480_SYS_PLL_DIV)
++#define G_BCM1480_SYS_PLL_DIV(x)            _SB_GETVALUE(x,S_BCM1480_SYS_PLL_DIV,M_BCM1480_SYS_PLL_DIV)
++
++#define S_BCM1480_SYS_SW_DIV                _SB_MAKE64(11)
++#define M_BCM1480_SYS_SW_DIV                _SB_MAKEMASK(5,S_BCM1480_SYS_SW_DIV)
++#define V_BCM1480_SYS_SW_DIV(x)             _SB_MAKEVALUE(x,S_BCM1480_SYS_SW_DIV)
++#define G_BCM1480_SYS_SW_DIV(x)             _SB_GETVALUE(x,S_BCM1480_SYS_SW_DIV,M_BCM1480_SYS_SW_DIV)
++
++#define M_BCM1480_SYS_PCMCIA_ENABLE         _SB_MAKEMASK1(16)
++#define M_BCM1480_SYS_DUART1_ENABLE         _SB_MAKEMASK1(17)
++
++#define S_BCM1480_SYS_BOOT_MODE             _SB_MAKE64(18)
++#define M_BCM1480_SYS_BOOT_MODE             _SB_MAKEMASK(2,S_BCM1480_SYS_BOOT_MODE)
++#define V_BCM1480_SYS_BOOT_MODE(x)          _SB_MAKEVALUE(x,S_BCM1480_SYS_BOOT_MODE)
++#define G_BCM1480_SYS_BOOT_MODE(x)          _SB_GETVALUE(x,S_BCM1480_SYS_BOOT_MODE,M_BCM1480_SYS_BOOT_MODE)
++#define K_BCM1480_SYS_BOOT_MODE_ROM32       0
++#define K_BCM1480_SYS_BOOT_MODE_ROM8        1
++#define K_BCM1480_SYS_BOOT_MODE_SMBUS_SMALL 2
++#define K_BCM1480_SYS_BOOT_MODE_SMBUS_BIG   3
++#define M_BCM1480_SYS_BOOT_MODE_SMBUS       _SB_MAKEMASK1(19)
++
++#define M_BCM1480_SYS_PCI_HOST              _SB_MAKEMASK1(20)
++#define M_BCM1480_SYS_PCI_ARBITER           _SB_MAKEMASK1(21)
++#define M_BCM1480_SYS_BIG_ENDIAN            _SB_MAKEMASK1(22)
++#define M_BCM1480_SYS_GENCLK_EN             _SB_MAKEMASK1(23)
++#define M_BCM1480_SYS_GEN_PARITY_EN         _SB_MAKEMASK1(24)
++#define M_BCM1480_SYS_RESERVED25            _SB_MAKEMASK1(25)
++
++#define S_BCM1480_SYS_CONFIG                26
++#define M_BCM1480_SYS_CONFIG                _SB_MAKEMASK(6,S_BCM1480_SYS_CONFIG)
++#define V_BCM1480_SYS_CONFIG(x)             _SB_MAKEVALUE(x,S_BCM1480_SYS_CONFIG)
++#define G_BCM1480_SYS_CONFIG(x)             _SB_GETVALUE(x,S_BCM1480_SYS_CONFIG,M_BCM1480_SYS_CONFIG)
++
++#define M_BCM1480_SYS_RESERVED32            _SB_MAKEMASK(32,15)
++
++#define S_BCM1480_SYS_NODEID                47
++#define M_BCM1480_SYS_NODEID                _SB_MAKEMASK(4,S_BCM1480_SYS_NODEID)
++#define V_BCM1480_SYS_NODEID(x)             _SB_MAKEVALUE(x,S_BCM1480_SYS_NODEID)
++#define G_BCM1480_SYS_NODEID(x)             _SB_GETVALUE(x,S_BCM1480_SYS_NODEID,M_BCM1480_SYS_NODEID)
++
++#define M_BCM1480_SYS_CCNUMA_EN             _SB_MAKEMASK1(51)
++#define M_BCM1480_SYS_CPU_RESET_0           _SB_MAKEMASK1(52)
++#define M_BCM1480_SYS_CPU_RESET_1           _SB_MAKEMASK1(53)
++#define M_BCM1480_SYS_CPU_RESET_2           _SB_MAKEMASK1(54)
++#define M_BCM1480_SYS_CPU_RESET_3           _SB_MAKEMASK1(55)
++#define S_BCM1480_SYS_DISABLECPU0           56
++#define M_BCM1480_SYS_DISABLECPU0           _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU0)
++#define S_BCM1480_SYS_DISABLECPU1           57
++#define M_BCM1480_SYS_DISABLECPU1           _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU1)
++#define S_BCM1480_SYS_DISABLECPU2           58
++#define M_BCM1480_SYS_DISABLECPU2           _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU2)
++#define S_BCM1480_SYS_DISABLECPU3           59
++#define M_BCM1480_SYS_DISABLECPU3           _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU3)
++
++#define M_BCM1480_SYS_SB_SOFTRES            _SB_MAKEMASK1(60)
++#define M_BCM1480_SYS_EXT_RESET             _SB_MAKEMASK1(61)
++#define M_BCM1480_SYS_SYSTEM_RESET          _SB_MAKEMASK1(62)
++#define M_BCM1480_SYS_SW_FLAG               _SB_MAKEMASK1(63)
++
++/*
++ * Scratch Register (Table 16)
++ * Register: SCD_SYSTEM_SCRATCH
++ * Same as BCM1250
++ */
++
++
++/*
++ * Mailbox Registers (Table 17)
++ * Registers: SCD_MBOX_{0,1}_CPU_x
++ * Same as BCM1250
++ */
++
++
++/*
++ * See bcm1480_int.h for interrupt mapper registers.
++ */
++
++
++/*
++ * Watchdog Timer Initial Count Registers (Table 23)
++ * Registers: SCD_WDOG_INIT_CNT_x
++ *
++ * The watchdogs are almost the same as the 1250, except
++ * the configuration register has more bits to control the
++ * other CPUs.
++ */
++
++
++/*
++ * Watchdog Timer Configuration Registers (Table 25)
++ * Registers: SCD_WDOG_CFG_x
++ */
++
++#define M_BCM1480_SCD_WDOG_ENABLE           _SB_MAKEMASK1(0)
++
++#define S_BCM1480_SCD_WDOG_RESET_TYPE       2
++#define M_BCM1480_SCD_WDOG_RESET_TYPE       _SB_MAKEMASK(5,S_BCM1480_SCD_WDOG_RESET_TYPE)
++#define V_BCM1480_SCD_WDOG_RESET_TYPE(x)    _SB_MAKEVALUE(x,S_BCM1480_SCD_WDOG_RESET_TYPE)
++#define G_BCM1480_SCD_WDOG_RESET_TYPE(x)    _SB_GETVALUE(x,S_BCM1480_SCD_WDOG_RESET_TYPE,M_BCM1480_SCD_WDOG_RESET_TYPE)
++
++#define K_BCM1480_SCD_WDOG_RESET_FULL       0	/* actually, (x & 1) == 0  */
++#define K_BCM1480_SCD_WDOG_RESET_SOFT       1
++#define K_BCM1480_SCD_WDOG_RESET_CPU0       3
++#define K_BCM1480_SCD_WDOG_RESET_CPU1       5
++#define K_BCM1480_SCD_WDOG_RESET_CPU2       9
++#define K_BCM1480_SCD_WDOG_RESET_CPU3       17
++#define K_BCM1480_SCD_WDOG_RESET_ALL_CPUS   31
++
++
++#define M_BCM1480_SCD_WDOG_HAS_RESET        _SB_MAKEMASK1(8)
++
++/*
++ * General Timer Initial Count Registers (Table 26)
++ * Registers: SCD_TIMER_INIT_x
++ *
++ * The timer registers are the same as the BCM1250
++ */
++
++
++/*
++ * ZBbus Count Register (Table 29)
++ * Register: ZBBUS_CYCLE_COUNT
++ *
++ * Same as BCM1250
++ */
++
++/*
++ * ZBbus Compare Registers (Table 30)
++ * Registers: ZBBUS_CYCLE_CPx
++ *
++ * Same as BCM1250
++ */
++
++
++/*
++ * System Performance Counter Configuration Register (Table 31)
++ * Register: PERF_CNT_CFG_0
++ *
++ * Since the clear/enable bits are moved compared to the
++ * 1250 and there are more fields, this register will be BCM1480 specific.
++ */
++
++#define S_BCM1480_SPC_CFG_SRC0              0
++#define M_BCM1480_SPC_CFG_SRC0              _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC0)
++#define V_BCM1480_SPC_CFG_SRC0(x)           _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC0)
++#define G_BCM1480_SPC_CFG_SRC0(x)           _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC0,M_BCM1480_SPC_CFG_SRC0)
++
++#define S_BCM1480_SPC_CFG_SRC1              8
++#define M_BCM1480_SPC_CFG_SRC1              _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC1)
++#define V_BCM1480_SPC_CFG_SRC1(x)           _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC1)
++#define G_BCM1480_SPC_CFG_SRC1(x)           _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC1,M_BCM1480_SPC_CFG_SRC1)
++
++#define S_BCM1480_SPC_CFG_SRC2              16
++#define M_BCM1480_SPC_CFG_SRC2              _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC2)
++#define V_BCM1480_SPC_CFG_SRC2(x)           _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC2)
++#define G_BCM1480_SPC_CFG_SRC2(x)           _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC2,M_BCM1480_SPC_CFG_SRC2)
++
++#define S_BCM1480_SPC_CFG_SRC3              24
++#define M_BCM1480_SPC_CFG_SRC3              _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC3)
++#define V_BCM1480_SPC_CFG_SRC3(x)           _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC3)
++#define G_BCM1480_SPC_CFG_SRC3(x)           _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC3,M_BCM1480_SPC_CFG_SRC3)
++
++#define S_BCM1480_SPC_CFG_SRC4              32
++#define M_BCM1480_SPC_CFG_SRC4              _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC4)
++#define V_BCM1480_SPC_CFG_SRC4(x)           _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC4)
++#define G_BCM1480_SPC_CFG_SRC4(x)           _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC4,M_BCM1480_SPC_CFG_SRC4)
++
++#define S_BCM1480_SPC_CFG_SRC5              40
++#define M_BCM1480_SPC_CFG_SRC5              _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC5)
++#define V_BCM1480_SPC_CFG_SRC5(x)           _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC5)
++#define G_BCM1480_SPC_CFG_SRC5(x)           _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC5,M_BCM1480_SPC_CFG_SRC5)
++
++#define S_BCM1480_SPC_CFG_SRC6              48
++#define M_BCM1480_SPC_CFG_SRC6              _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC6)
++#define V_BCM1480_SPC_CFG_SRC6(x)           _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC6)
++#define G_BCM1480_SPC_CFG_SRC6(x)           _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC6,M_BCM1480_SPC_CFG_SRC6)
++
++#define S_BCM1480_SPC_CFG_SRC7              56
++#define M_BCM1480_SPC_CFG_SRC7              _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC7)
++#define V_BCM1480_SPC_CFG_SRC7(x)           _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC7)
++#define G_BCM1480_SPC_CFG_SRC7(x)           _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC7,M_BCM1480_SPC_CFG_SRC7)
++
++/*
++ * System Performance Counter Control Register (Table 32)
++ * Register: PERF_CNT_CFG_1
++ * BCM1480 specific
++ */
++
++#define M_BCM1480_SPC_CFG_CLEAR             _SB_MAKEMASK1(0)
++#define M_BCM1480_SPC_CFG_ENABLE            _SB_MAKEMASK1(1)
++
++/*
++ * System Performance Counters (Table 33)
++ * Registers: PERF_CNT_x
++ */
++
++#define S_BCM1480_SPC_CNT_COUNT             0
++#define M_BCM1480_SPC_CNT_COUNT             _SB_MAKEMASK(40,S_BCM1480_SPC_CNT_COUNT)
++#define V_BCM1480_SPC_CNT_COUNT(x)          _SB_MAKEVALUE(x,S_BCM1480_SPC_CNT_COUNT)
++#define G_BCM1480_SPC_CNT_COUNT(x)          _SB_GETVALUE(x,S_BCM1480_SPC_CNT_COUNT,M_BCM1480_SPC_CNT_COUNT)
++
++#define M_BCM1480_SPC_CNT_OFLOW             _SB_MAKEMASK1(40)
++
++
++/*
++ * Bus Watcher Error Status Register (Tables 36, 37)
++ * Registers: BUS_ERR_STATUS, BUS_ERR_STATUS_DEBUG
++ * Same as BCM1250.
++ */
++
++/*
++ * Bus Watcher Error Data Registers (Table 38)
++ * Registers: BUS_ERR_DATA_x
++ * Same as BCM1250.
++ */
++
++/*
++ * Bus Watcher L2 ECC Counter Register (Table 39)
++ * Register: BUS_L2_ERRORS
++ * Same as BCM1250.
++ */
++
++
++/*
++ * Bus Watcher Memory and I/O Error Counter Register (Table 40)
++ * Register: BUS_MEM_IO_ERRORS
++ * Same as BCM1250.
++ */
++
++
++/*
++ * Address Trap Registers
++ *
++ * Register layout same as BCM1250, almost.  The bus agents
++ * are different, and the address trap configuration bits are
++ * slightly different.
++ */
++
++#define M_BCM1480_ATRAP_INDEX		  _SB_MAKEMASK(4,0)
++#define M_BCM1480_ATRAP_ADDRESS		  _SB_MAKEMASK(40,0)
++
++#define S_BCM1480_ATRAP_CFG_CNT            0
++#define M_BCM1480_ATRAP_CFG_CNT            _SB_MAKEMASK(3,S_BCM1480_ATRAP_CFG_CNT)
++#define V_BCM1480_ATRAP_CFG_CNT(x)         _SB_MAKEVALUE(x,S_BCM1480_ATRAP_CFG_CNT)
++#define G_BCM1480_ATRAP_CFG_CNT(x)         _SB_GETVALUE(x,S_BCM1480_ATRAP_CFG_CNT,M_BCM1480_ATRAP_CFG_CNT)
++
++#define M_BCM1480_ATRAP_CFG_WRITE	   _SB_MAKEMASK1(3)
++#define M_BCM1480_ATRAP_CFG_ALL	  	   _SB_MAKEMASK1(4)
++#define M_BCM1480_ATRAP_CFG_INV	   	   _SB_MAKEMASK1(5)
++#define M_BCM1480_ATRAP_CFG_USESRC	   _SB_MAKEMASK1(6)
++#define M_BCM1480_ATRAP_CFG_SRCINV	   _SB_MAKEMASK1(7)
++
++#define S_BCM1480_ATRAP_CFG_AGENTID     8
++#define M_BCM1480_ATRAP_CFG_AGENTID     _SB_MAKEMASK(4,S_BCM1480_ATRAP_CFG_AGENTID)
++#define V_BCM1480_ATRAP_CFG_AGENTID(x)  _SB_MAKEVALUE(x,S_BCM1480_ATRAP_CFG_AGENTID)
++#define G_BCM1480_ATRAP_CFG_AGENTID(x)  _SB_GETVALUE(x,S_BCM1480_ATRAP_CFG_AGENTID,M_BCM1480_ATRAP_CFG_AGENTID)
++
++
++#define K_BCM1480_BUS_AGENT_CPU0            0
++#define K_BCM1480_BUS_AGENT_CPU1            1
++#define K_BCM1480_BUS_AGENT_NC              2
++#define K_BCM1480_BUS_AGENT_IOB             3
++#define K_BCM1480_BUS_AGENT_SCD             4
++#define K_BCM1480_BUS_AGENT_L2C             6
++#define K_BCM1480_BUS_AGENT_MC              7
++#define K_BCM1480_BUS_AGENT_CPU2            8
++#define K_BCM1480_BUS_AGENT_CPU3            9
++#define K_BCM1480_BUS_AGENT_PM              10
++
++#define S_BCM1480_ATRAP_CFG_CATTR           12
++#define M_BCM1480_ATRAP_CFG_CATTR           _SB_MAKEMASK(2,S_BCM1480_ATRAP_CFG_CATTR)
++#define V_BCM1480_ATRAP_CFG_CATTR(x)        _SB_MAKEVALUE(x,S_BCM1480_ATRAP_CFG_CATTR)
++#define G_BCM1480_ATRAP_CFG_CATTR(x)        _SB_GETVALUE(x,S_BCM1480_ATRAP_CFG_CATTR,M_BCM1480_ATRAP_CFG_CATTR)
++
++#define K_BCM1480_ATRAP_CFG_CATTR_IGNORE    0
++#define K_BCM1480_ATRAP_CFG_CATTR_UNC       1
++#define K_BCM1480_ATRAP_CFG_CATTR_NONCOH    2
++#define K_BCM1480_ATRAP_CFG_CATTR_COHERENT  3
++
++#define M_BCM1480_ATRAP_CFG_CATTRINV        _SB_MAKEMASK1(14)
++
++
++/*
++ * Trace Event Registers (Table 47)
++ * Same as BCM1250.
++ */
++
++/*
++ * Trace Sequence Control Registers (Table 48)
++ * Registers: TRACE_SEQUENCE_x
++ *
++ * Same as BCM1250 except for two new fields.
++ */
++
++
++#define M_BCM1480_SCD_TRSEQ_TID_MATCH_EN    _SB_MAKEMASK1(25)
++
++#define S_BCM1480_SCD_TRSEQ_SWFUNC          26
++#define M_BCM1480_SCD_TRSEQ_SWFUNC          _SB_MAKEMASK(2,S_BCM1480_SCD_TRSEQ_SWFUNC)
++#define V_BCM1480_SCD_TRSEQ_SWFUNC(x)       _SB_MAKEVALUE(x,S_BCM1480_SCD_TRSEQ_SWFUNC)
++#define G_BCM1480_SCD_TRSEQ_SWFUNC(x)       _SB_GETVALUE(x,S_BCM1480_SCD_TRSEQ_SWFUNC,M_BCM1480_SCD_TRSEQ_SWFUNC)
++
++/*
++ * Trace Control Register (Table 49)
++ * Register: TRACE_CFG
++ *
++ * Bits 0..8 are the same as the BCM1250, rest are different.
++ * Entire register is redefined below.
++ */
++
++#define M_BCM1480_SCD_TRACE_CFG_RESET       _SB_MAKEMASK1(0)
++#define M_BCM1480_SCD_TRACE_CFG_START_READ  _SB_MAKEMASK1(1)
++#define M_BCM1480_SCD_TRACE_CFG_START       _SB_MAKEMASK1(2)
++#define M_BCM1480_SCD_TRACE_CFG_STOP        _SB_MAKEMASK1(3)
++#define M_BCM1480_SCD_TRACE_CFG_FREEZE      _SB_MAKEMASK1(4)
++#define M_BCM1480_SCD_TRACE_CFG_FREEZE_FULL _SB_MAKEMASK1(5)
++#define M_BCM1480_SCD_TRACE_CFG_DEBUG_FULL  _SB_MAKEMASK1(6)
++#define M_BCM1480_SCD_TRACE_CFG_FULL        _SB_MAKEMASK1(7)
++#define M_BCM1480_SCD_TRACE_CFG_FORCE_CNT   _SB_MAKEMASK1(8)
++
++#define S_BCM1480_SCD_TRACE_CFG_MODE        16
++#define M_BCM1480_SCD_TRACE_CFG_MODE        _SB_MAKEMASK(2,S_BCM1480_SCD_TRACE_CFG_MODE)
++#define V_BCM1480_SCD_TRACE_CFG_MODE(x)     _SB_MAKEVALUE(x,S_BCM1480_SCD_TRACE_CFG_MODE)
++#define G_BCM1480_SCD_TRACE_CFG_MODE(x)     _SB_GETVALUE(x,S_BCM1480_SCD_TRACE_CFG_MODE,M_BCM1480_SCD_TRACE_CFG_MODE)
++
++#define K_BCM1480_SCD_TRACE_CFG_MODE_BLOCKERS	0
++#define K_BCM1480_SCD_TRACE_CFG_MODE_BYTEEN_INT	1
++#define K_BCM1480_SCD_TRACE_CFG_MODE_FLOW_ID	2
++
++#define S_BCM1480_SCD_TRACE_CFG_CUR_ADDR    24
++#define M_BCM1480_SCD_TRACE_CFG_CUR_ADDR    _SB_MAKEMASK(8,S_BCM1480_SCD_TRACE_CFG_CUR_ADDR)
++#define V_BCM1480_SCD_TRACE_CFG_CUR_ADDR(x) _SB_MAKEVALUE(x,S_BCM1480_SCD_TRACE_CFG_CUR_ADDR)
++#define G_BCM1480_SCD_TRACE_CFG_CUR_ADDR(x) _SB_GETVALUE(x,S_BCM1480_SCD_TRACE_CFG_CUR_ADDR,M_BCM1480_SCD_TRACE_CFG_CUR_ADDR)
++
++#endif /* _BCM1480_SCD_H */
+diff --git a/include/asm-mips/sibyte/bigsur.h b/include/asm-mips/sibyte/bigsur.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/sibyte/bigsur.h
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom 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.
++ */
++#ifndef __ASM_SIBYTE_BIGSUR_H
++#define __ASM_SIBYTE_BIGSUR_H
++
++#include <asm/sibyte/sb1250.h>
++#include <asm/sibyte/bcm1480_int.h>
++
++#ifdef CONFIG_SIBYTE_BIGSUR
++#define SIBYTE_BOARD_NAME "BCM91x80A/B (BigSur)"
++#define SIBYTE_HAVE_PCMCIA 1
++#define SIBYTE_HAVE_IDE    1
++#endif
++
++/* Generic bus chip selects */
++#define LEDS_CS         3
++#define LEDS_PHYS       0x100a0000
++
++#ifdef SIBYTE_HAVE_IDE
++#define IDE_CS          4
++#define IDE_PHYS        0x100b0000
++#define K_GPIO_GB_IDE   4
++#define K_INT_GB_IDE    (K_INT_GPIO_0 + K_GPIO_GB_IDE)
++#endif
++
++#ifdef SIBYTE_HAVE_PCMCIA
++#define PCMCIA_CS       6
++#define PCMCIA_PHYS     0x11000000
++#define K_GPIO_PC_READY 9
++#define K_INT_PC_READY  (K_INT_GPIO_0 + K_GPIO_PC_READY)
++#endif
++
++#endif /* __ASM_SIBYTE_BIGSUR_H */
++
+diff --git a/include/asm-mips/sibyte/board.h b/include/asm-mips/sibyte/board.h
+--- a/include/asm-mips/sibyte/board.h
++++ b/include/asm-mips/sibyte/board.h
+@@ -21,8 +21,6 @@
+ 
+ #include <linux/config.h>
+ 
+-#ifdef CONFIG_SIBYTE_BOARD
+-
+ #if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) || \
+     defined(CONFIG_SIBYTE_CRHONE) || defined(CONFIG_SIBYTE_CRHINE) || \
+     defined(CONFIG_SIBYTE_LITTLESUR)
+@@ -37,6 +35,10 @@
+ #include <asm/sibyte/carmel.h>
+ #endif
+ 
++#ifdef CONFIG_SIBYTE_BIGSUR
++#include <asm/sibyte/bigsur.h>
++#endif
++
+ #ifdef __ASSEMBLY__
+ 
+ #ifdef LEDS_PHYS
+@@ -54,16 +56,6 @@
+ #define setleds(t0,t1,c0,c1,c2,c3)
+ #endif /* LEDS_PHYS */
+ 
+-#else
+-
+-#ifdef LEDS_PHYS
+-extern void setleds(char *str);
+-#else
+-#define setleds(s) do { } while (0)
+-#endif /* LEDS_PHYS */
+-
+ #endif /* __ASSEMBLY__ */
+ 
+-#endif /* CONFIG_SIBYTE_BOARD */
+-
+ #endif /* _SIBYTE_BOARD_H */
+diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
+--- a/include/asm-mips/sibyte/sb1250.h
++++ b/include/asm-mips/sibyte/sb1250.h
+@@ -27,6 +27,9 @@
+ 
+ #define SB1250_NR_IRQS 64
+ 
++#define BCM1480_NR_IRQS                 128
++#define BCM1480_NR_IRQS_HALF            64
++
+ #define SB1250_DUART_MINOR_BASE		64
+ 
+ #ifndef __ASSEMBLY__
+@@ -35,6 +38,7 @@
+ 
+ /* For revision/pass information */
+ #include <asm/sibyte/sb1250_scd.h>
++#include <asm/sibyte/bcm1480_scd.h>
+ extern unsigned int sb1_pass;
+ extern unsigned int soc_pass;
+ extern unsigned int soc_type;
+@@ -46,6 +50,13 @@ extern unsigned long sb1250_gettimeoffse
+ extern void sb1250_mask_irq(int cpu, int irq);
+ extern void sb1250_unmask_irq(int cpu, int irq);
+ extern void sb1250_smp_finish(void);
++
++extern void bcm1480_time_init(void);
++extern unsigned long bcm1480_gettimeoffset(void);
++extern void bcm1480_mask_irq(int cpu, int irq);
++extern void bcm1480_unmask_irq(int cpu, int irq);
++extern void bcm1480_smp_finish(void);
++
+ extern void prom_printf(char *fmt, ...);
+ 
+ #define AT_spin \
+@@ -58,6 +69,6 @@ extern void prom_printf(char *fmt, ...);
+ 
+ #endif
+ 
+-#define IOADDR(a) (IO_BASE + (a))
++#define IOADDR(a) ((volatile void __iomem *)(IO_BASE + (a)))
+ 
+ #endif
+diff --git a/include/asm-mips/sibyte/sb1250_defs.h b/include/asm-mips/sibyte/sb1250_defs.h
+--- a/include/asm-mips/sibyte/sb1250_defs.h
++++ b/include/asm-mips/sibyte/sb1250_defs.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  User's manual 1/02/02
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+@@ -97,13 +95,17 @@
+     *  ordering, so be careful when adding support for new minor revs.
+     ********************************************************************* */
+ 
+-#define	SIBYTE_HDR_FMASK_1250_ALL		0x00000ff
+-#define	SIBYTE_HDR_FMASK_1250_PASS1		0x0000001
+-#define	SIBYTE_HDR_FMASK_1250_PASS2		0x0000002
+-#define	SIBYTE_HDR_FMASK_1250_PASS3		0x0000004
+-
+-#define	SIBYTE_HDR_FMASK_112x_ALL		0x0000f00
+-#define	SIBYTE_HDR_FMASK_112x_PASS1		0x0000100
++#define	SIBYTE_HDR_FMASK_1250_ALL		0x000000ff
++#define	SIBYTE_HDR_FMASK_1250_PASS1		0x00000001
++#define	SIBYTE_HDR_FMASK_1250_PASS2		0x00000002
++#define	SIBYTE_HDR_FMASK_1250_PASS3		0x00000004
++
++#define	SIBYTE_HDR_FMASK_112x_ALL		0x00000f00
++#define	SIBYTE_HDR_FMASK_112x_PASS1		0x00000100
++
++#define SIBYTE_HDR_FMASK_1480_ALL		0x0000f000
++#define SIBYTE_HDR_FMASK_1480_PASS1		0x00001000
++#define SIBYTE_HDR_FMASK_1480_PASS2		0x00002000
+ 
+ /* Bit mask for chip/revision.  (use _ALL for all revisions of a chip).  */
+ #define	SIBYTE_HDR_FMASK(chip, pass)					\
+@@ -111,8 +113,17 @@
+ #define	SIBYTE_HDR_FMASK_ALLREVS(chip)					\
+     (SIBYTE_HDR_FMASK_ ## chip ## _ALL)
+ 
++/* Default constant value for all chips, all revisions */
+ #define	SIBYTE_HDR_FMASK_ALL						\
++    (SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL		\
++     | SIBYTE_HDR_FMASK_1480_ALL)
++
++/* This one is used for the "original" BCM1250/BCM112x chips.  We use this
++   to weed out constants and macros that do not exist on later chips like
++   the BCM1480  */
++#define SIBYTE_HDR_FMASK_1250_112x_ALL					\
+     (SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL)
++#define SIBYTE_HDR_FMASK_1250_112x SIBYTE_HDR_FMASK_1250_112x_ALL
+ 
+ #ifndef SIBYTE_HDR_FEATURES
+ #define	SIBYTE_HDR_FEATURES			SIBYTE_HDR_FMASK_ALL
+@@ -133,6 +144,12 @@
+ #define SIBYTE_HDR_FEATURE_CHIP(chip)					\
+     (!! (SIBYTE_HDR_FMASK_ALLREVS(chip) & SIBYTE_HDR_FEATURES))
+ 
++/* True for all versions of the BCM1250 and BCM1125, but not true for
++   anything else */
++#define SIBYTE_HDR_FEATURE_1250_112x \
++      (SIBYTE_HDR_FEATURE_CHIP(1250) || SIBYTE_HDR_FEATURE_CHIP(112x))
++/*    (!!  (SIBYTE_HDR_FEATURES & SIBYHTE_HDR_FMASK_1250_112x)) */
++
+ /* True if header features enabled for that rev or later, inclusive.  */
+ #define SIBYTE_HDR_FEATURE(chip, pass)					\
+     (!! ((SIBYTE_HDR_FMASK(chip, pass)					\
+diff --git a/include/asm-mips/sibyte/sb1250_dma.h b/include/asm-mips/sibyte/sb1250_dma.h
+--- a/include/asm-mips/sibyte/sb1250_dma.h
++++ b/include/asm-mips/sibyte/sb1250_dma.h
+@@ -7,9 +7,8 @@
+     *  programming the SB1250's DMA controllers, both the data mover
+     *  and the Ethernet DMA.
+     *
+-    *  SB1250 specification level:  User's manual 1/02/02
+-    *
+-    *  Author:  Mitch Lichtenberg
++    *  SB1250 specification level:  User's manual 10/21/02
++    *  BCM1280 specification level: User's manual 11/24/03
+     *
+     *********************************************************************
+     *
+@@ -58,17 +57,17 @@
+ #define M_DMA_RESERVED1             _SB_MAKEMASK1(2)
+ 
+ #define S_DMA_DESC_TYPE		    _SB_MAKE64(1)
+-#define M_DMA_DESC_TYPE		    _SB_MAKE64(2,S_DMA_DESC_TYPE)
++#define M_DMA_DESC_TYPE		    _SB_MAKEMASK(2,S_DMA_DESC_TYPE)
+ #define V_DMA_DESC_TYPE(x)          _SB_MAKEVALUE(x,S_DMA_DESC_TYPE)
+ #define G_DMA_DESC_TYPE(x)          _SB_GETVALUE(x,S_DMA_DESC_TYPE,M_DMA_DESC_TYPE)
+ 
+ #define K_DMA_DESC_TYPE_RING_AL		0
+ #define K_DMA_DESC_TYPE_CHAIN_AL	1
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define K_DMA_DESC_TYPE_RING_UAL_WI	2
+ #define K_DMA_DESC_TYPE_RING_UAL_RMW	3
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define M_DMA_EOP_INT_EN            _SB_MAKEMASK1(3)
+ #define M_DMA_HWM_INT_EN            _SB_MAKEMASK1(4)
+@@ -111,11 +110,11 @@
+ #define M_DMA_NO_DSCR_UPDT          _SB_MAKEMASK1(4)
+ #define M_DMA_L2CA		    _SB_MAKEMASK1(5)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define M_DMA_RX_XTRA_STATUS	    _SB_MAKEMASK1(6)
+ #define M_DMA_TX_CPU_PAUSE	    _SB_MAKEMASK1(6)
+ #define M_DMA_TX_FC_PAUSE_EN	    _SB_MAKEMASK1(7)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define M_DMA_MBZ1                  _SB_MAKEMASK(6,15)
+ 
+@@ -165,14 +164,14 @@
+ #define S_DMA_CURDSCR_COUNT         _SB_MAKE64(40)
+ #define M_DMA_CURDSCR_COUNT         _SB_MAKEMASK(16,S_DMA_CURDSCR_COUNT)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define M_DMA_TX_CH_PAUSE_ON	    _SB_MAKEMASK1(56)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ /*
+  * Receive Packet Drop Registers
+  */
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define S_DMA_OODLOST_RX           _SB_MAKE64(0)
+ #define M_DMA_OODLOST_RX           _SB_MAKEMASK(16,S_DMA_OODLOST_RX)
+ #define G_DMA_OODLOST_RX(x)        _SB_GETVALUE(x,S_DMA_OODLOST_RX,M_DMA_OODLOST_RX)
+@@ -180,7 +179,7 @@
+ #define S_DMA_EOP_COUNT_RX         _SB_MAKE64(16)
+ #define M_DMA_EOP_COUNT_RX         _SB_MAKEMASK(8,S_DMA_EOP_COUNT_RX)
+ #define G_DMA_EOP_COUNT_RX(x)      _SB_GETVALUE(x,S_DMA_EOP_COUNT_RX,M_DMA_EOP_COUNT_RX)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ /*  *********************************************************************
+     *  DMA Descriptors
+@@ -201,21 +200,21 @@
+ 
+ #define M_DMA_DSCRA_A_ADDR_OFFSET   (M_DMA_DSCRA_OFFSET | M_DMA_DSCRA_A_ADDR)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define S_DMA_DSCRA_A_ADDR_UA        _SB_MAKE64(0)
+ #define M_DMA_DSCRA_A_ADDR_UA        _SB_MAKEMASK(40,S_DMA_DSCRA_A_ADDR_UA)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define S_DMA_DSCRA_A_SIZE          _SB_MAKE64(40)
+ #define M_DMA_DSCRA_A_SIZE          _SB_MAKEMASK(9,S_DMA_DSCRA_A_SIZE)
+ #define V_DMA_DSCRA_A_SIZE(x)       _SB_MAKEVALUE(x,S_DMA_DSCRA_A_SIZE)
+ #define G_DMA_DSCRA_A_SIZE(x)       _SB_GETVALUE(x,S_DMA_DSCRA_A_SIZE,M_DMA_DSCRA_A_SIZE)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define S_DMA_DSCRA_DSCR_CNT	    _SB_MAKE64(40)
+ #define M_DMA_DSCRA_DSCR_CNT	    _SB_MAKEMASK(8,S_DMA_DSCRA_DSCR_CNT)
+ #define G_DMA_DSCRA_DSCR_CNT(x)	    _SB_GETVALUE(x,S_DMA_DSCRA_DSCR_CNT,M_DMA_DSCRA_DSCR_CNT)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define M_DMA_DSCRA_INTERRUPT       _SB_MAKEMASK1(49)
+ #define M_DMA_DSCRA_OFFSETB	    _SB_MAKEMASK1(50)
+@@ -235,12 +234,12 @@
+ #define V_DMA_DSCRB_OPTIONS(x)      _SB_MAKEVALUE(x,S_DMA_DSCRB_OPTIONS)
+ #define G_DMA_DSCRB_OPTIONS(x)      _SB_GETVALUE(x,S_DMA_DSCRB_OPTIONS,M_DMA_DSCRB_OPTIONS)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define S_DMA_DSCRB_A_SIZE        _SB_MAKE64(8)
+ #define M_DMA_DSCRB_A_SIZE        _SB_MAKEMASK(14,S_DMA_DSCRB_A_SIZE)
+ #define V_DMA_DSCRB_A_SIZE(x)     _SB_MAKEVALUE(x,S_DMA_DSCRB_A_SIZE)
+ #define G_DMA_DSCRB_A_SIZE(x)     _SB_GETVALUE(x,S_DMA_DSCRB_A_SIZE,M_DMA_DSCRB_A_SIZE)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define R_DMA_DSCRB_ADDR            _SB_MAKE64(0x10)
+ 
+@@ -255,12 +254,12 @@
+ 
+ #define M_DMA_DSCRB_B_VALID         _SB_MAKEMASK1(49)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define S_DMA_DSCRB_PKT_SIZE_MSB    _SB_MAKE64(48)
+ #define M_DMA_DSCRB_PKT_SIZE_MSB    _SB_MAKEMASK(2,S_DMA_DSCRB_PKT_SIZE_MSB)
+ #define V_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB)
+ #define G_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_GETVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB,M_DMA_DSCRB_PKT_SIZE_MSB)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define S_DMA_DSCRB_PKT_SIZE        _SB_MAKE64(50)
+ #define M_DMA_DSCRB_PKT_SIZE        _SB_MAKEMASK(14,S_DMA_DSCRB_PKT_SIZE)
+@@ -282,15 +281,16 @@
+ #define M_DMA_ETHRX_BADIP4CS        _SB_MAKEMASK1(51)
+ #define M_DMA_ETHRX_DSCRERR	    _SB_MAKEMASK1(52)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+-/* Note: BADTCPCS is actually in DSCR_B options field */
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
++/* Note: This bit is in the DSCR_B options field */
+ #define M_DMA_ETHRX_BADTCPCS	_SB_MAKEMASK1(0)
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
++/* Note: These bits are in the DSCR_B options field */
+ #define M_DMA_ETH_VLAN_FLAG	_SB_MAKEMASK1(1)
+ #define M_DMA_ETH_CRC_FLAG	_SB_MAKEMASK1(2)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define S_DMA_ETHRX_RXCH            53
+ #define M_DMA_ETHRX_RXCH            _SB_MAKEMASK(2,S_DMA_ETHRX_RXCH)
+@@ -438,7 +438,7 @@
+                                      M_DM_CUR_DSCR_DSCR_COUNT)
+ 
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ /*
+  * Data Mover Channel Partial Result Registers
+  * Register: DM_PARTIAL_0
+@@ -459,10 +459,10 @@
+                                        M_DM_PARTIAL_TCPCS_PARTIAL)
+ 
+ #define M_DM_PARTIAL_ODD_BYTE         _SB_MAKEMASK1(48)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ /*
+  * Data Mover CRC Definition Registers
+  * Register: CRC_DEF_0
+@@ -479,10 +479,10 @@
+ #define V_CRC_DEF_CRC_POLY(r)         _SB_MAKEVALUE(r,S_CRC_DEF_CRC_POLY)
+ #define G_CRC_DEF_CRC_POLY(r)         _SB_GETVALUE(r,S_CRC_DEF_CRC_POLY,\
+                                        M_CRC_DEF_CRC_POLY)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ /*
+  * Data Mover CRC/Checksum Definition Registers
+  * Register: CTCP_DEF_0
+@@ -511,7 +511,7 @@
+ #define K_CTCP_DEF_CRC_WIDTH_1        2
+ 
+ #define M_CTCP_DEF_CRC_BIT_ORDER      _SB_MAKEMASK1(50)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ 
+ /*
+@@ -560,12 +560,12 @@
+ #define M_DM_DSCRA_L2C_DEST         _SB_MAKEMASK1(50)
+ #define M_DM_DSCRA_L2C_SRC          _SB_MAKEMASK1(51)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define M_DM_DSCRA_RD_BKOFF	    _SB_MAKEMASK1(52)
+ #define M_DM_DSCRA_WR_BKOFF	    _SB_MAKEMASK1(53)
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define M_DM_DSCRA_TCPCS_EN         _SB_MAKEMASK1(54)
+ #define M_DM_DSCRA_TCPCS_RES        _SB_MAKEMASK1(55)
+ #define M_DM_DSCRA_TCPCS_AP         _SB_MAKEMASK1(56)
+@@ -574,7 +574,7 @@
+ #define M_DM_DSCRA_CRC_AP           _SB_MAKEMASK1(59)
+ #define M_DM_DSCRA_CRC_DFN          _SB_MAKEMASK1(60)
+ #define M_DM_DSCRA_CRC_XBIT         _SB_MAKEMASK1(61)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define M_DM_DSCRA_RESERVED2        _SB_MAKEMASK(3,61)
+ 
+diff --git a/include/asm-mips/sibyte/sb1250_genbus.h b/include/asm-mips/sibyte/sb1250_genbus.h
+--- a/include/asm-mips/sibyte/sb1250_genbus.h
++++ b/include/asm-mips/sibyte/sb1250_genbus.h
+@@ -6,9 +6,8 @@
+     *  This module contains constants and macros useful for
+     *  manipulating the SB1250's Generic Bus interface
+     *
+-    *  SB1250 specification level:  User's manual 1/02/02
+-    *
+-    *  Author:  Mitch Lichtenberg
++    *  SB1250 specification level:  User's manual 10/21/02
++    *  BCM1280 specification level: User's Manual 11/14/03
+     *
+     *********************************************************************
+     *
+@@ -51,19 +50,21 @@
+ #define M_IO_WIDTH_SEL		_SB_MAKEMASK(2,S_IO_WIDTH_SEL)
+ #define K_IO_WIDTH_SEL_1	0
+ #define K_IO_WIDTH_SEL_2	1
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
++    || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define K_IO_WIDTH_SEL_1L       2
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ #define K_IO_WIDTH_SEL_4	3
+ #define V_IO_WIDTH_SEL(x)	_SB_MAKEVALUE(x,S_IO_WIDTH_SEL)
+ #define G_IO_WIDTH_SEL(x)	_SB_GETVALUE(x,S_IO_WIDTH_SEL,M_IO_WIDTH_SEL)
+ 
+ #define S_IO_PARITY_ENA		4
+ #define M_IO_PARITY_ENA		_SB_MAKEMASK1(S_IO_PARITY_ENA)
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
++    || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define S_IO_BURST_EN		5
+ #define M_IO_BURST_EN		_SB_MAKEMASK1(S_IO_BURST_EN)
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ #define S_IO_PARITY_ODD		6
+ #define M_IO_PARITY_ODD		_SB_MAKEMASK1(S_IO_PARITY_ODD)
+ #define S_IO_NONMUX		7
+@@ -96,8 +97,11 @@
+ 
+ #define S_IO_ADDRBASE		16	 /* # bits to shift addr for this reg */
+ 
++#define M_IO_BLK_CACHE		_SB_MAKEMASK1(15)
++
++
+ /*
+- * Generic Bus Region 0 Timing Registers (Table 11-7)
++ * Generic Bus Timing 0 Registers (Table 11-7)
+  */
+ 
+ #define S_IO_ALE_WIDTH		0
+@@ -105,21 +109,23 @@
+ #define V_IO_ALE_WIDTH(x)	_SB_MAKEVALUE(x,S_IO_ALE_WIDTH)
+ #define G_IO_ALE_WIDTH(x)	_SB_GETVALUE(x,S_IO_ALE_WIDTH,M_IO_ALE_WIDTH)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
++    || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define M_IO_EARLY_CS	        _SB_MAKEMASK1(3)
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ 
+ #define S_IO_ALE_TO_CS		4
+ #define M_IO_ALE_TO_CS		_SB_MAKEMASK(2,S_IO_ALE_TO_CS)
+ #define V_IO_ALE_TO_CS(x)	_SB_MAKEVALUE(x,S_IO_ALE_TO_CS)
+ #define G_IO_ALE_TO_CS(x)	_SB_GETVALUE(x,S_IO_ALE_TO_CS,M_IO_ALE_TO_CS)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
++    || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define S_IO_BURST_WIDTH           _SB_MAKE64(6)
+ #define M_IO_BURST_WIDTH           _SB_MAKEMASK(2,S_IO_BURST_WIDTH)
+ #define V_IO_BURST_WIDTH(x)        _SB_MAKEVALUE(x,S_IO_BURST_WIDTH)
+ #define G_IO_BURST_WIDTH(x)        _SB_GETVALUE(x,S_IO_BURST_WIDTH,M_IO_BURST_WIDTH)
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ 
+ #define S_IO_CS_WIDTH		8
+ #define M_IO_CS_WIDTH		_SB_MAKEMASK(5,S_IO_CS_WIDTH)
+@@ -141,9 +147,10 @@
+ #define V_IO_ALE_TO_WRITE(x)	_SB_MAKEVALUE(x,S_IO_ALE_TO_WRITE)
+ #define G_IO_ALE_TO_WRITE(x)	_SB_GETVALUE(x,S_IO_ALE_TO_WRITE,M_IO_ALE_TO_WRITE)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
++    || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define M_IO_RDY_SYNC	        _SB_MAKEMASK1(3)
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ 
+ #define S_IO_WRITE_WIDTH	4
+ #define M_IO_WRITE_WIDTH	_SB_MAKEMASK(4,S_IO_WRITE_WIDTH)
+@@ -183,9 +190,127 @@
+ #define M_IO_TIMEOUT_INT	_SB_MAKEMASK1(10)
+ #define M_IO_ILL_ADDR_INT	_SB_MAKEMASK1(11)
+ #define M_IO_MULT_CS_INT	_SB_MAKEMASK1(12)
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define M_IO_COH_ERR	        _SB_MAKEMASK1(14)
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
++
++
++/*
++ * Generic Bus Output Drive Control Register 0 (Table 14-18)
++ */
++
++#define S_IO_SLEW0		0
++#define M_IO_SLEW0		_SB_MAKEMASK(2,S_IO_SLEW0)
++#define V_IO_SLEW0(x)		_SB_MAKEVALUE(x,S_IO_SLEW0)
++#define G_IO_SLEW0(x)		_SB_GETVALUE(x,S_IO_SLEW0,M_IO_SLEW0)
++
++#define S_IO_DRV_A		2
++#define M_IO_DRV_A		_SB_MAKEMASK(2,S_IO_DRV_A)
++#define V_IO_DRV_A(x)		_SB_MAKEVALUE(x,S_IO_DRV_A)
++#define G_IO_DRV_A(x)		_SB_GETVALUE(x,S_IO_DRV_A,M_IO_DRV_A)
++
++#define S_IO_DRV_B		6
++#define M_IO_DRV_B		_SB_MAKEMASK(2,S_IO_DRV_B)
++#define V_IO_DRV_B(x)		_SB_MAKEVALUE(x,S_IO_DRV_B)
++#define G_IO_DRV_B(x)		_SB_GETVALUE(x,S_IO_DRV_B,M_IO_DRV_B)
++
++#define S_IO_DRV_C		10
++#define M_IO_DRV_C		_SB_MAKEMASK(2,S_IO_DRV_C)
++#define V_IO_DRV_C(x)		_SB_MAKEVALUE(x,S_IO_DRV_C)
++#define G_IO_DRV_C(x)		_SB_GETVALUE(x,S_IO_DRV_C,M_IO_DRV_C)
++
++#define S_IO_DRV_D		14
++#define M_IO_DRV_D		_SB_MAKEMASK(2,S_IO_DRV_D)
++#define V_IO_DRV_D(x)		_SB_MAKEVALUE(x,S_IO_DRV_D)
++#define G_IO_DRV_D(x)		_SB_GETVALUE(x,S_IO_DRV_D,M_IO_DRV_D)
++
++/*
++ * Generic Bus Output Drive Control Register 1 (Table 14-19)
++ */
++
++#define S_IO_DRV_E		2
++#define M_IO_DRV_E		_SB_MAKEMASK(2,S_IO_DRV_E)
++#define V_IO_DRV_E(x)		_SB_MAKEVALUE(x,S_IO_DRV_E)
++#define G_IO_DRV_E(x)		_SB_GETVALUE(x,S_IO_DRV_E,M_IO_DRV_E)
++
++#define S_IO_DRV_F		6
++#define M_IO_DRV_F		_SB_MAKEMASK(2,S_IO_DRV_F)
++#define V_IO_DRV_F(x)		_SB_MAKEVALUE(x,S_IO_DRV_F)
++#define G_IO_DRV_F(x)		_SB_GETVALUE(x,S_IO_DRV_F,M_IO_DRV_F)
++
++#define S_IO_SLEW1		8
++#define M_IO_SLEW1		_SB_MAKEMASK(2,S_IO_SLEW1)
++#define V_IO_SLEW1(x)		_SB_MAKEVALUE(x,S_IO_SLEW1)
++#define G_IO_SLEW1(x)		_SB_GETVALUE(x,S_IO_SLEW1,M_IO_SLEW1)
++
++#define S_IO_DRV_G		10
++#define M_IO_DRV_G		_SB_MAKEMASK(2,S_IO_DRV_G)
++#define V_IO_DRV_G(x)		_SB_MAKEVALUE(x,S_IO_DRV_G)
++#define G_IO_DRV_G(x)		_SB_GETVALUE(x,S_IO_DRV_G,M_IO_DRV_G)
++
++#define S_IO_SLEW2		12
++#define M_IO_SLEW2		_SB_MAKEMASK(2,S_IO_SLEW2)
++#define V_IO_SLEW2(x)		_SB_MAKEVALUE(x,S_IO_SLEW2)
++#define G_IO_SLEW2(x)		_SB_GETVALUE(x,S_IO_SLEW2,M_IO_SLEW2)
++
++#define S_IO_DRV_H		14
++#define M_IO_DRV_H		_SB_MAKEMASK(2,S_IO_DRV_H)
++#define V_IO_DRV_H(x)		_SB_MAKEVALUE(x,S_IO_DRV_H)
++#define G_IO_DRV_H(x)		_SB_GETVALUE(x,S_IO_DRV_H,M_IO_DRV_H)
++
++/*
++ * Generic Bus Output Drive Control Register 2 (Table 14-20)
++ */
++
++#define S_IO_DRV_J		2
++#define M_IO_DRV_J		_SB_MAKEMASK(2,S_IO_DRV_J)
++#define V_IO_DRV_J(x)		_SB_MAKEVALUE(x,S_IO_DRV_J)
++#define G_IO_DRV_J(x)		_SB_GETVALUE(x,S_IO_DRV_J,M_IO_DRV_J)
++
++#define S_IO_DRV_K		6
++#define M_IO_DRV_K		_SB_MAKEMASK(2,S_IO_DRV_K)
++#define V_IO_DRV_K(x)		_SB_MAKEVALUE(x,S_IO_DRV_K)
++#define G_IO_DRV_K(x)		_SB_GETVALUE(x,S_IO_DRV_K,M_IO_DRV_K)
++
++#define S_IO_DRV_L		10
++#define M_IO_DRV_L		_SB_MAKEMASK(2,S_IO_DRV_L)
++#define V_IO_DRV_L(x)		_SB_MAKEVALUE(x,S_IO_DRV_L)
++#define G_IO_DRV_L(x)		_SB_GETVALUE(x,S_IO_DRV_L,M_IO_DRV_L)
++
++#define S_IO_DRV_M		14
++#define M_IO_DRV_M		_SB_MAKEMASK(2,S_IO_DRV_M)
++#define V_IO_DRV_M(x)		_SB_MAKEVALUE(x,S_IO_DRV_M)
++#define G_IO_DRV_M(x)		_SB_GETVALUE(x,S_IO_DRV_M,M_IO_DRV_M)
++
++/*
++ * Generic Bus Output Drive Control Register 3 (Table 14-21)
++ */
++
++#define S_IO_SLEW3		0
++#define M_IO_SLEW3		_SB_MAKEMASK(2,S_IO_SLEW3)
++#define V_IO_SLEW3(x)		_SB_MAKEVALUE(x,S_IO_SLEW3)
++#define G_IO_SLEW3(x)		_SB_GETVALUE(x,S_IO_SLEW3,M_IO_SLEW3)
++
++#define S_IO_DRV_N		2
++#define M_IO_DRV_N		_SB_MAKEMASK(2,S_IO_DRV_N)
++#define V_IO_DRV_N(x)		_SB_MAKEVALUE(x,S_IO_DRV_N)
++#define G_IO_DRV_N(x)		_SB_GETVALUE(x,S_IO_DRV_N,M_IO_DRV_N)
++
++#define S_IO_DRV_P		6
++#define M_IO_DRV_P		_SB_MAKEMASK(2,S_IO_DRV_P)
++#define V_IO_DRV_P(x)		_SB_MAKEVALUE(x,S_IO_DRV_P)
++#define G_IO_DRV_P(x)		_SB_GETVALUE(x,S_IO_DRV_P,M_IO_DRV_P)
++
++#define S_IO_DRV_Q		10
++#define M_IO_DRV_Q		_SB_MAKEMASK(2,S_IO_DRV_Q)
++#define V_IO_DRV_Q(x)		_SB_MAKEVALUE(x,S_IO_DRV_Q)
++#define G_IO_DRV_Q(x)		_SB_GETVALUE(x,S_IO_DRV_Q,M_IO_DRV_Q)
++
++#define S_IO_DRV_R		14
++#define M_IO_DRV_R		_SB_MAKEMASK(2,S_IO_DRV_R)
++#define V_IO_DRV_R(x)		_SB_MAKEVALUE(x,S_IO_DRV_R)
++#define G_IO_DRV_R(x)		_SB_GETVALUE(x,S_IO_DRV_R,M_IO_DRV_R)
++
+ 
+ /*
+  * PCMCIA configuration register (Table 12-6)
+@@ -202,6 +327,22 @@
+ #define M_PCMCIA_CFG_RDYMASK	_SB_MAKEMASK1(8)
+ #define M_PCMCIA_CFG_PWRCTL	_SB_MAKEMASK1(9)
+ 
++#if SIBYTE_HDR_FEATURE_CHIP(1480)
++#define S_PCMCIA_MODE		16
++#define M_PCMCIA_MODE		_SB_MAKEMASK(3,S_PCMCIA_MODE)
++#define V_PCMCIA_MODE(x)	_SB_MAKEVALUE(x,S_PCMCIA_MODE)
++#define G_PCMCIA_MODE(x)	_SB_GETVALUE(x,S_PCMCIA_MODE,M_PCMCIA_MODE)
++
++#define K_PCMCIA_MODE_PCMA_NOB	0	/* standard PCMCIA "A", no "B" */
++#define K_PCMCIA_MODE_IDEA_NOB	1	/* IDE "A", no "B" */
++#define K_PCMCIA_MODE_PCMIOA_NOB 2	/* PCMCIA with I/O "A", no "B" */
++#define K_PCMCIA_MODE_PCMA_PCMB 4	/* standard PCMCIA "A", standard PCMCIA "B" */
++#define K_PCMCIA_MODE_IDEA_PCMB 5	/* IDE "A", standard PCMCIA "B" */
++#define K_PCMCIA_MODE_PCMA_IDEB 6	/* standard PCMCIA "A", IDE "B" */
++#define K_PCMCIA_MODE_IDEA_IDEB 7	/* IDE "A", IDE "B" */
++#endif
++
++
+ /*
+  * PCMCIA status register (Table 12-7)
+  */
+@@ -272,5 +413,62 @@
+ #define V_GPIO_INTR_TYPE14(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_TYPE14)
+ #define G_GPIO_INTR_TYPE14(x)	_SB_GETVALUE(x,S_GPIO_INTR_TYPE14,M_GPIO_INTR_TYPE14)
+ 
++#if SIBYTE_HDR_FEATURE_CHIP(1480)
++
++/*
++ * GPIO Interrupt Additional Type Register
++ */
++
++#define K_GPIO_INTR_BOTHEDGE	0
++#define K_GPIO_INTR_RISEEDGE	1
++#define K_GPIO_INTR_UNPRED1	2
++#define K_GPIO_INTR_UNPRED2	3
++
++#define S_GPIO_INTR_ATYPEX(n)	(((n)/2)*2)
++#define M_GPIO_INTR_ATYPEX(n)	_SB_MAKEMASK(2,S_GPIO_INTR_ATYPEX(n))
++#define V_GPIO_INTR_ATYPEX(n,x)	_SB_MAKEVALUE(x,S_GPIO_INTR_ATYPEX(n))
++#define G_GPIO_INTR_ATYPEX(n,x)	_SB_GETVALUE(x,S_GPIO_INTR_ATYPEX(n),M_GPIO_INTR_ATYPEX(n))
++
++#define S_GPIO_INTR_ATYPE0	0
++#define M_GPIO_INTR_ATYPE0	_SB_MAKEMASK(2,S_GPIO_INTR_ATYPE0)
++#define V_GPIO_INTR_ATYPE0(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE0)
++#define G_GPIO_INTR_ATYPE0(x)	_SB_GETVALUE(x,S_GPIO_INTR_ATYPE0,M_GPIO_INTR_ATYPE0)
++
++#define S_GPIO_INTR_ATYPE2	2
++#define M_GPIO_INTR_ATYPE2	_SB_MAKEMASK(2,S_GPIO_INTR_ATYPE2)
++#define V_GPIO_INTR_ATYPE2(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE2)
++#define G_GPIO_INTR_ATYPE2(x)	_SB_GETVALUE(x,S_GPIO_INTR_ATYPE2,M_GPIO_INTR_ATYPE2)
++
++#define S_GPIO_INTR_ATYPE4	4
++#define M_GPIO_INTR_ATYPE4	_SB_MAKEMASK(2,S_GPIO_INTR_ATYPE4)
++#define V_GPIO_INTR_ATYPE4(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE4)
++#define G_GPIO_INTR_ATYPE4(x)	_SB_GETVALUE(x,S_GPIO_INTR_ATYPE4,M_GPIO_INTR_ATYPE4)
++
++#define S_GPIO_INTR_ATYPE6	6
++#define M_GPIO_INTR_ATYPE6	_SB_MAKEMASK(2,S_GPIO_INTR_ATYPE6)
++#define V_GPIO_INTR_ATYPE6(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE6)
++#define G_GPIO_INTR_ATYPE6(x)	_SB_GETVALUE(x,S_GPIO_INTR_ATYPE6,M_GPIO_INTR_ATYPE6)
++
++#define S_GPIO_INTR_ATYPE8	8
++#define M_GPIO_INTR_ATYPE8	_SB_MAKEMASK(2,S_GPIO_INTR_ATYPE8)
++#define V_GPIO_INTR_ATYPE8(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE8)
++#define G_GPIO_INTR_ATYPE8(x)	_SB_GETVALUE(x,S_GPIO_INTR_ATYPE8,M_GPIO_INTR_ATYPE8)
++
++#define S_GPIO_INTR_ATYPE10	10
++#define M_GPIO_INTR_ATYPE10	_SB_MAKEMASK(2,S_GPIO_INTR_ATYPE10)
++#define V_GPIO_INTR_ATYPE10(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE10)
++#define G_GPIO_INTR_ATYPE10(x)	_SB_GETVALUE(x,S_GPIO_INTR_ATYPE10,M_GPIO_INTR_ATYPE10)
++
++#define S_GPIO_INTR_ATYPE12	12
++#define M_GPIO_INTR_ATYPE12	_SB_MAKEMASK(2,S_GPIO_INTR_ATYPE12)
++#define V_GPIO_INTR_ATYPE12(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE12)
++#define G_GPIO_INTR_ATYPE12(x)	_SB_GETVALUE(x,S_GPIO_INTR_ATYPE12,M_GPIO_INTR_ATYPE12)
++
++#define S_GPIO_INTR_ATYPE14	14
++#define M_GPIO_INTR_ATYPE14	_SB_MAKEMASK(2,S_GPIO_INTR_ATYPE14)
++#define V_GPIO_INTR_ATYPE14(x)	_SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE14)
++#define G_GPIO_INTR_ATYPE14(x)	_SB_GETVALUE(x,S_GPIO_INTR_ATYPE14,M_GPIO_INTR_ATYPE14)
++#endif
++
+ 
+ #endif
+diff --git a/include/asm-mips/sibyte/sb1250_int.h b/include/asm-mips/sibyte/sb1250_int.h
+--- a/include/asm-mips/sibyte/sb1250_int.h
++++ b/include/asm-mips/sibyte/sb1250_int.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  User's manual 1/02/02
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+@@ -47,6 +45,10 @@
+  * First, the interrupt numbers.
+  */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x
++
++#define K_INT_SOURCES               64
++
+ #define K_INT_WATCHDOG_TIMER_0      0
+ #define K_INT_WATCHDOG_TIMER_1      1
+ #define K_INT_TIMER_0               2
+@@ -244,4 +246,6 @@
+ #define M_LDTVECT_RAISEMBOX             0x40
+ 
+ 
++#endif	/* 1250/112x */
++
+ #endif
+diff --git a/include/asm-mips/sibyte/sb1250_l2c.h b/include/asm-mips/sibyte/sb1250_l2c.h
+--- a/include/asm-mips/sibyte/sb1250_l2c.h
++++ b/include/asm-mips/sibyte/sb1250_l2c.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  User's manual 1/02/02
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+@@ -89,8 +87,13 @@
+ #define V_L2C_MGMT_WAY(x)           _SB_MAKEVALUE(x,S_L2C_MGMT_WAY)
+ #define G_L2C_MGMT_WAY(x)           _SB_GETVALUE(x,S_L2C_MGMT_WAY,M_L2C_MGMT_WAY)
+ 
+-#define S_L2C_MGMT_TAG              21
+-#define M_L2C_MGMT_TAG              _SB_MAKEMASK(6,S_L2C_MGMT_TAG)
++#define S_L2C_MGMT_ECC_DIAG         21
++#define M_L2C_MGMT_ECC_DIAG         _SB_MAKEMASK(2,S_L2C_MGMT_ECC_DIAG)
++#define V_L2C_MGMT_ECC_DIAG(x)      _SB_MAKEVALUE(x,S_L2C_MGMT_ECC_DIAG)
++#define G_L2C_MGMT_ECC_DIAG(x)      _SB_GETVALUE(x,S_L2C_MGMT_ECC_DIAG,M_L2C_MGMT_ECC_DIAG)
++
++#define S_L2C_MGMT_TAG              23
++#define M_L2C_MGMT_TAG              _SB_MAKEMASK(4,S_L2C_MGMT_TAG)
+ #define V_L2C_MGMT_TAG(x)           _SB_MAKEVALUE(x,S_L2C_MGMT_TAG)
+ #define G_L2C_MGMT_TAG(x)           _SB_GETVALUE(x,S_L2C_MGMT_TAG,M_L2C_MGMT_TAG)
+ 
+diff --git a/include/asm-mips/sibyte/sb1250_ldt.h b/include/asm-mips/sibyte/sb1250_ldt.h
+--- a/include/asm-mips/sibyte/sb1250_ldt.h
++++ b/include/asm-mips/sibyte/sb1250_ldt.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  User's manual 1/02/02
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+diff --git a/include/asm-mips/sibyte/sb1250_mac.h b/include/asm-mips/sibyte/sb1250_mac.h
+--- a/include/asm-mips/sibyte/sb1250_mac.h
++++ b/include/asm-mips/sibyte/sb1250_mac.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  User's manual 1/02/02
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+@@ -81,7 +79,10 @@
+ #define M_MAC_RESERVED1             _SB_MAKEMASK(8,9)
+ 
+ #define M_MAC_AP_STAT_EN            _SB_MAKEMASK1(17)
+-#define M_MAC_RESERVED2		    _SB_MAKEMASK1(18)
++
++#if SIBYTE_HDR_FEATURE_CHIP(1480)
++#define M_MAC_TIMESTAMP		    _SB_MAKEMASK1(18)
++#endif
+ #define M_MAC_DRP_ERRPKT_EN         _SB_MAKEMASK1(19)
+ #define M_MAC_DRP_FCSERRPKT_EN      _SB_MAKEMASK1(20)
+ #define M_MAC_DRP_CODEERRPKT_EN     _SB_MAKEMASK1(21)
+@@ -132,9 +133,9 @@
+ #define M_MAC_RX_CH_SEL_MSB	    _SB_MAKEMASK1(44)
+ #endif /* 1250 PASS2 || 112x PASS1 */
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define M_MAC_SPLIT_CH_SEL	    _SB_MAKEMASK1(45)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define S_MAC_BYPASS_IFG            _SB_MAKE64(46)
+ #define M_MAC_BYPASS_IFG            _SB_MAKEMASK(8,S_MAC_BYPASS_IFG)
+@@ -176,10 +177,22 @@
+ 
+ #define M_MAC_PORT_RESET            _SB_MAKEMASK1(8)
+ 
++#if (SIBYTE_HDR_FEATURE_CHIP(1250) || SIBYTE_HDR_FEATURE_CHIP(112x))
+ #define M_MAC_RX_ENABLE             _SB_MAKEMASK1(10)
+ #define M_MAC_TX_ENABLE             _SB_MAKEMASK1(11)
+ #define M_MAC_BYP_RX_ENABLE         _SB_MAKEMASK1(12)
+ #define M_MAC_BYP_TX_ENABLE         _SB_MAKEMASK1(13)
++#endif
++
++/*
++ * MAC reset information register (1280/1255)
++ */
++#if SIBYTE_HDR_FEATURE_CHIP(1480)
++#define M_MAC_RX_CH0_PAUSE_ON	_SB_MAKEMASK1(8)
++#define M_MAC_RX_CH1_PAUSE_ON	_SB_MAKEMASK1(16)
++#define M_MAC_TX_CH0_PAUSE_ON	_SB_MAKEMASK1(24)
++#define M_MAC_TX_CH1_PAUSE_ON	_SB_MAKEMASK1(32)
++#endif
+ 
+ /*
+  * MAC DMA Control Register
+@@ -267,12 +280,12 @@
+ #define V_MAC_IFG_RX(x)             _SB_MAKEVALUE(x,S_MAC_IFG_RX)
+ #define G_MAC_IFG_RX(x)             _SB_GETVALUE(x,S_MAC_IFG_RX,M_MAC_IFG_RX)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define S_MAC_PRE_LEN               _SB_MAKE64(0)
+ #define M_MAC_PRE_LEN               _SB_MAKEMASK(6,S_MAC_PRE_LEN)
+ #define V_MAC_PRE_LEN(x)            _SB_MAKEVALUE(x,S_MAC_PRE_LEN)
+ #define G_MAC_PRE_LEN(x)            _SB_GETVALUE(x,S_MAC_PRE_LEN,M_MAC_PRE_LEN)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ #define S_MAC_IFG_TX                _SB_MAKE64(6)
+ #define M_MAC_IFG_TX                _SB_MAKEMASK(6,S_MAC_IFG_TX)
+@@ -458,9 +471,9 @@
+ #define V_MAC_COUNTER_ADDR(x)       _SB_MAKEVALUE(x,S_MAC_COUNTER_ADDR)
+ #define G_MAC_COUNTER_ADDR(x)       _SB_GETVALUE(x,S_MAC_COUNTER_ADDR,M_MAC_COUNTER_ADDR)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define M_MAC_TX_PAUSE_ON	    _SB_MAKEMASK1(52)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ /*
+  * MAC Fifo Pointer Registers (Table 9-19)    [Debug register]
+@@ -594,7 +607,7 @@
+ #define V_MAC_IPHDR_OFFSET(x)	_SB_MAKEVALUE(x,S_MAC_IPHDR_OFFSET)
+ #define G_MAC_IPHDR_OFFSET(x)	_SB_GETVALUE(x,S_MAC_IPHDR_OFFSET,M_MAC_IPHDR_OFFSET)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define S_MAC_RX_CRC_OFFSET     _SB_MAKE64(16)
+ #define M_MAC_RX_CRC_OFFSET     _SB_MAKEMASK(8,S_MAC_RX_CRC_OFFSET)
+ #define V_MAC_RX_CRC_OFFSET(x)	_SB_MAKEVALUE(x,S_MAC_RX_CRC_OFFSET)
+@@ -612,7 +625,7 @@
+ #define M_MAC_RX_CH_MSN_SEL     _SB_MAKEMASK(8,S_MAC_RX_CH_MSN_SEL)
+ #define V_MAC_RX_CH_MSN_SEL(x)	_SB_MAKEVALUE(x,S_MAC_RX_CH_MSN_SEL)
+ #define G_MAC_RX_CH_MSN_SEL(x)	_SB_GETVALUE(x,S_MAC_RX_CH_MSN_SEL,M_MAC_RX_CH_MSN_SEL)
+-#endif /* 1250 PASS3 || 112x PASS1 */
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+ 
+ /*
+  * MAC Receive Channel Select Registers (Table 9-25)
+diff --git a/include/asm-mips/sibyte/sb1250_mc.h b/include/asm-mips/sibyte/sb1250_mc.h
+--- a/include/asm-mips/sibyte/sb1250_mc.h
++++ b/include/asm-mips/sibyte/sb1250_mc.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  User's manual 1/02/02
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+@@ -324,6 +322,10 @@
+ #define K_MC_tRFC_DEFAULT         12
+ #define V_MC_tRFC_DEFAULT         V_MC_tRFC(K_MC_tRFC_DEFAULT)
+ 
++#if SIBYTE_HDR_FEATURE(1250, PASS3)
++#define M_MC_tRFC_PLUS16          _SB_MAKEMASK1(51)	/* 1250C3 and later.  */
++#endif
++
+ #define S_MC_tCwCr                40
+ #define M_MC_tCwCr                _SB_MAKEMASK(4,S_MC_tCwCr)
+ #define V_MC_tCwCr(x)             _SB_MAKEVALUE(x,S_MC_tCwCr)
+diff --git a/include/asm-mips/sibyte/sb1250_regs.h b/include/asm-mips/sibyte/sb1250_regs.h
+--- a/include/asm-mips/sibyte/sb1250_regs.h
++++ b/include/asm-mips/sibyte/sb1250_regs.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  01/02/2002
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+@@ -61,6 +59,8 @@
+  * XXX: can't remove MC base 0 if 112x, since it's used by other macros,
+  * since there is one reg there (but it could get its addr/offset constant).
+  */
++
++#if SIBYTE_HDR_FEATURE_1250_112x		/* This MC only on 1250 & 112x */
+ #define A_MC_BASE_0                 0x0010051000
+ #define A_MC_BASE_1                 0x0010052000
+ #define MC_REGISTER_SPACING         0x1000
+@@ -101,10 +101,14 @@
+ #define R_MC_TEST_ECC               0x0000000420
+ #define R_MC_MCLK_CFG               0x0000000500
+ 
++#endif	/* 1250 & 112x */
++
+ /*  *********************************************************************
+     * L2 Cache Control Registers
+     ********************************************************************* */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x	/* This L2C only on 1250/112x */
++
+ #define A_L2_READ_TAG               0x0010040018
+ #define A_L2_ECC_TAG                0x0010040038
+ #if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+@@ -125,13 +129,16 @@
+ #define A_L2_READ_ADDRESS           A_L2_READ_TAG
+ #define A_L2_EEC_ADDRESS            A_L2_ECC_TAG
+ 
++#endif
+ 
+ /*  *********************************************************************
+     * PCI Interface Registers
+     ********************************************************************* */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x	/* This PCI/HT only on 1250/112x */
+ #define A_PCI_TYPE00_HEADER         0x00DE000000
+ #define A_PCI_TYPE01_HEADER         0x00DE000800
++#endif
+ 
+ 
+ /*  *********************************************************************
+@@ -264,15 +271,15 @@
+     ********************************************************************* */
+ 
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x		/* This MC only on 1250 & 112x */
+ #define R_DUART_NUM_PORTS           2
+ 
+ #define A_DUART                     0x0010060000
+ 
+-#define A_DUART_REG(r)
+-
+ #define DUART_CHANREG_SPACING       0x100
+ #define A_DUART_CHANREG(chan,reg)   (A_DUART + DUART_CHANREG_SPACING*(chan) + (reg))
+ #define R_DUART_CHANREG(chan,reg)   (DUART_CHANREG_SPACING*(chan) + (reg))
++#endif	/* 1250 & 112x */
+ 
+ #define R_DUART_MODE_REG_1	    0x100
+ #define R_DUART_MODE_REG_2	    0x110
+@@ -307,11 +314,13 @@
+ 
+ #define DUART_IMRISR_SPACING        0x20
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x		/* This MC only on 1250 & 112x */
+ #define R_DUART_IMRREG(chan)	    (R_DUART_IMR_A + (chan)*DUART_IMRISR_SPACING)
+ #define R_DUART_ISRREG(chan)	    (R_DUART_ISR_A + (chan)*DUART_IMRISR_SPACING)
+ 
+ #define A_DUART_IMRREG(chan)	    (A_DUART + R_DUART_IMRREG(chan))
+ #define A_DUART_ISRREG(chan)	    (A_DUART + R_DUART_ISRREG(chan))
++#endif	/* 1250 & 112x */
+ 
+ 
+ 
+@@ -368,6 +377,8 @@
+     ********************************************************************* */
+ 
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x	/* sync serial only on 1250/112x */
++
+ #define A_SER_BASE_0                0x0010060400
+ #define A_SER_BASE_1                0x0010060800
+ #define SER_SPACING                 0x400
+@@ -457,6 +468,8 @@
+ #define R_SER_RMON_RX_ERRORS        0x000001F0
+ #define R_SER_RMON_RX_BADADDR       0x000001F8
+ 
++#endif	/* 1250/112x */
++
+ /*  *********************************************************************
+     * Generic Bus Registers
+     ********************************************************************* */
+@@ -634,12 +647,13 @@
+ 
+ #if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+ #define A_SCD_SCRATCH		   0x0010020C10
++#endif /* 1250 PASS2 || 112x PASS1 */
+ 
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define A_SCD_ZBBUS_CYCLE_COUNT	   0x0010030000
+ #define A_SCD_ZBBUS_CYCLE_CP0	   0x0010020C00
+ #define A_SCD_ZBBUS_CYCLE_CP1	   0x0010020C08
+-#endif /* 1250 PASS2 || 112x PASS1 */
+-
++#endif
+ 
+ /*  *********************************************************************
+     * System Control Registers
+@@ -667,15 +681,16 @@
+ #define A_ADDR_TRAP_CFG_1           0x0010020448
+ #define A_ADDR_TRAP_CFG_2           0x0010020450
+ #define A_ADDR_TRAP_CFG_3           0x0010020458
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ #define A_ADDR_TRAP_REG_DEBUG	    0x0010020460
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ 
+ 
+ /*  *********************************************************************
+     * System Interrupt Mapper Registers
+     ********************************************************************* */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x
+ #define A_IMR_CPU0_BASE                 0x0010020000
+ #define A_IMR_CPU1_BASE                 0x0010022000
+ #define IMR_REGISTER_SPACING            0x2000
+@@ -700,6 +715,7 @@
+ #define R_IMR_INTERRUPT_STATUS_COUNT    7
+ #define R_IMR_INTERRUPT_MAP_BASE        0x0200
+ #define R_IMR_INTERRUPT_MAP_COUNT       64
++#endif	/* 1250/112x */
+ 
+ /*  *********************************************************************
+     * System Performance Counter Registers
+@@ -718,6 +734,7 @@
+ #define A_SCD_BUS_ERR_STATUS        0x0010020880
+ #if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+ #define A_SCD_BUS_ERR_STATUS_DEBUG  0x00100208D0
++#define A_BUS_ERR_STATUS_DEBUG  0x00100208D0
+ #endif /* 1250 PASS2 || 112x PASS1 */
+ #define A_BUS_ERR_DATA_0            0x00100208A0
+ #define A_BUS_ERR_DATA_1            0x00100208A8
+@@ -798,6 +815,7 @@
+     *  Physical Address Map
+     ********************************************************************* */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x
+ #define A_PHYS_MEMORY_0                 _SB_MAKE64(0x0000000000)
+ #define A_PHYS_MEMORY_SIZE              _SB_MAKE64((256*1024*1024))
+ #define A_PHYS_SYSTEM_CTL               _SB_MAKE64(0x0010000000)
+@@ -831,6 +849,7 @@
+ #define A_PHYS_L2CACHE_WAY1             _SB_MAKE64(0x00D01A0000)
+ #define A_PHYS_L2CACHE_WAY2             _SB_MAKE64(0x00D01C0000)
+ #define A_PHYS_L2CACHE_WAY3             _SB_MAKE64(0x00D01E0000)
++#endif
+ 
+ 
+ #endif
+diff --git a/include/asm-mips/sibyte/sb1250_scd.h b/include/asm-mips/sibyte/sb1250_scd.h
+--- a/include/asm-mips/sibyte/sb1250_scd.h
++++ b/include/asm-mips/sibyte/sb1250_scd.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  User's manual 1/02/02
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+@@ -51,26 +49,70 @@
+ #define V_SYS_REVISION(x)           _SB_MAKEVALUE(x,S_SYS_REVISION)
+ #define G_SYS_REVISION(x)           _SB_GETVALUE(x,S_SYS_REVISION,M_SYS_REVISION)
+ 
+-#if SIBYTE_HDR_FEATURE_CHIP(1250)
+-#define K_SYS_REVISION_BCM1250_PASS1	1
+-#define K_SYS_REVISION_BCM1250_PASS2	3
+-#define K_SYS_REVISION_BCM1250_A10	11
+-#define K_SYS_REVISION_BCM1250_PASS2_2	16
+-#define K_SYS_REVISION_BCM1250_B2	17
+-#define K_SYS_REVISION_BCM1250_PASS3	32
+-#define K_SYS_REVISION_BCM1250_C1	33
++#define K_SYS_REVISION_BCM1250_PASS1	0x01
+ 
++#define K_SYS_REVISION_BCM1250_PASS2	0x03
++#define K_SYS_REVISION_BCM1250_A1	0x03	/* Pass 2.0 WB */
++#define K_SYS_REVISION_BCM1250_A2	0x04	/* Pass 2.0 FC */
++#define K_SYS_REVISION_BCM1250_A3	0x05	/* Pass 2.1 FC */
++#define K_SYS_REVISION_BCM1250_A4	0x06	/* Pass 2.1 WB */
++#define K_SYS_REVISION_BCM1250_A6	0x07	/* OR 0x04 (A2) w/WID != 0 */
++#define K_SYS_REVISION_BCM1250_A8	0x0b	/* A8/A10 */
++#define K_SYS_REVISION_BCM1250_A9	0x08
++#define K_SYS_REVISION_BCM1250_A10	K_SYS_REVISION_BCM1250_A8
++
++#define K_SYS_REVISION_BCM1250_PASS2_2	0x10
++#define K_SYS_REVISION_BCM1250_B0	K_SYS_REVISION_BCM1250_B1
++#define K_SYS_REVISION_BCM1250_B1	0x10
++#define K_SYS_REVISION_BCM1250_B2	0x11
++
++#define K_SYS_REVISION_BCM1250_C0	0x20
++#define K_SYS_REVISION_BCM1250_C1	0x21
++#define K_SYS_REVISION_BCM1250_C2	0x22
++#define K_SYS_REVISION_BCM1250_C3	0x23
++
++#if SIBYTE_HDR_FEATURE_CHIP(1250)
+ /* XXX: discourage people from using these constants.  */
+ #define K_SYS_REVISION_PASS1	    K_SYS_REVISION_BCM1250_PASS1
+ #define K_SYS_REVISION_PASS2	    K_SYS_REVISION_BCM1250_PASS2
+ #define K_SYS_REVISION_PASS2_2	    K_SYS_REVISION_BCM1250_PASS2_2
+ #define K_SYS_REVISION_PASS3	    K_SYS_REVISION_BCM1250_PASS3
++#define K_SYS_REVISION_BCM1250_PASS3	K_SYS_REVISION_BCM1250_C0
+ #endif /* 1250 */
+ 
+-#if SIBYTE_HDR_FEATURE_CHIP(112x)
+-#define K_SYS_REVISION_BCM112x_A1	32
+-#define K_SYS_REVISION_BCM112x_A2	33
+-#endif /* 112x */
++#define K_SYS_REVISION_BCM112x_A1	0x20
++#define K_SYS_REVISION_BCM112x_A2	0x21
++#define K_SYS_REVISION_BCM112x_A3	0x22
++#define K_SYS_REVISION_BCM112x_A4	0x23
++
++#define K_SYS_REVISION_BCM1480_S0	0x01
++#define K_SYS_REVISION_BCM1480_A1	0x02
++#define K_SYS_REVISION_BCM1480_A2	0x03
++#define K_SYS_REVISION_BCM1480_A3	0x04
++#define K_SYS_REVISION_BCM1480_B0	0x11
++
++/*Cache size - 23:20  of revision register*/
++#define S_SYS_L2C_SIZE            _SB_MAKE64(20)
++#define M_SYS_L2C_SIZE            _SB_MAKEMASK(4,S_SYS_L2C_SIZE)
++#define V_SYS_L2C_SIZE(x)         _SB_MAKEVALUE(x,S_SYS_L2C_SIZE)
++#define G_SYS_L2C_SIZE(x)         _SB_GETVALUE(x,S_SYS_L2C_SIZE,M_SYS_L2C_SIZE)
++
++#define K_SYS_L2C_SIZE_1MB	0
++#define K_SYS_L2C_SIZE_512KB	5
++#define K_SYS_L2C_SIZE_256KB	2
++#define K_SYS_L2C_SIZE_128KB	1
++
++#define K_SYS_L2C_SIZE_BCM1250	K_SYS_L2C_SIZE_512KB
++#define K_SYS_L2C_SIZE_BCM1125	K_SYS_L2C_SIZE_256KB
++#define K_SYS_L2C_SIZE_BCM1122	K_SYS_L2C_SIZE_128KB
++
++
++/* Number of CPU cores, bits 27:24  of revision register*/
++#define S_SYS_NUM_CPUS            _SB_MAKE64(24)
++#define M_SYS_NUM_CPUS            _SB_MAKEMASK(4,S_SYS_NUM_CPUS)
++#define V_SYS_NUM_CPUS(x)         _SB_MAKEVALUE(x,S_SYS_NUM_CPUS)
++#define G_SYS_NUM_CPUS(x)         _SB_GETVALUE(x,S_SYS_NUM_CPUS,M_SYS_NUM_CPUS)
++
+ 
+ /* XXX: discourage people from using these constants.  */
+ #define S_SYS_PART                  _SB_MAKE64(16)
+@@ -83,6 +125,8 @@
+ #define K_SYS_PART_BCM1120          0x1121
+ #define K_SYS_PART_BCM1125          0x1123
+ #define K_SYS_PART_BCM1125H         0x1124
++#define K_SYS_PART_BCM1122          0x1113
++
+ 
+ /* The "peripheral set" (SOC type) is the low 4 bits of the "part" field.  */
+ #define S_SYS_SOC_TYPE              _SB_MAKE64(16)
+@@ -96,6 +140,8 @@
+ #define K_SYS_SOC_TYPE_BCM1125      0x3
+ #define K_SYS_SOC_TYPE_BCM1125H     0x4
+ #define K_SYS_SOC_TYPE_BCM1250_ALT2 0x5		/* 1250pass2 w/ 1/2 L2.  */
++#define K_SYS_SOC_TYPE_BCM1x80      0x6
++#define K_SYS_SOC_TYPE_BCM1x55      0x7
+ 
+ /*
+  * Calculate correct SOC type given a copy of system revision register.
+@@ -127,10 +173,12 @@
+ #define V_SYS_WID(x)                _SB_MAKEVALUE(x,S_SYS_WID)
+ #define G_SYS_WID(x)                _SB_GETVALUE(x,S_SYS_WID,M_SYS_WID)
+ 
+-/* System Manufacturing Register
+-* Register: SCD_SYSTEM_MANUF
+-*/
++/*
++ * System Manufacturing Register
++ * Register: SCD_SYSTEM_MANUF
++ */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x
+ /* Wafer ID: bits 31:0 */
+ #define S_SYS_WAFERID1_200        _SB_MAKE64(0)
+ #define M_SYS_WAFERID1_200        _SB_MAKEMASK(32,S_SYS_WAFERID1_200)
+@@ -139,8 +187,8 @@
+ 
+ #define S_SYS_BIN                 _SB_MAKE64(32)
+ #define M_SYS_BIN                 _SB_MAKEMASK(4,S_SYS_BIN)
+-#define V_SYS_BIN                 _SB_MAKEVALUE(x,S_SYS_BIN)
+-#define G_SYS_BIN                 _SB_GETVALUE(x,S_SYS_BIN,M_SYS_BIN)
++#define V_SYS_BIN(x)              _SB_MAKEVALUE(x,S_SYS_BIN)
++#define G_SYS_BIN(x)              _SB_GETVALUE(x,S_SYS_BIN,M_SYS_BIN)
+ 
+ /* Wafer ID: bits 39:36 */
+ #define S_SYS_WAFERID2_200        _SB_MAKE64(36)
+@@ -163,12 +211,14 @@
+ #define M_SYS_YPOS                _SB_MAKEMASK(6,S_SYS_YPOS)
+ #define V_SYS_YPOS(x)             _SB_MAKEVALUE(x,S_SYS_YPOS)
+ #define G_SYS_YPOS(x)             _SB_GETVALUE(x,S_SYS_YPOS,M_SYS_YPOS)
++#endif
+ 
+ /*
+  * System Config Register (Table 4-2)
+  * Register: SCD_SYSTEM_CFG
+  */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x
+ #define M_SYS_LDT_PLL_BYP           _SB_MAKEMASK1(3)
+ #define M_SYS_PCI_SYNC_TEST_MODE    _SB_MAKEMASK1(4)
+ #define M_SYS_IOB0_DIV              _SB_MAKEMASK1(5)
+@@ -253,6 +303,8 @@
+ #define M_SYS_SW_FLAG		    _SB_MAKEMASK1(63)
+ #endif /* 1250 PASS2 || 112x PASS1 */
+ 
++#endif
++
+ 
+ /*
+  * Mailbox Registers (Table 4-3)
+@@ -326,6 +378,7 @@
+  * System Performance Counters
+  */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x
+ #define S_SPC_CFG_SRC0            0
+ #define M_SPC_CFG_SRC0            _SB_MAKEMASK(8,S_SPC_CFG_SRC0)
+ #define V_SPC_CFG_SRC0(x)         _SB_MAKEVALUE(x,S_SPC_CFG_SRC0)
+@@ -348,6 +401,7 @@
+ 
+ #define M_SPC_CFG_CLEAR		_SB_MAKEMASK1(32)
+ #define M_SPC_CFG_ENABLE	_SB_MAKEMASK1(33)
++#endif
+ 
+ 
+ /*
+@@ -412,6 +466,7 @@
+  * Address Trap Registers
+  */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x
+ #define M_ATRAP_INDEX		  _SB_MAKEMASK(4,0)
+ #define M_ATRAP_ADDRESS		  _SB_MAKEMASK(40,0)
+ 
+@@ -436,7 +491,6 @@
+ #define K_BUS_AGENT_IOB0	2
+ #define K_BUS_AGENT_IOB1	3
+ #define K_BUS_AGENT_SCD	4
+-#define K_BUS_AGENT_RESERVED	5
+ #define K_BUS_AGENT_L2C	6
+ #define K_BUS_AGENT_MC	7
+ 
+@@ -454,10 +508,14 @@
+ #define K_ATRAP_CFG_CATTR_NOTNONCOH	6
+ #define K_ATRAP_CFG_CATTR_NOTCOHERENT   7
+ 
++#endif	/* 1250/112x */
++
+ /*
+  * Trace Buffer Config register
+  */
+ 
++#if SIBYTE_HDR_FEATURE_1250_112x
++
+ #define M_SCD_TRACE_CFG_RESET           _SB_MAKEMASK1(0)
+ #define M_SCD_TRACE_CFG_START_READ      _SB_MAKEMASK1(1)
+ #define M_SCD_TRACE_CFG_START           _SB_MAKEMASK1(2)
+@@ -475,6 +533,8 @@
+ #define V_SCD_TRACE_CFG_CUR_ADDR(x)     _SB_MAKEVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR)
+ #define G_SCD_TRACE_CFG_CUR_ADDR(x)     _SB_GETVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR,M_SCD_TRACE_CFG_CUR_ADDR)
+ 
++#endif	/* 1250/112x */
++
+ /*
+  * Trace Event registers
+  */
+@@ -578,5 +638,7 @@
+ #define M_SCD_TRSEQ_DEBUGPIN            _SB_MAKEMASK1(20)
+ #define M_SCD_TRSEQ_DEBUGCPU            _SB_MAKEMASK1(21)
+ #define M_SCD_TRSEQ_CLEARUSE            _SB_MAKEMASK1(22)
++#define M_SCD_TRSEQ_ALLD_A              _SB_MAKEMASK1(23)
++#define M_SCD_TRSEQ_ALL_A               _SB_MAKEMASK1(24)
+ 
+ #endif
+diff --git a/include/asm-mips/sibyte/sb1250_smbus.h b/include/asm-mips/sibyte/sb1250_smbus.h
+--- a/include/asm-mips/sibyte/sb1250_smbus.h
++++ b/include/asm-mips/sibyte/sb1250_smbus.h
+@@ -6,9 +6,8 @@
+     *  This module contains constants and macros useful for
+     *  manipulating the SB1250's SMbus devices.
+     *
+-    *  SB1250 specification level:  01/02/2002
+-    *
+-    *  Author:  Mitch Lichtenberg
++    *  SB1250 specification level:  10/21/02
++    *  BCM1280 specification level:  11/24/03
+     *
+     *********************************************************************
+     *
+@@ -47,6 +46,7 @@
+ 
+ #define K_SMB_FREQ_400KHZ	    0x1F
+ #define K_SMB_FREQ_100KHZ	    0x7D
++#define K_SMB_FREQ_10KHZ	    1250
+ 
+ #define S_SMB_CMD                   0
+ #define M_SMB_CMD                   _SB_MAKEMASK(8,S_SMB_CMD)
+@@ -58,7 +58,11 @@
+ 
+ #define M_SMB_ERR_INTR              _SB_MAKEMASK1(0)
+ #define M_SMB_FINISH_INTR           _SB_MAKEMASK1(1)
+-#define M_SMB_DATA_OUT              _SB_MAKEMASK1(4)
++
++#define S_SMB_DATA_OUT              4
++#define M_SMB_DATA_OUT              _SB_MAKEMASK1(S_SMB_DATA_OUT)
++#define V_SMB_DATA_OUT(x)           _SB_MAKEVALUE(x,S_SMB_DATA_OUT)
++
+ #define M_SMB_DATA_DIR              _SB_MAKEMASK1(5)
+ #define M_SMB_DATA_DIR_OUTPUT       M_SMB_DATA_DIR
+ #define M_SMB_CLK_OUT               _SB_MAKEMASK1(6)
+@@ -71,8 +75,23 @@
+ #define M_SMB_BUSY                  _SB_MAKEMASK1(0)
+ #define M_SMB_ERROR                 _SB_MAKEMASK1(1)
+ #define M_SMB_ERROR_TYPE            _SB_MAKEMASK1(2)
+-#define M_SMB_REF                   _SB_MAKEMASK1(6)
+-#define M_SMB_DATA_IN               _SB_MAKEMASK1(7)
++
++#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
++#define S_SMB_SCL_IN                5
++#define M_SMB_SCL_IN                _SB_MAKEMASK1(S_SMB_SCL_IN)
++#define V_SMB_SCL_IN(x)             _SB_MAKEVALUE(x,S_SMB_SCL_IN)
++#define G_SMB_SCL_IN(x)             _SB_GETVALUE(x,S_SMB_SCL_IN,M_SMB_SCL_IN)
++#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
++
++#define S_SMB_REF                   6
++#define M_SMB_REF                   _SB_MAKEMASK1(S_SMB_REF)
++#define V_SMB_REF(x)                _SB_MAKEVALUE(x,S_SMB_REF)
++#define G_SMB_REF(x)                _SB_GETVALUE(x,S_SMB_REF,M_SMB_REF)
++
++#define S_SMB_DATA_IN               7
++#define M_SMB_DATA_IN               _SB_MAKEMASK1(S_SMB_DATA_IN)
++#define V_SMB_DATA_IN(x)            _SB_MAKEVALUE(x,S_SMB_DATA_IN)
++#define G_SMB_DATA_IN(x)            _SB_GETVALUE(x,S_SMB_DATA_IN,M_SMB_DATA_IN)
+ 
+ /*
+  * SMBus Start/Command registers (Table 14-9)
+@@ -132,16 +151,14 @@
+ #define V_SPEC_MB(x)                _SB_MAKEVALUE(x,S_SPEC_PEC)
+ 
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ 
+ #define S_SMB_CMDH                  8
+-#define M_SMB_CMDH                  _SB_MAKEMASK(8,S_SMBH_CMD)
+-#define V_SMB_CMDH(x)               _SB_MAKEVALUE(x,S_SMBH_CMD)
++#define M_SMB_CMDH                  _SB_MAKEMASK(8,S_SMB_CMDH)
++#define V_SMB_CMDH(x)               _SB_MAKEVALUE(x,S_SMB_CMDH)
+ 
+ #define M_SMB_EXTEND		    _SB_MAKEMASK1(14)
+ 
+-#define M_SMB_DIR		    _SB_MAKEMASK1(13)
+-
+ #define S_SMB_DFMT                  8
+ #define M_SMB_DFMT                  _SB_MAKEMASK(3,S_SMB_DFMT)
+ #define V_SMB_DFMT(x)               _SB_MAKEVALUE(x,S_SMB_DFMT)
+@@ -165,6 +182,23 @@
+ #define V_SMB_DFMT_CMD5BYTE	    V_SMB_DFMT(K_SMB_DFMT_CMD5BYTE)
+ #define V_SMB_DFMT_RESERVED	    V_SMB_DFMT(K_SMB_DFMT_RESERVED)
+ 
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#define S_SMB_AFMT                  11
++#define M_SMB_AFMT                  _SB_MAKEMASK(2,S_SMB_AFMT)
++#define V_SMB_AFMT(x)               _SB_MAKEVALUE(x,S_SMB_AFMT)
++#define G_SMB_AFMT(x)               _SB_GETVALUE(x,S_SMB_AFMT,M_SMB_AFMT)
++
++#define K_SMB_AFMT_NONE             0
++#define K_SMB_AFMT_ADDR             1
++#define K_SMB_AFMT_ADDR_CMD1BYTE    2
++#define K_SMB_AFMT_ADDR_CMD2BYTE    3
++
++#define V_SMB_AFMT_NONE		    V_SMB_AFMT(K_SMB_AFMT_NONE)
++#define V_SMB_AFMT_ADDR		    V_SMB_AFMT(K_SMB_AFMT_ADDR)
++#define V_SMB_AFMT_ADDR_CMD1BYTE    V_SMB_AFMT(K_SMB_AFMT_ADDR_CMD1BYTE)
++#define V_SMB_AFMT_ADDR_CMD2BYTE    V_SMB_AFMT(K_SMB_AFMT_ADDR_CMD2BYTE)
++
++#define M_SMB_DIR		    _SB_MAKEMASK1(13)
++
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ 
+ #endif
+diff --git a/include/asm-mips/sibyte/sb1250_syncser.h b/include/asm-mips/sibyte/sb1250_syncser.h
+--- a/include/asm-mips/sibyte/sb1250_syncser.h
++++ b/include/asm-mips/sibyte/sb1250_syncser.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  User's manual 1/02/02
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+diff --git a/include/asm-mips/sibyte/sb1250_uart.h b/include/asm-mips/sibyte/sb1250_uart.h
+--- a/include/asm-mips/sibyte/sb1250_uart.h
++++ b/include/asm-mips/sibyte/sb1250_uart.h
+@@ -8,8 +8,6 @@
+     *
+     *  SB1250 specification level:  User's manual 1/02/02
+     *
+-    *  Author:  Mitch Lichtenberg
+-    *
+     *********************************************************************
+     *
+     *  Copyright 2000,2001,2002,2003
+@@ -240,7 +238,12 @@
+  */
+ 
+ #define M_DUART_ISR_TX_A            _SB_MAKEMASK1(0)
+-#define M_DUART_ISR_RX_A            _SB_MAKEMASK1(1)
++
++#define S_DUART_ISR_RX_A            1
++#define M_DUART_ISR_RX_A            _SB_MAKEMASK1(S_DUART_ISR_RX_A)
++#define V_DUART_ISR_RX_A(x)         _SB_MAKEVALUE(x,S_DUART_ISR_RX_A)
++#define G_DUART_ISR_RX_A(x)         _SB_GETVALUE(x,S_DUART_ISR_RX_A,M_DUART_ISR_RX_A)
++
+ #define M_DUART_ISR_BRK_A           _SB_MAKEMASK1(2)
+ #define M_DUART_ISR_IN_A            _SB_MAKEMASK1(3)
+ #define M_DUART_ISR_TX_B            _SB_MAKEMASK1(4)
+@@ -331,7 +334,7 @@
+ #define M_DUART_OUT_PIN_CLR(chan) \
+     (chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1)
+ 
+-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
++#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+ /*
+  * Full Interrupt Control Register
+  */
+@@ -345,7 +348,7 @@
+ #define M_DUART_INT_TIME           _SB_MAKEMASK(4,S_DUART_INT_TIME)
+ #define V_DUART_INT_TIME(x)        _SB_MAKEVALUE(x,S_DUART_INT_TIME)
+ #define G_DUART_INT_TIME(x)        _SB_GETVALUE(x,S_DUART_INT_TIME,M_DUART_INT_TIME)
+-#endif /* 1250 PASS2 || 112x PASS1 */
++#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+ 
+ 
+ /* ********************************************************************** */
+diff --git a/include/asm-mips/sibyte/swarm.h b/include/asm-mips/sibyte/swarm.h
+--- a/include/asm-mips/sibyte/swarm.h
++++ b/include/asm-mips/sibyte/swarm.h
+@@ -34,7 +34,7 @@
+ #define SIBYTE_DEFAULT_CONSOLE "ttyS0,115200"
+ #endif
+ #ifdef CONFIG_SIBYTE_LITTLESUR
+-#define SIBYTE_BOARD_NAME "BCM1250C2 (LittleSur)"
++#define SIBYTE_BOARD_NAME "BCM91250C2 (LittleSur)"
+ #define SIBYTE_HAVE_PCMCIA 0
+ #define SIBYTE_HAVE_IDE    1
+ #define SIBYTE_DEFAULT_CONSOLE "cfe0"
+diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h
+--- a/include/asm-mips/sigcontext.h
++++ b/include/asm-mips/sigcontext.h
+@@ -27,14 +27,15 @@ struct sigcontext {
+ 	unsigned int		sc_fpc_csr;
+ 	unsigned int		sc_fpc_eir;	/* Unused */
+ 	unsigned int		sc_used_math;
+-	unsigned int		sc_ssflags;	/* Unused */
++	unsigned int		sc_dsp;		/* dsp status, was sc_ssflags */
+ 	unsigned long long	sc_mdhi;
+ 	unsigned long long	sc_mdlo;
+-
+-	unsigned int		sc_cause;	/* Unused */
+-	unsigned int		sc_badvaddr;	/* Unused */
+-
+-	unsigned long		sc_sigset[4];	/* kernel's sigset_t */
++	unsigned long		sc_hi1;		/* Was sc_cause */
++	unsigned long		sc_lo1;		/* Was sc_badvaddr */
++	unsigned long		sc_hi2;		/* Was sc_sigset[4] */
++	unsigned long		sc_lo2;
++	unsigned long		sc_hi3;
++	unsigned long		sc_lo3;
+ };
+ 
+ #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+@@ -48,19 +49,19 @@ struct sigcontext {
+  * Warning: this structure illdefined with sc_badvaddr being just an unsigned
+  * int so it was changed to unsigned long in 2.6.0-test1.  This may break
+  * binary compatibility - no prisoners.
++ * DSP ASE in 2.6.12-rc4.  Turn sc_mdhi and sc_mdlo into an array of four
++ * entries, add sc_dsp and sc_reserved for padding.  No prisoners.
+  */
+ struct sigcontext {
+ 	unsigned long	sc_regs[32];
+ 	unsigned long	sc_fpregs[32];
+-	unsigned long	sc_mdhi;
+-	unsigned long	sc_mdlo;
++	unsigned long	sc_hi[4];
++	unsigned long	sc_lo[4];
+ 	unsigned long	sc_pc;
+-	unsigned long	sc_badvaddr;
+-	unsigned int	sc_status;
+ 	unsigned int	sc_fpc_csr;
+-	unsigned int	sc_fpc_eir;
+ 	unsigned int	sc_used_math;
+-	unsigned int	sc_cause;
++	unsigned int	sc_dsp;
++	unsigned int	sc_reserved;
+ };
+ 
+ #ifdef __KERNEL__
+@@ -68,23 +69,24 @@ struct sigcontext {
+ #include <linux/posix_types.h>
+ 
+ struct sigcontext32 {
+-	__u32	sc_regmask;		/* Unused */
+-	__u32	sc_status;
+-	__u64	sc_pc;
+-	__u64	sc_regs[32];
+-	__u64	sc_fpregs[32];
+-	__u32	sc_ownedfp;		/* Unused */
+-	__u32	sc_fpc_csr;
+-	__u32	sc_fpc_eir;		/* Unused */
+-	__u32	sc_used_math;
+-	__u32	sc_ssflags;		/* Unused */
+-	__u64	sc_mdhi;
+-	__u64	sc_mdlo;
+-
+-	__u32	sc_cause;		/* Unused */
+-	__u32	sc_badvaddr;		/* Unused */
+-
+-	__u32	sc_sigset[4];		/* kernel's sigset_t */
++	__u32		sc_regmask;	/* Unused */
++	__u32		sc_status;
++	__u64		sc_pc;
++	__u64		sc_regs[32];
++	__u64		sc_fpregs[32];
++	__u32		sc_ownedfp;	/* Unused */
++	__u32		sc_fpc_csr;
++	__u32		sc_fpc_eir;	/* Unused */
++	__u32		sc_used_math;
++	__u32		sc_dsp;		/* dsp status, was sc_ssflags */
++	__u64		sc_mdhi;
++	__u64		sc_mdlo;
++	__u32		sc_hi1;		/* Was sc_cause */
++	__u32		sc_lo1;		/* Was sc_badvaddr */
++	__u32		sc_hi2;		/* Was sc_sigset[4] */
++	__u32		sc_lo2;
++	__u32		sc_hi3;
++	__u32		sc_lo3;
+ };
+ #endif /* __KERNEL__ */
+ 
+diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h
+--- a/include/asm-mips/siginfo.h
++++ b/include/asm-mips/siginfo.h
+@@ -11,6 +11,7 @@
+ 
+ #include <linux/config.h>
+ 
++#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int))
+ #undef __ARCH_SI_TRAPNO	/* exception code needs to fill this ...  */
+ 
+ #define HAVE_ARCH_SIGINFO_T
+diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h
+--- a/include/asm-mips/signal.h
++++ b/include/asm-mips/signal.h
+@@ -98,12 +98,39 @@ typedef unsigned long old_sigset_t;		/* 
+ #define MINSIGSTKSZ    2048
+ #define SIGSTKSZ       8192
+ 
++#ifdef __KERNEL__
++
++/*
++ * These values of sa_flags are used only by the kernel as part of the
++ * irq handling routines.
++ *
++ * SA_INTERRUPT is also used by the irq handling routines.
++ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
++ */
++#define SA_SAMPLE_RANDOM	SA_RESTART
++
++#ifdef CONFIG_TRAD_SIGNALS
++#define sig_uses_siginfo(ka)	((ka)->sa.sa_flags & SA_SIGINFO)
++#else
++#define sig_uses_siginfo(ka)	(1)
++#endif
++
++#endif /* __KERNEL__ */
++
+ #define SIG_BLOCK	1	/* for blocking signals */
+ #define SIG_UNBLOCK	2	/* for unblocking signals */
+ #define SIG_SETMASK	3	/* for setting the signal mask */
+ #define SIG_SETMASK32	256	/* Goodie from SGI for BSD compatibility:
+ 				   set only the low 32 bit of the sigset.  */
+-#include <asm-generic/signal.h>
++
++/* Type of a signal handler.  */
++typedef void __signalfn_t(int);
++typedef __signalfn_t __user *__sighandler_t;
++
++/* Fake signal functions */
++#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
++#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
++#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+ 
+ struct sigaction {
+ 	unsigned int	sa_flags;
+diff --git a/include/asm-mips/sn/sn0/arch.h b/include/asm-mips/sn/sn0/arch.h
+--- a/include/asm-mips/sn/sn0/arch.h
++++ b/include/asm-mips/sn/sn0/arch.h
+@@ -74,13 +74,8 @@
+ #define MAX_MEM_SLOTS   32                      /* max slots per node */
+ #endif /* defined(N_MODE) */
+ 
+-#if SABLE_RTL
+-#define SLOT_SHIFT      	(28)
+-#define SLOT_MIN_MEM_SIZE	(16*1024*1024)
+-#else
+ #define SLOT_SHIFT      	(27)
+ #define SLOT_MIN_MEM_SIZE	(32*1024*1024)
+-#endif
+ 
+ #define CPUS_PER_NODE		2	/* CPUs on a single hub */
+ #define CPUS_PER_NODE_SHFT	1	/* Bits to shift in the node number */
+diff --git a/include/asm-mips/socket.h b/include/asm-mips/socket.h
+--- a/include/asm-mips/socket.h
++++ b/include/asm-mips/socket.h
+@@ -37,8 +37,6 @@ To add: #define SO_REUSEPORT 0x0200	/* A
+ #define SO_ERROR	0x1007	/* get error status and clear */
+ #define SO_SNDBUF	0x1001	/* Send buffer size. */
+ #define SO_RCVBUF	0x1002	/* Receive buffer. */
+-#define SO_SNDBUFFORCE	0x100a
+-#define SO_RCVBUFFORCE	0x100b
+ #define SO_SNDLOWAT	0x1003	/* send low-water mark */
+ #define SO_RCVLOWAT	0x1004	/* receive low-water mark */
+ #define SO_SNDTIMEO	0x1005	/* send timeout */
+@@ -69,6 +67,8 @@ To add: #define SO_REUSEPORT 0x0200	/* A
+ #define SCM_TIMESTAMP		SO_TIMESTAMP
+ 
+ #define SO_PEERSEC		30
++#define SO_SNDBUFFORCE		31
++#define SO_RCVBUFFORCE		33
+ 
+ #ifdef __KERNEL__
+ 
+@@ -92,6 +92,7 @@ enum sock_type {
+ 	SOCK_RAW	= 3,
+ 	SOCK_RDM	= 4,
+ 	SOCK_SEQPACKET	= 5,
++	SOCK_DCCP	= 6,
+ 	SOCK_PACKET	= 10,
+ };
+ 
+diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
+--- a/include/asm-mips/spinlock.h
++++ b/include/asm-mips/spinlock.h
+@@ -9,17 +9,16 @@
+ #ifndef _ASM_SPINLOCK_H
+ #define _ASM_SPINLOCK_H
+ 
+-#include <linux/config.h>
+ #include <asm/war.h>
+ 
+ /*
+  * Your basic SMP spinlocks, allowing only a single CPU anywhere
+  */
+ 
+-#define __raw_spin_is_locked(x)	((x)->lock != 0)
++#define __raw_spin_is_locked(x)       ((x)->lock != 0)
+ #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+ #define __raw_spin_unlock_wait(x) \
+-		do { cpu_relax(); } while ((x)->lock)
++	do { cpu_relax(); } while ((x)->lock)
+ 
+ /*
+  * Simple spin lock operations.  There are two variants, one clears IRQ's
+@@ -119,6 +118,18 @@ static inline unsigned int __raw_spin_tr
+  * read-locks.
+  */
+ 
++/*
++ * read_can_lock - would read_trylock() succeed?
++ * @lock: the rwlock in question.
++ */
++#define __raw_read_can_lock(rw)	((rw)->lock >= 0)
++
++/*
++ * write_can_lock - would write_trylock() succeed?
++ * @lock: the rwlock in question.
++ */
++#define __raw_write_can_lock(rw)	(!(rw)->lock)
++
+ static inline void __raw_read_lock(raw_rwlock_t *rw)
+ {
+ 	unsigned int tmp;
+@@ -197,8 +208,7 @@ static inline void __raw_write_lock(raw_
+ 		"	 lui	%1, 0x8000				\n"
+ 		"	sc	%1, %0					\n"
+ 		"	beqzl	%1, 1b					\n"
+-		"	 nop						\n"
+-		"	sync						\n"
++		"	 sync						\n"
+ 		"	.set	reorder					\n"
+ 		: "=m" (rw->lock), "=&r" (tmp)
+ 		: "m" (rw->lock)
+@@ -211,8 +221,7 @@ static inline void __raw_write_lock(raw_
+ 		"	 lui	%1, 0x8000				\n"
+ 		"	sc	%1, %0					\n"
+ 		"	beqz	%1, 1b					\n"
+-		"	 nop						\n"
+-		"	sync						\n"
++		"	 sync						\n"
+ 		"	.set	reorder					\n"
+ 		: "=m" (rw->lock), "=&r" (tmp)
+ 		: "m" (rw->lock)
+@@ -246,8 +255,7 @@ static inline int __raw_write_trylock(ra
+ 		"	 lui	%1, 0x8000				\n"
+ 		"	sc	%1, %0					\n"
+ 		"	beqzl	%1, 1b					\n"
+-		"	 nop						\n"
+-		"	sync						\n"
++		"	 sync						\n"
+ 		"	li	%2, 1					\n"
+ 		"	.set	reorder					\n"
+ 		"2:							\n"
+diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
+--- a/include/asm-mips/stackframe.h
++++ b/include/asm-mips/stackframe.h
+@@ -60,7 +60,6 @@
+ 		mfc0	k0, CP0_CONTEXT
+ 		lui	k1, %hi(kernelsp)
+ 		srl	k0, k0, 23
+-		sll	k0, k0, 2
+ 		addu	k1, k0
+ 		LONG_L	k1, %lo(kernelsp)(k1)
+ #endif
+@@ -76,9 +75,14 @@
+ #endif
+ #if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+ 		MFC0	k1, CP0_CONTEXT
++		lui	k0, %highest(kernelsp)
+ 		dsrl	k1, 23
+-		dsll	k1, k1, 3
+-		LONG_L	k1, kernelsp(k1)
++		daddiu	k0, %higher(kernelsp)
++		dsll	k0, k0, 16
++		daddiu	k0, %hi(kernelsp)
++		dsll	k0, k0, 16
++		daddu	k1, k1, k0
++		LONG_L	k1, %lo(kernelsp)(k1)
+ #endif
+ 		.endm
+ 
+@@ -86,25 +90,28 @@
+ #ifdef CONFIG_32BIT
+ 		mfc0	\temp, CP0_CONTEXT
+ 		srl	\temp, 23
+-		sll	\temp, 2
+-		LONG_S	\stackp, kernelsp(\temp)
+ #endif
+ #if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
+ 		lw	\temp, TI_CPU(gp)
+ 		dsll	\temp, 3
+-		lui	\temp2, %hi(kernelsp)
+-		daddu	\temp, \temp2
+-		LONG_S	\stackp, %lo(kernelsp)(\temp)
+ #endif
+ #if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+-		lw	\temp, TI_CPU(gp)
+-		dsll	\temp, 3
+-		LONG_S	\stackp, kernelsp(\temp)
++		MFC0	\temp, CP0_CONTEXT
++		dsrl	\temp, 23
+ #endif
++		LONG_S	\stackp, kernelsp(\temp)
+ 		.endm
+ #else
+ 		.macro	get_saved_sp	/* Uniprocessor variation */
++#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
++		lui	k1, %highest(kernelsp)
++		daddiu	k1, %higher(kernelsp)
++		dsll	k1, k1, 16
++		daddiu	k1, %hi(kernelsp)
++		dsll	k1, k1, 16
++#else
+ 		lui	k1, %hi(kernelsp)
++#endif
+ 		LONG_L	k1, %lo(kernelsp)(k1)
+ 		.endm
+ 
+diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
+--- a/include/asm-mips/system.h
++++ b/include/asm-mips/system.h
+@@ -17,6 +17,7 @@
+ 
+ #include <asm/addrspace.h>
+ #include <asm/cpu-features.h>
++#include <asm/dsp.h>
+ #include <asm/ptrace.h>
+ #include <asm/war.h>
+ #include <asm/interrupt.h>
+@@ -70,7 +71,7 @@
+  * does not enforce ordering, since there is no data dependency between
+  * the read of "a" and the read of "b".  Therefore, on some CPUs, such
+  * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
+- * in cases like thiswhere there are no data dependencies.
++ * in cases like this where there are no data dependencies.
+  */
+ 
+ #define read_barrier_depends()	do { } while(0)
+@@ -154,15 +155,15 @@ extern asmlinkage void *resume(void *las
+ 
+ struct task_struct;
+ 
+-#define switch_to(prev,next,last) \
+-do { \
+-	(last) = resume(prev, next, next->thread_info); \
++#define switch_to(prev,next,last)					\
++do {									\
++	if (cpu_has_dsp)						\
++		__save_dsp(prev);					\
++	(last) = resume(prev, next, next->thread_info);			\
++	if (cpu_has_dsp)						\
++		__restore_dsp(current);					\
+ } while(0)
+ 
+-#define ROT_IN_PIECES							\
+-	"	.set	noreorder	\n"				\
+-	"	.set	reorder		\n"
+-
+ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
+ {
+ 	__u32 retval;
+@@ -171,14 +172,17 @@ static inline unsigned long __xchg_u32(v
+ 		unsigned long dummy;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%0, %3			# xchg_u32	\n"
++		"	.set	mips0					\n"
+ 		"	move	%2, %z4					\n"
++		"	.set	mips3					\n"
+ 		"	sc	%2, %1					\n"
+ 		"	beqzl	%2, 1b					\n"
+-		ROT_IN_PIECES
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
++		"	.set	mips0					\n"
+ 		: "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ 		: "R" (*m), "Jr" (val)
+ 		: "memory");
+@@ -186,13 +190,17 @@ static inline unsigned long __xchg_u32(v
+ 		unsigned long dummy;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	ll	%0, %3			# xchg_u32	\n"
++		"	.set	mips0					\n"
+ 		"	move	%2, %z4					\n"
++		"	.set	mips3					\n"
+ 		"	sc	%2, %1					\n"
+ 		"	beqz	%2, 1b					\n"
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
++		"	.set	mips0					\n"
+ 		: "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ 		: "R" (*m), "Jr" (val)
+ 		: "memory");
+@@ -217,14 +225,15 @@ static inline __u64 __xchg_u64(volatile 
+ 		unsigned long dummy;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%0, %3			# xchg_u64	\n"
+ 		"	move	%2, %z4					\n"
+ 		"	scd	%2, %1					\n"
+ 		"	beqzl	%2, 1b					\n"
+-		ROT_IN_PIECES
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
++		"	.set	mips0					\n"
+ 		: "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ 		: "R" (*m), "Jr" (val)
+ 		: "memory");
+@@ -232,6 +241,7 @@ static inline __u64 __xchg_u64(volatile 
+ 		unsigned long dummy;
+ 
+ 		__asm__ __volatile__(
++		"	.set	mips3					\n"
+ 		"1:	lld	%0, %3			# xchg_u64	\n"
+ 		"	move	%2, %z4					\n"
+ 		"	scd	%2, %1					\n"
+@@ -239,6 +249,7 @@ static inline __u64 __xchg_u64(volatile 
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
++		"	.set	mips0					\n"
+ 		: "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ 		: "R" (*m), "Jr" (val)
+ 		: "memory");
+@@ -286,34 +297,41 @@ static inline unsigned long __cmpxchg_u3
+ 
+ 	if (cpu_has_llsc && R10000_LLSC_WAR) {
+ 		__asm__ __volatile__(
++		"	.set	push					\n"
+ 		"	.set	noat					\n"
++		"	.set	mips3					\n"
+ 		"1:	ll	%0, %2			# __cmpxchg_u32	\n"
+ 		"	bne	%0, %z3, 2f				\n"
++		"	.set	mips0					\n"
+ 		"	move	$1, %z4					\n"
++		"	.set	mips3					\n"
+ 		"	sc	$1, %1					\n"
+ 		"	beqzl	$1, 1b					\n"
+-		ROT_IN_PIECES
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
+ 		"2:							\n"
+-		"	.set	at					\n"
++		"	.set	pop					\n"
+ 		: "=&r" (retval), "=m" (*m)
+ 		: "R" (*m), "Jr" (old), "Jr" (new)
+ 		: "memory");
+ 	} else if (cpu_has_llsc) {
+ 		__asm__ __volatile__(
++		"	.set	push					\n"
+ 		"	.set	noat					\n"
++		"	.set	mips3					\n"
+ 		"1:	ll	%0, %2			# __cmpxchg_u32	\n"
+ 		"	bne	%0, %z3, 2f				\n"
++		"	.set	mips0					\n"
+ 		"	move	$1, %z4					\n"
++		"	.set	mips3					\n"
+ 		"	sc	$1, %1					\n"
+ 		"	beqz	$1, 1b					\n"
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
+ 		"2:							\n"
+-		"	.set	at					\n"
++		"	.set	pop					\n"
+ 		: "=&r" (retval), "=m" (*m)
+ 		: "R" (*m), "Jr" (old), "Jr" (new)
+ 		: "memory");
+@@ -338,24 +356,27 @@ static inline unsigned long __cmpxchg_u6
+ 
+ 	if (cpu_has_llsc) {
+ 		__asm__ __volatile__(
++		"	.set	push					\n"
+ 		"	.set	noat					\n"
++		"	.set	mips3					\n"
+ 		"1:	lld	%0, %2			# __cmpxchg_u64	\n"
+ 		"	bne	%0, %z3, 2f				\n"
+ 		"	move	$1, %z4					\n"
+ 		"	scd	$1, %1					\n"
+ 		"	beqzl	$1, 1b					\n"
+-		ROT_IN_PIECES
+ #ifdef CONFIG_SMP
+ 		"	sync						\n"
+ #endif
+ 		"2:							\n"
+-		"	.set	at					\n"
++		"	.set	pop					\n"
+ 		: "=&r" (retval), "=m" (*m)
+ 		: "R" (*m), "Jr" (old), "Jr" (new)
+ 		: "memory");
+ 	} else if (cpu_has_llsc) {
+ 		__asm__ __volatile__(
++		"	.set	push					\n"
+ 		"	.set	noat					\n"
++		"	.set	mips3					\n"
+ 		"1:	lld	%0, %2			# __cmpxchg_u64	\n"
+ 		"	bne	%0, %z3, 2f				\n"
+ 		"	move	$1, %z4					\n"
+@@ -365,7 +386,7 @@ static inline unsigned long __cmpxchg_u6
+ 		"	sync						\n"
+ #endif
+ 		"2:							\n"
+-		"	.set	at					\n"
++		"	.set	pop					\n"
+ 		: "=&r" (retval), "=m" (*m)
+ 		: "R" (*m), "Jr" (old), "Jr" (new)
+ 		: "memory");
+@@ -406,18 +427,20 @@ static inline unsigned long __cmpxchg(vo
+ 
+ #define cmpxchg(ptr,old,new) ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
+ 
++extern void set_handler (unsigned long offset, void *addr, unsigned long len);
++extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len);
++extern void *set_vi_handler (int n, void *addr);
++extern void *set_vi_srs_handler (int n, void *addr, int regset);
+ extern void *set_except_vector(int n, void *addr);
+ extern void per_cpu_trap_init(void);
+ 
+-extern NORET_TYPE void __die(const char *, struct pt_regs *, const char *file,
+-	const char *func, unsigned long line);
+-extern void __die_if_kernel(const char *, struct pt_regs *, const char *file,
+-	const char *func, unsigned long line);
+-
+-#define die(msg, regs)							\
+-	__die(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
+-#define die_if_kernel(msg, regs)					\
+-	__die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
++extern NORET_TYPE void die(const char *, struct pt_regs *);
++
++static inline void die_if_kernel(const char *str, struct pt_regs *regs)
++{
++	if (unlikely(!user_mode(regs)))
++		die(str, regs);
++}
+ 
+ extern int stop_a_enabled;
+ 
+diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
+--- a/include/asm-mips/thread_info.h
++++ b/include/asm-mips/thread_info.h
+@@ -26,6 +26,7 @@ struct thread_info {
+ 	struct task_struct	*task;		/* main task structure */
+ 	struct exec_domain	*exec_domain;	/* execution domain */
+ 	unsigned long		flags;		/* low level flags */
++	unsigned long		tp_value;	/* thread pointer */
+ 	__u32			cpu;		/* current CPU */
+ 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
+ 
+@@ -114,6 +115,7 @@ register struct thread_info *__current_t
+ #define TIF_SIGPENDING		2	/* signal pending */
+ #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+ #define TIF_SYSCALL_AUDIT	4	/* syscall auditing active */
++#define TIF_SECCOMP		5	/* secure computing */
+ #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
+ #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+ #define TIF_MEMDIE		18
+@@ -124,13 +126,14 @@ register struct thread_info *__current_t
+ #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+ #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+ #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
++#define _TIF_SECCOMP		(1<<TIF_SECCOMP)
+ #define _TIF_USEDFPU		(1<<TIF_USEDFPU)
+ #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+ 
+-#define _TIF_WORK_MASK		0x0000ffef	/* work to do on
+-                                                   interrupt/exception return */
+-#define _TIF_ALLWORK_MASK	0x8000ffff	/* work to do on any return to
+-                                                   u-space */
++/* work to do on interrupt/exception return */
++#define _TIF_WORK_MASK		(0x0000ffef & ~_TIF_SECCOMP)
++/* work to do on any return to u-space */
++#define _TIF_ALLWORK_MASK	(0x8000ffff & ~_TIF_SECCOMP)
+ 
+ #endif /* __KERNEL__ */
+ 
+diff --git a/include/asm-mips/traps.h b/include/asm-mips/traps.h
+--- a/include/asm-mips/traps.h
++++ b/include/asm-mips/traps.h
+@@ -21,4 +21,7 @@
+ extern void (*board_be_init)(void);
+ extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
+ 
++extern void (*board_nmi_handler_setup)(void);
++extern void (*board_ejtag_handler_setup)(void);
++
+ #endif /* _ASM_TRAPS_H */
+diff --git a/include/asm-mips/tx4938/rbtx4938.h b/include/asm-mips/tx4938/rbtx4938.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/tx4938/rbtx4938.h
+@@ -0,0 +1,207 @@
++/*
++ * linux/include/asm-mips/tx4938/rbtx4938.h
++ * Definitions for TX4937/TX4938
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#ifndef __ASM_TX_BOARDS_RBTX4938_H
++#define __ASM_TX_BOARDS_RBTX4938_H
++
++#include <asm/addrspace.h>
++#include <asm/tx4938/tx4938.h>
++
++/* CS */
++#define RBTX4938_CE0	0x1c000000	/* 64M */
++#define RBTX4938_CE2	0x17f00000	/* 1M */
++
++/* Address map */
++#define RBTX4938_FPGA_REG_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00000000)
++#define RBTX4938_FPGA_REV_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00000002)
++#define RBTX4938_CONFIG1_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00000004)
++#define RBTX4938_CONFIG2_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00000006)
++#define RBTX4938_CONFIG3_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00000008)
++#define RBTX4938_LED_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00001000)
++#define RBTX4938_DIPSW_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00001002)
++#define RBTX4938_BDIPSW_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00001004)
++#define RBTX4938_IMASK_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00002000)
++#define RBTX4938_IMASK2_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00002002)
++#define RBTX4938_INTPOL_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00002004)
++#define RBTX4938_ISTAT_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00002006)
++#define RBTX4938_ISTAT2_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00002008)
++#define RBTX4938_IMSTAT_ADDR	(KSEG1 + RBTX4938_CE2 + 0x0000200a)
++#define RBTX4938_IMSTAT2_ADDR	(KSEG1 + RBTX4938_CE2 + 0x0000200c)
++#define RBTX4938_SOFTINT_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00003000)
++#define RBTX4938_PIOSEL_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00005000)
++#define RBTX4938_SPICS_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00005002)
++#define RBTX4938_SFPWR_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00005008)
++#define RBTX4938_SFVOL_ADDR	(KSEG1 + RBTX4938_CE2 + 0x0000500a)
++#define RBTX4938_SOFTRESET_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00007000)
++#define RBTX4938_SOFTRESETLOCK_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00007002)
++#define RBTX4938_PCIRESET_ADDR	(KSEG1 + RBTX4938_CE2 + 0x00007004)
++#define RBTX4938_ETHER_BASE	(KSEG1 + RBTX4938_CE2 + 0x00020000)
++
++/* Ethernet port address (Jumperless Mode (W12:Open)) */
++#define RBTX4938_ETHER_ADDR	(RBTX4938_ETHER_BASE + 0x280)
++
++/* bits for ISTAT/IMASK/IMSTAT */
++#define RBTX4938_INTB_PCID	0
++#define RBTX4938_INTB_PCIC	1
++#define RBTX4938_INTB_PCIB	2
++#define RBTX4938_INTB_PCIA	3
++#define RBTX4938_INTB_RTC	4
++#define RBTX4938_INTB_ATA	5
++#define RBTX4938_INTB_MODEM	6
++#define RBTX4938_INTB_SWINT	7
++#define RBTX4938_INTF_PCID	(1 << RBTX4938_INTB_PCID)
++#define RBTX4938_INTF_PCIC	(1 << RBTX4938_INTB_PCIC)
++#define RBTX4938_INTF_PCIB	(1 << RBTX4938_INTB_PCIB)
++#define RBTX4938_INTF_PCIA	(1 << RBTX4938_INTB_PCIA)
++#define RBTX4938_INTF_RTC	(1 << RBTX4938_INTB_RTC)
++#define RBTX4938_INTF_ATA	(1 << RBTX4938_INTB_ATA)
++#define RBTX4938_INTF_MODEM	(1 << RBTX4938_INTB_MODEM)
++#define RBTX4938_INTF_SWINT	(1 << RBTX4938_INTB_SWINT)
++
++#define rbtx4938_fpga_rev_ptr	\
++	((volatile unsigned char *)RBTX4938_FPGA_REV_ADDR)
++#define rbtx4938_led_ptr	\
++	((volatile unsigned char *)RBTX4938_LED_ADDR)
++#define rbtx4938_dipsw_ptr	\
++	((volatile unsigned char *)RBTX4938_DIPSW_ADDR)
++#define rbtx4938_bdipsw_ptr	\
++	((volatile unsigned char *)RBTX4938_BDIPSW_ADDR)
++#define rbtx4938_imask_ptr	\
++	((volatile unsigned char *)RBTX4938_IMASK_ADDR)
++#define rbtx4938_imask2_ptr	\
++	((volatile unsigned char *)RBTX4938_IMASK2_ADDR)
++#define rbtx4938_intpol_ptr	\
++	((volatile unsigned char *)RBTX4938_INTPOL_ADDR)
++#define rbtx4938_istat_ptr	\
++	((volatile unsigned char *)RBTX4938_ISTAT_ADDR)
++#define rbtx4938_istat2_ptr	\
++	((volatile unsigned char *)RBTX4938_ISTAT2_ADDR)
++#define rbtx4938_imstat_ptr	\
++	((volatile unsigned char *)RBTX4938_IMSTAT_ADDR)
++#define rbtx4938_imstat2_ptr	\
++	((volatile unsigned char *)RBTX4938_IMSTAT2_ADDR)
++#define rbtx4938_softint_ptr	\
++	((volatile unsigned char *)RBTX4938_SOFTINT_ADDR)
++#define rbtx4938_piosel_ptr	\
++	((volatile unsigned char *)RBTX4938_PIOSEL_ADDR)
++#define rbtx4938_spics_ptr	\
++	((volatile unsigned char *)RBTX4938_SPICS_ADDR)
++#define rbtx4938_sfpwr_ptr	\
++	((volatile unsigned char *)RBTX4938_SFPWR_ADDR)
++#define rbtx4938_sfvol_ptr	\
++	((volatile unsigned char *)RBTX4938_SFVOL_ADDR)
++#define rbtx4938_softreset_ptr	\
++	((volatile unsigned char *)RBTX4938_SOFTRESET_ADDR)
++#define rbtx4938_softresetlock_ptr	\
++	((volatile unsigned char *)RBTX4938_SOFTRESETLOCK_ADDR)
++#define rbtx4938_pcireset_ptr	\
++	((volatile unsigned char *)RBTX4938_PCIRESET_ADDR)
++
++/* SPI */
++#define RBTX4938_SEEPROM1_CHIPID	0
++#define RBTX4938_SEEPROM2_CHIPID	1
++#define RBTX4938_SEEPROM3_CHIPID	2
++#define RBTX4938_SRTC_CHIPID	3
++
++/*
++ * IRQ mappings
++ */
++
++#define RBTX4938_SOFT_INT0	0	/* not used */
++#define RBTX4938_SOFT_INT1	1	/* not used */
++#define RBTX4938_IRC_INT	2
++#define RBTX4938_TIMER_INT	7
++
++/* These are the virtual IRQ numbers, we divide all IRQ's into
++ * 'spaces', the 'space' determines where and how to enable/disable
++ * that particular IRQ on an RBTX4938 machine.  Add new 'spaces' as new
++ * IRQ hardware is supported.
++ */
++#define RBTX4938_NR_IRQ_LOCAL	8
++#define RBTX4938_NR_IRQ_IRC	32	/* On-Chip IRC */
++#define RBTX4938_NR_IRQ_IOC	8
++
++#define MI8259_IRQ_ISA_RAW_BEG   0	/* optional backplane i8259 */
++#define MI8259_IRQ_ISA_RAW_END  15
++#define TX4938_IRQ_CP0_RAW_BEG   0	/* tx4938 cpu built-in cp0 */
++#define TX4938_IRQ_CP0_RAW_END   7
++#define TX4938_IRQ_PIC_RAW_BEG   0	/* tx4938 cpu build-in pic */
++#define TX4938_IRQ_PIC_RAW_END  31
++
++#define MI8259_IRQ_ISA_BEG                          MI8259_IRQ_ISA_RAW_BEG	/*  0 */
++#define MI8259_IRQ_ISA_END                          MI8259_IRQ_ISA_RAW_END	/* 15 */
++
++#define TX4938_IRQ_CP0_BEG  ((MI8259_IRQ_ISA_END+1)+TX4938_IRQ_CP0_RAW_BEG)	/* 16 */
++#define TX4938_IRQ_CP0_END  ((MI8259_IRQ_ISA_END+1)+TX4938_IRQ_CP0_RAW_END)	/* 23 */
++
++#define TX4938_IRQ_PIC_BEG  ((TX4938_IRQ_CP0_END+1)+TX4938_IRQ_PIC_RAW_BEG)	/* 24 */
++#define TX4938_IRQ_PIC_END  ((TX4938_IRQ_CP0_END+1)+TX4938_IRQ_PIC_RAW_END)	/* 55 */
++#define TX4938_IRQ_NEST_EXT_ON_PIC  (TX4938_IRQ_PIC_BEG+2)
++#define TX4938_IRQ_NEST_PIC_ON_CP0  (TX4938_IRQ_CP0_BEG+2)
++#define TX4938_IRQ_USER0            (TX4938_IRQ_CP0_BEG+0)
++#define TX4938_IRQ_USER1            (TX4938_IRQ_CP0_BEG+1)
++#define TX4938_IRQ_CPU_TIMER        (TX4938_IRQ_CP0_BEG+7)
++
++#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG   0
++#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_END   7
++
++#define TOSHIBA_RBTX4938_IRQ_IOC_BEG  ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG) /* 56 */
++#define TOSHIBA_RBTX4938_IRQ_IOC_END  ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_END) /* 63 */
++#define RBTX4938_IRQ_LOCAL	TX4938_IRQ_CP0_BEG
++#define RBTX4938_IRQ_IRC	(RBTX4938_IRQ_LOCAL + RBTX4938_NR_IRQ_LOCAL)
++#define RBTX4938_IRQ_IOC	(RBTX4938_IRQ_IRC + RBTX4938_NR_IRQ_IRC)
++#define RBTX4938_IRQ_END	(RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC)
++
++#define RBTX4938_IRQ_LOCAL_SOFT0	(RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT0)
++#define RBTX4938_IRQ_LOCAL_SOFT1	(RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT1)
++#define RBTX4938_IRQ_LOCAL_IRC	(RBTX4938_IRQ_LOCAL + RBTX4938_IRC_INT)
++#define RBTX4938_IRQ_LOCAL_TIMER	(RBTX4938_IRQ_LOCAL + RBTX4938_TIMER_INT)
++#define RBTX4938_IRQ_IRC_ECCERR	(RBTX4938_IRQ_IRC + TX4938_IR_ECCERR)
++#define RBTX4938_IRQ_IRC_WTOERR	(RBTX4938_IRQ_IRC + TX4938_IR_WTOERR)
++#define RBTX4938_IRQ_IRC_INT(n)	(RBTX4938_IRQ_IRC + TX4938_IR_INT(n))
++#define RBTX4938_IRQ_IRC_SIO(n)	(RBTX4938_IRQ_IRC + TX4938_IR_SIO(n))
++#define RBTX4938_IRQ_IRC_DMA(ch,n)	(RBTX4938_IRQ_IRC + TX4938_IR_DMA(ch,n))
++#define RBTX4938_IRQ_IRC_PIO	(RBTX4938_IRQ_IRC + TX4938_IR_PIO)
++#define RBTX4938_IRQ_IRC_PDMAC	(RBTX4938_IRQ_IRC + TX4938_IR_PDMAC)
++#define RBTX4938_IRQ_IRC_PCIC	(RBTX4938_IRQ_IRC + TX4938_IR_PCIC)
++#define RBTX4938_IRQ_IRC_TMR(n)	(RBTX4938_IRQ_IRC + TX4938_IR_TMR(n))
++#define RBTX4938_IRQ_IRC_NDFMC	(RBTX4938_IRQ_IRC + TX4938_IR_NDFMC)
++#define RBTX4938_IRQ_IRC_PCIERR	(RBTX4938_IRQ_IRC + TX4938_IR_PCIERR)
++#define RBTX4938_IRQ_IRC_PCIPME	(RBTX4938_IRQ_IRC + TX4938_IR_PCIPME)
++#define RBTX4938_IRQ_IRC_ACLC	(RBTX4938_IRQ_IRC + TX4938_IR_ACLC)
++#define RBTX4938_IRQ_IRC_ACLCPME	(RBTX4938_IRQ_IRC + TX4938_IR_ACLCPME)
++#define RBTX4938_IRQ_IRC_PCIC1	(RBTX4938_IRQ_IRC + TX4938_IR_PCIC1)
++#define RBTX4938_IRQ_IRC_SPI	(RBTX4938_IRQ_IRC + TX4938_IR_SPI)
++#define RBTX4938_IRQ_IOC_PCID	(RBTX4938_IRQ_IOC + RBTX4938_INTB_PCID)
++#define RBTX4938_IRQ_IOC_PCIC	(RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIC)
++#define RBTX4938_IRQ_IOC_PCIB	(RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIB)
++#define RBTX4938_IRQ_IOC_PCIA	(RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIA)
++#define RBTX4938_IRQ_IOC_RTC	(RBTX4938_IRQ_IOC + RBTX4938_INTB_RTC)
++#define RBTX4938_IRQ_IOC_ATA	(RBTX4938_IRQ_IOC + RBTX4938_INTB_ATA)
++#define RBTX4938_IRQ_IOC_MODEM	(RBTX4938_IRQ_IOC + RBTX4938_INTB_MODEM)
++#define RBTX4938_IRQ_IOC_SWINT	(RBTX4938_IRQ_IOC + RBTX4938_INTB_SWINT)
++
++
++/* IOC (PCI, etc) */
++#define RBTX4938_IRQ_IOCINT	(TX4938_IRQ_NEST_EXT_ON_PIC)
++/* Onboard 10M Ether */
++#define RBTX4938_IRQ_ETHER	(TX4938_IRQ_NEST_EXT_ON_PIC + 1)
++
++#define RBTX4938_RTL_8019_BASE (RBTX4938_ETHER_ADDR - mips_io_port_base)
++#define RBTX4938_RTL_8019_IRQ  (RBTX4938_IRQ_ETHER)
++
++/* IRCR : Int. Control */
++#define TX4938_IRCR_LOW  0x00000000
++#define TX4938_IRCR_HIGH 0x00000001
++#define TX4938_IRCR_DOWN 0x00000002
++#define TX4938_IRCR_UP   0x00000003
++
++#endif /* __ASM_TX_BOARDS_RBTX4938_H */
+diff --git a/include/asm-mips/tx4938/spi.h b/include/asm-mips/tx4938/spi.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/tx4938/spi.h
+@@ -0,0 +1,74 @@
++/*
++ * linux/include/asm-mips/tx4938/spi.h
++ * Definitions for TX4937/TX4938 SPI
++ *
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#ifndef __ASM_TX_BOARDS_TX4938_SPI_H
++#define __ASM_TX_BOARDS_TX4938_SPI_H
++
++/* SPI */
++struct spi_dev_desc {
++	unsigned int baud;
++	unsigned short tcss, tcsh, tcsr; /* CS setup/hold/recovery time */
++	unsigned int byteorder:1;	/* 0:LSB-First, 1:MSB-First */
++	unsigned int polarity:1;	/* 0:High-Active */
++	unsigned int phase:1;		/* 0:Sample-Then-Shift */
++};
++
++extern void txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)) __init;
++extern void txx9_spi_irqinit(int irc_irq) __init;
++extern int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
++		       unsigned char **inbufs, unsigned int *incounts,
++		       unsigned char **outbufs, unsigned int *outcounts,
++		       int cansleep);
++extern int spi_eeprom_write_enable(int chipid, int enable);
++extern int spi_eeprom_read_status(int chipid);
++extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
++extern int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len);
++extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) __init;
++
++#define TXX9_IMCLK     (txx9_gbus_clock / 2)
++
++/*
++* SPI
++*/
++
++/* SPMCR : SPI Master Control */
++#define TXx9_SPMCR_OPMODE	0xc0
++#define TXx9_SPMCR_CONFIG	0x40
++#define TXx9_SPMCR_ACTIVE	0x80
++#define TXx9_SPMCR_SPSTP	0x02
++#define TXx9_SPMCR_BCLR	0x01
++
++/* SPCR0 : SPI Status */
++#define TXx9_SPCR0_TXIFL_MASK	0xc000
++#define TXx9_SPCR0_RXIFL_MASK	0x3000
++#define TXx9_SPCR0_SIDIE	0x0800
++#define TXx9_SPCR0_SOEIE	0x0400
++#define TXx9_SPCR0_RBSIE	0x0200
++#define TXx9_SPCR0_TBSIE	0x0100
++#define TXx9_SPCR0_IFSPSE	0x0010
++#define TXx9_SPCR0_SBOS	0x0004
++#define TXx9_SPCR0_SPHA	0x0002
++#define TXx9_SPCR0_SPOL	0x0001
++
++/* SPSR : SPI Status */
++#define TXx9_SPSR_TBSI	0x8000
++#define TXx9_SPSR_RBSI	0x4000
++#define TXx9_SPSR_TBS_MASK	0x3800
++#define TXx9_SPSR_RBS_MASK	0x0700
++#define TXx9_SPSR_SPOE	0x0080
++#define TXx9_SPSR_IFSD	0x0008
++#define TXx9_SPSR_SIDLE	0x0004
++#define TXx9_SPSR_STRDY	0x0002
++#define TXx9_SPSR_SRRDY	0x0001
++
++#endif /* __ASM_TX_BOARDS_TX4938_SPI_H */
+diff --git a/include/asm-mips/tx4938/tx4938.h b/include/asm-mips/tx4938/tx4938.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/tx4938/tx4938.h
+@@ -0,0 +1,706 @@
++/*
++ * linux/include/asm-mips/tx4938/tx4938.h
++ * Definitions for TX4937/TX4938
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++#ifndef __ASM_TX_BOARDS_TX4938_H
++#define __ASM_TX_BOARDS_TX4938_H
++
++#include <asm/tx4938/tx4938_mips.h>
++
++#define tx4938_read_nfmc(addr) (*(volatile unsigned int *)(addr))
++#define tx4938_write_nfmc(b,addr) (*(volatile unsigned int *)(addr)) = (b)
++
++#define TX4938_NR_IRQ_LOCAL     TX4938_IRQ_PIC_BEG
++
++#define TX4938_IRQ_IRC_PCIC     (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIC)
++#define TX4938_IRQ_IRC_PCIERR   (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIERR)
++
++#define TX4938_PCIIO_0 0x10000000
++#define TX4938_PCIIO_1 0x01010000
++#define TX4938_PCIMEM_0 0x08000000
++#define TX4938_PCIMEM_1 0x11000000
++
++#define TX4938_PCIIO_SIZE_0 0x01000000
++#define TX4938_PCIIO_SIZE_1 0x00010000
++#define TX4938_PCIMEM_SIZE_0 0x08000000
++#define TX4938_PCIMEM_SIZE_1 0x00010000
++
++#define TX4938_REG_BASE	0xff1f0000 /* == TX4937_REG_BASE */
++#define TX4938_REG_SIZE	0x00010000 /* == TX4937_REG_SIZE */
++
++/* NDFMC, SRAMC, PCIC1, SPIC: TX4938 only */
++#define TX4938_NDFMC_REG	(TX4938_REG_BASE + 0x5000)
++#define TX4938_SRAMC_REG	(TX4938_REG_BASE + 0x6000)
++#define TX4938_PCIC1_REG	(TX4938_REG_BASE + 0x7000)
++#define TX4938_SDRAMC_REG	(TX4938_REG_BASE + 0x8000)
++#define TX4938_EBUSC_REG	(TX4938_REG_BASE + 0x9000)
++#define TX4938_DMA_REG(ch)	(TX4938_REG_BASE + 0xb000 + (ch) * 0x800)
++#define TX4938_PCIC_REG		(TX4938_REG_BASE + 0xd000)
++#define TX4938_CCFG_REG		(TX4938_REG_BASE + 0xe000)
++#define TX4938_NR_TMR	3
++#define TX4938_TMR_REG(ch)	((TX4938_REG_BASE + 0xf000) + (ch) * 0x100)
++#define TX4938_NR_SIO	2
++#define TX4938_SIO_REG(ch)	((TX4938_REG_BASE + 0xf300) + (ch) * 0x100)
++#define TX4938_PIO_REG		(TX4938_REG_BASE + 0xf500)
++#define TX4938_IRC_REG		(TX4938_REG_BASE + 0xf600)
++#define TX4938_ACLC_REG		(TX4938_REG_BASE + 0xf700)
++#define TX4938_SPI_REG		(TX4938_REG_BASE + 0xf800)
++
++#ifndef _LANGUAGE_ASSEMBLY
++#include <asm/byteorder.h>
++
++#define TX4938_MKA(x) ((u32)( ((u32)(TX4938_REG_BASE)) | ((u32)(x)) ))
++
++#define TX4938_RD08( reg      )   (*(vu08*)(reg))
++#define TX4938_WR08( reg, val )  ((*(vu08*)(reg))=(val))
++
++#define TX4938_RD16( reg      )   (*(vu16*)(reg))
++#define TX4938_WR16( reg, val )  ((*(vu16*)(reg))=(val))
++
++#define TX4938_RD32( reg      )   (*(vu32*)(reg))
++#define TX4938_WR32( reg, val )  ((*(vu32*)(reg))=(val))
++
++#define TX4938_RD64( reg      )   (*(vu64*)(reg))
++#define TX4938_WR64( reg, val )  ((*(vu64*)(reg))=(val))
++
++#define TX4938_RD( reg      ) TX4938_RD32( reg )
++#define TX4938_WR( reg, val ) TX4938_WR32( reg, val )
++
++#endif /* !__ASSEMBLY__ */
++
++#ifdef __ASSEMBLY__
++#define _CONST64(c)	c
++#else
++#define _CONST64(c)	c##ull
++
++#include <asm/byteorder.h>
++
++#ifdef __BIG_ENDIAN
++#define endian_def_l2(e1,e2)	\
++	volatile unsigned long e1,e2
++#define endian_def_s2(e1,e2)	\
++	volatile unsigned short e1,e2
++#define endian_def_sb2(e1,e2,e3)	\
++	volatile unsigned short e1;volatile unsigned char e2,e3
++#define endian_def_b2s(e1,e2,e3)	\
++	volatile unsigned char e1,e2;volatile unsigned short e3
++#define endian_def_b4(e1,e2,e3,e4)	\
++	volatile unsigned char e1,e2,e3,e4
++#else
++#define endian_def_l2(e1,e2)	\
++	volatile unsigned long e2,e1
++#define endian_def_s2(e1,e2)	\
++	volatile unsigned short e2,e1
++#define endian_def_sb2(e1,e2,e3)	\
++	volatile unsigned char e3,e2;volatile unsigned short e1
++#define endian_def_b2s(e1,e2,e3)	\
++	volatile unsigned short e3;volatile unsigned char e2,e1
++#define endian_def_b4(e1,e2,e3,e4)	\
++	volatile unsigned char e4,e3,e2,e1
++#endif
++
++
++struct tx4938_sdramc_reg {
++	volatile unsigned long long cr[4];
++	volatile unsigned long long unused0[4];
++	volatile unsigned long long tr;
++	volatile unsigned long long unused1[2];
++	volatile unsigned long long cmd;
++	volatile unsigned long long sfcmd;
++};
++
++struct tx4938_ebusc_reg {
++	volatile unsigned long long cr[8];
++};
++
++struct tx4938_dma_reg {
++	struct tx4938_dma_ch_reg {
++		volatile unsigned long long cha;
++		volatile unsigned long long sar;
++		volatile unsigned long long dar;
++		endian_def_l2(unused0, cntr);
++		endian_def_l2(unused1, sair);
++		endian_def_l2(unused2, dair);
++		endian_def_l2(unused3, ccr);
++		endian_def_l2(unused4, csr);
++	} ch[4];
++	volatile unsigned long long dbr[8];
++	volatile unsigned long long tdhr;
++	volatile unsigned long long midr;
++	endian_def_l2(unused0, mcr);
++};
++
++struct tx4938_pcic_reg {
++	volatile unsigned long pciid;
++	volatile unsigned long pcistatus;
++	volatile unsigned long pciccrev;
++	volatile unsigned long pcicfg1;
++	volatile unsigned long p2gm0plbase;		/* +10 */
++	volatile unsigned long p2gm0pubase;
++	volatile unsigned long p2gm1plbase;
++	volatile unsigned long p2gm1pubase;
++	volatile unsigned long p2gm2pbase;		/* +20 */
++	volatile unsigned long p2giopbase;
++	volatile unsigned long unused0;
++	volatile unsigned long pcisid;
++	volatile unsigned long unused1;		/* +30 */
++	volatile unsigned long pcicapptr;
++	volatile unsigned long unused2;
++	volatile unsigned long pcicfg2;
++	volatile unsigned long g2ptocnt;		/* +40 */
++	volatile unsigned long unused3[15];
++	volatile unsigned long g2pstatus;		/* +80 */
++	volatile unsigned long g2pmask;
++	volatile unsigned long pcisstatus;
++	volatile unsigned long pcimask;
++	volatile unsigned long p2gcfg;		/* +90 */
++	volatile unsigned long p2gstatus;
++	volatile unsigned long p2gmask;
++	volatile unsigned long p2gccmd;
++	volatile unsigned long unused4[24];		/* +a0 */
++	volatile unsigned long pbareqport;		/* +100 */
++	volatile unsigned long pbacfg;
++	volatile unsigned long pbastatus;
++	volatile unsigned long pbamask;
++	volatile unsigned long pbabm;		/* +110 */
++	volatile unsigned long pbacreq;
++	volatile unsigned long pbacgnt;
++	volatile unsigned long pbacstate;
++	volatile unsigned long long g2pmgbase[3];		/* +120 */
++	volatile unsigned long long g2piogbase;
++	volatile unsigned long g2pmmask[3];		/* +140 */
++	volatile unsigned long g2piomask;
++	volatile unsigned long long g2pmpbase[3];		/* +150 */
++	volatile unsigned long long g2piopbase;
++	volatile unsigned long pciccfg;		/* +170 */
++	volatile unsigned long pcicstatus;
++	volatile unsigned long pcicmask;
++	volatile unsigned long unused5;
++	volatile unsigned long long p2gmgbase[3];		/* +180 */
++	volatile unsigned long long p2giogbase;
++	volatile unsigned long g2pcfgadrs;		/* +1a0 */
++	volatile unsigned long g2pcfgdata;
++	volatile unsigned long unused6[8];
++	volatile unsigned long g2pintack;
++	volatile unsigned long g2pspc;
++	volatile unsigned long unused7[12];		/* +1d0 */
++	volatile unsigned long long pdmca;		/* +200 */
++	volatile unsigned long long pdmga;
++	volatile unsigned long long pdmpa;
++	volatile unsigned long long pdmctr;
++	volatile unsigned long long pdmcfg;		/* +220 */
++	volatile unsigned long long pdmsts;
++};
++
++struct tx4938_aclc_reg {
++	volatile unsigned long acctlen;
++	volatile unsigned long acctldis;
++	volatile unsigned long acregacc;
++	volatile unsigned long unused0;
++	volatile unsigned long acintsts;
++	volatile unsigned long acintmsts;
++	volatile unsigned long acinten;
++	volatile unsigned long acintdis;
++	volatile unsigned long acsemaph;
++	volatile unsigned long unused1[7];
++	volatile unsigned long acgpidat;
++	volatile unsigned long acgpodat;
++	volatile unsigned long acslten;
++	volatile unsigned long acsltdis;
++	volatile unsigned long acfifosts;
++	volatile unsigned long unused2[11];
++	volatile unsigned long acdmasts;
++	volatile unsigned long acdmasel;
++	volatile unsigned long unused3[6];
++	volatile unsigned long acaudodat;
++	volatile unsigned long acsurrdat;
++	volatile unsigned long accentdat;
++	volatile unsigned long aclfedat;
++	volatile unsigned long acaudiat;
++	volatile unsigned long unused4;
++	volatile unsigned long acmodoat;
++	volatile unsigned long acmodidat;
++	volatile unsigned long unused5[15];
++	volatile unsigned long acrevid;
++};
++
++
++struct tx4938_tmr_reg {
++	volatile unsigned long tcr;
++	volatile unsigned long tisr;
++	volatile unsigned long cpra;
++	volatile unsigned long cprb;
++	volatile unsigned long itmr;
++	volatile unsigned long unused0[3];
++	volatile unsigned long ccdr;
++	volatile unsigned long unused1[3];
++	volatile unsigned long pgmr;
++	volatile unsigned long unused2[3];
++	volatile unsigned long wtmr;
++	volatile unsigned long unused3[43];
++	volatile unsigned long trr;
++};
++
++struct tx4938_sio_reg {
++	volatile unsigned long lcr;
++	volatile unsigned long dicr;
++	volatile unsigned long disr;
++	volatile unsigned long cisr;
++	volatile unsigned long fcr;
++	volatile unsigned long flcr;
++	volatile unsigned long bgr;
++	volatile unsigned long tfifo;
++	volatile unsigned long rfifo;
++};
++
++struct tx4938_pio_reg {
++	volatile unsigned long dout;
++	volatile unsigned long din;
++	volatile unsigned long dir;
++	volatile unsigned long od;
++	volatile unsigned long flag[2];
++	volatile unsigned long pol;
++	volatile unsigned long intc;
++	volatile unsigned long maskcpu;
++	volatile unsigned long maskext;
++};
++struct tx4938_irc_reg {
++	volatile unsigned long cer;
++	volatile unsigned long cr[2];
++	volatile unsigned long unused0;
++	volatile unsigned long ilr[8];
++	volatile unsigned long unused1[4];
++	volatile unsigned long imr;
++	volatile unsigned long unused2[7];
++	volatile unsigned long scr;
++	volatile unsigned long unused3[7];
++	volatile unsigned long ssr;
++	volatile unsigned long unused4[7];
++	volatile unsigned long csr;
++};
++
++struct tx4938_ndfmc_reg {
++	endian_def_l2(unused0, dtr);
++	endian_def_l2(unused1, mcr);
++	endian_def_l2(unused2, sr);
++	endian_def_l2(unused3, isr);
++	endian_def_l2(unused4, imr);
++	endian_def_l2(unused5, spr);
++	endian_def_l2(unused6, rstr);
++};
++
++struct tx4938_spi_reg {
++	volatile unsigned long mcr;
++	volatile unsigned long cr0;
++	volatile unsigned long cr1;
++	volatile unsigned long fs;
++	volatile unsigned long unused1;
++	volatile unsigned long sr;
++	volatile unsigned long dr;
++	volatile unsigned long unused2;
++};
++
++struct tx4938_sramc_reg {
++	volatile unsigned long long cr;
++};
++
++struct tx4938_ccfg_reg {
++	volatile unsigned long long ccfg;
++	volatile unsigned long long crir;
++	volatile unsigned long long pcfg;
++	volatile unsigned long long tear;
++	volatile unsigned long long clkctr;
++	volatile unsigned long long unused0;
++	volatile unsigned long long garbc;
++	volatile unsigned long long unused1;
++	volatile unsigned long long unused2;
++	volatile unsigned long long ramp;
++	volatile unsigned long long unused3;
++	volatile unsigned long long jmpadr;
++};
++
++#undef endian_def_l2
++#undef endian_def_s2
++#undef endian_def_sb2
++#undef endian_def_b2s
++#undef endian_def_b4
++
++#endif /* __ASSEMBLY__ */
++
++/*
++ * NDFMC
++ */
++
++/* NDFMCR : NDFMC Mode Control */
++#define TX4938_NDFMCR_WE	0x80
++#define TX4938_NDFMCR_ECC_ALL	0x60
++#define TX4938_NDFMCR_ECC_RESET	0x60
++#define TX4938_NDFMCR_ECC_READ	0x40
++#define TX4938_NDFMCR_ECC_ON	0x20
++#define TX4938_NDFMCR_ECC_OFF	0x00
++#define TX4938_NDFMCR_CE	0x10
++#define TX4938_NDFMCR_BSPRT	0x04
++#define TX4938_NDFMCR_ALE	0x02
++#define TX4938_NDFMCR_CLE	0x01
++
++/* NDFMCR : NDFMC Status */
++#define TX4938_NDFSR_BUSY	0x80
++
++/* NDFMCR : NDFMC Reset */
++#define TX4938_NDFRSTR_RST	0x01
++
++/*
++ * IRC
++ */
++
++#define TX4938_IR_ECCERR	0
++#define TX4938_IR_WTOERR	1
++#define TX4938_NUM_IR_INT	6
++#define TX4938_IR_INT(n)	(2 + (n))
++#define TX4938_NUM_IR_SIO	2
++#define TX4938_IR_SIO(n)	(8 + (n))
++#define TX4938_NUM_IR_DMA	4
++#define TX4938_IR_DMA(ch,n)	((ch ? 27 : 10) + (n)) /* 10-13,27-30 */
++#define TX4938_IR_PIO	14
++#define TX4938_IR_PDMAC	15
++#define TX4938_IR_PCIC	16
++#define TX4938_NUM_IR_TMR	3
++#define TX4938_IR_TMR(n)	(17 + (n))
++#define TX4938_IR_NDFMC	21
++#define TX4938_IR_PCIERR	22
++#define TX4938_IR_PCIPME	23
++#define TX4938_IR_ACLC	24
++#define TX4938_IR_ACLCPME	25
++#define TX4938_IR_PCIC1	26
++#define TX4938_IR_SPI	31
++#define TX4938_NUM_IR	32
++/* multiplex */
++#define TX4938_IR_ETH0	TX4938_IR_INT(4)
++#define TX4938_IR_ETH1	TX4938_IR_INT(3)
++
++/*
++ * CCFG
++ */
++/* CCFG : Chip Configuration */
++#define TX4938_CCFG_WDRST	_CONST64(0x0000020000000000)
++#define TX4938_CCFG_WDREXEN	_CONST64(0x0000010000000000)
++#define TX4938_CCFG_BCFG_MASK	_CONST64(0x000000ff00000000)
++#define TX4938_CCFG_TINTDIS	0x01000000
++#define TX4938_CCFG_PCI66	0x00800000
++#define TX4938_CCFG_PCIMODE	0x00400000
++#define TX4938_CCFG_PCI1_66	0x00200000
++#define TX4938_CCFG_DIVMODE_MASK	0x001e0000
++#define TX4938_CCFG_DIVMODE_2	(0x4 << 17)
++#define TX4938_CCFG_DIVMODE_2_5	(0xf << 17)
++#define TX4938_CCFG_DIVMODE_3	(0x5 << 17)
++#define TX4938_CCFG_DIVMODE_4	(0x6 << 17)
++#define TX4938_CCFG_DIVMODE_4_5	(0xd << 17)
++#define TX4938_CCFG_DIVMODE_8	(0x0 << 17)
++#define TX4938_CCFG_DIVMODE_10	(0xb << 17)
++#define TX4938_CCFG_DIVMODE_12	(0x1 << 17)
++#define TX4938_CCFG_DIVMODE_16	(0x2 << 17)
++#define TX4938_CCFG_DIVMODE_18	(0x9 << 17)
++#define TX4938_CCFG_BEOW	0x00010000
++#define TX4938_CCFG_WR	0x00008000
++#define TX4938_CCFG_TOE	0x00004000
++#define TX4938_CCFG_PCIXARB	0x00002000
++#define TX4938_CCFG_PCIDIVMODE_MASK	0x00001c00
++#define TX4938_CCFG_PCIDIVMODE_4	(0x1 << 10)
++#define TX4938_CCFG_PCIDIVMODE_4_5	(0x3 << 10)
++#define TX4938_CCFG_PCIDIVMODE_5	(0x5 << 10)
++#define TX4938_CCFG_PCIDIVMODE_5_5	(0x7 << 10)
++#define TX4938_CCFG_PCIDIVMODE_8	(0x0 << 10)
++#define TX4938_CCFG_PCIDIVMODE_9	(0x2 << 10)
++#define TX4938_CCFG_PCIDIVMODE_10	(0x4 << 10)
++#define TX4938_CCFG_PCIDIVMODE_11	(0x6 << 10)
++#define TX4938_CCFG_PCI1DMD	0x00000100
++#define TX4938_CCFG_SYSSP_MASK	0x000000c0
++#define TX4938_CCFG_ENDIAN	0x00000004
++#define TX4938_CCFG_HALT	0x00000002
++#define TX4938_CCFG_ACEHOLD	0x00000001
++
++/* PCFG : Pin Configuration */
++#define TX4938_PCFG_ETH0_SEL	_CONST64(0x8000000000000000)
++#define TX4938_PCFG_ETH1_SEL	_CONST64(0x4000000000000000)
++#define TX4938_PCFG_ATA_SEL	_CONST64(0x2000000000000000)
++#define TX4938_PCFG_ISA_SEL	_CONST64(0x1000000000000000)
++#define TX4938_PCFG_SPI_SEL	_CONST64(0x0800000000000000)
++#define TX4938_PCFG_NDF_SEL	_CONST64(0x0400000000000000)
++#define TX4938_PCFG_SDCLKDLY_MASK	0x30000000
++#define TX4938_PCFG_SDCLKDLY(d)	((d)<<28)
++#define TX4938_PCFG_SYSCLKEN	0x08000000
++#define TX4938_PCFG_SDCLKEN_ALL	0x07800000
++#define TX4938_PCFG_SDCLKEN(ch)	(0x00800000<<(ch))
++#define TX4938_PCFG_PCICLKEN_ALL	0x003f0000
++#define TX4938_PCFG_PCICLKEN(ch)	(0x00010000<<(ch))
++#define TX4938_PCFG_SEL2	0x00000200
++#define TX4938_PCFG_SEL1	0x00000100
++#define TX4938_PCFG_DMASEL_ALL	0x0000000f
++#define TX4938_PCFG_DMASEL0_DRQ0	0x00000000
++#define TX4938_PCFG_DMASEL0_SIO1	0x00000001
++#define TX4938_PCFG_DMASEL1_DRQ1	0x00000000
++#define TX4938_PCFG_DMASEL1_SIO1	0x00000002
++#define TX4938_PCFG_DMASEL2_DRQ2	0x00000000
++#define TX4938_PCFG_DMASEL2_SIO0	0x00000004
++#define TX4938_PCFG_DMASEL3_DRQ3	0x00000000
++#define TX4938_PCFG_DMASEL3_SIO0	0x00000008
++
++/* CLKCTR : Clock Control */
++#define TX4938_CLKCTR_NDFCKD	_CONST64(0x0001000000000000)
++#define TX4938_CLKCTR_NDFRST	_CONST64(0x0000000100000000)
++#define TX4938_CLKCTR_ETH1CKD	0x80000000
++#define TX4938_CLKCTR_ETH0CKD	0x40000000
++#define TX4938_CLKCTR_SPICKD	0x20000000
++#define TX4938_CLKCTR_SRAMCKD	0x10000000
++#define TX4938_CLKCTR_PCIC1CKD	0x08000000
++#define TX4938_CLKCTR_DMA1CKD	0x04000000
++#define TX4938_CLKCTR_ACLCKD	0x02000000
++#define TX4938_CLKCTR_PIOCKD	0x01000000
++#define TX4938_CLKCTR_DMACKD	0x00800000
++#define TX4938_CLKCTR_PCICKD	0x00400000
++#define TX4938_CLKCTR_TM0CKD	0x00100000
++#define TX4938_CLKCTR_TM1CKD	0x00080000
++#define TX4938_CLKCTR_TM2CKD	0x00040000
++#define TX4938_CLKCTR_SIO0CKD	0x00020000
++#define TX4938_CLKCTR_SIO1CKD	0x00010000
++#define TX4938_CLKCTR_ETH1RST	0x00008000
++#define TX4938_CLKCTR_ETH0RST	0x00004000
++#define TX4938_CLKCTR_SPIRST	0x00002000
++#define TX4938_CLKCTR_SRAMRST	0x00001000
++#define TX4938_CLKCTR_PCIC1RST	0x00000800
++#define TX4938_CLKCTR_DMA1RST	0x00000400
++#define TX4938_CLKCTR_ACLRST	0x00000200
++#define TX4938_CLKCTR_PIORST	0x00000100
++#define TX4938_CLKCTR_DMARST	0x00000080
++#define TX4938_CLKCTR_PCIRST	0x00000040
++#define TX4938_CLKCTR_TM0RST	0x00000010
++#define TX4938_CLKCTR_TM1RST	0x00000008
++#define TX4938_CLKCTR_TM2RST	0x00000004
++#define TX4938_CLKCTR_SIO0RST	0x00000002
++#define TX4938_CLKCTR_SIO1RST	0x00000001
++
++/* bits for G2PSTATUS/G2PMASK */
++#define TX4938_PCIC_G2PSTATUS_ALL	0x00000003
++#define TX4938_PCIC_G2PSTATUS_TTOE	0x00000002
++#define TX4938_PCIC_G2PSTATUS_RTOE	0x00000001
++
++/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */
++#define TX4938_PCIC_PCISTATUS_ALL	0x0000f900
++
++/* bits for PBACFG */
++#define TX4938_PCIC_PBACFG_FIXPA	0x00000008
++#define TX4938_PCIC_PBACFG_RPBA	0x00000004
++#define TX4938_PCIC_PBACFG_PBAEN	0x00000002
++#define TX4938_PCIC_PBACFG_BMCEN	0x00000001
++
++/* bits for G2PMnGBASE */
++#define TX4938_PCIC_G2PMnGBASE_BSDIS	_CONST64(0x0000002000000000)
++#define TX4938_PCIC_G2PMnGBASE_ECHG	_CONST64(0x0000001000000000)
++
++/* bits for G2PIOGBASE */
++#define TX4938_PCIC_G2PIOGBASE_BSDIS	_CONST64(0x0000002000000000)
++#define TX4938_PCIC_G2PIOGBASE_ECHG	_CONST64(0x0000001000000000)
++
++/* bits for PCICSTATUS/PCICMASK */
++#define TX4938_PCIC_PCICSTATUS_ALL	0x000007b8
++#define TX4938_PCIC_PCICSTATUS_PME	0x00000400
++#define TX4938_PCIC_PCICSTATUS_TLB	0x00000200
++#define TX4938_PCIC_PCICSTATUS_NIB	0x00000100
++#define TX4938_PCIC_PCICSTATUS_ZIB	0x00000080
++#define TX4938_PCIC_PCICSTATUS_PERR	0x00000020
++#define TX4938_PCIC_PCICSTATUS_SERR	0x00000010
++#define TX4938_PCIC_PCICSTATUS_GBE	0x00000008
++#define TX4938_PCIC_PCICSTATUS_IWB	0x00000002
++#define TX4938_PCIC_PCICSTATUS_E2PDONE	0x00000001
++
++/* bits for PCICCFG */
++#define TX4938_PCIC_PCICCFG_GBWC_MASK	0x0fff0000
++#define TX4938_PCIC_PCICCFG_HRST	0x00000800
++#define TX4938_PCIC_PCICCFG_SRST	0x00000400
++#define TX4938_PCIC_PCICCFG_IRBER	0x00000200
++#define TX4938_PCIC_PCICCFG_G2PMEN(ch)	(0x00000100>>(ch))
++#define TX4938_PCIC_PCICCFG_G2PM0EN	0x00000100
++#define TX4938_PCIC_PCICCFG_G2PM1EN	0x00000080
++#define TX4938_PCIC_PCICCFG_G2PM2EN	0x00000040
++#define TX4938_PCIC_PCICCFG_G2PIOEN	0x00000020
++#define TX4938_PCIC_PCICCFG_TCAR	0x00000010
++#define TX4938_PCIC_PCICCFG_ICAEN	0x00000008
++
++/* bits for P2GMnGBASE */
++#define TX4938_PCIC_P2GMnGBASE_TMEMEN	_CONST64(0x0000004000000000)
++#define TX4938_PCIC_P2GMnGBASE_TBSDIS	_CONST64(0x0000002000000000)
++#define TX4938_PCIC_P2GMnGBASE_TECHG	_CONST64(0x0000001000000000)
++
++/* bits for P2GIOGBASE */
++#define TX4938_PCIC_P2GIOGBASE_TIOEN	_CONST64(0x0000004000000000)
++#define TX4938_PCIC_P2GIOGBASE_TBSDIS	_CONST64(0x0000002000000000)
++#define TX4938_PCIC_P2GIOGBASE_TECHG	_CONST64(0x0000001000000000)
++
++#define TX4938_PCIC_IDSEL_AD_TO_SLOT(ad)	((ad) - 11)
++#define TX4938_PCIC_MAX_DEVNU	TX4938_PCIC_IDSEL_AD_TO_SLOT(32)
++
++/* bits for PDMCFG */
++#define TX4938_PCIC_PDMCFG_RSTFIFO	0x00200000
++#define TX4938_PCIC_PDMCFG_EXFER	0x00100000
++#define TX4938_PCIC_PDMCFG_REQDLY_MASK	0x00003800
++#define TX4938_PCIC_PDMCFG_REQDLY_NONE	(0 << 11)
++#define TX4938_PCIC_PDMCFG_REQDLY_16	(1 << 11)
++#define TX4938_PCIC_PDMCFG_REQDLY_32	(2 << 11)
++#define TX4938_PCIC_PDMCFG_REQDLY_64	(3 << 11)
++#define TX4938_PCIC_PDMCFG_REQDLY_128	(4 << 11)
++#define TX4938_PCIC_PDMCFG_REQDLY_256	(5 << 11)
++#define TX4938_PCIC_PDMCFG_REQDLY_512	(6 << 11)
++#define TX4938_PCIC_PDMCFG_REQDLY_1024	(7 << 11)
++#define TX4938_PCIC_PDMCFG_ERRIE	0x00000400
++#define TX4938_PCIC_PDMCFG_NCCMPIE	0x00000200
++#define TX4938_PCIC_PDMCFG_NTCMPIE	0x00000100
++#define TX4938_PCIC_PDMCFG_CHNEN	0x00000080
++#define TX4938_PCIC_PDMCFG_XFRACT	0x00000040
++#define TX4938_PCIC_PDMCFG_BSWAP	0x00000020
++#define TX4938_PCIC_PDMCFG_XFRSIZE_MASK	0x0000000c
++#define TX4938_PCIC_PDMCFG_XFRSIZE_1DW	0x00000000
++#define TX4938_PCIC_PDMCFG_XFRSIZE_1QW	0x00000004
++#define TX4938_PCIC_PDMCFG_XFRSIZE_4QW	0x00000008
++#define TX4938_PCIC_PDMCFG_XFRDIRC	0x00000002
++#define TX4938_PCIC_PDMCFG_CHRST	0x00000001
++
++/* bits for PDMSTS */
++#define TX4938_PCIC_PDMSTS_REQCNT_MASK	0x3f000000
++#define TX4938_PCIC_PDMSTS_FIFOCNT_MASK	0x00f00000
++#define TX4938_PCIC_PDMSTS_FIFOWP_MASK	0x000c0000
++#define TX4938_PCIC_PDMSTS_FIFORP_MASK	0x00030000
++#define TX4938_PCIC_PDMSTS_ERRINT	0x00000800
++#define TX4938_PCIC_PDMSTS_DONEINT	0x00000400
++#define TX4938_PCIC_PDMSTS_CHNEN	0x00000200
++#define TX4938_PCIC_PDMSTS_XFRACT	0x00000100
++#define TX4938_PCIC_PDMSTS_ACCMP	0x00000080
++#define TX4938_PCIC_PDMSTS_NCCMP	0x00000040
++#define TX4938_PCIC_PDMSTS_NTCMP	0x00000020
++#define TX4938_PCIC_PDMSTS_CFGERR	0x00000008
++#define TX4938_PCIC_PDMSTS_PCIERR	0x00000004
++#define TX4938_PCIC_PDMSTS_CHNERR	0x00000002
++#define TX4938_PCIC_PDMSTS_DATAERR	0x00000001
++#define TX4938_PCIC_PDMSTS_ALL_CMP	0x000000e0
++#define TX4938_PCIC_PDMSTS_ALL_ERR	0x0000000f
++
++/*
++ * DMA
++ */
++/* bits for MCR */
++#define TX4938_DMA_MCR_EIS(ch)	(0x10000000<<(ch))
++#define TX4938_DMA_MCR_DIS(ch)	(0x01000000<<(ch))
++#define TX4938_DMA_MCR_RSFIF	0x00000080
++#define TX4938_DMA_MCR_FIFUM(ch)	(0x00000008<<(ch))
++#define TX4938_DMA_MCR_RPRT	0x00000002
++#define TX4938_DMA_MCR_MSTEN	0x00000001
++
++/* bits for CCRn */
++#define TX4938_DMA_CCR_IMMCHN	0x20000000
++#define TX4938_DMA_CCR_USEXFSZ	0x10000000
++#define TX4938_DMA_CCR_LE	0x08000000
++#define TX4938_DMA_CCR_DBINH	0x04000000
++#define TX4938_DMA_CCR_SBINH	0x02000000
++#define TX4938_DMA_CCR_CHRST	0x01000000
++#define TX4938_DMA_CCR_RVBYTE	0x00800000
++#define TX4938_DMA_CCR_ACKPOL	0x00400000
++#define TX4938_DMA_CCR_REQPL	0x00200000
++#define TX4938_DMA_CCR_EGREQ	0x00100000
++#define TX4938_DMA_CCR_CHDN	0x00080000
++#define TX4938_DMA_CCR_DNCTL	0x00060000
++#define TX4938_DMA_CCR_EXTRQ	0x00010000
++#define TX4938_DMA_CCR_INTRQD	0x0000e000
++#define TX4938_DMA_CCR_INTENE	0x00001000
++#define TX4938_DMA_CCR_INTENC	0x00000800
++#define TX4938_DMA_CCR_INTENT	0x00000400
++#define TX4938_DMA_CCR_CHNEN	0x00000200
++#define TX4938_DMA_CCR_XFACT	0x00000100
++#define TX4938_DMA_CCR_SMPCHN	0x00000020
++#define TX4938_DMA_CCR_XFSZ(order)	(((order) << 2) & 0x0000001c)
++#define TX4938_DMA_CCR_XFSZ_1W	TX4938_DMA_CCR_XFSZ(2)
++#define TX4938_DMA_CCR_XFSZ_2W	TX4938_DMA_CCR_XFSZ(3)
++#define TX4938_DMA_CCR_XFSZ_4W	TX4938_DMA_CCR_XFSZ(4)
++#define TX4938_DMA_CCR_XFSZ_8W	TX4938_DMA_CCR_XFSZ(5)
++#define TX4938_DMA_CCR_XFSZ_16W	TX4938_DMA_CCR_XFSZ(6)
++#define TX4938_DMA_CCR_XFSZ_32W	TX4938_DMA_CCR_XFSZ(7)
++#define TX4938_DMA_CCR_MEMIO	0x00000002
++#define TX4938_DMA_CCR_SNGAD	0x00000001
++
++/* bits for CSRn */
++#define TX4938_DMA_CSR_CHNEN	0x00000400
++#define TX4938_DMA_CSR_STLXFER	0x00000200
++#define TX4938_DMA_CSR_CHNACT	0x00000100
++#define TX4938_DMA_CSR_ABCHC	0x00000080
++#define TX4938_DMA_CSR_NCHNC	0x00000040
++#define TX4938_DMA_CSR_NTRNFC	0x00000020
++#define TX4938_DMA_CSR_EXTDN	0x00000010
++#define TX4938_DMA_CSR_CFERR	0x00000008
++#define TX4938_DMA_CSR_CHERR	0x00000004
++#define TX4938_DMA_CSR_DESERR	0x00000002
++#define TX4938_DMA_CSR_SORERR	0x00000001
++
++/* TX4938 Interrupt Controller (32-bit registers) */
++#define TX4938_IRC_BASE                 0xf510
++#define TX4938_IRC_IRFLAG0              0xf510
++#define TX4938_IRC_IRFLAG1              0xf514
++#define TX4938_IRC_IRPOL                0xf518
++#define TX4938_IRC_IRRCNT               0xf51c
++#define TX4938_IRC_IRMASKINT            0xf520
++#define TX4938_IRC_IRMASKEXT            0xf524
++#define TX4938_IRC_IRDEN                0xf600
++#define TX4938_IRC_IRDM0                0xf604
++#define TX4938_IRC_IRDM1                0xf608
++#define TX4938_IRC_IRLVL0               0xf610
++#define TX4938_IRC_IRLVL1               0xf614
++#define TX4938_IRC_IRLVL2               0xf618
++#define TX4938_IRC_IRLVL3               0xf61c
++#define TX4938_IRC_IRLVL4               0xf620
++#define TX4938_IRC_IRLVL5               0xf624
++#define TX4938_IRC_IRLVL6               0xf628
++#define TX4938_IRC_IRLVL7               0xf62c
++#define TX4938_IRC_IRMSK                0xf640
++#define TX4938_IRC_IREDC                0xf660
++#define TX4938_IRC_IRPND                0xf680
++#define TX4938_IRC_IRCS                 0xf6a0
++#define TX4938_IRC_LIMIT                0xf6ff
++
++
++#ifndef __ASSEMBLY__
++
++#define tx4938_sdramcptr	((struct tx4938_sdramc_reg *)TX4938_SDRAMC_REG)
++#define tx4938_ebuscptr         ((struct tx4938_ebusc_reg *)TX4938_EBUSC_REG)
++#define tx4938_dmaptr(ch)	((struct tx4938_dma_reg *)TX4938_DMA_REG(ch))
++#define tx4938_ndfmcptr		((struct tx4938_ndfmc_reg *)TX4938_NDFMC_REG)
++#define tx4938_ircptr		((struct tx4938_irc_reg *)TX4938_IRC_REG)
++#define tx4938_pcicptr		((struct tx4938_pcic_reg *)TX4938_PCIC_REG)
++#define tx4938_pcic1ptr		((struct tx4938_pcic_reg *)TX4938_PCIC1_REG)
++#define tx4938_ccfgptr		((struct tx4938_ccfg_reg *)TX4938_CCFG_REG)
++#define tx4938_tmrptr(ch)	((struct tx4938_tmr_reg *)TX4938_TMR_REG(ch))
++#define tx4938_sioptr(ch)	((struct tx4938_sio_reg *)TX4938_SIO_REG(ch))
++#define tx4938_pioptr		((struct tx4938_pio_reg *)TX4938_PIO_REG)
++#define tx4938_aclcptr		((struct tx4938_aclc_reg *)TX4938_ACLC_REG)
++#define tx4938_spiptr		((struct tx4938_spi_reg *)TX4938_SPI_REG)
++#define tx4938_sramcptr		((struct tx4938_sramc_reg *)TX4938_SRAMC_REG)
++
++
++#define TX4938_REV_MAJ_MIN()	((unsigned long)tx4938_ccfgptr->crir & 0x00ff)
++#define TX4938_REV_PCODE()	((unsigned long)tx4938_ccfgptr->crir >> 16)
++
++#define TX4938_SDRAMC_BA(ch)	((tx4938_sdramcptr->cr[ch] >> 49) << 21)
++#define TX4938_SDRAMC_SIZE(ch)	(((tx4938_sdramcptr->cr[ch] >> 33) + 1) << 21)
++
++#define TX4938_EBUSC_BA(ch)	((tx4938_ebuscptr->cr[ch] >> 48) << 20)
++#define TX4938_EBUSC_SIZE(ch)	\
++	(0x00100000 << ((unsigned long)(tx4938_ebuscptr->cr[ch] >> 8) & 0xf))
++
++
++#endif /* !__ASSEMBLY__ */
++
++#endif
+diff --git a/include/asm-mips/tx4938/tx4938_mips.h b/include/asm-mips/tx4938/tx4938_mips.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-mips/tx4938/tx4938_mips.h
+@@ -0,0 +1,54 @@
++/*
++ * linux/include/asm-mips/tx4938/tx4938_bitmask.h
++ * Generic bitmask definitions
++ *
++ * 2003-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.
++ *
++ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani at mvista.com)
++ */
++
++#ifndef TX4938_TX4938_MIPS_H
++#define TX4938_TX4938_MIPS_H
++#ifndef __ASSEMBLY__
++
++#define reg_rd08(r)    ((u8 )(*((vu8 *)(r))))
++#define reg_rd16(r)    ((u16)(*((vu16*)(r))))
++#define reg_rd32(r)    ((u32)(*((vu32*)(r))))
++#define reg_rd64(r)    ((u64)(*((vu64*)(r))))
++
++#define reg_wr08(r,v)  ((*((vu8 *)(r)))=((u8 )(v)))
++#define reg_wr16(r,v)  ((*((vu16*)(r)))=((u16)(v)))
++#define reg_wr32(r,v)  ((*((vu32*)(r)))=((u32)(v)))
++#define reg_wr64(r,v)  ((*((vu64*)(r)))=((u64)(v)))
++
++typedef volatile __signed char vs8;
++typedef volatile unsigned char vu8;
++
++typedef volatile __signed short vs16;
++typedef volatile unsigned short vu16;
++
++typedef volatile __signed int vs32;
++typedef volatile unsigned int vu32;
++
++typedef s8 s08;
++typedef vs8 vs08;
++
++typedef u8 u08;
++typedef vu8 vu08;
++
++#if (_MIPS_SZLONG == 64)
++
++typedef volatile __signed__ long vs64;
++typedef volatile unsigned long vu64;
++
++#else
++
++typedef volatile __signed__ long long vs64;
++typedef volatile unsigned long long vu64;
++
++#endif
++#endif
++#endif
+diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
+--- a/include/asm-mips/uaccess.h
++++ b/include/asm-mips/uaccess.h
+@@ -196,63 +196,55 @@
+ 	__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+ 
+ struct __large_struct { unsigned long buf[100]; };
+-#define __m(x) (*(struct __large_struct *)(x))
++#define __m(x) (*(struct __large_struct __user *)(x))
+ 
+ /*
+  * Yuck.  We need two variants, one for 64bit operation and one
+  * for 32 bit mode and old iron.
+  */
+ #ifdef __mips64
+-#define __GET_USER_DW(__gu_err) __get_user_asm("ld", __gu_err)
++#define __GET_USER_DW(ptr) __get_user_asm("ld", ptr)
+ #else
+-#define __GET_USER_DW(__gu_err) __get_user_asm_ll32(__gu_err)
++#define __GET_USER_DW(ptr) __get_user_asm_ll32(ptr)
+ #endif
+ 
+ #define __get_user_nocheck(x,ptr,size)					\
+ ({									\
+-	__typeof(*(ptr)) __gu_val = 0;					\
+-	long __gu_addr;							\
++	__typeof(*(ptr)) __gu_val =  (__typeof(*(ptr))) 0;		\
+ 	long __gu_err = 0;						\
+ 									\
+-	might_sleep();							\
+-	__gu_addr = (long) (ptr);					\
+ 	switch (size) {							\
+-	case 1: __get_user_asm("lb", __gu_err); break;			\
+-	case 2: __get_user_asm("lh", __gu_err); break;			\
+-	case 4: __get_user_asm("lw", __gu_err); break;			\
+-	case 8: __GET_USER_DW(__gu_err); break;				\
++	case 1: __get_user_asm("lb", ptr); break;			\
++	case 2: __get_user_asm("lh", ptr); break;			\
++	case 4: __get_user_asm("lw", ptr); break;			\
++	case 8: __GET_USER_DW(ptr); break;				\
+ 	default: __get_user_unknown(); break;				\
+ 	}								\
+-	x = (__typeof__(*(ptr))) __gu_val;				\
++	(x) = (__typeof__(*(ptr))) __gu_val;				\
+ 	__gu_err;							\
+ })
+ 
+ #define __get_user_check(x,ptr,size)					\
+ ({									\
++	const __typeof__(*(ptr)) __user * __gu_addr = (ptr);		\
+ 	__typeof__(*(ptr)) __gu_val = 0;				\
+-	long __gu_addr;							\
+-	long __gu_err;							\
+-									\
+-	might_sleep();							\
+-	__gu_addr = (long) (ptr);					\
+-	__gu_err = access_ok(VERIFY_READ, (void *) __gu_addr, size)	\
+-				? 0 : -EFAULT;				\
++	long __gu_err = -EFAULT;					\
+ 									\
+-	if (likely(!__gu_err)) {					\
++	if (likely(access_ok(VERIFY_READ,  __gu_addr, size))) {		\
+ 		switch (size) {						\
+-		case 1: __get_user_asm("lb", __gu_err); break;		\
+-		case 2: __get_user_asm("lh", __gu_err); break;		\
+-		case 4: __get_user_asm("lw", __gu_err); break;		\
+-		case 8: __GET_USER_DW(__gu_err); break;			\
++		case 1: __get_user_asm("lb", __gu_addr); break;		\
++		case 2: __get_user_asm("lh", __gu_addr); break;		\
++		case 4: __get_user_asm("lw", __gu_addr); break;		\
++		case 8: __GET_USER_DW(__gu_addr); break;		\
+ 		default: __get_user_unknown(); break;			\
+ 		}							\
+ 	}								\
+-	x = (__typeof__(*(ptr))) __gu_val;				\
++	(x) = (__typeof__(*(ptr))) __gu_val;				\
+ 	__gu_err;							\
+ })
+ 
+-#define __get_user_asm(insn,__gu_err)					\
+-({									\
++#define __get_user_asm(insn, addr)					\
++{									\
+ 	__asm__ __volatile__(						\
+ 	"1:	" insn "	%1, %3				\n"	\
+ 	"2:							\n"	\
+@@ -264,20 +256,20 @@ struct __large_struct { unsigned long bu
+ 	"	"__UA_ADDR "\t1b, 3b				\n"	\
+ 	"	.previous					\n"	\
+ 	: "=r" (__gu_err), "=r" (__gu_val)				\
+-	: "0" (__gu_err), "o" (__m(__gu_addr)), "i" (-EFAULT));		\
+-})
++	: "0" (0), "o" (__m(addr)), "i" (-EFAULT));			\
++}
+ 
+ /*
+  * Get a long long 64 using 32 bit registers.
+  */
+-#define __get_user_asm_ll32(__gu_err)					\
+-({									\
++#define __get_user_asm_ll32(addr)					\
++{									\
+ 	__asm__ __volatile__(						\
+-	"1:	lw	%1, %3					\n"	\
+-	"2:	lw	%D1, %4					\n"	\
++	"1:	lw	%1, (%3)				\n"	\
++	"2:	lw	%D1, 4(%3)				\n"	\
+ 	"	move	%0, $0					\n"	\
+ 	"3:	.section	.fixup,\"ax\"			\n"	\
+-	"4:	li	%0, %5					\n"	\
++	"4:	li	%0, %4					\n"	\
+ 	"	move	%1, $0					\n"	\
+ 	"	move	%D1, $0					\n"	\
+ 	"	j	3b					\n"	\
+@@ -287,9 +279,8 @@ struct __large_struct { unsigned long bu
+ 	"	" __UA_ADDR "	2b, 4b				\n"	\
+ 	"	.previous					\n"	\
+ 	: "=r" (__gu_err), "=&r" (__gu_val)				\
+-	: "0" (__gu_err), "o" (__m(__gu_addr)),				\
+-	  "o" (__m(__gu_addr + 4)), "i" (-EFAULT));			\
+-})
++	: "0" (0), "r" (addr), "i" (-EFAULT));				\
++}
+ 
+ extern void __get_user_unknown(void);
+ 
+@@ -298,25 +289,22 @@ extern void __get_user_unknown(void);
+  * for 32 bit mode and old iron.
+  */
+ #ifdef __mips64
+-#define __PUT_USER_DW(__pu_val) __put_user_asm("sd", __pu_val)
++#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
+ #else
+-#define __PUT_USER_DW(__pu_val) __put_user_asm_ll32(__pu_val)
++#define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr)
+ #endif
+ 
+ #define __put_user_nocheck(x,ptr,size)					\
+ ({									\
+ 	__typeof__(*(ptr)) __pu_val;					\
+-	long __pu_addr;							\
+ 	long __pu_err = 0;						\
+ 									\
+-	might_sleep();							\
+ 	__pu_val = (x);							\
+-	__pu_addr = (long) (ptr);					\
+ 	switch (size) {							\
+-	case 1: __put_user_asm("sb", __pu_val); break;			\
+-	case 2: __put_user_asm("sh", __pu_val); break;			\
+-	case 4: __put_user_asm("sw", __pu_val); break;			\
+-	case 8: __PUT_USER_DW(__pu_val); break;				\
++	case 1: __put_user_asm("sb", ptr); break;			\
++	case 2: __put_user_asm("sh", ptr); break;			\
++	case 4: __put_user_asm("sw", ptr); break;			\
++	case 8: __PUT_USER_DW(ptr); break;				\
+ 	default: __put_user_unknown(); break;				\
+ 	}								\
+ 	__pu_err;							\
+@@ -324,30 +312,24 @@ extern void __get_user_unknown(void);
+ 
+ #define __put_user_check(x,ptr,size)					\
+ ({									\
+-	__typeof__(*(ptr)) __pu_val;					\
+-	long __pu_addr;							\
+-	long __pu_err;							\
++	__typeof__(*(ptr)) __user *__pu_addr = (ptr);			\
++	__typeof__(*(ptr)) __pu_val = (x);				\
++	long __pu_err = -EFAULT;					\
+ 									\
+-	might_sleep();							\
+-	__pu_val = (x);							\
+-	__pu_addr = (long) (ptr);					\
+-	__pu_err = access_ok(VERIFY_WRITE, (void *) __pu_addr, size)	\
+-				? 0 : -EFAULT;				\
+-									\
+-	if (likely(!__pu_err)) {					\
++	if (likely(access_ok(VERIFY_WRITE,  __pu_addr, size))) {	\
+ 		switch (size) {						\
+-		case 1: __put_user_asm("sb", __pu_val); break;		\
+-		case 2: __put_user_asm("sh", __pu_val); break;		\
+-		case 4: __put_user_asm("sw", __pu_val); break;		\
+-		case 8: __PUT_USER_DW(__pu_val); break;			\
++		case 1: __put_user_asm("sb", __pu_addr); break;		\
++		case 2: __put_user_asm("sh", __pu_addr); break;		\
++		case 4: __put_user_asm("sw", __pu_addr); break;		\
++		case 8: __PUT_USER_DW(__pu_addr); break;		\
+ 		default: __put_user_unknown(); break;			\
+ 		}							\
+ 	}								\
+ 	__pu_err;							\
+ })
+ 
+-#define __put_user_asm(insn, __pu_val)					\
+-({									\
++#define __put_user_asm(insn, ptr)					\
++{									\
+ 	__asm__ __volatile__(						\
+ 	"1:	" insn "	%z2, %3		# __put_user_asm\n"	\
+ 	"2:							\n"	\
+@@ -359,18 +341,18 @@ extern void __get_user_unknown(void);
+ 	"	" __UA_ADDR "	1b, 3b				\n"	\
+ 	"	.previous					\n"	\
+ 	: "=r" (__pu_err)						\
+-	: "0" (__pu_err), "Jr" (__pu_val), "o" (__m(__pu_addr)),	\
++	: "0" (0), "Jr" (__pu_val), "o" (__m(ptr)),			\
+ 	  "i" (-EFAULT));						\
+-})
++}
+ 
+-#define __put_user_asm_ll32(__pu_val)					\
+-({									\
++#define __put_user_asm_ll32(ptr)					\
++{									\
+ 	__asm__ __volatile__(						\
+-	"1:	sw	%2, %3		# __put_user_asm_ll32	\n"	\
+-	"2:	sw	%D2, %4					\n"	\
++	"1:	sw	%2, (%3)	# __put_user_asm_ll32	\n"	\
++	"2:	sw	%D2, 4(%3)				\n"	\
+ 	"3:							\n"	\
+ 	"	.section	.fixup,\"ax\"			\n"	\
+-	"4:	li	%0, %5					\n"	\
++	"4:	li	%0, %4					\n"	\
+ 	"	j	3b					\n"	\
+ 	"	.previous					\n"	\
+ 	"	.section	__ex_table,\"a\"		\n"	\
+@@ -378,9 +360,9 @@ extern void __get_user_unknown(void);
+ 	"	" __UA_ADDR "	2b, 4b				\n"	\
+ 	"	.previous"						\
+ 	: "=r" (__pu_err)						\
+-	: "0" (__pu_err), "r" (__pu_val), "o" (__m(__pu_addr)),		\
+-	  "o" (__m(__pu_addr + 4)), "i" (-EFAULT));			\
+-})
++	: "0" (0), "r" (__pu_val), "r" (ptr),				\
++	  "i" (-EFAULT));						\
++}
+ 
+ extern void __put_user_unknown(void);
+ 
+@@ -403,7 +385,7 @@ extern size_t __copy_user(void *__to, co
+ 
+ #define __invoke_copy_to_user(to,from,n)				\
+ ({									\
+-	register void *__cu_to_r __asm__ ("$4");			\
++	register void __user *__cu_to_r __asm__ ("$4");			\
+ 	register const void *__cu_from_r __asm__ ("$5");		\
+ 	register long __cu_len_r __asm__ ("$6");			\
+ 									\
+@@ -435,7 +417,7 @@ extern size_t __copy_user(void *__to, co
+  */
+ #define __copy_to_user(to,from,n)					\
+ ({									\
+-	void *__cu_to;							\
++	void __user *__cu_to;						\
+ 	const void *__cu_from;						\
+ 	long __cu_len;							\
+ 									\
+@@ -465,7 +447,7 @@ extern size_t __copy_user(void *__to, co
+  */
+ #define copy_to_user(to,from,n)						\
+ ({									\
+-	void *__cu_to;							\
++	void __user *__cu_to;						\
+ 	const void *__cu_from;						\
+ 	long __cu_len;							\
+ 									\
+@@ -482,7 +464,7 @@ extern size_t __copy_user(void *__to, co
+ #define __invoke_copy_from_user(to,from,n)				\
+ ({									\
+ 	register void *__cu_to_r __asm__ ("$4");			\
+-	register const void *__cu_from_r __asm__ ("$5");		\
++	register const void __user *__cu_from_r __asm__ ("$5");		\
+ 	register long __cu_len_r __asm__ ("$6");			\
+ 									\
+ 	__cu_to_r = (to);						\
+@@ -521,7 +503,7 @@ extern size_t __copy_user(void *__to, co
+ #define __copy_from_user(to,from,n)					\
+ ({									\
+ 	void *__cu_to;							\
+-	const void *__cu_from;						\
++	const void __user *__cu_from;					\
+ 	long __cu_len;							\
+ 									\
+ 	might_sleep();							\
+@@ -552,7 +534,7 @@ extern size_t __copy_user(void *__to, co
+ #define copy_from_user(to,from,n)					\
+ ({									\
+ 	void *__cu_to;							\
+-	const void *__cu_from;						\
++	const void __user *__cu_from;					\
+ 	long __cu_len;							\
+ 									\
+ 	might_sleep();							\
+@@ -569,8 +551,8 @@ extern size_t __copy_user(void *__to, co
+ 
+ #define copy_in_user(to,from,n)						\
+ ({									\
+-	void *__cu_to;							\
+-	const void *__cu_from;						\
++	void __user *__cu_to;						\
++	const void __user *__cu_from;					\
+ 	long __cu_len;							\
+ 									\
+ 	might_sleep();							\
+@@ -596,7 +578,7 @@ extern size_t __copy_user(void *__to, co
+  * On success, this will be zero.
+  */
+ static inline __kernel_size_t
+-__clear_user(void *addr, __kernel_size_t size)
++__clear_user(void __user *addr, __kernel_size_t size)
+ {
+ 	__kernel_size_t res;
+ 
+@@ -616,7 +598,7 @@ __clear_user(void *addr, __kernel_size_t
+ 
+ #define clear_user(addr,n)						\
+ ({									\
+-	void * __cl_addr = (addr);					\
++	void __user * __cl_addr = (addr);				\
+ 	unsigned long __cl_size = (n);					\
+ 	if (__cl_size && access_ok(VERIFY_WRITE,			\
+ 		((unsigned long)(__cl_addr)), __cl_size))		\
+@@ -645,7 +627,7 @@ __clear_user(void *addr, __kernel_size_t
+  * and returns @count.
+  */
+ static inline long
+-__strncpy_from_user(char *__to, const char *__from, long __len)
++__strncpy_from_user(char *__to, const char __user *__from, long __len)
+ {
+ 	long res;
+ 
+@@ -682,7 +664,7 @@ __strncpy_from_user(char *__to, const ch
+  * and returns @count.
+  */
+ static inline long
+-strncpy_from_user(char *__to, const char *__from, long __len)
++strncpy_from_user(char *__to, const char __user *__from, long __len)
+ {
+ 	long res;
+ 
+@@ -701,7 +683,7 @@ strncpy_from_user(char *__to, const char
+ }
+ 
+ /* Returns: 0 if bad, string length+1 (memory size) of string if ok */
+-static inline long __strlen_user(const char *s)
++static inline long __strlen_user(const char __user *s)
+ {
+ 	long res;
+ 
+@@ -731,7 +713,7 @@ static inline long __strlen_user(const c
+  * If there is a limit on the length of a valid string, you may wish to
+  * consider using strnlen_user() instead.
+  */
+-static inline long strlen_user(const char *s)
++static inline long strlen_user(const char __user *s)
+ {
+ 	long res;
+ 
+@@ -748,7 +730,7 @@ static inline long strlen_user(const cha
+ }
+ 
+ /* Returns: 0 if bad, string length+1 (memory size) of string if ok */
+-static inline long __strnlen_user(const char *s, long n)
++static inline long __strnlen_user(const char __user *s, long n)
+ {
+ 	long res;
+ 
+@@ -779,7 +761,7 @@ static inline long __strnlen_user(const 
+  * If there is a limit on the length of a valid string, you may wish to
+  * consider using strnlen_user() instead.
+  */
+-static inline long strnlen_user(const char *s, long n)
++static inline long strnlen_user(const char __user *s, long n)
+ {
+ 	long res;
+ 
+diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
+--- a/include/asm-mips/unistd.h
++++ b/include/asm-mips/unistd.h
+@@ -303,16 +303,21 @@
+ #define __NR_add_key			(__NR_Linux + 280)
+ #define __NR_request_key		(__NR_Linux + 281)
+ #define __NR_keyctl			(__NR_Linux + 282)
++#define __NR_set_thread_area		(__NR_Linux + 283)
++#define __NR_inotify_init		(__NR_Linux + 284)
++#define __NR_inotify_add_watch		(__NR_Linux + 285)
++#define __NR_inotify_rm_watch		(__NR_Linux + 286)
++
+ 
+ /*
+  * Offset of the last Linux o32 flavoured syscall
+  */
+-#define __NR_Linux_syscalls		282
++#define __NR_Linux_syscalls		286
+ 
+ #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+ 
+ #define __NR_O32_Linux			4000
+-#define __NR_O32_Linux_syscalls		282
++#define __NR_O32_Linux_syscalls		283
+ 
+ #if _MIPS_SIM == _MIPS_SIM_ABI64
+ 
+@@ -562,16 +567,20 @@
+ #define __NR_add_key			(__NR_Linux + 239)
+ #define __NR_request_key		(__NR_Linux + 240)
+ #define __NR_keyctl			(__NR_Linux + 241)
++#define __NR_set_thread_area		(__NR_Linux + 242)
++#define __NR_inotify_init		(__NR_Linux + 243)
++#define __NR_inotify_add_watch		(__NR_Linux + 244)
++#define __NR_inotify_rm_watch		(__NR_Linux + 245)
+ 
+ /*
+  * Offset of the last Linux 64-bit flavoured syscall
+  */
+-#define __NR_Linux_syscalls		241
++#define __NR_Linux_syscalls		245
+ 
+ #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+ 
+ #define __NR_64_Linux			5000
+-#define __NR_64_Linux_syscalls		241
++#define __NR_64_Linux_syscalls		242
+ 
+ #if _MIPS_SIM == _MIPS_SIM_NABI32
+ 
+@@ -825,16 +834,20 @@
+ #define __NR_add_key			(__NR_Linux + 243)
+ #define __NR_request_key		(__NR_Linux + 244)
+ #define __NR_keyctl			(__NR_Linux + 245)
++#define __NR_set_thread_area		(__NR_Linux + 246)
++#define __NR_inotify_init		(__NR_Linux + 247)
++#define __NR_inotify_add_watch		(__NR_Linux + 248)
++#define __NR_inotify_rm_watch		(__NR_Linux + 249)
+ 
+ /*
+  * Offset of the last N32 flavoured syscall
+  */
+-#define __NR_Linux_syscalls		245
++#define __NR_Linux_syscalls		249
+ 
+ #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
+ 
+ #define __NR_N32_Linux			6000
+-#define __NR_N32_Linux_syscalls		245
++#define __NR_N32_Linux_syscalls		246
+ 
+ #ifndef __ASSEMBLY__
+ 
+@@ -1164,7 +1177,6 @@ asmlinkage long sys_mmap2(
+ 			unsigned long fd, unsigned long pgoff);
+ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs);
+ asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				const struct sigaction __user *act,
+diff --git a/include/asm-mips/vga.h b/include/asm-mips/vga.h
+--- a/include/asm-mips/vga.h
++++ b/include/asm-mips/vga.h
+@@ -6,6 +6,8 @@
+ #ifndef _ASM_VGA_H
+ #define _ASM_VGA_H
+ 
++#include <asm/byteorder.h>
++
+ /*
+  *	On the PC, we can just recalculate addresses and then
+  *	access the videoram directly without any black magic.
+@@ -16,4 +18,27 @@
+ #define vga_readb(x)	(*(x))
+ #define vga_writeb(x,y)	(*(y) = (x))
+ 
++#define VT_BUF_HAVE_RW
++/*
++ *  These are only needed for supporting VGA or MDA text mode, which use little
++ *  endian byte ordering.
++ *  In other cases, we can optimize by using native byte ordering and
++ *  <linux/vt_buffer.h> has already done the right job for us.
++ */
++
++static inline void scr_writew(u16 val, volatile u16 *addr)
++{
++	*addr = cpu_to_le16(val);
++}
++
++static inline u16 scr_readw(volatile const u16 *addr)
++{
++	return le16_to_cpu(*addr);
++}
++
++#define scr_memcpyw(d, s, c) memcpy(d, s, c)
++#define scr_memmovew(d, s, c) memmove(d, s, c)
++#define VT_BUF_HAVE_MEMCPYW
++#define VT_BUF_HAVE_MEMMOVEW
++
+ #endif /* _ASM_VGA_H */
+diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
+--- a/include/asm-mips/war.h
++++ b/include/asm-mips/war.h
+@@ -177,6 +177,17 @@
+ #endif
+ 
+ /*
++ * The RM9000 has a bug (though PMC-Sierra opposes it being called that)
++ * where invalid instructions in the same I-cache line worth of instructions
++ * being fetched may case spurious exceptions.
++ */
++#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_MOMENCO_OCELOT_3) || \
++    defined(CONFIG_PMC_YOSEMITE)
++#define ICACHE_REFILLS_WORKAROUND_WAR	1
++#endif
++
++
++/*
+  * ON the R10000 upto version 2.6 (not sure about 2.7) there is a bug that
+  * may cause ll / sc and lld / scd sequences to execute non-atomically.
+  */
+@@ -187,6 +198,9 @@
+ /*
+  * Workarounds default to off
+  */
++#ifndef ICACHE_REFILLS_WORKAROUND_WAR
++#define ICACHE_REFILLS_WORKAROUND_WAR	0
++#endif
+ #ifndef R4600_V1_INDEX_ICACHEOP_WAR
+ #define R4600_V1_INDEX_ICACHEOP_WAR	0
+ #endif
+diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h
+--- a/include/asm-parisc/assembly.h
++++ b/include/asm-parisc/assembly.h
+@@ -21,7 +21,9 @@
+ #ifndef _PARISC_ASSEMBLY_H
+ #define _PARISC_ASSEMBLY_H
+ 
+-#ifdef __LP64__
++#define CALLEE_FLOAT_FRAME_SIZE	80
++
++#ifdef CONFIG_64BIT
+ #define LDREG	ldd
+ #define STREG	std
+ #define LDREGX  ldd,s
+@@ -30,8 +32,8 @@
+ #define SHRREG  shrd
+ #define RP_OFFSET	16
+ #define FRAME_SIZE	128
+-#define CALLEE_SAVE_FRAME_SIZE	144
+-#else
++#define CALLEE_REG_FRAME_SIZE	144
++#else	/* CONFIG_64BIT */
+ #define LDREG	ldw
+ #define STREG	stw
+ #define LDREGX  ldwx,s
+@@ -40,9 +42,11 @@
+ #define SHRREG  shr
+ #define RP_OFFSET	20
+ #define FRAME_SIZE	64
+-#define CALLEE_SAVE_FRAME_SIZE	128
++#define CALLEE_REG_FRAME_SIZE	128
+ #endif
+ 
++#define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE)
++
+ #ifdef CONFIG_PA20
+ #define BL		b,l
+ # ifdef CONFIG_64BIT
+@@ -300,9 +304,35 @@
+ 	fldd,mb	-8(\regs),       %fr0
+ 	.endm
+ 
++	.macro	callee_save_float
++	fstd,ma	 %fr12,	8(%r30)
++	fstd,ma	 %fr13,	8(%r30)
++	fstd,ma	 %fr14,	8(%r30)
++	fstd,ma	 %fr15,	8(%r30)
++	fstd,ma	 %fr16,	8(%r30)
++	fstd,ma	 %fr17,	8(%r30)
++	fstd,ma	 %fr18,	8(%r30)
++	fstd,ma	 %fr19,	8(%r30)
++	fstd,ma	 %fr20,	8(%r30)
++	fstd,ma	 %fr21,	8(%r30)
++	.endm
++
++	.macro	callee_rest_float
++	fldd,mb	-8(%r30),   %fr21
++	fldd,mb	-8(%r30),   %fr20
++	fldd,mb	-8(%r30),   %fr19
++	fldd,mb	-8(%r30),   %fr18
++	fldd,mb	-8(%r30),   %fr17
++	fldd,mb	-8(%r30),   %fr16
++	fldd,mb	-8(%r30),   %fr15
++	fldd,mb	-8(%r30),   %fr14
++	fldd,mb	-8(%r30),   %fr13
++	fldd,mb	-8(%r30),   %fr12
++	.endm
++
+ #ifdef __LP64__
+ 	.macro	callee_save
+-	std,ma	  %r3,	CALLEE_SAVE_FRAME_SIZE(%r30)
++	std,ma	  %r3,	 CALLEE_REG_FRAME_SIZE(%r30)
+ 	mfctl	  %cr27, %r3
+ 	std	  %r4,	-136(%r30)
+ 	std	  %r5,	-128(%r30)
+@@ -340,13 +370,13 @@
+ 	ldd	-128(%r30),    %r5
+ 	ldd	-136(%r30),    %r4
+ 	mtctl	%r3, %cr27
+-	ldd,mb	-CALLEE_SAVE_FRAME_SIZE(%r30),    %r3
++	ldd,mb	-CALLEE_REG_FRAME_SIZE(%r30),    %r3
+ 	.endm
+ 
+ #else /* ! __LP64__ */
+ 
+ 	.macro	callee_save
+-	stw,ma	 %r3,	CALLEE_SAVE_FRAME_SIZE(%r30)
++	stw,ma	 %r3,	CALLEE_REG_FRAME_SIZE(%r30)
+ 	mfctl	 %cr27, %r3
+ 	stw	 %r4,	-124(%r30)
+ 	stw	 %r5,	-120(%r30)
+@@ -384,7 +414,7 @@
+ 	ldw	-120(%r30),   %r5
+ 	ldw	-124(%r30),   %r4
+ 	mtctl	%r3, %cr27
+-	ldw,mb	-CALLEE_SAVE_FRAME_SIZE(%r30),   %r3
++	ldw,mb	-CALLEE_REG_FRAME_SIZE(%r30),   %r3
+ 	.endm
+ #endif /* ! __LP64__ */
+ 
+@@ -450,5 +480,30 @@
+ 	REST_CR	(%cr22, PT_PSW	(\regs))
+ 	.endm
+ 
++
++	/* First step to create a "relied upon translation"
++	 * See PA 2.0 Arch. page F-4 and F-5.
++	 *
++	 * The ssm was originally necessary due to a "PCxT bug".
++	 * But someone decided it needed to be added to the architecture
++	 * and this "feature" went into rev3 of PA-RISC 1.1 Arch Manual.
++	 * It's been carried forward into PA 2.0 Arch as well. :^(
++	 *
++	 * "ssm 0,%r0" is a NOP with side effects (prefetch barrier).
++	 * rsm/ssm prevents the ifetch unit from speculatively fetching
++	 * instructions past this line in the code stream.
++	 * PA 2.0 processor will single step all insn in the same QUAD (4 insn).
++	 */
++	.macro	pcxt_ssm_bug
++	rsm	PSW_SM_I,%r0
++	nop	/* 1 */
++	nop	/* 2 */
++	nop	/* 3 */
++	nop	/* 4 */
++	nop	/* 5 */
++	nop	/* 6 */
++	nop	/* 7 */
++	.endm
++
+ #endif /* __ASSEMBLY__ */
+ #endif
+diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
+--- a/include/asm-parisc/bitops.h
++++ b/include/asm-parisc/bitops.h
+@@ -2,7 +2,7 @@
+ #define _PARISC_BITOPS_H
+ 
+ #include <linux/compiler.h>
+-#include <asm/spinlock.h>
++#include <asm/types.h>		/* for BITS_PER_LONG/SHIFT_PER_LONG */
+ #include <asm/byteorder.h>
+ #include <asm/atomic.h>
+ 
+@@ -12,193 +12,157 @@
+  * to include/asm-i386/bitops.h or kerneldoc
+  */
+ 
+-#ifdef __LP64__
+-#   define SHIFT_PER_LONG 6
+-#ifndef BITS_PER_LONG
+-#   define BITS_PER_LONG 64
+-#endif
+-#else
+-#   define SHIFT_PER_LONG 5
+-#ifndef BITS_PER_LONG
+-#   define BITS_PER_LONG 32
+-#endif
+-#endif
+-
+-#define CHOP_SHIFTCOUNT(x) ((x) & (BITS_PER_LONG - 1))
++#define CHOP_SHIFTCOUNT(x) (((unsigned long) (x)) & (BITS_PER_LONG - 1))
+ 
+ 
+ #define smp_mb__before_clear_bit()      smp_mb()
+ #define smp_mb__after_clear_bit()       smp_mb()
+ 
+-static __inline__ void set_bit(int nr, volatile unsigned long * address)
++/* See http://marc.theaimsgroup.com/?t=108826637900003 for discussion
++ * on use of volatile and __*_bit() (set/clear/change):
++ *	*_bit() want use of volatile.
++ *	__*_bit() are "relaxed" and don't use spinlock or volatile.
++ */
++
++static __inline__ void set_bit(int nr, volatile unsigned long * addr)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
++	unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
+ 	unsigned long flags;
+ 
+ 	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+ 	_atomic_spin_lock_irqsave(addr, flags);
+ 	*addr |= mask;
+ 	_atomic_spin_unlock_irqrestore(addr, flags);
+ }
+ 
+-static __inline__ void __set_bit(int nr, volatile unsigned long * address)
++static __inline__ void __set_bit(unsigned long nr, volatile unsigned long * addr)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
++	unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG);
+ 
+-	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+-	*addr |= mask;
++	*m |= 1UL << CHOP_SHIFTCOUNT(nr);
+ }
+ 
+-static __inline__ void clear_bit(int nr, volatile unsigned long * address)
++static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
++	unsigned long mask = ~(1UL << CHOP_SHIFTCOUNT(nr));
+ 	unsigned long flags;
+ 
+ 	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+ 	_atomic_spin_lock_irqsave(addr, flags);
+-	*addr &= ~mask;
++	*addr &= mask;
+ 	_atomic_spin_unlock_irqrestore(addr, flags);
+ }
+ 
+-static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * address)
++static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * addr)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
++	unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG);
+ 
+-	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+-	*addr &= ~mask;
++	*m &= ~(1UL << CHOP_SHIFTCOUNT(nr));
+ }
+ 
+-static __inline__ void change_bit(int nr, volatile unsigned long * address)
++static __inline__ void change_bit(int nr, volatile unsigned long * addr)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
++	unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
+ 	unsigned long flags;
+ 
+ 	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+ 	_atomic_spin_lock_irqsave(addr, flags);
+ 	*addr ^= mask;
+ 	_atomic_spin_unlock_irqrestore(addr, flags);
+ }
+ 
+-static __inline__ void __change_bit(int nr, volatile unsigned long * address)
++static __inline__ void __change_bit(unsigned long nr, volatile unsigned long * addr)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
++	unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG);
+ 
+-	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+-	*addr ^= mask;
++	*m ^= 1UL << CHOP_SHIFTCOUNT(nr);
+ }
+ 
+-static __inline__ int test_and_set_bit(int nr, volatile unsigned long * address)
++static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
+-	int oldbit;
++	unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
++	unsigned long oldbit;
+ 	unsigned long flags;
+ 
+ 	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+ 	_atomic_spin_lock_irqsave(addr, flags);
+-	oldbit = (*addr & mask) ? 1 : 0;
+-	*addr |= mask;
++	oldbit = *addr;
++	*addr = oldbit | mask;
+ 	_atomic_spin_unlock_irqrestore(addr, flags);
+ 
+-	return oldbit;
++	return (oldbit & mask) ? 1 : 0;
+ }
+ 
+ static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * address)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
+-	int oldbit;
++	unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
++	unsigned long oldbit;
++	unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG);
+ 
+-	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+-	oldbit = (*addr & mask) ? 1 : 0;
+-	*addr |= mask;
++	oldbit = *addr;
++	*addr = oldbit | mask;
+ 
+-	return oldbit;
++	return (oldbit & mask) ? 1 : 0;
+ }
+ 
+-static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * address)
++static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
+-	int oldbit;
++	unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
++	unsigned long oldbit;
+ 	unsigned long flags;
+ 
+ 	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+ 	_atomic_spin_lock_irqsave(addr, flags);
+-	oldbit = (*addr & mask) ? 1 : 0;
+-	*addr &= ~mask;
++	oldbit = *addr;
++	*addr = oldbit & ~mask;
+ 	_atomic_spin_unlock_irqrestore(addr, flags);
+ 
+-	return oldbit;
++	return (oldbit & mask) ? 1 : 0;
+ }
+ 
+ static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long * address)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
+-	int oldbit;
++	unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
++	unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG);
++	unsigned long oldbit;
+ 
+-	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+-	oldbit = (*addr & mask) ? 1 : 0;
+-	*addr &= ~mask;
++	oldbit = *addr;
++	*addr = oldbit & ~mask;
+ 
+-	return oldbit;
++	return (oldbit & mask) ? 1 : 0;
+ }
+ 
+-static __inline__ int test_and_change_bit(int nr, volatile unsigned long * address)
++static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
+-	int oldbit;
++	unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
++	unsigned long oldbit;
+ 	unsigned long flags;
+ 
+ 	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+ 	_atomic_spin_lock_irqsave(addr, flags);
+-	oldbit = (*addr & mask) ? 1 : 0;
+-	*addr ^= mask;
++	oldbit = *addr;
++	*addr = oldbit ^ mask;
+ 	_atomic_spin_unlock_irqrestore(addr, flags);
+ 
+-	return oldbit;
++	return (oldbit & mask) ? 1 : 0;
+ }
+ 
+ static __inline__ int __test_and_change_bit(int nr, volatile unsigned long * address)
+ {
+-	unsigned long mask;
+-	unsigned long *addr = (unsigned long *) address;
+-	int oldbit;
++	unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
++	unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG);
++	unsigned long oldbit;
+ 
+-	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
+-	oldbit = (*addr & mask) ? 1 : 0;
+-	*addr ^= mask;
++	oldbit = *addr;
++	*addr = oldbit ^ mask;
+ 
+-	return oldbit;
++	return (oldbit & mask) ? 1 : 0;
+ }
+ 
+ static __inline__ int test_bit(int nr, const volatile unsigned long *address)
+ {
+-	unsigned long mask;
+-	const unsigned long *addr = (const unsigned long *)address;
+-	
+-	addr += (nr >> SHIFT_PER_LONG);
+-	mask = 1L << CHOP_SHIFTCOUNT(nr);
++	unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
++	const unsigned long *addr = (const unsigned long *)address + (nr >> SHIFT_PER_LONG);
+ 	
+ 	return !!(*addr & mask);
+ }
+@@ -229,7 +193,7 @@ static __inline__ unsigned long __ffs(un
+ 	unsigned long ret;
+ 
+ 	__asm__(
+-#if BITS_PER_LONG > 32
++#ifdef __LP64__
+ 		" ldi       63,%1\n"
+ 		" extrd,u,*<>  %0,63,32,%%r0\n"
+ 		" extrd,u,*TR  %0,31,32,%0\n"	/* move top 32-bits down */
+@@ -304,14 +268,7 @@ static __inline__ int fls(int x)
+  * hweightN: returns the hamming weight (i.e. the number
+  * of bits set) of a N-bit word
+  */
+-#define hweight64(x)						\
+-({								\
+-	unsigned long __x = (x);				\
+-	unsigned int __w;					\
+-	__w = generic_hweight32((unsigned int) __x);		\
+-	__w += generic_hweight32((unsigned int) (__x>>32));	\
+-	__w;							\
+-})
++#define hweight64(x) generic_hweight64(x)
+ #define hweight32(x) generic_hweight32(x)
+ #define hweight16(x) generic_hweight16(x)
+ #define hweight8(x) generic_hweight8(x)
+@@ -324,7 +281,13 @@ static __inline__ int fls(int x)
+  */
+ static inline int sched_find_first_bit(const unsigned long *b)
+ {
+-#ifndef __LP64__
++#ifdef __LP64__
++	if (unlikely(b[0]))
++		return __ffs(b[0]);
++	if (unlikely(b[1]))
++		return __ffs(b[1]) + 64;
++	return __ffs(b[2]) + 128;
++#else
+ 	if (unlikely(b[0]))
+ 		return __ffs(b[0]);
+ 	if (unlikely(b[1]))
+@@ -334,14 +297,6 @@ static inline int sched_find_first_bit(c
+ 	if (b[3])
+ 		return __ffs(b[3]) + 96;
+ 	return __ffs(b[4]) + 128;
+-#else
+-	if (unlikely(b[0]))
+-		return __ffs(b[0]);
+-	if (unlikely(((unsigned int)b[1])))
+-		return __ffs(b[1]) + 64;
+-	if (b[1] >> 32)
+-		return __ffs(b[1] >> 32) + 96;
+-	return __ffs(b[2]) + 128;
+ #endif
+ }
+ 
+@@ -391,7 +346,7 @@ found_middle:
+ 
+ static __inline__ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset)
+ {
+-	const unsigned long *p = addr + (offset >> 6);
++	const unsigned long *p = addr + (offset >> SHIFT_PER_LONG);
+ 	unsigned long result = offset & ~(BITS_PER_LONG-1);
+ 	unsigned long tmp;
+ 
+@@ -445,71 +400,90 @@ found_middle:
+  * test_and_{set,clear}_bit guarantee atomicity without
+  * disabling interrupts.
+  */
+-#ifdef __LP64__
+-#define ext2_set_bit(nr, addr)		__test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
+-#define ext2_set_bit_atomic(l,nr,addr)  test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
+-#define ext2_clear_bit(nr, addr)	__test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
+-#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
+-#else
+-#define ext2_set_bit(nr, addr)		__test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
+-#define ext2_set_bit_atomic(l,nr,addr)  test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
+-#define ext2_clear_bit(nr, addr)	__test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
+-#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
+-#endif
+ 
+-#endif	/* __KERNEL__ */
++/* '3' is bits per byte */
++#define LE_BYTE_ADDR ((sizeof(unsigned long) - 1) << 3)
+ 
+-static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
+-{
+-	__const__ unsigned char	*ADDR = (__const__ unsigned char *) addr;
++#define ext2_test_bit(nr, addr) \
++			test_bit((nr)	^ LE_BYTE_ADDR, (unsigned long *)addr)
++#define ext2_set_bit(nr, addr)	\
++		__test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
++#define ext2_clear_bit(nr, addr) \
++		__test_and_clear_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
++
++#define ext2_set_bit_atomic(l,nr,addr) \
++		test_and_set_bit((nr)   ^ LE_BYTE_ADDR, (unsigned long *)addr)
++#define ext2_clear_bit_atomic(l,nr,addr) \
++		test_and_clear_bit( (nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
+ 
+-	return (ADDR[nr >> 3] >> (nr & 7)) & 1;
+-}
++#endif	/* __KERNEL__ */
+ 
+-/*
+- * This implementation of ext2_find_{first,next}_zero_bit was stolen from
+- * Linus' asm-alpha/bitops.h and modified for a big-endian machine.
+- */
+ 
+ #define ext2_find_first_zero_bit(addr, size) \
+-        ext2_find_next_zero_bit((addr), (size), 0)
++	ext2_find_next_zero_bit((addr), (size), 0)
++
++/* include/linux/byteorder does not support "unsigned long" type */
++static inline unsigned long ext2_swabp(unsigned long * x)
++{
++#ifdef __LP64__
++	return (unsigned long) __swab64p((u64 *) x);
++#else
++	return (unsigned long) __swab32p((u32 *) x);
++#endif
++}
++
++/* include/linux/byteorder doesn't support "unsigned long" type */
++static inline unsigned long ext2_swab(unsigned long y)
++{
++#ifdef __LP64__
++	return (unsigned long) __swab64((u64) y);
++#else
++	return (unsigned long) __swab32((u32) y);
++#endif
++}
+ 
+-extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr,
+-	unsigned long size, unsigned long offset)
++static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+ {
+-	unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
+-	unsigned int result = offset & ~31UL;
+-	unsigned int tmp;
++	unsigned long *p = (unsigned long *) addr + (offset >> SHIFT_PER_LONG);
++	unsigned long result = offset & ~(BITS_PER_LONG - 1);
++	unsigned long tmp;
+ 
+ 	if (offset >= size)
+ 		return size;
+ 	size -= result;
+-	offset &= 31UL;
++	offset &= (BITS_PER_LONG - 1UL);
+ 	if (offset) {
+-		tmp = cpu_to_le32p(p++);
+-		tmp |= ~0UL >> (32-offset);
+-		if (size < 32)
++		tmp = ext2_swabp(p++);
++		tmp |= (~0UL >> (BITS_PER_LONG - offset));
++		if (size < BITS_PER_LONG)
+ 			goto found_first;
+-		if (tmp != ~0U)
++		if (~tmp)
+ 			goto found_middle;
+-		size -= 32;
+-		result += 32;
++		size -= BITS_PER_LONG;
++		result += BITS_PER_LONG;
+ 	}
+-	while (size >= 32) {
+-		if ((tmp = cpu_to_le32p(p++)) != ~0U)
+-			goto found_middle;
+-		result += 32;
+-		size -= 32;
++
++	while (size & ~(BITS_PER_LONG - 1)) {
++		if (~(tmp = *(p++)))
++			goto found_middle_swap;
++		result += BITS_PER_LONG;
++		size -= BITS_PER_LONG;
+ 	}
+ 	if (!size)
+ 		return result;
+-	tmp = cpu_to_le32p(p);
++	tmp = ext2_swabp(p);
+ found_first:
+-	tmp |= ~0U << size;
++	tmp |= ~0UL << size;
++	if (tmp == ~0UL)	/* Are any bits zero? */
++		return result + size; /* Nope. Skip ffz */
+ found_middle:
+ 	return result + ffz(tmp);
++
++found_middle_swap:
++	return result + ffz(ext2_swab(tmp));
+ }
+ 
++
+ /* Bitmap functions for the minix filesystem.  */
+ #define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr)
+ #define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr))
+diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
+--- a/include/asm-parisc/cacheflush.h
++++ b/include/asm-parisc/cacheflush.h
+@@ -100,30 +100,34 @@ static inline void flush_cache_range(str
+ 
+ /* Simple function to work out if we have an existing address translation
+  * for a user space vma. */
+-static inline pte_t *__translation_exists(struct mm_struct *mm,
+-					  unsigned long addr)
++static inline int translation_exists(struct vm_area_struct *vma,
++				unsigned long addr, unsigned long pfn)
+ {
+-	pgd_t *pgd = pgd_offset(mm, addr);
++	pgd_t *pgd = pgd_offset(vma->vm_mm, addr);
+ 	pmd_t *pmd;
+-	pte_t *pte;
++	pte_t pte;
+ 
+ 	if(pgd_none(*pgd))
+-		return NULL;
++		return 0;
+ 
+ 	pmd = pmd_offset(pgd, addr);
+ 	if(pmd_none(*pmd) || pmd_bad(*pmd))
+-		return NULL;
++		return 0;
+ 
+-	pte = pte_offset_map(pmd, addr);
++	/* We cannot take the pte lock here: flush_cache_page is usually
++	 * called with pte lock already held.  Whereas flush_dcache_page
++	 * takes flush_dcache_mmap_lock, which is lower in the hierarchy:
++	 * the vma itself is secure, but the pte might come or go racily.
++	 */
++	pte = *pte_offset_map(pmd, addr);
++	/* But pte_unmap() does nothing on this architecture */
++
++	/* Filter out coincidental file entries and swap entries */
++	if (!(pte_val(pte) & (_PAGE_FLUSH|_PAGE_PRESENT)))
++		return 0;
+ 
+-	/* The PA flush mappings show up as pte_none, but they're
+-	 * valid none the less */
+-	if(pte_none(*pte) && ((pte_val(*pte) & _PAGE_FLUSH) == 0))
+-		return NULL;
+-	return pte;
++	return pte_pfn(pte) == pfn;
+ }
+-#define	translation_exists(vma, addr)	__translation_exists((vma)->vm_mm, addr)
+-
+ 
+ /* Private function to flush a page from the cache of a non-current
+  * process.  cr25 contains the Page Directory of the current user
+@@ -175,9 +179,8 @@ flush_cache_page(struct vm_area_struct *
+ {
+ 	BUG_ON(!vma->vm_mm->context);
+ 
+-	if(likely(translation_exists(vma, vmaddr)))
++	if (likely(translation_exists(vma, vmaddr, pfn)))
+ 		__flush_cache_page(vma, vmaddr);
+ 
+ }
+ #endif
+-
+diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
+--- a/include/asm-parisc/dma-mapping.h
++++ b/include/asm-parisc/dma-mapping.h
+@@ -9,8 +9,8 @@
+ /* See Documentation/DMA-mapping.txt */
+ struct hppa_dma_ops {
+ 	int  (*dma_supported)(struct device *dev, u64 mask);
+-	void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
+-	void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
++	void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
++	void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
+ 	void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova);
+ 	dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction);
+ 	void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction);
+@@ -49,14 +49,14 @@ extern struct hppa_dma_ops *hppa_dma_ops
+ 
+ static inline void *
+ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+-		   int flag)
++		   gfp_t flag)
+ {
+ 	return hppa_dma_ops->alloc_consistent(dev, size, dma_handle, flag);
+ }
+ 
+ static inline void *
+ dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+-		      int flag)
++		      gfp_t flag)
+ {
+ 	return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle, flag);
+ }
+diff --git a/include/asm-parisc/errno.h b/include/asm-parisc/errno.h
+--- a/include/asm-parisc/errno.h
++++ b/include/asm-parisc/errno.h
+@@ -114,6 +114,7 @@
+ 
+ #define ENOTSUP		252	/* Function not implemented (POSIX.4 / HPUX) */
+ #define ECANCELLED	253	/* aio request was canceled before complete (POSIX.4 / HPUX) */
++#define ECANCELED	ECANCELLED	/* SuSv3 and Solaris wants one 'L' */
+ 
+ /* for robust mutexes */
+ #define EOWNERDEAD	254	/* Owner died */
+diff --git a/include/asm-parisc/grfioctl.h b/include/asm-parisc/grfioctl.h
+--- a/include/asm-parisc/grfioctl.h
++++ b/include/asm-parisc/grfioctl.h
+@@ -69,6 +69,8 @@
+ #define CRT_ID_TVRX		S9000_ID_98765	/* TVRX (gto/falcon) */
+ #define CRT_ID_ARTIST		S9000_ID_ARTIST	/* Artist */
+ #define CRT_ID_SUMMIT		0x2FC1066B      /* Summit FX2, FX4, FX6 ... */
++#define CRT_ID_LEGO		0x35ACDA30	/* Lego FX5, FX10 ... */
++#define CRT_ID_PINNACLE		0x35ACDA16	/* Pinnacle FXe */ 
+ 
+ /* structure for ioctl(GCDESCRIBE) */
+ 
+diff --git a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h
+--- a/include/asm-parisc/ide.h
++++ b/include/asm-parisc/ide.h
+@@ -22,7 +22,6 @@
+ 
+ #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
+ #define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
+-#define ide_check_region(from,extent)		check_region((from), (extent))
+ #define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
+ #define ide_release_region(from,extent)		release_region((from), (extent))
+ /* Generic I/O and MEMIO string operations.  */
+diff --git a/include/asm-parisc/led.h b/include/asm-parisc/led.h
+--- a/include/asm-parisc/led.h
++++ b/include/asm-parisc/led.h
+@@ -23,9 +23,6 @@
+ 
+ #define LED_CMD_REG_NONE 0		/* NULL == no addr for the cmd register */
+ 
+-/* led tasklet struct */
+-extern struct tasklet_struct led_tasklet;
+-
+ /* register_led_driver() */
+ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg);
+ 
+diff --git a/include/asm-parisc/mmzone.h b/include/asm-parisc/mmzone.h
+--- a/include/asm-parisc/mmzone.h
++++ b/include/asm-parisc/mmzone.h
+@@ -27,12 +27,6 @@ extern struct node_map_data node_data[];
+ })
+ #define node_localnr(pfn, nid)		((pfn) - node_start_pfn(nid))
+ 
+-#define local_mapnr(kvaddr)						\
+-({									\
+-	unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT;		\
+-	(__pfn - node_start_pfn(pfn_to_nid(__pfn)));			\
+-})
+-
+ #define pfn_to_page(pfn)						\
+ ({									\
+ 	unsigned long __pfn = (pfn);					\
+diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
+--- a/include/asm-parisc/parisc-device.h
++++ b/include/asm-parisc/parisc-device.h
+@@ -1,7 +1,7 @@
+ #include <linux/device.h>
+ 
+ struct parisc_device {
+-	unsigned long   hpa;		/* Hard Physical Address */
++	struct resource hpa;		/* Hard Physical Address */
+ 	struct parisc_device_id id;
+ 	struct parisc_driver *driver;	/* Driver for this device */
+ 	char		name[80];	/* The hardware description */
+@@ -39,6 +39,11 @@ struct parisc_driver {
+ #define to_parisc_driver(d)	container_of(d, struct parisc_driver, drv)
+ #define parisc_parent(d)	to_parisc_device(d->dev.parent)
+ 
++static inline char *parisc_pathname(struct parisc_device *d)
++{
++	return d->dev.bus_id;
++}
++
+ static inline void
+ parisc_set_drvdata(struct parisc_device *d, void *p)
+ {
+diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
+--- a/include/asm-parisc/pci.h
++++ b/include/asm-parisc/pci.h
+@@ -69,7 +69,7 @@ struct pci_hba_data {
+ #define PCI_PORT_HBA(a)		((a) >> HBA_PORT_SPACE_BITS)
+ #define PCI_PORT_ADDR(a)	((a) & (HBA_PORT_SPACE_SIZE - 1))
+ 
+-#if CONFIG_64BIT
++#ifdef CONFIG_64BIT
+ #define PCI_F_EXTEND		0xffffffff00000000UL
+ #define PCI_IS_LMMIO(hba,a)	pci_is_lmmio(hba,a)
+ 
+diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
+--- a/include/asm-parisc/pgtable.h
++++ b/include/asm-parisc/pgtable.h
+@@ -501,6 +501,8 @@ static inline void ptep_set_wrprotect(st
+ #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
+ 		remap_pfn_range(vma, vaddr, pfn, size, prot)
+ 
++#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_NO_CACHE)
++
+ #define MK_IOSPACE_PFN(space, pfn)	(pfn)
+ #define GET_IOSPACE(pfn)		0
+ #define GET_PFN(pfn)			(pfn)
+diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
+--- a/include/asm-parisc/processor.h
++++ b/include/asm-parisc/processor.h
+@@ -122,8 +122,27 @@ struct thread_struct {
+ }; 
+ 
+ /* Thread struct flags. */
++#define PARISC_UAC_NOPRINT	(1UL << 0)	/* see prctl and unaligned.c */
++#define PARISC_UAC_SIGBUS	(1UL << 1)
+ #define PARISC_KERNEL_DEATH	(1UL << 31)	/* see die_if_kernel()... */
+ 
++#define PARISC_UAC_SHIFT	0
++#define PARISC_UAC_MASK		(PARISC_UAC_NOPRINT|PARISC_UAC_SIGBUS)
++
++#define SET_UNALIGN_CTL(task,value)                                       \
++        ({                                                                \
++        (task)->thread.flags = (((task)->thread.flags & ~PARISC_UAC_MASK) \
++                                | (((value) << PARISC_UAC_SHIFT) &        \
++                                   PARISC_UAC_MASK));                     \
++        0;                                                                \
++        })
++
++#define GET_UNALIGN_CTL(task,addr)                                        \
++        ({                                                                \
++        put_user(((task)->thread.flags & PARISC_UAC_MASK)                 \
++                 >> PARISC_UAC_SHIFT, (int __user *) (addr));             \
++        })
++
+ #define INIT_THREAD { \
+ 	regs:	{	gr: { 0, }, \
+ 			fr: { 0, }, \
+diff --git a/include/asm-parisc/psw.h b/include/asm-parisc/psw.h
+--- a/include/asm-parisc/psw.h
++++ b/include/asm-parisc/psw.h
+@@ -1,4 +1,7 @@
+ #ifndef _PARISC_PSW_H
++
++#include <linux/config.h>
++
+ #define	PSW_I	0x00000001
+ #define	PSW_D	0x00000002
+ #define	PSW_P	0x00000004
+@@ -9,6 +12,16 @@
+ #define	PSW_G	0x00000040	/* PA1.x only */
+ #define PSW_O	0x00000080	/* PA2.0 only */
+ 
++/* ssm/rsm instructions number PSW_W and PSW_E differently */
++#define PSW_SM_I	PSW_I	/* Enable External Interrupts */
++#define PSW_SM_D	PSW_D
++#define PSW_SM_P	PSW_P
++#define PSW_SM_Q	PSW_Q	/* Enable Interrupt State Collection */
++#define PSW_SM_R	PSW_R	/* Enable Recover Counter Trap */
++#define PSW_SM_W	0x200	/* PA2.0 only : Enable Wide Mode */
++
++#define PSW_SM_QUIET	PSW_SM_R+PSW_SM_Q+PSW_SM_P+PSW_SM_D+PSW_SM_I
++
+ #define PSW_CB	0x0000ff00
+ 
+ #define	PSW_M	0x00010000
+@@ -30,33 +43,21 @@
+ #define	PSW_Z	0x40000000	/* PA1.x only */
+ #define	PSW_Y	0x80000000	/* PA1.x only */
+ 
+-#ifdef __LP64__
+-#define PSW_HI_CB 0x000000ff    /* PA2.0 only */
++#ifdef CONFIG_64BIT
++#  define PSW_HI_CB 0x000000ff    /* PA2.0 only */
+ #endif
+ 
+-/* PSW bits to be used with ssm/rsm */
+-#define PSW_SM_I        0x1
+-#define PSW_SM_D        0x2
+-#define PSW_SM_P        0x4
+-#define PSW_SM_Q        0x8
+-#define PSW_SM_R        0x10
+-#define PSW_SM_F        0x20
+-#define PSW_SM_G        0x40
+-#define PSW_SM_O        0x80
+-#define PSW_SM_E        0x100
+-#define PSW_SM_W        0x200
+-
+-#ifdef __LP64__
+-#  define USER_PSW      (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I)
+-#  define KERNEL_PSW    (PSW_W | PSW_C | PSW_Q | PSW_P | PSW_D)
+-#  define REAL_MODE_PSW (PSW_W | PSW_Q)
+-#  define USER_PSW_MASK (PSW_W | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB)
+-#  define USER_PSW_HI_MASK (PSW_HI_CB)
+-#else
+-#  define USER_PSW      (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I)
+-#  define KERNEL_PSW    (PSW_C | PSW_Q | PSW_P | PSW_D)
+-#  define REAL_MODE_PSW (PSW_Q)
+-#  define USER_PSW_MASK (PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB)
++#ifdef CONFIG_64BIT
++#  define USER_PSW_HI_MASK	PSW_HI_CB
++#  define WIDE_PSW		PSW_W
++#else 
++#  define WIDE_PSW		0
+ #endif
+ 
++/* Used when setting up for rfi */
++#define KERNEL_PSW    (WIDE_PSW | PSW_C | PSW_Q | PSW_P | PSW_D)
++#define REAL_MODE_PSW (WIDE_PSW | PSW_Q)
++#define USER_PSW_MASK (WIDE_PSW | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB)
++#define USER_PSW      (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I)
++
+ #endif
+diff --git a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h
+--- a/include/asm-parisc/ptrace.h
++++ b/include/asm-parisc/ptrace.h
+@@ -49,7 +49,7 @@ struct pt_regs {
+ #define user_mode(regs)			(((regs)->iaoq[0] & 3) ? 1 : 0)
+ #define user_space(regs)		(((regs)->iasq[1] != 0) ? 1 : 0)
+ #define instruction_pointer(regs)	((regs)->iaoq[0] & ~3)
+-#define profile_pc(regs) instruction_pointer(regs)
++unsigned long profile_pc(struct pt_regs *);
+ extern void show_regs(struct pt_regs *);
+ #endif
+ 
+diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h
+--- a/include/asm-parisc/semaphore.h
++++ b/include/asm-parisc/semaphore.h
+@@ -49,9 +49,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
+--- a/include/asm-parisc/spinlock.h
++++ b/include/asm-parisc/spinlock.h
+@@ -5,11 +5,6 @@
+ #include <asm/processor.h>
+ #include <asm/spinlock_types.h>
+ 
+-/* Note that PA-RISC has to use `1' to mean unlocked and `0' to mean locked
+- * since it only has load-and-zero. Moreover, at least on some PA processors,
+- * the semaphore address has to be 16-byte aligned.
+- */
+-
+ static inline int __raw_spin_is_locked(raw_spinlock_t *x)
+ {
+ 	volatile unsigned int *a = __ldcw_align(x);
+diff --git a/include/asm-parisc/spinlock_types.h b/include/asm-parisc/spinlock_types.h
+--- a/include/asm-parisc/spinlock_types.h
++++ b/include/asm-parisc/spinlock_types.h
+@@ -6,11 +6,15 @@
+ #endif
+ 
+ typedef struct {
++#ifdef CONFIG_PA20
++	volatile unsigned int slock;
++# define __RAW_SPIN_LOCK_UNLOCKED { 1 }
++#else
+ 	volatile unsigned int lock[4];
++# define __RAW_SPIN_LOCK_UNLOCKED	{ { 1, 1, 1, 1 } }
++#endif
+ } raw_spinlock_t;
+ 
+-#define __RAW_SPIN_LOCK_UNLOCKED	{ { 1, 1, 1, 1 } }
+-
+ typedef struct {
+ 	raw_spinlock_t lock;
+ 	volatile int counter;
+diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h
+--- a/include/asm-parisc/system.h
++++ b/include/asm-parisc/system.h
+@@ -138,13 +138,7 @@ static inline void set_eiem(unsigned lon
+ #define set_wmb(var, value)		do { var = value; wmb(); } while (0)
+ 
+ 
+-/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*.  */
+-#define __ldcw(a) ({ \
+-	unsigned __ret; \
+-	__asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \
+-	__ret; \
+-})
+-
++#ifndef CONFIG_PA20
+ /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data,
+    and GCC only guarantees 8-byte alignment for stack locals, we can't
+    be assured of 16-byte alignment for atomic lock data even if we
+@@ -152,37 +146,41 @@ static inline void set_eiem(unsigned lon
+    we use a struct containing an array of four ints for the atomic lock
+    type and dynamically select the 16-byte aligned int from the array
+    for the semaphore.  */
++
+ #define __PA_LDCW_ALIGNMENT 16
+ #define __ldcw_align(a) ({ \
+   unsigned long __ret = (unsigned long) &(a)->lock[0];        		\
+   __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \
+   (volatile unsigned int *) __ret;                                      \
+ })
++#define LDCW	"ldcw"
+ 
+-#ifdef CONFIG_SMP
+-# define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
+-#endif
++#else /*CONFIG_PA20*/
++/* From: "Jim Hull" <jim.hull of hp.com>
++   I've attached a summary of the change, but basically, for PA 2.0, as
++   long as the ",CO" (coherent operation) completer is specified, then the
++   16-byte alignment requirement for ldcw and ldcd is relaxed, and instead
++   they only require "natural" alignment (4-byte for ldcw, 8-byte for
++   ldcd). */
++
++#define __PA_LDCW_ALIGNMENT 4
++#define __ldcw_align(a) ((volatile unsigned int *)a)
++#define LDCW	"ldcw,co"
+ 
+-#define KERNEL_START (0x10100000 - 0x1000)
++#endif /*!CONFIG_PA20*/
+ 
+-/* This is for the serialisation of PxTLB broadcasts.  At least on the
+- * N class systems, only one PxTLB inter processor broadcast can be
+- * active at any one time on the Merced bus.  This tlb purge
+- * synchronisation is fairly lightweight and harmless so we activate
+- * it on all SMP systems not just the N class. */
+-#ifdef CONFIG_SMP
+-extern spinlock_t pa_tlb_lock;
+-
+-#define purge_tlb_start(x) spin_lock(&pa_tlb_lock)
+-#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock)
+-
+-#else
+-
+-#define purge_tlb_start(x) do { } while(0)
+-#define purge_tlb_end(x) do { } while (0)
++/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*.  */
++#define __ldcw(a) ({ \
++	unsigned __ret; \
++	__asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \
++	__ret; \
++})
+ 
++#ifdef CONFIG_SMP
++# define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
+ #endif
+ 
++#define KERNEL_START (0x10100000 - 0x1000)
+ #define arch_align_stack(x) (x)
+ 
+ #endif
+diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h
+--- a/include/asm-parisc/tlbflush.h
++++ b/include/asm-parisc/tlbflush.h
+@@ -7,6 +7,26 @@
+ #include <linux/mm.h>
+ #include <asm/mmu_context.h>
+ 
++
++/* This is for the serialisation of PxTLB broadcasts.  At least on the
++ * N class systems, only one PxTLB inter processor broadcast can be
++ * active at any one time on the Merced bus.  This tlb purge
++ * synchronisation is fairly lightweight and harmless so we activate
++ * it on all SMP systems not just the N class. */
++#ifdef CONFIG_SMP
++extern spinlock_t pa_tlb_lock;
++
++#define purge_tlb_start(x) spin_lock(&pa_tlb_lock)
++#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock)
++
++#else
++
++#define purge_tlb_start(x) do { } while(0)
++#define purge_tlb_end(x) do { } while (0)
++
++#endif
++
++
+ extern void flush_tlb_all(void);
+ 
+ /*
+@@ -64,29 +84,27 @@ static inline void flush_tlb_range(struc
+ {
+ 	unsigned long npages;
+ 
+-	
+ 	npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+-	if (npages >= 512)  /* XXX arbitrary, should be tuned */
++	if (npages >= 512)  /* 2MB of space: arbitrary, should be tuned */
+ 		flush_tlb_all();
+ 	else {
+-
++		preempt_disable();
+ 		mtsp(vma->vm_mm->context,1);
++		purge_tlb_start();
+ 		if (split_tlb) {
+-			purge_tlb_start();
+ 			while (npages--) {
+ 				pdtlb(start);
+ 				pitlb(start);
+ 				start += PAGE_SIZE;
+ 			}
+-			purge_tlb_end();
+ 		} else {
+-			purge_tlb_start();
+ 			while (npages--) {
+ 				pdtlb(start);
+ 				start += PAGE_SIZE;
+ 			}
+-			purge_tlb_end();
++		preempt_enable();
+ 		}
++		purge_tlb_end();
+ 	}
+ }
+ 
+diff --git a/include/asm-parisc/types.h b/include/asm-parisc/types.h
+--- a/include/asm-parisc/types.h
++++ b/include/asm-parisc/types.h
+@@ -33,8 +33,10 @@ typedef unsigned long long __u64;
+ 
+ #ifdef __LP64__
+ #define BITS_PER_LONG 64
++#define SHIFT_PER_LONG 6
+ #else
+ #define BITS_PER_LONG 32
++#define SHIFT_PER_LONG 5
+ #endif
+ 
+ #ifndef __ASSEMBLY__
+diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
+--- a/include/asm-parisc/unistd.h
++++ b/include/asm-parisc/unistd.h
+@@ -687,8 +687,8 @@
+ #define __NR_shmget             (__NR_Linux + 194)
+ #define __NR_shmctl             (__NR_Linux + 195)
+ 
+-#define __NR_getpmsg            (__NR_Linux + 196)      /* some people actually want streams */
+-#define __NR_putpmsg            (__NR_Linux + 197)      /* some people actually want streams */
++#define __NR_getpmsg		(__NR_Linux + 196) /* Somebody *wants* streams? */
++#define __NR_putpmsg		(__NR_Linux + 197)
+ 
+ #define __NR_lstat64            (__NR_Linux + 198)
+ #define __NR_truncate64         (__NR_Linux + 199)
+@@ -755,8 +755,14 @@
+ #define __NR_mbind		(__NR_Linux + 260)
+ #define __NR_get_mempolicy	(__NR_Linux + 261)
+ #define __NR_set_mempolicy	(__NR_Linux + 262)
++#define __NR_vserver		(__NR_Linux + 263)
++#define __NR_add_key		(__NR_Linux + 264)
++#define __NR_request_key	(__NR_Linux + 265)
++#define __NR_keyctl		(__NR_Linux + 266)
++#define __NR_ioprio_set		(__NR_Linux + 267)
++#define __NR_ioprio_get		(__NR_Linux + 268)
+ 
+-#define __NR_Linux_syscalls     263
++#define __NR_Linux_syscalls     269
+ 
+ #define HPUX_GATEWAY_ADDR       0xC0000004
+ #define LINUX_GATEWAY_ADDR      0x100
+@@ -807,10 +813,10 @@
+ #define K_INLINE_SYSCALL(name, nr, args...)	({			\
+ 	long __sys_res;							\
+ 	{								\
+-		register unsigned long __res asm("r28");		\
++		register unsigned long __res __asm__("r28");		\
+ 		K_LOAD_ARGS_##nr(args)					\
+ 		/* FIXME: HACK stw/ldw r19 around syscall */		\
+-		asm volatile(						\
++		__asm__ volatile(					\
+ 			K_STW_ASM_PIC					\
+ 			"	ble  0x100(%%sr2, %%r0)\n"		\
+ 			"	ldi %1, %%r20\n"			\
+@@ -1005,7 +1011,6 @@ int sys_clone(unsigned long clone_flags,
+ 		struct pt_regs *regs);
+ int sys_vfork(struct pt_regs *regs);
+ int sys_pipe(int *fildes);
+-long sys_ptrace(long request, pid_t pid, long addr, long data);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				const struct sigaction __user *act,
+diff --git a/include/asm-powerpc/a.out.h b/include/asm-powerpc/a.out.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/a.out.h
+@@ -0,0 +1,36 @@
++#ifndef _ASM_POWERPC_A_OUT_H
++#define _ASM_POWERPC_A_OUT_H
++
++struct exec
++{
++	unsigned long a_info;	/* Use macros N_MAGIC, etc for access */
++	unsigned a_text;	/* length of text, in bytes */
++	unsigned a_data;	/* length of data, in bytes */
++	unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
++	unsigned a_syms;	/* length of symbol table data in file, in bytes */
++	unsigned a_entry;	/* start address */
++	unsigned a_trsize;	/* length of relocation info for text, in bytes */
++	unsigned a_drsize;	/* length of relocation info for data, in bytes */
++};
++
++#define N_TRSIZE(a)	((a).a_trsize)
++#define N_DRSIZE(a)	((a).a_drsize)
++#define N_SYMSIZE(a)	((a).a_syms)
++
++#ifdef __KERNEL__
++#ifdef __powerpc64__
++
++#define STACK_TOP_USER64 TASK_SIZE_USER64
++#define STACK_TOP_USER32 TASK_SIZE_USER32
++
++#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
++		   STACK_TOP_USER32 : STACK_TOP_USER64)
++
++#else /* __powerpc64__ */
++
++#define STACK_TOP TASK_SIZE
++
++#endif /* __powerpc64__ */
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_POWERPC_A_OUT_H */
+diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/atomic.h
+@@ -0,0 +1,209 @@
++#ifndef _ASM_POWERPC_ATOMIC_H_
++#define _ASM_POWERPC_ATOMIC_H_
++
++/*
++ * PowerPC atomic operations
++ */
++
++typedef struct { volatile int counter; } atomic_t;
++
++#ifdef __KERNEL__
++#include <asm/synch.h>
++
++#define ATOMIC_INIT(i)		{ (i) }
++
++#define atomic_read(v)		((v)->counter)
++#define atomic_set(v,i)		(((v)->counter) = (i))
++
++/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx.
++ * The old ATOMIC_SYNC_FIX covered some but not all of this.
++ */
++#ifdef CONFIG_IBM405_ERR77
++#define PPC405_ERR77(ra,rb)	"dcbt " #ra "," #rb ";"
++#else
++#define PPC405_ERR77(ra,rb)
++#endif
++
++static __inline__ void atomic_add(int a, atomic_t *v)
++{
++	int t;
++
++	__asm__ __volatile__(
++"1:	lwarx	%0,0,%3		# atomic_add\n\
++	add	%0,%2,%0\n"
++	PPC405_ERR77(0,%3)
++"	stwcx.	%0,0,%3 \n\
++	bne-	1b"
++	: "=&r" (t), "=m" (v->counter)
++	: "r" (a), "r" (&v->counter), "m" (v->counter)
++	: "cc");
++}
++
++static __inline__ int atomic_add_return(int a, atomic_t *v)
++{
++	int t;
++
++	__asm__ __volatile__(
++	EIEIO_ON_SMP
++"1:	lwarx	%0,0,%2		# atomic_add_return\n\
++	add	%0,%1,%0\n"
++	PPC405_ERR77(0,%2)
++"	stwcx.	%0,0,%2 \n\
++	bne-	1b"
++	ISYNC_ON_SMP
++	: "=&r" (t)
++	: "r" (a), "r" (&v->counter)
++	: "cc", "memory");
++
++	return t;
++}
++
++#define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
++
++static __inline__ void atomic_sub(int a, atomic_t *v)
++{
++	int t;
++
++	__asm__ __volatile__(
++"1:	lwarx	%0,0,%3		# atomic_sub\n\
++	subf	%0,%2,%0\n"
++	PPC405_ERR77(0,%3)
++"	stwcx.	%0,0,%3 \n\
++	bne-	1b"
++	: "=&r" (t), "=m" (v->counter)
++	: "r" (a), "r" (&v->counter), "m" (v->counter)
++	: "cc");
++}
++
++static __inline__ int atomic_sub_return(int a, atomic_t *v)
++{
++	int t;
++
++	__asm__ __volatile__(
++	EIEIO_ON_SMP
++"1:	lwarx	%0,0,%2		# atomic_sub_return\n\
++	subf	%0,%1,%0\n"
++	PPC405_ERR77(0,%2)
++"	stwcx.	%0,0,%2 \n\
++	bne-	1b"
++	ISYNC_ON_SMP
++	: "=&r" (t)
++	: "r" (a), "r" (&v->counter)
++	: "cc", "memory");
++
++	return t;
++}
++
++static __inline__ void atomic_inc(atomic_t *v)
++{
++	int t;
++
++	__asm__ __volatile__(
++"1:	lwarx	%0,0,%2		# atomic_inc\n\
++	addic	%0,%0,1\n"
++	PPC405_ERR77(0,%2)
++"	stwcx.	%0,0,%2 \n\
++	bne-	1b"
++	: "=&r" (t), "=m" (v->counter)
++	: "r" (&v->counter), "m" (v->counter)
++	: "cc");
++}
++
++static __inline__ int atomic_inc_return(atomic_t *v)
++{
++	int t;
++
++	__asm__ __volatile__(
++	EIEIO_ON_SMP
++"1:	lwarx	%0,0,%1		# atomic_inc_return\n\
++	addic	%0,%0,1\n"
++	PPC405_ERR77(0,%1)
++"	stwcx.	%0,0,%1 \n\
++	bne-	1b"
++	ISYNC_ON_SMP
++	: "=&r" (t)
++	: "r" (&v->counter)
++	: "cc", "memory");
++
++	return t;
++}
++
++/*
++ * atomic_inc_and_test - increment and test
++ * @v: pointer of type atomic_t
++ *
++ * Atomically increments @v by 1
++ * and returns true if the result is zero, or false for all
++ * other cases.
++ */
++#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
++
++static __inline__ void atomic_dec(atomic_t *v)
++{
++	int t;
++
++	__asm__ __volatile__(
++"1:	lwarx	%0,0,%2		# atomic_dec\n\
++	addic	%0,%0,-1\n"
++	PPC405_ERR77(0,%2)\
++"	stwcx.	%0,0,%2\n\
++	bne-	1b"
++	: "=&r" (t), "=m" (v->counter)
++	: "r" (&v->counter), "m" (v->counter)
++	: "cc");
++}
++
++static __inline__ int atomic_dec_return(atomic_t *v)
++{
++	int t;
++
++	__asm__ __volatile__(
++	EIEIO_ON_SMP
++"1:	lwarx	%0,0,%1		# atomic_dec_return\n\
++	addic	%0,%0,-1\n"
++	PPC405_ERR77(0,%1)
++"	stwcx.	%0,0,%1\n\
++	bne-	1b"
++	ISYNC_ON_SMP
++	: "=&r" (t)
++	: "r" (&v->counter)
++	: "cc", "memory");
++
++	return t;
++}
++
++#define atomic_sub_and_test(a, v)	(atomic_sub_return((a), (v)) == 0)
++#define atomic_dec_and_test(v)		(atomic_dec_return((v)) == 0)
++
++/*
++ * Atomically test *v and decrement if it is greater than 0.
++ * The function returns the old value of *v minus 1.
++ */
++static __inline__ int atomic_dec_if_positive(atomic_t *v)
++{
++	int t;
++
++	__asm__ __volatile__(
++	EIEIO_ON_SMP
++"1:	lwarx	%0,0,%1		# atomic_dec_if_positive\n\
++	addic.	%0,%0,-1\n\
++	blt-	2f\n"
++	PPC405_ERR77(0,%1)
++"	stwcx.	%0,0,%1\n\
++	bne-	1b"
++	ISYNC_ON_SMP
++	"\n\
++2:"	: "=&r" (t)
++	: "r" (&v->counter)
++	: "cc", "memory");
++
++	return t;
++}
++
++#define smp_mb__before_atomic_dec()     smp_mb()
++#define smp_mb__after_atomic_dec()      smp_mb()
++#define smp_mb__before_atomic_inc()     smp_mb()
++#define smp_mb__after_atomic_inc()      smp_mb()
++
++#endif /* __KERNEL__ */
++#endif /* _ASM_POWERPC_ATOMIC_H_ */
+diff --git a/include/asm-powerpc/auxvec.h b/include/asm-powerpc/auxvec.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/auxvec.h
+@@ -0,0 +1,21 @@
++#ifndef _ASM_POWERPC_AUXVEC_H
++#define _ASM_POWERPC_AUXVEC_H
++
++/*
++ * We need to put in some extra aux table entries to tell glibc what
++ * the cache block size is, so it can use the dcbz instruction safely.
++ */
++#define AT_DCACHEBSIZE		19
++#define AT_ICACHEBSIZE		20
++#define AT_UCACHEBSIZE		21
++/* A special ignored type value for PPC, for glibc compatibility.  */
++#define AT_IGNOREPPC		22
++
++/* The vDSO location. We have to use the same value as x86 for glibc's
++ * sake :-)
++ */
++#ifdef __powerpc64__
++#define AT_SYSINFO_EHDR		33
++#endif
++
++#endif
+diff --git a/include/asm-powerpc/backlight.h b/include/asm-powerpc/backlight.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/backlight.h
+@@ -0,0 +1,31 @@
++/*
++ * Routines for handling backlight control on PowerBooks
++ *
++ * For now, implementation resides in
++ * arch/powerpc/platforms/powermac/pmac_support.c
++ *
++ */
++#ifndef __ASM_POWERPC_BACKLIGHT_H
++#define __ASM_POWERPC_BACKLIGHT_H
++#ifdef __KERNEL__
++
++/* Abstract values */
++#define BACKLIGHT_OFF	0
++#define BACKLIGHT_MIN	1
++#define BACKLIGHT_MAX	0xf
++
++struct backlight_controller {
++	int (*set_enable)(int enable, int level, void *data);
++	int (*set_level)(int level, void *data);
++};
++
++extern void register_backlight_controller(struct backlight_controller *ctrler, void *data, char *type);
++extern void unregister_backlight_controller(struct backlight_controller *ctrler, void *data);
++
++extern int set_backlight_enable(int enable);
++extern int get_backlight_enable(void);
++extern int set_backlight_level(int level);
++extern int get_backlight_level(void);
++
++#endif /* __KERNEL__ */
++#endif
+diff --git a/include/asm-powerpc/bug.h b/include/asm-powerpc/bug.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/bug.h
+@@ -0,0 +1,81 @@
++#ifndef _ASM_POWERPC_BUG_H
++#define _ASM_POWERPC_BUG_H
++
++/*
++ * Define an illegal instr to trap on the bug.
++ * We don't use 0 because that marks the end of a function
++ * in the ELF ABI.  That's "Boo Boo" in case you wonder...
++ */
++#define BUG_OPCODE .long 0x00b00b00  /* For asm */
++#define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
++
++#ifndef __ASSEMBLY__
++
++#ifdef __powerpc64__
++#define BUG_TABLE_ENTRY(label, line, file, func) \
++	".llong " #label "\n .long " #line "\n .llong " #file ", " #func "\n"
++#define TRAP_OP(ra, rb) "1: tdnei " #ra ", " #rb "\n"
++#define DATA_TYPE long long
++#else 
++#define BUG_TABLE_ENTRY(label, line, file, func) \
++	".long " #label ", " #line ", " #file ", " #func "\n"
++#define TRAP_OP(ra, rb) "1: twnei " #ra ", " #rb "\n"
++#define DATA_TYPE int
++#endif /* __powerpc64__ */
++
++struct bug_entry {
++	unsigned long	bug_addr;
++	int		line;
++	const char	*file;
++	const char	*function;
++};
++
++struct bug_entry *find_bug(unsigned long bugaddr);
++
++/*
++ * If this bit is set in the line number it means that the trap
++ * is for WARN_ON rather than BUG or BUG_ON.
++ */
++#define BUG_WARNING_TRAP	0x1000000
++
++#ifdef CONFIG_BUG
++
++#define BUG() do {							 \
++	__asm__ __volatile__(						 \
++		"1:	twi 31,0,0\n"					 \
++		".section __bug_table,\"a\"\n\t"			 \
++		BUG_TABLE_ENTRY(1b,%0,%1,%2)				 \
++		".previous"						 \
++		: : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
++} while (0)
++
++#define BUG_ON(x) do {						\
++	__asm__ __volatile__(					\
++		TRAP_OP(%0,0)					\
++		".section __bug_table,\"a\"\n\t"		\
++		BUG_TABLE_ENTRY(1b,%1,%2,%3)			\
++		".previous"					\
++		: : "r" ((DATA_TYPE)(x)), "i" (__LINE__),	\
++		    "i" (__FILE__), "i" (__FUNCTION__));	\
++} while (0)
++
++#define WARN_ON(x) do {						\
++	__asm__ __volatile__(					\
++		TRAP_OP(%0,0)					\
++		".section __bug_table,\"a\"\n\t"		\
++		BUG_TABLE_ENTRY(1b,%1,%2,%3)			\
++		".previous"					\
++		: : "r" ((DATA_TYPE)(x)),			\
++		    "i" (__LINE__ + BUG_WARNING_TRAP),		\
++		    "i" (__FILE__), "i" (__FUNCTION__));	\
++} while (0)
++
++#define HAVE_ARCH_BUG
++#define HAVE_ARCH_BUG_ON
++#define HAVE_ARCH_WARN_ON
++#endif /* CONFIG_BUG */
++#endif /* __ASSEMBLY __ */
++
++#include <asm-generic/bug.h>
++
++#endif /* _ASM_POWERPC_BUG_H */
+diff --git a/include/asm-powerpc/byteorder.h b/include/asm-powerpc/byteorder.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/byteorder.h
+@@ -0,0 +1,89 @@
++#ifndef _ASM_POWERPC_BYTEORDER_H
++#define _ASM_POWERPC_BYTEORDER_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.
++ */
++
++#include <asm/types.h>
++#include <linux/compiler.h>
++
++#ifdef __GNUC__
++#ifdef __KERNEL__
++
++static __inline__ __u16 ld_le16(const volatile __u16 *addr)
++{
++	__u16 val;
++
++	__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
++	return val;
++}
++
++static __inline__ void st_le16(volatile __u16 *addr, const __u16 val)
++{
++	__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
++}
++
++static __inline__ __u32 ld_le32(const volatile __u32 *addr)
++{
++	__u32 val;
++
++	__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
++	return val;
++}
++
++static __inline__ void st_le32(volatile __u32 *addr, const __u32 val)
++{
++	__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
++}
++
++static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
++{
++	__u16 result;
++
++	__asm__("rlwimi %0,%1,8,16,23"
++	    : "=r" (result)
++	    : "r" (value), "0" (value >> 8));
++	return result;
++}
++
++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
++{
++	__u32 result;
++
++	__asm__("rlwimi %0,%1,24,16,23\n\t"
++	    "rlwimi %0,%1,8,8,15\n\t"
++	    "rlwimi %0,%1,24,0,7"
++	    : "=r" (result)
++	    : "r" (value), "0" (value >> 24));
++	return result;
++}
++
++#define __arch__swab16(x) ___arch__swab16(x)
++#define __arch__swab32(x) ___arch__swab32(x)
++
++/* The same, but returns converted value from the location pointer by addr. */
++#define __arch__swab16p(addr) ld_le16(addr)
++#define __arch__swab32p(addr) ld_le32(addr)
++
++/* The same, but do the conversion in situ, ie. put the value back to addr. */
++#define __arch__swab16s(addr) st_le16(addr,*addr)
++#define __arch__swab32s(addr) st_le32(addr,*addr)
++
++#endif /* __KERNEL__ */
++
++#ifndef __STRICT_ANSI__
++#define __BYTEORDER_HAS_U64__
++#ifndef __powerpc64__
++#define __SWAB_64_THRU_32__
++#endif /* __powerpc64__ */
++#endif /* __STRICT_ANSI__ */
++
++#endif /* __GNUC__ */
++
++#include <linux/byteorder/big_endian.h>
++
++#endif /* _ASM_POWERPC_BYTEORDER_H */
+diff --git a/include/asm-powerpc/checksum.h b/include/asm-powerpc/checksum.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/checksum.h
+@@ -0,0 +1,132 @@
++#ifndef _ASM_POWERPC_CHECKSUM_H
++#define _ASM_POWERPC_CHECKSUM_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 is a version of ip_compute_csum() optimized for IP headers,
++ * which always checksum on 4 octet boundaries.  ihl is the number
++ * of 32-bit words and is always >= 5.
++ */
++extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
++
++/*
++ * computes the checksum of the TCP/UDP pseudo-header
++ * returns a 16-bit checksum, already complemented
++ */
++extern unsigned short csum_tcpudp_magic(unsigned long saddr,
++					unsigned long daddr,
++					unsigned short len,
++					unsigned short proto,
++					unsigned int sum);
++
++/*
++ * computes the checksum of a memory block at buff, length len,
++ * and adds in "sum" (32-bit)
++ *
++ * returns a 32-bit number suitable for feeding into itself
++ * or csum_tcpudp_magic
++ *
++ * this function must be called with even lengths, except
++ * for the last fragment, which may be odd
++ *
++ * it's best to have buff aligned on a 32-bit boundary
++ */
++extern unsigned int csum_partial(const unsigned char * buff, int len,
++				 unsigned int sum);
++
++/*
++ * Computes the checksum of a memory block at src, length len,
++ * and adds in "sum" (32-bit), while copying the block to dst.
++ * If an access exception occurs on src or dst, it stores -EFAULT
++ * to *src_err or *dst_err respectively (if that pointer is not
++ * NULL), and, for an error on src, zeroes the rest of dst.
++ *
++ * Like csum_partial, this must be called with even lengths,
++ * except for the last fragment.
++ */
++extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
++					      int len, unsigned int sum,
++					      int *src_err, int *dst_err);
++/*
++ * the same as csum_partial, but copies from src to dst while it
++ * checksums.
++ */
++unsigned int csum_partial_copy_nocheck(const char *src, 
++				       char *dst, 
++				       int len, 
++				       unsigned int sum);
++
++#define csum_partial_copy_from_user(src, dst, len, sum, errp)   \
++        csum_partial_copy_generic((src), (dst), (len), (sum), (errp), NULL)
++
++#define csum_partial_copy_nocheck(src, dst, len, sum)   \
++        csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
++
++
++/*
++ * turns a 32-bit partial checksum (e.g. from csum_partial) into a
++ * 1's complement 16-bit checksum.
++ */
++static inline unsigned int csum_fold(unsigned int sum)
++{
++	unsigned int tmp;
++
++	/* swap the two 16-bit halves of sum */
++	__asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum));
++	/* if there is a carry from adding the two 16-bit halves,
++	   it will carry from the lower half into the upper half,
++	   giving us the correct sum in the upper half. */
++	sum = ~(sum + tmp) >> 16;
++	return sum;
++}
++
++/*
++ * this routine is used for miscellaneous IP-like checksums, mainly
++ * in icmp.c
++ */
++static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
++{
++	return csum_fold(csum_partial(buff, len, 0));
++}
++
++#ifdef __powerpc64__
++static inline u32 csum_tcpudp_nofold(u32 saddr,
++                                     u32 daddr,
++                                     unsigned short len,
++                                     unsigned short proto,
++                                     unsigned int sum)
++{
++	unsigned long s = sum;
++
++	s += saddr;
++	s += daddr;
++	s += (proto << 16) + len;
++	s += (s >> 32);
++	return (u32) s;
++}
++#else
++static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
++						   unsigned long daddr,
++						   unsigned short len,
++						   unsigned short proto,
++						   unsigned int sum)
++{
++    __asm__("\n\
++	addc %0,%0,%1 \n\
++	adde %0,%0,%2 \n\
++	adde %0,%0,%3 \n\
++	addze %0,%0 \n\
++	"
++	: "=r" (sum)
++	: "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum));
++    return sum;
++}
++
++#endif
++#endif
+diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/cputable.h
+@@ -0,0 +1,427 @@
++#ifndef __ASM_POWERPC_CPUTABLE_H
++#define __ASM_POWERPC_CPUTABLE_H
++
++#include <linux/config.h>
++#include <asm/ppc_asm.h> /* for ASM_CONST */
++
++#define PPC_FEATURE_32			0x80000000
++#define PPC_FEATURE_64			0x40000000
++#define PPC_FEATURE_601_INSTR		0x20000000
++#define PPC_FEATURE_HAS_ALTIVEC		0x10000000
++#define PPC_FEATURE_HAS_FPU		0x08000000
++#define PPC_FEATURE_HAS_MMU		0x04000000
++#define PPC_FEATURE_HAS_4xxMAC		0x02000000
++#define PPC_FEATURE_UNIFIED_CACHE	0x01000000
++#define PPC_FEATURE_HAS_SPE		0x00800000
++#define PPC_FEATURE_HAS_EFP_SINGLE	0x00400000
++#define PPC_FEATURE_HAS_EFP_DOUBLE	0x00200000
++#define PPC_FEATURE_NO_TB		0x00100000
++
++#ifdef __KERNEL__
++#ifndef __ASSEMBLY__
++
++/* This structure can grow, it's real size is used by head.S code
++ * via the mkdefs mechanism.
++ */
++struct cpu_spec;
++struct op_powerpc_model;
++
++typedef	void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
++
++struct cpu_spec {
++	/* CPU is matched via (PVR & pvr_mask) == pvr_value */
++	unsigned int	pvr_mask;
++	unsigned int	pvr_value;
++
++	char		*cpu_name;
++	unsigned long	cpu_features;		/* Kernel features */
++	unsigned int	cpu_user_features;	/* Userland features */
++
++	/* cache line sizes */
++	unsigned int	icache_bsize;
++	unsigned int	dcache_bsize;
++
++	/* number of performance monitor counters */
++	unsigned int	num_pmcs;
++
++	/* this is called to initialize various CPU bits like L1 cache,
++	 * BHT, SPD, etc... from head.S before branching to identify_machine
++	 */
++	cpu_setup_t	cpu_setup;
++
++	/* Used by oprofile userspace to select the right counters */
++	char		*oprofile_cpu_type;
++
++	/* Processor specific oprofile operations */
++	struct op_powerpc_model *oprofile_model;
++};
++
++extern struct cpu_spec		*cur_cpu_spec;
++
++extern void identify_cpu(unsigned long offset, unsigned long cpu);
++extern void do_cpu_ftr_fixups(unsigned long offset);
++
++#endif /* __ASSEMBLY__ */
++
++/* CPU kernel features */
++
++/* Retain the 32b definitions all use bottom half of word */
++#define CPU_FTR_SPLIT_ID_CACHE		ASM_CONST(0x0000000000000001)
++#define CPU_FTR_L2CR			ASM_CONST(0x0000000000000002)
++#define CPU_FTR_SPEC7450		ASM_CONST(0x0000000000000004)
++#define CPU_FTR_ALTIVEC			ASM_CONST(0x0000000000000008)
++#define CPU_FTR_TAU			ASM_CONST(0x0000000000000010)
++#define CPU_FTR_CAN_DOZE		ASM_CONST(0x0000000000000020)
++#define CPU_FTR_USE_TB			ASM_CONST(0x0000000000000040)
++#define CPU_FTR_604_PERF_MON		ASM_CONST(0x0000000000000080)
++#define CPU_FTR_601			ASM_CONST(0x0000000000000100)
++#define CPU_FTR_HPTE_TABLE		ASM_CONST(0x0000000000000200)
++#define CPU_FTR_CAN_NAP			ASM_CONST(0x0000000000000400)
++#define CPU_FTR_L3CR			ASM_CONST(0x0000000000000800)
++#define CPU_FTR_L3_DISABLE_NAP		ASM_CONST(0x0000000000001000)
++#define CPU_FTR_NAP_DISABLE_L2_PR	ASM_CONST(0x0000000000002000)
++#define CPU_FTR_DUAL_PLL_750FX		ASM_CONST(0x0000000000004000)
++#define CPU_FTR_NO_DPM			ASM_CONST(0x0000000000008000)
++#define CPU_FTR_HAS_HIGH_BATS		ASM_CONST(0x0000000000010000)
++#define CPU_FTR_NEED_COHERENT		ASM_CONST(0x0000000000020000)
++#define CPU_FTR_NO_BTIC			ASM_CONST(0x0000000000040000)
++#define CPU_FTR_BIG_PHYS		ASM_CONST(0x0000000000080000)
++
++#ifdef __powerpc64__
++/* Add the 64b processor unique features in the top half of the word */
++#define CPU_FTR_SLB           		ASM_CONST(0x0000000100000000)
++#define CPU_FTR_16M_PAGE      		ASM_CONST(0x0000000200000000)
++#define CPU_FTR_TLBIEL         		ASM_CONST(0x0000000400000000)
++#define CPU_FTR_NOEXECUTE     		ASM_CONST(0x0000000800000000)
++#define CPU_FTR_NODSISRALIGN  		ASM_CONST(0x0000001000000000)
++#define CPU_FTR_IABR  			ASM_CONST(0x0000002000000000)
++#define CPU_FTR_MMCRA  			ASM_CONST(0x0000004000000000)
++#define CPU_FTR_CTRL			ASM_CONST(0x0000008000000000)
++#define CPU_FTR_SMT  			ASM_CONST(0x0000010000000000)
++#define CPU_FTR_COHERENT_ICACHE  	ASM_CONST(0x0000020000000000)
++#define CPU_FTR_LOCKLESS_TLBIE		ASM_CONST(0x0000040000000000)
++#define CPU_FTR_MMCRA_SIHV		ASM_CONST(0x0000080000000000)
++#else
++/* ensure on 32b processors the flags are available for compiling but
++ * don't do anything */
++#define CPU_FTR_SLB           		ASM_CONST(0x0)
++#define CPU_FTR_16M_PAGE      		ASM_CONST(0x0)
++#define CPU_FTR_TLBIEL         		ASM_CONST(0x0)
++#define CPU_FTR_NOEXECUTE     		ASM_CONST(0x0)
++#define CPU_FTR_NODSISRALIGN  		ASM_CONST(0x0)
++#define CPU_FTR_IABR  			ASM_CONST(0x0)
++#define CPU_FTR_MMCRA  			ASM_CONST(0x0)
++#define CPU_FTR_CTRL			ASM_CONST(0x0)
++#define CPU_FTR_SMT  			ASM_CONST(0x0)
++#define CPU_FTR_COHERENT_ICACHE  	ASM_CONST(0x0)
++#define CPU_FTR_LOCKLESS_TLBIE		ASM_CONST(0x0)
++#define CPU_FTR_MMCRA_SIHV		ASM_CONST(0x0)
++#endif
++
++#ifndef __ASSEMBLY__
++
++#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
++					CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
++					CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL)
++
++/* iSeries doesn't support large pages */
++#ifdef CONFIG_PPC_ISERIES
++#define CPU_FTR_PPCAS_ARCH_V2	(CPU_FTR_PPCAS_ARCH_V2_BASE)
++#else
++#define CPU_FTR_PPCAS_ARCH_V2	(CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE)
++#endif /* CONFIG_PPC_ISERIES */
++
++/* We only set the altivec features if the kernel was compiled with altivec
++ * support
++ */
++#ifdef CONFIG_ALTIVEC
++#define CPU_FTR_ALTIVEC_COMP	CPU_FTR_ALTIVEC
++#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
++#else
++#define CPU_FTR_ALTIVEC_COMP	0
++#define PPC_FEATURE_HAS_ALTIVEC_COMP    0
++#endif
++
++/* We need to mark all pages as being coherent if we're SMP or we
++ * have a 74[45]x and an MPC107 host bridge.
++ */
++#if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE)
++#define CPU_FTR_COMMON                  CPU_FTR_NEED_COHERENT
++#else
++#define CPU_FTR_COMMON                  0
++#endif
++
++/* The powersave features NAP & DOZE seems to confuse BDI when
++   debugging. So if a BDI is used, disable theses
++ */
++#ifndef CONFIG_BDI_SWITCH
++#define CPU_FTR_MAYBE_CAN_DOZE	CPU_FTR_CAN_DOZE
++#define CPU_FTR_MAYBE_CAN_NAP	CPU_FTR_CAN_NAP
++#else
++#define CPU_FTR_MAYBE_CAN_DOZE	0
++#define CPU_FTR_MAYBE_CAN_NAP	0
++#endif
++
++#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
++		     !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
++		     !defined(CONFIG_BOOKE))
++
++enum {
++	CPU_FTRS_PPC601 = CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE,
++	CPU_FTRS_603 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
++	    CPU_FTR_MAYBE_CAN_NAP,
++	CPU_FTRS_604 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
++	CPU_FTRS_740_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
++	CPU_FTRS_740 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
++	    CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
++	CPU_FTRS_750 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
++	    CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
++	CPU_FTRS_750FX1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
++	    CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
++	    CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM,
++	CPU_FTRS_750FX2 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
++	    CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
++	    CPU_FTR_NO_DPM,
++	CPU_FTRS_750FX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
++	    CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
++	    CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
++	CPU_FTRS_750GX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
++	    CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
++	    CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
++	CPU_FTRS_7400_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
++	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
++	    CPU_FTR_MAYBE_CAN_NAP,
++	CPU_FTRS_7400 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
++	    CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
++	    CPU_FTR_MAYBE_CAN_NAP,
++	CPU_FTRS_7450_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
++	    CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
++	    CPU_FTR_NEED_COHERENT,
++	CPU_FTRS_7450_21 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB |
++	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
++	    CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
++	    CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
++	    CPU_FTR_NEED_COHERENT,
++	CPU_FTRS_7450_23 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB |
++	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
++	    CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
++	    CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT,
++	CPU_FTRS_7455_1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB |
++	    CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS |
++	    CPU_FTR_NEED_COHERENT,
++	CPU_FTRS_7455_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB |
++	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
++	    CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
++	    CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
++	    CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS,
++	CPU_FTRS_7455 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB |
++	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
++	    CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
++	    CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
++	    CPU_FTR_NEED_COHERENT,
++	CPU_FTRS_7447_10 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB |
++	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
++	    CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
++	    CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
++	    CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
++	CPU_FTRS_7447 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB |
++	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
++	    CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
++	    CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
++	    CPU_FTR_NEED_COHERENT,
++	CPU_FTRS_7447A = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB |
++	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
++	    CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
++	    CPU_FTR_NEED_COHERENT,
++	CPU_FTRS_82XX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB,
++	CPU_FTRS_G2_LE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
++	    CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
++	CPU_FTRS_E300 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
++	    CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
++	CPU_FTRS_CLASSIC32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
++	CPU_FTRS_POWER3_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
++	CPU_FTRS_POWER4_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
++	CPU_FTRS_970_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
++	    CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_ALTIVEC_COMP |
++	    CPU_FTR_MAYBE_CAN_NAP,
++	CPU_FTRS_8XX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
++	CPU_FTRS_40X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
++	CPU_FTRS_44X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
++	CPU_FTRS_E200 = CPU_FTR_USE_TB,
++	CPU_FTRS_E500 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
++	CPU_FTRS_E500_2 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
++	    CPU_FTR_BIG_PHYS,
++	CPU_FTRS_GENERIC_32 = CPU_FTR_COMMON,
++#ifdef __powerpc64__
++	CPU_FTRS_POWER3 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
++	CPU_FTRS_RS64 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
++	    CPU_FTR_MMCRA | CPU_FTR_CTRL,
++	CPU_FTRS_POWER4 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA,
++	CPU_FTRS_PPC970 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
++	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
++	CPU_FTRS_POWER5 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
++	    CPU_FTR_MMCRA | CPU_FTR_SMT |
++	    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
++	    CPU_FTR_MMCRA_SIHV,
++	CPU_FTRS_CELL = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
++	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT,
++	CPU_FTRS_COMPATIBLE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
++	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2,
++#endif
++
++	CPU_FTRS_POSSIBLE =
++#if CLASSIC_PPC
++	    CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU |
++	    CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 |
++	    CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX |
++	    CPU_FTRS_7400_NOTAU | CPU_FTRS_7400 | CPU_FTRS_7450_20 |
++	    CPU_FTRS_7450_21 | CPU_FTRS_7450_23 | CPU_FTRS_7455_1 |
++	    CPU_FTRS_7455_20 | CPU_FTRS_7455 | CPU_FTRS_7447_10 |
++	    CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_82XX |
++	    CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_CLASSIC32 |
++#else
++	    CPU_FTRS_GENERIC_32 |
++#endif
++#ifdef CONFIG_PPC64BRIDGE
++	    CPU_FTRS_POWER3_32 |
++#endif
++#ifdef CONFIG_POWER4
++	    CPU_FTRS_POWER4_32 | CPU_FTRS_970_32 |
++#endif
++#ifdef CONFIG_8xx
++	    CPU_FTRS_8XX |
++#endif
++#ifdef CONFIG_40x
++	    CPU_FTRS_40X |
++#endif
++#ifdef CONFIG_44x
++	    CPU_FTRS_44X |
++#endif
++#ifdef CONFIG_E200
++	    CPU_FTRS_E200 |
++#endif
++#ifdef CONFIG_E500
++	    CPU_FTRS_E500 | CPU_FTRS_E500_2 |
++#endif
++#ifdef __powerpc64__
++	    CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |
++	    CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL |
++#endif
++	    0,
++
++	CPU_FTRS_ALWAYS =
++#if CLASSIC_PPC
++	    CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
++	    CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 &
++	    CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX &
++	    CPU_FTRS_7400_NOTAU & CPU_FTRS_7400 & CPU_FTRS_7450_20 &
++	    CPU_FTRS_7450_21 & CPU_FTRS_7450_23 & CPU_FTRS_7455_1 &
++	    CPU_FTRS_7455_20 & CPU_FTRS_7455 & CPU_FTRS_7447_10 &
++	    CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_82XX &
++	    CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_CLASSIC32 &
++#else
++	    CPU_FTRS_GENERIC_32 &
++#endif
++#ifdef CONFIG_PPC64BRIDGE
++	    CPU_FTRS_POWER3_32 &
++#endif
++#ifdef CONFIG_POWER4
++	    CPU_FTRS_POWER4_32 & CPU_FTRS_970_32 &
++#endif
++#ifdef CONFIG_8xx
++	    CPU_FTRS_8XX &
++#endif
++#ifdef CONFIG_40x
++	    CPU_FTRS_40X &
++#endif
++#ifdef CONFIG_44x
++	    CPU_FTRS_44X &
++#endif
++#ifdef CONFIG_E200
++	    CPU_FTRS_E200 &
++#endif
++#ifdef CONFIG_E500
++	    CPU_FTRS_E500 & CPU_FTRS_E500_2 &
++#endif
++#ifdef __powerpc64__
++	    CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 &
++	    CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL &
++#endif
++	    CPU_FTRS_POSSIBLE,
++};
++
++static inline int cpu_has_feature(unsigned long feature)
++{
++	return (CPU_FTRS_ALWAYS & feature) ||
++	       (CPU_FTRS_POSSIBLE
++		& cur_cpu_spec->cpu_features
++		& feature);
++}
++
++#endif /* !__ASSEMBLY__ */
++
++#ifdef __ASSEMBLY__
++
++#define BEGIN_FTR_SECTION		98:
++
++#ifndef __powerpc64__
++#define END_FTR_SECTION(msk, val)		\
++99:						\
++	.section __ftr_fixup,"a";		\
++	.align 2;				\
++	.long msk;				\
++	.long val;				\
++	.long 98b;				\
++	.long 99b;				\
++	.previous
++#else /* __powerpc64__ */
++#define END_FTR_SECTION(msk, val)		\
++99:						\
++	.section __ftr_fixup,"a";		\
++	.align 3;				\
++	.llong msk;				\
++	.llong val;				\
++	.llong 98b;				\
++	.llong 99b;	 			\
++	.previous
++#endif /* __powerpc64__ */
++
++#define END_FTR_SECTION_IFSET(msk)	END_FTR_SECTION((msk), (msk))
++#define END_FTR_SECTION_IFCLR(msk)	END_FTR_SECTION((msk), 0)
++#endif /* __ASSEMBLY__ */
++
++#endif /* __KERNEL__ */
++#endif /* __ASM_POWERPC_CPUTABLE_H */
+diff --git a/include/asm-powerpc/dbdma.h b/include/asm-powerpc/dbdma.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/dbdma.h
+@@ -0,0 +1,102 @@
++/*
++ * Definitions for using the Apple Descriptor-Based DMA controller
++ * in Power Macintosh computers.
++ *
++ * Copyright (C) 1996 Paul Mackerras.
++ */
++
++#ifdef __KERNEL__
++#ifndef _ASM_DBDMA_H_
++#define _ASM_DBDMA_H_
++/*
++ * DBDMA control/status registers.  All little-endian.
++ */
++struct dbdma_regs {
++    unsigned int control;	/* lets you change bits in status */
++    unsigned int status;	/* DMA and device status bits (see below) */
++    unsigned int cmdptr_hi;	/* upper 32 bits of command address */
++    unsigned int cmdptr;	/* (lower 32 bits of) command address (phys) */
++    unsigned int intr_sel;	/* select interrupt condition bit */
++    unsigned int br_sel;	/* select branch condition bit */
++    unsigned int wait_sel;	/* select wait condition bit */
++    unsigned int xfer_mode;
++    unsigned int data2ptr_hi;
++    unsigned int data2ptr;
++    unsigned int res1;
++    unsigned int address_hi;
++    unsigned int br_addr_hi;
++    unsigned int res2[3];
++};
++
++/* Bits in control and status registers */
++#define RUN	0x8000
++#define PAUSE	0x4000
++#define FLUSH	0x2000
++#define WAKE	0x1000
++#define DEAD	0x0800
++#define ACTIVE	0x0400
++#define BT	0x0100
++#define DEVSTAT	0x00ff
++
++/*
++ * DBDMA command structure.  These fields are all little-endian!
++ */
++struct dbdma_cmd {
++    unsigned short req_count;	/* requested byte transfer count */
++    unsigned short command;	/* command word (has bit-fields) */
++    unsigned int   phy_addr;	/* physical data address */
++    unsigned int   cmd_dep;	/* command-dependent field */
++    unsigned short res_count;	/* residual count after completion */
++    unsigned short xfer_status;	/* transfer status */
++};
++
++/* DBDMA command values in command field */
++#define OUTPUT_MORE	0	/* transfer memory data to stream */
++#define OUTPUT_LAST	0x1000	/* ditto followed by end marker */
++#define INPUT_MORE	0x2000	/* transfer stream data to memory */
++#define INPUT_LAST	0x3000	/* ditto, expect end marker */
++#define STORE_WORD	0x4000	/* write word (4 bytes) to device reg */
++#define LOAD_WORD	0x5000	/* read word (4 bytes) from device reg */
++#define DBDMA_NOP	0x6000	/* do nothing */
++#define DBDMA_STOP	0x7000	/* suspend processing */
++
++/* Key values in command field */
++#define KEY_STREAM0	0	/* usual data stream */
++#define KEY_STREAM1	0x100	/* control/status stream */
++#define KEY_STREAM2	0x200	/* device-dependent stream */
++#define KEY_STREAM3	0x300	/* device-dependent stream */
++#define KEY_REGS	0x500	/* device register space */
++#define KEY_SYSTEM	0x600	/* system memory-mapped space */
++#define KEY_DEVICE	0x700	/* device memory-mapped space */
++
++/* Interrupt control values in command field */
++#define INTR_NEVER	0	/* don't interrupt */
++#define INTR_IFSET	0x10	/* intr if condition bit is 1 */
++#define INTR_IFCLR	0x20	/* intr if condition bit is 0 */
++#define INTR_ALWAYS	0x30	/* always interrupt */
++
++/* Branch control values in command field */
++#define BR_NEVER	0	/* don't branch */
++#define BR_IFSET	0x4	/* branch if condition bit is 1 */
++#define BR_IFCLR	0x8	/* branch if condition bit is 0 */
++#define BR_ALWAYS	0xc	/* always branch */
++
++/* Wait control values in command field */
++#define WAIT_NEVER	0	/* don't wait */
++#define WAIT_IFSET	1	/* wait if condition bit is 1 */
++#define WAIT_IFCLR	2	/* wait if condition bit is 0 */
++#define WAIT_ALWAYS	3	/* always wait */
++
++/* Align an address for a DBDMA command structure */
++#define DBDMA_ALIGN(x)	(((unsigned long)(x) + sizeof(struct dbdma_cmd) - 1) \
++			 & -sizeof(struct dbdma_cmd))
++
++/* Useful macros */
++#define DBDMA_DO_STOP(regs) do {				\
++	out_le32(&((regs)->control), (RUN|FLUSH)<<16);		\
++	while(in_le32(&((regs)->status)) & (ACTIVE|FLUSH))	\
++		;						\
++} while(0)
++
++#endif /* _ASM_DBDMA_H_ */
++#endif /* __KERNEL__ */
+diff --git a/include/asm-powerpc/dma.h b/include/asm-powerpc/dma.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/dma.h
+@@ -0,0 +1,390 @@
++#ifndef _ASM_POWERPC_DMA_H
++#define _ASM_POWERPC_DMA_H
++
++/*
++ * Defines for using and allocating dma channels.
++ * Written by Hennus Bergman, 1992.
++ * High DMA channel support & info by Hannu Savolainen
++ * and John Boyd, Nov. 1992.
++ * Changes for ppc sound by Christoph Nadig
++ */
++
++/*
++ * Note: Adapted for PowerPC by Gary Thomas
++ * Modified by Cort Dougan <cort at cs.nmt.edu>
++ *
++ * None of this really applies for Power Macintoshes.  There is
++ * basically just enough here to get kernel/dma.c to compile.
++ *
++ * There may be some comments or restrictions made here which are
++ * not valid for the PReP platform.  Take what you read
++ * with a grain of salt.
++ */
++
++#include <linux/config.h>
++#include <asm/io.h>
++#include <linux/spinlock.h>
++#include <asm/system.h>
++
++#ifndef MAX_DMA_CHANNELS
++#define MAX_DMA_CHANNELS	8
++#endif
++
++/* The maximum address that we can perform a DMA transfer to on this platform */
++/* Doesn't really apply... */
++#define MAX_DMA_ADDRESS		(~0UL)
++
++#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)
++
++#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
++#define dma_outb	outb_p
++#else
++#define dma_outb	outb
++#endif
++
++#define dma_inb		inb
++
++/*
++ * NOTES about DMA transfers:
++ *
++ *  controller 1: channels 0-3, byte operations, ports 00-1F
++ *  controller 2: channels 4-7, word operations, ports C0-DF
++ *
++ *  - ALL registers are 8 bits only, regardless of transfer size
++ *  - channel 4 is not used - cascades 1 into 2.
++ *  - channels 0-3 are byte - addresses/counts are for physical bytes
++ *  - channels 5-7 are word - addresses/counts are for physical words
++ *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
++ *  - transfer count loaded to registers is 1 less than actual count
++ *  - controller 2 offsets are all even (2x offsets for controller 1)
++ *  - page registers for 5-7 don't use data bit 0, represent 128K pages
++ *  - page registers for 0-3 use bit 0, represent 64K pages
++ *
++ * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory.
++ * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing.
++ * Note that addresses loaded into registers must be _physical_ addresses,
++ * not logical addresses (which may differ if paging is active).
++ *
++ *  Address mapping for channels 0-3:
++ *
++ *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
++ *    |  ...  |   |  ... |   |  ... |
++ *    |  ...  |   |  ... |   |  ... |
++ *    |  ...  |   |  ... |   |  ... |
++ *   P7  ...  P0  A7 ... A0  A7 ... A0
++ * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
++ *
++ *  Address mapping for channels 5-7:
++ *
++ *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
++ *    |  ...  |   \   \   ... \  \  \  ... \  \
++ *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
++ *    |  ...  |     \   \   ... \  \  \  ... \
++ *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0
++ * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
++ *
++ * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
++ * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
++ * the hardware level, so odd-byte transfers aren't possible).
++ *
++ * Transfer count (_not # bytes_) is limited to 64K, represented as actual
++ * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
++ * and up to 128K bytes may be transferred on channels 5-7 in one operation.
++ *
++ */
++
++/* see prep_setup_arch() for detailed informations */
++#if defined(CONFIG_SOUND_CS4232) && defined(CONFIG_PPC_PREP)
++extern long ppc_cs4232_dma, ppc_cs4232_dma2;
++#define SND_DMA1 ppc_cs4232_dma
++#define SND_DMA2 ppc_cs4232_dma2
++#else
++#define SND_DMA1 -1
++#define SND_DMA2 -1
++#endif
++
++/* 8237 DMA controllers */
++#define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
++#define IO_DMA2_BASE	0xC0	/* 16 bit master DMA, ch 4(=slave input)..7 */
++
++/* DMA controller registers */
++#define DMA1_CMD_REG		0x08	/* command register (w) */
++#define DMA1_STAT_REG		0x08	/* status register (r) */
++#define DMA1_REQ_REG		0x09	/* request register (w) */
++#define DMA1_MASK_REG		0x0A	/* single-channel mask (w) */
++#define DMA1_MODE_REG		0x0B	/* mode register (w) */
++#define DMA1_CLEAR_FF_REG	0x0C	/* clear pointer flip-flop (w) */
++#define DMA1_TEMP_REG		0x0D	/* Temporary Register (r) */
++#define DMA1_RESET_REG		0x0D	/* Master Clear (w) */
++#define DMA1_CLR_MASK_REG	0x0E	/* Clear Mask */
++#define DMA1_MASK_ALL_REG	0x0F	/* all-channels mask (w) */
++
++#define DMA2_CMD_REG		0xD0	/* command register (w) */
++#define DMA2_STAT_REG		0xD0	/* status register (r) */
++#define DMA2_REQ_REG		0xD2	/* request register (w) */
++#define DMA2_MASK_REG		0xD4	/* single-channel mask (w) */
++#define DMA2_MODE_REG		0xD6	/* mode register (w) */
++#define DMA2_CLEAR_FF_REG	0xD8	/* clear pointer flip-flop (w) */
++#define DMA2_TEMP_REG		0xDA	/* Temporary Register (r) */
++#define DMA2_RESET_REG		0xDA	/* Master Clear (w) */
++#define DMA2_CLR_MASK_REG	0xDC	/* Clear Mask */
++#define DMA2_MASK_ALL_REG	0xDE	/* all-channels mask (w) */
++
++#define DMA_ADDR_0		0x00	/* DMA address registers */
++#define DMA_ADDR_1		0x02
++#define DMA_ADDR_2		0x04
++#define DMA_ADDR_3		0x06
++#define DMA_ADDR_4		0xC0
++#define DMA_ADDR_5		0xC4
++#define DMA_ADDR_6		0xC8
++#define DMA_ADDR_7		0xCC
++
++#define DMA_CNT_0		0x01	/* DMA count registers */
++#define DMA_CNT_1		0x03
++#define DMA_CNT_2		0x05
++#define DMA_CNT_3		0x07
++#define DMA_CNT_4		0xC2
++#define DMA_CNT_5		0xC6
++#define DMA_CNT_6		0xCA
++#define DMA_CNT_7		0xCE
++
++#define DMA_LO_PAGE_0		0x87	/* DMA page registers */
++#define DMA_LO_PAGE_1		0x83
++#define DMA_LO_PAGE_2		0x81
++#define DMA_LO_PAGE_3		0x82
++#define DMA_LO_PAGE_5		0x8B
++#define DMA_LO_PAGE_6		0x89
++#define DMA_LO_PAGE_7		0x8A
++
++#define DMA_HI_PAGE_0		0x487	/* DMA page registers */
++#define DMA_HI_PAGE_1		0x483
++#define DMA_HI_PAGE_2		0x481
++#define DMA_HI_PAGE_3		0x482
++#define DMA_HI_PAGE_5		0x48B
++#define DMA_HI_PAGE_6		0x489
++#define DMA_HI_PAGE_7		0x48A
++
++#define DMA1_EXT_REG		0x40B
++#define DMA2_EXT_REG		0x4D6
++
++#ifndef __powerpc64__
++    /* in arch/ppc/kernel/setup.c -- Cort */
++    extern unsigned int DMA_MODE_WRITE;
++    extern unsigned int DMA_MODE_READ;
++    extern unsigned long ISA_DMA_THRESHOLD;
++#else
++    #define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
++    #define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
++#endif
++
++#define DMA_MODE_CASCADE	0xC0	/* pass thru DREQ->HRQ, DACK<-HLDA only */
++
++#define DMA_AUTOINIT		0x10
++
++extern spinlock_t dma_spin_lock;
++
++static __inline__ unsigned long claim_dma_lock(void)
++{
++	unsigned long flags;
++	spin_lock_irqsave(&dma_spin_lock, flags);
++	return flags;
++}
++
++static __inline__ void release_dma_lock(unsigned long flags)
++{
++	spin_unlock_irqrestore(&dma_spin_lock, flags);
++}
++
++/* enable/disable a specific DMA channel */
++static __inline__ void enable_dma(unsigned int dmanr)
++{
++	unsigned char ucDmaCmd = 0x00;
++
++	if (dmanr != 4) {
++		dma_outb(0, DMA2_MASK_REG);	/* This may not be enabled */
++		dma_outb(ucDmaCmd, DMA2_CMD_REG);	/* Enable group */
++	}
++	if (dmanr <= 3) {
++		dma_outb(dmanr, DMA1_MASK_REG);
++		dma_outb(ucDmaCmd, DMA1_CMD_REG);	/* Enable group */
++	} else {
++		dma_outb(dmanr & 3, DMA2_MASK_REG);
++	}
++}
++
++static __inline__ void disable_dma(unsigned int dmanr)
++{
++	if (dmanr <= 3)
++		dma_outb(dmanr | 4, DMA1_MASK_REG);
++	else
++		dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
++}
++
++/* Clear the 'DMA Pointer Flip Flop'.
++ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
++ * Use this once to initialize the FF to a known state.
++ * After that, keep track of it. :-)
++ * --- In order to do that, the DMA routines below should ---
++ * --- only be used while interrupts are disabled! ---
++ */
++static __inline__ void clear_dma_ff(unsigned int dmanr)
++{
++	if (dmanr <= 3)
++		dma_outb(0, DMA1_CLEAR_FF_REG);
++	else
++		dma_outb(0, DMA2_CLEAR_FF_REG);
++}
++
++/* set mode (above) for a specific DMA channel */
++static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
++{
++	if (dmanr <= 3)
++		dma_outb(mode | dmanr, DMA1_MODE_REG);
++	else
++		dma_outb(mode | (dmanr & 3), DMA2_MODE_REG);
++}
++
++/* Set only the page register bits of the transfer address.
++ * This is used for successive transfers when we know the contents of
++ * the lower 16 bits of the DMA current address register, but a 64k boundary
++ * may have been crossed.
++ */
++static __inline__ void set_dma_page(unsigned int dmanr, int pagenr)
++{
++	switch (dmanr) {
++	case 0:
++		dma_outb(pagenr, DMA_LO_PAGE_0);
++		dma_outb(pagenr >> 8, DMA_HI_PAGE_0);
++		break;
++	case 1:
++		dma_outb(pagenr, DMA_LO_PAGE_1);
++		dma_outb(pagenr >> 8, DMA_HI_PAGE_1);
++		break;
++	case 2:
++		dma_outb(pagenr, DMA_LO_PAGE_2);
++		dma_outb(pagenr >> 8, DMA_HI_PAGE_2);
++		break;
++	case 3:
++		dma_outb(pagenr, DMA_LO_PAGE_3);
++		dma_outb(pagenr >> 8, DMA_HI_PAGE_3);
++		break;
++	case 5:
++		if (SND_DMA1 == 5 || SND_DMA2 == 5)
++			dma_outb(pagenr, DMA_LO_PAGE_5);
++		else
++			dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5);
++		dma_outb(pagenr >> 8, DMA_HI_PAGE_5);
++		break;
++	case 6:
++		if (SND_DMA1 == 6 || SND_DMA2 == 6)
++			dma_outb(pagenr, DMA_LO_PAGE_6);
++		else
++			dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6);
++		dma_outb(pagenr >> 8, DMA_HI_PAGE_6);
++		break;
++	case 7:
++		if (SND_DMA1 == 7 || SND_DMA2 == 7)
++			dma_outb(pagenr, DMA_LO_PAGE_7);
++		else
++			dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7);
++		dma_outb(pagenr >> 8, DMA_HI_PAGE_7);
++		break;
++	}
++}
++
++/* Set transfer address & page bits for specific DMA channel.
++ * Assumes dma flipflop is clear.
++ */
++static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys)
++{
++	if (dmanr <= 3) {
++		dma_outb(phys & 0xff,
++			 ((dmanr & 3) << 1) + IO_DMA1_BASE);
++		dma_outb((phys >> 8) & 0xff,
++			 ((dmanr & 3) << 1) + IO_DMA1_BASE);
++	} else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) {
++		dma_outb(phys & 0xff,
++			 ((dmanr & 3) << 2) + IO_DMA2_BASE);
++		dma_outb((phys >> 8) & 0xff,
++			 ((dmanr & 3) << 2) + IO_DMA2_BASE);
++		dma_outb((dmanr & 3), DMA2_EXT_REG);
++	} else {
++		dma_outb((phys >> 1) & 0xff,
++			 ((dmanr & 3) << 2) + IO_DMA2_BASE);
++		dma_outb((phys >> 9) & 0xff,
++			 ((dmanr & 3) << 2) + IO_DMA2_BASE);
++	}
++	set_dma_page(dmanr, phys >> 16);
++}
++
++
++/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
++ * a specific DMA channel.
++ * You must ensure the parameters are valid.
++ * NOTE: from a manual: "the number of transfers is one more
++ * than the initial word count"! This is taken into account.
++ * Assumes dma flip-flop is clear.
++ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
++ */
++static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
++{
++	count--;
++	if (dmanr <= 3) {
++		dma_outb(count & 0xff,
++			 ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE);
++		dma_outb((count >> 8) & 0xff,
++			 ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE);
++	} else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) {
++		dma_outb(count & 0xff,
++			 ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
++		dma_outb((count >> 8) & 0xff,
++			 ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
++	} else {
++		dma_outb((count >> 1) & 0xff,
++			 ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
++		dma_outb((count >> 9) & 0xff,
++			 ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
++	}
++}
++
++
++/* Get DMA residue count. After a DMA transfer, this
++ * should return zero. Reading this while a DMA transfer is
++ * still in progress will return unpredictable results.
++ * If called before the channel has been used, it may return 1.
++ * Otherwise, it returns the number of _bytes_ left to transfer.
++ *
++ * Assumes DMA flip-flop is clear.
++ */
++static __inline__ int get_dma_residue(unsigned int dmanr)
++{
++	unsigned int io_port = (dmanr <= 3)
++	    ? ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE
++	    : ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE;
++
++	/* using short to get 16-bit wrap around */
++	unsigned short count;
++
++	count = 1 + dma_inb(io_port);
++	count += dma_inb(io_port) << 8;
++
++	return (dmanr <= 3 || dmanr == SND_DMA1 || dmanr == SND_DMA2)
++	    ? count : (count << 1);
++}
++
++/* These are in kernel/dma.c: */
++
++/* reserve a DMA channel */
++extern int request_dma(unsigned int dmanr, const char *device_id);
++/* release it again */
++extern void free_dma(unsigned int dmanr);
++
++#ifdef CONFIG_PCI
++extern int isa_dma_bridge_buggy;
++#else
++#define isa_dma_bridge_buggy	(0)
++#endif
++
++#endif	/* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */
++
++#endif	/* _ASM_POWERPC_DMA_H */
+diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/elf.h
+@@ -0,0 +1,411 @@
++#ifndef _ASM_POWERPC_ELF_H
++#define _ASM_POWERPC_ELF_H
++
++#include <asm/types.h>
++#include <asm/ptrace.h>
++#include <asm/cputable.h>
++#include <asm/auxvec.h>
++#include <asm/page.h>
++
++/* PowerPC relocations defined by the ABIs */
++#define R_PPC_NONE		0
++#define R_PPC_ADDR32		1	/* 32bit absolute address */
++#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
++#define R_PPC_ADDR16		3	/* 16bit absolute address */
++#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
++#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
++#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
++#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
++#define R_PPC_ADDR14_BRTAKEN	8
++#define R_PPC_ADDR14_BRNTAKEN	9
++#define R_PPC_REL24		10	/* PC relative 26 bit */
++#define R_PPC_REL14		11	/* PC relative 16 bit */
++#define R_PPC_REL14_BRTAKEN	12
++#define R_PPC_REL14_BRNTAKEN	13
++#define R_PPC_GOT16		14
++#define R_PPC_GOT16_LO		15
++#define R_PPC_GOT16_HI		16
++#define R_PPC_GOT16_HA		17
++#define R_PPC_PLTREL24		18
++#define R_PPC_COPY		19
++#define R_PPC_GLOB_DAT		20
++#define R_PPC_JMP_SLOT		21
++#define R_PPC_RELATIVE		22
++#define R_PPC_LOCAL24PC		23
++#define R_PPC_UADDR32		24
++#define R_PPC_UADDR16		25
++#define R_PPC_REL32		26
++#define R_PPC_PLT32		27
++#define R_PPC_PLTREL32		28
++#define R_PPC_PLT16_LO		29
++#define R_PPC_PLT16_HI		30
++#define R_PPC_PLT16_HA		31
++#define R_PPC_SDAREL16		32
++#define R_PPC_SECTOFF		33
++#define R_PPC_SECTOFF_LO	34
++#define R_PPC_SECTOFF_HI	35
++#define R_PPC_SECTOFF_HA	36
++
++/* PowerPC relocations defined for the TLS access ABI.  */
++#define R_PPC_TLS		67 /* none	(sym+add)@tls */
++#define R_PPC_DTPMOD32		68 /* word32	(sym+add)@dtpmod */
++#define R_PPC_TPREL16		69 /* half16*	(sym+add)@tprel */
++#define R_PPC_TPREL16_LO	70 /* half16	(sym+add)@tprel at l */
++#define R_PPC_TPREL16_HI	71 /* half16	(sym+add)@tprel at h */
++#define R_PPC_TPREL16_HA	72 /* half16	(sym+add)@tprel at ha */
++#define R_PPC_TPREL32		73 /* word32	(sym+add)@tprel */
++#define R_PPC_DTPREL16		74 /* half16*	(sym+add)@dtprel */
++#define R_PPC_DTPREL16_LO	75 /* half16	(sym+add)@dtprel at l */
++#define R_PPC_DTPREL16_HI	76 /* half16	(sym+add)@dtprel at h */
++#define R_PPC_DTPREL16_HA	77 /* half16	(sym+add)@dtprel at ha */
++#define R_PPC_DTPREL32		78 /* word32	(sym+add)@dtprel */
++#define R_PPC_GOT_TLSGD16	79 /* half16*	(sym+add)@got at tlsgd */
++#define R_PPC_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got at tlsgd@l */
++#define R_PPC_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got at tlsgd@h */
++#define R_PPC_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got at tlsgd@ha */
++#define R_PPC_GOT_TLSLD16	83 /* half16*	(sym+add)@got at tlsld */
++#define R_PPC_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got at tlsld@l */
++#define R_PPC_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got at tlsld@h */
++#define R_PPC_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got at tlsld@ha */
++#define R_PPC_GOT_TPREL16	87 /* half16*	(sym+add)@got at tprel */
++#define R_PPC_GOT_TPREL16_LO	88 /* half16	(sym+add)@got at tprel@l */
++#define R_PPC_GOT_TPREL16_HI	89 /* half16	(sym+add)@got at tprel@h */
++#define R_PPC_GOT_TPREL16_HA	90 /* half16	(sym+add)@got at tprel@ha */
++#define R_PPC_GOT_DTPREL16	91 /* half16*	(sym+add)@got at dtprel */
++#define R_PPC_GOT_DTPREL16_LO	92 /* half16*	(sym+add)@got at dtprel@l */
++#define R_PPC_GOT_DTPREL16_HI	93 /* half16*	(sym+add)@got at dtprel@h */
++#define R_PPC_GOT_DTPREL16_HA	94 /* half16*	(sym+add)@got at dtprel@ha */
++
++/* keep this the last entry. */
++#define R_PPC_NUM		95
++
++/*
++ * ELF register definitions..
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/ptrace.h>
++
++#define ELF_NGREG	48	/* includes nip, msr, lr, etc. */
++#define ELF_NFPREG	33	/* includes fpscr */
++
++typedef unsigned long elf_greg_t64;
++typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
++
++typedef unsigned int elf_greg_t32;
++typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
++
++/*
++ * ELF_ARCH, CLASS, and DATA are used to set parameters in the core dumps.
++ */
++#ifdef __powerpc64__
++# define ELF_NVRREG32	33	/* includes vscr & vrsave stuffed together */
++# define ELF_NVRREG	34	/* includes vscr & vrsave in split vectors */
++# define ELF_GREG_TYPE	elf_greg_t64
++#else
++# define ELF_NEVRREG	34	/* includes acc (as 2) */
++# define ELF_NVRREG	33	/* includes vscr */
++# define ELF_GREG_TYPE	elf_greg_t32
++# define ELF_ARCH	EM_PPC
++# define ELF_CLASS	ELFCLASS32
++# define ELF_DATA	ELFDATA2MSB
++#endif /* __powerpc64__ */
++
++#ifndef ELF_ARCH
++# define ELF_ARCH	EM_PPC64
++# define ELF_CLASS	ELFCLASS64
++# define ELF_DATA	ELFDATA2MSB
++  typedef elf_greg_t64 elf_greg_t;
++  typedef elf_gregset_t64 elf_gregset_t;
++# define elf_addr_t unsigned long
++#else
++  /* Assumption: ELF_ARCH == EM_PPC and ELF_CLASS == ELFCLASS32 */
++  typedef elf_greg_t32 elf_greg_t;
++  typedef elf_gregset_t32 elf_gregset_t;
++# define elf_addr_t u32
++#endif /* ELF_ARCH */
++
++/* Floating point registers */
++typedef double elf_fpreg_t;
++typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
++
++/* Altivec registers */
++/*
++ * The entries with indexes 0-31 contain the corresponding vector registers. 
++ * The entry with index 32 contains the vscr as the last word (offset 12) 
++ * within the quadword.  This allows the vscr to be stored as either a 
++ * quadword (since it must be copied via a vector register to/from storage) 
++ * or as a word.  
++ *
++ * 64-bit kernel notes: The entry at index 33 contains the vrsave as the first  
++ * word (offset 0) within the quadword.
++ *
++ * This definition of the VMX state is compatible with the current PPC32 
++ * ptrace interface.  This allows signal handling and ptrace to use the same 
++ * structures.  This also simplifies the implementation of a bi-arch 
++ * (combined (32- and 64-bit) gdb.
++ *
++ * Note that it's _not_ compatible with 32 bits ucontext which stuffs the
++ * vrsave along with vscr and so only uses 33 vectors for the register set
++ */
++typedef __vector128 elf_vrreg_t;
++typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
++#ifdef __powerpc64__
++typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
++#endif
++
++/*
++ * This is used to ensure we don't load something for the wrong architecture.
++ */
++#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
++
++#define USE_ELF_CORE_DUMP
++#define ELF_EXEC_PAGESIZE	PAGE_SIZE
++
++/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
++   use of this is to invoke "./ld.so someprog" to test out a new version of
++   the loader.  We need to make sure that it is out of the way of the program
++   that it will "exec", and that there is sufficient room for the brk.  */
++
++#define ELF_ET_DYN_BASE         (0x08000000)
++
++#ifdef __KERNEL__
++
++/* Common routine for both 32-bit and 64-bit processes */
++static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
++					    struct pt_regs *regs)
++{
++	int i;
++	int gprs = sizeof(struct pt_regs)/sizeof(ELF_GREG_TYPE);
++
++	if (gprs > ELF_NGREG)
++		gprs = ELF_NGREG;
++
++	for (i=0; i < gprs; i++)
++		elf_regs[i] = (elf_greg_t)((ELF_GREG_TYPE *)regs)[i];
++
++	memset((char *)(elf_regs) + sizeof(struct pt_regs), 0,  	\
++	       sizeof(elf_gregset_t) - sizeof(struct pt_regs));
++
++}
++#define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs);
++
++static inline int dump_task_regs(struct task_struct *tsk,
++				 elf_gregset_t *elf_regs)
++{
++	struct pt_regs *regs = tsk->thread.regs;
++	if (regs)
++		ppc_elf_core_copy_regs(*elf_regs, regs);
++
++	return 1;
++}
++#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
++
++extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); 
++#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
++
++#endif /* __KERNEL__ */
++
++/* ELF_HWCAP yields a mask that user programs can use to figure out what
++   instruction set this cpu supports.  This could be done in userspace,
++   but it's not easy, and we've already done it here.  */
++# define ELF_HWCAP	(cur_cpu_spec->cpu_user_features)
++#ifdef __powerpc64__
++# define ELF_PLAT_INIT(_r, load_addr)	do {	\
++	_r->gpr[2] = load_addr; 		\
++} while (0)
++#endif /* __powerpc64__ */
++
++/* This yields a string that ld.so will use to load implementation
++   specific libraries for optimization.  This is more specific in
++   intent than poking at uname or /proc/cpuinfo.
++
++   For the moment, we have only optimizations for the Intel generations,
++   but that could change... */
++
++#define ELF_PLATFORM	(NULL)
++
++#ifdef __KERNEL__
++
++#ifdef __powerpc64__
++# define SET_PERSONALITY(ex, ibcs2)				\
++do {								\
++	unsigned long new_flags = 0;				\
++	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
++		new_flags = _TIF_32BIT;				\
++	if ((current_thread_info()->flags & _TIF_32BIT)		\
++	    != new_flags)					\
++		set_thread_flag(TIF_ABI_PENDING);		\
++	else							\
++		clear_thread_flag(TIF_ABI_PENDING);		\
++	if (personality(current->personality) != PER_LINUX32)	\
++		set_personality(PER_LINUX);			\
++} while (0)
++/*
++ * An executable for which elf_read_implies_exec() returns TRUE will
++ * have the READ_IMPLIES_EXEC personality flag set automatically. This
++ * is only required to work around bugs in old 32bit toolchains. Since
++ * the 64bit ABI has never had these issues dont enable the workaround
++ * even if we have an executable stack.
++ */
++# define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
++		(exec_stk != EXSTACK_DISABLE_X) : 0)
++#else 
++# define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
++#endif /* __powerpc64__ */
++
++#endif /* __KERNEL__ */
++
++extern int dcache_bsize;
++extern int icache_bsize;
++extern int ucache_bsize;
++
++#ifdef __powerpc64__
++struct linux_binprm;
++#define ARCH_HAS_SETUP_ADDITIONAL_PAGES	/* vDSO has arch_setup_additional_pages */
++extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack);
++#define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b);
++#else
++#define VDSO_AUX_ENT(a,b)
++#endif /* __powerpc64__ */
++
++/*
++ * The requirements here are:
++ * - keep the final alignment of sp (sp & 0xf)
++ * - make sure the 32-bit value at the first 16 byte aligned position of
++ *   AUXV is greater than 16 for glibc compatibility.
++ *   AT_IGNOREPPC is used for that.
++ * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
++ *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
++ */
++#define ARCH_DLINFO							\
++do {									\
++	/* Handle glibc compatibility. */				\
++	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
++	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
++	/* Cache size items */						\
++	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
++	NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);			\
++	NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize);			\
++	VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base)	\
++} while (0)
++
++/* PowerPC64 relocations defined by the ABIs */
++#define R_PPC64_NONE    R_PPC_NONE
++#define R_PPC64_ADDR32  R_PPC_ADDR32  /* 32bit absolute address.  */
++#define R_PPC64_ADDR24  R_PPC_ADDR24  /* 26bit address, word aligned.  */
++#define R_PPC64_ADDR16  R_PPC_ADDR16  /* 16bit absolute address. */
++#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address.  */
++#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */
++#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits.  */
++#define R_PPC64_ADDR14 R_PPC_ADDR14   /* 16bit address, word aligned.  */
++#define R_PPC64_ADDR14_BRTAKEN  R_PPC_ADDR14_BRTAKEN
++#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
++#define R_PPC64_REL24   R_PPC_REL24 /* PC relative 26 bit, word aligned.  */
++#define R_PPC64_REL14   R_PPC_REL14 /* PC relative 16 bit. */
++#define R_PPC64_REL14_BRTAKEN   R_PPC_REL14_BRTAKEN
++#define R_PPC64_REL14_BRNTAKEN  R_PPC_REL14_BRNTAKEN
++#define R_PPC64_GOT16     R_PPC_GOT16
++#define R_PPC64_GOT16_LO  R_PPC_GOT16_LO
++#define R_PPC64_GOT16_HI  R_PPC_GOT16_HI
++#define R_PPC64_GOT16_HA  R_PPC_GOT16_HA
++
++#define R_PPC64_COPY      R_PPC_COPY
++#define R_PPC64_GLOB_DAT  R_PPC_GLOB_DAT
++#define R_PPC64_JMP_SLOT  R_PPC_JMP_SLOT
++#define R_PPC64_RELATIVE  R_PPC_RELATIVE
++
++#define R_PPC64_UADDR32   R_PPC_UADDR32
++#define R_PPC64_UADDR16   R_PPC_UADDR16
++#define R_PPC64_REL32     R_PPC_REL32
++#define R_PPC64_PLT32     R_PPC_PLT32
++#define R_PPC64_PLTREL32  R_PPC_PLTREL32
++#define R_PPC64_PLT16_LO  R_PPC_PLT16_LO
++#define R_PPC64_PLT16_HI  R_PPC_PLT16_HI
++#define R_PPC64_PLT16_HA  R_PPC_PLT16_HA
++
++#define R_PPC64_SECTOFF     R_PPC_SECTOFF
++#define R_PPC64_SECTOFF_LO  R_PPC_SECTOFF_LO
++#define R_PPC64_SECTOFF_HI  R_PPC_SECTOFF_HI
++#define R_PPC64_SECTOFF_HA  R_PPC_SECTOFF_HA
++#define R_PPC64_ADDR30          37  /* word30 (S + A - P) >> 2.  */
++#define R_PPC64_ADDR64          38  /* doubleword64 S + A.  */
++#define R_PPC64_ADDR16_HIGHER   39  /* half16 #higher(S + A).  */
++#define R_PPC64_ADDR16_HIGHERA  40  /* half16 #highera(S + A).  */
++#define R_PPC64_ADDR16_HIGHEST  41  /* half16 #highest(S + A).  */
++#define R_PPC64_ADDR16_HIGHESTA 42  /* half16 #highesta(S + A). */
++#define R_PPC64_UADDR64     43  /* doubleword64 S + A.  */
++#define R_PPC64_REL64       44  /* doubleword64 S + A - P.  */
++#define R_PPC64_PLT64       45  /* doubleword64 L + A.  */
++#define R_PPC64_PLTREL64    46  /* doubleword64 L + A - P.  */
++#define R_PPC64_TOC16       47  /* half16* S + A - .TOC.  */
++#define R_PPC64_TOC16_LO    48  /* half16 #lo(S + A - .TOC.).  */
++#define R_PPC64_TOC16_HI    49  /* half16 #hi(S + A - .TOC.).  */
++#define R_PPC64_TOC16_HA    50  /* half16 #ha(S + A - .TOC.).  */
++#define R_PPC64_TOC         51  /* doubleword64 .TOC. */
++#define R_PPC64_PLTGOT16    52  /* half16* M + A.  */
++#define R_PPC64_PLTGOT16_LO 53  /* half16 #lo(M + A).  */
++#define R_PPC64_PLTGOT16_HI 54  /* half16 #hi(M + A).  */
++#define R_PPC64_PLTGOT16_HA 55  /* half16 #ha(M + A).  */
++
++#define R_PPC64_ADDR16_DS      56 /* half16ds* (S + A) >> 2.  */
++#define R_PPC64_ADDR16_LO_DS   57 /* half16ds  #lo(S + A) >> 2.  */
++#define R_PPC64_GOT16_DS       58 /* half16ds* (G + A) >> 2.  */
++#define R_PPC64_GOT16_LO_DS    59 /* half16ds  #lo(G + A) >> 2.  */
++#define R_PPC64_PLT16_LO_DS    60 /* half16ds  #lo(L + A) >> 2.  */
++#define R_PPC64_SECTOFF_DS     61 /* half16ds* (R + A) >> 2.  */
++#define R_PPC64_SECTOFF_LO_DS  62 /* half16ds  #lo(R + A) >> 2.  */
++#define R_PPC64_TOC16_DS       63 /* half16ds* (S + A - .TOC.) >> 2.  */
++#define R_PPC64_TOC16_LO_DS    64 /* half16ds  #lo(S + A - .TOC.) >> 2.  */
++#define R_PPC64_PLTGOT16_DS    65 /* half16ds* (M + A) >> 2.  */
++#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds  #lo(M + A) >> 2.  */
++
++/* PowerPC64 relocations defined for the TLS access ABI.  */
++#define R_PPC64_TLS		67 /* none	(sym+add)@tls */
++#define R_PPC64_DTPMOD64	68 /* doubleword64 (sym+add)@dtpmod */
++#define R_PPC64_TPREL16		69 /* half16*	(sym+add)@tprel */
++#define R_PPC64_TPREL16_LO	70 /* half16	(sym+add)@tprel at l */
++#define R_PPC64_TPREL16_HI	71 /* half16	(sym+add)@tprel at h */
++#define R_PPC64_TPREL16_HA	72 /* half16	(sym+add)@tprel at ha */
++#define R_PPC64_TPREL64		73 /* doubleword64 (sym+add)@tprel */
++#define R_PPC64_DTPREL16	74 /* half16*	(sym+add)@dtprel */
++#define R_PPC64_DTPREL16_LO	75 /* half16	(sym+add)@dtprel at l */
++#define R_PPC64_DTPREL16_HI	76 /* half16	(sym+add)@dtprel at h */
++#define R_PPC64_DTPREL16_HA	77 /* half16	(sym+add)@dtprel at ha */
++#define R_PPC64_DTPREL64	78 /* doubleword64 (sym+add)@dtprel */
++#define R_PPC64_GOT_TLSGD16	79 /* half16*	(sym+add)@got at tlsgd */
++#define R_PPC64_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got at tlsgd@l */
++#define R_PPC64_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got at tlsgd@h */
++#define R_PPC64_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got at tlsgd@ha */
++#define R_PPC64_GOT_TLSLD16	83 /* half16*	(sym+add)@got at tlsld */
++#define R_PPC64_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got at tlsld@l */
++#define R_PPC64_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got at tlsld@h */
++#define R_PPC64_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got at tlsld@ha */
++#define R_PPC64_GOT_TPREL16_DS	87 /* half16ds*	(sym+add)@got at tprel */
++#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got at tprel@l */
++#define R_PPC64_GOT_TPREL16_HI	89 /* half16	(sym+add)@got at tprel@h */
++#define R_PPC64_GOT_TPREL16_HA	90 /* half16	(sym+add)@got at tprel@ha */
++#define R_PPC64_GOT_DTPREL16_DS	91 /* half16ds*	(sym+add)@got at dtprel */
++#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got at dtprel@l */
++#define R_PPC64_GOT_DTPREL16_HI	93 /* half16	(sym+add)@got at dtprel@h */
++#define R_PPC64_GOT_DTPREL16_HA	94 /* half16	(sym+add)@got at dtprel@ha */
++#define R_PPC64_TPREL16_DS	95 /* half16ds*	(sym+add)@tprel */
++#define R_PPC64_TPREL16_LO_DS	96 /* half16ds	(sym+add)@tprel at l */
++#define R_PPC64_TPREL16_HIGHER	97 /* half16	(sym+add)@tprel at higher */
++#define R_PPC64_TPREL16_HIGHERA	98 /* half16	(sym+add)@tprel at highera */
++#define R_PPC64_TPREL16_HIGHEST	99 /* half16	(sym+add)@tprel at highest */
++#define R_PPC64_TPREL16_HIGHESTA 100 /* half16	(sym+add)@tprel at highesta */
++#define R_PPC64_DTPREL16_DS	101 /* half16ds* (sym+add)@dtprel */
++#define R_PPC64_DTPREL16_LO_DS	102 /* half16ds	(sym+add)@dtprel at l */
++#define R_PPC64_DTPREL16_HIGHER	103 /* half16	(sym+add)@dtprel at higher */
++#define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel at highera */
++#define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel at highest */
++#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel at highesta */
++
++/* Keep this the last entry.  */
++#define R_PPC64_NUM		107
++
++#endif /* _ASM_POWERPC_ELF_H */
+diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/firmware.h
+@@ -0,0 +1,97 @@
++/*
++ *  Copyright (C) 2001 Ben. Herrenschmidt (benh at kernel.crashing.org)
++ *
++ *  Modifications for ppc64:
++ *      Copyright (C) 2003 Dave Engebretsen <engebret at 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.
++ */
++#ifndef __ASM_POWERPC_FIRMWARE_H
++#define __ASM_POWERPC_FIRMWARE_H
++
++#ifdef __KERNEL__
++
++#ifndef __ASSEMBLY__
++
++/* firmware feature bitmask values */
++#define FIRMWARE_MAX_FEATURES 63
++
++#define FW_FEATURE_PFT		(1UL<<0)
++#define FW_FEATURE_TCE		(1UL<<1)
++#define FW_FEATURE_SPRG0	(1UL<<2)
++#define FW_FEATURE_DABR		(1UL<<3)
++#define FW_FEATURE_COPY		(1UL<<4)
++#define FW_FEATURE_ASR		(1UL<<5)
++#define FW_FEATURE_DEBUG	(1UL<<6)
++#define FW_FEATURE_TERM		(1UL<<7)
++#define FW_FEATURE_PERF		(1UL<<8)
++#define FW_FEATURE_DUMP		(1UL<<9)
++#define FW_FEATURE_INTERRUPT	(1UL<<10)
++#define FW_FEATURE_MIGRATE	(1UL<<11)
++#define FW_FEATURE_PERFMON	(1UL<<12)
++#define FW_FEATURE_CRQ		(1UL<<13)
++#define FW_FEATURE_VIO		(1UL<<14)
++#define FW_FEATURE_RDMA		(1UL<<15)
++#define FW_FEATURE_LLAN		(1UL<<16)
++#define FW_FEATURE_BULK		(1UL<<17)
++#define FW_FEATURE_XDABR	(1UL<<18)
++#define FW_FEATURE_MULTITCE	(1UL<<19)
++#define FW_FEATURE_SPLPAR	(1UL<<20)
++#define FW_FEATURE_ISERIES	(1UL<<21)
++
++enum {
++	FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE |
++		FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY |
++		FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM |
++		FW_FEATURE_PERF | FW_FEATURE_DUMP | FW_FEATURE_INTERRUPT |
++		FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ |
++		FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
++		FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE |
++		FW_FEATURE_SPLPAR,
++	FW_FEATURE_PSERIES_ALWAYS = 0,
++	FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES,
++	FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES,
++	FW_FEATURE_POSSIBLE =
++#ifdef CONFIG_PPC_PSERIES
++		FW_FEATURE_PSERIES_POSSIBLE |
++#endif
++#ifdef CONFIG_PPC_ISERIES
++		FW_FEATURE_ISERIES_POSSIBLE |
++#endif
++		0,
++	FW_FEATURE_ALWAYS =
++#ifdef CONFIG_PPC_PSERIES
++		FW_FEATURE_PSERIES_ALWAYS &
++#endif
++#ifdef CONFIG_PPC_ISERIES
++		FW_FEATURE_ISERIES_ALWAYS &
++#endif
++		FW_FEATURE_POSSIBLE,
++};
++
++/* This is used to identify firmware features which are available
++ * to the kernel.
++ */
++extern unsigned long	ppc64_firmware_features;
++
++static inline unsigned long firmware_has_feature(unsigned long feature)
++{
++	return (FW_FEATURE_ALWAYS & feature) ||
++		(FW_FEATURE_POSSIBLE & ppc64_firmware_features & feature);
++}
++
++#ifdef CONFIG_PPC_PSERIES
++typedef struct {
++    unsigned long val;
++    char * name;
++} firmware_feature_t;
++
++extern firmware_feature_t firmware_features_table[];
++#endif
++
++#endif /* __ASSEMBLY__ */
++#endif /* __KERNEL__ */
++#endif /* __ASM_POWERPC_FIRMWARE_H */
+diff --git a/include/asm-powerpc/grackle.h b/include/asm-powerpc/grackle.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/grackle.h
+@@ -0,0 +1,7 @@
++/*
++ * Functions for setting up and using a MPC106 northbridge
++ */
++
++#include <asm/pci-bridge.h>
++
++extern void setup_grackle(struct pci_controller *hose);
+diff --git a/include/asm-powerpc/hardirq.h b/include/asm-powerpc/hardirq.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/hardirq.h
+@@ -0,0 +1,27 @@
++#ifndef _ASM_POWERPC_HARDIRQ_H
++#define _ASM_POWERPC_HARDIRQ_H
++
++#include <asm/irq.h>
++#include <asm/bug.h>
++
++/* The __last_jiffy_stamp field is needed to ensure that no decrementer
++ * interrupt is lost on SMP machines. Since on most CPUs it is in the same
++ * cache line as local_irq_count, it is cheap to access and is also used on UP
++ * for uniformity.
++ */
++typedef struct {
++	unsigned int __softirq_pending;	/* set_bit is used on this */
++	unsigned int __last_jiffy_stamp;
++} ____cacheline_aligned irq_cpustat_t;
++
++#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
++
++#define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp)
++
++static inline void ack_bad_irq(int irq)
++{
++	printk(KERN_CRIT "illegal vector %d received!\n", irq);
++	BUG();
++}
++
++#endif /* _ASM_POWERPC_HARDIRQ_H */
+diff --git a/include/asm-powerpc/heathrow.h b/include/asm-powerpc/heathrow.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/heathrow.h
+@@ -0,0 +1,62 @@
++/*
++ * heathrow.h: definitions for using the "Heathrow" I/O controller chip.
++ *
++ * Grabbed from Open Firmware definitions on a PowerBook G3 Series
++ *
++ * Copyright (C) 1997 Paul Mackerras.
++ */
++
++/* Front light color on Yikes/B&W G3. 32 bits */
++#define HEATHROW_FRONT_LIGHT		0x32 /* (set to 0 or 0xffffffff) */
++
++/* Brightness/contrast (gossamer iMac ?). 8 bits */
++#define HEATHROW_BRIGHTNESS_CNTL	0x32
++#define HEATHROW_CONTRAST_CNTL		0x33
++
++/* offset from ohare base for feature control register */
++#define HEATHROW_MBCR			0x34	/* Media bay control */
++#define HEATHROW_FCR			0x38	/* Feature control */
++#define HEATHROW_AUX_CNTL_REG		0x3c	/* Aux control */
++
++/*
++ * Bits in feature control register.
++ * Bits postfixed with a _N are in inverse logic
++ */
++#define HRW_SCC_TRANS_EN_N	0x00000001	/* Also controls modem power */
++#define HRW_BAY_POWER_N		0x00000002
++#define HRW_BAY_PCI_ENABLE	0x00000004
++#define HRW_BAY_IDE_ENABLE	0x00000008
++#define HRW_BAY_FLOPPY_ENABLE	0x00000010
++#define HRW_IDE0_ENABLE		0x00000020
++#define HRW_IDE0_RESET_N	0x00000040
++#define HRW_BAY_DEV_MASK	0x0000001c
++#define HRW_BAY_RESET_N		0x00000080
++#define HRW_IOBUS_ENABLE	0x00000100	/* Internal IDE ? */
++#define HRW_SCC_ENABLE		0x00000200
++#define HRW_MESH_ENABLE		0x00000400
++#define HRW_SWIM_ENABLE		0x00000800
++#define HRW_SOUND_POWER_N	0x00001000
++#define HRW_SOUND_CLK_ENABLE	0x00002000
++#define HRW_SCCA_IO		0x00004000
++#define HRW_SCCB_IO		0x00008000
++#define HRW_PORT_OR_DESK_VIA_N	0x00010000	/* This one is 0 on PowerBook */
++#define HRW_PWM_MON_ID_N	0x00020000	/* ??? (0) */
++#define HRW_HOOK_MB_CNT_N	0x00040000	/* ??? (0) */
++#define HRW_SWIM_CLONE_FLOPPY	0x00080000	/* ??? (0) */
++#define HRW_AUD_RUN22		0x00100000	/* ??? (1) */
++#define HRW_SCSI_LINK_MODE	0x00200000	/* Read ??? (1) */
++#define HRW_ARB_BYPASS		0x00400000	/* Disable internal PCI arbitrer */
++#define HRW_IDE1_RESET_N	0x00800000	/* Media bay */
++#define HRW_SLOW_SCC_PCLK	0x01000000	/* ??? (0) */
++#define HRW_RESET_SCC		0x02000000
++#define HRW_MFDC_CELL_ENABLE	0x04000000	/* ??? (0) */
++#define HRW_USE_MFDC		0x08000000	/* ??? (0) */
++#define HRW_BMAC_IO_ENABLE	0x60000000	/* two bits, not documented in OF */
++#define HRW_BMAC_RESET		0x80000000	/* not documented in OF */
++
++/* We OR those features at boot on desktop G3s */
++#define HRW_DEFAULTS		(HRW_SCCA_IO | HRW_SCCB_IO | HRW_SCC_ENABLE)
++
++/* Looks like Heathrow has some sort of GPIOs as well... */
++#define HRW_GPIO_MODEM_RESET	0x6d
++
+diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/hw_irq.h
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 1999 Cort Dougan <cort at cs.nmt.edu>
++ */
++#ifndef _ASM_POWERPC_HW_IRQ_H
++#define _ASM_POWERPC_HW_IRQ_H
++
++#ifdef __KERNEL__
++
++#include <linux/config.h>
++#include <linux/errno.h>
++#include <asm/ptrace.h>
++#include <asm/processor.h>
++
++extern void timer_interrupt(struct pt_regs *);
++extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
++
++#ifdef CONFIG_PPC_ISERIES
++
++extern unsigned long local_get_flags(void);
++extern unsigned long local_irq_disable(void);
++extern void local_irq_restore(unsigned long);
++
++#define local_irq_enable()	local_irq_restore(1)
++#define local_save_flags(flags)	((flags) = local_get_flags())
++#define local_irq_save(flags)	((flags) = local_irq_disable())
++
++#define irqs_disabled()		(local_get_flags() == 0)
++
++#else
++
++#if defined(CONFIG_BOOKE)
++#define SET_MSR_EE(x)	mtmsr(x)
++#define local_irq_restore(flags)	__asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
++#elif defined(__powerpc64__)
++#define SET_MSR_EE(x)	__mtmsrd(x, 1)
++#define local_irq_restore(flags) do { \
++	__asm__ __volatile__("": : :"memory"); \
++	__mtmsrd((flags), 1); \
++} while(0)
++#else
++#define SET_MSR_EE(x)	mtmsr(x)
++#define local_irq_restore(flags)	mtmsr(flags)
++#endif
++
++static inline void local_irq_disable(void)
++{
++#ifdef CONFIG_BOOKE
++	__asm__ __volatile__("wrteei 0": : :"memory");
++#else
++	unsigned long msr;
++	__asm__ __volatile__("": : :"memory");
++	msr = mfmsr();
++	SET_MSR_EE(msr & ~MSR_EE);
++#endif
++}
++
++static inline void local_irq_enable(void)
++{
++#ifdef CONFIG_BOOKE
++	__asm__ __volatile__("wrteei 1": : :"memory");
++#else
++	unsigned long msr;
++	__asm__ __volatile__("": : :"memory");
++	msr = mfmsr();
++	SET_MSR_EE(msr | MSR_EE);
++#endif
++}
++
++static inline void local_irq_save_ptr(unsigned long *flags)
++{
++	unsigned long msr;
++	msr = mfmsr();
++	*flags = msr;
++#ifdef CONFIG_BOOKE
++	__asm__ __volatile__("wrteei 0": : :"memory");
++#else
++	SET_MSR_EE(msr & ~MSR_EE);
++#endif
++	__asm__ __volatile__("": : :"memory");
++}
++
++#define local_save_flags(flags)	((flags) = mfmsr())
++#define local_irq_save(flags)	local_irq_save_ptr(&flags)
++#define irqs_disabled()		((mfmsr() & MSR_EE) == 0)
++
++#endif /* CONFIG_PPC_ISERIES */
++
++#define mask_irq(irq)						\
++	({							\
++	 	irq_desc_t *desc = get_irq_desc(irq);		\
++		if (desc->handler && desc->handler->disable)	\
++			desc->handler->disable(irq);		\
++	})
++#define unmask_irq(irq)						\
++	({							\
++	 	irq_desc_t *desc = get_irq_desc(irq);		\
++		if (desc->handler && desc->handler->enable)	\
++			desc->handler->enable(irq);		\
++	})
++#define ack_irq(irq)						\
++	({							\
++	 	irq_desc_t *desc = get_irq_desc(irq);		\
++		if (desc->handler && desc->handler->ack)	\
++			desc->handler->ack(irq);		\
++	})
++
++/* Should we handle this via lost interrupts and IPIs or should we don't care like
++ * we do now ? --BenH.
++ */
++struct hw_interrupt_type;
++static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
++
++#endif	/* __KERNEL__ */
++#endif	/* _ASM_POWERPC_HW_IRQ_H */
+diff --git a/include/asm-powerpc/i8259.h b/include/asm-powerpc/i8259.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/i8259.h
+@@ -0,0 +1,12 @@
++#ifndef _ASM_POWERPC_I8259_H
++#define _ASM_POWERPC_I8259_H
++
++#include <linux/irq.h>
++
++extern struct hw_interrupt_type i8259_pic;
++
++extern void i8259_init(unsigned long intack_addr, int offset);
++extern int i8259_irq(struct pt_regs *regs);
++extern int i8259_irq_cascade(struct pt_regs *regs, void *unused);
++
++#endif /* _ASM_POWERPC_I8259_H */
+diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/iommu.h
+@@ -0,0 +1,113 @@
++/*
++ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
++ * Rewrite, cleanup:
++ * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, 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
++ */
++
++#ifndef _ASM_IOMMU_H
++#define _ASM_IOMMU_H
++
++#include <linux/config.h>
++#include <asm/types.h>
++#include <linux/spinlock.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++
++/*
++ * IOMAP_MAX_ORDER defines the largest contiguous block
++ * of dma space we can get.  IOMAP_MAX_ORDER = 13
++ * allows up to 2**12 pages (4096 * 4096) = 16 MB
++ */
++#define IOMAP_MAX_ORDER 13
++
++struct iommu_table {
++	unsigned long  it_busno;     /* Bus number this table belongs to */
++	unsigned long  it_size;      /* Size of iommu table in entries */
++	unsigned long  it_offset;    /* Offset into global table */
++	unsigned long  it_base;      /* mapped address of tce table */
++	unsigned long  it_index;     /* which iommu table this is */
++	unsigned long  it_type;      /* type: PCI or Virtual Bus */
++	unsigned long  it_blocksize; /* Entries in each block (cacheline) */
++	unsigned long  it_hint;      /* Hint for next alloc */
++	unsigned long  it_largehint; /* Hint for large allocs */
++	unsigned long  it_halfpoint; /* Breaking point for small/large allocs */
++	spinlock_t     it_lock;      /* Protects it_map */
++	unsigned long *it_map;       /* A simple allocation bitmap for now */
++};
++
++struct scatterlist;
++struct device_node;
++
++#ifdef CONFIG_PPC_MULTIPLATFORM
++
++/* Walks all buses and creates iommu tables */
++extern void iommu_setup_pSeries(void);
++extern void iommu_setup_u3(void);
++
++/* Frees table for an individual device node */
++extern void iommu_free_table(struct device_node *dn);
++
++#endif /* CONFIG_PPC_MULTIPLATFORM */
++
++#ifdef CONFIG_PPC_PSERIES
++
++/* Creates table for an individual device node */
++extern void iommu_devnode_init_pSeries(struct device_node *dn);
++
++#endif /* CONFIG_PPC_PSERIES */
++
++#ifdef CONFIG_PPC_ISERIES
++
++/* Creates table for an individual device node */
++extern void iommu_devnode_init_iSeries(struct device_node *dn);
++
++#endif /* CONFIG_PPC_ISERIES */
++
++/* Initializes an iommu_table based in values set in the passed-in
++ * structure
++ */
++extern struct iommu_table *iommu_init_table(struct iommu_table * tbl);
++
++extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
++		struct scatterlist *sglist, int nelems,
++		enum dma_data_direction direction);
++extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
++		int nelems, enum dma_data_direction direction);
++
++extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
++		dma_addr_t *dma_handle, gfp_t flag);
++extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
++		void *vaddr, dma_addr_t dma_handle);
++extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
++		size_t size, enum dma_data_direction direction);
++extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
++		size_t size, enum dma_data_direction direction);
++
++extern void iommu_init_early_pSeries(void);
++extern void iommu_init_early_iSeries(void);
++extern void iommu_init_early_u3(void);
++
++#ifdef CONFIG_PCI
++extern void pci_iommu_init(void);
++extern void pci_direct_iommu_init(void);
++#else
++static inline void pci_iommu_init(void) { }
++#endif
++
++extern void alloc_u3_dart_table(void);
++
++#endif /* _ASM_IOMMU_H */
+diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/irq.h
+@@ -0,0 +1,504 @@
++#ifdef __KERNEL__
++#ifndef _ASM_POWERPC_IRQ_H
++#define _ASM_POWERPC_IRQ_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.
++ */
++
++#include <linux/config.h>
++#include <linux/threads.h>
++
++#include <asm/types.h>
++#include <asm/atomic.h>
++
++/* this number is used when no interrupt has been assigned */
++#define NO_IRQ			(-1)
++
++/*
++ * These constants are used for passing information about interrupt
++ * signal polarity and level/edge sensing to the low-level PIC chip
++ * drivers.
++ */
++#define IRQ_SENSE_MASK		0x1
++#define IRQ_SENSE_LEVEL		0x1	/* interrupt on active level */
++#define IRQ_SENSE_EDGE		0x0	/* interrupt triggered by edge */
++
++#define IRQ_POLARITY_MASK	0x2
++#define IRQ_POLARITY_POSITIVE	0x2	/* high level or low->high edge */
++#define IRQ_POLARITY_NEGATIVE	0x0	/* low level or high->low edge */
++
++/*
++ * IRQ line status macro IRQ_PER_CPU is used
++ */
++#define ARCH_HAS_IRQ_PER_CPU
++
++#define get_irq_desc(irq) (&irq_desc[(irq)])
++
++/* Define a way to iterate across irqs. */
++#define for_each_irq(i) \
++	for ((i) = 0; (i) < NR_IRQS; ++(i))
++
++#ifdef CONFIG_PPC64
++
++/*
++ * Maximum number of interrupt sources that we can handle.
++ */
++#define NR_IRQS		512
++
++/* Interrupt numbers are virtual in case they are sparsely
++ * distributed by the hardware.
++ */
++extern unsigned int virt_irq_to_real_map[NR_IRQS];
++
++/* Create a mapping for a real_irq if it doesn't already exist.
++ * Return the virtual irq as a convenience.
++ */
++int virt_irq_create_mapping(unsigned int real_irq);
++void virt_irq_init(void);
++
++static inline unsigned int virt_irq_to_real(unsigned int virt_irq)
++{
++	return virt_irq_to_real_map[virt_irq];
++}
++
++extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq);
++
++/*
++ * List of interrupt controllers.
++ */
++#define IC_INVALID    0
++#define IC_OPEN_PIC   1
++#define IC_PPC_XIC    2
++#define IC_BPA_IIC    3
++#define IC_ISERIES    4
++
++extern u64 ppc64_interrupt_controller;
++
++#else /* 32-bit */
++
++#if defined(CONFIG_40x)
++#include <asm/ibm4xx.h>
++
++#ifndef NR_BOARD_IRQS
++#define NR_BOARD_IRQS 0
++#endif
++
++#ifndef UIC_WIDTH /* Number of interrupts per device */
++#define UIC_WIDTH 32
++#endif
++
++#ifndef NR_UICS /* number  of UIC devices */
++#define NR_UICS 1
++#endif
++
++#if defined (CONFIG_403)
++/*
++ * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has
++ * 32 possible interrupts, a majority of which are not implemented on
++ * all cores. There are six configurable, external interrupt pins and
++ * there are eight internal interrupts for the on-chip serial port
++ * (SPU), DMA controller, and JTAG controller.
++ *
++ */
++
++#define	NR_AIC_IRQS 32
++#define	NR_IRQS	 (NR_AIC_IRQS + NR_BOARD_IRQS)
++
++#elif !defined (CONFIG_403)
++
++/*
++ *  The PowerPC 405 cores' Universal Interrupt Controller (UIC) has 32
++ * possible interrupts as well. There are seven, configurable external
++ * interrupt pins and there are 17 internal interrupts for the on-chip
++ * serial port, DMA controller, on-chip Ethernet controller, PCI, etc.
++ *
++ */
++
++
++#define NR_UIC_IRQS UIC_WIDTH
++#define NR_IRQS		((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS)
++#endif
++
++#elif defined(CONFIG_44x)
++#include <asm/ibm44x.h>
++
++#define	NR_UIC_IRQS	32
++#define	NR_IRQS		((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS)
++
++#elif defined(CONFIG_8xx)
++
++/* Now include the board configuration specific associations.
++*/
++#include <asm/mpc8xx.h>
++
++/* The MPC8xx cores have 16 possible interrupts.  There are eight
++ * possible level sensitive interrupts assigned and generated internally
++ * from such devices as CPM, PCMCIA, RTC, PIT, TimeBase and Decrementer.
++ * There are eight external interrupts (IRQs) that can be configured
++ * as either level or edge sensitive.
++ *
++ * On some implementations, there is also the possibility of an 8259
++ * through the PCI and PCI-ISA bridges.
++ *
++ * We are "flattening" the interrupt vectors of the cascaded CPM
++ * and 8259 interrupt controllers so that we can uniquely identify
++ * any interrupt source with a single integer.
++ */
++#define NR_SIU_INTS	16
++#define NR_CPM_INTS	32
++#ifndef NR_8259_INTS
++#define NR_8259_INTS 0
++#endif
++
++#define SIU_IRQ_OFFSET		0
++#define CPM_IRQ_OFFSET		(SIU_IRQ_OFFSET + NR_SIU_INTS)
++#define I8259_IRQ_OFFSET	(CPM_IRQ_OFFSET + NR_CPM_INTS)
++
++#define NR_IRQS	(NR_SIU_INTS + NR_CPM_INTS + NR_8259_INTS)
++
++/* These values must be zero-based and map 1:1 with the SIU configuration.
++ * They are used throughout the 8xx I/O subsystem to generate
++ * interrupt masks, flags, and other control patterns.  This is why the
++ * current kernel assumption of the 8259 as the base controller is such
++ * a pain in the butt.
++ */
++#define	SIU_IRQ0	(0)	/* Highest priority */
++#define	SIU_LEVEL0	(1)
++#define	SIU_IRQ1	(2)
++#define	SIU_LEVEL1	(3)
++#define	SIU_IRQ2	(4)
++#define	SIU_LEVEL2	(5)
++#define	SIU_IRQ3	(6)
++#define	SIU_LEVEL3	(7)
++#define	SIU_IRQ4	(8)
++#define	SIU_LEVEL4	(9)
++#define	SIU_IRQ5	(10)
++#define	SIU_LEVEL5	(11)
++#define	SIU_IRQ6	(12)
++#define	SIU_LEVEL6	(13)
++#define	SIU_IRQ7	(14)
++#define	SIU_LEVEL7	(15)
++
++#define MPC8xx_INT_FEC1		SIU_LEVEL1
++#define MPC8xx_INT_FEC2		SIU_LEVEL3
++
++#define MPC8xx_INT_SCC1		(CPM_IRQ_OFFSET + CPMVEC_SCC1)
++#define MPC8xx_INT_SCC2		(CPM_IRQ_OFFSET + CPMVEC_SCC2)
++#define MPC8xx_INT_SCC3		(CPM_IRQ_OFFSET + CPMVEC_SCC3)
++#define MPC8xx_INT_SCC4		(CPM_IRQ_OFFSET + CPMVEC_SCC4)
++#define MPC8xx_INT_SMC1		(CPM_IRQ_OFFSET + CPMVEC_SMC1)
++#define MPC8xx_INT_SMC2		(CPM_IRQ_OFFSET + CPMVEC_SMC2)
++
++/* The internal interrupts we can configure as we see fit.
++ * My personal preference is CPM at level 2, which puts it above the
++ * MBX PCI/ISA/IDE interrupts.
++ */
++#ifndef PIT_INTERRUPT
++#define PIT_INTERRUPT		SIU_LEVEL0
++#endif
++#ifndef	CPM_INTERRUPT
++#define CPM_INTERRUPT		SIU_LEVEL2
++#endif
++#ifndef	PCMCIA_INTERRUPT
++#define PCMCIA_INTERRUPT	SIU_LEVEL6
++#endif
++#ifndef	DEC_INTERRUPT
++#define DEC_INTERRUPT		SIU_LEVEL7
++#endif
++
++/* Some internal interrupt registers use an 8-bit mask for the interrupt
++ * level instead of a number.
++ */
++#define	mk_int_int_mask(IL) (1 << (7 - (IL/2)))
++
++#elif defined(CONFIG_83xx)
++#include <asm/mpc83xx.h>
++
++#define	NR_IRQS	(NR_IPIC_INTS)
++
++#elif defined(CONFIG_85xx)
++/* Now include the board configuration specific associations.
++*/
++#include <asm/mpc85xx.h>
++
++/* The MPC8548 openpic has 48 internal interrupts and 12 external
++ * interrupts.
++ *
++ * We are "flattening" the interrupt vectors of the cascaded CPM
++ * so that we can uniquely identify any interrupt source with a
++ * single integer.
++ */
++#define NR_CPM_INTS	64
++#define NR_EPIC_INTS	60
++#ifndef NR_8259_INTS
++#define NR_8259_INTS	0
++#endif
++#define NUM_8259_INTERRUPTS NR_8259_INTS
++
++#ifndef CPM_IRQ_OFFSET
++#define CPM_IRQ_OFFSET	0
++#endif
++
++#define NR_IRQS	(NR_EPIC_INTS + NR_CPM_INTS + NR_8259_INTS)
++
++/* Internal IRQs on MPC85xx OpenPIC */
++
++#ifndef MPC85xx_OPENPIC_IRQ_OFFSET
++#ifdef CONFIG_CPM2
++#define MPC85xx_OPENPIC_IRQ_OFFSET	(CPM_IRQ_OFFSET + NR_CPM_INTS)
++#else
++#define MPC85xx_OPENPIC_IRQ_OFFSET	0
++#endif
++#endif
++
++/* Not all of these exist on all MPC85xx implementations */
++#define MPC85xx_IRQ_L2CACHE	( 0 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_ECM		( 1 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_DDR		( 2 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_LBIU	( 3 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_DMA0	( 4 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_DMA1	( 5 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_DMA2	( 6 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_DMA3	( 7 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_PCI1	( 8 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_PCI2	( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_RIO_ERROR	( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_RIO_BELL	(10 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_RIO_TX	(11 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_RIO_RX	(12 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC1_TX	(13 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC1_RX	(14 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC3_TX	(15 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC3_RX	(16 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC3_ERROR	(17 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC1_ERROR	(18 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC2_TX	(19 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC2_RX	(20 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC4_TX	(21 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC4_RX	(22 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC4_ERROR	(23 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_TSEC2_ERROR	(24 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_FEC		(25 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_DUART	(26 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_IIC1	(27 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_PERFMON	(28 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_SEC2	(29 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_CPM		(30 + MPC85xx_OPENPIC_IRQ_OFFSET)
++
++/* The 12 external interrupt lines */
++#define MPC85xx_IRQ_EXT0        (48 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT1        (49 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT2        (50 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT3        (51 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT4        (52 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT5        (53 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT6        (54 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT7        (55 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT8        (56 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT9        (57 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT10       (58 + MPC85xx_OPENPIC_IRQ_OFFSET)
++#define MPC85xx_IRQ_EXT11       (59 + MPC85xx_OPENPIC_IRQ_OFFSET)
++
++/* CPM related interrupts */
++#define	SIU_INT_ERROR		((uint)0x00+CPM_IRQ_OFFSET)
++#define	SIU_INT_I2C		((uint)0x01+CPM_IRQ_OFFSET)
++#define	SIU_INT_SPI		((uint)0x02+CPM_IRQ_OFFSET)
++#define	SIU_INT_RISC		((uint)0x03+CPM_IRQ_OFFSET)
++#define	SIU_INT_SMC1		((uint)0x04+CPM_IRQ_OFFSET)
++#define	SIU_INT_SMC2		((uint)0x05+CPM_IRQ_OFFSET)
++#define	SIU_INT_USB		((uint)0x0b+CPM_IRQ_OFFSET)
++#define	SIU_INT_TIMER1		((uint)0x0c+CPM_IRQ_OFFSET)
++#define	SIU_INT_TIMER2		((uint)0x0d+CPM_IRQ_OFFSET)
++#define	SIU_INT_TIMER3		((uint)0x0e+CPM_IRQ_OFFSET)
++#define	SIU_INT_TIMER4		((uint)0x0f+CPM_IRQ_OFFSET)
++#define	SIU_INT_FCC1		((uint)0x20+CPM_IRQ_OFFSET)
++#define	SIU_INT_FCC2		((uint)0x21+CPM_IRQ_OFFSET)
++#define	SIU_INT_FCC3		((uint)0x22+CPM_IRQ_OFFSET)
++#define	SIU_INT_MCC1		((uint)0x24+CPM_IRQ_OFFSET)
++#define	SIU_INT_MCC2		((uint)0x25+CPM_IRQ_OFFSET)
++#define	SIU_INT_SCC1		((uint)0x28+CPM_IRQ_OFFSET)
++#define	SIU_INT_SCC2		((uint)0x29+CPM_IRQ_OFFSET)
++#define	SIU_INT_SCC3		((uint)0x2a+CPM_IRQ_OFFSET)
++#define	SIU_INT_SCC4		((uint)0x2b+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC15		((uint)0x30+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC14		((uint)0x31+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC13		((uint)0x32+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC12		((uint)0x33+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC11		((uint)0x34+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC10		((uint)0x35+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC9		((uint)0x36+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC8		((uint)0x37+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC7		((uint)0x38+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC6		((uint)0x39+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC5		((uint)0x3a+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC4		((uint)0x3b+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC3		((uint)0x3c+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC2		((uint)0x3d+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC1		((uint)0x3e+CPM_IRQ_OFFSET)
++#define	SIU_INT_PC0		((uint)0x3f+CPM_IRQ_OFFSET)
++
++#else /* CONFIG_40x + CONFIG_8xx */
++/*
++ * this is the # irq's for all ppc arch's (pmac/chrp/prep)
++ * so it is the max of them all
++ */
++#define NR_IRQS			256
++#define __DO_IRQ_CANON	1
++
++#ifndef CONFIG_8260
++
++#define NUM_8259_INTERRUPTS	16
++
++#else /* CONFIG_8260 */
++
++/* The 8260 has an internal interrupt controller with a maximum of
++ * 64 IRQs.  We will use NR_IRQs from above since it is large enough.
++ * Don't be confused by the 8260 documentation where they list an
++ * "interrupt number" and "interrupt vector".  We are only interested
++ * in the interrupt vector.  There are "reserved" holes where the
++ * vector number increases, but the interrupt number in the table does not.
++ * (Document errata updates have fixed this...make sure you have up to
++ * date processor documentation -- Dan).
++ */
++
++#ifndef CPM_IRQ_OFFSET
++#define CPM_IRQ_OFFSET	0
++#endif
++
++#define NR_CPM_INTS	64
++
++#define	SIU_INT_ERROR		((uint)0x00 + CPM_IRQ_OFFSET)
++#define	SIU_INT_I2C		((uint)0x01 + CPM_IRQ_OFFSET)
++#define	SIU_INT_SPI		((uint)0x02 + CPM_IRQ_OFFSET)
++#define	SIU_INT_RISC		((uint)0x03 + CPM_IRQ_OFFSET)
++#define	SIU_INT_SMC1		((uint)0x04 + CPM_IRQ_OFFSET)
++#define	SIU_INT_SMC2		((uint)0x05 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IDMA1		((uint)0x06 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IDMA2		((uint)0x07 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IDMA3		((uint)0x08 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IDMA4		((uint)0x09 + CPM_IRQ_OFFSET)
++#define	SIU_INT_SDMA		((uint)0x0a + CPM_IRQ_OFFSET)
++#define	SIU_INT_USB		((uint)0x0b + CPM_IRQ_OFFSET)
++#define	SIU_INT_TIMER1		((uint)0x0c + CPM_IRQ_OFFSET)
++#define	SIU_INT_TIMER2		((uint)0x0d + CPM_IRQ_OFFSET)
++#define	SIU_INT_TIMER3		((uint)0x0e + CPM_IRQ_OFFSET)
++#define	SIU_INT_TIMER4		((uint)0x0f + CPM_IRQ_OFFSET)
++#define	SIU_INT_TMCNT		((uint)0x10 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PIT		((uint)0x11 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IRQ1		((uint)0x13 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IRQ2		((uint)0x14 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IRQ3		((uint)0x15 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IRQ4		((uint)0x16 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IRQ5		((uint)0x17 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IRQ6		((uint)0x18 + CPM_IRQ_OFFSET)
++#define	SIU_INT_IRQ7		((uint)0x19 + CPM_IRQ_OFFSET)
++#define	SIU_INT_FCC1		((uint)0x20 + CPM_IRQ_OFFSET)
++#define	SIU_INT_FCC2		((uint)0x21 + CPM_IRQ_OFFSET)
++#define	SIU_INT_FCC3		((uint)0x22 + CPM_IRQ_OFFSET)
++#define	SIU_INT_MCC1		((uint)0x24 + CPM_IRQ_OFFSET)
++#define	SIU_INT_MCC2		((uint)0x25 + CPM_IRQ_OFFSET)
++#define	SIU_INT_SCC1		((uint)0x28 + CPM_IRQ_OFFSET)
++#define	SIU_INT_SCC2		((uint)0x29 + CPM_IRQ_OFFSET)
++#define	SIU_INT_SCC3		((uint)0x2a + CPM_IRQ_OFFSET)
++#define	SIU_INT_SCC4		((uint)0x2b + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC15		((uint)0x30 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC14		((uint)0x31 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC13		((uint)0x32 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC12		((uint)0x33 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC11		((uint)0x34 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC10		((uint)0x35 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC9		((uint)0x36 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC8		((uint)0x37 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC7		((uint)0x38 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC6		((uint)0x39 + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC5		((uint)0x3a + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC4		((uint)0x3b + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC3		((uint)0x3c + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC2		((uint)0x3d + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC1		((uint)0x3e + CPM_IRQ_OFFSET)
++#define	SIU_INT_PC0		((uint)0x3f + CPM_IRQ_OFFSET)
++
++#endif /* CONFIG_8260 */
++
++#endif
++
++#define NR_MASK_WORDS	((NR_IRQS + 31) / 32)
++/* pedantic: these are long because they are used with set_bit --RR */
++extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
++extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
++extern atomic_t ppc_n_lost_interrupts;
++
++#define virt_irq_create_mapping(x)	(x)
++
++#endif
++
++/*
++ * Because many systems have two overlapping names spaces for
++ * interrupts (ISA and XICS for example), and the ISA interrupts
++ * have historically not been easy to renumber, we allow ISA
++ * interrupts to take values 0 - 15, and shift up the remaining
++ * interrupts by 0x10.
++ */
++#define NUM_ISA_INTERRUPTS	0x10
++extern int __irq_offset_value;
++
++static inline int irq_offset_up(int irq)
++{
++	return(irq + __irq_offset_value);
++}
++
++static inline int irq_offset_down(int irq)
++{
++	return(irq - __irq_offset_value);
++}
++
++static inline int irq_offset_value(void)
++{
++	return __irq_offset_value;
++}
++
++#ifdef __DO_IRQ_CANON
++extern int ppc_do_canonicalize_irqs;
++#else
++#define ppc_do_canonicalize_irqs	0
++#endif
++
++static __inline__ int irq_canonicalize(int irq)
++{
++	if (ppc_do_canonicalize_irqs && irq == 2)
++		irq = 9;
++	return irq;
++}
++
++extern int distribute_irqs;
++
++struct irqaction;
++struct pt_regs;
++
++#ifdef CONFIG_IRQSTACKS
++/*
++ * Per-cpu stacks for handling hard and soft interrupts.
++ */
++extern struct thread_info *hardirq_ctx[NR_CPUS];
++extern struct thread_info *softirq_ctx[NR_CPUS];
++
++extern void irq_ctx_init(void);
++extern void call_do_softirq(struct thread_info *tp);
++extern int call_handle_IRQ_event(int irq, struct pt_regs *regs,
++			struct irqaction *action, struct thread_info *tp);
++
++#define __ARCH_HAS_DO_SOFTIRQ
++
++#else
++#define irq_ctx_init()
++
++#endif /* CONFIG_IRQSTACKS */
++
++extern void do_IRQ(struct pt_regs *regs);
++
++#endif /* _ASM_IRQ_H */
++#endif /* __KERNEL__ */
+diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/kdebug.h
+@@ -0,0 +1,42 @@
++#ifndef _ASM_POWERPC_KDEBUG_H
++#define _ASM_POWERPC_KDEBUG_H
++
++/* nearly identical to x86_64/i386 code */
++
++#include <linux/notifier.h>
++
++struct pt_regs;
++
++struct die_args {
++	struct pt_regs *regs;
++	const char *str;
++	long err;
++	int trapnr;
++	int signr;
++};
++
++/*
++   Note - you should never unregister because that can race with NMIs.
++   If you really want to do it first unregister - then synchronize_sched -
++   then free.
++ */
++int register_die_notifier(struct notifier_block *nb);
++extern struct notifier_block *powerpc_die_chain;
++
++/* Grossly misnamed. */
++enum die_val {
++	DIE_OOPS = 1,
++	DIE_IABR_MATCH,
++	DIE_DABR_MATCH,
++	DIE_BPT,
++	DIE_SSTEP,
++	DIE_PAGE_FAULT,
++};
++
++static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
++{
++	struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig };
++	return notifier_call_chain(&powerpc_die_chain, val, &args);
++}
++
++#endif /* _ASM_POWERPC_KDEBUG_H */
+diff --git a/include/asm-powerpc/keylargo.h b/include/asm-powerpc/keylargo.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/keylargo.h
+@@ -0,0 +1,248 @@
++/*
++ * keylargo.h: definitions for using the "KeyLargo" I/O controller chip.
++ *
++ */
++
++/* "Pangea" chipset has keylargo device-id 0x25 while core99
++ * has device-id 0x22. The rev. of the pangea one is 0, so we
++ * fake an artificial rev. in keylargo_rev by oring 0x100
++ */
++#define KL_PANGEA_REV		0x100
++
++/* offset from base for feature control registers */
++#define KEYLARGO_MBCR		0x34	/* KL Only, Media bay control/status */
++#define KEYLARGO_FCR0		0x38
++#define KEYLARGO_FCR1		0x3c
++#define KEYLARGO_FCR2		0x40
++#define KEYLARGO_FCR3		0x44
++#define KEYLARGO_FCR4		0x48
++#define KEYLARGO_FCR5		0x4c	/* Pangea only */
++
++/* K2 aditional FCRs */
++#define K2_FCR6			0x34
++#define K2_FCR7			0x30
++#define K2_FCR8			0x2c
++#define K2_FCR9			0x28
++#define K2_FCR10		0x24
++
++/* GPIO registers */
++#define KEYLARGO_GPIO_LEVELS0		0x50
++#define KEYLARGO_GPIO_LEVELS1		0x54
++#define KEYLARGO_GPIO_EXTINT_0		0x58
++#define KEYLARGO_GPIO_EXTINT_CNT	18
++#define KEYLARGO_GPIO_0			0x6A
++#define KEYLARGO_GPIO_CNT		17
++#define KEYLARGO_GPIO_EXTINT_DUAL_EDGE	0x80
++#define KEYLARGO_GPIO_OUTPUT_ENABLE	0x04
++#define KEYLARGO_GPIO_OUTOUT_DATA	0x01
++#define KEYLARGO_GPIO_INPUT_DATA	0x02
++
++/* K2 does only extint GPIOs and does 51 of them */
++#define K2_GPIO_EXTINT_0		0x58
++#define K2_GPIO_EXTINT_CNT		51
++
++/* Specific GPIO regs */
++
++#define KL_GPIO_MODEM_RESET		(KEYLARGO_GPIO_0+0x03)
++#define KL_GPIO_MODEM_POWER		(KEYLARGO_GPIO_0+0x02) /* Pangea */
++
++#define KL_GPIO_SOUND_POWER		(KEYLARGO_GPIO_0+0x05)
++
++/* Hrm... this one is only to be used on Pismo. It seeem to also
++ * control the timebase enable on other machines. Still to be
++ * experimented... --BenH.
++ */
++#define KL_GPIO_FW_CABLE_POWER		(KEYLARGO_GPIO_0+0x09)
++#define KL_GPIO_TB_ENABLE		(KEYLARGO_GPIO_0+0x09)
++
++#define KL_GPIO_ETH_PHY_RESET		(KEYLARGO_GPIO_0+0x10)
++
++#define KL_GPIO_EXTINT_CPU1		(KEYLARGO_GPIO_0+0x0a)
++#define KL_GPIO_EXTINT_CPU1_ASSERT	0x04
++#define KL_GPIO_EXTINT_CPU1_RELEASE	0x38
++
++#define KL_GPIO_RESET_CPU0		(KEYLARGO_GPIO_EXTINT_0+0x03)
++#define KL_GPIO_RESET_CPU1		(KEYLARGO_GPIO_EXTINT_0+0x04)
++#define KL_GPIO_RESET_CPU2		(KEYLARGO_GPIO_EXTINT_0+0x0f)
++#define KL_GPIO_RESET_CPU3		(KEYLARGO_GPIO_EXTINT_0+0x10)
++
++#define KL_GPIO_PMU_MESSAGE_IRQ		(KEYLARGO_GPIO_EXTINT_0+0x09)
++#define KL_GPIO_PMU_MESSAGE_BIT		KEYLARGO_GPIO_INPUT_DATA
++
++#define KL_GPIO_MEDIABAY_IRQ		(KEYLARGO_GPIO_EXTINT_0+0x0e)
++
++#define KL_GPIO_AIRPORT_0		(KEYLARGO_GPIO_EXTINT_0+0x0a)
++#define KL_GPIO_AIRPORT_1		(KEYLARGO_GPIO_EXTINT_0+0x0d)
++#define KL_GPIO_AIRPORT_2		(KEYLARGO_GPIO_0+0x0d)
++#define KL_GPIO_AIRPORT_3		(KEYLARGO_GPIO_0+0x0e)
++#define KL_GPIO_AIRPORT_4		(KEYLARGO_GPIO_0+0x0f)
++
++/*
++ * Bits in feature control register. Those bits different for K2 are
++ * listed separately
++ */
++#define KL_MBCR_MB0_PCI_ENABLE		0x00000800	/* exist ? */
++#define KL_MBCR_MB0_IDE_ENABLE		0x00001000
++#define KL_MBCR_MB0_FLOPPY_ENABLE	0x00002000	/* exist ? */
++#define KL_MBCR_MB0_SOUND_ENABLE	0x00004000	/* hrm... */
++#define KL_MBCR_MB0_DEV_MASK		0x00007800
++#define KL_MBCR_MB0_DEV_POWER		0x00000400
++#define KL_MBCR_MB0_DEV_RESET		0x00000200
++#define KL_MBCR_MB0_ENABLE		0x00000100
++#define KL_MBCR_MB1_PCI_ENABLE		0x08000000	/* exist ? */
++#define KL_MBCR_MB1_IDE_ENABLE		0x10000000
++#define KL_MBCR_MB1_FLOPPY_ENABLE	0x20000000	/* exist ? */
++#define KL_MBCR_MB1_SOUND_ENABLE	0x40000000	/* hrm... */
++#define KL_MBCR_MB1_DEV_MASK		0x78000000
++#define KL_MBCR_MB1_DEV_POWER		0x04000000
++#define KL_MBCR_MB1_DEV_RESET		0x02000000
++#define KL_MBCR_MB1_ENABLE		0x01000000
++
++#define KL0_SCC_B_INTF_ENABLE		0x00000001	/* (KL Only) */
++#define KL0_SCC_A_INTF_ENABLE		0x00000002
++#define KL0_SCC_SLOWPCLK		0x00000004
++#define KL0_SCC_RESET			0x00000008
++#define KL0_SCCA_ENABLE			0x00000010
++#define KL0_SCCB_ENABLE			0x00000020
++#define KL0_SCC_CELL_ENABLE		0x00000040
++#define KL0_IRDA_HIGH_BAND		0x00000100	/* (KL Only) */
++#define KL0_IRDA_SOURCE2_SEL		0x00000200	/* (KL Only) */
++#define KL0_IRDA_SOURCE1_SEL		0x00000400	/* (KL Only) */
++#define KL0_PG_USB0_PMI_ENABLE		0x00000400	/* (Pangea/Intrepid Only) */
++#define KL0_IRDA_RESET			0x00000800	/* (KL Only) */
++#define KL0_PG_USB0_REF_SUSPEND_SEL	0x00000800	/* (Pangea/Intrepid Only) */
++#define KL0_IRDA_DEFAULT1		0x00001000	/* (KL Only) */
++#define KL0_PG_USB0_REF_SUSPEND		0x00001000	/* (Pangea/Intrepid Only) */
++#define KL0_IRDA_DEFAULT0		0x00002000	/* (KL Only) */
++#define KL0_PG_USB0_PAD_SUSPEND		0x00002000	/* (Pangea/Intrepid Only) */
++#define KL0_IRDA_FAST_CONNECT		0x00004000	/* (KL Only) */
++#define KL0_PG_USB1_PMI_ENABLE		0x00004000	/* (Pangea/Intrepid Only) */
++#define KL0_IRDA_ENABLE			0x00008000	/* (KL Only) */
++#define KL0_PG_USB1_REF_SUSPEND_SEL	0x00008000	/* (Pangea/Intrepid Only) */
++#define KL0_IRDA_CLK32_ENABLE		0x00010000	/* (KL Only) */
++#define KL0_PG_USB1_REF_SUSPEND		0x00010000	/* (Pangea/Intrepid Only) */
++#define KL0_IRDA_CLK19_ENABLE		0x00020000	/* (KL Only) */
++#define KL0_PG_USB1_PAD_SUSPEND		0x00020000	/* (Pangea/Intrepid Only) */
++#define KL0_USB0_PAD_SUSPEND0		0x00040000
++#define KL0_USB0_PAD_SUSPEND1		0x00080000
++#define KL0_USB0_CELL_ENABLE		0x00100000
++#define KL0_USB1_PAD_SUSPEND0		0x00400000
++#define KL0_USB1_PAD_SUSPEND1		0x00800000
++#define KL0_USB1_CELL_ENABLE		0x01000000
++#define KL0_USB_REF_SUSPEND		0x10000000	/* (KL Only) */
++
++#define KL0_SERIAL_ENABLE		(KL0_SCC_B_INTF_ENABLE | \
++					KL0_SCC_SLOWPCLK | \
++					KL0_SCC_CELL_ENABLE | KL0_SCCA_ENABLE)
++
++#define KL1_USB2_PMI_ENABLE		0x00000001	/* Intrepid only */
++#define KL1_AUDIO_SEL_22MCLK		0x00000002	/* KL/Pangea only */
++#define KL1_USB2_REF_SUSPEND_SEL	0x00000002	/* Intrepid only */
++#define KL1_USB2_REF_SUSPEND		0x00000004	/* Intrepid only */
++#define KL1_AUDIO_CLK_ENABLE_BIT	0x00000008	/* KL/Pangea only */
++#define KL1_USB2_PAD_SUSPEND_SEL	0x00000008	/* Intrepid only */
++#define KL1_USB2_PAD_SUSPEND0		0x00000010	/* Intrepid only */
++#define KL1_AUDIO_CLK_OUT_ENABLE	0x00000020	/* KL/Pangea only */
++#define KL1_USB2_PAD_SUSPEND1		0x00000020	/* Intrepid only */
++#define KL1_AUDIO_CELL_ENABLE		0x00000040	/* KL/Pangea only */
++#define KL1_USB2_CELL_ENABLE		0x00000040	/* Intrepid only */
++#define KL1_AUDIO_CHOOSE		0x00000080	/* KL/Pangea only */
++#define KL1_I2S0_CHOOSE			0x00000200	/* KL Only */
++#define KL1_I2S0_CELL_ENABLE		0x00000400
++#define KL1_I2S0_CLK_ENABLE_BIT		0x00001000
++#define KL1_I2S0_ENABLE			0x00002000
++#define KL1_I2S1_CELL_ENABLE		0x00020000
++#define KL1_I2S1_CLK_ENABLE_BIT		0x00080000
++#define KL1_I2S1_ENABLE			0x00100000
++#define KL1_EIDE0_ENABLE		0x00800000	/* KL/Intrepid Only */
++#define KL1_EIDE0_RESET_N		0x01000000	/* KL/Intrepid Only */
++#define KL1_EIDE1_ENABLE		0x04000000	/* KL Only */
++#define KL1_EIDE1_RESET_N		0x08000000	/* KL Only */
++#define KL1_UIDE_ENABLE			0x20000000	/* KL/Pangea Only */
++#define KL1_UIDE_RESET_N		0x40000000	/* KL/Pangea Only */
++
++#define KL2_IOBUS_ENABLE		0x00000002
++#define KL2_SLEEP_STATE_BIT		0x00000100	/* KL Only */
++#define KL2_PG_STOP_ALL_CLOCKS		0x00000100	/* Pangea Only */
++#define KL2_MPIC_ENABLE			0x00020000
++#define KL2_CARDSLOT_RESET		0x00040000	/* Pangea/Intrepid Only */
++#define KL2_ALT_DATA_OUT		0x02000000	/* KL Only ??? */
++#define KL2_MEM_IS_BIG			0x04000000
++#define KL2_CARDSEL_16			0x08000000
++
++#define KL3_SHUTDOWN_PLL_TOTAL		0x00000001	/* KL/Pangea only */
++#define KL3_SHUTDOWN_PLLKW6		0x00000002	/* KL/Pangea only */
++#define KL3_IT_SHUTDOWN_PLL3		0x00000002	/* Intrepid only */
++#define KL3_SHUTDOWN_PLLKW4		0x00000004	/* KL/Pangea only */
++#define KL3_IT_SHUTDOWN_PLL2		0x00000004	/* Intrepid only */
++#define KL3_SHUTDOWN_PLLKW35		0x00000008	/* KL/Pangea only */
++#define KL3_IT_SHUTDOWN_PLL1		0x00000008	/* Intrepid only */
++#define KL3_SHUTDOWN_PLLKW12		0x00000010	/* KL Only */
++#define KL3_IT_ENABLE_PLL3_SHUTDOWN	0x00000010	/* Intrepid only */
++#define KL3_PLL_RESET			0x00000020	/* KL/Pangea only */
++#define KL3_IT_ENABLE_PLL2_SHUTDOWN	0x00000020	/* Intrepid only */
++#define KL3_IT_ENABLE_PLL1_SHUTDOWN	0x00000010	/* Intrepid only */
++#define KL3_SHUTDOWN_PLL2X		0x00000080	/* KL Only */
++#define KL3_CLK66_ENABLE		0x00000100	/* KL Only */
++#define KL3_CLK49_ENABLE		0x00000200
++#define KL3_CLK45_ENABLE		0x00000400
++#define KL3_CLK31_ENABLE		0x00000800	/* KL/Pangea only */
++#define KL3_TIMER_CLK18_ENABLE		0x00001000
++#define KL3_I2S1_CLK18_ENABLE		0x00002000
++#define KL3_I2S0_CLK18_ENABLE		0x00004000
++#define KL3_VIA_CLK16_ENABLE		0x00008000	/* KL/Pangea only */
++#define KL3_IT_VIA_CLK32_ENABLE		0x00008000	/* Intrepid only */
++#define KL3_STOPPING33_ENABLED		0x00080000	/* KL Only */
++#define KL3_PG_PLL_ENABLE_TEST		0x00080000	/* Pangea Only */
++
++/* Intrepid USB bus 2, port 0,1 */
++#define KL3_IT_PORT_WAKEUP_ENABLE(p)		(0x00080000 << ((p)<<3))
++#define KL3_IT_PORT_RESUME_WAKE_EN(p)		(0x00040000 << ((p)<<3))
++#define KL3_IT_PORT_CONNECT_WAKE_EN(p)		(0x00020000 << ((p)<<3))
++#define KL3_IT_PORT_DISCONNECT_WAKE_EN(p)	(0x00010000 << ((p)<<3))
++#define KL3_IT_PORT_RESUME_STAT(p)		(0x00300000 << ((p)<<3))
++#define KL3_IT_PORT_CONNECT_STAT(p)		(0x00200000 << ((p)<<3))
++#define KL3_IT_PORT_DISCONNECT_STAT(p)		(0x00100000 << ((p)<<3))
++
++/* Port 0,1 : bus 0, port 2,3 : bus 1 */
++#define KL4_PORT_WAKEUP_ENABLE(p)	(0x00000008 << ((p)<<3))
++#define KL4_PORT_RESUME_WAKE_EN(p)	(0x00000004 << ((p)<<3))
++#define KL4_PORT_CONNECT_WAKE_EN(p)	(0x00000002 << ((p)<<3))
++#define KL4_PORT_DISCONNECT_WAKE_EN(p)	(0x00000001 << ((p)<<3))
++#define KL4_PORT_RESUME_STAT(p)		(0x00000040 << ((p)<<3))
++#define KL4_PORT_CONNECT_STAT(p)	(0x00000020 << ((p)<<3))
++#define KL4_PORT_DISCONNECT_STAT(p)	(0x00000010 << ((p)<<3))
++
++/* Pangea and Intrepid only */
++#define KL5_VIA_USE_CLK31		0000000001	/* Pangea Only */
++#define KL5_SCC_USE_CLK31		0x00000002	/* Pangea Only */
++#define KL5_PWM_CLK32_EN		0x00000004
++#define KL5_CLK3_68_EN			0x00000010
++#define KL5_CLK32_EN			0x00000020
++
++
++/* K2 definitions */
++#define K2_FCR0_USB0_SWRESET		0x00200000
++#define K2_FCR0_USB1_SWRESET		0x02000000
++#define K2_FCR0_RING_PME_DISABLE	0x08000000
++
++#define K2_FCR1_PCI1_BUS_RESET_N	0x00000010
++#define K2_FCR1_PCI1_SLEEP_RESET_EN	0x00000020
++#define K2_FCR1_I2S0_CELL_ENABLE	0x00000400
++#define K2_FCR1_I2S0_RESET		0x00000800
++#define K2_FCR1_I2S0_CLK_ENABLE_BIT	0x00001000
++#define K2_FCR1_I2S0_ENABLE    		0x00002000
++
++#define K2_FCR1_PCI1_CLK_ENABLE		0x00004000
++#define K2_FCR1_FW_CLK_ENABLE		0x00008000
++#define K2_FCR1_FW_RESET_N		0x00010000
++#define K2_FCR1_GMAC_CLK_ENABLE		0x00400000
++#define K2_FCR1_GMAC_POWER_DOWN		0x00800000
++#define K2_FCR1_GMAC_RESET_N		0x01000000
++#define K2_FCR1_SATA_CLK_ENABLE		0x02000000
++#define K2_FCR1_SATA_POWER_DOWN		0x04000000
++#define K2_FCR1_SATA_RESET_N		0x08000000
++#define K2_FCR1_UATA_CLK_ENABLE		0x10000000
++#define K2_FCR1_UATA_RESET_N		0x40000000
++#define K2_FCR1_UATA_CHOOSE_CLK66	0x80000000
++
+diff --git a/include/asm-powerpc/kmap_types.h b/include/asm-powerpc/kmap_types.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/kmap_types.h
+@@ -0,0 +1,33 @@
++#ifndef _ASM_POWERPC_KMAP_TYPES_H
++#define _ASM_POWERPC_KMAP_TYPES_H
++
++#ifdef __KERNEL__
++
++/*
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++enum km_type {
++	KM_BOUNCE_READ,
++	KM_SKB_SUNRPC_DATA,
++	KM_SKB_DATA_SOFTIRQ,
++	KM_USER0,
++	KM_USER1,
++	KM_BIO_SRC_IRQ,
++	KM_BIO_DST_IRQ,
++	KM_PTE0,
++	KM_PTE1,
++	KM_IRQ0,
++	KM_IRQ1,
++	KM_SOFTIRQ0,
++	KM_SOFTIRQ1,
++	KM_PPC_SYNC_PAGE,
++	KM_PPC_SYNC_ICACHE,
++	KM_TYPE_NR
++};
++
++#endif	/* __KERNEL__ */
++#endif	/* _ASM_POWERPC_KMAP_TYPES_H */
+diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/kprobes.h
+@@ -0,0 +1,66 @@
++#ifndef _ASM_POWERPC_KPROBES_H
++#define _ASM_POWERPC_KPROBES_H
++/*
++ *  Kernel Probes (KProbes)
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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.
++ *
++ * Copyright (C) IBM Corporation, 2002, 2004
++ *
++ * 2002-Oct	Created by Vamsi Krishna S <vamsi_krishna at in.ibm.com> Kernel
++ *		Probes initial implementation ( includes suggestions from
++ *		Rusty Russell).
++ * 2004-Nov	Modified for PPC64 by Ananth N Mavinakayanahalli
++ *		<ananth at in.ibm.com>
++ */
++#include <linux/types.h>
++#include <linux/ptrace.h>
++
++struct pt_regs;
++
++typedef unsigned int kprobe_opcode_t;
++#define BREAKPOINT_INSTRUCTION	0x7fe00008	/* trap */
++#define MAX_INSN_SIZE 1
++
++#define IS_TW(instr)		(((instr) & 0xfc0007fe) == 0x7c000008)
++#define IS_TD(instr)		(((instr) & 0xfc0007fe) == 0x7c000088)
++#define IS_TDI(instr)		(((instr) & 0xfc000000) == 0x08000000)
++#define IS_TWI(instr)		(((instr) & 0xfc000000) == 0x0c000000)
++
++#define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)((func_descr_t *)pentry)
++
++#define is_trap(instr)	(IS_TW(instr) || IS_TD(instr) || \
++			IS_TWI(instr) || IS_TDI(instr))
++
++#define ARCH_SUPPORTS_KRETPROBES
++void kretprobe_trampoline(void);
++
++/* Architecture specific copy of original instruction */
++struct arch_specific_insn {
++	/* copy of original instruction */
++	kprobe_opcode_t *insn;
++};
++
++#ifdef CONFIG_KPROBES
++extern int kprobe_exceptions_notify(struct notifier_block *self,
++				    unsigned long val, void *data);
++#else				/* !CONFIG_KPROBES */
++static inline int kprobe_exceptions_notify(struct notifier_block *self,
++					   unsigned long val, void *data)
++{
++	return 0;
++}
++#endif
++#endif	/* _ASM_POWERPC_KPROBES_H */
+diff --git a/include/asm-powerpc/lmb.h b/include/asm-powerpc/lmb.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/lmb.h
+@@ -0,0 +1,81 @@
++#ifndef _PPC64_LMB_H
++#define _PPC64_LMB_H
++
++/*
++ * Definitions for talking to the Open Firmware PROM on
++ * Power Macintosh computers.
++ *
++ * Copyright (C) 2001 Peter Bergner, IBM Corp.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++#include <linux/init.h>
++#include <asm/prom.h>
++
++#define MAX_LMB_REGIONS 128
++
++#define LMB_ALLOC_ANYWHERE	0
++
++struct lmb_property {
++	unsigned long base;
++	unsigned long size;
++};
++
++struct lmb_region {
++	unsigned long cnt;
++	unsigned long size;
++	struct lmb_property region[MAX_LMB_REGIONS+1];
++};
++
++struct lmb {
++	unsigned long debug;
++	unsigned long rmo_size;
++	struct lmb_region memory;
++	struct lmb_region reserved;
++};
++
++extern struct lmb lmb;
++
++extern void __init lmb_init(void);
++extern void __init lmb_analyze(void);
++extern long __init lmb_add(unsigned long, unsigned long);
++extern long __init lmb_reserve(unsigned long, unsigned long);
++extern unsigned long __init lmb_alloc(unsigned long, unsigned long);
++extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long,
++					   unsigned long);
++extern unsigned long __init lmb_phys_mem_size(void);
++extern unsigned long __init lmb_end_of_DRAM(void);
++extern unsigned long __init lmb_abs_to_phys(unsigned long);
++extern void __init lmb_enforce_memory_limit(unsigned long);
++
++extern void lmb_dump_all(void);
++
++extern unsigned long io_hole_start;
++
++static inline unsigned long
++lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
++{
++	return type->region[region_nr].size;
++}
++static inline unsigned long
++lmb_size_pages(struct lmb_region *type, unsigned long region_nr)
++{
++	return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT;
++}
++static inline unsigned long
++lmb_start_pfn(struct lmb_region *type, unsigned long region_nr)
++{
++	return type->region[region_nr].base >> PAGE_SHIFT;
++}
++static inline unsigned long
++lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
++{
++	return lmb_start_pfn(type, region_nr) +
++	       lmb_size_pages(type, region_nr);
++}
++
++#endif /* _PPC64_LMB_H */
+diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/machdep.h
+@@ -0,0 +1,284 @@
++#ifndef _ASM_POWERPC_MACHDEP_H
++#define _ASM_POWERPC_MACHDEP_H
++#ifdef __KERNEL__
++
++/*
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/seq_file.h>
++#include <linux/init.h>
++#include <linux/dma-mapping.h>
++
++#include <asm/setup.h>
++
++/* We export this macro for external modules like Alsa to know if
++ * ppc_md.feature_call is implemented or not
++ */
++#define CONFIG_PPC_HAS_FEATURE_CALLS
++
++struct pt_regs;
++struct pci_bus;	
++struct device_node;
++struct iommu_table;
++struct rtc_time;
++struct file;
++
++#ifdef CONFIG_SMP
++struct smp_ops_t {
++	void  (*message_pass)(int target, int msg);
++	int   (*probe)(void);
++	void  (*kick_cpu)(int nr);
++	void  (*setup_cpu)(int nr);
++	void  (*take_timebase)(void);
++	void  (*give_timebase)(void);
++	int   (*cpu_enable)(unsigned int nr);
++	int   (*cpu_disable)(void);
++	void  (*cpu_die)(unsigned int nr);
++	int   (*cpu_bootable)(unsigned int nr);
++};
++#endif
++
++struct machdep_calls {
++#ifdef CONFIG_PPC64
++	void            (*hpte_invalidate)(unsigned long slot,
++					   unsigned long va,
++					   int large,
++					   int local);
++	long		(*hpte_updatepp)(unsigned long slot, 
++					 unsigned long newpp, 
++					 unsigned long va,
++					 int large,
++					 int local);
++	void            (*hpte_updateboltedpp)(unsigned long newpp, 
++					       unsigned long ea);
++	long		(*hpte_insert)(unsigned long hpte_group,
++				       unsigned long va,
++				       unsigned long prpn,
++				       unsigned long vflags,
++				       unsigned long rflags);
++	long		(*hpte_remove)(unsigned long hpte_group);
++	void		(*flush_hash_range)(unsigned long number, int local);
++
++	/* special for kexec, to be called in real mode, linar mapping is
++	 * destroyed as well */
++	void		(*hpte_clear_all)(void);
++
++	void		(*tce_build)(struct iommu_table * tbl,
++				     long index,
++				     long npages,
++				     unsigned long uaddr,
++				     enum dma_data_direction direction);
++	void		(*tce_free)(struct iommu_table *tbl,
++				    long index,
++				    long npages);
++	void		(*tce_flush)(struct iommu_table *tbl);
++	void		(*iommu_dev_setup)(struct pci_dev *dev);
++	void		(*iommu_bus_setup)(struct pci_bus *bus);
++	void		(*irq_bus_setup)(struct pci_bus *bus);
++#endif
++
++	int		(*probe)(int platform);
++	void		(*setup_arch)(void);
++	void		(*init_early)(void);
++	/* Optional, may be NULL. */
++	void		(*show_cpuinfo)(struct seq_file *m);
++	void		(*show_percpuinfo)(struct seq_file *m, int i);
++
++	void		(*init_IRQ)(void);
++	int		(*get_irq)(struct pt_regs *);
++	void		(*cpu_irq_down)(int secondary);
++
++	/* PCI stuff */
++	/* Called after scanning the bus, before allocating resources */
++	void		(*pcibios_fixup)(void);
++	int		(*pci_probe_mode)(struct pci_bus *);
++
++	void		(*restart)(char *cmd);
++	void		(*power_off)(void);
++	void		(*halt)(void);
++	void		(*panic)(char *str);
++	void		(*cpu_die)(void);
++
++	long		(*time_init)(void); /* Optional, may be NULL */
++
++	int		(*set_rtc_time)(struct rtc_time *);
++	void		(*get_rtc_time)(struct rtc_time *);
++	unsigned long	(*get_boot_time)(void);
++	unsigned char 	(*rtc_read_val)(int addr);
++	void		(*rtc_write_val)(int addr, unsigned char val);
++
++	void		(*calibrate_decr)(void);
++
++	void		(*progress)(char *, unsigned short);
++
++	/* Interface for platform error logging */
++	void 		(*log_error)(char *buf, unsigned int err_type, int fatal);
++
++	unsigned char 	(*nvram_read_val)(int addr);
++	void		(*nvram_write_val)(int addr, unsigned char val);
++	ssize_t		(*nvram_write)(char *buf, size_t count, loff_t *index);
++	ssize_t		(*nvram_read)(char *buf, size_t count, loff_t *index);	
++	ssize_t		(*nvram_size)(void);		
++	void		(*nvram_sync)(void);
++
++	/* Exception handlers */
++	void		(*system_reset_exception)(struct pt_regs *regs);
++	int 		(*machine_check_exception)(struct pt_regs *regs);
++
++	/* Motherboard/chipset features. This is a kind of general purpose
++	 * hook used to control some machine specific features (like reset
++	 * lines, chip power control, etc...).
++	 */
++	long	 	(*feature_call)(unsigned int feature, ...);
++
++	/* Check availability of legacy devices like i8042 */
++	int 		(*check_legacy_ioport)(unsigned int baseport);
++
++	/* Get legacy PCI/IDE interrupt mapping */ 
++	int		(*pci_get_legacy_ide_irq)(struct pci_dev *dev, int channel);
++	
++	/* Get access protection for /dev/mem */
++	pgprot_t	(*phys_mem_access_prot)(struct file *file,
++						unsigned long pfn,
++						unsigned long size,
++						pgprot_t vma_prot);
++
++	/* Idle loop for this platform, leave empty for default idle loop */
++	void		(*idle_loop)(void);
++
++	/* Function to enable performance monitor counters for this
++	   platform, called once per cpu. */
++	void		(*enable_pmcs)(void);
++
++#ifdef CONFIG_PPC32	/* XXX for now */
++	/* A general init function, called by ppc_init in init/main.c.
++	   May be NULL. */
++	void		(*init)(void);
++
++	void		(*idle)(void);
++	void		(*power_save)(void);
++
++	void		(*heartbeat)(void);
++	unsigned long	heartbeat_reset;
++	unsigned long	heartbeat_count;
++
++	void		(*setup_io_mappings)(void);
++
++	void		(*early_serial_map)(void);
++	void		(*kgdb_map_scc)(void);
++
++	/*
++	 * optional PCI "hooks"
++	 */
++
++	/* Called after PPC generic resource fixup to perform
++	   machine specific fixups */
++	void (*pcibios_fixup_resources)(struct pci_dev *);
++
++	/* Called for each PCI bus in the system when it's probed */
++	void (*pcibios_fixup_bus)(struct pci_bus *);
++
++	/* Called when pci_enable_device() is called (initial=0) or
++	 * when a device with no assigned resource is found (initial=1).
++	 * Returns 0 to allow assignment/enabling of the device. */
++	int  (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
++
++	/* For interrupt routing */
++	unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *);
++	int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char);
++
++	/* Called in indirect_* to avoid touching devices */
++	int (*pci_exclude_device)(unsigned char, unsigned char);
++
++	/* Called at then very end of pcibios_init() */
++	void (*pcibios_after_init)(void);
++
++	/* this is for modules, since _machine can be a define -- Cort */
++	int ppc_machine;
++
++#ifdef CONFIG_KEXEC
++	/* Called to shutdown machine specific hardware not already controlled
++	 * by other drivers.
++	 * XXX Should we move this one out of kexec scope?
++	 */
++	void (*machine_shutdown)(void);
++
++	/* Called to do the minimal shutdown needed to run a kexec'd kernel
++	 * to run successfully.
++	 * XXX Should we move this one out of kexec scope?
++	 */
++	void (*machine_crash_shutdown)(void);
++
++	/* Called to do what every setup is needed on image and the
++	 * reboot code buffer. Returns 0 on success.
++	 * Provide your own (maybe dummy) implementation if your platform
++	 * claims to support kexec.
++	 */
++	int (*machine_kexec_prepare)(struct kimage *image);
++
++	/* Called to handle any machine specific cleanup on image */
++	void (*machine_kexec_cleanup)(struct kimage *image);
++
++	/* Called to perform the _real_ kexec.
++	 * Do NOT allocate memory or fail here. We are past the point of
++	 * no return.
++	 */
++	void (*machine_kexec)(struct kimage *image);
++#endif /* CONFIG_KEXEC */
++#endif /* CONFIG_PPC32 */
++};
++
++extern void default_idle(void);
++extern void native_idle(void);
++
++extern struct machdep_calls ppc_md;
++extern char cmd_line[COMMAND_LINE_SIZE];
++
++#ifdef CONFIG_PPC_PMAC
++/*
++ * Power macintoshes have either a CUDA, PMU or SMU controlling
++ * system reset, power, NVRAM, RTC.
++ */
++typedef enum sys_ctrler_kind {
++	SYS_CTRLER_UNKNOWN = 0,
++	SYS_CTRLER_CUDA = 1,
++	SYS_CTRLER_PMU = 2,
++	SYS_CTRLER_SMU = 3,
++} sys_ctrler_t;
++extern sys_ctrler_t sys_ctrler;
++
++#endif /* CONFIG_PPC_PMAC */
++
++extern void setup_pci_ptrs(void);
++
++#ifdef CONFIG_SMP
++/* Poor default implementations */
++extern void __devinit smp_generic_give_timebase(void);
++extern void __devinit smp_generic_take_timebase(void);
++#endif /* CONFIG_SMP */
++
++
++/* Functions to produce codes on the leds.
++ * The SRC code should be unique for the message category and should
++ * be limited to the lower 24 bits (the upper 8 are set by these funcs),
++ * and (for boot & dump) should be sorted numerically in the order
++ * the events occur.
++ */
++/* Print a boot progress message. */
++void ppc64_boot_msg(unsigned int src, const char *msg);
++/* Print a termination message (print only -- does not stop the kernel) */
++void ppc64_terminate_msg(unsigned int src, const char *msg);
++
++static inline void log_error(char *buf, unsigned int err_type, int fatal)
++{
++	if (ppc_md.log_error)
++		ppc_md.log_error(buf, err_type, fatal);
++}
++
++#endif /* __KERNEL__ */
++#endif /* _ASM_POWERPC_MACHDEP_H */
+diff --git a/include/asm-powerpc/macio.h b/include/asm-powerpc/macio.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/macio.h
+@@ -0,0 +1,140 @@
++#ifndef __MACIO_ASIC_H__
++#define __MACIO_ASIC_H__
++
++#include <asm/of_device.h>
++
++extern struct bus_type macio_bus_type;
++
++/* MacIO device driver is defined later */
++struct macio_driver;
++struct macio_chip;
++
++#define MACIO_DEV_COUNT_RESOURCES	8
++#define MACIO_DEV_COUNT_IRQS		8
++
++/*
++ * the macio_bus structure is used to describe a "virtual" bus
++ * within a MacIO ASIC. It's typically provided by a macio_pci_asic
++ * PCI device, but could be provided differently as well (nubus
++ * machines using a fake OF tree).
++ *
++ * The pdev field can be NULL on non-PCI machines
++ */
++struct macio_bus
++{
++	struct macio_chip	*chip;		/* macio_chip (private use) */
++	int			index;		/* macio chip index in system */
++#ifdef CONFIG_PCI
++	struct pci_dev		*pdev;		/* PCI device hosting this bus */
++#endif
++};
++
++/*
++ * the macio_dev structure is used to describe a device
++ * within an Apple MacIO ASIC.
++ */
++struct macio_dev
++{
++	struct macio_bus	*bus;		/* macio bus this device is on */
++	struct macio_dev	*media_bay;	/* Device is part of a media bay */
++	struct of_device	ofdev;
++	int			n_resources;
++	struct resource		resource[MACIO_DEV_COUNT_RESOURCES];
++	int			n_interrupts;
++	struct resource		interrupt[MACIO_DEV_COUNT_IRQS];
++};
++#define	to_macio_device(d) container_of(d, struct macio_dev, ofdev.dev)
++#define	of_to_macio_device(d) container_of(d, struct macio_dev, ofdev)
++
++extern struct macio_dev *macio_dev_get(struct macio_dev *dev);
++extern void macio_dev_put(struct macio_dev *dev);
++
++/*
++ * Accessors to resources & interrupts and other device
++ * fields
++ */
++
++static inline int macio_resource_count(struct macio_dev *dev)
++{
++	return dev->n_resources;
++}
++
++static inline unsigned long macio_resource_start(struct macio_dev *dev, int resource_no)
++{
++	return dev->resource[resource_no].start;
++}
++
++static inline unsigned long macio_resource_end(struct macio_dev *dev, int resource_no)
++{
++	return dev->resource[resource_no].end;
++}
++
++static inline unsigned long macio_resource_len(struct macio_dev *dev, int resource_no)
++{
++	struct resource *res = &dev->resource[resource_no];
++	if (res->start == 0 || res->end == 0 || res->end < res->start)
++		return 0;
++	return res->end - res->start + 1;
++}
++
++extern int macio_request_resource(struct macio_dev *dev, int resource_no, const char *name);
++extern void macio_release_resource(struct macio_dev *dev, int resource_no);
++extern int macio_request_resources(struct macio_dev *dev, const char *name);
++extern void macio_release_resources(struct macio_dev *dev);
++
++static inline int macio_irq_count(struct macio_dev *dev)
++{
++	return dev->n_interrupts;
++}
++
++static inline int macio_irq(struct macio_dev *dev, int irq_no)
++{
++	return dev->interrupt[irq_no].start;
++}
++
++static inline void macio_set_drvdata(struct macio_dev *dev, void *data)
++{
++	dev_set_drvdata(&dev->ofdev.dev, data);
++}
++
++static inline void* macio_get_drvdata(struct macio_dev *dev)
++{
++	return dev_get_drvdata(&dev->ofdev.dev);
++}
++
++static inline struct device_node *macio_get_of_node(struct macio_dev *mdev)
++{
++	return mdev->ofdev.node;
++}
++
++#ifdef CONFIG_PCI
++static inline struct pci_dev *macio_get_pci_dev(struct macio_dev *mdev)
++{
++	return mdev->bus->pdev;
++}
++#endif
++
++/*
++ * A driver for a mac-io chip based device
++ */
++struct macio_driver
++{
++	char			*name;
++	struct of_device_id	*match_table;
++	struct module		*owner;
++
++	int	(*probe)(struct macio_dev* dev, const struct of_device_id *match);
++	int	(*remove)(struct macio_dev* dev);
++
++	int	(*suspend)(struct macio_dev* dev, pm_message_t state);
++	int	(*resume)(struct macio_dev* dev);
++	int	(*shutdown)(struct macio_dev* dev);
++
++	struct device_driver	driver;
++};
++#define	to_macio_driver(drv) container_of(drv,struct macio_driver, driver)
++
++extern int macio_register_driver(struct macio_driver *);
++extern void macio_unregister_driver(struct macio_driver *);
++
++#endif /* __MACIO_ASIC_H__ */
+diff --git a/include/asm-powerpc/mediabay.h b/include/asm-powerpc/mediabay.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/mediabay.h
+@@ -0,0 +1,31 @@
++/*
++ * mediabay.h: definitions for using the media bay
++ * on PowerBook 3400 and similar computers.
++ *
++ * Copyright (C) 1997 Paul Mackerras.
++ */
++#ifndef _PPC_MEDIABAY_H
++#define _PPC_MEDIABAY_H
++
++#ifdef __KERNEL__
++
++#define MB_FD		0	/* media bay contains floppy drive (automatic eject ?) */
++#define MB_FD1		1	/* media bay contains floppy drive (manual eject ?) */
++#define MB_SOUND	2	/* sound device ? */
++#define MB_CD		3	/* media bay contains ATA drive such as CD or ZIP */
++#define MB_PCI		5	/* media bay contains a PCI device */
++#define MB_POWER	6	/* media bay contains a Power device (???) */
++#define MB_NO		7	/* media bay contains nothing */
++
++int check_media_bay(struct device_node *which_bay, int what);
++int check_media_bay_by_base(unsigned long base, int what);
++
++/* Number of bays in the machine or 0 */
++extern int media_bay_count;
++
++/* called by pmac-ide.c to register IDE controller for media bay */
++extern int media_bay_set_ide_infos(struct device_node* which_bay,
++			unsigned long base, int irq, int index);
++
++#endif /* __KERNEL__ */
++#endif /* _PPC_MEDIABAY_H */
+diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/mpic.h
+@@ -0,0 +1,287 @@
++#ifndef _ASM_POWERPC_MPIC_H
++#define _ASM_POWERPC_MPIC_H
++
++#include <linux/irq.h>
++
++/*
++ * Global registers
++ */
++
++#define MPIC_GREG_BASE			0x01000
++
++#define MPIC_GREG_FEATURE_0		0x00000
++#define		MPIC_GREG_FEATURE_LAST_SRC_MASK		0x07ff0000
++#define		MPIC_GREG_FEATURE_LAST_SRC_SHIFT	16
++#define		MPIC_GREG_FEATURE_LAST_CPU_MASK		0x00001f00
++#define		MPIC_GREG_FEATURE_LAST_CPU_SHIFT	8
++#define		MPIC_GREG_FEATURE_VERSION_MASK		0xff
++#define MPIC_GREG_FEATURE_1		0x00010
++#define MPIC_GREG_GLOBAL_CONF_0		0x00020
++#define		MPIC_GREG_GCONF_RESET			0x80000000
++#define		MPIC_GREG_GCONF_8259_PTHROU_DIS		0x20000000
++#define		MPIC_GREG_GCONF_BASE_MASK		0x000fffff
++#define MPIC_GREG_GLOBAL_CONF_1		0x00030
++#define MPIC_GREG_VENDOR_0		0x00040
++#define MPIC_GREG_VENDOR_1		0x00050
++#define MPIC_GREG_VENDOR_2		0x00060
++#define MPIC_GREG_VENDOR_3		0x00070
++#define MPIC_GREG_VENDOR_ID		0x00080
++#define 	MPIC_GREG_VENDOR_ID_STEPPING_MASK	0x00ff0000
++#define 	MPIC_GREG_VENDOR_ID_STEPPING_SHIFT	16
++#define 	MPIC_GREG_VENDOR_ID_DEVICE_ID_MASK	0x0000ff00
++#define 	MPIC_GREG_VENDOR_ID_DEVICE_ID_SHIFT	8
++#define 	MPIC_GREG_VENDOR_ID_VENDOR_ID_MASK	0x000000ff
++#define MPIC_GREG_PROCESSOR_INIT	0x00090
++#define MPIC_GREG_IPI_VECTOR_PRI_0	0x000a0
++#define MPIC_GREG_IPI_VECTOR_PRI_1	0x000b0
++#define MPIC_GREG_IPI_VECTOR_PRI_2	0x000c0
++#define MPIC_GREG_IPI_VECTOR_PRI_3	0x000d0
++#define MPIC_GREG_SPURIOUS		0x000e0
++#define MPIC_GREG_TIMER_FREQ		0x000f0
++
++/*
++ *
++ * Timer registers
++ */
++#define MPIC_TIMER_BASE			0x01100
++#define MPIC_TIMER_STRIDE		0x40
++
++#define MPIC_TIMER_CURRENT_CNT		0x00000
++#define MPIC_TIMER_BASE_CNT		0x00010
++#define MPIC_TIMER_VECTOR_PRI		0x00020
++#define MPIC_TIMER_DESTINATION		0x00030
++
++/*
++ * Per-Processor registers
++ */
++
++#define MPIC_CPU_THISBASE		0x00000
++#define MPIC_CPU_BASE			0x20000
++#define MPIC_CPU_STRIDE			0x01000
++
++#define MPIC_CPU_IPI_DISPATCH_0		0x00040
++#define MPIC_CPU_IPI_DISPATCH_1		0x00050
++#define MPIC_CPU_IPI_DISPATCH_2		0x00060
++#define MPIC_CPU_IPI_DISPATCH_3		0x00070
++#define MPIC_CPU_CURRENT_TASK_PRI	0x00080
++#define 	MPIC_CPU_TASKPRI_MASK			0x0000000f
++#define MPIC_CPU_WHOAMI			0x00090
++#define 	MPIC_CPU_WHOAMI_MASK			0x0000001f
++#define MPIC_CPU_INTACK			0x000a0
++#define MPIC_CPU_EOI			0x000b0
++
++/*
++ * Per-source registers
++ */
++
++#define MPIC_IRQ_BASE			0x10000
++#define MPIC_IRQ_STRIDE			0x00020
++#define MPIC_IRQ_VECTOR_PRI		0x00000
++#define 	MPIC_VECPRI_MASK			0x80000000
++#define 	MPIC_VECPRI_ACTIVITY			0x40000000	/* Read Only */
++#define 	MPIC_VECPRI_PRIORITY_MASK		0x000f0000
++#define 	MPIC_VECPRI_PRIORITY_SHIFT		16
++#define 	MPIC_VECPRI_VECTOR_MASK			0x000007ff
++#define 	MPIC_VECPRI_POLARITY_POSITIVE		0x00800000
++#define 	MPIC_VECPRI_POLARITY_NEGATIVE		0x00000000
++#define 	MPIC_VECPRI_POLARITY_MASK		0x00800000
++#define 	MPIC_VECPRI_SENSE_LEVEL			0x00400000
++#define 	MPIC_VECPRI_SENSE_EDGE			0x00000000
++#define 	MPIC_VECPRI_SENSE_MASK			0x00400000
++#define MPIC_IRQ_DESTINATION		0x00010
++
++#define MPIC_MAX_IRQ_SOURCES	2048
++#define MPIC_MAX_CPUS		32
++#define MPIC_MAX_ISU		32
++
++/*
++ * Special vector numbers (internal use only)
++ */
++#define MPIC_VEC_SPURRIOUS	255
++#define MPIC_VEC_IPI_3		254
++#define MPIC_VEC_IPI_2		253
++#define MPIC_VEC_IPI_1		252
++#define MPIC_VEC_IPI_0		251
++
++/* unused */
++#define MPIC_VEC_TIMER_3	250
++#define MPIC_VEC_TIMER_2	249
++#define MPIC_VEC_TIMER_1	248
++#define MPIC_VEC_TIMER_0	247
++
++/* Type definition of the cascade handler */
++typedef int (*mpic_cascade_t)(struct pt_regs *regs, void *data);
++
++#ifdef CONFIG_MPIC_BROKEN_U3
++/* Fixup table entry */
++struct mpic_irq_fixup
++{
++	u8 __iomem	*base;
++	unsigned int   irq;
++};
++#endif /* CONFIG_MPIC_BROKEN_U3 */
++
++
++/* The instance data of a given MPIC */
++struct mpic
++{
++	/* The "linux" controller struct */
++	hw_irq_controller	hc_irq;
++#ifdef CONFIG_SMP
++	hw_irq_controller	hc_ipi;
++#endif
++	const char		*name;
++	/* Flags */
++	unsigned int		flags;
++	/* How many irq sources in a given ISU */
++	unsigned int		isu_size;
++	unsigned int		isu_shift;
++	unsigned int		isu_mask;
++	/* Offset of irq vector numbers */
++	unsigned int		irq_offset;	
++	unsigned int		irq_count;
++	/* Offset of ipi vector numbers */
++	unsigned int		ipi_offset;
++	/* Number of sources */
++	unsigned int		num_sources;
++	/* Number of CPUs */
++	unsigned int		num_cpus;
++	/* cascade handler */
++	mpic_cascade_t		cascade;
++	void			*cascade_data;
++	unsigned int		cascade_vec;
++	/* senses array */
++	unsigned char		*senses;
++	unsigned int		senses_count;
++
++#ifdef CONFIG_MPIC_BROKEN_U3
++	/* The fixup table */
++	struct mpic_irq_fixup	*fixups;
++	spinlock_t		fixup_lock;
++#endif
++
++	/* The various ioremap'ed bases */
++	volatile u32 __iomem	*gregs;
++	volatile u32 __iomem	*tmregs;
++	volatile u32 __iomem	*cpuregs[MPIC_MAX_CPUS];
++	volatile u32 __iomem	*isus[MPIC_MAX_ISU];
++
++	/* link */
++	struct mpic		*next;
++};
++
++/* This is the primary controller, only that one has IPIs and
++ * has afinity control. A non-primary MPIC always uses CPU0
++ * registers only
++ */
++#define MPIC_PRIMARY			0x00000001
++/* Set this for a big-endian MPIC */
++#define MPIC_BIG_ENDIAN			0x00000002
++/* Broken U3 MPIC */
++#define MPIC_BROKEN_U3			0x00000004
++/* Broken IPI registers (autodetected) */
++#define MPIC_BROKEN_IPI			0x00000008
++/* MPIC wants a reset */
++#define MPIC_WANTS_RESET		0x00000010
++
++/* Allocate the controller structure and setup the linux irq descs
++ * for the range if interrupts passed in. No HW initialization is
++ * actually performed.
++ * 
++ * @phys_addr:	physial base address of the MPIC
++ * @flags:	flags, see constants above
++ * @isu_size:	number of interrupts in an ISU. Use 0 to use a
++ *              standard ISU-less setup (aka powermac)
++ * @irq_offset: first irq number to assign to this mpic
++ * @irq_count:  number of irqs to use with this mpic IRQ sources. Pass 0
++ *	        to match the number of sources
++ * @ipi_offset: first irq number to assign to this mpic IPI sources,
++ *		used only on primary mpic
++ * @senses:	array of sense values
++ * @senses_num: number of entries in the array
++ *
++ * Note about the sense array. If none is passed, all interrupts are
++ * setup to be level negative unless MPIC_BROKEN_U3 is set in which
++ * case they are edge positive (and the array is ignored anyway).
++ * The values in the array start at the first source of the MPIC,
++ * that is senses[0] correspond to linux irq "irq_offset".
++ */
++extern struct mpic *mpic_alloc(unsigned long phys_addr,
++			       unsigned int flags,
++			       unsigned int isu_size,
++			       unsigned int irq_offset,
++			       unsigned int irq_count,
++			       unsigned int ipi_offset,
++			       unsigned char *senses,
++			       unsigned int senses_num,
++			       const char *name);
++
++/* Assign ISUs, to call before mpic_init()
++ *
++ * @mpic:	controller structure as returned by mpic_alloc()
++ * @isu_num:	ISU number
++ * @phys_addr:	physical address of the ISU
++ */
++extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
++			    unsigned long phys_addr);
++
++/* Initialize the controller. After this has been called, none of the above
++ * should be called again for this mpic
++ */
++extern void mpic_init(struct mpic *mpic);
++
++/* Setup a cascade. Currently, only one cascade is supported this
++ * way, though you can always do a normal request_irq() and add
++ * other cascades this way. You should call this _after_ having
++ * added all the ISUs
++ *
++ * @irq_no:	"linux" irq number of the cascade (that is offset'ed vector)
++ * @handler:	cascade handler function
++ */
++extern void mpic_setup_cascade(unsigned int irq_no, mpic_cascade_t hanlder,
++			       void *data);
++
++/*
++ * All of the following functions must only be used after the
++ * ISUs have been assigned and the controller fully initialized
++ * with mpic_init()
++ */
++
++
++/* Change/Read the priority of an interrupt. Default is 8 for irqs and
++ * 10 for IPIs. You can call this on both IPIs and IRQ numbers, but the
++ * IPI number is then the offset'ed (linux irq number mapped to the IPI)
++ */
++extern void mpic_irq_set_priority(unsigned int irq, unsigned int pri);
++extern unsigned int mpic_irq_get_priority(unsigned int irq);
++
++/* Setup a non-boot CPU */
++extern void mpic_setup_this_cpu(void);
++
++/* Clean up for kexec (or cpu offline or ...) */
++extern void mpic_teardown_this_cpu(int secondary);
++
++/* Get the current cpu priority for this cpu (0..15) */
++extern int mpic_cpu_get_priority(void);
++
++/* Set the current cpu priority for this cpu */
++extern void mpic_cpu_set_priority(int prio);
++
++/* Request IPIs on primary mpic */
++extern void mpic_request_ipis(void);
++
++/* Send an IPI (non offseted number 0..3) */
++extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
++
++/* Send a message (IPI) to a given target (cpu number or MSG_*) */
++void smp_mpic_message_pass(int target, int msg);
++
++/* Fetch interrupt from a given mpic */
++extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs);
++/* This one gets to the primary mpic */
++extern int mpic_get_irq(struct pt_regs *regs);
++
++/* global mpic for pSeries */
++extern struct mpic *pSeries_mpic;
++
++#endif	/* _ASM_POWERPC_MPIC_H */
+diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/of_device.h
+@@ -0,0 +1,64 @@
++#ifndef _ASM_POWERPC_OF_DEVICE_H
++#define _ASM_POWERPC_OF_DEVICE_H
++
++#include <linux/device.h>
++#include <linux/mod_devicetable.h>
++#include <asm/prom.h>
++
++/*
++ * The of_platform_bus_type is a bus type used by drivers that do not
++ * attach to a macio or similar bus but still use OF probing
++ * mecanism
++ */
++extern struct bus_type of_platform_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;		/* OF device node */
++	u64			dma_mask;	/* DMA mask */
++	struct device		dev;		/* Generic device interface */
++};
++#define	to_of_device(d) container_of(d, struct of_device, dev)
++
++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 "platform bus" (of_platform_bus_type)
++ */
++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);
++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);
++extern void of_release_dev(struct device *dev);
++
++#endif /* _ASM_POWERPC_OF_DEVICE_H */
+diff --git a/include/asm-powerpc/ohare.h b/include/asm-powerpc/ohare.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/ohare.h
+@@ -0,0 +1,48 @@
++/*
++ * ohare.h: definitions for using the "O'Hare" I/O controller chip.
++ *
++ * Copyright (C) 1997 Paul Mackerras.
++ *
++ * BenH: Changed to match those of heathrow (but not all of them). Please
++ *       check if I didn't break anything (especially the media bay).
++ */
++
++/* offset from ohare base for feature control register */
++#define OHARE_MBCR	0x34
++#define OHARE_FCR	0x38
++
++/*
++ * Bits in feature control register.
++ * These were mostly derived by experiment on a powerbook 3400
++ * and may differ for other machines.
++ */
++#define OH_SCC_RESET		1
++#define OH_BAY_POWER_N		2	/* a guess */
++#define OH_BAY_PCI_ENABLE	4	/* a guess */
++#define OH_BAY_IDE_ENABLE	8
++#define OH_BAY_FLOPPY_ENABLE	0x10
++#define OH_IDE0_ENABLE		0x20
++#define OH_IDE0_RESET_N		0x40	/* a guess */
++#define OH_BAY_DEV_MASK		0x1c
++#define OH_BAY_RESET_N		0x80
++#define OH_IOBUS_ENABLE		0x100	/* IOBUS seems to be IDE */
++#define OH_SCC_ENABLE		0x200
++#define OH_MESH_ENABLE		0x400
++#define OH_FLOPPY_ENABLE	0x800
++#define OH_SCCA_IO		0x4000
++#define OH_SCCB_IO		0x8000
++#define OH_VIA_ENABLE		0x10000	/* Is apparently wrong, to be verified */
++#define OH_IDE1_RESET_N		0x800000
++
++/*
++ * Bits to set in the feature control register on PowerBooks.
++ */
++#define PBOOK_FEATURES		(OH_IDE_ENABLE | OH_SCC_ENABLE | \
++				 OH_MESH_ENABLE | OH_SCCA_IO | OH_SCCB_IO)
++
++/*
++ * A magic value to put into the feature control register of the
++ * "ohare" I/O controller on Starmaxes to enable the IDE CD interface.
++ * Contributed by Harry Eaton.
++ */
++#define STARMAX_FEATURES	0xbeff7a
+diff --git a/include/asm-powerpc/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/oprofile_impl.h
+@@ -0,0 +1,123 @@
++/*
++ * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, IBM
++ *
++ * Based on alpha version.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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_OPROFILE_IMPL_H
++#define _ASM_POWERPC_OPROFILE_IMPL_H
++
++#define OP_MAX_COUNTER 8
++
++/* Per-counter configuration as set via oprofilefs.  */
++struct op_counter_config {
++#ifdef __powerpc64__
++	unsigned long valid;
++#endif
++	unsigned long enabled;
++	unsigned long event;
++	unsigned long count;
++	unsigned long kernel;
++#ifdef __powerpc64__
++	/* We dont support per counter user/kernel selection */
++#endif
++	unsigned long user;
++	unsigned long unit_mask;
++};
++
++/* System-wide configuration as set via oprofilefs.  */
++struct op_system_config {
++#ifdef __powerpc64__
++	unsigned long mmcr0;
++	unsigned long mmcr1;
++	unsigned long mmcra;
++#endif
++	unsigned long enable_kernel;
++	unsigned long enable_user;
++#ifdef __powerpc64__
++	unsigned long backtrace_spinlocks;
++#endif
++};
++
++/* Per-arch configuration */
++struct op_powerpc_model {
++	void (*reg_setup) (struct op_counter_config *,
++			   struct op_system_config *,
++			   int num_counters);
++#ifdef __powerpc64__
++	void (*cpu_setup) (void *);
++#endif
++	void (*start) (struct op_counter_config *);
++	void (*stop) (void);
++	void (*handle_interrupt) (struct pt_regs *,
++				  struct op_counter_config *);
++	int num_counters;
++};
++
++#ifdef __powerpc64__
++extern struct op_powerpc_model op_model_rs64;
++extern struct op_powerpc_model op_model_power4;
++
++static inline unsigned int ctr_read(unsigned int i)
++{
++	switch(i) {
++	case 0:
++		return mfspr(SPRN_PMC1);
++	case 1:
++		return mfspr(SPRN_PMC2);
++	case 2:
++		return mfspr(SPRN_PMC3);
++	case 3:
++		return mfspr(SPRN_PMC4);
++	case 4:
++		return mfspr(SPRN_PMC5);
++	case 5:
++		return mfspr(SPRN_PMC6);
++	case 6:
++		return mfspr(SPRN_PMC7);
++	case 7:
++		return mfspr(SPRN_PMC8);
++	default:
++		return 0;
++	}
++}
++
++static inline void ctr_write(unsigned int i, unsigned int val)
++{
++	switch(i) {
++	case 0:
++		mtspr(SPRN_PMC1, val);
++		break;
++	case 1:
++		mtspr(SPRN_PMC2, val);
++		break;
++	case 2:
++		mtspr(SPRN_PMC3, val);
++		break;
++	case 3:
++		mtspr(SPRN_PMC4, val);
++		break;
++	case 4:
++		mtspr(SPRN_PMC5, val);
++		break;
++	case 5:
++		mtspr(SPRN_PMC6, val);
++		break;
++	case 6:
++		mtspr(SPRN_PMC7, val);
++		break;
++	case 7:
++		mtspr(SPRN_PMC8, val);
++		break;
++	default:
++		break;
++	}
++}
++#endif /* __powerpc64__ */
++
++#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
+diff --git a/include/asm-powerpc/pSeries_reconfig.h b/include/asm-powerpc/pSeries_reconfig.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/pSeries_reconfig.h
+@@ -0,0 +1,25 @@
++#ifndef _PPC64_PSERIES_RECONFIG_H
++#define _PPC64_PSERIES_RECONFIG_H
++
++#include <linux/notifier.h>
++
++/*
++ * Use this API if your code needs to know about OF device nodes being
++ * added or removed on pSeries systems.
++ */
++
++#define PSERIES_RECONFIG_ADD    0x0001
++#define PSERIES_RECONFIG_REMOVE 0x0002
++
++#ifdef CONFIG_PPC_PSERIES
++extern int pSeries_reconfig_notifier_register(struct notifier_block *);
++extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
++#else /* !CONFIG_PPC_PSERIES */
++static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
++{
++	return 0;
++}
++static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { }
++#endif /* CONFIG_PPC_PSERIES */
++
++#endif /* _PPC64_PSERIES_RECONFIG_H */
+diff --git a/include/asm-powerpc/parport.h b/include/asm-powerpc/parport.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/parport.h
+@@ -0,0 +1,18 @@
++/*
++ * parport.h: platform-specific PC-style parport initialisation
++ *
++ * Copyright (C) 1999, 2000  Tim Waugh <tim at cyberelk.demon.co.uk>
++ *
++ * This file should only be included by drivers/parport/parport_pc.c.
++ */
++
++#ifndef _ASM_POWERPC_PARPORT_H
++#define _ASM_POWERPC_PARPORT_H
++
++static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
++static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
++{
++	return parport_pc_find_isa_ports (autoirq, autodma);
++}
++
++#endif /* !(_ASM_POWERPC_PARPORT_H) */
+diff --git a/include/asm-powerpc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/pmac_feature.h
+@@ -0,0 +1,380 @@
++/*
++ * Definition of platform feature hooks for PowerMacs
++ *
++ * 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) 1998 Paul Mackerras &
++ *                    Ben. Herrenschmidt.
++ *
++ *
++ * Note: I removed media-bay details from the feature stuff, I believe it's
++ *       not worth it, the media-bay driver can directly use the mac-io
++ *       ASIC registers.
++ *
++ * Implementation note: Currently, none of these functions will block.
++ * However, they may internally protect themselves with a spinlock
++ * for way too long. Be prepared for at least some of these to block
++ * in the future.
++ *
++ * Unless specifically defined, the result code is assumed to be an
++ * error when negative, 0 is the default success result. Some functions
++ * may return additional positive result values.
++ *
++ * To keep implementation simple, all feature calls are assumed to have
++ * the prototype parameters (struct device_node* node, int value).
++ * When either is not used, pass 0.
++ */
++
++#ifdef __KERNEL__
++#ifndef __PPC_ASM_PMAC_FEATURE_H
++#define __PPC_ASM_PMAC_FEATURE_H
++
++#include <asm/macio.h>
++#include <asm/machdep.h>
++
++/*
++ * Known Mac motherboard models
++ *
++ * Please, report any error here to benh at kernel.crashing.org, thanks !
++ *
++ * Note that I don't fully maintain this list for Core99 & MacRISC2
++ * and I'm considering removing all NewWorld entries from it and
++ * entirely rely on the model string.
++ */
++
++/* PowerSurge are the first generation of PCI Pmacs. This include
++ * all of the Grand-Central based machines. We currently don't
++ * differenciate most of them.
++ */
++#define PMAC_TYPE_PSURGE		0x10	/* PowerSurge */
++#define PMAC_TYPE_ANS			0x11	/* Apple Network Server */
++
++/* Here is the infamous serie of OHare based machines
++ */
++#define PMAC_TYPE_COMET			0x20	/* Beleived to be PowerBook 2400 */
++#define PMAC_TYPE_HOOPER		0x21	/* Beleived to be PowerBook 3400 */
++#define PMAC_TYPE_KANGA			0x22	/* PowerBook 3500 (first G3) */
++#define PMAC_TYPE_ALCHEMY		0x23	/* Alchemy motherboard base */
++#define PMAC_TYPE_GAZELLE		0x24	/* Spartacus, some 5xxx/6xxx */
++#define PMAC_TYPE_UNKNOWN_OHARE		0x2f	/* Unknown, but OHare based */
++
++/* Here are the Heathrow based machines
++ * FIXME: Differenciate wallstreet,mainstreet,wallstreetII
++ */
++#define PMAC_TYPE_GOSSAMER		0x30	/* Gossamer motherboard */
++#define PMAC_TYPE_SILK			0x31	/* Desktop PowerMac G3 */
++#define PMAC_TYPE_WALLSTREET		0x32	/* Wallstreet/Mainstreet PowerBook*/
++#define PMAC_TYPE_UNKNOWN_HEATHROW	0x3f	/* Unknown but heathrow based */
++
++/* Here are newworld machines based on Paddington (heathrow derivative)
++ */
++#define PMAC_TYPE_101_PBOOK		0x40	/* 101 PowerBook (aka Lombard) */
++#define PMAC_TYPE_ORIG_IMAC		0x41	/* First generation iMac */
++#define PMAC_TYPE_YOSEMITE		0x42	/* B&W G3 */
++#define PMAC_TYPE_YIKES			0x43	/* Yikes G4 (PCI graphics) */
++#define PMAC_TYPE_UNKNOWN_PADDINGTON	0x4f	/* Unknown but paddington based */
++
++/* Core99 machines based on UniNorth 1.0 and 1.5
++ *
++ * Note: A single entry here may cover several actual models according
++ * to the device-tree. (Sawtooth is most tower G4s, FW_IMAC is most
++ * FireWire based iMacs, etc...). Those machines are too similar to be
++ * distinguished here, when they need to be differencied, use the
++ * device-tree "model" or "compatible" property.
++ */
++#define PMAC_TYPE_ORIG_IBOOK		0x40	/* First iBook model (no firewire) */
++#define PMAC_TYPE_SAWTOOTH		0x41	/* Desktop G4s */
++#define PMAC_TYPE_FW_IMAC		0x42	/* FireWire iMacs (except Pangea based) */
++#define PMAC_TYPE_FW_IBOOK		0x43	/* FireWire iBooks (except iBook2) */
++#define PMAC_TYPE_CUBE			0x44	/* Cube PowerMac */
++#define PMAC_TYPE_QUICKSILVER		0x45	/* QuickSilver G4s */
++#define PMAC_TYPE_PISMO			0x46	/* Pismo PowerBook */
++#define PMAC_TYPE_TITANIUM		0x47	/* Titanium PowerBook */
++#define PMAC_TYPE_TITANIUM2		0x48	/* Titanium II PowerBook (no L3, M6) */
++#define PMAC_TYPE_TITANIUM3		0x49	/* Titanium III PowerBook (with L3 & M7) */
++#define PMAC_TYPE_TITANIUM4		0x50	/* Titanium IV PowerBook (with L3 & M9) */
++#define PMAC_TYPE_EMAC			0x50	/* eMac */
++#define PMAC_TYPE_UNKNOWN_CORE99	0x5f
++
++/* MacRisc2 with UniNorth 2.0 */
++#define PMAC_TYPE_RACKMAC		0x80	/* XServe */
++#define PMAC_TYPE_WINDTUNNEL		0x81
++
++/* MacRISC2 machines based on the Pangea chipset
++ */
++#define PMAC_TYPE_PANGEA_IMAC		0x100	/* Flower Power iMac */
++#define PMAC_TYPE_IBOOK2		0x101	/* iBook2 (polycarbonate) */
++#define PMAC_TYPE_FLAT_PANEL_IMAC	0x102	/* Flat panel iMac */
++#define PMAC_TYPE_UNKNOWN_PANGEA	0x10f
++
++/* MacRISC2 machines based on the Intrepid chipset
++ */
++#define PMAC_TYPE_UNKNOWN_INTREPID	0x11f	/* Generic */
++
++/* MacRISC4 / G5 machines. We don't have per-machine selection here anymore,
++ * but rather machine families
++ */
++#define PMAC_TYPE_POWERMAC_G5		0x150	/* U3 & U3H based */
++#define PMAC_TYPE_POWERMAC_G5_U3L	0x151	/* U3L based desktop */
++#define PMAC_TYPE_IMAC_G5		0x152	/* iMac G5 */
++#define PMAC_TYPE_XSERVE_G5		0x153	/* Xserve G5 */
++#define PMAC_TYPE_UNKNOWN_K2		0x19f	/* Any other K2 based */
++
++/*
++ * Motherboard flags
++ */
++
++#define PMAC_MB_CAN_SLEEP		0x00000001
++#define PMAC_MB_HAS_FW_POWER		0x00000002
++#define PMAC_MB_OLD_CORE99		0x00000004
++#define PMAC_MB_MOBILE			0x00000008
++#define PMAC_MB_MAY_SLEEP		0x00000010
++
++/*
++ * Feature calls supported on pmac
++ *
++ */
++
++/*
++ * Use this inline wrapper
++ */
++struct device_node;
++
++static inline long pmac_call_feature(int selector, struct device_node* node,
++					long param, long value)
++{
++	if (!ppc_md.feature_call)
++		return -ENODEV;
++	return ppc_md.feature_call(selector, node, param, value);
++}
++
++/* PMAC_FTR_SERIAL_ENABLE	(struct device_node* node, int param, int value)
++ * enable/disable an SCC side. Pass the node corresponding to the
++ * channel side as a parameter.
++ * param is the type of port
++ * if param is ored with PMAC_SCC_FLAG_XMON, then the SCC is locked enabled
++ * for use by xmon.
++ */
++#define PMAC_FTR_SCC_ENABLE		PMAC_FTR_DEF(0)
++	#define PMAC_SCC_ASYNC		0
++	#define PMAC_SCC_IRDA		1
++	#define PMAC_SCC_I2S1		2
++	#define PMAC_SCC_FLAG_XMON	0x00001000
++
++/* PMAC_FTR_MODEM_ENABLE	(struct device_node* node, 0, int value)
++ * enable/disable the internal modem.
++ */
++#define PMAC_FTR_MODEM_ENABLE		PMAC_FTR_DEF(1)
++
++/* PMAC_FTR_SWIM3_ENABLE	(struct device_node* node, 0,int value)
++ * enable/disable the swim3 (floppy) cell of a mac-io ASIC
++ */
++#define PMAC_FTR_SWIM3_ENABLE		PMAC_FTR_DEF(2)
++
++/* PMAC_FTR_MESH_ENABLE		(struct device_node* node, 0, int value)
++ * enable/disable the mesh (scsi) cell of a mac-io ASIC
++ */
++#define PMAC_FTR_MESH_ENABLE		PMAC_FTR_DEF(3)
++
++/* PMAC_FTR_IDE_ENABLE		(struct device_node* node, int busID, int value)
++ * enable/disable an IDE port of a mac-io ASIC
++ * pass the busID parameter
++ */
++#define PMAC_FTR_IDE_ENABLE		PMAC_FTR_DEF(4)
++
++/* PMAC_FTR_IDE_RESET		(struct device_node* node, int busID, int value)
++ * assert(1)/release(0) an IDE reset line (mac-io IDE only)
++ */
++#define PMAC_FTR_IDE_RESET		PMAC_FTR_DEF(5)
++
++/* PMAC_FTR_BMAC_ENABLE		(struct device_node* node, 0, int value)
++ * enable/disable the bmac (ethernet) cell of a mac-io ASIC, also drive
++ * it's reset line
++ */
++#define PMAC_FTR_BMAC_ENABLE		PMAC_FTR_DEF(6)
++
++/* PMAC_FTR_GMAC_ENABLE		(struct device_node* node, 0, int value)
++ * enable/disable the gmac (ethernet) cell of an uninorth ASIC. This
++ * control the cell's clock.
++ */
++#define PMAC_FTR_GMAC_ENABLE		PMAC_FTR_DEF(7)
++
++/* PMAC_FTR_GMAC_PHY_RESET	(struct device_node* node, 0, 0)
++ * Perform a HW reset of the PHY connected to a gmac controller.
++ * Pass the gmac device node, not the PHY node.
++ */
++#define PMAC_FTR_GMAC_PHY_RESET		PMAC_FTR_DEF(8)
++
++/* PMAC_FTR_SOUND_CHIP_ENABLE	(struct device_node* node, 0, int value)
++ * enable/disable the sound chip, whatever it is and provided it can
++ * acually be controlled
++ */
++#define PMAC_FTR_SOUND_CHIP_ENABLE	PMAC_FTR_DEF(9)
++
++/* -- add various tweaks related to sound routing -- */
++
++/* PMAC_FTR_AIRPORT_ENABLE	(struct device_node* node, 0, int value)
++ * enable/disable the airport card
++ */
++#define PMAC_FTR_AIRPORT_ENABLE		PMAC_FTR_DEF(10)
++
++/* PMAC_FTR_RESET_CPU		(NULL, int cpu_nr, 0)
++ * toggle the reset line of a CPU on an uninorth-based SMP machine
++ */
++#define PMAC_FTR_RESET_CPU		PMAC_FTR_DEF(11)
++
++/* PMAC_FTR_USB_ENABLE		(struct device_node* node, 0, int value)
++ * enable/disable an USB cell, along with the power of the USB "pad"
++ * on keylargo based machines
++ */
++#define PMAC_FTR_USB_ENABLE		PMAC_FTR_DEF(12)
++
++/* PMAC_FTR_1394_ENABLE		(struct device_node* node, 0, int value)
++ * enable/disable the firewire cell of an uninorth ASIC.
++ */
++#define PMAC_FTR_1394_ENABLE		PMAC_FTR_DEF(13)
++
++/* PMAC_FTR_1394_CABLE_POWER	(struct device_node* node, 0, int value)
++ * enable/disable the firewire cable power supply of the uninorth
++ * firewire cell
++ */
++#define PMAC_FTR_1394_CABLE_POWER	PMAC_FTR_DEF(14)
++
++/* PMAC_FTR_SLEEP_STATE		(struct device_node* node, 0, int value)
++ * set the sleep state of the motherboard.
++ *
++ * Pass -1 as value to query for sleep capability
++ * Pass 1 to set IOs to sleep
++ * Pass 0 to set IOs to wake
++ */
++#define PMAC_FTR_SLEEP_STATE		PMAC_FTR_DEF(15)
++
++/* PMAC_FTR_GET_MB_INFO		(NULL, selector, 0)
++ *
++ * returns some motherboard infos.
++ * selector: 0  - model id
++ *           1  - model flags (capabilities)
++ *           2  - model name (cast to const char *)
++ */
++#define PMAC_FTR_GET_MB_INFO		PMAC_FTR_DEF(16)
++#define   PMAC_MB_INFO_MODEL	0
++#define   PMAC_MB_INFO_FLAGS	1
++#define   PMAC_MB_INFO_NAME	2
++
++/* PMAC_FTR_READ_GPIO		(NULL, int index, 0)
++ *
++ * read a GPIO from a mac-io controller of type KeyLargo or Pangea.
++ * the value returned is a byte (positive), or a negative error code
++ */
++#define PMAC_FTR_READ_GPIO		PMAC_FTR_DEF(17)
++
++/* PMAC_FTR_WRITE_GPIO		(NULL, int index, int value)
++ *
++ * write a GPIO of a mac-io controller of type KeyLargo or Pangea.
++ */
++#define PMAC_FTR_WRITE_GPIO		PMAC_FTR_DEF(18)
++
++/* PMAC_FTR_ENABLE_MPIC
++ *
++ * Enable the MPIC cell
++ */
++#define PMAC_FTR_ENABLE_MPIC		PMAC_FTR_DEF(19)
++
++/* PMAC_FTR_AACK_DELAY_ENABLE	(NULL, int enable, 0)
++ *
++ * Enable/disable the AACK delay on the northbridge for systems using DFS
++ */
++#define PMAC_FTR_AACK_DELAY_ENABLE     	PMAC_FTR_DEF(20)
++
++/* PMAC_FTR_DEVICE_CAN_WAKE
++ *
++ * Used by video drivers to inform system that they can actually perform
++ * wakeup from sleep
++ */
++#define PMAC_FTR_DEVICE_CAN_WAKE	PMAC_FTR_DEF(22)
++
++
++/* Don't use those directly, they are for the sake of pmac_setup.c */
++extern long pmac_do_feature_call(unsigned int selector, ...);
++extern void pmac_feature_init(void);
++
++/* Video suspend tweak */
++extern void pmac_set_early_video_resume(void (*proc)(void *data), void *data);
++extern void pmac_call_early_video_resume(void);
++
++#define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x))
++
++/* The AGP driver registers itself here */
++extern void pmac_register_agp_pm(struct pci_dev *bridge,
++				 int (*suspend)(struct pci_dev *bridge),
++				 int (*resume)(struct pci_dev *bridge));
++
++/* Those are meant to be used by video drivers to deal with AGP
++ * suspend resume properly
++ */
++extern void pmac_suspend_agp_for_card(struct pci_dev *dev);
++extern void pmac_resume_agp_for_card(struct pci_dev *dev);
++
++/* Used by the via-pmu driver for suspend/resume
++ */
++extern void pmac_tweak_clock_spreading(int enable);
++
++/*
++ * The part below is for use by macio_asic.c only, do not rely
++ * on the data structures or constants below in a normal driver
++ *
++ */
++
++#define MAX_MACIO_CHIPS		2
++
++enum {
++	macio_unknown = 0,
++	macio_grand_central,
++	macio_ohare,
++	macio_ohareII,
++	macio_heathrow,
++	macio_gatwick,
++	macio_paddington,
++	macio_keylargo,
++	macio_pangea,
++	macio_intrepid,
++	macio_keylargo2,
++};
++
++struct macio_chip
++{
++	struct device_node	*of_node;
++	int			type;
++	const char		*name;
++	int			rev;
++	volatile u32		__iomem *base;
++	unsigned long		flags;
++
++	/* For use by macio_asic PCI driver */
++	struct macio_bus	lbus;
++};
++
++extern struct macio_chip macio_chips[MAX_MACIO_CHIPS];
++
++#define MACIO_FLAG_SCCA_ON	0x00000001
++#define MACIO_FLAG_SCCB_ON	0x00000002
++#define MACIO_FLAG_SCC_LOCKED	0x00000004
++#define MACIO_FLAG_AIRPORT_ON	0x00000010
++#define MACIO_FLAG_FW_SUPPORTED	0x00000020
++
++extern struct macio_chip* macio_find(struct device_node* child, int type);
++
++#define MACIO_FCR32(macio, r)	((macio)->base + ((r) >> 2))
++#define MACIO_FCR8(macio, r)	(((volatile u8 __iomem *)((macio)->base)) + (r))
++
++#define MACIO_IN32(r)		(in_le32(MACIO_FCR32(macio,r)))
++#define MACIO_OUT32(r,v)	(out_le32(MACIO_FCR32(macio,r), (v)))
++#define MACIO_BIS(r,v)		(MACIO_OUT32((r), MACIO_IN32(r) | (v)))
++#define MACIO_BIC(r,v)		(MACIO_OUT32((r), MACIO_IN32(r) & ~(v)))
++#define MACIO_IN8(r)		(in_8(MACIO_FCR8(macio,r)))
++#define MACIO_OUT8(r,v)		(out_8(MACIO_FCR8(macio,r), (v)))
++
++#endif /* __PPC_ASM_PMAC_FEATURE_H */
++#endif /* __KERNEL__ */
+diff --git a/include/asm-powerpc/pmac_low_i2c.h b/include/asm-powerpc/pmac_low_i2c.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/pmac_low_i2c.h
+@@ -0,0 +1,43 @@
++/* 
++ *  include/asm-ppc/pmac_low_i2c.h
++ *
++ *  Copyright (C) 2003 Ben. Herrenschmidt (benh at 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 __PMAC_LOW_I2C_H__
++#define __PMAC_LOW_I2C_H__
++
++/* i2c mode (based on the platform functions format) */
++enum {
++	pmac_low_i2c_mode_dumb		= 1,
++	pmac_low_i2c_mode_std		= 2,
++	pmac_low_i2c_mode_stdsub	= 3,
++	pmac_low_i2c_mode_combined	= 4,
++};
++
++/* RW bit in address */
++enum {
++	pmac_low_i2c_read		= 0x01,
++	pmac_low_i2c_write		= 0x00
++};
++
++/* Init, called early during boot */
++extern void pmac_init_low_i2c(void);
++
++/* Locking functions exposed to i2c-keywest */
++int pmac_low_i2c_lock(struct device_node *np);
++int pmac_low_i2c_unlock(struct device_node *np);
++
++/* Access functions for platform code */
++int pmac_low_i2c_open(struct device_node *np, int channel);
++int pmac_low_i2c_close(struct device_node *np);
++int pmac_low_i2c_setmode(struct device_node *np, int mode);
++int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len);
++
++
++#endif /* __PMAC_LOW_I2C_H__ */
+diff --git a/include/asm-powerpc/pmc.h b/include/asm-powerpc/pmc.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/pmc.h
+@@ -0,0 +1,46 @@
++/*
++ * pmc.h
++ * Copyright (C) 2004  David Gibson, 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
++ */
++#ifndef _POWERPC_PMC_H
++#define _POWERPC_PMC_H
++
++#include <asm/ptrace.h>
++
++typedef void (*perf_irq_t)(struct pt_regs *);
++
++int reserve_pmc_hardware(perf_irq_t new_perf_irq);
++void release_pmc_hardware(void);
++
++#ifdef CONFIG_PPC64
++void power4_enable_pmcs(void);
++#endif
++
++#ifdef CONFIG_FSL_BOOKE
++void init_pmc_stop(int ctr);
++void set_pmc_event(int ctr, int event);
++void set_pmc_user_kernel(int ctr, int user, int kernel);
++void set_pmc_marked(int ctr, int mark0, int mark1);
++void pmc_start_ctr(int ctr, int enable);
++void pmc_start_ctrs(int enable);
++void pmc_stop_ctrs(void);
++void dump_pmcs(void);
++
++extern struct op_powerpc_model op_model_fsl_booke;
++#endif
++
++#endif /* _POWERPC_PMC_H */
+diff --git a/include/asm-powerpc/posix_types.h b/include/asm-powerpc/posix_types.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/posix_types.h
+@@ -0,0 +1,129 @@
++#ifndef _ASM_POWERPC_POSIX_TYPES_H
++#define _ASM_POWERPC_POSIX_TYPES_H
++
++/*
++ * This file is generally used by user-level software, so you need to
++ * be a little careful about namespace pollution etc.  Also, we cannot
++ * assume GCC is being used.
++ */
++
++typedef unsigned long	__kernel_ino_t;
++typedef unsigned int	__kernel_mode_t;
++typedef long		__kernel_off_t;
++typedef int		__kernel_pid_t;
++typedef unsigned int	__kernel_uid_t;
++typedef unsigned int	__kernel_gid_t;
++typedef long		__kernel_ptrdiff_t;
++typedef long		__kernel_time_t;
++typedef long		__kernel_clock_t;
++typedef int		__kernel_timer_t;
++typedef int		__kernel_clockid_t;
++typedef long		__kernel_suseconds_t;
++typedef int		__kernel_daddr_t;
++typedef char *		__kernel_caddr_t;
++typedef unsigned short	__kernel_uid16_t;
++typedef unsigned short	__kernel_gid16_t;
++typedef unsigned int	__kernel_uid32_t;
++typedef unsigned int	__kernel_gid32_t;
++typedef unsigned int	__kernel_old_uid_t;
++typedef unsigned int	__kernel_old_gid_t;
++
++#ifdef __powerpc64__
++typedef unsigned long  	__kernel_nlink_t;
++typedef int             __kernel_ipc_pid_t;
++typedef unsigned long	__kernel_size_t;
++typedef long		__kernel_ssize_t;
++typedef unsigned long	__kernel_old_dev_t;
++#else
++typedef unsigned short	__kernel_nlink_t;
++typedef short		__kernel_ipc_pid_t;
++typedef unsigned int	__kernel_size_t;
++typedef int		__kernel_ssize_t;
++typedef unsigned int	__kernel_old_dev_t;
++#endif
++
++#ifdef __powerpc64__
++typedef long long	__kernel_loff_t;
++#else
++#ifdef __GNUC__
++typedef long long	__kernel_loff_t;
++#endif
++#endif
++
++typedef struct {
++	int	val[2];
++} __kernel_fsid_t;
++
++#ifndef __GNUC__
++
++#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
++#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
++#define	__FD_ISSET(d, set)	(((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0)
++#define	__FD_ZERO(set)	\
++  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
++
++#else /* __GNUC__ */
++
++#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
++    || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
++/* With GNU C, use inline functions instead so args are evaluated only once: */
++
++#undef __FD_SET
++static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
++{
++	unsigned long _tmp = fd / __NFDBITS;
++	unsigned long _rem = fd % __NFDBITS;
++	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
++}
++
++#undef __FD_CLR
++static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
++{
++	unsigned long _tmp = fd / __NFDBITS;
++	unsigned long _rem = fd % __NFDBITS;
++	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
++}
++
++#undef __FD_ISSET
++static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
++{ 
++	unsigned long _tmp = fd / __NFDBITS;
++	unsigned long _rem = fd % __NFDBITS;
++	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
++}
++
++/*
++ * This will unroll the loop for the normal constant case (8 ints,
++ * for a 256-bit fd_set)
++ */
++#undef __FD_ZERO
++static __inline__ void __FD_ZERO(__kernel_fd_set *p)
++{
++	unsigned long *tmp = (unsigned long *)p->fds_bits;
++	int i;
++
++	if (__builtin_constant_p(__FDSET_LONGS)) {
++		switch (__FDSET_LONGS) {
++		      case 16:
++			tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
++			tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
++
++		      case 8:
++			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
++
++		      case 4:
++			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
++			return;
++		}
++	}
++	i = __FDSET_LONGS;
++	while (i) {
++		i--;
++		*tmp = 0;
++		tmp++;
++	}
++}
++
++#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
++#endif /* __GNUC__ */
++#endif /* _ASM_POWERPC_POSIX_TYPES_H */
+diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/ppc-pci.h
+@@ -0,0 +1,54 @@
++/*
++ * c 2001 PPC 64 Team, IBM Corp
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ */
++#ifndef _ASM_POWERPC_PPC_PCI_H
++#define _ASM_POWERPC_PPC_PCI_H
++
++#include <linux/pci.h>
++#include <asm/pci-bridge.h>
++
++extern unsigned long isa_io_base;
++
++extern void pci_setup_pci_controller(struct pci_controller *hose);
++extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
++extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary);
++
++
++extern struct list_head hose_list;
++extern int global_phb_number;
++
++extern unsigned long find_and_init_phbs(void);
++
++extern struct pci_dev *ppc64_isabridge_dev;	/* may be NULL if no ISA bus */
++
++/* PCI device_node operations */
++struct device_node;
++typedef void *(*traverse_func)(struct device_node *me, void *data);
++void *traverse_pci_devices(struct device_node *start, traverse_func pre,
++		void *data);
++
++void pci_devs_phb_init(void);
++void pci_devs_phb_init_dynamic(struct pci_controller *phb);
++
++/* PCI address cache management routines */
++void pci_addr_cache_insert_device(struct pci_dev *dev);
++void pci_addr_cache_remove_device(struct pci_dev *dev);
++
++/* From rtas_pci.h */
++void init_pci_config_tokens (void);
++unsigned long get_phb_buid (struct device_node *);
++
++/* From pSeries_pci.h */
++extern void pSeries_final_fixup(void);
++extern void pSeries_irq_bus_setup(struct pci_bus *bus);
++
++extern unsigned long pci_probe_only;
++extern unsigned long pci_assign_all_buses;
++extern int pci_read_irq_line(struct pci_dev *pci_dev);
++
++#endif /* _ASM_POWERPC_PPC_PCI_H */
+diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/ppc_asm.h
+@@ -0,0 +1,511 @@
++/*
++ * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
++ */
++#ifndef _ASM_POWERPC_PPC_ASM_H
++#define _ASM_POWERPC_PPC_ASM_H
++
++#include <linux/stringify.h>
++#include <linux/config.h>
++
++#ifdef __ASSEMBLY__
++
++/*
++ * Macros for storing registers into and loading registers from
++ * exception frames.
++ */
++#ifdef __powerpc64__
++#define SAVE_GPR(n, base)	std	n,GPR0+8*(n)(base)
++#define REST_GPR(n, base)	ld	n,GPR0+8*(n)(base)
++#define SAVE_NVGPRS(base)	SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
++#define REST_NVGPRS(base)	REST_8GPRS(14, base); REST_10GPRS(22, base)
++#else
++#define SAVE_GPR(n, base)	stw	n,GPR0+4*(n)(base)
++#define REST_GPR(n, base)	lwz	n,GPR0+4*(n)(base)
++#define SAVE_NVGPRS(base)	SAVE_GPR(13, base); SAVE_8GPRS(14, base); \
++				SAVE_10GPRS(22, base)
++#define REST_NVGPRS(base)	REST_GPR(13, base); REST_8GPRS(14, base); \
++				REST_10GPRS(22, base)
++#endif
++
++
++#define SAVE_2GPRS(n, base)	SAVE_GPR(n, base); SAVE_GPR(n+1, base)
++#define SAVE_4GPRS(n, base)	SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
++#define SAVE_8GPRS(n, base)	SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
++#define SAVE_10GPRS(n, base)	SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
++#define REST_2GPRS(n, base)	REST_GPR(n, base); REST_GPR(n+1, base)
++#define REST_4GPRS(n, base)	REST_2GPRS(n, base); REST_2GPRS(n+2, base)
++#define REST_8GPRS(n, base)	REST_4GPRS(n, base); REST_4GPRS(n+4, base)
++#define REST_10GPRS(n, base)	REST_8GPRS(n, base); REST_2GPRS(n+8, base)
++
++#define SAVE_FPR(n, base)	stfd	n,THREAD_FPR0+8*(n)(base)
++#define SAVE_2FPRS(n, base)	SAVE_FPR(n, base); SAVE_FPR(n+1, base)
++#define SAVE_4FPRS(n, base)	SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
++#define SAVE_8FPRS(n, base)	SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
++#define SAVE_16FPRS(n, base)	SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
++#define SAVE_32FPRS(n, base)	SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
++#define REST_FPR(n, base)	lfd	n,THREAD_FPR0+8*(n)(base)
++#define REST_2FPRS(n, base)	REST_FPR(n, base); REST_FPR(n+1, base)
++#define REST_4FPRS(n, base)	REST_2FPRS(n, base); REST_2FPRS(n+2, base)
++#define REST_8FPRS(n, base)	REST_4FPRS(n, base); REST_4FPRS(n+4, base)
++#define REST_16FPRS(n, base)	REST_8FPRS(n, base); REST_8FPRS(n+8, base)
++#define REST_32FPRS(n, base)	REST_16FPRS(n, base); REST_16FPRS(n+16, base)
++
++#define SAVE_VR(n,b,base)	li b,THREAD_VR0+(16*(n));  stvx n,b,base
++#define SAVE_2VRS(n,b,base)	SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
++#define SAVE_4VRS(n,b,base)	SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
++#define SAVE_8VRS(n,b,base)	SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
++#define SAVE_16VRS(n,b,base)	SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
++#define SAVE_32VRS(n,b,base)	SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
++#define REST_VR(n,b,base)	li b,THREAD_VR0+(16*(n)); lvx n,b,base
++#define REST_2VRS(n,b,base)	REST_VR(n,b,base); REST_VR(n+1,b,base)
++#define REST_4VRS(n,b,base)	REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
++#define REST_8VRS(n,b,base)	REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
++#define REST_16VRS(n,b,base)	REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
++#define REST_32VRS(n,b,base)	REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
++
++#define SAVE_EVR(n,s,base)	evmergehi s,s,n; stw s,THREAD_EVR0+4*(n)(base)
++#define SAVE_2EVRS(n,s,base)	SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base)
++#define SAVE_4EVRS(n,s,base)	SAVE_2EVRS(n,s,base); SAVE_2EVRS(n+2,s,base)
++#define SAVE_8EVRS(n,s,base)	SAVE_4EVRS(n,s,base); SAVE_4EVRS(n+4,s,base)
++#define SAVE_16EVRS(n,s,base)	SAVE_8EVRS(n,s,base); SAVE_8EVRS(n+8,s,base)
++#define SAVE_32EVRS(n,s,base)	SAVE_16EVRS(n,s,base); SAVE_16EVRS(n+16,s,base)
++#define REST_EVR(n,s,base)	lwz s,THREAD_EVR0+4*(n)(base); evmergelo n,s,n
++#define REST_2EVRS(n,s,base)	REST_EVR(n,s,base); REST_EVR(n+1,s,base)
++#define REST_4EVRS(n,s,base)	REST_2EVRS(n,s,base); REST_2EVRS(n+2,s,base)
++#define REST_8EVRS(n,s,base)	REST_4EVRS(n,s,base); REST_4EVRS(n+4,s,base)
++#define REST_16EVRS(n,s,base)	REST_8EVRS(n,s,base); REST_8EVRS(n+8,s,base)
++#define REST_32EVRS(n,s,base)	REST_16EVRS(n,s,base); REST_16EVRS(n+16,s,base)
++
++/* Macros to adjust thread priority for hardware multithreading */
++#define HMT_VERY_LOW	or	31,31,31	# very low priority
++#define HMT_LOW		or	1,1,1
++#define HMT_MEDIUM_LOW  or	6,6,6		# medium low priority
++#define HMT_MEDIUM	or	2,2,2
++#define HMT_MEDIUM_HIGH or	5,5,5		# medium high priority
++#define HMT_HIGH	or	3,3,3
++
++/* handle instructions that older assemblers may not know */
++#define RFCI		.long 0x4c000066	/* rfci instruction */
++#define RFDI		.long 0x4c00004e	/* rfdi instruction */
++#define RFMCI		.long 0x4c00004c	/* rfmci instruction */
++
++#ifdef CONFIG_PPC64
++
++#define XGLUE(a,b) a##b
++#define GLUE(a,b) XGLUE(a,b)
++
++#define _GLOBAL(name) \
++	.section ".text"; \
++	.align 2 ; \
++	.globl name; \
++	.globl GLUE(.,name); \
++	.section ".opd","aw"; \
++name: \
++	.quad GLUE(.,name); \
++	.quad .TOC. at tocbase; \
++	.quad 0; \
++	.previous; \
++	.type GLUE(.,name), at function; \
++GLUE(.,name):
++
++#define _KPROBE(name) \
++	.section ".kprobes.text","a"; \
++	.align 2 ; \
++	.globl name; \
++	.globl GLUE(.,name); \
++	.section ".opd","aw"; \
++name: \
++	.quad GLUE(.,name); \
++	.quad .TOC. at tocbase; \
++	.quad 0; \
++	.previous; \
++	.type GLUE(.,name), at function; \
++GLUE(.,name):
++
++#define _STATIC(name) \
++	.section ".text"; \
++	.align 2 ; \
++	.section ".opd","aw"; \
++name: \
++	.quad GLUE(.,name); \
++	.quad .TOC. at tocbase; \
++	.quad 0; \
++	.previous; \
++	.type GLUE(.,name), at function; \
++GLUE(.,name):
++
++#else /* 32-bit */
++
++#define _GLOBAL(n)	\
++	.text;		\
++	.stabs __stringify(n:F-1),N_FUN,0,0,n;\
++	.globl n;	\
++n:
++
++#define _KPROBE(n)	\
++	.section ".kprobes.text","a";	\
++	.globl	n;	\
++n:
++
++#endif
++
++/* 
++ * LOADADDR( rn, name )
++ *   loads the address of 'name' into 'rn'
++ *
++ * LOADBASE( rn, name )
++ *   loads the address (possibly without the low 16 bits) of 'name' into 'rn'
++ *   suitable for base+disp addressing
++ */
++#ifdef __powerpc64__
++#define LOADADDR(rn,name) \
++	lis	rn,name##@highest;	\
++	ori	rn,rn,name##@higher;	\
++	rldicr	rn,rn,32,31;		\
++	oris	rn,rn,name##@h;		\
++	ori	rn,rn,name##@l
++
++#define LOADBASE(rn,name)		\
++	ld	rn,name at got(r2)
++
++#define OFF(name)	0
++
++#define SET_REG_TO_CONST(reg, value)	         	\
++	lis     reg,(((value)>>48)&0xFFFF);             \
++	ori     reg,reg,(((value)>>32)&0xFFFF);         \
++	rldicr  reg,reg,32,31;                          \
++	oris    reg,reg,(((value)>>16)&0xFFFF);         \
++	ori     reg,reg,((value)&0xFFFF);
++
++#define SET_REG_TO_LABEL(reg, label)	         	\
++	lis     reg,(label)@highest;                    \
++	ori     reg,reg,(label)@higher;                 \
++	rldicr  reg,reg,32,31;                          \
++	oris    reg,reg,(label)@h;                      \
++	ori     reg,reg,(label)@l;
++
++/* operations for longs and pointers */
++#define LDL	ld
++#define STL	std
++#define CMPI	cmpdi
++#define SZL	8
++
++/* offsets for stack frame layout */
++#define LRSAVE	16
++
++#else /* 32-bit */
++#define LOADADDR(rn,name) \
++	lis	rn,name at ha;	\
++	addi	rn,rn,name at l
++
++#define LOADBASE(rn,name)	\
++	lis	rn,name at ha
++
++#define OFF(name)	name at l
++
++/* operations for longs and pointers */
++#define LDL	lwz
++#define STL	stw
++#define CMPI	cmpwi
++#define SZL	4
++
++/* offsets for stack frame layout */
++#define LRSAVE	4
++
++#endif
++
++/* various errata or part fixups */
++#ifdef CONFIG_PPC601_SYNC_FIX
++#define SYNC				\
++BEGIN_FTR_SECTION			\
++	sync;				\
++	isync;				\
++END_FTR_SECTION_IFSET(CPU_FTR_601)
++#define SYNC_601			\
++BEGIN_FTR_SECTION			\
++	sync;				\
++END_FTR_SECTION_IFSET(CPU_FTR_601)
++#define ISYNC_601			\
++BEGIN_FTR_SECTION			\
++	isync;				\
++END_FTR_SECTION_IFSET(CPU_FTR_601)
++#else
++#define	SYNC
++#define SYNC_601
++#define ISYNC_601
++#endif
++
++
++#ifndef CONFIG_SMP
++#define TLBSYNC
++#else /* CONFIG_SMP */
++/* tlbsync is not implemented on 601 */
++#define TLBSYNC				\
++BEGIN_FTR_SECTION			\
++	tlbsync;			\
++	sync;				\
++END_FTR_SECTION_IFCLR(CPU_FTR_601)
++#endif
++
++	
++/*
++ * This instruction is not implemented on the PPC 603 or 601; however, on
++ * the 403GCX and 405GP tlbia IS defined and tlbie is not.
++ * All of these instructions exist in the 8xx, they have magical powers,
++ * and they must be used.
++ */
++
++#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
++#define tlbia					\
++	li	r4,1024;			\
++	mtctr	r4;				\
++	lis	r4,KERNELBASE at h;		\
++0:	tlbie	r4;				\
++	addi	r4,r4,0x1000;			\
++	bdnz	0b
++#endif
++
++
++#ifdef CONFIG_IBM405_ERR77
++#define PPC405_ERR77(ra,rb)	dcbt	ra, rb;
++#define	PPC405_ERR77_SYNC	sync;
++#else
++#define PPC405_ERR77(ra,rb)
++#define PPC405_ERR77_SYNC
++#endif
++
++
++#ifdef CONFIG_IBM440EP_ERR42
++#define PPC440EP_ERR42 isync
++#else
++#define PPC440EP_ERR42
++#endif
++
++
++#if defined(CONFIG_BOOKE)
++#define toreal(rd)
++#define fromreal(rd)
++
++#define tophys(rd,rs)				\
++	addis	rd,rs,0
++
++#define tovirt(rd,rs)				\
++	addis	rd,rs,0
++
++#elif defined(CONFIG_PPC64)
++#define toreal(rd)		/* we can access c000... in real mode */
++#define fromreal(rd)
++
++#define tophys(rd,rs)                           \
++	clrldi	rd,rs,2
++
++#define tovirt(rd,rs)                           \
++	rotldi	rd,rs,16;			\
++	ori	rd,rd,((KERNELBASE>>48)&0xFFFF);\
++	rotldi	rd,rd,48
++#else
++/*
++ * On APUS (Amiga PowerPC cpu upgrade board), we don't know the
++ * physical base address of RAM at compile time.
++ */
++#define toreal(rd)	tophys(rd,rd)
++#define fromreal(rd)	tovirt(rd,rd)
++
++#define tophys(rd,rs)				\
++0:	addis	rd,rs,-KERNELBASE at h;		\
++	.section ".vtop_fixup","aw";		\
++	.align  1;				\
++	.long   0b;				\
++	.previous
++
++#define tovirt(rd,rs)				\
++0:	addis	rd,rs,KERNELBASE at h;		\
++	.section ".ptov_fixup","aw";		\
++	.align  1;				\
++	.long   0b;				\
++	.previous
++#endif
++
++#ifdef CONFIG_PPC64
++#define RFI		rfid
++#define MTMSRD(r)	mtmsrd	r
++
++#else
++#define FIX_SRR1(ra, rb)
++#ifndef CONFIG_40x
++#define	RFI		rfi
++#else
++#define RFI		rfi; b .	/* Prevent prefetch past rfi */
++#endif
++#define MTMSRD(r)	mtmsr	r
++#define CLR_TOP32(r)
++#endif
++
++/* The boring bits... */
++
++/* Condition Register Bit Fields */
++
++#define	cr0	0
++#define	cr1	1
++#define	cr2	2
++#define	cr3	3
++#define	cr4	4
++#define	cr5	5
++#define	cr6	6
++#define	cr7	7
++
++
++/* General Purpose Registers (GPRs) */
++
++#define	r0	0
++#define	r1	1
++#define	r2	2
++#define	r3	3
++#define	r4	4
++#define	r5	5
++#define	r6	6
++#define	r7	7
++#define	r8	8
++#define	r9	9
++#define	r10	10
++#define	r11	11
++#define	r12	12
++#define	r13	13
++#define	r14	14
++#define	r15	15
++#define	r16	16
++#define	r17	17
++#define	r18	18
++#define	r19	19
++#define	r20	20
++#define	r21	21
++#define	r22	22
++#define	r23	23
++#define	r24	24
++#define	r25	25
++#define	r26	26
++#define	r27	27
++#define	r28	28
++#define	r29	29
++#define	r30	30
++#define	r31	31
++
++
++/* Floating Point Registers (FPRs) */
++
++#define	fr0	0
++#define	fr1	1
++#define	fr2	2
++#define	fr3	3
++#define	fr4	4
++#define	fr5	5
++#define	fr6	6
++#define	fr7	7
++#define	fr8	8
++#define	fr9	9
++#define	fr10	10
++#define	fr11	11
++#define	fr12	12
++#define	fr13	13
++#define	fr14	14
++#define	fr15	15
++#define	fr16	16
++#define	fr17	17
++#define	fr18	18
++#define	fr19	19
++#define	fr20	20
++#define	fr21	21
++#define	fr22	22
++#define	fr23	23
++#define	fr24	24
++#define	fr25	25
++#define	fr26	26
++#define	fr27	27
++#define	fr28	28
++#define	fr29	29
++#define	fr30	30
++#define	fr31	31
++
++/* AltiVec Registers (VPRs) */
++
++#define	vr0	0
++#define	vr1	1
++#define	vr2	2
++#define	vr3	3
++#define	vr4	4
++#define	vr5	5
++#define	vr6	6
++#define	vr7	7
++#define	vr8	8
++#define	vr9	9
++#define	vr10	10
++#define	vr11	11
++#define	vr12	12
++#define	vr13	13
++#define	vr14	14
++#define	vr15	15
++#define	vr16	16
++#define	vr17	17
++#define	vr18	18
++#define	vr19	19
++#define	vr20	20
++#define	vr21	21
++#define	vr22	22
++#define	vr23	23
++#define	vr24	24
++#define	vr25	25
++#define	vr26	26
++#define	vr27	27
++#define	vr28	28
++#define	vr29	29
++#define	vr30	30
++#define	vr31	31
++
++/* SPE Registers (EVPRs) */
++
++#define	evr0	0
++#define	evr1	1
++#define	evr2	2
++#define	evr3	3
++#define	evr4	4
++#define	evr5	5
++#define	evr6	6
++#define	evr7	7
++#define	evr8	8
++#define	evr9	9
++#define	evr10	10
++#define	evr11	11
++#define	evr12	12
++#define	evr13	13
++#define	evr14	14
++#define	evr15	15
++#define	evr16	16
++#define	evr17	17
++#define	evr18	18
++#define	evr19	19
++#define	evr20	20
++#define	evr21	21
++#define	evr22	22
++#define	evr23	23
++#define	evr24	24
++#define	evr25	25
++#define	evr26	26
++#define	evr27	27
++#define	evr28	28
++#define	evr29	29
++#define	evr30	30
++#define	evr31	31
++
++/* some stab codes */
++#define N_FUN	36
++#define N_RSYM	64
++#define N_SLINE	68
++#define N_SO	100
++
++#define ASM_CONST(x) x
++#else
++  #define __ASM_CONST(x) x##UL
++  #define ASM_CONST(x) __ASM_CONST(x)
++#endif /*  __ASSEMBLY__ */
++
++#endif /* _ASM_POWERPC_PPC_ASM_H */
+diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/processor.h
+@@ -0,0 +1,281 @@
++#ifndef _ASM_POWERPC_PROCESSOR_H
++#define _ASM_POWERPC_PROCESSOR_H
++
++/*
++ * Copyright (C) 2001 PPC 64 Team, IBM Corp
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++#include <linux/config.h>
++#include <asm/reg.h>
++
++#ifndef __ASSEMBLY__
++#include <linux/compiler.h>
++#include <asm/ptrace.h>
++#include <asm/types.h>
++#ifdef CONFIG_PPC64
++#include <asm/systemcfg.h>
++#endif
++
++#ifdef CONFIG_PPC32
++/* 32-bit platform types */
++/* We only need to define a new _MACH_xxx for machines which are part of
++ * a configuration which supports more than one type of different machine.
++ * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac.
++ * -- Tom
++ */
++#define _MACH_prep	0x00000001
++#define _MACH_Pmac	0x00000002	/* pmac or pmac clone (non-chrp) */
++#define _MACH_chrp	0x00000004	/* chrp machine */
++
++/* see residual.h for these */
++#define _PREP_Motorola	0x01	/* motorola prep */
++#define _PREP_Firm	0x02	/* firmworks prep */
++#define _PREP_IBM	0x00	/* ibm prep */
++#define _PREP_Bull	0x03	/* bull prep */
++
++/* these are arbitrary */
++#define _CHRP_Motorola	0x04	/* motorola chrp, the cobra */
++#define _CHRP_IBM	0x05	/* IBM chrp, the longtrail and longtrail 2 */
++#define _CHRP_Pegasos	0x06	/* Genesi/bplan's Pegasos and Pegasos2 */
++
++#ifdef CONFIG_PPC_MULTIPLATFORM
++extern int _machine;
++
++/* what kind of prep workstation we are */
++extern int _prep_type;
++extern int _chrp_type;
++
++/*
++ * This is used to identify the board type from a given PReP board
++ * vendor. Board revision is also made available.
++ */
++extern unsigned char ucSystemType;
++extern unsigned char ucBoardRev;
++extern unsigned char ucBoardRevMaj, ucBoardRevMin;
++#else
++#define _machine 0
++#endif /* CONFIG_PPC_MULTIPLATFORM */
++#endif /* CONFIG_PPC32 */
++
++#ifdef CONFIG_PPC64
++/* Platforms supported by PPC64 */
++#define PLATFORM_PSERIES      0x0100
++#define PLATFORM_PSERIES_LPAR 0x0101
++#define PLATFORM_ISERIES_LPAR 0x0201
++#define PLATFORM_LPAR         0x0001
++#define PLATFORM_POWERMAC     0x0400
++#define PLATFORM_MAPLE        0x0500
++#define PLATFORM_BPA          0x1000
++
++/* Compatibility with drivers coming from PPC32 world */
++#define _machine	(systemcfg->platform)
++#define _MACH_Pmac	PLATFORM_POWERMAC
++#endif
++
++/*
++ * Default implementation of macro that returns current
++ * instruction pointer ("program counter").
++ */
++#define current_text_addr() ({ __label__ _l; _l: &&_l;})
++
++/* Macros for adjusting thread priority (hardware multi-threading) */
++#define HMT_very_low()   asm volatile("or 31,31,31   # very low priority")
++#define HMT_low()	 asm volatile("or 1,1,1	     # low priority")
++#define HMT_medium_low() asm volatile("or 6,6,6      # medium low priority")
++#define HMT_medium()	 asm volatile("or 2,2,2	     # medium priority")
++#define HMT_medium_high() asm volatile("or 5,5,5      # medium high priority")
++#define HMT_high()	 asm volatile("or 3,3,3	     # high priority")
++
++#ifdef __KERNEL__
++
++extern int have_of;
++
++struct task_struct;
++void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
++void release_thread(struct task_struct *);
++
++/* Prepare to copy thread state - unlazy all lazy status */
++extern void prepare_to_copy(struct task_struct *tsk);
++
++/* Create a new kernel thread. */
++extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
++
++/* Lazy FPU handling on uni-processor */
++extern struct task_struct *last_task_used_math;
++extern struct task_struct *last_task_used_altivec;
++extern struct task_struct *last_task_used_spe;
++
++#ifdef CONFIG_PPC32
++#define TASK_SIZE	(CONFIG_TASK_SIZE)
++
++/* This decides where the kernel will search for a free chunk of vm
++ * space during mmap's.
++ */
++#define TASK_UNMAPPED_BASE	(TASK_SIZE / 8 * 3)
++#endif
++
++#ifdef CONFIG_PPC64
++/* 64-bit user address space is 44-bits (16TB user VM) */
++#define TASK_SIZE_USER64 (0x0000100000000000UL)
++
++/* 
++ * 32-bit user address space is 4GB - 1 page 
++ * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT
++ */
++#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE))
++
++#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
++		TASK_SIZE_USER32 : TASK_SIZE_USER64)
++
++/* This decides where the kernel will search for a free chunk of vm
++ * space during mmap's.
++ */
++#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4))
++#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4))
++
++#define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)) ? \
++		TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
++#endif
++
++typedef struct {
++	unsigned long seg;
++} mm_segment_t;
++
++struct thread_struct {
++	unsigned long	ksp;		/* Kernel stack pointer */
++#ifdef CONFIG_PPC64
++	unsigned long	ksp_vsid;
++#endif
++	struct pt_regs	*regs;		/* Pointer to saved register state */
++	mm_segment_t	fs;		/* for get_fs() validation */
++#ifdef CONFIG_PPC32
++	void		*pgdir;		/* root of page-table tree */
++	signed long	last_syscall;
++#endif
++#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
++	unsigned long	dbcr0;		/* debug control register values */
++	unsigned long	dbcr1;
++#endif
++	double		fpr[32];	/* Complete floating point set */
++	struct {			/* fpr ... fpscr must be contiguous */
++
++		unsigned int pad;
++		unsigned int val;	/* Floating point status */
++	} fpscr;
++	int		fpexc_mode;	/* floating-point exception mode */
++#ifdef CONFIG_PPC64
++	unsigned long	start_tb;	/* Start purr when proc switched in */
++	unsigned long	accum_tb;	/* Total accumilated purr for process */
++	unsigned long	vdso_base;	/* base of the vDSO library */
++#endif
++	unsigned long	dabr;		/* Data address breakpoint register */
++#ifdef CONFIG_ALTIVEC
++	/* Complete AltiVec register set */
++	vector128	vr[32] __attribute((aligned(16)));
++	/* AltiVec status */
++	vector128	vscr __attribute((aligned(16)));
++	unsigned long	vrsave;
++	int		used_vr;	/* set if process has used altivec */
++#endif /* CONFIG_ALTIVEC */
++#ifdef CONFIG_SPE
++	unsigned long	evr[32];	/* upper 32-bits of SPE regs */
++	u64		acc;		/* Accumulator */
++	unsigned long	spefscr;	/* SPE & eFP status */
++	int		used_spe;	/* set if process has used spe */
++#endif /* CONFIG_SPE */
++};
++
++#define ARCH_MIN_TASKALIGN 16
++
++#define INIT_SP		(sizeof(init_stack) + (unsigned long) &init_stack)
++
++
++#ifdef CONFIG_PPC32
++#define INIT_THREAD { \
++	.ksp = INIT_SP, \
++	.fs = KERNEL_DS, \
++	.pgdir = swapper_pg_dir, \
++	.fpexc_mode = MSR_FE0 | MSR_FE1, \
++}
++#else
++#define INIT_THREAD  { \
++	.ksp = INIT_SP, \
++	.regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
++	.fs = KERNEL_DS, \
++	.fpr = {0}, \
++	.fpscr = { .val = 0, }, \
++	.fpexc_mode = MSR_FE0|MSR_FE1, \
++}
++#endif
++
++/*
++ * Return saved PC of a blocked thread. For now, this is the "user" PC
++ */
++#define thread_saved_pc(tsk)    \
++        ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
++
++unsigned long get_wchan(struct task_struct *p);
++
++#define KSTK_EIP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
++#define KSTK_ESP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
++
++/* Get/set floating-point exception mode */
++#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr))
++#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val))
++
++extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
++extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
++
++static inline unsigned int __unpack_fe01(unsigned long msr_bits)
++{
++	return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
++}
++
++static inline unsigned long __pack_fe01(unsigned int fpmode)
++{
++	return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
++}
++
++#ifdef CONFIG_PPC64
++#define cpu_relax()	do { HMT_low(); HMT_medium(); barrier(); } while (0)
++#else
++#define cpu_relax()	barrier()
++#endif
++
++/*
++ * Prefetch macros.
++ */
++#define ARCH_HAS_PREFETCH
++#define ARCH_HAS_PREFETCHW
++#define ARCH_HAS_SPINLOCK_PREFETCH
++
++static inline void prefetch(const void *x)
++{
++	if (unlikely(!x))
++		return;
++
++	__asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
++}
++
++static inline void prefetchw(const void *x)
++{
++	if (unlikely(!x))
++		return;
++
++	__asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
++}
++
++#define spin_lock_prefetch(x)	prefetchw(x)
++
++#ifdef CONFIG_PPC64
++#define HAVE_ARCH_PICK_MMAP_LAYOUT
++#endif
++
++#endif /* __KERNEL__ */
++#endif /* __ASSEMBLY__ */
++#endif /* _ASM_POWERPC_PROCESSOR_H */
+diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/prom.h
+@@ -0,0 +1,219 @@
++#ifndef _POWERPC_PROM_H
++#define _POWERPC_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.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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/types.h>
++#include <linux/proc_fs.h>
++#include <asm/atomic.h>
++
++/* Definitions used by the flattened device tree */
++#define OF_DT_HEADER		0xd00dfeed	/* marker */
++#define OF_DT_BEGIN_NODE	0x1		/* Start of node, full name */
++#define OF_DT_END_NODE		0x2		/* End node */
++#define OF_DT_PROP		0x3		/* Property: name off, size,
++						 * content */
++#define OF_DT_NOP		0x4		/* nop */
++#define OF_DT_END		0x9
++
++#define OF_DT_VERSION		0x10
++
++/*
++ * This is what gets passed to the kernel by prom_init or kexec
++ *
++ * The dt struct contains the device tree structure, full pathes and
++ * property contents. The dt strings contain a separate block with just
++ * the strings for the property names, and is fully page aligned and
++ * self contained in a page, so that it can be kept around by the kernel,
++ * each property name appears only once in this page (cheap compression)
++ *
++ * the mem_rsvmap contains a map of reserved ranges of physical memory,
++ * passing it here instead of in the device-tree itself greatly simplifies
++ * the job of everybody. It's just a list of u64 pairs (base/size) that
++ * ends when size is 0
++ */
++struct boot_param_header
++{
++	u32	magic;			/* magic word OF_DT_HEADER */
++	u32	totalsize;		/* total size of DT block */
++	u32	off_dt_struct;		/* offset to structure */
++	u32	off_dt_strings;		/* offset to strings */
++	u32	off_mem_rsvmap;		/* offset to memory reserve map */
++	u32	version;		/* format version */
++	u32	last_comp_version;	/* last compatible version */
++	/* version 2 fields below */
++	u32	boot_cpuid_phys;	/* Physical CPU id we're booting on */
++	/* version 3 fields below */
++	u32	dt_strings_size;	/* size of the DT strings block */
++};
++
++
++
++typedef u32 phandle;
++typedef u32 ihandle;
++
++struct address_range {
++	unsigned long space;
++	unsigned long address;
++	unsigned long size;
++};
++
++struct interrupt_info {
++	int	line;
++	int	sense;		/* +ve/-ve logic, edge or level, etc. */
++};
++
++struct pci_address {
++	u32 a_hi;
++	u32 a_mid;
++	u32 a_lo;
++};
++
++struct isa_address {
++	u32 a_hi;
++	u32 a_lo;
++};
++
++struct isa_range {
++	struct isa_address isa_addr;
++	struct pci_address pci_addr;
++	unsigned int size;
++};
++
++struct reg_property {
++	unsigned long address;
++	unsigned long size;
++};
++
++struct reg_property32 {
++	unsigned int address;
++	unsigned int size;
++};
++
++struct reg_property64 {
++	u64 address;
++	u64 size;
++};
++
++struct property {
++	char	*name;
++	int	length;
++	unsigned char *value;
++	struct property *next;
++};
++
++struct device_node {
++	char	*name;
++	char	*type;
++	phandle	node;
++	phandle linux_phandle;
++	int	n_addrs;
++	struct	address_range *addrs;
++	int	n_intrs;
++	struct	interrupt_info *intrs;
++	char	*full_name;
++
++	struct	property *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;
++};
++
++extern struct device_node *of_chosen;
++
++/* 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 HAVE_ARCH_DEVTREE_FIXUPS
++
++static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
++{
++	dn->pde = de;
++}
++
++
++/* OBSOLETE: Old style node lookup */
++extern struct device_node *find_devices(const char *name);
++extern struct device_node *find_type_devices(const char *type);
++extern struct device_node *find_path_device(const char *path);
++extern struct device_node *find_compatible_devices(const char *type,
++						   const char *compat);
++extern struct device_node *find_all_nodes(void);
++
++/* New style node lookup */
++extern struct device_node *of_find_node_by_name(struct device_node *from,
++	const char *name);
++extern struct device_node *of_find_node_by_type(struct device_node *from,
++	const char *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_find_all_nodes(struct device_node *prev);
++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 device_node *of_node_get(struct device_node *node);
++extern void of_node_put(struct device_node *node);
++
++/* For updating the device tree at runtime */
++extern void of_attach_node(struct device_node *);
++extern void of_detach_node(const struct device_node *);
++
++/* Other Prototypes */
++extern void finish_device_tree(void);
++extern void unflatten_device_tree(void);
++extern void early_init_devtree(void *);
++extern int device_is_compatible(struct device_node *device, const char *);
++extern int machine_is_compatible(const char *compat);
++extern unsigned char *get_property(struct device_node *node, const char *name,
++				   int *lenp);
++extern void print_properties(struct device_node *node);
++extern int prom_n_addr_cells(struct device_node* np);
++extern int prom_n_size_cells(struct device_node* np);
++extern int prom_n_intr_cells(struct device_node* np);
++extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
++extern void prom_add_property(struct device_node* np, struct property* prop);
++
++#ifdef CONFIG_PPC32
++/*
++ * PCI <-> OF matching functions
++ * (XXX should these be here?)
++ */
++struct pci_bus;
++struct pci_dev;
++extern int pci_device_from_OF_node(struct device_node *node,
++				   u8* bus, u8* devfn);
++extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int);
++extern struct device_node* pci_device_to_OF_node(struct pci_dev *);
++extern void pci_create_OF_bus_map(void);
++#endif
++
++extern struct resource *request_OF_resource(struct device_node* node,
++				int index, const char* name_postfix);
++extern int release_OF_resource(struct device_node* node, int index);
++
++#endif /* __KERNEL__ */
++#endif /* _POWERPC_PROM_H */
+diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/reg.h
+@@ -0,0 +1,613 @@
++/*
++ * Contains the definition of registers common to all PowerPC variants.
++ * If a register definition has been changed in a different PowerPC
++ * variant, we will case it in #ifndef XXX ... #endif, and have the
++ * number used in the Programming Environments Manual For 32-Bit
++ * Implementations of the PowerPC Architecture (a.k.a. Green Book) here.
++ */
++
++#ifndef _ASM_POWERPC_REG_H
++#define _ASM_POWERPC_REG_H
++#ifdef __KERNEL__
++
++#include <linux/stringify.h>
++#include <asm/cputable.h>
++
++/* Pickup Book E specific registers. */
++#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
++#include <asm/reg_booke.h>
++#endif
++
++#define MSR_SF_LG	63              /* Enable 64 bit mode */
++#define MSR_ISF_LG	61              /* Interrupt 64b mode valid on 630 */
++#define MSR_HV_LG 	60              /* Hypervisor state */
++#define MSR_VEC_LG	25	        /* Enable AltiVec */
++#define MSR_POW_LG	18		/* Enable Power Management */
++#define MSR_WE_LG	18		/* Wait State Enable */
++#define MSR_TGPR_LG	17		/* TLB Update registers in use */
++#define MSR_CE_LG	17		/* Critical Interrupt Enable */
++#define MSR_ILE_LG	16		/* Interrupt Little Endian */
++#define MSR_EE_LG	15		/* External Interrupt Enable */
++#define MSR_PR_LG	14		/* Problem State / Privilege Level */
++#define MSR_FP_LG	13		/* Floating Point enable */
++#define MSR_ME_LG	12		/* Machine Check Enable */
++#define MSR_FE0_LG	11		/* Floating Exception mode 0 */
++#define MSR_SE_LG	10		/* Single Step */
++#define MSR_BE_LG	9		/* Branch Trace */
++#define MSR_DE_LG	9 		/* Debug Exception Enable */
++#define MSR_FE1_LG	8		/* Floating Exception mode 1 */
++#define MSR_IP_LG	6		/* Exception prefix 0x000/0xFFF */
++#define MSR_IR_LG	5 		/* Instruction Relocate */
++#define MSR_DR_LG	4 		/* Data Relocate */
++#define MSR_PE_LG	3		/* Protection Enable */
++#define MSR_PX_LG	2		/* Protection Exclusive Mode */
++#define MSR_PMM_LG	2		/* Performance monitor */
++#define MSR_RI_LG	1		/* Recoverable Exception */
++#define MSR_LE_LG	0 		/* Little Endian */
++
++#ifdef __ASSEMBLY__
++#define __MASK(X)	(1<<(X))
++#else
++#define __MASK(X)	(1UL<<(X))
++#endif
++
++#ifdef CONFIG_PPC64
++#define MSR_SF		__MASK(MSR_SF_LG)	/* Enable 64 bit mode */
++#define MSR_ISF		__MASK(MSR_ISF_LG)	/* Interrupt 64b mode valid on 630 */
++#define MSR_HV 		__MASK(MSR_HV_LG)	/* Hypervisor state */
++#else
++/* so tests for these bits fail on 32-bit */
++#define MSR_SF		0
++#define MSR_ISF		0
++#define MSR_HV		0
++#endif
++
++#define MSR_VEC		__MASK(MSR_VEC_LG)	/* Enable AltiVec */
++#define MSR_POW		__MASK(MSR_POW_LG)	/* Enable Power Management */
++#define MSR_WE		__MASK(MSR_WE_LG)	/* Wait State Enable */
++#define MSR_TGPR	__MASK(MSR_TGPR_LG)	/* TLB Update registers in use */
++#define MSR_CE		__MASK(MSR_CE_LG)	/* Critical Interrupt Enable */
++#define MSR_ILE		__MASK(MSR_ILE_LG)	/* Interrupt Little Endian */
++#define MSR_EE		__MASK(MSR_EE_LG)	/* External Interrupt Enable */
++#define MSR_PR		__MASK(MSR_PR_LG)	/* Problem State / Privilege Level */
++#define MSR_FP		__MASK(MSR_FP_LG)	/* Floating Point enable */
++#define MSR_ME		__MASK(MSR_ME_LG)	/* Machine Check Enable */
++#define MSR_FE0		__MASK(MSR_FE0_LG)	/* Floating Exception mode 0 */
++#define MSR_SE		__MASK(MSR_SE_LG)	/* Single Step */
++#define MSR_BE		__MASK(MSR_BE_LG)	/* Branch Trace */
++#define MSR_DE		__MASK(MSR_DE_LG)	/* Debug Exception Enable */
++#define MSR_FE1		__MASK(MSR_FE1_LG)	/* Floating Exception mode 1 */
++#define MSR_IP		__MASK(MSR_IP_LG)	/* Exception prefix 0x000/0xFFF */
++#define MSR_IR		__MASK(MSR_IR_LG)	/* Instruction Relocate */
++#define MSR_DR		__MASK(MSR_DR_LG)	/* Data Relocate */
++#define MSR_PE		__MASK(MSR_PE_LG)	/* Protection Enable */
++#define MSR_PX		__MASK(MSR_PX_LG)	/* Protection Exclusive Mode */
++#ifndef MSR_PMM
++#define MSR_PMM		__MASK(MSR_PMM_LG)	/* Performance monitor */
++#endif
++#define MSR_RI		__MASK(MSR_RI_LG)	/* Recoverable Exception */
++#define MSR_LE		__MASK(MSR_LE_LG)	/* Little Endian */
++
++#ifdef CONFIG_PPC64
++#define MSR_		MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF
++#define MSR_KERNEL      MSR_ | MSR_SF | MSR_HV
++
++#define MSR_USER32	MSR_ | MSR_PR | MSR_EE
++#define MSR_USER64	MSR_USER32 | MSR_SF
++
++#else /* 32-bit */
++/* Default MSR for kernel mode. */
++#ifndef MSR_KERNEL	/* reg_booke.h also defines this */
++#ifdef CONFIG_APUS_FAST_EXCEPT
++#define MSR_KERNEL	(MSR_ME|MSR_IP|MSR_RI|MSR_IR|MSR_DR)
++#else
++#define MSR_KERNEL	(MSR_ME|MSR_RI|MSR_IR|MSR_DR)
++#endif
++#endif
++
++#define MSR_USER	(MSR_KERNEL|MSR_PR|MSR_EE)
++#endif
++
++/* Floating Point Status and Control Register (FPSCR) Fields */
++#define FPSCR_FX	0x80000000	/* FPU exception summary */
++#define FPSCR_FEX	0x40000000	/* FPU enabled exception summary */
++#define FPSCR_VX	0x20000000	/* Invalid operation summary */
++#define FPSCR_OX	0x10000000	/* Overflow exception summary */
++#define FPSCR_UX	0x08000000	/* Underflow exception summary */
++#define FPSCR_ZX	0x04000000	/* Zero-divide exception summary */
++#define FPSCR_XX	0x02000000	/* Inexact exception summary */
++#define FPSCR_VXSNAN	0x01000000	/* Invalid op for SNaN */
++#define FPSCR_VXISI	0x00800000	/* Invalid op for Inv - Inv */
++#define FPSCR_VXIDI	0x00400000	/* Invalid op for Inv / Inv */
++#define FPSCR_VXZDZ	0x00200000	/* Invalid op for Zero / Zero */
++#define FPSCR_VXIMZ	0x00100000	/* Invalid op for Inv * Zero */
++#define FPSCR_VXVC	0x00080000	/* Invalid op for Compare */
++#define FPSCR_FR	0x00040000	/* Fraction rounded */
++#define FPSCR_FI	0x00020000	/* Fraction inexact */
++#define FPSCR_FPRF	0x0001f000	/* FPU Result Flags */
++#define FPSCR_FPCC	0x0000f000	/* FPU Condition Codes */
++#define FPSCR_VXSOFT	0x00000400	/* Invalid op for software request */
++#define FPSCR_VXSQRT	0x00000200	/* Invalid op for square root */
++#define FPSCR_VXCVI	0x00000100	/* Invalid op for integer convert */
++#define FPSCR_VE	0x00000080	/* Invalid op exception enable */
++#define FPSCR_OE	0x00000040	/* IEEE overflow exception enable */
++#define FPSCR_UE	0x00000020	/* IEEE underflow exception enable */
++#define FPSCR_ZE	0x00000010	/* IEEE zero divide exception enable */
++#define FPSCR_XE	0x00000008	/* FP inexact exception enable */
++#define FPSCR_NI	0x00000004	/* FPU non IEEE-Mode */
++#define FPSCR_RN	0x00000003	/* FPU rounding control */
++
++/* Special Purpose Registers (SPRNs)*/
++#define SPRN_CTR	0x009	/* Count Register */
++#define SPRN_CTRLF	0x088
++#define SPRN_CTRLT	0x098
++#define   CTRL_RUNLATCH	0x1
++#define SPRN_DABR	0x3F5	/* Data Address Breakpoint Register */
++#define   DABR_TRANSLATION	(1UL << 2)
++#define SPRN_DAR	0x013	/* Data Address Register */
++#define	SPRN_DSISR	0x012	/* Data Storage Interrupt Status Register */
++#define   DSISR_NOHPTE		0x40000000	/* no translation found */
++#define   DSISR_PROTFAULT	0x08000000	/* protection fault */
++#define   DSISR_ISSTORE		0x02000000	/* access was a store */
++#define   DSISR_DABRMATCH	0x00400000	/* hit data breakpoint */
++#define   DSISR_NOSEGMENT	0x00200000	/* STAB/SLB miss */
++#define SPRN_TBRL	0x10C	/* Time Base Read Lower Register (user, R/O) */
++#define SPRN_TBRU	0x10D	/* Time Base Read Upper Register (user, R/O) */
++#define SPRN_TBWL	0x11C	/* Time Base Lower Register (super, R/W) */
++#define SPRN_TBWU	0x11D	/* Time Base Upper Register (super, R/W) */
++#define SPRN_HIOR	0x137	/* 970 Hypervisor interrupt offset */
++#define SPRN_DBAT0L	0x219	/* Data BAT 0 Lower Register */
++#define SPRN_DBAT0U	0x218	/* Data BAT 0 Upper Register */
++#define SPRN_DBAT1L	0x21B	/* Data BAT 1 Lower Register */
++#define SPRN_DBAT1U	0x21A	/* Data BAT 1 Upper Register */
++#define SPRN_DBAT2L	0x21D	/* Data BAT 2 Lower Register */
++#define SPRN_DBAT2U	0x21C	/* Data BAT 2 Upper Register */
++#define SPRN_DBAT3L	0x21F	/* Data BAT 3 Lower Register */
++#define SPRN_DBAT3U	0x21E	/* Data BAT 3 Upper Register */
++#define SPRN_DBAT4L	0x239	/* Data BAT 4 Lower Register */
++#define SPRN_DBAT4U	0x238	/* Data BAT 4 Upper Register */
++#define SPRN_DBAT5L	0x23B	/* Data BAT 5 Lower Register */
++#define SPRN_DBAT5U	0x23A	/* Data BAT 5 Upper Register */
++#define SPRN_DBAT6L	0x23D	/* Data BAT 6 Lower Register */
++#define SPRN_DBAT6U	0x23C	/* Data BAT 6 Upper Register */
++#define SPRN_DBAT7L	0x23F	/* Data BAT 7 Lower Register */
++#define SPRN_DBAT7U	0x23E	/* Data BAT 7 Upper Register */
++
++#define SPRN_DEC	0x016		/* Decrement Register */
++#define SPRN_DER	0x095		/* Debug Enable Regsiter */
++#define DER_RSTE	0x40000000	/* Reset Interrupt */
++#define DER_CHSTPE	0x20000000	/* Check Stop */
++#define DER_MCIE	0x10000000	/* Machine Check Interrupt */
++#define DER_EXTIE	0x02000000	/* External Interrupt */
++#define DER_ALIE	0x01000000	/* Alignment Interrupt */
++#define DER_PRIE	0x00800000	/* Program Interrupt */
++#define DER_FPUVIE	0x00400000	/* FP Unavailable Interrupt */
++#define DER_DECIE	0x00200000	/* Decrementer Interrupt */
++#define DER_SYSIE	0x00040000	/* System Call Interrupt */
++#define DER_TRE		0x00020000	/* Trace Interrupt */
++#define DER_SEIE	0x00004000	/* FP SW Emulation Interrupt */
++#define DER_ITLBMSE	0x00002000	/* Imp. Spec. Instruction TLB Miss */
++#define DER_ITLBERE	0x00001000	/* Imp. Spec. Instruction TLB Error */
++#define DER_DTLBMSE	0x00000800	/* Imp. Spec. Data TLB Miss */
++#define DER_DTLBERE	0x00000400	/* Imp. Spec. Data TLB Error */
++#define DER_LBRKE	0x00000008	/* Load/Store Breakpoint Interrupt */
++#define DER_IBRKE	0x00000004	/* Instruction Breakpoint Interrupt */
++#define DER_EBRKE	0x00000002	/* External Breakpoint Interrupt */
++#define DER_DPIE	0x00000001	/* Dev. Port Nonmaskable Request */
++#define SPRN_DMISS	0x3D0		/* Data TLB Miss Register */
++#define SPRN_EAR	0x11A		/* External Address Register */
++#define SPRN_HASH1	0x3D2		/* Primary Hash Address Register */
++#define SPRN_HASH2	0x3D3		/* Secondary Hash Address Resgister */
++#define SPRN_HID0	0x3F0		/* Hardware Implementation Register 0 */
++#define HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
++#define HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
++#define HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
++#define HID0_SBCLK	(1<<27)
++#define HID0_EICE	(1<<26)
++#define HID0_TBEN	(1<<26)		/* Timebase enable - 745x */
++#define HID0_ECLK	(1<<25)
++#define HID0_PAR	(1<<24)
++#define HID0_STEN	(1<<24)		/* Software table search enable - 745x */
++#define HID0_HIGH_BAT	(1<<23)		/* Enable high BATs - 7455 */
++#define HID0_DOZE	(1<<23)
++#define HID0_NAP	(1<<22)
++#define HID0_SLEEP	(1<<21)
++#define HID0_DPM	(1<<20)
++#define HID0_BHTCLR	(1<<18)		/* Clear branch history table - 7450 */
++#define HID0_XAEN	(1<<17)		/* Extended addressing enable - 7450 */
++#define HID0_NHR	(1<<16)		/* Not hard reset (software bit-7450)*/
++#define HID0_ICE	(1<<15)		/* Instruction Cache Enable */
++#define HID0_DCE	(1<<14)		/* Data Cache Enable */
++#define HID0_ILOCK	(1<<13)		/* Instruction Cache Lock */
++#define HID0_DLOCK	(1<<12)		/* Data Cache Lock */
++#define HID0_ICFI	(1<<11)		/* Instr. Cache Flash Invalidate */
++#define HID0_DCI	(1<<10)		/* Data Cache Invalidate */
++#define HID0_SPD	(1<<9)		/* Speculative disable */
++#define HID0_DAPUEN	(1<<8)		/* Debug APU enable */
++#define HID0_SGE	(1<<7)		/* Store Gathering Enable */
++#define HID0_SIED	(1<<7)		/* Serial Instr. Execution [Disable] */
++#define HID0_DFCA	(1<<6)		/* Data Cache Flush Assist */
++#define HID0_LRSTK	(1<<4)		/* Link register stack - 745x */
++#define HID0_BTIC	(1<<5)		/* Branch Target Instr Cache Enable */
++#define HID0_ABE	(1<<3)		/* Address Broadcast Enable */
++#define HID0_FOLD	(1<<3)		/* Branch Folding enable - 745x */
++#define HID0_BHTE	(1<<2)		/* Branch History Table Enable */
++#define HID0_BTCD	(1<<1)		/* Branch target cache disable */
++#define HID0_NOPDST	(1<<1)		/* No-op dst, dstt, etc. instr. */
++#define HID0_NOPTI	(1<<0)		/* No-op dcbt and dcbst instr. */
++
++#define SPRN_HID1	0x3F1		/* Hardware Implementation Register 1 */
++#define HID1_EMCP	(1<<31)		/* 7450 Machine Check Pin Enable */
++#define HID1_DFS	(1<<22)		/* 7447A Dynamic Frequency Scaling */
++#define HID1_PC0	(1<<16)		/* 7450 PLL_CFG[0] */
++#define HID1_PC1	(1<<15)		/* 7450 PLL_CFG[1] */
++#define HID1_PC2	(1<<14)		/* 7450 PLL_CFG[2] */
++#define HID1_PC3	(1<<13)		/* 7450 PLL_CFG[3] */
++#define HID1_SYNCBE	(1<<11)		/* 7450 ABE for sync, eieio */
++#define HID1_ABE	(1<<10)		/* 7450 Address Broadcast Enable */
++#define HID1_PS		(1<<16)		/* 750FX PLL selection */
++#define SPRN_HID2	0x3F8		/* Hardware Implementation Register 2 */
++#define SPRN_IABR	0x3F2	/* Instruction Address Breakpoint Register */
++#define SPRN_HID4	0x3F4		/* 970 HID4 */
++#define SPRN_HID5	0x3F6		/* 970 HID5 */
++#define	SPRN_HID6	0x3F9	/* BE HID 6 */
++#define	  HID6_LB	(0x0F<<12) /* Concurrent Large Page Modes */
++#define	  HID6_DLP	(1<<20)	/* Disable all large page modes (4K only) */
++#define	SPRN_TSCR	0x399   /* Thread switch control on BE */
++#define	SPRN_TTR	0x39A   /* Thread switch timeout on BE */
++#define	  TSCR_DEC_ENABLE	0x200000 /* Decrementer Interrupt */
++#define	  TSCR_EE_ENABLE	0x100000 /* External Interrupt */
++#define	  TSCR_EE_BOOST		0x080000 /* External Interrupt Boost */
++#define	SPRN_TSC 	0x3FD	/* Thread switch control on others */
++#define	SPRN_TST 	0x3FC	/* Thread switch timeout on others */
++#if !defined(SPRN_IAC1) && !defined(SPRN_IAC2)
++#define SPRN_IAC1	0x3F4		/* Instruction Address Compare 1 */
++#define SPRN_IAC2	0x3F5		/* Instruction Address Compare 2 */
++#endif
++#define SPRN_IBAT0L	0x211		/* Instruction BAT 0 Lower Register */
++#define SPRN_IBAT0U	0x210		/* Instruction BAT 0 Upper Register */
++#define SPRN_IBAT1L	0x213		/* Instruction BAT 1 Lower Register */
++#define SPRN_IBAT1U	0x212		/* Instruction BAT 1 Upper Register */
++#define SPRN_IBAT2L	0x215		/* Instruction BAT 2 Lower Register */
++#define SPRN_IBAT2U	0x214		/* Instruction BAT 2 Upper Register */
++#define SPRN_IBAT3L	0x217		/* Instruction BAT 3 Lower Register */
++#define SPRN_IBAT3U	0x216		/* Instruction BAT 3 Upper Register */
++#define SPRN_IBAT4L	0x231		/* Instruction BAT 4 Lower Register */
++#define SPRN_IBAT4U	0x230		/* Instruction BAT 4 Upper Register */
++#define SPRN_IBAT5L	0x233		/* Instruction BAT 5 Lower Register */
++#define SPRN_IBAT5U	0x232		/* Instruction BAT 5 Upper Register */
++#define SPRN_IBAT6L	0x235		/* Instruction BAT 6 Lower Register */
++#define SPRN_IBAT6U	0x234		/* Instruction BAT 6 Upper Register */
++#define SPRN_IBAT7L	0x237		/* Instruction BAT 7 Lower Register */
++#define SPRN_IBAT7U	0x236		/* Instruction BAT 7 Upper Register */
++#define SPRN_ICMP	0x3D5		/* Instruction TLB Compare Register */
++#define SPRN_ICTC	0x3FB	/* Instruction Cache Throttling Control Reg */
++#define SPRN_ICTRL	0x3F3	/* 1011 7450 icache and interrupt ctrl */
++#define ICTRL_EICE	0x08000000	/* enable icache parity errs */
++#define ICTRL_EDC	0x04000000	/* enable dcache parity errs */
++#define ICTRL_EICP	0x00000100	/* enable icache par. check */
++#define SPRN_IMISS	0x3D4		/* Instruction TLB Miss Register */
++#define SPRN_IMMR	0x27E		/* Internal Memory Map Register */
++#define SPRN_L2CR	0x3F9		/* Level 2 Cache Control Regsiter */
++#define SPRN_L2CR2	0x3f8
++#define L2CR_L2E		0x80000000	/* L2 enable */
++#define L2CR_L2PE		0x40000000	/* L2 parity enable */
++#define L2CR_L2SIZ_MASK		0x30000000	/* L2 size mask */
++#define L2CR_L2SIZ_256KB	0x10000000	/* L2 size 256KB */
++#define L2CR_L2SIZ_512KB	0x20000000	/* L2 size 512KB */
++#define L2CR_L2SIZ_1MB		0x30000000	/* L2 size 1MB */
++#define L2CR_L2CLK_MASK		0x0e000000	/* L2 clock mask */
++#define L2CR_L2CLK_DISABLED	0x00000000	/* L2 clock disabled */
++#define L2CR_L2CLK_DIV1		0x02000000	/* L2 clock / 1 */
++#define L2CR_L2CLK_DIV1_5	0x04000000	/* L2 clock / 1.5 */
++#define L2CR_L2CLK_DIV2		0x08000000	/* L2 clock / 2 */
++#define L2CR_L2CLK_DIV2_5	0x0a000000	/* L2 clock / 2.5 */
++#define L2CR_L2CLK_DIV3		0x0c000000	/* L2 clock / 3 */
++#define L2CR_L2RAM_MASK		0x01800000	/* L2 RAM type mask */
++#define L2CR_L2RAM_FLOW		0x00000000	/* L2 RAM flow through */
++#define L2CR_L2RAM_PIPE		0x01000000	/* L2 RAM pipelined */
++#define L2CR_L2RAM_PIPE_LW	0x01800000	/* L2 RAM pipelined latewr */
++#define L2CR_L2DO		0x00400000	/* L2 data only */
++#define L2CR_L2I		0x00200000	/* L2 global invalidate */
++#define L2CR_L2CTL		0x00100000	/* L2 RAM control */
++#define L2CR_L2WT		0x00080000	/* L2 write-through */
++#define L2CR_L2TS		0x00040000	/* L2 test support */
++#define L2CR_L2OH_MASK		0x00030000	/* L2 output hold mask */
++#define L2CR_L2OH_0_5		0x00000000	/* L2 output hold 0.5 ns */
++#define L2CR_L2OH_1_0		0x00010000	/* L2 output hold 1.0 ns */
++#define L2CR_L2SL		0x00008000	/* L2 DLL slow */
++#define L2CR_L2DF		0x00004000	/* L2 differential clock */
++#define L2CR_L2BYP		0x00002000	/* L2 DLL bypass */
++#define L2CR_L2IP		0x00000001	/* L2 GI in progress */
++#define L2CR_L2IO_745x		0x00100000	/* L2 instr. only (745x) */
++#define L2CR_L2DO_745x		0x00010000	/* L2 data only (745x) */
++#define L2CR_L2REP_745x		0x00001000	/* L2 repl. algorithm (745x) */
++#define L2CR_L2HWF_745x		0x00000800	/* L2 hardware flush (745x) */
++#define SPRN_L3CR		0x3FA	/* Level 3 Cache Control Regsiter */
++#define L3CR_L3E		0x80000000	/* L3 enable */
++#define L3CR_L3PE		0x40000000	/* L3 data parity enable */
++#define L3CR_L3APE		0x20000000	/* L3 addr parity enable */
++#define L3CR_L3SIZ		0x10000000	/* L3 size */
++#define L3CR_L3CLKEN		0x08000000	/* L3 clock enable */
++#define L3CR_L3RES		0x04000000	/* L3 special reserved bit */
++#define L3CR_L3CLKDIV		0x03800000	/* L3 clock divisor */
++#define L3CR_L3IO		0x00400000	/* L3 instruction only */
++#define L3CR_L3SPO		0x00040000	/* L3 sample point override */
++#define L3CR_L3CKSP		0x00030000	/* L3 clock sample point */
++#define L3CR_L3PSP		0x0000e000	/* L3 P-clock sample point */
++#define L3CR_L3REP		0x00001000	/* L3 replacement algorithm */
++#define L3CR_L3HWF		0x00000800	/* L3 hardware flush */
++#define L3CR_L3I		0x00000400	/* L3 global invalidate */
++#define L3CR_L3RT		0x00000300	/* L3 SRAM type */
++#define L3CR_L3NIRCA		0x00000080	/* L3 non-integer ratio clock adj. */
++#define L3CR_L3DO		0x00000040	/* L3 data only mode */
++#define L3CR_PMEN		0x00000004	/* L3 private memory enable */
++#define L3CR_PMSIZ		0x00000001	/* L3 private memory size */
++
++#define SPRN_MSSCR0	0x3f6	/* Memory Subsystem Control Register 0 */
++#define SPRN_MSSSR0	0x3f7	/* Memory Subsystem Status Register 1 */
++#define SPRN_LDSTCR	0x3f8	/* Load/Store control register */
++#define SPRN_LDSTDB	0x3f4	/* */
++#define SPRN_LR		0x008	/* Link Register */
++#ifndef SPRN_PIR
++#define SPRN_PIR	0x3FF	/* Processor Identification Register */
++#endif
++#define SPRN_PTEHI	0x3D5	/* 981 7450 PTE HI word (S/W TLB load) */
++#define SPRN_PTELO	0x3D6	/* 982 7450 PTE LO word (S/W TLB load) */
++#define	SPRN_PURR	0x135	/* Processor Utilization of Resources Reg */
++#define SPRN_PVR	0x11F	/* Processor Version Register */
++#define SPRN_RPA	0x3D6	/* Required Physical Address Register */
++#define SPRN_SDA	0x3BF	/* Sampled Data Address Register */
++#define SPRN_SDR1	0x019	/* MMU Hash Base Register */
++#define SPRN_SIA	0x3BB	/* Sampled Instruction Address Register */
++#define SPRN_SPRG0	0x110	/* Special Purpose Register General 0 */
++#define SPRN_SPRG1	0x111	/* Special Purpose Register General 1 */
++#define SPRN_SPRG2	0x112	/* Special Purpose Register General 2 */
++#define SPRN_SPRG3	0x113	/* Special Purpose Register General 3 */
++#define SPRN_SPRG4	0x114	/* Special Purpose Register General 4 */
++#define SPRN_SPRG5	0x115	/* Special Purpose Register General 5 */
++#define SPRN_SPRG6	0x116	/* Special Purpose Register General 6 */
++#define SPRN_SPRG7	0x117	/* Special Purpose Register General 7 */
++#define SPRN_SRR0	0x01A	/* Save/Restore Register 0 */
++#define SPRN_SRR1	0x01B	/* Save/Restore Register 1 */
++#ifndef SPRN_SVR
++#define SPRN_SVR	0x11E	/* System Version Register */
++#endif
++#define SPRN_THRM1	0x3FC		/* Thermal Management Register 1 */
++/* these bits were defined in inverted endian sense originally, ugh, confusing */
++#define THRM1_TIN	(1 << 31)
++#define THRM1_TIV	(1 << 30)
++#define THRM1_THRES(x)	((x&0x7f)<<23)
++#define THRM3_SITV(x)	((x&0x3fff)<<1)
++#define THRM1_TID	(1<<2)
++#define THRM1_TIE	(1<<1)
++#define THRM1_V		(1<<0)
++#define SPRN_THRM2	0x3FD		/* Thermal Management Register 2 */
++#define SPRN_THRM3	0x3FE		/* Thermal Management Register 3 */
++#define THRM3_E		(1<<0)
++#define SPRN_TLBMISS	0x3D4		/* 980 7450 TLB Miss Register */
++#define SPRN_UMMCR0	0x3A8	/* User Monitor Mode Control Register 0 */
++#define SPRN_UMMCR1	0x3AC	/* User Monitor Mode Control Register 0 */
++#define SPRN_UPMC1	0x3A9	/* User Performance Counter Register 1 */
++#define SPRN_UPMC2	0x3AA	/* User Performance Counter Register 2 */
++#define SPRN_UPMC3	0x3AD	/* User Performance Counter Register 3 */
++#define SPRN_UPMC4	0x3AE	/* User Performance Counter Register 4 */
++#define SPRN_USIA	0x3AB	/* User Sampled Instruction Address Register */
++#define SPRN_VRSAVE	0x100	/* Vector Register Save Register */
++#define SPRN_XER	0x001	/* Fixed Point Exception Register */
++
++/* Performance monitor SPRs */
++#ifdef CONFIG_PPC64
++#define SPRN_MMCR0	795
++#define   MMCR0_FC	0x80000000UL /* freeze counters */
++#define   MMCR0_FCS	0x40000000UL /* freeze in supervisor state */
++#define   MMCR0_KERNEL_DISABLE MMCR0_FCS
++#define   MMCR0_FCP	0x20000000UL /* freeze in problem state */
++#define   MMCR0_PROBLEM_DISABLE MMCR0_FCP
++#define   MMCR0_FCM1	0x10000000UL /* freeze counters while MSR mark = 1 */
++#define   MMCR0_FCM0	0x08000000UL /* freeze counters while MSR mark = 0 */
++#define   MMCR0_PMXE	0x04000000UL /* performance monitor exception enable */
++#define   MMCR0_FCECE	0x02000000UL /* freeze ctrs on enabled cond or event */
++#define   MMCR0_TBEE	0x00400000UL /* time base exception enable */
++#define   MMCR0_PMC1CE	0x00008000UL /* PMC1 count enable*/
++#define   MMCR0_PMCjCE	0x00004000UL /* PMCj count enable*/
++#define   MMCR0_TRIGGER	0x00002000UL /* TRIGGER enable */
++#define   MMCR0_PMAO	0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
++#define   MMCR0_SHRFC	0x00000040UL /* SHRre freeze conditions between threads */
++#define   MMCR0_FCTI	0x00000008UL /* freeze counters in tags inactive mode */
++#define   MMCR0_FCTA	0x00000004UL /* freeze counters in tags active mode */
++#define   MMCR0_FCWAIT	0x00000002UL /* freeze counter in WAIT state */
++#define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
++#define SPRN_MMCR1	798
++#define SPRN_MMCRA	0x312
++#define   MMCRA_SIHV	0x10000000UL /* state of MSR HV when SIAR set */
++#define   MMCRA_SIPR	0x08000000UL /* state of MSR PR when SIAR set */
++#define   MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
++#define SPRN_PMC1	787
++#define SPRN_PMC2	788
++#define SPRN_PMC3	789
++#define SPRN_PMC4	790
++#define SPRN_PMC5	791
++#define SPRN_PMC6	792
++#define SPRN_PMC7	793
++#define SPRN_PMC8	794
++#define SPRN_SIAR	780
++#define SPRN_SDAR	781
++
++#else /* 32-bit */
++#define SPRN_MMCR0	0x3B8	/* Monitor Mode Control Register 0 */
++#define SPRN_MMCR1	0x3BC	/* Monitor Mode Control Register 1 */
++#define SPRN_PMC1	0x3B9	/* Performance Counter Register 1 */
++#define SPRN_PMC2	0x3BA	/* Performance Counter Register 2 */
++#define SPRN_PMC3	0x3BD	/* Performance Counter Register 3 */
++#define SPRN_PMC4	0x3BE	/* Performance Counter Register 4 */
++
++/* Bit definitions for MMCR0 and PMC1 / PMC2. */
++#define MMCR0_PMC1_CYCLES	(1 << 7)
++#define MMCR0_PMC1_ICACHEMISS	(5 << 7)
++#define MMCR0_PMC1_DTLB		(6 << 7)
++#define MMCR0_PMC2_DCACHEMISS	0x6
++#define MMCR0_PMC2_CYCLES	0x1
++#define MMCR0_PMC2_ITLB		0x7
++#define MMCR0_PMC2_LOADMISSTIME	0x5
++#define MMCR0_PMXE	(1 << 26)
++#endif
++
++/* Processor Version Register (PVR) field extraction */
++
++#define PVR_VER(pvr)	(((pvr) >>  16) & 0xFFFF)	/* Version field */
++#define PVR_REV(pvr)	(((pvr) >>   0) & 0xFFFF)	/* Revison field */
++
++#define __is_processor(pv)	(PVR_VER(mfspr(SPRN_PVR)) == (pv))
++
++/*
++ * IBM has further subdivided the standard PowerPC 16-bit version and
++ * revision subfields of the PVR for the PowerPC 403s into the following:
++ */
++
++#define PVR_FAM(pvr)	(((pvr) >> 20) & 0xFFF)	/* Family field */
++#define PVR_MEM(pvr)	(((pvr) >> 16) & 0xF)	/* Member field */
++#define PVR_CORE(pvr)	(((pvr) >> 12) & 0xF)	/* Core field */
++#define PVR_CFG(pvr)	(((pvr) >>  8) & 0xF)	/* Configuration field */
++#define PVR_MAJ(pvr)	(((pvr) >>  4) & 0xF)	/* Major revision field */
++#define PVR_MIN(pvr)	(((pvr) >>  0) & 0xF)	/* Minor revision field */
++
++/* Processor Version Numbers */
++
++#define PVR_403GA	0x00200000
++#define PVR_403GB	0x00200100
++#define PVR_403GC	0x00200200
++#define PVR_403GCX	0x00201400
++#define PVR_405GP	0x40110000
++#define PVR_STB03XXX	0x40310000
++#define PVR_NP405H	0x41410000
++#define PVR_NP405L	0x41610000
++#define PVR_601		0x00010000
++#define PVR_602		0x00050000
++#define PVR_603		0x00030000
++#define PVR_603e	0x00060000
++#define PVR_603ev	0x00070000
++#define PVR_603r	0x00071000
++#define PVR_604		0x00040000
++#define PVR_604e	0x00090000
++#define PVR_604r	0x000A0000
++#define PVR_620		0x00140000
++#define PVR_740		0x00080000
++#define PVR_750		PVR_740
++#define PVR_740P	0x10080000
++#define PVR_750P	PVR_740P
++#define PVR_7400	0x000C0000
++#define PVR_7410	0x800C0000
++#define PVR_7450	0x80000000
++#define PVR_8540	0x80200000
++#define PVR_8560	0x80200000
++/*
++ * For the 8xx processors, all of them report the same PVR family for
++ * the PowerPC core. The various versions of these processors must be
++ * differentiated by the version number in the Communication Processor
++ * Module (CPM).
++ */
++#define PVR_821		0x00500000
++#define PVR_823		PVR_821
++#define PVR_850		PVR_821
++#define PVR_860		PVR_821
++#define PVR_8240	0x00810100
++#define PVR_8245	0x80811014
++#define PVR_8260	PVR_8240
++
++/* 64-bit processors */
++/* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */
++#define	PV_NORTHSTAR	0x0033
++#define	PV_PULSAR	0x0034
++#define	PV_POWER4	0x0035
++#define	PV_ICESTAR	0x0036
++#define	PV_SSTAR	0x0037
++#define	PV_POWER4p	0x0038
++#define PV_970		0x0039
++#define	PV_POWER5	0x003A
++#define PV_POWER5p	0x003B
++#define PV_970FX	0x003C
++#define	PV_630		0x0040
++#define	PV_630p	0x0041
++#define	PV_970MP	0x0044
++#define	PV_BE		0x0070
++
++/*
++ * Number of entries in the SLB. If this ever changes we should handle
++ * it with a use a cpu feature fixup.
++ */
++#define SLB_NUM_ENTRIES 64
++
++/* Macros for setting and retrieving special purpose registers */
++#ifndef __ASSEMBLY__
++#define mfmsr()		({unsigned long rval; \
++			asm volatile("mfmsr %0" : "=r" (rval)); rval;})
++#ifdef CONFIG_PPC64
++#define __mtmsrd(v, l)	asm volatile("mtmsrd %0," __stringify(l) \
++				     : : "r" (v))
++#define mtmsrd(v)	__mtmsrd((v), 0)
++#define mtmsr(v)	mtmsrd(v)
++#else
++#define mtmsr(v)	asm volatile("mtmsr %0" : : "r" (v))
++#endif
++
++#define mfspr(rn)	({unsigned long rval; \
++			asm volatile("mfspr %0," __stringify(rn) \
++				: "=r" (rval)); rval;})
++#define mtspr(rn, v)	asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
++
++#define mftb()		({unsigned long rval;	\
++			asm volatile("mftb %0" : "=r" (rval)); rval;})
++#define mftbl()		({unsigned long rval;	\
++			asm volatile("mftbl %0" : "=r" (rval)); rval;})
++
++#define mttbl(v)	asm volatile("mttbl %0":: "r"(v))
++#define mttbu(v)	asm volatile("mttbu %0":: "r"(v))
++
++#ifdef CONFIG_PPC32
++#define mfsrin(v)	({unsigned int rval; \
++			asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \
++					rval;})
++#endif
++
++#define proc_trap()	asm volatile("trap")
++
++#ifdef CONFIG_PPC64
++static inline void ppc64_runlatch_on(void)
++{
++	unsigned long ctrl;
++
++	if (cpu_has_feature(CPU_FTR_CTRL)) {
++		ctrl = mfspr(SPRN_CTRLF);
++		ctrl |= CTRL_RUNLATCH;
++		mtspr(SPRN_CTRLT, ctrl);
++	}
++}
++
++static inline void ppc64_runlatch_off(void)
++{
++	unsigned long ctrl;
++
++	if (cpu_has_feature(CPU_FTR_CTRL)) {
++		ctrl = mfspr(SPRN_CTRLF);
++		ctrl &= ~CTRL_RUNLATCH;
++		mtspr(SPRN_CTRLT, ctrl);
++	}
++}
++#endif
++
++#define __get_SP()	({unsigned long sp; \
++			asm volatile("mr %0,1": "=r" (sp)); sp;})
++
++#else /* __ASSEMBLY__ */
++
++#define RUNLATCH_ON(REG)			\
++BEGIN_FTR_SECTION				\
++	mfspr	(REG),SPRN_CTRLF;		\
++	ori	(REG),(REG),CTRL_RUNLATCH;	\
++	mtspr	SPRN_CTRLT,(REG);		\
++END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
++
++#endif /* __ASSEMBLY__ */
++#endif /* __KERNEL__ */
++#endif /* _ASM_POWERPC_REG_H */
+diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/rtas.h
+@@ -0,0 +1,249 @@
++#ifndef _POWERPC_RTAS_H
++#define _POWERPC_RTAS_H
++
++#include <linux/spinlock.h>
++#include <asm/page.h>
++
++/*
++ * Definitions for talking to the RTAS on CHRP machines.
++ *
++ * Copyright (C) 2001 Peter Bergner
++ * Copyright (C) 2001 PPC 64 Team, IBM Corp
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++#define RTAS_UNKNOWN_SERVICE (-1)
++#define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */
++
++/* Buffer size for ppc_rtas system call. */
++#define RTAS_RMOBUF_MAX (64 * 1024)
++
++/* RTAS return status codes */
++#define RTAS_BUSY		-2    /* RTAS Busy */
++#define RTAS_EXTENDED_DELAY_MIN	9900
++#define RTAS_EXTENDED_DELAY_MAX	9905
++
++/*
++ * In general to call RTAS use rtas_token("string") to lookup
++ * an RTAS token for the given string (e.g. "event-scan").
++ * To actually perform the call use
++ *    ret = rtas_call(token, n_in, n_out, ...)
++ * Where n_in is the number of input parameters and
++ *       n_out is the number of output parameters
++ *
++ * If the "string" is invalid on this system, RTAS_UNKNOWN_SERVICE
++ * will be returned as a token.  rtas_call() does look for this
++ * token and error out gracefully so rtas_call(rtas_token("str"), ...)
++ * may be safely used for one-shot calls to RTAS.
++ *
++ */
++
++typedef u32 rtas_arg_t;
++
++struct rtas_args {
++	u32 token;
++	u32 nargs;
++	u32 nret; 
++	rtas_arg_t args[16];
++	rtas_arg_t *rets;     /* Pointer to return values in args[]. */
++};  
++
++extern struct rtas_args rtas_stop_self_args;
++
++struct rtas_t {
++	unsigned long entry;		/* physical address pointer */
++	unsigned long base;		/* physical address pointer */
++	unsigned long size;
++	spinlock_t lock;
++	struct rtas_args args;
++	struct device_node *dev;	/* virtual address pointer */
++};
++
++/* RTAS event classes */
++#define RTAS_INTERNAL_ERROR		0x80000000 /* set bit 0 */
++#define RTAS_EPOW_WARNING		0x40000000 /* set bit 1 */
++#define RTAS_POWERMGM_EVENTS		0x20000000 /* set bit 2 */
++#define RTAS_HOTPLUG_EVENTS		0x10000000 /* set bit 3 */
++#define RTAS_EVENT_SCAN_ALL_EVENTS	0xf0000000
++
++/* RTAS event severity */
++#define RTAS_SEVERITY_FATAL		0x5
++#define RTAS_SEVERITY_ERROR		0x4
++#define RTAS_SEVERITY_ERROR_SYNC	0x3
++#define RTAS_SEVERITY_WARNING		0x2
++#define RTAS_SEVERITY_EVENT		0x1
++#define RTAS_SEVERITY_NO_ERROR		0x0
++
++/* RTAS event disposition */
++#define RTAS_DISP_FULLY_RECOVERED	0x0
++#define RTAS_DISP_LIMITED_RECOVERY	0x1
++#define RTAS_DISP_NOT_RECOVERED		0x2
++
++/* RTAS event initiator */
++#define RTAS_INITIATOR_UNKNOWN		0x0
++#define RTAS_INITIATOR_CPU		0x1
++#define RTAS_INITIATOR_PCI		0x2
++#define RTAS_INITIATOR_ISA		0x3
++#define RTAS_INITIATOR_MEMORY		0x4
++#define RTAS_INITIATOR_POWERMGM		0x5
++
++/* RTAS event target */
++#define RTAS_TARGET_UNKNOWN		0x0
++#define RTAS_TARGET_CPU			0x1
++#define RTAS_TARGET_PCI			0x2
++#define RTAS_TARGET_ISA			0x3
++#define RTAS_TARGET_MEMORY		0x4
++#define RTAS_TARGET_POWERMGM		0x5
++
++/* RTAS event type */
++#define RTAS_TYPE_RETRY			0x01
++#define RTAS_TYPE_TCE_ERR		0x02
++#define RTAS_TYPE_INTERN_DEV_FAIL	0x03
++#define RTAS_TYPE_TIMEOUT		0x04
++#define RTAS_TYPE_DATA_PARITY		0x05
++#define RTAS_TYPE_ADDR_PARITY		0x06
++#define RTAS_TYPE_CACHE_PARITY		0x07
++#define RTAS_TYPE_ADDR_INVALID		0x08
++#define RTAS_TYPE_ECC_UNCORR		0x09
++#define RTAS_TYPE_ECC_CORR		0x0a
++#define RTAS_TYPE_EPOW			0x40
++#define RTAS_TYPE_PLATFORM		0xE0
++#define RTAS_TYPE_IO			0xE1
++#define RTAS_TYPE_INFO			0xE2
++#define RTAS_TYPE_DEALLOC		0xE3
++#define RTAS_TYPE_DUMP			0xE4
++/* I don't add PowerMGM events right now, this is a different topic */ 
++#define RTAS_TYPE_PMGM_POWER_SW_ON	0x60
++#define RTAS_TYPE_PMGM_POWER_SW_OFF	0x61
++#define RTAS_TYPE_PMGM_LID_OPEN		0x62
++#define RTAS_TYPE_PMGM_LID_CLOSE	0x63
++#define RTAS_TYPE_PMGM_SLEEP_BTN	0x64
++#define RTAS_TYPE_PMGM_WAKE_BTN		0x65
++#define RTAS_TYPE_PMGM_BATTERY_WARN	0x66
++#define RTAS_TYPE_PMGM_BATTERY_CRIT	0x67
++#define RTAS_TYPE_PMGM_SWITCH_TO_BAT	0x68
++#define RTAS_TYPE_PMGM_SWITCH_TO_AC	0x69
++#define RTAS_TYPE_PMGM_KBD_OR_MOUSE	0x6a
++#define RTAS_TYPE_PMGM_ENCLOS_OPEN	0x6b
++#define RTAS_TYPE_PMGM_ENCLOS_CLOSED	0x6c
++#define RTAS_TYPE_PMGM_RING_INDICATE	0x6d
++#define RTAS_TYPE_PMGM_LAN_ATTENTION	0x6e
++#define RTAS_TYPE_PMGM_TIME_ALARM	0x6f
++#define RTAS_TYPE_PMGM_CONFIG_CHANGE	0x70
++#define RTAS_TYPE_PMGM_SERVICE_PROC	0x71
++
++struct rtas_error_log {
++	unsigned long version:8;		/* Architectural version */
++	unsigned long severity:3;		/* Severity level of error */
++	unsigned long disposition:2;		/* Degree of recovery */
++	unsigned long extended:1;		/* extended log present? */
++	unsigned long /* reserved */ :2;	/* Reserved for future use */
++	unsigned long initiator:4;		/* Initiator of event */
++	unsigned long target:4;			/* Target of failed operation */
++	unsigned long type:8;			/* General event or error*/
++	unsigned long extended_log_length:32;	/* length in bytes */
++	unsigned char buffer[1];
++};
++
++struct flash_block {
++	char *data;
++	unsigned long length;
++};
++
++/* This struct is very similar but not identical to
++ * that needed by the rtas flash update.
++ * All we need to do for rtas is rewrite num_blocks
++ * into a version/length and translate the pointers
++ * to absolute.
++ */
++#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
++struct flash_block_list {
++	unsigned long num_blocks;
++	struct flash_block_list *next;
++	struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
++};
++struct flash_block_list_header { /* just the header of flash_block_list */
++	unsigned long num_blocks;
++	struct flash_block_list *next;
++};
++extern struct flash_block_list_header rtas_firmware_flash_list;
++
++extern struct rtas_t rtas;
++
++extern void enter_rtas(unsigned long);
++extern int rtas_token(const char *service);
++extern int rtas_call(int token, int, int, int *, ...);
++extern void call_rtas_display_status(unsigned char);
++extern void rtas_restart(char *cmd);
++extern void rtas_power_off(void);
++extern void rtas_halt(void);
++extern void rtas_os_term(char *str);
++extern int rtas_get_sensor(int sensor, int index, int *state);
++extern int rtas_get_power_level(int powerdomain, int *level);
++extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
++extern int rtas_set_indicator(int indicator, int index, int new_value);
++extern void rtas_progress(char *s, unsigned short hex);
++extern void rtas_initialize(void);
++
++struct rtc_time;
++extern unsigned long rtas_get_boot_time(void);
++extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
++extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
++
++/* Given an RTAS status code of 9900..9905 compute the hinted delay */
++unsigned int rtas_extended_busy_delay_time(int status);
++static inline int rtas_is_extended_busy(int status)
++{
++	return status >= 9900 && status <= 9909;
++}
++
++extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
++
++/* Error types logged.  */
++#define ERR_FLAG_ALREADY_LOGGED	0x0
++#define ERR_FLAG_BOOT		0x1 	/* log was pulled from NVRAM on boot */
++#define ERR_TYPE_RTAS_LOG	0x2	/* from rtas event-scan */
++#define ERR_TYPE_KERNEL_PANIC	0x4	/* from panic() */
++
++/* All the types and not flags */
++#define ERR_TYPE_MASK	(ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC)
++
++#define RTAS_DEBUG KERN_DEBUG "RTAS: "
++ 
++#define RTAS_ERROR_LOG_MAX 2048
++
++/*
++ * Return the firmware-specified size of the error log buffer
++ *  for all rtas calls that require an error buffer argument.
++ *  This includes 'check-exception' and 'rtas-last-error'.
++ */
++extern int rtas_get_error_log_max(void);
++
++/* Event Scan Parameters */
++#define EVENT_SCAN_ALL_EVENTS	0xf0000000
++#define SURVEILLANCE_TOKEN	9000
++#define LOG_NUMBER		64		/* must be a power of two */
++#define LOG_NUMBER_MASK		(LOG_NUMBER-1)
++
++/* Some RTAS ops require a data buffer and that buffer must be < 4G.
++ * Rather than having a memory allocator, just use this buffer
++ * (get the lock first), make the RTAS call.  Copy the data instead
++ * of holding the buffer for long.
++ */
++
++#define RTAS_DATA_BUF_SIZE 4096
++extern spinlock_t rtas_data_buf_lock;
++extern char rtas_data_buf[RTAS_DATA_BUF_SIZE];
++
++extern void rtas_stop_self(void);
++
++/* RMO buffer reserved for user-space RTAS use */
++extern unsigned long rtas_rmo_buf;
++
++#define GLOBAL_INTERRUPT_QUEUE 9005
++
++#endif /* _POWERPC_RTAS_H */
+diff --git a/include/asm-powerpc/rtc.h b/include/asm-powerpc/rtc.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/rtc.h
+@@ -0,0 +1,78 @@
++/*
++ * Real-time clock definitions and interfaces
++ *
++ * Author: Tom Rini <trini at mvista.com>
++ *
++ * 2002 (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.
++ *
++ * Based on:
++ * include/asm-m68k/rtc.h
++ *
++ * Copyright Richard Zidlicky
++ * implementation details for genrtc/q40rtc driver
++ *
++ * And the old drivers/macintosh/rtc.c which was heavily based on:
++ * Linux/SPARC Real Time Clock Driver
++ * Copyright (C) 1996 Thomas K. Dyas (tdyas at eden.rutgers.edu)
++ *
++ * With additional work by Paul Mackerras and Franz Sirl.
++ */
++
++#ifndef __ASM_POWERPC_RTC_H__
++#define __ASM_POWERPC_RTC_H__
++
++#ifdef __KERNEL__
++
++#include <linux/rtc.h>
++
++#include <asm/machdep.h>
++#include <asm/time.h>
++
++#define RTC_PIE 0x40		/* periodic interrupt enable */
++#define RTC_AIE 0x20		/* alarm interrupt enable */
++#define RTC_UIE 0x10		/* update-finished interrupt enable */
++
++/* some dummy definitions */
++#define RTC_BATT_BAD 0x100	/* battery bad */
++#define RTC_SQWE 0x08		/* enable square-wave output */
++#define RTC_DM_BINARY 0x04	/* all time/date values are BCD if clear */
++#define RTC_24H 0x02		/* 24 hour mode - else hours bit 7 means pm */
++#define RTC_DST_EN 0x01	        /* auto switch DST - works f. USA only */
++
++static inline unsigned int get_rtc_time(struct rtc_time *time)
++{
++	if (ppc_md.get_rtc_time)
++		ppc_md.get_rtc_time(time);
++	return RTC_24H;
++}
++
++/* Set the current date and time in the real time clock. */
++static inline int set_rtc_time(struct rtc_time *time)
++{
++	if (ppc_md.set_rtc_time)
++		return ppc_md.set_rtc_time(time);
++	return -EINVAL;
++}
++
++static inline unsigned int get_rtc_ss(void)
++{
++	struct rtc_time h;
++
++	get_rtc_time(&h);
++	return h.tm_sec;
++}
++
++static inline int get_rtc_pll(struct rtc_pll_info *pll)
++{
++	return -EINVAL;
++}
++static inline int set_rtc_pll(struct rtc_pll_info *pll)
++{
++	return -EINVAL;
++}
++
++#endif /* __KERNEL__ */
++#endif /* __ASM_POWERPC_RTC_H__ */
+diff --git a/include/asm-powerpc/rwsem.h b/include/asm-powerpc/rwsem.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/rwsem.h
+@@ -0,0 +1,168 @@
++#ifndef _ASM_POWERPC_RWSEM_H
++#define _ASM_POWERPC_RWSEM_H
++
++#ifdef __KERNEL__
++
++/*
++ * include/asm-ppc64/rwsem.h: R/W semaphores for PPC using the stuff
++ * in lib/rwsem.c.  Adapted largely from include/asm-i386/rwsem.h
++ * by Paul Mackerras <paulus at samba.org>.
++ */
++
++#include <linux/list.h>
++#include <linux/spinlock.h>
++#include <asm/atomic.h>
++#include <asm/system.h>
++
++/*
++ * the semaphore definition
++ */
++struct rw_semaphore {
++	/* XXX this should be able to be an atomic_t  -- paulus */
++	signed int		count;
++#define RWSEM_UNLOCKED_VALUE		0x00000000
++#define RWSEM_ACTIVE_BIAS		0x00000001
++#define RWSEM_ACTIVE_MASK		0x0000ffff
++#define RWSEM_WAITING_BIAS		(-0x00010000)
++#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
++#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
++	spinlock_t		wait_lock;
++	struct list_head	wait_list;
++#if RWSEM_DEBUG
++	int			debug;
++#endif
++};
++
++/*
++ * initialisation
++ */
++#if RWSEM_DEBUG
++#define __RWSEM_DEBUG_INIT      , 0
++#else
++#define __RWSEM_DEBUG_INIT	/* */
++#endif
++
++#define __RWSEM_INITIALIZER(name) \
++	{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
++	  LIST_HEAD_INIT((name).wait_list) \
++	  __RWSEM_DEBUG_INIT }
++
++#define DECLARE_RWSEM(name)		\
++	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
++
++extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
++extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
++extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
++extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
++
++static inline void init_rwsem(struct rw_semaphore *sem)
++{
++	sem->count = RWSEM_UNLOCKED_VALUE;
++	spin_lock_init(&sem->wait_lock);
++	INIT_LIST_HEAD(&sem->wait_list);
++#if RWSEM_DEBUG
++	sem->debug = 0;
++#endif
++}
++
++/*
++ * lock for reading
++ */
++static inline void __down_read(struct rw_semaphore *sem)
++{
++	if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0))
++		rwsem_down_read_failed(sem);
++}
++
++static inline int __down_read_trylock(struct rw_semaphore *sem)
++{
++	int tmp;
++
++	while ((tmp = sem->count) >= 0) {
++		if (tmp == cmpxchg(&sem->count, tmp,
++				   tmp + RWSEM_ACTIVE_READ_BIAS)) {
++			return 1;
++		}
++	}
++	return 0;
++}
++
++/*
++ * lock for writing
++ */
++static inline void __down_write(struct rw_semaphore *sem)
++{
++	int tmp;
++
++	tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
++				(atomic_t *)(&sem->count));
++	if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
++		rwsem_down_write_failed(sem);
++}
++
++static inline int __down_write_trylock(struct rw_semaphore *sem)
++{
++	int tmp;
++
++	tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
++		      RWSEM_ACTIVE_WRITE_BIAS);
++	return tmp == RWSEM_UNLOCKED_VALUE;
++}
++
++/*
++ * unlock after reading
++ */
++static inline void __up_read(struct rw_semaphore *sem)
++{
++	int tmp;
++
++	tmp = atomic_dec_return((atomic_t *)(&sem->count));
++	if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0))
++		rwsem_wake(sem);
++}
++
++/*
++ * unlock after writing
++ */
++static inline void __up_write(struct rw_semaphore *sem)
++{
++	if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
++			      (atomic_t *)(&sem->count)) < 0))
++		rwsem_wake(sem);
++}
++
++/*
++ * implement atomic add functionality
++ */
++static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
++{
++	atomic_add(delta, (atomic_t *)(&sem->count));
++}
++
++/*
++ * downgrade write lock to read lock
++ */
++static inline void __downgrade_write(struct rw_semaphore *sem)
++{
++	int tmp;
++
++	tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
++	if (tmp < 0)
++		rwsem_downgrade_wake(sem);
++}
++
++/*
++ * implement exchange and add functionality
++ */
++static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
++{
++	return atomic_add_return(delta, (atomic_t *)(&sem->count));
++}
++
++static inline int rwsem_is_locked(struct rw_semaphore *sem)
++{
++	return (sem->count != 0);
++}
++
++#endif	/* __KERNEL__ */
++#endif	/* _ASM_POWERPC_RWSEM_H */
+diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/scatterlist.h
+@@ -0,0 +1,45 @@
++#ifndef _ASM_POWERPC_SCATTERLIST_H
++#define _ASM_POWERPC_SCATTERLIST_H
++/*
++ * Copyright (C) 2001 PPC64 Team, IBM Corp
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++#ifdef __KERNEL__
++#include <linux/types.h>
++#include <asm/dma.h>
++
++struct scatterlist {
++	struct page *page;
++	unsigned int offset;
++	unsigned int length;
++
++	/* For TCE support */
++	dma_addr_t dma_address;
++	u32 dma_length;
++};
++
++/*
++ * These macros should be used after a dma_map_sg call has been done
++ * to get bus addresses of each of the SG entries and their lengths.
++ * You should only work with the number of sg entries pci_map_sg
++ * returns, or alternatively stop on the first sg_dma_len(sg) which
++ * is 0.
++ */
++#define sg_dma_address(sg)	((sg)->dma_address)
++#ifdef __powerpc64__
++#define sg_dma_len(sg)		((sg)->dma_length)
++#else
++#define sg_dma_len(sg)		((sg)->length)
++#endif
++
++#ifdef __powerpc64__
++#define ISA_DMA_THRESHOLD	(~0UL)
++#endif
++
++#endif /* __KERNEL__ */
++#endif /* _ASM_POWERPC_SCATTERLIST_H */
+diff --git a/include/asm-powerpc/seccomp.h b/include/asm-powerpc/seccomp.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/seccomp.h
+@@ -0,0 +1,16 @@
++#ifndef _ASM_POWERPC_SECCOMP_H
++
++#include <linux/thread_info.h>
++#include <linux/unistd.h>
++
++#define __NR_seccomp_read __NR_read
++#define __NR_seccomp_write __NR_write
++#define __NR_seccomp_exit __NR_exit
++#define __NR_seccomp_sigreturn __NR_rt_sigreturn
++
++#define __NR_seccomp_read_32 __NR_read
++#define __NR_seccomp_write_32 __NR_write
++#define __NR_seccomp_exit_32 __NR_exit
++#define __NR_seccomp_sigreturn_32 __NR_sigreturn
++
++#endif	/* _ASM_POWERPC_SECCOMP_H */
+diff --git a/include/asm-powerpc/sections.h b/include/asm-powerpc/sections.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/sections.h
+@@ -0,0 +1,20 @@
++#ifndef _ASM_POWERPC_SECTIONS_H
++#define _ASM_POWERPC_SECTIONS_H
++
++#include <asm-generic/sections.h>
++
++#ifdef __powerpc64__
++
++extern char _end[];
++
++static inline int in_kernel_text(unsigned long addr)
++{
++	if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end)
++		return 1;
++
++	return 0;
++}
++
++#endif
++
++#endif	/* _ASM_POWERPC_SECTIONS_H */
+diff --git a/include/asm-powerpc/semaphore.h b/include/asm-powerpc/semaphore.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/semaphore.h
+@@ -0,0 +1,95 @@
++#ifndef _ASM_POWERPC_SEMAPHORE_H
++#define _ASM_POWERPC_SEMAPHORE_H
++
++/*
++ * Remove spinlock-based RW semaphores; RW semaphore definitions are
++ * now in rwsem.h and we use the generic lib/rwsem.c implementation.
++ * Rework semaphores to use atomic_dec_if_positive.
++ * -- Paul Mackerras (paulus at samba.org)
++ */
++
++#ifdef __KERNEL__
++
++#include <asm/atomic.h>
++#include <asm/system.h>
++#include <linux/wait.h>
++#include <linux/rwsem.h>
++
++struct semaphore {
++	/*
++	 * Note that any negative value of count is equivalent to 0,
++	 * but additionally indicates that some process(es) might be
++	 * sleeping on `wait'.
++	 */
++	atomic_t count;
++	wait_queue_head_t wait;
++};
++
++#define __SEMAPHORE_INITIALIZER(name, n)				\
++{									\
++	.count		= ATOMIC_INIT(n),				\
++	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
++}
++
++#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
++	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
++
++#define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC(name, 1)
++#define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC(name, 0)
++
++static inline void sema_init (struct semaphore *sem, int val)
++{
++	atomic_set(&sem->count, val);
++	init_waitqueue_head(&sem->wait);
++}
++
++static inline void init_MUTEX (struct semaphore *sem)
++{
++	sema_init(sem, 1);
++}
++
++static inline void init_MUTEX_LOCKED (struct semaphore *sem)
++{
++	sema_init(sem, 0);
++}
++
++extern void __down(struct semaphore * sem);
++extern int  __down_interruptible(struct semaphore * sem);
++extern void __up(struct semaphore * sem);
++
++static inline void down(struct semaphore * sem)
++{
++	might_sleep();
++
++	/*
++	 * Try to get the semaphore, take the slow path if we fail.
++	 */
++	if (unlikely(atomic_dec_return(&sem->count) < 0))
++		__down(sem);
++}
++
++static inline int down_interruptible(struct semaphore * sem)
++{
++	int ret = 0;
++
++	might_sleep();
++
++	if (unlikely(atomic_dec_return(&sem->count) < 0))
++		ret = __down_interruptible(sem);
++	return ret;
++}
++
++static inline int down_trylock(struct semaphore * sem)
++{
++	return atomic_dec_if_positive(&sem->count) < 0;
++}
++
++static inline void up(struct semaphore * sem)
++{
++	if (unlikely(atomic_inc_return(&sem->count) <= 0))
++		__up(sem);
++}
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_POWERPC_SEMAPHORE_H */
+diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/smu.h
+@@ -0,0 +1,379 @@
++#ifndef _SMU_H
++#define _SMU_H
++
++/*
++ * Definitions for talking to the SMU chip in newer G5 PowerMacs
++ */
++
++#include <linux/config.h>
++#include <linux/list.h>
++
++/*
++ * Known SMU commands
++ *
++ * Most of what is below comes from looking at the Open Firmware driver,
++ * though this is still incomplete and could use better documentation here
++ * or there...
++ */
++
++
++/*
++ * Partition info commands
++ *
++ * I do not know what those are for at this point
++ */
++#define SMU_CMD_PARTITION_COMMAND		0x3e
++
++
++/*
++ * Fan control
++ *
++ * This is a "mux" for fan control commands, first byte is the
++ * "sub" command.
++ */
++#define SMU_CMD_FAN_COMMAND			0x4a
++
++
++/*
++ * Battery access
++ *
++ * Same command number as the PMU, could it be same syntax ?
++ */
++#define SMU_CMD_BATTERY_COMMAND			0x6f
++#define   SMU_CMD_GET_BATTERY_INFO		0x00
++
++/*
++ * Real time clock control
++ *
++ * This is a "mux", first data byte contains the "sub" command.
++ * The "RTC" part of the SMU controls the date, time, powerup
++ * timer, but also a PRAM
++ *
++ * Dates are in BCD format on 7 bytes:
++ * [sec] [min] [hour] [weekday] [month day] [month] [year]
++ * with month being 1 based and year minus 100
++ */
++#define SMU_CMD_RTC_COMMAND			0x8e
++#define   SMU_CMD_RTC_SET_PWRUP_TIMER		0x00 /* i: 7 bytes date */
++#define   SMU_CMD_RTC_GET_PWRUP_TIMER		0x01 /* o: 7 bytes date */
++#define   SMU_CMD_RTC_STOP_PWRUP_TIMER		0x02
++#define   SMU_CMD_RTC_SET_PRAM_BYTE_ACC		0x20 /* i: 1 byte (address?) */
++#define   SMU_CMD_RTC_SET_PRAM_AUTOINC		0x21 /* i: 1 byte (data?) */
++#define   SMU_CMD_RTC_SET_PRAM_LO_BYTES 	0x22 /* i: 10 bytes */
++#define   SMU_CMD_RTC_SET_PRAM_HI_BYTES 	0x23 /* i: 10 bytes */
++#define   SMU_CMD_RTC_GET_PRAM_BYTE		0x28 /* i: 1 bytes (address?) */
++#define   SMU_CMD_RTC_GET_PRAM_LO_BYTES 	0x29 /* o: 10 bytes */
++#define   SMU_CMD_RTC_GET_PRAM_HI_BYTES 	0x2a /* o: 10 bytes */
++#define	  SMU_CMD_RTC_SET_DATETIME		0x80 /* i: 7 bytes date */
++#define   SMU_CMD_RTC_GET_DATETIME		0x81 /* o: 7 bytes date */
++
++ /*
++  * i2c commands
++  *
++  * To issue an i2c command, first is to send a parameter block to the
++  * the SMU. This is a command of type 0x9a with 9 bytes of header
++  * eventually followed by data for a write:
++  *
++  * 0: bus number (from device-tree usually, SMU has lots of busses !)
++  * 1: transfer type/format (see below)
++  * 2: device address. For combined and combined4 type transfers, this
++  *    is the "write" version of the address (bit 0x01 cleared)
++  * 3: subaddress length (0..3)
++  * 4: subaddress byte 0 (or only byte for subaddress length 1)
++  * 5: subaddress byte 1
++  * 6: subaddress byte 2
++  * 7: combined address (device address for combined mode data phase)
++  * 8: data length
++  *
++  * The transfer types are the same good old Apple ones it seems,
++  * that is:
++  *   - 0x00: Simple transfer
++  *   - 0x01: Subaddress transfer (addr write + data tx, no restart)
++  *   - 0x02: Combined transfer (addr write + restart + data tx)
++  *
++  * This is then followed by actual data for a write.
++  *
++  * At this point, the OF driver seems to have a limitation on transfer
++  * sizes of 0xd bytes on reads and 0x5 bytes on writes. I do not know
++  * wether this is just an OF limit due to some temporary buffer size
++  * or if this is an SMU imposed limit. This driver has the same limitation
++  * for now as I use a 0x10 bytes temporary buffer as well
++  *
++  * Once that is completed, a response is expected from the SMU. This is
++  * obtained via a command of type 0x9a with a length of 1 byte containing
++  * 0 as the data byte. OF also fills the rest of the data buffer with 0xff's
++  * though I can't tell yet if this is actually necessary. Once this command
++  * is complete, at this point, all I can tell is what OF does. OF tests
++  * byte 0 of the reply:
++  *   - on read, 0xfe or 0xfc : bus is busy, wait (see below) or nak ?
++  *   - on read, 0x00 or 0x01 : reply is in buffer (after the byte 0)
++  *   - on write, < 0 -> failure (immediate exit)
++  *   - else, OF just exists (without error, weird)
++  *
++  * So on read, there is this wait-for-busy thing when getting a 0xfc or
++  * 0xfe result. OF does a loop of up to 64 retries, waiting 20ms and
++  * doing the above again until either the retries expire or the result
++  * is no longer 0xfe or 0xfc
++  *
++  * The Darwin I2C driver is less subtle though. On any non-success status
++  * from the response command, it waits 5ms and tries again up to 20 times,
++  * it doesn't differenciate between fatal errors or "busy" status.
++  *
++  * This driver provides an asynchronous paramblock based i2c command
++  * interface to be used either directly by low level code or by a higher
++  * level driver interfacing to the linux i2c layer. The current
++  * implementation of this relies on working timers & timer interrupts
++  * though, so be careful of calling context for now. This may be "fixed"
++  * in the future by adding a polling facility.
++  */
++#define SMU_CMD_I2C_COMMAND			0x9a
++          /* transfer types */
++#define   SMU_I2C_TRANSFER_SIMPLE	0x00
++#define   SMU_I2C_TRANSFER_STDSUB	0x01
++#define   SMU_I2C_TRANSFER_COMBINED	0x02
++
++/*
++ * Power supply control
++ *
++ * The "sub" command is an ASCII string in the data, the
++ * data lenght is that of the string.
++ *
++ * The VSLEW command can be used to get or set the voltage slewing.
++ *  - lenght 5 (only "VSLEW") : it returns "DONE" and 3 bytes of
++ *    reply at data offset 6, 7 and 8.
++ *  - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is
++ *    used to set the voltage slewing point. The SMU replies with "DONE"
++ * I yet have to figure out their exact meaning of those 3 bytes in
++ * both cases.
++ *
++ */
++#define SMU_CMD_POWER_COMMAND			0xaa
++#define   SMU_CMD_POWER_RESTART		       	"RESTART"
++#define   SMU_CMD_POWER_SHUTDOWN		"SHUTDOWN"
++#define   SMU_CMD_POWER_VOLTAGE_SLEW		"VSLEW"
++
++/* Misc commands
++ *
++ * This command seem to be a grab bag of various things
++ */
++#define SMU_CMD_MISC_df_COMMAND			0xdf
++#define   SMU_CMD_MISC_df_SET_DISPLAY_LIT	0x02 /* i: 1 byte */
++#define   SMU_CMD_MISC_df_NMI_OPTION		0x04
++
++/*
++ * Version info commands
++ *
++ * I haven't quite tried to figure out how these work
++ */
++#define SMU_CMD_VERSION_COMMAND			0xea
++
++
++/*
++ * Misc commands
++ *
++ * This command seem to be a grab bag of various things
++ */
++#define SMU_CMD_MISC_ee_COMMAND			0xee
++#define   SMU_CMD_MISC_ee_GET_DATABLOCK_REC	0x02
++#define	  SMU_CMD_MISC_ee_LEDS_CTRL		0x04 /* i: 00 (00,01) [00] */
++#define   SMU_CMD_MISC_ee_GET_DATA		0x05 /* i: 00 , o: ?? */
++
++
++
++/*
++ * - Kernel side interface -
++ */
++
++#ifdef __KERNEL__
++
++/*
++ * Asynchronous SMU commands
++ *
++ * Fill up this structure and submit it via smu_queue_command(),
++ * and get notified by the optional done() callback, or because
++ * status becomes != 1
++ */
++
++struct smu_cmd;
++
++struct smu_cmd
++{
++	/* public */
++	u8			cmd;		/* command */
++	int			data_len;	/* data len */
++	int			reply_len;	/* reply len */
++	void			*data_buf;	/* data buffer */
++	void			*reply_buf;	/* reply buffer */
++	int			status;		/* command status */
++	void			(*done)(struct smu_cmd *cmd, void *misc);
++	void			*misc;
++
++	/* private */
++	struct list_head	link;
++};
++
++/*
++ * Queues an SMU command, all fields have to be initialized
++ */
++extern int smu_queue_cmd(struct smu_cmd *cmd);
++
++/*
++ * Simple command wrapper. This structure embeds a small buffer
++ * to ease sending simple SMU commands from the stack
++ */
++struct smu_simple_cmd
++{
++	struct smu_cmd	cmd;
++	u8	       	buffer[16];
++};
++
++/*
++ * Queues a simple command. All fields will be initialized by that
++ * function
++ */
++extern int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command,
++			    unsigned int data_len,
++			    void (*done)(struct smu_cmd *cmd, void *misc),
++			    void *misc,
++			    ...);
++
++/*
++ * Completion helper. Pass it to smu_queue_simple or as 'done'
++ * member to smu_queue_cmd, it will call complete() on the struct
++ * completion passed in the "misc" argument
++ */
++extern void smu_done_complete(struct smu_cmd *cmd, void *misc);
++
++/*
++ * Synchronous helpers. Will spin-wait for completion of a command
++ */
++extern void smu_spinwait_cmd(struct smu_cmd *cmd);
++
++static inline void smu_spinwait_simple(struct smu_simple_cmd *scmd)
++{
++	smu_spinwait_cmd(&scmd->cmd);
++}
++
++/*
++ * Poll routine to call if blocked with irqs off
++ */
++extern void smu_poll(void);
++
++
++/*
++ * Init routine, presence check....
++ */
++extern int smu_init(void);
++extern int smu_present(void);
++struct of_device;
++extern struct of_device *smu_get_ofdev(void);
++
++
++/*
++ * Common command wrappers
++ */
++extern void smu_shutdown(void);
++extern void smu_restart(void);
++struct rtc_time;
++extern int smu_get_rtc_time(struct rtc_time *time, int spinwait);
++extern int smu_set_rtc_time(struct rtc_time *time, int spinwait);
++
++/*
++ * SMU command buffer absolute address, exported by pmac_setup,
++ * this is allocated very early during boot.
++ */
++extern unsigned long smu_cmdbuf_abs;
++
++
++/*
++ * Kenrel asynchronous i2c interface
++ */
++
++/* SMU i2c header, exactly matches i2c header on wire */
++struct smu_i2c_param
++{
++	u8	bus;		/* SMU bus ID (from device tree) */
++	u8	type;		/* i2c transfer type */
++	u8	devaddr;	/* device address (includes direction) */
++	u8	sublen;		/* subaddress length */
++	u8	subaddr[3];	/* subaddress */
++	u8	caddr;		/* combined address, filled by SMU driver */
++	u8	datalen;	/* length of transfer */
++	u8	data[7];	/* data */
++};
++
++#define SMU_I2C_READ_MAX	0x0d
++#define SMU_I2C_WRITE_MAX	0x05
++
++struct smu_i2c_cmd
++{
++	/* public */
++	struct smu_i2c_param	info;
++	void			(*done)(struct smu_i2c_cmd *cmd, void *misc);
++	void			*misc;
++	int			status; /* 1 = pending, 0 = ok, <0 = fail */
++
++	/* private */
++	struct smu_cmd		scmd;
++	int			read;
++	int			stage;
++	int			retries;
++	u8			pdata[0x10];
++	struct list_head	link;
++};
++
++/*
++ * Call this to queue an i2c command to the SMU. You must fill info,
++ * including info.data for a write, done and misc.
++ * For now, no polling interface is provided so you have to use completion
++ * callback.
++ */
++extern int smu_queue_i2c(struct smu_i2c_cmd *cmd);
++
++
++#endif /* __KERNEL__ */
++
++/*
++ * - Userland interface -
++ */
++
++/*
++ * A given instance of the device can be configured for 2 different
++ * things at the moment:
++ *
++ *  - sending SMU commands (default at open() time)
++ *  - receiving SMU events (not yet implemented)
++ *
++ * Commands are written with write() of a command block. They can be
++ * "driver" commands (for example to switch to event reception mode)
++ * or real SMU commands. They are made of a header followed by command
++ * data if any.
++ *
++ * For SMU commands (not for driver commands), you can then read() back
++ * a reply. The reader will be blocked or not depending on how the device
++ * file is opened. poll() isn't implemented yet. The reply will consist
++ * of a header as well, followed by the reply data if any. You should
++ * always provide a buffer large enough for the maximum reply data, I
++ * recommand one page.
++ *
++ * It is illegal to send SMU commands through a file descriptor configured
++ * for events reception
++ *
++ */
++struct smu_user_cmd_hdr
++{
++	__u32		cmdtype;
++#define SMU_CMDTYPE_SMU			0	/* SMU command */
++#define SMU_CMDTYPE_WANTS_EVENTS	1	/* switch fd to events mode */
++
++	__u8		cmd;			/* SMU command byte */
++	__u32		data_len;		/* Lenght of data following */
++};
++
++struct smu_user_reply_hdr
++{
++	__u32		status;			/* Command status */
++	__u32		reply_len;		/* Lenght of data follwing */
++};
++
++#endif /*  _SMU_H */
+diff --git a/include/asm-powerpc/spinlock_types.h b/include/asm-powerpc/spinlock_types.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/spinlock_types.h
+@@ -0,0 +1,20 @@
++#ifndef _ASM_POWERPC_SPINLOCK_TYPES_H
++#define _ASM_POWERPC_SPINLOCK_TYPES_H
++
++#ifndef __LINUX_SPINLOCK_TYPES_H
++# error "please don't include this file directly"
++#endif
++
++typedef struct {
++	volatile unsigned int slock;
++} raw_spinlock_t;
++
++#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
++
++typedef struct {
++	volatile signed int lock;
++} raw_rwlock_t;
++
++#define __RAW_RW_LOCK_UNLOCKED		{ 0 }
++
++#endif
+diff --git a/include/asm-powerpc/sstep.h b/include/asm-powerpc/sstep.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/sstep.h
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2004 Paul Mackerras <paulus at au.ibm.com>, 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.
++ */
++
++struct pt_regs;
++
++/*
++ * We don't allow single-stepping an mtmsrd that would clear
++ * MSR_RI, since that would make the exception unrecoverable.
++ * Since we need to single-step to proceed from a breakpoint,
++ * we don't allow putting a breakpoint on an mtmsrd instruction.
++ * Similarly we don't allow breakpoints on rfid instructions.
++ * These macros tell us if an instruction is a mtmsrd or rfid.
++ * Note that IS_MTMSRD returns true for both an mtmsr (32-bit)
++ * and an mtmsrd (64-bit).
++ */
++#define IS_MTMSRD(instr)	(((instr) & 0xfc0007be) == 0x7c000124)
++#define IS_RFID(instr)		(((instr) & 0xfc0007fe) == 0x4c000024)
++
++/* Emulate instructions that cause a transfer of control. */
++extern int emulate_step(struct pt_regs *regs, unsigned int instr);
+diff --git a/include/asm-powerpc/statfs.h b/include/asm-powerpc/statfs.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/statfs.h
+@@ -0,0 +1,60 @@
++#ifndef _ASM_POWERPC_STATFS_H
++#define _ASM_POWERPC_STATFS_H
++
++/* For ppc32 we just use the generic definitions, not so simple on ppc64 */
++
++#ifndef __powerpc64__
++#include <asm-generic/statfs.h>
++#else
++
++#ifndef __KERNEL_STRICT_NAMES
++#include <linux/types.h>
++typedef __kernel_fsid_t	fsid_t;
++#endif
++
++/*
++ * We're already 64-bit, so duplicate the definition
++ */
++struct statfs {
++	long f_type;
++	long f_bsize;
++	long f_blocks;
++	long f_bfree;
++	long f_bavail;
++	long f_files;
++	long f_ffree;
++	__kernel_fsid_t f_fsid;
++	long f_namelen;
++	long f_frsize;
++	long f_spare[5];
++};
++
++struct statfs64 {
++	long f_type;
++	long f_bsize;
++	long f_blocks;
++	long f_bfree;
++	long f_bavail;
++	long f_files;
++	long f_ffree;
++	__kernel_fsid_t f_fsid;
++	long f_namelen;
++	long f_frsize;
++	long f_spare[5];
++};
++
++struct compat_statfs64 {
++	__u32 f_type;
++	__u32 f_bsize;
++	__u64 f_blocks;
++	__u64 f_bfree;
++	__u64 f_bavail;
++	__u64 f_files;
++	__u64 f_ffree;
++	__kernel_fsid_t f_fsid;
++	__u32 f_namelen;
++	__u32 f_frsize;
++	__u32 f_spare[5];
++};
++#endif /* ! __powerpc64__ */
++#endif
+diff --git a/include/asm-powerpc/synch.h b/include/asm-powerpc/synch.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/synch.h
+@@ -0,0 +1,51 @@
++#ifndef _ASM_POWERPC_SYNCH_H 
++#define _ASM_POWERPC_SYNCH_H 
++
++#include <linux/config.h>
++
++#ifdef __powerpc64__
++#define __SUBARCH_HAS_LWSYNC
++#endif
++
++#ifdef __SUBARCH_HAS_LWSYNC
++#    define LWSYNC	lwsync
++#else
++#    define LWSYNC	sync
++#endif
++
++
++/*
++ * Arguably the bitops and *xchg operations don't imply any memory barrier
++ * or SMP ordering, but in fact a lot of drivers expect them to imply
++ * both, since they do on x86 cpus.
++ */
++#ifdef CONFIG_SMP
++#define EIEIO_ON_SMP	"eieio\n"
++#define ISYNC_ON_SMP	"\n\tisync"
++#define SYNC_ON_SMP	__stringify(LWSYNC) "\n"
++#else
++#define EIEIO_ON_SMP
++#define ISYNC_ON_SMP
++#define SYNC_ON_SMP
++#endif
++
++static inline void eieio(void)
++{
++	__asm__ __volatile__ ("eieio" : : : "memory");
++}
++
++static inline void isync(void)
++{
++	__asm__ __volatile__ ("isync" : : : "memory");
++}
++
++#ifdef CONFIG_SMP
++#define eieio_on_smp()	eieio()
++#define isync_on_smp()	isync()
++#else
++#define eieio_on_smp()	__asm__ __volatile__("": : :"memory")
++#define isync_on_smp()	__asm__ __volatile__("": : :"memory")
++#endif
++
++#endif	/* _ASM_POWERPC_SYNCH_H */
++
+diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/system.h
+@@ -0,0 +1,363 @@
++/*
++ * Copyright (C) 1999 Cort Dougan <cort at cs.nmt.edu>
++ */
++#ifndef _ASM_POWERPC_SYSTEM_H
++#define _ASM_POWERPC_SYSTEM_H
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++
++#include <asm/hw_irq.h>
++#include <asm/ppc_asm.h>
++#include <asm/atomic.h>
++
++/*
++ * Memory barrier.
++ * The sync instruction guarantees that all memory accesses initiated
++ * by this processor have been performed (with respect to all other
++ * mechanisms that access memory).  The eieio instruction is a barrier
++ * providing an ordering (separately) for (a) cacheable stores and (b)
++ * loads and stores to non-cacheable memory (e.g. I/O devices).
++ *
++ * mb() prevents loads and stores being reordered across this point.
++ * rmb() prevents loads being reordered across this point.
++ * wmb() prevents stores being reordered across this point.
++ * read_barrier_depends() prevents data-dependent loads being reordered
++ *	across this point (nop on PPC).
++ *
++ * We have to use the sync instructions for mb(), since lwsync doesn't
++ * order loads with respect to previous stores.  Lwsync is fine for
++ * rmb(), though.  Note that lwsync is interpreted as sync by
++ * 32-bit and older 64-bit CPUs.
++ *
++ * For wmb(), we use sync since wmb is used in drivers to order
++ * stores to system memory with respect to writes to the device.
++ * However, smp_wmb() can be a lighter-weight eieio barrier on
++ * SMP since it is only used to order updates to system memory.
++ */
++#define mb()   __asm__ __volatile__ ("sync" : : : "memory")
++#define rmb()  __asm__ __volatile__ ("lwsync" : : : "memory")
++#define wmb()  __asm__ __volatile__ ("sync" : : : "memory")
++#define read_barrier_depends()  do { } while(0)
++
++#define set_mb(var, value)	do { var = value; mb(); } while (0)
++#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
++
++#ifdef CONFIG_SMP
++#define smp_mb()	mb()
++#define smp_rmb()	rmb()
++#define smp_wmb()	__asm__ __volatile__ ("eieio" : : : "memory")
++#define smp_read_barrier_depends()	read_barrier_depends()
++#else
++#define smp_mb()	barrier()
++#define smp_rmb()	barrier()
++#define smp_wmb()	barrier()
++#define smp_read_barrier_depends()	do { } while(0)
++#endif /* CONFIG_SMP */
++
++#ifdef __KERNEL__
++struct task_struct;
++struct pt_regs;
++
++#ifdef CONFIG_DEBUGGER
++
++extern int (*__debugger)(struct pt_regs *regs);
++extern int (*__debugger_ipi)(struct pt_regs *regs);
++extern int (*__debugger_bpt)(struct pt_regs *regs);
++extern int (*__debugger_sstep)(struct pt_regs *regs);
++extern int (*__debugger_iabr_match)(struct pt_regs *regs);
++extern int (*__debugger_dabr_match)(struct pt_regs *regs);
++extern int (*__debugger_fault_handler)(struct pt_regs *regs);
++
++#define DEBUGGER_BOILERPLATE(__NAME) \
++static inline int __NAME(struct pt_regs *regs) \
++{ \
++	if (unlikely(__ ## __NAME)) \
++		return __ ## __NAME(regs); \
++	return 0; \
++}
++
++DEBUGGER_BOILERPLATE(debugger)
++DEBUGGER_BOILERPLATE(debugger_ipi)
++DEBUGGER_BOILERPLATE(debugger_bpt)
++DEBUGGER_BOILERPLATE(debugger_sstep)
++DEBUGGER_BOILERPLATE(debugger_iabr_match)
++DEBUGGER_BOILERPLATE(debugger_dabr_match)
++DEBUGGER_BOILERPLATE(debugger_fault_handler)
++
++#ifdef CONFIG_XMON
++extern void xmon_init(int enable);
++#endif
++
++#else
++static inline int debugger(struct pt_regs *regs) { return 0; }
++static inline int debugger_ipi(struct pt_regs *regs) { return 0; }
++static inline int debugger_bpt(struct pt_regs *regs) { return 0; }
++static inline int debugger_sstep(struct pt_regs *regs) { return 0; }
++static inline int debugger_iabr_match(struct pt_regs *regs) { return 0; }
++static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
++static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
++#endif
++
++extern int set_dabr(unsigned long dabr);
++extern void print_backtrace(unsigned long *);
++extern void show_regs(struct pt_regs * regs);
++extern void flush_instruction_cache(void);
++extern void hard_reset_now(void);
++extern void poweroff_now(void);
++
++#ifdef CONFIG_6xx
++extern long _get_L2CR(void);
++extern long _get_L3CR(void);
++extern void _set_L2CR(unsigned long);
++extern void _set_L3CR(unsigned long);
++#else
++#define _get_L2CR()	0L
++#define _get_L3CR()	0L
++#define _set_L2CR(val)	do { } while(0)
++#define _set_L3CR(val)	do { } while(0)
++#endif
++
++extern void via_cuda_init(void);
++extern void read_rtc_time(void);
++extern void pmac_find_display(void);
++extern void giveup_fpu(struct task_struct *);
++extern void disable_kernel_fp(void);
++extern void enable_kernel_fp(void);
++extern void flush_fp_to_thread(struct task_struct *);
++extern void enable_kernel_altivec(void);
++extern void giveup_altivec(struct task_struct *);
++extern void load_up_altivec(struct task_struct *);
++extern int emulate_altivec(struct pt_regs *);
++extern void giveup_spe(struct task_struct *);
++extern void load_up_spe(struct task_struct *);
++extern int fix_alignment(struct pt_regs *);
++extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
++extern void cvt_df(double *from, float *to, struct thread_struct *thread);
++
++#ifdef CONFIG_ALTIVEC
++extern void flush_altivec_to_thread(struct task_struct *);
++#else
++static inline void flush_altivec_to_thread(struct task_struct *t)
++{
++}
++#endif
++
++#ifdef CONFIG_SPE
++extern void flush_spe_to_thread(struct task_struct *);
++#else
++static inline void flush_spe_to_thread(struct task_struct *t)
++{
++}
++#endif
++
++extern int call_rtas(const char *, int, int, unsigned long *, ...);
++extern void cacheable_memzero(void *p, unsigned int nb);
++extern void *cacheable_memcpy(void *, const void *, unsigned int);
++extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
++extern void bad_page_fault(struct pt_regs *, unsigned long, int);
++extern int die(const char *, struct pt_regs *, long);
++extern void _exception(int, struct pt_regs *, int, unsigned long);
++#ifdef CONFIG_BOOKE_WDT
++extern u32 booke_wdt_enabled;
++extern u32 booke_wdt_period;
++#endif /* CONFIG_BOOKE_WDT */
++
++/* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
++extern unsigned char e2a(unsigned char);
++
++struct device_node;
++extern void note_scsi_host(struct device_node *, void *);
++
++extern struct task_struct *__switch_to(struct task_struct *,
++	struct task_struct *);
++#define switch_to(prev, next, last)	((last) = __switch_to((prev), (next)))
++
++struct thread_struct;
++extern struct task_struct *_switch(struct thread_struct *prev,
++				   struct thread_struct *next);
++
++extern unsigned int rtas_data;
++extern int mem_init_done;	/* set on boot once kmalloc can be called */
++extern unsigned long memory_limit;
++
++extern int powersave_nap;	/* set if nap mode can be used in idle loop */
++
++/*
++ * Atomic exchange
++ *
++ * Changes the memory location '*ptr' to be val and returns
++ * the previous value stored there.
++ */
++static __inline__ unsigned long
++__xchg_u32(volatile void *p, unsigned long val)
++{
++	unsigned long prev;
++
++	__asm__ __volatile__(
++	EIEIO_ON_SMP
++"1:	lwarx	%0,0,%2 \n"
++	PPC405_ERR77(0,%2)
++"	stwcx.	%3,0,%2 \n\
++	bne-	1b"
++	ISYNC_ON_SMP
++	: "=&r" (prev), "=m" (*(volatile unsigned int *)p)
++	: "r" (p), "r" (val), "m" (*(volatile unsigned int *)p)
++	: "cc", "memory");
++
++	return prev;
++}
++
++#ifdef CONFIG_PPC64
++static __inline__ unsigned long
++__xchg_u64(volatile void *p, unsigned long val)
++{
++	unsigned long prev;
++
++	__asm__ __volatile__(
++	EIEIO_ON_SMP
++"1:	ldarx	%0,0,%2 \n"
++	PPC405_ERR77(0,%2)
++"	stdcx.	%3,0,%2 \n\
++	bne-	1b"
++	ISYNC_ON_SMP
++	: "=&r" (prev), "=m" (*(volatile unsigned long *)p)
++	: "r" (p), "r" (val), "m" (*(volatile unsigned long *)p)
++	: "cc", "memory");
++
++	return prev;
++}
++#endif
++
++/*
++ * This function doesn't exist, so you'll get a linker error
++ * if something tries to do an invalid xchg().
++ */
++extern void __xchg_called_with_bad_pointer(void);
++
++static __inline__ unsigned long
++__xchg(volatile void *ptr, unsigned long x, unsigned int size)
++{
++	switch (size) {
++	case 4:
++		return __xchg_u32(ptr, x);
++#ifdef CONFIG_PPC64
++	case 8:
++		return __xchg_u64(ptr, x);
++#endif
++	}
++	__xchg_called_with_bad_pointer();
++	return x;
++}
++
++#define xchg(ptr,x)							     \
++  ({									     \
++     __typeof__(*(ptr)) _x_ = (x);					     \
++     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
++  })
++
++#define tas(ptr) (xchg((ptr),1))
++
++/*
++ * Compare and exchange - if *p == old, set it to new,
++ * and return the old value of *p.
++ */
++#define __HAVE_ARCH_CMPXCHG	1
++
++static __inline__ unsigned long
++__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
++{
++	unsigned int prev;
++
++	__asm__ __volatile__ (
++	EIEIO_ON_SMP
++"1:	lwarx	%0,0,%2		# __cmpxchg_u32\n\
++	cmpw	0,%0,%3\n\
++	bne-	2f\n"
++	PPC405_ERR77(0,%2)
++"	stwcx.	%4,0,%2\n\
++	bne-	1b"
++	ISYNC_ON_SMP
++	"\n\
++2:"
++	: "=&r" (prev), "=m" (*p)
++	: "r" (p), "r" (old), "r" (new), "m" (*p)
++	: "cc", "memory");
++
++	return prev;
++}
++
++#ifdef CONFIG_PPC64
++static __inline__ unsigned long
++__cmpxchg_u64(volatile long *p, unsigned long old, unsigned long new)
++{
++	unsigned long prev;
++
++	__asm__ __volatile__ (
++	EIEIO_ON_SMP
++"1:	ldarx	%0,0,%2		# __cmpxchg_u64\n\
++	cmpd	0,%0,%3\n\
++	bne-	2f\n\
++	stdcx.	%4,0,%2\n\
++	bne-	1b"
++	ISYNC_ON_SMP
++	"\n\
++2:"
++	: "=&r" (prev), "=m" (*p)
++	: "r" (p), "r" (old), "r" (new), "m" (*p)
++	: "cc", "memory");
++
++	return prev;
++}
++#endif
++
++/* This function doesn't exist, so you'll get a linker error
++   if something tries to do an invalid cmpxchg().  */
++extern void __cmpxchg_called_with_bad_pointer(void);
++
++static __inline__ unsigned long
++__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
++	  unsigned int size)
++{
++	switch (size) {
++	case 4:
++		return __cmpxchg_u32(ptr, old, new);
++#ifdef CONFIG_PPC64
++	case 8:
++		return __cmpxchg_u64(ptr, old, new);
++#endif
++	}
++	__cmpxchg_called_with_bad_pointer();
++	return old;
++}
++
++#define cmpxchg(ptr,o,n)						 \
++  ({									 \
++     __typeof__(*(ptr)) _o_ = (o);					 \
++     __typeof__(*(ptr)) _n_ = (n);					 \
++     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		 \
++				    (unsigned long)_n_, sizeof(*(ptr))); \
++  })
++
++#ifdef CONFIG_PPC64
++/*
++ * We handle most unaligned accesses in hardware. On the other hand 
++ * unaligned DMA can be very expensive on some ppc64 IO chips (it does
++ * powers of 2 writes until it reaches sufficient alignment).
++ *
++ * Based on this we disable the IP header alignment in network drivers.
++ */
++#define NET_IP_ALIGN   0
++#endif
++
++#define arch_align_stack(x) (x)
++
++/* Used in very early kernel initialization. */
++extern unsigned long reloc_offset(void);
++extern unsigned long add_reloc_offset(unsigned long);
++extern void reloc_got2(unsigned long);
++
++#define PTRRELOC(x)	((typeof(x)) add_reloc_offset((unsigned long)(x)))
++
++#endif /* __KERNEL__ */
++#endif /* _ASM_POWERPC_SYSTEM_H */
+diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/thread_info.h
+@@ -0,0 +1,142 @@
++/* thread_info.h: PowerPC low-level thread information
++ * adapted from the i386 version by Paul Mackerras
++ *
++ * Copyright (C) 2002  David Howells (dhowells at redhat.com)
++ * - Incorporating suggestions made by Linus Torvalds and Dave Miller
++ */
++
++#ifndef _ASM_POWERPC_THREAD_INFO_H
++#define _ASM_POWERPC_THREAD_INFO_H
++
++#ifdef __KERNEL__
++
++/* We have 8k stacks on ppc32 and 16k on ppc64 */
++
++#ifdef CONFIG_PPC64
++#define THREAD_SHIFT		14
++#else
++#define THREAD_SHIFT		13
++#endif
++
++#define THREAD_SIZE		(1 << THREAD_SHIFT)
++
++#ifndef __ASSEMBLY__
++#include <linux/config.h>
++#include <linux/cache.h>
++#include <asm/processor.h>
++#include <asm/page.h>
++#include <linux/stringify.h>
++
++/*
++ * low level task data.
++ */
++struct thread_info {
++	struct task_struct *task;		/* main task structure */
++	struct exec_domain *exec_domain;	/* execution domain */
++	int		cpu;			/* cpu we're on */
++	int		preempt_count;		/* 0 => preemptable,
++						   <0 => BUG */
++	struct restart_block restart_block;
++	/* set by force_successful_syscall_return */
++	unsigned char	syscall_noerror;
++	/* low level flags - has atomic operations done on it */
++	unsigned long	flags ____cacheline_aligned_in_smp;
++};
++
++/*
++ * macros/functions for gaining access to the thread information structure
++ *
++ * preempt_count needs to be 1 initially, until the scheduler is functional.
++ */
++#define INIT_THREAD_INFO(tsk)			\
++{						\
++	.task =		&tsk,			\
++	.exec_domain =	&default_exec_domain,	\
++	.cpu =		0,			\
++	.preempt_count = 1,			\
++	.restart_block = {			\
++		.fn = do_no_restart_syscall,	\
++	},					\
++	.flags =	0,			\
++}
++
++#define init_thread_info	(init_thread_union.thread_info)
++#define init_stack		(init_thread_union.stack)
++
++/* thread information allocation */
++
++#ifdef CONFIG_DEBUG_STACK_USAGE
++#define THREAD_INFO_GFP		GFP_KERNEL | __GFP_ZERO
++#else
++#define THREAD_INFO_GFP		GFP_KERNEL
++#endif
++
++#if THREAD_SHIFT >= PAGE_SHIFT
++
++#define THREAD_ORDER	(THREAD_SHIFT - PAGE_SHIFT)
++
++#define alloc_thread_info(tsk)	\
++	((struct thread_info *)__get_free_pages(THREAD_INFO_GFP, THREAD_ORDER))
++#define free_thread_info(ti)	free_pages((unsigned long)ti, THREAD_ORDER)
++
++#else /* THREAD_SHIFT < PAGE_SHIFT */
++
++#define alloc_thread_info(tsk)	kmalloc(THREAD_SIZE, THREAD_INFO_GFP)
++#define free_thread_info(ti)	kfree(ti)
++
++#endif /* THREAD_SHIFT < PAGE_SHIFT */
++
++#define get_thread_info(ti)	get_task_struct((ti)->task)
++#define put_thread_info(ti)	put_task_struct((ti)->task)
++
++/* how to get the thread information struct from C */
++static inline struct thread_info *current_thread_info(void)
++{
++	register unsigned long sp asm("r1");
++
++	/* gcc4, at least, is smart enough to turn this into a single
++	 * rlwinm for ppc32 and clrrdi for ppc64 */
++	return (struct thread_info *)(sp & ~(THREAD_SIZE-1));
++}
++
++#endif /* __ASSEMBLY__ */
++
++#define PREEMPT_ACTIVE		0x10000000
++
++/*
++ * thread information flag bit numbers
++ */
++#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
++#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
++#define TIF_SIGPENDING		2	/* signal pending */
++#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
++#define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
++					   TIF_NEED_RESCHED */
++#define TIF_32BIT		5	/* 32 bit binary */
++/* #define SPARE		6 */
++#define TIF_ABI_PENDING		7	/* 32/64 bit switch needed */
++#define TIF_SYSCALL_AUDIT	8	/* syscall auditing active */
++#define TIF_SINGLESTEP		9	/* singlestepping active */
++#define TIF_MEMDIE		10
++#define TIF_SECCOMP		11	/* secure computing */
++
++/* as above, but as bit values */
++#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
++#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
++#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
++#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
++#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
++#define _TIF_32BIT		(1<<TIF_32BIT)
++/* #define _SPARE		(1<<SPARE) */
++#define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
++#define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
++#define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
++#define _TIF_SECCOMP		(1<<TIF_SECCOMP)
++#define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
++
++#define _TIF_USER_WORK_MASK	(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
++				 _TIF_NEED_RESCHED)
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_POWERPC_THREAD_INFO_H */
+diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/time.h
+@@ -0,0 +1,226 @@
++/*
++ * Common time prototypes and such for all ppc machines.
++ *
++ * Written by Cort Dougan (cort at cs.nmt.edu) to merge
++ * Paul Mackerras' version and mine for PReP and Pmac.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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 __POWERPC_TIME_H
++#define __POWERPC_TIME_H
++
++#ifdef __KERNEL__
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/percpu.h>
++
++#include <asm/processor.h>
++#ifdef CONFIG_PPC64
++#include <asm/paca.h>
++#include <asm/iSeries/HvCall.h>
++#endif
++
++/* time.c */
++extern unsigned long tb_ticks_per_jiffy;
++extern unsigned long tb_ticks_per_usec;
++extern unsigned long tb_ticks_per_sec;
++extern u64 tb_to_xs;
++extern unsigned      tb_to_us;
++extern unsigned long tb_last_stamp;
++extern u64 tb_last_jiffy;
++
++DECLARE_PER_CPU(unsigned long, last_jiffy);
++
++struct rtc_time;
++extern void to_tm(int tim, struct rtc_time * tm);
++extern time_t last_rtc_update;
++
++extern void generic_calibrate_decr(void);
++extern void wakeup_decrementer(void);
++
++/* Some sane defaults: 125 MHz timebase, 1GHz processor */
++extern unsigned long ppc_proc_freq;
++#define DEFAULT_PROC_FREQ	(DEFAULT_TB_FREQ * 8)
++extern unsigned long ppc_tb_freq;
++#define DEFAULT_TB_FREQ		125000000UL
++
++/*
++ * By putting all of this stuff into a single struct we 
++ * reduce the number of cache lines touched by do_gettimeofday.
++ * Both by collecting all of the data in one cache line and
++ * by touching only one TOC entry on ppc64.
++ */
++struct gettimeofday_vars {
++	u64 tb_to_xs;
++	u64 stamp_xsec;
++	u64 tb_orig_stamp;
++};
++
++struct gettimeofday_struct {
++	unsigned long tb_ticks_per_sec;
++	struct gettimeofday_vars vars[2];
++	struct gettimeofday_vars * volatile varp;
++	unsigned      var_idx;
++	unsigned      tb_to_us;
++};
++
++struct div_result {
++	u64 result_high;
++	u64 result_low;
++};
++
++/* Accessor functions for the timebase (RTC on 601) registers. */
++/* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
++#ifdef CONFIG_6xx
++#define __USE_RTC()	(!cpu_has_feature(CPU_FTR_USE_TB))
++#else
++#define __USE_RTC()	0
++#endif
++
++/* On ppc64 this gets us the whole timebase; on ppc32 just the lower half */
++static inline unsigned long get_tbl(void)
++{
++	unsigned long tbl;
++
++#if defined(CONFIG_403GCX)
++	asm volatile("mfspr %0, 0x3dd" : "=r" (tbl));
++#else
++	asm volatile("mftb %0" : "=r" (tbl));
++#endif
++	return tbl;
++}
++
++static inline unsigned int get_tbu(void)
++{
++	unsigned int tbu;
++
++#if defined(CONFIG_403GCX)
++	asm volatile("mfspr %0, 0x3dc" : "=r" (tbu));
++#else
++	asm volatile("mftbu %0" : "=r" (tbu));
++#endif
++	return tbu;
++}
++
++static inline unsigned int get_rtcl(void)
++{
++	unsigned int rtcl;
++
++	asm volatile("mfrtcl %0" : "=r" (rtcl));
++	return rtcl;
++}
++
++static inline u64 get_rtc(void)
++{
++	unsigned int hi, lo, hi2;
++
++	do {
++		asm volatile("mfrtcu %0; mfrtcl %1; mfrtcu %2"
++			     : "=r" (hi), "=r" (lo), "=r" (hi2));
++	} while (hi2 != hi);
++	return (u64)hi * 1000000000 + lo;
++}
++
++#ifdef CONFIG_PPC64
++static inline u64 get_tb(void)
++{
++	return mftb();
++}
++#else
++static inline u64 get_tb(void)
++{
++	unsigned int tbhi, tblo, tbhi2;
++
++	do {
++		tbhi = get_tbu();
++		tblo = get_tbl();
++		tbhi2 = get_tbu();
++	} while (tbhi != tbhi2);
++
++	return ((u64)tbhi << 32) | tblo;
++}
++#endif
++
++static inline void set_tb(unsigned int upper, unsigned int lower)
++{
++	mtspr(SPRN_TBWL, 0);
++	mtspr(SPRN_TBWU, upper);
++	mtspr(SPRN_TBWL, lower);
++}
++
++/* Accessor functions for the decrementer register.
++ * The 4xx doesn't even have a decrementer.  I tried to use the
++ * generic timer interrupt code, which seems OK, with the 4xx PIT
++ * in auto-reload mode.  The problem is PIT stops counting when it
++ * hits zero.  If it would wrap, we could use it just like a decrementer.
++ */
++static inline unsigned int get_dec(void)
++{
++#if defined(CONFIG_40x)
++	return (mfspr(SPRN_PIT));
++#else
++	return (mfspr(SPRN_DEC));
++#endif
++}
++
++static inline void set_dec(int val)
++{
++#if defined(CONFIG_40x)
++	return;		/* Have to let it auto-reload */
++#elif defined(CONFIG_8xx_CPU6)
++	set_dec_cpu6(val);
++#else
++#ifdef CONFIG_PPC_ISERIES
++	struct paca_struct *lpaca = get_paca();
++	int cur_dec;
++
++	if (lpaca->lppaca.shared_proc) {
++		lpaca->lppaca.virtual_decr = val;
++		cur_dec = get_dec();
++		if (cur_dec > val)
++			HvCall_setVirtualDecr();
++	} else
++#endif
++		mtspr(SPRN_DEC, val);
++#endif /* not 40x or 8xx_CPU6 */
++}
++
++static inline unsigned long tb_ticks_since(unsigned long tstamp)
++{
++	if (__USE_RTC()) {
++		int delta = get_rtcl() - (unsigned int) tstamp;
++		return delta < 0 ? delta + 1000000000 : delta;
++	}
++	return get_tbl() - tstamp;
++}
++
++#define mulhwu(x,y) \
++({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
++
++#ifdef CONFIG_PPC64
++#define mulhdu(x,y) \
++({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
++#else
++extern u64 mulhdu(u64, u64);
++#endif
++
++extern void smp_space_timers(unsigned int);
++
++extern unsigned mulhwu_scale_factor(unsigned, unsigned);
++extern void div128_by_32(u64 dividend_high, u64 dividend_low,
++			 unsigned divisor, struct div_result *dr);
++
++/* Used to store Processor Utilization register (purr) values */
++
++struct cpu_usage {
++        u64 current_tb;  /* Holds the current purr register values */
++};
++
++DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
++
++#endif /* __KERNEL__ */
++#endif /* __PPC64_TIME_H */
+diff --git a/include/asm-powerpc/types.h b/include/asm-powerpc/types.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/types.h
+@@ -0,0 +1,110 @@
++#ifndef _ASM_POWERPC_TYPES_H
++#define _ASM_POWERPC_TYPES_H
++
++#ifndef __ASSEMBLY__
++
++/*
++ * This file is never included by application software unless
++ * explicitly requested (e.g., via linux/types.h) in which case the
++ * application is Linux specific so (user-) name space pollution is
++ * not a major issue.  However, for interoperability, libraries still
++ * need to be careful to avoid a name clashes.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the 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 __powerpc64__
++typedef unsigned int umode_t;
++#else
++typedef unsigned short umode_t;
++#endif
++
++/*
++ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
++ * header files exported to user space
++ */
++
++typedef __signed__ char __s8;
++typedef unsigned char __u8;
++
++typedef __signed__ short __s16;
++typedef unsigned short __u16;
++
++typedef __signed__ int __s32;
++typedef unsigned int __u32;
++
++#ifdef __powerpc64__
++typedef __signed__ long __s64;
++typedef unsigned long __u64;
++#else
++#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
++typedef __signed__ long long __s64;
++typedef unsigned long long __u64;
++#endif
++#endif /* __powerpc64__ */
++
++typedef struct {
++	__u32 u[4];
++} __attribute((aligned(16))) __vector128;
++
++#endif /* __ASSEMBLY__ */
++
++#ifdef __KERNEL__
++/*
++ * These aren't exported outside the kernel to avoid name space clashes
++ */
++#ifdef __powerpc64__
++#define BITS_PER_LONG 64
++#else
++#define BITS_PER_LONG 32
++#endif
++
++#ifndef __ASSEMBLY__
++
++#include <linux/config.h>
++
++typedef signed char s8;
++typedef unsigned char u8;
++
++typedef signed short s16;
++typedef unsigned short u16;
++
++typedef signed int s32;
++typedef unsigned int u32;
++
++#ifdef __powerpc64__
++typedef signed long s64;
++typedef unsigned long u64;
++#else
++typedef signed long long s64;
++typedef unsigned long long u64;
++#endif
++
++typedef __vector128 vector128;
++
++#ifdef __powerpc64__
++typedef u64 dma_addr_t;
++#else
++typedef u32 dma_addr_t;
++#endif
++typedef u64 dma64_addr_t;
++
++typedef struct {
++	unsigned long entry;
++	unsigned long toc;
++	unsigned long env;
++} func_descr_t;
++
++#ifdef CONFIG_LBD
++typedef u64 sector_t;
++#define HAVE_SECTOR_T
++#endif
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_POWERPC_TYPES_H */
+diff --git a/include/asm-powerpc/uninorth.h b/include/asm-powerpc/uninorth.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/uninorth.h
+@@ -0,0 +1,229 @@
++/*
++ * uninorth.h: definitions for using the "UniNorth" host bridge chip
++ *             from Apple. This chip is used on "Core99" machines
++ *	       This also includes U2 used on more recent MacRISC2/3
++ *             machines and U3 (G5) 
++ *
++ */
++#ifdef __KERNEL__
++#ifndef __ASM_UNINORTH_H__
++#define __ASM_UNINORTH_H__
++
++/*
++ * Uni-N and U3 config space reg. definitions
++ *
++ * (Little endian)
++ */
++
++/* Address ranges selection. This one should work with Bandit too */
++/* Not U3 */
++#define UNI_N_ADDR_SELECT		0x48
++#define UNI_N_ADDR_COARSE_MASK		0xffff0000	/* 256Mb regions at *0000000 */
++#define UNI_N_ADDR_FINE_MASK		0x0000ffff	/*  16Mb regions at f*000000 */
++
++/* AGP registers */
++/* Not U3 */
++#define UNI_N_CFG_GART_BASE		0x8c
++#define UNI_N_CFG_AGP_BASE		0x90
++#define UNI_N_CFG_GART_CTRL		0x94
++#define UNI_N_CFG_INTERNAL_STATUS	0x98
++#define UNI_N_CFG_GART_DUMMY_PAGE	0xa4
++
++/* UNI_N_CFG_GART_CTRL bits definitions */
++#define UNI_N_CFG_GART_INVAL		0x00000001
++#define UNI_N_CFG_GART_ENABLE		0x00000100
++#define UNI_N_CFG_GART_2xRESET		0x00010000
++#define UNI_N_CFG_GART_DISSBADET	0x00020000
++/* The following seems to only be used only on U3 <j.glisse at gmail.com> */
++#define U3_N_CFG_GART_SYNCMODE		0x00040000
++#define U3_N_CFG_GART_PERFRD		0x00080000
++#define U3_N_CFG_GART_B2BGNT		0x00200000
++#define U3_N_CFG_GART_FASTDDR		0x00400000
++
++/* My understanding of UniNorth AGP as of UniNorth rev 1.0x,
++ * revision 1.5 (x4 AGP) may need further changes.
++ *
++ * AGP_BASE register contains the base address of the AGP aperture on
++ * the AGP bus. It doesn't seem to be visible to the CPU as of UniNorth 1.x,
++ * even if decoding of this address range is enabled in the address select
++ * register. Apparently, the only supported bases are 256Mb multiples
++ * (high 4 bits of that register).
++ *
++ * GART_BASE register appear to contain the physical address of the GART
++ * in system memory in the high address bits (page aligned), and the
++ * GART size in the low order bits (number of GART pages)
++ *
++ * The GART format itself is one 32bits word per physical memory page.
++ * This word contains, in little-endian format (!!!), the physical address
++ * of the page in the high bits, and what appears to be an "enable" bit
++ * in the LSB bit (0) that must be set to 1 when the entry is valid.
++ *
++ * Obviously, the GART is not cache coherent and so any change to it
++ * must be flushed to memory (or maybe just make the GART space non
++ * cachable). AGP memory itself doens't seem to be cache coherent neither.
++ *
++ * In order to invalidate the GART (which is probably necessary to inval
++ * the bridge internal TLBs), the following sequence has to be written,
++ * in order, to the GART_CTRL register:
++ *
++ *   UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_INVAL
++ *   UNI_N_CFG_GART_ENABLE
++ *   UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_2xRESET
++ *   UNI_N_CFG_GART_ENABLE
++ *
++ * As far as AGP "features" are concerned, it looks like fast write may
++ * not be supported but this has to be confirmed.
++ *
++ * Turning on AGP seem to require a double invalidate operation, one before
++ * setting the AGP command register, on after.
++ *
++ * Turning off AGP seems to require the following sequence: first wait
++ * for the AGP to be idle by reading the internal status register, then
++ * write in that order to the GART_CTRL register:
++ *
++ *   UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_INVAL
++ *   0
++ *   UNI_N_CFG_GART_2xRESET
++ *   0
++ */
++
++/*
++ * Uni-N memory mapped reg. definitions
++ *
++ * Those registers are Big-Endian !!
++ *
++ * Their meaning come from either Darwin and/or from experiments I made with
++ * the bootrom, I'm not sure about their exact meaning yet
++ *
++ */
++
++/* Version of the UniNorth chip */
++#define UNI_N_VERSION			0x0000		/* Known versions: 3,7 and 8 */
++
++#define UNI_N_VERSION_107		0x0003		/* 1.0.7 */
++#define UNI_N_VERSION_10A		0x0007		/* 1.0.10 */
++#define UNI_N_VERSION_150		0x0011		/* 1.5 */
++#define UNI_N_VERSION_200		0x0024		/* 2.0 */
++#define UNI_N_VERSION_PANGEA		0x00C0		/* Integrated U1 + K */
++#define UNI_N_VERSION_INTREPID		0x00D2		/* Integrated U2 + K */
++#define UNI_N_VERSION_300		0x0030		/* 3.0 (U3 on G5) */
++
++/* This register is used to enable/disable various clocks */
++#define UNI_N_CLOCK_CNTL		0x0020
++#define UNI_N_CLOCK_CNTL_PCI		0x00000001	/* PCI2 clock control */
++#define UNI_N_CLOCK_CNTL_GMAC		0x00000002	/* GMAC clock control */
++#define UNI_N_CLOCK_CNTL_FW		0x00000004	/* FireWire clock control */
++#define UNI_N_CLOCK_CNTL_ATA100		0x00000010	/* ATA-100 clock control (U2) */
++
++/* Power Management control */
++#define UNI_N_POWER_MGT			0x0030
++#define UNI_N_POWER_MGT_NORMAL		0x00
++#define UNI_N_POWER_MGT_IDLE2		0x01
++#define UNI_N_POWER_MGT_SLEEP		0x02
++
++/* This register is configured by Darwin depending on the UniN
++ * revision
++ */
++#define UNI_N_ARB_CTRL			0x0040
++#define UNI_N_ARB_CTRL_QACK_DELAY_SHIFT	15
++#define UNI_N_ARB_CTRL_QACK_DELAY_MASK	0x0e1f8000
++#define UNI_N_ARB_CTRL_QACK_DELAY	0x30
++#define UNI_N_ARB_CTRL_QACK_DELAY105	0x00
++
++/* This one _might_ return the CPU number of the CPU reading it;
++ * the bootROM decides whether to boot or to sleep/spinloop depending
++ * on this register beeing 0 or not
++ */
++#define UNI_N_CPU_NUMBER		0x0050
++
++/* This register appear to be read by the bootROM to decide what
++ *  to do on a non-recoverable reset (powerup or wakeup)
++ */
++#define UNI_N_HWINIT_STATE		0x0070
++#define UNI_N_HWINIT_STATE_SLEEPING	0x01
++#define UNI_N_HWINIT_STATE_RUNNING	0x02
++/* This last bit appear to be used by the bootROM to know the second
++ * CPU has started and will enter it's sleep loop with IP=0
++ */
++#define UNI_N_HWINIT_STATE_CPU1_FLAG	0x10000000
++
++/* This register controls AACK delay, which is set when 2004 iBook/PowerBook
++ * is in low speed mode.
++ */
++#define UNI_N_AACK_DELAY		0x0100
++#define UNI_N_AACK_DELAY_ENABLE		0x00000001
++
++/* Clock status for Intrepid */
++#define UNI_N_CLOCK_STOP_STATUS0	0x0150
++#define UNI_N_CLOCK_STOPPED_EXTAGP	0x00200000
++#define UNI_N_CLOCK_STOPPED_AGPDEL	0x00100000
++#define UNI_N_CLOCK_STOPPED_I2S0_45_49	0x00080000
++#define UNI_N_CLOCK_STOPPED_I2S0_18	0x00040000
++#define UNI_N_CLOCK_STOPPED_I2S1_45_49	0x00020000
++#define UNI_N_CLOCK_STOPPED_I2S1_18	0x00010000
++#define UNI_N_CLOCK_STOPPED_TIMER	0x00008000
++#define UNI_N_CLOCK_STOPPED_SCC_RTCLK18	0x00004000
++#define UNI_N_CLOCK_STOPPED_SCC_RTCLK32	0x00002000
++#define UNI_N_CLOCK_STOPPED_SCC_VIA32	0x00001000
++#define UNI_N_CLOCK_STOPPED_SCC_SLOT0	0x00000800
++#define UNI_N_CLOCK_STOPPED_SCC_SLOT1	0x00000400
++#define UNI_N_CLOCK_STOPPED_SCC_SLOT2	0x00000200
++#define UNI_N_CLOCK_STOPPED_PCI_FBCLKO	0x00000100
++#define UNI_N_CLOCK_STOPPED_VEO0	0x00000080
++#define UNI_N_CLOCK_STOPPED_VEO1	0x00000040
++#define UNI_N_CLOCK_STOPPED_USB0	0x00000020
++#define UNI_N_CLOCK_STOPPED_USB1	0x00000010
++#define UNI_N_CLOCK_STOPPED_USB2	0x00000008
++#define UNI_N_CLOCK_STOPPED_32		0x00000004
++#define UNI_N_CLOCK_STOPPED_45		0x00000002
++#define UNI_N_CLOCK_STOPPED_49		0x00000001
++
++#define UNI_N_CLOCK_STOP_STATUS1	0x0160
++#define UNI_N_CLOCK_STOPPED_PLL4REF	0x00080000
++#define UNI_N_CLOCK_STOPPED_CPUDEL	0x00040000
++#define UNI_N_CLOCK_STOPPED_CPU		0x00020000
++#define UNI_N_CLOCK_STOPPED_BUF_REFCKO	0x00010000
++#define UNI_N_CLOCK_STOPPED_PCI2	0x00008000
++#define UNI_N_CLOCK_STOPPED_FW		0x00004000
++#define UNI_N_CLOCK_STOPPED_GB		0x00002000
++#define UNI_N_CLOCK_STOPPED_ATA66	0x00001000
++#define UNI_N_CLOCK_STOPPED_ATA100	0x00000800
++#define UNI_N_CLOCK_STOPPED_MAX		0x00000400
++#define UNI_N_CLOCK_STOPPED_PCI1	0x00000200
++#define UNI_N_CLOCK_STOPPED_KLPCI	0x00000100
++#define UNI_N_CLOCK_STOPPED_USB0PCI	0x00000080
++#define UNI_N_CLOCK_STOPPED_USB1PCI	0x00000040
++#define UNI_N_CLOCK_STOPPED_USB2PCI	0x00000020
++#define UNI_N_CLOCK_STOPPED_7PCI1	0x00000008
++#define UNI_N_CLOCK_STOPPED_AGP		0x00000004
++#define UNI_N_CLOCK_STOPPED_PCI0	0x00000002
++#define UNI_N_CLOCK_STOPPED_18		0x00000001
++
++/* Intrepid registe to OF do-platform-clockspreading */
++#define UNI_N_CLOCK_SPREADING		0x190
++
++/* Uninorth 1.5 rev. has additional perf. monitor registers at 0xf00-0xf50 */
++
++
++/*
++ * U3 specific registers
++ */
++
++
++/* U3 Toggle */
++#define U3_TOGGLE_REG			0x00e0
++#define U3_PMC_START_STOP		0x0001
++#define U3_MPIC_RESET			0x0002
++#define U3_MPIC_OUTPUT_ENABLE		0x0004
++
++/* U3 API PHY Config 1 */
++#define U3_API_PHY_CONFIG_1		0x23030
++
++/* U3 HyperTransport registers */
++#define U3_HT_CONFIG_BASE      		0x70000
++#define U3_HT_LINK_COMMAND		0x100
++#define U3_HT_LINK_CONFIG		0x110
++#define U3_HT_LINK_FREQ			0x120
++
++#endif /* __ASM_UNINORTH_H__ */
++#endif /* __KERNEL__ */
+diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/unistd.h
+@@ -0,0 +1,509 @@
++#ifndef _ASM_PPC_UNISTD_H_
++#define _ASM_PPC_UNISTD_H_
++
++/*
++ * This file contains the system call numbers.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++#define __NR_restart_syscall	  0
++#define __NR_exit		  1
++#define __NR_fork		  2
++#define __NR_read		  3
++#define __NR_write		  4
++#define __NR_open		  5
++#define __NR_close		  6
++#define __NR_waitpid		  7
++#define __NR_creat		  8
++#define __NR_link		  9
++#define __NR_unlink		 10
++#define __NR_execve		 11
++#define __NR_chdir		 12
++#define __NR_time		 13
++#define __NR_mknod		 14
++#define __NR_chmod		 15
++#define __NR_lchown		 16
++#define __NR_break		 17
++#define __NR_oldstat		 18
++#define __NR_lseek		 19
++#define __NR_getpid		 20
++#define __NR_mount		 21
++#define __NR_umount		 22
++#define __NR_setuid		 23
++#define __NR_getuid		 24
++#define __NR_stime		 25
++#define __NR_ptrace		 26
++#define __NR_alarm		 27
++#define __NR_oldfstat		 28
++#define __NR_pause		 29
++#define __NR_utime		 30
++#define __NR_stty		 31
++#define __NR_gtty		 32
++#define __NR_access		 33
++#define __NR_nice		 34
++#define __NR_ftime		 35
++#define __NR_sync		 36
++#define __NR_kill		 37
++#define __NR_rename		 38
++#define __NR_mkdir		 39
++#define __NR_rmdir		 40
++#define __NR_dup		 41
++#define __NR_pipe		 42
++#define __NR_times		 43
++#define __NR_prof		 44
++#define __NR_brk		 45
++#define __NR_setgid		 46
++#define __NR_getgid		 47
++#define __NR_signal		 48
++#define __NR_geteuid		 49
++#define __NR_getegid		 50
++#define __NR_acct		 51
++#define __NR_umount2		 52
++#define __NR_lock		 53
++#define __NR_ioctl		 54
++#define __NR_fcntl		 55
++#define __NR_mpx		 56
++#define __NR_setpgid		 57
++#define __NR_ulimit		 58
++#define __NR_oldolduname	 59
++#define __NR_umask		 60
++#define __NR_chroot		 61
++#define __NR_ustat		 62
++#define __NR_dup2		 63
++#define __NR_getppid		 64
++#define __NR_getpgrp		 65
++#define __NR_setsid		 66
++#define __NR_sigaction		 67
++#define __NR_sgetmask		 68
++#define __NR_ssetmask		 69
++#define __NR_setreuid		 70
++#define __NR_setregid		 71
++#define __NR_sigsuspend		 72
++#define __NR_sigpending		 73
++#define __NR_sethostname	 74
++#define __NR_setrlimit		 75
++#define __NR_getrlimit		 76
++#define __NR_getrusage		 77
++#define __NR_gettimeofday	 78
++#define __NR_settimeofday	 79
++#define __NR_getgroups		 80
++#define __NR_setgroups		 81
++#define __NR_select		 82
++#define __NR_symlink		 83
++#define __NR_oldlstat		 84
++#define __NR_readlink		 85
++#define __NR_uselib		 86
++#define __NR_swapon		 87
++#define __NR_reboot		 88
++#define __NR_readdir		 89
++#define __NR_mmap		 90
++#define __NR_munmap		 91
++#define __NR_truncate		 92
++#define __NR_ftruncate		 93
++#define __NR_fchmod		 94
++#define __NR_fchown		 95
++#define __NR_getpriority	 96
++#define __NR_setpriority	 97
++#define __NR_profil		 98
++#define __NR_statfs		 99
++#define __NR_fstatfs		100
++#define __NR_ioperm		101
++#define __NR_socketcall		102
++#define __NR_syslog		103
++#define __NR_setitimer		104
++#define __NR_getitimer		105
++#define __NR_stat		106
++#define __NR_lstat		107
++#define __NR_fstat		108
++#define __NR_olduname		109
++#define __NR_iopl		110
++#define __NR_vhangup		111
++#define __NR_idle		112
++#define __NR_vm86		113
++#define __NR_wait4		114
++#define __NR_swapoff		115
++#define __NR_sysinfo		116
++#define __NR_ipc		117
++#define __NR_fsync		118
++#define __NR_sigreturn		119
++#define __NR_clone		120
++#define __NR_setdomainname	121
++#define __NR_uname		122
++#define __NR_modify_ldt		123
++#define __NR_adjtimex		124
++#define __NR_mprotect		125
++#define __NR_sigprocmask	126
++#define __NR_create_module	127
++#define __NR_init_module	128
++#define __NR_delete_module	129
++#define __NR_get_kernel_syms	130
++#define __NR_quotactl		131
++#define __NR_getpgid		132
++#define __NR_fchdir		133
++#define __NR_bdflush		134
++#define __NR_sysfs		135
++#define __NR_personality	136
++#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
++#define __NR_setfsuid		138
++#define __NR_setfsgid		139
++#define __NR__llseek		140
++#define __NR_getdents		141
++#define __NR__newselect		142
++#define __NR_flock		143
++#define __NR_msync		144
++#define __NR_readv		145
++#define __NR_writev		146
++#define __NR_getsid		147
++#define __NR_fdatasync		148
++#define __NR__sysctl		149
++#define __NR_mlock		150
++#define __NR_munlock		151
++#define __NR_mlockall		152
++#define __NR_munlockall		153
++#define __NR_sched_setparam		154
++#define __NR_sched_getparam		155
++#define __NR_sched_setscheduler		156
++#define __NR_sched_getscheduler		157
++#define __NR_sched_yield		158
++#define __NR_sched_get_priority_max	159
++#define __NR_sched_get_priority_min	160
++#define __NR_sched_rr_get_interval	161
++#define __NR_nanosleep		162
++#define __NR_mremap		163
++#define __NR_setresuid		164
++#define __NR_getresuid		165
++#define __NR_query_module	166
++#define __NR_poll		167
++#define __NR_nfsservctl		168
++#define __NR_setresgid		169
++#define __NR_getresgid		170
++#define __NR_prctl		171
++#define __NR_rt_sigreturn	172
++#define __NR_rt_sigaction	173
++#define __NR_rt_sigprocmask	174
++#define __NR_rt_sigpending	175
++#define __NR_rt_sigtimedwait	176
++#define __NR_rt_sigqueueinfo	177
++#define __NR_rt_sigsuspend	178
++#define __NR_pread64		179
++#define __NR_pwrite64		180
++#define __NR_chown		181
++#define __NR_getcwd		182
++#define __NR_capget		183
++#define __NR_capset		184
++#define __NR_sigaltstack	185
++#define __NR_sendfile		186
++#define __NR_getpmsg		187	/* some people actually want streams */
++#define __NR_putpmsg		188	/* some people actually want streams */
++#define __NR_vfork		189
++#define __NR_ugetrlimit		190	/* SuS compliant getrlimit */
++#define __NR_readahead		191
++#ifndef __powerpc64__			/* these are 32-bit only */
++#define __NR_mmap2		192
++#define __NR_truncate64		193
++#define __NR_ftruncate64	194
++#define __NR_stat64		195
++#define __NR_lstat64		196
++#define __NR_fstat64		197
++#endif
++#define __NR_pciconfig_read	198
++#define __NR_pciconfig_write	199
++#define __NR_pciconfig_iobase	200
++#define __NR_multiplexer	201
++#define __NR_getdents64		202
++#define __NR_pivot_root		203
++#ifndef __powerpc64__
++#define __NR_fcntl64		204
++#endif
++#define __NR_madvise		205
++#define __NR_mincore		206
++#define __NR_gettid		207
++#define __NR_tkill		208
++#define __NR_setxattr		209
++#define __NR_lsetxattr		210
++#define __NR_fsetxattr		211
++#define __NR_getxattr		212
++#define __NR_lgetxattr		213
++#define __NR_fgetxattr		214
++#define __NR_listxattr		215
++#define __NR_llistxattr		216
++#define __NR_flistxattr		217
++#define __NR_removexattr	218
++#define __NR_lremovexattr	219
++#define __NR_fremovexattr	220
++#define __NR_futex		221
++#define __NR_sched_setaffinity	222
++#define __NR_sched_getaffinity	223
++/* 224 currently unused */
++#define __NR_tuxcall		225
++#ifndef __powerpc64__
++#define __NR_sendfile64		226
++#endif
++#define __NR_io_setup		227
++#define __NR_io_destroy		228
++#define __NR_io_getevents	229
++#define __NR_io_submit		230
++#define __NR_io_cancel		231
++#define __NR_set_tid_address	232
++#define __NR_fadvise64		233
++#define __NR_exit_group		234
++#define __NR_lookup_dcookie	235
++#define __NR_epoll_create	236
++#define __NR_epoll_ctl		237
++#define __NR_epoll_wait		238
++#define __NR_remap_file_pages	239
++#define __NR_timer_create	240
++#define __NR_timer_settime	241
++#define __NR_timer_gettime	242
++#define __NR_timer_getoverrun	243
++#define __NR_timer_delete	244
++#define __NR_clock_settime	245
++#define __NR_clock_gettime	246
++#define __NR_clock_getres	247
++#define __NR_clock_nanosleep	248
++#define __NR_swapcontext	249
++#define __NR_tgkill		250
++#define __NR_utimes		251
++#define __NR_statfs64		252
++#define __NR_fstatfs64		253
++#ifndef __powerpc64__
++#define __NR_fadvise64_64	254
++#endif
++#define __NR_rtas		255
++#define __NR_sys_debug_setcontext 256
++/* Number 257 is reserved for vserver */
++/* 258 currently unused */
++#define __NR_mbind		259
++#define __NR_get_mempolicy	260
++#define __NR_set_mempolicy	261
++#define __NR_mq_open		262
++#define __NR_mq_unlink		263
++#define __NR_mq_timedsend	264
++#define __NR_mq_timedreceive	265
++#define __NR_mq_notify		266
++#define __NR_mq_getsetattr	267
++#define __NR_kexec_load		268
++#define __NR_add_key		269
++#define __NR_request_key	270
++#define __NR_keyctl		271
++#define __NR_waitid		272
++#define __NR_ioprio_set		273
++#define __NR_ioprio_get		274
++#define __NR_inotify_init	275
++#define __NR_inotify_add_watch	276
++#define __NR_inotify_rm_watch	277
++
++#define __NR_syscalls		278
++
++#ifdef __KERNEL__
++#define __NR__exit __NR_exit
++#define NR_syscalls	__NR_syscalls
++#endif
++
++#ifndef __ASSEMBLY__
++
++/* On powerpc a system call basically clobbers the same registers like a
++ * function call, with the exception of LR (which is needed for the
++ * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
++ * an error return status).
++ */
++
++#define __syscall_nr(nr, type, name, args...)				\
++	unsigned long __sc_ret, __sc_err;				\
++	{								\
++		register unsigned long __sc_0  __asm__ ("r0");		\
++		register unsigned long __sc_3  __asm__ ("r3");		\
++		register unsigned long __sc_4  __asm__ ("r4");		\
++		register unsigned long __sc_5  __asm__ ("r5");		\
++		register unsigned long __sc_6  __asm__ ("r6");		\
++		register unsigned long __sc_7  __asm__ ("r7");		\
++		register unsigned long __sc_8  __asm__ ("r8");		\
++									\
++		__sc_loadargs_##nr(name, args);				\
++		__asm__ __volatile__					\
++			("sc           \n\t"				\
++			 "mfcr %0      "				\
++			: "=&r" (__sc_0),				\
++			  "=&r" (__sc_3),  "=&r" (__sc_4),		\
++			  "=&r" (__sc_5),  "=&r" (__sc_6),		\
++			  "=&r" (__sc_7),  "=&r" (__sc_8)		\
++			: __sc_asm_input_##nr				\
++			: "cr0", "ctr", "memory",			\
++			  "r9", "r10","r11", "r12");			\
++		__sc_ret = __sc_3;					\
++		__sc_err = __sc_0;					\
++	}								\
++	if (__sc_err & 0x10000000)					\
++	{								\
++		errno = __sc_ret;					\
++		__sc_ret = -1;						\
++	}								\
++	return (type) __sc_ret
++
++#define __sc_loadargs_0(name, dummy...)					\
++	__sc_0 = __NR_##name
++#define __sc_loadargs_1(name, arg1)					\
++	__sc_loadargs_0(name);						\
++	__sc_3 = (unsigned long) (arg1)
++#define __sc_loadargs_2(name, arg1, arg2)				\
++	__sc_loadargs_1(name, arg1);					\
++	__sc_4 = (unsigned long) (arg2)
++#define __sc_loadargs_3(name, arg1, arg2, arg3)				\
++	__sc_loadargs_2(name, arg1, arg2);				\
++	__sc_5 = (unsigned long) (arg3)
++#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4)			\
++	__sc_loadargs_3(name, arg1, arg2, arg3);			\
++	__sc_6 = (unsigned long) (arg4)
++#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5)		\
++	__sc_loadargs_4(name, arg1, arg2, arg3, arg4);			\
++	__sc_7 = (unsigned long) (arg5)
++#define __sc_loadargs_6(name, arg1, arg2, arg3, arg4, arg5, arg6)	\
++	__sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5);		\
++	__sc_8 = (unsigned long) (arg6)
++
++#define __sc_asm_input_0 "0" (__sc_0)
++#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
++#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
++#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
++#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
++#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
++#define __sc_asm_input_6 __sc_asm_input_5, "6" (__sc_8)
++
++#define _syscall0(type,name)						\
++type name(void)								\
++{									\
++	__syscall_nr(0, type, name);					\
++}
++
++#define _syscall1(type,name,type1,arg1)					\
++type name(type1 arg1)							\
++{									\
++	__syscall_nr(1, type, name, arg1);				\
++}
++
++#define _syscall2(type,name,type1,arg1,type2,arg2)			\
++type name(type1 arg1, type2 arg2)					\
++{									\
++	__syscall_nr(2, type, name, arg1, arg2);			\
++}
++
++#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
++type name(type1 arg1, type2 arg2, type3 arg3)				\
++{									\
++	__syscall_nr(3, type, name, arg1, arg2, arg3);			\
++}
++
++#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
++type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)		\
++{									\
++	__syscall_nr(4, type, name, arg1, arg2, arg3, arg4);		\
++}
++
++#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
++type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
++{									\
++	__syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5);	\
++}
++#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
++type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
++{									\
++	__syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
++}
++
++#ifdef __KERNEL__
++
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/compiler.h>
++#include <linux/linkage.h>
++
++#define __ARCH_WANT_IPC_PARSE_VERSION
++#define __ARCH_WANT_OLD_READDIR
++#define __ARCH_WANT_STAT64
++#define __ARCH_WANT_SYS_ALARM
++#define __ARCH_WANT_SYS_GETHOSTNAME
++#define __ARCH_WANT_SYS_PAUSE
++#define __ARCH_WANT_SYS_SGETMASK
++#define __ARCH_WANT_SYS_SIGNAL
++#define __ARCH_WANT_SYS_TIME
++#define __ARCH_WANT_SYS_UTIME
++#define __ARCH_WANT_SYS_WAITPID
++#define __ARCH_WANT_SYS_SOCKETCALL
++#define __ARCH_WANT_SYS_FADVISE64
++#define __ARCH_WANT_SYS_GETPGRP
++#define __ARCH_WANT_SYS_LLSEEK
++#define __ARCH_WANT_SYS_NICE
++#define __ARCH_WANT_SYS_OLD_GETRLIMIT
++#define __ARCH_WANT_SYS_OLDUMOUNT
++#define __ARCH_WANT_SYS_SIGPENDING
++#define __ARCH_WANT_SYS_SIGPROCMASK
++#define __ARCH_WANT_SYS_RT_SIGACTION
++#ifdef CONFIG_PPC32
++#define __ARCH_WANT_OLD_STAT
++#endif
++#ifdef CONFIG_PPC64
++#define __ARCH_WANT_COMPAT_SYS_TIME
++#endif
++
++/*
++ * System call prototypes.
++ */
++#ifdef __KERNEL_SYSCALLS__
++extern pid_t setsid(void);
++extern int write(int fd, const char *buf, off_t count);
++extern int read(int fd, char *buf, off_t count);
++extern off_t lseek(int fd, off_t offset, int count);
++extern int dup(int fd);
++extern int execve(const char *file, char **argv, char **envp);
++extern int open(const char *file, int flag, int mode);
++extern int close(int fd);
++extern pid_t waitpid(pid_t pid, int *wait_stat, int options);
++#endif /* __KERNEL_SYSCALLS__ */
++
++/*
++ * Functions that implement syscalls.
++ */
++unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot,
++		       unsigned long flags, unsigned long fd, off_t offset);
++unsigned long sys_mmap2(unsigned long addr, size_t len,
++			unsigned long prot, unsigned long flags,
++			unsigned long fd, unsigned long pgoff);
++struct pt_regs;
++int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
++		unsigned long a3, unsigned long a4, unsigned long a5,
++		struct pt_regs *regs);
++int sys_clone(unsigned long clone_flags, unsigned long usp,
++		int __user *parent_tidp, void __user *child_threadptr,
++		int __user *child_tidp, int p6, struct pt_regs *regs);
++int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
++		unsigned long p4, unsigned long p5, unsigned long p6,
++		struct pt_regs *regs);
++int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
++		unsigned long p4, unsigned long p5, unsigned long p6,
++		struct pt_regs *regs);
++int sys_pipe(int __user *fildes);
++struct sigaction;
++long sys_rt_sigaction(int sig, const struct sigaction __user *act,
++		      struct sigaction __user *oact, size_t sigsetsize);
++
++/*
++ * "Conditional" syscalls
++ *
++ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
++ * but it doesn't work on all toolchains, so we just do it by hand
++ */
++#ifdef CONFIG_PPC32
++#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
++#else
++#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall")
++#endif
++
++#endif		/* __KERNEL__ */
++
++#endif		/* __ASSEMBLY__ */
++
++#endif /* _ASM_PPC_UNISTD_H_ */
+diff --git a/include/asm-powerpc/vga.h b/include/asm-powerpc/vga.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/vga.h
+@@ -0,0 +1,54 @@
++#ifndef _ASM_POWERPC_VGA_H_
++#define _ASM_POWERPC_VGA_H_
++
++#ifdef __KERNEL__
++
++/*
++ *	Access to VGA videoram
++ *
++ *	(c) 1998 Martin Mares <mj at ucw.cz>
++ */
++
++
++#include <asm/io.h>
++
++#include <linux/config.h>
++
++#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
++
++#define VT_BUF_HAVE_RW
++/*
++ *  These are only needed for supporting VGA or MDA text mode, which use little
++ *  endian byte ordering.
++ *  In other cases, we can optimize by using native byte ordering and
++ *  <linux/vt_buffer.h> has already done the right job for us.
++ */
++
++static inline void scr_writew(u16 val, volatile u16 *addr)
++{
++    st_le16(addr, val);
++}
++
++static inline u16 scr_readw(volatile const u16 *addr)
++{
++    return ld_le16(addr);
++}
++
++#define VT_BUF_HAVE_MEMCPYW
++#define scr_memcpyw	memcpy
++
++#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
++
++extern unsigned long vgacon_remap_base;
++
++#ifdef __powerpc64__
++#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0))
++#else
++#define VGA_MAP_MEM(x) (x + vgacon_remap_base)
++#endif
++
++#define vga_readb(x) (*(x))
++#define vga_writeb(x,y) (*(y) = (x))
++
++#endif	/* __KERNEL__ */
++#endif	/* _ASM_POWERPC_VGA_H_ */
+diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/vio.h
+@@ -0,0 +1,106 @@
++/*
++ * IBM PowerPC Virtual I/O Infrastructure Support.
++ *
++ * Copyright (c) 2003 IBM Corp.
++ *  Dave Engebretsen engebret at us.ibm.com
++ *  Santiago Leon santil at 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.
++ */
++
++#ifndef _ASM_POWERPC_VIO_H
++#define _ASM_POWERPC_VIO_H
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++#include <linux/mod_devicetable.h>
++
++#include <asm/hvcall.h>
++#include <asm/scatterlist.h>
++
++/*
++ * Architecture-specific constants for drivers to
++ * extract attributes of the device using vio_get_attribute()
++ */
++#define VETH_MAC_ADDR "local-mac-address"
++#define VETH_MCAST_FILTER_SIZE "ibm,mac-address-filters"
++
++/* End architecture-specific constants */
++
++#define h_vio_signal(ua, mode) \
++  plpar_hcall_norets(H_VIO_SIGNAL, ua, mode)
++
++#define VIO_IRQ_DISABLE		0UL
++#define VIO_IRQ_ENABLE		1UL
++
++struct iommu_table;
++
++/*
++ * The vio_dev structure is used to describe virtual I/O devices.
++ */
++struct vio_dev {
++	struct iommu_table *iommu_table;     /* vio_map_* uses this */
++	char *name;
++	char *type;
++	uint32_t unit_address;
++	unsigned int irq;
++	struct device dev;
++};
++
++struct vio_driver {
++	struct list_head node;
++	const struct vio_device_id *id_table;
++	int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
++	int (*remove)(struct vio_dev *dev);
++	void (*shutdown)(struct vio_dev *dev);
++	unsigned long driver_data;
++	struct device_driver driver;
++};
++
++struct vio_bus_ops {
++	int (*match)(const struct vio_device_id *id, const struct vio_dev *dev);
++	void (*unregister_device)(struct vio_dev *);
++	void (*release_device)(struct device *);
++};
++
++extern struct dma_mapping_ops vio_dma_ops;
++extern struct bus_type vio_bus_type;
++extern struct vio_dev vio_bus_device;
++
++extern int vio_register_driver(struct vio_driver *drv);
++extern void vio_unregister_driver(struct vio_driver *drv);
++
++extern struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev);
++extern void __devinit vio_unregister_device(struct vio_dev *dev);
++
++extern int vio_bus_init(struct vio_bus_ops *);
++
++#ifdef CONFIG_PPC_PSERIES
++struct device_node;
++
++extern struct vio_dev * __devinit vio_register_device_node(
++		struct device_node *node_vdev);
++extern struct vio_dev *vio_find_node(struct device_node *vnode);
++extern const void *vio_get_attribute(struct vio_dev *vdev, void *which,
++		int *length);
++extern int vio_enable_interrupts(struct vio_dev *dev);
++extern int vio_disable_interrupts(struct vio_dev *dev);
++#endif
++
++static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
++{
++	return container_of(drv, struct vio_driver, driver);
++}
++
++static inline struct vio_dev *to_vio_dev(struct device *dev)
++{
++	return container_of(dev, struct vio_dev, dev);
++}
++
++#endif /* _ASM_POWERPC_VIO_H */
+diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-powerpc/xmon.h
+@@ -0,0 +1,12 @@
++#ifndef __PPC_XMON_H
++#define __PPC_XMON_H
++#ifdef __KERNEL__
++
++struct pt_regs;
++
++extern int xmon(struct pt_regs *excp);
++extern void xmon_printf(const char *fmt, ...);
++extern void xmon_init(int);
++
++#endif
++#endif
+diff --git a/include/asm-ppc/a.out.h b/include/asm-ppc/a.out.h
+deleted file mode 100644
+--- a/include/asm-ppc/a.out.h
++++ /dev/null
+@@ -1,26 +0,0 @@
+-#ifndef __PPC_A_OUT_H__
+-#define __PPC_A_OUT_H__
+-
+-/* grabbed from the intel stuff  */
+-#define STACK_TOP TASK_SIZE
+-
+-
+-struct exec
+-{
+-  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+-  unsigned a_text;		/* length of text, in bytes */
+-  unsigned a_data;		/* length of data, in bytes */
+-  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+-  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+-  unsigned a_entry;		/* start address */
+-  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+-  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+-};
+-
+-
+-#define N_TRSIZE(a)	((a).a_trsize)
+-#define N_DRSIZE(a)	((a).a_drsize)
+-#define N_SYMSIZE(a)	((a).a_syms)
+-
+-
+-#endif
+diff --git a/include/asm-ppc/atomic.h b/include/asm-ppc/atomic.h
+deleted file mode 100644
+--- a/include/asm-ppc/atomic.h
++++ /dev/null
+@@ -1,214 +0,0 @@
+-/*
+- * PowerPC atomic operations
+- */
+-
+-#ifndef _ASM_PPC_ATOMIC_H_
+-#define _ASM_PPC_ATOMIC_H_
+-
+-typedef struct { volatile int counter; } atomic_t;
+-
+-#ifdef __KERNEL__
+-
+-#define ATOMIC_INIT(i)	{ (i) }
+-
+-#define atomic_read(v)		((v)->counter)
+-#define atomic_set(v,i)		(((v)->counter) = (i))
+-
+-extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
+-
+-#ifdef CONFIG_SMP
+-#define SMP_SYNC	"sync"
+-#define SMP_ISYNC	"\n\tisync"
+-#else
+-#define SMP_SYNC	""
+-#define SMP_ISYNC
+-#endif
+-
+-/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx.
+- * The old ATOMIC_SYNC_FIX covered some but not all of this.
+- */
+-#ifdef CONFIG_IBM405_ERR77
+-#define PPC405_ERR77(ra,rb)	"dcbt " #ra "," #rb ";"
+-#else
+-#define PPC405_ERR77(ra,rb)
+-#endif
+-
+-static __inline__ void atomic_add(int a, atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%3		# atomic_add\n\
+-	add	%0,%2,%0\n"
+-	PPC405_ERR77(0,%3)
+-"	stwcx.	%0,0,%3 \n\
+-	bne-	1b"
+-	: "=&r" (t), "=m" (v->counter)
+-	: "r" (a), "r" (&v->counter), "m" (v->counter)
+-	: "cc");
+-}
+-
+-static __inline__ int atomic_add_return(int a, atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%2		# atomic_add_return\n\
+-	add	%0,%1,%0\n"
+-	PPC405_ERR77(0,%2)
+-"	stwcx.	%0,0,%2 \n\
+-	bne-	1b"
+-	SMP_ISYNC
+-	: "=&r" (t)
+-	: "r" (a), "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-#define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
+-
+-static __inline__ void atomic_sub(int a, atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%3		# atomic_sub\n\
+-	subf	%0,%2,%0\n"
+-	PPC405_ERR77(0,%3)
+-"	stwcx.	%0,0,%3 \n\
+-	bne-	1b"
+-	: "=&r" (t), "=m" (v->counter)
+-	: "r" (a), "r" (&v->counter), "m" (v->counter)
+-	: "cc");
+-}
+-
+-static __inline__ int atomic_sub_return(int a, atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%2		# atomic_sub_return\n\
+-	subf	%0,%1,%0\n"
+-	PPC405_ERR77(0,%2)
+-"	stwcx.	%0,0,%2 \n\
+-	bne-	1b"
+-	SMP_ISYNC
+-	: "=&r" (t)
+-	: "r" (a), "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-static __inline__ void atomic_inc(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%2		# atomic_inc\n\
+-	addic	%0,%0,1\n"
+-	PPC405_ERR77(0,%2)
+-"	stwcx.	%0,0,%2 \n\
+-	bne-	1b"
+-	: "=&r" (t), "=m" (v->counter)
+-	: "r" (&v->counter), "m" (v->counter)
+-	: "cc");
+-}
+-
+-static __inline__ int atomic_inc_return(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%1		# atomic_inc_return\n\
+-	addic	%0,%0,1\n"
+-	PPC405_ERR77(0,%1)
+-"	stwcx.	%0,0,%1 \n\
+-	bne-	1b"
+-	SMP_ISYNC
+-	: "=&r" (t)
+-	: "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-/*
+- * atomic_inc_and_test - increment and test
+- * @v: pointer of type atomic_t
+- *
+- * Atomically increments @v by 1
+- * and returns true if the result is zero, or false for all
+- * other cases.
+- */
+-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+-
+-static __inline__ void atomic_dec(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%2		# atomic_dec\n\
+-	addic	%0,%0,-1\n"
+-	PPC405_ERR77(0,%2)\
+-"	stwcx.	%0,0,%2\n\
+-	bne-	1b"
+-	: "=&r" (t), "=m" (v->counter)
+-	: "r" (&v->counter), "m" (v->counter)
+-	: "cc");
+-}
+-
+-static __inline__ int atomic_dec_return(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%1		# atomic_dec_return\n\
+-	addic	%0,%0,-1\n"
+-	PPC405_ERR77(0,%1)
+-"	stwcx.	%0,0,%1\n\
+-	bne-	1b"
+-	SMP_ISYNC
+-	: "=&r" (t)
+-	: "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-#define atomic_sub_and_test(a, v)	(atomic_sub_return((a), (v)) == 0)
+-#define atomic_dec_and_test(v)		(atomic_dec_return((v)) == 0)
+-
+-/*
+- * Atomically test *v and decrement if it is greater than 0.
+- * The function returns the old value of *v minus 1.
+- */
+-static __inline__ int atomic_dec_if_positive(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%1		# atomic_dec_if_positive\n\
+-	addic.	%0,%0,-1\n\
+-	blt-	2f\n"
+-	PPC405_ERR77(0,%1)
+-"	stwcx.	%0,0,%1\n\
+-	bne-	1b"
+-	SMP_ISYNC
+-	"\n\
+-2:"	: "=&r" (t)
+-	: "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-#define __MB	__asm__ __volatile__ (SMP_SYNC : : : "memory")
+-#define smp_mb__before_atomic_dec()	__MB
+-#define smp_mb__after_atomic_dec()	__MB
+-#define smp_mb__before_atomic_inc()	__MB
+-#define smp_mb__after_atomic_inc()	__MB
+-
+-#endif /* __KERNEL__ */
+-#endif /* _ASM_PPC_ATOMIC_H_ */
+diff --git a/include/asm-ppc/auxvec.h b/include/asm-ppc/auxvec.h
+deleted file mode 100644
+--- a/include/asm-ppc/auxvec.h
++++ /dev/null
+@@ -1,14 +0,0 @@
+-#ifndef __PPC_AUXVEC_H
+-#define __PPC_AUXVEC_H
+-
+-/*
+- * We need to put in some extra aux table entries to tell glibc what
+- * the cache block size is, so it can use the dcbz instruction safely.
+- */
+-#define AT_DCACHEBSIZE		19
+-#define AT_ICACHEBSIZE		20
+-#define AT_UCACHEBSIZE		21
+-/* A special ignored type value for PPC, for glibc compatibility.  */
+-#define AT_IGNOREPPC		22
+-
+-#endif
+diff --git a/include/asm-ppc/backlight.h b/include/asm-ppc/backlight.h
+deleted file mode 100644
+--- a/include/asm-ppc/backlight.h
++++ /dev/null
+@@ -1,30 +0,0 @@
+-/*
+- * Routines for handling backlight control on PowerBooks
+- *
+- * For now, implementation resides in arch/ppc/kernel/pmac_support.c
+- *
+- */
+-#ifdef __KERNEL__
+-#ifndef __ASM_PPC_BACKLIGHT_H
+-#define __ASM_PPC_BACKLIGHT_H
+-
+-/* Abstract values */
+-#define BACKLIGHT_OFF	0
+-#define BACKLIGHT_MIN	1
+-#define BACKLIGHT_MAX	0xf
+-
+-struct backlight_controller {
+-	int (*set_enable)(int enable, int level, void *data);
+-	int (*set_level)(int level, void *data);
+-};
+-
+-extern void register_backlight_controller(struct backlight_controller *ctrler, void *data, char *type);
+-extern void unregister_backlight_controller(struct backlight_controller *ctrler, void *data);
+-
+-extern int set_backlight_enable(int enable);
+-extern int get_backlight_enable(void);
+-extern int set_backlight_level(int level);
+-extern int get_backlight_level(void);
+-
+-#endif
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/bug.h b/include/asm-ppc/bug.h
+deleted file mode 100644
+--- a/include/asm-ppc/bug.h
++++ /dev/null
+@@ -1,58 +0,0 @@
+-#ifndef _PPC_BUG_H
+-#define _PPC_BUG_H
+-
+-struct bug_entry {
+-	unsigned long	bug_addr;
+-	int		line;
+-	const char	*file;
+-	const char	*function;
+-};
+-
+-/*
+- * If this bit is set in the line number it means that the trap
+- * is for WARN_ON rather than BUG or BUG_ON.
+- */
+-#define BUG_WARNING_TRAP	0x1000000
+-
+-#ifdef CONFIG_BUG
+-#define BUG() do {							 \
+-	__asm__ __volatile__(						 \
+-		"1:	twi 31,0,0\n"					 \
+-		".section __bug_table,\"a\"\n\t"			 \
+-		"	.long 1b,%0,%1,%2\n"				 \
+-		".previous"						 \
+-		: : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
+-} while (0)
+-
+-#define BUG_ON(x) do {							\
+-	if (!__builtin_constant_p(x) || (x)) {				\
+-		__asm__ __volatile__(					\
+-			"1:	twnei %0,0\n"				\
+-			".section __bug_table,\"a\"\n\t"		\
+-			"	.long 1b,%1,%2,%3\n"			\
+-			".previous"					\
+-			: : "r" (x), "i" (__LINE__), "i" (__FILE__),	\
+-			    "i" (__FUNCTION__));			\
+-	}								\
+-} while (0)
+-
+-#define WARN_ON(x) do {							\
+-	if (!__builtin_constant_p(x) || (x)) {				\
+-		__asm__ __volatile__(					\
+-			"1:	twnei %0,0\n"				\
+-			".section __bug_table,\"a\"\n\t"		\
+-			"	.long 1b,%1,%2,%3\n"			\
+-			".previous"					\
+-			: : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP),	\
+-			    "i" (__FILE__), "i" (__FUNCTION__));	\
+-	}								\
+-} while (0)
+-
+-#define HAVE_ARCH_BUG
+-#define HAVE_ARCH_BUG_ON
+-#define HAVE_ARCH_WARN_ON
+-#endif
+-
+-#include <asm-generic/bug.h>
+-
+-#endif
+diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h
+deleted file mode 100644
+--- a/include/asm-ppc/byteorder.h
++++ /dev/null
+@@ -1,76 +0,0 @@
+-#ifndef _PPC_BYTEORDER_H
+-#define _PPC_BYTEORDER_H
+-
+-#include <asm/types.h>
+-#include <linux/compiler.h>
+-
+-#ifdef __GNUC__
+-#ifdef __KERNEL__
+-
+-extern __inline__ unsigned ld_le16(const volatile unsigned short *addr)
+-{
+-	unsigned val;
+-
+-	__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+-	return val;
+-}
+-
+-extern __inline__ void st_le16(volatile unsigned short *addr, const unsigned val)
+-{
+-	__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+-}
+-
+-extern __inline__ unsigned ld_le32(const volatile unsigned *addr)
+-{
+-	unsigned val;
+-
+-	__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+-	return val;
+-}
+-
+-extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val)
+-{
+-	__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+-}
+-
+-static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
+-{
+-	__u16 result;
+-
+-	__asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (value >> 8), "r" (value));
+-	return result;
+-}
+-
+-static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
+-{
+-	__u32 result;
+-
+-	__asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (value>>24), "r" (value));
+-	__asm__("rlwimi %0,%2,8,8,15"   : "=&r" (result) : "0" (result),    "r" (value));
+-	__asm__("rlwimi %0,%2,24,0,7"   : "=&r" (result) : "0" (result),    "r" (value));
+-
+-	return result;
+-}
+-#define __arch__swab32(x) ___arch__swab32(x)
+-#define __arch__swab16(x) ___arch__swab16(x)
+-
+-/* The same, but returns converted value from the location pointer by addr. */
+-#define __arch__swab16p(addr) ld_le16(addr)
+-#define __arch__swab32p(addr) ld_le32(addr)
+-
+-/* The same, but do the conversion in situ, ie. put the value back to addr. */
+-#define __arch__swab16s(addr) st_le16(addr,*addr)
+-#define __arch__swab32s(addr) st_le32(addr,*addr)
+-
+-#endif /* __KERNEL__ */
+-
+-#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+-#  define __BYTEORDER_HAS_U64__
+-#  define __SWAB_64_THRU_32__
+-#endif
+-
+-#endif /* __GNUC__ */
+-
+-#include <linux/byteorder/big_endian.h>
+-
+-#endif /* _PPC_BYTEORDER_H */
+diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h
+--- a/include/asm-ppc/cache.h
++++ b/include/asm-ppc/cache.h
+@@ -9,21 +9,18 @@
+ 
+ /* bytes per L1 cache line */
+ #if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
+-#define	L1_CACHE_LINE_SIZE	16
+-#define LG_L1_CACHE_LINE_SIZE	4
++#define L1_CACHE_SHIFT	4
+ #define MAX_COPY_PREFETCH	1
+ #elif defined(CONFIG_PPC64BRIDGE)
+-#define L1_CACHE_LINE_SIZE	128
+-#define LG_L1_CACHE_LINE_SIZE	7
++#define L1_CACHE_SHIFT	7
+ #define MAX_COPY_PREFETCH	1
+ #else
+-#define	L1_CACHE_LINE_SIZE	32
+-#define LG_L1_CACHE_LINE_SIZE	5
++#define L1_CACHE_SHIFT	5
+ #define MAX_COPY_PREFETCH	4
+ #endif
+ 
+-#define	L1_CACHE_BYTES L1_CACHE_LINE_SIZE
+-#define L1_CACHE_SHIFT LG_L1_CACHE_LINE_SIZE
++#define	L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
++
+ #define	SMP_CACHE_BYTES L1_CACHE_BYTES
+ #define L1_CACHE_SHIFT_MAX 7	/* largest L1 which this arch supports */
+ 
+diff --git a/include/asm-ppc/checksum.h b/include/asm-ppc/checksum.h
+deleted file mode 100644
+--- a/include/asm-ppc/checksum.h
++++ /dev/null
+@@ -1,107 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef _PPC_CHECKSUM_H
+-#define _PPC_CHECKSUM_H
+-
+-
+-/*
+- * computes the checksum of a memory block at buff, length len,
+- * and adds in "sum" (32-bit)
+- *
+- * returns a 32-bit number suitable for feeding into itself
+- * or csum_tcpudp_magic
+- *
+- * this function must be called with even lengths, except
+- * for the last fragment, which may be odd
+- *
+- * it's best to have buff aligned on a 32-bit boundary
+- */
+-extern unsigned int csum_partial(const unsigned char * buff, int len,
+-				 unsigned int sum);
+-
+-/*
+- * Computes the checksum of a memory block at src, length len,
+- * and adds in "sum" (32-bit), while copying the block to dst.
+- * If an access exception occurs on src or dst, it stores -EFAULT
+- * to *src_err or *dst_err respectively (if that pointer is not
+- * NULL), and, for an error on src, zeroes the rest of dst.
+- *
+- * Like csum_partial, this must be called with even lengths,
+- * except for the last fragment.
+- */
+-extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
+-					      int len, unsigned int sum,
+-					      int *src_err, int *dst_err);
+-
+-#define csum_partial_copy_from_user(src, dst, len, sum, errp)	\
+-	csum_partial_copy_generic((__force void *)(src), (dst), (len), (sum), (errp), NULL)
+-
+-/* FIXME: this needs to be written to really do no check -- Cort */
+-#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+-	csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
+-
+-/*
+- * turns a 32-bit partial checksum (e.g. from csum_partial) into a
+- * 1's complement 16-bit checksum.
+- */
+-static inline unsigned int csum_fold(unsigned int sum)
+-{
+-	unsigned int tmp;
+-
+-	/* swap the two 16-bit halves of sum */
+-	__asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum));
+-	/* if there is a carry from adding the two 16-bit halves,
+-	   it will carry from the lower half into the upper half,
+-	   giving us the correct sum in the upper half. */
+-	sum = ~(sum + tmp) >> 16;
+-	return sum;
+-}
+-
+-/*
+- * this routine is used for miscellaneous IP-like checksums, mainly
+- * in icmp.c
+- */
+-static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
+-{
+-	return csum_fold(csum_partial(buff, len, 0));
+-}
+-
+-/*
+- * FIXME: I swiped this one from the sparc and made minor modifications.
+- * It may not be correct.  -- Cort
+- */
+-static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
+-						   unsigned long daddr,
+-						   unsigned short len,
+-						   unsigned short proto,
+-						   unsigned int sum)
+-{
+-    __asm__("\n\
+-	addc %0,%0,%1 \n\
+-	adde %0,%0,%2 \n\
+-	adde %0,%0,%3 \n\
+-	addze %0,%0 \n\
+-	"
+-	: "=r" (sum)
+-	: "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum));
+-    return sum;
+-}
+-
+-/*
+- * This is a version of ip_compute_csum() optimized for IP headers,
+- * which always checksum on 4 octet boundaries.  ihl is the number
+- * of 32-bit words and is always >= 5.
+- */
+-extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
+-
+-/*
+- * computes the checksum of the TCP/UDP pseudo-header
+- * returns a 16-bit checksum, already complemented
+- */
+-extern unsigned short csum_tcpudp_magic(unsigned long saddr,
+-					unsigned long daddr,
+-					unsigned short len,
+-					unsigned short proto,
+-					unsigned int sum);
+-
+-#endif
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
+--- a/include/asm-ppc/cpm2.h
++++ b/include/asm-ppc/cpm2.h
+@@ -1087,6 +1087,9 @@ typedef struct im_idma {
+ #define SCCR_PCIDF_MSK	0x00000078	/* PCI division factor	*/
+ #define SCCR_PCIDF_SHIFT 3
+ 
++#ifndef CPM_IMMR_OFFSET
++#define CPM_IMMR_OFFSET	0x101a8
++#endif
+ 
+ #endif /* __CPM2__ */
+ #endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/cputable.h b/include/asm-ppc/cputable.h
+deleted file mode 100644
+--- a/include/asm-ppc/cputable.h
++++ /dev/null
+@@ -1,129 +0,0 @@
+-/*
+- *  include/asm-ppc/cputable.h
+- *
+- *  Copyright (C) 2001 Ben. Herrenschmidt (benh at 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 __ASM_PPC_CPUTABLE_H
+-#define __ASM_PPC_CPUTABLE_H
+-
+-/* Exposed to userland CPU features */
+-#define PPC_FEATURE_32			0x80000000
+-#define PPC_FEATURE_64			0x40000000
+-#define PPC_FEATURE_601_INSTR		0x20000000
+-#define PPC_FEATURE_HAS_ALTIVEC		0x10000000
+-#define PPC_FEATURE_HAS_FPU		0x08000000
+-#define PPC_FEATURE_HAS_MMU		0x04000000
+-#define PPC_FEATURE_HAS_4xxMAC		0x02000000
+-#define PPC_FEATURE_UNIFIED_CACHE	0x01000000
+-#define PPC_FEATURE_HAS_SPE		0x00800000
+-#define PPC_FEATURE_HAS_EFP_SINGLE	0x00400000
+-#define PPC_FEATURE_HAS_EFP_DOUBLE	0x00200000
+-#define PPC_FEATURE_NO_TB		0x00100000
+-
+-#ifdef __KERNEL__
+-
+-#ifndef __ASSEMBLY__
+-
+-/* This structure can grow, it's real size is used by head.S code
+- * via the mkdefs mecanism.
+- */
+-struct cpu_spec;
+-
+-typedef	void (*cpu_setup_t)(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+-
+-struct cpu_spec {
+-	/* CPU is matched via (PVR & pvr_mask) == pvr_value */
+-	unsigned int	pvr_mask;
+-	unsigned int	pvr_value;
+-
+-	char		*cpu_name;
+-	unsigned int	cpu_features;		/* Kernel features */
+-	unsigned int	cpu_user_features;	/* Userland features */
+-
+-	/* cache line sizes */
+-	unsigned int	icache_bsize;
+-	unsigned int	dcache_bsize;
+-
+-	/* number of performance monitor counters */
+-	unsigned int	num_pmcs;
+-
+-	/* this is called to initialize various CPU bits like L1 cache,
+-	 * BHT, SPD, etc... from head.S before branching to identify_machine
+-	 */
+-	cpu_setup_t	cpu_setup;
+-};
+-
+-extern struct cpu_spec		cpu_specs[];
+-extern struct cpu_spec		*cur_cpu_spec[];
+-
+-static inline unsigned int cpu_has_feature(unsigned int feature)
+-{
+-	return cur_cpu_spec[0]->cpu_features & feature;
+-}
+-
+-#endif /* __ASSEMBLY__ */
+-
+-/* CPU kernel features */
+-#define CPU_FTR_SPLIT_ID_CACHE		0x00000001
+-#define CPU_FTR_L2CR			0x00000002
+-#define CPU_FTR_SPEC7450		0x00000004
+-#define CPU_FTR_ALTIVEC			0x00000008
+-#define CPU_FTR_TAU			0x00000010
+-#define CPU_FTR_CAN_DOZE		0x00000020
+-#define CPU_FTR_USE_TB			0x00000040
+-#define CPU_FTR_604_PERF_MON		0x00000080
+-#define CPU_FTR_601			0x00000100
+-#define CPU_FTR_HPTE_TABLE		0x00000200
+-#define CPU_FTR_CAN_NAP			0x00000400
+-#define CPU_FTR_L3CR			0x00000800
+-#define CPU_FTR_L3_DISABLE_NAP		0x00001000
+-#define CPU_FTR_NAP_DISABLE_L2_PR	0x00002000
+-#define CPU_FTR_DUAL_PLL_750FX		0x00004000
+-#define CPU_FTR_NO_DPM			0x00008000
+-#define CPU_FTR_HAS_HIGH_BATS		0x00010000
+-#define CPU_FTR_NEED_COHERENT		0x00020000
+-#define CPU_FTR_NO_BTIC			0x00040000
+-#define CPU_FTR_BIG_PHYS		0x00080000
+-
+-#ifdef __ASSEMBLY__
+-
+-#define BEGIN_FTR_SECTION		98:
+-
+-#define END_FTR_SECTION(msk, val)		\
+-99:						\
+-	.section __ftr_fixup,"a";		\
+-	.align 2;				\
+-	.long msk;				\
+-	.long val;				\
+-	.long 98b;				\
+-	.long 99b;				\
+-	.previous
+-
+-#else
+-
+-#define BEGIN_FTR_SECTION		"98:\n"
+-#define END_FTR_SECTION(msk, val)		\
+-"99:\n"						\
+-"	.section __ftr_fixup,\"a\";\n"		\
+-"	.align 2;\n"				\
+-"	.long "#msk";\n"			\
+-"	.long "#val";\n"			\
+-"	.long 98b;\n"			        \
+-"	.long 99b;\n"	 		        \
+-"	.previous\n"
+-
+-
+-#endif /* __ASSEMBLY__ */
+-
+-#define END_FTR_SECTION_IFSET(msk)	END_FTR_SECTION((msk), (msk))
+-#define END_FTR_SECTION_IFCLR(msk)	END_FTR_SECTION((msk), 0)
+-
+-#endif /* __ASM_PPC_CPUTABLE_H */
+-#endif /* __KERNEL__ */
+-
+diff --git a/include/asm-ppc/dbdma.h b/include/asm-ppc/dbdma.h
+deleted file mode 100644
+--- a/include/asm-ppc/dbdma.h
++++ /dev/null
+@@ -1,102 +0,0 @@
+-/*
+- * Definitions for using the Apple Descriptor-Based DMA controller
+- * in Power Macintosh computers.
+- *
+- * Copyright (C) 1996 Paul Mackerras.
+- */
+-
+-#ifdef __KERNEL__
+-#ifndef _ASM_DBDMA_H_
+-#define _ASM_DBDMA_H_
+-/*
+- * DBDMA control/status registers.  All little-endian.
+- */
+-struct dbdma_regs {
+-    unsigned int control;	/* lets you change bits in status */
+-    unsigned int status;	/* DMA and device status bits (see below) */
+-    unsigned int cmdptr_hi;	/* upper 32 bits of command address */
+-    unsigned int cmdptr;	/* (lower 32 bits of) command address (phys) */
+-    unsigned int intr_sel;	/* select interrupt condition bit */
+-    unsigned int br_sel;	/* select branch condition bit */
+-    unsigned int wait_sel;	/* select wait condition bit */
+-    unsigned int xfer_mode;
+-    unsigned int data2ptr_hi;
+-    unsigned int data2ptr;
+-    unsigned int res1;
+-    unsigned int address_hi;
+-    unsigned int br_addr_hi;
+-    unsigned int res2[3];
+-};
+-
+-/* Bits in control and status registers */
+-#define RUN	0x8000
+-#define PAUSE	0x4000
+-#define FLUSH	0x2000
+-#define WAKE	0x1000
+-#define DEAD	0x0800
+-#define ACTIVE	0x0400
+-#define BT	0x0100
+-#define DEVSTAT	0x00ff
+-
+-/*
+- * DBDMA command structure.  These fields are all little-endian!
+- */
+-struct dbdma_cmd {
+-    unsigned short req_count;	/* requested byte transfer count */
+-    unsigned short command;	/* command word (has bit-fields) */
+-    unsigned int   phy_addr;	/* physical data address */
+-    unsigned int   cmd_dep;	/* command-dependent field */
+-    unsigned short res_count;	/* residual count after completion */
+-    unsigned short xfer_status;	/* transfer status */
+-};
+-
+-/* DBDMA command values in command field */
+-#define OUTPUT_MORE	0	/* transfer memory data to stream */
+-#define OUTPUT_LAST	0x1000	/* ditto followed by end marker */
+-#define INPUT_MORE	0x2000	/* transfer stream data to memory */
+-#define INPUT_LAST	0x3000	/* ditto, expect end marker */
+-#define STORE_WORD	0x4000	/* write word (4 bytes) to device reg */
+-#define LOAD_WORD	0x5000	/* read word (4 bytes) from device reg */
+-#define DBDMA_NOP	0x6000	/* do nothing */
+-#define DBDMA_STOP	0x7000	/* suspend processing */
+-
+-/* Key values in command field */
+-#define KEY_STREAM0	0	/* usual data stream */
+-#define KEY_STREAM1	0x100	/* control/status stream */
+-#define KEY_STREAM2	0x200	/* device-dependent stream */
+-#define KEY_STREAM3	0x300	/* device-dependent stream */
+-#define KEY_REGS	0x500	/* device register space */
+-#define KEY_SYSTEM	0x600	/* system memory-mapped space */
+-#define KEY_DEVICE	0x700	/* device memory-mapped space */
+-
+-/* Interrupt control values in command field */
+-#define INTR_NEVER	0	/* don't interrupt */
+-#define INTR_IFSET	0x10	/* intr if condition bit is 1 */
+-#define INTR_IFCLR	0x20	/* intr if condition bit is 0 */
+-#define INTR_ALWAYS	0x30	/* always interrupt */
+-
+-/* Branch control values in command field */
+-#define BR_NEVER	0	/* don't branch */
+-#define BR_IFSET	0x4	/* branch if condition bit is 1 */
+-#define BR_IFCLR	0x8	/* branch if condition bit is 0 */
+-#define BR_ALWAYS	0xc	/* always branch */
+-
+-/* Wait control values in command field */
+-#define WAIT_NEVER	0	/* don't wait */
+-#define WAIT_IFSET	1	/* wait if condition bit is 1 */
+-#define WAIT_IFCLR	2	/* wait if condition bit is 0 */
+-#define WAIT_ALWAYS	3	/* always wait */
+-
+-/* Align an address for a DBDMA command structure */
+-#define DBDMA_ALIGN(x)	(((unsigned long)(x) + sizeof(struct dbdma_cmd) - 1) \
+-			 & -sizeof(struct dbdma_cmd))
+-
+-/* Useful macros */
+-#define DBDMA_DO_STOP(regs) do {				\
+-	out_le32(&((regs)->control), (RUN|FLUSH)<<16);		\
+-	while(in_le32(&((regs)->status)) & (ACTIVE|FLUSH))	\
+-		;						\
+-} while(0)
+-
+-#endif /* _ASM_DBDMA_H_ */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/dma-mapping.h b/include/asm-ppc/dma-mapping.h
+--- a/include/asm-ppc/dma-mapping.h
++++ b/include/asm-ppc/dma-mapping.h
+@@ -19,7 +19,7 @@
+  * allocate the space "normally" and use the cache management functions
+  * to ensure it is consistent.
+  */
+-extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, int gfp);
++extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp);
+ extern void __dma_free_coherent(size_t size, void *vaddr);
+ extern void __dma_sync(void *vaddr, size_t size, int direction);
+ extern void __dma_sync_page(struct page *page, unsigned long offset,
+diff --git a/include/asm-ppc/dma.h b/include/asm-ppc/dma.h
+deleted file mode 100644
+--- a/include/asm-ppc/dma.h
++++ /dev/null
+@@ -1,371 +0,0 @@
+-/*
+- * include/asm-ppc/dma.h: Defines for using and allocating dma channels.
+- * Written by Hennus Bergman, 1992.
+- * High DMA channel support & info by Hannu Savolainen
+- * and John Boyd, Nov. 1992.
+- * Changes for ppc sound by Christoph Nadig
+- */
+-
+-#ifdef __KERNEL__
+-
+-#include <linux/config.h>
+-#include <asm/io.h>
+-#include <linux/spinlock.h>
+-#include <asm/system.h>
+-
+-/*
+- * Note: Adapted for PowerPC by Gary Thomas
+- * Modified by Cort Dougan <cort at cs.nmt.edu>
+- *
+- * None of this really applies for Power Macintoshes.  There is
+- * basically just enough here to get kernel/dma.c to compile.
+- *
+- * There may be some comments or restrictions made here which are
+- * not valid for the PReP platform.  Take what you read
+- * with a grain of salt.
+- */
+-
+-#ifndef _ASM_DMA_H
+-#define _ASM_DMA_H
+-
+-#ifndef MAX_DMA_CHANNELS
+-#define MAX_DMA_CHANNELS	8
+-#endif
+-
+-/* The maximum address that we can perform a DMA transfer to on this platform */
+-/* Doesn't really apply... */
+-#define MAX_DMA_ADDRESS		0xFFFFFFFF
+-
+-/* in arch/ppc/kernel/setup.c -- Cort */
+-extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ;
+-extern unsigned long ISA_DMA_THRESHOLD;
+-
+-#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
+-#define dma_outb	outb_p
+-#else
+-#define dma_outb	outb
+-#endif
+-
+-#define dma_inb		inb
+-
+-/*
+- * NOTES about DMA transfers:
+- *
+- *  controller 1: channels 0-3, byte operations, ports 00-1F
+- *  controller 2: channels 4-7, word operations, ports C0-DF
+- *
+- *  - ALL registers are 8 bits only, regardless of transfer size
+- *  - channel 4 is not used - cascades 1 into 2.
+- *  - channels 0-3 are byte - addresses/counts are for physical bytes
+- *  - channels 5-7 are word - addresses/counts are for physical words
+- *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+- *  - transfer count loaded to registers is 1 less than actual count
+- *  - controller 2 offsets are all even (2x offsets for controller 1)
+- *  - page registers for 5-7 don't use data bit 0, represent 128K pages
+- *  - page registers for 0-3 use bit 0, represent 64K pages
+- *
+- * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory.
+- * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing.
+- * Note that addresses loaded into registers must be _physical_ addresses,
+- * not logical addresses (which may differ if paging is active).
+- *
+- *  Address mapping for channels 0-3:
+- *
+- *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
+- *    |  ...  |   |  ... |   |  ... |
+- *    |  ...  |   |  ... |   |  ... |
+- *    |  ...  |   |  ... |   |  ... |
+- *   P7  ...  P0  A7 ... A0  A7 ... A0
+- * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
+- *
+- *  Address mapping for channels 5-7:
+- *
+- *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
+- *    |  ...  |   \   \   ... \  \  \  ... \  \
+- *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
+- *    |  ...  |     \   \   ... \  \  \  ... \
+- *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0
+- * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
+- *
+- * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
+- * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
+- * the hardware level, so odd-byte transfers aren't possible).
+- *
+- * Transfer count (_not # bytes_) is limited to 64K, represented as actual
+- * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
+- * and up to 128K bytes may be transferred on channels 5-7 in one operation.
+- *
+- */
+-
+-/* see prep_setup_arch() for detailed informations */
+-#if defined(CONFIG_SOUND_CS4232) && defined(CONFIG_PPC_PREP)
+-extern long ppc_cs4232_dma, ppc_cs4232_dma2;
+-#define SND_DMA1 ppc_cs4232_dma
+-#define SND_DMA2 ppc_cs4232_dma2
+-#else
+-#define SND_DMA1 -1
+-#define SND_DMA2 -1
+-#endif
+-
+-/* 8237 DMA controllers */
+-#define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
+-#define IO_DMA2_BASE	0xC0	/* 16 bit master DMA, ch 4(=slave input)..7 */
+-
+-/* DMA controller registers */
+-#define DMA1_CMD_REG		0x08	/* command register (w) */
+-#define DMA1_STAT_REG		0x08	/* status register (r) */
+-#define DMA1_REQ_REG		0x09	/* request register (w) */
+-#define DMA1_MASK_REG		0x0A	/* single-channel mask (w) */
+-#define DMA1_MODE_REG		0x0B	/* mode register (w) */
+-#define DMA1_CLEAR_FF_REG	0x0C	/* clear pointer flip-flop (w) */
+-#define DMA1_TEMP_REG		0x0D	/* Temporary Register (r) */
+-#define DMA1_RESET_REG		0x0D	/* Master Clear (w) */
+-#define DMA1_CLR_MASK_REG	0x0E	/* Clear Mask */
+-#define DMA1_MASK_ALL_REG	0x0F	/* all-channels mask (w) */
+-
+-#define DMA2_CMD_REG		0xD0	/* command register (w) */
+-#define DMA2_STAT_REG		0xD0	/* status register (r) */
+-#define DMA2_REQ_REG		0xD2	/* request register (w) */
+-#define DMA2_MASK_REG		0xD4	/* single-channel mask (w) */
+-#define DMA2_MODE_REG		0xD6	/* mode register (w) */
+-#define DMA2_CLEAR_FF_REG	0xD8	/* clear pointer flip-flop (w) */
+-#define DMA2_TEMP_REG		0xDA	/* Temporary Register (r) */
+-#define DMA2_RESET_REG		0xDA	/* Master Clear (w) */
+-#define DMA2_CLR_MASK_REG	0xDC	/* Clear Mask */
+-#define DMA2_MASK_ALL_REG	0xDE	/* all-channels mask (w) */
+-
+-#define DMA_ADDR_0		0x00	/* DMA address registers */
+-#define DMA_ADDR_1		0x02
+-#define DMA_ADDR_2		0x04
+-#define DMA_ADDR_3		0x06
+-#define DMA_ADDR_4		0xC0
+-#define DMA_ADDR_5		0xC4
+-#define DMA_ADDR_6		0xC8
+-#define DMA_ADDR_7		0xCC
+-
+-#define DMA_CNT_0		0x01	/* DMA count registers */
+-#define DMA_CNT_1		0x03
+-#define DMA_CNT_2		0x05
+-#define DMA_CNT_3		0x07
+-#define DMA_CNT_4		0xC2
+-#define DMA_CNT_5		0xC6
+-#define DMA_CNT_6		0xCA
+-#define DMA_CNT_7		0xCE
+-
+-#define DMA_LO_PAGE_0		0x87	/* DMA page registers */
+-#define DMA_LO_PAGE_1		0x83
+-#define DMA_LO_PAGE_2		0x81
+-#define DMA_LO_PAGE_3		0x82
+-#define DMA_LO_PAGE_5		0x8B
+-#define DMA_LO_PAGE_6		0x89
+-#define DMA_LO_PAGE_7		0x8A
+-
+-#define DMA_HI_PAGE_0		0x487	/* DMA page registers */
+-#define DMA_HI_PAGE_1		0x483
+-#define DMA_HI_PAGE_2		0x481
+-#define DMA_HI_PAGE_3		0x482
+-#define DMA_HI_PAGE_5		0x48B
+-#define DMA_HI_PAGE_6		0x489
+-#define DMA_HI_PAGE_7		0x48A
+-
+-#define DMA1_EXT_REG		0x40B
+-#define DMA2_EXT_REG		0x4D6
+-
+-#define DMA_MODE_CASCADE	0xC0	/* pass thru DREQ->HRQ, DACK<-HLDA only */
+-#define DMA_AUTOINIT		0x10
+-
+-extern spinlock_t dma_spin_lock;
+-
+-static __inline__ unsigned long claim_dma_lock(void)
+-{
+-	unsigned long flags;
+-	spin_lock_irqsave(&dma_spin_lock, flags);
+-	return flags;
+-}
+-
+-static __inline__ void release_dma_lock(unsigned long flags)
+-{
+-	spin_unlock_irqrestore(&dma_spin_lock, flags);
+-}
+-
+-/* enable/disable a specific DMA channel */
+-static __inline__ void enable_dma(unsigned int dmanr)
+-{
+-	unsigned char ucDmaCmd = 0x00;
+-
+-	if (dmanr != 4) {
+-		dma_outb(0, DMA2_MASK_REG);	/* This may not be enabled */
+-		dma_outb(ucDmaCmd, DMA2_CMD_REG);	/* Enable group */
+-	}
+-	if (dmanr <= 3) {
+-		dma_outb(dmanr, DMA1_MASK_REG);
+-		dma_outb(ucDmaCmd, DMA1_CMD_REG);	/* Enable group */
+-	} else
+-		dma_outb(dmanr & 3, DMA2_MASK_REG);
+-}
+-
+-static __inline__ void disable_dma(unsigned int dmanr)
+-{
+-	if (dmanr <= 3)
+-		dma_outb(dmanr | 4, DMA1_MASK_REG);
+-	else
+-		dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
+-}
+-
+-/* Clear the 'DMA Pointer Flip Flop'.
+- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+- * Use this once to initialize the FF to a known state.
+- * After that, keep track of it. :-)
+- * --- In order to do that, the DMA routines below should ---
+- * --- only be used while interrupts are disabled! ---
+- */
+-static __inline__ void clear_dma_ff(unsigned int dmanr)
+-{
+-	if (dmanr <= 3)
+-		dma_outb(0, DMA1_CLEAR_FF_REG);
+-	else
+-		dma_outb(0, DMA2_CLEAR_FF_REG);
+-}
+-
+-/* set mode (above) for a specific DMA channel */
+-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+-{
+-	if (dmanr <= 3)
+-		dma_outb(mode | dmanr, DMA1_MODE_REG);
+-	else
+-		dma_outb(mode | (dmanr & 3), DMA2_MODE_REG);
+-}
+-
+-/* Set only the page register bits of the transfer address.
+- * This is used for successive transfers when we know the contents of
+- * the lower 16 bits of the DMA current address register, but a 64k boundary
+- * may have been crossed.
+- */
+-static __inline__ void set_dma_page(unsigned int dmanr, int pagenr)
+-{
+-	switch (dmanr) {
+-	case 0:
+-		dma_outb(pagenr, DMA_LO_PAGE_0);
+-		dma_outb(pagenr >> 8, DMA_HI_PAGE_0);
+-		break;
+-	case 1:
+-		dma_outb(pagenr, DMA_LO_PAGE_1);
+-		dma_outb(pagenr >> 8, DMA_HI_PAGE_1);
+-		break;
+-	case 2:
+-		dma_outb(pagenr, DMA_LO_PAGE_2);
+-		dma_outb(pagenr >> 8, DMA_HI_PAGE_2);
+-		break;
+-	case 3:
+-		dma_outb(pagenr, DMA_LO_PAGE_3);
+-		dma_outb(pagenr >> 8, DMA_HI_PAGE_3);
+-		break;
+-	case 5:
+-		if (SND_DMA1 == 5 || SND_DMA2 == 5)
+-			dma_outb(pagenr, DMA_LO_PAGE_5);
+-		else
+-			dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5);
+-		dma_outb(pagenr >> 8, DMA_HI_PAGE_5);
+-		break;
+-	case 6:
+-		if (SND_DMA1 == 6 || SND_DMA2 == 6)
+-			dma_outb(pagenr, DMA_LO_PAGE_6);
+-		else
+-			dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6);
+-		dma_outb(pagenr >> 8, DMA_HI_PAGE_6);
+-		break;
+-	case 7:
+-		if (SND_DMA1 == 7 || SND_DMA2 == 7)
+-			dma_outb(pagenr, DMA_LO_PAGE_7);
+-		else
+-			dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7);
+-		dma_outb(pagenr >> 8, DMA_HI_PAGE_7);
+-		break;
+-	}
+-}
+-
+-/* Set transfer address & page bits for specific DMA channel.
+- * Assumes dma flipflop is clear.
+- */
+-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys)
+-{
+-	if (dmanr <= 3) {
+-		dma_outb(phys & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE);
+-		dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE);
+-	} else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) {
+-		dma_outb(phys & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
+-		dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
+-		dma_outb((dmanr & 3), DMA2_EXT_REG);
+-	} else {
+-		dma_outb((phys >> 1) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
+-		dma_outb((phys >> 9) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
+-	}
+-	set_dma_page(dmanr, phys >> 16);
+-}
+-
+-/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
+- * a specific DMA channel.
+- * You must ensure the parameters are valid.
+- * NOTE: from a manual: "the number of transfers is one more
+- * than the initial word count"! This is taken into account.
+- * Assumes dma flip-flop is clear.
+- * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+- */
+-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+-{
+-	count--;
+-	if (dmanr <= 3) {
+-		dma_outb(count & 0xff, ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE);
+-		dma_outb((count >> 8) & 0xff, ((dmanr & 3) << 1) + 1 +
+-			 IO_DMA1_BASE);
+-	} else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) {
+-		dma_outb(count & 0xff, ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
+-		dma_outb((count >> 8) & 0xff, ((dmanr & 3) << 2) + 2 +
+-			 IO_DMA2_BASE);
+-	} else {
+-		dma_outb((count >> 1) & 0xff, ((dmanr & 3) << 2) + 2 +
+-			 IO_DMA2_BASE);
+-		dma_outb((count >> 9) & 0xff, ((dmanr & 3) << 2) + 2 +
+-			 IO_DMA2_BASE);
+-	}
+-}
+-
+-/* Get DMA residue count. After a DMA transfer, this
+- * should return zero. Reading this while a DMA transfer is
+- * still in progress will return unpredictable results.
+- * If called before the channel has been used, it may return 1.
+- * Otherwise, it returns the number of _bytes_ left to transfer.
+- *
+- * Assumes DMA flip-flop is clear.
+- */
+-static __inline__ int get_dma_residue(unsigned int dmanr)
+-{
+-	unsigned int io_port = (dmanr <= 3) ?
+-	    ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE
+-	    : ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE;
+-
+-	/* using short to get 16-bit wrap around */
+-	unsigned short count;
+-
+-	count = 1 + dma_inb(io_port);
+-	count += dma_inb(io_port) << 8;
+-
+-	return (dmanr <= 3 || dmanr == SND_DMA1 || dmanr == SND_DMA2)
+-	    ? count : (count << 1);
+-
+-}
+-
+-/* These are in kernel/dma.c: */
+-
+-/* reserve a DMA channel */
+-extern int request_dma(unsigned int dmanr, const char *device_id);
+-/* release it again */
+-extern void free_dma(unsigned int dmanr);
+-
+-#ifdef CONFIG_PCI
+-extern int isa_dma_bridge_buggy;
+-#else
+-#define isa_dma_bridge_buggy	(0)
+-#endif
+-#endif				/* _ASM_DMA_H */
+-#endif				/* __KERNEL__ */
+diff --git a/include/asm-ppc/elf.h b/include/asm-ppc/elf.h
+deleted file mode 100644
+--- a/include/asm-ppc/elf.h
++++ /dev/null
+@@ -1,151 +0,0 @@
+-#ifndef __PPC_ELF_H
+-#define __PPC_ELF_H
+-
+-/*
+- * ELF register definitions..
+- */
+-#include <asm/types.h>
+-#include <asm/ptrace.h>
+-#include <asm/cputable.h>
+-#include <asm/auxvec.h>
+-
+-/* PowerPC relocations defined by the ABIs */
+-#define R_PPC_NONE		0
+-#define R_PPC_ADDR32		1	/* 32bit absolute address */
+-#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
+-#define R_PPC_ADDR16		3	/* 16bit absolute address */
+-#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
+-#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
+-#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
+-#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
+-#define R_PPC_ADDR14_BRTAKEN	8
+-#define R_PPC_ADDR14_BRNTAKEN	9
+-#define R_PPC_REL24		10	/* PC relative 26 bit */
+-#define R_PPC_REL14		11	/* PC relative 16 bit */
+-#define R_PPC_REL14_BRTAKEN	12
+-#define R_PPC_REL14_BRNTAKEN	13
+-#define R_PPC_GOT16		14
+-#define R_PPC_GOT16_LO		15
+-#define R_PPC_GOT16_HI		16
+-#define R_PPC_GOT16_HA		17
+-#define R_PPC_PLTREL24		18
+-#define R_PPC_COPY		19
+-#define R_PPC_GLOB_DAT		20
+-#define R_PPC_JMP_SLOT		21
+-#define R_PPC_RELATIVE		22
+-#define R_PPC_LOCAL24PC		23
+-#define R_PPC_UADDR32		24
+-#define R_PPC_UADDR16		25
+-#define R_PPC_REL32		26
+-#define R_PPC_PLT32		27
+-#define R_PPC_PLTREL32		28
+-#define R_PPC_PLT16_LO		29
+-#define R_PPC_PLT16_HI		30
+-#define R_PPC_PLT16_HA		31
+-#define R_PPC_SDAREL16		32
+-#define R_PPC_SECTOFF		33
+-#define R_PPC_SECTOFF_LO	34
+-#define R_PPC_SECTOFF_HI	35
+-#define R_PPC_SECTOFF_HA	36
+-/* Keep this the last entry.  */
+-#define R_PPC_NUM		37
+-
+-#define ELF_NGREG	48	/* includes nip, msr, lr, etc. */
+-#define ELF_NFPREG	33	/* includes fpscr */
+-#define ELF_NVRREG	33	/* includes vscr */
+-#define ELF_NEVRREG	34	/* includes acc (as 2) */
+-
+-/*
+- * These are used to set parameters in the core dumps.
+- */
+-#define ELF_ARCH	EM_PPC
+-#define ELF_CLASS	ELFCLASS32
+-#define ELF_DATA	ELFDATA2MSB
+-
+-/* General registers */
+-typedef unsigned long elf_greg_t;
+-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+-
+-/* Floating point registers */
+-typedef double elf_fpreg_t;
+-typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+-
+-/* Altivec registers */
+-typedef __vector128 elf_vrreg_t;
+-typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
+-
+-#ifdef __KERNEL__
+-
+-struct task_struct;
+-
+-/*
+- * This is used to ensure we don't load something for the wrong architecture.
+- */
+-
+-#define elf_check_arch(x) ((x)->e_machine == EM_PPC)
+-
+-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+-   use of this is to invoke "./ld.so someprog" to test out a new version of
+-   the loader.  We need to make sure that it is out of the way of the program
+-   that it will "exec", and that there is sufficient room for the brk.  */
+-
+-#define ELF_ET_DYN_BASE         (0x08000000)
+-
+-#define USE_ELF_CORE_DUMP
+-#define ELF_EXEC_PAGESIZE	4096
+-
+-#define ELF_CORE_COPY_REGS(gregs, regs)				\
+-	memcpy((gregs), (regs), sizeof(struct pt_regs));	\
+-	memset((char *)(gregs) + sizeof(struct pt_regs), 0,	\
+-	       sizeof(elf_gregset_t) - sizeof(struct pt_regs));
+-
+-#define ELF_CORE_COPY_TASK_REGS(t, elfregs)			\
+-	((t)->thread.regs?					\
+-	 ({ ELF_CORE_COPY_REGS((elfregs), (t)->thread.regs); 1; }): 0)
+-
+-extern int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpu);
+-#define ELF_CORE_COPY_FPREGS(t, fpu)	dump_task_fpu((t), (fpu))
+-
+-/* This yields a mask that user programs can use to figure out what
+-   instruction set this cpu supports.  This could be done in userspace,
+-   but it's not easy, and we've already done it here.  */
+-
+-#define ELF_HWCAP	(cur_cpu_spec[0]->cpu_user_features)
+-
+-/* This yields a string that ld.so will use to load implementation
+-   specific libraries for optimization.  This is more specific in
+-   intent than poking at uname or /proc/cpuinfo.
+-
+-   For the moment, we have only optimizations for the Intel generations,
+-   but that could change... */
+-
+-#define ELF_PLATFORM	(NULL)
+-
+-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+-
+-extern int dcache_bsize;
+-extern int icache_bsize;
+-extern int ucache_bsize;
+-
+-/*
+- * The requirements here are:
+- * - keep the final alignment of sp (sp & 0xf)
+- * - make sure the 32-bit value at the first 16 byte aligned position of
+- *   AUXV is greater than 16 for glibc compatibility.
+- *   AT_IGNOREPPC is used for that.
+- * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
+- *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
+- */
+-#define ARCH_DLINFO							\
+-do {									\
+-	/* Handle glibc compatibility. */				\
+-	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
+-	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
+-	/* Cache size items */						\
+-	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
+-	NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);			\
+-	NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize);			\
+- } while (0)
+-
+-#endif /* __KERNEL__ */
+-#endif
+diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h
+deleted file mode 100644
+--- a/include/asm-ppc/hardirq.h
++++ /dev/null
+@@ -1,31 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef __ASM_HARDIRQ_H
+-#define __ASM_HARDIRQ_H
+-
+-#include <linux/config.h>
+-#include <linux/cache.h>
+-#include <linux/smp_lock.h>
+-#include <asm/irq.h>
+-
+-/* The __last_jiffy_stamp field is needed to ensure that no decrementer
+- * interrupt is lost on SMP machines. Since on most CPUs it is in the same
+- * cache line as local_irq_count, it is cheap to access and is also used on UP
+- * for uniformity.
+- */
+-typedef struct {
+-	unsigned long __softirq_pending;	/* set_bit is used on this */
+-	unsigned int __last_jiffy_stamp;
+-} ____cacheline_aligned irq_cpustat_t;
+-
+-#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+-
+-#define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp)
+-
+-static inline void ack_bad_irq(int irq)
+-{
+-	printk(KERN_CRIT "illegal vector %d received!\n", irq);
+-	BUG();
+-}
+-
+-#endif /* __ASM_HARDIRQ_H */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/heathrow.h b/include/asm-ppc/heathrow.h
+deleted file mode 100644
+--- a/include/asm-ppc/heathrow.h
++++ /dev/null
+@@ -1,62 +0,0 @@
+-/*
+- * heathrow.h: definitions for using the "Heathrow" I/O controller chip.
+- *
+- * Grabbed from Open Firmware definitions on a PowerBook G3 Series
+- *
+- * Copyright (C) 1997 Paul Mackerras.
+- */
+-
+-/* Front light color on Yikes/B&W G3. 32 bits */
+-#define HEATHROW_FRONT_LIGHT		0x32 /* (set to 0 or 0xffffffff) */
+-
+-/* Brightness/contrast (gossamer iMac ?). 8 bits */
+-#define HEATHROW_BRIGHTNESS_CNTL	0x32
+-#define HEATHROW_CONTRAST_CNTL		0x33
+-
+-/* offset from ohare base for feature control register */
+-#define HEATHROW_MBCR			0x34	/* Media bay control */
+-#define HEATHROW_FCR			0x38	/* Feature control */
+-#define HEATHROW_AUX_CNTL_REG		0x3c	/* Aux control */
+-
+-/*
+- * Bits in feature control register.
+- * Bits postfixed with a _N are in inverse logic
+- */
+-#define HRW_SCC_TRANS_EN_N	0x00000001	/* Also controls modem power */
+-#define HRW_BAY_POWER_N		0x00000002
+-#define HRW_BAY_PCI_ENABLE	0x00000004
+-#define HRW_BAY_IDE_ENABLE	0x00000008
+-#define HRW_BAY_FLOPPY_ENABLE	0x00000010
+-#define HRW_IDE0_ENABLE		0x00000020
+-#define HRW_IDE0_RESET_N	0x00000040
+-#define HRW_BAY_DEV_MASK	0x0000001c
+-#define HRW_BAY_RESET_N		0x00000080
+-#define HRW_IOBUS_ENABLE	0x00000100	/* Internal IDE ? */
+-#define HRW_SCC_ENABLE		0x00000200
+-#define HRW_MESH_ENABLE		0x00000400
+-#define HRW_SWIM_ENABLE		0x00000800
+-#define HRW_SOUND_POWER_N	0x00001000
+-#define HRW_SOUND_CLK_ENABLE	0x00002000
+-#define HRW_SCCA_IO		0x00004000
+-#define HRW_SCCB_IO		0x00008000
+-#define HRW_PORT_OR_DESK_VIA_N	0x00010000	/* This one is 0 on PowerBook */
+-#define HRW_PWM_MON_ID_N	0x00020000	/* ??? (0) */
+-#define HRW_HOOK_MB_CNT_N	0x00040000	/* ??? (0) */
+-#define HRW_SWIM_CLONE_FLOPPY	0x00080000	/* ??? (0) */
+-#define HRW_AUD_RUN22		0x00100000	/* ??? (1) */
+-#define HRW_SCSI_LINK_MODE	0x00200000	/* Read ??? (1) */
+-#define HRW_ARB_BYPASS		0x00400000	/* Disable internal PCI arbitrer */
+-#define HRW_IDE1_RESET_N	0x00800000	/* Media bay */
+-#define HRW_SLOW_SCC_PCLK	0x01000000	/* ??? (0) */
+-#define HRW_RESET_SCC		0x02000000
+-#define HRW_MFDC_CELL_ENABLE	0x04000000	/* ??? (0) */
+-#define HRW_USE_MFDC		0x08000000	/* ??? (0) */
+-#define HRW_BMAC_IO_ENABLE	0x60000000	/* two bits, not documented in OF */
+-#define HRW_BMAC_RESET		0x80000000	/* not documented in OF */
+-
+-/* We OR those features at boot on desktop G3s */
+-#define HRW_DEFAULTS		(HRW_SCCA_IO | HRW_SCCB_IO | HRW_SCC_ENABLE)
+-
+-/* Looks like Heathrow has some sort of GPIOs as well... */
+-#define HRW_GPIO_MODEM_RESET	0x6d
+-
+diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h
+deleted file mode 100644
+--- a/include/asm-ppc/hw_irq.h
++++ /dev/null
+@@ -1,74 +0,0 @@
+-/*
+- * Copyright (C) 1999 Cort Dougan <cort at cs.nmt.edu>
+- */
+-#ifdef __KERNEL__
+-#ifndef _PPC_HW_IRQ_H
+-#define _PPC_HW_IRQ_H
+-
+-#include <asm/ptrace.h>
+-#include <asm/reg.h>
+-
+-extern void timer_interrupt(struct pt_regs *);
+-
+-#define INLINE_IRQS
+-
+-#define irqs_disabled()	((mfmsr() & MSR_EE) == 0)
+-
+-#ifdef INLINE_IRQS
+-
+-static inline void local_irq_disable(void)
+-{
+-	unsigned long msr;
+-	msr = mfmsr();
+-	mtmsr(msr & ~MSR_EE);
+-	__asm__ __volatile__("": : :"memory");
+-}
+-
+-static inline void local_irq_enable(void)
+-{
+-	unsigned long msr;
+-	__asm__ __volatile__("": : :"memory");
+-	msr = mfmsr();
+-	mtmsr(msr | MSR_EE);
+-}
+-
+-static inline void local_irq_save_ptr(unsigned long *flags)
+-{
+-	unsigned long msr;
+-	msr = mfmsr();
+-	*flags = msr;
+-	mtmsr(msr & ~MSR_EE);
+-	__asm__ __volatile__("": : :"memory");
+-}
+-
+-#define local_save_flags(flags)		((flags) = mfmsr())
+-#define local_irq_save(flags)		local_irq_save_ptr(&flags)
+-#define local_irq_restore(flags)	mtmsr(flags)
+-
+-#else
+-
+-extern void local_irq_enable(void);
+-extern void local_irq_disable(void);
+-extern void local_irq_restore(unsigned long);
+-extern void local_save_flags_ptr(unsigned long *);
+-
+-#define local_save_flags(flags) local_save_flags_ptr(&flags)
+-#define local_irq_save(flags) ({local_save_flags(flags);local_irq_disable();})
+-
+-#endif
+-
+-extern void do_lost_interrupts(unsigned long);
+-
+-#define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);})
+-#define unmask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->enable) irq_desc[irq].handler->enable(irq);})
+-#define ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);})
+-
+-/* Should we handle this via lost interrupts and IPIs or should we don't care like
+- * we do now ? --BenH.
+- */
+-struct hw_interrupt_type;
+-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
+-
+-
+-#endif /* _PPC_HW_IRQ_H */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/i8259.h b/include/asm-ppc/i8259.h
+deleted file mode 100644
+--- a/include/asm-ppc/i8259.h
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#ifndef _PPC_KERNEL_i8259_H
+-#define _PPC_KERNEL_i8259_H
+-
+-#include <linux/irq.h>
+-
+-extern struct hw_interrupt_type i8259_pic;
+-
+-extern void i8259_init(long intack_addr);
+-extern int i8259_irq(struct pt_regs *regs);
+-
+-#endif /* _PPC_KERNEL_i8259_H */
+diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
+--- a/include/asm-ppc/io.h
++++ b/include/asm-ppc/io.h
+@@ -8,6 +8,7 @@
+ 
+ #include <asm/page.h>
+ #include <asm/byteorder.h>
++#include <asm/synch.h>
+ #include <asm/mmu.h>
+ 
+ #define SIO_CONFIG_RA	0x398
+@@ -440,16 +441,6 @@ extern inline void * phys_to_virt(unsign
+ #define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
+ #define page_to_bus(page)	(page_to_phys(page) + PCI_DRAM_OFFSET)
+ 
+-/*
+- * Enforce In-order Execution of I/O:
+- * Acts as a barrier to ensure all previous I/O accesses have
+- * completed before any further ones are issued.
+- */
+-extern inline void eieio(void)
+-{
+-	__asm__ __volatile__ ("eieio" : : : "memory");
+-}
+-
+ /* Enforce in-order execution of data I/O.
+  * No distinction between read/write on PPC; use eieio for all three.
+  */
+diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h
+deleted file mode 100644
+--- a/include/asm-ppc/irq.h
++++ /dev/null
+@@ -1,418 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef _ASM_IRQ_H
+-#define _ASM_IRQ_H
+-
+-#include <linux/config.h>
+-#include <asm/machdep.h>		/* ppc_md */
+-#include <asm/atomic.h>
+-
+-/*
+- * These constants are used for passing information about interrupt
+- * signal polarity and level/edge sensing to the low-level PIC chip
+- * drivers.
+- */
+-#define IRQ_SENSE_MASK		0x1
+-#define IRQ_SENSE_LEVEL		0x1	/* interrupt on active level */
+-#define IRQ_SENSE_EDGE		0x0	/* interrupt triggered by edge */
+-
+-#define IRQ_POLARITY_MASK	0x2
+-#define IRQ_POLARITY_POSITIVE	0x2	/* high level or low->high edge */
+-#define IRQ_POLARITY_NEGATIVE	0x0	/* low level or high->low edge */
+-
+-/*
+- * IRQ line status macro IRQ_PER_CPU is used
+- */
+-#define ARCH_HAS_IRQ_PER_CPU
+-
+-#if defined(CONFIG_40x)
+-#include <asm/ibm4xx.h>
+-
+-#ifndef NR_BOARD_IRQS
+-#define NR_BOARD_IRQS 0
+-#endif
+-
+-#ifndef UIC_WIDTH /* Number of interrupts per device */
+-#define UIC_WIDTH 32
+-#endif
+-
+-#ifndef NR_UICS /* number  of UIC devices */
+-#define NR_UICS 1
+-#endif
+-
+-#if defined (CONFIG_403)
+-/*
+- * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has
+- * 32 possible interrupts, a majority of which are not implemented on
+- * all cores. There are six configurable, external interrupt pins and
+- * there are eight internal interrupts for the on-chip serial port
+- * (SPU), DMA controller, and JTAG controller.
+- *
+- */
+-
+-#define	NR_AIC_IRQS 32
+-#define	NR_IRQS	 (NR_AIC_IRQS + NR_BOARD_IRQS)
+-
+-#elif !defined (CONFIG_403)
+-
+-/*
+- *  The PowerPC 405 cores' Universal Interrupt Controller (UIC) has 32
+- * possible interrupts as well. There are seven, configurable external
+- * interrupt pins and there are 17 internal interrupts for the on-chip
+- * serial port, DMA controller, on-chip Ethernet controller, PCI, etc.
+- *
+- */
+-
+-
+-#define NR_UIC_IRQS UIC_WIDTH
+-#define NR_IRQS		((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS)
+-#endif
+-static __inline__ int
+-irq_canonicalize(int irq)
+-{
+-	return (irq);
+-}
+-
+-#elif defined(CONFIG_44x)
+-#include <asm/ibm44x.h>
+-
+-#define	NR_UIC_IRQS	32
+-#define	NR_IRQS		((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS)
+-
+-static __inline__ int
+-irq_canonicalize(int irq)
+-{
+-	return (irq);
+-}
+-
+-#elif defined(CONFIG_8xx)
+-
+-/* Now include the board configuration specific associations.
+-*/
+-#include <asm/mpc8xx.h>
+-
+-/* The MPC8xx cores have 16 possible interrupts.  There are eight
+- * possible level sensitive interrupts assigned and generated internally
+- * from such devices as CPM, PCMCIA, RTC, PIT, TimeBase and Decrementer.
+- * There are eight external interrupts (IRQs) that can be configured
+- * as either level or edge sensitive.
+- *
+- * On some implementations, there is also the possibility of an 8259
+- * through the PCI and PCI-ISA bridges.
+- *
+- * We are "flattening" the interrupt vectors of the cascaded CPM
+- * and 8259 interrupt controllers so that we can uniquely identify
+- * any interrupt source with a single integer.
+- */
+-#define NR_SIU_INTS	16
+-#define NR_CPM_INTS	32
+-#ifndef NR_8259_INTS
+-#define NR_8259_INTS 0
+-#endif
+-
+-#define SIU_IRQ_OFFSET		0
+-#define CPM_IRQ_OFFSET		(SIU_IRQ_OFFSET + NR_SIU_INTS)
+-#define I8259_IRQ_OFFSET	(CPM_IRQ_OFFSET + NR_CPM_INTS)
+-
+-#define NR_IRQS	(NR_SIU_INTS + NR_CPM_INTS + NR_8259_INTS)
+-
+-/* These values must be zero-based and map 1:1 with the SIU configuration.
+- * They are used throughout the 8xx I/O subsystem to generate
+- * interrupt masks, flags, and other control patterns.  This is why the
+- * current kernel assumption of the 8259 as the base controller is such
+- * a pain in the butt.
+- */
+-#define	SIU_IRQ0	(0)	/* Highest priority */
+-#define	SIU_LEVEL0	(1)
+-#define	SIU_IRQ1	(2)
+-#define	SIU_LEVEL1	(3)
+-#define	SIU_IRQ2	(4)
+-#define	SIU_LEVEL2	(5)
+-#define	SIU_IRQ3	(6)
+-#define	SIU_LEVEL3	(7)
+-#define	SIU_IRQ4	(8)
+-#define	SIU_LEVEL4	(9)
+-#define	SIU_IRQ5	(10)
+-#define	SIU_LEVEL5	(11)
+-#define	SIU_IRQ6	(12)
+-#define	SIU_LEVEL6	(13)
+-#define	SIU_IRQ7	(14)
+-#define	SIU_LEVEL7	(15)
+-
+-#define MPC8xx_INT_FEC1		SIU_LEVEL1
+-#define MPC8xx_INT_FEC2		SIU_LEVEL3
+-
+-#define MPC8xx_INT_SCC1		(CPM_IRQ_OFFSET + CPMVEC_SCC1)
+-#define MPC8xx_INT_SCC2		(CPM_IRQ_OFFSET + CPMVEC_SCC2)
+-#define MPC8xx_INT_SCC3		(CPM_IRQ_OFFSET + CPMVEC_SCC3)
+-#define MPC8xx_INT_SCC4		(CPM_IRQ_OFFSET + CPMVEC_SCC4)
+-#define MPC8xx_INT_SMC1		(CPM_IRQ_OFFSET + CPMVEC_SMC1)
+-#define MPC8xx_INT_SMC2		(CPM_IRQ_OFFSET + CPMVEC_SMC2)
+-
+-/* The internal interrupts we can configure as we see fit.
+- * My personal preference is CPM at level 2, which puts it above the
+- * MBX PCI/ISA/IDE interrupts.
+- */
+-#ifndef PIT_INTERRUPT
+-#define PIT_INTERRUPT		SIU_LEVEL0
+-#endif
+-#ifndef	CPM_INTERRUPT
+-#define CPM_INTERRUPT		SIU_LEVEL2
+-#endif
+-#ifndef	PCMCIA_INTERRUPT
+-#define PCMCIA_INTERRUPT	SIU_LEVEL6
+-#endif
+-#ifndef	DEC_INTERRUPT
+-#define DEC_INTERRUPT		SIU_LEVEL7
+-#endif
+-
+-/* Some internal interrupt registers use an 8-bit mask for the interrupt
+- * level instead of a number.
+- */
+-#define	mk_int_int_mask(IL) (1 << (7 - (IL/2)))
+-
+-/* always the same on 8xx -- Cort */
+-static __inline__ int irq_canonicalize(int irq)
+-{
+-	return irq;
+-}
+-
+-#elif defined(CONFIG_83xx)
+-#include <asm/mpc83xx.h>
+-
+-static __inline__ int irq_canonicalize(int irq)
+-{
+-	return irq;
+-}
+-
+-#define	NR_IRQS	(NR_IPIC_INTS)
+-
+-#elif defined(CONFIG_85xx)
+-/* Now include the board configuration specific associations.
+-*/
+-#include <asm/mpc85xx.h>
+-
+-/* The MPC8548 openpic has 48 internal interrupts and 12 external
+- * interrupts.
+- *
+- * We are "flattening" the interrupt vectors of the cascaded CPM
+- * so that we can uniquely identify any interrupt source with a
+- * single integer.
+- */
+-#define NR_CPM_INTS	64
+-#define NR_EPIC_INTS	60
+-#ifndef NR_8259_INTS
+-#define NR_8259_INTS	0
+-#endif
+-#define NUM_8259_INTERRUPTS NR_8259_INTS
+-
+-#ifndef CPM_IRQ_OFFSET
+-#define CPM_IRQ_OFFSET	0
+-#endif
+-
+-#define NR_IRQS	(NR_EPIC_INTS + NR_CPM_INTS + NR_8259_INTS)
+-
+-/* Internal IRQs on MPC85xx OpenPIC */
+-
+-#ifndef MPC85xx_OPENPIC_IRQ_OFFSET
+-#ifdef CONFIG_CPM2
+-#define MPC85xx_OPENPIC_IRQ_OFFSET	(CPM_IRQ_OFFSET + NR_CPM_INTS)
+-#else
+-#define MPC85xx_OPENPIC_IRQ_OFFSET	0
+-#endif
+-#endif
+-
+-/* Not all of these exist on all MPC85xx implementations */
+-#define MPC85xx_IRQ_L2CACHE	( 0 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_ECM		( 1 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_DDR		( 2 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_LBIU	( 3 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_DMA0	( 4 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_DMA1	( 5 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_DMA2	( 6 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_DMA3	( 7 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_PCI1	( 8 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_PCI2	( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_RIO_ERROR	( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_RIO_BELL	(10 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_RIO_TX	(11 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_RIO_RX	(12 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC1_TX	(13 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC1_RX	(14 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC3_TX	(15 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC3_RX	(16 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC3_ERROR	(17 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC1_ERROR	(18 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC2_TX	(19 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC2_RX	(20 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC4_TX	(21 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC4_RX	(22 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC4_ERROR	(23 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_TSEC2_ERROR	(24 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_FEC		(25 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_DUART	(26 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_IIC1	(27 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_PERFMON	(28 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_SEC2	(29 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_CPM		(30 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-
+-/* The 12 external interrupt lines */
+-#define MPC85xx_IRQ_EXT0        (48 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT1        (49 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT2        (50 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT3        (51 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT4        (52 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT5        (53 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT6        (54 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT7        (55 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT8        (56 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT9        (57 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT10       (58 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-#define MPC85xx_IRQ_EXT11       (59 + MPC85xx_OPENPIC_IRQ_OFFSET)
+-
+-/* CPM related interrupts */
+-#define	SIU_INT_ERROR		((uint)0x00+CPM_IRQ_OFFSET)
+-#define	SIU_INT_I2C		((uint)0x01+CPM_IRQ_OFFSET)
+-#define	SIU_INT_SPI		((uint)0x02+CPM_IRQ_OFFSET)
+-#define	SIU_INT_RISC		((uint)0x03+CPM_IRQ_OFFSET)
+-#define	SIU_INT_SMC1		((uint)0x04+CPM_IRQ_OFFSET)
+-#define	SIU_INT_SMC2		((uint)0x05+CPM_IRQ_OFFSET)
+-#define	SIU_INT_USB		((uint)0x0b+CPM_IRQ_OFFSET)
+-#define	SIU_INT_TIMER1		((uint)0x0c+CPM_IRQ_OFFSET)
+-#define	SIU_INT_TIMER2		((uint)0x0d+CPM_IRQ_OFFSET)
+-#define	SIU_INT_TIMER3		((uint)0x0e+CPM_IRQ_OFFSET)
+-#define	SIU_INT_TIMER4		((uint)0x0f+CPM_IRQ_OFFSET)
+-#define	SIU_INT_FCC1		((uint)0x20+CPM_IRQ_OFFSET)
+-#define	SIU_INT_FCC2		((uint)0x21+CPM_IRQ_OFFSET)
+-#define	SIU_INT_FCC3		((uint)0x22+CPM_IRQ_OFFSET)
+-#define	SIU_INT_MCC1		((uint)0x24+CPM_IRQ_OFFSET)
+-#define	SIU_INT_MCC2		((uint)0x25+CPM_IRQ_OFFSET)
+-#define	SIU_INT_SCC1		((uint)0x28+CPM_IRQ_OFFSET)
+-#define	SIU_INT_SCC2		((uint)0x29+CPM_IRQ_OFFSET)
+-#define	SIU_INT_SCC3		((uint)0x2a+CPM_IRQ_OFFSET)
+-#define	SIU_INT_SCC4		((uint)0x2b+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC15		((uint)0x30+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC14		((uint)0x31+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC13		((uint)0x32+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC12		((uint)0x33+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC11		((uint)0x34+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC10		((uint)0x35+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC9		((uint)0x36+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC8		((uint)0x37+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC7		((uint)0x38+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC6		((uint)0x39+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC5		((uint)0x3a+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC4		((uint)0x3b+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC3		((uint)0x3c+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC2		((uint)0x3d+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC1		((uint)0x3e+CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC0		((uint)0x3f+CPM_IRQ_OFFSET)
+-
+-static __inline__ int irq_canonicalize(int irq)
+-{
+-	return irq;
+-}
+-
+-#else /* CONFIG_40x + CONFIG_8xx */
+-/*
+- * this is the # irq's for all ppc arch's (pmac/chrp/prep)
+- * so it is the max of them all
+- */
+-#define NR_IRQS			256
+-
+-#ifndef CONFIG_8260
+-
+-#define NUM_8259_INTERRUPTS	16
+-
+-#else /* CONFIG_8260 */
+-
+-/* The 8260 has an internal interrupt controller with a maximum of
+- * 64 IRQs.  We will use NR_IRQs from above since it is large enough.
+- * Don't be confused by the 8260 documentation where they list an
+- * "interrupt number" and "interrupt vector".  We are only interested
+- * in the interrupt vector.  There are "reserved" holes where the
+- * vector number increases, but the interrupt number in the table does not.
+- * (Document errata updates have fixed this...make sure you have up to
+- * date processor documentation -- Dan).
+- */
+-
+-#ifndef CPM_IRQ_OFFSET
+-#define CPM_IRQ_OFFSET	0
+-#endif
+-
+-#define NR_CPM_INTS	64
+-
+-#define	SIU_INT_ERROR		((uint)0x00 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_I2C		((uint)0x01 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_SPI		((uint)0x02 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_RISC		((uint)0x03 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_SMC1		((uint)0x04 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_SMC2		((uint)0x05 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IDMA1		((uint)0x06 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IDMA2		((uint)0x07 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IDMA3		((uint)0x08 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IDMA4		((uint)0x09 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_SDMA		((uint)0x0a + CPM_IRQ_OFFSET)
+-#define	SIU_INT_USB		((uint)0x0b + CPM_IRQ_OFFSET)
+-#define	SIU_INT_TIMER1		((uint)0x0c + CPM_IRQ_OFFSET)
+-#define	SIU_INT_TIMER2		((uint)0x0d + CPM_IRQ_OFFSET)
+-#define	SIU_INT_TIMER3		((uint)0x0e + CPM_IRQ_OFFSET)
+-#define	SIU_INT_TIMER4		((uint)0x0f + CPM_IRQ_OFFSET)
+-#define	SIU_INT_TMCNT		((uint)0x10 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PIT		((uint)0x11 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IRQ1		((uint)0x13 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IRQ2		((uint)0x14 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IRQ3		((uint)0x15 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IRQ4		((uint)0x16 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IRQ5		((uint)0x17 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IRQ6		((uint)0x18 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_IRQ7		((uint)0x19 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_FCC1		((uint)0x20 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_FCC2		((uint)0x21 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_FCC3		((uint)0x22 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_MCC1		((uint)0x24 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_MCC2		((uint)0x25 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_SCC1		((uint)0x28 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_SCC2		((uint)0x29 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_SCC3		((uint)0x2a + CPM_IRQ_OFFSET)
+-#define	SIU_INT_SCC4		((uint)0x2b + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC15		((uint)0x30 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC14		((uint)0x31 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC13		((uint)0x32 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC12		((uint)0x33 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC11		((uint)0x34 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC10		((uint)0x35 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC9		((uint)0x36 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC8		((uint)0x37 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC7		((uint)0x38 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC6		((uint)0x39 + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC5		((uint)0x3a + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC4		((uint)0x3b + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC3		((uint)0x3c + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC2		((uint)0x3d + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC1		((uint)0x3e + CPM_IRQ_OFFSET)
+-#define	SIU_INT_PC0		((uint)0x3f + CPM_IRQ_OFFSET)
+-
+-#endif /* CONFIG_8260 */
+-
+-/*
+- * This gets called from serial.c, which is now used on
+- * powermacs as well as prep/chrp boxes.
+- * Prep and chrp both have cascaded 8259 PICs.
+- */
+-static __inline__ int irq_canonicalize(int irq)
+-{
+-	if (ppc_md.irq_canonicalize)
+-		return ppc_md.irq_canonicalize(irq);
+-	return irq;
+-}
+-
+-#endif
+-
+-#define NR_MASK_WORDS	((NR_IRQS + 31) / 32)
+-/* pedantic: these are long because they are used with set_bit --RR */
+-extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+-extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
+-extern atomic_t ppc_n_lost_interrupts;
+-
+-#endif /* _ASM_IRQ_H */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/keylargo.h b/include/asm-ppc/keylargo.h
+deleted file mode 100644
+--- a/include/asm-ppc/keylargo.h
++++ /dev/null
+@@ -1,248 +0,0 @@
+-/*
+- * keylargo.h: definitions for using the "KeyLargo" I/O controller chip.
+- *
+- */
+-
+-/* "Pangea" chipset has keylargo device-id 0x25 while core99
+- * has device-id 0x22. The rev. of the pangea one is 0, so we
+- * fake an artificial rev. in keylargo_rev by oring 0x100
+- */
+-#define KL_PANGEA_REV		0x100
+-
+-/* offset from base for feature control registers */
+-#define KEYLARGO_MBCR		0x34	/* KL Only, Media bay control/status */
+-#define KEYLARGO_FCR0		0x38
+-#define KEYLARGO_FCR1		0x3c
+-#define KEYLARGO_FCR2		0x40
+-#define KEYLARGO_FCR3		0x44
+-#define KEYLARGO_FCR4		0x48
+-#define KEYLARGO_FCR5		0x4c	/* Pangea only */
+-
+-/* K2 aditional FCRs */
+-#define K2_FCR6			0x34
+-#define K2_FCR7			0x30
+-#define K2_FCR8			0x2c
+-#define K2_FCR9			0x28
+-#define K2_FCR10		0x24
+-
+-/* GPIO registers */
+-#define KEYLARGO_GPIO_LEVELS0		0x50
+-#define KEYLARGO_GPIO_LEVELS1		0x54
+-#define KEYLARGO_GPIO_EXTINT_0		0x58
+-#define KEYLARGO_GPIO_EXTINT_CNT	18
+-#define KEYLARGO_GPIO_0			0x6A
+-#define KEYLARGO_GPIO_CNT		17
+-#define KEYLARGO_GPIO_EXTINT_DUAL_EDGE	0x80
+-#define KEYLARGO_GPIO_OUTPUT_ENABLE	0x04
+-#define KEYLARGO_GPIO_OUTOUT_DATA	0x01
+-#define KEYLARGO_GPIO_INPUT_DATA	0x02
+-
+-/* K2 does only extint GPIOs and does 51 of them */
+-#define K2_GPIO_EXTINT_0		0x58
+-#define K2_GPIO_EXTINT_CNT		51
+-
+-/* Specific GPIO regs */
+-
+-#define KL_GPIO_MODEM_RESET		(KEYLARGO_GPIO_0+0x03)
+-#define KL_GPIO_MODEM_POWER		(KEYLARGO_GPIO_0+0x02) /* Pangea */
+-
+-#define KL_GPIO_SOUND_POWER		(KEYLARGO_GPIO_0+0x05)
+-
+-/* Hrm... this one is only to be used on Pismo. It seeem to also
+- * control the timebase enable on other machines. Still to be
+- * experimented... --BenH.
+- */
+-#define KL_GPIO_FW_CABLE_POWER		(KEYLARGO_GPIO_0+0x09)
+-#define KL_GPIO_TB_ENABLE		(KEYLARGO_GPIO_0+0x09)
+-
+-#define KL_GPIO_ETH_PHY_RESET		(KEYLARGO_GPIO_0+0x10)
+-
+-#define KL_GPIO_EXTINT_CPU1		(KEYLARGO_GPIO_0+0x0a)
+-#define KL_GPIO_EXTINT_CPU1_ASSERT	0x04
+-#define KL_GPIO_EXTINT_CPU1_RELEASE	0x38
+-
+-#define KL_GPIO_RESET_CPU0		(KEYLARGO_GPIO_EXTINT_0+0x03)
+-#define KL_GPIO_RESET_CPU1		(KEYLARGO_GPIO_EXTINT_0+0x04)
+-#define KL_GPIO_RESET_CPU2		(KEYLARGO_GPIO_EXTINT_0+0x0f)
+-#define KL_GPIO_RESET_CPU3		(KEYLARGO_GPIO_EXTINT_0+0x10)
+-
+-#define KL_GPIO_PMU_MESSAGE_IRQ		(KEYLARGO_GPIO_EXTINT_0+0x09)
+-#define KL_GPIO_PMU_MESSAGE_BIT		KEYLARGO_GPIO_INPUT_DATA
+-
+-#define KL_GPIO_MEDIABAY_IRQ		(KEYLARGO_GPIO_EXTINT_0+0x0e)
+-
+-#define KL_GPIO_AIRPORT_0		(KEYLARGO_GPIO_EXTINT_0+0x0a)
+-#define KL_GPIO_AIRPORT_1		(KEYLARGO_GPIO_EXTINT_0+0x0d)
+-#define KL_GPIO_AIRPORT_2		(KEYLARGO_GPIO_0+0x0d)
+-#define KL_GPIO_AIRPORT_3		(KEYLARGO_GPIO_0+0x0e)
+-#define KL_GPIO_AIRPORT_4		(KEYLARGO_GPIO_0+0x0f)
+-
+-/*
+- * Bits in feature control register. Those bits different for K2 are
+- * listed separately
+- */
+-#define KL_MBCR_MB0_PCI_ENABLE		0x00000800	/* exist ? */
+-#define KL_MBCR_MB0_IDE_ENABLE		0x00001000
+-#define KL_MBCR_MB0_FLOPPY_ENABLE	0x00002000	/* exist ? */
+-#define KL_MBCR_MB0_SOUND_ENABLE	0x00004000	/* hrm... */
+-#define KL_MBCR_MB0_DEV_MASK		0x00007800
+-#define KL_MBCR_MB0_DEV_POWER		0x00000400
+-#define KL_MBCR_MB0_DEV_RESET		0x00000200
+-#define KL_MBCR_MB0_ENABLE		0x00000100
+-#define KL_MBCR_MB1_PCI_ENABLE		0x08000000	/* exist ? */
+-#define KL_MBCR_MB1_IDE_ENABLE		0x10000000
+-#define KL_MBCR_MB1_FLOPPY_ENABLE	0x20000000	/* exist ? */
+-#define KL_MBCR_MB1_SOUND_ENABLE	0x40000000	/* hrm... */
+-#define KL_MBCR_MB1_DEV_MASK		0x78000000
+-#define KL_MBCR_MB1_DEV_POWER		0x04000000
+-#define KL_MBCR_MB1_DEV_RESET		0x02000000
+-#define KL_MBCR_MB1_ENABLE		0x01000000
+-
+-#define KL0_SCC_B_INTF_ENABLE		0x00000001	/* (KL Only) */
+-#define KL0_SCC_A_INTF_ENABLE		0x00000002
+-#define KL0_SCC_SLOWPCLK		0x00000004
+-#define KL0_SCC_RESET			0x00000008
+-#define KL0_SCCA_ENABLE			0x00000010
+-#define KL0_SCCB_ENABLE			0x00000020
+-#define KL0_SCC_CELL_ENABLE		0x00000040
+-#define KL0_IRDA_HIGH_BAND		0x00000100	/* (KL Only) */
+-#define KL0_IRDA_SOURCE2_SEL		0x00000200	/* (KL Only) */
+-#define KL0_IRDA_SOURCE1_SEL		0x00000400	/* (KL Only) */
+-#define KL0_PG_USB0_PMI_ENABLE		0x00000400	/* (Pangea/Intrepid Only) */
+-#define KL0_IRDA_RESET			0x00000800	/* (KL Only) */
+-#define KL0_PG_USB0_REF_SUSPEND_SEL	0x00000800	/* (Pangea/Intrepid Only) */
+-#define KL0_IRDA_DEFAULT1		0x00001000	/* (KL Only) */
+-#define KL0_PG_USB0_REF_SUSPEND		0x00001000	/* (Pangea/Intrepid Only) */
+-#define KL0_IRDA_DEFAULT0		0x00002000	/* (KL Only) */
+-#define KL0_PG_USB0_PAD_SUSPEND		0x00002000	/* (Pangea/Intrepid Only) */
+-#define KL0_IRDA_FAST_CONNECT		0x00004000	/* (KL Only) */
+-#define KL0_PG_USB1_PMI_ENABLE		0x00004000	/* (Pangea/Intrepid Only) */
+-#define KL0_IRDA_ENABLE			0x00008000	/* (KL Only) */
+-#define KL0_PG_USB1_REF_SUSPEND_SEL	0x00008000	/* (Pangea/Intrepid Only) */
+-#define KL0_IRDA_CLK32_ENABLE		0x00010000	/* (KL Only) */
+-#define KL0_PG_USB1_REF_SUSPEND		0x00010000	/* (Pangea/Intrepid Only) */
+-#define KL0_IRDA_CLK19_ENABLE		0x00020000	/* (KL Only) */
+-#define KL0_PG_USB1_PAD_SUSPEND		0x00020000	/* (Pangea/Intrepid Only) */
+-#define KL0_USB0_PAD_SUSPEND0		0x00040000
+-#define KL0_USB0_PAD_SUSPEND1		0x00080000
+-#define KL0_USB0_CELL_ENABLE		0x00100000
+-#define KL0_USB1_PAD_SUSPEND0		0x00400000
+-#define KL0_USB1_PAD_SUSPEND1		0x00800000
+-#define KL0_USB1_CELL_ENABLE		0x01000000
+-#define KL0_USB_REF_SUSPEND		0x10000000	/* (KL Only) */
+-
+-#define KL0_SERIAL_ENABLE		(KL0_SCC_B_INTF_ENABLE | \
+-					KL0_SCC_SLOWPCLK | \
+-					KL0_SCC_CELL_ENABLE | KL0_SCCA_ENABLE)
+-
+-#define KL1_USB2_PMI_ENABLE		0x00000001	/* Intrepid only */
+-#define KL1_AUDIO_SEL_22MCLK		0x00000002	/* KL/Pangea only */
+-#define KL1_USB2_REF_SUSPEND_SEL	0x00000002	/* Intrepid only */
+-#define KL1_USB2_REF_SUSPEND		0x00000004	/* Intrepid only */
+-#define KL1_AUDIO_CLK_ENABLE_BIT	0x00000008	/* KL/Pangea only */
+-#define KL1_USB2_PAD_SUSPEND_SEL	0x00000008	/* Intrepid only */
+-#define KL1_USB2_PAD_SUSPEND0		0x00000010	/* Intrepid only */
+-#define KL1_AUDIO_CLK_OUT_ENABLE	0x00000020	/* KL/Pangea only */
+-#define KL1_USB2_PAD_SUSPEND1		0x00000020	/* Intrepid only */
+-#define KL1_AUDIO_CELL_ENABLE		0x00000040	/* KL/Pangea only */
+-#define KL1_USB2_CELL_ENABLE		0x00000040	/* Intrepid only */
+-#define KL1_AUDIO_CHOOSE		0x00000080	/* KL/Pangea only */
+-#define KL1_I2S0_CHOOSE			0x00000200	/* KL Only */
+-#define KL1_I2S0_CELL_ENABLE		0x00000400
+-#define KL1_I2S0_CLK_ENABLE_BIT		0x00001000
+-#define KL1_I2S0_ENABLE			0x00002000
+-#define KL1_I2S1_CELL_ENABLE		0x00020000
+-#define KL1_I2S1_CLK_ENABLE_BIT		0x00080000
+-#define KL1_I2S1_ENABLE			0x00100000
+-#define KL1_EIDE0_ENABLE		0x00800000	/* KL/Intrepid Only */
+-#define KL1_EIDE0_RESET_N		0x01000000	/* KL/Intrepid Only */
+-#define KL1_EIDE1_ENABLE		0x04000000	/* KL Only */
+-#define KL1_EIDE1_RESET_N		0x08000000	/* KL Only */
+-#define KL1_UIDE_ENABLE			0x20000000	/* KL/Pangea Only */
+-#define KL1_UIDE_RESET_N		0x40000000	/* KL/Pangea Only */
+-
+-#define KL2_IOBUS_ENABLE		0x00000002
+-#define KL2_SLEEP_STATE_BIT		0x00000100	/* KL Only */
+-#define KL2_PG_STOP_ALL_CLOCKS		0x00000100	/* Pangea Only */
+-#define KL2_MPIC_ENABLE			0x00020000
+-#define KL2_CARDSLOT_RESET		0x00040000	/* Pangea/Intrepid Only */
+-#define KL2_ALT_DATA_OUT		0x02000000	/* KL Only ??? */
+-#define KL2_MEM_IS_BIG			0x04000000
+-#define KL2_CARDSEL_16			0x08000000
+-
+-#define KL3_SHUTDOWN_PLL_TOTAL		0x00000001	/* KL/Pangea only */
+-#define KL3_SHUTDOWN_PLLKW6		0x00000002	/* KL/Pangea only */
+-#define KL3_IT_SHUTDOWN_PLL3		0x00000002	/* Intrepid only */
+-#define KL3_SHUTDOWN_PLLKW4		0x00000004	/* KL/Pangea only */
+-#define KL3_IT_SHUTDOWN_PLL2		0x00000004	/* Intrepid only */
+-#define KL3_SHUTDOWN_PLLKW35		0x00000008	/* KL/Pangea only */
+-#define KL3_IT_SHUTDOWN_PLL1		0x00000008	/* Intrepid only */
+-#define KL3_SHUTDOWN_PLLKW12		0x00000010	/* KL Only */
+-#define KL3_IT_ENABLE_PLL3_SHUTDOWN	0x00000010	/* Intrepid only */
+-#define KL3_PLL_RESET			0x00000020	/* KL/Pangea only */
+-#define KL3_IT_ENABLE_PLL2_SHUTDOWN	0x00000020	/* Intrepid only */
+-#define KL3_IT_ENABLE_PLL1_SHUTDOWN	0x00000010	/* Intrepid only */
+-#define KL3_SHUTDOWN_PLL2X		0x00000080	/* KL Only */
+-#define KL3_CLK66_ENABLE		0x00000100	/* KL Only */
+-#define KL3_CLK49_ENABLE		0x00000200
+-#define KL3_CLK45_ENABLE		0x00000400
+-#define KL3_CLK31_ENABLE		0x00000800	/* KL/Pangea only */
+-#define KL3_TIMER_CLK18_ENABLE		0x00001000
+-#define KL3_I2S1_CLK18_ENABLE		0x00002000
+-#define KL3_I2S0_CLK18_ENABLE		0x00004000
+-#define KL3_VIA_CLK16_ENABLE		0x00008000	/* KL/Pangea only */
+-#define KL3_IT_VIA_CLK32_ENABLE		0x00008000	/* Intrepid only */
+-#define KL3_STOPPING33_ENABLED		0x00080000	/* KL Only */
+-#define KL3_PG_PLL_ENABLE_TEST		0x00080000	/* Pangea Only */
+-
+-/* Intrepid USB bus 2, port 0,1 */
+-#define KL3_IT_PORT_WAKEUP_ENABLE(p)		(0x00080000 << ((p)<<3))
+-#define KL3_IT_PORT_RESUME_WAKE_EN(p)		(0x00040000 << ((p)<<3))
+-#define KL3_IT_PORT_CONNECT_WAKE_EN(p)		(0x00020000 << ((p)<<3))
+-#define KL3_IT_PORT_DISCONNECT_WAKE_EN(p)	(0x00010000 << ((p)<<3))
+-#define KL3_IT_PORT_RESUME_STAT(p)		(0x00300000 << ((p)<<3))
+-#define KL3_IT_PORT_CONNECT_STAT(p)		(0x00200000 << ((p)<<3))
+-#define KL3_IT_PORT_DISCONNECT_STAT(p)		(0x00100000 << ((p)<<3))
+-
+-/* Port 0,1 : bus 0, port 2,3 : bus 1 */
+-#define KL4_PORT_WAKEUP_ENABLE(p)	(0x00000008 << ((p)<<3))
+-#define KL4_PORT_RESUME_WAKE_EN(p)	(0x00000004 << ((p)<<3))
+-#define KL4_PORT_CONNECT_WAKE_EN(p)	(0x00000002 << ((p)<<3))
+-#define KL4_PORT_DISCONNECT_WAKE_EN(p)	(0x00000001 << ((p)<<3))
+-#define KL4_PORT_RESUME_STAT(p)		(0x00000040 << ((p)<<3))
+-#define KL4_PORT_CONNECT_STAT(p)	(0x00000020 << ((p)<<3))
+-#define KL4_PORT_DISCONNECT_STAT(p)	(0x00000010 << ((p)<<3))
+-
+-/* Pangea and Intrepid only */
+-#define KL5_VIA_USE_CLK31		0000000001	/* Pangea Only */
+-#define KL5_SCC_USE_CLK31		0x00000002	/* Pangea Only */
+-#define KL5_PWM_CLK32_EN		0x00000004
+-#define KL5_CLK3_68_EN			0x00000010
+-#define KL5_CLK32_EN			0x00000020
+-
+-
+-/* K2 definitions */
+-#define K2_FCR0_USB0_SWRESET		0x00200000
+-#define K2_FCR0_USB1_SWRESET		0x02000000
+-#define K2_FCR0_RING_PME_DISABLE	0x08000000
+-
+-#define K2_FCR1_PCI1_BUS_RESET_N	0x00000010
+-#define K2_FCR1_PCI1_SLEEP_RESET_EN	0x00000020
+-#define K2_FCR1_I2S0_CELL_ENABLE	0x00000400
+-#define K2_FCR1_I2S0_RESET		0x00000800
+-#define K2_FCR1_I2S0_CLK_ENABLE_BIT	0x00001000
+-#define K2_FCR1_I2S0_ENABLE    		0x00002000
+-
+-#define K2_FCR1_PCI1_CLK_ENABLE		0x00004000
+-#define K2_FCR1_FW_CLK_ENABLE		0x00008000
+-#define K2_FCR1_FW_RESET_N		0x00010000
+-#define K2_FCR1_GMAC_CLK_ENABLE		0x00400000
+-#define K2_FCR1_GMAC_POWER_DOWN		0x00800000
+-#define K2_FCR1_GMAC_RESET_N		0x01000000
+-#define K2_FCR1_SATA_CLK_ENABLE		0x02000000
+-#define K2_FCR1_SATA_POWER_DOWN		0x04000000
+-#define K2_FCR1_SATA_RESET_N		0x08000000
+-#define K2_FCR1_UATA_CLK_ENABLE		0x10000000
+-#define K2_FCR1_UATA_RESET_N		0x40000000
+-#define K2_FCR1_UATA_CHOOSE_CLK66	0x80000000
+-
+diff --git a/include/asm-ppc/kmap_types.h b/include/asm-ppc/kmap_types.h
+deleted file mode 100644
+--- a/include/asm-ppc/kmap_types.h
++++ /dev/null
+@@ -1,25 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef _ASM_KMAP_TYPES_H
+-#define _ASM_KMAP_TYPES_H
+-
+-enum km_type {
+-	KM_BOUNCE_READ,
+-	KM_SKB_SUNRPC_DATA,
+-	KM_SKB_DATA_SOFTIRQ,
+-	KM_USER0,
+-	KM_USER1,
+-	KM_BIO_SRC_IRQ,
+-	KM_BIO_DST_IRQ,
+-	KM_PTE0,
+-	KM_PTE1,
+-	KM_IRQ0,
+-	KM_IRQ1,
+-	KM_SOFTIRQ0,
+-	KM_SOFTIRQ1,
+-	KM_PPC_SYNC_PAGE,
+-	KM_PPC_SYNC_ICACHE,
+-	KM_TYPE_NR
+-};
+-
+-#endif
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
+--- a/include/asm-ppc/machdep.h
++++ b/include/asm-ppc/machdep.h
+@@ -98,7 +98,7 @@ struct machdep_calls {
+ 
+ 	/* Get access protection for /dev/mem */
+ 	pgprot_t	(*phys_mem_access_prot)(struct file *file,
+-						unsigned long offset,
++						unsigned long pfn,
+ 						unsigned long size,
+ 						pgprot_t vma_prot);
+ 
+@@ -167,7 +167,7 @@ extern sys_ctrler_t sys_ctrler;
+ 
+ #ifdef CONFIG_SMP
+ struct smp_ops_t {
+-	void  (*message_pass)(int target, int msg, unsigned long data, int wait);
++	void  (*message_pass)(int target, int msg);
+ 	int   (*probe)(void);
+ 	void  (*kick_cpu)(int nr);
+ 	void  (*setup_cpu)(int nr);
+diff --git a/include/asm-ppc/macio.h b/include/asm-ppc/macio.h
+deleted file mode 100644
+--- a/include/asm-ppc/macio.h
++++ /dev/null
+@@ -1,140 +0,0 @@
+-#ifndef __MACIO_ASIC_H__
+-#define __MACIO_ASIC_H__
+-
+-#include <asm/of_device.h>
+-
+-extern struct bus_type macio_bus_type;
+-
+-/* MacIO device driver is defined later */
+-struct macio_driver;
+-struct macio_chip;
+-
+-#define MACIO_DEV_COUNT_RESOURCES	8
+-#define MACIO_DEV_COUNT_IRQS		8
+-
+-/*
+- * the macio_bus structure is used to describe a "virtual" bus
+- * within a MacIO ASIC. It's typically provided by a macio_pci_asic
+- * PCI device, but could be provided differently as well (nubus
+- * machines using a fake OF tree).
+- *
+- * The pdev field can be NULL on non-PCI machines
+- */
+-struct macio_bus
+-{
+-	struct macio_chip	*chip;		/* macio_chip (private use) */
+-	int			index;		/* macio chip index in system */
+-#ifdef CONFIG_PCI
+-	struct pci_dev		*pdev;		/* PCI device hosting this bus */
+-#endif
+-};
+-
+-/*
+- * the macio_dev structure is used to describe a device
+- * within an Apple MacIO ASIC.
+- */
+-struct macio_dev
+-{
+-	struct macio_bus	*bus;		/* macio bus this device is on */
+-	struct macio_dev	*media_bay;	/* Device is part of a media bay */
+-	struct of_device	ofdev;
+-	int			n_resources;
+-	struct resource		resource[MACIO_DEV_COUNT_RESOURCES];
+-	int			n_interrupts;
+-	struct resource		interrupt[MACIO_DEV_COUNT_IRQS];
+-};
+-#define	to_macio_device(d) container_of(d, struct macio_dev, ofdev.dev)
+-#define	of_to_macio_device(d) container_of(d, struct macio_dev, ofdev)
+-
+-extern struct macio_dev *macio_dev_get(struct macio_dev *dev);
+-extern void macio_dev_put(struct macio_dev *dev);
+-
+-/*
+- * Accessors to resources & interrupts and other device
+- * fields
+- */
+-
+-static inline int macio_resource_count(struct macio_dev *dev)
+-{
+-	return dev->n_resources;
+-}
+-
+-static inline unsigned long macio_resource_start(struct macio_dev *dev, int resource_no)
+-{
+-	return dev->resource[resource_no].start;
+-}
+-
+-static inline unsigned long macio_resource_end(struct macio_dev *dev, int resource_no)
+-{
+-	return dev->resource[resource_no].end;
+-}
+-
+-static inline unsigned long macio_resource_len(struct macio_dev *dev, int resource_no)
+-{
+-	struct resource *res = &dev->resource[resource_no];
+-	if (res->start == 0 || res->end == 0 || res->end < res->start)
+-		return 0;
+-	return res->end - res->start + 1;
+-}
+-
+-extern int macio_request_resource(struct macio_dev *dev, int resource_no, const char *name);
+-extern void macio_release_resource(struct macio_dev *dev, int resource_no);
+-extern int macio_request_resources(struct macio_dev *dev, const char *name);
+-extern void macio_release_resources(struct macio_dev *dev);
+-
+-static inline int macio_irq_count(struct macio_dev *dev)
+-{
+-	return dev->n_interrupts;
+-}
+-
+-static inline int macio_irq(struct macio_dev *dev, int irq_no)
+-{
+-	return dev->interrupt[irq_no].start;
+-}
+-
+-static inline void macio_set_drvdata(struct macio_dev *dev, void *data)
+-{
+-	dev_set_drvdata(&dev->ofdev.dev, data);
+-}
+-
+-static inline void* macio_get_drvdata(struct macio_dev *dev)
+-{
+-	return dev_get_drvdata(&dev->ofdev.dev);
+-}
+-
+-static inline struct device_node *macio_get_of_node(struct macio_dev *mdev)
+-{
+-	return mdev->ofdev.node;
+-}
+-
+-#ifdef CONFIG_PCI
+-static inline struct pci_dev *macio_get_pci_dev(struct macio_dev *mdev)
+-{
+-	return mdev->bus->pdev;
+-}
+-#endif
+-
+-/*
+- * A driver for a mac-io chip based device
+- */
+-struct macio_driver
+-{
+-	char			*name;
+-	struct of_device_id	*match_table;
+-	struct module		*owner;
+-
+-	int	(*probe)(struct macio_dev* dev, const struct of_device_id *match);
+-	int	(*remove)(struct macio_dev* dev);
+-
+-	int	(*suspend)(struct macio_dev* dev, pm_message_t state);
+-	int	(*resume)(struct macio_dev* dev);
+-	int	(*shutdown)(struct macio_dev* dev);
+-
+-	struct device_driver	driver;
+-};
+-#define	to_macio_driver(drv) container_of(drv,struct macio_driver, driver)
+-
+-extern int macio_register_driver(struct macio_driver *);
+-extern void macio_unregister_driver(struct macio_driver *);
+-
+-#endif /* __MACIO_ASIC_H__ */
+diff --git a/include/asm-ppc/mediabay.h b/include/asm-ppc/mediabay.h
+deleted file mode 100644
+--- a/include/asm-ppc/mediabay.h
++++ /dev/null
+@@ -1,31 +0,0 @@
+-/*
+- * mediabay.h: definitions for using the media bay
+- * on PowerBook 3400 and similar computers.
+- *
+- * Copyright (C) 1997 Paul Mackerras.
+- */
+-#ifndef _PPC_MEDIABAY_H
+-#define _PPC_MEDIABAY_H
+-
+-#ifdef __KERNEL__
+-
+-#define MB_FD		0	/* media bay contains floppy drive (automatic eject ?) */
+-#define MB_FD1		1	/* media bay contains floppy drive (manual eject ?) */
+-#define MB_SOUND	2	/* sound device ? */
+-#define MB_CD		3	/* media bay contains ATA drive such as CD or ZIP */
+-#define MB_PCI		5	/* media bay contains a PCI device */
+-#define MB_POWER	6	/* media bay contains a Power device (???) */
+-#define MB_NO		7	/* media bay contains nothing */
+-
+-int check_media_bay(struct device_node *which_bay, int what);
+-int check_media_bay_by_base(unsigned long base, int what);
+-
+-/* Number of bays in the machine or 0 */
+-extern int media_bay_count;
+-
+-/* called by pmac-ide.c to register IDE controller for media bay */
+-extern int media_bay_set_ide_infos(struct device_node* which_bay,
+-			unsigned long base, int irq, int index);
+-
+-#endif /* __KERNEL__ */
+-#endif /* _PPC_MEDIABAY_H */
+diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
+--- a/include/asm-ppc/mmu_context.h
++++ b/include/asm-ppc/mmu_context.h
+@@ -164,13 +164,11 @@ static inline void switch_mm(struct mm_s
+ 			     struct task_struct *tsk)
+ {
+ #ifdef CONFIG_ALTIVEC
+-	asm volatile (
+- BEGIN_FTR_SECTION
+-	"dssall;\n"
++	if (cpu_has_feature(CPU_FTR_ALTIVEC))
++	asm volatile ("dssall;\n"
+ #ifndef CONFIG_POWER4
+ 	 "sync;\n" /* G4 needs a sync here, G5 apparently not */
+ #endif
+- END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ 	 : : );
+ #endif /* CONFIG_ALTIVEC */
+ 
+diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
+--- a/include/asm-ppc/mpc8260.h
++++ b/include/asm-ppc/mpc8260.h
+@@ -92,6 +92,10 @@ enum ppc_sys_devices {
+ extern unsigned char __res[];
+ #endif
+ 
++#ifndef BOARD_CHIP_NAME
++#define BOARD_CHIP_NAME ""
++#endif
++
+ #endif /* CONFIG_8260 */
+ #endif /* !__ASM_PPC_MPC8260_H__ */
+ #endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
+--- a/include/asm-ppc/mpc85xx.h
++++ b/include/asm-ppc/mpc85xx.h
+@@ -67,6 +67,8 @@ extern unsigned char __res[];
+ #define MPC85xx_DMA3_SIZE	(0x00080)
+ #define MPC85xx_ENET1_OFFSET	(0x24000)
+ #define MPC85xx_ENET1_SIZE	(0x01000)
++#define MPC85xx_MIIM_OFFSET	(0x24520)
++#define MPC85xx_MIIM_SIZE	(0x00018)
+ #define MPC85xx_ENET2_OFFSET	(0x25000)
+ #define MPC85xx_ENET2_SIZE	(0x01000)
+ #define MPC85xx_ENET3_OFFSET	(0x26000)
+@@ -132,6 +134,7 @@ enum ppc_sys_devices {
+ 	MPC85xx_eTSEC3,
+ 	MPC85xx_eTSEC4,
+ 	MPC85xx_IIC2,
++	MPC85xx_MDIO,
+ };
+ 
+ /* Internal interrupts are all Level Sensitive, and Positive Polarity */
+diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
+--- a/include/asm-ppc/mpc8xx.h
++++ b/include/asm-ppc/mpc8xx.h
+@@ -113,6 +113,10 @@ enum ppc_sys_devices {
+ 	MPC8xx_CPM_USB,
+ };
+ 
++#ifndef BOARD_CHIP_NAME
++#define BOARD_CHIP_NAME ""
++#endif
++
+ #endif /* !__ASSEMBLY__ */
+ #endif /* CONFIG_8xx */
+ #endif /* __CONFIG_8xx_DEFS */
+diff --git a/include/asm-ppc/mv64x60.h b/include/asm-ppc/mv64x60.h
+--- a/include/asm-ppc/mv64x60.h
++++ b/include/asm-ppc/mv64x60.h
+@@ -27,6 +27,8 @@
+ #include <asm/pci-bridge.h>
+ #include <asm/mv64x60_defs.h>
+ 
++struct platform_device;
++
+ extern u8	mv64x60_pci_exclude_bridge;
+ 
+ extern spinlock_t mv64x60_lock;
+diff --git a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h
+deleted file mode 100644
+--- a/include/asm-ppc/of_device.h
++++ /dev/null
+@@ -1,65 +0,0 @@
+-#ifndef __OF_DEVICE_H__
+-#define __OF_DEVICE_H__
+-
+-#include <linux/device.h>
+-#include <linux/mod_devicetable.h>
+-#include <asm/prom.h>
+-
+-/*
+- * The of_platform_bus_type is a bus type used by drivers that do not
+- * attach to a macio or similar bus but still use OF probing
+- * mecanism
+- */
+-extern struct bus_type of_platform_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;		/* OF device node */
+-	u64			dma_mask;	/* DMA mask */
+-	struct device		dev;		/* Generic device interface */
+-};
+-#define	to_of_device(d) container_of(d, struct of_device, dev)
+-
+-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 "platform bus" (of_platform_bus_type)
+- */
+-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);
+-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);
+-extern void of_release_dev(struct device *dev);
+-
+-#endif /* __OF_DEVICE_H__ */
+-
+diff --git a/include/asm-ppc/ohare.h b/include/asm-ppc/ohare.h
+deleted file mode 100644
+--- a/include/asm-ppc/ohare.h
++++ /dev/null
+@@ -1,48 +0,0 @@
+-/*
+- * ohare.h: definitions for using the "O'Hare" I/O controller chip.
+- *
+- * Copyright (C) 1997 Paul Mackerras.
+- *
+- * BenH: Changed to match those of heathrow (but not all of them). Please
+- *       check if I didn't break anything (especially the media bay).
+- */
+-
+-/* offset from ohare base for feature control register */
+-#define OHARE_MBCR	0x34
+-#define OHARE_FCR	0x38
+-
+-/*
+- * Bits in feature control register.
+- * These were mostly derived by experiment on a powerbook 3400
+- * and may differ for other machines.
+- */
+-#define OH_SCC_RESET		1
+-#define OH_BAY_POWER_N		2	/* a guess */
+-#define OH_BAY_PCI_ENABLE	4	/* a guess */
+-#define OH_BAY_IDE_ENABLE	8
+-#define OH_BAY_FLOPPY_ENABLE	0x10
+-#define OH_IDE0_ENABLE		0x20
+-#define OH_IDE0_RESET_N		0x40	/* a guess */
+-#define OH_BAY_DEV_MASK		0x1c
+-#define OH_BAY_RESET_N		0x80
+-#define OH_IOBUS_ENABLE		0x100	/* IOBUS seems to be IDE */
+-#define OH_SCC_ENABLE		0x200
+-#define OH_MESH_ENABLE		0x400
+-#define OH_FLOPPY_ENABLE	0x800
+-#define OH_SCCA_IO		0x4000
+-#define OH_SCCB_IO		0x8000
+-#define OH_VIA_ENABLE		0x10000	/* Is apparently wrong, to be verified */
+-#define OH_IDE1_RESET_N		0x800000
+-
+-/*
+- * Bits to set in the feature control register on PowerBooks.
+- */
+-#define PBOOK_FEATURES		(OH_IDE_ENABLE | OH_SCC_ENABLE | \
+-				 OH_MESH_ENABLE | OH_SCCA_IO | OH_SCCB_IO)
+-
+-/*
+- * A magic value to put into the feature control register of the
+- * "ohare" I/O controller on Starmaxes to enable the IDE CD interface.
+- * Contributed by Harry Eaton.
+- */
+-#define STARMAX_FEATURES	0xbeff7a
+diff --git a/include/asm-ppc/open_pic.h b/include/asm-ppc/open_pic.h
+--- a/include/asm-ppc/open_pic.h
++++ b/include/asm-ppc/open_pic.h
+@@ -58,8 +58,7 @@ extern int openpic_get_irq(struct pt_reg
+ extern void openpic_reset_processor_phys(u_int cpumask);
+ extern void openpic_setup_ISU(int isu_num, unsigned long addr);
+ extern void openpic_cause_IPI(u_int ipi, cpumask_t cpumask);
+-extern void smp_openpic_message_pass(int target, int msg, unsigned long data,
+-				     int wait);
++extern void smp_openpic_message_pass(int target, int msg);
+ extern void openpic_set_k2_cascade(int irq);
+ extern void openpic_set_priority(u_int pri);
+ extern u_int openpic_get_priority(void);
+diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
+--- a/include/asm-ppc/page.h
++++ b/include/asm-ppc/page.h
+@@ -34,6 +34,17 @@ typedef unsigned long pte_basic_t;
+ #define PTE_FMT		"%.8lx"
+ #endif
+ 
++/* align addr on a size boundary - adjust address up/down if needed */
++#define _ALIGN_UP(addr,size)	(((addr)+((size)-1))&(~((size)-1)))
++#define _ALIGN_DOWN(addr,size)	((addr)&(~((size)-1)))
++
++/* align addr on a size boundary - adjust address up if needed */
++#define _ALIGN(addr,size)     _ALIGN_UP(addr,size)
++
++/* to align the pointer to the (next) page boundary */
++#define PAGE_ALIGN(addr)	_ALIGN(addr, PAGE_SIZE)
++
++
+ #undef STRICT_MM_TYPECHECKS
+ 
+ #ifdef STRICT_MM_TYPECHECKS
+@@ -76,13 +87,6 @@ typedef unsigned long pgprot_t;
+ 
+ #endif
+ 
+-
+-/* align addr on a size boundary - adjust address up if needed -- Cort */
+-#define _ALIGN(addr,size)	(((addr)+(size)-1)&(~((size)-1)))
+-
+-/* to align the pointer to the (next) page boundary */
+-#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+-
+ struct page;
+ extern void clear_pages(void *page, int order);
+ static inline void clear_page(void *page) { clear_pages(page, 0); }
+diff --git a/include/asm-ppc/parport.h b/include/asm-ppc/parport.h
+deleted file mode 100644
+--- a/include/asm-ppc/parport.h
++++ /dev/null
+@@ -1,18 +0,0 @@
+-/*
+- * parport.h: platform-specific PC-style parport initialisation
+- *
+- * Copyright (C) 1999, 2000  Tim Waugh <tim at cyberelk.demon.co.uk>
+- *
+- * This file should only be included by drivers/parport/parport_pc.c.
+- */
+-
+-#ifndef _ASM_PPC_PARPORT_H
+-#define _ASM_PPC_PARPORT_H
+-
+-static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
+-static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
+-{
+-	return parport_pc_find_isa_ports (autoirq, autodma);
+-}
+-
+-#endif /* !(_ASM_PPC_PARPORT_H) */
+diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h
+--- a/include/asm-ppc/pci-bridge.h
++++ b/include/asm-ppc/pci-bridge.h
+@@ -79,6 +79,11 @@ struct pci_controller {
+ 	struct resource mem_space;
+ };
+ 
++static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
++{
++	return bus->sysdata;
++}
++
+ /* These are used for config access before all the PCI probing
+    has been done. */
+ int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn,
+diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
+--- a/include/asm-ppc/pci.h
++++ b/include/asm-ppc/pci.h
+@@ -24,9 +24,9 @@ struct pci_dev;
+  * Set this to 1 if you want the kernel to re-assign all PCI
+  * bus numbers
+  */
+-extern int pci_assign_all_busses;
++extern int pci_assign_all_buses;
+ 
+-#define pcibios_assign_all_busses()	(pci_assign_all_busses)
++#define pcibios_assign_all_busses()	(pci_assign_all_buses)
+ #define pcibios_scan_all_fns(a, b)	0
+ 
+ #define PCIBIOS_MIN_IO		0x1000
+@@ -126,7 +126,7 @@ extern void pcibios_add_platform_entries
+ 
+ struct file;
+ extern pgprot_t	pci_phys_mem_access_prot(struct file *file,
+-					 unsigned long offset,
++					 unsigned long pfn,
+ 					 unsigned long size,
+ 					 pgprot_t prot);
+ 
+diff --git a/include/asm-ppc/perfmon.h b/include/asm-ppc/perfmon.h
+deleted file mode 100644
+--- a/include/asm-ppc/perfmon.h
++++ /dev/null
+@@ -1,22 +0,0 @@
+-#ifndef __PERFMON_H
+-#define __PERFMON_H
+-
+-extern void (*perf_irq)(struct pt_regs *);
+-
+-int request_perfmon_irq(void (*handler)(struct pt_regs *));
+-void free_perfmon_irq(void);
+-
+-#ifdef CONFIG_FSL_BOOKE
+-void init_pmc_stop(int ctr);
+-void set_pmc_event(int ctr, int event);
+-void set_pmc_user_kernel(int ctr, int user, int kernel);
+-void set_pmc_marked(int ctr, int mark0, int mark1);
+-void pmc_start_ctr(int ctr, int enable);
+-void pmc_start_ctrs(int enable);
+-void pmc_stop_ctrs(void);
+-void dump_pmcs(void);
+-
+-extern struct op_ppc32_model op_model_fsl_booke;
+-#endif
+-
+-#endif /* __PERFMON_H */
+diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
+--- a/include/asm-ppc/pgtable.h
++++ b/include/asm-ppc/pgtable.h
+@@ -705,7 +705,7 @@ static inline void __ptep_set_access_fla
+ #define pgprot_noncached(prot)	(__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
+ 
+ struct file;
+-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
++extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ 				     unsigned long size, pgprot_t vma_prot);
+ #define __HAVE_PHYS_MEM_ACCESS_PROT
+ 
+diff --git a/include/asm-ppc/pmac_feature.h b/include/asm-ppc/pmac_feature.h
+deleted file mode 100644
+--- a/include/asm-ppc/pmac_feature.h
++++ /dev/null
+@@ -1,380 +0,0 @@
+-/*
+- * Definition of platform feature hooks for PowerMacs
+- *
+- * 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) 1998 Paul Mackerras &
+- *                    Ben. Herrenschmidt.
+- *
+- *
+- * Note: I removed media-bay details from the feature stuff, I believe it's
+- *       not worth it, the media-bay driver can directly use the mac-io
+- *       ASIC registers.
+- *
+- * Implementation note: Currently, none of these functions will block.
+- * However, they may internally protect themselves with a spinlock
+- * for way too long. Be prepared for at least some of these to block
+- * in the future.
+- *
+- * Unless specifically defined, the result code is assumed to be an
+- * error when negative, 0 is the default success result. Some functions
+- * may return additional positive result values.
+- *
+- * To keep implementation simple, all feature calls are assumed to have
+- * the prototype parameters (struct device_node* node, int value).
+- * When either is not used, pass 0.
+- */
+-
+-#ifdef __KERNEL__
+-#ifndef __PPC_ASM_PMAC_FEATURE_H
+-#define __PPC_ASM_PMAC_FEATURE_H
+-
+-#include <asm/macio.h>
+-#include <asm/machdep.h>
+-
+-/*
+- * Known Mac motherboard models
+- *
+- * Please, report any error here to benh at kernel.crashing.org, thanks !
+- *
+- * Note that I don't fully maintain this list for Core99 & MacRISC2
+- * and I'm considering removing all NewWorld entries from it and
+- * entirely rely on the model string.
+- */
+-
+-/* PowerSurge are the first generation of PCI Pmacs. This include
+- * all of the Grand-Central based machines. We currently don't
+- * differenciate most of them.
+- */
+-#define PMAC_TYPE_PSURGE		0x10	/* PowerSurge */
+-#define PMAC_TYPE_ANS			0x11	/* Apple Network Server */
+-
+-/* Here is the infamous serie of OHare based machines
+- */
+-#define PMAC_TYPE_COMET			0x20	/* Beleived to be PowerBook 2400 */
+-#define PMAC_TYPE_HOOPER		0x21	/* Beleived to be PowerBook 3400 */
+-#define PMAC_TYPE_KANGA			0x22	/* PowerBook 3500 (first G3) */
+-#define PMAC_TYPE_ALCHEMY		0x23	/* Alchemy motherboard base */
+-#define PMAC_TYPE_GAZELLE		0x24	/* Spartacus, some 5xxx/6xxx */
+-#define PMAC_TYPE_UNKNOWN_OHARE		0x2f	/* Unknown, but OHare based */
+-
+-/* Here are the Heathrow based machines
+- * FIXME: Differenciate wallstreet,mainstreet,wallstreetII
+- */
+-#define PMAC_TYPE_GOSSAMER		0x30	/* Gossamer motherboard */
+-#define PMAC_TYPE_SILK			0x31	/* Desktop PowerMac G3 */
+-#define PMAC_TYPE_WALLSTREET		0x32	/* Wallstreet/Mainstreet PowerBook*/
+-#define PMAC_TYPE_UNKNOWN_HEATHROW	0x3f	/* Unknown but heathrow based */
+-
+-/* Here are newworld machines based on Paddington (heathrow derivative)
+- */
+-#define PMAC_TYPE_101_PBOOK		0x40	/* 101 PowerBook (aka Lombard) */
+-#define PMAC_TYPE_ORIG_IMAC		0x41	/* First generation iMac */
+-#define PMAC_TYPE_YOSEMITE		0x42	/* B&W G3 */
+-#define PMAC_TYPE_YIKES			0x43	/* Yikes G4 (PCI graphics) */
+-#define PMAC_TYPE_UNKNOWN_PADDINGTON	0x4f	/* Unknown but paddington based */
+-
+-/* Core99 machines based on UniNorth 1.0 and 1.5
+- *
+- * Note: A single entry here may cover several actual models according
+- * to the device-tree. (Sawtooth is most tower G4s, FW_IMAC is most
+- * FireWire based iMacs, etc...). Those machines are too similar to be
+- * distinguished here, when they need to be differencied, use the
+- * device-tree "model" or "compatible" property.
+- */
+-#define PMAC_TYPE_ORIG_IBOOK		0x40	/* First iBook model (no firewire) */
+-#define PMAC_TYPE_SAWTOOTH		0x41	/* Desktop G4s */
+-#define PMAC_TYPE_FW_IMAC		0x42	/* FireWire iMacs (except Pangea based) */
+-#define PMAC_TYPE_FW_IBOOK		0x43	/* FireWire iBooks (except iBook2) */
+-#define PMAC_TYPE_CUBE			0x44	/* Cube PowerMac */
+-#define PMAC_TYPE_QUICKSILVER		0x45	/* QuickSilver G4s */
+-#define PMAC_TYPE_PISMO			0x46	/* Pismo PowerBook */
+-#define PMAC_TYPE_TITANIUM		0x47	/* Titanium PowerBook */
+-#define PMAC_TYPE_TITANIUM2		0x48	/* Titanium II PowerBook (no L3, M6) */
+-#define PMAC_TYPE_TITANIUM3		0x49	/* Titanium III PowerBook (with L3 & M7) */
+-#define PMAC_TYPE_TITANIUM4		0x50	/* Titanium IV PowerBook (with L3 & M9) */
+-#define PMAC_TYPE_EMAC			0x50	/* eMac */
+-#define PMAC_TYPE_UNKNOWN_CORE99	0x5f
+-
+-/* MacRisc2 with UniNorth 2.0 */
+-#define PMAC_TYPE_RACKMAC		0x80	/* XServe */
+-#define PMAC_TYPE_WINDTUNNEL		0x81
+-
+-/* MacRISC2 machines based on the Pangea chipset
+- */
+-#define PMAC_TYPE_PANGEA_IMAC		0x100	/* Flower Power iMac */
+-#define PMAC_TYPE_IBOOK2		0x101	/* iBook2 (polycarbonate) */
+-#define PMAC_TYPE_FLAT_PANEL_IMAC	0x102	/* Flat panel iMac */
+-#define PMAC_TYPE_UNKNOWN_PANGEA	0x10f
+-
+-/* MacRISC2 machines based on the Intrepid chipset
+- */
+-#define PMAC_TYPE_UNKNOWN_INTREPID	0x11f	/* Generic */
+-
+-/* MacRISC4 / G5 machines. We don't have per-machine selection here anymore,
+- * but rather machine families
+- */
+-#define PMAC_TYPE_POWERMAC_G5		0x150	/* U3 & U3H based */
+-#define PMAC_TYPE_POWERMAC_G5_U3L	0x151	/* U3L based desktop */
+-#define PMAC_TYPE_IMAC_G5		0x152	/* iMac G5 */
+-#define PMAC_TYPE_XSERVE_G5		0x153	/* Xserve G5 */
+-#define PMAC_TYPE_UNKNOWN_K2		0x19f	/* Any other K2 based */
+-
+-/*
+- * Motherboard flags
+- */
+-
+-#define PMAC_MB_CAN_SLEEP		0x00000001
+-#define PMAC_MB_HAS_FW_POWER		0x00000002
+-#define PMAC_MB_OLD_CORE99		0x00000004
+-#define PMAC_MB_MOBILE			0x00000008
+-#define PMAC_MB_MAY_SLEEP		0x00000010
+-
+-/*
+- * Feature calls supported on pmac
+- *
+- */
+-
+-/*
+- * Use this inline wrapper
+- */
+-struct device_node;
+-
+-static inline long pmac_call_feature(int selector, struct device_node* node,
+-					long param, long value)
+-{
+-	if (!ppc_md.feature_call)
+-		return -ENODEV;
+-	return ppc_md.feature_call(selector, node, param, value);
+-}
+-
+-/* PMAC_FTR_SERIAL_ENABLE	(struct device_node* node, int param, int value)
+- * enable/disable an SCC side. Pass the node corresponding to the
+- * channel side as a parameter.
+- * param is the type of port
+- * if param is ored with PMAC_SCC_FLAG_XMON, then the SCC is locked enabled
+- * for use by xmon.
+- */
+-#define PMAC_FTR_SCC_ENABLE		PMAC_FTR_DEF(0)
+-	#define PMAC_SCC_ASYNC		0
+-	#define PMAC_SCC_IRDA		1
+-	#define PMAC_SCC_I2S1		2
+-	#define PMAC_SCC_FLAG_XMON	0x00001000
+-
+-/* PMAC_FTR_MODEM_ENABLE	(struct device_node* node, 0, int value)
+- * enable/disable the internal modem.
+- */
+-#define PMAC_FTR_MODEM_ENABLE		PMAC_FTR_DEF(1)
+-
+-/* PMAC_FTR_SWIM3_ENABLE	(struct device_node* node, 0,int value)
+- * enable/disable the swim3 (floppy) cell of a mac-io ASIC
+- */
+-#define PMAC_FTR_SWIM3_ENABLE		PMAC_FTR_DEF(2)
+-
+-/* PMAC_FTR_MESH_ENABLE		(struct device_node* node, 0, int value)
+- * enable/disable the mesh (scsi) cell of a mac-io ASIC
+- */
+-#define PMAC_FTR_MESH_ENABLE		PMAC_FTR_DEF(3)
+-
+-/* PMAC_FTR_IDE_ENABLE		(struct device_node* node, int busID, int value)
+- * enable/disable an IDE port of a mac-io ASIC
+- * pass the busID parameter
+- */
+-#define PMAC_FTR_IDE_ENABLE		PMAC_FTR_DEF(4)
+-
+-/* PMAC_FTR_IDE_RESET		(struct device_node* node, int busID, int value)
+- * assert(1)/release(0) an IDE reset line (mac-io IDE only)
+- */
+-#define PMAC_FTR_IDE_RESET		PMAC_FTR_DEF(5)
+-
+-/* PMAC_FTR_BMAC_ENABLE		(struct device_node* node, 0, int value)
+- * enable/disable the bmac (ethernet) cell of a mac-io ASIC, also drive
+- * it's reset line
+- */
+-#define PMAC_FTR_BMAC_ENABLE		PMAC_FTR_DEF(6)
+-
+-/* PMAC_FTR_GMAC_ENABLE		(struct device_node* node, 0, int value)
+- * enable/disable the gmac (ethernet) cell of an uninorth ASIC. This
+- * control the cell's clock.
+- */
+-#define PMAC_FTR_GMAC_ENABLE		PMAC_FTR_DEF(7)
+-
+-/* PMAC_FTR_GMAC_PHY_RESET	(struct device_node* node, 0, 0)
+- * Perform a HW reset of the PHY connected to a gmac controller.
+- * Pass the gmac device node, not the PHY node.
+- */
+-#define PMAC_FTR_GMAC_PHY_RESET		PMAC_FTR_DEF(8)
+-
+-/* PMAC_FTR_SOUND_CHIP_ENABLE	(struct device_node* node, 0, int value)
+- * enable/disable the sound chip, whatever it is and provided it can
+- * acually be controlled
+- */
+-#define PMAC_FTR_SOUND_CHIP_ENABLE	PMAC_FTR_DEF(9)
+-
+-/* -- add various tweaks related to sound routing -- */
+-
+-/* PMAC_FTR_AIRPORT_ENABLE	(struct device_node* node, 0, int value)
+- * enable/disable the airport card
+- */
+-#define PMAC_FTR_AIRPORT_ENABLE		PMAC_FTR_DEF(10)
+-
+-/* PMAC_FTR_RESET_CPU		(NULL, int cpu_nr, 0)
+- * toggle the reset line of a CPU on an uninorth-based SMP machine
+- */
+-#define PMAC_FTR_RESET_CPU		PMAC_FTR_DEF(11)
+-
+-/* PMAC_FTR_USB_ENABLE		(struct device_node* node, 0, int value)
+- * enable/disable an USB cell, along with the power of the USB "pad"
+- * on keylargo based machines
+- */
+-#define PMAC_FTR_USB_ENABLE		PMAC_FTR_DEF(12)
+-
+-/* PMAC_FTR_1394_ENABLE		(struct device_node* node, 0, int value)
+- * enable/disable the firewire cell of an uninorth ASIC.
+- */
+-#define PMAC_FTR_1394_ENABLE		PMAC_FTR_DEF(13)
+-
+-/* PMAC_FTR_1394_CABLE_POWER	(struct device_node* node, 0, int value)
+- * enable/disable the firewire cable power supply of the uninorth
+- * firewire cell
+- */
+-#define PMAC_FTR_1394_CABLE_POWER	PMAC_FTR_DEF(14)
+-
+-/* PMAC_FTR_SLEEP_STATE		(struct device_node* node, 0, int value)
+- * set the sleep state of the motherboard.
+- *
+- * Pass -1 as value to query for sleep capability
+- * Pass 1 to set IOs to sleep
+- * Pass 0 to set IOs to wake
+- */
+-#define PMAC_FTR_SLEEP_STATE		PMAC_FTR_DEF(15)
+-
+-/* PMAC_FTR_GET_MB_INFO		(NULL, selector, 0)
+- *
+- * returns some motherboard infos.
+- * selector: 0  - model id
+- *           1  - model flags (capabilities)
+- *           2  - model name (cast to const char *)
+- */
+-#define PMAC_FTR_GET_MB_INFO		PMAC_FTR_DEF(16)
+-#define   PMAC_MB_INFO_MODEL	0
+-#define   PMAC_MB_INFO_FLAGS	1
+-#define   PMAC_MB_INFO_NAME	2
+-
+-/* PMAC_FTR_READ_GPIO		(NULL, int index, 0)
+- *
+- * read a GPIO from a mac-io controller of type KeyLargo or Pangea.
+- * the value returned is a byte (positive), or a negative error code
+- */
+-#define PMAC_FTR_READ_GPIO		PMAC_FTR_DEF(17)
+-
+-/* PMAC_FTR_WRITE_GPIO		(NULL, int index, int value)
+- *
+- * write a GPIO of a mac-io controller of type KeyLargo or Pangea.
+- */
+-#define PMAC_FTR_WRITE_GPIO		PMAC_FTR_DEF(18)
+-
+-/* PMAC_FTR_ENABLE_MPIC
+- *
+- * Enable the MPIC cell
+- */
+-#define PMAC_FTR_ENABLE_MPIC		PMAC_FTR_DEF(19)
+-
+-/* PMAC_FTR_AACK_DELAY_ENABLE	(NULL, int enable, 0)
+- *
+- * Enable/disable the AACK delay on the northbridge for systems using DFS
+- */
+-#define PMAC_FTR_AACK_DELAY_ENABLE     	PMAC_FTR_DEF(20)
+-
+-/* PMAC_FTR_DEVICE_CAN_WAKE
+- *
+- * Used by video drivers to inform system that they can actually perform
+- * wakeup from sleep
+- */
+-#define PMAC_FTR_DEVICE_CAN_WAKE	PMAC_FTR_DEF(22)
+-
+-
+-/* Don't use those directly, they are for the sake of pmac_setup.c */
+-extern long pmac_do_feature_call(unsigned int selector, ...);
+-extern void pmac_feature_init(void);
+-
+-/* Video suspend tweak */
+-extern void pmac_set_early_video_resume(void (*proc)(void *data), void *data);
+-extern void pmac_call_early_video_resume(void);
+-
+-#define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x))
+-
+-/* The AGP driver registers itself here */
+-extern void pmac_register_agp_pm(struct pci_dev *bridge,
+-				 int (*suspend)(struct pci_dev *bridge),
+-				 int (*resume)(struct pci_dev *bridge));
+-
+-/* Those are meant to be used by video drivers to deal with AGP
+- * suspend resume properly
+- */
+-extern void pmac_suspend_agp_for_card(struct pci_dev *dev);
+-extern void pmac_resume_agp_for_card(struct pci_dev *dev);
+-
+-/* Used by the via-pmu driver for suspend/resume
+- */
+-extern void pmac_tweak_clock_spreading(int enable);
+-
+-/*
+- * The part below is for use by macio_asic.c only, do not rely
+- * on the data structures or constants below in a normal driver
+- *
+- */
+-
+-#define MAX_MACIO_CHIPS		2
+-
+-enum {
+-	macio_unknown = 0,
+-	macio_grand_central,
+-	macio_ohare,
+-	macio_ohareII,
+-	macio_heathrow,
+-	macio_gatwick,
+-	macio_paddington,
+-	macio_keylargo,
+-	macio_pangea,
+-	macio_intrepid,
+-	macio_keylargo2,
+-};
+-
+-struct macio_chip
+-{
+-	struct device_node	*of_node;
+-	int			type;
+-	const char		*name;
+-	int			rev;
+-	volatile u32		__iomem *base;
+-	unsigned long		flags;
+-
+-	/* For use by macio_asic PCI driver */
+-	struct macio_bus	lbus;
+-};
+-
+-extern struct macio_chip macio_chips[MAX_MACIO_CHIPS];
+-
+-#define MACIO_FLAG_SCCA_ON	0x00000001
+-#define MACIO_FLAG_SCCB_ON	0x00000002
+-#define MACIO_FLAG_SCC_LOCKED	0x00000004
+-#define MACIO_FLAG_AIRPORT_ON	0x00000010
+-#define MACIO_FLAG_FW_SUPPORTED	0x00000020
+-
+-extern struct macio_chip* macio_find(struct device_node* child, int type);
+-
+-#define MACIO_FCR32(macio, r)	((macio)->base + ((r) >> 2))
+-#define MACIO_FCR8(macio, r)	(((volatile u8 __iomem *)((macio)->base)) + (r))
+-
+-#define MACIO_IN32(r)		(in_le32(MACIO_FCR32(macio,r)))
+-#define MACIO_OUT32(r,v)	(out_le32(MACIO_FCR32(macio,r), (v)))
+-#define MACIO_BIS(r,v)		(MACIO_OUT32((r), MACIO_IN32(r) | (v)))
+-#define MACIO_BIC(r,v)		(MACIO_OUT32((r), MACIO_IN32(r) & ~(v)))
+-#define MACIO_IN8(r)		(in_8(MACIO_FCR8(macio,r)))
+-#define MACIO_OUT8(r,v)		(out_8(MACIO_FCR8(macio,r), (v)))
+-
+-#endif /* __PPC_ASM_PMAC_FEATURE_H */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/pmac_low_i2c.h b/include/asm-ppc/pmac_low_i2c.h
+deleted file mode 100644
+--- a/include/asm-ppc/pmac_low_i2c.h
++++ /dev/null
+@@ -1,43 +0,0 @@
+-/* 
+- *  include/asm-ppc/pmac_low_i2c.h
+- *
+- *  Copyright (C) 2003 Ben. Herrenschmidt (benh at 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 __PMAC_LOW_I2C_H__
+-#define __PMAC_LOW_I2C_H__
+-
+-/* i2c mode (based on the platform functions format) */
+-enum {
+-	pmac_low_i2c_mode_dumb		= 1,
+-	pmac_low_i2c_mode_std		= 2,
+-	pmac_low_i2c_mode_stdsub	= 3,
+-	pmac_low_i2c_mode_combined	= 4,
+-};
+-
+-/* RW bit in address */
+-enum {
+-	pmac_low_i2c_read		= 0x01,
+-	pmac_low_i2c_write		= 0x00
+-};
+-
+-/* Init, called early during boot */
+-extern void pmac_init_low_i2c(void);
+-
+-/* Locking functions exposed to i2c-keywest */
+-int pmac_low_i2c_lock(struct device_node *np);
+-int pmac_low_i2c_unlock(struct device_node *np);
+-
+-/* Access functions for platform code */
+-int pmac_low_i2c_open(struct device_node *np, int channel);
+-int pmac_low_i2c_close(struct device_node *np);
+-int pmac_low_i2c_setmode(struct device_node *np, int mode);
+-int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len);
+-
+-
+-#endif /* __PMAC_LOW_I2C_H__ */
+diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h
+deleted file mode 100644
+--- a/include/asm-ppc/posix_types.h
++++ /dev/null
+@@ -1,111 +0,0 @@
+-#ifndef _PPC_POSIX_TYPES_H
+-#define _PPC_POSIX_TYPES_H
+-
+-/*
+- * This file is generally used by user-level software, so you need to
+- * be a little careful about namespace pollution etc.  Also, we cannot
+- * assume GCC is being used.
+- */
+-
+-typedef unsigned long	__kernel_ino_t;
+-typedef unsigned int	__kernel_mode_t;
+-typedef unsigned short	__kernel_nlink_t;
+-typedef long		__kernel_off_t;
+-typedef int		__kernel_pid_t;
+-typedef unsigned int	__kernel_uid_t;
+-typedef unsigned int	__kernel_gid_t;
+-typedef unsigned int	__kernel_size_t;
+-typedef int		__kernel_ssize_t;
+-typedef long		__kernel_ptrdiff_t;
+-typedef long		__kernel_time_t;
+-typedef long		__kernel_suseconds_t;
+-typedef long		__kernel_clock_t;
+-typedef int		__kernel_timer_t;
+-typedef int		__kernel_clockid_t;
+-typedef int		__kernel_daddr_t;
+-typedef char *		__kernel_caddr_t;
+-typedef short             __kernel_ipc_pid_t;
+-typedef unsigned short	__kernel_uid16_t;
+-typedef unsigned short	__kernel_gid16_t;
+-typedef unsigned int	__kernel_uid32_t;
+-typedef unsigned int	__kernel_gid32_t;
+-
+-typedef unsigned int	__kernel_old_uid_t;
+-typedef unsigned int	__kernel_old_gid_t;
+-typedef unsigned int	__kernel_old_dev_t;
+-
+-#ifdef __GNUC__
+-typedef long long	__kernel_loff_t;
+-#endif
+-
+-typedef struct {
+-	int	val[2];
+-} __kernel_fsid_t;
+-
+-#ifndef __GNUC__
+-
+-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+-#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+-#define	__FD_ZERO(set)	\
+-  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
+-
+-#else /* __GNUC__ */
+-
+-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
+-    || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+-/* With GNU C, use inline functions instead so args are evaluated only once: */
+-
+-#undef __FD_SET
+-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+-{
+-	unsigned long _tmp = fd / __NFDBITS;
+-	unsigned long _rem = fd % __NFDBITS;
+-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+-}
+-
+-#undef __FD_CLR
+-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+-{
+-	unsigned long _tmp = fd / __NFDBITS;
+-	unsigned long _rem = fd % __NFDBITS;
+-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+-}
+-
+-#undef __FD_ISSET
+-static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
+-{
+-	unsigned long _tmp = fd / __NFDBITS;
+-	unsigned long _rem = fd % __NFDBITS;
+-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+-}
+-
+-/*
+- * This will unroll the loop for the normal constant case (8 ints,
+- * for a 256-bit fd_set)
+- */
+-#undef __FD_ZERO
+-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+-{
+-	unsigned int *tmp = (unsigned int *)p->fds_bits;
+-	int i;
+-
+-	if (__builtin_constant_p(__FDSET_LONGS)) {
+-		switch (__FDSET_LONGS) {
+-			case 8:
+-				tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
+-				tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
+-				return;
+-		}
+-	}
+-	i = __FDSET_LONGS;
+-	while (i) {
+-		i--;
+-		*tmp = 0;
+-		tmp++;
+-	}
+-}
+-
+-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+-#endif /* __GNUC__ */
+-#endif /* _PPC_POSIX_TYPES_H */
+diff --git a/include/asm-ppc/ppc_asm.h b/include/asm-ppc/ppc_asm.h
+deleted file mode 100644
+--- a/include/asm-ppc/ppc_asm.h
++++ /dev/null
+@@ -1,350 +0,0 @@
+-/*
+- * include/asm-ppc/ppc_asm.h
+- *
+- * Definitions used by various bits of low-level assembly code on PowerPC.
+- *
+- * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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>
+-
+-/*
+- * Macros for storing registers into and loading registers from
+- * exception frames.
+- */
+-#define SAVE_GPR(n, base)	stw	n,GPR0+4*(n)(base)
+-#define SAVE_2GPRS(n, base)	SAVE_GPR(n, base); SAVE_GPR(n+1, base)
+-#define SAVE_4GPRS(n, base)	SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
+-#define SAVE_8GPRS(n, base)	SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
+-#define SAVE_10GPRS(n, base)	SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
+-#define REST_GPR(n, base)	lwz	n,GPR0+4*(n)(base)
+-#define REST_2GPRS(n, base)	REST_GPR(n, base); REST_GPR(n+1, base)
+-#define REST_4GPRS(n, base)	REST_2GPRS(n, base); REST_2GPRS(n+2, base)
+-#define REST_8GPRS(n, base)	REST_4GPRS(n, base); REST_4GPRS(n+4, base)
+-#define REST_10GPRS(n, base)	REST_8GPRS(n, base); REST_2GPRS(n+8, base)
+-
+-#define SAVE_NVGPRS(base)	SAVE_GPR(13, base); SAVE_8GPRS(14, base); \
+-				SAVE_10GPRS(22, base)
+-#define REST_NVGPRS(base)	REST_GPR(13, base); REST_8GPRS(14, base); \
+-				REST_10GPRS(22, base)
+-
+-#define SAVE_FPR(n, base)	stfd	n,THREAD_FPR0+8*(n)(base)
+-#define SAVE_2FPRS(n, base)	SAVE_FPR(n, base); SAVE_FPR(n+1, base)
+-#define SAVE_4FPRS(n, base)	SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
+-#define SAVE_8FPRS(n, base)	SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
+-#define SAVE_16FPRS(n, base)	SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
+-#define SAVE_32FPRS(n, base)	SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
+-#define REST_FPR(n, base)	lfd	n,THREAD_FPR0+8*(n)(base)
+-#define REST_2FPRS(n, base)	REST_FPR(n, base); REST_FPR(n+1, base)
+-#define REST_4FPRS(n, base)	REST_2FPRS(n, base); REST_2FPRS(n+2, base)
+-#define REST_8FPRS(n, base)	REST_4FPRS(n, base); REST_4FPRS(n+4, base)
+-#define REST_16FPRS(n, base)	REST_8FPRS(n, base); REST_8FPRS(n+8, base)
+-#define REST_32FPRS(n, base)	REST_16FPRS(n, base); REST_16FPRS(n+16, base)
+-
+-#define SAVE_VR(n,b,base)	li b,THREAD_VR0+(16*(n));  stvx n,b,base
+-#define SAVE_2VR(n,b,base)	SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
+-#define SAVE_4VR(n,b,base)	SAVE_2VR(n,b,base); SAVE_2VR(n+2,b,base)
+-#define SAVE_8VR(n,b,base)	SAVE_4VR(n,b,base); SAVE_4VR(n+4,b,base)
+-#define SAVE_16VR(n,b,base)	SAVE_8VR(n,b,base); SAVE_8VR(n+8,b,base)
+-#define SAVE_32VR(n,b,base)	SAVE_16VR(n,b,base); SAVE_16VR(n+16,b,base)
+-#define REST_VR(n,b,base)	li b,THREAD_VR0+(16*(n)); lvx n,b,base
+-#define REST_2VR(n,b,base)	REST_VR(n,b,base); REST_VR(n+1,b,base)
+-#define REST_4VR(n,b,base)	REST_2VR(n,b,base); REST_2VR(n+2,b,base)
+-#define REST_8VR(n,b,base)	REST_4VR(n,b,base); REST_4VR(n+4,b,base)
+-#define REST_16VR(n,b,base)	REST_8VR(n,b,base); REST_8VR(n+8,b,base)
+-#define REST_32VR(n,b,base)	REST_16VR(n,b,base); REST_16VR(n+16,b,base)
+-
+-#define SAVE_EVR(n,s,base)	evmergehi s,s,n; stw s,THREAD_EVR0+4*(n)(base)
+-#define SAVE_2EVR(n,s,base)	SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base)
+-#define SAVE_4EVR(n,s,base)	SAVE_2EVR(n,s,base); SAVE_2EVR(n+2,s,base)
+-#define SAVE_8EVR(n,s,base)	SAVE_4EVR(n,s,base); SAVE_4EVR(n+4,s,base)
+-#define SAVE_16EVR(n,s,base)	SAVE_8EVR(n,s,base); SAVE_8EVR(n+8,s,base)
+-#define SAVE_32EVR(n,s,base)	SAVE_16EVR(n,s,base); SAVE_16EVR(n+16,s,base)
+-
+-#define REST_EVR(n,s,base)	lwz s,THREAD_EVR0+4*(n)(base); evmergelo n,s,n
+-#define REST_2EVR(n,s,base)	REST_EVR(n,s,base); REST_EVR(n+1,s,base)
+-#define REST_4EVR(n,s,base)	REST_2EVR(n,s,base); REST_2EVR(n+2,s,base)
+-#define REST_8EVR(n,s,base)	REST_4EVR(n,s,base); REST_4EVR(n+4,s,base)
+-#define REST_16EVR(n,s,base)	REST_8EVR(n,s,base); REST_8EVR(n+8,s,base)
+-#define REST_32EVR(n,s,base)	REST_16EVR(n,s,base); REST_16EVR(n+16,s,base)
+-
+-#ifdef CONFIG_PPC601_SYNC_FIX
+-#define SYNC				\
+-BEGIN_FTR_SECTION			\
+-	sync;				\
+-	isync;				\
+-END_FTR_SECTION_IFSET(CPU_FTR_601)
+-#define SYNC_601			\
+-BEGIN_FTR_SECTION			\
+-	sync;				\
+-END_FTR_SECTION_IFSET(CPU_FTR_601)
+-#define ISYNC_601			\
+-BEGIN_FTR_SECTION			\
+-	isync;				\
+-END_FTR_SECTION_IFSET(CPU_FTR_601)
+-#else
+-#define	SYNC
+-#define SYNC_601
+-#define ISYNC_601
+-#endif
+-
+-#ifndef CONFIG_SMP
+-#define TLBSYNC
+-#else /* CONFIG_SMP */
+-/* tlbsync is not implemented on 601 */
+-#define TLBSYNC				\
+-BEGIN_FTR_SECTION			\
+-	tlbsync;			\
+-	sync;				\
+-END_FTR_SECTION_IFCLR(CPU_FTR_601)
+-#endif
+-
+-/*
+- * This instruction is not implemented on the PPC 603 or 601; however, on
+- * the 403GCX and 405GP tlbia IS defined and tlbie is not.
+- * All of these instructions exist in the 8xx, they have magical powers,
+- * and they must be used.
+- */
+-
+-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
+-#define tlbia					\
+-	li	r4,1024;			\
+-	mtctr	r4;				\
+-	lis	r4,KERNELBASE at h;		\
+-0:	tlbie	r4;				\
+-	addi	r4,r4,0x1000;			\
+-	bdnz	0b
+-#endif
+-
+-#ifdef CONFIG_BOOKE
+-#define tophys(rd,rs)				\
+-	addis	rd,rs,0
+-
+-#define tovirt(rd,rs)				\
+-	addis	rd,rs,0
+-
+-#else  /* CONFIG_BOOKE */
+-/*
+- * On APUS (Amiga PowerPC cpu upgrade board), we don't know the
+- * physical base address of RAM at compile time.
+- */
+-#define tophys(rd,rs)				\
+-0:	addis	rd,rs,-KERNELBASE at h;		\
+-	.section ".vtop_fixup","aw";		\
+-	.align  1;				\
+-	.long   0b;				\
+-	.previous
+-
+-#define tovirt(rd,rs)				\
+-0:	addis	rd,rs,KERNELBASE at h;		\
+-	.section ".ptov_fixup","aw";		\
+-	.align  1;				\
+-	.long   0b;				\
+-	.previous
+-#endif  /* CONFIG_BOOKE */
+-
+-/*
+- * On 64-bit cpus, we use the rfid instruction instead of rfi, but
+- * we then have to make sure we preserve the top 32 bits except for
+- * the 64-bit mode bit, which we clear.
+- */
+-#ifdef CONFIG_PPC64BRIDGE
+-#define	FIX_SRR1(ra, rb)	\
+-	mr	rb,ra;		\
+-	mfmsr	ra;		\
+-	clrldi	ra,ra,1;		/* turn off 64-bit mode */ \
+-	rldimi	ra,rb,0,32
+-#define	RFI		.long	0x4c000024	/* rfid instruction */
+-#define MTMSRD(r)	.long	(0x7c000164 + ((r) << 21))	/* mtmsrd */
+-#define CLR_TOP32(r)	rlwinm	(r),(r),0,0,31	/* clear top 32 bits */
+-
+-#else
+-#define FIX_SRR1(ra, rb)
+-#ifndef CONFIG_40x
+-#define	RFI		rfi
+-#else
+-#define RFI		rfi; b .	/* Prevent prefetch past rfi */
+-#endif
+-#define MTMSRD(r)	mtmsr	r
+-#define CLR_TOP32(r)
+-#endif /* CONFIG_PPC64BRIDGE */
+-
+-#define RFCI		.long 0x4c000066	/* rfci instruction */
+-#define RFDI		.long 0x4c00004e	/* rfdi instruction */
+-#define RFMCI		.long 0x4c00004c	/* rfmci instruction */
+-
+-#ifdef CONFIG_IBM405_ERR77
+-#define PPC405_ERR77(ra,rb)	dcbt	ra, rb;
+-#define	PPC405_ERR77_SYNC	sync;
+-#else
+-#define PPC405_ERR77(ra,rb)
+-#define PPC405_ERR77_SYNC
+-#endif
+-
+-#ifdef CONFIG_IBM440EP_ERR42
+-#define PPC440EP_ERR42 isync
+-#else
+-#define PPC440EP_ERR42
+-#endif
+-
+-/* The boring bits... */
+-
+-/* Condition Register Bit Fields */
+-
+-#define	cr0	0
+-#define	cr1	1
+-#define	cr2	2
+-#define	cr3	3
+-#define	cr4	4
+-#define	cr5	5
+-#define	cr6	6
+-#define	cr7	7
+-
+-
+-/* General Purpose Registers (GPRs) */
+-
+-#define	r0	0
+-#define	r1	1
+-#define	r2	2
+-#define	r3	3
+-#define	r4	4
+-#define	r5	5
+-#define	r6	6
+-#define	r7	7
+-#define	r8	8
+-#define	r9	9
+-#define	r10	10
+-#define	r11	11
+-#define	r12	12
+-#define	r13	13
+-#define	r14	14
+-#define	r15	15
+-#define	r16	16
+-#define	r17	17
+-#define	r18	18
+-#define	r19	19
+-#define	r20	20
+-#define	r21	21
+-#define	r22	22
+-#define	r23	23
+-#define	r24	24
+-#define	r25	25
+-#define	r26	26
+-#define	r27	27
+-#define	r28	28
+-#define	r29	29
+-#define	r30	30
+-#define	r31	31
+-
+-
+-/* Floating Point Registers (FPRs) */
+-
+-#define	fr0	0
+-#define	fr1	1
+-#define	fr2	2
+-#define	fr3	3
+-#define	fr4	4
+-#define	fr5	5
+-#define	fr6	6
+-#define	fr7	7
+-#define	fr8	8
+-#define	fr9	9
+-#define	fr10	10
+-#define	fr11	11
+-#define	fr12	12
+-#define	fr13	13
+-#define	fr14	14
+-#define	fr15	15
+-#define	fr16	16
+-#define	fr17	17
+-#define	fr18	18
+-#define	fr19	19
+-#define	fr20	20
+-#define	fr21	21
+-#define	fr22	22
+-#define	fr23	23
+-#define	fr24	24
+-#define	fr25	25
+-#define	fr26	26
+-#define	fr27	27
+-#define	fr28	28
+-#define	fr29	29
+-#define	fr30	30
+-#define	fr31	31
+-
+-#define	vr0	0
+-#define	vr1	1
+-#define	vr2	2
+-#define	vr3	3
+-#define	vr4	4
+-#define	vr5	5
+-#define	vr6	6
+-#define	vr7	7
+-#define	vr8	8
+-#define	vr9	9
+-#define	vr10	10
+-#define	vr11	11
+-#define	vr12	12
+-#define	vr13	13
+-#define	vr14	14
+-#define	vr15	15
+-#define	vr16	16
+-#define	vr17	17
+-#define	vr18	18
+-#define	vr19	19
+-#define	vr20	20
+-#define	vr21	21
+-#define	vr22	22
+-#define	vr23	23
+-#define	vr24	24
+-#define	vr25	25
+-#define	vr26	26
+-#define	vr27	27
+-#define	vr28	28
+-#define	vr29	29
+-#define	vr30	30
+-#define	vr31	31
+-
+-#define	evr0	0
+-#define	evr1	1
+-#define	evr2	2
+-#define	evr3	3
+-#define	evr4	4
+-#define	evr5	5
+-#define	evr6	6
+-#define	evr7	7
+-#define	evr8	8
+-#define	evr9	9
+-#define	evr10	10
+-#define	evr11	11
+-#define	evr12	12
+-#define	evr13	13
+-#define	evr14	14
+-#define	evr15	15
+-#define	evr16	16
+-#define	evr17	17
+-#define	evr18	18
+-#define	evr19	19
+-#define	evr20	20
+-#define	evr21	21
+-#define	evr22	22
+-#define	evr23	23
+-#define	evr24	24
+-#define	evr25	25
+-#define	evr26	26
+-#define	evr27	27
+-#define	evr28	28
+-#define	evr29	29
+-#define	evr30	30
+-#define	evr31	31
+-
+-/* some stab codes */
+-#define N_FUN	36
+-#define N_RSYM	64
+-#define N_SLINE	68
+-#define N_SO	100
+diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
+--- a/include/asm-ppc/ppc_sys.h
++++ b/include/asm-ppc/ppc_sys.h
+@@ -18,7 +18,7 @@
+ #define __ASM_PPC_SYS_H
+ 
+ #include <linux/init.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/types.h>
+ 
+ #if defined(CONFIG_8260)
+diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
+deleted file mode 100644
+--- a/include/asm-ppc/processor.h
++++ /dev/null
+@@ -1,201 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef __ASM_PPC_PROCESSOR_H
+-#define __ASM_PPC_PROCESSOR_H
+-
+-/*
+- * Default implementation of macro that returns current
+- * instruction pointer ("program counter").
+- */
+-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+-
+-#include <linux/config.h>
+-#include <linux/stringify.h>
+-
+-#include <asm/ptrace.h>
+-#include <asm/types.h>
+-#include <asm/mpc8xx.h>
+-#include <asm/reg.h>
+-
+-/* We only need to define a new _MACH_xxx for machines which are part of
+- * a configuration which supports more than one type of different machine.
+- * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac.
+- * -- Tom
+- */
+-#define _MACH_prep	0x00000001
+-#define _MACH_Pmac	0x00000002	/* pmac or pmac clone (non-chrp) */
+-#define _MACH_chrp	0x00000004	/* chrp machine */
+-
+-/* see residual.h for these */
+-#define _PREP_Motorola	0x01	/* motorola prep */
+-#define _PREP_Firm	0x02	/* firmworks prep */
+-#define _PREP_IBM	0x00	/* ibm prep */
+-#define _PREP_Bull	0x03	/* bull prep */
+-
+-/* these are arbitrary */
+-#define _CHRP_Motorola	0x04	/* motorola chrp, the cobra */
+-#define _CHRP_IBM	0x05	/* IBM chrp, the longtrail and longtrail 2 */
+-#define _CHRP_Pegasos	0x06	/* Genesi/bplan's Pegasos and Pegasos2 */
+-
+-#define _GLOBAL(n)\
+-	.stabs __stringify(n:F-1),N_FUN,0,0,n;\
+-	.globl n;\
+-n:
+-
+-/*
+- * this is the minimum allowable io space due to the location
+- * of the io areas on prep (first one at 0x80000000) but
+- * as soon as I get around to remapping the io areas with the BATs
+- * to match the mac we can raise this. -- Cort
+- */
+-#define TASK_SIZE	(CONFIG_TASK_SIZE)
+-
+-#ifndef __ASSEMBLY__
+-#ifdef CONFIG_PPC_MULTIPLATFORM
+-extern int _machine;
+-
+-/* what kind of prep workstation we are */
+-extern int _prep_type;
+-extern int _chrp_type;
+-
+-/*
+- * This is used to identify the board type from a given PReP board
+- * vendor. Board revision is also made available.
+- */
+-extern unsigned char ucSystemType;
+-extern unsigned char ucBoardRev;
+-extern unsigned char ucBoardRevMaj, ucBoardRevMin;
+-#else
+-#define _machine 0
+-#endif /* CONFIG_PPC_MULTIPLATFORM */
+-
+-struct task_struct;
+-void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
+-void release_thread(struct task_struct *);
+-
+-/* Prepare to copy thread state - unlazy all lazy status */
+-extern void prepare_to_copy(struct task_struct *tsk);
+-
+-/*
+- * Create a new kernel thread.
+- */
+-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+-
+-/* Lazy FPU handling on uni-processor */
+-extern struct task_struct *last_task_used_math;
+-extern struct task_struct *last_task_used_altivec;
+-extern struct task_struct *last_task_used_spe;
+-
+-/* This decides where the kernel will search for a free chunk of vm
+- * space during mmap's.
+- */
+-#define TASK_UNMAPPED_BASE	(TASK_SIZE / 8 * 3)
+-
+-typedef struct {
+-	unsigned long seg;
+-} mm_segment_t;
+-
+-struct thread_struct {
+-	unsigned long	ksp;		/* Kernel stack pointer */
+-	struct pt_regs	*regs;		/* Pointer to saved register state */
+-	mm_segment_t	fs;		/* for get_fs() validation */
+-	void		*pgdir;		/* root of page-table tree */
+-	int		fpexc_mode;	/* floating-point exception mode */
+-	signed long	last_syscall;
+-#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
+-	unsigned long	dbcr0;		/* debug control register values */
+-	unsigned long	dbcr1;
+-#endif
+-	double		fpr[32];	/* Complete floating point set */
+-	unsigned long	fpscr_pad;	/* fpr ... fpscr must be contiguous */
+-	unsigned long	fpscr;		/* Floating point status */
+-#ifdef CONFIG_ALTIVEC
+-	/* Complete AltiVec register set */
+-	vector128	vr[32] __attribute((aligned(16)));
+-	/* AltiVec status */
+-	vector128	vscr __attribute((aligned(16)));
+-	unsigned long	vrsave;
+-	int		used_vr;	/* set if process has used altivec */
+-#endif /* CONFIG_ALTIVEC */
+-#ifdef CONFIG_SPE
+-	unsigned long	evr[32];	/* upper 32-bits of SPE regs */
+-	u64		acc;		/* Accumulator */
+-	unsigned long	spefscr;	/* SPE & eFP status */
+-	int		used_spe;	/* set if process has used spe */
+-#endif /* CONFIG_SPE */
+-};
+-
+-#define ARCH_MIN_TASKALIGN 16
+-
+-#define INIT_SP		(sizeof(init_stack) + (unsigned long) &init_stack)
+-
+-#define INIT_THREAD { \
+-	.ksp = INIT_SP, \
+-	.fs = KERNEL_DS, \
+-	.pgdir = swapper_pg_dir, \
+-	.fpexc_mode = MSR_FE0 | MSR_FE1, \
+-}
+-
+-/*
+- * Return saved PC of a blocked thread. For now, this is the "user" PC
+- */
+-#define thread_saved_pc(tsk)	\
+-	((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
+-
+-unsigned long get_wchan(struct task_struct *p);
+-
+-#define KSTK_EIP(tsk)	((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
+-#define KSTK_ESP(tsk)	((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
+-
+-/* Get/set floating-point exception mode */
+-#define GET_FPEXC_CTL(tsk, adr)	get_fpexc_mode((tsk), (adr))
+-#define SET_FPEXC_CTL(tsk, val)	set_fpexc_mode((tsk), (val))
+-
+-extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
+-extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
+-
+-static inline unsigned int __unpack_fe01(unsigned int msr_bits)
+-{
+-	return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
+-}
+-
+-static inline unsigned int __pack_fe01(unsigned int fpmode)
+-{
+-	return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
+-}
+-
+-/* in process.c - for early bootup debug -- Cort */
+-int ll_printk(const char *, ...);
+-void ll_puts(const char *);
+-
+-/* In misc.c */
+-void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
+-
+-#define have_of (_machine == _MACH_chrp || _machine == _MACH_Pmac)
+-
+-#define cpu_relax()	barrier()
+-
+-/*
+- * Prefetch macros.
+- */
+-#define ARCH_HAS_PREFETCH
+-#define ARCH_HAS_PREFETCHW
+-#define ARCH_HAS_SPINLOCK_PREFETCH
+-
+-extern inline void prefetch(const void *x)
+-{
+-	 __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
+-}
+-
+-extern inline void prefetchw(const void *x)
+-{
+-	 __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
+-}
+-
+-#define spin_lock_prefetch(x)	prefetchw(x)
+-
+-extern int emulate_altivec(struct pt_regs *regs);
+-
+-#endif /* !__ASSEMBLY__ */
+-
+-#endif /* __ASM_PPC_PROCESSOR_H */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h
+--- a/include/asm-ppc/ptrace.h
++++ b/include/asm-ppc/ptrace.h
+@@ -57,7 +57,7 @@ extern unsigned long profile_pc(struct p
+ 
+ #define force_successful_syscall_return()   \
+ 	do { \
+-		current_thread_info()->local_flags |= _TIFL_FORCE_NOERROR; \
++		current_thread_info()->syscall_noerror = 1; \
+ 	} while(0)
+ 
+ /*
+diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h
+deleted file mode 100644
+--- a/include/asm-ppc/reg.h
++++ /dev/null
+@@ -1,440 +0,0 @@
+-/*
+- * Contains the definition of registers common to all PowerPC variants.
+- * If a register definition has been changed in a different PowerPC
+- * variant, we will case it in #ifndef XXX ... #endif, and have the
+- * number used in the Programming Environments Manual For 32-Bit
+- * Implementations of the PowerPC Architecture (a.k.a. Green Book) here.
+- */
+-
+-#ifdef __KERNEL__
+-#ifndef __ASM_PPC_REGS_H__
+-#define __ASM_PPC_REGS_H__
+-
+-#include <linux/stringify.h>
+-
+-/* Pickup Book E specific registers. */
+-#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+-#include <asm/reg_booke.h>
+-#endif
+-
+-/* Machine State Register (MSR) Fields */
+-#define MSR_SF		(1<<63)
+-#define MSR_ISF		(1<<61)
+-#define MSR_VEC		(1<<25)		/* Enable AltiVec */
+-#define MSR_POW		(1<<18)		/* Enable Power Management */
+-#define MSR_WE		(1<<18)		/* Wait State Enable */
+-#define MSR_TGPR	(1<<17)		/* TLB Update registers in use */
+-#define MSR_CE		(1<<17)		/* Critical Interrupt Enable */
+-#define MSR_ILE		(1<<16)		/* Interrupt Little Endian */
+-#define MSR_EE		(1<<15)		/* External Interrupt Enable */
+-#define MSR_PR		(1<<14)		/* Problem State / Privilege Level */
+-#define MSR_FP		(1<<13)		/* Floating Point enable */
+-#define MSR_ME		(1<<12)		/* Machine Check Enable */
+-#define MSR_FE0		(1<<11)		/* Floating Exception mode 0 */
+-#define MSR_SE		(1<<10)		/* Single Step */
+-#define MSR_BE		(1<<9)		/* Branch Trace */
+-#define MSR_DE		(1<<9)		/* Debug Exception Enable */
+-#define MSR_FE1		(1<<8)		/* Floating Exception mode 1 */
+-#define MSR_IP		(1<<6)		/* Exception prefix 0x000/0xFFF */
+-#define MSR_IR		(1<<5)		/* Instruction Relocate */
+-#define MSR_DR		(1<<4)		/* Data Relocate */
+-#define MSR_PE		(1<<3)		/* Protection Enable */
+-#define MSR_PX		(1<<2)		/* Protection Exclusive Mode */
+-#define MSR_RI		(1<<1)		/* Recoverable Exception */
+-#define MSR_LE		(1<<0)		/* Little Endian */
+-
+-/* Default MSR for kernel mode. */
+-#ifdef CONFIG_APUS_FAST_EXCEPT
+-#define MSR_KERNEL	(MSR_ME|MSR_IP|MSR_RI|MSR_IR|MSR_DR)
+-#endif
+-
+-#ifndef MSR_KERNEL
+-#define MSR_KERNEL	(MSR_ME|MSR_RI|MSR_IR|MSR_DR)
+-#endif
+-
+-#define MSR_USER	(MSR_KERNEL|MSR_PR|MSR_EE)
+-
+-/* Floating Point Status and Control Register (FPSCR) Fields */
+-#define FPSCR_FX	0x80000000	/* FPU exception summary */
+-#define FPSCR_FEX	0x40000000	/* FPU enabled exception summary */
+-#define FPSCR_VX	0x20000000	/* Invalid operation summary */
+-#define FPSCR_OX	0x10000000	/* Overflow exception summary */
+-#define FPSCR_UX	0x08000000	/* Underflow exception summary */
+-#define FPSCR_ZX	0x04000000	/* Zero-devide exception summary */
+-#define FPSCR_XX	0x02000000	/* Inexact exception summary */
+-#define FPSCR_VXSNAN	0x01000000	/* Invalid op for SNaN */
+-#define FPSCR_VXISI	0x00800000	/* Invalid op for Inv - Inv */
+-#define FPSCR_VXIDI	0x00400000	/* Invalid op for Inv / Inv */
+-#define FPSCR_VXZDZ	0x00200000	/* Invalid op for Zero / Zero */
+-#define FPSCR_VXIMZ	0x00100000	/* Invalid op for Inv * Zero */
+-#define FPSCR_VXVC	0x00080000	/* Invalid op for Compare */
+-#define FPSCR_FR	0x00040000	/* Fraction rounded */
+-#define FPSCR_FI	0x00020000	/* Fraction inexact */
+-#define FPSCR_FPRF	0x0001f000	/* FPU Result Flags */
+-#define FPSCR_FPCC	0x0000f000	/* FPU Condition Codes */
+-#define FPSCR_VXSOFT	0x00000400	/* Invalid op for software request */
+-#define FPSCR_VXSQRT	0x00000200	/* Invalid op for square root */
+-#define FPSCR_VXCVI	0x00000100	/* Invalid op for integer convert */
+-#define FPSCR_VE	0x00000080	/* Invalid op exception enable */
+-#define FPSCR_OE	0x00000040	/* IEEE overflow exception enable */
+-#define FPSCR_UE	0x00000020	/* IEEE underflow exception enable */
+-#define FPSCR_ZE	0x00000010	/* IEEE zero divide exception enable */
+-#define FPSCR_XE	0x00000008	/* FP inexact exception enable */
+-#define FPSCR_NI	0x00000004	/* FPU non IEEE-Mode */
+-#define FPSCR_RN	0x00000003	/* FPU rounding control */
+-
+-/* Special Purpose Registers (SPRNs)*/
+-#define SPRN_CTR	0x009	/* Count Register */
+-#define SPRN_DABR	0x3F5	/* Data Address Breakpoint Register */
+-#define SPRN_DAR	0x013	/* Data Address Register */
+-#define SPRN_TBRL	0x10C	/* Time Base Read Lower Register (user, R/O) */
+-#define SPRN_TBRU	0x10D	/* Time Base Read Upper Register (user, R/O) */
+-#define SPRN_TBWL	0x11C	/* Time Base Lower Register (super, R/W) */
+-#define SPRN_TBWU	0x11D	/* Time Base Upper Register (super, R/W) */
+-#define SPRN_HIOR	0x137	/* 970 Hypervisor interrupt offset */
+-#define SPRN_DBAT0L	0x219	/* Data BAT 0 Lower Register */
+-#define SPRN_DBAT0U	0x218	/* Data BAT 0 Upper Register */
+-#define SPRN_DBAT1L	0x21B	/* Data BAT 1 Lower Register */
+-#define SPRN_DBAT1U	0x21A	/* Data BAT 1 Upper Register */
+-#define SPRN_DBAT2L	0x21D	/* Data BAT 2 Lower Register */
+-#define SPRN_DBAT2U	0x21C	/* Data BAT 2 Upper Register */
+-#define SPRN_DBAT3L	0x21F	/* Data BAT 3 Lower Register */
+-#define SPRN_DBAT3U	0x21E	/* Data BAT 3 Upper Register */
+-#define SPRN_DBAT4L	0x239	/* Data BAT 4 Lower Register */
+-#define SPRN_DBAT4U	0x238	/* Data BAT 4 Upper Register */
+-#define SPRN_DBAT5L	0x23B	/* Data BAT 5 Lower Register */
+-#define SPRN_DBAT5U	0x23A	/* Data BAT 5 Upper Register */
+-#define SPRN_DBAT6L	0x23D	/* Data BAT 6 Lower Register */
+-#define SPRN_DBAT6U	0x23C	/* Data BAT 6 Upper Register */
+-#define SPRN_DBAT7L	0x23F	/* Data BAT 7 Lower Register */
+-#define SPRN_DBAT7U	0x23E	/* Data BAT 7 Upper Register */
+-
+-#define SPRN_DEC	0x016		/* Decrement Register */
+-#define SPRN_DER	0x095		/* Debug Enable Regsiter */
+-#define DER_RSTE	0x40000000	/* Reset Interrupt */
+-#define DER_CHSTPE	0x20000000	/* Check Stop */
+-#define DER_MCIE	0x10000000	/* Machine Check Interrupt */
+-#define DER_EXTIE	0x02000000	/* External Interrupt */
+-#define DER_ALIE	0x01000000	/* Alignment Interrupt */
+-#define DER_PRIE	0x00800000	/* Program Interrupt */
+-#define DER_FPUVIE	0x00400000	/* FP Unavailable Interrupt */
+-#define DER_DECIE	0x00200000	/* Decrementer Interrupt */
+-#define DER_SYSIE	0x00040000	/* System Call Interrupt */
+-#define DER_TRE		0x00020000	/* Trace Interrupt */
+-#define DER_SEIE	0x00004000	/* FP SW Emulation Interrupt */
+-#define DER_ITLBMSE	0x00002000	/* Imp. Spec. Instruction TLB Miss */
+-#define DER_ITLBERE	0x00001000	/* Imp. Spec. Instruction TLB Error */
+-#define DER_DTLBMSE	0x00000800	/* Imp. Spec. Data TLB Miss */
+-#define DER_DTLBERE	0x00000400	/* Imp. Spec. Data TLB Error */
+-#define DER_LBRKE	0x00000008	/* Load/Store Breakpoint Interrupt */
+-#define DER_IBRKE	0x00000004	/* Instruction Breakpoint Interrupt */
+-#define DER_EBRKE	0x00000002	/* External Breakpoint Interrupt */
+-#define DER_DPIE	0x00000001	/* Dev. Port Nonmaskable Request */
+-#define SPRN_DMISS	0x3D0		/* Data TLB Miss Register */
+-#define SPRN_DSISR	0x012	/* Data Storage Interrupt Status Register */
+-#define SPRN_EAR	0x11A		/* External Address Register */
+-#define SPRN_HASH1	0x3D2		/* Primary Hash Address Register */
+-#define SPRN_HASH2	0x3D3		/* Secondary Hash Address Resgister */
+-#define SPRN_HID0	0x3F0		/* Hardware Implementation Register 0 */
+-#define HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
+-#define HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
+-#define HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
+-#define HID0_SBCLK	(1<<27)
+-#define HID0_EICE	(1<<26)
+-#define HID0_TBEN	(1<<26)		/* Timebase enable - 745x */
+-#define HID0_ECLK	(1<<25)
+-#define HID0_PAR	(1<<24)
+-#define HID0_STEN	(1<<24)		/* Software table search enable - 745x */
+-#define HID0_HIGH_BAT	(1<<23)		/* Enable high BATs - 7455 */
+-#define HID0_DOZE	(1<<23)
+-#define HID0_NAP	(1<<22)
+-#define HID0_SLEEP	(1<<21)
+-#define HID0_DPM	(1<<20)
+-#define HID0_BHTCLR	(1<<18)		/* Clear branch history table - 7450 */
+-#define HID0_XAEN	(1<<17)		/* Extended addressing enable - 7450 */
+-#define HID0_NHR	(1<<16)		/* Not hard reset (software bit-7450)*/
+-#define HID0_ICE	(1<<15)		/* Instruction Cache Enable */
+-#define HID0_DCE	(1<<14)		/* Data Cache Enable */
+-#define HID0_ILOCK	(1<<13)		/* Instruction Cache Lock */
+-#define HID0_DLOCK	(1<<12)		/* Data Cache Lock */
+-#define HID0_ICFI	(1<<11)		/* Instr. Cache Flash Invalidate */
+-#define HID0_DCI	(1<<10)		/* Data Cache Invalidate */
+-#define HID0_SPD	(1<<9)		/* Speculative disable */
+-#define HID0_DAPUEN	(1<<8)		/* Debug APU enable */
+-#define HID0_SGE	(1<<7)		/* Store Gathering Enable */
+-#define HID0_SIED	(1<<7)		/* Serial Instr. Execution [Disable] */
+-#define HID0_DFCA	(1<<6)		/* Data Cache Flush Assist */
+-#define HID0_LRSTK	(1<<4)		/* Link register stack - 745x */
+-#define HID0_BTIC	(1<<5)		/* Branch Target Instr Cache Enable */
+-#define HID0_ABE	(1<<3)		/* Address Broadcast Enable */
+-#define HID0_FOLD	(1<<3)		/* Branch Folding enable - 745x */
+-#define HID0_BHTE	(1<<2)		/* Branch History Table Enable */
+-#define HID0_BTCD	(1<<1)		/* Branch target cache disable */
+-#define HID0_NOPDST	(1<<1)		/* No-op dst, dstt, etc. instr. */
+-#define HID0_NOPTI	(1<<0)		/* No-op dcbt and dcbst instr. */
+-
+-#define SPRN_HID1	0x3F1		/* Hardware Implementation Register 1 */
+-#define HID1_EMCP	(1<<31)		/* 7450 Machine Check Pin Enable */
+-#define HID1_DFS	(1<<22)		/* 7447A Dynamic Frequency Scaling */
+-#define HID1_PC0	(1<<16)		/* 7450 PLL_CFG[0] */
+-#define HID1_PC1	(1<<15)		/* 7450 PLL_CFG[1] */
+-#define HID1_PC2	(1<<14)		/* 7450 PLL_CFG[2] */
+-#define HID1_PC3	(1<<13)		/* 7450 PLL_CFG[3] */
+-#define HID1_SYNCBE	(1<<11)		/* 7450 ABE for sync, eieio */
+-#define HID1_ABE	(1<<10)		/* 7450 Address Broadcast Enable */
+-#define HID1_PS		(1<<16)		/* 750FX PLL selection */
+-#define SPRN_HID2	0x3F8		/* Hardware Implementation Register 2 */
+-#define SPRN_IABR	0x3F2	/* Instruction Address Breakpoint Register */
+-#define SPRN_HID4	0x3F4		/* 970 HID4 */
+-#define SPRN_HID5	0x3F6		/* 970 HID5 */
+-#if !defined(SPRN_IAC1) && !defined(SPRN_IAC2)
+-#define SPRN_IAC1	0x3F4		/* Instruction Address Compare 1 */
+-#define SPRN_IAC2	0x3F5		/* Instruction Address Compare 2 */
+-#endif
+-#define SPRN_IBAT0L	0x211		/* Instruction BAT 0 Lower Register */
+-#define SPRN_IBAT0U	0x210		/* Instruction BAT 0 Upper Register */
+-#define SPRN_IBAT1L	0x213		/* Instruction BAT 1 Lower Register */
+-#define SPRN_IBAT1U	0x212		/* Instruction BAT 1 Upper Register */
+-#define SPRN_IBAT2L	0x215		/* Instruction BAT 2 Lower Register */
+-#define SPRN_IBAT2U	0x214		/* Instruction BAT 2 Upper Register */
+-#define SPRN_IBAT3L	0x217		/* Instruction BAT 3 Lower Register */
+-#define SPRN_IBAT3U	0x216		/* Instruction BAT 3 Upper Register */
+-#define SPRN_IBAT4L	0x231		/* Instruction BAT 4 Lower Register */
+-#define SPRN_IBAT4U	0x230		/* Instruction BAT 4 Upper Register */
+-#define SPRN_IBAT5L	0x233		/* Instruction BAT 5 Lower Register */
+-#define SPRN_IBAT5U	0x232		/* Instruction BAT 5 Upper Register */
+-#define SPRN_IBAT6L	0x235		/* Instruction BAT 6 Lower Register */
+-#define SPRN_IBAT6U	0x234		/* Instruction BAT 6 Upper Register */
+-#define SPRN_IBAT7L	0x237		/* Instruction BAT 7 Lower Register */
+-#define SPRN_IBAT7U	0x236		/* Instruction BAT 7 Upper Register */
+-#define SPRN_ICMP	0x3D5		/* Instruction TLB Compare Register */
+-#define SPRN_ICTC	0x3FB	/* Instruction Cache Throttling Control Reg */
+-#define SPRN_ICTRL	0x3F3	/* 1011 7450 icache and interrupt ctrl */
+-#define ICTRL_EICE	0x08000000	/* enable icache parity errs */
+-#define ICTRL_EDC	0x04000000	/* enable dcache parity errs */
+-#define ICTRL_EICP	0x00000100	/* enable icache par. check */
+-#define SPRN_IMISS	0x3D4		/* Instruction TLB Miss Register */
+-#define SPRN_IMMR	0x27E		/* Internal Memory Map Register */
+-#define SPRN_L2CR	0x3F9		/* Level 2 Cache Control Regsiter */
+-#define SPRN_L2CR2	0x3f8
+-#define L2CR_L2E		0x80000000	/* L2 enable */
+-#define L2CR_L2PE		0x40000000	/* L2 parity enable */
+-#define L2CR_L2SIZ_MASK		0x30000000	/* L2 size mask */
+-#define L2CR_L2SIZ_256KB	0x10000000	/* L2 size 256KB */
+-#define L2CR_L2SIZ_512KB	0x20000000	/* L2 size 512KB */
+-#define L2CR_L2SIZ_1MB		0x30000000	/* L2 size 1MB */
+-#define L2CR_L2CLK_MASK		0x0e000000	/* L2 clock mask */
+-#define L2CR_L2CLK_DISABLED	0x00000000	/* L2 clock disabled */
+-#define L2CR_L2CLK_DIV1		0x02000000	/* L2 clock / 1 */
+-#define L2CR_L2CLK_DIV1_5	0x04000000	/* L2 clock / 1.5 */
+-#define L2CR_L2CLK_DIV2		0x08000000	/* L2 clock / 2 */
+-#define L2CR_L2CLK_DIV2_5	0x0a000000	/* L2 clock / 2.5 */
+-#define L2CR_L2CLK_DIV3		0x0c000000	/* L2 clock / 3 */
+-#define L2CR_L2RAM_MASK		0x01800000	/* L2 RAM type mask */
+-#define L2CR_L2RAM_FLOW		0x00000000	/* L2 RAM flow through */
+-#define L2CR_L2RAM_PIPE		0x01000000	/* L2 RAM pipelined */
+-#define L2CR_L2RAM_PIPE_LW	0x01800000	/* L2 RAM pipelined latewr */
+-#define L2CR_L2DO		0x00400000	/* L2 data only */
+-#define L2CR_L2I		0x00200000	/* L2 global invalidate */
+-#define L2CR_L2CTL		0x00100000	/* L2 RAM control */
+-#define L2CR_L2WT		0x00080000	/* L2 write-through */
+-#define L2CR_L2TS		0x00040000	/* L2 test support */
+-#define L2CR_L2OH_MASK		0x00030000	/* L2 output hold mask */
+-#define L2CR_L2OH_0_5		0x00000000	/* L2 output hold 0.5 ns */
+-#define L2CR_L2OH_1_0		0x00010000	/* L2 output hold 1.0 ns */
+-#define L2CR_L2SL		0x00008000	/* L2 DLL slow */
+-#define L2CR_L2DF		0x00004000	/* L2 differential clock */
+-#define L2CR_L2BYP		0x00002000	/* L2 DLL bypass */
+-#define L2CR_L2IP		0x00000001	/* L2 GI in progress */
+-#define L2CR_L2IO_745x		0x00100000	/* L2 instr. only (745x) */
+-#define L2CR_L2DO_745x		0x00010000	/* L2 data only (745x) */
+-#define L2CR_L2REP_745x		0x00001000	/* L2 repl. algorithm (745x) */
+-#define L2CR_L2HWF_745x		0x00000800	/* L2 hardware flush (745x) */
+-#define SPRN_L3CR		0x3FA	/* Level 3 Cache Control Regsiter */
+-#define L3CR_L3E		0x80000000	/* L3 enable */
+-#define L3CR_L3PE		0x40000000	/* L3 data parity enable */
+-#define L3CR_L3APE		0x20000000	/* L3 addr parity enable */
+-#define L3CR_L3SIZ		0x10000000	/* L3 size */
+-#define L3CR_L3CLKEN		0x08000000	/* L3 clock enable */
+-#define L3CR_L3RES		0x04000000	/* L3 special reserved bit */
+-#define L3CR_L3CLKDIV		0x03800000	/* L3 clock divisor */
+-#define L3CR_L3IO		0x00400000	/* L3 instruction only */
+-#define L3CR_L3SPO		0x00040000	/* L3 sample point override */
+-#define L3CR_L3CKSP		0x00030000	/* L3 clock sample point */
+-#define L3CR_L3PSP		0x0000e000	/* L3 P-clock sample point */
+-#define L3CR_L3REP		0x00001000	/* L3 replacement algorithm */
+-#define L3CR_L3HWF		0x00000800	/* L3 hardware flush */
+-#define L3CR_L3I		0x00000400	/* L3 global invalidate */
+-#define L3CR_L3RT		0x00000300	/* L3 SRAM type */
+-#define L3CR_L3NIRCA		0x00000080	/* L3 non-integer ratio clock adj. */
+-#define L3CR_L3DO		0x00000040	/* L3 data only mode */
+-#define L3CR_PMEN		0x00000004	/* L3 private memory enable */
+-#define L3CR_PMSIZ		0x00000001	/* L3 private memory size */
+-#define SPRN_MSSCR0	0x3f6	/* Memory Subsystem Control Register 0 */
+-#define SPRN_MSSSR0	0x3f7	/* Memory Subsystem Status Register 1 */
+-#define SPRN_LDSTCR	0x3f8	/* Load/Store control register */
+-#define SPRN_LDSTDB	0x3f4	/* */
+-#define SPRN_LR		0x008	/* Link Register */
+-#define SPRN_MMCR0	0x3B8	/* Monitor Mode Control Register 0 */
+-#define SPRN_MMCR1	0x3BC	/* Monitor Mode Control Register 1 */
+-#ifndef SPRN_PIR
+-#define SPRN_PIR	0x3FF	/* Processor Identification Register */
+-#endif
+-#define SPRN_PMC1	0x3B9	/* Performance Counter Register 1 */
+-#define SPRN_PMC2	0x3BA	/* Performance Counter Register 2 */
+-#define SPRN_PMC3	0x3BD	/* Performance Counter Register 3 */
+-#define SPRN_PMC4	0x3BE	/* Performance Counter Register 4 */
+-#define SPRN_PTEHI	0x3D5	/* 981 7450 PTE HI word (S/W TLB load) */
+-#define SPRN_PTELO	0x3D6	/* 982 7450 PTE LO word (S/W TLB load) */
+-#define SPRN_PVR	0x11F	/* Processor Version Register */
+-#define SPRN_RPA	0x3D6	/* Required Physical Address Register */
+-#define SPRN_SDA	0x3BF	/* Sampled Data Address Register */
+-#define SPRN_SDR1	0x019	/* MMU Hash Base Register */
+-#define SPRN_SIA	0x3BB	/* Sampled Instruction Address Register */
+-#define SPRN_SPRG0	0x110	/* Special Purpose Register General 0 */
+-#define SPRN_SPRG1	0x111	/* Special Purpose Register General 1 */
+-#define SPRN_SPRG2	0x112	/* Special Purpose Register General 2 */
+-#define SPRN_SPRG3	0x113	/* Special Purpose Register General 3 */
+-#define SPRN_SPRG4	0x114	/* Special Purpose Register General 4 */
+-#define SPRN_SPRG5	0x115	/* Special Purpose Register General 5 */
+-#define SPRN_SPRG6	0x116	/* Special Purpose Register General 6 */
+-#define SPRN_SPRG7	0x117	/* Special Purpose Register General 7 */
+-#define SPRN_SRR0	0x01A	/* Save/Restore Register 0 */
+-#define SPRN_SRR1	0x01B	/* Save/Restore Register 1 */
+-#ifndef SPRN_SVR
+-#define SPRN_SVR	0x11E	/* System Version Register */
+-#endif
+-#define SPRN_THRM1	0x3FC		/* Thermal Management Register 1 */
+-/* these bits were defined in inverted endian sense originally, ugh, confusing */
+-#define THRM1_TIN	(1 << 31)
+-#define THRM1_TIV	(1 << 30)
+-#define THRM1_THRES(x)	((x&0x7f)<<23)
+-#define THRM3_SITV(x)	((x&0x3fff)<<1)
+-#define THRM1_TID	(1<<2)
+-#define THRM1_TIE	(1<<1)
+-#define THRM1_V		(1<<0)
+-#define SPRN_THRM2	0x3FD		/* Thermal Management Register 2 */
+-#define SPRN_THRM3	0x3FE		/* Thermal Management Register 3 */
+-#define THRM3_E		(1<<0)
+-#define SPRN_TLBMISS	0x3D4		/* 980 7450 TLB Miss Register */
+-#define SPRN_UMMCR0	0x3A8	/* User Monitor Mode Control Register 0 */
+-#define SPRN_UMMCR1	0x3AC	/* User Monitor Mode Control Register 0 */
+-#define SPRN_UPMC1	0x3A9	/* User Performance Counter Register 1 */
+-#define SPRN_UPMC2	0x3AA	/* User Performance Counter Register 2 */
+-#define SPRN_UPMC3	0x3AD	/* User Performance Counter Register 3 */
+-#define SPRN_UPMC4	0x3AE	/* User Performance Counter Register 4 */
+-#define SPRN_USIA	0x3AB	/* User Sampled Instruction Address Register */
+-#define SPRN_VRSAVE	0x100	/* Vector Register Save Register */
+-#define SPRN_XER	0x001	/* Fixed Point Exception Register */
+-
+-/* Bit definitions for MMCR0 and PMC1 / PMC2. */
+-#define MMCR0_PMC1_CYCLES	(1 << 7)
+-#define MMCR0_PMC1_ICACHEMISS	(5 << 7)
+-#define MMCR0_PMC1_DTLB		(6 << 7)
+-#define MMCR0_PMC2_DCACHEMISS	0x6
+-#define MMCR0_PMC2_CYCLES	0x1
+-#define MMCR0_PMC2_ITLB		0x7
+-#define MMCR0_PMC2_LOADMISSTIME	0x5
+-#define MMCR0_PMXE	(1 << 26)
+-
+-/* Processor Version Register */
+-
+-/* Processor Version Register (PVR) field extraction */
+-
+-#define PVR_VER(pvr)	(((pvr) >>  16) & 0xFFFF)	/* Version field */
+-#define PVR_REV(pvr)	(((pvr) >>   0) & 0xFFFF)	/* Revison field */
+-
+-/*
+- * IBM has further subdivided the standard PowerPC 16-bit version and
+- * revision subfields of the PVR for the PowerPC 403s into the following:
+- */
+-
+-#define PVR_FAM(pvr)	(((pvr) >> 20) & 0xFFF)	/* Family field */
+-#define PVR_MEM(pvr)	(((pvr) >> 16) & 0xF)	/* Member field */
+-#define PVR_CORE(pvr)	(((pvr) >> 12) & 0xF)	/* Core field */
+-#define PVR_CFG(pvr)	(((pvr) >>  8) & 0xF)	/* Configuration field */
+-#define PVR_MAJ(pvr)	(((pvr) >>  4) & 0xF)	/* Major revision field */
+-#define PVR_MIN(pvr)	(((pvr) >>  0) & 0xF)	/* Minor revision field */
+-
+-/* Processor Version Numbers */
+-
+-#define PVR_403GA	0x00200000
+-#define PVR_403GB	0x00200100
+-#define PVR_403GC	0x00200200
+-#define PVR_403GCX	0x00201400
+-#define PVR_405GP	0x40110000
+-#define PVR_STB03XXX	0x40310000
+-#define PVR_NP405H	0x41410000
+-#define PVR_NP405L	0x41610000
+-#define PVR_601		0x00010000
+-#define PVR_602		0x00050000
+-#define PVR_603		0x00030000
+-#define PVR_603e	0x00060000
+-#define PVR_603ev	0x00070000
+-#define PVR_603r	0x00071000
+-#define PVR_604		0x00040000
+-#define PVR_604e	0x00090000
+-#define PVR_604r	0x000A0000
+-#define PVR_620		0x00140000
+-#define PVR_740		0x00080000
+-#define PVR_750		PVR_740
+-#define PVR_740P	0x10080000
+-#define PVR_750P	PVR_740P
+-#define PVR_7400	0x000C0000
+-#define PVR_7410	0x800C0000
+-#define PVR_7450	0x80000000
+-#define PVR_8540	0x80200000
+-#define PVR_8560	0x80200000
+-/*
+- * For the 8xx processors, all of them report the same PVR family for
+- * the PowerPC core. The various versions of these processors must be
+- * differentiated by the version number in the Communication Processor
+- * Module (CPM).
+- */
+-#define PVR_821		0x00500000
+-#define PVR_823		PVR_821
+-#define PVR_850		PVR_821
+-#define PVR_860		PVR_821
+-#define PVR_8240	0x00810100
+-#define PVR_8245	0x80811014
+-#define PVR_8260	PVR_8240
+-
+-#if 0
+-/* Segment Registers */
+-#define SR0	0
+-#define SR1	1
+-#define SR2	2
+-#define SR3	3
+-#define SR4	4
+-#define SR5	5
+-#define SR6	6
+-#define SR7	7
+-#define SR8	8
+-#define SR9	9
+-#define SR10	10
+-#define SR11	11
+-#define SR12	12
+-#define SR13	13
+-#define SR14	14
+-#define SR15	15
+-#endif
+-
+-/* Macros for setting and retrieving special purpose registers */
+-#ifndef __ASSEMBLY__
+-#define mfmsr()		({unsigned int rval; \
+-			asm volatile("mfmsr %0" : "=r" (rval)); rval;})
+-#define mtmsr(v)	asm volatile("mtmsr %0" : : "r" (v))
+-
+-#define mfspr(rn)	({unsigned int rval; \
+-			asm volatile("mfspr %0," __stringify(rn) \
+-				: "=r" (rval)); rval;})
+-#define mtspr(rn, v)	asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
+-
+-#define mfsrin(v)	({unsigned int rval; \
+-			asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \
+-					rval;})
+-
+-#define proc_trap()	asm volatile("trap")
+-#endif /* __ASSEMBLY__ */
+-#endif /* __ASM_PPC_REGS_H__ */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/rwsem.h b/include/asm-ppc/rwsem.h
+deleted file mode 100644
+--- a/include/asm-ppc/rwsem.h
++++ /dev/null
+@@ -1,172 +0,0 @@
+-/*
+- * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff
+- * in lib/rwsem.c.  Adapted largely from include/asm-i386/rwsem.h
+- * by Paul Mackerras <paulus at samba.org>.
+- */
+-
+-#ifndef _PPC_RWSEM_H
+-#define _PPC_RWSEM_H
+-
+-#ifdef __KERNEL__
+-#include <linux/list.h>
+-#include <linux/spinlock.h>
+-#include <asm/atomic.h>
+-#include <asm/system.h>
+-
+-/*
+- * the semaphore definition
+- */
+-struct rw_semaphore {
+-	/* XXX this should be able to be an atomic_t  -- paulus */
+-	signed long		count;
+-#define RWSEM_UNLOCKED_VALUE		0x00000000
+-#define RWSEM_ACTIVE_BIAS		0x00000001
+-#define RWSEM_ACTIVE_MASK		0x0000ffff
+-#define RWSEM_WAITING_BIAS		(-0x00010000)
+-#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
+-#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+-	spinlock_t		wait_lock;
+-	struct list_head	wait_list;
+-#if RWSEM_DEBUG
+-	int			debug;
+-#endif
+-};
+-
+-/*
+- * initialisation
+- */
+-#if RWSEM_DEBUG
+-#define __RWSEM_DEBUG_INIT      , 0
+-#else
+-#define __RWSEM_DEBUG_INIT	/* */
+-#endif
+-
+-#define __RWSEM_INITIALIZER(name) \
+-	{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+-	  LIST_HEAD_INIT((name).wait_list) \
+-	  __RWSEM_DEBUG_INIT }
+-
+-#define DECLARE_RWSEM(name)		\
+-	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+-
+-extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+-extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+-extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
+-extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
+-
+-static inline void init_rwsem(struct rw_semaphore *sem)
+-{
+-	sem->count = RWSEM_UNLOCKED_VALUE;
+-	spin_lock_init(&sem->wait_lock);
+-	INIT_LIST_HEAD(&sem->wait_list);
+-#if RWSEM_DEBUG
+-	sem->debug = 0;
+-#endif
+-}
+-
+-/*
+- * lock for reading
+- */
+-static inline void __down_read(struct rw_semaphore *sem)
+-{
+-	if (atomic_inc_return((atomic_t *)(&sem->count)) > 0)
+-		smp_wmb();
+-	else
+-		rwsem_down_read_failed(sem);
+-}
+-
+-static inline int __down_read_trylock(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	while ((tmp = sem->count) >= 0) {
+-		if (tmp == cmpxchg(&sem->count, tmp,
+-				   tmp + RWSEM_ACTIVE_READ_BIAS)) {
+-			smp_wmb();
+-			return 1;
+-		}
+-	}
+-	return 0;
+-}
+-
+-/*
+- * lock for writing
+- */
+-static inline void __down_write(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+-				(atomic_t *)(&sem->count));
+-	if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
+-		smp_wmb();
+-	else
+-		rwsem_down_write_failed(sem);
+-}
+-
+-static inline int __down_write_trylock(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+-		      RWSEM_ACTIVE_WRITE_BIAS);
+-	smp_wmb();
+-	return tmp == RWSEM_UNLOCKED_VALUE;
+-}
+-
+-/*
+- * unlock after reading
+- */
+-static inline void __up_read(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	smp_wmb();
+-	tmp = atomic_dec_return((atomic_t *)(&sem->count));
+-	if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
+-		rwsem_wake(sem);
+-}
+-
+-/*
+- * unlock after writing
+- */
+-static inline void __up_write(struct rw_semaphore *sem)
+-{
+-	smp_wmb();
+-	if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+-			      (atomic_t *)(&sem->count)) < 0)
+-		rwsem_wake(sem);
+-}
+-
+-/*
+- * implement atomic add functionality
+- */
+-static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+-{
+-	atomic_add(delta, (atomic_t *)(&sem->count));
+-}
+-
+-/*
+- * downgrade write lock to read lock
+- */
+-static inline void __downgrade_write(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	smp_wmb();
+-	tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
+-	if (tmp < 0)
+-		rwsem_downgrade_wake(sem);
+-}
+-
+-/*
+- * implement exchange and add functionality
+- */
+-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+-{
+-	smp_mb();
+-	return atomic_add_return(delta, (atomic_t *)(&sem->count));
+-}
+-
+-#endif /* __KERNEL__ */
+-#endif /* _PPC_RWSEM_XADD_H */
+diff --git a/include/asm-ppc/scatterlist.h b/include/asm-ppc/scatterlist.h
+deleted file mode 100644
+--- a/include/asm-ppc/scatterlist.h
++++ /dev/null
+@@ -1,25 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef _PPC_SCATTERLIST_H
+-#define _PPC_SCATTERLIST_H
+-
+-#include <asm/dma.h>
+-
+-struct scatterlist {
+-	struct page	*page;
+-	unsigned int	offset;
+-	dma_addr_t	dma_address;
+-	unsigned int	length;
+-};
+-
+-/*
+- * These macros should be used after a pci_map_sg call has been done
+- * to get bus addresses of each of the SG entries and their lengths.
+- * You should only work with the number of sg entries pci_map_sg
+- * returns, or alternatively stop on the first sg_dma_len(sg) which
+- * is 0.
+- */
+-#define sg_dma_address(sg)      ((sg)->dma_address)
+-#define sg_dma_len(sg)          ((sg)->length)
+-
+-#endif /* !(_PPC_SCATTERLIST_H) */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/seccomp.h b/include/asm-ppc/seccomp.h
+deleted file mode 100644
+--- a/include/asm-ppc/seccomp.h
++++ /dev/null
+@@ -1,10 +0,0 @@
+-#ifndef _ASM_SECCOMP_H
+-
+-#include <linux/unistd.h>
+-
+-#define __NR_seccomp_read __NR_read
+-#define __NR_seccomp_write __NR_write
+-#define __NR_seccomp_exit __NR_exit
+-#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+-
+-#endif /* _ASM_SECCOMP_H */
+diff --git a/include/asm-ppc/sections.h b/include/asm-ppc/sections.h
+deleted file mode 100644
+--- a/include/asm-ppc/sections.h
++++ /dev/null
+@@ -1,33 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef _PPC_SECTIONS_H
+-#define _PPC_SECTIONS_H
+-
+-#include <asm-generic/sections.h>
+-
+-#define __pmac __attribute__ ((__section__ (".pmac.text")))
+-#define __pmacdata __attribute__ ((__section__ (".pmac.data")))
+-#define __pmacfunc(__argpmac) \
+-	__argpmac __pmac; \
+-	__argpmac
+-	
+-#define __prep __attribute__ ((__section__ (".prep.text")))
+-#define __prepdata __attribute__ ((__section__ (".prep.data")))
+-#define __prepfunc(__argprep) \
+-	__argprep __prep; \
+-	__argprep
+-
+-#define __chrp __attribute__ ((__section__ (".chrp.text")))
+-#define __chrpdata __attribute__ ((__section__ (".chrp.data")))
+-#define __chrpfunc(__argchrp) \
+-	__argchrp __chrp; \
+-	__argchrp
+-
+-/* this is actually just common chrp/pmac code, not OF code -- Cort */
+-#define __openfirmware __attribute__ ((__section__ (".openfirmware.text")))
+-#define __openfirmwaredata __attribute__ ((__section__ (".openfirmware.data")))
+-#define __openfirmwarefunc(__argopenfirmware) \
+-	__argopenfirmware __openfirmware; \
+-	__argopenfirmware
+-	
+-#endif /* _PPC_SECTIONS_H */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/semaphore.h b/include/asm-ppc/semaphore.h
+deleted file mode 100644
+--- a/include/asm-ppc/semaphore.h
++++ /dev/null
+@@ -1,111 +0,0 @@
+-#ifndef _PPC_SEMAPHORE_H
+-#define _PPC_SEMAPHORE_H
+-
+-/*
+- * Swiped from asm-sparc/semaphore.h and modified
+- * -- Cort (cort at cs.nmt.edu)
+- *
+- * Stole some rw spinlock-based semaphore stuff from asm-alpha/semaphore.h
+- * -- Ani Joshi (ajoshi at unixbox.com)
+- *
+- * Remove spinlock-based RW semaphores; RW semaphore definitions are
+- * now in rwsem.h and we use the generic lib/rwsem.c implementation.
+- * Rework semaphores to use atomic_dec_if_positive.
+- * -- Paul Mackerras (paulus at samba.org)
+- */
+-
+-#ifdef __KERNEL__
+-
+-#include <asm/atomic.h>
+-#include <asm/system.h>
+-#include <linux/wait.h>
+-#include <linux/rwsem.h>
+-
+-struct semaphore {
+-	/*
+-	 * Note that any negative value of count is equivalent to 0,
+-	 * but additionally indicates that some process(es) might be
+-	 * sleeping on `wait'.
+-	 */
+-	atomic_t count;
+-	wait_queue_head_t wait;
+-};
+-
+-#define __SEMAPHORE_INITIALIZER(name, n)				\
+-{									\
+-	.count		= ATOMIC_INIT(n),				\
+-	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+-}
+-
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name, 1)
+-
+-#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
+-	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+-
+-#define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC(name, 1)
+-#define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC(name, 0)
+-
+-static inline void sema_init (struct semaphore *sem, int val)
+-{
+-	atomic_set(&sem->count, val);
+-	init_waitqueue_head(&sem->wait);
+-}
+-
+-static inline void init_MUTEX (struct semaphore *sem)
+-{
+-	sema_init(sem, 1);
+-}
+-
+-static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+-{
+-	sema_init(sem, 0);
+-}
+-
+-extern void __down(struct semaphore * sem);
+-extern int  __down_interruptible(struct semaphore * sem);
+-extern void __up(struct semaphore * sem);
+-
+-extern inline void down(struct semaphore * sem)
+-{
+-	might_sleep();
+-
+-	/*
+-	 * Try to get the semaphore, take the slow path if we fail.
+-	 */
+-	if (atomic_dec_return(&sem->count) < 0)
+-		__down(sem);
+-	smp_wmb();
+-}
+-
+-extern inline int down_interruptible(struct semaphore * sem)
+-{
+-	int ret = 0;
+-
+-	might_sleep();
+-
+-	if (atomic_dec_return(&sem->count) < 0)
+-		ret = __down_interruptible(sem);
+-	smp_wmb();
+-	return ret;
+-}
+-
+-extern inline int down_trylock(struct semaphore * sem)
+-{
+-	int ret;
+-
+-	ret = atomic_dec_if_positive(&sem->count) < 0;
+-	smp_wmb();
+-	return ret;
+-}
+-
+-extern inline void up(struct semaphore * sem)
+-{
+-	smp_wmb();
+-	if (atomic_inc_return(&sem->count) <= 0)
+-		__up(sem);
+-}
+-
+-#endif /* __KERNEL__ */
+-
+-#endif /* !(_PPC_SEMAPHORE_H) */
+diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
+--- a/include/asm-ppc/smp.h
++++ b/include/asm-ppc/smp.h
+@@ -35,6 +35,7 @@ extern cpumask_t cpu_possible_map;
+ extern unsigned long smp_proc_in_lock[];
+ extern volatile unsigned long cpu_callin_map[];
+ extern int smp_tb_synchronized;
++extern struct smp_ops_t *smp_ops;
+ 
+ extern void smp_send_tlb_invalidate(int);
+ extern void smp_send_xmon_break(int cpu);
+@@ -45,32 +46,31 @@ extern int __cpu_disable(void);
+ extern void __cpu_die(unsigned int cpu);
+ extern void cpu_die(void) __attribute__((noreturn));
+ 
+-#define NO_PROC_ID		0xFF            /* No processor magic marker */
+-#define PROC_CHANGE_PENALTY	20
+-
+ #define raw_smp_processor_id()	(current_thread_info()->cpu)
+ 
+ extern int __cpu_up(unsigned int cpu);
+ 
+ extern int smp_hw_index[];
+-#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()])
+-
+-struct klock_info_struct {
+-	unsigned long kernel_flag;
+-	unsigned char akp;
+-};
+-
+-extern struct klock_info_struct klock_info;
+-#define KLOCK_HELD       0xffffffff
+-#define KLOCK_CLEAR      0x0
+-
++#define hard_smp_processor_id() 	(smp_hw_index[smp_processor_id()])
++#define get_hard_smp_processor_id(cpu)	(smp_hw_index[(cpu)])
++#define set_hard_smp_processor_id(cpu, phys)\
++					(smp_hw_index[(cpu)] = (phys))
++ 
+ #endif /* __ASSEMBLY__ */
+ 
+ #else /* !(CONFIG_SMP) */
+ 
+ static inline void cpu_die(void) { }
++#define get_hard_smp_processor_id(cpu) 0
++#define set_hard_smp_processor_id(cpu, phys)
++#define hard_smp_processor_id() 0
+ 
+ #endif /* !(CONFIG_SMP) */
+ 
++#ifndef __ASSEMBLY__
++extern int boot_cpuid;
++extern int boot_cpuid_phys;
++#endif
++
+ #endif /* !(_PPC_SMP_H) */
+ #endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h
+--- a/include/asm-ppc/spinlock.h
++++ b/include/asm-ppc/spinlock.h
+@@ -9,7 +9,7 @@
+  * (the type definitions are in asm/raw_spinlock_types.h)
+  */
+ 
+-#define __raw_spin_is_locked(x)		((x)->lock != 0)
++#define __raw_spin_is_locked(x)		((x)->slock != 0)
+ #define __raw_spin_unlock_wait(lock) \
+ 	do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+ #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+@@ -31,17 +31,17 @@ static inline void __raw_spin_lock(raw_s
+ 	bne-	2b\n\
+ 	isync"
+ 	: "=&r"(tmp)
+-	: "r"(&lock->lock), "r"(1)
++	: "r"(&lock->slock), "r"(1)
+ 	: "cr0", "memory");
+ }
+ 
+ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+ {
+ 	__asm__ __volatile__("eieio	# __raw_spin_unlock": : :"memory");
+-	lock->lock = 0;
++	lock->slock = 0;
+ }
+ 
+-#define __raw_spin_trylock(l) (!test_and_set_bit(0,&(l)->lock))
++#define __raw_spin_trylock(l) (!test_and_set_bit(0,(volatile unsigned long *)(&(l)->slock)))
+ 
+ /*
+  * Read-write spinlocks, allowing multiple readers
+diff --git a/include/asm-ppc/spinlock_types.h b/include/asm-ppc/spinlock_types.h
+deleted file mode 100644
+--- a/include/asm-ppc/spinlock_types.h
++++ /dev/null
+@@ -1,20 +0,0 @@
+-#ifndef __ASM_SPINLOCK_TYPES_H
+-#define __ASM_SPINLOCK_TYPES_H
+-
+-#ifndef __LINUX_SPINLOCK_TYPES_H
+-# error "please don't include this file directly"
+-#endif
+-
+-typedef struct {
+-	volatile unsigned long lock;
+-} raw_spinlock_t;
+-
+-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+-
+-typedef struct {
+-	volatile signed int lock;
+-} raw_rwlock_t;
+-
+-#define __RAW_RW_LOCK_UNLOCKED		{ 0 }
+-
+-#endif
+diff --git a/include/asm-ppc/statfs.h b/include/asm-ppc/statfs.h
+deleted file mode 100644
+--- a/include/asm-ppc/statfs.h
++++ /dev/null
+@@ -1,8 +0,0 @@
+-#ifndef _PPC_STATFS_H
+-#define _PPC_STATFS_H
+-
+-#include <asm-generic/statfs.h>
+-#endif
+-
+-
+-
+diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
+--- a/include/asm-ppc/system.h
++++ b/include/asm-ppc/system.h
+@@ -70,25 +70,47 @@ extern void _set_L3CR(unsigned long);
+ #endif
+ extern void via_cuda_init(void);
+ extern void pmac_nvram_init(void);
++extern void chrp_nvram_init(void);
+ extern void read_rtc_time(void);
+ extern void pmac_find_display(void);
+ extern void giveup_fpu(struct task_struct *);
+ extern void enable_kernel_fp(void);
++extern void flush_fp_to_thread(struct task_struct *);
+ extern void enable_kernel_altivec(void);
+ extern void giveup_altivec(struct task_struct *);
+ extern void load_up_altivec(struct task_struct *);
++extern int emulate_altivec(struct pt_regs *);
+ extern void giveup_spe(struct task_struct *);
+ extern void load_up_spe(struct task_struct *);
+ extern int fix_alignment(struct pt_regs *);
+-extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
+-extern void cvt_df(double *from, float *to, unsigned long *fpscr);
++extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
++extern void cvt_df(double *from, float *to, struct thread_struct *thread);
++
++#ifdef CONFIG_ALTIVEC
++extern void flush_altivec_to_thread(struct task_struct *);
++#else
++static inline void flush_altivec_to_thread(struct task_struct *t)
++{
++}
++#endif
++
++#ifdef CONFIG_SPE
++extern void flush_spe_to_thread(struct task_struct *);
++#else
++static inline void flush_spe_to_thread(struct task_struct *t)
++{
++}
++#endif
++
+ extern int call_rtas(const char *, int, int, unsigned long *, ...);
+ extern void cacheable_memzero(void *p, unsigned int nb);
+ extern void *cacheable_memcpy(void *, const void *, unsigned int);
+ extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
+ extern void bad_page_fault(struct pt_regs *, unsigned long, int);
+-extern void die(const char *, struct pt_regs *, long);
++extern int die(const char *, struct pt_regs *, long);
+ extern void _exception(int, struct pt_regs *, int, unsigned long);
++void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
++
+ #ifdef CONFIG_BOOKE_WDT
+ extern u32 booke_wdt_enabled;
+ extern u32 booke_wdt_period;
+diff --git a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h
+deleted file mode 100644
+--- a/include/asm-ppc/thread_info.h
++++ /dev/null
+@@ -1,107 +0,0 @@
+-/* thread_info.h: PPC low-level thread information
+- * adapted from the i386 version by Paul Mackerras
+- *
+- * Copyright (C) 2002  David Howells (dhowells at redhat.com)
+- * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+- */
+-
+-#ifndef _ASM_THREAD_INFO_H
+-#define _ASM_THREAD_INFO_H
+-
+-#ifdef __KERNEL__
+-#ifndef __ASSEMBLY__
+-/*
+- * low level task data.
+- * If you change this, change the TI_* offsets below to match.
+- */
+-struct thread_info {
+-	struct task_struct	*task;		/* main task structure */
+-	struct exec_domain	*exec_domain;	/* execution domain */
+-	unsigned long		flags;		/* low level flags */
+-	unsigned long		local_flags;	/* non-racy flags */
+-	int			cpu;		/* cpu we're on */
+-	int			preempt_count;	/* 0 => preemptable,
+-						   <0 => BUG */
+-	struct restart_block	restart_block;
+-};
+-
+-#define INIT_THREAD_INFO(tsk)			\
+-{						\
+-	.task =		&tsk,			\
+-	.exec_domain =	&default_exec_domain,	\
+-	.flags =	0,			\
+-	.local_flags =  0,			\
+-	.cpu =		0,			\
+-	.preempt_count = 1,			\
+-	.restart_block = {			\
+-		.fn = do_no_restart_syscall,	\
+-	},					\
+-}
+-
+-#define init_thread_info	(init_thread_union.thread_info)
+-#define init_stack		(init_thread_union.stack)
+-
+-/*
+- * macros/functions for gaining access to the thread information structure
+- */
+-
+-/* how to get the thread information struct from C */
+-static inline struct thread_info *current_thread_info(void)
+-{
+-	struct thread_info *ti;
+-	__asm__("rlwinm %0,1,0,0,18" : "=r"(ti));
+-	return ti;
+-}
+-
+-/* thread information allocation */
+-#define alloc_thread_info(tsk) ((struct thread_info *) \
+-				__get_free_pages(GFP_KERNEL, 1))
+-#define free_thread_info(ti)	free_pages((unsigned long) (ti), 1)
+-#define get_thread_info(ti)	get_task_struct((ti)->task)
+-#define put_thread_info(ti)	put_task_struct((ti)->task)
+-#endif /* __ASSEMBLY__ */
+-
+-/*
+- * Size of kernel stack for each process.
+- */
+-#define THREAD_SIZE		8192	/* 2 pages */
+-
+-#define PREEMPT_ACTIVE		0x10000000
+-
+-/*
+- * thread information flag bit numbers
+- */
+-#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+-#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+-#define TIF_SIGPENDING		2	/* signal pending */
+-#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+-#define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
+-					   TIF_NEED_RESCHED */
+-#define TIF_MEMDIE		5
+-#define TIF_SYSCALL_AUDIT       6       /* syscall auditing active */
+-#define TIF_SECCOMP             7      /* secure computing */
+-
+-/* as above, but as bit values */
+-#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+-#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+-#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+-#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+-#define _TIF_SYSCALL_AUDIT      (1<<TIF_SYSCALL_AUDIT)
+-#define _TIF_SECCOMP            (1<<TIF_SECCOMP)
+-
+-#define _TIF_SYSCALL_T_OR_A     (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
+-
+-/*
+- * Non racy (local) flags bit numbers
+- */
+-#define TIFL_FORCE_NOERROR	0	/* don't return error from current
+-					   syscall even if result < 0 */
+-
+-/* as above, but as bit values */
+-#define _TIFL_FORCE_NOERROR	(1<<TIFL_FORCE_NOERROR)
+-
+-
+-#endif /* __KERNEL__ */
+-
+-#endif /* _ASM_THREAD_INFO_H */
+diff --git a/include/asm-ppc/types.h b/include/asm-ppc/types.h
+deleted file mode 100644
+--- a/include/asm-ppc/types.h
++++ /dev/null
+@@ -1,69 +0,0 @@
+-#ifndef _PPC_TYPES_H
+-#define _PPC_TYPES_H
+-
+-#ifndef __ASSEMBLY__
+-
+-typedef __signed__ char __s8;
+-typedef unsigned char __u8;
+-
+-typedef __signed__ short __s16;
+-typedef unsigned short __u16;
+-
+-typedef __signed__ int __s32;
+-typedef unsigned int __u32;
+-
+-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+-typedef __signed__ long long __s64;
+-typedef unsigned long long __u64;
+-#endif
+-
+-typedef struct {
+-	__u32 u[4];
+-} __vector128;
+-
+-/*
+- * XXX allowed outside of __KERNEL__ for now, until glibc gets
+- * a proper set of asm headers of its own.  -- paulus
+- */
+-typedef unsigned short umode_t;
+-
+-#endif /* __ASSEMBLY__ */
+-
+-#ifdef __KERNEL__
+-/*
+- * These aren't exported outside the kernel to avoid name space clashes
+- */
+-#define BITS_PER_LONG 32
+-
+-#ifndef __ASSEMBLY__
+-
+-#include <linux/config.h>
+-
+-typedef signed char s8;
+-typedef unsigned char u8;
+-
+-typedef signed short s16;
+-typedef unsigned short u16;
+-
+-typedef signed int s32;
+-typedef unsigned int u32;
+-
+-typedef signed long long s64;
+-typedef unsigned long long u64;
+-
+-typedef __vector128 vector128;
+-
+-/* DMA addresses are 32-bits wide */
+-typedef u32 dma_addr_t;
+-typedef u64 dma64_addr_t;
+-
+-#ifdef CONFIG_LBD
+-typedef u64 sector_t;
+-#define HAVE_SECTOR_T
+-#endif
+-
+-#endif /* __ASSEMBLY__ */
+-
+-#endif /* __KERNEL__ */
+-
+-#endif
+diff --git a/include/asm-ppc/uninorth.h b/include/asm-ppc/uninorth.h
+deleted file mode 100644
+--- a/include/asm-ppc/uninorth.h
++++ /dev/null
+@@ -1,229 +0,0 @@
+-/*
+- * uninorth.h: definitions for using the "UniNorth" host bridge chip
+- *             from Apple. This chip is used on "Core99" machines
+- *	       This also includes U2 used on more recent MacRISC2/3
+- *             machines and U3 (G5) 
+- *
+- */
+-#ifdef __KERNEL__
+-#ifndef __ASM_UNINORTH_H__
+-#define __ASM_UNINORTH_H__
+-
+-/*
+- * Uni-N and U3 config space reg. definitions
+- *
+- * (Little endian)
+- */
+-
+-/* Address ranges selection. This one should work with Bandit too */
+-/* Not U3 */
+-#define UNI_N_ADDR_SELECT		0x48
+-#define UNI_N_ADDR_COARSE_MASK		0xffff0000	/* 256Mb regions at *0000000 */
+-#define UNI_N_ADDR_FINE_MASK		0x0000ffff	/*  16Mb regions at f*000000 */
+-
+-/* AGP registers */
+-/* Not U3 */
+-#define UNI_N_CFG_GART_BASE		0x8c
+-#define UNI_N_CFG_AGP_BASE		0x90
+-#define UNI_N_CFG_GART_CTRL		0x94
+-#define UNI_N_CFG_INTERNAL_STATUS	0x98
+-#define UNI_N_CFG_GART_DUMMY_PAGE	0xa4
+-
+-/* UNI_N_CFG_GART_CTRL bits definitions */
+-#define UNI_N_CFG_GART_INVAL		0x00000001
+-#define UNI_N_CFG_GART_ENABLE		0x00000100
+-#define UNI_N_CFG_GART_2xRESET		0x00010000
+-#define UNI_N_CFG_GART_DISSBADET	0x00020000
+-/* The following seems to only be used only on U3 <j.glisse at gmail.com> */
+-#define U3_N_CFG_GART_SYNCMODE		0x00040000
+-#define U3_N_CFG_GART_PERFRD		0x00080000
+-#define U3_N_CFG_GART_B2BGNT		0x00200000
+-#define U3_N_CFG_GART_FASTDDR		0x00400000
+-
+-/* My understanding of UniNorth AGP as of UniNorth rev 1.0x,
+- * revision 1.5 (x4 AGP) may need further changes.
+- *
+- * AGP_BASE register contains the base address of the AGP aperture on
+- * the AGP bus. It doesn't seem to be visible to the CPU as of UniNorth 1.x,
+- * even if decoding of this address range is enabled in the address select
+- * register. Apparently, the only supported bases are 256Mb multiples
+- * (high 4 bits of that register).
+- *
+- * GART_BASE register appear to contain the physical address of the GART
+- * in system memory in the high address bits (page aligned), and the
+- * GART size in the low order bits (number of GART pages)
+- *
+- * The GART format itself is one 32bits word per physical memory page.
+- * This word contains, in little-endian format (!!!), the physical address
+- * of the page in the high bits, and what appears to be an "enable" bit
+- * in the LSB bit (0) that must be set to 1 when the entry is valid.
+- *
+- * Obviously, the GART is not cache coherent and so any change to it
+- * must be flushed to memory (or maybe just make the GART space non
+- * cachable). AGP memory itself doens't seem to be cache coherent neither.
+- *
+- * In order to invalidate the GART (which is probably necessary to inval
+- * the bridge internal TLBs), the following sequence has to be written,
+- * in order, to the GART_CTRL register:
+- *
+- *   UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_INVAL
+- *   UNI_N_CFG_GART_ENABLE
+- *   UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_2xRESET
+- *   UNI_N_CFG_GART_ENABLE
+- *
+- * As far as AGP "features" are concerned, it looks like fast write may
+- * not be supported but this has to be confirmed.
+- *
+- * Turning on AGP seem to require a double invalidate operation, one before
+- * setting the AGP command register, on after.
+- *
+- * Turning off AGP seems to require the following sequence: first wait
+- * for the AGP to be idle by reading the internal status register, then
+- * write in that order to the GART_CTRL register:
+- *
+- *   UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_INVAL
+- *   0
+- *   UNI_N_CFG_GART_2xRESET
+- *   0
+- */
+-
+-/*
+- * Uni-N memory mapped reg. definitions
+- *
+- * Those registers are Big-Endian !!
+- *
+- * Their meaning come from either Darwin and/or from experiments I made with
+- * the bootrom, I'm not sure about their exact meaning yet
+- *
+- */
+-
+-/* Version of the UniNorth chip */
+-#define UNI_N_VERSION			0x0000		/* Known versions: 3,7 and 8 */
+-
+-#define UNI_N_VERSION_107		0x0003		/* 1.0.7 */
+-#define UNI_N_VERSION_10A		0x0007		/* 1.0.10 */
+-#define UNI_N_VERSION_150		0x0011		/* 1.5 */
+-#define UNI_N_VERSION_200		0x0024		/* 2.0 */
+-#define UNI_N_VERSION_PANGEA		0x00C0		/* Integrated U1 + K */
+-#define UNI_N_VERSION_INTREPID		0x00D2		/* Integrated U2 + K */
+-#define UNI_N_VERSION_300		0x0030		/* 3.0 (U3 on G5) */
+-
+-/* This register is used to enable/disable various clocks */
+-#define UNI_N_CLOCK_CNTL		0x0020
+-#define UNI_N_CLOCK_CNTL_PCI		0x00000001	/* PCI2 clock control */
+-#define UNI_N_CLOCK_CNTL_GMAC		0x00000002	/* GMAC clock control */
+-#define UNI_N_CLOCK_CNTL_FW		0x00000004	/* FireWire clock control */
+-#define UNI_N_CLOCK_CNTL_ATA100		0x00000010	/* ATA-100 clock control (U2) */
+-
+-/* Power Management control */
+-#define UNI_N_POWER_MGT			0x0030
+-#define UNI_N_POWER_MGT_NORMAL		0x00
+-#define UNI_N_POWER_MGT_IDLE2		0x01
+-#define UNI_N_POWER_MGT_SLEEP		0x02
+-
+-/* This register is configured by Darwin depending on the UniN
+- * revision
+- */
+-#define UNI_N_ARB_CTRL			0x0040
+-#define UNI_N_ARB_CTRL_QACK_DELAY_SHIFT	15
+-#define UNI_N_ARB_CTRL_QACK_DELAY_MASK	0x0e1f8000
+-#define UNI_N_ARB_CTRL_QACK_DELAY	0x30
+-#define UNI_N_ARB_CTRL_QACK_DELAY105	0x00
+-
+-/* This one _might_ return the CPU number of the CPU reading it;
+- * the bootROM decides whether to boot or to sleep/spinloop depending
+- * on this register beeing 0 or not
+- */
+-#define UNI_N_CPU_NUMBER		0x0050
+-
+-/* This register appear to be read by the bootROM to decide what
+- *  to do on a non-recoverable reset (powerup or wakeup)
+- */
+-#define UNI_N_HWINIT_STATE		0x0070
+-#define UNI_N_HWINIT_STATE_SLEEPING	0x01
+-#define UNI_N_HWINIT_STATE_RUNNING	0x02
+-/* This last bit appear to be used by the bootROM to know the second
+- * CPU has started and will enter it's sleep loop with IP=0
+- */
+-#define UNI_N_HWINIT_STATE_CPU1_FLAG	0x10000000
+-
+-/* This register controls AACK delay, which is set when 2004 iBook/PowerBook
+- * is in low speed mode.
+- */
+-#define UNI_N_AACK_DELAY		0x0100
+-#define UNI_N_AACK_DELAY_ENABLE		0x00000001
+-
+-/* Clock status for Intrepid */
+-#define UNI_N_CLOCK_STOP_STATUS0	0x0150
+-#define UNI_N_CLOCK_STOPPED_EXTAGP	0x00200000
+-#define UNI_N_CLOCK_STOPPED_AGPDEL	0x00100000
+-#define UNI_N_CLOCK_STOPPED_I2S0_45_49	0x00080000
+-#define UNI_N_CLOCK_STOPPED_I2S0_18	0x00040000
+-#define UNI_N_CLOCK_STOPPED_I2S1_45_49	0x00020000
+-#define UNI_N_CLOCK_STOPPED_I2S1_18	0x00010000
+-#define UNI_N_CLOCK_STOPPED_TIMER	0x00008000
+-#define UNI_N_CLOCK_STOPPED_SCC_RTCLK18	0x00004000
+-#define UNI_N_CLOCK_STOPPED_SCC_RTCLK32	0x00002000
+-#define UNI_N_CLOCK_STOPPED_SCC_VIA32	0x00001000
+-#define UNI_N_CLOCK_STOPPED_SCC_SLOT0	0x00000800
+-#define UNI_N_CLOCK_STOPPED_SCC_SLOT1	0x00000400
+-#define UNI_N_CLOCK_STOPPED_SCC_SLOT2	0x00000200
+-#define UNI_N_CLOCK_STOPPED_PCI_FBCLKO	0x00000100
+-#define UNI_N_CLOCK_STOPPED_VEO0	0x00000080
+-#define UNI_N_CLOCK_STOPPED_VEO1	0x00000040
+-#define UNI_N_CLOCK_STOPPED_USB0	0x00000020
+-#define UNI_N_CLOCK_STOPPED_USB1	0x00000010
+-#define UNI_N_CLOCK_STOPPED_USB2	0x00000008
+-#define UNI_N_CLOCK_STOPPED_32		0x00000004
+-#define UNI_N_CLOCK_STOPPED_45		0x00000002
+-#define UNI_N_CLOCK_STOPPED_49		0x00000001
+-
+-#define UNI_N_CLOCK_STOP_STATUS1	0x0160
+-#define UNI_N_CLOCK_STOPPED_PLL4REF	0x00080000
+-#define UNI_N_CLOCK_STOPPED_CPUDEL	0x00040000
+-#define UNI_N_CLOCK_STOPPED_CPU		0x00020000
+-#define UNI_N_CLOCK_STOPPED_BUF_REFCKO	0x00010000
+-#define UNI_N_CLOCK_STOPPED_PCI2	0x00008000
+-#define UNI_N_CLOCK_STOPPED_FW		0x00004000
+-#define UNI_N_CLOCK_STOPPED_GB		0x00002000
+-#define UNI_N_CLOCK_STOPPED_ATA66	0x00001000
+-#define UNI_N_CLOCK_STOPPED_ATA100	0x00000800
+-#define UNI_N_CLOCK_STOPPED_MAX		0x00000400
+-#define UNI_N_CLOCK_STOPPED_PCI1	0x00000200
+-#define UNI_N_CLOCK_STOPPED_KLPCI	0x00000100
+-#define UNI_N_CLOCK_STOPPED_USB0PCI	0x00000080
+-#define UNI_N_CLOCK_STOPPED_USB1PCI	0x00000040
+-#define UNI_N_CLOCK_STOPPED_USB2PCI	0x00000020
+-#define UNI_N_CLOCK_STOPPED_7PCI1	0x00000008
+-#define UNI_N_CLOCK_STOPPED_AGP		0x00000004
+-#define UNI_N_CLOCK_STOPPED_PCI0	0x00000002
+-#define UNI_N_CLOCK_STOPPED_18		0x00000001
+-
+-/* Intrepid registe to OF do-platform-clockspreading */
+-#define UNI_N_CLOCK_SPREADING		0x190
+-
+-/* Uninorth 1.5 rev. has additional perf. monitor registers at 0xf00-0xf50 */
+-
+-
+-/*
+- * U3 specific registers
+- */
+-
+-
+-/* U3 Toggle */
+-#define U3_TOGGLE_REG			0x00e0
+-#define U3_PMC_START_STOP		0x0001
+-#define U3_MPIC_RESET			0x0002
+-#define U3_MPIC_OUTPUT_ENABLE		0x0004
+-
+-/* U3 API PHY Config 1 */
+-#define U3_API_PHY_CONFIG_1		0x23030
+-
+-/* U3 HyperTransport registers */
+-#define U3_HT_CONFIG_BASE      		0x70000
+-#define U3_HT_LINK_COMMAND		0x100
+-#define U3_HT_LINK_CONFIG		0x110
+-#define U3_HT_LINK_FREQ			0x120
+-
+-#endif /* __ASM_UNINORTH_H__ */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
+deleted file mode 100644
+--- a/include/asm-ppc/unistd.h
++++ /dev/null
+@@ -1,493 +0,0 @@
+-#ifndef _ASM_PPC_UNISTD_H_
+-#define _ASM_PPC_UNISTD_H_
+-
+-/*
+- * This file contains the system call numbers.
+- */
+-#define __NR_restart_syscall	  0
+-#define __NR_exit		  1
+-#define __NR_fork		  2
+-#define __NR_read		  3
+-#define __NR_write		  4
+-#define __NR_open		  5
+-#define __NR_close		  6
+-#define __NR_waitpid		  7
+-#define __NR_creat		  8
+-#define __NR_link		  9
+-#define __NR_unlink		 10
+-#define __NR_execve		 11
+-#define __NR_chdir		 12
+-#define __NR_time		 13
+-#define __NR_mknod		 14
+-#define __NR_chmod		 15
+-#define __NR_lchown		 16
+-#define __NR_break		 17
+-#define __NR_oldstat		 18
+-#define __NR_lseek		 19
+-#define __NR_getpid		 20
+-#define __NR_mount		 21
+-#define __NR_umount		 22
+-#define __NR_setuid		 23
+-#define __NR_getuid		 24
+-#define __NR_stime		 25
+-#define __NR_ptrace		 26
+-#define __NR_alarm		 27
+-#define __NR_oldfstat		 28
+-#define __NR_pause		 29
+-#define __NR_utime		 30
+-#define __NR_stty		 31
+-#define __NR_gtty		 32
+-#define __NR_access		 33
+-#define __NR_nice		 34
+-#define __NR_ftime		 35
+-#define __NR_sync		 36
+-#define __NR_kill		 37
+-#define __NR_rename		 38
+-#define __NR_mkdir		 39
+-#define __NR_rmdir		 40
+-#define __NR_dup		 41
+-#define __NR_pipe		 42
+-#define __NR_times		 43
+-#define __NR_prof		 44
+-#define __NR_brk		 45
+-#define __NR_setgid		 46
+-#define __NR_getgid		 47
+-#define __NR_signal		 48
+-#define __NR_geteuid		 49
+-#define __NR_getegid		 50
+-#define __NR_acct		 51
+-#define __NR_umount2		 52
+-#define __NR_lock		 53
+-#define __NR_ioctl		 54
+-#define __NR_fcntl		 55
+-#define __NR_mpx		 56
+-#define __NR_setpgid		 57
+-#define __NR_ulimit		 58
+-#define __NR_oldolduname	 59
+-#define __NR_umask		 60
+-#define __NR_chroot		 61
+-#define __NR_ustat		 62
+-#define __NR_dup2		 63
+-#define __NR_getppid		 64
+-#define __NR_getpgrp		 65
+-#define __NR_setsid		 66
+-#define __NR_sigaction		 67
+-#define __NR_sgetmask		 68
+-#define __NR_ssetmask		 69
+-#define __NR_setreuid		 70
+-#define __NR_setregid		 71
+-#define __NR_sigsuspend		 72
+-#define __NR_sigpending		 73
+-#define __NR_sethostname	 74
+-#define __NR_setrlimit		 75
+-#define __NR_getrlimit		 76
+-#define __NR_getrusage		 77
+-#define __NR_gettimeofday	 78
+-#define __NR_settimeofday	 79
+-#define __NR_getgroups		 80
+-#define __NR_setgroups		 81
+-#define __NR_select		 82
+-#define __NR_symlink		 83
+-#define __NR_oldlstat		 84
+-#define __NR_readlink		 85
+-#define __NR_uselib		 86
+-#define __NR_swapon		 87
+-#define __NR_reboot		 88
+-#define __NR_readdir		 89
+-#define __NR_mmap		 90
+-#define __NR_munmap		 91
+-#define __NR_truncate		 92
+-#define __NR_ftruncate		 93
+-#define __NR_fchmod		 94
+-#define __NR_fchown		 95
+-#define __NR_getpriority	 96
+-#define __NR_setpriority	 97
+-#define __NR_profil		 98
+-#define __NR_statfs		 99
+-#define __NR_fstatfs		100
+-#define __NR_ioperm		101
+-#define __NR_socketcall		102
+-#define __NR_syslog		103
+-#define __NR_setitimer		104
+-#define __NR_getitimer		105
+-#define __NR_stat		106
+-#define __NR_lstat		107
+-#define __NR_fstat		108
+-#define __NR_olduname		109
+-#define __NR_iopl		110
+-#define __NR_vhangup		111
+-#define __NR_idle		112
+-#define __NR_vm86		113
+-#define __NR_wait4		114
+-#define __NR_swapoff		115
+-#define __NR_sysinfo		116
+-#define __NR_ipc		117
+-#define __NR_fsync		118
+-#define __NR_sigreturn		119
+-#define __NR_clone		120
+-#define __NR_setdomainname	121
+-#define __NR_uname		122
+-#define __NR_modify_ldt		123
+-#define __NR_adjtimex		124
+-#define __NR_mprotect		125
+-#define __NR_sigprocmask	126
+-#define __NR_create_module	127
+-#define __NR_init_module	128
+-#define __NR_delete_module	129
+-#define __NR_get_kernel_syms	130
+-#define __NR_quotactl		131
+-#define __NR_getpgid		132
+-#define __NR_fchdir		133
+-#define __NR_bdflush		134
+-#define __NR_sysfs		135
+-#define __NR_personality	136
+-#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+-#define __NR_setfsuid		138
+-#define __NR_setfsgid		139
+-#define __NR__llseek		140
+-#define __NR_getdents		141
+-#define __NR__newselect		142
+-#define __NR_flock		143
+-#define __NR_msync		144
+-#define __NR_readv		145
+-#define __NR_writev		146
+-#define __NR_getsid		147
+-#define __NR_fdatasync		148
+-#define __NR__sysctl		149
+-#define __NR_mlock		150
+-#define __NR_munlock		151
+-#define __NR_mlockall		152
+-#define __NR_munlockall		153
+-#define __NR_sched_setparam		154
+-#define __NR_sched_getparam		155
+-#define __NR_sched_setscheduler		156
+-#define __NR_sched_getscheduler		157
+-#define __NR_sched_yield		158
+-#define __NR_sched_get_priority_max	159
+-#define __NR_sched_get_priority_min	160
+-#define __NR_sched_rr_get_interval	161
+-#define __NR_nanosleep		162
+-#define __NR_mremap		163
+-#define __NR_setresuid		164
+-#define __NR_getresuid		165
+-#define __NR_query_module	166
+-#define __NR_poll		167
+-#define __NR_nfsservctl		168
+-#define __NR_setresgid		169
+-#define __NR_getresgid		170
+-#define __NR_prctl		171
+-#define __NR_rt_sigreturn	172
+-#define __NR_rt_sigaction	173
+-#define __NR_rt_sigprocmask	174
+-#define __NR_rt_sigpending	175
+-#define __NR_rt_sigtimedwait	176
+-#define __NR_rt_sigqueueinfo	177
+-#define __NR_rt_sigsuspend	178
+-#define __NR_pread64		179
+-#define __NR_pwrite64		180
+-#define __NR_chown		181
+-#define __NR_getcwd		182
+-#define __NR_capget		183
+-#define __NR_capset		184
+-#define __NR_sigaltstack	185
+-#define __NR_sendfile		186
+-#define __NR_getpmsg		187	/* some people actually want streams */
+-#define __NR_putpmsg		188	/* some people actually want streams */
+-#define __NR_vfork		189
+-#define __NR_ugetrlimit		190	/* SuS compliant getrlimit */
+-#define __NR_readahead		191
+-#define __NR_mmap2		192
+-#define __NR_truncate64		193
+-#define __NR_ftruncate64	194
+-#define __NR_stat64		195
+-#define __NR_lstat64		196
+-#define __NR_fstat64		197
+-#define __NR_pciconfig_read	198
+-#define __NR_pciconfig_write	199
+-#define __NR_pciconfig_iobase	200
+-#define __NR_multiplexer	201
+-#define __NR_getdents64		202
+-#define __NR_pivot_root		203
+-#define __NR_fcntl64		204
+-#define __NR_madvise		205
+-#define __NR_mincore		206
+-#define __NR_gettid		207
+-#define __NR_tkill		208
+-#define __NR_setxattr		209
+-#define __NR_lsetxattr		210
+-#define __NR_fsetxattr		211
+-#define __NR_getxattr		212
+-#define __NR_lgetxattr		213
+-#define __NR_fgetxattr		214
+-#define __NR_listxattr		215
+-#define __NR_llistxattr		216
+-#define __NR_flistxattr		217
+-#define __NR_removexattr	218
+-#define __NR_lremovexattr	219
+-#define __NR_fremovexattr	220
+-#define __NR_futex		221
+-#define __NR_sched_setaffinity	222
+-#define __NR_sched_getaffinity	223
+-/* 224 currently unused */
+-#define __NR_tuxcall		225
+-#define __NR_sendfile64		226
+-#define __NR_io_setup		227
+-#define __NR_io_destroy		228
+-#define __NR_io_getevents	229
+-#define __NR_io_submit		230
+-#define __NR_io_cancel		231
+-#define __NR_set_tid_address	232
+-#define __NR_fadvise64		233
+-#define __NR_exit_group		234
+-#define __NR_lookup_dcookie	235
+-#define __NR_epoll_create	236
+-#define __NR_epoll_ctl		237
+-#define __NR_epoll_wait		238
+-#define __NR_remap_file_pages	239
+-#define __NR_timer_create	240
+-#define __NR_timer_settime	241
+-#define __NR_timer_gettime	242
+-#define __NR_timer_getoverrun	243
+-#define __NR_timer_delete	244
+-#define __NR_clock_settime	245
+-#define __NR_clock_gettime	246
+-#define __NR_clock_getres	247
+-#define __NR_clock_nanosleep	248
+-#define __NR_swapcontext	249
+-#define __NR_tgkill		250
+-#define __NR_utimes		251
+-#define __NR_statfs64		252
+-#define __NR_fstatfs64		253
+-#define __NR_fadvise64_64	254
+-#define __NR_rtas		255
+-#define __NR_sys_debug_setcontext 256
+-/* Number 257 is reserved for vserver */
+-/* 258 currently unused */
+-/* Number 259 is reserved for new sys_mbind */
+-/* Number 260 is reserved for new sys_get_mempolicy */
+-/* Number 261 is reserved for new sys_set_mempolicy */
+-#define __NR_mq_open		262
+-#define __NR_mq_unlink		263
+-#define __NR_mq_timedsend	264
+-#define __NR_mq_timedreceive	265
+-#define __NR_mq_notify		266
+-#define __NR_mq_getsetattr	267
+-#define __NR_kexec_load		268
+-#define __NR_add_key		269
+-#define __NR_request_key	270
+-#define __NR_keyctl		271
+-#define __NR_waitid		272
+-#define __NR_ioprio_set		273
+-#define __NR_ioprio_get		274
+-#define __NR_inotify_init	275
+-#define __NR_inotify_add_watch	276
+-#define __NR_inotify_rm_watch	277
+-
+-#define __NR_syscalls		278
+-
+-#define __NR(n)	#n
+-
+-/* On powerpc a system call basically clobbers the same registers like a
+- * function call, with the exception of LR (which is needed for the
+- * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
+- * an error return status).
+- */
+-
+-#define __syscall_nr(nr, type, name, args...)				\
+-	unsigned long __sc_ret, __sc_err;				\
+-	{								\
+-		register unsigned long __sc_0  __asm__ ("r0");		\
+-		register unsigned long __sc_3  __asm__ ("r3");		\
+-		register unsigned long __sc_4  __asm__ ("r4");		\
+-		register unsigned long __sc_5  __asm__ ("r5");		\
+-		register unsigned long __sc_6  __asm__ ("r6");		\
+-		register unsigned long __sc_7  __asm__ ("r7");		\
+-		register unsigned long __sc_8  __asm__ ("r8");		\
+-									\
+-		__sc_loadargs_##nr(name, args);				\
+-		__asm__ __volatile__					\
+-			("sc           \n\t"				\
+-			 "mfcr %0      "				\
+-			: "=&r" (__sc_0),				\
+-			  "=&r" (__sc_3),  "=&r" (__sc_4),		\
+-			  "=&r" (__sc_5),  "=&r" (__sc_6),		\
+-			  "=&r" (__sc_7),  "=&r" (__sc_8)		\
+-			: __sc_asm_input_##nr				\
+-			: "cr0", "ctr", "memory",			\
+-			  "r9", "r10","r11", "r12");			\
+-		__sc_ret = __sc_3;					\
+-		__sc_err = __sc_0;					\
+-	}								\
+-	if (__sc_err & 0x10000000)					\
+-	{								\
+-		errno = __sc_ret;					\
+-		__sc_ret = -1;						\
+-	}								\
+-	return (type) __sc_ret
+-
+-#define __sc_loadargs_0(name, dummy...)					\
+-	__sc_0 = __NR_##name
+-#define __sc_loadargs_1(name, arg1)					\
+-	__sc_loadargs_0(name);						\
+-	__sc_3 = (unsigned long) (arg1)
+-#define __sc_loadargs_2(name, arg1, arg2)				\
+-	__sc_loadargs_1(name, arg1);					\
+-	__sc_4 = (unsigned long) (arg2)
+-#define __sc_loadargs_3(name, arg1, arg2, arg3)				\
+-	__sc_loadargs_2(name, arg1, arg2);				\
+-	__sc_5 = (unsigned long) (arg3)
+-#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4)			\
+-	__sc_loadargs_3(name, arg1, arg2, arg3);			\
+-	__sc_6 = (unsigned long) (arg4)
+-#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5)		\
+-	__sc_loadargs_4(name, arg1, arg2, arg3, arg4);			\
+-	__sc_7 = (unsigned long) (arg5)
+-#define __sc_loadargs_6(name, arg1, arg2, arg3, arg4, arg5, arg6)	\
+-	__sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5);		\
+-	__sc_8 = (unsigned long) (arg6)
+-
+-#define __sc_asm_input_0 "0" (__sc_0)
+-#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
+-#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
+-#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
+-#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
+-#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
+-#define __sc_asm_input_6 __sc_asm_input_5, "6" (__sc_8)
+-
+-#define _syscall0(type,name)						\
+-type name(void)								\
+-{									\
+-	__syscall_nr(0, type, name);					\
+-}
+-
+-#define _syscall1(type,name,type1,arg1)					\
+-type name(type1 arg1)							\
+-{									\
+-	__syscall_nr(1, type, name, arg1);				\
+-}
+-
+-#define _syscall2(type,name,type1,arg1,type2,arg2)			\
+-type name(type1 arg1, type2 arg2)					\
+-{									\
+-	__syscall_nr(2, type, name, arg1, arg2);			\
+-}
+-
+-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
+-type name(type1 arg1, type2 arg2, type3 arg3)				\
+-{									\
+-	__syscall_nr(3, type, name, arg1, arg2, arg3);			\
+-}
+-
+-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)		\
+-{									\
+-	__syscall_nr(4, type, name, arg1, arg2, arg3, arg4);		\
+-}
+-
+-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
+-{									\
+-	__syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5);	\
+-}
+-
+-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
+-{									\
+-	__syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
+-}
+-
+-#ifdef __KERNEL__
+-
+-#define __NR__exit __NR_exit
+-#define NR_syscalls	__NR_syscalls
+-
+-#define __ARCH_WANT_IPC_PARSE_VERSION
+-#define __ARCH_WANT_OLD_READDIR
+-#define __ARCH_WANT_OLD_STAT
+-#define __ARCH_WANT_STAT64
+-#define __ARCH_WANT_SYS_ALARM
+-#define __ARCH_WANT_SYS_GETHOSTNAME
+-#define __ARCH_WANT_SYS_PAUSE
+-#define __ARCH_WANT_SYS_SGETMASK
+-#define __ARCH_WANT_SYS_SIGNAL
+-#define __ARCH_WANT_SYS_TIME
+-#define __ARCH_WANT_SYS_UTIME
+-#define __ARCH_WANT_SYS_WAITPID
+-#define __ARCH_WANT_SYS_SOCKETCALL
+-#define __ARCH_WANT_SYS_FADVISE64
+-#define __ARCH_WANT_SYS_GETPGRP
+-#define __ARCH_WANT_SYS_LLSEEK
+-#define __ARCH_WANT_SYS_NICE
+-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+-#define __ARCH_WANT_SYS_OLDUMOUNT
+-#define __ARCH_WANT_SYS_SIGPENDING
+-#define __ARCH_WANT_SYS_SIGPROCMASK
+-#define __ARCH_WANT_SYS_RT_SIGACTION
+-
+-/*
+- * Forking from kernel space will result in the child getting a new,
+- * empty kernel stack area.  Thus the child cannot access automatic
+- * variables set in the parent unless they are in registers, and the
+- * procedure where the fork was done cannot return to its caller in
+- * the child.
+- */
+-
+-#ifdef __KERNEL_SYSCALLS__
+-
+-#include <linux/compiler.h>
+-#include <linux/types.h>
+-
+-/*
+- * System call prototypes.
+- */
+-extern pid_t setsid(void);
+-extern int write(int fd, const char *buf, off_t count);
+-extern int read(int fd, char *buf, off_t count);
+-extern off_t lseek(int fd, off_t offset, int count);
+-extern int dup(int fd);
+-extern int execve(const char *file, char **argv, char **envp);
+-extern int open(const char *file, int flag, int mode);
+-extern int close(int fd);
+-extern pid_t waitpid(pid_t pid, int *wait_stat, int options);
+-
+-unsigned long sys_mmap(unsigned long addr, size_t len,
+-			unsigned long prot, unsigned long flags,
+-			unsigned long fd, off_t offset);
+-unsigned long sys_mmap2(unsigned long addr, size_t len,
+-			unsigned long prot, unsigned long flags,
+-			unsigned long fd, unsigned long pgoff);
+-struct pt_regs;
+-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+-		unsigned long a3, unsigned long a4, unsigned long a5,
+-		struct pt_regs *regs);
+-int sys_clone(unsigned long clone_flags, unsigned long usp,
+-	      int __user *parent_tidp, void __user *child_threadptr,
+-	      int __user *child_tidp, int p6,
+-	      struct pt_regs *regs);
+-int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
+-		struct pt_regs *regs);
+-int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
+-		struct pt_regs *regs);
+-int sys_pipe(int __user *fildes);
+-int sys_ptrace(long request, long pid, long addr, long data);
+-struct sigaction;
+-long sys_rt_sigaction(int sig,
+-		      const struct sigaction __user *act,
+-		      struct sigaction __user *oact,
+-		      size_t sigsetsize);
+-
+-#endif /* __KERNEL_SYSCALLS__ */
+-
+-/*
+- * "Conditional" syscalls
+- *
+- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+- * but it doesn't work on all toolchains, so we just do it by hand
+- */
+-#ifndef cond_syscall
+-#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+-#endif
+-
+-#endif /* __KERNEL__ */
+-
+-#endif /* _ASM_PPC_UNISTD_H_ */
+diff --git a/include/asm-ppc/vga.h b/include/asm-ppc/vga.h
+deleted file mode 100644
+--- a/include/asm-ppc/vga.h
++++ /dev/null
+@@ -1,46 +0,0 @@
+-/*
+- *	Access to VGA videoram
+- *
+- *	(c) 1998 Martin Mares <mj at ucw.cz>
+- */
+-
+-#ifdef __KERNEL__
+-#ifndef _LINUX_ASM_VGA_H_
+-#define _LINUX_ASM_VGA_H_
+-
+-#include <asm/io.h>
+-
+-#include <linux/config.h>
+-
+-#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
+-
+-#define VT_BUF_HAVE_RW
+-/*
+- *  These are only needed for supporting VGA or MDA text mode, which use little
+- *  endian byte ordering.
+- *  In other cases, we can optimize by using native byte ordering and
+- *  <linux/vt_buffer.h> has already done the right job for us.
+- */
+-
+-extern inline void scr_writew(u16 val, volatile u16 *addr)
+-{
+-    st_le16(addr, val);
+-}
+-
+-extern inline u16 scr_readw(volatile const u16 *addr)
+-{
+-    return ld_le16(addr);
+-}
+-
+-#define VT_BUF_HAVE_MEMCPYW
+-#define scr_memcpyw	memcpy
+-
+-#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
+-
+-extern unsigned long vgacon_remap_base;
+-#define VGA_MAP_MEM(x) (x + vgacon_remap_base)
+-#define vga_readb(x) (*(x))
+-#define vga_writeb(x,y) (*(y) = (x))
+-
+-#endif
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc/xmon.h b/include/asm-ppc/xmon.h
+deleted file mode 100644
+--- a/include/asm-ppc/xmon.h
++++ /dev/null
+@@ -1,17 +0,0 @@
+-#ifndef __PPC_XMON_H
+-#define __PPC_XMON_H
+-#ifdef __KERNEL__
+-
+-struct pt_regs;
+-
+-extern void xmon(struct pt_regs *excp);
+-extern void xmon_printf(const char *fmt, ...);
+-extern void xmon_map_scc(void);
+-extern int xmon_bpt(struct pt_regs *regs);
+-extern int xmon_sstep(struct pt_regs *regs);
+-extern int xmon_iabr_match(struct pt_regs *regs);
+-extern int xmon_dabr_match(struct pt_regs *regs);
+-extern void (*xmon_fault_handler)(struct pt_regs *regs);
+-
+-#endif
+-#endif
+diff --git a/include/asm-ppc64/a.out.h b/include/asm-ppc64/a.out.h
+deleted file mode 100644
+--- a/include/asm-ppc64/a.out.h
++++ /dev/null
+@@ -1,39 +0,0 @@
+-#ifndef __PPC64_A_OUT_H__
+-#define __PPC64_A_OUT_H__
+-
+-/*
+- * c 2001 PPC 64 Team, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-struct exec
+-{
+-	unsigned long a_info;	/* Use macros N_MAGIC, etc for access */
+-	unsigned a_text;	/* length of text, in bytes */
+-	unsigned a_data;	/* length of data, in bytes */
+-	unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+-	unsigned a_syms;	/* length of symbol table data in file, in bytes */
+-	unsigned a_entry;	/* start address */
+-	unsigned a_trsize;	/* length of relocation info for text, in bytes */
+-	unsigned a_drsize;	/* length of relocation info for data, in bytes */
+-};
+-
+-#define N_TRSIZE(a)	((a).a_trsize)
+-#define N_DRSIZE(a)	((a).a_drsize)
+-#define N_SYMSIZE(a)	((a).a_syms)
+-
+-#ifdef __KERNEL__
+-
+-#define STACK_TOP_USER64 TASK_SIZE_USER64
+-#define STACK_TOP_USER32 TASK_SIZE_USER32
+-
+-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
+-		   STACK_TOP_USER32 : STACK_TOP_USER64)
+-
+-#endif /* __KERNEL__ */
+-
+-#endif /* __PPC64_A_OUT_H__ */
+diff --git a/include/asm-ppc64/abs_addr.h b/include/asm-ppc64/abs_addr.h
+--- a/include/asm-ppc64/abs_addr.h
++++ b/include/asm-ppc64/abs_addr.h
+@@ -63,4 +63,11 @@ static inline unsigned long phys_to_abs(
+ #define virt_to_abs(va) phys_to_abs(__pa(va))
+ #define abs_to_virt(aa) __va(aa)
+ 
++/*
++ * Converts Virtual Address to Real Address for
++ * Legacy iSeries Hypervisor calls
++ */
++#define iseries_hv_addr(virtaddr)	\
++	(0x8000000000000000 | virt_to_abs(virtaddr))
++
+ #endif /* _ABS_ADDR_H */
+diff --git a/include/asm-ppc64/atomic.h b/include/asm-ppc64/atomic.h
+deleted file mode 100644
+--- a/include/asm-ppc64/atomic.h
++++ /dev/null
+@@ -1,197 +0,0 @@
+-/*
+- * PowerPC64 atomic operations
+- *
+- * Copyright (C) 2001 Paul Mackerras <paulus at au.ibm.com>, IBM
+- * Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, 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.
+- */
+-
+-#ifndef _ASM_PPC64_ATOMIC_H_ 
+-#define _ASM_PPC64_ATOMIC_H_
+-
+-#include <asm/memory.h>
+-
+-typedef struct { volatile int counter; } atomic_t;
+-
+-#define ATOMIC_INIT(i)	{ (i) }
+-
+-#define atomic_read(v)		((v)->counter)
+-#define atomic_set(v,i)		(((v)->counter) = (i))
+-
+-static __inline__ void atomic_add(int a, atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%3		# atomic_add\n\
+-	add	%0,%2,%0\n\
+-	stwcx.	%0,0,%3\n\
+-	bne-	1b"
+-	: "=&r" (t), "=m" (v->counter)
+-	: "r" (a), "r" (&v->counter), "m" (v->counter)
+-	: "cc");
+-}
+-
+-static __inline__ int atomic_add_return(int a, atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-	EIEIO_ON_SMP
+-"1:	lwarx	%0,0,%2		# atomic_add_return\n\
+-	add	%0,%1,%0\n\
+-	stwcx.	%0,0,%2\n\
+-	bne-	1b"
+-	ISYNC_ON_SMP
+-	: "=&r" (t)
+-	: "r" (a), "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-#define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
+-
+-static __inline__ void atomic_sub(int a, atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%3		# atomic_sub\n\
+-	subf	%0,%2,%0\n\
+-	stwcx.	%0,0,%3\n\
+-	bne-	1b"
+-	: "=&r" (t), "=m" (v->counter)
+-	: "r" (a), "r" (&v->counter), "m" (v->counter)
+-	: "cc");
+-}
+-
+-static __inline__ int atomic_sub_return(int a, atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-	EIEIO_ON_SMP
+-"1:	lwarx	%0,0,%2		# atomic_sub_return\n\
+-	subf	%0,%1,%0\n\
+-	stwcx.	%0,0,%2\n\
+-	bne-	1b"
+-	ISYNC_ON_SMP
+-	: "=&r" (t)
+-	: "r" (a), "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-static __inline__ void atomic_inc(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%2		# atomic_inc\n\
+-	addic	%0,%0,1\n\
+-	stwcx.	%0,0,%2\n\
+-	bne-	1b"
+-	: "=&r" (t), "=m" (v->counter)
+-	: "r" (&v->counter), "m" (v->counter)
+-	: "cc");
+-}
+-
+-static __inline__ int atomic_inc_return(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-	EIEIO_ON_SMP
+-"1:	lwarx	%0,0,%1		# atomic_inc_return\n\
+-	addic	%0,%0,1\n\
+-	stwcx.	%0,0,%1\n\
+-	bne-	1b"
+-	ISYNC_ON_SMP
+-	: "=&r" (t)
+-	: "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-/*
+- * atomic_inc_and_test - increment and test
+- * @v: pointer of type atomic_t
+- *
+- * Atomically increments @v by 1
+- * and returns true if the result is zero, or false for all
+- * other cases.
+- */
+-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+-
+-static __inline__ void atomic_dec(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-"1:	lwarx	%0,0,%2		# atomic_dec\n\
+-	addic	%0,%0,-1\n\
+-	stwcx.	%0,0,%2\n\
+-	bne-	1b"
+-	: "=&r" (t), "=m" (v->counter)
+-	: "r" (&v->counter), "m" (v->counter)
+-	: "cc");
+-}
+-
+-static __inline__ int atomic_dec_return(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-	EIEIO_ON_SMP
+-"1:	lwarx	%0,0,%1		# atomic_dec_return\n\
+-	addic	%0,%0,-1\n\
+-	stwcx.	%0,0,%1\n\
+-	bne-	1b"
+-	ISYNC_ON_SMP
+-	: "=&r" (t)
+-	: "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-#define atomic_sub_and_test(a, v)	(atomic_sub_return((a), (v)) == 0)
+-#define atomic_dec_and_test(v)		(atomic_dec_return((v)) == 0)
+-
+-/*
+- * Atomically test *v and decrement if it is greater than 0.
+- * The function returns the old value of *v minus 1.
+- */
+-static __inline__ int atomic_dec_if_positive(atomic_t *v)
+-{
+-	int t;
+-
+-	__asm__ __volatile__(
+-	EIEIO_ON_SMP
+-"1:	lwarx	%0,0,%1		# atomic_dec_if_positive\n\
+-	addic.	%0,%0,-1\n\
+-	blt-	2f\n\
+-	stwcx.	%0,0,%1\n\
+-	bne-	1b"
+-	ISYNC_ON_SMP
+-	"\n\
+-2:"	: "=&r" (t)
+-	: "r" (&v->counter)
+-	: "cc", "memory");
+-
+-	return t;
+-}
+-
+-#define smp_mb__before_atomic_dec()     smp_mb()
+-#define smp_mb__after_atomic_dec()      smp_mb()
+-#define smp_mb__before_atomic_inc()     smp_mb()
+-#define smp_mb__after_atomic_inc()      smp_mb()
+-
+-#endif /* _ASM_PPC64_ATOMIC_H_ */
+diff --git a/include/asm-ppc64/auxvec.h b/include/asm-ppc64/auxvec.h
+deleted file mode 100644
+--- a/include/asm-ppc64/auxvec.h
++++ /dev/null
+@@ -1,19 +0,0 @@
+-#ifndef __PPC64_AUXVEC_H
+-#define __PPC64_AUXVEC_H
+-
+-/*
+- * We need to put in some extra aux table entries to tell glibc what
+- * the cache block size is, so it can use the dcbz instruction safely.
+- */
+-#define AT_DCACHEBSIZE		19
+-#define AT_ICACHEBSIZE		20
+-#define AT_UCACHEBSIZE		21
+-/* A special ignored type value for PPC, for glibc compatibility.  */
+-#define AT_IGNOREPPC		22
+-
+-/* The vDSO location. We have to use the same value as x86 for glibc's
+- * sake :-)
+- */
+-#define AT_SYSINFO_EHDR		33
+-
+-#endif /* __PPC64_AUXVEC_H */
+diff --git a/include/asm-ppc64/bitops.h b/include/asm-ppc64/bitops.h
+--- a/include/asm-ppc64/bitops.h
++++ b/include/asm-ppc64/bitops.h
+@@ -42,7 +42,7 @@
+ 
+ #ifdef __KERNEL__
+ 
+-#include <asm/memory.h>
++#include <asm/synch.h>
+ 
+ /*
+  * clear_bit doesn't imply a memory barrier
+diff --git a/include/asm-ppc64/bootinfo.h b/include/asm-ppc64/bootinfo.h
+deleted file mode 100644
+--- a/include/asm-ppc64/bootinfo.h
++++ /dev/null
+@@ -1,70 +0,0 @@
+-/*
+- * Non-machine dependent bootinfo structure.  Basic idea
+- * borrowed from the m68k.
+- *
+- * Copyright (C) 1999 Cort Dougan <cort at ppc.kernel.org>
+- * Copyright (c) 2001 PPC64 Team, IBM Corp 
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-
+-#ifndef _PPC64_BOOTINFO_H
+-#define _PPC64_BOOTINFO_H
+-
+-#include <asm/types.h>
+-
+-/* We use a u32 for the type of the fields since they're written by
+- * the bootloader which is a 32-bit process and read by the kernel
+- * which is a 64-bit process.  This way they can both agree on the
+- * size of the type.
+- */
+-typedef u32 bi_rec_field;
+-
+-struct bi_record {
+-	bi_rec_field tag;	/* tag ID */
+-	bi_rec_field size;	/* size of record (in bytes) */
+-	bi_rec_field data[0];	/* data */
+-};
+-
+-#define BI_FIRST		0x1010  /* first record - marker */
+-#define BI_LAST			0x1011	/* last record - marker */
+-#define BI_CMD_LINE		0x1012
+-#define BI_BOOTLOADER_ID	0x1013
+-#define BI_INITRD		0x1014
+-#define BI_SYSMAP		0x1015
+-#define BI_MACHTYPE		0x1016
+-
+-static __inline__ struct bi_record * bi_rec_init(unsigned long addr)
+-{
+-	struct bi_record *bi_recs;
+-	bi_recs = (struct bi_record *)_ALIGN(addr, PAGE_SIZE);
+-	bi_recs->size = 0;
+-	return bi_recs;
+-}
+-
+-static __inline__ struct bi_record * bi_rec_alloc(struct bi_record *rec,
+-						  unsigned long args)
+-{
+-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+-	rec->size = sizeof(struct bi_record) + args*sizeof(bi_rec_field);
+-	return rec;
+-}
+-
+-static __inline__ struct bi_record * bi_rec_alloc_bytes(struct bi_record *rec,
+-							unsigned long bytes)
+-{
+-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+-	rec->size = sizeof(struct bi_record) + bytes;
+-	return rec;
+-}
+-
+-static __inline__ struct bi_record * bi_rec_next(struct bi_record *rec)
+-{
+-	return (struct bi_record *)((unsigned long)rec + rec->size);
+-}
+-
+-#endif /* _PPC64_BOOTINFO_H */
+diff --git a/include/asm-ppc64/btext.h b/include/asm-ppc64/btext.h
+--- a/include/asm-ppc64/btext.h
++++ b/include/asm-ppc64/btext.h
+@@ -15,6 +15,7 @@ extern int boot_text_mapped;
+ extern int btext_initialize(struct device_node *np);
+ 
+ extern void map_boot_text(void);
++extern void init_boot_display(void);
+ extern void btext_update_display(unsigned long phys, int width, int height,
+ 				 int depth, int pitch);
+ 
+diff --git a/include/asm-ppc64/bug.h b/include/asm-ppc64/bug.h
+deleted file mode 100644
+--- a/include/asm-ppc64/bug.h
++++ /dev/null
+@@ -1,69 +0,0 @@
+-#ifndef _PPC64_BUG_H
+-#define _PPC64_BUG_H
+-
+-/*
+- * Define an illegal instr to trap on the bug.
+- * We don't use 0 because that marks the end of a function
+- * in the ELF ABI.  That's "Boo Boo" in case you wonder...
+- */
+-#define BUG_OPCODE .long 0x00b00b00  /* For asm */
+-#define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
+-
+-#ifndef __ASSEMBLY__
+-
+-struct bug_entry {
+-	unsigned long	bug_addr;
+-	long		line;
+-	const char	*file;
+-	const char	*function;
+-};
+-
+-struct bug_entry *find_bug(unsigned long bugaddr);
+-
+-/*
+- * If this bit is set in the line number it means that the trap
+- * is for WARN_ON rather than BUG or BUG_ON.
+- */
+-#define BUG_WARNING_TRAP	0x1000000
+-
+-#ifdef CONFIG_BUG
+-
+-#define BUG() do {							 \
+-	__asm__ __volatile__(						 \
+-		"1:	twi 31,0,0\n"					 \
+-		".section __bug_table,\"a\"\n\t"			 \
+-		"	.llong 1b,%0,%1,%2\n"				 \
+-		".previous"						 \
+-		: : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
+-} while (0)
+-
+-#define BUG_ON(x) do {						\
+-	__asm__ __volatile__(					\
+-		"1:	tdnei %0,0\n"				\
+-		".section __bug_table,\"a\"\n\t"		\
+-		"	.llong 1b,%1,%2,%3\n"			\
+-		".previous"					\
+-		: : "r" ((long long)(x)), "i" (__LINE__),	\
+-		    "i" (__FILE__), "i" (__FUNCTION__));	\
+-} while (0)
+-
+-#define WARN_ON(x) do {						\
+-	__asm__ __volatile__(					\
+-		"1:	tdnei %0,0\n"				\
+-		".section __bug_table,\"a\"\n\t"		\
+-		"	.llong 1b,%1,%2,%3\n"			\
+-		".previous"					\
+-		: : "r" ((long long)(x)),			\
+-		    "i" (__LINE__ + BUG_WARNING_TRAP),		\
+-		    "i" (__FILE__), "i" (__FUNCTION__));	\
+-} while (0)
+-
+-#define HAVE_ARCH_BUG
+-#define HAVE_ARCH_BUG_ON
+-#define HAVE_ARCH_WARN_ON
+-#endif
+-#endif
+-
+-#include <asm-generic/bug.h>
+-
+-#endif
+diff --git a/include/asm-ppc64/byteorder.h b/include/asm-ppc64/byteorder.h
+deleted file mode 100644
+--- a/include/asm-ppc64/byteorder.h
++++ /dev/null
+@@ -1,86 +0,0 @@
+-#ifndef _PPC64_BYTEORDER_H
+-#define _PPC64_BYTEORDER_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.
+- */
+-
+-#include <asm/types.h>
+-#include <linux/compiler.h>
+-
+-#ifdef __GNUC__
+-#ifdef __KERNEL__
+-
+-static __inline__ __u16 ld_le16(const volatile __u16 *addr)
+-{
+-	__u16 val;
+-
+-	__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+-	return val;
+-}
+-
+-static __inline__ void st_le16(volatile __u16 *addr, const __u16 val)
+-{
+-	__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+-}
+-
+-static __inline__ __u32 ld_le32(const volatile __u32 *addr)
+-{
+-	__u32 val;
+-
+-	__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+-	return val;
+-}
+-
+-static __inline__ void st_le32(volatile __u32 *addr, const __u32 val)
+-{
+-	__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+-}
+-
+-static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
+-{
+-	__u16 result;
+-
+-	__asm__("rlwimi %0,%1,8,16,23"
+-	    : "=r" (result)
+-	    : "r" (value), "0" (value >> 8));
+-	return result;
+-}
+-
+-static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
+-{
+-	__u32 result;
+-
+-	__asm__("rlwimi %0,%1,24,16,23\n\t"
+-	    "rlwimi %0,%1,8,8,15\n\t"
+-	    "rlwimi %0,%1,24,0,7"
+-	    : "=r" (result)
+-	    : "r" (value), "0" (value >> 24));
+-	return result;
+-}
+-
+-#define __arch__swab16(x) ___arch__swab16(x)
+-#define __arch__swab32(x) ___arch__swab32(x)
+-
+-/* The same, but returns converted value from the location pointer by addr. */
+-#define __arch__swab16p(addr) ld_le16(addr)
+-#define __arch__swab32p(addr) ld_le32(addr)
+-
+-/* The same, but do the conversion in situ, ie. put the value back to addr. */
+-#define __arch__swab16s(addr) st_le16(addr,*addr)
+-#define __arch__swab32s(addr) st_le32(addr,*addr)
+-
+-#endif /* __KERNEL__ */
+-
+-#ifndef __STRICT_ANSI__
+-#define __BYTEORDER_HAS_U64__
+-#endif
+-
+-#endif /* __GNUC__ */
+-
+-#include <linux/byteorder/big_endian.h>
+-
+-#endif /* _PPC64_BYTEORDER_H */
+diff --git a/include/asm-ppc64/checksum.h b/include/asm-ppc64/checksum.h
+deleted file mode 100644
+--- a/include/asm-ppc64/checksum.h
++++ /dev/null
+@@ -1,107 +0,0 @@
+-#ifndef _PPC64_CHECKSUM_H
+-#define _PPC64_CHECKSUM_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 is a version of ip_compute_csum() optimized for IP headers,
+- * which always checksum on 4 octet boundaries.  ihl is the number
+- * of 32-bit words and is always >= 5.
+- */
+-extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
+-
+-/*
+- * computes the checksum of the TCP/UDP pseudo-header
+- * returns a 16-bit checksum, already complemented
+- */
+-extern unsigned short csum_tcpudp_magic(unsigned long saddr,
+-					unsigned long daddr,
+-					unsigned short len,
+-					unsigned short proto,
+-					unsigned int sum);
+-
+-/*
+- * computes the checksum of a memory block at buff, length len,
+- * and adds in "sum" (32-bit)
+- *
+- * returns a 32-bit number suitable for feeding into itself
+- * or csum_tcpudp_magic
+- *
+- * this function must be called with even lengths, except
+- * for the last fragment, which may be odd
+- *
+- * it's best to have buff aligned on a 32-bit boundary
+- */
+-extern unsigned int csum_partial(const unsigned char * buff, int len,
+-				 unsigned int sum);
+-
+-/*
+- * the same as csum_partial, but copies from src to dst while it
+- * checksums
+- */
+-extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
+-					      int len, unsigned int sum,
+-					      int *src_err, int *dst_err);
+-/*
+- * the same as csum_partial, but copies from src to dst while it
+- * checksums.
+- */
+-
+-unsigned int csum_partial_copy_nocheck(const char *src, 
+-				       char *dst, 
+-				       int len, 
+-				       unsigned int sum);
+-
+-/*
+- * turns a 32-bit partial checksum (e.g. from csum_partial) into a
+- * 1's complement 16-bit checksum.
+- */
+-static inline unsigned int csum_fold(unsigned int sum)
+-{
+-	unsigned int tmp;
+-
+-	/* swap the two 16-bit halves of sum */
+-	__asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum));
+-	/* if there is a carry from adding the two 16-bit halves,
+-	   it will carry from the lower half into the upper half,
+-	   giving us the correct sum in the upper half. */
+-	sum = ~(sum + tmp) >> 16;
+-	return sum;
+-}
+-
+-/*
+- * this routine is used for miscellaneous IP-like checksums, mainly
+- * in icmp.c
+- */
+-static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
+-{
+-	return csum_fold(csum_partial(buff, len, 0));
+-}
+-
+-#define csum_partial_copy_from_user(src, dst, len, sum, errp)   \
+-        csum_partial_copy_generic((src), (dst), (len), (sum), (errp), NULL)
+-
+-#define csum_partial_copy_nocheck(src, dst, len, sum)   \
+-        csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
+-
+-static inline u32 csum_tcpudp_nofold(u32 saddr,
+-                                     u32 daddr,
+-                                     unsigned short len,
+-                                     unsigned short proto,
+-                                     unsigned int sum)
+-{
+-	unsigned long s = sum;
+-
+-	s += saddr;
+-	s += daddr;
+-	s += (proto << 16) + len;
+-	s += (s >> 32);
+-	return (u32) s;
+-}
+-
+-#endif
+diff --git a/include/asm-ppc64/cputable.h b/include/asm-ppc64/cputable.h
+deleted file mode 100644
+--- a/include/asm-ppc64/cputable.h
++++ /dev/null
+@@ -1,167 +0,0 @@
+-/*
+- *  include/asm-ppc64/cputable.h
+- *
+- *  Copyright (C) 2001 Ben. Herrenschmidt (benh at kernel.crashing.org)
+- *
+- *  Modifications for ppc64:
+- *      Copyright (C) 2003 Dave Engebretsen <engebret at 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.
+- */
+-
+-#ifndef __ASM_PPC_CPUTABLE_H
+-#define __ASM_PPC_CPUTABLE_H
+-
+-#include <linux/config.h>
+-#include <asm/page.h> /* for ASM_CONST */
+-
+-/* Exposed to userland CPU features - Must match ppc32 definitions */
+-#define PPC_FEATURE_32			0x80000000
+-#define PPC_FEATURE_64			0x40000000
+-#define PPC_FEATURE_601_INSTR		0x20000000
+-#define PPC_FEATURE_HAS_ALTIVEC		0x10000000
+-#define PPC_FEATURE_HAS_FPU		0x08000000
+-#define PPC_FEATURE_HAS_MMU		0x04000000
+-#define PPC_FEATURE_HAS_4xxMAC		0x02000000
+-#define PPC_FEATURE_UNIFIED_CACHE	0x01000000
+-
+-#ifdef __KERNEL__
+-
+-#ifndef __ASSEMBLY__
+-
+-/* This structure can grow, it's real size is used by head.S code
+- * via the mkdefs mechanism.
+- */
+-struct cpu_spec;
+-struct op_ppc64_model;
+-
+-typedef	void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
+-
+-struct cpu_spec {
+-	/* CPU is matched via (PVR & pvr_mask) == pvr_value */
+-	unsigned int	pvr_mask;
+-	unsigned int	pvr_value;
+-
+-	char		*cpu_name;
+-	unsigned long	cpu_features;		/* Kernel features */
+-	unsigned int	cpu_user_features;	/* Userland features */
+-
+-	/* cache line sizes */
+-	unsigned int	icache_bsize;
+-	unsigned int	dcache_bsize;
+-
+-	/* number of performance monitor counters */
+-	unsigned int	num_pmcs;
+-
+-	/* this is called to initialize various CPU bits like L1 cache,
+-	 * BHT, SPD, etc... from head.S before branching to identify_machine
+-	 */
+-	cpu_setup_t	cpu_setup;
+-
+-	/* Used by oprofile userspace to select the right counters */
+-	char		*oprofile_cpu_type;
+-
+-	/* Processor specific oprofile operations */
+-	struct op_ppc64_model *oprofile_model;
+-};
+-
+-extern struct cpu_spec		cpu_specs[];
+-extern struct cpu_spec		*cur_cpu_spec;
+-
+-static inline unsigned long cpu_has_feature(unsigned long feature)
+-{
+-	return cur_cpu_spec->cpu_features & feature;
+-}
+-
+-#endif /* __ASSEMBLY__ */
+-
+-/* CPU kernel features */
+-
+-/* Retain the 32b definitions for the time being - use bottom half of word */
+-#define CPU_FTR_SPLIT_ID_CACHE		ASM_CONST(0x0000000000000001)
+-#define CPU_FTR_L2CR			ASM_CONST(0x0000000000000002)
+-#define CPU_FTR_SPEC7450		ASM_CONST(0x0000000000000004)
+-#define CPU_FTR_ALTIVEC			ASM_CONST(0x0000000000000008)
+-#define CPU_FTR_TAU			ASM_CONST(0x0000000000000010)
+-#define CPU_FTR_CAN_DOZE		ASM_CONST(0x0000000000000020)
+-#define CPU_FTR_USE_TB			ASM_CONST(0x0000000000000040)
+-#define CPU_FTR_604_PERF_MON		ASM_CONST(0x0000000000000080)
+-#define CPU_FTR_601			ASM_CONST(0x0000000000000100)
+-#define CPU_FTR_HPTE_TABLE		ASM_CONST(0x0000000000000200)
+-#define CPU_FTR_CAN_NAP			ASM_CONST(0x0000000000000400)
+-#define CPU_FTR_L3CR			ASM_CONST(0x0000000000000800)
+-#define CPU_FTR_L3_DISABLE_NAP		ASM_CONST(0x0000000000001000)
+-#define CPU_FTR_NAP_DISABLE_L2_PR	ASM_CONST(0x0000000000002000)
+-#define CPU_FTR_DUAL_PLL_750FX		ASM_CONST(0x0000000000004000)
+-
+-/* Add the 64b processor unique features in the top half of the word */
+-#define CPU_FTR_SLB           		ASM_CONST(0x0000000100000000)
+-#define CPU_FTR_16M_PAGE      		ASM_CONST(0x0000000200000000)
+-#define CPU_FTR_TLBIEL         		ASM_CONST(0x0000000400000000)
+-#define CPU_FTR_NOEXECUTE     		ASM_CONST(0x0000000800000000)
+-#define CPU_FTR_NODSISRALIGN  		ASM_CONST(0x0000001000000000)
+-#define CPU_FTR_IABR  			ASM_CONST(0x0000002000000000)
+-#define CPU_FTR_MMCRA  			ASM_CONST(0x0000004000000000)
+-/* unused 				ASM_CONST(0x0000008000000000) */
+-#define CPU_FTR_SMT  			ASM_CONST(0x0000010000000000)
+-#define CPU_FTR_COHERENT_ICACHE  	ASM_CONST(0x0000020000000000)
+-#define CPU_FTR_LOCKLESS_TLBIE		ASM_CONST(0x0000040000000000)
+-#define CPU_FTR_MMCRA_SIHV		ASM_CONST(0x0000080000000000)
+-#define CPU_FTR_CTRL			ASM_CONST(0x0000100000000000)
+-
+-#ifndef __ASSEMBLY__
+-
+-#define COMMON_USER_PPC64	(PPC_FEATURE_32 | PPC_FEATURE_64 | \
+-			         PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_MMU)
+-
+-#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
+-                                 CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
+-                                 CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL)
+-
+-/* iSeries doesn't support large pages */
+-#ifdef CONFIG_PPC_ISERIES
+-#define CPU_FTR_PPCAS_ARCH_V2	(CPU_FTR_PPCAS_ARCH_V2_BASE)
+-#else
+-#define CPU_FTR_PPCAS_ARCH_V2	(CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE)
+-#endif /* CONFIG_PPC_ISERIES */
+-
+-#endif /* __ASSEMBLY */
+-
+-#ifdef __ASSEMBLY__
+-
+-#define BEGIN_FTR_SECTION		98:
+-
+-#define END_FTR_SECTION(msk, val)		\
+-99:						\
+-	.section __ftr_fixup,"a";		\
+-	.align 3;				\
+-	.llong msk;			        \
+-	.llong val;			        \
+-	.llong 98b;			        \
+-	.llong 99b;	 		        \
+-	.previous
+-
+-#else
+-
+-#define BEGIN_FTR_SECTION		"98:\n"
+-#define END_FTR_SECTION(msk, val)		\
+-"99:\n"						\
+-"	.section __ftr_fixup,\"a\";\n"		\
+-"	.align 3;\n"				\
+-"	.llong "#msk";\n"			\
+-"	.llong "#val";\n"			\
+-"	.llong 98b;\n"			        \
+-"	.llong 99b;\n"	 		        \
+-"	.previous\n"
+-
+-#endif /* __ASSEMBLY__ */
+-
+-#define END_FTR_SECTION_IFSET(msk)	END_FTR_SECTION((msk), (msk))
+-#define END_FTR_SECTION_IFCLR(msk)	END_FTR_SECTION((msk), 0)
+-
+-#endif /* __ASM_PPC_CPUTABLE_H */
+-#endif /* __KERNEL__ */
+-
+diff --git a/include/asm-ppc64/dart.h b/include/asm-ppc64/dart.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-ppc64/dart.h
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, 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
++ */
++
++#ifndef _ASM_DART_H
++#define _ASM_DART_H
++
++
++/* physical base of DART registers */
++#define DART_BASE        0xf8033000UL
++
++/* Offset from base to control register */
++#define DARTCNTL   0
++/* Offset from base to exception register */
++#define DARTEXCP   0x10
++/* Offset from base to TLB tag registers */
++#define DARTTAG    0x1000
++
++
++/* Control Register fields */
++
++/* base address of table (pfn) */
++#define DARTCNTL_BASE_MASK    0xfffff
++#define DARTCNTL_BASE_SHIFT   12
++
++#define DARTCNTL_FLUSHTLB     0x400
++#define DARTCNTL_ENABLE       0x200
++
++/* size of table in pages */
++#define DARTCNTL_SIZE_MASK    0x1ff
++#define DARTCNTL_SIZE_SHIFT   0
++
++
++/* DART table fields */
++
++#define DARTMAP_VALID   0x80000000
++#define DARTMAP_RPNMASK 0x00ffffff
++
++
++#define DART_PAGE_SHIFT		12
++#define DART_PAGE_SIZE		(1 << DART_PAGE_SHIFT)
++#define DART_PAGE_FACTOR	(PAGE_SHIFT - DART_PAGE_SHIFT)
++
++
++#endif
+diff --git a/include/asm-ppc64/dbdma.h b/include/asm-ppc64/dbdma.h
+deleted file mode 100644
+--- a/include/asm-ppc64/dbdma.h
++++ /dev/null
+@@ -1,2 +0,0 @@
+-#include <asm-ppc/dbdma.h>
+-
+diff --git a/include/asm-ppc64/dma.h b/include/asm-ppc64/dma.h
+deleted file mode 100644
+--- a/include/asm-ppc64/dma.h
++++ /dev/null
+@@ -1,329 +0,0 @@
+-/* 
+- * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+- * Written by Hennus Bergman, 1992.
+- * High DMA channel support & info by Hannu Savolainen
+- * and John Boyd, Nov. 1992.
+- * Changes for ppc sound by Christoph Nadig
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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_DMA_H
+-#define _ASM_DMA_H
+-
+-#include <linux/config.h>
+-#include <asm/io.h>
+-#include <linux/spinlock.h>
+-#include <asm/system.h>
+-
+-#ifndef MAX_DMA_CHANNELS
+-#define MAX_DMA_CHANNELS	8
+-#endif
+-
+-/* The maximum address that we can perform a DMA transfer to on this platform */
+-/* Doesn't really apply... */
+-#define MAX_DMA_ADDRESS  (~0UL)
+-
+-#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)
+-
+-#define dma_outb	outb
+-#define dma_inb		inb
+-
+-/*
+- * NOTES about DMA transfers:
+- *
+- *  controller 1: channels 0-3, byte operations, ports 00-1F
+- *  controller 2: channels 4-7, word operations, ports C0-DF
+- *
+- *  - ALL registers are 8 bits only, regardless of transfer size
+- *  - channel 4 is not used - cascades 1 into 2.
+- *  - channels 0-3 are byte - addresses/counts are for physical bytes
+- *  - channels 5-7 are word - addresses/counts are for physical words
+- *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+- *  - transfer count loaded to registers is 1 less than actual count
+- *  - controller 2 offsets are all even (2x offsets for controller 1)
+- *  - page registers for 5-7 don't use data bit 0, represent 128K pages
+- *  - page registers for 0-3 use bit 0, represent 64K pages
+- *
+- * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory.  
+- * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing.
+- * Note that addresses loaded into registers must be _physical_ addresses,
+- * not logical addresses (which may differ if paging is active).
+- *
+- *  Address mapping for channels 0-3:
+- *
+- *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
+- *    |  ...  |   |  ... |   |  ... |
+- *    |  ...  |   |  ... |   |  ... |
+- *    |  ...  |   |  ... |   |  ... |
+- *   P7  ...  P0  A7 ... A0  A7 ... A0   
+- * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
+- *
+- *  Address mapping for channels 5-7:
+- *
+- *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
+- *    |  ...  |   \   \   ... \  \  \  ... \  \
+- *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
+- *    |  ...  |     \   \   ... \  \  \  ... \
+- *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0   
+- * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
+- *
+- * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
+- * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
+- * the hardware level, so odd-byte transfers aren't possible).
+- *
+- * Transfer count (_not # bytes_) is limited to 64K, represented as actual
+- * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
+- * and up to 128K bytes may be transferred on channels 5-7 in one operation. 
+- *
+- */
+-
+-/* 8237 DMA controllers */
+-#define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
+-#define IO_DMA2_BASE	0xC0	/* 16 bit master DMA, ch 4(=slave input)..7 */
+-
+-/* DMA controller registers */
+-#define DMA1_CMD_REG		0x08	/* command register (w) */
+-#define DMA1_STAT_REG		0x08	/* status register (r) */
+-#define DMA1_REQ_REG            0x09    /* request register (w) */
+-#define DMA1_MASK_REG		0x0A	/* single-channel mask (w) */
+-#define DMA1_MODE_REG		0x0B	/* mode register (w) */
+-#define DMA1_CLEAR_FF_REG	0x0C	/* clear pointer flip-flop (w) */
+-#define DMA1_TEMP_REG           0x0D    /* Temporary Register (r) */
+-#define DMA1_RESET_REG		0x0D	/* Master Clear (w) */
+-#define DMA1_CLR_MASK_REG       0x0E    /* Clear Mask */
+-#define DMA1_MASK_ALL_REG       0x0F    /* all-channels mask (w) */
+-
+-#define DMA2_CMD_REG		0xD0	/* command register (w) */
+-#define DMA2_STAT_REG		0xD0	/* status register (r) */
+-#define DMA2_REQ_REG            0xD2    /* request register (w) */
+-#define DMA2_MASK_REG		0xD4	/* single-channel mask (w) */
+-#define DMA2_MODE_REG		0xD6	/* mode register (w) */
+-#define DMA2_CLEAR_FF_REG	0xD8	/* clear pointer flip-flop (w) */
+-#define DMA2_TEMP_REG           0xDA    /* Temporary Register (r) */
+-#define DMA2_RESET_REG		0xDA	/* Master Clear (w) */
+-#define DMA2_CLR_MASK_REG       0xDC    /* Clear Mask */
+-#define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
+-
+-#define DMA_ADDR_0              0x00    /* DMA address registers */
+-#define DMA_ADDR_1              0x02
+-#define DMA_ADDR_2              0x04
+-#define DMA_ADDR_3              0x06
+-#define DMA_ADDR_4              0xC0
+-#define DMA_ADDR_5              0xC4
+-#define DMA_ADDR_6              0xC8
+-#define DMA_ADDR_7              0xCC
+-
+-#define DMA_CNT_0               0x01    /* DMA count registers */
+-#define DMA_CNT_1               0x03
+-#define DMA_CNT_2               0x05
+-#define DMA_CNT_3               0x07
+-#define DMA_CNT_4               0xC2
+-#define DMA_CNT_5               0xC6
+-#define DMA_CNT_6               0xCA
+-#define DMA_CNT_7               0xCE
+-
+-#define DMA_LO_PAGE_0              0x87    /* DMA page registers */
+-#define DMA_LO_PAGE_1              0x83
+-#define DMA_LO_PAGE_2              0x81
+-#define DMA_LO_PAGE_3              0x82
+-#define DMA_LO_PAGE_5              0x8B
+-#define DMA_LO_PAGE_6              0x89
+-#define DMA_LO_PAGE_7              0x8A
+-
+-#define DMA_HI_PAGE_0              0x487    /* DMA page registers */
+-#define DMA_HI_PAGE_1              0x483
+-#define DMA_HI_PAGE_2              0x481
+-#define DMA_HI_PAGE_3              0x482
+-#define DMA_HI_PAGE_5              0x48B
+-#define DMA_HI_PAGE_6              0x489
+-#define DMA_HI_PAGE_7              0x48A
+-
+-#define DMA1_EXT_REG               0x40B
+-#define DMA2_EXT_REG               0x4D6
+-
+-#define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
+-#define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
+-#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
+-
+-#define DMA_AUTOINIT   	 0x10
+-
+-extern spinlock_t  dma_spin_lock;
+-
+-static __inline__ unsigned long claim_dma_lock(void)
+-{
+-	unsigned long flags;
+-	spin_lock_irqsave(&dma_spin_lock, flags);
+-	return flags;
+-}
+-
+-static __inline__ void release_dma_lock(unsigned long flags)
+-{
+-	spin_unlock_irqrestore(&dma_spin_lock, flags);
+-}
+-
+-/* enable/disable a specific DMA channel */
+-static __inline__ void enable_dma(unsigned int dmanr)
+-{
+-	unsigned char ucDmaCmd=0x00;
+-
+-	if (dmanr != 4)
+-	{
+-		dma_outb(0, DMA2_MASK_REG);  /* This may not be enabled */
+-		dma_outb(ucDmaCmd, DMA2_CMD_REG);  /* Enable group */
+-	}
+-	if (dmanr<=3)
+-	{
+-		dma_outb(dmanr,  DMA1_MASK_REG);
+-		dma_outb(ucDmaCmd, DMA1_CMD_REG);  /* Enable group */
+-	} else
+-	{
+-		dma_outb(dmanr & 3,  DMA2_MASK_REG);
+-	}
+-}
+-
+-static __inline__ void disable_dma(unsigned int dmanr)
+-{
+-	if (dmanr<=3)
+-		dma_outb(dmanr | 4,  DMA1_MASK_REG);
+-	else
+-		dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
+-}
+-
+-/* Clear the 'DMA Pointer Flip Flop'.
+- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+- * Use this once to initialize the FF to a known state.
+- * After that, keep track of it. :-)
+- * --- In order to do that, the DMA routines below should ---
+- * --- only be used while interrupts are disabled! ---
+- */
+-static __inline__ void clear_dma_ff(unsigned int dmanr)
+-{
+-	if (dmanr<=3)
+-		dma_outb(0,  DMA1_CLEAR_FF_REG);
+-	else
+-		dma_outb(0,  DMA2_CLEAR_FF_REG);
+-}
+-
+-/* set mode (above) for a specific DMA channel */
+-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+-{
+-	if (dmanr<=3)
+-		dma_outb(mode | dmanr,  DMA1_MODE_REG);
+-	else
+-		dma_outb(mode | (dmanr&3),  DMA2_MODE_REG);
+-}
+-
+-/* Set only the page register bits of the transfer address.
+- * This is used for successive transfers when we know the contents of
+- * the lower 16 bits of the DMA current address register, but a 64k boundary
+- * may have been crossed.
+- */
+-static __inline__ void set_dma_page(unsigned int dmanr, int pagenr)
+-{
+-	switch(dmanr) {
+-		case 0:
+-			dma_outb(pagenr, DMA_LO_PAGE_0);
+-                        dma_outb(pagenr>>8, DMA_HI_PAGE_0);
+-			break;
+-		case 1:
+-			dma_outb(pagenr, DMA_LO_PAGE_1);
+-                        dma_outb(pagenr>>8, DMA_HI_PAGE_1);
+-			break;
+-		case 2:
+-			dma_outb(pagenr, DMA_LO_PAGE_2);
+-			dma_outb(pagenr>>8, DMA_HI_PAGE_2); 
+-			break;
+-		case 3:
+-			dma_outb(pagenr, DMA_LO_PAGE_3);
+-			dma_outb(pagenr>>8, DMA_HI_PAGE_3); 
+-			break;
+-	        case 5:
+-		        dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5);
+-                        dma_outb(pagenr>>8, DMA_HI_PAGE_5);
+-			break;
+-		case 6:
+-		        dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6);
+-			dma_outb(pagenr>>8, DMA_HI_PAGE_6);
+-			break;
+-		case 7:
+-		        dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7);
+-			dma_outb(pagenr>>8, DMA_HI_PAGE_7);
+-		  break;
+-	}
+-}
+-
+-
+-/* Set transfer address & page bits for specific DMA channel.
+- * Assumes dma flipflop is clear.
+- */
+-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys)
+-{
+-	if (dmanr <= 3)  {
+-	    dma_outb( phys & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+-            dma_outb( (phys>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+-	}  else  {
+-	    dma_outb( (phys>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+-	    dma_outb( (phys>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+-	}
+-	set_dma_page(dmanr, phys>>16);
+-}
+-
+-
+-/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
+- * a specific DMA channel.
+- * You must ensure the parameters are valid.
+- * NOTE: from a manual: "the number of transfers is one more
+- * than the initial word count"! This is taken into account.
+- * Assumes dma flip-flop is clear.
+- * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+- */
+-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+-{
+-        count--;
+-	if (dmanr <= 3)  {
+-	    dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+-	    dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+-        } else {
+-	    dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+-	    dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+-        }
+-}
+-
+-
+-/* Get DMA residue count. After a DMA transfer, this
+- * should return zero. Reading this while a DMA transfer is
+- * still in progress will return unpredictable results.
+- * If called before the channel has been used, it may return 1.
+- * Otherwise, it returns the number of _bytes_ left to transfer.
+- *
+- * Assumes DMA flip-flop is clear.
+- */
+-static __inline__ int get_dma_residue(unsigned int dmanr)
+-{
+-	unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
+-					 : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
+-
+-	/* using short to get 16-bit wrap around */
+-	unsigned short count;
+-
+-	count = 1 + dma_inb(io_port);
+-	count += dma_inb(io_port) << 8;
+-	
+-	return (dmanr <= 3)? count : (count<<1);
+-}
+-
+-/* These are in kernel/dma.c: */
+-extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
+-extern void free_dma(unsigned int dmanr);	/* release it again */
+-
+-#ifdef CONFIG_PCI
+-extern int isa_dma_bridge_buggy;                                        
+-#else                                                         
+-#define isa_dma_bridge_buggy   (0)
+-#endif
+-#endif	/* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */
+-#endif /* _ASM_DMA_H */
+diff --git a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h
+deleted file mode 100644
+--- a/include/asm-ppc64/elf.h
++++ /dev/null
+@@ -1,387 +0,0 @@
+-#ifndef __PPC64_ELF_H
+-#define __PPC64_ELF_H
+-
+-#include <asm/types.h>
+-#include <asm/ptrace.h>
+-#include <asm/cputable.h>
+-#include <asm/auxvec.h>
+-
+-/* PowerPC relocations defined by the ABIs */
+-#define R_PPC_NONE		0
+-#define R_PPC_ADDR32		1	/* 32bit absolute address */
+-#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
+-#define R_PPC_ADDR16		3	/* 16bit absolute address */
+-#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
+-#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
+-#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
+-#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
+-#define R_PPC_ADDR14_BRTAKEN	8
+-#define R_PPC_ADDR14_BRNTAKEN	9
+-#define R_PPC_REL24		10	/* PC relative 26 bit */
+-#define R_PPC_REL14		11	/* PC relative 16 bit */
+-#define R_PPC_REL14_BRTAKEN	12
+-#define R_PPC_REL14_BRNTAKEN	13
+-#define R_PPC_GOT16		14
+-#define R_PPC_GOT16_LO		15
+-#define R_PPC_GOT16_HI		16
+-#define R_PPC_GOT16_HA		17
+-#define R_PPC_PLTREL24		18
+-#define R_PPC_COPY		19
+-#define R_PPC_GLOB_DAT		20
+-#define R_PPC_JMP_SLOT		21
+-#define R_PPC_RELATIVE		22
+-#define R_PPC_LOCAL24PC		23
+-#define R_PPC_UADDR32		24
+-#define R_PPC_UADDR16		25
+-#define R_PPC_REL32		26
+-#define R_PPC_PLT32		27
+-#define R_PPC_PLTREL32		28
+-#define R_PPC_PLT16_LO		29
+-#define R_PPC_PLT16_HI		30
+-#define R_PPC_PLT16_HA		31
+-#define R_PPC_SDAREL16		32
+-#define R_PPC_SECTOFF		33
+-#define R_PPC_SECTOFF_LO	34
+-#define R_PPC_SECTOFF_HI	35
+-#define R_PPC_SECTOFF_HA	36
+-
+-/* PowerPC relocations defined for the TLS access ABI.  */
+-#define R_PPC_TLS		67 /* none	(sym+add)@tls */
+-#define R_PPC_DTPMOD32		68 /* word32	(sym+add)@dtpmod */
+-#define R_PPC_TPREL16		69 /* half16*	(sym+add)@tprel */
+-#define R_PPC_TPREL16_LO	70 /* half16	(sym+add)@tprel at l */
+-#define R_PPC_TPREL16_HI	71 /* half16	(sym+add)@tprel at h */
+-#define R_PPC_TPREL16_HA	72 /* half16	(sym+add)@tprel at ha */
+-#define R_PPC_TPREL32		73 /* word32	(sym+add)@tprel */
+-#define R_PPC_DTPREL16		74 /* half16*	(sym+add)@dtprel */
+-#define R_PPC_DTPREL16_LO	75 /* half16	(sym+add)@dtprel at l */
+-#define R_PPC_DTPREL16_HI	76 /* half16	(sym+add)@dtprel at h */
+-#define R_PPC_DTPREL16_HA	77 /* half16	(sym+add)@dtprel at ha */
+-#define R_PPC_DTPREL32		78 /* word32	(sym+add)@dtprel */
+-#define R_PPC_GOT_TLSGD16	79 /* half16*	(sym+add)@got at tlsgd */
+-#define R_PPC_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got at tlsgd@l */
+-#define R_PPC_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got at tlsgd@h */
+-#define R_PPC_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got at tlsgd@ha */
+-#define R_PPC_GOT_TLSLD16	83 /* half16*	(sym+add)@got at tlsld */
+-#define R_PPC_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got at tlsld@l */
+-#define R_PPC_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got at tlsld@h */
+-#define R_PPC_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got at tlsld@ha */
+-#define R_PPC_GOT_TPREL16	87 /* half16*	(sym+add)@got at tprel */
+-#define R_PPC_GOT_TPREL16_LO	88 /* half16	(sym+add)@got at tprel@l */
+-#define R_PPC_GOT_TPREL16_HI	89 /* half16	(sym+add)@got at tprel@h */
+-#define R_PPC_GOT_TPREL16_HA	90 /* half16	(sym+add)@got at tprel@ha */
+-#define R_PPC_GOT_DTPREL16	91 /* half16*	(sym+add)@got at dtprel */
+-#define R_PPC_GOT_DTPREL16_LO	92 /* half16*	(sym+add)@got at dtprel@l */
+-#define R_PPC_GOT_DTPREL16_HI	93 /* half16*	(sym+add)@got at dtprel@h */
+-#define R_PPC_GOT_DTPREL16_HA	94 /* half16*	(sym+add)@got at dtprel@ha */
+-
+-/* Keep this the last entry.  */
+-#define R_PPC_NUM		95
+-
+-/*
+- * ELF register definitions..
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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/ptrace.h>
+-
+-#define ELF_NGREG	48	/* includes nip, msr, lr, etc. */
+-#define ELF_NFPREG	33	/* includes fpscr */
+-#define ELF_NVRREG32	33	/* includes vscr & vrsave stuffed together */
+-#define ELF_NVRREG	34	/* includes vscr & vrsave in split vectors */
+-
+-typedef unsigned long elf_greg_t64;
+-typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
+-
+-typedef unsigned int elf_greg_t32;
+-typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
+-
+-/*
+- * These are used to set parameters in the core dumps.
+- */
+-#ifndef ELF_ARCH
+-# define ELF_ARCH	EM_PPC64
+-# define ELF_CLASS	ELFCLASS64
+-# define ELF_DATA	ELFDATA2MSB
+-  typedef elf_greg_t64 elf_greg_t;
+-  typedef elf_gregset_t64 elf_gregset_t;
+-# define elf_addr_t unsigned long
+-#else
+-  /* Assumption: ELF_ARCH == EM_PPC and ELF_CLASS == ELFCLASS32 */
+-  typedef elf_greg_t32 elf_greg_t;
+-  typedef elf_gregset_t32 elf_gregset_t;
+-# define elf_addr_t u32
+-#endif
+-
+-typedef double elf_fpreg_t;
+-typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+-
+-/* Altivec registers */
+-/*
+- * The entries with indexes 0-31 contain the corresponding vector registers. 
+- * The entry with index 32 contains the vscr as the last word (offset 12) 
+- * within the quadword.  This allows the vscr to be stored as either a 
+- * quadword (since it must be copied via a vector register to/from storage) 
+- * or as a word.  The entry with index 33 contains the vrsave as the first 
+- * word (offset 0) within the quadword.
+- *
+- * This definition of the VMX state is compatible with the current PPC32 
+- * ptrace interface.  This allows signal handling and ptrace to use the same 
+- * structures.  This also simplifies the implementation of a bi-arch 
+- * (combined (32- and 64-bit) gdb.
+- *
+- * Note that it's _not_ compatible with 32 bits ucontext which stuffs the
+- * vrsave along with vscr and so only uses 33 vectors for the register set
+- */
+-typedef __vector128 elf_vrreg_t;
+-typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
+-typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
+-
+-/*
+- * This is used to ensure we don't load something for the wrong architecture.
+- */
+-#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
+-
+-#define USE_ELF_CORE_DUMP
+-#define ELF_EXEC_PAGESIZE	4096
+-
+-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+-   use of this is to invoke "./ld.so someprog" to test out a new version of
+-   the loader.  We need to make sure that it is out of the way of the program
+-   that it will "exec", and that there is sufficient room for the brk.  */
+-
+-#define ELF_ET_DYN_BASE         (0x08000000)
+-
+-#ifdef __KERNEL__
+-
+-/* Common routine for both 32-bit and 64-bit processes */
+-static inline void ppc64_elf_core_copy_regs(elf_gregset_t elf_regs,
+-					    struct pt_regs *regs)
+-{
+-	int i;
+-	int gprs = sizeof(struct pt_regs)/sizeof(elf_greg_t64);
+-
+-	if (gprs > ELF_NGREG)
+-		gprs = ELF_NGREG;
+-
+-	for (i=0; i < gprs; i++)
+-		elf_regs[i] = (elf_greg_t)((elf_greg_t64 *)regs)[i];
+-}
+-#define ELF_CORE_COPY_REGS(gregs, regs) ppc64_elf_core_copy_regs(gregs, regs);
+-
+-static inline int dump_task_regs(struct task_struct *tsk,
+-				 elf_gregset_t *elf_regs)
+-{
+-	struct pt_regs *regs = tsk->thread.regs;
+-	if (regs)
+-		ppc64_elf_core_copy_regs(*elf_regs, regs);
+-
+-	return 1;
+-}
+-#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
+-
+-extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); 
+-#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+-
+-/* XXX Should we define the XFPREGS using altivec ??? */
+-
+-#endif
+-
+-/* This yields a mask that user programs can use to figure out what
+-   instruction set this cpu supports.  This could be done in userspace,
+-   but it's not easy, and we've already done it here.  */
+-
+-#define ELF_HWCAP	(cur_cpu_spec->cpu_user_features)
+-
+-/* This yields a string that ld.so will use to load implementation
+-   specific libraries for optimization.  This is more specific in
+-   intent than poking at uname or /proc/cpuinfo.
+-
+-   For the moment, we have only optimizations for the Intel generations,
+-   but that could change... */
+-
+-#define ELF_PLATFORM	(NULL)
+-
+-#define ELF_PLAT_INIT(_r, load_addr)	do { \
+-	memset(_r->gpr, 0, sizeof(_r->gpr)); \
+-	_r->ctr = _r->link = _r->xer = _r->ccr = 0; \
+-	_r->gpr[2] = load_addr; \
+-} while (0)
+-
+-#ifdef __KERNEL__
+-#define SET_PERSONALITY(ex, ibcs2)				\
+-do {								\
+-	unsigned long new_flags = 0;				\
+-	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
+-		new_flags = _TIF_32BIT;				\
+-	if ((current_thread_info()->flags & _TIF_32BIT)		\
+-	    != new_flags)					\
+-		set_thread_flag(TIF_ABI_PENDING);		\
+-	else							\
+-		clear_thread_flag(TIF_ABI_PENDING);		\
+-	if (personality(current->personality) != PER_LINUX32)	\
+-		set_personality(PER_LINUX);			\
+-} while (0)
+-
+-/*
+- * An executable for which elf_read_implies_exec() returns TRUE will
+- * have the READ_IMPLIES_EXEC personality flag set automatically. This
+- * is only required to work around bugs in old 32bit toolchains. Since
+- * the 64bit ABI has never had these issues dont enable the workaround
+- * even if we have an executable stack.
+- */
+-#define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
+-		(exec_stk != EXSTACK_DISABLE_X) : 0)
+-
+-#endif
+-
+-extern int dcache_bsize;
+-extern int icache_bsize;
+-extern int ucache_bsize;
+-
+-/* We do have an arch_setup_additional_pages for vDSO matters */
+-#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+-struct linux_binprm;
+-extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack);
+-
+-/*
+- * The requirements here are:
+- * - keep the final alignment of sp (sp & 0xf)
+- * - make sure the 32-bit value at the first 16 byte aligned position of
+- *   AUXV is greater than 16 for glibc compatibility.
+- *   AT_IGNOREPPC is used for that.
+- * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
+- *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
+- */
+-#define ARCH_DLINFO							\
+-do {									\
+-	/* Handle glibc compatibility. */				\
+-	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
+-	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
+-	/* Cache size items */						\
+-	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
+-	NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);			\
+-	NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize);			\
+-	/* vDSO base */							\
+-	NEW_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base);       	\
+- } while (0)
+-
+-/* PowerPC64 relocations defined by the ABIs */
+-#define R_PPC64_NONE    R_PPC_NONE
+-#define R_PPC64_ADDR32  R_PPC_ADDR32  /* 32bit absolute address.  */
+-#define R_PPC64_ADDR24  R_PPC_ADDR24  /* 26bit address, word aligned.  */
+-#define R_PPC64_ADDR16  R_PPC_ADDR16  /* 16bit absolute address. */
+-#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address.  */
+-#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */
+-#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits.  */
+-#define R_PPC64_ADDR14 R_PPC_ADDR14   /* 16bit address, word aligned.  */
+-#define R_PPC64_ADDR14_BRTAKEN  R_PPC_ADDR14_BRTAKEN
+-#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+-#define R_PPC64_REL24   R_PPC_REL24 /* PC relative 26 bit, word aligned.  */
+-#define R_PPC64_REL14   R_PPC_REL14 /* PC relative 16 bit. */
+-#define R_PPC64_REL14_BRTAKEN   R_PPC_REL14_BRTAKEN
+-#define R_PPC64_REL14_BRNTAKEN  R_PPC_REL14_BRNTAKEN
+-#define R_PPC64_GOT16     R_PPC_GOT16
+-#define R_PPC64_GOT16_LO  R_PPC_GOT16_LO
+-#define R_PPC64_GOT16_HI  R_PPC_GOT16_HI
+-#define R_PPC64_GOT16_HA  R_PPC_GOT16_HA
+-
+-#define R_PPC64_COPY      R_PPC_COPY
+-#define R_PPC64_GLOB_DAT  R_PPC_GLOB_DAT
+-#define R_PPC64_JMP_SLOT  R_PPC_JMP_SLOT
+-#define R_PPC64_RELATIVE  R_PPC_RELATIVE
+-
+-#define R_PPC64_UADDR32   R_PPC_UADDR32
+-#define R_PPC64_UADDR16   R_PPC_UADDR16
+-#define R_PPC64_REL32     R_PPC_REL32
+-#define R_PPC64_PLT32     R_PPC_PLT32
+-#define R_PPC64_PLTREL32  R_PPC_PLTREL32
+-#define R_PPC64_PLT16_LO  R_PPC_PLT16_LO
+-#define R_PPC64_PLT16_HI  R_PPC_PLT16_HI
+-#define R_PPC64_PLT16_HA  R_PPC_PLT16_HA
+-
+-#define R_PPC64_SECTOFF     R_PPC_SECTOFF
+-#define R_PPC64_SECTOFF_LO  R_PPC_SECTOFF_LO
+-#define R_PPC64_SECTOFF_HI  R_PPC_SECTOFF_HI
+-#define R_PPC64_SECTOFF_HA  R_PPC_SECTOFF_HA
+-#define R_PPC64_ADDR30          37  /* word30 (S + A - P) >> 2.  */
+-#define R_PPC64_ADDR64          38  /* doubleword64 S + A.  */
+-#define R_PPC64_ADDR16_HIGHER   39  /* half16 #higher(S + A).  */
+-#define R_PPC64_ADDR16_HIGHERA  40  /* half16 #highera(S + A).  */
+-#define R_PPC64_ADDR16_HIGHEST  41  /* half16 #highest(S + A).  */
+-#define R_PPC64_ADDR16_HIGHESTA 42  /* half16 #highesta(S + A). */
+-#define R_PPC64_UADDR64     43  /* doubleword64 S + A.  */
+-#define R_PPC64_REL64       44  /* doubleword64 S + A - P.  */
+-#define R_PPC64_PLT64       45  /* doubleword64 L + A.  */
+-#define R_PPC64_PLTREL64    46  /* doubleword64 L + A - P.  */
+-#define R_PPC64_TOC16       47  /* half16* S + A - .TOC.  */
+-#define R_PPC64_TOC16_LO    48  /* half16 #lo(S + A - .TOC.).  */
+-#define R_PPC64_TOC16_HI    49  /* half16 #hi(S + A - .TOC.).  */
+-#define R_PPC64_TOC16_HA    50  /* half16 #ha(S + A - .TOC.).  */
+-#define R_PPC64_TOC         51  /* doubleword64 .TOC. */
+-#define R_PPC64_PLTGOT16    52  /* half16* M + A.  */
+-#define R_PPC64_PLTGOT16_LO 53  /* half16 #lo(M + A).  */
+-#define R_PPC64_PLTGOT16_HI 54  /* half16 #hi(M + A).  */
+-#define R_PPC64_PLTGOT16_HA 55  /* half16 #ha(M + A).  */
+-
+-#define R_PPC64_ADDR16_DS      56 /* half16ds* (S + A) >> 2.  */
+-#define R_PPC64_ADDR16_LO_DS   57 /* half16ds  #lo(S + A) >> 2.  */
+-#define R_PPC64_GOT16_DS       58 /* half16ds* (G + A) >> 2.  */
+-#define R_PPC64_GOT16_LO_DS    59 /* half16ds  #lo(G + A) >> 2.  */
+-#define R_PPC64_PLT16_LO_DS    60 /* half16ds  #lo(L + A) >> 2.  */
+-#define R_PPC64_SECTOFF_DS     61 /* half16ds* (R + A) >> 2.  */
+-#define R_PPC64_SECTOFF_LO_DS  62 /* half16ds  #lo(R + A) >> 2.  */
+-#define R_PPC64_TOC16_DS       63 /* half16ds* (S + A - .TOC.) >> 2.  */
+-#define R_PPC64_TOC16_LO_DS    64 /* half16ds  #lo(S + A - .TOC.) >> 2.  */
+-#define R_PPC64_PLTGOT16_DS    65 /* half16ds* (M + A) >> 2.  */
+-#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds  #lo(M + A) >> 2.  */
+-
+-/* PowerPC64 relocations defined for the TLS access ABI.  */
+-#define R_PPC64_TLS		67 /* none	(sym+add)@tls */
+-#define R_PPC64_DTPMOD64	68 /* doubleword64 (sym+add)@dtpmod */
+-#define R_PPC64_TPREL16		69 /* half16*	(sym+add)@tprel */
+-#define R_PPC64_TPREL16_LO	70 /* half16	(sym+add)@tprel at l */
+-#define R_PPC64_TPREL16_HI	71 /* half16	(sym+add)@tprel at h */
+-#define R_PPC64_TPREL16_HA	72 /* half16	(sym+add)@tprel at ha */
+-#define R_PPC64_TPREL64		73 /* doubleword64 (sym+add)@tprel */
+-#define R_PPC64_DTPREL16	74 /* half16*	(sym+add)@dtprel */
+-#define R_PPC64_DTPREL16_LO	75 /* half16	(sym+add)@dtprel at l */
+-#define R_PPC64_DTPREL16_HI	76 /* half16	(sym+add)@dtprel at h */
+-#define R_PPC64_DTPREL16_HA	77 /* half16	(sym+add)@dtprel at ha */
+-#define R_PPC64_DTPREL64	78 /* doubleword64 (sym+add)@dtprel */
+-#define R_PPC64_GOT_TLSGD16	79 /* half16*	(sym+add)@got at tlsgd */
+-#define R_PPC64_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got at tlsgd@l */
+-#define R_PPC64_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got at tlsgd@h */
+-#define R_PPC64_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got at tlsgd@ha */
+-#define R_PPC64_GOT_TLSLD16	83 /* half16*	(sym+add)@got at tlsld */
+-#define R_PPC64_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got at tlsld@l */
+-#define R_PPC64_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got at tlsld@h */
+-#define R_PPC64_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got at tlsld@ha */
+-#define R_PPC64_GOT_TPREL16_DS	87 /* half16ds*	(sym+add)@got at tprel */
+-#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got at tprel@l */
+-#define R_PPC64_GOT_TPREL16_HI	89 /* half16	(sym+add)@got at tprel@h */
+-#define R_PPC64_GOT_TPREL16_HA	90 /* half16	(sym+add)@got at tprel@ha */
+-#define R_PPC64_GOT_DTPREL16_DS	91 /* half16ds*	(sym+add)@got at dtprel */
+-#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got at dtprel@l */
+-#define R_PPC64_GOT_DTPREL16_HI	93 /* half16	(sym+add)@got at dtprel@h */
+-#define R_PPC64_GOT_DTPREL16_HA	94 /* half16	(sym+add)@got at dtprel@ha */
+-#define R_PPC64_TPREL16_DS	95 /* half16ds*	(sym+add)@tprel */
+-#define R_PPC64_TPREL16_LO_DS	96 /* half16ds	(sym+add)@tprel at l */
+-#define R_PPC64_TPREL16_HIGHER	97 /* half16	(sym+add)@tprel at higher */
+-#define R_PPC64_TPREL16_HIGHERA	98 /* half16	(sym+add)@tprel at highera */
+-#define R_PPC64_TPREL16_HIGHEST	99 /* half16	(sym+add)@tprel at highest */
+-#define R_PPC64_TPREL16_HIGHESTA 100 /* half16	(sym+add)@tprel at highesta */
+-#define R_PPC64_DTPREL16_DS	101 /* half16ds* (sym+add)@dtprel */
+-#define R_PPC64_DTPREL16_LO_DS	102 /* half16ds	(sym+add)@dtprel at l */
+-#define R_PPC64_DTPREL16_HIGHER	103 /* half16	(sym+add)@dtprel at higher */
+-#define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel at highera */
+-#define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel at highest */
+-#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel at highesta */
+-
+-/* Keep this the last entry.  */
+-#define R_PPC64_NUM		107
+-
+-#endif /* __PPC64_ELF_H */
+diff --git a/include/asm-ppc64/firmware.h b/include/asm-ppc64/firmware.h
+deleted file mode 100644
+--- a/include/asm-ppc64/firmware.h
++++ /dev/null
+@@ -1,101 +0,0 @@
+-/*
+- *  include/asm-ppc64/firmware.h
+- *
+- *  Extracted from include/asm-ppc64/cputable.h
+- *
+- *  Copyright (C) 2001 Ben. Herrenschmidt (benh at kernel.crashing.org)
+- *
+- *  Modifications for ppc64:
+- *      Copyright (C) 2003 Dave Engebretsen <engebret at 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.
+- */
+-#ifndef __ASM_PPC_FIRMWARE_H
+-#define __ASM_PPC_FIRMWARE_H
+-
+-#ifdef __KERNEL__
+-
+-#ifndef __ASSEMBLY__
+-
+-/* firmware feature bitmask values */
+-#define FIRMWARE_MAX_FEATURES 63
+-
+-#define FW_FEATURE_PFT		(1UL<<0)
+-#define FW_FEATURE_TCE		(1UL<<1)
+-#define FW_FEATURE_SPRG0	(1UL<<2)
+-#define FW_FEATURE_DABR		(1UL<<3)
+-#define FW_FEATURE_COPY		(1UL<<4)
+-#define FW_FEATURE_ASR		(1UL<<5)
+-#define FW_FEATURE_DEBUG	(1UL<<6)
+-#define FW_FEATURE_TERM		(1UL<<7)
+-#define FW_FEATURE_PERF		(1UL<<8)
+-#define FW_FEATURE_DUMP		(1UL<<9)
+-#define FW_FEATURE_INTERRUPT	(1UL<<10)
+-#define FW_FEATURE_MIGRATE	(1UL<<11)
+-#define FW_FEATURE_PERFMON	(1UL<<12)
+-#define FW_FEATURE_CRQ		(1UL<<13)
+-#define FW_FEATURE_VIO		(1UL<<14)
+-#define FW_FEATURE_RDMA		(1UL<<15)
+-#define FW_FEATURE_LLAN		(1UL<<16)
+-#define FW_FEATURE_BULK		(1UL<<17)
+-#define FW_FEATURE_XDABR	(1UL<<18)
+-#define FW_FEATURE_MULTITCE	(1UL<<19)
+-#define FW_FEATURE_SPLPAR	(1UL<<20)
+-#define FW_FEATURE_ISERIES	(1UL<<21)
+-
+-enum {
+-	FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE |
+-		FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY |
+-		FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM |
+-		FW_FEATURE_PERF | FW_FEATURE_DUMP | FW_FEATURE_INTERRUPT |
+-		FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ |
+-		FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
+-		FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE |
+-		FW_FEATURE_SPLPAR,
+-	FW_FEATURE_PSERIES_ALWAYS = 0,
+-	FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES,
+-	FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES,
+-	FW_FEATURE_POSSIBLE =
+-#ifdef CONFIG_PPC_PSERIES
+-		FW_FEATURE_PSERIES_POSSIBLE |
+-#endif
+-#ifdef CONFIG_PPC_ISERIES
+-		FW_FEATURE_ISERIES_POSSIBLE |
+-#endif
+-		0,
+-	FW_FEATURE_ALWAYS =
+-#ifdef CONFIG_PPC_PSERIES
+-		FW_FEATURE_PSERIES_ALWAYS &
+-#endif
+-#ifdef CONFIG_PPC_ISERIES
+-		FW_FEATURE_ISERIES_ALWAYS &
+-#endif
+-		FW_FEATURE_POSSIBLE,
+-};
+-
+-/* This is used to identify firmware features which are available
+- * to the kernel.
+- */
+-extern unsigned long	ppc64_firmware_features;
+-
+-static inline unsigned long firmware_has_feature(unsigned long feature)
+-{
+-	return (FW_FEATURE_ALWAYS & feature) ||
+-		(FW_FEATURE_POSSIBLE & ppc64_firmware_features & feature);
+-}
+-
+-#ifdef CONFIG_PPC_PSERIES
+-typedef struct {
+-    unsigned long val;
+-    char * name;
+-} firmware_feature_t;
+-
+-extern firmware_feature_t firmware_features_table[];
+-#endif
+-
+-#endif /* __ASSEMBLY__ */
+-#endif /* __KERNEL__ */
+-#endif /* __ASM_PPC_FIRMWARE_H */
+diff --git a/include/asm-ppc64/futex.h b/include/asm-ppc64/futex.h
+--- a/include/asm-ppc64/futex.h
++++ b/include/asm-ppc64/futex.h
+@@ -5,7 +5,7 @@
+ 
+ #include <linux/futex.h>
+ #include <asm/errno.h>
+-#include <asm/memory.h>
++#include <asm/synch.h>
+ #include <asm/uaccess.h>
+ 
+ #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
+diff --git a/include/asm-ppc64/hardirq.h b/include/asm-ppc64/hardirq.h
+deleted file mode 100644
+--- a/include/asm-ppc64/hardirq.h
++++ /dev/null
+@@ -1,27 +0,0 @@
+-#ifndef __ASM_HARDIRQ_H
+-#define __ASM_HARDIRQ_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.
+- */
+-
+-#include <linux/config.h>
+-#include <linux/cache.h>
+-#include <linux/preempt.h>
+-
+-typedef struct {
+-	unsigned int __softirq_pending;
+-} ____cacheline_aligned irq_cpustat_t;
+-
+-#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+-
+-static inline void ack_bad_irq(int irq)
+-{
+-	printk(KERN_CRIT "illegal vector %d received!\n", irq);
+-	BUG();
+-}
+-
+-#endif /* __ASM_HARDIRQ_H */
+diff --git a/include/asm-ppc64/hw_irq.h b/include/asm-ppc64/hw_irq.h
+deleted file mode 100644
+--- a/include/asm-ppc64/hw_irq.h
++++ /dev/null
+@@ -1,104 +0,0 @@
+-/*
+- * Copyright (C) 1999 Cort Dougan <cort at cs.nmt.edu>
+- *
+- * Use inline IRQs where possible - Anton Blanchard <anton at au.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.
+- */
+-#ifdef __KERNEL__
+-#ifndef _PPC64_HW_IRQ_H
+-#define _PPC64_HW_IRQ_H
+-
+-#include <linux/config.h>
+-#include <linux/errno.h>
+-#include <asm/irq.h>
+-
+-int timer_interrupt(struct pt_regs *);
+-extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
+-
+-#ifdef CONFIG_PPC_ISERIES
+-
+-extern unsigned long local_get_flags(void);
+-extern unsigned long local_irq_disable(void);
+-extern void local_irq_restore(unsigned long);
+-
+-#define local_irq_enable()	local_irq_restore(1)
+-#define local_save_flags(flags)	((flags) = local_get_flags())
+-#define local_irq_save(flags)	((flags) = local_irq_disable())
+-
+-#define irqs_disabled()		(local_get_flags() == 0)
+-
+-#else
+-
+-#define local_save_flags(flags)	((flags) = mfmsr())
+-#define local_irq_restore(flags) do { \
+-	__asm__ __volatile__("": : :"memory"); \
+-	__mtmsrd((flags), 1); \
+-} while(0)
+-
+-static inline void local_irq_disable(void)
+-{
+-	unsigned long msr;
+-	msr = mfmsr();
+-	__mtmsrd(msr & ~MSR_EE, 1);
+-	__asm__ __volatile__("": : :"memory");
+-}
+-
+-static inline void local_irq_enable(void)
+-{
+-	unsigned long msr;
+-	__asm__ __volatile__("": : :"memory");
+-	msr = mfmsr();
+-	__mtmsrd(msr | MSR_EE, 1);
+-}
+-
+-static inline void __do_save_and_cli(unsigned long *flags)
+-{
+-	unsigned long msr;
+-	msr = mfmsr();
+-	*flags = msr;
+-	__mtmsrd(msr & ~MSR_EE, 1);
+-	__asm__ __volatile__("": : :"memory");
+-}
+-
+-#define local_irq_save(flags)          __do_save_and_cli(&flags)
+-
+-#define irqs_disabled()				\
+-({						\
+-	unsigned long flags;			\
+-	local_save_flags(flags);		\
+-	!(flags & MSR_EE);			\
+-})
+-
+-#endif /* CONFIG_PPC_ISERIES */
+-
+-#define mask_irq(irq)						\
+-	({							\
+-	 	irq_desc_t *desc = get_irq_desc(irq);		\
+-		if (desc->handler && desc->handler->disable)	\
+-			desc->handler->disable(irq);		\
+-	})
+-#define unmask_irq(irq)						\
+-	({							\
+-	 	irq_desc_t *desc = get_irq_desc(irq);		\
+-		if (desc->handler && desc->handler->enable)	\
+-			desc->handler->enable(irq);		\
+-	})
+-#define ack_irq(irq)						\
+-	({							\
+-	 	irq_desc_t *desc = get_irq_desc(irq);		\
+-		if (desc->handler && desc->handler->ack)	\
+-			desc->handler->ack(irq);		\
+-	})
+-
+-/* Should we handle this via lost interrupts and IPIs or should we don't care like
+- * we do now ? --BenH.
+- */
+-struct hw_interrupt_type;
+-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
+- 
+-#endif /* _PPC64_HW_IRQ_H */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc64/iSeries/HvCallHpt.h b/include/asm-ppc64/iSeries/HvCallHpt.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/HvCallHpt.h
++++ /dev/null
+@@ -1,102 +0,0 @@
+-/*
+- * HvCallHpt.h
+- * Copyright (C) 2001  Mike Corrigan 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
+- */
+-#ifndef _HVCALLHPT_H
+-#define _HVCALLHPT_H
+-
+-/*
+- * This file contains the "hypervisor call" interface which is used to
+- * drive the hypervisor from the OS.
+- */
+-
+-#include <asm/iSeries/HvCallSc.h>
+-#include <asm/iSeries/HvTypes.h>
+-#include <asm/mmu.h>
+-
+-#define HvCallHptGetHptAddress		HvCallHpt +  0
+-#define HvCallHptGetHptPages		HvCallHpt +  1
+-#define HvCallHptSetPp			HvCallHpt +  5
+-#define HvCallHptSetSwBits		HvCallHpt +  6
+-#define HvCallHptUpdate			HvCallHpt +  7
+-#define HvCallHptInvalidateNoSyncICache	HvCallHpt +  8
+-#define HvCallHptGet			HvCallHpt + 11
+-#define HvCallHptFindNextValid		HvCallHpt + 12
+-#define HvCallHptFindValid		HvCallHpt + 13
+-#define HvCallHptAddValidate		HvCallHpt + 16
+-#define HvCallHptInvalidateSetSwBitsGet HvCallHpt + 18
+-
+-
+-static inline u64 HvCallHpt_getHptAddress(void)
+-{
+-	return HvCall0(HvCallHptGetHptAddress);
+-}
+-
+-static inline u64 HvCallHpt_getHptPages(void)
+-{
+-	return HvCall0(HvCallHptGetHptPages);
+-}
+-
+-static inline void HvCallHpt_setPp(u32 hpteIndex, u8 value)
+-{
+-	HvCall2(HvCallHptSetPp, hpteIndex, value);
+-}
+-
+-static inline void HvCallHpt_setSwBits(u32 hpteIndex, u8 bitson, u8 bitsoff)
+-{
+-	HvCall3(HvCallHptSetSwBits, hpteIndex, bitson, bitsoff);
+-}
+-
+-static inline void HvCallHpt_invalidateNoSyncICache(u32 hpteIndex)
+-{
+-	HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex);
+-}
+-
+-static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson,
+-		u8 bitsoff)
+-{
+-	u64 compressedStatus;
+-
+-	compressedStatus = HvCall4(HvCallHptInvalidateSetSwBitsGet,
+-			hpteIndex, bitson, bitsoff, 1);
+-	HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex);
+-	return compressedStatus;
+-}
+-
+-static inline u64 HvCallHpt_findValid(hpte_t *hpte, u64 vpn)
+-{
+-	return HvCall3Ret16(HvCallHptFindValid, hpte, vpn, 0, 0);
+-}
+-
+-static inline u64 HvCallHpt_findNextValid(hpte_t *hpte, u32 hpteIndex,
+-		u8 bitson, u8 bitsoff)
+-{
+-	return HvCall3Ret16(HvCallHptFindNextValid, hpte, hpteIndex,
+-			bitson, bitsoff);
+-}
+-
+-static inline void HvCallHpt_get(hpte_t *hpte, u32 hpteIndex)
+-{
+-	HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0);
+-}
+-
+-static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, hpte_t *hpte)
+-{
+-	HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r);
+-}
+-
+-#endif /* _HVCALLHPT_H */
+diff --git a/include/asm-ppc64/iSeries/HvCallPci.h b/include/asm-ppc64/iSeries/HvCallPci.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/HvCallPci.h
++++ /dev/null
+@@ -1,533 +0,0 @@
+-/*
+- * Provides the Hypervisor PCI calls for iSeries Linux Parition.
+- * Copyright (C) 2001  <Wayne G Holm> <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
+- *
+- * Change Activity:
+- *   Created, Jan 9, 2001
+- */
+-
+-#ifndef _HVCALLPCI_H
+-#define _HVCALLPCI_H
+-
+-#include <asm/iSeries/HvCallSc.h>
+-#include <asm/iSeries/HvTypes.h>
+-
+-/*
+- * DSA == Direct Select Address
+- * this struct must be 64 bits in total
+- */
+-struct HvCallPci_DsaAddr {
+-	u16		busNumber;		/* PHB index? */
+-	u8		subBusNumber;		/* PCI bus number? */
+-	u8		deviceId;		/* device and function? */
+-	u8		barNumber;
+-	u8		reserved[3];
+-};
+-
+-union HvDsaMap {
+-	u64	DsaAddr;
+-	struct HvCallPci_DsaAddr Dsa;
+-};
+-
+-struct HvCallPci_LoadReturn {
+-	u64		rc;
+-	u64		value;
+-};
+-
+-enum HvCallPci_DeviceType {
+-	HvCallPci_NodeDevice	= 1,
+-	HvCallPci_SpDevice	= 2,
+-	HvCallPci_IopDevice     = 3,
+-	HvCallPci_BridgeDevice	= 4,
+-	HvCallPci_MultiFunctionDevice = 5,
+-	HvCallPci_IoaDevice	= 6
+-};
+-
+-
+-struct HvCallPci_DeviceInfo {
+-	u32	deviceType;		/* See DeviceType enum for values */
+-};
+-
+-struct HvCallPci_BusUnitInfo {
+-	u32	sizeReturned;		/* length of data returned */
+-	u32	deviceType;		/* see DeviceType enum for values */
+-};
+-
+-struct HvCallPci_BridgeInfo {
+-	struct HvCallPci_BusUnitInfo busUnitInfo;  /* Generic bus unit info */
+-	u8		subBusNumber;	/* Bus number of secondary bus */
+-	u8		maxAgents;	/* Max idsels on secondary bus */
+-        u8              maxSubBusNumber; /* Max Sub Bus */
+-	u8		logicalSlotNumber; /* Logical Slot Number for IOA */
+-};
+-
+-
+-/*
+- * Maximum BusUnitInfo buffer size.  Provided for clients so
+- * they can allocate a buffer big enough for any type of bus
+- * unit.  Increase as needed.
+- */
+-enum {HvCallPci_MaxBusUnitInfoSize = 128};
+-
+-struct HvCallPci_BarParms {
+-	u64		vaddr;
+-	u64		raddr;
+-	u64		size;
+-	u64		protectStart;
+-	u64		protectEnd;
+-	u64		relocationOffset;
+-	u64		pciAddress;
+-	u64		reserved[3];
+-};
+-
+-enum HvCallPci_VpdType {
+-	HvCallPci_BusVpd	= 1,
+-	HvCallPci_BusAdapterVpd	= 2
+-};
+-
+-#define HvCallPciConfigLoad8		HvCallPci + 0
+-#define HvCallPciConfigLoad16		HvCallPci + 1
+-#define HvCallPciConfigLoad32		HvCallPci + 2
+-#define HvCallPciConfigStore8		HvCallPci + 3
+-#define HvCallPciConfigStore16		HvCallPci + 4
+-#define HvCallPciConfigStore32		HvCallPci + 5
+-#define HvCallPciEoi			HvCallPci + 16
+-#define HvCallPciGetBarParms		HvCallPci + 18
+-#define HvCallPciMaskFisr		HvCallPci + 20
+-#define HvCallPciUnmaskFisr		HvCallPci + 21
+-#define HvCallPciSetSlotReset		HvCallPci + 25
+-#define HvCallPciGetDeviceInfo		HvCallPci + 27
+-#define HvCallPciGetCardVpd		HvCallPci + 28
+-#define HvCallPciBarLoad8		HvCallPci + 40
+-#define HvCallPciBarLoad16		HvCallPci + 41
+-#define HvCallPciBarLoad32		HvCallPci + 42
+-#define HvCallPciBarLoad64		HvCallPci + 43
+-#define HvCallPciBarStore8		HvCallPci + 44
+-#define HvCallPciBarStore16		HvCallPci + 45
+-#define HvCallPciBarStore32		HvCallPci + 46
+-#define HvCallPciBarStore64		HvCallPci + 47
+-#define HvCallPciMaskInterrupts		HvCallPci + 48
+-#define HvCallPciUnmaskInterrupts	HvCallPci + 49
+-#define HvCallPciGetBusUnitInfo		HvCallPci + 50
+-
+-static inline u64 HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber,
+-		u8 deviceId, u32 offset, u8 *value)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-	struct HvCallPci_LoadReturn retVal;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumber;
+-	dsa.subBusNumber = subBusNumber;
+-	dsa.deviceId = deviceId;
+-
+-	HvCall3Ret16(HvCallPciConfigLoad8, &retVal, *(u64 *)&dsa, offset, 0);
+-
+-	*value = retVal.value;
+-
+-	return retVal.rc;
+-}
+-
+-static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
+-		u8 deviceId, u32 offset, u16 *value)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-	struct HvCallPci_LoadReturn retVal;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumber;
+-	dsa.subBusNumber = subBusNumber;
+-	dsa.deviceId = deviceId;
+-
+-	HvCall3Ret16(HvCallPciConfigLoad16, &retVal, *(u64 *)&dsa, offset, 0);
+-
+-	*value = retVal.value;
+-
+-	return retVal.rc;
+-}
+-
+-static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber,
+-		u8 deviceId, u32 offset, u32 *value)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-	struct HvCallPci_LoadReturn retVal;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumber;
+-	dsa.subBusNumber = subBusNumber;
+-	dsa.deviceId = deviceId;
+-
+-	HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0);
+-
+-	*value = retVal.value;
+-
+-	return retVal.rc;
+-}
+-
+-static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
+-		u8 deviceId, u32 offset, u8 value)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumber;
+-	dsa.subBusNumber = subBusNumber;
+-	dsa.deviceId = deviceId;
+-
+-	return HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0);
+-}
+-
+-static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber,
+-		u8 deviceId, u32 offset, u16 value)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumber;
+-	dsa.subBusNumber = subBusNumber;
+-	dsa.deviceId = deviceId;
+-
+-	return HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0);
+-}
+-
+-static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber,
+-		u8 deviceId, u32 offset, u32 value)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumber;
+-	dsa.subBusNumber = subBusNumber;
+-	dsa.deviceId = deviceId;
+-
+-	return HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0);
+-}
+-
+-static inline u64 HvCallPci_barLoad8(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+-		u8 *valueParm)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-	struct HvCallPci_LoadReturn retVal;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-	dsa.barNumber = barNumberParm;
+-
+-	HvCall3Ret16(HvCallPciBarLoad8, &retVal, *(u64 *)&dsa, offsetParm, 0);
+-
+-	*valueParm = retVal.value;
+-
+-	return retVal.rc;
+-}
+-
+-static inline u64 HvCallPci_barLoad16(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+-		u16 *valueParm)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-	struct HvCallPci_LoadReturn retVal;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-	dsa.barNumber = barNumberParm;
+-
+-	HvCall3Ret16(HvCallPciBarLoad16, &retVal, *(u64 *)&dsa, offsetParm, 0);
+-
+-	*valueParm = retVal.value;
+-
+-	return retVal.rc;
+-}
+-
+-static inline u64 HvCallPci_barLoad32(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+-		u32 *valueParm)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-	struct HvCallPci_LoadReturn retVal;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-	dsa.barNumber = barNumberParm;
+-
+-	HvCall3Ret16(HvCallPciBarLoad32, &retVal, *(u64 *)&dsa, offsetParm, 0);
+-
+-	*valueParm = retVal.value;
+-
+-	return retVal.rc;
+-}
+-
+-static inline u64 HvCallPci_barLoad64(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+-		u64 *valueParm)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-	struct HvCallPci_LoadReturn retVal;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-	dsa.barNumber = barNumberParm;
+-
+-	HvCall3Ret16(HvCallPciBarLoad64, &retVal, *(u64 *)&dsa, offsetParm, 0);
+-
+-	*valueParm = retVal.value;
+-
+-	return retVal.rc;
+-}
+-
+-static inline u64 HvCallPci_barStore8(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+-		u8 valueParm)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-	dsa.barNumber = barNumberParm;
+-
+-	return HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm,
+-			valueParm, 0);
+-}
+-
+-static inline u64 HvCallPci_barStore16(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+-		u16 valueParm)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-	dsa.barNumber = barNumberParm;
+-
+-	return HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm,
+-			valueParm, 0);
+-}
+-
+-static inline u64 HvCallPci_barStore32(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+-		u32 valueParm)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-	dsa.barNumber = barNumberParm;
+-
+-	return HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm,
+-			valueParm, 0);
+-}
+-
+-static inline u64 HvCallPci_barStore64(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+-		u64 valueParm)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-	dsa.barNumber = barNumberParm;
+-
+-	return HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm,
+-			valueParm, 0);
+-}
+-
+-static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-	struct HvCallPci_LoadReturn retVal;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-
+-	HvCall1Ret16(HvCallPciEoi, &retVal, *(u64*)&dsa);
+-
+-	return retVal.rc;
+-}
+-
+-static inline u64 HvCallPci_getBarParms(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u8 barNumberParm, u64 parms, u32 sizeofParms)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-	dsa.barNumber = barNumberParm;
+-
+-	return HvCall3(HvCallPciGetBarParms, *(u64*)&dsa, parms, sizeofParms);
+-}
+-
+-static inline u64 HvCallPci_maskFisr(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u64 fisrMask)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-
+-	return HvCall2(HvCallPciMaskFisr, *(u64*)&dsa, fisrMask);
+-}
+-
+-static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u64 fisrMask)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-
+-	return HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask);
+-}
+-
+-static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u64 onNotOff)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-
+-	return HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff);
+-}
+-
+-static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceNumberParm, u64 parms, u32 sizeofParms)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceNumberParm << 4;
+-
+-	return HvCall3(HvCallPciGetDeviceInfo, *(u64*)&dsa, parms, sizeofParms);
+-}
+-
+-static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u64 interruptMask)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-
+-	return HvCall2(HvCallPciMaskInterrupts, *(u64*)&dsa, interruptMask);
+-}
+-
+-static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u64 interruptMask)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-
+-	return HvCall2(HvCallPciUnmaskInterrupts, *(u64*)&dsa, interruptMask);
+-}
+-
+-static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, u8 subBusParm,
+-		u8 deviceIdParm, u64 parms, u32 sizeofParms)
+-{
+-	struct HvCallPci_DsaAddr dsa;
+-
+-	*((u64*)&dsa) = 0;
+-
+-	dsa.busNumber = busNumberParm;
+-	dsa.subBusNumber = subBusParm;
+-	dsa.deviceId = deviceIdParm;
+-
+-	return HvCall3(HvCallPciGetBusUnitInfo, *(u64*)&dsa, parms,
+-			sizeofParms);
+-}
+-
+-static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm,
+-		u16 sizeParm)
+-{
+-	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm,
+-			sizeParm, HvCallPci_BusVpd);
+-	if (xRc == -1)
+-		return -1;
+-	else
+-		return xRc & 0xFFFF;
+-}
+-
+-static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm,
+-		u16 sizeParm)
+-{
+-	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm,
+-			sizeParm, HvCallPci_BusAdapterVpd);
+-	if (xRc == -1)
+-		return -1;
+-	else
+-		return xRc & 0xFFFF;
+-}
+-
+-#endif /* _HVCALLPCI_H */
+diff --git a/include/asm-ppc64/iSeries/HvCallSm.h b/include/asm-ppc64/iSeries/HvCallSm.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/HvCallSm.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/*
+- * HvCallSm.h
+- * Copyright (C) 2001  Mike Corrigan 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
+- */
+-#ifndef _HVCALLSM_H
+-#define _HVCALLSM_H
+-
+-/*
+- * This file contains the "hypervisor call" interface which is used to
+- * drive the hypervisor from the OS.
+- */
+-
+-#include <asm/iSeries/HvCallSc.h>
+-#include <asm/iSeries/HvTypes.h>
+-
+-#define HvCallSmGet64BitsOfAccessMap	HvCallSm  + 11
+-
+-static inline u64 HvCallSm_get64BitsOfAccessMap(HvLpIndex lpIndex,
+-		u64 indexIntoBitMap)
+-{
+-	return HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, indexIntoBitMap);
+-}
+-
+-#endif /* _HVCALLSM_H */
+diff --git a/include/asm-ppc64/iSeries/HvReleaseData.h b/include/asm-ppc64/iSeries/HvReleaseData.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/HvReleaseData.h
++++ /dev/null
+@@ -1,64 +0,0 @@
+-/*
+- * HvReleaseData.h
+- * Copyright (C) 2001  Mike Corrigan 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
+- */
+-#ifndef _HVRELEASEDATA_H
+-#define _HVRELEASEDATA_H
+-
+-/*
+- * This control block contains the critical information about the
+- * release so that it can be changed in the future (ie, the virtual
+- * address of the OS's NACA).
+- */
+-#include <asm/types.h>
+-#include <asm/naca.h>
+-
+-/*
+- * When we IPL a secondary partition, we will check if if the
+- * secondary xMinPlicVrmIndex > the primary xVrmIndex.
+- * If it is then this tells PLIC that this secondary is not
+- * supported running on this "old" of a level of PLIC.
+- *
+- * Likewise, we will compare the primary xMinSlicVrmIndex to
+- * the secondary xVrmIndex.
+- * If the primary xMinSlicVrmDelta > secondary xVrmDelta then we
+- * know that this PLIC does not support running an OS "that old".
+- */
+-
+-#define	HVREL_TAGSINACTIVE	0x8000
+-#define HVREL_32BIT		0x4000
+-#define HVREL_NOSHAREDPROCS	0x2000
+-#define HVREL_NOHMT		0x1000
+-
+-struct HvReleaseData {
+-	u32	xDesc;		/* Descriptor "HvRD" ebcdic	x00-x03 */
+-	u16	xSize;		/* Size of this control block	x04-x05 */
+-	u16	xVpdAreasPtrOffset; /* Offset in NACA of ItVpdAreas x06-x07 */
+-	struct  naca_struct	*xSlicNacaAddr; /* Virt addr of SLIC NACA x08-x0F */
+-	u32	xMsNucDataOffset; /* Offset of Linux Mapping Data x10-x13 */
+-	u32	xRsvd1;		/* Reserved			x14-x17 */
+-	u16	xFlags;
+-	u16	xVrmIndex;	/* VRM Index of OS image	x1A-x1B */
+-	u16	xMinSupportedPlicVrmIndex; /* Min PLIC level  (soft) x1C-x1D */
+-	u16	xMinCompatablePlicVrmIndex; /* Min PLIC levelP (hard) x1E-x1F */
+-	char	xVrmName[12];	/* Displayable name		x20-x2B */
+-	char	xRsvd3[20];	/* Reserved			x2C-x3F */
+-};
+-
+-extern struct HvReleaseData	hvReleaseData;
+-
+-#endif /* _HVRELEASEDATA_H */
+diff --git a/include/asm-ppc64/iSeries/IoHriMainStore.h b/include/asm-ppc64/iSeries/IoHriMainStore.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/IoHriMainStore.h
++++ /dev/null
+@@ -1,166 +0,0 @@
+-/*
+- * IoHriMainStore.h
+- * Copyright (C) 2001  Mike Corrigan 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
+- */
+-
+-#ifndef _IOHRIMAINSTORE_H
+-#define _IOHRIMAINSTORE_H
+-
+-/* Main Store Vpd for Condor,iStar,sStar */
+-struct IoHriMainStoreSegment4 {
+-	u8	msArea0Exists:1;
+-	u8	msArea1Exists:1;
+-	u8	msArea2Exists:1;
+-	u8	msArea3Exists:1;
+-	u8	reserved1:4;
+-	u8	reserved2;
+-
+-	u8	msArea0Functional:1;
+-	u8	msArea1Functional:1;
+-	u8	msArea2Functional:1;
+-	u8	msArea3Functional:1;
+-	u8	reserved3:4;
+-	u8	reserved4;
+-
+-	u32	totalMainStore;
+-
+-	u64	msArea0Ptr;
+-	u64	msArea1Ptr;
+-	u64	msArea2Ptr;
+-	u64	msArea3Ptr;
+-
+-	u32	cardProductionLevel;
+-
+-	u32	msAdrHole;
+-
+-	u8	msArea0HasRiserVpd:1;
+-	u8	msArea1HasRiserVpd:1;
+-	u8	msArea2HasRiserVpd:1;
+-	u8	msArea3HasRiserVpd:1;
+-	u8	reserved5:4;
+-	u8	reserved6;
+-	u16	reserved7;
+-
+-	u8	reserved8[28];
+-
+-	u64	nonInterleavedBlocksStartAdr;
+-	u64	nonInterleavedBlocksEndAdr;
+-};
+-
+-/* Main Store VPD for Power4 */
+-struct IoHriMainStoreChipInfo1 {
+-	u32	chipMfgID	__attribute((packed));
+-	char	chipECLevel[4]	__attribute((packed));
+-};
+-
+-struct IoHriMainStoreVpdIdData {
+-	char	typeNumber[4];
+-	char	modelNumber[4];
+-	char	partNumber[12];
+-	char	serialNumber[12];
+-};
+-
+-struct IoHriMainStoreVpdFruData {
+-	char	fruLabel[8]	__attribute((packed));
+-	u8	numberOfSlots	__attribute((packed));
+-	u8	pluggingType	__attribute((packed));
+-	u16	slotMapIndex	__attribute((packed));
+-};
+-
+-struct IoHriMainStoreAdrRangeBlock {
+-	void	*blockStart      __attribute((packed));
+-	void	*blockEnd        __attribute((packed));
+-	u32	blockProcChipId __attribute((packed));
+-};
+-
+-#define MaxAreaAdrRangeBlocks 4
+-
+-struct IoHriMainStoreArea4 {
+-	u32	msVpdFormat			__attribute((packed));
+-	u8	containedVpdType		__attribute((packed));
+-	u8	reserved1			__attribute((packed));
+-	u16	reserved2			__attribute((packed));
+-
+-	u64	msExists			__attribute((packed));
+-	u64	msFunctional			__attribute((packed));
+-
+-	u32	memorySize			__attribute((packed));
+-	u32	procNodeId			__attribute((packed));
+-
+-	u32	numAdrRangeBlocks		__attribute((packed));
+-	struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks]	__attribute((packed));
+-
+-	struct IoHriMainStoreChipInfo1	chipInfo0	__attribute((packed));
+-	struct IoHriMainStoreChipInfo1	chipInfo1	__attribute((packed));
+-	struct IoHriMainStoreChipInfo1	chipInfo2	__attribute((packed));
+-	struct IoHriMainStoreChipInfo1	chipInfo3	__attribute((packed));
+-	struct IoHriMainStoreChipInfo1	chipInfo4	__attribute((packed));
+-	struct IoHriMainStoreChipInfo1	chipInfo5	__attribute((packed));
+-	struct IoHriMainStoreChipInfo1	chipInfo6	__attribute((packed));
+-	struct IoHriMainStoreChipInfo1	chipInfo7	__attribute((packed));
+-
+-	void	*msRamAreaArray			__attribute((packed));
+-	u32	msRamAreaArrayNumEntries	__attribute((packed));
+-	u32	msRamAreaArrayEntrySize		__attribute((packed));
+-
+-	u32	numaDimmExists			__attribute((packed));
+-	u32	numaDimmFunctional		__attribute((packed));
+-	void	*numaDimmArray			__attribute((packed));
+-	u32	numaDimmArrayNumEntries		__attribute((packed));
+-	u32	numaDimmArrayEntrySize		__attribute((packed));
+-
+-	struct IoHriMainStoreVpdIdData idData	__attribute((packed));
+-
+-	u64	powerData			__attribute((packed));
+-	u64	cardAssemblyPartNum		__attribute((packed));
+-	u64	chipSerialNum			__attribute((packed));
+-
+-	u64	reserved3			__attribute((packed));
+-	char	reserved4[16]			__attribute((packed));
+-
+-	struct IoHriMainStoreVpdFruData fruData	__attribute((packed));
+-
+-	u8	vpdPortNum			__attribute((packed));
+-	u8	reserved5			__attribute((packed));
+-	u8	frameId				__attribute((packed));
+-	u8	rackUnit			__attribute((packed));
+-	char	asciiKeywordVpd[256]		__attribute((packed));
+-	u32	reserved6			__attribute((packed));
+-};
+-
+-
+-struct IoHriMainStoreSegment5 {
+-	u16	reserved1;
+-	u8	reserved2;
+-	u8	msVpdFormat;
+-
+-	u32	totalMainStore;
+-	u64	maxConfiguredMsAdr;
+-
+-	struct IoHriMainStoreArea4	*msAreaArray;
+-	u32	msAreaArrayNumEntries;
+-	u32	msAreaArrayEntrySize;
+-
+-	u32	msAreaExists;
+-	u32	msAreaFunctional;
+-
+-	u64	reserved3;
+-};
+-
+-extern u64	xMsVpd[];
+-
+-#endif	/* _IOHRIMAINSTORE_H */
+diff --git a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h b/include/asm-ppc64/iSeries/IoHriProcessorVpd.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h
++++ /dev/null
+@@ -1,86 +0,0 @@
+-/*
+- * IoHriProcessorVpd.h
+- * Copyright (C) 2001  Mike Corrigan 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
+- */
+-#ifndef _IOHRIPROCESSORVPD_H
+-#define _IOHRIPROCESSORVPD_H
+-
+-#include <asm/types.h>
+-
+-/*
+- * This struct maps Processor Vpd that is DMAd to SLIC by CSP
+- */
+-struct IoHriProcessorVpd {
+-	u8	xFormat;		// VPD format indicator		x00-x00
+-	u8	xProcStatus:8;		// Processor State		x01-x01
+-	u8	xSecondaryThreadCount;	// Secondary thread cnt		x02-x02
+-	u8	xSrcType:1;		// Src Type			x03-x03
+-	u8	xSrcSoft:1;		// Src stay soft		...
+-	u8	xSrcParable:1;		// Src parable			...
+-	u8	xRsvd1:5;		// Reserved			...
+-	u16	xHvPhysicalProcIndex;	// Hypervisor physical proc index04-x05
+-	u16	xRsvd2;			// Reserved			x06-x07
+-	u32	xHwNodeId;		// Hardware node id		x08-x0B
+-	u32	xHwProcId;		// Hardware processor id	x0C-x0F
+-
+-	u32	xTypeNum;		// Card Type/CCIN number	x10-x13
+-	u32	xModelNum;		// Model/Feature number		x14-x17
+-	u64	xSerialNum;		// Serial number		x18-x1F
+-	char	xPartNum[12];		// Book Part or FPU number	x20-x2B
+-	char	xMfgID[4];		// Manufacturing ID		x2C-x2F
+-
+-	u32	xProcFreq;		// Processor Frequency		x30-x33
+-	u32	xTimeBaseFreq;		// Time Base Frequency		x34-x37
+-
+-	u32	xChipEcLevel;		// Chip EC Levels		x38-x3B
+-	u32	xProcIdReg;		// PIR SPR value		x3C-x3F
+-	u32	xPVR;			// PVR value			x40-x43
+-	u8	xRsvd3[12];		// Reserved			x44-x4F
+-
+-	u32	xInstCacheSize;		// Instruction cache size in KB	x50-x53
+-	u32	xInstBlockSize;		// Instruction cache block size	x54-x57
+-	u32	xDataCacheOperandSize;	// Data cache operand size	x58-x5B
+-	u32	xInstCacheOperandSize;	// Inst cache operand size	x5C-x5F
+-
+-	u32	xDataL1CacheSizeKB;	// L1 data cache size in KB	x60-x63
+-	u32	xDataL1CacheLineSize;	// L1 data cache block size	x64-x67
+-	u64	xRsvd4;			// Reserved			x68-x6F
+-
+-	u32	xDataL2CacheSizeKB;	// L2 data cache size in KB	x70-x73
+-	u32	xDataL2CacheLineSize;	// L2 data cache block size	x74-x77
+-	u64	xRsvd5;			// Reserved			x78-x7F
+-
+-	u32	xDataL3CacheSizeKB;	// L3 data cache size in KB	x80-x83
+-	u32	xDataL3CacheLineSize;	// L3 data cache block size	x84-x87
+-	u64	xRsvd6;			// Reserved			x88-x8F
+-
+-	u64	xFruLabel;		// Card Location Label		x90-x97
+-	u8	xSlotsOnCard;		// Slots on card (0=no slots)	x98-x98
+-	u8	xPartLocFlag;		// Location flag (0-pluggable 1-imbedded) x99-x99
+-	u16	xSlotMapIndex;		// Index in slot map table	x9A-x9B
+-	u8	xSmartCardPortNo;	// Smart card port number	x9C-x9C
+-	u8	xRsvd7;			// Reserved			x9D-x9D
+-	u16	xFrameIdAndRackUnit;	// Frame ID and rack unit adr	x9E-x9F
+-
+-	u8	xRsvd8[24];		// Reserved			xA0-xB7
+-
+-	char	xProcSrc[72];		// CSP format SRC		xB8-xFF
+-};
+-
+-extern struct IoHriProcessorVpd	xIoHriProcessorVpd[];
+-
+-#endif /* _IOHRIPROCESSORVPD_H */
+diff --git a/include/asm-ppc64/iSeries/ItIplParmsReal.h b/include/asm-ppc64/iSeries/ItIplParmsReal.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/ItIplParmsReal.h
++++ /dev/null
+@@ -1,71 +0,0 @@
+-/*
+- * ItIplParmsReal.h
+- * Copyright (C) 2001  Mike Corrigan 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
+- */
+-#ifndef _ITIPLPARMSREAL_H
+-#define _ITIPLPARMSREAL_H
+-
+-/*
+- *	This struct maps the IPL Parameters DMA'd from the SP.
+- *
+- * Warning:
+- *	This data must map in exactly 64 bytes and match the architecture for
+- *	the IPL parms
+- */
+-
+-#include <asm/types.h>
+-
+-struct ItIplParmsReal {
+-	u8	xFormat;		// Defines format of IplParms	x00-x00
+-	u8	xRsvd01:6;		// Reserved			x01-x01
+-	u8	xAlternateSearch:1;	// Alternate search indicator	...
+-	u8	xUaSupplied:1;		// UA Supplied on programmed IPL...
+-	u8	xLsUaFormat;		// Format byte for UA		x02-x02
+-	u8	xRsvd02;		// Reserved			x03-x03
+-	u32	xLsUa;			// LS UA			x04-x07
+-	u32	xUnusedLsLid;		// First OS LID to load		x08-x0B
+-	u16	xLsBusNumber;		// LS Bus Number		x0C-x0D
+-	u8	xLsCardAdr;		// LS Card Address		x0E-x0E
+-	u8	xLsBoardAdr;		// LS Board Address		x0F-x0F
+-	u32	xRsvd03;		// Reserved			x10-x13
+-	u8	xSpcnPresent:1;		// SPCN present			x14-x14
+-	u8	xCpmPresent:1;		// CPM present			...
+-	u8	xRsvd04:6;		// Reserved			...
+-	u8	xRsvd05:4;		// Reserved			x15-x15
+-	u8	xKeyLock:4;		// Keylock setting		...
+-	u8	xRsvd06:6;		// Reserved			x16-x16
+-	u8	xIplMode:2;		// Ipl mode (A|B|C|D)		...
+-	u8	xHwIplType;		// Fast v slow v slow EC HW IPL	x17-x17
+-	u16	xCpmEnabledIpl:1;	// CPM in effect when IPL initiatedx18-x19
+-	u16	xPowerOnResetIpl:1;	// Indicate POR condition	...
+-	u16	xMainStorePreserved:1;	// Main Storage is preserved	...
+-	u16	xRsvd07:13;		// Reserved			...
+-	u16	xIplSource:16;		// Ipl source			x1A-x1B
+-	u8	xIplReason:8;		// Reason for this IPL		x1C-x1C
+-	u8	xRsvd08;		// Reserved			x1D-x1D
+-	u16	xRsvd09;		// Reserved			x1E-x1F
+-	u16	xSysBoxType;		// System Box Type		x20-x21
+-	u16	xSysProcType;		// System Processor Type	x22-x23
+-	u32	xRsvd10;		// Reserved			x24-x27
+-	u64	xRsvd11;		// Reserved			x28-x2F
+-	u64	xRsvd12;		// Reserved			x30-x37
+-	u64	xRsvd13;		// Reserved			x38-x3F
+-};
+-
+-extern struct ItIplParmsReal	xItIplParmsReal;
+-
+-#endif /* _ITIPLPARMSREAL_H */
+diff --git a/include/asm-ppc64/iSeries/ItSpCommArea.h b/include/asm-ppc64/iSeries/ItSpCommArea.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/ItSpCommArea.h
++++ /dev/null
+@@ -1,37 +0,0 @@
+-/*
+- * ItSpCommArea.h
+- * Copyright (C) 2001  Mike Corrigan 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
+- */
+-
+-#ifndef _ITSPCOMMAREA_H
+-#define _ITSPCOMMAREA_H
+-
+-
+-struct SpCommArea {
+-	u32	xDesc;			// Descriptor (only in new formats)	000-003
+-	u8	xFormat;		// Format (only in new formats)		004-004
+-	u8	xRsvd1[11];		// Reserved				005-00F
+-	u64	xRawTbAtIplStart;	// Raw HW TB value when IPL is started	010-017
+-	u64	xRawTodAtIplStart;	// Raw HW TOD value when IPL is started	018-01F
+-	u64	xBcdTimeAtIplStart;	// BCD time when IPL is started		020-027
+-	u64	xBcdTimeAtOsStart;	// BCD time when OS passed control	028-02F
+-	u8	xRsvd2[80];		// Reserved				030-07F
+-};
+-
+-extern struct SpCommArea xSpCommArea;
+-
+-#endif /* _ITSPCOMMAREA_H */
+diff --git a/include/asm-ppc64/iSeries/ItVpdAreas.h b/include/asm-ppc64/iSeries/ItVpdAreas.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/ItVpdAreas.h
++++ /dev/null
+@@ -1,89 +0,0 @@
+-/*
+- * ItVpdAreas.h
+- * Copyright (C) 2001  Mike Corrigan 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
+- */
+-#ifndef _ITVPDAREAS_H
+-#define _ITVPDAREAS_H
+-
+-/*
+- * This file defines the address and length of all of the VPD area passed to
+- * the OS from PLIC (most of which start from the SP).
+- */
+-
+-#include <asm/types.h>
+-
+-/* VPD Entry index is carved in stone - cannot be changed (easily). */
+-#define ItVpdCecVpd				0
+-#define ItVpdDynamicSpace			1
+-#define ItVpdExtVpd				2
+-#define ItVpdExtVpdOnPanel			3
+-#define ItVpdFirstPaca				4
+-#define ItVpdIoVpd				5
+-#define ItVpdIplParms				6
+-#define ItVpdMsVpd				7
+-#define ItVpdPanelVpd				8
+-#define ItVpdLpNaca				9
+-#define ItVpdBackplaneAndMaybeClockCardVpd	10
+-#define ItVpdRecoveryLogBuffer			11
+-#define ItVpdSpCommArea				12
+-#define ItVpdSpLogBuffer			13
+-#define ItVpdSpLogBufferSave			14
+-#define ItVpdSpCardVpd				15
+-#define ItVpdFirstProcVpd			16
+-#define ItVpdApModelVpd				17
+-#define ItVpdClockCardVpd			18
+-#define ItVpdBusExtCardVpd			19
+-#define ItVpdProcCapacityVpd			20
+-#define ItVpdInteractiveCapacityVpd		21
+-#define ItVpdFirstSlotLabel			22
+-#define ItVpdFirstLpQueue			23
+-#define ItVpdFirstL3CacheVpd			24
+-#define ItVpdFirstProcFruVpd			25
+-
+-#define ItVpdMaxEntries				26
+-
+-#define ItDmaMaxEntries				10
+-
+-#define ItVpdAreasMaxSlotLabels			192
+-
+-
+-struct ItVpdAreas {
+-	u32	xSlicDesc;		// Descriptor			000-003
+-	u16	xSlicSize;		// Size of this control block	004-005
+-	u16	xPlicAdjustVpdLens:1;	// Flag to indicate new interface006-007
+-	u16	xRsvd1:15;		// Reserved bits		...
+-	u16	xSlicVpdEntries;	// Number of VPD entries	008-009
+-	u16	xSlicDmaEntries;	// Number of DMA entries	00A-00B
+-	u16	xSlicMaxLogicalProcs;	// Maximum logical processors	00C-00D
+-	u16	xSlicMaxPhysicalProcs;	// Maximum physical processors	00E-00F
+-	u16	xSlicDmaToksOffset;	// Offset into this of array	010-011
+-	u16	xSlicVpdAdrsOffset;	// Offset into this of array	012-013
+-	u16	xSlicDmaLensOffset;	// Offset into this of array	014-015
+-	u16	xSlicVpdLensOffset;	// Offset into this of array	016-017
+-	u16	xSlicMaxSlotLabels;	// Maximum number of slot labels018-019
+-	u16	xSlicMaxLpQueues;	// Maximum number of LP Queues	01A-01B
+-	u8	xRsvd2[4];		// Reserved			01C-01F
+-	u64	xRsvd3[12];		// Reserved			020-07F
+-	u32	xPlicDmaLens[ItDmaMaxEntries];// Array of DMA lengths	080-0A7
+-	u32	xPlicDmaToks[ItDmaMaxEntries];// Array of DMA tokens	0A8-0CF
+-	u32	xSlicVpdLens[ItVpdMaxEntries];// Array of VPD lengths	0D0-12F
+-	void	*xSlicVpdAdrs[ItVpdMaxEntries];// Array of VPD buffers	130-1EF
+-};
+-
+-extern struct ItVpdAreas	itVpdAreas;
+-
+-#endif /* _ITVPDAREAS_H */
+diff --git a/include/asm-ppc64/iSeries/iSeries_irq.h b/include/asm-ppc64/iSeries/iSeries_irq.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/iSeries_irq.h
++++ /dev/null
+@@ -1,8 +0,0 @@
+-#ifndef	__ISERIES_IRQ_H__
+-#define	__ISERIES_IRQ_H__
+-
+-extern void iSeries_init_IRQ(void);
+-extern int  iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
+-extern void iSeries_activate_IRQs(void);
+-
+-#endif /* __ISERIES_IRQ_H__ */
+diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iSeries/iSeries_pci.h
++++ /dev/null
+@@ -1,88 +0,0 @@
+-#ifndef _ISERIES_64_PCI_H
+-#define _ISERIES_64_PCI_H
+-
+-/*
+- * File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001.
+- *
+- * Define some useful macros for the iSeries pci routines.
+- * Copyright (C) 2001  Allan H Trautman, 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
+- *
+- * Change Activity:
+- *   Created Feb 20, 2001
+- *   Added device reset, March 22, 2001
+- *   Ported to ppc64, May 25, 2001
+- * End Change Activity
+- */
+-
+-#include <asm/iSeries/HvCallPci.h>
+-#include <asm/abs_addr.h>
+-
+-struct pci_dev;				/* For Forward Reference */
+-struct iSeries_Device_Node;
+-
+-/*
+- * Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure
+- */
+-
+-#define ISERIES_BUS(DevPtr)	DevPtr->DsaAddr.Dsa.busNumber
+-#define ISERIES_SUBBUS(DevPtr)	DevPtr->DsaAddr.Dsa.subBusNumber
+-#define ISERIES_DEVICE(DevPtr)	DevPtr->DsaAddr.Dsa.deviceId
+-#define ISERIES_DSA(DevPtr)	DevPtr->DsaAddr.DsaAddr
+-#define ISERIES_DEVNODE(PciDev)	((struct iSeries_Device_Node *)PciDev->sysdata)
+-
+-#define EADsMaxAgents 7
+-
+-/*
+- * Decodes Linux DevFn to iSeries DevFn, bridge device, or function.
+- * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h
+- */
+-
+-#define ISERIES_PCI_AGENTID(idsel, func)	\
+-	(((idsel & 0x0F) << 4) | (func & 0x07))
+-#define ISERIES_ENCODE_DEVICE(agentid)		\
+-	((0x10) | ((agentid & 0x20) >> 2) | (agentid & 0x07))
+-
+-#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus)		((subbus >> 5) & 0x7)
+-#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)	((subbus >> 2) & 0x7)
+-
+-/*
+- * Converts Virtual Address to Real Address for Hypervisor calls
+- */
+-#define ISERIES_HV_ADDR(virtaddr)	\
+-	(0x8000000000000000 | virt_to_abs(virtaddr))
+-
+-/*
+- * iSeries Device Information
+- */
+-struct iSeries_Device_Node {
+-	struct list_head Device_List;
+-	struct pci_dev	*PciDev;
+-	union HvDsaMap	DsaAddr;	/* Direct Select Address */
+-					/* busNumber, subBusNumber, */
+-					/* deviceId, barNumber */
+-	int		DevFn;		/* Linux devfn */
+-	int		Irq;		/* Assigned IRQ */
+-	int		Flags;		/* Possible flags(disable/bist)*/
+-	u8		LogicalSlot;	/* Hv Slot Index for Tces */
+-	struct iommu_table *iommu_table;/* Device TCE Table */
+-};
+-
+-extern void	iSeries_Device_Information(struct pci_dev*, int);
+-
+-#endif /* _ISERIES_64_PCI_H */
+diff --git a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h
+--- a/include/asm-ppc64/io.h
++++ b/include/asm-ppc64/io.h
+@@ -15,7 +15,7 @@
+ #ifdef CONFIG_PPC_ISERIES 
+ #include <asm/iSeries/iSeries_io.h>
+ #endif  
+-#include <asm/memory.h>
++#include <asm/synch.h>
+ #include <asm/delay.h>
+ 
+ #include <asm-generic/iomap.h>
+diff --git a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h
+deleted file mode 100644
+--- a/include/asm-ppc64/iommu.h
++++ /dev/null
+@@ -1,146 +0,0 @@
+-/*
+- * iommu.h
+- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+- * Rewrite, cleanup:
+- * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, 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
+- */
+-
+-#ifndef _ASM_IOMMU_H
+-#define _ASM_IOMMU_H
+-
+-#include <asm/types.h>
+-#include <linux/spinlock.h>
+-#include <linux/device.h>
+-#include <linux/dma-mapping.h>
+-
+-/*
+- * IOMAP_MAX_ORDER defines the largest contiguous block
+- * of dma (tce) space we can get.  IOMAP_MAX_ORDER = 13
+- * allows up to 2**12 pages (4096 * 4096) = 16 MB
+- */
+-#define IOMAP_MAX_ORDER 13
+-
+-/*
+- * Tces come in two formats, one for the virtual bus and a different
+- * format for PCI
+- */
+-#define TCE_VB  0
+-#define TCE_PCI 1
+-
+-/* tce_entry
+- * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
+- * abstracted so layout is irrelevant.
+- */
+-union tce_entry {
+-   	unsigned long te_word;
+-	struct {
+-		unsigned int  tb_cacheBits :6;	/* Cache hash bits - not used */
+-		unsigned int  tb_rsvd      :6;
+-		unsigned long tb_rpn       :40;	/* Real page number */
+-		unsigned int  tb_valid     :1;	/* Tce is valid (vb only) */
+-		unsigned int  tb_allio     :1;	/* Tce is valid for all lps (vb only) */
+-		unsigned int  tb_lpindex   :8;	/* LpIndex for user of TCE (vb only) */
+-		unsigned int  tb_pciwr     :1;	/* Write allowed (pci only) */
+-		unsigned int  tb_rdwr      :1;	/* Read allowed  (pci), Write allowed (vb) */
+-	} te_bits;
+-#define te_cacheBits te_bits.tb_cacheBits
+-#define te_rpn       te_bits.tb_rpn
+-#define te_valid     te_bits.tb_valid
+-#define te_allio     te_bits.tb_allio
+-#define te_lpindex   te_bits.tb_lpindex
+-#define te_pciwr     te_bits.tb_pciwr
+-#define te_rdwr      te_bits.tb_rdwr
+-};
+-
+-
+-struct iommu_table {
+-	unsigned long  it_busno;     /* Bus number this table belongs to */
+-	unsigned long  it_size;      /* Size of iommu table in entries */
+-	unsigned long  it_offset;    /* Offset into global table */
+-	unsigned long  it_base;      /* mapped address of tce table */
+-	unsigned long  it_index;     /* which iommu table this is */
+-	unsigned long  it_type;      /* type: PCI or Virtual Bus */
+-	unsigned long  it_blocksize; /* Entries in each block (cacheline) */
+-	unsigned long  it_hint;      /* Hint for next alloc */
+-	unsigned long  it_largehint; /* Hint for large allocs */
+-	unsigned long  it_halfpoint; /* Breaking point for small/large allocs */
+-	spinlock_t     it_lock;      /* Protects it_map */
+-	unsigned long *it_map;       /* A simple allocation bitmap for now */
+-};
+-
+-struct scatterlist;
+-
+-#ifdef CONFIG_PPC_MULTIPLATFORM
+-
+-/* Walks all buses and creates iommu tables */
+-extern void iommu_setup_pSeries(void);
+-extern void iommu_setup_u3(void);
+-
+-/* Frees table for an individual device node */
+-extern void iommu_free_table(struct device_node *dn);
+-
+-#endif /* CONFIG_PPC_MULTIPLATFORM */
+-
+-#ifdef CONFIG_PPC_PSERIES
+-
+-/* Creates table for an individual device node */
+-extern void iommu_devnode_init_pSeries(struct device_node *dn);
+-
+-#endif /* CONFIG_PPC_PSERIES */
+-
+-#ifdef CONFIG_PPC_ISERIES
+-
+-struct iSeries_Device_Node;
+-/* Creates table for an individual device node */
+-extern void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn);
+-
+-#endif /* CONFIG_PPC_ISERIES */
+-
+-/* Initializes an iommu_table based in values set in the passed-in
+- * structure
+- */
+-extern struct iommu_table *iommu_init_table(struct iommu_table * tbl);
+-
+-extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
+-		struct scatterlist *sglist, int nelems,
+-		enum dma_data_direction direction);
+-extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
+-		int nelems, enum dma_data_direction direction);
+-
+-extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
+-		dma_addr_t *dma_handle, gfp_t flag);
+-extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
+-		void *vaddr, dma_addr_t dma_handle);
+-extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
+-		size_t size, enum dma_data_direction direction);
+-extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
+-		size_t size, enum dma_data_direction direction);
+-
+-extern void iommu_init_early_pSeries(void);
+-extern void iommu_init_early_iSeries(void);
+-extern void iommu_init_early_u3(void);
+-
+-#ifdef CONFIG_PCI
+-extern void pci_iommu_init(void);
+-extern void pci_direct_iommu_init(void);
+-#else
+-static inline void pci_iommu_init(void) { }
+-#endif
+-
+-extern void alloc_u3_dart_table(void);
+-
+-#endif /* _ASM_IOMMU_H */
+diff --git a/include/asm-ppc64/irq.h b/include/asm-ppc64/irq.h
+deleted file mode 100644
+--- a/include/asm-ppc64/irq.h
++++ /dev/null
+@@ -1,120 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef _ASM_IRQ_H
+-#define _ASM_IRQ_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.
+- */
+-
+-#include <linux/config.h>
+-#include <linux/threads.h>
+-
+-/*
+- * Maximum number of interrupt sources that we can handle.
+- */
+-#define NR_IRQS		512
+-
+-/* this number is used when no interrupt has been assigned */
+-#define NO_IRQ			(-1)
+-
+-/*
+- * These constants are used for passing information about interrupt
+- * signal polarity and level/edge sensing to the low-level PIC chip
+- * drivers.
+- */
+-#define IRQ_SENSE_MASK		0x1
+-#define IRQ_SENSE_LEVEL		0x1	/* interrupt on active level */
+-#define IRQ_SENSE_EDGE		0x0	/* interrupt triggered by edge */
+-
+-#define IRQ_POLARITY_MASK	0x2
+-#define IRQ_POLARITY_POSITIVE	0x2	/* high level or low->high edge */
+-#define IRQ_POLARITY_NEGATIVE	0x0	/* low level or high->low edge */
+-
+-/*
+- * IRQ line status macro IRQ_PER_CPU is used
+- */
+-#define ARCH_HAS_IRQ_PER_CPU
+-
+-#define get_irq_desc(irq) (&irq_desc[(irq)])
+-
+-/* Define a way to iterate across irqs. */
+-#define for_each_irq(i) \
+-	for ((i) = 0; (i) < NR_IRQS; ++(i))
+-
+-/* Interrupt numbers are virtual in case they are sparsely
+- * distributed by the hardware.
+- */
+-extern unsigned int virt_irq_to_real_map[NR_IRQS];
+-
+-/* Create a mapping for a real_irq if it doesn't already exist.
+- * Return the virtual irq as a convenience.
+- */
+-int virt_irq_create_mapping(unsigned int real_irq);
+-void virt_irq_init(void);
+-
+-static inline unsigned int virt_irq_to_real(unsigned int virt_irq)
+-{
+-	return virt_irq_to_real_map[virt_irq];
+-}
+-
+-extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq);
+-
+-/*
+- * Because many systems have two overlapping names spaces for
+- * interrupts (ISA and XICS for example), and the ISA interrupts
+- * have historically not been easy to renumber, we allow ISA
+- * interrupts to take values 0 - 15, and shift up the remaining
+- * interrupts by 0x10.
+- */
+-#define NUM_ISA_INTERRUPTS	0x10
+-extern int __irq_offset_value;
+-
+-static inline int irq_offset_up(int irq)
+-{
+-	return(irq + __irq_offset_value);
+-}
+-
+-static inline int irq_offset_down(int irq)
+-{
+-	return(irq - __irq_offset_value);
+-}
+-
+-static inline int irq_offset_value(void)
+-{
+-	return __irq_offset_value;
+-}
+-
+-static __inline__ int irq_canonicalize(int irq)
+-{
+-	return irq;
+-}
+-
+-extern int distribute_irqs;
+-
+-struct irqaction;
+-struct pt_regs;
+-
+-#ifdef CONFIG_IRQSTACKS
+-/*
+- * Per-cpu stacks for handling hard and soft interrupts.
+- */
+-extern struct thread_info *hardirq_ctx[NR_CPUS];
+-extern struct thread_info *softirq_ctx[NR_CPUS];
+-
+-extern void irq_ctx_init(void);
+-extern void call_do_softirq(struct thread_info *tp);
+-extern int call_handle_IRQ_event(int irq, struct pt_regs *regs,
+-			struct irqaction *action, struct thread_info *tp);
+-
+-#define __ARCH_HAS_DO_SOFTIRQ
+-
+-#else
+-#define irq_ctx_init()
+-
+-#endif /* CONFIG_IRQSTACKS */
+-
+-#endif /* _ASM_IRQ_H */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc64/kdebug.h b/include/asm-ppc64/kdebug.h
+deleted file mode 100644
+--- a/include/asm-ppc64/kdebug.h
++++ /dev/null
+@@ -1,43 +0,0 @@
+-#ifndef _PPC64_KDEBUG_H
+-#define _PPC64_KDEBUG_H 1
+-
+-/* nearly identical to x86_64/i386 code */
+-
+-#include <linux/notifier.h>
+-
+-struct pt_regs;
+-
+-struct die_args {
+-	struct pt_regs *regs;
+-	const char *str;
+-	long err;
+-	int trapnr;
+-	int signr;
+-};
+-
+-/*
+-   Note - you should never unregister because that can race with NMIs.
+-   If you really want to do it first unregister - then synchronize_sched -
+-   then free.
+- */
+-int register_die_notifier(struct notifier_block *nb);
+-extern struct notifier_block *ppc64_die_chain;
+-
+-/* Grossly misnamed. */
+-enum die_val {
+-	DIE_OOPS = 1,
+-	DIE_IABR_MATCH,
+-	DIE_DABR_MATCH,
+-	DIE_BPT,
+-	DIE_SSTEP,
+-	DIE_GPF,
+-	DIE_PAGE_FAULT,
+-};
+-
+-static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
+-{
+-	struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig };
+-	return notifier_call_chain(&ppc64_die_chain, val, &args);
+-}
+-
+-#endif
+diff --git a/include/asm-ppc64/keylargo.h b/include/asm-ppc64/keylargo.h
+deleted file mode 100644
+--- a/include/asm-ppc64/keylargo.h
++++ /dev/null
+@@ -1,2 +0,0 @@
+-#include <asm-ppc/keylargo.h>
+-
+diff --git a/include/asm-ppc64/kmap_types.h b/include/asm-ppc64/kmap_types.h
+deleted file mode 100644
+--- a/include/asm-ppc64/kmap_types.h
++++ /dev/null
+@@ -1,23 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef _ASM_KMAP_TYPES_H
+-#define _ASM_KMAP_TYPES_H
+-
+-enum km_type {
+-	KM_BOUNCE_READ,
+-	KM_SKB_SUNRPC_DATA,
+-	KM_SKB_DATA_SOFTIRQ,
+-	KM_USER0,
+-	KM_USER1,
+-	KM_BIO_SRC_IRQ,
+-	KM_BIO_DST_IRQ,
+-	KM_PTE0,
+-	KM_PTE1,
+-	KM_IRQ0,
+-	KM_IRQ1,
+-	KM_SOFTIRQ0,
+-	KM_SOFTIRQ1,	
+-	KM_TYPE_NR
+-};
+-
+-#endif
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc64/kprobes.h b/include/asm-ppc64/kprobes.h
+deleted file mode 100644
+--- a/include/asm-ppc64/kprobes.h
++++ /dev/null
+@@ -1,67 +0,0 @@
+-#ifndef _ASM_KPROBES_H
+-#define _ASM_KPROBES_H
+-/*
+- *  Kernel Probes (KProbes)
+- *  include/asm-ppc64/kprobes.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.
+- *
+- * Copyright (C) IBM Corporation, 2002, 2004
+- *
+- * 2002-Oct	Created by Vamsi Krishna S <vamsi_krishna at in.ibm.com> Kernel
+- *		Probes initial implementation ( includes suggestions from
+- *		Rusty Russell).
+- * 2004-Nov	Modified for PPC64 by Ananth N Mavinakayanahalli
+- *		<ananth at in.ibm.com>
+- */
+-#include <linux/types.h>
+-#include <linux/ptrace.h>
+-
+-struct pt_regs;
+-
+-typedef unsigned int kprobe_opcode_t;
+-#define BREAKPOINT_INSTRUCTION	0x7fe00008	/* trap */
+-#define MAX_INSN_SIZE 1
+-
+-#define IS_TW(instr)		(((instr) & 0xfc0007fe) == 0x7c000008)
+-#define IS_TD(instr)		(((instr) & 0xfc0007fe) == 0x7c000088)
+-#define IS_TDI(instr)		(((instr) & 0xfc000000) == 0x08000000)
+-#define IS_TWI(instr)		(((instr) & 0xfc000000) == 0x0c000000)
+-
+-#define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)((func_descr_t *)pentry)
+-
+-#define is_trap(instr)	(IS_TW(instr) || IS_TD(instr) || \
+-			IS_TWI(instr) || IS_TDI(instr))
+-
+-#define ARCH_SUPPORTS_KRETPROBES
+-void kretprobe_trampoline(void);
+-
+-/* Architecture specific copy of original instruction */
+-struct arch_specific_insn {
+-	/* copy of original instruction */
+-	kprobe_opcode_t *insn;
+-};
+-
+-#ifdef CONFIG_KPROBES
+-extern int kprobe_exceptions_notify(struct notifier_block *self,
+-				    unsigned long val, void *data);
+-#else				/* !CONFIG_KPROBES */
+-static inline int kprobe_exceptions_notify(struct notifier_block *self,
+-					   unsigned long val, void *data)
+-{
+-	return 0;
+-}
+-#endif
+-#endif				/* _ASM_KPROBES_H */
+diff --git a/include/asm-ppc64/lmb.h b/include/asm-ppc64/lmb.h
+deleted file mode 100644
+--- a/include/asm-ppc64/lmb.h
++++ /dev/null
+@@ -1,81 +0,0 @@
+-#ifndef _PPC64_LMB_H
+-#define _PPC64_LMB_H
+-
+-/*
+- * Definitions for talking to the Open Firmware PROM on
+- * Power Macintosh computers.
+- *
+- * Copyright (C) 2001 Peter Bergner, IBM Corp.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-#include <linux/init.h>
+-#include <asm/prom.h>
+-
+-#define MAX_LMB_REGIONS 128
+-
+-#define LMB_ALLOC_ANYWHERE	0
+-
+-struct lmb_property {
+-	unsigned long base;
+-	unsigned long size;
+-};
+-
+-struct lmb_region {
+-	unsigned long cnt;
+-	unsigned long size;
+-	struct lmb_property region[MAX_LMB_REGIONS+1];
+-};
+-
+-struct lmb {
+-	unsigned long debug;
+-	unsigned long rmo_size;
+-	struct lmb_region memory;
+-	struct lmb_region reserved;
+-};
+-
+-extern struct lmb lmb;
+-
+-extern void __init lmb_init(void);
+-extern void __init lmb_analyze(void);
+-extern long __init lmb_add(unsigned long, unsigned long);
+-extern long __init lmb_reserve(unsigned long, unsigned long);
+-extern unsigned long __init lmb_alloc(unsigned long, unsigned long);
+-extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long,
+-					   unsigned long);
+-extern unsigned long __init lmb_phys_mem_size(void);
+-extern unsigned long __init lmb_end_of_DRAM(void);
+-extern unsigned long __init lmb_abs_to_phys(unsigned long);
+-extern void __init lmb_enforce_memory_limit(void);
+-
+-extern void lmb_dump_all(void);
+-
+-extern unsigned long io_hole_start;
+-
+-static inline unsigned long
+-lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
+-{
+-	return type->region[region_nr].size;
+-}
+-static inline unsigned long
+-lmb_size_pages(struct lmb_region *type, unsigned long region_nr)
+-{
+-	return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT;
+-}
+-static inline unsigned long
+-lmb_start_pfn(struct lmb_region *type, unsigned long region_nr)
+-{
+-	return type->region[region_nr].base >> PAGE_SHIFT;
+-}
+-static inline unsigned long
+-lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
+-{
+-	return lmb_start_pfn(type, region_nr) +
+-	       lmb_size_pages(type, region_nr);
+-}
+-
+-#endif /* _PPC64_LMB_H */
+diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
+deleted file mode 100644
+--- a/include/asm-ppc64/machdep.h
++++ /dev/null
+@@ -1,185 +0,0 @@
+-#ifdef __KERNEL__
+-#ifndef _PPC64_MACHDEP_H
+-#define _PPC64_MACHDEP_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.
+- */
+-
+-#include <linux/config.h>
+-#include <linux/seq_file.h>
+-#include <linux/init.h>
+-#include <linux/dma-mapping.h>
+-
+-#include <asm/setup.h>
+-
+-struct pt_regs;
+-struct pci_bus;	
+-struct device_node;
+-struct iommu_table;
+-struct rtc_time;
+-struct file;
+-
+-#ifdef CONFIG_SMP
+-struct smp_ops_t {
+-	void  (*message_pass)(int target, int msg);
+-	int   (*probe)(void);
+-	void  (*kick_cpu)(int nr);
+-	void  (*setup_cpu)(int nr);
+-	void  (*take_timebase)(void);
+-	void  (*give_timebase)(void);
+-	int   (*cpu_enable)(unsigned int nr);
+-	int   (*cpu_disable)(void);
+-	void  (*cpu_die)(unsigned int nr);
+-	int   (*cpu_bootable)(unsigned int nr);
+-};
+-#endif
+-
+-struct machdep_calls {
+-	void            (*hpte_invalidate)(unsigned long slot,
+-					   unsigned long va,
+-					   int large,
+-					   int local);
+-	long		(*hpte_updatepp)(unsigned long slot, 
+-					 unsigned long newpp, 
+-					 unsigned long va,
+-					 int large,
+-					 int local);
+-	void            (*hpte_updateboltedpp)(unsigned long newpp, 
+-					       unsigned long ea);
+-	long		(*hpte_insert)(unsigned long hpte_group,
+-				       unsigned long va,
+-				       unsigned long prpn,
+-				       unsigned long vflags,
+-				       unsigned long rflags);
+-	long		(*hpte_remove)(unsigned long hpte_group);
+-	void		(*flush_hash_range)(unsigned long context,
+-					    unsigned long number,
+-					    int local);
+-	/* special for kexec, to be called in real mode, linar mapping is
+-	 * destroyed as well */
+-	void		(*hpte_clear_all)(void);
+-
+-	void		(*tce_build)(struct iommu_table * tbl,
+-				     long index,
+-				     long npages,
+-				     unsigned long uaddr,
+-				     enum dma_data_direction direction);
+-	void		(*tce_free)(struct iommu_table *tbl,
+-				    long index,
+-				    long npages);
+-	void		(*tce_flush)(struct iommu_table *tbl);
+-	void		(*iommu_dev_setup)(struct pci_dev *dev);
+-	void		(*iommu_bus_setup)(struct pci_bus *bus);
+-	void		(*irq_bus_setup)(struct pci_bus *bus);
+-
+-	int		(*probe)(int platform);
+-	void		(*setup_arch)(void);
+-	void		(*init_early)(void);
+-	/* Optional, may be NULL. */
+-	void		(*get_cpuinfo)(struct seq_file *m);
+-
+-	void		(*init_IRQ)(void);
+-	int		(*get_irq)(struct pt_regs *);
+-	void		(*cpu_irq_down)(int secondary);
+-
+-	/* PCI stuff */
+-	void		(*pcibios_fixup)(void);
+-	int		(*pci_probe_mode)(struct pci_bus *);
+-
+-	void		(*restart)(char *cmd);
+-	void		(*power_off)(void);
+-	void		(*halt)(void);
+-	void		(*panic)(char *str);
+-	void		(*cpu_die)(void);
+-
+-	int		(*set_rtc_time)(struct rtc_time *);
+-	void		(*get_rtc_time)(struct rtc_time *);
+-	void		(*get_boot_time)(struct rtc_time *);
+-
+-	void		(*calibrate_decr)(void);
+-
+-	void		(*progress)(char *, unsigned short);
+-
+-	/* Interface for platform error logging */
+-	void 		(*log_error)(char *buf, unsigned int err_type, int fatal);
+-
+-	ssize_t		(*nvram_write)(char *buf, size_t count, loff_t *index);
+-	ssize_t		(*nvram_read)(char *buf, size_t count, loff_t *index);	
+-	ssize_t		(*nvram_size)(void);		
+-	int		(*nvram_sync)(void);
+-
+-	/* Exception handlers */
+-	void		(*system_reset_exception)(struct pt_regs *regs);
+-	int 		(*machine_check_exception)(struct pt_regs *regs);
+-
+-	/* Motherboard/chipset features. This is a kind of general purpose
+-	 * hook used to control some machine specific features (like reset
+-	 * lines, chip power control, etc...).
+-	 */
+-	long	 	(*feature_call)(unsigned int feature, ...);
+-
+-	/* Check availability of legacy devices like i8042 */
+-	int 		(*check_legacy_ioport)(unsigned int baseport);
+-
+-	/* Get legacy PCI/IDE interrupt mapping */ 
+-	int		(*pci_get_legacy_ide_irq)(struct pci_dev *dev, int channel);
+-	
+-	/* Get access protection for /dev/mem */
+-	pgprot_t	(*phys_mem_access_prot)(struct file *file,
+-						unsigned long offset,
+-						unsigned long size,
+-						pgprot_t vma_prot);
+-
+-	/* Idle loop for this platform, leave empty for default idle loop */
+-	int		(*idle_loop)(void);
+-
+-	/* Function to enable pmcs for this platform, called once per cpu. */
+-	void		(*enable_pmcs)(void);
+-};
+-
+-extern int default_idle(void);
+-extern int native_idle(void);
+-
+-extern struct machdep_calls ppc_md;
+-extern char cmd_line[COMMAND_LINE_SIZE];
+-
+-#ifdef CONFIG_PPC_PMAC
+-/*
+- * Power macintoshes have either a CUDA, PMU or SMU controlling
+- * system reset, power, NVRAM, RTC.
+- */
+-typedef enum sys_ctrler_kind {
+-	SYS_CTRLER_UNKNOWN = 0,
+-	SYS_CTRLER_CUDA = 1,
+-	SYS_CTRLER_PMU = 2,
+-	SYS_CTRLER_SMU = 3,
+-} sys_ctrler_t;
+-extern sys_ctrler_t sys_ctrler;
+-
+-#endif /* CONFIG_PPC_PMAC */
+-
+-
+-
+-/* Functions to produce codes on the leds.
+- * The SRC code should be unique for the message category and should
+- * be limited to the lower 24 bits (the upper 8 are set by these funcs),
+- * and (for boot & dump) should be sorted numerically in the order
+- * the events occur.
+- */
+-/* Print a boot progress message. */
+-void ppc64_boot_msg(unsigned int src, const char *msg);
+-/* Print a termination message (print only -- does not stop the kernel) */
+-void ppc64_terminate_msg(unsigned int src, const char *msg);
+-
+-static inline void log_error(char *buf, unsigned int err_type, int fatal)
+-{
+-	if (ppc_md.log_error)
+-		ppc_md.log_error(buf, err_type, fatal);
+-}
+-
+-#endif /* _PPC64_MACHDEP_H */
+-#endif /* __KERNEL__ */
+diff --git a/include/asm-ppc64/macio.h b/include/asm-ppc64/macio.h
+deleted file mode 100644
+--- a/include/asm-ppc64/macio.h
++++ /dev/null
+@@ -1,2 +0,0 @@
+-#include <asm-ppc/macio.h>
+-
+diff --git a/include/asm-ppc64/memory.h b/include/asm-ppc64/memory.h
+deleted file mode 100644
+--- a/include/asm-ppc64/memory.h
++++ /dev/null
+@@ -1,61 +0,0 @@
+-#ifndef _ASM_PPC64_MEMORY_H_ 
+-#define _ASM_PPC64_MEMORY_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.
+- */
+-
+-#include <linux/config.h>
+-
+-/*
+- * Arguably the bitops and *xchg operations don't imply any memory barrier
+- * or SMP ordering, but in fact a lot of drivers expect them to imply
+- * both, since they do on x86 cpus.
+- */
+-#ifdef CONFIG_SMP
+-#define EIEIO_ON_SMP	"eieio\n"
+-#define ISYNC_ON_SMP	"\n\tisync"
+-#define SYNC_ON_SMP	"lwsync\n\t"
+-#else
+-#define EIEIO_ON_SMP
+-#define ISYNC_ON_SMP
+-#define SYNC_ON_SMP
+-#endif
+-
+-static inline void eieio(void)
+-{
+-	__asm__ __volatile__ ("eieio" : : : "memory");
+-}
+-
+-static inline void isync(void)
+-{
+-	__asm__ __volatile__ ("isync" : : : "memory");
+-}
+-
+-#ifdef CONFIG_SMP
+-#define eieio_on_smp()	eieio()
+-#define isync_on_smp()	isync()
+-#else
+-#define eieio_on_smp()	__asm__ __volatile__("": : :"memory")
+-#define isync_on_smp()	__asm__ __volatile__("": : :"memory")
+-#endif
+-
+-/* Macros for adjusting thread priority (hardware multi-threading) */
+-#define HMT_very_low()    asm volatile("or 31,31,31   # very low priority")
+-#define HMT_low()	asm volatile("or 1,1,1		# low priority")
+-#define HMT_medium_low()  asm volatile("or 6,6,6      # medium low priority")
+-#define HMT_medium()	asm volatile("or 2,2,2		# medium priority")
+-#define HMT_medium_high() asm volatile("or 5,5,5      # medium high priority")
+-#define HMT_high()	asm volatile("or 3,3,3		# high priority")
+-
+-#define HMT_VERY_LOW    "\tor   31,31,31        # very low priority\n"
+-#define HMT_LOW		"\tor	1,1,1		# low priority\n"
+-#define HMT_MEDIUM_LOW  "\tor   6,6,6           # medium low priority\n"
+-#define HMT_MEDIUM	"\tor	2,2,2		# medium priority\n"
+-#define HMT_MEDIUM_HIGH "\tor   5,5,5           # medium high priority\n"
+-#define HMT_HIGH	"\tor	3,3,3		# high priority\n"
+-
+-#endif
+diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
+--- a/include/asm-ppc64/mmu.h
++++ b/include/asm-ppc64/mmu.h
+@@ -14,6 +14,7 @@
+ #define _PPC64_MMU_H_
+ 
+ #include <linux/config.h>
++#include <asm/ppc_asm.h> /* for ASM_CONST */
+ #include <asm/page.h>
+ 
+ /*
+@@ -29,7 +30,7 @@
+ 
+ /* Location of cpu0's segment table */
+ #define STAB0_PAGE	0x6
+-#define STAB0_PHYS_ADDR	(STAB0_PAGE<<PAGE_SHIFT)
++#define STAB0_PHYS_ADDR	(STAB0_PAGE<<12)
+ 
+ #ifndef __ASSEMBLY__
+ extern char initial_stab[];
+@@ -205,6 +206,10 @@ extern long native_hpte_insert(unsigned 
+ 			       unsigned long prpn,
+ 			       unsigned long vflags, unsigned long rflags);
+ 
++extern long iSeries_hpte_bolt_or_insert(unsigned long hpte_group,
++		unsigned long va, unsigned long prpn,
++		unsigned long vflags, unsigned long rflags);
++
+ extern void stabs_alloc(void);
+ 
+ #endif /* __ASSEMBLY__ */
+diff --git a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h
+--- a/include/asm-ppc64/mmzone.h
++++ b/include/asm-ppc64/mmzone.h
+@@ -67,9 +67,6 @@ static inline int pa_to_nid(unsigned lon
+ #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
+ #define node_end_pfn(nid)	(NODE_DATA(nid)->node_end_pfn)
+ 
+-#define local_mapnr(kvaddr) \
+-	( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) 
+-
+ #ifdef CONFIG_DISCONTIGMEM
+ 
+ /*
+diff --git a/include/asm-ppc64/of_device.h b/include/asm-ppc64/of_device.h
+deleted file mode 100644
+--- a/include/asm-ppc64/of_device.h
++++ /dev/null
+@@ -1,2 +0,0 @@
+-#include <asm-ppc/of_device.h>
+-
+diff --git a/include/asm-ppc64/oprofile_impl.h b/include/asm-ppc64/oprofile_impl.h
+deleted file mode 100644
+--- a/include/asm-ppc64/oprofile_impl.h
++++ /dev/null
+@@ -1,111 +0,0 @@
+-/*
+- * Copyright (C) 2004 Anton Blanchard <anton at au.ibm.com>, IBM
+- *
+- * Based on alpha version.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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 OP_IMPL_H
+-#define OP_IMPL_H 1
+-
+-#define OP_MAX_COUNTER 8
+-
+-/* Per-counter configuration as set via oprofilefs.  */
+-struct op_counter_config {
+-	unsigned long valid;
+-	unsigned long enabled;
+-	unsigned long event;
+-	unsigned long count;
+-	unsigned long kernel;
+-	/* We dont support per counter user/kernel selection */
+-	unsigned long user;
+-	unsigned long unit_mask;
+-};
+-
+-/* System-wide configuration as set via oprofilefs.  */
+-struct op_system_config {
+-	unsigned long mmcr0;
+-	unsigned long mmcr1;
+-	unsigned long mmcra;
+-	unsigned long enable_kernel;
+-	unsigned long enable_user;
+-	unsigned long backtrace_spinlocks;
+-};
+-
+-/* Per-arch configuration */
+-struct op_ppc64_model {
+-	void (*reg_setup) (struct op_counter_config *,
+-			   struct op_system_config *,
+-			   int num_counters);
+-	void (*cpu_setup) (void *);
+-	void (*start) (struct op_counter_config *);
+-	void (*stop) (void);
+-	void (*handle_interrupt) (struct pt_regs *,
+-				  struct op_counter_config *);
+-	int num_counters;
+-};
+-
+-extern struct op_ppc64_model op_model_rs64;
+-extern struct op_ppc64_model op_model_power4;
+-
+-static inline unsigned int ctr_read(unsigned int i)
+-{
+-	switch(i) {
+-	case 0:
+-		return mfspr(SPRN_PMC1);
+-	case 1:
+-		return mfspr(SPRN_PMC2);
+-	case 2:
+-		return mfspr(SPRN_PMC3);
+-	case 3:
+-		return mfspr(SPRN_PMC4);
+-	case 4:
+-		return mfspr(SPRN_PMC5);
+-	case 5:
+-		return mfspr(SPRN_PMC6);
+-	case 6:
+-		return mfspr(SPRN_PMC7);
+-	case 7:
+-		return mfspr(SPRN_PMC8);
+-	default:
+-		return 0;
+-	}
+-}
+-
+-static inline void ctr_write(unsigned int i, unsigned int val)
+-{
+-	switch(i) {
+-	case 0:
+-		mtspr(SPRN_PMC1, val);
+-		break;
+-	case 1:
+-		mtspr(SPRN_PMC2, val);
+-		break;
+-	case 2:
+-		mtspr(SPRN_PMC3, val);
+-		break;
+-	case 3:
+-		mtspr(SPRN_PMC4, val);
+-		break;
+-	case 4:
+-		mtspr(SPRN_PMC5, val);
+-		break;
+-	case 5:
+-		mtspr(SPRN_PMC6, val);
+-		break;
+-	case 6:
+-		mtspr(SPRN_PMC7, val);
+-		break;
+-	case 7:
+-		mtspr(SPRN_PMC8, val);
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-
+-#endif
+diff --git a/include/asm-ppc64/pSeries_reconfig.h b/include/asm-ppc64/pSeries_reconfig.h
+deleted file mode 100644
+--- a/include/asm-ppc64/pSeries_reconfig.h
++++ /dev/null
+@@ -1,25 +0,0 @@
+-#ifndef _PPC64_PSERIES_RECONFIG_H
+-#define _PPC64_PSERIES_RECONFIG_H
+-
+-#include <linux/notifier.h>
+-
+-/*
+- * Use this API if your code needs to know about OF device nodes being
+- * added or removed on pSeries systems.
+- */
+-
+-#define PSERIES_RECONFIG_ADD    0x0001
+-#define PSERIES_RECONFIG_REMOVE 0x0002
+-
+-#ifdef CONFIG_PPC_PSERIES
+-extern int pSeries_reconfig_notifier_register(struct notifier_block *);
+-extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
+-#else /* !CONFIG_PPC_PSERIES */
+-static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
+-{
+-	return 0;
+-}
+-static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { }
+-#endif /* CONFIG_PPC_PSERIES */
+-
+-#endif /* _PPC64_PSERIES_RECONFIG_H */
+diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
+--- a/include/asm-ppc64/page.h
++++ b/include/asm-ppc64/page.h
+@@ -11,13 +11,7 @@
+  */
+ 
+ #include <linux/config.h>
+-
+-#ifdef __ASSEMBLY__
+-  #define ASM_CONST(x) x
+-#else
+-  #define __ASM_CONST(x) x##UL
+-  #define ASM_CONST(x) __ASM_CONST(x)
+-#endif
++#include <asm/ppc_asm.h> /* for ASM_CONST */
+ 
+ /* PAGE_SHIFT determines the page size */
+ #define PAGE_SHIFT	12
+diff --git a/include/asm-ppc64/parport.h b/include/asm-ppc64/parport.h
+deleted file mode 100644
+--- a/include/asm-ppc64/parport.h
++++ /dev/null
+@@ -1,18 +0,0 @@
+-/*
+- * parport.h: platform-specific PC-style parport initialisation
+- *
+- * Copyright (C) 1999, 2000  Tim Waugh <tim at cyberelk.demon.co.uk>
+- *
+- * This file should only be included by drivers/parport/parport_pc.c.
+- */
+-
+-#ifndef _ASM_PPC64_PARPORT_H
+-#define _ASM_PPC64_PARPORT_H
+-
+-static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
+-static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
+-{
+-	return parport_pc_find_isa_ports (autoirq, autodma);
+-}
+-
+-#endif /* !(_ASM_PPC_PARPORT_H) */
+diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h
+--- a/include/asm-ppc64/pci-bridge.h
++++ b/include/asm-ppc64/pci-bridge.h
+@@ -2,7 +2,9 @@
+ #ifndef _ASM_PCI_BRIDGE_H
+ #define _ASM_PCI_BRIDGE_H
+ 
++#include <linux/config.h>
+ #include <linux/pci.h>
++#include <linux/list.h>
+ 
+ /*
+  * This program is free software; you can redistribute it and/or
+@@ -34,7 +36,7 @@ struct pci_controller {
+ 
+ 	struct pci_ops *ops;
+ 	volatile unsigned int __iomem *cfg_addr;
+-	volatile unsigned char __iomem *cfg_data;
++	volatile void __iomem *cfg_data;
+ 
+ 	/* Currently, we limit ourselves to 1 IO range and 3 mem
+ 	 * ranges since the common pci_bus structure can't handle more
+@@ -71,6 +73,12 @@ struct pci_dn {
+ 	struct	iommu_table *iommu_table;	/* for phb's or bridges */
+ 	struct	pci_dev *pcidev;	/* back-pointer to the pci device */
+ 	struct	device_node *node;	/* back-pointer to the device_node */
++#ifdef CONFIG_PPC_ISERIES
++	struct	list_head Device_List;
++	int		Irq;		/* Assigned IRQ */
++	int		Flags;		/* Possible flags(disable/bist)*/
++	u8		LogicalSlot;	/* Hv Slot Index for Tces */
++#endif
+ 	u32	config_space[16];	/* saved PCI config space */
+ };
+ 
+@@ -96,6 +104,16 @@ static inline struct device_node *pci_de
+ 	return fetch_dev_dn(dev);
+ }
+ 
++static inline int pci_device_from_OF_node(struct device_node *np,
++					  u8 *bus, u8 *devfn)
++{
++	if (!PCI_DN(np))
++		return -ENODEV;
++	*bus = PCI_DN(np)->busno;
++	*devfn = PCI_DN(np)->devfn;
++	return 0;
++}
++
+ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+ {
+ 	if (bus->self)
+@@ -105,7 +123,7 @@ static inline struct device_node *pci_bu
+ }
+ 
+ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
+-					 struct device_node *dev);
++					 struct device_node *dev, int primary);
+ 
+ extern int pcibios_remove_root_bus(struct pci_controller *phb);
+ 
+diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
+--- a/include/asm-ppc64/pci.h
++++ b/include/asm-ppc64/pci.h
+@@ -168,7 +168,7 @@ extern void pcibios_add_platform_entries
+ 
+ struct file;
+ extern pgprot_t	pci_phys_mem_access_prot(struct file *file,
+-					 unsigned long offset,
++					 unsigned long pfn,
+ 					 unsigned long size,
+ 					 pgprot_t prot);
+ 
+diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
+--- a/include/asm-ppc64/pgtable.h
++++ b/include/asm-ppc64/pgtable.h
+@@ -471,17 +471,19 @@ static inline void __ptep_set_access_fla
+ #define pgprot_noncached(prot)	(__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
+ 
+ struct file;
+-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
++extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ 				     unsigned long size, pgprot_t vma_prot);
+ #define __HAVE_PHYS_MEM_ACCESS_PROT
+ 
+ #define __HAVE_ARCH_PTE_SAME
+ #define pte_same(A,B)	(((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
+ 
++#define pte_ERROR(e) \
++	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+ #define pmd_ERROR(e) \
+ 	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+ #define pud_ERROR(e) \
+-	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pud_val(e))
++	printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
+ #define pgd_ERROR(e) \
+ 	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+ 
+diff --git a/include/asm-ppc64/pmac_feature.h b/include/asm-ppc64/pmac_feature.h
+deleted file mode 100644
+--- a/include/asm-ppc64/pmac_feature.h
++++ /dev/null
+@@ -1,2 +0,0 @@
+-#include <asm-ppc/pmac_feature.h>
+-
+diff --git a/include/asm-ppc64/pmac_low_i2c.h b/include/asm-ppc64/pmac_low_i2c.h
+deleted file mode 100644
+--- a/include/asm-ppc64/pmac_low_i2c.h
++++ /dev/null
+@@ -1,2 +0,0 @@
+-#include <asm-ppc/pmac_low_i2c.h>
+-
+diff --git a/include/asm-ppc64/pmc.h b/include/asm-ppc64/pmc.h
+deleted file mode 100644
+--- a/include/asm-ppc64/pmc.h
++++ /dev/null
+@@ -1,31 +0,0 @@
+-/*
+- * pmc.h
+- * Copyright (C) 2004  David Gibson, 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
+- */
+-#ifndef _PPC64_PMC_H
+-#define _PPC64_PMC_H
+-
+-#include <asm/ptrace.h>
+-
+-typedef void (*perf_irq_t)(struct pt_regs *);
+-
+-int reserve_pmc_hardware(perf_irq_t new_perf_irq);
+-void release_pmc_hardware(void);
+-
+-void power4_enable_pmcs(void);
+-
+-#endif /* _PPC64_PMC_H */
+diff --git a/include/asm-ppc64/posix_types.h b/include/asm-ppc64/posix_types.h
+deleted file mode 100644
+--- a/include/asm-ppc64/posix_types.h
++++ /dev/null
+@@ -1,119 +0,0 @@
+-#ifndef _PPC64_POSIX_TYPES_H
+-#define _PPC64_POSIX_TYPES_H
+-
+-/*
+- * This file is generally used by user-level software, so you need to
+- * be a little careful about namespace pollution etc.  Also, we cannot
+- * assume GCC is being used.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-typedef unsigned long	__kernel_ino_t;
+-typedef unsigned long  	__kernel_nlink_t;
+-typedef unsigned int	__kernel_mode_t;
+-typedef long		__kernel_off_t;
+-typedef long long	__kernel_loff_t;
+-typedef int		__kernel_pid_t;
+-typedef int             __kernel_ipc_pid_t;
+-typedef unsigned int	__kernel_uid_t;
+-typedef unsigned int	__kernel_gid_t;
+-typedef unsigned long	__kernel_size_t;
+-typedef long		__kernel_ssize_t;
+-typedef long		__kernel_ptrdiff_t;
+-typedef long		__kernel_time_t;
+-typedef int		__kernel_timer_t;
+-typedef int		__kernel_clockid_t;
+-typedef long		__kernel_suseconds_t;
+-typedef long		__kernel_clock_t;
+-typedef int		__kernel_daddr_t;
+-typedef char *		__kernel_caddr_t;
+-typedef unsigned short	__kernel_uid16_t;
+-typedef unsigned short	__kernel_gid16_t;
+-typedef unsigned int	__kernel_uid32_t;
+-typedef unsigned int	__kernel_gid32_t;
+-
+-typedef unsigned int	__kernel_old_uid_t;
+-typedef unsigned int	__kernel_old_gid_t;
+-typedef unsigned long	__kernel_old_dev_t;
+-
+-typedef struct {
+-	int	val[2];
+-} __kernel_fsid_t;
+-
+-#ifndef __GNUC__
+-
+-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+-#define	__FD_ISSET(d, set)	(((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0)
+-#define	__FD_ZERO(set)	\
+-  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
+-
+-#else /* __GNUC__ */
+-
+-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
+-    || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+-/* With GNU C, use inline functions instead so args are evaluated only once: */
+-
+-#undef __FD_SET
+-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+-{
+-	unsigned long _tmp = fd / __NFDBITS;
+-	unsigned long _rem = fd % __NFDBITS;
+-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+-}
+-
+-#undef __FD_CLR
+-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+-{
+-	unsigned long _tmp = fd / __NFDBITS;
+-	unsigned long _rem = fd % __NFDBITS;
+-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+-}
+-
+-#undef __FD_ISSET
+-static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
+-{ 
+-	unsigned long _tmp = fd / __NFDBITS;
+-	unsigned long _rem = fd % __NFDBITS;
+-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+-}
+-
+-/*
+- * This will unroll the loop for the normal constant case (8 ints,
+- * for a 256-bit fd_set)
+- */
+-#undef __FD_ZERO
+-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+-{
+-	unsigned long *tmp = (unsigned long *)p->fds_bits;
+-	int i;
+-
+-	if (__builtin_constant_p(__FDSET_LONGS)) {
+-		switch (__FDSET_LONGS) {
+-		      case 16:
+-			tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+-			tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+-
+-		      case 8:
+-			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+-
+-		      case 4:
+-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+-			return;
+-		}
+-	}
+-	i = __FDSET_LONGS;
+-	while (i) {
+-		i--;
+-		*tmp = 0;
+-		tmp++;
+-	}
+-}
+-
+-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+-#endif /* __GNUC__ */
+-#endif /* _PPC64_POSIX_TYPES_H */
+diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h
+--- a/include/asm-ppc64/ppc32.h
++++ b/include/asm-ppc64/ppc32.h
+@@ -70,18 +70,18 @@ typedef struct compat_siginfo {
+ #define __old_sigaction32	old_sigaction32
+ 
+ struct __old_sigaction32 {
+-	unsigned		sa_handler;
++	compat_uptr_t		sa_handler;
+ 	compat_old_sigset_t  	sa_mask;
+ 	unsigned int    	sa_flags;
+-	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
++	compat_uptr_t		sa_restorer;     /* not used by Linux/SPARC yet */
+ };
+ 
+ 
+ 
+ struct sigaction32 {
+-       unsigned int  sa_handler;	/* Really a pointer, but need to deal with 32 bits */
++       compat_uptr_t  sa_handler;	/* Really a pointer, but need to deal with 32 bits */
+        unsigned int sa_flags;
+-       unsigned int sa_restorer;	/* Another 32 bit pointer */
++       compat_uptr_t sa_restorer;	/* Another 32 bit pointer */
+        compat_sigset_t sa_mask;		/* A 32 bit mask */
+ };
+ 
+@@ -94,9 +94,9 @@ typedef struct sigaltstack_32 {
+ struct sigcontext32 {
+ 	unsigned int	_unused[4];
+ 	int		signal;
+-	unsigned int	handler;
++	compat_uptr_t	handler;
+ 	unsigned int	oldmask;
+-	u32 regs;  /* 4 byte pointer to the pt_regs32 structure. */
++	compat_uptr_t	regs;  /* 4 byte pointer to the pt_regs32 structure. */
+ };
+ 
+ struct mcontext32 {
+@@ -111,7 +111,7 @@ struct ucontext32 { 
+ 	unsigned int 	  	uc_link;
+ 	stack_32_t	 	uc_stack;
+ 	int		 	uc_pad[7];
+-	u32			uc_regs;	/* points to uc_mcontext field */
++	compat_uptr_t		uc_regs;	/* points to uc_mcontext field */
+ 	compat_sigset_t	 	uc_sigmask;	/* mask last for extensibility */
+ 	/* glibc has 1024-bit signal masks, ours are 64-bit */
+ 	int		 	uc_maskext[30];
+diff --git a/include/asm-ppc64/ppc_asm.h b/include/asm-ppc64/ppc_asm.h
+deleted file mode 100644
+--- a/include/asm-ppc64/ppc_asm.h
++++ /dev/null
+@@ -1,242 +0,0 @@
+-/*
+- * arch/ppc64/kernel/ppc_asm.h
+- *
+- * Definitions used by various bits of low-level assembly code on PowerPC.
+- *
+- * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
+- *
+- *  This program is free software; you can redistribute it and/or
+- *  modify it under the terms of the 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 _PPC64_PPC_ASM_H
+-#define _PPC64_PPC_ASM_H
+-/*
+- * Macros for storing registers into and loading registers from
+- * exception frames.
+- */
+-#define SAVE_GPR(n, base)	std	n,GPR0+8*(n)(base)
+-#define SAVE_2GPRS(n, base)	SAVE_GPR(n, base); SAVE_GPR(n+1, base)
+-#define SAVE_4GPRS(n, base)	SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
+-#define SAVE_8GPRS(n, base)	SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
+-#define SAVE_10GPRS(n, base)	SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
+-#define REST_GPR(n, base)	ld	n,GPR0+8*(n)(base)
+-#define REST_2GPRS(n, base)	REST_GPR(n, base); REST_GPR(n+1, base)
+-#define REST_4GPRS(n, base)	REST_2GPRS(n, base); REST_2GPRS(n+2, base)
+-#define REST_8GPRS(n, base)	REST_4GPRS(n, base); REST_4GPRS(n+4, base)
+-#define REST_10GPRS(n, base)	REST_8GPRS(n, base); REST_2GPRS(n+8, base)
+-
+-#define SAVE_NVGPRS(base)	SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
+-#define REST_NVGPRS(base)	REST_8GPRS(14, base); REST_10GPRS(22, base)
+-
+-#define SAVE_FPR(n, base)	stfd	n,THREAD_FPR0+8*(n)(base)
+-#define SAVE_2FPRS(n, base)	SAVE_FPR(n, base); SAVE_FPR(n+1, base)
+-#define SAVE_4FPRS(n, base)	SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
+-#define SAVE_8FPRS(n, base)	SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
+-#define SAVE_16FPRS(n, base)	SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
+-#define SAVE_32FPRS(n, base)	SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
+-#define REST_FPR(n, base)	lfd	n,THREAD_FPR0+8*(n)(base)
+-#define REST_2FPRS(n, base)	REST_FPR(n, base); REST_FPR(n+1, base)
+-#define REST_4FPRS(n, base)	REST_2FPRS(n, base); REST_2FPRS(n+2, base)
+-#define REST_8FPRS(n, base)	REST_4FPRS(n, base); REST_4FPRS(n+4, base)
+-#define REST_16FPRS(n, base)	REST_8FPRS(n, base); REST_8FPRS(n+8, base)
+-#define REST_32FPRS(n, base)	REST_16FPRS(n, base); REST_16FPRS(n+16, base)
+-
+-#define SAVE_VR(n,b,base)	li b,THREAD_VR0+(16*(n));  stvx n,b,base
+-#define SAVE_2VRS(n,b,base)	SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
+-#define SAVE_4VRS(n,b,base)	SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
+-#define SAVE_8VRS(n,b,base)	SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
+-#define SAVE_16VRS(n,b,base)	SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
+-#define SAVE_32VRS(n,b,base)	SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
+-#define REST_VR(n,b,base)	li b,THREAD_VR0+(16*(n)); lvx n,b,base
+-#define REST_2VRS(n,b,base)	REST_VR(n,b,base); REST_VR(n+1,b,base)
+-#define REST_4VRS(n,b,base)	REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
+-#define REST_8VRS(n,b,base)	REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
+-#define REST_16VRS(n,b,base)	REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
+-#define REST_32VRS(n,b,base)	REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
+-
+-/* Macros to adjust thread priority for Iseries hardware multithreading */
+-#define HMT_LOW		or 1,1,1
+-#define HMT_MEDIUM	or 2,2,2
+-#define HMT_HIGH	or 3,3,3
+-
+-/* Insert the high 32 bits of the MSR into what will be the new
+-   MSR (via SRR1 and rfid)  This preserves the MSR.SF and MSR.ISF
+-   bits. */
+-
+-#define FIX_SRR1(ra, rb)	\
+-	mr	rb,ra;		\
+-	mfmsr	ra;		\
+-	rldimi	ra,rb,0,32
+-
+-#define CLR_TOP32(r)	rlwinm	(r),(r),0,0,31	/* clear top 32 bits */
+-
+-/* 
+- * LOADADDR( rn, name )
+- *   loads the address of 'name' into 'rn'
+- *
+- * LOADBASE( rn, name )
+- *   loads the address (less the low 16 bits) of 'name' into 'rn'
+- *   suitable for base+disp addressing
+- */
+-#define LOADADDR(rn,name) \
+-	lis	rn,name##@highest;	\
+-	ori	rn,rn,name##@higher;	\
+-	rldicr	rn,rn,32,31;		\
+-	oris	rn,rn,name##@h;		\
+-	ori	rn,rn,name##@l
+-
+-#define LOADBASE(rn,name) \
+-	lis	rn,name at highest;	\
+-	ori	rn,rn,name at higher;	\
+-	rldicr	rn,rn,32,31;		\
+-	oris	rn,rn,name at ha
+-
+-
+-#define SET_REG_TO_CONST(reg, value)	         	\
+-	lis     reg,(((value)>>48)&0xFFFF);             \
+-	ori     reg,reg,(((value)>>32)&0xFFFF);         \
+-	rldicr  reg,reg,32,31;                          \
+-	oris    reg,reg,(((value)>>16)&0xFFFF);         \
+-	ori     reg,reg,((value)&0xFFFF);
+-
+-#define SET_REG_TO_LABEL(reg, label)	         	\
+-	lis     reg,(label)@highest;                    \
+-	ori     reg,reg,(label)@higher;                 \
+-	rldicr  reg,reg,32,31;                          \
+-	oris    reg,reg,(label)@h;                      \
+-	ori     reg,reg,(label)@l;
+-
+-
+-/* PPPBBB - DRENG  If KERNELBASE is always 0xC0...,
+- * Then we can easily do this with one asm insn. -Peter
+- */
+-#define tophys(rd,rs)                           \
+-        lis     rd,((KERNELBASE>>48)&0xFFFF);   \
+-        rldicr  rd,rd,32,31;                    \
+-        sub     rd,rs,rd
+-
+-#define tovirt(rd,rs)                           \
+-        lis     rd,((KERNELBASE>>48)&0xFFFF);   \
+-        rldicr  rd,rd,32,31;                    \
+-        add     rd,rs,rd
+-
+-/* Condition Register Bit Fields */
+-
+-#define	cr0	0
+-#define	cr1	1
+-#define	cr2	2
+-#define	cr3	3
+-#define	cr4	4
+-#define	cr5	5
+-#define	cr6	6
+-#define	cr7	7
+-
+-
+-/* General Purpose Registers (GPRs) */
+-
+-#define	r0	0
+-#define	r1	1
+-#define	r2	2
+-#define	r3	3
+-#define	r4	4
+-#define	r5	5
+-#define	r6	6
+-#define	r7	7
+-#define	r8	8
+-#define	r9	9
+-#define	r10	10
+-#define	r11	11
+-#define	r12	12
+-#define	r13	13
+-#define	r14	14
+-#define	r15	15
+-#define	r16	16
+-#define	r17	17
+-#define	r18	18
+-#define	r19	19
+-#define	r20	20
+-#define	r21	21
+-#define	r22	22
+-#define	r23	23
+-#define	r24	24
+-#define	r25	25
+-#define	r26	26
+-#define	r27	27
+-#define	r28	28
+-#define	r29	29
+-#define	r30	30
+-#define	r31	31
+-
+-
+-/* Floating Point Registers (FPRs) */
+-
+-#define	fr0	0
+-#define	fr1	1
+-#define	fr2	2
+-#define	fr3	3
+-#define	fr4	4
+-#define	fr5	5
+-#define	fr6	6
+-#define	fr7	7
+-#define	fr8	8
+-#define	fr9	9
+-#define	fr10	10
+-#define	fr11	11
+-#define	fr12	12
+-#define	fr13	13
+-#define	fr14	14
+-#define	fr15	15
+-#define	fr16	16
+-#define	fr17	17
+-#define	fr18	18
+-#define	fr19	19
+-#define	fr20	20
+-#define	fr21	21
+-#define	fr22	22
+-#define	fr23	23
+-#define	fr24	24
+-#define	fr25	25
+-#define	fr26	26
+-#define	fr27	27
+-#define	fr28	28
+-#define	fr29	29
+-#define	fr30	30
+-#define	fr31	31
+-
+-#define	vr0	0
+-#define	vr1	1
+-#define	vr2	2
+-#define	vr3	3
+-#define	vr4	4
+-#define	vr5	5
+-#define	vr6	6
+-#define	vr7	7
+-#define	vr8	8
+-#define	vr9	9
+-#define	vr10	10
+-#define	vr11	11
+-#define	vr12	12
+-#define	vr13	13
+-#define	vr14	14
+-#define	vr15	15
+-#define	vr16	16
+-#define	vr17	17
+-#define	vr18	18
+-#define	vr19	19
+-#define	vr20	20
+-#define	vr21	21
+-#define	vr22	22
+-#define	vr23	23
+-#define	vr24	24
+-#define	vr25	25
+-#define	vr26	26
+-#define	vr27	27
+-#define	vr28	28
+-#define	vr29	29
+-#define	vr30	30
+-#define	vr31	31
+-
+-#endif /* _PPC64_PPC_ASM_H */
+diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
+deleted file mode 100644
+--- a/include/asm-ppc64/processor.h
++++ /dev/null
+@@ -1,558 +0,0 @@
+-#ifndef __ASM_PPC64_PROCESSOR_H
+-#define __ASM_PPC64_PROCESSOR_H
+-
+-/*
+- * Copyright (C) 2001 PPC 64 Team, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-#include <linux/stringify.h>
+-#ifndef __ASSEMBLY__
+-#include <linux/config.h>
+-#include <asm/atomic.h>
+-#include <asm/ppcdebug.h>
+-#include <asm/a.out.h>
+-#endif
+-#include <asm/ptrace.h>
+-#include <asm/types.h>
+-#include <asm/systemcfg.h>
+-#include <asm/cputable.h>
+-
+-/* Machine State Register (MSR) Fields */
+-#define MSR_SF_LG	63              /* Enable 64 bit mode */
+-#define MSR_ISF_LG	61              /* Interrupt 64b mode valid on 630 */
+-#define MSR_HV_LG 	60              /* Hypervisor state */
+-#define MSR_VEC_LG	25	        /* Enable AltiVec */
+-#define MSR_POW_LG	18		/* Enable Power Management */
+-#define MSR_WE_LG	18		/* Wait State Enable */
+-#define MSR_TGPR_LG	17		/* TLB Update registers in use */
+-#define MSR_CE_LG	17		/* Critical Interrupt Enable */
+-#define MSR_ILE_LG	16		/* Interrupt Little Endian */
+-#define MSR_EE_LG	15		/* External Interrupt Enable */
+-#define MSR_PR_LG	14		/* Problem State / Privilege Level */
+-#define MSR_FP_LG	13		/* Floating Point enable */
+-#define MSR_ME_LG	12		/* Machine Check Enable */
+-#define MSR_FE0_LG	11		/* Floating Exception mode 0 */
+-#define MSR_SE_LG	10		/* Single Step */
+-#define MSR_BE_LG	9		/* Branch Trace */
+-#define MSR_DE_LG	9 		/* Debug Exception Enable */
+-#define MSR_FE1_LG	8		/* Floating Exception mode 1 */
+-#define MSR_IP_LG	6		/* Exception prefix 0x000/0xFFF */
+-#define MSR_IR_LG	5 		/* Instruction Relocate */
+-#define MSR_DR_LG	4 		/* Data Relocate */
+-#define MSR_PE_LG	3		/* Protection Enable */
+-#define MSR_PX_LG	2		/* Protection Exclusive Mode */
+-#define MSR_PMM_LG	2		/* Performance monitor */
+-#define MSR_RI_LG	1		/* Recoverable Exception */
+-#define MSR_LE_LG	0 		/* Little Endian */
+-
+-#ifdef __ASSEMBLY__
+-#define __MASK(X)	(1<<(X))
+-#else
+-#define __MASK(X)	(1UL<<(X))
+-#endif
+-
+-#define MSR_SF		__MASK(MSR_SF_LG)	/* Enable 64 bit mode */
+-#define MSR_ISF		__MASK(MSR_ISF_LG)	/* Interrupt 64b mode valid on 630 */
+-#define MSR_HV 		__MASK(MSR_HV_LG)	/* Hypervisor state */
+-#define MSR_VEC		__MASK(MSR_VEC_LG)	/* Enable AltiVec */
+-#define MSR_POW		__MASK(MSR_POW_LG)	/* Enable Power Management */
+-#define MSR_WE		__MASK(MSR_WE_LG)	/* Wait State Enable */
+-#define MSR_TGPR	__MASK(MSR_TGPR_LG)	/* TLB Update registers in use */
+-#define MSR_CE		__MASK(MSR_CE_LG)	/* Critical Interrupt Enable */
+-#define MSR_ILE		__MASK(MSR_ILE_LG)	/* Interrupt Little Endian */
+-#define MSR_EE		__MASK(MSR_EE_LG)	/* External Interrupt Enable */
+-#define MSR_PR		__MASK(MSR_PR_LG)	/* Problem State / Privilege Level */
+-#define MSR_FP		__MASK(MSR_FP_LG)	/* Floating Point enable */
+-#define MSR_ME		__MASK(MSR_ME_LG)	/* Machine Check Enable */
+-#define MSR_FE0		__MASK(MSR_FE0_LG)	/* Floating Exception mode 0 */
+-#define MSR_SE		__MASK(MSR_SE_LG)	/* Single Step */
+-#define MSR_BE		__MASK(MSR_BE_LG)	/* Branch Trace */
+-#define MSR_DE		__MASK(MSR_DE_LG)	/* Debug Exception Enable */
+-#define MSR_FE1		__MASK(MSR_FE1_LG)	/* Floating Exception mode 1 */
+-#define MSR_IP		__MASK(MSR_IP_LG)	/* Exception prefix 0x000/0xFFF */
+-#define MSR_IR		__MASK(MSR_IR_LG)	/* Instruction Relocate */
+-#define MSR_DR		__MASK(MSR_DR_LG)	/* Data Relocate */
+-#define MSR_PE		__MASK(MSR_PE_LG)	/* Protection Enable */
+-#define MSR_PX		__MASK(MSR_PX_LG)	/* Protection Exclusive Mode */
+-#define MSR_PMM		__MASK(MSR_PMM_LG)	/* Performance monitor */
+-#define MSR_RI		__MASK(MSR_RI_LG)	/* Recoverable Exception */
+-#define MSR_LE		__MASK(MSR_LE_LG)	/* Little Endian */
+-
+-#define MSR_		MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF
+-#define MSR_KERNEL      MSR_ | MSR_SF | MSR_HV
+-
+-#define MSR_USER32	MSR_ | MSR_PR | MSR_EE
+-#define MSR_USER64	MSR_USER32 | MSR_SF
+-
+-/* Floating Point Status and Control Register (FPSCR) Fields */
+-
+-#define FPSCR_FX	0x80000000	/* FPU exception summary */
+-#define FPSCR_FEX	0x40000000	/* FPU enabled exception summary */
+-#define FPSCR_VX	0x20000000	/* Invalid operation summary */
+-#define FPSCR_OX	0x10000000	/* Overflow exception summary */
+-#define FPSCR_UX	0x08000000	/* Underflow exception summary */
+-#define FPSCR_ZX	0x04000000	/* Zero-divide exception summary */
+-#define FPSCR_XX	0x02000000	/* Inexact exception summary */
+-#define FPSCR_VXSNAN	0x01000000	/* Invalid op for SNaN */
+-#define FPSCR_VXISI	0x00800000	/* Invalid op for Inv - Inv */
+-#define FPSCR_VXIDI	0x00400000	/* Invalid op for Inv / Inv */
+-#define FPSCR_VXZDZ	0x00200000	/* Invalid op for Zero / Zero */
+-#define FPSCR_VXIMZ	0x00100000	/* Invalid op for Inv * Zero */
+-#define FPSCR_VXVC	0x00080000	/* Invalid op for Compare */
+-#define FPSCR_FR	0x00040000	/* Fraction rounded */
+-#define FPSCR_FI	0x00020000	/* Fraction inexact */
+-#define FPSCR_FPRF	0x0001f000	/* FPU Result Flags */
+-#define FPSCR_FPCC	0x0000f000	/* FPU Condition Codes */
+-#define FPSCR_VXSOFT	0x00000400	/* Invalid op for software request */
+-#define FPSCR_VXSQRT	0x00000200	/* Invalid op for square root */
+-#define FPSCR_VXCVI	0x00000100	/* Invalid op for integer convert */
+-#define FPSCR_VE	0x00000080	/* Invalid op exception enable */
+-#define FPSCR_OE	0x00000040	/* IEEE overflow exception enable */
+-#define FPSCR_UE	0x00000020	/* IEEE underflow exception enable */
+-#define FPSCR_ZE	0x00000010	/* IEEE zero divide exception enable */
+-#define FPSCR_XE	0x00000008	/* FP inexact exception enable */
+-#define FPSCR_NI	0x00000004	/* FPU non IEEE-Mode */
+-#define FPSCR_RN	0x00000003	/* FPU rounding control */
+-
+-/* Special Purpose Registers (SPRNs)*/
+-
+-#define	SPRN_CTR	0x009	/* Count Register */
+-#define	SPRN_DABR	0x3F5	/* Data Address Breakpoint Register */
+-#define   DABR_TRANSLATION	(1UL << 2)
+-#define	SPRN_DAR	0x013	/* Data Address Register */
+-#define	SPRN_DEC	0x016	/* Decrement Register */
+-#define	SPRN_DSISR	0x012	/* Data Storage Interrupt Status Register */
+-#define   DSISR_NOHPTE		0x40000000	/* no translation found */
+-#define   DSISR_PROTFAULT	0x08000000	/* protection fault */
+-#define   DSISR_ISSTORE		0x02000000	/* access was a store */
+-#define   DSISR_DABRMATCH	0x00400000	/* hit data breakpoint */
+-#define   DSISR_NOSEGMENT	0x00200000	/* STAB/SLB miss */
+-#define	SPRN_HID0	0x3F0	/* Hardware Implementation Register 0 */
+-#define	SPRN_MSRDORM	0x3F1	/* Hardware Implementation Register 1 */
+-#define SPRN_HID1	0x3F1	/* Hardware Implementation Register 1 */
+-#define	SPRN_IABR	0x3F2	/* Instruction Address Breakpoint Register */
+-#define	SPRN_NIADORM	0x3F3	/* Hardware Implementation Register 2 */
+-#define SPRN_HID4	0x3F4	/* 970 HID4 */
+-#define SPRN_HID5	0x3F6	/* 970 HID5 */
+-#define	SPRN_HID6	0x3F9	/* BE HID 6 */
+-#define	  HID6_LB	(0x0F<<12) /* Concurrent Large Page Modes */
+-#define	  HID6_DLP	(1<<20)	/* Disable all large page modes (4K only) */
+-#define	SPRN_TSCR	0x399   /* Thread switch control on BE */
+-#define	SPRN_TTR	0x39A   /* Thread switch timeout on BE */
+-#define	  TSCR_DEC_ENABLE	0x200000 /* Decrementer Interrupt */
+-#define	  TSCR_EE_ENABLE	0x100000 /* External Interrupt */
+-#define	  TSCR_EE_BOOST		0x080000 /* External Interrupt Boost */
+-#define	SPRN_TSC 	0x3FD	/* Thread switch control on others */
+-#define	SPRN_TST 	0x3FC	/* Thread switch timeout on others */
+-#define	SPRN_L2CR	0x3F9	/* Level 2 Cache Control Regsiter */
+-#define	SPRN_LR		0x008	/* Link Register */
+-#define	SPRN_PIR	0x3FF	/* Processor Identification Register */
+-#define	SPRN_PIT	0x3DB	/* Programmable Interval Timer */
+-#define	SPRN_PURR	0x135	/* Processor Utilization of Resources Register */
+-#define	SPRN_PVR	0x11F	/* Processor Version Register */
+-#define	SPRN_RPA	0x3D6	/* Required Physical Address Register */
+-#define	SPRN_SDA	0x3BF	/* Sampled Data Address Register */
+-#define	SPRN_SDR1	0x019	/* MMU Hash Base Register */
+-#define	SPRN_SIA	0x3BB	/* Sampled Instruction Address Register */
+-#define	SPRN_SPRG0	0x110	/* Special Purpose Register General 0 */
+-#define	SPRN_SPRG1	0x111	/* Special Purpose Register General 1 */
+-#define	SPRN_SPRG2	0x112	/* Special Purpose Register General 2 */
+-#define	SPRN_SPRG3	0x113	/* Special Purpose Register General 3 */
+-#define	SPRN_SRR0	0x01A	/* Save/Restore Register 0 */
+-#define	SPRN_SRR1	0x01B	/* Save/Restore Register 1 */
+-#define	SPRN_TBRL	0x10C	/* Time Base Read Lower Register (user, R/O) */
+-#define	SPRN_TBRU	0x10D	/* Time Base Read Upper Register (user, R/O) */
+-#define	SPRN_TBWL	0x11C	/* Time Base Lower Register (super, W/O) */
+-#define	SPRN_TBWU	0x11D	/* Time Base Write Upper Register (super, W/O) */
+-#define SPRN_HIOR	0x137	/* 970 Hypervisor interrupt offset */
+-#define	SPRN_USIA	0x3AB	/* User Sampled Instruction Address Register */
+-#define	SPRN_XER	0x001	/* Fixed Point Exception Register */
+-#define SPRN_VRSAVE     0x100   /* Vector save */
+-#define SPRN_CTRLF	0x088
+-#define SPRN_CTRLT	0x098
+-#define   CTRL_RUNLATCH	0x1
+-
+-/* Performance monitor SPRs */
+-#define SPRN_SIAR	780
+-#define SPRN_SDAR	781
+-#define SPRN_MMCRA	786
+-#define   MMCRA_SIHV	0x10000000UL /* state of MSR HV when SIAR set */
+-#define   MMCRA_SIPR	0x08000000UL /* state of MSR PR when SIAR set */
+-#define   MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
+-#define SPRN_PMC1	787
+-#define SPRN_PMC2	788
+-#define SPRN_PMC3	789
+-#define SPRN_PMC4	790
+-#define SPRN_PMC5	791
+-#define SPRN_PMC6	792
+-#define SPRN_PMC7	793
+-#define SPRN_PMC8	794
+-#define SPRN_MMCR0	795
+-#define   MMCR0_FC	0x80000000UL /* freeze counters. set to 1 on a perfmon exception */
+-#define   MMCR0_FCS	0x40000000UL /* freeze in supervisor state */
+-#define   MMCR0_KERNEL_DISABLE MMCR0_FCS
+-#define   MMCR0_FCP	0x20000000UL /* freeze in problem state */
+-#define   MMCR0_PROBLEM_DISABLE MMCR0_FCP
+-#define   MMCR0_FCM1	0x10000000UL /* freeze counters while MSR mark = 1 */
+-#define   MMCR0_FCM0	0x08000000UL /* freeze counters while MSR mark = 0 */
+-#define   MMCR0_PMXE	0x04000000UL /* performance monitor exception enable */
+-#define   MMCR0_FCECE	0x02000000UL /* freeze counters on enabled condition or event */
+-/* time base exception enable */
+-#define   MMCR0_TBEE	0x00400000UL /* time base exception enable */
+-#define   MMCR0_PMC1CE	0x00008000UL /* PMC1 count enable*/
+-#define   MMCR0_PMCjCE	0x00004000UL /* PMCj count enable*/
+-#define   MMCR0_TRIGGER	0x00002000UL /* TRIGGER enable */
+-#define   MMCR0_PMAO	0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
+-#define   MMCR0_SHRFC	0x00000040UL /* SHRre freeze conditions between threads */
+-#define   MMCR0_FCTI	0x00000008UL /* freeze counters in tags inactive mode */
+-#define   MMCR0_FCTA	0x00000004UL /* freeze counters in tags active mode */
+-#define   MMCR0_FCWAIT	0x00000002UL /* freeze counter in WAIT state */
+-#define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
+-#define SPRN_MMCR1	798
+-
+-/* Short-hand versions for a number of the above SPRNs */
+-
+-#define	CTR	SPRN_CTR	/* Counter Register */
+-#define	DAR	SPRN_DAR	/* Data Address Register */
+-#define	DABR	SPRN_DABR	/* Data Address Breakpoint Register */
+-#define	DEC	SPRN_DEC       	/* Decrement Register */
+-#define	DSISR	SPRN_DSISR	/* Data Storage Interrupt Status Register */
+-#define	HID0	SPRN_HID0	/* Hardware Implementation Register 0 */
+-#define	MSRDORM	SPRN_MSRDORM	/* MSR Dormant Register */
+-#define	NIADORM	SPRN_NIADORM	/* NIA Dormant Register */
+-#define	TSC    	SPRN_TSC 	/* Thread switch control */
+-#define	TST    	SPRN_TST 	/* Thread switch timeout */
+-#define	IABR	SPRN_IABR      	/* Instruction Address Breakpoint Register */
+-#define	L2CR	SPRN_L2CR    	/* PPC 750 L2 control register */
+-#define	__LR	SPRN_LR
+-#define	PVR	SPRN_PVR	/* Processor Version */
+-#define	PIR	SPRN_PIR	/* Processor ID */
+-#define	PURR	SPRN_PURR	/* Processor Utilization of Resource Register */
+-#define	SDR1	SPRN_SDR1      	/* MMU hash base register */
+-#define	SPR0	SPRN_SPRG0	/* Supervisor Private Registers */
+-#define	SPR1	SPRN_SPRG1
+-#define	SPR2	SPRN_SPRG2
+-#define	SPR3	SPRN_SPRG3
+-#define	SPRG0   SPRN_SPRG0
+-#define	SPRG1   SPRN_SPRG1
+-#define	SPRG2   SPRN_SPRG2
+-#define	SPRG3   SPRN_SPRG3
+-#define	SRR0	SPRN_SRR0	/* Save and Restore Register 0 */
+-#define	SRR1	SPRN_SRR1	/* Save and Restore Register 1 */
+-#define	TBRL	SPRN_TBRL	/* Time Base Read Lower Register */
+-#define	TBRU	SPRN_TBRU	/* Time Base Read Upper Register */
+-#define	TBWL	SPRN_TBWL	/* Time Base Write Lower Register */
+-#define	TBWU	SPRN_TBWU	/* Time Base Write Upper Register */
+-#define	XER	SPRN_XER
+-
+-/* Processor Version Register (PVR) field extraction */
+-
+-#define	PVR_VER(pvr)  (((pvr) >>  16) & 0xFFFF)	/* Version field */
+-#define	PVR_REV(pvr)  (((pvr) >>   0) & 0xFFFF)	/* Revison field */
+-
+-/* Processor Version Numbers */
+-#define	PV_NORTHSTAR	0x0033
+-#define	PV_PULSAR	0x0034
+-#define	PV_POWER4	0x0035
+-#define	PV_ICESTAR	0x0036
+-#define	PV_SSTAR	0x0037
+-#define	PV_POWER4p	0x0038
+-#define PV_970		0x0039
+-#define	PV_POWER5	0x003A
+-#define PV_POWER5p	0x003B
+-#define PV_970FX	0x003C
+-#define	PV_630        	0x0040
+-#define	PV_630p	        0x0041
+-#define	PV_970MP	0x0044
+-#define	PV_BE		0x0070
+-
+-/* Platforms supported by PPC64 */
+-#define PLATFORM_PSERIES      0x0100
+-#define PLATFORM_PSERIES_LPAR 0x0101
+-#define PLATFORM_ISERIES_LPAR 0x0201
+-#define PLATFORM_LPAR         0x0001
+-#define PLATFORM_POWERMAC     0x0400
+-#define PLATFORM_MAPLE        0x0500
+-#define PLATFORM_BPA          0x1000
+-
+-/* Compatibility with drivers coming from PPC32 world */
+-#define _machine	(systemcfg->platform)
+-#define _MACH_Pmac	PLATFORM_POWERMAC
+-
+-/*
+- * List of interrupt controllers.
+- */
+-#define IC_INVALID    0
+-#define IC_OPEN_PIC   1
+-#define IC_PPC_XIC    2
+-#define IC_BPA_IIC    3
+-
+-#define XGLUE(a,b) a##b
+-#define GLUE(a,b) XGLUE(a,b)
+-
+-#ifdef __ASSEMBLY__
+-
+-#define _GLOBAL(name) \
+-	.section ".text"; \
+-	.align 2 ; \
+-	.globl name; \
+-	.globl GLUE(.,name); \
+-	.section ".opd","aw"; \
+-name: \
+-	.quad GLUE(.,name); \
+-	.quad .TOC. at tocbase; \
+-	.quad 0; \
+-	.previous; \
+-	.type GLUE(.,name), at function; \
+-GLUE(.,name):
+-
+-#define _KPROBE(name) \
+-	.section ".kprobes.text","a"; \
+-	.align 2 ; \
+-	.globl name; \
+-	.globl GLUE(.,name); \
+-	.section ".opd","aw"; \
+-name: \
+-	.quad GLUE(.,name); \
+-	.quad .TOC. at tocbase; \
+-	.quad 0; \
+-	.previous; \
+-	.type GLUE(.,name), at function; \
+-GLUE(.,name):
+-
+-#define _STATIC(name) \
+-	.section ".text"; \
+-	.align 2 ; \
+-	.section ".opd","aw"; \
+-name: \
+-	.quad GLUE(.,name); \
+-	.quad .TOC. at tocbase; \
+-	.quad 0; \
+-	.previous; \
+-	.type GLUE(.,name), at function; \
+-GLUE(.,name):
+-
+-#else /* __ASSEMBLY__ */
+-
+-/*
+- * Default implementation of macro that returns current
+- * instruction pointer ("program counter").
+- */
+-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+-
+-/* Macros for setting and retrieving special purpose registers */
+-
+-#define mfmsr()		({unsigned long rval; \
+-			asm volatile("mfmsr %0" : "=r" (rval)); rval;})
+-
+-#define __mtmsrd(v, l)	asm volatile("mtmsrd %0," __stringify(l) \
+-				     : : "r" (v))
+-#define mtmsrd(v)	__mtmsrd((v), 0)
+-
+-#define mfspr(rn)	({unsigned long rval; \
+-			asm volatile("mfspr %0," __stringify(rn) \
+-				     : "=r" (rval)); rval;})
+-#define mtspr(rn, v)	asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
+-
+-#define mftb()		({unsigned long rval;	\
+-			asm volatile("mftb %0" : "=r" (rval)); rval;})
+-
+-#define mttbl(v)	asm volatile("mttbl %0":: "r"(v))
+-#define mttbu(v)	asm volatile("mttbu %0":: "r"(v))
+-
+-#define mfasr()		({unsigned long rval; \
+-			asm volatile("mfasr %0" : "=r" (rval)); rval;})
+-
+-static inline void set_tb(unsigned int upper, unsigned int lower)
+-{
+-	mttbl(0);
+-	mttbu(upper);
+-	mttbl(lower);
+-}
+-
+-#define __get_SP()	({unsigned long sp; \
+-			asm volatile("mr %0,1": "=r" (sp)); sp;})
+-
+-#ifdef __KERNEL__
+-
+-extern int have_of;
+-extern u64 ppc64_interrupt_controller;
+-
+-struct task_struct;
+-void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
+-void release_thread(struct task_struct *);
+-
+-/* Prepare to copy thread state - unlazy all lazy status */
+-extern void prepare_to_copy(struct task_struct *tsk);
+-
+-/* Create a new kernel thread. */
+-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+-
+-/* Lazy FPU handling on uni-processor */
+-extern struct task_struct *last_task_used_math;
+-extern struct task_struct *last_task_used_altivec;
+-
+-/* 64-bit user address space is 44-bits (16TB user VM) */
+-#define TASK_SIZE_USER64 (0x0000100000000000UL)
+-
+-/* 
+- * 32-bit user address space is 4GB - 1 page 
+- * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT
+- */
+-#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE))
+-
+-#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
+-		TASK_SIZE_USER32 : TASK_SIZE_USER64)
+-
+-/* This decides where the kernel will search for a free chunk of vm
+- * space during mmap's.
+- */
+-#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4))
+-#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4))
+-
+-#define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)||(ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \
+-		TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
+-
+-typedef struct {
+-	unsigned long seg;
+-} mm_segment_t;
+-
+-struct thread_struct {
+-	unsigned long	ksp;		/* Kernel stack pointer */
+-	unsigned long	ksp_vsid;
+-	struct pt_regs	*regs;		/* Pointer to saved register state */
+-	mm_segment_t	fs;		/* for get_fs() validation */
+-	double		fpr[32];	/* Complete floating point set */
+-	unsigned long	fpscr;		/* Floating point status (plus pad) */
+-	unsigned long	fpexc_mode;	/* Floating-point exception mode */
+-	unsigned long	start_tb;	/* Start purr when proc switched in */
+-	unsigned long	accum_tb;	/* Total accumilated purr for process */
+-	unsigned long	vdso_base;	/* base of the vDSO library */
+-	unsigned long	dabr;		/* Data address breakpoint register */
+-#ifdef CONFIG_ALTIVEC
+-	/* Complete AltiVec register set */
+-	vector128	vr[32] __attribute((aligned(16)));
+-	/* AltiVec status */
+-	vector128	vscr __attribute((aligned(16)));
+-	unsigned long	vrsave;
+-	int		used_vr;	/* set if process has used altivec */
+-#endif /* CONFIG_ALTIVEC */
+-};
+-
+-#define ARCH_MIN_TASKALIGN 16
+-
+-#define INIT_SP		(sizeof(init_stack) + (unsigned long) &init_stack)
+-
+-#define INIT_THREAD  { \
+-	.ksp = INIT_SP, \
+-	.regs = (struct pt_regs *)INIT_SP - 1, \
+-	.fs = KERNEL_DS, \
+-	.fpr = {0}, \
+-	.fpscr = 0, \
+-	.fpexc_mode = MSR_FE0|MSR_FE1, \
+-}
+-
+-/*
+- * Return saved PC of a blocked thread. For now, this is the "user" PC
+- */
+-#define thread_saved_pc(tsk)    \
+-        ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
+-
+-unsigned long get_wchan(struct task_struct *p);
+-
+-#define KSTK_EIP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
+-#define KSTK_ESP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
+-
+-/* Get/set floating-point exception mode */
+-#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr))
+-#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val))
+-
+-extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
+-extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
+-
+-static inline unsigned int __unpack_fe01(unsigned long msr_bits)
+-{
+-	return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
+-}
+-
+-static inline unsigned long __pack_fe01(unsigned int fpmode)
+-{
+-	return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
+-}
+-
+-#define cpu_relax()	do { HMT_low(); HMT_medium(); barrier(); } while (0)
+-
+-/*
+- * Prefetch macros.
+- */
+-#define ARCH_HAS_PREFETCH
+-#define ARCH_HAS_PREFETCHW
+-#define ARCH_HAS_SPINLOCK_PREFETCH
+-
+-static inline void prefetch(const void *x)
+-{
+-	if (unlikely(!x))
+-		return;
+-
+-	__asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
+-}
+-
+-static inline void prefetchw(const void *x)
+-{
+-	if (unlikely(!x))
+-		return;
+-
+-	__asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
+-}
+-
+-#define spin_lock_prefetch(x)	prefetchw(x)
+-
+-#define HAVE_ARCH_PICK_MMAP_LAYOUT
+-
+-static inline void ppc64_runlatch_on(void)
+-{
+-	unsigned long ctrl;
+-
+-	if (cpu_has_feature(CPU_FTR_CTRL)) {
+-		ctrl = mfspr(SPRN_CTRLF);
+-		ctrl |= CTRL_RUNLATCH;
+-		mtspr(SPRN_CTRLT, ctrl);
+-	}
+-}
+-
+-static inline void ppc64_runlatch_off(void)
+-{
+-	unsigned long ctrl;
+-
+-	if (cpu_has_feature(CPU_FTR_CTRL)) {
+-		ctrl = mfspr(SPRN_CTRLF);
+-		ctrl &= ~CTRL_RUNLATCH;
+-		mtspr(SPRN_CTRLT, ctrl);
+-	}
+-}
+-
+-#endif /* __KERNEL__ */
+-
+-#endif /* __ASSEMBLY__ */
+-
+-#ifdef __KERNEL__
+-#define RUNLATCH_ON(REG)			\
+-BEGIN_FTR_SECTION				\
+-	mfspr	(REG),SPRN_CTRLF;		\
+-	ori	(REG),(REG),CTRL_RUNLATCH;	\
+-	mtspr	SPRN_CTRLT,(REG);		\
+-END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
+-#endif
+-
+-/*
+- * Number of entries in the SLB. If this ever changes we should handle
+- * it with a use a cpu feature fixup.
+- */
+-#define SLB_NUM_ENTRIES 64
+-
+-#endif /* __ASM_PPC64_PROCESSOR_H */
+diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
+--- a/include/asm-ppc64/prom.h
++++ b/include/asm-ppc64/prom.h
+@@ -14,6 +14,7 @@
+  * 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/proc_fs.h>
+ #include <asm/atomic.h>
+ 
+@@ -137,6 +138,9 @@ struct device_node {
+ 	struct  kref kref;
+ 	unsigned long _flags;
+ 	void	*data;
++#ifdef CONFIG_PPC_ISERIES
++	struct list_head Device_List;
++#endif
+ };
+ 
+ extern struct device_node *of_chosen;
+diff --git a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h
+deleted file mode 100644
+--- a/include/asm-ppc64/rtas.h
++++ /dev/null
+@@ -1,249 +0,0 @@
+-#ifndef _PPC64_RTAS_H
+-#define _PPC64_RTAS_H
+-
+-#include <linux/spinlock.h>
+-#include <asm/page.h>
+-
+-/*
+- * Definitions for talking to the RTAS on CHRP machines.
+- *
+- * Copyright (C) 2001 Peter Bergner
+- * Copyright (C) 2001 PPC 64 Team, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-#define RTAS_UNKNOWN_SERVICE (-1)
+-#define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */
+-
+-/* Buffer size for ppc_rtas system call. */
+-#define RTAS_RMOBUF_MAX (64 * 1024)
+-
+-/* RTAS return status codes */
+-#define RTAS_BUSY		-2    /* RTAS Busy */
+-#define RTAS_EXTENDED_DELAY_MIN	9900
+-#define RTAS_EXTENDED_DELAY_MAX	9905
+-
+-/*
+- * In general to call RTAS use rtas_token("string") to lookup
+- * an RTAS token for the given string (e.g. "event-scan").
+- * To actually perform the call use
+- *    ret = rtas_call(token, n_in, n_out, ...)
+- * Where n_in is the number of input parameters and
+- *       n_out is the number of output parameters
+- *
+- * If the "string" is invalid on this system, RTAS_UNKNOWN_SERVICE
+- * will be returned as a token.  rtas_call() does look for this
+- * token and error out gracefully so rtas_call(rtas_token("str"), ...)
+- * may be safely used for one-shot calls to RTAS.
+- *
+- */
+-
+-typedef u32 rtas_arg_t;
+-
+-struct rtas_args {
+-	u32 token;
+-	u32 nargs;
+-	u32 nret; 
+-	rtas_arg_t args[16];
+-	rtas_arg_t *rets;     /* Pointer to return values in args[]. */
+-};  
+-
+-extern struct rtas_args rtas_stop_self_args;
+-
+-struct rtas_t {
+-	unsigned long entry;		/* physical address pointer */
+-	unsigned long base;		/* physical address pointer */
+-	unsigned long size;
+-	spinlock_t lock;
+-	struct rtas_args args;
+-	struct device_node *dev;	/* virtual address pointer */
+-};
+-
+-/* RTAS event classes */
+-#define RTAS_INTERNAL_ERROR		0x80000000 /* set bit 0 */
+-#define RTAS_EPOW_WARNING		0x40000000 /* set bit 1 */
+-#define RTAS_POWERMGM_EVENTS		0x20000000 /* set bit 2 */
+-#define RTAS_HOTPLUG_EVENTS		0x10000000 /* set bit 3 */
+-#define RTAS_EVENT_SCAN_ALL_EVENTS	0xf0000000
+-
+-/* RTAS event severity */
+-#define RTAS_SEVERITY_FATAL		0x5
+-#define RTAS_SEVERITY_ERROR		0x4
+-#define RTAS_SEVERITY_ERROR_SYNC	0x3
+-#define RTAS_SEVERITY_WARNING		0x2
+-#define RTAS_SEVERITY_EVENT		0x1
+-#define RTAS_SEVERITY_NO_ERROR		0x0
+-
+-/* RTAS event disposition */
+-#define RTAS_DISP_FULLY_RECOVERED	0x0
+-#define RTAS_DISP_LIMITED_RECOVERY	0x1
+-#define RTAS_DISP_NOT_RECOVERED		0x2
+-
+-/* RTAS event initiator */
+-#define RTAS_INITIATOR_UNKNOWN		0x0
+-#define RTAS_INITIATOR_CPU		0x1
+-#define RTAS_INITIATOR_PCI		0x2
+-#define RTAS_INITIATOR_ISA		0x3
+-#define RTAS_INITIATOR_MEMORY		0x4
+-#define RTAS_INITIATOR_POWERMGM		0x5
+-
+-/* RTAS event target */
+-#define RTAS_TARGET_UNKNOWN		0x0
+-#define RTAS_TARGET_CPU			0x1
+-#define RTAS_TARGET_PCI			0x2
+-#define RTAS_TARGET_ISA			0x3
+-#define RTAS_TARGET_MEMORY		0x4
+-#define RTAS_TARGET_POWERMGM		0x5
+-
+-/* RTAS event type */
+-#define RTAS_TYPE_RETRY			0x01
+-#define RTAS_TYPE_TCE_ERR		0x02
+-#define RTAS_TYPE_INTERN_DEV_FAIL	0x03
+-#define RTAS_TYPE_TIMEOUT		0x04
+-#define RTAS_TYPE_DATA_PARITY		0x05
+-#define RTAS_TYPE_ADDR_PARITY		0x06
+-#define RTAS_TYPE_CACHE_PARITY		0x07
+-#define RTAS_TYPE_ADDR_INVALID		0x08
+-#define RTAS_TYPE_ECC_UNCORR		0x09
+-#define RTAS_TYPE_ECC_CORR		0x0a
+-#define RTAS_TYPE_EPOW			0x40
+-#define RTAS_TYPE_PLATFORM		0xE0
+-#define RTAS_TYPE_IO			0xE1
+-#define RTAS_TYPE_INFO			0xE2
+-#define RTAS_TYPE_DEALLOC		0xE3
+-#define RTAS_TYPE_DUMP			0xE4
+-/* I don't add PowerMGM events right now, this is a different topic */ 
+-#define RTAS_TYPE_PMGM_POWER_SW_ON	0x60
+-#define RTAS_TYPE_PMGM_POWER_SW_OFF	0x61
+-#define RTAS_TYPE_PMGM_LID_OPEN		0x62
+-#define RTAS_TYPE_PMGM_LID_CLOSE	0x63
+-#define RTAS_TYPE_PMGM_SLEEP_BTN	0x64
+-#define RTAS_TYPE_PMGM_WAKE_BTN		0x65
+-#define RTAS_TYPE_PMGM_BATTERY_WARN	0x66
+-#define RTAS_TYPE_PMGM_BATTERY_CRIT	0x67
+-#define RTAS_TYPE_PMGM_SWITCH_TO_BAT	0x68
+-#define RTAS_TYPE_PMGM_SWITCH_TO_AC	0x69
+-#define RTAS_TYPE_PMGM_KBD_OR_MOUSE	0x6a
+-#define RTAS_TYPE_PMGM_ENCLOS_OPEN	0x6b
+-#define RTAS_TYPE_PMGM_ENCLOS_CLOSED	0x6c
+-#define RTAS_TYPE_PMGM_RING_INDICATE	0x6d
+-#define RTAS_TYPE_PMGM_LAN_ATTENTION	0x6e
+-#define RTAS_TYPE_PMGM_TIME_ALARM	0x6f
+-#define RTAS_TYPE_PMGM_CONFIG_CHANGE	0x70
+-#define RTAS_TYPE_PMGM_SERVICE_PROC	0x71
+-
+-struct rtas_error_log {
+-	unsigned long version:8;		/* Architectural version */
+-	unsigned long severity:3;		/* Severity level of error */
+-	unsigned long disposition:2;		/* Degree of recovery */
+-	unsigned long extended:1;		/* extended log present? */
+-	unsigned long /* reserved */ :2;	/* Reserved for future use */
+-	unsigned long initiator:4;		/* Initiator of event */
+-	unsigned long target:4;			/* Target of failed operation */
+-	unsigned long type:8;			/* General event or error*/
+-	unsigned long extended_log_length:32;	/* length in bytes */
+-	unsigned char buffer[1];
+-};
+-
+-struct flash_block {
+-	char *data;
+-	unsigned long length;
+-};
+-
+-/* This struct is very similar but not identical to
+- * that needed by the rtas flash update.
+- * All we need to do for rtas is rewrite num_blocks
+- * into a version/length and translate the pointers
+- * to absolute.
+- */
+-#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
+-struct flash_block_list {
+-	unsigned long num_blocks;
+-	struct flash_block_list *next;
+-	struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
+-};
+-struct flash_block_list_header { /* just the header of flash_block_list */
+-	unsigned long num_blocks;
+-	struct flash_block_list *next;
+-};
+-extern struct flash_block_list_header rtas_firmware_flash_list;
+-
+-extern struct rtas_t rtas;
+-
+-extern void enter_rtas(unsigned long);
+-extern int rtas_token(const char *service);
+-extern int rtas_call(int token, int, int, int *, ...);
+-extern void call_rtas_display_status(unsigned char);
+-extern void rtas_restart(char *cmd);
+-extern void rtas_power_off(void);
+-extern void rtas_halt(void);
+-extern void rtas_os_term(char *str);
+-extern int rtas_get_sensor(int sensor, int index, int *state);
+-extern int rtas_get_power_level(int powerdomain, int *level);
+-extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
+-extern int rtas_set_indicator(int indicator, int index, int new_value);
+-extern void rtas_progress(char *s, unsigned short hex);
+-extern void rtas_initialize(void);
+-
+-struct rtc_time;
+-extern void rtas_get_boot_time(struct rtc_time *rtc_time);
+-extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
+-extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
+-
+-/* Given an RTAS status code of 9900..9905 compute the hinted delay */
+-unsigned int rtas_extended_busy_delay_time(int status);
+-static inline int rtas_is_extended_busy(int status)
+-{
+-	return status >= 9900 && status <= 9909;
+-}
+-
+-extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
+-
+-/* Error types logged.  */
+-#define ERR_FLAG_ALREADY_LOGGED	0x0
+-#define ERR_FLAG_BOOT		0x1 	/* log was pulled from NVRAM on boot */
+-#define ERR_TYPE_RTAS_LOG	0x2	/* from rtas event-scan */
+-#define ERR_TYPE_KERNEL_PANIC	0x4	/* from panic() */
+-
+-/* All the types and not flags */
+-#define ERR_TYPE_MASK	(ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC)
+-
+-#define RTAS_DEBUG KERN_DEBUG "RTAS: "
+- 
+-#define RTAS_ERROR_LOG_MAX 2048
+-
+-/*
+- * Return the firmware-specified size of the error log buffer
+- *  for all rtas calls that require an error buffer argument.
+- *  This includes 'check-exception' and 'rtas-last-error'.
+- */
+-extern int rtas_get_error_log_max(void);
+-
+-/* Event Scan Parameters */
+-#define EVENT_SCAN_ALL_EVENTS	0xf0000000
+-#define SURVEILLANCE_TOKEN	9000
+-#define LOG_NUMBER		64		/* must be a power of two */
+-#define LOG_NUMBER_MASK		(LOG_NUMBER-1)
+-
+-/* Some RTAS ops require a data buffer and that buffer must be < 4G.
+- * Rather than having a memory allocator, just use this buffer
+- * (get the lock first), make the RTAS call.  Copy the data instead
+- * of holding the buffer for long.
+- */
+-
+-#define RTAS_DATA_BUF_SIZE 4096
+-extern spinlock_t rtas_data_buf_lock;
+-extern char rtas_data_buf[RTAS_DATA_BUF_SIZE];
+-
+-extern void rtas_stop_self(void);
+-
+-/* RMO buffer reserved for user-space RTAS use */
+-extern unsigned long rtas_rmo_buf;
+-
+-#define GLOBAL_INTERRUPT_QUEUE 9005
+-
+-#endif /* _PPC64_RTAS_H */
+diff --git a/include/asm-ppc64/rwsem.h b/include/asm-ppc64/rwsem.h
+deleted file mode 100644
+--- a/include/asm-ppc64/rwsem.h
++++ /dev/null
+@@ -1,167 +0,0 @@
+-/*
+- * include/asm-ppc64/rwsem.h: R/W semaphores for PPC using the stuff
+- * in lib/rwsem.c.  Adapted largely from include/asm-i386/rwsem.h
+- * by Paul Mackerras <paulus at samba.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 _PPC64_RWSEM_H
+-#define _PPC64_RWSEM_H
+-
+-#ifdef __KERNEL__
+-#include <linux/list.h>
+-#include <linux/spinlock.h>
+-#include <asm/atomic.h>
+-#include <asm/system.h>
+-
+-/*
+- * the semaphore definition
+- */
+-struct rw_semaphore {
+-	/* XXX this should be able to be an atomic_t  -- paulus */
+-	signed int		count;
+-#define RWSEM_UNLOCKED_VALUE		0x00000000
+-#define RWSEM_ACTIVE_BIAS		0x00000001
+-#define RWSEM_ACTIVE_MASK		0x0000ffff
+-#define RWSEM_WAITING_BIAS		(-0x00010000)
+-#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
+-#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+-	spinlock_t		wait_lock;
+-	struct list_head	wait_list;
+-#if RWSEM_DEBUG
+-	int			debug;
+-#endif
+-};
+-
+-/*
+- * initialisation
+- */
+-#if RWSEM_DEBUG
+-#define __RWSEM_DEBUG_INIT      , 0
+-#else
+-#define __RWSEM_DEBUG_INIT	/* */
+-#endif
+-
+-#define __RWSEM_INITIALIZER(name) \
+-	{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+-	  LIST_HEAD_INIT((name).wait_list) \
+-	  __RWSEM_DEBUG_INIT }
+-
+-#define DECLARE_RWSEM(name)		\
+-	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+-
+-extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+-extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+-extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
+-extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
+-
+-static inline void init_rwsem(struct rw_semaphore *sem)
+-{
+-	sem->count = RWSEM_UNLOCKED_VALUE;
+-	spin_lock_init(&sem->wait_lock);
+-	INIT_LIST_HEAD(&sem->wait_list);
+-#if RWSEM_DEBUG
+-	sem->debug = 0;
+-#endif
+-}
+-
+-/*
+- * lock for reading
+- */
+-static inline void __down_read(struct rw_semaphore *sem)
+-{
+-	if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0))
+-		rwsem_down_read_failed(sem);
+-}
+-
+-static inline int __down_read_trylock(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	while ((tmp = sem->count) >= 0) {
+-		if (tmp == cmpxchg(&sem->count, tmp,
+-				   tmp + RWSEM_ACTIVE_READ_BIAS)) {
+-			return 1;
+-		}
+-	}
+-	return 0;
+-}
+-
+-/*
+- * lock for writing
+- */
+-static inline void __down_write(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+-				(atomic_t *)(&sem->count));
+-	if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
+-		rwsem_down_write_failed(sem);
+-}
+-
+-static inline int __down_write_trylock(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+-		      RWSEM_ACTIVE_WRITE_BIAS);
+-	return tmp == RWSEM_UNLOCKED_VALUE;
+-}
+-
+-/*
+- * unlock after reading
+- */
+-static inline void __up_read(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	tmp = atomic_dec_return((atomic_t *)(&sem->count));
+-	if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0))
+-		rwsem_wake(sem);
+-}
+-
+-/*
+- * unlock after writing
+- */
+-static inline void __up_write(struct rw_semaphore *sem)
+-{
+-	if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+-			      (atomic_t *)(&sem->count)) < 0))
+-		rwsem_wake(sem);
+-}
+-
+-/*
+- * implement atomic add functionality
+- */
+-static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+-{
+-	atomic_add(delta, (atomic_t *)(&sem->count));
+-}
+-
+-/*
+- * downgrade write lock to read lock
+- */
+-static inline void __downgrade_write(struct rw_semaphore *sem)
+-{
+-	int tmp;
+-
+-	tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
+-	if (tmp < 0)
+-		rwsem_downgrade_wake(sem);
+-}
+-
+-/*
+- * implement exchange and add functionality
+- */
+-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+-{
+-	return atomic_add_return(delta, (atomic_t *)(&sem->count));
+-}
+-
+-#endif /* __KERNEL__ */
+-#endif /* _PPC_RWSEM_XADD_H */
+diff --git a/include/asm-ppc64/scatterlist.h b/include/asm-ppc64/scatterlist.h
+deleted file mode 100644
+--- a/include/asm-ppc64/scatterlist.h
++++ /dev/null
+@@ -1,31 +0,0 @@
+-#ifndef _PPC64_SCATTERLIST_H
+-#define _PPC64_SCATTERLIST_H
+-
+-/*
+- * Copyright (C) 2001 PPC64 Team, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-#include <linux/types.h>
+-#include <asm/dma.h>
+-
+-struct scatterlist {
+-	struct page *page;
+-	unsigned int offset;
+-	unsigned int length;
+-
+-	/* For TCE support */
+-	u32 dma_address;
+-	u32 dma_length;
+-};
+-
+-#define sg_dma_address(sg)	((sg)->dma_address)
+-#define sg_dma_len(sg)		((sg)->dma_length)
+-
+-#define ISA_DMA_THRESHOLD	(~0UL)
+-
+-#endif /* !(_PPC64_SCATTERLIST_H) */
+diff --git a/include/asm-ppc64/seccomp.h b/include/asm-ppc64/seccomp.h
+deleted file mode 100644
+--- a/include/asm-ppc64/seccomp.h
++++ /dev/null
+@@ -1,21 +0,0 @@
+-#ifndef _ASM_SECCOMP_H
+-
+-#include <linux/thread_info.h> /* already defines TIF_32BIT */
+-
+-#ifndef TIF_32BIT
+-#error "unexpected TIF_32BIT on ppc64"
+-#endif
+-
+-#include <linux/unistd.h>
+-
+-#define __NR_seccomp_read __NR_read
+-#define __NR_seccomp_write __NR_write
+-#define __NR_seccomp_exit __NR_exit
+-#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+-
+-#define __NR_seccomp_read_32 __NR_read
+-#define __NR_seccomp_write_32 __NR_write
+-#define __NR_seccomp_exit_32 __NR_exit
+-#define __NR_seccomp_sigreturn_32 __NR_sigreturn
+-
+-#endif /* _ASM_SECCOMP_H */
+diff --git a/include/asm-ppc64/sections.h b/include/asm-ppc64/sections.h
+deleted file mode 100644
+--- a/include/asm-ppc64/sections.h
++++ /dev/null
+@@ -1,29 +0,0 @@
+-#ifndef _PPC64_SECTIONS_H
+-#define _PPC64_SECTIONS_H
+-
+-extern char _end[];
+-
+-#include <asm-generic/sections.h>
+-
+-#define __pmac
+-#define __pmacdata
+-
+-#define __prep
+-#define __prepdata
+-
+-#define __chrp
+-#define __chrpdata
+-
+-#define __openfirmware
+-#define __openfirmwaredata
+-
+-
+-static inline int in_kernel_text(unsigned long addr)
+-{
+-	if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end)
+-		return 1;
+-
+-	return 0;
+-}
+-
+-#endif
+diff --git a/include/asm-ppc64/semaphore.h b/include/asm-ppc64/semaphore.h
+deleted file mode 100644
+--- a/include/asm-ppc64/semaphore.h
++++ /dev/null
+@@ -1,98 +0,0 @@
+-#ifndef _PPC64_SEMAPHORE_H
+-#define _PPC64_SEMAPHORE_H
+-
+-/*
+- * Remove spinlock-based RW semaphores; RW semaphore definitions are
+- * now in rwsem.h and we use the generic lib/rwsem.c implementation.
+- * Rework semaphores to use atomic_dec_if_positive.
+- * -- Paul Mackerras (paulus at samba.org)
+- */
+-
+-#ifdef __KERNEL__
+-
+-#include <asm/atomic.h>
+-#include <asm/system.h>
+-#include <linux/wait.h>
+-#include <linux/rwsem.h>
+-
+-struct semaphore {
+-	/*
+-	 * Note that any negative value of count is equivalent to 0,
+-	 * but additionally indicates that some process(es) might be
+-	 * sleeping on `wait'.
+-	 */
+-	atomic_t count;
+-	wait_queue_head_t wait;
+-};
+-
+-#define __SEMAPHORE_INITIALIZER(name, n)				\
+-{									\
+-	.count		= ATOMIC_INIT(n),				\
+-	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+-}
+-
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name, 1)
+-
+-#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
+-	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+-
+-#define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC(name, 1)
+-#define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC(name, 0)
+-
+-static inline void sema_init (struct semaphore *sem, int val)
+-{
+-	atomic_set(&sem->count, val);
+-	init_waitqueue_head(&sem->wait);
+-}
+-
+-static inline void init_MUTEX (struct semaphore *sem)
+-{
+-	sema_init(sem, 1);
+-}
+-
+-static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+-{
+-	sema_init(sem, 0);
+-}
+-
+-extern void __down(struct semaphore * sem);
+-extern int  __down_interruptible(struct semaphore * sem);
+-extern void __up(struct semaphore * sem);
+-
+-static inline void down(struct semaphore * sem)
+-{
+-	might_sleep();
+-
+-	/*
+-	 * Try to get the semaphore, take the slow path if we fail.
+-	 */
+-	if (unlikely(atomic_dec_return(&sem->count) < 0))
+-		__down(sem);
+-}
+-
+-static inline int down_interruptible(struct semaphore * sem)
+-{
+-	int ret = 0;
+-
+-	might_sleep();
+-
+-	if (unlikely(atomic_dec_return(&sem->count) < 0))
+-		ret = __down_interruptible(sem);
+-	return ret;
+-}
+-
+-static inline int down_trylock(struct semaphore * sem)
+-{
+-	return atomic_dec_if_positive(&sem->count) < 0;
+-}
+-
+-static inline void up(struct semaphore * sem)
+-{
+-	if (unlikely(atomic_inc_return(&sem->count) <= 0))
+-		__up(sem);
+-}
+-
+-#endif /* __KERNEL__ */
+-
+-#endif /* !(_PPC64_SEMAPHORE_H) */
+diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
+--- a/include/asm-ppc64/smp.h
++++ b/include/asm-ppc64/smp.h
+@@ -77,7 +77,6 @@ extern int smt_enabled_at_boot;
+ 
+ extern int smp_mpic_probe(void);
+ extern void smp_mpic_setup_cpu(int cpu);
+-extern void smp_mpic_message_pass(int target, int msg);
+ extern void smp_generic_kick_cpu(int nr);
+ 
+ extern void smp_generic_give_timebase(void);
+diff --git a/include/asm-ppc64/smu.h b/include/asm-ppc64/smu.h
+deleted file mode 100644
+--- a/include/asm-ppc64/smu.h
++++ /dev/null
+@@ -1,379 +0,0 @@
+-#ifndef _SMU_H
+-#define _SMU_H
+-
+-/*
+- * Definitions for talking to the SMU chip in newer G5 PowerMacs
+- */
+-
+-#include <linux/config.h>
+-#include <linux/list.h>
+-
+-/*
+- * Known SMU commands
+- *
+- * Most of what is below comes from looking at the Open Firmware driver,
+- * though this is still incomplete and could use better documentation here
+- * or there...
+- */
+-
+-
+-/*
+- * Partition info commands
+- *
+- * I do not know what those are for at this point
+- */
+-#define SMU_CMD_PARTITION_COMMAND		0x3e
+-
+-
+-/*
+- * Fan control
+- *
+- * This is a "mux" for fan control commands, first byte is the
+- * "sub" command.
+- */
+-#define SMU_CMD_FAN_COMMAND			0x4a
+-
+-
+-/*
+- * Battery access
+- *
+- * Same command number as the PMU, could it be same syntax ?
+- */
+-#define SMU_CMD_BATTERY_COMMAND			0x6f
+-#define   SMU_CMD_GET_BATTERY_INFO		0x00
+-
+-/*
+- * Real time clock control
+- *
+- * This is a "mux", first data byte contains the "sub" command.
+- * The "RTC" part of the SMU controls the date, time, powerup
+- * timer, but also a PRAM
+- *
+- * Dates are in BCD format on 7 bytes:
+- * [sec] [min] [hour] [weekday] [month day] [month] [year]
+- * with month being 1 based and year minus 100
+- */
+-#define SMU_CMD_RTC_COMMAND			0x8e
+-#define   SMU_CMD_RTC_SET_PWRUP_TIMER		0x00 /* i: 7 bytes date */
+-#define   SMU_CMD_RTC_GET_PWRUP_TIMER		0x01 /* o: 7 bytes date */
+-#define   SMU_CMD_RTC_STOP_PWRUP_TIMER		0x02
+-#define   SMU_CMD_RTC_SET_PRAM_BYTE_ACC		0x20 /* i: 1 byte (address?) */
+-#define   SMU_CMD_RTC_SET_PRAM_AUTOINC		0x21 /* i: 1 byte (data?) */
+-#define   SMU_CMD_RTC_SET_PRAM_LO_BYTES 	0x22 /* i: 10 bytes */
+-#define   SMU_CMD_RTC_SET_PRAM_HI_BYTES 	0x23 /* i: 10 bytes */
+-#define   SMU_CMD_RTC_GET_PRAM_BYTE		0x28 /* i: 1 bytes (address?) */
+-#define   SMU_CMD_RTC_GET_PRAM_LO_BYTES 	0x29 /* o: 10 bytes */
+-#define   SMU_CMD_RTC_GET_PRAM_HI_BYTES 	0x2a /* o: 10 bytes */
+-#define	  SMU_CMD_RTC_SET_DATETIME		0x80 /* i: 7 bytes date */
+-#define   SMU_CMD_RTC_GET_DATETIME		0x81 /* o: 7 bytes date */
+-
+- /*
+-  * i2c commands
+-  *
+-  * To issue an i2c command, first is to send a parameter block to the
+-  * the SMU. This is a command of type 0x9a with 9 bytes of header
+-  * eventually followed by data for a write:
+-  *
+-  * 0: bus number (from device-tree usually, SMU has lots of busses !)
+-  * 1: transfer type/format (see below)
+-  * 2: device address. For combined and combined4 type transfers, this
+-  *    is the "write" version of the address (bit 0x01 cleared)
+-  * 3: subaddress length (0..3)
+-  * 4: subaddress byte 0 (or only byte for subaddress length 1)
+-  * 5: subaddress byte 1
+-  * 6: subaddress byte 2
+-  * 7: combined address (device address for combined mode data phase)
+-  * 8: data length
+-  *
+-  * The transfer types are the same good old Apple ones it seems,
+-  * that is:
+-  *   - 0x00: Simple transfer
+-  *   - 0x01: Subaddress transfer (addr write + data tx, no restart)
+-  *   - 0x02: Combined transfer (addr write + restart + data tx)
+-  *
+-  * This is then followed by actual data for a write.
+-  *
+-  * At this point, the OF driver seems to have a limitation on transfer
+-  * sizes of 0xd bytes on reads and 0x5 bytes on writes. I do not know
+-  * wether this is just an OF limit due to some temporary buffer size
+-  * or if this is an SMU imposed limit. This driver has the same limitation
+-  * for now as I use a 0x10 bytes temporary buffer as well
+-  *
+-  * Once that is completed, a response is expected from the SMU. This is
+-  * obtained via a command of type 0x9a with a length of 1 byte containing
+-  * 0 as the data byte. OF also fills the rest of the data buffer with 0xff's
+-  * though I can't tell yet if this is actually necessary. Once this command
+-  * is complete, at this point, all I can tell is what OF does. OF tests
+-  * byte 0 of the reply:
+-  *   - on read, 0xfe or 0xfc : bus is busy, wait (see below) or nak ?
+-  *   - on read, 0x00 or 0x01 : reply is in buffer (after the byte 0)
+-  *   - on write, < 0 -> failure (immediate exit)
+-  *   - else, OF just exists (without error, weird)
+-  *
+-  * So on read, there is this wait-for-busy thing when getting a 0xfc or
+-  * 0xfe result. OF does a loop of up to 64 retries, waiting 20ms and
+-  * doing the above again until either the retries expire or the result
+-  * is no longer 0xfe or 0xfc
+-  *
+-  * The Darwin I2C driver is less subtle though. On any non-success status
+-  * from the response command, it waits 5ms and tries again up to 20 times,
+-  * it doesn't differenciate between fatal errors or "busy" status.
+-  *
+-  * This driver provides an asynchronous paramblock based i2c command
+-  * interface to be used either directly by low level code or by a higher
+-  * level driver interfacing to the linux i2c layer. The current
+-  * implementation of this relies on working timers & timer interrupts
+-  * though, so be careful of calling context for now. This may be "fixed"
+-  * in the future by adding a polling facility.
+-  */
+-#define SMU_CMD_I2C_COMMAND			0x9a
+-          /* transfer types */
+-#define   SMU_I2C_TRANSFER_SIMPLE	0x00
+-#define   SMU_I2C_TRANSFER_STDSUB	0x01
+-#define   SMU_I2C_TRANSFER_COMBINED	0x02
+-
+-/*
+- * Power supply control
+- *
+- * The "sub" command is an ASCII string in the data, the
+- * data lenght is that of the string.
+- *
+- * The VSLEW command can be used to get or set the voltage slewing.
+- *  - lenght 5 (only "VSLEW") : it returns "DONE" and 3 bytes of
+- *    reply at data offset 6, 7 and 8.
+- *  - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is
+- *    used to set the voltage slewing point. The SMU replies with "DONE"
+- * I yet have to figure out their exact meaning of those 3 bytes in
+- * both cases.
+- *
+- */
+-#define SMU_CMD_POWER_COMMAND			0xaa
+-#define   SMU_CMD_POWER_RESTART		       	"RESTART"
+-#define   SMU_CMD_POWER_SHUTDOWN		"SHUTDOWN"
+-#define   SMU_CMD_POWER_VOLTAGE_SLEW		"VSLEW"
+-
+-/* Misc commands
+- *
+- * This command seem to be a grab bag of various things
+- */
+-#define SMU_CMD_MISC_df_COMMAND			0xdf
+-#define   SMU_CMD_MISC_df_SET_DISPLAY_LIT	0x02 /* i: 1 byte */
+-#define   SMU_CMD_MISC_df_NMI_OPTION		0x04
+-
+-/*
+- * Version info commands
+- *
+- * I haven't quite tried to figure out how these work
+- */
+-#define SMU_CMD_VERSION_COMMAND			0xea
+-
+-
+-/*
+- * Misc commands
+- *
+- * This command seem to be a grab bag of various things
+- */
+-#define SMU_CMD_MISC_ee_COMMAND			0xee
+-#define   SMU_CMD_MISC_ee_GET_DATABLOCK_REC	0x02
+-#define	  SMU_CMD_MISC_ee_LEDS_CTRL		0x04 /* i: 00 (00,01) [00] */
+-#define   SMU_CMD_MISC_ee_GET_DATA		0x05 /* i: 00 , o: ?? */
+-
+-
+-
+-/*
+- * - Kernel side interface -
+- */
+-
+-#ifdef __KERNEL__
+-
+-/*
+- * Asynchronous SMU commands
+- *
+- * Fill up this structure and submit it via smu_queue_command(),
+- * and get notified by the optional done() callback, or because
+- * status becomes != 1
+- */
+-
+-struct smu_cmd;
+-
+-struct smu_cmd
+-{
+-	/* public */
+-	u8			cmd;		/* command */
+-	int			data_len;	/* data len */
+-	int			reply_len;	/* reply len */
+-	void			*data_buf;	/* data buffer */
+-	void			*reply_buf;	/* reply buffer */
+-	int			status;		/* command status */
+-	void			(*done)(struct smu_cmd *cmd, void *misc);
+-	void			*misc;
+-
+-	/* private */
+-	struct list_head	link;
+-};
+-
+-/*
+- * Queues an SMU command, all fields have to be initialized
+- */
+-extern int smu_queue_cmd(struct smu_cmd *cmd);
+-
+-/*
+- * Simple command wrapper. This structure embeds a small buffer
+- * to ease sending simple SMU commands from the stack
+- */
+-struct smu_simple_cmd
+-{
+-	struct smu_cmd	cmd;
+-	u8	       	buffer[16];
+-};
+-
+-/*
+- * Queues a simple command. All fields will be initialized by that
+- * function
+- */
+-extern int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command,
+-			    unsigned int data_len,
+-			    void (*done)(struct smu_cmd *cmd, void *misc),
+-			    void *misc,
+-			    ...);
+-
+-/*
+- * Completion helper. Pass it to smu_queue_simple or as 'done'
+- * member to smu_queue_cmd, it will call complete() on the struct
+- * completion passed in the "misc" argument
+- */
+-extern void smu_done_complete(struct smu_cmd *cmd, void *misc);
+-
+-/*
+- * Synchronous helpers. Will spin-wait for completion of a command
+- */
+-extern void smu_spinwait_cmd(struct smu_cmd *cmd);
+-
+-static inline void smu_spinwait_simple(struct smu_simple_cmd *scmd)
+-{
+-	smu_spinwait_cmd(&scmd->cmd);
+-}
+-
+-/*
+- * Poll routine to call if blocked with irqs off
+- */
+-extern void smu_poll(void);
+-
+-
+-/*
+- * Init routine, presence check....
+- */
+-extern int smu_init(void);
+-extern int smu_present(void);
+-struct of_device;
+-extern struct of_device *smu_get_ofdev(void);
+-
+-
+-/*
+- * Common command wrappers
+- */
+-extern void smu_shutdown(void);
+-extern void smu_restart(void);
+-struct rtc_time;
+-extern int smu_get_rtc_time(struct rtc_time *time, int spinwait);
+-extern int smu_set_rtc_time(struct rtc_time *time, int spinwait);
+-
+-/*
+- * SMU command buffer absolute address, exported by pmac_setup,
+- * this is allocated very early during boot.
+- */
+-extern unsigned long smu_cmdbuf_abs;
+-
+-
+-/*
+- * Kenrel asynchronous i2c interface
+- */
+-
+-/* SMU i2c header, exactly matches i2c header on wire */
+-struct smu_i2c_param
+-{
+-	u8	bus;		/* SMU bus ID (from device tree) */
+-	u8	type;		/* i2c transfer type */
+-	u8	devaddr;	/* device address (includes direction) */
+-	u8	sublen;		/* subaddress length */
+-	u8	subaddr[3];	/* subaddress */
+-	u8	caddr;		/* combined address, filled by SMU driver */
+-	u8	datalen;	/* length of transfer */
+-	u8	data[7];	/* data */
+-};
+-
+-#define SMU_I2C_READ_MAX	0x0d
+-#define SMU_I2C_WRITE_MAX	0x05
+-
+-struct smu_i2c_cmd
+-{
+-	/* public */
+-	struct smu_i2c_param	info;
+-	void			(*done)(struct smu_i2c_cmd *cmd, void *misc);
+-	void			*misc;
+-	int			status; /* 1 = pending, 0 = ok, <0 = fail */
+-
+-	/* private */
+-	struct smu_cmd		scmd;
+-	int			read;
+-	int			stage;
+-	int			retries;
+-	u8			pdata[0x10];
+-	struct list_head	link;
+-};
+-
+-/*
+- * Call this to queue an i2c command to the SMU. You must fill info,
+- * including info.data for a write, done and misc.
+- * For now, no polling interface is provided so you have to use completion
+- * callback.
+- */
+-extern int smu_queue_i2c(struct smu_i2c_cmd *cmd);
+-
+-
+-#endif /* __KERNEL__ */
+-
+-/*
+- * - Userland interface -
+- */
+-
+-/*
+- * A given instance of the device can be configured for 2 different
+- * things at the moment:
+- *
+- *  - sending SMU commands (default at open() time)
+- *  - receiving SMU events (not yet implemented)
+- *
+- * Commands are written with write() of a command block. They can be
+- * "driver" commands (for example to switch to event reception mode)
+- * or real SMU commands. They are made of a header followed by command
+- * data if any.
+- *
+- * For SMU commands (not for driver commands), you can then read() back
+- * a reply. The reader will be blocked or not depending on how the device
+- * file is opened. poll() isn't implemented yet. The reply will consist
+- * of a header as well, followed by the reply data if any. You should
+- * always provide a buffer large enough for the maximum reply data, I
+- * recommand one page.
+- *
+- * It is illegal to send SMU commands through a file descriptor configured
+- * for events reception
+- *
+- */
+-struct smu_user_cmd_hdr
+-{
+-	__u32		cmdtype;
+-#define SMU_CMDTYPE_SMU			0	/* SMU command */
+-#define SMU_CMDTYPE_WANTS_EVENTS	1	/* switch fd to events mode */
+-
+-	__u8		cmd;			/* SMU command byte */
+-	__u32		data_len;		/* Lenght of data following */
+-};
+-
+-struct smu_user_reply_hdr
+-{
+-	__u32		status;			/* Command status */
+-	__u32		reply_len;		/* Lenght of data follwing */
+-};
+-
+-#endif /*  _SMU_H */
+diff --git a/include/asm-ppc64/spinlock_types.h b/include/asm-ppc64/spinlock_types.h
+deleted file mode 100644
+--- a/include/asm-ppc64/spinlock_types.h
++++ /dev/null
+@@ -1,20 +0,0 @@
+-#ifndef __ASM_SPINLOCK_TYPES_H
+-#define __ASM_SPINLOCK_TYPES_H
+-
+-#ifndef __LINUX_SPINLOCK_TYPES_H
+-# error "please don't include this file directly"
+-#endif
+-
+-typedef struct {
+-	volatile unsigned int slock;
+-} raw_spinlock_t;
+-
+-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+-
+-typedef struct {
+-	volatile signed int lock;
+-} raw_rwlock_t;
+-
+-#define __RAW_RW_LOCK_UNLOCKED		{ 0 }
+-
+-#endif
+diff --git a/include/asm-ppc64/sstep.h b/include/asm-ppc64/sstep.h
+deleted file mode 100644
+--- a/include/asm-ppc64/sstep.h
++++ /dev/null
+@@ -1,24 +0,0 @@
+-/*
+- * Copyright (C) 2004 Paul Mackerras <paulus at au.ibm.com>, 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.
+- */
+-
+-struct pt_regs;
+-
+-/*
+- * We don't allow single-stepping an mtmsrd that would clear
+- * MSR_RI, since that would make the exception unrecoverable.
+- * Since we need to single-step to proceed from a breakpoint,
+- * we don't allow putting a breakpoint on an mtmsrd instruction.
+- * Similarly we don't allow breakpoints on rfid instructions.
+- * These macros tell us if an instruction is a mtmsrd or rfid.
+- */
+-#define IS_MTMSRD(instr)	(((instr) & 0xfc0007fe) == 0x7c000164)
+-#define IS_RFID(instr)		(((instr) & 0xfc0007fe) == 0x4c000024)
+-
+-/* Emulate instructions that cause a transfer of control. */
+-extern int emulate_step(struct pt_regs *regs, unsigned int instr);
+diff --git a/include/asm-ppc64/statfs.h b/include/asm-ppc64/statfs.h
+deleted file mode 100644
+--- a/include/asm-ppc64/statfs.h
++++ /dev/null
+@@ -1,61 +0,0 @@
+-#ifndef _PPC64_STATFS_H
+-#define _PPC64_STATFS_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.
+- */
+-
+-#ifndef __KERNEL_STRICT_NAMES
+-#include <linux/types.h>
+-typedef __kernel_fsid_t	fsid_t;
+-#endif
+-
+-/*
+- * We're already 64-bit, so duplicate the definition
+- */
+-struct statfs {
+-	long f_type;
+-	long f_bsize;
+-	long f_blocks;
+-	long f_bfree;
+-	long f_bavail;
+-	long f_files;
+-	long f_ffree;
+-	__kernel_fsid_t f_fsid;
+-	long f_namelen;
+-	long f_frsize;
+-	long f_spare[5];
+-};
+-
+-struct statfs64 {
+-	long f_type;
+-	long f_bsize;
+-	long f_blocks;
+-	long f_bfree;
+-	long f_bavail;
+-	long f_files;
+-	long f_ffree;
+-	__kernel_fsid_t f_fsid;
+-	long f_namelen;
+-	long f_frsize;
+-	long f_spare[5];
+-};
+-
+-struct compat_statfs64 {
+-	__u32 f_type;
+-	__u32 f_bsize;
+-	__u64 f_blocks;
+-	__u64 f_bfree;
+-	__u64 f_bavail;
+-	__u64 f_files;
+-	__u64 f_ffree;
+-	__kernel_fsid_t f_fsid;
+-	__u32 f_namelen;
+-	__u32 f_frsize;
+-	__u32 f_spare[5];
+-};
+-
+-#endif  /* _PPC64_STATFS_H */
+diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
+--- a/include/asm-ppc64/system.h
++++ b/include/asm-ppc64/system.h
+@@ -13,7 +13,7 @@
+ #include <asm/page.h>
+ #include <asm/processor.h>
+ #include <asm/hw_irq.h>
+-#include <asm/memory.h>
++#include <asm/synch.h>
+ 
+ /*
+  * Memory barrier.
+@@ -48,7 +48,7 @@
+ #ifdef CONFIG_SMP
+ #define smp_mb()	mb()
+ #define smp_rmb()	rmb()
+-#define smp_wmb()	__asm__ __volatile__ ("eieio" : : : "memory")
++#define smp_wmb()	eieio()
+ #define smp_read_barrier_depends()  read_barrier_depends()
+ #else
+ #define smp_mb()	__asm__ __volatile__("": : :"memory")
+@@ -120,8 +120,8 @@ extern void giveup_altivec(struct task_s
+ extern void disable_kernel_altivec(void);
+ extern void enable_kernel_altivec(void);
+ extern int emulate_altivec(struct pt_regs *);
+-extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
+-extern void cvt_df(double *from, float *to, unsigned long *fpscr);
++extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
++extern void cvt_df(double *from, float *to, struct thread_struct *thread);
+ 
+ #ifdef CONFIG_ALTIVEC
+ extern void flush_altivec_to_thread(struct task_struct *);
+@@ -131,7 +131,12 @@ static inline void flush_altivec_to_thre
+ }
+ #endif
+ 
++static inline void flush_spe_to_thread(struct task_struct *t)
++{
++}
++
+ extern int mem_init_done;	/* set on boot once kmalloc can be called */
++extern unsigned long memory_limit;
+ 
+ /* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
+ extern unsigned char e2a(unsigned char);
+@@ -144,12 +149,7 @@ struct thread_struct;
+ extern struct task_struct * _switch(struct thread_struct *prev,
+ 				    struct thread_struct *next);
+ 
+-static inline int __is_processor(unsigned long pv)
+-{
+-	unsigned long pvr;
+-	asm("mfspr %0, 0x11F" : "=r" (pvr)); 
+-	return(PVR_VER(pvr) == pv);
+-}
++extern int powersave_nap;	/* set if nap mode can be used in idle loop */
+ 
+ /*
+  * Atomic exchange
+diff --git a/include/asm-ppc64/tce.h b/include/asm-ppc64/tce.h
+new file mode 100644
+--- /dev/null
++++ b/include/asm-ppc64/tce.h
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
++ * Rewrite, cleanup:
++ * Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, 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
++ */
++
++#ifndef _ASM_TCE_H
++#define _ASM_TCE_H
++
++/*
++ * Tces come in two formats, one for the virtual bus and a different
++ * format for PCI
++ */
++#define TCE_VB  0
++#define TCE_PCI 1
++
++/* TCE page size is 4096 bytes (1 << 12) */
++
++#define TCE_SHIFT	12
++#define TCE_PAGE_SIZE	(1 << TCE_SHIFT)
++#define TCE_PAGE_FACTOR	(PAGE_SHIFT - TCE_SHIFT)
++
++
++/* tce_entry
++ * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
++ * abstracted so layout is irrelevant.
++ */
++union tce_entry {
++   	unsigned long te_word;
++	struct {
++		unsigned int  tb_cacheBits :6;	/* Cache hash bits - not used */
++		unsigned int  tb_rsvd      :6;
++		unsigned long tb_rpn       :40;	/* Real page number */
++		unsigned int  tb_valid     :1;	/* Tce is valid (vb only) */
++		unsigned int  tb_allio     :1;	/* Tce is valid for all lps (vb only) */
++		unsigned int  tb_lpindex   :8;	/* LpIndex for user of TCE (vb only) */
++		unsigned int  tb_pciwr     :1;	/* Write allowed (pci only) */
++		unsigned int  tb_rdwr      :1;	/* Read allowed  (pci), Write allowed (vb) */
++	} te_bits;
++#define te_cacheBits te_bits.tb_cacheBits
++#define te_rpn       te_bits.tb_rpn
++#define te_valid     te_bits.tb_valid
++#define te_allio     te_bits.tb_allio
++#define te_lpindex   te_bits.tb_lpindex
++#define te_pciwr     te_bits.tb_pciwr
++#define te_rdwr      te_bits.tb_rdwr
++};
++
++
++#endif
+diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
+deleted file mode 100644
+--- a/include/asm-ppc64/thread_info.h
++++ /dev/null
+@@ -1,125 +0,0 @@
+-/* thread_info.h: PPC low-level thread information
+- * adapted from the i386 version by Paul Mackerras
+- *
+- * Copyright (C) 2002  David Howells (dhowells at redhat.com)
+- * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+- */
+-
+-#ifndef _ASM_THREAD_INFO_H
+-#define _ASM_THREAD_INFO_H
+-
+-#ifdef __KERNEL__
+-
+-#ifndef __ASSEMBLY__
+-#include <linux/config.h>
+-#include <linux/cache.h>
+-#include <asm/processor.h>
+-#include <asm/page.h>
+-#include <linux/stringify.h>
+-
+-/*
+- * low level task data.
+- */
+-struct thread_info {
+-	struct task_struct *task;		/* main task structure */
+-	struct exec_domain *exec_domain;	/* execution domain */
+-	int		cpu;			/* cpu we're on */
+-	int		preempt_count;		/* 0 => preemptable, <0 => BUG */
+-	struct restart_block restart_block;
+-	/* set by force_successful_syscall_return */
+-	unsigned char	syscall_noerror;
+-	/* low level flags - has atomic operations done on it */
+-	unsigned long	flags ____cacheline_aligned_in_smp;
+-};
+-
+-/*
+- * macros/functions for gaining access to the thread information structure
+- *
+- * preempt_count needs to be 1 initially, until the scheduler is functional.
+- */
+-#define INIT_THREAD_INFO(tsk)			\
+-{						\
+-	.task =		&tsk,			\
+-	.exec_domain =	&default_exec_domain,	\
+-	.cpu =		0,			\
+-	.preempt_count = 1,			\
+-	.restart_block = {			\
+-		.fn = do_no_restart_syscall,	\
+-	},					\
+-	.flags =	0,			\
+-}
+-
+-#define init_thread_info	(init_thread_union.thread_info)
+-#define init_stack		(init_thread_union.stack)
+-
+-/* thread information allocation */
+-
+-#define THREAD_ORDER		2
+-#define THREAD_SIZE		(PAGE_SIZE << THREAD_ORDER)
+-#define THREAD_SHIFT		(PAGE_SHIFT + THREAD_ORDER)
+-#ifdef CONFIG_DEBUG_STACK_USAGE
+-#define alloc_thread_info(tsk)					\
+-	({							\
+-		struct thread_info *ret;			\
+-								\
+-		ret = kmalloc(THREAD_SIZE, GFP_KERNEL);		\
+-		if (ret)					\
+-			memset(ret, 0, THREAD_SIZE);		\
+-		ret;						\
+-	})
+-#else
+-#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+-#endif
+-#define free_thread_info(ti)	kfree(ti)
+-#define get_thread_info(ti)	get_task_struct((ti)->task)
+-#define put_thread_info(ti)	put_task_struct((ti)->task)
+-
+-/* how to get the thread information struct from C */
+-static inline struct thread_info *current_thread_info(void)
+-{
+-	struct thread_info *ti;
+-	__asm__("clrrdi %0,1,%1" : "=r"(ti) : "i" (THREAD_SHIFT));
+-	return ti;
+-}
+-
+-#endif /* __ASSEMBLY__ */
+-
+-#define PREEMPT_ACTIVE		0x10000000
+-
+-/*
+- * thread information flag bit numbers
+- */
+-#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+-#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+-#define TIF_SIGPENDING		2	/* signal pending */
+-#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+-#define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
+-					   TIF_NEED_RESCHED */
+-#define TIF_32BIT		5	/* 32 bit binary */
+-/* #define SPARE		6 */
+-#define TIF_ABI_PENDING		7	/* 32/64 bit switch needed */
+-#define TIF_SYSCALL_AUDIT	8	/* syscall auditing active */
+-#define TIF_SINGLESTEP		9	/* singlestepping active */
+-#define TIF_MEMDIE		10
+-#define TIF_SECCOMP		11	/* secure computing */
+-
+-/* as above, but as bit values */
+-#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+-#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+-#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+-#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+-#define _TIF_32BIT		(1<<TIF_32BIT)
+-/* #define _SPARE		(1<<SPARE) */
+-#define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
+-#define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
+-#define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
+-#define _TIF_SECCOMP		(1<<TIF_SECCOMP)
+-#define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
+-
+-#define _TIF_USER_WORK_MASK	(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
+-				 _TIF_NEED_RESCHED)
+-
+-#endif /* __KERNEL__ */
+-
+-#endif /* _ASM_THREAD_INFO_H */
+diff --git a/include/asm-ppc64/time.h b/include/asm-ppc64/time.h
+deleted file mode 100644
+--- a/include/asm-ppc64/time.h
++++ /dev/null
+@@ -1,124 +0,0 @@
+-/*
+- * Common time prototypes and such for all ppc machines.
+- *
+- * Written by Cort Dougan (cort at cs.nmt.edu) to merge
+- * Paul Mackerras' version and mine for PReP and Pmac.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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 __PPC64_TIME_H
+-#define __PPC64_TIME_H
+-
+-#ifdef __KERNEL__
+-#include <linux/config.h>
+-#include <linux/types.h>
+-#include <linux/mc146818rtc.h>
+-
+-#include <asm/processor.h>
+-#include <asm/paca.h>
+-#include <asm/iSeries/HvCall.h>
+-
+-/* time.c */
+-extern unsigned long tb_ticks_per_jiffy;
+-extern unsigned long tb_ticks_per_usec;
+-extern unsigned long tb_ticks_per_sec;
+-extern unsigned long tb_to_xs;
+-extern unsigned      tb_to_us;
+-extern unsigned long tb_last_stamp;
+-
+-struct rtc_time;
+-extern void to_tm(int tim, struct rtc_time * tm);
+-extern time_t last_rtc_update;
+-
+-void generic_calibrate_decr(void);
+-void setup_default_decr(void);
+-
+-/* Some sane defaults: 125 MHz timebase, 1GHz processor */
+-extern unsigned long ppc_proc_freq;
+-#define DEFAULT_PROC_FREQ	(DEFAULT_TB_FREQ * 8)
+-extern unsigned long ppc_tb_freq;
+-#define DEFAULT_TB_FREQ		125000000UL
+-
+-/*
+- * By putting all of this stuff into a single struct we 
+- * reduce the number of cache lines touched by do_gettimeofday.
+- * Both by collecting all of the data in one cache line and
+- * by touching only one TOC entry
+- */
+-struct gettimeofday_vars {
+-	unsigned long tb_to_xs;
+-	unsigned long stamp_xsec;
+-	unsigned long tb_orig_stamp;
+-};
+-
+-struct gettimeofday_struct {
+-	unsigned long tb_ticks_per_sec;
+-	struct gettimeofday_vars vars[2];
+-	struct gettimeofday_vars * volatile varp;
+-	unsigned      var_idx;
+-	unsigned      tb_to_us;
+-};
+-
+-struct div_result {
+-	unsigned long result_high;
+-	unsigned long result_low;
+-};
+-
+-int via_calibrate_decr(void);
+-
+-static __inline__ unsigned long get_tb(void)
+-{
+-	return mftb();
+-}
+-
+-/* Accessor functions for the decrementer register. */
+-static __inline__ unsigned int get_dec(void)
+-{
+-	return (mfspr(SPRN_DEC));
+-}
+-
+-static __inline__ void set_dec(int val)
+-{
+-#ifdef CONFIG_PPC_ISERIES
+-	struct paca_struct *lpaca = get_paca();
+-	int cur_dec;
+-
+-	if (lpaca->lppaca.shared_proc) {
+-		lpaca->lppaca.virtual_decr = val;
+-		cur_dec = get_dec();
+-		if (cur_dec > val)
+-			HvCall_setVirtualDecr();
+-	} else
+-#endif
+-		mtspr(SPRN_DEC, val);
+-}
+-
+-static inline unsigned long tb_ticks_since(unsigned long tstamp)
+-{
+-	return get_tb() - tstamp;
+-}
+-
+-#define mulhwu(x,y) \
+-({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+-#define mulhdu(x,y) \
+-({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+-
+-
+-unsigned mulhwu_scale_factor(unsigned, unsigned);
+-void div128_by_32( unsigned long dividend_high, unsigned long dividend_low,
+-		   unsigned divisor, struct div_result *dr );
+-
+-/* Used to store Processor Utilization register (purr) values */
+-
+-struct cpu_usage {
+-        u64 current_tb;  /* Holds the current purr register values */
+-};
+-
+-DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
+-
+-#endif /* __KERNEL__ */
+-#endif /* __PPC64_TIME_H */
+diff --git a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h
+--- a/include/asm-ppc64/tlbflush.h
++++ b/include/asm-ppc64/tlbflush.h
+@@ -20,10 +20,8 @@
+ struct mm_struct;
+ struct ppc64_tlb_batch {
+ 	unsigned long index;
+-	unsigned long context;
+ 	struct mm_struct *mm;
+ 	pte_t pte[PPC64_TLB_BATCH_NR];
+-	unsigned long addr[PPC64_TLB_BATCH_NR];
+ 	unsigned long vaddr[PPC64_TLB_BATCH_NR];
+ 	unsigned int large;
+ };
+@@ -48,8 +46,7 @@ static inline void flush_tlb_pending(voi
+ #define flush_tlb_kernel_range(start, end)	flush_tlb_pending()
+ #define flush_tlb_pgtables(mm, start, end)	do { } while (0)
+ 
+-extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
+-			    int local);
+-void flush_hash_range(unsigned long context, unsigned long number, int local);
++extern void flush_hash_page(unsigned long va, pte_t pte, int local);
++void flush_hash_range(unsigned long number, int local);
+ 
+ #endif /* _PPC64_TLBFLUSH_H */
+diff --git a/include/asm-ppc64/types.h b/include/asm-ppc64/types.h
+deleted file mode 100644
+--- a/include/asm-ppc64/types.h
++++ /dev/null
+@@ -1,79 +0,0 @@
+-#ifndef _PPC64_TYPES_H
+-#define _PPC64_TYPES_H
+-
+-#ifndef __ASSEMBLY__
+-
+-/*
+- * This file is never included by application software unless
+- * explicitly requested (e.g., via linux/types.h) in which case the
+- * application is Linux specific so (user-) name space pollution is
+- * not a major issue.  However, for interoperability, libraries still
+- * need to be careful to avoid a name clashes.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-typedef unsigned int umode_t;
+-
+-/*
+- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+- * header files exported to user space
+- */
+-
+-typedef __signed__ char __s8;
+-typedef unsigned char __u8;
+-
+-typedef __signed__ short __s16;
+-typedef unsigned short __u16;
+-
+-typedef __signed__ int __s32;
+-typedef unsigned int __u32;
+-
+-typedef __signed__ long __s64;
+-typedef unsigned long __u64;
+-
+-typedef struct {
+-	__u32 u[4];
+-} __attribute((aligned(16))) __vector128;
+-
+-#endif /* __ASSEMBLY__ */
+-
+-#ifdef __KERNEL__
+-/*
+- * These aren't exported outside the kernel to avoid name space clashes
+- */
+-#define BITS_PER_LONG 64
+-
+-#ifndef __ASSEMBLY__
+-
+-typedef signed char s8;
+-typedef unsigned char u8;
+-
+-typedef signed short s16;
+-typedef unsigned short u16;
+-
+-typedef signed int s32;
+-typedef unsigned int u32;
+-
+-typedef signed long s64;
+-typedef unsigned long u64;
+-
+-typedef __vector128 vector128;
+-
+-typedef u32 dma_addr_t;
+-typedef u64 dma64_addr_t;
+-
+-typedef struct {
+-	unsigned long entry;
+-	unsigned long toc;
+-	unsigned long env;
+-} func_descr_t;
+-
+-#endif /* __ASSEMBLY__ */
+-
+-#endif /* __KERNEL__ */
+-
+-#endif /* _PPC64_TYPES_H */
+diff --git a/include/asm-ppc64/udbg.h b/include/asm-ppc64/udbg.h
+--- a/include/asm-ppc64/udbg.h
++++ b/include/asm-ppc64/udbg.h
+@@ -28,4 +28,7 @@ extern unsigned long udbg_ifdebug(unsign
+ extern void __init ppcdbg_initialize(void);
+ 
+ extern void udbg_init_uart(void __iomem *comport, unsigned int speed);
++
++struct device_node;
++extern void udbg_init_scc(struct device_node *np);
+ #endif
+diff --git a/include/asm-ppc64/uninorth.h b/include/asm-ppc64/uninorth.h
+deleted file mode 100644
+--- a/include/asm-ppc64/uninorth.h
++++ /dev/null
+@@ -1,2 +0,0 @@
+-#include <asm-ppc/uninorth.h>
+-
+diff --git a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
+deleted file mode 100644
+--- a/include/asm-ppc64/unistd.h
++++ /dev/null
+@@ -1,487 +0,0 @@
+-#ifndef _ASM_PPC_UNISTD_H_
+-#define _ASM_PPC_UNISTD_H_
+-
+-/*
+- * This file contains the system call numbers.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-#define __NR_restart_syscall	  0
+-#define __NR_exit		  1
+-#define __NR_fork		  2
+-#define __NR_read		  3
+-#define __NR_write		  4
+-#define __NR_open		  5
+-#define __NR_close		  6
+-#define __NR_waitpid		  7
+-#define __NR_creat		  8
+-#define __NR_link		  9
+-#define __NR_unlink		 10
+-#define __NR_execve		 11
+-#define __NR_chdir		 12
+-#define __NR_time		 13
+-#define __NR_mknod		 14
+-#define __NR_chmod		 15
+-#define __NR_lchown		 16
+-#define __NR_break		 17
+-#define __NR_oldstat		 18
+-#define __NR_lseek		 19
+-#define __NR_getpid		 20
+-#define __NR_mount		 21
+-#define __NR_umount		 22
+-#define __NR_setuid		 23
+-#define __NR_getuid		 24
+-#define __NR_stime		 25
+-#define __NR_ptrace		 26
+-#define __NR_alarm		 27
+-#define __NR_oldfstat		 28
+-#define __NR_pause		 29
+-#define __NR_utime		 30
+-#define __NR_stty		 31
+-#define __NR_gtty		 32
+-#define __NR_access		 33
+-#define __NR_nice		 34
+-#define __NR_ftime		 35
+-#define __NR_sync		 36
+-#define __NR_kill		 37
+-#define __NR_rename		 38
+-#define __NR_mkdir		 39
+-#define __NR_rmdir		 40
+-#define __NR_dup		 41
+-#define __NR_pipe		 42
+-#define __NR_times		 43
+-#define __NR_prof		 44
+-#define __NR_brk		 45
+-#define __NR_setgid		 46
+-#define __NR_getgid		 47
+-#define __NR_signal		 48
+-#define __NR_geteuid		 49
+-#define __NR_getegid		 50
+-#define __NR_acct		 51
+-#define __NR_umount2		 52
+-#define __NR_lock		 53
+-#define __NR_ioctl		 54
+-#define __NR_fcntl		 55
+-#define __NR_mpx		 56
+-#define __NR_setpgid		 57
+-#define __NR_ulimit		 58
+-#define __NR_oldolduname	 59
+-#define __NR_umask		 60
+-#define __NR_chroot		 61
+-#define __NR_ustat		 62
+-#define __NR_dup2		 63
+-#define __NR_getppid		 64
+-#define __NR_getpgrp		 65
+-#define __NR_setsid		 66
+-#define __NR_sigaction		 67
+-#define __NR_sgetmask		 68
+-#define __NR_ssetmask		 69
+-#define __NR_setreuid		 70
+-#define __NR_setregid		 71
+-#define __NR_sigsuspend		 72
+-#define __NR_sigpending		 73
+-#define __NR_sethostname	 74
+-#define __NR_setrlimit		 75
+-#define __NR_getrlimit		 76
+-#define __NR_getrusage		 77
+-#define __NR_gettimeofday	 78
+-#define __NR_settimeofday	 79
+-#define __NR_getgroups		 80
+-#define __NR_setgroups		 81
+-#define __NR_select		 82
+-#define __NR_symlink		 83
+-#define __NR_oldlstat		 84
+-#define __NR_readlink		 85
+-#define __NR_uselib		 86
+-#define __NR_swapon		 87
+-#define __NR_reboot		 88
+-#define __NR_readdir		 89
+-#define __NR_mmap		 90
+-#define __NR_munmap		 91
+-#define __NR_truncate		 92
+-#define __NR_ftruncate		 93
+-#define __NR_fchmod		 94
+-#define __NR_fchown		 95
+-#define __NR_getpriority	 96
+-#define __NR_setpriority	 97
+-#define __NR_profil		 98
+-#define __NR_statfs		 99
+-#define __NR_fstatfs		100
+-#define __NR_ioperm		101
+-#define __NR_socketcall		102
+-#define __NR_syslog		103
+-#define __NR_setitimer		104
+-#define __NR_getitimer		105
+-#define __NR_stat		106
+-#define __NR_lstat		107
+-#define __NR_fstat		108
+-#define __NR_olduname		109
+-#define __NR_iopl		110
+-#define __NR_vhangup		111
+-#define __NR_idle		112
+-#define __NR_vm86		113
+-#define __NR_wait4		114
+-#define __NR_swapoff		115
+-#define __NR_sysinfo		116
+-#define __NR_ipc		117
+-#define __NR_fsync		118
+-#define __NR_sigreturn		119
+-#define __NR_clone		120
+-#define __NR_setdomainname	121
+-#define __NR_uname		122
+-#define __NR_modify_ldt		123
+-#define __NR_adjtimex		124
+-#define __NR_mprotect		125
+-#define __NR_sigprocmask	126
+-#define __NR_create_module	127
+-#define __NR_init_module	128
+-#define __NR_delete_module	129
+-#define __NR_get_kernel_syms	130
+-#define __NR_quotactl		131
+-#define __NR_getpgid		132
+-#define __NR_fchdir		133
+-#define __NR_bdflush		134
+-#define __NR_sysfs		135
+-#define __NR_personality	136
+-#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+-#define __NR_setfsuid		138
+-#define __NR_setfsgid		139
+-#define __NR__llseek		140
+-#define __NR_getdents		141
+-#define __NR__newselect		142
+-#define __NR_flock		143
+-#define __NR_msync		144
+-#define __NR_readv		145
+-#define __NR_writev		146
+-#define __NR_getsid		147
+-#define __NR_fdatasync		148
+-#define __NR__sysctl		149
+-#define __NR_mlock		150
+-#define __NR_munlock		151
+-#define __NR_mlockall		152
+-#define __NR_munlockall		153
+-#define __NR_sched_setparam		154
+-#define __NR_sched_getparam		155
+-#define __NR_sched_setscheduler		156
+-#define __NR_sched_getscheduler		157
+-#define __NR_sched_yield		158
+-#define __NR_sched_get_priority_max	159
+-#define __NR_sched_get_priority_min	160
+-#define __NR_sched_rr_get_interval	161
+-#define __NR_nanosleep		162
+-#define __NR_mremap		163
+-#define __NR_setresuid		164
+-#define __NR_getresuid		165
+-#define __NR_query_module	166
+-#define __NR_poll		167
+-#define __NR_nfsservctl		168
+-#define __NR_setresgid		169
+-#define __NR_getresgid		170
+-#define __NR_prctl		171
+-#define __NR_rt_sigreturn	172
+-#define __NR_rt_sigaction	173
+-#define __NR_rt_sigprocmask	174
+-#define __NR_rt_sigpending	175
+-#define __NR_rt_sigtimedwait	176
+-#define __NR_rt_sigqueueinfo	177
+-#define __NR_rt_sigsuspend	178
+-#define __NR_pread64		179
+-#define __NR_pwrite64		180
+-#define __NR_chown		181
+-#define __NR_getcwd		182
+-#define __NR_capget		183
+-#define __NR_capset		184
+-#define __NR_sigaltstack	185
+-#define __NR_sendfile		186
+-#define __NR_getpmsg		187	/* some people actually want streams */
+-#define __NR_putpmsg		188	/* some people actually want streams */
+-#define __NR_vfork		189
+-#define __NR_ugetrlimit		190	/* SuS compliant getrlimit */
+-#define __NR_readahead		191
+-/* #define __NR_mmap2		192	32bit only */
+-/* #define __NR_truncate64	193	32bit only */
+-/* #define __NR_ftruncate64	194	32bit only */
+-/* #define __NR_stat64		195	32bit only */
+-/* #define __NR_lstat64		196	32bit only */
+-/* #define __NR_fstat64		197	32bit only */
+-#define __NR_pciconfig_read	198
+-#define __NR_pciconfig_write	199
+-#define __NR_pciconfig_iobase	200
+-#define __NR_multiplexer	201
+-#define __NR_getdents64		202
+-#define __NR_pivot_root		203
+-/* #define __NR_fcntl64		204	32bit only */
+-#define __NR_madvise		205
+-#define __NR_mincore		206
+-#define __NR_gettid		207
+-#define __NR_tkill		208
+-#define __NR_setxattr		209
+-#define __NR_lsetxattr		210
+-#define __NR_fsetxattr		211
+-#define __NR_getxattr		212
+-#define __NR_lgetxattr		213
+-#define __NR_fgetxattr		214
+-#define __NR_listxattr		215
+-#define __NR_llistxattr		216
+-#define __NR_flistxattr		217
+-#define __NR_removexattr	218
+-#define __NR_lremovexattr	219
+-#define __NR_fremovexattr	220
+-#define __NR_futex		221
+-#define __NR_sched_setaffinity	222
+-#define __NR_sched_getaffinity	223
+-/* 224 currently unused */
+-#define __NR_tuxcall		225
+-/* #define __NR_sendfile64	226	32bit only */
+-#define __NR_io_setup		227
+-#define __NR_io_destroy		228
+-#define __NR_io_getevents	229
+-#define __NR_io_submit		230
+-#define __NR_io_cancel		231
+-#define __NR_set_tid_address	232
+-#define __NR_fadvise64		233
+-#define __NR_exit_group		234
+-#define __NR_lookup_dcookie	235
+-#define __NR_epoll_create	236
+-#define __NR_epoll_ctl		237
+-#define __NR_epoll_wait		238
+-#define __NR_remap_file_pages	239
+-#define __NR_timer_create	240
+-#define __NR_timer_settime	241
+-#define __NR_timer_gettime	242
+-#define __NR_timer_getoverrun	243
+-#define __NR_timer_delete	244
+-#define __NR_clock_settime	245
+-#define __NR_clock_gettime	246
+-#define __NR_clock_getres	247
+-#define __NR_clock_nanosleep	248
+-#define __NR_swapcontext	249
+-#define __NR_tgkill		250
+-#define __NR_utimes		251
+-#define __NR_statfs64		252
+-#define __NR_fstatfs64		253
+-/* #define __NR_fadvise64_64	254	32bit only */
+-#define __NR_rtas		255
+-/* Number 256 is reserved for sys_debug_setcontext */
+-/* Number 257 is reserved for vserver */
+-/* 258 currently unused */
+-#define __NR_mbind		259
+-#define __NR_get_mempolicy	260
+-#define __NR_set_mempolicy	261
+-#define __NR_mq_open		262
+-#define __NR_mq_unlink		263
+-#define __NR_mq_timedsend	264
+-#define __NR_mq_timedreceive	265
+-#define __NR_mq_notify		266
+-#define __NR_mq_getsetattr	267
+-#define __NR_kexec_load		268
+-#define __NR_add_key		269
+-#define __NR_request_key	270
+-#define __NR_keyctl		271
+-#define __NR_waitid		272
+-#define __NR_ioprio_set		273
+-#define __NR_ioprio_get		274
+-#define __NR_inotify_init	275
+-#define __NR_inotify_add_watch	276
+-#define __NR_inotify_rm_watch	277
+-
+-#define __NR_syscalls		278
+-#ifdef __KERNEL__
+-#define NR_syscalls	__NR_syscalls
+-#endif
+-
+-#ifndef __ASSEMBLY__
+-
+-/* On powerpc a system call basically clobbers the same registers like a
+- * function call, with the exception of LR (which is needed for the
+- * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
+- * an error return status).
+- */
+-
+-#define __syscall_nr(nr, type, name, args...)				\
+-	unsigned long __sc_ret, __sc_err;				\
+-	{								\
+-		register unsigned long __sc_0  __asm__ ("r0");		\
+-		register unsigned long __sc_3  __asm__ ("r3");		\
+-		register unsigned long __sc_4  __asm__ ("r4");		\
+-		register unsigned long __sc_5  __asm__ ("r5");		\
+-		register unsigned long __sc_6  __asm__ ("r6");		\
+-		register unsigned long __sc_7  __asm__ ("r7");		\
+-		register unsigned long __sc_8  __asm__ ("r8");		\
+-									\
+-		__sc_loadargs_##nr(name, args);				\
+-		__asm__ __volatile__					\
+-			("sc           \n\t"				\
+-			 "mfcr %0      "				\
+-			: "=&r" (__sc_0),				\
+-			  "=&r" (__sc_3),  "=&r" (__sc_4),		\
+-			  "=&r" (__sc_5),  "=&r" (__sc_6),		\
+-			  "=&r" (__sc_7),  "=&r" (__sc_8)		\
+-			: __sc_asm_input_##nr				\
+-			: "cr0", "ctr", "memory",			\
+-			        "r9", "r10","r11", "r12");		\
+-		__sc_ret = __sc_3;					\
+-		__sc_err = __sc_0;					\
+-	}								\
+-	if (__sc_err & 0x10000000)					\
+-	{								\
+-		errno = __sc_ret;					\
+-		__sc_ret = -1;						\
+-	}								\
+-	return (type) __sc_ret
+-
+-#define __sc_loadargs_0(name, dummy...)					\
+-	__sc_0 = __NR_##name
+-#define __sc_loadargs_1(name, arg1)					\
+-	__sc_loadargs_0(name);						\
+-	__sc_3 = (unsigned long) (arg1)
+-#define __sc_loadargs_2(name, arg1, arg2)				\
+-	__sc_loadargs_1(name, arg1);					\
+-	__sc_4 = (unsigned long) (arg2)
+-#define __sc_loadargs_3(name, arg1, arg2, arg3)				\
+-	__sc_loadargs_2(name, arg1, arg2);				\
+-	__sc_5 = (unsigned long) (arg3)
+-#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4)			\
+-	__sc_loadargs_3(name, arg1, arg2, arg3);			\
+-	__sc_6 = (unsigned long) (arg4)
+-#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5)		\
+-	__sc_loadargs_4(name, arg1, arg2, arg3, arg4);			\
+-	__sc_7 = (unsigned long) (arg5)
+-#define __sc_loadargs_6(name, arg1, arg2, arg3, arg4, arg5, arg6)	\
+-	__sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5);		\
+-	__sc_8 = (unsigned long) (arg6)
+-
+-#define __sc_asm_input_0 "0" (__sc_0)
+-#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
+-#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
+-#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
+-#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
+-#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
+-#define __sc_asm_input_6 __sc_asm_input_5, "6" (__sc_8)
+-
+-#define _syscall0(type,name)						\
+-type name(void)								\
+-{									\
+-	__syscall_nr(0, type, name);					\
+-}
+-
+-#define _syscall1(type,name,type1,arg1)					\
+-type name(type1 arg1)							\
+-{									\
+-	__syscall_nr(1, type, name, arg1);				\
+-}
+-
+-#define _syscall2(type,name,type1,arg1,type2,arg2)			\
+-type name(type1 arg1, type2 arg2)					\
+-{									\
+-	__syscall_nr(2, type, name, arg1, arg2);			\
+-}
+-
+-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
+-type name(type1 arg1, type2 arg2, type3 arg3)				\
+-{									\
+-	__syscall_nr(3, type, name, arg1, arg2, arg3);			\
+-}
+-
+-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)		\
+-{									\
+-	__syscall_nr(4, type, name, arg1, arg2, arg3, arg4);		\
+-}
+-
+-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
+-{									\
+-	__syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5);	\
+-}
+-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
+-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6)	\
+-{									\
+-	__syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6);	\
+-}
+-
+-#ifdef __KERNEL_SYSCALLS__
+-
+-/*
+- * Forking from kernel space will result in the child getting a new,
+- * empty kernel stack area.  Thus the child cannot access automatic
+- * variables set in the parent unless they are in registers, and the
+- * procedure where the fork was done cannot return to its caller in
+- * the child.
+- */
+-
+-/*
+- * System call prototypes.
+- */
+-static inline _syscall3(int, execve, __const__ char *, file, char **, argv,
+-			char **,envp)
+-
+-#endif /* __KERNEL_SYSCALLS__ */
+-
+-#ifdef __KERNEL__
+-
+-#include <linux/types.h>
+-#include <linux/compiler.h>
+-#include <linux/linkage.h>
+-
+-#define __ARCH_WANT_IPC_PARSE_VERSION
+-#define __ARCH_WANT_OLD_READDIR
+-#define __ARCH_WANT_STAT64
+-#define __ARCH_WANT_SYS_ALARM
+-#define __ARCH_WANT_SYS_GETHOSTNAME
+-#define __ARCH_WANT_SYS_PAUSE
+-#define __ARCH_WANT_SYS_SGETMASK
+-#define __ARCH_WANT_SYS_SIGNAL
+-#define __ARCH_WANT_SYS_TIME
+-#define __ARCH_WANT_COMPAT_SYS_TIME
+-#define __ARCH_WANT_SYS_UTIME
+-#define __ARCH_WANT_SYS_WAITPID
+-#define __ARCH_WANT_SYS_SOCKETCALL
+-#define __ARCH_WANT_SYS_FADVISE64
+-#define __ARCH_WANT_SYS_GETPGRP
+-#define __ARCH_WANT_SYS_LLSEEK
+-#define __ARCH_WANT_SYS_NICE
+-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+-#define __ARCH_WANT_SYS_OLDUMOUNT
+-#define __ARCH_WANT_SYS_SIGPENDING
+-#define __ARCH_WANT_SYS_SIGPROCMASK
+-#define __ARCH_WANT_SYS_RT_SIGACTION
+-
+-unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot,
+-		       unsigned long flags, unsigned long fd, off_t offset);
+-struct pt_regs;
+-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+-		unsigned long a3, unsigned long a4, unsigned long a5,
+-		struct pt_regs *regs);
+-int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,
+-		unsigned long p4, unsigned long p5, unsigned long p6,
+-		struct pt_regs *regs);
+-int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
+-		unsigned long p4, unsigned long p5, unsigned long p6,
+-		struct pt_regs *regs);
+-int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
+-		unsigned long p4, unsigned long p5, unsigned long p6,
+-		struct pt_regs *regs);
+-int sys_pipe(int __user *fildes);
+-int sys_ptrace(long request, long pid, long addr, long data);
+-struct sigaction;
+-long sys_rt_sigaction(int sig, const struct sigaction __user *act,
+-		      struct sigaction __user *oact, size_t sigsetsize);
+-
+-/*
+- * "Conditional" syscalls
+- *
+- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+- * but it doesn't work on all toolchains, so we just do it by hand
+- */
+-#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall")
+-
+-#endif		/* __KERNEL__ */
+-
+-#endif		/* __ASSEMBLY__ */
+-
+-#endif /* _ASM_PPC_UNISTD_H_ */
+diff --git a/include/asm-ppc64/vga.h b/include/asm-ppc64/vga.h
+deleted file mode 100644
+--- a/include/asm-ppc64/vga.h
++++ /dev/null
+@@ -1,50 +0,0 @@
+-/*
+- *	Access to VGA videoram
+- *
+- *	(c) 1998 Martin Mares <mj at ucw.cz>
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the 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 _LINUX_ASM_VGA_H_
+-#define _LINUX_ASM_VGA_H_
+-
+-#include <asm/io.h>
+-
+-#include <linux/config.h>
+-
+-#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
+-
+-#define VT_BUF_HAVE_RW
+-/*
+- *  These are only needed for supporting VGA or MDA text mode, which use little
+- *  endian byte ordering.
+- *  In other cases, we can optimize by using native byte ordering and
+- *  <linux/vt_buffer.h> has already done the right job for us.
+- */
+-
+-static inline void scr_writew(u16 val, volatile u16 *addr)
+-{
+-    st_le16(addr, val);
+-}
+-
+-static inline u16 scr_readw(volatile const u16 *addr)
+-{
+-    return ld_le16(addr);
+-}
+-
+-#define VT_BUF_HAVE_MEMCPYW
+-#define scr_memcpyw	memcpy
+-
+-#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
+-
+-extern unsigned long vgacon_remap_base;
+-#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0))
+-
+-#define vga_readb(x) (*(x))
+-#define vga_writeb(x,y) (*(y) = (x))
+-
+-#endif
+diff --git a/include/asm-ppc64/vio.h b/include/asm-ppc64/vio.h
+deleted file mode 100644
+--- a/include/asm-ppc64/vio.h
++++ /dev/null
+@@ -1,106 +0,0 @@
+-/*
+- * IBM PowerPC Virtual I/O Infrastructure Support.
+- *
+- *    Copyright (c) 2003 IBM Corp.
+- *     Dave Engebretsen engebret at us.ibm.com
+- *     Santiago Leon santil at 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.
+- */
+-
+-#ifndef _ASM_VIO_H
+-#define _ASM_VIO_H
+-
+-#include <linux/config.h>
+-#include <linux/init.h>
+-#include <linux/errno.h>
+-#include <linux/device.h>
+-#include <linux/dma-mapping.h>
+-#include <linux/mod_devicetable.h>
+-
+-#include <asm/hvcall.h>
+-#include <asm/scatterlist.h>
+-
+-/*
+- * Architecture-specific constants for drivers to
+- * extract attributes of the device using vio_get_attribute()
+- */
+-#define VETH_MAC_ADDR "local-mac-address"
+-#define VETH_MCAST_FILTER_SIZE "ibm,mac-address-filters"
+-
+-/* End architecture-specific constants */
+-
+-#define h_vio_signal(ua, mode) \
+-  plpar_hcall_norets(H_VIO_SIGNAL, ua, mode)
+-
+-#define VIO_IRQ_DISABLE		0UL
+-#define VIO_IRQ_ENABLE		1UL
+-
+-struct iommu_table;
+-
+-/*
+- * The vio_dev structure is used to describe virtual I/O devices.
+- */
+-struct vio_dev {
+-	struct iommu_table *iommu_table;     /* vio_map_* uses this */
+-	char *name;
+-	char *type;
+-	uint32_t unit_address;
+-	unsigned int irq;
+-	struct device dev;
+-};
+-
+-struct vio_driver {
+-	struct list_head node;
+-	char *name;
+-	const struct vio_device_id *id_table;
+-	int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
+-	int (*remove)(struct vio_dev *dev);
+-	unsigned long driver_data;
+-	struct device_driver driver;
+-};
+-
+-struct vio_bus_ops {
+-	int (*match)(const struct vio_device_id *id, const struct vio_dev *dev);
+-	void (*unregister_device)(struct vio_dev *);
+-	void (*release_device)(struct device *);
+-};
+-
+-extern struct dma_mapping_ops vio_dma_ops;
+-extern struct bus_type vio_bus_type;
+-extern struct vio_dev vio_bus_device;
+-
+-extern int vio_register_driver(struct vio_driver *drv);
+-extern void vio_unregister_driver(struct vio_driver *drv);
+-
+-extern struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev);
+-extern void __devinit vio_unregister_device(struct vio_dev *dev);
+-
+-extern int vio_bus_init(struct vio_bus_ops *);
+-
+-#ifdef CONFIG_PPC_PSERIES
+-struct device_node;
+-
+-extern struct vio_dev * __devinit vio_register_device_node(
+-		struct device_node *node_vdev);
+-extern struct vio_dev *vio_find_node(struct device_node *vnode);
+-extern const void *vio_get_attribute(struct vio_dev *vdev, void *which,
+-		int *length);
+-extern int vio_enable_interrupts(struct vio_dev *dev);
+-extern int vio_disable_interrupts(struct vio_dev *dev);
+-#endif
+-
+-static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
+-{
+-	return container_of(drv, struct vio_driver, driver);
+-}
+-
+-static inline struct vio_dev *to_vio_dev(struct device *dev)
+-{
+-	return container_of(dev, struct vio_dev, dev);
+-}
+-
+-#endif /* _ASM_VIO_H */
+diff --git a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h
+deleted file mode 100644
+--- a/include/asm-ppc64/xics.h
++++ /dev/null
+@@ -1,34 +0,0 @@
+-/* 
+- * arch/ppc64/kernel/xics.h
+- *
+- * Copyright 2000 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.
+- */
+-
+-#ifndef _PPC64_KERNEL_XICS_H
+-#define _PPC64_KERNEL_XICS_H
+-
+-#include <linux/cache.h>
+-
+-void xics_init_IRQ(void);
+-int xics_get_irq(struct pt_regs *);
+-void xics_setup_cpu(void);
+-void xics_teardown_cpu(int secondary);
+-void xics_cause_IPI(int cpu);
+-void xics_request_IPIs(void);
+-void xics_migrate_irqs_away(void);
+-
+-/* first argument is ignored for now*/
+-void pSeriesLP_cppr_info(int n_cpu, u8 value);
+-
+-struct xics_ipi_struct {
+-	volatile unsigned long value;
+-} ____cacheline_aligned;
+-
+-extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
+-
+-#endif /* _PPC64_KERNEL_XICS_H */
+diff --git a/include/asm-s390/rwsem.h b/include/asm-s390/rwsem.h
+--- a/include/asm-s390/rwsem.h
++++ b/include/asm-s390/rwsem.h
+@@ -351,5 +351,10 @@ static inline long rwsem_atomic_update(l
+ 	return new;
+ }
+ 
++static inline int rwsem_is_locked(struct rw_semaphore *sem)
++{
++	return (sem->count != 0);
++}
++
+ #endif /* __KERNEL__ */
+ #endif /* _S390_RWSEM_H */
+diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h
+--- a/include/asm-s390/semaphore.h
++++ b/include/asm-s390/semaphore.h
+@@ -29,9 +29,6 @@ struct semaphore {
+ #define __SEMAPHORE_INITIALIZER(name,count) \
+ 	{ ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h
+--- a/include/asm-s390/setup.h
++++ b/include/asm-s390/setup.h
+@@ -8,11 +8,14 @@
+ #ifndef _ASM_S390_SETUP_H
+ #define _ASM_S390_SETUP_H
+ 
++#include <asm/types.h>
++
+ #define PARMAREA		0x10400
+ #define COMMAND_LINE_SIZE 	896
+ #define RAMDISK_ORIGIN		0x800000
+ #define RAMDISK_SIZE		0x800000
+ #define MEMORY_CHUNKS		16	/* max 0x7fff */
++#define IPL_PARMBLOCK_ORIGIN	0x2000
+ 
+ #ifndef __ASSEMBLY__
+ 
+@@ -64,6 +67,53 @@ extern unsigned int console_irq;
+ #define SET_CONSOLE_3215	do { console_mode = 2; } while (0)
+ #define SET_CONSOLE_3270	do { console_mode = 3; } while (0)
+ 
++struct ipl_list_header {
++	u32 length;
++	u8  reserved[3];
++	u8  version;
++} __attribute__((packed));
++
++struct ipl_block_fcp {
++	u32 length;
++	u8  pbt;
++	u8  reserved1[322-1];
++	u16 devno;
++	u8  reserved2[4];
++	u64 wwpn;
++	u64 lun;
++	u32 bootprog;
++	u8  reserved3[12];
++	u64 br_lba;
++	u32 scp_data_len;
++	u8  reserved4[260];
++	u8  scp_data[];
++} __attribute__((packed));
++
++struct ipl_parameter_block {
++	union {
++		u32 length;
++		struct ipl_list_header header;
++	} hdr;
++	struct ipl_block_fcp fcp;
++} __attribute__((packed));
++
++#define IPL_MAX_SUPPORTED_VERSION (0)
++
++#define IPL_TYPE_FCP (0)
++
++/*
++ * IPL validity flags and parameters as detected in head.S
++ */
++extern u32 ipl_parameter_flags;
++extern u16 ipl_devno;
++
++#define IPL_DEVNO_VALID		(ipl_parameter_flags & 1)
++#define IPL_PARMBLOCK_VALID	(ipl_parameter_flags & 2)
++
++#define IPL_PARMBLOCK_START	((struct ipl_parameter_block *) \
++				 IPL_PARMBLOCK_ORIGIN)
++#define IPL_PARMBLOCK_SIZE	(IPL_PARMBLOCK_START->hdr.length)
++
+ #else 
+ 
+ #ifndef __s390x__
+diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
+--- a/include/asm-s390/unistd.h
++++ b/include/asm-s390/unistd.h
+@@ -590,7 +590,6 @@ asmlinkage long sys_clone(struct pt_regs
+ asmlinkage long sys_fork(struct pt_regs regs);
+ asmlinkage long sys_vfork(struct pt_regs regs);
+ asmlinkage long sys_pipe(unsigned long __user *fildes);
+-asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				const struct sigaction __user *act,
+diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
+--- a/include/asm-sh/dma-mapping.h
++++ b/include/asm-sh/dma-mapping.h
+@@ -9,7 +9,7 @@
+ extern struct bus_type pci_bus_type;
+ 
+ /* arch/sh/mm/consistent.c */
+-extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
++extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle);
+ extern void consistent_free(void *vaddr, size_t size);
+ extern void consistent_sync(void *vaddr, size_t size, int direction);
+ 
+@@ -26,7 +26,7 @@ static inline int dma_set_mask(struct de
+ }
+ 
+ static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+-			 dma_addr_t *dma_handle, int flag)
++			 dma_addr_t *dma_handle, gfp_t flag)
+ {
+ 	if (sh_mv.mv_consistent_alloc) {
+ 		void *ret;
+diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h
+--- a/include/asm-sh/machvec.h
++++ b/include/asm-sh/machvec.h
+@@ -64,7 +64,7 @@ struct sh_machine_vector
+ 
+ 	void (*mv_heartbeat)(void);
+ 
+-	void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, int);
++	void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, gfp_t);
+ 	int (*mv_consistent_free)(struct device *, size_t, void *, dma_addr_t);
+ };
+ 
+diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
+--- a/include/asm-sh/pgtable.h
++++ b/include/asm-sh/pgtable.h
+@@ -224,8 +224,6 @@ static inline pgprot_t pgprot_noncached(
+ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ { set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
+ 
+-#define page_pte(page) page_pte_prot(page, __pgprot(0))
+-
+ #define pmd_page_kernel(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+ 
+diff --git a/include/asm-sh/rwsem.h b/include/asm-sh/rwsem.h
+--- a/include/asm-sh/rwsem.h
++++ b/include/asm-sh/rwsem.h
+@@ -166,5 +166,10 @@ static inline int rwsem_atomic_update(in
+ 	return atomic_add_return(delta, (atomic_t *)(&sem->count));
+ }
+ 
++static inline int rwsem_is_locked(struct rw_semaphore *sem)
++{
++	return (sem->count != 0);
++}
++
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_SH_RWSEM_H */
+diff --git a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h
+--- a/include/asm-sh/semaphore.h
++++ b/include/asm-sh/semaphore.h
+@@ -33,9 +33,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
+--- a/include/asm-sh/unistd.h
++++ b/include/asm-sh/unistd.h
+@@ -503,7 +503,6 @@ asmlinkage int sys_vfork(unsigned long r
+ asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
+ 			unsigned long r6, unsigned long r7,
+ 			struct pt_regs regs);
+-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+ asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char *buf,
+ 				size_t count, long dummy, loff_t pos);
+ asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char *buf,
+diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
+--- a/include/asm-sh64/dma-mapping.h
++++ b/include/asm-sh64/dma-mapping.h
+@@ -25,7 +25,7 @@ static inline int dma_set_mask(struct de
+ }
+ 
+ static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+-			 dma_addr_t *dma_handle, int flag)
++			 dma_addr_t *dma_handle, gfp_t flag)
+ {
+ 	return consistent_alloc(NULL, size, dma_handle);
+ }
+diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
+--- a/include/asm-sh64/pgtable.h
++++ b/include/asm-sh64/pgtable.h
+@@ -457,9 +457,6 @@ extern inline pte_t pte_mkhuge(pte_t pte
+ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ { set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
+ 
+-#define page_pte_prot(page, prot) mk_pte(page, prot)
+-#define page_pte(page) page_pte_prot(page, __pgprot(0))
+-
+ typedef pte_t *pte_addr_t;
+ #define pgtable_cache_init()	do { } while (0)
+ 
+diff --git a/include/asm-sh64/semaphore.h b/include/asm-sh64/semaphore.h
+--- a/include/asm-sh64/semaphore.h
++++ b/include/asm-sh64/semaphore.h
+@@ -40,9 +40,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h
+--- a/include/asm-sparc/dma-mapping.h
++++ b/include/asm-sparc/dma-mapping.h
+@@ -8,7 +8,7 @@
+ #else
+ 
+ static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+-			 dma_addr_t *dma_handle, int flag)
++			 dma_addr_t *dma_handle, gfp_t flag)
+ {
+ 	BUG();
+ 	return NULL;
+diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h
+--- a/include/asm-sparc/floppy.h
++++ b/include/asm-sparc/floppy.h
+@@ -17,10 +17,8 @@
+ 
+ /* We don't need no stinkin' I/O port allocation crap. */
+ #undef release_region
+-#undef check_region
+ #undef request_region
+ #define release_region(X, Y)	do { } while(0)
+-#define check_region(X, Y)	(0)
+ #define request_region(X, Y, Z)	(1)
+ 
+ /* References:
+diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
+--- a/include/asm-sparc/pgtable.h
++++ b/include/asm-sparc/pgtable.h
+@@ -255,8 +255,6 @@ BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung
+ #define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte)
+ #define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
+ 
+-#define page_pte_prot(page, prot)	mk_pte(page, prot)
+-#define page_pte(page)			mk_pte(page, __pgprot(0))
+ #define pfn_pte(pfn, prot)		mk_pte(pfn_to_page(pfn), prot)
+ 
+ BTFIXUPDEF_CALL(unsigned long,	 pte_pfn, pte_t)
+diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h
+--- a/include/asm-sparc/semaphore.h
++++ b/include/asm-sparc/semaphore.h
+@@ -22,9 +22,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
+--- a/include/asm-sparc64/dma-mapping.h
++++ b/include/asm-sparc64/dma-mapping.h
+@@ -10,7 +10,7 @@
+ struct device;
+ 
+ static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+-			 dma_addr_t *dma_handle, int flag)
++			 dma_addr_t *dma_handle, gfp_t flag)
+ {
+ 	BUG();
+ 	return NULL;
+diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
+--- a/include/asm-sparc64/pgtable.h
++++ b/include/asm-sparc64/pgtable.h
+@@ -231,9 +231,6 @@ extern struct page *mem_map_zero;
+ #define pte_pfn(x)		((pte_val(x) & _PAGE_PADDR)>>PAGE_SHIFT)
+ #define pte_page(x)		pfn_to_page(pte_pfn(x))
+ 
+-#define page_pte_prot(page, prot)	mk_pte(page, prot)
+-#define page_pte(page)			page_pte_prot(page, __pgprot(0))
+-
+ static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
+ {
+ 	pte_t __pte;
+diff --git a/include/asm-sparc64/rwsem.h b/include/asm-sparc64/rwsem.h
+--- a/include/asm-sparc64/rwsem.h
++++ b/include/asm-sparc64/rwsem.h
+@@ -56,6 +56,11 @@ static inline void rwsem_atomic_add(int 
+ 	atomic_add(delta, (atomic_t *)(&sem->count));
+ }
+ 
++static inline int rwsem_is_locked(struct rw_semaphore *sem)
++{
++	return (sem->count != 0);
++}
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _SPARC64_RWSEM_H */
+diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h
+--- a/include/asm-sparc64/semaphore.h
++++ b/include/asm-sparc64/semaphore.h
+@@ -22,9 +22,6 @@ struct semaphore {
+ 	{ ATOMIC_INIT(count), \
+ 	  __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name, 1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name, count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h
+--- a/include/asm-sparc64/tlb.h
++++ b/include/asm-sparc64/tlb.h
+@@ -25,9 +25,8 @@ struct mmu_gather {
+ 	struct mm_struct *mm;
+ 	unsigned int pages_nr;
+ 	unsigned int need_flush;
+-	unsigned int tlb_frozen;
++	unsigned int fullmm;
+ 	unsigned int tlb_nr;
+-	unsigned long freed;
+ 	unsigned long vaddrs[TLB_BATCH_NR];
+ 	struct page *pages[FREE_PTE_NR];
+ };
+@@ -44,14 +43,13 @@ extern void flush_tlb_pending(void);
+ 
+ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+ {
+-	struct mmu_gather *mp = &__get_cpu_var(mmu_gathers);
++	struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
+ 
+ 	BUG_ON(mp->tlb_nr);
+ 
+ 	mp->mm = mm;
+ 	mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U;
+-	mp->tlb_frozen = full_mm_flush;
+-	mp->freed = 0;
++	mp->fullmm = full_mm_flush;
+ 
+ 	return mp;
+ }
+@@ -78,30 +76,19 @@ extern void smp_flush_tlb_mm(struct mm_s
+ 
+ static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end)
+ {
+-	unsigned long freed = mp->freed;
+-	struct mm_struct *mm = mp->mm;
+-	unsigned long rss = get_mm_counter(mm, rss);
+-
+-	if (rss < freed)
+-		freed = rss;
+-	add_mm_counter(mm, rss, -freed);
+-
+ 	tlb_flush_mmu(mp);
+ 
+-	if (mp->tlb_frozen) {
+-		if (CTX_VALID(mm->context))
+-			do_flush_tlb_mm(mm);
+-		mp->tlb_frozen = 0;
++	if (mp->fullmm) {
++		if (CTX_VALID(mp->mm->context))
++			do_flush_tlb_mm(mp->mm);
++		mp->fullmm = 0;
+ 	} else
+ 		flush_tlb_pending();
+ 
+ 	/* keep the page table cache within bounds */
+ 	check_pgt_cache();
+-}
+ 
+-static inline unsigned int tlb_is_full_mm(struct mmu_gather *mp)
+-{
+-	return mp->tlb_frozen;
++	put_cpu_var(mmu_gathers);
+ }
+ 
+ static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page)
+diff --git a/include/asm-um/cache.h b/include/asm-um/cache.h
+--- a/include/asm-um/cache.h
++++ b/include/asm-um/cache.h
+@@ -1,10 +1,21 @@
+ #ifndef __UM_CACHE_H
+ #define __UM_CACHE_H
+ 
+-/* These are x86 numbers */
+-#define L1_CACHE_SHIFT 5
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#include <linux/config.h>
+ 
+-#define L1_CACHE_SHIFT_MAX 7	/* largest L1 which this arch supports */
++#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
++# define L1_CACHE_SHIFT		(CONFIG_X86_L1_CACHE_SHIFT)
++#elif defined(CONFIG_UML_X86) /* 64-bit */
++# define L1_CACHE_SHIFT		6 /* Should be 7 on Intel */
++#else
++/* XXX: this was taken from x86, now it's completely random. Luckily only
++ * affects SMP padding. */
++# define L1_CACHE_SHIFT		5
++#endif
++
++/* XXX: this is valid for x86 and x86_64. */
++#define L1_CACHE_SHIFT_MAX	7	/* largest L1 which this arch supports */
++
++#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+ 
+ #endif
+diff --git a/include/asm-um/dma-mapping.h b/include/asm-um/dma-mapping.h
+--- a/include/asm-um/dma-mapping.h
++++ b/include/asm-um/dma-mapping.h
+@@ -19,7 +19,7 @@ dma_set_mask(struct device *dev, u64 dma
+ 
+ static inline void *
+ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+-		   int flag)
++		   gfp_t flag)
+ {
+ 	BUG();
+ 	return((void *) 0);
+diff --git a/include/asm-um/linkage.h b/include/asm-um/linkage.h
+--- a/include/asm-um/linkage.h
++++ b/include/asm-um/linkage.h
+@@ -3,4 +3,12 @@
+ 
+ #include "asm/arch/linkage.h"
+ 
++#include <linux/config.h>
++
++/* <linux/linkage.h> will pick sane defaults */
++#ifdef CONFIG_GPROF
++#undef FASTCALL
++#undef fastcall
++#endif
++
+ #endif
+diff --git a/include/asm-um/page.h b/include/asm-um/page.h
+--- a/include/asm-um/page.h
++++ b/include/asm-um/page.h
+@@ -115,7 +115,7 @@ extern unsigned long uml_physmem;
+ #define pfn_valid(pfn) ((pfn) < max_mapnr)
+ #define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
+ 
+-extern struct page *arch_validate(struct page *page, int mask, int order);
++extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
+ #define HAVE_ARCH_VALIDATE
+ 
+ extern void arch_free_page(struct page *page, int order);
+diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
+--- a/include/asm-um/pgtable.h
++++ b/include/asm-um/pgtable.h
+@@ -138,7 +138,7 @@ extern unsigned long pg0[1024];
+ 
+ #define pte_clear(mm,addr,xp) pte_set_val(*(xp), (phys_t) 0, __pgprot(_PAGE_NEWPAGE))
+ 
+-#define pmd_none(x)	(!(pmd_val(x) & ~_PAGE_NEWPAGE))
++#define pmd_none(x)	(!((unsigned long)pmd_val(x) & ~_PAGE_NEWPAGE))
+ #define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
+ #define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
+ #define pmd_clear(xp)	do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
+diff --git a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h
+--- a/include/asm-v850/semaphore.h
++++ b/include/asm-v850/semaphore.h
+@@ -18,9 +18,6 @@ struct semaphore {
+ 	{ ATOMIC_INIT (count), 0,					      \
+ 	  __WAIT_QUEUE_HEAD_INITIALIZER ((name).wait) }
+ 
+-#define __MUTEX_INITIALIZER(name)					      \
+-	__SEMAPHORE_INITIALIZER (name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count)	\
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER (name,count)
+ 
+diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h
+--- a/include/asm-v850/unistd.h
++++ b/include/asm-v850/unistd.h
+@@ -452,7 +452,6 @@ unsigned long sys_mmap2(unsigned long ad
+ struct pt_regs;
+ int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs);
+ int sys_pipe (int *fildes);
+-int sys_ptrace(long request, long pid, long addr, long data);
+ struct sigaction;
+ asmlinkage long sys_rt_sigaction(int sig,
+ 				const struct sigaction __user *act,
+diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
+--- a/include/asm-x86_64/dma-mapping.h
++++ b/include/asm-x86_64/dma-mapping.h
+@@ -17,7 +17,7 @@ extern dma_addr_t bad_dma_address;
+ 	(swiotlb ? swiotlb_dma_mapping_error(x) : ((x) == bad_dma_address))
+ 
+ void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+-			 unsigned gfp);
++			 gfp_t gfp);
+ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+ 			 dma_addr_t dma_handle);
+ 
+diff --git a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h
+--- a/include/asm-x86_64/mtrr.h
++++ b/include/asm-x86_64/mtrr.h
+@@ -25,6 +25,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/ioctl.h>
++#include <linux/compat.h>
+ 
+ #define	MTRR_IOCTL_BASE	'M'
+ 
+@@ -105,4 +106,36 @@ static __inline__ int mtrr_del_page (int
+ 
+ #endif
+ 
++#ifdef CONFIG_COMPAT
++
++struct mtrr_sentry32
++{
++    compat_ulong_t base;    /*  Base address     */
++    compat_uint_t size;    /*  Size of region   */
++    compat_uint_t type;     /*  Type of region   */
++};
++
++struct mtrr_gentry32
++{
++    compat_ulong_t regnum;   /*  Register number  */
++    compat_uint_t base;    /*  Base address     */
++    compat_uint_t size;    /*  Size of region   */
++    compat_uint_t type;     /*  Type of region   */
++};
++
++#define MTRR_IOCTL_BASE 'M'
++
++#define MTRRIOC32_ADD_ENTRY        _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry32)
++#define MTRRIOC32_SET_ENTRY        _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry32)
++#define MTRRIOC32_DEL_ENTRY        _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry32)
++#define MTRRIOC32_GET_ENTRY        _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
++#define MTRRIOC32_KILL_ENTRY       _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry32)
++#define MTRRIOC32_ADD_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry32)
++#define MTRRIOC32_SET_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry32)
++#define MTRRIOC32_DEL_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry32)
++#define MTRRIOC32_GET_PAGE_ENTRY   _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
++#define MTRRIOC32_KILL_PAGE_ENTRY  _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry32)
++
++#endif /* CONFIG_COMPAT */
++
+ #endif  /*  _LINUX_MTRR_H  */
+diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
+--- a/include/asm-x86_64/pgtable.h
++++ b/include/asm-x86_64/pgtable.h
+@@ -318,8 +318,6 @@ static inline int pmd_large(pmd_t pte) {
+  * and a page entry and page directory to the page they refer to.
+  */
+ 
+-#define page_pte(page) page_pte_prot(page, __pgprot(0))
+-
+ /*
+  * Level 4 access.
+  */
+diff --git a/include/asm-x86_64/rwsem.h b/include/asm-x86_64/rwsem.h
+--- a/include/asm-x86_64/rwsem.h
++++ b/include/asm-x86_64/rwsem.h
+@@ -274,5 +274,10 @@ LOCK_PREFIX	"xaddl %0,(%2)"
+ 	return tmp+delta;
+ }
+ 
++static inline int rwsem_is_locked(struct rw_semaphore *sem)
++{
++	return (sem->count != 0);
++}
++
+ #endif /* __KERNEL__ */
+ #endif /* _X8664_RWSEM_H */
+diff --git a/include/asm-x86_64/semaphore.h b/include/asm-x86_64/semaphore.h
+--- a/include/asm-x86_64/semaphore.h
++++ b/include/asm-x86_64/semaphore.h
+@@ -56,9 +56,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) \
+-	__SEMAPHORE_INITIALIZER(name,1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/asm-x86_64/swiotlb.h b/include/asm-x86_64/swiotlb.h
+--- a/include/asm-x86_64/swiotlb.h
++++ b/include/asm-x86_64/swiotlb.h
+@@ -27,7 +27,7 @@ extern void swiotlb_unmap_sg(struct devi
+ 			 int nents, int direction);
+ extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr);
+ extern void *swiotlb_alloc_coherent (struct device *hwdev, size_t size,
+-				     dma_addr_t *dma_handle, int flags);
++				     dma_addr_t *dma_handle, gfp_t flags);
+ extern void swiotlb_free_coherent (struct device *hwdev, size_t size,
+ 				   void *vaddr, dma_addr_t dma_handle);
+ 
+diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
+--- a/include/asm-x86_64/unistd.h
++++ b/include/asm-x86_64/unistd.h
+@@ -780,8 +780,6 @@ asmlinkage long sys_pipe(int *fildes);
+ #include <linux/types.h>
+ #include <asm/ptrace.h>
+ 
+-asmlinkage long sys_ptrace(long request, long pid,
+-				unsigned long addr, long data);
+ asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs);
+ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on);
+ struct sigaction;
+diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
+--- a/include/asm-xtensa/dma-mapping.h
++++ b/include/asm-xtensa/dma-mapping.h
+@@ -28,7 +28,7 @@ extern void consistent_sync(void*, size_
+ #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+ 
+ void *dma_alloc_coherent(struct device *dev, size_t size,
+-			   dma_addr_t *dma_handle, int flag);
++			   dma_addr_t *dma_handle, gfp_t flag);
+ 
+ void dma_free_coherent(struct device *dev, size_t size,
+ 			 void *vaddr, dma_addr_t dma_handle);
+diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h
+--- a/include/asm-xtensa/semaphore.h
++++ b/include/asm-xtensa/semaphore.h
+@@ -29,9 +29,6 @@ struct semaphore {
+ 	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+ }
+ 
+-#define __MUTEX_INITIALIZER(name) 					\
+-	__SEMAPHORE_INITIALIZER(name, 1)
+-
+ #define __DECLARE_SEMAPHORE_GENERIC(name,count) 			\
+ 	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+ 
+diff --git a/include/keys/user-type.h b/include/keys/user-type.h
+new file mode 100644
+--- /dev/null
++++ b/include/keys/user-type.h
+@@ -0,0 +1,47 @@
++/* user-type.h: User-defined key type
++ *
++ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells at 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 _KEYS_USER_TYPE_H
++#define _KEYS_USER_TYPE_H
++
++#include <linux/key.h>
++#include <linux/rcupdate.h>
++
++/*****************************************************************************/
++/*
++ * the payload for a key of type "user"
++ * - once filled in and attached to a key:
++ *   - the payload struct is invariant may not be changed, only replaced
++ *   - the payload must be read with RCU procedures or with the key semaphore
++ *     held
++ *   - the payload may only be replaced with the key semaphore write-locked
++ * - the key's data length is the size of the actual data, not including the
++ *   payload wrapper
++ */
++struct user_key_payload {
++	struct rcu_head	rcu;		/* RCU destructor */
++	unsigned short	datalen;	/* length of this data */
++	char		data[0];	/* actual data */
++};
++
++extern struct key_type key_type_user;
++
++extern int user_instantiate(struct key *key, const void *data, size_t datalen);
++extern int user_duplicate(struct key *key, const struct key *source);
++extern int user_update(struct key *key, const void *data, size_t datalen);
++extern int user_match(const struct key *key, const void *criterion);
++extern void user_destroy(struct key *key);
++extern void user_describe(const struct key *user, struct seq_file *m);
++extern long user_read(const struct key *key,
++		      char __user *buffer, size_t buflen);
++
++
++#endif /* _KEYS_USER_TYPE_H */
+diff --git a/include/linux/ata.h b/include/linux/ata.h
+--- a/include/linux/ata.h
++++ b/include/linux/ata.h
+@@ -42,13 +42,18 @@ enum {
+ 	ATA_SECT_SIZE		= 512,
+ 
+ 	ATA_ID_WORDS		= 256,
+-	ATA_ID_PROD_OFS		= 27,
+-	ATA_ID_FW_REV_OFS	= 23,
+ 	ATA_ID_SERNO_OFS	= 10,
+-	ATA_ID_MAJOR_VER	= 80,
+-	ATA_ID_PIO_MODES	= 64,
++	ATA_ID_FW_REV_OFS	= 23,
++	ATA_ID_PROD_OFS		= 27,
++	ATA_ID_OLD_PIO_MODES	= 51,
++	ATA_ID_FIELD_VALID	= 53,
+ 	ATA_ID_MWDMA_MODES	= 63,
++	ATA_ID_PIO_MODES	= 64,
++	ATA_ID_EIDE_DMA_MIN	= 65,
++	ATA_ID_EIDE_PIO		= 67,
++	ATA_ID_EIDE_PIO_IORDY	= 68,
+ 	ATA_ID_UDMA_MODES	= 88,
++	ATA_ID_MAJOR_VER	= 80,
+ 	ATA_ID_PIO4		= (1 << 1),
+ 
+ 	ATA_PCI_CTL_OFS		= 2,
+@@ -128,10 +133,15 @@ enum {
+ 	ATA_CMD_PIO_READ_EXT	= 0x24,
+ 	ATA_CMD_PIO_WRITE	= 0x30,
+ 	ATA_CMD_PIO_WRITE_EXT	= 0x34,
++	ATA_CMD_READ_MULTI	= 0xC4,
++	ATA_CMD_READ_MULTI_EXT	= 0x29,
++	ATA_CMD_WRITE_MULTI	= 0xC5,
++	ATA_CMD_WRITE_MULTI_EXT	= 0x39,
+ 	ATA_CMD_SET_FEATURES	= 0xEF,
+ 	ATA_CMD_PACKET		= 0xA0,
+ 	ATA_CMD_VERIFY		= 0x40,
+ 	ATA_CMD_VERIFY_EXT	= 0x42,
++	ATA_CMD_INIT_DEV_PARAMS	= 0x91,
+ 
+ 	/* SETFEATURES stuff */
+ 	SETFEATURES_XFER	= 0x03,
+@@ -146,14 +156,14 @@ enum {
+ 	XFER_MW_DMA_2		= 0x22,
+ 	XFER_MW_DMA_1		= 0x21,
+ 	XFER_MW_DMA_0		= 0x20,
++	XFER_SW_DMA_2		= 0x12,
++	XFER_SW_DMA_1		= 0x11,
++	XFER_SW_DMA_0		= 0x10,
+ 	XFER_PIO_4		= 0x0C,
+ 	XFER_PIO_3		= 0x0B,
+ 	XFER_PIO_2		= 0x0A,
+ 	XFER_PIO_1		= 0x09,
+ 	XFER_PIO_0		= 0x08,
+-	XFER_SW_DMA_2		= 0x12,
+-	XFER_SW_DMA_1		= 0x11,
+-	XFER_SW_DMA_0		= 0x10,
+ 	XFER_PIO_SLOW		= 0x00,
+ 
+ 	/* ATAPI stuff */
+@@ -181,6 +191,7 @@ enum {
+ 	ATA_TFLAG_ISADDR	= (1 << 1), /* enable r/w to nsect/lba regs */
+ 	ATA_TFLAG_DEVICE	= (1 << 2), /* enable r/w to device reg */
+ 	ATA_TFLAG_WRITE		= (1 << 3), /* data dir: host->dev==1 (write) */
++	ATA_TFLAG_LBA		= (1 << 4), /* enable LBA */
+ };
+ 
+ enum ata_tf_protocols {
+@@ -250,7 +261,19 @@ struct ata_taskfile {
+ 	  ((u64) (id)[(n) + 1] << 16) |	\
+ 	  ((u64) (id)[(n) + 0]) )
+ 
+-static inline int atapi_cdb_len(u16 *dev_id)
++static inline int ata_id_current_chs_valid(const u16 *id)
++{
++	/* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command 
++	   has not been issued to the device then the values of 
++	   id[54] to id[56] are vendor specific. */
++	return (id[53] & 0x01) && /* Current translation valid */
++		id[54] &&  /* cylinders in current translation */
++		id[55] &&  /* heads in current translation */
++		id[55] <= 16 &&
++		id[56];    /* sectors in current translation */
++}
++
++static inline int atapi_cdb_len(const u16 *dev_id)
+ {
+ 	u16 tmp = dev_id[0] & 0x3;
+ 	switch (tmp) {
+@@ -260,7 +283,7 @@ static inline int atapi_cdb_len(u16 *dev
+ 	}
+ }
+ 
+-static inline int is_atapi_taskfile(struct ata_taskfile *tf)
++static inline int is_atapi_taskfile(const struct ata_taskfile *tf)
+ {
+ 	return (tf->protocol == ATA_PROT_ATAPI) ||
+ 	       (tf->protocol == ATA_PROT_ATAPI_NODATA) ||
+diff --git a/include/linux/audit.h b/include/linux/audit.h
+--- a/include/linux/audit.h
++++ b/include/linux/audit.h
+@@ -260,11 +260,11 @@ extern int audit_filter_user(struct netl
+ #ifdef CONFIG_AUDIT
+ /* These are defined in audit.c */
+ 				/* Public API */
+-extern void		    audit_log(struct audit_context *ctx, int gfp_mask,
++extern void		    audit_log(struct audit_context *ctx, gfp_t gfp_mask,
+ 				      int type, const char *fmt, ...)
+ 				      __attribute__((format(printf,4,5)));
+ 
+-extern struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, int type);
++extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
+ extern void		    audit_log_format(struct audit_buffer *ab,
+ 					     const char *fmt, ...)
+ 			    __attribute__((format(printf,2,3)));
+diff --git a/include/linux/bio.h b/include/linux/bio.h
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -301,7 +301,7 @@ extern struct bio *bio_map_user_iov(stru
+ 				    struct sg_iovec *, int, int);
+ extern void bio_unmap_user(struct bio *);
+ extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
+-				unsigned int);
++				gfp_t);
+ extern void bio_set_pages_dirty(struct bio *bio);
+ extern void bio_check_pages_dirty(struct bio *bio);
+ extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
+diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
+--- a/include/linux/bitmap.h
++++ b/include/linux/bitmap.h
+@@ -40,6 +40,8 @@
+  * bitmap_weight(src, nbits)			Hamming Weight: number set bits
+  * bitmap_shift_right(dst, src, n, nbits)	*dst = *src >> n
+  * bitmap_shift_left(dst, src, n, nbits)	*dst = *src << n
++ * bitmap_remap(dst, src, old, new, nbits)	*dst = map(old, new)(src)
++ * bitmap_bitremap(oldbit, old, new, nbits)	newbit = map(old, new)(oldbit)
+  * bitmap_scnprintf(buf, len, src, nbits)	Print bitmap src to buf
+  * bitmap_parse(ubuf, ulen, dst, nbits)		Parse bitmap dst from user buf
+  * bitmap_scnlistprintf(buf, len, src, nbits)	Print bitmap src as list to buf
+@@ -104,6 +106,10 @@ extern int bitmap_scnlistprintf(char *bu
+ 			const unsigned long *src, int nbits);
+ extern int bitmap_parselist(const char *buf, unsigned long *maskp,
+ 			int nmaskbits);
++extern void bitmap_remap(unsigned long *dst, const unsigned long *src,
++		const unsigned long *old, const unsigned long *new, int bits);
++extern int bitmap_bitremap(int oldbit,
++		const unsigned long *old, const unsigned long *new, int bits);
+ extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order);
+ extern void bitmap_release_region(unsigned long *bitmap, int pos, int order);
+ extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order);
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -96,8 +96,8 @@ struct io_context {
+ 
+ void put_io_context(struct io_context *ioc);
+ void exit_io_context(void);
+-struct io_context *current_io_context(int gfp_flags);
+-struct io_context *get_io_context(int gfp_flags);
++struct io_context *current_io_context(gfp_t gfp_flags);
++struct io_context *get_io_context(gfp_t gfp_flags);
+ void copy_io_context(struct io_context **pdst, struct io_context **psrc);
+ void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
+ 
+@@ -107,9 +107,9 @@ typedef void (rq_end_io_fn)(struct reque
+ struct request_list {
+ 	int count[2];
+ 	int starved[2];
++	int elvpriv;
+ 	mempool_t *rq_pool;
+ 	wait_queue_head_t wait[2];
+-	wait_queue_head_t drain;
+ };
+ 
+ #define BLK_MAX_CDB	16
+@@ -203,6 +203,7 @@ struct request {
+ enum rq_flag_bits {
+ 	__REQ_RW,		/* not set, read. set, write */
+ 	__REQ_FAILFAST,		/* no low level driver retries */
++	__REQ_SORTED,		/* elevator knows about this request */
+ 	__REQ_SOFTBARRIER,	/* may not be passed by ioscheduler */
+ 	__REQ_HARDBARRIER,	/* may not be passed by drive either */
+ 	__REQ_CMD,		/* is a regular fs rw request */
+@@ -210,6 +211,7 @@ enum rq_flag_bits {
+ 	__REQ_STARTED,		/* drive already may have started this one */
+ 	__REQ_DONTPREP,		/* don't call prep for this one */
+ 	__REQ_QUEUED,		/* uses queueing */
++	__REQ_ELVPRIV,		/* elevator private data attached */
+ 	/*
+ 	 * for ATA/ATAPI devices
+ 	 */
+@@ -235,6 +237,7 @@ enum rq_flag_bits {
+ 
+ #define REQ_RW		(1 << __REQ_RW)
+ #define REQ_FAILFAST	(1 << __REQ_FAILFAST)
++#define REQ_SORTED	(1 << __REQ_SORTED)
+ #define REQ_SOFTBARRIER	(1 << __REQ_SOFTBARRIER)
+ #define REQ_HARDBARRIER	(1 << __REQ_HARDBARRIER)
+ #define REQ_CMD		(1 << __REQ_CMD)
+@@ -242,6 +245,7 @@ enum rq_flag_bits {
+ #define REQ_STARTED	(1 << __REQ_STARTED)
+ #define REQ_DONTPREP	(1 << __REQ_DONTPREP)
+ #define REQ_QUEUED	(1 << __REQ_QUEUED)
++#define REQ_ELVPRIV	(1 << __REQ_ELVPRIV)
+ #define REQ_PC		(1 << __REQ_PC)
+ #define REQ_BLOCK_PC	(1 << __REQ_BLOCK_PC)
+ #define REQ_SENSE	(1 << __REQ_SENSE)
+@@ -333,6 +337,12 @@ struct request_queue
+ 	end_flush_fn		*end_flush_fn;
+ 
+ 	/*
++	 * Dispatch queue sorting
++	 */
++	sector_t		end_sector;
++	struct request		*boundary_rq;
++
++	/*
+ 	 * Auto-unplugging state
+ 	 */
+ 	struct timer_list	unplug_timer;
+@@ -354,7 +364,7 @@ struct request_queue
+ 	 * queue needs bounce pages for pages above this limit
+ 	 */
+ 	unsigned long		bounce_pfn;
+-	unsigned int		bounce_gfp;
++	gfp_t			bounce_gfp;
+ 
+ 	/*
+ 	 * various queue flags, see QUEUE_* below
+@@ -405,8 +415,6 @@ struct request_queue
+ 	unsigned int		sg_reserved_size;
+ 	int			node;
+ 
+-	struct list_head	drain_list;
+-
+ 	/*
+ 	 * reserved for flush operations
+ 	 */
+@@ -434,7 +442,7 @@ enum {
+ #define QUEUE_FLAG_DEAD		5	/* queue being torn down */
+ #define QUEUE_FLAG_REENTER	6	/* Re-entrancy avoidance */
+ #define QUEUE_FLAG_PLUGGED	7	/* queue is plugged */
+-#define QUEUE_FLAG_DRAIN	8	/* draining queue for sched switch */
++#define QUEUE_FLAG_ELVSWITCH	8	/* don't use elevator, just do FIFO */
+ #define QUEUE_FLAG_FLUSH	9	/* doing barrier flush sequence */
+ 
+ #define blk_queue_plugged(q)	test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
+@@ -454,6 +462,7 @@ enum {
+ #define blk_pm_request(rq)	\
+ 	((rq)->flags & (REQ_PM_SUSPEND | REQ_PM_RESUME))
+ 
++#define blk_sorted_rq(rq)	((rq)->flags & REQ_SORTED)
+ #define blk_barrier_rq(rq)	((rq)->flags & REQ_HARDBARRIER)
+ #define blk_barrier_preflush(rq)	((rq)->flags & REQ_BAR_PREFLUSH)
+ #define blk_barrier_postflush(rq)	((rq)->flags & REQ_BAR_POSTFLUSH)
+@@ -550,7 +559,7 @@ extern void generic_make_request(struct 
+ extern void blk_put_request(struct request *);
+ extern void blk_end_sync_rq(struct request *rq);
+ extern void blk_attempt_remerge(request_queue_t *, struct request *);
+-extern struct request *blk_get_request(request_queue_t *, int, int);
++extern struct request *blk_get_request(request_queue_t *, int, gfp_t);
+ extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
+ extern void blk_requeue_request(request_queue_t *, struct request *);
+ extern void blk_plug_device(request_queue_t *);
+@@ -565,7 +574,7 @@ extern void blk_run_queue(request_queue_
+ extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *);
+ extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int);
+ extern int blk_rq_unmap_user(struct bio *, unsigned int);
+-extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, unsigned int);
++extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, gfp_t);
+ extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int);
+ extern int blk_execute_rq(request_queue_t *, struct gendisk *,
+ 			  struct request *, int);
+@@ -611,12 +620,21 @@ extern void end_request(struct request *
+ 
+ static inline void blkdev_dequeue_request(struct request *req)
+ {
+-	BUG_ON(list_empty(&req->queuelist));
++	elv_dequeue_request(req->q, req);
++}
+ 
+-	list_del_init(&req->queuelist);
++/*
++ * This should be in elevator.h, but that requires pulling in rq and q
++ */
++static inline void elv_dispatch_add_tail(struct request_queue *q,
++					 struct request *rq)
++{
++	if (q->last_merge == rq)
++		q->last_merge = NULL;
+ 
+-	if (req->rl)
+-		elv_remove_request(req->q, req);
++	q->end_sector = rq_end_sector(rq);
++	q->boundary_rq = rq;
++	list_add_tail(&rq->queuelist, &q->queue_head);
+ }
+ 
+ /*
+@@ -650,12 +668,10 @@ extern void blk_dump_rq_flags(struct req
+ extern void generic_unplug_device(request_queue_t *);
+ extern void __generic_unplug_device(request_queue_t *);
+ extern long nr_blockdev_pages(void);
+-extern void blk_wait_queue_drained(request_queue_t *, int);
+-extern void blk_finish_queue_drain(request_queue_t *);
+ 
+ int blk_get_queue(request_queue_t *);
+-request_queue_t *blk_alloc_queue(int gfp_mask);
+-request_queue_t *blk_alloc_queue_node(int,int);
++request_queue_t *blk_alloc_queue(gfp_t);
++request_queue_t *blk_alloc_queue_node(gfp_t, int);
+ #define blk_put_queue(q) blk_cleanup_queue((q))
+ 
+ /*
+diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
+--- a/include/linux/buffer_head.h
++++ b/include/linux/buffer_head.h
+@@ -126,8 +126,8 @@ BUFFER_FNS(Eopnotsupp, eopnotsupp)
+ /* If we *know* page->private refers to buffer_heads */
+ #define page_buffers(page)					\
+ 	({							\
+-		BUG_ON(!PagePrivate(page));		\
+-		((struct buffer_head *)(page)->private);	\
++		BUG_ON(!PagePrivate(page));			\
++		((struct buffer_head *)page_private(page));	\
+ 	})
+ #define page_has_buffers(page)	PagePrivate(page)
+ 
+@@ -188,8 +188,9 @@ extern int buffer_heads_over_limit;
+  * Generic address_space_operations implementations for buffer_head-backed
+  * address_spaces.
+  */
+-int try_to_release_page(struct page * page, int gfp_mask);
++int try_to_release_page(struct page * page, gfp_t gfp_mask);
+ int block_invalidatepage(struct page *page, unsigned long offset);
++int do_invalidatepage(struct page *page, unsigned long offset);
+ int block_write_full_page(struct page *page, get_block_t *get_block,
+ 				struct writeback_control *wbc);
+ int block_read_full_page(struct page*, get_block_t*);
+@@ -219,7 +220,7 @@ static inline void attach_page_buffers(s
+ {
+ 	page_cache_get(page);
+ 	SetPagePrivate(page);
+-	page->private = (unsigned long)head;
++	set_page_private(page, (unsigned long)head);
+ }
+ 
+ static inline void get_bh(struct buffer_head *bh)
+diff --git a/include/linux/cpu.h b/include/linux/cpu.h
+--- a/include/linux/cpu.h
++++ b/include/linux/cpu.h
+@@ -32,6 +32,7 @@ struct cpu {
+ };
+ 
+ extern int register_cpu(struct cpu *, int, struct node *);
++extern struct sys_device *get_cpu_sysdev(int cpu);
+ #ifdef CONFIG_HOTPLUG_CPU
+ extern void unregister_cpu(struct cpu *, struct node *);
+ #endif
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -23,6 +23,7 @@
+ #include <linux/completion.h>
+ #include <linux/workqueue.h>
+ #include <linux/cpumask.h>
++#include <asm/div64.h>
+ 
+ #define CPUFREQ_NAME_LEN 16
+ 
+diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
+--- a/include/linux/cpumask.h
++++ b/include/linux/cpumask.h
+@@ -12,6 +12,8 @@
+  * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
+  * For details of cpulist_scnprintf() and cpulist_parse(), see
+  * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
++ * For details of cpu_remap(), see bitmap_bitremap in lib/bitmap.c
++ * For details of cpus_remap(), see bitmap_remap in lib/bitmap.c.
+  *
+  * The available cpumask operations are:
+  *
+@@ -50,6 +52,8 @@
+  * int cpumask_parse(ubuf, ulen, mask)	Parse ascii string as cpumask
+  * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing
+  * int cpulist_parse(buf, map)		Parse ascii string as cpulist
++ * int cpu_remap(oldbit, old, new)	newbit = map(old, new)(oldbit)
++ * int cpus_remap(dst, src, old, new)	*dst = map(old, new)(src)
+  *
+  * for_each_cpu_mask(cpu, mask)		for-loop cpu over mask
+  *
+@@ -294,6 +298,22 @@ static inline int __cpulist_parse(const 
+ 	return bitmap_parselist(buf, dstp->bits, nbits);
+ }
+ 
++#define cpu_remap(oldbit, old, new) \
++		__cpu_remap((oldbit), &(old), &(new), NR_CPUS)
++static inline int __cpu_remap(int oldbit,
++		const cpumask_t *oldp, const cpumask_t *newp, int nbits)
++{
++	return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
++}
++
++#define cpus_remap(dst, src, old, new) \
++		__cpus_remap(&(dst), &(src), &(old), &(new), NR_CPUS)
++static inline void __cpus_remap(cpumask_t *dstp, const cpumask_t *srcp,
++		const cpumask_t *oldp, const cpumask_t *newp, int nbits)
++{
++	bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
++}
++
+ #if NR_CPUS > 1
+ #define for_each_cpu_mask(cpu, mask)		\
+ 	for ((cpu) = first_cpu(mask);		\
+diff --git a/include/linux/cyclomx.h b/include/linux/cyclomx.h
+--- a/include/linux/cyclomx.h
++++ b/include/linux/cyclomx.h
+@@ -37,8 +37,6 @@
+ #include <linux/cycx_x25.h>
+ #endif
+ 
+-#define	is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
+-
+ /* Adapter Data Space.
+  * This structure is needed because we handle multiple cards, otherwise
+  * static data would do it.
+diff --git a/include/linux/cycx_drv.h b/include/linux/cycx_drv.h
+--- a/include/linux/cycx_drv.h
++++ b/include/linux/cycx_drv.h
+@@ -60,6 +60,5 @@ extern int cycx_peek(struct cycx_hw *hw,
+ extern int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
+ extern int cycx_exec(void __iomem *addr);
+ 
+-extern void cycx_inten(struct cycx_hw *hw);
+ extern void cycx_intr(struct cycx_hw *hw);
+ #endif	/* _CYCX_DRV_H */
+diff --git a/include/linux/device.h b/include/linux/device.h
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -28,19 +28,6 @@
+ #define BUS_ID_SIZE		KOBJ_NAME_LEN
+ 
+ 
+-enum {
+-	SUSPEND_NOTIFY,
+-	SUSPEND_SAVE_STATE,
+-	SUSPEND_DISABLE,
+-	SUSPEND_POWER_DOWN,
+-};
+-
+-enum {
+-	RESUME_POWER_ON,
+-	RESUME_RESTORE_STATE,
+-	RESUME_ENABLE,
+-};
+-
+ struct device;
+ struct device_driver;
+ struct class;
+@@ -115,8 +102,8 @@ struct device_driver {
+ 	int	(*probe)	(struct device * dev);
+ 	int	(*remove)	(struct device * dev);
+ 	void	(*shutdown)	(struct device * dev);
+-	int	(*suspend)	(struct device * dev, pm_message_t state, u32 level);
+-	int	(*resume)	(struct device * dev, u32 level);
++	int	(*suspend)	(struct device * dev, pm_message_t state);
++	int	(*resume)	(struct device * dev);
+ };
+ 
+ 
+@@ -190,7 +177,43 @@ struct class_attribute class_attr_##_nam
+ extern int class_create_file(struct class *, const struct class_attribute *);
+ extern void class_remove_file(struct class *, const struct class_attribute *);
+ 
++struct class_device_attribute {
++	struct attribute	attr;
++	ssize_t (*show)(struct class_device *, char * buf);
++	ssize_t (*store)(struct class_device *, const char * buf, size_t count);
++};
+ 
++#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store)		\
++struct class_device_attribute class_device_attr_##_name = 	\
++	__ATTR(_name,_mode,_show,_store)
++
++extern int class_device_create_file(struct class_device *,
++				    const struct class_device_attribute *);
++
++/**
++ * struct class_device - class devices
++ * @class: pointer to the parent class for this class device.  This is required.
++ * @devt: for internal use by the driver core only.
++ * @node: for internal use by the driver core only.
++ * @kobj: for internal use by the driver core only.
++ * @devt_attr: for internal use by the driver core only.
++ * @dev: if set, a symlink to the struct device is created in the sysfs
++ * directory for this struct class device.
++ * @class_data: pointer to whatever you want to store here for this struct
++ * class_device.  Use class_get_devdata() and class_set_devdata() to get and
++ * set this pointer.
++ * @parent: pointer to a struct class_device that is the parent of this struct
++ * class_device.  If NULL, this class_device will show up at the root of the
++ * struct class in sysfs (which is probably what you want to have happen.)
++ * @release: pointer to a release function for this struct class_device.  If
++ * set, this will be called instead of the class specific release function.
++ * Only use this if you want to override the default release function, like
++ * when you are nesting class_device structures.
++ * @hotplug: pointer to a hotplug function for this struct class_device.  If
++ * set, this will be called instead of the class specific hotplug function.
++ * Only use this if you want to override the default hotplug function, like
++ * when you are nesting class_device structures.
++ */
+ struct class_device {
+ 	struct list_head	node;
+ 
+@@ -198,9 +221,14 @@ struct class_device {
+ 	struct class		* class;	/* required */
+ 	dev_t			devt;		/* dev_t, creates the sysfs "dev" */
+ 	struct class_device_attribute *devt_attr;
++	struct class_device_attribute uevent_attr;
+ 	struct device		* dev;		/* not necessary, but nice to have */
+ 	void			* class_data;	/* class-specific data */
++	struct class_device	*parent;	/* parent of this child device, if there is one */
+ 
++	void	(*release)(struct class_device *dev);
++	int	(*hotplug)(struct class_device *dev, char **envp,
++			   int num_envp, char *buffer, int buffer_size);
+ 	char	class_id[BUS_ID_SIZE];	/* unique to this class */
+ };
+ 
+@@ -228,18 +256,6 @@ extern int class_device_rename(struct cl
+ extern struct class_device * class_device_get(struct class_device *);
+ extern void class_device_put(struct class_device *);
+ 
+-struct class_device_attribute {
+-	struct attribute	attr;
+-	ssize_t (*show)(struct class_device *, char * buf);
+-	ssize_t (*store)(struct class_device *, const char * buf, size_t count);
+-};
+-
+-#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store)		\
+-struct class_device_attribute class_device_attr_##_name = 	\
+-	__ATTR(_name,_mode,_show,_store)
+-
+-extern int class_device_create_file(struct class_device *, 
+-				    const struct class_device_attribute *);
+ extern void class_device_remove_file(struct class_device *, 
+ 				     const struct class_device_attribute *);
+ extern int class_device_create_bin_file(struct class_device *,
+@@ -251,8 +267,8 @@ struct class_interface {
+ 	struct list_head	node;
+ 	struct class		*class;
+ 
+-	int (*add)	(struct class_device *);
+-	void (*remove)	(struct class_device *);
++	int (*add)	(struct class_device *, struct class_interface *);
++	void (*remove)	(struct class_device *, struct class_interface *);
+ };
+ 
+ extern int class_interface_register(struct class_interface *);
+@@ -260,12 +276,29 @@ extern void class_interface_unregister(s
+ 
+ extern struct class *class_create(struct module *owner, char *name);
+ extern void class_destroy(struct class *cls);
+-extern struct class_device *class_device_create(struct class *cls, dev_t devt,
+-						struct device *device, char *fmt, ...)
+-					__attribute__((format(printf,4,5)));
++extern struct class_device *class_device_create(struct class *cls,
++						struct class_device *parent,
++						dev_t devt,
++						struct device *device,
++						char *fmt, ...)
++					__attribute__((format(printf,5,6)));
+ extern void class_device_destroy(struct class *cls, dev_t devt);
+ 
+ 
++/* interface for exporting device attributes */
++struct device_attribute {
++	struct attribute	attr;
++	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
++			char *buf);
++	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
++			 const char *buf, size_t count);
++};
++
++#define DEVICE_ATTR(_name,_mode,_show,_store) \
++struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
++
++extern int device_create_file(struct device *device, struct device_attribute * entry);
++extern void device_remove_file(struct device * dev, struct device_attribute * attr);
+ struct device {
+ 	struct klist		klist_children;
+ 	struct klist_node	knode_parent;		/* node in sibling list */
+@@ -275,6 +308,7 @@ struct device {
+ 
+ 	struct kobject kobj;
+ 	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
++	struct device_attribute uevent_attr;
+ 
+ 	struct semaphore	sem;	/* semaphore to synchronize calls to
+ 					 * its driver.
+@@ -343,23 +377,6 @@ extern int  device_attach(struct device 
+ extern void driver_attach(struct device_driver * drv);
+ 
+ 
+-/* driverfs interface for exporting device attributes */
+-
+-struct device_attribute {
+-	struct attribute	attr;
+-	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+-			char *buf);
+-	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+-			 const char *buf, size_t count);
+-};
+-
+-#define DEVICE_ATTR(_name,_mode,_show,_store) \
+-struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
+-
+-
+-extern int device_create_file(struct device *device, struct device_attribute * entry);
+-extern void device_remove_file(struct device * dev, struct device_attribute * attr);
+-
+ /*
+  * Platform "fixup" functions - allow the platform to have their say
+  * about devices and actions that the general device layer doesn't
+@@ -379,32 +396,6 @@ extern struct device * get_device(struct
+ extern void put_device(struct device * dev);
+ 
+ 
+-/* drivers/base/platform.c */
+-
+-struct platform_device {
+-	const char	* name;
+-	u32		id;
+-	struct device	dev;
+-	u32		num_resources;
+-	struct resource	* resource;
+-};
+-
+-#define to_platform_device(x) container_of((x), struct platform_device, dev)
+-
+-extern int platform_device_register(struct platform_device *);
+-extern void platform_device_unregister(struct platform_device *);
+-
+-extern struct bus_type platform_bus_type;
+-extern struct device platform_bus;
+-
+-extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
+-extern int platform_get_irq(struct platform_device *, unsigned int);
+-extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *);
+-extern int platform_get_irq_byname(struct platform_device *, char *);
+-extern int platform_add_devices(struct platform_device **, int);
+-
+-extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int);
+-
+ /* drivers/base/power.c */
+ extern void device_shutdown(void);
+ 
+diff --git a/include/linux/dmi.h b/include/linux/dmi.h
+--- a/include/linux/dmi.h
++++ b/include/linux/dmi.h
+@@ -60,7 +60,7 @@ struct dmi_device {
+ 	void *device_data;	/* Type specific data */
+ };
+ 
+-#if defined(CONFIG_X86) && !defined(CONFIG_X86_64)
++#if defined(CONFIG_X86_32)
+ 
+ extern int dmi_check_system(struct dmi_system_id *list);
+ extern char * dmi_get_system_info(int field);
+diff --git a/include/linux/elevator.h b/include/linux/elevator.h
+--- a/include/linux/elevator.h
++++ b/include/linux/elevator.h
+@@ -8,18 +8,17 @@ typedef void (elevator_merge_req_fn) (re
+ 
+ typedef void (elevator_merged_fn) (request_queue_t *, struct request *);
+ 
+-typedef struct request *(elevator_next_req_fn) (request_queue_t *);
++typedef int (elevator_dispatch_fn) (request_queue_t *, int);
+ 
+-typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, int);
++typedef void (elevator_add_req_fn) (request_queue_t *, struct request *);
+ typedef int (elevator_queue_empty_fn) (request_queue_t *);
+-typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
+-typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *);
+ typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
+ typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
+ typedef int (elevator_may_queue_fn) (request_queue_t *, int, struct bio *);
+ 
+-typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, struct bio *, int);
++typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, struct bio *, gfp_t);
+ typedef void (elevator_put_req_fn) (request_queue_t *, struct request *);
++typedef void (elevator_activate_req_fn) (request_queue_t *, struct request *);
+ typedef void (elevator_deactivate_req_fn) (request_queue_t *, struct request *);
+ 
+ typedef int (elevator_init_fn) (request_queue_t *, elevator_t *);
+@@ -31,10 +30,9 @@ struct elevator_ops
+ 	elevator_merged_fn *elevator_merged_fn;
+ 	elevator_merge_req_fn *elevator_merge_req_fn;
+ 
+-	elevator_next_req_fn *elevator_next_req_fn;
++	elevator_dispatch_fn *elevator_dispatch_fn;
+ 	elevator_add_req_fn *elevator_add_req_fn;
+-	elevator_remove_req_fn *elevator_remove_req_fn;
+-	elevator_requeue_req_fn *elevator_requeue_req_fn;
++	elevator_activate_req_fn *elevator_activate_req_fn;
+ 	elevator_deactivate_req_fn *elevator_deactivate_req_fn;
+ 
+ 	elevator_queue_empty_fn *elevator_queue_empty_fn;
+@@ -81,15 +79,15 @@ struct elevator_queue
+ /*
+  * block elevator interface
+  */
++extern void elv_dispatch_sort(request_queue_t *, struct request *);
+ extern void elv_add_request(request_queue_t *, struct request *, int, int);
+ extern void __elv_add_request(request_queue_t *, struct request *, int, int);
+ extern int elv_merge(request_queue_t *, struct request **, struct bio *);
+ extern void elv_merge_requests(request_queue_t *, struct request *,
+ 			       struct request *);
+ extern void elv_merged_request(request_queue_t *, struct request *);
+-extern void elv_remove_request(request_queue_t *, struct request *);
++extern void elv_dequeue_request(request_queue_t *, struct request *);
+ extern void elv_requeue_request(request_queue_t *, struct request *);
+-extern void elv_deactivate_request(request_queue_t *, struct request *);
+ extern int elv_queue_empty(request_queue_t *);
+ extern struct request *elv_next_request(struct request_queue *q);
+ extern struct request *elv_former_request(request_queue_t *, struct request *);
+@@ -98,7 +96,7 @@ extern int elv_register_queue(request_qu
+ extern void elv_unregister_queue(request_queue_t *q);
+ extern int elv_may_queue(request_queue_t *, int, struct bio *);
+ extern void elv_completed_request(request_queue_t *, struct request *);
+-extern int elv_set_request(request_queue_t *, struct request *, struct bio *, int);
++extern int elv_set_request(request_queue_t *, struct request *, struct bio *, gfp_t);
+ extern void elv_put_request(request_queue_t *, struct request *);
+ 
+ /*
+@@ -142,4 +140,6 @@ enum {
+ 	ELV_MQUEUE_MUST,
+ };
+ 
++#define rq_end_sector(rq)	((rq)->sector + (rq)->nr_sectors)
++
+ #endif
+diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
+--- a/include/linux/etherdevice.h
++++ b/include/linux/etherdevice.h
+@@ -104,6 +104,22 @@ static inline void random_ether_addr(u8 
+ 	addr [0] &= 0xfe;	/* clear multicast bit */
+ 	addr [0] |= 0x02;	/* set local assignment bit (IEEE802) */
+ }
++
++/**
++ * compare_ether_addr - Compare two Ethernet addresses
++ * @addr1: Pointer to a six-byte array containing the Ethernet address
++ * @addr2 Pointer other six-byte array containing the Ethernet address
++ *
++ * Compare two ethernet addresses, returns 0 if equal
++ */
++static inline unsigned compare_ether_addr(const u8 *_a, const u8 *_b)
++{
++	const u16 *a = (const u16 *) _a;
++	const u16 *b = (const u16 *) _b;
++
++	BUILD_BUG_ON(ETH_ALEN != 6);
++	return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
++}
+ #endif	/* __KERNEL__ */
+ 
+ #endif	/* _LINUX_ETHERDEVICE_H */
+diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
+--- a/include/linux/ethtool.h
++++ b/include/linux/ethtool.h
+@@ -269,6 +269,8 @@ u32 ethtool_op_get_tso(struct net_device
+ int ethtool_op_set_tso(struct net_device *dev, u32 data);
+ int ethtool_op_get_perm_addr(struct net_device *dev, 
+ 			     struct ethtool_perm_addr *addr, u8 *data);
++u32 ethtool_op_get_ufo(struct net_device *dev);
++int ethtool_op_set_ufo(struct net_device *dev, u32 data);
+ 
+ /**
+  * &ethtool_ops - Alter and report network device settings
+@@ -298,6 +300,8 @@ int ethtool_op_get_perm_addr(struct net_
+  * set_sg: Turn scatter-gather on or off
+  * get_tso: Report whether TCP segmentation offload is enabled
+  * set_tso: Turn TCP segmentation offload on or off
++ * get_ufo: Report whether UDP fragmentation offload is enabled
++ * set_ufo: Turn UDP fragmentation offload on or off
+  * self_test: Run specified self-tests
+  * get_strings: Return a set of strings that describe the requested objects 
+  * phys_id: Identify the device
+@@ -364,6 +368,8 @@ struct ethtool_ops {
+ 	int	(*get_perm_addr)(struct net_device *, struct ethtool_perm_addr *, u8 *);
+ 	int	(*begin)(struct net_device *);
+ 	void	(*complete)(struct net_device *);
++	u32     (*get_ufo)(struct net_device *);
++	int     (*set_ufo)(struct net_device *, u32);
+ };
+ 
+ /* CMDs currently supported */
+@@ -400,6 +406,8 @@ struct ethtool_ops {
+ #define ETHTOOL_GTSO		0x0000001e /* Get TSO enable (ethtool_value) */
+ #define ETHTOOL_STSO		0x0000001f /* Set TSO enable (ethtool_value) */
+ #define ETHTOOL_GPERMADDR	0x00000020 /* Get permanent hardware address */
++#define ETHTOOL_GUFO		0x00000021 /* Get UFO enable (ethtool_value) */
++#define ETHTOOL_SUFO		0x00000022 /* Set UFO enable (ethtool_value) */
+ 
+ /* compatibility with older code */
+ #define SPARC_ETH_GSET		ETHTOOL_GSET
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -320,7 +320,7 @@ struct address_space_operations {
+ 	/* Unfortunately this kludge is needed for FIBMAP. Don't use it */
+ 	sector_t (*bmap)(struct address_space *, sector_t);
+ 	int (*invalidatepage) (struct page *, unsigned long);
+-	int (*releasepage) (struct page *, int);
++	int (*releasepage) (struct page *, gfp_t);
+ 	ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
+ 			loff_t offset, unsigned long nr_segs);
+ 	struct page* (*get_xip_page)(struct address_space *, sector_t,
+@@ -574,7 +574,14 @@ struct file_ra_state {
+ #define RA_FLAG_INCACHE 0x02	/* file is already in cache */
+ 
+ struct file {
+-	struct list_head	f_list;
++	/*
++	 * fu_list becomes invalid after file_free is called and queued via
++	 * fu_rcuhead for RCU freeing
++	 */
++	union {
++		struct list_head	fu_list;
++		struct rcu_head 	fu_rcuhead;
++	} f_u;
+ 	struct dentry		*f_dentry;
+ 	struct vfsmount         *f_vfsmnt;
+ 	struct file_operations	*f_op;
+@@ -598,7 +605,6 @@ struct file {
+ 	spinlock_t		f_ep_lock;
+ #endif /* #ifdef CONFIG_EPOLL */
+ 	struct address_space	*f_mapping;
+-	struct rcu_head 	f_rcuhead;
+ };
+ extern spinlock_t files_lock;
+ #define file_list_lock() spin_lock(&files_lock);
+diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
+new file mode 100644
+--- /dev/null
++++ b/include/linux/fs_enet_pd.h
+@@ -0,0 +1,136 @@
++/*
++ * Platform information definitions for the
++ * universal Freescale Ethernet driver.
++ *
++ * Copyright (c) 2003 Intracom S.A. 
++ *  by Pantelis Antoniou <panto at intracom.gr>
++ *
++ * 2005 (c) MontaVista Software, Inc. 
++ * Vitaly Bordug <vbordug at 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.
++ */
++
++#ifndef FS_ENET_PD_H
++#define FS_ENET_PD_H
++
++#include <linux/version.h>
++#include <asm/types.h>
++
++#define FS_ENET_NAME	"fs_enet"
++
++enum fs_id {
++	fsid_fec1,
++	fsid_fec2,
++	fsid_fcc1,
++	fsid_fcc2,
++	fsid_fcc3,
++	fsid_scc1,
++	fsid_scc2,
++	fsid_scc3,
++	fsid_scc4,
++};
++
++#define FS_MAX_INDEX	9
++
++static inline int fs_get_fec_index(enum fs_id id)
++{
++	if (id >= fsid_fec1 && id <= fsid_fec2)
++		return id - fsid_fec1;
++	return -1;
++}
++
++static inline int fs_get_fcc_index(enum fs_id id)
++{
++	if (id >= fsid_fcc1 && id <= fsid_fcc3)
++		return id - fsid_fcc1;
++	return -1;
++}
++
++static inline int fs_get_scc_index(enum fs_id id)
++{
++	if (id >= fsid_scc1 && id <= fsid_scc4)
++		return id - fsid_scc1;
++	return -1;
++}
++
++enum fs_mii_method {
++	fsmii_fixed,
++	fsmii_fec,
++	fsmii_bitbang,
++};
++
++enum fs_ioport {
++	fsiop_porta,
++	fsiop_portb,
++	fsiop_portc,
++	fsiop_portd,
++	fsiop_porte,
++};
++
++struct fs_mii_bus_info {
++	int method;		/* mii method                  */
++	int id;			/* the id of the mii_bus       */
++	int disable_aneg;	/* if the controller needs to negothiate speed & duplex */
++	int lpa; 		/* the default board-specific vallues will be applied otherwise */
++
++	union {
++		struct {
++			int duplex;
++			int speed;
++		} fixed;
++
++		struct {
++			/* nothing */
++		} fec;
++		
++		struct {
++			/* nothing */
++		} scc;
++
++		struct {
++			int mdio_port;	/* port & bit for MDIO */
++			int mdio_bit;
++			int mdc_port;	/* port & bit for MDC  */
++			int mdc_bit;
++			int delay;	/* delay in us         */
++		} bitbang;
++	} i;
++};
++
++struct fs_platform_info {
++	
++	void(*init_ioports)(void);
++	/* device specific information */
++	int fs_no;		/* controller index            */
++
++	u32 cp_page;		/* CPM page */
++	u32 cp_block;		/* CPM sblock */
++	
++	u32 clk_trx;		/* some stuff for pins & mux configuration*/
++	u32 clk_route;
++	u32 clk_mask;
++	
++	u32 mem_offset;
++	u32 dpram_offset;
++	u32 fcc_regs_c;
++	
++	u32 device_flags;
++
++	int phy_addr;		/* the phy address (-1 no phy) */
++	int phy_irq;		/* the phy irq (if it exists)  */
++
++	const struct fs_mii_bus_info *bus_info;
++
++	int rx_ring, tx_ring;	/* number of buffers on rx     */
++	__u8 macaddr[6];	/* mac address                 */
++	int rx_copybreak;	/* limit we copy small frames  */
++	int use_napi;		/* use NAPI                    */
++	int napi_weight;	/* NAPI weight                 */
++
++	int use_rmii;		/* use RMII mode 	       */
++};
++
++#endif
+diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
+--- a/include/linux/fsl_devices.h
++++ b/include/linux/fsl_devices.h
+@@ -47,16 +47,21 @@
+ struct gianfar_platform_data {
+ 	/* device specific information */
+ 	u32 device_flags;
+-	u32 phy_reg_addr;
+ 
+ 	/* board specific information */
+ 	u32 board_flags;
+-	u32 phy_flags;
+-	u32 phyid;
+-	u32 interruptPHY;
++	const char *bus_id;
+ 	u8 mac_addr[6];
+ };
+ 
++struct gianfar_mdio_data {
++	/* device specific information */
++	u32 paddr;
++
++	/* board specific information */
++	int irq[32];
++};
++
+ /* Flags related to gianfar device features */
+ #define FSL_GIANFAR_DEV_HAS_GIGABIT		0x00000001
+ #define FSL_GIANFAR_DEV_HAS_COALESCE		0x00000002
+diff --git a/include/linux/fuse.h b/include/linux/fuse.h
+--- a/include/linux/fuse.h
++++ b/include/linux/fuse.h
+@@ -61,7 +61,6 @@ struct fuse_kstatfs {
+ #define FATTR_SIZE	(1 << 3)
+ #define FATTR_ATIME	(1 << 4)
+ #define FATTR_MTIME	(1 << 5)
+-#define FATTR_CTIME	(1 << 6)
+ 
+ /**
+  * Flags returned by the OPEN request
+diff --git a/include/linux/gameport.h b/include/linux/gameport.h
+--- a/include/linux/gameport.h
++++ b/include/linux/gameport.h
+@@ -12,6 +12,7 @@
+ #include <asm/io.h>
+ #include <linux/list.h>
+ #include <linux/device.h>
++#include <linux/timer.h>
+ 
+ struct gameport {
+ 
+diff --git a/include/linux/genhd.h b/include/linux/genhd.h
+--- a/include/linux/genhd.h
++++ b/include/linux/genhd.h
+@@ -119,7 +119,7 @@ struct gendisk {
+ 	int policy;
+ 
+ 	atomic_t sync_io;		/* RAID */
+-	unsigned long stamp, stamp_idle;
++	unsigned long stamp;
+ 	int in_flight;
+ #ifdef	CONFIG_SMP
+ 	struct disk_stats *dkstats;
+@@ -132,6 +132,7 @@ struct gendisk {
+ struct disk_attribute {
+ 	struct attribute attr;
+ 	ssize_t (*show)(struct gendisk *, char *);
++	ssize_t (*store)(struct gendisk *, const char *, size_t);
+ };
+ 
+ /* 
+diff --git a/include/linux/gfp.h b/include/linux/gfp.h
+--- a/include/linux/gfp.h
++++ b/include/linux/gfp.h
+@@ -12,8 +12,8 @@ struct vm_area_struct;
+  * GFP bitmasks..
+  */
+ /* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low two bits) */
+-#define __GFP_DMA	0x01u
+-#define __GFP_HIGHMEM	0x02u
++#define __GFP_DMA	((__force gfp_t)0x01u)
++#define __GFP_HIGHMEM	((__force gfp_t)0x02u)
+ 
+ /*
+  * Action modifiers - doesn't change the zoning
+@@ -26,24 +26,24 @@ struct vm_area_struct;
+  *
+  * __GFP_NORETRY: The VM implementation must not retry indefinitely.
+  */
+-#define __GFP_WAIT	0x10u	/* Can wait and reschedule? */
+-#define __GFP_HIGH	0x20u	/* Should access emergency pools? */
+-#define __GFP_IO	0x40u	/* Can start physical IO? */
+-#define __GFP_FS	0x80u	/* Can call down to low-level FS? */
+-#define __GFP_COLD	0x100u	/* Cache-cold page required */
+-#define __GFP_NOWARN	0x200u	/* Suppress page allocation failure warning */
+-#define __GFP_REPEAT	0x400u	/* Retry the allocation.  Might fail */
+-#define __GFP_NOFAIL	0x800u	/* Retry for ever.  Cannot fail */
+-#define __GFP_NORETRY	0x1000u	/* Do not retry.  Might fail */
+-#define __GFP_NO_GROW	0x2000u	/* Slab internal usage */
+-#define __GFP_COMP	0x4000u	/* Add compound page metadata */
+-#define __GFP_ZERO	0x8000u	/* Return zeroed page on success */
+-#define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */
+-#define __GFP_NORECLAIM  0x20000u /* No realy zone reclaim during allocation */
+-#define __GFP_HARDWALL   0x40000u /* Enforce hardwall cpuset memory allocs */
++#define __GFP_WAIT	((__force gfp_t)0x10u)	/* Can wait and reschedule? */
++#define __GFP_HIGH	((__force gfp_t)0x20u)	/* Should access emergency pools? */
++#define __GFP_IO	((__force gfp_t)0x40u)	/* Can start physical IO? */
++#define __GFP_FS	((__force gfp_t)0x80u)	/* Can call down to low-level FS? */
++#define __GFP_COLD	((__force gfp_t)0x100u)	/* Cache-cold page required */
++#define __GFP_NOWARN	((__force gfp_t)0x200u)	/* Suppress page allocation failure warning */
++#define __GFP_REPEAT	((__force gfp_t)0x400u)	/* Retry the allocation.  Might fail */
++#define __GFP_NOFAIL	((__force gfp_t)0x800u)	/* Retry for ever.  Cannot fail */
++#define __GFP_NORETRY	((__force gfp_t)0x1000u)/* Do not retry.  Might fail */
++#define __GFP_NO_GROW	((__force gfp_t)0x2000u)/* Slab internal usage */
++#define __GFP_COMP	((__force gfp_t)0x4000u)/* Add compound page metadata */
++#define __GFP_ZERO	((__force gfp_t)0x8000u)/* Return zeroed page on success */
++#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
++#define __GFP_NORECLAIM  ((__force gfp_t)0x20000u) /* No realy zone reclaim during allocation */
++#define __GFP_HARDWALL   ((__force gfp_t)0x40000u) /* Enforce hardwall cpuset memory allocs */
+ 
+ #define __GFP_BITS_SHIFT 20	/* Room for 20 __GFP_FOO bits */
+-#define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
++#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
+ 
+ /* if you forget to add the bitmask here kernel will crash, period */
+ #define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \
+@@ -64,6 +64,7 @@ struct vm_area_struct;
+ 
+ #define GFP_DMA		__GFP_DMA
+ 
++#define gfp_zone(mask) ((__force int)((mask) & (__force gfp_t)GFP_ZONEMASK))
+ 
+ /*
+  * There is only one page-allocator function, and two main namespaces to
+@@ -94,7 +95,7 @@ static inline struct page *alloc_pages_n
+ 		return NULL;
+ 
+ 	return __alloc_pages(gfp_mask, order,
+-		NODE_DATA(nid)->node_zonelists + (gfp_mask & GFP_ZONEMASK));
++		NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_mask));
+ }
+ 
+ #ifdef CONFIG_NUMA
+diff --git a/include/linux/hil.h b/include/linux/hil.h
+new file mode 100644
+--- /dev/null
++++ b/include/linux/hil.h
+@@ -0,0 +1,483 @@
++#ifndef _HIL_H_
++#define _HIL_H_
++
++/*
++ * Hewlett Packard Human Interface Loop (HP-HIL) Protocol -- header.
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * 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,
++ *    without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ *    derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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
++ *
++ * References:
++ * HP-HIL Technical Reference Manual.  Hewlett Packard Product No. 45918A
++ *
++ * A note of thanks to HP for providing and shipping reference materials
++ * free of charge to help in the development of HIL support for Linux.
++ *
++ */
++
++#include <asm/types.h>
++
++/* Physical constants relevant to raw loop/device timing. 
++ */ 
++
++#define HIL_CLOCK		8MHZ
++#define HIL_EK1_CLOCK		30HZ
++#define HIL_EK2_CLOCK		60HZ
++
++#define HIL_TIMEOUT_DEV         5	/* ms */
++#define HIL_TIMEOUT_DEVS	10	/* ms */
++#define HIL_TIMEOUT_NORESP	10	/* ms */
++#define HIL_TIMEOUT_DEVS_DATA	16	/* ms */
++#define HIL_TIMEOUT_SELFTEST	200	/* ms */
++
++
++/* Actual wire line coding.  These will only be useful if someone is 
++ * implementing a software MLC to run HIL devices on a non-parisc machine.
++ */
++
++#define HIL_WIRE_PACKET_LEN	15
++enum hil_wire_bitpos {
++	HIL_WIRE_START		= 0,
++	HIL_WIRE_ADDR2,
++	HIL_WIRE_ADDR1,
++	HIL_WIRE_ADDR0,
++	HIL_WIRE_COMMAND,
++	HIL_WIRE_DATA7,
++	HIL_WIRE_DATA6,
++	HIL_WIRE_DATA5,
++	HIL_WIRE_DATA4,
++	HIL_WIRE_DATA3,
++	HIL_WIRE_DATA2,
++	HIL_WIRE_DATA1,
++	HIL_WIRE_DATA0,
++	HIL_WIRE_PARITY,
++	HIL_WIRE_STOP
++};
++
++/* HP documentation uses these bit positions to refer to commands;
++ * we will call these "packets".
++ */
++enum hil_pkt_bitpos {
++	HIL_PKT_CMD		= 0x00000800,
++	HIL_PKT_ADDR2		= 0x00000400,
++	HIL_PKT_ADDR1		= 0x00000200,
++	HIL_PKT_ADDR0		= 0x00000100,
++	HIL_PKT_ADDR_MASK	= 0x00000700,
++	HIL_PKT_ADDR_SHIFT	= 8,
++	HIL_PKT_DATA7		= 0x00000080,
++	HIL_PKT_DATA6		= 0x00000040,
++	HIL_PKT_DATA5		= 0x00000020,
++	HIL_PKT_DATA4		= 0x00000010,
++	HIL_PKT_DATA3		= 0x00000008,
++	HIL_PKT_DATA2		= 0x00000004,
++	HIL_PKT_DATA1		= 0x00000002,
++	HIL_PKT_DATA0		= 0x00000001,
++	HIL_PKT_DATA_MASK	= 0x000000FF,
++	HIL_PKT_DATA_SHIFT	= 0
++};
++
++/* The HIL MLC also has several error/status/control bits.  We extend the 
++ * "packet" to include these when direct access to the MLC is available,
++ * or emulate them in cases where they are not available. 
++ *
++ * This way the device driver knows that the underlying MLC driver
++ * has had to deal with loop errors.
++ */
++enum hil_error_bitpos {
++	HIL_ERR_OB	= 0x00000800, /* MLC is busy sending an auto-poll, 
++					 or we have filled up the output 
++					 buffer and must wait. */
++	HIL_ERR_INT	= 0x00010000, /* A normal interrupt has occurred. */
++	HIL_ERR_NMI	= 0x00020000, /* An NMI has occurred. */
++	HIL_ERR_LERR	= 0x00040000, /* A poll didn't come back. */
++	HIL_ERR_PERR	= 0x01000000, /* There was a Parity Error. */
++	HIL_ERR_FERR	= 0x02000000, /* There was a Framing Error. */
++	HIL_ERR_FOF	= 0x04000000  /* Input FIFO Overflowed. */
++};
++
++enum hil_control_bitpos {
++	HIL_CTRL_TEST	= 0x00010000,
++	HIL_CTRL_IPF	= 0x00040000,
++	HIL_CTRL_APE	= 0x02000000
++};
++
++/* Bits 30,31 are unused, we use them to control write behavior. */
++#define HIL_DO_ALTER_CTRL  0x40000000 /* Write MSW of packet to control 
++                                          before writing LSW to loop */
++#define HIL_CTRL_ONLY      0xc0000000 /* *Only* alter the control registers */
++
++/* This gives us a 32-bit "packet" 
++ */
++typedef u32 hil_packet;
++
++
++/* HIL Loop commands 
++ */
++enum hil_command {
++	HIL_CMD_IFC	= 0x00,	/* Interface Clear */
++	HIL_CMD_EPT	= 0x01,	/* Enter Pass-Thru Mode */
++	HIL_CMD_ELB	= 0x02,	/* Enter Loop-Back Mode */
++	HIL_CMD_IDD	= 0x03,	/* Identify and Describe */
++	HIL_CMD_DSR	= 0x04,	/* Device Soft Reset */
++	HIL_CMD_PST	= 0x05,	/* Perform Self Test */
++	HIL_CMD_RRG	= 0x06,	/* Read Register */
++	HIL_CMD_WRG	= 0x07,	/* Write Register */
++	HIL_CMD_ACF	= 0x08,	/* Auto Configure */
++	HIL_CMDID_ACF	= 0x07,	/* Auto Configure bits with incremented ID */
++	HIL_CMD_POL	= 0x10,	/* Poll */
++	HIL_CMDCT_POL	= 0x0f,	/* Poll command bits with item count  */
++	HIL_CMD_RPL	= 0x20,	/* RePoll */
++	HIL_CMDCT_RPL	= 0x0f,	/* RePoll command bits with item count */
++	HIL_CMD_RNM	= 0x30,	/* Report Name */
++	HIL_CMD_RST	= 0x31,	/* Report Status */
++	HIL_CMD_EXD	= 0x32,	/* Extended Describe */
++	HIL_CMD_RSC	= 0x33,	/* Report Security Code */
++
++	/* 0x34 to 0x3c reserved for future use  */
++
++	HIL_CMD_DKA	= 0x3d,	/* Disable Keyswitch Autorepeat */
++	HIL_CMD_EK1	= 0x3e,	/* Enable Keyswitch Autorepeat 1 */
++	HIL_CMD_EK2	= 0x3f,	/* Enable Keyswitch Autorepeat 2 */
++	HIL_CMD_PR1	= 0x40,	/* Prompt1 */  
++	HIL_CMD_PR2	= 0x41,	/* Prompt2 */
++	HIL_CMD_PR3	= 0x42,	/* Prompt3 */
++	HIL_CMD_PR4	= 0x43,	/* Prompt4 */
++	HIL_CMD_PR5	= 0x44,	/* Prompt5 */
++	HIL_CMD_PR6	= 0x45,	/* Prompt6 */
++	HIL_CMD_PR7	= 0x46,	/* Prompt7 */
++	HIL_CMD_PRM	= 0x47,	/* Prompt (General Purpose) */
++	HIL_CMD_AK1	= 0x48,	/* Acknowlege1 */  
++	HIL_CMD_AK2	= 0x49,	/* Acknowlege2 */
++	HIL_CMD_AK3	= 0x4a,	/* Acknowlege3 */
++	HIL_CMD_AK4	= 0x4b,	/* Acknowlege4 */
++	HIL_CMD_AK5	= 0x4c,	/* Acknowlege5 */
++	HIL_CMD_AK6	= 0x4d,	/* Acknowlege6 */
++	HIL_CMD_AK7	= 0x4e,	/* Acknowlege7 */
++	HIL_CMD_ACK	= 0x4f,	/* Acknowlege (General Purpose) */
++
++	/* 0x50 to 0x78 reserved for future use  */
++	/* 0x80 to 0xEF device-specific commands */
++	/* 0xf0 to 0xf9 reserved for future use  */
++
++	HIL_CMD_RIO	= 0xfa,	/* Register I/O Error */
++	HIL_CMD_SHR	= 0xfb,	/* System Hard Reset */
++	HIL_CMD_TER	= 0xfc,	/* Transmission Error */
++	HIL_CMD_CAE	= 0xfd,	/* Configuration Address Error */
++	HIL_CMD_DHR	= 0xfe,	/* Device Hard Reset */
++
++	/* 0xff is prohibited from use. */
++};
++
++
++/* 
++ * Response "records" to HIL commands
++ */
++
++/* Device ID byte 
++ */
++#define HIL_IDD_DID_TYPE_MASK		0xe0	/* Primary type bits */
++#define HIL_IDD_DID_TYPE_KB_INTEGRAL	0xa0	/* Integral keyboard */
++#define HIL_IDD_DID_TYPE_KB_ITF		0xc0	/* ITD keyboard */
++#define HIL_IDD_DID_TYPE_KB_RSVD	0xe0	/* Reserved keyboard type */
++#define HIL_IDD_DID_TYPE_KB_LANG_MASK	0x1f	/* Keyboard locale bits */
++#define HIL_IDD_DID_KBLANG_USE_ESD	0x00	/* Use ESD Locale instead */
++#define HIL_IDD_DID_TYPE_ABS		0x80    /* Absolute Positioners */
++#define HIL_IDD_DID_ABS_RSVD1_MASK	0xf8	/* Reserved */
++#define HIL_IDD_DID_ABS_RSVD1		0x98
++#define HIL_IDD_DID_ABS_TABLET_MASK	0xf8	/* Tablets and digitizers */
++#define HIL_IDD_DID_ABS_TABLET		0x90
++#define HIL_IDD_DID_ABS_TSCREEN_MASK	0xfc	/* Touch screens */
++#define HIL_IDD_DID_ABS_TSCREEN		0x8c
++#define HIL_IDD_DID_ABS_RSVD2_MASK	0xfc	/* Reserved */
++#define HIL_IDD_DID_ABS_RSVD2		0x88
++#define HIL_IDD_DID_ABS_RSVD3_MASK	0xfc	/* Reserved */
++#define HIL_IDD_DID_ABS_RSVD3		0x80
++#define HIL_IDD_DID_TYPE_REL		0x60    /* Relative Positioners */
++#define HIL_IDD_DID_REL_RSVD1_MASK	0xf0	/* Reserved */
++#define HIL_IDD_DID_REL_RSVD1		0x70
++#define HIL_IDD_DID_REL_RSVD2_MASK	0xfc	/* Reserved */
++#define HIL_IDD_DID_REL_RSVD2		0x6c
++#define HIL_IDD_DID_REL_MOUSE_MASK	0xfc	/* Mouse */
++#define HIL_IDD_DID_REL_MOUSE		0x68
++#define HIL_IDD_DID_REL_QUAD_MASK	0xf8	/* Other Quadrature Devices */
++#define HIL_IDD_DID_REL_QUAD		0x60
++#define HIL_IDD_DID_TYPE_CHAR		0x40    /* Character Entry */
++#define HIL_IDD_DID_CHAR_BARCODE_MASK	0xfc	/* Barcode Reader */
++#define HIL_IDD_DID_CHAR_BARCODE	0x5c
++#define HIL_IDD_DID_CHAR_RSVD1_MASK	0xfc	/* Reserved */
++#define HIL_IDD_DID_CHAR_RSVD1		0x58
++#define HIL_IDD_DID_CHAR_RSVD2_MASK	0xf8	/* Reserved */
++#define HIL_IDD_DID_CHAR_RSVD2		0x50
++#define HIL_IDD_DID_CHAR_RSVD3_MASK	0xf0	/* Reserved */
++#define HIL_IDD_DID_CHAR_RSVD3		0x40
++#define HIL_IDD_DID_TYPE_OTHER		0x20    /* Miscellaneous */
++#define HIL_IDD_DID_OTHER_RSVD1_MASK	0xf0	/* Reserved */
++#define HIL_IDD_DID_OTHER_RSVD1		0x30
++#define HIL_IDD_DID_OTHER_BARCODE_MASK	0xfc	/* Tone Generator */
++#define HIL_IDD_DID_OTHER_BARCODE	0x2c
++#define HIL_IDD_DID_OTHER_RSVD2_MASK	0xfc	/* Reserved */
++#define HIL_IDD_DID_OTHER_RSVD2		0x28
++#define HIL_IDD_DID_OTHER_RSVD3_MASK	0xf8	/* Reserved */
++#define HIL_IDD_DID_OTHER_RSVD3		0x20
++#define HIL_IDD_DID_TYPE_KEYPAD		0x00	/* Vectra Keyboard */
++
++/* IDD record header 
++ */
++#define HIL_IDD_HEADER_AXSET_MASK	0x03    /* Number of axis in a set */
++#define HIL_IDD_HEADER_RSC		0x04	/* Supports RSC command */
++#define HIL_IDD_HEADER_EXD		0x08	/* Supports EXD command */
++#define HIL_IDD_HEADER_IOD		0x10	/* IOD byte to follow */
++#define HIL_IDD_HEADER_16BIT		0x20	/* 16 (vs. 8) bit resolution */
++#define HIL_IDD_HEADER_ABS		0x40	/* Reports Absolute Position */
++#define HIL_IDD_HEADER_2X_AXIS		0x80	/* Two sets of 1-3 axis */
++
++/* I/O Descriptor
++ */
++#define HIL_IDD_IOD_NBUTTON_MASK	0x07	/* Number of buttons */
++#define HIL_IDD_IOD_PROXIMITY		0x08	/* Proximity in/out events */
++#define HIL_IDD_IOD_PROMPT_MASK		0x70	/* Number of prompts/acks */
++#define HIL_IDD_IOD_PROMPT_SHIFT	4
++#define HIL_IDD_IOD_PROMPT		0x80	/* Generic prompt/ack */
++
++#define HIL_IDD_NUM_AXES_PER_SET(header_packet) \
++((header_packet) & HIL_IDD_HEADER_AXSET_MASK)
++
++#define HIL_IDD_NUM_AXSETS(header_packet) \
++(2 - !((header_packet) & HIL_IDD_HEADER_2X_AXIS))
++
++#define HIL_IDD_LEN(header_packet) \
++((4 - !(header_packet & HIL_IDD_HEADER_IOD) -			\
++  2 * !(HIL_IDD_NUM_AXES_PER_SET(header_packet))) +		\
++  2 * HIL_IDD_NUM_AXES_PER_SET(header_packet) *			\
++ !!((header_packet) & HIL_IDD_HEADER_ABS))
++
++/* The following HIL_IDD_* macros assume you have an array of 
++ * packets and/or unpacked 8-bit data in the order that they 
++ * were received.
++ */
++
++#define HIL_IDD_AXIS_COUNTS_PER_M(header_ptr) \
++(!(HIL_IDD_NUM_AXSETS(*(header_ptr))) ? -1 :			\
++(((*(header_ptr + 1) & HIL_PKT_DATA_MASK) +			\
++  ((*(header_ptr + 2) & HIL_PKT_DATA_MASK)) << 8)		\
++* ((*(header_ptr) & HIL_IDD_HEADER_16BIT) ? 100 : 1)))
++
++#define HIL_IDD_AXIS_MAX(header_ptr, __axnum) \
++((!(*(header_ptr) & HIL_IDD_HEADER_ABS) ||			\
++  (HIL_IDD_NUM_AXES_PER_SET(*(header_ptr)) <= __axnum)) ? 0 :	\
++ ((HIL_PKT_DATA_MASK & *((header_ptr) + 3 + 2 * __axnum)) +	\
++  ((HIL_PKT_DATA_MASK & *((header_ptr) + 4 + 2 * __axnum)) << 8)))
++
++#define HIL_IDD_IOD(header_ptr) \
++(*(header_ptr + HIL_IDD_LEN((*header_ptr)) - 1))
++
++#define HIL_IDD_HAS_GEN_PROMPT(header_ptr) \
++((*header_ptr & HIL_IDD_HEADER_IOD) &&				\
++ (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROMPT))
++
++#define HIL_IDD_HAS_GEN_PROXIMITY(header_ptr) \
++((*header_ptr & HIL_IDD_HEADER_IOD) &&				\
++ (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROXIMITY))
++
++#define HIL_IDD_NUM_BUTTONS(header_ptr) \
++((*header_ptr & HIL_IDD_HEADER_IOD) ?				\
++ (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NBUTTON_MASK) : 0)
++
++#define HIL_IDD_NUM_PROMPTS(header_ptr) \
++((*header_ptr & HIL_IDD_HEADER_IOD) ?				\
++ ((HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NPROMPT_MASK)		\
++  >> HIL_IDD_IOD_PROMPT_SHIFT) : 0)
++
++/* The response to HIL EXD commands -- the "extended describe record" */
++#define	HIL_EXD_HEADER_WRG		0x03	/* Supports type2 WRG */
++#define HIL_EXD_HEADER_WRG_TYPE1	0x01	/* Supports type1 WRG */
++#define	HIL_EXD_HEADER_WRG_TYPE2	0x02	/* Supports type2 WRG */
++#define	HIL_EXD_HEADER_RRG		0x04	/* Supports RRG command */
++#define	HIL_EXD_HEADER_RNM		0x10	/* Supports RNM command */
++#define HIL_EXD_HEADER_RST		0x20	/* Supports RST command */
++#define HIL_EXD_HEADER_LOCALE		0x40	/* Contains locale code */
++
++#define HIL_EXD_NUM_RRG(header_ptr) \
++((*header_ptr & HIL_EXD_HEADER_RRG) ? \
++ (*(header_ptr + 1) & HIL_PKT_DATA_MASK) : 0)
++
++#define HIL_EXD_NUM_WWG(header_ptr) \
++((*header_ptr & HIL_EXD_HEADER_WRG) ?				\
++ (*(header_ptr + 2 - !(*header_ptr & HIL_EXD_HEADER_RRG)) &	\
++    HIL_PKT_DATA_MASK) : 0)
++
++#define HIL_EXD_LEN(header_ptr) \
++(!!(*header_ptr & HIL_EXD_HEADER_RRG) +				\
++ !!(*header_ptr & HIL_EXD_HEADER_WRG) +				\
++ !!(*header_ptr & HIL_EXD_HEADER_LOCALE) +			\
++ 2 * !!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) + 1)
++
++#define HIL_EXD_LOCALE(header_ptr) \
++(!(*header_ptr & HIL_EXD_HEADER_LOCALE) ? -1 :			\
++ (*(header_ptr + HIL_EXD_LEN(header_ptr) - 1) & HIL_PKT_DATA_MASK))
++
++#define HIL_EXD_WRG_TYPE2_LEN(header_ptr) \
++(!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) ? -1	:			\
++ (*(header_ptr + HIL_EXD_LEN(header_ptr) - 2 -                  	\
++    !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) +	\
++ ((*(header_ptr + HIL_EXD_LEN(header_ptr) - 1 -				\
++     !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) << 8))
++
++/* Device locale codes. */ 
++
++/* Last defined locale code.  Everything above this is "Reserved",
++   and note that this same table applies to the Device ID Byte where 
++   keyboards may have a nationality code which is only 5 bits. */
++#define HIL_LOCALE_MAX 0x1f
++
++/* Map to hopefully useful strings.  I was trying to make these look
++   like locale.aliases strings do; maybe that isn't the right table to
++   emulate.  In either case, I didn't have much to work on. */
++#define HIL_LOCALE_MAP \
++"",			/* 0x00 Reserved */		\
++"",			/* 0x01 Reserved */		\
++"",			/* 0x02 Reserved */		\
++"swiss.french",		/* 0x03 Swiss/French */		\
++"portuguese",		/* 0x04 Portuguese */		\
++"arabic",		/* 0x05 Arabic */		\
++"hebrew",		/* 0x06 Hebrew */		\
++"english.canadian",	/* 0x07 Canadian English */	\
++"turkish",		/* 0x08 Turkish */		\
++"greek",		/* 0x09 Greek */		\
++"thai",			/* 0x0a Thai (Thailand) */	\
++"italian",		/* 0x0b Italian */		\
++"korean",		/* 0x0c Hangul (Korea) */	\
++"dutch",		/* 0x0d Dutch */		\
++"swedish",		/* 0x0e Swedish */		\
++"german",		/* 0x0f German */		\
++"chinese",		/* 0x10 Chinese-PRC */		\
++"chinese",		/* 0x11 Chinese-ROC */		\
++"swiss.french",		/* 0x12 Swiss/French II */	\
++"spanish",		/* 0x13 Spanish */		\
++"swiss.german",		/* 0x14 Swiss/German II */	\
++"flemish",		/* 0x15 Belgian (Flemish) */	\
++"finnish",		/* 0x16 Finnish	*/		\
++"english.uk",		/* 0x17 United Kingdom */	\
++"french.canadian",	/* 0x18 French/Canadian */	\
++"swiss.german",		/* 0x19 Swiss/German */		\
++"norwegian",		/* 0x1a Norwegian */		\
++"french",		/* 0x1b French */		\
++"danish",		/* 0x1c Danish */		\
++"japanese",		/* 0x1d Katakana */		\
++"spanish",		/* 0x1e Latin American/Spanish*/\
++"english.us"		/* 0x1f United States */	\
++
++
++/* HIL keycodes */
++#define HIL_KEYCODES_SET1_TBLSIZE 128
++#define HIL_KEYCODES_SET1 	\
++   KEY_5,		KEY_RESERVED,	KEY_RIGHTALT,	KEY_LEFTALT,	\
++   KEY_RIGHTSHIFT,	KEY_LEFTSHIFT,	KEY_LEFTCTRL,	KEY_SYSRQ,	\
++   KEY_KP4,		KEY_KP8,	KEY_KP5,	KEY_KP9,	\
++   KEY_KP6,		KEY_KP7,	KEY_KPCOMMA,	KEY_KPENTER,	\
++   KEY_KP1,		KEY_KPSLASH,	KEY_KP2,	KEY_KPPLUS,	\
++   KEY_KP3,		KEY_KPASTERISK,	KEY_KP0,	KEY_KPMINUS,	\
++   KEY_B,		KEY_V,		KEY_C,		KEY_X,		\
++   KEY_Z,		KEY_RESERVED,	KEY_RESERVED,   KEY_ESC,	\
++   KEY_6,		KEY_F10,	KEY_3,		KEY_F11,	\
++   KEY_KPDOT,		KEY_F9,		KEY_TAB /*KP*/,	KEY_F12,	\
++   KEY_H,		KEY_G,		KEY_F,		KEY_D,		\
++   KEY_S,		KEY_A,		KEY_RESERVED,	KEY_CAPSLOCK,	\
++   KEY_U,		KEY_Y,		KEY_T,		KEY_R,		\
++   KEY_E,		KEY_W,		KEY_Q,		KEY_TAB,	\
++   KEY_7,		KEY_6,		KEY_5,		KEY_4,		\
++   KEY_3,		KEY_2,		KEY_1,		KEY_GRAVE,	\
++   KEY_F13,		KEY_F14,	KEY_F15,	KEY_F16,	\
++   KEY_F17,		KEY_F18,	KEY_F19,	KEY_F20,	\
++   KEY_MENU,		KEY_F4,		KEY_F3,		KEY_F2,		\
++   KEY_F1,		KEY_VOLUMEUP,	KEY_STOP,	KEY_SENDFILE,	\
++   KEY_SYSRQ,		KEY_F5,		KEY_F6,		KEY_F7,		\
++   KEY_F8,		KEY_VOLUMEDOWN,	KEY_DEL_EOL,	KEY_DEL_EOS,	\
++   KEY_8,		KEY_9,		KEY_0,		KEY_MINUS,	\
++   KEY_EQUAL,		KEY_BACKSPACE,	KEY_INS_LINE,	KEY_DEL_LINE,	\
++   KEY_I,		KEY_O,		KEY_P,		KEY_LEFTBRACE,	\
++   KEY_RIGHTBRACE,	KEY_BACKSLASH,	KEY_INSERT,	KEY_DELETE,	\
++   KEY_J,		KEY_K,		KEY_L,		KEY_SEMICOLON,	\
++   KEY_APOSTROPHE,	KEY_ENTER,	KEY_HOME,	KEY_PAGEUP,	\
++   KEY_M,		KEY_COMMA,	KEY_DOT,	KEY_SLASH,	\
++   KEY_BACKSLASH,	KEY_SELECT,	KEY_102ND,	KEY_PAGEDOWN,	\
++   KEY_N,		KEY_SPACE,	KEY_NEXT,	KEY_RESERVED,	\
++   KEY_LEFT,		KEY_DOWN,	KEY_UP,		KEY_RIGHT
++
++
++#define HIL_KEYCODES_SET3_TBLSIZE 128
++#define HIL_KEYCODES_SET3 	\
++  KEY_RESERVED,	KEY_ESC,	KEY_1,		KEY_2,			\
++  KEY_3,	KEY_4,		KEY_5,		KEY_6,			\
++  KEY_7,	KEY_8,		KEY_9,		KEY_0,			\
++  KEY_MINUS,	KEY_EQUAL,	KEY_BACKSPACE,	KEY_TAB,		\
++  KEY_Q,	KEY_W,		KEY_E,		KEY_R,			\
++  KEY_T,	KEY_Y,		KEY_U,		KEY_I,			\
++  KEY_O,	KEY_P,		KEY_LEFTBRACE,	KEY_RIGHTBRACE,		\
++  KEY_ENTER,	KEY_LEFTCTRL,	KEY_A,		KEY_S,			\
++  KEY_D,	KEY_F,		KEY_G,		KEY_H,			\
++  KEY_J,	KEY_K,		KEY_L,		KEY_SEMICOLON,		\
++  KEY_APOSTROPHE,KEY_GRAVE,	KEY_LEFTSHIFT,	KEY_BACKSLASH,		\
++  KEY_Z,	KEY_X,		KEY_C,		KEY_V,			\
++  KEY_B,	KEY_N,		KEY_M,		KEY_COMMA,		\
++  KEY_DOT,	KEY_SLASH,	KEY_RIGHTSHIFT,	KEY_KPASTERISK,		\
++  KEY_LEFTALT,	KEY_SPACE,	KEY_CAPSLOCK,	KEY_F1,			\
++  KEY_F2,	KEY_F3,		KEY_F4,		KEY_F5,			\
++  KEY_F6,	KEY_F7,		KEY_F8,		KEY_F9,			\
++  KEY_F10,	KEY_NUMLOCK,	KEY_SCROLLLOCK,	KEY_KP7,		\
++  KEY_KP8,	KEY_KP9,	KEY_KPMINUS,	KEY_KP4,		\
++  KEY_KP5,	KEY_KP6,	KEY_KPPLUS,	KEY_KP1,		\
++  KEY_KP2,	KEY_KP3,	KEY_KP0,	KEY_KPDOT,		\
++  KEY_SYSRQ,	KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,		\
++  KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,		\
++  KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,		\
++  KEY_UP,	KEY_LEFT,	KEY_DOWN,	KEY_RIGHT,		\
++  KEY_HOME,	KEY_PAGEUP,	KEY_END,	KEY_PAGEDOWN,		\
++  KEY_INSERT,	KEY_DELETE,	KEY_102ND,	KEY_RESERVED,		\
++  KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,		\
++  KEY_F1,	KEY_F2,		KEY_F3,		KEY_F4,			\
++  KEY_F5,	KEY_F6,		KEY_F7,		KEY_F8,			\
++  KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,		\
++  KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED,	KEY_RESERVED
++
++
++/* Response to POL command, the "poll record header" */
++
++#define HIL_POL_NUM_AXES_MASK	0x03	/* Number of axis reported */
++#define HIL_POL_CTS		0x04	/* Device ready to receive data */
++#define HIL_POL_STATUS_PENDING	0x08	/* Device has status to report */
++#define HIL_POL_CHARTYPE_MASK	0x70	/* Type of character data to follow */
++#define HIL_POL_CHARTYPE_NONE	0x00	/* No character data to follow */
++#define HIL_POL_CHARTYPE_RSVD1	0x10	/* Reserved Set 1 */
++#define HIL_POL_CHARTYPE_ASCII	0x20	/* U.S. ASCII */
++#define HIL_POL_CHARTYPE_BINARY	0x30	/* Binary data */
++#define HIL_POL_CHARTYPE_SET1	0x40	/* Keycode Set 1 */
++#define HIL_POL_CHARTYPE_RSVD2	0x50	/* Reserved Set 2 */
++#define HIL_POL_CHARTYPE_SET2	0x60	/* Keycode Set 2 */
++#define HIL_POL_CHARTYPE_SET3	0x70	/* Keycode Set 3 */
++#define HIL_POL_AXIS_ALT	0x80	/* Data is from axis set 2 */
++
++
++#endif /* _HIL_H_ */
+diff --git a/include/linux/hil_mlc.h b/include/linux/hil_mlc.h
+new file mode 100644
+--- /dev/null
++++ b/include/linux/hil_mlc.h
+@@ -0,0 +1,168 @@
++/*
++ * HP Human Interface Loop Master Link Controller driver.
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * 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,
++ *    without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ *    derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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
++ *
++ * References:
++ * HP-HIL Technical Reference Manual.  Hewlett Packard Product No. 45918A
++ *
++ */
++
++#include <linux/hil.h>
++#include <linux/time.h>
++#include <linux/interrupt.h>
++#include <asm/semaphore.h>
++#include <linux/serio.h>
++#include <linux/list.h>
++
++typedef struct hil_mlc hil_mlc;
++
++/* The HIL has a complicated state engine.
++ * We define the structure of nodes in the state engine here.
++ */
++enum hilse_act {
++  	/* HILSE_OUT prepares to receive input if the next node
++	 * is an IN or EXPECT, and then sends the given packet.
++	 */
++	HILSE_OUT = 0,
++
++  	/* HILSE_CTS checks if the loop is busy. */
++	HILSE_CTS,
++
++	/* HILSE_OUT_LAST sends the given command packet to 
++	 * the last configured/running device on the loop.
++	 */
++	HILSE_OUT_LAST,
++
++	/* HILSE_OUT_DISC sends the given command packet to
++	 * the next device past the last configured/running one.
++	 */
++	HILSE_OUT_DISC,
++
++	/* HILSE_FUNC runs a callback function with given arguments.
++	 * a positive return value causes the "ugly" branch to be taken.
++	 */
++	HILSE_FUNC,
++
++  	/* HILSE_IN simply expects any non-errored packet to arrive 
++	 * within arg usecs.
++	 */
++	HILSE_IN		= 0x100,
++
++  	/* HILSE_EXPECT expects a particular packet to arrive 
++	 * within arg usecs, any other packet is considered an error.
++	 */
++	HILSE_EXPECT,
++
++  	/* HILSE_EXPECT_LAST as above but dev field should be last 
++	 * discovered/operational device.
++	 */
++	HILSE_EXPECT_LAST,
++
++  	/* HILSE_EXPECT_LAST as above but dev field should be first 
++	 * undiscovered/inoperational device.
++	 */
++	HILSE_EXPECT_DISC
++};
++
++typedef int	(hilse_func) (hil_mlc *mlc, int arg);
++struct hilse_node {
++	enum hilse_act		act;	/* How to process this node         */
++	union {
++		hilse_func	*func;	/* Function to call if HILSE_FUNC   */
++		hil_packet	packet;	/* Packet to send or to compare     */
++	} object;
++	int			arg;	/* Timeout in usec or parm for func */
++	int			good;	/* Node to jump to on success       */
++	int			bad;	/* Node to jump to on error         */
++	int			ugly;	/* Node to jump to on timeout       */
++};
++
++/* Methods for back-end drivers, e.g. hp_sdc_mlc */
++typedef int	(hil_mlc_cts) (hil_mlc *mlc);
++typedef void	(hil_mlc_out) (hil_mlc *mlc);
++typedef int	(hil_mlc_in)  (hil_mlc *mlc, suseconds_t timeout);
++
++struct hil_mlc_devinfo {
++	uint8_t	idd[16];	/* Device ID Byte and Describe Record */
++	uint8_t	rsc[16];	/* Security Code Header and Record */
++	uint8_t	exd[16];	/* Extended Describe Record */
++	uint8_t	rnm[16];	/* Device name as returned by RNM command */
++};
++
++struct hil_mlc_serio_map {
++	hil_mlc *mlc;
++	int di_revmap;
++	int didx;
++};
++
++/* How many (possibly old/detached) devices the we try to keep track of */
++#define HIL_MLC_DEVMEM 16
++
++struct hil_mlc {
++	struct list_head	list;	/* hil_mlc is organized as linked list */
++
++	rwlock_t		lock;
++
++	void *priv; /* Data specific to a particular type of MLC */
++
++	int 			seidx;	/* Current node in state engine */
++	int			istarted, ostarted;
++
++	hil_mlc_cts		*cts;
++	struct semaphore	csem;   /* Raised when loop idle */
++
++	hil_mlc_out		*out;
++	struct semaphore	osem;   /* Raised when outpacket dispatched */
++	hil_packet		opacket;
++
++	hil_mlc_in		*in;
++	struct semaphore	isem;   /* Raised when a packet arrives */
++	hil_packet		ipacket[16];
++	hil_packet		imatch;
++	int			icount;
++	struct timeval		instart;
++	suseconds_t		intimeout;
++
++	int			ddi;	/* Last operational device id */
++	int			lcv;	/* LCV to throttle loops */
++	struct timeval		lcv_tv; /* Time loop was started */
++
++	int			di_map[7]; /* Maps below items to live devs */
++	struct hil_mlc_devinfo	di[HIL_MLC_DEVMEM];
++	struct serio		*serio[HIL_MLC_DEVMEM];
++	struct hil_mlc_serio_map serio_map[HIL_MLC_DEVMEM];
++	hil_packet		serio_opacket[HIL_MLC_DEVMEM];
++	int			serio_oidx[HIL_MLC_DEVMEM];
++	struct hil_mlc_devinfo	di_scratch; /* Temporary area */
++
++	int			opercnt;
++
++	struct tasklet_struct	*tasklet;
++};
++
++int hil_mlc_register(hil_mlc *mlc);
++int hil_mlc_unregister(hil_mlc *mlc);
+diff --git a/include/linux/hp_sdc.h b/include/linux/hp_sdc.h
+new file mode 100644
+--- /dev/null
++++ b/include/linux/hp_sdc.h
+@@ -0,0 +1,300 @@
++/*
++ * HP i8042 System Device Controller -- header
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * 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,
++ *    without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ *    derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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
++ *
++ * References:
++ * 
++ * HP-HIL Technical Reference Manual.  Hewlett Packard Product No. 45918A
++ *
++ * System Device Controller Microprocessor Firmware Theory of Operation
++ * 	for Part Number 1820-4784 Revision B.  Dwg No. A-1820-4784-2
++ *
++ */
++
++#ifndef _LINUX_HP_SDC_H
++#define _LINUX_HP_SDC_H
++
++#include <linux/interrupt.h>
++#include <linux/types.h>
++#include <linux/time.h>
++#include <linux/timer.h>
++#if defined(__hppa__)
++#include <asm/hardware.h>
++#endif
++
++
++/* No 4X status reads take longer than this (in usec).
++ */
++#define HP_SDC_MAX_REG_DELAY 20000
++
++typedef void (hp_sdc_irqhook) (int irq, void *dev_id, 
++			       uint8_t status, uint8_t data);
++
++int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback);
++int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback);
++int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback);
++int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback);
++int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback);
++int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback);
++
++typedef struct {
++	int actidx;	/* Start of act.  Acts are atomic WRT I/O to SDC */
++	int idx;	/* Index within the act */
++	int endidx;	/* transaction is over and done if idx == endidx */
++	uint8_t *seq;	/* commands/data for the transaction */
++	union {
++	  hp_sdc_irqhook   *irqhook;	/* Callback, isr or tasklet context */
++	  struct semaphore *semaphore;	/* Semaphore to sleep on. */
++	} act;
++} hp_sdc_transaction;
++int hp_sdc_enqueue_transaction(hp_sdc_transaction *this);
++int hp_sdc_dequeue_transaction(hp_sdc_transaction *this);
++
++/* The HP_SDC_ACT* values are peculiar to this driver.
++ * Nuance: never HP_SDC_ACT_DATAIN | HP_SDC_ACT_DEALLOC, use another
++ * act to perform the dealloc.
++ */
++#define HP_SDC_ACT_PRECMD	0x01		/* Send a command first */
++#define HP_SDC_ACT_DATAREG	0x02		/* Set data registers */
++#define HP_SDC_ACT_DATAOUT	0x04		/* Send data bytes */
++#define HP_SDC_ACT_POSTCMD      0x08            /* Send command after */
++#define HP_SDC_ACT_DATAIN	0x10		/* Collect data after */
++#define HP_SDC_ACT_DURING	0x1f
++#define HP_SDC_ACT_SEMAPHORE    0x20            /* Raise semaphore after */
++#define HP_SDC_ACT_CALLBACK	0x40		/* Pass data to IRQ handler */
++#define HP_SDC_ACT_DEALLOC	0x80		/* Destroy transaction after */
++#define HP_SDC_ACT_AFTER	0xe0
++#define HP_SDC_ACT_DEAD		0x60		/* Act timed out. */
++
++/* Rest of the flags are straightforward representation of the SDC interface */
++#define HP_SDC_STATUS_IBF	0x02	/* Input buffer full */
++
++#define HP_SDC_STATUS_IRQMASK	0xf0	/* Bits containing "level 1" irq */
++#define HP_SDC_STATUS_PERIODIC  0x10    /* Periodic 10ms timer */
++#define HP_SDC_STATUS_USERTIMER 0x20    /* "Special purpose" timer */
++#define HP_SDC_STATUS_TIMER     0x30    /* Both PERIODIC and USERTIMER */
++#define HP_SDC_STATUS_REG	0x40	/* Data from an i8042 register */
++#define HP_SDC_STATUS_HILCMD    0x50	/* Command from HIL MLC */
++#define HP_SDC_STATUS_HILDATA   0x60	/* Data from HIL MLC */
++#define HP_SDC_STATUS_PUP	0x70	/* Sucessful power-up self test */
++#define HP_SDC_STATUS_KCOOKED	0x80	/* Key from cooked kbd */
++#define HP_SDC_STATUS_KRPG	0xc0	/* Key from Repeat Gen */
++#define HP_SDC_STATUS_KMOD_SUP	0x10	/* Shift key is up */
++#define HP_SDC_STATUS_KMOD_CUP	0x20	/* Control key is up */
++
++#define HP_SDC_NMISTATUS_FHS	0x40	/* NMI is a fast handshake irq */
++
++/* Internal i8042 registers (there are more, but they are not too useful). */
++
++#define HP_SDC_USE		0x02	/* Resource usage (including OB bit) */
++#define HP_SDC_IM		0x04	/* Interrupt mask */
++#define HP_SDC_CFG		0x11	/* Configuration register */
++#define HP_SDC_KBLANGUAGE	0x12	/* Keyboard language */
++
++#define HP_SDC_D0		0x70	/* General purpose data buffer 0 */
++#define HP_SDC_D1		0x71	/* General purpose data buffer 1 */
++#define HP_SDC_D2		0x72	/* General purpose data buffer 2 */
++#define HP_SDC_D3		0x73	/* General purpose data buffer 3 */
++#define HP_SDC_VT1		0x74	/* Timer for voice 1 */
++#define HP_SDC_VT2		0x75	/* Timer for voice 2 */
++#define HP_SDC_VT3		0x76	/* Timer for voice 3 */
++#define HP_SDC_VT4		0x77	/* Timer for voice 4 */
++#define HP_SDC_KBN		0x78	/* Which HIL devs are Nimitz */
++#define HP_SDC_KBC		0x79	/* Which HIL devs are cooked kbds */
++#define HP_SDC_LPS		0x7a	/* i8042's view of HIL status */
++#define HP_SDC_LPC		0x7b	/* i8042's view of HIL "control" */
++#define HP_SDC_RSV  		0x7c	/* Reserved "for testing" */
++#define HP_SDC_LPR		0x7d    /* i8042 count of HIL reconfigs */
++#define HP_SDC_XTD		0x7e    /* "Extended Configuration" register */
++#define HP_SDC_STR		0x7f    /* i8042 self-test result */
++
++/* Bitfields for above registers */
++#define HP_SDC_USE_LOOP		0x04	/* Command is currently on the loop. */
++
++#define HP_SDC_IM_MASK          0x1f    /* these bits not part of cmd/status */
++#define HP_SDC_IM_FH		0x10	/* Mask the fast handshake irq */
++#define HP_SDC_IM_PT		0x08	/* Mask the periodic timer irq */
++#define HP_SDC_IM_TIMERS	0x04	/* Mask the MT/DT/CT irq */
++#define HP_SDC_IM_RESET		0x02	/* Mask the reset key irq */
++#define HP_SDC_IM_HIL		0x01	/* Mask the HIL MLC irq */
++
++#define HP_SDC_CFG_ROLLOVER	0x08	/* WTF is "N-key rollover"? */
++#define HP_SDC_CFG_KBD		0x10	/* There is a keyboard */
++#define HP_SDC_CFG_NEW		0x20	/* Supports/uses HIL MLC */
++#define HP_SDC_CFG_KBD_OLD	0x03	/* keyboard code for non-HIL */
++#define HP_SDC_CFG_KBD_NEW	0x07	/* keyboard code from HIL autoconfig */
++#define HP_SDC_CFG_REV		0x40	/* Code revision bit */
++#define HP_SDC_CFG_IDPROM	0x80	/* IDPROM present in kbd (not HIL) */
++
++#define HP_SDC_LPS_NDEV		0x07	/* # devices autoconfigured on HIL */
++#define HP_SDC_LPS_ACSUCC	0x08	/* loop autoconfigured successfully */
++#define HP_SDC_LPS_ACFAIL	0x80	/* last loop autoconfigure failed */
++
++#define HP_SDC_LPC_APE_IPF	0x01	/* HIL MLC APE/IPF (autopoll) set */
++#define HP_SDC_LPC_ARCONERR	0x02	/* i8042 autoreconfigs loop on err */
++#define HP_SDC_LPC_ARCQUIET	0x03	/* i8042 doesn't report autoreconfigs*/
++#define HP_SDC_LPC_COOK		0x10	/* i8042 cooks devices in _KBN */
++#define HP_SDC_LPC_RC		0x80	/* causes autoreconfig */
++
++#define HP_SDC_XTD_REV		0x07	/* contains revision code */
++#define HP_SDC_XTD_REV_STRINGS(val, str) \
++switch (val) {						\
++	case 0x1: str = "1820-3712"; break;		\
++	case 0x2: str = "1820-4379"; break;		\
++	case 0x3: str = "1820-4784"; break;		\
++	default: str = "unknown";			\
++};
++#define HP_SDC_XTD_BEEPER	0x08	/* TI SN76494 beeper available */
++#define HP_SDC_XTD_BBRTC	0x20	/* OKI MSM-58321 BBRTC present */
++
++#define HP_SDC_CMD_LOAD_RT	0x31	/* Load real time (from 8042) */
++#define HP_SDC_CMD_LOAD_FHS	0x36	/* Load the fast handshake timer */
++#define HP_SDC_CMD_LOAD_MT	0x38	/* Load the match timer */
++#define HP_SDC_CMD_LOAD_DT	0x3B	/* Load the delay timer */
++#define HP_SDC_CMD_LOAD_CT	0x3E	/* Load the cycle timer */
++
++#define HP_SDC_CMD_SET_IM	0x40    /* 010xxxxx == set irq mask */
++
++/* The documents provided do not explicitly state that all registers betweem 
++ * 0x01 and 0x1f inclusive can be read by sending their register index as a 
++ * command, but this is implied and appears to be the case.
++ */
++#define HP_SDC_CMD_READ_RAM	0x00	/* Load from i8042 RAM (autoinc) */
++#define HP_SDC_CMD_READ_USE	0x02	/* Undocumented! Load from usage reg */
++#define HP_SDC_CMD_READ_IM	0x04	/* Load current interrupt mask */
++#define HP_SDC_CMD_READ_KCC	0x11	/* Load primary kbd config code */
++#define HP_SDC_CMD_READ_KLC	0x12	/* Load primary kbd language code */
++#define HP_SDC_CMD_READ_T1	0x13	/* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_T2	0x14	/* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_T3	0x15	/* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_T4	0x16	/* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_T5	0x17	/* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_D0	0xf0	/* Load from i8042 RAM location 0x70 */
++#define HP_SDC_CMD_READ_D1	0xf1	/* Load from i8042 RAM location 0x71 */
++#define HP_SDC_CMD_READ_D2	0xf2	/* Load from i8042 RAM location 0x72 */
++#define HP_SDC_CMD_READ_D3	0xf3	/* Load from i8042 RAM location 0x73 */
++#define HP_SDC_CMD_READ_VT1	0xf4	/* Load from i8042 RAM location 0x74 */
++#define HP_SDC_CMD_READ_VT2	0xf5	/* Load from i8042 RAM location 0x75 */
++#define HP_SDC_CMD_READ_VT3	0xf6	/* Load from i8042 RAM location 0x76 */
++#define HP_SDC_CMD_READ_VT4	0xf7	/* Load from i8042 RAM location 0x77 */
++#define HP_SDC_CMD_READ_KBN	0xf8	/* Load from i8042 RAM location 0x78 */
++#define HP_SDC_CMD_READ_KBC	0xf9	/* Load from i8042 RAM location 0x79 */
++#define HP_SDC_CMD_READ_LPS	0xfa	/* Load from i8042 RAM location 0x7a */
++#define HP_SDC_CMD_READ_LPC	0xfb	/* Load from i8042 RAM location 0x7b */
++#define HP_SDC_CMD_READ_RSV	0xfc	/* Load from i8042 RAM location 0x7c */
++#define HP_SDC_CMD_READ_LPR	0xfd	/* Load from i8042 RAM location 0x7d */
++#define HP_SDC_CMD_READ_XTD	0xfe	/* Load from i8042 RAM location 0x7e */
++#define HP_SDC_CMD_READ_STR	0xff	/* Load from i8042 RAM location 0x7f */
++
++#define HP_SDC_CMD_SET_ARD	0xA0	/* Set emulated autorepeat delay */
++#define HP_SDC_CMD_SET_ARR	0xA2	/* Set emulated autorepeat rate */
++#define HP_SDC_CMD_SET_BELL	0xA3	/* Set voice 3 params for "beep" cmd */
++#define HP_SDC_CMD_SET_RPGR	0xA6	/* Set "RPG" irq rate (doesn't work) */
++#define HP_SDC_CMD_SET_RTMS	0xAD	/* Set the RTC time (milliseconds) */
++#define HP_SDC_CMD_SET_RTD	0xAF	/* Set the RTC time (days) */
++#define HP_SDC_CMD_SET_FHS	0xB2	/* Set fast handshake timer */
++#define HP_SDC_CMD_SET_MT	0xB4	/* Set match timer */
++#define HP_SDC_CMD_SET_DT	0xB7	/* Set delay timer */
++#define HP_SDC_CMD_SET_CT	0xBA	/* Set cycle timer */
++#define HP_SDC_CMD_SET_RAMP	0xC1	/* Reset READ_RAM autoinc counter */
++#define HP_SDC_CMD_SET_D0	0xe0	/* Load to i8042 RAM location 0x70 */
++#define HP_SDC_CMD_SET_D1	0xe1	/* Load to i8042 RAM location 0x71 */
++#define HP_SDC_CMD_SET_D2	0xe2	/* Load to i8042 RAM location 0x72 */
++#define HP_SDC_CMD_SET_D3	0xe3	/* Load to i8042 RAM location 0x73 */
++#define HP_SDC_CMD_SET_VT1	0xe4	/* Load to i8042 RAM location 0x74 */
++#define HP_SDC_CMD_SET_VT2	0xe5	/* Load to i8042 RAM location 0x75 */
++#define HP_SDC_CMD_SET_VT3	0xe6	/* Load to i8042 RAM location 0x76 */
++#define HP_SDC_CMD_SET_VT4	0xe7	/* Load to i8042 RAM location 0x77 */
++#define HP_SDC_CMD_SET_KBN	0xe8	/* Load to i8042 RAM location 0x78 */
++#define HP_SDC_CMD_SET_KBC	0xe9	/* Load to i8042 RAM location 0x79 */
++#define HP_SDC_CMD_SET_LPS	0xea	/* Load to i8042 RAM location 0x7a */
++#define HP_SDC_CMD_SET_LPC	0xeb	/* Load to i8042 RAM location 0x7b */
++#define HP_SDC_CMD_SET_RSV	0xec	/* Load to i8042 RAM location 0x7c */
++#define HP_SDC_CMD_SET_LPR	0xed	/* Load to i8042 RAM location 0x7d */
++#define HP_SDC_CMD_SET_XTD	0xee	/* Load to i8042 RAM location 0x7e */
++#define HP_SDC_CMD_SET_STR	0xef	/* Load to i8042 RAM location 0x7f */
++
++#define HP_SDC_CMD_DO_RTCW	0xc2	/* i8042 RAM 0x70 --> RTC */
++#define HP_SDC_CMD_DO_RTCR	0xc3	/* RTC[0x70 0:3] --> irq/status/data */
++#define HP_SDC_CMD_DO_BEEP	0xc4	/* i8042 RAM 0x70-74  --> beeper,VT3 */
++#define HP_SDC_CMD_DO_HIL	0xc5	/* i8042 RAM 0x70-73 --> 
++					   HIL MLC R0,R1 i8042 HIL watchdog */
++
++/* Values used to (de)mangle input/output to/from the HIL MLC */
++#define HP_SDC_DATA		0x40	/* Data from an 8042 register */
++#define HP_SDC_HIL_CMD		0x50	/* Data from HIL MLC R1/8042 */
++#define HP_SDC_HIL_R1MASK	0x0f	/* Contents of HIL MLC R1 0:3 */
++#define HP_SDC_HIL_AUTO		0x10	/* Set if POL results from i8042 */   
++#define HP_SDC_HIL_ISERR	0x80	/* Has meaning as in next 4 values */
++#define HP_SDC_HIL_RC_DONE	0x80	/* i8042 auto-configured loop */
++#define HP_SDC_HIL_ERR		0x81	/* HIL MLC R2 had a bit set */
++#define HP_SDC_HIL_TO		0x82	/* i8042 HIL watchdog expired */
++#define HP_SDC_HIL_RC		0x84	/* i8042 is auto-configuring loop */
++#define HP_SDC_HIL_DAT		0x60	/* Data from HIL MLC R0 */
++
++
++typedef struct {
++	rwlock_t	ibf_lock;
++	rwlock_t	lock;		/* user/tasklet lock */
++	rwlock_t	rtq_lock;	/* isr/tasklet lock */
++	rwlock_t	hook_lock;	/* isr/user lock for handler add/del */
++
++	unsigned int	irq, nmi;	/* Our IRQ lines */
++	unsigned long	base_io, status_io, data_io; /* Our IO ports */
++
++	uint8_t		im;		/* Interrupt mask */
++	int		set_im; 	/* Interrupt mask needs to be set. */
++
++	int		ibf;		/* Last known status of IBF flag */
++	uint8_t		wi;		/* current i8042 write index */
++	uint8_t		r7[4];          /* current i8042[0x70 - 0x74] values */
++	uint8_t		r11, r7e;	/* Values from version/revision regs */
++
++	hp_sdc_irqhook	*timer, *reg, *hil, *pup, *cooked;
++
++#define HP_SDC_QUEUE_LEN 16
++	hp_sdc_transaction *tq[HP_SDC_QUEUE_LEN]; /* All pending read/writes */
++
++	int		rcurr, rqty;	/* Current read transact in process */
++	struct timeval	rtv;		/* Time when current read started */
++	int		wcurr;		/* Current write transact in process */
++
++	int		dev_err;	/* carries status from registration */
++#if defined(__hppa__)
++	struct parisc_device	*dev;
++#elif defined(__mc68000__)
++	void		*dev;
++#else
++#error No support for device registration on this arch yet.
++#endif
++
++	struct timer_list kicker;	/* Keeps below task alive */
++	struct tasklet_struct	task;
++
++} hp_i8042_sdc;
++
++#endif /* _LINUX_HP_SDC_H */
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -16,7 +16,6 @@ static inline int is_vm_hugetlb_page(str
+ int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
+ int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
+ int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
+-void zap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
+ void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
+ int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
+ int hugetlb_report_meminfo(char *);
+@@ -87,7 +86,6 @@ static inline unsigned long hugetlb_tota
+ #define follow_huge_addr(mm, addr, write)	ERR_PTR(-EINVAL)
+ #define copy_hugetlb_page_range(src, dst, vma)	({ BUG(); 0; })
+ #define hugetlb_prefault(mapping, vma)		({ BUG(); 0; })
+-#define zap_hugepage_range(vma, start, len)	BUG()
+ #define unmap_hugepage_range(vma, start, end)	BUG()
+ #define is_hugepage_mem_enough(size)		0
+ #define hugetlb_report_meminfo(buf)		0
+diff --git a/include/linux/i2c-algo-bit.h b/include/linux/i2c-algo-bit.h
+--- a/include/linux/i2c-algo-bit.h
++++ b/include/linux/i2c-algo-bit.h
+@@ -21,8 +21,6 @@
+ /* With some changes from Kyösti Mälkki <kmalkki at cc.hut.fi> and even
+    Frodo Looijaard <frodol at dds.nl> */
+ 
+-/* $Id: i2c-algo-bit.h,v 1.10 2003/01/21 08:08:16 kmalkki Exp $ */
+-
+ #ifndef _LINUX_I2C_ALGO_BIT_H
+ #define _LINUX_I2C_ALGO_BIT_H
+ 
+@@ -46,8 +44,6 @@ struct i2c_algo_bit_data {
+ 	int timeout;		/* in jiffies */
+ };
+ 
+-#define I2C_BIT_ADAP_MAX	16
+-
+ int i2c_bit_add_bus(struct i2c_adapter *);
+ int i2c_bit_del_bus(struct i2c_adapter *);
+ 
+diff --git a/include/linux/i2c-algo-pca.h b/include/linux/i2c-algo-pca.h
+--- a/include/linux/i2c-algo-pca.h
++++ b/include/linux/i2c-algo-pca.h
+@@ -9,8 +9,6 @@ struct i2c_algo_pca_data {
+ 	int  (*wait_for_interrupt)	(struct i2c_algo_pca_data *adap);
+ };
+ 
+-#define I2C_PCA_ADAP_MAX	16
+-
+ int i2c_pca_add_bus(struct i2c_adapter *);
+ int i2c_pca_del_bus(struct i2c_adapter *);
+ 
+diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h
+--- a/include/linux/i2c-algo-pcf.h
++++ b/include/linux/i2c-algo-pcf.h
+@@ -22,8 +22,6 @@
+ /* With some changes from Kyösti Mälkki <kmalkki at cc.hut.fi> and even
+    Frodo Looijaard <frodol at dds.nl> */
+ 
+-/* $Id: i2c-algo-pcf.h,v 1.8 2003/01/21 08:08:16 kmalkki Exp $ */
+-
+ #ifndef _LINUX_I2C_ALGO_PCF_H
+ #define _LINUX_I2C_ALGO_PCF_H
+ 
+@@ -41,8 +39,6 @@ struct i2c_algo_pcf_data {
+ 	int timeout;
+ };
+ 
+-#define I2C_PCF_ADAP_MAX	16
+-
+ int i2c_pcf_add_bus(struct i2c_adapter *);
+ int i2c_pcf_del_bus(struct i2c_adapter *);
+ 
+diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h
+--- a/include/linux/i2c-dev.h
++++ b/include/linux/i2c-dev.h
+@@ -19,8 +19,6 @@
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+ 
+-/* $Id: i2c-dev.h,v 1.13 2003/01/21 08:08:16 kmalkki Exp $ */
+-
+ #ifndef _LINUX_I2C_DEV_H
+ #define _LINUX_I2C_DEV_H
+ 
+diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
+--- a/include/linux/i2c-id.h
++++ b/include/linux/i2c-id.h
+@@ -164,10 +164,7 @@
+ 
+ /* --- Bit algorithm adapters 						*/
+ #define I2C_HW_B_LP		0x010000 /* Parallel port Philips style */
+-#define I2C_HW_B_LPC		0x010001 /* Parallel port control reg. */
+ #define I2C_HW_B_SER		0x010002 /* Serial line interface */
+-#define I2C_HW_B_ELV		0x010003 /* ELV Card */
+-#define I2C_HW_B_VELLE		0x010004 /* Vellemann K8000 */
+ #define I2C_HW_B_BT848		0x010005 /* BT848 video boards */
+ #define I2C_HW_B_WNV		0x010006 /* Winnov Videums */
+ #define I2C_HW_B_VIA		0x010007 /* Via vt82c586b */
+diff --git a/include/linux/i2c.h b/include/linux/i2c.h
+--- a/include/linux/i2c.h
++++ b/include/linux/i2c.h
+@@ -23,15 +23,15 @@
+ /* With some changes from Kyösti Mälkki <kmalkki at cc.hut.fi> and
+    Frodo Looijaard <frodol at dds.nl> */
+ 
+-/* $Id: i2c.h,v 1.68 2003/01/21 08:08:16 kmalkki Exp $ */
+-
+ #ifndef _LINUX_I2C_H
+ #define _LINUX_I2C_H
+ 
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/i2c-id.h>
++#include <linux/mod_devicetable.h>
+ #include <linux/device.h>	/* for struct device */
++#include <linux/sched.h>	/* for completion */
+ #include <asm/semaphore.h>
+ 
+ /* --- For i2c-isa ---------------------------------------------------- */
+@@ -94,10 +94,10 @@ extern s32 i2c_smbus_write_byte_data(str
+ extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
+ extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
+                                      u8 command, u16 value);
+-/* Returns the number of bytes transferred */
+ extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
+ 				      u8 command, u8 length,
+ 				      u8 *values);
++/* Returns the number of read bytes */
+ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
+ 					 u8 command, u8 *values);
+ 
+@@ -391,10 +391,6 @@ struct i2c_msg {
+ #define I2C_FUNC_10BIT_ADDR		0x00000002
+ #define I2C_FUNC_PROTOCOL_MANGLING	0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
+ #define I2C_FUNC_SMBUS_HWPEC_CALC	0x00000008 /* SMBus 2.0 */
+-#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC  0x00000800 /* SMBus 2.0 */ 
+-#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */ 
+-#define I2C_FUNC_SMBUS_PROC_CALL_PEC	0x00002000 /* SMBus 2.0 */
+-#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */
+ #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL	0x00008000 /* SMBus 2.0 */
+ #define I2C_FUNC_SMBUS_QUICK		0x00010000 
+ #define I2C_FUNC_SMBUS_READ_BYTE	0x00020000 
+@@ -410,8 +406,6 @@ struct i2c_msg {
+ #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK	0x08000000 /* w/ 1-byte reg. addr. */
+ #define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2	 0x10000000 /* I2C-like block xfer  */
+ #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */
+-#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC  0x40000000 /* SMBus 2.0 */
+-#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */
+ 
+ #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
+                              I2C_FUNC_SMBUS_WRITE_BYTE)
+@@ -425,17 +419,6 @@ struct i2c_msg {
+                                   I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
+ #define I2C_FUNC_SMBUS_I2C_BLOCK_2 (I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \
+                                     I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2)
+-#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC (I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \
+-                                       I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC)
+-#define I2C_FUNC_SMBUS_WORD_DATA_PEC  (I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \
+-                                       I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC)
+-
+-#define I2C_FUNC_SMBUS_READ_BYTE_PEC		I2C_FUNC_SMBUS_READ_BYTE_DATA
+-#define I2C_FUNC_SMBUS_WRITE_BYTE_PEC		I2C_FUNC_SMBUS_WRITE_BYTE_DATA
+-#define I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC	I2C_FUNC_SMBUS_READ_WORD_DATA
+-#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA_PEC	I2C_FUNC_SMBUS_WRITE_WORD_DATA
+-#define I2C_FUNC_SMBUS_BYTE_PEC			I2C_FUNC_SMBUS_BYTE_DATA
+-#define I2C_FUNC_SMBUS_BYTE_DATA_PEC		I2C_FUNC_SMBUS_WORD_DATA
+ 
+ #define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \
+                              I2C_FUNC_SMBUS_BYTE | \
+@@ -443,20 +426,17 @@ struct i2c_msg {
+                              I2C_FUNC_SMBUS_WORD_DATA | \
+                              I2C_FUNC_SMBUS_PROC_CALL | \
+                              I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
+-                             I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \
+                              I2C_FUNC_SMBUS_I2C_BLOCK)
+ 
+ /* 
+  * Data for SMBus Messages 
+  */
+ #define I2C_SMBUS_BLOCK_MAX	32	/* As specified in SMBus standard */	
+-#define I2C_SMBUS_I2C_BLOCK_MAX	32	/* Not specified but we use same structure */
+ union i2c_smbus_data {
+ 	__u8 byte;
+ 	__u16 word;
+-	__u8 block[I2C_SMBUS_BLOCK_MAX + 3]; /* block[0] is used for length */
+-                          /* one more for read length in block process call */
+-	                                            /* and one more for PEC */
++	__u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
++	                       /* and one more for user-space compatibility */
+ };
+ 
+ /* smbus_access read or write markers */
+@@ -473,10 +453,6 @@ union i2c_smbus_data {
+ #define I2C_SMBUS_BLOCK_DATA	    5
+ #define I2C_SMBUS_I2C_BLOCK_DATA    6
+ #define I2C_SMBUS_BLOCK_PROC_CALL   7		/* SMBus 2.0 */
+-#define I2C_SMBUS_BLOCK_DATA_PEC    8		/* SMBus 2.0 */
+-#define I2C_SMBUS_PROC_CALL_PEC     9		/* SMBus 2.0 */
+-#define I2C_SMBUS_BLOCK_PROC_CALL_PEC  10	/* SMBus 2.0 */
+-#define I2C_SMBUS_WORD_DATA_PEC	   11		/* SMBus 2.0 */
+ 
+ 
+ /* ----- commands for the ioctl like i2c_command call:
+@@ -506,11 +482,6 @@ union i2c_smbus_data {
+ 
+ #define I2C_SMBUS	0x0720	/* SMBus-level access */
+ 
+-/* ... algo-bit.c recognizes */
+-#define I2C_UDELAY	0x0705	/* set delay in microsecs between each	*/
+-				/* written byte (except address)	*/
+-#define I2C_MDELAY	0x0706	/* millisec delay between written bytes */
+-
+ /* ----- I2C-DEV: char device interface stuff ------------------------- */
+ 
+ #define I2C_MAJOR	89		/* Device major number		*/
+diff --git a/include/linux/i2o.h b/include/linux/i2o.h
+--- a/include/linux/i2o.h
++++ b/include/linux/i2o.h
+@@ -25,10 +25,14 @@
+ /* How many different OSM's are we allowing */
+ #define I2O_MAX_DRIVERS		8
+ 
+-#include <asm/io.h>
+-#include <asm/semaphore.h>	/* Needed for MUTEX init macros */
+ #include <linux/pci.h>
+ #include <linux/dma-mapping.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/workqueue.h>	/* work_struct */
++
++#include <asm/io.h>
++#include <asm/semaphore.h>	/* Needed for MUTEX init macros */
+ 
+ /* message queue empty */
+ #define I2O_QUEUE_EMPTY		0xffffffff
+@@ -66,8 +70,6 @@ struct i2o_device {
+ 	struct device device;
+ 
+ 	struct semaphore lock;	/* device lock */
+-
+-	struct class_device classdev;	/* i2o device class */
+ };
+ 
+ /*
+@@ -194,7 +196,7 @@ struct i2o_controller {
+ 	struct resource mem_resource;	/* Mem resource allocated to the IOP */
+ 
+ 	struct device device;
+-	struct class_device classdev;	/* I2O controller class */
++	struct class_device *classdev;	/* I2O controller class device */
+ 	struct i2o_device *exec;	/* Executive */
+ #if BITS_PER_LONG == 64
+ 	spinlock_t context_list_lock;	/* lock for context_list */
+@@ -492,7 +494,7 @@ static inline int i2o_dma_map_sg(struct 
+  *	Returns 0 on success or -ENOMEM on failure.
+  */
+ static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
+-				size_t len, unsigned int gfp_mask)
++				size_t len, gfp_t gfp_mask)
+ {
+ 	struct pci_dev *pdev = to_pci_dev(dev);
+ 	int dma_64 = 0;
+@@ -551,7 +553,7 @@ static inline void i2o_dma_free(struct d
+  *	Returns the 0 on success or negative error code on failure.
+  */
+ static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
+-				  size_t len, unsigned int gfp_mask)
++				  size_t len, gfp_t gfp_mask)
+ {
+ 	i2o_dma_free(dev, addr);
+ 
+diff --git a/include/linux/ibmtr.h b/include/linux/ibmtr.h
+--- a/include/linux/ibmtr.h
++++ b/include/linux/ibmtr.h
+@@ -7,8 +7,8 @@
+ /* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */
+ 
+ #define TR_RETRY_INTERVAL	(30*HZ)	/* 500 on PC = 5 s */
+-#define TR_RST_TIME		(HZ/20) /* 5 on PC = 50 ms */
+-#define TR_BUSY_INTERVAL	(HZ/5)	/* 5 on PC = 200 ms */
++#define TR_RST_TIME		(msecs_to_jiffies(50))	/* 5 on PC = 50 ms */
++#define TR_BUSY_INTERVAL	(msecs_to_jiffies(200))	/* 5 on PC = 200 ms */
+ #define TR_SPIN_INTERVAL	(3*HZ)	/* 3 seconds before init timeout */
+ 
+ #define TR_ISA 1
+diff --git a/include/linux/ide.h b/include/linux/ide.h
+--- a/include/linux/ide.h
++++ b/include/linux/ide.h
+@@ -218,7 +218,7 @@ typedef enum {	ide_unknown,	ide_generic,
+ 		ide_rz1000,	ide_trm290,
+ 		ide_cmd646,	ide_cy82c693,	ide_4drives,
+ 		ide_pmac,	ide_etrax100,	ide_acorn,
+-		ide_forced
++		ide_au1xxx, ide_forced
+ } hwif_chipset_t;
+ 
+ /*
+diff --git a/include/linux/idr.h b/include/linux/idr.h
+--- a/include/linux/idr.h
++++ b/include/linux/idr.h
+@@ -71,7 +71,7 @@ struct idr {
+  */
+ 
+ void *idr_find(struct idr *idp, int id);
+-int idr_pre_get(struct idr *idp, unsigned gfp_mask);
++int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
+ int idr_get_new(struct idr *idp, void *ptr, int *id);
+ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
+ void idr_remove(struct idr *idp, int id);
+diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
+--- a/include/linux/if_arp.h
++++ b/include/linux/if_arp.h
+@@ -84,6 +84,7 @@
+ #define ARPHRD_IEEE802_TR 800		/* Magic type ident for TR	*/
+ #define ARPHRD_IEEE80211 801		/* IEEE 802.11			*/
+ #define ARPHRD_IEEE80211_PRISM 802	/* IEEE 802.11 + Prism2 header  */
++#define ARPHRD_IEEE80211_RADIOTAP 803	/* IEEE 802.11 + radiotap header */
+ 
+ #define ARPHRD_VOID	  0xFFFF	/* Void type, nothing is known */
+ #define ARPHRD_NONE	  0xFFFE	/* zero header length */
+diff --git a/include/linux/input.h b/include/linux/input.h
+--- a/include/linux/input.h
++++ b/include/linux/input.h
+@@ -12,6 +12,7 @@
+ #ifdef __KERNEL__
+ #include <linux/time.h>
+ #include <linux/list.h>
++#include <linux/device.h>
+ #else
+ #include <sys/time.h>
+ #include <sys/ioctl.h>
+@@ -644,6 +645,7 @@ struct input_absinfo {
+ #define BUS_ADB			0x17
+ #define BUS_I2C			0x18
+ #define BUS_HOST		0x19
++#define BUS_GSC			0x1A
+ 
+ /*
+  * Values describing the status of an effect
+@@ -889,11 +891,15 @@ struct input_dev {
+ 	struct semaphore sem;	/* serializes open and close operations */
+ 	unsigned int users;
+ 
+-	struct device *dev;
++	struct class_device cdev;
++	struct device *dev;	/* will be removed soon */
++
++	int dynalloc;	/* temporarily */
+ 
+ 	struct list_head	h_list;
+ 	struct list_head	node;
+ };
++#define to_input_dev(d) container_of(d, struct input_dev, cdev)
+ 
+ /*
+  * Structure for hotplug & device<->driver matching.
+@@ -984,6 +990,23 @@ static inline void init_input_dev(struct
+ 	INIT_LIST_HEAD(&dev->node);
+ }
+ 
++struct input_dev *input_allocate_device(void);
++
++static inline void input_free_device(struct input_dev *dev)
++{
++	kfree(dev);
++}
++
++static inline struct input_dev *input_get_device(struct input_dev *dev)
++{
++	return to_input_dev(class_device_get(&dev->cdev));
++}
++
++static inline void input_put_device(struct input_dev *dev)
++{
++	class_device_put(&dev->cdev);
++}
++
+ void input_register_device(struct input_dev *);
+ void input_unregister_device(struct input_dev *);
+ 
+@@ -1052,7 +1075,7 @@ static inline void input_set_abs_params(
+ 	dev->absbit[LONG(axis)] |= BIT(axis);
+ }
+ 
+-extern struct class *input_class;
++extern struct class input_class;
+ 
+ #endif
+ #endif
+diff --git a/include/linux/jbd.h b/include/linux/jbd.h
+--- a/include/linux/jbd.h
++++ b/include/linux/jbd.h
+@@ -69,7 +69,7 @@ extern int journal_enable_debug;
+ #define jbd_debug(f, a...)	/**/
+ #endif
+ 
+-extern void * __jbd_kmalloc (const char *where, size_t size, int flags, int retry);
++extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
+ #define jbd_kmalloc(size, flags) \
+ 	__jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
+ #define jbd_rep_kmalloc(size, flags) \
+@@ -890,7 +890,7 @@ extern int	 journal_forget (handle_t *, 
+ extern void	 journal_sync_buffer (struct buffer_head *);
+ extern int	 journal_invalidatepage(journal_t *,
+ 				struct page *, unsigned long);
+-extern int	 journal_try_to_free_buffers(journal_t *, struct page *, int);
++extern int	 journal_try_to_free_buffers(journal_t *, struct page *, gfp_t);
+ extern int	 journal_stop(handle_t *);
+ extern int	 journal_flush (journal_t *);
+ extern void	 journal_lock_updates (journal_t *);
+diff --git a/include/linux/kernel.h b/include/linux/kernel.h
+--- a/include/linux/kernel.h
++++ b/include/linux/kernel.h
+@@ -307,7 +307,7 @@ struct sysinfo {
+ 	char _f[20-2*sizeof(long)-sizeof(int)];	/* Padding: libc5 uses this.. */
+ };
+ 
+-/* Force a compilation error if condition is false */
++/* Force a compilation error if condition is true */
+ #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+ 
+ #ifdef CONFIG_SYSCTL
+diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
+--- a/include/linux/key-ui.h
++++ b/include/linux/key-ui.h
+@@ -24,7 +24,8 @@ extern spinlock_t key_serial_lock;
+ #define	KEY_WRITE	0x04	/* require permission to update / modify */
+ #define	KEY_SEARCH	0x08	/* require permission to search (keyring) or find (key) */
+ #define	KEY_LINK	0x10	/* require permission to link */
+-#define	KEY_ALL		0x1f	/* all the above permissions */
++#define	KEY_SETATTR	0x20	/* require permission to change attributes */
++#define	KEY_ALL		0x3f	/* all the above permissions */
+ 
+ /*
+  * the keyring payload contains a list of the keys to which the keyring is
+diff --git a/include/linux/key.h b/include/linux/key.h
+--- a/include/linux/key.h
++++ b/include/linux/key.h
+@@ -40,28 +40,32 @@ struct key;
+ #define KEY_POS_WRITE	0x04000000	/* possessor can update key payload / add link to keyring */
+ #define KEY_POS_SEARCH	0x08000000	/* possessor can find a key in search / search a keyring */
+ #define KEY_POS_LINK	0x10000000	/* possessor can create a link to a key/keyring */
+-#define KEY_POS_ALL	0x1f000000
++#define KEY_POS_SETATTR	0x20000000	/* possessor can set key attributes */
++#define KEY_POS_ALL	0x3f000000
+ 
+ #define KEY_USR_VIEW	0x00010000	/* user permissions... */
+ #define KEY_USR_READ	0x00020000
+ #define KEY_USR_WRITE	0x00040000
+ #define KEY_USR_SEARCH	0x00080000
+ #define KEY_USR_LINK	0x00100000
+-#define KEY_USR_ALL	0x001f0000
++#define KEY_USR_SETATTR	0x00200000
++#define KEY_USR_ALL	0x003f0000
+ 
+ #define KEY_GRP_VIEW	0x00000100	/* group permissions... */
+ #define KEY_GRP_READ	0x00000200
+ #define KEY_GRP_WRITE	0x00000400
+ #define KEY_GRP_SEARCH	0x00000800
+ #define KEY_GRP_LINK	0x00001000
+-#define KEY_GRP_ALL	0x00001f00
++#define KEY_GRP_SETATTR	0x00002000
++#define KEY_GRP_ALL	0x00003f00
+ 
+ #define KEY_OTH_VIEW	0x00000001	/* third party permissions... */
+ #define KEY_OTH_READ	0x00000002
+ #define KEY_OTH_WRITE	0x00000004
+ #define KEY_OTH_SEARCH	0x00000008
+ #define KEY_OTH_LINK	0x00000010
+-#define KEY_OTH_ALL	0x0000001f
++#define KEY_OTH_SETATTR	0x00000020
++#define KEY_OTH_ALL	0x0000003f
+ 
+ struct seq_file;
+ struct user_struct;
+@@ -119,6 +123,7 @@ struct key {
+ 	struct key_type		*type;		/* type of key */
+ 	struct rw_semaphore	sem;		/* change vs change sem */
+ 	struct key_user		*user;		/* owner of this key */
++	void			*security;	/* security data for this key */
+ 	time_t			expiry;		/* time at which key expires (or 0) */
+ 	uid_t			uid;
+ 	gid_t			gid;
+diff --git a/include/linux/kobj_map.h b/include/linux/kobj_map.h
+--- a/include/linux/kobj_map.h
++++ b/include/linux/kobj_map.h
+@@ -1,5 +1,7 @@
+ #ifdef __KERNEL__
+ 
++#include <asm/semaphore.h>
++
+ typedef struct kobject *kobj_probe_t(dev_t, int *, void *);
+ struct kobj_map;
+ 
+diff --git a/include/linux/kobject.h b/include/linux/kobject.h
+--- a/include/linux/kobject.h
++++ b/include/linux/kobject.h
+@@ -65,7 +65,7 @@ extern void kobject_unregister(struct ko
+ extern struct kobject * kobject_get(struct kobject *);
+ extern void kobject_put(struct kobject *);
+ 
+-extern char * kobject_get_path(struct kobject *, int);
++extern char * kobject_get_path(struct kobject *, gfp_t);
+ 
+ struct kobj_type {
+ 	void (*release)(struct kobject *);
+diff --git a/include/linux/kthread.h b/include/linux/kthread.h
+--- a/include/linux/kthread.h
++++ b/include/linux/kthread.h
+@@ -70,6 +70,18 @@ void kthread_bind(struct task_struct *k,
+ int kthread_stop(struct task_struct *k);
+ 
+ /**
++ * kthread_stop_sem: stop a thread created by kthread_create().
++ * @k: thread created by kthread_create().
++ * @s: semaphore that @k waits on while idle.
++ *
++ * Does essentially the same thing as kthread_stop() above, but wakes
++ * @k by calling up(@s).
++ *
++ * Returns the result of threadfn(), or -EINTR if wake_up_process()
++ * was never called. */
++int kthread_stop_sem(struct task_struct *k, struct semaphore *s);
++
++/**
+  * kthread_should_stop: should this kthread return now?
+  *
+  * When someone calls kthread_stop on your kthread, it will be woken
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -91,12 +91,13 @@ enum {
+ 	ATA_SHT_EMULATED	= 1,
+ 	ATA_SHT_CMD_PER_LUN	= 1,
+ 	ATA_SHT_THIS_ID		= -1,
+-	ATA_SHT_USE_CLUSTERING	= 0,
++	ATA_SHT_USE_CLUSTERING	= 1,
+ 
+ 	/* struct ata_device stuff */
+ 	ATA_DFLAG_LBA48		= (1 << 0), /* device supports LBA48 */
+ 	ATA_DFLAG_PIO		= (1 << 1), /* device currently in PIO mode */
+ 	ATA_DFLAG_LOCK_SECTORS	= (1 << 2), /* don't adjust max_sectors */
++	ATA_DFLAG_LBA		= (1 << 3), /* device supports LBA */
+ 
+ 	ATA_DEV_UNKNOWN		= 0,	/* unknown device */
+ 	ATA_DEV_ATA		= 1,	/* ATA device */
+@@ -154,17 +155,28 @@ enum {
+ 	ATA_SHIFT_UDMA		= 0,
+ 	ATA_SHIFT_MWDMA		= 8,
+ 	ATA_SHIFT_PIO		= 11,
+-};
+-
+-enum pio_task_states {
+-	PIO_ST_UNKNOWN,
+-	PIO_ST_IDLE,
+-	PIO_ST_POLL,
+-	PIO_ST_TMOUT,
+-	PIO_ST,
+-	PIO_ST_LAST,
+-	PIO_ST_LAST_POLL,
+-	PIO_ST_ERR,
++	
++	/* Masks for port functions */
++	ATA_PORT_PRIMARY	= (1 << 0),
++	ATA_PORT_SECONDARY	= (1 << 1),
++};
++
++enum hsm_task_states {
++	HSM_ST_UNKNOWN,
++	HSM_ST_IDLE,
++	HSM_ST_POLL,
++	HSM_ST_TMOUT,
++	HSM_ST,
++	HSM_ST_LAST,
++	HSM_ST_LAST_POLL,
++	HSM_ST_ERR,
++};
++
++enum ata_completion_errors {
++	AC_ERR_OTHER		= (1 << 0),
++	AC_ERR_DEV		= (1 << 1),
++	AC_ERR_ATA_BUS		= (1 << 2),
++	AC_ERR_HOST_BUS		= (1 << 3),
+ };
+ 
+ /* forward declarations */
+@@ -174,7 +186,7 @@ struct ata_port;
+ struct ata_queued_cmd;
+ 
+ /* typedefs */
+-typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat);
++typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask);
+ 
+ struct ata_ioports {
+ 	unsigned long		cmd_addr;
+@@ -197,7 +209,7 @@ struct ata_ioports {
+ struct ata_probe_ent {
+ 	struct list_head	node;
+ 	struct device 		*dev;
+-	struct ata_port_operations	*port_ops;
++	const struct ata_port_operations *port_ops;
+ 	Scsi_Host_Template	*sht;
+ 	struct ata_ioports	port[ATA_MAX_PORTS];
+ 	unsigned int		n_ports;
+@@ -220,7 +232,7 @@ struct ata_host_set {
+ 	void __iomem		*mmio_base;
+ 	unsigned int		n_ports;
+ 	void			*private_data;
+-	struct ata_port_operations *ops;
++	const struct ata_port_operations *ops;
+ 	struct ata_port *	ports[0];
+ };
+ 
+@@ -278,15 +290,18 @@ struct ata_device {
+ 	u8			xfer_mode;
+ 	unsigned int		xfer_shift;	/* ATA_SHIFT_xxx */
+ 
+-	/* cache info about current transfer mode */
+-	u8			xfer_protocol;	/* taskfile xfer protocol */
+-	u8			read_cmd;	/* opcode to use on read */
+-	u8			write_cmd;	/* opcode to use on write */
++	unsigned int		multi_count;	/* sectors count for
++						   READ/WRITE MULTIPLE */
++
++	/* for CHS addressing */
++	u16			cylinders;	/* Number of cylinders */
++	u16			heads;		/* Number of heads */
++	u16			sectors;	/* Number of sectors per track */
+ };
+ 
+ struct ata_port {
+ 	struct Scsi_Host	*host;	/* our co-allocated scsi host */
+-	struct ata_port_operations	*ops;
++	const struct ata_port_operations *ops;
+ 	unsigned long		flags;	/* ATA_FLAG_xxx */
+ 	unsigned int		id;	/* unique id req'd by scsi midlyr */
+ 	unsigned int		port_no; /* unique port #; from zero */
+@@ -319,7 +334,7 @@ struct ata_port {
+ 	struct work_struct	packet_task;
+ 
+ 	struct work_struct	pio_task;
+-	unsigned int		pio_task_state;
++	unsigned int		hsm_task_state;
+ 	unsigned long		pio_task_timeout;
+ 
+ 	void			*private_data;
+@@ -333,13 +348,12 @@ struct ata_port_operations {
+ 	void (*set_piomode) (struct ata_port *, struct ata_device *);
+ 	void (*set_dmamode) (struct ata_port *, struct ata_device *);
+ 
+-	void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
++	void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf);
+ 	void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
+ 
+-	void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
++	void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf);
+ 	u8   (*check_status)(struct ata_port *ap);
+ 	u8   (*check_altstatus)(struct ata_port *ap);
+-	u8   (*check_err)(struct ata_port *ap);
+ 	void (*dev_select)(struct ata_port *ap, unsigned int device);
+ 
+ 	void (*phy_reset) (struct ata_port *ap);
+@@ -377,9 +391,22 @@ struct ata_port_info {
+ 	unsigned long		pio_mask;
+ 	unsigned long		mwdma_mask;
+ 	unsigned long		udma_mask;
+-	struct ata_port_operations	*port_ops;
++	const struct ata_port_operations *port_ops;
++};
++
++struct ata_timing {
++	unsigned short mode;		/* ATA mode */
++	unsigned short setup;		/* t1 */
++	unsigned short act8b;		/* t2 for 8-bit I/O */
++	unsigned short rec8b;		/* t2i for 8-bit I/O */
++	unsigned short cyc8b;		/* t0 for 8-bit I/O */
++	unsigned short active;		/* t2 or tD */
++	unsigned short recover;		/* t2i or tK */
++	unsigned short cycle;		/* t0 */
++	unsigned short udma;		/* t2CYCTYP/2 */
+ };
+ 
++#define FIT(v,vmin,vmax)	max_t(short,min_t(short,v,vmax),vmin)
+ 
+ extern void ata_port_probe(struct ata_port *);
+ extern void __sata_phy_reset(struct ata_port *ap);
+@@ -392,7 +419,7 @@ extern int ata_pci_init_one (struct pci_
+ 			     unsigned int n_ports);
+ extern void ata_pci_remove_one (struct pci_dev *pdev);
+ #endif /* CONFIG_PCI */
+-extern int ata_device_add(struct ata_probe_ent *ent);
++extern int ata_device_add(const struct ata_probe_ent *ent);
+ extern void ata_host_set_remove(struct ata_host_set *host_set);
+ extern int ata_scsi_detect(Scsi_Host_Template *sht);
+ extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
+@@ -400,19 +427,20 @@ extern int ata_scsi_queuecmd(struct scsi
+ extern int ata_scsi_error(struct Scsi_Host *host);
+ extern int ata_scsi_release(struct Scsi_Host *host);
+ extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
++extern int ata_ratelimit(void);
++
+ /*
+  * Default driver ops implementations
+  */
+-extern void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf);
++extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
+ extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+-extern void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp);
+-extern void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf);
++extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp);
++extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf);
+ extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
+ extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
+ extern u8 ata_check_status(struct ata_port *ap);
+ extern u8 ata_altstatus(struct ata_port *ap);
+-extern u8 ata_chk_err(struct ata_port *ap);
+-extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf);
++extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
+ extern int ata_port_start (struct ata_port *ap);
+ extern void ata_port_stop (struct ata_port *ap);
+ extern void ata_host_stop (struct ata_host_set *host_set);
+@@ -423,8 +451,8 @@ extern void ata_sg_init_one(struct ata_q
+ 		unsigned int buflen);
+ extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
+ 		 unsigned int n_elem);
+-extern unsigned int ata_dev_classify(struct ata_taskfile *tf);
+-extern void ata_dev_id_string(u16 *id, unsigned char *s,
++extern unsigned int ata_dev_classify(const struct ata_taskfile *tf);
++extern void ata_dev_id_string(const u16 *id, unsigned char *s,
+ 			      unsigned int ofs, unsigned int len);
+ extern void ata_dev_config(struct ata_port *ap, unsigned int i);
+ extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
+@@ -432,7 +460,7 @@ extern void ata_bmdma_start (struct ata_
+ extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
+ extern u8   ata_bmdma_status(struct ata_port *ap);
+ extern void ata_bmdma_irq_clear(struct ata_port *ap);
+-extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
++extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask);
+ extern void ata_eng_timeout(struct ata_port *ap);
+ extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
+ 			      void (*done)(struct scsi_cmnd *));
+@@ -441,6 +469,32 @@ extern int ata_std_bios_param(struct scs
+ 			      sector_t capacity, int geom[]);
+ extern int ata_scsi_slave_config(struct scsi_device *sdev);
+ 
++/*
++ * Timing helpers
++ */
++extern int ata_timing_compute(struct ata_device *, unsigned short,
++			      struct ata_timing *, int, int);
++extern void ata_timing_merge(const struct ata_timing *,
++			     const struct ata_timing *, struct ata_timing *,
++			     unsigned int);
++
++enum {
++	ATA_TIMING_SETUP	= (1 << 0),
++	ATA_TIMING_ACT8B	= (1 << 1),
++	ATA_TIMING_REC8B	= (1 << 2),
++	ATA_TIMING_CYC8B	= (1 << 3),
++	ATA_TIMING_8BIT		= ATA_TIMING_ACT8B | ATA_TIMING_REC8B |
++				  ATA_TIMING_CYC8B,
++	ATA_TIMING_ACTIVE	= (1 << 4),
++	ATA_TIMING_RECOVER	= (1 << 5),
++	ATA_TIMING_CYCLE	= (1 << 6),
++	ATA_TIMING_UDMA		= (1 << 7),
++	ATA_TIMING_ALL		= ATA_TIMING_SETUP | ATA_TIMING_ACT8B |
++				  ATA_TIMING_REC8B | ATA_TIMING_CYC8B |
++				  ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER |
++				  ATA_TIMING_CYCLE | ATA_TIMING_UDMA,
++};
++
+ 
+ #ifdef CONFIG_PCI
+ struct pci_bits {
+@@ -452,8 +506,8 @@ struct pci_bits {
+ 
+ extern void ata_pci_host_stop (struct ata_host_set *host_set);
+ extern struct ata_probe_ent *
+-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port);
+-extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
++ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask);
++extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
+ 
+ #endif /* CONFIG_PCI */
+ 
+@@ -463,7 +517,7 @@ static inline unsigned int ata_tag_valid
+ 	return (tag < ATA_MAX_QUEUE) ? 1 : 0;
+ }
+ 
+-static inline unsigned int ata_dev_present(struct ata_device *dev)
++static inline unsigned int ata_dev_present(const struct ata_device *dev)
+ {
+ 	return ((dev->class == ATA_DEV_ATA) ||
+ 		(dev->class == ATA_DEV_ATAPI));
+@@ -662,11 +716,28 @@ static inline unsigned int sata_dev_pres
+ 	return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
+ }
+ 
+-static inline int ata_try_flush_cache(struct ata_device *dev)
++static inline int ata_try_flush_cache(const struct ata_device *dev)
+ {
+ 	return ata_id_wcache_enabled(dev->id) ||
+ 	       ata_id_has_flush(dev->id) ||
+ 	       ata_id_has_flush_ext(dev->id);
+ }
+ 
++static inline unsigned int ac_err_mask(u8 status)
++{
++	if (status & ATA_BUSY)
++		return AC_ERR_ATA_BUS;
++	if (status & (ATA_ERR | ATA_DF))
++		return AC_ERR_DEV;
++	return 0;
++}
++
++static inline unsigned int __ac_err_mask(u8 status)
++{
++	unsigned int mask = ac_err_mask(status);
++	if (mask == 0)
++		return AC_ERR_OTHER;
++	return mask;
++}
++
+ #endif /* __LINUX_LIBATA_H__ */
+diff --git a/include/linux/loop.h b/include/linux/loop.h
+--- a/include/linux/loop.h
++++ b/include/linux/loop.h
+@@ -52,7 +52,7 @@ struct loop_device {
+ 	unsigned	lo_blocksize;
+ 	void		*key_data; 
+ 
+-	int		old_gfp_mask;
++	gfp_t		old_gfp_mask;
+ 
+ 	spinlock_t		lo_lock;
+ 	struct bio 		*lo_bio;
+diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h
+--- a/include/linux/mbcache.h
++++ b/include/linux/mbcache.h
+@@ -22,7 +22,7 @@ struct mb_cache_entry {
+ };
+ 
+ struct mb_cache_op {
+-	int (*free)(struct mb_cache_entry *, int);
++	int (*free)(struct mb_cache_entry *, gfp_t);
+ };
+ 
+ /* Functions on caches */
+diff --git a/include/linux/memory.h b/include/linux/memory.h
+new file mode 100644
+--- /dev/null
++++ b/include/linux/memory.h
+@@ -0,0 +1,94 @@
++/*
++ * include/linux/memory.h - generic memory definition
++ *
++ * This is mainly for topological representation. We define the
++ * basic "struct memory_block" here, which can be embedded in per-arch
++ * definitions or NUMA information.
++ *
++ * Basic handling of the devices is done in drivers/base/memory.c
++ * and system devices are handled in drivers/base/sys.c.
++ *
++ * Memory block are exported via sysfs in the class/memory/devices/
++ * directory.
++ *
++ */
++#ifndef _LINUX_MEMORY_H_
++#define _LINUX_MEMORY_H_
++
++#include <linux/sysdev.h>
++#include <linux/node.h>
++#include <linux/compiler.h>
++
++#include <asm/semaphore.h>
++
++struct memory_block {
++	unsigned long phys_index;
++	unsigned long state;
++	/*
++	 * This serializes all state change requests.  It isn't
++	 * held during creation because the control files are
++	 * created long after the critical areas during
++	 * initialization.
++	 */
++	struct semaphore state_sem;
++	int phys_device;		/* to which fru does this belong? */
++	void *hw;			/* optional pointer to fw/hw data */
++	int (*phys_callback)(struct memory_block *);
++	struct sys_device sysdev;
++};
++
++/* These states are exposed to userspace as text strings in sysfs */
++#define	MEM_ONLINE		(1<<0) /* exposed to userspace */
++#define	MEM_GOING_OFFLINE	(1<<1) /* exposed to userspace */
++#define	MEM_OFFLINE		(1<<2) /* exposed to userspace */
++
++/*
++ * All of these states are currently kernel-internal for notifying
++ * kernel components and architectures.
++ *
++ * For MEM_MAPPING_INVALID, all notifier chains with priority >0
++ * are called before pfn_to_page() becomes invalid.  The priority=0
++ * entry is reserved for the function that actually makes
++ * pfn_to_page() stop working.  Any notifiers that want to be called
++ * after that should have priority <0.
++ */
++#define	MEM_MAPPING_INVALID	(1<<3)
++
++#ifndef CONFIG_MEMORY_HOTPLUG
++static inline int memory_dev_init(void)
++{
++	return 0;
++}
++static inline int register_memory_notifier(struct notifier_block *nb)
++{
++	return 0;
++}
++static inline void unregister_memory_notifier(struct notifier_block *nb)
++{
++}
++#else
++extern int register_memory(struct memory_block *, struct mem_section *section, struct node *);
++extern int register_new_memory(struct mem_section *);
++extern int unregister_memory_section(struct mem_section *);
++extern int memory_dev_init(void);
++extern int register_memory_notifier(struct notifier_block *nb);
++extern void unregister_memory_notifier(struct notifier_block *nb);
++
++#define CONFIG_MEM_BLOCK_SIZE	(PAGES_PER_SECTION<<PAGE_SHIFT)
++
++extern int invalidate_phys_mapping(unsigned long, unsigned long);
++struct notifier_block;
++
++extern int register_memory_notifier(struct notifier_block *nb);
++extern void unregister_memory_notifier(struct notifier_block *nb);
++
++extern struct sysdev_class memory_sysdev_class;
++#endif /* CONFIG_MEMORY_HOTPLUG */
++
++#define hotplug_memory_notifier(fn, pri) {			\
++	static struct notifier_block fn##_mem_nb =		\
++		{ .notifier_call = fn, .priority = pri };	\
++	register_memory_notifier(&fn##_mem_nb);			\
++}
++
++#endif /* _LINUX_MEMORY_H_ */
+diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
+new file mode 100644
+--- /dev/null
++++ b/include/linux/memory_hotplug.h
+@@ -0,0 +1,104 @@
++#ifndef __LINUX_MEMORY_HOTPLUG_H
++#define __LINUX_MEMORY_HOTPLUG_H
++
++#include <linux/mmzone.h>
++#include <linux/spinlock.h>
++#include <linux/mmzone.h>
++#include <linux/notifier.h>
++
++#ifdef CONFIG_MEMORY_HOTPLUG
++/*
++ * pgdat resizing functions
++ */
++static inline
++void pgdat_resize_lock(struct pglist_data *pgdat, unsigned long *flags)
++{
++	spin_lock_irqsave(&pgdat->node_size_lock, *flags);
++}
++static inline
++void pgdat_resize_unlock(struct pglist_data *pgdat, unsigned long *flags)
++{
++	spin_unlock_irqrestore(&pgdat->node_size_lock, *flags);
++}
++static inline
++void pgdat_resize_init(struct pglist_data *pgdat)
++{
++	spin_lock_init(&pgdat->node_size_lock);
++}
++/*
++ * Zone resizing functions
++ */
++static inline unsigned zone_span_seqbegin(struct zone *zone)
++{
++	return read_seqbegin(&zone->span_seqlock);
++}
++static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
++{
++	return read_seqretry(&zone->span_seqlock, iv);
++}
++static inline void zone_span_writelock(struct zone *zone)
++{
++	write_seqlock(&zone->span_seqlock);
++}
++static inline void zone_span_writeunlock(struct zone *zone)
++{
++	write_sequnlock(&zone->span_seqlock);
++}
++static inline void zone_seqlock_init(struct zone *zone)
++{
++	seqlock_init(&zone->span_seqlock);
++}
++extern int zone_grow_free_lists(struct zone *zone, unsigned long new_nr_pages);
++extern int zone_grow_waitqueues(struct zone *zone, unsigned long nr_pages);
++extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
++/* need some defines for these for archs that don't support it */
++extern void online_page(struct page *page);
++/* VM interface that may be used by firmware interface */
++extern int add_memory(u64 start, u64 size);
++extern int remove_memory(u64 start, u64 size);
++extern int online_pages(unsigned long, unsigned long);
++
++/* reasonably generic interface to expand the physical pages in a zone  */
++extern int __add_pages(struct zone *zone, unsigned long start_pfn,
++	unsigned long nr_pages);
++#else /* ! CONFIG_MEMORY_HOTPLUG */
++/*
++ * Stub functions for when hotplug is off
++ */
++static inline void pgdat_resize_lock(struct pglist_data *p, unsigned long *f) {}
++static inline void pgdat_resize_unlock(struct pglist_data *p, unsigned long *f) {}
++static inline void pgdat_resize_init(struct pglist_data *pgdat) {}
++
++static inline unsigned zone_span_seqbegin(struct zone *zone)
++{
++	return 0;
++}
++static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
++{
++	return 0;
++}
++static inline void zone_span_writelock(struct zone *zone) {}
++static inline void zone_span_writeunlock(struct zone *zone) {}
++static inline void zone_seqlock_init(struct zone *zone) {}
++
++static inline int mhp_notimplemented(const char *func)
++{
++	printk(KERN_WARNING "%s() called, with CONFIG_MEMORY_HOTPLUG disabled\n", func);
++	dump_stack();
++	return -ENOSYS;
++}
++
++static inline int __add_pages(struct zone *zone, unsigned long start_pfn,
++	unsigned long nr_pages)
++{
++	return mhp_notimplemented(__FUNCTION__);
++}
++#endif /* ! CONFIG_MEMORY_HOTPLUG */
++static inline int __remove_pages(struct zone *zone, unsigned long start_pfn,
++	unsigned long nr_pages)
++{
++	printk(KERN_WARNING "%s() called, not yet supported\n", __FUNCTION__);
++	dump_stack();
++	return -ENOSYS;
++}
++#endif /* __LINUX_MEMORY_HOTPLUG_H */
+diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
+--- a/include/linux/mempolicy.h
++++ b/include/linux/mempolicy.h
+@@ -27,10 +27,10 @@
+ 
+ #include <linux/config.h>
+ #include <linux/mmzone.h>
+-#include <linux/bitmap.h>
+ #include <linux/slab.h>
+ #include <linux/rbtree.h>
+ #include <linux/spinlock.h>
++#include <linux/nodemask.h>
+ 
+ struct vm_area_struct;
+ 
+@@ -47,8 +47,7 @@ struct vm_area_struct;
+  * Locking policy for interlave:
+  * In process context there is no locking because only the process accesses
+  * its own state. All vma manipulation is somewhat protected by a down_read on
+- * mmap_sem. For allocating in the interleave policy the page_table_lock
+- * must be also aquired to protect il_next.
++ * mmap_sem.
+  *
+  * Freeing policy:
+  * When policy is MPOL_BIND v.zonelist is kmalloc'ed and must be kfree'd.
+@@ -63,7 +62,7 @@ struct mempolicy {
+ 	union {
+ 		struct zonelist  *zonelist;	/* bind */
+ 		short 		 preferred_node; /* preferred */
+-		DECLARE_BITMAP(nodes, MAX_NUMNODES); /* interleave */
++		nodemask_t	 nodes;		/* interleave */
+ 		/* undefined for default */
+ 	} v;
+ };
+@@ -155,6 +154,7 @@ struct mempolicy *get_vma_policy(struct 
+ 
+ extern void numa_default_policy(void);
+ extern void numa_policy_init(void);
++extern void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new);
+ extern struct mempolicy default_policy;
+ 
+ #else
+@@ -227,6 +227,11 @@ static inline void numa_default_policy(v
+ {
+ }
+ 
++static inline void numa_policy_rebind(const nodemask_t *old,
++					const nodemask_t *new)
++{
++}
++
+ #endif /* CONFIG_NUMA */
+ #endif /* __KERNEL__ */
+ 
+diff --git a/include/linux/mii.h b/include/linux/mii.h
+--- a/include/linux/mii.h
++++ b/include/linux/mii.h
+@@ -158,6 +158,7 @@ extern int mii_link_ok (struct mii_if_in
+ extern int mii_nway_restart (struct mii_if_info *mii);
+ extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
+ extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
++extern int mii_check_gmii_support(struct mii_if_info *mii);
+ extern void mii_check_link (struct mii_if_info *mii);
+ extern unsigned int mii_check_media (struct mii_if_info *mii,
+ 				     unsigned int ok_to_print,
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -157,7 +157,7 @@ extern unsigned int kobjsize(const void 
+ 
+ #define VM_DONTCOPY	0x00020000      /* Do not copy this vma on fork */
+ #define VM_DONTEXPAND	0x00040000	/* Cannot expand with mremap() */
+-#define VM_RESERVED	0x00080000	/* Don't unmap it from swap_out */
++#define VM_RESERVED	0x00080000	/* Pages managed in a special way */
+ #define VM_ACCOUNT	0x00100000	/* Is a VM accounted object */
+ #define VM_HUGETLB	0x00400000	/* Huge TLB Page VM */
+ #define VM_NONLINEAR	0x00800000	/* Is non-linear (remap_file_pages) */
+@@ -226,13 +226,18 @@ struct page {
+ 					 * to show when page is mapped
+ 					 * & limit reverse map searches.
+ 					 */
+-	unsigned long private;		/* Mapping-private opaque data:
++	union {
++		unsigned long private;	/* Mapping-private opaque data:
+ 					 * usually used for buffer_heads
+ 					 * if PagePrivate set; used for
+ 					 * swp_entry_t if PageSwapCache
+ 					 * When page is free, this indicates
+ 					 * order in the buddy system.
+ 					 */
++#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
++		spinlock_t ptl;
++#endif
++	} u;
+ 	struct address_space *mapping;	/* If low bit clear, points to
+ 					 * inode address_space, or NULL.
+ 					 * If page mapped as anonymous
+@@ -260,6 +265,9 @@ struct page {
+ #endif /* WANT_PAGE_VIRTUAL */
+ };
+ 
++#define page_private(page)		((page)->u.private)
++#define set_page_private(page, v)	((page)->u.private = (v))
++
+ /*
+  * FIXME: take this include out, include page-flags.h in
+  * files which need it (119 of them)
+@@ -311,17 +319,17 @@ extern void FASTCALL(__page_cache_releas
+ 
+ #ifdef CONFIG_HUGETLB_PAGE
+ 
+-static inline int page_count(struct page *p)
++static inline int page_count(struct page *page)
+ {
+-	if (PageCompound(p))
+-		p = (struct page *)p->private;
+-	return atomic_read(&(p)->_count) + 1;
++	if (PageCompound(page))
++		page = (struct page *)page_private(page);
++	return atomic_read(&page->_count) + 1;
+ }
+ 
+ static inline void get_page(struct page *page)
+ {
+ 	if (unlikely(PageCompound(page)))
+-		page = (struct page *)page->private;
++		page = (struct page *)page_private(page);
+ 	atomic_inc(&page->_count);
+ }
+ 
+@@ -338,7 +346,7 @@ static inline void get_page(struct page 
+ 
+ static inline void put_page(struct page *page)
+ {
+-	if (!PageReserved(page) && put_page_testzero(page))
++	if (put_page_testzero(page))
+ 		__page_cache_release(page);
+ }
+ 
+@@ -587,7 +595,7 @@ static inline int PageAnon(struct page *
+ static inline pgoff_t page_index(struct page *page)
+ {
+ 	if (unlikely(PageSwapCache(page)))
+-		return page->private;
++		return page_private(page);
+ 	return page->index;
+ }
+ 
+@@ -682,7 +690,7 @@ struct zap_details {
+ 
+ unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address,
+ 		unsigned long size, struct zap_details *);
+-unsigned long unmap_vmas(struct mmu_gather **tlb, struct mm_struct *mm,
++unsigned long unmap_vmas(struct mmu_gather **tlb,
+ 		struct vm_area_struct *start_vma, unsigned long start_addr,
+ 		unsigned long end_addr, unsigned long *nr_accounted,
+ 		struct zap_details *);
+@@ -704,10 +712,6 @@ static inline void unmap_shared_mapping_
+ }
+ 
+ extern int vmtruncate(struct inode * inode, loff_t offset);
+-extern pud_t *FASTCALL(__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address));
+-extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address));
+-extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
+-extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
+ extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
+ extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
+ extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
+@@ -723,6 +727,7 @@ void install_arg_page(struct vm_area_str
+ 
+ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
+ 		int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
++void print_bad_pte(struct vm_area_struct *, pte_t, unsigned long);
+ 
+ int __set_page_dirty_buffers(struct page *page);
+ int __set_page_dirty_nobuffers(struct page *page);
+@@ -747,7 +752,7 @@ extern unsigned long do_mremap(unsigned 
+  * The callback will be passed nr_to_scan == 0 when the VM is querying the
+  * cache size, so a fastpath for that case is appropriate.
+  */
+-typedef int (*shrinker_t)(int nr_to_scan, unsigned int gfp_mask);
++typedef int (*shrinker_t)(int nr_to_scan, gfp_t gfp_mask);
+ 
+ /*
+  * Add an aging callback.  The int is the number of 'seeks' it takes
+@@ -759,38 +764,83 @@ struct shrinker;
+ extern struct shrinker *set_shrinker(int, shrinker_t);
+ extern void remove_shrinker(struct shrinker *shrinker);
+ 
+-/*
+- * On a two-level or three-level page table, this ends up being trivial. Thus
+- * the inlining and the symmetry break with pte_alloc_map() that does all
+- * of this out-of-line.
+- */
++int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address);
++int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address);
++int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address);
++int __pte_alloc_kernel(pmd_t *pmd, unsigned long address);
++
+ /*
+  * The following ifdef needed to get the 4level-fixup.h header to work.
+  * Remove it when 4level-fixup.h has been removed.
+  */
+-#ifdef CONFIG_MMU
+-#ifndef __ARCH_HAS_4LEVEL_HACK 
++#if defined(CONFIG_MMU) && !defined(__ARCH_HAS_4LEVEL_HACK)
+ static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+ {
+-	if (pgd_none(*pgd))
+-		return __pud_alloc(mm, pgd, address);
+-	return pud_offset(pgd, address);
++	return (unlikely(pgd_none(*pgd)) && __pud_alloc(mm, pgd, address))?
++		NULL: pud_offset(pgd, address);
+ }
+ 
+ static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+ {
+-	if (pud_none(*pud))
+-		return __pmd_alloc(mm, pud, address);
+-	return pmd_offset(pud, address);
++	return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address))?
++		NULL: pmd_offset(pud, address);
+ }
+-#endif
+-#endif /* CONFIG_MMU */
++#endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */
++
++#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
++/*
++ * We tuck a spinlock to guard each pagetable page into its struct page,
++ * at page->private, with BUILD_BUG_ON to make sure that this will not
++ * overflow into the next struct page (as it might with DEBUG_SPINLOCK).
++ * When freeing, reset page->mapping so free_pages_check won't complain.
++ */
++#define __pte_lockptr(page)	&((page)->u.ptl)
++#define pte_lock_init(_page)	do {					\
++	spin_lock_init(__pte_lockptr(_page));				\
++} while (0)
++#define pte_lock_deinit(page)	((page)->mapping = NULL)
++#define pte_lockptr(mm, pmd)	({(void)(mm); __pte_lockptr(pmd_page(*(pmd)));})
++#else
++/*
++ * We use mm->page_table_lock to guard all pagetable pages of the mm.
++ */
++#define pte_lock_init(page)	do {} while (0)
++#define pte_lock_deinit(page)	do {} while (0)
++#define pte_lockptr(mm, pmd)	({(void)(pmd); &(mm)->page_table_lock;})
++#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
++
++#define pte_offset_map_lock(mm, pmd, address, ptlp)	\
++({							\
++	spinlock_t *__ptl = pte_lockptr(mm, pmd);	\
++	pte_t *__pte = pte_offset_map(pmd, address);	\
++	*(ptlp) = __ptl;				\
++	spin_lock(__ptl);				\
++	__pte;						\
++})
++
++#define pte_unmap_unlock(pte, ptl)	do {		\
++	spin_unlock(ptl);				\
++	pte_unmap(pte);					\
++} while (0)
++
++#define pte_alloc_map(mm, pmd, address)			\
++	((unlikely(!pmd_present(*(pmd))) && __pte_alloc(mm, pmd, address))? \
++		NULL: pte_offset_map(pmd, address))
++
++#define pte_alloc_map_lock(mm, pmd, address, ptlp)	\
++	((unlikely(!pmd_present(*(pmd))) && __pte_alloc(mm, pmd, address))? \
++		NULL: pte_offset_map_lock(mm, pmd, address, ptlp))
++
++#define pte_alloc_kernel(pmd, address)			\
++	((unlikely(!pmd_present(*(pmd))) && __pte_alloc_kernel(pmd, address))? \
++		NULL: pte_offset_kernel(pmd, address))
+ 
+ extern void free_area_init(unsigned long * zones_size);
+ extern void free_area_init_node(int nid, pg_data_t *pgdat,
+ 	unsigned long * zones_size, unsigned long zone_start_pfn, 
+ 	unsigned long *zholes_size);
+ extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long);
++extern void setup_per_zone_pages_min(void);
+ extern void mem_init(void);
+ extern void show_mem(void);
+ extern void si_meminfo(struct sysinfo * val);
+@@ -834,6 +884,7 @@ extern int split_vma(struct mm_struct *,
+ extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
+ extern void __vma_link_rb(struct mm_struct *, struct vm_area_struct *,
+ 	struct rb_node **, struct rb_node *);
++extern void unlink_file_vma(struct vm_area_struct *);
+ extern struct vm_area_struct *copy_vma(struct vm_area_struct **,
+ 	unsigned long addr, unsigned long len, pgoff_t pgoff);
+ extern void exit_mmap(struct mm_struct *);
+@@ -894,7 +945,8 @@ void handle_ra_miss(struct address_space
+ unsigned long max_sane_readahead(unsigned long nr);
+ 
+ /* Do stack extension */
+-extern int expand_stack(struct vm_area_struct * vma, unsigned long address);
++extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
++extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
+ 
+ /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
+ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
+@@ -917,40 +969,28 @@ static inline unsigned long vma_pages(st
+ 	return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+ }
+ 
+-extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
+-
+-extern struct page * vmalloc_to_page(void *addr);
+-extern unsigned long vmalloc_to_pfn(void *addr);
+-extern struct page * follow_page(struct mm_struct *mm, unsigned long address,
+-		int write);
+-extern int check_user_page_readable(struct mm_struct *mm, unsigned long address);
+-int remap_pfn_range(struct vm_area_struct *, unsigned long,
+-		unsigned long, unsigned long, pgprot_t);
++struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
++struct page *vmalloc_to_page(void *addr);
++unsigned long vmalloc_to_pfn(void *addr);
++int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
++			unsigned long pfn, unsigned long size, pgprot_t);
++
++struct page *follow_page(struct mm_struct *, unsigned long address,
++			unsigned int foll_flags);
++#define FOLL_WRITE	0x01	/* check pte is writable */
++#define FOLL_TOUCH	0x02	/* mark page accessed */
++#define FOLL_GET	0x04	/* do get_page on page */
++#define FOLL_ANON	0x08	/* give ZERO_PAGE if no pgtable */
+ 
+ #ifdef CONFIG_PROC_FS
+-void __vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
++void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
+ #else
+-static inline void __vm_stat_account(struct mm_struct *mm,
++static inline void vm_stat_account(struct mm_struct *mm,
+ 			unsigned long flags, struct file *file, long pages)
+ {
+ }
+ #endif /* CONFIG_PROC_FS */
+ 
+-static inline void vm_stat_account(struct vm_area_struct *vma)
+-{
+-	__vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
+-							vma_pages(vma));
+-}
+-
+-static inline void vm_stat_unaccount(struct vm_area_struct *vma)
+-{
+-	__vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
+-							-vma_pages(vma));
+-}
+-
+-/* update per process rss and vm hiwater data */
+-extern void update_mem_hiwater(struct task_struct *tsk);
+-
+ #ifndef CONFIG_DEBUG_PAGEALLOC
+ static inline void
+ kernel_map_pages(struct page *page, int numpages, int enable)
+diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
+--- a/include/linux/mmc/mmc.h
++++ b/include/linux/mmc/mmc.h
+@@ -50,7 +50,7 @@ struct mmc_command {
+ #define MMC_ERR_INVALID	5
+ 
+ 	struct mmc_data		*data;		/* data segment associated with cmd */
+-	struct mmc_request	*mrq;		/* assoicated request */
++	struct mmc_request	*mrq;		/* associated request */
+ };
+ 
+ struct mmc_data {
+@@ -68,7 +68,7 @@ struct mmc_data {
+ 	unsigned int		bytes_xfered;
+ 
+ 	struct mmc_command	*stop;		/* stop command */
+-	struct mmc_request	*mrq;		/* assoicated request */
++	struct mmc_request	*mrq;		/* associated request */
+ 
+ 	unsigned int		sg_len;		/* size of scatter list */
+ 	struct scatterlist	*sg;		/* I/O scatter list */
+diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
+--- a/include/linux/mmzone.h
++++ b/include/linux/mmzone.h
+@@ -12,6 +12,7 @@
+ #include <linux/threads.h>
+ #include <linux/numa.h>
+ #include <linux/init.h>
++#include <linux/seqlock.h>
+ #include <asm/atomic.h>
+ 
+ /* Free memory management - zoned buddy allocator.  */
+@@ -137,6 +138,10 @@ struct zone {
+ 	 * free areas of different sizes
+ 	 */
+ 	spinlock_t		lock;
++#ifdef CONFIG_MEMORY_HOTPLUG
++	/* see spanned/present_pages for more description */
++	seqlock_t		span_seqlock;
++#endif
+ 	struct free_area	free_area[MAX_ORDER];
+ 
+ 
+@@ -220,6 +225,16 @@ struct zone {
+ 	/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
+ 	unsigned long		zone_start_pfn;
+ 
++	/*
++	 * zone_start_pfn, spanned_pages and present_pages are all
++	 * protected by span_seqlock.  It is a seqlock because it has
++	 * to be read outside of zone->lock, and it is done in the main
++	 * allocator path.  But, it is written quite infrequently.
++	 *
++	 * The lock is declared along with zone->lock because it is
++	 * frequently read in proximity to zone->lock.  It's good to
++	 * give them a chance of being in the same cacheline.
++	 */
+ 	unsigned long		spanned_pages;	/* total size, including holes */
+ 	unsigned long		present_pages;	/* amount of memory (excluding holes) */
+ 
+@@ -273,6 +288,16 @@ typedef struct pglist_data {
+ 	struct page *node_mem_map;
+ #endif
+ 	struct bootmem_data *bdata;
++#ifdef CONFIG_MEMORY_HOTPLUG
++	/*
++	 * Must be held any time you expect node_start_pfn, node_present_pages
++	 * or node_spanned_pages stay constant.  Holding this will also
++	 * guarantee that any pfn_valid() stays that way.
++	 *
++	 * Nests above zone->lock and zone->size_seqlock.
++	 */
++	spinlock_t node_size_lock;
++#endif
+ 	unsigned long node_start_pfn;
+ 	unsigned long node_present_pages; /* total number of physical pages */
+ 	unsigned long node_spanned_pages; /* total size of physical page
+@@ -293,6 +318,8 @@ typedef struct pglist_data {
+ #endif
+ #define nid_page_nr(nid, pagenr) 	pgdat_page_nr(NODE_DATA(nid),(pagenr))
+ 
++#include <linux/memory_hotplug.h>
++
+ extern struct pglist_data *pgdat_list;
+ 
+ void __get_zone_counts(unsigned long *active, unsigned long *inactive,
+@@ -302,7 +329,7 @@ void get_zone_counts(unsigned long *acti
+ void build_all_zonelists(void);
+ void wakeup_kswapd(struct zone *zone, int order);
+ int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
+-		int alloc_type, int can_try_harder, int gfp_high);
++		int alloc_type, int can_try_harder, gfp_t gfp_high);
+ 
+ #ifdef CONFIG_HAVE_MEMORY_PRESENT
+ void memory_present(int nid, unsigned long start, unsigned long end);
+@@ -509,6 +536,7 @@ static inline struct mem_section *__nr_t
+ 		return NULL;
+ 	return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK];
+ }
++extern int __section_nr(struct mem_section* ms);
+ 
+ /*
+  * We use the lower bits of the mem_map pointer to store
+diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
+--- a/include/linux/mod_devicetable.h
++++ b/include/linux/mod_devicetable.h
+@@ -244,4 +244,9 @@ struct pcmcia_device_id {
+ #define PCMCIA_DEV_ID_MATCH_FAKE_CIS	0x0200
+ #define PCMCIA_DEV_ID_MATCH_ANONYMOUS	0x0400
+ 
++/* I2C */
++struct i2c_device_id {
++	__u16 id;
++};
++
+ #endif /* LINUX_MOD_DEVICETABLE_H */
+diff --git a/include/linux/module.h b/include/linux/module.h
+--- a/include/linux/module.h
++++ b/include/linux/module.h
+@@ -554,7 +554,9 @@ static inline void MODULE_PARM_(void) { 
+ #ifdef MODULE
+ /* DEPRECATED: Do not use. */
+ #define MODULE_PARM(var,type)						    \
+-struct obsolete_modparm __parm_##var __attribute__((section("__obsparm"))) = \
++extern struct obsolete_modparm __parm_##var \
++__attribute__((section("__obsparm"))); \
++struct obsolete_modparm __parm_##var = \
+ { __stringify(var), type, &MODULE_PARM_ }; \
+ __MODULE_PARM_TYPE(var, type);
+ #else
+diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
+--- a/include/linux/msdos_fs.h
++++ b/include/linux/msdos_fs.h
+@@ -282,6 +282,17 @@ static inline u8 fat_attr(struct inode *
+ 		MSDOS_I(inode)->i_attrs;
+ }
+ 
++static inline unsigned char fat_checksum(const __u8 *name)
++{
++	unsigned char s = name[0];
++	s = (s<<7) + (s>>1) + name[1];	s = (s<<7) + (s>>1) + name[2];
++	s = (s<<7) + (s>>1) + name[3];	s = (s<<7) + (s>>1) + name[4];
++	s = (s<<7) + (s>>1) + name[5];	s = (s<<7) + (s>>1) + name[6];
++	s = (s<<7) + (s>>1) + name[7];	s = (s<<7) + (s>>1) + name[8];
++	s = (s<<7) + (s>>1) + name[9];	s = (s<<7) + (s>>1) + name[10];
++	return s;
++}
++
+ static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus)
+ {
+ 	return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus
+diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
+--- a/include/linux/mtd/map.h
++++ b/include/linux/mtd/map.h
+@@ -8,7 +8,10 @@
+ #include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/list.h>
++#include <linux/string.h>
++
+ #include <linux/mtd/compatmac.h>
++
+ #include <asm/unaligned.h>
+ #include <asm/system.h>
+ #include <asm/io.h>
+diff --git a/include/linux/namei.h b/include/linux/namei.h
+--- a/include/linux/namei.h
++++ b/include/linux/namei.h
+@@ -8,6 +8,7 @@ struct vfsmount;
+ struct open_intent {
+ 	int	flags;
+ 	int	create_mode;
++	struct file *file;
+ };
+ 
+ enum { MAX_NESTED_LINKS = 5 };
+@@ -65,6 +66,13 @@ extern int FASTCALL(link_path_walk(const
+ extern void path_release(struct nameidata *);
+ extern void path_release_on_umount(struct nameidata *);
+ 
++extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
++extern int path_lookup_open(const char *, unsigned lookup_flags, struct nameidata *, int open_flags);
++extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
++		int (*open)(struct inode *, struct file *));
++extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
++extern void release_open_intent(struct nameidata *);
++
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ 
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -308,6 +308,7 @@ struct net_device
+ #define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
+ #define NETIF_F_TSO		2048	/* Can offload TCP/IP segmentation */
+ #define NETIF_F_LLTX		4096	/* LockLess TX */
++#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
+ 
+ 	struct net_device	*next_sched;
+ 
+@@ -873,11 +874,9 @@ static inline void netif_rx_complete(str
+ 
+ static inline void netif_poll_disable(struct net_device *dev)
+ {
+-	while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
++	while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state))
+ 		/* No hurry. */
+-		current->state = TASK_INTERRUPTIBLE;
+-		schedule_timeout(1);
+-	}
++		schedule_timeout_interruptible(1);
+ }
+ 
+ static inline void netif_poll_enable(struct net_device *dev)
+diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
+--- a/include/linux/netfilter_arp/arp_tables.h
++++ b/include/linux/netfilter_arp/arp_tables.h
+@@ -68,7 +68,8 @@ struct arpt_entry_target
+ 			u_int16_t target_size;
+ 
+ 			/* Used by userspace */
+-			char name[ARPT_FUNCTION_MAXNAMELEN];
++			char name[ARPT_FUNCTION_MAXNAMELEN-1];
++			u_int8_t revision;
+ 		} user;
+ 		struct {
+ 			u_int16_t target_size;
+@@ -148,7 +149,9 @@ struct arpt_entry
+ 
+ #define ARPT_SO_GET_INFO		(ARPT_BASE_CTL)
+ #define ARPT_SO_GET_ENTRIES		(ARPT_BASE_CTL + 1)
+-#define ARPT_SO_GET_MAX			ARPT_SO_GET_ENTRIES
++/* #define ARPT_SO_GET_REVISION_MATCH	(ARPT_BASE_CTL + 2)*/
++#define ARPT_SO_GET_REVISION_TARGET	(ARPT_BASE_CTL + 3)
++#define ARPT_SO_GET_MAX			ARPT_SO_GET_REVISION_TARGET
+ 
+ /* CONTINUE verdict for targets */
+ #define ARPT_CONTINUE 0xFFFFFFFF
+@@ -236,6 +239,15 @@ struct arpt_get_entries
+ 	struct arpt_entry entrytable[0];
+ };
+ 
++/* The argument to ARPT_SO_GET_REVISION_*.  Returns highest revision
++ * kernel supports, if >= revision. */
++struct arpt_get_revision
++{
++	char name[ARPT_FUNCTION_MAXNAMELEN-1];
++
++	u_int8_t revision;
++};
++
+ /* Standard return verdict, or do jump. */
+ #define ARPT_STANDARD_TARGET ""
+ /* Error verdict. */
+@@ -274,7 +286,9 @@ struct arpt_target
+ {
+ 	struct list_head list;
+ 
+-	const char name[ARPT_FUNCTION_MAXNAMELEN];
++	const char name[ARPT_FUNCTION_MAXNAMELEN-1];
++
++	u_int8_t revision;
+ 
+ 	/* Returns verdict. */
+ 	unsigned int (*target)(struct sk_buff **pskb,
+diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
+--- a/include/linux/netfilter_ipv6/ip6_tables.h
++++ b/include/linux/netfilter_ipv6/ip6_tables.h
+@@ -57,7 +57,8 @@ struct ip6t_entry_match
+ 			u_int16_t match_size;
+ 
+ 			/* Used by userspace */
+-			char name[IP6T_FUNCTION_MAXNAMELEN];
++			char name[IP6T_FUNCTION_MAXNAMELEN-1];
++			u_int8_t revision;
+ 		} user;
+ 		struct {
+ 			u_int16_t match_size;
+@@ -80,7 +81,8 @@ struct ip6t_entry_target
+ 			u_int16_t target_size;
+ 
+ 			/* Used by userspace */
+-			char name[IP6T_FUNCTION_MAXNAMELEN];
++			char name[IP6T_FUNCTION_MAXNAMELEN-1];
++			u_int8_t revision;
+ 		} user;
+ 		struct {
+ 			u_int16_t target_size;
+@@ -161,7 +163,9 @@ struct ip6t_entry
+ 
+ #define IP6T_SO_GET_INFO		(IP6T_BASE_CTL)
+ #define IP6T_SO_GET_ENTRIES		(IP6T_BASE_CTL + 1)
+-#define IP6T_SO_GET_MAX			IP6T_SO_GET_ENTRIES
++#define	IP6T_SO_GET_REVISION_MATCH	(IP6T_BASE_CTL + 2)
++#define	IP6T_SO_GET_REVISION_TARGET	(IP6T_BASE_CTL + 3)
++#define IP6T_SO_GET_MAX			IP6T_SO_GET_REVISION_TARGET
+ 
+ /* CONTINUE verdict for targets */
+ #define IP6T_CONTINUE 0xFFFFFFFF
+@@ -291,6 +295,15 @@ struct ip6t_get_entries
+ 	struct ip6t_entry entrytable[0];
+ };
+ 
++/* The argument to IP6T_SO_GET_REVISION_*.  Returns highest revision
++ * kernel supports, if >= revision. */
++struct ip6t_get_revision
++{
++	char name[IP6T_FUNCTION_MAXNAMELEN-1];
++
++	u_int8_t revision;
++};
++
+ /* Standard return verdict, or do jump. */
+ #define IP6T_STANDARD_TARGET ""
+ /* Error verdict. */
+@@ -352,7 +365,9 @@ struct ip6t_match
+ {
+ 	struct list_head list;
+ 
+-	const char name[IP6T_FUNCTION_MAXNAMELEN];
++	const char name[IP6T_FUNCTION_MAXNAMELEN-1];
++
++	u_int8_t revision;
+ 
+ 	/* Return true or false: return FALSE and set *hotdrop = 1 to
+            force immediate packet drop. */
+@@ -387,7 +402,9 @@ struct ip6t_target
+ {
+ 	struct list_head list;
+ 
+-	const char name[IP6T_FUNCTION_MAXNAMELEN];
++	const char name[IP6T_FUNCTION_MAXNAMELEN-1];
++
++	u_int8_t revision;
+ 
+ 	/* Returns verdict. Argument order changed since 2.6.9, as this
+ 	   must now handle non-linear skbs, using skb_copy_bits and
+diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
+--- a/include/linux/nfs_fs.h
++++ b/include/linux/nfs_fs.h
+@@ -41,6 +41,10 @@
+ #define NFS_MAX_FILE_IO_BUFFER_SIZE	32768
+ #define NFS_DEF_FILE_IO_BUFFER_SIZE	4096
+ 
++/* Default timeout values */
++#define NFS_MAX_UDP_TIMEOUT	(60*HZ)
++#define NFS_MAX_TCP_TIMEOUT	(600*HZ)
++
+ /*
+  * superblock magic number for NFS
+  */
+@@ -137,6 +141,7 @@ struct nfs_inode {
+ 	unsigned long		attrtimeo_timestamp;
+ 	__u64			change_attr;		/* v4 only */
+ 
++	unsigned long		last_updated;
+ 	/* "Generation counter" for the attribute cache. This is
+ 	 * bumped whenever we update the metadata on the
+ 	 * server.
+@@ -236,13 +241,17 @@ static inline int nfs_caches_unstable(st
+ 	return atomic_read(&NFS_I(inode)->data_updates) != 0;
+ }
+ 
++static inline void nfs_mark_for_revalidate(struct inode *inode)
++{
++	spin_lock(&inode->i_lock);
++	NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
++	spin_unlock(&inode->i_lock);
++}
++
+ static inline void NFS_CACHEINV(struct inode *inode)
+ {
+-	if (!nfs_caches_unstable(inode)) {
+-		spin_lock(&inode->i_lock);
+-		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
+-		spin_unlock(&inode->i_lock);
+-	}
++	if (!nfs_caches_unstable(inode))
++		nfs_mark_for_revalidate(inode);
+ }
+ 
+ static inline int nfs_server_capable(struct inode *inode, int cap)
+@@ -276,7 +285,7 @@ static inline long nfs_save_change_attri
+ static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long chattr)
+ {
+ 	return !nfs_caches_unstable(inode)
+-		&& chattr == NFS_I(inode)->cache_change_attribute;
++		&& time_after_eq(chattr, NFS_I(inode)->cache_change_attribute);
+ }
+ 
+ /*
+@@ -286,6 +295,7 @@ extern void nfs_zap_caches(struct inode 
+ extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
+ 				struct nfs_fattr *);
+ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
++extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
+ extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+ extern int nfs_permission(struct inode *, int, struct nameidata *);
+ extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *);
+@@ -312,6 +322,12 @@ extern void nfs_file_clear_open_context(
+ /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
+ extern u32 root_nfs_parse_addr(char *name); /*__init*/
+ 
++static inline void nfs_fattr_init(struct nfs_fattr *fattr)
++{
++	fattr->valid = 0;
++	fattr->time_start = jiffies;
++}
++
+ /*
+  * linux/fs/nfs/file.c
+  */
+diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
+--- a/include/linux/nfs_xdr.h
++++ b/include/linux/nfs_xdr.h
+@@ -41,7 +41,7 @@ struct nfs_fattr {
+ 	__u32			bitmap[2];	/* NFSv4 returned attribute bitmap */
+ 	__u64			change_attr;	/* NFSv4 change attribute */
+ 	__u64			pre_change_attr;/* pre-op NFSv4 change attribute */
+-	unsigned long		timestamp;
++	unsigned long		time_start;
+ };
+ 
+ #define NFS_ATTR_WCC		0x0001		/* pre-op WCC data    */
+@@ -96,12 +96,13 @@ struct nfs4_change_info {
+ 	u64			after;
+ };
+ 
++struct nfs_seqid;
+ /*
+  * Arguments to the open call.
+  */
+ struct nfs_openargs {
+ 	const struct nfs_fh *	fh;
+-	__u32                   seqid;
++	struct nfs_seqid *	seqid;
+ 	int			open_flags;
+ 	__u64                   clientid;
+ 	__u32                   id;
+@@ -123,6 +124,7 @@ struct nfs_openres {
+ 	struct nfs4_change_info	cinfo;
+ 	__u32                   rflags;
+ 	struct nfs_fattr *      f_attr;
++	struct nfs_fattr *      dir_attr;
+ 	const struct nfs_server *server;
+ 	int			delegation_type;
+ 	nfs4_stateid		delegation;
+@@ -136,7 +138,7 @@ struct nfs_openres {
+ struct nfs_open_confirmargs {
+ 	const struct nfs_fh *	fh;
+ 	nfs4_stateid            stateid;
+-	__u32                   seqid;
++	struct nfs_seqid *	seqid;
+ };
+ 
+ struct nfs_open_confirmres {
+@@ -148,13 +150,16 @@ struct nfs_open_confirmres {
+  */
+ struct nfs_closeargs {
+ 	struct nfs_fh *         fh;
+-	nfs4_stateid            stateid;
+-	__u32                   seqid;
++	nfs4_stateid *		stateid;
++	struct nfs_seqid *	seqid;
+ 	int			open_flags;
++	const u32 *		bitmask;
+ };
+ 
+ struct nfs_closeres {
+ 	nfs4_stateid            stateid;
++	struct nfs_fattr *	fattr;
++	const struct nfs_server *server;
+ };
+ /*
+  *  * Arguments to the lock,lockt, and locku call.
+@@ -164,30 +169,19 @@ struct nfs_lowner {
+ 	u32                     id;
+ };
+ 
+-struct nfs_open_to_lock {
+-	__u32                   open_seqid;
+-	nfs4_stateid            open_stateid;
+-	__u32                   lock_seqid;
+-	struct nfs_lowner       lock_owner;
+-};
+-
+-struct nfs_exist_lock {
+-	nfs4_stateid            stateid;
+-	__u32                   seqid;
+-};
+-
+ struct nfs_lock_opargs {
++	struct nfs_seqid *	lock_seqid;
++	nfs4_stateid *		lock_stateid;
++	struct nfs_seqid *	open_seqid;
++	nfs4_stateid *		open_stateid;
++	struct nfs_lowner       lock_owner;
+ 	__u32                   reclaim;
+ 	__u32                   new_lock_owner;
+-	union {
+-		struct nfs_open_to_lock *open_lock;
+-		struct nfs_exist_lock   *exist_lock;
+-	} u;
+ };
+ 
+ struct nfs_locku_opargs {
+-	__u32                   seqid;
+-	nfs4_stateid            stateid;
++	struct nfs_seqid *	seqid;
++	nfs4_stateid *		stateid;
+ };
+ 
+ struct nfs_lockargs {
+@@ -262,6 +256,7 @@ struct nfs_writeargs {
+ 	enum nfs3_stable_how	stable;
+ 	unsigned int		pgbase;
+ 	struct page **		pages;
++	const u32 *		bitmask;
+ };
+ 
+ struct nfs_writeverf {
+@@ -273,6 +268,7 @@ struct nfs_writeres {
+ 	struct nfs_fattr *	fattr;
+ 	struct nfs_writeverf *	verf;
+ 	__u32			count;
++	const struct nfs_server *server;
+ };
+ 
+ /*
+@@ -550,6 +546,7 @@ struct nfs4_create_res {
+ 	struct nfs_fh *			fh;
+ 	struct nfs_fattr *		fattr;
+ 	struct nfs4_change_info		dir_cinfo;
++	struct nfs_fattr *		dir_fattr;
+ };
+ 
+ struct nfs4_fsinfo_arg {
+@@ -571,8 +568,17 @@ struct nfs4_link_arg {
+ 	const struct nfs_fh *		fh;
+ 	const struct nfs_fh *		dir_fh;
+ 	const struct qstr *		name;
++	const u32 *			bitmask;
++};
++
++struct nfs4_link_res {
++	const struct nfs_server *	server;
++	struct nfs_fattr *		fattr;
++	struct nfs4_change_info		cinfo;
++	struct nfs_fattr *		dir_attr;
+ };
+ 
++
+ struct nfs4_lookup_arg {
+ 	const struct nfs_fh *		dir_fh;
+ 	const struct qstr *		name;
+@@ -619,6 +625,13 @@ struct nfs4_readlink {
+ struct nfs4_remove_arg {
+ 	const struct nfs_fh *		fh;
+ 	const struct qstr *		name;
++	const u32 *			bitmask;
++};
++
++struct nfs4_remove_res {
++	const struct nfs_server *	server;
++	struct nfs4_change_info		cinfo;
++	struct nfs_fattr *		dir_attr;
+ };
+ 
+ struct nfs4_rename_arg {
+@@ -626,11 +639,15 @@ struct nfs4_rename_arg {
+ 	const struct nfs_fh *		new_dir;
+ 	const struct qstr *		old_name;
+ 	const struct qstr *		new_name;
++	const u32 *			bitmask;
+ };
+ 
+ struct nfs4_rename_res {
++	const struct nfs_server *	server;
+ 	struct nfs4_change_info		old_cinfo;
++	struct nfs_fattr *		old_fattr;
+ 	struct nfs4_change_info		new_cinfo;
++	struct nfs_fattr *		new_fattr;
+ };
+ 
+ struct nfs4_setclientid {
+@@ -722,7 +739,7 @@ struct nfs_rpc_ops {
+ 	int	(*write)   (struct nfs_write_data *);
+ 	int	(*commit)  (struct nfs_write_data *);
+ 	int	(*create)  (struct inode *, struct dentry *,
+-			    struct iattr *, int);
++			    struct iattr *, int, struct nameidata *);
+ 	int	(*remove)  (struct inode *, struct qstr *);
+ 	int	(*unlink_setup)  (struct rpc_message *,
+ 			    struct dentry *, struct qstr *);
+diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
+--- a/include/linux/nodemask.h
++++ b/include/linux/nodemask.h
+@@ -12,6 +12,8 @@
+  * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
+  * For details of nodelist_scnprintf() and nodelist_parse(), see
+  * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
++ * For details of node_remap(), see bitmap_bitremap in lib/bitmap.c.
++ * For details of nodes_remap(), see bitmap_remap in lib/bitmap.c.
+  *
+  * The available nodemask operations are:
+  *
+@@ -52,6 +54,8 @@
+  * int nodemask_parse(ubuf, ulen, mask)	Parse ascii string as nodemask
+  * int nodelist_scnprintf(buf, len, mask) Format nodemask as list for printing
+  * int nodelist_parse(buf, map)		Parse ascii string as nodelist
++ * int node_remap(oldbit, old, new)	newbit = map(old, new)(oldbit)
++ * int nodes_remap(dst, src, old, new)	*dst = map(old, new)(dst)
+  *
+  * for_each_node_mask(node, mask)	for-loop node over mask
+  *
+@@ -307,6 +311,22 @@ static inline int __nodelist_parse(const
+ 	return bitmap_parselist(buf, dstp->bits, nbits);
+ }
+ 
++#define node_remap(oldbit, old, new) \
++		__node_remap((oldbit), &(old), &(new), MAX_NUMNODES)
++static inline int __node_remap(int oldbit,
++		const nodemask_t *oldp, const nodemask_t *newp, int nbits)
++{
++	return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
++}
++
++#define nodes_remap(dst, src, old, new) \
++		__nodes_remap(&(dst), &(src), &(old), &(new), MAX_NUMNODES)
++static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
++		const nodemask_t *oldp, const nodemask_t *newp, int nbits)
++{
++	bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
++}
++
+ #if MAX_NUMNODES > 1
+ #define for_each_node_mask(node, mask)			\
+ 	for ((node) = first_node(mask);			\
+diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
+--- a/include/linux/pagemap.h
++++ b/include/linux/pagemap.h
+@@ -21,16 +21,17 @@
+ 
+ static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
+ {
+-	return mapping->flags & __GFP_BITS_MASK;
++	return (__force gfp_t)mapping->flags & __GFP_BITS_MASK;
+ }
+ 
+ /*
+  * This is non-atomic.  Only to be used before the mapping is activated.
+  * Probably needs a barrier...
+  */
+-static inline void mapping_set_gfp_mask(struct address_space *m, int mask)
++static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
+ {
+-	m->flags = (m->flags & ~__GFP_BITS_MASK) | mask;
++	m->flags = (m->flags & ~(__force unsigned long)__GFP_BITS_MASK) |
++				(__force unsigned long)mask;
+ }
+ 
+ /*
+@@ -69,7 +70,7 @@ extern struct page * find_lock_page(stru
+ extern struct page * find_trylock_page(struct address_space *mapping,
+ 				unsigned long index);
+ extern struct page * find_or_create_page(struct address_space *mapping,
+-				unsigned long index, unsigned int gfp_mask);
++				unsigned long index, gfp_t gfp_mask);
+ unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
+ 			unsigned int nr_pages, struct page **pages);
+ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
+@@ -92,9 +93,9 @@ extern int read_cache_pages(struct addre
+ 		struct list_head *pages, filler_t *filler, void *data);
+ 
+ int add_to_page_cache(struct page *page, struct address_space *mapping,
+-				unsigned long index, int gfp_mask);
++				unsigned long index, gfp_t gfp_mask);
+ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
+-				unsigned long index, int gfp_mask);
++				unsigned long index, gfp_t gfp_mask);
+ extern void remove_from_page_cache(struct page *page);
+ extern void __remove_from_page_cache(struct page *page);
+ 
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -132,6 +132,7 @@ struct pci_dev {
+ 	unsigned int	is_enabled:1;	/* pci_enable_device has been called */
+ 	unsigned int	is_busmaster:1; /* device is busmaster */
+ 	unsigned int	no_msi:1;	/* device may not use msi */
++	unsigned int	block_ucfg_access:1;	/* userspace config space access is blocked */
+ 
+ 	u32		saved_config_space[16]; /* config space saved at suspend time */
+ 	struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
+@@ -490,6 +491,9 @@ extern void pci_disable_msix(struct pci_
+ extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
+ #endif
+ 
++extern void pci_block_user_cfg_access(struct pci_dev *dev);
++extern void pci_unblock_user_cfg_access(struct pci_dev *dev);
++
+ /*
+  * PCI domain support.  Sometimes called PCI segment (eg by ACPI),
+  * a PCI domain is defined to be a set of PCI busses which share
+@@ -560,6 +564,9 @@ static inline int pci_enable_wake(struct
+ 
+ #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
+ 
++static inline void pci_block_user_cfg_access(struct pci_dev *dev) { }
++static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) { }
++
+ #endif /* CONFIG_PCI */
+ 
+ /* Include architecture-dependent settings and functions */
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -96,6 +96,9 @@
+ #define PCI_CLASS_SERIAL_ACCESS		0x0c01
+ #define PCI_CLASS_SERIAL_SSA		0x0c02
+ #define PCI_CLASS_SERIAL_USB		0x0c03
++#define PCI_CLASS_SERIAL_USB_UHCI	0x0c0300
++#define PCI_CLASS_SERIAL_USB_OHCI	0x0c0310
++#define PCI_CLASS_SERIAL_USB_EHCI	0x0c0320
+ #define PCI_CLASS_SERIAL_FIBER		0x0c04
+ #define PCI_CLASS_SERIAL_SMBUS		0x0c05
+ 
+@@ -132,9 +135,6 @@
+ 
+ #define PCI_VENDOR_ID_COMPAQ		0x0e11
+ #define PCI_DEVICE_ID_COMPAQ_TOKENRING	0x0508
+-#define PCI_DEVICE_ID_COMPAQ_1280	0x3033
+-#define PCI_DEVICE_ID_COMPAQ_TRIFLEX	0x4000
+-#define PCI_DEVICE_ID_COMPAQ_6010	0x6010
+ #define PCI_DEVICE_ID_COMPAQ_TACHYON	0xa0fc
+ #define PCI_DEVICE_ID_COMPAQ_SMART2P	0xae10
+ #define PCI_DEVICE_ID_COMPAQ_NETEL100	0xae32
+@@ -274,7 +274,6 @@
+ #define PCI_DEVICE_ID_ATI_RAGE128_PP	0x5050
+ #define PCI_DEVICE_ID_ATI_RAGE128_PQ	0x5051
+ #define PCI_DEVICE_ID_ATI_RAGE128_PR	0x5052
+-#define PCI_DEVICE_ID_ATI_RAGE128_TR	0x5452
+ #define PCI_DEVICE_ID_ATI_RAGE128_PS	0x5053
+ #define PCI_DEVICE_ID_ATI_RAGE128_PT	0x5054
+ #define PCI_DEVICE_ID_ATI_RAGE128_PU	0x5055
+@@ -282,8 +281,6 @@
+ #define PCI_DEVICE_ID_ATI_RAGE128_PW	0x5057
+ #define PCI_DEVICE_ID_ATI_RAGE128_PX	0x5058
+ /* Rage128 M4 */
+-#define PCI_DEVICE_ID_ATI_RADEON_LE	0x4d45
+-#define PCI_DEVICE_ID_ATI_RADEON_LF	0x4d46
+ /* Radeon R100 */
+ #define PCI_DEVICE_ID_ATI_RADEON_QD	0x5144
+ #define PCI_DEVICE_ID_ATI_RADEON_QE	0x5145
+@@ -304,32 +301,22 @@
+ #define PCI_DEVICE_ID_ATI_RADEON_QW	0x5157
+ #define PCI_DEVICE_ID_ATI_RADEON_QX	0x5158
+ /* Radeon NV-100 */
+-#define PCI_DEVICE_ID_ATI_RADEON_N1	0x5159
+-#define PCI_DEVICE_ID_ATI_RADEON_N2	0x515a
+ /* Radeon RV250 (9000) */
+ #define PCI_DEVICE_ID_ATI_RADEON_Id	0x4964
+ #define PCI_DEVICE_ID_ATI_RADEON_Ie	0x4965
+ #define PCI_DEVICE_ID_ATI_RADEON_If	0x4966
+ #define PCI_DEVICE_ID_ATI_RADEON_Ig	0x4967
+ /* Radeon RV280 (9200) */
+-#define PCI_DEVICE_ID_ATI_RADEON_Y_	0x5960
+ #define PCI_DEVICE_ID_ATI_RADEON_Ya	0x5961
+ #define PCI_DEVICE_ID_ATI_RADEON_Yd	0x5964
+ /* Radeon R300 (9500) */
+-#define PCI_DEVICE_ID_ATI_RADEON_AD	0x4144
+ /* Radeon R300 (9700) */
+ #define PCI_DEVICE_ID_ATI_RADEON_ND	0x4e44
+ #define PCI_DEVICE_ID_ATI_RADEON_NE	0x4e45
+ #define PCI_DEVICE_ID_ATI_RADEON_NF	0x4e46
+ #define PCI_DEVICE_ID_ATI_RADEON_NG	0x4e47
+-#define PCI_DEVICE_ID_ATI_RADEON_AE	0x4145
+-#define PCI_DEVICE_ID_ATI_RADEON_AF	0x4146
+ /* Radeon R350 (9800) */
+-#define PCI_DEVICE_ID_ATI_RADEON_NH	0x4e48
+-#define PCI_DEVICE_ID_ATI_RADEON_NI	0x4e49
+ /* Radeon RV350 (9600) */
+-#define PCI_DEVICE_ID_ATI_RADEON_AP	0x4150
+-#define PCI_DEVICE_ID_ATI_RADEON_AR	0x4152
+ /* Radeon M6 */
+ #define PCI_DEVICE_ID_ATI_RADEON_LY	0x4c59
+ #define PCI_DEVICE_ID_ATI_RADEON_LZ	0x4c5a
+@@ -342,10 +329,6 @@
+ #define PCI_DEVICE_ID_ATI_RADEON_Lf	0x4c66
+ #define PCI_DEVICE_ID_ATI_RADEON_Lg	0x4c67
+ /* Radeon */
+-#define PCI_DEVICE_ID_ATI_RADEON_RA	0x5144
+-#define PCI_DEVICE_ID_ATI_RADEON_RB	0x5145
+-#define PCI_DEVICE_ID_ATI_RADEON_RC	0x5146
+-#define PCI_DEVICE_ID_ATI_RADEON_RD	0x5147
+ /* RadeonIGP */
+ #define PCI_DEVICE_ID_ATI_RS100		0xcab0
+ #define PCI_DEVICE_ID_ATI_RS200		0xcab2
+@@ -446,45 +429,28 @@
+ #define PCI_DEVICE_ID_CIRRUS_5465	0x00d6
+ #define PCI_DEVICE_ID_CIRRUS_6729	0x1100
+ #define PCI_DEVICE_ID_CIRRUS_6832	0x1110
+-#define PCI_DEVICE_ID_CIRRUS_7542	0x1200
+ #define PCI_DEVICE_ID_CIRRUS_7543	0x1202
+-#define PCI_DEVICE_ID_CIRRUS_7541	0x1204
+ #define PCI_DEVICE_ID_CIRRUS_4610	0x6001
+ #define PCI_DEVICE_ID_CIRRUS_4612	0x6003
+ #define PCI_DEVICE_ID_CIRRUS_4615	0x6004
+-#define PCI_DEVICE_ID_CIRRUS_4281	0x6005
+ 
+ #define PCI_VENDOR_ID_IBM		0x1014
+-#define PCI_DEVICE_ID_IBM_FIRE_CORAL	0x000a
+ #define PCI_DEVICE_ID_IBM_TR		0x0018
+-#define PCI_DEVICE_ID_IBM_82G2675	0x001d
+-#define PCI_DEVICE_ID_IBM_MCA		0x0020
+-#define PCI_DEVICE_ID_IBM_82351		0x0022
+-#define PCI_DEVICE_ID_IBM_PYTHON	0x002d
+-#define PCI_DEVICE_ID_IBM_SERVERAID	0x002e
+ #define PCI_DEVICE_ID_IBM_TR_WAKE	0x003e
+-#define PCI_DEVICE_ID_IBM_MPIC		0x0046
+-#define PCI_DEVICE_ID_IBM_3780IDSP	0x007d
+-#define PCI_DEVICE_ID_IBM_CHUKAR	0x0096
+ #define PCI_DEVICE_ID_IBM_CPC710_PCI64	0x00fc
+-#define PCI_DEVICE_ID_IBM_CPC710_PCI32	0x0105
+-#define	PCI_DEVICE_ID_IBM_405GP		0x0156
+ #define PCI_DEVICE_ID_IBM_SNIPE		0x0180
+-#define PCI_DEVICE_ID_IBM_SERVERAIDI960	0x01bd
+ #define PCI_DEVICE_ID_IBM_CITRINE		0x028C
+ #define PCI_DEVICE_ID_IBM_GEMSTONE		0xB166
+-#define PCI_DEVICE_ID_IBM_MPIC_2	0xffff
+ #define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1	0x0031
+ #define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2	0x0219
+ #define PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX		0x021A
+ #define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM	0x0251
+ #define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL	0x252
+ 
+-#define PCI_VENDOR_ID_COMPEX2		0x101a // pci.ids says "AT&T GIS (NCR)"
++#define PCI_VENDOR_ID_COMPEX2		0x101a /* pci.ids says "AT&T GIS (NCR)" */
+ #define PCI_DEVICE_ID_COMPEX2_100VG	0x0005
+ 
+ #define PCI_VENDOR_ID_WD		0x101c
+-#define PCI_DEVICE_ID_WD_7197		0x3296
+ #define PCI_DEVICE_ID_WD_90C		0xc24a
+ 
+ #define PCI_VENDOR_ID_AMI		0x101e
+@@ -501,33 +467,18 @@
+ #define PCI_DEVICE_ID_AMD_FE_GATE_7006	0x7006
+ #define PCI_DEVICE_ID_AMD_FE_GATE_7007	0x7007
+ #define PCI_DEVICE_ID_AMD_FE_GATE_700C	0x700C
+-#define PCI_DEVICE_ID_AMD_FE_GATE_700D	0x700D
+ #define PCI_DEVICE_ID_AMD_FE_GATE_700E	0x700E
+-#define PCI_DEVICE_ID_AMD_FE_GATE_700F	0x700F
+-#define PCI_DEVICE_ID_AMD_COBRA_7400	0x7400
+ #define PCI_DEVICE_ID_AMD_COBRA_7401	0x7401
+-#define PCI_DEVICE_ID_AMD_COBRA_7403	0x7403
+-#define PCI_DEVICE_ID_AMD_COBRA_7404	0x7404
+-#define PCI_DEVICE_ID_AMD_VIPER_7408	0x7408
+ #define PCI_DEVICE_ID_AMD_VIPER_7409	0x7409
+ #define PCI_DEVICE_ID_AMD_VIPER_740B	0x740B
+-#define PCI_DEVICE_ID_AMD_VIPER_740C	0x740C
+ #define PCI_DEVICE_ID_AMD_VIPER_7410	0x7410
+ #define PCI_DEVICE_ID_AMD_VIPER_7411	0x7411
+ #define PCI_DEVICE_ID_AMD_VIPER_7413	0x7413
+-#define PCI_DEVICE_ID_AMD_VIPER_7414	0x7414
+-#define PCI_DEVICE_ID_AMD_OPUS_7440	0x7440
+-#	define PCI_DEVICE_ID_AMD_VIPER_7440	PCI_DEVICE_ID_AMD_OPUS_7440
++#define PCI_DEVICE_ID_AMD_VIPER_7440	0x7440
+ #define PCI_DEVICE_ID_AMD_OPUS_7441	0x7441
+-#	define PCI_DEVICE_ID_AMD_VIPER_7441	PCI_DEVICE_ID_AMD_OPUS_7441
+ #define PCI_DEVICE_ID_AMD_OPUS_7443	0x7443
+-#	define PCI_DEVICE_ID_AMD_VIPER_7443	PCI_DEVICE_ID_AMD_OPUS_7443
++#define PCI_DEVICE_ID_AMD_VIPER_7443	0x7443
+ #define PCI_DEVICE_ID_AMD_OPUS_7445	0x7445
+-#define PCI_DEVICE_ID_AMD_OPUS_7448	0x7448
+-# define	PCI_DEVICE_ID_AMD_VIPER_7448	PCI_DEVICE_ID_AMD_OPUS_7448
+-#define PCI_DEVICE_ID_AMD_OPUS_7449	0x7449
+-#	define PCI_DEVICE_ID_AMD_VIPER_7449	PCI_DEVICE_ID_AMD_OPUS_7449
+-#define PCI_DEVICE_ID_AMD_8111_LAN	0x7462
+ #define PCI_DEVICE_ID_AMD_8111_LPC	0x7468
+ #define PCI_DEVICE_ID_AMD_8111_IDE	0x7469
+ #define PCI_DEVICE_ID_AMD_8111_SMBUS2	0x746a
+@@ -585,7 +536,6 @@
+ #define PCI_DEVICE_ID_CT_65550		0x00e0
+ #define PCI_DEVICE_ID_CT_65554		0x00e4
+ #define PCI_DEVICE_ID_CT_65555		0x00e5
+-#define PCI_DEVICE_ID_CT_69000		0x00c0
+ 
+ #define PCI_VENDOR_ID_MIRO		0x1031
+ #define PCI_DEVICE_ID_MIRO_36050	0x5601
+@@ -639,7 +589,6 @@
+ #define PCI_DEVICE_ID_SI_550		0x0550
+ #define PCI_DEVICE_ID_SI_540_VGA	0x5300
+ #define PCI_DEVICE_ID_SI_550_VGA	0x5315
+-#define PCI_DEVICE_ID_SI_601		0x0601
+ #define PCI_DEVICE_ID_SI_620		0x0620
+ #define PCI_DEVICE_ID_SI_630		0x0630
+ #define PCI_DEVICE_ID_SI_633		0x0633
+@@ -650,30 +599,22 @@
+ #define PCI_DEVICE_ID_SI_648		0x0648
+ #define PCI_DEVICE_ID_SI_650		0x0650
+ #define PCI_DEVICE_ID_SI_651		0x0651
+-#define PCI_DEVICE_ID_SI_652		0x0652
+ #define PCI_DEVICE_ID_SI_655		0x0655
+ #define PCI_DEVICE_ID_SI_661		0x0661
+ #define PCI_DEVICE_ID_SI_730		0x0730
+ #define PCI_DEVICE_ID_SI_733		0x0733
+ #define PCI_DEVICE_ID_SI_630_VGA	0x6300
+-#define PCI_DEVICE_ID_SI_730_VGA	0x7300
+ #define PCI_DEVICE_ID_SI_735		0x0735
+ #define PCI_DEVICE_ID_SI_740		0x0740
+ #define PCI_DEVICE_ID_SI_741		0x0741
+ #define PCI_DEVICE_ID_SI_745		0x0745
+ #define PCI_DEVICE_ID_SI_746		0x0746
+-#define PCI_DEVICE_ID_SI_748		0x0748
+-#define PCI_DEVICE_ID_SI_750		0x0750
+-#define PCI_DEVICE_ID_SI_751		0x0751
+-#define PCI_DEVICE_ID_SI_752		0x0752
+ #define PCI_DEVICE_ID_SI_755		0x0755
+ #define PCI_DEVICE_ID_SI_760		0x0760
+ #define PCI_DEVICE_ID_SI_900		0x0900
+ #define PCI_DEVICE_ID_SI_961		0x0961
+ #define PCI_DEVICE_ID_SI_962		0x0962
+ #define PCI_DEVICE_ID_SI_963		0x0963
+-#define PCI_DEVICE_ID_SI_5107		0x5107
+-#define PCI_DEVICE_ID_SI_5300		0x5300
+ #define PCI_DEVICE_ID_SI_5511		0x5511
+ #define PCI_DEVICE_ID_SI_5513		0x5513
+ #define PCI_DEVICE_ID_SI_5518		0x5518
+@@ -685,10 +626,6 @@
+ #define PCI_DEVICE_ID_SI_5597		0x5597
+ #define PCI_DEVICE_ID_SI_5598		0x5598
+ #define PCI_DEVICE_ID_SI_5600		0x5600
+-#define PCI_DEVICE_ID_SI_6300		0x6300
+-#define PCI_DEVICE_ID_SI_6306		0x6306
+-#define PCI_DEVICE_ID_SI_6326		0x6326
+-#define PCI_DEVICE_ID_SI_7001		0x7001
+ #define PCI_DEVICE_ID_SI_7012		0x7012
+ #define PCI_DEVICE_ID_SI_7013		0x7013
+ #define PCI_DEVICE_ID_SI_7016		0x7016
+@@ -709,14 +646,11 @@
+ #define PCI_DEVICE_ID_HP_DIVA_TOSCA1	0x1049
+ #define PCI_DEVICE_ID_HP_DIVA_TOSCA2	0x104A
+ #define PCI_DEVICE_ID_HP_DIVA_MAESTRO	0x104B
+-#define PCI_DEVICE_ID_HP_PCI_LBA	0x1054
+-#define PCI_DEVICE_ID_HP_REO_SBA	0x10f0
+ #define PCI_DEVICE_ID_HP_REO_IOC	0x10f1
+ #define PCI_DEVICE_ID_HP_VISUALIZE_FXE	0x108b
+ #define PCI_DEVICE_ID_HP_DIVA_HALFDOME	0x1223
+ #define PCI_DEVICE_ID_HP_DIVA_KEYSTONE	0x1226
+ #define PCI_DEVICE_ID_HP_DIVA_POWERBAR	0x1227
+-#define PCI_DEVICE_ID_HP_ZX1_SBA	0x1229
+ #define PCI_DEVICE_ID_HP_ZX1_IOC	0x122a
+ #define PCI_DEVICE_ID_HP_PCIX_LBA	0x122e
+ #define PCI_DEVICE_ID_HP_SX1000_IOC	0x127c
+@@ -724,9 +658,7 @@
+ #define PCI_DEVICE_ID_HP_DIVA_AUX	0x1290
+ #define PCI_DEVICE_ID_HP_DIVA_RMP3	0x1301
+ #define PCI_DEVICE_ID_HP_DIVA_HURRICANE	0x132a
+-#define PCI_DEVICE_ID_HP_CISS		0x3210
+ #define PCI_DEVICE_ID_HP_CISSA		0x3220
+-#define PCI_DEVICE_ID_HP_CISSB		0x3222
+ #define PCI_DEVICE_ID_HP_CISSC		0x3230
+ #define PCI_DEVICE_ID_HP_CISSD		0x3238
+ #define PCI_DEVICE_ID_HP_ZX2_IOC	0x4031
+@@ -734,8 +666,6 @@
+ #define PCI_VENDOR_ID_PCTECH		0x1042
+ #define PCI_DEVICE_ID_PCTECH_RZ1000	0x1000
+ #define PCI_DEVICE_ID_PCTECH_RZ1001	0x1001
+-#define PCI_DEVICE_ID_PCTECH_SAMURAI_0	0x3000
+-#define PCI_DEVICE_ID_PCTECH_SAMURAI_1	0x3010
+ #define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020
+ 
+ #define PCI_VENDOR_ID_ASUSTEK		0x1043
+@@ -745,24 +675,15 @@
+ #define PCI_DEVICE_ID_DPT		0xa400
+ 
+ #define PCI_VENDOR_ID_OPTI		0x1045
+-#define PCI_DEVICE_ID_OPTI_92C178	0xc178
+-#define PCI_DEVICE_ID_OPTI_82C557	0xc557
+ #define PCI_DEVICE_ID_OPTI_82C558	0xc558
+ #define PCI_DEVICE_ID_OPTI_82C621	0xc621
+ #define PCI_DEVICE_ID_OPTI_82C700	0xc700
+-#define PCI_DEVICE_ID_OPTI_82C701	0xc701
+-#define PCI_DEVICE_ID_OPTI_82C814	0xc814
+-#define PCI_DEVICE_ID_OPTI_82C822	0xc822
+-#define PCI_DEVICE_ID_OPTI_82C861	0xc861
+ #define PCI_DEVICE_ID_OPTI_82C825	0xd568
+ 
+ #define PCI_VENDOR_ID_ELSA		0x1048
+ #define PCI_DEVICE_ID_ELSA_MICROLINK	0x1000
+ #define PCI_DEVICE_ID_ELSA_QS3000	0x3000
+ 
+-#define PCI_VENDOR_ID_SGS		0x104a
+-#define PCI_DEVICE_ID_SGS_2000		0x0008
+-#define PCI_DEVICE_ID_SGS_1764		0x0009
+ 
+ #define PCI_VENDOR_ID_BUSLOGIC		      0x104B
+ #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
+@@ -770,7 +691,6 @@
+ #define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT     0x8130
+ 
+ #define PCI_VENDOR_ID_TI		0x104c
+-#define PCI_DEVICE_ID_TI_TVP4010	0x3d04
+ #define PCI_DEVICE_ID_TI_TVP4020	0x3d07
+ #define PCI_DEVICE_ID_TI_4450		0x8011
+ #define PCI_DEVICE_ID_TI_XX21_XX11	0x8031
+@@ -804,14 +724,10 @@
+ #define PCI_DEVICE_ID_TI_X420		0xac8e
+ 
+ #define PCI_VENDOR_ID_SONY		0x104d
+-#define PCI_DEVICE_ID_SONY_CXD3222	0x8039
+ 
+-#define PCI_VENDOR_ID_OAK		0x104e
+-#define PCI_DEVICE_ID_OAK_OTI107	0x0107
+ 
+ /* Winbond have two vendor IDs! See 0x10ad as well */
+ #define PCI_VENDOR_ID_WINBOND2		0x1050
+-#define PCI_DEVICE_ID_WINBOND2_89C940	0x0940
+ #define PCI_DEVICE_ID_WINBOND2_89C940F	0x5a5a
+ #define PCI_DEVICE_ID_WINBOND2_6692	0x6692
+ 
+@@ -820,19 +736,15 @@
+   
+ #define PCI_VENDOR_ID_EFAR		0x1055
+ #define PCI_DEVICE_ID_EFAR_SLC90E66_1	0x9130
+-#define PCI_DEVICE_ID_EFAR_SLC90E66_0	0x9460
+-#define PCI_DEVICE_ID_EFAR_SLC90E66_2	0x9462
+ #define PCI_DEVICE_ID_EFAR_SLC90E66_3	0x9463
+ 
+ #define PCI_VENDOR_ID_MOTOROLA		0x1057
+-#define PCI_VENDOR_ID_MOTOROLA_OOPS	0x1507
+ #define PCI_DEVICE_ID_MOTOROLA_MPC105	0x0001
+ #define PCI_DEVICE_ID_MOTOROLA_MPC106	0x0002
+ #define PCI_DEVICE_ID_MOTOROLA_MPC107	0x0004
+ #define PCI_DEVICE_ID_MOTOROLA_RAVEN	0x4801
+ #define PCI_DEVICE_ID_MOTOROLA_FALCON	0x4802
+ #define PCI_DEVICE_ID_MOTOROLA_HAWK	0x4803
+-#define PCI_DEVICE_ID_MOTOROLA_CPX8216	0x4806
+ #define PCI_DEVICE_ID_MOTOROLA_HARRIER	0x480b
+ #define PCI_DEVICE_ID_MOTOROLA_MPC5200	0x5803
+ 
+@@ -843,33 +755,19 @@
+ #define PCI_DEVICE_ID_PROMISE_20262	0x4d38
+ #define PCI_DEVICE_ID_PROMISE_20263	0x0D38
+ #define PCI_DEVICE_ID_PROMISE_20268	0x4d68
+-#define PCI_DEVICE_ID_PROMISE_20268R	0x6268
+ #define PCI_DEVICE_ID_PROMISE_20269	0x4d69
+ #define PCI_DEVICE_ID_PROMISE_20270	0x6268
+ #define PCI_DEVICE_ID_PROMISE_20271	0x6269
+ #define PCI_DEVICE_ID_PROMISE_20275	0x1275
+ #define PCI_DEVICE_ID_PROMISE_20276	0x5275
+ #define PCI_DEVICE_ID_PROMISE_20277	0x7275
+-#define PCI_DEVICE_ID_PROMISE_5300	0x5300
+ 
+-#define PCI_VENDOR_ID_N9		0x105d
+-#define PCI_DEVICE_ID_N9_I128		0x2309
+-#define PCI_DEVICE_ID_N9_I128_2		0x2339
+-#define PCI_DEVICE_ID_N9_I128_T2R	0x493d
+ 
+ #define PCI_VENDOR_ID_UMC		0x1060
+ #define PCI_DEVICE_ID_UMC_UM8673F	0x0101
+-#define PCI_DEVICE_ID_UMC_UM8891A	0x0891
+ #define PCI_DEVICE_ID_UMC_UM8886BF	0x673a
+ #define PCI_DEVICE_ID_UMC_UM8886A	0x886a
+-#define PCI_DEVICE_ID_UMC_UM8881F	0x8881
+-#define PCI_DEVICE_ID_UMC_UM8886F	0x8886
+-#define PCI_DEVICE_ID_UMC_UM9017F	0x9017
+-#define PCI_DEVICE_ID_UMC_UM8886N	0xe886
+-#define PCI_DEVICE_ID_UMC_UM8891N	0xe891
+ 
+-#define PCI_VENDOR_ID_X			0x1061
+-#define PCI_DEVICE_ID_X_AGX016		0x0001
+ 
+ #define PCI_VENDOR_ID_MYLEX		0x1069
+ #define PCI_DEVICE_ID_MYLEX_DAC960_P	0x0001
+@@ -880,37 +778,26 @@
+ #define PCI_DEVICE_ID_MYLEX_DAC960_BA	0xBA56
+ #define PCI_DEVICE_ID_MYLEX_DAC960_GEM	0xB166
+ 
+-#define PCI_VENDOR_ID_PICOP		0x1066
+-#define PCI_DEVICE_ID_PICOP_PT86C52X	0x0001
+-#define PCI_DEVICE_ID_PICOP_PT80C524	0x8002
+ 
+ #define PCI_VENDOR_ID_APPLE		0x106b
+ #define PCI_DEVICE_ID_APPLE_BANDIT	0x0001
+-#define PCI_DEVICE_ID_APPLE_GC		0x0002
+ #define PCI_DEVICE_ID_APPLE_HYDRA	0x000e
+ #define PCI_DEVICE_ID_APPLE_UNI_N_FW	0x0018
+-#define PCI_DEVICE_ID_APPLE_KL_USB	0x0019
+ #define PCI_DEVICE_ID_APPLE_UNI_N_AGP	0x0020
+ #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC	0x0021
+-#define PCI_DEVICE_ID_APPLE_KEYLARGO	0x0022
+ #define PCI_DEVICE_ID_APPLE_UNI_N_GMACP	0x0024
+-#define PCI_DEVICE_ID_APPLE_KEYLARGO_P	0x0025
+-#define PCI_DEVICE_ID_APPLE_KL_USB_P	0x0026
+ #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P	0x0027
+ #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15	0x002d
+ #define PCI_DEVICE_ID_APPLE_UNI_N_PCI15	0x002e
+-#define PCI_DEVICE_ID_APPLE_UNI_N_FW2	0x0030
+ #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2	0x0032
+ #define PCI_DEVICE_ID_APPLE_UNI_N_ATA	0x0033
+ #define PCI_DEVICE_ID_APPLE_UNI_N_AGP2	0x0034
+ #define PCI_DEVICE_ID_APPLE_IPID_ATA100	0x003b
+-#define PCI_DEVICE_ID_APPLE_KEYLARGO_I	0x003e
+ #define PCI_DEVICE_ID_APPLE_K2_ATA100	0x0043
+ #define PCI_DEVICE_ID_APPLE_U3_AGP	0x004b
+ #define PCI_DEVICE_ID_APPLE_K2_GMAC	0x004c
+ #define PCI_DEVICE_ID_APPLE_SH_ATA      0x0050
+ #define PCI_DEVICE_ID_APPLE_SH_SUNGEM   0x0051
+-#define PCI_DEVICE_ID_APPLE_SH_FW       0x0052
+ #define PCI_DEVICE_ID_APPLE_U3L_AGP	0x0058
+ #define PCI_DEVICE_ID_APPLE_U3H_AGP	0x0059
+ #define PCI_DEVICE_ID_APPLE_TIGON3	0x1645
+@@ -923,12 +810,9 @@
+ #define PCI_DEVICE_ID_YAMAHA_744	0x0010
+ #define PCI_DEVICE_ID_YAMAHA_754	0x0012
+ 
+-#define PCI_VENDOR_ID_NEXGEN		0x1074
+-#define PCI_DEVICE_ID_NEXGEN_82C501	0x4e78
+ 
+ #define PCI_VENDOR_ID_QLOGIC		0x1077
+ #define PCI_DEVICE_ID_QLOGIC_ISP1020	0x1020
+-#define PCI_DEVICE_ID_QLOGIC_ISP1022	0x1022
+ #define PCI_DEVICE_ID_QLOGIC_ISP2100	0x2100
+ #define PCI_DEVICE_ID_QLOGIC_ISP2200	0x2200
+ #define PCI_DEVICE_ID_QLOGIC_ISP2300	0x2300
+@@ -946,32 +830,20 @@
+ #define PCI_DEVICE_ID_CYRIX_PCI_MASTER	0x0001
+ #define PCI_DEVICE_ID_CYRIX_5520	0x0002
+ #define PCI_DEVICE_ID_CYRIX_5530_LEGACY	0x0100
+-#define PCI_DEVICE_ID_CYRIX_5530_SMI	0x0101
+ #define PCI_DEVICE_ID_CYRIX_5530_IDE	0x0102
+ #define PCI_DEVICE_ID_CYRIX_5530_AUDIO	0x0103
+ #define PCI_DEVICE_ID_CYRIX_5530_VIDEO	0x0104
+ 
+-#define PCI_VENDOR_ID_LEADTEK		0x107d
+-#define PCI_DEVICE_ID_LEADTEK_805	0x0000
+ 
+-#define PCI_VENDOR_ID_INTERPHASE	0x107e
+-#define PCI_DEVICE_ID_INTERPHASE_5526	0x0004
+-#define PCI_DEVICE_ID_INTERPHASE_55x6	0x0005
+-#define PCI_DEVICE_ID_INTERPHASE_5575	0x0008
+ 
+ #define PCI_VENDOR_ID_CONTAQ		0x1080
+-#define PCI_DEVICE_ID_CONTAQ_82C599	0x0600
+ #define PCI_DEVICE_ID_CONTAQ_82C693	0xc693
+ 
+-#define PCI_VENDOR_ID_FOREX		0x1083
+ 
+ #define PCI_VENDOR_ID_OLICOM		0x108d
+-#define PCI_DEVICE_ID_OLICOM_OC3136	0x0001
+-#define PCI_DEVICE_ID_OLICOM_OC2315	0x0011
+ #define PCI_DEVICE_ID_OLICOM_OC2325	0x0012
+ #define PCI_DEVICE_ID_OLICOM_OC2183	0x0013
+ #define PCI_DEVICE_ID_OLICOM_OC2326	0x0014
+-#define PCI_DEVICE_ID_OLICOM_OC6151	0x0021
+ 
+ #define PCI_VENDOR_ID_SUN		0x108e
+ #define PCI_DEVICE_ID_SUN_EBUS		0x1000
+@@ -990,49 +862,31 @@
+ #define PCI_DEVICE_ID_SUN_CASSINI	0xabba
+ 
+ #define PCI_VENDOR_ID_CMD		0x1095
+-#define PCI_DEVICE_ID_CMD_640		0x0640
+ #define PCI_DEVICE_ID_CMD_643		0x0643
+ #define PCI_DEVICE_ID_CMD_646		0x0646
+-#define PCI_DEVICE_ID_CMD_647		0x0647
+ #define PCI_DEVICE_ID_CMD_648		0x0648
+ #define PCI_DEVICE_ID_CMD_649		0x0649
+-#define PCI_DEVICE_ID_CMD_670		0x0670
+-#define PCI_DEVICE_ID_CMD_680		0x0680
+ 
+ #define PCI_DEVICE_ID_SII_680		0x0680
+ #define PCI_DEVICE_ID_SII_3112		0x3112
+ #define PCI_DEVICE_ID_SII_1210SA	0x0240
+ 
+-#define PCI_VENDOR_ID_VISION		0x1098
+-#define PCI_DEVICE_ID_VISION_QD8500	0x0001
+-#define PCI_DEVICE_ID_VISION_QD8580	0x0002
+ 
+ #define PCI_VENDOR_ID_BROOKTREE		0x109e
+-#define PCI_DEVICE_ID_BROOKTREE_848	0x0350
+-#define PCI_DEVICE_ID_BROOKTREE_849A	0x0351
+-#define PCI_DEVICE_ID_BROOKTREE_878_1	0x036e
+ #define PCI_DEVICE_ID_BROOKTREE_878	0x0878
+ #define PCI_DEVICE_ID_BROOKTREE_879	0x0879
+-#define PCI_DEVICE_ID_BROOKTREE_8474	0x8474
+ 
+-#define PCI_VENDOR_ID_SIERRA		0x10a8
+-#define PCI_DEVICE_ID_SIERRA_STB	0x0000
+ 
+ #define PCI_VENDOR_ID_SGI		0x10a9
+ #define PCI_DEVICE_ID_SGI_IOC3		0x0003
+ #define PCI_DEVICE_ID_SGI_IOC4		0x100a
+ #define PCI_VENDOR_ID_SGI_LITHIUM	0x1002
+ 
+-#define PCI_VENDOR_ID_ACC		0x10aa
+-#define PCI_DEVICE_ID_ACC_2056		0x0000
+ 
+ #define PCI_VENDOR_ID_WINBOND		0x10ad
+-#define PCI_DEVICE_ID_WINBOND_83769	0x0001
+ #define PCI_DEVICE_ID_WINBOND_82C105	0x0105
+ #define PCI_DEVICE_ID_WINBOND_83C553	0x0565
+ 
+-#define PCI_VENDOR_ID_DATABOOK		0x10b3
+-#define PCI_DEVICE_ID_DATABOOK_87144	0xb106
+ 
+ #define PCI_VENDOR_ID_PLX		0x10b5
+ #define PCI_DEVICE_ID_PLX_R685		0x1030
+@@ -1043,33 +897,19 @@
+ #define PCI_DEVICE_ID_PLX_DJINN_ITOO	0x1151
+ #define PCI_DEVICE_ID_PLX_R753		0x1152
+ #define PCI_DEVICE_ID_PLX_OLITEC	0x1187
+-#define PCI_DEVICE_ID_PLX_9030		0x9030
+ #define PCI_DEVICE_ID_PLX_9050		0x9050
+-#define PCI_DEVICE_ID_PLX_9060		0x9060
+-#define PCI_DEVICE_ID_PLX_9060ES	0x906E
+-#define PCI_DEVICE_ID_PLX_9060SD	0x906D
+ #define PCI_DEVICE_ID_PLX_9080		0x9080
+ #define PCI_DEVICE_ID_PLX_GTEK_SERIAL2	0xa001
+ 
+ #define PCI_VENDOR_ID_MADGE		0x10b6
+ #define PCI_DEVICE_ID_MADGE_MK2		0x0002
+-#define PCI_DEVICE_ID_MADGE_C155S	0x1001
+ 
+ #define PCI_VENDOR_ID_3COM		0x10b7
+ #define PCI_DEVICE_ID_3COM_3C985	0x0001
+ #define PCI_DEVICE_ID_3COM_3C940	0x1700
+ #define PCI_DEVICE_ID_3COM_3C339	0x3390
+ #define PCI_DEVICE_ID_3COM_3C359	0x3590
+-#define PCI_DEVICE_ID_3COM_3C590	0x5900
+-#define PCI_DEVICE_ID_3COM_3C595TX	0x5950
+-#define PCI_DEVICE_ID_3COM_3C595T4	0x5951
+-#define PCI_DEVICE_ID_3COM_3C595MII	0x5952
+ #define PCI_DEVICE_ID_3COM_3C940B	0x80eb
+-#define PCI_DEVICE_ID_3COM_3C900TPO	0x9000
+-#define PCI_DEVICE_ID_3COM_3C900COMBO	0x9001
+-#define PCI_DEVICE_ID_3COM_3C905TX	0x9050
+-#define PCI_DEVICE_ID_3COM_3C905T4	0x9051
+-#define PCI_DEVICE_ID_3COM_3C905B_TX	0x9055
+ #define PCI_DEVICE_ID_3COM_3CR990	0x9900
+ #define PCI_DEVICE_ID_3COM_3CR990_TX_95	0x9902
+ #define PCI_DEVICE_ID_3COM_3CR990_TX_97	0x9903
+@@ -1079,24 +919,11 @@
+ #define PCI_DEVICE_ID_3COM_3CR990SVR97	0x9909
+ #define PCI_DEVICE_ID_3COM_3CR990SVR	0x990a
+ 
+-#define PCI_VENDOR_ID_SMC		0x10b8
+-#define PCI_DEVICE_ID_SMC_EPIC100	0x0005
+ 
+ #define PCI_VENDOR_ID_AL		0x10b9
+-#define PCI_DEVICE_ID_AL_M1445		0x1445
+-#define PCI_DEVICE_ID_AL_M1449		0x1449
+-#define PCI_DEVICE_ID_AL_M1451		0x1451
+-#define PCI_DEVICE_ID_AL_M1461		0x1461
+-#define PCI_DEVICE_ID_AL_M1489		0x1489
+-#define PCI_DEVICE_ID_AL_M1511		0x1511
+-#define PCI_DEVICE_ID_AL_M1513		0x1513
+-#define PCI_DEVICE_ID_AL_M1521		0x1521
+-#define PCI_DEVICE_ID_AL_M1523		0x1523
+-#define PCI_DEVICE_ID_AL_M1531		0x1531
+ #define PCI_DEVICE_ID_AL_M1533		0x1533
+ #define PCI_DEVICE_ID_AL_M1535 		0x1535
+ #define PCI_DEVICE_ID_AL_M1541		0x1541
+-#define PCI_DEVICE_ID_AL_M1543		0x1543
+ #define PCI_DEVICE_ID_AL_M1563		0x1563
+ #define PCI_DEVICE_ID_AL_M1621		0x1621
+ #define PCI_DEVICE_ID_AL_M1631		0x1631
+@@ -1109,49 +936,23 @@
+ #define PCI_DEVICE_ID_AL_M1681		0x1681
+ #define PCI_DEVICE_ID_AL_M1683		0x1683
+ #define PCI_DEVICE_ID_AL_M1689		0x1689
+-#define PCI_DEVICE_ID_AL_M3307		0x3307
+-#define PCI_DEVICE_ID_AL_M4803		0x5215
+ #define PCI_DEVICE_ID_AL_M5219		0x5219
+ #define PCI_DEVICE_ID_AL_M5228		0x5228
+ #define PCI_DEVICE_ID_AL_M5229		0x5229
+-#define PCI_DEVICE_ID_AL_M5237		0x5237
+-#define PCI_DEVICE_ID_AL_M5243		0x5243
+ #define PCI_DEVICE_ID_AL_M5451		0x5451
+ #define PCI_DEVICE_ID_AL_M7101		0x7101
+ 
+-#define PCI_VENDOR_ID_MITSUBISHI	0x10ba
+ 
+-#define PCI_VENDOR_ID_SURECOM		0x10bd
+-#define PCI_DEVICE_ID_SURECOM_NE34	0x0e34
+ 
+ #define PCI_VENDOR_ID_NEOMAGIC		0x10c8
+-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001
+-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002
+-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003
+-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
+-#define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV       0x0005
+-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS   0x0083
+ #define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
+ #define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
+ #define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
+ 
+-#define PCI_VENDOR_ID_ASP		0x10cd
+-#define PCI_DEVICE_ID_ASP_ABP940	0x1200
+-#define PCI_DEVICE_ID_ASP_ABP940U	0x1300
+-#define PCI_DEVICE_ID_ASP_ABP940UW	0x2300
+-
+-#define PCI_VENDOR_ID_MACRONIX		0x10d9
+-#define PCI_DEVICE_ID_MACRONIX_MX98713	0x0512
+-#define PCI_DEVICE_ID_MACRONIX_MX987x5	0x0531
+ 
+ #define PCI_VENDOR_ID_TCONRAD		0x10da
+ #define PCI_DEVICE_ID_TCONRAD_TOKENRING	0x0508
+ 
+-#define PCI_VENDOR_ID_CERN		0x10dc
+-#define PCI_DEVICE_ID_CERN_SPSB_PMC	0x0001
+-#define PCI_DEVICE_ID_CERN_SPSB_PCI	0x0002
+-#define PCI_DEVICE_ID_CERN_HIPPI_DST	0x0021
+-#define PCI_DEVICE_ID_CERN_HIPPI_SRC	0x0022
+ 
+ #define PCI_VENDOR_ID_NVIDIA			0x10de
+ #define PCI_DEVICE_ID_NVIDIA_TNT		0x0020
+@@ -1197,7 +998,6 @@
+ #define PCI_DEVICE_ID_QUADRO_FX_GO1400          0x00cc
+ #define PCI_DEVICE_ID_QUADRO_FX_1400            0x00ce
+ #define PCI_DEVICE_ID_NVIDIA_NFORCE3		0x00d1
+-#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO		0x00da
+ #define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS	0x00d4
+ #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE	0x00d5
+ #define PCI_DEVICE_ID_NVIDIA_NVENET_3		0x00d6
+@@ -1284,7 +1084,6 @@
+ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2	0x037F
+ #define PCI_DEVICE_ID_NVIDIA_NVENET_12		0x0268
+ #define PCI_DEVICE_ID_NVIDIA_NVENET_13		0x0269
+-#define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO	0x026B
+ #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800	0x0280
+ #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X    0x0281
+ #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE     0x0282
+@@ -1335,24 +1134,13 @@
+ #define PCI_DEVICE_ID_NVIDIA_NVENET_15              0x0373
+ 
+ #define PCI_VENDOR_ID_IMS		0x10e0
+-#define PCI_DEVICE_ID_IMS_8849		0x8849
+ #define PCI_DEVICE_ID_IMS_TT128		0x9128
+ #define PCI_DEVICE_ID_IMS_TT3D		0x9135
+ 
+-#define PCI_VENDOR_ID_TEKRAM2		0x10e1
+-#define PCI_DEVICE_ID_TEKRAM2_690c	0x690c
+ 
+-#define PCI_VENDOR_ID_TUNDRA		0x10e3
+-#define PCI_DEVICE_ID_TUNDRA_CA91C042	0x0000
+ 
+-#define PCI_VENDOR_ID_AMCC		0x10e8
+-#define PCI_DEVICE_ID_AMCC_MYRINET	0x8043
+-#define PCI_DEVICE_ID_AMCC_PARASTATION	0x8062
+-#define PCI_DEVICE_ID_AMCC_S5933	0x807d
+-#define PCI_DEVICE_ID_AMCC_S5933_HEPC3	0x809c
+ 
+ #define PCI_VENDOR_ID_INTERG		0x10ea
+-#define PCI_DEVICE_ID_INTERG_1680	0x1680
+ #define PCI_DEVICE_ID_INTERG_1682	0x1682
+ #define PCI_DEVICE_ID_INTERG_2000	0x2000
+ #define PCI_DEVICE_ID_INTERG_2010	0x2010
+@@ -1360,32 +1148,23 @@
+ #define PCI_DEVICE_ID_INTERG_5050	0x5050
+ 
+ #define PCI_VENDOR_ID_REALTEK		0x10ec
+-#define PCI_DEVICE_ID_REALTEK_8029	0x8029
+-#define PCI_DEVICE_ID_REALTEK_8129	0x8129
+ #define PCI_DEVICE_ID_REALTEK_8139	0x8139
+-#define PCI_DEVICE_ID_REALTEK_8169	0x8169
+ 
+ #define PCI_VENDOR_ID_XILINX		0x10ee
+ #define PCI_DEVICE_ID_RME_DIGI96	0x3fc0
+ #define PCI_DEVICE_ID_RME_DIGI96_8	0x3fc1
+ #define PCI_DEVICE_ID_RME_DIGI96_8_PRO	0x3fc2
+ #define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3
+-#define PCI_DEVICE_ID_XILINX_HAMMERFALL	0x3fc4
+ #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
+ #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
+-#define PCI_DEVICE_ID_TURBOPAM		0x4020
+ 
+-#define PCI_VENDOR_ID_TRUEVISION	0x10fa
+-#define PCI_DEVICE_ID_TRUEVISION_T1000	0x000c
+ 
+ #define PCI_VENDOR_ID_INIT		0x1101
+-#define PCI_DEVICE_ID_INIT_320P		0x9100
+-#define PCI_DEVICE_ID_INIT_360P		0x9500
+ 
+-#define PCI_VENDOR_ID_CREATIVE		0x1102 // duplicate: ECTIVA
++#define PCI_VENDOR_ID_CREATIVE		0x1102 /* duplicate: ECTIVA */
+ #define PCI_DEVICE_ID_CREATIVE_EMU10K1	0x0002
+ 
+-#define PCI_VENDOR_ID_ECTIVA		0x1102 // duplicate: CREATIVE
++#define PCI_VENDOR_ID_ECTIVA		0x1102 /* duplicate: CREATIVE */
+ #define PCI_DEVICE_ID_ECTIVA_EV1938	0x8938
+ 
+ #define PCI_VENDOR_ID_TTI		0x1103
+@@ -1395,7 +1174,7 @@
+ #define PCI_DEVICE_ID_TTI_HPT302	0x0006
+ #define PCI_DEVICE_ID_TTI_HPT371	0x0007
+ #define PCI_DEVICE_ID_TTI_HPT374	0x0008
+-#define PCI_DEVICE_ID_TTI_HPT372N	0x0009	// apparently a 372N variant?
++#define PCI_DEVICE_ID_TTI_HPT372N	0x0009	/* apparently a 372N variant? */
+ 
+ #define PCI_VENDOR_ID_VIA		0x1106
+ #define PCI_DEVICE_ID_VIA_8763_0	0x0198
+@@ -1408,36 +1187,25 @@
+ #define PCI_DEVICE_ID_VIA_8363_0	0x0305
+ #define PCI_DEVICE_ID_VIA_8371_0	0x0391
+ #define PCI_DEVICE_ID_VIA_8501_0	0x0501
+-#define PCI_DEVICE_ID_VIA_82C505	0x0505
+ #define PCI_DEVICE_ID_VIA_82C561	0x0561
+ #define PCI_DEVICE_ID_VIA_82C586_1	0x0571
+ #define PCI_DEVICE_ID_VIA_82C576	0x0576
+-#define PCI_DEVICE_ID_VIA_82C585	0x0585
+ #define PCI_DEVICE_ID_VIA_82C586_0	0x0586
+-#define PCI_DEVICE_ID_VIA_82C595	0x0595
+ #define PCI_DEVICE_ID_VIA_82C596	0x0596
+ #define PCI_DEVICE_ID_VIA_82C597_0	0x0597
+ #define PCI_DEVICE_ID_VIA_82C598_0	0x0598
+ #define PCI_DEVICE_ID_VIA_8601_0	0x0601
+ #define PCI_DEVICE_ID_VIA_8605_0	0x0605
+-#define PCI_DEVICE_ID_VIA_82C680	0x0680
+ #define PCI_DEVICE_ID_VIA_82C686	0x0686
+ #define PCI_DEVICE_ID_VIA_82C691_0	0x0691
+-#define PCI_DEVICE_ID_VIA_82C693	0x0693
+-#define PCI_DEVICE_ID_VIA_82C693_1	0x0698
+-#define PCI_DEVICE_ID_VIA_82C926	0x0926
+ #define PCI_DEVICE_ID_VIA_82C576_1	0x1571
+-#define PCI_DEVICE_ID_VIA_82C595_97	0x1595
+ #define PCI_DEVICE_ID_VIA_82C586_2	0x3038
+ #define PCI_DEVICE_ID_VIA_82C586_3	0x3040
+-#define PCI_DEVICE_ID_VIA_6305		0x3044
+ #define PCI_DEVICE_ID_VIA_82C596_3	0x3050
+ #define PCI_DEVICE_ID_VIA_82C596B_3	0x3051
+ #define PCI_DEVICE_ID_VIA_82C686_4	0x3057
+ #define PCI_DEVICE_ID_VIA_82C686_5	0x3058
+ #define PCI_DEVICE_ID_VIA_8233_5	0x3059
+-#define PCI_DEVICE_ID_VIA_8233_7	0x3065
+-#define PCI_DEVICE_ID_VIA_82C686_6	0x3068
+ #define PCI_DEVICE_ID_VIA_8233_0	0x3074
+ #define PCI_DEVICE_ID_VIA_8633_0	0x3091
+ #define PCI_DEVICE_ID_VIA_8367_0	0x3099
+@@ -1455,38 +1223,23 @@
+ #define PCI_DEVICE_ID_VIA_XN266		0x3156
+ #define PCI_DEVICE_ID_VIA_8754C_0	0x3168
+ #define PCI_DEVICE_ID_VIA_8235		0x3177
+-#define PCI_DEVICE_ID_VIA_P4N333	0x3178
+ #define PCI_DEVICE_ID_VIA_8385_0	0x3188
+ #define PCI_DEVICE_ID_VIA_8377_0	0x3189
+ #define PCI_DEVICE_ID_VIA_8378_0	0x3205
+ #define PCI_DEVICE_ID_VIA_8783_0	0x3208
+-#define PCI_DEVICE_ID_VIA_P4M400	0x3209
+ #define PCI_DEVICE_ID_VIA_8237		0x3227
+ #define PCI_DEVICE_ID_VIA_3296_0	0x0296
+-#define PCI_DEVICE_ID_VIA_86C100A	0x6100
+ #define PCI_DEVICE_ID_VIA_8231		0x8231
+ #define PCI_DEVICE_ID_VIA_8231_4	0x8235
+ #define PCI_DEVICE_ID_VIA_8365_1	0x8305
+ #define PCI_DEVICE_ID_VIA_8371_1	0x8391
+-#define PCI_DEVICE_ID_VIA_8501_1	0x8501
+-#define PCI_DEVICE_ID_VIA_82C597_1	0x8597
+ #define PCI_DEVICE_ID_VIA_82C598_1	0x8598
+-#define PCI_DEVICE_ID_VIA_8601_1	0x8601
+-#define PCI_DEVICE_ID_VIA_8505_1	0x8605
+-#define PCI_DEVICE_ID_VIA_8633_1	0xB091
+-#define PCI_DEVICE_ID_VIA_8367_1	0xB099
+-#define PCI_DEVICE_ID_VIA_P4X266_1	0xB101
+-#define PCI_DEVICE_ID_VIA_8615_1	0xB103
+-#define PCI_DEVICE_ID_VIA_8361_1	0xB112
+-#define PCI_DEVICE_ID_VIA_8235_1	0xB168
+ #define PCI_DEVICE_ID_VIA_838X_1	0xB188
+ #define PCI_DEVICE_ID_VIA_83_87XX_1	0xB198
+ 
+ #define PCI_VENDOR_ID_SIEMENS           0x110A
+ #define PCI_DEVICE_ID_SIEMENS_DSCC4     0x2102
+ 
+-#define PCI_VENDOR_ID_SMC2		0x1113
+-#define PCI_DEVICE_ID_SMC2_1211TX	0x1211
+ 
+ #define PCI_VENDOR_ID_VORTEX		0x1119
+ #define PCI_DEVICE_ID_VORTEX_GDT60x0	0x0000
+@@ -1509,18 +1262,6 @@
+ #define PCI_DEVICE_ID_VORTEX_GDT6557RP	0x0103
+ #define PCI_DEVICE_ID_VORTEX_GDT6x11RP	0x0104
+ #define PCI_DEVICE_ID_VORTEX_GDT6x21RP	0x0105
+-#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1	0x0110
+-#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1	0x0111
+-#define PCI_DEVICE_ID_VORTEX_GDT6537RP1	0x0112
+-#define PCI_DEVICE_ID_VORTEX_GDT6557RP1	0x0113
+-#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1	0x0114
+-#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1	0x0115
+-#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2	0x0120
+-#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2	0x0121
+-#define PCI_DEVICE_ID_VORTEX_GDT6537RP2	0x0122
+-#define PCI_DEVICE_ID_VORTEX_GDT6557RP2	0x0123
+-#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2	0x0124
+-#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2	0x0125
+ 
+ #define PCI_VENDOR_ID_EF		0x111a
+ #define PCI_DEVICE_ID_EF_ATM_FPGA	0x0000
+@@ -1532,21 +1273,15 @@
+ #define PCI_DEVICE_ID_IDT_IDT77201	0x0001
+ 
+ #define PCI_VENDOR_ID_FORE		0x1127
+-#define PCI_DEVICE_ID_FORE_PCA200PC	0x0210
+ #define PCI_DEVICE_ID_FORE_PCA200E	0x0300
+ 
+-#define PCI_VENDOR_ID_IMAGINGTECH	0x112f
+-#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI	0x0000
+ 
+ #define PCI_VENDOR_ID_PHILIPS		0x1131
+-#define PCI_DEVICE_ID_PHILIPS_SAA7145	0x7145
+ #define PCI_DEVICE_ID_PHILIPS_SAA7146	0x7146
+ #define PCI_DEVICE_ID_PHILIPS_SAA9730	0x9730
+ 
+ #define PCI_VENDOR_ID_EICON		0x1133
+-#define PCI_DEVICE_ID_EICON_DIVA20PRO	0xe001
+ #define PCI_DEVICE_ID_EICON_DIVA20	0xe002
+-#define PCI_DEVICE_ID_EICON_DIVA20PRO_U	0xe003
+ #define PCI_DEVICE_ID_EICON_DIVA20_U	0xe004
+ #define PCI_DEVICE_ID_EICON_DIVA201	0xe005
+ #define PCI_DEVICE_ID_EICON_DIVA202	0xe00b
+@@ -1558,35 +1293,17 @@
+ #define PCI_VENDOR_ID_ZIATECH		0x1138
+ #define PCI_DEVICE_ID_ZIATECH_5550_HC	0x5550
+  
+-#define PCI_VENDOR_ID_CYCLONE		0x113c
+-#define PCI_DEVICE_ID_CYCLONE_SDK	0x0001
+ 
+-#define PCI_VENDOR_ID_ALLIANCE		0x1142
+-#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO	0x3210
+-#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO	0x6422
+-#define PCI_DEVICE_ID_ALLIANCE_AT24	0x6424
+-#define PCI_DEVICE_ID_ALLIANCE_AT3D	0x643d
+ 
+ #define PCI_VENDOR_ID_SYSKONNECT	0x1148
+-#define PCI_DEVICE_ID_SYSKONNECT_FP	0x4000
+ #define PCI_DEVICE_ID_SYSKONNECT_TR	0x4200
+ #define PCI_DEVICE_ID_SYSKONNECT_GE	0x4300
+ #define PCI_DEVICE_ID_SYSKONNECT_YU	0x4320
+ #define PCI_DEVICE_ID_SYSKONNECT_9DXX	0x4400
+ #define PCI_DEVICE_ID_SYSKONNECT_9MXX	0x4500
+ 
+-#define PCI_VENDOR_ID_VMIC		0x114a
+-#define PCI_DEVICE_ID_VMIC_VME		0x7587
+ 
+ #define PCI_VENDOR_ID_DIGI		0x114f
+-#define PCI_DEVICE_ID_DIGI_EPC		0x0002
+-#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH	0x0003
+-#define PCI_DEVICE_ID_DIGI_XEM		0x0004
+-#define PCI_DEVICE_ID_DIGI_XR		0x0005
+-#define PCI_DEVICE_ID_DIGI_CX		0x0006
+-#define PCI_DEVICE_ID_DIGI_XRJ		0x0009
+-#define PCI_DEVICE_ID_DIGI_EPCJ		0x000a
+-#define PCI_DEVICE_ID_DIGI_XR_920	0x0027
+ #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E	0x0070
+ #define PCI_DEVICE_ID_DIGI_DF_M_E	0x0071
+ #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A	0x0072
+@@ -1596,23 +1313,15 @@
+ #define PCI_DEVICE_ID_NEO_2RJ45         0x00CA
+ #define PCI_DEVICE_ID_NEO_2RJ45PRI      0x00CB
+ 
+-#define PCI_VENDOR_ID_MUTECH		0x1159
+-#define PCI_DEVICE_ID_MUTECH_MV1000	0x0001
+ 
+ #define PCI_VENDOR_ID_XIRCOM		0x115d
+-#define PCI_DEVICE_ID_XIRCOM_X3201_ETH	0x0003
+ #define PCI_DEVICE_ID_XIRCOM_RBM56G	0x0101
+ #define PCI_DEVICE_ID_XIRCOM_X3201_MDM	0x0103
+ 
+-#define PCI_VENDOR_ID_RENDITION		0x1163
+-#define PCI_DEVICE_ID_RENDITION_VERITE	0x0001
+-#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000
+ 
+ #define PCI_VENDOR_ID_SERVERWORKS	  0x1166
+ #define PCI_DEVICE_ID_SERVERWORKS_HE	  0x0008
+ #define PCI_DEVICE_ID_SERVERWORKS_LE	  0x0009
+-#define PCI_DEVICE_ID_SERVERWORKS_CIOB30  0x0010
+-#define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011
+ #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
+ #define PCI_DEVICE_ID_SERVERWORKS_OSB4	  0x0200
+ #define PCI_DEVICE_ID_SERVERWORKS_CSB5	  0x0201
+@@ -1622,13 +1331,7 @@
+ #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213
+ #define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214
+ #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217
+-#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
+-#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
+-#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221
+ #define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227
+-#define PCI_DEVICE_ID_SERVERWORKS_GCLE    0x0225
+-#define PCI_DEVICE_ID_SERVERWORKS_GCLE2   0x0227
+-#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
+ 
+ #define PCI_VENDOR_ID_SBE		0x1176
+ #define PCI_DEVICE_ID_SBE_WANXL100	0x0301
+@@ -1639,17 +1342,12 @@
+ #define PCI_DEVICE_ID_TOSHIBA_PICCOLO	0x0102
+ #define PCI_DEVICE_ID_TOSHIBA_PICCOLO_1	0x0103
+ #define PCI_DEVICE_ID_TOSHIBA_PICCOLO_2	0x0105
+-#define PCI_DEVICE_ID_TOSHIBA_601	0x0601
+ #define PCI_DEVICE_ID_TOSHIBA_TOPIC95	0x060a
+-#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_A 0x0603
+-#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_B 0x060a
+ #define PCI_DEVICE_ID_TOSHIBA_TOPIC97	0x060f
+ #define PCI_DEVICE_ID_TOSHIBA_TOPIC100	0x0617
+ 
+ #define PCI_VENDOR_ID_TOSHIBA_2		0x102f
+-#define PCI_DEVICE_ID_TOSHIBA_TX3927	0x000a
+ #define PCI_DEVICE_ID_TOSHIBA_TC35815CF	0x0030
+-#define PCI_DEVICE_ID_TOSHIBA_TX4927	0x0180
+ #define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC	0x0108
+ #define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3
+ 
+@@ -1664,7 +1362,6 @@
+ #define PCI_DEVICE_ID_DLINK_DGE510T	0x4c00
+ 
+ #define PCI_VENDOR_ID_ARTOP		0x1191
+-#define PCI_DEVICE_ID_ARTOP_ATP8400	0x0004
+ #define PCI_DEVICE_ID_ARTOP_ATP850UF	0x0005
+ #define PCI_DEVICE_ID_ARTOP_ATP860	0x0006
+ #define PCI_DEVICE_ID_ARTOP_ATP860R	0x0007
+@@ -1677,16 +1374,11 @@
+ #define PCI_DEVICE_ID_ARTOP_AEC7612D	0x8040
+ #define PCI_DEVICE_ID_ARTOP_AEC7612SUW	0x8050
+ #define PCI_DEVICE_ID_ARTOP_8060	0x8060
+-#define PCI_DEVICE_ID_ARTOP_AEC67160	0x8080
+-#define PCI_DEVICE_ID_ARTOP_AEC67160_2	0x8081
+-#define PCI_DEVICE_ID_ARTOP_AEC67162	0x808a
+ 
+ #define PCI_VENDOR_ID_ZEITNET		0x1193
+ #define PCI_DEVICE_ID_ZEITNET_1221	0x0001
+ #define PCI_DEVICE_ID_ZEITNET_1225	0x0002
+ 
+-#define PCI_VENDOR_ID_OMEGA		0x119b
+-#define PCI_DEVICE_ID_OMEGA_82C092G	0x1221
+ 
+ #define PCI_VENDOR_ID_FUJITSU_ME	0x119e
+ #define PCI_DEVICE_ID_FUJITSU_FS155	0x0001
+@@ -1696,61 +1388,41 @@
+ #define PCI_SUBDEVICE_ID_KEYSPAN_SX2	0x5334
+ 
+ #define PCI_VENDOR_ID_MARVELL		0x11ab
+-#define PCI_DEVICE_ID_MARVELL_GT64011	0x4146
+-#define PCI_DEVICE_ID_MARVELL_GT64111	0x4146
+ #define PCI_DEVICE_ID_MARVELL_GT64260	0x6430
+ #define PCI_DEVICE_ID_MARVELL_MV64360	0x6460
+ #define PCI_DEVICE_ID_MARVELL_MV64460	0x6480
+ #define PCI_DEVICE_ID_MARVELL_GT96100	0x9652
+ #define PCI_DEVICE_ID_MARVELL_GT96100A	0x9653
+ 
+-#define PCI_VENDOR_ID_LITEON		0x11ad
+-#define PCI_DEVICE_ID_LITEON_LNE100TX	0x0002
+ 
+ #define PCI_VENDOR_ID_V3		0x11b0
+ #define PCI_DEVICE_ID_V3_V960		0x0001
+-#define PCI_DEVICE_ID_V3_V350		0x0001
+-#define PCI_DEVICE_ID_V3_V961		0x0002
+ #define PCI_DEVICE_ID_V3_V351		0x0002
+ 
+-#define PCI_VENDOR_ID_NP		0x11bc
+-#define PCI_DEVICE_ID_NP_PCI_FDDI	0x0001
+ 
+ #define PCI_VENDOR_ID_ATT		0x11c1
+-#define PCI_DEVICE_ID_ATT_L56XMF	0x0440
+ #define PCI_DEVICE_ID_ATT_VENUS_MODEM	0x480
+ 
+-#define PCI_VENDOR_ID_NEC2		0x11c3 /* NEC (2nd) */
+ 
+ #define PCI_VENDOR_ID_SPECIALIX		0x11cb
+ #define PCI_DEVICE_ID_SPECIALIX_IO8	0x2000
+-#define PCI_DEVICE_ID_SPECIALIX_XIO	0x4000
+ #define PCI_DEVICE_ID_SPECIALIX_RIO	0x8000
+ #define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004
+ 
+-#define PCI_VENDOR_ID_AURAVISION	0x11d1
+-#define PCI_DEVICE_ID_AURAVISION_VXP524	0x01f7
+ 
+ #define PCI_VENDOR_ID_ANALOG_DEVICES	0x11d4
+ #define PCI_DEVICE_ID_AD1889JS		0x1889
+ 
+-#define PCI_VENDOR_ID_IKON		0x11d5
+-#define PCI_DEVICE_ID_IKON_10115	0x0115
+-#define PCI_DEVICE_ID_IKON_10117	0x0117
+ 
+-#define PCI_VENDOR_ID_SEGA		0x11db
+ #define PCI_DEVICE_ID_SEGA_BBA		0x1234
+ 
+ #define PCI_VENDOR_ID_ZORAN		0x11de
+ #define PCI_DEVICE_ID_ZORAN_36057	0x6057
+ #define PCI_DEVICE_ID_ZORAN_36120	0x6120
+ 
+-#define PCI_VENDOR_ID_KINETIC		0x11f4
+-#define PCI_DEVICE_ID_KINETIC_2915	0x2915
+ 
+ #define PCI_VENDOR_ID_COMPEX		0x11f6
+ #define PCI_DEVICE_ID_COMPEX_ENET100VG4	0x0112
+-#define PCI_DEVICE_ID_COMPEX_RL2000	0x1401
+ 
+ #define PCI_VENDOR_ID_RP		0x11fe
+ #define PCI_DEVICE_ID_RP32INTF		0x0001
+@@ -1764,7 +1436,6 @@
+ #define PCI_DEVICE_ID_RP16SNI		0x0009	
+ #define PCI_DEVICE_ID_RPP4		0x000A
+ #define PCI_DEVICE_ID_RPP8		0x000B
+-#define PCI_DEVICE_ID_RP8M		0x000C
+ #define PCI_DEVICE_ID_RP4M		0x000D
+ #define PCI_DEVICE_ID_RP2_232		0x000E
+ #define PCI_DEVICE_ID_RP2_422		0x000F
+@@ -1792,10 +1463,6 @@
+ #define PCI_DEVICE_ID_PC300_TE_M_2	0x0320
+ #define PCI_DEVICE_ID_PC300_TE_M_1	0x0321
+ 
+-/* Allied Telesyn */
+-#define PCI_VENDOR_ID_AT    		0x1259
+-#define PCI_SUBDEVICE_ID_AT_2701FX	0x2703
+-
+ #define PCI_VENDOR_ID_ESSENTIAL		0x120f
+ #define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER	0x0001
+ 
+@@ -1812,10 +1479,7 @@
+ #define PCI_DEVICE_ID_3DFX_VOODOO3	0x0005
+ #define PCI_DEVICE_ID_3DFX_VOODOO5	0x0009
+ 
+-#define PCI_VENDOR_ID_SIGMADES		0x1236
+-#define PCI_DEVICE_ID_SIGMADES_6425	0x6401
+ 
+-#define PCI_VENDOR_ID_CCUBE		0x123f
+ 
+ #define PCI_VENDOR_ID_AVM		0x1244
+ #define PCI_DEVICE_ID_AVM_B1		0x0700
+@@ -1825,19 +1489,8 @@
+ #define PCI_DEVICE_ID_AVM_C2		0x1100
+ #define PCI_DEVICE_ID_AVM_T1		0x1200
+ 
+-#define PCI_VENDOR_ID_DIPIX		0x1246
+ 
+ #define PCI_VENDOR_ID_STALLION		0x124d
+-#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000
+-#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002
+-#define PCI_DEVICE_ID_STALLION_EIOPCI	0x0003
+-
+-#define PCI_VENDOR_ID_OPTIBASE		0x1255
+-#define PCI_DEVICE_ID_OPTIBASE_FORGE	0x1110
+-#define PCI_DEVICE_ID_OPTIBASE_FUSION	0x1210
+-#define PCI_DEVICE_ID_OPTIBASE_VPLEX	0x2110
+-#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC	0x2120
+-#define PCI_DEVICE_ID_OPTIBASE_VQUEST	0x2130
+ 
+ /* Allied Telesyn */
+ #define PCI_VENDOR_ID_AT    		0x1259
+@@ -1846,7 +1499,6 @@
+ 
+ #define PCI_VENDOR_ID_ESS		0x125d
+ #define PCI_DEVICE_ID_ESS_ESS1968	0x1968
+-#define PCI_DEVICE_ID_ESS_AUDIOPCI	0x1969
+ #define PCI_DEVICE_ID_ESS_ESS1978	0x1978
+ #define PCI_DEVICE_ID_ESS_ALLEGRO_1	0x1988
+ #define PCI_DEVICE_ID_ESS_ALLEGRO	0x1989
+@@ -1859,11 +1511,7 @@
+ 
+ #define PCI_VENDOR_ID_SATSAGEM		0x1267
+ #define PCI_DEVICE_ID_SATSAGEM_NICCY	0x1016
+-#define PCI_DEVICE_ID_SATSAGEM_PCR2101	0x5352
+-#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
+ 
+-#define PCI_VENDOR_ID_HUGHES		0x1273
+-#define PCI_DEVICE_ID_HUGHES_DIRECPC	0x0002
+ 
+ #define PCI_VENDOR_ID_ENSONIQ		0x1274
+ #define PCI_DEVICE_ID_ENSONIQ_CT5880	0x5880
+@@ -1884,13 +1532,10 @@
+ #define PCI_DEVICE_ID_ITE_IT8330G_0	0xe886
+ 
+ /* formerly Platform Tech */
+-#define PCI_VENDOR_ID_ESS_OLD		0x1285
+ #define PCI_DEVICE_ID_ESS_ESS0100	0x0100
+ 
+ #define PCI_VENDOR_ID_ALTEON		0x12ae
+-#define PCI_DEVICE_ID_ALTEON_ACENIC	0x0001
+ 
+-#define PCI_VENDOR_ID_USR		0x12B9
+ 
+ #define PCI_SUBVENDOR_ID_CONNECT_TECH			0x12c4
+ #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232		0x0001
+@@ -1905,8 +1550,6 @@
+ #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1	0x000A
+ #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1	0x000B
+ 
+-#define PCI_VENDOR_ID_PICTUREL		0x12c5
+-#define PCI_DEVICE_ID_PICTUREL_PCIVST	0x0081
+ 
+ #define PCI_VENDOR_ID_NVIDIA_SGS	0x12d2
+ #define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
+@@ -1928,8 +1571,6 @@
+ #define PCI_VENDOR_ID_ELECTRONICDESIGNGMBH 0x12f8
+ #define PCI_DEVICE_ID_LML_33R10		0x8a02
+ 
+-#define PCI_VENDOR_ID_CBOARDS		0x1307
+-#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
+ 
+ #define PCI_VENDOR_ID_SIIG		0x131f
+ #define PCI_SUBVENDOR_ID_SIIG		0x131f
+@@ -1973,7 +1614,6 @@
+ #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL	0x2050
+ 
+ #define PCI_VENDOR_ID_RADISYS		0x1331
+-#define PCI_DEVICE_ID_RADISYS_ENP2611	0x0030
+ 
+ #define PCI_VENDOR_ID_DOMEX		0x134a
+ #define PCI_DEVICE_ID_DOMEX_DMX3191D	0x0001
+@@ -1981,8 +1621,6 @@
+ #define PCI_VENDOR_ID_QUATECH		0x135C
+ #define PCI_DEVICE_ID_QUATECH_QSC100	0x0010
+ #define PCI_DEVICE_ID_QUATECH_DSC100	0x0020
+-#define PCI_DEVICE_ID_QUATECH_DSC200	0x0030
+-#define PCI_DEVICE_ID_QUATECH_QSC200	0x0040
+ #define PCI_DEVICE_ID_QUATECH_ESC100D	0x0050
+ #define PCI_DEVICE_ID_QUATECH_ESC100M	0x0060
+ 
+@@ -2001,7 +1639,6 @@
+ #define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO		0x0106
+ #define PCI_SUBDEVICE_ID_HYPERCOPE_METRO	0x0107
+ #define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2	0x0108
+-#define PCI_SUBDEVICE_ID_HYPERCOPE_PLEXUS	0x0109
+ 
+ #define PCI_VENDOR_ID_KAWASAKI		0x136b
+ #define PCI_DEVICE_ID_MCHIP_KL5A72002	0xff01
+@@ -2015,12 +1652,9 @@
+ #define PCI_DEVICE_ID_LMC_SSI		0x0005
+ #define PCI_DEVICE_ID_LMC_T1		0x0006
+ 
+-#define PCI_VENDOR_ID_MARIAN		0x1382
+-#define PCI_DEVICE_ID_MARIAN_PRODIF_PLUS 0x2048
+ 
+ #define PCI_VENDOR_ID_NETGEAR		0x1385
+ #define PCI_DEVICE_ID_NETGEAR_GA620	0x620a
+-#define PCI_DEVICE_ID_NETGEAR_GA622	0x622a
+ 
+ #define PCI_VENDOR_ID_APPLICOM		0x1389
+ #define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001
+@@ -2043,9 +1677,6 @@
+ #define PCI_DEVICE_ID_MOXA_CP134U	0x1340
+ #define PCI_DEVICE_ID_MOXA_C168		0x1680
+ #define PCI_DEVICE_ID_MOXA_CP168U	0x1681
+-#define PCI_DEVICE_ID_MOXA_CP204J	0x2040
+-#define PCI_DEVICE_ID_MOXA_C218		0x2180
+-#define PCI_DEVICE_ID_MOXA_C320		0x3200
+ 
+ #define PCI_VENDOR_ID_CCD		0x1397
+ #define PCI_DEVICE_ID_CCD_2BD0		0x2bd0
+@@ -2066,9 +1697,7 @@
+ 
+ #define PCI_VENDOR_ID_MICROGATE		0x13c0
+ #define PCI_DEVICE_ID_MICROGATE_USC	0x0010
+-#define PCI_DEVICE_ID_MICROGATE_SCC	0x0020
+ #define PCI_DEVICE_ID_MICROGATE_SCA	0x0030
+-#define PCI_DEVICE_ID_MICROGATE_USC2	0x0210
+ 
+ #define PCI_VENDOR_ID_3WARE		0x13C1
+ #define PCI_DEVICE_ID_3WARE_1000	0x1000
+@@ -2119,10 +1748,6 @@
+ 
+ #define PCI_VENDOR_ID_SAMSUNG		0x144d
+ 
+-#define PCI_VENDOR_ID_AIRONET		0x14b9
+-#define PCI_DEVICE_ID_AIRONET_4800_1	0x0001
+-#define PCI_DEVICE_ID_AIRONET_4800	0x4500 // values switched?  see
+-#define PCI_DEVICE_ID_AIRONET_4500	0x4800 // drivers/net/aironet4500_card.c
+ 
+ #define PCI_VENDOR_ID_TITAN		0x14D2
+ #define PCI_DEVICE_ID_TITAN_010L	0x8001
+@@ -2141,8 +1766,6 @@
+ #define PCI_DEVICE_ID_PANACOM_QUADMODEM	0x0400
+ #define PCI_DEVICE_ID_PANACOM_DUALMODEM	0x0402
+ 
+-#define PCI_VENDOR_ID_SIPACKETS		0x14d9
+-#define PCI_DEVICE_ID_SP_HT		0x0010
+ 
+ #define PCI_VENDOR_ID_AFAVLAB		0x14db
+ #define PCI_DEVICE_ID_AFAVLAB_P028	0x2180
+@@ -2165,11 +1788,13 @@
+ #define PCI_DEVICE_ID_TIGON3_5721	0x1659
+ #define PCI_DEVICE_ID_TIGON3_5705M	0x165d
+ #define PCI_DEVICE_ID_TIGON3_5705M_2	0x165e
++#define PCI_DEVICE_ID_TIGON3_5714	0x1668
+ #define PCI_DEVICE_ID_TIGON3_5780	0x166a
+ #define PCI_DEVICE_ID_TIGON3_5780S	0x166b
+ #define PCI_DEVICE_ID_TIGON3_5705F	0x166e
+ #define PCI_DEVICE_ID_TIGON3_5750	0x1676
+ #define PCI_DEVICE_ID_TIGON3_5751	0x1677
++#define PCI_DEVICE_ID_TIGON3_5715	0x1678
+ #define PCI_DEVICE_ID_TIGON3_5750M	0x167c
+ #define PCI_DEVICE_ID_TIGON3_5751M	0x167d
+ #define PCI_DEVICE_ID_TIGON3_5751F	0x167e
+@@ -2207,8 +1832,6 @@
+ 
+ #define PCI_VENDOR_ID_CHELSIO		0x1425
+ 
+-#define PCI_VENDOR_ID_MIPS		0x153f
+-#define PCI_DEVICE_ID_SOC_IT		0x0001
+ 
+ #define PCI_VENDOR_ID_SYBA		0x1592
+ #define PCI_DEVICE_ID_SYBA_2P_EPP	0x0782
+@@ -2228,15 +1851,7 @@
+ #define PCI_DEVICE_ID_MELLANOX_SINAI	0x6274
+ 
+ #define PCI_VENDOR_ID_PDC		0x15e9
+-#define PCI_DEVICE_ID_PDC_1841		0x1841
+ 
+-#define PCI_VENDOR_ID_MACROLINK		0x15ed
+-#define PCI_DEVICE_ID_MACROLINK_MCCS8	0x1000
+-#define PCI_DEVICE_ID_MACROLINK_MCCS	0x1001
+-#define PCI_DEVICE_ID_MACROLINK_MCCS8H	0x1002
+-#define PCI_DEVICE_ID_MACROLINK_MCCSH	0x1003
+-#define PCI_DEVICE_ID_MACROLINK_MCCR8	0x2000
+-#define PCI_DEVICE_ID_MACROLINK_MCCR	0x2001
+ 
+ #define PCI_VENDOR_ID_FARSITE           0x1619
+ #define PCI_DEVICE_ID_FARSITE_T2P       0x0400
+@@ -2254,7 +1869,6 @@
+ #define PCI_DEVICE_ID_REVOLUTION	0x0044
+ 
+ #define PCI_VENDOR_ID_LINKSYS		0x1737
+-#define PCI_DEVICE_ID_LINKSYS_EG1032	0x1032
+ #define PCI_DEVICE_ID_LINKSYS_EG1064	0x1064
+ 
+ #define PCI_VENDOR_ID_ALTIMA		0x173b
+@@ -2269,7 +1883,6 @@
+ #define PCI_DEVICE_ID_HERC_WIN		0x5732
+ #define PCI_DEVICE_ID_HERC_UNI		0x5832
+ 
+-#define PCI_VENDOR_ID_INFINICON		0x1820
+ 
+ #define PCI_VENDOR_ID_SITECOM		0x182d
+ #define PCI_DEVICE_ID_SITECOM_DC105V2	0x3069
+@@ -2279,8 +1892,6 @@
+ #define PCI_VENDOR_ID_TDI               0x192E
+ #define PCI_DEVICE_ID_TDI_EHCI          0x0101
+ 
+-#define PCI_VENDOR_ID_SYMPHONY		0x1c1c
+-#define PCI_DEVICE_ID_SYMPHONY_101	0x0001
+ 
+ #define PCI_VENDOR_ID_TEKRAM		0x1de1
+ #define PCI_DEVICE_ID_TEKRAM_DC290	0xdc29
+@@ -2289,70 +1900,33 @@
+ #define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
+ 
+ #define PCI_VENDOR_ID_3DLABS		0x3d3d
+-#define PCI_DEVICE_ID_3DLABS_300SX	0x0001
+-#define PCI_DEVICE_ID_3DLABS_500TX	0x0002
+-#define PCI_DEVICE_ID_3DLABS_DELTA	0x0003
+-#define PCI_DEVICE_ID_3DLABS_PERMEDIA	0x0004
+-#define PCI_DEVICE_ID_3DLABS_MX		0x0006
+ #define PCI_DEVICE_ID_3DLABS_PERMEDIA2	0x0007
+-#define PCI_DEVICE_ID_3DLABS_GAMMA	0x0008
+ #define PCI_DEVICE_ID_3DLABS_PERMEDIA2V	0x0009
+ 
+-#define PCI_VENDOR_ID_AVANCE		0x4005
+-#define PCI_DEVICE_ID_AVANCE_ALG2064	0x2064
+-#define PCI_DEVICE_ID_AVANCE_2302	0x2302
+ 
+ #define PCI_VENDOR_ID_AKS		0x416c
+ #define PCI_DEVICE_ID_AKS_ALADDINCARD	0x0100
+-#define PCI_DEVICE_ID_AKS_CPC		0x0200
+ 
+-#define PCI_VENDOR_ID_REDCREEK		0x4916
+-#define PCI_DEVICE_ID_RC45		0x1960
+ 
+-#define PCI_VENDOR_ID_NETVIN		0x4a14
+-#define PCI_DEVICE_ID_NETVIN_NV5000SC	0x5000
+ 
+ #define PCI_VENDOR_ID_S3		0x5333
+-#define PCI_DEVICE_ID_S3_PLATO_PXS	0x0551
+-#define PCI_DEVICE_ID_S3_ViRGE		0x5631
+ #define PCI_DEVICE_ID_S3_TRIO		0x8811
+-#define PCI_DEVICE_ID_S3_AURORA64VP	0x8812
+-#define PCI_DEVICE_ID_S3_TRIO64UVP	0x8814
+-#define PCI_DEVICE_ID_S3_ViRGE_VX	0x883d
+ #define PCI_DEVICE_ID_S3_868		0x8880
+-#define PCI_DEVICE_ID_S3_928		0x88b0
+-#define PCI_DEVICE_ID_S3_864_1		0x88c0
+-#define PCI_DEVICE_ID_S3_864_2		0x88c1
+-#define PCI_DEVICE_ID_S3_964_1		0x88d0
+-#define PCI_DEVICE_ID_S3_964_2		0x88d1
+ #define PCI_DEVICE_ID_S3_968		0x88f0
+-#define PCI_DEVICE_ID_S3_TRIO64V2	0x8901
+-#define PCI_DEVICE_ID_S3_PLATO_PXG	0x8902
+-#define PCI_DEVICE_ID_S3_ViRGE_DXGX	0x8a01
+-#define PCI_DEVICE_ID_S3_ViRGE_GX2	0x8a10
+ #define PCI_DEVICE_ID_S3_SAVAGE4	0x8a25
+-#define PCI_DEVICE_ID_S3_ViRGE_MX	0x8c01
+-#define PCI_DEVICE_ID_S3_ViRGE_MXP	0x8c02
+-#define PCI_DEVICE_ID_S3_ViRGE_MXPMV	0x8c03
+ #define PCI_DEVICE_ID_S3_PROSAVAGE8	0x8d04
+ #define PCI_DEVICE_ID_S3_SONICVIBES	0xca00
+ 
+ #define PCI_VENDOR_ID_DUNORD		0x5544
+ #define PCI_DEVICE_ID_DUNORD_I3000	0x0001
+ 
++
+ #define PCI_VENDOR_ID_DCI		0x6666
+ #define PCI_DEVICE_ID_DCI_PCCOM4	0x0001
+ #define PCI_DEVICE_ID_DCI_PCCOM8	0x0002
+ 
+-#define PCI_VENDOR_ID_DUNORD		0x5544
+-#define PCI_DEVICE_ID_DUNORD_I3000	0x0001
+-
+-#define PCI_VENDOR_ID_GENROCO		0x5555
+-#define PCI_DEVICE_ID_GENROCO_HFP832	0x0003
+-
+ #define PCI_VENDOR_ID_INTEL		0x8086
+ #define PCI_DEVICE_ID_INTEL_EESSC	0x0008
+-#define PCI_DEVICE_ID_INTEL_21145	0x0039
+ #define PCI_DEVICE_ID_INTEL_PXHD_0	0x0320
+ #define PCI_DEVICE_ID_INTEL_PXHD_1	0x0321
+ #define PCI_DEVICE_ID_INTEL_PXH_0	0x0329
+@@ -2361,30 +1935,17 @@
+ #define PCI_DEVICE_ID_INTEL_82375	0x0482
+ #define PCI_DEVICE_ID_INTEL_82424	0x0483
+ #define PCI_DEVICE_ID_INTEL_82378	0x0484
+-#define PCI_DEVICE_ID_INTEL_82430	0x0486
+-#define PCI_DEVICE_ID_INTEL_82434	0x04a3
+ #define PCI_DEVICE_ID_INTEL_I960	0x0960
+ #define PCI_DEVICE_ID_INTEL_I960RM	0x0962
+-#define PCI_DEVICE_ID_INTEL_82562ET	0x1031
+-#define PCI_DEVICE_ID_INTEL_82801CAM	0x1038
+ #define PCI_DEVICE_ID_INTEL_82815_MC	0x1130
+-#define PCI_DEVICE_ID_INTEL_82815_AB	0x1131
+ #define PCI_DEVICE_ID_INTEL_82815_CGC	0x1132
+-#define PCI_DEVICE_ID_INTEL_82559ER	0x1209
+ #define PCI_DEVICE_ID_INTEL_82092AA_0	0x1221
+-#define PCI_DEVICE_ID_INTEL_82092AA_1	0x1222
+-#define PCI_DEVICE_ID_INTEL_7116	0x1223
+ #define PCI_DEVICE_ID_INTEL_7505_0	0x2550  
+-#define PCI_DEVICE_ID_INTEL_7505_1	0x2552  
+ #define PCI_DEVICE_ID_INTEL_7205_0	0x255d
+-#define PCI_DEVICE_ID_INTEL_82596	0x1226
+-#define PCI_DEVICE_ID_INTEL_82865	0x1227
+-#define PCI_DEVICE_ID_INTEL_82557	0x1229
+ #define PCI_DEVICE_ID_INTEL_82437	0x122d
+ #define PCI_DEVICE_ID_INTEL_82371FB_0	0x122e
+ #define PCI_DEVICE_ID_INTEL_82371FB_1	0x1230
+ #define PCI_DEVICE_ID_INTEL_82371MX	0x1234
+-#define PCI_DEVICE_ID_INTEL_82437MX	0x1235
+ #define PCI_DEVICE_ID_INTEL_82441	0x1237
+ #define PCI_DEVICE_ID_INTEL_82380FB	0x124b
+ #define PCI_DEVICE_ID_INTEL_82439	0x1250
+@@ -2393,83 +1954,53 @@
+ #define PCI_DEVICE_ID_INTEL_82845_HB	0x1a30
+ #define PCI_DEVICE_ID_INTEL_82801AA_0	0x2410
+ #define PCI_DEVICE_ID_INTEL_82801AA_1	0x2411
+-#define PCI_DEVICE_ID_INTEL_82801AA_2	0x2412
+ #define PCI_DEVICE_ID_INTEL_82801AA_3	0x2413
+ #define PCI_DEVICE_ID_INTEL_82801AA_5	0x2415
+ #define PCI_DEVICE_ID_INTEL_82801AA_6	0x2416
+ #define PCI_DEVICE_ID_INTEL_82801AA_8	0x2418
+ #define PCI_DEVICE_ID_INTEL_82801AB_0	0x2420
+ #define PCI_DEVICE_ID_INTEL_82801AB_1	0x2421
+-#define PCI_DEVICE_ID_INTEL_82801AB_2	0x2422
+ #define PCI_DEVICE_ID_INTEL_82801AB_3	0x2423
+ #define PCI_DEVICE_ID_INTEL_82801AB_5	0x2425
+ #define PCI_DEVICE_ID_INTEL_82801AB_6	0x2426
+ #define PCI_DEVICE_ID_INTEL_82801AB_8	0x2428
+ #define PCI_DEVICE_ID_INTEL_82801BA_0	0x2440
+-#define PCI_DEVICE_ID_INTEL_82801BA_1	0x2442
+ #define PCI_DEVICE_ID_INTEL_82801BA_2	0x2443
+-#define PCI_DEVICE_ID_INTEL_82801BA_3	0x2444
+ #define PCI_DEVICE_ID_INTEL_82801BA_4	0x2445
+-#define PCI_DEVICE_ID_INTEL_82801BA_5	0x2446
+ #define PCI_DEVICE_ID_INTEL_82801BA_6	0x2448
+-#define PCI_DEVICE_ID_INTEL_82801BA_7	0x2449
+ #define PCI_DEVICE_ID_INTEL_82801BA_8	0x244a
+ #define PCI_DEVICE_ID_INTEL_82801BA_9	0x244b
+ #define PCI_DEVICE_ID_INTEL_82801BA_10	0x244c
+ #define PCI_DEVICE_ID_INTEL_82801BA_11	0x244e
+ #define PCI_DEVICE_ID_INTEL_82801E_0	0x2450
+-#define PCI_DEVICE_ID_INTEL_82801E_2	0x2452
+-#define PCI_DEVICE_ID_INTEL_82801E_3	0x2453
+-#define PCI_DEVICE_ID_INTEL_82801E_9	0x2459
+ #define PCI_DEVICE_ID_INTEL_82801E_11	0x245b
+-#define PCI_DEVICE_ID_INTEL_82801E_13	0x245d
+-#define PCI_DEVICE_ID_INTEL_82801E_14	0x245e
+ #define PCI_DEVICE_ID_INTEL_82801CA_0	0x2480
+-#define PCI_DEVICE_ID_INTEL_82801CA_2	0x2482
+ #define PCI_DEVICE_ID_INTEL_82801CA_3	0x2483
+-#define PCI_DEVICE_ID_INTEL_82801CA_4	0x2484
+ #define PCI_DEVICE_ID_INTEL_82801CA_5	0x2485
+ #define PCI_DEVICE_ID_INTEL_82801CA_6	0x2486
+-#define PCI_DEVICE_ID_INTEL_82801CA_7	0x2487
+ #define PCI_DEVICE_ID_INTEL_82801CA_10	0x248a
+ #define PCI_DEVICE_ID_INTEL_82801CA_11	0x248b
+ #define PCI_DEVICE_ID_INTEL_82801CA_12	0x248c
+ #define PCI_DEVICE_ID_INTEL_82801DB_0	0x24c0
+ #define PCI_DEVICE_ID_INTEL_82801DB_1	0x24c1
+-#define PCI_DEVICE_ID_INTEL_82801DB_2	0x24c2
+ #define PCI_DEVICE_ID_INTEL_82801DB_3	0x24c3
+-#define PCI_DEVICE_ID_INTEL_82801DB_4	0x24c4
+ #define PCI_DEVICE_ID_INTEL_82801DB_5	0x24c5
+ #define PCI_DEVICE_ID_INTEL_82801DB_6	0x24c6
+-#define PCI_DEVICE_ID_INTEL_82801DB_7	0x24c7
+ #define PCI_DEVICE_ID_INTEL_82801DB_9	0x24c9
+ #define PCI_DEVICE_ID_INTEL_82801DB_10	0x24ca
+ #define PCI_DEVICE_ID_INTEL_82801DB_11	0x24cb
+ #define PCI_DEVICE_ID_INTEL_82801DB_12  0x24cc
+-#define PCI_DEVICE_ID_INTEL_82801DB_13	0x24cd
+ #define PCI_DEVICE_ID_INTEL_82801EB_0	0x24d0
+ #define PCI_DEVICE_ID_INTEL_82801EB_1	0x24d1
+-#define PCI_DEVICE_ID_INTEL_82801EB_2	0x24d2
+ #define PCI_DEVICE_ID_INTEL_82801EB_3	0x24d3
+-#define PCI_DEVICE_ID_INTEL_82801EB_4	0x24d4
+ #define PCI_DEVICE_ID_INTEL_82801EB_5	0x24d5
+ #define PCI_DEVICE_ID_INTEL_82801EB_6	0x24d6
+-#define PCI_DEVICE_ID_INTEL_82801EB_7	0x24d7
+ #define PCI_DEVICE_ID_INTEL_82801EB_11	0x24db
+-#define PCI_DEVICE_ID_INTEL_82801EB_13	0x24dd
+ #define PCI_DEVICE_ID_INTEL_ESB_1	0x25a1
+ #define PCI_DEVICE_ID_INTEL_ESB_2	0x25a2
+-#define PCI_DEVICE_ID_INTEL_ESB_3	0x25a3
+-#define PCI_DEVICE_ID_INTEL_ESB_31	0x25b0
+ #define PCI_DEVICE_ID_INTEL_ESB_4	0x25a4
+ #define PCI_DEVICE_ID_INTEL_ESB_5	0x25a6
+-#define PCI_DEVICE_ID_INTEL_ESB_6	0x25a7
+-#define PCI_DEVICE_ID_INTEL_ESB_7	0x25a9
+-#define PCI_DEVICE_ID_INTEL_ESB_8	0x25aa
+ #define PCI_DEVICE_ID_INTEL_ESB_9	0x25ab
+-#define PCI_DEVICE_ID_INTEL_ESB_11	0x25ac
+-#define PCI_DEVICE_ID_INTEL_ESB_12	0x25ad
+-#define PCI_DEVICE_ID_INTEL_ESB_13	0x25ae
+ #define PCI_DEVICE_ID_INTEL_82820_HB	0x2500
+ #define PCI_DEVICE_ID_INTEL_82820_UP_HB	0x2501
+ #define PCI_DEVICE_ID_INTEL_82850_HB	0x2530
+@@ -2479,7 +2010,6 @@
+ #define PCI_DEVICE_ID_INTEL_82865_HB	0x2570
+ #define PCI_DEVICE_ID_INTEL_82865_IG	0x2572
+ #define PCI_DEVICE_ID_INTEL_82875_HB	0x2578
+-#define PCI_DEVICE_ID_INTEL_82875_IG	0x257b
+ #define PCI_DEVICE_ID_INTEL_82915G_HB	0x2580
+ #define PCI_DEVICE_ID_INTEL_82915G_IG	0x2582
+ #define PCI_DEVICE_ID_INTEL_82915GM_HB	0x2590
+@@ -2489,80 +2019,23 @@
+ #define PCI_DEVICE_ID_INTEL_ICH6_0	0x2640
+ #define PCI_DEVICE_ID_INTEL_ICH6_1	0x2641
+ #define PCI_DEVICE_ID_INTEL_ICH6_2	0x2642
+-#define PCI_DEVICE_ID_INTEL_ICH6_3	0x2651
+-#define PCI_DEVICE_ID_INTEL_ICH6_4	0x2652
+-#define PCI_DEVICE_ID_INTEL_ICH6_5	0x2653
+-#define PCI_DEVICE_ID_INTEL_ICH6_6	0x2658
+-#define PCI_DEVICE_ID_INTEL_ICH6_7	0x2659
+-#define PCI_DEVICE_ID_INTEL_ICH6_8	0x265a
+-#define PCI_DEVICE_ID_INTEL_ICH6_9	0x265b
+-#define PCI_DEVICE_ID_INTEL_ICH6_10	0x265c
+-#define PCI_DEVICE_ID_INTEL_ICH6_11	0x2660
+-#define PCI_DEVICE_ID_INTEL_ICH6_12	0x2662
+-#define PCI_DEVICE_ID_INTEL_ICH6_13	0x2664
+-#define PCI_DEVICE_ID_INTEL_ICH6_14	0x2666
+-#define PCI_DEVICE_ID_INTEL_ICH6_15	0x2668
+ #define PCI_DEVICE_ID_INTEL_ICH6_16	0x266a
+ #define PCI_DEVICE_ID_INTEL_ICH6_17	0x266d
+ #define PCI_DEVICE_ID_INTEL_ICH6_18	0x266e
+ #define PCI_DEVICE_ID_INTEL_ICH6_19	0x266f
+ #define PCI_DEVICE_ID_INTEL_ESB2_0	0x2670
+-#define PCI_DEVICE_ID_INTEL_ESB2_1	0x2680
+-#define PCI_DEVICE_ID_INTEL_ESB2_2	0x2681
+-#define PCI_DEVICE_ID_INTEL_ESB2_3	0x2682
+-#define PCI_DEVICE_ID_INTEL_ESB2_4	0x2683
+-#define PCI_DEVICE_ID_INTEL_ESB2_5	0x2688
+-#define PCI_DEVICE_ID_INTEL_ESB2_6	0x2689
+-#define PCI_DEVICE_ID_INTEL_ESB2_7	0x268a
+-#define PCI_DEVICE_ID_INTEL_ESB2_8	0x268b
+-#define PCI_DEVICE_ID_INTEL_ESB2_9	0x268c
+-#define PCI_DEVICE_ID_INTEL_ESB2_10	0x2690
+-#define PCI_DEVICE_ID_INTEL_ESB2_11	0x2692
+-#define PCI_DEVICE_ID_INTEL_ESB2_12	0x2694
+-#define PCI_DEVICE_ID_INTEL_ESB2_13	0x2696
+ #define PCI_DEVICE_ID_INTEL_ESB2_14	0x2698
+-#define PCI_DEVICE_ID_INTEL_ESB2_15	0x2699
+-#define PCI_DEVICE_ID_INTEL_ESB2_16	0x269a
+ #define PCI_DEVICE_ID_INTEL_ESB2_17	0x269b
+ #define PCI_DEVICE_ID_INTEL_ESB2_18	0x269e
+ #define PCI_DEVICE_ID_INTEL_ICH7_0	0x27b8
+ #define PCI_DEVICE_ID_INTEL_ICH7_1	0x27b9
+-#define PCI_DEVICE_ID_INTEL_ICH7_2	0x27c0
+-#define PCI_DEVICE_ID_INTEL_ICH7_3	0x27c1
+ #define PCI_DEVICE_ID_INTEL_ICH7_30	0x27b0
+ #define PCI_DEVICE_ID_INTEL_ICH7_31	0x27bd
+-#define PCI_DEVICE_ID_INTEL_ICH7_5	0x27c4
+-#define PCI_DEVICE_ID_INTEL_ICH7_6	0x27c5
+-#define PCI_DEVICE_ID_INTEL_ICH7_7	0x27c8
+-#define PCI_DEVICE_ID_INTEL_ICH7_8	0x27c9
+-#define PCI_DEVICE_ID_INTEL_ICH7_9	0x27ca
+-#define PCI_DEVICE_ID_INTEL_ICH7_10	0x27cb
+-#define PCI_DEVICE_ID_INTEL_ICH7_11	0x27cc
+-#define PCI_DEVICE_ID_INTEL_ICH7_12	0x27d0
+-#define PCI_DEVICE_ID_INTEL_ICH7_13	0x27d2
+-#define PCI_DEVICE_ID_INTEL_ICH7_14	0x27d4
+-#define PCI_DEVICE_ID_INTEL_ICH7_15	0x27d6
+-#define PCI_DEVICE_ID_INTEL_ICH7_16	0x27d8
+ #define PCI_DEVICE_ID_INTEL_ICH7_17	0x27da
+-#define PCI_DEVICE_ID_INTEL_ICH7_18	0x27dc
+ #define PCI_DEVICE_ID_INTEL_ICH7_19	0x27dd
+ #define PCI_DEVICE_ID_INTEL_ICH7_20	0x27de
+ #define PCI_DEVICE_ID_INTEL_ICH7_21	0x27df
+-#define PCI_DEVICE_ID_INTEL_ICH7_22	0x27e0
+-#define PCI_DEVICE_ID_INTEL_ICH7_23	0x27e2
+ #define PCI_DEVICE_ID_INTEL_82855PM_HB	0x3340
+-#define PCI_DEVICE_ID_INTEL_ESB2_19	0x3500
+-#define PCI_DEVICE_ID_INTEL_ESB2_20	0x3501
+-#define PCI_DEVICE_ID_INTEL_ESB2_21	0x3504
+-#define PCI_DEVICE_ID_INTEL_ESB2_22	0x3505
+-#define PCI_DEVICE_ID_INTEL_ESB2_23	0x350c
+-#define PCI_DEVICE_ID_INTEL_ESB2_24	0x350d
+-#define PCI_DEVICE_ID_INTEL_ESB2_25	0x3510
+-#define PCI_DEVICE_ID_INTEL_ESB2_26	0x3511
+-#define PCI_DEVICE_ID_INTEL_ESB2_27	0x3514
+-#define PCI_DEVICE_ID_INTEL_ESB2_28	0x3515
+-#define PCI_DEVICE_ID_INTEL_ESB2_29	0x3518
+-#define PCI_DEVICE_ID_INTEL_ESB2_30	0x3519
+ #define PCI_DEVICE_ID_INTEL_82830_HB	0x3575
+ #define PCI_DEVICE_ID_INTEL_82830_CGC	0x3577
+ #define PCI_DEVICE_ID_INTEL_82855GM_HB	0x3580
+@@ -2576,7 +2049,6 @@
+ #define PCI_DEVICE_ID_INTEL_MCH_PC	0x3599
+ #define PCI_DEVICE_ID_INTEL_MCH_PC1	0x359a
+ #define PCI_DEVICE_ID_INTEL_E7525_MCH	0x359e
+-#define PCI_DEVICE_ID_INTEL_80310	0x530d
+ #define PCI_DEVICE_ID_INTEL_82371SB_0	0x7000
+ #define PCI_DEVICE_ID_INTEL_82371SB_1	0x7010
+ #define PCI_DEVICE_ID_INTEL_82371SB_2	0x7020
+@@ -2601,22 +2073,15 @@
+ #define PCI_DEVICE_ID_INTEL_440MX_6	0x7196
+ #define PCI_DEVICE_ID_INTEL_82443MX_0	0x7198
+ #define PCI_DEVICE_ID_INTEL_82443MX_1	0x7199
+-#define PCI_DEVICE_ID_INTEL_82443MX_2	0x719a
+ #define PCI_DEVICE_ID_INTEL_82443MX_3	0x719b
+ #define PCI_DEVICE_ID_INTEL_82443GX_0	0x71a0
+-#define PCI_DEVICE_ID_INTEL_82443GX_1	0x71a1
+ #define PCI_DEVICE_ID_INTEL_82443GX_2	0x71a2
+-#define PCI_DEVICE_ID_INTEL_82372FB_0	0x7600
+ #define PCI_DEVICE_ID_INTEL_82372FB_1	0x7601
+-#define PCI_DEVICE_ID_INTEL_82372FB_2	0x7602
+-#define PCI_DEVICE_ID_INTEL_82372FB_3	0x7603
+ #define PCI_DEVICE_ID_INTEL_82454GX	0x84c4
+-#define PCI_DEVICE_ID_INTEL_82450GX	0x84c5
+ #define PCI_DEVICE_ID_INTEL_82451NX	0x84ca
+ #define PCI_DEVICE_ID_INTEL_82454NX     0x84cb
+ #define PCI_DEVICE_ID_INTEL_84460GX	0x84ea
+ #define PCI_DEVICE_ID_INTEL_IXP4XX	0x8500
+-#define PCI_DEVICE_ID_INTEL_IXP2400	0x9001
+ #define PCI_DEVICE_ID_INTEL_IXP2800	0x9004
+ #define PCI_DEVICE_ID_INTEL_S21152BB	0xb152
+ 
+@@ -2629,7 +2094,6 @@
+ #define PCI_SUBDEVICE_ID_COMPUTONE_PG6	0x0003
+ 
+ #define PCI_VENDOR_ID_KTI		0x8e2e
+-#define PCI_DEVICE_ID_KTI_ET32P2	0x3000
+ 
+ #define PCI_VENDOR_ID_ADAPTEC		0x9004
+ #define PCI_DEVICE_ID_ADAPTEC_7810	0x1078
+@@ -2637,7 +2101,6 @@
+ #define PCI_DEVICE_ID_ADAPTEC_38602	0x3860
+ #define PCI_DEVICE_ID_ADAPTEC_7850	0x5078
+ #define PCI_DEVICE_ID_ADAPTEC_7855	0x5578
+-#define PCI_DEVICE_ID_ADAPTEC_5800	0x5800
+ #define PCI_DEVICE_ID_ADAPTEC_3860	0x6038
+ #define PCI_DEVICE_ID_ADAPTEC_1480A	0x6075
+ #define PCI_DEVICE_ID_ADAPTEC_7860	0x6078
+@@ -2657,7 +2120,6 @@
+ #define PCI_DEVICE_ID_ADAPTEC_7886	0x8678
+ #define PCI_DEVICE_ID_ADAPTEC_7887	0x8778
+ #define PCI_DEVICE_ID_ADAPTEC_7888	0x8878
+-#define PCI_DEVICE_ID_ADAPTEC_1030	0x8b78
+ 
+ #define PCI_VENDOR_ID_ADAPTEC2		0x9005
+ #define PCI_DEVICE_ID_ADAPTEC2_2940U2	0x0010
+@@ -2677,8 +2139,6 @@
+ #define PCI_DEVICE_ID_ADAPTEC2_7899P	0x00cf
+ #define PCI_DEVICE_ID_ADAPTEC2_SCAMP	0x0503
+ 
+-#define PCI_VENDOR_ID_ATRONICS		0x907f
+-#define PCI_DEVICE_ID_ATRONICS_2015	0x2015
+ 
+ #define PCI_VENDOR_ID_HOLTEK		0x9412
+ #define PCI_DEVICE_ID_HOLTEK_6565	0x6565
+@@ -2711,7 +2171,3 @@
+ #define PCI_DEVICE_ID_RME_DIGI32_PRO	0x9897
+ #define PCI_DEVICE_ID_RME_DIGI32_8	0x9898
+ 
+-#define PCI_VENDOR_ID_ARK		0xedd8
+-#define PCI_DEVICE_ID_ARK_STING		0xa091
+-#define PCI_DEVICE_ID_ARK_STINGARK	0xa099
+-#define PCI_DEVICE_ID_ARK_2000MT	0xa0a1
+diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
+new file mode 100644
+--- /dev/null
++++ b/include/linux/platform_device.h
+@@ -0,0 +1,40 @@
++/*
++ * platform_device.h - generic, centralized driver model
++ *
++ * Copyright (c) 2001-2003 Patrick Mochel <mochel at osdl.org>
++ *
++ * This file is released under the GPLv2
++ *
++ * See Documentation/driver-model/ for more information.
++ */
++
++#ifndef _PLATFORM_DEVICE_H_
++#define _PLATFORM_DEVICE_H_
++
++#include <linux/device.h>
++
++struct platform_device {
++	const char	* name;
++	u32		id;
++	struct device	dev;
++	u32		num_resources;
++	struct resource	* resource;
++};
++
++#define to_platform_device(x) container_of((x), struct platform_device, dev)
++
++extern int platform_device_register(struct platform_device *);
++extern void platform_device_unregister(struct platform_device *);
++
++extern struct bus_type platform_bus_type;
++extern struct device platform_bus;
++
++extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
++extern int platform_get_irq(struct platform_device *, unsigned int);
++extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *);
++extern int platform_get_irq_byname(struct platform_device *, char *);
++extern int platform_add_devices(struct platform_device **, int);
++
++extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int);
++
++#endif /* _PLATFORM_DEVICE_H_ */
+diff --git a/include/linux/pm.h b/include/linux/pm.h
+--- a/include/linux/pm.h
++++ b/include/linux/pm.h
+@@ -170,6 +170,7 @@ typedef int __bitwise suspend_disk_metho
+ 
+ struct pm_ops {
+ 	suspend_disk_method_t pm_disk_mode;
++	int (*valid)(suspend_state_t state);
+ 	int (*prepare)(suspend_state_t state);
+ 	int (*enter)(suspend_state_t state);
+ 	int (*finish)(suspend_state_t state);
+@@ -219,10 +220,11 @@ typedef struct pm_message {
+ 
+ struct dev_pm_info {
+ 	pm_message_t		power_state;
++	unsigned		can_wakeup:1;
+ #ifdef	CONFIG_PM
++	unsigned		should_wakeup:1;
+ 	pm_message_t		prev_state;
+ 	void			* saved_state;
+-	atomic_t		pm_users;
+ 	struct device		* pm_parent;
+ 	struct list_head	entry;
+ #endif
+@@ -236,13 +238,48 @@ extern void device_resume(void);
+ 
+ #ifdef CONFIG_PM
+ extern int device_suspend(pm_message_t state);
+-#else
++
++#define device_set_wakeup_enable(dev,val) \
++	((dev)->power.should_wakeup = !!(val))
++#define device_may_wakeup(dev) \
++	(device_can_wakeup(dev) && (dev)->power.should_wakeup)
++
++extern int dpm_runtime_suspend(struct device *, pm_message_t);
++extern void dpm_runtime_resume(struct device *);
++
++#else /* !CONFIG_PM */
++
+ static inline int device_suspend(pm_message_t state)
+ {
+ 	return 0;
+ }
++
++#define device_set_wakeup_enable(dev,val)	do{}while(0)
++#define device_may_wakeup(dev)			(0)
++
++static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state)
++{
++	return 0;
++}
++
++static inline void dpm_runtime_resume(struct device * dev)
++{
++
++}
++
+ #endif
+ 
++/* changes to device_may_wakeup take effect on the next pm state change.
++ * by default, devices should wakeup if they can.
++ */
++#define device_can_wakeup(dev) \
++	((dev)->power.can_wakeup)
++#define device_init_wakeup(dev,val) \
++	do { \
++		device_can_wakeup(dev) = !!(val); \
++		device_set_wakeup_enable(dev,val); \
++	} while(0)
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _LINUX_PM_H */
+diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
+--- a/include/linux/radix-tree.h
++++ b/include/linux/radix-tree.h
+@@ -24,7 +24,7 @@
+ 
+ struct radix_tree_root {
+ 	unsigned int		height;
+-	unsigned int		gfp_mask;
++	gfp_t			gfp_mask;
+ 	struct radix_tree_node	*rnode;
+ };
+ 
+diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
+--- a/include/linux/rcupdate.h
++++ b/include/linux/rcupdate.h
+@@ -275,6 +275,7 @@ static inline int rcu_pending(int cpu)
+ extern void rcu_init(void);
+ extern void rcu_check_callbacks(int cpu, int user);
+ extern void rcu_restart_cpu(int cpu);
++extern long rcu_batches_completed(void);
+ 
+ /* Exported interfaces */
+ extern void FASTCALL(call_rcu(struct rcu_head *head, 
+diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
+--- a/include/linux/reiserfs_fs.h
++++ b/include/linux/reiserfs_fs.h
+@@ -1972,7 +1972,7 @@ extern struct address_space_operations r
+ 
+ /* fix_nodes.c */
+ #ifdef CONFIG_REISERFS_CHECK
+-void *reiserfs_kmalloc(size_t size, int flags, struct super_block *s);
++void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s);
+ void reiserfs_kfree(const void *vp, size_t size, struct super_block *s);
+ #else
+ static inline void *reiserfs_kmalloc(size_t size, int flags,
+diff --git a/include/linux/rmap.h b/include/linux/rmap.h
+--- a/include/linux/rmap.h
++++ b/include/linux/rmap.h
+@@ -95,8 +95,8 @@ int try_to_unmap(struct page *);
+ /*
+  * Called from mm/filemap_xip.c to unmap empty zero page
+  */
+-pte_t *page_check_address(struct page *, struct mm_struct *, unsigned long);
+-
++pte_t *page_check_address(struct page *, struct mm_struct *,
++				unsigned long, spinlock_t **);
+ 
+ /*
+  * Used by swapoff to help locate where page is expected in vma.
+diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h
+--- a/include/linux/rwsem-spinlock.h
++++ b/include/linux/rwsem-spinlock.h
+@@ -61,5 +61,10 @@ extern void FASTCALL(__up_read(struct rw
+ extern void FASTCALL(__up_write(struct rw_semaphore *sem));
+ extern void FASTCALL(__downgrade_write(struct rw_semaphore *sem));
+ 
++static inline int rwsem_is_locked(struct rw_semaphore *sem)
++{
++	return (sem->activity != 0);
++}
++
+ #endif /* __KERNEL__ */
+ #endif /* _LINUX_RWSEM_SPINLOCK_H */
+diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
+--- a/include/linux/scatterlist.h
++++ b/include/linux/scatterlist.h
+@@ -1,14 +1,23 @@
+ #ifndef _LINUX_SCATTERLIST_H
+ #define _LINUX_SCATTERLIST_H
+ 
+-static inline void sg_init_one(struct scatterlist *sg,
+-			       u8 *buf, unsigned int buflen)
+-{
+-	memset(sg, 0, sizeof(*sg));
++#include <asm/scatterlist.h>
++#include <linux/mm.h>
++#include <linux/string.h>
+ 
++static inline void sg_set_buf(struct scatterlist *sg, void *buf,
++			      unsigned int buflen)
++{
+ 	sg->page = virt_to_page(buf);
+ 	sg->offset = offset_in_page(buf);
+ 	sg->length = buflen;
+ }
+ 
++static inline void sg_init_one(struct scatterlist *sg, void *buf,
++			       unsigned int buflen)
++{
++	memset(sg, 0, sizeof(*sg));
++	sg_set_buf(sg, buf, buflen);
++}
++
+ #endif /* _LINUX_SCATTERLIST_H */
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -249,6 +249,36 @@ arch_get_unmapped_area_topdown(struct fi
+ extern void arch_unmap_area(struct mm_struct *, unsigned long);
+ extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
+ 
++#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
++/*
++ * The mm counters are not protected by its page_table_lock,
++ * so must be incremented atomically.
++ */
++#ifdef ATOMIC64_INIT
++#define set_mm_counter(mm, member, value) atomic64_set(&(mm)->_##member, value)
++#define get_mm_counter(mm, member) ((unsigned long)atomic64_read(&(mm)->_##member))
++#define add_mm_counter(mm, member, value) atomic64_add(value, &(mm)->_##member)
++#define inc_mm_counter(mm, member) atomic64_inc(&(mm)->_##member)
++#define dec_mm_counter(mm, member) atomic64_dec(&(mm)->_##member)
++typedef atomic64_t mm_counter_t;
++#else /* !ATOMIC64_INIT */
++/*
++ * The counters wrap back to 0 at 2^32 * PAGE_SIZE,
++ * that is, at 16TB if using 4kB page size.
++ */
++#define set_mm_counter(mm, member, value) atomic_set(&(mm)->_##member, value)
++#define get_mm_counter(mm, member) ((unsigned long)atomic_read(&(mm)->_##member))
++#define add_mm_counter(mm, member, value) atomic_add(value, &(mm)->_##member)
++#define inc_mm_counter(mm, member) atomic_inc(&(mm)->_##member)
++#define dec_mm_counter(mm, member) atomic_dec(&(mm)->_##member)
++typedef atomic_t mm_counter_t;
++#endif /* !ATOMIC64_INIT */
++
++#else  /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
++/*
++ * The mm counters are protected by its page_table_lock,
++ * so can be incremented directly.
++ */
+ #define set_mm_counter(mm, member, value) (mm)->_##member = (value)
+ #define get_mm_counter(mm, member) ((mm)->_##member)
+ #define add_mm_counter(mm, member, value) (mm)->_##member += (value)
+@@ -256,6 +286,20 @@ extern void arch_unmap_area_topdown(stru
+ #define dec_mm_counter(mm, member) (mm)->_##member--
+ typedef unsigned long mm_counter_t;
+ 
++#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
++
++#define get_mm_rss(mm)					\
++	(get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
++#define update_hiwater_rss(mm)	do {			\
++	unsigned long _rss = get_mm_rss(mm);		\
++	if ((mm)->hiwater_rss < _rss)			\
++		(mm)->hiwater_rss = _rss;		\
++} while (0)
++#define update_hiwater_vm(mm)	do {			\
++	if ((mm)->hiwater_vm < (mm)->total_vm)		\
++		(mm)->hiwater_vm = (mm)->total_vm;	\
++} while (0)
++
+ struct mm_struct {
+ 	struct vm_area_struct * mmap;		/* list of VMAs */
+ 	struct rb_root mm_rb;
+@@ -279,15 +323,20 @@ struct mm_struct {
+ 						 * by mmlist_lock
+ 						 */
+ 
++	/* Special counters, in some configurations protected by the
++	 * page_table_lock, in other configurations by being atomic.
++	 */
++	mm_counter_t _file_rss;
++	mm_counter_t _anon_rss;
++
++	unsigned long hiwater_rss;	/* High-watermark of RSS usage */
++	unsigned long hiwater_vm;	/* High-water virtual memory usage */
++
++	unsigned long total_vm, locked_vm, shared_vm, exec_vm;
++	unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
+ 	unsigned long start_code, end_code, start_data, end_data;
+ 	unsigned long start_brk, brk, start_stack;
+ 	unsigned long arg_start, arg_end, env_start, env_end;
+-	unsigned long total_vm, locked_vm, shared_vm;
+-	unsigned long exec_vm, stack_vm, reserved_vm, def_flags, nr_ptes;
+-
+-	/* Special counters protected by the page_table_lock */
+-	mm_counter_t _rss;
+-	mm_counter_t _anon_rss;
+ 
+ 	unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
+ 
+@@ -308,11 +357,7 @@ struct mm_struct {
+ 	/* aio bits */
+ 	rwlock_t		ioctx_list_lock;
+ 	struct kioctx		*ioctx_list;
+-
+ 	struct kioctx		default_kioctx;
+-
+-	unsigned long hiwater_rss;	/* High-water RSS usage */
+-	unsigned long hiwater_vm;	/* High-water virtual memory usage */
+ };
+ 
+ struct sighand_struct {
+@@ -895,7 +940,7 @@ extern int set_cpus_allowed(task_t *p, c
+ #else
+ static inline int set_cpus_allowed(task_t *p, cpumask_t new_mask)
+ {
+-	if (!cpus_intersects(new_mask, cpu_online_map))
++	if (!cpu_isset(0, new_mask))
+ 		return -EINVAL;
+ 	return 0;
+ }
+@@ -1039,6 +1084,11 @@ extern int do_sigaltstack(const stack_t 
+ #define SEND_SIG_PRIV	((struct siginfo *) 1)
+ #define SEND_SIG_FORCED	((struct siginfo *) 2)
+ 
++static inline int is_si_special(const struct siginfo *info)
++{
++	return info <= SEND_SIG_FORCED;
++}
++
+ /* True if we are on the alternate signal stack.  */
+ 
+ static inline int on_sig_stack(unsigned long sp)
+@@ -1166,7 +1216,7 @@ extern void unhash_process(struct task_s
+ /*
+  * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring
+  * subscriptions and synchronises with wait4().  Also used in procfs.  Also
+- * pins the final release of task.io_context.
++ * pins the final release of task.io_context.  Also protects ->cpuset.
+  *
+  * Nests both inside and outside of read_lock(&tasklist_lock).
+  * It must not be nested with write_lock_irq(&tasklist_lock),
+diff --git a/include/linux/sdladrv.h b/include/linux/sdladrv.h
+--- a/include/linux/sdladrv.h
++++ b/include/linux/sdladrv.h
+@@ -52,12 +52,8 @@ typedef struct sdlahw
+ 
+ extern int sdla_setup	(sdlahw_t* hw, void* sfm, unsigned len);
+ extern int sdla_down	(sdlahw_t* hw);
+-extern int sdla_inten	(sdlahw_t* hw);
+-extern int sdla_intde	(sdlahw_t* hw);
+-extern int sdla_intack	(sdlahw_t* hw);
+ extern void S514_intack  (sdlahw_t* hw, u32 int_status);
+ extern void read_S514_int_stat (sdlahw_t* hw, u32* int_status);
+-extern int sdla_intr	(sdlahw_t* hw);
+ extern int sdla_mapmem	(sdlahw_t* hw, unsigned long addr);
+ extern int sdla_peek	(sdlahw_t* hw, unsigned long addr, void* buf,
+ 			 unsigned len);
+diff --git a/include/linux/security.h b/include/linux/security.h
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -30,6 +30,7 @@
+ #include <linux/shm.h>
+ #include <linux/msg.h>
+ #include <linux/sched.h>
++#include <linux/key.h>
+ 
+ struct ctl_table;
+ 
+@@ -385,6 +386,9 @@ struct swap_info_struct;
+  *	NULL to request the size of the buffer required.  @size indicates
+  *	the size of @buffer in bytes.  Note that @name is the remainder
+  *	of the attribute name after the security. prefix has been removed.
++ *	@err is the return value from the preceding fs getxattr call,
++ *	and can be used by the security module to determine whether it
++ *	should try and canonicalize the attribute value.
+  *	Return number of bytes used/required on success.
+  * @inode_setsecurity:
+  *	Set the security label associated with @name for @inode from the
+@@ -785,6 +789,27 @@ struct swap_info_struct;
+  * @sk_free_security:
+  *	Deallocate security structure.
+  *
++ * Security hooks affecting all Key Management operations
++ *
++ * @key_alloc:
++ *	Permit allocation of a key and assign security data. Note that key does
++ *	not have a serial number assigned at this point.
++ *	@key points to the key.
++ *	Return 0 if permission is granted, -ve error otherwise.
++ * @key_free:
++ *	Notification of destruction; free security data.
++ *	@key points to the key.
++ *	No return value.
++ * @key_permission:
++ *	See whether a specific operational right is granted to a process on a
++ *      key.
++ *	@key_ref refers to the key (key pointer + possession attribute bit).
++ *	@context points to the process to provide the context against which to
++ *       evaluate the security data on the key.
++ *	@perm describes the combination of permissions required of this key.
++ *	Return 1 if permission granted, 0 if permission denied and -ve it the
++ *      normal permissions model should be effected.
++ *
+  * Security hooks affecting all System V IPC operations.
+  *
+  * @ipc_permission:
+@@ -1091,7 +1116,7 @@ struct security_operations {
+ 	int (*inode_getxattr) (struct dentry *dentry, char *name);
+ 	int (*inode_listxattr) (struct dentry *dentry);
+ 	int (*inode_removexattr) (struct dentry *dentry, char *name);
+-  	int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size);
++  	int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err);
+   	int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
+   	int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
+ 
+@@ -1210,9 +1235,20 @@ struct security_operations {
+ 	int (*socket_shutdown) (struct socket * sock, int how);
+ 	int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);
+ 	int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
+-	int (*sk_alloc_security) (struct sock *sk, int family, int priority);
++	int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
+ 	void (*sk_free_security) (struct sock *sk);
+ #endif	/* CONFIG_SECURITY_NETWORK */
++
++	/* key management security hooks */
++#ifdef CONFIG_KEYS
++	int (*key_alloc)(struct key *key);
++	void (*key_free)(struct key *key);
++	int (*key_permission)(key_ref_t key_ref,
++			      struct task_struct *context,
++			      key_perm_t perm);
++
++#endif	/* CONFIG_KEYS */
++
+ };
+ 
+ /* global variables */
+@@ -1580,11 +1616,11 @@ static inline int security_inode_removex
+ 	return security_ops->inode_removexattr (dentry, name);
+ }
+ 
+-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
++static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
+ {
+ 	if (unlikely (IS_PRIVATE (inode)))
+ 		return 0;
+-	return security_ops->inode_getsecurity(inode, name, buffer, size);
++	return security_ops->inode_getsecurity(inode, name, buffer, size, err);
+ }
+ 
+ static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
+@@ -2222,7 +2258,7 @@ static inline int security_inode_removex
+ 	return cap_inode_removexattr(dentry, name);
+ }
+ 
+-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
++static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
+ {
+ 	return -EOPNOTSUPP;
+ }
+@@ -2761,5 +2797,45 @@ static inline void security_sk_free(stru
+ }
+ #endif	/* CONFIG_SECURITY_NETWORK */
+ 
++#ifdef CONFIG_KEYS
++#ifdef CONFIG_SECURITY
++static inline int security_key_alloc(struct key *key)
++{
++	return security_ops->key_alloc(key);
++}
++
++static inline void security_key_free(struct key *key)
++{
++	security_ops->key_free(key);
++}
++
++static inline int security_key_permission(key_ref_t key_ref,
++					  struct task_struct *context,
++					  key_perm_t perm)
++{
++	return security_ops->key_permission(key_ref, context, perm);
++}
++
++#else
++
++static inline int security_key_alloc(struct key *key)
++{
++	return 0;
++}
++
++static inline void security_key_free(struct key *key)
++{
++}
++
++static inline int security_key_permission(key_ref_t key_ref,
++					  struct task_struct *context,
++					  key_perm_t perm)
++{
++	return 0;
++}
++
++#endif
++#endif /* CONFIG_KEYS */
++
+ #endif /* ! __LINUX_SECURITY_H */
+ 
+diff --git a/include/linux/serial.h b/include/linux/serial.h
+--- a/include/linux/serial.h
++++ b/include/linux/serial.h
+@@ -11,6 +11,7 @@
+ #define _LINUX_SERIAL_H
+ 
+ #ifdef __KERNEL__
++#include <linux/types.h>
+ #include <asm/page.h>
+ 
+ /*
+diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
+--- a/include/linux/serial_8250.h
++++ b/include/linux/serial_8250.h
+@@ -12,7 +12,7 @@
+ #define _LINUX_SERIAL_8250_H
+ 
+ #include <linux/serial_core.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ 
+ /*
+  * This is the platform device platform_data structure
+diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
+--- a/include/linux/serial_core.h
++++ b/include/linux/serial_core.h
+@@ -117,7 +117,9 @@
+ #define PORT_M32R_SIO	68
+ 
+ /*Digi jsm */
+-#define PORT_JSM        65
++#define PORT_JSM        69
++
++#define PORT_IP3106	70
+ 
+ #ifdef __KERNEL__
+ 
+diff --git a/include/linux/serial_ip3106.h b/include/linux/serial_ip3106.h
+new file mode 100644
+--- /dev/null
++++ b/include/linux/serial_ip3106.h
+@@ -0,0 +1,81 @@
++/*
++ * Embedded Alley Solutions, source at embeddedalley.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 _LINUX_SERIAL_IP3106_H
++#define _LINUX_SERIAL_IP3106_H
++
++#include <linux/serial_core.h>
++#include <linux/device.h>
++
++#define IP3106_NR_PORTS		2
++
++struct ip3106_port {
++	struct uart_port	port;
++	struct timer_list	timer;
++	unsigned int		old_status;
++};
++
++/* register offsets */
++#define IP3106_LCR		0
++#define IP3106_MCR		0x004
++#define IP3106_BAUD		0x008
++#define IP3106_CFG		0x00c
++#define IP3106_FIFO		0x028
++#define IP3106_ISTAT		0xfe0
++#define IP3106_IEN		0xfe4
++#define IP3106_ICLR		0xfe8
++#define IP3106_ISET		0xfec
++#define IP3106_PD		0xff4
++#define IP3106_MID		0xffc
++
++#define IP3106_UART_LCR_TXBREAK		(1<<30)
++#define IP3106_UART_LCR_PAREVN		0x10000000
++#define IP3106_UART_LCR_PAREN		0x08000000
++#define IP3106_UART_LCR_2STOPB		0x04000000
++#define IP3106_UART_LCR_8BIT		0x01000000
++#define IP3106_UART_LCR_TX_RST		0x00040000
++#define IP3106_UART_LCR_RX_RST		0x00020000
++#define IP3106_UART_LCR_RX_NEXT		0x00010000
++
++#define IP3106_UART_MCR_SCR		0xFF000000
++#define IP3106_UART_MCR_DCD		0x00800000
++#define IP3106_UART_MCR_CTS		0x00100000
++#define IP3106_UART_MCR_LOOP		0x00000010
++#define IP3106_UART_MCR_RTS		0x00000002
++#define IP3106_UART_MCR_DTR		0x00000001
++
++#define IP3106_UART_INT_TX		0x00000080
++#define IP3106_UART_INT_EMPTY		0x00000040
++#define IP3106_UART_INT_RCVTO		0x00000020
++#define IP3106_UART_INT_RX		0x00000010
++#define IP3106_UART_INT_RXOVRN		0x00000008
++#define IP3106_UART_INT_FRERR		0x00000004
++#define IP3106_UART_INT_BREAK		0x00000002
++#define IP3106_UART_INT_PARITY		0x00000001
++#define IP3106_UART_INT_ALLRX		0x0000003F
++#define IP3106_UART_INT_ALLTX		0x000000C0
++
++#define IP3106_UART_FIFO_TXFIFO		0x001F0000
++#define IP3106_UART_FIFO_TXFIFO_STA	(0x1f<<16)
++#define IP3106_UART_FIFO_RXBRK		0x00008000
++#define IP3106_UART_FIFO_RXFE		0x00004000
++#define IP3106_UART_FIFO_RXPAR		0x00002000
++#define IP3106_UART_FIFO_RXFIFO		0x00001F00
++#define IP3106_UART_FIFO_RBRTHR		0x000000FF
++
++#endif
+diff --git a/include/linux/signal.h b/include/linux/signal.h
+--- a/include/linux/signal.h
++++ b/include/linux/signal.h
+@@ -25,7 +25,6 @@
+ 
+ struct sigqueue {
+ 	struct list_head list;
+-	spinlock_t *lock;
+ 	int flags;
+ 	siginfo_t info;
+ 	struct user_struct *user;
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -137,6 +137,8 @@ struct skb_shared_info {
+ 	unsigned int	nr_frags;
+ 	unsigned short	tso_size;
+ 	unsigned short	tso_segs;
++	unsigned short  ufo_size;
++	unsigned int    ip6_frag_id;
+ 	struct sk_buff	*frag_list;
+ 	skb_frag_t	frags[MAX_SKB_FRAGS];
+ };
+@@ -171,7 +173,6 @@ enum {
+  *	struct sk_buff - socket buffer
+  *	@next: Next buffer in list
+  *	@prev: Previous buffer in list
+- *	@list: List we are on
+  *	@sk: Socket we are owned by
+  *	@tstamp: Time we arrived
+  *	@dev: Device we arrived on/are leaving by
+@@ -190,6 +191,7 @@ enum {
+  *	@cloned: Head may be cloned (check refcnt to be sure)
+  *	@nohdr: Payload reference only, must not modify header
+  *	@pkt_type: Packet class
++ *	@fclone: skbuff clone status
+  *	@ip_summed: Driver fed us an IP checksum
+  *	@priority: Packet queueing priority
+  *	@users: User count - see {datagram,tcp}.c
+@@ -202,6 +204,7 @@ enum {
+  *	@destructor: Destruct function
+  *	@nfmark: Can be used for communication between hooks
+  *	@nfct: Associated connection, if any
++ *	@ipvs_property: skbuff is owned by ipvs
+  *	@nfctinfo: Relationship of this skb to the connection
+  *	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c
+  *	@tc_index: Traffic control index
+@@ -340,6 +343,11 @@ extern void	      skb_over_panic(struct 
+ extern void	      skb_under_panic(struct sk_buff *skb, int len,
+ 				      void *here);
+ 
++extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
++			int getfrag(void *from, char *to, int offset,
++			int len,int odd, struct sk_buff *skb),
++			void *from, int length);
++
+ struct skb_seq_state
+ {
+ 	__u32		lower_offset;
+diff --git a/include/linux/slab.h b/include/linux/slab.h
+--- a/include/linux/slab.h
++++ b/include/linux/slab.h
+@@ -121,7 +121,7 @@ extern unsigned int ksize(const void *);
+ extern void *kmem_cache_alloc_node(kmem_cache_t *, gfp_t flags, int node);
+ extern void *kmalloc_node(size_t size, gfp_t flags, int node);
+ #else
+-static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int node)
++static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int node)
+ {
+ 	return kmem_cache_alloc(cachep, flags);
+ }
+diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
+--- a/include/linux/spinlock.h
++++ b/include/linux/spinlock.h
+@@ -171,23 +171,42 @@ extern int __lockfunc generic__raw_read_
+ #define write_lock_irq(lock)		_write_lock_irq(lock)
+ #define write_lock_bh(lock)		_write_lock_bh(lock)
+ 
+-#define spin_unlock(lock)		_spin_unlock(lock)
+-#define write_unlock(lock)		_write_unlock(lock)
+-#define read_unlock(lock)		_read_unlock(lock)
++/*
++ * We inline the unlock functions in the nondebug case:
++ */
++#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
++# define spin_unlock(lock)		_spin_unlock(lock)
++# define read_unlock(lock)		_read_unlock(lock)
++# define write_unlock(lock)		_write_unlock(lock)
++#else
++# define spin_unlock(lock)		__raw_spin_unlock(&(lock)->raw_lock)
++# define read_unlock(lock)		__raw_read_unlock(&(lock)->raw_lock)
++# define write_unlock(lock)		__raw_write_unlock(&(lock)->raw_lock)
++#endif
++
++#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
++# define spin_unlock_irq(lock)		_spin_unlock_irq(lock)
++# define read_unlock_irq(lock)		_read_unlock_irq(lock)
++# define write_unlock_irq(lock)		_write_unlock_irq(lock)
++#else
++# define spin_unlock_irq(lock) \
++    do { __raw_spin_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
++# define read_unlock_irq(lock) \
++    do { __raw_read_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
++# define write_unlock_irq(lock) \
++    do { __raw_write_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
++#endif
+ 
+ #define spin_unlock_irqrestore(lock, flags) \
+ 					_spin_unlock_irqrestore(lock, flags)
+-#define spin_unlock_irq(lock)		_spin_unlock_irq(lock)
+ #define spin_unlock_bh(lock)		_spin_unlock_bh(lock)
+ 
+ #define read_unlock_irqrestore(lock, flags) \
+ 					_read_unlock_irqrestore(lock, flags)
+-#define read_unlock_irq(lock)		_read_unlock_irq(lock)
+ #define read_unlock_bh(lock)		_read_unlock_bh(lock)
+ 
+ #define write_unlock_irqrestore(lock, flags) \
+ 					_write_unlock_irqrestore(lock, flags)
+-#define write_unlock_irq(lock)		_write_unlock_irq(lock)
+ #define write_unlock_bh(lock)		_write_unlock_bh(lock)
+ 
+ #define spin_trylock_bh(lock)		__cond_lock(_spin_trylock_bh(lock))
+diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
+--- a/include/linux/sunrpc/auth.h
++++ b/include/linux/sunrpc/auth.h
+@@ -66,7 +66,12 @@ struct rpc_cred_cache {
+ 
+ struct rpc_auth {
+ 	unsigned int		au_cslack;	/* call cred size estimate */
+-	unsigned int		au_rslack;	/* reply verf size guess */
++				/* guess at number of u32's auth adds before
++				 * reply data; normally the verifier size: */
++	unsigned int		au_rslack;
++				/* for gss, used to calculate au_rslack: */
++	unsigned int		au_verfsize;
++
+ 	unsigned int		au_flags;	/* various flags */
+ 	struct rpc_authops *	au_ops;		/* operations */
+ 	rpc_authflavor_t	au_flavor;	/* pseudoflavor (note may
+diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
+--- a/include/linux/sunrpc/debug.h
++++ b/include/linux/sunrpc/debug.h
+@@ -32,6 +32,7 @@
+ #define RPCDBG_AUTH		0x0010
+ #define RPCDBG_PMAP		0x0020
+ #define RPCDBG_SCHED		0x0040
++#define RPCDBG_TRANS		0x0080
+ #define RPCDBG_SVCSOCK		0x0100
+ #define RPCDBG_SVCDSP		0x0200
+ #define RPCDBG_MISC		0x0400
+@@ -94,6 +95,8 @@ enum {
+ 	CTL_NLMDEBUG,
+ 	CTL_SLOTTABLE_UDP,
+ 	CTL_SLOTTABLE_TCP,
++	CTL_MIN_RESVPORT,
++	CTL_MAX_RESVPORT,
+ };
+ 
+ #endif /* _LINUX_SUNRPC_DEBUG_H_ */
+diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
+--- a/include/linux/sunrpc/gss_api.h
++++ b/include/linux/sunrpc/gss_api.h
+@@ -40,14 +40,21 @@ int gss_import_sec_context(
+ 		struct gss_ctx		**ctx_id);
+ u32 gss_get_mic(
+ 		struct gss_ctx		*ctx_id,
+-		u32			qop,
+ 		struct xdr_buf		*message,
+ 		struct xdr_netobj	*mic_token);
+ u32 gss_verify_mic(
+ 		struct gss_ctx		*ctx_id,
+ 		struct xdr_buf		*message,
+-		struct xdr_netobj	*mic_token,
+-		u32			*qstate);
++		struct xdr_netobj	*mic_token);
++u32 gss_wrap(
++		struct gss_ctx		*ctx_id,
++		int			offset,
++		struct xdr_buf		*outbuf,
++		struct page		**inpages);
++u32 gss_unwrap(
++		struct gss_ctx		*ctx_id,
++		int			offset,
++		struct xdr_buf		*inbuf);
+ u32 gss_delete_sec_context(
+ 		struct gss_ctx		**ctx_id);
+ 
+@@ -56,7 +63,6 @@ char *gss_service_to_auth_domain_name(st
+ 
+ struct pf_desc {
+ 	u32	pseudoflavor;
+-	u32	qop;
+ 	u32	service;
+ 	char	*name;
+ 	char	*auth_domain_name;
+@@ -85,14 +91,21 @@ struct gss_api_ops {
+ 			struct gss_ctx		*ctx_id);
+ 	u32 (*gss_get_mic)(
+ 			struct gss_ctx		*ctx_id,
+-			u32			qop, 
+ 			struct xdr_buf		*message,
+ 			struct xdr_netobj	*mic_token);
+ 	u32 (*gss_verify_mic)(
+ 			struct gss_ctx		*ctx_id,
+ 			struct xdr_buf		*message,
+-			struct xdr_netobj	*mic_token,
+-			u32			*qstate);
++			struct xdr_netobj	*mic_token);
++	u32 (*gss_wrap)(
++			struct gss_ctx		*ctx_id,
++			int			offset,
++			struct xdr_buf		*outbuf,
++			struct page		**inpages);
++	u32 (*gss_unwrap)(
++			struct gss_ctx		*ctx_id,
++			int			offset,
++			struct xdr_buf		*buf);
+ 	void (*gss_delete_sec_context)(
+ 			void			*internal_ctx_id);
+ };
+diff --git a/include/linux/sunrpc/gss_err.h b/include/linux/sunrpc/gss_err.h
+--- a/include/linux/sunrpc/gss_err.h
++++ b/include/linux/sunrpc/gss_err.h
+@@ -66,16 +66,6 @@ typedef unsigned int OM_uint32;
+ 
+ 
+ /*
+- * Define the default Quality of Protection for per-message services.  Note
+- * that an implementation that offers multiple levels of QOP may either reserve
+- * a value (for example zero, as assumed here) to mean "default protection", or
+- * alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
+- * QOP value.  However a value of 0 should always be interpreted by a GSSAPI
+- * implementation as a request for the default protection level.
+- */
+-#define GSS_C_QOP_DEFAULT 0
+-
+-/*
+  * Expiration time of 2^32-1 seconds means infinite lifetime for a
+  * credential or security context
+  */
+diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
+--- a/include/linux/sunrpc/gss_krb5.h
++++ b/include/linux/sunrpc/gss_krb5.h
+@@ -116,18 +116,22 @@ enum seal_alg {
+ 
+ s32
+ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
+-		   struct xdr_netobj *cksum);
++		   int body_offset, struct xdr_netobj *cksum);
++
++u32 gss_get_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
++		struct xdr_netobj *);
++
++u32 gss_verify_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
++		struct xdr_netobj *);
+ 
+ u32
+-krb5_make_token(struct krb5_ctx *context_handle, int qop_req,
+-	struct xdr_buf *input_message_buffer,
+-	struct xdr_netobj *output_message_buffer, int toktype);
++gss_wrap_kerberos(struct gss_ctx *ctx_id, int offset,
++		struct xdr_buf *outbuf, struct page **pages);
+ 
+ u32
+-krb5_read_token(struct krb5_ctx *context_handle,
+-	  struct xdr_netobj *input_token_buffer,
+-	  struct xdr_buf *message_buffer,
+-	  int *qop_state, int toktype);
++gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset,
++		struct xdr_buf *buf);
++
+ 
+ u32
+ krb5_encrypt(struct crypto_tfm * key,
+@@ -137,6 +141,13 @@ u32
+ krb5_decrypt(struct crypto_tfm * key,
+ 	     void *iv, void *in, void *out, int length); 
+ 
++int
++gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *outbuf, int offset,
++		struct page **pages);
++
++int
++gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *inbuf, int offset);
++
+ s32
+ krb5_make_seq_num(struct crypto_tfm * key,
+ 		int direction,
+diff --git a/include/linux/sunrpc/gss_spkm3.h b/include/linux/sunrpc/gss_spkm3.h
+--- a/include/linux/sunrpc/gss_spkm3.h
++++ b/include/linux/sunrpc/gss_spkm3.h
+@@ -41,9 +41,9 @@ struct spkm3_ctx {
+ #define SPKM_WRAP_TOK	5
+ #define SPKM_DEL_TOK	6
+ 
+-u32 spkm3_make_token(struct spkm3_ctx *ctx, int qop_req, struct xdr_buf * text, struct xdr_netobj * token, int toktype);
++u32 spkm3_make_token(struct spkm3_ctx *ctx, struct xdr_buf * text, struct xdr_netobj * token, int toktype);
+ 
+-u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int *qop_state, int toktype);
++u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int toktype);
+ 
+ #define CKSUMTYPE_RSA_MD5            0x0007
+ 
+diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
+--- a/include/linux/sunrpc/msg_prot.h
++++ b/include/linux/sunrpc/msg_prot.h
+@@ -76,5 +76,30 @@ enum rpc_auth_stat {
+ 
+ #define RPC_MAXNETNAMELEN	256
+ 
++/*
++ * From RFC 1831:
++ *
++ * "A record is composed of one or more record fragments.  A record
++ *  fragment is a four-byte header followed by 0 to (2**31) - 1 bytes of
++ *  fragment data.  The bytes encode an unsigned binary number; as with
++ *  XDR integers, the byte order is from highest to lowest.  The number
++ *  encodes two values -- a boolean which indicates whether the fragment
++ *  is the last fragment of the record (bit value 1 implies the fragment
++ *  is the last fragment) and a 31-bit unsigned binary value which is the
++ *  length in bytes of the fragment's data.  The boolean value is the
++ *  highest-order bit of the header; the length is the 31 low-order bits.
++ *  (Note that this record specification is NOT in XDR standard form!)"
++ *
++ * The Linux RPC client always sends its requests in a single record
++ * fragment, limiting the maximum payload size for stream transports to
++ * 2GB.
++ */
++
++typedef u32	rpc_fraghdr;
++
++#define	RPC_LAST_STREAM_FRAGMENT	(1U << 31)
++#define	RPC_FRAGMENT_SIZE_MASK		(~RPC_LAST_STREAM_FRAGMENT)
++#define	RPC_MAX_FRAGMENT_SIZE		((1U << 31) - 1)
++
+ #endif /* __KERNEL__ */
+ #endif /* _LINUX_SUNRPC_MSGPROT_H_ */
+diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
+--- a/include/linux/sunrpc/xdr.h
++++ b/include/linux/sunrpc/xdr.h
+@@ -161,14 +161,10 @@ typedef struct {
+ 
+ typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
+ 
++extern int csum_partial_copy_to_xdr(struct xdr_buf *, struct sk_buff *);
+ extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
+ 		skb_reader_t *, skb_read_actor_t);
+ 
+-struct socket;
+-struct sockaddr;
+-extern int xdr_sendpages(struct socket *, struct sockaddr *, int,
+-		struct xdr_buf *, unsigned int, int);
+-
+ extern int xdr_encode_word(struct xdr_buf *, int, u32);
+ extern int xdr_decode_word(struct xdr_buf *, int, u32 *);
+ 
+diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
+--- a/include/linux/sunrpc/xprt.h
++++ b/include/linux/sunrpc/xprt.h
+@@ -1,5 +1,5 @@
+ /*
+- *  linux/include/linux/sunrpc/clnt_xprt.h
++ *  linux/include/linux/sunrpc/xprt.h
+  *
+  *  Declarations for the RPC transport interface.
+  *
+@@ -15,20 +15,6 @@
+ #include <linux/sunrpc/sched.h>
+ #include <linux/sunrpc/xdr.h>
+ 
+-/*
+- * The transport code maintains an estimate on the maximum number of out-
+- * standing RPC requests, using a smoothed version of the congestion
+- * avoidance implemented in 44BSD. This is basically the Van Jacobson
+- * congestion algorithm: If a retransmit occurs, the congestion window is
+- * halved; otherwise, it is incremented by 1/cwnd when
+- *
+- *	-	a reply is received and
+- *	-	a full number of requests are outstanding and
+- *	-	the congestion window hasn't been updated recently.
+- *
+- * Upper procedures may check whether a request would block waiting for
+- * a free RPC slot by using the RPC_CONGESTED() macro.
+- */
+ extern unsigned int xprt_udp_slot_table_entries;
+ extern unsigned int xprt_tcp_slot_table_entries;
+ 
+@@ -36,34 +22,23 @@ extern unsigned int xprt_tcp_slot_table_
+ #define RPC_DEF_SLOT_TABLE	(16U)
+ #define RPC_MAX_SLOT_TABLE	(128U)
+ 
+-#define RPC_CWNDSHIFT		(8U)
+-#define RPC_CWNDSCALE		(1U << RPC_CWNDSHIFT)
+-#define RPC_INITCWND		RPC_CWNDSCALE
+-#define RPC_MAXCWND(xprt)	((xprt)->max_reqs << RPC_CWNDSHIFT)
+-#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
+-
+-/* Default timeout values */
+-#define RPC_MAX_UDP_TIMEOUT	(60*HZ)
+-#define RPC_MAX_TCP_TIMEOUT	(600*HZ)
+-
+ /*
+- * Wait duration for an RPC TCP connection to be established.  Solaris
+- * NFS over TCP uses 60 seconds, for example, which is in line with how
+- * long a server takes to reboot.
++ * RPC call and reply header size as number of 32bit words (verifier
++ * size computed separately)
+  */
+-#define RPC_CONNECT_TIMEOUT	(60*HZ)
++#define RPC_CALLHDRSIZE		6
++#define RPC_REPHDRSIZE		4
+ 
+ /*
+- * Delay an arbitrary number of seconds before attempting to reconnect
+- * after an error.
++ * Parameters for choosing a free port
+  */
+-#define RPC_REESTABLISH_TIMEOUT	(15*HZ)
++extern unsigned int xprt_min_resvport;
++extern unsigned int xprt_max_resvport;
+ 
+-/* RPC call and reply header size as number of 32bit words (verifier
+- * size computed separately)
+- */
+-#define RPC_CALLHDRSIZE		6
+-#define RPC_REPHDRSIZE		4
++#define RPC_MIN_RESVPORT	(1U)
++#define RPC_MAX_RESVPORT	(65535U)
++#define RPC_DEF_MIN_RESVPORT	(650U)
++#define RPC_DEF_MAX_RESVPORT	(1023U)
+ 
+ /*
+  * This describes a timeout strategy
+@@ -76,6 +51,9 @@ struct rpc_timeout {
+ 	unsigned char		to_exponential;
+ };
+ 
++struct rpc_task;
++struct rpc_xprt;
++
+ /*
+  * This describes a complete RPC request
+  */
+@@ -95,7 +73,10 @@ struct rpc_rqst {
+ 	int			rq_cong;	/* has incremented xprt->cong */
+ 	int			rq_received;	/* receive completed */
+ 	u32			rq_seqno;	/* gss seq no. used on req. */
+-
++	int			rq_enc_pages_num;
++	struct page		**rq_enc_pages;	/* scratch pages for use by
++						   gss privacy code */
++	void (*rq_release_snd_buf)(struct rpc_rqst *); /* release rq_enc_pages */
+ 	struct list_head	rq_list;
+ 
+ 	struct xdr_buf		rq_private_buf;		/* The receive buffer
+@@ -121,12 +102,21 @@ struct rpc_rqst {
+ #define rq_svec			rq_snd_buf.head
+ #define rq_slen			rq_snd_buf.len
+ 
+-#define XPRT_LAST_FRAG		(1 << 0)
+-#define XPRT_COPY_RECM		(1 << 1)
+-#define XPRT_COPY_XID		(1 << 2)
+-#define XPRT_COPY_DATA		(1 << 3)
++struct rpc_xprt_ops {
++	void		(*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize);
++	int		(*reserve_xprt)(struct rpc_task *task);
++	void		(*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task);
++	void		(*connect)(struct rpc_task *task);
++	int		(*send_request)(struct rpc_task *task);
++	void		(*set_retrans_timeout)(struct rpc_task *task);
++	void		(*timer)(struct rpc_task *task);
++	void		(*release_request)(struct rpc_task *task);
++	void		(*close)(struct rpc_xprt *xprt);
++	void		(*destroy)(struct rpc_xprt *xprt);
++};
+ 
+ struct rpc_xprt {
++	struct rpc_xprt_ops *	ops;		/* transport methods */
+ 	struct socket *		sock;		/* BSD socket layer */
+ 	struct sock *		inet;		/* INET layer */
+ 
+@@ -137,11 +127,13 @@ struct rpc_xprt {
+ 	unsigned long		cong;		/* current congestion */
+ 	unsigned long		cwnd;		/* congestion window */
+ 
+-	unsigned int		rcvsize,	/* socket receive buffer size */
+-				sndsize;	/* socket send buffer size */
++	size_t			rcvsize,	/* transport rcv buffer size */
++				sndsize;	/* transport send buffer size */
+ 
+ 	size_t			max_payload;	/* largest RPC payload size,
+ 						   in bytes */
++	unsigned int		tsh_size;	/* size of transport specific
++						   header */
+ 
+ 	struct rpc_wait_queue	sending;	/* requests waiting to send */
+ 	struct rpc_wait_queue	resend;		/* requests waiting to resend */
+@@ -150,11 +142,9 @@ struct rpc_xprt {
+ 	struct list_head	free;		/* free slots */
+ 	struct rpc_rqst *	slot;		/* slot table storage */
+ 	unsigned int		max_reqs;	/* total slots */
+-	unsigned long		sockstate;	/* Socket state */
++	unsigned long		state;		/* transport state */
+ 	unsigned char		shutdown   : 1,	/* being shut down */
+-				nocong	   : 1,	/* no congestion control */
+-				resvport   : 1, /* use a reserved port */
+-				stream     : 1;	/* TCP */
++				resvport   : 1; /* use a reserved port */
+ 
+ 	/*
+ 	 * XID
+@@ -171,22 +161,27 @@ struct rpc_xprt {
+ 	unsigned long		tcp_copied,	/* copied to request */
+ 				tcp_flags;
+ 	/*
+-	 * Connection of sockets
++	 * Connection of transports
+ 	 */
+-	struct work_struct	sock_connect;
++	unsigned long		connect_timeout,
++				bind_timeout,
++				reestablish_timeout;
++	struct work_struct	connect_worker;
+ 	unsigned short		port;
++
+ 	/*
+-	 * Disconnection of idle sockets
++	 * Disconnection of idle transports
+ 	 */
+ 	struct work_struct	task_cleanup;
+ 	struct timer_list	timer;
+-	unsigned long		last_used;
++	unsigned long		last_used,
++				idle_timeout;
+ 
+ 	/*
+ 	 * Send stuff
+ 	 */
+-	spinlock_t		sock_lock;	/* lock socket info */
+-	spinlock_t		xprt_lock;	/* lock xprt info */
++	spinlock_t		transport_lock;	/* lock transport info */
++	spinlock_t		reserve_lock;	/* lock slot table */
+ 	struct rpc_task *	snd_task;	/* Task blocked in send */
+ 
+ 	struct list_head	recv;
+@@ -195,37 +190,111 @@ struct rpc_xprt {
+ 	void			(*old_data_ready)(struct sock *, int);
+ 	void			(*old_state_change)(struct sock *);
+ 	void			(*old_write_space)(struct sock *);
+-
+-	wait_queue_head_t	cong_wait;
+ };
+ 
++#define XPRT_LAST_FRAG		(1 << 0)
++#define XPRT_COPY_RECM		(1 << 1)
++#define XPRT_COPY_XID		(1 << 2)
++#define XPRT_COPY_DATA		(1 << 3)
++
+ #ifdef __KERNEL__
+ 
+-struct rpc_xprt *	xprt_create_proto(int proto, struct sockaddr_in *addr,
+-					struct rpc_timeout *toparms);
+-int			xprt_destroy(struct rpc_xprt *);
+-void			xprt_set_timeout(struct rpc_timeout *, unsigned int,
+-					unsigned long);
+-
+-void			xprt_reserve(struct rpc_task *);
+-int			xprt_prepare_transmit(struct rpc_task *);
+-void			xprt_transmit(struct rpc_task *);
+-void			xprt_receive(struct rpc_task *);
++/*
++ * Transport operations used by ULPs
++ */
++struct rpc_xprt *	xprt_create_proto(int proto, struct sockaddr_in *addr, struct rpc_timeout *to);
++void			xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr);
++
++/*
++ * Generic internal transport functions
++ */
++void			xprt_connect(struct rpc_task *task);
++void			xprt_reserve(struct rpc_task *task);
++int			xprt_reserve_xprt(struct rpc_task *task);
++int			xprt_reserve_xprt_cong(struct rpc_task *task);
++int			xprt_prepare_transmit(struct rpc_task *task);
++void			xprt_transmit(struct rpc_task *task);
++void			xprt_abort_transmit(struct rpc_task *task);
+ int			xprt_adjust_timeout(struct rpc_rqst *req);
+-void			xprt_release(struct rpc_task *);
+-void			xprt_connect(struct rpc_task *);
+-void			xprt_sock_setbufsize(struct rpc_xprt *);
+-
+-#define XPRT_LOCKED	0
+-#define XPRT_CONNECT	1
+-#define XPRT_CONNECTING	2
+-
+-#define xprt_connected(xp)		(test_bit(XPRT_CONNECT, &(xp)->sockstate))
+-#define xprt_set_connected(xp)		(set_bit(XPRT_CONNECT, &(xp)->sockstate))
+-#define xprt_test_and_set_connected(xp)	(test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
+-#define xprt_test_and_clear_connected(xp) \
+-					(test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate))
+-#define xprt_clear_connected(xp)	(clear_bit(XPRT_CONNECT, &(xp)->sockstate))
++void			xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
++void			xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
++void			xprt_release(struct rpc_task *task);
++int			xprt_destroy(struct rpc_xprt *xprt);
++
++static inline u32 *xprt_skip_transport_header(struct rpc_xprt *xprt, u32 *p)
++{
++	return p + xprt->tsh_size;
++}
++
++/*
++ * Transport switch helper functions
++ */
++void			xprt_set_retrans_timeout_def(struct rpc_task *task);
++void			xprt_set_retrans_timeout_rtt(struct rpc_task *task);
++void			xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status);
++void			xprt_wait_for_buffer_space(struct rpc_task *task);
++void			xprt_write_space(struct rpc_xprt *xprt);
++void			xprt_update_rtt(struct rpc_task *task);
++void			xprt_adjust_cwnd(struct rpc_task *task, int result);
++struct rpc_rqst *	xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid);
++void			xprt_complete_rqst(struct rpc_task *task, int copied);
++void			xprt_release_rqst_cong(struct rpc_task *task);
++void			xprt_disconnect(struct rpc_xprt *xprt);
++
++/*
++ * Socket transport setup operations
++ */
++int			xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to);
++int			xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to);
++
++/*
++ * Reserved bit positions in xprt->state
++ */
++#define XPRT_LOCKED		(0)
++#define XPRT_CONNECTED		(1)
++#define XPRT_CONNECTING		(2)
++
++static inline void xprt_set_connected(struct rpc_xprt *xprt)
++{
++	set_bit(XPRT_CONNECTED, &xprt->state);
++}
++
++static inline void xprt_clear_connected(struct rpc_xprt *xprt)
++{
++	clear_bit(XPRT_CONNECTED, &xprt->state);
++}
++
++static inline int xprt_connected(struct rpc_xprt *xprt)
++{
++	return test_bit(XPRT_CONNECTED, &xprt->state);
++}
++
++static inline int xprt_test_and_set_connected(struct rpc_xprt *xprt)
++{
++	return test_and_set_bit(XPRT_CONNECTED, &xprt->state);
++}
++
++static inline int xprt_test_and_clear_connected(struct rpc_xprt *xprt)
++{
++	return test_and_clear_bit(XPRT_CONNECTED, &xprt->state);
++}
++
++static inline void xprt_clear_connecting(struct rpc_xprt *xprt)
++{
++	smp_mb__before_clear_bit();
++	clear_bit(XPRT_CONNECTING, &xprt->state);
++	smp_mb__after_clear_bit();
++}
++
++static inline int xprt_connecting(struct rpc_xprt *xprt)
++{
++	return test_bit(XPRT_CONNECTING, &xprt->state);
++}
++
++static inline int xprt_test_and_set_connecting(struct rpc_xprt *xprt)
++{
++	return test_and_set_bit(XPRT_CONNECTING, &xprt->state);
++}
+ 
+ #endif /* __KERNEL__*/
+ 
+diff --git a/include/linux/suspend.h b/include/linux/suspend.h
+--- a/include/linux/suspend.h
++++ b/include/linux/suspend.h
+@@ -71,7 +71,12 @@ void restore_processor_state(void);
+ struct saved_context;
+ void __save_processor_state(struct saved_context *ctxt);
+ void __restore_processor_state(struct saved_context *ctxt);
+-extern unsigned long get_usable_page(unsigned gfp_mask);
+-extern void free_eaten_memory(void);
++unsigned long get_safe_page(gfp_t gfp_mask);
++
++/*
++ * XXX: We try to keep some more pages free so that I/O operations succeed
++ * without paging. Might this be more?
++ */
++#define PAGES_FOR_IO	512
+ 
+ #endif /* _LINUX_SWSUSP_H */
+diff --git a/include/linux/swap.h b/include/linux/swap.h
+--- a/include/linux/swap.h
++++ b/include/linux/swap.h
+@@ -171,8 +171,8 @@ extern int rotate_reclaimable_page(struc
+ extern void swap_setup(void);
+ 
+ /* linux/mm/vmscan.c */
+-extern int try_to_free_pages(struct zone **, unsigned int);
+-extern int zone_reclaim(struct zone *, unsigned int, unsigned int);
++extern int try_to_free_pages(struct zone **, gfp_t);
++extern int zone_reclaim(struct zone *, gfp_t, unsigned int);
+ extern int shrink_all_memory(int);
+ extern int vm_swappiness;
+ 
+diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
+--- a/include/linux/syscalls.h
++++ b/include/linux/syscalls.h
+@@ -491,6 +491,7 @@ asmlinkage long sys_nfsservctl(int cmd,
+ asmlinkage long sys_syslog(int type, char __user *buf, int len);
+ asmlinkage long sys_uselib(const char __user *library);
+ asmlinkage long sys_ni_syscall(void);
++asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
+ 
+ asmlinkage long sys_add_key(const char __user *_type,
+ 			    const char __user *_description,
+diff --git a/include/linux/textsearch.h b/include/linux/textsearch.h
+--- a/include/linux/textsearch.h
++++ b/include/linux/textsearch.h
+@@ -8,6 +8,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/err.h>
++#include <linux/slab.h>
+ 
+ struct ts_config;
+ 
+@@ -40,7 +41,7 @@ struct ts_state
+ struct ts_ops
+ {
+ 	const char		*name;
+-	struct ts_config *	(*init)(const void *, unsigned int, int);
++	struct ts_config *	(*init)(const void *, unsigned int, gfp_t);
+ 	unsigned int		(*find)(struct ts_config *,
+ 					struct ts_state *);
+ 	void			(*destroy)(struct ts_config *);
+@@ -148,7 +149,7 @@ static inline unsigned int textsearch_ge
+ extern int textsearch_register(struct ts_ops *);
+ extern int textsearch_unregister(struct ts_ops *);
+ extern struct ts_config *textsearch_prepare(const char *, const void *,
+-					    unsigned int, int, int);
++					    unsigned int, gfp_t, int);
+ extern void textsearch_destroy(struct ts_config *conf);
+ extern unsigned int textsearch_find_continuous(struct ts_config *,
+ 					       struct ts_state *,
+diff --git a/include/linux/timer.h b/include/linux/timer.h
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -12,16 +12,12 @@ struct timer_list {
+ 	struct list_head entry;
+ 	unsigned long expires;
+ 
+-	unsigned long magic;
+-
+ 	void (*function)(unsigned long);
+ 	unsigned long data;
+ 
+ 	struct timer_base_s *base;
+ };
+ 
+-#define TIMER_MAGIC	0x4b87ad6e
+-
+ extern struct timer_base_s __init_timer_base;
+ 
+ #define TIMER_INITIALIZER(_function, _expires, _data) {		\
+@@ -29,7 +25,6 @@ extern struct timer_base_s __init_timer_
+ 		.expires = (_expires),				\
+ 		.data = (_data),				\
+ 		.base = &__init_timer_base,			\
+-		.magic = TIMER_MAGIC,				\
+ 	}
+ 
+ #define DEFINE_TIMER(_name, _function, _expires, _data)		\
+@@ -38,6 +33,15 @@ extern struct timer_base_s __init_timer_
+ 
+ void fastcall init_timer(struct timer_list * timer);
+ 
++static inline void setup_timer(struct timer_list * timer,
++				void (*function)(unsigned long),
++				unsigned long data)
++{
++	timer->function = function;
++	timer->data = data;
++	init_timer(timer);
++}
++
+ /***
+  * timer_pending - is a timer pending?
+  * @timer: the timer in question
+@@ -74,8 +78,9 @@ extern unsigned long next_timer_interrup
+  * Timers with an ->expired field in the past will be executed in the next
+  * timer tick.
+  */
+-static inline void add_timer(struct timer_list * timer)
++static inline void add_timer(struct timer_list *timer)
+ {
++	BUG_ON(timer_pending(timer));
+ 	__mod_timer(timer, timer->expires);
+ }
+ 
+diff --git a/include/linux/timex.h b/include/linux/timex.h
+--- a/include/linux/timex.h
++++ b/include/linux/timex.h
+@@ -282,6 +282,13 @@ static inline int ntp_synced(void)
+ 	return !(time_status & STA_UNSYNC);
+ }
+ 
++/* Required to safely shift negative values */
++#define shift_right(x, s) ({	\
++	__typeof__(x) __x = (x);	\
++	__typeof__(s) __s = (s);	\
++	__x < 0 ? -(-__x >> __s) : __x >> __s;	\
++})
++
+ 
+ #ifdef CONFIG_TIME_INTERPOLATION
+ 
+diff --git a/include/linux/types.h b/include/linux/types.h
+--- a/include/linux/types.h
++++ b/include/linux/types.h
+@@ -151,7 +151,12 @@ typedef unsigned long sector_t;
+  */
+ 
+ #ifdef __CHECKER__
+-#define __bitwise __attribute__((bitwise))
++#define __bitwise__ __attribute__((bitwise))
++#else
++#define __bitwise__
++#endif
++#ifdef __CHECK_ENDIAN__
++#define __bitwise __bitwise__
+ #else
+ #define __bitwise
+ #endif
+@@ -166,7 +171,7 @@ typedef __u64 __bitwise __be64;
+ #endif
+ 
+ #ifdef __KERNEL__
+-typedef unsigned __nocast gfp_t;
++typedef unsigned __bitwise__ gfp_t;
+ #endif
+ 
+ struct ustat {
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -57,6 +57,7 @@ struct usb_host_endpoint {
+ 	struct usb_endpoint_descriptor	desc;
+ 	struct list_head		urb_list;
+ 	void				*hcpriv;
++	struct kobject			*kobj;	/* For sysfs info */
+ 
+ 	unsigned char *extra;   /* Extra descriptors */
+ 	int extralen;
+@@ -136,7 +137,8 @@ struct usb_interface {
+ 					 * active alternate setting */
+ 	unsigned num_altsetting;	/* number of alternate settings */
+ 
+-	int minor;			/* minor number this interface is bound to */
++	int minor;			/* minor number this interface is
++					 * bound to */
+ 	enum usb_interface_condition condition;		/* state of binding */
+ 	struct device dev;		/* interface specific device info */
+ 	struct class_device *class_dev;
+@@ -229,7 +231,7 @@ struct usb_interface_cache {
+ struct usb_host_config {
+ 	struct usb_config_descriptor	desc;
+ 
+-	char *string;
++	char *string;		/* iConfiguration string, if present */
+ 	/* the interfaces associated with this configuration,
+ 	 * stored in no particular order */
+ 	struct usb_interface *interface[USB_MAXINTERFACES];
+@@ -248,7 +250,7 @@ int __usb_get_extra_descriptor(char *buf
+ 	__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
+ 		type,(void**)ptr)
+ 
+-/* -------------------------------------------------------------------------- */
++/* ----------------------------------------------------------------------- */
+ 
+ struct usb_operations;
+ 
+@@ -268,7 +270,8 @@ struct usb_bus {
+ 	unsigned is_b_host:1;		/* true during some HNP roleswitches */
+ 	unsigned b_hnp_enable:1;	/* OTG: did A-Host enable HNP? */
+ 
+-	int devnum_next;		/* Next open device number in round-robin allocation */
++	int devnum_next;		/* Next open device number in
++					 * round-robin allocation */
+ 
+ 	struct usb_devmap devmap;	/* device address allocation map */
+ 	struct usb_operations *op;	/* Operations (specific to the HC) */
+@@ -289,15 +292,16 @@ struct usb_bus {
+ 	struct dentry *usbfs_dentry;	/* usbfs dentry entry for the bus */
+ 
+ 	struct class_device *class_dev;	/* class device for this bus */
+-	struct kref kref;		/* handles reference counting this bus */
+-	void (*release)(struct usb_bus *bus);	/* function to destroy this bus's memory */
++	struct kref kref;		/* reference counting for this bus */
++	void (*release)(struct usb_bus *bus);
++
+ #if defined(CONFIG_USB_MON)
+ 	struct mon_bus *mon_bus;	/* non-null when associated */
+ 	int monitored;			/* non-zero when monitored */
+ #endif
+ };
+ 
+-/* -------------------------------------------------------------------------- */
++/* ----------------------------------------------------------------------- */
+ 
+ /* This is arbitrary.
+  * From USB 2.0 spec Table 11-13, offset 7, a hub can
+@@ -326,7 +330,8 @@ struct usb_device {
+ 
+ 	struct semaphore serialize;
+ 
+-	unsigned int toggle[2];		/* one bit for each endpoint ([0] = IN, [1] = OUT) */
++	unsigned int toggle[2];		/* one bit for each endpoint
++					 * ([0] = IN, [1] = OUT) */
+ 
+ 	struct usb_device *parent;	/* our hub, unless we're the root */
+ 	struct usb_bus *bus;		/* Bus we're part of */
+@@ -343,12 +348,14 @@ struct usb_device {
+ 
+ 	char **rawdescriptors;		/* Raw descriptors for each config */
+ 
+-	int have_langid;		/* whether string_langid is valid yet */
++	int have_langid;		/* whether string_langid is valid */
+ 	int string_langid;		/* language ID for strings */
+ 
+-	char *product;
+-	char *manufacturer;
+-	char *serial;			/* static strings from the device */
++	/* static strings from the device */
++	char *product;			/* iProduct string, if present */
++	char *manufacturer;		/* iManufacturer string, if present */
++	char *serial;			/* iSerialNumber string, if present */
++
+ 	struct list_head filelist;
+ 	struct class_device *class_dev;
+ 	struct dentry *usbfs_dentry;	/* usbfs dentry entry for the device */
+@@ -440,22 +447,31 @@ extern struct usb_host_interface *usb_al
+  * USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are
+  * high speed, and a different one if they are full or low speed.
+  */
+-static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
++static inline int usb_make_path (struct usb_device *dev, char *buf,
++		size_t size)
+ {
+ 	int actual;
+-	actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
++	actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name,
++			dev->devpath);
+ 	return (actual >= (int)size) ? -1 : actual;
+ }
+ 
+ /*-------------------------------------------------------------------------*/
+ 
+-#define USB_DEVICE_ID_MATCH_DEVICE		(USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
+-#define USB_DEVICE_ID_MATCH_DEV_RANGE		(USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
+-#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION	(USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
++#define USB_DEVICE_ID_MATCH_DEVICE \
++		(USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
++#define USB_DEVICE_ID_MATCH_DEV_RANGE \
++		(USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
++#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION \
++		(USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
+ #define USB_DEVICE_ID_MATCH_DEV_INFO \
+-	(USB_DEVICE_ID_MATCH_DEV_CLASS | USB_DEVICE_ID_MATCH_DEV_SUBCLASS | USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
++		(USB_DEVICE_ID_MATCH_DEV_CLASS | \
++		USB_DEVICE_ID_MATCH_DEV_SUBCLASS | \
++		USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
+ #define USB_DEVICE_ID_MATCH_INT_INFO \
+-	(USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL)
++		(USB_DEVICE_ID_MATCH_INT_CLASS | \
++		USB_DEVICE_ID_MATCH_INT_SUBCLASS | \
++		USB_DEVICE_ID_MATCH_INT_PROTOCOL)
+ 
+ /**
+  * USB_DEVICE - macro used to describe a specific usb device
+@@ -466,9 +482,11 @@ static inline int usb_make_path (struct 
+  * specific device.
+  */
+ #define USB_DEVICE(vend,prod) \
+-	.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), .idProduct = (prod)
++	.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), \
++			.idProduct = (prod)
+ /**
+- * USB_DEVICE_VER - macro used to describe a specific usb device with a version range
++ * USB_DEVICE_VER - macro used to describe a specific usb device with a
++ *		version range
+  * @vend: the 16 bit USB Vendor ID
+  * @prod: the 16 bit USB Product ID
+  * @lo: the bcdDevice_lo value
+@@ -478,7 +496,9 @@ static inline int usb_make_path (struct 
+  * specific device, with a version range.
+  */
+ #define USB_DEVICE_VER(vend,prod,lo,hi) \
+-	.match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, .idVendor = (vend), .idProduct = (prod), .bcdDevice_lo = (lo), .bcdDevice_hi = (hi)
++	.match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, \
++	.idVendor = (vend), .idProduct = (prod), \
++	.bcdDevice_lo = (lo), .bcdDevice_hi = (hi)
+ 
+ /**
+  * USB_DEVICE_INFO - macro used to describe a class of usb devices
+@@ -490,7 +510,8 @@ static inline int usb_make_path (struct 
+  * specific class of devices.
+  */
+ #define USB_DEVICE_INFO(cl,sc,pr) \
+-	.match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), .bDeviceSubClass = (sc), .bDeviceProtocol = (pr)
++	.match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), \
++	.bDeviceSubClass = (sc), .bDeviceProtocol = (pr)
+ 
+ /**
+  * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces 
+@@ -502,9 +523,10 @@ static inline int usb_make_path (struct 
+  * specific class of interfaces.
+  */
+ #define USB_INTERFACE_INFO(cl,sc,pr) \
+-	.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
++	.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \
++	.bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
+ 
+-/* -------------------------------------------------------------------------- */
++/* ----------------------------------------------------------------------- */
+ 
+ /**
+  * struct usb_driver - identifies USB driver to usbcore
+@@ -557,7 +579,8 @@ struct usb_driver {
+ 
+ 	void (*disconnect) (struct usb_interface *intf);
+ 
+-	int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf);
++	int (*ioctl) (struct usb_interface *intf, unsigned int code,
++			void *buf);
+ 
+ 	int (*suspend) (struct usb_interface *intf, pm_message_t message);
+ 	int (*resume) (struct usb_interface *intf);
+@@ -572,10 +595,8 @@ extern struct bus_type usb_bus_type;
+ 
+ /**
+  * struct usb_class_driver - identifies a USB driver that wants to use the USB major number
+- * @name: devfs name for this driver.  Will also be used by the driver
+- *	class code to create a usb class device.
++ * @name: the usb class device name for this driver.  Will show up in sysfs.
+  * @fops: pointer to the struct file_operations of this driver.
+- * @mode: the mode for the devfs file to be created for this driver.
+  * @minor_base: the start of the minor range for this driver.
+  *
+  * This structure is used for the usb_register_dev() and
+@@ -585,8 +606,7 @@ extern struct bus_type usb_bus_type;
+ struct usb_class_driver {
+ 	char *name;
+ 	struct file_operations *fops;
+-	mode_t mode;
+-	int minor_base;	
++	int minor_base;
+ };
+ 
+ /*
+@@ -603,7 +623,7 @@ extern void usb_deregister_dev(struct us
+ 
+ extern int usb_disabled(void);
+ 
+-/* -------------------------------------------------------------------------- */
++/* ----------------------------------------------------------------------- */
+ 
+ /*
+  * URB support, for asynchronous request completions
+@@ -613,12 +633,14 @@ extern int usb_disabled(void);
+  * urb->transfer_flags:
+  */
+ #define URB_SHORT_NOT_OK	0x0001	/* report short reads as errors */
+-#define URB_ISO_ASAP		0x0002	/* iso-only, urb->start_frame ignored */
++#define URB_ISO_ASAP		0x0002	/* iso-only, urb->start_frame
++					 * ignored */
+ #define URB_NO_TRANSFER_DMA_MAP	0x0004	/* urb->transfer_dma valid on submit */
+ #define URB_NO_SETUP_DMA_MAP	0x0008	/* urb->setup_dma valid on submit */
+ #define URB_NO_FSBR		0x0020	/* UHCI-specific */
+-#define URB_ZERO_PACKET		0x0040	/* Finish bulk OUTs with short packet */
+-#define URB_NO_INTERRUPT	0x0080	/* HINT: no non-error interrupt needed */
++#define URB_ZERO_PACKET		0x0040	/* Finish bulk OUT with short packet */
++#define URB_NO_INTERRUPT	0x0080	/* HINT: no non-error interrupt
++					 * needed */
+ 
+ struct usb_iso_packet_descriptor {
+ 	unsigned int offset;
+@@ -806,7 +828,8 @@ struct urb
+ 	u8 reject;			/* submissions will fail */
+ 
+ 	/* public, documented fields in the urb that can be used by drivers */
+-	struct list_head urb_list;	/* list head for use by the urb owner */
++	struct list_head urb_list;	/* list head for use by the urb's
++					 * current owner */
+ 	struct usb_device *dev; 	/* (in) pointer to associated device */
+ 	unsigned int pipe;		/* (in) pipe information */
+ 	int status;			/* (return) non-ISO status */
+@@ -819,14 +842,16 @@ struct urb
+ 	dma_addr_t setup_dma;		/* (in) dma addr for setup_packet */
+ 	int start_frame;		/* (modify) start frame (ISO) */
+ 	int number_of_packets;		/* (in) number of ISO packets */
+-	int interval;			/* (modify) transfer interval (INT/ISO) */
++	int interval;			/* (modify) transfer interval
++					 * (INT/ISO) */
+ 	int error_count;		/* (return) number of ISO errors */
+ 	void *context;			/* (in) context for completion */
+ 	usb_complete_t complete;	/* (in) completion routine */
+-	struct usb_iso_packet_descriptor iso_frame_desc[0];	/* (in) ISO ONLY */
++	struct usb_iso_packet_descriptor iso_frame_desc[0];
++					/* (in) ISO ONLY */
+ };
+ 
+-/* -------------------------------------------------------------------------- */
++/* ----------------------------------------------------------------------- */
+ 
+ /**
+  * usb_fill_control_urb - initializes a control urb
+@@ -933,17 +958,17 @@ static inline void usb_fill_int_urb (str
+ }
+ 
+ extern void usb_init_urb(struct urb *urb);
+-extern struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags);
++extern struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags);
+ extern void usb_free_urb(struct urb *urb);
+ #define usb_put_urb usb_free_urb
+ extern struct urb *usb_get_urb(struct urb *urb);
+-extern int usb_submit_urb(struct urb *urb, unsigned mem_flags);
++extern int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
+ extern int usb_unlink_urb(struct urb *urb);
+ extern void usb_kill_urb(struct urb *urb);
+ 
+ #define HAVE_USB_BUFFERS
+ void *usb_buffer_alloc (struct usb_device *dev, size_t size,
+-	unsigned mem_flags, dma_addr_t *dma);
++	gfp_t mem_flags, dma_addr_t *dma);
+ void usb_buffer_free (struct usb_device *dev, size_t size,
+ 	void *addr, dma_addr_t dma);
+ 
+@@ -974,11 +999,6 @@ extern int usb_bulk_msg(struct usb_devic
+ 	void *data, int len, int *actual_length,
+ 	int timeout);
+ 
+-/* selective suspend/resume */
+-extern int usb_suspend_device(struct usb_device *dev, pm_message_t message);
+-extern int usb_resume_device(struct usb_device *dev);
+-
+-
+ /* wrappers around usb_control_msg() for the most common standard requests */
+ extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
+ 	unsigned char descindex, void *buf, int size);
+@@ -1050,13 +1070,13 @@ int usb_sg_init (
+ 	struct scatterlist	*sg,
+ 	int			nents,
+ 	size_t			length,
+-	unsigned		mem_flags
++	gfp_t			mem_flags
+ );
+ void usb_sg_cancel (struct usb_sg_request *io);
+ void usb_sg_wait (struct usb_sg_request *io);
+ 
+ 
+-/* -------------------------------------------------------------------------- */
++/* ----------------------------------------------------------------------- */
+ 
+ /*
+  * For various legacy reasons, Linux has a small cookie that's paired with
+@@ -1097,23 +1117,34 @@ void usb_sg_wait (struct usb_sg_request 
+ /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
+ #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
+ #define	usb_dotoggle(dev, ep, out)  ((dev)->toggle[out] ^= (1 << (ep)))
+-#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | ((bit) << (ep)))
++#define usb_settoggle(dev, ep, out, bit) \
++		((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
++		 ((bit) << (ep)))
+ 
+ 
+-static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint)
++static inline unsigned int __create_pipe(struct usb_device *dev,
++		unsigned int endpoint)
+ {
+ 	return (dev->devnum << 8) | (endpoint << 15);
+ }
+ 
+ /* Create various pipes... */
+-#define usb_sndctrlpipe(dev,endpoint)	((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint))
+-#define usb_rcvctrlpipe(dev,endpoint)	((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+-#define usb_sndisocpipe(dev,endpoint)	((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint))
+-#define usb_rcvisocpipe(dev,endpoint)	((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+-#define usb_sndbulkpipe(dev,endpoint)	((PIPE_BULK << 30) | __create_pipe(dev,endpoint))
+-#define usb_rcvbulkpipe(dev,endpoint)	((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+-#define usb_sndintpipe(dev,endpoint)	((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
+-#define usb_rcvintpipe(dev,endpoint)	((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
++#define usb_sndctrlpipe(dev,endpoint)	\
++	((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint))
++#define usb_rcvctrlpipe(dev,endpoint)	\
++	((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
++#define usb_sndisocpipe(dev,endpoint)	\
++	((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint))
++#define usb_rcvisocpipe(dev,endpoint)	\
++	((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
++#define usb_sndbulkpipe(dev,endpoint)	\
++	((PIPE_BULK << 30) | __create_pipe(dev,endpoint))
++#define usb_rcvbulkpipe(dev,endpoint)	\
++	((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
++#define usb_sndintpipe(dev,endpoint)	\
++	((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
++#define usb_rcvintpipe(dev,endpoint)	\
++	((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+ 
+ /*-------------------------------------------------------------------------*/
+ 
+@@ -1137,17 +1168,29 @@ usb_maxpacket(struct usb_device *udev, i
+ 	return le16_to_cpu(ep->desc.wMaxPacketSize);
+ }
+ 
+-/* -------------------------------------------------------------------------- */
++/* ----------------------------------------------------------------------- */
++
++/* Events from the usb core */
++#define USB_DEVICE_ADD		0x0001
++#define USB_DEVICE_REMOVE	0x0002
++#define USB_BUS_ADD		0x0003
++#define USB_BUS_REMOVE		0x0004
++extern void usb_register_notify(struct notifier_block *nb);
++extern void usb_unregister_notify(struct notifier_block *nb);
+ 
+ #ifdef DEBUG
+-#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg)
++#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \
++	__FILE__ , ## arg)
+ #else
+ #define dbg(format, arg...) do {} while (0)
+ #endif
+ 
+-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
+-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
+-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
++#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
++	__FILE__ , ## arg)
++#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , \
++	__FILE__ , ## arg)
++#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , \
++	__FILE__ , ## arg)
+ 
+ 
+ #endif  /* __KERNEL__ */
+diff --git a/include/linux/usb_gadget.h b/include/linux/usb_gadget.h
+--- a/include/linux/usb_gadget.h
++++ b/include/linux/usb_gadget.h
+@@ -107,18 +107,18 @@ struct usb_ep_ops {
+ 	int (*disable) (struct usb_ep *ep);
+ 
+ 	struct usb_request *(*alloc_request) (struct usb_ep *ep,
+-		unsigned gfp_flags);
++		gfp_t gfp_flags);
+ 	void (*free_request) (struct usb_ep *ep, struct usb_request *req);
+ 
+ 	void *(*alloc_buffer) (struct usb_ep *ep, unsigned bytes,
+-		dma_addr_t *dma, unsigned gfp_flags);
++		dma_addr_t *dma, gfp_t gfp_flags);
+ 	void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma,
+ 		unsigned bytes);
+ 	// NOTE:  on 2.6, drivers may also use dma_map() and
+ 	// dma_sync_single_*() to directly manage dma overhead. 
+ 
+ 	int (*queue) (struct usb_ep *ep, struct usb_request *req,
+-		unsigned gfp_flags);
++		gfp_t gfp_flags);
+ 	int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
+ 
+ 	int (*set_halt) (struct usb_ep *ep, int value);
+@@ -214,7 +214,7 @@ usb_ep_disable (struct usb_ep *ep)
+  * Returns the request, or null if one could not be allocated.
+  */
+ static inline struct usb_request *
+-usb_ep_alloc_request (struct usb_ep *ep, unsigned gfp_flags)
++usb_ep_alloc_request (struct usb_ep *ep, gfp_t gfp_flags)
+ {
+ 	return ep->ops->alloc_request (ep, gfp_flags);
+ }
+@@ -254,7 +254,7 @@ usb_ep_free_request (struct usb_ep *ep, 
+  */
+ static inline void *
+ usb_ep_alloc_buffer (struct usb_ep *ep, unsigned len, dma_addr_t *dma,
+-	unsigned gfp_flags)
++	gfp_t gfp_flags)
+ {
+ 	return ep->ops->alloc_buffer (ep, len, dma, gfp_flags);
+ }
+@@ -330,7 +330,7 @@ usb_ep_free_buffer (struct usb_ep *ep, v
+  * reported when the usb peripheral is disconnected.
+  */
+ static inline int
+-usb_ep_queue (struct usb_ep *ep, struct usb_request *req, unsigned gfp_flags)
++usb_ep_queue (struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags)
+ {
+ 	return ep->ops->queue (ep, req, gfp_flags);
+ }
+diff --git a/include/linux/usb_otg.h b/include/linux/usb_otg.h
+--- a/include/linux/usb_otg.h
++++ b/include/linux/usb_otg.h
+@@ -63,6 +63,10 @@ struct otg_transceiver {
+ 	int	(*set_power)(struct otg_transceiver *otg,
+ 				unsigned mA);
+ 
++	/* for non-OTG B devices: set transceiver into suspend mode */
++	int	(*set_suspend)(struct otg_transceiver *otg,
++				int suspend);
++
+ 	/* for B devices only:  start session with A-Host */
+ 	int	(*start_srp)(struct otg_transceiver *otg);
+ 
+@@ -108,6 +112,15 @@ otg_set_power(struct otg_transceiver *ot
+ }
+ 
+ static inline int
++otg_set_suspend(struct otg_transceiver *otg, int suspend)
++{
++	if (otg->set_suspend != NULL)
++		return otg->set_suspend(otg, suspend);
++	else
++		return 0;
++}
++
++static inline int
+ otg_start_srp(struct otg_transceiver *otg)
+ {
+ 	return otg->start_srp(otg);
+diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
+--- a/include/linux/usbdevice_fs.h
++++ b/include/linux/usbdevice_fs.h
+@@ -140,6 +140,12 @@ struct usbdevfs_urb32 {
+ 	compat_caddr_t usercontext; /* unused */
+ 	struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+ };
++
++struct usbdevfs_ioctl32 {
++	s32 ifno;
++	s32 ioctl_code;
++	compat_caddr_t data;
++};
+ #endif
+ 
+ #define USBDEVFS_CONTROL           _IOWR('U', 0, struct usbdevfs_ctrltransfer)
+@@ -160,6 +166,7 @@ struct usbdevfs_urb32 {
+ #define USBDEVFS_RELEASEINTERFACE  _IOR('U', 16, unsigned int)
+ #define USBDEVFS_CONNECTINFO       _IOW('U', 17, struct usbdevfs_connectinfo)
+ #define USBDEVFS_IOCTL             _IOWR('U', 18, struct usbdevfs_ioctl)
++#define USBDEVFS_IOCTL32           _IOWR('U', 18, struct usbdevfs_ioctl32)
+ #define USBDEVFS_HUB_PORTINFO      _IOR('U', 19, struct usbdevfs_hub_portinfo)
+ #define USBDEVFS_RESET             _IO('U', 20)
+ #define USBDEVFS_CLEAR_HALT        _IOR('U', 21, unsigned int)
+diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
+--- a/include/linux/vmalloc.h
++++ b/include/linux/vmalloc.h
+@@ -32,10 +32,14 @@ struct vm_struct {
+  *	Highlevel APIs for driver use
+  */
+ extern void *vmalloc(unsigned long size);
++extern void *vmalloc_node(unsigned long size, int node);
+ extern void *vmalloc_exec(unsigned long size);
+ extern void *vmalloc_32(unsigned long size);
+ extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
+-extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot);
++extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask,
++				pgprot_t prot);
++extern void *__vmalloc_node(unsigned long size, gfp_t gfp_mask,
++				pgprot_t prot, int node);
+ extern void vfree(void *addr);
+ 
+ extern void *vmap(struct page **pages, unsigned int count,
+@@ -48,6 +52,8 @@ extern void vunmap(void *addr);
+ extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
+ extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
+ 					unsigned long start, unsigned long end);
++extern struct vm_struct *get_vm_area_node(unsigned long size,
++					unsigned long flags, int node);
+ extern struct vm_struct *remove_vm_area(void *addr);
+ extern struct vm_struct *__remove_vm_area(void *addr);
+ extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
+diff --git a/include/linux/wanpipe.h b/include/linux/wanpipe.h
+--- a/include/linux/wanpipe.h
++++ b/include/linux/wanpipe.h
+@@ -265,15 +265,6 @@ typedef struct {
+ #include <linux/tty_driver.h>
+ #include <linux/tty_flip.h>
+ 
+-
+-#define	is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
+-#define	is_alpha(ch) ((((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'z')||\
+-	 	  ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'Z'))?1:0)
+-#define	is_hex_digit(ch) ((((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')||\
+-	 	  ((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'f')||\
+-	 	  ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'F'))?1:0)
+-
+-
+ /****** Data Structures *****************************************************/
+ 
+ /* Adapter Data Space.
+diff --git a/include/linux/x1205.h b/include/linux/x1205.h
+new file mode 100644
+--- /dev/null
++++ b/include/linux/x1205.h
+@@ -0,0 +1,31 @@
++/*
++ *  x1205.h - defines for drivers/i2c/chips/x1205.c
++ *  Copyright 2004 Karen Spearel
++ *  Copyright 2005 Alessandro Zummo
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the 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 __LINUX_X1205_H__
++#define __LINUX_X1205_H__
++
++/* commands */
++
++#define X1205_CMD_GETDATETIME	0
++#define X1205_CMD_SETTIME	1
++#define X1205_CMD_SETDATETIME	2
++#define X1205_CMD_GETALARM	3
++#define X1205_CMD_SETALARM	4
++#define X1205_CMD_GETDTRIM	5
++#define X1205_CMD_SETDTRIM	6
++#define X1205_CMD_GETATRIM	7
++#define X1205_CMD_SETATRIM	8
++
++extern int x1205_do_command(unsigned int cmd, void *arg);
++extern int x1205_direct_attach(int adapter_id,
++	struct i2c_client_address_data *address_data);
++
++#endif /* __LINUX_X1205_H__ */
+diff --git a/include/linux/zutil.h b/include/linux/zutil.h
+--- a/include/linux/zutil.h
++++ b/include/linux/zutil.h
+@@ -15,7 +15,6 @@
+ 
+ #include <linux/zlib.h>
+ #include <linux/string.h>
+-#include <linux/errno.h>
+ #include <linux/kernel.h>
+ 
+ typedef unsigned char  uch;
+diff --git a/include/media/ovcamchip.h b/include/media/ovcamchip.h
+--- a/include/media/ovcamchip.h
++++ b/include/media/ovcamchip.h
+@@ -17,20 +17,6 @@
+ #include <linux/videodev.h>
+ #include <linux/i2c.h>
+ 
+-/* Remove these once they are officially defined */
+-#ifndef I2C_DRIVERID_OVCAMCHIP
+-	#define I2C_DRIVERID_OVCAMCHIP	0xf00f
+-#endif
+-#ifndef I2C_HW_SMBUS_OV511
+-	#define I2C_HW_SMBUS_OV511	0xfe
+-#endif
+-#ifndef I2C_HW_SMBUS_OV518
+-	#define I2C_HW_SMBUS_OV518	0xff
+-#endif
+-#ifndef I2C_HW_SMBUS_OVFX2
+-	#define I2C_HW_SMBUS_OVFX2	0xfd
+-#endif
+-
+ /* --------------------------------- */
+ /*           ENUMERATIONS            */
+ /* --------------------------------- */
+diff --git a/include/net/ax25.h b/include/net/ax25.h
+--- a/include/net/ax25.h
++++ b/include/net/ax25.h
+@@ -237,8 +237,7 @@ typedef struct ax25_cb {
+ static __inline__ void ax25_cb_put(ax25_cb *ax25)
+ {
+ 	if (atomic_dec_and_test(&ax25->refcount)) {
+-		if (ax25->digipeat)
+-			kfree(ax25->digipeat);
++		kfree(ax25->digipeat);
+ 		kfree(ax25);
+ 	}
+ }
+diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
+--- a/include/net/bluetooth/bluetooth.h
++++ b/include/net/bluetooth/bluetooth.h
+@@ -171,4 +171,10 @@ static inline int skb_frags_no(struct sk
+ 
+ int bt_err(__u16 code);
+ 
++extern int hci_sock_init(void);
++extern int hci_sock_cleanup(void);
++
++extern int bt_sysfs_init(void);
++extern void bt_sysfs_cleanup(void);
++
+ #endif /* __BLUETOOTH_H */
+diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
+--- a/include/net/bluetooth/rfcomm.h
++++ b/include/net/bluetooth/rfcomm.h
+@@ -275,9 +275,6 @@ static inline void rfcomm_session_hold(s
+ 	atomic_inc(&s->refcnt);
+ }
+ 
+-/* ---- RFCOMM chechsum ---- */
+-extern u8 rfcomm_crc_table[];
+-
+ /* ---- RFCOMM sockets ---- */
+ struct sockaddr_rc {
+ 	sa_family_t	rc_family;
+diff --git a/include/net/dst.h b/include/net/dst.h
+--- a/include/net/dst.h
++++ b/include/net/dst.h
+@@ -94,7 +94,6 @@ struct dst_ops
+ 	struct dst_entry *	(*negative_advice)(struct dst_entry *);
+ 	void			(*link_failure)(struct sk_buff *);
+ 	void			(*update_pmtu)(struct dst_entry *dst, u32 mtu);
+-	int			(*get_mss)(struct dst_entry *dst, u32 mtu);
+ 	int			entry_size;
+ 
+ 	atomic_t		entries;
+diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
+--- a/include/net/ieee80211.h
++++ b/include/net/ieee80211.h
+@@ -11,19 +11,26 @@
+  *
+  * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+  * <jketreno at linux.intel.com>
+- * Copyright (c) 2004, Intel Corporation
++ * Copyright (c) 2004-2005, Intel 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. See README and COPYING for
+  * more details.
++ *
++ * API Version History
++ * 1.0.x -- Initial version
++ * 1.1.x -- Added radiotap, QoS, TIM, ieee80211_geo APIs,
++ *          various structure changes, and crypto API init method
+  */
+ #ifndef IEEE80211_H
+ #define IEEE80211_H
+-#include <linux/if_ether.h> /* ETH_ALEN */
+-#include <linux/kernel.h>   /* ARRAY_SIZE */
++#include <linux/if_ether.h>	/* ETH_ALEN */
++#include <linux/kernel.h>	/* ARRAY_SIZE */
+ #include <linux/wireless.h>
+ 
++#define IEEE80211_VERSION "git-1.1.6"
++
+ #define IEEE80211_DATA_LEN		2304
+ /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+    6.2.1.1.2.
+@@ -33,34 +40,13 @@
+    represents the 2304 bytes of real data, plus a possible 8 bytes of
+    WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
+ 
+-
+-#define IEEE80211_HLEN			30
+-#define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
+-
+-struct ieee80211_hdr {
+-	__le16 frame_ctl;
+-	__le16 duration_id;
+-	u8 addr1[ETH_ALEN];
+-	u8 addr2[ETH_ALEN];
+-	u8 addr3[ETH_ALEN];
+-	__le16 seq_ctl;
+-	u8 addr4[ETH_ALEN];
+-} __attribute__ ((packed));
+-
+-struct ieee80211_hdr_3addr {
+-	__le16 frame_ctl;
+-	__le16 duration_id;
+-	u8 addr1[ETH_ALEN];
+-	u8 addr2[ETH_ALEN];
+-	u8 addr3[ETH_ALEN];
+-	__le16 seq_ctl;
+-} __attribute__ ((packed));
+-
+ #define IEEE80211_1ADDR_LEN 10
+ #define IEEE80211_2ADDR_LEN 16
+ #define IEEE80211_3ADDR_LEN 24
+ #define IEEE80211_4ADDR_LEN 30
+ #define IEEE80211_FCS_LEN    4
++#define IEEE80211_HLEN			(IEEE80211_4ADDR_LEN)
++#define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
+ 
+ #define MIN_FRAG_THRESHOLD     256U
+ #define	MAX_FRAG_THRESHOLD     2346U
+@@ -113,11 +99,11 @@ struct ieee80211_hdr_3addr {
+ #define IEEE80211_STYPE_CFACK		0x0050
+ #define IEEE80211_STYPE_CFPOLL		0x0060
+ #define IEEE80211_STYPE_CFACKPOLL	0x0070
++#define IEEE80211_STYPE_QOS_DATA        0x0080
+ 
+ #define IEEE80211_SCTL_FRAG		0x000F
+ #define IEEE80211_SCTL_SEQ		0xFFF0
+ 
+-
+ /* debug macros */
+ 
+ #ifdef CONFIG_IEEE80211_DEBUG
+@@ -128,8 +114,7 @@ do { if (ieee80211_debug_level & (level)
+          in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+ #else
+ #define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+-#endif	/* CONFIG_IEEE80211_DEBUG */
+-
++#endif				/* CONFIG_IEEE80211_DEBUG */
+ 
+ /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
+ 
+@@ -140,7 +125,6 @@ do { if (ieee80211_debug_level & (level)
+  * messages. It should never be used for passing essid to user space. */
+ const char *escape_essid(const char *essid, u8 essid_len);
+ 
+-
+ /*
+  * To use the debug system:
+  *
+@@ -177,6 +161,7 @@ const char *escape_essid(const char *ess
+ 
+ #define IEEE80211_DL_TX            (1<<8)
+ #define IEEE80211_DL_RX            (1<<9)
++#define IEEE80211_DL_QOS           (1<<31)
+ 
+ #define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
+ #define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
+@@ -190,9 +175,10 @@ const char *escape_essid(const char *ess
+ #define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
+ #define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
+ #define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
++#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
+ #include <linux/netdevice.h>
+ #include <linux/wireless.h>
+-#include <linux/if_arp.h> /* ARPHRD_ETHER */
++#include <linux/if_arp.h>	/* ARPHRD_ETHER */
+ 
+ #ifndef WIRELESS_SPY
+ #define WIRELESS_SPY		/* enable iwspy support */
+@@ -200,10 +186,10 @@ const char *escape_essid(const char *ess
+ #include <net/iw_handler.h>	/* new driver API */
+ 
+ #ifndef ETH_P_PAE
+-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+-#endif /* ETH_P_PAE */
++#define ETH_P_PAE 0x888E	/* Port Access Entity (IEEE 802.1X) */
++#endif				/* ETH_P_PAE */
+ 
+-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
++#define ETH_P_PREAUTH 0x88C7	/* IEEE 802.11i pre-authentication */
+ 
+ #ifndef ETH_P_80211_RAW
+ #define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+@@ -215,10 +201,10 @@ const char *escape_essid(const char *ess
+ 
+ struct ieee80211_snap_hdr {
+ 
+-        u8    dsap;   /* always 0xAA */
+-        u8    ssap;   /* always 0xAA */
+-        u8    ctrl;   /* always 0x03 */
+-        u8    oui[P80211_OUI_LEN];    /* organizational universal id */
++	u8 dsap;		/* always 0xAA */
++	u8 ssap;		/* always 0xAA */
++	u8 ctrl;		/* always 0x03 */
++	u8 oui[P80211_OUI_LEN];	/* organizational universal id */
+ 
+ } __attribute__ ((packed));
+ 
+@@ -246,8 +232,9 @@ struct ieee80211_snap_hdr {
+ #define WLAN_CAPABILITY_PBCC (1<<6)
+ #define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
+ #define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
++#define WLAN_CAPABILITY_QOS (1<<9)
+ #define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
+-#define WLAN_CAPABILITY_OSSS_OFDM (1<<13)
++#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
+ 
+ /* Status codes */
+ enum ieee80211_statuscode {
+@@ -312,14 +299,12 @@ enum ieee80211_reasoncode {
+ 	WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+ };
+ 
+-
+ #define IEEE80211_STATMASK_SIGNAL (1<<0)
+ #define IEEE80211_STATMASK_RSSI (1<<1)
+ #define IEEE80211_STATMASK_NOISE (1<<2)
+ #define IEEE80211_STATMASK_RATE (1<<3)
+ #define IEEE80211_STATMASK_WEMASK 0x7
+ 
+-
+ #define IEEE80211_CCK_MODULATION    (1<<0)
+ #define IEEE80211_OFDM_MODULATION   (1<<1)
+ 
+@@ -377,9 +362,6 @@ enum ieee80211_reasoncode {
+ #define IEEE80211_NUM_CCK_RATES	            4
+ #define IEEE80211_OFDM_SHIFT_MASK_A         4
+ 
+-
+-
+-
+ /* NOTE: This data is for statistical purposes; not all hardware provides this
+  *       information for frames received.  Not setting these will not cause
+  *       any adverse affects. */
+@@ -388,7 +370,7 @@ struct ieee80211_rx_stats {
+ 	s8 rssi;
+ 	u8 signal;
+ 	u8 noise;
+-	u16 rate; /* in 100 kbps */
++	u16 rate;		/* in 100 kbps */
+ 	u8 received_channel;
+ 	u8 control;
+ 	u8 mask;
+@@ -439,38 +421,44 @@ struct ieee80211_device;
+ 
+ #include "ieee80211_crypt.h"
+ 
+-#define SEC_KEY_1         (1<<0)
+-#define SEC_KEY_2         (1<<1)
+-#define SEC_KEY_3         (1<<2)
+-#define SEC_KEY_4         (1<<3)
+-#define SEC_ACTIVE_KEY    (1<<4)
+-#define SEC_AUTH_MODE     (1<<5)
+-#define SEC_UNICAST_GROUP (1<<6)
+-#define SEC_LEVEL         (1<<7)
+-#define SEC_ENABLED       (1<<8)
+-
+-#define SEC_LEVEL_0      0 /* None */
+-#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
+-#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
+-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
+-#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
+-
+-#define WEP_KEYS 4
+-#define WEP_KEY_LEN 13
++#define SEC_KEY_1		(1<<0)
++#define SEC_KEY_2		(1<<1)
++#define SEC_KEY_3		(1<<2)
++#define SEC_KEY_4		(1<<3)
++#define SEC_ACTIVE_KEY		(1<<4)
++#define SEC_AUTH_MODE		(1<<5)
++#define SEC_UNICAST_GROUP	(1<<6)
++#define SEC_LEVEL		(1<<7)
++#define SEC_ENABLED		(1<<8)
++#define SEC_ENCRYPT		(1<<9)
++
++#define SEC_LEVEL_0		0	/* None */
++#define SEC_LEVEL_1		1	/* WEP 40 and 104 bit */
++#define SEC_LEVEL_2		2	/* Level 1 + TKIP */
++#define SEC_LEVEL_2_CKIP	3	/* Level 1 + CKIP */
++#define SEC_LEVEL_3		4	/* Level 2 + CCMP */
++
++#define SEC_ALG_NONE		0
++#define SEC_ALG_WEP		1
++#define SEC_ALG_TKIP		2
++#define SEC_ALG_CCMP		3
++
++#define WEP_KEYS		4
++#define WEP_KEY_LEN		13
++#define SCM_KEY_LEN		32
++#define SCM_TEMPORAL_KEY_LENGTH	16
+ 
+ struct ieee80211_security {
+ 	u16 active_key:2,
+-            enabled:1,
+-	    auth_mode:2,
+-            auth_algo:4,
+-            unicast_uses_group:1;
++	    enabled:1,
++	    auth_mode:2, auth_algo:4, unicast_uses_group:1, encrypt:1;
++	u8 encode_alg[WEP_KEYS];
+ 	u8 key_sizes[WEP_KEYS];
+-	u8 keys[WEP_KEYS][WEP_KEY_LEN];
++	u8 keys[WEP_KEYS][SCM_KEY_LEN];
+ 	u8 level;
+ 	u16 flags;
+ } __attribute__ ((packed));
+ 
+-
+ /*
+ 
+  802.11 data frame from AP
+@@ -494,7 +482,7 @@ enum ieee80211_mfie {
+ 	MFIE_TYPE_RATES = 1,
+ 	MFIE_TYPE_FH_SET = 2,
+ 	MFIE_TYPE_DS_SET = 3,
+-	MFIE_TYPE_CF_SET =  4,
++	MFIE_TYPE_CF_SET = 4,
+ 	MFIE_TYPE_TIM = 5,
+ 	MFIE_TYPE_IBSS_SET = 6,
+ 	MFIE_TYPE_COUNTRY = 7,
+@@ -516,11 +504,75 @@ enum ieee80211_mfie {
+ 	MFIE_TYPE_RSN = 48,
+ 	MFIE_TYPE_RATES_EX = 50,
+ 	MFIE_TYPE_GENERIC = 221,
++	MFIE_TYPE_QOS_PARAMETER = 222,
+ };
+ 
+-struct ieee80211_info_element_hdr {
+-	u8 id;
+-	u8 len;
++/* Minimal header; can be used for passing 802.11 frames with sufficient
++ * information to determine what type of underlying data type is actually
++ * stored in the data. */
++struct ieee80211_hdr {
++	__le16 frame_ctl;
++	__le16 duration_id;
++	u8 payload[0];
++} __attribute__ ((packed));
++
++struct ieee80211_hdr_1addr {
++	__le16 frame_ctl;
++	__le16 duration_id;
++	u8 addr1[ETH_ALEN];
++	u8 payload[0];
++} __attribute__ ((packed));
++
++struct ieee80211_hdr_2addr {
++	__le16 frame_ctl;
++	__le16 duration_id;
++	u8 addr1[ETH_ALEN];
++	u8 addr2[ETH_ALEN];
++	u8 payload[0];
++} __attribute__ ((packed));
++
++struct ieee80211_hdr_3addr {
++	__le16 frame_ctl;
++	__le16 duration_id;
++	u8 addr1[ETH_ALEN];
++	u8 addr2[ETH_ALEN];
++	u8 addr3[ETH_ALEN];
++	__le16 seq_ctl;
++	u8 payload[0];
++} __attribute__ ((packed));
++
++struct ieee80211_hdr_4addr {
++	__le16 frame_ctl;
++	__le16 duration_id;
++	u8 addr1[ETH_ALEN];
++	u8 addr2[ETH_ALEN];
++	u8 addr3[ETH_ALEN];
++	__le16 seq_ctl;
++	u8 addr4[ETH_ALEN];
++	u8 payload[0];
++} __attribute__ ((packed));
++
++struct ieee80211_hdr_3addrqos {
++	__le16 frame_ctl;
++	__le16 duration_id;
++	u8 addr1[ETH_ALEN];
++	u8 addr2[ETH_ALEN];
++	u8 addr3[ETH_ALEN];
++	__le16 seq_ctl;
++	u8 payload[0];
++	__le16 qos_ctl;
++} __attribute__ ((packed));
++
++struct ieee80211_hdr_4addrqos {
++	__le16 frame_ctl;
++	__le16 duration_id;
++	u8 addr1[ETH_ALEN];
++	u8 addr2[ETH_ALEN];
++	u8 addr3[ETH_ALEN];
++	__le16 seq_ctl;
++	u8 addr4[ETH_ALEN];
++	u8 payload[0];
++	__le16 qos_ctl;
+ } __attribute__ ((packed));
+ 
+ struct ieee80211_info_element {
+@@ -546,49 +598,77 @@ struct ieee80211_info_element {
+ 	u16 status;
+ */
+ 
+-struct ieee80211_authentication {
++struct ieee80211_auth {
+ 	struct ieee80211_hdr_3addr header;
+ 	__le16 algorithm;
+ 	__le16 transaction;
+ 	__le16 status;
+-	struct ieee80211_info_element info_element;
++	/* challenge */
++	struct ieee80211_info_element info_element[0];
+ } __attribute__ ((packed));
+ 
++struct ieee80211_disassoc {
++	struct ieee80211_hdr_3addr header;
++	__le16 reason;
++} __attribute__ ((packed));
++
++/* Alias deauth for disassoc */
++#define ieee80211_deauth ieee80211_disassoc
++
++struct ieee80211_probe_request {
++	struct ieee80211_hdr_3addr header;
++	/* SSID, supported rates */
++	struct ieee80211_info_element info_element[0];
++} __attribute__ ((packed));
+ 
+ struct ieee80211_probe_response {
+ 	struct ieee80211_hdr_3addr header;
+ 	u32 time_stamp[2];
+ 	__le16 beacon_interval;
+ 	__le16 capability;
+-	struct ieee80211_info_element info_element;
++	/* SSID, supported rates, FH params, DS params,
++	 * CF params, IBSS params, TIM (if beacon), RSN */
++	struct ieee80211_info_element info_element[0];
+ } __attribute__ ((packed));
+ 
+-struct ieee80211_assoc_request_frame {
++/* Alias beacon for probe_response */
++#define ieee80211_beacon ieee80211_probe_response
++
++struct ieee80211_assoc_request {
++	struct ieee80211_hdr_3addr header;
++	__le16 capability;
++	__le16 listen_interval;
++	/* SSID, supported rates, RSN */
++	struct ieee80211_info_element info_element[0];
++} __attribute__ ((packed));
++
++struct ieee80211_reassoc_request {
++	struct ieee80211_hdr_3addr header;
+ 	__le16 capability;
+ 	__le16 listen_interval;
+ 	u8 current_ap[ETH_ALEN];
+-	struct ieee80211_info_element info_element;
++	struct ieee80211_info_element info_element[0];
+ } __attribute__ ((packed));
+ 
+-struct ieee80211_assoc_response_frame {
++struct ieee80211_assoc_response {
+ 	struct ieee80211_hdr_3addr header;
+ 	__le16 capability;
+ 	__le16 status;
+ 	__le16 aid;
+-	struct ieee80211_info_element info_element; /* supported rates */
++	/* supported rates */
++	struct ieee80211_info_element info_element[0];
+ } __attribute__ ((packed));
+ 
+-
+ struct ieee80211_txb {
+ 	u8 nr_frags;
+ 	u8 encrypted;
+-	u16 reserved;
+-	u16 frag_size;
+-	u16 payload_size;
++	u8 rts_included;
++	u8 reserved;
++	__le16 frag_size;
++	__le16 payload_size;
+ 	struct sk_buff *fragments[0];
+ };
+ 
+-
+ /* SWEEP TABLE ENTRIES NUMBER */
+ #define MAX_SWEEP_TAB_ENTRIES		  42
+ #define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
+@@ -604,9 +684,68 @@ struct ieee80211_txb {
+ 
+ #define MAX_WPA_IE_LEN 64
+ 
+-#define NETWORK_EMPTY_ESSID (1<<0)
+-#define NETWORK_HAS_OFDM    (1<<1)
+-#define NETWORK_HAS_CCK     (1<<2)
++#define NETWORK_EMPTY_ESSID    (1<<0)
++#define NETWORK_HAS_OFDM       (1<<1)
++#define NETWORK_HAS_CCK        (1<<2)
++
++/* QoS structure */
++#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
++#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
++#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | NETWORK_HAS_QOS_INFORMATION)
++
++#define QOS_QUEUE_NUM                   4
++#define QOS_OUI_LEN                     3
++#define QOS_OUI_TYPE                    2
++#define QOS_ELEMENT_ID                  221
++#define QOS_OUI_INFO_SUB_TYPE           0
++#define QOS_OUI_PARAM_SUB_TYPE          1
++#define QOS_VERSION_1                   1
++#define QOS_AIFSN_MIN_VALUE             2
++
++struct ieee80211_qos_information_element {
++	u8 elementID;
++	u8 length;
++	u8 qui[QOS_OUI_LEN];
++	u8 qui_type;
++	u8 qui_subtype;
++	u8 version;
++	u8 ac_info;
++} __attribute__ ((packed));
++
++struct ieee80211_qos_ac_parameter {
++	u8 aci_aifsn;
++	u8 ecw_min_max;
++	__le16 tx_op_limit;
++} __attribute__ ((packed));
++
++struct ieee80211_qos_parameter_info {
++	struct ieee80211_qos_information_element info_element;
++	u8 reserved;
++	struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
++} __attribute__ ((packed));
++
++struct ieee80211_qos_parameters {
++	__le16 cw_min[QOS_QUEUE_NUM];
++	__le16 cw_max[QOS_QUEUE_NUM];
++	u8 aifs[QOS_QUEUE_NUM];
++	u8 flag[QOS_QUEUE_NUM];
++	__le16 tx_op_limit[QOS_QUEUE_NUM];
++} __attribute__ ((packed));
++
++struct ieee80211_qos_data {
++	struct ieee80211_qos_parameters parameters;
++	int active;
++	int supported;
++	u8 param_count;
++	u8 old_param_count;
++};
++
++struct ieee80211_tim_parameters {
++	u8 tim_count;
++	u8 tim_period;
++} __attribute__ ((packed));
++
++/*******************************************************/
+ 
+ struct ieee80211_network {
+ 	/* These entries are used to identify a unique network */
+@@ -616,6 +755,8 @@ struct ieee80211_network {
+ 	u8 ssid[IW_ESSID_MAX_SIZE + 1];
+ 	u8 ssid_len;
+ 
++	struct ieee80211_qos_data qos_data;
++
+ 	/* These are network statistics */
+ 	struct ieee80211_rx_stats stats;
+ 	u16 capability;
+@@ -631,10 +772,12 @@ struct ieee80211_network {
+ 	u16 beacon_interval;
+ 	u16 listen_interval;
+ 	u16 atim_window;
++	u8 erp_value;
+ 	u8 wpa_ie[MAX_WPA_IE_LEN];
+ 	size_t wpa_ie_len;
+ 	u8 rsn_ie[MAX_WPA_IE_LEN];
+ 	size_t rsn_ie_len;
++	struct ieee80211_tim_parameters tim;
+ 	struct list_head list;
+ };
+ 
+@@ -651,17 +794,52 @@ enum ieee80211_state {
+ #define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+ #define DEFAULT_FTS 2346
+ 
+-
+ #define CFG_IEEE80211_RESERVE_FCS (1<<0)
+ #define CFG_IEEE80211_COMPUTE_FCS (1<<1)
++#define CFG_IEEE80211_RTS (1<<2)
++
++#define IEEE80211_24GHZ_MIN_CHANNEL 1
++#define IEEE80211_24GHZ_MAX_CHANNEL 14
++#define IEEE80211_24GHZ_CHANNELS    14
++
++#define IEEE80211_52GHZ_MIN_CHANNEL 36
++#define IEEE80211_52GHZ_MAX_CHANNEL 165
++#define IEEE80211_52GHZ_CHANNELS    32
++
++enum {
++	IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
++	IEEE80211_CH_B_ONLY = (1 << 2),
++	IEEE80211_CH_NO_IBSS = (1 << 3),
++	IEEE80211_CH_UNIFORM_SPREADING = (1 << 4),
++	IEEE80211_CH_RADAR_DETECT = (1 << 5),
++	IEEE80211_CH_INVALID = (1 << 6),
++};
++
++struct ieee80211_channel {
++	u32 freq;
++	u8 channel;
++	u8 flags;
++	u8 max_power;
++};
++
++struct ieee80211_geo {
++	u8 name[4];
++	u8 bg_channels;
++	u8 a_channels;
++	struct ieee80211_channel bg[IEEE80211_24GHZ_CHANNELS];
++	struct ieee80211_channel a[IEEE80211_52GHZ_CHANNELS];
++};
+ 
+ struct ieee80211_device {
+ 	struct net_device *dev;
++	struct ieee80211_security sec;
+ 
+ 	/* Bookkeeping structures */
+ 	struct net_device_stats stats;
+ 	struct ieee80211_stats ieee_stats;
+ 
++	struct ieee80211_geo geo;
++
+ 	/* Probe / Beacon management */
+ 	struct list_head network_free_list;
+ 	struct list_head network_list;
+@@ -669,62 +847,102 @@ struct ieee80211_device {
+ 	int scans;
+ 	int scan_age;
+ 
+-	int iw_mode; /* operating mode (IW_MODE_*) */
++	int iw_mode;		/* operating mode (IW_MODE_*) */
++	struct iw_spy_data spy_data;	/* iwspy support */
+ 
+ 	spinlock_t lock;
+ 
+-	int tx_headroom; /* Set to size of any additional room needed at front
+-			  * of allocated Tx SKBs */
++	int tx_headroom;	/* Set to size of any additional room needed at front
++				 * of allocated Tx SKBs */
+ 	u32 config;
+ 
+ 	/* WEP and other encryption related settings at the device level */
+-	int open_wep; /* Set to 1 to allow unencrypted frames */
++	int open_wep;		/* Set to 1 to allow unencrypted frames */
+ 
+-	int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
++	int reset_on_keychange;	/* Set to 1 if the HW needs to be reset on
+ 				 * WEP key changes */
+ 
+ 	/* If the host performs {en,de}cryption, then set to 1 */
+ 	int host_encrypt;
++	int host_encrypt_msdu;
+ 	int host_decrypt;
+-	int ieee802_1x; /* is IEEE 802.1X used */
++	/* host performs multicast decryption */
++	int host_mc_decrypt;
++
++	int host_open_frag;
++	int host_build_iv;
++	int ieee802_1x;		/* is IEEE 802.1X used */
+ 
+ 	/* WPA data */
+ 	int wpa_enabled;
+ 	int drop_unencrypted;
+-	int tkip_countermeasures;
+ 	int privacy_invoked;
+ 	size_t wpa_ie_len;
+ 	u8 *wpa_ie;
+ 
+ 	struct list_head crypt_deinit_list;
+ 	struct ieee80211_crypt_data *crypt[WEP_KEYS];
+-	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
++	int tx_keyidx;		/* default TX key index (crypt[tx_keyidx]) */
+ 	struct timer_list crypt_deinit_timer;
++	int crypt_quiesced;
+ 
+-	int bcrx_sta_key; /* use individual keys to override default keys even
+-			   * with RX of broad/multicast frames */
++	int bcrx_sta_key;	/* use individual keys to override default keys even
++				 * with RX of broad/multicast frames */
+ 
+ 	/* Fragmentation structures */
+ 	struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
+ 	unsigned int frag_next_idx;
+-	u16 fts; /* Fragmentation Threshold */
++	u16 fts;		/* Fragmentation Threshold */
++	u16 rts;		/* RTS threshold */
+ 
+ 	/* Association info */
+ 	u8 bssid[ETH_ALEN];
+ 
+ 	enum ieee80211_state state;
+ 
+-	int mode;       /* A, B, G */
+-	int modulation; /* CCK, OFDM */
+-	int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
+-	int abg_ture;   /* ABG flag              */
++	int mode;		/* A, B, G */
++	int modulation;		/* CCK, OFDM */
++	int freq_band;		/* 2.4Ghz, 5.2Ghz, Mixed */
++	int abg_true;		/* ABG flag              */
++
++	int perfect_rssi;
++	int worst_rssi;
+ 
+ 	/* Callback functions */
+-	void (*set_security)(struct net_device *dev,
+-			     struct ieee80211_security *sec);
+-	int (*hard_start_xmit)(struct ieee80211_txb *txb,
+-			       struct net_device *dev);
+-	int (*reset_port)(struct net_device *dev);
++	void (*set_security) (struct net_device * dev,
++			      struct ieee80211_security * sec);
++	int (*hard_start_xmit) (struct ieee80211_txb * txb,
++				struct net_device * dev, int pri);
++	int (*reset_port) (struct net_device * dev);
++	int (*is_queue_full) (struct net_device * dev, int pri);
++
++	int (*handle_management) (struct net_device * dev,
++				  struct ieee80211_network * network, u16 type);
++
++	/* Typical STA methods */
++	int (*handle_auth) (struct net_device * dev,
++			    struct ieee80211_auth * auth);
++	int (*handle_deauth) (struct net_device * dev,
++			      struct ieee80211_auth * auth);
++	int (*handle_disassoc) (struct net_device * dev,
++				struct ieee80211_disassoc * assoc);
++	int (*handle_beacon) (struct net_device * dev,
++			      struct ieee80211_beacon * beacon,
++			      struct ieee80211_network * network);
++	int (*handle_probe_response) (struct net_device * dev,
++				      struct ieee80211_probe_response * resp,
++				      struct ieee80211_network * network);
++	int (*handle_probe_request) (struct net_device * dev,
++				     struct ieee80211_probe_request * req,
++				     struct ieee80211_rx_stats * stats);
++	int (*handle_assoc_response) (struct net_device * dev,
++				      struct ieee80211_assoc_response * resp,
++				      struct ieee80211_network * network);
++
++	/* Typical AP methods */
++	int (*handle_assoc_request) (struct net_device * dev);
++	int (*handle_reassoc_request) (struct net_device * dev,
++				       struct ieee80211_reassoc_request * req);
+ 
+ 	/* This must be the last item so that it points to the data
+ 	 * allocated beyond this structure by alloc_ieee80211 */
+@@ -736,12 +954,12 @@ struct ieee80211_device {
+ #define IEEE_G            (1<<2)
+ #define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
+ 
+-extern inline void *ieee80211_priv(struct net_device *dev)
++static inline void *ieee80211_priv(struct net_device *dev)
+ {
+ 	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
+ }
+ 
+-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
++static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+ {
+ 	/* Single white space is for Linksys APs */
+ 	if (essid_len == 1 && essid[0] == ' ')
+@@ -757,7 +975,8 @@ extern inline int ieee80211_is_empty_ess
+ 	return 1;
+ }
+ 
+-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
++static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
++					  int mode)
+ {
+ 	/*
+ 	 * It is possible for both access points and our device to support
+@@ -783,14 +1002,17 @@ extern inline int ieee80211_is_valid_mod
+ 	return 0;
+ }
+ 
+-extern inline int ieee80211_get_hdrlen(u16 fc)
++static inline int ieee80211_get_hdrlen(u16 fc)
+ {
+ 	int hdrlen = IEEE80211_3ADDR_LEN;
++	u16 stype = WLAN_FC_GET_STYPE(fc);
+ 
+ 	switch (WLAN_FC_GET_TYPE(fc)) {
+ 	case IEEE80211_FTYPE_DATA:
+ 		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+ 			hdrlen = IEEE80211_4ADDR_LEN;
++		if (stype & IEEE80211_STYPE_QOS_DATA)
++			hdrlen += 2;
+ 		break;
+ 	case IEEE80211_FTYPE_CTL:
+ 		switch (WLAN_FC_GET_STYPE(fc)) {
+@@ -808,7 +1030,48 @@ extern inline int ieee80211_get_hdrlen(u
+ 	return hdrlen;
+ }
+ 
++static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
++{
++	switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
++	case IEEE80211_1ADDR_LEN:
++		return ((struct ieee80211_hdr_1addr *)hdr)->payload;
++	case IEEE80211_2ADDR_LEN:
++		return ((struct ieee80211_hdr_2addr *)hdr)->payload;
++	case IEEE80211_3ADDR_LEN:
++		return ((struct ieee80211_hdr_3addr *)hdr)->payload;
++	case IEEE80211_4ADDR_LEN:
++		return ((struct ieee80211_hdr_4addr *)hdr)->payload;
++	}
++
++}
++
++static inline int ieee80211_is_ofdm_rate(u8 rate)
++{
++	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
++	case IEEE80211_OFDM_RATE_6MB:
++	case IEEE80211_OFDM_RATE_9MB:
++	case IEEE80211_OFDM_RATE_12MB:
++	case IEEE80211_OFDM_RATE_18MB:
++	case IEEE80211_OFDM_RATE_24MB:
++	case IEEE80211_OFDM_RATE_36MB:
++	case IEEE80211_OFDM_RATE_48MB:
++	case IEEE80211_OFDM_RATE_54MB:
++		return 1;
++	}
++	return 0;
++}
+ 
++static inline int ieee80211_is_cck_rate(u8 rate)
++{
++	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
++	case IEEE80211_CCK_RATE_1MB:
++	case IEEE80211_CCK_RATE_2MB:
++	case IEEE80211_CCK_RATE_5MB:
++	case IEEE80211_CCK_RATE_11MB:
++		return 1;
++	}
++	return 0;
++}
+ 
+ /* ieee80211.c */
+ extern void free_ieee80211(struct net_device *dev);
+@@ -817,18 +1080,30 @@ extern struct net_device *alloc_ieee8021
+ extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
+ 
+ /* ieee80211_tx.c */
+-extern int ieee80211_xmit(struct sk_buff *skb,
+-			  struct net_device *dev);
++extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
+ extern void ieee80211_txb_free(struct ieee80211_txb *);
+-
++extern int ieee80211_tx_frame(struct ieee80211_device *ieee,
++			      struct ieee80211_hdr *frame, int len);
+ 
+ /* ieee80211_rx.c */
+ extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+ 			struct ieee80211_rx_stats *rx_stats);
+ extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+-			     struct ieee80211_hdr *header,
++			     struct ieee80211_hdr_4addr *header,
+ 			     struct ieee80211_rx_stats *stats);
+ 
++/* ieee80211_geo.c */
++extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device
++						     *ieee);
++extern int ieee80211_set_geo(struct ieee80211_device *ieee,
++			     const struct ieee80211_geo *geo);
++
++extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee,
++				      u8 channel);
++extern int ieee80211_channel_to_index(struct ieee80211_device *ieee,
++				      u8 channel);
++extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq);
++
+ /* ieee80211_wx.c */
+ extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+ 				 struct iw_request_info *info,
+@@ -839,17 +1114,21 @@ extern int ieee80211_wx_set_encode(struc
+ extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
+ 				   struct iw_request_info *info,
+ 				   union iwreq_data *wrqu, char *key);
++extern int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
++				      struct iw_request_info *info,
++				      union iwreq_data *wrqu, char *extra);
++extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
++				      struct iw_request_info *info,
++				      union iwreq_data *wrqu, char *extra);
+ 
+-
+-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
++static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+ {
+ 	ieee->scans++;
+ }
+ 
+-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
++static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+ {
+ 	return ieee->scans;
+ }
+ 
+-
+-#endif /* IEEE80211_H */
++#endif				/* IEEE80211_H */
+diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
+--- a/include/net/ieee80211_crypt.h
++++ b/include/net/ieee80211_crypt.h
+@@ -25,16 +25,22 @@
+ 
+ #include <linux/skbuff.h>
+ 
++enum {
++	IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
++};
++
+ struct ieee80211_crypto_ops {
+ 	const char *name;
+ 
+ 	/* init new crypto context (e.g., allocate private data space,
+ 	 * select IV, etc.); returns NULL on failure or pointer to allocated
+ 	 * private data on success */
+-	void * (*init)(int keyidx);
++	void *(*init) (int keyidx);
+ 
+ 	/* deinitialize crypto context and free allocated private data */
+-	void (*deinit)(void *priv);
++	void (*deinit) (void *priv);
++
++	int (*build_iv) (struct sk_buff * skb, int hdr_len, void *priv);
+ 
+ 	/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
+ 	 * value from decrypt_mpdu is passed as the keyidx value for
+@@ -42,34 +48,39 @@ struct ieee80211_crypto_ops {
+ 	 * encryption; if not, error will be returned; these functions are
+ 	 * called for all MPDUs (i.e., fragments).
+ 	 */
+-	int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
+-	int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
++	int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
++	int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
+ 
+ 	/* These functions are called for full MSDUs, i.e. full frames.
+ 	 * These can be NULL if full MSDU operations are not needed. */
+-	int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
+-	int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
+-			    void *priv);
++	int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
++	int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
++			     void *priv);
+ 
+-	int (*set_key)(void *key, int len, u8 *seq, void *priv);
+-	int (*get_key)(void *key, int len, u8 *seq, void *priv);
++	int (*set_key) (void *key, int len, u8 * seq, void *priv);
++	int (*get_key) (void *key, int len, u8 * seq, void *priv);
+ 
+ 	/* procfs handler for printing out key information and possible
+ 	 * statistics */
+-	char * (*print_stats)(char *p, void *priv);
++	char *(*print_stats) (char *p, void *priv);
++
++	/* Crypto specific flag get/set for configuration settings */
++	unsigned long (*get_flags) (void *priv);
++	unsigned long (*set_flags) (unsigned long flags, void *priv);
+ 
+ 	/* maximum number of bytes added by encryption; encrypt buf is
+ 	 * allocated with extra_prefix_len bytes, copy of in_buf, and
+ 	 * extra_postfix_len; encrypt need not use all this space, but
+ 	 * the result must start at the beginning of the buffer and correct
+ 	 * length must be returned */
+-	int extra_prefix_len, extra_postfix_len;
++	int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
++	int extra_msdu_prefix_len, extra_msdu_postfix_len;
+ 
+ 	struct module *owner;
+ };
+ 
+ struct ieee80211_crypt_data {
+-	struct list_head list; /* delayed deletion list */
++	struct list_head list;	/* delayed deletion list */
+ 	struct ieee80211_crypto_ops *ops;
+ 	void *priv;
+ 	atomic_t refcnt;
+@@ -77,10 +88,11 @@ struct ieee80211_crypt_data {
+ 
+ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
+ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
+-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
++struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
+ void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
+ void ieee80211_crypt_deinit_handler(unsigned long);
+ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
+ 				    struct ieee80211_crypt_data **crypt);
++void ieee80211_crypt_quiescing(struct ieee80211_device *ieee);
+ 
+ #endif
+diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
+new file mode 100644
+--- /dev/null
++++ b/include/net/ieee80211_radiotap.h
+@@ -0,0 +1,231 @@
++/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
++/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */
++
++/*-
++ * Copyright (c) 2003, 2004 David Young.  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. The name of David Young may not be used to endorse or promote
++ *    products derived from this software without specific prior
++ *    written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``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 DAVID
++ * YOUNG 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.
++ */
++
++/*
++ * Modifications to fit into the linux IEEE 802.11 stack,
++ * Mike Kershaw (dragorn at kismetwireless.net)
++ */
++
++#ifndef IEEE80211RADIOTAP_H
++#define IEEE80211RADIOTAP_H
++
++#include <linux/if_ether.h>
++#include <linux/kernel.h>
++
++/* Radiotap header version (from official NetBSD feed) */
++#define IEEE80211RADIOTAP_VERSION	"1.5"
++/* Base version of the radiotap packet header data */
++#define PKTHDR_RADIOTAP_VERSION		0
++
++/* A generic radio capture format is desirable. There is one for
++ * Linux, but it is neither rigidly defined (there were not even
++ * units given for some fields) nor easily extensible.
++ *
++ * I suggest the following extensible radio capture format. It is
++ * based on a bitmap indicating which fields are present.
++ *
++ * I am trying to describe precisely what the application programmer
++ * should expect in the following, and for that reason I tell the
++ * units and origin of each measurement (where it applies), or else I
++ * use sufficiently weaselly language ("is a monotonically nondecreasing
++ * function of...") that I cannot set false expectations for lawyerly
++ * readers.
++ */
++
++/* XXX tcpdump/libpcap do not tolerate variable-length headers,
++ * yet, so we pad every radiotap header to 64 bytes. Ugh.
++ */
++#define IEEE80211_RADIOTAP_HDRLEN	64
++
++/* The radio capture header precedes the 802.11 header. */
++struct ieee80211_radiotap_header {
++	u8 it_version;		/* Version 0. Only increases
++				 * for drastic changes,
++				 * introduction of compatible
++				 * new fields does not count.
++				 */
++	u8 it_pad;
++	u16 it_len;		/* length of the whole
++				 * header in bytes, including
++				 * it_version, it_pad,
++				 * it_len, and data fields.
++				 */
++	u32 it_present;		/* A bitmap telling which
++				 * fields are present. Set bit 31
++				 * (0x80000000) to extend the
++				 * bitmap by another 32 bits.
++				 * Additional extensions are made
++				 * by setting bit 31.
++				 */
++};
++
++/* Name                                 Data type       Units
++ * ----                                 ---------       -----
++ *
++ * IEEE80211_RADIOTAP_TSFT              u64       microseconds
++ *
++ *      Value in microseconds of the MAC's 64-bit 802.11 Time
++ *      Synchronization Function timer when the first bit of the
++ *      MPDU arrived at the MAC. For received frames, only.
++ *
++ * IEEE80211_RADIOTAP_CHANNEL           2 x u16   MHz, bitmap
++ *
++ *      Tx/Rx frequency in MHz, followed by flags (see below).
++ *
++ * IEEE80211_RADIOTAP_FHSS              u16       see below
++ *
++ *      For frequency-hopping radios, the hop set (first byte)
++ *      and pattern (second byte).
++ *
++ * IEEE80211_RADIOTAP_RATE              u8        500kb/s
++ *
++ *      Tx/Rx data rate
++ *
++ * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     int8_t          decibels from
++ *                                                      one milliwatt (dBm)
++ *
++ *      RF signal power at the antenna, decibel difference from
++ *      one milliwatt.
++ *
++ * IEEE80211_RADIOTAP_DBM_ANTNOISE      int8_t          decibels from
++ *                                                      one milliwatt (dBm)
++ *
++ *      RF noise power at the antenna, decibel difference from one
++ *      milliwatt.
++ *
++ * IEEE80211_RADIOTAP_DB_ANTSIGNAL      u8        decibel (dB)
++ *
++ *      RF signal power at the antenna, decibel difference from an
++ *      arbitrary, fixed reference.
++ *
++ * IEEE80211_RADIOTAP_DB_ANTNOISE       u8        decibel (dB)
++ *
++ *      RF noise power at the antenna, decibel difference from an
++ *      arbitrary, fixed reference point.
++ *
++ * IEEE80211_RADIOTAP_LOCK_QUALITY      u16       unitless
++ *
++ *      Quality of Barker code lock. Unitless. Monotonically
++ *      nondecreasing with "better" lock strength. Called "Signal
++ *      Quality" in datasheets.  (Is there a standard way to measure
++ *      this?)
++ *
++ * IEEE80211_RADIOTAP_TX_ATTENUATION    u16       unitless
++ *
++ *      Transmit power expressed as unitless distance from max
++ *      power set at factory calibration.  0 is max power.
++ *      Monotonically nondecreasing with lower power levels.
++ *
++ * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u16       decibels (dB)
++ *
++ *      Transmit power expressed as decibel distance from max power
++ *      set at factory calibration.  0 is max power.  Monotonically
++ *      nondecreasing with lower power levels.
++ *
++ * IEEE80211_RADIOTAP_DBM_TX_POWER      int8_t          decibels from
++ *                                                      one milliwatt (dBm)
++ *
++ *      Transmit power expressed as dBm (decibels from a 1 milliwatt
++ *      reference). This is the absolute power level measured at
++ *      the antenna port.
++ *
++ * IEEE80211_RADIOTAP_FLAGS             u8        bitmap
++ *
++ *      Properties of transmitted and received frames. See flags
++ *      defined below.
++ *
++ * IEEE80211_RADIOTAP_ANTENNA           u8        antenna index
++ *
++ *      Unitless indication of the Rx/Tx antenna for this packet.
++ *      The first antenna is antenna 0.
++ *
++ * IEEE80211_RADIOTAP_FCS           	u32       data
++ *
++ *	FCS from frame in network byte order.
++ */
++enum ieee80211_radiotap_type {
++	IEEE80211_RADIOTAP_TSFT = 0,
++	IEEE80211_RADIOTAP_FLAGS = 1,
++	IEEE80211_RADIOTAP_RATE = 2,
++	IEEE80211_RADIOTAP_CHANNEL = 3,
++	IEEE80211_RADIOTAP_FHSS = 4,
++	IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
++	IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
++	IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
++	IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
++	IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
++	IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
++	IEEE80211_RADIOTAP_ANTENNA = 11,
++	IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
++	IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
++	IEEE80211_RADIOTAP_EXT = 31,
++};
++
++/* Channel flags. */
++#define	IEEE80211_CHAN_TURBO	0x0010	/* Turbo channel */
++#define	IEEE80211_CHAN_CCK	0x0020	/* CCK channel */
++#define	IEEE80211_CHAN_OFDM	0x0040	/* OFDM channel */
++#define	IEEE80211_CHAN_2GHZ	0x0080	/* 2 GHz spectrum channel. */
++#define	IEEE80211_CHAN_5GHZ	0x0100	/* 5 GHz spectrum channel */
++#define	IEEE80211_CHAN_PASSIVE	0x0200	/* Only passive scan allowed */
++#define	IEEE80211_CHAN_DYN	0x0400	/* Dynamic CCK-OFDM channel */
++#define	IEEE80211_CHAN_GFSK	0x0800	/* GFSK channel (FHSS PHY) */
++
++/* For IEEE80211_RADIOTAP_FLAGS */
++#define	IEEE80211_RADIOTAP_F_CFP	0x01	/* sent/received
++						 * during CFP
++						 */
++#define	IEEE80211_RADIOTAP_F_SHORTPRE	0x02	/* sent/received
++						 * with short
++						 * preamble
++						 */
++#define	IEEE80211_RADIOTAP_F_WEP	0x04	/* sent/received
++						 * with WEP encryption
++						 */
++#define	IEEE80211_RADIOTAP_F_FRAG	0x08	/* sent/received
++						 * with fragmentation
++						 */
++#define	IEEE80211_RADIOTAP_F_FCS	0x10	/* frame includes FCS */
++#define	IEEE80211_RADIOTAP_F_DATAPAD	0x20	/* frame has padding between
++						 * 802.11 header and payload
++						 * (to 32-bit boundary)
++						 */
++
++/* Ugly macro to convert literal channel numbers into their mhz equivalents
++ * There are certianly some conditions that will break this (like feeding it '30')
++ * but they shouldn't arise since nothing talks on channel 30. */
++#define ieee80211chan2mhz(x) \
++	(((x) <= 14) ? \
++	(((x) == 14) ? 2484 : ((x) * 5) + 2407) : \
++	((x) + 1000) * 5)
++
++#endif				/* IEEE80211_RADIOTAP_H */
+diff --git a/include/net/netrom.h b/include/net/netrom.h
+--- a/include/net/netrom.h
++++ b/include/net/netrom.h
+@@ -136,8 +136,7 @@ static __inline__ void nr_node_put(struc
+ static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh)
+ {
+ 	if (atomic_dec_and_test(&nr_neigh->refcount)) {
+-		if (nr_neigh->digipeat != NULL)
+-			kfree(nr_neigh->digipeat);
++		kfree(nr_neigh->digipeat);
+ 		kfree(nr_neigh);
+ 	}
+ }
+diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
+--- a/include/net/sctp/user.h
++++ b/include/net/sctp/user.h
+@@ -171,10 +171,10 @@ struct sctp_sndrcvinfo {
+  */
+ 
+ enum sctp_sinfo_flags {
+-	MSG_UNORDERED = 1,  /* Send/receive message unordered. */
+-	MSG_ADDR_OVER = 2,  /* Override the primary destination. */
+-	MSG_ABORT=4,        /* Send an ABORT message to the peer. */
+-	/* MSG_EOF is already defined per socket.h */
++	SCTP_UNORDERED = 1,  /* Send/receive message unordered. */
++	SCTP_ADDR_OVER = 2,  /* Override the primary destination. */
++	SCTP_ABORT=4,        /* Send an ABORT message to the peer. */
++	SCTP_EOF=MSG_FIN,    /* Initiate graceful shutdown process. */	
+ };
+ 
+ 
+diff --git a/include/net/sock.h b/include/net/sock.h
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -207,7 +207,7 @@ struct sock {
+ 	struct sk_buff_head	sk_write_queue;
+ 	int			sk_wmem_queued;
+ 	int			sk_forward_alloc;
+-	unsigned int		sk_allocation;
++	gfp_t			sk_allocation;
+ 	int			sk_sndbuf;
+ 	int			sk_route_caps;
+ 	unsigned long 		sk_flags;
+diff --git a/include/net/syncppp.h b/include/net/syncppp.h
+--- a/include/net/syncppp.h
++++ b/include/net/syncppp.h
+@@ -86,7 +86,6 @@ static inline struct sppp *sppp_of(struc
+ 
+ void sppp_attach (struct ppp_device *pd);
+ void sppp_detach (struct net_device *dev);
+-void sppp_input (struct net_device *dev, struct sk_buff *m);
+ int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd);
+ struct sk_buff *sppp_dequeue (struct net_device *dev);
+ int sppp_isempty (struct net_device *dev);
+diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
+--- a/include/pcmcia/ss.h
++++ b/include/pcmcia/ss.h
+@@ -17,6 +17,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/device.h>
++#include <linux/sched.h>	/* task_struct, completion */
+ 
+ #include <pcmcia/cs_types.h>
+ #include <pcmcia/cs.h>
+diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h
+--- a/include/rdma/ib_cm.h
++++ b/include/rdma/ib_cm.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2004 Intel Corporation.  All rights reserved.
++ * Copyright (c) 2004, 2005 Intel Corporation.  All rights reserved.
+  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
+  * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
+  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+@@ -109,7 +109,6 @@ struct ib_cm_id;
+ 
+ struct ib_cm_req_event_param {
+ 	struct ib_cm_id		*listen_id;
+-	struct ib_device	*device;
+ 	u8			port;
+ 
+ 	struct ib_sa_path_rec	*primary_path;
+@@ -220,7 +219,6 @@ struct ib_cm_apr_event_param {
+ 
+ struct ib_cm_sidr_req_event_param {
+ 	struct ib_cm_id		*listen_id;
+-	struct ib_device	*device;
+ 	u8			port;
+ 	u16			pkey;
+ };
+@@ -284,6 +282,7 @@ typedef int (*ib_cm_handler)(struct ib_c
+ struct ib_cm_id {
+ 	ib_cm_handler		cm_handler;
+ 	void			*context;
++	struct ib_device	*device;
+ 	__be64			service_id;
+ 	__be64			service_mask;
+ 	enum ib_cm_state	state;		/* internal CM/debug use */
+@@ -295,6 +294,8 @@ struct ib_cm_id {
+ 
+ /**
+  * ib_create_cm_id - Allocate a communication identifier.
++ * @device: Device associated with the cm_id.  All related communication will
++ * be associated with the specified device.
+  * @cm_handler: Callback invoked to notify the user of CM events.
+  * @context: User specified context associated with the communication
+  *   identifier.
+@@ -302,7 +303,8 @@ struct ib_cm_id {
+  * Communication identifiers are used to track connection states, service
+  * ID resolution requests, and listen requests.
+  */
+-struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
++struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
++				 ib_cm_handler cm_handler,
+ 				 void *context);
+ 
+ /**
+diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
+--- a/include/rdma/ib_mad.h
++++ b/include/rdma/ib_mad.h
+@@ -109,10 +109,14 @@
+ #define IB_QP_SET_QKEY	0x80000000
+ 
+ enum {
++	IB_MGMT_MAD_HDR = 24,
+ 	IB_MGMT_MAD_DATA = 232,
++	IB_MGMT_RMPP_HDR = 36,
+ 	IB_MGMT_RMPP_DATA = 220,
++	IB_MGMT_VENDOR_HDR = 40,
+ 	IB_MGMT_VENDOR_DATA = 216,
+-	IB_MGMT_SA_DATA = 200
++	IB_MGMT_SA_HDR = 56,
++	IB_MGMT_SA_DATA = 200,
+ };
+ 
+ struct ib_mad_hdr {
+@@ -203,26 +207,25 @@ struct ib_class_port_info
+ 
+ /**
+  * ib_mad_send_buf - MAD data buffer and work request for sends.
+- * @mad: References an allocated MAD data buffer.  The size of the data
+- *   buffer is specified in the @send_wr.length field.
+- * @mapping: DMA mapping information.
++ * @next: A pointer used to chain together MADs for posting.
++ * @mad: References an allocated MAD data buffer.
+  * @mad_agent: MAD agent that allocated the buffer.
++ * @ah: The address handle to use when sending the MAD.
+  * @context: User-controlled context fields.
+- * @send_wr: An initialized work request structure used when sending the MAD.
+- *   The wr_id field of the work request is initialized to reference this
+- *   data structure.
+- * @sge: A scatter-gather list referenced by the work request.
++ * @timeout_ms: Time to wait for a response.
++ * @retries: Number of times to retry a request for a response.
+  *
+  * Users are responsible for initializing the MAD buffer itself, with the
+  * exception of specifying the payload length field in any RMPP MAD.
+  */
+ struct ib_mad_send_buf {
+-	struct ib_mad		*mad;
+-	DECLARE_PCI_UNMAP_ADDR(mapping)
++	struct ib_mad_send_buf	*next;
++	void			*mad;
+ 	struct ib_mad_agent	*mad_agent;
++	struct ib_ah		*ah;
+ 	void			*context[2];
+-	struct ib_send_wr	send_wr;
+-	struct ib_sge		sge;
++	int			timeout_ms;
++	int			retries;
+ };
+ 
+ /**
+@@ -287,7 +290,7 @@ typedef void (*ib_mad_send_handler)(stru
+  * or @mad_send_wc.
+  */
+ typedef void (*ib_mad_snoop_handler)(struct ib_mad_agent *mad_agent,
+-				     struct ib_send_wr *send_wr,
++				     struct ib_mad_send_buf *send_buf,
+ 				     struct ib_mad_send_wc *mad_send_wc);
+ 
+ /**
+@@ -334,13 +337,13 @@ struct ib_mad_agent {
+ 
+ /**
+  * ib_mad_send_wc - MAD send completion information.
+- * @wr_id: Work request identifier associated with the send MAD request.
++ * @send_buf: Send MAD data buffer associated with the send MAD request.
+  * @status: Completion status.
+  * @vendor_err: Optional vendor error information returned with a failed
+  *   request.
+  */
+ struct ib_mad_send_wc {
+-	u64			wr_id;
++	struct ib_mad_send_buf	*send_buf;
+ 	enum ib_wc_status	status;
+ 	u32			vendor_err;
+ };
+@@ -366,7 +369,7 @@ struct ib_mad_recv_buf {
+  * @rmpp_list: Specifies a list of RMPP reassembled received MAD buffers.
+  * @mad_len: The length of the received MAD, without duplicated headers.
+  *
+- * For received response, the wr_id field of the wc is set to the wr_id
++ * For received response, the wr_id contains a pointer to the ib_mad_send_buf
+  *   for the corresponding send request.
+  */
+ struct ib_mad_recv_wc {
+@@ -463,9 +466,9 @@ int ib_unregister_mad_agent(struct ib_ma
+ /**
+  * ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated
+  *   with the registered client.
+- * @mad_agent: Specifies the associated registration to post the send to.
+- * @send_wr: Specifies the information needed to send the MAD(s).
+- * @bad_send_wr: Specifies the MAD on which an error was encountered.
++ * @send_buf: Specifies the information needed to send the MAD(s).
++ * @bad_send_buf: Specifies the MAD on which an error was encountered.  This
++ *   parameter is optional if only a single MAD is posted.
+  *
+  * Sent MADs are not guaranteed to complete in the order that they were posted.
+  *
+@@ -479,9 +482,8 @@ int ib_unregister_mad_agent(struct ib_ma
+  * defined data being transferred.  The paylen_newwin field should be
+  * specified in network-byte order.
+  */
+-int ib_post_send_mad(struct ib_mad_agent *mad_agent,
+-		     struct ib_send_wr *send_wr,
+-		     struct ib_send_wr **bad_send_wr);
++int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
++		     struct ib_mad_send_buf **bad_send_buf);
+ 
+ /**
+  * ib_coalesce_recv_mad - Coalesces received MAD data into a single buffer.
+@@ -507,23 +509,25 @@ void ib_free_recv_mad(struct ib_mad_recv
+ /**
+  * ib_cancel_mad - Cancels an outstanding send MAD operation.
+  * @mad_agent: Specifies the registration associated with sent MAD.
+- * @wr_id: Indicates the work request identifier of the MAD to cancel.
++ * @send_buf: Indicates the MAD to cancel.
+  *
+  * MADs will be returned to the user through the corresponding
+  * ib_mad_send_handler.
+  */
+-void ib_cancel_mad(struct ib_mad_agent *mad_agent, u64 wr_id);
++void ib_cancel_mad(struct ib_mad_agent *mad_agent,
++		   struct ib_mad_send_buf *send_buf);
+ 
+ /**
+  * ib_modify_mad - Modifies an outstanding send MAD operation.
+  * @mad_agent: Specifies the registration associated with sent MAD.
+- * @wr_id: Indicates the work request identifier of the MAD to modify.
++ * @send_buf: Indicates the MAD to modify.
+  * @timeout_ms: New timeout value for sent MAD.
+  *
+  * This call will reset the timeout value for a sent MAD to the specified
+  * value.
+  */
+-int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms);
++int ib_modify_mad(struct ib_mad_agent *mad_agent,
++		  struct ib_mad_send_buf *send_buf, u32 timeout_ms);
+ 
+ /**
+  * ib_redirect_mad_qp - Registers a QP for MAD services.
+@@ -572,7 +576,6 @@ int ib_process_mad_wc(struct ib_mad_agen
+  * @remote_qpn: Specifies the QPN of the receiving node.
+  * @pkey_index: Specifies which PKey the MAD will be sent using.  This field
+  *   is valid only if the remote_qpn is QP 1.
+- * @ah: References the address handle used to transfer to the remote node.
+  * @rmpp_active: Indicates if the send will enable RMPP.
+  * @hdr_len: Indicates the size of the data header of the MAD.  This length
+  *   should include the common MAD header, RMPP header, plus any class
+@@ -582,11 +585,10 @@ int ib_process_mad_wc(struct ib_mad_agen
+  *   additional padding that may be necessary.
+  * @gfp_mask: GFP mask used for the memory allocation.
+  *
+- * This is a helper routine that may be used to allocate a MAD.  Users are
+- * not required to allocate outbound MADs using this call.  The returned
+- * MAD send buffer will reference a data buffer usable for sending a MAD, along
++ * This routine allocates a MAD for sending.  The returned MAD send buffer
++ * will reference a data buffer usable for sending a MAD, along
+  * with an initialized work request structure.  Users may modify the returned
+- * MAD data buffer or work request before posting the send.
++ * MAD data buffer before posting the send.
+  *
+  * The returned data buffer will be cleared.  Users are responsible for
+  * initializing the common MAD and any class specific headers.  If @rmpp_active
+@@ -594,7 +596,7 @@ int ib_process_mad_wc(struct ib_mad_agen
+  */
+ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
+ 					    u32 remote_qpn, u16 pkey_index,
+-					    struct ib_ah *ah, int rmpp_active,
++					    int rmpp_active,
+ 					    int hdr_len, int data_len,
+ 					    gfp_t gfp_mask);
+ 
+diff --git a/include/rdma/ib_user_cm.h b/include/rdma/ib_user_cm.h
+--- a/include/rdma/ib_user_cm.h
++++ b/include/rdma/ib_user_cm.h
+@@ -38,7 +38,7 @@
+ 
+ #include <linux/types.h>
+ 
+-#define IB_USER_CM_ABI_VERSION 2
++#define IB_USER_CM_ABI_VERSION 3
+ 
+ enum {
+ 	IB_USER_CM_CMD_CREATE_ID,
+@@ -299,8 +299,6 @@ struct ib_ucm_event_get {
+ };
+ 
+ struct ib_ucm_req_event_resp {
+-	/* device */
+-	/* port */
+ 	struct ib_ucm_path_rec primary_path;
+ 	struct ib_ucm_path_rec alternate_path;
+ 	__be64                 remote_ca_guid;
+@@ -316,6 +314,7 @@ struct ib_ucm_req_event_resp {
+ 	__u8  retry_count;
+ 	__u8  rnr_retry_count;
+ 	__u8  srq;
++	__u8  port;
+ };
+ 
+ struct ib_ucm_rep_event_resp {
+@@ -353,10 +352,9 @@ struct ib_ucm_apr_event_resp {
+ };
+ 
+ struct ib_ucm_sidr_req_event_resp {
+-	/* device */
+-	/* port */
+ 	__u16 pkey;
+-	__u8  reserved[2];
++	__u8  port;
++	__u8  reserved;
+ };
+ 
+ struct ib_ucm_sidr_rep_event_resp {
+diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h
+--- a/include/rdma/ib_user_verbs.h
++++ b/include/rdma/ib_user_verbs.h
+@@ -1,6 +1,7 @@
+ /*
+  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+  * Copyright (c) 2005 Cisco Systems.  All rights reserved.
++ * Copyright (c) 2005 PathScale, 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
+@@ -42,15 +43,12 @@
+  * Increment this value if any changes that break userspace ABI
+  * compatibility are made.
+  */
+-#define IB_USER_VERBS_ABI_VERSION	2
++#define IB_USER_VERBS_ABI_VERSION	3
+ 
+ enum {
+-	IB_USER_VERBS_CMD_QUERY_PARAMS,
+ 	IB_USER_VERBS_CMD_GET_CONTEXT,
+ 	IB_USER_VERBS_CMD_QUERY_DEVICE,
+ 	IB_USER_VERBS_CMD_QUERY_PORT,
+-	IB_USER_VERBS_CMD_QUERY_GID,
+-	IB_USER_VERBS_CMD_QUERY_PKEY,
+ 	IB_USER_VERBS_CMD_ALLOC_PD,
+ 	IB_USER_VERBS_CMD_DEALLOC_PD,
+ 	IB_USER_VERBS_CMD_CREATE_AH,
+@@ -65,6 +63,7 @@ enum {
+ 	IB_USER_VERBS_CMD_ALLOC_MW,
+ 	IB_USER_VERBS_CMD_BIND_MW,
+ 	IB_USER_VERBS_CMD_DEALLOC_MW,
++	IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL,
+ 	IB_USER_VERBS_CMD_CREATE_CQ,
+ 	IB_USER_VERBS_CMD_RESIZE_CQ,
+ 	IB_USER_VERBS_CMD_DESTROY_CQ,
+@@ -90,8 +89,11 @@ enum {
+  * Make sure that all structs defined in this file remain laid out so
+  * that they pack the same way on 32-bit and 64-bit architectures (to
+  * avoid incompatibility between 32-bit userspace and 64-bit kernels).
+- * In particular do not use pointer types -- pass pointers in __u64
+- * instead.
++ * Specifically:
++ *  - Do not use pointer types -- pass pointers in __u64 instead.
++ *  - Make sure that any structure larger than 4 bytes is padded to a
++ *    multiple of 8 bytes.  Otherwise the structure size will be
++ *    different between 32-bit and 64-bit architectures.
+  */
+ 
+ struct ib_uverbs_async_event_desc {
+@@ -118,27 +120,14 @@ struct ib_uverbs_cmd_hdr {
+ 	__u16 out_words;
+ };
+ 
+-/*
+- * No driver_data for "query params" command, since this is intended
+- * to be a core function with no possible device dependence.
+- */
+-struct ib_uverbs_query_params {
+-	__u64 response;
+-};
+-
+-struct ib_uverbs_query_params_resp {
+-	__u32 num_cq_events;
+-};
+-
+ struct ib_uverbs_get_context {
+ 	__u64 response;
+-	__u64 cq_fd_tab;
+ 	__u64 driver_data[0];
+ };
+ 
+ struct ib_uverbs_get_context_resp {
+ 	__u32 async_fd;
+-	__u32 reserved;
++	__u32 num_comp_vectors;
+ };
+ 
+ struct ib_uverbs_query_device {
+@@ -220,31 +209,6 @@ struct ib_uverbs_query_port_resp {
+ 	__u8  reserved[3];
+ };
+ 
+-struct ib_uverbs_query_gid {
+-	__u64 response;
+-	__u8  port_num;
+-	__u8  index;
+-	__u8  reserved[6];
+-	__u64 driver_data[0];
+-};
+-
+-struct ib_uverbs_query_gid_resp {
+-	__u8  gid[16];
+-};
+-
+-struct ib_uverbs_query_pkey {
+-	__u64 response;
+-	__u8  port_num;
+-	__u8  index;
+-	__u8  reserved[6];
+-	__u64 driver_data[0];
+-};
+-
+-struct ib_uverbs_query_pkey_resp {
+-	__u16 pkey;
+-	__u16 reserved;
+-};
+-
+ struct ib_uverbs_alloc_pd {
+ 	__u64 response;
+ 	__u64 driver_data[0];
+@@ -278,11 +242,21 @@ struct ib_uverbs_dereg_mr {
+ 	__u32 mr_handle;
+ };
+ 
++struct ib_uverbs_create_comp_channel {
++	__u64 response;
++};
++
++struct ib_uverbs_create_comp_channel_resp {
++	__u32 fd;
++};
++
+ struct ib_uverbs_create_cq {
+ 	__u64 response;
+ 	__u64 user_handle;
+ 	__u32 cqe;
+-	__u32 event_handler;
++	__u32 comp_vector;
++	__s32 comp_channel;
++	__u32 reserved;
+ 	__u64 driver_data[0];
+ };
+ 
+@@ -291,6 +265,41 @@ struct ib_uverbs_create_cq_resp {
+ 	__u32 cqe;
+ };
+ 
++struct ib_uverbs_poll_cq {
++	__u64 response;
++	__u32 cq_handle;
++	__u32 ne;
++};
++
++struct ib_uverbs_wc {
++	__u64 wr_id;
++	__u32 status;
++	__u32 opcode;
++	__u32 vendor_err;
++	__u32 byte_len;
++	__u32 imm_data;
++	__u32 qp_num;
++	__u32 src_qp;
++	__u32 wc_flags;
++	__u16 pkey_index;
++	__u16 slid;
++	__u8 sl;
++	__u8 dlid_path_bits;
++	__u8 port_num;
++	__u8 reserved;
++};
++
++struct ib_uverbs_poll_cq_resp {
++	__u32 count;
++	__u32 reserved;
++	struct ib_uverbs_wc wc[0];
++};
++
++struct ib_uverbs_req_notify_cq {
++	__u32 cq_handle;
++	__u32 solicited_only;
++};
++
+ struct ib_uverbs_destroy_cq {
+ 	__u64 response;
+ 	__u32 cq_handle;
+@@ -388,6 +397,127 @@ struct ib_uverbs_destroy_qp_resp {
+ 	__u32 events_reported;
+ };
+ 
++/*
++ * The ib_uverbs_sge structure isn't used anywhere, since we assume
++ * the ib_sge structure is packed the same way on 32-bit and 64-bit
++ * architectures in both kernel and user space.  It's just here to
++ * document the ABI.
++ */
++struct ib_uverbs_sge {
++	__u64 addr;
++	__u32 length;
++	__u32 lkey;
++};
++
++struct ib_uverbs_send_wr {
++	__u64 wr_id; 
++	__u32 num_sge;
++	__u32 opcode;
++	__u32 send_flags;
++	__u32 imm_data;
++	union {
++		struct {
++			__u64 remote_addr;
++			__u32 rkey;
++			__u32 reserved;
++		} rdma;
++		struct {
++			__u64 remote_addr;
++			__u64 compare_add;
++			__u64 swap;
++			__u32 rkey;
++			__u32 reserved;
++		} atomic;
++		struct {
++			__u32 ah;
++			__u32 remote_qpn;
++			__u32 remote_qkey;
++			__u32 reserved;
++		} ud;
++	} wr;
++};
++
++struct ib_uverbs_post_send {
++	__u64 response;
++	__u32 qp_handle;
++	__u32 wr_count;
++	__u32 sge_count;
++	__u32 wqe_size;
++	struct ib_uverbs_send_wr send_wr[0];
++};
++
++struct ib_uverbs_post_send_resp {
++	__u32 bad_wr;
++};
++
++struct ib_uverbs_recv_wr {
++	__u64 wr_id;
++	__u32 num_sge;
++	__u32 reserved;
++};
++
++struct ib_uverbs_post_recv {
++	__u64 response;
++	__u32 qp_handle;
++	__u32 wr_count;
++	__u32 sge_count;
++	__u32 wqe_size;
++	struct ib_uverbs_recv_wr recv_wr[0];
++};
++
++struct ib_uverbs_post_recv_resp {
++	__u32 bad_wr;
++};
++
++struct ib_uverbs_post_srq_recv {
++	__u64 response;
++	__u32 srq_handle;
++	__u32 wr_count;
++	__u32 sge_count;
++	__u32 wqe_size;
++	struct ib_uverbs_recv_wr recv[0];
++};
++
++struct ib_uverbs_post_srq_recv_resp {
++	__u32 bad_wr;
++};
++
++struct ib_uverbs_global_route {
++	__u8  dgid[16];
++	__u32 flow_label;    
++	__u8  sgid_index;
++	__u8  hop_limit;
++	__u8  traffic_class;
++	__u8  reserved;
++};
++
++struct ib_uverbs_ah_attr {
++	struct ib_uverbs_global_route grh;
++	__u16 dlid;
++	__u8  sl;
++	__u8  src_path_bits;
++	__u8  static_rate;
++	__u8  is_global;
++	__u8  port_num;
++	__u8  reserved;
++};
++
++struct ib_uverbs_create_ah {
++	__u64 response;
++	__u64 user_handle;
++	__u32 pd_handle;
++	__u32 reserved;
++	struct ib_uverbs_ah_attr attr;
++};
++
++struct ib_uverbs_create_ah_resp {
++	__u32 ah_handle;
++};
++
++struct ib_uverbs_destroy_ah {
++	__u32 ah_handle;
++};
++
+ struct ib_uverbs_attach_mcast {
+ 	__u8  gid[16];
+ 	__u32 qp_handle;
+diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
+--- a/include/rdma/ib_verbs.h
++++ b/include/rdma/ib_verbs.h
+@@ -595,11 +595,8 @@ struct ib_send_wr {
+ 		} atomic;
+ 		struct {
+ 			struct ib_ah *ah;
+-			struct ib_mad_hdr *mad_hdr;
+ 			u32	remote_qpn;
+ 			u32	remote_qkey;
+-			int	timeout_ms; /* valid for MADs only */
+-			int	retries;    /* valid for MADs only */
+ 			u16	pkey_index; /* valid for GSI only */
+ 			u8	port_num;   /* valid for DR SMPs on switch only */
+ 		} ud;
+@@ -951,6 +948,9 @@ struct ib_device {
+ 		IB_DEV_UNREGISTERED
+ 	}                            reg_state;
+ 
++	u64			     uverbs_cmd_mask;
++	int			     uverbs_abi_ver;
++
+ 	u8                           node_type;
+ 	u8                           phys_port_cnt;
+ };
+diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
+--- a/include/scsi/scsi.h
++++ b/include/scsi/scsi.h
+@@ -116,6 +116,9 @@ extern const char *const scsi_device_typ
+ /* values for service action in */
+ #define	SAI_READ_CAPACITY_16  0x10
+ 
++/* Values for T10/04-262r7 */
++#define	ATA_16		      0x85	/* 16-byte pass-thru */
++#define	ATA_12		      0xa1	/* 12-byte pass-thru */
+ 
+ /*
+  *  SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
+diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
+--- a/include/scsi/scsi_cmnd.h
++++ b/include/scsi/scsi_cmnd.h
+@@ -4,6 +4,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/list.h>
+ #include <linux/types.h>
++#include <linux/timer.h>
+ 
+ struct request;
+ struct scatterlist;
+@@ -146,7 +147,7 @@ struct scsi_cmnd {
+ #define SCSI_STATE_MLQUEUE         0x100b
+ 
+ 
+-extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, int);
++extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
+ extern void scsi_put_command(struct scsi_cmnd *);
+ extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
+ extern void scsi_finish_command(struct scsi_cmnd *cmd);
+diff --git a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h
+--- a/include/scsi/scsi_request.h
++++ b/include/scsi/scsi_request.h
+@@ -45,7 +45,7 @@ struct scsi_request {
+  					   level driver) of this request */
+ };
+ 
+-extern struct scsi_request *scsi_allocate_request(struct scsi_device *, int);
++extern struct scsi_request *scsi_allocate_request(struct scsi_device *, gfp_t);
+ extern void scsi_release_request(struct scsi_request *);
+ extern void scsi_wait_req(struct scsi_request *, const void *cmnd,
+ 			  void *buffer, unsigned bufflen,
+diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
+--- a/include/scsi/scsi_transport_fc.h
++++ b/include/scsi/scsi_transport_fc.h
+@@ -28,6 +28,7 @@
+ #define SCSI_TRANSPORT_FC_H
+ 
+ #include <linux/config.h>
++#include <linux/sched.h>
+ 
+ struct scsi_transport_template;
+ 
+diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
+--- a/include/sound/emu10k1.h
++++ b/include/sound/emu10k1.h
+@@ -1055,6 +1055,7 @@ typedef struct {
+ 	unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */
+ 	unsigned char ca0102_chip;  /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */
+ 	unsigned char ca0108_chip;  /* Audigy 2 Value */
++	unsigned char ca_cardbus_chip; /* Audigy 2 ZS Notebook */
+ 	unsigned char ca0151_chip;  /* P16V */
+ 	unsigned char spk71;        /* Has 7.1 speakers */
+ 	unsigned char sblive51;	    /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */
+diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
+--- a/include/sound/memalloc.h
++++ b/include/sound/memalloc.h
+@@ -111,7 +111,7 @@ size_t snd_dma_get_reserved_buf(struct s
+ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id);
+ 
+ /* basic memory allocation functions */
+-void *snd_malloc_pages(size_t size, unsigned int gfp_flags);
++void *snd_malloc_pages(size_t size, gfp_t gfp_flags);
+ void snd_free_pages(void *ptr, size_t size);
+ 
+ #endif /* __SOUND_MEMALLOC_H */
+diff --git a/init/Kconfig b/init/Kconfig
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -60,8 +60,8 @@ config INIT_ENV_ARG_LIMIT
+ 	default 32 if !USERMODE
+ 	default 128 if USERMODE
+ 	help
+-	  This is the value of the two limits on the number of argument and of
+-	  env.var passed to init from the kernel command line.
++	  Maximum of each of the number of arguments and environment
++	  variables passed to init from the kernel command line.
+ 
+ endmenu
+ 
+diff --git a/ipc/shm.c b/ipc/shm.c
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -233,10 +233,11 @@ static int newseg (key_t key, int shmflg
+ 	shp->id = shm_buildid(id,shp->shm_perm.seq);
+ 	shp->shm_file = file;
+ 	file->f_dentry->d_inode->i_ino = shp->id;
+-	if (shmflg & SHM_HUGETLB)
+-		set_file_hugepages(file);
+-	else
++
++	/* Hugetlb ops would have already been assigned. */
++	if (!(shmflg & SHM_HUGETLB))
+ 		file->f_op = &shm_file_operations;
++
+ 	shm_tot += numpages;
+ 	shm_unlock(shp);
+ 	return shp->id;
+diff --git a/kernel/Makefile b/kernel/Makefile
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -22,7 +22,6 @@ obj-$(CONFIG_KEXEC) += kexec.o
+ obj-$(CONFIG_COMPAT) += compat.o
+ obj-$(CONFIG_CPUSETS) += cpuset.o
+ obj-$(CONFIG_IKCONFIG) += configs.o
+-obj-$(CONFIG_IKCONFIG_PROC) += configs.o
+ obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
+ obj-$(CONFIG_AUDIT) += audit.o
+ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
+@@ -32,6 +31,7 @@ obj-$(CONFIG_DETECT_SOFTLOCKUP) += softl
+ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
+ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+ obj-$(CONFIG_SECCOMP) += seccomp.o
++obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
+ 
+ ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
+ # According to Alan Modra <alan at linuxcare.com.au>, the -fno-omit-frame-pointer is
+diff --git a/kernel/acct.c b/kernel/acct.c
+--- a/kernel/acct.c
++++ b/kernel/acct.c
+@@ -553,7 +553,7 @@ void acct_update_integrals(struct task_s
+ 		if (delta == 0)
+ 			return;
+ 		tsk->acct_stimexpd = tsk->stime;
+-		tsk->acct_rss_mem1 += delta * get_mm_counter(tsk->mm, rss);
++		tsk->acct_rss_mem1 += delta * get_mm_rss(tsk->mm);
+ 		tsk->acct_vm_mem1 += delta * tsk->mm->total_vm;
+ 	}
+ }
+diff --git a/kernel/audit.c b/kernel/audit.c
+--- a/kernel/audit.c
++++ b/kernel/audit.c
+@@ -133,7 +133,7 @@ struct audit_buffer {
+ 	struct list_head     list;
+ 	struct sk_buff       *skb;	/* formatted skb ready to send */
+ 	struct audit_context *ctx;	/* NULL or associated context */
+-	int		     gfp_mask;
++	gfp_t		     gfp_mask;
+ };
+ 
+ static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
+@@ -647,7 +647,7 @@ static inline void audit_get_stamp(struc
+  * will be written at syscall exit.  If there is no associated task, tsk
+  * should be NULL. */
+ 
+-struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
++struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
+ 				     int type)
+ {
+ 	struct audit_buffer	*ab	= NULL;
+@@ -879,7 +879,7 @@ void audit_log_end(struct audit_buffer *
+ /* Log an audit record.  This is a convenience function that calls
+  * audit_log_start, audit_log_vformat, and audit_log_end.  It may be
+  * called in any context. */
+-void audit_log(struct audit_context *ctx, int gfp_mask, int type, 
++void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, 
+ 	       const char *fmt, ...)
+ {
+ 	struct audit_buffer *ab;
+diff --git a/kernel/auditsc.c b/kernel/auditsc.c
+--- a/kernel/auditsc.c
++++ b/kernel/auditsc.c
+@@ -803,7 +803,7 @@ static void audit_log_task_info(struct a
+ 	up_read(&mm->mmap_sem);
+ }
+ 
+-static void audit_log_exit(struct audit_context *context, unsigned int gfp_mask)
++static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
+ {
+ 	int i;
+ 	struct audit_buffer *ab;
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -17,6 +17,7 @@
+ 
+ /* This protects CPUs going up and down... */
+ DECLARE_MUTEX(cpucontrol);
++EXPORT_SYMBOL_GPL(cpucontrol);
+ 
+ static struct notifier_block *cpu_chain;
+ 
+diff --git a/kernel/cpuset.c b/kernel/cpuset.c
+--- a/kernel/cpuset.c
++++ b/kernel/cpuset.c
+@@ -32,6 +32,7 @@
+ #include <linux/kernel.h>
+ #include <linux/kmod.h>
+ #include <linux/list.h>
++#include <linux/mempolicy.h>
+ #include <linux/mm.h>
+ #include <linux/module.h>
+ #include <linux/mount.h>
+@@ -60,6 +61,9 @@ struct cpuset {
+ 	cpumask_t cpus_allowed;		/* CPUs allowed to tasks in cpuset */
+ 	nodemask_t mems_allowed;	/* Memory Nodes allowed to tasks */
+ 
++	/*
++	 * Count is atomic so can incr (fork) or decr (exit) without a lock.
++	 */
+ 	atomic_t count;			/* count tasks using this cpuset */
+ 
+ 	/*
+@@ -142,80 +146,91 @@ static struct vfsmount *cpuset_mount;
+ static struct super_block *cpuset_sb = NULL;
+ 
+ /*
+- * cpuset_sem should be held by anyone who is depending on the children
+- * or sibling lists of any cpuset, or performing non-atomic operations
+- * on the flags or *_allowed values of a cpuset, such as raising the
+- * CS_REMOVED flag bit iff it is not already raised, or reading and
+- * conditionally modifying the *_allowed values.  One kernel global
+- * cpuset semaphore should be sufficient - these things don't change
+- * that much.
+- *
+- * The code that modifies cpusets holds cpuset_sem across the entire
+- * operation, from cpuset_common_file_write() down, single threading
+- * all cpuset modifications (except for counter manipulations from
+- * fork and exit) across the system.  This presumes that cpuset
+- * modifications are rare - better kept simple and safe, even if slow.
+- *
+- * The code that reads cpusets, such as in cpuset_common_file_read()
+- * and below, only holds cpuset_sem across small pieces of code, such
+- * as when reading out possibly multi-word cpumasks and nodemasks, as
+- * the risks are less, and the desire for performance a little greater.
+- * The proc_cpuset_show() routine needs to hold cpuset_sem to insure
+- * that no cs->dentry is NULL, as it walks up the cpuset tree to root.
+- *
+- * The hooks from fork and exit, cpuset_fork() and cpuset_exit(), don't
+- * (usually) grab cpuset_sem.  These are the two most performance
+- * critical pieces of code here.  The exception occurs on exit(),
+- * when a task in a notify_on_release cpuset exits.  Then cpuset_sem
++ * We have two global cpuset semaphores below.  They can nest.
++ * It is ok to first take manage_sem, then nest callback_sem.  We also
++ * require taking task_lock() when dereferencing a tasks cpuset pointer.
++ * See "The task_lock() exception", at the end of this comment.
++ *
++ * A task must hold both semaphores to modify cpusets.  If a task
++ * holds manage_sem, then it blocks others wanting that semaphore,
++ * ensuring that it is the only task able to also acquire callback_sem
++ * and be able to modify cpusets.  It can perform various checks on
++ * the cpuset structure first, knowing nothing will change.  It can
++ * also allocate memory while just holding manage_sem.  While it is
++ * performing these checks, various callback routines can briefly
++ * acquire callback_sem to query cpusets.  Once it is ready to make
++ * the changes, it takes callback_sem, blocking everyone else.
++ *
++ * Calls to the kernel memory allocator can not be made while holding
++ * callback_sem, as that would risk double tripping on callback_sem
++ * from one of the callbacks into the cpuset code from within
++ * __alloc_pages().
++ *
++ * If a task is only holding callback_sem, then it has read-only
++ * access to cpusets.
++ *
++ * The task_struct fields mems_allowed and mems_generation may only
++ * be accessed in the context of that task, so require no locks.
++ *
++ * Any task can increment and decrement the count field without lock.
++ * So in general, code holding manage_sem or callback_sem can't rely
++ * on the count field not changing.  However, if the count goes to
++ * zero, then only attach_task(), which holds both semaphores, can
++ * increment it again.  Because a count of zero means that no tasks
++ * are currently attached, therefore there is no way a task attached
++ * to that cpuset can fork (the other way to increment the count).
++ * So code holding manage_sem or callback_sem can safely assume that
++ * if the count is zero, it will stay zero.  Similarly, if a task
++ * holds manage_sem or callback_sem on a cpuset with zero count, it
++ * knows that the cpuset won't be removed, as cpuset_rmdir() needs
++ * both of those semaphores.
++ *
++ * A possible optimization to improve parallelism would be to make
++ * callback_sem a R/W semaphore (rwsem), allowing the callback routines
++ * to proceed in parallel, with read access, until the holder of
++ * manage_sem needed to take this rwsem for exclusive write access
++ * and modify some cpusets.
++ *
++ * The cpuset_common_file_write handler for operations that modify
++ * the cpuset hierarchy holds manage_sem across the entire operation,
++ * single threading all such cpuset modifications across the system.
++ *
++ * The cpuset_common_file_read() handlers only hold callback_sem across
++ * small pieces of code, such as when reading out possibly multi-word
++ * cpumasks and nodemasks.
++ *
++ * The fork and exit callbacks cpuset_fork() and cpuset_exit(), don't
++ * (usually) take either semaphore.  These are the two most performance
++ * critical pieces of code here.  The exception occurs on cpuset_exit(),
++ * when a task in a notify_on_release cpuset exits.  Then manage_sem
+  * is taken, and if the cpuset count is zero, a usermode call made
+  * to /sbin/cpuset_release_agent with the name of the cpuset (path
+  * relative to the root of cpuset file system) as the argument.
+  *
+- * A cpuset can only be deleted if both its 'count' of using tasks is
+- * zero, and its list of 'children' cpusets is empty.  Since all tasks
+- * in the system use _some_ cpuset, and since there is always at least
+- * one task in the system (init, pid == 1), therefore, top_cpuset
+- * always has either children cpusets and/or using tasks.  So no need
+- * for any special hack to ensure that top_cpuset cannot be deleted.
+- */
+-
+-static DECLARE_MUTEX(cpuset_sem);
+-static struct task_struct *cpuset_sem_owner;
+-static int cpuset_sem_depth;
+-
+-/*
+- * The global cpuset semaphore cpuset_sem can be needed by the
+- * memory allocator to update a tasks mems_allowed (see the calls
+- * to cpuset_update_current_mems_allowed()) or to walk up the
+- * cpuset hierarchy to find a mem_exclusive cpuset see the calls
+- * to cpuset_excl_nodes_overlap()).
+- *
+- * But if the memory allocation is being done by cpuset.c code, it
+- * usually already holds cpuset_sem.  Double tripping on a kernel
+- * semaphore deadlocks the current task, and any other task that
+- * subsequently tries to obtain the lock.
+- *
+- * Run all up's and down's on cpuset_sem through the following
+- * wrappers, which will detect this nested locking, and avoid
+- * deadlocking.
++ * A cpuset can only be deleted if both its 'count' of using tasks
++ * is zero, and its list of 'children' cpusets is empty.  Since all
++ * tasks in the system use _some_ cpuset, and since there is always at
++ * least one task in the system (init, pid == 1), therefore, top_cpuset
++ * always has either children cpusets and/or using tasks.  So we don't
++ * need a special hack to ensure that top_cpuset cannot be deleted.
++ *
++ * The above "Tale of Two Semaphores" would be complete, but for:
++ *
++ *	The task_lock() exception
++ *
++ * The need for this exception arises from the action of attach_task(),
++ * which overwrites one tasks cpuset pointer with another.  It does
++ * so using both semaphores, however there are several performance
++ * critical places that need to reference task->cpuset without the
++ * expense of grabbing a system global semaphore.  Therefore except as
++ * noted below, when dereferencing or, as in attach_task(), modifying
++ * a tasks cpuset pointer we use task_lock(), which acts on a spinlock
++ * (task->alloc_lock) already in the task_struct routinely used for
++ * such matters.
+  */
+ 
+-static inline void cpuset_down(struct semaphore *psem)
+-{
+-	if (cpuset_sem_owner != current) {
+-		down(psem);
+-		cpuset_sem_owner = current;
+-	}
+-	cpuset_sem_depth++;
+-}
+-
+-static inline void cpuset_up(struct semaphore *psem)
+-{
+-	if (--cpuset_sem_depth == 0) {
+-		cpuset_sem_owner = NULL;
+-		up(psem);
+-	}
+-}
++static DECLARE_MUTEX(manage_sem);
++static DECLARE_MUTEX(callback_sem);
+ 
+ /*
+  * A couple of forward declarations required, due to cyclic reference loop:
+@@ -390,7 +405,7 @@ static inline struct cftype *__d_cft(str
+ }
+ 
+ /*
+- * Call with cpuset_sem held.  Writes path of cpuset into buf.
++ * Call with manage_sem held.  Writes path of cpuset into buf.
+  * Returns 0 on success, -errno on error.
+  */
+ 
+@@ -442,10 +457,11 @@ static int cpuset_path(const struct cpus
+  * status of the /sbin/cpuset_release_agent task, so no sense holding
+  * our caller up for that.
+  *
+- * The simple act of forking that task might require more memory,
+- * which might need cpuset_sem.  So this routine must be called while
+- * cpuset_sem is not held, to avoid a possible deadlock.  See also
+- * comments for check_for_release(), below.
++ * When we had only one cpuset semaphore, we had to call this
++ * without holding it, to avoid deadlock when call_usermodehelper()
++ * allocated memory.  With two locks, we could now call this while
++ * holding manage_sem, but we still don't, so as to minimize
++ * the time manage_sem is held.
+  */
+ 
+ static void cpuset_release_agent(const char *pathbuf)
+@@ -477,15 +493,15 @@ static void cpuset_release_agent(const c
+  * cs is notify_on_release() and now both the user count is zero and
+  * the list of children is empty, prepare cpuset path in a kmalloc'd
+  * buffer, to be returned via ppathbuf, so that the caller can invoke
+- * cpuset_release_agent() with it later on, once cpuset_sem is dropped.
+- * Call here with cpuset_sem held.
++ * cpuset_release_agent() with it later on, once manage_sem is dropped.
++ * Call here with manage_sem held.
+  *
+  * This check_for_release() routine is responsible for kmalloc'ing
+  * pathbuf.  The above cpuset_release_agent() is responsible for
+  * kfree'ing pathbuf.  The caller of these routines is responsible
+  * for providing a pathbuf pointer, initialized to NULL, then
+- * calling check_for_release() with cpuset_sem held and the address
+- * of the pathbuf pointer, then dropping cpuset_sem, then calling
++ * calling check_for_release() with manage_sem held and the address
++ * of the pathbuf pointer, then dropping manage_sem, then calling
+  * cpuset_release_agent() with pathbuf, as set by check_for_release().
+  */
+ 
+@@ -516,7 +532,7 @@ static void check_for_release(struct cpu
+  * One way or another, we guarantee to return some non-empty subset
+  * of cpu_online_map.
+  *
+- * Call with cpuset_sem held.
++ * Call with callback_sem held.
+  */
+ 
+ static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
+@@ -540,7 +556,7 @@ static void guarantee_online_cpus(const 
+  * One way or another, we guarantee to return some non-empty subset
+  * of node_online_map.
+  *
+- * Call with cpuset_sem held.
++ * Call with callback_sem held.
+  */
+ 
+ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
+@@ -555,22 +571,47 @@ static void guarantee_online_mems(const 
+ }
+ 
+ /*
+- * Refresh current tasks mems_allowed and mems_generation from
+- * current tasks cpuset.  Call with cpuset_sem held.
++ * Refresh current tasks mems_allowed and mems_generation from current
++ * tasks cpuset.
+  *
+- * This routine is needed to update the per-task mems_allowed
+- * data, within the tasks context, when it is trying to allocate
+- * memory (in various mm/mempolicy.c routines) and notices
+- * that some other task has been modifying its cpuset.
++ * Call without callback_sem or task_lock() held.  May be called with
++ * or without manage_sem held.  Will acquire task_lock() and might
++ * acquire callback_sem during call.
++ *
++ * The task_lock() is required to dereference current->cpuset safely.
++ * Without it, we could pick up the pointer value of current->cpuset
++ * in one instruction, and then attach_task could give us a different
++ * cpuset, and then the cpuset we had could be removed and freed,
++ * and then on our next instruction, we could dereference a no longer
++ * valid cpuset pointer to get its mems_generation field.
++ *
++ * This routine is needed to update the per-task mems_allowed data,
++ * within the tasks context, when it is trying to allocate memory
++ * (in various mm/mempolicy.c routines) and notices that some other
++ * task has been modifying its cpuset.
+  */
+ 
+ static void refresh_mems(void)
+ {
+-	struct cpuset *cs = current->cpuset;
++	int my_cpusets_mem_gen;
+ 
+-	if (current->cpuset_mems_generation != cs->mems_generation) {
++	task_lock(current);
++	my_cpusets_mem_gen = current->cpuset->mems_generation;
++	task_unlock(current);
++
++	if (current->cpuset_mems_generation != my_cpusets_mem_gen) {
++		struct cpuset *cs;
++		nodemask_t oldmem = current->mems_allowed;
++
++		down(&callback_sem);
++		task_lock(current);
++		cs = current->cpuset;
+ 		guarantee_online_mems(cs, &current->mems_allowed);
+ 		current->cpuset_mems_generation = cs->mems_generation;
++		task_unlock(current);
++		up(&callback_sem);
++		if (!nodes_equal(oldmem, current->mems_allowed))
++			numa_policy_rebind(&oldmem, &current->mems_allowed);
+ 	}
+ }
+ 
+@@ -579,7 +620,7 @@ static void refresh_mems(void)
+  *
+  * One cpuset is a subset of another if all its allowed CPUs and
+  * Memory Nodes are a subset of the other, and its exclusive flags
+- * are only set if the other's are set.
++ * are only set if the other's are set.  Call holding manage_sem.
+  */
+ 
+ static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
+@@ -597,7 +638,7 @@ static int is_cpuset_subset(const struct
+  * If we replaced the flag and mask values of the current cpuset
+  * (cur) with those values in the trial cpuset (trial), would
+  * our various subset and exclusive rules still be valid?  Presumes
+- * cpuset_sem held.
++ * manage_sem held.
+  *
+  * 'cur' is the address of an actual, in-use cpuset.  Operations
+  * such as list traversal that depend on the actual address of the
+@@ -651,7 +692,7 @@ static int validate_change(const struct 
+  *    exclusive child cpusets
+  * Build these two partitions by calling partition_sched_domains
+  *
+- * Call with cpuset_sem held.  May nest a call to the
++ * Call with manage_sem held.  May nest a call to the
+  * lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
+  */
+ 
+@@ -696,6 +737,10 @@ static void update_cpu_domains(struct cp
+ 	unlock_cpu_hotplug();
+ }
+ 
++/*
++ * Call with manage_sem held.  May take callback_sem during call.
++ */
++
+ static int update_cpumask(struct cpuset *cs, char *buf)
+ {
+ 	struct cpuset trialcs;
+@@ -712,12 +757,18 @@ static int update_cpumask(struct cpuset 
+ 	if (retval < 0)
+ 		return retval;
+ 	cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed);
++	down(&callback_sem);
+ 	cs->cpus_allowed = trialcs.cpus_allowed;
++	up(&callback_sem);
+ 	if (is_cpu_exclusive(cs) && !cpus_unchanged)
+ 		update_cpu_domains(cs);
+ 	return 0;
+ }
+ 
++/*
++ * Call with manage_sem held.  May take callback_sem during call.
++ */
++
+ static int update_nodemask(struct cpuset *cs, char *buf)
+ {
+ 	struct cpuset trialcs;
+@@ -732,9 +783,11 @@ static int update_nodemask(struct cpuset
+ 		return -ENOSPC;
+ 	retval = validate_change(cs, &trialcs);
+ 	if (retval == 0) {
++		down(&callback_sem);
+ 		cs->mems_allowed = trialcs.mems_allowed;
+ 		atomic_inc(&cpuset_mems_generation);
+ 		cs->mems_generation = atomic_read(&cpuset_mems_generation);
++		up(&callback_sem);
+ 	}
+ 	return retval;
+ }
+@@ -745,6 +798,8 @@ static int update_nodemask(struct cpuset
+  *						CS_NOTIFY_ON_RELEASE)
+  * cs:	the cpuset to update
+  * buf:	the buffer where we read the 0 or 1
++ *
++ * Call with manage_sem held.
+  */
+ 
+ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
+@@ -766,16 +821,27 @@ static int update_flag(cpuset_flagbits_t
+ 		return err;
+ 	cpu_exclusive_changed =
+ 		(is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs));
++	down(&callback_sem);
+ 	if (turning_on)
+ 		set_bit(bit, &cs->flags);
+ 	else
+ 		clear_bit(bit, &cs->flags);
++	up(&callback_sem);
+ 
+ 	if (cpu_exclusive_changed)
+                 update_cpu_domains(cs);
+ 	return 0;
+ }
+ 
++/*
++ * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly
++ * writing the path of the old cpuset in 'ppathbuf' if it needs to be
++ * notified on release.
++ *
++ * Call holding manage_sem.  May take callback_sem and task_lock of
++ * the task 'pid' during call.
++ */
++
+ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
+ {
+ 	pid_t pid;
+@@ -792,7 +858,7 @@ static int attach_task(struct cpuset *cs
+ 		read_lock(&tasklist_lock);
+ 
+ 		tsk = find_task_by_pid(pid);
+-		if (!tsk) {
++		if (!tsk || tsk->flags & PF_EXITING) {
+ 			read_unlock(&tasklist_lock);
+ 			return -ESRCH;
+ 		}
+@@ -810,10 +876,13 @@ static int attach_task(struct cpuset *cs
+ 		get_task_struct(tsk);
+ 	}
+ 
++	down(&callback_sem);
++
+ 	task_lock(tsk);
+ 	oldcs = tsk->cpuset;
+ 	if (!oldcs) {
+ 		task_unlock(tsk);
++		up(&callback_sem);
+ 		put_task_struct(tsk);
+ 		return -ESRCH;
+ 	}
+@@ -824,6 +893,7 @@ static int attach_task(struct cpuset *cs
+ 	guarantee_online_cpus(cs, &cpus);
+ 	set_cpus_allowed(tsk, cpus);
+ 
++	up(&callback_sem);
+ 	put_task_struct(tsk);
+ 	if (atomic_dec_and_test(&oldcs->count))
+ 		check_for_release(oldcs, ppathbuf);
+@@ -867,7 +937,7 @@ static ssize_t cpuset_common_file_write(
+ 	}
+ 	buffer[nbytes] = 0;	/* nul-terminate */
+ 
+-	cpuset_down(&cpuset_sem);
++	down(&manage_sem);
+ 
+ 	if (is_removed(cs)) {
+ 		retval = -ENODEV;
+@@ -901,7 +971,7 @@ static ssize_t cpuset_common_file_write(
+ 	if (retval == 0)
+ 		retval = nbytes;
+ out2:
+-	cpuset_up(&cpuset_sem);
++	up(&manage_sem);
+ 	cpuset_release_agent(pathbuf);
+ out1:
+ 	kfree(buffer);
+@@ -941,9 +1011,9 @@ static int cpuset_sprintf_cpulist(char *
+ {
+ 	cpumask_t mask;
+ 
+-	cpuset_down(&cpuset_sem);
++	down(&callback_sem);
+ 	mask = cs->cpus_allowed;
+-	cpuset_up(&cpuset_sem);
++	up(&callback_sem);
+ 
+ 	return cpulist_scnprintf(page, PAGE_SIZE, mask);
+ }
+@@ -952,9 +1022,9 @@ static int cpuset_sprintf_memlist(char *
+ {
+ 	nodemask_t mask;
+ 
+-	cpuset_down(&cpuset_sem);
++	down(&callback_sem);
+ 	mask = cs->mems_allowed;
+-	cpuset_up(&cpuset_sem);
++	up(&callback_sem);
+ 
+ 	return nodelist_scnprintf(page, PAGE_SIZE, mask);
+ }
+@@ -995,7 +1065,6 @@ static ssize_t cpuset_common_file_read(s
+ 		goto out;
+ 	}
+ 	*s++ = '\n';
+-	*s = '\0';
+ 
+ 	retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
+ out:
+@@ -1048,6 +1117,21 @@ static int cpuset_file_release(struct in
+ 	return 0;
+ }
+ 
++/*
++ * cpuset_rename - Only allow simple rename of directories in place.
++ */
++static int cpuset_rename(struct inode *old_dir, struct dentry *old_dentry,
++                  struct inode *new_dir, struct dentry *new_dentry)
++{
++	if (!S_ISDIR(old_dentry->d_inode->i_mode))
++		return -ENOTDIR;
++	if (new_dentry->d_inode)
++		return -EEXIST;
++	if (old_dir != new_dir)
++		return -EIO;
++	return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
++}
++
+ static struct file_operations cpuset_file_operations = {
+ 	.read = cpuset_file_read,
+ 	.write = cpuset_file_write,
+@@ -1060,6 +1144,7 @@ static struct inode_operations cpuset_di
+ 	.lookup = simple_lookup,
+ 	.mkdir = cpuset_mkdir,
+ 	.rmdir = cpuset_rmdir,
++	.rename = cpuset_rename,
+ };
+ 
+ static int cpuset_create_file(struct dentry *dentry, int mode)
+@@ -1163,7 +1248,9 @@ struct ctr_struct {
+ 
+ /*
+  * Load into 'pidarray' up to 'npids' of the tasks using cpuset 'cs'.
+- * Return actual number of pids loaded.
++ * Return actual number of pids loaded.  No need to task_lock(p)
++ * when reading out p->cpuset, as we don't really care if it changes
++ * on the next cycle, and we are not going to try to dereference it.
+  */
+ static inline int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs)
+ {
+@@ -1205,6 +1292,12 @@ static int pid_array_to_buf(char *buf, i
+ 	return cnt;
+ }
+ 
++/*
++ * Handle an open on 'tasks' file.  Prepare a buffer listing the
++ * process id's of tasks currently attached to the cpuset being opened.
++ *
++ * Does not require any specific cpuset semaphores, and does not take any.
++ */
+ static int cpuset_tasks_open(struct inode *unused, struct file *file)
+ {
+ 	struct cpuset *cs = __d_cs(file->f_dentry->d_parent);
+@@ -1352,7 +1445,8 @@ static long cpuset_create(struct cpuset 
+ 	if (!cs)
+ 		return -ENOMEM;
+ 
+-	cpuset_down(&cpuset_sem);
++	down(&manage_sem);
++	refresh_mems();
+ 	cs->flags = 0;
+ 	if (notify_on_release(parent))
+ 		set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
+@@ -1366,25 +1460,27 @@ static long cpuset_create(struct cpuset 
+ 
+ 	cs->parent = parent;
+ 
++	down(&callback_sem);
+ 	list_add(&cs->sibling, &cs->parent->children);
++	up(&callback_sem);
+ 
+ 	err = cpuset_create_dir(cs, name, mode);
+ 	if (err < 0)
+ 		goto err;
+ 
+ 	/*
+-	 * Release cpuset_sem before cpuset_populate_dir() because it
++	 * Release manage_sem before cpuset_populate_dir() because it
+ 	 * will down() this new directory's i_sem and if we race with
+ 	 * another mkdir, we might deadlock.
+ 	 */
+-	cpuset_up(&cpuset_sem);
++	up(&manage_sem);
+ 
+ 	err = cpuset_populate_dir(cs->dentry);
+ 	/* If err < 0, we have a half-filled directory - oh well ;) */
+ 	return 0;
+ err:
+ 	list_del(&cs->sibling);
+-	cpuset_up(&cpuset_sem);
++	up(&manage_sem);
+ 	kfree(cs);
+ 	return err;
+ }
+@@ -1406,29 +1502,32 @@ static int cpuset_rmdir(struct inode *un
+ 
+ 	/* the vfs holds both inode->i_sem already */
+ 
+-	cpuset_down(&cpuset_sem);
++	down(&manage_sem);
++	refresh_mems();
+ 	if (atomic_read(&cs->count) > 0) {
+-		cpuset_up(&cpuset_sem);
++		up(&manage_sem);
+ 		return -EBUSY;
+ 	}
+ 	if (!list_empty(&cs->children)) {
+-		cpuset_up(&cpuset_sem);
++		up(&manage_sem);
+ 		return -EBUSY;
+ 	}
+ 	parent = cs->parent;
++	down(&callback_sem);
+ 	set_bit(CS_REMOVED, &cs->flags);
+ 	if (is_cpu_exclusive(cs))
+ 		update_cpu_domains(cs);
+ 	list_del(&cs->sibling);	/* delete my sibling from parent->children */
+-	if (list_empty(&parent->children))
+-		check_for_release(parent, &pathbuf);
+ 	spin_lock(&cs->dentry->d_lock);
+ 	d = dget(cs->dentry);
+ 	cs->dentry = NULL;
+ 	spin_unlock(&d->d_lock);
+ 	cpuset_d_remove_dir(d);
+ 	dput(d);
+-	cpuset_up(&cpuset_sem);
++	up(&callback_sem);
++	if (list_empty(&parent->children))
++		check_for_release(parent, &pathbuf);
++	up(&manage_sem);
+ 	cpuset_release_agent(pathbuf);
+ 	return 0;
+ }
+@@ -1488,16 +1587,26 @@ void __init cpuset_init_smp(void)
+  * cpuset_fork - attach newly forked task to its parents cpuset.
+  * @tsk: pointer to task_struct of forking parent process.
+  *
+- * Description: By default, on fork, a task inherits its
+- * parent's cpuset.  The pointer to the shared cpuset is
+- * automatically copied in fork.c by dup_task_struct().
+- * This cpuset_fork() routine need only increment the usage
+- * counter in that cpuset.
++ * Description: A task inherits its parent's cpuset at fork().
++ *
++ * A pointer to the shared cpuset was automatically copied in fork.c
++ * by dup_task_struct().  However, we ignore that copy, since it was
++ * not made under the protection of task_lock(), so might no longer be
++ * a valid cpuset pointer.  attach_task() might have already changed
++ * current->cpuset, allowing the previously referenced cpuset to
++ * be removed and freed.  Instead, we task_lock(current) and copy
++ * its present value of current->cpuset for our freshly forked child.
++ *
++ * At the point that cpuset_fork() is called, 'current' is the parent
++ * task, and the passed argument 'child' points to the child task.
+  **/
+ 
+-void cpuset_fork(struct task_struct *tsk)
++void cpuset_fork(struct task_struct *child)
+ {
+-	atomic_inc(&tsk->cpuset->count);
++	task_lock(current);
++	child->cpuset = current->cpuset;
++	atomic_inc(&child->cpuset->count);
++	task_unlock(current);
+ }
+ 
+ /**
+@@ -1506,35 +1615,42 @@ void cpuset_fork(struct task_struct *tsk
+  *
+  * Description: Detach cpuset from @tsk and release it.
+  *
+- * Note that cpusets marked notify_on_release force every task
+- * in them to take the global cpuset_sem semaphore when exiting.
+- * This could impact scaling on very large systems.  Be reluctant
+- * to use notify_on_release cpusets where very high task exit
+- * scaling is required on large systems.
+- *
+- * Don't even think about derefencing 'cs' after the cpuset use
+- * count goes to zero, except inside a critical section guarded
+- * by the cpuset_sem semaphore.  If you don't hold cpuset_sem,
+- * then a zero cpuset use count is a license to any other task to
+- * nuke the cpuset immediately.
++ * Note that cpusets marked notify_on_release force every task in
++ * them to take the global manage_sem semaphore when exiting.
++ * This could impact scaling on very large systems.  Be reluctant to
++ * use notify_on_release cpusets where very high task exit scaling
++ * is required on large systems.
++ *
++ * Don't even think about derefencing 'cs' after the cpuset use count
++ * goes to zero, except inside a critical section guarded by manage_sem
++ * or callback_sem.   Otherwise a zero cpuset use count is a license to
++ * any other task to nuke the cpuset immediately, via cpuset_rmdir().
++ *
++ * This routine has to take manage_sem, not callback_sem, because
++ * it is holding that semaphore while calling check_for_release(),
++ * which calls kmalloc(), so can't be called holding callback__sem().
++ *
++ * We don't need to task_lock() this reference to tsk->cpuset,
++ * because tsk is already marked PF_EXITING, so attach_task() won't
++ * mess with it.
+  **/
+ 
+ void cpuset_exit(struct task_struct *tsk)
+ {
+ 	struct cpuset *cs;
+ 
+-	task_lock(tsk);
++	BUG_ON(!(tsk->flags & PF_EXITING));
++
+ 	cs = tsk->cpuset;
+ 	tsk->cpuset = NULL;
+-	task_unlock(tsk);
+ 
+ 	if (notify_on_release(cs)) {
+ 		char *pathbuf = NULL;
+ 
+-		cpuset_down(&cpuset_sem);
++		down(&manage_sem);
+ 		if (atomic_dec_and_test(&cs->count))
+ 			check_for_release(cs, &pathbuf);
+-		cpuset_up(&cpuset_sem);
++		up(&manage_sem);
+ 		cpuset_release_agent(pathbuf);
+ 	} else {
+ 		atomic_dec(&cs->count);
+@@ -1555,11 +1671,11 @@ cpumask_t cpuset_cpus_allowed(const stru
+ {
+ 	cpumask_t mask;
+ 
+-	cpuset_down(&cpuset_sem);
++	down(&callback_sem);
+ 	task_lock((struct task_struct *)tsk);
+ 	guarantee_online_cpus(tsk->cpuset, &mask);
+ 	task_unlock((struct task_struct *)tsk);
+-	cpuset_up(&cpuset_sem);
++	up(&callback_sem);
+ 
+ 	return mask;
+ }
+@@ -1575,19 +1691,28 @@ void cpuset_init_current_mems_allowed(vo
+  * If the current tasks cpusets mems_allowed changed behind our backs,
+  * update current->mems_allowed and mems_generation to the new value.
+  * Do not call this routine if in_interrupt().
++ *
++ * Call without callback_sem or task_lock() held.  May be called
++ * with or without manage_sem held.  Unless exiting, it will acquire
++ * task_lock().  Also might acquire callback_sem during call to
++ * refresh_mems().
+  */
+ 
+ void cpuset_update_current_mems_allowed(void)
+ {
+-	struct cpuset *cs = current->cpuset;
++	struct cpuset *cs;
++	int need_to_refresh = 0;
+ 
++	task_lock(current);
++	cs = current->cpuset;
+ 	if (!cs)
+-		return;		/* task is exiting */
+-	if (current->cpuset_mems_generation != cs->mems_generation) {
+-		cpuset_down(&cpuset_sem);
++		goto done;
++	if (current->cpuset_mems_generation != cs->mems_generation)
++		need_to_refresh = 1;
++done:
++	task_unlock(current);
++	if (need_to_refresh)
+ 		refresh_mems();
+-		cpuset_up(&cpuset_sem);
+-	}
+ }
+ 
+ /**
+@@ -1621,7 +1746,7 @@ int cpuset_zonelist_valid_mems_allowed(s
+ 
+ /*
+  * nearest_exclusive_ancestor() - Returns the nearest mem_exclusive
+- * ancestor to the specified cpuset.  Call while holding cpuset_sem.
++ * ancestor to the specified cpuset.  Call holding callback_sem.
+  * If no ancestor is mem_exclusive (an unusual configuration), then
+  * returns the root cpuset.
+  */
+@@ -1648,12 +1773,12 @@ static const struct cpuset *nearest_excl
+  * GFP_KERNEL allocations are not so marked, so can escape to the
+  * nearest mem_exclusive ancestor cpuset.
+  *
+- * Scanning up parent cpusets requires cpuset_sem.  The __alloc_pages()
++ * Scanning up parent cpusets requires callback_sem.  The __alloc_pages()
+  * routine only calls here with __GFP_HARDWALL bit _not_ set if
+  * it's a GFP_KERNEL allocation, and all nodes in the current tasks
+  * mems_allowed came up empty on the first pass over the zonelist.
+  * So only GFP_KERNEL allocations, if all nodes in the cpuset are
+- * short of memory, might require taking the cpuset_sem semaphore.
++ * short of memory, might require taking the callback_sem semaphore.
+  *
+  * The first loop over the zonelist in mm/page_alloc.c:__alloc_pages()
+  * calls here with __GFP_HARDWALL always set in gfp_mask, enforcing
+@@ -1685,14 +1810,16 @@ int cpuset_zone_allowed(struct zone *z, 
+ 		return 0;
+ 
+ 	/* Not hardwall and node outside mems_allowed: scan up cpusets */
+-	cpuset_down(&cpuset_sem);
+-	cs = current->cpuset;
+-	if (!cs)
+-		goto done;		/* current task exiting */
+-	cs = nearest_exclusive_ancestor(cs);
++	down(&callback_sem);
++
++	if (current->flags & PF_EXITING) /* Let dying task have memory */
++		return 1;
++	task_lock(current);
++	cs = nearest_exclusive_ancestor(current->cpuset);
++	task_unlock(current);
++
+ 	allowed = node_isset(node, cs->mems_allowed);
+-done:
+-	cpuset_up(&cpuset_sem);
++	up(&callback_sem);
+ 	return allowed;
+ }
+ 
+@@ -1705,7 +1832,7 @@ done:
+  * determine if task @p's memory usage might impact the memory
+  * available to the current task.
+  *
+- * Acquires cpuset_sem - not suitable for calling from a fast path.
++ * Acquires callback_sem - not suitable for calling from a fast path.
+  **/
+ 
+ int cpuset_excl_nodes_overlap(const struct task_struct *p)
+@@ -1713,18 +1840,27 @@ int cpuset_excl_nodes_overlap(const stru
+ 	const struct cpuset *cs1, *cs2;	/* my and p's cpuset ancestors */
+ 	int overlap = 0;		/* do cpusets overlap? */
+ 
+-	cpuset_down(&cpuset_sem);
+-	cs1 = current->cpuset;
+-	if (!cs1)
+-		goto done;		/* current task exiting */
+-	cs2 = p->cpuset;
+-	if (!cs2)
+-		goto done;		/* task p is exiting */
+-	cs1 = nearest_exclusive_ancestor(cs1);
+-	cs2 = nearest_exclusive_ancestor(cs2);
++	down(&callback_sem);
++
++	task_lock(current);
++	if (current->flags & PF_EXITING) {
++		task_unlock(current);
++		goto done;
++	}
++	cs1 = nearest_exclusive_ancestor(current->cpuset);
++	task_unlock(current);
++
++	task_lock((struct task_struct *)p);
++	if (p->flags & PF_EXITING) {
++		task_unlock((struct task_struct *)p);
++		goto done;
++	}
++	cs2 = nearest_exclusive_ancestor(p->cpuset);
++	task_unlock((struct task_struct *)p);
++
+ 	overlap = nodes_intersects(cs1->mems_allowed, cs2->mems_allowed);
+ done:
+-	cpuset_up(&cpuset_sem);
++	up(&callback_sem);
+ 
+ 	return overlap;
+ }
+@@ -1733,6 +1869,10 @@ done:
+  * proc_cpuset_show()
+  *  - Print tasks cpuset path into seq_file.
+  *  - Used for /proc/<pid>/cpuset.
++ *  - No need to task_lock(tsk) on this tsk->cpuset reference, as it
++ *    doesn't really matter if tsk->cpuset changes after we read it,
++ *    and we take manage_sem, keeping attach_task() from changing it
++ *    anyway.
+  */
+ 
+ static int proc_cpuset_show(struct seq_file *m, void *v)
+@@ -1747,10 +1887,8 @@ static int proc_cpuset_show(struct seq_f
+ 		return -ENOMEM;
+ 
+ 	tsk = m->private;
+-	cpuset_down(&cpuset_sem);
+-	task_lock(tsk);
++	down(&manage_sem);
+ 	cs = tsk->cpuset;
+-	task_unlock(tsk);
+ 	if (!cs) {
+ 		retval = -EINVAL;
+ 		goto out;
+@@ -1762,7 +1900,7 @@ static int proc_cpuset_show(struct seq_f
+ 	seq_puts(m, buf);
+ 	seq_putc(m, '\n');
+ out:
+-	cpuset_up(&cpuset_sem);
++	up(&manage_sem);
+ 	kfree(buf);
+ 	return retval;
+ }
+diff --git a/kernel/exit.c b/kernel/exit.c
+--- a/kernel/exit.c
++++ b/kernel/exit.c
+@@ -547,7 +547,7 @@ static inline void reparent_thread(task_
+ 
+ 	if (p->pdeath_signal)
+ 		/* We already hold the tasklist_lock here.  */
+-		group_send_sig_info(p->pdeath_signal, (void *) 0, p);
++		group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
+ 
+ 	/* Move the child from its dying parent to the new one.  */
+ 	if (unlikely(traced)) {
+@@ -591,8 +591,8 @@ static inline void reparent_thread(task_
+ 		int pgrp = process_group(p);
+ 
+ 		if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
+-			__kill_pg_info(SIGHUP, (void *)1, pgrp);
+-			__kill_pg_info(SIGCONT, (void *)1, pgrp);
++			__kill_pg_info(SIGHUP, SEND_SIG_PRIV, pgrp);
++			__kill_pg_info(SIGCONT, SEND_SIG_PRIV, pgrp);
+ 		}
+ 	}
+ }
+@@ -727,8 +727,8 @@ static void exit_notify(struct task_stru
+ 	    (t->signal->session == tsk->signal->session) &&
+ 	    will_become_orphaned_pgrp(process_group(tsk), tsk) &&
+ 	    has_stopped_jobs(process_group(tsk))) {
+-		__kill_pg_info(SIGHUP, (void *)1, process_group(tsk));
+-		__kill_pg_info(SIGCONT, (void *)1, process_group(tsk));
++		__kill_pg_info(SIGHUP, SEND_SIG_PRIV, process_group(tsk));
++		__kill_pg_info(SIGCONT, SEND_SIG_PRIV, process_group(tsk));
+ 	}
+ 
+ 	/* Let father know we died 
+@@ -783,10 +783,6 @@ static void exit_notify(struct task_stru
+ 	/* If the process is dead, release it - nobody will wait for it */
+ 	if (state == EXIT_DEAD)
+ 		release_task(tsk);
+-
+-	/* PF_DEAD causes final put_task_struct after we schedule. */
+-	preempt_disable();
+-	tsk->flags |= PF_DEAD;
+ }
+ 
+ fastcall NORET_TYPE void do_exit(long code)
+@@ -839,7 +835,10 @@ fastcall NORET_TYPE void do_exit(long co
+ 				preempt_count());
+ 
+ 	acct_update_integrals(tsk);
+-	update_mem_hiwater(tsk);
++	if (tsk->mm) {
++		update_hiwater_rss(tsk->mm);
++		update_hiwater_vm(tsk->mm);
++	}
+ 	group_dead = atomic_dec_and_test(&tsk->signal->live);
+ 	if (group_dead) {
+  		del_timer_sync(&tsk->signal->real_timer);
+@@ -870,7 +869,11 @@ fastcall NORET_TYPE void do_exit(long co
+ 	tsk->mempolicy = NULL;
+ #endif
+ 
+-	BUG_ON(!(current->flags & PF_DEAD));
++	/* PF_DEAD causes final put_task_struct after we schedule. */
++	preempt_disable();
++	BUG_ON(tsk->flags & PF_DEAD);
++	tsk->flags |= PF_DEAD;
++
+ 	schedule();
+ 	BUG();
+ 	/* Avoid "noreturn function does return".  */
+@@ -1380,6 +1383,15 @@ repeat:
+ 
+ 			switch (p->state) {
+ 			case TASK_TRACED:
++				/*
++				 * When we hit the race with PTRACE_ATTACH,
++				 * we will not report this child.  But the
++				 * race means it has not yet been moved to
++				 * our ptrace_children list, so we need to
++				 * set the flag here to avoid a spurious ECHILD
++				 * when the race happens with the only child.
++				 */
++				flag = 1;
+ 				if (!my_ptrace_child(p))
+ 					continue;
+ 				/*FALLTHROUGH*/
+diff --git a/kernel/fork.c b/kernel/fork.c
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -182,37 +182,37 @@ static struct task_struct *dup_task_stru
+ }
+ 
+ #ifdef CONFIG_MMU
+-static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
++static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+ {
+-	struct vm_area_struct * mpnt, *tmp, **pprev;
++	struct vm_area_struct *mpnt, *tmp, **pprev;
+ 	struct rb_node **rb_link, *rb_parent;
+ 	int retval;
+ 	unsigned long charge;
+ 	struct mempolicy *pol;
+ 
+ 	down_write(&oldmm->mmap_sem);
+-	flush_cache_mm(current->mm);
++	flush_cache_mm(oldmm);
++	down_write(&mm->mmap_sem);
++
+ 	mm->locked_vm = 0;
+ 	mm->mmap = NULL;
+ 	mm->mmap_cache = NULL;
+ 	mm->free_area_cache = oldmm->mmap_base;
+ 	mm->cached_hole_size = ~0UL;
+ 	mm->map_count = 0;
+-	set_mm_counter(mm, rss, 0);
+-	set_mm_counter(mm, anon_rss, 0);
+ 	cpus_clear(mm->cpu_vm_mask);
+ 	mm->mm_rb = RB_ROOT;
+ 	rb_link = &mm->mm_rb.rb_node;
+ 	rb_parent = NULL;
+ 	pprev = &mm->mmap;
+ 
+-	for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
++	for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
+ 		struct file *file;
+ 
+ 		if (mpnt->vm_flags & VM_DONTCOPY) {
+ 			long pages = vma_pages(mpnt);
+ 			mm->total_vm -= pages;
+-			__vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
++			vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
+ 								-pages);
+ 			continue;
+ 		}
+@@ -253,12 +253,8 @@ static inline int dup_mmap(struct mm_str
+ 		}
+ 
+ 		/*
+-		 * Link in the new vma and copy the page table entries:
+-		 * link in first so that swapoff can see swap entries.
+-		 * Note that, exceptionally, here the vma is inserted
+-		 * without holding mm->mmap_sem.
++		 * Link in the new vma and copy the page table entries.
+ 		 */
+-		spin_lock(&mm->page_table_lock);
+ 		*pprev = tmp;
+ 		pprev = &tmp->vm_next;
+ 
+@@ -267,8 +263,7 @@ static inline int dup_mmap(struct mm_str
+ 		rb_parent = &tmp->vm_rb;
+ 
+ 		mm->map_count++;
+-		retval = copy_page_range(mm, current->mm, tmp);
+-		spin_unlock(&mm->page_table_lock);
++		retval = copy_page_range(mm, oldmm, tmp);
+ 
+ 		if (tmp->vm_ops && tmp->vm_ops->open)
+ 			tmp->vm_ops->open(tmp);
+@@ -277,9 +272,9 @@ static inline int dup_mmap(struct mm_str
+ 			goto out;
+ 	}
+ 	retval = 0;
+-
+ out:
+-	flush_tlb_mm(current->mm);
++	up_write(&mm->mmap_sem);
++	flush_tlb_mm(oldmm);
+ 	up_write(&oldmm->mmap_sem);
+ 	return retval;
+ fail_nomem_policy:
+@@ -323,6 +318,8 @@ static struct mm_struct * mm_init(struct
+ 	INIT_LIST_HEAD(&mm->mmlist);
+ 	mm->core_waiters = 0;
+ 	mm->nr_ptes = 0;
++	set_mm_counter(mm, file_rss, 0);
++	set_mm_counter(mm, anon_rss, 0);
+ 	spin_lock_init(&mm->page_table_lock);
+ 	rwlock_init(&mm->ioctx_list_lock);
+ 	mm->ioctx_list = NULL;
+@@ -499,7 +496,7 @@ static int copy_mm(unsigned long clone_f
+ 	if (retval)
+ 		goto free_pt;
+ 
+-	mm->hiwater_rss = get_mm_counter(mm,rss);
++	mm->hiwater_rss = get_mm_rss(mm);
+ 	mm->hiwater_vm = mm->total_vm;
+ 
+ good_mm:
+diff --git a/kernel/futex.c b/kernel/futex.c
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -205,15 +205,13 @@ static int get_futex_key(unsigned long u
+ 	/*
+ 	 * Do a quick atomic lookup first - this is the fastpath.
+ 	 */
+-	spin_lock(&current->mm->page_table_lock);
+-	page = follow_page(mm, uaddr, 0);
++	page = follow_page(mm, uaddr, FOLL_TOUCH|FOLL_GET);
+ 	if (likely(page != NULL)) {
+ 		key->shared.pgoff =
+ 			page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+-		spin_unlock(&current->mm->page_table_lock);
++		put_page(page);
+ 		return 0;
+ 	}
+-	spin_unlock(&current->mm->page_table_lock);
+ 
+ 	/*
+ 	 * Do it the general way.
+diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
+--- a/kernel/irq/handle.c
++++ b/kernel/irq/handle.c
+@@ -117,14 +117,16 @@ fastcall unsigned int __do_IRQ(unsigned 
+ 		/*
+ 		 * No locking required for CPU-local interrupts:
+ 		 */
+-		desc->handler->ack(irq);
++		if (desc->handler->ack)
++			desc->handler->ack(irq);
+ 		action_ret = handle_IRQ_event(irq, regs, desc->action);
+ 		desc->handler->end(irq);
+ 		return 1;
+ 	}
+ 
+ 	spin_lock(&desc->lock);
+-	desc->handler->ack(irq);
++	if (desc->handler->ack)
++		desc->handler->ack(irq);
+ 	/*
+ 	 * REPLAY is when Linux resends an IRQ that was dropped earlier
+ 	 * WAITING is used by probe to mark irqs that are being tested
+diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
+--- a/kernel/kallsyms.c
++++ b/kernel/kallsyms.c
+@@ -18,6 +18,7 @@
+ #include <linux/fs.h>
+ #include <linux/err.h>
+ #include <linux/proc_fs.h>
++#include <linux/sched.h>	/* for cond_resched */
+ #include <linux/mm.h>
+ 
+ #include <asm/sections.h>
+diff --git a/kernel/kexec.c b/kernel/kexec.c
+--- a/kernel/kexec.c
++++ b/kernel/kexec.c
+@@ -90,7 +90,7 @@ int kexec_should_crash(struct task_struc
+ static int kimage_is_destination_range(struct kimage *image,
+ 				       unsigned long start, unsigned long end);
+ static struct page *kimage_alloc_page(struct kimage *image,
+-				       unsigned int gfp_mask,
++				       gfp_t gfp_mask,
+ 				       unsigned long dest);
+ 
+ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
+@@ -326,8 +326,7 @@ static int kimage_is_destination_range(s
+ 	return 0;
+ }
+ 
+-static struct page *kimage_alloc_pages(unsigned int gfp_mask,
+-					unsigned int order)
++static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order)
+ {
+ 	struct page *pages;
+ 
+@@ -335,7 +334,7 @@ static struct page *kimage_alloc_pages(u
+ 	if (pages) {
+ 		unsigned int count, i;
+ 		pages->mapping = NULL;
+-		pages->private = order;
++		set_page_private(pages, order);
+ 		count = 1 << order;
+ 		for (i = 0; i < count; i++)
+ 			SetPageReserved(pages + i);
+@@ -348,7 +347,7 @@ static void kimage_free_pages(struct pag
+ {
+ 	unsigned int order, count, i;
+ 
+-	order = page->private;
++	order = page_private(page);
+ 	count = 1 << order;
+ 	for (i = 0; i < count; i++)
+ 		ClearPageReserved(page + i);
+@@ -654,7 +653,7 @@ static kimage_entry_t *kimage_dst_used(s
+ }
+ 
+ static struct page *kimage_alloc_page(struct kimage *image,
+-					unsigned int gfp_mask,
++					gfp_t gfp_mask,
+ 					unsigned long destination)
+ {
+ 	/*
+diff --git a/kernel/kmod.c b/kernel/kmod.c
+--- a/kernel/kmod.c
++++ b/kernel/kmod.c
+@@ -131,14 +131,14 @@ struct subprocess_info {
+ static int ____call_usermodehelper(void *data)
+ {
+ 	struct subprocess_info *sub_info = data;
+-	struct key *old_session;
++	struct key *new_session, *old_session;
+ 	int retval;
+ 
+ 	/* Unblock all signals and set the session keyring. */
+-	key_get(sub_info->ring);
++	new_session = key_get(sub_info->ring);
+ 	flush_signals(current);
+ 	spin_lock_irq(&current->sighand->siglock);
+-	old_session = __install_session_keyring(current, sub_info->ring);
++	old_session = __install_session_keyring(current, new_session);
+ 	flush_signal_handlers(current, 1);
+ 	sigemptyset(&current->blocked);
+ 	recalc_sigpending();
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -35,6 +35,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/hash.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ #include <linux/module.h>
+ #include <linux/moduleloader.h>
+ #include <asm-generic/sections.h>
+diff --git a/kernel/kthread.c b/kernel/kthread.c
+--- a/kernel/kthread.c
++++ b/kernel/kthread.c
+@@ -165,6 +165,12 @@ EXPORT_SYMBOL(kthread_bind);
+ 
+ int kthread_stop(struct task_struct *k)
+ {
++	return kthread_stop_sem(k, NULL);
++}
++EXPORT_SYMBOL(kthread_stop);
++
++int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
++{
+ 	int ret;
+ 
+ 	down(&kthread_stop_lock);
+@@ -178,7 +184,10 @@ int kthread_stop(struct task_struct *k)
+ 
+ 	/* Now set kthread_should_stop() to true, and wake it up. */
+ 	kthread_stop_info.k = k;
+-	wake_up_process(k);
++	if (s)
++		up(s);
++	else
++		wake_up_process(k);
+ 	put_task_struct(k);
+ 
+ 	/* Once it dies, reset stop ptr, gather result and we're done. */
+@@ -189,7 +198,7 @@ int kthread_stop(struct task_struct *k)
+ 
+ 	return ret;
+ }
+-EXPORT_SYMBOL(kthread_stop);
++EXPORT_SYMBOL(kthread_stop_sem);
+ 
+ static __init int helper_init(void)
+ {
+diff --git a/kernel/params.c b/kernel/params.c
+--- a/kernel/params.c
++++ b/kernel/params.c
+@@ -23,6 +23,7 @@
+ #include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/err.h>
++#include <linux/slab.h>
+ 
+ #if 0
+ #define DEBUGP printk
+diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
+--- a/kernel/posix-cpu-timers.c
++++ b/kernel/posix-cpu-timers.c
+@@ -1225,7 +1225,7 @@ void posix_cpu_timer_schedule(struct k_i
+ 		/*
+ 		 * The task was cleaned up already, no future firings.
+ 		 */
+-		return;
++		goto out;
+ 
+ 	/*
+ 	 * Fetch the current sample and update the timer's expiry time.
+@@ -1235,7 +1235,7 @@ void posix_cpu_timer_schedule(struct k_i
+ 		bump_cpu_timer(timer, now);
+ 		if (unlikely(p->exit_state)) {
+ 			clear_dead_task(timer, now);
+-			return;
++			goto out;
+ 		}
+ 		read_lock(&tasklist_lock); /* arm_timer needs it.  */
+ 	} else {
+@@ -1248,8 +1248,7 @@ void posix_cpu_timer_schedule(struct k_i
+ 			put_task_struct(p);
+ 			timer->it.cpu.task = p = NULL;
+ 			timer->it.cpu.expires.sched = 0;
+-			read_unlock(&tasklist_lock);
+-			return;
++			goto out_unlock;
+ 		} else if (unlikely(p->exit_state) && thread_group_empty(p)) {
+ 			/*
+ 			 * We've noticed that the thread is dead, but
+@@ -1257,8 +1256,7 @@ void posix_cpu_timer_schedule(struct k_i
+ 			 * drop our task ref.
+ 			 */
+ 			clear_dead_task(timer, now);
+-			read_unlock(&tasklist_lock);
+-			return;
++			goto out_unlock;
+ 		}
+ 		cpu_clock_sample_group(timer->it_clock, p, &now);
+ 		bump_cpu_timer(timer, now);
+@@ -1270,7 +1268,13 @@ void posix_cpu_timer_schedule(struct k_i
+ 	 */
+ 	arm_timer(timer, now);
+ 
++out_unlock:
+ 	read_unlock(&tasklist_lock);
++
++out:
++	timer->it_overrun_last = timer->it_overrun;
++	timer->it_overrun = -1;
++	++timer->it_requeue_pending;
+ }
+ 
+ /*
+diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
+--- a/kernel/posix-timers.c
++++ b/kernel/posix-timers.c
+@@ -1295,13 +1295,6 @@ sys_clock_getres(clockid_t which_clock, 
+ 	return error;
+ }
+ 
+-static void nanosleep_wake_up(unsigned long __data)
+-{
+-	struct task_struct *p = (struct task_struct *) __data;
+-
+-	wake_up_process(p);
+-}
+-
+ /*
+  * The standard says that an absolute nanosleep call MUST wake up at
+  * the requested time in spite of clock settings.  Here is what we do:
+@@ -1442,7 +1435,6 @@ static int common_nsleep(clockid_t which
+ 			 int flags, struct timespec *tsave)
+ {
+ 	struct timespec t, dum;
+-	struct timer_list new_timer;
+ 	DECLARE_WAITQUEUE(abs_wqueue, current);
+ 	u64 rq_time = (u64)0;
+ 	s64 left;
+@@ -1451,10 +1443,6 @@ static int common_nsleep(clockid_t which
+ 	    &current_thread_info()->restart_block;
+ 
+ 	abs_wqueue.flags = 0;
+-	init_timer(&new_timer);
+-	new_timer.expires = 0;
+-	new_timer.data = (unsigned long) current;
+-	new_timer.function = nanosleep_wake_up;
+ 	abs = flags & TIMER_ABSTIME;
+ 
+ 	if (restart_block->fn == clock_nanosleep_restart) {
+@@ -1490,13 +1478,8 @@ static int common_nsleep(clockid_t which
+ 		if (left < (s64)0)
+ 			break;
+ 
+-		new_timer.expires = jiffies + left;
+-		__set_current_state(TASK_INTERRUPTIBLE);
+-		add_timer(&new_timer);
+-
+-		schedule();
++		schedule_timeout_interruptible(left);
+ 
+-		del_timer_sync(&new_timer);
+ 		left = rq_time - get_jiffies_64();
+ 	} while (left > (s64)0 && !test_thread_flag(TIF_SIGPENDING));
+ 
+diff --git a/kernel/power/Makefile b/kernel/power/Makefile
+--- a/kernel/power/Makefile
++++ b/kernel/power/Makefile
+@@ -4,7 +4,7 @@ EXTRA_CFLAGS	+=	-DDEBUG
+ endif
+ 
+ obj-y				:= main.o process.o console.o pm.o
+-obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o disk.o
++obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o disk.o snapshot.o
+ 
+ obj-$(CONFIG_SUSPEND_SMP)	+= smp.o
+ 
+diff --git a/kernel/power/disk.c b/kernel/power/disk.c
+--- a/kernel/power/disk.c
++++ b/kernel/power/disk.c
+@@ -30,7 +30,6 @@ extern int swsusp_check(void);
+ extern int swsusp_read(void);
+ extern void swsusp_close(void);
+ extern int swsusp_resume(void);
+-extern int swsusp_free(void);
+ 
+ 
+ static int noresume = 0;
+@@ -93,10 +92,7 @@ static void free_some_memory(void)
+ 	printk("Freeing memory...  ");
+ 	while ((tmp = shrink_all_memory(10000))) {
+ 		pages += tmp;
+-		printk("\b%c", p[i]);
+-		i++;
+-		if (i > 3)
+-			i = 0;
++		printk("\b%c", p[i++ % 4]);
+ 	}
+ 	printk("\bdone (%li pages freed)\n", pages);
+ }
+@@ -178,13 +174,12 @@ int pm_suspend_disk(void)
+ 		goto Done;
+ 
+ 	if (in_suspend) {
++		device_resume();
+ 		pr_debug("PM: writing image.\n");
+ 		error = swsusp_write();
+ 		if (!error)
+ 			power_down(pm_disk_mode);
+ 		else {
+-		/* swsusp_write can not fail in device_resume,
+-		   no need to do second device_resume */
+ 			swsusp_free();
+ 			unprepare_processes();
+ 			return error;
+@@ -252,14 +247,17 @@ static int software_resume(void)
+ 
+ 	pr_debug("PM: Reading swsusp image.\n");
+ 
+-	if ((error = swsusp_read()))
+-		goto Cleanup;
++	if ((error = swsusp_read())) {
++		swsusp_free();
++		goto Thaw;
++	}
+ 
+ 	pr_debug("PM: Preparing devices for restore.\n");
+ 
+ 	if ((error = device_suspend(PMSG_FREEZE))) {
+ 		printk("Some devices failed to suspend\n");
+-		goto Free;
++		swsusp_free();
++		goto Thaw;
+ 	}
+ 
+ 	mb();
+@@ -268,9 +266,7 @@ static int software_resume(void)
+ 	swsusp_resume();
+ 	pr_debug("PM: Restore failed, recovering.n");
+ 	device_resume();
+- Free:
+-	swsusp_free();
+- Cleanup:
++ Thaw:
+ 	unprepare_processes();
+  Done:
+ 	/* For success case, the suspend path will release the lock */
+diff --git a/kernel/power/main.c b/kernel/power/main.c
+--- a/kernel/power/main.c
++++ b/kernel/power/main.c
+@@ -167,6 +167,8 @@ static int enter_state(suspend_state_t s
+ {
+ 	int error;
+ 
++	if (pm_ops->valid && !pm_ops->valid(state))
++		return -ENODEV;
+ 	if (down_trylock(&pm_sem))
+ 		return -EBUSY;
+ 
+@@ -236,7 +238,8 @@ static ssize_t state_show(struct subsyst
+ 	char * s = buf;
+ 
+ 	for (i = 0; i < PM_SUSPEND_MAX; i++) {
+-		if (pm_states[i])
++		if (pm_states[i] && pm_ops && (!pm_ops->valid
++			||(pm_ops->valid && pm_ops->valid(i))))
+ 			s += sprintf(s,"%s ",pm_states[i]);
+ 	}
+ 	s += sprintf(s,"\n");
+diff --git a/kernel/power/power.h b/kernel/power/power.h
+--- a/kernel/power/power.h
++++ b/kernel/power/power.h
+@@ -53,3 +53,20 @@ extern void thaw_processes(void);
+ 
+ extern int pm_prepare_console(void);
+ extern void pm_restore_console(void);
++
++
++/* References to section boundaries */
++extern const void __nosave_begin, __nosave_end;
++
++extern unsigned int nr_copy_pages;
++extern suspend_pagedir_t *pagedir_nosave;
++extern suspend_pagedir_t *pagedir_save;
++
++extern asmlinkage int swsusp_arch_suspend(void);
++extern asmlinkage int swsusp_arch_resume(void);
++
++extern int restore_highmem(void);
++extern struct pbe * alloc_pagedir(unsigned nr_pages);
++extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages);
++extern void swsusp_free(void);
++extern int enough_swap(unsigned nr_pages);
+diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
+new file mode 100644
+--- /dev/null
++++ b/kernel/power/snapshot.c
+@@ -0,0 +1,435 @@
++/*
++ * linux/kernel/power/snapshot.c
++ *
++ * This file provide system snapshot/restore functionality.
++ *
++ * Copyright (C) 1998-2005 Pavel Machek <pavel at suse.cz>
++ *
++ * This file is released under the GPLv2, and is based on swsusp.c.
++ *
++ */
++
++
++#include <linux/module.h>
++#include <linux/mm.h>
++#include <linux/suspend.h>
++#include <linux/smp_lock.h>
++#include <linux/delay.h>
++#include <linux/bitops.h>
++#include <linux/spinlock.h>
++#include <linux/kernel.h>
++#include <linux/pm.h>
++#include <linux/device.h>
++#include <linux/bootmem.h>
++#include <linux/syscalls.h>
++#include <linux/console.h>
++#include <linux/highmem.h>
++
++#include <asm/uaccess.h>
++#include <asm/mmu_context.h>
++#include <asm/pgtable.h>
++#include <asm/tlbflush.h>
++#include <asm/io.h>
++
++#include "power.h"
++
++#ifdef CONFIG_HIGHMEM
++struct highmem_page {
++	char *data;
++	struct page *page;
++	struct highmem_page *next;
++};
++
++static struct highmem_page *highmem_copy;
++
++static int save_highmem_zone(struct zone *zone)
++{
++	unsigned long zone_pfn;
++	mark_free_pages(zone);
++	for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
++		struct page *page;
++		struct highmem_page *save;
++		void *kaddr;
++		unsigned long pfn = zone_pfn + zone->zone_start_pfn;
++
++		if (!(pfn%1000))
++			printk(".");
++		if (!pfn_valid(pfn))
++			continue;
++		page = pfn_to_page(pfn);
++		/*
++		 * This condition results from rvmalloc() sans vmalloc_32()
++		 * and architectural memory reservations. This should be
++		 * corrected eventually when the cases giving rise to this
++		 * are better understood.
++		 */
++		if (PageReserved(page)) {
++			printk("highmem reserved page?!\n");
++			continue;
++		}
++		BUG_ON(PageNosave(page));
++		if (PageNosaveFree(page))
++			continue;
++		save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
++		if (!save)
++			return -ENOMEM;
++		save->next = highmem_copy;
++		save->page = page;
++		save->data = (void *) get_zeroed_page(GFP_ATOMIC);
++		if (!save->data) {
++			kfree(save);
++			return -ENOMEM;
++		}
++		kaddr = kmap_atomic(page, KM_USER0);
++		memcpy(save->data, kaddr, PAGE_SIZE);
++		kunmap_atomic(kaddr, KM_USER0);
++		highmem_copy = save;
++	}
++	return 0;
++}
++
++
++static int save_highmem(void)
++{
++	struct zone *zone;
++	int res = 0;
++
++	pr_debug("swsusp: Saving Highmem\n");
++	for_each_zone (zone) {
++		if (is_highmem(zone))
++			res = save_highmem_zone(zone);
++		if (res)
++			return res;
++	}
++	return 0;
++}
++
++int restore_highmem(void)
++{
++	printk("swsusp: Restoring Highmem\n");
++	while (highmem_copy) {
++		struct highmem_page *save = highmem_copy;
++		void *kaddr;
++		highmem_copy = save->next;
++
++		kaddr = kmap_atomic(save->page, KM_USER0);
++		memcpy(kaddr, save->data, PAGE_SIZE);
++		kunmap_atomic(kaddr, KM_USER0);
++		free_page((long) save->data);
++		kfree(save);
++	}
++	return 0;
++}
++#else
++static int save_highmem(void) { return 0; }
++int restore_highmem(void) { return 0; }
++#endif /* CONFIG_HIGHMEM */
++
++
++static int pfn_is_nosave(unsigned long pfn)
++{
++	unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
++	unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
++	return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
++}
++
++/**
++ *	saveable - Determine whether a page should be cloned or not.
++ *	@pfn:	The page
++ *
++ *	We save a page if it's Reserved, and not in the range of pages
++ *	statically defined as 'unsaveable', or if it isn't reserved, and
++ *	isn't part of a free chunk of pages.
++ */
++
++static int saveable(struct zone *zone, unsigned long *zone_pfn)
++{
++	unsigned long pfn = *zone_pfn + zone->zone_start_pfn;
++	struct page *page;
++
++	if (!pfn_valid(pfn))
++		return 0;
++
++	page = pfn_to_page(pfn);
++	BUG_ON(PageReserved(page) && PageNosave(page));
++	if (PageNosave(page))
++		return 0;
++	if (PageReserved(page) && pfn_is_nosave(pfn)) {
++		pr_debug("[nosave pfn 0x%lx]", pfn);
++		return 0;
++	}
++	if (PageNosaveFree(page))
++		return 0;
++
++	return 1;
++}
++
++static unsigned count_data_pages(void)
++{
++	struct zone *zone;
++	unsigned long zone_pfn;
++	unsigned n;
++
++	n = 0;
++	for_each_zone (zone) {
++		if (is_highmem(zone))
++			continue;
++		mark_free_pages(zone);
++		for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
++			n += saveable(zone, &zone_pfn);
++	}
++	return n;
++}
++
++static void copy_data_pages(struct pbe *pblist)
++{
++	struct zone *zone;
++	unsigned long zone_pfn;
++	struct pbe *pbe, *p;
++
++	pbe = pblist;
++	for_each_zone (zone) {
++		if (is_highmem(zone))
++			continue;
++		mark_free_pages(zone);
++		/* This is necessary for swsusp_free() */
++		for_each_pb_page (p, pblist)
++			SetPageNosaveFree(virt_to_page(p));
++		for_each_pbe (p, pblist)
++			SetPageNosaveFree(virt_to_page(p->address));
++		for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
++			if (saveable(zone, &zone_pfn)) {
++				struct page *page;
++				page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
++				BUG_ON(!pbe);
++				pbe->orig_address = (unsigned long)page_address(page);
++				/* copy_page is not usable for copying task structs. */
++				memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
++				pbe = pbe->next;
++			}
++		}
++	}
++	BUG_ON(pbe);
++}
++
++
++/**
++ *	free_pagedir - free pages allocated with alloc_pagedir()
++ */
++
++static void free_pagedir(struct pbe *pblist)
++{
++	struct pbe *pbe;
++
++	while (pblist) {
++		pbe = (pblist + PB_PAGE_SKIP)->next;
++		ClearPageNosave(virt_to_page(pblist));
++		ClearPageNosaveFree(virt_to_page(pblist));
++		free_page((unsigned long)pblist);
++		pblist = pbe;
++	}
++}
++
++/**
++ *	fill_pb_page - Create a list of PBEs on a given memory page
++ */
++
++static inline void fill_pb_page(struct pbe *pbpage)
++{
++	struct pbe *p;
++
++	p = pbpage;
++	pbpage += PB_PAGE_SKIP;
++	do
++		p->next = p + 1;
++	while (++p < pbpage);
++}
++
++/**
++ *	create_pbe_list - Create a list of PBEs on top of a given chain
++ *	of memory pages allocated with alloc_pagedir()
++ */
++
++void create_pbe_list(struct pbe *pblist, unsigned nr_pages)
++{
++	struct pbe *pbpage, *p;
++	unsigned num = PBES_PER_PAGE;
++
++	for_each_pb_page (pbpage, pblist) {
++		if (num >= nr_pages)
++			break;
++
++		fill_pb_page(pbpage);
++		num += PBES_PER_PAGE;
++	}
++	if (pbpage) {
++		for (num -= PBES_PER_PAGE - 1, p = pbpage; num < nr_pages; p++, num++)
++			p->next = p + 1;
++		p->next = NULL;
++	}
++	pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
++}
++
++static void *alloc_image_page(void)
++{
++	void *res = (void *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
++	if (res) {
++		SetPageNosave(virt_to_page(res));
++		SetPageNosaveFree(virt_to_page(res));
++	}
++	return res;
++}
++
++/**
++ *	alloc_pagedir - Allocate the page directory.
++ *
++ *	First, determine exactly how many pages we need and
++ *	allocate them.
++ *
++ *	We arrange the pages in a chain: each page is an array of PBES_PER_PAGE
++ *	struct pbe elements (pbes) and the last element in the page points
++ *	to the next page.
++ *
++ *	On each page we set up a list of struct_pbe elements.
++ */
++
++struct pbe *alloc_pagedir(unsigned nr_pages)
++{
++	unsigned num;
++	struct pbe *pblist, *pbe;
++
++	if (!nr_pages)
++		return NULL;
++
++	pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
++	pblist = alloc_image_page();
++	/* FIXME: rewrite this ugly loop */
++	for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
++        		pbe = pbe->next, num += PBES_PER_PAGE) {
++		pbe += PB_PAGE_SKIP;
++		pbe->next = alloc_image_page();
++	}
++	if (!pbe) { /* get_zeroed_page() failed */
++		free_pagedir(pblist);
++		pblist = NULL;
++        }
++	return pblist;
++}
++
++/**
++ * Free pages we allocated for suspend. Suspend pages are alocated
++ * before atomic copy, so we need to free them after resume.
++ */
++
++void swsusp_free(void)
++{
++	struct zone *zone;
++	unsigned long zone_pfn;
++
++	for_each_zone(zone) {
++		for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
++			if (pfn_valid(zone_pfn + zone->zone_start_pfn)) {
++				struct page * page;
++				page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
++				if (PageNosave(page) && PageNosaveFree(page)) {
++					ClearPageNosave(page);
++					ClearPageNosaveFree(page);
++					free_page((long) page_address(page));
++				}
++			}
++	}
++}
++
++
++/**
++ *	enough_free_mem - Make sure we enough free memory to snapshot.
++ *
++ *	Returns TRUE or FALSE after checking the number of available
++ *	free pages.
++ */
++
++static int enough_free_mem(unsigned nr_pages)
++{
++	pr_debug("swsusp: available memory: %u pages\n", nr_free_pages());
++	return nr_free_pages() > (nr_pages + PAGES_FOR_IO +
++		(nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
++}
++
++
++static struct pbe *swsusp_alloc(unsigned nr_pages)
++{
++	struct pbe *pblist, *p;
++
++	if (!(pblist = alloc_pagedir(nr_pages))) {
++		printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
++		return NULL;
++	}
++	create_pbe_list(pblist, nr_pages);
++
++	for_each_pbe (p, pblist) {
++		p->address = (unsigned long)alloc_image_page();
++		if (!p->address) {
++			printk(KERN_ERR "suspend: Allocating image pages failed.\n");
++			swsusp_free();
++			return NULL;
++		}
++	}
++
++	return pblist;
++}
++
++asmlinkage int swsusp_save(void)
++{
++	unsigned nr_pages;
++
++	pr_debug("swsusp: critical section: \n");
++	if (save_highmem()) {
++		printk(KERN_CRIT "swsusp: Not enough free pages for highmem\n");
++		restore_highmem();
++		return -ENOMEM;
++	}
++
++	drain_local_pages();
++	nr_pages = count_data_pages();
++	printk("swsusp: Need to copy %u pages\n", nr_pages);
++
++	pr_debug("swsusp: pages needed: %u + %lu + %u, free: %u\n",
++		 nr_pages,
++		 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE,
++		 PAGES_FOR_IO, nr_free_pages());
++
++	/* This is needed because of the fixed size of swsusp_info */
++	if (MAX_PBES < (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE)
++		return -ENOSPC;
++
++	if (!enough_free_mem(nr_pages)) {
++		printk(KERN_ERR "swsusp: Not enough free memory\n");
++		return -ENOMEM;
++	}
++
++	if (!enough_swap(nr_pages)) {
++		printk(KERN_ERR "swsusp: Not enough free swap\n");
++		return -ENOSPC;
++	}
++
++	pagedir_nosave = swsusp_alloc(nr_pages);
++	if (!pagedir_nosave)
++		return -ENOMEM;
++
++	/* During allocating of suspend pagedir, new cold pages may appear.
++	 * Kill them.
++	 */
++	drain_local_pages();
++	copy_data_pages(pagedir_nosave);
++
++	/*
++	 * End of critical section. From now on, we can write to memory,
++	 * but we should not touch disk. This specially means we must _not_
++	 * touch swap space! Except we must write out our image of course.
++	 */
++
++	nr_copy_pages = nr_pages;
++
++	printk("swsusp: critical section/: done (%d pages copied)\n", nr_pages);
++	return 0;
++}
+diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
+--- a/kernel/power/swsusp.c
++++ b/kernel/power/swsusp.c
+@@ -1,11 +1,10 @@
+ /*
+  * linux/kernel/power/swsusp.c
+  *
+- * This file is to realize architecture-independent
+- * machine suspend feature using pretty near only high-level routines
++ * This file provides code to write suspend image to swap and read it back.
+  *
+  * Copyright (C) 1998-2001 Gabor Kuti <seasons at fornax.hu>
+- * Copyright (C) 1998,2001-2004 Pavel Machek <pavel at suse.cz>
++ * Copyright (C) 1998,2001-2005 Pavel Machek <pavel at suse.cz>
+  *
+  * This file is released under the GPLv2.
+  *
+@@ -47,11 +46,7 @@
+ #include <linux/utsname.h>
+ #include <linux/version.h>
+ #include <linux/delay.h>
+-#include <linux/reboot.h>
+ #include <linux/bitops.h>
+-#include <linux/vt_kern.h>
+-#include <linux/kbd_kern.h>
+-#include <linux/keyboard.h>
+ #include <linux/spinlock.h>
+ #include <linux/genhd.h>
+ #include <linux/kernel.h>
+@@ -63,10 +58,8 @@
+ #include <linux/swapops.h>
+ #include <linux/bootmem.h>
+ #include <linux/syscalls.h>
+-#include <linux/console.h>
+ #include <linux/highmem.h>
+ #include <linux/bio.h>
+-#include <linux/mount.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/mmu_context.h>
+@@ -84,16 +77,10 @@
+ #define MAXKEY 32
+ #define MAXIV  32
+ 
+-/* References to section boundaries */
+-extern const void __nosave_begin, __nosave_end;
+-
+-/* Variables to be preserved over suspend */
+-static int nr_copy_pages_check;
+-
+ extern char resume_file[];
+ 
+ /* Local variables that should not be affected by save */
+-static unsigned int nr_copy_pages __nosavedata = 0;
++unsigned int nr_copy_pages __nosavedata = 0;
+ 
+ /* Suspend pagedir is allocated before final copy, therefore it
+    must be freed after resume
+@@ -109,7 +96,7 @@ static unsigned int nr_copy_pages __nosa
+    MMU hardware.
+  */
+ suspend_pagedir_t *pagedir_nosave __nosavedata = NULL;
+-static suspend_pagedir_t *pagedir_save;
++suspend_pagedir_t *pagedir_save;
+ 
+ #define SWSUSP_SIG	"S1SUSPEND"
+ 
+@@ -124,12 +111,6 @@ static struct swsusp_header {
+ static struct swsusp_info swsusp_info;
+ 
+ /*
+- * XXX: We try to keep some more pages free so that I/O operations succeed
+- * without paging. Might this be more?
+- */
+-#define PAGES_FOR_IO	512
+-
+-/*
+  * Saving part...
+  */
+ 
+@@ -552,346 +533,6 @@ static int write_suspend_image(void)
+ 	goto Done;
+ }
+ 
+-
+-#ifdef CONFIG_HIGHMEM
+-struct highmem_page {
+-	char *data;
+-	struct page *page;
+-	struct highmem_page *next;
+-};
+-
+-static struct highmem_page *highmem_copy;
+-
+-static int save_highmem_zone(struct zone *zone)
+-{
+-	unsigned long zone_pfn;
+-	mark_free_pages(zone);
+-	for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
+-		struct page *page;
+-		struct highmem_page *save;
+-		void *kaddr;
+-		unsigned long pfn = zone_pfn + zone->zone_start_pfn;
+-
+-		if (!(pfn%1000))
+-			printk(".");
+-		if (!pfn_valid(pfn))
+-			continue;
+-		page = pfn_to_page(pfn);
+-		/*
+-		 * This condition results from rvmalloc() sans vmalloc_32()
+-		 * and architectural memory reservations. This should be
+-		 * corrected eventually when the cases giving rise to this
+-		 * are better understood.
+-		 */
+-		if (PageReserved(page)) {
+-			printk("highmem reserved page?!\n");
+-			continue;
+-		}
+-		BUG_ON(PageNosave(page));
+-		if (PageNosaveFree(page))
+-			continue;
+-		save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
+-		if (!save)
+-			return -ENOMEM;
+-		save->next = highmem_copy;
+-		save->page = page;
+-		save->data = (void *) get_zeroed_page(GFP_ATOMIC);
+-		if (!save->data) {
+-			kfree(save);
+-			return -ENOMEM;
+-		}
+-		kaddr = kmap_atomic(page, KM_USER0);
+-		memcpy(save->data, kaddr, PAGE_SIZE);
+-		kunmap_atomic(kaddr, KM_USER0);
+-		highmem_copy = save;
+-	}
+-	return 0;
+-}
+-#endif /* CONFIG_HIGHMEM */
+-
+-
+-static int save_highmem(void)
+-{
+-#ifdef CONFIG_HIGHMEM
+-	struct zone *zone;
+-	int res = 0;
+-
+-	pr_debug("swsusp: Saving Highmem\n");
+-	for_each_zone (zone) {
+-		if (is_highmem(zone))
+-			res = save_highmem_zone(zone);
+-		if (res)
+-			return res;
+-	}
+-#endif
+-	return 0;
+-}
+-
+-static int restore_highmem(void)
+-{
+-#ifdef CONFIG_HIGHMEM
+-	printk("swsusp: Restoring Highmem\n");
+-	while (highmem_copy) {
+-		struct highmem_page *save = highmem_copy;
+-		void *kaddr;
+-		highmem_copy = save->next;
+-
+-		kaddr = kmap_atomic(save->page, KM_USER0);
+-		memcpy(kaddr, save->data, PAGE_SIZE);
+-		kunmap_atomic(kaddr, KM_USER0);
+-		free_page((long) save->data);
+-		kfree(save);
+-	}
+-#endif
+-	return 0;
+-}
+-
+-
+-static int pfn_is_nosave(unsigned long pfn)
+-{
+-	unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
+-	unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
+-	return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
+-}
+-
+-/**
+- *	saveable - Determine whether a page should be cloned or not.
+- *	@pfn:	The page
+- *
+- *	We save a page if it's Reserved, and not in the range of pages
+- *	statically defined as 'unsaveable', or if it isn't reserved, and
+- *	isn't part of a free chunk of pages.
+- */
+-
+-static int saveable(struct zone * zone, unsigned long * zone_pfn)
+-{
+-	unsigned long pfn = *zone_pfn + zone->zone_start_pfn;
+-	struct page * page;
+-
+-	if (!pfn_valid(pfn))
+-		return 0;
+-
+-	page = pfn_to_page(pfn);
+-	BUG_ON(PageReserved(page) && PageNosave(page));
+-	if (PageNosave(page))
+-		return 0;
+-	if (PageReserved(page) && pfn_is_nosave(pfn)) {
+-		pr_debug("[nosave pfn 0x%lx]", pfn);
+-		return 0;
+-	}
+-	if (PageNosaveFree(page))
+-		return 0;
+-
+-	return 1;
+-}
+-
+-static void count_data_pages(void)
+-{
+-	struct zone *zone;
+-	unsigned long zone_pfn;
+-
+-	nr_copy_pages = 0;
+-
+-	for_each_zone (zone) {
+-		if (is_highmem(zone))
+-			continue;
+-		mark_free_pages(zone);
+-		for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+-			nr_copy_pages += saveable(zone, &zone_pfn);
+-	}
+-}
+-
+-
+-static void copy_data_pages(void)
+-{
+-	struct zone *zone;
+-	unsigned long zone_pfn;
+-	struct pbe * pbe = pagedir_nosave;
+-
+-	pr_debug("copy_data_pages(): pages to copy: %d\n", nr_copy_pages);
+-	for_each_zone (zone) {
+-		if (is_highmem(zone))
+-			continue;
+-		mark_free_pages(zone);
+-		for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
+-			if (saveable(zone, &zone_pfn)) {
+-				struct page * page;
+-				page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
+-				BUG_ON(!pbe);
+-				pbe->orig_address = (long) page_address(page);
+-				/* copy_page is not usable for copying task structs. */
+-				memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
+-				pbe = pbe->next;
+-			}
+-		}
+-	}
+-	BUG_ON(pbe);
+-}
+-
+-
+-/**
+- *	calc_nr - Determine the number of pages needed for a pbe list.
+- */
+-
+-static int calc_nr(int nr_copy)
+-{
+-	return nr_copy + (nr_copy+PBES_PER_PAGE-2)/(PBES_PER_PAGE-1);
+-}
+-
+-/**
+- *	free_pagedir - free pages allocated with alloc_pagedir()
+- */
+-
+-static inline void free_pagedir(struct pbe *pblist)
+-{
+-	struct pbe *pbe;
+-
+-	while (pblist) {
+-		pbe = (pblist + PB_PAGE_SKIP)->next;
+-		free_page((unsigned long)pblist);
+-		pblist = pbe;
+-	}
+-}
+-
+-/**
+- *	fill_pb_page - Create a list of PBEs on a given memory page
+- */
+-
+-static inline void fill_pb_page(struct pbe *pbpage)
+-{
+-	struct pbe *p;
+-
+-	p = pbpage;
+-	pbpage += PB_PAGE_SKIP;
+-	do
+-		p->next = p + 1;
+-	while (++p < pbpage);
+-}
+-
+-/**
+- *	create_pbe_list - Create a list of PBEs on top of a given chain
+- *	of memory pages allocated with alloc_pagedir()
+- */
+-
+-static void create_pbe_list(struct pbe *pblist, unsigned nr_pages)
+-{
+-	struct pbe *pbpage, *p;
+-	unsigned num = PBES_PER_PAGE;
+-
+-	for_each_pb_page (pbpage, pblist) {
+-		if (num >= nr_pages)
+-			break;
+-
+-		fill_pb_page(pbpage);
+-		num += PBES_PER_PAGE;
+-	}
+-	if (pbpage) {
+-		for (num -= PBES_PER_PAGE - 1, p = pbpage; num < nr_pages; p++, num++)
+-			p->next = p + 1;
+-		p->next = NULL;
+-	}
+-	pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
+-}
+-
+-/**
+- *	alloc_pagedir - Allocate the page directory.
+- *
+- *	First, determine exactly how many pages we need and
+- *	allocate them.
+- *
+- *	We arrange the pages in a chain: each page is an array of PBES_PER_PAGE
+- *	struct pbe elements (pbes) and the last element in the page points
+- *	to the next page.
+- *
+- *	On each page we set up a list of struct_pbe elements.
+- */
+-
+-static struct pbe * alloc_pagedir(unsigned nr_pages)
+-{
+-	unsigned num;
+-	struct pbe *pblist, *pbe;
+-
+-	if (!nr_pages)
+-		return NULL;
+-
+-	pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
+-	pblist = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
+-	for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
+-        		pbe = pbe->next, num += PBES_PER_PAGE) {
+-		pbe += PB_PAGE_SKIP;
+-		pbe->next = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
+-	}
+-	if (!pbe) { /* get_zeroed_page() failed */
+-		free_pagedir(pblist);
+-		pblist = NULL;
+-        }
+-	return pblist;
+-}
+-
+-/**
+- *	free_image_pages - Free pages allocated for snapshot
+- */
+-
+-static void free_image_pages(void)
+-{
+-	struct pbe * p;
+-
+-	for_each_pbe (p, pagedir_save) {
+-		if (p->address) {
+-			ClearPageNosave(virt_to_page(p->address));
+-			free_page(p->address);
+-			p->address = 0;
+-		}
+-	}
+-}
+-
+-/**
+- *	alloc_image_pages - Allocate pages for the snapshot.
+- */
+-
+-static int alloc_image_pages(void)
+-{
+-	struct pbe * p;
+-
+-	for_each_pbe (p, pagedir_save) {
+-		p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
+-		if (!p->address)
+-			return -ENOMEM;
+-		SetPageNosave(virt_to_page(p->address));
+-	}
+-	return 0;
+-}
+-
+-/* Free pages we allocated for suspend. Suspend pages are alocated
+- * before atomic copy, so we need to free them after resume.
+- */
+-void swsusp_free(void)
+-{
+-	BUG_ON(PageNosave(virt_to_page(pagedir_save)));
+-	BUG_ON(PageNosaveFree(virt_to_page(pagedir_save)));
+-	free_image_pages();
+-	free_pagedir(pagedir_save);
+-}
+-
+-
+-/**
+- *	enough_free_mem - Make sure we enough free memory to snapshot.
+- *
+- *	Returns TRUE or FALSE after checking the number of available
+- *	free pages.
+- */
+-
+-static int enough_free_mem(void)
+-{
+-	if (nr_free_pages() < (nr_copy_pages + PAGES_FOR_IO)) {
+-		pr_debug("swsusp: Not enough free pages: Have %d\n",
+-			 nr_free_pages());
+-		return 0;
+-	}
+-	return 1;
+-}
+-
+-
+ /**
+  *	enough_swap - Make sure we have enough swap to save the image.
+  *
+@@ -902,87 +543,14 @@ static int enough_free_mem(void)
+  *	We should only consider resume_device.
+  */
+ 
+-static int enough_swap(void)
++int enough_swap(unsigned nr_pages)
+ {
+ 	struct sysinfo i;
+ 
+ 	si_swapinfo(&i);
+-	if (i.freeswap < (nr_copy_pages + PAGES_FOR_IO))  {
+-		pr_debug("swsusp: Not enough swap. Need %ld\n",i.freeswap);
+-		return 0;
+-	}
+-	return 1;
+-}
+-
+-static int swsusp_alloc(void)
+-{
+-	int error;
+-
+-	pagedir_nosave = NULL;
+-	nr_copy_pages = calc_nr(nr_copy_pages);
+-	nr_copy_pages_check = nr_copy_pages;
+-
+-	pr_debug("suspend: (pages needed: %d + %d free: %d)\n",
+-		 nr_copy_pages, PAGES_FOR_IO, nr_free_pages());
+-
+-	if (!enough_free_mem())
+-		return -ENOMEM;
+-
+-	if (!enough_swap())
+-		return -ENOSPC;
+-
+-	if (MAX_PBES < nr_copy_pages / PBES_PER_PAGE +
+-	    !!(nr_copy_pages % PBES_PER_PAGE))
+-		return -ENOSPC;
+-
+-	if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) {
+-		printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
+-		return -ENOMEM;
+-	}
+-	create_pbe_list(pagedir_save, nr_copy_pages);
+-	pagedir_nosave = pagedir_save;
+-	if ((error = alloc_image_pages())) {
+-		printk(KERN_ERR "suspend: Allocating image pages failed.\n");
+-		swsusp_free();
+-		return error;
+-	}
+-
+-	return 0;
+-}
+-
+-static int suspend_prepare_image(void)
+-{
+-	int error;
+-
+-	pr_debug("swsusp: critical section: \n");
+-	if (save_highmem()) {
+-		printk(KERN_CRIT "Suspend machine: Not enough free pages for highmem\n");
+-		restore_highmem();
+-		return -ENOMEM;
+-	}
+-
+-	drain_local_pages();
+-	count_data_pages();
+-	printk("swsusp: Need to copy %u pages\n", nr_copy_pages);
+-
+-	error = swsusp_alloc();
+-	if (error)
+-		return error;
+-
+-	/* During allocating of suspend pagedir, new cold pages may appear.
+-	 * Kill them.
+-	 */
+-	drain_local_pages();
+-	copy_data_pages();
+-
+-	/*
+-	 * End of critical section. From now on, we can write to memory,
+-	 * but we should not touch disk. This specially means we must _not_
+-	 * touch swap space! Except we must write out our image of course.
+-	 */
+-
+-	printk("swsusp: critical section/: done (%d pages copied)\n", nr_copy_pages );
+-	return 0;
++	pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
++	return i.freeswap > (nr_pages + PAGES_FOR_IO +
++		(nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
+ }
+ 
+ 
+@@ -994,7 +562,7 @@ static int suspend_prepare_image(void)
+ int swsusp_write(void)
+ {
+ 	int error;
+-	device_resume();
++
+ 	lock_swapdevices();
+ 	error = write_suspend_image();
+ 	/* This will unlock ignored swap devices since writing is finished */
+@@ -1004,14 +572,6 @@ int swsusp_write(void)
+ }
+ 
+ 
+-extern asmlinkage int swsusp_arch_suspend(void);
+-extern asmlinkage int swsusp_arch_resume(void);
+-
+-
+-asmlinkage int swsusp_save(void)
+-{
+-	return suspend_prepare_image();
+-}
+ 
+ int swsusp_suspend(void)
+ {
+@@ -1043,7 +603,6 @@ int swsusp_suspend(void)
+ 		printk(KERN_ERR "Error %d suspending\n", error);
+ 	/* Restore control flow magically appears here */
+ 	restore_processor_state();
+-	BUG_ON (nr_copy_pages_check != nr_copy_pages);
+ 	restore_highmem();
+ 	device_power_up();
+ 	local_irq_enable();
+@@ -1063,6 +622,11 @@ int swsusp_resume(void)
+ 	 * execution continues at place where swsusp_arch_suspend was called
+          */
+ 	BUG_ON(!error);
++	/* The only reason why swsusp_arch_resume() can fail is memory being
++	 * very tight, so we have to free it as soon as we can to avoid
++	 * subsequent failures
++	 */
++	swsusp_free();
+ 	restore_processor_state();
+ 	restore_highmem();
+ 	touch_softlockup_watchdog();
+@@ -1078,54 +642,28 @@ int swsusp_resume(void)
+  *
+  *	We don't know which pages are usable until we allocate them.
+  *
+- *	Allocated but unusable (ie eaten) memory pages are linked together
+- *	to create a list, so that we can free them easily
+- *
+- *	We could have used a type other than (void *)
+- *	for this purpose, but ...
++ *	Allocated but unusable (ie eaten) memory pages are marked so that
++ *	swsusp_free() can release them
+  */
+-static void **eaten_memory = NULL;
+-
+-static inline void eat_page(void *page)
+-{
+-	void **c;
+-
+-	c = eaten_memory;
+-	eaten_memory = page;
+-	*eaten_memory = c;
+-}
+ 
+-unsigned long get_usable_page(unsigned gfp_mask)
++unsigned long get_safe_page(gfp_t gfp_mask)
+ {
+ 	unsigned long m;
+ 
+-	m = get_zeroed_page(gfp_mask);
+-	while (!PageNosaveFree(virt_to_page(m))) {
+-		eat_page((void *)m);
++	do {
+ 		m = get_zeroed_page(gfp_mask);
+-		if (!m)
+-			break;
++		if (m && PageNosaveFree(virt_to_page(m)))
++			/* This is for swsusp_free() */
++			SetPageNosave(virt_to_page(m));
++	} while (m && PageNosaveFree(virt_to_page(m)));
++	if (m) {
++		/* This is for swsusp_free() */
++		SetPageNosave(virt_to_page(m));
++		SetPageNosaveFree(virt_to_page(m));
+ 	}
+ 	return m;
+ }
+ 
+-void free_eaten_memory(void)
+-{
+-	unsigned long m;
+-	void **c;
+-	int i = 0;
+-
+-	c = eaten_memory;
+-	while (c) {
+-		m = (unsigned long)c;
+-		c = *c;
+-		free_page(m);
+-		i++;
+-	}
+-	eaten_memory = NULL;
+-	pr_debug("swsusp: %d unused pages freed\n", i);
+-}
+-
+ /**
+  *	check_pagedir - We ensure here that pages that the PBEs point to
+  *	won't collide with pages where we're going to restore from the loaded
+@@ -1143,7 +681,7 @@ static int check_pagedir(struct pbe *pbl
+ 		p->address = 0UL;
+ 
+ 	for_each_pbe (p, pblist) {
+-		p->address = get_usable_page(GFP_ATOMIC);
++		p->address = get_safe_page(GFP_ATOMIC);
+ 		if (!p->address)
+ 			return -ENOMEM;
+ 	}
+@@ -1162,7 +700,7 @@ static struct pbe * swsusp_pagedir_reloc
+ 	unsigned long zone_pfn;
+ 	struct pbe *pbpage, *tail, *p;
+ 	void *m;
+-	int rel = 0, error = 0;
++	int rel = 0;
+ 
+ 	if (!pblist) /* a sanity check */
+ 		return NULL;
+@@ -1170,41 +708,37 @@ static struct pbe * swsusp_pagedir_reloc
+ 	pr_debug("swsusp: Relocating pagedir (%lu pages to check)\n",
+ 			swsusp_info.pagedir_pages);
+ 
+-	/* Set page flags */
++	/* Clear page flags */
+ 
+ 	for_each_zone (zone) {
+         	for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+-                	SetPageNosaveFree(pfn_to_page(zone_pfn +
++        		if (pfn_valid(zone_pfn + zone->zone_start_pfn))
++                		ClearPageNosaveFree(pfn_to_page(zone_pfn +
+ 					zone->zone_start_pfn));
+ 	}
+ 
+-	/* Clear orig addresses */
++	/* Mark orig addresses */
+ 
+ 	for_each_pbe (p, pblist)
+-		ClearPageNosaveFree(virt_to_page(p->orig_address));
++		SetPageNosaveFree(virt_to_page(p->orig_address));
+ 
+ 	tail = pblist + PB_PAGE_SKIP;
+ 
+ 	/* Relocate colliding pages */
+ 
+ 	for_each_pb_page (pbpage, pblist) {
+-		if (!PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
+-			m = (void *)get_usable_page(GFP_ATOMIC | __GFP_COLD);
+-			if (!m) {
+-				error = -ENOMEM;
+-				break;
+-			}
++		if (PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
++			m = (void *)get_safe_page(GFP_ATOMIC | __GFP_COLD);
++			if (!m)
++				return NULL;
+ 			memcpy(m, (void *)pbpage, PAGE_SIZE);
+ 			if (pbpage == pblist)
+ 				pblist = (struct pbe *)m;
+ 			else
+ 				tail->next = (struct pbe *)m;
+-
+-			eat_page((void *)pbpage);
+ 			pbpage = (struct pbe *)m;
+ 
+ 			/* We have to link the PBEs again */
+-
+ 			for (p = pbpage; p < pbpage + PB_PAGE_SKIP; p++)
+ 				if (p->next) /* needed to save the end */
+ 					p->next = p + 1;
+@@ -1214,15 +748,13 @@ static struct pbe * swsusp_pagedir_reloc
+ 		tail = pbpage + PB_PAGE_SKIP;
+ 	}
+ 
+-	if (error) {
+-		printk("\nswsusp: Out of memory\n\n");
+-		free_pagedir(pblist);
+-		free_eaten_memory();
+-		pblist = NULL;
+-		/* Is this even worth handling? It should never ever happen, and we
+-		   have just lost user's state, anyway... */
+-	} else
+-		printk("swsusp: Relocated %d pages\n", rel);
++	/* This is for swsusp_free() */
++	for_each_pb_page (pbpage, pblist) {
++		SetPageNosave(virt_to_page(pbpage));
++		SetPageNosaveFree(virt_to_page(pbpage));
++	}
++
++	printk("swsusp: Relocated %d pages\n", rel);
+ 
+ 	return pblist;
+ }
+@@ -1440,9 +972,7 @@ static int read_pagedir(struct pbe *pbli
+ 			break;
+ 	}
+ 
+-	if (error)
+-		free_pagedir(pblist);
+-	else
++	if (!error)
+ 		BUG_ON(i != swsusp_info.pagedir_pages);
+ 
+ 	return error;
+@@ -1485,15 +1015,6 @@ static int read_suspend_image(void)
+ 	if (!error)
+ 		error = data_read(pagedir_nosave);
+ 
+-	if (error) { /* We fail cleanly */
+-		free_eaten_memory();
+-		for_each_pbe (p, pagedir_nosave)
+-			if (p->address) {
+-				free_page(p->address);
+-				p->address = 0UL;
+-			}
+-		free_pagedir(pagedir_nosave);
+-	}
+ 	return error;
+ }
+ 
+diff --git a/kernel/printk.c b/kernel/printk.c
+--- a/kernel/printk.c
++++ b/kernel/printk.c
+@@ -10,7 +10,7 @@
+  * elsewhere, in preparation for a serial line console (someday).
+  * Ted Ts'o, 2/11/93.
+  * Modified for sysctl support, 1/8/97, Chris Horn.
+- * Fixed SMP synchronization, 08/08/99, Manfred Spraul 
++ * Fixed SMP synchronization, 08/08/99, Manfred Spraul
+  *     manfreds at colorfullife.com
+  * Rewrote bits to get rid of console_lock
+  *	01Mar01 Andrew Morton <andrewm at uow.edu.au>
+@@ -148,7 +148,7 @@ static int __init console_setup(char *st
+ 	if (!strcmp(str, "ttyb"))
+ 		strcpy(name, "ttyS1");
+ #endif
+-	for(s = name; *s; s++)
++	for (s = name; *s; s++)
+ 		if ((*s >= '0' && *s <= '9') || *s == ',')
+ 			break;
+ 	idx = simple_strtoul(s, NULL, 10);
+@@ -169,11 +169,11 @@ static int __init log_buf_len_setup(char
+ 		size = roundup_pow_of_two(size);
+ 	if (size > log_buf_len) {
+ 		unsigned long start, dest_idx, offset;
+-		char * new_log_buf;
++		char *new_log_buf;
+ 
+ 		new_log_buf = alloc_bootmem(size);
+ 		if (!new_log_buf) {
+-			printk("log_buf_len: allocation failed\n");
++			printk(KERN_WARNING "log_buf_len: allocation failed\n");
+ 			goto out;
+ 		}
+ 
+@@ -193,10 +193,9 @@ static int __init log_buf_len_setup(char
+ 		log_end -= offset;
+ 		spin_unlock_irqrestore(&logbuf_lock, flags);
+ 
+-		printk("log_buf_len: %d\n", log_buf_len);
++		printk(KERN_NOTICE "log_buf_len: %d\n", log_buf_len);
+ 	}
+ out:
+-
+ 	return 1;
+ }
+ 
+@@ -217,7 +216,7 @@ __setup("log_buf_len=", log_buf_len_setu
+  *	9 -- Return number of unread characters in the log buffer
+  *     10 -- Return size of the log buffer
+  */
+-int do_syslog(int type, char __user * buf, int len)
++int do_syslog(int type, char __user *buf, int len)
+ {
+ 	unsigned long i, j, limit, count;
+ 	int do_clear = 0;
+@@ -244,7 +243,8 @@ int do_syslog(int type, char __user * bu
+ 			error = -EFAULT;
+ 			goto out;
+ 		}
+-		error = wait_event_interruptible(log_wait, (log_start - log_end));
++		error = wait_event_interruptible(log_wait,
++							(log_start - log_end));
+ 		if (error)
+ 			goto out;
+ 		i = 0;
+@@ -264,7 +264,7 @@ int do_syslog(int type, char __user * bu
+ 			error = i;
+ 		break;
+ 	case 4:		/* Read/clear last kernel messages */
+-		do_clear = 1; 
++		do_clear = 1;
+ 		/* FALL THRU */
+ 	case 3:		/* Read last kernel messages */
+ 		error = -EINVAL;
+@@ -288,11 +288,11 @@ int do_syslog(int type, char __user * bu
+ 		limit = log_end;
+ 		/*
+ 		 * __put_user() could sleep, and while we sleep
+-		 * printk() could overwrite the messages 
++		 * printk() could overwrite the messages
+ 		 * we try to copy to user space. Therefore
+ 		 * the messages are copied in reverse. <manfreds>
+ 		 */
+-		for(i = 0; i < count && !error; i++) {
++		for (i = 0; i < count && !error; i++) {
+ 			j = limit-1-i;
+ 			if (j + log_buf_len < log_end)
+ 				break;
+@@ -306,10 +306,10 @@ int do_syslog(int type, char __user * bu
+ 		if (error)
+ 			break;
+ 		error = i;
+-		if(i != count) {
++		if (i != count) {
+ 			int offset = count-error;
+ 			/* buffer overflow during copy, correct user buffer. */
+-			for(i=0;i<error;i++) {
++			for (i = 0; i < error; i++) {
+ 				if (__get_user(c,&buf[i+offset]) ||
+ 				    __put_user(c,&buf[i])) {
+ 					error = -EFAULT;
+@@ -351,7 +351,7 @@ out:
+ 	return error;
+ }
+ 
+-asmlinkage long sys_syslog(int type, char __user * buf, int len)
++asmlinkage long sys_syslog(int type, char __user *buf, int len)
+ {
+ 	return do_syslog(type, buf, len);
+ }
+@@ -404,21 +404,19 @@ static void call_console_drivers(unsigne
+ 	cur_index = start;
+ 	start_print = start;
+ 	while (cur_index != end) {
+-		if (	msg_level < 0 &&
+-			((end - cur_index) > 2) &&
+-			LOG_BUF(cur_index + 0) == '<' &&
+-			LOG_BUF(cur_index + 1) >= '0' &&
+-			LOG_BUF(cur_index + 1) <= '7' &&
+-			LOG_BUF(cur_index + 2) == '>')
+-		{
++		if (msg_level < 0 && ((end - cur_index) > 2) &&
++				LOG_BUF(cur_index + 0) == '<' &&
++				LOG_BUF(cur_index + 1) >= '0' &&
++				LOG_BUF(cur_index + 1) <= '7' &&
++				LOG_BUF(cur_index + 2) == '>') {
+ 			msg_level = LOG_BUF(cur_index + 1) - '0';
+ 			cur_index += 3;
+ 			start_print = cur_index;
+ 		}
+ 		while (cur_index != end) {
+ 			char c = LOG_BUF(cur_index);
+-			cur_index++;
+ 
++			cur_index++;
+ 			if (c == '\n') {
+ 				if (msg_level < 0) {
+ 					/*
+@@ -461,7 +459,7 @@ static void zap_locks(void)
+ 	static unsigned long oops_timestamp;
+ 
+ 	if (time_after_eq(jiffies, oops_timestamp) &&
+-			!time_after(jiffies, oops_timestamp + 30*HZ))
++			!time_after(jiffies, oops_timestamp + 30 * HZ))
+ 		return;
+ 
+ 	oops_timestamp = jiffies;
+@@ -495,7 +493,7 @@ __attribute__((weak)) unsigned long long
+ 
+ /*
+  * This is printk.  It can be called from any context.  We want it to work.
+- * 
++ *
+  * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
+  * call the console drivers.  If we fail to get the semaphore we place the output
+  * into the log buffer and return.  The current holder of the console_sem will
+@@ -639,13 +637,19 @@ EXPORT_SYMBOL(vprintk);
+ 
+ #else
+ 
+-asmlinkage long sys_syslog(int type, char __user * buf, int len)
++asmlinkage long sys_syslog(int type, char __user *buf, int len)
+ {
+ 	return 0;
+ }
+ 
+-int do_syslog(int type, char __user * buf, int len) { return 0; }
+-static void call_console_drivers(unsigned long start, unsigned long end) {}
++int do_syslog(int type, char __user *buf, int len)
++{
++	return 0;
++}
++
++static void call_console_drivers(unsigned long start, unsigned long end)
++{
++}
+ 
+ #endif
+ 
+@@ -851,9 +855,9 @@ EXPORT_SYMBOL(console_start);
+  * print any messages that were printed by the kernel before the
+  * console driver was initialized.
+  */
+-void register_console(struct console * console)
++void register_console(struct console *console)
+ {
+-	int     i;
++	int i;
+ 	unsigned long flags;
+ 
+ 	if (preferred_console < 0)
+@@ -878,7 +882,8 @@ void register_console(struct console * c
+ 	 *	See if this console matches one we selected on
+ 	 *	the command line.
+ 	 */
+-	for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) {
++	for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0];
++			i++) {
+ 		if (strcmp(console_cmdline[i].name, console->name) != 0)
+ 			continue;
+ 		if (console->index >= 0 &&
+@@ -933,9 +938,9 @@ void register_console(struct console * c
+ }
+ EXPORT_SYMBOL(register_console);
+ 
+-int unregister_console(struct console * console)
++int unregister_console(struct console *console)
+ {
+-        struct console *a,*b;
++        struct console *a, *b;
+ 	int res = 1;
+ 
+ 	acquire_console_sem();
+@@ -949,10 +954,10 @@ int unregister_console(struct console * 
+ 				b->next = a->next;
+ 				res = 0;
+ 				break;
+-			}  
++			}
+ 		}
+ 	}
+-	
++
+ 	/* If last console is removed, we re-enable picking the first
+ 	 * one that gets registered. Without that, pmac early boot console
+ 	 * would prevent fbcon from taking over.
+@@ -994,7 +999,7 @@ void tty_write_message(struct tty_struct
+ int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
+ {
+ 	static DEFINE_SPINLOCK(ratelimit_lock);
+-	static unsigned long toks = 10*5*HZ;
++	static unsigned long toks = 10 * 5 * HZ;
+ 	static unsigned long last_msg;
+ 	static int missed;
+ 	unsigned long flags;
+@@ -1007,6 +1012,7 @@ int __printk_ratelimit(int ratelimit_jif
+ 		toks = ratelimit_burst * ratelimit_jiffies;
+ 	if (toks >= ratelimit_jiffies) {
+ 		int lost = missed;
++
+ 		missed = 0;
+ 		toks -= ratelimit_jiffies;
+ 		spin_unlock_irqrestore(&ratelimit_lock, flags);
+@@ -1021,7 +1027,7 @@ int __printk_ratelimit(int ratelimit_jif
+ EXPORT_SYMBOL(__printk_ratelimit);
+ 
+ /* minimum time in jiffies between messages */
+-int printk_ratelimit_jiffies = 5*HZ;
++int printk_ratelimit_jiffies = 5 * HZ;
+ 
+ /* number of messages we send before ratelimiting */
+ int printk_ratelimit_burst = 10;
+diff --git a/kernel/ptrace.c b/kernel/ptrace.c
+--- a/kernel/ptrace.c
++++ b/kernel/ptrace.c
+@@ -56,6 +56,10 @@ void ptrace_untrace(task_t *child)
+ 			signal_wake_up(child, 1);
+ 		}
+ 	}
++	if (child->signal->flags & SIGNAL_GROUP_EXIT) {
++		sigaddset(&child->pending.signal, SIGKILL);
++		signal_wake_up(child, 1);
++	}
+ 	spin_unlock(&child->sighand->siglock);
+ }
+ 
+@@ -77,8 +81,7 @@ void __ptrace_unlink(task_t *child)
+ 		SET_LINKS(child);
+ 	}
+ 
+-	if (child->state == TASK_TRACED)
+-		ptrace_untrace(child);
++	ptrace_untrace(child);
+ }
+ 
+ /*
+diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
+--- a/kernel/rcupdate.c
++++ b/kernel/rcupdate.c
+@@ -154,6 +154,15 @@ void fastcall call_rcu_bh(struct rcu_hea
+ }
+ 
+ /*
++ * Return the number of RCU batches processed thus far.  Useful
++ * for debug and statistics.
++ */
++long rcu_batches_completed(void)
++{
++	return rcu_ctrlblk.completed;
++}
++
++/*
+  * Invoke the completed RCU callbacks. They are expected to be in
+  * a per-cpu list.
+  */
+@@ -501,6 +510,7 @@ void synchronize_kernel(void)
+ }
+ 
+ module_param(maxbatch, int, 0);
++EXPORT_SYMBOL_GPL(rcu_batches_completed);
+ EXPORT_SYMBOL(call_rcu);  /* WARNING: GPL-only in April 2006. */
+ EXPORT_SYMBOL(call_rcu_bh);  /* WARNING: GPL-only in April 2006. */
+ EXPORT_SYMBOL_GPL(synchronize_rcu);
+diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
+new file mode 100644
+--- /dev/null
++++ b/kernel/rcutorture.c
+@@ -0,0 +1,492 @@
++/*
++ * Read-Copy Update /proc-based torture test facility
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the 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.
++ *
++ * Copyright (C) IBM Corporation, 2005
++ *
++ * Authors: Paul E. McKenney <paulmck at us.ibm.com>
++ *
++ * See also:  Documentation/RCU/torture.txt
++ */
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/kthread.h>
++#include <linux/err.h>
++#include <linux/spinlock.h>
++#include <linux/smp.h>
++#include <linux/rcupdate.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <asm/atomic.h>
++#include <linux/bitops.h>
++#include <linux/module.h>
++#include <linux/completion.h>
++#include <linux/moduleparam.h>
++#include <linux/percpu.h>
++#include <linux/notifier.h>
++#include <linux/rcuref.h>
++#include <linux/cpu.h>
++#include <linux/random.h>
++#include <linux/delay.h>
++#include <linux/byteorder/swabb.h>
++#include <linux/stat.h>
++
++MODULE_LICENSE("GPL");
++
++static int nreaders = -1;	/* # reader threads, defaults to 4*ncpus */
++static int stat_interval = 0;	/* Interval between stats, in seconds. */
++				/*  Defaults to "only at end of test". */
++static int verbose = 0;		/* Print more debug info. */
++
++MODULE_PARM(nreaders, "i");
++MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
++MODULE_PARM(stat_interval, "i");
++MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
++MODULE_PARM(verbose, "i");
++MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
++#define TORTURE_FLAG "rcutorture: "
++#define PRINTK_STRING(s) \
++	do { printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
++#define VERBOSE_PRINTK_STRING(s) \
++	do { if (verbose) printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
++#define VERBOSE_PRINTK_ERRSTRING(s) \
++	do { if (verbose) printk(KERN_ALERT TORTURE_FLAG "!!! " s "\n"); } while (0)
++
++static char printk_buf[4096];
++
++static int nrealreaders;
++static struct task_struct *writer_task;
++static struct task_struct **reader_tasks;
++static struct task_struct *stats_task;
++
++#define RCU_TORTURE_PIPE_LEN 10
++
++struct rcu_torture {
++	struct rcu_head rtort_rcu;
++	int rtort_pipe_count;
++	struct list_head rtort_free;
++};
++
++static int fullstop = 0;	/* stop generating callbacks at test end. */
++static LIST_HEAD(rcu_torture_freelist);
++static struct rcu_torture *rcu_torture_current = NULL;
++static long rcu_torture_current_version = 0;
++static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN];
++static DEFINE_SPINLOCK(rcu_torture_lock);
++static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) =
++	{ 0 };
++static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) =
++	{ 0 };
++static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
++atomic_t n_rcu_torture_alloc;
++atomic_t n_rcu_torture_alloc_fail;
++atomic_t n_rcu_torture_free;
++
++/*
++ * Allocate an element from the rcu_tortures pool.
++ */
++struct rcu_torture *
++rcu_torture_alloc(void)
++{
++	struct list_head *p;
++
++	spin_lock(&rcu_torture_lock);
++	if (list_empty(&rcu_torture_freelist)) {
++		atomic_inc(&n_rcu_torture_alloc_fail);
++		spin_unlock(&rcu_torture_lock);
++		return NULL;
++	}
++	atomic_inc(&n_rcu_torture_alloc);
++	p = rcu_torture_freelist.next;
++	list_del_init(p);
++	spin_unlock(&rcu_torture_lock);
++	return container_of(p, struct rcu_torture, rtort_free);
++}
++
++/*
++ * Free an element to the rcu_tortures pool.
++ */
++static void
++rcu_torture_free(struct rcu_torture *p)
++{
++	atomic_inc(&n_rcu_torture_free);
++	spin_lock(&rcu_torture_lock);
++	list_add_tail(&p->rtort_free, &rcu_torture_freelist);
++	spin_unlock(&rcu_torture_lock);
++}
++
++static void
++rcu_torture_cb(struct rcu_head *p)
++{
++	int i;
++	struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu);
++
++	if (fullstop) {
++		/* Test is ending, just drop callbacks on the floor. */
++		/* The next initialization will pick up the pieces. */
++		return;
++	}
++	i = rp->rtort_pipe_count;
++	if (i > RCU_TORTURE_PIPE_LEN)
++		i = RCU_TORTURE_PIPE_LEN;
++	atomic_inc(&rcu_torture_wcount[i]);
++	if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN)
++		rcu_torture_free(rp);
++	else
++		call_rcu(p, rcu_torture_cb);
++}
++
++struct rcu_random_state {
++	unsigned long rrs_state;
++	unsigned long rrs_count;
++};
++
++#define RCU_RANDOM_MULT 39916801  /* prime */
++#define RCU_RANDOM_ADD	479001701 /* prime */
++#define RCU_RANDOM_REFRESH 10000
++
++#define DEFINE_RCU_RANDOM(name) struct rcu_random_state name = { 0, 0 }
++
++/*
++ * Crude but fast random-number generator.  Uses a linear congruential
++ * generator, with occasional help from get_random_bytes().
++ */
++static long
++rcu_random(struct rcu_random_state *rrsp)
++{
++	long refresh;
++
++	if (--rrsp->rrs_count < 0) {
++		get_random_bytes(&refresh, sizeof(refresh));
++		rrsp->rrs_state += refresh;
++		rrsp->rrs_count = RCU_RANDOM_REFRESH;
++	}
++	rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD;
++	return swahw32(rrsp->rrs_state);
++}
++
++/*
++ * RCU torture writer kthread.  Repeatedly substitutes a new structure
++ * for that pointed to by rcu_torture_current, freeing the old structure
++ * after a series of grace periods (the "pipeline").
++ */
++static int
++rcu_torture_writer(void *arg)
++{
++	int i;
++	long oldbatch = rcu_batches_completed();
++	struct rcu_torture *rp;
++	struct rcu_torture *old_rp;
++	static DEFINE_RCU_RANDOM(rand);
++
++	VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
++	do {
++		schedule_timeout_uninterruptible(1);
++		if (rcu_batches_completed() == oldbatch)
++			continue;
++		if ((rp = rcu_torture_alloc()) == NULL)
++			continue;
++		rp->rtort_pipe_count = 0;
++		udelay(rcu_random(&rand) & 0x3ff);
++		old_rp = rcu_torture_current;
++		rcu_assign_pointer(rcu_torture_current, rp);
++		smp_wmb();
++		if (old_rp != NULL) {
++			i = old_rp->rtort_pipe_count;
++			if (i > RCU_TORTURE_PIPE_LEN)
++				i = RCU_TORTURE_PIPE_LEN;
++			atomic_inc(&rcu_torture_wcount[i]);
++			old_rp->rtort_pipe_count++;
++			call_rcu(&old_rp->rtort_rcu, rcu_torture_cb);
++		}
++		rcu_torture_current_version++;
++		oldbatch = rcu_batches_completed();
++	} while (!kthread_should_stop() && !fullstop);
++	VERBOSE_PRINTK_STRING("rcu_torture_writer task stopping");
++	while (!kthread_should_stop())
++		schedule_timeout_uninterruptible(1);
++	return 0;
++}
++
++/*
++ * RCU torture reader kthread.  Repeatedly dereferences rcu_torture_current,
++ * incrementing the corresponding element of the pipeline array.  The
++ * counter in the element should never be greater than 1, otherwise, the
++ * RCU implementation is broken.
++ */
++static int
++rcu_torture_reader(void *arg)
++{
++	int completed;
++	DEFINE_RCU_RANDOM(rand);
++	struct rcu_torture *p;
++	int pipe_count;
++
++	VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
++	do {
++		rcu_read_lock();
++		completed = rcu_batches_completed();
++		p = rcu_dereference(rcu_torture_current);
++		if (p == NULL) {
++			/* Wait for rcu_torture_writer to get underway */
++			rcu_read_unlock();
++			schedule_timeout_interruptible(HZ);
++			continue;
++		}
++		udelay(rcu_random(&rand) & 0x7f);
++		preempt_disable();
++		pipe_count = p->rtort_pipe_count;
++		if (pipe_count > RCU_TORTURE_PIPE_LEN) {
++			/* Should not happen, but... */
++			pipe_count = RCU_TORTURE_PIPE_LEN;
++		}
++		++__get_cpu_var(rcu_torture_count)[pipe_count];
++		completed = rcu_batches_completed() - completed;
++		if (completed > RCU_TORTURE_PIPE_LEN) {
++			/* Should not happen, but... */
++			completed = RCU_TORTURE_PIPE_LEN;
++		}
++		++__get_cpu_var(rcu_torture_batch)[completed];
++		preempt_enable();
++		rcu_read_unlock();
++		schedule();
++	} while (!kthread_should_stop() && !fullstop);
++	VERBOSE_PRINTK_STRING("rcu_torture_reader task stopping");
++	while (!kthread_should_stop())
++		schedule_timeout_uninterruptible(1);
++	return 0;
++}
++
++/*
++ * Create an RCU-torture statistics message in the specified buffer.
++ */
++static int
++rcu_torture_printk(char *page)
++{
++	int cnt = 0;
++	int cpu;
++	int i;
++	long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
++	long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
++
++	for_each_cpu(cpu) {
++		for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
++			pipesummary[i] += per_cpu(rcu_torture_count, cpu)[i];
++			batchsummary[i] += per_cpu(rcu_torture_batch, cpu)[i];
++		}
++	}
++	for (i = RCU_TORTURE_PIPE_LEN - 1; i >= 0; i--) {
++		if (pipesummary[i] != 0)
++			break;
++	}
++	cnt += sprintf(&page[cnt], "rcutorture: ");
++	cnt += sprintf(&page[cnt],
++		       "rtc: %p ver: %ld tfle: %d rta: %d rtaf: %d rtf: %d",
++		       rcu_torture_current,
++		       rcu_torture_current_version,
++		       list_empty(&rcu_torture_freelist),
++		       atomic_read(&n_rcu_torture_alloc),
++		       atomic_read(&n_rcu_torture_alloc_fail),
++		       atomic_read(&n_rcu_torture_free));
++	cnt += sprintf(&page[cnt], "\nrcutorture: ");
++	if (i > 1)
++		cnt += sprintf(&page[cnt], "!!! ");
++	cnt += sprintf(&page[cnt], "Reader Pipe: ");
++	for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
++		cnt += sprintf(&page[cnt], " %ld", pipesummary[i]);
++	cnt += sprintf(&page[cnt], "\nrcutorture: ");
++	cnt += sprintf(&page[cnt], "Reader Batch: ");
++	for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
++		cnt += sprintf(&page[cnt], " %ld", batchsummary[i]);
++	cnt += sprintf(&page[cnt], "\nrcutorture: ");
++	cnt += sprintf(&page[cnt], "Free-Block Circulation: ");
++	for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
++		cnt += sprintf(&page[cnt], " %d",
++			       atomic_read(&rcu_torture_wcount[i]));
++	}
++	cnt += sprintf(&page[cnt], "\n");
++	return cnt;
++}
++
++/*
++ * Print torture statistics.  Caller must ensure that there is only
++ * one call to this function at a given time!!!  This is normally
++ * accomplished by relying on the module system to only have one copy
++ * of the module loaded, and then by giving the rcu_torture_stats
++ * kthread full control (or the init/cleanup functions when rcu_torture_stats
++ * thread is not running).
++ */
++static void
++rcu_torture_stats_print(void)
++{
++	int cnt;
++
++	cnt = rcu_torture_printk(printk_buf);
++	printk(KERN_ALERT "%s", printk_buf);
++}
++
++/*
++ * Periodically prints torture statistics, if periodic statistics printing
++ * was specified via the stat_interval module parameter.
++ *
++ * No need to worry about fullstop here, since this one doesn't reference
++ * volatile state or register callbacks.
++ */
++static int
++rcu_torture_stats(void *arg)
++{
++	VERBOSE_PRINTK_STRING("rcu_torture_stats task started");
++	do {
++		schedule_timeout_interruptible(stat_interval * HZ);
++		rcu_torture_stats_print();
++	} while (!kthread_should_stop());
++	VERBOSE_PRINTK_STRING("rcu_torture_stats task stopping");
++	return 0;
++}
++
++static void
++rcu_torture_cleanup(void)
++{
++	int i;
++
++	fullstop = 1;
++	if (writer_task != NULL) {
++		VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
++		kthread_stop(writer_task);
++	}
++	writer_task = NULL;
++
++	if (reader_tasks != NULL) {
++		for (i = 0; i < nrealreaders; i++) {
++			if (reader_tasks[i] != NULL) {
++				VERBOSE_PRINTK_STRING(
++					"Stopping rcu_torture_reader task");
++				kthread_stop(reader_tasks[i]);
++			}
++			reader_tasks[i] = NULL;
++		}
++		kfree(reader_tasks);
++		reader_tasks = NULL;
++	}
++	rcu_torture_current = NULL;
++
++	if (stats_task != NULL) {
++		VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
++		kthread_stop(stats_task);
++	}
++	stats_task = NULL;
++
++	/* Wait for all RCU callbacks to fire.  */
++
++	for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
++		synchronize_rcu();
++	rcu_torture_stats_print();  /* -After- the stats thread is stopped! */
++	PRINTK_STRING("--- End of test");
++}
++
++static int
++rcu_torture_init(void)
++{
++	int i;
++	int cpu;
++	int firsterr = 0;
++
++	/* Process args and tell the world that the torturer is on the job. */
++
++	if (nreaders >= 0)
++		nrealreaders = nreaders;
++	else
++		nrealreaders = 2 * num_online_cpus();
++	printk(KERN_ALERT TORTURE_FLAG
++	       "--- Start of test: nreaders=%d stat_interval=%d verbose=%d\n",
++	       nrealreaders, stat_interval, verbose);
++	fullstop = 0;
++
++	/* Set up the freelist. */
++
++	INIT_LIST_HEAD(&rcu_torture_freelist);
++	for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) {
++		list_add_tail(&rcu_tortures[i].rtort_free,
++			      &rcu_torture_freelist);
++	}
++
++	/* Initialize the statistics so that each run gets its own numbers. */
++
++	rcu_torture_current = NULL;
++	rcu_torture_current_version = 0;
++	atomic_set(&n_rcu_torture_alloc, 0);
++	atomic_set(&n_rcu_torture_alloc_fail, 0);
++	atomic_set(&n_rcu_torture_free, 0);
++	for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
++		atomic_set(&rcu_torture_wcount[i], 0);
++	for_each_cpu(cpu) {
++		for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
++			per_cpu(rcu_torture_count, cpu)[i] = 0;
++			per_cpu(rcu_torture_batch, cpu)[i] = 0;
++		}
++	}
++
++	/* Start up the kthreads. */
++
++	VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task");
++	writer_task = kthread_run(rcu_torture_writer, NULL,
++				  "rcu_torture_writer");
++	if (IS_ERR(writer_task)) {
++		firsterr = PTR_ERR(writer_task);
++		VERBOSE_PRINTK_ERRSTRING("Failed to create writer");
++		writer_task = NULL;
++		goto unwind;
++	}
++	reader_tasks = kmalloc(nrealreaders * sizeof(reader_tasks[0]),
++			       GFP_KERNEL);
++	if (reader_tasks == NULL) {
++		VERBOSE_PRINTK_ERRSTRING("out of memory");
++		firsterr = -ENOMEM;
++		goto unwind;
++	}
++	for (i = 0; i < nrealreaders; i++) {
++		VERBOSE_PRINTK_STRING("Creating rcu_torture_reader task");
++		reader_tasks[i] = kthread_run(rcu_torture_reader, NULL,
++					      "rcu_torture_reader");
++		if (IS_ERR(reader_tasks[i])) {
++			firsterr = PTR_ERR(reader_tasks[i]);
++			VERBOSE_PRINTK_ERRSTRING("Failed to create reader");
++			reader_tasks[i] = NULL;
++			goto unwind;
++		}
++	}
++	if (stat_interval > 0) {
++		VERBOSE_PRINTK_STRING("Creating rcu_torture_stats task");
++		stats_task = kthread_run(rcu_torture_stats, NULL,
++					"rcu_torture_stats");
++		if (IS_ERR(stats_task)) {
++			firsterr = PTR_ERR(stats_task);
++			VERBOSE_PRINTK_ERRSTRING("Failed to create stats");
++			stats_task = NULL;
++			goto unwind;
++		}
++	}
++	return 0;
++
++unwind:
++	rcu_torture_cleanup();
++	return firsterr;
++}
++
++module_init(rcu_torture_init);
++module_exit(rcu_torture_cleanup);
+diff --git a/kernel/sched.c b/kernel/sched.c
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -2511,8 +2511,6 @@ void account_system_time(struct task_str
+ 		cpustat->idle = cputime64_add(cpustat->idle, tmp);
+ 	/* Account for system time used */
+ 	acct_update_integrals(p);
+-	/* Update rss highwater mark */
+-	update_mem_hiwater(p);
+ }
+ 
+ /*
+@@ -3879,7 +3877,6 @@ EXPORT_SYMBOL(cpu_present_map);
+ 
+ #ifndef CONFIG_SMP
+ cpumask_t cpu_online_map = CPU_MASK_ALL;
+-EXPORT_SYMBOL_GPL(cpu_online_map);
+ cpumask_t cpu_possible_map = CPU_MASK_ALL;
+ #endif
+ 
+diff --git a/kernel/signal.c b/kernel/signal.c
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -277,7 +277,6 @@ static struct sigqueue *__sigqueue_alloc
+ 	} else {
+ 		INIT_LIST_HEAD(&q->list);
+ 		q->flags = 0;
+-		q->lock = NULL;
+ 		q->user = get_uid(t->user);
+ 	}
+ 	return(q);
+@@ -406,6 +405,8 @@ void __exit_signal(struct task_struct *t
+ 
+ void exit_signal(struct task_struct *tsk)
+ {
++	atomic_dec(&tsk->signal->live);
++
+ 	write_lock_irq(&tasklist_lock);
+ 	__exit_signal(tsk);
+ 	write_unlock_irq(&tasklist_lock);
+@@ -650,8 +651,7 @@ static int check_kill_permission(int sig
+ 	if (!valid_signal(sig))
+ 		return error;
+ 	error = -EPERM;
+-	if ((!info || ((unsigned long)info != 1 &&
+-			(unsigned long)info != 2 && SI_FROMUSER(info)))
++	if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
+ 	    && ((sig != SIGCONT) ||
+ 		(current->signal->session != t->signal->session))
+ 	    && (current->euid ^ t->suid) && (current->euid ^ t->uid)
+@@ -788,7 +788,7 @@ static int send_signal(int sig, struct s
+ 	 * fast-pathed signals for kernel-internal things like SIGSTOP
+ 	 * or SIGKILL.
+ 	 */
+-	if ((unsigned long)info == 2)
++	if (info == SEND_SIG_FORCED)
+ 		goto out_set;
+ 
+ 	/* Real-time signals must be queued if sent by sigqueue, or
+@@ -800,19 +800,19 @@ static int send_signal(int sig, struct s
+ 	   pass on the info struct.  */
+ 
+ 	q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
+-					     ((unsigned long) info < 2 ||
++					     (is_si_special(info) ||
+ 					      info->si_code >= 0)));
+ 	if (q) {
+ 		list_add_tail(&q->list, &signals->list);
+ 		switch ((unsigned long) info) {
+-		case 0:
++		case (unsigned long) SEND_SIG_NOINFO:
+ 			q->info.si_signo = sig;
+ 			q->info.si_errno = 0;
+ 			q->info.si_code = SI_USER;
+ 			q->info.si_pid = current->pid;
+ 			q->info.si_uid = current->uid;
+ 			break;
+-		case 1:
++		case (unsigned long) SEND_SIG_PRIV:
+ 			q->info.si_signo = sig;
+ 			q->info.si_errno = 0;
+ 			q->info.si_code = SI_KERNEL;
+@@ -823,20 +823,13 @@ static int send_signal(int sig, struct s
+ 			copy_siginfo(&q->info, info);
+ 			break;
+ 		}
+-	} else {
+-		if (sig >= SIGRTMIN && info && (unsigned long)info != 1
+-		   && info->si_code != SI_USER)
++	} else if (!is_si_special(info)) {
++		if (sig >= SIGRTMIN && info->si_code != SI_USER)
+ 		/*
+ 		 * Queue overflow, abort.  We may abort if the signal was rt
+ 		 * and sent by user using something other than kill().
+ 		 */
+ 			return -EAGAIN;
+-		if (((unsigned long)info > 1) && (info->si_code == SI_TIMER))
+-			/*
+-			 * Set up a return to indicate that we dropped 
+-			 * the signal.
+-			 */
+-			ret = info->si_sys_private;
+ 	}
+ 
+ out_set:
+@@ -857,12 +850,6 @@ specific_send_sig_info(int sig, struct s
+ 		BUG();
+ 	assert_spin_locked(&t->sighand->siglock);
+ 
+-	if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
+-		/*
+-		 * Set up a return to indicate that we dropped the signal.
+-		 */
+-		ret = info->si_sys_private;
+-
+ 	/* Short-circuit ignored signals.  */
+ 	if (sig_ignored(t, sig))
+ 		goto out;
+@@ -892,11 +879,13 @@ force_sig_info(int sig, struct siginfo *
+ 	int ret;
+ 
+ 	spin_lock_irqsave(&t->sighand->siglock, flags);
+-	if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
++	if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
+ 		t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
++	}
++	if (sigismember(&t->blocked, sig)) {
+ 		sigdelset(&t->blocked, sig);
+-		recalc_sigpending_tsk(t);
+ 	}
++	recalc_sigpending_tsk(t);
+ 	ret = specific_send_sig_info(sig, info, t);
+ 	spin_unlock_irqrestore(&t->sighand->siglock, flags);
+ 
+@@ -906,15 +895,7 @@ force_sig_info(int sig, struct siginfo *
+ void
+ force_sig_specific(int sig, struct task_struct *t)
+ {
+-	unsigned long int flags;
+-
+-	spin_lock_irqsave(&t->sighand->siglock, flags);
+-	if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN)
+-		t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
+-	sigdelset(&t->blocked, sig);
+-	recalc_sigpending_tsk(t);
+-	specific_send_sig_info(sig, (void *)2, t);
+-	spin_unlock_irqrestore(&t->sighand->siglock, flags);
++	force_sig_info(sig, SEND_SIG_FORCED, t);
+ }
+ 
+ /*
+@@ -1049,12 +1030,6 @@ __group_send_sig_info(int sig, struct si
+ 	assert_spin_locked(&p->sighand->siglock);
+ 	handle_stop_signal(sig, p);
+ 
+-	if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
+-		/*
+-		 * Set up a return to indicate that we dropped the signal.
+-		 */
+-		ret = info->si_sys_private;
+-
+ 	/* Short-circuit ignored signals.  */
+ 	if (sig_ignored(p, sig))
+ 		return ret;
+@@ -1107,8 +1082,8 @@ void zap_other_threads(struct task_struc
+ 		if (t != p->group_leader)
+ 			t->exit_signal = -1;
+ 
++		/* SIGKILL will be handled before any pending SIGSTOP */
+ 		sigaddset(&t->pending.signal, SIGKILL);
+-		rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
+ 		signal_wake_up(t, 1);
+ 	}
+ }
+@@ -1284,10 +1259,13 @@ send_sig_info(int sig, struct siginfo *i
+ 	return ret;
+ }
+ 
++#define __si_special(priv) \
++	((priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO)
++
+ int
+ send_sig(int sig, struct task_struct *p, int priv)
+ {
+-	return send_sig_info(sig, (void*)(long)(priv != 0), p);
++	return send_sig_info(sig, __si_special(priv), p);
+ }
+ 
+ /*
+@@ -1307,7 +1285,7 @@ send_group_sig_info(int sig, struct sigi
+ void
+ force_sig(int sig, struct task_struct *p)
+ {
+-	force_sig_info(sig, (void*)1L, p);
++	force_sig_info(sig, SEND_SIG_PRIV, p);
+ }
+ 
+ /*
+@@ -1332,13 +1310,13 @@ force_sigsegv(int sig, struct task_struc
+ int
+ kill_pg(pid_t pgrp, int sig, int priv)
+ {
+-	return kill_pg_info(sig, (void *)(long)(priv != 0), pgrp);
++	return kill_pg_info(sig, __si_special(priv), pgrp);
+ }
+ 
+ int
+ kill_proc(pid_t pid, int sig, int priv)
+ {
+-	return kill_proc_info(sig, (void *)(long)(priv != 0), pid);
++	return kill_proc_info(sig, __si_special(priv), pid);
+ }
+ 
+ /*
+@@ -1369,11 +1347,12 @@ void sigqueue_free(struct sigqueue *q)
+ 	 * pending queue.
+ 	 */
+ 	if (unlikely(!list_empty(&q->list))) {
+-		read_lock(&tasklist_lock);  
+-		spin_lock_irqsave(q->lock, flags);
++		spinlock_t *lock = &current->sighand->siglock;
++		read_lock(&tasklist_lock);
++		spin_lock_irqsave(lock, flags);
+ 		if (!list_empty(&q->list))
+ 			list_del_init(&q->list);
+-		spin_unlock_irqrestore(q->lock, flags);
++		spin_unlock_irqrestore(lock, flags);
+ 		read_unlock(&tasklist_lock);
+ 	}
+ 	q->flags &= ~SIGQUEUE_PREALLOC;
+@@ -1412,7 +1391,6 @@ send_sigqueue(int sig, struct sigqueue *
+ 		goto out;
+ 	}
+ 
+-	q->lock = &p->sighand->siglock;
+ 	list_add_tail(&q->list, &p->pending.list);
+ 	sigaddset(&p->pending.signal, sig);
+ 	if (!sigismember(&p->blocked, sig))
+@@ -1460,7 +1438,6 @@ send_group_sigqueue(int sig, struct sigq
+ 	 * We always use the shared queue for process-wide signals,
+ 	 * to avoid several races.
+ 	 */
+-	q->lock = &p->sighand->siglock;
+ 	list_add_tail(&q->list, &p->signal->shared_pending.list);
+ 	sigaddset(&p->signal->shared_pending.signal, sig);
+ 
+@@ -1879,9 +1856,9 @@ relock:
+ 			/* Let the debugger run.  */
+ 			ptrace_stop(signr, signr, info);
+ 
+-			/* We're back.  Did the debugger cancel the sig?  */
++			/* We're back.  Did the debugger cancel the sig or group_exit? */
+ 			signr = current->exit_code;
+-			if (signr == 0)
++			if (signr == 0 || current->signal->flags & SIGNAL_GROUP_EXIT)
+ 				continue;
+ 
+ 			current->exit_code = 0;
+@@ -2283,26 +2260,13 @@ sys_kill(int pid, int sig)
+ 	return kill_something_info(sig, &info, pid);
+ }
+ 
+-/**
+- *  sys_tgkill - send signal to one specific thread
+- *  @tgid: the thread group ID of the thread
+- *  @pid: the PID of the thread
+- *  @sig: signal to be sent
+- *
+- *  This syscall also checks the tgid and returns -ESRCH even if the PID
+- *  exists but it's not belonging to the target process anymore. This
+- *  method solves the problem of threads exiting and PIDs getting reused.
+- */
+-asmlinkage long sys_tgkill(int tgid, int pid, int sig)
++static int do_tkill(int tgid, int pid, int sig)
+ {
+-	struct siginfo info;
+ 	int error;
++	struct siginfo info;
+ 	struct task_struct *p;
+ 
+-	/* This is only valid for single tasks */
+-	if (pid <= 0 || tgid <= 0)
+-		return -EINVAL;
+-
++	error = -ESRCH;
+ 	info.si_signo = sig;
+ 	info.si_errno = 0;
+ 	info.si_code = SI_TKILL;
+@@ -2311,8 +2275,7 @@ asmlinkage long sys_tgkill(int tgid, int
+ 
+ 	read_lock(&tasklist_lock);
+ 	p = find_task_by_pid(pid);
+-	error = -ESRCH;
+-	if (p && (p->tgid == tgid)) {
++	if (p && (tgid <= 0 || p->tgid == tgid)) {
+ 		error = check_kill_permission(sig, &info, p);
+ 		/*
+ 		 * The null signal is a permissions and process existence
+@@ -2326,47 +2289,40 @@ asmlinkage long sys_tgkill(int tgid, int
+ 		}
+ 	}
+ 	read_unlock(&tasklist_lock);
++
+ 	return error;
+ }
+ 
++/**
++ *  sys_tgkill - send signal to one specific thread
++ *  @tgid: the thread group ID of the thread
++ *  @pid: the PID of the thread
++ *  @sig: signal to be sent
++ *
++ *  This syscall also checks the tgid and returns -ESRCH even if the PID
++ *  exists but it's not belonging to the target process anymore. This
++ *  method solves the problem of threads exiting and PIDs getting reused.
++ */
++asmlinkage long sys_tgkill(int tgid, int pid, int sig)
++{
++	/* This is only valid for single tasks */
++	if (pid <= 0 || tgid <= 0)
++		return -EINVAL;
++
++	return do_tkill(tgid, pid, sig);
++}
++
+ /*
+  *  Send a signal to only one task, even if it's a CLONE_THREAD task.
+  */
+ asmlinkage long
+ sys_tkill(int pid, int sig)
+ {
+-	struct siginfo info;
+-	int error;
+-	struct task_struct *p;
+-
+ 	/* This is only valid for single tasks */
+ 	if (pid <= 0)
+ 		return -EINVAL;
+ 
+-	info.si_signo = sig;
+-	info.si_errno = 0;
+-	info.si_code = SI_TKILL;
+-	info.si_pid = current->tgid;
+-	info.si_uid = current->uid;
+-
+-	read_lock(&tasklist_lock);
+-	p = find_task_by_pid(pid);
+-	error = -ESRCH;
+-	if (p) {
+-		error = check_kill_permission(sig, &info, p);
+-		/*
+-		 * The null signal is a permissions and process existence
+-		 * probe.  No signal is actually delivered.
+-		 */
+-		if (!error && sig && p->sighand) {
+-			spin_lock_irq(&p->sighand->siglock);
+-			handle_stop_signal(sig, p);
+-			error = specific_send_sig_info(sig, &info, p);
+-			spin_unlock_irq(&p->sighand->siglock);
+-		}
+-	}
+-	read_unlock(&tasklist_lock);
+-	return error;
++	return do_tkill(0, pid, sig);
+ }
+ 
+ asmlinkage long
+diff --git a/kernel/time.c b/kernel/time.c
+--- a/kernel/time.c
++++ b/kernel/time.c
+@@ -338,30 +338,20 @@ int do_adjtimex(struct timex *txc)
+ 		        if (mtemp >= MINSEC) {
+ 			    ltemp = (time_offset / mtemp) << (SHIFT_USEC -
+ 							      SHIFT_UPDATE);
+-			    if (ltemp < 0)
+-			        time_freq -= -ltemp >> SHIFT_KH;
+-			    else
+-			        time_freq += ltemp >> SHIFT_KH;
++			    time_freq += shift_right(ltemp, SHIFT_KH);
+ 			} else /* calibration interval too short (p. 12) */
+ 				result = TIME_ERROR;
+ 		    } else {	/* PLL mode */
+ 		        if (mtemp < MAXSEC) {
+ 			    ltemp *= mtemp;
+-			    if (ltemp < 0)
+-			        time_freq -= -ltemp >> (time_constant +
+-							time_constant +
+-							SHIFT_KF - SHIFT_USEC);
+-			    else
+-			        time_freq += ltemp >> (time_constant +
++			    time_freq += shift_right(ltemp,(time_constant +
+ 						       time_constant +
+-						       SHIFT_KF - SHIFT_USEC);
++						       SHIFT_KF - SHIFT_USEC));
+ 			} else /* calibration interval too long (p. 12) */
+ 				result = TIME_ERROR;
+ 		    }
+-		    if (time_freq > time_tolerance)
+-		        time_freq = time_tolerance;
+-		    else if (time_freq < -time_tolerance)
+-		        time_freq = -time_tolerance;
++		    time_freq = min(time_freq, time_tolerance);
++		    time_freq = max(time_freq, -time_tolerance);
+ 		} /* STA_PLL || STA_PPSTIME */
+ 	    } /* txc->modes & ADJ_OFFSET */
+ 	    if (txc->modes & ADJ_TICK) {
+@@ -384,10 +374,7 @@ leave:	if ((time_status & (STA_UNSYNC|ST
+ 	if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
+ 	    txc->offset	   = save_adjust;
+ 	else {
+-	    if (time_offset < 0)
+-		txc->offset = -(-time_offset >> SHIFT_UPDATE);
+-	    else
+-		txc->offset = time_offset >> SHIFT_UPDATE;
++	    txc->offset = shift_right(time_offset, SHIFT_UPDATE);
+ 	}
+ 	txc->freq	   = time_freq + pps_freq;
+ 	txc->maxerror	   = time_maxerror;
+@@ -532,6 +519,7 @@ int do_settimeofday (struct timespec *tv
+ 	clock_was_set();
+ 	return 0;
+ }
++EXPORT_SYMBOL(do_settimeofday);
+ 
+ void do_gettimeofday (struct timeval *tv)
+ {
+diff --git a/kernel/timer.c b/kernel/timer.c
+--- a/kernel/timer.c
++++ b/kernel/timer.c
+@@ -46,6 +46,10 @@ static void time_interpolator_update(lon
+ #define time_interpolator_update(x)
+ #endif
+ 
++u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
++
++EXPORT_SYMBOL(jiffies_64);
++
+ /*
+  * per-CPU timer vector definitions:
+  */
+@@ -91,30 +95,6 @@ static inline void set_running_timer(tve
+ #endif
+ }
+ 
+-static void check_timer_failed(struct timer_list *timer)
+-{
+-	static int whine_count;
+-	if (whine_count < 16) {
+-		whine_count++;
+-		printk("Uninitialised timer!\n");
+-		printk("This is just a warning.  Your computer is OK\n");
+-		printk("function=0x%p, data=0x%lx\n",
+-			timer->function, timer->data);
+-		dump_stack();
+-	}
+-	/*
+-	 * Now fix it up
+-	 */
+-	timer->magic = TIMER_MAGIC;
+-}
+-
+-static inline void check_timer(struct timer_list *timer)
+-{
+-	if (timer->magic != TIMER_MAGIC)
+-		check_timer_failed(timer);
+-}
+-
+-
+ static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
+ {
+ 	unsigned long expires = timer->expires;
+@@ -177,7 +157,6 @@ void fastcall init_timer(struct timer_li
+ {
+ 	timer->entry.next = NULL;
+ 	timer->base = &per_cpu(tvec_bases, raw_smp_processor_id()).t_base;
+-	timer->magic = TIMER_MAGIC;
+ }
+ EXPORT_SYMBOL(init_timer);
+ 
+@@ -230,7 +209,6 @@ int __mod_timer(struct timer_list *timer
+ 	int ret = 0;
+ 
+ 	BUG_ON(!timer->function);
+-	check_timer(timer);
+ 
+ 	base = lock_timer_base(timer, &flags);
+ 
+@@ -283,9 +261,6 @@ void add_timer_on(struct timer_list *tim
+   	unsigned long flags;
+ 
+   	BUG_ON(timer_pending(timer) || !timer->function);
+-
+-	check_timer(timer);
+-
+ 	spin_lock_irqsave(&base->t_base.lock, flags);
+ 	timer->base = &base->t_base;
+ 	internal_add_timer(base, timer);
+@@ -316,8 +291,6 @@ int mod_timer(struct timer_list *timer, 
+ {
+ 	BUG_ON(!timer->function);
+ 
+-	check_timer(timer);
+-
+ 	/*
+ 	 * This is a common optimization triggered by the
+ 	 * networking code - if the timer is re-modified
+@@ -348,8 +321,6 @@ int del_timer(struct timer_list *timer)
+ 	unsigned long flags;
+ 	int ret = 0;
+ 
+-	check_timer(timer);
+-
+ 	if (timer_pending(timer)) {
+ 		base = lock_timer_base(timer, &flags);
+ 		if (timer_pending(timer)) {
+@@ -412,8 +383,6 @@ out:
+  */
+ int del_timer_sync(struct timer_list *timer)
+ {
+-	check_timer(timer);
+-
+ 	for (;;) {
+ 		int ret = try_to_del_timer_sync(timer);
+ 		if (ret >= 0)
+@@ -632,134 +601,118 @@ long time_next_adjust;
+  */
+ static void second_overflow(void)
+ {
+-    long ltemp;
++	long ltemp;
+ 
+-    /* Bump the maxerror field */
+-    time_maxerror += time_tolerance >> SHIFT_USEC;
+-    if ( time_maxerror > NTP_PHASE_LIMIT ) {
+-	time_maxerror = NTP_PHASE_LIMIT;
+-	time_status |= STA_UNSYNC;
+-    }
+-
+-    /*
+-     * Leap second processing. If in leap-insert state at
+-     * the end of the day, the system clock is set back one
+-     * second; if in leap-delete state, the system clock is
+-     * set ahead one second. The microtime() routine or
+-     * external clock driver will insure that reported time
+-     * is always monotonic. The ugly divides should be
+-     * replaced.
+-     */
+-    switch (time_state) {
+-
+-    case TIME_OK:
+-	if (time_status & STA_INS)
+-	    time_state = TIME_INS;
+-	else if (time_status & STA_DEL)
+-	    time_state = TIME_DEL;
+-	break;
+-
+-    case TIME_INS:
+-	if (xtime.tv_sec % 86400 == 0) {
+-	    xtime.tv_sec--;
+-	    wall_to_monotonic.tv_sec++;
+-	    /* The timer interpolator will make time change gradually instead
+-	     * of an immediate jump by one second.
+-	     */
+-	    time_interpolator_update(-NSEC_PER_SEC);
+-	    time_state = TIME_OOP;
+-	    clock_was_set();
+-	    printk(KERN_NOTICE "Clock: inserting leap second 23:59:60 UTC\n");
+-	}
+-	break;
+-
+-    case TIME_DEL:
+-	if ((xtime.tv_sec + 1) % 86400 == 0) {
+-	    xtime.tv_sec++;
+-	    wall_to_monotonic.tv_sec--;
+-	    /* Use of time interpolator for a gradual change of time */
+-	    time_interpolator_update(NSEC_PER_SEC);
+-	    time_state = TIME_WAIT;
+-	    clock_was_set();
+-	    printk(KERN_NOTICE "Clock: deleting leap second 23:59:59 UTC\n");
+-	}
+-	break;
+-
+-    case TIME_OOP:
+-	time_state = TIME_WAIT;
+-	break;
+-
+-    case TIME_WAIT:
+-	if (!(time_status & (STA_INS | STA_DEL)))
+-	    time_state = TIME_OK;
+-    }
+-
+-    /*
+-     * Compute the phase adjustment for the next second. In
+-     * PLL mode, the offset is reduced by a fixed factor
+-     * times the time constant. In FLL mode the offset is
+-     * used directly. In either mode, the maximum phase
+-     * adjustment for each second is clamped so as to spread
+-     * the adjustment over not more than the number of
+-     * seconds between updates.
+-     */
+-    if (time_offset < 0) {
+-	ltemp = -time_offset;
+-	if (!(time_status & STA_FLL))
+-	    ltemp >>= SHIFT_KG + time_constant;
+-	if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
+-	    ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
+-	time_offset += ltemp;
+-	time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+-    } else {
++	/* Bump the maxerror field */
++	time_maxerror += time_tolerance >> SHIFT_USEC;
++	if (time_maxerror > NTP_PHASE_LIMIT) {
++		time_maxerror = NTP_PHASE_LIMIT;
++		time_status |= STA_UNSYNC;
++	}
++
++	/*
++	 * Leap second processing. If in leap-insert state at the end of the
++	 * day, the system clock is set back one second; if in leap-delete
++	 * state, the system clock is set ahead one second. The microtime()
++	 * routine or external clock driver will insure that reported time is
++	 * always monotonic. The ugly divides should be replaced.
++	 */
++	switch (time_state) {
++	case TIME_OK:
++		if (time_status & STA_INS)
++			time_state = TIME_INS;
++		else if (time_status & STA_DEL)
++			time_state = TIME_DEL;
++		break;
++	case TIME_INS:
++		if (xtime.tv_sec % 86400 == 0) {
++			xtime.tv_sec--;
++			wall_to_monotonic.tv_sec++;
++			/*
++			 * The timer interpolator will make time change
++			 * gradually instead of an immediate jump by one second
++			 */
++			time_interpolator_update(-NSEC_PER_SEC);
++			time_state = TIME_OOP;
++			clock_was_set();
++			printk(KERN_NOTICE "Clock: inserting leap second "
++					"23:59:60 UTC\n");
++		}
++		break;
++	case TIME_DEL:
++		if ((xtime.tv_sec + 1) % 86400 == 0) {
++			xtime.tv_sec++;
++			wall_to_monotonic.tv_sec--;
++			/*
++			 * Use of time interpolator for a gradual change of
++			 * time
++			 */
++			time_interpolator_update(NSEC_PER_SEC);
++			time_state = TIME_WAIT;
++			clock_was_set();
++			printk(KERN_NOTICE "Clock: deleting leap second "
++					"23:59:59 UTC\n");
++		}
++		break;
++	case TIME_OOP:
++		time_state = TIME_WAIT;
++		break;
++	case TIME_WAIT:
++		if (!(time_status & (STA_INS | STA_DEL)))
++		time_state = TIME_OK;
++	}
++
++	/*
++	 * Compute the phase adjustment for the next second. In PLL mode, the
++	 * offset is reduced by a fixed factor times the time constant. In FLL
++	 * mode the offset is used directly. In either mode, the maximum phase
++	 * adjustment for each second is clamped so as to spread the adjustment
++	 * over not more than the number of seconds between updates.
++	 */
+ 	ltemp = time_offset;
+ 	if (!(time_status & STA_FLL))
+-	    ltemp >>= SHIFT_KG + time_constant;
+-	if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
+-	    ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
++		ltemp = shift_right(ltemp, SHIFT_KG + time_constant);
++	ltemp = min(ltemp, (MAXPHASE / MINSEC) << SHIFT_UPDATE);
++	ltemp = max(ltemp, -(MAXPHASE / MINSEC) << SHIFT_UPDATE);
+ 	time_offset -= ltemp;
+ 	time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+-    }
+ 
+-    /*
+-     * Compute the frequency estimate and additional phase
+-     * adjustment due to frequency error for the next
+-     * second. When the PPS signal is engaged, gnaw on the
+-     * watchdog counter and update the frequency computed by
+-     * the pll and the PPS signal.
+-     */
+-    pps_valid++;
+-    if (pps_valid == PPS_VALID) {	/* PPS signal lost */
+-	pps_jitter = MAXTIME;
+-	pps_stabil = MAXFREQ;
+-	time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
+-			 STA_PPSWANDER | STA_PPSERROR);
+-    }
+-    ltemp = time_freq + pps_freq;
+-    if (ltemp < 0)
+-	time_adj -= -ltemp >>
+-	    (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
+-    else
+-	time_adj += ltemp >>
+-	    (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
++	/*
++	 * Compute the frequency estimate and additional phase adjustment due
++	 * to frequency error for the next second. When the PPS signal is
++	 * engaged, gnaw on the watchdog counter and update the frequency
++	 * computed by the pll and the PPS signal.
++	 */
++	pps_valid++;
++	if (pps_valid == PPS_VALID) {	/* PPS signal lost */
++		pps_jitter = MAXTIME;
++		pps_stabil = MAXFREQ;
++		time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
++				STA_PPSWANDER | STA_PPSERROR);
++	}
++	ltemp = time_freq + pps_freq;
++	time_adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE));
+ 
+ #if HZ == 100
+-    /* Compensate for (HZ==100) != (1 << SHIFT_HZ).
+-     * Add 25% and 3.125% to get 128.125; => only 0.125% error (p. 14)
+-     */
+-    if (time_adj < 0)
+-	time_adj -= (-time_adj >> 2) + (-time_adj >> 5);
+-    else
+-	time_adj += (time_adj >> 2) + (time_adj >> 5);
++	/*
++	 * Compensate for (HZ==100) != (1 << SHIFT_HZ).  Add 25% and 3.125% to
++	 * get 128.125; => only 0.125% error (p. 14)
++	 */
++	time_adj += shift_right(time_adj, 2) + shift_right(time_adj, 5);
++#endif
++#if HZ == 250
++	/*
++	 * Compensate for (HZ==250) != (1 << SHIFT_HZ).  Add 1.5625% and
++	 * 0.78125% to get 255.85938; => only 0.05% error (p. 14)
++	 */
++	time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
+ #endif
+ #if HZ == 1000
+-    /* Compensate for (HZ==1000) != (1 << SHIFT_HZ).
+-     * Add 1.5625% and 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
+-     */
+-    if (time_adj < 0)
+-	time_adj -= (-time_adj >> 6) + (-time_adj >> 7);
+-    else
+-	time_adj += (time_adj >> 6) + (time_adj >> 7);
++	/*
++	 * Compensate for (HZ==1000) != (1 << SHIFT_HZ).  Add 1.5625% and
++	 * 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
++	 */
++	time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
+ #endif
+ }
+ 
+@@ -768,23 +721,20 @@ static void update_wall_time_one_tick(vo
+ {
+ 	long time_adjust_step, delta_nsec;
+ 
+-	if ( (time_adjust_step = time_adjust) != 0 ) {
+-	    /* We are doing an adjtime thing. 
+-	     *
+-	     * Prepare time_adjust_step to be within bounds.
+-	     * Note that a positive time_adjust means we want the clock
+-	     * to run faster.
+-	     *
+-	     * Limit the amount of the step to be in the range
+-	     * -tickadj .. +tickadj
+-	     */
+-	     if (time_adjust > tickadj)
+-		time_adjust_step = tickadj;
+-	     else if (time_adjust < -tickadj)
+-		time_adjust_step = -tickadj;
++	if ((time_adjust_step = time_adjust) != 0 ) {
++		/*
++		 * We are doing an adjtime thing.  Prepare time_adjust_step to
++		 * be within bounds.  Note that a positive time_adjust means we
++		 * want the clock to run faster.
++		 *
++		 * Limit the amount of the step to be in the range
++		 * -tickadj .. +tickadj
++		 */
++		time_adjust_step = min(time_adjust_step, (long)tickadj);
++		time_adjust_step = max(time_adjust_step, (long)-tickadj);
+ 
+-	    /* Reduce by this step the amount of time left  */
+-	    time_adjust -= time_adjust_step;
++		/* Reduce by this step the amount of time left  */
++		time_adjust -= time_adjust_step;
+ 	}
+ 	delta_nsec = tick_nsec + time_adjust_step * 1000;
+ 	/*
+@@ -792,13 +742,8 @@ static void update_wall_time_one_tick(vo
+ 	 * advance the tick more.
+ 	 */
+ 	time_phase += time_adj;
+-	if (time_phase <= -FINENSEC) {
+-		long ltemp = -time_phase >> (SHIFT_SCALE - 10);
+-		time_phase += ltemp << (SHIFT_SCALE - 10);
+-		delta_nsec -= ltemp;
+-	}
+-	else if (time_phase >= FINENSEC) {
+-		long ltemp = time_phase >> (SHIFT_SCALE - 10);
++	if ((time_phase >= FINENSEC) || (time_phase <= -FINENSEC)) {
++		long ltemp = shift_right(time_phase, (SHIFT_SCALE - 10));
+ 		time_phase -= ltemp << (SHIFT_SCALE - 10);
+ 		delta_nsec += ltemp;
+ 	}
+@@ -1128,8 +1073,8 @@ fastcall signed long __sched schedule_ti
+ 		if (timeout < 0)
+ 		{
+ 			printk(KERN_ERR "schedule_timeout: wrong timeout "
+-			       "value %lx from %p\n", timeout,
+-			       __builtin_return_address(0));
++				"value %lx from %p\n", timeout,
++				__builtin_return_address(0));
+ 			current->state = TASK_RUNNING;
+ 			goto out;
+ 		}
+@@ -1137,12 +1082,8 @@ fastcall signed long __sched schedule_ti
+ 
+ 	expire = timeout + jiffies;
+ 
+-	init_timer(&timer);
+-	timer.expires = expire;
+-	timer.data = (unsigned long) current;
+-	timer.function = process_timeout;
+-
+-	add_timer(&timer);
++	setup_timer(&timer, process_timeout, (unsigned long)current);
++	__mod_timer(&timer, expire);
+ 	schedule();
+ 	del_singleshot_timer_sync(&timer);
+ 
+@@ -1159,15 +1100,15 @@ EXPORT_SYMBOL(schedule_timeout);
+  */
+ signed long __sched schedule_timeout_interruptible(signed long timeout)
+ {
+-       __set_current_state(TASK_INTERRUPTIBLE);
+-       return schedule_timeout(timeout);
++	__set_current_state(TASK_INTERRUPTIBLE);
++	return schedule_timeout(timeout);
+ }
+ EXPORT_SYMBOL(schedule_timeout_interruptible);
+ 
+ signed long __sched schedule_timeout_uninterruptible(signed long timeout)
+ {
+-       __set_current_state(TASK_UNINTERRUPTIBLE);
+-       return schedule_timeout(timeout);
++	__set_current_state(TASK_UNINTERRUPTIBLE);
++	return schedule_timeout(timeout);
+ }
+ EXPORT_SYMBOL(schedule_timeout_uninterruptible);
+ 
+@@ -1507,16 +1448,18 @@ static void time_interpolator_update(lon
+ 	if (!time_interpolator)
+ 		return;
+ 
+-	/* The interpolator compensates for late ticks by accumulating
+-         * the late time in time_interpolator->offset. A tick earlier than
+-	 * expected will lead to a reset of the offset and a corresponding
+-	 * jump of the clock forward. Again this only works if the
+-	 * interpolator clock is running slightly slower than the regular clock
+-	 * and the tuning logic insures that.
+-         */
++	/*
++	 * The interpolator compensates for late ticks by accumulating the late
++	 * time in time_interpolator->offset. A tick earlier than expected will
++	 * lead to a reset of the offset and a corresponding jump of the clock
++	 * forward. Again this only works if the interpolator clock is running
++	 * slightly slower than the regular clock and the tuning logic insures
++	 * that.
++	 */
+ 
+ 	counter = time_interpolator_get_counter(1);
+-	offset = time_interpolator->offset + GET_TI_NSECS(counter, time_interpolator);
++	offset = time_interpolator->offset +
++			GET_TI_NSECS(counter, time_interpolator);
+ 
+ 	if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)
+ 		time_interpolator->offset = offset - delta_nsec;
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -12,6 +12,8 @@
+  *   Andrew Morton <andrewm at uow.edu.au>
+  *   Kai Petzke <wpp at marie.physik.tu-berlin.de>
+  *   Theodore Ts'o <tytso at mit.edu>
++ *
++ * Made to use alloc_percpu by Christoph Lameter <clameter at sgi.com>.
+  */
+ 
+ #include <linux/module.h>
+@@ -57,7 +59,7 @@ struct cpu_workqueue_struct {
+  * per-CPU workqueues:
+  */
+ struct workqueue_struct {
+-	struct cpu_workqueue_struct cpu_wq[NR_CPUS];
++	struct cpu_workqueue_struct *cpu_wq;
+ 	const char *name;
+ 	struct list_head list; 	/* Empty if single thread */
+ };
+@@ -102,7 +104,7 @@ int fastcall queue_work(struct workqueue
+ 		if (unlikely(is_single_threaded(wq)))
+ 			cpu = 0;
+ 		BUG_ON(!list_empty(&work->entry));
+-		__queue_work(wq->cpu_wq + cpu, work);
++		__queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
+ 		ret = 1;
+ 	}
+ 	put_cpu();
+@@ -118,7 +120,7 @@ static void delayed_work_timer_fn(unsign
+ 	if (unlikely(is_single_threaded(wq)))
+ 		cpu = 0;
+ 
+-	__queue_work(wq->cpu_wq + cpu, work);
++	__queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
+ }
+ 
+ int fastcall queue_delayed_work(struct workqueue_struct *wq,
+@@ -265,13 +267,13 @@ void fastcall flush_workqueue(struct wor
+ 
+ 	if (is_single_threaded(wq)) {
+ 		/* Always use cpu 0's area. */
+-		flush_cpu_workqueue(wq->cpu_wq + 0);
++		flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, 0));
+ 	} else {
+ 		int cpu;
+ 
+ 		lock_cpu_hotplug();
+ 		for_each_online_cpu(cpu)
+-			flush_cpu_workqueue(wq->cpu_wq + cpu);
++			flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
+ 		unlock_cpu_hotplug();
+ 	}
+ }
+@@ -279,7 +281,7 @@ void fastcall flush_workqueue(struct wor
+ static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq,
+ 						   int cpu)
+ {
+-	struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
++	struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
+ 	struct task_struct *p;
+ 
+ 	spin_lock_init(&cwq->lock);
+@@ -312,6 +314,7 @@ struct workqueue_struct *__create_workqu
+ 	if (!wq)
+ 		return NULL;
+ 
++	wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct);
+ 	wq->name = name;
+ 	/* We don't need the distraction of CPUs appearing and vanishing. */
+ 	lock_cpu_hotplug();
+@@ -353,7 +356,7 @@ static void cleanup_workqueue_thread(str
+ 	unsigned long flags;
+ 	struct task_struct *p;
+ 
+-	cwq = wq->cpu_wq + cpu;
++	cwq = per_cpu_ptr(wq->cpu_wq, cpu);
+ 	spin_lock_irqsave(&cwq->lock, flags);
+ 	p = cwq->thread;
+ 	cwq->thread = NULL;
+@@ -380,6 +383,7 @@ void destroy_workqueue(struct workqueue_
+ 		spin_unlock(&workqueue_lock);
+ 	}
+ 	unlock_cpu_hotplug();
++	free_percpu(wq->cpu_wq);
+ 	kfree(wq);
+ }
+ 
+@@ -458,7 +462,7 @@ int current_is_keventd(void)
+ 
+ 	BUG_ON(!keventd_wq);
+ 
+-	cwq = keventd_wq->cpu_wq + cpu;
++	cwq = per_cpu_ptr(keventd_wq->cpu_wq, cpu);
+ 	if (current == cwq->thread)
+ 		ret = 1;
+ 
+@@ -470,7 +474,7 @@ int current_is_keventd(void)
+ /* Take the work from this (downed) CPU. */
+ static void take_over_work(struct workqueue_struct *wq, unsigned int cpu)
+ {
+-	struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
++	struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
+ 	LIST_HEAD(list);
+ 	struct work_struct *work;
+ 
+@@ -481,7 +485,7 @@ static void take_over_work(struct workqu
+ 		printk("Taking work for %s\n", wq->name);
+ 		work = list_entry(list.next,struct work_struct,entry);
+ 		list_del(&work->entry);
+-		__queue_work(wq->cpu_wq + smp_processor_id(), work);
++		__queue_work(per_cpu_ptr(wq->cpu_wq, smp_processor_id()), work);
+ 	}
+ 	spin_unlock_irq(&cwq->lock);
+ }
+@@ -508,15 +512,18 @@ static int __devinit workqueue_cpu_callb
+ 	case CPU_ONLINE:
+ 		/* Kick off worker threads. */
+ 		list_for_each_entry(wq, &workqueues, list) {
+-			kthread_bind(wq->cpu_wq[hotcpu].thread, hotcpu);
+-			wake_up_process(wq->cpu_wq[hotcpu].thread);
++			struct cpu_workqueue_struct *cwq;
++
++			cwq = per_cpu_ptr(wq->cpu_wq, hotcpu);
++			kthread_bind(cwq->thread, hotcpu);
++			wake_up_process(cwq->thread);
+ 		}
+ 		break;
+ 
+ 	case CPU_UP_CANCELED:
+ 		list_for_each_entry(wq, &workqueues, list) {
+ 			/* Unbind so it can run. */
+-			kthread_bind(wq->cpu_wq[hotcpu].thread,
++			kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread,
+ 				     smp_processor_id());
+ 			cleanup_workqueue_thread(wq, hotcpu);
+ 		}
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -128,7 +128,7 @@ config DEBUG_HIGHMEM
+ config DEBUG_BUGVERBOSE
+ 	bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
+ 	depends on BUG
+-	depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || (X86 && !X86_64) || FRV
++	depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV
+ 	default !EMBEDDED
+ 	help
+ 	  Say Y here to make BUG() panics output the file name and line number
+@@ -168,13 +168,34 @@ config DEBUG_FS
+ 
+ 	  If unsure, say N.
+ 
++config DEBUG_VM
++	bool "Debug VM"
++	depends on DEBUG_KERNEL
++	help
++	  Enable this to debug the virtual-memory system.
++
++	  If unsure, say N.
++
+ config FRAME_POINTER
+ 	bool "Compile the kernel with frame pointers"
+ 	depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML)
+ 	default y if DEBUG_INFO && UML
+ 	help
+ 	  If you say Y here the resulting kernel image will be slightly larger
+-	  and slower, but it might give very useful debugging information
+-	  on some architectures or you use external debuggers.
++	  and slower, but it might give very useful debugging information on
++	  some architectures or if you use external debuggers.
+ 	  If you don't debug the kernel, you can say N.
+ 
++config RCU_TORTURE_TEST
++	tristate "torture tests for RCU"
++	depends on DEBUG_KERNEL
++	default n
++	help
++	  This option provides a kernel module that runs torture tests
++	  on the RCU infrastructure.  The kernel module may be built
++	  after the fact on the running kernel to be tested, if desired.
++
++	  Say Y here if you want RCU torture tests to start automatically
++	  at boot time (you probably don't).
++	  Say M if you want the RCU torture tests to build as a module.
++	  Say N if you are unsure.
+diff --git a/lib/bitmap.c b/lib/bitmap.c
+--- a/lib/bitmap.c
++++ b/lib/bitmap.c
+@@ -511,6 +511,172 @@ int bitmap_parselist(const char *bp, uns
+ }
+ EXPORT_SYMBOL(bitmap_parselist);
+ 
++/*
++ * bitmap_pos_to_ord(buf, pos, bits)
++ *	@buf: pointer to a bitmap
++ *	@pos: a bit position in @buf (0 <= @pos < @bits)
++ *	@bits: number of valid bit positions in @buf
++ *
++ * Map the bit at position @pos in @buf (of length @bits) to the
++ * ordinal of which set bit it is.  If it is not set or if @pos
++ * is not a valid bit position, map to zero (0).
++ *
++ * If for example, just bits 4 through 7 are set in @buf, then @pos
++ * values 4 through 7 will get mapped to 0 through 3, respectively,
++ * and other @pos values will get mapped to 0.  When @pos value 7
++ * gets mapped to (returns) @ord value 3 in this example, that means
++ * that bit 7 is the 3rd (starting with 0th) set bit in @buf.
++ *
++ * The bit positions 0 through @bits are valid positions in @buf.
++ */
++static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
++{
++	int ord = 0;
++
++	if (pos >= 0 && pos < bits) {
++		int i;
++
++		for (i = find_first_bit(buf, bits);
++		     i < pos;
++		     i = find_next_bit(buf, bits, i + 1))
++	     		ord++;
++		if (i > pos)
++			ord = 0;
++	}
++	return ord;
++}
++
++/**
++ * bitmap_ord_to_pos(buf, ord, bits)
++ *	@buf: pointer to bitmap
++ *	@ord: ordinal bit position (n-th set bit, n >= 0)
++ *	@bits: number of valid bit positions in @buf
++ *
++ * Map the ordinal offset of bit @ord in @buf to its position in @buf.
++ * If @ord is not the ordinal offset of a set bit in @buf, map to zero (0).
++ *
++ * If for example, just bits 4 through 7 are set in @buf, then @ord
++ * values 0 through 3 will get mapped to 4 through 7, respectively,
++ * and all other @ord valuds will get mapped to 0.  When @ord value 3
++ * gets mapped to (returns) @pos value 7 in this example, that means
++ * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
++ *
++ * The bit positions 0 through @bits are valid positions in @buf.
++ */
++static int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
++{
++	int pos = 0;
++
++	if (ord >= 0 && ord < bits) {
++		int i;
++
++		for (i = find_first_bit(buf, bits);
++		     i < bits && ord > 0;
++		     i = find_next_bit(buf, bits, i + 1))
++	     		ord--;
++		if (i < bits && ord == 0)
++			pos = i;
++	}
++
++	return pos;
++}
++
++/**
++ * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
++ *	@src: subset to be remapped
++ *	@dst: remapped result
++ *	@old: defines domain of map
++ *	@new: defines range of map
++ *	@bits: number of bits in each of these bitmaps
++ *
++ * Let @old and @new define a mapping of bit positions, such that
++ * whatever position is held by the n-th set bit in @old is mapped
++ * to the n-th set bit in @new.  In the more general case, allowing
++ * for the possibility that the weight 'w' of @new is less than the
++ * weight of @old, map the position of the n-th set bit in @old to
++ * the position of the m-th set bit in @new, where m == n % w.
++ *
++ * If either of the @old and @new bitmaps are empty, or if at src and @dst
++ * point to the same location, then this routine does nothing.
++ *
++ * The positions of unset bits in @old are mapped to the position of
++ * the first set bit in @new.
++ *
++ * Apply the above specified mapping to @src, placing the result in
++ * @dst, clearing any bits previously set in @dst.
++ *
++ * The resulting value of @dst will have either the same weight as
++ * @src, or less weight in the general case that the mapping wasn't
++ * injective due to the weight of @new being less than that of @old.
++ * The resulting value of @dst will never have greater weight than
++ * that of @src, except perhaps in the case that one of the above
++ * conditions was not met and this routine just returned.
++ *
++ * For example, lets say that @old has bits 4 through 7 set, and
++ * @new has bits 12 through 15 set.  This defines the mapping of bit
++ * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
++ * bit positions to 12 (the first set bit in @new.  So if say @src
++ * comes into this routine with bits 1, 5 and 7 set, then @dst should
++ * leave with bits 12, 13 and 15 set.
++ */
++void bitmap_remap(unsigned long *dst, const unsigned long *src,
++		const unsigned long *old, const unsigned long *new,
++		int bits)
++{
++	int s;
++
++	if (bitmap_weight(old, bits) == 0)
++		return;
++	if (bitmap_weight(new, bits) == 0)
++		return;
++	if (dst == src)		/* following doesn't handle inplace remaps */
++		return;
++
++	bitmap_zero(dst, bits);
++	for (s = find_first_bit(src, bits);
++	     s < bits;
++	     s = find_next_bit(src, bits, s + 1)) {
++	     	int x = bitmap_pos_to_ord(old, s, bits);
++		int y = bitmap_ord_to_pos(new, x, bits);
++		set_bit(y, dst);
++	}
++}
++EXPORT_SYMBOL(bitmap_remap);
++
++/**
++ * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
++ *	@oldbit - bit position to be mapped
++ *      @old: defines domain of map
++ *      @new: defines range of map
++ *      @bits: number of bits in each of these bitmaps
++ *
++ * Let @old and @new define a mapping of bit positions, such that
++ * whatever position is held by the n-th set bit in @old is mapped
++ * to the n-th set bit in @new.  In the more general case, allowing
++ * for the possibility that the weight 'w' of @new is less than the
++ * weight of @old, map the position of the n-th set bit in @old to
++ * the position of the m-th set bit in @new, where m == n % w.
++ *
++ * The positions of unset bits in @old are mapped to the position of
++ * the first set bit in @new.
++ *
++ * Apply the above specified mapping to bit position @oldbit, returning
++ * the new bit position.
++ *
++ * For example, lets say that @old has bits 4 through 7 set, and
++ * @new has bits 12 through 15 set.  This defines the mapping of bit
++ * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
++ * bit positions to 12 (the first set bit in @new.  So if say @oldbit
++ * is 5, then this routine returns 13.
++ */
++int bitmap_bitremap(int oldbit, const unsigned long *old,
++				const unsigned long *new, int bits)
++{
++	int x = bitmap_pos_to_ord(old, oldbit, bits);
++	return bitmap_ord_to_pos(new, x, bits);
++}
++EXPORT_SYMBOL(bitmap_bitremap);
++
+ /**
+  *	bitmap_find_free_region - find a contiguous aligned mem region
+  *	@bitmap: an array of unsigned longs corresponding to the bitmap
+diff --git a/lib/extable.c b/lib/extable.c
+--- a/lib/extable.c
++++ b/lib/extable.c
+@@ -16,9 +16,6 @@
+ #include <linux/sort.h>
+ #include <asm/uaccess.h>
+ 
+-extern struct exception_table_entry __start___ex_table[];
+-extern struct exception_table_entry __stop___ex_table[];
+-
+ #ifndef ARCH_HAS_SORT_EXTABLE
+ /*
+  * The exception table needs to be sorted so that the binary
+diff --git a/lib/idr.c b/lib/idr.c
+--- a/lib/idr.c
++++ b/lib/idr.c
+@@ -6,20 +6,20 @@
+  * Modified by George Anzinger to reuse immediately and to use
+  * find bit instructions.  Also removed _irq on spinlocks.
+  *
+- * Small id to pointer translation service.  
++ * Small id to pointer translation service.
+  *
+- * It uses a radix tree like structure as a sparse array indexed 
++ * It uses a radix tree like structure as a sparse array indexed
+  * by the id to obtain the pointer.  The bitmap makes allocating
+- * a new id quick.  
++ * a new id quick.
+  *
+  * You call it to allocate an id (an int) an associate with that id a
+  * pointer or what ever, we treat it as a (void *).  You can pass this
+  * id to a user for him to pass back at a later time.  You then pass
+  * that id to this code and it returns your pointer.
+ 
+- * You can release ids at any time. When all ids are released, most of 
++ * You can release ids at any time. When all ids are released, most of
+  * the memory is returned (we keep IDR_FREE_MAX) in a local pool so we
+- * don't need to go to the memory "store" during an id allocate, just 
++ * don't need to go to the memory "store" during an id allocate, just
+  * so you don't need to be too concerned about locking and conflicts
+  * with the slab allocator.
+  */
+@@ -72,12 +72,12 @@ static void free_layer(struct idr *idp, 
+  * If the system is REALLY out of memory this function returns 0,
+  * otherwise 1.
+  */
+-int idr_pre_get(struct idr *idp, unsigned gfp_mask)
++int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+ {
+ 	while (idp->id_free_cnt < IDR_FREE_MAX) {
+ 		struct idr_layer *new;
+ 		new = kmem_cache_alloc(idr_layer_cache, gfp_mask);
+-		if(new == NULL)
++		if (new == NULL)
+ 			return (0);
+ 		free_layer(idp, new);
+ 	}
+@@ -107,7 +107,7 @@ static int sub_alloc(struct idr *idp, vo
+ 		if (m == IDR_SIZE) {
+ 			/* no space available go back to previous layer. */
+ 			l++;
+-			id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
++			id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;
+ 			if (!(p = pa[l])) {
+ 				*starting_id = id;
+ 				return -2;
+@@ -161,7 +161,7 @@ static int idr_get_new_above_int(struct 
+ {
+ 	struct idr_layer *p, *new;
+ 	int layers, v, id;
+-	
++
+ 	id = starting_id;
+ build_up:
+ 	p = idp->top;
+@@ -225,6 +225,7 @@ build_up:
+ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
+ {
+ 	int rv;
++
+ 	rv = idr_get_new_above_int(idp, ptr, starting_id);
+ 	/*
+ 	 * This is a cheap hack until the IDR code can be fixed to
+@@ -259,6 +260,7 @@ EXPORT_SYMBOL(idr_get_new_above);
+ int idr_get_new(struct idr *idp, void *ptr, int *id)
+ {
+ 	int rv;
++
+ 	rv = idr_get_new_above_int(idp, ptr, 0);
+ 	/*
+ 	 * This is a cheap hack until the IDR code can be fixed to
+@@ -306,11 +308,10 @@ static void sub_remove(struct idr *idp, 
+ 			free_layer(idp, **paa);
+ 			**paa-- = NULL;
+ 		}
+-		if ( ! *paa )
++		if (!*paa)
+ 			idp->layers = 0;
+-	} else {
++	} else
+ 		idr_remove_warning(id);
+-	}
+ }
+ 
+ /**
+@@ -326,9 +327,8 @@ void idr_remove(struct idr *idp, int id)
+ 	id &= MAX_ID_MASK;
+ 
+ 	sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
+-	if ( idp->top && idp->top->count == 1 && 
+-	     (idp->layers > 1) &&
+-	     idp->top->ary[0]){  // We can drop a layer
++	if (idp->top && idp->top->count == 1 && (idp->layers > 1) &&
++	    idp->top->ary[0]) {  // We can drop a layer
+ 
+ 		p = idp->top->ary[0];
+ 		idp->top->bitmap = idp->top->count = 0;
+@@ -337,7 +337,6 @@ void idr_remove(struct idr *idp, int id)
+ 		--idp->layers;
+ 	}
+ 	while (idp->id_free_cnt >= IDR_FREE_MAX) {
+-		
+ 		p = alloc_layer(idp);
+ 		kmem_cache_free(idr_layer_cache, p);
+ 		return;
+@@ -391,8 +390,8 @@ void *idr_find(struct idr *idp, int id)
+ }
+ EXPORT_SYMBOL(idr_find);
+ 
+-static void idr_cache_ctor(void * idr_layer, 
+-			   kmem_cache_t *idr_layer_cache, unsigned long flags)
++static void idr_cache_ctor(void * idr_layer, kmem_cache_t *idr_layer_cache,
++		unsigned long flags)
+ {
+ 	memset(idr_layer, 0, sizeof(struct idr_layer));
+ }
+@@ -400,7 +399,7 @@ static void idr_cache_ctor(void * idr_la
+ static  int init_id_cache(void)
+ {
+ 	if (!idr_layer_cache)
+-		idr_layer_cache = kmem_cache_create("idr_layer_cache", 
++		idr_layer_cache = kmem_cache_create("idr_layer_cache",
+ 			sizeof(struct idr_layer), 0, 0, idr_cache_ctor, NULL);
+ 	return 0;
+ }
+diff --git a/lib/kobject.c b/lib/kobject.c
+--- a/lib/kobject.c
++++ b/lib/kobject.c
+@@ -14,6 +14,7 @@
+ #include <linux/string.h>
+ #include <linux/module.h>
+ #include <linux/stat.h>
++#include <linux/slab.h>
+ 
+ /**
+  *	populate_dir - populate directory with attributes.
+@@ -100,7 +101,7 @@ static void fill_kobj_path(struct kobjec
+  * @kobj:	kobject in question, with which to build the path
+  * @gfp_mask:	the allocation type used to allocate the path
+  */
+-char *kobject_get_path(struct kobject *kobj, int gfp_mask)
++char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
+ {
+ 	char *path;
+ 	int len;
+diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
+--- a/lib/kobject_uevent.c
++++ b/lib/kobject_uevent.c
+@@ -54,7 +54,7 @@ static char *action_to_string(enum kobje
+ static struct sock *uevent_sock;
+ 
+ /**
+- * send_uevent - notify userspace by sending event trough netlink socket
++ * send_uevent - notify userspace by sending event through netlink socket
+  *
+  * @signal: signal name
+  * @obj: object path (kobject)
+@@ -62,7 +62,7 @@ static struct sock *uevent_sock;
+  * @gfp_mask:
+  */
+ static int send_uevent(const char *signal, const char *obj,
+-		       char **envp, int gfp_mask)
++		       char **envp, gfp_t gfp_mask)
+ {
+ 	struct sk_buff *skb;
+ 	char *pos;
+@@ -98,7 +98,7 @@ static int send_uevent(const char *signa
+ }
+ 
+ static int do_kobject_uevent(struct kobject *kobj, enum kobject_action action, 
+-			     struct attribute *attr, int gfp_mask)
++			     struct attribute *attr, gfp_t gfp_mask)
+ {
+ 	char *path;
+ 	char *attrpath;
+diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
+--- a/lib/smp_processor_id.c
++++ b/lib/smp_processor_id.c
+@@ -5,6 +5,7 @@
+  */
+ #include <linux/module.h>
+ #include <linux/kallsyms.h>
++#include <linux/sched.h>
+ 
+ unsigned int debug_smp_processor_id(void)
+ {
+diff --git a/lib/sort.c b/lib/sort.c
+--- a/lib/sort.c
++++ b/lib/sort.c
+@@ -7,6 +7,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/sort.h>
++#include <linux/slab.h>
+ 
+ static void u32_swap(void *a, void *b, int size)
+ {
+diff --git a/lib/string.c b/lib/string.c
+--- a/lib/string.c
++++ b/lib/string.c
+@@ -36,11 +36,13 @@ int strnicmp(const char *s1, const char 
+ 	/* Yes, Virginia, it had better be unsigned */
+ 	unsigned char c1, c2;
+ 
+-	c1 = 0;	c2 = 0;
++	c1 = c2 = 0;
+ 	if (len) {
+ 		do {
+-			c1 = *s1; c2 = *s2;
+-			s1++; s2++;
++			c1 = *s1;
++			c2 = *s2;
++			s1++;
++			s2++;
+ 			if (!c1)
+ 				break;
+ 			if (!c2)
+@@ -55,7 +57,6 @@ int strnicmp(const char *s1, const char 
+ 	}
+ 	return (int)c1 - (int)c2;
+ }
+-
+ EXPORT_SYMBOL(strnicmp);
+ #endif
+ 
+@@ -66,7 +67,7 @@ EXPORT_SYMBOL(strnicmp);
+  * @src: Where to copy the string from
+  */
+ #undef strcpy
+-char * strcpy(char * dest,const char *src)
++char *strcpy(char *dest, const char *src)
+ {
+ 	char *tmp = dest;
+ 
+@@ -91,12 +92,13 @@ EXPORT_SYMBOL(strcpy);
+  * count, the remainder of @dest will be padded with %NUL.
+  *
+  */
+-char * strncpy(char * dest,const char *src,size_t count)
++char *strncpy(char *dest, const char *src, size_t count)
+ {
+ 	char *tmp = dest;
+ 
+ 	while (count) {
+-		if ((*tmp = *src) != 0) src++;
++		if ((*tmp = *src) != 0)
++			src++;
+ 		tmp++;
+ 		count--;
+ 	}
+@@ -122,7 +124,7 @@ size_t strlcpy(char *dest, const char *s
+ 	size_t ret = strlen(src);
+ 
+ 	if (size) {
+-		size_t len = (ret >= size) ? size-1 : ret;
++		size_t len = (ret >= size) ? size - 1 : ret;
+ 		memcpy(dest, src, len);
+ 		dest[len] = '\0';
+ 	}
+@@ -138,7 +140,7 @@ EXPORT_SYMBOL(strlcpy);
+  * @src: The string to append to it
+  */
+ #undef strcat
+-char * strcat(char * dest, const char * src)
++char *strcat(char *dest, const char *src)
+ {
+ 	char *tmp = dest;
+ 
+@@ -146,7 +148,6 @@ char * strcat(char * dest, const char * 
+ 		dest++;
+ 	while ((*dest++ = *src++) != '\0')
+ 		;
+-
+ 	return tmp;
+ }
+ EXPORT_SYMBOL(strcat);
+@@ -162,7 +163,7 @@ EXPORT_SYMBOL(strcat);
+  * Note that in contrast to strncpy, strncat ensures the result is
+  * terminated.
+  */
+-char * strncat(char *dest, const char *src, size_t count)
++char *strncat(char *dest, const char *src, size_t count)
+ {
+ 	char *tmp = dest;
+ 
+@@ -176,7 +177,6 @@ char * strncat(char *dest, const char *s
+ 			}
+ 		}
+ 	}
+-
+ 	return tmp;
+ }
+ EXPORT_SYMBOL(strncat);
+@@ -216,15 +216,14 @@ EXPORT_SYMBOL(strlcat);
+  * @ct: Another string
+  */
+ #undef strcmp
+-int strcmp(const char * cs,const char * ct)
++int strcmp(const char *cs, const char *ct)
+ {
+-	register signed char __res;
++	signed char __res;
+ 
+ 	while (1) {
+ 		if ((__res = *cs - *ct++) != 0 || !*cs++)
+ 			break;
+ 	}
+-
+ 	return __res;
+ }
+ EXPORT_SYMBOL(strcmp);
+@@ -237,16 +236,15 @@ EXPORT_SYMBOL(strcmp);
+  * @ct: Another string
+  * @count: The maximum number of bytes to compare
+  */
+-int strncmp(const char * cs,const char * ct,size_t count)
++int strncmp(const char *cs, const char *ct, size_t count)
+ {
+-	register signed char __res = 0;
++	signed char __res = 0;
+ 
+ 	while (count) {
+ 		if ((__res = *cs - *ct++) != 0 || !*cs++)
+ 			break;
+ 		count--;
+ 	}
+-
+ 	return __res;
+ }
+ EXPORT_SYMBOL(strncmp);
+@@ -258,12 +256,12 @@ EXPORT_SYMBOL(strncmp);
+  * @s: The string to be searched
+  * @c: The character to search for
+  */
+-char * strchr(const char * s, int c)
++char *strchr(const char *s, int c)
+ {
+-	for(; *s != (char) c; ++s)
++	for (; *s != (char)c; ++s)
+ 		if (*s == '\0')
+ 			return NULL;
+-	return (char *) s;
++	return (char *)s;
+ }
+ EXPORT_SYMBOL(strchr);
+ #endif
+@@ -274,7 +272,7 @@ EXPORT_SYMBOL(strchr);
+  * @s: The string to be searched
+  * @c: The character to search for
+  */
+-char * strrchr(const char * s, int c)
++char *strrchr(const char *s, int c)
+ {
+        const char *p = s + strlen(s);
+        do {
+@@ -296,8 +294,8 @@ EXPORT_SYMBOL(strrchr);
+ char *strnchr(const char *s, size_t count, int c)
+ {
+ 	for (; count-- && *s != '\0'; ++s)
+-		if (*s == (char) c)
+-			return (char *) s;
++		if (*s == (char)c)
++			return (char *)s;
+ 	return NULL;
+ }
+ EXPORT_SYMBOL(strnchr);
+@@ -308,7 +306,7 @@ EXPORT_SYMBOL(strnchr);
+  * strlen - Find the length of a string
+  * @s: The string to be sized
+  */
+-size_t strlen(const char * s)
++size_t strlen(const char *s)
+ {
+ 	const char *sc;
+ 
+@@ -325,7 +323,7 @@ EXPORT_SYMBOL(strlen);
+  * @s: The string to be sized
+  * @count: The maximum number of bytes to search
+  */
+-size_t strnlen(const char * s, size_t count)
++size_t strnlen(const char *s, size_t count)
+ {
+ 	const char *sc;
+ 
+@@ -358,7 +356,6 @@ size_t strspn(const char *s, const char 
+ 			return count;
+ 		++count;
+ 	}
+-
+ 	return count;
+ }
+ 
+@@ -384,9 +381,8 @@ size_t strcspn(const char *s, const char
+ 		}
+ 		++count;
+ 	}
+-
+ 	return count;
+-}	
++}
+ EXPORT_SYMBOL(strcspn);
+ 
+ #ifndef __HAVE_ARCH_STRPBRK
+@@ -395,14 +391,14 @@ EXPORT_SYMBOL(strcspn);
+  * @cs: The string to be searched
+  * @ct: The characters to search for
+  */
+-char * strpbrk(const char * cs,const char * ct)
++char *strpbrk(const char *cs, const char *ct)
+ {
+-	const char *sc1,*sc2;
++	const char *sc1, *sc2;
+ 
+-	for( sc1 = cs; *sc1 != '\0'; ++sc1) {
+-		for( sc2 = ct; *sc2 != '\0'; ++sc2) {
++	for (sc1 = cs; *sc1 != '\0'; ++sc1) {
++		for (sc2 = ct; *sc2 != '\0'; ++sc2) {
+ 			if (*sc1 == *sc2)
+-				return (char *) sc1;
++				return (char *)sc1;
+ 		}
+ 	}
+ 	return NULL;
+@@ -422,9 +418,10 @@ EXPORT_SYMBOL(strpbrk);
+  * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
+  * Same semantics, slimmer shape. ;)
+  */
+-char * strsep(char **s, const char *ct)
++char *strsep(char **s, const char *ct)
+ {
+-	char *sbegin = *s, *end;
++	char *sbegin = *s;
++	char *end;
+ 
+ 	if (sbegin == NULL)
+ 		return NULL;
+@@ -433,10 +430,8 @@ char * strsep(char **s, const char *ct)
+ 	if (end)
+ 		*end++ = '\0';
+ 	*s = end;
+-
+ 	return sbegin;
+ }
+-
+ EXPORT_SYMBOL(strsep);
+ #endif
+ 
+@@ -449,13 +444,12 @@ EXPORT_SYMBOL(strsep);
+  *
+  * Do not use memset() to access IO space, use memset_io() instead.
+  */
+-void * memset(void * s,int c,size_t count)
++void *memset(void *s, int c, size_t count)
+ {
+-	char *xs = (char *) s;
++	char *xs = s;
+ 
+ 	while (count--)
+ 		*xs++ = c;
+-
+ 	return s;
+ }
+ EXPORT_SYMBOL(memset);
+@@ -471,13 +465,13 @@ EXPORT_SYMBOL(memset);
+  * You should not use this function to access IO space, use memcpy_toio()
+  * or memcpy_fromio() instead.
+  */
+-void * memcpy(void * dest,const void *src,size_t count)
++void *memcpy(void *dest, const void *src, size_t count)
+ {
+-	char *tmp = (char *) dest, *s = (char *) src;
++	char *tmp = dest;
++	char *s = src;
+ 
+ 	while (count--)
+ 		*tmp++ = *s++;
+-
+ 	return dest;
+ }
+ EXPORT_SYMBOL(memcpy);
+@@ -492,23 +486,24 @@ EXPORT_SYMBOL(memcpy);
+  *
+  * Unlike memcpy(), memmove() copes with overlapping areas.
+  */
+-void * memmove(void * dest,const void *src,size_t count)
++void *memmove(void *dest, const void *src, size_t count)
+ {
+-	char *tmp, *s;
++	char *tmp;
++	const char *s;
+ 
+ 	if (dest <= src) {
+-		tmp = (char *) dest;
+-		s = (char *) src;
++		tmp = dest;
++		s = src;
+ 		while (count--)
+ 			*tmp++ = *s++;
+-		}
+-	else {
+-		tmp = (char *) dest + count;
+-		s = (char *) src + count;
++	} else {
++		tmp = dest;
++		tmp += count;
++		s = src;
++		s += count;
+ 		while (count--)
+ 			*--tmp = *--s;
+-		}
+-
++	}
+ 	return dest;
+ }
+ EXPORT_SYMBOL(memmove);
+@@ -522,12 +517,12 @@ EXPORT_SYMBOL(memmove);
+  * @count: The size of the area.
+  */
+ #undef memcmp
+-int memcmp(const void * cs,const void * ct,size_t count)
++int memcmp(const void *cs, const void *ct, size_t count)
+ {
+ 	const unsigned char *su1, *su2;
+ 	int res = 0;
+ 
+-	for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
++	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+ 		if ((res = *su1 - *su2) != 0)
+ 			break;
+ 	return res;
+@@ -545,17 +540,17 @@ EXPORT_SYMBOL(memcmp);
+  * returns the address of the first occurrence of @c, or 1 byte past
+  * the area if @c is not found
+  */
+-void * memscan(void * addr, int c, size_t size)
++void *memscan(void *addr, int c, size_t size)
+ {
+-	unsigned char * p = (unsigned char *) addr;
++	unsigned char *p = addr;
+ 
+ 	while (size) {
+ 		if (*p == c)
+-			return (void *) p;
++			return (void *)p;
+ 		p++;
+ 		size--;
+ 	}
+-  	return (void *) p;
++  	return (void *)p;
+ }
+ EXPORT_SYMBOL(memscan);
+ #endif
+@@ -566,18 +561,18 @@ EXPORT_SYMBOL(memscan);
+  * @s1: The string to be searched
+  * @s2: The string to search for
+  */
+-char * strstr(const char * s1,const char * s2)
++char *strstr(const char *s1, const char *s2)
+ {
+ 	int l1, l2;
+ 
+ 	l2 = strlen(s2);
+ 	if (!l2)
+-		return (char *) s1;
++		return (char *)s1;
+ 	l1 = strlen(s1);
+ 	while (l1 >= l2) {
+ 		l1--;
+-		if (!memcmp(s1,s2,l2))
+-			return (char *) s1;
++		if (!memcmp(s1, s2, l2))
++			return (char *)s1;
+ 		s1++;
+ 	}
+ 	return NULL;
+@@ -600,7 +595,7 @@ void *memchr(const void *s, int c, size_
+ 	const unsigned char *p = s;
+ 	while (n-- != 0) {
+         	if ((unsigned char)c == *p++) {
+-			return (void *)(p-1);
++			return (void *)(p - 1);
+ 		}
+ 	}
+ 	return NULL;
+diff --git a/lib/textsearch.c b/lib/textsearch.c
+--- a/lib/textsearch.c
++++ b/lib/textsearch.c
+@@ -254,7 +254,7 @@ unsigned int textsearch_find_continuous(
+  *         parameters or a ERR_PTR().
+  */
+ struct ts_config *textsearch_prepare(const char *algo, const void *pattern,
+-				     unsigned int len, int gfp_mask, int flags)
++				     unsigned int len, gfp_t gfp_mask, int flags)
+ {
+ 	int err = -ENOENT;
+ 	struct ts_config *conf;
+diff --git a/lib/vsprintf.c b/lib/vsprintf.c
+--- a/lib/vsprintf.c
++++ b/lib/vsprintf.c
+@@ -23,6 +23,7 @@
+ #include <linux/ctype.h>
+ #include <linux/kernel.h>
+ 
++#include <asm/page.h>		/* for PAGE_SIZE */
+ #include <asm/div64.h>
+ 
+ /**
+diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
+--- a/lib/zlib_inflate/inflate.c
++++ b/lib/zlib_inflate/inflate.c
+@@ -3,7 +3,6 @@
+  * For conditions of distribution and use, see copyright notice in zlib.h 
+  */
+ 
+-#include <linux/module.h>
+ #include <linux/zutil.h>
+ #include "infblock.h"
+ #include "infutil.h"
+diff --git a/mm/Kconfig b/mm/Kconfig
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -111,3 +111,24 @@ config SPARSEMEM_STATIC
+ config SPARSEMEM_EXTREME
+ 	def_bool y
+ 	depends on SPARSEMEM && !SPARSEMEM_STATIC
++
++# eventually, we can have this option just 'select SPARSEMEM'
++config MEMORY_HOTPLUG
++	bool "Allow for memory hot-add"
++	depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND
++
++comment "Memory hotplug is currently incompatible with Software Suspend"
++	depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND
++
++# Heavily threaded applications may benefit from splitting the mm-wide
++# page_table_lock, so that faults on different parts of the user address
++# space can be handled with less contention: split it at this NR_CPUS.
++# Default to 4 for wider testing, though 8 might be more appropriate.
++# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
++# PA-RISC's debug spinlock_t is too large for the 32-bit struct page.
++#
++config SPLIT_PTLOCK_CPUS
++	int
++	default "4096" if ARM && !CPU_CACHE_VIPT
++	default "4096" if PARISC && DEBUG_SPINLOCK && !64BIT
++	default "4"
+diff --git a/mm/Makefile b/mm/Makefile
+--- a/mm/Makefile
++++ b/mm/Makefile
+@@ -18,5 +18,5 @@ obj-$(CONFIG_NUMA) 	+= mempolicy.o
+ obj-$(CONFIG_SPARSEMEM)	+= sparse.o
+ obj-$(CONFIG_SHMEM) += shmem.o
+ obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
+-
++obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
+ obj-$(CONFIG_FS_XIP) += filemap_xip.o
+diff --git a/mm/bootmem.c b/mm/bootmem.c
+--- a/mm/bootmem.c
++++ b/mm/bootmem.c
+@@ -305,6 +305,7 @@ static unsigned long __init free_all_boo
+ 				if (j + 16 < BITS_PER_LONG)
+ 					prefetchw(page + j + 16);
+ 				__ClearPageReserved(page + j);
++				set_page_count(page + j, 0);
+ 			}
+ 			__free_pages(page, order);
+ 			i += BITS_PER_LONG;
+diff --git a/mm/filemap.c b/mm/filemap.c
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -66,7 +66,7 @@ generic_file_direct_IO(int rw, struct ki
+  *
+  *  ->mmap_sem
+  *    ->i_mmap_lock
+- *      ->page_table_lock	(various places, mainly in mmap.c)
++ *      ->page_table_lock or pte_lock	(various, mainly in memory.c)
+  *        ->mapping->tree_lock	(arch-dependent flush_dcache_mmap_lock)
+  *
+  *  ->mmap_sem
+@@ -86,9 +86,9 @@ generic_file_direct_IO(int rw, struct ki
+  *    ->anon_vma.lock		(vma_adjust)
+  *
+  *  ->anon_vma.lock
+- *    ->page_table_lock		(anon_vma_prepare and various)
++ *    ->page_table_lock or pte_lock	(anon_vma_prepare and various)
+  *
+- *  ->page_table_lock
++ *  ->page_table_lock or pte_lock
+  *    ->swap_lock		(try_to_unmap_one)
+  *    ->private_lock		(try_to_unmap_one)
+  *    ->tree_lock		(try_to_unmap_one)
+@@ -152,7 +152,7 @@ static int sync_page(void *word)
+ 	 * in the ->sync_page() methods make essential use of the
+ 	 * page_mapping(), merely passing the page down to the backing
+ 	 * device's unplug functions when it's non-NULL, which in turn
+-	 * ignore it for all cases but swap, where only page->private is
++	 * ignore it for all cases but swap, where only page_private(page) is
+ 	 * of interest. When page_mapping() does go NULL, the entire
+ 	 * call stack gracefully ignores the page and returns.
+ 	 * -- wli
+@@ -377,7 +377,7 @@ int filemap_write_and_wait_range(struct 
+  * This function does not add the page to the LRU.  The caller must do that.
+  */
+ int add_to_page_cache(struct page *page, struct address_space *mapping,
+-		pgoff_t offset, int gfp_mask)
++		pgoff_t offset, gfp_t gfp_mask)
+ {
+ 	int error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);
+ 
+@@ -401,7 +401,7 @@ int add_to_page_cache(struct page *page,
+ EXPORT_SYMBOL(add_to_page_cache);
+ 
+ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
+-				pgoff_t offset, int gfp_mask)
++				pgoff_t offset, gfp_t gfp_mask)
+ {
+ 	int ret = add_to_page_cache(page, mapping, offset, gfp_mask);
+ 	if (ret == 0)
+@@ -591,7 +591,7 @@ EXPORT_SYMBOL(find_lock_page);
+  * memory exhaustion.
+  */
+ struct page *find_or_create_page(struct address_space *mapping,
+-		unsigned long index, unsigned int gfp_mask)
++		unsigned long index, gfp_t gfp_mask)
+ {
+ 	struct page *page, *cached_page = NULL;
+ 	int err;
+@@ -683,7 +683,7 @@ struct page *
+ grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
+ {
+ 	struct page *page = find_get_page(mapping, index);
+-	unsigned int gfp_mask;
++	gfp_t gfp_mask;
+ 
+ 	if (page) {
+ 		if (!TestSetPageLocked(page))
+@@ -1030,8 +1030,8 @@ __generic_file_aio_read(struct kiocb *io
+ 			desc.error = 0;
+ 			do_generic_file_read(filp,ppos,&desc,file_read_actor);
+ 			retval += desc.written;
+-			if (!retval) {
+-				retval = desc.error;
++			if (desc.error) {
++				retval = retval ?: desc.error;
+ 				break;
+ 			}
+ 		}
+@@ -1520,7 +1520,7 @@ repeat:
+ 			page_cache_release(page);
+ 			return err;
+ 		}
+-	} else {
++	} else if (vma->vm_flags & VM_NONLINEAR) {
+ 		/* No page was found just because we can't read it in now (being
+ 		 * here implies nonblock != 0), but the page may exist, so set
+ 		 * the PTE to fault it in later. */
+@@ -1537,6 +1537,7 @@ repeat:
+ 
+ 	return 0;
+ }
++EXPORT_SYMBOL(filemap_populate);
+ 
+ struct vm_operations_struct generic_file_vm_ops = {
+ 	.nopage		= filemap_nopage,
+@@ -1555,7 +1556,6 @@ int generic_file_mmap(struct file * file
+ 	vma->vm_ops = &generic_file_vm_ops;
+ 	return 0;
+ }
+-EXPORT_SYMBOL(filemap_populate);
+ 
+ /*
+  * This is for filesystems which do not implement ->writepage.
+diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
+--- a/mm/filemap_xip.c
++++ b/mm/filemap_xip.c
+@@ -174,6 +174,8 @@ __xip_unmap (struct address_space * mapp
+ 	unsigned long address;
+ 	pte_t *pte;
+ 	pte_t pteval;
++	spinlock_t *ptl;
++	struct page *page;
+ 
+ 	spin_lock(&mapping->i_mmap_lock);
+ 	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+@@ -181,19 +183,17 @@ __xip_unmap (struct address_space * mapp
+ 		address = vma->vm_start +
+ 			((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
+ 		BUG_ON(address < vma->vm_start || address >= vma->vm_end);
+-		/*
+-		 * We need the page_table_lock to protect us from page faults,
+-		 * munmap, fork, etc...
+-		 */
+-		pte = page_check_address(ZERO_PAGE(address), mm,
+-					 address);
+-		if (!IS_ERR(pte)) {
++		page = ZERO_PAGE(address);
++		pte = page_check_address(page, mm, address, &ptl);
++		if (pte) {
+ 			/* Nuke the page table entry. */
+ 			flush_cache_page(vma, address, pte_pfn(*pte));
+ 			pteval = ptep_clear_flush(vma, address, pte);
++			page_remove_rmap(page);
++			dec_mm_counter(mm, file_rss);
+ 			BUG_ON(pte_dirty(pteval));
+-			pte_unmap(pte);
+-			spin_unlock(&mm->page_table_lock);
++			pte_unmap_unlock(pte, ptl);
++			page_cache_release(page);
+ 		}
+ 	}
+ 	spin_unlock(&mapping->i_mmap_lock);
+@@ -228,7 +228,7 @@ xip_file_nopage(struct vm_area_struct * 
+ 
+ 	page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);
+ 	if (!IS_ERR(page)) {
+-		return page;
++		goto out;
+ 	}
+ 	if (PTR_ERR(page) != -ENODATA)
+ 		return NULL;
+@@ -249,6 +249,8 @@ xip_file_nopage(struct vm_area_struct * 
+ 		page = ZERO_PAGE(address);
+ 	}
+ 
++out:
++	page_cache_get(page);
+ 	return page;
+ }
+ 
+diff --git a/mm/fremap.c b/mm/fremap.c
+--- a/mm/fremap.c
++++ b/mm/fremap.c
+@@ -20,33 +20,32 @@
+ #include <asm/cacheflush.h>
+ #include <asm/tlbflush.h>
+ 
+-static inline void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
++static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
+ 			unsigned long addr, pte_t *ptep)
+ {
+ 	pte_t pte = *ptep;
++	struct page *page = NULL;
+ 
+-	if (pte_none(pte))
+-		return;
+ 	if (pte_present(pte)) {
+ 		unsigned long pfn = pte_pfn(pte);
+-
+ 		flush_cache_page(vma, addr, pfn);
+ 		pte = ptep_clear_flush(vma, addr, ptep);
+-		if (pfn_valid(pfn)) {
+-			struct page *page = pfn_to_page(pfn);
+-			if (!PageReserved(page)) {
+-				if (pte_dirty(pte))
+-					set_page_dirty(page);
+-				page_remove_rmap(page);
+-				page_cache_release(page);
+-				dec_mm_counter(mm, rss);
+-			}
++		if (unlikely(!pfn_valid(pfn))) {
++			print_bad_pte(vma, pte, addr);
++			goto out;
+ 		}
++		page = pfn_to_page(pfn);
++		if (pte_dirty(pte))
++			set_page_dirty(page);
++		page_remove_rmap(page);
++		page_cache_release(page);
+ 	} else {
+ 		if (!pte_file(pte))
+ 			free_swap_and_cache(pte_to_swp_entry(pte));
+ 		pte_clear(mm, addr, ptep);
+ 	}
++out:
++	return !!page;
+ }
+ 
+ /*
+@@ -64,21 +63,20 @@ int install_page(struct mm_struct *mm, s
+ 	pud_t *pud;
+ 	pgd_t *pgd;
+ 	pte_t pte_val;
++	spinlock_t *ptl;
++
++	BUG_ON(vma->vm_flags & VM_RESERVED);
+ 
+ 	pgd = pgd_offset(mm, addr);
+-	spin_lock(&mm->page_table_lock);
+-	
+ 	pud = pud_alloc(mm, pgd, addr);
+ 	if (!pud)
+-		goto err_unlock;
+-
++		goto out;
+ 	pmd = pmd_alloc(mm, pud, addr);
+ 	if (!pmd)
+-		goto err_unlock;
+-
+-	pte = pte_alloc_map(mm, pmd, addr);
++		goto out;
++	pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
+ 	if (!pte)
+-		goto err_unlock;
++		goto out;
+ 
+ 	/*
+ 	 * This page may have been truncated. Tell the
+@@ -88,29 +86,27 @@ int install_page(struct mm_struct *mm, s
+ 	inode = vma->vm_file->f_mapping->host;
+ 	size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+ 	if (!page->mapping || page->index >= size)
+-		goto err_unlock;
++		goto unlock;
+ 	err = -ENOMEM;
+ 	if (page_mapcount(page) > INT_MAX/2)
+-		goto err_unlock;
++		goto unlock;
+ 
+-	zap_pte(mm, vma, addr, pte);
++	if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
++		inc_mm_counter(mm, file_rss);
+ 
+-	inc_mm_counter(mm,rss);
+ 	flush_icache_page(vma, page);
+ 	set_pte_at(mm, addr, pte, mk_pte(page, prot));
+ 	page_add_file_rmap(page);
+ 	pte_val = *pte;
+-	pte_unmap(pte);
+ 	update_mmu_cache(vma, addr, pte_val);
+-
+ 	err = 0;
+-err_unlock:
+-	spin_unlock(&mm->page_table_lock);
++unlock:
++	pte_unmap_unlock(pte, ptl);
++out:
+ 	return err;
+ }
+ EXPORT_SYMBOL(install_page);
+ 
+-
+ /*
+  * Install a file pte to a given virtual memory address, release any
+  * previously existing mapping.
+@@ -124,37 +120,35 @@ int install_file_pte(struct mm_struct *m
+ 	pud_t *pud;
+ 	pgd_t *pgd;
+ 	pte_t pte_val;
++	spinlock_t *ptl;
++
++	BUG_ON(vma->vm_flags & VM_RESERVED);
+ 
+ 	pgd = pgd_offset(mm, addr);
+-	spin_lock(&mm->page_table_lock);
+-	
+ 	pud = pud_alloc(mm, pgd, addr);
+ 	if (!pud)
+-		goto err_unlock;
+-
++		goto out;
+ 	pmd = pmd_alloc(mm, pud, addr);
+ 	if (!pmd)
+-		goto err_unlock;
+-
+-	pte = pte_alloc_map(mm, pmd, addr);
++		goto out;
++	pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
+ 	if (!pte)
+-		goto err_unlock;
++		goto out;
+ 
+-	zap_pte(mm, vma, addr, pte);
++	if (!pte_none(*pte) && zap_pte(mm, vma, addr, pte)) {
++		update_hiwater_rss(mm);
++		dec_mm_counter(mm, file_rss);
++	}
+ 
+ 	set_pte_at(mm, addr, pte, pgoff_to_pte(pgoff));
+ 	pte_val = *pte;
+-	pte_unmap(pte);
+ 	update_mmu_cache(vma, addr, pte_val);
+-	spin_unlock(&mm->page_table_lock);
+-	return 0;
+-
+-err_unlock:
+-	spin_unlock(&mm->page_table_lock);
++	pte_unmap_unlock(pte, ptl);
++	err = 0;
++out:
+ 	return err;
+ }
+ 
+-
+ /***
+  * sys_remap_file_pages - remap arbitrary pages of a shared backing store
+  *                        file within an existing vma.
+diff --git a/mm/highmem.c b/mm/highmem.c
+--- a/mm/highmem.c
++++ b/mm/highmem.c
+@@ -30,11 +30,9 @@
+ 
+ static mempool_t *page_pool, *isa_page_pool;
+ 
+-static void *page_pool_alloc(gfp_t gfp_mask, void *data)
++static void *page_pool_alloc_isa(gfp_t gfp_mask, void *data)
+ {
+-	unsigned int gfp = gfp_mask | (unsigned int) (long) data;
+-
+-	return alloc_page(gfp);
++	return alloc_page(gfp_mask | GFP_DMA);
+ }
+ 
+ static void page_pool_free(void *page, void *data)
+@@ -51,6 +49,12 @@ static void page_pool_free(void *page, v
+  *  n means that there are (n-1) current users of it.
+  */
+ #ifdef CONFIG_HIGHMEM
++
++static void *page_pool_alloc(gfp_t gfp_mask, void *data)
++{
++	return alloc_page(gfp_mask);
++}
++
+ static int pkmap_count[LAST_PKMAP];
+ static unsigned int last_pkmap_nr;
+ static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(kmap_lock);
+@@ -267,7 +271,7 @@ int init_emergency_isa_pool(void)
+ 	if (isa_page_pool)
+ 		return 0;
+ 
+-	isa_page_pool = mempool_create(ISA_POOL_SIZE, page_pool_alloc, page_pool_free, (void *) __GFP_DMA);
++	isa_page_pool = mempool_create(ISA_POOL_SIZE, page_pool_alloc_isa, page_pool_free, NULL);
+ 	if (!isa_page_pool)
+ 		BUG();
+ 
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -277,19 +277,23 @@ int copy_hugetlb_page_range(struct mm_st
+ 	unsigned long addr;
+ 
+ 	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
++		src_pte = huge_pte_offset(src, addr);
++		if (!src_pte)
++			continue;
+ 		dst_pte = huge_pte_alloc(dst, addr);
+ 		if (!dst_pte)
+ 			goto nomem;
++		spin_lock(&dst->page_table_lock);
+ 		spin_lock(&src->page_table_lock);
+-		src_pte = huge_pte_offset(src, addr);
+-		if (src_pte && !pte_none(*src_pte)) {
++		if (!pte_none(*src_pte)) {
+ 			entry = *src_pte;
+ 			ptepage = pte_page(entry);
+ 			get_page(ptepage);
+-			add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
++			add_mm_counter(dst, file_rss, HPAGE_SIZE / PAGE_SIZE);
+ 			set_huge_pte_at(dst, addr, dst_pte, entry);
+ 		}
+ 		spin_unlock(&src->page_table_lock);
++		spin_unlock(&dst->page_table_lock);
+ 	}
+ 	return 0;
+ 
+@@ -310,12 +314,14 @@ void unmap_hugepage_range(struct vm_area
+ 	BUG_ON(start & ~HPAGE_MASK);
+ 	BUG_ON(end & ~HPAGE_MASK);
+ 
++	spin_lock(&mm->page_table_lock);
++
++	/* Update high watermark before we lower rss */
++	update_hiwater_rss(mm);
++
+ 	for (address = start; address < end; address += HPAGE_SIZE) {
+ 		ptep = huge_pte_offset(mm, address);
+-		if (! ptep)
+-			/* This can happen on truncate, or if an
+-			 * mmap() is aborted due to an error before
+-			 * the prefault */
++		if (!ptep)
+ 			continue;
+ 
+ 		pte = huge_ptep_get_and_clear(mm, address, ptep);
+@@ -324,96 +330,99 @@ void unmap_hugepage_range(struct vm_area
+ 
+ 		page = pte_page(pte);
+ 		put_page(page);
+-		add_mm_counter(mm, rss,  - (HPAGE_SIZE / PAGE_SIZE));
++		add_mm_counter(mm, file_rss, (int) -(HPAGE_SIZE / PAGE_SIZE));
+ 	}
+-	flush_tlb_range(vma, start, end);
+-}
+-
+-void zap_hugepage_range(struct vm_area_struct *vma,
+-			unsigned long start, unsigned long length)
+-{
+-	struct mm_struct *mm = vma->vm_mm;
+ 
+-	spin_lock(&mm->page_table_lock);
+-	unmap_hugepage_range(vma, start, start + length);
+ 	spin_unlock(&mm->page_table_lock);
++	flush_tlb_range(vma, start, end);
+ }
+ 
+-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
++static struct page *find_lock_huge_page(struct address_space *mapping,
++			unsigned long idx)
+ {
+-	struct mm_struct *mm = current->mm;
+-	unsigned long addr;
+-	int ret = 0;
+-
+-	WARN_ON(!is_vm_hugetlb_page(vma));
+-	BUG_ON(vma->vm_start & ~HPAGE_MASK);
+-	BUG_ON(vma->vm_end & ~HPAGE_MASK);
+-
+-	hugetlb_prefault_arch_hook(mm);
+-
+-	spin_lock(&mm->page_table_lock);
+-	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
+-		unsigned long idx;
+-		pte_t *pte = huge_pte_alloc(mm, addr);
+-		struct page *page;
+-
+-		if (!pte) {
+-			ret = -ENOMEM;
+-			goto out;
+-		}
++	struct page *page;
++	int err;
++	struct inode *inode = mapping->host;
++	unsigned long size;
++
++retry:
++	page = find_lock_page(mapping, idx);
++	if (page)
++		goto out;
++
++	/* Check to make sure the mapping hasn't been truncated */
++	size = i_size_read(inode) >> HPAGE_SHIFT;
++	if (idx >= size)
++		goto out;
++
++	if (hugetlb_get_quota(mapping))
++		goto out;
++	page = alloc_huge_page();
++	if (!page) {
++		hugetlb_put_quota(mapping);
++		goto out;
++	}
+ 
+-		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
+-			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+-		page = find_get_page(mapping, idx);
+-		if (!page) {
+-			/* charge the fs quota first */
+-			if (hugetlb_get_quota(mapping)) {
+-				ret = -ENOMEM;
+-				goto out;
+-			}
+-			page = alloc_huge_page();
+-			if (!page) {
+-				hugetlb_put_quota(mapping);
+-				ret = -ENOMEM;
+-				goto out;
+-			}
+-			ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
+-			if (! ret) {
+-				unlock_page(page);
+-			} else {
+-				hugetlb_put_quota(mapping);
+-				free_huge_page(page);
+-				goto out;
+-			}
+-		}
+-		add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
+-		set_huge_pte_at(mm, addr, pte, make_huge_pte(vma, page));
++	err = add_to_page_cache(page, mapping, idx, GFP_KERNEL);
++	if (err) {
++		put_page(page);
++		hugetlb_put_quota(mapping);
++		if (err == -EEXIST)
++			goto retry;
++		page = NULL;
+ 	}
+ out:
+-	spin_unlock(&mm->page_table_lock);
+-	return ret;
++	return page;
+ }
+ 
+-/*
+- * On ia64 at least, it is possible to receive a hugetlb fault from a
+- * stale zero entry left in the TLB from earlier hardware prefetching.
+- * Low-level arch code should already have flushed the stale entry as
+- * part of its fault handling, but we do need to accept this minor fault
+- * and return successfully.  Whereas the "normal" case is that this is
+- * an access to a hugetlb page which has been truncated off since mmap.
+- */
+ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+ 			unsigned long address, int write_access)
+ {
+ 	int ret = VM_FAULT_SIGBUS;
++	unsigned long idx;
++	unsigned long size;
+ 	pte_t *pte;
++	struct page *page;
++	struct address_space *mapping;
++
++	pte = huge_pte_alloc(mm, address);
++	if (!pte)
++		goto out;
++
++	mapping = vma->vm_file->f_mapping;
++	idx = ((address - vma->vm_start) >> HPAGE_SHIFT)
++		+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
++
++	/*
++	 * Use page lock to guard against racing truncation
++	 * before we get page_table_lock.
++	 */
++	page = find_lock_huge_page(mapping, idx);
++	if (!page)
++		goto out;
+ 
+ 	spin_lock(&mm->page_table_lock);
+-	pte = huge_pte_offset(mm, address);
+-	if (pte && !pte_none(*pte))
+-		ret = VM_FAULT_MINOR;
++	size = i_size_read(mapping->host) >> HPAGE_SHIFT;
++	if (idx >= size)
++		goto backout;
++
++	ret = VM_FAULT_MINOR;
++	if (!pte_none(*pte))
++		goto backout;
++
++	add_mm_counter(mm, file_rss, HPAGE_SIZE / PAGE_SIZE);
++	set_huge_pte_at(mm, address, pte, make_huge_pte(vma, page));
+ 	spin_unlock(&mm->page_table_lock);
++	unlock_page(page);
++out:
+ 	return ret;
++
++backout:
++	spin_unlock(&mm->page_table_lock);
++	hugetlb_put_quota(mapping);
++	unlock_page(page);
++	put_page(page);
++	goto out;
+ }
+ 
+ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -423,34 +432,36 @@ int follow_hugetlb_page(struct mm_struct
+ 	unsigned long vpfn, vaddr = *position;
+ 	int remainder = *length;
+ 
+-	BUG_ON(!is_vm_hugetlb_page(vma));
+-
+ 	vpfn = vaddr/PAGE_SIZE;
+ 	spin_lock(&mm->page_table_lock);
+ 	while (vaddr < vma->vm_end && remainder) {
++		pte_t *pte;
++		struct page *page;
+ 
+-		if (pages) {
+-			pte_t *pte;
+-			struct page *page;
+-
+-			/* Some archs (sparc64, sh*) have multiple
+-			 * pte_ts to each hugepage.  We have to make
+-			 * sure we get the first, for the page
+-			 * indexing below to work. */
+-			pte = huge_pte_offset(mm, vaddr & HPAGE_MASK);
+-
+-			/* the hugetlb file might have been truncated */
+-			if (!pte || pte_none(*pte)) {
+-				remainder = 0;
+-				if (!i)
+-					i = -EFAULT;
+-				break;
+-			}
++		/*
++		 * Some archs (sparc64, sh*) have multiple pte_ts to
++		 * each hugepage.  We have to make * sure we get the
++		 * first, for the page indexing below to work.
++		 */
++		pte = huge_pte_offset(mm, vaddr & HPAGE_MASK);
++
++		if (!pte || pte_none(*pte)) {
++			int ret;
++
++			spin_unlock(&mm->page_table_lock);
++			ret = hugetlb_fault(mm, vma, vaddr, 0);
++			spin_lock(&mm->page_table_lock);
++			if (ret == VM_FAULT_MINOR)
++				continue;
++
++			remainder = 0;
++			if (!i)
++				i = -EFAULT;
++			break;
++		}
+ 
++		if (pages) {
+ 			page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
+-
+-			WARN_ON(!PageCompound(page));
+-
+ 			get_page(page);
+ 			pages[i] = page;
+ 		}
+diff --git a/mm/madvise.c b/mm/madvise.c
+--- a/mm/madvise.c
++++ b/mm/madvise.c
+@@ -126,7 +126,7 @@ static long madvise_dontneed(struct vm_a
+ 			     unsigned long start, unsigned long end)
+ {
+ 	*prev = vma;
+-	if ((vma->vm_flags & VM_LOCKED) || is_vm_hugetlb_page(vma))
++	if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_RESERVED))
+ 		return -EINVAL;
+ 
+ 	if (unlikely(vma->vm_flags & VM_NONLINEAR)) {
+diff --git a/mm/memory.c b/mm/memory.c
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -114,6 +114,7 @@ static void free_pte_range(struct mmu_ga
+ {
+ 	struct page *page = pmd_page(*pmd);
+ 	pmd_clear(pmd);
++	pte_lock_deinit(page);
+ 	pte_free_tlb(tlb, page);
+ 	dec_page_state(nr_page_table_pages);
+ 	tlb->mm->nr_ptes--;
+@@ -249,7 +250,7 @@ void free_pgd_range(struct mmu_gather **
+ 		free_pud_range(*tlb, pgd, addr, next, floor, ceiling);
+ 	} while (pgd++, addr = next, addr != end);
+ 
+-	if (!tlb_is_full_mm(*tlb))
++	if (!(*tlb)->fullmm)
+ 		flush_tlb_pgtables((*tlb)->mm, start, end);
+ }
+ 
+@@ -260,6 +261,12 @@ void free_pgtables(struct mmu_gather **t
+ 		struct vm_area_struct *next = vma->vm_next;
+ 		unsigned long addr = vma->vm_start;
+ 
++		/*
++		 * Hide vma from rmap and vmtruncate before freeing pgtables
++		 */
++		anon_vma_unlink(vma);
++		unlink_file_vma(vma);
++
+ 		if (is_hugepage_only_range(vma->vm_mm, addr, HPAGE_SIZE)) {
+ 			hugetlb_free_pgd_range(tlb, addr, vma->vm_end,
+ 				floor, next? next->vm_start: ceiling);
+@@ -272,6 +279,8 @@ void free_pgtables(struct mmu_gather **t
+ 							HPAGE_SIZE)) {
+ 				vma = next;
+ 				next = vma->vm_next;
++				anon_vma_unlink(vma);
++				unlink_file_vma(vma);
+ 			}
+ 			free_pgd_range(tlb, addr, vma->vm_end,
+ 				floor, next? next->vm_start: ceiling);
+@@ -280,72 +289,78 @@ void free_pgtables(struct mmu_gather **t
+ 	}
+ }
+ 
+-pte_t fastcall *pte_alloc_map(struct mm_struct *mm, pmd_t *pmd,
+-				unsigned long address)
++int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
+ {
+-	if (!pmd_present(*pmd)) {
+-		struct page *new;
++	struct page *new = pte_alloc_one(mm, address);
++	if (!new)
++		return -ENOMEM;
+ 
+-		spin_unlock(&mm->page_table_lock);
+-		new = pte_alloc_one(mm, address);
+-		spin_lock(&mm->page_table_lock);
+-		if (!new)
+-			return NULL;
+-		/*
+-		 * Because we dropped the lock, we should re-check the
+-		 * entry, as somebody else could have populated it..
+-		 */
+-		if (pmd_present(*pmd)) {
+-			pte_free(new);
+-			goto out;
+-		}
++	pte_lock_init(new);
++	spin_lock(&mm->page_table_lock);
++	if (pmd_present(*pmd)) {	/* Another has populated it */
++		pte_lock_deinit(new);
++		pte_free(new);
++	} else {
+ 		mm->nr_ptes++;
+ 		inc_page_state(nr_page_table_pages);
+ 		pmd_populate(mm, pmd, new);
+ 	}
+-out:
+-	return pte_offset_map(pmd, address);
++	spin_unlock(&mm->page_table_lock);
++	return 0;
+ }
+ 
+-pte_t fastcall * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
++int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
+ {
+-	if (!pmd_present(*pmd)) {
+-		pte_t *new;
++	pte_t *new = pte_alloc_one_kernel(&init_mm, address);
++	if (!new)
++		return -ENOMEM;
+ 
+-		spin_unlock(&mm->page_table_lock);
+-		new = pte_alloc_one_kernel(mm, address);
+-		spin_lock(&mm->page_table_lock);
+-		if (!new)
+-			return NULL;
++	spin_lock(&init_mm.page_table_lock);
++	if (pmd_present(*pmd))		/* Another has populated it */
++		pte_free_kernel(new);
++	else
++		pmd_populate_kernel(&init_mm, pmd, new);
++	spin_unlock(&init_mm.page_table_lock);
++	return 0;
++}
+ 
+-		/*
+-		 * Because we dropped the lock, we should re-check the
+-		 * entry, as somebody else could have populated it..
+-		 */
+-		if (pmd_present(*pmd)) {
+-			pte_free_kernel(new);
+-			goto out;
+-		}
+-		pmd_populate_kernel(mm, pmd, new);
+-	}
+-out:
+-	return pte_offset_kernel(pmd, address);
++static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss)
++{
++	if (file_rss)
++		add_mm_counter(mm, file_rss, file_rss);
++	if (anon_rss)
++		add_mm_counter(mm, anon_rss, anon_rss);
++}
++
++/*
++ * This function is called to print an error when a pte in a
++ * !VM_RESERVED region is found pointing to an invalid pfn (which
++ * is an error.
++ *
++ * The calling function must still handle the error.
++ */
++void print_bad_pte(struct vm_area_struct *vma, pte_t pte, unsigned long vaddr)
++{
++	printk(KERN_ERR "Bad pte = %08llx, process = %s, "
++			"vm_flags = %lx, vaddr = %lx\n",
++		(long long)pte_val(pte),
++		(vma->vm_mm == current->mm ? current->comm : "???"),
++		vma->vm_flags, vaddr);
++	dump_stack();
+ }
+ 
+ /*
+  * copy one vm_area from one task to the other. Assumes the page tables
+  * already present in the new task to be cleared in the whole range
+  * covered by this vma.
+- *
+- * dst->page_table_lock is held on entry and exit,
+- * but may be dropped within p[mg]d_alloc() and pte_alloc_map().
+  */
+ 
+ static inline void
+ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
+-		pte_t *dst_pte, pte_t *src_pte, unsigned long vm_flags,
+-		unsigned long addr)
++		pte_t *dst_pte, pte_t *src_pte, struct vm_area_struct *vma,
++		unsigned long addr, int *rss)
+ {
++	unsigned long vm_flags = vma->vm_flags;
+ 	pte_t pte = *src_pte;
+ 	struct page *page;
+ 	unsigned long pfn;
+@@ -357,29 +372,32 @@ copy_one_pte(struct mm_struct *dst_mm, s
+ 			/* make sure dst_mm is on swapoff's mmlist. */
+ 			if (unlikely(list_empty(&dst_mm->mmlist))) {
+ 				spin_lock(&mmlist_lock);
+-				list_add(&dst_mm->mmlist, &src_mm->mmlist);
++				if (list_empty(&dst_mm->mmlist))
++					list_add(&dst_mm->mmlist,
++						 &src_mm->mmlist);
+ 				spin_unlock(&mmlist_lock);
+ 			}
+ 		}
+-		set_pte_at(dst_mm, addr, dst_pte, pte);
+-		return;
++		goto out_set_pte;
+ 	}
+ 
+-	pfn = pte_pfn(pte);
+-	/* the pte points outside of valid memory, the
+-	 * mapping is assumed to be good, meaningful
+-	 * and not mapped via rmap - duplicate the
+-	 * mapping as is.
++	/* If the region is VM_RESERVED, the mapping is not
++	 * mapped via rmap - duplicate the pte as is.
+ 	 */
+-	page = NULL;
+-	if (pfn_valid(pfn))
+-		page = pfn_to_page(pfn);
++	if (vm_flags & VM_RESERVED)
++		goto out_set_pte;
+ 
+-	if (!page || PageReserved(page)) {
+-		set_pte_at(dst_mm, addr, dst_pte, pte);
+-		return;
++	pfn = pte_pfn(pte);
++	/* If the pte points outside of valid memory but
++	 * the region is not VM_RESERVED, we have a problem.
++	 */
++	if (unlikely(!pfn_valid(pfn))) {
++		print_bad_pte(vma, pte, addr);
++		goto out_set_pte; /* try to do something sane */
+ 	}
+ 
++	page = pfn_to_page(pfn);
++
+ 	/*
+ 	 * If it's a COW mapping, write protect it both
+ 	 * in the parent and the child
+@@ -397,11 +415,11 @@ copy_one_pte(struct mm_struct *dst_mm, s
+ 		pte = pte_mkclean(pte);
+ 	pte = pte_mkold(pte);
+ 	get_page(page);
+-	inc_mm_counter(dst_mm, rss);
+-	if (PageAnon(page))
+-		inc_mm_counter(dst_mm, anon_rss);
+-	set_pte_at(dst_mm, addr, dst_pte, pte);
+ 	page_dup_rmap(page);
++	rss[!!PageAnon(page)]++;
++
++out_set_pte:
++	set_pte_at(dst_mm, addr, dst_pte, pte);
+ }
+ 
+ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
+@@ -409,38 +427,44 @@ static int copy_pte_range(struct mm_stru
+ 		unsigned long addr, unsigned long end)
+ {
+ 	pte_t *src_pte, *dst_pte;
+-	unsigned long vm_flags = vma->vm_flags;
+-	int progress;
++	spinlock_t *src_ptl, *dst_ptl;
++	int progress = 0;
++	int rss[2];
+ 
+ again:
+-	dst_pte = pte_alloc_map(dst_mm, dst_pmd, addr);
++	rss[1] = rss[0] = 0;
++	dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
+ 	if (!dst_pte)
+ 		return -ENOMEM;
+ 	src_pte = pte_offset_map_nested(src_pmd, addr);
++	src_ptl = pte_lockptr(src_mm, src_pmd);
++	spin_lock(src_ptl);
+ 
+-	progress = 0;
+-	spin_lock(&src_mm->page_table_lock);
+ 	do {
+ 		/*
+ 		 * We are holding two locks at this point - either of them
+ 		 * could generate latencies in another task on another CPU.
+ 		 */
+-		if (progress >= 32 && (need_resched() ||
+-		    need_lockbreak(&src_mm->page_table_lock) ||
+-		    need_lockbreak(&dst_mm->page_table_lock)))
+-			break;
++		if (progress >= 32) {
++			progress = 0;
++			if (need_resched() ||
++			    need_lockbreak(src_ptl) ||
++			    need_lockbreak(dst_ptl))
++				break;
++		}
+ 		if (pte_none(*src_pte)) {
+ 			progress++;
+ 			continue;
+ 		}
+-		copy_one_pte(dst_mm, src_mm, dst_pte, src_pte, vm_flags, addr);
++		copy_one_pte(dst_mm, src_mm, dst_pte, src_pte, vma, addr, rss);
+ 		progress += 8;
+ 	} while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
+-	spin_unlock(&src_mm->page_table_lock);
+ 
++	spin_unlock(src_ptl);
+ 	pte_unmap_nested(src_pte - 1);
+-	pte_unmap(dst_pte - 1);
+-	cond_resched_lock(&dst_mm->page_table_lock);
++	add_mm_rss(dst_mm, rss[0], rss[1]);
++	pte_unmap_unlock(dst_pte - 1, dst_ptl);
++	cond_resched();
+ 	if (addr != end)
+ 		goto again;
+ 	return 0;
+@@ -525,24 +549,30 @@ int copy_page_range(struct mm_struct *ds
+ 	return 0;
+ }
+ 
+-static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
++static void zap_pte_range(struct mmu_gather *tlb,
++				struct vm_area_struct *vma, pmd_t *pmd,
+ 				unsigned long addr, unsigned long end,
+ 				struct zap_details *details)
+ {
++	struct mm_struct *mm = tlb->mm;
+ 	pte_t *pte;
++	spinlock_t *ptl;
++	int file_rss = 0;
++	int anon_rss = 0;
+ 
+-	pte = pte_offset_map(pmd, addr);
++	pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ 	do {
+ 		pte_t ptent = *pte;
+ 		if (pte_none(ptent))
+ 			continue;
+ 		if (pte_present(ptent)) {
+ 			struct page *page = NULL;
+-			unsigned long pfn = pte_pfn(ptent);
+-			if (pfn_valid(pfn)) {
+-				page = pfn_to_page(pfn);
+-				if (PageReserved(page))
+-					page = NULL;
++			if (!(vma->vm_flags & VM_RESERVED)) {
++				unsigned long pfn = pte_pfn(ptent);
++				if (unlikely(!pfn_valid(pfn)))
++					print_bad_pte(vma, ptent, addr);
++				else
++					page = pfn_to_page(pfn);
+ 			}
+ 			if (unlikely(details) && page) {
+ 				/*
+@@ -562,7 +592,7 @@ static void zap_pte_range(struct mmu_gat
+ 				     page->index > details->last_index))
+ 					continue;
+ 			}
+-			ptent = ptep_get_and_clear_full(tlb->mm, addr, pte,
++			ptent = ptep_get_and_clear_full(mm, addr, pte,
+ 							tlb->fullmm);
+ 			tlb_remove_tlb_entry(tlb, pte, addr);
+ 			if (unlikely(!page))
+@@ -570,15 +600,17 @@ static void zap_pte_range(struct mmu_gat
+ 			if (unlikely(details) && details->nonlinear_vma
+ 			    && linear_page_index(details->nonlinear_vma,
+ 						addr) != page->index)
+-				set_pte_at(tlb->mm, addr, pte,
++				set_pte_at(mm, addr, pte,
+ 					   pgoff_to_pte(page->index));
+-			if (pte_dirty(ptent))
+-				set_page_dirty(page);
+ 			if (PageAnon(page))
+-				dec_mm_counter(tlb->mm, anon_rss);
+-			else if (pte_young(ptent))
+-				mark_page_accessed(page);
+-			tlb->freed++;
++				anon_rss--;
++			else {
++				if (pte_dirty(ptent))
++					set_page_dirty(page);
++				if (pte_young(ptent))
++					mark_page_accessed(page);
++				file_rss--;
++			}
+ 			page_remove_rmap(page);
+ 			tlb_remove_page(tlb, page);
+ 			continue;
+@@ -591,12 +623,15 @@ static void zap_pte_range(struct mmu_gat
+ 			continue;
+ 		if (!pte_file(ptent))
+ 			free_swap_and_cache(pte_to_swp_entry(ptent));
+-		pte_clear_full(tlb->mm, addr, pte, tlb->fullmm);
++		pte_clear_full(mm, addr, pte, tlb->fullmm);
+ 	} while (pte++, addr += PAGE_SIZE, addr != end);
+-	pte_unmap(pte - 1);
++
++	add_mm_rss(mm, file_rss, anon_rss);
++	pte_unmap_unlock(pte - 1, ptl);
+ }
+ 
+-static inline void zap_pmd_range(struct mmu_gather *tlb, pud_t *pud,
++static inline void zap_pmd_range(struct mmu_gather *tlb,
++				struct vm_area_struct *vma, pud_t *pud,
+ 				unsigned long addr, unsigned long end,
+ 				struct zap_details *details)
+ {
+@@ -608,11 +643,12 @@ static inline void zap_pmd_range(struct 
+ 		next = pmd_addr_end(addr, end);
+ 		if (pmd_none_or_clear_bad(pmd))
+ 			continue;
+-		zap_pte_range(tlb, pmd, addr, next, details);
++		zap_pte_range(tlb, vma, pmd, addr, next, details);
+ 	} while (pmd++, addr = next, addr != end);
+ }
+ 
+-static inline void zap_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
++static inline void zap_pud_range(struct mmu_gather *tlb,
++				struct vm_area_struct *vma, pgd_t *pgd,
+ 				unsigned long addr, unsigned long end,
+ 				struct zap_details *details)
+ {
+@@ -624,7 +660,7 @@ static inline void zap_pud_range(struct 
+ 		next = pud_addr_end(addr, end);
+ 		if (pud_none_or_clear_bad(pud))
+ 			continue;
+-		zap_pmd_range(tlb, pud, addr, next, details);
++		zap_pmd_range(tlb, vma, pud, addr, next, details);
+ 	} while (pud++, addr = next, addr != end);
+ }
+ 
+@@ -645,7 +681,7 @@ static void unmap_page_range(struct mmu_
+ 		next = pgd_addr_end(addr, end);
+ 		if (pgd_none_or_clear_bad(pgd))
+ 			continue;
+-		zap_pud_range(tlb, pgd, addr, next, details);
++		zap_pud_range(tlb, vma, pgd, addr, next, details);
+ 	} while (pgd++, addr = next, addr != end);
+ 	tlb_end_vma(tlb, vma);
+ }
+@@ -660,7 +696,6 @@ static void unmap_page_range(struct mmu_
+ /**
+  * unmap_vmas - unmap a range of memory covered by a list of vma's
+  * @tlbp: address of the caller's struct mmu_gather
+- * @mm: the controlling mm_struct
+  * @vma: the starting vma
+  * @start_addr: virtual address at which to start unmapping
+  * @end_addr: virtual address at which to end unmapping
+@@ -669,10 +704,10 @@ static void unmap_page_range(struct mmu_
+  *
+  * Returns the end address of the unmapping (restart addr if interrupted).
+  *
+- * Unmap all pages in the vma list.  Called under page_table_lock.
++ * Unmap all pages in the vma list.
+  *
+- * We aim to not hold page_table_lock for too long (for scheduling latency
+- * reasons).  So zap pages in ZAP_BLOCK_SIZE bytecounts.  This means we need to
++ * We aim to not hold locks for too long (for scheduling latency reasons).
++ * So zap pages in ZAP_BLOCK_SIZE bytecounts.  This means we need to
+  * return the ending mmu_gather to the caller.
+  *
+  * Only addresses between `start' and `end' will be unmapped.
+@@ -684,7 +719,7 @@ static void unmap_page_range(struct mmu_
+  * ensure that any thus-far unmapped pages are flushed before unmap_vmas()
+  * drops the lock and schedules.
+  */
+-unsigned long unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm,
++unsigned long unmap_vmas(struct mmu_gather **tlbp,
+ 		struct vm_area_struct *vma, unsigned long start_addr,
+ 		unsigned long end_addr, unsigned long *nr_accounted,
+ 		struct zap_details *details)
+@@ -694,7 +729,7 @@ unsigned long unmap_vmas(struct mmu_gath
+ 	int tlb_start_valid = 0;
+ 	unsigned long start = start_addr;
+ 	spinlock_t *i_mmap_lock = details? details->i_mmap_lock: NULL;
+-	int fullmm = tlb_is_full_mm(*tlbp);
++	int fullmm = (*tlbp)->fullmm;
+ 
+ 	for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) {
+ 		unsigned long end;
+@@ -734,19 +769,15 @@ unsigned long unmap_vmas(struct mmu_gath
+ 			tlb_finish_mmu(*tlbp, tlb_start, start);
+ 
+ 			if (need_resched() ||
+-				need_lockbreak(&mm->page_table_lock) ||
+ 				(i_mmap_lock && need_lockbreak(i_mmap_lock))) {
+ 				if (i_mmap_lock) {
+-					/* must reset count of rss freed */
+-					*tlbp = tlb_gather_mmu(mm, fullmm);
++					*tlbp = NULL;
+ 					goto out;
+ 				}
+-				spin_unlock(&mm->page_table_lock);
+ 				cond_resched();
+-				spin_lock(&mm->page_table_lock);
+ 			}
+ 
+-			*tlbp = tlb_gather_mmu(mm, fullmm);
++			*tlbp = tlb_gather_mmu(vma->vm_mm, fullmm);
+ 			tlb_start_valid = 0;
+ 			zap_bytes = ZAP_BLOCK_SIZE;
+ 		}
+@@ -770,123 +801,93 @@ unsigned long zap_page_range(struct vm_a
+ 	unsigned long end = address + size;
+ 	unsigned long nr_accounted = 0;
+ 
+-	if (is_vm_hugetlb_page(vma)) {
+-		zap_hugepage_range(vma, address, size);
+-		return end;
+-	}
+-
+ 	lru_add_drain();
+-	spin_lock(&mm->page_table_lock);
+ 	tlb = tlb_gather_mmu(mm, 0);
+-	end = unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted, details);
+-	tlb_finish_mmu(tlb, address, end);
+-	spin_unlock(&mm->page_table_lock);
++	update_hiwater_rss(mm);
++	end = unmap_vmas(&tlb, vma, address, end, &nr_accounted, details);
++	if (tlb)
++		tlb_finish_mmu(tlb, address, end);
+ 	return end;
+ }
+ 
+ /*
+  * Do a quick page-table lookup for a single page.
+- * mm->page_table_lock must be held.
+  */
+-static struct page *__follow_page(struct mm_struct *mm, unsigned long address,
+-			int read, int write, int accessed)
++struct page *follow_page(struct mm_struct *mm, unsigned long address,
++			unsigned int flags)
+ {
+ 	pgd_t *pgd;
+ 	pud_t *pud;
+ 	pmd_t *pmd;
+ 	pte_t *ptep, pte;
++	spinlock_t *ptl;
+ 	unsigned long pfn;
+ 	struct page *page;
+ 
+-	page = follow_huge_addr(mm, address, write);
+-	if (! IS_ERR(page))
+-		return page;
++	page = follow_huge_addr(mm, address, flags & FOLL_WRITE);
++	if (!IS_ERR(page)) {
++		BUG_ON(flags & FOLL_GET);
++		goto out;
++	}
+ 
++	page = NULL;
+ 	pgd = pgd_offset(mm, address);
+ 	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+-		goto out;
++		goto no_page_table;
+ 
+ 	pud = pud_offset(pgd, address);
+ 	if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+-		goto out;
++		goto no_page_table;
+ 	
+ 	pmd = pmd_offset(pud, address);
+ 	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
++		goto no_page_table;
++
++	if (pmd_huge(*pmd)) {
++		BUG_ON(flags & FOLL_GET);
++		page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE);
+ 		goto out;
+-	if (pmd_huge(*pmd))
+-		return follow_huge_pmd(mm, address, pmd, write);
++	}
+ 
+-	ptep = pte_offset_map(pmd, address);
++	ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
+ 	if (!ptep)
+ 		goto out;
+ 
+ 	pte = *ptep;
+-	pte_unmap(ptep);
+-	if (pte_present(pte)) {
+-		if (write && !pte_write(pte))
+-			goto out;
+-		if (read && !pte_read(pte))
+-			goto out;
+-		pfn = pte_pfn(pte);
+-		if (pfn_valid(pfn)) {
+-			page = pfn_to_page(pfn);
+-			if (accessed) {
+-				if (write && !pte_dirty(pte) &&!PageDirty(page))
+-					set_page_dirty(page);
+-				mark_page_accessed(page);
+-			}
+-			return page;
+-		}
+-	}
++	if (!pte_present(pte))
++		goto unlock;
++	if ((flags & FOLL_WRITE) && !pte_write(pte))
++		goto unlock;
++	pfn = pte_pfn(pte);
++	if (!pfn_valid(pfn))
++		goto unlock;
+ 
++	page = pfn_to_page(pfn);
++	if (flags & FOLL_GET)
++		get_page(page);
++	if (flags & FOLL_TOUCH) {
++		if ((flags & FOLL_WRITE) &&
++		    !pte_dirty(pte) && !PageDirty(page))
++			set_page_dirty(page);
++		mark_page_accessed(page);
++	}
++unlock:
++	pte_unmap_unlock(ptep, ptl);
+ out:
+-	return NULL;
+-}
+-
+-inline struct page *
+-follow_page(struct mm_struct *mm, unsigned long address, int write)
+-{
+-	return __follow_page(mm, address, 0, write, 1);
+-}
+-
+-/*
+- * check_user_page_readable() can be called frm niterrupt context by oprofile,
+- * so we need to avoid taking any non-irq-safe locks
+- */
+-int check_user_page_readable(struct mm_struct *mm, unsigned long address)
+-{
+-	return __follow_page(mm, address, 1, 0, 0) != NULL;
+-}
+-EXPORT_SYMBOL(check_user_page_readable);
+-
+-static inline int
+-untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma,
+-			 unsigned long address)
+-{
+-	pgd_t *pgd;
+-	pud_t *pud;
+-	pmd_t *pmd;
+-
+-	/* Check if the vma is for an anonymous mapping. */
+-	if (vma->vm_ops && vma->vm_ops->nopage)
+-		return 0;
+-
+-	/* Check if page directory entry exists. */
+-	pgd = pgd_offset(mm, address);
+-	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+-		return 1;
+-
+-	pud = pud_offset(pgd, address);
+-	if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+-		return 1;
+-
+-	/* Check if page middle directory entry exists. */
+-	pmd = pmd_offset(pud, address);
+-	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+-		return 1;
++	return page;
+ 
+-	/* There is a pte slot for 'address' in 'mm'. */
+-	return 0;
++no_page_table:
++	/*
++	 * When core dumping an enormous anonymous area that nobody
++	 * has touched so far, we don't want to allocate page tables.
++	 */
++	if (flags & FOLL_ANON) {
++		page = ZERO_PAGE(address);
++		if (flags & FOLL_GET)
++			get_page(page);
++		BUG_ON(flags & FOLL_WRITE);
++	}
++	return page;
+ }
+ 
+ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+@@ -894,18 +895,19 @@ int get_user_pages(struct task_struct *t
+ 		struct page **pages, struct vm_area_struct **vmas)
+ {
+ 	int i;
+-	unsigned int flags;
++	unsigned int vm_flags;
+ 
+ 	/* 
+ 	 * Require read or write permissions.
+ 	 * If 'force' is set, we only require the "MAY" flags.
+ 	 */
+-	flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
+-	flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
++	vm_flags  = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
++	vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
+ 	i = 0;
+ 
+ 	do {
+-		struct vm_area_struct *	vma;
++		struct vm_area_struct *vma;
++		unsigned int foll_flags;
+ 
+ 		vma = find_extend_vma(mm, start);
+ 		if (!vma && in_gate_area(tsk, start)) {
+@@ -945,8 +947,8 @@ int get_user_pages(struct task_struct *t
+ 			continue;
+ 		}
+ 
+-		if (!vma || (vma->vm_flags & VM_IO)
+-				|| !(flags & vma->vm_flags))
++		if (!vma || (vma->vm_flags & (VM_IO | VM_RESERVED))
++				|| !(vm_flags & vma->vm_flags))
+ 			return i ? : -EFAULT;
+ 
+ 		if (is_vm_hugetlb_page(vma)) {
+@@ -954,29 +956,25 @@ int get_user_pages(struct task_struct *t
+ 						&start, &len, i);
+ 			continue;
+ 		}
+-		spin_lock(&mm->page_table_lock);
++
++		foll_flags = FOLL_TOUCH;
++		if (pages)
++			foll_flags |= FOLL_GET;
++		if (!write && !(vma->vm_flags & VM_LOCKED) &&
++		    (!vma->vm_ops || !vma->vm_ops->nopage))
++			foll_flags |= FOLL_ANON;
++
+ 		do {
+-			int write_access = write;
+ 			struct page *page;
+ 
+-			cond_resched_lock(&mm->page_table_lock);
+-			while (!(page = follow_page(mm, start, write_access))) {
+-				int ret;
+-
+-				/*
+-				 * Shortcut for anonymous pages. We don't want
+-				 * to force the creation of pages tables for
+-				 * insanely big anonymously mapped areas that
+-				 * nobody touched so far. This is important
+-				 * for doing a core dump for these mappings.
+-				 */
+-				if (!write && untouched_anonymous_page(mm,vma,start)) {
+-					page = ZERO_PAGE(start);
+-					break;
+-				}
+-				spin_unlock(&mm->page_table_lock);
+-				ret = __handle_mm_fault(mm, vma, start, write_access);
++			if (write)
++				foll_flags |= FOLL_WRITE;
+ 
++			cond_resched();
++			while (!(page = follow_page(mm, start, foll_flags))) {
++				int ret;
++				ret = __handle_mm_fault(mm, vma, start,
++						foll_flags & FOLL_WRITE);
+ 				/*
+ 				 * The VM_FAULT_WRITE bit tells us that do_wp_page has
+ 				 * broken COW when necessary, even if maybe_mkwrite
+@@ -984,7 +982,7 @@ int get_user_pages(struct task_struct *t
+ 				 * subsequent page lookups as if they were reads.
+ 				 */
+ 				if (ret & VM_FAULT_WRITE)
+-					write_access = 0;
++					foll_flags &= ~FOLL_WRITE;
+ 				
+ 				switch (ret & ~VM_FAULT_WRITE) {
+ 				case VM_FAULT_MINOR:
+@@ -1000,13 +998,10 @@ int get_user_pages(struct task_struct *t
+ 				default:
+ 					BUG();
+ 				}
+-				spin_lock(&mm->page_table_lock);
+ 			}
+ 			if (pages) {
+ 				pages[i] = page;
+ 				flush_dcache_page(page);
+-				if (!PageReserved(page))
+-					page_cache_get(page);
+ 			}
+ 			if (vmas)
+ 				vmas[i] = vma;
+@@ -1014,7 +1009,6 @@ int get_user_pages(struct task_struct *t
+ 			start += PAGE_SIZE;
+ 			len--;
+ 		} while (len && start < vma->vm_end);
+-		spin_unlock(&mm->page_table_lock);
+ 	} while (len);
+ 	return i;
+ }
+@@ -1024,16 +1018,21 @@ static int zeromap_pte_range(struct mm_s
+ 			unsigned long addr, unsigned long end, pgprot_t prot)
+ {
+ 	pte_t *pte;
++	spinlock_t *ptl;
+ 
+-	pte = pte_alloc_map(mm, pmd, addr);
++	pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
+ 	if (!pte)
+ 		return -ENOMEM;
+ 	do {
+-		pte_t zero_pte = pte_wrprotect(mk_pte(ZERO_PAGE(addr), prot));
++		struct page *page = ZERO_PAGE(addr);
++		pte_t zero_pte = pte_wrprotect(mk_pte(page, prot));
++		page_cache_get(page);
++		page_add_file_rmap(page);
++		inc_mm_counter(mm, file_rss);
+ 		BUG_ON(!pte_none(*pte));
+ 		set_pte_at(mm, addr, pte, zero_pte);
+ 	} while (pte++, addr += PAGE_SIZE, addr != end);
+-	pte_unmap(pte - 1);
++	pte_unmap_unlock(pte - 1, ptl);
+ 	return 0;
+ }
+ 
+@@ -1083,14 +1082,12 @@ int zeromap_page_range(struct vm_area_st
+ 	BUG_ON(addr >= end);
+ 	pgd = pgd_offset(mm, addr);
+ 	flush_cache_range(vma, addr, end);
+-	spin_lock(&mm->page_table_lock);
+ 	do {
+ 		next = pgd_addr_end(addr, end);
+ 		err = zeromap_pud_range(mm, pgd, addr, next, prot);
+ 		if (err)
+ 			break;
+ 	} while (pgd++, addr = next, addr != end);
+-	spin_unlock(&mm->page_table_lock);
+ 	return err;
+ }
+ 
+@@ -1104,17 +1101,17 @@ static int remap_pte_range(struct mm_str
+ 			unsigned long pfn, pgprot_t prot)
+ {
+ 	pte_t *pte;
++	spinlock_t *ptl;
+ 
+-	pte = pte_alloc_map(mm, pmd, addr);
++	pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
+ 	if (!pte)
+ 		return -ENOMEM;
+ 	do {
+ 		BUG_ON(!pte_none(*pte));
+-		if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn)))
+-			set_pte_at(mm, addr, pte, pfn_pte(pfn, prot));
++		set_pte_at(mm, addr, pte, pfn_pte(pfn, prot));
+ 		pfn++;
+ 	} while (pte++, addr += PAGE_SIZE, addr != end);
+-	pte_unmap(pte - 1);
++	pte_unmap_unlock(pte - 1, ptl);
+ 	return 0;
+ }
+ 
+@@ -1173,8 +1170,8 @@ int remap_pfn_range(struct vm_area_struc
+ 	 * rest of the world about it:
+ 	 *   VM_IO tells people not to look at these pages
+ 	 *	(accesses can have side effects).
+-	 *   VM_RESERVED tells swapout not to try to touch
+-	 *	this region.
++	 *   VM_RESERVED tells the core MM not to "manage" these pages
++         *	(e.g. refcount, mapcount, try to swap them out).
+ 	 */
+ 	vma->vm_flags |= VM_IO | VM_RESERVED;
+ 
+@@ -1182,7 +1179,6 @@ int remap_pfn_range(struct vm_area_struc
+ 	pfn -= addr >> PAGE_SHIFT;
+ 	pgd = pgd_offset(mm, addr);
+ 	flush_cache_range(vma, addr, end);
+-	spin_lock(&mm->page_table_lock);
+ 	do {
+ 		next = pgd_addr_end(addr, end);
+ 		err = remap_pud_range(mm, pgd, addr, next,
+@@ -1190,12 +1186,36 @@ int remap_pfn_range(struct vm_area_struc
+ 		if (err)
+ 			break;
+ 	} while (pgd++, addr = next, addr != end);
+-	spin_unlock(&mm->page_table_lock);
+ 	return err;
+ }
+ EXPORT_SYMBOL(remap_pfn_range);
+ 
+ /*
++ * handle_pte_fault chooses page fault handler according to an entry
++ * which was read non-atomically.  Before making any commitment, on
++ * those architectures or configurations (e.g. i386 with PAE) which
++ * might give a mix of unmatched parts, do_swap_page and do_file_page
++ * must check under lock before unmapping the pte and proceeding
++ * (but do_wp_page is only called after already making such a check;
++ * and do_anonymous_page and do_no_page can safely check later on).
++ */
++static inline int pte_unmap_same(struct mm_struct *mm, pmd_t *pmd,
++				pte_t *page_table, pte_t orig_pte)
++{
++	int same = 1;
++#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
++	if (sizeof(pte_t) > sizeof(unsigned long)) {
++		spinlock_t *ptl = pte_lockptr(mm, pmd);
++		spin_lock(ptl);
++		same = pte_same(*page_table, orig_pte);
++		spin_unlock(ptl);
++	}
++#endif
++	pte_unmap(page_table);
++	return same;
++}
++
++/*
+  * Do pte_mkwrite, but only if the vma says VM_WRITE.  We do this when
+  * servicing faults for write access.  In the normal case, do always want
+  * pte_mkwrite.  But get_user_pages can cause write faults for mappings
+@@ -1209,28 +1229,10 @@ static inline pte_t maybe_mkwrite(pte_t 
+ }
+ 
+ /*
+- * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock
+- */
+-static inline void break_cow(struct vm_area_struct * vma, struct page * new_page, unsigned long address, 
+-		pte_t *page_table)
+-{
+-	pte_t entry;
+-
+-	entry = maybe_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot)),
+-			      vma);
+-	ptep_establish(vma, address, page_table, entry);
+-	update_mmu_cache(vma, address, entry);
+-	lazy_mmu_prot_update(entry);
+-}
+-
+-/*
+  * This routine handles present pages, when users try to write
+  * to a shared page. It is done by copying the page to a new address
+  * and decrementing the shared-page counter for the old page.
+  *
+- * Goto-purists beware: the only reason for goto's here is that it results
+- * in better assembly code.. The "default" path will see no jumps at all.
+- *
+  * Note that this routine assumes that the protection checks have been
+  * done by the caller (the low-level page fault routine in most cases).
+  * Thus we can safely just mark it writable once we've done any necessary
+@@ -1240,28 +1242,28 @@ static inline void break_cow(struct vm_a
+  * change only once the write actually happens. This avoids a few races,
+  * and potentially makes it more efficient.
+  *
+- * We hold the mm semaphore and the page_table_lock on entry and exit
+- * with the page_table_lock released.
+- */
+-static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
+-	unsigned long address, pte_t *page_table, pmd_t *pmd, pte_t pte)
++ * We enter with non-exclusive mmap_sem (to exclude vma changes,
++ * but allow concurrent faults), with pte both mapped and locked.
++ * We return with mmap_sem still held, but pte unmapped and unlocked.
++ */
++static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
++		unsigned long address, pte_t *page_table, pmd_t *pmd,
++		spinlock_t *ptl, pte_t orig_pte)
+ {
+ 	struct page *old_page, *new_page;
+-	unsigned long pfn = pte_pfn(pte);
++	unsigned long pfn = pte_pfn(orig_pte);
+ 	pte_t entry;
+-	int ret;
++	int ret = VM_FAULT_MINOR;
++
++	BUG_ON(vma->vm_flags & VM_RESERVED);
+ 
+ 	if (unlikely(!pfn_valid(pfn))) {
+ 		/*
+-		 * This should really halt the system so it can be debugged or
+-		 * at least the kernel stops what it's doing before it corrupts
+-		 * data, but for the moment just pretend this is OOM.
++		 * Page table corrupted: show pte and kill process.
+ 		 */
+-		pte_unmap(page_table);
+-		printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n",
+-				address);
+-		spin_unlock(&mm->page_table_lock);
+-		return VM_FAULT_OOM;
++		print_bad_pte(vma, orig_pte, address);
++		ret = VM_FAULT_OOM;
++		goto unlock;
+ 	}
+ 	old_page = pfn_to_page(pfn);
+ 
+@@ -1270,52 +1272,51 @@ static int do_wp_page(struct mm_struct *
+ 		unlock_page(old_page);
+ 		if (reuse) {
+ 			flush_cache_page(vma, address, pfn);
+-			entry = maybe_mkwrite(pte_mkyoung(pte_mkdirty(pte)),
+-					      vma);
++			entry = pte_mkyoung(orig_pte);
++			entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ 			ptep_set_access_flags(vma, address, page_table, entry, 1);
+ 			update_mmu_cache(vma, address, entry);
+ 			lazy_mmu_prot_update(entry);
+-			pte_unmap(page_table);
+-			spin_unlock(&mm->page_table_lock);
+-			return VM_FAULT_MINOR|VM_FAULT_WRITE;
++			ret |= VM_FAULT_WRITE;
++			goto unlock;
+ 		}
+ 	}
+-	pte_unmap(page_table);
+ 
+ 	/*
+ 	 * Ok, we need to copy. Oh, well..
+ 	 */
+-	if (!PageReserved(old_page))
+-		page_cache_get(old_page);
+-	spin_unlock(&mm->page_table_lock);
++	page_cache_get(old_page);
++	pte_unmap_unlock(page_table, ptl);
+ 
+ 	if (unlikely(anon_vma_prepare(vma)))
+-		goto no_new_page;
++		goto oom;
+ 	if (old_page == ZERO_PAGE(address)) {
+ 		new_page = alloc_zeroed_user_highpage(vma, address);
+ 		if (!new_page)
+-			goto no_new_page;
++			goto oom;
+ 	} else {
+ 		new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
+ 		if (!new_page)
+-			goto no_new_page;
++			goto oom;
+ 		copy_user_highpage(new_page, old_page, address);
+ 	}
++
+ 	/*
+ 	 * Re-check the pte - we dropped the lock
+ 	 */
+-	ret = VM_FAULT_MINOR;
+-	spin_lock(&mm->page_table_lock);
+-	page_table = pte_offset_map(pmd, address);
+-	if (likely(pte_same(*page_table, pte))) {
+-		if (PageAnon(old_page))
+-			dec_mm_counter(mm, anon_rss);
+-		if (PageReserved(old_page))
+-			inc_mm_counter(mm, rss);
+-		else
+-			page_remove_rmap(old_page);
++	page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
++	if (likely(pte_same(*page_table, orig_pte))) {
++		page_remove_rmap(old_page);
++		if (!PageAnon(old_page)) {
++			inc_mm_counter(mm, anon_rss);
++			dec_mm_counter(mm, file_rss);
++		}
+ 		flush_cache_page(vma, address, pfn);
+-		break_cow(vma, new_page, address, page_table);
++		entry = mk_pte(new_page, vma->vm_page_prot);
++		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
++		ptep_establish(vma, address, page_table, entry);
++		update_mmu_cache(vma, address, entry);
++		lazy_mmu_prot_update(entry);
+ 		lru_cache_add_active(new_page);
+ 		page_add_anon_rmap(new_page, vma, address);
+ 
+@@ -1323,13 +1324,12 @@ static int do_wp_page(struct mm_struct *
+ 		new_page = old_page;
+ 		ret |= VM_FAULT_WRITE;
+ 	}
+-	pte_unmap(page_table);
+ 	page_cache_release(new_page);
+ 	page_cache_release(old_page);
+-	spin_unlock(&mm->page_table_lock);
++unlock:
++	pte_unmap_unlock(page_table, ptl);
+ 	return ret;
+-
+-no_new_page:
++oom:
+ 	page_cache_release(old_page);
+ 	return VM_FAULT_OOM;
+ }
+@@ -1399,13 +1399,6 @@ again:
+ 
+ 	restart_addr = zap_page_range(vma, start_addr,
+ 					end_addr - start_addr, details);
+-
+-	/*
+-	 * We cannot rely on the break test in unmap_vmas:
+-	 * on the one hand, we don't want to restart our loop
+-	 * just because that broke out for the page_table_lock;
+-	 * on the other hand, it does no test when vma is small.
+-	 */
+ 	need_break = need_resched() ||
+ 			need_lockbreak(details->i_mmap_lock);
+ 
+@@ -1654,38 +1647,37 @@ void swapin_readahead(swp_entry_t entry,
+ }
+ 
+ /*
+- * We hold the mm semaphore and the page_table_lock on entry and
+- * should release the pagetable lock on exit..
+- */
+-static int do_swap_page(struct mm_struct * mm,
+-	struct vm_area_struct * vma, unsigned long address,
+-	pte_t *page_table, pmd_t *pmd, pte_t orig_pte, int write_access)
++ * We enter with non-exclusive mmap_sem (to exclude vma changes,
++ * but allow concurrent faults), and pte mapped but not yet locked.
++ * We return with mmap_sem still held, but pte unmapped and unlocked.
++ */
++static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
++		unsigned long address, pte_t *page_table, pmd_t *pmd,
++		int write_access, pte_t orig_pte)
+ {
++	spinlock_t *ptl;
+ 	struct page *page;
+-	swp_entry_t entry = pte_to_swp_entry(orig_pte);
++	swp_entry_t entry;
+ 	pte_t pte;
+ 	int ret = VM_FAULT_MINOR;
+ 
+-	pte_unmap(page_table);
+-	spin_unlock(&mm->page_table_lock);
++	if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
++		goto out;
++
++	entry = pte_to_swp_entry(orig_pte);
+ 	page = lookup_swap_cache(entry);
+ 	if (!page) {
+  		swapin_readahead(entry, address, vma);
+  		page = read_swap_cache_async(entry, vma, address);
+ 		if (!page) {
+ 			/*
+-			 * Back out if somebody else faulted in this pte while
+-			 * we released the page table lock.
++			 * Back out if somebody else faulted in this pte
++			 * while we released the pte lock.
+ 			 */
+-			spin_lock(&mm->page_table_lock);
+-			page_table = pte_offset_map(pmd, address);
++			page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ 			if (likely(pte_same(*page_table, orig_pte)))
+ 				ret = VM_FAULT_OOM;
+-			else
+-				ret = VM_FAULT_MINOR;
+-			pte_unmap(page_table);
+-			spin_unlock(&mm->page_table_lock);
+-			goto out;
++			goto unlock;
+ 		}
+ 
+ 		/* Had to read the page from swap area: Major fault */
+@@ -1698,15 +1690,11 @@ static int do_swap_page(struct mm_struct
+ 	lock_page(page);
+ 
+ 	/*
+-	 * Back out if somebody else faulted in this pte while we
+-	 * released the page table lock.
++	 * Back out if somebody else already faulted in this pte.
+ 	 */
+-	spin_lock(&mm->page_table_lock);
+-	page_table = pte_offset_map(pmd, address);
+-	if (unlikely(!pte_same(*page_table, orig_pte))) {
+-		ret = VM_FAULT_MINOR;
++	page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
++	if (unlikely(!pte_same(*page_table, orig_pte)))
+ 		goto out_nomap;
+-	}
+ 
+ 	if (unlikely(!PageUptodate(page))) {
+ 		ret = VM_FAULT_SIGBUS;
+@@ -1715,7 +1703,7 @@ static int do_swap_page(struct mm_struct
+ 
+ 	/* The page isn't present yet, go ahead with the fault. */
+ 
+-	inc_mm_counter(mm, rss);
++	inc_mm_counter(mm, anon_rss);
+ 	pte = mk_pte(page, vma->vm_page_prot);
+ 	if (write_access && can_share_swap_page(page)) {
+ 		pte = maybe_mkwrite(pte_mkdirty(pte), vma);
+@@ -1733,7 +1721,7 @@ static int do_swap_page(struct mm_struct
+ 
+ 	if (write_access) {
+ 		if (do_wp_page(mm, vma, address,
+-				page_table, pmd, pte) == VM_FAULT_OOM)
++				page_table, pmd, ptl, pte) == VM_FAULT_OOM)
+ 			ret = VM_FAULT_OOM;
+ 		goto out;
+ 	}
+@@ -1741,74 +1729,76 @@ static int do_swap_page(struct mm_struct
+ 	/* No need to invalidate - it was non-present before */
+ 	update_mmu_cache(vma, address, pte);
+ 	lazy_mmu_prot_update(pte);
+-	pte_unmap(page_table);
+-	spin_unlock(&mm->page_table_lock);
++unlock:
++	pte_unmap_unlock(page_table, ptl);
+ out:
+ 	return ret;
+ out_nomap:
+-	pte_unmap(page_table);
+-	spin_unlock(&mm->page_table_lock);
++	pte_unmap_unlock(page_table, ptl);
+ 	unlock_page(page);
+ 	page_cache_release(page);
+-	goto out;
++	return ret;
+ }
+ 
+ /*
+- * We are called with the MM semaphore and page_table_lock
+- * spinlock held to protect against concurrent faults in
+- * multithreaded programs. 
+- */
+-static int
+-do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
+-		pte_t *page_table, pmd_t *pmd, int write_access,
+-		unsigned long addr)
++ * We enter with non-exclusive mmap_sem (to exclude vma changes,
++ * but allow concurrent faults), and pte mapped but not yet locked.
++ * We return with mmap_sem still held, but pte unmapped and unlocked.
++ */
++static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
++		unsigned long address, pte_t *page_table, pmd_t *pmd,
++		int write_access)
+ {
++	struct page *page;
++	spinlock_t *ptl;
+ 	pte_t entry;
+-	struct page * page = ZERO_PAGE(addr);
+-
+-	/* Read-only mapping of ZERO_PAGE. */
+-	entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot));
+ 
+-	/* ..except if it's a write access */
+ 	if (write_access) {
+ 		/* Allocate our own private page. */
+ 		pte_unmap(page_table);
+-		spin_unlock(&mm->page_table_lock);
+ 
+ 		if (unlikely(anon_vma_prepare(vma)))
+-			goto no_mem;
+-		page = alloc_zeroed_user_highpage(vma, addr);
++			goto oom;
++		page = alloc_zeroed_user_highpage(vma, address);
+ 		if (!page)
+-			goto no_mem;
++			goto oom;
+ 
+-		spin_lock(&mm->page_table_lock);
+-		page_table = pte_offset_map(pmd, addr);
++		entry = mk_pte(page, vma->vm_page_prot);
++		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ 
+-		if (!pte_none(*page_table)) {
+-			pte_unmap(page_table);
+-			page_cache_release(page);
+-			spin_unlock(&mm->page_table_lock);
+-			goto out;
+-		}
+-		inc_mm_counter(mm, rss);
+-		entry = maybe_mkwrite(pte_mkdirty(mk_pte(page,
+-							 vma->vm_page_prot)),
+-				      vma);
++		page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
++		if (!pte_none(*page_table))
++			goto release;
++		inc_mm_counter(mm, anon_rss);
+ 		lru_cache_add_active(page);
+ 		SetPageReferenced(page);
+-		page_add_anon_rmap(page, vma, addr);
++		page_add_anon_rmap(page, vma, address);
++	} else {
++		/* Map the ZERO_PAGE - vm_page_prot is readonly */
++		page = ZERO_PAGE(address);
++		page_cache_get(page);
++		entry = mk_pte(page, vma->vm_page_prot);
++
++		ptl = pte_lockptr(mm, pmd);
++		spin_lock(ptl);
++		if (!pte_none(*page_table))
++			goto release;
++		inc_mm_counter(mm, file_rss);
++		page_add_file_rmap(page);
+ 	}
+ 
+-	set_pte_at(mm, addr, page_table, entry);
+-	pte_unmap(page_table);
++	set_pte_at(mm, address, page_table, entry);
+ 
+ 	/* No need to invalidate - it was non-present before */
+-	update_mmu_cache(vma, addr, entry);
++	update_mmu_cache(vma, address, entry);
+ 	lazy_mmu_prot_update(entry);
+-	spin_unlock(&mm->page_table_lock);
+-out:
++unlock:
++	pte_unmap_unlock(page_table, ptl);
+ 	return VM_FAULT_MINOR;
+-no_mem:
++release:
++	page_cache_release(page);
++	goto unlock;
++oom:
+ 	return VM_FAULT_OOM;
+ }
+ 
+@@ -1821,25 +1811,23 @@ no_mem:
+  * As this is called only for pages that do not currently exist, we
+  * do not need to flush old virtual caches or the TLB.
+  *
+- * This is called with the MM semaphore held and the page table
+- * spinlock held. Exit with the spinlock released.
+- */
+-static int
+-do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
+-	unsigned long address, int write_access, pte_t *page_table, pmd_t *pmd)
++ * We enter with non-exclusive mmap_sem (to exclude vma changes,
++ * but allow concurrent faults), and pte mapped but not yet locked.
++ * We return with mmap_sem still held, but pte unmapped and unlocked.
++ */
++static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
++		unsigned long address, pte_t *page_table, pmd_t *pmd,
++		int write_access)
+ {
+-	struct page * new_page;
++	spinlock_t *ptl;
++	struct page *new_page;
+ 	struct address_space *mapping = NULL;
+ 	pte_t entry;
+ 	unsigned int sequence = 0;
+ 	int ret = VM_FAULT_MINOR;
+ 	int anon = 0;
+ 
+-	if (!vma->vm_ops || !vma->vm_ops->nopage)
+-		return do_anonymous_page(mm, vma, page_table,
+-					pmd, write_access, address);
+ 	pte_unmap(page_table);
+-	spin_unlock(&mm->page_table_lock);
+ 
+ 	if (vma->vm_file) {
+ 		mapping = vma->vm_file->f_mapping;
+@@ -1847,7 +1835,6 @@ do_no_page(struct mm_struct *mm, struct 
+ 		smp_rmb(); /* serializes i_size against truncate_count */
+ 	}
+ retry:
+-	cond_resched();
+ 	new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);
+ 	/*
+ 	 * No smp_rmb is needed here as long as there's a full
+@@ -1880,19 +1867,20 @@ retry:
+ 		anon = 1;
+ 	}
+ 
+-	spin_lock(&mm->page_table_lock);
++	page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ 	/*
+ 	 * For a file-backed vma, someone could have truncated or otherwise
+ 	 * invalidated this page.  If unmap_mapping_range got called,
+ 	 * retry getting the page.
+ 	 */
+ 	if (mapping && unlikely(sequence != mapping->truncate_count)) {
+-		sequence = mapping->truncate_count;
+-		spin_unlock(&mm->page_table_lock);
++		pte_unmap_unlock(page_table, ptl);
+ 		page_cache_release(new_page);
++		cond_resched();
++		sequence = mapping->truncate_count;
++		smp_rmb();
+ 		goto retry;
+ 	}
+-	page_table = pte_offset_map(pmd, address);
+ 
+ 	/*
+ 	 * This silly early PAGE_DIRTY setting removes a race
+@@ -1906,68 +1894,67 @@ retry:
+ 	 */
+ 	/* Only go through if we didn't race with anybody else... */
+ 	if (pte_none(*page_table)) {
+-		if (!PageReserved(new_page))
+-			inc_mm_counter(mm, rss);
+-
+ 		flush_icache_page(vma, new_page);
+ 		entry = mk_pte(new_page, vma->vm_page_prot);
+ 		if (write_access)
+ 			entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ 		set_pte_at(mm, address, page_table, entry);
+ 		if (anon) {
++			inc_mm_counter(mm, anon_rss);
+ 			lru_cache_add_active(new_page);
+ 			page_add_anon_rmap(new_page, vma, address);
+-		} else
++		} else if (!(vma->vm_flags & VM_RESERVED)) {
++			inc_mm_counter(mm, file_rss);
+ 			page_add_file_rmap(new_page);
+-		pte_unmap(page_table);
++		}
+ 	} else {
+ 		/* One of our sibling threads was faster, back out. */
+-		pte_unmap(page_table);
+ 		page_cache_release(new_page);
+-		spin_unlock(&mm->page_table_lock);
+-		goto out;
++		goto unlock;
+ 	}
+ 
+ 	/* no need to invalidate: a not-present page shouldn't be cached */
+ 	update_mmu_cache(vma, address, entry);
+ 	lazy_mmu_prot_update(entry);
+-	spin_unlock(&mm->page_table_lock);
+-out:
++unlock:
++	pte_unmap_unlock(page_table, ptl);
+ 	return ret;
+ oom:
+ 	page_cache_release(new_page);
+-	ret = VM_FAULT_OOM;
+-	goto out;
++	return VM_FAULT_OOM;
+ }
+ 
+ /*
+  * Fault of a previously existing named mapping. Repopulate the pte
+  * from the encoded file_pte if possible. This enables swappable
+  * nonlinear vmas.
+- */
+-static int do_file_page(struct mm_struct * mm, struct vm_area_struct * vma,
+-	unsigned long address, int write_access, pte_t *pte, pmd_t *pmd)
++ *
++ * We enter with non-exclusive mmap_sem (to exclude vma changes,
++ * but allow concurrent faults), and pte mapped but not yet locked.
++ * We return with mmap_sem still held, but pte unmapped and unlocked.
++ */
++static int do_file_page(struct mm_struct *mm, struct vm_area_struct *vma,
++		unsigned long address, pte_t *page_table, pmd_t *pmd,
++		int write_access, pte_t orig_pte)
+ {
+-	unsigned long pgoff;
++	pgoff_t pgoff;
+ 	int err;
+ 
+-	BUG_ON(!vma->vm_ops || !vma->vm_ops->nopage);
+-	/*
+-	 * Fall back to the linear mapping if the fs does not support
+-	 * ->populate:
+-	 */
+-	if (!vma->vm_ops->populate ||
+-			(write_access && !(vma->vm_flags & VM_SHARED))) {
+-		pte_clear(mm, address, pte);
+-		return do_no_page(mm, vma, address, write_access, pte, pmd);
+-	}
+-
+-	pgoff = pte_to_pgoff(*pte);
++	if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
++		return VM_FAULT_MINOR;
+ 
+-	pte_unmap(pte);
+-	spin_unlock(&mm->page_table_lock);
++	if (unlikely(!(vma->vm_flags & VM_NONLINEAR))) {
++		/*
++		 * Page table corrupted: show pte and kill process.
++		 */
++		print_bad_pte(vma, orig_pte, address);
++		return VM_FAULT_OOM;
++	}
++	/* We can then assume vm->vm_ops && vma->vm_ops->populate */
+ 
+-	err = vma->vm_ops->populate(vma, address & PAGE_MASK, PAGE_SIZE, vma->vm_page_prot, pgoff, 0);
++	pgoff = pte_to_pgoff(orig_pte);
++	err = vma->vm_ops->populate(vma, address & PAGE_MASK, PAGE_SIZE,
++					vma->vm_page_prot, pgoff, 0);
+ 	if (err == -ENOMEM)
+ 		return VM_FAULT_OOM;
+ 	if (err)
+@@ -1984,56 +1971,68 @@ static int do_file_page(struct mm_struct
+  * with external mmu caches can use to update those (ie the Sparc or
+  * PowerPC hashed page tables that act as extended TLBs).
+  *
+- * Note the "page_table_lock". It is to protect against kswapd removing
+- * pages from under us. Note that kswapd only ever _removes_ pages, never
+- * adds them. As such, once we have noticed that the page is not present,
+- * we can drop the lock early.
+- *
+- * The adding of pages is protected by the MM semaphore (which we hold),
+- * so we don't need to worry about a page being suddenly been added into
+- * our VM.
+- *
+- * We enter with the pagetable spinlock held, we are supposed to
+- * release it when done.
++ * We enter with non-exclusive mmap_sem (to exclude vma changes,
++ * but allow concurrent faults), and pte mapped but not yet locked.
++ * We return with mmap_sem still held, but pte unmapped and unlocked.
+  */
+ static inline int handle_pte_fault(struct mm_struct *mm,
+-	struct vm_area_struct * vma, unsigned long address,
+-	int write_access, pte_t *pte, pmd_t *pmd)
++		struct vm_area_struct *vma, unsigned long address,
++		pte_t *pte, pmd_t *pmd, int write_access)
+ {
+ 	pte_t entry;
++	pte_t old_entry;
++	spinlock_t *ptl;
+ 
+-	entry = *pte;
++	old_entry = entry = *pte;
+ 	if (!pte_present(entry)) {
+-		/*
+-		 * If it truly wasn't present, we know that kswapd
+-		 * and the PTE updates will not touch it later. So
+-		 * drop the lock.
+-		 */
+-		if (pte_none(entry))
+-			return do_no_page(mm, vma, address, write_access, pte, pmd);
++		if (pte_none(entry)) {
++			if (!vma->vm_ops || !vma->vm_ops->nopage)
++				return do_anonymous_page(mm, vma, address,
++					pte, pmd, write_access);
++			return do_no_page(mm, vma, address,
++					pte, pmd, write_access);
++		}
+ 		if (pte_file(entry))
+-			return do_file_page(mm, vma, address, write_access, pte, pmd);
+-		return do_swap_page(mm, vma, address, pte, pmd, entry, write_access);
++			return do_file_page(mm, vma, address,
++					pte, pmd, write_access, entry);
++		return do_swap_page(mm, vma, address,
++					pte, pmd, write_access, entry);
+ 	}
+ 
++	ptl = pte_lockptr(mm, pmd);
++	spin_lock(ptl);
++	if (unlikely(!pte_same(*pte, entry)))
++		goto unlock;
+ 	if (write_access) {
+ 		if (!pte_write(entry))
+-			return do_wp_page(mm, vma, address, pte, pmd, entry);
++			return do_wp_page(mm, vma, address,
++					pte, pmd, ptl, entry);
+ 		entry = pte_mkdirty(entry);
+ 	}
+ 	entry = pte_mkyoung(entry);
+-	ptep_set_access_flags(vma, address, pte, entry, write_access);
+-	update_mmu_cache(vma, address, entry);
+-	lazy_mmu_prot_update(entry);
+-	pte_unmap(pte);
+-	spin_unlock(&mm->page_table_lock);
++	if (!pte_same(old_entry, entry)) {
++		ptep_set_access_flags(vma, address, pte, entry, write_access);
++		update_mmu_cache(vma, address, entry);
++		lazy_mmu_prot_update(entry);
++	} else {
++		/*
++		 * This is needed only for protection faults but the arch code
++		 * is not yet telling us if this is a protection fault or not.
++		 * This still avoids useless tlb flushes for .text page faults
++		 * with threads.
++		 */
++		if (write_access)
++			flush_tlb_page(vma, address);
++	}
++unlock:
++	pte_unmap_unlock(pte, ptl);
+ 	return VM_FAULT_MINOR;
+ }
+ 
+ /*
+  * By the time we get here, we already hold the mm semaphore
+  */
+-int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
++int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+ 		unsigned long address, int write_access)
+ {
+ 	pgd_t *pgd;
+@@ -2048,100 +2047,66 @@ int __handle_mm_fault(struct mm_struct *
+ 	if (unlikely(is_vm_hugetlb_page(vma)))
+ 		return hugetlb_fault(mm, vma, address, write_access);
+ 
+-	/*
+-	 * We need the page table lock to synchronize with kswapd
+-	 * and the SMP-safe atomic PTE updates.
+-	 */
+ 	pgd = pgd_offset(mm, address);
+-	spin_lock(&mm->page_table_lock);
+-
+ 	pud = pud_alloc(mm, pgd, address);
+ 	if (!pud)
+-		goto oom;
+-
++		return VM_FAULT_OOM;
+ 	pmd = pmd_alloc(mm, pud, address);
+ 	if (!pmd)
+-		goto oom;
+-
++		return VM_FAULT_OOM;
+ 	pte = pte_alloc_map(mm, pmd, address);
+ 	if (!pte)
+-		goto oom;
+-	
+-	return handle_pte_fault(mm, vma, address, write_access, pte, pmd);
++		return VM_FAULT_OOM;
+ 
+- oom:
+-	spin_unlock(&mm->page_table_lock);
+-	return VM_FAULT_OOM;
++	return handle_pte_fault(mm, vma, address, pte, pmd, write_access);
+ }
+ 
+ #ifndef __PAGETABLE_PUD_FOLDED
+ /*
+  * Allocate page upper directory.
+- *
+- * We've already handled the fast-path in-line, and we own the
+- * page table lock.
++ * We've already handled the fast-path in-line.
+  */
+-pud_t fastcall *__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
++int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+ {
+-	pud_t *new;
+-
+-	spin_unlock(&mm->page_table_lock);
+-	new = pud_alloc_one(mm, address);
+-	spin_lock(&mm->page_table_lock);
++	pud_t *new = pud_alloc_one(mm, address);
+ 	if (!new)
+-		return NULL;
++		return -ENOMEM;
+ 
+-	/*
+-	 * Because we dropped the lock, we should re-check the
+-	 * entry, as somebody else could have populated it..
+-	 */
+-	if (pgd_present(*pgd)) {
++	spin_lock(&mm->page_table_lock);
++	if (pgd_present(*pgd))		/* Another has populated it */
+ 		pud_free(new);
+-		goto out;
+-	}
+-	pgd_populate(mm, pgd, new);
+- out:
+-	return pud_offset(pgd, address);
++	else
++		pgd_populate(mm, pgd, new);
++	spin_unlock(&mm->page_table_lock);
++	return 0;
+ }
+ #endif /* __PAGETABLE_PUD_FOLDED */
+ 
+ #ifndef __PAGETABLE_PMD_FOLDED
+ /*
+  * Allocate page middle directory.
+- *
+- * We've already handled the fast-path in-line, and we own the
+- * page table lock.
++ * We've already handled the fast-path in-line.
+  */
+-pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
++int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+ {
+-	pmd_t *new;
+-
+-	spin_unlock(&mm->page_table_lock);
+-	new = pmd_alloc_one(mm, address);
+-	spin_lock(&mm->page_table_lock);
++	pmd_t *new = pmd_alloc_one(mm, address);
+ 	if (!new)
+-		return NULL;
++		return -ENOMEM;
+ 
+-	/*
+-	 * Because we dropped the lock, we should re-check the
+-	 * entry, as somebody else could have populated it..
+-	 */
++	spin_lock(&mm->page_table_lock);
+ #ifndef __ARCH_HAS_4LEVEL_HACK
+-	if (pud_present(*pud)) {
++	if (pud_present(*pud))		/* Another has populated it */
+ 		pmd_free(new);
+-		goto out;
+-	}
+-	pud_populate(mm, pud, new);
++	else
++		pud_populate(mm, pud, new);
+ #else
+-	if (pgd_present(*pud)) {
++	if (pgd_present(*pud))		/* Another has populated it */
+ 		pmd_free(new);
+-		goto out;
+-	}
+-	pgd_populate(mm, pud, new);
++	else
++		pgd_populate(mm, pud, new);
+ #endif /* __ARCH_HAS_4LEVEL_HACK */
+-
+- out:
+-	return pmd_offset(pud, address);
++	spin_unlock(&mm->page_table_lock);
++	return 0;
+ }
+ #endif /* __PAGETABLE_PMD_FOLDED */
+ 
+@@ -2206,22 +2171,6 @@ unsigned long vmalloc_to_pfn(void * vmal
+ 
+ EXPORT_SYMBOL(vmalloc_to_pfn);
+ 
+-/*
+- * update_mem_hiwater
+- *	- update per process rss and vm high water data
+- */
+-void update_mem_hiwater(struct task_struct *tsk)
+-{
+-	if (tsk->mm) {
+-		unsigned long rss = get_mm_counter(tsk->mm, rss);
+-
+-		if (tsk->mm->hiwater_rss < rss)
+-			tsk->mm->hiwater_rss = rss;
+-		if (tsk->mm->hiwater_vm < tsk->mm->total_vm)
+-			tsk->mm->hiwater_vm = tsk->mm->total_vm;
+-	}
+-}
+-
+ #if !defined(__HAVE_ARCH_GATE_AREA)
+ 
+ #if defined(AT_SYSINFO_EHDR)
+@@ -2233,7 +2182,7 @@ static int __init gate_vma_init(void)
+ 	gate_vma.vm_start = FIXADDR_USER_START;
+ 	gate_vma.vm_end = FIXADDR_USER_END;
+ 	gate_vma.vm_page_prot = PAGE_READONLY;
+-	gate_vma.vm_flags = 0;
++	gate_vma.vm_flags = VM_RESERVED;
+ 	return 0;
+ }
+ __initcall(gate_vma_init);
+diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
+new file mode 100644
+--- /dev/null
++++ b/mm/memory_hotplug.c
+@@ -0,0 +1,138 @@
++/*
++ *  linux/mm/memory_hotplug.c
++ *
++ *  Copyright (C)
++ */
++
++#include <linux/config.h>
++#include <linux/stddef.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/interrupt.h>
++#include <linux/pagemap.h>
++#include <linux/bootmem.h>
++#include <linux/compiler.h>
++#include <linux/module.h>
++#include <linux/pagevec.h>
++#include <linux/slab.h>
++#include <linux/sysctl.h>
++#include <linux/cpu.h>
++#include <linux/memory.h>
++#include <linux/memory_hotplug.h>
++#include <linux/highmem.h>
++#include <linux/vmalloc.h>
++
++#include <asm/tlbflush.h>
++
++extern void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn,
++			  unsigned long size);
++static void __add_zone(struct zone *zone, unsigned long phys_start_pfn)
++{
++	struct pglist_data *pgdat = zone->zone_pgdat;
++	int nr_pages = PAGES_PER_SECTION;
++	int nid = pgdat->node_id;
++	int zone_type;
++
++	zone_type = zone - pgdat->node_zones;
++	memmap_init_zone(nr_pages, nid, zone_type, phys_start_pfn);
++	zonetable_add(zone, nid, zone_type, phys_start_pfn, nr_pages);
++}
++
++extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
++				  int nr_pages);
++static int __add_section(struct zone *zone, unsigned long phys_start_pfn)
++{
++	struct pglist_data *pgdat = zone->zone_pgdat;
++	int nr_pages = PAGES_PER_SECTION;
++	int ret;
++
++	ret = sparse_add_one_section(zone, phys_start_pfn, nr_pages);
++
++	if (ret < 0)
++		return ret;
++
++	__add_zone(zone, phys_start_pfn);
++	return register_new_memory(__pfn_to_section(phys_start_pfn));
++}
++
++/*
++ * Reasonably generic function for adding memory.  It is
++ * expected that archs that support memory hotplug will
++ * call this function after deciding the zone to which to
++ * add the new pages.
++ */
++int __add_pages(struct zone *zone, unsigned long phys_start_pfn,
++		 unsigned long nr_pages)
++{
++	unsigned long i;
++	int err = 0;
++
++	for (i = 0; i < nr_pages; i += PAGES_PER_SECTION) {
++		err = __add_section(zone, phys_start_pfn + i);
++
++		if (err)
++			break;
++	}
++
++	return err;
++}
++
++static void grow_zone_span(struct zone *zone,
++		unsigned long start_pfn, unsigned long end_pfn)
++{
++	unsigned long old_zone_end_pfn;
++
++	zone_span_writelock(zone);
++
++	old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
++	if (start_pfn < zone->zone_start_pfn)
++		zone->zone_start_pfn = start_pfn;
++
++	if (end_pfn > old_zone_end_pfn)
++		zone->spanned_pages = end_pfn - zone->zone_start_pfn;
++
++	zone_span_writeunlock(zone);
++}
++
++static void grow_pgdat_span(struct pglist_data *pgdat,
++		unsigned long start_pfn, unsigned long end_pfn)
++{
++	unsigned long old_pgdat_end_pfn =
++		pgdat->node_start_pfn + pgdat->node_spanned_pages;
++
++	if (start_pfn < pgdat->node_start_pfn)
++		pgdat->node_start_pfn = start_pfn;
++
++	if (end_pfn > old_pgdat_end_pfn)
++		pgdat->node_spanned_pages = end_pfn - pgdat->node_spanned_pages;
++}
++
++int online_pages(unsigned long pfn, unsigned long nr_pages)
++{
++	unsigned long i;
++	unsigned long flags;
++	unsigned long onlined_pages = 0;
++	struct zone *zone;
++
++	/*
++	 * This doesn't need a lock to do pfn_to_page().
++	 * The section can't be removed here because of the
++	 * memory_block->state_sem.
++	 */
++	zone = page_zone(pfn_to_page(pfn));
++	pgdat_resize_lock(zone->zone_pgdat, &flags);
++	grow_zone_span(zone, pfn, pfn + nr_pages);
++	grow_pgdat_span(zone->zone_pgdat, pfn, pfn + nr_pages);
++	pgdat_resize_unlock(zone->zone_pgdat, &flags);
++
++	for (i = 0; i < nr_pages; i++) {
++		struct page *page = pfn_to_page(pfn + i);
++		online_page(page);
++		onlined_pages++;
++	}
++	zone->present_pages += onlined_pages;
++
++	setup_per_zone_pages_min();
++
++	return 0;
++}
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -2,6 +2,7 @@
+  * Simple NUMA memory policy for the Linux kernel.
+  *
+  * Copyright 2003,2004 Andi Kleen, SuSE Labs.
++ * (C) Copyright 2005 Christoph Lameter, Silicon Graphics, Inc.
+  * Subject to the GNU Public License, version 2.
+  *
+  * NUMA policy allows the user to give hints in which node(s) memory should
+@@ -17,13 +18,19 @@
+  *                offset into the backing object or offset into the mapping
+  *                for anonymous memory. For process policy an process counter
+  *                is used.
++ *
+  * bind           Only allocate memory on a specific set of nodes,
+  *                no fallback.
++ *                FIXME: memory is allocated starting with the first node
++ *                to the last. It would be better if bind would truly restrict
++ *                the allocation to memory nodes instead
++ *
+  * preferred       Try a specific node first before normal fallback.
+  *                As a special case node -1 here means do the allocation
+  *                on the local CPU. This is normally identical to default,
+  *                but useful to set in a VMA when you have a non default
+  *                process policy.
++ *
+  * default        Allocate on the local node first, or when on a VMA
+  *                use the process policy. This is what Linux always did
+  *		  in a NUMA aware kernel and still does by, ahem, default.
+@@ -93,23 +100,10 @@ struct mempolicy default_policy = {
+ 	.policy = MPOL_DEFAULT,
+ };
+ 
+-/* Check if all specified nodes are online */
+-static int nodes_online(unsigned long *nodes)
+-{
+-	DECLARE_BITMAP(online2, MAX_NUMNODES);
+-
+-	bitmap_copy(online2, nodes_addr(node_online_map), MAX_NUMNODES);
+-	if (bitmap_empty(online2, MAX_NUMNODES))
+-		set_bit(0, online2);
+-	if (!bitmap_subset(nodes, online2, MAX_NUMNODES))
+-		return -EINVAL;
+-	return 0;
+-}
+-
+ /* Do sanity checking on a policy */
+-static int mpol_check_policy(int mode, unsigned long *nodes)
++static int mpol_check_policy(int mode, nodemask_t *nodes)
+ {
+-	int empty = bitmap_empty(nodes, MAX_NUMNODES);
++	int empty = nodes_empty(*nodes);
+ 
+ 	switch (mode) {
+ 	case MPOL_DEFAULT:
+@@ -124,71 +118,20 @@ static int mpol_check_policy(int mode, u
+ 			return -EINVAL;
+ 		break;
+ 	}
+-	return nodes_online(nodes);
++	return nodes_subset(*nodes, node_online_map) ? 0 : -EINVAL;
+ }
+-
+-/* Copy a node mask from user space. */
+-static int get_nodes(unsigned long *nodes, unsigned long __user *nmask,
+-		     unsigned long maxnode, int mode)
+-{
+-	unsigned long k;
+-	unsigned long nlongs;
+-	unsigned long endmask;
+-
+-	--maxnode;
+-	bitmap_zero(nodes, MAX_NUMNODES);
+-	if (maxnode == 0 || !nmask)
+-		return 0;
+-
+-	nlongs = BITS_TO_LONGS(maxnode);
+-	if ((maxnode % BITS_PER_LONG) == 0)
+-		endmask = ~0UL;
+-	else
+-		endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1;
+-
+-	/* When the user specified more nodes than supported just check
+-	   if the non supported part is all zero. */
+-	if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) {
+-		if (nlongs > PAGE_SIZE/sizeof(long))
+-			return -EINVAL;
+-		for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) {
+-			unsigned long t;
+-			if (get_user(t,  nmask + k))
+-				return -EFAULT;
+-			if (k == nlongs - 1) {
+-				if (t & endmask)
+-					return -EINVAL;
+-			} else if (t)
+-				return -EINVAL;
+-		}
+-		nlongs = BITS_TO_LONGS(MAX_NUMNODES);
+-		endmask = ~0UL;
+-	}
+-
+-	if (copy_from_user(nodes, nmask, nlongs*sizeof(unsigned long)))
+-		return -EFAULT;
+-	nodes[nlongs-1] &= endmask;
+-	/* Update current mems_allowed */
+-	cpuset_update_current_mems_allowed();
+-	/* Ignore nodes not set in current->mems_allowed */
+-	cpuset_restrict_to_mems_allowed(nodes);
+-	return mpol_check_policy(mode, nodes);
+-}
+-
+ /* Generate a custom zonelist for the BIND policy. */
+-static struct zonelist *bind_zonelist(unsigned long *nodes)
++static struct zonelist *bind_zonelist(nodemask_t *nodes)
+ {
+ 	struct zonelist *zl;
+ 	int num, max, nd;
+ 
+-	max = 1 + MAX_NR_ZONES * bitmap_weight(nodes, MAX_NUMNODES);
++	max = 1 + MAX_NR_ZONES * nodes_weight(*nodes);
+ 	zl = kmalloc(sizeof(void *) * max, GFP_KERNEL);
+ 	if (!zl)
+ 		return NULL;
+ 	num = 0;
+-	for (nd = find_first_bit(nodes, MAX_NUMNODES);
+-	     nd < MAX_NUMNODES;
+-	     nd = find_next_bit(nodes, MAX_NUMNODES, 1+nd)) {
++	for_each_node_mask(nd, *nodes) {
+ 		int k;
+ 		for (k = MAX_NR_ZONES-1; k >= 0; k--) {
+ 			struct zone *z = &NODE_DATA(nd)->node_zones[k];
+@@ -199,17 +142,16 @@ static struct zonelist *bind_zonelist(un
+ 				policy_zone = k;
+ 		}
+ 	}
+-	BUG_ON(num >= max);
+ 	zl->zones[num] = NULL;
+ 	return zl;
+ }
+ 
+ /* Create a new policy */
+-static struct mempolicy *mpol_new(int mode, unsigned long *nodes)
++static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
+ {
+ 	struct mempolicy *policy;
+ 
+-	PDprintk("setting mode %d nodes[0] %lx\n", mode, nodes[0]);
++	PDprintk("setting mode %d nodes[0] %lx\n", mode, nodes_addr(*nodes)[0]);
+ 	if (mode == MPOL_DEFAULT)
+ 		return NULL;
+ 	policy = kmem_cache_alloc(policy_cache, GFP_KERNEL);
+@@ -218,10 +160,10 @@ static struct mempolicy *mpol_new(int mo
+ 	atomic_set(&policy->refcnt, 1);
+ 	switch (mode) {
+ 	case MPOL_INTERLEAVE:
+-		bitmap_copy(policy->v.nodes, nodes, MAX_NUMNODES);
++		policy->v.nodes = *nodes;
+ 		break;
+ 	case MPOL_PREFERRED:
+-		policy->v.preferred_node = find_first_bit(nodes, MAX_NUMNODES);
++		policy->v.preferred_node = first_node(*nodes);
+ 		if (policy->v.preferred_node >= MAX_NUMNODES)
+ 			policy->v.preferred_node = -1;
+ 		break;
+@@ -238,14 +180,14 @@ static struct mempolicy *mpol_new(int mo
+ }
+ 
+ /* Ensure all existing pages follow the policy. */
+-static int check_pte_range(struct mm_struct *mm, pmd_t *pmd,
+-		unsigned long addr, unsigned long end, unsigned long *nodes)
++static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
++		unsigned long addr, unsigned long end, nodemask_t *nodes)
+ {
+ 	pte_t *orig_pte;
+ 	pte_t *pte;
++	spinlock_t *ptl;
+ 
+-	spin_lock(&mm->page_table_lock);
+-	orig_pte = pte = pte_offset_map(pmd, addr);
++	orig_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+ 	do {
+ 		unsigned long pfn;
+ 		unsigned int nid;
+@@ -253,19 +195,20 @@ static int check_pte_range(struct mm_str
+ 		if (!pte_present(*pte))
+ 			continue;
+ 		pfn = pte_pfn(*pte);
+-		if (!pfn_valid(pfn))
++		if (!pfn_valid(pfn)) {
++			print_bad_pte(vma, *pte, addr);
+ 			continue;
++		}
+ 		nid = pfn_to_nid(pfn);
+-		if (!test_bit(nid, nodes))
++		if (!node_isset(nid, *nodes))
+ 			break;
+ 	} while (pte++, addr += PAGE_SIZE, addr != end);
+-	pte_unmap(orig_pte);
+-	spin_unlock(&mm->page_table_lock);
++	pte_unmap_unlock(orig_pte, ptl);
+ 	return addr != end;
+ }
+ 
+-static inline int check_pmd_range(struct mm_struct *mm, pud_t *pud,
+-		unsigned long addr, unsigned long end, unsigned long *nodes)
++static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud,
++		unsigned long addr, unsigned long end, nodemask_t *nodes)
+ {
+ 	pmd_t *pmd;
+ 	unsigned long next;
+@@ -275,14 +218,14 @@ static inline int check_pmd_range(struct
+ 		next = pmd_addr_end(addr, end);
+ 		if (pmd_none_or_clear_bad(pmd))
+ 			continue;
+-		if (check_pte_range(mm, pmd, addr, next, nodes))
++		if (check_pte_range(vma, pmd, addr, next, nodes))
+ 			return -EIO;
+ 	} while (pmd++, addr = next, addr != end);
+ 	return 0;
+ }
+ 
+-static inline int check_pud_range(struct mm_struct *mm, pgd_t *pgd,
+-		unsigned long addr, unsigned long end, unsigned long *nodes)
++static inline int check_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
++		unsigned long addr, unsigned long end, nodemask_t *nodes)
+ {
+ 	pud_t *pud;
+ 	unsigned long next;
+@@ -292,24 +235,24 @@ static inline int check_pud_range(struct
+ 		next = pud_addr_end(addr, end);
+ 		if (pud_none_or_clear_bad(pud))
+ 			continue;
+-		if (check_pmd_range(mm, pud, addr, next, nodes))
++		if (check_pmd_range(vma, pud, addr, next, nodes))
+ 			return -EIO;
+ 	} while (pud++, addr = next, addr != end);
+ 	return 0;
+ }
+ 
+-static inline int check_pgd_range(struct mm_struct *mm,
+-		unsigned long addr, unsigned long end, unsigned long *nodes)
++static inline int check_pgd_range(struct vm_area_struct *vma,
++		unsigned long addr, unsigned long end, nodemask_t *nodes)
+ {
+ 	pgd_t *pgd;
+ 	unsigned long next;
+ 
+-	pgd = pgd_offset(mm, addr);
++	pgd = pgd_offset(vma->vm_mm, addr);
+ 	do {
+ 		next = pgd_addr_end(addr, end);
+ 		if (pgd_none_or_clear_bad(pgd))
+ 			continue;
+-		if (check_pud_range(mm, pgd, addr, next, nodes))
++		if (check_pud_range(vma, pgd, addr, next, nodes))
+ 			return -EIO;
+ 	} while (pgd++, addr = next, addr != end);
+ 	return 0;
+@@ -318,7 +261,7 @@ static inline int check_pgd_range(struct
+ /* Step 1: check the range */
+ static struct vm_area_struct *
+ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
+-	    unsigned long *nodes, unsigned long flags)
++	    nodemask_t *nodes, unsigned long flags)
+ {
+ 	int err;
+ 	struct vm_area_struct *first, *vma, *prev;
+@@ -326,6 +269,8 @@ check_range(struct mm_struct *mm, unsign
+ 	first = find_vma(mm, start);
+ 	if (!first)
+ 		return ERR_PTR(-EFAULT);
++	if (first->vm_flags & VM_RESERVED)
++		return ERR_PTR(-EACCES);
+ 	prev = NULL;
+ 	for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
+ 		if (!vma->vm_next && vma->vm_end < end)
+@@ -338,8 +283,7 @@ check_range(struct mm_struct *mm, unsign
+ 				endvma = end;
+ 			if (vma->vm_start > start)
+ 				start = vma->vm_start;
+-			err = check_pgd_range(vma->vm_mm,
+-					   start, endvma, nodes);
++			err = check_pgd_range(vma, start, endvma, nodes);
+ 			if (err) {
+ 				first = ERR_PTR(err);
+ 				break;
+@@ -393,17 +337,25 @@ static int mbind_range(struct vm_area_st
+ 	return err;
+ }
+ 
+-/* Change policy for a memory range */
+-asmlinkage long sys_mbind(unsigned long start, unsigned long len,
+-			  unsigned long mode,
+-			  unsigned long __user *nmask, unsigned long maxnode,
+-			  unsigned flags)
++static int contextualize_policy(int mode, nodemask_t *nodes)
++{
++	if (!nodes)
++		return 0;
++
++	/* Update current mems_allowed */
++	cpuset_update_current_mems_allowed();
++	/* Ignore nodes not set in current->mems_allowed */
++	cpuset_restrict_to_mems_allowed(nodes->bits);
++	return mpol_check_policy(mode, nodes);
++}
++
++long do_mbind(unsigned long start, unsigned long len,
++		unsigned long mode, nodemask_t *nmask, unsigned long flags)
+ {
+ 	struct vm_area_struct *vma;
+ 	struct mm_struct *mm = current->mm;
+ 	struct mempolicy *new;
+ 	unsigned long end;
+-	DECLARE_BITMAP(nodes, MAX_NUMNODES);
+ 	int err;
+ 
+ 	if ((flags & ~(unsigned long)(MPOL_MF_STRICT)) || mode > MPOL_MAX)
+@@ -418,20 +370,17 @@ asmlinkage long sys_mbind(unsigned long 
+ 		return -EINVAL;
+ 	if (end == start)
+ 		return 0;
+-
+-	err = get_nodes(nodes, nmask, maxnode, mode);
+-	if (err)
+-		return err;
+-
+-	new = mpol_new(mode, nodes);
++	if (mpol_check_policy(mode, nmask))
++		return -EINVAL;
++	new = mpol_new(mode, nmask);
+ 	if (IS_ERR(new))
+ 		return PTR_ERR(new);
+ 
+ 	PDprintk("mbind %lx-%lx mode:%ld nodes:%lx\n",start,start+len,
+-			mode,nodes[0]);
++			mode,nodes_addr(nodes)[0]);
+ 
+ 	down_write(&mm->mmap_sem);
+-	vma = check_range(mm, start, end, nodes, flags);
++	vma = check_range(mm, start, end, nmask, flags);
+ 	err = PTR_ERR(vma);
+ 	if (!IS_ERR(vma))
+ 		err = mbind_range(vma, start, end, new);
+@@ -441,50 +390,45 @@ asmlinkage long sys_mbind(unsigned long 
+ }
+ 
+ /* Set the process memory policy */
+-asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
+-				   unsigned long maxnode)
++long do_set_mempolicy(int mode, nodemask_t *nodes)
+ {
+-	int err;
+ 	struct mempolicy *new;
+-	DECLARE_BITMAP(nodes, MAX_NUMNODES);
+ 
+-	if (mode < 0 || mode > MPOL_MAX)
++	if (contextualize_policy(mode, nodes))
+ 		return -EINVAL;
+-	err = get_nodes(nodes, nmask, maxnode, mode);
+-	if (err)
+-		return err;
+ 	new = mpol_new(mode, nodes);
+ 	if (IS_ERR(new))
+ 		return PTR_ERR(new);
+ 	mpol_free(current->mempolicy);
+ 	current->mempolicy = new;
+ 	if (new && new->policy == MPOL_INTERLEAVE)
+-		current->il_next = find_first_bit(new->v.nodes, MAX_NUMNODES);
++		current->il_next = first_node(new->v.nodes);
+ 	return 0;
+ }
+ 
+ /* Fill a zone bitmap for a policy */
+-static void get_zonemask(struct mempolicy *p, unsigned long *nodes)
++static void get_zonemask(struct mempolicy *p, nodemask_t *nodes)
+ {
+ 	int i;
+ 
+-	bitmap_zero(nodes, MAX_NUMNODES);
++	nodes_clear(*nodes);
+ 	switch (p->policy) {
+ 	case MPOL_BIND:
+ 		for (i = 0; p->v.zonelist->zones[i]; i++)
+-			__set_bit(p->v.zonelist->zones[i]->zone_pgdat->node_id, nodes);
++			node_set(p->v.zonelist->zones[i]->zone_pgdat->node_id,
++				*nodes);
+ 		break;
+ 	case MPOL_DEFAULT:
+ 		break;
+ 	case MPOL_INTERLEAVE:
+-		bitmap_copy(nodes, p->v.nodes, MAX_NUMNODES);
++		*nodes = p->v.nodes;
+ 		break;
+ 	case MPOL_PREFERRED:
+ 		/* or use current node instead of online map? */
+ 		if (p->v.preferred_node < 0)
+-			bitmap_copy(nodes, nodes_addr(node_online_map), MAX_NUMNODES);
++			*nodes = node_online_map;
+ 		else
+-			__set_bit(p->v.preferred_node, nodes);
++			node_set(p->v.preferred_node, *nodes);
+ 		break;
+ 	default:
+ 		BUG();
+@@ -504,37 +448,18 @@ static int lookup_node(struct mm_struct 
+ 	return err;
+ }
+ 
+-/* Copy a kernel node mask to user space */
+-static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
+-			      void *nodes, unsigned nbytes)
+-{
+-	unsigned long copy = ALIGN(maxnode-1, 64) / 8;
+-
+-	if (copy > nbytes) {
+-		if (copy > PAGE_SIZE)
+-			return -EINVAL;
+-		if (clear_user((char __user *)mask + nbytes, copy - nbytes))
+-			return -EFAULT;
+-		copy = nbytes;
+-	}
+-	return copy_to_user(mask, nodes, copy) ? -EFAULT : 0;
+-}
+-
+ /* Retrieve NUMA policy */
+-asmlinkage long sys_get_mempolicy(int __user *policy,
+-				  unsigned long __user *nmask,
+-				  unsigned long maxnode,
+-				  unsigned long addr, unsigned long flags)
++long do_get_mempolicy(int *policy, nodemask_t *nmask,
++			unsigned long addr, unsigned long flags)
+ {
+-	int err, pval;
++	int err;
+ 	struct mm_struct *mm = current->mm;
+ 	struct vm_area_struct *vma = NULL;
+ 	struct mempolicy *pol = current->mempolicy;
+ 
++	cpuset_update_current_mems_allowed();
+ 	if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR))
+ 		return -EINVAL;
+-	if (nmask != NULL && maxnode < MAX_NUMNODES)
+-		return -EINVAL;
+ 	if (flags & MPOL_F_ADDR) {
+ 		down_read(&mm->mmap_sem);
+ 		vma = find_vma_intersection(mm, addr, addr+1);
+@@ -557,31 +482,25 @@ asmlinkage long sys_get_mempolicy(int __
+ 			err = lookup_node(mm, addr);
+ 			if (err < 0)
+ 				goto out;
+-			pval = err;
++			*policy = err;
+ 		} else if (pol == current->mempolicy &&
+ 				pol->policy == MPOL_INTERLEAVE) {
+-			pval = current->il_next;
++			*policy = current->il_next;
+ 		} else {
+ 			err = -EINVAL;
+ 			goto out;
+ 		}
+ 	} else
+-		pval = pol->policy;
++		*policy = pol->policy;
+ 
+ 	if (vma) {
+ 		up_read(&current->mm->mmap_sem);
+ 		vma = NULL;
+ 	}
+ 
+-	if (policy && put_user(pval, policy))
+-		return -EFAULT;
+-
+ 	err = 0;
+-	if (nmask) {
+-		DECLARE_BITMAP(nodes, MAX_NUMNODES);
+-		get_zonemask(pol, nodes);
+-		err = copy_nodes_to_user(nmask, maxnode, nodes, sizeof(nodes));
+-	}
++	if (nmask)
++		get_zonemask(pol, nmask);
+ 
+  out:
+ 	if (vma)
+@@ -589,6 +508,126 @@ asmlinkage long sys_get_mempolicy(int __
+ 	return err;
+ }
+ 
++/*
++ * User space interface with variable sized bitmaps for nodelists.
++ */
++
++/* Copy a node mask from user space. */
++static int get_nodes(nodemask_t *nodes, unsigned long __user *nmask,
++		     unsigned long maxnode)
++{
++	unsigned long k;
++	unsigned long nlongs;
++	unsigned long endmask;
++
++	--maxnode;
++	nodes_clear(*nodes);
++	if (maxnode == 0 || !nmask)
++		return 0;
++
++	nlongs = BITS_TO_LONGS(maxnode);
++	if ((maxnode % BITS_PER_LONG) == 0)
++		endmask = ~0UL;
++	else
++		endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1;
++
++	/* When the user specified more nodes than supported just check
++	   if the non supported part is all zero. */
++	if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) {
++		if (nlongs > PAGE_SIZE/sizeof(long))
++			return -EINVAL;
++		for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) {
++			unsigned long t;
++			if (get_user(t, nmask + k))
++				return -EFAULT;
++			if (k == nlongs - 1) {
++				if (t & endmask)
++					return -EINVAL;
++			} else if (t)
++				return -EINVAL;
++		}
++		nlongs = BITS_TO_LONGS(MAX_NUMNODES);
++		endmask = ~0UL;
++	}
++
++	if (copy_from_user(nodes_addr(*nodes), nmask, nlongs*sizeof(unsigned long)))
++		return -EFAULT;
++	nodes_addr(*nodes)[nlongs-1] &= endmask;
++	return 0;
++}
++
++/* Copy a kernel node mask to user space */
++static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
++			      nodemask_t *nodes)
++{
++	unsigned long copy = ALIGN(maxnode-1, 64) / 8;
++	const int nbytes = BITS_TO_LONGS(MAX_NUMNODES) * sizeof(long);
++
++	if (copy > nbytes) {
++		if (copy > PAGE_SIZE)
++			return -EINVAL;
++		if (clear_user((char __user *)mask + nbytes, copy - nbytes))
++			return -EFAULT;
++		copy = nbytes;
++	}
++	return copy_to_user(mask, nodes_addr(*nodes), copy) ? -EFAULT : 0;
++}
++
++asmlinkage long sys_mbind(unsigned long start, unsigned long len,
++			unsigned long mode,
++			unsigned long __user *nmask, unsigned long maxnode,
++			unsigned flags)
++{
++	nodemask_t nodes;
++	int err;
++
++	err = get_nodes(&nodes, nmask, maxnode);
++	if (err)
++		return err;
++	return do_mbind(start, len, mode, &nodes, flags);
++}
++
++/* Set the process memory policy */
++asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
++		unsigned long maxnode)
++{
++	int err;
++	nodemask_t nodes;
++
++	if (mode < 0 || mode > MPOL_MAX)
++		return -EINVAL;
++	err = get_nodes(&nodes, nmask, maxnode);
++	if (err)
++		return err;
++	return do_set_mempolicy(mode, &nodes);
++}
++
++/* Retrieve NUMA policy */
++asmlinkage long sys_get_mempolicy(int __user *policy,
++				unsigned long __user *nmask,
++				unsigned long maxnode,
++				unsigned long addr, unsigned long flags)
++{
++	int err, pval;
++	nodemask_t nodes;
++
++	if (nmask != NULL && maxnode < MAX_NUMNODES)
++		return -EINVAL;
++
++	err = do_get_mempolicy(&pval, &nodes, addr, flags);
++
++	if (err)
++		return err;
++
++	if (policy && put_user(pval, policy))
++		return -EFAULT;
++
++	if (nmask)
++		err = copy_nodes_to_user(nmask, maxnode, &nodes);
++
++	return err;
++}
++
+ #ifdef CONFIG_COMPAT
+ 
+ asmlinkage long compat_sys_get_mempolicy(int __user *policy,
+@@ -649,15 +688,15 @@ asmlinkage long compat_sys_mbind(compat_
+ 	long err = 0;
+ 	unsigned long __user *nm = NULL;
+ 	unsigned long nr_bits, alloc_size;
+-	DECLARE_BITMAP(bm, MAX_NUMNODES);
++	nodemask_t bm;
+ 
+ 	nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
+ 	alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
+ 
+ 	if (nmask) {
+-		err = compat_get_bitmap(bm, nmask, nr_bits);
++		err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits);
+ 		nm = compat_alloc_user_space(alloc_size);
+-		err |= copy_to_user(nm, bm, alloc_size);
++		err |= copy_to_user(nm, nodes_addr(bm), alloc_size);
+ 	}
+ 
+ 	if (err)
+@@ -676,7 +715,7 @@ get_vma_policy(struct task_struct *task,
+ 
+ 	if (vma) {
+ 		if (vma->vm_ops && vma->vm_ops->get_policy)
+-		        pol = vma->vm_ops->get_policy(vma, addr);
++			pol = vma->vm_ops->get_policy(vma, addr);
+ 		else if (vma->vm_policy &&
+ 				vma->vm_policy->policy != MPOL_DEFAULT)
+ 			pol = vma->vm_policy;
+@@ -700,7 +739,7 @@ static struct zonelist *zonelist_policy(
+ 	case MPOL_BIND:
+ 		/* Lower zones don't get a policy applied */
+ 		/* Careful: current->mems_allowed might have moved */
+-		if ((gfp & GFP_ZONEMASK) >= policy_zone)
++		if (gfp_zone(gfp) >= policy_zone)
+ 			if (cpuset_zonelist_valid_mems_allowed(policy->v.zonelist))
+ 				return policy->v.zonelist;
+ 		/*FALL THROUGH*/
+@@ -712,7 +751,7 @@ static struct zonelist *zonelist_policy(
+ 		nd = 0;
+ 		BUG();
+ 	}
+-	return NODE_DATA(nd)->node_zonelists + (gfp & GFP_ZONEMASK);
++	return NODE_DATA(nd)->node_zonelists + gfp_zone(gfp);
+ }
+ 
+ /* Do dynamic interleaving for a process */
+@@ -722,10 +761,9 @@ static unsigned interleave_nodes(struct 
+ 	struct task_struct *me = current;
+ 
+ 	nid = me->il_next;
+-	BUG_ON(nid >= MAX_NUMNODES);
+-	next = find_next_bit(policy->v.nodes, MAX_NUMNODES, 1+nid);
++	next = next_node(nid, policy->v.nodes);
+ 	if (next >= MAX_NUMNODES)
+-		next = find_first_bit(policy->v.nodes, MAX_NUMNODES);
++		next = first_node(policy->v.nodes);
+ 	me->il_next = next;
+ 	return nid;
+ }
+@@ -734,30 +772,28 @@ static unsigned interleave_nodes(struct 
+ static unsigned offset_il_node(struct mempolicy *pol,
+ 		struct vm_area_struct *vma, unsigned long off)
+ {
+-	unsigned nnodes = bitmap_weight(pol->v.nodes, MAX_NUMNODES);
++	unsigned nnodes = nodes_weight(pol->v.nodes);
+ 	unsigned target = (unsigned)off % nnodes;
+ 	int c;
+ 	int nid = -1;
+ 
+ 	c = 0;
+ 	do {
+-		nid = find_next_bit(pol->v.nodes, MAX_NUMNODES, nid+1);
++		nid = next_node(nid, pol->v.nodes);
+ 		c++;
+ 	} while (c <= target);
+-	BUG_ON(nid >= MAX_NUMNODES);
+-	BUG_ON(!test_bit(nid, pol->v.nodes));
+ 	return nid;
+ }
+ 
+ /* Allocate a page in interleaved policy.
+    Own path because it needs to do special accounting. */
+-static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, unsigned nid)
++static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
++					unsigned nid)
+ {
+ 	struct zonelist *zl;
+ 	struct page *page;
+ 
+-	BUG_ON(!node_online(nid));
+-	zl = NODE_DATA(nid)->node_zonelists + (gfp & GFP_ZONEMASK);
++	zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp);
+ 	page = __alloc_pages(gfp, order, zl);
+ 	if (page && page_zone(page) == zl->zones[0]) {
+ 		zone_pcp(zl->zones[0],get_cpu())->interleave_hit++;
+@@ -799,8 +835,6 @@ alloc_page_vma(gfp_t gfp, struct vm_area
+ 		unsigned nid;
+ 		if (vma) {
+ 			unsigned long off;
+-			BUG_ON(addr >= vma->vm_end);
+-			BUG_ON(addr < vma->vm_start);
+ 			off = vma->vm_pgoff;
+ 			off += (addr - vma->vm_start) >> PAGE_SHIFT;
+ 			nid = offset_il_node(pol, vma, off);
+@@ -878,7 +912,7 @@ int __mpol_equal(struct mempolicy *a, st
+ 	case MPOL_DEFAULT:
+ 		return 1;
+ 	case MPOL_INTERLEAVE:
+-		return bitmap_equal(a->v.nodes, b->v.nodes, MAX_NUMNODES);
++		return nodes_equal(a->v.nodes, b->v.nodes);
+ 	case MPOL_PREFERRED:
+ 		return a->v.preferred_node == b->v.preferred_node;
+ 	case MPOL_BIND: {
+@@ -1117,7 +1151,7 @@ int mpol_set_shared_policy(struct shared
+ 	PDprintk("set_shared_policy %lx sz %lu %d %lx\n",
+ 		 vma->vm_pgoff,
+ 		 sz, npol? npol->policy : -1,
+-		npol ? npol->v.nodes[0] : -1);
++		npol ? nodes_addr(npol->v.nodes)[0] : -1);
+ 
+ 	if (npol) {
+ 		new = sp_alloc(vma->vm_pgoff, vma->vm_pgoff + sz, npol);
+@@ -1164,14 +1198,75 @@ void __init numa_policy_init(void)
+ 	/* Set interleaving policy for system init. This way not all
+ 	   the data structures allocated at system boot end up in node zero. */
+ 
+-	if (sys_set_mempolicy(MPOL_INTERLEAVE, nodes_addr(node_online_map),
+-							MAX_NUMNODES) < 0)
++	if (do_set_mempolicy(MPOL_INTERLEAVE, &node_online_map))
+ 		printk("numa_policy_init: interleaving failed\n");
+ }
+ 
+-/* Reset policy of current process to default.
+- * Assumes fs == KERNEL_DS */
++/* Reset policy of current process to default */
+ void numa_default_policy(void)
+ {
+-	sys_set_mempolicy(MPOL_DEFAULT, NULL, 0);
++	do_set_mempolicy(MPOL_DEFAULT, NULL);
++}
++
++/* Migrate a policy to a different set of nodes */
++static void rebind_policy(struct mempolicy *pol, const nodemask_t *old,
++							const nodemask_t *new)
++{
++	nodemask_t tmp;
++
++	if (!pol)
++		return;
++
++	switch (pol->policy) {
++	case MPOL_DEFAULT:
++		break;
++	case MPOL_INTERLEAVE:
++		nodes_remap(tmp, pol->v.nodes, *old, *new);
++		pol->v.nodes = tmp;
++		current->il_next = node_remap(current->il_next, *old, *new);
++		break;
++	case MPOL_PREFERRED:
++		pol->v.preferred_node = node_remap(pol->v.preferred_node,
++								*old, *new);
++		break;
++	case MPOL_BIND: {
++		nodemask_t nodes;
++		struct zone **z;
++		struct zonelist *zonelist;
++
++		nodes_clear(nodes);
++		for (z = pol->v.zonelist->zones; *z; z++)
++			node_set((*z)->zone_pgdat->node_id, nodes);
++		nodes_remap(tmp, nodes, *old, *new);
++		nodes = tmp;
++
++		zonelist = bind_zonelist(&nodes);
++
++		/* If no mem, then zonelist is NULL and we keep old zonelist.
++		 * If that old zonelist has no remaining mems_allowed nodes,
++		 * then zonelist_policy() will "FALL THROUGH" to MPOL_DEFAULT.
++		 */
++
++		if (zonelist) {
++			/* Good - got mem - substitute new zonelist */
++			kfree(pol->v.zonelist);
++			pol->v.zonelist = zonelist;
++		}
++		break;
++	}
++	default:
++		BUG();
++		break;
++	}
++}
++
++/*
++ * Someone moved this task to different nodes.  Fixup mempolicies.
++ *
++ * TODO - fixup current->mm->vma and shmfs/tmpfs/hugetlbfs policies as well,
++ * once we have a cpuset mechanism to mark which cpuset subtree is migrating.
++ */
++void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new)
++{
++	rebind_policy(current->mempolicy, old, new);
+ }
+diff --git a/mm/mempool.c b/mm/mempool.c
+--- a/mm/mempool.c
++++ b/mm/mempool.c
+@@ -205,7 +205,7 @@ void * mempool_alloc(mempool_t *pool, gf
+ 	void *element;
+ 	unsigned long flags;
+ 	wait_queue_t wait;
+-	unsigned int gfp_temp;
++	gfp_t gfp_temp;
+ 
+ 	might_sleep_if(gfp_mask & __GFP_WAIT);
+ 
+diff --git a/mm/mmap.c b/mm/mmap.c
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -181,26 +181,36 @@ static void __remove_shared_vm_struct(st
+ }
+ 
+ /*
+- * Remove one vm structure and free it.
++ * Unlink a file-based vm structure from its prio_tree, to hide
++ * vma from rmap and vmtruncate before freeing its page tables.
+  */
+-static void remove_vm_struct(struct vm_area_struct *vma)
++void unlink_file_vma(struct vm_area_struct *vma)
+ {
+ 	struct file *file = vma->vm_file;
+ 
+-	might_sleep();
+ 	if (file) {
+ 		struct address_space *mapping = file->f_mapping;
+ 		spin_lock(&mapping->i_mmap_lock);
+ 		__remove_shared_vm_struct(vma, file, mapping);
+ 		spin_unlock(&mapping->i_mmap_lock);
+ 	}
++}
++
++/*
++ * Close a vm structure and free it, returning the next.
++ */
++static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
++{
++	struct vm_area_struct *next = vma->vm_next;
++
++	might_sleep();
+ 	if (vma->vm_ops && vma->vm_ops->close)
+ 		vma->vm_ops->close(vma);
+-	if (file)
+-		fput(file);
+-	anon_vma_unlink(vma);
++	if (vma->vm_file)
++		fput(vma->vm_file);
+ 	mpol_free(vma_policy(vma));
+ 	kmem_cache_free(vm_area_cachep, vma);
++	return next;
+ }
+ 
+ asmlinkage unsigned long sys_brk(unsigned long brk)
+@@ -832,7 +842,7 @@ none:
+ }
+ 
+ #ifdef CONFIG_PROC_FS
+-void __vm_stat_account(struct mm_struct *mm, unsigned long flags,
++void vm_stat_account(struct mm_struct *mm, unsigned long flags,
+ 						struct file *file, long pages)
+ {
+ 	const unsigned long stack_flags
+@@ -1070,6 +1080,17 @@ munmap_back:
+ 		error = file->f_op->mmap(file, vma);
+ 		if (error)
+ 			goto unmap_and_free_vma;
++		if ((vma->vm_flags & (VM_SHARED | VM_WRITE | VM_RESERVED))
++						== (VM_WRITE | VM_RESERVED)) {
++			printk(KERN_WARNING "program %s is using MAP_PRIVATE, "
++				"PROT_WRITE mmap of VM_RESERVED memory, which "
++				"is deprecated. Please report this to "
++				"linux-kernel at vger.kernel.org\n",current->comm);
++			if (vma->vm_ops && vma->vm_ops->close)
++				vma->vm_ops->close(vma);
++			error = -EACCES;
++			goto unmap_and_free_vma;
++		}
+ 	} else if (vm_flags & VM_SHARED) {
+ 		error = shmem_zero_setup(vma);
+ 		if (error)
+@@ -1110,7 +1131,7 @@ munmap_back:
+ 	}
+ out:	
+ 	mm->total_vm += len >> PAGE_SHIFT;
+-	__vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
++	vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
+ 	if (vm_flags & VM_LOCKED) {
+ 		mm->locked_vm += len >> PAGE_SHIFT;
+ 		make_pages_present(addr, addr + len);
+@@ -1475,15 +1496,19 @@ static int acct_stack_growth(struct vm_a
+ 	mm->total_vm += grow;
+ 	if (vma->vm_flags & VM_LOCKED)
+ 		mm->locked_vm += grow;
+-	__vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
++	vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
+ 	return 0;
+ }
+ 
+-#ifdef CONFIG_STACK_GROWSUP
++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
+ /*
+- * vma is the first one with address > vma->vm_end.  Have to extend vma.
++ * PA-RISC uses this for its stack; IA64 for its Register Backing Store.
++ * vma is the last one with address > vma->vm_end.  Have to extend vma.
+  */
+-int expand_stack(struct vm_area_struct * vma, unsigned long address)
++#ifdef CONFIG_STACK_GROWSUP
++static inline
++#endif
++int expand_upwards(struct vm_area_struct *vma, unsigned long address)
+ {
+ 	int error;
+ 
+@@ -1521,6 +1546,13 @@ int expand_stack(struct vm_area_struct *
+ 	anon_vma_unlock(vma);
+ 	return error;
+ }
++#endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */
++
++#ifdef CONFIG_STACK_GROWSUP
++int expand_stack(struct vm_area_struct *vma, unsigned long address)
++{
++	return expand_upwards(vma, address);
++}
+ 
+ struct vm_area_struct *
+ find_extend_vma(struct mm_struct *mm, unsigned long addr)
+@@ -1603,36 +1635,24 @@ find_extend_vma(struct mm_struct * mm, u
+ }
+ #endif
+ 
+-/* Normal function to fix up a mapping
+- * This function is the default for when an area has no specific
+- * function.  This may be used as part of a more specific routine.
+- *
+- * By the time this function is called, the area struct has been
+- * removed from the process mapping list.
+- */
+-static void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area)
+-{
+-	size_t len = area->vm_end - area->vm_start;
+-
+-	area->vm_mm->total_vm -= len >> PAGE_SHIFT;
+-	if (area->vm_flags & VM_LOCKED)
+-		area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
+-	vm_stat_unaccount(area);
+-	remove_vm_struct(area);
+-}
+-
+ /*
+- * Update the VMA and inode share lists.
+- *
+- * Ok - we have the memory areas we should free on the 'free' list,
++ * Ok - we have the memory areas we should free on the vma list,
+  * so release them, and do the vma updates.
++ *
++ * Called with the mm semaphore held.
+  */
+-static void unmap_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
++static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
+ {
++	/* Update high watermark before we lower total_vm */
++	update_hiwater_vm(mm);
+ 	do {
+-		struct vm_area_struct *next = vma->vm_next;
+-		unmap_vma(mm, vma);
+-		vma = next;
++		long nrpages = vma_pages(vma);
++
++		mm->total_vm -= nrpages;
++		if (vma->vm_flags & VM_LOCKED)
++			mm->locked_vm -= nrpages;
++		vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
++		vma = remove_vma(vma);
+ 	} while (vma);
+ 	validate_mm(mm);
+ }
+@@ -1651,14 +1671,13 @@ static void unmap_region(struct mm_struc
+ 	unsigned long nr_accounted = 0;
+ 
+ 	lru_add_drain();
+-	spin_lock(&mm->page_table_lock);
+ 	tlb = tlb_gather_mmu(mm, 0);
+-	unmap_vmas(&tlb, mm, vma, start, end, &nr_accounted, NULL);
++	update_hiwater_rss(mm);
++	unmap_vmas(&tlb, vma, start, end, &nr_accounted, NULL);
+ 	vm_unacct_memory(nr_accounted);
+ 	free_pgtables(&tlb, vma, prev? prev->vm_end: FIRST_USER_ADDRESS,
+ 				 next? next->vm_start: 0);
+ 	tlb_finish_mmu(tlb, start, end);
+-	spin_unlock(&mm->page_table_lock);
+ }
+ 
+ /*
+@@ -1799,7 +1818,7 @@ int do_munmap(struct mm_struct *mm, unsi
+ 	unmap_region(mm, vma, prev, start, end);
+ 
+ 	/* Fix up all other VM information */
+-	unmap_vma_list(mm, vma);
++	remove_vma_list(mm, vma);
+ 
+ 	return 0;
+ }
+@@ -1821,7 +1840,7 @@ asmlinkage long sys_munmap(unsigned long
+ 
+ static inline void verify_mm_writelocked(struct mm_struct *mm)
+ {
+-#ifdef CONFIG_DEBUG_KERNEL
++#ifdef CONFIG_DEBUG_VM
+ 	if (unlikely(down_read_trylock(&mm->mmap_sem))) {
+ 		WARN_ON(1);
+ 		up_read(&mm->mmap_sem);
+@@ -1933,34 +1952,21 @@ void exit_mmap(struct mm_struct *mm)
+ 	unsigned long end;
+ 
+ 	lru_add_drain();
+-
+-	spin_lock(&mm->page_table_lock);
+-
+ 	flush_cache_mm(mm);
+ 	tlb = tlb_gather_mmu(mm, 1);
++	/* Don't update_hiwater_rss(mm) here, do_exit already did */
+ 	/* Use -1 here to ensure all VMAs in the mm are unmapped */
+-	end = unmap_vmas(&tlb, mm, vma, 0, -1, &nr_accounted, NULL);
++	end = unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL);
+ 	vm_unacct_memory(nr_accounted);
+ 	free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
+ 	tlb_finish_mmu(tlb, 0, end);
+ 
+-	mm->mmap = mm->mmap_cache = NULL;
+-	mm->mm_rb = RB_ROOT;
+-	set_mm_counter(mm, rss, 0);
+-	mm->total_vm = 0;
+-	mm->locked_vm = 0;
+-
+-	spin_unlock(&mm->page_table_lock);
+-
+-	/*
+-	 * Walk the list again, actually closing and freeing it
+-	 * without holding any MM locks.
+-	 */
+-	while (vma) {
+-		struct vm_area_struct *next = vma->vm_next;
+-		remove_vm_struct(vma);
+-		vma = next;
+-	}
++	/*
++	 * Walk the list again, actually closing and freeing it,
++	 * with preemption enabled, without holding any MM locks.
++	 */
++	while (vma)
++		vma = remove_vma(vma);
+ 
+ 	BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
+ }
+diff --git a/mm/mprotect.c b/mm/mprotect.c
+--- a/mm/mprotect.c
++++ b/mm/mprotect.c
+@@ -29,8 +29,9 @@ static void change_pte_range(struct mm_s
+ 		unsigned long addr, unsigned long end, pgprot_t newprot)
+ {
+ 	pte_t *pte;
++	spinlock_t *ptl;
+ 
+-	pte = pte_offset_map(pmd, addr);
++	pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ 	do {
+ 		if (pte_present(*pte)) {
+ 			pte_t ptent;
+@@ -44,7 +45,7 @@ static void change_pte_range(struct mm_s
+ 			lazy_mmu_prot_update(ptent);
+ 		}
+ 	} while (pte++, addr += PAGE_SIZE, addr != end);
+-	pte_unmap(pte - 1);
++	pte_unmap_unlock(pte - 1, ptl);
+ }
+ 
+ static inline void change_pmd_range(struct mm_struct *mm, pud_t *pud,
+@@ -88,7 +89,6 @@ static void change_protection(struct vm_
+ 	BUG_ON(addr >= end);
+ 	pgd = pgd_offset(mm, addr);
+ 	flush_cache_range(vma, addr, end);
+-	spin_lock(&mm->page_table_lock);
+ 	do {
+ 		next = pgd_addr_end(addr, end);
+ 		if (pgd_none_or_clear_bad(pgd))
+@@ -96,7 +96,6 @@ static void change_protection(struct vm_
+ 		change_pud_range(mm, pgd, addr, next, newprot);
+ 	} while (pgd++, addr = next, addr != end);
+ 	flush_tlb_range(vma, start, end);
+-	spin_unlock(&mm->page_table_lock);
+ }
+ 
+ static int
+@@ -125,6 +124,14 @@ mprotect_fixup(struct vm_area_struct *vm
+ 	 * a MAP_NORESERVE private mapping to writable will now reserve.
+ 	 */
+ 	if (newflags & VM_WRITE) {
++		if (oldflags & VM_RESERVED) {
++			BUG_ON(oldflags & VM_WRITE);
++			printk(KERN_WARNING "program %s is using MAP_PRIVATE, "
++				"PROT_WRITE mprotect of VM_RESERVED memory, "
++				"which is deprecated. Please report this to "
++				"linux-kernel at vger.kernel.org\n",current->comm);
++			return -EACCES;
++		}
+ 		if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_SHARED|VM_HUGETLB))) {
+ 			charged = nrpages;
+ 			if (security_vm_enough_memory(charged))
+@@ -168,8 +175,8 @@ success:
+ 	vma->vm_flags = newflags;
+ 	vma->vm_page_prot = newprot;
+ 	change_protection(vma, start, end, newprot);
+-	__vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
+-	__vm_stat_account(mm, newflags, vma->vm_file, nrpages);
++	vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
++	vm_stat_account(mm, newflags, vma->vm_file, nrpages);
+ 	return 0;
+ 
+ fail:
+diff --git a/mm/mremap.c b/mm/mremap.c
+--- a/mm/mremap.c
++++ b/mm/mremap.c
+@@ -22,35 +22,7 @@
+ #include <asm/cacheflush.h>
+ #include <asm/tlbflush.h>
+ 
+-static pte_t *get_one_pte_map_nested(struct mm_struct *mm, unsigned long addr)
+-{
+-	pgd_t *pgd;
+-	pud_t *pud;
+-	pmd_t *pmd;
+-	pte_t *pte = NULL;
+-
+-	pgd = pgd_offset(mm, addr);
+-	if (pgd_none_or_clear_bad(pgd))
+-		goto end;
+-
+-	pud = pud_offset(pgd, addr);
+-	if (pud_none_or_clear_bad(pud))
+-		goto end;
+-
+-	pmd = pmd_offset(pud, addr);
+-	if (pmd_none_or_clear_bad(pmd))
+-		goto end;
+-
+-	pte = pte_offset_map_nested(pmd, addr);
+-	if (pte_none(*pte)) {
+-		pte_unmap_nested(pte);
+-		pte = NULL;
+-	}
+-end:
+-	return pte;
+-}
+-
+-static pte_t *get_one_pte_map(struct mm_struct *mm, unsigned long addr)
++static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr)
+ {
+ 	pgd_t *pgd;
+ 	pud_t *pud;
+@@ -68,35 +40,39 @@ static pte_t *get_one_pte_map(struct mm_
+ 	if (pmd_none_or_clear_bad(pmd))
+ 		return NULL;
+ 
+-	return pte_offset_map(pmd, addr);
++	return pmd;
+ }
+ 
+-static inline pte_t *alloc_one_pte_map(struct mm_struct *mm, unsigned long addr)
++static pmd_t *alloc_new_pmd(struct mm_struct *mm, unsigned long addr)
+ {
+ 	pgd_t *pgd;
+ 	pud_t *pud;
+ 	pmd_t *pmd;
+-	pte_t *pte = NULL;
+ 
+ 	pgd = pgd_offset(mm, addr);
+-
+ 	pud = pud_alloc(mm, pgd, addr);
+ 	if (!pud)
+ 		return NULL;
++
+ 	pmd = pmd_alloc(mm, pud, addr);
+-	if (pmd)
+-		pte = pte_alloc_map(mm, pmd, addr);
+-	return pte;
++	if (!pmd)
++		return NULL;
++
++	if (!pmd_present(*pmd) && __pte_alloc(mm, pmd, addr))
++		return NULL;
++
++	return pmd;
+ }
+ 
+-static int
+-move_one_page(struct vm_area_struct *vma, unsigned long old_addr,
+-		struct vm_area_struct *new_vma, unsigned long new_addr)
++static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
++		unsigned long old_addr, unsigned long old_end,
++		struct vm_area_struct *new_vma, pmd_t *new_pmd,
++		unsigned long new_addr)
+ {
+ 	struct address_space *mapping = NULL;
+ 	struct mm_struct *mm = vma->vm_mm;
+-	int error = 0;
+-	pte_t *src, *dst;
++	pte_t *old_pte, *new_pte, pte;
++	spinlock_t *old_ptl, *new_ptl;
+ 
+ 	if (vma->vm_file) {
+ 		/*
+@@ -111,74 +87,69 @@ move_one_page(struct vm_area_struct *vma
+ 		    new_vma->vm_truncate_count != vma->vm_truncate_count)
+ 			new_vma->vm_truncate_count = 0;
+ 	}
+-	spin_lock(&mm->page_table_lock);
+ 
+-	src = get_one_pte_map_nested(mm, old_addr);
+-	if (src) {
+-		/*
+-		 * Look to see whether alloc_one_pte_map needs to perform a
+-		 * memory allocation.  If it does then we need to drop the
+-		 * atomic kmap
+-		 */
+-		dst = get_one_pte_map(mm, new_addr);
+-		if (unlikely(!dst)) {
+-			pte_unmap_nested(src);
+-			if (mapping)
+-				spin_unlock(&mapping->i_mmap_lock);
+-			dst = alloc_one_pte_map(mm, new_addr);
+-			if (mapping && !spin_trylock(&mapping->i_mmap_lock)) {
+-				spin_unlock(&mm->page_table_lock);
+-				spin_lock(&mapping->i_mmap_lock);
+-				spin_lock(&mm->page_table_lock);
+-			}
+-			src = get_one_pte_map_nested(mm, old_addr);
+-		}
+-		/*
+-		 * Since alloc_one_pte_map can drop and re-acquire
+-		 * page_table_lock, we should re-check the src entry...
+-		 */
+-		if (src) {
+-			if (dst) {
+-				pte_t pte;
+-				pte = ptep_clear_flush(vma, old_addr, src);
+-
+-				/* ZERO_PAGE can be dependant on virtual addr */
+-				pte = move_pte(pte, new_vma->vm_page_prot,
+-							old_addr, new_addr);
+-				set_pte_at(mm, new_addr, dst, pte);
+-			} else
+-				error = -ENOMEM;
+-			pte_unmap_nested(src);
+-		}
+-		if (dst)
+-			pte_unmap(dst);
+-	}
+-	spin_unlock(&mm->page_table_lock);
++	/*
++	 * We don't have to worry about the ordering of src and dst
++	 * pte locks because exclusive mmap_sem prevents deadlock.
++	 */
++	old_pte = pte_offset_map_lock(mm, old_pmd, old_addr, &old_ptl);
++ 	new_pte = pte_offset_map_nested(new_pmd, new_addr);
++	new_ptl = pte_lockptr(mm, new_pmd);
++	if (new_ptl != old_ptl)
++		spin_lock(new_ptl);
++
++	for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE,
++				   new_pte++, new_addr += PAGE_SIZE) {
++		if (pte_none(*old_pte))
++			continue;
++		pte = ptep_clear_flush(vma, old_addr, old_pte);
++		/* ZERO_PAGE can be dependant on virtual addr */
++		pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
++		set_pte_at(mm, new_addr, new_pte, pte);
++	}
++
++	if (new_ptl != old_ptl)
++		spin_unlock(new_ptl);
++	pte_unmap_nested(new_pte - 1);
++	pte_unmap_unlock(old_pte - 1, old_ptl);
+ 	if (mapping)
+ 		spin_unlock(&mapping->i_mmap_lock);
+-	return error;
+ }
+ 
++#define LATENCY_LIMIT	(64 * PAGE_SIZE)
++
+ static unsigned long move_page_tables(struct vm_area_struct *vma,
+ 		unsigned long old_addr, struct vm_area_struct *new_vma,
+ 		unsigned long new_addr, unsigned long len)
+ {
+-	unsigned long offset;
++	unsigned long extent, next, old_end;
++	pmd_t *old_pmd, *new_pmd;
+ 
+-	flush_cache_range(vma, old_addr, old_addr + len);
++	old_end = old_addr + len;
++	flush_cache_range(vma, old_addr, old_end);
+ 
+-	/*
+-	 * This is not the clever way to do this, but we're taking the
+-	 * easy way out on the assumption that most remappings will be
+-	 * only a few pages.. This also makes error recovery easier.
+-	 */
+-	for (offset = 0; offset < len; offset += PAGE_SIZE) {
+-		if (move_one_page(vma, old_addr + offset,
+-				new_vma, new_addr + offset) < 0)
+-			break;
++	for (; old_addr < old_end; old_addr += extent, new_addr += extent) {
+ 		cond_resched();
++		next = (old_addr + PMD_SIZE) & PMD_MASK;
++		if (next - 1 > old_end)
++			next = old_end;
++		extent = next - old_addr;
++		old_pmd = get_old_pmd(vma->vm_mm, old_addr);
++		if (!old_pmd)
++			continue;
++		new_pmd = alloc_new_pmd(vma->vm_mm, new_addr);
++		if (!new_pmd)
++			break;
++		next = (new_addr + PMD_SIZE) & PMD_MASK;
++		if (extent > next - new_addr)
++			extent = next - new_addr;
++		if (extent > LATENCY_LIMIT)
++			extent = LATENCY_LIMIT;
++		move_ptes(vma, old_pmd, old_addr, old_addr + extent,
++				new_vma, new_pmd, new_addr);
+ 	}
+-	return offset;
++
++	return len + old_addr - old_end;	/* how much done */
+ }
+ 
+ static unsigned long move_vma(struct vm_area_struct *vma,
+@@ -191,6 +162,7 @@ static unsigned long move_vma(struct vm_
+ 	unsigned long new_pgoff;
+ 	unsigned long moved_len;
+ 	unsigned long excess = 0;
++	unsigned long hiwater_vm;
+ 	int split = 0;
+ 
+ 	/*
+@@ -229,17 +201,24 @@ static unsigned long move_vma(struct vm_
+ 	}
+ 
+ 	/*
+-	 * if we failed to move page tables we still do total_vm increment
+-	 * since do_munmap() will decrement it by old_len == new_len
++	 * If we failed to move page tables we still do total_vm increment
++	 * since do_munmap() will decrement it by old_len == new_len.
++	 *
++	 * Since total_vm is about to be raised artificially high for a
++	 * moment, we need to restore high watermark afterwards: if stats
++	 * are taken meanwhile, total_vm and hiwater_vm appear too high.
++	 * If this were a serious issue, we'd add a flag to do_munmap().
+ 	 */
++	hiwater_vm = mm->hiwater_vm;
+ 	mm->total_vm += new_len >> PAGE_SHIFT;
+-	__vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
++	vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
+ 
+ 	if (do_munmap(mm, old_addr, old_len) < 0) {
+ 		/* OOM: unable to split vma, just get accounts right */
+ 		vm_unacct_memory(excess >> PAGE_SHIFT);
+ 		excess = 0;
+ 	}
++	mm->hiwater_vm = hiwater_vm;
+ 
+ 	/* Restore VM_ACCOUNT if one or two pieces of vma left */
+ 	if (excess) {
+@@ -269,6 +248,7 @@ unsigned long do_mremap(unsigned long ad
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, unsigned long new_addr)
+ {
++	struct mm_struct *mm = current->mm;
+ 	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+ 	unsigned long charged = 0;
+@@ -309,7 +289,7 @@ unsigned long do_mremap(unsigned long ad
+ 		if ((addr <= new_addr) && (addr+old_len) > new_addr)
+ 			goto out;
+ 
+-		ret = do_munmap(current->mm, new_addr, new_len);
++		ret = do_munmap(mm, new_addr, new_len);
+ 		if (ret)
+ 			goto out;
+ 	}
+@@ -320,7 +300,7 @@ unsigned long do_mremap(unsigned long ad
+ 	 * do_munmap does all the needed commit accounting
+ 	 */
+ 	if (old_len >= new_len) {
+-		ret = do_munmap(current->mm, addr+new_len, old_len - new_len);
++		ret = do_munmap(mm, addr+new_len, old_len - new_len);
+ 		if (ret && old_len != new_len)
+ 			goto out;
+ 		ret = addr;
+@@ -333,7 +313,7 @@ unsigned long do_mremap(unsigned long ad
+ 	 * Ok, we need to grow..  or relocate.
+ 	 */
+ 	ret = -EFAULT;
+-	vma = find_vma(current->mm, addr);
++	vma = find_vma(mm, addr);
+ 	if (!vma || vma->vm_start > addr)
+ 		goto out;
+ 	if (is_vm_hugetlb_page(vma)) {
+@@ -349,14 +329,14 @@ unsigned long do_mremap(unsigned long ad
+ 	}
+ 	if (vma->vm_flags & VM_LOCKED) {
+ 		unsigned long locked, lock_limit;
+-		locked = current->mm->locked_vm << PAGE_SHIFT;
++		locked = mm->locked_vm << PAGE_SHIFT;
+ 		lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ 		locked += new_len - old_len;
+ 		ret = -EAGAIN;
+ 		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+ 			goto out;
+ 	}
+-	if (!may_expand_vm(current->mm, (new_len - old_len) >> PAGE_SHIFT)) {
++	if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
+ 		ret = -ENOMEM;
+ 		goto out;
+ 	}
+@@ -383,11 +363,10 @@ unsigned long do_mremap(unsigned long ad
+ 			vma_adjust(vma, vma->vm_start,
+ 				addr + new_len, vma->vm_pgoff, NULL);
+ 
+-			current->mm->total_vm += pages;
+-			__vm_stat_account(vma->vm_mm, vma->vm_flags,
+-							vma->vm_file, pages);
++			mm->total_vm += pages;
++			vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
+ 			if (vma->vm_flags & VM_LOCKED) {
+-				current->mm->locked_vm += pages;
++				mm->locked_vm += pages;
+ 				make_pages_present(addr + old_len,
+ 						   addr + new_len);
+ 			}
+diff --git a/mm/msync.c b/mm/msync.c
+--- a/mm/msync.c
++++ b/mm/msync.c
+@@ -17,40 +17,48 @@
+ #include <asm/pgtable.h>
+ #include <asm/tlbflush.h>
+ 
+-/*
+- * Called with mm->page_table_lock held to protect against other
+- * threads/the swapper from ripping pte's out from under us.
+- */
+-
+-static void sync_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
++static void msync_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+ 				unsigned long addr, unsigned long end)
+ {
+ 	pte_t *pte;
++	spinlock_t *ptl;
++	int progress = 0;
+ 
+-	pte = pte_offset_map(pmd, addr);
++again:
++	pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+ 	do {
+ 		unsigned long pfn;
+ 		struct page *page;
+ 
++		if (progress >= 64) {
++			progress = 0;
++			if (need_resched() || need_lockbreak(ptl))
++				break;
++		}
++		progress++;
+ 		if (!pte_present(*pte))
+ 			continue;
+ 		if (!pte_maybe_dirty(*pte))
+ 			continue;
+ 		pfn = pte_pfn(*pte);
+-		if (!pfn_valid(pfn))
++		if (unlikely(!pfn_valid(pfn))) {
++			print_bad_pte(vma, *pte, addr);
+ 			continue;
++		}
+ 		page = pfn_to_page(pfn);
+-		if (PageReserved(page))
+-			continue;
+ 
+ 		if (ptep_clear_flush_dirty(vma, addr, pte) ||
+ 		    page_test_and_clear_dirty(page))
+ 			set_page_dirty(page);
++		progress += 3;
+ 	} while (pte++, addr += PAGE_SIZE, addr != end);
+-	pte_unmap(pte - 1);
++	pte_unmap_unlock(pte - 1, ptl);
++	cond_resched();
++	if (addr != end)
++		goto again;
+ }
+ 
+-static inline void sync_pmd_range(struct vm_area_struct *vma, pud_t *pud,
++static inline void msync_pmd_range(struct vm_area_struct *vma, pud_t *pud,
+ 				unsigned long addr, unsigned long end)
+ {
+ 	pmd_t *pmd;
+@@ -61,11 +69,11 @@ static inline void sync_pmd_range(struct
+ 		next = pmd_addr_end(addr, end);
+ 		if (pmd_none_or_clear_bad(pmd))
+ 			continue;
+-		sync_pte_range(vma, pmd, addr, next);
++		msync_pte_range(vma, pmd, addr, next);
+ 	} while (pmd++, addr = next, addr != end);
+ }
+ 
+-static inline void sync_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
++static inline void msync_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
+ 				unsigned long addr, unsigned long end)
+ {
+ 	pud_t *pud;
+@@ -76,58 +84,34 @@ static inline void sync_pud_range(struct
+ 		next = pud_addr_end(addr, end);
+ 		if (pud_none_or_clear_bad(pud))
+ 			continue;
+-		sync_pmd_range(vma, pud, addr, next);
++		msync_pmd_range(vma, pud, addr, next);
+ 	} while (pud++, addr = next, addr != end);
+ }
+ 
+-static void sync_page_range(struct vm_area_struct *vma,
++static void msync_page_range(struct vm_area_struct *vma,
+ 				unsigned long addr, unsigned long end)
+ {
+-	struct mm_struct *mm = vma->vm_mm;
+ 	pgd_t *pgd;
+ 	unsigned long next;
+ 
+ 	/* For hugepages we can't go walking the page table normally,
+ 	 * but that's ok, hugetlbfs is memory based, so we don't need
+-	 * to do anything more on an msync() */
+-	if (is_vm_hugetlb_page(vma))
++	 * to do anything more on an msync().
++	 * Can't do anything with VM_RESERVED regions either.
++	 */
++	if (vma->vm_flags & (VM_HUGETLB|VM_RESERVED))
+ 		return;
+ 
+ 	BUG_ON(addr >= end);
+-	pgd = pgd_offset(mm, addr);
++	pgd = pgd_offset(vma->vm_mm, addr);
+ 	flush_cache_range(vma, addr, end);
+-	spin_lock(&mm->page_table_lock);
+ 	do {
+ 		next = pgd_addr_end(addr, end);
+ 		if (pgd_none_or_clear_bad(pgd))
+ 			continue;
+-		sync_pud_range(vma, pgd, addr, next);
++		msync_pud_range(vma, pgd, addr, next);
+ 	} while (pgd++, addr = next, addr != end);
+-	spin_unlock(&mm->page_table_lock);
+-}
+-
+-#ifdef CONFIG_PREEMPT
+-static inline void filemap_sync(struct vm_area_struct *vma,
+-				unsigned long addr, unsigned long end)
+-{
+-	const size_t chunk = 64 * 1024;	/* bytes */
+-	unsigned long next;
+-
+-	do {
+-		next = addr + chunk;
+-		if (next > end || next < addr)
+-			next = end;
+-		sync_page_range(vma, addr, next);
+-		cond_resched();
+-	} while (addr = next, addr != end);
+-}
+-#else
+-static inline void filemap_sync(struct vm_area_struct *vma,
+-				unsigned long addr, unsigned long end)
+-{
+-	sync_page_range(vma, addr, end);
+ }
+-#endif
+ 
+ /*
+  * MS_SYNC syncs the entire file - including mappings.
+@@ -150,7 +134,7 @@ static int msync_interval(struct vm_area
+ 		return -EBUSY;
+ 
+ 	if (file && (vma->vm_flags & VM_SHARED)) {
+-		filemap_sync(vma, addr, end);
++		msync_page_range(vma, addr, end);
+ 
+ 		if (flags & MS_SYNC) {
+ 			struct address_space *mapping = file->f_mapping;
+diff --git a/mm/nommu.c b/mm/nommu.c
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -931,6 +931,8 @@ int do_munmap(struct mm_struct *mm, unsi
+ 	realalloc -= kobjsize(vml);
+ 	askedalloc -= sizeof(*vml);
+ 	kfree(vml);
++
++	update_hiwater_vm(mm);
+ 	mm->total_vm -= len >> PAGE_SHIFT;
+ 
+ #ifdef DEBUG
+@@ -1047,7 +1049,8 @@ struct vm_area_struct *find_vma(struct m
+ 
+ EXPORT_SYMBOL(find_vma);
+ 
+-struct page * follow_page(struct mm_struct *mm, unsigned long addr, int write)
++struct page *follow_page(struct mm_struct *mm, unsigned long address,
++			unsigned int foll_flags)
+ {
+ 	return NULL;
+ }
+@@ -1078,19 +1081,6 @@ void arch_unmap_area(struct mm_struct *m
+ {
+ }
+ 
+-void update_mem_hiwater(struct task_struct *tsk)
+-{
+-	unsigned long rss;
+-
+-	if (likely(tsk->mm)) {
+-		rss = get_mm_counter(tsk->mm, rss);
+-		if (tsk->mm->hiwater_rss < rss)
+-			tsk->mm->hiwater_rss = rss;
+-		if (tsk->mm->hiwater_vm < tsk->mm->total_vm)
+-			tsk->mm->hiwater_vm = tsk->mm->total_vm;
+-	}
+-}
+-
+ void unmap_mapping_range(struct address_space *mapping,
+ 			 loff_t const holebegin, loff_t const holelen,
+ 			 int even_cows)
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -33,6 +33,7 @@
+ #include <linux/sysctl.h>
+ #include <linux/cpu.h>
+ #include <linux/cpuset.h>
++#include <linux/memory_hotplug.h>
+ #include <linux/nodemask.h>
+ #include <linux/vmalloc.h>
+ 
+@@ -78,21 +79,44 @@ int min_free_kbytes = 1024;
+ unsigned long __initdata nr_kernel_pages;
+ unsigned long __initdata nr_all_pages;
+ 
++static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
++{
++	int ret = 0;
++	unsigned seq;
++	unsigned long pfn = page_to_pfn(page);
++
++	do {
++		seq = zone_span_seqbegin(zone);
++		if (pfn >= zone->zone_start_pfn + zone->spanned_pages)
++			ret = 1;
++		else if (pfn < zone->zone_start_pfn)
++			ret = 1;
++	} while (zone_span_seqretry(zone, seq));
++
++	return ret;
++}
++
++static int page_is_consistent(struct zone *zone, struct page *page)
++{
++#ifdef CONFIG_HOLES_IN_ZONE
++	if (!pfn_valid(page_to_pfn(page)))
++		return 0;
++#endif
++	if (zone != page_zone(page))
++		return 0;
++
++	return 1;
++}
+ /*
+  * Temporary debugging check for pages not lying within a given zone.
+  */
+ static int bad_range(struct zone *zone, struct page *page)
+ {
+-	if (page_to_pfn(page) >= zone->zone_start_pfn + zone->spanned_pages)
++	if (page_outside_zone_boundaries(zone, page))
+ 		return 1;
+-	if (page_to_pfn(page) < zone->zone_start_pfn)
+-		return 1;
+-#ifdef CONFIG_HOLES_IN_ZONE
+-	if (!pfn_valid(page_to_pfn(page)))
+-		return 1;
+-#endif
+-	if (zone != page_zone(page))
++	if (!page_is_consistent(zone, page))
+ 		return 1;
++
+ 	return 0;
+ }
+ 
+@@ -114,7 +138,8 @@ static void bad_page(const char *functio
+ 			1 << PG_reclaim |
+ 			1 << PG_slab    |
+ 			1 << PG_swapcache |
+-			1 << PG_writeback);
++			1 << PG_writeback |
++			1 << PG_reserved );
+ 	set_page_count(page, 0);
+ 	reset_page_mapcount(page);
+ 	page->mapping = NULL;
+@@ -153,7 +178,7 @@ static void prep_compound_page(struct pa
+ 		struct page *p = page + i;
+ 
+ 		SetPageCompound(p);
+-		p->private = (unsigned long)page;
++		set_page_private(p, (unsigned long)page);
+ 	}
+ }
+ 
+@@ -173,7 +198,7 @@ static void destroy_compound_page(struct
+ 
+ 		if (!PageCompound(p))
+ 			bad_page(__FUNCTION__, page);
+-		if (p->private != (unsigned long)page)
++		if (page_private(p) != (unsigned long)page)
+ 			bad_page(__FUNCTION__, page);
+ 		ClearPageCompound(p);
+ 	}
+@@ -186,18 +211,18 @@ static void destroy_compound_page(struct
+  * So, we don't need atomic page->flags operations here.
+  */
+ static inline unsigned long page_order(struct page *page) {
+-	return page->private;
++	return page_private(page);
+ }
+ 
+ static inline void set_page_order(struct page *page, int order) {
+-	page->private = order;
++	set_page_private(page, order);
+ 	__SetPagePrivate(page);
+ }
+ 
+ static inline void rmv_page_order(struct page *page)
+ {
+ 	__ClearPagePrivate(page);
+-	page->private = 0;
++	set_page_private(page, 0);
+ }
+ 
+ /*
+@@ -237,14 +262,13 @@ __find_combined_index(unsigned long page
+  * (a) the buddy is free &&
+  * (b) the buddy is on the buddy system &&
+  * (c) a page and its buddy have the same order.
+- * for recording page's order, we use page->private and PG_private.
++ * for recording page's order, we use page_private(page) and PG_private.
+  *
+  */
+ static inline int page_is_buddy(struct page *page, int order)
+ {
+        if (PagePrivate(page)           &&
+            (page_order(page) == order) &&
+-           !PageReserved(page)         &&
+             page_count(page) == 0)
+                return 1;
+        return 0;
+@@ -264,7 +288,7 @@ static inline int page_is_buddy(struct p
+  * parts of the VM system.
+  * At each level, we keep a list of pages, which are heads of continuous
+  * free pages of length of (1 << order) and marked with PG_Private.Page's
+- * order is recorded in page->private field.
++ * order is recorded in page_private(page) field.
+  * So when we are allocating or freeing one, we can derive the state of the
+  * other.  That is, if we allocate a small block, and both were   
+  * free, the remainder of the region must be split into blocks.   
+@@ -327,7 +351,8 @@ static inline void free_pages_check(cons
+ 			1 << PG_reclaim	|
+ 			1 << PG_slab	|
+ 			1 << PG_swapcache |
+-			1 << PG_writeback )))
++			1 << PG_writeback |
++			1 << PG_reserved )))
+ 		bad_page(function, page);
+ 	if (PageDirty(page))
+ 		__ClearPageDirty(page);
+@@ -455,13 +480,14 @@ static void prep_new_page(struct page *p
+ 			1 << PG_reclaim	|
+ 			1 << PG_slab    |
+ 			1 << PG_swapcache |
+-			1 << PG_writeback )))
++			1 << PG_writeback |
++			1 << PG_reserved )))
+ 		bad_page(__FUNCTION__, page);
+ 
+ 	page->flags &= ~(1 << PG_uptodate | 1 << PG_error |
+ 			1 << PG_referenced | 1 << PG_arch_1 |
+ 			1 << PG_checked | 1 << PG_mappedtodisk);
+-	page->private = 0;
++	set_page_private(page, 0);
+ 	set_page_refs(page, order);
+ 	kernel_map_pages(page, 1 << order, 1);
+ }
+@@ -734,7 +760,7 @@ buffered_rmqueue(struct zone *zone, int 
+  * of the allocation.
+  */
+ int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
+-		      int classzone_idx, int can_try_harder, int gfp_high)
++		      int classzone_idx, int can_try_harder, gfp_t gfp_high)
+ {
+ 	/* free_pages my go negative - that's OK */
+ 	long min = mark, free_pages = z->free_pages - (1 << order) + 1;
+@@ -777,7 +803,7 @@ struct page * fastcall
+ __alloc_pages(gfp_t gfp_mask, unsigned int order,
+ 		struct zonelist *zonelist)
+ {
+-	const int wait = gfp_mask & __GFP_WAIT;
++	const gfp_t wait = gfp_mask & __GFP_WAIT;
+ 	struct zone **zones, *z;
+ 	struct page *page;
+ 	struct reclaim_state reclaim_state;
+@@ -996,7 +1022,7 @@ fastcall unsigned long get_zeroed_page(g
+ 	 * get_zeroed_page() returns a 32-bit address, which cannot represent
+ 	 * a highmem page
+ 	 */
+-	BUG_ON(gfp_mask & __GFP_HIGHMEM);
++	BUG_ON((gfp_mask & __GFP_HIGHMEM) != 0);
+ 
+ 	page = alloc_pages(gfp_mask | __GFP_ZERO, 0);
+ 	if (page)
+@@ -1016,7 +1042,7 @@ void __pagevec_free(struct pagevec *pvec
+ 
+ fastcall void __free_pages(struct page *page, unsigned int order)
+ {
+-	if (!PageReserved(page) && put_page_testzero(page)) {
++	if (put_page_testzero(page)) {
+ 		if (order == 0)
+ 			free_hot_page(page);
+ 		else
+@@ -1089,7 +1115,7 @@ static unsigned int nr_free_zone_pages(i
+  */
+ unsigned int nr_free_buffer_pages(void)
+ {
+-	return nr_free_zone_pages(GFP_USER & GFP_ZONEMASK);
++	return nr_free_zone_pages(gfp_zone(GFP_USER));
+ }
+ 
+ /*
+@@ -1097,7 +1123,7 @@ unsigned int nr_free_buffer_pages(void)
+  */
+ unsigned int nr_free_pagecache_pages(void)
+ {
+-	return nr_free_zone_pages(GFP_HIGHUSER & GFP_ZONEMASK);
++	return nr_free_zone_pages(gfp_zone(GFP_HIGHUSER));
+ }
+ 
+ #ifdef CONFIG_HIGHMEM
+@@ -1305,12 +1331,9 @@ void show_free_areas(void)
+ 		} else
+ 			printk("\n");
+ 
+-		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
++		for_each_cpu(cpu) {
+ 			struct per_cpu_pageset *pageset;
+ 
+-			if (!cpu_possible(cpu))
+-				continue;
+-
+ 			pageset = zone_pcp(zone, cpu);
+ 
+ 			for (temperature = 0; temperature < 2; temperature++)
+@@ -1428,6 +1451,16 @@ static int __init build_zonelists_node(p
+ 	return j;
+ }
+ 
++static inline int highest_zone(int zone_bits)
++{
++	int res = ZONE_NORMAL;
++	if (zone_bits & (__force int)__GFP_HIGHMEM)
++		res = ZONE_HIGHMEM;
++	if (zone_bits & (__force int)__GFP_DMA)
++		res = ZONE_DMA;
++	return res;
++}
++
+ #ifdef CONFIG_NUMA
+ #define MAX_NODE_LOAD (num_online_nodes())
+ static int __initdata node_load[MAX_NUMNODES];
+@@ -1524,11 +1557,7 @@ static void __init build_zonelists(pg_da
+ 			zonelist = pgdat->node_zonelists + i;
+ 			for (j = 0; zonelist->zones[j] != NULL; j++);
+ 
+-			k = ZONE_NORMAL;
+-			if (i & __GFP_HIGHMEM)
+-				k = ZONE_HIGHMEM;
+-			if (i & __GFP_DMA)
+-				k = ZONE_DMA;
++			k = highest_zone(i);
+ 
+ 	 		j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
+ 			zonelist->zones[j] = NULL;
+@@ -1549,12 +1578,7 @@ static void __init build_zonelists(pg_da
+ 		zonelist = pgdat->node_zonelists + i;
+ 
+ 		j = 0;
+-		k = ZONE_NORMAL;
+-		if (i & __GFP_HIGHMEM)
+-			k = ZONE_HIGHMEM;
+-		if (i & __GFP_DMA)
+-			k = ZONE_DMA;
+-
++		k = highest_zone(i);
+  		j = build_zonelists_node(pgdat, zonelist, j, k);
+  		/*
+  		 * Now we build the zonelist so that it contains the zones
+@@ -1659,7 +1683,7 @@ static void __init calculate_zone_totalp
+  * up by free_all_bootmem() once the early boot process is
+  * done. Non-atomic initialization, single-pass.
+  */
+-void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone,
++void __devinit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
+ 		unsigned long start_pfn)
+ {
+ 	struct page *page;
+@@ -1673,7 +1697,7 @@ void __init memmap_init_zone(unsigned lo
+ 			continue;
+ 		page = pfn_to_page(pfn);
+ 		set_page_links(page, zone, nid, pfn);
+-		set_page_count(page, 0);
++		set_page_count(page, 1);
+ 		reset_page_mapcount(page);
+ 		SetPageReserved(page);
+ 		INIT_LIST_HEAD(&page->lru);
+@@ -1720,29 +1744,29 @@ static int __devinit zone_batchsize(stru
+ 
+ 	/*
+ 	 * The per-cpu-pages pools are set to around 1000th of the
+-	 * size of the zone.  But no more than 1/4 of a meg - there's
+-	 * no point in going beyond the size of L2 cache.
++	 * size of the zone.  But no more than 1/2 of a meg.
+ 	 *
+ 	 * OK, so we don't know how big the cache is.  So guess.
+ 	 */
+ 	batch = zone->present_pages / 1024;
+-	if (batch * PAGE_SIZE > 256 * 1024)
+-		batch = (256 * 1024) / PAGE_SIZE;
++	if (batch * PAGE_SIZE > 512 * 1024)
++		batch = (512 * 1024) / PAGE_SIZE;
+ 	batch /= 4;		/* We effectively *= 4 below */
+ 	if (batch < 1)
+ 		batch = 1;
+ 
+ 	/*
+-	 * Clamp the batch to a 2^n - 1 value. Having a power
+-	 * of 2 value was found to be more likely to have
+-	 * suboptimal cache aliasing properties in some cases.
++	 * We will be trying to allcoate bigger chunks of contiguous
++	 * memory of the order of fls(batch).  This should result in
++	 * better cache coloring.
+ 	 *
+-	 * For example if 2 tasks are alternately allocating
+-	 * batches of pages, one task can end up with a lot
+-	 * of pages of one half of the possible page colors
+-	 * and the other with pages of the other colors.
++	 * A sanity check also to ensure that batch is still in limits.
+ 	 */
+-	batch = (1 << fls(batch + batch/2)) - 1;
++	batch = (1 << fls(batch + batch/2));
++
++	if (fls(batch) >= (PAGE_SHIFT + MAX_ORDER - 2))
++		batch = PAGE_SHIFT + ((MAX_ORDER - 1 - PAGE_SHIFT)/2);
++
+ 	return batch;
+ }
+ 
+@@ -1754,7 +1778,7 @@ inline void setup_pageset(struct per_cpu
+ 
+ 	pcp = &p->pcp[0];		/* hot */
+ 	pcp->count = 0;
+-	pcp->low = 2 * batch;
++	pcp->low = 0;
+ 	pcp->high = 6 * batch;
+ 	pcp->batch = max(1UL, 1 * batch);
+ 	INIT_LIST_HEAD(&pcp->list);
+@@ -1763,7 +1787,7 @@ inline void setup_pageset(struct per_cpu
+ 	pcp->count = 0;
+ 	pcp->low = 0;
+ 	pcp->high = 2 * batch;
+-	pcp->batch = max(1UL, 1 * batch);
++	pcp->batch = max(1UL, batch/2);
+ 	INIT_LIST_HEAD(&pcp->list);
+ }
+ 
+@@ -1872,6 +1896,60 @@ void __init setup_per_cpu_pageset()
+ 
+ #endif
+ 
++static __devinit
++void zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages)
++{
++	int i;
++	struct pglist_data *pgdat = zone->zone_pgdat;
++
++	/*
++	 * The per-page waitqueue mechanism uses hashed waitqueues
++	 * per zone.
++	 */
++	zone->wait_table_size = wait_table_size(zone_size_pages);
++	zone->wait_table_bits =	wait_table_bits(zone->wait_table_size);
++	zone->wait_table = (wait_queue_head_t *)
++		alloc_bootmem_node(pgdat, zone->wait_table_size
++					* sizeof(wait_queue_head_t));
++
++	for(i = 0; i < zone->wait_table_size; ++i)
++		init_waitqueue_head(zone->wait_table + i);
++}
++
++static __devinit void zone_pcp_init(struct zone *zone)
++{
++	int cpu;
++	unsigned long batch = zone_batchsize(zone);
++
++	for (cpu = 0; cpu < NR_CPUS; cpu++) {
++#ifdef CONFIG_NUMA
++		/* Early boot. Slab allocator not functional yet */
++		zone->pageset[cpu] = &boot_pageset[cpu];
++		setup_pageset(&boot_pageset[cpu],0);
++#else
++		setup_pageset(zone_pcp(zone,cpu), batch);
++#endif
++	}
++	printk(KERN_DEBUG "  %s zone: %lu pages, LIFO batch:%lu\n",
++		zone->name, zone->present_pages, batch);
++}
++
++static __devinit void init_currently_empty_zone(struct zone *zone,
++		unsigned long zone_start_pfn, unsigned long size)
++{
++	struct pglist_data *pgdat = zone->zone_pgdat;
++
++	zone_wait_table_init(zone, size);
++	pgdat->nr_zones = zone_idx(zone) + 1;
++
++	zone->zone_mem_map = pfn_to_page(zone_start_pfn);
++	zone->zone_start_pfn = zone_start_pfn;
++
++	memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn);
++
++	zone_init_free_lists(pgdat, zone, zone->spanned_pages);
++}
++
+ /*
+  * Set up the zone data structures:
+  *   - mark all pages reserved
+@@ -1881,10 +1959,11 @@ void __init setup_per_cpu_pageset()
+ static void __init free_area_init_core(struct pglist_data *pgdat,
+ 		unsigned long *zones_size, unsigned long *zholes_size)
+ {
+-	unsigned long i, j;
+-	int cpu, nid = pgdat->node_id;
++	unsigned long j;
++	int nid = pgdat->node_id;
+ 	unsigned long zone_start_pfn = pgdat->node_start_pfn;
+ 
++	pgdat_resize_init(pgdat);
+ 	pgdat->nr_zones = 0;
+ 	init_waitqueue_head(&pgdat->kswapd_wait);
+ 	pgdat->kswapd_max_order = 0;
+@@ -1892,7 +1971,6 @@ static void __init free_area_init_core(s
+ 	for (j = 0; j < MAX_NR_ZONES; j++) {
+ 		struct zone *zone = pgdat->node_zones + j;
+ 		unsigned long size, realsize;
+-		unsigned long batch;
+ 
+ 		realsize = size = zones_size[j];
+ 		if (zholes_size)
+@@ -1907,24 +1985,13 @@ static void __init free_area_init_core(s
+ 		zone->name = zone_names[j];
+ 		spin_lock_init(&zone->lock);
+ 		spin_lock_init(&zone->lru_lock);
++		zone_seqlock_init(zone);
+ 		zone->zone_pgdat = pgdat;
+ 		zone->free_pages = 0;
+ 
+ 		zone->temp_priority = zone->prev_priority = DEF_PRIORITY;
+ 
+-		batch = zone_batchsize(zone);
+-
+-		for (cpu = 0; cpu < NR_CPUS; cpu++) {
+-#ifdef CONFIG_NUMA
+-			/* Early boot. Slab allocator not functional yet */
+-			zone->pageset[cpu] = &boot_pageset[cpu];
+-			setup_pageset(&boot_pageset[cpu],0);
+-#else
+-			setup_pageset(zone_pcp(zone,cpu), batch);
+-#endif
+-		}
+-		printk(KERN_DEBUG "  %s zone: %lu pages, LIFO batch:%lu\n",
+-				zone_names[j], realsize, batch);
++		zone_pcp_init(zone);
+ 		INIT_LIST_HEAD(&zone->active_list);
+ 		INIT_LIST_HEAD(&zone->inactive_list);
+ 		zone->nr_scan_active = 0;
+@@ -1935,32 +2002,9 @@ static void __init free_area_init_core(s
+ 		if (!size)
+ 			continue;
+ 
+-		/*
+-		 * The per-page waitqueue mechanism uses hashed waitqueues
+-		 * per zone.
+-		 */
+-		zone->wait_table_size = wait_table_size(size);
+-		zone->wait_table_bits =
+-			wait_table_bits(zone->wait_table_size);
+-		zone->wait_table = (wait_queue_head_t *)
+-			alloc_bootmem_node(pgdat, zone->wait_table_size
+-						* sizeof(wait_queue_head_t));
+-
+-		for(i = 0; i < zone->wait_table_size; ++i)
+-			init_waitqueue_head(zone->wait_table + i);
+-
+-		pgdat->nr_zones = j+1;
+-
+-		zone->zone_mem_map = pfn_to_page(zone_start_pfn);
+-		zone->zone_start_pfn = zone_start_pfn;
+-
+-		memmap_init(size, nid, j, zone_start_pfn);
+-
+ 		zonetable_add(zone, nid, j, zone_start_pfn, size);
+-
++		init_currently_empty_zone(zone, zone_start_pfn, size);
+ 		zone_start_pfn += size;
+-
+-		zone_init_free_lists(pgdat, zone, zone->spanned_pages);
+ 	}
+ }
+ 
+@@ -2360,7 +2404,7 @@ static void setup_per_zone_lowmem_reserv
+  *	that the pages_{min,low,high} values for each zone are set correctly 
+  *	with respect to min_free_kbytes.
+  */
+-static void setup_per_zone_pages_min(void)
++void setup_per_zone_pages_min(void)
+ {
+ 	unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
+ 	unsigned long lowmem_pages = 0;
+diff --git a/mm/page_io.c b/mm/page_io.c
+--- a/mm/page_io.c
++++ b/mm/page_io.c
+@@ -91,7 +91,8 @@ int swap_writepage(struct page *page, st
+ 		unlock_page(page);
+ 		goto out;
+ 	}
+-	bio = get_swap_bio(GFP_NOIO, page->private, page, end_swap_bio_write);
++	bio = get_swap_bio(GFP_NOIO, page_private(page), page,
++				end_swap_bio_write);
+ 	if (bio == NULL) {
+ 		set_page_dirty(page);
+ 		unlock_page(page);
+@@ -115,7 +116,8 @@ int swap_readpage(struct file *file, str
+ 
+ 	BUG_ON(!PageLocked(page));
+ 	ClearPageUptodate(page);
+-	bio = get_swap_bio(GFP_KERNEL, page->private, page, end_swap_bio_read);
++	bio = get_swap_bio(GFP_KERNEL, page_private(page), page,
++				end_swap_bio_read);
+ 	if (bio == NULL) {
+ 		unlock_page(page);
+ 		ret = -ENOMEM;
+diff --git a/mm/pdflush.c b/mm/pdflush.c
+--- a/mm/pdflush.c
++++ b/mm/pdflush.c
+@@ -20,6 +20,7 @@
+ #include <linux/fs.h>		// Needed by writeback.h
+ #include <linux/writeback.h>	// Prototypes pdflush_operation()
+ #include <linux/kthread.h>
++#include <linux/cpuset.h>
+ 
+ 
+ /*
+@@ -170,12 +171,24 @@ static int __pdflush(struct pdflush_work
+ static int pdflush(void *dummy)
+ {
+ 	struct pdflush_work my_work;
++	cpumask_t cpus_allowed;
+ 
+ 	/*
+ 	 * pdflush can spend a lot of time doing encryption via dm-crypt.  We
+ 	 * don't want to do that at keventd's priority.
+ 	 */
+ 	set_user_nice(current, 0);
++
++	/*
++	 * Some configs put our parent kthread in a limited cpuset,
++	 * which kthread() overrides, forcing cpus_allowed == CPU_MASK_ALL.
++	 * Our needs are more modest - cut back to our cpusets cpus_allowed.
++	 * This is needed as pdflush's are dynamically created and destroyed.
++	 * The boottime pdflush's are easily placed w/o these 2 lines.
++	 */
++	cpus_allowed = cpuset_cpus_allowed(current);
++	set_cpus_allowed(current, cpus_allowed);
++
+ 	return __pdflush(&my_work);
+ }
+ 
+diff --git a/mm/rmap.c b/mm/rmap.c
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -32,7 +32,7 @@
+  *   page->flags PG_locked (lock_page)
+  *     mapping->i_mmap_lock
+  *       anon_vma->lock
+- *         mm->page_table_lock
++ *         mm->page_table_lock or pte_lock
+  *           zone->lru_lock (in mark_page_accessed)
+  *           swap_lock (in swap_duplicate, swap_info_get)
+  *             mmlist_lock (in mmput, drain_mmlist and others)
+@@ -244,37 +244,44 @@ unsigned long page_address_in_vma(struct
+ /*
+  * Check that @page is mapped at @address into @mm.
+  *
+- * On success returns with mapped pte and locked mm->page_table_lock.
++ * On success returns with pte mapped and locked.
+  */
+ pte_t *page_check_address(struct page *page, struct mm_struct *mm,
+-			  unsigned long address)
++			  unsigned long address, spinlock_t **ptlp)
+ {
+ 	pgd_t *pgd;
+ 	pud_t *pud;
+ 	pmd_t *pmd;
+ 	pte_t *pte;
++	spinlock_t *ptl;
+ 
+-	/*
+-	 * We need the page_table_lock to protect us from page faults,
+-	 * munmap, fork, etc...
+-	 */
+-	spin_lock(&mm->page_table_lock);
+ 	pgd = pgd_offset(mm, address);
+-	if (likely(pgd_present(*pgd))) {
+-		pud = pud_offset(pgd, address);
+-		if (likely(pud_present(*pud))) {
+-			pmd = pmd_offset(pud, address);
+-			if (likely(pmd_present(*pmd))) {
+-				pte = pte_offset_map(pmd, address);
+-				if (likely(pte_present(*pte) &&
+-					   page_to_pfn(page) == pte_pfn(*pte)))
+-					return pte;
+-				pte_unmap(pte);
+-			}
+-		}
++	if (!pgd_present(*pgd))
++		return NULL;
++
++	pud = pud_offset(pgd, address);
++	if (!pud_present(*pud))
++		return NULL;
++
++	pmd = pmd_offset(pud, address);
++	if (!pmd_present(*pmd))
++		return NULL;
++
++	pte = pte_offset_map(pmd, address);
++	/* Make a quick check before getting the lock */
++	if (!pte_present(*pte)) {
++		pte_unmap(pte);
++		return NULL;
++	}
++
++	ptl = pte_lockptr(mm, pmd);
++	spin_lock(ptl);
++	if (pte_present(*pte) && page_to_pfn(page) == pte_pfn(*pte)) {
++		*ptlp = ptl;
++		return pte;
+ 	}
+-	spin_unlock(&mm->page_table_lock);
+-	return ERR_PTR(-ENOENT);
++	pte_unmap_unlock(pte, ptl);
++	return NULL;
+ }
+ 
+ /*
+@@ -287,24 +294,28 @@ static int page_referenced_one(struct pa
+ 	struct mm_struct *mm = vma->vm_mm;
+ 	unsigned long address;
+ 	pte_t *pte;
++	spinlock_t *ptl;
+ 	int referenced = 0;
+ 
+ 	address = vma_address(page, vma);
+ 	if (address == -EFAULT)
+ 		goto out;
+ 
+-	pte = page_check_address(page, mm, address);
+-	if (!IS_ERR(pte)) {
+-		if (ptep_clear_flush_young(vma, address, pte))
+-			referenced++;
++	pte = page_check_address(page, mm, address, &ptl);
++	if (!pte)
++		goto out;
+ 
+-		if (mm != current->mm && !ignore_token && has_swap_token(mm))
+-			referenced++;
++	if (ptep_clear_flush_young(vma, address, pte))
++		referenced++;
+ 
+-		(*mapcount)--;
+-		pte_unmap(pte);
+-		spin_unlock(&mm->page_table_lock);
+-	}
++	/* Pretend the page is referenced if the task has the
++	   swap token and is in the middle of a page fault. */
++	if (mm != current->mm && !ignore_token && has_swap_token(mm) &&
++			rwsem_is_locked(&mm->mmap_sem))
++		referenced++;
++
++	(*mapcount)--;
++	pte_unmap_unlock(pte, ptl);
+ out:
+ 	return referenced;
+ }
+@@ -434,15 +445,11 @@ int page_referenced(struct page *page, i
+  * @vma:	the vm area in which the mapping is added
+  * @address:	the user virtual address mapped
+  *
+- * The caller needs to hold the mm->page_table_lock.
++ * The caller needs to hold the pte lock.
+  */
+ void page_add_anon_rmap(struct page *page,
+ 	struct vm_area_struct *vma, unsigned long address)
+ {
+-	BUG_ON(PageReserved(page));
+-
+-	inc_mm_counter(vma->vm_mm, anon_rss);
+-
+ 	if (atomic_inc_and_test(&page->_mapcount)) {
+ 		struct anon_vma *anon_vma = vma->anon_vma;
+ 
+@@ -461,13 +468,12 @@ void page_add_anon_rmap(struct page *pag
+  * page_add_file_rmap - add pte mapping to a file page
+  * @page: the page to add the mapping to
+  *
+- * The caller needs to hold the mm->page_table_lock.
++ * The caller needs to hold the pte lock.
+  */
+ void page_add_file_rmap(struct page *page)
+ {
+ 	BUG_ON(PageAnon(page));
+-	if (!pfn_valid(page_to_pfn(page)) || PageReserved(page))
+-		return;
++	BUG_ON(!pfn_valid(page_to_pfn(page)));
+ 
+ 	if (atomic_inc_and_test(&page->_mapcount))
+ 		inc_page_state(nr_mapped);
+@@ -477,12 +483,10 @@ void page_add_file_rmap(struct page *pag
+  * page_remove_rmap - take down pte mapping from a page
+  * @page: page to remove mapping from
+  *
+- * Caller needs to hold the mm->page_table_lock.
++ * The caller needs to hold the pte lock.
+  */
+ void page_remove_rmap(struct page *page)
+ {
+-	BUG_ON(PageReserved(page));
+-
+ 	if (atomic_add_negative(-1, &page->_mapcount)) {
+ 		BUG_ON(page_mapcount(page) < 0);
+ 		/*
+@@ -510,14 +514,15 @@ static int try_to_unmap_one(struct page 
+ 	unsigned long address;
+ 	pte_t *pte;
+ 	pte_t pteval;
++	spinlock_t *ptl;
+ 	int ret = SWAP_AGAIN;
+ 
+ 	address = vma_address(page, vma);
+ 	if (address == -EFAULT)
+ 		goto out;
+ 
+-	pte = page_check_address(page, mm, address);
+-	if (IS_ERR(pte))
++	pte = page_check_address(page, mm, address, &ptl);
++	if (!pte)
+ 		goto out;
+ 
+ 	/*
+@@ -541,8 +546,11 @@ static int try_to_unmap_one(struct page 
+ 	if (pte_dirty(pteval))
+ 		set_page_dirty(page);
+ 
++	/* Update high watermark before we lower rss */
++	update_hiwater_rss(mm);
++
+ 	if (PageAnon(page)) {
+-		swp_entry_t entry = { .val = page->private };
++		swp_entry_t entry = { .val = page_private(page) };
+ 		/*
+ 		 * Store the swap location in the pte.
+ 		 * See handle_pte_fault() ...
+@@ -551,21 +559,21 @@ static int try_to_unmap_one(struct page 
+ 		swap_duplicate(entry);
+ 		if (list_empty(&mm->mmlist)) {
+ 			spin_lock(&mmlist_lock);
+-			list_add(&mm->mmlist, &init_mm.mmlist);
++			if (list_empty(&mm->mmlist))
++				list_add(&mm->mmlist, &init_mm.mmlist);
+ 			spin_unlock(&mmlist_lock);
+ 		}
+ 		set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
+ 		BUG_ON(pte_file(*pte));
+ 		dec_mm_counter(mm, anon_rss);
+-	}
++	} else
++		dec_mm_counter(mm, file_rss);
+ 
+-	dec_mm_counter(mm, rss);
+ 	page_remove_rmap(page);
+ 	page_cache_release(page);
+ 
+ out_unmap:
+-	pte_unmap(pte);
+-	spin_unlock(&mm->page_table_lock);
++	pte_unmap_unlock(pte, ptl);
+ out:
+ 	return ret;
+ }
+@@ -599,19 +607,14 @@ static void try_to_unmap_cluster(unsigne
+ 	pgd_t *pgd;
+ 	pud_t *pud;
+ 	pmd_t *pmd;
+-	pte_t *pte, *original_pte;
++	pte_t *pte;
+ 	pte_t pteval;
++	spinlock_t *ptl;
+ 	struct page *page;
+ 	unsigned long address;
+ 	unsigned long end;
+ 	unsigned long pfn;
+ 
+-	/*
+-	 * We need the page_table_lock to protect us from page faults,
+-	 * munmap, fork, etc...
+-	 */
+-	spin_lock(&mm->page_table_lock);
+-
+ 	address = (vma->vm_start + cursor) & CLUSTER_MASK;
+ 	end = address + CLUSTER_SIZE;
+ 	if (address < vma->vm_start)
+@@ -621,30 +624,33 @@ static void try_to_unmap_cluster(unsigne
+ 
+ 	pgd = pgd_offset(mm, address);
+ 	if (!pgd_present(*pgd))
+-		goto out_unlock;
++		return;
+ 
+ 	pud = pud_offset(pgd, address);
+ 	if (!pud_present(*pud))
+-		goto out_unlock;
++		return;
+ 
+ 	pmd = pmd_offset(pud, address);
+ 	if (!pmd_present(*pmd))
+-		goto out_unlock;
++		return;
++
++	pte = pte_offset_map_lock(mm, pmd, address, &ptl);
+ 
+-	for (original_pte = pte = pte_offset_map(pmd, address);
+-			address < end; pte++, address += PAGE_SIZE) {
++	/* Update high watermark before we lower rss */
++	update_hiwater_rss(mm);
+ 
++	for (; address < end; pte++, address += PAGE_SIZE) {
+ 		if (!pte_present(*pte))
+ 			continue;
+ 
+ 		pfn = pte_pfn(*pte);
+-		if (!pfn_valid(pfn))
++		if (unlikely(!pfn_valid(pfn))) {
++			print_bad_pte(vma, *pte, address);
+ 			continue;
++		}
+ 
+ 		page = pfn_to_page(pfn);
+ 		BUG_ON(PageAnon(page));
+-		if (PageReserved(page))
+-			continue;
+ 
+ 		if (ptep_clear_flush_young(vma, address, pte))
+ 			continue;
+@@ -663,13 +669,10 @@ static void try_to_unmap_cluster(unsigne
+ 
+ 		page_remove_rmap(page);
+ 		page_cache_release(page);
+-		dec_mm_counter(mm, rss);
++		dec_mm_counter(mm, file_rss);
+ 		(*mapcount)--;
+ 	}
+-
+-	pte_unmap(original_pte);
+-out_unlock:
+-	spin_unlock(&mm->page_table_lock);
++	pte_unmap_unlock(pte - 1, ptl);
+ }
+ 
+ static int try_to_unmap_anon(struct page *page)
+@@ -806,7 +809,6 @@ int try_to_unmap(struct page *page)
+ {
+ 	int ret;
+ 
+-	BUG_ON(PageReserved(page));
+ 	BUG_ON(!PageLocked(page));
+ 
+ 	if (PageAnon(page))
+diff --git a/mm/shmem.c b/mm/shmem.c
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -71,9 +71,6 @@
+ /* Pretend that each entry is of this size in directory's i_size */
+ #define BOGO_DIRENT_SIZE 20
+ 
+-/* Keep swapped page count in private field of indirect struct page */
+-#define nr_swapped		private
+-
+ /* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */
+ enum sgp_type {
+ 	SGP_QUICK,	/* don't try more than file page cache lookup */
+@@ -85,7 +82,7 @@ enum sgp_type {
+ static int shmem_getpage(struct inode *inode, unsigned long idx,
+ 			 struct page **pagep, enum sgp_type sgp, int *type);
+ 
+-static inline struct page *shmem_dir_alloc(unsigned int gfp_mask)
++static inline struct page *shmem_dir_alloc(gfp_t gfp_mask)
+ {
+ 	/*
+ 	 * The above definition of ENTRIES_PER_PAGE, and the use of
+@@ -324,8 +321,10 @@ static void shmem_swp_set(struct shmem_i
+ 
+ 	entry->val = value;
+ 	info->swapped += incdec;
+-	if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT)
+-		kmap_atomic_to_page(entry)->nr_swapped += incdec;
++	if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT) {
++		struct page *page = kmap_atomic_to_page(entry);
++		set_page_private(page, page_private(page) + incdec);
++	}
+ }
+ 
+ /*
+@@ -368,9 +367,8 @@ static swp_entry_t *shmem_swp_alloc(stru
+ 
+ 		spin_unlock(&info->lock);
+ 		page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping) | __GFP_ZERO);
+-		if (page) {
+-			page->nr_swapped = 0;
+-		}
++		if (page)
++			set_page_private(page, 0);
+ 		spin_lock(&info->lock);
+ 
+ 		if (!page) {
+@@ -561,7 +559,7 @@ static void shmem_truncate(struct inode 
+ 			diroff = 0;
+ 		}
+ 		subdir = dir[diroff];
+-		if (subdir && subdir->nr_swapped) {
++		if (subdir && page_private(subdir)) {
+ 			size = limit - idx;
+ 			if (size > ENTRIES_PER_PAGE)
+ 				size = ENTRIES_PER_PAGE;
+@@ -572,10 +570,10 @@ static void shmem_truncate(struct inode 
+ 			nr_swaps_freed += freed;
+ 			if (offset)
+ 				spin_lock(&info->lock);
+-			subdir->nr_swapped -= freed;
++			set_page_private(subdir, page_private(subdir) - freed);
+ 			if (offset)
+ 				spin_unlock(&info->lock);
+-			BUG_ON(subdir->nr_swapped > offset);
++			BUG_ON(page_private(subdir) > offset);
+ 		}
+ 		if (offset)
+ 			offset = 0;
+@@ -743,7 +741,7 @@ static int shmem_unuse_inode(struct shme
+ 			dir = shmem_dir_map(subdir);
+ 		}
+ 		subdir = *dir;
+-		if (subdir && subdir->nr_swapped) {
++		if (subdir && page_private(subdir)) {
+ 			ptr = shmem_swp_map(subdir);
+ 			size = limit - idx;
+ 			if (size > ENTRIES_PER_PAGE)
+@@ -898,7 +896,7 @@ struct page *shmem_swapin(struct shmem_i
+ }
+ 
+ static struct page *
+-shmem_alloc_page(unsigned long gfp, struct shmem_inode_info *info,
++shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info,
+ 		 unsigned long idx)
+ {
+ 	struct vm_area_struct pvma;
+@@ -1201,7 +1199,7 @@ static int shmem_populate(struct vm_area
+ 				page_cache_release(page);
+ 				return err;
+ 			}
+-		} else {
++		} else if (vma->vm_flags & VM_NONLINEAR) {
+ 			/* No page was found just because we can't read it in
+ 			 * now (being here implies nonblock != 0), but the page
+ 			 * may exist, so set the PTE to fault it in later. */
+@@ -1506,8 +1504,10 @@ static void do_shmem_file_read(struct fi
+ 			 */
+ 			if (!offset)
+ 				mark_page_accessed(page);
+-		} else
++		} else {
+ 			page = ZERO_PAGE(0);
++			page_cache_get(page);
++		}
+ 
+ 		/*
+ 		 * Ok, we have the page, and it's up-to-date, so
+diff --git a/mm/slab.c b/mm/slab.c
+--- a/mm/slab.c
++++ b/mm/slab.c
+@@ -386,7 +386,7 @@ struct kmem_cache_s {
+ 	unsigned int		gfporder;
+ 
+ 	/* force GFP flags, e.g. GFP_DMA */
+-	unsigned int		gfpflags;
++	gfp_t			gfpflags;
+ 
+ 	size_t			colour;		/* cache colouring range */
+ 	unsigned int		colour_off;	/* colour offset */
+@@ -2117,7 +2117,7 @@ static void cache_init_objs(kmem_cache_t
+ 	slabp->free = 0;
+ }
+ 
+-static void kmem_flagcheck(kmem_cache_t *cachep, unsigned int flags)
++static void kmem_flagcheck(kmem_cache_t *cachep, gfp_t flags)
+ {
+ 	if (flags & SLAB_DMA) {
+ 		if (!(cachep->gfpflags & GFP_DMA))
+@@ -2152,7 +2152,7 @@ static int cache_grow(kmem_cache_t *cach
+ 	struct slab	*slabp;
+ 	void		*objp;
+ 	size_t		 offset;
+-	unsigned int	 local_flags;
++	gfp_t	 	 local_flags;
+ 	unsigned long	 ctor_flags;
+ 	struct kmem_list3 *l3;
+ 
+@@ -2419,6 +2419,7 @@ retry:
+ 			next = slab_bufctl(slabp)[slabp->free];
+ #if DEBUG
+ 			slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
++			WARN_ON(numa_node_id() != slabp->nodeid);
+ #endif
+ 		       	slabp->free = next;
+ 		}
+@@ -2546,7 +2547,7 @@ static inline void *__cache_alloc(kmem_c
+ /*
+  * A interface to enable slab creation on nodeid
+  */
+-static void *__cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid)
++static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
+ {
+ 	struct list_head *entry;
+  	struct slab *slabp;
+@@ -2633,8 +2634,10 @@ static void free_block(kmem_cache_t *cac
+ 		check_spinlock_acquired_node(cachep, node);
+ 		check_slabp(cachep, slabp);
+ 
+-
+ #if DEBUG
++		/* Verify that the slab belongs to the intended node */
++		WARN_ON(slabp->nodeid != node);
++
+ 		if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
+ 			printk(KERN_ERR "slab: double free detected in cache "
+ 					"'%s', objp %p\n", cachep->name, objp);
+diff --git a/mm/sparse.c b/mm/sparse.c
+--- a/mm/sparse.c
++++ b/mm/sparse.c
+@@ -5,8 +5,10 @@
+ #include <linux/mm.h>
+ #include <linux/mmzone.h>
+ #include <linux/bootmem.h>
++#include <linux/highmem.h>
+ #include <linux/module.h>
+ #include <linux/spinlock.h>
++#include <linux/vmalloc.h>
+ #include <asm/dma.h>
+ 
+ /*
+@@ -72,6 +74,31 @@ static inline int sparse_index_init(unsi
+ }
+ #endif
+ 
++/*
++ * Although written for the SPARSEMEM_EXTREME case, this happens
++ * to also work for the flat array case becase
++ * NR_SECTION_ROOTS==NR_MEM_SECTIONS.
++ */
++int __section_nr(struct mem_section* ms)
++{
++	unsigned long root_nr;
++	struct mem_section* root;
++
++	for (root_nr = 0;
++	     root_nr < NR_MEM_SECTIONS;
++	     root_nr += SECTIONS_PER_ROOT) {
++		root = __nr_to_section(root_nr);
++
++		if (!root)
++			continue;
++
++		if ((ms >= root) && (ms < (root + SECTIONS_PER_ROOT)))
++		     break;
++	}
++
++	return (root_nr * SECTIONS_PER_ROOT) + (ms - root);
++}
++
+ /* Record a memory area against a node. */
+ void memory_present(int nid, unsigned long start, unsigned long end)
+ {
+@@ -162,6 +189,45 @@ static struct page *sparse_early_mem_map
+ 	return NULL;
+ }
+ 
++static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
++{
++	struct page *page, *ret;
++	unsigned long memmap_size = sizeof(struct page) * nr_pages;
++
++	page = alloc_pages(GFP_KERNEL, get_order(memmap_size));
++	if (page)
++		goto got_map_page;
++
++	ret = vmalloc(memmap_size);
++	if (ret)
++		goto got_map_ptr;
++
++	return NULL;
++got_map_page:
++	ret = (struct page *)pfn_to_kaddr(page_to_pfn(page));
++got_map_ptr:
++	memset(ret, 0, memmap_size);
++
++	return ret;
++}
++
++static int vaddr_in_vmalloc_area(void *addr)
++{
++	if (addr >= (void *)VMALLOC_START &&
++	    addr < (void *)VMALLOC_END)
++		return 1;
++	return 0;
++}
++
++static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
++{
++	if (vaddr_in_vmalloc_area(memmap))
++		vfree(memmap);
++	else
++		free_pages((unsigned long)memmap,
++			   get_order(sizeof(struct page) * nr_pages));
++}
++
+ /*
+  * Allocate the accumulated non-linear sections, allocate a mem_map
+  * for each and record the physical to section mapping.
+@@ -187,14 +253,37 @@ void sparse_init(void)
+  * set.  If this is <=0, then that means that the passed-in
+  * map was not consumed and must be freed.
+  */
+-int sparse_add_one_section(unsigned long start_pfn, int nr_pages, struct page *map)
++int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
++			   int nr_pages)
+ {
+-	struct mem_section *ms = __pfn_to_section(start_pfn);
++	unsigned long section_nr = pfn_to_section_nr(start_pfn);
++	struct pglist_data *pgdat = zone->zone_pgdat;
++	struct mem_section *ms;
++	struct page *memmap;
++	unsigned long flags;
++	int ret;
+ 
+-	if (ms->section_mem_map & SECTION_MARKED_PRESENT)
+-		return -EEXIST;
++	/*
++	 * no locking for this, because it does its own
++	 * plus, it does a kmalloc
++	 */
++	sparse_index_init(section_nr, pgdat->node_id);
++	memmap = __kmalloc_section_memmap(nr_pages);
++
++	pgdat_resize_lock(pgdat, &flags);
+ 
++	ms = __pfn_to_section(start_pfn);
++	if (ms->section_mem_map & SECTION_MARKED_PRESENT) {
++		ret = -EEXIST;
++		goto out;
++	}
+ 	ms->section_mem_map |= SECTION_MARKED_PRESENT;
+ 
+-	return sparse_init_one_section(ms, pfn_to_section_nr(start_pfn), map);
++	ret = sparse_init_one_section(ms, section_nr, memmap);
++
++	if (ret <= 0)
++		__kfree_section_memmap(memmap, nr_pages);
++out:
++	pgdat_resize_unlock(pgdat, &flags);
++	return ret;
+ }
+diff --git a/mm/swap.c b/mm/swap.c
+--- a/mm/swap.c
++++ b/mm/swap.c
+@@ -39,7 +39,7 @@ int page_cluster;
+ void put_page(struct page *page)
+ {
+ 	if (unlikely(PageCompound(page))) {
+-		page = (struct page *)page->private;
++		page = (struct page *)page_private(page);
+ 		if (put_page_testzero(page)) {
+ 			void (*dtor)(struct page *page);
+ 
+@@ -48,7 +48,7 @@ void put_page(struct page *page)
+ 		}
+ 		return;
+ 	}
+-	if (!PageReserved(page) && put_page_testzero(page))
++	if (put_page_testzero(page))
+ 		__page_cache_release(page);
+ }
+ EXPORT_SYMBOL(put_page);
+@@ -215,7 +215,7 @@ void release_pages(struct page **pages, 
+ 		struct page *page = pages[i];
+ 		struct zone *pagezone;
+ 
+-		if (PageReserved(page) || !put_page_testzero(page))
++		if (!put_page_testzero(page))
+ 			continue;
+ 
+ 		pagezone = page_zone(page);
+@@ -259,6 +259,8 @@ void __pagevec_release(struct pagevec *p
+ 	pagevec_reinit(pvec);
+ }
+ 
++EXPORT_SYMBOL(__pagevec_release);
++
+ /*
+  * pagevec_release() for pages which are known to not be on the LRU
+  *
+@@ -270,7 +272,6 @@ void __pagevec_release_nonlru(struct pag
+ 	struct pagevec pages_to_free;
+ 
+ 	pagevec_init(&pages_to_free, pvec->cold);
+-	pages_to_free.cold = pvec->cold;
+ 	for (i = 0; i < pagevec_count(pvec); i++) {
+ 		struct page *page = pvec->pages[i];
+ 
+@@ -388,6 +389,7 @@ unsigned pagevec_lookup_tag(struct pagev
+ 	return pagevec_count(pvec);
+ }
+ 
++EXPORT_SYMBOL(pagevec_lookup_tag);
+ 
+ #ifdef CONFIG_SMP
+ /*
+diff --git a/mm/swap_state.c b/mm/swap_state.c
+--- a/mm/swap_state.c
++++ b/mm/swap_state.c
+@@ -83,7 +83,7 @@ static int __add_to_swap_cache(struct pa
+ 			page_cache_get(page);
+ 			SetPageLocked(page);
+ 			SetPageSwapCache(page);
+-			page->private = entry.val;
++			set_page_private(page, entry.val);
+ 			total_swapcache_pages++;
+ 			pagecache_acct(1);
+ 		}
+@@ -126,8 +126,8 @@ void __delete_from_swap_cache(struct pag
+ 	BUG_ON(PageWriteback(page));
+ 	BUG_ON(PagePrivate(page));
+ 
+-	radix_tree_delete(&swapper_space.page_tree, page->private);
+-	page->private = 0;
++	radix_tree_delete(&swapper_space.page_tree, page_private(page));
++	set_page_private(page, 0);
+ 	ClearPageSwapCache(page);
+ 	total_swapcache_pages--;
+ 	pagecache_acct(-1);
+@@ -197,7 +197,7 @@ void delete_from_swap_cache(struct page 
+ {
+ 	swp_entry_t entry;
+ 
+-	entry.val = page->private;
++	entry.val = page_private(page);
+ 
+ 	write_lock_irq(&swapper_space.tree_lock);
+ 	__delete_from_swap_cache(page);
+@@ -259,8 +259,7 @@ static inline void free_swap_cache(struc
+ 
+ /* 
+  * Perform a free_page(), also freeing any swap cache associated with
+- * this page if it is the last user of the page. Can not do a lock_page,
+- * as we are holding the page_table_lock spinlock.
++ * this page if it is the last user of the page.
+  */
+ void free_page_and_swap_cache(struct page *page)
+ {
+diff --git a/mm/swapfile.c b/mm/swapfile.c
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -61,7 +61,7 @@ void swap_unplug_io_fn(struct backing_de
+ 	swp_entry_t entry;
+ 
+ 	down_read(&swap_unplug_sem);
+-	entry.val = page->private;
++	entry.val = page_private(page);
+ 	if (PageSwapCache(page)) {
+ 		struct block_device *bdev = swap_info[swp_type(entry)].bdev;
+ 		struct backing_dev_info *bdi;
+@@ -69,8 +69,8 @@ void swap_unplug_io_fn(struct backing_de
+ 		/*
+ 		 * If the page is removed from swapcache from under us (with a
+ 		 * racy try_to_unuse/swapoff) we need an additional reference
+-		 * count to avoid reading garbage from page->private above. If
+-		 * the WARN_ON triggers during a swapoff it maybe the race
++		 * count to avoid reading garbage from page_private(page) above.
++		 * If the WARN_ON triggers during a swapoff it maybe the race
+ 		 * condition and it's harmless. However if it triggers without
+ 		 * swapoff it signals a problem.
+ 		 */
+@@ -294,7 +294,7 @@ static inline int page_swapcount(struct 
+ 	struct swap_info_struct *p;
+ 	swp_entry_t entry;
+ 
+-	entry.val = page->private;
++	entry.val = page_private(page);
+ 	p = swap_info_get(entry);
+ 	if (p) {
+ 		/* Subtract the 1 for the swap cache itself */
+@@ -339,7 +339,7 @@ int remove_exclusive_swap_page(struct pa
+ 	if (page_count(page) != 2) /* 2: us + cache */
+ 		return 0;
+ 
+-	entry.val = page->private;
++	entry.val = page_private(page);
+ 	p = swap_info_get(entry);
+ 	if (!p)
+ 		return 0;
+@@ -398,17 +398,14 @@ void free_swap_and_cache(swp_entry_t ent
+ }
+ 
+ /*
+- * Always set the resulting pte to be nowrite (the same as COW pages
+- * after one process has exited).  We don't know just how many PTEs will
+- * share this swap entry, so be cautious and let do_wp_page work out
+- * what to do if a write is requested later.
+- *
+- * vma->vm_mm->page_table_lock is held.
++ * No need to decide whether this PTE shares the swap entry with others,
++ * just let do_wp_page work it out if a write is requested later - to
++ * force COW, vm_page_prot omits write permission from any private vma.
+  */
+ static void unuse_pte(struct vm_area_struct *vma, pte_t *pte,
+ 		unsigned long addr, swp_entry_t entry, struct page *page)
+ {
+-	inc_mm_counter(vma->vm_mm, rss);
++	inc_mm_counter(vma->vm_mm, anon_rss);
+ 	get_page(page);
+ 	set_pte_at(vma->vm_mm, addr, pte,
+ 		   pte_mkold(mk_pte(page, vma->vm_page_prot)));
+@@ -425,23 +422,25 @@ static int unuse_pte_range(struct vm_are
+ 				unsigned long addr, unsigned long end,
+ 				swp_entry_t entry, struct page *page)
+ {
+-	pte_t *pte;
+ 	pte_t swp_pte = swp_entry_to_pte(entry);
++	pte_t *pte;
++	spinlock_t *ptl;
++	int found = 0;
+ 
+-	pte = pte_offset_map(pmd, addr);
++	pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+ 	do {
+ 		/*
+ 		 * swapoff spends a _lot_ of time in this loop!
+ 		 * Test inline before going to call unuse_pte.
+ 		 */
+ 		if (unlikely(pte_same(*pte, swp_pte))) {
+-			unuse_pte(vma, pte, addr, entry, page);
+-			pte_unmap(pte);
+-			return 1;
++			unuse_pte(vma, pte++, addr, entry, page);
++			found = 1;
++			break;
+ 		}
+ 	} while (pte++, addr += PAGE_SIZE, addr != end);
+-	pte_unmap(pte - 1);
+-	return 0;
++	pte_unmap_unlock(pte - 1, ptl);
++	return found;
+ }
+ 
+ static inline int unuse_pmd_range(struct vm_area_struct *vma, pud_t *pud,
+@@ -523,12 +522,10 @@ static int unuse_mm(struct mm_struct *mm
+ 		down_read(&mm->mmap_sem);
+ 		lock_page(page);
+ 	}
+-	spin_lock(&mm->page_table_lock);
+ 	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+ 		if (vma->anon_vma && unuse_vma(vma, entry, page))
+ 			break;
+ 	}
+-	spin_unlock(&mm->page_table_lock);
+ 	up_read(&mm->mmap_sem);
+ 	/*
+ 	 * Currently unuse_mm cannot fail, but leave error handling
+@@ -1045,7 +1042,7 @@ int page_queue_congested(struct page *pa
+ 	BUG_ON(!PageLocked(page));	/* It pins the swap_info_struct */
+ 
+ 	if (PageSwapCache(page)) {
+-		swp_entry_t entry = { .val = page->private };
++		swp_entry_t entry = { .val = page_private(page) };
+ 		struct swap_info_struct *sis;
+ 
+ 		sis = get_swap_info_struct(swp_type(entry));
+diff --git a/mm/thrash.c b/mm/thrash.c
+--- a/mm/thrash.c
++++ b/mm/thrash.c
+@@ -19,7 +19,7 @@ static unsigned long swap_token_check;
+ struct mm_struct * swap_token_mm = &init_mm;
+ 
+ #define SWAP_TOKEN_CHECK_INTERVAL (HZ * 2)
+-#define SWAP_TOKEN_TIMEOUT	0
++#define SWAP_TOKEN_TIMEOUT	(300 * HZ)
+ /*
+  * Currently disabled; Needs further code to work at HZ * 300.
+  */
+diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c
+--- a/mm/tiny-shmem.c
++++ b/mm/tiny-shmem.c
+@@ -31,11 +31,14 @@ static struct vfsmount *shm_mnt;
+ 
+ static int __init init_tmpfs(void)
+ {
+-	register_filesystem(&tmpfs_fs_type);
++	BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
++
+ #ifdef CONFIG_TMPFS
+ 	devfs_mk_dir("shm");
+ #endif
+ 	shm_mnt = kern_mount(&tmpfs_fs_type);
++	BUG_ON(IS_ERR(shm_mnt));
++
+ 	return 0;
+ }
+ module_init(init_tmpfs)
+diff --git a/mm/truncate.c b/mm/truncate.c
+--- a/mm/truncate.c
++++ b/mm/truncate.c
+@@ -13,18 +13,9 @@
+ #include <linux/pagemap.h>
+ #include <linux/pagevec.h>
+ #include <linux/buffer_head.h>	/* grr. try_to_release_page,
+-				   block_invalidatepage */
++				   do_invalidatepage */
+ 
+ 
+-static int do_invalidatepage(struct page *page, unsigned long offset)
+-{
+-	int (*invalidatepage)(struct page *, unsigned long);
+-	invalidatepage = page->mapping->a_ops->invalidatepage;
+-	if (invalidatepage == NULL)
+-		invalidatepage = block_invalidatepage;
+-	return (*invalidatepage)(page, offset);
+-}
+-
+ static inline void truncate_partial_page(struct page *page, unsigned partial)
+ {
+ 	memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
+diff --git a/mm/vmalloc.c b/mm/vmalloc.c
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -5,6 +5,7 @@
+  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+  *  SMP-safe vmalloc/vfree/ioremap, Tigran Aivazian <tigran at veritas.com>, May 2000
+  *  Major rework to support vmap/vunmap, Christoph Hellwig, SGI, August 2002
++ *  Numa awareness, Christoph Lameter, SGI, June 2005
+  */
+ 
+ #include <linux/mm.h>
+@@ -88,7 +89,7 @@ static int vmap_pte_range(pmd_t *pmd, un
+ {
+ 	pte_t *pte;
+ 
+-	pte = pte_alloc_kernel(&init_mm, pmd, addr);
++	pte = pte_alloc_kernel(pmd, addr);
+ 	if (!pte)
+ 		return -ENOMEM;
+ 	do {
+@@ -146,20 +147,18 @@ int map_vm_area(struct vm_struct *area, 
+ 
+ 	BUG_ON(addr >= end);
+ 	pgd = pgd_offset_k(addr);
+-	spin_lock(&init_mm.page_table_lock);
+ 	do {
+ 		next = pgd_addr_end(addr, end);
+ 		err = vmap_pud_range(pgd, addr, next, prot, pages);
+ 		if (err)
+ 			break;
+ 	} while (pgd++, addr = next, addr != end);
+-	spin_unlock(&init_mm.page_table_lock);
+ 	flush_cache_vmap((unsigned long) area->addr, end);
+ 	return err;
+ }
+ 
+-struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
+-				unsigned long start, unsigned long end)
++struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
++				unsigned long start, unsigned long end, int node)
+ {
+ 	struct vm_struct **p, *tmp, *area;
+ 	unsigned long align = 1;
+@@ -178,7 +177,7 @@ struct vm_struct *__get_vm_area(unsigned
+ 	addr = ALIGN(start, align);
+ 	size = PAGE_ALIGN(size);
+ 
+-	area = kmalloc(sizeof(*area), GFP_KERNEL);
++	area = kmalloc_node(sizeof(*area), GFP_KERNEL, node);
+ 	if (unlikely(!area))
+ 		return NULL;
+ 
+@@ -231,6 +230,12 @@ out:
+ 	return NULL;
+ }
+ 
++struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
++				unsigned long start, unsigned long end)
++{
++	return __get_vm_area_node(size, flags, start, end, -1);
++}
++
+ /**
+  *	get_vm_area  -  reserve a contingous kernel virtual area
+  *
+@@ -246,6 +251,11 @@ struct vm_struct *get_vm_area(unsigned l
+ 	return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END);
+ }
+ 
++struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node)
++{
++	return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node);
++}
++
+ /* Caller must hold vmlist_lock */
+ struct vm_struct *__remove_vm_area(void *addr)
+ {
+@@ -342,7 +352,6 @@ void vfree(void *addr)
+ 	BUG_ON(in_interrupt());
+ 	__vunmap(addr, 1);
+ }
+-
+ EXPORT_SYMBOL(vfree);
+ 
+ /**
+@@ -360,7 +369,6 @@ void vunmap(void *addr)
+ 	BUG_ON(in_interrupt());
+ 	__vunmap(addr, 0);
+ }
+-
+ EXPORT_SYMBOL(vunmap);
+ 
+ /**
+@@ -392,10 +400,10 @@ void *vmap(struct page **pages, unsigned
+ 
+ 	return area->addr;
+ }
+-
+ EXPORT_SYMBOL(vmap);
+ 
+-void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
++void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
++				pgprot_t prot, int node)
+ {
+ 	struct page **pages;
+ 	unsigned int nr_pages, array_size, i;
+@@ -406,9 +414,9 @@ void *__vmalloc_area(struct vm_struct *a
+ 	area->nr_pages = nr_pages;
+ 	/* Please note that the recursion is strictly bounded. */
+ 	if (array_size > PAGE_SIZE)
+-		pages = __vmalloc(array_size, gfp_mask, PAGE_KERNEL);
++		pages = __vmalloc_node(array_size, gfp_mask, PAGE_KERNEL, node);
+ 	else
+-		pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));
++		pages = kmalloc_node(array_size, (gfp_mask & ~__GFP_HIGHMEM), node);
+ 	area->pages = pages;
+ 	if (!area->pages) {
+ 		remove_vm_area(area->addr);
+@@ -418,7 +426,10 @@ void *__vmalloc_area(struct vm_struct *a
+ 	memset(area->pages, 0, array_size);
+ 
+ 	for (i = 0; i < area->nr_pages; i++) {
+-		area->pages[i] = alloc_page(gfp_mask);
++		if (node < 0)
++			area->pages[i] = alloc_page(gfp_mask);
++		else
++			area->pages[i] = alloc_pages_node(node, gfp_mask, 0);
+ 		if (unlikely(!area->pages[i])) {
+ 			/* Successfully allocated i pages, free them in __vunmap() */
+ 			area->nr_pages = i;
+@@ -435,18 +446,25 @@ fail:
+ 	return NULL;
+ }
+ 
++void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
++{
++	return __vmalloc_area_node(area, gfp_mask, prot, -1);
++}
++
+ /**
+- *	__vmalloc  -  allocate virtually contiguous memory
++ *	__vmalloc_node  -  allocate virtually contiguous memory
+  *
+  *	@size:		allocation size
+  *	@gfp_mask:	flags for the page level allocator
+  *	@prot:		protection mask for the allocated pages
++ *	@node		node to use for allocation or -1
+  *
+  *	Allocate enough pages to cover @size from the page level
+  *	allocator with @gfp_mask flags.  Map them into contiguous
+  *	kernel virtual space, using a pagetable protection of @prot.
+  */
+-void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
++void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
++			int node)
+ {
+ 	struct vm_struct *area;
+ 
+@@ -454,13 +472,18 @@ void *__vmalloc(unsigned long size, gfp_
+ 	if (!size || (size >> PAGE_SHIFT) > num_physpages)
+ 		return NULL;
+ 
+-	area = get_vm_area(size, VM_ALLOC);
++	area = get_vm_area_node(size, VM_ALLOC, node);
+ 	if (!area)
+ 		return NULL;
+ 
+-	return __vmalloc_area(area, gfp_mask, prot);
++	return __vmalloc_area_node(area, gfp_mask, prot, node);
+ }
++EXPORT_SYMBOL(__vmalloc_node);
+ 
++void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
++{
++	return __vmalloc_node(size, gfp_mask, prot, -1);
++}
+ EXPORT_SYMBOL(__vmalloc);
+ 
+ /**
+@@ -478,9 +501,26 @@ void *vmalloc(unsigned long size)
+ {
+        return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
+ }
+-
+ EXPORT_SYMBOL(vmalloc);
+ 
++/**
++ *	vmalloc_node  -  allocate memory on a specific node
++ *
++ *	@size:		allocation size
++ *	@node;		numa node
++ *
++ *	Allocate enough pages to cover @size from the page level
++ *	allocator and map them into contiguous kernel virtual space.
++ *
++ *	For tight cotrol over page level allocator and protection flags
++ *	use __vmalloc() instead.
++ */
++void *vmalloc_node(unsigned long size, int node)
++{
++       return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, node);
++}
++EXPORT_SYMBOL(vmalloc_node);
++
+ #ifndef PAGE_KERNEL_EXEC
+ # define PAGE_KERNEL_EXEC PAGE_KERNEL
+ #endif
+@@ -515,7 +555,6 @@ void *vmalloc_32(unsigned long size)
+ {
+ 	return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
+ }
+-
+ EXPORT_SYMBOL(vmalloc_32);
+ 
+ long vread(char *buf, char *addr, unsigned long count)
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -70,7 +70,7 @@ struct scan_control {
+ 	unsigned int priority;
+ 
+ 	/* This context's GFP mask */
+-	unsigned int gfp_mask;
++	gfp_t gfp_mask;
+ 
+ 	int may_writepage;
+ 
+@@ -186,7 +186,7 @@ EXPORT_SYMBOL(remove_shrinker);
+  *
+  * Returns the number of slab objects which we shrunk.
+  */
+-static int shrink_slab(unsigned long scanned, unsigned int gfp_mask,
++static int shrink_slab(unsigned long scanned, gfp_t gfp_mask,
+ 			unsigned long lru_pages)
+ {
+ 	struct shrinker *shrinker;
+@@ -417,7 +417,9 @@ static int shrink_list(struct list_head 
+ 		 * Anonymous process memory has backing store?
+ 		 * Try to allocate it some swap space here.
+ 		 */
+-		if (PageAnon(page) && !PageSwapCache(page) && sc->may_swap) {
++		if (PageAnon(page) && !PageSwapCache(page)) {
++			if (!sc->may_swap)
++				goto keep_locked;
+ 			if (!add_to_swap(page))
+ 				goto activate_locked;
+ 		}
+@@ -519,7 +521,7 @@ static int shrink_list(struct list_head 
+ 
+ #ifdef CONFIG_SWAP
+ 		if (PageSwapCache(page)) {
+-			swp_entry_t swap = { .val = page->private };
++			swp_entry_t swap = { .val = page_private(page) };
+ 			__delete_from_swap_cache(page);
+ 			write_unlock_irq(&mapping->tree_lock);
+ 			swap_free(swap);
+@@ -926,7 +928,7 @@ shrink_caches(struct zone **zones, struc
+  * holds filesystem locks which prevent writeout this might not work, and the
+  * allocation attempt will fail.
+  */
+-int try_to_free_pages(struct zone **zones, unsigned int gfp_mask)
++int try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
+ {
+ 	int priority;
+ 	int ret = 0;
+@@ -1338,7 +1340,7 @@ module_init(kswapd_init)
+ /*
+  * Try to free up some pages from this zone through reclaim.
+  */
+-int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order)
++int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
+ {
+ 	struct scan_control sc;
+ 	int nr_pages = 1 << order;
+diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -308,12 +308,6 @@ static struct net_proto_family bt_sock_f
+ 	.create	= bt_sock_create,
+ };
+ 
+-extern int hci_sock_init(void);
+-extern int hci_sock_cleanup(void);
+-
+-extern int bt_sysfs_init(void);
+-extern int bt_sysfs_cleanup(void);
+-
+ static int __init bt_init(void)
+ {
+ 	BT_INFO("Core ver %s", VERSION);
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -87,7 +87,7 @@ int hci_unregister_notifier(struct notif
+ 	return notifier_chain_unregister(&hci_notifier, nb);
+ }
+ 
+-void hci_notify(struct hci_dev *hdev, int event)
++static void hci_notify(struct hci_dev *hdev, int event)
+ {
+ 	notifier_call_chain(&hci_notifier, event, hdev);
+ }
+@@ -1347,7 +1347,7 @@ static inline void hci_scodata_packet(st
+ 	kfree_skb(skb);
+ }
+ 
+-void hci_rx_task(unsigned long arg)
++static void hci_rx_task(unsigned long arg)
+ {
+ 	struct hci_dev *hdev = (struct hci_dev *) arg;
+ 	struct sk_buff *skb;
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -66,20 +66,20 @@ static struct hci_sec_filter hci_sec_fil
+ 	/* Packet types */
+ 	0x10,
+ 	/* Events */
+-	{ 0x1000d9fe, 0x0000300c },
++	{ 0x1000d9fe, 0x0000b00c },
+ 	/* Commands */
+ 	{
+ 		{ 0x0 },
+ 		/* OGF_LINK_CTL */
+-		{ 0xbe000006, 0x00000001, 0x0000, 0x00 },
++		{ 0xbe000006, 0x00000001, 0x000000, 0x00 },
+ 		/* OGF_LINK_POLICY */
+-		{ 0x00005200, 0x00000000, 0x0000, 0x00 },
++		{ 0x00005200, 0x00000000, 0x000000, 0x00 },
+ 		/* OGF_HOST_CTL */
+-		{ 0xaab00200, 0x2b402aaa, 0x0154, 0x00 },
++		{ 0xaab00200, 0x2b402aaa, 0x020154, 0x00 },
+ 		/* OGF_INFO_PARAM */
+-		{ 0x000002be, 0x00000000, 0x0000, 0x00 },
++		{ 0x000002be, 0x00000000, 0x000000, 0x00 },
+ 		/* OGF_STATUS_PARAM */
+-		{ 0x000000ea, 0x00000000, 0x0000, 0x00 }
++		{ 0x000000ea, 0x00000000, 0x000000, 0x00 }
+ 	}
+ };
+ 
+diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig
+--- a/net/bluetooth/hidp/Kconfig
++++ b/net/bluetooth/hidp/Kconfig
+@@ -1,6 +1,6 @@
+ config BT_HIDP
+ 	tristate "HIDP protocol support"
+-	depends on BT && BT_L2CAP
++	depends on BT && BT_L2CAP && (BROKEN || !S390)
+ 	select INPUT
+ 	help
+ 	  HIDP (Human Interface Device Protocol) is a transport layer
+diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
+--- a/net/bluetooth/hidp/core.c
++++ b/net/bluetooth/hidp/core.c
+@@ -520,7 +520,7 @@ static int hidp_session(void *arg)
+ 
+ 	if (session->input) {
+ 		input_unregister_device(session->input);
+-		kfree(session->input);
++		session->input = NULL;
+ 	}
+ 
+ 	up_write(&hidp_session_sem);
+@@ -536,6 +536,8 @@ static inline void hidp_setup_input(stru
+ 
+ 	input->private = session;
+ 
++	input->name = "Bluetooth HID Boot Protocol Device";
++
+ 	input->id.bustype = BUS_BLUETOOTH;
+ 	input->id.vendor  = req->vendor;
+ 	input->id.product = req->product;
+@@ -582,16 +584,15 @@ int hidp_add_connection(struct hidp_conn
+ 		return -ENOTUNIQ;
+ 
+ 	session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);
+-	if (!session) 
++	if (!session)
+ 		return -ENOMEM;
+ 	memset(session, 0, sizeof(struct hidp_session));
+ 
+-	session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
++	session->input = input_allocate_device();
+ 	if (!session->input) {
+ 		kfree(session);
+ 		return -ENOMEM;
+ 	}
+-	memset(session->input, 0, sizeof(struct input_dev));
+ 
+ 	down_write(&hidp_session_sem);
+ 
+@@ -651,8 +652,10 @@ unlink:
+ 
+ 	__hidp_unlink_session(session);
+ 
+-	if (session->input)
++	if (session->input) {
+ 		input_unregister_device(session->input);
++		session->input = NULL; /* don't try to free it here */
++	}
+ 
+ failed:
+ 	up_write(&hidp_session_sem);
+diff --git a/net/bluetooth/rfcomm/Makefile b/net/bluetooth/rfcomm/Makefile
+--- a/net/bluetooth/rfcomm/Makefile
++++ b/net/bluetooth/rfcomm/Makefile
+@@ -4,5 +4,5 @@
+ 
+ obj-$(CONFIG_BT_RFCOMM) += rfcomm.o
+ 
+-rfcomm-y			:= core.o sock.o crc.o
++rfcomm-y			:= core.o sock.o
+ rfcomm-$(CONFIG_BT_RFCOMM_TTY)	+= tty.o
+diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
+--- a/net/bluetooth/rfcomm/core.c
++++ b/net/bluetooth/rfcomm/core.c
+@@ -133,6 +133,49 @@ static inline void rfcomm_session_put(st
+ 
+ /* ---- RFCOMM FCS computation ---- */
+ 
++/* reversed, 8-bit, poly=0x07 */
++static unsigned char rfcomm_crc_table[256] = { 
++	0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
++	0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
++	0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
++	0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
++
++	0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
++	0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
++	0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
++	0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
++
++	0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
++	0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
++	0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
++	0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
++
++	0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
++	0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
++	0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
++	0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
++
++	0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
++	0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
++	0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
++	0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
++
++	0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
++	0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
++	0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
++	0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
++
++	0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
++	0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
++	0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
++	0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
++
++	0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
++	0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
++	0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
++	0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
++};
++
+ /* CRC on 2 bytes */
+ #define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
+ 
+diff --git a/net/bluetooth/rfcomm/crc.c b/net/bluetooth/rfcomm/crc.c
+deleted file mode 100644
+--- a/net/bluetooth/rfcomm/crc.c
++++ /dev/null
+@@ -1,71 +0,0 @@
+-/* 
+-   RFCOMM implementation for Linux Bluetooth stack (BlueZ).
+-   Copyright (C) 2002 Maxim Krasnyansky <maxk at qualcomm.com>
+-   Copyright (C) 2002 Marcel Holtmann <marcel at holtmann.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;
+-
+-   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 OF THIRD PARTY RIGHTS.
+-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+-   SOFTWARE IS DISCLAIMED.
+-*/
+-
+-/*
+- * RFCOMM FCS calculation.
+- *
+- * $Id: crc.c,v 1.2 2002/09/21 09:54:32 holtmann Exp $
+- */
+-
+-/* reversed, 8-bit, poly=0x07 */
+-unsigned char rfcomm_crc_table[256] = { 
+-	0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
+-	0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
+-	0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
+-	0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
+-
+-	0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
+-	0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
+-	0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
+-	0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
+-
+-	0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
+-	0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
+-	0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
+-	0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
+-
+-	0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
+-	0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
+-	0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
+-	0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
+-
+-	0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
+-	0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
+-	0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
+-	0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
+-
+-	0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
+-	0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
+-	0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
+-	0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
+-
+-	0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
+-	0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
+-	0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
+-	0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
+-
+-	0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
+-	0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
+-	0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
+-	0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
+-};
+diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
+--- a/net/bridge/br_fdb.c
++++ b/net/bridge/br_fdb.c
+@@ -86,8 +86,8 @@ void br_fdb_changeaddr(struct net_bridge
+ 				struct net_bridge_port *op;
+ 				list_for_each_entry(op, &br->port_list, list) {
+ 					if (op != p && 
+-					    !memcmp(op->dev->dev_addr,
+-						    f->addr.addr, ETH_ALEN)) {
++					    !compare_ether_addr(op->dev->dev_addr,
++								f->addr.addr)) {
+ 						f->dst = op;
+ 						goto insert;
+ 					}
+@@ -151,8 +151,8 @@ void br_fdb_delete_by_port(struct net_br
+ 				struct net_bridge_port *op;
+ 				list_for_each_entry(op, &br->port_list, list) {
+ 					if (op != p && 
+-					    !memcmp(op->dev->dev_addr,
+-						    f->addr.addr, ETH_ALEN)) {
++					    !compare_ether_addr(op->dev->dev_addr,
++								f->addr.addr)) {
+ 						f->dst = op;
+ 						goto skip_delete;
+ 					}
+@@ -174,7 +174,7 @@ struct net_bridge_fdb_entry *__br_fdb_ge
+ 	struct net_bridge_fdb_entry *fdb;
+ 
+ 	hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) {
+-		if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) {
++		if (!compare_ether_addr(fdb->addr.addr, addr)) {
+ 			if (unlikely(has_expired(br, fdb)))
+ 				break;
+ 			return fdb;
+@@ -264,7 +264,7 @@ static inline struct net_bridge_fdb_entr
+ 	struct net_bridge_fdb_entry *fdb;
+ 
+ 	hlist_for_each_entry_rcu(fdb, h, head, hlist) {
+-		if (!memcmp(fdb->addr.addr, addr, ETH_ALEN))
++		if (!compare_ether_addr(fdb->addr.addr, addr))
+ 			return fdb;
+ 	}
+ 	return NULL;
+diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
+--- a/net/bridge/br_input.c
++++ b/net/bridge/br_input.c
+@@ -128,7 +128,7 @@ int br_handle_frame(struct net_bridge_po
+ 			dest = eth_hdr(skb)->h_dest;
+ 		}
+ 
+-		if (!memcmp(p->br->dev->dev_addr, dest, ETH_ALEN))
++		if (!compare_ether_addr(p->br->dev->dev_addr, dest))
+ 			skb->pkt_type = PACKET_HOST;
+ 
+ 		NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
+diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
+--- a/net/bridge/br_stp_if.c
++++ b/net/bridge/br_stp_if.c
+@@ -15,6 +15,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/smp_lock.h>
++#include <linux/etherdevice.h>
+ 
+ #include "br_private.h"
+ #include "br_private_stp.h"
+@@ -133,10 +134,10 @@ static void br_stp_change_bridge_id(stru
+ 	memcpy(br->dev->dev_addr, addr, ETH_ALEN);
+ 
+ 	list_for_each_entry(p, &br->port_list, list) {
+-		if (!memcmp(p->designated_bridge.addr, oldaddr, ETH_ALEN))
++		if (!compare_ether_addr(p->designated_bridge.addr, oldaddr))
+ 			memcpy(p->designated_bridge.addr, addr, ETH_ALEN);
+ 
+-		if (!memcmp(p->designated_root.addr, oldaddr, ETH_ALEN))
++		if (!compare_ether_addr(p->designated_root.addr, oldaddr))
+ 			memcpy(p->designated_root.addr, addr, ETH_ALEN);
+ 
+ 	}
+@@ -157,12 +158,12 @@ void br_stp_recalculate_bridge_id(struct
+ 
+ 	list_for_each_entry(p, &br->port_list, list) {
+ 		if (addr == br_mac_zero ||
+-		    memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
++		    compare_ether_addr(p->dev->dev_addr, addr) < 0)
+ 			addr = p->dev->dev_addr;
+ 
+ 	}
+ 
+-	if (memcmp(br->bridge_id.addr, addr, ETH_ALEN))
++	if (compare_ether_addr(br->bridge_id.addr, addr))
+ 		br_stp_change_bridge_id(br, addr);
+ }
+ 
+diff --git a/net/core/dev.c b/net/core/dev.c
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2717,6 +2717,20 @@ int register_netdevice(struct net_device
+ 		       dev->name);
+ 		dev->features &= ~NETIF_F_TSO;
+ 	}
++	if (dev->features & NETIF_F_UFO) {
++		if (!(dev->features & NETIF_F_HW_CSUM)) {
++			printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no "
++					"NETIF_F_HW_CSUM feature.\n",
++							dev->name);
++			dev->features &= ~NETIF_F_UFO;
++		}
++		if (!(dev->features & NETIF_F_SG)) {
++			printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no "
++					"NETIF_F_SG feature.\n",
++					dev->name);
++			dev->features &= ~NETIF_F_UFO;
++		}
++	}
+ 
+ 	/*
+ 	 *	nil rebuild_header routine,
+diff --git a/net/core/ethtool.c b/net/core/ethtool.c
+--- a/net/core/ethtool.c
++++ b/net/core/ethtool.c
+@@ -93,6 +93,20 @@ int ethtool_op_get_perm_addr(struct net_
+ }
+  
+ 
++u32 ethtool_op_get_ufo(struct net_device *dev)
++{
++	return (dev->features & NETIF_F_UFO) != 0;
++}
++
++int ethtool_op_set_ufo(struct net_device *dev, u32 data)
++{
++	if (data)
++		dev->features |= NETIF_F_UFO;
++	else
++		dev->features &= ~NETIF_F_UFO;
++	return 0;
++}
++
+ /* Handlers for each ethtool command */
+ 
+ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
+@@ -483,6 +497,11 @@ static int __ethtool_set_sg(struct net_d
+ 			return err;
+ 	}
+ 
++	if (!data && dev->ethtool_ops->set_ufo) {
++		err = dev->ethtool_ops->set_ufo(dev, 0);
++		if (err)
++			return err;
++	}
+ 	return dev->ethtool_ops->set_sg(dev, data);
+ }
+ 
+@@ -569,6 +588,32 @@ static int ethtool_set_tso(struct net_de
+ 	return dev->ethtool_ops->set_tso(dev, edata.data);
+ }
+ 
++static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr)
++{
++	struct ethtool_value edata = { ETHTOOL_GTSO };
++
++	if (!dev->ethtool_ops->get_ufo)
++		return -EOPNOTSUPP;
++	edata.data = dev->ethtool_ops->get_ufo(dev);
++	if (copy_to_user(useraddr, &edata, sizeof(edata)))
++		 return -EFAULT;
++	return 0;
++}
++static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr)
++{
++	struct ethtool_value edata;
++
++	if (!dev->ethtool_ops->set_ufo)
++		return -EOPNOTSUPP;
++	if (copy_from_user(&edata, useraddr, sizeof(edata)))
++		return -EFAULT;
++	if (edata.data && !(dev->features & NETIF_F_SG))
++		return -EINVAL;
++	if (edata.data && !(dev->features & NETIF_F_HW_CSUM))
++		return -EINVAL;
++	return dev->ethtool_ops->set_ufo(dev, edata.data);
++}
++
+ static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
+ {
+ 	struct ethtool_test test;
+@@ -854,6 +899,12 @@ int dev_ethtool(struct ifreq *ifr)
+ 	case ETHTOOL_GPERMADDR:
+ 		rc = ethtool_get_perm_addr(dev, useraddr);
+ 		break;
++	case ETHTOOL_GUFO:
++		rc = ethtool_get_ufo(dev, useraddr);
++		break;
++	case ETHTOOL_SUFO:
++		rc = ethtool_set_ufo(dev, useraddr);
++		break;
+ 	default:
+ 		rc =  -EOPNOTSUPP;
+ 	}
+@@ -882,3 +933,5 @@ EXPORT_SYMBOL(ethtool_op_set_sg);
+ EXPORT_SYMBOL(ethtool_op_set_tso);
+ EXPORT_SYMBOL(ethtool_op_set_tx_csum);
+ EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum);
++EXPORT_SYMBOL(ethtool_op_set_ufo);
++EXPORT_SYMBOL(ethtool_op_get_ufo);
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -1625,12 +1625,9 @@ static int neightbl_fill_info(struct nei
+ 
+ 		memset(&ndst, 0, sizeof(ndst));
+ 
+-		for (cpu = 0; cpu < NR_CPUS; cpu++) {
++		for_each_cpu(cpu) {
+ 			struct neigh_statistics	*st;
+ 
+-			if (!cpu_possible(cpu))
+-				continue;
+-
+ 			st = per_cpu_ptr(tbl->stats, cpu);
+ 			ndst.ndts_allocs		+= st->allocs;
+ 			ndst.ndts_destroys		+= st->destroys;
+diff --git a/net/core/pktgen.c b/net/core/pktgen.c
+--- a/net/core/pktgen.c
++++ b/net/core/pktgen.c
+@@ -75,7 +75,7 @@
+  * By design there should only be *one* "controlling" process. In practice 
+  * multiple write accesses gives unpredictable result. Understood by "write" 
+  * to /proc gives result code thats should be read be the "writer".
+- * For pratical use this should be no problem.
++ * For practical use this should be no problem.
+  *
+  * Note when adding devices to a specific CPU there good idea to also assign 
+  * /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU. 
+@@ -96,7 +96,7 @@
+  * New xmit() return, do_div and misc clean up by Stephen Hemminger 
+  * <shemminger at osdl.org> 040923
+  *
+- * Rany Dunlap fixed u64 printk compiler waring 
++ * Randy Dunlap fixed u64 printk compiler waring 
+  *
+  * Remove FCS from BW calculation.  Lennert Buytenhek <buytenh at wantstofly.org>
+  * New time handling. Lennert Buytenhek <buytenh at wantstofly.org> 041213
+@@ -137,6 +137,7 @@
+ #include <linux/ipv6.h>
+ #include <linux/udp.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/wait.h>
+ #include <net/checksum.h>
+ #include <net/ipv6.h>
+@@ -151,7 +152,7 @@
+ #include <asm/timex.h>
+ 
+ 
+-#define VERSION  "pktgen v2.62: Packet Generator for packet performance testing.\n"
++#define VERSION  "pktgen v2.63: Packet Generator for packet performance testing.\n"
+ 
+ /* #define PG_DEBUG(a) a */
+ #define PG_DEBUG(a) 
+@@ -177,8 +178,8 @@
+ #define T_REMDEV      (1<<3)  /* Remove all devs */
+ 
+ /* Locks */
+-#define   thread_lock()        spin_lock(&_thread_lock)
+-#define   thread_unlock()      spin_unlock(&_thread_lock)
++#define   thread_lock()        down(&pktgen_sem)
++#define   thread_unlock()      up(&pktgen_sem)
+ 
+ /* If lock -- can be removed after some work */
+ #define   if_lock(t)           spin_lock(&(t->if_lock));
+@@ -186,7 +187,9 @@
+ 
+ /* Used to help with determining the pkts on receive */
+ #define PKTGEN_MAGIC 0xbe9be955
+-#define PG_PROC_DIR "net/pktgen"
++#define PG_PROC_DIR "pktgen"
++#define PGCTRL	    "pgctrl"
++static struct proc_dir_entry *pg_proc_dir = NULL;
+ 
+ #define MAX_CFLOWS  65536
+ 
+@@ -202,11 +205,8 @@ struct pktgen_dev {
+ 	 * Try to keep frequent/infrequent used vars. separated.
+ 	 */
+ 
+-        char ifname[32];
+-        struct proc_dir_entry *proc_ent;
++        char ifname[IFNAMSIZ];
+         char result[512];
+-        /* proc file names */
+-        char fname[80];
+ 
+         struct pktgen_thread* pg_thread; /* the owner */
+         struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */
+@@ -244,7 +244,7 @@ struct pktgen_dev {
+         __u32 seq_num;
+         
+         int clone_skb; /* Use multiple SKBs during packet gen.  If this number
+-                          * is greater than 1, then that many coppies of the same
++                          * is greater than 1, then that many copies of the same
+                           * packet will be sent before a new packet is allocated.
+                           * For instance, if you want to send 1024 identical packets
+                           * before creating a new packet, set clone_skb to 1024.
+@@ -330,8 +330,6 @@ struct pktgen_thread {
+         struct pktgen_dev *if_list;           /* All device here */
+         struct pktgen_thread* next;
+         char name[32];
+-        char fname[128]; /* name of proc file */
+-        struct proc_dir_entry *proc_ent;
+         char result[512];
+         u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
+         
+@@ -396,7 +394,7 @@ static inline s64 divremdi3(s64 x, s64 y
+ 
+ /* End of hacks to deal with 64-bit math on x86 */
+ 
+-/** Convert to miliseconds */
++/** Convert to milliseconds */
+ static inline __u64 tv_to_ms(const struct timeval* tv) 
+ {
+         __u64 ms = tv->tv_usec / 1000;
+@@ -425,7 +423,7 @@ static inline __u64 pg_div64(__u64 n, __
+ {
+         __u64 tmp = n;
+ /*
+- * How do we know if the architectrure we are running on
++ * How do we know if the architecture we are running on
+  * supports division with 64 bit base?
+  * 
+  */
+@@ -473,16 +471,6 @@ static inline __u64 tv_diff(const struct
+ 
+ static char version[] __initdata = VERSION;
+ 
+-static ssize_t proc_pgctrl_read(struct file* file, char __user * buf, size_t count, loff_t *ppos);
+-static ssize_t proc_pgctrl_write(struct file* file, const char __user * buf, size_t count, loff_t *ppos);
+-static int proc_if_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
+-
+-static int proc_thread_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
+-static int proc_if_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
+-static int proc_thread_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
+-static int create_proc_dir(void);
+-static int remove_proc_dir(void);
+-
+ static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i);
+ static int pktgen_add_device(struct pktgen_thread* t, const char* ifname);
+ static struct pktgen_thread* pktgen_find_thread(const char* name);
+@@ -503,83 +491,41 @@ static int pg_delay_d = 0;
+ static int pg_clone_skb_d = 0;
+ static int debug = 0;
+ 
+-static DEFINE_SPINLOCK(_thread_lock);
++static DECLARE_MUTEX(pktgen_sem);
+ static struct pktgen_thread *pktgen_threads = NULL;
+ 
+-static char module_fname[128];
+-static struct proc_dir_entry *module_proc_ent = NULL;
+-
+ static struct notifier_block pktgen_notifier_block = {
+ 	.notifier_call = pktgen_device_event,
+ };
+ 
+-static struct file_operations pktgen_fops = {
+-        .read     = proc_pgctrl_read,
+-        .write    = proc_pgctrl_write,
+-	/*  .ioctl    = pktgen_ioctl, later maybe */
+-};
+-
+ /*
+  * /proc handling functions 
+  *
+  */
+ 
+-static struct proc_dir_entry *pg_proc_dir = NULL;
+-static int proc_pgctrl_read_eof=0;
+-
+-static ssize_t proc_pgctrl_read(struct file* file, char __user * buf,
+-                                 size_t count, loff_t *ppos)
++static int pgctrl_show(struct seq_file *seq, void *v)
+ { 
+-	char data[200];
+-	int len = 0;
+-
+-	if(proc_pgctrl_read_eof) {
+-		proc_pgctrl_read_eof=0;
+-		len = 0;
+-		goto out;
+-	}
+-
+-	sprintf(data, "%s", VERSION); 
+-
+-	len = strlen(data);
+-
+-	if(len > count) {
+-		len =-EFAULT;
+-		goto out;
+-	}  	
+-
+-	if (copy_to_user(buf, data, len)) {
+-		len =-EFAULT;
+-		goto out;
+-	}  
+-
+-	*ppos += len;
+-	proc_pgctrl_read_eof=1; /* EOF next call */
+-
+- out:
+-	return len;
++	seq_puts(seq, VERSION);
++	return 0;
+ }
+ 
+-static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf,
+-				 size_t count, loff_t *ppos)
++static ssize_t pgctrl_write(struct file* file,const char __user * buf,
++			    size_t count, loff_t *ppos)
+ {
+-	char *data = NULL;
+ 	int err = 0;
++	char data[128];
+ 
+         if (!capable(CAP_NET_ADMIN)){
+                 err = -EPERM;
+ 		goto out;
+         }
+ 
+-	data = (void*)vmalloc ((unsigned int)count);
++	if (count > sizeof(data))
++		count = sizeof(data);
+ 
+-	if(!data) {
+-		err = -ENOMEM;
+-		goto out;
+-	}
+ 	if (copy_from_user(data, buf, count)) {
+-		err =-EFAULT;
+-		goto out_free;
++		err = -EFAULT;
++		goto out;
+ 	}  
+ 	data[count-1] = 0; /* Make string */
+ 
+@@ -594,31 +540,40 @@ static ssize_t proc_pgctrl_write(struct 
+ 
+ 	err = count;
+ 
+- out_free:
+-	vfree (data);
+  out:
+         return err;
+ }
+ 
+-static int proc_if_read(char *buf , char **start, off_t offset,
+-                           int len, int *eof, void *data)
++static int pgctrl_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, pgctrl_show, PDE(inode)->data);
++}
++
++static struct file_operations pktgen_fops = {
++	.owner	  = THIS_MODULE,
++	.open	  = pgctrl_open,
++        .read     = seq_read,
++	.llseek	  = seq_lseek,
++        .write    = pgctrl_write,
++	.release  = single_release,
++};
++
++static int pktgen_if_show(struct seq_file *seq, void *v)
+ {
+-	char *p;
+ 	int i;
+-        struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
++        struct pktgen_dev *pkt_dev = seq->private;
+         __u64 sa;
+         __u64 stopped;
+         __u64 now = getCurUs();
+         
+-	p = buf;
+-	p += sprintf(p, "Params: count %llu  min_pkt_size: %u  max_pkt_size: %u\n",
+-		     (unsigned long long) pkt_dev->count,
+-		     pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
++	seq_printf(seq, "Params: count %llu  min_pkt_size: %u  max_pkt_size: %u\n",
++		   (unsigned long long) pkt_dev->count,
++		   pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
+ 
+-	p += sprintf(p, "     frags: %d  delay: %u  clone_skb: %d  ifname: %s\n",
+-                     pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
++	seq_printf(seq, "     frags: %d  delay: %u  clone_skb: %d  ifname: %s\n",
++		   pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
+ 
+-	p += sprintf(p, "     flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
++	seq_printf(seq, "     flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
+ 
+ 
+ 	if(pkt_dev->flags & F_IPV6) {
+@@ -626,19 +581,19 @@ static int proc_if_read(char *buf , char
+ 		fmt_ip6(b1,  pkt_dev->in6_saddr.s6_addr);
+ 		fmt_ip6(b2,  pkt_dev->min_in6_saddr.s6_addr);
+ 		fmt_ip6(b3,  pkt_dev->max_in6_saddr.s6_addr);
+-		p += sprintf(p, "     saddr: %s  min_saddr: %s  max_saddr: %s\n", b1, b2, b3);
++		seq_printf(seq, "     saddr: %s  min_saddr: %s  max_saddr: %s\n", b1, b2, b3);
+ 
+ 		fmt_ip6(b1,  pkt_dev->in6_daddr.s6_addr);
+ 		fmt_ip6(b2,  pkt_dev->min_in6_daddr.s6_addr);
+ 		fmt_ip6(b3,  pkt_dev->max_in6_daddr.s6_addr);
+-		p += sprintf(p, "     daddr: %s  min_daddr: %s  max_daddr: %s\n", b1, b2, b3);
++		seq_printf(seq, "     daddr: %s  min_daddr: %s  max_daddr: %s\n", b1, b2, b3);
+ 
+ 	} 
+ 	else 
+-		p += sprintf(p, "     dst_min: %s  dst_max: %s\n     src_min: %s  src_max: %s\n",
+-                     pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
++		seq_printf(seq,"     dst_min: %s  dst_max: %s\n     src_min: %s  src_max: %s\n",
++			   pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
+ 
+-        p += sprintf(p, "     src_mac: ");
++	seq_puts(seq, "     src_mac: ");
+ 
+ 	if ((pkt_dev->src_mac[0] == 0) && 
+ 	    (pkt_dev->src_mac[1] == 0) && 
+@@ -648,89 +603,89 @@ static int proc_if_read(char *buf , char
+ 	    (pkt_dev->src_mac[5] == 0)) 
+ 
+ 		for (i = 0; i < 6; i++) 
+-			p += sprintf(p, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? "  " : ":");
++			seq_printf(seq,  "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? "  " : ":");
+ 
+ 	else 
+ 		for (i = 0; i < 6; i++) 
+-			p += sprintf(p, "%02X%s", pkt_dev->src_mac[i], i == 5 ? "  " : ":");
++			seq_printf(seq,  "%02X%s", pkt_dev->src_mac[i], i == 5 ? "  " : ":");
+ 
+-        p += sprintf(p, "dst_mac: ");
++        seq_printf(seq,  "dst_mac: ");
+ 	for (i = 0; i < 6; i++) 
+-		p += sprintf(p, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
++		seq_printf(seq,  "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
+ 
+-        p += sprintf(p, "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
+-                     pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
+-                     pkt_dev->udp_dst_max);
++        seq_printf(seq,  "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
++		   pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
++		   pkt_dev->udp_dst_max);
+ 
+-        p += sprintf(p, "     src_mac_count: %d  dst_mac_count: %d \n     Flags: ",
+-                     pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
++        seq_printf(seq,  "     src_mac_count: %d  dst_mac_count: %d \n     Flags: ",
++		   pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
+ 
+ 
+         if (pkt_dev->flags &  F_IPV6) 
+-                p += sprintf(p, "IPV6  ");
++                seq_printf(seq,  "IPV6  ");
+ 
+         if (pkt_dev->flags &  F_IPSRC_RND) 
+-                p += sprintf(p, "IPSRC_RND  ");
++                seq_printf(seq,  "IPSRC_RND  ");
+ 
+         if (pkt_dev->flags & F_IPDST_RND) 
+-                p += sprintf(p, "IPDST_RND  ");
++                seq_printf(seq,  "IPDST_RND  ");
+         
+         if (pkt_dev->flags & F_TXSIZE_RND) 
+-                p += sprintf(p, "TXSIZE_RND  ");
++                seq_printf(seq,  "TXSIZE_RND  ");
+         
+         if (pkt_dev->flags & F_UDPSRC_RND) 
+-                p += sprintf(p, "UDPSRC_RND  ");
++                seq_printf(seq,  "UDPSRC_RND  ");
+         
+         if (pkt_dev->flags & F_UDPDST_RND) 
+-                p += sprintf(p, "UDPDST_RND  ");
++                seq_printf(seq,  "UDPDST_RND  ");
+         
+         if (pkt_dev->flags & F_MACSRC_RND) 
+-                p += sprintf(p, "MACSRC_RND  ");
++                seq_printf(seq,  "MACSRC_RND  ");
+         
+         if (pkt_dev->flags & F_MACDST_RND) 
+-                p += sprintf(p, "MACDST_RND  ");
++                seq_printf(seq,  "MACDST_RND  ");
+ 
+         
+-        p += sprintf(p, "\n");
++        seq_puts(seq,  "\n");
+         
+         sa = pkt_dev->started_at;
+         stopped = pkt_dev->stopped_at;
+         if (pkt_dev->running) 
+                 stopped = now; /* not really stopped, more like last-running-at */
+         
+-        p += sprintf(p, "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %lluus  stopped: %lluus idle: %lluus\n",
+-		     (unsigned long long) pkt_dev->sofar,
+-		     (unsigned long long) pkt_dev->errors,
+-		     (unsigned long long) sa,
+-		     (unsigned long long) stopped, 
+-		     (unsigned long long) pkt_dev->idle_acc);
+-
+-        p += sprintf(p, "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
+-                     pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset, pkt_dev->cur_src_mac_offset);
++        seq_printf(seq,  "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %lluus  stopped: %lluus idle: %lluus\n",
++		   (unsigned long long) pkt_dev->sofar,
++		   (unsigned long long) pkt_dev->errors,
++		   (unsigned long long) sa,
++		   (unsigned long long) stopped,
++		   (unsigned long long) pkt_dev->idle_acc);
++
++        seq_printf(seq,  "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
++		   pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset,
++		   pkt_dev->cur_src_mac_offset);
+ 
+ 	if(pkt_dev->flags & F_IPV6) {
+ 		char b1[128], b2[128];
+ 		fmt_ip6(b1,  pkt_dev->cur_in6_daddr.s6_addr);
+ 		fmt_ip6(b2,  pkt_dev->cur_in6_saddr.s6_addr);
+-		p += sprintf(p, "     cur_saddr: %s  cur_daddr: %s\n", b2, b1);
++		seq_printf(seq,  "     cur_saddr: %s  cur_daddr: %s\n", b2, b1);
+ 	} 
+ 	else 
+-		p += sprintf(p, "     cur_saddr: 0x%x  cur_daddr: 0x%x\n",
+-                     pkt_dev->cur_saddr, pkt_dev->cur_daddr);
++		seq_printf(seq,  "     cur_saddr: 0x%x  cur_daddr: 0x%x\n",
++			   pkt_dev->cur_saddr, pkt_dev->cur_daddr);
+ 
+ 
+-	p += sprintf(p, "     cur_udp_dst: %d  cur_udp_src: %d\n",
+-                     pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
++	seq_printf(seq,  "     cur_udp_dst: %d  cur_udp_src: %d\n",
++		   pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
+ 
+-	p += sprintf(p, "     flows: %u\n", pkt_dev->nflows);
++	seq_printf(seq,  "     flows: %u\n", pkt_dev->nflows);
+ 
+ 	if (pkt_dev->result[0])
+-		p += sprintf(p, "Result: %s\n", pkt_dev->result);
++		seq_printf(seq,  "Result: %s\n", pkt_dev->result);
+ 	else
+-		p += sprintf(p, "Result: Idle\n");
+-	*eof = 1;
++		seq_printf(seq,  "Result: Idle\n");
+ 
+-	return p - buf;
++	return 0;
+ }
+ 
+ 
+@@ -802,13 +757,14 @@ done_str:
+ 	return i;
+ }
+ 
+-static int proc_if_write(struct file *file, const char __user *user_buffer,
+-                            unsigned long count, void *data)
++static ssize_t pktgen_if_write(struct file *file, const char __user *user_buffer,
++			       size_t count, loff_t *offset)
+ {
++	struct seq_file *seq = (struct seq_file *) file->private_data;
++        struct pktgen_dev *pkt_dev = seq->private;
+ 	int i = 0, max, len;
+ 	char name[16], valstr[32];
+ 	unsigned long value = 0;
+-        struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
+         char* pg_result = NULL;
+         int tmp = 0;
+ 	char buf[128];
+@@ -849,7 +805,8 @@ static int proc_if_write(struct file *fi
+                 if (copy_from_user(tb, user_buffer, count))
+ 			return -EFAULT;
+                 tb[count] = 0;
+-		printk("pktgen: %s,%lu  buffer -:%s:-\n", name, count, tb);
++		printk("pktgen: %s,%lu  buffer -:%s:-\n", name,
++		       (unsigned long) count, tb);
+         }
+ 
+ 	if (!strcmp(name, "min_pkt_size")) {
+@@ -1335,92 +1292,98 @@ static int proc_if_write(struct file *fi
+ 	return -EINVAL;
+ }
+ 
+-static int proc_thread_read(char *buf , char **start, off_t offset,
+-                               int len, int *eof, void *data)
++static int pktgen_if_open(struct inode *inode, struct file *file)
+ {
+-	char *p;
+-        struct pktgen_thread *t = (struct pktgen_thread*)(data);
+-        struct pktgen_dev *pkt_dev = NULL;
++	return single_open(file, pktgen_if_show, PDE(inode)->data);
++}
+ 
++static struct file_operations pktgen_if_fops = {
++	.owner	  = THIS_MODULE,
++	.open	  = pktgen_if_open,
++        .read     = seq_read,
++	.llseek	  = seq_lseek,
++        .write    = pktgen_if_write,
++	.release  = single_release,
++};
+ 
+-        if (!t) {
+-                printk("pktgen: ERROR: could not find thread in proc_thread_read\n");
+-                return -EINVAL;
+-        }
++static int pktgen_thread_show(struct seq_file *seq, void *v)
++{
++        struct pktgen_thread *t = seq->private;
++        struct pktgen_dev *pkt_dev = NULL;
+ 
+-	p = buf;
+-	p += sprintf(p, "Name: %s  max_before_softirq: %d\n",
++	BUG_ON(!t);
++
++	seq_printf(seq, "Name: %s  max_before_softirq: %d\n",
+                      t->name, t->max_before_softirq);
+ 
+-        p += sprintf(p, "Running: ");
++        seq_printf(seq, "Running: ");
+         
+         if_lock(t);
+         for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) 
+ 		if(pkt_dev->running)
+-			p += sprintf(p, "%s ", pkt_dev->ifname);
++			seq_printf(seq, "%s ", pkt_dev->ifname);
+         
+-        p += sprintf(p, "\nStopped: ");
++        seq_printf(seq, "\nStopped: ");
+ 
+         for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) 
+ 		if(!pkt_dev->running)
+-			p += sprintf(p, "%s ", pkt_dev->ifname);
++			seq_printf(seq, "%s ", pkt_dev->ifname);
+ 
+ 	if (t->result[0])
+-		p += sprintf(p, "\nResult: %s\n", t->result);
++		seq_printf(seq, "\nResult: %s\n", t->result);
+ 	else
+-		p += sprintf(p, "\nResult: NA\n");
+-
+-	*eof = 1;
++		seq_printf(seq, "\nResult: NA\n");
+ 
+         if_unlock(t);
+ 
+-	return p - buf;
++	return 0;
+ }
+ 
+-static int proc_thread_write(struct file *file, const char __user *user_buffer,
+-                                unsigned long count, void *data)
++static ssize_t pktgen_thread_write(struct file *file,
++				   const char __user *user_buffer,
++				   size_t count, loff_t *offset)
+ {
++	struct seq_file *seq = (struct seq_file *) file->private_data;
++        struct pktgen_thread *t = seq->private;
+ 	int i = 0, max, len, ret;
+ 	char name[40];
+-        struct pktgen_thread *t;
+         char *pg_result;
+         unsigned long value = 0;
+-        
++
+ 	if (count < 1) {
+ 		//	sprintf(pg_result, "Wrong command format");
+ 		return -EINVAL;
+ 	}
+-  
++
+ 	max = count - i;
+         len = count_trail_chars(&user_buffer[i], max);
+-        if (len < 0) 
+-		return len; 
+-     
++        if (len < 0)
++		return len;
++
+ 	i += len;
+-  
++
+ 	/* Read variable name */
+ 
+ 	len = strn_len(&user_buffer[i], sizeof(name) - 1);
+-        if (len < 0)  
+-		return len; 
++        if (len < 0)
++		return len;
+ 	
+ 	memset(name, 0, sizeof(name));
+ 	if (copy_from_user(name, &user_buffer[i], len))
+ 		return -EFAULT;
+ 	i += len;
+-  
++
+ 	max = count -i;
+ 	len = count_trail_chars(&user_buffer[i], max);
+-        if (len < 0)  
+-		return len; 
+-	
++        if (len < 0)
++		return len;
++
+ 	i += len;
+ 
+-	if (debug) 
+-		printk("pktgen: t=%s, count=%lu\n", name, count);
+-        
++	if (debug)
++		printk("pktgen: t=%s, count=%lu\n", name,
++		       (unsigned long) count);
+ 
+-        t = (struct pktgen_thread*)(data);
+ 	if(!t) {
+ 		printk("pktgen: ERROR: No thread\n");
+ 		ret = -EINVAL;
+@@ -1474,21 +1437,19 @@ static int proc_thread_write(struct file
+ 	return ret;
+ }
+ 
+-static int create_proc_dir(void)
++static int pktgen_thread_open(struct inode *inode, struct file *file)
+ {
+-	pg_proc_dir = proc_mkdir(PG_PROC_DIR, NULL);
+-        
+-        if (!pg_proc_dir) 
+-                return -ENODEV;
+-        
+-        return 0;
++	return single_open(file, pktgen_thread_show, PDE(inode)->data);
+ }
+ 
+-static int remove_proc_dir(void)
+-{
+-        remove_proc_entry(PG_PROC_DIR, NULL);
+-        return 0;
+-}
++static struct file_operations pktgen_thread_fops = {
++	.owner	  = THIS_MODULE,
++	.open	  = pktgen_thread_open,
++        .read     = seq_read,
++	.llseek	  = seq_lseek,
++        .write    = pktgen_thread_write,
++	.release  = single_release,
++};
+ 
+ /* Think find or remove for NN */
+ static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove) 
+@@ -1702,7 +1663,7 @@ static void spin(struct pktgen_dev *pkt_
+ 	start = now = getCurUs();
+ 	printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
+ 	while (now < spin_until_us) {
+-		/* TODO: optimise sleeping behavior */
++		/* TODO: optimize sleeping behavior */
+ 		if (spin_until_us - now > jiffies_to_usecs(1)+1)
+ 			schedule_timeout_interruptible(1);
+ 		else if (spin_until_us - now > 100) {
+@@ -2361,7 +2322,7 @@ static void pktgen_stop_all_threads_ifs(
+ 		pktgen_stop(t);
+ 		t = t->next;
+ 	}
+-       thread_unlock();
++	thread_unlock();
+ }
+ 
+ static int thread_is_running(struct pktgen_thread *t )
+@@ -2552,10 +2513,9 @@ static void pktgen_rem_thread(struct pkt
+ 
+ 	struct pktgen_thread *tmp = pktgen_threads;
+ 
+-        if (strlen(t->fname))
+-                remove_proc_entry(t->fname, NULL);
++	remove_proc_entry(t->name, pg_proc_dir);
+ 
+-       thread_lock();
++	thread_lock();
+ 
+ 	if (tmp == t)
+ 		pktgen_threads = tmp->next;
+@@ -2825,7 +2785,7 @@ static struct pktgen_dev *pktgen_find_de
+         if_lock(t);
+ 
+         for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
+-                if (strcmp(pkt_dev->ifname, ifname) == 0) {
++                if (strncmp(pkt_dev->ifname, ifname, IFNAMSIZ) == 0) {
+                         break;
+                 }
+         }
+@@ -2864,74 +2824,70 @@ static int add_dev_to_thread(struct pktg
+ static int pktgen_add_device(struct pktgen_thread *t, const char* ifname) 
+ {
+         struct pktgen_dev *pkt_dev;
++	struct proc_dir_entry *pe;
+ 	
+ 	/* We don't allow a device to be on several threads */
+ 
+-	if( (pkt_dev = __pktgen_NN_threads(ifname, FIND)) == NULL) {
+-						   
+-		pkt_dev = kmalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
+-                if (!pkt_dev) 
+-                        return -ENOMEM;
+-
+-                memset(pkt_dev, 0, sizeof(struct pktgen_dev));
+-
+-		pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
+-		if (pkt_dev->flows == NULL) {
+-			kfree(pkt_dev);
+-			return -ENOMEM;
+-		}
+-		memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
+-
+-		pkt_dev->min_pkt_size = ETH_ZLEN;
+-                pkt_dev->max_pkt_size = ETH_ZLEN;
+-                pkt_dev->nfrags = 0;
+-                pkt_dev->clone_skb = pg_clone_skb_d;
+-                pkt_dev->delay_us = pg_delay_d / 1000;
+-                pkt_dev->delay_ns = pg_delay_d % 1000;
+-                pkt_dev->count = pg_count_d;
+-                pkt_dev->sofar = 0;
+-                pkt_dev->udp_src_min = 9; /* sink port */
+-                pkt_dev->udp_src_max = 9;
+-                pkt_dev->udp_dst_min = 9;
+-                pkt_dev->udp_dst_max = 9;
+-
+-                strncpy(pkt_dev->ifname, ifname, 31);
+-                sprintf(pkt_dev->fname, "%s/%s", PG_PROC_DIR, ifname);
+-
+-                if (! pktgen_setup_dev(pkt_dev)) {
+-                        printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
+-			if (pkt_dev->flows)
+-				vfree(pkt_dev->flows);
+-                        kfree(pkt_dev);
+-                        return -ENODEV;
+-                }
+-
+-                pkt_dev->proc_ent = create_proc_entry(pkt_dev->fname, 0600, NULL);
+-                if (!pkt_dev->proc_ent) {
+-                        printk("pktgen: cannot create %s procfs entry.\n", pkt_dev->fname);
+-			if (pkt_dev->flows)
+-				vfree(pkt_dev->flows);
+-                        kfree(pkt_dev);
+-                        return -EINVAL;
+-                }
+-                pkt_dev->proc_ent->read_proc = proc_if_read;
+-                pkt_dev->proc_ent->write_proc = proc_if_write;
+-                pkt_dev->proc_ent->data = (void*)(pkt_dev);
+-		pkt_dev->proc_ent->owner = THIS_MODULE;
+-
+-                return add_dev_to_thread(t, pkt_dev);
+-        }
+-        else {
++	pkt_dev = __pktgen_NN_threads(ifname, FIND);
++	if (pkt_dev) {
+                 printk("pktgen: ERROR: interface already used.\n");
+                 return -EBUSY;
+         }
++
++	pkt_dev = kzalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
++	if (!pkt_dev)
++		return -ENOMEM;
++
++	pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
++	if (pkt_dev->flows == NULL) {
++		kfree(pkt_dev);
++		return -ENOMEM;
++	}
++	memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
++
++	pkt_dev->min_pkt_size = ETH_ZLEN;
++	pkt_dev->max_pkt_size = ETH_ZLEN;
++	pkt_dev->nfrags = 0;
++	pkt_dev->clone_skb = pg_clone_skb_d;
++	pkt_dev->delay_us = pg_delay_d / 1000;
++	pkt_dev->delay_ns = pg_delay_d % 1000;
++	pkt_dev->count = pg_count_d;
++	pkt_dev->sofar = 0;
++	pkt_dev->udp_src_min = 9; /* sink port */
++	pkt_dev->udp_src_max = 9;
++	pkt_dev->udp_dst_min = 9;
++	pkt_dev->udp_dst_max = 9;
++
++	strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
++
++	if (! pktgen_setup_dev(pkt_dev)) {
++		printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
++		if (pkt_dev->flows)
++			vfree(pkt_dev->flows);
++		kfree(pkt_dev);
++		return -ENODEV;
++	}
++
++	pe = create_proc_entry(ifname, 0600, pg_proc_dir);
++	if (!pe) {
++		printk("pktgen: cannot create %s/%s procfs entry.\n",
++		       PG_PROC_DIR, ifname);
++		if (pkt_dev->flows)
++			vfree(pkt_dev->flows);
++		kfree(pkt_dev);
++		return -EINVAL;
++	}
++	pe->proc_fops = &pktgen_if_fops;
++	pe->data = pkt_dev;
++
++	return add_dev_to_thread(t, pkt_dev);
+ }
+ 
+ static struct pktgen_thread *pktgen_find_thread(const char* name) 
+ {
+         struct pktgen_thread *t = NULL;
+ 
+-       thread_lock();
++	thread_lock();
+ 
+         t = pktgen_threads;
+         while (t) {
+@@ -2947,6 +2903,7 @@ static struct pktgen_thread *pktgen_find
+ static int pktgen_create_thread(const char* name, int cpu) 
+ {
+         struct pktgen_thread *t = NULL;
++	struct proc_dir_entry *pe;
+ 
+         if (strlen(name) > 31) {
+                 printk("pktgen: ERROR:  Thread name cannot be more than 31 characters.\n");
+@@ -2958,28 +2915,26 @@ static int pktgen_create_thread(const ch
+                 return -EINVAL;
+         }
+ 
+-        t = (struct pktgen_thread*)(kmalloc(sizeof(struct pktgen_thread), GFP_KERNEL));
++        t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL);
+         if (!t) {
+                 printk("pktgen: ERROR: out of memory, can't create new thread.\n");
+                 return -ENOMEM;
+         }
+ 
+-        memset(t, 0, sizeof(struct pktgen_thread));
+         strcpy(t->name, name);
+         spin_lock_init(&t->if_lock);
+ 	t->cpu = cpu;
+         
+-        sprintf(t->fname, "%s/%s", PG_PROC_DIR, t->name);
+-        t->proc_ent = create_proc_entry(t->fname, 0600, NULL);
+-        if (!t->proc_ent) {
+-                printk("pktgen: cannot create %s procfs entry.\n", t->fname);
++        pe = create_proc_entry(t->name, 0600, pg_proc_dir);
++        if (!pe) {
++                printk("pktgen: cannot create %s/%s procfs entry.\n",
++		       PG_PROC_DIR, t->name);
+                 kfree(t);
+                 return -EINVAL;
+         }
+-        t->proc_ent->read_proc = proc_thread_read;
+-        t->proc_ent->write_proc = proc_thread_write;
+-        t->proc_ent->data = (void*)(t);
+-        t->proc_ent->owner = THIS_MODULE;
++
++	pe->proc_fops = &pktgen_thread_fops;
++	pe->data = t;
+ 
+         t->next = pktgen_threads;
+         pktgen_threads = t;
+@@ -3034,8 +2989,7 @@ static int pktgen_remove_device(struct p
+ 
+         /* Clean up proc file system */
+ 
+-        if (strlen(pkt_dev->fname)) 
+-                remove_proc_entry(pkt_dev->fname, NULL);
++	remove_proc_entry(pkt_dev->ifname, pg_proc_dir);
+ 
+ 	if (pkt_dev->flows)
+ 		vfree(pkt_dev->flows);
+@@ -3046,31 +3000,31 @@ static int pktgen_remove_device(struct p
+ static int __init pg_init(void) 
+ {
+ 	int cpu;
+-	printk(version);
++	struct proc_dir_entry *pe;
+ 
+-        module_fname[0] = 0;
+-
+-	create_proc_dir();
++	printk(version);
+ 
+-        sprintf(module_fname, "%s/pgctrl", PG_PROC_DIR);
+-        module_proc_ent = create_proc_entry(module_fname, 0600, NULL);
+-        if (!module_proc_ent) {
+-                printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname);
++	pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net);
++	if (!pg_proc_dir)
++		return -ENODEV;
++	pg_proc_dir->owner = THIS_MODULE;
++
++	pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir);
++        if (pe == NULL) {
++		printk("pktgen: ERROR: cannot create %s procfs entry.\n", PGCTRL);
++		proc_net_remove(PG_PROC_DIR);
+                 return -EINVAL;
+         }
+ 
+-        module_proc_ent->proc_fops =  &pktgen_fops;
+-        module_proc_ent->data = NULL;
++        pe->proc_fops = &pktgen_fops;
++        pe->data      = NULL;
+ 
+ 	/* Register us to receive netdevice events */
+ 	register_netdevice_notifier(&pktgen_notifier_block);
+         
+-	for (cpu = 0; cpu < NR_CPUS ; cpu++) {
++	for_each_online_cpu(cpu) {
+ 		char buf[30];
+ 
+-		if (!cpu_online(cpu))
+-			continue;
+-
+                 sprintf(buf, "kpktgend_%i", cpu);
+                 pktgen_create_thread(buf, cpu);
+         }
+@@ -3095,10 +3049,8 @@ static void __exit pg_cleanup(void)
+ 	unregister_netdevice_notifier(&pktgen_notifier_block);
+ 
+         /* Clean up proc file system */
+-
+-        remove_proc_entry(module_fname, NULL);
+-        
+-	remove_proc_dir();
++	remove_proc_entry(PGCTRL, pg_proc_dir);
++	proc_net_remove(PG_PROC_DIR);
+ }
+ 
+ 
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -122,6 +122,8 @@ void skb_under_panic(struct sk_buff *skb
+  *	__alloc_skb	-	allocate a network buffer
+  *	@size: size to allocate
+  *	@gfp_mask: allocation mask
++ *	@fclone: allocate from fclone cache instead of head cache
++ *		and allocate a cloned (child) skb
+  *
+  *	Allocate a new &sk_buff. The returned buffer has no headroom and a
+  *	tail room of size bytes. The object has a reference count of one.
+@@ -174,6 +176,8 @@ struct sk_buff *__alloc_skb(unsigned int
+ 	skb_shinfo(skb)->tso_size = 0;
+ 	skb_shinfo(skb)->tso_segs = 0;
+ 	skb_shinfo(skb)->frag_list = NULL;
++	skb_shinfo(skb)->ufo_size = 0;
++	skb_shinfo(skb)->ip6_frag_id = 0;
+ out:
+ 	return skb;
+ nodata:
+@@ -1694,6 +1698,78 @@ unsigned int skb_find_text(struct sk_buf
+ 	return textsearch_find(config, state);
+ }
+ 
++/**
++ * skb_append_datato_frags: - append the user data to a skb
++ * @sk: sock  structure
++ * @skb: skb structure to be appened with user data.
++ * @getfrag: call back function to be used for getting the user data
++ * @from: pointer to user message iov
++ * @length: length of the iov message
++ *
++ * Description: This procedure append the user data in the fragment part
++ * of the skb if any page alloc fails user this procedure returns  -ENOMEM
++ */
++int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
++			int getfrag(void *from, char *to, int offset,
++					int len, int odd, struct sk_buff *skb),
++			void *from, int length)
++{
++	int frg_cnt = 0;
++	skb_frag_t *frag = NULL;
++	struct page *page = NULL;
++	int copy, left;
++	int offset = 0;
++	int ret;
++
++	do {
++		/* Return error if we don't have space for new frag */
++		frg_cnt = skb_shinfo(skb)->nr_frags;
++		if (frg_cnt >= MAX_SKB_FRAGS)
++			return -EFAULT;
++
++		/* allocate a new page for next frag */
++		page = alloc_pages(sk->sk_allocation, 0);
++
++		/* If alloc_page fails just return failure and caller will
++		 * free previous allocated pages by doing kfree_skb()
++		 */
++		if (page == NULL)
++			return -ENOMEM;
++
++		/* initialize the next frag */
++		sk->sk_sndmsg_page = page;
++		sk->sk_sndmsg_off = 0;
++		skb_fill_page_desc(skb, frg_cnt, page, 0, 0);
++		skb->truesize += PAGE_SIZE;
++		atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
++
++		/* get the new initialized frag */
++		frg_cnt = skb_shinfo(skb)->nr_frags;
++		frag = &skb_shinfo(skb)->frags[frg_cnt - 1];
++
++		/* copy the user data to page */
++		left = PAGE_SIZE - frag->page_offset;
++		copy = (length > left)? left : length;
++
++		ret = getfrag(from, (page_address(frag->page) +
++			    frag->page_offset + frag->size),
++			    offset, copy, 0, skb);
++		if (ret < 0)
++			return -EFAULT;
++
++		/* copy was successful so update the size parameters */
++		sk->sk_sndmsg_off += copy;
++		frag->size += copy;
++		skb->len += copy;
++		skb->data_len += copy;
++		offset += copy;
++		length -= copy;
++
++	} while (length > 0);
++
++	return 0;
++}
++
+ void __init skb_init(void)
+ {
+ 	skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
+@@ -1745,3 +1821,4 @@ EXPORT_SYMBOL(skb_prepare_seq_read);
+ EXPORT_SYMBOL(skb_seq_read);
+ EXPORT_SYMBOL(skb_abort_seq_read);
+ EXPORT_SYMBOL(skb_find_text);
++EXPORT_SYMBOL(skb_append_datato_frags);
+diff --git a/net/core/sock.c b/net/core/sock.c
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -940,7 +940,7 @@ static struct sk_buff *sock_alloc_send_p
+ 					    int noblock, int *errcode)
+ {
+ 	struct sk_buff *skb;
+-	unsigned int gfp_mask;
++	gfp_t gfp_mask;
+ 	long timeo;
+ 	int err;
+ 
+diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
+--- a/net/dccp/dccp.h
++++ b/net/dccp/dccp.h
+@@ -118,7 +118,6 @@ DECLARE_SNMP_STAT(struct dccp_mib, dccp_
+ #define DCCP_ADD_STATS_USER(field, val)	\
+ 			SNMP_ADD_STATS_USER(dccp_statistics, field, val)
+ 
+-extern int  dccp_transmit_skb(struct sock *sk, struct sk_buff *skb);
+ extern int  dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb);
+ 
+ extern int dccp_send_response(struct sock *sk);
+diff --git a/net/dccp/output.c b/net/dccp/output.c
+--- a/net/dccp/output.c
++++ b/net/dccp/output.c
+@@ -12,6 +12,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/dccp.h>
++#include <linux/kernel.h>
+ #include <linux/skbuff.h>
+ 
+ #include <net/sock.h>
+@@ -25,13 +26,20 @@ static inline void dccp_event_ack_sent(s
+ 	inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
+ }
+ 
++static inline void dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
++{
++	skb_set_owner_w(skb, sk);
++	WARN_ON(sk->sk_send_head);
++	sk->sk_send_head = skb;
++}
++
+ /*
+  * All SKB's seen here are completely headerless. It is our
+  * job to build the DCCP header, and pass the packet down to
+  * IP so it can do the same plus pass the packet off to the
+  * device.
+  */
+-int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
++static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
+ {
+ 	if (likely(skb != NULL)) {
+ 		const struct inet_sock *inet = inet_sk(sk);
+@@ -50,10 +58,21 @@ int dccp_transmit_skb(struct sock *sk, s
+ 		switch (dcb->dccpd_type) {
+ 		case DCCP_PKT_DATA:
+ 			set_ack = 0;
++			/* fall through */
++		case DCCP_PKT_DATAACK:
+ 			break;
++
+ 		case DCCP_PKT_SYNC:
+ 		case DCCP_PKT_SYNCACK:
+ 			ackno = dcb->dccpd_seq;
++			/* fall through */
++		default:
++			/*
++			 * Only data packets should come through with skb->sk
++			 * set.
++			 */
++			WARN_ON(skb->sk);
++			skb_set_owner_w(skb, sk);
+ 			break;
+ 		}
+ 
+@@ -63,9 +82,6 @@ int dccp_transmit_skb(struct sock *sk, s
+ 		skb->h.raw = skb_push(skb, dccp_header_size);
+ 		dh = dccp_hdr(skb);
+ 
+-		if (!skb->sk)
+-			skb_set_owner_w(skb, sk);
+-
+ 		/* Build DCCP header and checksum it. */
+ 		memset(dh, 0, dccp_header_size);
+ 		dh->dccph_type	= dcb->dccpd_type;
+@@ -393,10 +409,8 @@ int dccp_connect(struct sock *sk)
+ 
+ 	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;
+ 	skb->csum = 0;
+-	skb_set_owner_w(skb, sk);
+ 
+-	BUG_TRAP(sk->sk_send_head == NULL);
+-	sk->sk_send_head = skb;
++	dccp_skb_entail(sk, skb);
+ 	dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL));
+ 	DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);
+ 
+@@ -425,7 +439,6 @@ void dccp_send_ack(struct sock *sk)
+ 		skb_reserve(skb, MAX_DCCP_HEADER);
+ 		skb->csum = 0;
+ 		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK;
+-		skb_set_owner_w(skb, sk);
+ 		dccp_transmit_skb(sk, skb);
+ 	}
+ }
+@@ -482,7 +495,6 @@ void dccp_send_sync(struct sock *sk, con
+ 	DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
+ 	DCCP_SKB_CB(skb)->dccpd_seq = seq;
+ 
+-	skb_set_owner_w(skb, sk);
+ 	dccp_transmit_skb(sk, skb);
+ }
+ 
+@@ -495,7 +507,7 @@ void dccp_send_close(struct sock *sk, co
+ {
+ 	struct dccp_sock *dp = dccp_sk(sk);
+ 	struct sk_buff *skb;
+-	const unsigned int prio = active ? GFP_KERNEL : GFP_ATOMIC;
++	const gfp_t prio = active ? GFP_KERNEL : GFP_ATOMIC;
+ 
+ 	skb = alloc_skb(sk->sk_prot->max_header, prio);
+ 	if (skb == NULL)
+@@ -507,10 +519,8 @@ void dccp_send_close(struct sock *sk, co
+ 	DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ?
+ 					DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ;
+ 
+-	skb_set_owner_w(skb, sk);
+ 	if (active) {
+-		BUG_TRAP(sk->sk_send_head == NULL);
+-		sk->sk_send_head = skb;
++		dccp_skb_entail(sk, skb);
+ 		dccp_transmit_skb(sk, skb_clone(skb, prio));
+ 	} else
+ 		dccp_transmit_skb(sk, skb);
+diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
+--- a/net/decnet/af_decnet.c
++++ b/net/decnet/af_decnet.c
+@@ -719,22 +719,9 @@ static int dn_bind(struct socket *sock, 
+ 	if (saddr->sdn_flags & ~SDF_WILD)
+ 		return -EINVAL;
+ 
+-#if 1
+ 	if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum ||
+ 	    (saddr->sdn_flags & SDF_WILD)))
+ 		return -EACCES;
+-#else
+-	/*
+-	 * Maybe put the default actions in the default security ops for
+-	 * dn_prot_sock ? Would be nice if the capable call would go there
+-	 * too.
+-	 */
+-	if (security_dn_prot_sock(saddr) &&
+-	    !capable(CAP_NET_BIND_SERVICE) || 
+-	    saddr->sdn_objnum || (saddr->sdn_flags & SDF_WILD))
+-		return -EACCES;
+-#endif
+-
+ 
+ 	if (!(saddr->sdn_flags & SDF_WILD)) {
+ 		if (dn_ntohs(saddr->sdn_nodeaddrl)) {
+diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
+--- a/net/ethernet/eth.c
++++ b/net/ethernet/eth.c
+@@ -146,19 +146,6 @@ int eth_rebuild_header(struct sk_buff *s
+ 	return 0;
+ }
+ 
+-static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b)
+-{
+-	const unsigned short *dest = (unsigned short *) __a;
+-	const unsigned short *devaddr = (unsigned short *) __b;
+-	unsigned int res;
+-
+-	BUILD_BUG_ON(ETH_ALEN != 6);
+-	res = ((dest[0] ^ devaddr[0]) |
+-	       (dest[1] ^ devaddr[1]) |
+-	       (dest[2] ^ devaddr[2])) != 0;
+-
+-	return res;
+-}
+ 
+ /*
+  *	Determine the packet's protocol ID. The rule here is that we 
+@@ -176,7 +163,7 @@ __be16 eth_type_trans(struct sk_buff *sk
+ 	eth = eth_hdr(skb);
+ 	
+ 	if (*eth->h_dest&1) {
+-		if (!compare_eth_addr(eth->h_dest, dev->broadcast))
++		if (!compare_ether_addr(eth->h_dest, dev->broadcast))
+ 			skb->pkt_type = PACKET_BROADCAST;
+ 		else
+ 			skb->pkt_type = PACKET_MULTICAST;
+@@ -191,7 +178,7 @@ __be16 eth_type_trans(struct sk_buff *sk
+ 	 */
+ 	 
+ 	else if(1 /*dev->flags&IFF_PROMISC*/) {
+-		if (unlikely(compare_eth_addr(eth->h_dest, dev->dev_addr)))
++		if (unlikely(compare_ether_addr(eth->h_dest, dev->dev_addr)))
+ 			skb->pkt_type = PACKET_OTHERHOST;
+ 	}
+ 	
+diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile
+--- a/net/ieee80211/Makefile
++++ b/net/ieee80211/Makefile
+@@ -7,5 +7,6 @@ ieee80211-objs := \
+ 	ieee80211_module.o \
+ 	ieee80211_tx.o \
+ 	ieee80211_rx.o \
+-	ieee80211_wx.o
++	ieee80211_wx.o \
++	ieee80211_geo.o
+ 
+diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
+--- a/net/ieee80211/ieee80211_crypt.c
++++ b/net/ieee80211/ieee80211_crypt.c
+@@ -41,6 +41,12 @@ void ieee80211_crypt_deinit_entries(stru
+ {
+ 	struct list_head *ptr, *n;
+ 	struct ieee80211_crypt_data *entry;
++	unsigned long flags;
++
++	spin_lock_irqsave(&ieee->lock, flags);
++
++	if (list_empty(&ieee->crypt_deinit_list))
++		goto unlock;
+ 
+ 	for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
+ 	     ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
+@@ -57,6 +63,18 @@ void ieee80211_crypt_deinit_entries(stru
+ 		}
+ 		kfree(entry);
+ 	}
++      unlock:
++	spin_unlock_irqrestore(&ieee->lock, flags);
++}
++
++/* After this, crypt_deinit_list won't accept new members */
++void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&ieee->lock, flags);
++	ieee->crypt_quiesced = 1;
++	spin_unlock_irqrestore(&ieee->lock, flags);
+ }
+ 
+ void ieee80211_crypt_deinit_handler(unsigned long data)
+@@ -64,16 +82,16 @@ void ieee80211_crypt_deinit_handler(unsi
+ 	struct ieee80211_device *ieee = (struct ieee80211_device *)data;
+ 	unsigned long flags;
+ 
+-	spin_lock_irqsave(&ieee->lock, flags);
+ 	ieee80211_crypt_deinit_entries(ieee, 0);
+-	if (!list_empty(&ieee->crypt_deinit_list)) {
++
++	spin_lock_irqsave(&ieee->lock, flags);
++	if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
+ 		printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
+ 		       "deletion list\n", ieee->dev->name);
+ 		ieee->crypt_deinit_timer.expires = jiffies + HZ;
+ 		add_timer(&ieee->crypt_deinit_timer);
+ 	}
+ 	spin_unlock_irqrestore(&ieee->lock, flags);
+-
+ }
+ 
+ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
+@@ -93,10 +111,12 @@ void ieee80211_crypt_delayed_deinit(stru
+ 	 * locking. */
+ 
+ 	spin_lock_irqsave(&ieee->lock, flags);
+-	list_add(&tmp->list, &ieee->crypt_deinit_list);
+-	if (!timer_pending(&ieee->crypt_deinit_timer)) {
+-		ieee->crypt_deinit_timer.expires = jiffies + HZ;
+-		add_timer(&ieee->crypt_deinit_timer);
++	if (!ieee->crypt_quiesced) {
++		list_add(&tmp->list, &ieee->crypt_deinit_list);
++		if (!timer_pending(&ieee->crypt_deinit_timer)) {
++			ieee->crypt_deinit_timer.expires = jiffies + HZ;
++			add_timer(&ieee->crypt_deinit_timer);
++		}
+ 	}
+ 	spin_unlock_irqrestore(&ieee->lock, flags);
+ }
+@@ -191,18 +211,18 @@ static void ieee80211_crypt_null_deinit(
+ }
+ 
+ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
+-	.name			= "NULL",
+-	.init			= ieee80211_crypt_null_init,
+-	.deinit			= ieee80211_crypt_null_deinit,
+-	.encrypt_mpdu		= NULL,
+-	.decrypt_mpdu		= NULL,
+-	.encrypt_msdu		= NULL,
+-	.decrypt_msdu		= NULL,
+-	.set_key		= NULL,
+-	.get_key		= NULL,
+-	.extra_prefix_len	= 0,
+-	.extra_postfix_len	= 0,
+-	.owner			= THIS_MODULE,
++	.name = "NULL",
++	.init = ieee80211_crypt_null_init,
++	.deinit = ieee80211_crypt_null_deinit,
++	.encrypt_mpdu = NULL,
++	.decrypt_mpdu = NULL,
++	.encrypt_msdu = NULL,
++	.decrypt_msdu = NULL,
++	.set_key = NULL,
++	.get_key = NULL,
++	.extra_mpdu_prefix_len = 0,
++	.extra_mpdu_postfix_len = 0,
++	.owner = THIS_MODULE,
+ };
+ 
+ static int __init ieee80211_crypto_init(void)
+@@ -249,6 +269,7 @@ static void __exit ieee80211_crypto_dein
+ EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
+ EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
+ EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
++EXPORT_SYMBOL(ieee80211_crypt_quiescing);
+ 
+ EXPORT_SYMBOL(ieee80211_register_crypto_ops);
+ EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
+diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
+--- a/net/ieee80211/ieee80211_crypt_ccmp.c
++++ b/net/ieee80211/ieee80211_crypt_ccmp.c
+@@ -119,7 +119,7 @@ static inline void xor_block(u8 * b, u8 
+ }
+ 
+ static void ccmp_init_blocks(struct crypto_tfm *tfm,
+-			     struct ieee80211_hdr *hdr,
++			     struct ieee80211_hdr_4addr *hdr,
+ 			     u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
+ {
+ 	u8 *pos, qc = 0;
+@@ -191,26 +191,18 @@ static void ccmp_init_blocks(struct cryp
+ 	ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
+ }
+ 
+-static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
++static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv)
+ {
+ 	struct ieee80211_ccmp_data *key = priv;
+-	int data_len, i, blocks, last, len;
+-	u8 *pos, *mic;
+-	struct ieee80211_hdr *hdr;
+-	u8 *b0 = key->tx_b0;
+-	u8 *b = key->tx_b;
+-	u8 *e = key->tx_e;
+-	u8 *s0 = key->tx_s0;
++	int i;
++	u8 *pos;
+ 
+-	if (skb_headroom(skb) < CCMP_HDR_LEN ||
+-	    skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
++	if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len)
+ 		return -1;
+ 
+-	data_len = skb->len - hdr_len;
+ 	pos = skb_push(skb, CCMP_HDR_LEN);
+ 	memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
+ 	pos += hdr_len;
+-	mic = skb_put(skb, CCMP_MIC_LEN);
+ 
+ 	i = CCMP_PN_LEN - 1;
+ 	while (i >= 0) {
+@@ -229,7 +221,31 @@ static int ieee80211_ccmp_encrypt(struct
+ 	*pos++ = key->tx_pn[1];
+ 	*pos++ = key->tx_pn[0];
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
++	return CCMP_HDR_LEN;
++}
++
++static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
++{
++	struct ieee80211_ccmp_data *key = priv;
++	int data_len, i, blocks, last, len;
++	u8 *pos, *mic;
++	struct ieee80211_hdr_4addr *hdr;
++	u8 *b0 = key->tx_b0;
++	u8 *b = key->tx_b;
++	u8 *e = key->tx_e;
++	u8 *s0 = key->tx_s0;
++
++	if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
++		return -1;
++
++	data_len = skb->len - hdr_len;
++	len = ieee80211_ccmp_hdr(skb, hdr_len, priv);
++	if (len < 0)
++		return -1;
++
++	pos = skb->data + hdr_len + CCMP_HDR_LEN;
++	mic = skb_put(skb, CCMP_MIC_LEN);
++	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+ 	ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
+ 
+ 	blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
+@@ -258,7 +274,7 @@ static int ieee80211_ccmp_decrypt(struct
+ {
+ 	struct ieee80211_ccmp_data *key = priv;
+ 	u8 keyidx, *pos;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u8 *b0 = key->rx_b0;
+ 	u8 *b = key->rx_b;
+ 	u8 *a = key->rx_a;
+@@ -272,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct
+ 		return -1;
+ 	}
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
++	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+ 	pos = skb->data + hdr_len;
+ 	keyidx = pos[3];
+ 	if (!(keyidx & (1 << 5))) {
+@@ -426,19 +442,20 @@ static char *ieee80211_ccmp_print_stats(
+ }
+ 
+ static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
+-	.name			= "CCMP",
+-	.init			= ieee80211_ccmp_init,
+-	.deinit			= ieee80211_ccmp_deinit,
+-	.encrypt_mpdu		= ieee80211_ccmp_encrypt,
+-	.decrypt_mpdu		= ieee80211_ccmp_decrypt,
+-	.encrypt_msdu		= NULL,
+-	.decrypt_msdu		= NULL,
+-	.set_key		= ieee80211_ccmp_set_key,
+-	.get_key		= ieee80211_ccmp_get_key,
+-	.print_stats		= ieee80211_ccmp_print_stats,
+-	.extra_prefix_len	= CCMP_HDR_LEN,
+-	.extra_postfix_len	= CCMP_MIC_LEN,
+-	.owner			= THIS_MODULE,
++	.name = "CCMP",
++	.init = ieee80211_ccmp_init,
++	.deinit = ieee80211_ccmp_deinit,
++	.build_iv = ieee80211_ccmp_hdr,
++	.encrypt_mpdu = ieee80211_ccmp_encrypt,
++	.decrypt_mpdu = ieee80211_ccmp_decrypt,
++	.encrypt_msdu = NULL,
++	.decrypt_msdu = NULL,
++	.set_key = ieee80211_ccmp_set_key,
++	.get_key = ieee80211_ccmp_get_key,
++	.print_stats = ieee80211_ccmp_print_stats,
++	.extra_mpdu_prefix_len = CCMP_HDR_LEN,
++	.extra_mpdu_postfix_len = CCMP_MIC_LEN,
++	.owner = THIS_MODULE,
+ };
+ 
+ static int __init ieee80211_crypto_ccmp_init(void)
+diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
+--- a/net/ieee80211/ieee80211_crypt_tkip.c
++++ b/net/ieee80211/ieee80211_crypt_tkip.c
+@@ -59,8 +59,24 @@ struct ieee80211_tkip_data {
+ 
+ 	/* scratch buffers for virt_to_page() (crypto API) */
+ 	u8 rx_hdr[16], tx_hdr[16];
++
++	unsigned long flags;
+ };
+ 
++static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv)
++{
++	struct ieee80211_tkip_data *_priv = priv;
++	unsigned long old_flags = _priv->flags;
++	_priv->flags = flags;
++	return old_flags;
++}
++
++static unsigned long ieee80211_tkip_get_flags(void *priv)
++{
++	struct ieee80211_tkip_data *_priv = priv;
++	return _priv->flags;
++}
++
+ static void *ieee80211_tkip_init(int key_idx)
+ {
+ 	struct ieee80211_tkip_data *priv;
+@@ -69,6 +85,7 @@ static void *ieee80211_tkip_init(int key
+ 	if (priv == NULL)
+ 		goto fail;
+ 	memset(priv, 0, sizeof(*priv));
++
+ 	priv->key_idx = key_idx;
+ 
+ 	priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
+@@ -255,25 +272,27 @@ static void tkip_mixing_phase2(u8 * WEPS
+ #endif
+ }
+ 
+-static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
++static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv)
+ {
+ 	struct ieee80211_tkip_data *tkey = priv;
+ 	int len;
+-	u8 rc4key[16], *pos, *icv;
+-	struct ieee80211_hdr *hdr;
++	u8 *rc4key, *pos, *icv;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u32 crc;
+-	struct scatterlist sg;
+ 
+-	if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
+-	    skb->len < hdr_len)
+-		return -1;
++	hdr = (struct ieee80211_hdr_4addr *)skb->data;
++
++	if (skb_headroom(skb) < 8 || skb->len < hdr_len)
++		return NULL;
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
+ 	if (!tkey->tx_phase1_done) {
+ 		tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
+ 				   tkey->tx_iv32);
+ 		tkey->tx_phase1_done = 1;
+ 	}
++	rc4key = kmalloc(16, GFP_ATOMIC);
++	if (!rc4key)
++		return NULL;
+ 	tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
+ 
+ 	len = skb->len - hdr_len;
+@@ -282,9 +301,9 @@ static int ieee80211_tkip_encrypt(struct
+ 	pos += hdr_len;
+ 	icv = skb_put(skb, 4);
+ 
+-	*pos++ = rc4key[0];
+-	*pos++ = rc4key[1];
+-	*pos++ = rc4key[2];
++	*pos++ = *rc4key;
++	*pos++ = *(rc4key + 1);
++	*pos++ = *(rc4key + 2);
+ 	*pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
+ 	*pos++ = tkey->tx_iv32 & 0xff;
+ 	*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
+@@ -297,6 +316,38 @@ static int ieee80211_tkip_encrypt(struct
+ 	icv[2] = crc >> 16;
+ 	icv[3] = crc >> 24;
+ 
++	return rc4key;
++}
++
++static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
++{
++	struct ieee80211_tkip_data *tkey = priv;
++	int len;
++	const u8 *rc4key;
++	u8 *pos;
++	struct scatterlist sg;
++
++	if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
++		if (net_ratelimit()) {
++			struct ieee80211_hdr_4addr *hdr =
++			    (struct ieee80211_hdr_4addr *)skb->data;
++			printk(KERN_DEBUG "TKIP countermeasures: dropped "
++			       "TX packet to " MAC_FMT "\n",
++			       MAC_ARG(hdr->addr1));
++		}
++		return -1;
++	}
++
++	if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
++		return -1;
++
++	len = skb->len - hdr_len;
++	pos = skb->data + hdr_len;
++
++	rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv);
++	if (!rc4key)
++		return -1;
++
+ 	crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
+ 	sg.page = virt_to_page(pos);
+ 	sg.offset = offset_in_page(pos);
+@@ -319,16 +370,26 @@ static int ieee80211_tkip_decrypt(struct
+ 	u8 keyidx, *pos;
+ 	u32 iv32;
+ 	u16 iv16;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	u8 icv[4];
+ 	u32 crc;
+ 	struct scatterlist sg;
+ 	int plen;
+ 
++	hdr = (struct ieee80211_hdr_4addr *)skb->data;
++
++	if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
++		if (net_ratelimit()) {
++			printk(KERN_DEBUG "TKIP countermeasures: dropped "
++			       "received packet from " MAC_FMT "\n",
++			       MAC_ARG(hdr->addr2));
++		}
++		return -1;
++	}
++
+ 	if (skb->len < hdr_len + 8 + 4)
+ 		return -1;
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
+ 	pos = skb->data + hdr_len;
+ 	keyidx = pos[3];
+ 	if (!(keyidx & (1 << 5))) {
+@@ -441,9 +502,9 @@ static int michael_mic(struct ieee80211_
+ 
+ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
+ {
+-	struct ieee80211_hdr *hdr11;
++	struct ieee80211_hdr_4addr *hdr11;
+ 
+-	hdr11 = (struct ieee80211_hdr *)skb->data;
++	hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
+ 	switch (le16_to_cpu(hdr11->frame_ctl) &
+ 		(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
+ 	case IEEE80211_FCTL_TODS:
+@@ -490,9 +551,9 @@ static int ieee80211_michael_mic_add(str
+ 	return 0;
+ }
+ 
+-#if WIRELESS_EXT >= 18
+ static void ieee80211_michael_mic_failure(struct net_device *dev,
+-					  struct ieee80211_hdr *hdr, int keyidx)
++					  struct ieee80211_hdr_4addr *hdr,
++					  int keyidx)
+ {
+ 	union iwreq_data wrqu;
+ 	struct iw_michaelmicfailure ev;
+@@ -510,28 +571,6 @@ static void ieee80211_michael_mic_failur
+ 	wrqu.data.length = sizeof(ev);
+ 	wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
+ }
+-#elif WIRELESS_EXT >= 15
+-static void ieee80211_michael_mic_failure(struct net_device *dev,
+-					  struct ieee80211_hdr *hdr, int keyidx)
+-{
+-	union iwreq_data wrqu;
+-	char buf[128];
+-
+-	/* TODO: needed parameters: count, keyid, key type, TSC */
+-	sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
+-		MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
+-		MAC_ARG(hdr->addr2));
+-	memset(&wrqu, 0, sizeof(wrqu));
+-	wrqu.data.length = strlen(buf);
+-	wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
+-}
+-#else				/* WIRELESS_EXT >= 15 */
+-static inline void ieee80211_michael_mic_failure(struct net_device *dev,
+-						 struct ieee80211_hdr *hdr,
+-						 int keyidx)
+-{
+-}
+-#endif				/* WIRELESS_EXT >= 15 */
+ 
+ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
+ 					int hdr_len, void *priv)
+@@ -547,8 +586,8 @@ static int ieee80211_michael_mic_verify(
+ 			skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
+ 		return -1;
+ 	if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
+-		struct ieee80211_hdr *hdr;
+-		hdr = (struct ieee80211_hdr *)skb->data;
++		struct ieee80211_hdr_4addr *hdr;
++		hdr = (struct ieee80211_hdr_4addr *)skb->data;
+ 		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
+ 		       "MSDU from " MAC_FMT " keyidx=%d\n",
+ 		       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+@@ -654,19 +693,22 @@ static char *ieee80211_tkip_print_stats(
+ }
+ 
+ static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
+-	.name			= "TKIP",
+-	.init			= ieee80211_tkip_init,
+-	.deinit			= ieee80211_tkip_deinit,
+-	.encrypt_mpdu		= ieee80211_tkip_encrypt,
+-	.decrypt_mpdu		= ieee80211_tkip_decrypt,
+-	.encrypt_msdu		= ieee80211_michael_mic_add,
+-	.decrypt_msdu		= ieee80211_michael_mic_verify,
+-	.set_key		= ieee80211_tkip_set_key,
+-	.get_key		= ieee80211_tkip_get_key,
+-	.print_stats		= ieee80211_tkip_print_stats,
+-	.extra_prefix_len	= 4 + 4,	/* IV + ExtIV */
+-	.extra_postfix_len	= 8 + 4,	/* MIC + ICV */
+-	.owner			= THIS_MODULE,
++	.name = "TKIP",
++	.init = ieee80211_tkip_init,
++	.deinit = ieee80211_tkip_deinit,
++	.encrypt_mpdu = ieee80211_tkip_encrypt,
++	.decrypt_mpdu = ieee80211_tkip_decrypt,
++	.encrypt_msdu = ieee80211_michael_mic_add,
++	.decrypt_msdu = ieee80211_michael_mic_verify,
++	.set_key = ieee80211_tkip_set_key,
++	.get_key = ieee80211_tkip_get_key,
++	.print_stats = ieee80211_tkip_print_stats,
++	.extra_mpdu_prefix_len = 4 + 4,	/* IV + ExtIV */
++	.extra_mpdu_postfix_len = 4,	/* ICV */
++	.extra_msdu_postfix_len = 8,	/* MIC */
++	.get_flags = ieee80211_tkip_get_flags,
++	.set_flags = ieee80211_tkip_set_flags,
++	.owner = THIS_MODULE,
+ };
+ 
+ static int __init ieee80211_crypto_tkip_init(void)
+diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
+--- a/net/ieee80211/ieee80211_crypt_wep.c
++++ b/net/ieee80211/ieee80211_crypt_wep.c
+@@ -229,19 +229,19 @@ static char *prism2_wep_print_stats(char
+ }
+ 
+ static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
+-	.name			= "WEP",
+-	.init			= prism2_wep_init,
+-	.deinit			= prism2_wep_deinit,
+-	.encrypt_mpdu		= prism2_wep_encrypt,
+-	.decrypt_mpdu		= prism2_wep_decrypt,
+-	.encrypt_msdu		= NULL,
+-	.decrypt_msdu		= NULL,
+-	.set_key		= prism2_wep_set_key,
+-	.get_key		= prism2_wep_get_key,
+-	.print_stats		= prism2_wep_print_stats,
+-	.extra_prefix_len	= 4,	/* IV */
+-	.extra_postfix_len	= 4,	/* ICV */
+-	.owner			= THIS_MODULE,
++	.name = "WEP",
++	.init = prism2_wep_init,
++	.deinit = prism2_wep_deinit,
++	.encrypt_mpdu = prism2_wep_encrypt,
++	.decrypt_mpdu = prism2_wep_decrypt,
++	.encrypt_msdu = NULL,
++	.decrypt_msdu = NULL,
++	.set_key = prism2_wep_set_key,
++	.get_key = prism2_wep_get_key,
++	.print_stats = prism2_wep_print_stats,
++	.extra_mpdu_prefix_len = 4,	/* IV */
++	.extra_mpdu_postfix_len = 4,	/* ICV */
++	.owner = THIS_MODULE,
+ };
+ 
+ static int __init ieee80211_crypto_wep_init(void)
+diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c
+new file mode 100644
+--- /dev/null
++++ b/net/ieee80211/ieee80211_geo.c
+@@ -0,0 +1,141 @@
++/******************************************************************************
++
++  Copyright(c) 2005 Intel Corporation. All rights reserved.
++
++  This program is free software; you can redistribute it and/or modify it
++  under the terms of version 2 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.
++
++  The full GNU General Public License is included in this distribution in the
++  file called LICENSE.
++
++  Contact Information:
++  James P. Ketrenos <ipw2100-admin at linux.intel.com>
++  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
++
++******************************************************************************/
++#include <linux/compiler.h>
++#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/if_arp.h>
++#include <linux/in6.h>
++#include <linux/in.h>
++#include <linux/ip.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/netdevice.h>
++#include <linux/proc_fs.h>
++#include <linux/skbuff.h>
++#include <linux/slab.h>
++#include <linux/tcp.h>
++#include <linux/types.h>
++#include <linux/version.h>
++#include <linux/wireless.h>
++#include <linux/etherdevice.h>
++#include <asm/uaccess.h>
++
++#include <net/ieee80211.h>
++
++int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
++{
++	int i;
++
++	/* Driver needs to initialize the geography map before using
++	 * these helper functions */
++	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
++
++	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
++		for (i = 0; i < ieee->geo.bg_channels; i++)
++			/* NOTE: If G mode is currently supported but
++			 * this is a B only channel, we don't see it
++			 * as valid. */
++			if ((ieee->geo.bg[i].channel == channel) &&
++			    (!(ieee->mode & IEEE_G) ||
++			     !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
++				return IEEE80211_24GHZ_BAND;
++
++	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
++		for (i = 0; i < ieee->geo.a_channels; i++)
++			if (ieee->geo.a[i].channel == channel)
++				return IEEE80211_52GHZ_BAND;
++
++	return 0;
++}
++
++int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
++{
++	int i;
++
++	/* Driver needs to initialize the geography map before using
++	 * these helper functions */
++	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
++
++	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
++		for (i = 0; i < ieee->geo.bg_channels; i++)
++			if (ieee->geo.bg[i].channel == channel)
++				return i;
++
++	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
++		for (i = 0; i < ieee->geo.a_channels; i++)
++			if (ieee->geo.a[i].channel == channel)
++				return i;
++
++	return -1;
++}
++
++u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
++{
++	int i;
++
++	/* Driver needs to initialize the geography map before using
++	 * these helper functions */
++	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
++
++	freq /= 100000;
++
++	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
++		for (i = 0; i < ieee->geo.bg_channels; i++)
++			if (ieee->geo.bg[i].freq == freq)
++				return ieee->geo.bg[i].channel;
++
++	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
++		for (i = 0; i < ieee->geo.a_channels; i++)
++			if (ieee->geo.a[i].freq == freq)
++				return ieee->geo.a[i].channel;
++
++	return 0;
++}
++
++int ieee80211_set_geo(struct ieee80211_device *ieee,
++		      const struct ieee80211_geo *geo)
++{
++	memcpy(ieee->geo.name, geo->name, 3);
++	ieee->geo.name[3] = '\0';
++	ieee->geo.bg_channels = geo->bg_channels;
++	ieee->geo.a_channels = geo->a_channels;
++	memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
++	       sizeof(struct ieee80211_channel));
++	memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
++	       sizeof(struct ieee80211_channel));
++	return 0;
++}
++
++const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee)
++{
++	return &ieee->geo;
++}
++
++EXPORT_SYMBOL(ieee80211_is_valid_channel);
++EXPORT_SYMBOL(ieee80211_freq_to_channel);
++EXPORT_SYMBOL(ieee80211_channel_to_index);
++EXPORT_SYMBOL(ieee80211_set_geo);
++EXPORT_SYMBOL(ieee80211_get_geo);
+diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
+--- a/net/ieee80211/ieee80211_module.c
++++ b/net/ieee80211/ieee80211_module.c
+@@ -1,6 +1,6 @@
+ /*******************************************************************************
+ 
+-  Copyright(c) 2004 Intel Corporation. All rights reserved.
++  Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
+ 
+   Portions of this file are based on the WEP enablement code provided by the
+   Host AP project hostap-drivers v0.1.3
+@@ -53,13 +53,16 @@
+ 
+ #include <net/ieee80211.h>
+ 
+-MODULE_DESCRIPTION("802.11 data/management/control stack");
+-MODULE_AUTHOR
+-    ("Copyright (C) 2004 Intel Corporation <jketreno at linux.intel.com>");
++#define DRV_DESCRIPTION "802.11 data/management/control stack"
++#define DRV_NAME        "ieee80211"
++#define DRV_VERSION	IEEE80211_VERSION
++#define DRV_COPYRIGHT   "Copyright (C) 2004-2005 Intel Corporation <jketreno at linux.intel.com>"
++
++MODULE_VERSION(DRV_VERSION);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_COPYRIGHT);
+ MODULE_LICENSE("GPL");
+ 
+-#define DRV_NAME "ieee80211"
+-
+ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
+ {
+ 	if (ieee->networks)
+@@ -126,26 +129,34 @@ struct net_device *alloc_ieee80211(int s
+ 
+ 	/* Default fragmentation threshold is maximum payload size */
+ 	ieee->fts = DEFAULT_FTS;
++	ieee->rts = DEFAULT_FTS;
+ 	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
+ 	ieee->open_wep = 1;
+ 
+ 	/* Default to enabling full open WEP with host based encrypt/decrypt */
+ 	ieee->host_encrypt = 1;
+ 	ieee->host_decrypt = 1;
++	ieee->host_mc_decrypt = 1;
++
++	/* Host fragementation in Open mode. Default is enabled.
++	 * Note: host fragmentation is always enabled if host encryption
++	 * is enabled. For cards can do hardware encryption, they must do
++	 * hardware fragmentation as well. So we don't need a variable
++	 * like host_enc_frag. */
++	ieee->host_open_frag = 1;
+ 	ieee->ieee802_1x = 1;	/* Default to supporting 802.1x */
+ 
+ 	INIT_LIST_HEAD(&ieee->crypt_deinit_list);
+ 	init_timer(&ieee->crypt_deinit_timer);
+ 	ieee->crypt_deinit_timer.data = (unsigned long)ieee;
+ 	ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
++	ieee->crypt_quiesced = 0;
+ 
+ 	spin_lock_init(&ieee->lock);
+ 
+ 	ieee->wpa_enabled = 0;
+-	ieee->tkip_countermeasures = 0;
+ 	ieee->drop_unencrypted = 0;
+ 	ieee->privacy_invoked = 0;
+-	ieee->ieee802_1x = 1;
+ 
+ 	return dev;
+ 
+@@ -161,6 +172,7 @@ void free_ieee80211(struct net_device *d
+ 
+ 	int i;
+ 
++	ieee80211_crypt_quiescing(ieee);
+ 	del_timer_sync(&ieee->crypt_deinit_timer);
+ 	ieee80211_crypt_deinit_entries(ieee, 1);
+ 
+@@ -195,38 +207,26 @@ static int show_debug_level(char *page, 
+ static int store_debug_level(struct file *file, const char __user * buffer,
+ 			     unsigned long count, void *data)
+ {
+-	char buf[] = "0x00000000";
+-	char *p = (char *)buf;
++	char buf[] = "0x00000000\n";
++	unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
+ 	unsigned long val;
+ 
+-	if (count > sizeof(buf) - 1)
+-		count = sizeof(buf) - 1;
+-
+-	if (copy_from_user(buf, buffer, count))
++	if (copy_from_user(buf, buffer, len))
+ 		return count;
+-	buf[count] = 0;
+-	/*
+-	 * what a FPOS...  What, sscanf(buf, "%i", &val) would be too
+-	 * scary?
+-	 */
+-	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
+-		p++;
+-		if (p[0] == 'x' || p[0] == 'X')
+-			p++;
+-		val = simple_strtoul(p, &p, 16);
+-	} else
+-		val = simple_strtoul(p, &p, 10);
+-	if (p == buf)
++	buf[len] = 0;
++	if (sscanf(buf, "%li", &val) != 1)
+ 		printk(KERN_INFO DRV_NAME
+ 		       ": %s is not in hex or decimal form.\n", buf);
+ 	else
+ 		ieee80211_debug_level = val;
+ 
+-	return strlen(buf);
++	return strnlen(buf, len);
+ }
++#endif				/* CONFIG_IEEE80211_DEBUG */
+ 
+ static int __init ieee80211_init(void)
+ {
++#ifdef CONFIG_IEEE80211_DEBUG
+ 	struct proc_dir_entry *e;
+ 
+ 	ieee80211_debug_level = debug;
+@@ -246,26 +246,33 @@ static int __init ieee80211_init(void)
+ 	e->read_proc = show_debug_level;
+ 	e->write_proc = store_debug_level;
+ 	e->data = NULL;
++#endif				/* CONFIG_IEEE80211_DEBUG */
++
++	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
++	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
+ 
+ 	return 0;
+ }
+ 
+ static void __exit ieee80211_exit(void)
+ {
++#ifdef CONFIG_IEEE80211_DEBUG
+ 	if (ieee80211_proc) {
+ 		remove_proc_entry("debug_level", ieee80211_proc);
+ 		remove_proc_entry(DRV_NAME, proc_net);
+ 		ieee80211_proc = NULL;
+ 	}
++#endif				/* CONFIG_IEEE80211_DEBUG */
+ }
+ 
++#ifdef CONFIG_IEEE80211_DEBUG
+ #include <linux/moduleparam.h>
+ module_param(debug, int, 0444);
+ MODULE_PARM_DESC(debug, "debug output mask");
++#endif				/* CONFIG_IEEE80211_DEBUG */
+ 
+ module_exit(ieee80211_exit);
+ module_init(ieee80211_init);
+-#endif
+ 
+ const char *escape_essid(const char *essid, u8 essid_len)
+ {
+diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
+--- a/net/ieee80211/ieee80211_rx.c
++++ b/net/ieee80211/ieee80211_rx.c
+@@ -5,7 +5,7 @@
+  * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+  * <jkmaline at cc.hut.fi>
+  * Copyright (c) 2002-2003, Jouni Malinen <jkmaline at cc.hut.fi>
+- * Copyright (c) 2004, Intel Corporation
++ * Copyright (c) 2004-2005, Intel 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
+@@ -87,7 +87,7 @@ static struct ieee80211_frag_entry *ieee
+ 
+ /* Called only as a tasklet (software IRQ) */
+ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
+-						struct ieee80211_hdr *hdr)
++						struct ieee80211_hdr_4addr *hdr)
+ {
+ 	struct sk_buff *skb = NULL;
+ 	u16 sc;
+@@ -101,7 +101,7 @@ static struct sk_buff *ieee80211_frag_ca
+ 	if (frag == 0) {
+ 		/* Reserve enough space to fit maximum frame length */
+ 		skb = dev_alloc_skb(ieee->dev->mtu +
+-				    sizeof(struct ieee80211_hdr) +
++				    sizeof(struct ieee80211_hdr_4addr) +
+ 				    8 /* LLC */  +
+ 				    2 /* alignment */  +
+ 				    8 /* WEP */  + ETH_ALEN /* WDS */ );
+@@ -138,7 +138,7 @@ static struct sk_buff *ieee80211_frag_ca
+ 
+ /* Called only as a tasklet (software IRQ) */
+ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
+-					   struct ieee80211_hdr *hdr)
++					   struct ieee80211_hdr_4addr *hdr)
+ {
+ 	u16 sc;
+ 	unsigned int seq;
+@@ -176,7 +176,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211
+ 		       ieee->dev->name);
+ 		return 0;
+ /*
+-  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
++  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
+   skb->data);*/
+ 	}
+ 
+@@ -232,13 +232,13 @@ static int ieee80211_is_eapol_frame(stru
+ {
+ 	struct net_device *dev = ieee->dev;
+ 	u16 fc, ethertype;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_3addr *hdr;
+ 	u8 *pos;
+ 
+ 	if (skb->len < 24)
+ 		return 0;
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
++	hdr = (struct ieee80211_hdr_3addr *)skb->data;
+ 	fc = le16_to_cpu(hdr->frame_ctl);
+ 
+ 	/* check that the frame is unicast frame to us */
+@@ -271,26 +271,15 @@ static inline int
+ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
+ 			   struct ieee80211_crypt_data *crypt)
+ {
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_3addr *hdr;
+ 	int res, hdrlen;
+ 
+ 	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
+ 		return 0;
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
++	hdr = (struct ieee80211_hdr_3addr *)skb->data;
+ 	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+ 
+-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
+-	if (ieee->tkip_countermeasures && strcmp(crypt->ops->name, "TKIP") == 0) {
+-		if (net_ratelimit()) {
+-			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
+-			       "received packet from " MAC_FMT "\n",
+-			       ieee->dev->name, MAC_ARG(hdr->addr2));
+-		}
+-		return -1;
+-	}
+-#endif
+-
+ 	atomic_inc(&crypt->refcnt);
+ 	res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
+ 	atomic_dec(&crypt->refcnt);
+@@ -314,13 +303,13 @@ ieee80211_rx_frame_decrypt_msdu(struct i
+ 				struct sk_buff *skb, int keyidx,
+ 				struct ieee80211_crypt_data *crypt)
+ {
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_3addr *hdr;
+ 	int res, hdrlen;
+ 
+ 	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
+ 		return 0;
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
++	hdr = (struct ieee80211_hdr_3addr *)skb->data;
+ 	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+ 
+ 	atomic_inc(&crypt->refcnt);
+@@ -343,7 +332,7 @@ int ieee80211_rx(struct ieee80211_device
+ 		 struct ieee80211_rx_stats *rx_stats)
+ {
+ 	struct net_device *dev = ieee->dev;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr_4addr *hdr;
+ 	size_t hdrlen;
+ 	u16 fc, type, stype, sc;
+ 	struct net_device_stats *stats;
+@@ -363,7 +352,7 @@ int ieee80211_rx(struct ieee80211_device
+ 	struct ieee80211_crypt_data *crypt = NULL;
+ 	int keyidx = 0;
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
++	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+ 	stats = &ieee->stats;
+ 
+ 	if (skb->len < 10) {
+@@ -378,35 +367,51 @@ int ieee80211_rx(struct ieee80211_device
+ 	frag = WLAN_GET_SEQ_FRAG(sc);
+ 	hdrlen = ieee80211_get_hdrlen(fc);
+ 
+-#ifdef NOT_YET
+-#if WIRELESS_EXT > 15
+ 	/* Put this code here so that we avoid duplicating it in all
+ 	 * Rx paths. - Jean II */
+ #ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
+ 	/* If spy monitoring on */
+-	if (iface->spy_data.spy_number > 0) {
++	if (ieee->spy_data.spy_number > 0) {
+ 		struct iw_quality wstats;
+-		wstats.level = rx_stats->signal;
+-		wstats.noise = rx_stats->noise;
+-		wstats.updated = 6;	/* No qual value */
++
++		wstats.updated = 0;
++		if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
++			wstats.level = rx_stats->rssi;
++			wstats.updated |= IW_QUAL_LEVEL_UPDATED;
++		} else
++			wstats.updated |= IW_QUAL_LEVEL_INVALID;
++
++		if (rx_stats->mask & IEEE80211_STATMASK_NOISE) {
++			wstats.noise = rx_stats->noise;
++			wstats.updated |= IW_QUAL_NOISE_UPDATED;
++		} else
++			wstats.updated |= IW_QUAL_NOISE_INVALID;
++
++		if (rx_stats->mask & IEEE80211_STATMASK_SIGNAL) {
++			wstats.qual = rx_stats->signal;
++			wstats.updated |= IW_QUAL_QUAL_UPDATED;
++		} else
++			wstats.updated |= IW_QUAL_QUAL_INVALID;
++
+ 		/* Update spy records */
+-		wireless_spy_update(dev, hdr->addr2, &wstats);
++		wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
+ 	}
+ #endif				/* IW_WIRELESS_SPY */
+-#endif				/* WIRELESS_EXT > 15 */
++
++#ifdef NOT_YET
+ 	hostap_update_rx_stats(local->ap, hdr, rx_stats);
+ #endif
+ 
+-#if WIRELESS_EXT > 15
+ 	if (ieee->iw_mode == IW_MODE_MONITOR) {
+ 		ieee80211_monitor_rx(ieee, skb, rx_stats);
+ 		stats->rx_packets++;
+ 		stats->rx_bytes += skb->len;
+ 		return 1;
+ 	}
+-#endif
+ 
+-	if (ieee->host_decrypt) {
++	if ((is_multicast_ether_addr(hdr->addr1) ||
++	     is_broadcast_ether_addr(hdr->addr2)) ? ieee->host_mc_decrypt :
++	    ieee->host_decrypt) {
+ 		int idx = 0;
+ 		if (skb->len >= hdrlen + 3)
+ 			idx = skb->data[hdrlen + 3] >> 6;
+@@ -531,6 +536,9 @@ int ieee80211_rx(struct ieee80211_device
+ 
+ 	/* Nullfunc frames may have PS-bit set, so they must be passed to
+ 	 * hostap_handle_sta_rx() before being dropped here. */
++
++	stype &= ~IEEE80211_STYPE_QOS_DATA;
++
+ 	if (stype != IEEE80211_STYPE_DATA &&
+ 	    stype != IEEE80211_STYPE_DATA_CFACK &&
+ 	    stype != IEEE80211_STYPE_DATA_CFPOLL &&
+@@ -549,7 +557,7 @@ int ieee80211_rx(struct ieee80211_device
+ 	    (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
+ 		goto rx_dropped;
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
++	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+ 
+ 	/* skb: hdr + (possibly fragmented) plaintext payload */
+ 	// PR: FIXME: hostap has additional conditions in the "if" below:
+@@ -603,7 +611,7 @@ int ieee80211_rx(struct ieee80211_device
+ 		/* this was the last fragment and the frame will be
+ 		 * delivered, so remove skb from fragment cache */
+ 		skb = frag_skb;
+-		hdr = (struct ieee80211_hdr *)skb->data;
++		hdr = (struct ieee80211_hdr_4addr *)skb->data;
+ 		ieee80211_frag_cache_invalidate(ieee, hdr);
+ 	}
+ 
+@@ -613,7 +621,7 @@ int ieee80211_rx(struct ieee80211_device
+ 	    ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
+ 		goto rx_dropped;
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
++	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+ 	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
+ 		if (		/*ieee->ieee802_1x && */
+ 			   ieee80211_is_eapol_frame(ieee, skb)) {
+@@ -755,69 +763,179 @@ int ieee80211_rx(struct ieee80211_device
+ 
+ #define MGMT_FRAME_FIXED_PART_LENGTH		0x24
+ 
+-static inline int ieee80211_is_ofdm_rate(u8 rate)
++static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
++
++/*
++* Make ther structure we read from the beacon packet has
++* the right values
++*/
++static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
++				     *info_element, int sub_type)
+ {
+-	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+-	case IEEE80211_OFDM_RATE_6MB:
+-	case IEEE80211_OFDM_RATE_9MB:
+-	case IEEE80211_OFDM_RATE_12MB:
+-	case IEEE80211_OFDM_RATE_18MB:
+-	case IEEE80211_OFDM_RATE_24MB:
+-	case IEEE80211_OFDM_RATE_36MB:
+-	case IEEE80211_OFDM_RATE_48MB:
+-	case IEEE80211_OFDM_RATE_54MB:
+-		return 1;
+-	}
++
++	if (info_element->qui_subtype != sub_type)
++		return -1;
++	if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
++		return -1;
++	if (info_element->qui_type != QOS_OUI_TYPE)
++		return -1;
++	if (info_element->version != QOS_VERSION_1)
++		return -1;
++
+ 	return 0;
+ }
+ 
+-static inline int ieee80211_network_init(struct ieee80211_device *ieee,
+-					 struct ieee80211_probe_response
+-					 *beacon,
+-					 struct ieee80211_network *network,
+-					 struct ieee80211_rx_stats *stats)
++/*
++ * Parse a QoS parameter element
++ */
++static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
++					    *element_param, struct ieee80211_info_element
++					    *info_element)
+ {
+-#ifdef CONFIG_IEEE80211_DEBUG
+-	char rates_str[64];
+-	char *p;
+-#endif
+-	struct ieee80211_info_element *info_element;
+-	u16 left;
+-	u8 i;
++	int ret = 0;
++	u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
+ 
+-	/* Pull out fixed field data */
+-	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
+-	network->capability = beacon->capability;
+-	network->last_scanned = jiffies;
+-	network->time_stamp[0] = beacon->time_stamp[0];
+-	network->time_stamp[1] = beacon->time_stamp[1];
+-	network->beacon_interval = beacon->beacon_interval;
+-	/* Where to pull this? beacon->listen_interval; */
+-	network->listen_interval = 0x0A;
+-	network->rates_len = network->rates_ex_len = 0;
+-	network->last_associate = 0;
+-	network->ssid_len = 0;
+-	network->flags = 0;
+-	network->atim_window = 0;
++	if ((info_element == NULL) || (element_param == NULL))
++		return -1;
+ 
+-	if (stats->freq == IEEE80211_52GHZ_BAND) {
+-		/* for A band (No DS info) */
+-		network->channel = stats->received_channel;
++	if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
++		memcpy(element_param->info_element.qui, info_element->data,
++		       info_element->len);
++		element_param->info_element.elementID = info_element->id;
++		element_param->info_element.length = info_element->len;
+ 	} else
+-		network->flags |= NETWORK_HAS_CCK;
++		ret = -1;
++	if (ret == 0)
++		ret = ieee80211_verify_qos_info(&element_param->info_element,
++						QOS_OUI_PARAM_SUB_TYPE);
++	return ret;
++}
+ 
+-	network->wpa_ie_len = 0;
+-	network->rsn_ie_len = 0;
++/*
++ * Parse a QoS information element
++ */
++static int ieee80211_read_qos_info_element(struct
++					   ieee80211_qos_information_element
++					   *element_info, struct ieee80211_info_element
++					   *info_element)
++{
++	int ret = 0;
++	u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
++
++	if (element_info == NULL)
++		return -1;
++	if (info_element == NULL)
++		return -1;
++
++	if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
++		memcpy(element_info->qui, info_element->data,
++		       info_element->len);
++		element_info->elementID = info_element->id;
++		element_info->length = info_element->len;
++	} else
++		ret = -1;
++
++	if (ret == 0)
++		ret = ieee80211_verify_qos_info(element_info,
++						QOS_OUI_INFO_SUB_TYPE);
++	return ret;
++}
++
++/*
++ * Write QoS parameters from the ac parameters.
++ */
++static int ieee80211_qos_convert_ac_to_parameters(struct
++						  ieee80211_qos_parameter_info
++						  *param_elm, struct
++						  ieee80211_qos_parameters
++						  *qos_param)
++{
++	int rc = 0;
++	int i;
++	struct ieee80211_qos_ac_parameter *ac_params;
++	u32 txop;
++	u8 cw_min;
++	u8 cw_max;
+ 
+-	info_element = &beacon->info_element;
+-	left = stats->len - ((void *)info_element - (void *)beacon);
+-	while (left >= sizeof(struct ieee80211_info_element_hdr)) {
+-		if (sizeof(struct ieee80211_info_element_hdr) +
+-		    info_element->len > left) {
+-			IEEE80211_DEBUG_SCAN
+-			    ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n",
+-			     info_element->len +
+-			     sizeof(struct ieee80211_info_element), left);
++	for (i = 0; i < QOS_QUEUE_NUM; i++) {
++		ac_params = &(param_elm->ac_params_record[i]);
++
++		qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F;
++		qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
++
++		cw_min = ac_params->ecw_min_max & 0x0F;
++		qos_param->cw_min[i] = (u16) ((1 << cw_min) - 1);
++
++		cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
++		qos_param->cw_max[i] = (u16) ((1 << cw_max) - 1);
++
++		qos_param->flag[i] =
++		    (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
++
++		txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
++		qos_param->tx_op_limit[i] = (u16) txop;
++	}
++	return rc;
++}
++
++/*
++ * we have a generic data element which it may contain QoS information or
++ * parameters element. check the information element length to decide
++ * which type to read
++ */
++static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
++					     *info_element,
++					     struct ieee80211_network *network)
++{
++	int rc = 0;
++	struct ieee80211_qos_parameters *qos_param = NULL;
++	struct ieee80211_qos_information_element qos_info_element;
++
++	rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
++
++	if (rc == 0) {
++		network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
++		network->flags |= NETWORK_HAS_QOS_INFORMATION;
++	} else {
++		struct ieee80211_qos_parameter_info param_element;
++
++		rc = ieee80211_read_qos_param_element(&param_element,
++						      info_element);
++		if (rc == 0) {
++			qos_param = &(network->qos_data.parameters);
++			ieee80211_qos_convert_ac_to_parameters(&param_element,
++							       qos_param);
++			network->flags |= NETWORK_HAS_QOS_PARAMETERS;
++			network->qos_data.param_count =
++			    param_element.info_element.ac_info & 0x0F;
++		}
++	}
++
++	if (rc == 0) {
++		IEEE80211_DEBUG_QOS("QoS is supported\n");
++		network->qos_data.supported = 1;
++	}
++	return rc;
++}
++
++static int ieee80211_parse_info_param(struct ieee80211_info_element
++				      *info_element, u16 length,
++				      struct ieee80211_network *network)
++{
++	u8 i;
++#ifdef CONFIG_IEEE80211_DEBUG
++	char rates_str[64];
++	char *p;
++#endif
++
++	while (length >= sizeof(*info_element)) {
++		if (sizeof(*info_element) + info_element->len > length) {
++			IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
++					     "info_element->len + 2 > left : "
++					     "info_element->len+2=%zd left=%d, id=%d.\n",
++					     info_element->len +
++					     sizeof(*info_element),
++					     length, info_element->id);
+ 			return 1;
+ 		}
+ 
+@@ -837,7 +955,7 @@ static inline int ieee80211_network_init
+ 				memset(network->ssid + network->ssid_len, 0,
+ 				       IW_ESSID_MAX_SIZE - network->ssid_len);
+ 
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
+ 					     network->ssid, network->ssid_len);
+ 			break;
+ 
+@@ -845,15 +963,14 @@ static inline int ieee80211_network_init
+ #ifdef CONFIG_IEEE80211_DEBUG
+ 			p = rates_str;
+ #endif
+-			network->rates_len =
+-			    min(info_element->len, MAX_RATES_LENGTH);
++			network->rates_len = min(info_element->len,
++						 MAX_RATES_LENGTH);
+ 			for (i = 0; i < network->rates_len; i++) {
+ 				network->rates[i] = info_element->data[i];
+ #ifdef CONFIG_IEEE80211_DEBUG
+-				p += snprintf(p,
+-					      sizeof(rates_str) - (p -
+-								   rates_str),
+-					      "%02X ", network->rates[i]);
++				p += snprintf(p, sizeof(rates_str) -
++					      (p - rates_str), "%02X ",
++					      network->rates[i]);
+ #endif
+ 				if (ieee80211_is_ofdm_rate
+ 				    (info_element->data[i])) {
+@@ -865,7 +982,7 @@ static inline int ieee80211_network_init
+ 				}
+ 			}
+ 
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
+ 					     rates_str, network->rates_len);
+ 			break;
+ 
+@@ -873,15 +990,14 @@ static inline int ieee80211_network_init
+ #ifdef CONFIG_IEEE80211_DEBUG
+ 			p = rates_str;
+ #endif
+-			network->rates_ex_len =
+-			    min(info_element->len, MAX_RATES_EX_LENGTH);
++			network->rates_ex_len = min(info_element->len,
++						    MAX_RATES_EX_LENGTH);
+ 			for (i = 0; i < network->rates_ex_len; i++) {
+ 				network->rates_ex[i] = info_element->data[i];
+ #ifdef CONFIG_IEEE80211_DEBUG
+-				p += snprintf(p,
+-					      sizeof(rates_str) - (p -
+-								   rates_str),
+-					      "%02X ", network->rates[i]);
++				p += snprintf(p, sizeof(rates_str) -
++					      (p - rates_str), "%02X ",
++					      network->rates[i]);
+ #endif
+ 				if (ieee80211_is_ofdm_rate
+ 				    (info_element->data[i])) {
+@@ -893,40 +1009,51 @@ static inline int ieee80211_network_init
+ 				}
+ 			}
+ 
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
+ 					     rates_str, network->rates_ex_len);
+ 			break;
+ 
+ 		case MFIE_TYPE_DS_SET:
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
+ 					     info_element->data[0]);
+-			if (stats->freq == IEEE80211_24GHZ_BAND)
+-				network->channel = info_element->data[0];
++			network->channel = info_element->data[0];
+ 			break;
+ 
+ 		case MFIE_TYPE_FH_SET:
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
+ 			break;
+ 
+ 		case MFIE_TYPE_CF_SET:
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
+ 			break;
+ 
+ 		case MFIE_TYPE_TIM:
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n");
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n");
++			break;
++
++		case MFIE_TYPE_ERP_INFO:
++			network->erp_value = info_element->data[0];
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
++					     network->erp_value);
+ 			break;
+ 
+ 		case MFIE_TYPE_IBSS_SET:
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
++			network->atim_window = info_element->data[0];
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
++					     network->atim_window);
+ 			break;
+ 
+ 		case MFIE_TYPE_CHALLENGE:
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
+ 			break;
+ 
+ 		case MFIE_TYPE_GENERIC:
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
+ 					     info_element->len);
++			if (!ieee80211_parse_qos_info_param_IE(info_element,
++							       network))
++				break;
++
+ 			if (info_element->len >= 4 &&
+ 			    info_element->data[0] == 0x00 &&
+ 			    info_element->data[1] == 0x50 &&
+@@ -940,7 +1067,7 @@ static inline int ieee80211_network_init
+ 			break;
+ 
+ 		case MFIE_TYPE_RSN:
+-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
++			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
+ 					     info_element->len);
+ 			network->rsn_ie_len = min(info_element->len + 2,
+ 						  MAX_WPA_IE_LEN);
+@@ -948,18 +1075,127 @@ static inline int ieee80211_network_init
+ 			       network->rsn_ie_len);
+ 			break;
+ 
++		case MFIE_TYPE_QOS_PARAMETER:
++			printk(KERN_ERR
++			       "QoS Error need to parse QOS_PARAMETER IE\n");
++			break;
++
+ 		default:
+-			IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
++			IEEE80211_DEBUG_MGMT("unsupported IE %d\n",
+ 					     info_element->id);
+ 			break;
+ 		}
+ 
+-		left -= sizeof(struct ieee80211_info_element_hdr) +
+-		    info_element->len;
+-		info_element = (struct ieee80211_info_element *)
+-		    &info_element->data[info_element->len];
++		length -= sizeof(*info_element) + info_element->len;
++		info_element =
++		    (struct ieee80211_info_element *)&info_element->
++		    data[info_element->len];
+ 	}
+ 
++	return 0;
++}
++
++static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
++				       *frame, struct ieee80211_rx_stats *stats)
++{
++	struct ieee80211_network network_resp;
++	struct ieee80211_network *network = &network_resp;
++	struct net_device *dev = ieee->dev;
++
++	network->flags = 0;
++	network->qos_data.active = 0;
++	network->qos_data.supported = 0;
++	network->qos_data.param_count = 0;
++	network->qos_data.old_param_count = 0;
++
++	//network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
++	network->atim_window = le16_to_cpu(frame->aid);
++	network->listen_interval = le16_to_cpu(frame->status);
++	memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
++	network->capability = le16_to_cpu(frame->capability);
++	network->last_scanned = jiffies;
++	network->rates_len = network->rates_ex_len = 0;
++	network->last_associate = 0;
++	network->ssid_len = 0;
++	network->erp_value =
++	    (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
++
++	if (stats->freq == IEEE80211_52GHZ_BAND) {
++		/* for A band (No DS info) */
++		network->channel = stats->received_channel;
++	} else
++		network->flags |= NETWORK_HAS_CCK;
++
++	network->wpa_ie_len = 0;
++	network->rsn_ie_len = 0;
++
++	if (ieee80211_parse_info_param
++	    (frame->info_element, stats->len - sizeof(*frame), network))
++		return 1;
++
++	network->mode = 0;
++	if (stats->freq == IEEE80211_52GHZ_BAND)
++		network->mode = IEEE_A;
++	else {
++		if (network->flags & NETWORK_HAS_OFDM)
++			network->mode |= IEEE_G;
++		if (network->flags & NETWORK_HAS_CCK)
++			network->mode |= IEEE_B;
++	}
++
++	if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
++		network->flags |= NETWORK_EMPTY_ESSID;
++
++	memcpy(&network->stats, stats, sizeof(network->stats));
++
++	if (ieee->handle_assoc_response != NULL)
++		ieee->handle_assoc_response(dev, frame, network);
++
++	return 0;
++}
++
++/***************************************************/
++
++static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
++					 *beacon,
++					 struct ieee80211_network *network,
++					 struct ieee80211_rx_stats *stats)
++{
++	network->qos_data.active = 0;
++	network->qos_data.supported = 0;
++	network->qos_data.param_count = 0;
++	network->qos_data.old_param_count = 0;
++
++	/* Pull out fixed field data */
++	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
++	network->capability = le16_to_cpu(beacon->capability);
++	network->last_scanned = jiffies;
++	network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
++	network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
++	network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
++	/* Where to pull this? beacon->listen_interval; */
++	network->listen_interval = 0x0A;
++	network->rates_len = network->rates_ex_len = 0;
++	network->last_associate = 0;
++	network->ssid_len = 0;
++	network->flags = 0;
++	network->atim_window = 0;
++	network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
++	    0x3 : 0x0;
++
++	if (stats->freq == IEEE80211_52GHZ_BAND) {
++		/* for A band (No DS info) */
++		network->channel = stats->received_channel;
++	} else
++		network->flags |= NETWORK_HAS_CCK;
++
++	network->wpa_ie_len = 0;
++	network->rsn_ie_len = 0;
++
++	if (ieee80211_parse_info_param
++	    (beacon->info_element, stats->len - sizeof(*beacon), network))
++		return 1;
++
+ 	network->mode = 0;
+ 	if (stats->freq == IEEE80211_52GHZ_BAND)
+ 		network->mode = IEEE_A;
+@@ -1002,6 +1238,9 @@ static inline int is_same_network(struct
+ static inline void update_network(struct ieee80211_network *dst,
+ 				  struct ieee80211_network *src)
+ {
++	int qos_active;
++	u8 old_param;
++
+ 	memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
+ 	dst->capability = src->capability;
+ 	memcpy(dst->rates, src->rates, src->rates_len);
+@@ -1017,6 +1256,7 @@ static inline void update_network(struct
+ 	dst->beacon_interval = src->beacon_interval;
+ 	dst->listen_interval = src->listen_interval;
+ 	dst->atim_window = src->atim_window;
++	dst->erp_value = src->erp_value;
+ 
+ 	memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
+ 	dst->wpa_ie_len = src->wpa_ie_len;
+@@ -1024,22 +1264,48 @@ static inline void update_network(struct
+ 	dst->rsn_ie_len = src->rsn_ie_len;
+ 
+ 	dst->last_scanned = jiffies;
++	qos_active = src->qos_data.active;
++	old_param = dst->qos_data.old_param_count;
++	if (dst->flags & NETWORK_HAS_QOS_MASK)
++		memcpy(&dst->qos_data, &src->qos_data,
++		       sizeof(struct ieee80211_qos_data));
++	else {
++		dst->qos_data.supported = src->qos_data.supported;
++		dst->qos_data.param_count = src->qos_data.param_count;
++	}
++
++	if (dst->qos_data.supported == 1) {
++		if (dst->ssid_len)
++			IEEE80211_DEBUG_QOS
++			    ("QoS the network %s is QoS supported\n",
++			     dst->ssid);
++		else
++			IEEE80211_DEBUG_QOS
++			    ("QoS the network is QoS supported\n");
++	}
++	dst->qos_data.active = qos_active;
++	dst->qos_data.old_param_count = old_param;
++
+ 	/* dst->last_associate is not overwritten */
+ }
+ 
++static inline int is_beacon(int fc)
++{
++	return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
++}
++
+ static inline void ieee80211_process_probe_response(struct ieee80211_device
+-						    *ieee,
+-						    struct
++						    *ieee, struct
+ 						    ieee80211_probe_response
+-						    *beacon,
+-						    struct ieee80211_rx_stats
++						    *beacon, struct ieee80211_rx_stats
+ 						    *stats)
+ {
++	struct net_device *dev = ieee->dev;
+ 	struct ieee80211_network network;
+ 	struct ieee80211_network *target;
+ 	struct ieee80211_network *oldest = NULL;
+ #ifdef CONFIG_IEEE80211_DEBUG
+-	struct ieee80211_info_element *info_element = &beacon->info_element;
++	struct ieee80211_info_element *info_element = beacon->info_element;
+ #endif
+ 	unsigned long flags;
+ 
+@@ -1070,10 +1336,10 @@ static inline void ieee80211_process_pro
+ 				     escape_essid(info_element->data,
+ 						  info_element->len),
+ 				     MAC_ARG(beacon->header.addr3),
+-				     WLAN_FC_GET_STYPE(beacon->header.
+-						       frame_ctl) ==
+-				     IEEE80211_STYPE_PROBE_RESP ?
+-				     "PROBE RESPONSE" : "BEACON");
++				     is_beacon(le16_to_cpu
++					       (beacon->header.
++						frame_ctl)) ?
++				     "BEACON" : "PROBE RESPONSE");
+ 		return;
+ 	}
+ 
+@@ -1122,10 +1388,10 @@ static inline void ieee80211_process_pro
+ 				     escape_essid(network.ssid,
+ 						  network.ssid_len),
+ 				     MAC_ARG(network.bssid),
+-				     WLAN_FC_GET_STYPE(beacon->header.
+-						       frame_ctl) ==
+-				     IEEE80211_STYPE_PROBE_RESP ?
+-				     "PROBE RESPONSE" : "BEACON");
++				     is_beacon(le16_to_cpu
++					       (beacon->header.
++						frame_ctl)) ?
++				     "BEACON" : "PROBE RESPONSE");
+ #endif
+ 		memcpy(target, &network, sizeof(*target));
+ 		list_add_tail(&target->list, &ieee->network_list);
+@@ -1134,34 +1400,60 @@ static inline void ieee80211_process_pro
+ 				     escape_essid(target->ssid,
+ 						  target->ssid_len),
+ 				     MAC_ARG(target->bssid),
+-				     WLAN_FC_GET_STYPE(beacon->header.
+-						       frame_ctl) ==
+-				     IEEE80211_STYPE_PROBE_RESP ?
+-				     "PROBE RESPONSE" : "BEACON");
++				     is_beacon(le16_to_cpu
++					       (beacon->header.
++						frame_ctl)) ?
++				     "BEACON" : "PROBE RESPONSE");
+ 		update_network(target, &network);
+ 	}
+ 
+ 	spin_unlock_irqrestore(&ieee->lock, flags);
++
++	if (is_beacon(le16_to_cpu(beacon->header.frame_ctl))) {
++		if (ieee->handle_beacon != NULL)
++			ieee->handle_beacon(dev, beacon, &network);
++	} else {
++		if (ieee->handle_probe_response != NULL)
++			ieee->handle_probe_response(dev, beacon, &network);
++	}
+ }
+ 
+ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+-		      struct ieee80211_hdr *header,
++		      struct ieee80211_hdr_4addr *header,
+ 		      struct ieee80211_rx_stats *stats)
+ {
+-	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
++	switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
+ 	case IEEE80211_STYPE_ASSOC_RESP:
+ 		IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
+-				     WLAN_FC_GET_STYPE(header->frame_ctl));
++				     WLAN_FC_GET_STYPE(le16_to_cpu
++						       (header->frame_ctl)));
++		ieee80211_handle_assoc_resp(ieee,
++					    (struct ieee80211_assoc_response *)
++					    header, stats);
+ 		break;
+ 
+ 	case IEEE80211_STYPE_REASSOC_RESP:
+ 		IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
+-				     WLAN_FC_GET_STYPE(header->frame_ctl));
++				     WLAN_FC_GET_STYPE(le16_to_cpu
++						       (header->frame_ctl)));
++		break;
++
++	case IEEE80211_STYPE_PROBE_REQ:
++		IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
++				     WLAN_FC_GET_STYPE(le16_to_cpu
++						       (header->frame_ctl)));
++
++		if (ieee->handle_probe_request != NULL)
++			ieee->handle_probe_request(ieee->dev,
++						   (struct
++						    ieee80211_probe_request *)
++						   header, stats);
+ 		break;
+ 
+ 	case IEEE80211_STYPE_PROBE_RESP:
+ 		IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
+-				     WLAN_FC_GET_STYPE(header->frame_ctl));
++				     WLAN_FC_GET_STYPE(le16_to_cpu
++						       (header->frame_ctl)));
+ 		IEEE80211_DEBUG_SCAN("Probe response\n");
+ 		ieee80211_process_probe_response(ieee,
+ 						 (struct
+@@ -1171,20 +1463,46 @@ void ieee80211_rx_mgt(struct ieee80211_d
+ 
+ 	case IEEE80211_STYPE_BEACON:
+ 		IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
+-				     WLAN_FC_GET_STYPE(header->frame_ctl));
++				     WLAN_FC_GET_STYPE(le16_to_cpu
++						       (header->frame_ctl)));
+ 		IEEE80211_DEBUG_SCAN("Beacon\n");
+ 		ieee80211_process_probe_response(ieee,
+ 						 (struct
+ 						  ieee80211_probe_response *)
+ 						 header, stats);
+ 		break;
++	case IEEE80211_STYPE_AUTH:
+ 
++		IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
++				     WLAN_FC_GET_STYPE(le16_to_cpu
++						       (header->frame_ctl)));
++
++		if (ieee->handle_auth != NULL)
++			ieee->handle_auth(ieee->dev,
++					  (struct ieee80211_auth *)header);
++		break;
++
++	case IEEE80211_STYPE_DISASSOC:
++		if (ieee->handle_disassoc != NULL)
++			ieee->handle_disassoc(ieee->dev,
++					      (struct ieee80211_disassoc *)
++					      header);
++		break;
++
++	case IEEE80211_STYPE_DEAUTH:
++		printk("DEAUTH from AP\n");
++		if (ieee->handle_deauth != NULL)
++			ieee->handle_deauth(ieee->dev, (struct ieee80211_auth *)
++					    header);
++		break;
+ 	default:
+ 		IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
+-				     WLAN_FC_GET_STYPE(header->frame_ctl));
++				     WLAN_FC_GET_STYPE(le16_to_cpu
++						       (header->frame_ctl)));
+ 		IEEE80211_WARNING("%s: Unknown management packet: %d\n",
+ 				  ieee->dev->name,
+-				  WLAN_FC_GET_STYPE(header->frame_ctl));
++				  WLAN_FC_GET_STYPE(le16_to_cpu
++						    (header->frame_ctl)));
+ 		break;
+ 	}
+ }
+diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
+--- a/net/ieee80211/ieee80211_tx.c
++++ b/net/ieee80211/ieee80211_tx.c
+@@ -1,6 +1,6 @@
+ /******************************************************************************
+ 
+-  Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
++  Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
+ 
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of version 2 of the GNU General Public License as
+@@ -128,7 +128,7 @@ payload of each frame is reduced to 492 
+ static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
+ static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
+ 
+-static inline int ieee80211_put_snap(u8 * data, u16 h_proto)
++static inline int ieee80211_copy_snap(u8 * data, u16 h_proto)
+ {
+ 	struct ieee80211_snap_hdr *snap;
+ 	u8 *oui;
+@@ -157,31 +157,14 @@ static inline int ieee80211_encrypt_frag
+ 	struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
+ 	int res;
+ 
+-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
+-	struct ieee80211_hdr *header;
+-
+-	if (ieee->tkip_countermeasures &&
+-	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
+-		header = (struct ieee80211_hdr *)frag->data;
+-		if (net_ratelimit()) {
+-			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
+-			       "TX packet to " MAC_FMT "\n",
+-			       ieee->dev->name, MAC_ARG(header->addr1));
+-		}
++	if (crypt == NULL)
+ 		return -1;
+-	}
+-#endif
++
+ 	/* To encrypt, frame format is:
+ 	 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
+-
+-	// PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
+-	/* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
+-	 * call both MSDU and MPDU encryption functions from here. */
+ 	atomic_inc(&crypt->refcnt);
+ 	res = 0;
+-	if (crypt->ops->encrypt_msdu)
+-		res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
+-	if (res == 0 && crypt->ops->encrypt_mpdu)
++	if (crypt->ops && crypt->ops->encrypt_mpdu)
+ 		res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
+ 
+ 	atomic_dec(&crypt->refcnt);
+@@ -207,7 +190,7 @@ void ieee80211_txb_free(struct ieee80211
+ }
+ 
+ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
+-						 gfp_t gfp_mask)
++						 int headroom, gfp_t gfp_mask)
+ {
+ 	struct ieee80211_txb *txb;
+ 	int i;
+@@ -221,11 +204,13 @@ static struct ieee80211_txb *ieee80211_a
+ 	txb->frag_size = txb_size;
+ 
+ 	for (i = 0; i < nr_frags; i++) {
+-		txb->fragments[i] = dev_alloc_skb(txb_size);
++		txb->fragments[i] = __dev_alloc_skb(txb_size + headroom,
++						    gfp_mask);
+ 		if (unlikely(!txb->fragments[i])) {
+ 			i--;
+ 			break;
+ 		}
++		skb_reserve(txb->fragments[i], headroom);
+ 	}
+ 	if (unlikely(i != nr_frags)) {
+ 		while (i >= 0)
+@@ -236,25 +221,31 @@ static struct ieee80211_txb *ieee80211_a
+ 	return txb;
+ }
+ 
+-/* SKBs are added to the ieee->tx_queue. */
++/* Incoming skb is converted to a txb which consists of
++ * a block of 802.11 fragment packets (stored as skbs) */
+ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct ieee80211_device *ieee = netdev_priv(dev);
+ 	struct ieee80211_txb *txb = NULL;
+-	struct ieee80211_hdr *frag_hdr;
+-	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
++	struct ieee80211_hdr_3addr *frag_hdr;
++	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
++	    rts_required;
+ 	unsigned long flags;
+ 	struct net_device_stats *stats = &ieee->stats;
+-	int ether_type, encrypt;
++	int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
+ 	int bytes, fc, hdr_len;
+ 	struct sk_buff *skb_frag;
+-	struct ieee80211_hdr header = {	/* Ensure zero initialized */
++	struct ieee80211_hdr_3addr header = {	/* Ensure zero initialized */
+ 		.duration_id = 0,
+ 		.seq_ctl = 0
+ 	};
+ 	u8 dest[ETH_ALEN], src[ETH_ALEN];
+-
+ 	struct ieee80211_crypt_data *crypt;
++	int priority = skb->priority;
++	int snapped = 0;
++
++	if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))
++		return NETDEV_TX_BUSY;
+ 
+ 	spin_lock_irqsave(&ieee->lock, flags);
+ 
+@@ -276,7 +267,11 @@ int ieee80211_xmit(struct sk_buff *skb, 
+ 	crypt = ieee->crypt[ieee->tx_keyidx];
+ 
+ 	encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
+-	    ieee->host_encrypt && crypt && crypt->ops;
++	    ieee->sec.encrypt;
++
++	host_encrypt = ieee->host_encrypt && encrypt && crypt;
++	host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
++	host_build_iv = ieee->host_build_iv && encrypt && crypt;
+ 
+ 	if (!encrypt && ieee->ieee802_1x &&
+ 	    ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
+@@ -285,8 +280,8 @@ int ieee80211_xmit(struct sk_buff *skb, 
+ 	}
+ 
+ 	/* Save source and destination addresses */
+-	memcpy(&dest, skb->data, ETH_ALEN);
+-	memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN);
++	memcpy(dest, skb->data, ETH_ALEN);
++	memcpy(src, skb->data + ETH_ALEN, ETH_ALEN);
+ 
+ 	/* Advance the SKB to the start of the payload */
+ 	skb_pull(skb, sizeof(struct ethhdr));
+@@ -294,7 +289,7 @@ int ieee80211_xmit(struct sk_buff *skb, 
+ 	/* Determine total amount of storage required for TXB packets */
+ 	bytes = skb->len + SNAP_SIZE + sizeof(u16);
+ 
+-	if (encrypt)
++	if (host_encrypt)
+ 		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
+ 		    IEEE80211_FCTL_PROTECTED;
+ 	else
+@@ -302,70 +297,144 @@ int ieee80211_xmit(struct sk_buff *skb, 
+ 
+ 	if (ieee->iw_mode == IW_MODE_INFRA) {
+ 		fc |= IEEE80211_FCTL_TODS;
+-		/* To DS: Addr1 = BSSID, Addr2 = SA,
+-		   Addr3 = DA */
+-		memcpy(&header.addr1, ieee->bssid, ETH_ALEN);
+-		memcpy(&header.addr2, &src, ETH_ALEN);
+-		memcpy(&header.addr3, &dest, ETH_ALEN);
++		/* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
++		memcpy(header.addr1, ieee->bssid, ETH_ALEN);
++		memcpy(header.addr2, src, ETH_ALEN);
++		memcpy(header.addr3, dest, ETH_ALEN);
+ 	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
+-		/* not From/To DS: Addr1 = DA, Addr2 = SA,
+-		   Addr3 = BSSID */
+-		memcpy(&header.addr1, dest, ETH_ALEN);
+-		memcpy(&header.addr2, src, ETH_ALEN);
+-		memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
++		/* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
++		memcpy(header.addr1, dest, ETH_ALEN);
++		memcpy(header.addr2, src, ETH_ALEN);
++		memcpy(header.addr3, ieee->bssid, ETH_ALEN);
+ 	}
+ 	header.frame_ctl = cpu_to_le16(fc);
+ 	hdr_len = IEEE80211_3ADDR_LEN;
+ 
+-	/* Determine fragmentation size based on destination (multicast
+-	 * and broadcast are not fragmented) */
+-	if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest))
+-		frag_size = MAX_FRAG_THRESHOLD;
+-	else
+-		frag_size = ieee->fts;
+-
+-	/* Determine amount of payload per fragment.  Regardless of if
+-	 * this stack is providing the full 802.11 header, one will
+-	 * eventually be affixed to this fragment -- so we must account for
+-	 * it when determining the amount of payload space. */
+-	bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
+-	if (ieee->config &
+-	    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+-		bytes_per_frag -= IEEE80211_FCS_LEN;
++	/* Encrypt msdu first on the whole data packet. */
++	if ((host_encrypt || host_encrypt_msdu) &&
++	    crypt && crypt->ops && crypt->ops->encrypt_msdu) {
++		int res = 0;
++		int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
++		    crypt->ops->extra_msdu_postfix_len;
++		struct sk_buff *skb_new = dev_alloc_skb(len);
++
++		if (unlikely(!skb_new))
++			goto failed;
++
++		skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
++		memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
++		snapped = 1;
++		ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
++				    ether_type);
++		memcpy(skb_put(skb_new, skb->len), skb->data, skb->len);
++		res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
++		if (res < 0) {
++			IEEE80211_ERROR("msdu encryption failed\n");
++			dev_kfree_skb_any(skb_new);
++			goto failed;
++		}
++		dev_kfree_skb_any(skb);
++		skb = skb_new;
++		bytes += crypt->ops->extra_msdu_prefix_len +
++		    crypt->ops->extra_msdu_postfix_len;
++		skb_pull(skb, hdr_len);
++	}
++
++	if (host_encrypt || ieee->host_open_frag) {
++		/* Determine fragmentation size based on destination (multicast
++		 * and broadcast are not fragmented) */
++		if (is_multicast_ether_addr(dest) ||
++		    is_broadcast_ether_addr(dest))
++			frag_size = MAX_FRAG_THRESHOLD;
++		else
++			frag_size = ieee->fts;
++
++		/* Determine amount of payload per fragment.  Regardless of if
++		 * this stack is providing the full 802.11 header, one will
++		 * eventually be affixed to this fragment -- so we must account
++		 * for it when determining the amount of payload space. */
++		bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
++		if (ieee->config &
++		    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
++			bytes_per_frag -= IEEE80211_FCS_LEN;
+ 
+-	/* Each fragment may need to have room for encryptiong pre/postfix */
+-	if (encrypt)
+-		bytes_per_frag -= crypt->ops->extra_prefix_len +
+-		    crypt->ops->extra_postfix_len;
+-
+-	/* Number of fragments is the total bytes_per_frag /
+-	 * payload_per_fragment */
+-	nr_frags = bytes / bytes_per_frag;
+-	bytes_last_frag = bytes % bytes_per_frag;
+-	if (bytes_last_frag)
++		/* Each fragment may need to have room for encryptiong
++		 * pre/postfix */
++		if (host_encrypt)
++			bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
++			    crypt->ops->extra_mpdu_postfix_len;
++
++		/* Number of fragments is the total
++		 * bytes_per_frag / payload_per_fragment */
++		nr_frags = bytes / bytes_per_frag;
++		bytes_last_frag = bytes % bytes_per_frag;
++		if (bytes_last_frag)
++			nr_frags++;
++		else
++			bytes_last_frag = bytes_per_frag;
++	} else {
++		nr_frags = 1;
++		bytes_per_frag = bytes_last_frag = bytes;
++		frag_size = bytes + IEEE80211_3ADDR_LEN;
++	}
++
++	rts_required = (frag_size > ieee->rts
++			&& ieee->config & CFG_IEEE80211_RTS);
++	if (rts_required)
+ 		nr_frags++;
+-	else
+-		bytes_last_frag = bytes_per_frag;
+ 
+ 	/* When we allocate the TXB we allocate enough space for the reserve
+ 	 * and full fragment bytes (bytes_per_frag doesn't include prefix,
+ 	 * postfix, header, FCS, etc.) */
+-	txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
++	txb = ieee80211_alloc_txb(nr_frags, frag_size,
++				  ieee->tx_headroom, GFP_ATOMIC);
+ 	if (unlikely(!txb)) {
+ 		printk(KERN_WARNING "%s: Could not allocate TXB\n",
+ 		       ieee->dev->name);
+ 		goto failed;
+ 	}
+ 	txb->encrypted = encrypt;
+-	txb->payload_size = bytes;
++	if (host_encrypt)
++		txb->payload_size = frag_size * (nr_frags - 1) +
++		    bytes_last_frag;
++	else
++		txb->payload_size = bytes;
+ 
+-	for (i = 0; i < nr_frags; i++) {
++	if (rts_required) {
++		skb_frag = txb->fragments[0];
++		frag_hdr =
++		    (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
++
++		/*
++		 * Set header frame_ctl to the RTS.
++		 */
++		header.frame_ctl =
++		    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
++		memcpy(frag_hdr, &header, hdr_len);
++
++		/*
++		 * Restore header frame_ctl to the original data setting.
++		 */
++		header.frame_ctl = cpu_to_le16(fc);
++
++		if (ieee->config &
++		    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
++			skb_put(skb_frag, 4);
++
++		txb->rts_included = 1;
++		i = 1;
++	} else
++		i = 0;
++
++	for (; i < nr_frags; i++) {
+ 		skb_frag = txb->fragments[i];
+ 
+-		if (encrypt)
+-			skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
++		if (host_encrypt || host_build_iv)
++			skb_reserve(skb_frag,
++				    crypt->ops->extra_mpdu_prefix_len);
+ 
+-		frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
++		frag_hdr =
++		    (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
+ 		memcpy(frag_hdr, &header, hdr_len);
+ 
+ 		/* If this is not the last fragment, then add the MOREFRAGS
+@@ -379,11 +448,10 @@ int ieee80211_xmit(struct sk_buff *skb, 
+ 			bytes = bytes_last_frag;
+ 		}
+ 
+-		/* Put a SNAP header on the first fragment */
+-		if (i == 0) {
+-			ieee80211_put_snap(skb_put
+-					   (skb_frag, SNAP_SIZE + sizeof(u16)),
+-					   ether_type);
++		if (i == 0 && !snapped) {
++			ieee80211_copy_snap(skb_put
++					    (skb_frag, SNAP_SIZE + sizeof(u16)),
++					    ether_type);
+ 			bytes -= SNAP_SIZE + sizeof(u16);
+ 		}
+ 
+@@ -394,8 +462,19 @@ int ieee80211_xmit(struct sk_buff *skb, 
+ 
+ 		/* Encryption routine will move the header forward in order
+ 		 * to insert the IV between the header and the payload */
+-		if (encrypt)
++		if (host_encrypt)
+ 			ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
++		else if (host_build_iv) {
++			struct ieee80211_crypt_data *crypt;
++
++			crypt = ieee->crypt[ieee->tx_keyidx];
++			atomic_inc(&crypt->refcnt);
++			if (crypt->ops->build_iv)
++				crypt->ops->build_iv(skb_frag, hdr_len,
++						     crypt->priv);
++			atomic_dec(&crypt->refcnt);
++		}
++
+ 		if (ieee->config &
+ 		    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+ 			skb_put(skb_frag, 4);
+@@ -407,11 +486,20 @@ int ieee80211_xmit(struct sk_buff *skb, 
+ 	dev_kfree_skb_any(skb);
+ 
+ 	if (txb) {
+-		if ((*ieee->hard_start_xmit) (txb, dev) == 0) {
++		int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
++		if (ret == 0) {
+ 			stats->tx_packets++;
+ 			stats->tx_bytes += txb->payload_size;
+ 			return 0;
+ 		}
++
++		if (ret == NETDEV_TX_BUSY) {
++			printk(KERN_ERR "%s: NETDEV_TX_BUSY returned; "
++			       "driver should report queue full via "
++			       "ieee_device->is_queue_full.\n",
++			       ieee->dev->name);
++		}
++
+ 		ieee80211_txb_free(txb);
+ 	}
+ 
+@@ -422,7 +510,72 @@ int ieee80211_xmit(struct sk_buff *skb, 
+ 	netif_stop_queue(dev);
+ 	stats->tx_errors++;
+ 	return 1;
++}
++
++/* Incoming 802.11 strucure is converted to a TXB
++ * a block of 802.11 fragment packets (stored as skbs) */
++int ieee80211_tx_frame(struct ieee80211_device *ieee,
++		       struct ieee80211_hdr *frame, int len)
++{
++	struct ieee80211_txb *txb = NULL;
++	unsigned long flags;
++	struct net_device_stats *stats = &ieee->stats;
++	struct sk_buff *skb_frag;
++	int priority = -1;
++
++	spin_lock_irqsave(&ieee->lock, flags);
+ 
++	/* If there is no driver handler to take the TXB, dont' bother
++	 * creating it... */
++	if (!ieee->hard_start_xmit) {
++		printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
++		goto success;
++	}
++
++	if (unlikely(len < 24)) {
++		printk(KERN_WARNING "%s: skb too small (%d).\n",
++		       ieee->dev->name, len);
++		goto success;
++	}
++
++	/* When we allocate the TXB we allocate enough space for the reserve
++	 * and full fragment bytes (bytes_per_frag doesn't include prefix,
++	 * postfix, header, FCS, etc.) */
++	txb = ieee80211_alloc_txb(1, len, ieee->tx_headroom, GFP_ATOMIC);
++	if (unlikely(!txb)) {
++		printk(KERN_WARNING "%s: Could not allocate TXB\n",
++		       ieee->dev->name);
++		goto failed;
++	}
++	txb->encrypted = 0;
++	txb->payload_size = len;
++
++	skb_frag = txb->fragments[0];
++
++	memcpy(skb_put(skb_frag, len), frame, len);
++
++	if (ieee->config &
++	    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
++		skb_put(skb_frag, 4);
++
++      success:
++	spin_unlock_irqrestore(&ieee->lock, flags);
++
++	if (txb) {
++		if ((*ieee->hard_start_xmit) (txb, ieee->dev, priority) == 0) {
++			stats->tx_packets++;
++			stats->tx_bytes += txb->payload_size;
++			return 0;
++		}
++		ieee80211_txb_free(txb);
++	}
++	return 0;
++
++      failed:
++	spin_unlock_irqrestore(&ieee->lock, flags);
++	stats->tx_errors++;
++	return 1;
+ }
+ 
++EXPORT_SYMBOL(ieee80211_tx_frame);
+ EXPORT_SYMBOL(ieee80211_txb_free);
+diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
+--- a/net/ieee80211/ieee80211_wx.c
++++ b/net/ieee80211/ieee80211_wx.c
+@@ -1,6 +1,6 @@
+ /******************************************************************************
+ 
+-  Copyright(c) 2004 Intel Corporation. All rights reserved.
++  Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
+ 
+   Portions of this file are based on the WEP enablement code provided by the
+   Host AP project hostap-drivers v0.1.3
+@@ -32,6 +32,7 @@
+ 
+ #include <linux/kmod.h>
+ #include <linux/module.h>
++#include <linux/jiffies.h>
+ 
+ #include <net/ieee80211.h>
+ #include <linux/wireless.h>
+@@ -140,18 +141,41 @@ static inline char *ipw2100_translate_sc
+ 		start = iwe_stream_add_point(start, stop, &iwe, custom);
+ 
+ 	/* Add quality statistics */
+-	/* TODO: Fix these values... */
+ 	iwe.cmd = IWEVQUAL;
+-	iwe.u.qual.qual = network->stats.signal;
+-	iwe.u.qual.level = network->stats.rssi;
+-	iwe.u.qual.noise = network->stats.noise;
+-	iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
+-	if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
+-		iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
+-	if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
++	iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
++	    IW_QUAL_NOISE_UPDATED;
++
++	if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) {
++		iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID |
++		    IW_QUAL_LEVEL_INVALID;
++		iwe.u.qual.qual = 0;
++		iwe.u.qual.level = 0;
++	} else {
++		iwe.u.qual.level = network->stats.rssi;
++		if (ieee->perfect_rssi == ieee->worst_rssi)
++			iwe.u.qual.qual = 100;
++		else
++			iwe.u.qual.qual =
++			    (100 *
++			     (ieee->perfect_rssi - ieee->worst_rssi) *
++			     (ieee->perfect_rssi - ieee->worst_rssi) -
++			     (ieee->perfect_rssi - network->stats.rssi) *
++			     (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
++			      62 * (ieee->perfect_rssi - network->stats.rssi))) /
++			    ((ieee->perfect_rssi - ieee->worst_rssi) *
++			     (ieee->perfect_rssi - ieee->worst_rssi));
++		if (iwe.u.qual.qual > 100)
++			iwe.u.qual.qual = 100;
++		else if (iwe.u.qual.qual < 1)
++			iwe.u.qual.qual = 0;
++	}
++
++	if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) {
+ 		iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
+-	if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
+-		iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
++		iwe.u.qual.noise = 0;
++	} else {
++		iwe.u.qual.noise = network->stats.noise;
++	}
+ 
+ 	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
+ 
+@@ -162,7 +186,7 @@ static inline char *ipw2100_translate_sc
+ 	if (iwe.u.data.length)
+ 		start = iwe_stream_add_point(start, stop, &iwe, custom);
+ 
+-	if (ieee->wpa_enabled && network->wpa_ie_len) {
++	if (network->wpa_ie_len) {
+ 		char buf[MAX_WPA_IE_LEN * 2 + 30];
+ 
+ 		u8 *p = buf;
+@@ -177,7 +201,7 @@ static inline char *ipw2100_translate_sc
+ 		start = iwe_stream_add_point(start, stop, &iwe, buf);
+ 	}
+ 
+-	if (ieee->wpa_enabled && network->rsn_ie_len) {
++	if (network->rsn_ie_len) {
+ 		char buf[MAX_WPA_IE_LEN * 2 + 30];
+ 
+ 		u8 *p = buf;
+@@ -197,8 +221,8 @@ static inline char *ipw2100_translate_sc
+ 	iwe.cmd = IWEVCUSTOM;
+ 	p = custom;
+ 	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
+-		      " Last beacon: %lums ago",
+-		      (jiffies - network->last_scanned) / (HZ / 100));
++		      " Last beacon: %dms ago",
++		      jiffies_to_msecs(jiffies - network->last_scanned));
+ 	iwe.u.data.length = p - custom;
+ 	if (iwe.u.data.length)
+ 		start = iwe_stream_add_point(start, stop, &iwe, custom);
+@@ -228,13 +252,13 @@ int ieee80211_wx_get_scan(struct ieee802
+ 			ev = ipw2100_translate_scan(ieee, ev, stop, network);
+ 		else
+ 			IEEE80211_DEBUG_SCAN("Not showing network '%s ("
+-					     MAC_FMT ")' due to age (%lums).\n",
++					     MAC_FMT ")' due to age (%dms).\n",
+ 					     escape_essid(network->ssid,
+ 							  network->ssid_len),
+ 					     MAC_ARG(network->bssid),
+-					     (jiffies -
+-					      network->last_scanned) / (HZ /
+-									100));
++					     jiffies_to_msecs(jiffies -
++							      network->
++							      last_scanned));
+ 	}
+ 
+ 	spin_unlock_irqrestore(&ieee->lock, flags);
+@@ -258,6 +282,7 @@ int ieee80211_wx_set_encode(struct ieee8
+ 	};
+ 	int i, key, key_provided, len;
+ 	struct ieee80211_crypt_data **crypt;
++	int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
+ 
+ 	IEEE80211_DEBUG_WX("SET_ENCODE\n");
+ 
+@@ -298,15 +323,17 @@ int ieee80211_wx_set_encode(struct ieee8
+ 
+ 		if (i == WEP_KEYS) {
+ 			sec.enabled = 0;
++			sec.encrypt = 0;
+ 			sec.level = SEC_LEVEL_0;
+-			sec.flags |= SEC_ENABLED | SEC_LEVEL;
++			sec.flags |= SEC_ENABLED | SEC_LEVEL | SEC_ENCRYPT;
+ 		}
+ 
+ 		goto done;
+ 	}
+ 
+ 	sec.enabled = 1;
+-	sec.flags |= SEC_ENABLED;
++	sec.encrypt = 1;
++	sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
+ 
+ 	if (*crypt != NULL && (*crypt)->ops != NULL &&
+ 	    strcmp((*crypt)->ops->name, "WEP") != 0) {
+@@ -315,7 +342,7 @@ int ieee80211_wx_set_encode(struct ieee8
+ 		ieee80211_crypt_delayed_deinit(ieee, crypt);
+ 	}
+ 
+-	if (*crypt == NULL) {
++	if (*crypt == NULL && host_crypto) {
+ 		struct ieee80211_crypt_data *new_crypt;
+ 
+ 		/* take WEP into use */
+@@ -355,49 +382,56 @@ int ieee80211_wx_set_encode(struct ieee8
+ 				   key, escape_essid(sec.keys[key], len),
+ 				   erq->length, len);
+ 		sec.key_sizes[key] = len;
+-		(*crypt)->ops->set_key(sec.keys[key], len, NULL,
+-				       (*crypt)->priv);
++		if (*crypt)
++			(*crypt)->ops->set_key(sec.keys[key], len, NULL,
++					       (*crypt)->priv);
+ 		sec.flags |= (1 << key);
+ 		/* This ensures a key will be activated if no key is
+ 		 * explicitely set */
+ 		if (key == sec.active_key)
+ 			sec.flags |= SEC_ACTIVE_KEY;
++
+ 	} else {
+-		len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
+-					     NULL, (*crypt)->priv);
+-		if (len == 0) {
+-			/* Set a default key of all 0 */
+-			IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
+-					   key);
+-			memset(sec.keys[key], 0, 13);
+-			(*crypt)->ops->set_key(sec.keys[key], 13, NULL,
+-					       (*crypt)->priv);
+-			sec.key_sizes[key] = 13;
+-			sec.flags |= (1 << key);
++		if (host_crypto) {
++			len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
++						     NULL, (*crypt)->priv);
++			if (len == 0) {
++				/* Set a default key of all 0 */
++				IEEE80211_DEBUG_WX("Setting key %d to all "
++						   "zero.\n", key);
++				memset(sec.keys[key], 0, 13);
++				(*crypt)->ops->set_key(sec.keys[key], 13, NULL,
++						       (*crypt)->priv);
++				sec.key_sizes[key] = 13;
++				sec.flags |= (1 << key);
++			}
+ 		}
+-
+ 		/* No key data - just set the default TX key index */
+ 		if (key_provided) {
+-			IEEE80211_DEBUG_WX
+-			    ("Setting key %d to default Tx key.\n", key);
++			IEEE80211_DEBUG_WX("Setting key %d to default Tx "
++					   "key.\n", key);
+ 			ieee->tx_keyidx = key;
+ 			sec.active_key = key;
+ 			sec.flags |= SEC_ACTIVE_KEY;
+ 		}
+ 	}
+-
+-      done:
+-	ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
+-	sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
+-	sec.flags |= SEC_AUTH_MODE;
+-	IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
+-			   "OPEN" : "SHARED KEY");
++	if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
++		ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
++		sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
++		    WLAN_AUTH_SHARED_KEY;
++		sec.flags |= SEC_AUTH_MODE;
++		IEEE80211_DEBUG_WX("Auth: %s\n",
++				   sec.auth_mode == WLAN_AUTH_OPEN ?
++				   "OPEN" : "SHARED KEY");
++	}
+ 
+ 	/* For now we just support WEP, so only set that security level...
+ 	 * TODO: When WPA is added this is one place that needs to change */
+ 	sec.flags |= SEC_LEVEL;
+ 	sec.level = SEC_LEVEL_1;	/* 40 and 104 bit WEP */
++	sec.encode_alg[key] = SEC_ALG_WEP;
+ 
++      done:
+ 	if (ieee->set_security)
+ 		ieee->set_security(dev, &sec);
+ 
+@@ -422,6 +456,7 @@ int ieee80211_wx_get_encode(struct ieee8
+ 	struct iw_point *erq = &(wrqu->encoding);
+ 	int len, key;
+ 	struct ieee80211_crypt_data *crypt;
++	struct ieee80211_security *sec = &ieee->sec;
+ 
+ 	IEEE80211_DEBUG_WX("GET_ENCODE\n");
+ 
+@@ -436,23 +471,16 @@ int ieee80211_wx_get_encode(struct ieee8
+ 	crypt = ieee->crypt[key];
+ 	erq->flags = key + 1;
+ 
+-	if (crypt == NULL || crypt->ops == NULL) {
++	if (!sec->enabled) {
+ 		erq->length = 0;
+ 		erq->flags |= IW_ENCODE_DISABLED;
+ 		return 0;
+ 	}
+ 
+-	if (strcmp(crypt->ops->name, "WEP") != 0) {
+-		/* only WEP is supported with wireless extensions, so just
+-		 * report that encryption is used */
+-		erq->length = 0;
+-		erq->flags |= IW_ENCODE_ENABLED;
+-		return 0;
+-	}
++	len = sec->key_sizes[key];
++	memcpy(keybuf, sec->keys[key], len);
+ 
+-	len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
+ 	erq->length = (len >= 0 ? len : 0);
+-
+ 	erq->flags |= IW_ENCODE_ENABLED;
+ 
+ 	if (ieee->open_wep)
+@@ -463,6 +491,240 @@ int ieee80211_wx_get_encode(struct ieee8
+ 	return 0;
+ }
+ 
++int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
++			       struct iw_request_info *info,
++			       union iwreq_data *wrqu, char *extra)
++{
++	struct net_device *dev = ieee->dev;
++	struct iw_point *encoding = &wrqu->encoding;
++	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
++	int i, idx, ret = 0;
++	int group_key = 0;
++	const char *alg, *module;
++	struct ieee80211_crypto_ops *ops;
++	struct ieee80211_crypt_data **crypt;
++
++	struct ieee80211_security sec = {
++		.flags = 0,
++	};
++
++	idx = encoding->flags & IW_ENCODE_INDEX;
++	if (idx) {
++		if (idx < 1 || idx > WEP_KEYS)
++			return -EINVAL;
++		idx--;
++	} else
++		idx = ieee->tx_keyidx;
++
++	if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
++		crypt = &ieee->crypt[idx];
++		group_key = 1;
++	} else {
++		if (idx != 0)
++			return -EINVAL;
++		if (ieee->iw_mode == IW_MODE_INFRA)
++			crypt = &ieee->crypt[idx];
++		else
++			return -EINVAL;
++	}
++
++	sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
++	if ((encoding->flags & IW_ENCODE_DISABLED) ||
++	    ext->alg == IW_ENCODE_ALG_NONE) {
++		if (*crypt)
++			ieee80211_crypt_delayed_deinit(ieee, crypt);
++
++		for (i = 0; i < WEP_KEYS; i++)
++			if (ieee->crypt[i] != NULL)
++				break;
++
++		if (i == WEP_KEYS) {
++			sec.enabled = 0;
++			sec.encrypt = 0;
++			sec.level = SEC_LEVEL_0;
++			sec.flags |= SEC_LEVEL;
++		}
++		goto done;
++	}
++
++	sec.enabled = 1;
++	sec.encrypt = 1;
++
++	if (group_key ? !ieee->host_mc_decrypt :
++	    !(ieee->host_encrypt || ieee->host_decrypt ||
++	      ieee->host_encrypt_msdu))
++		goto skip_host_crypt;
++
++	switch (ext->alg) {
++	case IW_ENCODE_ALG_WEP:
++		alg = "WEP";
++		module = "ieee80211_crypt_wep";
++		break;
++	case IW_ENCODE_ALG_TKIP:
++		alg = "TKIP";
++		module = "ieee80211_crypt_tkip";
++		break;
++	case IW_ENCODE_ALG_CCMP:
++		alg = "CCMP";
++		module = "ieee80211_crypt_ccmp";
++		break;
++	default:
++		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
++				   dev->name, ext->alg);
++		ret = -EINVAL;
++		goto done;
++	}
++
++	ops = ieee80211_get_crypto_ops(alg);
++	if (ops == NULL) {
++		request_module(module);
++		ops = ieee80211_get_crypto_ops(alg);
++	}
++	if (ops == NULL) {
++		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
++				   dev->name, ext->alg);
++		ret = -EINVAL;
++		goto done;
++	}
++
++	if (*crypt == NULL || (*crypt)->ops != ops) {
++		struct ieee80211_crypt_data *new_crypt;
++
++		ieee80211_crypt_delayed_deinit(ieee, crypt);
++
++		new_crypt = (struct ieee80211_crypt_data *)
++		    kmalloc(sizeof(*new_crypt), GFP_KERNEL);
++		if (new_crypt == NULL) {
++			ret = -ENOMEM;
++			goto done;
++		}
++		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
++		new_crypt->ops = ops;
++		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
++			new_crypt->priv = new_crypt->ops->init(idx);
++		if (new_crypt->priv == NULL) {
++			kfree(new_crypt);
++			ret = -EINVAL;
++			goto done;
++		}
++		*crypt = new_crypt;
++	}
++
++	if (ext->key_len > 0 && (*crypt)->ops->set_key &&
++	    (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
++				   (*crypt)->priv) < 0) {
++		IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
++		ret = -EINVAL;
++		goto done;
++	}
++
++      skip_host_crypt:
++	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
++		ieee->tx_keyidx = idx;
++		sec.active_key = idx;
++		sec.flags |= SEC_ACTIVE_KEY;
++	}
++
++	if (ext->alg != IW_ENCODE_ALG_NONE) {
++		memcpy(sec.keys[idx], ext->key, ext->key_len);
++		sec.key_sizes[idx] = ext->key_len;
++		sec.flags |= (1 << idx);
++		if (ext->alg == IW_ENCODE_ALG_WEP) {
++			sec.encode_alg[idx] = SEC_ALG_WEP;
++			sec.flags |= SEC_LEVEL;
++			sec.level = SEC_LEVEL_1;
++		} else if (ext->alg == IW_ENCODE_ALG_TKIP) {
++			sec.encode_alg[idx] = SEC_ALG_TKIP;
++			sec.flags |= SEC_LEVEL;
++			sec.level = SEC_LEVEL_2;
++		} else if (ext->alg == IW_ENCODE_ALG_CCMP) {
++			sec.encode_alg[idx] = SEC_ALG_CCMP;
++			sec.flags |= SEC_LEVEL;
++			sec.level = SEC_LEVEL_3;
++		}
++		/* Don't set sec level for group keys. */
++		if (group_key)
++			sec.flags &= ~SEC_LEVEL;
++	}
++      done:
++	if (ieee->set_security)
++		ieee->set_security(ieee->dev, &sec);
++
++	/*
++	 * Do not reset port if card is in Managed mode since resetting will
++	 * generate new IEEE 802.11 authentication which may end up in looping
++	 * with IEEE 802.1X. If your hardware requires a reset after WEP
++	 * configuration (for example... Prism2), implement the reset_port in
++	 * the callbacks structures used to initialize the 802.11 stack.
++	 */
++	if (ieee->reset_on_keychange &&
++	    ieee->iw_mode != IW_MODE_INFRA &&
++	    ieee->reset_port && ieee->reset_port(dev)) {
++		IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
++		return -EINVAL;
++	}
++
++	return ret;
++}
++
++int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
++			       struct iw_request_info *info,
++			       union iwreq_data *wrqu, char *extra)
++{
++	struct iw_point *encoding = &wrqu->encoding;
++	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
++	struct ieee80211_security *sec = &ieee->sec;
++	int idx, max_key_len;
++
++	max_key_len = encoding->length - sizeof(*ext);
++	if (max_key_len < 0)
++		return -EINVAL;
++
++	idx = encoding->flags & IW_ENCODE_INDEX;
++	if (idx) {
++		if (idx < 1 || idx > WEP_KEYS)
++			return -EINVAL;
++		idx--;
++	} else
++		idx = ieee->tx_keyidx;
++
++	if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
++		if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
++			return -EINVAL;
++
++	encoding->flags = idx + 1;
++	memset(ext, 0, sizeof(*ext));
++
++	if (!sec->enabled) {
++		ext->alg = IW_ENCODE_ALG_NONE;
++		ext->key_len = 0;
++		encoding->flags |= IW_ENCODE_DISABLED;
++	} else {
++		if (sec->encode_alg[idx] == SEC_ALG_WEP)
++			ext->alg = IW_ENCODE_ALG_WEP;
++		else if (sec->encode_alg[idx] == SEC_ALG_TKIP)
++			ext->alg = IW_ENCODE_ALG_TKIP;
++		else if (sec->encode_alg[idx] == SEC_ALG_CCMP)
++			ext->alg = IW_ENCODE_ALG_CCMP;
++		else
++			return -EINVAL;
++
++		ext->key_len = sec->key_sizes[idx];
++		memcpy(ext->key, sec->keys[idx], ext->key_len);
++		encoding->flags |= IW_ENCODE_ENABLED;
++		if (ext->key_len &&
++		    (ext->alg == IW_ENCODE_ALG_TKIP ||
++		     ext->alg == IW_ENCODE_ALG_CCMP))
++			ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
++
++	}
++
++	return 0;
++}
++
++EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
++EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
++
+ EXPORT_SYMBOL(ieee80211_wx_get_scan);
+ EXPORT_SYMBOL(ieee80211_wx_set_encode);
+ EXPORT_SYMBOL(ieee80211_wx_get_encode);
+diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
+--- a/net/ipv4/devinet.c
++++ b/net/ipv4/devinet.c
+@@ -715,6 +715,7 @@ int devinet_ioctl(unsigned int cmd, void
+ 			break;
+ 		ret = 0;
+ 		if (ifa->ifa_mask != sin->sin_addr.s_addr) {
++			u32 old_mask = ifa->ifa_mask;
+ 			inet_del_ifa(in_dev, ifap, 0);
+ 			ifa->ifa_mask = sin->sin_addr.s_addr;
+ 			ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
+@@ -728,7 +729,7 @@ int devinet_ioctl(unsigned int cmd, void
+ 			if ((dev->flags & IFF_BROADCAST) &&
+ 			    (ifa->ifa_prefixlen < 31) &&
+ 			    (ifa->ifa_broadcast ==
+-			     (ifa->ifa_local|~ifa->ifa_mask))) {
++			     (ifa->ifa_local|~old_mask))) {
+ 				ifa->ifa_broadcast = (ifa->ifa_local |
+ 						      ~sin->sin_addr.s_addr);
+ 			}
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -591,7 +591,7 @@ static int fib_inetaddr_event(struct not
+ 		break;
+ 	case NETDEV_DOWN:
+ 		fib_del_ifaddr(ifa);
+-		if (ifa->ifa_dev && ifa->ifa_dev->ifa_list == NULL) {
++		if (ifa->ifa_dev->ifa_list == NULL) {
+ 			/* Last address was deleted from this interface.
+ 			   Disable IP.
+ 			 */
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -2404,7 +2404,7 @@ static int fib_route_seq_show(struct seq
+ 		prefix = htonl(l->key);
+ 
+ 		list_for_each_entry_rcu(fa, &li->falh, fa_list) {
+-			const struct fib_info *fi = rcu_dereference(fa->fa_info);
++			const struct fib_info *fi = fa->fa_info;
+ 			unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
+ 
+ 			if (fa->fa_type == RTN_BROADCAST
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -1108,12 +1108,9 @@ void __init icmp_init(struct net_proto_f
+ 	struct inet_sock *inet;
+ 	int i;
+ 
+-	for (i = 0; i < NR_CPUS; i++) {
++	for_each_cpu(i) {
+ 		int err;
+ 
+-		if (!cpu_possible(i))
+-			continue;
+-
+ 		err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,
+ 				       &per_cpu(__icmp_socket, i));
+ 
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -275,7 +275,8 @@ int ip_output(struct sk_buff *skb)
+ {
+ 	IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
+ 
+-	if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->tso_size)
++	if (skb->len > dst_mtu(skb->dst) &&
++		!(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
+ 		return ip_fragment(skb, ip_finish_output);
+ 	else
+ 		return ip_finish_output(skb);
+@@ -688,6 +689,60 @@ csum_page(struct page *page, int offset,
+ 	return csum;
+ }
+ 
++inline int ip_ufo_append_data(struct sock *sk,
++			int getfrag(void *from, char *to, int offset, int len,
++			       int odd, struct sk_buff *skb),
++			void *from, int length, int hh_len, int fragheaderlen,
++			int transhdrlen, int mtu,unsigned int flags)
++{
++	struct sk_buff *skb;
++	int err;
++
++	/* There is support for UDP fragmentation offload by network
++	 * device, so create one single skb packet containing complete
++	 * udp datagram
++	 */
++	if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
++		skb = sock_alloc_send_skb(sk,
++			hh_len + fragheaderlen + transhdrlen + 20,
++			(flags & MSG_DONTWAIT), &err);
++
++		if (skb == NULL)
++			return err;
++
++		/* reserve space for Hardware header */
++		skb_reserve(skb, hh_len);
++
++		/* create space for UDP/IP header */
++		skb_put(skb,fragheaderlen + transhdrlen);
++
++		/* initialize network header pointer */
++		skb->nh.raw = skb->data;
++
++		/* initialize protocol header pointer */
++		skb->h.raw = skb->data + fragheaderlen;
++
++		skb->ip_summed = CHECKSUM_HW;
++		skb->csum = 0;
++		sk->sk_sndmsg_off = 0;
++	}
++
++	err = skb_append_datato_frags(sk,skb, getfrag, from,
++			       (length - transhdrlen));
++	if (!err) {
++		/* specify the length of each IP datagram fragment*/
++		skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
++		__skb_queue_tail(&sk->sk_write_queue, skb);
++
++		return 0;
++	}
++	/* There is not enough support do UFO ,
++	 * so follow normal path
++	 */
++	kfree_skb(skb);
++	return err;
++}
++
+ /*
+  *	ip_append_data() and ip_append_page() can make one large IP datagram
+  *	from many pieces of data. Each pieces will be holded on the socket
+@@ -777,6 +832,15 @@ int ip_append_data(struct sock *sk,
+ 		csummode = CHECKSUM_HW;
+ 
+ 	inet->cork.length += length;
++	if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
++			(rt->u.dst.dev->features & NETIF_F_UFO)) {
++
++		if(ip_ufo_append_data(sk, getfrag, from, length, hh_len,
++			       fragheaderlen, transhdrlen, mtu, flags))
++			goto error;
++
++		return 0;
++	}
+ 
+ 	/* So, what's going on in the loop below?
+ 	 *
+@@ -1008,14 +1072,23 @@ ssize_t	ip_append_page(struct sock *sk, 
+ 		return -EINVAL;
+ 
+ 	inet->cork.length += size;
++	if ((sk->sk_protocol == IPPROTO_UDP) &&
++	    (rt->u.dst.dev->features & NETIF_F_UFO))
++		skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
++
+ 
+ 	while (size > 0) {
+ 		int i;
+ 
+-		/* Check if the remaining data fits into current packet. */
+-		len = mtu - skb->len;
+-		if (len < size)
+-			len = maxfraglen - skb->len;
++		if (skb_shinfo(skb)->ufo_size)
++			len = size;
++		else {
++
++			/* Check if the remaining data fits into current packet. */
++			len = mtu - skb->len;
++			if (len < size)
++				len = maxfraglen - skb->len;
++		}
+ 		if (len <= 0) {
+ 			struct sk_buff *skb_prev;
+ 			char *data;
+@@ -1023,10 +1096,7 @@ ssize_t	ip_append_page(struct sock *sk, 
+ 			int alloclen;
+ 
+ 			skb_prev = skb;
+-			if (skb_prev)
+-				fraggap = skb_prev->len - maxfraglen;
+-			else
+-				fraggap = 0;
++			fraggap = skb_prev->len - maxfraglen;
+ 
+ 			alloclen = fragheaderlen + hh_len + fraggap + 15;
+ 			skb = sock_wmalloc(sk, alloclen, 1, sk->sk_allocation);
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -347,58 +347,106 @@ unsigned int arpt_do_table(struct sk_buf
+ 		return verdict;
+ }
+ 
+-static inline void *find_inlist_lock_noload(struct list_head *head,
+-					    const char *name,
+-					    int *error,
+-					    struct semaphore *mutex)
++/*
++ * These are weird, but module loading must not be done with mutex
++ * held (since they will register), and we have to have a single
++ * function to use try_then_request_module().
++ */
++
++/* Find table by name, grabs mutex & ref.  Returns ERR_PTR() on error. */
++static inline struct arpt_table *find_table_lock(const char *name)
+ {
+-	void *ret;
++	struct arpt_table *t;
+ 
+-	*error = down_interruptible(mutex);
+-	if (*error != 0)
+-		return NULL;
++	if (down_interruptible(&arpt_mutex) != 0)
++		return ERR_PTR(-EINTR);
+ 
+-	ret = list_named_find(head, name);
+-	if (!ret) {
+-		*error = -ENOENT;
+-		up(mutex);
+-	}
+-	return ret;
++	list_for_each_entry(t, &arpt_tables, list)
++		if (strcmp(t->name, name) == 0 && try_module_get(t->me))
++			return t;
++	up(&arpt_mutex);
++	return NULL;
+ }
+ 
+-#ifndef CONFIG_KMOD
+-#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
+-#else
+-static void *
+-find_inlist_lock(struct list_head *head,
+-		 const char *name,
+-		 const char *prefix,
+-		 int *error,
+-		 struct semaphore *mutex)
+-{
+-	void *ret;
+-
+-	ret = find_inlist_lock_noload(head, name, error, mutex);
+-	if (!ret) {
+-		duprintf("find_inlist: loading `%s%s'.\n", prefix, name);
+-		request_module("%s%s", prefix, name);
+-		ret = find_inlist_lock_noload(head, name, error, mutex);
++
++/* Find target, grabs ref.  Returns ERR_PTR() on error. */
++static inline struct arpt_target *find_target(const char *name, u8 revision)
++{
++	struct arpt_target *t;
++	int err = 0;
++
++	if (down_interruptible(&arpt_mutex) != 0)
++		return ERR_PTR(-EINTR);
++
++	list_for_each_entry(t, &arpt_target, list) {
++		if (strcmp(t->name, name) == 0) {
++			if (t->revision == revision) {
++				if (try_module_get(t->me)) {
++					up(&arpt_mutex);
++					return t;
++				}
++			} else
++				err = -EPROTOTYPE; /* Found something. */
++		}
+ 	}
++	up(&arpt_mutex);
++	return ERR_PTR(err);
++}
+ 
+-	return ret;
++struct arpt_target *arpt_find_target(const char *name, u8 revision)
++{
++	struct arpt_target *target;
++
++	target = try_then_request_module(find_target(name, revision),
++					 "arpt_%s", name);
++	if (IS_ERR(target) || !target)
++		return NULL;
++	return target;
+ }
+-#endif
+ 
+-static inline struct arpt_table *arpt_find_table_lock(const char *name, int *error, struct semaphore *mutex)
++static int target_revfn(const char *name, u8 revision, int *bestp)
+ {
+-	return find_inlist_lock(&arpt_tables, name, "arptable_", error, mutex);
++	struct arpt_target *t;
++	int have_rev = 0;
++
++	list_for_each_entry(t, &arpt_target, list) {
++		if (strcmp(t->name, name) == 0) {
++			if (t->revision > *bestp)
++				*bestp = t->revision;
++			if (t->revision == revision)
++				have_rev =1;
++		}
++	}
++	return have_rev;
+ }
+ 
+-static struct arpt_target *arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex)
++/* Returns true or false (if no such extension at all) */
++static inline int find_revision(const char *name, u8 revision,
++				int (*revfn)(const char *, u8, int *),
++				int *err)
+ {
+-	return find_inlist_lock(&arpt_target, name, "arpt_", error, mutex);
++	int have_rev, best = -1;
++
++	if (down_interruptible(&arpt_mutex) != 0) {
++		*err = -EINTR;
++		return 1;
++	}
++	have_rev = revfn(name, revision, &best);
++	up(&arpt_mutex);
++
++	/* Nothing at all?  Return 0 to try loading module. */
++	if (best == -1) {
++		*err = -ENOENT;
++		return 0;
++	}
++
++	*err = best;
++	if (!have_rev)
++		*err = -EPROTONOSUPPORT;
++	return 1;
+ }
+ 
++
+ /* All zeroes == unconditional rule. */
+ static inline int unconditional(const struct arpt_arp *arp)
+ {
+@@ -544,17 +592,15 @@ static inline int check_entry(struct arp
+ 	}
+ 
+ 	t = arpt_get_target(e);
+-	target = arpt_find_target_lock(t->u.user.name, &ret, &arpt_mutex);
+-	if (!target) {
++	target = try_then_request_module(find_target(t->u.user.name,
++						     t->u.user.revision),
++					 "arpt_%s", t->u.user.name);
++	if (IS_ERR(target) || !target) {
+ 		duprintf("check_entry: `%s' not found\n", t->u.user.name);
++		ret = target ? PTR_ERR(target) : -ENOENT;
+ 		goto out;
+ 	}
+-	if (!try_module_get((target->me))) {
+-		ret = -ENOENT;
+-		goto out_unlock;
+-	}
+ 	t->u.kernel.target = target;
+-	up(&arpt_mutex);
+ 
+ 	if (t->u.kernel.target == &arpt_standard_target) {
+ 		if (!standard_check(t, size)) {
+@@ -576,8 +622,6 @@ static inline int check_entry(struct arp
+ 	(*i)++;
+ 	return 0;
+ 
+-out_unlock:
+-	up(&arpt_mutex);
+ out:
+ 	return ret;
+ }
+@@ -846,8 +890,8 @@ static int get_entries(const struct arpt
+ 	int ret;
+ 	struct arpt_table *t;
+ 
+-	t = arpt_find_table_lock(entries->name, &ret, &arpt_mutex);
+-	if (t) {
++	t = find_table_lock(entries->name);
++	if (t || !IS_ERR(t)) {
+ 		duprintf("t->private->number = %u\n",
+ 			 t->private->number);
+ 		if (entries->size == t->private->size)
+@@ -859,10 +903,10 @@ static int get_entries(const struct arpt
+ 				 entries->size);
+ 			ret = -EINVAL;
+ 		}
++		module_put(t->me);
+ 		up(&arpt_mutex);
+ 	} else
+-		duprintf("get_entries: Can't find %s!\n",
+-			 entries->name);
++		ret = t ? PTR_ERR(t) : -ENOENT;
+ 
+ 	return ret;
+ }
+@@ -913,22 +957,19 @@ static int do_replace(void __user *user,
+ 
+ 	duprintf("arp_tables: Translated table\n");
+ 
+-	t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex);
+-	if (!t)
++	t = try_then_request_module(find_table_lock(tmp.name),
++				    "arptable_%s", tmp.name);
++	if (!t || IS_ERR(t)) {
++		ret = t ? PTR_ERR(t) : -ENOENT;
+ 		goto free_newinfo_counters_untrans;
++	}
+ 
+ 	/* You lied! */
+ 	if (tmp.valid_hooks != t->valid_hooks) {
+ 		duprintf("Valid hook crap: %08X vs %08X\n",
+ 			 tmp.valid_hooks, t->valid_hooks);
+ 		ret = -EINVAL;
+-		goto free_newinfo_counters_untrans_unlock;
+-	}
+-
+-	/* Get a reference in advance, we're not allowed fail later */
+-	if (!try_module_get(t->me)) {
+-		ret = -EBUSY;
+-		goto free_newinfo_counters_untrans_unlock;
++		goto put_module;
+ 	}
+ 
+ 	oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
+@@ -959,7 +1000,6 @@ static int do_replace(void __user *user,
+ 
+  put_module:
+ 	module_put(t->me);
+- free_newinfo_counters_untrans_unlock:
+ 	up(&arpt_mutex);
+  free_newinfo_counters_untrans:
+ 	ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry, NULL);
+@@ -989,7 +1029,7 @@ static int do_add_counters(void __user *
+ 	unsigned int i;
+ 	struct arpt_counters_info tmp, *paddc;
+ 	struct arpt_table *t;
+-	int ret;
++	int ret = 0;
+ 
+ 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
+ 		return -EFAULT;
+@@ -1006,9 +1046,11 @@ static int do_add_counters(void __user *
+ 		goto free;
+ 	}
+ 
+-	t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex);
+-	if (!t)
++	t = find_table_lock(tmp.name);
++	if (!t || IS_ERR(t)) {
++		ret = t ? PTR_ERR(t) : -ENOENT;
+ 		goto free;
++	}
+ 
+ 	write_lock_bh(&t->lock);
+ 	if (t->private->number != paddc->num_counters) {
+@@ -1025,6 +1067,7 @@ static int do_add_counters(void __user *
+  unlock_up_free:
+ 	write_unlock_bh(&t->lock);
+ 	up(&arpt_mutex);
++	module_put(t->me);
+  free:
+ 	vfree(paddc);
+ 
+@@ -1079,8 +1122,10 @@ static int do_arpt_get_ctl(struct sock *
+ 			break;
+ 		}
+ 		name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
+-		t = arpt_find_table_lock(name, &ret, &arpt_mutex);
+-		if (t) {
++
++		t = try_then_request_module(find_table_lock(name),
++					    "arptable_%s", name);
++		if (t && !IS_ERR(t)) {
+ 			struct arpt_getinfo info;
+ 
+ 			info.valid_hooks = t->valid_hooks;
+@@ -1096,9 +1141,10 @@ static int do_arpt_get_ctl(struct sock *
+ 				ret = -EFAULT;
+ 			else
+ 				ret = 0;
+-
+ 			up(&arpt_mutex);
+-		}
++			module_put(t->me);
++		} else
++			ret = t ? PTR_ERR(t) : -ENOENT;
+ 	}
+ 	break;
+ 
+@@ -1119,6 +1165,24 @@ static int do_arpt_get_ctl(struct sock *
+ 		break;
+ 	}
+ 
++	case ARPT_SO_GET_REVISION_TARGET: {
++		struct arpt_get_revision rev;
++
++		if (*len != sizeof(rev)) {
++			ret = -EINVAL;
++			break;
++		}
++		if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
++			ret = -EFAULT;
++			break;
++		}
++
++		try_then_request_module(find_revision(rev.name, rev.revision,
++						      target_revfn, &ret),
++					"arpt_%s", rev.name);
++		break;
++	}
++
+ 	default:
+ 		duprintf("do_arpt_get_ctl: unknown request %i\n", cmd);
+ 		ret = -EINVAL;
+@@ -1136,12 +1200,9 @@ int arpt_register_target(struct arpt_tar
+ 	if (ret != 0)
+ 		return ret;
+ 
+-	if (!list_named_insert(&arpt_target, target)) {
+-		duprintf("arpt_register_target: `%s' already in list!\n",
+-			 target->name);
+-		ret = -EINVAL;
+-	}
++	list_add(&target->list, &arpt_target);
+ 	up(&arpt_mutex);
++
+ 	return ret;
+ }
+ 
+diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
+--- a/net/ipv4/netfilter/ip_conntrack_core.c
++++ b/net/ipv4/netfilter/ip_conntrack_core.c
+@@ -50,7 +50,7 @@
+ #include <linux/netfilter_ipv4/ip_conntrack_core.h>
+ #include <linux/netfilter_ipv4/listhelp.h>
+ 
+-#define IP_CONNTRACK_VERSION	"2.3"
++#define IP_CONNTRACK_VERSION	"2.4"
+ 
+ #if 0
+ #define DEBUGP printk
+@@ -148,16 +148,20 @@ DEFINE_PER_CPU(struct ip_conntrack_stat,
+ static int ip_conntrack_hash_rnd_initted;
+ static unsigned int ip_conntrack_hash_rnd;
+ 
+-static u_int32_t
+-hash_conntrack(const struct ip_conntrack_tuple *tuple)
++static u_int32_t __hash_conntrack(const struct ip_conntrack_tuple *tuple,
++			    unsigned int size, unsigned int rnd)
+ {
+-#if 0
+-	dump_tuple(tuple);
+-#endif
+ 	return (jhash_3words(tuple->src.ip,
+ 	                     (tuple->dst.ip ^ tuple->dst.protonum),
+ 	                     (tuple->src.u.all | (tuple->dst.u.all << 16)),
+-	                     ip_conntrack_hash_rnd) % ip_conntrack_htable_size);
++	                     rnd) % size);
++}
++
++static u_int32_t
++hash_conntrack(const struct ip_conntrack_tuple *tuple)
++{
++	return __hash_conntrack(tuple, ip_conntrack_htable_size,
++				ip_conntrack_hash_rnd);
+ }
+ 
+ int
+@@ -1341,14 +1345,13 @@ static int kill_all(struct ip_conntrack 
+ 	return 1;
+ }
+ 
+-static void free_conntrack_hash(void)
++static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size)
+ {
+-	if (ip_conntrack_vmalloc)
+-		vfree(ip_conntrack_hash);
++	if (vmalloced)
++		vfree(hash);
+ 	else
+-		free_pages((unsigned long)ip_conntrack_hash, 
+-			   get_order(sizeof(struct list_head)
+-				     * ip_conntrack_htable_size));
++		free_pages((unsigned long)hash, 
++			   get_order(sizeof(struct list_head) * size));
+ }
+ 
+ void ip_conntrack_flush()
+@@ -1378,12 +1381,83 @@ void ip_conntrack_cleanup(void)
+ 	ip_conntrack_flush();
+ 	kmem_cache_destroy(ip_conntrack_cachep);
+ 	kmem_cache_destroy(ip_conntrack_expect_cachep);
+-	free_conntrack_hash();
++	free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
++			    ip_conntrack_htable_size);
+ 	nf_unregister_sockopt(&so_getorigdst);
+ }
+ 
+-static int hashsize;
+-module_param(hashsize, int, 0400);
++static struct list_head *alloc_hashtable(int size, int *vmalloced)
++{
++	struct list_head *hash;
++	unsigned int i;
++
++	*vmalloced = 0; 
++	hash = (void*)__get_free_pages(GFP_KERNEL, 
++				       get_order(sizeof(struct list_head)
++						 * size));
++	if (!hash) { 
++		*vmalloced = 1;
++		printk(KERN_WARNING"ip_conntrack: falling back to vmalloc.\n");
++		hash = vmalloc(sizeof(struct list_head) * size);
++	}
++
++	if (hash)
++		for (i = 0; i < size; i++)
++			INIT_LIST_HEAD(&hash[i]);
++
++	return hash;
++}
++
++int set_hashsize(const char *val, struct kernel_param *kp)
++{
++	int i, bucket, hashsize, vmalloced;
++	int old_vmalloced, old_size;
++	int rnd;
++	struct list_head *hash, *old_hash;
++	struct ip_conntrack_tuple_hash *h;
++
++	/* On boot, we can set this without any fancy locking. */
++	if (!ip_conntrack_htable_size)
++		return param_set_int(val, kp);
++
++	hashsize = simple_strtol(val, NULL, 0);
++	if (!hashsize)
++		return -EINVAL;
++
++	hash = alloc_hashtable(hashsize, &vmalloced);
++	if (!hash)
++		return -ENOMEM;
++
++	/* We have to rehash for the new table anyway, so we also can 
++	 * use a new random seed */
++	get_random_bytes(&rnd, 4);
++
++	write_lock_bh(&ip_conntrack_lock);
++	for (i = 0; i < ip_conntrack_htable_size; i++) {
++		while (!list_empty(&ip_conntrack_hash[i])) {
++			h = list_entry(ip_conntrack_hash[i].next,
++				       struct ip_conntrack_tuple_hash, list);
++			list_del(&h->list);
++			bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
++			list_add_tail(&h->list, &hash[bucket]);
++		}
++	}
++	old_size = ip_conntrack_htable_size;
++	old_vmalloced = ip_conntrack_vmalloc;
++	old_hash = ip_conntrack_hash;
++
++	ip_conntrack_htable_size = hashsize;
++	ip_conntrack_vmalloc = vmalloced;
++	ip_conntrack_hash = hash;
++	ip_conntrack_hash_rnd = rnd;
++	write_unlock_bh(&ip_conntrack_lock);
++
++	free_conntrack_hash(old_hash, old_vmalloced, old_size);
++	return 0;
++}
++
++module_param_call(hashsize, set_hashsize, param_get_uint,
++		  &ip_conntrack_htable_size, 0600);
+ 
+ int __init ip_conntrack_init(void)
+ {
+@@ -1392,9 +1466,7 @@ int __init ip_conntrack_init(void)
+ 
+ 	/* Idea from tcp.c: use 1/16384 of memory.  On i386: 32MB
+ 	 * machine has 256 buckets.  >= 1GB machines have 8192 buckets. */
+- 	if (hashsize) {
+- 		ip_conntrack_htable_size = hashsize;
+- 	} else {
++ 	if (!ip_conntrack_htable_size) {
+ 		ip_conntrack_htable_size
+ 			= (((num_physpages << PAGE_SHIFT) / 16384)
+ 			   / sizeof(struct list_head));
+@@ -1416,20 +1488,8 @@ int __init ip_conntrack_init(void)
+ 		return ret;
+ 	}
+ 
+-	/* AK: the hash table is twice as big than needed because it
+-	   uses list_head.  it would be much nicer to caches to use a
+-	   single pointer list head here. */
+-	ip_conntrack_vmalloc = 0; 
+-	ip_conntrack_hash 
+-		=(void*)__get_free_pages(GFP_KERNEL, 
+-					 get_order(sizeof(struct list_head)
+-						   *ip_conntrack_htable_size));
+-	if (!ip_conntrack_hash) { 
+-		ip_conntrack_vmalloc = 1;
+-		printk(KERN_WARNING "ip_conntrack: falling back to vmalloc.\n");
+-		ip_conntrack_hash = vmalloc(sizeof(struct list_head)
+-					    * ip_conntrack_htable_size);
+-	}
++	ip_conntrack_hash = alloc_hashtable(ip_conntrack_htable_size,
++					    &ip_conntrack_vmalloc);
+ 	if (!ip_conntrack_hash) {
+ 		printk(KERN_ERR "Unable to create ip_conntrack_hash\n");
+ 		goto err_unreg_sockopt;
+@@ -1461,9 +1521,6 @@ int __init ip_conntrack_init(void)
+ 	ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
+ 	write_unlock_bh(&ip_conntrack_lock);
+ 
+-	for (i = 0; i < ip_conntrack_htable_size; i++)
+-		INIT_LIST_HEAD(&ip_conntrack_hash[i]);
+-
+ 	/* For use by ipt_REJECT */
+ 	ip_ct_attach = ip_conntrack_attach;
+ 
+@@ -1478,7 +1535,8 @@ int __init ip_conntrack_init(void)
+ err_free_conntrack_slab:
+ 	kmem_cache_destroy(ip_conntrack_cachep);
+ err_free_hash:
+-	free_conntrack_hash();
++	free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
++			    ip_conntrack_htable_size);
+ err_unreg_sockopt:
+ 	nf_unregister_sockopt(&so_getorigdst);
+ 
+diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
+--- a/net/ipv4/netfilter/ipt_addrtype.c
++++ b/net/ipv4/netfilter/ipt_addrtype.c
+@@ -48,7 +48,7 @@ static int checkentry(const char *tablen
+ 		      unsigned int hook_mask)
+ {
+ 	if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
+-		printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n.",
++		printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n",
+ 		       matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
+ 		return 0;
+ 	}
+diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
+--- a/net/ipv4/proc.c
++++ b/net/ipv4/proc.c
+@@ -90,9 +90,7 @@ fold_field(void *mib[], int offt)
+ 	unsigned long res = 0;
+ 	int i;
+ 
+-	for (i = 0; i < NR_CPUS; i++) {
+-		if (!cpu_possible(i))
+-			continue;
++	for_each_cpu(i) {
+ 		res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt);
+ 		res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt);
+ 	}
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -75,7 +75,7 @@
+ #ifdef CONFIG_IPV6_PRIVACY
+ #include <linux/random.h>
+ #include <linux/crypto.h>
+-#include <asm/scatterlist.h>
++#include <linux/scatterlist.h>
+ #endif
+ 
+ #include <asm/uaccess.h>
+@@ -1217,12 +1217,8 @@ static int __ipv6_regen_rndid(struct ine
+ 	struct net_device *dev;
+ 	struct scatterlist sg[2];
+ 
+-	sg[0].page = virt_to_page(idev->entropy);
+-	sg[0].offset = offset_in_page(idev->entropy);
+-	sg[0].length = 8;
+-	sg[1].page = virt_to_page(idev->work_eui64);
+-	sg[1].offset = offset_in_page(idev->work_eui64);
+-	sg[1].length = 8;
++	sg_set_buf(&sg[0], idev->entropy, 8);
++	sg_set_buf(&sg[1], idev->work_eui64, 8);
+ 
+ 	dev = idev->dev;
+ 
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -700,10 +700,7 @@ int __init icmpv6_init(struct net_proto_
+ 	struct sock *sk;
+ 	int err, i, j;
+ 
+-	for (i = 0; i < NR_CPUS; i++) {
+-		if (!cpu_possible(i))
+-			continue;
+-
++	for_each_cpu(i) {
+ 		err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
+ 				       &per_cpu(__icmpv6_socket, i));
+ 		if (err < 0) {
+@@ -749,9 +746,7 @@ void icmpv6_cleanup(void)
+ {
+ 	int i;
+ 
+-	for (i = 0; i < NR_CPUS; i++) {
+-		if (!cpu_possible(i))
+-			continue;
++	for_each_cpu(i) {
+ 		sock_release(per_cpu(__icmpv6_socket, i));
+ 	}
+ 	inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -147,7 +147,8 @@ static int ip6_output2(struct sk_buff *s
+ 
+ int ip6_output(struct sk_buff *skb)
+ {
+-	if (skb->len > dst_mtu(skb->dst) || dst_allfrag(skb->dst))
++	if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) ||
++				dst_allfrag(skb->dst))
+ 		return ip6_fragment(skb, ip6_output2);
+ 	else
+ 		return ip6_output2(skb);
+@@ -768,6 +769,65 @@ out_err_release:
+ 	*dst = NULL;
+ 	return err;
+ }
++inline int ip6_ufo_append_data(struct sock *sk,
++			int getfrag(void *from, char *to, int offset, int len,
++			int odd, struct sk_buff *skb),
++			void *from, int length, int hh_len, int fragheaderlen,
++			int transhdrlen, int mtu,unsigned int flags)
++
++{
++	struct sk_buff *skb;
++	int err;
++
++	/* There is support for UDP large send offload by network
++	 * device, so create one single skb packet containing complete
++	 * udp datagram
++	 */
++	if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
++		skb = sock_alloc_send_skb(sk,
++			hh_len + fragheaderlen + transhdrlen + 20,
++			(flags & MSG_DONTWAIT), &err);
++		if (skb == NULL)
++			return -ENOMEM;
++
++		/* reserve space for Hardware header */
++		skb_reserve(skb, hh_len);
++
++		/* create space for UDP/IP header */
++		skb_put(skb,fragheaderlen + transhdrlen);
++
++		/* initialize network header pointer */
++		skb->nh.raw = skb->data;
++
++		/* initialize protocol header pointer */
++		skb->h.raw = skb->data + fragheaderlen;
++
++		skb->ip_summed = CHECKSUM_HW;
++		skb->csum = 0;
++		sk->sk_sndmsg_off = 0;
++	}
++
++	err = skb_append_datato_frags(sk,skb, getfrag, from,
++				      (length - transhdrlen));
++	if (!err) {
++		struct frag_hdr fhdr;
++
++		/* specify the length of each IP datagram fragment*/
++		skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) - 
++						sizeof(struct frag_hdr);
++		ipv6_select_ident(skb, &fhdr);
++		skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
++		__skb_queue_tail(&sk->sk_write_queue, skb);
++
++		return 0;
++	}
++	/* There is not enough support do UPD LSO,
++	 * so follow normal path
++	 */
++	kfree_skb(skb);
++
++	return err;
++}
+ 
+ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+ 	int offset, int len, int odd, struct sk_buff *skb),
+@@ -860,6 +920,15 @@ int ip6_append_data(struct sock *sk, int
+ 	 */
+ 
+ 	inet->cork.length += length;
++	if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
++	    (rt->u.dst.dev->features & NETIF_F_UFO)) {
++
++		if(ip6_ufo_append_data(sk, getfrag, from, length, hh_len,
++				fragheaderlen, transhdrlen, mtu, flags))
++			goto error;
++
++		return 0;
++	}
+ 
+ 	if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
+ 		goto alloc_new_skb;
+diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
+--- a/net/ipv6/mcast.c
++++ b/net/ipv6/mcast.c
+@@ -164,7 +164,7 @@ static int ip6_mc_leave_src(struct sock 
+ #define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value))
+ #define MLDV2_EXP(thresh, nbmant, nbexp, value) \
+ 	((value) < (thresh) ? (value) : \
+-	((MLDV2_MASK(value, nbmant) | (1<<(nbmant+nbexp))) << \
++	((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \
+ 	(MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp))))
+ 
+ #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
+@@ -1087,7 +1087,7 @@ static void mld_marksources(struct ifmca
+ 
+ int igmp6_event_query(struct sk_buff *skb)
+ {
+-	struct mld2_query *mlh2 = (struct mld2_query *) skb->h.raw;
++	struct mld2_query *mlh2 = NULL;
+ 	struct ifmcaddr6 *ma;
+ 	struct in6_addr *group;
+ 	unsigned long max_delay;
+@@ -1140,6 +1140,13 @@ int igmp6_event_query(struct sk_buff *sk
+ 		/* clear deleted report items */
+ 		mld_clear_delrec(idev);
+ 	} else if (len >= 28) {
++		int srcs_offset = sizeof(struct mld2_query) - 
++				  sizeof(struct icmp6hdr);
++		if (!pskb_may_pull(skb, srcs_offset)) {
++			in6_dev_put(idev);
++			return -EINVAL;
++		}
++		mlh2 = (struct mld2_query *) skb->h.raw;
+ 		max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000;
+ 		if (!max_delay)
+ 			max_delay = 1;
+@@ -1156,7 +1163,15 @@ int igmp6_event_query(struct sk_buff *sk
+ 			return 0;
+ 		}
+ 		/* mark sources to include, if group & source-specific */
+-		mark = mlh2->nsrcs != 0;
++		if (mlh2->nsrcs != 0) {
++			if (!pskb_may_pull(skb, srcs_offset + 
++				mlh2->nsrcs * sizeof(struct in6_addr))) {
++				in6_dev_put(idev);
++				return -EINVAL;
++			}
++			mlh2 = (struct mld2_query *) skb->h.raw;
++			mark = 1;
++		}
+ 	} else {
+ 		in6_dev_put(idev);
+ 		return -EINVAL;
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -2,7 +2,7 @@
+  * Packet matching code.
+  *
+  * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+- * Copyright (C) 2000-2002 Netfilter core team <coreteam at netfilter.org>
++ * Copyright (C) 2000-2005 Netfilter Core Team <coreteam at netfilter.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
+@@ -23,7 +23,6 @@
+ #include <linux/tcp.h>
+ #include <linux/udp.h>
+ #include <linux/icmpv6.h>
+-#include <net/ip.h>
+ #include <net/ipv6.h>
+ #include <asm/uaccess.h>
+ #include <asm/semaphore.h>
+@@ -80,13 +79,12 @@ static DECLARE_MUTEX(ip6t_mutex);
+ #define inline
+ #endif
+ 
+-/* Locking is simple: we assume at worst case there will be one packet
+-   in user context and one from bottom halves (or soft irq if Alexey's
+-   softnet patch was applied).
+-
++/*
+    We keep a set of rules for each CPU, so we can avoid write-locking
+-   them; doing a readlock_bh() stops packets coming through if we're
+-   in user context.
++   them in the softirq when updating the counters and therefore
++   only need to read-lock in the softirq; doing a write_lock_bh() in user
++   context stops packets coming through and allows user context to read
++   the counters or update the rules.
+ 
+    To be cache friendly on SMP, we arrange them like so:
+    [ n-entries ]
+@@ -356,7 +354,7 @@ ip6t_do_table(struct sk_buff **pskb,
+ 	      struct ip6t_table *table,
+ 	      void *userdata)
+ {
+-	static const char nulldevname[IFNAMSIZ];
++	static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
+ 	int offset = 0;
+ 	unsigned int protoff = 0;
+ 	int hotdrop = 0;
+@@ -369,7 +367,6 @@ ip6t_do_table(struct sk_buff **pskb,
+ 	/* Initialization */
+ 	indev = in ? in->name : nulldevname;
+ 	outdev = out ? out->name : nulldevname;
+-
+ 	/* We handle fragments by dealing with the first fragment as
+ 	 * if it was a normal packet.  All other fragments are treated
+ 	 * normally, except that they will NEVER match rules that ask
+@@ -497,75 +494,145 @@ ip6t_do_table(struct sk_buff **pskb,
+ #endif
+ }
+ 
+-/* If it succeeds, returns element and locks mutex */
+-static inline void *
+-find_inlist_lock_noload(struct list_head *head,
+-			const char *name,
+-			int *error,
+-			struct semaphore *mutex)
+-{
+-	void *ret;
+-
+-#if 1
+-	duprintf("find_inlist: searching for `%s' in %s.\n",
+-		 name, head == &ip6t_target ? "ip6t_target"
+-		 : head == &ip6t_match ? "ip6t_match"
+-		 : head == &ip6t_tables ? "ip6t_tables" : "UNKNOWN");
+-#endif
++/*
++ * These are weird, but module loading must not be done with mutex
++ * held (since they will register), and we have to have a single
++ * function to use try_then_request_module().
++ */
+ 
+-	*error = down_interruptible(mutex);
+-	if (*error != 0)
+-		return NULL;
++/* Find table by name, grabs mutex & ref.  Returns ERR_PTR() on error. */
++static inline struct ip6t_table *find_table_lock(const char *name)
++{
++	struct ip6t_table *t;
++
++	if (down_interruptible(&ip6t_mutex) != 0)
++		return ERR_PTR(-EINTR);
++
++	list_for_each_entry(t, &ip6t_tables, list)
++		if (strcmp(t->name, name) == 0 && try_module_get(t->me))
++			return t;
++	up(&ip6t_mutex);
++	return NULL;
++}
++
++/* Find match, grabs ref.  Returns ERR_PTR() on error. */
++static inline struct ip6t_match *find_match(const char *name, u8 revision)
++{
++	struct ip6t_match *m;
++	int err = 0;
++
++	if (down_interruptible(&ip6t_mutex) != 0)
++		return ERR_PTR(-EINTR);
+ 
+-	ret = list_named_find(head, name);
+-	if (!ret) {
+-		*error = -ENOENT;
+-		up(mutex);
++	list_for_each_entry(m, &ip6t_match, list) {
++		if (strcmp(m->name, name) == 0) {
++			if (m->revision == revision) {
++				if (try_module_get(m->me)) {
++					up(&ip6t_mutex);
++					return m;
++				}
++			} else
++				err = -EPROTOTYPE; /* Found something. */
++		}
+ 	}
+-	return ret;
++	up(&ip6t_mutex);
++	return ERR_PTR(err);
+ }
+ 
+-#ifndef CONFIG_KMOD
+-#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
+-#else
+-static void *
+-find_inlist_lock(struct list_head *head,
+-		 const char *name,
+-		 const char *prefix,
+-		 int *error,
+-		 struct semaphore *mutex)
+-{
+-	void *ret;
+-
+-	ret = find_inlist_lock_noload(head, name, error, mutex);
+-	if (!ret) {
+-		duprintf("find_inlist: loading `%s%s'.\n", prefix, name);
+-		request_module("%s%s", prefix, name);
+-		ret = find_inlist_lock_noload(head, name, error, mutex);
++/* Find target, grabs ref.  Returns ERR_PTR() on error. */
++static inline struct ip6t_target *find_target(const char *name, u8 revision)
++{
++	struct ip6t_target *t;
++	int err = 0;
++
++	if (down_interruptible(&ip6t_mutex) != 0)
++		return ERR_PTR(-EINTR);
++
++	list_for_each_entry(t, &ip6t_target, list) {
++		if (strcmp(t->name, name) == 0) {
++			if (t->revision == revision) {
++				if (try_module_get(t->me)) {
++					up(&ip6t_mutex);
++					return t;
++				}
++			} else
++				err = -EPROTOTYPE; /* Found something. */
++		}
+ 	}
++	up(&ip6t_mutex);
++	return ERR_PTR(err);
++}
+ 
+-	return ret;
++struct ip6t_target *ip6t_find_target(const char *name, u8 revision)
++{
++	struct ip6t_target *target;
++
++	target = try_then_request_module(find_target(name, revision),
++					 "ip6t_%s", name);
++	if (IS_ERR(target) || !target)
++		return NULL;
++	return target;
+ }
+-#endif
+ 
+-static inline struct ip6t_table *
+-ip6t_find_table_lock(const char *name, int *error, struct semaphore *mutex)
++static int match_revfn(const char *name, u8 revision, int *bestp)
+ {
+-	return find_inlist_lock(&ip6t_tables, name, "ip6table_", error, mutex);
++	struct ip6t_match *m;
++	int have_rev = 0;
++
++	list_for_each_entry(m, &ip6t_match, list) {
++		if (strcmp(m->name, name) == 0) {
++			if (m->revision > *bestp)
++				*bestp = m->revision;
++			if (m->revision == revision)
++				have_rev = 1;
++		}
++	}
++	return have_rev;
+ }
+ 
+-static inline struct ip6t_match *
+-find_match_lock(const char *name, int *error, struct semaphore *mutex)
++static int target_revfn(const char *name, u8 revision, int *bestp)
+ {
+-	return find_inlist_lock(&ip6t_match, name, "ip6t_", error, mutex);
++	struct ip6t_target *t;
++	int have_rev = 0;
++
++	list_for_each_entry(t, &ip6t_target, list) {
++		if (strcmp(t->name, name) == 0) {
++			if (t->revision > *bestp)
++				*bestp = t->revision;
++			if (t->revision == revision)
++				have_rev = 1;
++		}
++	}
++	return have_rev;
+ }
+ 
+-static struct ip6t_target *
+-ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex)
++/* Returns true or fals (if no such extension at all) */
++static inline int find_revision(const char *name, u8 revision,
++				int (*revfn)(const char *, u8, int *),
++				int *err)
+ {
+-	return find_inlist_lock(&ip6t_target, name, "ip6t_", error, mutex);
++	int have_rev, best = -1;
++
++	if (down_interruptible(&ip6t_mutex) != 0) {
++		*err = -EINTR;
++		return 1;
++	}
++	have_rev = revfn(name, revision, &best);
++	up(&ip6t_mutex);
++
++	/* Nothing at all?  Return 0 to try loading module. */
++	if (best == -1) {
++		*err = -ENOENT;
++		return 0;
++	}
++
++	*err = best;
++	if (!have_rev)
++		*err = -EPROTONOSUPPORT;
++	return 1;
+ }
+ 
++
+ /* All zeroes == unconditional rule. */
+ static inline int
+ unconditional(const struct ip6t_ip6 *ipv6)
+@@ -725,20 +792,16 @@ check_match(struct ip6t_entry_match *m,
+ 	    unsigned int hookmask,
+ 	    unsigned int *i)
+ {
+-	int ret;
+ 	struct ip6t_match *match;
+ 
+-	match = find_match_lock(m->u.user.name, &ret, &ip6t_mutex);
+-	if (!match) {
+-	  //		duprintf("check_match: `%s' not found\n", m->u.name);
+-		return ret;
+-	}
+-	if (!try_module_get(match->me)) {
+-		up(&ip6t_mutex);
+-		return -ENOENT;
++	match = try_then_request_module(find_match(m->u.user.name,
++						   m->u.user.revision),
++					"ip6t_%s", m->u.user.name);
++	if (IS_ERR(match) || !match) {
++		duprintf("check_match: `%s' not found\n", m->u.user.name);
++		return match ? PTR_ERR(match) : -ENOENT;
+ 	}
+ 	m->u.kernel.match = match;
+-	up(&ip6t_mutex);
+ 
+ 	if (m->u.kernel.match->checkentry
+ 	    && !m->u.kernel.match->checkentry(name, ipv6, m->data,
+@@ -776,22 +839,16 @@ check_entry(struct ip6t_entry *e, const 
+ 		goto cleanup_matches;
+ 
+ 	t = ip6t_get_target(e);
+-	target = ip6t_find_target_lock(t->u.user.name, &ret, &ip6t_mutex);
+-	if (!target) {
++	target = try_then_request_module(find_target(t->u.user.name,
++						     t->u.user.revision),
++					 "ip6t_%s", t->u.user.name);
++	if (IS_ERR(target) || !target) {
+ 		duprintf("check_entry: `%s' not found\n", t->u.user.name);
+-		goto cleanup_matches;
+-	}
+-	if (!try_module_get(target->me)) {
+-		up(&ip6t_mutex);
+-		ret = -ENOENT;
++		ret = target ? PTR_ERR(target) : -ENOENT;
+ 		goto cleanup_matches;
+ 	}
+ 	t->u.kernel.target = target;
+-	up(&ip6t_mutex);
+-	if (!t->u.kernel.target) {
+-		ret = -EBUSY;
+-		goto cleanup_matches;
+-	}
++
+ 	if (t->u.kernel.target == &ip6t_standard_target) {
+ 		if (!standard_check(t, size)) {
+ 			ret = -EINVAL;
+@@ -1118,8 +1175,8 @@ get_entries(const struct ip6t_get_entrie
+ 	int ret;
+ 	struct ip6t_table *t;
+ 
+-	t = ip6t_find_table_lock(entries->name, &ret, &ip6t_mutex);
+-	if (t) {
++	t = find_table_lock(entries->name);
++	if (t && !IS_ERR(t)) {
+ 		duprintf("t->private->number = %u\n",
+ 			 t->private->number);
+ 		if (entries->size == t->private->size)
+@@ -1131,10 +1188,10 @@ get_entries(const struct ip6t_get_entrie
+ 				 entries->size);
+ 			ret = -EINVAL;
+ 		}
++		module_put(t->me);
+ 		up(&ip6t_mutex);
+ 	} else
+-		duprintf("get_entries: Can't find %s!\n",
+-			 entries->name);
++		ret = t ? PTR_ERR(t) : -ENOENT;
+ 
+ 	return ret;
+ }
+@@ -1182,22 +1239,19 @@ do_replace(void __user *user, unsigned i
+ 
+ 	duprintf("ip_tables: Translated table\n");
+ 
+-	t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex);
+-	if (!t)
++	t = try_then_request_module(find_table_lock(tmp.name),
++				    "ip6table_%s", tmp.name);
++	if (!t || IS_ERR(t)) {
++		ret = t ? PTR_ERR(t) : -ENOENT;
+ 		goto free_newinfo_counters_untrans;
++	}
+ 
+ 	/* You lied! */
+ 	if (tmp.valid_hooks != t->valid_hooks) {
+ 		duprintf("Valid hook crap: %08X vs %08X\n",
+ 			 tmp.valid_hooks, t->valid_hooks);
+ 		ret = -EINVAL;
+-		goto free_newinfo_counters_untrans_unlock;
+-	}
+-
+-	/* Get a reference in advance, we're not allowed fail later */
+-	if (!try_module_get(t->me)) {
+-		ret = -EBUSY;
+-		goto free_newinfo_counters_untrans_unlock;
++		goto put_module;
+ 	}
+ 
+ 	oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
+@@ -1219,7 +1273,6 @@ do_replace(void __user *user, unsigned i
+ 	/* Decrease module usage counts and free resource */
+ 	IP6T_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
+ 	vfree(oldinfo);
+-	/* Silent error: too late now. */
+ 	if (copy_to_user(tmp.counters, counters,
+ 			 sizeof(struct ip6t_counters) * tmp.num_counters) != 0)
+ 		ret = -EFAULT;
+@@ -1229,7 +1282,6 @@ do_replace(void __user *user, unsigned i
+ 
+  put_module:
+ 	module_put(t->me);
+- free_newinfo_counters_untrans_unlock:
+ 	up(&ip6t_mutex);
+  free_newinfo_counters_untrans:
+ 	IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
+@@ -1268,7 +1320,7 @@ do_add_counters(void __user *user, unsig
+ 	unsigned int i;
+ 	struct ip6t_counters_info tmp, *paddc;
+ 	struct ip6t_table *t;
+-	int ret;
++	int ret = 0;
+ 
+ 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
+ 		return -EFAULT;
+@@ -1285,9 +1337,11 @@ do_add_counters(void __user *user, unsig
+ 		goto free;
+ 	}
+ 
+-	t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex);
+-	if (!t)
++	t = find_table_lock(tmp.name);
++	if (!t || IS_ERR(t)) {
++		ret = t ? PTR_ERR(t) : -ENOENT;
+ 		goto free;
++	}
+ 
+ 	write_lock_bh(&t->lock);
+ 	if (t->private->number != paddc->num_counters) {
+@@ -1304,6 +1358,7 @@ do_add_counters(void __user *user, unsig
+  unlock_up_free:
+ 	write_unlock_bh(&t->lock);
+ 	up(&ip6t_mutex);
++	module_put(t->me);
+  free:
+ 	vfree(paddc);
+ 
+@@ -1360,8 +1415,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd
+ 			break;
+ 		}
+ 		name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
+-		t = ip6t_find_table_lock(name, &ret, &ip6t_mutex);
+-		if (t) {
++
++		t = try_then_request_module(find_table_lock(name),
++					    "ip6table_%s", name);
++		if (t && !IS_ERR(t)) {
+ 			struct ip6t_getinfo info;
+ 
+ 			info.valid_hooks = t->valid_hooks;
+@@ -1377,9 +1434,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd
+ 				ret = -EFAULT;
+ 			else
+ 				ret = 0;
+-
+ 			up(&ip6t_mutex);
+-		}
++			module_put(t->me);
++		} else
++			ret = t ? PTR_ERR(t) : -ENOENT;
+ 	}
+ 	break;
+ 
+@@ -1400,6 +1458,31 @@ do_ip6t_get_ctl(struct sock *sk, int cmd
+ 		break;
+ 	}
+ 
++	case IP6T_SO_GET_REVISION_MATCH:
++	case IP6T_SO_GET_REVISION_TARGET: {
++		struct ip6t_get_revision rev;
++		int (*revfn)(const char *, u8, int *);
++
++		if (*len != sizeof(rev)) {
++			ret = -EINVAL;
++			break;
++		}
++		if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
++			ret = -EFAULT;
++			break;
++		}
++
++		if (cmd == IP6T_SO_GET_REVISION_TARGET)
++			revfn = target_revfn;
++		else
++			revfn = match_revfn;
++
++		try_then_request_module(find_revision(rev.name, rev.revision,
++						      revfn, &ret),
++					"ip6t_%s", rev.name);
++		break;
++	}
++
+ 	default:
+ 		duprintf("do_ip6t_get_ctl: unknown request %i\n", cmd);
+ 		ret = -EINVAL;
+@@ -1417,12 +1500,7 @@ ip6t_register_target(struct ip6t_target 
+ 	ret = down_interruptible(&ip6t_mutex);
+ 	if (ret != 0)
+ 		return ret;
+-
+-	if (!list_named_insert(&ip6t_target, target)) {
+-		duprintf("ip6t_register_target: `%s' already in list!\n",
+-			 target->name);
+-		ret = -EINVAL;
+-	}
++	list_add(&target->list, &ip6t_target);
+ 	up(&ip6t_mutex);
+ 	return ret;
+ }
+@@ -1444,11 +1522,7 @@ ip6t_register_match(struct ip6t_match *m
+ 	if (ret != 0)
+ 		return ret;
+ 
+-	if (!list_named_insert(&ip6t_match, match)) {
+-		duprintf("ip6t_register_match: `%s' already in list!\n",
+-			 match->name);
+-		ret = -EINVAL;
+-	}
++	list_add(&match->list, &ip6t_match);
+ 	up(&ip6t_mutex);
+ 
+ 	return ret;
+diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c
+--- a/net/ipv6/netfilter/ip6t_MARK.c
++++ b/net/ipv6/netfilter/ip6t_MARK.c
+@@ -56,8 +56,12 @@ checkentry(const char *tablename,
+ 	return 1;
+ }
+ 
+-static struct ip6t_target ip6t_mark_reg
+-= { { NULL, NULL }, "MARK", target, checkentry, NULL, THIS_MODULE };
++static struct ip6t_target ip6t_mark_reg = {
++	.name 		= "MARK",
++	.target 	= target,
++	.checkentry	= checkentry,
++	.me		= THIS_MODULE
++};
+ 
+ static int __init init(void)
+ {
+diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
+--- a/net/ipv6/proc.c
++++ b/net/ipv6/proc.c
+@@ -140,9 +140,7 @@ fold_field(void *mib[], int offt)
+         unsigned long res = 0;
+         int i;
+  
+-        for (i = 0; i < NR_CPUS; i++) {
+-                if (!cpu_possible(i))
+-                        continue;
++        for_each_cpu(i) {
+                 res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt);
+                 res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt);
+         }
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -483,7 +483,7 @@ restart:
+ 		goto out;
+ 	}
+ 
+-	rt = rt6_device_match(rt, skb->dev->ifindex, 0);
++	rt = rt6_device_match(rt, skb->dev->ifindex, strict);
+ 	BACKTRACK();
+ 
+ 	if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) {
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -740,11 +740,8 @@ int netlink_attachskb(struct sock *sk, s
+ 
+ int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol)
+ {
+-	struct netlink_sock *nlk;
+ 	int len = skb->len;
+ 
+-	nlk = nlk_sk(sk);
+-
+ 	skb_queue_tail(&sk->sk_receive_queue, skb);
+ 	sk->sk_data_ready(sk, len);
+ 	sock_put(sk);
+@@ -827,7 +824,7 @@ struct netlink_broadcast_data {
+ 	int failure;
+ 	int congested;
+ 	int delivered;
+-	unsigned int allocation;
++	gfp_t allocation;
+ 	struct sk_buff *skb, *skb2;
+ };
+ 
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -727,7 +727,7 @@ int rose_rt_ioctl(unsigned int cmd, void
+ 		}
+ 		if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
+ 			return -EINVAL;
+-		if (rose_route.ndigis > 8) /* No more than 8 digipeats */
++		if (rose_route.ndigis > AX25_MAX_DIGIS)
+ 			return -EINVAL;
+ 		err = rose_add_node(&rose_route, dev);
+ 		dev_put(dev);
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -138,6 +138,7 @@ static void rose_heartbeat_expiry(unsign
+ 		   is accepted() it isn't 'dead' so doesn't get removed. */
+ 		if (sock_flag(sk, SOCK_DESTROY) ||
+ 		    (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
++			bh_unlock_sock(sk);
+ 			rose_destroy_socket(sk);
+ 			return;
+ 		}
+diff --git a/net/sctp/proc.c b/net/sctp/proc.c
+--- a/net/sctp/proc.c
++++ b/net/sctp/proc.c
+@@ -69,9 +69,7 @@ fold_field(void *mib[], int nr)
+ 	unsigned long res = 0;
+ 	int i;
+ 
+-	for (i = 0; i < NR_CPUS; i++) {
+-		if (!cpu_possible(i))
+-			continue;
++	for_each_cpu(i) {
+ 		res +=
+ 		    *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
+ 					 sizeof (unsigned long) * nr));
+diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -554,7 +554,7 @@ struct sctp_chunk *sctp_make_datafrag_em
+ 	dp.ppid   = sinfo->sinfo_ppid;
+ 
+ 	/* Set the flags for an unordered send.  */
+-	if (sinfo->sinfo_flags & MSG_UNORDERED) {
++	if (sinfo->sinfo_flags & SCTP_UNORDERED) {
+ 		flags |= SCTP_DATA_UNORDERED;
+ 		dp.ssn = 0;
+ 	} else
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -1010,6 +1010,19 @@ static int __sctp_connect(struct sock* s
+ 					err = -EAGAIN;
+ 					goto out_free;
+ 				}
++			} else {
++				/*
++				 * If an unprivileged user inherits a 1-many 
++				 * style socket with open associations on a 
++				 * privileged port, it MAY be permitted to 
++				 * accept new associations, but it SHOULD NOT 
++				 * be permitted to open new associations.
++				 */
++				if (ep->base.bind_addr.port < PROT_SOCK &&
++				    !capable(CAP_NET_BIND_SERVICE)) {
++					err = -EACCES;
++					goto out_free;
++				}
+ 			}
+ 
+ 			scope = sctp_scope(&to);
+@@ -1389,27 +1402,27 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
+ 	SCTP_DEBUG_PRINTK("msg_len: %zu, sinfo_flags: 0x%x\n",
+ 			  msg_len, sinfo_flags);
+ 
+-	/* MSG_EOF or MSG_ABORT cannot be set on a TCP-style socket. */
+-	if (sctp_style(sk, TCP) && (sinfo_flags & (MSG_EOF | MSG_ABORT))) {
++	/* SCTP_EOF or SCTP_ABORT cannot be set on a TCP-style socket. */
++	if (sctp_style(sk, TCP) && (sinfo_flags & (SCTP_EOF | SCTP_ABORT))) {
+ 		err = -EINVAL;
+ 		goto out_nounlock;
+ 	}
+ 
+-	/* If MSG_EOF is set, no data can be sent. Disallow sending zero
+-	 * length messages when MSG_EOF|MSG_ABORT is not set.
+-	 * If MSG_ABORT is set, the message length could be non zero with
++	/* If SCTP_EOF is set, no data can be sent. Disallow sending zero
++	 * length messages when SCTP_EOF|SCTP_ABORT is not set.
++	 * If SCTP_ABORT is set, the message length could be non zero with
+ 	 * the msg_iov set to the user abort reason.
+  	 */
+-	if (((sinfo_flags & MSG_EOF) && (msg_len > 0)) ||
+-	    (!(sinfo_flags & (MSG_EOF|MSG_ABORT)) && (msg_len == 0))) {
++	if (((sinfo_flags & SCTP_EOF) && (msg_len > 0)) ||
++	    (!(sinfo_flags & (SCTP_EOF|SCTP_ABORT)) && (msg_len == 0))) {
+ 		err = -EINVAL;
+ 		goto out_nounlock;
+ 	}
+ 
+-	/* If MSG_ADDR_OVER is set, there must be an address
++	/* If SCTP_ADDR_OVER is set, there must be an address
+ 	 * specified in msg_name.
+ 	 */
+-	if ((sinfo_flags & MSG_ADDR_OVER) && (!msg->msg_name)) {
++	if ((sinfo_flags & SCTP_ADDR_OVER) && (!msg->msg_name)) {
+ 		err = -EINVAL;
+ 		goto out_nounlock;
+ 	}
+@@ -1458,14 +1471,14 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
+ 			goto out_unlock;
+ 		}
+ 
+-		if (sinfo_flags & MSG_EOF) {
++		if (sinfo_flags & SCTP_EOF) {
+ 			SCTP_DEBUG_PRINTK("Shutting down association: %p\n",
+ 					  asoc);
+ 			sctp_primitive_SHUTDOWN(asoc, NULL);
+ 			err = 0;
+ 			goto out_unlock;
+ 		}
+-		if (sinfo_flags & MSG_ABORT) {
++		if (sinfo_flags & SCTP_ABORT) {
+ 			SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
+ 			sctp_primitive_ABORT(asoc, msg);
+ 			err = 0;
+@@ -1477,7 +1490,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
+ 	if (!asoc) {
+ 		SCTP_DEBUG_PRINTK("There is no association yet.\n");
+ 
+-		if (sinfo_flags & (MSG_EOF | MSG_ABORT)) {
++		if (sinfo_flags & (SCTP_EOF | SCTP_ABORT)) {
+ 			err = -EINVAL;
+ 			goto out_unlock;
+ 		}
+@@ -1515,6 +1528,19 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
+ 				err = -EAGAIN;
+ 				goto out_unlock;
+ 			}
++		} else {
++			/*
++			 * If an unprivileged user inherits a one-to-many
++			 * style socket with open associations on a privileged
++			 * port, it MAY be permitted to accept new associations,
++			 * but it SHOULD NOT be permitted to open new
++			 * associations.
++			 */
++			if (ep->base.bind_addr.port < PROT_SOCK &&
++			    !capable(CAP_NET_BIND_SERVICE)) {
++				err = -EACCES;
++				goto out_unlock;
++			}
+ 		}
+ 
+ 		scope = sctp_scope(&to);
+@@ -1611,10 +1637,10 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
+ 
+ 	/* If an address is passed with the sendto/sendmsg call, it is used
+ 	 * to override the primary destination address in the TCP model, or
+-	 * when MSG_ADDR_OVER flag is set in the UDP model.
++	 * when SCTP_ADDR_OVER flag is set in the UDP model.
+ 	 */
+ 	if ((sctp_style(sk, TCP) && msg_name) ||
+-	    (sinfo_flags & MSG_ADDR_OVER)) {
++	    (sinfo_flags & SCTP_ADDR_OVER)) {
+ 		chunk_tp = sctp_assoc_lookup_paddr(asoc, &to);
+ 		if (!chunk_tp) {
+ 			err = -EINVAL;
+@@ -2306,16 +2332,14 @@ static int sctp_setsockopt_maxseg(struct
+ 		return -EINVAL;
+ 	if (get_user(val, (int __user *)optval))
+ 		return -EFAULT;
+-	if ((val < 8) || (val > SCTP_MAX_CHUNK_LEN))
++	if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN)))
+ 		return -EINVAL;
+ 	sp->user_frag = val;
+ 
+-	if (val) {
+-		/* Update the frag_point of the existing associations. */
+-		list_for_each(pos, &(sp->ep->asocs)) {
+-			asoc = list_entry(pos, struct sctp_association, asocs);
+-			asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); 
+-		}
++	/* Update the frag_point of the existing associations. */
++	list_for_each(pos, &(sp->ep->asocs)) {
++		asoc = list_entry(pos, struct sctp_association, asocs);
++		asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); 
+ 	}
+ 
+ 	return 0;
+@@ -2384,14 +2408,14 @@ static int sctp_setsockopt_peer_primary_
+ static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval,
+ 					  int optlen)
+ {
+-	__u32 val;
++	struct sctp_setadaption adaption;
+ 
+-	if (optlen < sizeof(__u32))
++	if (optlen != sizeof(struct sctp_setadaption))
+ 		return -EINVAL;
+-	if (copy_from_user(&val, optval, sizeof(__u32)))
++	if (copy_from_user(&adaption, optval, optlen)) 
+ 		return -EFAULT;
+ 
+-	sctp_sk(sk)->adaption_ind = val;
++	sctp_sk(sk)->adaption_ind = adaption.ssb_adaption_ind;
+ 
+ 	return 0;
+ }
+@@ -3672,17 +3696,15 @@ static int sctp_getsockopt_primary_addr(
+ static int sctp_getsockopt_adaption_layer(struct sock *sk, int len,
+ 				  char __user *optval, int __user *optlen)
+ {
+-	__u32 val;
++	struct sctp_setadaption adaption;
+ 
+-	if (len < sizeof(__u32))
++	if (len != sizeof(struct sctp_setadaption))
+ 		return -EINVAL;
+ 
+-	len = sizeof(__u32);
+-	val = sctp_sk(sk)->adaption_ind;
+-	if (put_user(len, optlen))
+-		return -EFAULT;
+-	if (copy_to_user(optval, &val, len))
++	adaption.ssb_adaption_ind = sctp_sk(sk)->adaption_ind;
++	if (copy_to_user(optval, &adaption, len))
+ 		return -EFAULT;
++
+ 	return 0;
+ }
+ 
+@@ -4640,8 +4662,8 @@ SCTP_STATIC int sctp_msghdr_parse(const 
+ 
+ 			/* Minimally, validate the sinfo_flags. */
+ 			if (cmsgs->info->sinfo_flags &
+-			    ~(MSG_UNORDERED | MSG_ADDR_OVER |
+-			      MSG_ABORT | MSG_EOF))
++			    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
++			      SCTP_ABORT | SCTP_EOF))
+ 				return -EINVAL;
+ 			break;
+ 
+diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
+--- a/net/sctp/ulpevent.c
++++ b/net/sctp/ulpevent.c
+@@ -698,7 +698,7 @@ struct sctp_ulpevent *sctp_ulpevent_make
+ 	event->ssn = ntohs(chunk->subh.data_hdr->ssn);
+ 	event->ppid = chunk->subh.data_hdr->ppid;
+ 	if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
+-		event->flags |= MSG_UNORDERED;
++		event->flags |= SCTP_UNORDERED;
+ 		event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
+ 	}
+ 	event->tsn = ntohl(chunk->subh.data_hdr->tsn);
+@@ -824,7 +824,7 @@ void sctp_ulpevent_read_sndrcvinfo(const
+ 	 *
+ 	 * recvmsg() flags:
+ 	 *
+-	 * MSG_UNORDERED - This flag is present when the message was sent
++	 * SCTP_UNORDERED - This flag is present when the message was sent
+ 	 *                 non-ordered.
+ 	 */
+ 	sinfo.sinfo_flags = event->flags;
+@@ -839,7 +839,7 @@ void sctp_ulpevent_read_sndrcvinfo(const
+ 	 * This field will hold the current cumulative TSN as
+ 	 * known by the underlying SCTP layer.  Note this field is
+ 	 * ignored when sending and only valid for a receive
+-	 * operation when sinfo_flags are set to MSG_UNORDERED.
++	 * operation when sinfo_flags are set to SCTP_UNORDERED.
+ 	 */
+ 	sinfo.sinfo_cumtsn = event->cumtsn;
+ 	/* sinfo_assoc_id: sizeof (sctp_assoc_t)
+diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
+--- a/net/sunrpc/Makefile
++++ b/net/sunrpc/Makefile
+@@ -6,7 +6,7 @@
+ obj-$(CONFIG_SUNRPC) += sunrpc.o
+ obj-$(CONFIG_SUNRPC_GSS) += auth_gss/
+ 
+-sunrpc-y := clnt.o xprt.o sched.o \
++sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
+ 	    auth.o auth_null.o auth_unix.o \
+ 	    svc.o svcsock.o svcauth.o svcauth_unix.o \
+ 	    pmap_clnt.o timer.o xdr.o \
+diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
+--- a/net/sunrpc/auth.c
++++ b/net/sunrpc/auth.c
+@@ -11,7 +11,6 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/errno.h>
+-#include <linux/socket.h>
+ #include <linux/sunrpc/clnt.h>
+ #include <linux/spinlock.h>
+ 
+diff --git a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile
+--- a/net/sunrpc/auth_gss/Makefile
++++ b/net/sunrpc/auth_gss/Makefile
+@@ -10,7 +10,7 @@ auth_rpcgss-objs := auth_gss.o gss_gener
+ obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o
+ 
+ rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \
+-	gss_krb5_seqnum.o
++	gss_krb5_seqnum.o gss_krb5_wrap.o
+ 
+ obj-$(CONFIG_RPCSEC_GSS_SPKM3) += rpcsec_gss_spkm3.o
+ 
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -42,9 +42,8 @@
+ #include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/slab.h>
+-#include <linux/socket.h>
+-#include <linux/in.h>
+ #include <linux/sched.h>
++#include <linux/pagemap.h>
+ #include <linux/sunrpc/clnt.h>
+ #include <linux/sunrpc/auth.h>
+ #include <linux/sunrpc/auth_gss.h>
+@@ -846,10 +845,8 @@ gss_marshal(struct rpc_task *task, u32 *
+ 
+ 	/* We compute the checksum for the verifier over the xdr-encoded bytes
+ 	 * starting with the xid and ending at the end of the credential: */
+-	iov.iov_base = req->rq_snd_buf.head[0].iov_base;
+-	if (task->tk_client->cl_xprt->stream)
+-		/* See clnt.c:call_header() */
+-		iov.iov_base += 4;
++	iov.iov_base = xprt_skip_transport_header(task->tk_xprt,
++					req->rq_snd_buf.head[0].iov_base);
+ 	iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
+ 	xdr_buf_from_iov(&iov, &verf_buf);
+ 
+@@ -857,9 +854,7 @@ gss_marshal(struct rpc_task *task, u32 *
+ 	*p++ = htonl(RPC_AUTH_GSS);
+ 
+ 	mic.data = (u8 *)(p + 1);
+-	maj_stat = gss_get_mic(ctx->gc_gss_ctx,
+-			       GSS_C_QOP_DEFAULT, 
+-			       &verf_buf, &mic);
++	maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
+ 	if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
+ 		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+ 	} else if (maj_stat != 0) {
+@@ -890,10 +885,8 @@ static u32 *
+ gss_validate(struct rpc_task *task, u32 *p)
+ {
+ 	struct rpc_cred *cred = task->tk_msg.rpc_cred;
+-	struct gss_cred	*gss_cred = container_of(cred, struct gss_cred,
+-						gc_base);
+ 	struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
+-	u32		seq, qop_state;
++	u32		seq;
+ 	struct kvec	iov;
+ 	struct xdr_buf	verf_buf;
+ 	struct xdr_netobj mic;
+@@ -914,23 +907,14 @@ gss_validate(struct rpc_task *task, u32 
+ 	mic.data = (u8 *)p;
+ 	mic.len = len;
+ 
+-	maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic, &qop_state);
++	maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
+ 	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+ 		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+ 	if (maj_stat)
+ 		goto out_bad;
+-       switch (gss_cred->gc_service) {
+-       case RPC_GSS_SVC_NONE:
+-	       /* verifier data, flavor, length: */
+-	       task->tk_auth->au_rslack = XDR_QUADLEN(len) + 2;
+-	       break;
+-       case RPC_GSS_SVC_INTEGRITY:
+-	       /* verifier data, flavor, length, length, sequence number: */
+-	       task->tk_auth->au_rslack = XDR_QUADLEN(len) + 4;
+-	       break;
+-       case RPC_GSS_SVC_PRIVACY:
+-	       goto out_bad;
+-       }
++	/* We leave it to unwrap to calculate au_rslack. For now we just
++	 * calculate the length of the verifier: */
++	task->tk_auth->au_verfsize = XDR_QUADLEN(len) + 2;
+ 	gss_put_ctx(ctx);
+ 	dprintk("RPC: %4u GSS gss_validate: gss_verify_mic succeeded.\n",
+ 			task->tk_pid);
+@@ -975,8 +959,7 @@ gss_wrap_req_integ(struct rpc_cred *cred
+ 	p = iov->iov_base + iov->iov_len;
+ 	mic.data = (u8 *)(p + 1);
+ 
+-	maj_stat = gss_get_mic(ctx->gc_gss_ctx,
+-			GSS_C_QOP_DEFAULT, &integ_buf, &mic);
++	maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
+ 	status = -EIO; /* XXX? */
+ 	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+ 		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+@@ -990,6 +973,113 @@ gss_wrap_req_integ(struct rpc_cred *cred
+ 	return 0;
+ }
+ 
++static void
++priv_release_snd_buf(struct rpc_rqst *rqstp)
++{
++	int i;
++
++	for (i=0; i < rqstp->rq_enc_pages_num; i++)
++		__free_page(rqstp->rq_enc_pages[i]);
++	kfree(rqstp->rq_enc_pages);
++}
++
++static int
++alloc_enc_pages(struct rpc_rqst *rqstp)
++{
++	struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
++	int first, last, i;
++
++	if (snd_buf->page_len == 0) {
++		rqstp->rq_enc_pages_num = 0;
++		return 0;
++	}
++
++	first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
++	last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT;
++	rqstp->rq_enc_pages_num = last - first + 1 + 1;
++	rqstp->rq_enc_pages
++		= kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *),
++				GFP_NOFS);
++	if (!rqstp->rq_enc_pages)
++		goto out;
++	for (i=0; i < rqstp->rq_enc_pages_num; i++) {
++		rqstp->rq_enc_pages[i] = alloc_page(GFP_NOFS);
++		if (rqstp->rq_enc_pages[i] == NULL)
++			goto out_free;
++	}
++	rqstp->rq_release_snd_buf = priv_release_snd_buf;
++	return 0;
++out_free:
++	for (i--; i >= 0; i--) {
++		__free_page(rqstp->rq_enc_pages[i]);
++	}
++out:
++	return -EAGAIN;
++}
++
++static inline int
++gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
++		kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
++{
++	struct xdr_buf	*snd_buf = &rqstp->rq_snd_buf;
++	u32		offset;
++	u32             maj_stat;
++	int		status;
++	u32		*opaque_len;
++	struct page	**inpages;
++	int		first;
++	int		pad;
++	struct kvec	*iov;
++	char		*tmp;
++
++	opaque_len = p++;
++	offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
++	*p++ = htonl(rqstp->rq_seqno);
++
++	status = encode(rqstp, p, obj);
++	if (status)
++		return status;
++
++	status = alloc_enc_pages(rqstp);
++	if (status)
++		return status;
++	first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
++	inpages = snd_buf->pages + first;
++	snd_buf->pages = rqstp->rq_enc_pages;
++	snd_buf->page_base -= first << PAGE_CACHE_SHIFT;
++	/* Give the tail its own page, in case we need extra space in the
++	 * head when wrapping: */
++	if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
++		tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
++		memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
++		snd_buf->tail[0].iov_base = tmp;
++	}
++	maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
++	/* RPC_SLACK_SPACE should prevent this ever happening: */
++	BUG_ON(snd_buf->len > snd_buf->buflen);
++        status = -EIO;
++	/* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
++	 * done anyway, so it's safe to put the request on the wire: */
++	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
++		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
++	else if (maj_stat)
++		return status;
++
++	*opaque_len = htonl(snd_buf->len - offset);
++	/* guess whether we're in the head or the tail: */
++	if (snd_buf->page_len || snd_buf->tail[0].iov_len)
++		iov = snd_buf->tail;
++	else
++		iov = snd_buf->head;
++	p = iov->iov_base + iov->iov_len;
++	pad = 3 - ((snd_buf->len - offset - 1) & 3);
++	memset(p, 0, pad);
++	iov->iov_len += pad;
++	snd_buf->len += pad;
++
++	return 0;
++}
++
+ static int
+ gss_wrap_req(struct rpc_task *task,
+ 	     kxdrproc_t encode, void *rqstp, u32 *p, void *obj)
+@@ -1017,6 +1107,8 @@ gss_wrap_req(struct rpc_task *task,
+ 								rqstp, p, obj);
+ 			break;
+        		case RPC_GSS_SVC_PRIVACY:
++			status = gss_wrap_req_priv(cred, ctx, encode,
++					rqstp, p, obj);
+ 			break;
+ 	}
+ out:
+@@ -1054,15 +1146,43 @@ gss_unwrap_resp_integ(struct rpc_cred *c
+ 	if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
+ 		return status;
+ 
+-	maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf,
+-			&mic, NULL);
++	maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
++	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
++		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
++	if (maj_stat != GSS_S_COMPLETE)
++		return status;
++	return 0;
++}
++
++static inline int
++gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
++		struct rpc_rqst *rqstp, u32 **p)
++{
++	struct xdr_buf  *rcv_buf = &rqstp->rq_rcv_buf;
++	u32 offset;
++	u32 opaque_len;
++	u32 maj_stat;
++	int status = -EIO;
++
++	opaque_len = ntohl(*(*p)++);
++	offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
++	if (offset + opaque_len > rcv_buf->len)
++		return status;
++	/* remove padding: */
++	rcv_buf->len = offset + opaque_len;
++
++	maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
+ 	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+ 		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+ 	if (maj_stat != GSS_S_COMPLETE)
+ 		return status;
++	if (ntohl(*(*p)++) != rqstp->rq_seqno)
++		return status;
++
+ 	return 0;
+ }
+ 
++
+ static int
+ gss_unwrap_resp(struct rpc_task *task,
+ 		kxdrproc_t decode, void *rqstp, u32 *p, void *obj)
+@@ -1071,6 +1191,9 @@ gss_unwrap_resp(struct rpc_task *task,
+ 	struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
+ 			gc_base);
+ 	struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
++	u32		*savedp = p;
++	struct kvec	*head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
++	int		savedlen = head->iov_len;
+ 	int             status = -EIO;
+ 
+ 	if (ctx->gc_proc != RPC_GSS_PROC_DATA)
+@@ -1084,8 +1207,14 @@ gss_unwrap_resp(struct rpc_task *task,
+ 				goto out;
+ 			break;
+        		case RPC_GSS_SVC_PRIVACY:
++			status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
++			if (status)
++				goto out;
+ 			break;
+ 	}
++	/* take into account extra slack for integrity and privacy cases: */
++	task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp)
++						+ (savedlen - head->iov_len);
+ out_decode:
+ 	status = decode(rqstp, p, obj);
+ out:
+diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
+--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
++++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
+@@ -37,7 +37,7 @@
+ #include <linux/types.h>
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+-#include <asm/scatterlist.h>
++#include <linux/scatterlist.h>
+ #include <linux/crypto.h>
+ #include <linux/highmem.h>
+ #include <linux/pagemap.h>
+@@ -75,9 +75,7 @@ krb5_encrypt(
+ 		memcpy(local_iv, iv, crypto_tfm_alg_ivsize(tfm));
+ 
+ 	memcpy(out, in, length);
+-	sg[0].page = virt_to_page(out);
+-	sg[0].offset = offset_in_page(out);
+-	sg[0].length = length;
++	sg_set_buf(sg, out, length);
+ 
+ 	ret = crypto_cipher_encrypt_iv(tfm, sg, sg, length, local_iv);
+ 
+@@ -117,9 +115,7 @@ krb5_decrypt(
+ 		memcpy(local_iv,iv, crypto_tfm_alg_ivsize(tfm));
+ 
+ 	memcpy(out, in, length);
+-	sg[0].page = virt_to_page(out);
+-	sg[0].offset = offset_in_page(out);
+-	sg[0].length = length;
++	sg_set_buf(sg, out, length);
+ 
+ 	ret = crypto_cipher_decrypt_iv(tfm, sg, sg, length, local_iv);
+ 
+@@ -132,24 +128,91 @@ out:
+ 
+ EXPORT_SYMBOL(krb5_decrypt);
+ 
+-static void
+-buf_to_sg(struct scatterlist *sg, char *ptr, int len) {
+-	sg->page = virt_to_page(ptr);
+-	sg->offset = offset_in_page(ptr);
+-	sg->length = len;
++static int
++process_xdr_buf(struct xdr_buf *buf, int offset, int len,
++		int (*actor)(struct scatterlist *, void *), void *data)
++{
++	int i, page_len, thislen, page_offset, ret = 0;
++	struct scatterlist	sg[1];
++
++	if (offset >= buf->head[0].iov_len) {
++		offset -= buf->head[0].iov_len;
++	} else {
++		thislen = buf->head[0].iov_len - offset;
++		if (thislen > len)
++			thislen = len;
++		sg_set_buf(sg, buf->head[0].iov_base + offset, thislen);
++		ret = actor(sg, data);
++		if (ret)
++			goto out;
++		offset = 0;
++		len -= thislen;
++	}
++	if (len == 0)
++		goto out;
++
++	if (offset >= buf->page_len) {
++		offset -= buf->page_len;
++	} else {
++		page_len = buf->page_len - offset;
++		if (page_len > len)
++			page_len = len;
++		len -= page_len;
++		page_offset = (offset + buf->page_base) & (PAGE_CACHE_SIZE - 1);
++		i = (offset + buf->page_base) >> PAGE_CACHE_SHIFT;
++		thislen = PAGE_CACHE_SIZE - page_offset;
++		do {
++			if (thislen > page_len)
++				thislen = page_len;
++			sg->page = buf->pages[i];
++			sg->offset = page_offset;
++			sg->length = thislen;
++			ret = actor(sg, data);
++			if (ret)
++				goto out;
++			page_len -= thislen;
++			i++;
++			page_offset = 0;
++			thislen = PAGE_CACHE_SIZE;
++		} while (page_len != 0);
++		offset = 0;
++	}
++	if (len == 0)
++		goto out;
++
++	if (offset < buf->tail[0].iov_len) {
++		thislen = buf->tail[0].iov_len - offset;
++		if (thislen > len)
++			thislen = len;
++		sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen);
++		ret = actor(sg, data);
++		len -= thislen;
++	}
++	if (len != 0)
++		ret = -EINVAL;
++out:
++	return ret;
++}
++
++static int
++checksummer(struct scatterlist *sg, void *data)
++{
++	struct crypto_tfm *tfm = (struct crypto_tfm *)data;
++
++	crypto_digest_update(tfm, sg, 1);
++
++	return 0;
+ }
+ 
+ /* checksum the plaintext data and hdrlen bytes of the token header */
+ s32
+ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
+-		   struct xdr_netobj *cksum)
++		   int body_offset, struct xdr_netobj *cksum)
+ {
+ 	char                            *cksumname;
+ 	struct crypto_tfm               *tfm = NULL; /* XXX add to ctx? */
+ 	struct scatterlist              sg[1];
+ 	u32                             code = GSS_S_FAILURE;
+-	int				len, thislen, offset;
+-	int				i;
+ 
+ 	switch (cksumtype) {
+ 		case CKSUMTYPE_RSA_MD5:
+@@ -167,35 +230,10 @@ make_checksum(s32 cksumtype, char *heade
+ 		goto out;
+ 
+ 	crypto_digest_init(tfm);
+-	buf_to_sg(sg, header, hdrlen);
++	sg_set_buf(sg, header, hdrlen);
+ 	crypto_digest_update(tfm, sg, 1);
+-	if (body->head[0].iov_len) {
+-		buf_to_sg(sg, body->head[0].iov_base, body->head[0].iov_len);
+-		crypto_digest_update(tfm, sg, 1);
+-	}
+-
+-	len = body->page_len;
+-	if (len != 0) {
+-		offset = body->page_base & (PAGE_CACHE_SIZE - 1);
+-		i = body->page_base >> PAGE_CACHE_SHIFT;
+-		thislen = PAGE_CACHE_SIZE - offset;
+-		do {
+-			if (thislen > len)
+-				thislen = len;
+-			sg->page = body->pages[i];
+-			sg->offset = offset;
+-			sg->length = thislen;
+-			crypto_digest_update(tfm, sg, 1);
+-			len -= thislen;
+-			i++;
+-			offset = 0;
+-			thislen = PAGE_CACHE_SIZE;
+-		} while(len != 0);
+-	}
+-	if (body->tail[0].iov_len) {
+-		buf_to_sg(sg, body->tail[0].iov_base, body->tail[0].iov_len);
+-		crypto_digest_update(tfm, sg, 1);
+-	}
++	process_xdr_buf(body, body_offset, body->len - body_offset,
++			checksummer, tfm);
+ 	crypto_digest_final(tfm, cksum->data);
+ 	code = 0;
+ out:
+@@ -204,3 +242,154 @@ out:
+ }
+ 
+ EXPORT_SYMBOL(make_checksum);
++
++struct encryptor_desc {
++	u8 iv[8]; /* XXX hard-coded blocksize */
++	struct crypto_tfm *tfm;
++	int pos;
++	struct xdr_buf *outbuf;
++	struct page **pages;
++	struct scatterlist infrags[4];
++	struct scatterlist outfrags[4];
++	int fragno;
++	int fraglen;
++};
++
++static int
++encryptor(struct scatterlist *sg, void *data)
++{
++	struct encryptor_desc *desc = data;
++	struct xdr_buf *outbuf = desc->outbuf;
++	struct page *in_page;
++	int thislen = desc->fraglen + sg->length;
++	int fraglen, ret;
++	int page_pos;
++
++	/* Worst case is 4 fragments: head, end of page 1, start
++	 * of page 2, tail.  Anything more is a bug. */
++	BUG_ON(desc->fragno > 3);
++	desc->infrags[desc->fragno] = *sg;
++	desc->outfrags[desc->fragno] = *sg;
++
++	page_pos = desc->pos - outbuf->head[0].iov_len;
++	if (page_pos >= 0 && page_pos < outbuf->page_len) {
++		/* pages are not in place: */
++		int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
++		in_page = desc->pages[i];
++	} else {
++		in_page = sg->page;
++	}
++	desc->infrags[desc->fragno].page = in_page;
++	desc->fragno++;
++	desc->fraglen += sg->length;
++	desc->pos += sg->length;
++
++	fraglen = thislen & 7; /* XXX hardcoded blocksize */
++	thislen -= fraglen;
++
++	if (thislen == 0)
++		return 0;
++
++	ret = crypto_cipher_encrypt_iv(desc->tfm, desc->outfrags, desc->infrags,
++					thislen, desc->iv);
++	if (ret)
++		return ret;
++	if (fraglen) {
++		desc->outfrags[0].page = sg->page;
++		desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
++		desc->outfrags[0].length = fraglen;
++		desc->infrags[0] = desc->outfrags[0];
++		desc->infrags[0].page = in_page;
++		desc->fragno = 1;
++		desc->fraglen = fraglen;
++	} else {
++		desc->fragno = 0;
++		desc->fraglen = 0;
++	}
++	return 0;
++}
++
++int
++gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset,
++		struct page **pages)
++{
++	int ret;
++	struct encryptor_desc desc;
++
++	BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0);
++
++	memset(desc.iv, 0, sizeof(desc.iv));
++	desc.tfm = tfm;
++	desc.pos = offset;
++	desc.outbuf = buf;
++	desc.pages = pages;
++	desc.fragno = 0;
++	desc.fraglen = 0;
++
++	ret = process_xdr_buf(buf, offset, buf->len - offset, encryptor, &desc);
++	return ret;
++}
++
++EXPORT_SYMBOL(gss_encrypt_xdr_buf);
++
++struct decryptor_desc {
++	u8 iv[8]; /* XXX hard-coded blocksize */
++	struct crypto_tfm *tfm;
++	struct scatterlist frags[4];
++	int fragno;
++	int fraglen;
++};
++
++static int
++decryptor(struct scatterlist *sg, void *data)
++{
++	struct decryptor_desc *desc = data;
++	int thislen = desc->fraglen + sg->length;
++	int fraglen, ret;
++
++	/* Worst case is 4 fragments: head, end of page 1, start
++	 * of page 2, tail.  Anything more is a bug. */
++	BUG_ON(desc->fragno > 3);
++	desc->frags[desc->fragno] = *sg;
++	desc->fragno++;
++	desc->fraglen += sg->length;
++
++	fraglen = thislen & 7; /* XXX hardcoded blocksize */
++	thislen -= fraglen;
++
++	if (thislen == 0)
++		return 0;
++
++	ret = crypto_cipher_decrypt_iv(desc->tfm, desc->frags, desc->frags,
++					thislen, desc->iv);
++	if (ret)
++		return ret;
++	if (fraglen) {
++		desc->frags[0].page = sg->page;
++		desc->frags[0].offset = sg->offset + sg->length - fraglen;
++		desc->frags[0].length = fraglen;
++		desc->fragno = 1;
++		desc->fraglen = fraglen;
++	} else {
++		desc->fragno = 0;
++		desc->fraglen = 0;
++	}
++	return 0;
++}
++
++int
++gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset)
++{
++	struct decryptor_desc desc;
++
++	/* XXXJBF: */
++	BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0);
++
++	memset(desc.iv, 0, sizeof(desc.iv));
++	desc.tfm = tfm;
++	desc.fragno = 0;
++	desc.fraglen = 0;
++	return process_xdr_buf(buf, offset, buf->len - offset, decryptor, &desc);
++}
++
++EXPORT_SYMBOL(gss_decrypt_xdr_buf);
+diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
+--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
++++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
+@@ -39,7 +39,6 @@
+ #include <linux/types.h>
+ #include <linux/slab.h>
+ #include <linux/sunrpc/auth.h>
+-#include <linux/in.h>
+ #include <linux/sunrpc/gss_krb5.h>
+ #include <linux/sunrpc/xdr.h>
+ #include <linux/crypto.h>
+@@ -191,43 +190,12 @@ gss_delete_sec_context_kerberos(void *in
+ 	kfree(kctx);
+ }
+ 
+-static u32
+-gss_verify_mic_kerberos(struct gss_ctx		*ctx,
+-			struct xdr_buf		*message,
+-			struct xdr_netobj	*mic_token,
+-			u32			*qstate) {
+-	u32 maj_stat = 0;
+-	int qop_state;
+-	struct krb5_ctx *kctx = ctx->internal_ctx_id;
+-
+-	maj_stat = krb5_read_token(kctx, mic_token, message, &qop_state,
+-				   KG_TOK_MIC_MSG);
+-	if (!maj_stat && qop_state)
+-	    *qstate = qop_state;
+-
+-	dprintk("RPC:      gss_verify_mic_kerberos returning %d\n", maj_stat);
+-	return maj_stat;
+-}
+-
+-static u32
+-gss_get_mic_kerberos(struct gss_ctx	*ctx,
+-		     u32		qop,
+-		     struct xdr_buf 	*message,
+-		     struct xdr_netobj	*mic_token) {
+-	u32 err = 0;
+-	struct krb5_ctx *kctx = ctx->internal_ctx_id;
+-
+-	err = krb5_make_token(kctx, qop, message, mic_token, KG_TOK_MIC_MSG);
+-
+-	dprintk("RPC:      gss_get_mic_kerberos returning %d\n",err);
+-
+-	return err;
+-}
+-
+ static struct gss_api_ops gss_kerberos_ops = {
+ 	.gss_import_sec_context	= gss_import_sec_context_kerberos,
+ 	.gss_get_mic		= gss_get_mic_kerberos,
+ 	.gss_verify_mic		= gss_verify_mic_kerberos,
++	.gss_wrap		= gss_wrap_kerberos,
++	.gss_unwrap		= gss_unwrap_kerberos,
+ 	.gss_delete_sec_context	= gss_delete_sec_context_kerberos,
+ };
+ 
+@@ -242,6 +210,11 @@ static struct pf_desc gss_kerberos_pfs[]
+ 		.service = RPC_GSS_SVC_INTEGRITY,
+ 		.name = "krb5i",
+ 	},
++	[2] = {
++		.pseudoflavor = RPC_AUTH_GSS_KRB5P,
++		.service = RPC_GSS_SVC_PRIVACY,
++		.name = "krb5p",
++	},
+ };
+ 
+ static struct gss_api_mech gss_kerberos_mech = {
+diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
+--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
++++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
+@@ -70,22 +70,13 @@
+ # define RPCDBG_FACILITY        RPCDBG_AUTH
+ #endif
+ 
+-static inline int
+-gss_krb5_padding(int blocksize, int length) {
+-	/* Most of the code is block-size independent but in practice we
+-	 * use only 8: */
+-	BUG_ON(blocksize != 8);
+-	return 8 - (length & 7);
+-}
+-
+ u32
+-krb5_make_token(struct krb5_ctx *ctx, int qop_req,
+-		   struct xdr_buf *text, struct xdr_netobj *token,
+-		   int toktype)
++gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
++		struct xdr_netobj *token)
+ {
++	struct krb5_ctx		*ctx = gss_ctx->internal_ctx_id;
+ 	s32			checksum_type;
+ 	struct xdr_netobj	md5cksum = {.len = 0, .data = NULL};
+-	int			blocksize = 0, tmsglen;
+ 	unsigned char		*ptr, *krb5_hdr, *msg_start;
+ 	s32			now;
+ 
+@@ -93,9 +84,6 @@ krb5_make_token(struct krb5_ctx *ctx, in
+ 
+ 	now = get_seconds();
+ 
+-	if (qop_req != 0)
+-		goto out_err;
+-
+ 	switch (ctx->signalg) {
+ 		case SGN_ALG_DES_MAC_MD5:
+ 			checksum_type = CKSUMTYPE_RSA_MD5;
+@@ -111,21 +99,13 @@ krb5_make_token(struct krb5_ctx *ctx, in
+ 		goto out_err;
+ 	}
+ 
+-	if (toktype == KG_TOK_WRAP_MSG) {
+-		blocksize = crypto_tfm_alg_blocksize(ctx->enc);
+-		tmsglen = blocksize + text->len
+-			+ gss_krb5_padding(blocksize, blocksize + text->len);
+-	} else {
+-		tmsglen = 0;
+-	}
+-
+-	token->len = g_token_size(&ctx->mech_used, 22 + tmsglen);
++	token->len = g_token_size(&ctx->mech_used, 22);
+ 
+ 	ptr = token->data;
+-	g_make_token_header(&ctx->mech_used, 22 + tmsglen, &ptr);
++	g_make_token_header(&ctx->mech_used, 22, &ptr);
+ 
+-	*ptr++ = (unsigned char) ((toktype>>8)&0xff);
+-	*ptr++ = (unsigned char) (toktype&0xff);
++	*ptr++ = (unsigned char) ((KG_TOK_MIC_MSG>>8)&0xff);
++	*ptr++ = (unsigned char) (KG_TOK_MIC_MSG&0xff);
+ 
+ 	/* ptr now at byte 2 of header described in rfc 1964, section 1.2.1: */
+ 	krb5_hdr = ptr - 2;
+@@ -133,17 +113,9 @@ krb5_make_token(struct krb5_ctx *ctx, in
+ 
+ 	*(u16 *)(krb5_hdr + 2) = htons(ctx->signalg);
+ 	memset(krb5_hdr + 4, 0xff, 4);
+-	if (toktype == KG_TOK_WRAP_MSG)
+-		*(u16 *)(krb5_hdr + 4) = htons(ctx->sealalg);
+ 
+-	if (toktype == KG_TOK_WRAP_MSG) {
+-		/* XXX removing support for now */
+-		goto out_err;
+-	} else { /* Sign only.  */
+-		if (make_checksum(checksum_type, krb5_hdr, 8, text,
+-				       &md5cksum))
++	if (make_checksum(checksum_type, krb5_hdr, 8, text, 0, &md5cksum))
+ 			goto out_err;
+-	}
+ 
+ 	switch (ctx->signalg) {
+ 	case SGN_ALG_DES_MAC_MD5:
+diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
+--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
++++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
+@@ -68,21 +68,14 @@
+ #endif
+ 
+ 
+-/* message_buffer is an input if toktype is MIC and an output if it is WRAP:
+- * If toktype is MIC: read_token is a mic token, and message_buffer is the
+- *   data that the mic was supposedly taken over.
+- * If toktype is WRAP: read_token is a wrap token, and message_buffer is used
+- *   to return the decrypted data.
+- */
++/* read_token is a mic token, and message_buffer is the data that the mic was
++ * supposedly taken over. */
+ 
+-/* XXX will need to change prototype and/or just split into a separate function
+- * when we add privacy (because read_token will be in pages too). */
+ u32
+-krb5_read_token(struct krb5_ctx *ctx,
+-		struct xdr_netobj *read_token,
+-		struct xdr_buf *message_buffer,
+-		int *qop_state, int toktype)
++gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
++		struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
+ {
++	struct krb5_ctx		*ctx = gss_ctx->internal_ctx_id;
+ 	int			signalg;
+ 	int			sealalg;
+ 	s32			checksum_type;
+@@ -100,16 +93,12 @@ krb5_read_token(struct krb5_ctx *ctx,
+ 					read_token->len))
+ 		goto out;
+ 
+-	if ((*ptr++ != ((toktype>>8)&0xff)) || (*ptr++ != (toktype&0xff)))
++	if ((*ptr++ != ((KG_TOK_MIC_MSG>>8)&0xff)) ||
++	    (*ptr++ != ( KG_TOK_MIC_MSG    &0xff))   )
+ 		goto out;
+ 
+ 	/* XXX sanity-check bodysize?? */
+ 
+-	if (toktype == KG_TOK_WRAP_MSG) {
+-		/* XXX gone */
+-		goto out;
+-	}
+-
+ 	/* get the sign and seal algorithms */
+ 
+ 	signalg = ptr[0] + (ptr[1] << 8);
+@@ -120,14 +109,7 @@ krb5_read_token(struct krb5_ctx *ctx,
+ 	if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
+ 		goto out;
+ 
+-	if (((toktype != KG_TOK_WRAP_MSG) && (sealalg != 0xffff)) ||
+-	    ((toktype == KG_TOK_WRAP_MSG) && (sealalg == 0xffff)))
+-		goto out;
+-
+-	/* in the current spec, there is only one valid seal algorithm per
+-	   key type, so a simple comparison is ok */
+-
+-	if ((toktype == KG_TOK_WRAP_MSG) && !(sealalg == ctx->sealalg))
++	if (sealalg != 0xffff)
+ 		goto out;
+ 
+ 	/* there are several mappings of seal algorithms to sign algorithms,
+@@ -154,7 +136,7 @@ krb5_read_token(struct krb5_ctx *ctx,
+ 	switch (signalg) {
+ 	case SGN_ALG_DES_MAC_MD5:
+ 		ret = make_checksum(checksum_type, ptr - 2, 8,
+-					 message_buffer, &md5cksum);
++					 message_buffer, 0, &md5cksum);
+ 		if (ret)
+ 			goto out;
+ 
+@@ -175,9 +157,6 @@ krb5_read_token(struct krb5_ctx *ctx,
+ 
+ 	/* it got through unscathed.  Make sure the context is unexpired */
+ 
+-	if (qop_state)
+-		*qop_state = GSS_C_QOP_DEFAULT;
+-
+ 	now = get_seconds();
+ 
+ 	ret = GSS_S_CONTEXT_EXPIRED;
+diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
+new file mode 100644
+--- /dev/null
++++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
+@@ -0,0 +1,363 @@
++#include <linux/types.h>
++#include <linux/slab.h>
++#include <linux/jiffies.h>
++#include <linux/sunrpc/gss_krb5.h>
++#include <linux/random.h>
++#include <linux/pagemap.h>
++#include <asm/scatterlist.h>
++#include <linux/crypto.h>
++
++#ifdef RPC_DEBUG
++# define RPCDBG_FACILITY	RPCDBG_AUTH
++#endif
++
++static inline int
++gss_krb5_padding(int blocksize, int length)
++{
++	/* Most of the code is block-size independent but currently we
++	 * use only 8: */
++	BUG_ON(blocksize != 8);
++	return 8 - (length & 7);
++}
++
++static inline void
++gss_krb5_add_padding(struct xdr_buf *buf, int offset, int blocksize)
++{
++	int padding = gss_krb5_padding(blocksize, buf->len - offset);
++	char *p;
++	struct kvec *iov;
++
++	if (buf->page_len || buf->tail[0].iov_len)
++		iov = &buf->tail[0];
++	else
++		iov = &buf->head[0];
++	p = iov->iov_base + iov->iov_len;
++	iov->iov_len += padding;
++	buf->len += padding;
++	memset(p, padding, padding);
++}
++
++static inline int
++gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize)
++{
++	u8 *ptr;
++	u8 pad;
++	int len = buf->len;
++
++	if (len <= buf->head[0].iov_len) {
++		pad = *(u8 *)(buf->head[0].iov_base + len - 1);
++		if (pad > buf->head[0].iov_len)
++			return -EINVAL;
++		buf->head[0].iov_len -= pad;
++		goto out;
++	} else
++		len -= buf->head[0].iov_len;
++	if (len <= buf->page_len) {
++		int last = (buf->page_base + len - 1)
++					>>PAGE_CACHE_SHIFT;
++		int offset = (buf->page_base + len - 1)
++					& (PAGE_CACHE_SIZE - 1);
++		ptr = kmap_atomic(buf->pages[last], KM_SKB_SUNRPC_DATA);
++		pad = *(ptr + offset);
++		kunmap_atomic(ptr, KM_SKB_SUNRPC_DATA);
++		goto out;
++	} else
++		len -= buf->page_len;
++	BUG_ON(len > buf->tail[0].iov_len);
++	pad = *(u8 *)(buf->tail[0].iov_base + len - 1);
++out:
++	/* XXX: NOTE: we do not adjust the page lengths--they represent
++	 * a range of data in the real filesystem page cache, and we need
++	 * to know that range so the xdr code can properly place read data.
++	 * However adjusting the head length, as we do above, is harmless.
++	 * In the case of a request that fits into a single page, the server
++	 * also uses length and head length together to determine the original
++	 * start of the request to copy the request for deferal; so it's
++	 * easier on the server if we adjust head and tail length in tandem.
++	 * It's not really a problem that we don't fool with the page and
++	 * tail lengths, though--at worst badly formed xdr might lead the
++	 * server to attempt to parse the padding.
++	 * XXX: Document all these weird requirements for gss mechanism
++	 * wrap/unwrap functions. */
++	if (pad > blocksize)
++		return -EINVAL;
++	if (buf->len > pad)
++		buf->len -= pad;
++	else
++		return -EINVAL;
++	return 0;
++}
++
++static inline void
++make_confounder(char *p, int blocksize)
++{
++	static u64 i = 0;
++	u64 *q = (u64 *)p;
++
++	/* rfc1964 claims this should be "random".  But all that's really
++	 * necessary is that it be unique.  And not even that is necessary in
++	 * our case since our "gssapi" implementation exists only to support
++	 * rpcsec_gss, so we know that the only buffers we will ever encrypt
++	 * already begin with a unique sequence number.  Just to hedge my bets
++	 * I'll make a half-hearted attempt at something unique, but ensuring
++	 * uniqueness would mean worrying about atomicity and rollover, and I
++	 * don't care enough. */
++
++	BUG_ON(blocksize != 8);
++	*q = i++;
++}
++
++/* Assumptions: the head and tail of inbuf are ours to play with.
++ * The pages, however, may be real pages in the page cache and we replace
++ * them with scratch pages from **pages before writing to them. */
++/* XXX: obviously the above should be documentation of wrap interface,
++ * and shouldn't be in this kerberos-specific file. */
++
++/* XXX factor out common code with seal/unseal. */
++
++u32
++gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
++		struct xdr_buf *buf, struct page **pages)
++{
++	struct krb5_ctx		*kctx = ctx->internal_ctx_id;
++	s32			checksum_type;
++	struct xdr_netobj	md5cksum = {.len = 0, .data = NULL};
++	int			blocksize = 0, plainlen;
++	unsigned char		*ptr, *krb5_hdr, *msg_start;
++	s32			now;
++	int			headlen;
++	struct page		**tmp_pages;
++
++	dprintk("RPC:     gss_wrap_kerberos\n");
++
++	now = get_seconds();
++
++	switch (kctx->signalg) {
++		case SGN_ALG_DES_MAC_MD5:
++			checksum_type = CKSUMTYPE_RSA_MD5;
++			break;
++		default:
++			dprintk("RPC:      gss_krb5_seal: kctx->signalg %d not"
++				" supported\n", kctx->signalg);
++			goto out_err;
++	}
++	if (kctx->sealalg != SEAL_ALG_NONE && kctx->sealalg != SEAL_ALG_DES) {
++		dprintk("RPC:      gss_krb5_seal: kctx->sealalg %d not supported\n",
++			kctx->sealalg);
++		goto out_err;
++	}
++
++	blocksize = crypto_tfm_alg_blocksize(kctx->enc);
++	gss_krb5_add_padding(buf, offset, blocksize);
++	BUG_ON((buf->len - offset) % blocksize);
++	plainlen = blocksize + buf->len - offset;
++
++	headlen = g_token_size(&kctx->mech_used, 22 + plainlen) -
++						(buf->len - offset);
++
++	ptr = buf->head[0].iov_base + offset;
++	/* shift data to make room for header. */
++	/* XXX Would be cleverer to encrypt while copying. */
++	/* XXX bounds checking, slack, etc. */
++	memmove(ptr + headlen, ptr, buf->head[0].iov_len - offset);
++	buf->head[0].iov_len += headlen;
++	buf->len += headlen;
++	BUG_ON((buf->len - offset - headlen) % blocksize);
++
++	g_make_token_header(&kctx->mech_used, 22 + plainlen, &ptr);
++
++
++	*ptr++ = (unsigned char) ((KG_TOK_WRAP_MSG>>8)&0xff);
++	*ptr++ = (unsigned char) (KG_TOK_WRAP_MSG&0xff);
++
++	/* ptr now at byte 2 of header described in rfc 1964, section 1.2.1: */
++	krb5_hdr = ptr - 2;
++	msg_start = krb5_hdr + 24;
++	/* XXXJBF: */ BUG_ON(buf->head[0].iov_base + offset + headlen != msg_start + blocksize);
++
++	*(u16 *)(krb5_hdr + 2) = htons(kctx->signalg);
++	memset(krb5_hdr + 4, 0xff, 4);
++	*(u16 *)(krb5_hdr + 4) = htons(kctx->sealalg);
++
++	make_confounder(msg_start, blocksize);
++
++	/* XXXJBF: UGH!: */
++	tmp_pages = buf->pages;
++	buf->pages = pages;
++	if (make_checksum(checksum_type, krb5_hdr, 8, buf,
++				offset + headlen - blocksize, &md5cksum))
++		goto out_err;
++	buf->pages = tmp_pages;
++
++	switch (kctx->signalg) {
++	case SGN_ALG_DES_MAC_MD5:
++		if (krb5_encrypt(kctx->seq, NULL, md5cksum.data,
++				  md5cksum.data, md5cksum.len))
++			goto out_err;
++		memcpy(krb5_hdr + 16,
++		       md5cksum.data + md5cksum.len - KRB5_CKSUM_LENGTH,
++		       KRB5_CKSUM_LENGTH);
++
++		dprintk("RPC:      make_seal_token: cksum data: \n");
++		print_hexl((u32 *) (krb5_hdr + 16), KRB5_CKSUM_LENGTH, 0);
++		break;
++	default:
++		BUG();
++	}
++
++	kfree(md5cksum.data);
++
++	/* XXX would probably be more efficient to compute checksum
++	 * and encrypt at the same time: */
++	if ((krb5_make_seq_num(kctx->seq, kctx->initiate ? 0 : 0xff,
++			       kctx->seq_send, krb5_hdr + 16, krb5_hdr + 8)))
++		goto out_err;
++
++	if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - blocksize,
++									pages))
++		goto out_err;
++
++	kctx->seq_send++;
++
++	return ((kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE);
++out_err:
++	if (md5cksum.data) kfree(md5cksum.data);
++	return GSS_S_FAILURE;
++}
++
++u32
++gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
++{
++	struct krb5_ctx		*kctx = ctx->internal_ctx_id;
++	int			signalg;
++	int			sealalg;
++	s32			checksum_type;
++	struct xdr_netobj	md5cksum = {.len = 0, .data = NULL};
++	s32			now;
++	int			direction;
++	s32			seqnum;
++	unsigned char		*ptr;
++	int			bodysize;
++	u32			ret = GSS_S_DEFECTIVE_TOKEN;
++	void			*data_start, *orig_start;
++	int			data_len;
++	int			blocksize;
++
++	dprintk("RPC:      gss_unwrap_kerberos\n");
++
++	ptr = (u8 *)buf->head[0].iov_base + offset;
++	if (g_verify_token_header(&kctx->mech_used, &bodysize, &ptr,
++					buf->len - offset))
++		goto out;
++
++	if ((*ptr++ != ((KG_TOK_WRAP_MSG>>8)&0xff)) ||
++	    (*ptr++ !=  (KG_TOK_WRAP_MSG    &0xff))   )
++		goto out;
++
++	/* XXX sanity-check bodysize?? */
++
++	/* get the sign and seal algorithms */
++
++	signalg = ptr[0] + (ptr[1] << 8);
++	sealalg = ptr[2] + (ptr[3] << 8);
++
++	/* Sanity checks */
++
++	if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
++		goto out;
++
++	if (sealalg == 0xffff)
++		goto out;
++
++	/* in the current spec, there is only one valid seal algorithm per
++	   key type, so a simple comparison is ok */
++
++	if (sealalg != kctx->sealalg)
++		goto out;
++
++	/* there are several mappings of seal algorithms to sign algorithms,
++	   but few enough that we can try them all. */
++
++	if ((kctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
++	    (kctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
++	    (kctx->sealalg == SEAL_ALG_DES3KD &&
++	     signalg != SGN_ALG_HMAC_SHA1_DES3_KD))
++		goto out;
++
++	if (gss_decrypt_xdr_buf(kctx->enc, buf,
++			ptr + 22 - (unsigned char *)buf->head[0].iov_base))
++		goto out;
++
++	/* compute the checksum of the message */
++
++	/* initialize the the cksum */
++	switch (signalg) {
++	case SGN_ALG_DES_MAC_MD5:
++		checksum_type = CKSUMTYPE_RSA_MD5;
++		break;
++	default:
++		ret = GSS_S_DEFECTIVE_TOKEN;
++		goto out;
++	}
++
++	switch (signalg) {
++	case SGN_ALG_DES_MAC_MD5:
++		ret = make_checksum(checksum_type, ptr - 2, 8, buf,
++			 ptr + 22 - (unsigned char *)buf->head[0].iov_base, &md5cksum);
++		if (ret)
++			goto out;
++
++		ret = krb5_encrypt(kctx->seq, NULL, md5cksum.data,
++				   md5cksum.data, md5cksum.len);
++		if (ret)
++			goto out;
++
++		if (memcmp(md5cksum.data + 8, ptr + 14, 8)) {
++			ret = GSS_S_BAD_SIG;
++			goto out;
++		}
++		break;
++	default:
++		ret = GSS_S_DEFECTIVE_TOKEN;
++		goto out;
++	}
++
++	/* it got through unscathed.  Make sure the context is unexpired */
++
++	now = get_seconds();
++
++	ret = GSS_S_CONTEXT_EXPIRED;
++	if (now > kctx->endtime)
++		goto out;
++
++	/* do sequencing checks */
++
++	ret = GSS_S_BAD_SIG;
++	if ((ret = krb5_get_seq_num(kctx->seq, ptr + 14, ptr + 6, &direction,
++				    &seqnum)))
++		goto out;
++
++	if ((kctx->initiate && direction != 0xff) ||
++	    (!kctx->initiate && direction != 0))
++		goto out;
++
++	/* Copy the data back to the right position.  XXX: Would probably be
++	 * better to copy and encrypt at the same time. */
++
++	blocksize = crypto_tfm_alg_blocksize(kctx->enc);
++	data_start = ptr + 22 + blocksize;
++	orig_start = buf->head[0].iov_base + offset;
++	data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start;
++	memmove(orig_start, data_start, data_len);
++	buf->head[0].iov_len -= (data_start - orig_start);
++	buf->len -= (data_start - orig_start);
++
++	ret = GSS_S_DEFECTIVE_TOKEN;
++	if (gss_krb5_remove_padding(buf, blocksize))
++		goto out;
++
++	ret = GSS_S_COMPLETE;
++out:
++	if (md5cksum.data) kfree(md5cksum.data);
++	return ret;
++}
+diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
+--- a/net/sunrpc/auth_gss/gss_mech_switch.c
++++ b/net/sunrpc/auth_gss/gss_mech_switch.c
+@@ -35,7 +35,6 @@
+ 
+ #include <linux/types.h>
+ #include <linux/slab.h>
+-#include <linux/socket.h>
+ #include <linux/module.h>
+ #include <linux/sunrpc/msg_prot.h>
+ #include <linux/sunrpc/gss_asn1.h>
+@@ -251,13 +250,11 @@ gss_import_sec_context(const void *input
+ 
+ u32
+ gss_get_mic(struct gss_ctx	*context_handle,
+-	    u32			qop,
+ 	    struct xdr_buf	*message,
+ 	    struct xdr_netobj	*mic_token)
+ {
+ 	 return context_handle->mech_type->gm_ops
+ 		->gss_get_mic(context_handle,
+-			      qop,
+ 			      message,
+ 			      mic_token);
+ }
+@@ -267,16 +264,34 @@ gss_get_mic(struct gss_ctx	*context_hand
+ u32
+ gss_verify_mic(struct gss_ctx		*context_handle,
+ 	       struct xdr_buf		*message,
+-	       struct xdr_netobj	*mic_token,
+-	       u32			*qstate)
++	       struct xdr_netobj	*mic_token)
+ {
+ 	return context_handle->mech_type->gm_ops
+ 		->gss_verify_mic(context_handle,
+ 				 message,
+-				 mic_token,
+-				 qstate);
++				 mic_token);
+ }
+ 
++u32
++gss_wrap(struct gss_ctx	*ctx_id,
++	 int		offset,
++	 struct xdr_buf	*buf,
++	 struct page	**inpages)
++{
++	return ctx_id->mech_type->gm_ops
++		->gss_wrap(ctx_id, offset, buf, inpages);
++}
++
++u32
++gss_unwrap(struct gss_ctx	*ctx_id,
++	   int			offset,
++	   struct xdr_buf	*buf)
++{
++	return ctx_id->mech_type->gm_ops
++		->gss_unwrap(ctx_id, offset, buf);
++}
++
++
+ /* gss_delete_sec_context: free all resources associated with context_handle.
+  * Note this differs from the RFC 2744-specified prototype in that we don't
+  * bother returning an output token, since it would never be used anyway. */
+diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
+--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
++++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
+@@ -224,18 +224,13 @@ gss_delete_sec_context_spkm3(void *inter
+ static u32
+ gss_verify_mic_spkm3(struct gss_ctx		*ctx,
+ 			struct xdr_buf		*signbuf,
+-			struct xdr_netobj	*checksum,
+-			u32		*qstate) {
++			struct xdr_netobj	*checksum)
++{
+ 	u32 maj_stat = 0;
+-	int qop_state = 0;
+ 	struct spkm3_ctx *sctx = ctx->internal_ctx_id;
+ 
+ 	dprintk("RPC: gss_verify_mic_spkm3 calling spkm3_read_token\n");
+-	maj_stat = spkm3_read_token(sctx, checksum, signbuf, &qop_state,
+-				   SPKM_MIC_TOK);
+-
+-	if (!maj_stat && qop_state)
+-	    *qstate = qop_state;
++	maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK);
+ 
+ 	dprintk("RPC: gss_verify_mic_spkm3 returning %d\n", maj_stat);
+ 	return maj_stat;
+@@ -243,15 +238,15 @@ gss_verify_mic_spkm3(struct gss_ctx		*ct
+ 
+ static u32
+ gss_get_mic_spkm3(struct gss_ctx	*ctx,
+-		     u32		qop,
+ 		     struct xdr_buf	*message_buffer,
+-		     struct xdr_netobj	*message_token) {
++		     struct xdr_netobj	*message_token)
++{
+ 	u32 err = 0;
+ 	struct spkm3_ctx *sctx = ctx->internal_ctx_id;
+ 
+ 	dprintk("RPC: gss_get_mic_spkm3\n");
+ 
+-	err = spkm3_make_token(sctx, qop, message_buffer,
++	err = spkm3_make_token(sctx, message_buffer,
+ 			      message_token, SPKM_MIC_TOK);
+ 	return err;
+ }
+@@ -264,8 +259,8 @@ static struct gss_api_ops gss_spkm3_ops 
+ };
+ 
+ static struct pf_desc gss_spkm3_pfs[] = {
+-	{RPC_AUTH_GSS_SPKM, 0, RPC_GSS_SVC_NONE, "spkm3"},
+-	{RPC_AUTH_GSS_SPKMI, 0, RPC_GSS_SVC_INTEGRITY, "spkm3i"},
++	{RPC_AUTH_GSS_SPKM, RPC_GSS_SVC_NONE, "spkm3"},
++	{RPC_AUTH_GSS_SPKMI, RPC_GSS_SVC_INTEGRITY, "spkm3i"},
+ };
+ 
+ static struct gss_api_mech gss_spkm3_mech = {
+diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c
+--- a/net/sunrpc/auth_gss/gss_spkm3_seal.c
++++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c
+@@ -51,7 +51,7 @@
+  */
+ 
+ u32
+-spkm3_make_token(struct spkm3_ctx *ctx, int qop_req,
++spkm3_make_token(struct spkm3_ctx *ctx,
+ 		   struct xdr_buf * text, struct xdr_netobj * token,
+ 		   int toktype)
+ {
+@@ -68,8 +68,6 @@ spkm3_make_token(struct spkm3_ctx *ctx, 
+ 	dprintk("RPC: spkm3_make_token\n");
+ 
+ 	now = jiffies;
+-	if (qop_req != 0)
+-		goto out_err;
+ 
+ 	if (ctx->ctx_id.len != 16) {
+ 		dprintk("RPC: spkm3_make_token BAD ctx_id.len %d\n",
+diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
+--- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c
++++ b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
+@@ -52,7 +52,7 @@ u32
+ spkm3_read_token(struct spkm3_ctx *ctx,
+ 		struct xdr_netobj *read_token,    /* checksum */
+ 		struct xdr_buf *message_buffer, /* signbuf */
+-		int *qop_state, int toktype)
++		int toktype)
+ {
+ 	s32			code;
+ 	struct xdr_netobj	wire_cksum = {.len =0, .data = NULL};
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -566,8 +566,7 @@ gss_verify_header(struct svc_rqst *rqstp
+ 
+ 	if (rqstp->rq_deferred) /* skip verification of revisited request */
+ 		return SVC_OK;
+-	if (gss_verify_mic(ctx_id, &rpchdr, &checksum, NULL)
+-							!= GSS_S_COMPLETE) {
++	if (gss_verify_mic(ctx_id, &rpchdr, &checksum) != GSS_S_COMPLETE) {
+ 		*authp = rpcsec_gsserr_credproblem;
+ 		return SVC_DENIED;
+ 	}
+@@ -604,7 +603,7 @@ gss_write_verf(struct svc_rqst *rqstp, s
+ 	xdr_buf_from_iov(&iov, &verf_data);
+ 	p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
+ 	mic.data = (u8 *)(p + 1);
+-	maj_stat = gss_get_mic(ctx_id, 0, &verf_data, &mic);
++	maj_stat = gss_get_mic(ctx_id, &verf_data, &mic);
+ 	if (maj_stat != GSS_S_COMPLETE)
+ 		return -1;
+ 	*p++ = htonl(mic.len);
+@@ -710,7 +709,7 @@ unwrap_integ_data(struct xdr_buf *buf, u
+ 		goto out;
+ 	if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len))
+ 		goto out;
+-	maj_stat = gss_verify_mic(ctx, &integ_buf, &mic, NULL);
++	maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
+ 	if (maj_stat != GSS_S_COMPLETE)
+ 		goto out;
+ 	if (ntohl(svc_getu32(&buf->head[0])) != seq)
+@@ -1012,7 +1011,7 @@ svcauth_gss_release(struct svc_rqst *rqs
+ 			resv = &resbuf->tail[0];
+ 		}
+ 		mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
+-		if (gss_get_mic(gsd->rsci->mechctx, 0, &integ_buf, &mic))
++		if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
+ 			goto out_err;
+ 		svc_putu32(resv, htonl(mic.len));
+ 		memset(mic.data + mic.len, 0,
+diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
+--- a/net/sunrpc/auth_null.c
++++ b/net/sunrpc/auth_null.c
+@@ -7,9 +7,7 @@
+  */
+ 
+ #include <linux/types.h>
+-#include <linux/socket.h>
+ #include <linux/module.h>
+-#include <linux/in.h>
+ #include <linux/utsname.h>
+ #include <linux/sunrpc/clnt.h>
+ #include <linux/sched.h>
+diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
+--- a/net/sunrpc/auth_unix.c
++++ b/net/sunrpc/auth_unix.c
+@@ -9,8 +9,6 @@
+ #include <linux/types.h>
+ #include <linux/sched.h>
+ #include <linux/module.h>
+-#include <linux/socket.h>
+-#include <linux/in.h>
+ #include <linux/sunrpc/clnt.h>
+ #include <linux/sunrpc/auth.h>
+ 
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -1,5 +1,5 @@
+ /*
+- *  linux/net/sunrpc/rpcclnt.c
++ *  linux/net/sunrpc/clnt.c
+  *
+  *  This file contains the high-level RPC interface.
+  *  It is modeled as a finite state machine to support both synchronous
+@@ -27,7 +27,6 @@
+ #include <linux/types.h>
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+-#include <linux/in.h>
+ #include <linux/utsname.h>
+ 
+ #include <linux/sunrpc/clnt.h>
+@@ -53,6 +52,7 @@ static void	call_allocate(struct rpc_tas
+ static void	call_encode(struct rpc_task *task);
+ static void	call_decode(struct rpc_task *task);
+ static void	call_bind(struct rpc_task *task);
++static void	call_bind_status(struct rpc_task *task);
+ static void	call_transmit(struct rpc_task *task);
+ static void	call_status(struct rpc_task *task);
+ static void	call_refresh(struct rpc_task *task);
+@@ -517,15 +517,8 @@ void
+ rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize)
+ {
+ 	struct rpc_xprt *xprt = clnt->cl_xprt;
+-
+-	xprt->sndsize = 0;
+-	if (sndsize)
+-		xprt->sndsize = sndsize + RPC_SLACK_SPACE;
+-	xprt->rcvsize = 0;
+-	if (rcvsize)
+-		xprt->rcvsize = rcvsize + RPC_SLACK_SPACE;
+-	if (xprt_connected(xprt))
+-		xprt_sock_setbufsize(xprt);
++	if (xprt->ops->set_buffer_size)
++		xprt->ops->set_buffer_size(xprt, sndsize, rcvsize);
+ }
+ 
+ /*
+@@ -685,13 +678,11 @@ call_allocate(struct rpc_task *task)
+ static void
+ call_encode(struct rpc_task *task)
+ {
+-	struct rpc_clnt	*clnt = task->tk_client;
+ 	struct rpc_rqst	*req = task->tk_rqstp;
+ 	struct xdr_buf *sndbuf = &req->rq_snd_buf;
+ 	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
+ 	unsigned int	bufsiz;
+ 	kxdrproc_t	encode;
+-	int		status;
+ 	u32		*p;
+ 
+ 	dprintk("RPC: %4d call_encode (status %d)\n", 
+@@ -719,11 +710,15 @@ call_encode(struct rpc_task *task)
+ 		rpc_exit(task, -EIO);
+ 		return;
+ 	}
+-	if (encode && (status = rpcauth_wrap_req(task, encode, req, p,
+-						 task->tk_msg.rpc_argp)) < 0) {
+-		printk(KERN_WARNING "%s: can't encode arguments: %d\n",
+-				clnt->cl_protname, -status);
+-		rpc_exit(task, status);
++	if (encode == NULL)
++		return;
++
++	task->tk_status = rpcauth_wrap_req(task, encode, req, p,
++			task->tk_msg.rpc_argp);
++	if (task->tk_status == -ENOMEM) {
++		/* XXX: Is this sane? */
++		rpc_delay(task, 3*HZ);
++		task->tk_status = -EAGAIN;
+ 	}
+ }
+ 
+@@ -734,43 +729,95 @@ static void
+ call_bind(struct rpc_task *task)
+ {
+ 	struct rpc_clnt	*clnt = task->tk_client;
+-	struct rpc_xprt *xprt = clnt->cl_xprt;
+ 
+-	dprintk("RPC: %4d call_bind xprt %p %s connected\n", task->tk_pid,
+-			xprt, (xprt_connected(xprt) ? "is" : "is not"));
+-
+-	task->tk_action = (xprt_connected(xprt)) ? call_transmit : call_connect;
++	dprintk("RPC: %4d call_bind (status %d)\n",
++				task->tk_pid, task->tk_status);
+ 
++	task->tk_action = call_connect;
+ 	if (!clnt->cl_port) {
+-		task->tk_action = call_connect;
+-		task->tk_timeout = RPC_CONNECT_TIMEOUT;
++		task->tk_action = call_bind_status;
++		task->tk_timeout = task->tk_xprt->bind_timeout;
+ 		rpc_getport(task, clnt);
+ 	}
+ }
+ 
+ /*
+- * 4a.	Connect to the RPC server (TCP case)
++ * 4a.	Sort out bind result
+  */
+ static void
+-call_connect(struct rpc_task *task)
++call_bind_status(struct rpc_task *task)
+ {
+-	struct rpc_clnt *clnt = task->tk_client;
+-
+-	dprintk("RPC: %4d call_connect status %d\n",
+-				task->tk_pid, task->tk_status);
++	int status = -EACCES;
+ 
+-	if (xprt_connected(clnt->cl_xprt)) {
+-		task->tk_action = call_transmit;
++	if (task->tk_status >= 0) {
++		dprintk("RPC: %4d call_bind_status (status %d)\n",
++					task->tk_pid, task->tk_status);
++		task->tk_status = 0;
++		task->tk_action = call_connect;
+ 		return;
+ 	}
+-	task->tk_action = call_connect_status;
+-	if (task->tk_status < 0)
+-		return;
+-	xprt_connect(task);
++
++	switch (task->tk_status) {
++	case -EACCES:
++		dprintk("RPC: %4d remote rpcbind: RPC program/version unavailable\n",
++				task->tk_pid);
++		rpc_delay(task, 3*HZ);
++		goto retry_bind;
++	case -ETIMEDOUT:
++		dprintk("RPC: %4d rpcbind request timed out\n",
++				task->tk_pid);
++		if (RPC_IS_SOFT(task)) {
++			status = -EIO;
++			break;
++		}
++		goto retry_bind;
++	case -EPFNOSUPPORT:
++		dprintk("RPC: %4d remote rpcbind service unavailable\n",
++				task->tk_pid);
++		break;
++	case -EPROTONOSUPPORT:
++		dprintk("RPC: %4d remote rpcbind version 2 unavailable\n",
++				task->tk_pid);
++		break;
++	default:
++		dprintk("RPC: %4d unrecognized rpcbind error (%d)\n",
++				task->tk_pid, -task->tk_status);
++		status = -EIO;
++		break;
++	}
++
++	rpc_exit(task, status);
++	return;
++
++retry_bind:
++	task->tk_status = 0;
++	task->tk_action = call_bind;
++	return;
++}
++
++/*
++ * 4b.	Connect to the RPC server
++ */
++static void
++call_connect(struct rpc_task *task)
++{
++	struct rpc_xprt *xprt = task->tk_xprt;
++
++	dprintk("RPC: %4d call_connect xprt %p %s connected\n",
++			task->tk_pid, xprt,
++			(xprt_connected(xprt) ? "is" : "is not"));
++
++	task->tk_action = call_transmit;
++	if (!xprt_connected(xprt)) {
++		task->tk_action = call_connect_status;
++		if (task->tk_status < 0)
++			return;
++		xprt_connect(task);
++	}
+ }
+ 
+ /*
+- * 4b. Sort out connect result
++ * 4c.	Sort out connect result
+  */
+ static void
+ call_connect_status(struct rpc_task *task)
+@@ -778,6 +825,9 @@ call_connect_status(struct rpc_task *tas
+ 	struct rpc_clnt *clnt = task->tk_client;
+ 	int status = task->tk_status;
+ 
++	dprintk("RPC: %5u call_connect_status (status %d)\n", 
++				task->tk_pid, task->tk_status);
++
+ 	task->tk_status = 0;
+ 	if (status >= 0) {
+ 		clnt->cl_stats->netreconn++;
+@@ -785,17 +835,19 @@ call_connect_status(struct rpc_task *tas
+ 		return;
+ 	}
+ 
+-	/* Something failed: we may have to rebind */
++	/* Something failed: remote service port may have changed */
+ 	if (clnt->cl_autobind)
+ 		clnt->cl_port = 0;
++
+ 	switch (status) {
+ 	case -ENOTCONN:
+ 	case -ETIMEDOUT:
+ 	case -EAGAIN:
+-		task->tk_action = (clnt->cl_port == 0) ? call_bind : call_connect;
++		task->tk_action = call_bind;
+ 		break;
+ 	default:
+ 		rpc_exit(task, -EIO);
++		break;
+ 	}
+ }
+ 
+@@ -815,10 +867,12 @@ call_transmit(struct rpc_task *task)
+ 	if (task->tk_status != 0)
+ 		return;
+ 	/* Encode here so that rpcsec_gss can use correct sequence number. */
+-	if (!task->tk_rqstp->rq_bytes_sent)
++	if (task->tk_rqstp->rq_bytes_sent == 0) {
+ 		call_encode(task);
+-	if (task->tk_status < 0)
+-		return;
++		/* Did the encode result in an error condition? */
++		if (task->tk_status != 0)
++			goto out_nosend;
++	}
+ 	xprt_transmit(task);
+ 	if (task->tk_status < 0)
+ 		return;
+@@ -826,6 +880,10 @@ call_transmit(struct rpc_task *task)
+ 		task->tk_action = NULL;
+ 		rpc_wake_up_task(task);
+ 	}
++	return;
++out_nosend:
++	/* release socket write lock before attempting to handle error */
++	xprt_abort_transmit(task);
+ }
+ 
+ /*
+@@ -1020,13 +1078,12 @@ static u32 *
+ call_header(struct rpc_task *task)
+ {
+ 	struct rpc_clnt *clnt = task->tk_client;
+-	struct rpc_xprt *xprt = clnt->cl_xprt;
+ 	struct rpc_rqst	*req = task->tk_rqstp;
+ 	u32		*p = req->rq_svec[0].iov_base;
+ 
+ 	/* FIXME: check buffer size? */
+-	if (xprt->stream)
+-		*p++ = 0;		/* fill in later */
++
++	p = xprt_skip_transport_header(task->tk_xprt, p);
+ 	*p++ = req->rq_xid;		/* XID */
+ 	*p++ = htonl(RPC_CALL);		/* CALL */
+ 	*p++ = htonl(RPC_VERSION);	/* RPC version */
+diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
+--- a/net/sunrpc/pmap_clnt.c
++++ b/net/sunrpc/pmap_clnt.c
+@@ -26,7 +26,7 @@
+ #define PMAP_GETPORT		3
+ 
+ static struct rpc_procinfo	pmap_procedures[];
+-static struct rpc_clnt *	pmap_create(char *, struct sockaddr_in *, int);
++static struct rpc_clnt *	pmap_create(char *, struct sockaddr_in *, int, int);
+ static void			pmap_getport_done(struct rpc_task *);
+ static struct rpc_program	pmap_program;
+ static DEFINE_SPINLOCK(pmap_lock);
+@@ -65,7 +65,7 @@ rpc_getport(struct rpc_task *task, struc
+ 	map->pm_binding = 1;
+ 	spin_unlock(&pmap_lock);
+ 
+-	pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot);
++	pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot, 0);
+ 	if (IS_ERR(pmap_clnt)) {
+ 		task->tk_status = PTR_ERR(pmap_clnt);
+ 		goto bailout;
+@@ -112,7 +112,7 @@ rpc_getport_external(struct sockaddr_in 
+ 			NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
+ 
+ 	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
+-	pmap_clnt = pmap_create(hostname, sin, prot);
++	pmap_clnt = pmap_create(hostname, sin, prot, 0);
+ 	if (IS_ERR(pmap_clnt))
+ 		return PTR_ERR(pmap_clnt);
+ 
+@@ -171,7 +171,7 @@ rpc_register(u32 prog, u32 vers, int pro
+ 
+ 	sin.sin_family = AF_INET;
+ 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+-	pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP);
++	pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP, 1);
+ 	if (IS_ERR(pmap_clnt)) {
+ 		error = PTR_ERR(pmap_clnt);
+ 		dprintk("RPC: couldn't create pmap client. Error = %d\n", error);
+@@ -198,7 +198,7 @@ rpc_register(u32 prog, u32 vers, int pro
+ }
+ 
+ static struct rpc_clnt *
+-pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto)
++pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileged)
+ {
+ 	struct rpc_xprt	*xprt;
+ 	struct rpc_clnt	*clnt;
+@@ -208,6 +208,8 @@ pmap_create(char *hostname, struct socka
+ 	if (IS_ERR(xprt))
+ 		return (struct rpc_clnt *)xprt;
+ 	xprt->addr.sin_port = htons(RPC_PMAP_PORT);
++	if (!privileged)
++		xprt->resvport = 0;
+ 
+ 	/* printk("pmap: create clnt\n"); */
+ 	clnt = rpc_new_client(xprt, hostname,
+diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
+--- a/net/sunrpc/rpc_pipe.c
++++ b/net/sunrpc/rpc_pipe.c
+@@ -76,25 +76,35 @@ int
+ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
+ {
+ 	struct rpc_inode *rpci = RPC_I(inode);
+-	int res = 0;
++	int res = -EPIPE;
+ 
+ 	down(&inode->i_sem);
++	if (rpci->ops == NULL)
++		goto out;
+ 	if (rpci->nreaders) {
+ 		list_add_tail(&msg->list, &rpci->pipe);
+ 		rpci->pipelen += msg->len;
++		res = 0;
+ 	} else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) {
+ 		if (list_empty(&rpci->pipe))
+ 			schedule_delayed_work(&rpci->queue_timeout,
+ 					RPC_UPCALL_TIMEOUT);
+ 		list_add_tail(&msg->list, &rpci->pipe);
+ 		rpci->pipelen += msg->len;
+-	} else
+-		res = -EPIPE;
++		res = 0;
++	}
++out:
+ 	up(&inode->i_sem);
+ 	wake_up(&rpci->waitq);
+ 	return res;
+ }
+ 
++static inline void
++rpc_inode_setowner(struct inode *inode, void *private)
++{
++	RPC_I(inode)->private = private;
++}
++
+ static void
+ rpc_close_pipes(struct inode *inode)
+ {
+@@ -111,15 +121,10 @@ rpc_close_pipes(struct inode *inode)
+ 			rpci->ops->release_pipe(inode);
+ 		rpci->ops = NULL;
+ 	}
++	rpc_inode_setowner(inode, NULL);
+ 	up(&inode->i_sem);
+ }
+ 
+-static inline void
+-rpc_inode_setowner(struct inode *inode, void *private)
+-{
+-	RPC_I(inode)->private = private;
+-}
+-
+ static struct inode *
+ rpc_alloc_inode(struct super_block *sb)
+ {
+@@ -501,7 +506,6 @@ repeat:
+ 			dentry = dvec[--n];
+ 			if (dentry->d_inode) {
+ 				rpc_close_pipes(dentry->d_inode);
+-				rpc_inode_setowner(dentry->d_inode, NULL);
+ 				simple_unlink(dir, dentry);
+ 			}
+ 			dput(dentry);
+@@ -576,10 +580,8 @@ __rpc_rmdir(struct inode *dir, struct de
+ 	int error;
+ 
+ 	shrink_dcache_parent(dentry);
+-	if (dentry->d_inode) {
++	if (dentry->d_inode)
+ 		rpc_close_pipes(dentry->d_inode);
+-		rpc_inode_setowner(dentry->d_inode, NULL);
+-	}
+ 	if ((error = simple_rmdir(dir, dentry)) != 0)
+ 		return error;
+ 	if (!error) {
+@@ -732,7 +734,6 @@ rpc_unlink(char *path)
+ 	d_drop(dentry);
+ 	if (dentry->d_inode) {
+ 		rpc_close_pipes(dentry->d_inode);
+-		rpc_inode_setowner(dentry->d_inode, NULL);
+ 		error = simple_unlink(dir, dentry);
+ 	}
+ 	dput(dentry);
+diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
+new file mode 100644
+--- /dev/null
++++ b/net/sunrpc/socklib.c
+@@ -0,0 +1,175 @@
++/*
++ * linux/net/sunrpc/socklib.c
++ *
++ * Common socket helper routines for RPC client and server
++ *
++ * Copyright (C) 1995, 1996 Olaf Kirch <okir at monad.swb.de>
++ */
++
++#include <linux/types.h>
++#include <linux/pagemap.h>
++#include <linux/udp.h>
++#include <linux/sunrpc/xdr.h>
++
++
++/**
++ * skb_read_bits - copy some data bits from skb to internal buffer
++ * @desc: sk_buff copy helper
++ * @to: copy destination
++ * @len: number of bytes to copy
++ *
++ * Possibly called several times to iterate over an sk_buff and copy
++ * data out of it.
++ */
++static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
++{
++	if (len > desc->count)
++		len = desc->count;
++	if (skb_copy_bits(desc->skb, desc->offset, to, len))
++		return 0;
++	desc->count -= len;
++	desc->offset += len;
++	return len;
++}
++
++/**
++ * skb_read_and_csum_bits - copy and checksum from skb to buffer
++ * @desc: sk_buff copy helper
++ * @to: copy destination
++ * @len: number of bytes to copy
++ *
++ * Same as skb_read_bits, but calculate a checksum at the same time.
++ */
++static size_t skb_read_and_csum_bits(skb_reader_t *desc, void *to, size_t len)
++{
++	unsigned int	csum2, pos;
++
++	if (len > desc->count)
++		len = desc->count;
++	pos = desc->offset;
++	csum2 = skb_copy_and_csum_bits(desc->skb, pos, to, len, 0);
++	desc->csum = csum_block_add(desc->csum, csum2, pos);
++	desc->count -= len;
++	desc->offset += len;
++	return len;
++}
++
++/**
++ * xdr_partial_copy_from_skb - copy data out of an skb
++ * @xdr: target XDR buffer
++ * @base: starting offset
++ * @desc: sk_buff copy helper
++ * @copy_actor: virtual method for copying data
++ *
++ */
++ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, skb_reader_t *desc, skb_read_actor_t copy_actor)
++{
++	struct page	**ppage = xdr->pages;
++	unsigned int	len, pglen = xdr->page_len;
++	ssize_t		copied = 0;
++	int		ret;
++
++	len = xdr->head[0].iov_len;
++	if (base < len) {
++		len -= base;
++		ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len);
++		copied += ret;
++		if (ret != len || !desc->count)
++			goto out;
++		base = 0;
++	} else
++		base -= len;
++
++	if (unlikely(pglen == 0))
++		goto copy_tail;
++	if (unlikely(base >= pglen)) {
++		base -= pglen;
++		goto copy_tail;
++	}
++	if (base || xdr->page_base) {
++		pglen -= base;
++		base += xdr->page_base;
++		ppage += base >> PAGE_CACHE_SHIFT;
++		base &= ~PAGE_CACHE_MASK;
++	}
++	do {
++		char *kaddr;
++
++		/* ACL likes to be lazy in allocating pages - ACLs
++		 * are small by default but can get huge. */
++		if (unlikely(*ppage == NULL)) {
++			*ppage = alloc_page(GFP_ATOMIC);
++			if (unlikely(*ppage == NULL)) {
++				if (copied == 0)
++					copied = -ENOMEM;
++				goto out;
++			}
++		}
++
++		len = PAGE_CACHE_SIZE;
++		kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
++		if (base) {
++			len -= base;
++			if (pglen < len)
++				len = pglen;
++			ret = copy_actor(desc, kaddr + base, len);
++			base = 0;
++		} else {
++			if (pglen < len)
++				len = pglen;
++			ret = copy_actor(desc, kaddr, len);
++		}
++		flush_dcache_page(*ppage);
++		kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
++		copied += ret;
++		if (ret != len || !desc->count)
++			goto out;
++		ppage++;
++	} while ((pglen -= len) != 0);
++copy_tail:
++	len = xdr->tail[0].iov_len;
++	if (base < len)
++		copied += copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
++out:
++	return copied;
++}
++
++/**
++ * csum_partial_copy_to_xdr - checksum and copy data
++ * @xdr: target XDR buffer
++ * @skb: source skb
++ *
++ * We have set things up such that we perform the checksum of the UDP
++ * packet in parallel with the copies into the RPC client iovec.  -DaveM
++ */
++int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
++{
++	skb_reader_t	desc;
++
++	desc.skb = skb;
++	desc.offset = sizeof(struct udphdr);
++	desc.count = skb->len - desc.offset;
++
++	if (skb->ip_summed == CHECKSUM_UNNECESSARY)
++		goto no_checksum;
++
++	desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
++	if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0)
++		return -1;
++	if (desc.offset != skb->len) {
++		unsigned int csum2;
++		csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
++		desc.csum = csum_block_add(desc.csum, csum2, desc.offset);
++	}
++	if (desc.count)
++		return -1;
++	if ((unsigned short)csum_fold(desc.csum))
++		return -1;
++	return 0;
++no_checksum:
++	if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
++		return -1;
++	if (desc.count)
++		return -1;
++	return 0;
++}
+diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
+--- a/net/sunrpc/sunrpc_syms.c
++++ b/net/sunrpc/sunrpc_syms.c
+@@ -10,7 +10,6 @@
+ #include <linux/module.h>
+ 
+ #include <linux/types.h>
+-#include <linux/socket.h>
+ #include <linux/sched.h>
+ #include <linux/uio.h>
+ #include <linux/unistd.h>
+diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -548,9 +548,6 @@ svc_write_space(struct sock *sk)
+ /*
+  * Receive a datagram from a UDP socket.
+  */
+-extern int
+-csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb);
+-
+ static int
+ svc_udp_recvfrom(struct svc_rqst *rqstp)
+ {
+diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
+--- a/net/sunrpc/sysctl.c
++++ b/net/sunrpc/sysctl.c
+@@ -119,8 +119,18 @@ done:
+ 	return 0;
+ }
+ 
++unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE;
++unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE;
++unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT;
++EXPORT_SYMBOL(xprt_min_resvport);
++unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT;
++EXPORT_SYMBOL(xprt_max_resvport);
++
++
+ static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
+ static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
++static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT;
++static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT;
+ 
+ static ctl_table debug_table[] = {
+ 	{
+@@ -177,6 +187,28 @@ static ctl_table debug_table[] = {
+ 		.extra1		= &min_slot_table_size,
+ 		.extra2		= &max_slot_table_size
+ 	},
++	{
++		.ctl_name	= CTL_MIN_RESVPORT,
++		.procname	= "min_resvport",
++		.data		= &xprt_min_resvport,
++		.maxlen		= sizeof(unsigned int),
++		.mode		= 0644,
++		.proc_handler	= &proc_dointvec_minmax,
++		.strategy	= &sysctl_intvec,
++		.extra1		= &xprt_min_resvport_limit,
++		.extra2		= &xprt_max_resvport_limit
++	},
++	{
++		.ctl_name	= CTL_MAX_RESVPORT,
++		.procname	= "max_resvport",
++		.data		= &xprt_max_resvport,
++		.maxlen		= sizeof(unsigned int),
++		.mode		= 0644,
++		.proc_handler	= &proc_dointvec_minmax,
++		.strategy	= &sysctl_intvec,
++		.extra1		= &xprt_min_resvport_limit,
++		.extra2		= &xprt_max_resvport_limit
++	},
+ 	{ .ctl_name = 0 }
+ };
+ 
+diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
+--- a/net/sunrpc/xdr.c
++++ b/net/sunrpc/xdr.c
+@@ -6,15 +6,12 @@
+  * Copyright (C) 1995, 1996 Olaf Kirch <okir at monad.swb.de>
+  */
+ 
++#include <linux/module.h>
+ #include <linux/types.h>
+-#include <linux/socket.h>
+ #include <linux/string.h>
+ #include <linux/kernel.h>
+ #include <linux/pagemap.h>
+ #include <linux/errno.h>
+-#include <linux/in.h>
+-#include <linux/net.h>
+-#include <net/sock.h>
+ #include <linux/sunrpc/xdr.h>
+ #include <linux/sunrpc/msg_prot.h>
+ 
+@@ -176,178 +173,6 @@ xdr_inline_pages(struct xdr_buf *xdr, un
+ 	xdr->buflen += len;
+ }
+ 
+-ssize_t
+-xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
+-			  skb_reader_t *desc,
+-			  skb_read_actor_t copy_actor)
+-{
+-	struct page	**ppage = xdr->pages;
+-	unsigned int	len, pglen = xdr->page_len;
+-	ssize_t		copied = 0;
+-	int		ret;
+-
+-	len = xdr->head[0].iov_len;
+-	if (base < len) {
+-		len -= base;
+-		ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len);
+-		copied += ret;
+-		if (ret != len || !desc->count)
+-			goto out;
+-		base = 0;
+-	} else
+-		base -= len;
+-
+-	if (pglen == 0)
+-		goto copy_tail;
+-	if (base >= pglen) {
+-		base -= pglen;
+-		goto copy_tail;
+-	}
+-	if (base || xdr->page_base) {
+-		pglen -= base;
+-		base  += xdr->page_base;
+-		ppage += base >> PAGE_CACHE_SHIFT;
+-		base &= ~PAGE_CACHE_MASK;
+-	}
+-	do {
+-		char *kaddr;
+-
+-		/* ACL likes to be lazy in allocating pages - ACLs
+-		 * are small by default but can get huge. */
+-		if (unlikely(*ppage == NULL)) {
+-			*ppage = alloc_page(GFP_ATOMIC);
+-			if (unlikely(*ppage == NULL)) {
+-				if (copied == 0)
+-					copied = -ENOMEM;
+-				goto out;
+-			}
+-		}
+-
+-		len = PAGE_CACHE_SIZE;
+-		kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
+-		if (base) {
+-			len -= base;
+-			if (pglen < len)
+-				len = pglen;
+-			ret = copy_actor(desc, kaddr + base, len);
+-			base = 0;
+-		} else {
+-			if (pglen < len)
+-				len = pglen;
+-			ret = copy_actor(desc, kaddr, len);
+-		}
+-		flush_dcache_page(*ppage);
+-		kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
+-		copied += ret;
+-		if (ret != len || !desc->count)
+-			goto out;
+-		ppage++;
+-	} while ((pglen -= len) != 0);
+-copy_tail:
+-	len = xdr->tail[0].iov_len;
+-	if (base < len)
+-		copied += copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
+-out:
+-	return copied;
+-}
+-
+-
+-int
+-xdr_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
+-		struct xdr_buf *xdr, unsigned int base, int msgflags)
+-{
+-	struct page **ppage = xdr->pages;
+-	unsigned int len, pglen = xdr->page_len;
+-	int err, ret = 0;
+-	ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
+-
+-	len = xdr->head[0].iov_len;
+-	if (base < len || (addr != NULL && base == 0)) {
+-		struct kvec iov = {
+-			.iov_base = xdr->head[0].iov_base + base,
+-			.iov_len  = len - base,
+-		};
+-		struct msghdr msg = {
+-			.msg_name    = addr,
+-			.msg_namelen = addrlen,
+-			.msg_flags   = msgflags,
+-		};
+-		if (xdr->len > len)
+-			msg.msg_flags |= MSG_MORE;
+-
+-		if (iov.iov_len != 0)
+-			err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+-		else
+-			err = kernel_sendmsg(sock, &msg, NULL, 0, 0);
+-		if (ret == 0)
+-			ret = err;
+-		else if (err > 0)
+-			ret += err;
+-		if (err != iov.iov_len)
+-			goto out;
+-		base = 0;
+-	} else
+-		base -= len;
+-
+-	if (pglen == 0)
+-		goto copy_tail;
+-	if (base >= pglen) {
+-		base -= pglen;
+-		goto copy_tail;
+-	}
+-	if (base || xdr->page_base) {
+-		pglen -= base;
+-		base  += xdr->page_base;
+-		ppage += base >> PAGE_CACHE_SHIFT;
+-		base &= ~PAGE_CACHE_MASK;
+-	}
+-
+-	sendpage = sock->ops->sendpage ? : sock_no_sendpage;
+-	do {
+-		int flags = msgflags;
+-
+-		len = PAGE_CACHE_SIZE;
+-		if (base)
+-			len -= base;
+-		if (pglen < len)
+-			len = pglen;
+-
+-		if (pglen != len || xdr->tail[0].iov_len != 0)
+-			flags |= MSG_MORE;
+-
+-		/* Hmm... We might be dealing with highmem pages */
+-		if (PageHighMem(*ppage))
+-			sendpage = sock_no_sendpage;
+-		err = sendpage(sock, *ppage, base, len, flags);
+-		if (ret == 0)
+-			ret = err;
+-		else if (err > 0)
+-			ret += err;
+-		if (err != len)
+-			goto out;
+-		base = 0;
+-		ppage++;
+-	} while ((pglen -= len) != 0);
+-copy_tail:
+-	len = xdr->tail[0].iov_len;
+-	if (base < len) {
+-		struct kvec iov = {
+-			.iov_base = xdr->tail[0].iov_base + base,
+-			.iov_len  = len - base,
+-		};
+-		struct msghdr msg = {
+-			.msg_flags   = msgflags,
+-		};
+-		err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+-		if (ret == 0)
+-			ret = err;
+-		else if (err > 0)
+-			ret += err;
+-	}
+-out:
+-	return ret;
+-}
+-
+ 
+ /*
+  * Helper routines for doing 'memmove' like operations on a struct xdr_buf
+diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -10,12 +10,12 @@
+  *	one is available. Otherwise, it sleeps on the backlog queue
+  *	(xprt_reserve).
+  *  -	Next, the caller puts together the RPC message, stuffs it into
+- *	the request struct, and calls xprt_call().
+- *  -	xprt_call transmits the message and installs the caller on the
+- *	socket's wait list. At the same time, it installs a timer that
++ *	the request struct, and calls xprt_transmit().
++ *  -	xprt_transmit sends the message and installs the caller on the
++ *	transport's wait list. At the same time, it installs a timer that
+  *	is run after the packet's timeout has expired.
+  *  -	When a packet arrives, the data_ready handler walks the list of
+- *	pending requests for that socket. If a matching XID is found, the
++ *	pending requests for that transport. If a matching XID is found, the
+  *	caller is woken up, and the timer removed.
+  *  -	When no reply arrives within the timeout interval, the timer is
+  *	fired by the kernel and runs xprt_timer(). It either adjusts the
+@@ -33,36 +33,17 @@
+  *
+  *  Copyright (C) 1995-1997, Olaf Kirch <okir at monad.swb.de>
+  *
+- *  TCP callback races fixes (C) 1998 Red Hat Software <alan at redhat.com>
+- *  TCP send fixes (C) 1998 Red Hat Software <alan at redhat.com>
+- *  TCP NFS related read + write fixes
+- *   (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied at linux.ie>
+- *
+- *  Rewrite of larges part of the code in order to stabilize TCP stuff.
+- *  Fix behaviour when socket buffer is full.
+- *   (C) 1999 Trond Myklebust <trond.myklebust at fys.uio.no>
++ *  Transport switch API copyright (C) 2005, Chuck Lever <cel at netapp.com>
+  */
+ 
++#include <linux/module.h>
++
+ #include <linux/types.h>
+-#include <linux/slab.h>
+-#include <linux/capability.h>
+-#include <linux/sched.h>
+-#include <linux/errno.h>
+-#include <linux/socket.h>
+-#include <linux/in.h>
+-#include <linux/net.h>
+-#include <linux/mm.h>
+-#include <linux/udp.h>
+-#include <linux/tcp.h>
+-#include <linux/sunrpc/clnt.h>
+-#include <linux/file.h>
++#include <linux/interrupt.h>
+ #include <linux/workqueue.h>
+ #include <linux/random.h>
+ 
+-#include <net/sock.h>
+-#include <net/checksum.h>
+-#include <net/udp.h>
+-#include <net/tcp.h>
++#include <linux/sunrpc/clnt.h>
+ 
+ /*
+  * Local variables
+@@ -73,81 +54,90 @@
+ # define RPCDBG_FACILITY	RPCDBG_XPRT
+ #endif
+ 
+-#define XPRT_MAX_BACKOFF	(8)
+-#define XPRT_IDLE_TIMEOUT	(5*60*HZ)
+-#define XPRT_MAX_RESVPORT	(800)
+-
+ /*
+  * Local functions
+  */
+ static void	xprt_request_init(struct rpc_task *, struct rpc_xprt *);
+ static inline void	do_xprt_reserve(struct rpc_task *);
+-static void	xprt_disconnect(struct rpc_xprt *);
+ static void	xprt_connect_status(struct rpc_task *task);
+-static struct rpc_xprt * xprt_setup(int proto, struct sockaddr_in *ap,
+-						struct rpc_timeout *to);
+-static struct socket *xprt_create_socket(struct rpc_xprt *, int, int);
+-static void	xprt_bind_socket(struct rpc_xprt *, struct socket *);
+ static int      __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
+ 
+-static int	xprt_clear_backlog(struct rpc_xprt *xprt);
+-
+-#ifdef RPC_DEBUG_DATA
+ /*
+- * Print the buffer contents (first 128 bytes only--just enough for
+- * diropres return).
++ * The transport code maintains an estimate on the maximum number of out-
++ * standing RPC requests, using a smoothed version of the congestion
++ * avoidance implemented in 44BSD. This is basically the Van Jacobson
++ * congestion algorithm: If a retransmit occurs, the congestion window is
++ * halved; otherwise, it is incremented by 1/cwnd when
++ *
++ *	-	a reply is received and
++ *	-	a full number of requests are outstanding and
++ *	-	the congestion window hasn't been updated recently.
++ */
++#define RPC_CWNDSHIFT		(8U)
++#define RPC_CWNDSCALE		(1U << RPC_CWNDSHIFT)
++#define RPC_INITCWND		RPC_CWNDSCALE
++#define RPC_MAXCWND(xprt)	((xprt)->max_reqs << RPC_CWNDSHIFT)
++
++#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
++
++/**
++ * xprt_reserve_xprt - serialize write access to transports
++ * @task: task that is requesting access to the transport
++ *
++ * This prevents mixing the payload of separate requests, and prevents
++ * transport connects from colliding with writes.  No congestion control
++ * is provided.
+  */
+-static void
+-xprt_pktdump(char *msg, u32 *packet, unsigned int count)
++int xprt_reserve_xprt(struct rpc_task *task)
+ {
+-	u8	*buf = (u8 *) packet;
+-	int	j;
++	struct rpc_xprt	*xprt = task->tk_xprt;
++	struct rpc_rqst *req = task->tk_rqstp;
+ 
+-	dprintk("RPC:      %s\n", msg);
+-	for (j = 0; j < count && j < 128; j += 4) {
+-		if (!(j & 31)) {
+-			if (j)
+-				dprintk("\n");
+-			dprintk("0x%04x ", j);
+-		}
+-		dprintk("%02x%02x%02x%02x ",
+-			buf[j], buf[j+1], buf[j+2], buf[j+3]);
++	if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
++		if (task == xprt->snd_task)
++			return 1;
++		if (task == NULL)
++			return 0;
++		goto out_sleep;
+ 	}
+-	dprintk("\n");
+-}
+-#else
+-static inline void
+-xprt_pktdump(char *msg, u32 *packet, unsigned int count)
+-{
+-	/* NOP */
+-}
+-#endif
++	xprt->snd_task = task;
++	if (req) {
++		req->rq_bytes_sent = 0;
++		req->rq_ntrans++;
++	}
++	return 1;
+ 
+-/*
+- * Look up RPC transport given an INET socket
+- */
+-static inline struct rpc_xprt *
+-xprt_from_sock(struct sock *sk)
+-{
+-	return (struct rpc_xprt *) sk->sk_user_data;
++out_sleep:
++	dprintk("RPC: %4d failed to lock transport %p\n",
++			task->tk_pid, xprt);
++	task->tk_timeout = 0;
++	task->tk_status = -EAGAIN;
++	if (req && req->rq_ntrans)
++		rpc_sleep_on(&xprt->resend, task, NULL, NULL);
++	else
++		rpc_sleep_on(&xprt->sending, task, NULL, NULL);
++	return 0;
+ }
+ 
+ /*
+- * Serialize write access to sockets, in order to prevent different
+- * requests from interfering with each other.
+- * Also prevents TCP socket connects from colliding with writes.
++ * xprt_reserve_xprt_cong - serialize write access to transports
++ * @task: task that is requesting access to the transport
++ *
++ * Same as xprt_reserve_xprt, but Van Jacobson congestion control is
++ * integrated into the decision of whether a request is allowed to be
++ * woken up and given access to the transport.
+  */
+-static int
+-__xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
++int xprt_reserve_xprt_cong(struct rpc_task *task)
+ {
++	struct rpc_xprt	*xprt = task->tk_xprt;
+ 	struct rpc_rqst *req = task->tk_rqstp;
+ 
+-	if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate)) {
++	if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
+ 		if (task == xprt->snd_task)
+ 			return 1;
+ 		goto out_sleep;
+ 	}
+-	if (xprt->nocong || __xprt_get_cong(xprt, task)) {
++	if (__xprt_get_cong(xprt, task)) {
+ 		xprt->snd_task = task;
+ 		if (req) {
+ 			req->rq_bytes_sent = 0;
+@@ -156,10 +146,10 @@ __xprt_lock_write(struct rpc_xprt *xprt,
+ 		return 1;
+ 	}
+ 	smp_mb__before_clear_bit();
+-	clear_bit(XPRT_LOCKED, &xprt->sockstate);
++	clear_bit(XPRT_LOCKED, &xprt->state);
+ 	smp_mb__after_clear_bit();
+ out_sleep:
+-	dprintk("RPC: %4d failed to lock socket %p\n", task->tk_pid, xprt);
++	dprintk("RPC: %4d failed to lock transport %p\n", task->tk_pid, xprt);
+ 	task->tk_timeout = 0;
+ 	task->tk_status = -EAGAIN;
+ 	if (req && req->rq_ntrans)
+@@ -169,26 +159,52 @@ out_sleep:
+ 	return 0;
+ }
+ 
+-static inline int
+-xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
++static inline int xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
+ {
+ 	int retval;
+ 
+-	spin_lock_bh(&xprt->sock_lock);
+-	retval = __xprt_lock_write(xprt, task);
+-	spin_unlock_bh(&xprt->sock_lock);
++	spin_lock_bh(&xprt->transport_lock);
++	retval = xprt->ops->reserve_xprt(task);
++	spin_unlock_bh(&xprt->transport_lock);
+ 	return retval;
+ }
+ 
++static void __xprt_lock_write_next(struct rpc_xprt *xprt)
++{
++	struct rpc_task *task;
++	struct rpc_rqst *req;
+ 
+-static void
+-__xprt_lock_write_next(struct rpc_xprt *xprt)
++	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
++		return;
++
++	task = rpc_wake_up_next(&xprt->resend);
++	if (!task) {
++		task = rpc_wake_up_next(&xprt->sending);
++		if (!task)
++			goto out_unlock;
++	}
++
++	req = task->tk_rqstp;
++	xprt->snd_task = task;
++	if (req) {
++		req->rq_bytes_sent = 0;
++		req->rq_ntrans++;
++	}
++	return;
++
++out_unlock:
++	smp_mb__before_clear_bit();
++	clear_bit(XPRT_LOCKED, &xprt->state);
++	smp_mb__after_clear_bit();
++}
++
++static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
+ {
+ 	struct rpc_task *task;
+ 
+-	if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate))
++	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
+ 		return;
+-	if (!xprt->nocong && RPCXPRT_CONGESTED(xprt))
++	if (RPCXPRT_CONGESTED(xprt))
+ 		goto out_unlock;
+ 	task = rpc_wake_up_next(&xprt->resend);
+ 	if (!task) {
+@@ -196,7 +212,7 @@ __xprt_lock_write_next(struct rpc_xprt *
+ 		if (!task)
+ 			goto out_unlock;
+ 	}
+-	if (xprt->nocong || __xprt_get_cong(xprt, task)) {
++	if (__xprt_get_cong(xprt, task)) {
+ 		struct rpc_rqst *req = task->tk_rqstp;
+ 		xprt->snd_task = task;
+ 		if (req) {
+@@ -207,87 +223,52 @@ __xprt_lock_write_next(struct rpc_xprt *
+ 	}
+ out_unlock:
+ 	smp_mb__before_clear_bit();
+-	clear_bit(XPRT_LOCKED, &xprt->sockstate);
++	clear_bit(XPRT_LOCKED, &xprt->state);
+ 	smp_mb__after_clear_bit();
+ }
+ 
+-/*
+- * Releases the socket for use by other requests.
++/**
++ * xprt_release_xprt - allow other requests to use a transport
++ * @xprt: transport with other tasks potentially waiting
++ * @task: task that is releasing access to the transport
++ *
++ * Note that "task" can be NULL.  No congestion control is provided.
+  */
+-static void
+-__xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
++void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
+ {
+ 	if (xprt->snd_task == task) {
+ 		xprt->snd_task = NULL;
+ 		smp_mb__before_clear_bit();
+-		clear_bit(XPRT_LOCKED, &xprt->sockstate);
++		clear_bit(XPRT_LOCKED, &xprt->state);
+ 		smp_mb__after_clear_bit();
+ 		__xprt_lock_write_next(xprt);
+ 	}
+ }
+ 
+-static inline void
+-xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
+-{
+-	spin_lock_bh(&xprt->sock_lock);
+-	__xprt_release_write(xprt, task);
+-	spin_unlock_bh(&xprt->sock_lock);
+-}
+-
+-/*
+- * Write data to socket.
++/**
++ * xprt_release_xprt_cong - allow other requests to use a transport
++ * @xprt: transport with other tasks potentially waiting
++ * @task: task that is releasing access to the transport
++ *
++ * Note that "task" can be NULL.  Another task is awoken to use the
++ * transport if the transport's congestion window allows it.
+  */
+-static inline int
+-xprt_sendmsg(struct rpc_xprt *xprt, struct rpc_rqst *req)
++void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
+ {
+-	struct socket	*sock = xprt->sock;
+-	struct xdr_buf	*xdr = &req->rq_snd_buf;
+-	struct sockaddr *addr = NULL;
+-	int addrlen = 0;
+-	unsigned int	skip;
+-	int		result;
+-
+-	if (!sock)
+-		return -ENOTCONN;
+-
+-	xprt_pktdump("packet data:",
+-				req->rq_svec->iov_base,
+-				req->rq_svec->iov_len);
+-
+-	/* For UDP, we need to provide an address */
+-	if (!xprt->stream) {
+-		addr = (struct sockaddr *) &xprt->addr;
+-		addrlen = sizeof(xprt->addr);
++	if (xprt->snd_task == task) {
++		xprt->snd_task = NULL;
++		smp_mb__before_clear_bit();
++		clear_bit(XPRT_LOCKED, &xprt->state);
++		smp_mb__after_clear_bit();
++		__xprt_lock_write_next_cong(xprt);
+ 	}
+-	/* Dont repeat bytes */
+-	skip = req->rq_bytes_sent;
+-
+-	clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
+-	result = xdr_sendpages(sock, addr, addrlen, xdr, skip, MSG_DONTWAIT);
+-
+-	dprintk("RPC:      xprt_sendmsg(%d) = %d\n", xdr->len - skip, result);
+-
+-	if (result >= 0)
+-		return result;
++}
+ 
+-	switch (result) {
+-	case -ECONNREFUSED:
+-		/* When the server has died, an ICMP port unreachable message
+-		 * prompts ECONNREFUSED.
+-		 */
+-	case -EAGAIN:
+-		break;
+-	case -ECONNRESET:
+-	case -ENOTCONN:
+-	case -EPIPE:
+-		/* connection broken */
+-		if (xprt->stream)
+-			result = -ENOTCONN;
+-		break;
+-	default:
+-		printk(KERN_NOTICE "RPC: sendmsg returned error %d\n", -result);
+-	}
+-	return result;
++static inline void xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
++{
++	spin_lock_bh(&xprt->transport_lock);
++	xprt->ops->release_xprt(xprt, task);
++	spin_unlock_bh(&xprt->transport_lock);
+ }
+ 
+ /*
+@@ -321,26 +302,40 @@ __xprt_put_cong(struct rpc_xprt *xprt, s
+ 		return;
+ 	req->rq_cong = 0;
+ 	xprt->cong -= RPC_CWNDSCALE;
+-	__xprt_lock_write_next(xprt);
++	__xprt_lock_write_next_cong(xprt);
+ }
+ 
+-/*
+- * Adjust RPC congestion window
++/**
++ * xprt_release_rqst_cong - housekeeping when request is complete
++ * @task: RPC request that recently completed
++ *
++ * Useful for transports that require congestion control.
++ */
++void xprt_release_rqst_cong(struct rpc_task *task)
++{
++	__xprt_put_cong(task->tk_xprt, task->tk_rqstp);
++}
++
++/**
++ * xprt_adjust_cwnd - adjust transport congestion window
++ * @task: recently completed RPC request used to adjust window
++ * @result: result code of completed RPC request
++ *
+  * We use a time-smoothed congestion estimator to avoid heavy oscillation.
+  */
+-static void
+-xprt_adjust_cwnd(struct rpc_xprt *xprt, int result)
++void xprt_adjust_cwnd(struct rpc_task *task, int result)
+ {
+-	unsigned long	cwnd;
++	struct rpc_rqst *req = task->tk_rqstp;
++	struct rpc_xprt *xprt = task->tk_xprt;
++	unsigned long cwnd = xprt->cwnd;
+ 
+-	cwnd = xprt->cwnd;
+ 	if (result >= 0 && cwnd <= xprt->cong) {
+ 		/* The (cwnd >> 1) term makes sure
+ 		 * the result gets rounded properly. */
+ 		cwnd += (RPC_CWNDSCALE * RPC_CWNDSCALE + (cwnd >> 1)) / cwnd;
+ 		if (cwnd > RPC_MAXCWND(xprt))
+ 			cwnd = RPC_MAXCWND(xprt);
+-		__xprt_lock_write_next(xprt);
++		__xprt_lock_write_next_cong(xprt);
+ 	} else if (result == -ETIMEDOUT) {
+ 		cwnd >>= 1;
+ 		if (cwnd < RPC_CWNDSCALE)
+@@ -349,11 +344,89 @@ xprt_adjust_cwnd(struct rpc_xprt *xprt, 
+ 	dprintk("RPC:      cong %ld, cwnd was %ld, now %ld\n",
+ 			xprt->cong, xprt->cwnd, cwnd);
+ 	xprt->cwnd = cwnd;
++	__xprt_put_cong(xprt, req);
++}
++
++/**
++ * xprt_wake_pending_tasks - wake all tasks on a transport's pending queue
++ * @xprt: transport with waiting tasks
++ * @status: result code to plant in each task before waking it
++ *
++ */
++void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status)
++{
++	if (status < 0)
++		rpc_wake_up_status(&xprt->pending, status);
++	else
++		rpc_wake_up(&xprt->pending);
++}
++
++/**
++ * xprt_wait_for_buffer_space - wait for transport output buffer to clear
++ * @task: task to be put to sleep
++ *
++ */
++void xprt_wait_for_buffer_space(struct rpc_task *task)
++{
++	struct rpc_rqst *req = task->tk_rqstp;
++	struct rpc_xprt *xprt = req->rq_xprt;
++
++	task->tk_timeout = req->rq_timeout;
++	rpc_sleep_on(&xprt->pending, task, NULL, NULL);
++}
++
++/**
++ * xprt_write_space - wake the task waiting for transport output buffer space
++ * @xprt: transport with waiting tasks
++ *
++ * Can be called in a soft IRQ context, so xprt_write_space never sleeps.
++ */
++void xprt_write_space(struct rpc_xprt *xprt)
++{
++	if (unlikely(xprt->shutdown))
++		return;
++
++	spin_lock_bh(&xprt->transport_lock);
++	if (xprt->snd_task) {
++		dprintk("RPC:      write space: waking waiting task on xprt %p\n",
++				xprt);
++		rpc_wake_up_task(xprt->snd_task);
++	}
++	spin_unlock_bh(&xprt->transport_lock);
++}
++
++/**
++ * xprt_set_retrans_timeout_def - set a request's retransmit timeout
++ * @task: task whose timeout is to be set
++ *
++ * Set a request's retransmit timeout based on the transport's
++ * default timeout parameters.  Used by transports that don't adjust
++ * the retransmit timeout based on round-trip time estimation.
++ */
++void xprt_set_retrans_timeout_def(struct rpc_task *task)
++{
++	task->tk_timeout = task->tk_rqstp->rq_timeout;
+ }
+ 
+ /*
+- * Reset the major timeout value
++ * xprt_set_retrans_timeout_rtt - set a request's retransmit timeout
++ * @task: task whose timeout is to be set
++ * 
++ * Set a request's retransmit timeout using the RTT estimator.
+  */
++void xprt_set_retrans_timeout_rtt(struct rpc_task *task)
++{
++	int timer = task->tk_msg.rpc_proc->p_timer;
++	struct rpc_rtt *rtt = task->tk_client->cl_rtt;
++	struct rpc_rqst *req = task->tk_rqstp;
++	unsigned long max_timeout = req->rq_xprt->timeout.to_maxval;
++
++	task->tk_timeout = rpc_calc_rto(rtt, timer);
++	task->tk_timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries;
++	if (task->tk_timeout > max_timeout || task->tk_timeout == 0)
++		task->tk_timeout = max_timeout;
++}
++
+ static void xprt_reset_majortimeo(struct rpc_rqst *req)
+ {
+ 	struct rpc_timeout *to = &req->rq_xprt->timeout;
+@@ -368,8 +441,10 @@ static void xprt_reset_majortimeo(struct
+ 	req->rq_majortimeo += jiffies;
+ }
+ 
+-/*
+- * Adjust timeout values etc for next retransmit
++/**
++ * xprt_adjust_timeout - adjust timeout values for next retransmit
++ * @req: RPC request containing parameters to use for the adjustment
++ *
+  */
+ int xprt_adjust_timeout(struct rpc_rqst *req)
+ {
+@@ -391,9 +466,9 @@ int xprt_adjust_timeout(struct rpc_rqst 
+ 		req->rq_retries = 0;
+ 		xprt_reset_majortimeo(req);
+ 		/* Reset the RTT counters == "slow start" */
+-		spin_lock_bh(&xprt->sock_lock);
++		spin_lock_bh(&xprt->transport_lock);
+ 		rpc_init_rtt(req->rq_task->tk_client->cl_rtt, to->to_initval);
+-		spin_unlock_bh(&xprt->sock_lock);
++		spin_unlock_bh(&xprt->transport_lock);
+ 		pprintk("RPC: %lu timeout\n", jiffies);
+ 		status = -ETIMEDOUT;
+ 	}
+@@ -405,133 +480,52 @@ int xprt_adjust_timeout(struct rpc_rqst 
+ 	return status;
+ }
+ 
+-/*
+- * Close down a transport socket
+- */
+-static void
+-xprt_close(struct rpc_xprt *xprt)
+-{
+-	struct socket	*sock = xprt->sock;
+-	struct sock	*sk = xprt->inet;
+-
+-	if (!sk)
+-		return;
+-
+-	write_lock_bh(&sk->sk_callback_lock);
+-	xprt->inet = NULL;
+-	xprt->sock = NULL;
+-
+-	sk->sk_user_data    = NULL;
+-	sk->sk_data_ready   = xprt->old_data_ready;
+-	sk->sk_state_change = xprt->old_state_change;
+-	sk->sk_write_space  = xprt->old_write_space;
+-	write_unlock_bh(&sk->sk_callback_lock);
+-
+-	sk->sk_no_check	 = 0;
+-
+-	sock_release(sock);
+-}
+-
+-static void
+-xprt_socket_autoclose(void *args)
++static void xprt_autoclose(void *args)
+ {
+ 	struct rpc_xprt *xprt = (struct rpc_xprt *)args;
+ 
+ 	xprt_disconnect(xprt);
+-	xprt_close(xprt);
++	xprt->ops->close(xprt);
+ 	xprt_release_write(xprt, NULL);
+ }
+ 
+-/*
+- * Mark a transport as disconnected
++/**
++ * xprt_disconnect - mark a transport as disconnected
++ * @xprt: transport to flag for disconnect
++ *
+  */
+-static void
+-xprt_disconnect(struct rpc_xprt *xprt)
++void xprt_disconnect(struct rpc_xprt *xprt)
+ {
+ 	dprintk("RPC:      disconnected transport %p\n", xprt);
+-	spin_lock_bh(&xprt->sock_lock);
++	spin_lock_bh(&xprt->transport_lock);
+ 	xprt_clear_connected(xprt);
+-	rpc_wake_up_status(&xprt->pending, -ENOTCONN);
+-	spin_unlock_bh(&xprt->sock_lock);
++	xprt_wake_pending_tasks(xprt, -ENOTCONN);
++	spin_unlock_bh(&xprt->transport_lock);
+ }
+ 
+-/*
+- * Used to allow disconnection when we've been idle
+- */
+ static void
+ xprt_init_autodisconnect(unsigned long data)
+ {
+ 	struct rpc_xprt *xprt = (struct rpc_xprt *)data;
+ 
+-	spin_lock(&xprt->sock_lock);
++	spin_lock(&xprt->transport_lock);
+ 	if (!list_empty(&xprt->recv) || xprt->shutdown)
+ 		goto out_abort;
+-	if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate))
++	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
+ 		goto out_abort;
+-	spin_unlock(&xprt->sock_lock);
+-	/* Let keventd close the socket */
+-	if (test_bit(XPRT_CONNECTING, &xprt->sockstate) != 0)
++	spin_unlock(&xprt->transport_lock);
++	if (xprt_connecting(xprt))
+ 		xprt_release_write(xprt, NULL);
+ 	else
+ 		schedule_work(&xprt->task_cleanup);
+ 	return;
+ out_abort:
+-	spin_unlock(&xprt->sock_lock);
++	spin_unlock(&xprt->transport_lock);
+ }
+ 
+-static void xprt_socket_connect(void *args)
+-{
+-	struct rpc_xprt *xprt = (struct rpc_xprt *)args;
+-	struct socket *sock = xprt->sock;
+-	int status = -EIO;
+-
+-	if (xprt->shutdown || xprt->addr.sin_port == 0)
+-		goto out;
+-
+-	/*
+-	 * Start by resetting any existing state
+-	 */
+-	xprt_close(xprt);
+-	sock = xprt_create_socket(xprt, xprt->prot, xprt->resvport);
+-	if (sock == NULL) {
+-		/* couldn't create socket or bind to reserved port;
+-		 * this is likely a permanent error, so cause an abort */
+-		goto out;
+-	}
+-	xprt_bind_socket(xprt, sock);
+-	xprt_sock_setbufsize(xprt);
+-
+-	status = 0;
+-	if (!xprt->stream)
+-		goto out;
+-
+-	/*
+-	 * Tell the socket layer to start connecting...
+-	 */
+-	status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
+-			sizeof(xprt->addr), O_NONBLOCK);
+-	dprintk("RPC: %p  connect status %d connected %d sock state %d\n",
+-			xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
+-	if (status < 0) {
+-		switch (status) {
+-			case -EINPROGRESS:
+-			case -EALREADY:
+-				goto out_clear;
+-		}
+-	}
+-out:
+-	if (status < 0)
+-		rpc_wake_up_status(&xprt->pending, status);
+-	else
+-		rpc_wake_up(&xprt->pending);
+-out_clear:
+-	smp_mb__before_clear_bit();
+-	clear_bit(XPRT_CONNECTING, &xprt->sockstate);
+-	smp_mb__after_clear_bit();
+-}
+-
+-/*
+- * Attempt to connect a TCP socket.
++/**
++ * xprt_connect - schedule a transport connect operation
++ * @task: RPC task that is requesting the connect
+  *
+  */
+ void xprt_connect(struct rpc_task *task)
+@@ -552,37 +546,19 @@ void xprt_connect(struct rpc_task *task)
+ 	if (!xprt_lock_write(xprt, task))
+ 		return;
+ 	if (xprt_connected(xprt))
+-		goto out_write;
+-
+-	if (task->tk_rqstp)
+-		task->tk_rqstp->rq_bytes_sent = 0;
+-
+-	task->tk_timeout = RPC_CONNECT_TIMEOUT;
+-	rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL);
+-	if (!test_and_set_bit(XPRT_CONNECTING, &xprt->sockstate)) {
+-		/* Note: if we are here due to a dropped connection
+-		 * 	 we delay reconnecting by RPC_REESTABLISH_TIMEOUT/HZ
+-		 * 	 seconds
+-		 */
+-		if (xprt->sock != NULL)
+-			schedule_delayed_work(&xprt->sock_connect,
+-					RPC_REESTABLISH_TIMEOUT);
+-		else {
+-			schedule_work(&xprt->sock_connect);
+-			if (!RPC_IS_ASYNC(task))
+-				flush_scheduled_work();
+-		}
++		xprt_release_write(xprt, task);
++	else {
++		if (task->tk_rqstp)
++			task->tk_rqstp->rq_bytes_sent = 0;
++
++		task->tk_timeout = xprt->connect_timeout;
++		rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL);
++		xprt->ops->connect(task);
+ 	}
+ 	return;
+- out_write:
+-	xprt_release_write(xprt, task);
+ }
+ 
+-/*
+- * We arrive here when awoken from waiting on connection establishment.
+- */
+-static void
+-xprt_connect_status(struct rpc_task *task)
++static void xprt_connect_status(struct rpc_task *task)
+ {
+ 	struct rpc_xprt	*xprt = task->tk_xprt;
+ 
+@@ -592,31 +568,42 @@ xprt_connect_status(struct rpc_task *tas
+ 		return;
+ 	}
+ 
+-	/* if soft mounted, just cause this RPC to fail */
+-	if (RPC_IS_SOFT(task))
+-		task->tk_status = -EIO;
+-
+ 	switch (task->tk_status) {
+ 	case -ECONNREFUSED:
+ 	case -ECONNRESET:
++		dprintk("RPC: %4d xprt_connect_status: server %s refused connection\n",
++				task->tk_pid, task->tk_client->cl_server);
++		break;
+ 	case -ENOTCONN:
+-		return;
++		dprintk("RPC: %4d xprt_connect_status: connection broken\n",
++				task->tk_pid);
++		break;
+ 	case -ETIMEDOUT:
+-		dprintk("RPC: %4d xprt_connect_status: timed out\n",
++		dprintk("RPC: %4d xprt_connect_status: connect attempt timed out\n",
+ 				task->tk_pid);
+ 		break;
+ 	default:
+-		printk(KERN_ERR "RPC: error %d connecting to server %s\n",
+-				-task->tk_status, task->tk_client->cl_server);
++		dprintk("RPC: %4d xprt_connect_status: error %d connecting to server %s\n",
++				task->tk_pid, -task->tk_status, task->tk_client->cl_server);
++		xprt_release_write(xprt, task);
++		task->tk_status = -EIO;
++		return;
++	}
++
++	/* if soft mounted, just cause this RPC to fail */
++	if (RPC_IS_SOFT(task)) {
++		xprt_release_write(xprt, task);
++		task->tk_status = -EIO;
+ 	}
+-	xprt_release_write(xprt, task);
+ }
+ 
+-/*
+- * Look up the RPC request corresponding to a reply, and then lock it.
++/**
++ * xprt_lookup_rqst - find an RPC request corresponding to an XID
++ * @xprt: transport on which the original request was transmitted
++ * @xid: RPC XID of incoming reply
++ *
+  */
+-static inline struct rpc_rqst *
+-xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
++struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
+ {
+ 	struct list_head *pos;
+ 	struct rpc_rqst	*req = NULL;
+@@ -631,556 +618,68 @@ xprt_lookup_rqst(struct rpc_xprt *xprt, 
+ 	return req;
+ }
+ 
+-/*
+- * Complete reply received.
+- * The TCP code relies on us to remove the request from xprt->pending.
+- */
+-static void
+-xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied)
+-{
+-	struct rpc_task	*task = req->rq_task;
+-	struct rpc_clnt *clnt = task->tk_client;
+-
+-	/* Adjust congestion window */
+-	if (!xprt->nocong) {
+-		unsigned timer = task->tk_msg.rpc_proc->p_timer;
+-		xprt_adjust_cwnd(xprt, copied);
+-		__xprt_put_cong(xprt, req);
+-		if (timer) {
+-			if (req->rq_ntrans == 1)
+-				rpc_update_rtt(clnt->cl_rtt, timer,
+-						(long)jiffies - req->rq_xtime);
+-			rpc_set_timeo(clnt->cl_rtt, timer, req->rq_ntrans - 1);
+-		}
+-	}
+-
+-#ifdef RPC_PROFILE
+-	/* Profile only reads for now */
+-	if (copied > 1024) {
+-		static unsigned long	nextstat;
+-		static unsigned long	pkt_rtt, pkt_len, pkt_cnt;
+-
+-		pkt_cnt++;
+-		pkt_len += req->rq_slen + copied;
+-		pkt_rtt += jiffies - req->rq_xtime;
+-		if (time_before(nextstat, jiffies)) {
+-			printk("RPC: %lu %ld cwnd\n", jiffies, xprt->cwnd);
+-			printk("RPC: %ld %ld %ld %ld stat\n",
+-					jiffies, pkt_cnt, pkt_len, pkt_rtt);
+-			pkt_rtt = pkt_len = pkt_cnt = 0;
+-			nextstat = jiffies + 5 * HZ;
+-		}
+-	}
+-#endif
+-
+-	dprintk("RPC: %4d has input (%d bytes)\n", task->tk_pid, copied);
+-	list_del_init(&req->rq_list);
+-	req->rq_received = req->rq_private_buf.len = copied;
+-
+-	/* ... and wake up the process. */
+-	rpc_wake_up_task(task);
+-	return;
+-}
+-
+-static size_t
+-skb_read_bits(skb_reader_t *desc, void *to, size_t len)
+-{
+-	if (len > desc->count)
+-		len = desc->count;
+-	if (skb_copy_bits(desc->skb, desc->offset, to, len))
+-		return 0;
+-	desc->count -= len;
+-	desc->offset += len;
+-	return len;
+-}
+-
+-static size_t
+-skb_read_and_csum_bits(skb_reader_t *desc, void *to, size_t len)
+-{
+-	unsigned int csum2, pos;
+-
+-	if (len > desc->count)
+-		len = desc->count;
+-	pos = desc->offset;
+-	csum2 = skb_copy_and_csum_bits(desc->skb, pos, to, len, 0);
+-	desc->csum = csum_block_add(desc->csum, csum2, pos);
+-	desc->count -= len;
+-	desc->offset += len;
+-	return len;
+-}
+-
+-/*
+- * We have set things up such that we perform the checksum of the UDP
+- * packet in parallel with the copies into the RPC client iovec.  -DaveM
+- */
+-int
+-csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
+-{
+-	skb_reader_t desc;
+-
+-	desc.skb = skb;
+-	desc.offset = sizeof(struct udphdr);
+-	desc.count = skb->len - desc.offset;
+-
+-	if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+-		goto no_checksum;
+-
+-	desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
+-	if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0)
+-		return -1;
+-	if (desc.offset != skb->len) {
+-		unsigned int csum2;
+-		csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
+-		desc.csum = csum_block_add(desc.csum, csum2, desc.offset);
+-	}
+-	if (desc.count)
+-		return -1;
+-	if ((unsigned short)csum_fold(desc.csum))
+-		return -1;
+-	return 0;
+-no_checksum:
+-	if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
+-		return -1;
+-	if (desc.count)
+-		return -1;
+-	return 0;
+-}
+-
+-/*
+- * Input handler for RPC replies. Called from a bottom half and hence
+- * atomic.
+- */
+-static void
+-udp_data_ready(struct sock *sk, int len)
+-{
+-	struct rpc_task	*task;
+-	struct rpc_xprt	*xprt;
+-	struct rpc_rqst *rovr;
+-	struct sk_buff	*skb;
+-	int err, repsize, copied;
+-	u32 _xid, *xp;
+-
+-	read_lock(&sk->sk_callback_lock);
+-	dprintk("RPC:      udp_data_ready...\n");
+-	if (!(xprt = xprt_from_sock(sk))) {
+-		printk("RPC:      udp_data_ready request not found!\n");
+-		goto out;
+-	}
+-
+-	dprintk("RPC:      udp_data_ready client %p\n", xprt);
+-
+-	if ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL)
+-		goto out;
+-
+-	if (xprt->shutdown)
+-		goto dropit;
+-
+-	repsize = skb->len - sizeof(struct udphdr);
+-	if (repsize < 4) {
+-		printk("RPC: impossible RPC reply size %d!\n", repsize);
+-		goto dropit;
+-	}
+-
+-	/* Copy the XID from the skb... */
+-	xp = skb_header_pointer(skb, sizeof(struct udphdr),
+-				sizeof(_xid), &_xid);
+-	if (xp == NULL)
+-		goto dropit;
+-
+-	/* Look up and lock the request corresponding to the given XID */
+-	spin_lock(&xprt->sock_lock);
+-	rovr = xprt_lookup_rqst(xprt, *xp);
+-	if (!rovr)
+-		goto out_unlock;
+-	task = rovr->rq_task;
+-
+-	dprintk("RPC: %4d received reply\n", task->tk_pid);
+-
+-	if ((copied = rovr->rq_private_buf.buflen) > repsize)
+-		copied = repsize;
+-
+-	/* Suck it into the iovec, verify checksum if not done by hw. */
+-	if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb))
+-		goto out_unlock;
+-
+-	/* Something worked... */
+-	dst_confirm(skb->dst);
+-
+-	xprt_complete_rqst(xprt, rovr, copied);
+-
+- out_unlock:
+-	spin_unlock(&xprt->sock_lock);
+- dropit:
+-	skb_free_datagram(sk, skb);
+- out:
+-	read_unlock(&sk->sk_callback_lock);
+-}
+-
+-/*
+- * Copy from an skb into memory and shrink the skb.
+- */
+-static inline size_t
+-tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
+-{
+-	if (len > desc->count)
+-		len = desc->count;
+-	if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
+-		dprintk("RPC:      failed to copy %zu bytes from skb. %zu bytes remain\n",
+-				len, desc->count);
+-		return 0;
+-	}
+-	desc->offset += len;
+-	desc->count -= len;
+-	dprintk("RPC:      copied %zu bytes from skb. %zu bytes remain\n",
+-			len, desc->count);
+-	return len;
+-}
+-
+-/*
+- * TCP read fragment marker
+- */
+-static inline void
+-tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
+-{
+-	size_t len, used;
+-	char *p;
+-
+-	p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
+-	len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
+-	used = tcp_copy_data(desc, p, len);
+-	xprt->tcp_offset += used;
+-	if (used != len)
+-		return;
+-	xprt->tcp_reclen = ntohl(xprt->tcp_recm);
+-	if (xprt->tcp_reclen & 0x80000000)
+-		xprt->tcp_flags |= XPRT_LAST_FRAG;
+-	else
+-		xprt->tcp_flags &= ~XPRT_LAST_FRAG;
+-	xprt->tcp_reclen &= 0x7fffffff;
+-	xprt->tcp_flags &= ~XPRT_COPY_RECM;
+-	xprt->tcp_offset = 0;
+-	/* Sanity check of the record length */
+-	if (xprt->tcp_reclen < 4) {
+-		printk(KERN_ERR "RPC: Invalid TCP record fragment length\n");
+-		xprt_disconnect(xprt);
+-	}
+-	dprintk("RPC:      reading TCP record fragment of length %d\n",
+-			xprt->tcp_reclen);
+-}
+-
+-static void
+-tcp_check_recm(struct rpc_xprt *xprt)
+-{
+-	dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
+-			xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
+-	if (xprt->tcp_offset == xprt->tcp_reclen) {
+-		xprt->tcp_flags |= XPRT_COPY_RECM;
+-		xprt->tcp_offset = 0;
+-		if (xprt->tcp_flags & XPRT_LAST_FRAG) {
+-			xprt->tcp_flags &= ~XPRT_COPY_DATA;
+-			xprt->tcp_flags |= XPRT_COPY_XID;
+-			xprt->tcp_copied = 0;
+-		}
+-	}
+-}
+-
+-/*
+- * TCP read xid
+- */
+-static inline void
+-tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
+-{
+-	size_t len, used;
+-	char *p;
+-
+-	len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
+-	dprintk("RPC:      reading XID (%Zu bytes)\n", len);
+-	p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
+-	used = tcp_copy_data(desc, p, len);
+-	xprt->tcp_offset += used;
+-	if (used != len)
+-		return;
+-	xprt->tcp_flags &= ~XPRT_COPY_XID;
+-	xprt->tcp_flags |= XPRT_COPY_DATA;
+-	xprt->tcp_copied = 4;
+-	dprintk("RPC:      reading reply for XID %08x\n",
+-						ntohl(xprt->tcp_xid));
+-	tcp_check_recm(xprt);
+-}
+-
+-/*
+- * TCP read and complete request
+- */
+-static inline void
+-tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
+-{
+-	struct rpc_rqst *req;
+-	struct xdr_buf *rcvbuf;
+-	size_t len;
+-	ssize_t r;
+-
+-	/* Find and lock the request corresponding to this xid */
+-	spin_lock(&xprt->sock_lock);
+-	req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
+-	if (!req) {
+-		xprt->tcp_flags &= ~XPRT_COPY_DATA;
+-		dprintk("RPC:      XID %08x request not found!\n",
+-				ntohl(xprt->tcp_xid));
+-		spin_unlock(&xprt->sock_lock);
+-		return;
+-	}
+-
+-	rcvbuf = &req->rq_private_buf;
+-	len = desc->count;
+-	if (len > xprt->tcp_reclen - xprt->tcp_offset) {
+-		skb_reader_t my_desc;
+-
+-		len = xprt->tcp_reclen - xprt->tcp_offset;
+-		memcpy(&my_desc, desc, sizeof(my_desc));
+-		my_desc.count = len;
+-		r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+-					  &my_desc, tcp_copy_data);
+-		desc->count -= r;
+-		desc->offset += r;
+-	} else
+-		r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+-					  desc, tcp_copy_data);
+-
+-	if (r > 0) {
+-		xprt->tcp_copied += r;
+-		xprt->tcp_offset += r;
+-	}
+-	if (r != len) {
+-		/* Error when copying to the receive buffer,
+-		 * usually because we weren't able to allocate
+-		 * additional buffer pages. All we can do now
+-		 * is turn off XPRT_COPY_DATA, so the request
+-		 * will not receive any additional updates,
+-		 * and time out.
+-		 * Any remaining data from this record will
+-		 * be discarded.
+-		 */
+-		xprt->tcp_flags &= ~XPRT_COPY_DATA;
+-		dprintk("RPC:      XID %08x truncated request\n",
+-				ntohl(xprt->tcp_xid));
+-		dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
+-				xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
+-		goto out;
+-	}
+-
+-	dprintk("RPC:      XID %08x read %Zd bytes\n",
+-			ntohl(xprt->tcp_xid), r);
+-	dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
+-			xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
+-
+-	if (xprt->tcp_copied == req->rq_private_buf.buflen)
+-		xprt->tcp_flags &= ~XPRT_COPY_DATA;
+-	else if (xprt->tcp_offset == xprt->tcp_reclen) {
+-		if (xprt->tcp_flags & XPRT_LAST_FRAG)
+-			xprt->tcp_flags &= ~XPRT_COPY_DATA;
+-	}
+-
+-out:
+-	if (!(xprt->tcp_flags & XPRT_COPY_DATA)) {
+-		dprintk("RPC: %4d received reply complete\n",
+-				req->rq_task->tk_pid);
+-		xprt_complete_rqst(xprt, req, xprt->tcp_copied);
+-	}
+-	spin_unlock(&xprt->sock_lock);
+-	tcp_check_recm(xprt);
+-}
+-
+-/*
+- * TCP discard extra bytes from a short read
+- */
+-static inline void
+-tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
+-{
+-	size_t len;
+-
+-	len = xprt->tcp_reclen - xprt->tcp_offset;
+-	if (len > desc->count)
+-		len = desc->count;
+-	desc->count -= len;
+-	desc->offset += len;
+-	xprt->tcp_offset += len;
+-	dprintk("RPC:      discarded %Zu bytes\n", len);
+-	tcp_check_recm(xprt);
+-}
+-
+-/*
+- * TCP record receive routine
+- * We first have to grab the record marker, then the XID, then the data.
++/**
++ * xprt_update_rtt - update an RPC client's RTT state after receiving a reply
++ * @task: RPC request that recently completed
++ *
+  */
+-static int
+-tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
+-		unsigned int offset, size_t len)
++void xprt_update_rtt(struct rpc_task *task)
+ {
+-	struct rpc_xprt *xprt = rd_desc->arg.data;
+-	skb_reader_t desc = {
+-		.skb	= skb,
+-		.offset	= offset,
+-		.count	= len,
+-		.csum	= 0
+-       	};
+-
+-	dprintk("RPC:      tcp_data_recv\n");
+-	do {
+-		/* Read in a new fragment marker if necessary */
+-		/* Can we ever really expect to get completely empty fragments? */
+-		if (xprt->tcp_flags & XPRT_COPY_RECM) {
+-			tcp_read_fraghdr(xprt, &desc);
+-			continue;
+-		}
+-		/* Read in the xid if necessary */
+-		if (xprt->tcp_flags & XPRT_COPY_XID) {
+-			tcp_read_xid(xprt, &desc);
+-			continue;
+-		}
+-		/* Read in the request data */
+-		if (xprt->tcp_flags & XPRT_COPY_DATA) {
+-			tcp_read_request(xprt, &desc);
+-			continue;
+-		}
+-		/* Skip over any trailing bytes on short reads */
+-		tcp_read_discard(xprt, &desc);
+-	} while (desc.count);
+-	dprintk("RPC:      tcp_data_recv done\n");
+-	return len - desc.count;
+-}
+-
+-static void tcp_data_ready(struct sock *sk, int bytes)
+-{
+-	struct rpc_xprt *xprt;
+-	read_descriptor_t rd_desc;
+-
+-	read_lock(&sk->sk_callback_lock);
+-	dprintk("RPC:      tcp_data_ready...\n");
+-	if (!(xprt = xprt_from_sock(sk))) {
+-		printk("RPC:      tcp_data_ready socket info not found!\n");
+-		goto out;
+-	}
+-	if (xprt->shutdown)
+-		goto out;
+-
+-	/* We use rd_desc to pass struct xprt to tcp_data_recv */
+-	rd_desc.arg.data = xprt;
+-	rd_desc.count = 65536;
+-	tcp_read_sock(sk, &rd_desc, tcp_data_recv);
+-out:
+-	read_unlock(&sk->sk_callback_lock);
+-}
+-
+-static void
+-tcp_state_change(struct sock *sk)
+-{
+-	struct rpc_xprt	*xprt;
++	struct rpc_rqst *req = task->tk_rqstp;
++	struct rpc_rtt *rtt = task->tk_client->cl_rtt;
++	unsigned timer = task->tk_msg.rpc_proc->p_timer;
+ 
+-	read_lock(&sk->sk_callback_lock);
+-	if (!(xprt = xprt_from_sock(sk)))
+-		goto out;
+-	dprintk("RPC:      tcp_state_change client %p...\n", xprt);
+-	dprintk("RPC:      state %x conn %d dead %d zapped %d\n",
+-				sk->sk_state, xprt_connected(xprt),
+-				sock_flag(sk, SOCK_DEAD),
+-				sock_flag(sk, SOCK_ZAPPED));
+-
+-	switch (sk->sk_state) {
+-	case TCP_ESTABLISHED:
+-		spin_lock_bh(&xprt->sock_lock);
+-		if (!xprt_test_and_set_connected(xprt)) {
+-			/* Reset TCP record info */
+-			xprt->tcp_offset = 0;
+-			xprt->tcp_reclen = 0;
+-			xprt->tcp_copied = 0;
+-			xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
+-			rpc_wake_up(&xprt->pending);
+-		}
+-		spin_unlock_bh(&xprt->sock_lock);
+-		break;
+-	case TCP_SYN_SENT:
+-	case TCP_SYN_RECV:
+-		break;
+-	default:
+-		xprt_disconnect(xprt);
+-		break;
++	if (timer) {
++		if (req->rq_ntrans == 1)
++			rpc_update_rtt(rtt, timer,
++					(long)jiffies - req->rq_xtime);
++		rpc_set_timeo(rtt, timer, req->rq_ntrans - 1);
+ 	}
+- out:
+-	read_unlock(&sk->sk_callback_lock);
+ }
+ 
+-/*
+- * Called when more output buffer space is available for this socket.
+- * We try not to wake our writers until they can make "significant"
+- * progress, otherwise we'll waste resources thrashing sock_sendmsg
+- * with a bunch of small requests.
++/**
++ * xprt_complete_rqst - called when reply processing is complete
++ * @task: RPC request that recently completed
++ * @copied: actual number of bytes received from the transport
++ *
++ * Caller holds transport lock.
+  */
+-static void
+-xprt_write_space(struct sock *sk)
++void xprt_complete_rqst(struct rpc_task *task, int copied)
+ {
+-	struct rpc_xprt	*xprt;
+-	struct socket	*sock;
+-
+-	read_lock(&sk->sk_callback_lock);
+-	if (!(xprt = xprt_from_sock(sk)) || !(sock = sk->sk_socket))
+-		goto out;
+-	if (xprt->shutdown)
+-		goto out;
+-
+-	/* Wait until we have enough socket memory */
+-	if (xprt->stream) {
+-		/* from net/core/stream.c:sk_stream_write_space */
+-		if (sk_stream_wspace(sk) < sk_stream_min_wspace(sk))
+-			goto out;
+-	} else {
+-		/* from net/core/sock.c:sock_def_write_space */
+-		if (!sock_writeable(sk))
+-			goto out;
+-	}
++	struct rpc_rqst *req = task->tk_rqstp;
+ 
+-	if (!test_and_clear_bit(SOCK_NOSPACE, &sock->flags))
+-		goto out;
++	dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
++			task->tk_pid, ntohl(req->rq_xid), copied);
+ 
+-	spin_lock_bh(&xprt->sock_lock);
+-	if (xprt->snd_task)
+-		rpc_wake_up_task(xprt->snd_task);
+-	spin_unlock_bh(&xprt->sock_lock);
+-out:
+-	read_unlock(&sk->sk_callback_lock);
++	list_del_init(&req->rq_list);
++	req->rq_received = req->rq_private_buf.len = copied;
++	rpc_wake_up_task(task);
+ }
+ 
+-/*
+- * RPC receive timeout handler.
+- */
+-static void
+-xprt_timer(struct rpc_task *task)
++static void xprt_timer(struct rpc_task *task)
+ {
+-	struct rpc_rqst	*req = task->tk_rqstp;
++	struct rpc_rqst *req = task->tk_rqstp;
+ 	struct rpc_xprt *xprt = req->rq_xprt;
+ 
+-	spin_lock(&xprt->sock_lock);
+-	if (req->rq_received)
+-		goto out;
++	dprintk("RPC: %4d xprt_timer\n", task->tk_pid);
+ 
+-	xprt_adjust_cwnd(req->rq_xprt, -ETIMEDOUT);
+-	__xprt_put_cong(xprt, req);
+-
+-	dprintk("RPC: %4d xprt_timer (%s request)\n",
+-		task->tk_pid, req ? "pending" : "backlogged");
+-
+-	task->tk_status  = -ETIMEDOUT;
+-out:
++	spin_lock(&xprt->transport_lock);
++	if (!req->rq_received) {
++		if (xprt->ops->timer)
++			xprt->ops->timer(task);
++		task->tk_status = -ETIMEDOUT;
++	}
+ 	task->tk_timeout = 0;
+ 	rpc_wake_up_task(task);
+-	spin_unlock(&xprt->sock_lock);
++	spin_unlock(&xprt->transport_lock);
+ }
+ 
+-/*
+- * Place the actual RPC call.
+- * We have to copy the iovec because sendmsg fiddles with its contents.
++/**
++ * xprt_prepare_transmit - reserve the transport before sending a request
++ * @task: RPC task about to send a request
++ *
+  */
+-int
+-xprt_prepare_transmit(struct rpc_task *task)
++int xprt_prepare_transmit(struct rpc_task *task)
+ {
+ 	struct rpc_rqst	*req = task->tk_rqstp;
+ 	struct rpc_xprt	*xprt = req->rq_xprt;
+@@ -1191,12 +690,12 @@ xprt_prepare_transmit(struct rpc_task *t
+ 	if (xprt->shutdown)
+ 		return -EIO;
+ 
+-	spin_lock_bh(&xprt->sock_lock);
++	spin_lock_bh(&xprt->transport_lock);
+ 	if (req->rq_received && !req->rq_bytes_sent) {
+ 		err = req->rq_received;
+ 		goto out_unlock;
+ 	}
+-	if (!__xprt_lock_write(xprt, task)) {
++	if (!xprt->ops->reserve_xprt(task)) {
+ 		err = -EAGAIN;
+ 		goto out_unlock;
+ 	}
+@@ -1206,39 +705,42 @@ xprt_prepare_transmit(struct rpc_task *t
+ 		goto out_unlock;
+ 	}
+ out_unlock:
+-	spin_unlock_bh(&xprt->sock_lock);
++	spin_unlock_bh(&xprt->transport_lock);
+ 	return err;
+ }
+ 
+ void
+-xprt_transmit(struct rpc_task *task)
++xprt_abort_transmit(struct rpc_task *task)
++{
++	struct rpc_xprt	*xprt = task->tk_xprt;
++
++	xprt_release_write(xprt, task);
++}
++
++/**
++ * xprt_transmit - send an RPC request on a transport
++ * @task: controlling RPC task
++ *
++ * We have to copy the iovec because sendmsg fiddles with its contents.
++ */
++void xprt_transmit(struct rpc_task *task)
+ {
+-	struct rpc_clnt *clnt = task->tk_client;
+ 	struct rpc_rqst	*req = task->tk_rqstp;
+ 	struct rpc_xprt	*xprt = req->rq_xprt;
+-	int status, retry = 0;
+-
++	int status;
+ 
+ 	dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
+ 
+-	/* set up everything as needed. */
+-	/* Write the record marker */
+-	if (xprt->stream) {
+-		u32	*marker = req->rq_svec[0].iov_base;
+-
+-		*marker = htonl(0x80000000|(req->rq_slen-sizeof(*marker)));
+-	}
+-
+ 	smp_rmb();
+ 	if (!req->rq_received) {
+ 		if (list_empty(&req->rq_list)) {
+-			spin_lock_bh(&xprt->sock_lock);
++			spin_lock_bh(&xprt->transport_lock);
+ 			/* Update the softirq receive buffer */
+ 			memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
+ 					sizeof(req->rq_private_buf));
+ 			/* Add request to the receive list */
+ 			list_add_tail(&req->rq_list, &xprt->recv);
+-			spin_unlock_bh(&xprt->sock_lock);
++			spin_unlock_bh(&xprt->transport_lock);
+ 			xprt_reset_majortimeo(req);
+ 			/* Turn off autodisconnect */
+ 			del_singleshot_timer_sync(&xprt->timer);
+@@ -1246,40 +748,19 @@ xprt_transmit(struct rpc_task *task)
+ 	} else if (!req->rq_bytes_sent)
+ 		return;
+ 
+-	/* Continue transmitting the packet/record. We must be careful
+-	 * to cope with writespace callbacks arriving _after_ we have
+-	 * called xprt_sendmsg().
+-	 */
+-	while (1) {
+-		req->rq_xtime = jiffies;
+-		status = xprt_sendmsg(xprt, req);
+-
+-		if (status < 0)
+-			break;
+-
+-		if (xprt->stream) {
+-			req->rq_bytes_sent += status;
+-
+-			/* If we've sent the entire packet, immediately
+-			 * reset the count of bytes sent. */
+-			if (req->rq_bytes_sent >= req->rq_slen) {
+-				req->rq_bytes_sent = 0;
+-				goto out_receive;
+-			}
+-		} else {
+-			if (status >= req->rq_slen)
+-				goto out_receive;
+-			status = -EAGAIN;
+-			break;
+-		}
+-
+-		dprintk("RPC: %4d xmit incomplete (%d left of %d)\n",
+-				task->tk_pid, req->rq_slen - req->rq_bytes_sent,
+-				req->rq_slen);
+-
+-		status = -EAGAIN;
+-		if (retry++ > 50)
+-			break;
++	status = xprt->ops->send_request(task);
++	if (status == 0) {
++		dprintk("RPC: %4d xmit complete\n", task->tk_pid);
++		spin_lock_bh(&xprt->transport_lock);
++		xprt->ops->set_retrans_timeout(task);
++		/* Don't race with disconnect */
++		if (!xprt_connected(xprt))
++			task->tk_status = -ENOTCONN;
++		else if (!req->rq_received)
++			rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer);
++		xprt->ops->release_xprt(xprt, task);
++		spin_unlock_bh(&xprt->transport_lock);
++		return;
+ 	}
+ 
+ 	/* Note: at this point, task->tk_sleeping has not yet been set,
+@@ -1289,60 +770,19 @@ xprt_transmit(struct rpc_task *task)
+ 	task->tk_status = status;
+ 
+ 	switch (status) {
+-	case -EAGAIN:
+-		if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) {
+-			/* Protect against races with xprt_write_space */
+-			spin_lock_bh(&xprt->sock_lock);
+-			/* Don't race with disconnect */
+-			if (!xprt_connected(xprt))
+-				task->tk_status = -ENOTCONN;
+-			else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags)) {
+-				task->tk_timeout = req->rq_timeout;
+-				rpc_sleep_on(&xprt->pending, task, NULL, NULL);
+-			}
+-			spin_unlock_bh(&xprt->sock_lock);
+-			return;
+-		}
+-		/* Keep holding the socket if it is blocked */
+-		rpc_delay(task, HZ>>4);
+-		return;
+ 	case -ECONNREFUSED:
+-		task->tk_timeout = RPC_REESTABLISH_TIMEOUT;
+ 		rpc_sleep_on(&xprt->sending, task, NULL, NULL);
++	case -EAGAIN:
+ 	case -ENOTCONN:
+ 		return;
+ 	default:
+-		if (xprt->stream)
+-			xprt_disconnect(xprt);
++		break;
+ 	}
+ 	xprt_release_write(xprt, task);
+ 	return;
+- out_receive:
+-	dprintk("RPC: %4d xmit complete\n", task->tk_pid);
+-	/* Set the task's receive timeout value */
+-	spin_lock_bh(&xprt->sock_lock);
+-	if (!xprt->nocong) {
+-		int timer = task->tk_msg.rpc_proc->p_timer;
+-		task->tk_timeout = rpc_calc_rto(clnt->cl_rtt, timer);
+-		task->tk_timeout <<= rpc_ntimeo(clnt->cl_rtt, timer) + req->rq_retries;
+-		if (task->tk_timeout > xprt->timeout.to_maxval || task->tk_timeout == 0)
+-			task->tk_timeout = xprt->timeout.to_maxval;
+-	} else
+-		task->tk_timeout = req->rq_timeout;
+-	/* Don't race with disconnect */
+-	if (!xprt_connected(xprt))
+-		task->tk_status = -ENOTCONN;
+-	else if (!req->rq_received)
+-		rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer);
+-	__xprt_release_write(xprt, task);
+-	spin_unlock_bh(&xprt->sock_lock);
+ }
+ 
+-/*
+- * Reserve an RPC call slot.
+- */
+-static inline void
+-do_xprt_reserve(struct rpc_task *task)
++static inline void do_xprt_reserve(struct rpc_task *task)
+ {
+ 	struct rpc_xprt	*xprt = task->tk_xprt;
+ 
+@@ -1362,22 +802,25 @@ do_xprt_reserve(struct rpc_task *task)
+ 	rpc_sleep_on(&xprt->backlog, task, NULL, NULL);
+ }
+ 
+-void
+-xprt_reserve(struct rpc_task *task)
++/**
++ * xprt_reserve - allocate an RPC request slot
++ * @task: RPC task requesting a slot allocation
++ *
++ * If no more slots are available, place the task on the transport's
++ * backlog queue.
++ */
++void xprt_reserve(struct rpc_task *task)
+ {
+ 	struct rpc_xprt	*xprt = task->tk_xprt;
+ 
+ 	task->tk_status = -EIO;
+ 	if (!xprt->shutdown) {
+-		spin_lock(&xprt->xprt_lock);
++		spin_lock(&xprt->reserve_lock);
+ 		do_xprt_reserve(task);
+-		spin_unlock(&xprt->xprt_lock);
++		spin_unlock(&xprt->reserve_lock);
+ 	}
+ }
+ 
+-/*
+- * Allocate a 'unique' XID
+- */
+ static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
+ {
+ 	return xprt->xid++;
+@@ -1388,11 +831,7 @@ static inline void xprt_init_xid(struct 
+ 	get_random_bytes(&xprt->xid, sizeof(xprt->xid));
+ }
+ 
+-/*
+- * Initialize RPC request
+- */
+-static void
+-xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
++static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
+ {
+ 	struct rpc_rqst	*req = task->tk_rqstp;
+ 
+@@ -1400,128 +839,104 @@ xprt_request_init(struct rpc_task *task,
+ 	req->rq_task	= task;
+ 	req->rq_xprt    = xprt;
+ 	req->rq_xid     = xprt_alloc_xid(xprt);
++	req->rq_release_snd_buf = NULL;
+ 	dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
+ 			req, ntohl(req->rq_xid));
+ }
+ 
+-/*
+- * Release an RPC call slot
++/**
++ * xprt_release - release an RPC request slot
++ * @task: task which is finished with the slot
++ *
+  */
+-void
+-xprt_release(struct rpc_task *task)
++void xprt_release(struct rpc_task *task)
+ {
+ 	struct rpc_xprt	*xprt = task->tk_xprt;
+ 	struct rpc_rqst	*req;
+ 
+ 	if (!(req = task->tk_rqstp))
+ 		return;
+-	spin_lock_bh(&xprt->sock_lock);
+-	__xprt_release_write(xprt, task);
+-	__xprt_put_cong(xprt, req);
++	spin_lock_bh(&xprt->transport_lock);
++	xprt->ops->release_xprt(xprt, task);
++	if (xprt->ops->release_request)
++		xprt->ops->release_request(task);
+ 	if (!list_empty(&req->rq_list))
+ 		list_del(&req->rq_list);
+ 	xprt->last_used = jiffies;
+ 	if (list_empty(&xprt->recv) && !xprt->shutdown)
+-		mod_timer(&xprt->timer, xprt->last_used + XPRT_IDLE_TIMEOUT);
+-	spin_unlock_bh(&xprt->sock_lock);
++		mod_timer(&xprt->timer,
++				xprt->last_used + xprt->idle_timeout);
++	spin_unlock_bh(&xprt->transport_lock);
+ 	task->tk_rqstp = NULL;
++	if (req->rq_release_snd_buf)
++		req->rq_release_snd_buf(req);
+ 	memset(req, 0, sizeof(*req));	/* mark unused */
+ 
+ 	dprintk("RPC: %4d release request %p\n", task->tk_pid, req);
+ 
+-	spin_lock(&xprt->xprt_lock);
++	spin_lock(&xprt->reserve_lock);
+ 	list_add(&req->rq_list, &xprt->free);
+-	xprt_clear_backlog(xprt);
+-	spin_unlock(&xprt->xprt_lock);
+-}
+-
+-/*
+- * Set default timeout parameters
+- */
+-static void
+-xprt_default_timeout(struct rpc_timeout *to, int proto)
+-{
+-	if (proto == IPPROTO_UDP)
+-		xprt_set_timeout(to, 5,  5 * HZ);
+-	else
+-		xprt_set_timeout(to, 5, 60 * HZ);
++	rpc_wake_up_next(&xprt->backlog);
++	spin_unlock(&xprt->reserve_lock);
+ }
+ 
+-/*
+- * Set constant timeout
++/**
++ * xprt_set_timeout - set constant RPC timeout
++ * @to: RPC timeout parameters to set up
++ * @retr: number of retries
++ * @incr: amount of increase after each retry
++ *
+  */
+-void
+-xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr)
++void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr)
+ {
+ 	to->to_initval   = 
+ 	to->to_increment = incr;
+-	to->to_maxval    = incr * retr;
++	to->to_maxval    = to->to_initval + (incr * retr);
+ 	to->to_retries   = retr;
+ 	to->to_exponential = 0;
+ }
+ 
+-unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE;
+-unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE;
+-
+-/*
+- * Initialize an RPC client
+- */
+-static struct rpc_xprt *
+-xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
++static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
+ {
++	int result;
+ 	struct rpc_xprt	*xprt;
+-	unsigned int entries;
+-	size_t slot_table_size;
+ 	struct rpc_rqst	*req;
+ 
+-	dprintk("RPC:      setting up %s transport...\n",
+-				proto == IPPROTO_UDP? "UDP" : "TCP");
+-
+-	entries = (proto == IPPROTO_TCP)?
+-		xprt_tcp_slot_table_entries : xprt_udp_slot_table_entries;
+-
+ 	if ((xprt = kmalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL)
+ 		return ERR_PTR(-ENOMEM);
+ 	memset(xprt, 0, sizeof(*xprt)); /* Nnnngh! */
+-	xprt->max_reqs = entries;
+-	slot_table_size = entries * sizeof(xprt->slot[0]);
+-	xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
+-	if (xprt->slot == NULL) {
+-		kfree(xprt);
+-		return ERR_PTR(-ENOMEM);
+-	}
+-	memset(xprt->slot, 0, slot_table_size);
+ 
+ 	xprt->addr = *ap;
+-	xprt->prot = proto;
+-	xprt->stream = (proto == IPPROTO_TCP)? 1 : 0;
+-	if (xprt->stream) {
+-		xprt->cwnd = RPC_MAXCWND(xprt);
+-		xprt->nocong = 1;
+-		xprt->max_payload = (1U << 31) - 1;
+-	} else {
+-		xprt->cwnd = RPC_INITCWND;
+-		xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
++
++	switch (proto) {
++	case IPPROTO_UDP:
++		result = xs_setup_udp(xprt, to);
++		break;
++	case IPPROTO_TCP:
++		result = xs_setup_tcp(xprt, to);
++		break;
++	default:
++		printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
++				proto);
++		result = -EIO;
++		break;
+ 	}
+-	spin_lock_init(&xprt->sock_lock);
+-	spin_lock_init(&xprt->xprt_lock);
+-	init_waitqueue_head(&xprt->cong_wait);
++	if (result) {
++		kfree(xprt);
++		return ERR_PTR(result);
++	}
++
++	spin_lock_init(&xprt->transport_lock);
++	spin_lock_init(&xprt->reserve_lock);
+ 
+ 	INIT_LIST_HEAD(&xprt->free);
+ 	INIT_LIST_HEAD(&xprt->recv);
+-	INIT_WORK(&xprt->sock_connect, xprt_socket_connect, xprt);
+-	INIT_WORK(&xprt->task_cleanup, xprt_socket_autoclose, xprt);
++	INIT_WORK(&xprt->task_cleanup, xprt_autoclose, xprt);
+ 	init_timer(&xprt->timer);
+ 	xprt->timer.function = xprt_init_autodisconnect;
+ 	xprt->timer.data = (unsigned long) xprt;
+ 	xprt->last_used = jiffies;
+-	xprt->port = XPRT_MAX_RESVPORT;
+-
+-	/* Set timeout parameters */
+-	if (to) {
+-		xprt->timeout = *to;
+-	} else
+-		xprt_default_timeout(&xprt->timeout, xprt->prot);
++	xprt->cwnd = RPC_INITCWND;
+ 
+ 	rpc_init_wait_queue(&xprt->pending, "xprt_pending");
+ 	rpc_init_wait_queue(&xprt->sending, "xprt_sending");
+@@ -1529,139 +944,25 @@ xprt_setup(int proto, struct sockaddr_in
+ 	rpc_init_priority_wait_queue(&xprt->backlog, "xprt_backlog");
+ 
+ 	/* initialize free list */
+-	for (req = &xprt->slot[entries-1]; req >= &xprt->slot[0]; req--)
++	for (req = &xprt->slot[xprt->max_reqs-1]; req >= &xprt->slot[0]; req--)
+ 		list_add(&req->rq_list, &xprt->free);
+ 
+ 	xprt_init_xid(xprt);
+ 
+-	/* Check whether we want to use a reserved port */
+-	xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
+-
+ 	dprintk("RPC:      created transport %p with %u slots\n", xprt,
+ 			xprt->max_reqs);
+ 	
+ 	return xprt;
+ }
+ 
+-/*
+- * Bind to a reserved port
+- */
+-static inline int xprt_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
+-{
+-	struct sockaddr_in myaddr = {
+-		.sin_family = AF_INET,
+-	};
+-	int		err, port;
+-
+-	/* Were we already bound to a given port? Try to reuse it */
+-	port = xprt->port;
+-	do {
+-		myaddr.sin_port = htons(port);
+-		err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
+-						sizeof(myaddr));
+-		if (err == 0) {
+-			xprt->port = port;
+-			return 0;
+-		}
+-		if (--port == 0)
+-			port = XPRT_MAX_RESVPORT;
+-	} while (err == -EADDRINUSE && port != xprt->port);
+-
+-	printk("RPC: Can't bind to reserved port (%d).\n", -err);
+-	return err;
+-}
+-
+-static void
+-xprt_bind_socket(struct rpc_xprt *xprt, struct socket *sock)
+-{
+-	struct sock	*sk = sock->sk;
+-
+-	if (xprt->inet)
+-		return;
+-
+-	write_lock_bh(&sk->sk_callback_lock);
+-	sk->sk_user_data = xprt;
+-	xprt->old_data_ready = sk->sk_data_ready;
+-	xprt->old_state_change = sk->sk_state_change;
+-	xprt->old_write_space = sk->sk_write_space;
+-	if (xprt->prot == IPPROTO_UDP) {
+-		sk->sk_data_ready = udp_data_ready;
+-		sk->sk_no_check = UDP_CSUM_NORCV;
+-		xprt_set_connected(xprt);
+-	} else {
+-		tcp_sk(sk)->nonagle = 1;	/* disable Nagle's algorithm */
+-		sk->sk_data_ready = tcp_data_ready;
+-		sk->sk_state_change = tcp_state_change;
+-		xprt_clear_connected(xprt);
+-	}
+-	sk->sk_write_space = xprt_write_space;
+-
+-	/* Reset to new socket */
+-	xprt->sock = sock;
+-	xprt->inet = sk;
+-	write_unlock_bh(&sk->sk_callback_lock);
+-
+-	return;
+-}
+-
+-/*
+- * Set socket buffer length
+- */
+-void
+-xprt_sock_setbufsize(struct rpc_xprt *xprt)
+-{
+-	struct sock *sk = xprt->inet;
+-
+-	if (xprt->stream)
+-		return;
+-	if (xprt->rcvsize) {
+-		sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
+-		sk->sk_rcvbuf = xprt->rcvsize * xprt->max_reqs *  2;
+-	}
+-	if (xprt->sndsize) {
+-		sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
+-		sk->sk_sndbuf = xprt->sndsize * xprt->max_reqs * 2;
+-		sk->sk_write_space(sk);
+-	}
+-}
+-
+-/*
+- * Datastream sockets are created here, but xprt_connect will create
+- * and connect stream sockets.
+- */
+-static struct socket * xprt_create_socket(struct rpc_xprt *xprt, int proto, int resvport)
+-{
+-	struct socket	*sock;
+-	int		type, err;
+-
+-	dprintk("RPC:      xprt_create_socket(%s %d)\n",
+-			   (proto == IPPROTO_UDP)? "udp" : "tcp", proto);
+-
+-	type = (proto == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
+-
+-	if ((err = sock_create_kern(PF_INET, type, proto, &sock)) < 0) {
+-		printk("RPC: can't create socket (%d).\n", -err);
+-		return NULL;
+-	}
+-
+-	/* If the caller has the capability, bind to a reserved port */
+-	if (resvport && xprt_bindresvport(xprt, sock) < 0) {
+-		printk("RPC: can't bind to reserved port.\n");
+-		goto failed;
+-	}
+-
+-	return sock;
+-
+-failed:
+-	sock_release(sock);
+-	return NULL;
+-}
+-
+-/*
+- * Create an RPC client transport given the protocol and peer address.
++/**
++ * xprt_create_proto - create an RPC client transport
++ * @proto: requested transport protocol
++ * @sap: remote peer's address
++ * @to: timeout parameters for new transport
++ *
+  */
+-struct rpc_xprt *
+-xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
++struct rpc_xprt *xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
+ {
+ 	struct rpc_xprt	*xprt;
+ 
+@@ -1673,46 +974,26 @@ xprt_create_proto(int proto, struct sock
+ 	return xprt;
+ }
+ 
+-/*
+- * Prepare for transport shutdown.
+- */
+-static void
+-xprt_shutdown(struct rpc_xprt *xprt)
++static void xprt_shutdown(struct rpc_xprt *xprt)
+ {
+ 	xprt->shutdown = 1;
+ 	rpc_wake_up(&xprt->sending);
+ 	rpc_wake_up(&xprt->resend);
+-	rpc_wake_up(&xprt->pending);
++	xprt_wake_pending_tasks(xprt, -EIO);
+ 	rpc_wake_up(&xprt->backlog);
+-	wake_up(&xprt->cong_wait);
+ 	del_timer_sync(&xprt->timer);
+-
+-	/* synchronously wait for connect worker to finish */
+-	cancel_delayed_work(&xprt->sock_connect);
+-	flush_scheduled_work();
+-}
+-
+-/*
+- * Clear the xprt backlog queue
+- */
+-static int
+-xprt_clear_backlog(struct rpc_xprt *xprt) {
+-	rpc_wake_up_next(&xprt->backlog);
+-	wake_up(&xprt->cong_wait);
+-	return 1;
+ }
+ 
+-/*
+- * Destroy an RPC transport, killing off all requests.
++/**
++ * xprt_destroy - destroy an RPC transport, killing off all requests.
++ * @xprt: transport to destroy
++ *
+  */
+-int
+-xprt_destroy(struct rpc_xprt *xprt)
++int xprt_destroy(struct rpc_xprt *xprt)
+ {
+ 	dprintk("RPC:      destroying transport %p\n", xprt);
+ 	xprt_shutdown(xprt);
+-	xprt_disconnect(xprt);
+-	xprt_close(xprt);
+-	kfree(xprt->slot);
++	xprt->ops->destroy(xprt);
+ 	kfree(xprt);
+ 
+ 	return 0;
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+new file mode 100644
+--- /dev/null
++++ b/net/sunrpc/xprtsock.c
+@@ -0,0 +1,1252 @@
++/*
++ * linux/net/sunrpc/xprtsock.c
++ *
++ * Client-side transport implementation for sockets.
++ *
++ * TCP callback races fixes (C) 1998 Red Hat Software <alan at redhat.com>
++ * TCP send fixes (C) 1998 Red Hat Software <alan at redhat.com>
++ * TCP NFS related read + write fixes
++ *  (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied at linux.ie>
++ *
++ * Rewrite of larges part of the code in order to stabilize TCP stuff.
++ * Fix behaviour when socket buffer is full.
++ *  (C) 1999 Trond Myklebust <trond.myklebust at fys.uio.no>
++ *
++ * IP socket transport implementation, (C) 2005 Chuck Lever <cel at netapp.com>
++ */
++
++#include <linux/types.h>
++#include <linux/slab.h>
++#include <linux/capability.h>
++#include <linux/sched.h>
++#include <linux/pagemap.h>
++#include <linux/errno.h>
++#include <linux/socket.h>
++#include <linux/in.h>
++#include <linux/net.h>
++#include <linux/mm.h>
++#include <linux/udp.h>
++#include <linux/tcp.h>
++#include <linux/sunrpc/clnt.h>
++#include <linux/file.h>
++
++#include <net/sock.h>
++#include <net/checksum.h>
++#include <net/udp.h>
++#include <net/tcp.h>
++
++/*
++ * How many times to try sending a request on a socket before waiting
++ * for the socket buffer to clear.
++ */
++#define XS_SENDMSG_RETRY	(10U)
++
++/*
++ * Time out for an RPC UDP socket connect.  UDP socket connects are
++ * synchronous, but we set a timeout anyway in case of resource
++ * exhaustion on the local host.
++ */
++#define XS_UDP_CONN_TO		(5U * HZ)
++
++/*
++ * Wait duration for an RPC TCP connection to be established.  Solaris
++ * NFS over TCP uses 60 seconds, for example, which is in line with how
++ * long a server takes to reboot.
++ */
++#define XS_TCP_CONN_TO		(60U * HZ)
++
++/*
++ * Wait duration for a reply from the RPC portmapper.
++ */
++#define XS_BIND_TO		(60U * HZ)
++
++/*
++ * Delay if a UDP socket connect error occurs.  This is most likely some
++ * kind of resource problem on the local host.
++ */
++#define XS_UDP_REEST_TO		(2U * HZ)
++
++/*
++ * The reestablish timeout allows clients to delay for a bit before attempting
++ * to reconnect to a server that just dropped our connection.
++ *
++ * We implement an exponential backoff when trying to reestablish a TCP
++ * transport connection with the server.  Some servers like to drop a TCP
++ * connection when they are overworked, so we start with a short timeout and
++ * increase over time if the server is down or not responding.
++ */
++#define XS_TCP_INIT_REEST_TO	(3U * HZ)
++#define XS_TCP_MAX_REEST_TO	(5U * 60 * HZ)
++
++/*
++ * TCP idle timeout; client drops the transport socket if it is idle
++ * for this long.  Note that we also timeout UDP sockets to prevent
++ * holding port numbers when there is no RPC traffic.
++ */
++#define XS_IDLE_DISC_TO		(5U * 60 * HZ)
++
++#ifdef RPC_DEBUG
++# undef  RPC_DEBUG_DATA
++# define RPCDBG_FACILITY	RPCDBG_TRANS
++#endif
++
++#ifdef RPC_DEBUG_DATA
++static void xs_pktdump(char *msg, u32 *packet, unsigned int count)
++{
++	u8 *buf = (u8 *) packet;
++	int j;
++
++	dprintk("RPC:      %s\n", msg);
++	for (j = 0; j < count && j < 128; j += 4) {
++		if (!(j & 31)) {
++			if (j)
++				dprintk("\n");
++			dprintk("0x%04x ", j);
++		}
++		dprintk("%02x%02x%02x%02x ",
++			buf[j], buf[j+1], buf[j+2], buf[j+3]);
++	}
++	dprintk("\n");
++}
++#else
++static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count)
++{
++	/* NOP */
++}
++#endif
++
++#define XS_SENDMSG_FLAGS	(MSG_DONTWAIT | MSG_NOSIGNAL)
++
++static inline int xs_send_head(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, unsigned int len)
++{
++	struct kvec iov = {
++		.iov_base	= xdr->head[0].iov_base + base,
++		.iov_len	= len - base,
++	};
++	struct msghdr msg = {
++		.msg_name	= addr,
++		.msg_namelen	= addrlen,
++		.msg_flags	= XS_SENDMSG_FLAGS,
++	};
++
++	if (xdr->len > len)
++		msg.msg_flags |= MSG_MORE;
++
++	if (likely(iov.iov_len))
++		return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
++	return kernel_sendmsg(sock, &msg, NULL, 0, 0);
++}
++
++static int xs_send_tail(struct socket *sock, struct xdr_buf *xdr, unsigned int base, unsigned int len)
++{
++	struct kvec iov = {
++		.iov_base	= xdr->tail[0].iov_base + base,
++		.iov_len	= len - base,
++	};
++	struct msghdr msg = {
++		.msg_flags	= XS_SENDMSG_FLAGS,
++	};
++
++	return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
++}
++
++/**
++ * xs_sendpages - write pages directly to a socket
++ * @sock: socket to send on
++ * @addr: UDP only -- address of destination
++ * @addrlen: UDP only -- length of destination address
++ * @xdr: buffer containing this request
++ * @base: starting position in the buffer
++ *
++ */
++static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base)
++{
++	struct page **ppage = xdr->pages;
++	unsigned int len, pglen = xdr->page_len;
++	int err, ret = 0;
++	ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
++
++	if (unlikely(!sock))
++		return -ENOTCONN;
++
++	clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
++
++	len = xdr->head[0].iov_len;
++	if (base < len || (addr != NULL && base == 0)) {
++		err = xs_send_head(sock, addr, addrlen, xdr, base, len);
++		if (ret == 0)
++			ret = err;
++		else if (err > 0)
++			ret += err;
++		if (err != (len - base))
++			goto out;
++		base = 0;
++	} else
++		base -= len;
++
++	if (unlikely(pglen == 0))
++		goto copy_tail;
++	if (unlikely(base >= pglen)) {
++		base -= pglen;
++		goto copy_tail;
++	}
++	if (base || xdr->page_base) {
++		pglen -= base;
++		base += xdr->page_base;
++		ppage += base >> PAGE_CACHE_SHIFT;
++		base &= ~PAGE_CACHE_MASK;
++	}
++
++	sendpage = sock->ops->sendpage ? : sock_no_sendpage;
++	do {
++		int flags = XS_SENDMSG_FLAGS;
++
++		len = PAGE_CACHE_SIZE;
++		if (base)
++			len -= base;
++		if (pglen < len)
++			len = pglen;
++
++		if (pglen != len || xdr->tail[0].iov_len != 0)
++			flags |= MSG_MORE;
++
++		/* Hmm... We might be dealing with highmem pages */
++		if (PageHighMem(*ppage))
++			sendpage = sock_no_sendpage;
++		err = sendpage(sock, *ppage, base, len, flags);
++		if (ret == 0)
++			ret = err;
++		else if (err > 0)
++			ret += err;
++		if (err != len)
++			goto out;
++		base = 0;
++		ppage++;
++	} while ((pglen -= len) != 0);
++copy_tail:
++	len = xdr->tail[0].iov_len;
++	if (base < len) {
++		err = xs_send_tail(sock, xdr, base, len);
++		if (ret == 0)
++			ret = err;
++		else if (err > 0)
++			ret += err;
++	}
++out:
++	return ret;
++}
++
++/**
++ * xs_nospace - place task on wait queue if transmit was incomplete
++ * @task: task to put to sleep
++ *
++ */
++static void xs_nospace(struct rpc_task *task)
++{
++	struct rpc_rqst *req = task->tk_rqstp;
++	struct rpc_xprt *xprt = req->rq_xprt;
++
++	dprintk("RPC: %4d xmit incomplete (%u left of %u)\n",
++			task->tk_pid, req->rq_slen - req->rq_bytes_sent,
++			req->rq_slen);
++
++	if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) {
++		/* Protect against races with write_space */
++		spin_lock_bh(&xprt->transport_lock);
++
++		/* Don't race with disconnect */
++		if (!xprt_connected(xprt))
++			task->tk_status = -ENOTCONN;
++		else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags))
++			xprt_wait_for_buffer_space(task);
++
++		spin_unlock_bh(&xprt->transport_lock);
++	} else
++		/* Keep holding the socket if it is blocked */
++		rpc_delay(task, HZ>>4);
++}
++
++/**
++ * xs_udp_send_request - write an RPC request to a UDP socket
++ * @task: address of RPC task that manages the state of an RPC request
++ *
++ * Return values:
++ *        0:	The request has been sent
++ *   EAGAIN:	The socket was blocked, please call again later to
++ *		complete the request
++ * ENOTCONN:	Caller needs to invoke connect logic then call again
++ *    other:	Some other error occured, the request was not sent
++ */
++static int xs_udp_send_request(struct rpc_task *task)
++{
++	struct rpc_rqst *req = task->tk_rqstp;
++	struct rpc_xprt *xprt = req->rq_xprt;
++	struct xdr_buf *xdr = &req->rq_snd_buf;
++	int status;
++
++	xs_pktdump("packet data:",
++				req->rq_svec->iov_base,
++				req->rq_svec->iov_len);
++
++	req->rq_xtime = jiffies;
++	status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr,
++				sizeof(xprt->addr), xdr, req->rq_bytes_sent);
++
++	dprintk("RPC:      xs_udp_send_request(%u) = %d\n",
++			xdr->len - req->rq_bytes_sent, status);
++
++	if (likely(status >= (int) req->rq_slen))
++		return 0;
++
++	/* Still some bytes left; set up for a retry later. */
++	if (status > 0)
++		status = -EAGAIN;
++
++	switch (status) {
++	case -ENETUNREACH:
++	case -EPIPE:
++	case -ECONNREFUSED:
++		/* When the server has died, an ICMP port unreachable message
++		 * prompts ECONNREFUSED. */
++		break;
++	case -EAGAIN:
++		xs_nospace(task);
++		break;
++	default:
++		dprintk("RPC:      sendmsg returned unrecognized error %d\n",
++			-status);
++		break;
++	}
++
++	return status;
++}
++
++static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf)
++{
++	u32 reclen = buf->len - sizeof(rpc_fraghdr);
++	rpc_fraghdr *base = buf->head[0].iov_base;
++	*base = htonl(RPC_LAST_STREAM_FRAGMENT | reclen);
++}
++
++/**
++ * xs_tcp_send_request - write an RPC request to a TCP socket
++ * @task: address of RPC task that manages the state of an RPC request
++ *
++ * Return values:
++ *        0:	The request has been sent
++ *   EAGAIN:	The socket was blocked, please call again later to
++ *		complete the request
++ * ENOTCONN:	Caller needs to invoke connect logic then call again
++ *    other:	Some other error occured, the request was not sent
++ *
++ * XXX: In the case of soft timeouts, should we eventually give up
++ *	if sendmsg is not able to make progress?
++ */
++static int xs_tcp_send_request(struct rpc_task *task)
++{
++	struct rpc_rqst *req = task->tk_rqstp;
++	struct rpc_xprt *xprt = req->rq_xprt;
++	struct xdr_buf *xdr = &req->rq_snd_buf;
++	int status, retry = 0;
++
++	xs_encode_tcp_record_marker(&req->rq_snd_buf);
++
++	xs_pktdump("packet data:",
++				req->rq_svec->iov_base,
++				req->rq_svec->iov_len);
++
++	/* Continue transmitting the packet/record. We must be careful
++	 * to cope with writespace callbacks arriving _after_ we have
++	 * called sendmsg(). */
++	while (1) {
++		req->rq_xtime = jiffies;
++		status = xs_sendpages(xprt->sock, NULL, 0, xdr,
++						req->rq_bytes_sent);
++
++		dprintk("RPC:      xs_tcp_send_request(%u) = %d\n",
++				xdr->len - req->rq_bytes_sent, status);
++
++		if (unlikely(status < 0))
++			break;
++
++		/* If we've sent the entire packet, immediately
++		 * reset the count of bytes sent. */
++		req->rq_bytes_sent += status;
++		if (likely(req->rq_bytes_sent >= req->rq_slen)) {
++			req->rq_bytes_sent = 0;
++			return 0;
++		}
++
++		status = -EAGAIN;
++		if (retry++ > XS_SENDMSG_RETRY)
++			break;
++	}
++
++	switch (status) {
++	case -EAGAIN:
++		xs_nospace(task);
++		break;
++	case -ECONNREFUSED:
++	case -ECONNRESET:
++	case -ENOTCONN:
++	case -EPIPE:
++		status = -ENOTCONN;
++		break;
++	default:
++		dprintk("RPC:      sendmsg returned unrecognized error %d\n",
++			-status);
++		xprt_disconnect(xprt);
++		break;
++	}
++
++	return status;
++}
++
++/**
++ * xs_close - close a socket
++ * @xprt: transport
++ *
++ * This is used when all requests are complete; ie, no DRC state remains
++ * on the server we want to save.
++ */
++static void xs_close(struct rpc_xprt *xprt)
++{
++	struct socket *sock = xprt->sock;
++	struct sock *sk = xprt->inet;
++
++	if (!sk)
++		return;
++
++	dprintk("RPC:      xs_close xprt %p\n", xprt);
++
++	write_lock_bh(&sk->sk_callback_lock);
++	xprt->inet = NULL;
++	xprt->sock = NULL;
++
++	sk->sk_user_data = NULL;
++	sk->sk_data_ready = xprt->old_data_ready;
++	sk->sk_state_change = xprt->old_state_change;
++	sk->sk_write_space = xprt->old_write_space;
++	write_unlock_bh(&sk->sk_callback_lock);
++
++	sk->sk_no_check = 0;
++
++	sock_release(sock);
++}
++
++/**
++ * xs_destroy - prepare to shutdown a transport
++ * @xprt: doomed transport
++ *
++ */
++static void xs_destroy(struct rpc_xprt *xprt)
++{
++	dprintk("RPC:      xs_destroy xprt %p\n", xprt);
++
++	cancel_delayed_work(&xprt->connect_worker);
++	flush_scheduled_work();
++
++	xprt_disconnect(xprt);
++	xs_close(xprt);
++	kfree(xprt->slot);
++}
++
++static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
++{
++	return (struct rpc_xprt *) sk->sk_user_data;
++}
++
++/**
++ * xs_udp_data_ready - "data ready" callback for UDP sockets
++ * @sk: socket with data to read
++ * @len: how much data to read
++ *
++ */
++static void xs_udp_data_ready(struct sock *sk, int len)
++{
++	struct rpc_task *task;
++	struct rpc_xprt *xprt;
++	struct rpc_rqst *rovr;
++	struct sk_buff *skb;
++	int err, repsize, copied;
++	u32 _xid, *xp;
++
++	read_lock(&sk->sk_callback_lock);
++	dprintk("RPC:      xs_udp_data_ready...\n");
++	if (!(xprt = xprt_from_sock(sk)))
++		goto out;
++
++	if ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL)
++		goto out;
++
++	if (xprt->shutdown)
++		goto dropit;
++
++	repsize = skb->len - sizeof(struct udphdr);
++	if (repsize < 4) {
++		dprintk("RPC:      impossible RPC reply size %d!\n", repsize);
++		goto dropit;
++	}
++
++	/* Copy the XID from the skb... */
++	xp = skb_header_pointer(skb, sizeof(struct udphdr),
++				sizeof(_xid), &_xid);
++	if (xp == NULL)
++		goto dropit;
++
++	/* Look up and lock the request corresponding to the given XID */
++	spin_lock(&xprt->transport_lock);
++	rovr = xprt_lookup_rqst(xprt, *xp);
++	if (!rovr)
++		goto out_unlock;
++	task = rovr->rq_task;
++
++	if ((copied = rovr->rq_private_buf.buflen) > repsize)
++		copied = repsize;
++
++	/* Suck it into the iovec, verify checksum if not done by hw. */
++	if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb))
++		goto out_unlock;
++
++	/* Something worked... */
++	dst_confirm(skb->dst);
++
++	xprt_adjust_cwnd(task, copied);
++	xprt_update_rtt(task);
++	xprt_complete_rqst(task, copied);
++
++ out_unlock:
++	spin_unlock(&xprt->transport_lock);
++ dropit:
++	skb_free_datagram(sk, skb);
++ out:
++	read_unlock(&sk->sk_callback_lock);
++}
++
++static inline size_t xs_tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
++{
++	if (len > desc->count)
++		len = desc->count;
++	if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
++		dprintk("RPC:      failed to copy %zu bytes from skb. %zu bytes remain\n",
++				len, desc->count);
++		return 0;
++	}
++	desc->offset += len;
++	desc->count -= len;
++	dprintk("RPC:      copied %zu bytes from skb. %zu bytes remain\n",
++			len, desc->count);
++	return len;
++}
++
++static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
++{
++	size_t len, used;
++	char *p;
++
++	p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
++	len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
++	used = xs_tcp_copy_data(desc, p, len);
++	xprt->tcp_offset += used;
++	if (used != len)
++		return;
++
++	xprt->tcp_reclen = ntohl(xprt->tcp_recm);
++	if (xprt->tcp_reclen & RPC_LAST_STREAM_FRAGMENT)
++		xprt->tcp_flags |= XPRT_LAST_FRAG;
++	else
++		xprt->tcp_flags &= ~XPRT_LAST_FRAG;
++	xprt->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK;
++
++	xprt->tcp_flags &= ~XPRT_COPY_RECM;
++	xprt->tcp_offset = 0;
++
++	/* Sanity check of the record length */
++	if (unlikely(xprt->tcp_reclen < 4)) {
++		dprintk("RPC:      invalid TCP record fragment length\n");
++		xprt_disconnect(xprt);
++		return;
++	}
++	dprintk("RPC:      reading TCP record fragment of length %d\n",
++			xprt->tcp_reclen);
++}
++
++static void xs_tcp_check_recm(struct rpc_xprt *xprt)
++{
++	dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
++			xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
++	if (xprt->tcp_offset == xprt->tcp_reclen) {
++		xprt->tcp_flags |= XPRT_COPY_RECM;
++		xprt->tcp_offset = 0;
++		if (xprt->tcp_flags & XPRT_LAST_FRAG) {
++			xprt->tcp_flags &= ~XPRT_COPY_DATA;
++			xprt->tcp_flags |= XPRT_COPY_XID;
++			xprt->tcp_copied = 0;
++		}
++	}
++}
++
++static inline void xs_tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
++{
++	size_t len, used;
++	char *p;
++
++	len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
++	dprintk("RPC:      reading XID (%Zu bytes)\n", len);
++	p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
++	used = xs_tcp_copy_data(desc, p, len);
++	xprt->tcp_offset += used;
++	if (used != len)
++		return;
++	xprt->tcp_flags &= ~XPRT_COPY_XID;
++	xprt->tcp_flags |= XPRT_COPY_DATA;
++	xprt->tcp_copied = 4;
++	dprintk("RPC:      reading reply for XID %08x\n",
++						ntohl(xprt->tcp_xid));
++	xs_tcp_check_recm(xprt);
++}
++
++static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
++{
++	struct rpc_rqst *req;
++	struct xdr_buf *rcvbuf;
++	size_t len;
++	ssize_t r;
++
++	/* Find and lock the request corresponding to this xid */
++	spin_lock(&xprt->transport_lock);
++	req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
++	if (!req) {
++		xprt->tcp_flags &= ~XPRT_COPY_DATA;
++		dprintk("RPC:      XID %08x request not found!\n",
++				ntohl(xprt->tcp_xid));
++		spin_unlock(&xprt->transport_lock);
++		return;
++	}
++
++	rcvbuf = &req->rq_private_buf;
++	len = desc->count;
++	if (len > xprt->tcp_reclen - xprt->tcp_offset) {
++		skb_reader_t my_desc;
++
++		len = xprt->tcp_reclen - xprt->tcp_offset;
++		memcpy(&my_desc, desc, sizeof(my_desc));
++		my_desc.count = len;
++		r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
++					  &my_desc, xs_tcp_copy_data);
++		desc->count -= r;
++		desc->offset += r;
++	} else
++		r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
++					  desc, xs_tcp_copy_data);
++
++	if (r > 0) {
++		xprt->tcp_copied += r;
++		xprt->tcp_offset += r;
++	}
++	if (r != len) {
++		/* Error when copying to the receive buffer,
++		 * usually because we weren't able to allocate
++		 * additional buffer pages. All we can do now
++		 * is turn off XPRT_COPY_DATA, so the request
++		 * will not receive any additional updates,
++		 * and time out.
++		 * Any remaining data from this record will
++		 * be discarded.
++		 */
++		xprt->tcp_flags &= ~XPRT_COPY_DATA;
++		dprintk("RPC:      XID %08x truncated request\n",
++				ntohl(xprt->tcp_xid));
++		dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
++				xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
++		goto out;
++	}
++
++	dprintk("RPC:      XID %08x read %Zd bytes\n",
++			ntohl(xprt->tcp_xid), r);
++	dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
++			xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
++
++	if (xprt->tcp_copied == req->rq_private_buf.buflen)
++		xprt->tcp_flags &= ~XPRT_COPY_DATA;
++	else if (xprt->tcp_offset == xprt->tcp_reclen) {
++		if (xprt->tcp_flags & XPRT_LAST_FRAG)
++			xprt->tcp_flags &= ~XPRT_COPY_DATA;
++	}
++
++out:
++	if (!(xprt->tcp_flags & XPRT_COPY_DATA))
++		xprt_complete_rqst(req->rq_task, xprt->tcp_copied);
++	spin_unlock(&xprt->transport_lock);
++	xs_tcp_check_recm(xprt);
++}
++
++static inline void xs_tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
++{
++	size_t len;
++
++	len = xprt->tcp_reclen - xprt->tcp_offset;
++	if (len > desc->count)
++		len = desc->count;
++	desc->count -= len;
++	desc->offset += len;
++	xprt->tcp_offset += len;
++	dprintk("RPC:      discarded %Zu bytes\n", len);
++	xs_tcp_check_recm(xprt);
++}
++
++static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len)
++{
++	struct rpc_xprt *xprt = rd_desc->arg.data;
++	skb_reader_t desc = {
++		.skb	= skb,
++		.offset	= offset,
++		.count	= len,
++		.csum	= 0
++	};
++
++	dprintk("RPC:      xs_tcp_data_recv started\n");
++	do {
++		/* Read in a new fragment marker if necessary */
++		/* Can we ever really expect to get completely empty fragments? */
++		if (xprt->tcp_flags & XPRT_COPY_RECM) {
++			xs_tcp_read_fraghdr(xprt, &desc);
++			continue;
++		}
++		/* Read in the xid if necessary */
++		if (xprt->tcp_flags & XPRT_COPY_XID) {
++			xs_tcp_read_xid(xprt, &desc);
++			continue;
++		}
++		/* Read in the request data */
++		if (xprt->tcp_flags & XPRT_COPY_DATA) {
++			xs_tcp_read_request(xprt, &desc);
++			continue;
++		}
++		/* Skip over any trailing bytes on short reads */
++		xs_tcp_read_discard(xprt, &desc);
++	} while (desc.count);
++	dprintk("RPC:      xs_tcp_data_recv done\n");
++	return len - desc.count;
++}
++
++/**
++ * xs_tcp_data_ready - "data ready" callback for TCP sockets
++ * @sk: socket with data to read
++ * @bytes: how much data to read
++ *
++ */
++static void xs_tcp_data_ready(struct sock *sk, int bytes)
++{
++	struct rpc_xprt *xprt;
++	read_descriptor_t rd_desc;
++
++	read_lock(&sk->sk_callback_lock);
++	dprintk("RPC:      xs_tcp_data_ready...\n");
++	if (!(xprt = xprt_from_sock(sk)))
++		goto out;
++	if (xprt->shutdown)
++		goto out;
++
++	/* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
++	rd_desc.arg.data = xprt;
++	rd_desc.count = 65536;
++	tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
++out:
++	read_unlock(&sk->sk_callback_lock);
++}
++
++/**
++ * xs_tcp_state_change - callback to handle TCP socket state changes
++ * @sk: socket whose state has changed
++ *
++ */
++static void xs_tcp_state_change(struct sock *sk)
++{
++	struct rpc_xprt *xprt;
++
++	read_lock(&sk->sk_callback_lock);
++	if (!(xprt = xprt_from_sock(sk)))
++		goto out;
++	dprintk("RPC:      xs_tcp_state_change client %p...\n", xprt);
++	dprintk("RPC:      state %x conn %d dead %d zapped %d\n",
++				sk->sk_state, xprt_connected(xprt),
++				sock_flag(sk, SOCK_DEAD),
++				sock_flag(sk, SOCK_ZAPPED));
++
++	switch (sk->sk_state) {
++	case TCP_ESTABLISHED:
++		spin_lock_bh(&xprt->transport_lock);
++		if (!xprt_test_and_set_connected(xprt)) {
++			/* Reset TCP record info */
++			xprt->tcp_offset = 0;
++			xprt->tcp_reclen = 0;
++			xprt->tcp_copied = 0;
++			xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
++			xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
++			xprt_wake_pending_tasks(xprt, 0);
++		}
++		spin_unlock_bh(&xprt->transport_lock);
++		break;
++	case TCP_SYN_SENT:
++	case TCP_SYN_RECV:
++		break;
++	default:
++		xprt_disconnect(xprt);
++		break;
++	}
++ out:
++	read_unlock(&sk->sk_callback_lock);
++}
++
++/**
++ * xs_udp_write_space - callback invoked when socket buffer space
++ *                             becomes available
++ * @sk: socket whose state has changed
++ *
++ * Called when more output buffer space is available for this socket.
++ * We try not to wake our writers until they can make "significant"
++ * progress, otherwise we'll waste resources thrashing kernel_sendmsg
++ * with a bunch of small requests.
++ */
++static void xs_udp_write_space(struct sock *sk)
++{
++	read_lock(&sk->sk_callback_lock);
++
++	/* from net/core/sock.c:sock_def_write_space */
++	if (sock_writeable(sk)) {
++		struct socket *sock;
++		struct rpc_xprt *xprt;
++
++		if (unlikely(!(sock = sk->sk_socket)))
++			goto out;
++		if (unlikely(!(xprt = xprt_from_sock(sk))))
++			goto out;
++		if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags)))
++			goto out;
++
++		xprt_write_space(xprt);
++	}
++
++ out:
++	read_unlock(&sk->sk_callback_lock);
++}
++
++/**
++ * xs_tcp_write_space - callback invoked when socket buffer space
++ *                             becomes available
++ * @sk: socket whose state has changed
++ *
++ * Called when more output buffer space is available for this socket.
++ * We try not to wake our writers until they can make "significant"
++ * progress, otherwise we'll waste resources thrashing kernel_sendmsg
++ * with a bunch of small requests.
++ */
++static void xs_tcp_write_space(struct sock *sk)
++{
++	read_lock(&sk->sk_callback_lock);
++
++	/* from net/core/stream.c:sk_stream_write_space */
++	if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
++		struct socket *sock;
++		struct rpc_xprt *xprt;
++
++		if (unlikely(!(sock = sk->sk_socket)))
++			goto out;
++		if (unlikely(!(xprt = xprt_from_sock(sk))))
++			goto out;
++		if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags)))
++			goto out;
++
++		xprt_write_space(xprt);
++	}
++
++ out:
++	read_unlock(&sk->sk_callback_lock);
++}
++
++static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
++{
++	struct sock *sk = xprt->inet;
++
++	if (xprt->rcvsize) {
++		sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
++		sk->sk_rcvbuf = xprt->rcvsize * xprt->max_reqs *  2;
++	}
++	if (xprt->sndsize) {
++		sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
++		sk->sk_sndbuf = xprt->sndsize * xprt->max_reqs * 2;
++		sk->sk_write_space(sk);
++	}
++}
++
++/**
++ * xs_udp_set_buffer_size - set send and receive limits
++ * @xprt: generic transport
++ * @sndsize: requested size of send buffer, in bytes
++ * @rcvsize: requested size of receive buffer, in bytes
++ *
++ * Set socket send and receive buffer size limits.
++ */
++static void xs_udp_set_buffer_size(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize)
++{
++	xprt->sndsize = 0;
++	if (sndsize)
++		xprt->sndsize = sndsize + 1024;
++	xprt->rcvsize = 0;
++	if (rcvsize)
++		xprt->rcvsize = rcvsize + 1024;
++
++	xs_udp_do_set_buffer_size(xprt);
++}
++
++/**
++ * xs_udp_timer - called when a retransmit timeout occurs on a UDP transport
++ * @task: task that timed out
++ *
++ * Adjust the congestion window after a retransmit timeout has occurred.
++ */
++static void xs_udp_timer(struct rpc_task *task)
++{
++	xprt_adjust_cwnd(task, -ETIMEDOUT);
++}
++
++static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
++{
++	struct sockaddr_in myaddr = {
++		.sin_family = AF_INET,
++	};
++	int err;
++	unsigned short port = xprt->port;
++
++	do {
++		myaddr.sin_port = htons(port);
++		err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
++						sizeof(myaddr));
++		if (err == 0) {
++			xprt->port = port;
++			dprintk("RPC:      xs_bindresvport bound to port %u\n",
++					port);
++			return 0;
++		}
++		if (port <= xprt_min_resvport)
++			port = xprt_max_resvport;
++		else
++			port--;
++	} while (err == -EADDRINUSE && port != xprt->port);
++
++	dprintk("RPC:      can't bind to reserved port (%d).\n", -err);
++	return err;
++}
++
++/**
++ * xs_udp_connect_worker - set up a UDP socket
++ * @args: RPC transport to connect
++ *
++ * Invoked by a work queue tasklet.
++ */
++static void xs_udp_connect_worker(void *args)
++{
++	struct rpc_xprt *xprt = (struct rpc_xprt *) args;
++	struct socket *sock = xprt->sock;
++	int err, status = -EIO;
++
++	if (xprt->shutdown || xprt->addr.sin_port == 0)
++		goto out;
++
++	dprintk("RPC:      xs_udp_connect_worker for xprt %p\n", xprt);
++
++	/* Start by resetting any existing state */
++	xs_close(xprt);
++
++	if ((err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
++		dprintk("RPC:      can't create UDP transport socket (%d).\n", -err);
++		goto out;
++	}
++
++	if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) {
++		sock_release(sock);
++		goto out;
++	}
++
++	if (!xprt->inet) {
++		struct sock *sk = sock->sk;
++
++		write_lock_bh(&sk->sk_callback_lock);
++
++		sk->sk_user_data = xprt;
++		xprt->old_data_ready = sk->sk_data_ready;
++		xprt->old_state_change = sk->sk_state_change;
++		xprt->old_write_space = sk->sk_write_space;
++		sk->sk_data_ready = xs_udp_data_ready;
++		sk->sk_write_space = xs_udp_write_space;
++		sk->sk_no_check = UDP_CSUM_NORCV;
++
++		xprt_set_connected(xprt);
++
++		/* Reset to new socket */
++		xprt->sock = sock;
++		xprt->inet = sk;
++
++		write_unlock_bh(&sk->sk_callback_lock);
++	}
++	xs_udp_do_set_buffer_size(xprt);
++	status = 0;
++out:
++	xprt_wake_pending_tasks(xprt, status);
++	xprt_clear_connecting(xprt);
++}
++
++/*
++ * We need to preserve the port number so the reply cache on the server can
++ * find our cached RPC replies when we get around to reconnecting.
++ */
++static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
++{
++	int result;
++	struct socket *sock = xprt->sock;
++	struct sockaddr any;
++
++	dprintk("RPC:      disconnecting xprt %p to reuse port\n", xprt);
++
++	/*
++	 * Disconnect the transport socket by doing a connect operation
++	 * with AF_UNSPEC.  This should return immediately...
++	 */
++	memset(&any, 0, sizeof(any));
++	any.sa_family = AF_UNSPEC;
++	result = sock->ops->connect(sock, &any, sizeof(any), 0);
++	if (result)
++		dprintk("RPC:      AF_UNSPEC connect return code %d\n",
++				result);
++}
++
++/**
++ * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
++ * @args: RPC transport to connect
++ *
++ * Invoked by a work queue tasklet.
++ */
++static void xs_tcp_connect_worker(void *args)
++{
++	struct rpc_xprt *xprt = (struct rpc_xprt *)args;
++	struct socket *sock = xprt->sock;
++	int err, status = -EIO;
++
++	if (xprt->shutdown || xprt->addr.sin_port == 0)
++		goto out;
++
++	dprintk("RPC:      xs_tcp_connect_worker for xprt %p\n", xprt);
++
++	if (!xprt->sock) {
++		/* start from scratch */
++		if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
++			dprintk("RPC:      can't create TCP transport socket (%d).\n", -err);
++			goto out;
++		}
++
++		if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) {
++			sock_release(sock);
++			goto out;
++		}
++	} else
++		/* "close" the socket, preserving the local port */
++		xs_tcp_reuse_connection(xprt);
++
++	if (!xprt->inet) {
++		struct sock *sk = sock->sk;
++
++		write_lock_bh(&sk->sk_callback_lock);
++
++		sk->sk_user_data = xprt;
++		xprt->old_data_ready = sk->sk_data_ready;
++		xprt->old_state_change = sk->sk_state_change;
++		xprt->old_write_space = sk->sk_write_space;
++		sk->sk_data_ready = xs_tcp_data_ready;
++		sk->sk_state_change = xs_tcp_state_change;
++		sk->sk_write_space = xs_tcp_write_space;
++
++		/* socket options */
++		sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
++		sock_reset_flag(sk, SOCK_LINGER);
++		tcp_sk(sk)->linger2 = 0;
++		tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
++
++		xprt_clear_connected(xprt);
++
++		/* Reset to new socket */
++		xprt->sock = sock;
++		xprt->inet = sk;
++
++		write_unlock_bh(&sk->sk_callback_lock);
++	}
++
++	/* Tell the socket layer to start connecting... */
++	status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
++			sizeof(xprt->addr), O_NONBLOCK);
++	dprintk("RPC: %p  connect status %d connected %d sock state %d\n",
++			xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
++	if (status < 0) {
++		switch (status) {
++			case -EINPROGRESS:
++			case -EALREADY:
++				goto out_clear;
++			case -ECONNREFUSED:
++			case -ECONNRESET:
++				/* retry with existing socket, after a delay */
++				break;
++			default:
++				/* get rid of existing socket, and retry */
++				xs_close(xprt);
++				break;
++		}
++	}
++out:
++	xprt_wake_pending_tasks(xprt, status);
++out_clear:
++	xprt_clear_connecting(xprt);
++}
++
++/**
++ * xs_connect - connect a socket to a remote endpoint
++ * @task: address of RPC task that manages state of connect request
++ *
++ * TCP: If the remote end dropped the connection, delay reconnecting.
++ *
++ * UDP socket connects are synchronous, but we use a work queue anyway
++ * to guarantee that even unprivileged user processes can set up a
++ * socket on a privileged port.
++ *
++ * If a UDP socket connect fails, the delay behavior here prevents
++ * retry floods (hard mounts).
++ */
++static void xs_connect(struct rpc_task *task)
++{
++	struct rpc_xprt *xprt = task->tk_xprt;
++
++	if (xprt_test_and_set_connecting(xprt))
++		return;
++
++	if (xprt->sock != NULL) {
++		dprintk("RPC:      xs_connect delayed xprt %p for %lu seconds\n",
++				xprt, xprt->reestablish_timeout / HZ);
++		schedule_delayed_work(&xprt->connect_worker,
++					xprt->reestablish_timeout);
++		xprt->reestablish_timeout <<= 1;
++		if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
++			xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
++	} else {
++		dprintk("RPC:      xs_connect scheduled xprt %p\n", xprt);
++		schedule_work(&xprt->connect_worker);
++
++		/* flush_scheduled_work can sleep... */
++		if (!RPC_IS_ASYNC(task))
++			flush_scheduled_work();
++	}
++}
++
++static struct rpc_xprt_ops xs_udp_ops = {
++	.set_buffer_size	= xs_udp_set_buffer_size,
++	.reserve_xprt		= xprt_reserve_xprt_cong,
++	.release_xprt		= xprt_release_xprt_cong,
++	.connect		= xs_connect,
++	.send_request		= xs_udp_send_request,
++	.set_retrans_timeout	= xprt_set_retrans_timeout_rtt,
++	.timer			= xs_udp_timer,
++	.release_request	= xprt_release_rqst_cong,
++	.close			= xs_close,
++	.destroy		= xs_destroy,
++};
++
++static struct rpc_xprt_ops xs_tcp_ops = {
++	.reserve_xprt		= xprt_reserve_xprt,
++	.release_xprt		= xprt_release_xprt,
++	.connect		= xs_connect,
++	.send_request		= xs_tcp_send_request,
++	.set_retrans_timeout	= xprt_set_retrans_timeout_def,
++	.close			= xs_close,
++	.destroy		= xs_destroy,
++};
++
++/**
++ * xs_setup_udp - Set up transport to use a UDP socket
++ * @xprt: transport to set up
++ * @to:   timeout parameters
++ *
++ */
++int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
++{
++	size_t slot_table_size;
++
++	dprintk("RPC:      setting up udp-ipv4 transport...\n");
++
++	xprt->max_reqs = xprt_udp_slot_table_entries;
++	slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
++	xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
++	if (xprt->slot == NULL)
++		return -ENOMEM;
++	memset(xprt->slot, 0, slot_table_size);
++
++	xprt->prot = IPPROTO_UDP;
++	xprt->port = xprt_max_resvport;
++	xprt->tsh_size = 0;
++	xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
++	/* XXX: header size can vary due to auth type, IPv6, etc. */
++	xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
++
++	INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt);
++	xprt->bind_timeout = XS_BIND_TO;
++	xprt->connect_timeout = XS_UDP_CONN_TO;
++	xprt->reestablish_timeout = XS_UDP_REEST_TO;
++	xprt->idle_timeout = XS_IDLE_DISC_TO;
++
++	xprt->ops = &xs_udp_ops;
++
++	if (to)
++		xprt->timeout = *to;
++	else
++		xprt_set_timeout(&xprt->timeout, 5, 5 * HZ);
++
++	return 0;
++}
++
++/**
++ * xs_setup_tcp - Set up transport to use a TCP socket
++ * @xprt: transport to set up
++ * @to: timeout parameters
++ *
++ */
++int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
++{
++	size_t slot_table_size;
++
++	dprintk("RPC:      setting up tcp-ipv4 transport...\n");
++
++	xprt->max_reqs = xprt_tcp_slot_table_entries;
++	slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
++	xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
++	if (xprt->slot == NULL)
++		return -ENOMEM;
++	memset(xprt->slot, 0, slot_table_size);
++
++	xprt->prot = IPPROTO_TCP;
++	xprt->port = xprt_max_resvport;
++	xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
++	xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
++	xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
++
++	INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt);
++	xprt->bind_timeout = XS_BIND_TO;
++	xprt->connect_timeout = XS_TCP_CONN_TO;
++	xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
++	xprt->idle_timeout = XS_IDLE_DISC_TO;
++
++	xprt->ops = &xs_tcp_ops;
++
++	if (to)
++		xprt->timeout = *to;
++	else
++		xprt_set_timeout(&xprt->timeout, 2, 60 * HZ);
++
++	return 0;
++}
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1192,46 +1192,6 @@ int xfrm_bundle_ok(struct xfrm_dst *firs
+ 
+ EXPORT_SYMBOL(xfrm_bundle_ok);
+ 
+-/* Well... that's _TASK_. We need to scan through transformation
+- * list and figure out what mss tcp should generate in order to
+- * final datagram fit to mtu. Mama mia... :-)
+- *
+- * Apparently, some easy way exists, but we used to choose the most
+- * bizarre ones. :-) So, raising Kalashnikov... tra-ta-ta.
+- *
+- * Consider this function as something like dark humour. :-)
+- */
+-static int xfrm_get_mss(struct dst_entry *dst, u32 mtu)
+-{
+-	int res = mtu - dst->header_len;
+-
+-	for (;;) {
+-		struct dst_entry *d = dst;
+-		int m = res;
+-
+-		do {
+-			struct xfrm_state *x = d->xfrm;
+-			if (x) {
+-				spin_lock_bh(&x->lock);
+-				if (x->km.state == XFRM_STATE_VALID &&
+-				    x->type && x->type->get_max_size)
+-					m = x->type->get_max_size(d->xfrm, m);
+-				else
+-					m += x->props.header_len;
+-				spin_unlock_bh(&x->lock);
+-			}
+-		} while ((d = d->child) != NULL);
+-
+-		if (m <= mtu)
+-			break;
+-		res -= (m - mtu);
+-		if (res < 88)
+-			return mtu;
+-	}
+-
+-	return res + dst->header_len;
+-}
+-
+ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
+ {
+ 	int err = 0;
+@@ -1252,8 +1212,6 @@ int xfrm_policy_register_afinfo(struct x
+ 			dst_ops->negative_advice = xfrm_negative_advice;
+ 		if (likely(dst_ops->link_failure == NULL))
+ 			dst_ops->link_failure = xfrm_link_failure;
+-		if (likely(dst_ops->get_mss == NULL))
+-			dst_ops->get_mss = xfrm_get_mss;
+ 		if (likely(afinfo->garbage_collect == NULL))
+ 			afinfo->garbage_collect = __xfrm_garbage_collect;
+ 		xfrm_policy_afinfo[afinfo->family] = afinfo;
+@@ -1281,7 +1239,6 @@ int xfrm_policy_unregister_afinfo(struct
+ 			dst_ops->check = NULL;
+ 			dst_ops->negative_advice = NULL;
+ 			dst_ops->link_failure = NULL;
+-			dst_ops->get_mss = NULL;
+ 			afinfo->garbage_collect = NULL;
+ 		}
+ 	}
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -1026,6 +1026,12 @@ void xfrm_state_delete_tunnel(struct xfr
+ }
+ EXPORT_SYMBOL(xfrm_state_delete_tunnel);
+ 
++/*
++ * This function is NOT optimal.  For example, with ESP it will give an
++ * MTU that's usually two bytes short of being optimal.  However, it will
++ * usually give an answer that's a multiple of 4 provided the input is
++ * also a multiple of 4.
++ */
+ int xfrm_state_mtu(struct xfrm_state *x, int mtu)
+ {
+ 	int res = mtu;
+diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
+--- a/scripts/kconfig/Makefile
++++ b/scripts/kconfig/Makefile
+@@ -116,6 +116,15 @@ endif
+ clean-files	:= lkc_defs.h qconf.moc .tmp_qtcheck \
+ 		   .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c
+ 
++# Needed for systems without gettext
++KBUILD_HAVE_NLS := $(shell \
++     if echo "\#include <libint.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
++     then echo yes ; \
++     else echo no ; fi)
++ifeq ($(KBUILD_HAVE_NLS),no)
++HOSTCFLAGS	+= -DKBUILD_NO_NLS
++endif
++
+ # generated files seem to need this to find local include files
+ HOSTCFLAGS_lex.zconf.o	:= -I$(src)
+ HOSTCFLAGS_zconf.tab.o	:= -I$(src)
+diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
+--- a/scripts/kconfig/lkc.h
++++ b/scripts/kconfig/lkc.h
+@@ -8,7 +8,13 @@
+ 
+ #include "expr.h"
+ 
+-#include <libintl.h>
++#ifndef KBUILD_NO_NLS
++# include <libintl.h>
++#else
++# define gettext(Msgid) ((const char *) (Msgid))
++# define textdomain(Domainname) ((const char *) (Domainname))
++# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
++#endif
+ 
+ #ifdef __cplusplus
+ extern "C" {
+diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
+--- a/scripts/kconfig/mconf.c
++++ b/scripts/kconfig/mconf.c
+@@ -219,6 +219,7 @@ save_config_help[] = N_(
+ search_help[] = N_(
+ 	"\n"
+ 	"Search for CONFIG_ symbols and display their relations.\n"
++	"Regular expressions are allowed.\n"
+ 	"Example: search for \"^FOO\"\n"
+ 	"Result:\n"
+ 	"-----------------------------------------------------------------\n"
+@@ -531,7 +532,7 @@ again:
+ 	cprint("--title");
+ 	cprint(_("Search Configuration Parameter"));
+ 	cprint("--inputbox");
+-	cprint(_("Enter Keyword"));
++	cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"));
+ 	cprint("10");
+ 	cprint("75");
+ 	cprint("");
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -359,6 +359,13 @@ static int do_vio_entry(const char *file
+ 	return 1;
+ }
+ 
++static int do_i2c_entry(const char *filename, struct i2c_device_id *i2c, char *alias)
++{
++	strcpy(alias, "i2c:");
++	ADD(alias, "id", 1, i2c->id);
++	return 1;
++}
++
+ /* Ignore any prefix, eg. v850 prepends _ */
+ static inline int sym_is(const char *symbol, const char *name)
+ {
+@@ -443,6 +450,9 @@ void handle_moddevtable(struct module *m
+         else if (sym_is(symname, "__mod_vio_device_table"))
+ 		do_table(symval, sym->st_size, sizeof(struct vio_device_id),
+ 			 do_vio_entry, mod);
++	else if (sym_is(symname, "__mod_i2c_device_table"))
++		do_table(symval, sym->st_size, sizeof(struct i2c_device_id),
++			 do_i2c_entry, mod);
+ 
+ }
+ 
+diff --git a/security/dummy.c b/security/dummy.c
+--- a/security/dummy.c
++++ b/security/dummy.c
+@@ -377,7 +377,7 @@ static int dummy_inode_removexattr (stru
+ 	return 0;
+ }
+ 
+-static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
++static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
+ {
+ 	return -EOPNOTSUPP;
+ }
+@@ -768,7 +768,7 @@ static int dummy_socket_getpeersec(struc
+ 	return -ENOPROTOOPT;
+ }
+ 
+-static inline int dummy_sk_alloc_security (struct sock *sk, int family, int priority)
++static inline int dummy_sk_alloc_security (struct sock *sk, int family, gfp_t priority)
+ {
+ 	return 0;
+ }
+@@ -803,6 +803,23 @@ static int dummy_setprocattr(struct task
+ 	return -EINVAL;
+ }
+ 
++#ifdef CONFIG_KEYS
++static inline int dummy_key_alloc(struct key *key)
++{
++	return 0;
++}
++
++static inline void dummy_key_free(struct key *key)
++{
++}
++
++static inline int dummy_key_permission(key_ref_t key_ref,
++				       struct task_struct *context,
++				       key_perm_t perm)
++{
++	return 0;
++}
++#endif /* CONFIG_KEYS */
+ 
+ struct security_operations dummy_security_ops;
+ 
+@@ -954,5 +971,11 @@ void security_fixup_ops (struct security
+ 	set_to_dummy_if_null(ops, sk_alloc_security);
+ 	set_to_dummy_if_null(ops, sk_free_security);
+ #endif	/* CONFIG_SECURITY_NETWORK */
++#ifdef CONFIG_KEYS
++	set_to_dummy_if_null(ops, key_alloc);
++	set_to_dummy_if_null(ops, key_free);
++	set_to_dummy_if_null(ops, key_permission);
++#endif	/* CONFIG_KEYS */
++
+ }
+ 
+diff --git a/security/keys/key.c b/security/keys/key.c
+--- a/security/keys/key.c
++++ b/security/keys/key.c
+@@ -1,6 +1,6 @@
+ /* key.c: basic authentication token and access key management
+  *
+- * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
++ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+  * Written by David Howells (dhowells at redhat.com)
+  *
+  * This program is free software; you can redistribute it and/or
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/sched.h>
+ #include <linux/slab.h>
++#include <linux/security.h>
+ #include <linux/workqueue.h>
+ #include <linux/err.h>
+ #include "internal.h"
+@@ -253,6 +254,7 @@ struct key *key_alloc(struct key_type *t
+ 	struct key_user *user = NULL;
+ 	struct key *key;
+ 	size_t desclen, quotalen;
++	int ret;
+ 
+ 	key = ERR_PTR(-EINVAL);
+ 	if (!desc || !*desc)
+@@ -305,6 +307,7 @@ struct key *key_alloc(struct key_type *t
+ 	key->flags = 0;
+ 	key->expiry = 0;
+ 	key->payload.data = NULL;
++	key->security = NULL;
+ 
+ 	if (!not_in_quota)
+ 		key->flags |= 1 << KEY_FLAG_IN_QUOTA;
+@@ -315,16 +318,34 @@ struct key *key_alloc(struct key_type *t
+ 	key->magic = KEY_DEBUG_MAGIC;
+ #endif
+ 
++	/* let the security module know about the key */
++	ret = security_key_alloc(key);
++	if (ret < 0)
++		goto security_error;
++
+ 	/* publish the key by giving it a serial number */
+ 	atomic_inc(&user->nkeys);
+ 	key_alloc_serial(key);
+ 
+- error:
++error:
+ 	return key;
+ 
+- no_memory_3:
++security_error:
++	kfree(key->description);
++	kmem_cache_free(key_jar, key);
++	if (!not_in_quota) {
++		spin_lock(&user->lock);
++		user->qnkeys--;
++		user->qnbytes -= quotalen;
++		spin_unlock(&user->lock);
++	}
++	key_user_put(user);
++	key = ERR_PTR(ret);
++	goto error;
++
++no_memory_3:
+ 	kmem_cache_free(key_jar, key);
+- no_memory_2:
++no_memory_2:
+ 	if (!not_in_quota) {
+ 		spin_lock(&user->lock);
+ 		user->qnkeys--;
+@@ -332,11 +353,11 @@ struct key *key_alloc(struct key_type *t
+ 		spin_unlock(&user->lock);
+ 	}
+ 	key_user_put(user);
+- no_memory_1:
++no_memory_1:
+ 	key = ERR_PTR(-ENOMEM);
+ 	goto error;
+ 
+- no_quota:
++no_quota:
+ 	spin_unlock(&user->lock);
+ 	key_user_put(user);
+ 	key = ERR_PTR(-EDQUOT);
+@@ -556,6 +577,8 @@ static void key_cleanup(void *data)
+ 
+ 	key_check(key);
+ 
++	security_key_free(key);
++
+ 	/* deal with the user's key tracking and quota */
+ 	if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
+ 		spin_lock(&key->user->lock);
+@@ -700,8 +723,8 @@ static inline key_ref_t __key_update(key
+ 	int ret;
+ 
+ 	/* need write permission on the key to update it */
+-	ret = -EACCES;
+-	if (!key_permission(key_ref, KEY_WRITE))
++	ret = key_permission(key_ref, KEY_WRITE);
++	if (ret < 0)
+ 		goto error;
+ 
+ 	ret = -EEXIST;
+@@ -711,7 +734,6 @@ static inline key_ref_t __key_update(key
+ 	down_write(&key->sem);
+ 
+ 	ret = key->type->update(key, payload, plen);
+-
+ 	if (ret == 0)
+ 		/* updating a negative key instantiates it */
+ 		clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
+@@ -768,9 +790,11 @@ key_ref_t key_create_or_update(key_ref_t
+ 
+ 	/* if we're going to allocate a new key, we're going to have
+ 	 * to modify the keyring */
+-	key_ref = ERR_PTR(-EACCES);
+-	if (!key_permission(keyring_ref, KEY_WRITE))
++	ret = key_permission(keyring_ref, KEY_WRITE);
++	if (ret < 0) {
++		key_ref = ERR_PTR(ret);
+ 		goto error_3;
++	}
+ 
+ 	/* search for an existing key of the same type and description in the
+ 	 * destination keyring
+@@ -780,8 +804,8 @@ key_ref_t key_create_or_update(key_ref_t
+ 		goto found_matching_key;
+ 
+ 	/* decide on the permissions we want */
+-	perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK;
+-	perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
++	perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
++	perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;
+ 
+ 	if (ktype->read)
+ 		perm |= KEY_POS_READ | KEY_USR_READ;
+@@ -840,16 +864,16 @@ int key_update(key_ref_t key_ref, const 
+ 	key_check(key);
+ 
+ 	/* the key must be writable */
+-	ret = -EACCES;
+-	if (!key_permission(key_ref, KEY_WRITE))
++	ret = key_permission(key_ref, KEY_WRITE);
++	if (ret < 0)
+ 		goto error;
+ 
+ 	/* attempt to update it if supported */
+ 	ret = -EOPNOTSUPP;
+ 	if (key->type->update) {
+ 		down_write(&key->sem);
+-		ret = key->type->update(key, payload, plen);
+ 
++		ret = key->type->update(key, payload, plen);
+ 		if (ret == 0)
+ 			/* updating a negative key instantiates it */
+ 			clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
+diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -624,8 +624,8 @@ long keyctl_keyring_search(key_serial_t 
+ 
+ 	/* link the resulting key to the destination keyring if we can */
+ 	if (dest_ref) {
+-		ret = -EACCES;
+-		if (!key_permission(key_ref, KEY_LINK))
++		ret = key_permission(key_ref, KEY_LINK);
++		if (ret < 0)
+ 			goto error6;
+ 
+ 		ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref));
+@@ -676,8 +676,11 @@ long keyctl_read_key(key_serial_t keyid,
+ 	key = key_ref_to_ptr(key_ref);
+ 
+ 	/* see if we can read it directly */
+-	if (key_permission(key_ref, KEY_READ))
++	ret = key_permission(key_ref, KEY_READ);
++	if (ret == 0)
+ 		goto can_read_key;
++	if (ret != -EACCES)
++		goto error;
+ 
+ 	/* we can't; see if it's searchable from this process's keyrings
+ 	 * - we automatically take account of the fact that it may be
+@@ -726,7 +729,7 @@ long keyctl_chown_key(key_serial_t id, u
+ 	if (uid == (uid_t) -1 && gid == (gid_t) -1)
+ 		goto error;
+ 
+-	key_ref = lookup_user_key(NULL, id, 1, 1, 0);
++	key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
+ 	if (IS_ERR(key_ref)) {
+ 		ret = PTR_ERR(key_ref);
+ 		goto error;
+@@ -786,7 +789,7 @@ long keyctl_setperm_key(key_serial_t id,
+ 	if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
+ 		goto error;
+ 
+-	key_ref = lookup_user_key(NULL, id, 1, 1, 0);
++	key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
+ 	if (IS_ERR(key_ref)) {
+ 		ret = PTR_ERR(key_ref);
+ 		goto error;
+diff --git a/security/keys/keyring.c b/security/keys/keyring.c
+--- a/security/keys/keyring.c
++++ b/security/keys/keyring.c
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/sched.h>
+ #include <linux/slab.h>
++#include <linux/security.h>
+ #include <linux/seq_file.h>
+ #include <linux/err.h>
+ #include <asm/uaccess.h>
+@@ -309,7 +310,9 @@ struct key *keyring_alloc(const char *de
+ 	int ret;
+ 
+ 	keyring = key_alloc(&key_type_keyring, description,
+-			    uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota);
++			    uid, gid,
++			    (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
++			    not_in_quota);
+ 
+ 	if (!IS_ERR(keyring)) {
+ 		ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
+@@ -359,9 +362,11 @@ key_ref_t keyring_search_aux(key_ref_t k
+ 	key_check(keyring);
+ 
+ 	/* top keyring must have search permission to begin the search */
+-	key_ref = ERR_PTR(-EACCES);
+-	if (!key_task_permission(keyring_ref, context, KEY_SEARCH))
++        err = key_task_permission(keyring_ref, context, KEY_SEARCH);
++	if (err < 0) {
++		key_ref = ERR_PTR(err);
+ 		goto error;
++	}
+ 
+ 	key_ref = ERR_PTR(-ENOTDIR);
+ 	if (keyring->type != &key_type_keyring)
+@@ -402,8 +407,8 @@ descend:
+ 			continue;
+ 
+ 		/* key must have search permissions */
+-		if (!key_task_permission(make_key_ref(key, possessed),
+-					 context, KEY_SEARCH))
++		if (key_task_permission(make_key_ref(key, possessed),
++					context, KEY_SEARCH) < 0)
+ 			continue;
+ 
+ 		/* we set a different error code if we find a negative key */
+@@ -430,7 +435,7 @@ ascend:
+ 			continue;
+ 
+ 		if (!key_task_permission(make_key_ref(key, possessed),
+-					 context, KEY_SEARCH))
++					 context, KEY_SEARCH) < 0)
+ 			continue;
+ 
+ 		/* stack the current position */
+@@ -521,7 +526,7 @@ key_ref_t __keyring_search_one(key_ref_t
+ 			    (!key->type->match ||
+ 			     key->type->match(key, description)) &&
+ 			    key_permission(make_key_ref(key, possessed),
+-					   perm) &&
++					   perm) < 0 &&
+ 			    !test_bit(KEY_FLAG_REVOKED, &key->flags)
+ 			    )
+ 				goto found;
+@@ -617,7 +622,7 @@ struct key *find_keyring_by_name(const c
+ 				continue;
+ 
+ 			if (!key_permission(make_key_ref(keyring, 0),
+-					    KEY_SEARCH))
++					    KEY_SEARCH) < 0)
+ 				continue;
+ 
+ 			/* found a potential candidate, but we still need to
+diff --git a/security/keys/permission.c b/security/keys/permission.c
+--- a/security/keys/permission.c
++++ b/security/keys/permission.c
+@@ -10,6 +10,7 @@
+  */
+ 
+ #include <linux/module.h>
++#include <linux/security.h>
+ #include "internal.h"
+ 
+ /*****************************************************************************/
+@@ -63,7 +64,11 @@ use_these_perms:
+ 
+ 	kperm = kperm & perm & KEY_ALL;
+ 
+-	return kperm == perm;
++	if (kperm != perm)
++		return -EACCES;
++
++	/* let LSM be the final arbiter */
++	return security_key_permission(key_ref, context, perm);
+ 
+ } /* end key_task_permission() */
+ 
+diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
+--- a/security/keys/process_keys.c
++++ b/security/keys/process_keys.c
+@@ -39,7 +39,7 @@ struct key root_user_keyring = {
+ 	.type		= &key_type_keyring,
+ 	.user		= &root_key_user,
+ 	.sem		= __RWSEM_INITIALIZER(root_user_keyring.sem),
+-	.perm		= KEY_POS_ALL | KEY_USR_ALL,
++	.perm		= (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
+ 	.flags		= 1 << KEY_FLAG_INSTANTIATED,
+ 	.description	= "_uid.0",
+ #ifdef KEY_DEBUGGING
+@@ -54,7 +54,7 @@ struct key root_session_keyring = {
+ 	.type		= &key_type_keyring,
+ 	.user		= &root_key_user,
+ 	.sem		= __RWSEM_INITIALIZER(root_session_keyring.sem),
+-	.perm		= KEY_POS_ALL | KEY_USR_ALL,
++	.perm		= (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
+ 	.flags		= 1 << KEY_FLAG_INSTANTIATED,
+ 	.description	= "_uid_ses.0",
+ #ifdef KEY_DEBUGGING
+@@ -666,9 +666,8 @@ key_ref_t lookup_user_key(struct task_st
+ 		goto invalid_key;
+ 
+ 	/* check the permissions */
+-	ret = -EACCES;
+-
+-	if (!key_task_permission(key_ref, context, perm))
++	ret = key_task_permission(key_ref, context, perm);
++	if (ret < 0)
+ 		goto invalid_key;
+ 
+ error:
+diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
+--- a/security/keys/user_defined.c
++++ b/security/keys/user_defined.c
+@@ -15,18 +15,10 @@
+ #include <linux/slab.h>
+ #include <linux/seq_file.h>
+ #include <linux/err.h>
++#include <keys/user-type.h>
+ #include <asm/uaccess.h>
+ #include "internal.h"
+ 
+-static int user_instantiate(struct key *key, const void *data, size_t datalen);
+-static int user_duplicate(struct key *key, const struct key *source);
+-static int user_update(struct key *key, const void *data, size_t datalen);
+-static int user_match(const struct key *key, const void *criterion);
+-static void user_destroy(struct key *key);
+-static void user_describe(const struct key *user, struct seq_file *m);
+-static long user_read(const struct key *key,
+-		      char __user *buffer, size_t buflen);
+-
+ /*
+  * user defined keys take an arbitrary string as the description and an
+  * arbitrary blob of data as the payload
+@@ -42,19 +34,13 @@ struct key_type key_type_user = {
+ 	.read		= user_read,
+ };
+ 
+-struct user_key_payload {
+-	struct rcu_head	rcu;		/* RCU destructor */
+-	unsigned short	datalen;	/* length of this data */
+-	char		data[0];	/* actual data */
+-};
+-
+ EXPORT_SYMBOL_GPL(key_type_user);
+ 
+ /*****************************************************************************/
+ /*
+  * instantiate a user defined key
+  */
+-static int user_instantiate(struct key *key, const void *data, size_t datalen)
++int user_instantiate(struct key *key, const void *data, size_t datalen)
+ {
+ 	struct user_key_payload *upayload;
+ 	int ret;
+@@ -78,18 +64,20 @@ static int user_instantiate(struct key *
+ 	rcu_assign_pointer(key->payload.data, upayload);
+ 	ret = 0;
+ 
+- error:
++error:
+ 	return ret;
+ 
+ } /* end user_instantiate() */
+ 
++EXPORT_SYMBOL_GPL(user_instantiate);
++
+ /*****************************************************************************/
+ /*
+  * duplicate a user defined key
+  * - both keys' semaphores are locked against further modification
+  * - the new key cannot yet be accessed
+  */
+-static int user_duplicate(struct key *key, const struct key *source)
++int user_duplicate(struct key *key, const struct key *source)
+ {
+ 	struct user_key_payload *upayload, *spayload;
+ 	int ret;
+@@ -112,6 +100,8 @@ static int user_duplicate(struct key *ke
+ 
+ } /* end user_duplicate() */
+ 
++EXPORT_SYMBOL_GPL(user_duplicate);
++
+ /*****************************************************************************/
+ /*
+  * dispose of the old data from an updated user defined key
+@@ -131,7 +121,7 @@ static void user_update_rcu_disposal(str
+  * update a user defined key
+  * - the key's semaphore is write-locked
+  */
+-static int user_update(struct key *key, const void *data, size_t datalen)
++int user_update(struct key *key, const void *data, size_t datalen)
+ {
+ 	struct user_key_payload *upayload, *zap;
+ 	int ret;
+@@ -163,26 +153,30 @@ static int user_update(struct key *key, 
+ 
+ 	call_rcu(&zap->rcu, user_update_rcu_disposal);
+ 
+- error:
++error:
+ 	return ret;
+ 
+ } /* end user_update() */
+ 
++EXPORT_SYMBOL_GPL(user_update);
++
+ /*****************************************************************************/
+ /*
+  * match users on their name
+  */
+-static int user_match(const struct key *key, const void *description)
++int user_match(const struct key *key, const void *description)
+ {
+ 	return strcmp(key->description, description) == 0;
+ 
+ } /* end user_match() */
+ 
++EXPORT_SYMBOL_GPL(user_match);
++
+ /*****************************************************************************/
+ /*
+  * dispose of the data dangling from the corpse of a user
+  */
+-static void user_destroy(struct key *key)
++void user_destroy(struct key *key)
+ {
+ 	struct user_key_payload *upayload = key->payload.data;
+ 
+@@ -190,11 +184,13 @@ static void user_destroy(struct key *key
+ 
+ } /* end user_destroy() */
+ 
++EXPORT_SYMBOL_GPL(user_destroy);
++
+ /*****************************************************************************/
+ /*
+  * describe the user key
+  */
+-static void user_describe(const struct key *key, struct seq_file *m)
++void user_describe(const struct key *key, struct seq_file *m)
+ {
+ 	seq_puts(m, key->description);
+ 
+@@ -202,13 +198,14 @@ static void user_describe(const struct k
+ 
+ } /* end user_describe() */
+ 
++EXPORT_SYMBOL_GPL(user_describe);
++
+ /*****************************************************************************/
+ /*
+  * read the key data
+  * - the key's semaphore is read-locked
+  */
+-static long user_read(const struct key *key,
+-		      char __user *buffer, size_t buflen)
++long user_read(const struct key *key, char __user *buffer, size_t buflen)
+ {
+ 	struct user_key_payload *upayload;
+ 	long ret;
+@@ -228,3 +225,5 @@ static long user_read(const struct key *
+ 	return ret;
+ 
+ } /* end user_read() */
++
++EXPORT_SYMBOL_GPL(user_read);
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -122,11 +122,10 @@ static int task_alloc_security(struct ta
+ {
+ 	struct task_security_struct *tsec;
+ 
+-	tsec = kmalloc(sizeof(struct task_security_struct), GFP_KERNEL);
++	tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
+ 	if (!tsec)
+ 		return -ENOMEM;
+ 
+-	memset(tsec, 0, sizeof(struct task_security_struct));
+ 	tsec->magic = SELINUX_MAGIC;
+ 	tsec->task = task;
+ 	tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;
+@@ -151,11 +150,10 @@ static int inode_alloc_security(struct i
+ 	struct task_security_struct *tsec = current->security;
+ 	struct inode_security_struct *isec;
+ 
+-	isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
++	isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
+ 	if (!isec)
+ 		return -ENOMEM;
+ 
+-	memset(isec, 0, sizeof(struct inode_security_struct));
+ 	init_MUTEX(&isec->sem);
+ 	INIT_LIST_HEAD(&isec->list);
+ 	isec->magic = SELINUX_MAGIC;
+@@ -193,11 +191,10 @@ static int file_alloc_security(struct fi
+ 	struct task_security_struct *tsec = current->security;
+ 	struct file_security_struct *fsec;
+ 
+-	fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
++	fsec = kzalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
+ 	if (!fsec)
+ 		return -ENOMEM;
+ 
+-	memset(fsec, 0, sizeof(struct file_security_struct));
+ 	fsec->magic = SELINUX_MAGIC;
+ 	fsec->file = file;
+ 	if (tsec && tsec->magic == SELINUX_MAGIC) {
+@@ -227,11 +224,10 @@ static int superblock_alloc_security(str
+ {
+ 	struct superblock_security_struct *sbsec;
+ 
+-	sbsec = kmalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
++	sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
+ 	if (!sbsec)
+ 		return -ENOMEM;
+ 
+-	memset(sbsec, 0, sizeof(struct superblock_security_struct));
+ 	init_MUTEX(&sbsec->sem);
+ 	INIT_LIST_HEAD(&sbsec->list);
+ 	INIT_LIST_HEAD(&sbsec->isec_head);
+@@ -262,18 +258,17 @@ static void superblock_free_security(str
+ }
+ 
+ #ifdef CONFIG_SECURITY_NETWORK
+-static int sk_alloc_security(struct sock *sk, int family, int priority)
++static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
+ {
+ 	struct sk_security_struct *ssec;
+ 
+ 	if (family != PF_UNIX)
+ 		return 0;
+ 
+-	ssec = kmalloc(sizeof(*ssec), priority);
++	ssec = kzalloc(sizeof(*ssec), priority);
+ 	if (!ssec)
+ 		return -ENOMEM;
+ 
+-	memset(ssec, 0, sizeof(*ssec));
+ 	ssec->magic = SELINUX_MAGIC;
+ 	ssec->sk = sk;
+ 	ssec->peer_sid = SECINITSID_UNLABELED;
+@@ -1483,11 +1478,10 @@ static int selinux_bprm_alloc_security(s
+ {
+ 	struct bprm_security_struct *bsec;
+ 
+-	bsec = kmalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
++	bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
+ 	if (!bsec)
+ 		return -ENOMEM;
+ 
+-	memset(bsec, 0, sizeof *bsec);
+ 	bsec->magic = SELINUX_MAGIC;
+ 	bsec->bprm = bprm;
+ 	bsec->sid = SECINITSID_UNLABELED;
+@@ -1615,7 +1609,7 @@ static inline void flush_unauthorized_fi
+ 
+ 	if (tty) {
+ 		file_list_lock();
+-		file = list_entry(tty->tty_files.next, typeof(*file), f_list);
++		file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);
+ 		if (file) {
+ 			/* Revalidate access to controlling tty.
+ 			   Use inode_has_perm on the tty inode directly rather
+@@ -2211,12 +2205,6 @@ static void selinux_inode_post_setxattr(
+ 
+ static int selinux_inode_getxattr (struct dentry *dentry, char *name)
+ {
+-	struct inode *inode = dentry->d_inode;
+-	struct superblock_security_struct *sbsec = inode->i_sb->s_security;
+-
+-	if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
+-		return -EOPNOTSUPP;
+-
+ 	return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
+ }
+ 
+@@ -2247,33 +2235,54 @@ static int selinux_inode_removexattr (st
+ 	return -EACCES;
+ }
+ 
+-static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
++/*
++ * Copy the in-core inode security context value to the user.  If the
++ * getxattr() prior to this succeeded, check to see if we need to
++ * canonicalize the value to be finally returned to the user.
++ *
++ * Permission check is handled by selinux_inode_getxattr hook.
++ */
++static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
+ {
+ 	struct inode_security_struct *isec = inode->i_security;
+ 	char *context;
+ 	unsigned len;
+ 	int rc;
+ 
+-	/* Permission check handled by selinux_inode_getxattr hook.*/
+-
+-	if (strcmp(name, XATTR_SELINUX_SUFFIX))
+-		return -EOPNOTSUPP;
++	if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
++		rc = -EOPNOTSUPP;
++		goto out;
++	}
+ 
+ 	rc = security_sid_to_context(isec->sid, &context, &len);
+ 	if (rc)
+-		return rc;
++		goto out;
+ 
++	/* Probe for required buffer size */
+ 	if (!buffer || !size) {
+-		kfree(context);
+-		return len;
++		rc = len;
++		goto out_free;
+ 	}
++
+ 	if (size < len) {
+-		kfree(context);
+-		return -ERANGE;
++		rc = -ERANGE;
++		goto out_free;
++	}
++
++	if (err > 0) {
++		if ((len == err) && !(memcmp(context, buffer, len))) {
++			/* Don't need to canonicalize value */
++			rc = err;
++			goto out_free;
++		}
++		memset(buffer, 0, size);
+ 	}
+ 	memcpy(buffer, context, len);
++	rc = len;
++out_free:
+ 	kfree(context);
+-	return len;
++out:
++	return rc;
+ }
+ 
+ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
+@@ -2704,8 +2713,7 @@ static int selinux_task_kill(struct task
+ 	if (rc)
+ 		return rc;
+ 
+-	if (info && ((unsigned long)info == 1 ||
+-	             (unsigned long)info == 2 || SI_FROMKERNEL(info)))
++	if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
+ 		return 0;
+ 
+ 	if (!sig)
+@@ -3380,7 +3388,7 @@ out:	
+ 	return err;
+ }
+ 
+-static int selinux_sk_alloc_security(struct sock *sk, int family, int priority)
++static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
+ {
+ 	return sk_alloc_security(sk, family, priority);
+ }
+@@ -3599,11 +3607,10 @@ static int ipc_alloc_security(struct tas
+ 	struct task_security_struct *tsec = task->security;
+ 	struct ipc_security_struct *isec;
+ 
+-	isec = kmalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
++	isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
+ 	if (!isec)
+ 		return -ENOMEM;
+ 
+-	memset(isec, 0, sizeof(struct ipc_security_struct));
+ 	isec->magic = SELINUX_MAGIC;
+ 	isec->sclass = sclass;
+ 	isec->ipc_perm = perm;
+@@ -3631,11 +3638,10 @@ static int msg_msg_alloc_security(struct
+ {
+ 	struct msg_security_struct *msec;
+ 
+-	msec = kmalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
++	msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
+ 	if (!msec)
+ 		return -ENOMEM;
+ 
+-	memset(msec, 0, sizeof(struct msg_security_struct));
+ 	msec->magic = SELINUX_MAGIC;
+ 	msec->msg = msg;
+ 	msec->sid = SECINITSID_UNLABELED;
+diff --git a/security/selinux/netif.c b/security/selinux/netif.c
+--- a/security/selinux/netif.c
++++ b/security/selinux/netif.c
+@@ -114,13 +114,12 @@ static struct sel_netif *sel_netif_looku
+ 	if (likely(netif != NULL))
+ 		goto out;
+ 	
+-	new = kmalloc(sizeof(*new), GFP_ATOMIC);
++	new = kzalloc(sizeof(*new), GFP_ATOMIC);
+ 	if (!new) {
+ 		netif = ERR_PTR(-ENOMEM);
+ 		goto out;
+ 	}
+ 	
+-	memset(new, 0, sizeof(*new));
+ 	nsec = &new->nsec;
+ 
+ 	ret = security_netif_sid(dev->name, &nsec->if_sid, &nsec->msg_sid);
+diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
+--- a/security/selinux/selinuxfs.c
++++ b/security/selinux/selinuxfs.c
+@@ -105,7 +105,7 @@ static ssize_t sel_write_enforce(struct 
+ 	ssize_t length;
+ 	int new_value;
+ 
+-	if (count < 0 || count >= PAGE_SIZE)
++	if (count >= PAGE_SIZE)
+ 		return -ENOMEM;
+ 	if (*ppos != 0) {
+ 		/* No partial writes. */
+@@ -155,7 +155,7 @@ static ssize_t sel_write_disable(struct 
+ 	int new_value;
+ 	extern int selinux_disable(void);
+ 
+-	if (count < 0 || count >= PAGE_SIZE)
++	if (count >= PAGE_SIZE)
+ 		return -ENOMEM;
+ 	if (*ppos != 0) {
+ 		/* No partial writes. */
+@@ -242,7 +242,7 @@ static ssize_t sel_write_load(struct fil
+ 		goto out;
+ 	}
+ 
+-	if ((count < 0) || (count > 64 * 1024 * 1024)
++	if ((count > 64 * 1024 * 1024)
+ 	    || (data = vmalloc(count)) == NULL) {
+ 		length = -ENOMEM;
+ 		goto out;
+@@ -284,7 +284,7 @@ static ssize_t sel_write_context(struct 
+ 	if (length)
+ 		return length;
+ 
+-	if (count < 0 || count >= PAGE_SIZE)
++	if (count >= PAGE_SIZE)
+ 		return -ENOMEM;
+ 	if (*ppos != 0) {
+ 		/* No partial writes. */
+@@ -332,7 +332,7 @@ static ssize_t sel_write_checkreqprot(st
+ 	if (length)
+ 		return length;
+ 
+-	if (count < 0 || count >= PAGE_SIZE)
++	if (count >= PAGE_SIZE)
+ 		return -ENOMEM;
+ 	if (*ppos != 0) {
+ 		/* No partial writes. */
+@@ -424,15 +424,13 @@ static ssize_t sel_write_access(struct f
+ 		return length;
+ 
+ 	length = -ENOMEM;
+-	scon = kmalloc(size+1, GFP_KERNEL);
++	scon = kzalloc(size+1, GFP_KERNEL);
+ 	if (!scon)
+ 		return length;
+-	memset(scon, 0, size+1);
+ 
+-	tcon = kmalloc(size+1, GFP_KERNEL);
++	tcon = kzalloc(size+1, GFP_KERNEL);
+ 	if (!tcon)
+ 		goto out;
+-	memset(tcon, 0, size+1);
+ 
+ 	length = -EINVAL;
+ 	if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
+@@ -475,15 +473,13 @@ static ssize_t sel_write_create(struct f
+ 		return length;
+ 
+ 	length = -ENOMEM;
+-	scon = kmalloc(size+1, GFP_KERNEL);
++	scon = kzalloc(size+1, GFP_KERNEL);
+ 	if (!scon)
+ 		return length;
+-	memset(scon, 0, size+1);
+ 
+-	tcon = kmalloc(size+1, GFP_KERNEL);
++	tcon = kzalloc(size+1, GFP_KERNEL);
+ 	if (!tcon)
+ 		goto out;
+-	memset(tcon, 0, size+1);
+ 
+ 	length = -EINVAL;
+ 	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
+@@ -536,15 +532,13 @@ static ssize_t sel_write_relabel(struct 
+ 		return length;
+ 
+ 	length = -ENOMEM;
+-	scon = kmalloc(size+1, GFP_KERNEL);
++	scon = kzalloc(size+1, GFP_KERNEL);
+ 	if (!scon)
+ 		return length;
+-	memset(scon, 0, size+1);
+ 
+-	tcon = kmalloc(size+1, GFP_KERNEL);
++	tcon = kzalloc(size+1, GFP_KERNEL);
+ 	if (!tcon)
+ 		goto out;
+-	memset(tcon, 0, size+1);
+ 
+ 	length = -EINVAL;
+ 	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
+@@ -595,15 +589,13 @@ static ssize_t sel_write_user(struct fil
+ 		return length;
+ 
+ 	length = -ENOMEM;
+-	con = kmalloc(size+1, GFP_KERNEL);
++	con = kzalloc(size+1, GFP_KERNEL);
+ 	if (!con)
+ 		return length;
+-	memset(con, 0, size+1);
+ 
+-	user = kmalloc(size+1, GFP_KERNEL);
++	user = kzalloc(size+1, GFP_KERNEL);
+ 	if (!user)
+ 		goto out;
+-	memset(user, 0, size+1);
+ 
+ 	length = -EINVAL;
+ 	if (sscanf(buf, "%s %s", con, user) != 2)
+@@ -658,15 +650,13 @@ static ssize_t sel_write_member(struct f
+ 		return length;
+ 
+ 	length = -ENOMEM;
+-	scon = kmalloc(size+1, GFP_KERNEL);
++	scon = kzalloc(size+1, GFP_KERNEL);
+ 	if (!scon)
+ 		return length;
+-	memset(scon, 0, size+1);
+ 
+-	tcon = kmalloc(size+1, GFP_KERNEL);
++	tcon = kzalloc(size+1, GFP_KERNEL);
+ 	if (!tcon)
+ 		goto out;
+-	memset(tcon, 0, size+1);
+ 
+ 	length = -EINVAL;
+ 	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
+@@ -739,7 +729,7 @@ static ssize_t sel_read_bool(struct file
+ 	if (!filep->f_op)
+ 		goto out;
+ 
+-	if (count < 0 || count > PAGE_SIZE) {
++	if (count > PAGE_SIZE) {
+ 		ret = -EINVAL;
+ 		goto out;
+ 	}
+@@ -800,7 +790,7 @@ static ssize_t sel_write_bool(struct fil
+ 	if (!filep->f_op)
+ 		goto out;
+ 
+-	if (count < 0 || count >= PAGE_SIZE) {
++	if (count >= PAGE_SIZE) {
+ 		length = -ENOMEM;
+ 		goto out;
+ 	}
+@@ -858,7 +848,7 @@ static ssize_t sel_commit_bools_write(st
+ 	if (!filep->f_op)
+ 		goto out;
+ 
+-	if (count < 0 || count >= PAGE_SIZE) {
++	if (count >= PAGE_SIZE) {
+ 		length = -ENOMEM;
+ 		goto out;
+ 	}
+@@ -924,7 +914,7 @@ static void sel_remove_bools(struct dent
+ 
+ 	file_list_lock();
+ 	list_for_each(p, &sb->s_files) {
+-		struct file * filp = list_entry(p, struct file, f_list);
++		struct file * filp = list_entry(p, struct file, f_u.fu_list);
+ 		struct dentry * dentry = filp->f_dentry;
+ 
+ 		if (dentry->d_parent != de) {
+@@ -1032,7 +1022,7 @@ static ssize_t sel_write_avc_cache_thres
+ 	ssize_t ret;
+ 	int new_value;
+ 
+-	if (count < 0 || count >= PAGE_SIZE) {
++	if (count >= PAGE_SIZE) {
+ 		ret = -ENOMEM;
+ 		goto out;
+ 	}
+diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
+--- a/security/selinux/ss/conditional.c
++++ b/security/selinux/ss/conditional.c
+@@ -220,10 +220,9 @@ int cond_read_bool(struct policydb *p, s
+ 	u32 len;
+ 	int rc;
+ 
+-	booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
++	booldatum = kzalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
+ 	if (!booldatum)
+ 		return -1;
+-	memset(booldatum, 0, sizeof(struct cond_bool_datum));
+ 
+ 	rc = next_entry(buf, fp, sizeof buf);
+ 	if (rc < 0)
+@@ -321,10 +320,9 @@ static int cond_insertf(struct avtab *a,
+ 		goto err;
+ 	}
+ 
+-	list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
++	list = kzalloc(sizeof(struct cond_av_list), GFP_KERNEL);
+ 	if (!list)
+ 		goto err;
+-	memset(list, 0, sizeof(*list));
+ 
+ 	list->node = node_ptr;
+ 	if (!data->head)
+@@ -414,11 +412,10 @@ static int cond_read_node(struct policyd
+ 		if (rc < 0)
+ 			goto err;
+ 
+-		expr = kmalloc(sizeof(struct cond_expr), GFP_KERNEL);
++		expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL);
+ 		if (!expr) {
+ 			goto err;
+ 		}
+-		memset(expr, 0, sizeof(struct cond_expr));
+ 
+ 		expr->expr_type = le32_to_cpu(buf[0]);
+ 		expr->bool = le32_to_cpu(buf[1]);
+@@ -460,10 +457,9 @@ int cond_read_list(struct policydb *p, v
+ 	len = le32_to_cpu(buf[0]);
+ 
+ 	for (i = 0; i < len; i++) {
+-		node = kmalloc(sizeof(struct cond_node), GFP_KERNEL);
++		node = kzalloc(sizeof(struct cond_node), GFP_KERNEL);
+ 		if (!node)
+ 			goto err;
+-		memset(node, 0, sizeof(struct cond_node));
+ 
+ 		if (cond_read_node(p, node, fp) != 0)
+ 			goto err;
+diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
+--- a/security/selinux/ss/ebitmap.c
++++ b/security/selinux/ss/ebitmap.c
+@@ -39,12 +39,11 @@ int ebitmap_cpy(struct ebitmap *dst, str
+ 	n = src->node;
+ 	prev = NULL;
+ 	while (n) {
+-		new = kmalloc(sizeof(*new), GFP_ATOMIC);
++		new = kzalloc(sizeof(*new), GFP_ATOMIC);
+ 		if (!new) {
+ 			ebitmap_destroy(dst);
+ 			return -ENOMEM;
+ 		}
+-		memset(new, 0, sizeof(*new));
+ 		new->startbit = n->startbit;
+ 		new->map = n->map;
+ 		new->next = NULL;
+@@ -150,10 +149,9 @@ int ebitmap_set_bit(struct ebitmap *e, u
+ 	if (!value)
+ 		return 0;
+ 
+-	new = kmalloc(sizeof(*new), GFP_ATOMIC);
++	new = kzalloc(sizeof(*new), GFP_ATOMIC);
+ 	if (!new)
+ 		return -ENOMEM;
+-	memset(new, 0, sizeof(*new));
+ 
+ 	new->startbit = bit & ~(MAPSIZE - 1);
+ 	new->map = (MAPBIT << (bit - new->startbit));
+@@ -232,13 +230,12 @@ int ebitmap_read(struct ebitmap *e, void
+ 			printk(KERN_ERR "security: ebitmap: truncated map\n");
+ 			goto bad;
+ 		}
+-		n = kmalloc(sizeof(*n), GFP_KERNEL);
++		n = kzalloc(sizeof(*n), GFP_KERNEL);
+ 		if (!n) {
+ 			printk(KERN_ERR "security: ebitmap: out of memory\n");
+ 			rc = -ENOMEM;
+ 			goto bad;
+ 		}
+-		memset(n, 0, sizeof(*n));
+ 
+ 		n->startbit = le32_to_cpu(buf[0]);
+ 
+diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c
+--- a/security/selinux/ss/hashtab.c
++++ b/security/selinux/ss/hashtab.c
+@@ -15,11 +15,10 @@ struct hashtab *hashtab_create(u32 (*has
+ 	struct hashtab *p;
+ 	u32 i;
+ 
+-	p = kmalloc(sizeof(*p), GFP_KERNEL);
++	p = kzalloc(sizeof(*p), GFP_KERNEL);
+ 	if (p == NULL)
+ 		return p;
+ 
+-	memset(p, 0, sizeof(*p));
+ 	p->size = size;
+ 	p->nel = 0;
+ 	p->hash_value = hash_value;
+@@ -55,10 +54,9 @@ int hashtab_insert(struct hashtab *h, vo
+ 	if (cur && (h->keycmp(h, key, cur->key) == 0))
+ 		return -EEXIST;
+ 
+-	newnode = kmalloc(sizeof(*newnode), GFP_KERNEL);
++	newnode = kzalloc(sizeof(*newnode), GFP_KERNEL);
+ 	if (newnode == NULL)
+ 		return -ENOMEM;
+-	memset(newnode, 0, sizeof(*newnode));
+ 	newnode->key = key;
+ 	newnode->datum = datum;
+ 	if (prev) {
+diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
+--- a/security/selinux/ss/policydb.c
++++ b/security/selinux/ss/policydb.c
+@@ -121,12 +121,11 @@ static int roles_init(struct policydb *p
+ 	int rc;
+ 	struct role_datum *role;
+ 
+-	role = kmalloc(sizeof(*role), GFP_KERNEL);
++	role = kzalloc(sizeof(*role), GFP_KERNEL);
+ 	if (!role) {
+ 		rc = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset(role, 0, sizeof(*role));
+ 	role->value = ++p->p_roles.nprim;
+ 	if (role->value != OBJECT_R_VAL) {
+ 		rc = -EINVAL;
+@@ -851,12 +850,11 @@ static int perm_read(struct policydb *p,
+ 	__le32 buf[2];
+ 	u32 len;
+ 
+-	perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
++	perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
+ 	if (!perdatum) {
+ 		rc = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset(perdatum, 0, sizeof(*perdatum));
+ 
+ 	rc = next_entry(buf, fp, sizeof buf);
+ 	if (rc < 0)
+@@ -893,12 +891,11 @@ static int common_read(struct policydb *
+ 	u32 len, nel;
+ 	int i, rc;
+ 
+-	comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL);
++	comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
+ 	if (!comdatum) {
+ 		rc = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset(comdatum, 0, sizeof(*comdatum));
+ 
+ 	rc = next_entry(buf, fp, sizeof buf);
+ 	if (rc < 0)
+@@ -950,10 +947,9 @@ static int read_cons_helper(struct const
+ 
+ 	lc = NULL;
+ 	for (i = 0; i < ncons; i++) {
+-		c = kmalloc(sizeof(*c), GFP_KERNEL);
++		c = kzalloc(sizeof(*c), GFP_KERNEL);
+ 		if (!c)
+ 			return -ENOMEM;
+-		memset(c, 0, sizeof(*c));
+ 
+ 		if (lc) {
+ 			lc->next = c;
+@@ -969,10 +965,9 @@ static int read_cons_helper(struct const
+ 		le = NULL;
+ 		depth = -1;
+ 		for (j = 0; j < nexpr; j++) {
+-			e = kmalloc(sizeof(*e), GFP_KERNEL);
++			e = kzalloc(sizeof(*e), GFP_KERNEL);
+ 			if (!e)
+ 				return -ENOMEM;
+-			memset(e, 0, sizeof(*e));
+ 
+ 			if (le) {
+ 				le->next = e;
+@@ -1033,12 +1028,11 @@ static int class_read(struct policydb *p
+ 	u32 len, len2, ncons, nel;
+ 	int i, rc;
+ 
+-	cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL);
++	cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
+ 	if (!cladatum) {
+ 		rc = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset(cladatum, 0, sizeof(*cladatum));
+ 
+ 	rc = next_entry(buf, fp, sizeof(u32)*6);
+ 	if (rc < 0)
+@@ -1127,12 +1121,11 @@ static int role_read(struct policydb *p,
+ 	__le32 buf[2];
+ 	u32 len;
+ 
+-	role = kmalloc(sizeof(*role), GFP_KERNEL);
++	role = kzalloc(sizeof(*role), GFP_KERNEL);
+ 	if (!role) {
+ 		rc = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset(role, 0, sizeof(*role));
+ 
+ 	rc = next_entry(buf, fp, sizeof buf);
+ 	if (rc < 0)
+@@ -1188,12 +1181,11 @@ static int type_read(struct policydb *p,
+ 	__le32 buf[3];
+ 	u32 len;
+ 
+-	typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL);
++	typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL);
+ 	if (!typdatum) {
+ 		rc = -ENOMEM;
+ 		return rc;
+ 	}
+-	memset(typdatum, 0, sizeof(*typdatum));
+ 
+ 	rc = next_entry(buf, fp, sizeof buf);
+ 	if (rc < 0)
+@@ -1261,12 +1253,11 @@ static int user_read(struct policydb *p,
+ 	__le32 buf[2];
+ 	u32 len;
+ 
+-	usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
++	usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
+ 	if (!usrdatum) {
+ 		rc = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset(usrdatum, 0, sizeof(*usrdatum));
+ 
+ 	rc = next_entry(buf, fp, sizeof buf);
+ 	if (rc < 0)
+@@ -1316,12 +1307,11 @@ static int sens_read(struct policydb *p,
+ 	__le32 buf[2];
+ 	u32 len;
+ 
+-	levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
++	levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
+ 	if (!levdatum) {
+ 		rc = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset(levdatum, 0, sizeof(*levdatum));
+ 
+ 	rc = next_entry(buf, fp, sizeof buf);
+ 	if (rc < 0)
+@@ -1368,12 +1358,11 @@ static int cat_read(struct policydb *p, 
+ 	__le32 buf[3];
+ 	u32 len;
+ 
+-	catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
++	catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
+ 	if (!catdatum) {
+ 		rc = -ENOMEM;
+ 		goto out;
+ 	}
+-	memset(catdatum, 0, sizeof(*catdatum));
+ 
+ 	rc = next_entry(buf, fp, sizeof buf);
+ 	if (rc < 0)
+@@ -1567,12 +1556,11 @@ int policydb_read(struct policydb *p, vo
+ 	nel = le32_to_cpu(buf[0]);
+ 	ltr = NULL;
+ 	for (i = 0; i < nel; i++) {
+-		tr = kmalloc(sizeof(*tr), GFP_KERNEL);
++		tr = kzalloc(sizeof(*tr), GFP_KERNEL);
+ 		if (!tr) {
+ 			rc = -ENOMEM;
+ 			goto bad;
+ 		}
+-		memset(tr, 0, sizeof(*tr));
+ 		if (ltr) {
+ 			ltr->next = tr;
+ 		} else {
+@@ -1593,12 +1581,11 @@ int policydb_read(struct policydb *p, vo
+ 	nel = le32_to_cpu(buf[0]);
+ 	lra = NULL;
+ 	for (i = 0; i < nel; i++) {
+-		ra = kmalloc(sizeof(*ra), GFP_KERNEL);
++		ra = kzalloc(sizeof(*ra), GFP_KERNEL);
+ 		if (!ra) {
+ 			rc = -ENOMEM;
+ 			goto bad;
+ 		}
+-		memset(ra, 0, sizeof(*ra));
+ 		if (lra) {
+ 			lra->next = ra;
+ 		} else {
+@@ -1627,12 +1614,11 @@ int policydb_read(struct policydb *p, vo
+ 		nel = le32_to_cpu(buf[0]);
+ 		l = NULL;
+ 		for (j = 0; j < nel; j++) {
+-			c = kmalloc(sizeof(*c), GFP_KERNEL);
++			c = kzalloc(sizeof(*c), GFP_KERNEL);
+ 			if (!c) {
+ 				rc = -ENOMEM;
+ 				goto bad;
+ 			}
+-			memset(c, 0, sizeof(*c));
+ 			if (l) {
+ 				l->next = c;
+ 			} else {
+@@ -1743,12 +1729,11 @@ int policydb_read(struct policydb *p, vo
+ 		if (rc < 0)
+ 			goto bad;
+ 		len = le32_to_cpu(buf[0]);
+-		newgenfs = kmalloc(sizeof(*newgenfs), GFP_KERNEL);
++		newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL);
+ 		if (!newgenfs) {
+ 			rc = -ENOMEM;
+ 			goto bad;
+ 		}
+-		memset(newgenfs, 0, sizeof(*newgenfs));
+ 
+ 		newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL);
+ 		if (!newgenfs->fstype) {
+@@ -1790,12 +1775,11 @@ int policydb_read(struct policydb *p, vo
+ 				goto bad;
+ 			len = le32_to_cpu(buf[0]);
+ 
+-			newc = kmalloc(sizeof(*newc), GFP_KERNEL);
++			newc = kzalloc(sizeof(*newc), GFP_KERNEL);
+ 			if (!newc) {
+ 				rc = -ENOMEM;
+ 				goto bad;
+ 			}
+-			memset(newc, 0, sizeof(*newc));
+ 
+ 			newc->u.name = kmalloc(len + 1,GFP_KERNEL);
+ 			if (!newc->u.name) {
+@@ -1843,12 +1827,11 @@ int policydb_read(struct policydb *p, vo
+ 		nel = le32_to_cpu(buf[0]);
+ 		lrt = NULL;
+ 		for (i = 0; i < nel; i++) {
+-			rt = kmalloc(sizeof(*rt), GFP_KERNEL);
++			rt = kzalloc(sizeof(*rt), GFP_KERNEL);
+ 			if (!rt) {
+ 				rc = -ENOMEM;
+ 				goto bad;
+ 			}
+-			memset(rt, 0, sizeof(*rt));
+ 			if (lrt)
+ 				lrt->next = rt;
+ 			else
+diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -1531,12 +1531,11 @@ int security_get_user_sids(u32 fromsid,
+ 	}
+ 	usercon.user = user->value;
+ 
+-	mysids = kmalloc(maxnel*sizeof(*mysids), GFP_ATOMIC);
++	mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
+ 	if (!mysids) {
+ 		rc = -ENOMEM;
+ 		goto out_unlock;
+ 	}
+-	memset(mysids, 0, maxnel*sizeof(*mysids));
+ 
+ 	ebitmap_for_each_bit(&user->roles, rnode, i) {
+ 		if (!ebitmap_node_get_bit(rnode, i))
+@@ -1566,13 +1565,12 @@ int security_get_user_sids(u32 fromsid,
+ 				mysids[mynel++] = sid;
+ 			} else {
+ 				maxnel += SIDS_NEL;
+-				mysids2 = kmalloc(maxnel*sizeof(*mysids2), GFP_ATOMIC);
++				mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
+ 				if (!mysids2) {
+ 					rc = -ENOMEM;
+ 					kfree(mysids);
+ 					goto out_unlock;
+ 				}
+-				memset(mysids2, 0, maxnel*sizeof(*mysids2));
+ 				memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
+ 				kfree(mysids);
+ 				mysids = mysids2;
+@@ -1714,12 +1712,11 @@ int security_get_bools(int *len, char **
+ 		goto out;
+ 	}
+ 
+-	*names = (char**)kmalloc(sizeof(char*) * *len, GFP_ATOMIC);
++	*names = (char**)kcalloc(*len, sizeof(char*), GFP_ATOMIC);
+ 	if (!*names)
+ 		goto err;
+-	memset(*names, 0, sizeof(char*) * *len);
+ 
+-	*values = (int*)kmalloc(sizeof(int) * *len, GFP_ATOMIC);
++	*values = (int*)kcalloc(*len, sizeof(int), GFP_ATOMIC);
+ 	if (!*values)
+ 		goto err;
+ 
+diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
+--- a/sound/arm/aaci.c
++++ b/sound/arm/aaci.c
+@@ -20,6 +20,7 @@
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
++#include <asm/sizes.h>
+ #include <asm/hardware/amba.h>
+ 
+ #include <sound/driver.h>
+diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
+--- a/sound/arm/pxa2xx-ac97.c
++++ b/sound/arm/pxa2xx-ac97.c
+@@ -13,7 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ #include <linux/wait.h>
+ #include <linux/delay.h>
+@@ -275,23 +275,23 @@ static int pxa2xx_ac97_do_resume(snd_car
+ 	return 0;
+ }
+ 
+-static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state, u32 level)
++static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state)
+ {
+ 	snd_card_t *card = dev_get_drvdata(_dev);
+ 	int ret = 0;
+ 
+-	if (card && level == SUSPEND_DISABLE)
++	if (card)
+ 		ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND);
+ 
+ 	return ret;
+ }
+ 
+-static int pxa2xx_ac97_resume(struct device *_dev, u32 level)
++static int pxa2xx_ac97_resume(struct device *_dev)
+ {
+ 	snd_card_t *card = dev_get_drvdata(_dev);
+ 	int ret = 0;
+ 
+-	if (card && level == RESUME_ENABLE)
++	if (card)
+ 		ret = pxa2xx_ac97_do_resume(card);
+ 
+ 	return ret;
+diff --git a/sound/core/init.c b/sound/core/init.c
+--- a/sound/core/init.c
++++ b/sound/core/init.c
+@@ -28,6 +28,8 @@
+ #include <linux/ctype.h>
+ #include <linux/pci.h>
+ #include <linux/pm.h>
++#include <linux/platform_device.h>
++
+ #include <sound/core.h>
+ #include <sound/control.h>
+ #include <sound/info.h>
+@@ -676,8 +678,8 @@ struct snd_generic_device {
+ #define SND_GENERIC_NAME	"snd_generic"
+ 
+ #ifdef CONFIG_PM
+-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
+-static int snd_generic_resume(struct device *dev, u32 level);
++static int snd_generic_suspend(struct device *dev, pm_message_t state);
++static int snd_generic_resume(struct device *dev);
+ #endif
+ 
+ /* initialized in sound.c */
+@@ -818,13 +820,10 @@ int snd_card_set_pm_callback(snd_card_t 
+ 
+ #ifdef CONFIG_SND_GENERIC_DRIVER
+ /* suspend/resume callbacks for snd_generic platform device */
+-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level)
++static int snd_generic_suspend(struct device *dev, pm_message_t state)
+ {
+ 	snd_card_t *card;
+ 
+-	if (level != SUSPEND_DISABLE)
+-		return 0;
+-
+ 	card = get_snd_generic_card(dev);
+ 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
+ 		return 0;
+@@ -834,13 +833,10 @@ static int snd_generic_suspend(struct de
+ 	return 0;
+ }
+ 
+-static int snd_generic_resume(struct device *dev, u32 level)
++static int snd_generic_resume(struct device *dev)
+ {
+ 	snd_card_t *card;
+ 
+-	if (level != RESUME_ENABLE)
+-		return 0;
+-
+ 	card = get_snd_generic_card(dev);
+ 	if (card->power_state == SNDRV_CTL_POWER_D0)
+ 		return 0;
+diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
+--- a/sound/core/memalloc.c
++++ b/sound/core/memalloc.c
+@@ -190,7 +190,7 @@ static void unmark_pages(struct page *pa
+  *
+  * Returns the pointer of the buffer, or NULL if no enoguh memory.
+  */
+-void *snd_malloc_pages(size_t size, unsigned int gfp_flags)
++void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
+ {
+ 	int pg;
+ 	void *res;
+@@ -235,7 +235,7 @@ static void *snd_malloc_dev_pages(struct
+ {
+ 	int pg;
+ 	void *res;
+-	unsigned int gfp_flags;
++	gfp_t gfp_flags;
+ 
+ 	snd_assert(size > 0, return NULL);
+ 	snd_assert(dma != NULL, return NULL);
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -2949,8 +2949,7 @@ static struct page * snd_pcm_mmap_status
+ 		return NOPAGE_OOM;
+ 	runtime = substream->runtime;
+ 	page = virt_to_page(runtime->status);
+-	if (!PageReserved(page))
+-		get_page(page);
++	get_page(page);
+ 	if (type)
+ 		*type = VM_FAULT_MINOR;
+ 	return page;
+@@ -2992,8 +2991,7 @@ static struct page * snd_pcm_mmap_contro
+ 		return NOPAGE_OOM;
+ 	runtime = substream->runtime;
+ 	page = virt_to_page(runtime->control);
+-	if (!PageReserved(page))
+-		get_page(page);
++	get_page(page);
+ 	if (type)
+ 		*type = VM_FAULT_MINOR;
+ 	return page;
+@@ -3066,8 +3064,7 @@ static struct page *snd_pcm_mmap_data_no
+ 		vaddr = runtime->dma_area + offset;
+ 		page = virt_to_page(vaddr);
+ 	}
+-	if (!PageReserved(page))
+-		get_page(page);
++	get_page(page);
+ 	if (type)
+ 		*type = VM_FAULT_MINOR;
+ 	return page;
+diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
+--- a/sound/core/seq/instr/ainstr_gf1.c
++++ b/sound/core/seq/instr/ainstr_gf1.c
+@@ -51,7 +51,7 @@ static int snd_seq_gf1_copy_wave_from_st
+ 	gf1_wave_t *wp, *prev;
+ 	gf1_xwave_t xp;
+ 	int err;
+-	unsigned int gfp_mask;
++	gfp_t gfp_mask;
+ 	unsigned int real_size;
+ 	
+ 	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
+@@ -144,7 +144,8 @@ static int snd_seq_gf1_put(void *private
+ 	snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
+ 	gf1_instrument_t *ip;
+ 	gf1_xinstrument_t ix;
+-	int err, gfp_mask;
++	int err;
++	gfp_t gfp_mask;
+ 
+ 	if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
+ 		return -EINVAL;
+diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
+--- a/sound/core/seq/instr/ainstr_iw.c
++++ b/sound/core/seq/instr/ainstr_iw.c
+@@ -129,7 +129,7 @@ static int snd_seq_iwffff_copy_wave_from
+ 	iwffff_wave_t *wp, *prev;
+ 	iwffff_xwave_t xp;
+ 	int err;
+-	unsigned int gfp_mask;
++	gfp_t gfp_mask;
+ 	unsigned int real_size;
+ 	
+ 	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
+@@ -236,7 +236,7 @@ static int snd_seq_iwffff_put(void *priv
+ 	iwffff_layer_t *lp, *prev_lp;
+ 	iwffff_xlayer_t lx;
+ 	int err;
+-	unsigned int gfp_mask;
++	gfp_t gfp_mask;
+ 
+ 	if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
+ 		return -EINVAL;
+diff --git a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c
+--- a/sound/core/seq/instr/ainstr_simple.c
++++ b/sound/core/seq/instr/ainstr_simple.c
+@@ -57,7 +57,8 @@ static int snd_seq_simple_put(void *priv
+ 	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
+ 	simple_instrument_t *ip;
+ 	simple_xinstrument_t ix;
+-	int err, gfp_mask;
++	int err;
++	gfp_t gfp_mask;
+ 	unsigned int real_size;
+ 
+ 	if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
+diff --git a/sound/core/sound.c b/sound/core/sound.c
+--- a/sound/core/sound.c
++++ b/sound/core/sound.c
+@@ -231,7 +231,7 @@ int snd_register_device(int type, snd_ca
+ 		devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
+ 	if (card)
+ 		device = card->dev;
+-	class_device_create(sound_class, MKDEV(major, minor), device, "%s", name);
++	class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name);
+ 
+ 	up(&sound_mutex);
+ 	return 0;
+diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
+--- a/sound/oss/ac97_codec.c
++++ b/sound/oss/ac97_codec.c
+@@ -55,6 +55,7 @@
+ #include <linux/pci.h>
+ #include <linux/ac97_codec.h>
+ #include <asm/uaccess.h>
++#include <asm/semaphore.h>
+ 
+ #define CODEC_ID_BUFSZ 14
+ 
+diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
+--- a/sound/oss/au1550_ac97.c
++++ b/sound/oss/au1550_ac97.c
+@@ -35,7 +35,6 @@
+ 
+ #undef DEBUG
+ 
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/string.h>
+ #include <linux/ioport.h>
+diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
+--- a/sound/oss/awe_wave.c
++++ b/sound/oss/awe_wave.c
+@@ -6062,7 +6062,7 @@ static int awe_pnp_probe(struct pnp_dev 
+ 	io1 = pnp_port_start(dev,0);
+ 	io2 = pnp_port_start(dev,1);
+ 	io3 = pnp_port_start(dev,2);
+-	printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x\n.",
++	printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
+ 	       io1, io2, io3);
+ 	setup_ports(io1, io2, io3);
+ 
+diff --git a/sound/oss/cs4232.c b/sound/oss/cs4232.c
+--- a/sound/oss/cs4232.c
++++ b/sound/oss/cs4232.c
+@@ -195,10 +195,12 @@ static int __init probe_cs4232(struct ad
+ 		CS_OUT2(0x15, 0x00);	/* Select logical device 0 (WSS/SB/FM) */
+ 		CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff);	/* WSS base */
+ 
+-		if (check_region(0x388, 4))	/* Not free */
++		if (!request_region(0x388, 4, "FM"))	/* Not free */
+ 			CS_OUT3(0x48, 0x00, 0x00)	/* FM base off */
+-		else
++		else {
++			release_region(0x388, 4);
+ 			CS_OUT3(0x48, 0x03, 0x88);	/* FM base 0x388 */
++		}
+ 
+ 		CS_OUT3(0x42, 0x00, 0x00);	/* SB base off */
+ 		CS_OUT2(0x22, irq);		/* SB+WSS IRQ */
+diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
+--- a/sound/oss/dmasound/dmasound.h
++++ b/sound/oss/dmasound/dmasound.h
+@@ -116,7 +116,7 @@ typedef struct {
+     const char *name;
+     const char *name2;
+     struct module *owner;
+-    void *(*dma_alloc)(unsigned int, int);
++    void *(*dma_alloc)(unsigned int, gfp_t);
+     void (*dma_free)(void *, unsigned int);
+     int (*irqinit)(void);
+ #ifdef MODULE
+diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
+--- a/sound/oss/dmasound/dmasound_atari.c
++++ b/sound/oss/dmasound/dmasound_atari.c
+@@ -114,7 +114,7 @@ static ssize_t ata_ctx_u16le(const u_cha
+ /*** Low level stuff *********************************************************/
+ 
+ 
+-static void *AtaAlloc(unsigned int size, int flags);
++static void *AtaAlloc(unsigned int size, gfp_t flags);
+ static void AtaFree(void *, unsigned int size);
+ static int AtaIrqInit(void);
+ #ifdef MODULE
+@@ -810,7 +810,7 @@ static TRANS transFalconExpanding = {
+  * Atari (TT/Falcon)
+  */
+ 
+-static void *AtaAlloc(unsigned int size, int flags)
++static void *AtaAlloc(unsigned int size, gfp_t flags)
+ {
+ 	return atari_stram_alloc(size, "dmasound");
+ }
+diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
+--- a/sound/oss/dmasound/dmasound_awacs.c
++++ b/sound/oss/dmasound/dmasound_awacs.c
+@@ -271,7 +271,7 @@ int expand_read_bal;	/* Balance factor f
+ 
+ /*** Low level stuff *********************************************************/
+ 
+-static void *PMacAlloc(unsigned int size, int flags);
++static void *PMacAlloc(unsigned int size, gfp_t flags);
+ static void PMacFree(void *ptr, unsigned int size);
+ static int PMacIrqInit(void);
+ #ifdef MODULE
+@@ -614,7 +614,7 @@ tas_init_frame_rates(unsigned int *prop,
+ /*
+  * PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA.
+  */
+-static void *PMacAlloc(unsigned int size, int flags)
++static void *PMacAlloc(unsigned int size, gfp_t flags)
+ {
+ 	return kmalloc(size, flags);
+ }
+diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
+--- a/sound/oss/dmasound/dmasound_paula.c
++++ b/sound/oss/dmasound/dmasound_paula.c
+@@ -69,7 +69,7 @@ static int write_sq_block_size_half, wri
+ /*** Low level stuff *********************************************************/
+ 
+ 
+-static void *AmiAlloc(unsigned int size, int flags);
++static void *AmiAlloc(unsigned int size, gfp_t flags);
+ static void AmiFree(void *obj, unsigned int size);
+ static int AmiIrqInit(void);
+ #ifdef MODULE
+@@ -317,7 +317,7 @@ static inline void StopDMA(void)
+ 	enable_heartbeat();
+ }
+ 
+-static void *AmiAlloc(unsigned int size, int flags)
++static void *AmiAlloc(unsigned int size, gfp_t flags)
+ {
+ 	return amiga_chip_alloc((long)size, "dmasound [Paula]");
+ }
+diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c
+--- a/sound/oss/dmasound/dmasound_q40.c
++++ b/sound/oss/dmasound/dmasound_q40.c
+@@ -36,7 +36,7 @@ static int expand_data;	/* Data for expa
+ /*** Low level stuff *********************************************************/
+ 
+ 
+-static void *Q40Alloc(unsigned int size, int flags);
++static void *Q40Alloc(unsigned int size, gfp_t flags);
+ static void Q40Free(void *, unsigned int);
+ static int Q40IrqInit(void);
+ #ifdef MODULE
+@@ -358,7 +358,7 @@ static TRANS transQ40Compressing = {
+ 
+ /*** Low level stuff *********************************************************/
+ 
+-static void *Q40Alloc(unsigned int size, int flags)
++static void *Q40Alloc(unsigned int size, gfp_t flags)
+ {
+          return kmalloc(size, flags); /* change to vmalloc */
+ }
+diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
+--- a/sound/oss/soundcard.c
++++ b/sound/oss/soundcard.c
+@@ -567,7 +567,7 @@ static int __init oss_init(void)
+ 		devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor),
+ 				S_IFCHR | dev_list[i].mode,
+ 				"sound/%s", dev_list[i].name);
+-		class_device_create(sound_class,
++		class_device_create(sound_class, NULL,
+ 				    MKDEV(SOUND_MAJOR, dev_list[i].minor),
+ 				    NULL, "%s", dev_list[i].name);
+ 
+@@ -579,7 +579,7 @@ static int __init oss_init(void)
+ 						dev_list[i].minor + (j*0x10)),
+ 					S_IFCHR | dev_list[i].mode,
+ 					"sound/%s%d", dev_list[i].name, j);
+-			class_device_create(sound_class,
++			class_device_create(sound_class, NULL,
+ 					    MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
+ 					    NULL, "%s%d", dev_list[i].name, j);
+ 		}
+diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c
+--- a/sound/oss/wavfront.c
++++ b/sound/oss/wavfront.c
+@@ -2434,7 +2434,7 @@ static int __init detect_wavefront (int 
+ 	   consumes 16.
+ 	*/
+ 
+-	if (check_region (io_base, 16)) {
++	if (!request_region (io_base, 16, "wavfront")) {
+ 		printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
+ 			"already in use - ignored\n", dev.base,
+ 			dev.base+15);
+@@ -2466,10 +2466,13 @@ static int __init detect_wavefront (int 
+ 		} else {
+ 			printk (KERN_WARNING LOGNAME "not raw, but no "
+ 				"hardware version!\n");
++			release_region (io_base, 16);
+ 			return 0;
+ 		}
+ 
+ 		if (!wf_raw) {
++			/* will re-acquire region in install_wavefront() */
++			release_region (io_base, 16);
+ 			return 1;
+ 		} else {
+ 			printk (KERN_INFO LOGNAME
+@@ -2489,6 +2492,7 @@ static int __init detect_wavefront (int 
+ 
+ 	if (wavefront_hw_reset ()) {
+ 		printk (KERN_WARNING LOGNAME "hardware reset failed\n");
++		release_region (io_base, 16);
+ 		return 0;
+ 	}
+ 
+@@ -2496,6 +2500,8 @@ static int __init detect_wavefront (int 
+ 
+ 	dev.has_fx = (detect_wffx () == 0);
+ 
++	/* will re-acquire region in install_wavefront() */
++	release_region (io_base, 16);
+ 	return 1;
+ }
+ 
+@@ -2804,17 +2810,27 @@ static int __init wavefront_init (int at
+ }
+ 
+ static int __init install_wavefront (void)
+-
+ {
++	if (!request_region (dev.base+2, 6, "wavefront synth"))
++		return -1;
++
++	if (dev.has_fx) {
++		if (!request_region (dev.base+8, 8, "wavefront fx")) {
++			release_region (dev.base+2, 6);
++			return -1;
++		}
++	}
++
+ 	if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
+ 		printk (KERN_ERR LOGNAME "cannot register raw synth\n");
+-		return -1;
++		goto err_out;
+ 	}
+ 
+ #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
+ 	if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
+ 		printk (KERN_ERR LOGNAME "Too many sequencers\n");
+-		return -1;
++		/* FIXME: leak: should unregister sound synth */
++		goto err_out;
+ 	} else {
+ 		synth_devs[dev.oss_dev] = &wavefront_operations;
+ 	}
+@@ -2827,20 +2843,20 @@ static int __init install_wavefront (voi
+ 		sound_unload_synthdev (dev.oss_dev);
+ #endif /* OSS_SUPPORT_SEQ */ 
+ 
+-		return -1;
++		goto err_out;
+ 	}
+     
+-	request_region (dev.base+2, 6, "wavefront synth");
+-
+-	if (dev.has_fx) {
+-		request_region (dev.base+8, 8, "wavefront fx");
+-	}
+-
+ 	if (wavefront_config_midi ()) {
+ 		printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
+ 	}
+ 
+ 	return dev.oss_dev;
++
++err_out:
++	release_region (dev.base+2, 6);
++	if (dev.has_fx)
++		release_region (dev.base+8, 8);
++	return -1;
+ }
+ 
+ static void __exit uninstall_wavefront (void)
+diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c
+--- a/sound/oss/ymfpci.c
++++ b/sound/oss/ymfpci.c
+@@ -107,14 +107,15 @@ static LIST_HEAD(ymf_devs);
+  */
+ 
+ static struct pci_device_id ymf_id_tbl[] = {
+-#define DEV(v, d, data) \
+-  { PCI_VENDOR_ID_##v, PCI_DEVICE_ID_##v##_##d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)data }
+-	DEV (YAMAHA, 724,  "YMF724"),
+-	DEV (YAMAHA, 724F, "YMF724F"),
+-	DEV (YAMAHA, 740,  "YMF740"),
+-	DEV (YAMAHA, 740C, "YMF740C"),
+-	DEV (YAMAHA, 744,  "YMF744"),
+-	DEV (YAMAHA, 754,  "YMF754"),
++#define DEV(dev, data) \
++	{ PCI_VENDOR_ID_YAMAHA, dev, PCI_ANY_ID, PCI_ANY_ID, 0, 0, \
++		(unsigned long)data }
++	DEV (PCI_DEVICE_ID_YAMAHA_724,  "YMF724"),
++	DEV (PCI_DEVICE_ID_YAMAHA_724F, "YMF724F"),
++	DEV (PCI_DEVICE_ID_YAMAHA_740,  "YMF740"),
++	DEV (PCI_DEVICE_ID_YAMAHA_740C, "YMF740C"),
++	DEV (PCI_DEVICE_ID_YAMAHA_744,  "YMF744"),
++	DEV (PCI_DEVICE_ID_YAMAHA_754,  "YMF754"),
+ #undef DEV
+ 	{ }
+ };
+diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
+--- a/sound/parisc/harmony.c
++++ b/sound/parisc/harmony.c
+@@ -197,7 +197,7 @@ snd_harmony_interrupt(int irq, void *dev
+ 	spin_unlock(&h->lock);
+ 
+ 	if (dstatus & HARMONY_DSTATUS_PN) {
+-		if (h->psubs) {
++		if (h->psubs && h->st.playing) {
+ 			spin_lock(&h->lock);
+ 			h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */
+ 			h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */
+@@ -216,7 +216,7 @@ snd_harmony_interrupt(int irq, void *dev
+ 	}
+ 
+ 	if (dstatus & HARMONY_DSTATUS_RN) {
+-		if (h->csubs) {
++		if (h->csubs && h->st.capturing) {
+ 			spin_lock(&h->lock);
+ 			h->cbuf.buf += h->cbuf.count;
+ 			h->cbuf.buf %= h->cbuf.size;
+@@ -316,6 +316,7 @@ snd_harmony_playback_trigger(snd_pcm_sub
+ 	case SNDRV_PCM_TRIGGER_STOP:
+ 		h->st.playing = 0;
+ 		harmony_mute(h);
++		harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
+ 		harmony_disable_interrupts(h);
+ 		break;
+ 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+@@ -351,8 +352,9 @@ snd_harmony_capture_trigger(snd_pcm_subs
+ 		break;
+         case SNDRV_PCM_TRIGGER_STOP:
+ 		h->st.capturing = 0;
+-                harmony_mute(h);
+-                harmony_disable_interrupts(h);
++		harmony_mute(h);
++		harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
++		harmony_disable_interrupts(h);
+ 		break;
+         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+@@ -408,7 +410,8 @@ snd_harmony_playback_prepare(snd_pcm_sub
+ 	
+ 	h->pbuf.size = snd_pcm_lib_buffer_bytes(ss);
+ 	h->pbuf.count = snd_pcm_lib_period_bytes(ss);
+-	h->pbuf.buf = 0;
++	if (h->pbuf.buf >= h->pbuf.size)
++		h->pbuf.buf = 0;
+ 	h->st.playing = 0;
+ 
+ 	h->st.rate = snd_harmony_rate_bits(rt->rate);
+@@ -437,7 +440,8 @@ snd_harmony_capture_prepare(snd_pcm_subs
+ 
+         h->cbuf.size = snd_pcm_lib_buffer_bytes(ss);
+         h->cbuf.count = snd_pcm_lib_period_bytes(ss);
+-        h->cbuf.buf = 0;
++	if (h->cbuf.buf >= h->cbuf.size)
++	        h->cbuf.buf = 0;
+ 	h->st.capturing = 0;
+ 
+         h->st.rate = snd_harmony_rate_bits(rt->rate);
+@@ -712,13 +716,14 @@ snd_harmony_volume_get(snd_kcontrol_t *k
+ 
+ 	left = (h->st.gain >> shift_left) & mask;
+ 	right = (h->st.gain >> shift_right) & mask;
+-
+ 	if (invert) {
+ 		left = mask - left;
+ 		right = mask - right;
+ 	}
++	
+ 	ucontrol->value.integer.value[0] = left;
+-	ucontrol->value.integer.value[1] = right;
++	if (shift_left != shift_right)
++		ucontrol->value.integer.value[1] = right;
+ 
+ 	spin_unlock_irqrestore(&h->mixer_lock, flags);
+ 
+@@ -738,22 +743,82 @@ snd_harmony_volume_put(snd_kcontrol_t *k
+ 	int old_gain = h->st.gain;
+ 	unsigned long flags;
+ 	
++	spin_lock_irqsave(&h->mixer_lock, flags);
++
+ 	left = ucontrol->value.integer.value[0] & mask;
+-	right = ucontrol->value.integer.value[1] & mask;
+-	if (invert) {
++	if (invert)
+ 		left = mask - left;
+-		right = mask - right;
++	h->st.gain &= ~( (mask << shift_left ) );
++ 	h->st.gain |= (left << shift_left);
++
++	if (shift_left != shift_right) {
++		right = ucontrol->value.integer.value[1] & mask;
++		if (invert)
++			right = mask - right;
++		h->st.gain &= ~( (mask << shift_right) );
++		h->st.gain |= (right << shift_right);
+ 	}
++
++	snd_harmony_set_new_gain(h);
++
++	spin_unlock_irqrestore(&h->mixer_lock, flags);
++	
++	return h->st.gain != old_gain;
++}
++
++static int 
++snd_harmony_captureroute_info(snd_kcontrol_t *kc, 
++			      snd_ctl_elem_info_t *uinfo)
++{
++	static char *texts[2] = { "Line", "Mic" };
++	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 
++snd_harmony_captureroute_get(snd_kcontrol_t *kc, 
++			     snd_ctl_elem_value_t *ucontrol)
++{
++	harmony_t *h = snd_kcontrol_chip(kc);
++	int value;
++	unsigned long flags;
+ 	
+ 	spin_lock_irqsave(&h->mixer_lock, flags);
+ 
+-	h->st.gain &= ~( (mask << shift_right) | (mask << shift_left) );
+- 	h->st.gain |=  ( (left << shift_left) | (right << shift_right) );
++	value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1;
++	ucontrol->value.enumerated.item[0] = value;
++
++	spin_unlock_irqrestore(&h->mixer_lock, flags);
++
++	return 0;
++}  
++
++static int 
++snd_harmony_captureroute_put(snd_kcontrol_t *kc, 
++			     snd_ctl_elem_value_t *ucontrol)
++{
++	harmony_t *h = snd_kcontrol_chip(kc);
++	int value;
++	int old_gain = h->st.gain;
++	unsigned long flags;
++	
++	spin_lock_irqsave(&h->mixer_lock, flags);
++
++	value = ucontrol->value.enumerated.item[0] & 1;
++	h->st.gain &= ~HARMONY_GAIN_IS_MASK;
++ 	h->st.gain |= value << HARMONY_GAIN_IS_SHIFT;
++
+ 	snd_harmony_set_new_gain(h);
+ 
+ 	spin_unlock_irqrestore(&h->mixer_lock, flags);
+ 	
+-	return (old_gain - h->st.gain);
++	return h->st.gain != old_gain;
+ }
+ 
+ #define HARMONY_CONTROLS (sizeof(snd_harmony_controls)/ \
+@@ -767,10 +832,25 @@ snd_harmony_volume_put(snd_kcontrol_t *k
+                    ((mask) << 16) | ((invert) << 24)) }
+ 
+ static snd_kcontrol_new_t snd_harmony_controls[] = {
+-	HARMONY_VOLUME("Playback Volume", HARMONY_GAIN_LO_SHIFT, 
++	HARMONY_VOLUME("Master Playback Volume", HARMONY_GAIN_LO_SHIFT, 
+ 		       HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1),
+ 	HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT,
+ 		       HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0),
++	HARMONY_VOLUME("Monitor Volume", HARMONY_GAIN_MA_SHIFT,
++		       HARMONY_GAIN_MA_SHIFT, HARMONY_GAIN_MA, 1),
++	{
++		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
++		.name = "Input Route",
++		.info = snd_harmony_captureroute_info,
++		.get = snd_harmony_captureroute_get,
++		.put = snd_harmony_captureroute_put
++	},
++	HARMONY_VOLUME("Internal Speaker Switch", HARMONY_GAIN_SE_SHIFT,
++		       HARMONY_GAIN_SE_SHIFT, 1, 0),
++	HARMONY_VOLUME("Line-Out Switch", HARMONY_GAIN_LE_SHIFT,
++		       HARMONY_GAIN_LE_SHIFT, 1, 0),
++	HARMONY_VOLUME("Headphones Switch", HARMONY_GAIN_HE_SHIFT,
++		       HARMONY_GAIN_HE_SHIFT, 1, 0),
+ };
+ 
+ static void __init 
+@@ -852,14 +932,14 @@ snd_harmony_create(snd_card_t *card, 
+ 	memset(&h->pbuf, 0, sizeof(h->pbuf));
+ 	memset(&h->cbuf, 0, sizeof(h->cbuf));
+ 
+-	h->hpa = padev->hpa;
++	h->hpa = padev->hpa.start;
+ 	h->card = card;
+ 	h->dev = padev;
+ 	h->irq = padev->irq;
+-	h->iobase = ioremap_nocache(padev->hpa, HARMONY_SIZE);
++	h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE);
+ 	if (h->iobase == NULL) {
+ 		printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
+-		       padev->hpa);
++		       padev->hpa.start);
+ 		err = -EBUSY;
+ 		goto free_and_ret;
+ 	}
+diff --git a/sound/parisc/harmony.h b/sound/parisc/harmony.h
+--- a/sound/parisc/harmony.h
++++ b/sound/parisc/harmony.h
+@@ -61,7 +61,7 @@ typedef struct snd_card_harmony {
+ #define HARMONY_SIZE       64
+ 
+ #define BUF_SIZE     PAGE_SIZE
+-#define MAX_BUFS     10
++#define MAX_BUFS     16
+ #define MAX_BUF_SIZE (MAX_BUFS * BUF_SIZE)
+ 
+ #define PLAYBACK_BUFS    MAX_BUFS
+@@ -101,28 +101,31 @@ typedef struct snd_card_harmony {
+ #define HARMONY_SS_MONO         0x00000000
+ #define HARMONY_SS_STEREO       0x00000001
+ 
+-#define HARMONY_GAIN_SILENCE    0x00F00FFF
+-#define HARMONY_GAIN_DEFAULT    0x0FF00000
++#define HARMONY_GAIN_SILENCE    0x01F00FFF
++#define HARMONY_GAIN_DEFAULT    0x01F00FFF
+ 
+-#define HARMONY_GAIN_HE_SHIFT   27
++#define HARMONY_GAIN_HE_SHIFT   27 /* headphones enabled */
+ #define HARMONY_GAIN_HE_MASK    (1 << HARMONY_GAIN_HE_SHIFT)
+-#define HARMONY_GAIN_LE_SHIFT   26
++#define HARMONY_GAIN_LE_SHIFT   26 /* line-out enabled */
+ #define HARMONY_GAIN_LE_MASK    (1 << HARMONY_GAIN_LE_SHIFT)
+-#define HARMONY_GAIN_SE_SHIFT   25
++#define HARMONY_GAIN_SE_SHIFT   25 /* internal-speaker enabled */
+ #define HARMONY_GAIN_SE_MASK    (1 << HARMONY_GAIN_SE_SHIFT)
+-#define HARMONY_GAIN_IS_SHIFT   24
++#define HARMONY_GAIN_IS_SHIFT   24 /* input select - 0 for line, 1 for mic */
+ #define HARMONY_GAIN_IS_MASK    (1 << HARMONY_GAIN_IS_SHIFT)
+ 
++/* monitor attenuation */
+ #define HARMONY_GAIN_MA         0x0f
+ #define HARMONY_GAIN_MA_SHIFT   20
+ #define HARMONY_GAIN_MA_MASK    (HARMONY_GAIN_MA << HARMONY_GAIN_MA_SHIFT)
+ 
++/* input gain */
+ #define HARMONY_GAIN_IN         0x0f
+ #define HARMONY_GAIN_LI_SHIFT   16
+ #define HARMONY_GAIN_LI_MASK    (HARMONY_GAIN_IN << HARMONY_GAIN_LI_SHIFT)
+ #define HARMONY_GAIN_RI_SHIFT   12
+ #define HARMONY_GAIN_RI_MASK    (HARMONY_GAIN_IN << HARMONY_GAIN_RI_SHIFT)
+ 
++/* output gain (master volume) */
+ #define HARMONY_GAIN_OUT        0x3f
+ #define HARMONY_GAIN_LO_SHIFT   6
+ #define HARMONY_GAIN_LO_MASK    (HARMONY_GAIN_OUT << HARMONY_GAIN_LO_SHIFT)
+diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c
+--- a/sound/pci/ac97/ac97_bus.c
++++ b/sound/pci/ac97/ac97_bus.c
+@@ -31,7 +31,8 @@ static int ac97_bus_suspend(struct devic
+ 	int ret = 0;
+ 
+ 	if (dev->driver && dev->driver->suspend)
+-		ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
++		ret = dev->driver->suspend(dev, state);
++
+ 	return ret;
+ }
+ 
+@@ -40,7 +41,8 @@ static int ac97_bus_resume(struct device
+ 	int ret = 0;
+ 
+ 	if (dev->driver && dev->driver->resume)
+-		ret = dev->driver->resume(dev, RESUME_POWER_ON);
++		ret = dev->driver->resume(dev);
++
+ 	return ret;
+ }
+ 
+diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
+--- a/sound/pci/bt87x.c
++++ b/sound/pci/bt87x.c
+@@ -761,15 +761,18 @@ static int __devinit snd_bt87x_create(sn
+ 
+ #define BT_DEVICE(chip, subvend, subdev, rate) \
+ 	{ .vendor = PCI_VENDOR_ID_BROOKTREE, \
+-	  .device = PCI_DEVICE_ID_BROOKTREE_##chip, \
++	  .device = chip, \
+ 	  .subvendor = subvend, .subdevice = subdev, \
+ 	  .driver_data = rate }
+ 
+ /* driver_data is the default digital_rate value for that device */
+ static struct pci_device_id snd_bt87x_ids[] = {
+-	BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
+-	BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
+-	BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */
++	/* Hauppauge WinTV series */
++	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000),
++	/* Hauppauge WinTV series */
++	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
++	/* Viewcast Osprey 200 */
++	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
+ 	{ }
+ };
+ MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
+diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
+--- a/sound/pci/emu10k1/emu10k1_main.c
++++ b/sound/pci/emu10k1/emu10k1_main.c
+@@ -579,6 +579,30 @@ static int __devinit snd_emu10k1_ecard_i
+ 	return 0;
+ }
+ 
++static int __devinit snd_emu10k1_cardbus_init(emu10k1_t * emu)
++{
++	unsigned long special_port;
++	unsigned int value;
++
++	/* Special initialisation routine
++	 * before the rest of the IO-Ports become active.
++	 */
++	special_port = emu->port + 0x38;
++	value = inl(special_port);
++	outl(0x00d00000, special_port);
++	value = inl(special_port);
++	outl(0x00d00001, special_port);
++	value = inl(special_port);
++	outl(0x00d0005f, special_port);
++	value = inl(special_port);
++	outl(0x00d0007f, special_port);
++	value = inl(special_port);
++	outl(0x0090007f, special_port);
++	value = inl(special_port);
++
++	return 0;
++}
++
+ /*
+  *  Create the EMU10K1 instance
+  */
+@@ -624,6 +648,16 @@ static emu_chip_details_t emu_chip_detai
+ 	 .ca0108_chip = 1,
+ 	 .spk71 = 1,
+ 	 .ac97_chip = 1} ,
++	/* Audigy 2 ZS Notebook Cardbus card.*/
++	/* Tested by James at superbug.co.uk 30th October 2005 */
++	/* Not working yet, but progressing. */
++	{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
++	 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", 
++	 .id = "Audigy2",
++	 .emu10k2_chip = 1,
++	 .ca0108_chip = 1,
++	 .ca_cardbus_chip = 1,
++	 .spk71 = 1} ,
+ 	{.vendor = 0x1102, .device = 0x0008, 
+ 	 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 
+ 	 .id = "Audigy2",
+@@ -1011,6 +1045,11 @@ int __devinit snd_emu10k1_create(snd_car
+ 			snd_emu10k1_free(emu);
+ 			return err;
+ 		}
++	} else if (emu->card_capabilities->ca_cardbus_chip) {
++		if ((err = snd_emu10k1_cardbus_init(emu)) < 0) {
++			snd_emu10k1_free(emu);
++			return err;
++		}
+ 	} else {
+ 		/* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
+ 			does not support this, it shouldn't do any harm */
+diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
+--- a/sound/ppc/beep.c
++++ b/sound/ppc/beep.c
+@@ -31,14 +31,14 @@
+ #include "pmac.h"
+ 
+ struct snd_pmac_beep {
+-	int running;	/* boolean */
+-	int volume;	/* mixer volume: 0-100 */
++	int running;		/* boolean */
++	int volume;		/* mixer volume: 0-100 */
+ 	int volume_play;	/* currently playing volume */
+ 	int hz;
+ 	int nsamples;
+ 	short *buf;		/* allocated wave buffer */
+ 	dma_addr_t addr;	/* physical address of buffer */
+-	struct input_dev dev;
++	struct input_dev *dev;
+ };
+ 
+ /*
+@@ -212,47 +212,55 @@ static snd_kcontrol_new_t snd_pmac_beep_
+ int __init snd_pmac_attach_beep(pmac_t *chip)
+ {
+ 	pmac_beep_t *beep;
+-	int err;
+-
+-	beep = kmalloc(sizeof(*beep), GFP_KERNEL);
+-	if (! beep)
+-		return -ENOMEM;
+-
+-	memset(beep, 0, sizeof(*beep));
+-	beep->buf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
+-					&beep->addr, GFP_KERNEL);
+-
+-	beep->dev.evbit[0] = BIT(EV_SND);
+-	beep->dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+-	beep->dev.event = snd_pmac_beep_event;
+-	beep->dev.private = chip;
++	struct input_dev *input_dev;
++	void *dmabuf;
++	int err = -ENOMEM;
++
++	beep = kzalloc(sizeof(*beep), GFP_KERNEL);
++	dmabuf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
++				    &beep->addr, GFP_KERNEL);
++	input_dev = input_allocate_device();
++	if (!beep || !dmabuf || !input_dev)
++		goto fail;
+ 
+ 	/* FIXME: set more better values */
+-	beep->dev.name = "PowerMac Beep";
+-	beep->dev.phys = "powermac/beep";
+-	beep->dev.id.bustype = BUS_ADB;
+-	beep->dev.id.vendor = 0x001f;
+-	beep->dev.id.product = 0x0001;
+-	beep->dev.id.version = 0x0100;
++	input_dev->name = "PowerMac Beep";
++	input_dev->phys = "powermac/beep";
++	input_dev->id.bustype = BUS_ADB;
++	input_dev->id.vendor = 0x001f;
++	input_dev->id.product = 0x0001;
++	input_dev->id.version = 0x0100;
++
++	input_dev->evbit[0] = BIT(EV_SND);
++	input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
++	input_dev->event = snd_pmac_beep_event;
++	input_dev->private = chip;
++	input_dev->cdev.dev = &chip->pdev->dev;
+ 
++	beep->dev = input_dev;
++	beep->buf = dmabuf;
+ 	beep->volume = BEEP_VOLUME;
+ 	beep->running = 0;
+-	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_beep_mixer, chip))) < 0) {
+-		kfree(beep->buf);
+-		kfree(beep);
+-		return err;
+-	}
++
++	err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_beep_mixer, chip));
++	if (err < 0)
++		goto fail;
+ 
+ 	chip->beep = beep;
+-	input_register_device(&beep->dev);
++	input_register_device(beep->dev);
+ 
+ 	return 0;
++
++ fail:	input_free_device(input_dev);
++	kfree(dmabuf);
++	kfree(beep);
++	return err;
+ }
+ 
+ void snd_pmac_detach_beep(pmac_t *chip)
+ {
+ 	if (chip->beep) {
+-		input_unregister_device(&chip->beep->dev);
++		input_unregister_device(chip->beep->dev);
+ 		dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
+ 				  chip->beep->buf, chip->beep->addr);
+ 		kfree(chip->beep);
+diff --git a/sound/sound_core.c b/sound/sound_core.c
+--- a/sound/sound_core.c
++++ b/sound/sound_core.c
+@@ -174,7 +174,7 @@ static int sound_insert_unit(struct soun
+ 
+ 	devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor),
+ 			S_IFCHR | mode, s->name);
+-	class_device_create(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor),
++	class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, s->unit_minor),
+ 			    dev, s->name+6);
+ 	return r;
+ 
+diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
+--- a/sound/usb/usbmidi.c
++++ b/sound/usb/usbmidi.c
+@@ -163,7 +163,7 @@ static const uint8_t snd_usbmidi_cin_len
+ /*
+  * Submits the URB, with error handling.
+  */
+-static int snd_usbmidi_submit_urb(struct urb* urb, int flags)
++static int snd_usbmidi_submit_urb(struct urb* urb, gfp_t flags)
+ {
+ 	int err = usb_submit_urb(urb, flags);
+ 	if (err < 0 && err != -ENODEV)

Deleted: dists/trunk/linux-2.6-git/debian/patches-debian/series/2.6.14-1
===================================================================
--- dists/trunk/linux-2.6/debian/patches-debian/series/2.6.14-1	2005-11-03 11:39:35 UTC (rev 4717)
+++ dists/trunk/linux-2.6-git/debian/patches-debian/series/2.6.14-1	2005-11-03 17:51:59 UTC (rev 4720)
@@ -1,27 +0,0 @@
-+ amd64-int3-fix.patch
-#+ drivers-scsi-megaraid_splitup.patch
-+ fbdev-radeon-noaccel.patch
-+ fs-asfs-2.patch
-+ ia64-irq-affinity-upfix.patch
-#- m68k-42_dma.patch
-#- m68k-sonic.patch
-#+ m68k-arch.patch
-#+ m68k-drivers.patch
-#+ m68k-kernel.patch
-#+ m68k-include-m68k.patch
-+ modular-ide.patch
-+ modular-ide-pnp.patch
-+ powerpc-calibrate-tau.patch
-+ powerpc-g3-750cxe.patch
-#+ powerpc-g4-l2-flush-errata.patch
-+ powerpc-mkvmlinuz-support.patch
-+ powerpc-serial.patch
-+ qla2xxx-removed.patch
-#+ remove-references-to-removed-drivers.patch
-+ sparc64-hme-lockup.patch
-+ tty-locking-fixes9.patch
-+ version.patch
-+ powerpc-mv643xx-hotplug-support.patch
-+ powerpc-apus.patch
-+ s390-uaccess-const.patch
-+ powerpc-build-links.patch

Deleted: dists/trunk/linux-2.6-git/debian/patches-debian/series/2.6.14-2
===================================================================
--- dists/trunk/linux-2.6/debian/patches-debian/series/2.6.14-2	2005-11-03 11:39:35 UTC (rev 4717)
+++ dists/trunk/linux-2.6-git/debian/patches-debian/series/2.6.14-2	2005-11-03 17:51:59 UTC (rev 4720)
@@ -1,2 +0,0 @@
-+ alpha-compile-fix.patch
-+ powerpc64-audit_sysctl-build.patch

Added: dists/trunk/linux-2.6-git/debian/patches-debian/series/2.6.14-git-20051103
===================================================================
--- dists/trunk/linux-2.6/debian/patches-debian/series/2.6.14-git-20051103	2005-11-03 11:39:35 UTC (rev 4717)
+++ dists/trunk/linux-2.6-git/debian/patches-debian/series/2.6.14-git-20051103	2005-11-03 17:51:59 UTC (rev 4720)
@@ -0,0 +1,21 @@
++ patch-2.6.14-git5
++ amd64-int3-fix.patch
++ fbdev-radeon-noaccel.patch
++ fs-asfs-2.patch
++ ia64-irq-affinity-upfix.patch
++ modular-ide.patch
++ modular-ide-pnp.patch
+#+ powerpc-calibrate-tau.patch
+#+ powerpc-g3-750cxe.patch
++ powerpc-mkvmlinuz-support.patch
++ powerpc-serial.patch
++ qla2xxx-removed.patch
++ sparc64-hme-lockup.patch
++ tty-locking-fixes9.patch
++ version.patch
+#+ powerpc-mv643xx-hotplug-support.patch
+#+ powerpc-apus.patch
++ s390-uaccess-const.patch
++ powerpc-build-links.patch
+#+ alpha-compile-fix.patch
+#+ powerpc64-audit_sysctl-build.patch




More information about the Kernel-svn-changes mailing list